Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwclouser@mozilla.com <wclouser@mozilla.com@4eb1ac78-321c-0410-a911-ec516a8615a5>2009-06-10 04:17:09 (GMT)
committer wclouser@mozilla.com <wclouser@mozilla.com@4eb1ac78-321c-0410-a911-ec516a8615a5>2009-06-10 04:17:09 (GMT)
commitee24d0e4d4e6ee577df1388c6668e76ef7861579 (patch)
tree737a3e38100e82f2c85f8d5e833136ce18bdbcc6
Tag 5.0.6 for production
git-svn-id: http://svn.mozilla.org/addons/trunk@27440 4eb1ac78-321c-0410-a911-ec516a8615a5
-rw-r--r--README3
-rwxr-xr-xbandwagon/build.sh9
-rw-r--r--bandwagon/chrome.manifest51
-rw-r--r--bandwagon/components/bandwagon-service.js1399
-rw-r--r--bandwagon/content/scripts/bandwagon.js69
-rw-r--r--bandwagon/content/scripts/factory/collectionFactory.js893
-rw-r--r--bandwagon/content/scripts/logger.js156
-rw-r--r--bandwagon/content/scripts/model/addon.js305
-rw-r--r--bandwagon/content/scripts/model/collection.js255
-rw-r--r--bandwagon/content/scripts/model/serviceDocument.js79
-rw-r--r--bandwagon/content/scripts/prefs.js222
-rw-r--r--bandwagon/content/scripts/rpc/constants.js82
-rw-r--r--bandwagon/content/scripts/rpc/error.js67
-rw-r--r--bandwagon/content/scripts/rpc/event.js88
-rw-r--r--bandwagon/content/scripts/rpc/net.js353
-rw-r--r--bandwagon/content/scripts/rpc/service.js610
-rw-r--r--bandwagon/content/scripts/util.js424
-rw-r--r--bandwagon/content/ui/bindings/bandwagon.css16
-rw-r--r--bandwagon/content/ui/bindings/bandwagon.xml766
-rw-r--r--bandwagon/content/ui/collectionsPaneController.js867
-rw-r--r--bandwagon/content/ui/dialog.js77
-rw-r--r--bandwagon/content/ui/overlays/browserOverlay.xul74
-rw-r--r--bandwagon/content/ui/overlays/browserOverlayController.js222
-rw-r--r--bandwagon/content/ui/overlays/extensionsOverlay.xul220
-rw-r--r--bandwagon/content/ui/overlays/extensionsOverlayController.js420
-rw-r--r--bandwagon/content/ui/publish.xul96
-rw-r--r--bandwagon/content/ui/publishController.js261
-rw-r--r--bandwagon/content/ui/settings.xul305
-rw-r--r--bandwagon/content/ui/settingsController.js807
-rw-r--r--bandwagon/defaults/preferences/bandwagon.js60
-rw-r--r--bandwagon/install.rdf178
-rw-r--r--bandwagon/locale/ar/bandwagon.properties2
-rw-r--r--bandwagon/locale/ar/bandwagonAddon.properties38
-rw-r--r--bandwagon/locale/ar/browserOverlay.dtd38
-rw-r--r--bandwagon/locale/ar/browserOverlay.properties4
-rw-r--r--bandwagon/locale/ar/extensionOverlay.properties14
-rw-r--r--bandwagon/locale/ar/extensionsOverlay.dtd69
-rw-r--r--bandwagon/locale/ar/publish.dtd48
-rw-r--r--bandwagon/locale/ar/publish.properties20
-rw-r--r--bandwagon/locale/ar/settings.dtd108
-rw-r--r--bandwagon/locale/ar/settings.properties26
-rw-r--r--bandwagon/locale/ca/bandwagon.properties2
-rw-r--r--bandwagon/locale/ca/bandwagonAddon.properties38
-rw-r--r--bandwagon/locale/ca/browserOverlay.dtd38
-rw-r--r--bandwagon/locale/ca/browserOverlay.properties4
-rw-r--r--bandwagon/locale/ca/extensionOverlay.properties14
-rw-r--r--bandwagon/locale/ca/extensionsOverlay.dtd69
-rw-r--r--bandwagon/locale/ca/publish.dtd48
-rw-r--r--bandwagon/locale/ca/publish.properties20
-rw-r--r--bandwagon/locale/ca/settings.dtd108
-rw-r--r--bandwagon/locale/ca/settings.properties26
-rw-r--r--bandwagon/locale/cs/bandwagon.properties2
-rw-r--r--bandwagon/locale/cs/bandwagonAddon.properties38
-rw-r--r--bandwagon/locale/cs/browserOverlay.dtd38
-rw-r--r--bandwagon/locale/cs/browserOverlay.properties4
-rw-r--r--bandwagon/locale/cs/contents.rdf15
-rw-r--r--bandwagon/locale/cs/extensionOverlay.properties15
-rw-r--r--bandwagon/locale/cs/extensionsOverlay.dtd68
-rw-r--r--bandwagon/locale/cs/publish.dtd47
-rw-r--r--bandwagon/locale/cs/publish.properties20
-rw-r--r--bandwagon/locale/cs/settings.dtd108
-rw-r--r--bandwagon/locale/cs/settings.properties26
-rw-r--r--bandwagon/locale/da/bandwagon.properties2
-rw-r--r--bandwagon/locale/da/bandwagonAddon.properties38
-rw-r--r--bandwagon/locale/da/browserOverlay.dtd38
-rw-r--r--bandwagon/locale/da/browserOverlay.properties4
-rw-r--r--bandwagon/locale/da/extensionOverlay.properties14
-rw-r--r--bandwagon/locale/da/extensionsOverlay.dtd69
-rw-r--r--bandwagon/locale/da/publish.dtd48
-rw-r--r--bandwagon/locale/da/publish.properties20
-rw-r--r--bandwagon/locale/da/settings.dtd108
-rw-r--r--bandwagon/locale/da/settings.properties26
-rw-r--r--bandwagon/locale/de/bandwagon.properties2
-rw-r--r--bandwagon/locale/de/bandwagonAddon.properties38
-rw-r--r--bandwagon/locale/de/browserOverlay.dtd38
-rw-r--r--bandwagon/locale/de/browserOverlay.properties4
-rw-r--r--bandwagon/locale/de/extensionOverlay.properties15
-rw-r--r--bandwagon/locale/de/extensionsOverlay.dtd69
-rw-r--r--bandwagon/locale/de/publish.dtd48
-rw-r--r--bandwagon/locale/de/publish.properties20
-rw-r--r--bandwagon/locale/de/settings.dtd108
-rw-r--r--bandwagon/locale/de/settings.properties27
-rw-r--r--bandwagon/locale/el-GR/bandwagon.properties2
-rw-r--r--bandwagon/locale/el-GR/bandwagonAddon.properties56
-rw-r--r--bandwagon/locale/el-GR/browserOverlay.dtd3
-rw-r--r--bandwagon/locale/el-GR/browserOverlay.properties6
-rw-r--r--bandwagon/locale/el-GR/contents.rdf15
-rw-r--r--bandwagon/locale/el-GR/extensionOverlay.properties16
-rw-r--r--bandwagon/locale/el-GR/extensionsOverlay.dtd26
-rw-r--r--bandwagon/locale/el-GR/publish.dtd47
-rw-r--r--bandwagon/locale/el-GR/publish.properties30
-rw-r--r--bandwagon/locale/el-GR/settings.dtd54
-rw-r--r--bandwagon/locale/el-GR/settings.properties34
-rw-r--r--bandwagon/locale/en-US/bandwagon.properties2
-rw-r--r--bandwagon/locale/en-US/bandwagonAddon.properties39
-rw-r--r--bandwagon/locale/en-US/browserOverlay.dtd38
-rw-r--r--bandwagon/locale/en-US/browserOverlay.properties4
-rw-r--r--bandwagon/locale/en-US/contents.rdf15
-rw-r--r--bandwagon/locale/en-US/extensionOverlay.properties14
-rw-r--r--bandwagon/locale/en-US/extensionsOverlay.dtd69
-rw-r--r--bandwagon/locale/en-US/publish.dtd48
-rw-r--r--bandwagon/locale/en-US/publish.properties22
-rw-r--r--bandwagon/locale/en-US/settings.dtd108
-rw-r--r--bandwagon/locale/en-US/settings.properties26
-rw-r--r--bandwagon/locale/es-ES/bandwagon.properties2
-rw-r--r--bandwagon/locale/es-ES/bandwagonAddon.properties56
-rw-r--r--bandwagon/locale/es-ES/browserOverlay.dtd3
-rw-r--r--bandwagon/locale/es-ES/browserOverlay.properties6
-rw-r--r--bandwagon/locale/es-ES/contents.rdf15
-rw-r--r--bandwagon/locale/es-ES/extensionOverlay.properties16
-rw-r--r--bandwagon/locale/es-ES/extensionsOverlay.dtd26
-rw-r--r--bandwagon/locale/es-ES/publish.dtd47
-rw-r--r--bandwagon/locale/es-ES/publish.properties30
-rw-r--r--bandwagon/locale/es-ES/settings.dtd54
-rw-r--r--bandwagon/locale/es-ES/settings.properties34
-rw-r--r--bandwagon/locale/fa/bandwagon.properties2
-rw-r--r--bandwagon/locale/fa/bandwagonAddon.properties38
-rw-r--r--bandwagon/locale/fa/browserOverlay.dtd38
-rw-r--r--bandwagon/locale/fa/browserOverlay.properties4
-rw-r--r--bandwagon/locale/fa/contents.rdf15
-rw-r--r--bandwagon/locale/fa/extensionOverlay.properties14
-rw-r--r--bandwagon/locale/fa/extensionsOverlay.dtd69
-rw-r--r--bandwagon/locale/fa/publish.dtd48
-rw-r--r--bandwagon/locale/fa/publish.properties20
-rw-r--r--bandwagon/locale/fa/settings.dtd108
-rw-r--r--bandwagon/locale/fa/settings.properties26
-rw-r--r--bandwagon/locale/fr/bandwagon.properties2
-rw-r--r--bandwagon/locale/fr/bandwagonAddon.properties56
-rw-r--r--bandwagon/locale/fr/browserOverlay.dtd3
-rw-r--r--bandwagon/locale/fr/browserOverlay.properties6
-rw-r--r--bandwagon/locale/fr/extensionOverlay.properties16
-rw-r--r--bandwagon/locale/fr/extensionsOverlay.dtd26
-rw-r--r--bandwagon/locale/fr/publish.dtd46
-rw-r--r--bandwagon/locale/fr/publish.properties30
-rw-r--r--bandwagon/locale/fr/settings.dtd54
-rw-r--r--bandwagon/locale/fr/settings.properties34
-rw-r--r--bandwagon/locale/fy-NL/bandwagon.properties2
-rw-r--r--bandwagon/locale/fy-NL/bandwagonAddon.properties56
-rw-r--r--bandwagon/locale/fy-NL/browserOverlay.dtd3
-rw-r--r--bandwagon/locale/fy-NL/browserOverlay.properties6
-rw-r--r--bandwagon/locale/fy-NL/contents.rdf15
-rw-r--r--bandwagon/locale/fy-NL/extensionOverlay.properties16
-rw-r--r--bandwagon/locale/fy-NL/extensionsOverlay.dtd26
-rw-r--r--bandwagon/locale/fy-NL/publish.dtd47
-rw-r--r--bandwagon/locale/fy-NL/publish.properties30
-rw-r--r--bandwagon/locale/fy-NL/settings.dtd54
-rw-r--r--bandwagon/locale/fy-NL/settings.properties34
-rw-r--r--bandwagon/locale/he/bandwagon.properties2
-rw-r--r--bandwagon/locale/he/bandwagonAddon.properties38
-rw-r--r--bandwagon/locale/he/browserOverlay.dtd38
-rw-r--r--bandwagon/locale/he/browserOverlay.properties4
-rw-r--r--bandwagon/locale/he/extensionOverlay.properties14
-rw-r--r--bandwagon/locale/he/extensionsOverlay.dtd70
-rw-r--r--bandwagon/locale/he/publish.dtd48
-rw-r--r--bandwagon/locale/he/publish.properties20
-rw-r--r--bandwagon/locale/he/settings.dtd108
-rw-r--r--bandwagon/locale/he/settings.properties26
-rw-r--r--bandwagon/locale/id/bandwagon.properties2
-rw-r--r--bandwagon/locale/id/bandwagonAddon.properties38
-rw-r--r--bandwagon/locale/id/browserOverlay.dtd38
-rw-r--r--bandwagon/locale/id/browserOverlay.properties4
-rw-r--r--bandwagon/locale/id/contents.rdf15
-rw-r--r--bandwagon/locale/id/extensionOverlay.properties14
-rw-r--r--bandwagon/locale/id/extensionsOverlay.dtd69
-rw-r--r--bandwagon/locale/id/publish.dtd48
-rw-r--r--bandwagon/locale/id/publish.properties22
-rw-r--r--bandwagon/locale/id/settings.dtd108
-rw-r--r--bandwagon/locale/id/settings.properties26
-rw-r--r--bandwagon/locale/it/bandwagon.properties2
-rw-r--r--bandwagon/locale/it/bandwagonAddon.properties56
-rw-r--r--bandwagon/locale/it/browserOverlay.dtd3
-rw-r--r--bandwagon/locale/it/browserOverlay.properties6
-rw-r--r--bandwagon/locale/it/contents.rdf15
-rw-r--r--bandwagon/locale/it/extensionOverlay.properties16
-rw-r--r--bandwagon/locale/it/extensionsOverlay.dtd26
-rw-r--r--bandwagon/locale/it/publish.dtd47
-rw-r--r--bandwagon/locale/it/publish.properties30
-rw-r--r--bandwagon/locale/it/settings.dtd54
-rw-r--r--bandwagon/locale/it/settings.properties34
-rw-r--r--bandwagon/locale/ja/bandwagon.properties2
-rw-r--r--bandwagon/locale/ja/bandwagonAddon.properties56
-rw-r--r--bandwagon/locale/ja/browserOverlay.dtd3
-rw-r--r--bandwagon/locale/ja/browserOverlay.properties6
-rw-r--r--bandwagon/locale/ja/extensionOverlay.properties16
-rw-r--r--bandwagon/locale/ja/extensionsOverlay.dtd26
-rw-r--r--bandwagon/locale/ja/publish.dtd46
-rw-r--r--bandwagon/locale/ja/publish.properties30
-rw-r--r--bandwagon/locale/ja/settings.dtd54
-rw-r--r--bandwagon/locale/ja/settings.properties34
-rw-r--r--bandwagon/locale/nl/bandwagon.properties2
-rw-r--r--bandwagon/locale/nl/bandwagonAddon.properties56
-rw-r--r--bandwagon/locale/nl/browserOverlay.dtd3
-rw-r--r--bandwagon/locale/nl/browserOverlay.properties6
-rw-r--r--bandwagon/locale/nl/contents.rdf15
-rw-r--r--bandwagon/locale/nl/extensionOverlay.properties16
-rw-r--r--bandwagon/locale/nl/extensionsOverlay.dtd26
-rw-r--r--bandwagon/locale/nl/publish.dtd48
-rw-r--r--bandwagon/locale/nl/publish.properties30
-rw-r--r--bandwagon/locale/nl/settings.dtd54
-rw-r--r--bandwagon/locale/nl/settings.properties34
-rw-r--r--bandwagon/locale/pl/bandwagon.properties2
-rw-r--r--bandwagon/locale/pl/bandwagonAddon.properties56
-rw-r--r--bandwagon/locale/pl/browserOverlay.dtd39
-rw-r--r--bandwagon/locale/pl/browserOverlay.properties6
-rw-r--r--bandwagon/locale/pl/contents.rdf15
-rw-r--r--bandwagon/locale/pl/extensionOverlay.properties16
-rw-r--r--bandwagon/locale/pl/extensionsOverlay.dtd63
-rw-r--r--bandwagon/locale/pl/publish.dtd47
-rw-r--r--bandwagon/locale/pl/publish.properties30
-rw-r--r--bandwagon/locale/pl/settings.dtd91
-rw-r--r--bandwagon/locale/pl/settings.properties34
-rw-r--r--bandwagon/locale/pt-BR/bandwagon.properties2
-rw-r--r--bandwagon/locale/pt-BR/bandwagonAddon.properties38
-rw-r--r--bandwagon/locale/pt-BR/browserOverlay.dtd38
-rw-r--r--bandwagon/locale/pt-BR/browserOverlay.properties4
-rw-r--r--bandwagon/locale/pt-BR/extensionOverlay.properties14
-rw-r--r--bandwagon/locale/pt-BR/extensionsOverlay.dtd69
-rw-r--r--bandwagon/locale/pt-BR/publish.dtd48
-rw-r--r--bandwagon/locale/pt-BR/publish.properties20
-rw-r--r--bandwagon/locale/pt-BR/settings.dtd108
-rw-r--r--bandwagon/locale/pt-BR/settings.properties26
-rw-r--r--bandwagon/locale/pt-PT/bandwagon.properties2
-rw-r--r--bandwagon/locale/pt-PT/bandwagonAddon.properties38
-rw-r--r--bandwagon/locale/pt-PT/browserOverlay.dtd38
-rw-r--r--bandwagon/locale/pt-PT/browserOverlay.properties4
-rw-r--r--bandwagon/locale/pt-PT/extensionOverlay.properties14
-rw-r--r--bandwagon/locale/pt-PT/extensionsOverlay.dtd69
-rw-r--r--bandwagon/locale/pt-PT/publish.dtd48
-rw-r--r--bandwagon/locale/pt-PT/publish.properties20
-rw-r--r--bandwagon/locale/pt-PT/settings.dtd108
-rw-r--r--bandwagon/locale/pt-PT/settings.properties26
-rw-r--r--bandwagon/locale/ro/bandwagon.properties2
-rw-r--r--bandwagon/locale/ro/bandwagonAddon.properties38
-rw-r--r--bandwagon/locale/ro/browserOverlay.dtd38
-rw-r--r--bandwagon/locale/ro/browserOverlay.properties4
-rw-r--r--bandwagon/locale/ro/extensionOverlay.properties18
-rw-r--r--bandwagon/locale/ro/extensionsOverlay.dtd69
-rw-r--r--bandwagon/locale/ro/publish.dtd48
-rw-r--r--bandwagon/locale/ro/publish.properties20
-rw-r--r--bandwagon/locale/ro/settings.dtd108
-rw-r--r--bandwagon/locale/ro/settings.properties29
-rw-r--r--bandwagon/locale/ru/bandwagon.properties2
-rw-r--r--bandwagon/locale/ru/bandwagonAddon.properties39
-rw-r--r--bandwagon/locale/ru/browserOverlay.dtd38
-rw-r--r--bandwagon/locale/ru/browserOverlay.properties4
-rw-r--r--bandwagon/locale/ru/contents.rdf15
-rw-r--r--bandwagon/locale/ru/extensionOverlay.properties14
-rw-r--r--bandwagon/locale/ru/extensionsOverlay.dtd69
-rw-r--r--bandwagon/locale/ru/publish.dtd48
-rw-r--r--bandwagon/locale/ru/publish.properties22
-rw-r--r--bandwagon/locale/ru/settings.dtd108
-rw-r--r--bandwagon/locale/ru/settings.properties26
-rw-r--r--bandwagon/locale/sk/bandwagon.properties2
-rw-r--r--bandwagon/locale/sk/bandwagonAddon.properties56
-rw-r--r--bandwagon/locale/sk/browserOverlay.dtd3
-rw-r--r--bandwagon/locale/sk/browserOverlay.properties6
-rw-r--r--bandwagon/locale/sk/contents.rdf15
-rw-r--r--bandwagon/locale/sk/extensionOverlay.properties16
-rw-r--r--bandwagon/locale/sk/extensionsOverlay.dtd26
-rw-r--r--bandwagon/locale/sk/publish.dtd47
-rw-r--r--bandwagon/locale/sk/publish.properties30
-rw-r--r--bandwagon/locale/sk/settings.dtd54
-rw-r--r--bandwagon/locale/sk/settings.properties34
-rw-r--r--bandwagon/locale/sq/bandwagon.properties2
-rw-r--r--bandwagon/locale/sq/bandwagonAddon.properties38
-rw-r--r--bandwagon/locale/sq/browserOverlay.dtd38
-rw-r--r--bandwagon/locale/sq/browserOverlay.properties4
-rw-r--r--bandwagon/locale/sq/extensionOverlay.properties14
-rw-r--r--bandwagon/locale/sq/extensionsOverlay.dtd69
-rw-r--r--bandwagon/locale/sq/publish.dtd48
-rw-r--r--bandwagon/locale/sq/publish.properties20
-rw-r--r--bandwagon/locale/sq/settings.dtd108
-rw-r--r--bandwagon/locale/sq/settings.properties26
-rw-r--r--bandwagon/locale/sv-SE/bandwagon.properties2
-rw-r--r--bandwagon/locale/sv-SE/bandwagonAddon.properties38
-rw-r--r--bandwagon/locale/sv-SE/browserOverlay.dtd38
-rw-r--r--bandwagon/locale/sv-SE/browserOverlay.properties4
-rw-r--r--bandwagon/locale/sv-SE/extensionOverlay.properties14
-rw-r--r--bandwagon/locale/sv-SE/extensionsOverlay.dtd69
-rw-r--r--bandwagon/locale/sv-SE/publish.dtd48
-rw-r--r--bandwagon/locale/sv-SE/publish.properties20
-rw-r--r--bandwagon/locale/sv-SE/settings.dtd108
-rw-r--r--bandwagon/locale/sv-SE/settings.properties26
-rw-r--r--bandwagon/locale/uk/bandwagon.properties2
-rw-r--r--bandwagon/locale/uk/bandwagonAddon.properties38
-rw-r--r--bandwagon/locale/uk/browserOverlay.dtd38
-rw-r--r--bandwagon/locale/uk/browserOverlay.properties4
-rw-r--r--bandwagon/locale/uk/extensionOverlay.properties14
-rw-r--r--bandwagon/locale/uk/extensionsOverlay.dtd69
-rw-r--r--bandwagon/locale/uk/publish.dtd48
-rw-r--r--bandwagon/locale/uk/publish.properties20
-rw-r--r--bandwagon/locale/uk/settings.dtd108
-rw-r--r--bandwagon/locale/uk/settings.properties26
-rw-r--r--bandwagon/locale/vi/bandwagon.properties2
-rw-r--r--bandwagon/locale/vi/bandwagonAddon.properties56
-rw-r--r--bandwagon/locale/vi/browserOverlay.dtd3
-rw-r--r--bandwagon/locale/vi/browserOverlay.properties6
-rw-r--r--bandwagon/locale/vi/contents.rdf15
-rw-r--r--bandwagon/locale/vi/extensionOverlay.properties16
-rw-r--r--bandwagon/locale/vi/extensionsOverlay.dtd26
-rw-r--r--bandwagon/locale/vi/publish.dtd47
-rw-r--r--bandwagon/locale/vi/publish.properties30
-rw-r--r--bandwagon/locale/vi/settings.dtd54
-rw-r--r--bandwagon/locale/vi/settings.properties34
-rw-r--r--bandwagon/locale/zh-CN/bandwagon.properties2
-rw-r--r--bandwagon/locale/zh-CN/bandwagonAddon.properties56
-rw-r--r--bandwagon/locale/zh-CN/browserOverlay.dtd3
-rw-r--r--bandwagon/locale/zh-CN/browserOverlay.properties6
-rw-r--r--bandwagon/locale/zh-CN/contents.rdf15
-rw-r--r--bandwagon/locale/zh-CN/extensionOverlay.properties16
-rw-r--r--bandwagon/locale/zh-CN/extensionsOverlay.dtd26
-rw-r--r--bandwagon/locale/zh-CN/publish.dtd47
-rw-r--r--bandwagon/locale/zh-CN/publish.properties30
-rw-r--r--bandwagon/locale/zh-CN/settings.dtd54
-rw-r--r--bandwagon/locale/zh-CN/settings.properties34
-rw-r--r--bandwagon/locale/zh-TW/bandwagon.properties2
-rw-r--r--bandwagon/locale/zh-TW/bandwagonAddon.properties56
-rw-r--r--bandwagon/locale/zh-TW/browserOverlay.dtd3
-rw-r--r--bandwagon/locale/zh-TW/browserOverlay.properties6
-rw-r--r--bandwagon/locale/zh-TW/contents.rdf15
-rw-r--r--bandwagon/locale/zh-TW/extensionOverlay.properties16
-rw-r--r--bandwagon/locale/zh-TW/extensionsOverlay.dtd26
-rw-r--r--bandwagon/locale/zh-TW/publish.dtd46
-rw-r--r--bandwagon/locale/zh-TW/publish.properties30
-rw-r--r--bandwagon/locale/zh-TW/settings.dtd54
-rw-r--r--bandwagon/locale/zh-TW/settings.properties34
-rw-r--r--bandwagon/skin/extensionsOverlay.css276
-rw-r--r--bandwagon/skin/global.css41
-rw-r--r--bandwagon/skin/images/addon-toolbar.pngbin0 -> 8896 bytes
-rw-r--r--bandwagon/skin/images/addons_autoUp_sm.pngbin0 -> 2272 bytes
-rw-r--r--bandwagon/skin/images/addons_comments_sm.pngbin0 -> 1121 bytes
-rw-r--r--bandwagon/skin/images/addons_prefs_autoUp.pngbin0 -> 12179 bytes
-rw-r--r--bandwagon/skin/images/addons_prefs_general.pngbin0 -> 4162 bytes
-rw-r--r--bandwagon/skin/images/addons_prefs_logo.pngbin0 -> 5089 bytes
-rwxr-xr-xbandwagon/skin/images/error.pngbin0 -> 666 bytes
-rw-r--r--bandwagon/skin/images/gear.pngbin0 -> 722 bytes
-rw-r--r--bandwagon/skin/images/icon32.pngbin0 -> 2263 bytes
-rwxr-xr-xbandwagon/skin/images/information.pngbin0 -> 778 bytes
-rw-r--r--bandwagon/skin/images/logo-login.pngbin0 -> 19148 bytes
-rw-r--r--bandwagon/skin/images/missing-thumbnail.pngbin0 -> 29478 bytes
-rw-r--r--bandwagon/skin/images/plus.pngbin0 -> 336 bytes
-rw-r--r--bandwagon/skin/images/reload.pngbin0 -> 706 bytes
-rw-r--r--bandwagon/skin/images/spinner-small.gifbin0 -> 1849 bytes
-rw-r--r--bandwagon/skin/images/spinner.gifbin0 -> 3208 bytes
-rw-r--r--bandwagon/skin/images/star.pngbin0 -> 14249 bytes
-rw-r--r--bandwagon/skin/images/twisty-clsd.pngbin0 -> 235 bytes
-rw-r--r--bandwagon/skin/images/twisty-open.pngbin0 -> 2878 bytes
-rw-r--r--bandwagon/skin/platform/linux/browserOverlay.css56
-rw-r--r--bandwagon/skin/platform/linux/extensionsOverlayIcons.css72
-rw-r--r--bandwagon/skin/platform/linux/settingsIcons.css50
-rw-r--r--bandwagon/skin/platform/mac/browserOverlay.css64
-rw-r--r--bandwagon/skin/platform/mac/extensionsOverlayIcons.css72
-rw-r--r--bandwagon/skin/platform/mac/settingsIcons.css62
-rw-r--r--bandwagon/skin/platform/vista/browserOverlay.css56
-rw-r--r--bandwagon/skin/platform/vista/extensionsOverlayIcons.css72
-rw-r--r--bandwagon/skin/platform/vista/settingsIcons.css58
-rw-r--r--bandwagon/skin/platform/xp/browserOverlay.css56
-rw-r--r--bandwagon/skin/platform/xp/extensionsOverlayIcons.css76
-rw-r--r--bandwagon/skin/platform/xp/settingsIcons.css62
-rw-r--r--bandwagon/skin/publish.css40
-rw-r--r--bandwagon/skin/settings.css62
-rwxr-xr-xbandwagon/utils/merge-to-locales.sh14
-rw-r--r--bandwagon/utils/new.txt4
-rwxr-xr-xbandwagon/utils/read-locales.sh16
-rw-r--r--bin/README11
-rw-r--r--bin/blank.pngbin0 -> 4387 bytes
-rwxr-xr-xbin/build.py288
-rw-r--r--bin/check_stats.php154
-rwxr-xr-xbin/clean.sh26
-rw-r--r--bin/compatibility_report.php214
-rw-r--r--bin/database.class.php156
-rwxr-xr-xbin/fix_ratings.php45
-rwxr-xr-xbin/installck.pl80
-rwxr-xr-xbin/load_tests.sh24
-rwxr-xr-xbin/maintenance.php632
-rw-r--r--bin/migration.py1429
-rw-r--r--bin/parse_logs/count_downloads.class.php195
-rw-r--r--bin/parse_logs/count_update_pings.class.php276
-rw-r--r--bin/parse_logs/log_parser.class.php321
-rw-r--r--bin/parse_logs/parse_logs.php108
-rwxr-xr-xbin/reset_alpha.pl-default113
-rw-r--r--bin/run_once/calculate_undated_totals.php67
-rw-r--r--bin/run_once/combine_daily_downloads.php69
-rw-r--r--bin/run_once/delete_duplicate_daily_downloads.php78
-rw-r--r--bin/run_once/fix_entities.php82
-rw-r--r--bin/update-hashes.php123
-rw-r--r--bin/update-search-views.php156
-rw-r--r--bin/yuicompressor-2.3.4/build/yuicompressor-2.3.4.jarbin0 -> 847381 bytes
-rw-r--r--bin/yuicompressor-2.3.4/doc/CHANGELOG186
-rw-r--r--bin/yuicompressor-2.3.4/doc/README135
-rw-r--r--bin/yuicompressor-2.3.4/lib/jargs-1.0.jarbin0 -> 11406 bytes
-rw-r--r--bin/yuicompressor-2.3.4/lib/rhino-1.6R7.jarbin0 -> 813521 bytes
-rw-r--r--bin/yuicompressor-2.3.4/src/com/yahoo/platform/yui/compressor/CssCompressor.java176
-rw-r--r--bin/yuicompressor-2.3.4/src/com/yahoo/platform/yui/compressor/JavaScriptCompressor.java1309
-rw-r--r--bin/yuicompressor-2.3.4/src/com/yahoo/platform/yui/compressor/JavaScriptIdentifier.java55
-rw-r--r--bin/yuicompressor-2.3.4/src/com/yahoo/platform/yui/compressor/JavaScriptToken.java28
-rw-r--r--bin/yuicompressor-2.3.4/src/com/yahoo/platform/yui/compressor/ScriptOrFnScope.java154
-rw-r--r--bin/yuicompressor-2.3.4/src/com/yahoo/platform/yui/compressor/YUICompressor.java240
-rw-r--r--bin/yuicompressor-2.3.4/src/org/mozilla/javascript/Decompiler.java916
-rw-r--r--bin/yuicompressor-2.3.4/src/org/mozilla/javascript/Decompiler.java.orig910
-rw-r--r--bin/yuicompressor-2.3.4/src/org/mozilla/javascript/Parser.java2170
-rw-r--r--bin/yuicompressor-2.3.4/src/org/mozilla/javascript/Parser.java.orig2159
-rw-r--r--bin/yuicompressor-2.3.4/src/org/mozilla/javascript/Token.java420
-rw-r--r--bin/yuicompressor-2.3.4/src/org/mozilla/javascript/Token.java.orig417
-rw-r--r--bin/yuicompressor-2.3.4/src/org/mozilla/javascript/TokenStream.java1381
-rw-r--r--bin/yuicompressor-2.3.4/src/org/mozilla/javascript/TokenStream.java.orig1398
-rw-r--r--site/.htaccess5
-rw-r--r--site/app/.htaccess5
-rw-r--r--site/app/app_controller.php483
-rw-r--r--site/app/app_model.php793
-rw-r--r--site/app/config/acl.ini.php76
-rw-r--r--site/app/config/bootstrap.php306
-rw-r--r--site/app/config/config.php.default232
-rw-r--r--site/app/config/constants.php309
-rw-r--r--site/app/config/core.php242
-rw-r--r--site/app/config/database.php131
-rw-r--r--site/app/config/inflections.php72
-rw-r--r--site/app/config/language.inc.php225
-rw-r--r--site/app/config/language.php379
-rw-r--r--site/app/config/revisions.php5
-rw-r--r--site/app/config/routes.php131
-rw-r--r--site/app/config/shadowdb.inc.php76
-rw-r--r--site/app/config/sql/anonymize.sql18
-rw-r--r--site/app/config/sql/remora.sql1250
-rw-r--r--site/app/config/tags.ini.php34
-rw-r--r--site/app/controllers/addons_controller.php1570
-rw-r--r--site/app/controllers/admin_controller.php1840
-rw-r--r--site/app/controllers/api_controller.php1134
-rw-r--r--site/app/controllers/collections_controller.php1067
-rw-r--r--site/app/controllers/compatibility_controller.php202
-rw-r--r--site/app/controllers/components/amo.php753
-rw-r--r--site/app/controllers/components/audit.php332
-rw-r--r--site/app/controllers/components/collections_listing.php102
-rw-r--r--site/app/controllers/components/developers.php1251
-rw-r--r--site/app/controllers/components/diff.php180
-rw-r--r--site/app/controllers/components/editors.php753
-rw-r--r--site/app/controllers/components/email.php104
-rw-r--r--site/app/controllers/components/error.php110
-rw-r--r--site/app/controllers/components/filebrowser.php104
-rw-r--r--site/app/controllers/components/helper.php74
-rw-r--r--site/app/controllers/components/image.php243
-rw-r--r--site/app/controllers/components/includes/rdf_parser.php1639
-rw-r--r--site/app/controllers/components/ldap.php82
-rw-r--r--site/app/controllers/components/newsfeed.php385
-rw-r--r--site/app/controllers/components/opensearch.php492
-rw-r--r--site/app/controllers/components/pagination.php489
-rw-r--r--site/app/controllers/components/rdf.php124
-rw-r--r--site/app/controllers/components/recaptcha.php145
-rw-r--r--site/app/controllers/components/search.php458
-rw-r--r--site/app/controllers/components/simple_acl.php172
-rw-r--r--site/app/controllers/components/simple_auth.php163
-rw-r--r--site/app/controllers/components/src.php72
-rw-r--r--site/app/controllers/components/stats.php611
-rw-r--r--site/app/controllers/components/userfunc.php90
-rw-r--r--site/app/controllers/components/versioncompare.php285
-rw-r--r--site/app/controllers/developers_controller.php1511
-rw-r--r--site/app/controllers/downloads_controller.php169
-rw-r--r--site/app/controllers/editors_controller.php1534
-rw-r--r--site/app/controllers/facebook_controller.php805
-rw-r--r--site/app/controllers/facebookinstall_controller.php126
-rw-r--r--site/app/controllers/favorites_controller.php55
-rw-r--r--site/app/controllers/features_controller.php59
-rw-r--r--site/app/controllers/files_controller.php446
-rw-r--r--site/app/controllers/groups_controller.php122
-rw-r--r--site/app/controllers/images_controller.php159
-rw-r--r--site/app/controllers/legacy_url_controller.php89
-rw-r--r--site/app/controllers/localizers_controller.php449
-rw-r--r--site/app/controllers/pages_controller.php140
-rw-r--r--site/app/controllers/previews_controller.php328
-rw-r--r--site/app/controllers/reviews_controller.php579
-rw-r--r--site/app/controllers/search_controller.php301
-rw-r--r--site/app/controllers/sharing_api_controller.php1517
-rw-r--r--site/app/controllers/statistics_controller.php410
-rw-r--r--site/app/controllers/tests_controller.php243
-rw-r--r--site/app/controllers/users_controller.php855
-rw-r--r--site/app/controllers/versions_controller.php95
-rw-r--r--site/app/index.php26
-rw-r--r--site/app/locale/af/LC_MESSAGES/messages.mobin0 -> 438 bytes
-rw-r--r--site/app/locale/af/LC_MESSAGES/messages.po9471
-rw-r--r--site/app/locale/ar/LC_MESSAGES/messages.mobin0 -> 87133 bytes
-rw-r--r--site/app/locale/ar/LC_MESSAGES/messages.po8524
-rw-r--r--site/app/locale/ar/images/sandbox-review.pngbin0 -> 17201 bytes
-rw-r--r--site/app/locale/ar/pages/error404.thtml16
-rw-r--r--site/app/locale/ar/pages/nomination.thtml10
-rwxr-xr-xsite/app/locale/ar/pages/policy.thtml110
-rw-r--r--site/app/locale/ar/pages/reviewguide.thtml66
-rw-r--r--site/app/locale/ar/pages/sandbox.thtml13
-rw-r--r--site/app/locale/ar/pages/statistics_help.thtml7
-rw-r--r--site/app/locale/ar/pages/submission_help.thtml35
-rw-r--r--site/app/locale/ca/LC_MESSAGES/messages.mobin0 -> 146137 bytes
-rw-r--r--site/app/locale/ca/LC_MESSAGES/messages.po8027
-rw-r--r--site/app/locale/ca/images/sandbox-review.pngbin0 -> 17903 bytes
-rw-r--r--site/app/locale/ca/pages/collector_features.thtml25
-rw-r--r--site/app/locale/ca/pages/error404.thtml16
-rw-r--r--site/app/locale/ca/pages/nomination.thtml8
-rw-r--r--site/app/locale/ca/pages/policy.thtml110
-rw-r--r--site/app/locale/ca/pages/sandbox.thtml13
-rw-r--r--site/app/locale/ca/pages/submission_help.thtml34
-rwxr-xr-xsite/app/locale/compile-mo.sh19
-rw-r--r--site/app/locale/cs/LC_MESSAGES/messages.mobin0 -> 139067 bytes
-rw-r--r--site/app/locale/cs/LC_MESSAGES/messages.po7285
-rw-r--r--site/app/locale/cs/pages/collector.thtml47
-rw-r--r--site/app/locale/cs/pages/collector_faq.thtml24
-rw-r--r--site/app/locale/cs/pages/collector_features.thtml32
-rw-r--r--site/app/locale/cs/pages/collector_firstrun.thtml38
-rw-r--r--site/app/locale/cs/pages/error404.thtml16
-rw-r--r--site/app/locale/cs/pages/faq.thtml78
-rw-r--r--site/app/locale/cs/pages/nomination.thtml8
-rw-r--r--site/app/locale/cs/pages/sandbox.thtml13
-rw-r--r--site/app/locale/cs/pages/statistics_help.thtml8
-rw-r--r--site/app/locale/cs/pages/submission_help.thtml35
-rw-r--r--site/app/locale/cy/LC_MESSAGES/messages.mobin0 -> 51200 bytes
-rw-r--r--site/app/locale/cy/LC_MESSAGES/messages.po8769
-rw-r--r--site/app/locale/cy/images/sandbox-review.pngbin0 -> 16596 bytes
-rw-r--r--site/app/locale/da/LC_MESSAGES/da.txt2044
-rw-r--r--site/app/locale/da/LC_MESSAGES/en-US.txt2044
-rw-r--r--site/app/locale/da/LC_MESSAGES/messages.mobin0 -> 114185 bytes
-rw-r--r--site/app/locale/da/LC_MESSAGES/messages.po7539
-rw-r--r--site/app/locale/da/glossary.txt25
-rw-r--r--site/app/locale/da/pages/collector_features.thtml30
-rw-r--r--site/app/locale/da/pages/compatibility_developer_tips.thtml6
-rw-r--r--site/app/locale/da/pages/compatibility_user_tips.thtml6
-rw-r--r--site/app/locale/da/pages/error404.thtml16
-rw-r--r--site/app/locale/da/pages/reviewguide.thtml66
-rw-r--r--site/app/locale/da/pages/sandbox.thtml13
-rw-r--r--site/app/locale/de/LC_MESSAGES/messages.mobin0 -> 147788 bytes
-rw-r--r--site/app/locale/de/LC_MESSAGES/messages.po7500
-rw-r--r--site/app/locale/de/images/sandbox-review.pngbin0 -> 18967 bytes
-rw-r--r--site/app/locale/de/pages/error404.thtml16
-rwxr-xr-xsite/app/locale/de/pages/faq.thtml65
-rw-r--r--site/app/locale/de/pages/nomination.thtml8
-rw-r--r--site/app/locale/de/pages/policy.thtml110
-rw-r--r--site/app/locale/de/pages/reviewguide.thtml109
-rw-r--r--site/app/locale/de/pages/sandbox.thtml13
-rw-r--r--site/app/locale/de/pages/submission_help.thtml35
-rw-r--r--site/app/locale/el/LC_MESSAGES/messages.mobin0 -> 206077 bytes
-rw-r--r--site/app/locale/el/LC_MESSAGES/messages.po7239
-rw-r--r--site/app/locale/el/images/sandbox-review.pngbin0 -> 20308 bytes
-rw-r--r--site/app/locale/el/pages/about.thtml45
-rw-r--r--site/app/locale/el/pages/collector.thtml47
-rw-r--r--site/app/locale/el/pages/collector_faq.thtml24
-rw-r--r--site/app/locale/el/pages/collector_features.thtml27
-rw-r--r--site/app/locale/el/pages/collector_firstrun.thtml38
-rw-r--r--site/app/locale/el/pages/compatibility_user_tips.thtml6
-rw-r--r--site/app/locale/el/pages/error404.thtml16
-rw-r--r--site/app/locale/el/pages/faq.thtml78
-rw-r--r--site/app/locale/el/pages/nomination.thtml10
-rw-r--r--site/app/locale/el/pages/reviewguide.thtml85
-rw-r--r--site/app/locale/el/pages/sandbox.thtml13
-rw-r--r--site/app/locale/el/pages/statistics_help.thtml7
-rw-r--r--site/app/locale/el/pages/submission_help.thtml35
-rw-r--r--site/app/locale/en_US/LC_MESSAGES/messages.mobin0 -> 133034 bytes
-rw-r--r--site/app/locale/en_US/LC_MESSAGES/messages.po7248
-rw-r--r--site/app/locale/en_US/images/sandbox-review.pngbin0 -> 17151 bytes
-rw-r--r--site/app/locale/en_US/pages/about.thtml65
-rw-r--r--site/app/locale/en_US/pages/collector.thtml47
-rw-r--r--site/app/locale/en_US/pages/collector_faq.thtml24
-rw-r--r--site/app/locale/en_US/pages/collector_features.thtml33
-rw-r--r--site/app/locale/en_US/pages/collector_firstrun.thtml38
-rw-r--r--site/app/locale/en_US/pages/compatibility_developer_tips.thtml6
-rw-r--r--site/app/locale/en_US/pages/compatibility_user_tips.thtml6
-rw-r--r--site/app/locale/en_US/pages/developer_agreement.thtml215
-rw-r--r--site/app/locale/en_US/pages/developer_faq.thtml275
-rw-r--r--site/app/locale/en_US/pages/error404.thtml16
-rwxr-xr-xsite/app/locale/en_US/pages/faq.thtml78
-rw-r--r--site/app/locale/en_US/pages/fashion_faq.thtml56
-rw-r--r--site/app/locale/en_US/pages/nomination.thtml10
-rw-r--r--site/app/locale/en_US/pages/policy.thtml112
-rw-r--r--site/app/locale/en_US/pages/privacy.thtml162
-rw-r--r--site/app/locale/en_US/pages/reviewguide.thtml90
-rw-r--r--site/app/locale/en_US/pages/sandbox.thtml13
-rw-r--r--site/app/locale/en_US/pages/statistics_help.thtml7
-rw-r--r--site/app/locale/en_US/pages/submission_help.thtml35
-rw-r--r--site/app/locale/es_ES/LC_MESSAGES/messages.mobin0 -> 123255 bytes
-rw-r--r--site/app/locale/es_ES/LC_MESSAGES/messages.po8241
-rw-r--r--site/app/locale/es_ES/images/sandbox-review.pngbin0 -> 19029 bytes
-rw-r--r--site/app/locale/es_ES/pages/error404.thtml16
-rw-r--r--site/app/locale/es_ES/pages/nomination.thtml9
-rw-r--r--site/app/locale/es_ES/pages/policy.thtml111
-rw-r--r--site/app/locale/es_ES/pages/reviewguide.thtml66
-rw-r--r--site/app/locale/es_ES/pages/sandbox.thtml13
-rw-r--r--site/app/locale/es_ES/pages/submission_help.thtml35
-rw-r--r--site/app/locale/eu/LC_MESSAGES/messages.mobin0 -> 53801 bytes
-rw-r--r--site/app/locale/eu/LC_MESSAGES/messages.po8854
-rw-r--r--site/app/locale/eu/images/sandbox-review.pngbin0 -> 18963 bytes
-rw-r--r--site/app/locale/eu/pages/error404.thtml16
-rw-r--r--site/app/locale/eu/pages/nomination.thtml8
-rw-r--r--site/app/locale/eu/pages/policy.thtml111
-rw-r--r--site/app/locale/eu/pages/sandbox.thtml13
-rw-r--r--site/app/locale/eu/pages/submission_help.thtml35
-rwxr-xr-xsite/app/locale/extract-po.sh18
-rw-r--r--site/app/locale/fa/LC_MESSAGES/messages.mobin0 -> 153181 bytes
-rw-r--r--site/app/locale/fa/LC_MESSAGES/messages.po7248
-rw-r--r--site/app/locale/fa/images/sandbox-review.pngbin0 -> 22562 bytes
-rw-r--r--site/app/locale/fa/pages/error404.thtml16
-rw-r--r--site/app/locale/fa/pages/faq.thtml56
-rw-r--r--site/app/locale/fa/pages/nomination.thtml10
-rw-r--r--site/app/locale/fa/pages/policy.thtml111
-rw-r--r--site/app/locale/fa/pages/privacy.thtml164
-rw-r--r--site/app/locale/fa/pages/reviewguide.thtml92
-rw-r--r--site/app/locale/fa/pages/sandbox.thtml13
-rw-r--r--site/app/locale/fa/pages/statistics_help.thtml7
-rw-r--r--site/app/locale/fa/pages/submission_help.thtml35
-rw-r--r--site/app/locale/fi/LC_MESSAGES/messages.mobin0 -> 50067 bytes
-rw-r--r--site/app/locale/fi/LC_MESSAGES/messages.po8805
-rw-r--r--site/app/locale/fi/images/sandbox-review.pngbin0 -> 17250 bytes
-rw-r--r--site/app/locale/fi/pages/error404.thtml16
-rw-r--r--site/app/locale/fi/pages/nomination.thtml8
-rw-r--r--site/app/locale/fi/pages/policy.thtml110
-rw-r--r--site/app/locale/fi/pages/sandbox.thtml13
-rw-r--r--site/app/locale/fi/pages/submission_help.thtml35
-rw-r--r--site/app/locale/fr/LC_MESSAGES/messages.mobin0 -> 78983 bytes
-rw-r--r--site/app/locale/fr/LC_MESSAGES/messages.po8610
-rw-r--r--site/app/locale/fr/images/sandbox-review.pngbin0 -> 17008 bytes
-rw-r--r--site/app/locale/fr/pages/error404.thtml16
-rw-r--r--site/app/locale/fr/pages/nomination.thtml9
-rw-r--r--site/app/locale/fr/pages/sandbox.thtml13
-rw-r--r--site/app/locale/fr/pages/submission_help.thtml35
-rw-r--r--site/app/locale/fy_NL/LC_MESSAGES/messages.mobin0 -> 438 bytes
-rw-r--r--site/app/locale/fy_NL/LC_MESSAGES/messages.po9576
-rw-r--r--site/app/locale/ga_IE/LC_MESSAGES/messages.mobin0 -> 91880 bytes
-rw-r--r--site/app/locale/ga_IE/LC_MESSAGES/messages.po7943
-rw-r--r--site/app/locale/ga_IE/images/sandbox-review.pngbin0 -> 17231 bytes
-rw-r--r--site/app/locale/ga_IE/pages/error404.thtml16
-rw-r--r--site/app/locale/ga_IE/pages/nomination.thtml10
-rw-r--r--site/app/locale/ga_IE/pages/sandbox.thtml13
-rw-r--r--site/app/locale/ga_IE/pages/statistics_help.thtml7
-rw-r--r--site/app/locale/ga_IE/pages/submission_help.thtml35
-rw-r--r--site/app/locale/he/LC_MESSAGES/messages.mobin0 -> 67224 bytes
-rw-r--r--site/app/locale/he/LC_MESSAGES/messages.po8639
-rw-r--r--site/app/locale/he/pages/error404.thtml16
-rw-r--r--site/app/locale/he/pages/nomination.thtml10
-rw-r--r--site/app/locale/he/pages/submission_help.thtml35
-rw-r--r--site/app/locale/hu/LC_MESSAGES/messages.mobin0 -> 74785 bytes
-rw-r--r--site/app/locale/hu/LC_MESSAGES/messages.po8676
-rw-r--r--site/app/locale/hu/images/sandbox-review.pngbin0 -> 16425 bytes
-rw-r--r--site/app/locale/hu/pages/about.thtml45
-rw-r--r--site/app/locale/hu/pages/compatibility_developer_tips.thtml6
-rw-r--r--site/app/locale/hu/pages/compatibility_user_tips.thtml6
-rw-r--r--site/app/locale/hu/pages/error404.thtml16
-rw-r--r--site/app/locale/hu/pages/faq.thtml56
-rw-r--r--site/app/locale/hu/pages/fashion_faq.thtml56
-rw-r--r--site/app/locale/hu/pages/nomination.thtml10
-rw-r--r--site/app/locale/hu/pages/policy.thtml110
-rw-r--r--site/app/locale/hu/pages/reviewguide.thtml66
-rw-r--r--site/app/locale/hu/pages/sandbox.thtml13
-rw-r--r--site/app/locale/hu/pages/statistics_help.thtml7
-rw-r--r--site/app/locale/hu/pages/submission_help.thtml35
-rw-r--r--site/app/locale/id/LC_MESSAGES/messages.mobin0 -> 73928 bytes
-rw-r--r--site/app/locale/id/LC_MESSAGES/messages.po8586
-rw-r--r--site/app/locale/id/images/sandbox-review.pngbin0 -> 15630 bytes
-rw-r--r--site/app/locale/id/pages/compatibility_developer_tips.thtml6
-rw-r--r--site/app/locale/id/pages/compatibility_user_tips.thtml6
-rw-r--r--site/app/locale/id/pages/error404.thtml16
-rw-r--r--site/app/locale/id/pages/nomination.thtml10
-rw-r--r--site/app/locale/id/pages/policy.thtml111
-rw-r--r--site/app/locale/id/pages/reviewguide.thtml113
-rw-r--r--site/app/locale/id/pages/sandbox.thtml13
-rw-r--r--site/app/locale/id/pages/statistics_help.thtml7
-rw-r--r--site/app/locale/id/pages/submission_help.thtml35
-rw-r--r--site/app/locale/it/LC_MESSAGES/messages.mobin0 -> 146414 bytes
-rw-r--r--site/app/locale/it/LC_MESSAGES/messages.po7544
-rw-r--r--site/app/locale/it/images/sandbox-review.pngbin0 -> 18706 bytes
-rw-r--r--site/app/locale/it/pages/error404.thtml16
-rw-r--r--site/app/locale/it/pages/nomination.thtml8
-rw-r--r--site/app/locale/it/pages/policy.thtml110
-rw-r--r--site/app/locale/it/pages/sandbox.thtml13
-rw-r--r--site/app/locale/it/pages/statistics_help.thtml8
-rw-r--r--site/app/locale/it/pages/submission_help.thtml35
-rw-r--r--site/app/locale/ja/LC_MESSAGES/messages.mobin0 -> 164371 bytes
-rw-r--r--site/app/locale/ja/LC_MESSAGES/messages.po7351
-rw-r--r--site/app/locale/ja/images/sandbox-review.pngbin0 -> 26790 bytes
-rw-r--r--site/app/locale/ja/pages/about.thtml27
-rw-r--r--site/app/locale/ja/pages/compatibility_developer_tips.thtml6
-rw-r--r--site/app/locale/ja/pages/compatibility_user_tips.thtml6
-rw-r--r--site/app/locale/ja/pages/error404.thtml12
-rw-r--r--site/app/locale/ja/pages/faq.thtml56
-rw-r--r--site/app/locale/ja/pages/nomination.thtml9
-rw-r--r--site/app/locale/ja/pages/policy.thtml79
-rw-r--r--site/app/locale/ja/pages/sandbox.thtml12
-rw-r--r--site/app/locale/ja/pages/statistics_help.thtml8
-rw-r--r--site/app/locale/ja/pages/submission_help.thtml35
-rw-r--r--site/app/locale/ko/LC_MESSAGES/messages.mobin0 -> 61333 bytes
-rw-r--r--site/app/locale/ko/LC_MESSAGES/messages.po8738
-rw-r--r--site/app/locale/ko/images/sandbox-review.pngbin0 -> 16330 bytes
-rw-r--r--site/app/locale/ko/pages/error404.thtml16
-rw-r--r--site/app/locale/ko/pages/nomination.thtml10
-rw-r--r--site/app/locale/ko/pages/policy.thtml118
-rw-r--r--site/app/locale/ko/pages/sandbox.thtml15
-rw-r--r--site/app/locale/ko/pages/statistics_help.thtml8
-rw-r--r--site/app/locale/ko/pages/submission_help.thtml41
-rwxr-xr-xsite/app/locale/merge-enus2all.sh9
-rwxr-xr-xsite/app/locale/merge-po.sh22
-rw-r--r--site/app/locale/mn/LC_MESSAGES/messages.mobin0 -> 78567 bytes
-rw-r--r--site/app/locale/mn/LC_MESSAGES/messages.po8732
-rw-r--r--site/app/locale/mn/images/sandbox-review.pngbin0 -> 18561 bytes
-rw-r--r--site/app/locale/mn/pages/error404.thtml16
-rw-r--r--site/app/locale/mn/pages/nomination.thtml8
-rw-r--r--site/app/locale/mn/pages/policy.thtml110
-rw-r--r--site/app/locale/mn/pages/sandbox.thtml13
-rw-r--r--site/app/locale/mn/pages/submission_help.thtml35
-rw-r--r--site/app/locale/nl/LC_MESSAGES/messages.mobin0 -> 142039 bytes
-rw-r--r--site/app/locale/nl/LC_MESSAGES/messages.po7338
-rw-r--r--site/app/locale/nl/images/sandbox-review.pngbin0 -> 18015 bytes
-rw-r--r--site/app/locale/nl/pages/about.thtml47
-rw-r--r--site/app/locale/nl/pages/collector_features.thtml27
-rw-r--r--site/app/locale/nl/pages/compatibility_developer_tips.thtml6
-rw-r--r--site/app/locale/nl/pages/compatibility_user_tips.thtml6
-rw-r--r--site/app/locale/nl/pages/developer_faq.thtml44
-rw-r--r--site/app/locale/nl/pages/error404.thtml16
-rw-r--r--site/app/locale/nl/pages/faq.thtml65
-rw-r--r--site/app/locale/nl/pages/nomination.thtml10
-rw-r--r--site/app/locale/nl/pages/policy.thtml110
-rw-r--r--site/app/locale/nl/pages/reviewguide.thtml66
-rw-r--r--site/app/locale/nl/pages/sandbox.thtml13
-rw-r--r--site/app/locale/nl/pages/statistics_help.thtml7
-rw-r--r--site/app/locale/nl/pages/submission_help.thtml35
-rw-r--r--site/app/locale/pl/LC_MESSAGES/messages.mobin0 -> 142584 bytes
-rw-r--r--site/app/locale/pl/LC_MESSAGES/messages.po7084
-rw-r--r--site/app/locale/pl/images/sandbox-review.pngbin0 -> 18937 bytes
-rw-r--r--site/app/locale/pl/pages/about.thtml63
-rw-r--r--site/app/locale/pl/pages/collector.thtml47
-rw-r--r--site/app/locale/pl/pages/collector_faq.thtml24
-rw-r--r--site/app/locale/pl/pages/collector_firstrun.thtml38
-rw-r--r--site/app/locale/pl/pages/compatibility_developer_tips.thtml6
-rw-r--r--site/app/locale/pl/pages/compatibility_user_tips.thtml6
-rw-r--r--site/app/locale/pl/pages/developer_faq.thtml226
-rw-r--r--site/app/locale/pl/pages/error404.thtml16
-rw-r--r--site/app/locale/pl/pages/nomination.thtml10
-rw-r--r--site/app/locale/pl/pages/policy.thtml229
-rw-r--r--site/app/locale/pl/pages/sandbox.thtml13
-rw-r--r--site/app/locale/pl/pages/statistics_help.thtml7
-rw-r--r--site/app/locale/pl/pages/submission_help.thtml35
-rw-r--r--site/app/locale/pt_BR/LC_MESSAGES/messages.mobin0 -> 122314 bytes
-rw-r--r--site/app/locale/pt_BR/LC_MESSAGES/messages.po8216
-rw-r--r--site/app/locale/pt_BR/images/sandbox-review.pngbin0 -> 15545 bytes
-rw-r--r--site/app/locale/pt_BR/pages/error404.thtml17
-rw-r--r--site/app/locale/pt_BR/pages/nomination.thtml10
-rw-r--r--site/app/locale/pt_BR/pages/policy.thtml113
-rw-r--r--site/app/locale/pt_BR/pages/sandbox.thtml13
-rw-r--r--site/app/locale/pt_BR/pages/statistics_help.thtml7
-rw-r--r--site/app/locale/pt_BR/pages/submission_help.thtml69
-rw-r--r--site/app/locale/pt_PT/LC_MESSAGES/messages.mobin0 -> 136700 bytes
-rw-r--r--site/app/locale/pt_PT/LC_MESSAGES/messages.po7995
-rw-r--r--site/app/locale/pt_PT/images/sandbox-review.pngbin0 -> 15854 bytes
-rw-r--r--site/app/locale/pt_PT/pages/error404.thtml16
-rw-r--r--site/app/locale/pt_PT/pages/extension_features.thtml30
-rw-r--r--site/app/locale/pt_PT/pages/nomination.thtml10
-rw-r--r--site/app/locale/pt_PT/pages/policy.thtml112
-rw-r--r--site/app/locale/pt_PT/pages/sandbox.thtml13
-rw-r--r--site/app/locale/pt_PT/pages/submission_help.thtml35
-rw-r--r--site/app/locale/ro/LC_MESSAGES/messages.mobin0 -> 90355 bytes
-rw-r--r--site/app/locale/ro/LC_MESSAGES/messages.po7037
-rw-r--r--site/app/locale/ro/images/sandbox-review.pngbin0 -> 17200 bytes
-rw-r--r--site/app/locale/ro/pages/error404.thtml16
-rw-r--r--site/app/locale/ro/pages/nomination.thtml8
-rw-r--r--site/app/locale/ro/pages/sandbox.thtml13
-rw-r--r--site/app/locale/ro/pages/submission_help.thtml35
-rw-r--r--site/app/locale/ru/LC_MESSAGES/messages.mobin0 -> 196629 bytes
-rw-r--r--site/app/locale/ru/LC_MESSAGES/messages.po8139
-rw-r--r--site/app/locale/ru/images/sandbox-review.pngbin0 -> 18219 bytes
-rw-r--r--site/app/locale/ru/pages/about.thtml67
-rw-r--r--site/app/locale/ru/pages/error404.thtml16
-rw-r--r--site/app/locale/ru/pages/nomination.thtml9
-rw-r--r--site/app/locale/ru/pages/sandbox.thtml13
-rw-r--r--site/app/locale/ru/pages/submission_help.thtml35
-rw-r--r--site/app/locale/sk/LC_MESSAGES/messages.mobin0 -> 142505 bytes
-rw-r--r--site/app/locale/sk/LC_MESSAGES/messages.po7258
-rw-r--r--site/app/locale/sk/images/sandbox-review.pngbin0 -> 22600 bytes
-rw-r--r--site/app/locale/sk/pages/collector.thtml47
-rw-r--r--site/app/locale/sk/pages/collector_faq.thtml24
-rw-r--r--site/app/locale/sk/pages/collector_features.thtml33
-rw-r--r--site/app/locale/sk/pages/collector_firstrun.thtml38
-rw-r--r--site/app/locale/sk/pages/error404.thtml16
-rw-r--r--site/app/locale/sk/pages/nomination.thtml10
-rw-r--r--site/app/locale/sk/pages/policy.thtml110
-rw-r--r--site/app/locale/sk/pages/reviewguide.thtml83
-rw-r--r--site/app/locale/sk/pages/sandbox.thtml13
-rw-r--r--site/app/locale/sk/pages/statistics_help.thtml7
-rw-r--r--site/app/locale/sk/pages/submission_help.thtml35
-rw-r--r--site/app/locale/sq/LC_MESSAGES/messages.mobin0 -> 115872 bytes
-rw-r--r--site/app/locale/sq/LC_MESSAGES/messages.po7582
-rw-r--r--site/app/locale/sq/images/sandbox-review.pngbin0 -> 17612 bytes
-rw-r--r--site/app/locale/sq/pages/about.thtml56
-rw-r--r--site/app/locale/sq/pages/collector_features.thtml29
-rw-r--r--site/app/locale/sq/pages/compatibility_developer_tips.thtml6
-rw-r--r--site/app/locale/sq/pages/compatibility_user_tips.thtml6
-rw-r--r--site/app/locale/sq/pages/developer_faq.thtml62
-rw-r--r--site/app/locale/sq/pages/error404.thtml17
-rw-r--r--site/app/locale/sq/pages/experimental_addons.thtml24
-rwxr-xr-xsite/app/locale/sq/pages/faq.thtml78
-rw-r--r--site/app/locale/sq/pages/fashion_faq.thtml72
-rw-r--r--site/app/locale/sq/pages/nomination.thtml16
-rw-r--r--site/app/locale/sq/pages/policy.thtml115
-rw-r--r--site/app/locale/sq/pages/reviewguide.thtml68
-rw-r--r--site/app/locale/sq/pages/sandbox.thtml13
-rw-r--r--site/app/locale/sq/pages/statistics_help.thtml7
-rw-r--r--site/app/locale/sq/pages/submission_help.thtml36
-rwxr-xr-xsite/app/locale/stats-po.sh13
-rw-r--r--site/app/locale/sv_SE/LC_MESSAGES/messages.mobin0 -> 134232 bytes
-rw-r--r--site/app/locale/sv_SE/LC_MESSAGES/messages.po7940
-rw-r--r--site/app/locale/sv_SE/pages/error404.thtml16
-rw-r--r--site/app/locale/sv_SE/pages/nomination.thtml10
-rw-r--r--site/app/locale/sv_SE/pages/policy.thtml112
-rw-r--r--site/app/locale/sv_SE/pages/reviewguide.thtml70
-rw-r--r--site/app/locale/sv_SE/pages/sandbox.thtml15
-rw-r--r--site/app/locale/sv_SE/pages/statistics_help.thtml7
-rw-r--r--site/app/locale/sv_SE/pages/submission_help.thtml35
-rw-r--r--site/app/locale/tr/LC_MESSAGES/messages.mobin0 -> 24475 bytes
-rw-r--r--site/app/locale/tr/LC_MESSAGES/messages.po9193
-rw-r--r--site/app/locale/uk/LC_MESSAGES/messages.mobin0 -> 86601 bytes
-rw-r--r--site/app/locale/uk/LC_MESSAGES/messages.po8611
-rw-r--r--site/app/locale/uk/images/sandbox-review.pngbin0 -> 28135 bytes
-rw-r--r--site/app/locale/uk/pages/error404.thtml16
-rw-r--r--site/app/locale/uk/pages/nomination.thtml10
-rw-r--r--site/app/locale/uk/pages/policy.thtml110
-rw-r--r--site/app/locale/uk/pages/sandbox.thtml13
-rw-r--r--site/app/locale/uk/pages/submission_help.thtml37
-rw-r--r--site/app/locale/vi/LC_MESSAGES/messages.mobin0 -> 158903 bytes
-rw-r--r--site/app/locale/vi/LC_MESSAGES/messages.po7520
-rw-r--r--site/app/locale/vi/images/sandbox-review.pngbin0 -> 16455 bytes
-rw-r--r--site/app/locale/vi/pages/about.thtml66
-rw-r--r--site/app/locale/vi/pages/collector.thtml47
-rw-r--r--site/app/locale/vi/pages/collector_faq.thtml24
-rw-r--r--site/app/locale/vi/pages/collector_features.thtml30
-rw-r--r--site/app/locale/vi/pages/collector_firstrun.thtml38
-rw-r--r--site/app/locale/vi/pages/compatibility_developer_tips.thtml6
-rw-r--r--site/app/locale/vi/pages/compatibility_user_tips.thtml6
-rw-r--r--site/app/locale/vi/pages/error404.thtml16
-rw-r--r--site/app/locale/vi/pages/faq.thtml60
-rw-r--r--site/app/locale/vi/pages/fashion_faq.thtml57
-rw-r--r--site/app/locale/vi/pages/nomination.thtml10
-rw-r--r--site/app/locale/vi/pages/policy.thtml112
-rw-r--r--site/app/locale/vi/pages/reviewguide.thtml90
-rw-r--r--site/app/locale/vi/pages/sandbox.thtml13
-rw-r--r--site/app/locale/vi/pages/statistics_help.thtml7
-rw-r--r--site/app/locale/vi/pages/submission_help.thtml35
-rw-r--r--site/app/locale/zh_CN/LC_MESSAGES/messages.mobin0 -> 66584 bytes
-rw-r--r--site/app/locale/zh_CN/LC_MESSAGES/messages.po8584
-rw-r--r--site/app/locale/zh_CN/images/sandbox-review.pngbin0 -> 6945 bytes
-rw-r--r--site/app/locale/zh_CN/pages/error404.thtml16
-rw-r--r--site/app/locale/zh_CN/pages/nomination.thtml10
-rw-r--r--site/app/locale/zh_CN/pages/policy.thtml110
-rw-r--r--site/app/locale/zh_CN/pages/sandbox.thtml14
-rw-r--r--site/app/locale/zh_CN/pages/statistics_help.thtml7
-rw-r--r--site/app/locale/zh_CN/pages/submission_help.thtml36
-rw-r--r--site/app/locale/zh_TW/LC_MESSAGES/messages.mobin0 -> 130517 bytes
-rw-r--r--site/app/locale/zh_TW/LC_MESSAGES/messages.po6992
-rw-r--r--site/app/locale/zh_TW/images/sandbox-review.pngbin0 -> 6785 bytes
-rw-r--r--site/app/locale/zh_TW/pages/about.thtml57
-rw-r--r--site/app/locale/zh_TW/pages/collector.thtml45
-rw-r--r--site/app/locale/zh_TW/pages/collector_faq.thtml24
-rw-r--r--site/app/locale/zh_TW/pages/collector_features.thtml30
-rw-r--r--site/app/locale/zh_TW/pages/collector_firstrun.thtml38
-rw-r--r--site/app/locale/zh_TW/pages/compatibility_developer_tips.thtml6
-rw-r--r--site/app/locale/zh_TW/pages/compatibility_user_tips.thtml6
-rw-r--r--site/app/locale/zh_TW/pages/developer_faq.thtml55
-rw-r--r--site/app/locale/zh_TW/pages/error404.thtml16
-rw-r--r--site/app/locale/zh_TW/pages/faq.thtml78
-rw-r--r--site/app/locale/zh_TW/pages/nomination.thtml10
-rw-r--r--site/app/locale/zh_TW/pages/policy.thtml110
-rw-r--r--site/app/locale/zh_TW/pages/sandbox.thtml13
-rw-r--r--site/app/locale/zh_TW/pages/statistics_help.thtml8
-rw-r--r--site/app/locale/zh_TW/pages/submission_help.thtml35
-rw-r--r--site/app/models/addon.php883
-rw-r--r--site/app/models/addon_collection.php222
-rw-r--r--site/app/models/addon_tag.php90
-rw-r--r--site/app/models/addontype.php110
-rw-r--r--site/app/models/api_auth_token.php190
-rw-r--r--site/app/models/application.php142
-rw-r--r--site/app/models/approval.php56
-rw-r--r--site/app/models/appversion.php80
-rw-r--r--site/app/models/blapp.php44
-rw-r--r--site/app/models/blitem.php54
-rw-r--r--site/app/models/blplugin.php43
-rw-r--r--site/app/models/cake_session.php45
-rw-r--r--site/app/models/cannedresponse.php47
-rw-r--r--site/app/models/collection.php630
-rw-r--r--site/app/models/collection_promo.php140
-rw-r--r--site/app/models/config.php88
-rw-r--r--site/app/models/dbo/dbo_amo_mysql.php270
-rw-r--r--site/app/models/download.php45
-rw-r--r--site/app/models/editor_subscription.php94
-rw-r--r--site/app/models/eventlog.php63
-rw-r--r--site/app/models/facebook_data.php118
-rw-r--r--site/app/models/facebook_detected.php65
-rw-r--r--site/app/models/facebook_favorite.php200
-rw-r--r--site/app/models/facebook_session.php65
-rw-r--r--site/app/models/facebook_user.php114
-rw-r--r--site/app/models/favorite.php43
-rw-r--r--site/app/models/feature.php45
-rw-r--r--site/app/models/file.php113
-rw-r--r--site/app/models/global_stat.php55
-rw-r--r--site/app/models/group.php57
-rw-r--r--site/app/models/license.php89
-rw-r--r--site/app/models/memcaching.php296
-rw-r--r--site/app/models/platform.php93
-rw-r--r--site/app/models/preview.php97
-rw-r--r--site/app/models/review.php308
-rw-r--r--site/app/models/reviewrating.php56
-rw-r--r--site/app/models/reviews_moderation_flag.php77
-rw-r--r--site/app/models/tag.php134
-rw-r--r--site/app/models/translation.php60
-rw-r--r--site/app/models/update_count.php57
-rw-r--r--site/app/models/user.php316
-rw-r--r--site/app/models/version.php305
-rw-r--r--site/app/tests/amo-selenium.html412
-rw-r--r--site/app/tests/app_controller.test.php80
-rw-r--r--site/app/tests/bot_reporter.php41
-rw-r--r--site/app/tests/cake_reporter.php181
-rw-r--r--site/app/tests/controllers/addons_controller.test.php117
-rw-r--r--site/app/tests/controllers/admin_controller.test.php71
-rw-r--r--site/app/tests/controllers/api_controller.test.php33
-rw-r--r--site/app/tests/controllers/compatibility_controller.test.php31
-rw-r--r--site/app/tests/controllers/components/amo.test.php122
-rw-r--r--site/app/tests/controllers/components/audit.test.php286
-rw-r--r--site/app/tests/controllers/components/developers.test.php420
-rw-r--r--site/app/tests/controllers/components/error.test.php69
-rw-r--r--site/app/tests/controllers/components/image.test.php42
-rw-r--r--site/app/tests/controllers/components/opensearch.test.php349
-rw-r--r--site/app/tests/controllers/components/rdf.test.php78
-rw-r--r--site/app/tests/controllers/components/simple_acl.test.php121
-rw-r--r--site/app/tests/controllers/components/src.test.php86
-rw-r--r--site/app/tests/controllers/components/versioncompare.test.php130
-rw-r--r--site/app/tests/controllers/developers_controller.test.php73
-rw-r--r--site/app/tests/controllers/downloads_controller.test.php77
-rw-r--r--site/app/tests/controllers/editors_controller.test.php329
-rw-r--r--site/app/tests/controllers/groups_controller.test.php79
-rw-r--r--site/app/tests/controllers/legacy_url_controller.test.php11
-rw-r--r--site/app/tests/controllers/reviews_controller.test.php49
-rw-r--r--site/app/tests/controllers/search_controller.test.php140
-rw-r--r--site/app/tests/controllers/sharing_api_controller.test.php1506
-rw-r--r--site/app/tests/controllers/users_controller.test.php342
-rw-r--r--site/app/tests/data/base-icon.pngbin0 -> 3740 bytes
-rwxr-xr-xsite/app/tests/data/extension-noinstall.xpibin0 -> 162 bytes
-rwxr-xr-xsite/app/tests/data/extension-works.xpibin0 -> 629 bytes
-rw-r--r--site/app/tests/data/remora-test-data.sql1077
-rw-r--r--site/app/tests/data/remora-test-log.log27
-rw-r--r--site/app/tests/data/resized-icon.pngbin0 -> 1379 bytes
-rw-r--r--site/app/tests/data/test-install.rdf34
-rw-r--r--site/app/tests/database.test.php154
-rw-r--r--site/app/tests/facebook-selenium359
-rw-r--r--site/app/tests/global.test.php50
-rw-r--r--site/app/tests/groups.php90
-rw-r--r--site/app/tests/installation.test.php220
-rw-r--r--site/app/tests/languageConfig.test.php291
-rw-r--r--site/app/tests/models/addon.test.php17
-rw-r--r--site/app/tests/models/app_model.test.php158
-rw-r--r--site/app/tests/models/collection.test.php60
-rw-r--r--site/app/tests/models/collection_promos.test.php66
-rw-r--r--site/app/tests/models/memcaching_model.test.php289
-rw-r--r--site/app/tests/models/memcaching_web.test.php112
-rw-r--r--site/app/tests/models/translation_model.test.php130
-rw-r--r--site/app/tests/models/user.test.php115
-rw-r--r--site/app/tests/multiapp.test.php80
-rw-r--r--site/app/tests/oldUrls.test.php88
-rw-r--r--site/app/tests/search.html467
-rw-r--r--site/app/tests/services/bin/maintenance.test.php53
-rw-r--r--site/app/tests/services/bin/parse_logs/count_downloads.test.php160
-rw-r--r--site/app/tests/services/bin/parse_logs/log_parser.test.php107
-rw-r--r--site/app/tests/services/bin/update-hashes.test.php53
-rw-r--r--site/app/tests/services/blocklist.test.php357
-rw-r--r--site/app/tests/services/pfs.test.php282
-rw-r--r--site/app/tests/services/update.test.php418
-rw-r--r--site/app/tests/testSuite.html10
-rw-r--r--site/app/tests/test_helper_unit.php316
-rw-r--r--site/app/tests/test_helper_web.php244
-rw-r--r--site/app/tests/test_manager.php190
-rw-r--r--site/app/tests/views/addons/dictionaries.test.php71
-rw-r--r--site/app/tests/views/addons/display.test.php222
-rw-r--r--site/app/tests/views/addons/home.test.php111
-rw-r--r--site/app/tests/views/addons/plugins.test.php91
-rw-r--r--site/app/tests/views/addons/policy.test.php106
-rw-r--r--site/app/tests/views/addons/previews.test.php83
-rw-r--r--site/app/tests/views/addons/rss/parserss.test.php77
-rw-r--r--site/app/tests/views/addons/searchengines.test.php93
-rw-r--r--site/app/tests/views/addons/versions.test.php125
-rw-r--r--site/app/tests/views/admin/addons_status.test.php27
-rw-r--r--site/app/tests/views/admin/serverstatus.test.php98
-rw-r--r--site/app/tests/views/developers/add.test.php62
-rw-r--r--site/app/tests/views/developers/edit.test.php94
-rw-r--r--site/app/tests/views/developers/editversion.test.php84
-rw-r--r--site/app/tests/views/developers/index.test.php69
-rw-r--r--site/app/tests/views/elements/install.test.php91
-rw-r--r--site/app/tests/views/helpers/addons_html.test.php118
-rw-r--r--site/app/tests/views/helpers/localization.test.php53
-rw-r--r--site/app/tests/views/helpers/statistics.test.php66
-rw-r--r--site/app/tests/views/images/show.test.php116
-rw-r--r--site/app/tests/views/reviews/add.test.php75
-rw-r--r--site/app/tests/views/reviews/display.test.php75
-rw-r--r--site/app/tests/views/search/index.test.php57
-rw-r--r--site/app/tests/views/search/rss/index.test.php57
-rw-r--r--site/app/tests/views/users/pwreset.test.php32
-rw-r--r--site/app/views/addons.php111
-rw-r--r--site/app/views/addons/ajaxy.thtml42
-rw-r--r--site/app/views/addons/browse.thtml75
-rw-r--r--site/app/views/addons/browse_thumbs.thtml148
-rw-r--r--site/app/views/addons/category_landing.thtml178
-rw-r--r--site/app/views/addons/dictionaries.thtml111
-rw-r--r--site/app/views/addons/display.thtml521
-rw-r--r--site/app/views/addons/home.thtml180
-rw-r--r--site/app/views/addons/plugins.thtml141
-rw-r--r--site/app/views/addons/policy.thtml122
-rw-r--r--site/app/views/addons/previews.thtml62
-rw-r--r--site/app/views/addons/recommended.thtml64
-rw-r--r--site/app/views/addons/rss/addons.thtml66
-rw-r--r--site/app/views/addons/rss/categories.thtml50
-rw-r--r--site/app/views/addons/rss/searchengines.thtml48
-rw-r--r--site/app/views/addons/rss/versions.thtml60
-rw-r--r--site/app/views/addons/searchengines.thtml95
-rw-r--r--site/app/views/addons/share.thtml24
-rw-r--r--site/app/views/addons/themes_landing.thtml75
-rw-r--r--site/app/views/addons/versions.thtml144
-rw-r--r--site/app/views/admin/addons.thtml65
-rw-r--r--site/app/views/admin/addons_status.thtml85
-rw-r--r--site/app/views/admin/addontypes_edit.thtml58
-rw-r--r--site/app/views/admin/applications.thtml82
-rw-r--r--site/app/views/admin/applications_create.thtml66
-rw-r--r--site/app/views/admin/applications_edit.thtml66
-rw-r--r--site/app/views/admin/collections.thtml46
-rw-r--r--site/app/views/admin/collections_promobox.thtml112
-rw-r--r--site/app/views/admin/config.thtml142
-rw-r--r--site/app/views/admin/config_login.thtml61
-rw-r--r--site/app/views/admin/features.thtml130
-rw-r--r--site/app/views/admin/flagged_queue.thtml96
-rw-r--r--site/app/views/admin/groups.thtml93
-rw-r--r--site/app/views/admin/groups_create.thtml65
-rw-r--r--site/app/views/admin/groups_edit.thtml67
-rw-r--r--site/app/views/admin/lists.thtml49
-rw-r--r--site/app/views/admin/log_details.thtml51
-rw-r--r--site/app/views/admin/logs.thtml97
-rw-r--r--site/app/views/admin/platforms.thtml55
-rw-r--r--site/app/views/admin/platforms_create.thtml58
-rw-r--r--site/app/views/admin/platforms_edit.thtml59
-rw-r--r--site/app/views/admin/responses.thtml56
-rw-r--r--site/app/views/admin/responses_create.thtml58
-rw-r--r--site/app/views/admin/responses_edit.thtml59
-rw-r--r--site/app/views/admin/serverstatus.thtml101
-rw-r--r--site/app/views/admin/summary.thtml125
-rw-r--r--site/app/views/admin/tags.thtml59
-rw-r--r--site/app/views/admin/tags_create.thtml66
-rw-r--r--site/app/views/admin/tags_edit.thtml71
-rw-r--r--site/app/views/admin/userlookup.thtml10
-rw-r--r--site/app/views/admin/users.thtml65
-rw-r--r--site/app/views/admin/users_edit.thtml148
-rw-r--r--site/app/views/admin/variables.thtml57
-rw-r--r--site/app/views/api/addon.thtml44
-rw-r--r--site/app/views/api/api_addon.thtml167
-rw-r--r--site/app/views/api/collections_feed.thtml153
-rw-r--r--site/app/views/api/cumulative_downloads.thtml47
-rw-r--r--site/app/views/api/get_language_packs.thtml52
-rw-r--r--site/app/views/api/list_addons.thtml50
-rw-r--r--site/app/views/api/search.thtml57
-rw-r--r--site/app/views/api/update_pings.thtml90
-rw-r--r--site/app/views/collections/add.thtml124
-rw-r--r--site/app/views/collections/ajax/addon_lookup.thtml49
-rw-r--r--site/app/views/collections/detail.thtml205
-rw-r--r--site/app/views/collections/edit.thtml347
-rw-r--r--site/app/views/collections/install.thtml149
-rw-r--r--site/app/views/collections/interactive.thtml164
-rw-r--r--site/app/views/collections/json.thtml14
-rw-r--r--site/app/views/collections/listing.thtml104
-rw-r--r--site/app/views/collections/rss/collection.thtml66
-rw-r--r--site/app/views/collections/subscribe.thtml116
-rw-r--r--site/app/views/collections/success.thtml108
-rw-r--r--site/app/views/compatibility/dashboard.thtml165
-rw-r--r--site/app/views/compatibility/developers.thtml82
-rw-r--r--site/app/views/compatibility/report.thtml74
-rw-r--r--site/app/views/compatibility/users.thtml52
-rw-r--r--site/app/views/developers/addon_edit.thtml57
-rw-r--r--site/app/views/developers/addon_edit_authors.thtml118
-rw-r--r--site/app/views/developers/addon_edit_categories.thtml107
-rw-r--r--site/app/views/developers/addon_edit_descriptions.thtml119
-rw-r--r--site/app/views/developers/addon_edit_properties.thtml215
-rw-r--r--site/app/views/developers/addon_status.thtml196
-rw-r--r--site/app/views/developers/addon_status_confirm.thtml80
-rw-r--r--site/app/views/developers/addon_status_nominate.thtml69
-rw-r--r--site/app/views/developers/dashboard.thtml118
-rw-r--r--site/app/views/developers/discuss.thtml85
-rw-r--r--site/app/views/developers/json.thtml14
-rw-r--r--site/app/views/developers/previews.thtml129
-rw-r--r--site/app/views/developers/uploader.thtml186
-rw-r--r--site/app/views/developers/versions.thtml94
-rw-r--r--site/app/views/developers/versions_delete.thtml63
-rw-r--r--site/app/views/developers/versions_edit.thtml262
-rw-r--r--site/app/views/downloads/file.thtml45
-rw-r--r--site/app/views/editors/ajax/addon_and_author_lookup.thtml12
-rw-r--r--site/app/views/editors/ajax/appversion_lookup.thtml44
-rw-r--r--site/app/views/editors/ajax/json.thtml7
-rw-r--r--site/app/views/editors/email/inforequest_plain.thtml13
-rw-r--r--site/app/views/editors/email/inforequest_reply_plain.thtml11
-rw-r--r--site/app/views/editors/email/nominated/public_plain.thtml17
-rw-r--r--site/app/views/editors/email/nominated/sandbox_plain.thtml12
-rw-r--r--site/app/views/editors/email/notify_update_plain.thtml19
-rw-r--r--site/app/views/editors/email/pending/public_plain.thtml20
-rw-r--r--site/app/views/editors/email/pending/sandbox_plain.thtml15
-rw-r--r--site/app/views/editors/email/superreview_plain.thtml19
-rw-r--r--site/app/views/editors/featured.thtml134
-rw-r--r--site/app/views/editors/logs.thtml63
-rw-r--r--site/app/views/editors/performance_charts.thtml156
-rw-r--r--site/app/views/editors/performance_table.thtml141
-rw-r--r--site/app/views/editors/queue.thtml191
-rw-r--r--site/app/views/editors/review.thtml327
-rw-r--r--site/app/views/editors/reviewlog.thtml114
-rw-r--r--site/app/views/editors/reviews_queue.thtml122
-rw-r--r--site/app/views/editors/summary.thtml108
-rw-r--r--site/app/views/elements/addon_author_addons.thtml65
-rw-r--r--site/app/views/elements/addon_categories.thtml75
-rw-r--r--site/app/views/elements/addon_discussionheader.thtml87
-rw-r--r--site/app/views/elements/addon_list_options.thtml110
-rw-r--r--site/app/views/elements/addon_listitem.thtml129
-rw-r--r--site/app/views/elements/addon_version_detail.thtml54
-rw-r--r--site/app/views/elements/amo2009/addon_list_options.thtml120
-rw-r--r--site/app/views/elements/amo2009/addon_version_detail.thtml53
-rw-r--r--site/app/views/elements/amo2009/breadcrumbs.thtml58
-rw-r--r--site/app/views/elements/amo2009/categories.thtml84
-rw-r--r--site/app/views/elements/amo2009/collection_add_form.thtml75
-rw-r--r--site/app/views/elements/amo2009/collection_listing_item.thtml95
-rw-r--r--site/app/views/elements/amo2009/collections_js_init.thtml76
-rw-r--r--site/app/views/elements/amo2009/collections_sidebar_whatare.thtml47
-rw-r--r--site/app/views/elements/amo2009/collections_sort_form.thtml57
-rw-r--r--site/app/views/elements/amo2009/collector_info_secondary.thtml76
-rw-r--r--site/app/views/elements/amo2009/collector_sidebar_download.thtml55
-rw-r--r--site/app/views/elements/amo2009/homepage_addon.thtml130
-rw-r--r--site/app/views/elements/amo2009/homepage_addon_listing.thtml76
-rw-r--r--site/app/views/elements/amo2009/install.thtml401
-rw-r--r--site/app/views/elements/amo2009/pagination.thtml51
-rw-r--r--site/app/views/elements/amo2009/reviews.thtml55
-rw-r--r--site/app/views/elements/amo2009/search.thtml414
-rw-r--r--site/app/views/elements/amo2009/stars.thtml59
-rw-r--r--site/app/views/elements/amo2009/teaser_collections.thtml122
-rw-r--r--site/app/views/elements/app_chooser.thtml54
-rw-r--r--site/app/views/elements/app_compatibility.thtml61
-rw-r--r--site/app/views/elements/categories.thtml99
-rw-r--r--site/app/views/elements/collections_install_item.thtml87
-rw-r--r--site/app/views/elements/collections_interactive_addon.thtml100
-rw-r--r--site/app/views/elements/developers/actionbar.thtml54
-rw-r--r--site/app/views/elements/developers/additem.thtml80
-rw-r--r--site/app/views/elements/developers/addonheader.thtml46
-rw-r--r--site/app/views/elements/developers/adminmenu.thtml97
-rw-r--r--site/app/views/elements/developers/editbox.thtml62
-rw-r--r--site/app/views/elements/developers/editors_review_history_item.thtml101
-rw-r--r--site/app/views/elements/developers/editorsmenu.thtml66
-rw-r--r--site/app/views/elements/developers/editorsqueue.thtml46
-rw-r--r--site/app/views/elements/developers/license_picker.thtml49
-rw-r--r--site/app/views/elements/developers/license_translationbox.thtml62
-rw-r--r--site/app/views/elements/developers/localebox.thtml98
-rw-r--r--site/app/views/elements/developers/localizermenu.thtml70
-rw-r--r--site/app/views/elements/developers/myaddons.thtml82
-rw-r--r--site/app/views/elements/developers/performanceheader.thtml64
-rw-r--r--site/app/views/elements/developers/rolecheck.thtml46
-rw-r--r--site/app/views/elements/developers/sidebar.thtml77
-rw-r--r--site/app/views/elements/developers/statsbar.thtml47
-rw-r--r--site/app/views/elements/extendfirefox.thtml11
-rw-r--r--site/app/views/elements/feature.thtml129
-rw-r--r--site/app/views/elements/footer.thtml82
-rw-r--r--site/app/views/elements/header.thtml165
-rw-r--r--site/app/views/elements/install.thtml303
-rw-r--r--site/app/views/elements/noscript.thtml43
-rw-r--r--site/app/views/elements/notification.thtml83
-rw-r--r--site/app/views/elements/pagination.thtml71
-rw-r--r--site/app/views/elements/pitch.thtml81
-rw-r--r--site/app/views/elements/recaptcha.thtml95
-rw-r--r--site/app/views/elements/rss_listitem.thtml60
-rw-r--r--site/app/views/elements/search.thtml325
-rw-r--r--site/app/views/elements/search_mini.thtml72
-rw-r--r--site/app/views/elements/sidebar.thtml57
-rw-r--r--site/app/views/elements/stars.thtml67
-rw-r--r--site/app/views/elements/translationbox.thtml158
-rw-r--r--site/app/views/errors/error401.thtml55
-rw-r--r--site/app/views/errors/error404.thtml75
l---------site/app/views/errors/missing_controller.thtml1
-rw-r--r--site/app/views/facebook/admin.thtml80
-rw-r--r--site/app/views/facebook/browse.thtml88
-rw-r--r--site/app/views/facebook/faq.thtml122
-rw-r--r--site/app/views/facebook/favorites.thtml147
-rw-r--r--site/app/views/facebook/home.thtml194
-rw-r--r--site/app/views/facebook/import.thtml245
-rw-r--r--site/app/views/facebook/import_info.thtml91
-rw-r--r--site/app/views/facebook/install.thtml183
-rw-r--r--site/app/views/facebook/invite.thtml51
-rw-r--r--site/app/views/facebook/outage.thtml79
-rw-r--r--site/app/views/facebook/search.thtml65
-rw-r--r--site/app/views/facebook/share.thtml70
-rw-r--r--site/app/views/facebook/updatenotes.thtml121
-rw-r--r--site/app/views/facebook/view.thtml265
-rw-r--r--site/app/views/facebook/wallpaper.thtml71
-rw-r--r--site/app/views/files/browse.thtml75
-rw-r--r--site/app/views/files/view.thtml51
-rw-r--r--site/app/views/groups/add.thtml60
-rw-r--r--site/app/views/groups/edit.thtml59
-rw-r--r--site/app/views/groups/index.thtml69
-rw-r--r--site/app/views/helpers/addons_html.php600
-rw-r--r--site/app/views/helpers/facebook.php258
-rw-r--r--site/app/views/helpers/link.php75
-rw-r--r--site/app/views/helpers/listing.php105
-rw-r--r--site/app/views/helpers/localization.php68
-rw-r--r--site/app/views/helpers/pagination.php527
-rw-r--r--site/app/views/helpers/statistics.php34
-rw-r--r--site/app/views/images/show.thtml40
-rw-r--r--site/app/views/layouts/ajax_with_css.thtml87
-rw-r--r--site/app/views/layouts/amo2009.thtml370
-rw-r--r--site/app/views/layouts/facebook.thtml98
-rw-r--r--site/app/views/layouts/mozilla.thtml349
-rw-r--r--site/app/views/layouts/rest.thtml42
-rw-r--r--site/app/views/layouts/rss.thtml15
-rw-r--r--site/app/views/layouts/tests.thtml36
-rw-r--r--site/app/views/localizers/applications.thtml74
-rw-r--r--site/app/views/localizers/gettext.thtml66
-rw-r--r--site/app/views/localizers/logs.thtml53
-rw-r--r--site/app/views/localizers/pages.thtml87
-rw-r--r--site/app/views/localizers/platforms.thtml74
-rw-r--r--site/app/views/localizers/summary.thtml85
-rw-r--r--site/app/views/localizers/tags.thtml74
-rw-r--r--site/app/views/pages/about.thtml49
-rw-r--r--site/app/views/pages/appversions.thtml96
-rw-r--r--site/app/views/pages/collector.thtml70
-rw-r--r--site/app/views/pages/collector_faq.thtml66
-rw-r--r--site/app/views/pages/collector_features.thtml77
-rw-r--r--site/app/views/pages/collector_firstrun.thtml119
-rw-r--r--site/app/views/pages/credits.thtml144
-rw-r--r--site/app/views/pages/developer_faq.thtml48
-rw-r--r--site/app/views/pages/faq.thtml52
-rw-r--r--site/app/views/pages/fashionyourfirefox_faq.thtml51
-rw-r--r--site/app/views/pages/js_constants.js.thtml108
-rw-r--r--site/app/views/pages/policy.thtml53
-rw-r--r--site/app/views/pages/privacy.thtml53
-rw-r--r--site/app/views/pages/review_guide.thtml53
-rw-r--r--site/app/views/pages/robots.txt.thtml66
-rw-r--r--site/app/views/pages/sandbox.thtml53
-rw-r--r--site/app/views/pages/submissionhelp.thtml53
-rw-r--r--site/app/views/previews/add.thtml68
-rw-r--r--site/app/views/previews/edit.thtml60
-rw-r--r--site/app/views/reviews/add.thtml121
-rw-r--r--site/app/views/reviews/delete.thtml68
-rw-r--r--site/app/views/reviews/display.thtml238
-rw-r--r--site/app/views/reviews/flag.thtml67
-rw-r--r--site/app/views/reviews/review_added.thtml60
-rw-r--r--site/app/views/reviews/rss/reviews.thtml52
-rw-r--r--site/app/views/search/collections.thtml82
-rw-r--r--site/app/views/search/index.thtml75
-rw-r--r--site/app/views/search/rss/index.thtml26
-rw-r--r--site/app/views/sharing_api/addon.thtml134
-rw-r--r--site/app/views/sharing_api/auth_token.thtml42
-rw-r--r--site/app/views/sharing_api/collection_detail.thtml68
-rw-r--r--site/app/views/sharing_api/collections.thtml61
-rw-r--r--site/app/views/sharing_api/email/recommend_email_plain.thtml23
-rw-r--r--site/app/views/sharing_api/empty.thtml40
-rw-r--r--site/app/views/sharing_api/error.thtml44
-rw-r--r--site/app/views/sharing_api/options.thtml40
-rw-r--r--site/app/views/sharing_api/service_doc.thtml66
-rw-r--r--site/app/views/statistics/addon.thtml271
-rw-r--r--site/app/views/statistics/csv.thtml23
-rw-r--r--site/app/views/statistics/index.thtml103
-rw-r--r--site/app/views/statistics/json.thtml7
-rw-r--r--site/app/views/statistics/rss/summary.thtml76
-rw-r--r--site/app/views/statistics/settings.thtml61
-rw-r--r--site/app/views/statistics/xml.thtml15
-rw-r--r--site/app/views/tests/case.thtml3
-rw-r--r--site/app/views/tests/discover.thtml11
-rw-r--r--site/app/views/tests/group.thtml3
-rw-r--r--site/app/views/tests/index.thtml131
-rw-r--r--site/app/views/tests/search.thtml10
-rw-r--r--site/app/views/users/activatefirst.thtml53
-rw-r--r--site/app/views/users/delete.thtml139
-rw-r--r--site/app/views/users/edit.thtml216
-rw-r--r--site/app/views/users/email/confirm_plain.thtml8
-rw-r--r--site/app/views/users/email/emailchange_plain.thtml7
-rw-r--r--site/app/views/users/email/pwreset_plain.thtml6
-rw-r--r--site/app/views/users/emailchange.thtml60
-rw-r--r--site/app/views/users/info.thtml172
-rw-r--r--site/app/views/users/login.thtml105
-rw-r--r--site/app/views/users/pwreset.thtml87
-rw-r--r--site/app/views/users/register.thtml117
-rw-r--r--site/app/views/users/register_complete.thtml54
-rw-r--r--site/app/views/versions/license.thtml57
-rw-r--r--site/app/views/versions/update_info.thtml56
-rw-r--r--site/app/webroot/.htaccess70
-rw-r--r--site/app/webroot/AMOSearch.xml11
-rw-r--r--site/app/webroot/css.php101
-rw-r--r--site/app/webroot/css/admin.css67
-rw-r--r--site/app/webroot/css/amo2009/ie.css53
-rw-r--r--site/app/webroot/css/amo2009/ie6.css25
-rw-r--r--site/app/webroot/css/amo2009/ie7.css3
-rw-r--r--site/app/webroot/css/amo2009/iepngfix.htc73
-rw-r--r--site/app/webroot/css/amo2009/legacy.css7
-rw-r--r--site/app/webroot/css/amo2009/main-mozilla.css2112
-rw-r--r--site/app/webroot/css/amo2009/main.css4049
-rwxr-xr-xsite/app/webroot/css/amo2009/slimbox2.css83
-rw-r--r--site/app/webroot/css/base.template.css95
-rw-r--r--site/app/webroot/css/browse.css280
-rw-r--r--site/app/webroot/css/cake.generic.css225
-rw-r--r--site/app/webroot/css/collection-style.css240
-rw-r--r--site/app/webroot/css/color.css327
-rw-r--r--site/app/webroot/css/compatibility.css274
-rw-r--r--site/app/webroot/css/developers.css1179
-rw-r--r--site/app/webroot/css/diff.css2
-rw-r--r--site/app/webroot/css/editors.css477
-rw-r--r--site/app/webroot/css/f8.css91
-rw-r--r--site/app/webroot/css/facebook.php411
-rw-r--r--site/app/webroot/css/filebrowser.css68
-rw-r--r--site/app/webroot/css/forms.css74
-rw-r--r--site/app/webroot/css/frame.css28
-rw-r--r--site/app/webroot/css/ie.css64
-rw-r--r--site/app/webroot/css/ie6.css125
-rw-r--r--site/app/webroot/css/images/arrow.gifbin0 -> 62 bytes
-rwxr-xr-xsite/app/webroot/css/images/container_bg.gifbin0 -> 109 bytes
-rwxr-xr-xsite/app/webroot/css/images/logo.gifbin0 -> 18012 bytes
-rwxr-xr-xsite/app/webroot/css/images/nav_bg.gifbin0 -> 874 bytes
-rwxr-xr-xsite/app/webroot/css/images/nav_item_bg.gifbin0 -> 531 bytes
-rw-r--r--site/app/webroot/css/jquery-lightbox.css102
-rw-r--r--site/app/webroot/css/jquery-ui/dark/dark.css11
-rw-r--r--site/app/webroot/css/jquery-ui/dark/dark.form.css192
-rw-r--r--site/app/webroot/css/jquery-ui/dark/dark.form.pngbin0 -> 12308 bytes
-rw-r--r--site/app/webroot/css/jquery-ui/dark/dark.menu.css9
-rw-r--r--site/app/webroot/css/jquery-ui/dark/dark.modal.css93
-rw-r--r--site/app/webroot/css/jquery-ui/dark/dark.tabs.css73
-rw-r--r--site/app/webroot/css/jquery-ui/dark/dark.tree.css61
-rw-r--r--site/app/webroot/css/jquery-ui/flora/flora.accordion.css12
-rw-r--r--site/app/webroot/css/jquery-ui/flora/flora.all.css9
-rw-r--r--site/app/webroot/css/jquery-ui/flora/flora.calendar.css167
-rw-r--r--site/app/webroot/css/jquery-ui/flora/flora.css2
-rw-r--r--site/app/webroot/css/jquery-ui/flora/flora.dialog.css86
-rw-r--r--site/app/webroot/css/jquery-ui/flora/flora.menu.css8
-rw-r--r--site/app/webroot/css/jquery-ui/flora/flora.resizable.css20
-rw-r--r--site/app/webroot/css/jquery-ui/flora/flora.shadow.css33
-rw-r--r--site/app/webroot/css/jquery-ui/flora/flora.slider.css8
-rw-r--r--site/app/webroot/css/jquery-ui/flora/flora.tablesorter.css40
-rw-r--r--site/app/webroot/css/jquery-ui/flora/flora.tabs.css111
-rw-r--r--site/app/webroot/css/jquery-ui/flora/i/accordion-left-act.pngbin0 -> 249 bytes
-rw-r--r--site/app/webroot/css/jquery-ui/flora/i/accordion-left-over.pngbin0 -> 174 bytes
-rw-r--r--site/app/webroot/css/jquery-ui/flora/i/accordion-left.pngbin0 -> 174 bytes
-rw-r--r--site/app/webroot/css/jquery-ui/flora/i/accordion-middle-act.pngbin0 -> 148 bytes
-rw-r--r--site/app/webroot/css/jquery-ui/flora/i/accordion-middle-over.pngbin0 -> 122 bytes
-rw-r--r--site/app/webroot/css/jquery-ui/flora/i/accordion-middle.pngbin0 -> 122 bytes
-rw-r--r--site/app/webroot/css/jquery-ui/flora/i/accordion-right-act.pngbin0 -> 245 bytes
-rw-r--r--site/app/webroot/css/jquery-ui/flora/i/accordion-right-over.pngbin0 -> 177 bytes
-rw-r--r--site/app/webroot/css/jquery-ui/flora/i/accordion-right.pngbin0 -> 177 bytes
-rw-r--r--site/app/webroot/css/jquery-ui/flora/i/asc.gifbin0 -> 54 bytes
-rw-r--r--site/app/webroot/css/jquery-ui/flora/i/bg.gifbin0 -> 64 bytes
-rw-r--r--site/app/webroot/css/jquery-ui/flora/i/desc.gifbin0 -> 54 bytes
-rw-r--r--site/app/webroot/css/jquery-ui/flora/i/dialog-e.gifbin0 -> 440 bytes
-rw-r--r--site/app/webroot/css/jquery-ui/flora/i/dialog-n.gifbin0 -> 569 bytes
-rw-r--r--site/app/webroot/css/jquery-ui/flora/i/dialog-ne.gifbin0 -> 353 bytes
-rw-r--r--site/app/webroot/css/jquery-ui/flora/i/dialog-nw.gifbin0 -> 353 bytes
-rw-r--r--site/app/webroot/css/jquery-ui/flora/i/dialog-s.gifbin0 -> 434 bytes
-rw-r--r--site/app/webroot/css/jquery-ui/flora/i/dialog-se.gifbin0 -> 175 bytes
-rw-r--r--site/app/webroot/css/jquery-ui/flora/i/dialog-sw.gifbin0 -> 175 bytes
-rw-r--r--site/app/webroot/css/jquery-ui/flora/i/dialog-title.gifbin0 -> 238 bytes
-rw-r--r--site/app/webroot/css/jquery-ui/flora/i/dialog-titlebar-close-hover.pngbin0 -> 2927 bytes
-rw-r--r--site/app/webroot/css/jquery-ui/flora/i/dialog-titlebar-close.pngbin0 -> 2880 bytes
-rw-r--r--site/app/webroot/css/jquery-ui/flora/i/dialog-w.gifbin0 -> 437 bytes
-rw-r--r--site/app/webroot/css/jquery-ui/flora/i/menu-submenu.gifbin0 -> 93 bytes
-rw-r--r--site/app/webroot/css/jquery-ui/flora/i/resizable-e.gifbin0 -> 338 bytes
-rw-r--r--site/app/webroot/css/jquery-ui/flora/i/resizable-n.gifbin0 -> 341 bytes
-rw-r--r--site/app/webroot/css/jquery-ui/flora/i/resizable-ne.gifbin0 -> 124 bytes
-rw-r--r--site/app/webroot/css/jquery-ui/flora/i/resizable-nw.gifbin0 -> 91 bytes
-rw-r--r--site/app/webroot/css/jquery-ui/flora/i/resizable-s.gifbin0 -> 341 bytes
-rw-r--r--site/app/webroot/css/jquery-ui/flora/i/resizable-se.gifbin0 -> 120 bytes
-rw-r--r--site/app/webroot/css/jquery-ui/flora/i/resizable-sw.gifbin0 -> 175 bytes
-rw-r--r--site/app/webroot/css/jquery-ui/flora/i/resizable-w.gifbin0 -> 339 bytes
-rw-r--r--site/app/webroot/css/jquery-ui/flora/i/shadow.pngbin0 -> 3977 bytes
-rw-r--r--site/app/webroot/css/jquery-ui/flora/i/slider-bg-1.pngbin0 -> 204 bytes
-rw-r--r--site/app/webroot/css/jquery-ui/flora/i/slider-bg-2.pngbin0 -> 326 bytes
-rw-r--r--site/app/webroot/css/jquery-ui/flora/i/slider-handle.gifbin0 -> 176 bytes
-rw-r--r--site/app/webroot/css/jquery-ui/flora/i/tabs.gifbin0 -> 377 bytes
-rw-r--r--site/app/webroot/css/jquery-ui/flora/i/tabs.pngbin0 -> 263 bytes
-rw-r--r--site/app/webroot/css/jquery-ui/light/light.css11
-rw-r--r--site/app/webroot/css/jquery-ui/light/light.form.css45
-rw-r--r--site/app/webroot/css/jquery-ui/light/light.menu.css8
-rw-r--r--site/app/webroot/css/jquery-ui/light/light.modal.css91
-rw-r--r--site/app/webroot/css/jquery-ui/light/light.tabs.css71
-rw-r--r--site/app/webroot/css/jquery-ui/light/light.tree.css61
-rw-r--r--site/app/webroot/css/localizers.css66
-rw-r--r--site/app/webroot/css/print.css52
-rw-r--r--site/app/webroot/css/remora.css177
-rw-r--r--site/app/webroot/css/rustico.content.css558
-rw-r--r--site/app/webroot/css/rustico.css1165
-rw-r--r--site/app/webroot/css/rustico.template.css292
-rw-r--r--site/app/webroot/css/sandbox_rustico.css27
-rw-r--r--site/app/webroot/css/screen.css1826
-rw-r--r--site/app/webroot/css/simile/bundle.css269
-rwxr-xr-xsite/app/webroot/css/simile/ethers.css63
-rwxr-xr-xsite/app/webroot/css/simile/events.css45
-rwxr-xr-xsite/app/webroot/css/simile/timeline.css65
-rwxr-xr-xsite/app/webroot/css/simile/timeplot.css95
-rw-r--r--site/app/webroot/css/slimbox/close.pngbin0 -> 3647 bytes
-rw-r--r--site/app/webroot/css/slimbox/closelabel.gifbin0 -> 979 bytes
-rw-r--r--site/app/webroot/css/slimbox/goleft.pngbin0 -> 4079 bytes
-rw-r--r--site/app/webroot/css/slimbox/goright.pngbin0 -> 4071 bytes
-rw-r--r--site/app/webroot/css/slimbox/loading.gifbin0 -> 2767 bytes
-rw-r--r--site/app/webroot/css/slimbox/nextlabel.gifbin0 -> 354 bytes
-rw-r--r--site/app/webroot/css/slimbox/prevlabel.gifbin0 -> 371 bytes
-rw-r--r--site/app/webroot/css/slimbox/slimbox.css108
-rwxr-xr-xsite/app/webroot/css/stats/dropdowns.css408
-rwxr-xr-xsite/app/webroot/css/stats/stats.css279
-rw-r--r--site/app/webroot/css/style.min.css1
-rw-r--r--site/app/webroot/css/summary.css26
-rw-r--r--site/app/webroot/css/tests.css136
-rw-r--r--site/app/webroot/css/thickbox.css129
-rw-r--r--site/app/webroot/css/type.css176
-rw-r--r--site/app/webroot/disabled.php90
-rw-r--r--site/app/webroot/ebay/ebay-extension/eBay32x32.pngbin0 -> 1714 bytes
-rw-r--r--site/app/webroot/ebay/ebay-extension/ebay-0.9.6.5.xpibin0 -> 507054 bytes
-rw-r--r--site/app/webroot/ebay/ebay-extension/ebay_extension.html31
-rw-r--r--site/app/webroot/ebay/ebay-extension/update.rdf26
-rw-r--r--site/app/webroot/files/10/del.icio.us.src26
-rw-r--r--site/app/webroot/files/11/IMDB.src47
-rw-r--r--site/app/webroot/files/12/wikipedia.src43
-rw-r--r--site/app/webroot/files/13/a9.src75
-rw-r--r--site/app/webroot/files/3677/arabic_spell-checking_dictionary-1.2b1-fx+zm+tb.xpibin0 -> 3593882 bytes
-rw-r--r--site/app/webroot/files/4023/microdefender-1.0-fx+tb.xpibin0 -> 621 bytes
-rw-r--r--site/app/webroot/files/5/google.src48
-rw-r--r--site/app/webroot/files/7/farming.xpibin0 -> 599 bytes
-rw-r--r--site/app/webroot/files/7/farming2.xpibin0 -> 599 bytes
-rw-r--r--site/app/webroot/files/9/hunting.xpibin0 -> 19807 bytes
-rw-r--r--site/app/webroot/google/google_browsersync.html16
-rw-r--r--site/app/webroot/google/google_desktop_gadget_win.html5
-rw-r--r--site/app/webroot/google/google_gears_linux.html16
-rw-r--r--site/app/webroot/google/google_gears_osx.html16
-rw-r--r--site/app/webroot/google/google_notebook.html16
-rw-r--r--site/app/webroot/google/google_safebrowsing.html16
-rw-r--r--site/app/webroot/google/google_sendtophone.html16
-rw-r--r--site/app/webroot/google/google_suggest.html16
-rw-r--r--site/app/webroot/google/google_toolbar.html15
-rw-r--r--site/app/webroot/google/google_toolbar_beta_linux.html15
-rw-r--r--site/app/webroot/google/google_toolbar_beta_mac.html15
-rw-r--r--site/app/webroot/google/google_toolbar_beta_win.html15
-rw-r--r--site/app/webroot/google/google_toolbar_linux.html16
-rw-r--r--site/app/webroot/google/google_toolbar_mac.html16
-rw-r--r--site/app/webroot/google/google_toolbar_win.html16
-rw-r--r--site/app/webroot/google/google_webcomments.html16
-rw-r--r--site/app/webroot/google/joga_companion.html4
-rw-r--r--site/app/webroot/img/__utm.gifbin0 -> 35 bytes
-rw-r--r--site/app/webroot/img/actionBarBackground.gifbin0 -> 168 bytes
-rw-r--r--site/app/webroot/img/addon-bl.pngbin0 -> 272 bytes
-rw-r--r--site/app/webroot/img/addon-br.pngbin0 -> 287 bytes
-rw-r--r--site/app/webroot/img/addon-icn.pngbin0 -> 1962 bytes
-rw-r--r--site/app/webroot/img/addon-tl.pngbin0 -> 462 bytes
-rw-r--r--site/app/webroot/img/addon-tr.pngbin0 -> 5263 bytes
-rw-r--r--site/app/webroot/img/advanced-search-closed.pngbin0 -> 169 bytes
-rw-r--r--site/app/webroot/img/advanced-search-open.pngbin0 -> 4018 bytes
-rw-r--r--site/app/webroot/img/ajax_loading.gifbin0 -> 1608 bytes
-rw-r--r--site/app/webroot/img/amo2009/app-icons/fennec.pngbin0 -> 16539 bytes
-rw-r--r--site/app/webroot/img/amo2009/app-icons/firefox.pngbin0 -> 20680 bytes
-rw-r--r--site/app/webroot/img/amo2009/app-icons/generic.pngbin0 -> 9363 bytes
-rw-r--r--site/app/webroot/img/amo2009/app-icons/seamonkey.pngbin0 -> 10694 bytes
-rw-r--r--site/app/webroot/img/amo2009/app-icons/sunbird.pngbin0 -> 20127 bytes
-rw-r--r--site/app/webroot/img/amo2009/app-icons/thunderbird.pngbin0 -> 20234 bytes
-rw-r--r--site/app/webroot/img/amo2009/applications.pngbin0 -> 2261 bytes
-rw-r--r--site/app/webroot/img/amo2009/bg/add-on-row.jpgbin0 -> 318 bytes
-rw-r--r--site/app/webroot/img/amo2009/bg/body.jpgbin0 -> 42814 bytes
-rw-r--r--site/app/webroot/img/amo2009/bg/border-header-user-options.gifbin0 -> 176 bytes
-rw-r--r--site/app/webroot/img/amo2009/bg/button-blue.jpgbin0 -> 348 bytes
-rw-r--r--site/app/webroot/img/amo2009/bg/button-green.jpgbin0 -> 370 bytes
-rw-r--r--site/app/webroot/img/amo2009/bg/button-orange.jpgbin0 -> 376 bytes
-rw-r--r--site/app/webroot/img/amo2009/bg/button-red.jpgbin0 -> 363 bytes
-rw-r--r--site/app/webroot/img/amo2009/bg/footer.pngbin0 -> 1456 bytes
-rw-r--r--site/app/webroot/img/amo2009/bg/header-border.pngbin0 -> 1246 bytes
-rw-r--r--site/app/webroot/img/amo2009/bg/header-dropdown.pngbin0 -> 1292 bytes
-rw-r--r--site/app/webroot/img/amo2009/bg/heading-dark-blue.jpgbin0 -> 311 bytes
-rw-r--r--site/app/webroot/img/amo2009/bg/listing-footer.gifbin0 -> 146 bytes
-rw-r--r--site/app/webroot/img/amo2009/bg/listing-header.gifbin0 -> 115 bytes
-rw-r--r--site/app/webroot/img/amo2009/bg/listing-item-red.pngbin0 -> 255 bytes
-rw-r--r--site/app/webroot/img/amo2009/bg/listing-item-yellow.pngbin0 -> 235 bytes
-rw-r--r--site/app/webroot/img/amo2009/bg/listing-item.pngbin0 -> 275 bytes
-rw-r--r--site/app/webroot/img/amo2009/bg/panel-selected.pngbin0 -> 1308 bytes
-rw-r--r--site/app/webroot/img/amo2009/blank.gifbin0 -> 43 bytes
-rw-r--r--site/app/webroot/img/amo2009/icons/Collection_Directory.gifbin0 -> 356 bytes
-rw-r--r--site/app/webroot/img/amo2009/icons/add-minus.gifbin0 -> 150 bytes
-rw-r--r--site/app/webroot/img/amo2009/icons/arrow-blue-down.gifbin0 -> 49 bytes
-rw-r--r--site/app/webroot/img/amo2009/icons/arrows-scroller.gifbin0 -> 2325 bytes
-rw-r--r--site/app/webroot/img/amo2009/icons/arrows-scroller.pngbin0 -> 1330 bytes
-rw-r--r--site/app/webroot/img/amo2009/icons/arrows.gifbin0 -> 13371 bytes
-rw-r--r--site/app/webroot/img/amo2009/icons/buttons/arrow-blue-3x3.gifbin0 -> 46 bytes
-rw-r--r--site/app/webroot/img/amo2009/icons/buttons/arrow-white-down.gifbin0 -> 60 bytes
-rw-r--r--site/app/webroot/img/amo2009/icons/buttons/breadcrumb.gifbin0 -> 205 bytes
-rw-r--r--site/app/webroot/img/amo2009/icons/buttons/button-circle-back.gifbin0 -> 13763 bytes
-rw-r--r--site/app/webroot/img/amo2009/icons/buttons/button-circle-forward.gifbin0 -> 13791 bytes
-rw-r--r--site/app/webroot/img/amo2009/icons/buttons/go-blue.gifbin0 -> 59 bytes
-rw-r--r--site/app/webroot/img/amo2009/icons/buttons/go-green.gifbin0 -> 130 bytes
-rw-r--r--site/app/webroot/img/amo2009/icons/buttons/go-green_rtl.gifbin0 -> 130 bytes
-rw-r--r--site/app/webroot/img/amo2009/icons/buttons/heart-blue-10x10.gifbin0 -> 125 bytes
-rw-r--r--site/app/webroot/img/amo2009/icons/buttons/heart-blue-13x13.gifbin0 -> 197 bytes
-rw-r--r--site/app/webroot/img/amo2009/icons/buttons/heart-blue-16x16.gifbin0 -> 211 bytes
-rw-r--r--site/app/webroot/img/amo2009/icons/buttons/minus-orange-10x10.gifbin0 -> 13129 bytes
-rw-r--r--site/app/webroot/img/amo2009/icons/buttons/minus-orange-16x16.gifbin0 -> 13140 bytes
-rw-r--r--site/app/webroot/img/amo2009/icons/buttons/minus-orange-8x9.gifbin0 -> 13128 bytes
-rw-r--r--site/app/webroot/img/amo2009/icons/buttons/minus-red-10x10.gifbin0 -> 60 bytes
-rw-r--r--site/app/webroot/img/amo2009/icons/buttons/minus-red-11x12.gifbin0 -> 64 bytes
-rw-r--r--site/app/webroot/img/amo2009/icons/buttons/minus-red-16x16.gifbin0 -> 71 bytes
-rw-r--r--site/app/webroot/img/amo2009/icons/buttons/minus-red-8x9.gifbin0 -> 59 bytes
-rw-r--r--site/app/webroot/img/amo2009/icons/buttons/plus-green-11x12.gifbin0 -> 71 bytes
-rw-r--r--site/app/webroot/img/amo2009/icons/buttons/plus-green-16x16.gifbin0 -> 82 bytes
-rw-r--r--site/app/webroot/img/amo2009/icons/buttons/plus-green-8x9.gifbin0 -> 64 bytes
-rw-r--r--site/app/webroot/img/amo2009/icons/buttons/plus-green-large.gifbin0 -> 61 bytes
-rw-r--r--site/app/webroot/img/amo2009/icons/buttons/plus-orange-11x12.gifbin0 -> 71 bytes
-rw-r--r--site/app/webroot/img/amo2009/icons/buttons/plus-orange-16x16.gifbin0 -> 82 bytes
-rw-r--r--site/app/webroot/img/amo2009/icons/buttons/plus-orange-8x9.gifbin0 -> 64 bytes
-rw-r--r--site/app/webroot/img/amo2009/icons/buttons/resize.pngbin0 -> 53825 bytes
-rw-r--r--site/app/webroot/img/amo2009/icons/category-dropdown-down.gifbin0 -> 156 bytes
-rw-r--r--site/app/webroot/img/amo2009/icons/category-dropdown-up.gifbin0 -> 156 bytes
-rw-r--r--site/app/webroot/img/amo2009/icons/default-addon.pngbin0 -> 2023 bytes
-rw-r--r--site/app/webroot/img/amo2009/icons/default-collection.pngbin0 -> 1190 bytes
-rw-r--r--site/app/webroot/img/amo2009/icons/developer.pngbin0 -> 448 bytes
-rw-r--r--site/app/webroot/img/amo2009/icons/fav-off.gifbin0 -> 592 bytes
-rw-r--r--site/app/webroot/img/amo2009/icons/fav-on.gifbin0 -> 590 bytes
-rw-r--r--site/app/webroot/img/amo2009/icons/icons.pngbin0 -> 3136 bytes
-rw-r--r--site/app/webroot/img/amo2009/icons/logos-applications.gifbin0 -> 2904 bytes
-rw-r--r--site/app/webroot/img/amo2009/icons/magnifying-glass.gifbin0 -> 434 bytes
-rw-r--r--site/app/webroot/img/amo2009/icons/minus.gifbin0 -> 63 bytes
-rw-r--r--site/app/webroot/img/amo2009/icons/orange-loading.gifbin0 -> 1849 bytes
-rw-r--r--site/app/webroot/img/amo2009/icons/page_code.pngbin0 -> 818 bytes
-rw-r--r--site/app/webroot/img/amo2009/icons/plus.gifbin0 -> 64 bytes
-rw-r--r--site/app/webroot/img/amo2009/icons/pointer.gifbin0 -> 13136 bytes
-rw-r--r--site/app/webroot/img/amo2009/icons/resize.pngbin0 -> 2003 bytes
-rw-r--r--site/app/webroot/img/amo2009/icons/script_code_red.pngbin0 -> 868 bytes
-rw-r--r--site/app/webroot/img/amo2009/icons/stars.pngbin0 -> 1473 bytes
-rw-r--r--site/app/webroot/img/amo2009/icons/starselect.gifbin0 -> 486 bytes
-rw-r--r--site/app/webroot/img/amo2009/icons/starselect_single.gifbin0 -> 131 bytes
-rw-r--r--site/app/webroot/img/amo2009/icons/step-1.pngbin0 -> 485 bytes
-rw-r--r--site/app/webroot/img/amo2009/icons/step-2.pngbin0 -> 553 bytes
-rw-r--r--site/app/webroot/img/amo2009/icons/step-3.pngbin0 -> 577 bytes
-rw-r--r--site/app/webroot/img/amo2009/icons/step.pngbin0 -> 430 bytes
-rw-r--r--site/app/webroot/img/amo2009/icons/steps.gifbin0 -> 852 bytes
-rw-r--r--site/app/webroot/img/amo2009/icons/tick.pngbin0 -> 1659 bytes
-rw-r--r--site/app/webroot/img/amo2009/icons/white-loading-16x16.gifbin0 -> 1849 bytes
-rw-r--r--site/app/webroot/img/amo2009/icons/white-loading-8x8.gifbin0 -> 825 bytes
-rw-r--r--site/app/webroot/img/amo2009/illustrations/extras.gifbin0 -> 1878 bytes
-rw-r--r--site/app/webroot/img/amo2009/illustrations/install.gifbin0 -> 1755 bytes
-rw-r--r--site/app/webroot/img/amo2009/illustrations/logo-add-ons-half.pngbin0 -> 44604 bytes
-rw-r--r--site/app/webroot/img/amo2009/illustrations/logo-collections-100x125.pngbin0 -> 6997 bytes
-rw-r--r--site/app/webroot/img/amo2009/illustrations/logo-collections-220x270.pngbin0 -> 55976 bytes
-rw-r--r--site/app/webroot/img/amo2009/illustrations/logo-collections-download-146x159.pngbin0 -> 28780 bytes
-rw-r--r--site/app/webroot/img/amo2009/illustrations/shopping-online-rtl.jpgbin0 -> 6083 bytes
-rw-r--r--site/app/webroot/img/amo2009/illustrations/shopping-online.jpgbin0 -> 5218 bytes
-rw-r--r--site/app/webroot/img/amo2009/illustrations/themes.gifbin0 -> 2248 bytes
-rwxr-xr-xsite/app/webroot/img/amo2009/lightbox/closelabel.gifbin0 -> 971 bytes
-rwxr-xr-xsite/app/webroot/img/amo2009/lightbox/loading.gifbin0 -> 1279 bytes
-rwxr-xr-xsite/app/webroot/img/amo2009/lightbox/nextlabel.gifbin0 -> 354 bytes
-rwxr-xr-xsite/app/webroot/img/amo2009/lightbox/prevlabel.gifbin0 -> 371 bytes
-rw-r--r--site/app/webroot/img/amo2009/logo-firefox.gifbin0 -> 5581 bytes
-rw-r--r--site/app/webroot/img/amo2009/logo-mozilla.gifbin0 -> 900 bytes
-rw-r--r--site/app/webroot/img/amo2009/logo-seamonkey.gifbin0 -> 7687 bytes
-rw-r--r--site/app/webroot/img/amo2009/logo-sunbird.gifbin0 -> 6288 bytes
-rw-r--r--site/app/webroot/img/amo2009/logo-thunderbird.gifbin0 -> 6837 bytes
-rw-r--r--site/app/webroot/img/amo2009/notifications/error.pngbin0 -> 2650 bytes
-rw-r--r--site/app/webroot/img/amo2009/notifications/error.svg213
-rw-r--r--site/app/webroot/img/amo2009/notifications/info.pngbin0 -> 3398 bytes
-rw-r--r--site/app/webroot/img/amo2009/notifications/info.svg218
-rw-r--r--site/app/webroot/img/amo2009/notifications/sprite.pngbin0 -> 12401 bytes
-rw-r--r--site/app/webroot/img/amo2009/notifications/success.pngbin0 -> 3589 bytes
-rw-r--r--site/app/webroot/img/amo2009/notifications/success.svg270
-rw-r--r--site/app/webroot/img/amo2009/notifications/warning.pngbin0 -> 2858 bytes
-rw-r--r--site/app/webroot/img/amo2009/notifications/warning.svg221
-rw-r--r--site/app/webroot/img/amo2009/site-images/add-on-abp.gifbin0 -> 527 bytes
-rw-r--r--site/app/webroot/img/amo2009/site-images/add-on-ebay.gifbin0 -> 1201 bytes
-rw-r--r--site/app/webroot/img/amo2009/site-images/add-on-icon-games.gifbin0 -> 1141 bytes
-rw-r--r--site/app/webroot/img/amo2009/site-images/add-on-icon-pdf.gifbin0 -> 952 bytes
-rw-r--r--site/app/webroot/img/amo2009/site-images/add-on-retail.gifbin0 -> 896 bytes
-rw-r--r--site/app/webroot/img/amo2009/site-images/add-on-yapta.gifbin0 -> 805 bytes
-rw-r--r--site/app/webroot/img/amo2009/site-images/avatar-128x128.jpgbin0 -> 4497 bytes
-rw-r--r--site/app/webroot/img/amo2009/site-images/avatar-developer-128x128.jpgbin0 -> 5293 bytes
-rw-r--r--site/app/webroot/img/amo2009/site-images/avatar-developer-200x200.jpgbin0 -> 9224 bytes
-rw-r--r--site/app/webroot/img/amo2009/site-images/avatar-developer-32x32.jpgbin0 -> 756 bytes
-rw-r--r--site/app/webroot/img/amo2009/site-images/avatar-developer-64x64.jpgbin0 -> 1815 bytes
-rw-r--r--site/app/webroot/img/amo2009/site-images/collection-music.gifbin0 -> 979 bytes
-rw-r--r--site/app/webroot/img/amo2009/site-images/collection-travellers.gifbin0 -> 1009 bytes
-rw-r--r--site/app/webroot/img/amo2009/site-images/collection-web-developers.gifbin0 -> 1547 bytes
-rw-r--r--site/app/webroot/img/amo2009/site-images/plus-green-small.gifbin0 -> 52 bytes
-rw-r--r--site/app/webroot/img/amo2009/site-images/screenshot-addon-example-01.jpgbin0 -> 8408 bytes
-rw-r--r--site/app/webroot/img/amo2009/site-images/screenshot-addon-example-02.jpgbin0 -> 8408 bytes
-rw-r--r--site/app/webroot/img/amo2009/site-images/screenshot-addon-example-03.jpgbin0 -> 8688 bytes
-rw-r--r--site/app/webroot/img/amo2009/site-images/screenshot-addon-example-04.jpgbin0 -> 8244 bytes
-rw-r--r--site/app/webroot/img/amo2009/site-images/screenshot-addon-example-05.jpgbin0 -> 9854 bytes
-rw-r--r--site/app/webroot/img/amo2009/site-images/thumbnail-large-screenshot-pdf.jpgbin0 -> 6434 bytes
-rw-r--r--site/app/webroot/img/amo2009/site-images/thumbnail-large-screenshot.gifbin0 -> 3759 bytes
-rw-r--r--site/app/webroot/img/amo2009/site-images/thumbnail-screenshot.jpgbin0 -> 2707 bytes
-rw-r--r--site/app/webroot/img/amo2009/tab-mozilla.pngbin0 -> 2214 bytes
-rw-r--r--site/app/webroot/img/app-icons/developers.pngbin0 -> 9363 bytes
-rw-r--r--site/app/webroot/img/app-icons/fennec-header.pngbin0 -> 16539 bytes
-rw-r--r--site/app/webroot/img/app-icons/fennec_small.pngbin0 -> 4888 bytes
-rw-r--r--site/app/webroot/img/app-icons/firefox-header.pngbin0 -> 21313 bytes
-rw-r--r--site/app/webroot/img/app-icons/firefox-ie.pngbin0 -> 7060 bytes
-rw-r--r--site/app/webroot/img/app-icons/firefox-other.pngbin0 -> 992 bytes
-rw-r--r--site/app/webroot/img/app-icons/firefox-sm.pngbin0 -> 20606 bytes
-rw-r--r--site/app/webroot/img/app-icons/firefox.pngbin0 -> 20680 bytes
-rw-r--r--site/app/webroot/img/app-icons/firefox_small.pngbin0 -> 5837 bytes
-rw-r--r--site/app/webroot/img/app-icons/generic.pngbin0 -> 9363 bytes
-rw-r--r--site/app/webroot/img/app-icons/mozilla_small.pngbin0 -> 3308 bytes
-rw-r--r--site/app/webroot/img/app-icons/seamonkey-header.pngbin0 -> 17769 bytes
-rw-r--r--site/app/webroot/img/app-icons/seamonkey-ie.pngbin0 -> 5436 bytes
-rw-r--r--site/app/webroot/img/app-icons/seamonkey-other.pngbin0 -> 920 bytes
-rw-r--r--site/app/webroot/img/app-icons/seamonkey.pngbin0 -> 10694 bytes
-rw-r--r--site/app/webroot/img/app-icons/seamonkey_small.pngbin0 -> 2463 bytes
-rw-r--r--site/app/webroot/img/app-icons/sunbird-header.pngbin0 -> 27637 bytes
-rw-r--r--site/app/webroot/img/app-icons/sunbird-ie.pngbin0 -> 7118 bytes
-rw-r--r--site/app/webroot/img/app-icons/sunbird-other.pngbin0 -> 1002 bytes
-rw-r--r--site/app/webroot/img/app-icons/sunbird.pngbin0 -> 20127 bytes
-rw-r--r--site/app/webroot/img/app-icons/sunbird_small.pngbin0 -> 1509 bytes
-rw-r--r--site/app/webroot/img/app-icons/thunderbird-header.pngbin0 -> 22921 bytes
-rw-r--r--site/app/webroot/img/app-icons/thunderbird-ie.pngbin0 -> 6579 bytes
-rw-r--r--site/app/webroot/img/app-icons/thunderbird-other.pngbin0 -> 979 bytes
-rw-r--r--site/app/webroot/img/app-icons/thunderbird.pngbin0 -> 20234 bytes
-rw-r--r--site/app/webroot/img/app-icons/thunderbird_small.pngbin0 -> 1896 bytes
-rw-r--r--site/app/webroot/img/arr-next.pngbin0 -> 169 bytes
-rw-r--r--site/app/webroot/img/arr-otherapps-closed.pngbin0 -> 175 bytes
-rw-r--r--site/app/webroot/img/arr-otherapps-open.pngbin0 -> 169 bytes
-rw-r--r--site/app/webroot/img/arr-prev.pngbin0 -> 168 bytes
-rw-r--r--site/app/webroot/img/arr-rtl-view.pngbin0 -> 4087 bytes
-rw-r--r--site/app/webroot/img/arr-view-big.pngbin0 -> 622 bytes
-rw-r--r--site/app/webroot/img/arr-view-bigo.pngbin0 -> 447 bytes
-rw-r--r--site/app/webroot/img/arr-view-o.pngbin0 -> 163 bytes
-rw-r--r--site/app/webroot/img/arr-view-rtl-big.pngbin0 -> 5005 bytes
-rw-r--r--site/app/webroot/img/arr-view-rtl-bigo.pngbin0 -> 4527 bytes
-rw-r--r--site/app/webroot/img/arr-view-rtl-o.pngbin0 -> 4020 bytes
-rw-r--r--site/app/webroot/img/arr-view.pngbin0 -> 195 bytes
-rw-r--r--site/app/webroot/img/bigRss.pngbin0 -> 7448 bytes
-rw-r--r--site/app/webroot/img/box-pointer-top.pngbin0 -> 392 bytes
-rw-r--r--site/app/webroot/img/brandbanner-bg.pngbin0 -> 403 bytes
-rw-r--r--site/app/webroot/img/build-icn.pngbin0 -> 889 bytes
-rw-r--r--site/app/webroot/img/buttonbg-dis.pngbin0 -> 146 bytes
-rw-r--r--site/app/webroot/img/buttonbg-exp.pngbin0 -> 156 bytes
-rw-r--r--site/app/webroot/img/buttonbg-rec.pngbin0 -> 156 bytes
-rw-r--r--site/app/webroot/img/buttonbg-search.pngbin0 -> 174 bytes
-rw-r--r--site/app/webroot/img/buttonbg.pngbin0 -> 156 bytes
-rw-r--r--site/app/webroot/img/cake.power.pngbin0 -> 3053 bytes
-rw-r--r--site/app/webroot/img/cat-link.pngbin0 -> 319 bytes
-rw-r--r--site/app/webroot/img/cat-linkhover.pngbin0 -> 183 bytes
-rw-r--r--site/app/webroot/img/cathead-closed.pngbin0 -> 2232 bytes
-rw-r--r--site/app/webroot/img/cathead-open.pngbin0 -> 2017 bytes
-rw-r--r--site/app/webroot/img/cathead.pngbin0 -> 1915 bytes
-rw-r--r--site/app/webroot/img/collection.pngbin0 -> 2263 bytes
-rw-r--r--site/app/webroot/img/community.pngbin0 -> 1254 bytes
-rw-r--r--site/app/webroot/img/default_icon.pngbin0 -> 1962 bytes
-rwxr-xr-xsite/app/webroot/img/developers/actionbar/details.pngbin0 -> 566 bytes
-rwxr-xr-xsite/app/webroot/img/developers/actionbar/displaypage.pngbin0 -> 500 bytes
-rwxr-xr-xsite/app/webroot/img/developers/actionbar/edit.pngbin0 -> 746 bytes
-rwxr-xr-xsite/app/webroot/img/developers/actionbar/edit_addon.pngbin0 -> 746 bytes
-rwxr-xr-xsite/app/webroot/img/developers/actionbar/edit_authors.pngbin0 -> 785 bytes
-rwxr-xr-xsite/app/webroot/img/developers/actionbar/edit_categories.pngbin0 -> 748 bytes
-rwxr-xr-xsite/app/webroot/img/developers/actionbar/edit_descriptions.pngbin0 -> 731 bytes
-rwxr-xr-xsite/app/webroot/img/developers/actionbar/edit_properties.pngbin0 -> 865 bytes
-rwxr-xr-xsite/app/webroot/img/developers/actionbar/previews.pngbin0 -> 661 bytes
-rwxr-xr-xsite/app/webroot/img/developers/actionbar/stats.pngbin0 -> 710 bytes
-rwxr-xr-xsite/app/webroot/img/developers/actionbar/status.pngbin0 -> 781 bytes
-rwxr-xr-xsite/app/webroot/img/developers/actionbar/versions.pngbin0 -> 694 bytes
-rwxr-xr-xsite/app/webroot/img/developers/actionbar/versions_add.pngbin0 -> 691 bytes
-rwxr-xr-xsite/app/webroot/img/developers/actionbar_add.pngbin0 -> 691 bytes
-rwxr-xr-xsite/app/webroot/img/developers/actionbar_detailed.pngbin0 -> 566 bytes
-rwxr-xr-xsite/app/webroot/img/developers/actionbar_disable.pngbin0 -> 347 bytes
-rwxr-xr-xsite/app/webroot/img/developers/actionbar_edit.pngbin0 -> 746 bytes
-rwxr-xr-xsite/app/webroot/img/developers/actionbar_enable.pngbin0 -> 591 bytes
-rwxr-xr-xsite/app/webroot/img/developers/actionbar_nominate.pngbin0 -> 733 bytes
-rwxr-xr-xsite/app/webroot/img/developers/actionbar_stats.pngbin0 -> 710 bytes
-rwxr-xr-xsite/app/webroot/img/developers/actionbar_viewpublic.pngbin0 -> 500 bytes
-rw-r--r--site/app/webroot/img/developers/add.pngbin0 -> 733 bytes
-rw-r--r--site/app/webroot/img/developers/admin_review.pngbin0 -> 702 bytes
-rwxr-xr-xsite/app/webroot/img/developers/arrow_down.pngbin0 -> 379 bytes
-rwxr-xr-xsite/app/webroot/img/developers/arrow_up.pngbin0 -> 372 bytes
-rwxr-xr-xsite/app/webroot/img/developers/asterisk_yellow.pngbin0 -> 743 bytes
-rwxr-xr-xsite/app/webroot/img/developers/cross.pngbin0 -> 655 bytes
-rw-r--r--site/app/webroot/img/developers/delete.pngbin0 -> 715 bytes
-rwxr-xr-xsite/app/webroot/img/developers/edit.pngbin0 -> 888 bytes
-rwxr-xr-xsite/app/webroot/img/developers/edit_authors_add.pngbin0 -> 746 bytes
-rwxr-xr-xsite/app/webroot/img/developers/edit_authors_delete.pngbin0 -> 767 bytes
-rwxr-xr-xsite/app/webroot/img/developers/exclamation.pngbin0 -> 701 bytes
-rw-r--r--site/app/webroot/img/developers/extension.pngbin0 -> 988 bytes
-rw-r--r--site/app/webroot/img/developers/firefox.pngbin0 -> 1129 bytes
-rwxr-xr-xsite/app/webroot/img/developers/help.pngbin0 -> 786 bytes
-rwxr-xr-xsite/app/webroot/img/developers/history.pngbin0 -> 1920 bytes
-rwxr-xr-xsite/app/webroot/img/developers/homepage.pngbin0 -> 1625 bytes
-rw-r--r--site/app/webroot/img/developers/homepage_small.pngbin0 -> 838 bytes
-rw-r--r--site/app/webroot/img/developers/info-bw.pngbin0 -> 607 bytes
-rw-r--r--site/app/webroot/img/developers/info-color.pngbin0 -> 1166 bytes
-rw-r--r--site/app/webroot/img/developers/locale-background-hover.pngbin0 -> 329 bytes
-rw-r--r--site/app/webroot/img/developers/locale-background-selected.pngbin0 -> 347 bytes
-rw-r--r--site/app/webroot/img/developers/locale-background.pngbin0 -> 336 bytes
-rw-r--r--site/app/webroot/img/developers/mozilla.pngbin0 -> 1123 bytes
-rw-r--r--site/app/webroot/img/developers/new.pngbin0 -> 741 bytes
-rwxr-xr-xsite/app/webroot/img/developers/noscript.pngbin0 -> 861 bytes
-rwxr-xr-xsite/app/webroot/img/developers/overview.pngbin0 -> 2114 bytes
-rwxr-xr-xsite/app/webroot/img/developers/pencil.pngbin0 -> 450 bytes
-rwxr-xr-xsite/app/webroot/img/developers/preview_add.pngbin0 -> 653 bytes
-rwxr-xr-xsite/app/webroot/img/developers/preview_delete.pngbin0 -> 653 bytes
-rwxr-xr-xsite/app/webroot/img/developers/preview_edit.pngbin0 -> 783 bytes
-rwxr-xr-xsite/app/webroot/img/developers/previews.pngbin0 -> 2003 bytes
-rwxr-xr-xsite/app/webroot/img/developers/privileges.pngbin0 -> 612 bytes
-rwxr-xr-xsite/app/webroot/img/developers/public-bw.pngbin0 -> 1076 bytes
-rwxr-xr-xsite/app/webroot/img/developers/public-color.pngbin0 -> 1392 bytes
-rwxr-xr-xsite/app/webroot/img/developers/sandbox-bw.pngbin0 -> 1122 bytes
-rwxr-xr-xsite/app/webroot/img/developers/sandbox-color.pngbin0 -> 1483 bytes
-rw-r--r--site/app/webroot/img/developers/seamonkey.pngbin0 -> 865 bytes
-rw-r--r--site/app/webroot/img/developers/sort-asc.gifbin0 -> 54 bytes
-rw-r--r--site/app/webroot/img/developers/sort-bg.gifbin0 -> 64 bytes
-rw-r--r--site/app/webroot/img/developers/sort-desc.gifbin0 -> 54 bytes
-rw-r--r--site/app/webroot/img/developers/spacer.pngbin0 -> 204 bytes
-rwxr-xr-xsite/app/webroot/img/developers/status_active.pngbin0 -> 591 bytes
-rwxr-xr-xsite/app/webroot/img/developers/status_inactive.pngbin0 -> 347 bytes
-rwxr-xr-xsite/app/webroot/img/developers/status_nominate.pngbin0 -> 733 bytes
-rw-r--r--site/app/webroot/img/developers/sunbird.pngbin0 -> 791 bytes
-rwxr-xr-xsite/app/webroot/img/developers/superreview-bw.pngbin0 -> 1107 bytes
-rwxr-xr-xsite/app/webroot/img/developers/superreview-color.pngbin0 -> 1425 bytes
-rwxr-xr-xsite/app/webroot/img/developers/tab_add.pngbin0 -> 488 bytes
-rwxr-xr-xsite/app/webroot/img/developers/tab_delete.pngbin0 -> 493 bytes
-rw-r--r--site/app/webroot/img/developers/theme.pngbin0 -> 936 bytes
-rw-r--r--site/app/webroot/img/developers/thunderbird.pngbin0 -> 938 bytes
-rwxr-xr-xsite/app/webroot/img/developers/tick.pngbin0 -> 537 bytes
-rw-r--r--site/app/webroot/img/developers/update.pngbin0 -> 917 bytes
-rwxr-xr-xsite/app/webroot/img/developers/versions_compat_add.pngbin0 -> 592 bytes
-rwxr-xr-xsite/app/webroot/img/developers/versions_compat_remove.pngbin0 -> 605 bytes
-rwxr-xr-xsite/app/webroot/img/developers/versions_delete.pngbin0 -> 692 bytes
-rwxr-xr-xsite/app/webroot/img/developers/versions_link.pngbin0 -> 759 bytes
-rw-r--r--site/app/webroot/img/divider.gifbin0 -> 1293 bytes
-rw-r--r--site/app/webroot/img/download.gifbin0 -> 1287 bytes
-rwxr-xr-xsite/app/webroot/img/edit.pngbin0 -> 888 bytes
-rw-r--r--site/app/webroot/img/email.gifbin0 -> 1560 bytes
-rw-r--r--site/app/webroot/img/exp-bl.pngbin0 -> 288 bytes
-rw-r--r--site/app/webroot/img/exp-br.pngbin0 -> 307 bytes
-rw-r--r--site/app/webroot/img/exp-flag.pngbin0 -> 2130 bytes
-rw-r--r--site/app/webroot/img/exp-tl.pngbin0 -> 447 bytes
-rw-r--r--site/app/webroot/img/exp-tr.pngbin0 -> 4886 bytes
-rw-r--r--site/app/webroot/img/extendfirefox/extendfirefox-large.jpgbin0 -> 37411 bytes
-rw-r--r--site/app/webroot/img/extendfirefox/extendfirefox-small.jpgbin0 -> 19177 bytes
-rw-r--r--site/app/webroot/img/extendfirefox/extendfirefox3.pngbin0 -> 34676 bytes
-rwxr-xr-xsite/app/webroot/img/extension.pngbin0 -> 1962 bytes
-rw-r--r--site/app/webroot/img/facebook/confirm_button.gifbin0 -> 1549 bytes
-rw-r--r--site/app/webroot/img/facebook/confirm_button_active.gifbin0 -> 1253 bytes
-rw-r--r--site/app/webroot/img/facebook/confirm_button_extension.gifbin0 -> 79 bytes
-rw-r--r--site/app/webroot/img/facebook/detect-step1.pngbin0 -> 26308 bytes
-rw-r--r--site/app/webroot/img/facebook/detect-step2.pngbin0 -> 40321 bytes
-rw-r--r--site/app/webroot/img/facebook/facebook_header.pngbin0 -> 52452 bytes
-rw-r--r--site/app/webroot/img/facebook/icon_remove.gifbin0 -> 64 bytes
-rw-r--r--site/app/webroot/img/facebook/medal.pngbin0 -> 1492 bytes
-rw-r--r--site/app/webroot/img/facebook/new_media_button.gifbin0 -> 4705 bytes
-rw-r--r--site/app/webroot/img/facebook/new_media_button_active.gifbin0 -> 3084 bytes
-rw-r--r--site/app/webroot/img/facebook/new_media_button_plus.gifbin0 -> 111 bytes
-rw-r--r--site/app/webroot/img/facebook/newsfeed/addedfavorite.pngbin0 -> 902 bytes
-rwxr-xr-xsite/app/webroot/img/facebook/newsfeed/extension.pngbin0 -> 988 bytes
-rwxr-xr-xsite/app/webroot/img/facebook/newsfeed/lightning.pngbin0 -> 634 bytes
-rw-r--r--site/app/webroot/img/facebook/newsfeed/newversion.pngbin0 -> 1129 bytes
-rw-r--r--site/app/webroot/img/facebook/newsfeed/recommendation.pngbin0 -> 1121 bytes
-rw-r--r--site/app/webroot/img/facebook/no-preview-thumb.pngbin0 -> 11591 bytes
-rw-r--r--site/app/webroot/img/facebook/no-preview.pngbin0 -> 33845 bytes
-rw-r--r--site/app/webroot/img/facebook/non-firefox-box.pngbin0 -> 32940 bytes
-rw-r--r--site/app/webroot/img/facebook/outage.pngbin0 -> 137408 bytes
-rw-r--r--site/app/webroot/img/facebook/rockyourfirefox-75x70.pngbin0 -> 12656 bytes
-rw-r--r--site/app/webroot/img/facebook/rockyourfirefox-header.pngbin0 -> 48934 bytes
-rw-r--r--site/app/webroot/img/facebook/rockyourfirefox-intro.pngbin0 -> 97482 bytes
-rw-r--r--site/app/webroot/img/facebook/smallMedal.pngbin0 -> 394 bytes
-rw-r--r--site/app/webroot/img/facebook/wallpaper/rock_firefox_1024x768.jpgbin0 -> 46853 bytes
-rw-r--r--site/app/webroot/img/facebook/wallpaper/rock_firefox_1280x1024.jpgbin0 -> 62804 bytes
-rw-r--r--site/app/webroot/img/facebook/wallpaper/rock_firefox_1440x900.jpgbin0 -> 64229 bytes
-rw-r--r--site/app/webroot/img/facebook/wallpaper/rock_firefox_1680x1050.jpgbin0 -> 73301 bytes
-rw-r--r--site/app/webroot/img/facebook/wallpaper/rock_firefox_1920x1200.jpgbin0 -> 91798 bytes
-rw-r--r--site/app/webroot/img/facebook/wallpaper/rock_firefox_800x600.jpgbin0 -> 33681 bytes
-rw-r--r--site/app/webroot/img/facebook/wallpaper/rock_firefox_preview.pngbin0 -> 39129 bytes
-rw-r--r--site/app/webroot/img/farmer.gifbin0 -> 1755 bytes
-rw-r--r--site/app/webroot/img/farmer.pngbin0 -> 1931 bytes
-rw-r--r--site/app/webroot/img/farming_slice.pngbin0 -> 5290 bytes
-rw-r--r--site/app/webroot/img/farming_thumb1.gifbin0 -> 7404 bytes
-rw-r--r--site/app/webroot/img/farming_thumb1.pngbin0 -> 26928 bytes
-rw-r--r--site/app/webroot/img/favicon.icobin0 -> 811 bytes
-rw-r--r--site/app/webroot/img/favicons/delicious.gifbin0 -> 171 bytes
-rw-r--r--site/app/webroot/img/favicons/digg.gifbin0 -> 256 bytes
-rw-r--r--site/app/webroot/img/favicons/facebook.gifbin0 -> 121 bytes
-rw-r--r--site/app/webroot/img/favicons/friendfeed.gifbin0 -> 239 bytes
-rw-r--r--site/app/webroot/img/favicons/myspace.gifbin0 -> 268 bytes
-rw-r--r--site/app/webroot/img/favicons/reddit.gifbin0 -> 581 bytes
-rw-r--r--site/app/webroot/img/featured-bg.pngbin0 -> 3687 bytes
-rw-r--r--site/app/webroot/img/foot-bg.pngbin0 -> 290 bytes
-rw-r--r--site/app/webroot/img/footer.gifbin0 -> 43 bytes
-rw-r--r--site/app/webroot/img/fyf/addonguy-head.pngbin0 -> 8561 bytes
-rw-r--r--site/app/webroot/img/fyf/addonguy-large.pngbin0 -> 13812 bytes
-rw-r--r--site/app/webroot/img/fyf/addonguy-success.pngbin0 -> 46261 bytes
-rw-r--r--site/app/webroot/img/fyf/addonguy.pngbin0 -> 6723 bytes
-rw-r--r--site/app/webroot/img/fyf/bg.pngbin0 -> 682 bytes
-rw-r--r--site/app/webroot/img/fyf/collection-bg.pngbin0 -> 196 bytes
-rw-r--r--site/app/webroot/img/fyf/collection-bg2.pngbin0 -> 264 bytes
-rw-r--r--site/app/webroot/img/fyf/faq_header.pngbin0 -> 1422 bytes
-rw-r--r--site/app/webroot/img/fyf/faq_subheader.pngbin0 -> 1531 bytes
-rw-r--r--site/app/webroot/img/fyf/fashioned.pngbin0 -> 8156 bytes
-rw-r--r--site/app/webroot/img/fyf/footer-bg.pngbin0 -> 323 bytes
-rw-r--r--site/app/webroot/img/fyf/fyf_header.pngbin0 -> 5851 bytes
-rw-r--r--site/app/webroot/img/fyf/installbtn-bg.pngbin0 -> 5441 bytes
-rw-r--r--site/app/webroot/img/fyf/installsubmit.pngbin0 -> 1759 bytes
-rw-r--r--site/app/webroot/img/fyf/triangle-down.pngbin0 -> 325 bytes
-rw-r--r--site/app/webroot/img/fyf/triangle-right.pngbin0 -> 313 bytes
-rw-r--r--site/app/webroot/img/gear.pngbin0 -> 1150 bytes
-rw-r--r--site/app/webroot/img/gearwrench.pngbin0 -> 1152 bytes
-rw-r--r--site/app/webroot/img/header.jpgbin0 -> 10811 bytes
-rw-r--r--site/app/webroot/img/icn-collapse.pngbin0 -> 224 bytes
-rw-r--r--site/app/webroot/img/icn-expand.pngbin0 -> 228 bytes
-rw-r--r--site/app/webroot/img/install-button-dis.pngbin0 -> 1030 bytes
-rw-r--r--site/app/webroot/img/install-button-exp.pngbin0 -> 2004 bytes
-rw-r--r--site/app/webroot/img/install-button-rec.pngbin0 -> 2050 bytes
-rw-r--r--site/app/webroot/img/install-button-search.pngbin0 -> 1982 bytes
-rw-r--r--site/app/webroot/img/install-button.pngbin0 -> 1925 bytes
-rw-r--r--site/app/webroot/img/install.gifbin0 -> 1392 bytes
-rw-r--r--site/app/webroot/img/installbtn-bg-dis.pngbin0 -> 1728 bytes
-rw-r--r--site/app/webroot/img/installbtn-bg.pngbin0 -> 5441 bytes
-rw-r--r--site/app/webroot/img/installbtn-edges-dis.pngbin0 -> 975 bytes
-rw-r--r--site/app/webroot/img/installbtn-edges-exp.pngbin0 -> 1164 bytes
-rw-r--r--site/app/webroot/img/installbtn-edges-list.pngbin0 -> 1162 bytes
-rw-r--r--site/app/webroot/img/installbtn-edges-rec.pngbin0 -> 1210 bytes
-rw-r--r--site/app/webroot/img/installbtn-edges-search.pngbin0 -> 1167 bytes
-rw-r--r--site/app/webroot/img/installbtn-edges.pngbin0 -> 1121 bytes
-rw-r--r--site/app/webroot/img/jquery-lightbox/close.pngbin0 -> 3647 bytes
-rw-r--r--site/app/webroot/img/jquery-lightbox/goleft.pngbin0 -> 4079 bytes
-rw-r--r--site/app/webroot/img/jquery-lightbox/goright.pngbin0 -> 4071 bytes
-rw-r--r--site/app/webroot/img/jquery-lightbox/lightbox-blank.gifbin0 -> 43 bytes
-rw-r--r--site/app/webroot/img/jquery-lightbox/lightbox-ico-loading.gifbin0 -> 3990 bytes
-rw-r--r--site/app/webroot/img/landrec-bl.pngbin0 -> 267 bytes
-rw-r--r--site/app/webroot/img/landrec-br.pngbin0 -> 287 bytes
-rw-r--r--site/app/webroot/img/landrec-tl.pngbin0 -> 461 bytes
-rw-r--r--site/app/webroot/img/landrec-tr.pngbin0 -> 5262 bytes
-rw-r--r--site/app/webroot/img/loadingAnimation.gifbin0 -> 7347 bytes
-rw-r--r--site/app/webroot/img/mdc-logo.pngbin0 -> 6116 bytes
-rw-r--r--site/app/webroot/img/moz-tab-ie.pngbin0 -> 3888 bytes
-rw-r--r--site/app/webroot/img/moz-tab.pngbin0 -> 1184 bytes
-rw-r--r--site/app/webroot/img/no-preview.pngbin0 -> 29478 bytes
-rwxr-xr-xsite/app/webroot/img/plugins/faq_small.pngbin0 -> 757 bytes
-rwxr-xr-xsite/app/webroot/img/plugins/install.pngbin0 -> 1475 bytes
-rw-r--r--site/app/webroot/img/plugins/linux_icon.pngbin0 -> 1584 bytes
-rw-r--r--site/app/webroot/img/plugins/macosx_icon.pngbin0 -> 1440 bytes
-rw-r--r--site/app/webroot/img/plugins/windows_icon.pngbin0 -> 1966 bytes
-rw-r--r--site/app/webroot/img/preview-img.pngbin0 -> 4581 bytes
-rw-r--r--site/app/webroot/img/puzzle-corner.pngbin0 -> 46747 bytes
-rw-r--r--site/app/webroot/img/quotationmark.gifbin0 -> 452 bytes
-rw-r--r--site/app/webroot/img/ratings/1stars.pngbin0 -> 405 bytes
-rw-r--r--site/app/webroot/img/ratings/2stars.pngbin0 -> 417 bytes
-rw-r--r--site/app/webroot/img/ratings/3stars.pngbin0 -> 418 bytes
-rw-r--r--site/app/webroot/img/ratings/4stars.pngbin0 -> 403 bytes
-rw-r--r--site/app/webroot/img/ratings/5stars.pngbin0 -> 296 bytes
-rw-r--r--site/app/webroot/img/ratings_images.gifbin0 -> 744 bytes
-rw-r--r--site/app/webroot/img/rec-bl.pngbin0 -> 288 bytes
-rw-r--r--site/app/webroot/img/rec-br.pngbin0 -> 307 bytes
-rw-r--r--site/app/webroot/img/rec-flag.pngbin0 -> 2150 bytes
-rw-r--r--site/app/webroot/img/rec-tl.pngbin0 -> 463 bytes
-rw-r--r--site/app/webroot/img/rec-tr.pngbin0 -> 5008 bytes
-rw-r--r--site/app/webroot/img/recommended_medal.gifbin0 -> 1353 bytes
-rw-r--r--site/app/webroot/img/remora2.pngbin0 -> 22053 bytes
-rw-r--r--site/app/webroot/img/rustico/addons/firefox-addons-mglass-ico.pngbin0 -> 1700 bytes
-rw-r--r--site/app/webroot/img/rustico/addons/firefox-addons-puzzle-ico.pngbin0 -> 2709 bytes
-rw-r--r--site/app/webroot/img/rustico/bookmarks/firefox-bm-divider.pngbin0 -> 438 bytes
-rw-r--r--site/app/webroot/img/rustico/bookmarks/firefox-bm-puzzle-ico.pngbin0 -> 1688 bytes
-rw-r--r--site/app/webroot/img/rustico/bookmarks/firefox-bm-ss-01.jpgbin0 -> 8817 bytes
-rw-r--r--site/app/webroot/img/rustico/bookmarks/firefox-bm-ss-02.jpgbin0 -> 10423 bytes
-rw-r--r--site/app/webroot/img/rustico/bookmarks/firefox-bm-ss-03.jpgbin0 -> 9589 bytes
-rw-r--r--site/app/webroot/img/rustico/bookmarks/firefox-bm-ss-04.jpgbin0 -> 9407 bytes
-rw-r--r--site/app/webroot/img/rustico/bookmarks/firefox-bm-ss-05.jpgbin0 -> 11314 bytes
-rw-r--r--site/app/webroot/img/rustico/common/addons-title.pngbin0 -> 2914 bytes
-rw-r--r--site/app/webroot/img/rustico/common/bg-header-small.jpgbin0 -> 721 bytes
-rw-r--r--site/app/webroot/img/rustico/common/bg-header-thin.jpgbin0 -> 448 bytes
-rw-r--r--site/app/webroot/img/rustico/common/firefox-addons-hdr.jpgbin0 -> 23308 bytes
-rw-r--r--site/app/webroot/img/rustico/featured/firefox-featured-divider.pngbin0 -> 439 bytes
-rw-r--r--site/app/webroot/img/rustico/featured/firefox-featured-hb-mid.jpgbin0 -> 680 bytes
-rw-r--r--site/app/webroot/img/rustico/featured/firefox-featured-hb-top.jpgbin0 -> 682 bytes
-rw-r--r--site/app/webroot/img/rustico/featured/firefox-featured-mglass.pngbin0 -> 1394 bytes
-rw-r--r--site/app/webroot/img/rustico/featured/firefox-featured-ss-01.jpgbin0 -> 12032 bytes
-rw-r--r--site/app/webroot/img/rustico/featured/firefox-featured-ss-02.jpgbin0 -> 10941 bytes
-rw-r--r--site/app/webroot/img/rustico/featured/firefox-featured-ss-03.jpgbin0 -> 9970 bytes
-rw-r--r--site/app/webroot/img/rustico/featured/firefox-featured-title.pngbin0 -> 4118 bytes
-rw-r--r--site/app/webroot/img/rustico/firefox-featured-divider.pngbin0 -> 439 bytes
-rw-r--r--site/app/webroot/img/rustico/footer/disclaimer.pngbin0 -> 290 bytes
-rw-r--r--site/app/webroot/img/rustico/footer/footer-icon-firefox.pngbin0 -> 1102 bytes
-rw-r--r--site/app/webroot/img/rustico/footer/footer-icon-mozilla.pngbin0 -> 1144 bytes
-rw-r--r--site/app/webroot/img/rustico/footer/footer-icon-thunderbird.pngbin0 -> 1042 bytes
-rw-r--r--site/app/webroot/img/rustico/header/header-background.pngbin0 -> 3026 bytes
-rw-r--r--site/app/webroot/img/rustico/header/moz-com-logo.pngbin0 -> 2220 bytes
-rw-r--r--site/app/webroot/img/rustico/install-button-red.pngbin0 -> 5175 bytes
-rw-r--r--site/app/webroot/img/rustico/install-button.pngbin0 -> 5667 bytes
-rw-r--r--site/app/webroot/img/rustico/left-top-corner-box.jpgbin0 -> 919 bytes
-rw-r--r--site/app/webroot/img/rustico/menu-box/menu-box-background.pngbin0 -> 4172 bytes
-rw-r--r--site/app/webroot/img/rustico/menu-box/menu-box-bottom.pngbin0 -> 3692 bytes
-rw-r--r--site/app/webroot/img/rustico/menu-box/menu-box-top.pngbin0 -> 3653 bytes
-rw-r--r--site/app/webroot/img/rustico/right-top-corner-box.jpgbin0 -> 1000 bytes
-rw-r--r--site/app/webroot/img/sandbox.pngbin0 -> 241 bytes
-rw-r--r--site/app/webroot/img/search-bg.pngbin0 -> 484 bytes
-rw-r--r--site/app/webroot/img/search-icn.pngbin0 -> 460 bytes
-rw-r--r--site/app/webroot/img/search-left-bottom.pngbin0 -> 4059 bytes
-rwxr-xr-xsite/app/webroot/img/search-left-tab.pngbin0 -> 4156 bytes
-rw-r--r--site/app/webroot/img/search-left.pngbin0 -> 4238 bytes
-rw-r--r--site/app/webroot/img/search-right-bottom.pngbin0 -> 4143 bytes
-rwxr-xr-xsite/app/webroot/img/search-right-tab.pngbin0 -> 4133 bytes
-rw-r--r--site/app/webroot/img/search-right.pngbin0 -> 4652 bytes
-rw-r--r--site/app/webroot/img/searchBarBackground.gifbin0 -> 175 bytes
-rw-r--r--site/app/webroot/img/sidebarBackground.gifbin0 -> 43 bytes
-rw-r--r--site/app/webroot/img/sidebarHighlight.gifbin0 -> 1116 bytes
-rw-r--r--site/app/webroot/img/slider-next-disabled.gifbin0 -> 777 bytes
-rw-r--r--site/app/webroot/img/slider-next.gifbin0 -> 1292 bytes
-rw-r--r--site/app/webroot/img/slider-prev-disabled.gifbin0 -> 816 bytes
-rw-r--r--site/app/webroot/img/slider-prev.gifbin0 -> 1291 bytes
-rw-r--r--site/app/webroot/img/softwareIcon.pngbin0 -> 1309 bytes
-rw-r--r--site/app/webroot/img/sprite-alpha.pngbin0 -> 22716 bytes
-rw-r--r--site/app/webroot/img/sprite.pngbin0 -> 16886 bytes
-rwxr-xr-xsite/app/webroot/img/stats/chart_curve_add.pngbin0 -> 761 bytes
-rwxr-xr-xsite/app/webroot/img/stats/cog.pngbin0 -> 512 bytes
-rwxr-xr-xsite/app/webroot/img/stats/lock.pngbin0 -> 749 bytes
-rwxr-xr-xsite/app/webroot/img/stats/lock_open.pngbin0 -> 727 bytes
-rwxr-xr-xsite/app/webroot/img/stats/page_white_go.pngbin0 -> 612 bytes
-rwxr-xr-xsite/app/webroot/img/stats/rss16x16.pngbin0 -> 745 bytes
-rwxr-xr-xsite/app/webroot/img/stats/tick.pngbin0 -> 537 bytes
-rwxr-xr-xsite/app/webroot/img/stats/x.pngbin0 -> 172 bytes
-rwxr-xr-xsite/app/webroot/img/stats/zoom_in.pngbin0 -> 725 bytes
-rwxr-xr-xsite/app/webroot/img/stats/zoom_out.pngbin0 -> 708 bytes
-rw-r--r--site/app/webroot/img/template/body-background.pngbin0 -> 229 bytes
-rw-r--r--site/app/webroot/img/template/breadcrumbs-background.pngbin0 -> 992 bytes
-rw-r--r--site/app/webroot/img/template/download-firefox-white.pngbin0 -> 7962 bytes
-rw-r--r--site/app/webroot/img/template/download-firefox.pngbin0 -> 8099 bytes
-rw-r--r--site/app/webroot/img/template/download-store-promo-2.pngbin0 -> 17631 bytes
-rw-r--r--site/app/webroot/img/template/download-store-promo.pngbin0 -> 5871 bytes
-rw-r--r--site/app/webroot/img/template/download-thunderbird.pngbin0 -> 8452 bytes
-rw-r--r--site/app/webroot/img/template/feature-back.pngbin0 -> 2744 bytes
-rw-r--r--site/app/webroot/img/template/firefox-15-headline.pngbin0 -> 4251 bytes
-rw-r--r--site/app/webroot/img/template/firefox-awards-2006-jan.pngbin0 -> 13455 bytes
-rw-r--r--site/app/webroot/img/template/firefox-livebookmarks-thumb.pngbin0 -> 6600 bytes
-rw-r--r--site/app/webroot/img/template/firefox-logo-64x64.pngbin0 -> 8118 bytes
-rw-r--r--site/app/webroot/img/template/firefox-screen-mac.pngbin0 -> 23930 bytes
-rw-r--r--site/app/webroot/img/template/firefox-screen-windows.pngbin0 -> 17334 bytes
-rw-r--r--site/app/webroot/img/template/firefox-screen.pngbin0 -> 17334 bytes
-rw-r--r--site/app/webroot/img/template/firefox-searchbar-thumb.pngbin0 -> 6056 bytes
-rw-r--r--site/app/webroot/img/template/firefox-tabbedbrowsing-thumb.pngbin0 -> 5995 bytes
-rw-r--r--site/app/webroot/img/template/go-to-home.pngbin0 -> 5820 bytes
-rw-r--r--site/app/webroot/img/template/header-background.pngbin0 -> 3026 bytes
-rw-r--r--site/app/webroot/img/template/ico-osx-uni.pngbin0 -> 1180 bytes
-rw-r--r--site/app/webroot/img/template/ico-osx.pngbin0 -> 730 bytes
-rw-r--r--site/app/webroot/img/template/ico-tux.pngbin0 -> 495 bytes
-rw-r--r--site/app/webroot/img/template/ico-win.pngbin0 -> 738 bytes
-rw-r--r--site/app/webroot/img/template/menu_back.gifbin0 -> 94 bytes
-rw-r--r--site/app/webroot/img/template/menu_bl.gifbin0 -> 162 bytes
-rw-r--r--site/app/webroot/img/template/menu_br.gifbin0 -> 384 bytes
-rw-r--r--site/app/webroot/img/template/menu_tl.gifbin0 -> 103 bytes
-rw-r--r--site/app/webroot/img/template/menu_tr.gifbin0 -> 107 bytes
-rw-r--r--site/app/webroot/img/template/moz-com-logo.pngbin0 -> 2220 bytes
-rw-r--r--site/app/webroot/img/template/mozilla-16.pngbin0 -> 580 bytes
-rw-r--r--site/app/webroot/img/template/page-background.pngbin0 -> 855 bytes
-rw-r--r--site/app/webroot/img/template/product-firefox-screen.pngbin0 -> 23578 bytes
-rw-r--r--site/app/webroot/img/template/product-thunderbird-screen.pngbin0 -> 13087 bytes
-rw-r--r--site/app/webroot/img/template/releasenotes-firefox.pngbin0 -> 16079 bytes
-rw-r--r--site/app/webroot/img/template/releasenotes-thunderbird.pngbin0 -> 10977 bytes
-rw-r--r--site/app/webroot/img/template/rss.pngbin0 -> 745 bytes
-rw-r--r--site/app/webroot/img/template/store-firefox-backpack.pngbin0 -> 11261 bytes
-rw-r--r--site/app/webroot/img/template/store-firefox-cds.pngbin0 -> 12691 bytes
-rw-r--r--site/app/webroot/img/template/store-firefox-visor.pngbin0 -> 9578 bytes
-rw-r--r--site/app/webroot/img/template/store-thunderbird-tshirt.pngbin0 -> 9395 bytes
-rw-r--r--site/app/webroot/img/template/survey-title.pngbin0 -> 3884 bytes
-rw-r--r--site/app/webroot/img/template/thunderbird-headline.pngbin0 -> 4963 bytes
-rw-r--r--site/app/webroot/img/template/thunderbird-logo-64x64.pngbin0 -> 8057 bytes
-rw-r--r--site/app/webroot/img/template/thunderbird-screen-mac.pngbin0 -> 12465 bytes
-rw-r--r--site/app/webroot/img/template/thunderbird-screen-windows.pngbin0 -> 22195 bytes
-rw-r--r--site/app/webroot/img/template/title-firefox.pngbin0 -> 2208 bytes
-rw-r--r--site/app/webroot/img/template/title-thunderbird.pngbin0 -> 2901 bytes
-rw-r--r--site/app/webroot/img/template/warning.pngbin0 -> 2025 bytes
-rwxr-xr-xsite/app/webroot/img/theme.pngbin0 -> 2002 bytes
-rw-r--r--site/app/webroot/img/thumbnail.pngbin0 -> 527 bytes
-rw-r--r--site/app/webroot/img/tinyRss.pngbin0 -> 1258 bytes
-rw-r--r--site/app/webroot/img/version.pngbin0 -> 607 bytes
-rw-r--r--site/app/webroot/img/warning-ie.pngbin0 -> 735 bytes
-rw-r--r--site/app/webroot/img/warning.pngbin0 -> 2025 bytes
-rw-r--r--site/app/webroot/img/wordmarks/firefox-3.0.pngbin0 -> 13647 bytes
-rw-r--r--site/app/webroot/img/wordmarks/firefox-3.0_small.pngbin0 -> 3484 bytes
-rw-r--r--site/app/webroot/img/wordmarks/firefox-3.5.pngbin0 -> 17879 bytes
-rw-r--r--site/app/webroot/img/wordmarks/firefox-3.5_small.pngbin0 -> 5266 bytes
-rw-r--r--site/app/webroot/index.php87
-rw-r--r--site/app/webroot/js/__utm.js488
-rw-r--r--site/app/webroot/js/__utm.min.js1
-rw-r--r--site/app/webroot/js/addons.js1830
-rw-r--r--site/app/webroot/js/amo-bundle.js1
-rw-r--r--site/app/webroot/js/amo2009/addons.js1972
-rw-r--r--site/app/webroot/js/amo2009/collections.js107
-rw-r--r--site/app/webroot/js/amo2009/global-mozilla.js0
-rw-r--r--site/app/webroot/js/amo2009/global.js343
-rw-r--r--site/app/webroot/js/amo2009/home.js66
-rw-r--r--site/app/webroot/js/amo2009/jquery-1.3.2.min.js19
-rwxr-xr-xsite/app/webroot/js/amo2009/slimbox2.js13
-rw-r--r--site/app/webroot/js/compatibility.js55
-rw-r--r--site/app/webroot/js/developers.js761
-rw-r--r--site/app/webroot/js/editors.js435
-rw-r--r--site/app/webroot/js/f8.js152
-rw-r--r--site/app/webroot/js/filebrowser.js18
-rw-r--r--site/app/webroot/js/jquery-compressed.js19
-rw-r--r--site/app/webroot/js/jquery-ui/GPL-LICENSE.txt278
-rw-r--r--site/app/webroot/js/jquery-ui/MIT-LICENSE.txt20
-rwxr-xr-xsite/app/webroot/js/jquery-ui/effects.blind.min.js1
-rwxr-xr-xsite/app/webroot/js/jquery-ui/effects.bounce.min.js1
-rwxr-xr-xsite/app/webroot/js/jquery-ui/effects.clip.min.js1
-rwxr-xr-xsite/app/webroot/js/jquery-ui/effects.core.min.js1
-rwxr-xr-xsite/app/webroot/js/jquery-ui/effects.drop.min.js1
-rwxr-xr-xsite/app/webroot/js/jquery-ui/effects.explode.min.js1
-rwxr-xr-xsite/app/webroot/js/jquery-ui/effects.fold.min.js1
-rwxr-xr-xsite/app/webroot/js/jquery-ui/effects.highlight.min.js1
-rwxr-xr-xsite/app/webroot/js/jquery-ui/effects.pulsate.min.js1
-rwxr-xr-xsite/app/webroot/js/jquery-ui/effects.scale.min.js1
-rwxr-xr-xsite/app/webroot/js/jquery-ui/effects.shake.min.js1
-rwxr-xr-xsite/app/webroot/js/jquery-ui/effects.slide.min.js1
-rwxr-xr-xsite/app/webroot/js/jquery-ui/effects.transfer.min.js1
-rw-r--r--site/app/webroot/js/jquery-ui/jq-ui-162rc2-accordion-bundle-a11y.min.js1
-rw-r--r--site/app/webroot/js/jquery-ui/jqModal.js69
-rw-r--r--site/app/webroot/js/jquery-ui/jquery.dimensions.js116
-rw-r--r--site/app/webroot/js/jquery-ui/jquery.dimensions.min.js20
-rwxr-xr-xsite/app/webroot/js/jquery-ui/jquery.ui.all.min.js1
-rwxr-xr-xsite/app/webroot/js/jquery-ui/ui.accordion.min.js1
-rwxr-xr-xsite/app/webroot/js/jquery-ui/ui.autocomplete.min.js1
-rwxr-xr-xsite/app/webroot/js/jquery-ui/ui.colorpicker.min.js1
-rwxr-xr-xsite/app/webroot/js/jquery-ui/ui.core.min.js1
-rwxr-xr-xsite/app/webroot/js/jquery-ui/ui.datepicker.min.js1
-rwxr-xr-xsite/app/webroot/js/jquery-ui/ui.dialog.min.js1
-rwxr-xr-xsite/app/webroot/js/jquery-ui/ui.draggable.min.js1
-rwxr-xr-xsite/app/webroot/js/jquery-ui/ui.droppable.min.js1
-rw-r--r--site/app/webroot/js/jquery-ui/ui.lightbox.js446
-rwxr-xr-xsite/app/webroot/js/jquery-ui/ui.magnifier.min.js1
-rwxr-xr-xsite/app/webroot/js/jquery-ui/ui.progressbar.min.js1
-rwxr-xr-xsite/app/webroot/js/jquery-ui/ui.resizable.min.js1
-rwxr-xr-xsite/app/webroot/js/jquery-ui/ui.selectable.min.js1
-rwxr-xr-xsite/app/webroot/js/jquery-ui/ui.slider.min.js1
-rwxr-xr-xsite/app/webroot/js/jquery-ui/ui.sortable.min.js1
-rwxr-xr-xsite/app/webroot/js/jquery-ui/ui.spinner.min.js1
-rwxr-xr-xsite/app/webroot/js/jquery-ui/ui.tabs.min.js1
-rw-r--r--site/app/webroot/js/jquery.addons.min.js1
-rw-r--r--site/app/webroot/js/jquery.autocomplete.pack.js13
-rw-r--r--site/app/webroot/js/jquery.cookie.js96
-rw-r--r--site/app/webroot/js/jquery.flot.js2380
-rw-r--r--site/app/webroot/js/jquery.sparkline.min.js72
-rw-r--r--site/app/webroot/js/jquery.tablesorter.min.js2
-rw-r--r--site/app/webroot/js/json.js2
-rw-r--r--site/app/webroot/js/listing.js28
-rw-r--r--site/app/webroot/js/mochikit/MochiKit.js4802
-rw-r--r--site/app/webroot/js/mochikit/__package__.js2
-rw-r--r--site/app/webroot/js/mootools/mootools-release-1.11.js184
-rw-r--r--site/app/webroot/js/plotkit/Base.js406
-rw-r--r--site/app/webroot/js/plotkit/Canvas.js683
-rw-r--r--site/app/webroot/js/plotkit/EasyPlot.js161
-rw-r--r--site/app/webroot/js/plotkit/Layout.js756
-rw-r--r--site/app/webroot/js/plotkit/PlotKit.js151
-rw-r--r--site/app/webroot/js/plotkit/PlotKit_Packed.js2177
-rw-r--r--site/app/webroot/js/plotkit/SVG.js705
-rw-r--r--site/app/webroot/js/plotkit/SweetCanvas.js348
-rw-r--r--site/app/webroot/js/plotkit/SweetSVG.js247
-rw-r--r--site/app/webroot/js/plotkit/dummy.svg9
-rwxr-xr-xsite/app/webroot/js/plotkit/excanvas.js723
-rw-r--r--site/app/webroot/js/reviews.js105
-rw-r--r--site/app/webroot/js/scriptaculous/builder.js101
-rw-r--r--site/app/webroot/js/scriptaculous/controls.js821
-rw-r--r--site/app/webroot/js/scriptaculous/dragdrop.js931
-rw-r--r--site/app/webroot/js/scriptaculous/effects.js959
-rw-r--r--site/app/webroot/js/scriptaculous/prototype.js2006
-rw-r--r--site/app/webroot/js/scriptaculous/scriptaculous.js47
-rw-r--r--site/app/webroot/js/scriptaculous/slider.js292
-rw-r--r--site/app/webroot/js/scriptaculous/unittest.js390
-rw-r--r--site/app/webroot/js/simile/ajax/ajax-api-amo-bundle.js161
-rwxr-xr-xsite/app/webroot/js/simile/ajax/content/history.html7
-rwxr-xr-xsite/app/webroot/js/simile/ajax/images/bubble-bottom-arrow.pngbin0 -> 1087 bytes
-rwxr-xr-xsite/app/webroot/js/simile/ajax/images/bubble-bottom-left.pngbin0 -> 754 bytes
-rwxr-xr-xsite/app/webroot/js/simile/ajax/images/bubble-bottom-right.pngbin0 -> 803 bytes
-rwxr-xr-xsite/app/webroot/js/simile/ajax/images/bubble-bottom.pngbin0 -> 1141 bytes
-rwxr-xr-xsite/app/webroot/js/simile/ajax/images/bubble-left-arrow.pngbin0 -> 880 bytes
-rwxr-xr-xsite/app/webroot/js/simile/ajax/images/bubble-left.pngbin0 -> 5670 bytes
-rwxr-xr-xsite/app/webroot/js/simile/ajax/images/bubble-right-arrow.pngbin0 -> 941 bytes
-rwxr-xr-xsite/app/webroot/js/simile/ajax/images/bubble-right.pngbin0 -> 5686 bytes
-rwxr-xr-xsite/app/webroot/js/simile/ajax/images/bubble-top-arrow.pngbin0 -> 793 bytes
-rwxr-xr-xsite/app/webroot/js/simile/ajax/images/bubble-top-left.pngbin0 -> 560 bytes
-rwxr-xr-xsite/app/webroot/js/simile/ajax/images/bubble-top-right.pngbin0 -> 676 bytes
-rwxr-xr-xsite/app/webroot/js/simile/ajax/images/bubble-top.pngbin0 -> 905 bytes
-rwxr-xr-xsite/app/webroot/js/simile/ajax/images/close-button.pngbin0 -> 624 bytes
-rwxr-xr-xsite/app/webroot/js/simile/ajax/images/copy.pngbin0 -> 196 bytes
-rwxr-xr-xsite/app/webroot/js/simile/ajax/images/message-bottom-left.pngbin0 -> 1339 bytes
-rwxr-xr-xsite/app/webroot/js/simile/ajax/images/message-bottom-right.pngbin0 -> 2074 bytes
-rwxr-xr-xsite/app/webroot/js/simile/ajax/images/message-left.pngbin0 -> 717 bytes
-rwxr-xr-xsite/app/webroot/js/simile/ajax/images/message-right.pngbin0 -> 1892 bytes
-rwxr-xr-xsite/app/webroot/js/simile/ajax/images/message-top-left.pngbin0 -> 918 bytes
-rwxr-xr-xsite/app/webroot/js/simile/ajax/images/message-top-right.pngbin0 -> 1604 bytes
-rwxr-xr-xsite/app/webroot/js/simile/ajax/scripts/ajax.js45
-rwxr-xr-xsite/app/webroot/js/simile/ajax/scripts/data-structure.js447
-rwxr-xr-xsite/app/webroot/js/simile/ajax/scripts/date-time.js452
-rwxr-xr-xsite/app/webroot/js/simile/ajax/scripts/debug.js94
-rwxr-xr-xsite/app/webroot/js/simile/ajax/scripts/dom.js324
-rwxr-xr-xsite/app/webroot/js/simile/ajax/scripts/graphics.js572
-rwxr-xr-xsite/app/webroot/js/simile/ajax/scripts/history.js220
-rwxr-xr-xsite/app/webroot/js/simile/ajax/scripts/html.js274
-rwxr-xr-xsite/app/webroot/js/simile/ajax/scripts/jquery-1.2.1.js2992
-rwxr-xr-xsite/app/webroot/js/simile/ajax/scripts/json.js129
-rwxr-xr-xsite/app/webroot/js/simile/ajax/scripts/platform.js98
-rwxr-xr-xsite/app/webroot/js/simile/ajax/scripts/signal.js44
-rwxr-xr-xsite/app/webroot/js/simile/ajax/scripts/string.js43
-rwxr-xr-xsite/app/webroot/js/simile/ajax/scripts/units.js64
-rwxr-xr-xsite/app/webroot/js/simile/ajax/scripts/window-manager.js414
-rwxr-xr-xsite/app/webroot/js/simile/ajax/scripts/xmlhttp.js137
-rwxr-xr-xsite/app/webroot/js/simile/ajax/simile-ajax-api.js211
-rwxr-xr-xsite/app/webroot/js/simile/ajax/simile-ajax-bundle.js2464
-rw-r--r--site/app/webroot/js/simile/amo-bundle.compressed.js1
-rw-r--r--site/app/webroot/js/simile/amo-bundle.js10830
-rw-r--r--site/app/webroot/js/simile/bundlemaker/ajax.txt14
-rw-r--r--site/app/webroot/js/simile/bundlemaker/bundle-template.js263
-rwxr-xr-xsite/app/webroot/js/simile/bundlemaker/class.JavaScriptPacker.php736
-rwxr-xr-xsite/app/webroot/js/simile/bundlemaker/make-bundle.sh23
-rw-r--r--site/app/webroot/js/simile/bundlemaker/pack-bundle.php26
-rw-r--r--site/app/webroot/js/simile/bundlemaker/timeline.txt12
-rw-r--r--site/app/webroot/js/simile/bundlemaker/timeplot.txt9
-rwxr-xr-xsite/app/webroot/js/simile/timeline/ext/geochrono/geochrono-api.js92
-rwxr-xr-xsite/app/webroot/js/simile/timeline/ext/geochrono/scripts/ether-painters.js204
-rwxr-xr-xsite/app/webroot/js/simile/timeline/ext/geochrono/scripts/geochrono.js518
-rwxr-xr-xsite/app/webroot/js/simile/timeline/ext/geochrono/scripts/l10n/en/labellers.js10
-rwxr-xr-xsite/app/webroot/js/simile/timeline/ext/geochrono/scripts/labellers.js52
-rwxr-xr-xsite/app/webroot/js/simile/timeline/ext/geochrono/scripts/units.js86
-rwxr-xr-xsite/app/webroot/js/simile/timeline/ext/planning/planning-api.js92
-rwxr-xr-xsite/app/webroot/js/simile/timeline/ext/planning/scripts/ether-painters.js176
-rwxr-xr-xsite/app/webroot/js/simile/timeline/ext/planning/scripts/l10n/en/labellers.js12
-rwxr-xr-xsite/app/webroot/js/simile/timeline/ext/planning/scripts/labellers.js33
-rwxr-xr-xsite/app/webroot/js/simile/timeline/ext/planning/scripts/planning.js47
-rwxr-xr-xsite/app/webroot/js/simile/timeline/ext/planning/scripts/units.js66
-rwxr-xr-xsite/app/webroot/js/simile/timeline/images/blue-circle.pngbin0 -> 534 bytes
-rwxr-xr-xsite/app/webroot/js/simile/timeline/images/bubble-bottom-arrow.pngbin0 -> 1087 bytes
-rwxr-xr-xsite/app/webroot/js/simile/timeline/images/bubble-bottom-left.pngbin0 -> 754 bytes
-rwxr-xr-xsite/app/webroot/js/simile/timeline/images/bubble-bottom-right.pngbin0 -> 803 bytes
-rwxr-xr-xsite/app/webroot/js/simile/timeline/images/bubble-bottom.pngbin0 -> 1141 bytes
-rwxr-xr-xsite/app/webroot/js/simile/timeline/images/bubble-left-arrow.pngbin0 -> 880 bytes
-rwxr-xr-xsite/app/webroot/js/simile/timeline/images/bubble-left.pngbin0 -> 5670 bytes
-rwxr-xr-xsite/app/webroot/js/simile/timeline/images/bubble-right-arrow.pngbin0 -> 941 bytes
-rwxr-xr-xsite/app/webroot/js/simile/timeline/images/bubble-right.pngbin0 -> 5686 bytes
-rwxr-xr-xsite/app/webroot/js/simile/timeline/images/bubble-top-arrow.pngbin0 -> 793 bytes
-rwxr-xr-xsite/app/webroot/js/simile/timeline/images/bubble-top-left.pngbin0 -> 560 bytes
-rwxr-xr-xsite/app/webroot/js/simile/timeline/images/bubble-top-right.pngbin0 -> 676 bytes
-rwxr-xr-xsite/app/webroot/js/simile/timeline/images/bubble-top.pngbin0 -> 905 bytes
-rwxr-xr-xsite/app/webroot/js/simile/timeline/images/close-button.pngbin0 -> 624 bytes
-rwxr-xr-xsite/app/webroot/js/simile/timeline/images/copyright-vertical.pngbin0 -> 1695 bytes
-rwxr-xr-xsite/app/webroot/js/simile/timeline/images/copyright.pngbin0 -> 1400 bytes
-rwxr-xr-xsite/app/webroot/js/simile/timeline/images/dark-blue-circle.pngbin0 -> 551 bytes
-rwxr-xr-xsite/app/webroot/js/simile/timeline/images/dark-green-circle.pngbin0 -> 513 bytes
-rwxr-xr-xsite/app/webroot/js/simile/timeline/images/dark-red-circle.pngbin0 -> 497 bytes
-rwxr-xr-xsite/app/webroot/js/simile/timeline/images/dull-blue-circle.pngbin0 -> 539 bytes
-rwxr-xr-xsite/app/webroot/js/simile/timeline/images/dull-green-circle.pngbin0 -> 539 bytes
-rwxr-xr-xsite/app/webroot/js/simile/timeline/images/dull-red-circle.pngbin0 -> 532 bytes
-rwxr-xr-xsite/app/webroot/js/simile/timeline/images/gray-circle.pngbin0 -> 513 bytes
-rwxr-xr-xsite/app/webroot/js/simile/timeline/images/green-circle.pngbin0 -> 544 bytes
-rwxr-xr-xsite/app/webroot/js/simile/timeline/images/message-bottom-left.pngbin0 -> 1339 bytes
-rwxr-xr-xsite/app/webroot/js/simile/timeline/images/message-bottom-right.pngbin0 -> 2074 bytes
-rwxr-xr-xsite/app/webroot/js/simile/timeline/images/message-left.pngbin0 -> 717 bytes
-rwxr-xr-xsite/app/webroot/js/simile/timeline/images/message-right.pngbin0 -> 1892 bytes
-rwxr-xr-xsite/app/webroot/js/simile/timeline/images/message-top-left.pngbin0 -> 918 bytes
-rwxr-xr-xsite/app/webroot/js/simile/timeline/images/message-top-right.pngbin0 -> 1604 bytes
-rwxr-xr-xsite/app/webroot/js/simile/timeline/images/progress-running.gifbin0 -> 1002 bytes
-rwxr-xr-xsite/app/webroot/js/simile/timeline/images/red-circle.pngbin0 -> 538 bytes
-rwxr-xr-xsite/app/webroot/js/simile/timeline/images/top-bubble.pngbin0 -> 6092 bytes
-rwxr-xr-xsite/app/webroot/js/simile/timeline/scripts/decorators.js186
-rwxr-xr-xsite/app/webroot/js/simile/timeline/scripts/detailed-painter.js667
-rwxr-xr-xsite/app/webroot/js/simile/timeline/scripts/ether-painters.js566
-rwxr-xr-xsite/app/webroot/js/simile/timeline/scripts/ethers.js250
-rwxr-xr-xsite/app/webroot/js/simile/timeline/scripts/ext/japanese-eras.js395
-rwxr-xr-xsite/app/webroot/js/simile/timeline/scripts/l10n/cs/labellers.js30
-rwxr-xr-xsite/app/webroot/js/simile/timeline/scripts/l10n/cs/timeline.js9
-rwxr-xr-xsite/app/webroot/js/simile/timeline/scripts/l10n/de/labellers.js27
-rwxr-xr-xsite/app/webroot/js/simile/timeline/scripts/l10n/de/timeline.js8
-rwxr-xr-xsite/app/webroot/js/simile/timeline/scripts/l10n/en/labellers.js8
-rwxr-xr-xsite/app/webroot/js/simile/timeline/scripts/l10n/en/timeline.js9
-rwxr-xr-xsite/app/webroot/js/simile/timeline/scripts/l10n/es/labellers.js8
-rwxr-xr-xsite/app/webroot/js/simile/timeline/scripts/l10n/es/timeline.js9
-rwxr-xr-xsite/app/webroot/js/simile/timeline/scripts/l10n/fr/labellers.js8
-rwxr-xr-xsite/app/webroot/js/simile/timeline/scripts/l10n/fr/timeline.js9
-rwxr-xr-xsite/app/webroot/js/simile/timeline/scripts/l10n/it/labellers.js8
-rwxr-xr-xsite/app/webroot/js/simile/timeline/scripts/l10n/it/timeline.js9
-rwxr-xr-xsite/app/webroot/js/simile/timeline/scripts/l10n/ru/labellers.js10
-rwxr-xr-xsite/app/webroot/js/simile/timeline/scripts/l10n/ru/timeline.js9
-rwxr-xr-xsite/app/webroot/js/simile/timeline/scripts/l10n/se/labellers.js12
-rwxr-xr-xsite/app/webroot/js/simile/timeline/scripts/l10n/se/timeline.js9
-rwxr-xr-xsite/app/webroot/js/simile/timeline/scripts/l10n/tr/labellers.js8
-rwxr-xr-xsite/app/webroot/js/simile/timeline/scripts/l10n/tr/timeline.js9
-rwxr-xr-xsite/app/webroot/js/simile/timeline/scripts/l10n/vi/labellers.js26
-rwxr-xr-xsite/app/webroot/js/simile/timeline/scripts/l10n/vi/timeline.js9
-rwxr-xr-xsite/app/webroot/js/simile/timeline/scripts/l10n/zh/labellers.js27
-rwxr-xr-xsite/app/webroot/js/simile/timeline/scripts/l10n/zh/timeline.js9
-rwxr-xr-xsite/app/webroot/js/simile/timeline/scripts/labellers.js91
-rwxr-xr-xsite/app/webroot/js/simile/timeline/scripts/original-painter.js488
-rwxr-xr-xsite/app/webroot/js/simile/timeline/scripts/overview-painter.js231
-rwxr-xr-xsite/app/webroot/js/simile/timeline/scripts/sources.js439
-rwxr-xr-xsite/app/webroot/js/simile/timeline/scripts/themes.js136
-rwxr-xr-xsite/app/webroot/js/simile/timeline/scripts/timeline.js913
-rwxr-xr-xsite/app/webroot/js/simile/timeline/scripts/units.js68
-rw-r--r--site/app/webroot/js/simile/timeline/timeline-api-amo-bundle.js25
-rwxr-xr-xsite/app/webroot/js/simile/timeline/timeline-api.js224
-rwxr-xr-xsite/app/webroot/js/simile/timeline/timeline-bundle.css172
-rwxr-xr-xsite/app/webroot/js/simile/timeline/timeline-bundle.js4007
-rwxr-xr-xsite/app/webroot/js/simile/timeplot/images/copyright.pngbin0 -> 4291 bytes
-rwxr-xr-xsite/app/webroot/js/simile/timeplot/images/line_left.pngbin0 -> 340 bytes
-rwxr-xr-xsite/app/webroot/js/simile/timeplot/images/line_right.pngbin0 -> 340 bytes
-rwxr-xr-xsite/app/webroot/js/simile/timeplot/images/progress-running.gifbin0 -> 1002 bytes
-rwxr-xr-xsite/app/webroot/js/simile/timeplot/lib/excanvas.js785
-rwxr-xr-xsite/app/webroot/js/simile/timeplot/lib/firebug/errorIcon.pngbin0 -> 457 bytes
-rwxr-xr-xsite/app/webroot/js/simile/timeplot/lib/firebug/firebug.css209
-rwxr-xr-xsite/app/webroot/js/simile/timeplot/lib/firebug/firebug.html23
-rwxr-xr-xsite/app/webroot/js/simile/timeplot/lib/firebug/firebug.js672
-rwxr-xr-xsite/app/webroot/js/simile/timeplot/lib/firebug/firebugx.js10
-rwxr-xr-xsite/app/webroot/js/simile/timeplot/lib/firebug/infoIcon.pngbin0 -> 524 bytes
-rwxr-xr-xsite/app/webroot/js/simile/timeplot/lib/firebug/warningIcon.pngbin0 -> 516 bytes
-rwxr-xr-xsite/app/webroot/js/simile/timeplot/locales/en/locale.js0
-rwxr-xr-xsite/app/webroot/js/simile/timeplot/scripts/color.js152
-rwxr-xr-xsite/app/webroot/js/simile/timeplot/scripts/geometry.js861
-rwxr-xr-xsite/app/webroot/js/simile/timeplot/scripts/math.js193
-rwxr-xr-xsite/app/webroot/js/simile/timeplot/scripts/plot.js386
-rwxr-xr-xsite/app/webroot/js/simile/timeplot/scripts/processor.js120
-rwxr-xr-xsite/app/webroot/js/simile/timeplot/scripts/sources.js348
-rwxr-xr-xsite/app/webroot/js/simile/timeplot/scripts/timeplot.js603
-rw-r--r--site/app/webroot/js/simile/timeplot/timeplot-api-amo-bundle.js78
-rwxr-xr-xsite/app/webroot/js/simile/timeplot/timeplot-api.js190
-rwxr-xr-xsite/app/webroot/js/simile/timeplot/timeplot-bundle.css95
-rwxr-xr-xsite/app/webroot/js/simile/timeplot/timeplot-bundle.js2253
-rw-r--r--site/app/webroot/js/slimbox/slimbox.js257
-rwxr-xr-xsite/app/webroot/js/stats/colors.js34
-rwxr-xr-xsite/app/webroot/js/stats/dropdowns.js443
-rwxr-xr-xsite/app/webroot/js/stats/plot-selection.js380
-rw-r--r--site/app/webroot/js/stats/plot-tables.js191
-rwxr-xr-xsite/app/webroot/js/stats/plots.js577
-rw-r--r--site/app/webroot/js/stats/stats.js65
-rw-r--r--site/app/webroot/js/strftime-min-1.3.js1
-rw-r--r--site/app/webroot/js/vendors.php36
-rw-r--r--site/app/webroot/kodak/kodak_extension.html15
-rw-r--r--site/app/webroot/licenses/0.txt470
-rw-r--r--site/app/webroot/licenses/1.txt339
-rw-r--r--site/app/webroot/licenses/2.txt674
-rw-r--r--site/app/webroot/licenses/3.txt504
-rw-r--r--site/app/webroot/licenses/4.txt165
-rw-r--r--site/app/webroot/licenses/5.txt21
-rw-r--r--site/app/webroot/licenses/6.txt56
-rw-r--r--site/app/webroot/newsletter/.htaccess4
-rw-r--r--site/app/webroot/newsletter/banner.pngbin0 -> 66827 bytes
-rw-r--r--site/app/webroot/sample/icon.gifbin0 -> 1739 bytes
-rw-r--r--site/app/webroot/sample/screenshot.gifbin0 -> 7389 bytes
-rw-r--r--site/app/webroot/sample/screenshot2.gifbin0 -> 29081 bytes
-rw-r--r--site/app/webroot/sample/screenshot3.gifbin0 -> 21509 bytes
-rw-r--r--site/app/webroot/services/blocklist.php461
-rw-r--r--site/app/webroot/services/functions.php76
-rw-r--r--site/app/webroot/services/install.php233
-rw-r--r--site/app/webroot/services/monitor.php133
-rw-r--r--site/app/webroot/services/pfs.php435
-rw-r--r--site/app/webroot/services/update.php420
-rw-r--r--site/cake/LICENSE.txt24
-rw-r--r--site/cake/VERSION.txt9
-rw-r--r--site/cake/app_controller.php42
-rw-r--r--site/cake/app_model.php42
-rw-r--r--site/cake/basics.php1169
-rw-r--r--site/cake/bootstrap.php104
-rw-r--r--site/cake/config/config.php28
-rw-r--r--site/cake/config/paths.php175
-rw-r--r--site/cake/dispatcher.php429
-rw-r--r--site/cake/libs/cache.php137
-rw-r--r--site/cake/libs/cake_log.php57
-rw-r--r--site/cake/libs/class_registry.php117
-rw-r--r--site/cake/libs/configure.php354
-rw-r--r--site/cake/libs/controller/component.php139
-rw-r--r--site/cake/libs/controller/components/acl.php196
-rw-r--r--site/cake/libs/controller/components/acl_base.php63
-rw-r--r--site/cake/libs/controller/components/dbacl/db_acl.php310
-rw-r--r--site/cake/libs/controller/components/dbacl/models/aclnode.php309
-rw-r--r--site/cake/libs/controller/components/dbacl/models/aco.php52
-rw-r--r--site/cake/libs/controller/components/dbacl/models/acoaction.php56
-rw-r--r--site/cake/libs/controller/components/dbacl/models/aro.php52
-rw-r--r--site/cake/libs/controller/components/dbacl/models/aros_aco.php63
-rw-r--r--site/cake/libs/controller/components/iniacl/ini_acl.php184
-rw-r--r--site/cake/libs/controller/components/request_handler.php412
-rw-r--r--site/cake/libs/controller/components/security.php202
-rw-r--r--site/cake/libs/controller/components/session.php375
-rw-r--r--site/cake/libs/controller/controller.php998
-rw-r--r--site/cake/libs/controller/pages_controller.php105
-rw-r--r--site/cake/libs/controller/scaffold.php432
-rw-r--r--site/cake/libs/error.php347
-rw-r--r--site/cake/libs/file.php293
-rw-r--r--site/cake/libs/flay.php278
-rw-r--r--site/cake/libs/folder.php328
-rw-r--r--site/cake/libs/inflector.php437
-rw-r--r--site/cake/libs/legacy.php70
-rw-r--r--site/cake/libs/model/connection_manager.php243
-rw-r--r--site/cake/libs/model/datasources/datasource.php492
-rw-r--r--site/cake/libs/model/datasources/dbo_source.php1894
-rw-r--r--site/cake/libs/model/dbo/dbo_adodb.php437
-rw-r--r--site/cake/libs/model/dbo/dbo_mssql.php604
-rw-r--r--site/cake/libs/model/dbo/dbo_mysql.php679
-rw-r--r--site/cake/libs/model/dbo/dbo_mysqli.php441
-rw-r--r--site/cake/libs/model/dbo/dbo_odbc.php437
-rw-r--r--site/cake/libs/model/dbo/dbo_pear.php241
-rw-r--r--site/cake/libs/model/dbo/dbo_postgres.php595
-rw-r--r--site/cake/libs/model/dbo/dbo_sqlite.php409
-rw-r--r--site/cake/libs/model/model.php42
-rw-r--r--site/cake/libs/model/model_php4.php1712
-rw-r--r--site/cake/libs/model/model_php5.php1701
-rw-r--r--site/cake/libs/neat_array.php318
-rw-r--r--site/cake/libs/neat_string.php88
-rw-r--r--site/cake/libs/object.php259
-rw-r--r--site/cake/libs/router.php230
-rw-r--r--site/cake/libs/sanitize.php245
-rw-r--r--site/cake/libs/security.php151
-rw-r--r--site/cake/libs/session.php777
-rw-r--r--site/cake/libs/set.php805
-rw-r--r--site/cake/libs/validators.php45
-rw-r--r--site/cake/libs/view/helper.php167
-rw-r--r--site/cake/libs/view/helpers/ajax.php853
-rw-r--r--site/cake/libs/view/helpers/cache.php266
-rw-r--r--site/cake/libs/view/helpers/form.php491
-rw-r--r--site/cake/libs/view/helpers/html.php1257
-rw-r--r--site/cake/libs/view/helpers/javascript.php317
-rw-r--r--site/cake/libs/view/helpers/number.php88
-rw-r--r--site/cake/libs/view/helpers/session.php198
-rw-r--r--site/cake/libs/view/helpers/text.php238
-rw-r--r--site/cake/libs/view/helpers/time.php397
-rw-r--r--site/cake/libs/view/templates/elements/dump.thtml32
-rw-r--r--site/cake/libs/view/templates/errors/error404.thtml28
-rw-r--r--site/cake/libs/view/templates/errors/missing_action.thtml37
-rw-r--r--site/cake/libs/view/templates/errors/missing_component_class.thtml36
-rw-r--r--site/cake/libs/view/templates/errors/missing_component_file.thtml35
-rw-r--r--site/cake/libs/view/templates/errors/missing_connection.thtml30
-rw-r--r--site/cake/libs/view/templates/errors/missing_controller.thtml36
-rw-r--r--site/cake/libs/view/templates/errors/missing_helper_class.thtml35
-rw-r--r--site/cake/libs/view/templates/errors/missing_helper_file.thtml35
-rw-r--r--site/cake/libs/view/templates/errors/missing_layout.thtml30
-rw-r--r--site/cake/libs/view/templates/errors/missing_model.thtml36
-rw-r--r--site/cake/libs/view/templates/errors/missing_scaffolddb.thtml30
-rw-r--r--site/cake/libs/view/templates/errors/missing_table.thtml29
-rw-r--r--site/cake/libs/view/templates/errors/missing_view.thtml30
-rw-r--r--site/cake/libs/view/templates/errors/private_action.thtml29
-rw-r--r--site/cake/libs/view/templates/errors/scaffold_error.thtml33
-rw-r--r--site/cake/libs/view/templates/layouts/ajax.thtml27
-rw-r--r--site/cake/libs/view/templates/layouts/default.thtml58
-rw-r--r--site/cake/libs/view/templates/layouts/flash.thtml45
-rw-r--r--site/cake/libs/view/templates/pages/home.thtml75
-rw-r--r--site/cake/libs/view/templates/scaffolds/add.thtml40
-rw-r--r--site/cake/libs/view/templates/scaffolds/edit.thtml56
-rw-r--r--site/cake/libs/view/templates/scaffolds/index.thtml95
-rw-r--r--site/cake/libs/view/templates/scaffolds/view.thtml166
-rw-r--r--site/cake/libs/view/view.php765
-rw-r--r--site/cake/scripts/acl.php853
-rw-r--r--site/cake/scripts/bake.php2635
-rw-r--r--site/cake/scripts/templates/skel/.htaccess5
-rw-r--r--site/cake/scripts/templates/skel/app_controller.php41
-rw-r--r--site/cake/scripts/templates/skel/app_model.php43
-rw-r--r--site/cake/scripts/templates/skel/config/acl.ini.php76
-rw-r--r--site/cake/scripts/templates/skel/config/bootstrap.php46
-rw-r--r--site/cake/scripts/templates/skel/config/core.php146
-rw-r--r--site/cake/scripts/templates/skel/config/database.php.default74
-rw-r--r--site/cake/scripts/templates/skel/config/inflections.php72
-rw-r--r--site/cake/scripts/templates/skel/config/routes.php46
-rw-r--r--site/cake/scripts/templates/skel/config/sql/db_acl.sql30
-rw-r--r--site/cake/scripts/templates/skel/config/sql/sessions.sql11
-rw-r--r--site/cake/scripts/templates/skel/controllers/pages_controller.php105
-rw-r--r--site/cake/scripts/templates/skel/index.php26
-rw-r--r--site/cake/scripts/templates/skel/views/layouts/ajax.thtml30
-rw-r--r--site/cake/scripts/templates/skel/views/layouts/default.thtml30
-rw-r--r--site/cake/scripts/templates/skel/views/layouts/flash.thtml50
-rw-r--r--site/cake/scripts/templates/skel/webroot/.htaccess6
-rw-r--r--site/cake/scripts/templates/skel/webroot/css.php100
-rw-r--r--site/cake/scripts/templates/skel/webroot/css/cake.generic.css251
-rw-r--r--site/cake/scripts/templates/skel/webroot/favicon.icobin0 -> 4973 bytes
-rw-r--r--site/cake/scripts/templates/skel/webroot/img/cake.power.pngbin0 -> 3053 bytes
-rw-r--r--site/cake/scripts/templates/skel/webroot/index.php87
-rw-r--r--site/cake/scripts/templates/skel/webroot/js/vendors.php43
-rw-r--r--site/cake/scripts/templates/views/home.thtml16
-rw-r--r--site/index.php77
-rw-r--r--site/vendors/facebook/facebook.php243
-rw-r--r--site/vendors/facebook/facebookapi_php5_restlib.php1553
-rw-r--r--site/vendors/phpQuery/Callback.php38
-rw-r--r--site/vendors/phpQuery/DOMDocumentWrapper.php606
-rw-r--r--site/vendors/phpQuery/DOMEvent.php107
-rw-r--r--site/vendors/phpQuery/LICENSE19
-rw-r--r--site/vendors/phpQuery/Zend/Exception.php30
-rw-r--r--site/vendors/phpQuery/Zend/Http/Client.php1186
-rw-r--r--site/vendors/phpQuery/Zend/Http/Client/Adapter/Exception.php33
-rw-r--r--site/vendors/phpQuery/Zend/Http/Client/Adapter/Interface.php78
-rw-r--r--site/vendors/phpQuery/Zend/Http/Client/Adapter/Proxy.php268
-rw-r--r--site/vendors/phpQuery/Zend/Http/Client/Adapter/Socket.php332
-rw-r--r--site/vendors/phpQuery/Zend/Http/Client/Adapter/Test.php193
-rw-r--r--site/vendors/phpQuery/Zend/Http/Client/Exception.php33
-rw-r--r--site/vendors/phpQuery/Zend/Http/Cookie.php327
-rw-r--r--site/vendors/phpQuery/Zend/Http/CookieJar.php350
-rw-r--r--site/vendors/phpQuery/Zend/Http/Exception.php33
-rw-r--r--site/vendors/phpQuery/Zend/Http/Response.php625
-rw-r--r--site/vendors/phpQuery/Zend/Json/Decoder.php457
-rw-r--r--site/vendors/phpQuery/Zend/Json/Encoder.php431
-rw-r--r--site/vendors/phpQuery/Zend/Json/Exception.php36
-rw-r--r--site/vendors/phpQuery/Zend/Loader.php258
-rw-r--r--site/vendors/phpQuery/Zend/Registry.php195
-rw-r--r--site/vendors/phpQuery/Zend/Uri.php164
-rw-r--r--site/vendors/phpQuery/Zend/Uri/Exception.php37
-rw-r--r--site/vendors/phpQuery/Zend/Uri/Http.php702
-rw-r--r--site/vendors/phpQuery/Zend/Validate/Abstract.php348
-rw-r--r--site/vendors/phpQuery/Zend/Validate/Alnum.php120
-rw-r--r--site/vendors/phpQuery/Zend/Validate/Alpha.php120
-rw-r--r--site/vendors/phpQuery/Zend/Validate/Barcode.php99
-rw-r--r--site/vendors/phpQuery/Zend/Validate/Barcode/Ean13.php100
-rw-r--r--site/vendors/phpQuery/Zend/Validate/Barcode/UpcA.php100
-rw-r--r--site/vendors/phpQuery/Zend/Validate/Between.php200
-rw-r--r--site/vendors/phpQuery/Zend/Validate/Ccnum.php111
-rw-r--r--site/vendors/phpQuery/Zend/Validate/Date.php250
-rw-r--r--site/vendors/phpQuery/Zend/Validate/Digits.php100
-rw-r--r--site/vendors/phpQuery/Zend/Validate/EmailAddress.php245
-rw-r--r--site/vendors/phpQuery/Zend/Validate/Exception.php37
-rw-r--r--site/vendors/phpQuery/Zend/Validate/File/Count.php229
-rw-r--r--site/vendors/phpQuery/Zend/Validate/File/Exists.php192
-rw-r--r--site/vendors/phpQuery/Zend/Validate/File/Extension.php204
-rw-r--r--site/vendors/phpQuery/Zend/Validate/File/FilesSize.php156
-rw-r--r--site/vendors/phpQuery/Zend/Validate/File/ImageSize.php335
-rw-r--r--site/vendors/phpQuery/Zend/Validate/File/MimeType.php200
-rw-r--r--site/vendors/phpQuery/Zend/Validate/File/NotExists.php86
-rw-r--r--site/vendors/phpQuery/Zend/Validate/File/Size.php308
-rw-r--r--site/vendors/phpQuery/Zend/Validate/File/Upload.php216
-rw-r--r--site/vendors/phpQuery/Zend/Validate/Float.php75
-rw-r--r--site/vendors/phpQuery/Zend/Validate/GreaterThan.php114
-rw-r--r--site/vendors/phpQuery/Zend/Validate/Hex.php74
-rw-r--r--site/vendors/phpQuery/Zend/Validate/Hostname.php444
-rw-r--r--site/vendors/phpQuery/Zend/Validate/Hostname/At.php50
-rw-r--r--site/vendors/phpQuery/Zend/Validate/Hostname/Ch.php50
-rw-r--r--site/vendors/phpQuery/Zend/Validate/Hostname/De.php58
-rw-r--r--site/vendors/phpQuery/Zend/Validate/Hostname/Fi.php50
-rw-r--r--site/vendors/phpQuery/Zend/Validate/Hostname/Hu.php50
-rw-r--r--site/vendors/phpQuery/Zend/Validate/Hostname/Interface.php52
-rw-r--r--site/vendors/phpQuery/Zend/Validate/Hostname/Li.php50
-rw-r--r--site/vendors/phpQuery/Zend/Validate/Hostname/No.php52
-rw-r--r--site/vendors/phpQuery/Zend/Validate/Hostname/Se.php50
-rw-r--r--site/vendors/phpQuery/Zend/Validate/Identical.php117
-rw-r--r--site/vendors/phpQuery/Zend/Validate/InArray.php138
-rw-r--r--site/vendors/phpQuery/Zend/Validate/Int.php75
-rw-r--r--site/vendors/phpQuery/Zend/Validate/Interface.php71
-rw-r--r--site/vendors/phpQuery/Zend/Validate/Ip.php70
-rw-r--r--site/vendors/phpQuery/Zend/Validate/LessThan.php113
-rw-r--r--site/vendors/phpQuery/Zend/Validate/NotEmpty.php74
-rw-r--r--site/vendors/phpQuery/Zend/Validate/Regex.php125
-rw-r--r--site/vendors/phpQuery/Zend/Validate/StringLength.php180
-rw-r--r--site/vendors/phpQuery/bootstrap.example.php14
-rw-r--r--site/vendors/phpQuery/compat/mbstring.php88
-rw-r--r--site/vendors/phpQuery/phpQuery.php1074
-rw-r--r--site/vendors/phpQuery/phpQueryEvents.php153
-rw-r--r--site/vendors/phpQuery/phpQueryObject.php3134
-rw-r--r--site/vendors/phpQuery/plugins/Scripts.php48
-rw-r--r--site/vendors/phpQuery/plugins/Scripts/__config.example.php10
-rw-r--r--site/vendors/phpQuery/plugins/Scripts/example.php14
-rw-r--r--site/vendors/phpQuery/plugins/Scripts/fix_webroot.php16
-rw-r--r--site/vendors/phpQuery/plugins/Scripts/google_login.php47
-rw-r--r--site/vendors/phpQuery/plugins/Scripts/print_source.php9
-rw-r--r--site/vendors/phpQuery/plugins/Scripts/print_websafe.php13
-rw-r--r--site/vendors/phpQuery/plugins/WebBrowser.php385
-rw-r--r--site/vendors/phpQuery/plugins/example.php75
-rw-r--r--site/vendors/phpmailer/ChangeLog.txt252
-rw-r--r--site/vendors/phpmailer/LICENSE504
-rw-r--r--site/vendors/phpmailer/README121
-rw-r--r--site/vendors/phpmailer/class.phpmailer.php1856
-rw-r--r--site/vendors/phpmailer/class.pop3.php437
-rw-r--r--site/vendors/phpmailer/class.smtp.php1062
-rw-r--r--site/vendors/phpmailer/docs/extending.html148
-rw-r--r--site/vendors/phpmailer/docs/faq.html66
-rw-r--r--site/vendors/phpmailer/docs/pop3_article.txt39
-rw-r--r--site/vendors/phpmailer/docs/timeoutfix.diff23
-rw-r--r--site/vendors/phpmailer/docs/use_gmail.txt40
-rw-r--r--site/vendors/phpmailer/examples/contents.html12
-rw-r--r--site/vendors/phpmailer/examples/images/bkgrnd.gifbin0 -> 49 bytes
-rw-r--r--site/vendors/phpmailer/examples/images/phpmailer.gifbin0 -> 4756 bytes
-rw-r--r--site/vendors/phpmailer/examples/images/phpmailer.pngbin0 -> 3506 bytes
-rw-r--r--site/vendors/phpmailer/examples/images/phpmailer_mini.gifbin0 -> 1042 bytes
-rw-r--r--site/vendors/phpmailer/examples/index.html73
-rw-r--r--site/vendors/phpmailer/examples/pop3_before_smtp_test.php39
-rw-r--r--site/vendors/phpmailer/examples/test1.php28
-rw-r--r--site/vendors/phpmailer/language/phpmailer.lang-br.php21
-rw-r--r--site/vendors/phpmailer/language/phpmailer.lang-ca.php22
-rw-r--r--site/vendors/phpmailer/language/phpmailer.lang-cz.php24
-rw-r--r--site/vendors/phpmailer/language/phpmailer.lang-de.php23
-rw-r--r--site/vendors/phpmailer/language/phpmailer.lang-dk.php24
-rw-r--r--site/vendors/phpmailer/language/phpmailer.lang-en.php23
-rw-r--r--site/vendors/phpmailer/language/phpmailer.lang-es.php23
-rw-r--r--site/vendors/phpmailer/language/phpmailer.lang-et.php22
-rw-r--r--site/vendors/phpmailer/language/phpmailer.lang-fi.php23
-rw-r--r--site/vendors/phpmailer/language/phpmailer.lang-fo.php25
-rw-r--r--site/vendors/phpmailer/language/phpmailer.lang-fr.php24
-rw-r--r--site/vendors/phpmailer/language/phpmailer.lang-hu.php23
-rw-r--r--site/vendors/phpmailer/language/phpmailer.lang-it.php28
-rw-r--r--site/vendors/phpmailer/language/phpmailer.lang-ja.php25
-rw-r--r--site/vendors/phpmailer/language/phpmailer.lang-nl.php23
-rw-r--r--site/vendors/phpmailer/language/phpmailer.lang-no.php23
-rw-r--r--site/vendors/phpmailer/language/phpmailer.lang-pl.php24
-rw-r--r--site/vendors/phpmailer/language/phpmailer.lang-ro.php23
-rw-r--r--site/vendors/phpmailer/language/phpmailer.lang-ru.php23
-rw-r--r--site/vendors/phpmailer/language/phpmailer.lang-se.php24
-rw-r--r--site/vendors/phpmailer/language/phpmailer.lang-tr.php25
-rw-r--r--site/vendors/phpmailer/phpdoc/PHPMailer/PHPMailer.html1475
-rw-r--r--site/vendors/phpmailer/phpdoc/PHPMailer/SMTP.html734
-rw-r--r--site/vendors/phpmailer/phpdoc/PHPMailer/_class_phpmailer_php.html60
-rw-r--r--site/vendors/phpmailer/phpdoc/PHPMailer/_class_smtp_php.html60
-rw-r--r--site/vendors/phpmailer/phpdoc/blank.html13
-rw-r--r--site/vendors/phpmailer/phpdoc/classtrees_PHPMailer.html28
-rw-r--r--site/vendors/phpmailer/phpdoc/elementindex.html734
-rw-r--r--site/vendors/phpmailer/phpdoc/elementindex_PHPMailer.html731
-rw-r--r--site/vendors/phpmailer/phpdoc/errors.html23
-rw-r--r--site/vendors/phpmailer/phpdoc/index.html24
-rw-r--r--site/vendors/phpmailer/phpdoc/li_PHPMailer.html36
-rw-r--r--site/vendors/phpmailer/phpdoc/media/banner.css32
-rw-r--r--site/vendors/phpmailer/phpdoc/media/stylesheet.css133
-rw-r--r--site/vendors/phpmailer/phpdoc/packages.html27
-rw-r--r--site/vendors/phpmailer/test/phpmailer_test.php572
-rw-r--r--site/vendors/phpmailer/test/phpunit.php376
-rw-r--r--site/vendors/phpmailer/test/test.pngbin0 -> 1280 bytes
-rw-r--r--site/vendors/recaptcha/LICENSE22
-rw-r--r--site/vendors/recaptcha/README7
-rw-r--r--site/vendors/recaptcha/example-captcha.php37
-rw-r--r--site/vendors/recaptcha/example-mailhide.php17
-rw-r--r--site/vendors/recaptcha/recaptchalib.php277
-rw-r--r--site/vendors/simpletest/HELP_MY_TESTS_DONT_WORK_ANYMORE348
-rw-r--r--site/vendors/simpletest/LICENSE502
-rw-r--r--site/vendors/simpletest/README108
-rw-r--r--site/vendors/simpletest/VERSION1
-rw-r--r--site/vendors/simpletest/authentication.php238
-rw-r--r--site/vendors/simpletest/autorun.php87
-rw-r--r--site/vendors/simpletest/browser.php1098
-rw-r--r--site/vendors/simpletest/collector.php122
-rw-r--r--site/vendors/simpletest/compatibility.php173
-rw-r--r--site/vendors/simpletest/cookies.php380
-rw-r--r--site/vendors/simpletest/default_reporter.php133
-rw-r--r--site/vendors/simpletest/detached.php96
-rw-r--r--site/vendors/simpletest/docs/en/authentication_documentation.html355
-rw-r--r--site/vendors/simpletest/docs/en/browser_documentation.html447
-rw-r--r--site/vendors/simpletest/docs/en/docs.css121
-rw-r--r--site/vendors/simpletest/docs/en/expectation_documentation.html422
-rw-r--r--site/vendors/simpletest/docs/en/form_testing_documentation.html342
-rw-r--r--site/vendors/simpletest/docs/en/group_test_documentation.html386
-rw-r--r--site/vendors/simpletest/docs/en/index.html538
-rw-r--r--site/vendors/simpletest/docs/en/mock_objects_documentation.html757
-rw-r--r--site/vendors/simpletest/docs/en/overview.html486
-rw-r--r--site/vendors/simpletest/docs/en/partial_mocks_documentation.html445
-rw-r--r--site/vendors/simpletest/docs/en/reporter_documentation.html519
-rw-r--r--site/vendors/simpletest/docs/en/unit_test_documentation.html431
-rw-r--r--site/vendors/simpletest/docs/en/web_tester_documentation.html584
-rw-r--r--site/vendors/simpletest/docs/fr/authentication_documentation.html332
-rw-r--r--site/vendors/simpletest/docs/fr/browser_documentation.html446
-rw-r--r--site/vendors/simpletest/docs/fr/docs.css84
-rw-r--r--site/vendors/simpletest/docs/fr/expectation_documentation.html383
-rw-r--r--site/vendors/simpletest/docs/fr/form_testing_documentation.html349
-rw-r--r--site/vendors/simpletest/docs/fr/group_test_documentation.html398
-rw-r--r--site/vendors/simpletest/docs/fr/index.html572
-rw-r--r--site/vendors/simpletest/docs/fr/mock_objects_documentation.html778
-rw-r--r--site/vendors/simpletest/docs/fr/overview.html318
-rw-r--r--site/vendors/simpletest/docs/fr/partial_mocks_documentation.html460
-rw-r--r--site/vendors/simpletest/docs/fr/reporter_documentation.html534
-rw-r--r--site/vendors/simpletest/docs/fr/server_stubs_documentation.html0
-rw-r--r--site/vendors/simpletest/docs/fr/unit_test_documentation.html447
-rw-r--r--site/vendors/simpletest/docs/fr/web_tester_documentation.html566
-rw-r--r--site/vendors/simpletest/dumper.php360
-rw-r--r--site/vendors/simpletest/eclipse.php307
-rw-r--r--site/vendors/simpletest/encoding.php552
-rw-r--r--site/vendors/simpletest/errors.php288
-rw-r--r--site/vendors/simpletest/exceptions.php198
-rw-r--r--site/vendors/simpletest/expectation.php895
-rw-r--r--site/vendors/simpletest/extensions/pear_test_case.php198
-rw-r--r--site/vendors/simpletest/extensions/phpunit_test_case.php96
-rw-r--r--site/vendors/simpletest/extensions/testdox.php42
-rw-r--r--site/vendors/simpletest/extensions/testdox/test.php108
-rw-r--r--site/vendors/simpletest/form.php355
-rw-r--r--site/vendors/simpletest/frames.php596
-rw-r--r--site/vendors/simpletest/http.php624
-rw-r--r--site/vendors/simpletest/invoker.php139
-rw-r--r--site/vendors/simpletest/mock_objects.php1581
-rw-r--r--site/vendors/simpletest/page.php983
-rw-r--r--site/vendors/simpletest/parser.php764
-rw-r--r--site/vendors/simpletest/reflection_php4.php136
-rw-r--r--site/vendors/simpletest/reflection_php5.php380
-rw-r--r--site/vendors/simpletest/remote.php117
-rw-r--r--site/vendors/simpletest/reporter.php447
-rw-r--r--site/vendors/simpletest/scorer.php863
-rw-r--r--site/vendors/simpletest/selector.php137
-rw-r--r--site/vendors/simpletest/shell_tester.php333
-rw-r--r--site/vendors/simpletest/simpletest.php478
-rw-r--r--site/vendors/simpletest/socket.php216
-rw-r--r--site/vendors/simpletest/tag.php1418
-rw-r--r--site/vendors/simpletest/test/acceptance_test.php1633
-rw-r--r--site/vendors/simpletest/test/adapter_test.php77
-rw-r--r--site/vendors/simpletest/test/all_tests.php13
-rw-r--r--site/vendors/simpletest/test/authentication_test.php145
-rw-r--r--site/vendors/simpletest/test/autorun_test.php13
-rw-r--r--site/vendors/simpletest/test/bad_test_suite.php10
-rw-r--r--site/vendors/simpletest/test/browser_test.php779
-rw-r--r--site/vendors/simpletest/test/collector_test.php51
-rw-r--r--site/vendors/simpletest/test/command_line_test.php40
-rw-r--r--site/vendors/simpletest/test/compatibility_test.php97
-rw-r--r--site/vendors/simpletest/test/cookies_test.php227
-rw-r--r--site/vendors/simpletest/test/detached_test.php15
-rw-r--r--site/vendors/simpletest/test/dumper_test.php88
-rw-r--r--site/vendors/simpletest/test/eclipse_test.php32
-rw-r--r--site/vendors/simpletest/test/encoding_test.php213
-rw-r--r--site/vendors/simpletest/test/errors_test.php300
-rw-r--r--site/vendors/simpletest/test/exceptions_test.php153
-rw-r--r--site/vendors/simpletest/test/expectation_test.php245
-rw-r--r--site/vendors/simpletest/test/form_test.php323
-rw-r--r--site/vendors/simpletest/test/frames_test.php549
-rw-r--r--site/vendors/simpletest/test/http_test.php427
-rw-r--r--site/vendors/simpletest/test/interfaces_test.php137
-rw-r--r--site/vendors/simpletest/test/live_test.php47
-rw-r--r--site/vendors/simpletest/test/mock_objects_test.php994
-rw-r--r--site/vendors/simpletest/test/page_test.php903
-rw-r--r--site/vendors/simpletest/test/parse_error_test.php9
-rw-r--r--site/vendors/simpletest/test/parser_test.php551
-rw-r--r--site/vendors/simpletest/test/reflection_php4_test.php61
-rw-r--r--site/vendors/simpletest/test/reflection_php5_test.php271
-rw-r--r--site/vendors/simpletest/test/remote_test.php20
-rw-r--r--site/vendors/simpletest/test/shell_test.php38
-rw-r--r--site/vendors/simpletest/test/shell_tester_test.php42
-rw-r--r--site/vendors/simpletest/test/simpletest_test.php58
-rw-r--r--site/vendors/simpletest/test/socket_test.php25
-rw-r--r--site/vendors/simpletest/test/support/collector/collectable.10
-rw-r--r--site/vendors/simpletest/test/support/collector/collectable.20
-rw-r--r--site/vendors/simpletest/test/support/empty_test_file.php3
-rw-r--r--site/vendors/simpletest/test/support/latin1_sample1
-rw-r--r--site/vendors/simpletest/test/support/spl_examples.php15
-rw-r--r--site/vendors/simpletest/test/support/supplementary_upload_sample.txt1
-rw-r--r--site/vendors/simpletest/test/support/test1.php7
-rw-r--r--site/vendors/simpletest/test/support/upload_sample.txt1
-rw-r--r--site/vendors/simpletest/test/tag_test.php554
-rw-r--r--site/vendors/simpletest/test/test_groups.php64
-rw-r--r--site/vendors/simpletest/test/test_with_parse_error.php8
-rw-r--r--site/vendors/simpletest/test/unit_tester_test.php55
-rw-r--r--site/vendors/simpletest/test/unit_tests.php55
-rw-r--r--site/vendors/simpletest/test/url_test.php443
-rw-r--r--site/vendors/simpletest/test/user_agent_test.php358
-rw-r--r--site/vendors/simpletest/test/visual_test.php495
-rw-r--r--site/vendors/simpletest/test/web_tester_test.php156
-rw-r--r--site/vendors/simpletest/test/xml_test.php187
-rw-r--r--site/vendors/simpletest/test_case.php708
-rw-r--r--site/vendors/simpletest/unit_tester.php420
-rw-r--r--site/vendors/simpletest/url.php528
-rw-r--r--site/vendors/simpletest/user_agent.php332
-rw-r--r--site/vendors/simpletest/web_tester.php1541
-rw-r--r--site/vendors/simpletest/xml.php647
2624 files changed, 622123 insertions, 0 deletions
diff --git a/README b/README
new file mode 100644
index 0000000..4cee392
--- /dev/null
+++ b/README
@@ -0,0 +1,3 @@
+Remora
+
+For more information, visit http://wiki.mozilla.org/Update:Remora
diff --git a/bandwagon/build.sh b/bandwagon/build.sh
new file mode 100755
index 0000000..e76a01a
--- /dev/null
+++ b/bandwagon/build.sh
@@ -0,0 +1,9 @@
+#!/bin/sh
+
+mkdir -p chrome;
+[ -f bandwagon.xpi ] && rm bandwagon.xpi;
+[ -f chrome/bandwagon.jar ] && rm chrome/bandwagon.jar;
+zip -r0 bandwagon.jar content locale skin -x \*.svn/* -x \*.zip -x \*.db -x \*.xcf -x \*.\*~ -x \*.DS_Store;
+mv bandwagon.jar chrome/
+zip -r9 bandwagon.xpi chrome.manifest install.rdf defaults/ chrome/ components/ -x \*.svn/* -x \*.DS_Store;
+printf "build finished.\n";
diff --git a/bandwagon/chrome.manifest b/bandwagon/chrome.manifest
new file mode 100644
index 0000000..1567fdf
--- /dev/null
+++ b/bandwagon/chrome.manifest
@@ -0,0 +1,51 @@
+content bandwagon jar:chrome/bandwagon.jar!/content/
+
+#locale bandwagon ar jar:chrome/bandwagon.jar!/locale/ar/
+locale bandwagon ca jar:chrome/bandwagon.jar!/locale/ca/
+locale bandwagon cs jar:chrome/bandwagon.jar!/locale/cs/
+locale bandwagon da jar:chrome/bandwagon.jar!/locale/da/
+locale bandwagon de jar:chrome/bandwagon.jar!/locale/de/
+locale bandwagon el-GR jar:chrome/bandwagon.jar!/locale/el-GR/
+locale bandwagon en-US jar:chrome/bandwagon.jar!/locale/en-US/
+locale bandwagon es-ES jar:chrome/bandwagon.jar!/locale/es-ES/
+locale bandwagon fa jar:chrome/bandwagon.jar!/locale/fa/
+locale bandwagon fr jar:chrome/bandwagon.jar!/locale/fr/
+locale bandwagon fy-NL jar:chrome/bandwagon.jar!/locale/fy-NL/
+locale bandwagon he jar:chrome/bandwagon.jar!/locale/he/
+locale bandwagon id jar:chrome/bandwagon.jar!/locale/id/
+locale bandwagon it jar:chrome/bandwagon.jar!/locale/it/
+#locale bandwagon ja jar:chrome/bandwagon.jar!/locale/ja/
+locale bandwagon nl jar:chrome/bandwagon.jar!/locale/nl/
+locale bandwagon pl jar:chrome/bandwagon.jar!/locale/pl/
+locale bandwagon pt-BR jar:chrome/bandwagon.jar!/locale/pt-BR/
+locale bandwagon pt-PT jar:chrome/bandwagon.jar!/locale/pt-PT/
+locale bandwagon ro jar:chrome/bandwagon.jar!/locale/ro/
+locale bandwagon ru jar:chrome/bandwagon.jar!/locale/ru/
+locale bandwagon sk jar:chrome/bandwagon.jar!/locale/sk/
+locale bandwagon sq jar:chrome/bandwagon.jar!/locale/sq/
+locale bandwagon sv-SE jar:chrome/bandwagon.jar!/locale/sv-SE/
+#locale bandwagon uk jar:chrome/bandwagon.jar!/locale/uk/
+locale bandwagon vi jar:chrome/bandwagon.jar!/locale/vi/
+locale bandwagon zh-CN jar:chrome/bandwagon.jar!/locale/zh-CN/
+locale bandwagon zh-TW jar:chrome/bandwagon.jar!/locale/zh-TW/
+
+skin bandwagon classic/1.0 jar:chrome/bandwagon.jar!/skin/
+
+overlay chrome://browser/content/browser.xul chrome://bandwagon/content/ui/overlays/browserOverlay.xul
+overlay chrome://mozapps/content/extensions/extensions.xul chrome://bandwagon/content/ui/overlays/extensionsOverlay.xul
+style chrome://global/content/customizeToolbar.xul chrome://bandwagon/skin/browserOverlay.css
+
+override chrome://bandwagon/skin/browserOverlay.css chrome://bandwagon/skin/platform/linux/browserOverlay.css os=Linux
+override chrome://bandwagon/skin/browserOverlay.css chrome://bandwagon/skin/platform/mac/browserOverlay.css os=Darwin
+override chrome://bandwagon/skin/browserOverlay.css chrome://bandwagon/skin/platform/xp/browserOverlay.css os=WINNT osversion<=5.1
+override chrome://bandwagon/skin/browserOverlay.css chrome://bandwagon/skin/platform/vista/browserOverlay.css os=WINNT osversion>=6
+
+override chrome://bandwagon/skin/settingsIcons.css chrome://bandwagon/skin/platform/linux/settingsIcons.css os=Linux
+override chrome://bandwagon/skin/settingsIcons.css chrome://bandwagon/skin/platform/mac/settingsIcons.css os=Darwin
+override chrome://bandwagon/skin/settingsIcons.css chrome://bandwagon/skin/platform/xp/settingsIcons.css os=WINNT osversion<=5.1
+override chrome://bandwagon/skin/settingsIcons.css chrome://bandwagon/skin/platform/vista/settingsIcons.css os=WINNT osversion>=6
+
+override chrome://bandwagon/skin/extensionsOverlayIcons.css chrome://bandwagon/skin/platform/linux/extensionsOverlayIcons.css os=Linux
+override chrome://bandwagon/skin/extensionsOverlayIcons.css chrome://bandwagon/skin/platform/mac/extensionsOverlayIcons.css os=Darwin
+override chrome://bandwagon/skin/extensionsOverlayIcons.css chrome://bandwagon/skin/platform/xp/extensionsOverlayIcons.css os=WINNT osversion<=5.1
+override chrome://bandwagon/skin/extensionsOverlayIcons.css chrome://bandwagon/skin/platform/vista/extensionsOverlayIcons.css os=WINNT osversion>=6
diff --git a/bandwagon/components/bandwagon-service.js b/bandwagon/components/bandwagon-service.js
new file mode 100644
index 0000000..8362ff8
--- /dev/null
+++ b/bandwagon/components/bandwagon-service.js
@@ -0,0 +1,1399 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is bandwagon.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s): David McNamara
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+const nsISupports = Components.interfaces.nsISupports;
+const CLASS_ID = Components.ID("5c896f09-126c-466d-b28a-4e8b87a29916");
+const CLASS_NAME = "";
+const CONTRACT_ID = "@addons.mozilla.org/bandwagonservice;1";
+
+const Cc = Components.classes;
+const Ci = Components.interfaces;
+
+const WindowMediator = Cc["@mozilla.org/appshell/window-mediator;1"];
+const Timer = Cc["@mozilla.org/timer;1"];
+const ExtensionsManager = Cc["@mozilla.org/extensions/manager;1"];
+const Storage = Cc["@mozilla.org/storage/service;1"];
+const DirectoryService = Cc["@mozilla.org/file/directory_service;1"];
+const ObserverService = Cc["@mozilla.org/observer-service;1"];
+const CookieManager = Cc["@mozilla.org/cookiemanager;1"];
+
+const nsIWindowMediator = Ci.nsIWindowMediator;
+const nsITimer = Ci.nsITimer;
+const nsIExtensionManager = Ci.nsIExtensionManager;
+const mozIStorageService = Ci.mozIStorageService;
+const nsIProperties = Ci.nsIProperties;
+const nsIFile = Ci.nsIFile;
+const nsIObserverService = Ci.nsIObserverService;
+const nsICookieManager = Ci.nsICookieManager;
+
+var Bandwagon;
+var bandwagonService;
+
+var gEmGUID;
+var gUninstallObserverInited = false;
+
+/* Restore settings added or changed by the extension:
+ * - extension preferences
+ * - logins stored in the Login Manager?
+ */
+function cleanupSettings()
+{
+ // Cleanup preferences
+ var prefs = Components.classes["@mozilla.org/preferences-service;1"]
+ .getService(Components.interfaces.nsIPrefBranch);
+ try {
+ prefs.deleteBranch("extensions.bandwagon");
+ }
+ catch(e) {}
+}
+
+function BandwagonService()
+{
+ this.wrappedJSObject = this;
+ gEmGUID = "sharing@addons.mozilla.org";
+}
+
+BandwagonService.prototype = {
+
+ collections: {},
+
+ _initialized: false,
+ _service: null,
+ _collectionUpdateObservers: [],
+ _collectionListChangeObservers: [],
+ _authenticationStatusChangeObservers: [],
+ _storageConnection: null,
+ _collectionFactory: null,
+ _collectionUpdateTimer: null,
+ _bwObserver: null,
+ _serviceDocument: null,
+
+ init: function()
+ {
+ if (this._initialized)
+ return;
+
+ // get access to Bandwagon.* singletons
+
+ var browserWindow = WindowMediator.getService(nsIWindowMediator).getMostRecentWindow("navigator:browser");
+
+ if (!browserWindow || !browserWindow.Bandwagon)
+ {
+ debug("Bandwagon: could not get access to Bandwagon singletons from last window");
+ return;
+ }
+
+ Bandwagon = browserWindow.Bandwagon;
+ bandwagonService = this;
+
+ Bandwagon.Logger.info("Initializing Bandwagon");
+
+ this._initAMOHost();
+
+ // init rpc service
+
+ this._service = new Bandwagon.RPC.Service();
+ this._service.registerLogger(Bandwagon.Logger);
+ this._service.registerObserver(this._getCollectionObserver);
+ this._service.registerObserver(this._getServiceDocumentObserver);
+
+ this.registerCollectionUpdateObserver(this._collectionUpdateObserver);
+ // init sqlite storage (also creating tables in sqlite if needed). create factory objects.
+
+ this._initStorage();
+
+ // first run stuff
+
+ if (Bandwagon.Preferences.getPreference("firstrun") == true)
+ {
+ Bandwagon.Preferences.setPreference("firstrun", false);
+ this.firstrun();
+ }
+
+ // storage initialized, tables created - open the collections and service document
+
+ this._initCollections();
+
+ // start the update timer
+
+ this._initUpdateTimer();
+
+ // observe when the app shuts down so we can uninit
+
+ ObserverService.getService(nsIObserverService).addObserver(this._bwObserver, "quit-application", false);
+
+ // kick off the auto-publish functionality
+
+ this.autopublishExtensions();
+
+ this._initialized = true;
+
+ Bandwagon.Logger.info("Bandwagon has been initialized");
+ },
+
+ /**
+ * Update "constants" to reflect amo_host in preferences
+ */
+ _initAMOHost: function()
+ {
+ var amoHost = Bandwagon.Preferences.getPreference("amo_host");
+
+ Bandwagon.RPC.Constants.BANDWAGON_RPC_SERVICE_DOCUMENT = Bandwagon.RPC.Constants.BANDWAGON_RPC_SERVICE_DOCUMENT.replace("%%AMO_HOST%%", amoHost);
+ Bandwagon.LOGINPANE_DO_NEW_ACCOUNT = Bandwagon.LOGINPANE_DO_NEW_ACCOUNT.replace("%%AMO_HOST%%", amoHost);
+ Bandwagon.COLLECTIONSPANE_DO_SUBSCRIBE_URL = Bandwagon.COLLECTIONSPANE_DO_SUBSCRIBE_URL.replace("%%AMO_HOST%%", amoHost);
+ Bandwagon.COLLECTIONSPANE_DO_NEW_COLLECTION_URL = Bandwagon.COLLECTIONSPANE_DO_NEW_COLLECTION_URL.replace("%%AMO_HOST%%", amoHost);
+ Bandwagon.FIRSTRUN_LANDING_PAGE = Bandwagon.FIRSTRUN_LANDING_PAGE.replace("%%AMO_HOST%%", amoHost);
+ Bandwagon.AMO_AUTH_COOKIE_HOST = Bandwagon.AMO_AUTH_COOKIE_HOST.replace("%%AMO_HOST%%", amoHost);
+ },
+
+ _initCollections: function()
+ {
+ var storageCollections = this._collectionFactory.openCollections();
+
+ for (var id in storageCollections)
+ {
+ this.collections[id] = storageCollections[id];
+ this.collections[id].setAllNotified();
+
+ if (this.collections[id].isLocalAutoPublisher())
+ {
+ this.collections[id].autoPublishExtensions = Bandwagon.Preferences.getPreference("local.autopublisher.publish.extensions");
+ this.collections[id].autoPublishThemes = Bandwagon.Preferences.getPreference("local.autopublisher.publish.themes");
+ this.collections[id].autoPublishDicts = Bandwagon.Preferences.getPreference("local.autopublisher.publish.dictionaries");
+ this.collections[id].autoPublishLangPacks = Bandwagon.Preferences.getPreference("local.autopublisher.publish.language.packs");
+ this.collections[id].autoPublishDisabled = !Bandwagon.Preferences.getPreference("local.autopublisher.only.publish.enabled");
+ }
+
+ Bandwagon.Logger.debug("opened collection from storage: " + id);
+ }
+
+ this._serviceDocument = this._collectionFactory.openServiceDocument();
+ this._service._serviceDocument = this._serviceDocument;
+
+ if (!this._serviceDocument)
+ {
+ // no service document in storage, we never had it or we've lost it - go fetch it
+ this.updateCollectionsList();
+ }
+ },
+
+ _initUpdateTimer: function()
+ {
+ this._bwObserver =
+ {
+ observe: function(aSubject, aTopic, aData)
+ {
+ if (aTopic == "timer-callback")
+ {
+ bandwagonService.checkAllForUpdates();
+ }
+ else if (aTopic == "quit-application")
+ {
+ bandwagonService.uninit();
+ }
+ }
+ };
+
+ this._collectionUpdateTimer = Timer.createInstance(nsITimer);
+ this._collectionUpdateTimer.init(
+ this._bwObserver,
+ (Bandwagon.Preferences.getPreference("debug")?120*1000:Bandwagon.COLLECTION_UPDATE_TIMER_DELAY*1000),
+ nsITimer.TYPE_REPEATING_SLACK
+ );
+ },
+
+ uninit: function()
+ {
+ this._collectionUpdateTimer = null;
+ this.commitAll();
+ this._service = null;
+ this._collectionFactory = null;
+ Bandwagon = null;
+ bandwagonService = null;
+ },
+
+ getLocalAutoPublisher: function()
+ {
+ for (var id in bandwagonService.collections)
+ {
+ if (bandwagonService.collections[id].isLocalAutoPublisher())
+ {
+ return bandwagonService.collections[id];
+ }
+ }
+
+ return null;
+ },
+
+ autopublishExtensions: function(callback)
+ {
+ Bandwagon.Logger.debug("in autopublishExtensions()");
+
+ var localAutoPublisher = bandwagonService.getLocalAutoPublisher();
+
+ if (localAutoPublisher == null)
+ {
+ Bandwagon.Preferences.setPreferenceList("autopublished.extensions", []);
+ return;
+ }
+
+ var internalCallback = function(event)
+ {
+ if (!event.isError())
+ {
+ bandwagonService._notifyCollectionUpdateObservers(localAutoPublisher);
+ }
+
+ if (callback)
+ {
+ callback(event);
+ }
+ }
+
+ var installedExtensions = Bandwagon.Util.getInstalledExtensions();
+ var autopublishedExtensions = Bandwagon.Preferences.getPreferenceList("autopublished.extensions");
+ var willAutopublishExtensions = [];
+
+ for (var i=0; i<installedExtensions.length; i++)
+ {
+ //Bandwagon.Logger.debug("checking addon '" + installedExtensions[i].id + "' against user auto pub prefs (type=" + installedExtensions[i].type + ")");
+
+ // check if user wants to publish this extension (enabled, type)
+
+ if ((
+ Bandwagon.Util.getExtensionProperty(installedExtensions[i].id, "isDisabled") == "true"
+ ||
+ Bandwagon.Util.getExtensionProperty(installedExtensions[i].id, "appDisabled") == "true"
+ ||
+ Bandwagon.Util.getExtensionProperty(installedExtensions[i].id, "userDisabled") == "true"
+ )
+ && !localAutoPublisher.autoPublishDisabled)
+ {
+ //Bandwagon.Logger.debug("addon '" + installedExtensions[i].id + "' is disabled, so won't publish");
+ continue;
+ }
+
+ if (installedExtensions[i].type & installedExtensions[i].TYPE_EXTENSION
+ && !localAutoPublisher.autoPublishExtensions)
+ {
+ //Bandwagon.Logger.debug("addon '" + installedExtensions[i].id + "' is an extension, so won't publish");
+ continue;
+ }
+
+ if (installedExtensions[i].type & installedExtensions[i].TYPE_THEME
+ && !localAutoPublisher.autoPublishThemes)
+ {
+ //Bandwagon.Logger.debug("addon '" + installedExtensions[i].id + "' is a theme, so won't publish");
+ continue;
+ }
+
+ if (installedExtensions[i].type & installedExtensions[i].TYPE_LOCALE
+ && !localAutoPublisher.autoPublishLangPacks)
+ {
+ //Bandwagon.Logger.debug("addon '" + installedExtensions[i].id + "' is a locale, so won't publish");
+ continue;
+ }
+
+ /** TODO
+ if (installedExtensions[i].type & installedExtensions[i].TYPE_DICT
+ && !localAutoPublisher.autoPublishDicts)
+ {
+ Bandwagon.Logger.debug("addon '" + installedExtensions[i].id + "' is a dict, so won't publish");
+ continue;
+ }
+ */
+
+ // check if we have already published this extension
+
+ var hasPublished = false;
+
+ for (var j=0; j<autopublishedExtensions.length; j++)
+ {
+ if (installedExtensions[i].id == autopublishedExtensions[j])
+ {
+ hasPublished = true;
+ break;
+ }
+ }
+
+ if (hasPublished == false)
+ {
+ //Bandwagon.Logger.debug("addon '" + installedExtensions[i].id + "' added to auto-publish queue");
+ willAutopublishExtensions.push(installedExtensions[i]);
+ }
+ else
+ {
+ //Bandwagon.Logger.debug("addon '" + installedExtensions[i].id + "' has already been published");
+ }
+ }
+
+ if (willAutopublishExtensions.length > 0)
+ {
+ for (var i=0; i<willAutopublishExtensions.length; i++)
+ {
+ //Bandwagon.Logger.debug("Will autopublish extension '" + willAutopublishExtensions[i].id + "' to collection '" + localAutoPublisher.resourceURL + "'");
+
+ var extension =
+ {
+ guid: willAutopublishExtensions[i].id,
+ name: willAutopublishExtensions[i].name
+ }
+
+ bandwagonService.publishToCollection(extension, localAutoPublisher, "", internalCallback);
+
+ // add to autopublish
+ autopublishedExtensions.push(willAutopublishExtensions[i].id);
+ }
+
+ Bandwagon.Preferences.setPreferenceList("autopublished.extensions", autopublishedExtensions);
+ }
+ },
+
+ _getCollectionObserver: function(event)
+ {
+ Bandwagon.Logger.info("in _getCollectionObserver()");
+
+ if (event.getType() == Bandwagon.RPC.Constants.BANDWAGON_RPC_EVENT_TYPE_BANDWAGON_RPC_GET_COLLECTION_COMPLETE)
+ {
+ var collection = event.collection;
+
+ if (event.isError())
+ {
+ Bandwagon.Logger.error("RPC error: '" + event.getError().getMessage() + "'");
+
+ if (event.getError().getCode() == Bandwagon.RPC.Constants.BANDWAGON_RPC_SERVICE_ERROR_UNAUTHORIZED)
+ {
+ bandwagonService.deauthenticate();
+ }
+
+ // otherwise ignore for now
+ }
+ else
+ {
+ if (collection != null && collection.resourceURL != null)
+ {
+ Bandwagon.Logger.info("Finished getting updates for collection '" + collection.resourceURL + "'");
+ bandwagonService.collections[collection.resourceURL] = collection;
+ }
+ }
+
+ // we want to notify the observers even if there's been an error
+
+ bandwagonService._notifyCollectionUpdateObservers(collection);
+ }
+ },
+
+ _getServiceDocumentObserver: function(event)
+ {
+ Bandwagon.Logger.info("in _getServiceDocumentObserver()");
+
+ if (event.getType() == Bandwagon.RPC.Constants.BANDWAGON_RPC_EVENT_TYPE_BANDWAGON_RPC_GET_SERVICE_DOCUMENT_COMPLETE)
+ {
+ if (event.isError())
+ {
+ Bandwagon.Logger.error("Could not update collections list: " + event.getError().toString());
+
+ if (event.getError().getCode() == Bandwagon.RPC.Constants.BANDWAGON_RPC_SERVICE_ERROR_UNAUTHORIZED)
+ {
+ bandwagonService.deauthenticate();
+ }
+ }
+ else
+ {
+ bandwagonService._serviceDocument = event.serviceDocument;
+ bandwagonService._service._serviceDocument = bandwagonService._serviceDocument;
+
+ var collections = bandwagonService._serviceDocument.collections;
+
+ Bandwagon.Logger.debug("Updating collections list: saw " + collections.length + " collections");
+
+ for (var id in bandwagonService.collections)
+ {
+ var isStaleCollection = true;
+
+ for (var jd in collections)
+ {
+ if (bandwagonService.collections[id].equals(collections[jd]))
+ {
+ isStaleCollection = false;
+ break;
+ }
+ }
+
+ if (isStaleCollection)
+ {
+ Bandwagon.Logger.debug("Updating collections list: removing stale collection: " + bandwagonService.collections[id].toString());
+
+ bandwagonService.unlinkCollection(bandwagonService.collections[id]);
+ }
+ }
+
+ for (var id in collections)
+ {
+ var collection = collections[id];
+
+ if (bandwagonService.collections[collection.resourceURL])
+ {
+ // we have already added this collection
+ }
+ else
+ {
+ // this is a new collection
+ Bandwagon.Logger.debug("Updating collections list: adding new collection: " + collection.toString());
+
+ bandwagonService.collections[collection.resourceURL] = collection;
+ }
+ }
+
+ bandwagonService.forceCheckAllForUpdates();
+
+ bandwagonService._notifyListChangeObservers();
+
+ if (Bandwagon.COMMIT_NOW)
+ bandwagonService.commitAll();
+ }
+ }
+ },
+
+ _notifyCollectionUpdateObservers: function(collection)
+ {
+ Bandwagon.Logger.debug("Notifying collection update observers");
+
+ for (var i=0; i<bandwagonService._collectionUpdateObservers.length; i++)
+ {
+ if (bandwagonService._collectionUpdateObservers[i])
+ {
+ bandwagonService._collectionUpdateObservers[i](collection);
+ }
+ }
+ },
+
+ registerCollectionUpdateObserver: function(observer)
+ {
+ Bandwagon.Logger.debug("Registering collection update observer");
+ this._collectionUpdateObservers.push(observer);
+ },
+
+ unregisterCollectionUpdateObserver: function(observer)
+ {
+ Bandwagon.Logger.debug("Unregistering collection update observer");
+
+ for (var i=0; i<this._collectionUpdateObservers.length; i++)
+ {
+ if (this._collectionUpdateObservers[i] == observer)
+ {
+ delete this._collectionUpdateObservers[i];
+ }
+ }
+ },
+
+ _notifyAuthenticationStatusChangeObservers: function()
+ {
+ Bandwagon.Logger.debug("Notifying authentication status change observers");
+
+ for (var i=0; i<bandwagonService._authenticationStatusChangeObservers.length; i++)
+ {
+ if (bandwagonService._authenticationStatusChangeObservers[i])
+ {
+ bandwagonService._authenticationStatusChangeObservers[i]();
+ }
+ }
+ },
+
+ registerAuthenticationStatusChangeObserver: function(observer)
+ {
+ Bandwagon.Logger.debug("Registering authentication status change observer");
+ this._authenticationStatusChangeObservers.push(observer);
+ },
+
+ unregisterAuthenticationStatusChangeObserver: function(observer)
+ {
+ Bandwagon.Logger.debug("Unregistering authentication status change observer");
+
+ for (var i=0; i<this._authenticationStatusChangeObservers.length; i++)
+ {
+ if (this._authenticationStatusChangeObservers[i] == observer)
+ {
+ delete this._authenticationStatusChangeObservers[i];
+ }
+ }
+ },
+
+ _notifyListChangeObservers: function()
+ {
+ Bandwagon.Logger.debug("Notifying collection list change observers");
+
+ for (var i=0; i<bandwagonService._collectionListChangeObservers.length; i++)
+ {
+ if (bandwagonService._collectionListChangeObservers[i])
+ {
+ bandwagonService._collectionListChangeObservers[i]();
+ }
+ }
+ },
+
+ registerCollectionListChangeObserver: function(observer)
+ {
+ Bandwagon.Logger.debug("Registering collection list change observer");
+ this._collectionListChangeObservers.push(observer);
+ },
+
+ unregisterCollectionListChangeObserver: function(observer)
+ {
+ Bandwagon.Logger.debug("Unregistering collection list change observer");
+
+ for (var i=0; i<this._collectionListChangeObservers.length; i++)
+ {
+ if (this._collectionListChangeObservers[i] == observer)
+ {
+ delete this._collectionListChangeObservers[i];
+ }
+ }
+ },
+
+ authenticate: function(login, password, callback)
+ {
+ Bandwagon.Logger.debug("in authenticate()");
+
+ var service = this;
+
+ Bandwagon.Preferences.setPreference(Bandwagon.PREF_AUTH_TOKEN, "");
+ Bandwagon.Preferences.setPreference("login", "");
+ this.deleteAMOCookie();
+
+ var internalCallback = function(event)
+ {
+ if (!event.isError())
+ {
+ Bandwagon.Preferences.setPreference("login", login);
+
+ service._notifyAuthenticationStatusChangeObservers();
+ }
+
+ if (callback)
+ callback(event);
+ }
+
+ this._service.authenticate(login, password, internalCallback);
+ },
+
+ deauthenticate: function(callback)
+ {
+ Bandwagon.Preferences.setPreference(Bandwagon.PREF_AUTH_TOKEN, "");
+ Bandwagon.Preferences.setPreference("login", "");
+
+ this._notifyAuthenticationStatusChangeObservers();
+
+ if (callback)
+ callback();
+ },
+
+ updateCollectionsList: function(callback)
+ {
+ Bandwagon.Logger.debug("Updating collections list...");
+
+ this.updateServiceDocument(callback);
+ },
+
+ updateServiceDocument: function(callback)
+ {
+ if (!this.isAuthenticated())
+ return;
+
+ this._service.getServiceDocument(callback);
+ },
+
+ checkForUpdates: function(collection)
+ {
+ if (!this.isAuthenticated())
+ return;
+
+ this._service.getCollection(collection);
+
+ var now = new Date();
+
+ collection.dateLastCheck = now;
+ },
+
+ checkAllForUpdates: function()
+ {
+ Bandwagon.Logger.debug("in checkAllForUpdates()");
+
+ var now = new Date();
+
+ for (var id in this.collections)
+ {
+ var collection = this.collections[id];
+
+ if (collection.updateInterval == -1)
+ {
+ // use global setting
+
+ var dateLastCheck = new Date(Bandwagon.Preferences.getPreference("updateall.datelastcheck")*1000);
+ var dateNextCheck = new Date(dateLastCheck.getTime() + Bandwagon.Util.intervalUnitsToMilliseconds(
+ Bandwagon.Preferences.getPreference("global.update.interval"),
+ Bandwagon.Preferences.getPreference("global.update.units")
+ ));
+
+ if (dateNextCheck.getTime() > now.getTime())
+ {
+ return;
+ }
+ else
+ {
+ this.checkForUpdates(collection);
+ }
+ }
+ else
+ {
+ // use per-collection setting
+
+ var dateLastCheck = null;
+ var dateNextCheck = null;
+
+ if (collection.dateLastCheck != null)
+ {
+ dateLastCheck = collection.dateLastCheck;
+ dateNextCheck = new Date(dateLastCheck.getTime() + collection.updateInterval*1000);
+ }
+ else
+ {
+ dateLastCheck = null;
+ dateNextCheck = now;
+ }
+
+ if (dateLastCheck == null || dateNextCheck.getTime() <= now.getTime())
+ {
+ this.checkForUpdates(collection);
+ }
+ }
+ }
+
+ Bandwagon.Preferences.setPreference("updateall.datelastcheck", now.getTime()/1000);
+ },
+
+ forceCheckForUpdates: function(collection)
+ {
+ if (!this.isAuthenticated())
+ return;
+
+ this._service.getCollection(collection);
+ collection.dateLastCheck = new Date();
+ },
+
+ forceCheckAllForUpdates: function()
+ {
+ Bandwagon.Logger.debug("in forceCheckAllForUpdates()");
+
+ for (var id in this.collections)
+ {
+ var collection = this.collections[id];
+ this.forceCheckForUpdates(collection);
+ }
+ },
+
+ forceCheckAllForUpdatesAndUpdateCollectionsList: function(callback)
+ {
+ // All updates to the collections list are forced, i.e. they are always
+ // caused by *some* user interaction, never in the background.
+ // Updating the collections list also forces the collections to be updated.
+
+ this.updateCollectionsList(callback);
+ },
+
+ firstrun: function()
+ {
+ Bandwagon.Logger.info("This is bandwagon's firstrun. Welcome!");
+
+ // the last check date is now
+
+ var now = new Date();
+ Bandwagon.Preferences.setPreference("updateall.datelastcheck", now.getTime()/1000);
+
+ // open the firstrun landing page
+
+ Bandwagon.Controller.BrowserOverlay.openFirstRunLandingPage();
+ },
+
+ _addDefaultCollection: function(url, name)
+ {
+ var collection = this._collectionFactory.newCollection();
+ collection.resourceURL = url;
+ collection.name = name;
+ collection.showNotifications = 0;
+
+ this.collections[collection.resourceURL] = collection;
+
+ if (Bandwagon.COMMIT_NOW)
+ this.commit(collection);
+
+ this.forceCheckForUpdates(collection);
+ this.subscribe(collection);
+ },
+
+ uninstall: function()
+ {
+ // TODO
+ },
+
+ commit: function(collection)
+ {
+ if (!bandwagonService._collectionFactory)
+ return;
+
+ Bandwagon.Logger.debug("In commit() with collection: " + collection.resourceURL);
+
+ bandwagonService._collectionFactory.commitCollection(collection);
+ },
+
+ commitAll: function()
+ {
+ Bandwagon.Logger.debug("In commitAll()");
+
+ for (var id in bandwagonService.collections)
+ {
+ var collection = bandwagonService.collections[id];
+
+ this.commit(collection);
+ }
+
+ if (bandwagonService._serviceDocument)
+ bandwagonService._collectionFactory.commitServiceDocument(bandwagonService._serviceDocument);
+ },
+
+ removeAddonFromCollection: function(guid, collection, callback)
+ {
+ Bandwagon.Logger.debug("In removeAddonFromCollection()");
+
+ if (!this.isAuthenticated())
+ return;
+
+ this._service.removeAddonFromCollection(guid, collection, callback);
+ },
+
+ newCollection: function(collection, callback)
+ {
+ Bandwagon.Logger.debug("In newCollection()");
+
+ if (!this.isAuthenticated())
+ return;
+
+ var internalCallback = function(event)
+ {
+ if (!event.isError())
+ {
+ var collection = event.collection;
+
+ bandwagonService.collections[collection.resourceURL] = collection;
+ //bandwagonService._notifyCollectionUpdateObservers(collection);
+ bandwagonService._notifyListChangeObservers();
+ }
+
+ if (callback)
+ {
+ callback(event);
+ }
+ }
+
+ this._service.newCollection(collection, internalCallback);
+ },
+
+ unlinkCollection: function(collection)
+ {
+ this._collectionFactory.deleteCollection(collection);
+
+ for (var id in bandwagonService.collections)
+ {
+ if (collection.equals(bandwagonService.collections[id]))
+ {
+ delete bandwagonService.collections[id];
+
+ bandwagonService._notifyListChangeObservers();
+
+ break;
+ }
+ }
+ },
+
+ deleteCollection: function(collection, callback)
+ {
+ if (!this.isAuthenticated())
+ return;
+
+ this._service.deleteCollection(collection, callback);
+ },
+
+ subscribeToCollection: function(collection, callback)
+ {
+ if (!this.isAuthenticated())
+ return;
+
+ var internalCallback = function(event)
+ {
+ if (!event.isError())
+ {
+ collection.subscribed = true;
+ bandwagonService._notifyListChangeObservers();
+ }
+
+ if (callback)
+ {
+ callback(event);
+ }
+ }
+
+ this._service.subscribeToCollection(collection, internalCallback);
+ },
+
+ unsubscribeFromCollection: function(collection, callback)
+ {
+ if (!this.isAuthenticated())
+ return;
+
+ var internalCallback = function(event)
+ {
+ if (!event.isError())
+ {
+ bandwagonService.unlinkCollection(collection);
+ }
+
+ if (callback)
+ {
+ callback(event);
+ }
+ }
+
+ this._service.unsubscribeFromCollection(collection, internalCallback);
+ },
+
+ updateCollectionDetails: function(collection, callback)
+ {
+ if (!this.isAuthenticated())
+ return;
+
+ this._service.updateCollectionDetails(collection, callback);
+ },
+
+ /** This function is called when a 3rd party extension is uninstalled by
+ * the user. If this extension is part of a local auto publisher, we
+ * remove it from that autopublisher.
+ */
+ processOtherExtensionUninstall: function(guid, callback)
+ {
+ Bandwagon.Logger.debug("In processOtherExtensionUninstall() with guid = " + guid);
+
+ var localAutoPublisher = bandwagonService.getLocalAutoPublisher();
+
+ if (!localAutoPublisher)
+ return;
+
+ var internalCallback = function(event)
+ {
+ if (!event.isError())
+ {
+ // update list of autopublished extensions to remove this one
+ var autopublishedExtensions = Bandwagon.Preferences.getPreferenceList("autopublished.extensions");
+
+ for (var j=0; j<autopublishedExtensions.length; j++)
+ {
+ if (autopublishedExtensions[j] == guid)
+ {
+ delete autopublishedExtensions[j];
+ break;
+ }
+ }
+
+ Bandwagon.Preferences.setPreferenceList("autopublished.extensions", autopublishedExtensions);
+
+ bandwagonService.forceCheckForUpdates(localAutoPublisher);
+
+ if (callback)
+ callback(event);
+ }
+ }
+
+ for (var id in localAutoPublisher.addons)
+ {
+ if (localAutoPublisher.addons[id].guid == guid)
+ {
+ Bandwagon.Logger.debug("Found this extension in local auto publisher: '" + localAutoPublisher.addons[id].guid + "' vs '" + guid + "', will remove.");
+
+ this.removeAddonFromCollection(guid, localAutoPublisher, internalCallback);
+
+ break;
+ }
+ }
+ },
+
+ getAddonsPerPage: function(collection)
+ {
+ // returns this collection's custom items per page, or else the global value
+
+ var addonsPerPage;
+
+ if (collection.addonsPerPage != -1)
+ {
+ addonsPerPage = collection.addonsPerPage;
+ }
+ else
+ {
+ addonsPerPage = Bandwagon.Preferences.getPreference("global.addonsperpage");
+ }
+
+ if (addonsPerPage < 1)
+ {
+ addonsPerPage = 1;
+ }
+
+ return addonsPerPage;
+ },
+
+ getPreviouslySharedEmailAddresses: function()
+ {
+ return Bandwagon.Preferences.getPreferenceList("publish.shared.emails");
+ },
+
+ clearPreviouslySharedEmailAddresses: function()
+ {
+ Bandwagon.Preferences.setPreferenceList("publish.shared.emails", []);
+ },
+
+ addPreviouslySharedEmailAddress: function(emailAddress)
+ {
+ emailAddress = emailAddress.replace(/^\s+/, "");
+ emailAddress = emailAddress.replace(/\s+$/, "");
+ emailAddress = emailAddress.replace(/^,/, "");
+ emailAddress = emailAddress.replace(/,$/, "");
+
+ var previouslySharedEmailAddresses = this.getPreviouslySharedEmailAddresses();
+
+ for (var i=0; i<previouslySharedEmailAddresses.length; i++)
+ {
+ if (previouslySharedEmailAddresses[i] == emailAddress)
+ {
+ return;
+ }
+ }
+
+ previouslySharedEmailAddresses.push(emailAddress);
+
+ Bandwagon.Preferences.setPreferenceList("publish.shared.emails", previouslySharedEmailAddresses);
+ },
+
+ addPreviouslySharedEmailAddresses: function(commaSeparatedEmailAddresses)
+ {
+ var bits = commaSeparatedEmailAddresses.split(",");
+
+ for (var i=0; i<bits.length; i++)
+ {
+ if (bits[i].match(/.*@.*/))
+ {
+ this.addPreviouslySharedEmailAddress(bits[i]);
+ }
+ }
+ },
+
+ publishToCollection: function(extension, collection, personalNote, callback)
+ {
+ if (!this.isAuthenticated())
+ return;
+
+ this._service.publishToCollection(extension, collection, personalNote, callback);
+ },
+
+ shareToEmail: function(extension, emailAddress, personalNote, callback)
+ {
+ if (!this.isAuthenticated())
+ return;
+
+ // trim any commas from a multi-email string
+
+ emailAddress = emailAddress.replace(/^,/, "");
+ emailAddress = emailAddress.replace(/,$/, "");
+
+ this._service.shareToEmail(extension, emailAddress, personalNote, callback);
+ },
+
+ /**
+ * Performs a 'soft' check for authenication. I.e. do we have a token from a previous auth. This method doesn't
+ * check if that token is still valid on the server.
+ */
+ isAuthenticated: function()
+ {
+ return (Bandwagon.Preferences.getPreference(Bandwagon.PREF_AUTH_TOKEN) != "");
+ },
+
+ deleteAMOCookie: function()
+ {
+ var cm = CookieManager.getService(nsICookieManager);
+
+ var iterator = cm.enumerator;
+
+ while (iterator.hasMoreElements())
+ {
+ var cookie = iterator.getNext();
+
+ if (cookie instanceof Ci.nsICookie)
+ {
+ if (cookie.host == Bandwagon.AMO_AUTH_COOKIE_HOST && cookie.name == Bandwagon.AMO_AUTH_COOKIE_NAME)
+ {
+ // KILL!
+ cm.remove(cookie.host, cookie.name, cookie.path, false);
+ }
+ }
+ }
+ },
+
+ _collectionUpdateObserver: function(collection)
+ {
+ // called when a collection is updated
+
+ // if there are new items, notify the user if notifications are enabled for this user and it's not a preview of a collection
+
+ Bandwagon.Logger.debug("in _collectionUpdateObserver() with collection '" + collection + "', unnotified collection items = " + collection.getUnnotifiedAddons().length)
+
+ var showNotificationsForThisCollection;
+
+ if (collection.showNotifications == -1)
+ {
+ showNotificationsForThisCollection = Bandwagon.Preferences.getPreference("global.notify.enabled");
+ }
+ else
+ {
+ showNotificationsForThisCollection = collection.showNotifications;
+ }
+
+ if (showNotificationsForThisCollection && collection.getUnnotifiedAddons().length > 0)
+ {
+ var browserWindow = WindowMediator.getService(nsIWindowMediator).getMostRecentWindow("navigator:browser");
+
+ if (browserWindow)
+ {
+ browserWindow.Bandwagon.Controller.BrowserOverlay.showNewAddonsAlert(collection);
+ }
+ else
+ {
+ Bandwagon.Logger.error("Can't find a browser window to notify the user");
+ }
+
+ collection.setAllNotified();
+ }
+
+ // commit the collection
+
+ if (Bandwagon.COMMIT_NOW)
+ bandwagonService.commit(collection);
+ },
+
+ _initStorage: function()
+ {
+ var storageService = Storage.getService(mozIStorageService);
+
+ var file = DirectoryService.getService(nsIProperties).get("ProfD", nsIFile);
+ file.append(Bandwagon.EMID);
+
+ if (!file.exists() || !file.isDirectory())
+ {
+ file.create(nsIFile.DIRECTORY_TYPE, 0777);
+ }
+
+ file.append(Bandwagon.SQLITE_FILENAME);
+
+ try
+ {
+ this._storageConnection = storageService.openUnsharedDatabase(file);
+ }
+ catch (e)
+ {
+ Bandwagon.Logger.error("Error opening Storage connection: " + e);
+ return;
+ }
+
+ this._collectionFactory = new Bandwagon.Factory.CollectionFactory(this._storageConnection);
+
+ this._initStorageTables();
+ },
+
+ _initStorageTables: function()
+ {
+ if (!this._storageConnection)
+ return;
+
+ // create tables (if they're not already created)
+
+ this._storageConnection.beginTransaction();
+
+ try
+ {
+ this._storageConnection.executeSimpleSQL(
+ "CREATE TABLE IF NOT EXISTS serviceDocument "
+ + "(emailResourceURL TEXT NOT NULL, "
+ + "collectionListResourceURL TEXT NOT NULL)"
+ );
+ this._storageConnection.executeSimpleSQL(
+ "CREATE TABLE IF NOT EXISTS collections "
+ + "(id INTEGER PRIMARY KEY AUTOINCREMENT, "
+ + "url TEXT NOT NULL UNIQUE, "
+ + "name TEXT NOT NULL, "
+ + "description TEXT, "
+ + "dateAdded INTEGER NOT NULL, "
+ + "dateLastCheck INTEGER, "
+ + "updateInterval INTEGER NOT NULL, "
+ + "showNotifications INTEGER NOT NULL, "
+ + "autoPublish INTEGER NOT NULL, "
+ + "active INTEGER NOT NULL DEFAULT 1, "
+ + "addonsPerPage INTEGER NOT NULL, "
+ + "creator TEXT, "
+ + "listed INTEGER NOT NULL DEFAULT 1, "
+ + "writable INTEGER NOT NULL DEFAULT 0, "
+ + "subscribed INTEGER NOT NULL DEFAULT 1, "
+ + "lastModified INTEGER, "
+ + "addonsResourceURL TEXT, "
+ + "type TEXT)"
+ );
+ this._storageConnection.executeSimpleSQL(
+ "CREATE TABLE IF NOT EXISTS collectionsLinks "
+ + "(id INTEGER PRIMARY KEY AUTOINCREMENT, "
+ + "collection INTEGER NOT NULL, "
+ + "name TEXT NOT NULL, "
+ + "href TEXT NOT NULL)"
+ );
+ this._storageConnection.executeSimpleSQL(
+ "CREATE TABLE IF NOT EXISTS collectionsAddons "
+ + "(id INTEGER PRIMARY KEY AUTOINCREMENT, "
+ + "collection INTEGER NOT NULL, "
+ + "addon INTEGER NOT NULL, "
+ + "read INTEGER NOT NULL DEFAULT 0)"
+ );
+ this._storageConnection.executeSimpleSQL(
+ "CREATE TABLE IF NOT EXISTS addons "
+ + "(id INTEGER PRIMARY KEY AUTOINCREMENT, "
+ + "guid TEXT NOT NULL UNIQUE, "
+ + "name TEXT NOT NULL, "
+ + "type INTEGER NOT NULL, "
+ + "version TEXT NOT NULL, "
+ + "status INTEGER NOT NULL, "
+ + "summary TEXT, "
+ + "description TEXT, "
+ + "icon TEXT, "
+ + "eula TEXT, "
+ + "thumbnail TEXT, "
+ + "learnmore TEXT NOT NULL, "
+ + "author TEXT, "
+ + "category TEXT, "
+ + "dateAdded INTEGER NOT NULL)"
+ );
+ this._storageConnection.executeSimpleSQL(
+ "CREATE TABLE IF NOT EXISTS addonCompatibleApplications "
+ + "(addon INTEGER NOT NULL, "
+ + "name TEXT NOT NULL, "
+ + "applicationId INTEGER NOT NULL, "
+ + "minVersion TEXT NOT NULL, "
+ + "maxVersion TEXT NOT NULL, "
+ + "guid TEXT NOT NULL)"
+ );
+ this._storageConnection.executeSimpleSQL(
+ "CREATE TABLE IF NOT EXISTS addonCompatibleOS "
+ + "(addon INTEGER NOT NULL, "
+ + "name TEXT NOT NULL)"
+ );
+ this._storageConnection.executeSimpleSQL(
+ "CREATE TABLE IF NOT EXISTS addonInstalls "
+ + "(addon INTEGER NOT NULL, "
+ + "url TEXT NOT NULL, "
+ + "hash TEXT NOT NULL, "
+ + "os TEXT NOT NULL)"
+ );
+ this._storageConnection.executeSimpleSQL(
+ "CREATE TABLE IF NOT EXISTS addonComments "
+ + "(addon INTEGER NOT NULL, "
+ + "comment TEXT NOT NULL, "
+ + "author TEXT NOT NULL)"
+ );
+ this._storageConnection.executeSimpleSQL(
+ "CREATE TABLE IF NOT EXISTS addonAuthors "
+ + "(addon INTEGER NOT NULL, "
+ + "author TEXT NOT NULL)"
+ );
+ }
+ catch (e)
+ {
+ Bandwagon.Logger.error("Error creating sqlite table: " + e);
+ this._storageConnection.rollbackTransaction();
+ return;
+ }
+
+ this._storageConnection.commitTransaction();
+ },
+
+ startUninstallObserver : function ()
+ {
+ if (gUninstallObserverInited) return;
+
+ var extService = Components.classes["@mozilla.org/extensions/manager;1"]
+ .getService(Components.interfaces.nsIExtensionManager);
+
+ if (extService && ("uninstallItem" in extService))
+ {
+ var observerService = Components.classes["@mozilla.org/observer-service;1"]
+ .getService(Components.interfaces.nsIObserverService);
+ observerService.addObserver(this.addonsAction, "em-action-requested", false);
+ gUninstallObserverInited = true;
+ }
+ else
+ {
+ try
+ {
+ extService.datasource.AddObserver(this.addonsObserver);
+ gUninstallObserverInited = true;
+ }
+ catch (e) { }
+ }
+ },
+
+ addonsObserver:
+ {
+ onAssert: function (ds, subject, predicate, target)
+ {
+ if ((predicate.Value == "http://www.mozilla.org/2004/em-rdf#toBeUninstalled")
+ &&
+ (target instanceof Components.interfaces.nsIRDFLiteral)
+ &&
+ (target.Value == "true"))
+ {
+ if (subject.Value == "urn:mozilla:extension:" + gEmGUID)
+ {
+ // This is case where bandwagon is being uninstalled - clean up
+
+ cleanupSettings();
+ }
+ else
+ {
+ // This is case where some other extension is being uninstalled
+
+ var val = subject.Value;
+ val = val.replace(/urn:mozilla:extension:/, "");
+
+ bandwagonService.processOtherExtensionUninstall(val);
+ }
+ }
+ },
+
+ onUnassert: function (ds, subject, predicate, target) {},
+ onChange: function (ds, subject, predicate, oldtarget, newtarget) {},
+ onMove: function (ds, oldsubject, newsubject, predicate, target) {},
+ onBeginUpdateBatch: function() {},
+ onEndUpdateBatch: function() {}
+ },
+
+ addonsAction:
+ {
+ observe: function (subject, topic, data)
+ {
+ if ((data == "item-uninstalled") &&
+ (subject instanceof Components.interfaces.nsIUpdateItem))
+ {
+ if (subject.id == gEmGUID)
+ {
+ // This is case where bandwagon is being uninstalled - clean up
+
+ cleanupSettings();
+ }
+ else
+ {
+ // This is case where some other extension is being uninstalled
+
+ bandwagonService.processOtherExtensionUninstall(subject.id);
+ }
+ }
+ }
+ },
+
+ // for nsISupports
+ QueryInterface: function(aIID)
+ {
+ // add any other interfaces you support here
+ if (!aIID.equals(nsISupports))
+ throw Components.results.NS_ERROR_NO_INTERFACE;
+
+ return this;
+ }
+}
+
+var BandwagonServiceFactory = {
+ singleton: null,
+ createInstance: function (aOuter, aIID)
+ {
+ if (aOuter != null)
+ throw Components.results.NS_ERROR_NO_AGGREGATION;
+
+ if (this.singleton == null)
+ this.singleton = new BandwagonService();
+
+ return this.singleton.QueryInterface(aIID);
+ }
+};
+
+var BandwagonServiceModule = {
+ registerSelf: function(aCompMgr, aFileSpec, aLocation, aType)
+ {
+ aCompMgr = aCompMgr.QueryInterface(Components.interfaces.nsIComponentRegistrar);
+ aCompMgr.registerFactoryLocation(CLASS_ID, CLASS_NAME, CONTRACT_ID, aFileSpec, aLocation, aType);
+ },
+
+ unregisterSelf: function(aCompMgr, aLocation, aType)
+ {
+ aCompMgr = aCompMgr.QueryInterface(Components.interfaces.nsIComponentRegistrar);
+ aCompMgr.unregisterFactoryLocation(CLASS_ID, aLocation);
+ },
+
+ getClassObject: function(aCompMgr, aCID, aIID)
+ {
+ if (!aIID.equals(Components.interfaces.nsIFactory))
+ throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
+
+ if (aCID.equals(CLASS_ID))
+ return BandwagonServiceFactory;
+
+ throw Components.results.NS_ERROR_NO_INTERFACE;
+ },
+
+ canUnload: function(aCompMgr) { return true; }
+};
+
+//module initialization
+function NSGetModule(aCompMgr, aFileSpec) { return BandwagonServiceModule; }
+
diff --git a/bandwagon/content/scripts/bandwagon.js b/bandwagon/content/scripts/bandwagon.js
new file mode 100644
index 0000000..76fede1
--- /dev/null
+++ b/bandwagon/content/scripts/bandwagon.js
@@ -0,0 +1,69 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is bandwagon.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s): David McNamara
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+top.Bandwagon = new function() {}
+Bandwagon.Model = new function() {}
+Bandwagon.Factory = new function() {}
+Bandwagon.Controller = new function() {}
+Bandwagon.RPC = new function() {}
+
+Bandwagon.EMID = "sharing@addons.mozilla.org";
+Bandwagon.SQLITE_FILENAME = "bandwagon.sqlite";
+
+// This is the interval between checking if the collections need updating (in
+// seconds) (this will always be 120 seconds in debug mode). Note, this is not
+// the delay between instances of when the feeds are pulled down (this is
+// decided by "extensions.bandwagon.global.update.*" or per-collection
+// settings), but rather the minimum delay.
+
+Bandwagon.COLLECTION_UPDATE_TIMER_DELAY = 10 * 60;
+
+// Note: %%AMO_HOST%% replacement done in bandwagonService._initAMOHost()
+// XX Brian - this should really be done on the fly to avoid repitition of urls throughtout the code
+// and to lessen maintenance.
+
+Bandwagon.LOGINPANE_DO_NEW_ACCOUNT = "https://%%AMO_HOST%%/users/register";
+Bandwagon.COLLECTIONSPANE_DO_SUBSCRIBE_URL = "https://%%AMO_HOST%%/collections";
+Bandwagon.COLLECTIONSPANE_DO_NEW_COLLECTION_URL = "https://%%AMO_HOST%%/collections/add";
+Bandwagon.FIRSTRUN_LANDING_PAGE = "https://%%AMO_HOST%%/pages/collector_firstrun";
+Bandwagon.AMO_AUTH_COOKIE_HOST = "%%AMO_HOST%%";
+Bandwagon.AMO_AUTH_COOKIE_NAME = "AMOv3";
+Bandwagon.PREF_AUTH_TOKEN = "authtoken";
+
+Bandwagon.COMMIT_NOW = 0; // 1=commit on the fly. 0=commit when browser exit.
+Bandwagon.ENABLE_PAGINATION = 0; // 1=enable "add-ons per page" settings, limit number of add-ons displayed in EM. 0=disable these settings, show all add-ons in EM.
+
+
diff --git a/bandwagon/content/scripts/factory/collectionFactory.js b/bandwagon/content/scripts/factory/collectionFactory.js
new file mode 100644
index 0000000..0c32dc4
--- /dev/null
+++ b/bandwagon/content/scripts/factory/collectionFactory.js
@@ -0,0 +1,893 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is bandwagon.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s): David McNamara
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+Bandwagon.Factory.CollectionFactory = function(connection)
+{
+ this.Bandwagon = Bandwagon;
+ this.connection = connection;
+
+ this.connection.executeSimpleSQL("PRAGMA locking_mode = EXCLUSIVE");
+}
+
+Bandwagon.Factory.CollectionFactory.prototype.openServiceDocument = function()
+{
+ if (!this.connection)
+ return null;
+
+ var statement = this.connection.createStatement("SELECT * FROM serviceDocument LIMIT 1");
+
+ var serviceDocument = null;
+
+ try
+ {
+ while (statement.executeStep())
+ {
+ serviceDocument = new this.Bandwagon.Model.ServiceDocument();
+ serviceDocument.emailResourceURL = statement.getUTF8String(0);
+ serviceDocument.collectionListResourceURL = statement.getUTF8String(1);
+ }
+ }
+ finally
+ {
+ statement.reset();
+ }
+
+ return serviceDocument;
+}
+
+Bandwagon.Factory.CollectionFactory.prototype.commitServiceDocument = function(serviceDocument)
+{
+ if (!this.connection)
+ return;
+
+ this.connection.beginTransaction();
+
+ var statement1 = this.connection.createStatement("DELETE FROM serviceDocument");
+
+ try
+ {
+ statement1.execute();
+ }
+ catch (e)
+ {
+ this.connection.rollbackTransaction();
+ throw e;
+ }
+ finally
+ {
+ statement1.reset();
+ }
+
+ var statement2 = this.connection.createStatement("INSERT INTO serviceDocument VALUES (?1, ?2)");
+
+ try
+ {
+ statement2.bindUTF8StringParameter(0, serviceDocument.emailResourceURL);
+ statement2.bindUTF8StringParameter(1, serviceDocument.collectionListResourceURL);
+ statement2.execute();
+ }
+ catch (e)
+ {
+ this.connection.rollbackTransaction();
+ throw e;
+ }
+ finally
+ {
+ statement2.reset();
+ }
+
+ this.connection.commitTransaction();
+}
+
+Bandwagon.Factory.CollectionFactory.prototype.newCollection = function()
+{
+ return new this.Bandwagon.Model.Collection();
+}
+
+Bandwagon.Factory.CollectionFactory.prototype.openCollection = function(collection_id)
+{
+ if (!this.connection)
+ return null;
+
+ var collections = {};
+
+ var statement = this.connection.createStatement("SELECT * FROM collections where id = ?1");
+
+ try
+ {
+ statement.bindInt32Parameter(0, collection_id);
+ statement.execute();
+
+ var collection = this._openCollectionFromRS(statement);
+
+ if (!collection)
+ return null;
+
+ collection.addons = this._openAddons(collection);
+ collection.links = this._openCollectionLinks(collection);
+
+ collections[collection.resourceURL] = collection;
+ }
+ finally
+ {
+ statement.reset();
+ }
+
+ return collection;
+}
+
+Bandwagon.Factory.CollectionFactory.prototype.openCollections = function()
+{
+ if (!this.connection)
+ return null;
+
+ var collections = {};
+
+ var statement = this.connection.createStatement("SELECT * FROM collections");
+
+ try
+ {
+ while (statement.executeStep())
+ {
+ var collection = this._openCollectionFromRS(statement);
+
+ if (!collection)
+ continue;
+
+ collection.addons = this._openAddons(collection);
+ collection.links = this._openCollectionLinks(collection);
+
+ collections[collection.resourceURL] = collection;
+ }
+ }
+ finally
+ {
+ statement.reset();
+ }
+
+ return collections;
+}
+
+Bandwagon.Factory.CollectionFactory.prototype.commitCollection = function(collection)
+{
+ if (!this.connection)
+ return;
+
+ this.connection.beginTransaction();
+
+ var statement = this.connection.createStatement("REPLACE INTO collections VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12, ?13, ?14, ?15, ?16, ?17, ?18)");
+
+ try
+ {
+ (collection.storageID==-1?statement.bindNullParameter(0):statement.bindInt32Parameter(0, collection.storageID));
+ statement.bindUTF8StringParameter(1, collection.resourceURL);
+ statement.bindUTF8StringParameter(2, collection.name);
+ statement.bindUTF8StringParameter(3, collection.description);
+ statement.bindInt32Parameter(4, collection.dateAdded.getTime()/1000);
+ (collection.dateLastCheck == null?statement.bindNullParameter(5):statement.bindInt32Parameter(5, collection.dateLastCheck.getTime()/1000));
+ statement.bindInt32Parameter(6, collection.updateInterval);
+ statement.bindInt32Parameter(7, collection.showNotifications);
+ statement.bindInt32Parameter(8, (collection.autoPublish?1:0));
+ statement.bindInt32Parameter(9, (collection.active?1:0));
+ statement.bindInt32Parameter(10, collection.addonsPerPage);
+ statement.bindUTF8StringParameter(11, collection.creator);
+ statement.bindInt32Parameter(12, collection.listed);
+ statement.bindInt32Parameter(13, collection.writable);
+ statement.bindInt32Parameter(14, collection.subscribed);
+ (collection.lastModified == null?statement.bindNullParameter(15):statement.bindInt32Parameter(15, collection.lastModified.getTime()/1000));
+ statement.bindUTF8StringParameter(16, collection.addonsResourceURL);
+ statement.bindUTF8StringParameter(17, collection.type);
+
+ statement.execute();
+ }
+ catch (e)
+ {
+ this.connection.rollbackTransaction();
+ throw e;
+ }
+ finally
+ {
+ statement.reset();
+ }
+
+ if (collection.storageID == -1)
+ {
+ collection.storageID = this.connection.lastInsertRowID;
+ }
+
+ var statement3 = this.connection.createStatement("DELETE FROM collectionsAddons where collection = ?1");
+
+ try
+ {
+ statement3.bindInt32Parameter(0, collection.storageID);
+ statement3.execute();
+ }
+ catch (e)
+ {
+ this.connection.rollbackTransaction();
+ throw e;
+ }
+ finally
+ {
+ statement3.reset();
+ }
+
+ for (var id in collection.addons)
+ {
+ try
+ {
+ this._commitAddon(collection, collection.addons[id]);
+ }
+ catch (e)
+ {
+ this.connection.rollbackTransaction();
+ throw e;
+ }
+ }
+
+ var statement2 = this.connection.createStatement("DELETE FROM collectionsLinks WHERE collection = ?1");
+
+ try
+ {
+ statement2.bindInt32Parameter(0, collection.storageID);
+ statement2.execute();
+ }
+ catch (e)
+ {
+ this.connection.rollbackTransaction();
+ throw e;
+ }
+ finally
+ {
+ statement2.reset();
+ }
+
+ for (var id in collection.links)
+ {
+ try
+ {
+ this._commitCollectionLink(collection, id);
+ }
+ catch (e)
+ {
+ this.connection.rollbackTransaction();
+ throw e;
+ }
+ }
+
+ this.connection.commitTransaction();
+
+ return true;
+}
+
+Bandwagon.Factory.CollectionFactory.prototype.commitCollections = function(collections)
+{
+ for (var id in collections)
+ {
+ this.commitCollection(collections[id]);
+ }
+}
+
+Bandwagon.Factory.CollectionFactory.prototype.deleteCollection = function(collection)
+{
+ if (!this.connection)
+ return;
+
+ this.connection.beginTransaction();
+
+ var statement1 = this.connection.createStatement("DELETE FROM collections where id = ?1");
+ var statement2 = this.connection.createStatement("DELETE FROM collectionsAddons where collection = ?1");
+
+ try
+ {
+ statement1.bindInt32Parameter(0, collection.storageID);
+ statement1.execute();
+
+ statement2.bindInt32Parameter(0, collection.storageID);
+ statement2.execute();
+ }
+ catch (e)
+ {
+ this.connection.rollbackTransaction();
+ throw e;
+ }
+ finally
+ {
+ statement1.reset();
+ statement2.reset();
+ }
+
+ this.connection.commitTransaction();
+
+ return (statement2.lastError>0?false:true);
+}
+
+// private methods
+
+Bandwagon.Factory.CollectionFactory.prototype._openCollectionFromRS = function(resultset)
+{
+ var collection = new this.Bandwagon.Model.Collection();
+ collection.storageID = resultset.getInt32(0);
+ collection.resourceURL = resultset.getUTF8String(1);
+ collection.name = resultset.getUTF8String(2);
+ collection.description = resultset.getUTF8String(3);
+ collection.dateAdded = new Date(resultset.getInt32(4)*1000);
+
+ if (!resultset.getIsNull(5))
+ collection.dateLastCheck = new Date(resultset.getInt32(5)*1000);
+
+ collection.updateInterval = resultset.getInt32(6);
+ collection.showNotifications = resultset.getInt32(7);
+ collection.autoPublish = (resultset.getInt32(8)==1?true:false);
+ collection.active = (resultset.getInt32(9)==1?true:false);
+ collection.addonsPerPage = resultset.getInt32(10);
+ collection.creator = resultset.getUTF8String(11);
+ collection.listed = resultset.getInt32(12);
+ collection.writable = resultset.getInt32(13);
+ collection.subscribed = resultset.getInt32(14);
+
+ if (!resultset.getIsNull(15))
+ collection.lastModified = new Date(resultset.getInt32(15)*1000);
+
+ collection.addonsResourceURL = resultset.getUTF8String(16);
+ collection.type = resultset.getUTF8String(17);
+
+ return collection;
+}
+
+Bandwagon.Factory.CollectionFactory.prototype._openCollectionLinks = function(collection)
+{
+ var links = {};
+
+ var statement = this.connection.createStatement("SELECT * FROM collectionsLinks WHERE collection = ?1");
+
+ try
+ {
+ statement.bindInt32Parameter(0, collection.storageID);
+
+ while (statement.executeStep())
+ {
+ var name = statement.getUTF8String(2);
+ var href = statement.getUTF8String(3);
+ links[name] = href;
+ }
+ }
+ finally
+ {
+ statement.reset();
+ }
+
+ return links;
+}
+
+Bandwagon.Factory.CollectionFactory.prototype._openAddons = function(collection)
+{
+ var addons = {};
+
+ var statement = this.connection.createStatement("SELECT addons.*, collectionsAddons.id, collectionsAddons.read FROM addons LEFT JOIN collectionsAddons ON addons.id = collectionsAddons.addon WHERE collectionsAddons.collection = ?1");
+
+ try
+ {
+ statement.bindInt32Parameter(0, collection.storageID);
+
+ while (statement.executeStep())
+ {
+ var addon = new this.Bandwagon.Model.Addon();
+ addon.Bandwagon = this.Bandwagon;
+
+ addon.storageID = statement.getInt32(0);
+ addon.guid = statement.getUTF8String(1);
+ addon.name = statement.getUTF8String(2);
+ addon.type = statement.getInt32(3);
+ addon.version = statement.getUTF8String(4);
+ addon.status = statement.getInt32(5);
+ addon.summary = statement.getUTF8String(6);
+ addon.description = statement.getUTF8String(7);
+ addon.icon = statement.getUTF8String(8);
+ addon.eula = statement.getUTF8String(9);
+ addon.thumbnail = statement.getUTF8String(10);
+ addon.learnmore = statement.getUTF8String(11);
+ addon.author = statement.getUTF8String(12);
+ addon.category = statement.getUTF8String(13);
+ addon.dateAdded = new Date(statement.getInt32(14)*1000);
+ addon.collectionsAddonsStorageID = statement.getInt32(15);
+ addon.read = (statement.getInt32(16)==1?true:false);
+
+ addon.compatibleApplications = this._openAddonCompatibleApplications(addon);
+ addon.compatibleOS = this._openAddonCompatibleOS(addon);
+ addon.installs = this._openAddonInstalls(addon);
+ addon.comments = this._openAddonComments(addon);
+ addon.authors = this._openAddonAuthors(addon);
+
+ addons[addon.guid] = addon;
+ }
+ }
+ finally
+ {
+ statement.reset();
+ }
+
+ return addons;
+}
+
+Bandwagon.Factory.CollectionFactory.prototype._openAddonCompatibleApplications = function(addon)
+{
+ var compatibleApplications = {};
+
+ var statement = this.connection.createStatement("SELECT * FROM addonCompatibleApplications WHERE addon = ?1");
+
+ try
+ {
+ statement.bindInt32Parameter(0, addon.storageID);
+
+ while (statement.executeStep())
+ {
+ var application =
+ {
+ name: statement.getUTF8String(1).toString().toUpperCase(),
+ applicationId: statement.getInt32(2),
+ minVersion: statement.getUTF8String(3),
+ maxVersion: statement.getUTF8String(4),
+ guid: statement.getUTF8String(5)
+ };
+
+ compatibleApplications[application.name.toUpperCase()] = application;
+ }
+ }
+ finally
+ {
+ statement.reset();
+ }
+
+ return compatibleApplications;
+}
+
+Bandwagon.Factory.CollectionFactory.prototype._openAddonCompatibleOS = function(addon)
+{
+ var compatibleOS = {};
+
+ var statement = this.connection.createStatement("SELECT * FROM addonCompatibleOS WHERE addon = ?1");
+
+ try
+ {
+ statement.bindInt32Parameter(0, addon.storageID);
+
+ while (statement.executeStep())
+ {
+ var os = statement.getUTF8String(1).toString().toUpperCase();
+
+ compatibleOS[os] = os;
+ }
+ }
+ finally
+ {
+ statement.reset();
+ }
+
+ return compatibleOS;
+}
+
+Bandwagon.Factory.CollectionFactory.prototype._openAddonInstalls = function(addon)
+{
+ var installs = {};
+
+ var statement = this.connection.createStatement("SELECT * FROM addonInstalls WHERE addon = ?1");
+
+ try
+ {
+ statement.bindInt32Parameter(0, addon.storageID);
+
+ while (statement.executeStep())
+ {
+ var install =
+ {
+ url: statement.getUTF8String(1),
+ hash: statement.getUTF8String(2),
+ os: statement.getUTF8String(3).toString().toUpperCase()
+ };
+
+ installs[install.os] = install;
+ }
+ }
+ finally
+ {
+ statement.reset();
+ }
+
+ return installs;
+}
+
+Bandwagon.Factory.CollectionFactory.prototype._openAddonComments = function(addon)
+{
+ var comments = [];
+
+ var statement = this.connection.createStatement("SELECT * FROM addonComments WHERE addon = ?1");
+
+ try
+ {
+ statement.bindInt32Parameter(0, addon.storageID);
+
+ while (statement.executeStep())
+ {
+ var comment =
+ {
+ comment: statement.getUTF8String(1),
+ author: statement.getUTF8String(2)
+ };
+
+ comments.push(comment);
+ }
+ }
+ finally
+ {
+ statement.reset();
+ }
+
+ return comments;
+}
+
+Bandwagon.Factory.CollectionFactory.prototype._openAddonAuthors = function(addon)
+{
+ var authors = [];
+
+ var statement = this.connection.createStatement("SELECT * FROM addonAuthors WHERE addon = ?1");
+
+ try
+ {
+ statement.bindInt32Parameter(0, addon.storageID);
+
+ while (statement.executeStep())
+ {
+ authors.push(statement.getUTF8String(1));
+ }
+ }
+ finally
+ {
+ statement.reset();
+ }
+
+ return authors;
+}
+
+Bandwagon.Factory.CollectionFactory.prototype._commitCollectionLink = function(collection, linkName)
+{
+ if (!this.connection)
+ return;
+
+ var statement = this.connection.createStatement("INSERT INTO collectionsLinks VALUES (?1, ?2, ?3, ?4)");
+
+ try
+ {
+ statement.bindNullParameter(0);
+ statement.bindInt32Parameter(1, collection.storageID);
+ statement.bindUTF8StringParameter(2, linkName);
+ statement.bindUTF8StringParameter(3, collection.links[linkName]);
+
+ statement.execute();
+ }
+ finally
+ {
+ statement.reset();
+ }
+}
+
+Bandwagon.Factory.CollectionFactory.prototype._commitAddon = function(collection, addon)
+{
+ if (!this.connection)
+ return;
+
+ // addons
+ // if guid already exists - just update the addon
+ // if guid doesn't exist - insert
+
+ var statement = this.connection.createStatement("SELECT id FROM addons where guid = ?1");
+ var addonStorageID = null;
+
+ try
+ {
+ statement.bindUTF8StringParameter(0, addon.guid);
+
+ while (statement.executeStep())
+ {
+ addonStorageID = statement.getInt32(0);
+ }
+ }
+ finally
+ {
+ statement.reset();
+ }
+
+ var statement2 = this.connection.createStatement("REPLACE INTO addons VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12, ?13, ?14, ?15)");
+
+ try
+ {
+ if (addonStorageID != null)
+ {
+ // addon already exists (in another collection, or from previous commit of this collection)
+ statement2.bindInt32Parameter(0, addonStorageID);
+ }
+ else if (addon.storageID != -1)
+ {
+ // addon doesn't already exist, but exists from a previous commit of this collection (?)
+ statement2.bindInt32Parameter(0, addon.storageID);
+ }
+ else
+ {
+ // new addon
+ statement2.bindNullParameter(0)
+ }
+
+ statement2.bindUTF8StringParameter(1, addon.guid);
+ statement2.bindUTF8StringParameter(2, addon.name);
+ statement2.bindInt32Parameter(3, addon.type);
+ statement2.bindUTF8StringParameter(4, addon.version);
+ statement2.bindInt32Parameter(5, addon.status);
+ statement2.bindUTF8StringParameter(6, addon.summary);
+ statement2.bindUTF8StringParameter(7, addon.description);
+ statement2.bindUTF8StringParameter(8, addon.icon);
+ statement2.bindUTF8StringParameter(9, addon.eula);
+ statement2.bindUTF8StringParameter(10, addon.thumbnail);
+ statement2.bindUTF8StringParameter(11, addon.learnmore);
+ statement2.bindUTF8StringParameter(12, addon.author);
+ statement2.bindUTF8StringParameter(13, addon.category);
+ statement2.bindUTF8StringParameter(14, addon.dateAdded.getTime()/1000);
+
+ statement2.execute();
+ }
+ finally
+ {
+ statement2.reset();
+ }
+
+ if (addon.storageID == -1 && addonStorageID == null)
+ {
+ addonStorageID = this.connection.lastInsertRowID;
+ }
+
+ // add the other addon bits
+
+ for (var id in addon.compatibleApplications)
+ {
+ this._commitAddonCompatibleApplication(addonStorageID, addon.compatibleApplications[id]);
+ }
+
+ for (var id in addon.compatibleOS)
+ {
+ this._commitAddonCompatibleOS(addonStorageID, addon.compatibleOS[id]);
+ }
+
+ for (var id in addon.installs)
+ {
+ this._commitAddonInstall(addonStorageID, addon.installs[id]);
+ }
+
+ for (var i=0; i<addon.comments.length; i++)
+ {
+ this._commitAddonComment(addonStorageID, addon.comments[i]);
+ }
+
+ for (var id in addon.authors)
+ {
+ this._commitAddonAuthor(addonStorageID, addon.authors[id]);
+ }
+
+ // add the addon connector
+
+ var statement3 = this.connection.createStatement("REPLACE INTO collectionsAddons VALUES (?1, ?2, ?3, ?4)");
+
+ try
+ {
+ if (addon.collectionsAddonsStorageID == -1)
+ {
+ statement3.bindNullParameter(0);
+ }
+ else
+ {
+ statement3.bindInt32Parameter(0, addon.collectionsAddonsStorageID);
+ }
+
+ statement3.bindInt32Parameter(1, collection.storageID);
+ statement3.bindInt32Parameter(2, addonStorageID);
+ statement3.bindInt32Parameter(3, (addon.read?1:0));
+
+ statement3.execute();
+ }
+ finally
+ {
+ statement3.reset();
+ }
+
+ if (addon.collectionsAddonsStorageID == -1)
+ {
+ addon.collectionsAddonsStorageID = this.connection.lastInsertRowID;
+ }
+
+ return true;
+}
+
+Bandwagon.Factory.CollectionFactory.prototype._commitAddonCompatibleApplication = function(addonStorageID, application)
+{
+ var statement = this.connection.createStatement("DELETE FROM addonCompatibleApplications WHERE addon = ?1");
+
+ try
+ {
+ statement.bindInt32Parameter(0, addonStorageID);
+ statement.execute();
+ }
+ finally
+ {
+ statement.reset();
+ }
+
+ var statement2 = this.connection.createStatement("INSERT INTO addonCompatibleApplications VALUES (?1, ?2, ?3, ?4, ?5, ?6)");
+
+ try
+ {
+ statement2.bindInt32Parameter(0, addonStorageID);
+ statement2.bindUTF8StringParameter(1, application.name);
+ statement2.bindInt32Parameter(2, application.applicationId);
+ statement2.bindUTF8StringParameter(3, application.minVersion);
+ statement2.bindUTF8StringParameter(4, application.maxVersion);
+ statement2.bindUTF8StringParameter(5, application.guid);
+
+ statement2.execute();
+ }
+ finally
+ {
+ statement2.reset();
+ }
+}
+
+Bandwagon.Factory.CollectionFactory.prototype._commitAddonCompatibleOS = function(addonStorageID, os)
+{
+ var statement = this.connection.createStatement("DELETE FROM addonCompatibleOS WHERE addon = ?1");
+
+ try
+ {
+ statement.bindInt32Parameter(0, addonStorageID);
+ statement.execute();
+ }
+ finally
+ {
+ statement.reset();
+ }
+
+ var statement2 = this.connection.createStatement("INSERT INTO addonCompatibleOS VALUES (?1, ?2)");
+
+ try
+ {
+ statement2.bindInt32Parameter(0, addonStorageID);
+ statement2.bindUTF8StringParameter(1, os);
+
+ statement2.execute();
+ }
+ finally
+ {
+ statement2.reset();
+ }
+}
+
+Bandwagon.Factory.CollectionFactory.prototype._commitAddonInstall = function(addonStorageID, install)
+{
+ var statement = this.connection.createStatement("DELETE FROM addonInstalls WHERE addon = ?1");
+
+ try
+ {
+ statement.bindInt32Parameter(0, addonStorageID);
+ statement.execute();
+ }
+ finally
+ {
+ statement.reset();
+ }
+
+ var statement2 = this.connection.createStatement("INSERT INTO addonInstalls VALUES (?1, ?2, ?3, ?4)");
+
+ try
+ {
+ statement2.bindInt32Parameter(0, addonStorageID);
+ statement2.bindUTF8StringParameter(1, install.url);
+ statement2.bindUTF8StringParameter(2, install.hash);
+ statement2.bindUTF8StringParameter(3, install.os);
+
+ statement2.execute();
+ }
+ finally
+ {
+ statement2.reset();
+ }
+}
+
+Bandwagon.Factory.CollectionFactory.prototype._commitAddonComment = function(addonStorageID, comment)
+{
+ var statement = this.connection.createStatement("DELETE FROM addonComments WHERE addon = ?1");
+
+ try
+ {
+ statement.bindInt32Parameter(0, addonStorageID);
+ statement.execute();
+ }
+ finally
+ {
+ statement.reset();
+ }
+
+ var statement2 = this.connection.createStatement("INSERT INTO addonComments VALUES (?1, ?2, ?3)");
+
+ try
+ {
+ statement2.bindInt32Parameter(0, addonStorageID);
+ statement2.bindUTF8StringParameter(1, comment.comment);
+ statement2.bindUTF8StringParameter(2, comment.author);
+
+ statement2.execute();
+ }
+ finally
+ {
+ statement2.reset();
+ }
+}
+
+Bandwagon.Factory.CollectionFactory.prototype._commitAddonAuthor = function(addonStorageID, author)
+{
+ var statement = this.connection.createStatement("DELETE FROM addonAuthors WHERE addon = ?1");
+
+ try
+ {
+ statement.bindInt32Parameter(0, addonStorageID);
+ statement.execute();
+ }
+ finally
+ {
+ statement.reset();
+ }
+
+ var statement2 = this.connection.createStatement("INSERT INTO addonAuthors VALUES (?1, ?2)");
+
+ try
+ {
+ statement2.bindInt32Parameter(0, addonStorageID);
+ statement2.bindUTF8StringParameter(1, author);
+
+ statement2.execute();
+ }
+ finally
+ {
+ statement2.reset();
+ }
+}
+
+
diff --git a/bandwagon/content/scripts/logger.js b/bandwagon/content/scripts/logger.js
new file mode 100644
index 0000000..b4393df
--- /dev/null
+++ b/bandwagon/content/scripts/logger.js
@@ -0,0 +1,156 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is bandwagon.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s): David McNamara
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+Bandwagon.Logger = new function()
+{
+ this.ENABLE_CONSOLE_LOG = true;
+ this.ENABLE_DUMP_LOG = false;
+ this.ENABLE_TIMESTAMPS = false;
+
+ this.consoleService = null;
+ this._debug = null;
+ this._verbose = null;
+
+ this._realLog = function(msg, level)
+ {
+ if (this.ENABLE_DUMP_LOG)
+ this._dumpLog(msg, level);
+
+ if (this.ENABLE_CONSOLE_LOG)
+ this._consoleLog(msg, level);
+ }
+
+ this._dumpLog = function(msg, level)
+ {
+ dump("bandwagon(" + level + "): " + msg + "\n\n");
+ }
+
+ this._consoleLog = function(msg, level)
+ {
+ if (!this.consoleService)
+ {
+ this.consoleService = Components.classes['@mozilla.org/consoleservice;1'].
+ getService(Components.interfaces.nsIConsoleService);
+ }
+
+ var datestr = "";
+
+ if (this.ENABLE_TIMESTAMPS)
+ {
+ var date = new Date();
+ datestr = " " + date.getHours() + ":" + date.getMinutes() + ":" + date.getSeconds() + "." + date.getMilliseconds();
+ }
+
+ this.consoleService.logStringMessage("bandwagon(" + level + ")" + datestr + ": " + msg);
+ }
+
+ this._isDebugEnabled = function()
+ {
+ if (this._debug == undefined)
+ {
+ var debug = Bandwagon.Preferences.getPreference("debug");
+
+ if (debug == undefined)
+ this._debug = false;
+ else
+ this._debug = debug;
+ }
+
+ return this._debug;
+ }
+
+ this._isVerboseEnabled = function()
+ {
+ if (this._isDebugEnabled() == true)
+ {
+ return true;
+ }
+
+ if (this._verbose == undefined)
+ {
+ var verbose = Bandwagon.Preferences.getPreference("verbose");
+
+ if (verbose == undefined)
+ this._verbose = false;
+ else
+ this._verbose = verbose;
+ }
+
+ return this._verbose;
+ }
+}
+
+Bandwagon.Logger.debug = function(msg)
+{
+ //alert("Bandwagon.Logger.debug 1");
+ if (!this._isDebugEnabled()) return;
+
+ //alert("Bandwagon.Logger.debug 1");
+ this._realLog(msg, 5);
+}
+
+Bandwagon.Logger.info = function(msg)
+{
+ if (!this._isVerboseEnabled()) return;
+
+ this._realLog(msg, 3);
+}
+
+Bandwagon.Logger.log = function(msg)
+{
+ if (!this._isVerboseEnabled()) return;
+
+ this._realLog(msg, 3);
+}
+
+Bandwagon.Logger.warn = function(msg)
+{
+ if (!this._isVerboseEnabled()) return;
+
+ this._realLog(msg, 2);
+}
+
+Bandwagon.Logger.error = function(msg)
+{
+ this._realLog(msg, 1);
+}
+
+Bandwagon.Logger.fatal = function(msg)
+{
+ this._realLog(msg, 1);
+}
+
+
diff --git a/bandwagon/content/scripts/model/addon.js b/bandwagon/content/scripts/model/addon.js
new file mode 100644
index 0000000..abf4634
--- /dev/null
+++ b/bandwagon/content/scripts/model/addon.js
@@ -0,0 +1,305 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is bandwagon.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s): David McNamara
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+Bandwagon.Model.Addon = function()
+{
+ try
+ {
+ this.Bandwagon = Bandwagon;
+ }
+ catch (e) {}
+
+ this.TYPE_EXTENSION = 1;
+ this.STATUS_PUBLIC = 4;
+
+ this.storageID = -1;
+ this.collectionsAddonsStorageID = -1;
+
+ this.name = "";
+ this.type = -1;
+ this.guid = "";
+ this.version = "";
+ this.status = -1;
+ this.summary = "";
+ this.description = "";
+ this.icon = "";
+ this.eula = "";
+ this.thumbnail = "";
+ this.rating = -1;
+ this.learnmore = "";
+
+ this.compatibleApplications = {};
+ this.compatibleOS = {};
+ this.installs = {};
+
+ this.authors = {};
+ this.categories = {};
+ this.dateAdded = new Date();
+ this.comments = [];
+
+ this.read = false; // has the user seen this add-on in the collections pane
+ this.notified = false; // have we notified the user that we have a new addon
+
+ // *** temp comment
+ //this.comments.push({comment: "Hey guys - you need to check out this cool new add-on! Two days in and I'm addicted!", author: "Bob"});
+
+}
+
+Bandwagon.Model.Addon.INSTALL_YES = 1;
+Bandwagon.Model.Addon.INSTALL_NO_ADDON_IS_FOR_OLDER_VERSION = 2;
+Bandwagon.Model.Addon.INSTALL_NO_UPGRADE_TO_USE_THIS_VERSION = 3;
+Bandwagon.Model.Addon.INSTALL_NO_MUST_DOWNLOAD_BETA = 4;
+Bandwagon.Model.Addon.INSTALL_NO_NOT_COMPATIBLE_OS = 5;
+Bandwagon.Model.Addon.INSTALL_NO_IS_EXPERIMENTAL = 6;
+
+Bandwagon.Model.Addon.STATUS_PUBLIC = 4;
+Bandwagon.Model.Addon.STATUS_SANDBOX = 1;
+
+Bandwagon.Model.Addon.prototype.canInstall = function(env)
+{
+ // chec is the extension experimental
+
+ if (this.status == Bandwagon.Model.Addon.STATUS_SANDBOX)
+ {
+ var details =
+ {
+ type: Bandwagon.Model.Addon.INSTALL_NO_IS_EXPERIMENTAL,
+ requiredVersion: ""
+ };
+
+ return details;
+ }
+
+ // check is the extension compatible with this os
+
+ if (!this.getInstaller(env.os))
+ {
+ var details =
+ {
+ type: Bandwagon.Model.Addon.INSTALL_NO_NOT_COMPATIBLE_OS,
+ requiredVersion: env.os
+ };
+
+ return details;
+ }
+
+ // check is this extension compatible with firefox, etc.
+
+ var application = this.compatibleApplications[env.appName.toUpperCase()];
+
+ if (!application)
+ {
+ // this isn't the right error, but is the closest we have
+
+ var details =
+ {
+ type: Bandwagon.Model.Addon.INSTALL_NO_NOT_COMPATIBLE_OS,
+ requiredVersion: env.appName
+ };
+
+ return details;
+ }
+
+ // check the version is compatible
+
+ if (this.Bandwagon.Util.compareVersions(env.appVersion, application.minVersion) < 0)
+ {
+ // this version of firefox is less than the min version of this addon
+
+ var details;
+
+ // FIXME I don't think this the correct way to test for the "upgrade to beta"
+
+ if (application.minVersion.match(/pre/))
+ {
+ details =
+ {
+ type: Bandwagon.Model.Addon.INSTALL_NO_MUST_DOWNLOAD_BETA,
+ requiredVersion: application.minVersion
+ };
+ }
+ else
+ {
+ details =
+ {
+ type: Bandwagon.Model.Addon.INSTALL_NO_UPGRADE_TO_USE_THIS_VERSION,
+ requiredVersion: application.minVersion
+ };
+ }
+
+ return details;
+ }
+
+ if (this.Bandwagon.Util.compareVersions(env.appVersion, application.maxVersion) > 0)
+ {
+ // the version of firefox is higher than the max version of this addon
+
+ var details =
+ {
+ type: Bandwagon.Model.Addon.INSTALL_NO_ADDON_IS_FOR_OLDER_VERSION,
+ requiredVersion: application.maxVersion
+ };
+
+ return details;
+ }
+
+ // if we get this far, then the add-on is compatible
+
+ var details =
+ {
+ type: Bandwagon.Model.Addon.INSTALL_YES,
+ requiredVersion: ""
+ };
+
+ return details;
+}
+
+Bandwagon.Model.Addon.prototype.getInstaller = function(os)
+{
+ var install;
+ var addon = this;
+
+ os = os.toUpperCase();
+
+ if (this.installs['ALL'])
+ {
+ install = this.installs['ALL']
+ }
+ else if (this.installs[os])
+ {
+ install = this.installs[os];
+ }
+
+ if (!install)
+ return null;
+
+ var installer =
+ {
+ URL: install.url,
+ Hash: install.hash,
+ IconURL: addon.icon,
+ toString: function () { return this.URL; }
+ };
+
+ return installer;
+}
+
+Bandwagon.Model.Addon.prototype.toString = function()
+{
+ return this.name + " (" + this.guid + ")";
+}
+
+Bandwagon.Model.Addon.prototype.equals = function(other)
+{
+ if (other == null)
+ return false;
+
+ return (this.guid == other.guid);
+}
+
+Bandwagon.Model.Addon.prototype.unserialize = function(xaddon)
+{
+ this.name = xaddon.name.text().toString();
+ this.type = xaddon.type.attribute("id").toString();
+ this.guid = xaddon.guid.text().toString();
+ this.status = xaddon.status.attribute("id").toString();
+ this.summary = xaddon.summary.text().toString();
+ this.description = xaddon.description.text().toString();
+ this.icon = xaddon.icon.text().toString();
+ this.eula = xaddon.eula.text().toString();
+ this.thumbnail = xaddon.thumbnail.text().toString();
+ this.rating = xaddon.rating.text().toString();
+ this.learnmore = xaddon.learnmore.text().toString();
+
+ this.version = xaddon.version.text().toString(); // TODO parse version here?
+
+ for each (var xinstall in xaddon.install)
+ {
+ var install =
+ {
+ url: xinstall.text().toString(),
+ hash: xinstall.attribute("hash").toString(),
+ os: xinstall.attribute("os").toString().toUpperCase()
+ };
+
+ this.installs[install.os] = install;
+ }
+
+ for each (var xos in xaddon.all_compatible_os.os)
+ {
+ var os = xos.text().toString().toUpperCase();
+ this.compatibleOS[os] = os;
+ }
+
+ for each (var xapplication in xaddon.compatible_applications.application)
+ {
+ var application =
+ {
+ name: xapplication.name.text().toString(),
+ applicationId: xapplication.application_id.text().toString(),
+ minVersion: xapplication.min_version.text().toString(),
+ maxVersion: xapplication.max_version.text().toString(),
+ guid: xapplication.appID.text().toString()
+ };
+
+ this.compatibleApplications[application.name.toUpperCase()] = application;
+ }
+
+ for each (var xauthor in xaddon.authors.author)
+ {
+ this.authors[xauthor.text().toString()] = xauthor.text().toString();
+ }
+
+ for each (var xcategory in xaddon.categories.category)
+ {
+ this.categories[xcategory.text().toString()] = xcategory.text().toString();
+ }
+
+ this.dateAdded = this.Bandwagon.Util.ISO8601toDate(xaddon.meta.added.text().toString());
+
+ this.comments = [];
+
+ var comment0Comment = xaddon.meta.comments.text().toString();
+ var comment0Author = xaddon.meta.addedby.text().toString();
+
+ if (!comment0Author.match(/\w/))
+ comment0Author = "Unknown";
+
+ //if (comment0Comment.match(/\w/))
+ this.comments.push({comment: comment0Comment, author: comment0Author});
+
+}
+
diff --git a/bandwagon/content/scripts/model/collection.js b/bandwagon/content/scripts/model/collection.js
new file mode 100644
index 0000000..c156198
--- /dev/null
+++ b/bandwagon/content/scripts/model/collection.js
@@ -0,0 +1,255 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is bandwagon.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s): David McNamara
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+Bandwagon.Model.Collection = function()
+{
+ this.Bandwagon = Bandwagon;
+
+ this.storageID = -1;
+ this.resourceURL = "";
+ this.addonsResourceURL = "";
+
+ this.name = "";
+ this.description = "";
+ this.creator = "";
+ this.listed = false;
+ this.writable = false;
+ this.subscribed = false;
+ this.lastModified = new Date();
+
+ this.password = null;
+ this.dateAdded = new Date();
+ this.dateLastCheck = null;
+ this.active = true;
+
+ this.updateInterval = -1; // default is to use global setting
+ this.showNotifications = -1; // default is to use global setting
+ this.addonsPerPage = -1; // default is to use global setting
+
+ this.autoPublishExtensions = true;
+ this.autoPublishThemes = true;
+ this.autoPublishDicts = true;
+ this.autoPublishLangPacks = true;
+ this.autoPublishDisabled = false;
+
+ this.status = this.STATUS_NEW;
+ this.type = this.TYPE_NORMAL;
+
+ this.addons = {};
+ this.links = {};
+}
+
+Bandwagon.Model.Collection.prototype.STATUS_NEW = 0;
+Bandwagon.Model.Collection.prototype.STATUS_LOADING = 1;
+Bandwagon.Model.Collection.prototype.STATUS_LOADERROR = 2;
+Bandwagon.Model.Collection.prototype.STATUS_LOADED = 3;
+
+Bandwagon.Model.Collection.prototype.TYPE_NORMAL = "normal";
+Bandwagon.Model.Collection.prototype.TYPE_AUTOPUBLISHER = "autopublisher";
+Bandwagon.Model.Collection.prototype.TYPE_OTHER = "other";
+
+Bandwagon.Model.Collection.prototype.getUnreadAddons = function()
+{
+ var unreadAddons = [];
+
+ for (var id in this.addons)
+ {
+ if (!this.addons[id].read)
+ {
+ unreadAddons.push(this.addons[id]);
+ }
+ }
+
+ return unreadAddons;
+}
+
+Bandwagon.Model.Collection.prototype.setAllRead = function()
+{
+ for (var id in this.addons)
+ {
+ this.addons[id].read = true;
+ }
+}
+
+Bandwagon.Model.Collection.prototype.getUnnotifiedAddons = function()
+{
+ var unnotifiedAddons = [];
+
+ for (var id in this.addons)
+ {
+ if (!this.addons[id].notified)
+ {
+ unnotifiedAddons.push(this.addons[id]);
+ }
+ }
+
+ return unnotifiedAddons;
+}
+
+Bandwagon.Model.Collection.prototype.setAllNotified = function()
+{
+ for (var id in this.addons)
+ {
+ this.addons[id].notified = true;
+ }
+}
+
+Bandwagon.Model.Collection.prototype.getSortedAddons = function()
+{
+ var sortedAddons = [];
+
+ for (var id in this.addons)
+ {
+ sortedAddons.push(this.addons[id]);
+ }
+
+ sortedAddons.sort(function(a, b)
+ {
+ // sorting is unread, then dateadded
+
+ if (a.read == false && b.read == true ) return -1;
+ if (a.read == true && b.read == false ) return 1;
+
+ return (a.dateAdded.getTime() < b.dateAdded.getTime()?1:-1);
+ });
+
+ return sortedAddons;
+}
+
+Bandwagon.Model.Collection.prototype.hasAddon = function()
+{
+ for (var id in this.addons)
+ {
+ if (this.addons[id] && this.addons[id].guid)
+ {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+Bandwagon.Model.Collection.prototype.getNicknameFromName = function()
+{
+ return this.name.replace(/\W/g, "_");
+}
+
+Bandwagon.Model.Collection.prototype.isLocalAutoPublisher = function()
+{
+ if (this.type != this.TYPE_AUTOPUBLISHER)
+ return false;
+
+ if (this.name == "")
+ return false;
+
+ return (this.Bandwagon.Preferences.getPreference("local.autopublisher") == this.resourceURL);
+}
+
+Bandwagon.Model.Collection.prototype.toString = function()
+{
+ return this.name + " (" + this.resourceURL + ")";
+}
+
+Bandwagon.Model.Collection.prototype.equals = function(other)
+{
+ if (other == null)
+ return false;
+
+ return (this.resourceURL == other.resourceURL);
+}
+
+Bandwagon.Model.Collection.prototype.unserialize = function(xcollection)
+{
+ var baseURL = xcollection.@xmlbase.toString();
+
+ //this.resourceURL = baseURL + "/" + xcollection.attribute("href").toString();
+
+ this.name = xcollection.attribute("name").toString();
+ this.description = xcollection.attribute("description").toString();
+ this.creator = xcollection.attribute("creator").toString();
+ this.listed = (xcollection.attribute("listed").toString()=="yes"?true:false);
+ this.writable = (xcollection.attribute("writable").toString()=="yes"?true:false);
+ this.subscribed = (xcollection.attribute("subscribed").toString()=="yes"?true:false);
+ this.lastModified = this.Bandwagon.Util.ISO8601toDate(xcollection.attribute("lastmodified").toString());
+ this.type = xcollection.attribute("type").toString();
+
+ //this.addonsResourceURL = baseURL + "/" + xcollection.addons.attribute("href").toString();
+
+ for each (var xaddon in xcollection.addons.addon)
+ {
+ var addon = new this.Bandwagon.Model.Addon();
+ addon.Bandwagon = this.Bandwagon;
+
+ addon.unserialize(xaddon);
+
+ if (addon.guid && addon.guid != "" && addon.name && addon.name != "")
+ {
+ if (this.addons[addon.guid])
+ {
+ // "merge" with existing item
+ this.addons[addon.guid].unserialize(xaddon);
+ }
+ else
+ {
+ this.addons[addon.guid] = addon;
+ }
+
+ this.addons[addon.guid].seen = true;
+ }
+ }
+
+ for (var id in this.addons)
+ {
+ if (this.addons[id].seen != true)
+ {
+ delete this.addons[id];
+ continue;
+ }
+
+ this.addons[id].seen = false;
+ }
+
+ var linkBaseURL = xcollection.links.@xmlbase.toString();
+
+ for each (var xlink in xcollection.links.link)
+ {
+ var rel = xlink.attribute("id").toString();
+ var href = xlink.attribute("href").toString();
+
+ this.links[rel] = linkBaseURL + href;
+ }
+}
+
diff --git a/bandwagon/content/scripts/model/serviceDocument.js b/bandwagon/content/scripts/model/serviceDocument.js
new file mode 100644
index 0000000..fc29a50
--- /dev/null
+++ b/bandwagon/content/scripts/model/serviceDocument.js
@@ -0,0 +1,79 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is bandwagon.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s): David McNamara
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+Bandwagon.Model.ServiceDocument = function()
+{
+ this.Bandwagon = Bandwagon;
+
+ this.emailResourceURL = "";
+ this.collectionListResourceURL = "";
+
+ this.collections = [];
+}
+
+Bandwagon.Model.ServiceDocument.prototype.unserialize = function(xsharing)
+{
+ var baseURL = xsharing.@xmlbase.toString();
+
+ // resource urls
+
+ this.emailResourceURL = baseURL + "/" + xsharing.email.attribute("href").toString();
+ this.collectionListResourceURL = baseURL + "/" + xsharing.collections.attribute("href").toString();
+
+ // collections
+
+ for each (var xcollection in xsharing.collections.collection)
+ {
+ var collection = new this.Bandwagon.Model.Collection();
+ collection.Bandwagon = this.Bandwagon;
+
+ collection.resourceURL = baseURL + "/" + xcollection.attribute("href").toString();
+
+ collection.name = xcollection.attribute("name").toString();
+ collection.description = xcollection.attribute("description").toString();
+ collection.creator = xcollection.attribute("creator").toString();
+ collection.listed = (xcollection.attribute("listed").toString()=="yes"?true:false);
+ collection.writable = (xcollection.attribute("writable").toString()=="yes"?true:false);
+ collection.subscribed = (xcollection.attribute("subscribed").toString()=="yes"?true:false);
+ collection.lastModified = this.Bandwagon.Util.ISO8601toDate(xcollection.attribute("lastmodified").toString());
+ collection.type = xcollection.attribute("type").toString();
+
+ collection.addonsResourceURL = baseURL + "/" + xcollection.addons.attribute("href").toString();
+
+ if (collection.subscribed)
+ this.collections.push(collection);
+ }
+}
diff --git a/bandwagon/content/scripts/prefs.js b/bandwagon/content/scripts/prefs.js
new file mode 100644
index 0000000..85862db
--- /dev/null
+++ b/bandwagon/content/scripts/prefs.js
@@ -0,0 +1,222 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is bandwagon.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s): David McNamara
+ * Brian King
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+Bandwagon.Preferences = new function() {}
+
+Bandwagon.Preferences._prefServiceRoot = "extensions.bandwagon.";
+Bandwagon.Preferences._prefServiceListDelimiter = "|";
+Bandwagon.Preferences._prefServiceCache = null;
+
+Bandwagon.Preferences.setPreference = function(name, value)
+{
+ try
+ {
+ if (typeof value == 'boolean')
+ {
+ this._getPrefService().setBoolPref(name, value);
+ }
+ else if (typeof value == 'number')
+ {
+ this._getPrefService().setIntPref(name, value);
+ }
+ else if (typeof value == 'string')
+ {
+ this._getPrefService().setCharPref(name, value);
+ }
+ else
+ {
+ this._getPrefService().setCharPref(name, value.toString());
+ }
+ }
+ catch (e)
+ {
+ Bandwagon.Logger.error(e);
+ }
+}
+
+Bandwagon.Preferences.getPreference = function(name)
+{
+ var val = null;
+
+ try
+ {
+ var type = this._getPrefService().getPrefType(name);
+
+ if (this._getPrefService().PREF_BOOL == type)
+ {
+ val = this._getPrefService().getBoolPref(name);
+ }
+ else if (this._getPrefService().PREF_INT == type)
+ {
+ val = this._getPrefService().getIntPref(name);
+ }
+ else if (this._getPrefService().PREF_STRING == type)
+ {
+ val = this._getPrefService().getCharPref(name);
+ }
+ else
+ {
+ Bandwagon.Logger.error("Invalid pref: " + name);
+ }
+ }
+ catch (e)
+ {
+ Bandwagon.Logger.error(e);
+ }
+
+ return val;
+}
+
+Bandwagon.Preferences.setPreferenceList = function(name, list)
+{
+ // TODO ensure there's no this._prefServiceListDelimiter in the list
+
+ var joinedList = list.join(this._prefServiceListDelimiter);
+
+ this.setPreference(name, joinedList);
+}
+
+Bandwagon.Preferences.getPreferenceList = function(name)
+{
+ var pref = this.getPreference(name, "char");
+
+ if (!pref) return new Array();
+
+ return pref.split(this._prefServiceListDelimiter);
+}
+
+Bandwagon.Preferences.addObserver = function(observer)
+{
+ var prefService = this._getPrefService();
+
+ prefService.QueryInterface(Components.interfaces.nsIPrefBranch2);
+ prefService.addObserver("", observer, false);
+}
+
+Bandwagon.Preferences.removeObserver = function(observer)
+{
+ this._getPrefService().removeObserver("", observer);
+}
+
+Bandwagon.Preferences.notifyObservers = function(data)
+{
+ Components.classes["@mozilla.org/observer-service;1"]
+ .getService(Components.interfaces.nsIObserverService)
+ .notifyObservers(null, "nsPref:changed", data);
+}
+
+Bandwagon.Preferences.getGlobalPreference = function(name, failSilently)
+{
+ var prefSvc = Components.classes["@mozilla.org/preferences-service;1"].
+ getService(Components.interfaces.nsIPrefService);
+
+ var val = null;
+
+ try
+ {
+ var type = prefSvc.getPrefType(name);
+
+ if (prefSvc.PREF_BOOL == type)
+ {
+ val = prefSvc.getBoolPref(name);
+ }
+ else if (prefSvc.PREF_INT == type)
+ {
+ val = prefSvc.getIntPref(name);
+ }
+ else if (prefSvc.PREF_STRING == type)
+ {
+ val = prefSvc.getCharPref(name);
+ }
+ else if (failSilently == undefined || failSilently == false)
+ {
+ Bandwagon.Logger.error("Invalid pref: " + name);
+ }
+ }
+ catch (e)
+ {
+ if (failSilently == undefined || failSilently == false)
+ Bandwagon.Logger.error(e);
+
+ return null;
+ }
+
+ return val;
+}
+
+Bandwagon.Preferences.addGlobalObserver = function(observer, branchName)
+{
+ var prefService = Components.classes["@mozilla.org/preferences-service;1"]
+ .getService(Components.interfaces.nsIPrefService);
+
+ var branch = prefService.getBranch(branchName);
+ branch.QueryInterface(Components.interfaces.nsIPrefBranch2);
+
+ branch.addObserver("", observer, false);
+}
+
+Bandwagon.Preferences.removeGlobalObserver = function(observer, branchName)
+{
+ var prefService = Components.classes["@mozilla.org/preferences-service;1"]
+ .getService(Components.interfaces.nsIPrefService);
+
+ var branch = prefService.getBranch(branchName);
+ branch.QueryInterface(Components.interfaces.nsIPrefBranch2);
+
+ branch.removeObserver("", observer);
+}
+
+Bandwagon.Preferences._getPrefService = function()
+{
+ if (!this._prefServiceCache)
+ {
+ try
+ {
+ var prefSvc = Components.classes["@mozilla.org/preferences-service;1"].
+ getService(Components.interfaces.nsIPrefService);
+ this._prefServiceCache = prefSvc.getBranch(this._prefServiceRoot);
+ }
+ catch (e)
+ {
+ Bandwagon.Logger.error("Can't get Prefs Service: " + e);
+ }
+ }
+
+ return this._prefServiceCache;
+}
+
+
diff --git a/bandwagon/content/scripts/rpc/constants.js b/bandwagon/content/scripts/rpc/constants.js
new file mode 100644
index 0000000..3676bed
--- /dev/null
+++ b/bandwagon/content/scripts/rpc/constants.js
@@ -0,0 +1,82 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is bandwagon.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s): David McNamara
+ * Brian King
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+Bandwagon.RPC.Constants = new function()
+{
+ this.BANDWAGON_RPC_SERVICE_DOCUMENT = "https://%%AMO_HOST%%/en-US/firefox/api/1.3/sharing/";
+
+ this.BANDWAGON_RPC_ENABLE_CACHE_BUSTER = 1;
+
+ this.BANDWAGON_RPC_EVENT_TYPE_BANDWAGON_RPC_GET_SERVICE_DOCUMENT_COMPLETE = 100;
+ this.BANDWAGON_RPC_EVENT_TYPE_BANDWAGON_RPC_GET_COLLECTION_COMPLETE = 200;
+ this.BANDWAGON_RPC_EVENT_TYPE_BANDWAGON_RPC_SHARE_TO_EMAIL_COMPLETE = 300;
+ this.BANDWAGON_RPC_EVENT_TYPE_BANDWAGON_RPC_PUBLISH_COMPLETE = 400;
+ this.BANDWAGON_RPC_EVENT_TYPE_BANDWAGON_RPC_REMOVE_ADDON_FROM_COLLECTION_COMPLETE = 500;
+ this.BANDWAGON_RPC_EVENT_TYPE_BANDWAGON_RPC_NEW_COLLECTION_COMPLETE = 600;
+ this.BANDWAGON_RPC_EVENT_TYPE_BANDWAGON_RPC_DELETE_COLLECTION_COMPLETE = 700;
+ this.BANDWAGON_RPC_EVENT_TYPE_BANDWAGON_RPC_GET_AUTH_DOCUMENT_COMPLETE = 800;
+ this.BANDWAGON_RPC_EVENT_TYPE_BANDWAGON_RPC_UNSUBSCRIBE_FROM_COLLECTION_COMPLETE = 900;
+ this.BANDWAGON_RPC_EVENT_TYPE_BANDWAGON_RPC_SUBSCRIBE_TO_COLLECTION_COMPLETE = 1000;
+ this.BANDWAGON_RPC_EVENT_TYPE_BANDWAGON_RPC_UPDATE_COLLECTION_COMPLETE = 1100;
+
+ // xhr layer constants
+
+ this.BANDWAGON_RPC_NET_FAILURE = -1;
+ this.BANDWAGON_RPC_NET_SUCCESS = 1;
+ this.BANDWAGON_RPC_NET_CREATED = 10;
+ this.BANDWAGON_RPC_NET_INPROGRESS = 20;
+ this.BANDWAGON_RPC_NET_FINISHED = 30;
+
+ this.BANDWAGON_RPC_NET_ERROR_HTTP = 400;
+ this.BANDWAGON_RPC_NET_ERROR_XHR_CONNECTION = 500;
+ this.BANDWAGON_RPC_NET_ERROR_XHR_CREATE = 510;
+ this.BANDWAGON_RPC_NET_ERROR_XML_PROTOCOL = 520;
+
+ this.BANDWAGON_RPC_SERVICE_ERROR_BAD_XML = 1010; // http status 200 - 300, but unparsable XML response
+ this.BANDWAGON_RPC_SERVICE_ERROR_UNEXPECTED_XML = 1011; // http status 200 - 300, but unexpected XML response
+ this.BANDWAGON_RPC_SERVICE_ERROR = 1050; // http status 200 - 300, but "expected" error in XML response
+
+ this.BANDWAGON_RPC_SERVICE_ERROR_BAD_REQUEST = 1400; //400 BAD REQUEST = Invalid request URI or header, or unsupported nonstandard parameter.
+ this.BANDWAGON_RPC_SERVICE_ERROR_UNAUTHORIZED = 1401; //401 UNAUTHORIZED = Authorization required.
+ this.BANDWAGON_RPC_SERVICE_ERROR_FORBIDDEN = 1403; //403 FORBIDDEN = Unsupported standard parameter, or authentication or authorization failed.
+ this.BANDWAGON_RPC_SERVICE_ERROR_NOT_FOUND = 1404; //404 NOT FOUND = Resource (such as a collection or entry) not found.
+ this.BANDWAGON_RPC_SERVICE_ERROR_CONFLICT = 1409; //409 CONFLICT = Specified version number doesn't match resource's latest version number.
+ this.BANDWAGON_RPC_SERVICE_ERROR_BAD_CONTEXT = 1422; //422 BAD CONTENT = The data within this entry's <content> is not valid. For example, this may indicate not "well-formed" XML
+ this.BANDWAGON_RPC_SERVICE_ERROR_INTERNAL_SERVER_ERROR = 1500; //500 INTERNAL SERVER ERROR = Internal error. This is the default code that is used for all unrecognized errors.
+ this.BANDWAGON_RPC_SERVICE_ERROR_CRITICAL_ERROR = 1600; // http status other
+
+}
diff --git a/bandwagon/content/scripts/rpc/error.js b/bandwagon/content/scripts/rpc/error.js
new file mode 100644
index 0000000..f5a9a48
--- /dev/null
+++ b/bandwagon/content/scripts/rpc/error.js
@@ -0,0 +1,67 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is bandwagon.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s): David McNamara
+ * Brian King
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+
+Bandwagon.RPC.Error = function(code, message)
+{
+ this.code = (code != null?code:0);
+ this.message = message;
+ this.url = null;
+}
+
+Bandwagon.RPC.Error.prototype.getCode = function()
+{
+ return this.code;
+}
+
+Bandwagon.RPC.Error.prototype.getMessage = function()
+{
+ if (this.message == null || this.message == "")
+ {
+ return "(error " + this.code + ")";
+ }
+ else
+ {
+ return this.message;
+ }
+}
+
+Bandwagon.RPC.Error.prototype.toString = function()
+{
+ return "Error " + this.getCode() + ": " + this.getMessage();
+}
+
diff --git a/bandwagon/content/scripts/rpc/event.js b/bandwagon/content/scripts/rpc/event.js
new file mode 100644
index 0000000..a388f3a
--- /dev/null
+++ b/bandwagon/content/scripts/rpc/event.js
@@ -0,0 +1,88 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is bandwagon.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s): David McNamara
+ * Brian King
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+Bandwagon.RPC.Event = function(type, result, response)
+{
+ this.Bandwagon = Bandwagon;
+
+ // public instance variables
+ this._type = type;
+ this._result = result;
+ this._response = response;
+ this.error = null;
+}
+
+Bandwagon.RPC.Event.prototype.isError = function()
+{
+ return this._result != this.Bandwagon.RPC.Constants.BANDWAGON_RPC_NET_SUCCESS;
+}
+
+Bandwagon.RPC.Event.prototype.setError = function(error)
+{
+ this.error = error;
+ this._result = error.code;
+}
+
+Bandwagon.RPC.Event.prototype.getError = function()
+{
+ if (this._result == this.Bandwagon.RPC.Constants.BANDWAGON_RPC_NET_SUCCESS) return null;
+
+ if (this.error == null)
+ {
+ this.error = new this.Bandwagon.RPC.Error();
+ this.error.code = -1;
+ this.error.message = "Internal error";
+ }
+
+ return this.error;
+}
+
+Bandwagon.RPC.Event.prototype.getType = function()
+{
+ return this._type;
+}
+
+Bandwagon.RPC.Event.prototype.getData = function()
+{
+ return this._response;
+}
+
+Bandwagon.RPC.Event.prototype.toString = function()
+{
+ return "Event (" + (this.isError() ? this.getError().toString() : "Success") + ")";
+}
+
diff --git a/bandwagon/content/scripts/rpc/net.js b/bandwagon/content/scripts/rpc/net.js
new file mode 100644
index 0000000..7a2c2a8
--- /dev/null
+++ b/bandwagon/content/scripts/rpc/net.js
@@ -0,0 +1,353 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is bandwagon.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s): David McNamara
+ * Brian King
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+Bandwagon.RPC.Net = function(Bandwagon, Components)
+{
+ this.Bandwagon = Bandwagon;
+ this.Components = Components;
+
+ // public instance variables
+ this.onComplete = function(rpc, result, response, type, request) {};
+ this.status = this.Bandwagon.RPC.Constants.BANDWAGON_RPC_NET_CREATED;
+ this.id = ((new Date()).getTime() - 1169730000000) + "" + (Math.round(1000*Math.random())+1000);
+
+ // private instance variables
+ this._url = '';
+ this._method = 'GET';
+ this._basicAuthUsername = '';
+ this._basicAuthPassword = '';
+ this._queryString = '';
+ this._postData = '';
+ this._type = null;
+ this._headers = {};
+
+ this._request = null;
+ this._logger = null;
+
+ this.finished = function(result, response, request)
+ {
+ this._logger.debug('Bandwagon.RPC.Net.finished: ' + this.id + ': finished');
+ this.status = this.Bandwagon.RPC.Constants.BANDWAGON_RPC_NET_FINISHED;
+ this.onComplete(this, result, response, this._type, request);
+ };
+
+ this.failed = function(errorCode, errorMessage, data)
+ {
+ this._logger.debug('Bandwagon.RPC.Net.failed: ' + this.id + ': failed');
+ this.status = this.Bandwagon.RPC.Constants.BANDWAGON_RPC_NET_FINISHED;
+ var response = {errorCode: errorCode, errorMessage: errorMessage, data: data};
+ this.onComplete(this, this.Bandwagon.RPC.Constants.BANDWAGON_RPC_NET_FAILURE, response, this._type, null);
+ };
+
+ this.ready = function (rpcnetrequest)
+ {
+ var rpcnet = this;
+
+ try
+ {
+ //rpc._logger.debug('Bandwagon.RPC.Net.send.onreadystatechange: ' + rpc.id + ': readyState = ' + rpcnetrequest.readyState);
+ if (rpcnetrequest.readyState != 4) { return; }
+ }
+ catch (e)
+ {
+ rpcnet._logger.error('Bandwagon.RPC.Net.send.onreadystatechange: ' + rpcnet.id + ': error in readyState: ' + e);
+ rpcnet.failed(rpcnet.Bandwagon.RPC.Constants.BANDWAGON_RPC_NET_ERROR_XHR_CONNECTION);
+ return;
+ }
+
+ var result = rpcnet.Bandwagon.RPC.Constants.BANDWAGON_RPC_NET_SUCCESS;
+ var status = 0;
+ var response = null;
+ var lastErr = null;
+
+ try
+ {
+ status = rpcnetrequest.status;
+ }
+ catch (e)
+ {
+ rpcnet._logger.error('Bandwagon.RPC.Net.send.onreadystatechange: ' + rpcnet.id + ': no http status... a protocol error occured');
+ rpcnet.failed(rpcnet.Bandwagon.RPC.Constants.BANDWAGON_RPC_NET_ERROR_HTTP);
+ return;
+ }
+
+ try
+ {
+ var xmlStr = rpcnetrequest.responseText;
+
+ // dave@briks: The following hacks are workarounds for E4X
+ // bugs/features. If anyone knows the dark secrets of namespace
+ // support in e4x please let me know!
+
+ xmlStr = xmlStr.replace(/^<\?xml\s+version\s*=\s*(["'])[^\1]+\1[^?]*\?>/, ""); // bug 336551
+ xmlStr = xmlStr.replace(/xmlns="http:\/\/addons.mozilla.org\/"/gi, "");
+ xmlStr = xmlStr.replace(/xml:base=/gi, "xmlbase=");
+
+ response = new XML(xmlStr);
+
+ //rpcnet._logger.debug("Bandwagon.RPC.Net.send.onreadystatechange: ' + rpcnet.id + ': XML representation: '" + response.toXMLString() + "'");
+ }
+ catch (e)
+ {
+ rpcnet._logger.error('Bandwagon.RPC.Net.send.onreadystatechange: ' + rpcnet.id + ": can't evaluate XML response... '" + e + "'");
+ lastErr = e;
+ }
+
+ rpcnet._logger.debug('Bandwagon.RPC.Net.send.onreadystatechange: ' + rpcnet.id + ': completed, status = ' + status);
+ rpcnet._logger.debug('Bandwagon.RPC.Net.send.onreadystatechange: ' + rpcnet.id + ": completed, response text = '" + rpcnetrequest.responseText + "'");
+
+ if (
+ (rpcnet._method == 'DELETE' && (status == 303))
+ || (rpcnet._method == 'DELETE' && (status == 410))
+ || (status >= 200 && status <= 300)
+ )
+ {
+ if (response != null)
+ {
+ // everything went successfully
+ rpcnet.finished(rpcnet.Bandwagon.RPC.Constants.BANDWAGON_RPC_NET_SUCCESS, response, rpcnetrequest);
+ return;
+ }
+ else
+ {
+ // application error (bad xml)
+ rpcnet.failed(rpcnet.Bandwagon.RPC.Constants.BANDWAGON_RPC_SERVICE_ERROR_BAD_XML, lastErr, response);
+ return;
+ }
+ }
+
+ // try to get an error message in response error -> lastErr
+
+ try
+ {
+ lastErr = (response.attribute("reason")?response.attribute("reason"):"?");
+ rpcnet._logger.debug('Bandwagon.RPC.Net.send.onreadystatechange: ' + rpcnet.id + ": completed, response error message = '" + lastErr + "'");
+ }
+ catch (e)
+ {
+ rpcnet._logger.debug('Bandwagon.RPC.Net.send.onreadystatechange: ' + rpcnet.id + ": have an error status code (" + status + "), but there is no error message in the XML response");
+ lastErr = null;
+ }
+
+ if (status == 400)
+ {
+ rpcnet.failed(rpcnet.Bandwagon.RPC.Constants.BANDWAGON_RPC_SERVICE_ERROR_BAD_REQUEST, lastErr, response);
+ return;
+ }
+ else if (status == 401)
+ {
+ rpcnet.failed(rpcnet.Bandwagon.RPC.Constants.BANDWAGON_RPC_SERVICE_ERROR_UNAUTHORIZED, lastErr, response);
+ return;
+ }
+ else if (status == 403)
+ {
+ rpcnet.failed(rpcnet.Bandwagon.RPC.Constants.BANDWAGON_RPC_SERVICE_ERROR_FORBIDDEN, lastErr, response);
+ return;
+ }
+ else if (status == 404)
+ {
+ rpcnet.failed(rpcnet.Bandwagon.RPC.Constants.BANDWAGON_RPC_SERVICE_ERROR_NOT_FOUND, lastErr, response);
+ return;
+ }
+ else if (status == 409)
+ {
+ rpcnet.failed(rpcnet.Bandwagon.RPC.Constants.BANDWAGON_RPC_SERVICE_ERROR_CONFLICT, lastErr, response);
+ return;
+ }
+ else if (status == 422)
+ {
+ rpcnet.failed(rpcnet.Bandwagon.RPC.Constants.BANDWAGON_RPC_SERVICE_ERROR_BAD_CONTEXT, lastErr, response);
+ return;
+ }
+ else if (status == 500)
+ {
+ rpcnet.failed(rpcnet.Bandwagon.RPC.Constants.BANDWAGON_RPC_SERVICE_ERROR_INTERNAL_SERVER_ERROR, lastErr, response);
+ return;
+ }
+ else
+ {
+ rpcnet.failed(rpcnet.Bandwagon.RPC.Constants.BANDWAGON_RPC_SERVICE_ERROR_CRITICAL_ERROR, lastErr, response);
+ return;
+ }
+ };
+}
+
+Bandwagon.RPC.Net.prototype.registerLogger = function(logger)
+{
+ this._logger = logger;
+}
+
+Bandwagon.RPC.Net.prototype.setUrl = function(url)
+{
+ this._url = url;
+}
+
+Bandwagon.RPC.Net.prototype.setType = function(type)
+{
+ this._type = type;
+}
+
+Bandwagon.RPC.Net.prototype.setPostData = function(args)
+{
+ this._postData = '';
+
+ for (var i in args)
+ {
+ this._postData += this.Bandwagon.Util.encodeURL(i) + '=' + this.Bandwagon.Util.encodeURL(args[i]) + '&';
+ }
+
+ if ('&' == this._postData.charAt(this._postData.length-1))
+ {
+ this._postData = this._postData.substring(0,this._postData.length-1);
+ }
+}
+
+Bandwagon.RPC.Net.prototype.setArguments = function(args)
+{
+ this._queryString = '';
+
+ for (var i in args)
+ {
+ this._queryString += this.Bandwagon.Util.encodeURL(i) + '=' + this.Bandwagon.Util.encodeURL(args[i]) + '&';
+ }
+
+ if ('&' == this._queryString.charAt(this._queryString.length-1))
+ {
+ this._queryString = this._queryString.substring(0,this._queryString.length-1);
+ }
+}
+
+Bandwagon.RPC.Net.prototype.setMethod = function(method)
+{
+ if (method == 'POST')
+ {
+ this._method = 'POST';
+ }
+ else if (method == 'DELETE')
+ {
+ this._method = 'DELETE';
+ }
+ else if (method == 'PUT')
+ {
+ this._method = 'PUT';
+ }
+ else
+ {
+ this._method = 'GET';
+ }
+
+ this._method = method;
+}
+
+Bandwagon.RPC.Net.prototype.setHeader = function(header, value)
+{
+ this._headers[header] = value;
+}
+
+Bandwagon.RPC.Net.prototype.setCredentials = function(username, password)
+{
+ this._basicAuthUsername = username;
+ this._basicAuthPassword = password;
+}
+
+Bandwagon.RPC.Net.prototype.send = function()
+{
+ var rpcnet = this;
+
+ rpcnet.status = rpcnet.Bandwagon.RPC.Constants.BANDWAGON_RPC_NET_INPROGRESS;
+
+ //rpc._logger.debug('Bandwagon.RPC.Net.send: ' + rpc.id + ': creating ' + rpc._method + ' XMLHttpRequest');
+
+ var rpcnetrequest = rpcnet.Components.classes["@mozilla.org/xmlextras/xmlhttprequest;1"].createInstance(rpcnet.Components.interfaces.nsIXMLHttpRequest);
+
+ if (!rpcnetrequest) { rpcnet.failed(rpcnet.Bandwagon.RPC.Constants.BANDWAGON_RPC_NET_ERROR_XHR_CREATE); }
+
+ rpcnetrequest.mozBackgroundRequest = true;
+
+ var postData = null;
+ var url = rpcnet._url;
+
+ if (('POST' == rpcnet._method || 'PUT' == rpcnet._method)
+ && rpcnet._postData.length > 0)
+ {
+ postData = rpcnet._postData;
+ }
+ else if (rpcnet._queryString && (rpcnet._queryString.length > 0))
+ {
+ url += "?" + rpcnet._queryString;
+ }
+
+ rpcnet._logger.debug('Bandwagon.RPC.Net.send: ' + rpcnet.id + ': opening ' + rpcnet._method + ' XMLHttpRequest to ' + url);
+
+ try
+ {
+ rpcnetrequest.open(rpcnet._method, url, true);
+ }
+ catch (e)
+ {
+ rpcnet._logger.error('Bandwagon.RPC.Net.send: ' + rpcnet.id + ': error opening connection: ' + e);
+ rpcnet.failed(rpcnet.Bandwagon.RPC.Constants.BANDWAGON_RPC_NET_ERROR_XHR_CREATE);
+ return;
+ }
+
+ if ('POST' == rpcnet._method)
+ {
+ rpcnetrequest.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
+ }
+
+ for (var header in rpcnet._headers)
+ {
+ //rpcnet._logger.debug('Bandwagon.RPC.Net.send: ' + rpcnet.id + ': adding custom header ' + header + ': ' + rpcnet._headers[header]);
+ rpcnetrequest.setRequestHeader(header, rpcnet._headers[header]);
+ }
+
+ if ('' != rpcnet._basicAuthUsername) {
+ rpcnet._logger.debug('Bandwagon.RPC.Net.send: using credentials for ' + rpcnet._basicAuthUsername);
+ rpcnetrequest.setRequestHeader('Authorization', 'Basic ' + btoa(rpcnet._basicAuthUsername + ':' + rpcnet._basicAuthPassword));
+ }
+
+ rpcnetrequest.setRequestHeader("If-Modified-Since", "Sat, 1 Jan 2005 00:00:00 GMT");
+
+ // Cache-Control: no-cache ?
+ //rpcnetrequest.overrideMimeType('text/xml');
+
+ rpcnetrequest.onreadystatechange = function() { rpcnet.ready(rpcnetrequest); };
+
+ rpcnet._logger.debug('Bandwagon.RPC.Net.send: ' + rpcnet.id + ': sending XMLHttpRequest ' + (postData?' with data "' + postData + '"':''));
+
+ rpcnetrequest.send(postData);
+}
diff --git a/bandwagon/content/scripts/rpc/service.js b/bandwagon/content/scripts/rpc/service.js
new file mode 100644
index 0000000..a444e7a
--- /dev/null
+++ b/bandwagon/content/scripts/rpc/service.js
@@ -0,0 +1,610 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is bandwagon.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s): David McNamara
+ * Brian King
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+Bandwagon.RPC = new function() {}
+
+Bandwagon.RPC.Service = function()
+{
+ // keep reference these things in case they go away. (we're in a component - it happens)
+ this.Bandwagon = Bandwagon;
+ this.Components = Components;
+
+ // private instance variables
+ this._observers = new Array();
+ this._logger = null;
+ this._serviceDocument = null;
+ this._serviceRootURL = this.Bandwagon.RPC.Constants.BANDWAGON_RPC_SERVICE_DOCUMENT;
+
+ this.rpcComplete = function(rpcnet, result, response, type, callback)
+ {
+ var service = this;
+
+ service._logger.debug("Bandwagon.RPC.Service: got rpc complete (id=" + (rpcnet?rpcnet.id:"null") + ",s=" + (rpcnet?rpcnet.status:"null") + ") of type = " + type + " and status = " + result);
+
+ var event = new service.Bandwagon.RPC.Event(type, result, response);
+ event.Bandwagon = service.Bandwagon;
+
+ if (result == service.Bandwagon.RPC.Constants.BANDWAGON_RPC_NET_FAILURE)
+ {
+ // response is error code
+ service._logger.debug("Bandwagon.RPC.Service: complete is error with error code: " + response.errorCode + ", message: " + response.errorMessage);
+ event.error = new service.Bandwagon.RPC.Error(response.errorCode, response.errorMessage);
+ event._response = response.data;
+ }
+
+ // CALLBACK TYPE 1: if we have a callback, call it
+
+ if (callback && typeof(callback) == 'function')
+ {
+ callback(event);
+ }
+
+ // CALLBACK TYPE 2: if we have observers, notify them
+
+ service.notifyObservers(event);
+ };
+
+ this.rpcCompleteWithError = function(rpcnet, errorCode, type)
+ {
+ this.rpcComplete(rpcnet, this.Bandwagon.RPC.Constants.BANDWAGON_RPC_RPC_FAILURE, errorCode, type);
+ }
+
+ this.notifyObservers = function(event)
+ {
+ //for (var i=0; i<this._observers.length; i++)
+ for (var id in this._observers)
+ {
+ if (this._observers[id])
+ {
+ try
+ {
+ this._observers[id](event);
+ }
+ catch (e)
+ {
+ this._logger.error("Bandwagon.RPC.Service.onComplete: error notifying observer: " + e);
+ //Bandwagon.Util.dumpObject(e);
+ }
+ }
+ }
+ };
+
+ this.rpcSend = function(type, callback, action, method, data, url, credentials)
+ {
+ var service = this;
+
+ var rpcnet = new service.Bandwagon.RPC.Net(service.Bandwagon, service.Components);
+
+ rpcnet.registerLogger(service._logger);
+ var isLogin = (type == service.Bandwagon.RPC.Constants.BANDWAGON_RPC_EVENT_TYPE_BANDWAGON_RPC_LOGIN_COMPLETE);
+ var actionUrl = (action.match(/^https?:/)?action:(this._serviceRootURL+action));
+ service._logger.debug("Bandwagon.RPC.Service: request going to : " + actionUrl);
+ rpcnet.setUrl(actionUrl);
+ rpcnet.setType(type);
+
+ if (method && method == "POST")
+ {
+ rpcnet.setMethod("POST");
+ rpcnet.setPostData(data);
+ }
+ else if (method == "DELETE")
+ {
+ rpcnet.setMethod("DELETE");
+ }
+ else if (method == "PUT")
+ {
+ rpcnet.setMethod("PUT");
+ rpcnet.setPostData(data);
+ }
+ else
+ {
+ rpcnet.setMethod("GET");
+
+ if (service.Bandwagon.RPC.Constants.BANDWAGON_RPC_ENABLE_CACHE_BUSTER)
+ {
+ if (data == null)
+ data = [];
+
+ data["__"] = (new Date()).getTime();
+ }
+
+ rpcnet.setArguments(data);
+ }
+
+ rpcnet.setHeader("X-API-Auth", service.Bandwagon.Preferences.getPreference(service.Bandwagon.PREF_AUTH_TOKEN));
+
+ if (credentials)
+ {
+ rpcnet.setCredentials(credentials.login, credentials.password);
+ }
+
+ rpcnet.onComplete = function(rpc, result, response, type) { service.rpcComplete(rpc, result, response, type, callback); };
+
+ // send immediately
+ service._logger.debug("Bandwagon.RPC.Service: sending rpc immediately");
+ rpcnet.send();
+ };
+
+ this.createAction = function(action, replacements)
+ {
+ if (replacements)
+ {
+ for (var i=0; i<replacements.length; i++)
+ {
+ action = action.replace("%" + (i+1), encodeURIComponent(replacements[i]));
+ }
+ }
+
+ return action;
+ };
+
+ this.getUniqueId = function()
+ {
+ var id = ((new Date()).getTime() - 1169730000000) + "" + (Math.round(1000*Math.random())+1000);
+ return id;
+ };
+}
+
+/*
+ * Public Utility Methods
+ */
+
+Bandwagon.RPC.Service.prototype.registerLogger = function(logger)
+{
+ this._logger = logger;
+}
+
+Bandwagon.RPC.Service.prototype.registerObserver = function(observer)
+{
+ var id = this.getUniqueId();
+
+ this._observers[id] = observer;
+
+ this._logger.info('Bandwagon.RPC.Service.registerObserver: adding observer, id = ' + id);
+
+ return id;
+}
+
+Bandwagon.RPC.Service.prototype.unregisterObserver = function(observerId)
+{
+ for (var i in this._observers)
+ {
+ if (i == observerId)
+ {
+ this._observers[observerId] = null;
+ this._logger.debug('Bandwagon.RPC.Service.unregisterObserver: removed observer, id = ' + observerId);
+ return;
+ }
+ }
+}
+
+/*
+ * Bandwagon Protocol Methods Below Here
+ */
+
+Bandwagon.RPC.Service.prototype.authenticate = function(login, password, callback)
+{
+ var service = this;
+
+ this._logger.debug("Bandwagon.RPC.Service.authenticate: getting auth token for user '" + login + "'");
+
+ var internalCallback2 = function(event)
+ {
+ if (event.isError())
+ {
+ service._logger.info("Bandwagon.RPC.Service.authenticate: authentication failed");
+ }
+ else
+ {
+ event.authToken = event.getData().attribute("value");
+
+ service._logger.debug("Bandwagon.RPC.Service.authenticate: have an auth token: " + event.authToken);
+
+ service.Bandwagon.Preferences.setPreference(service.Bandwagon.PREF_AUTH_TOKEN, event.authToken);
+ }
+
+ if (callback)
+ {
+ callback(event);
+ }
+ }
+
+ var internalCallback1 = function(event)
+ {
+ if (event && event.authURL)
+ {
+ service._logger.debug("Bandwagon.RPC.Service.authenticate: using authURL = " + event.authURL);
+
+ service.rpcSend(service.Bandwagon.RPC.Constants.BANDWAGON_RPC_EVENT_TYPE_BANDWAGON_RPC_GET_AUTH_DOCUMENT_COMPLETE,
+ internalCallback2,
+ event.authURL,
+ "POST",
+ null,
+ null,
+ {login: login, password: password}
+ );
+ }
+ else if (callback)
+ {
+ callback(event);
+ }
+ }
+
+ this.getServiceDocument(internalCallback1);
+}
+
+Bandwagon.RPC.Service.prototype.getServiceDocument = function(callback)
+{
+ var service = this;
+
+ this._logger.debug("Bandwagon.RPC.Service.getServiceDocument: getting service document for logged in user");
+
+ var internalCallback = function(event)
+ {
+ if (event.isError())
+ {
+ // in the case of unauthorized access, we are given the href to the auth resource
+ event.authURL = "";
+
+ try
+ {
+ event.authURL = event.getData().attribute("href");
+ }
+ catch (e) {}
+
+ if (event.authURL != "")
+ {
+ service._logger.debug("Bandwagon.RPC.Service.getServiceDocument: is error, but have an authURL = " + event.authURL);
+ }
+ else
+ {
+ service._logger.debug("Bandwagon.RPC.Service.getServiceDocument: is error and there is no authURL");
+ }
+ }
+ else
+ {
+ event.serviceDocument = new Bandwagon.Model.ServiceDocument();
+ event.serviceDocument.unserialize(event.getData());
+ }
+
+ if (callback)
+ {
+ callback(event);
+ }
+ }
+
+ this.rpcSend(service.Bandwagon.RPC.Constants.BANDWAGON_RPC_EVENT_TYPE_BANDWAGON_RPC_GET_SERVICE_DOCUMENT_COMPLETE,
+ internalCallback,
+ service.Bandwagon.RPC.Constants.BANDWAGON_RPC_SERVICE_DOCUMENT,
+ "GET",
+ null);
+}
+
+Bandwagon.RPC.Service.prototype.getCollection = function(collection, callback)
+{
+ var service = this;
+
+ this._logger.debug("Bandwagon.RPC.Service.getCollection: getting updates for collection '" + collection.toString() + "' ...");
+
+ collection.status = collection.STATUS_LOADING;
+
+ var data = null;
+
+ var internalCallback = function(event)
+ {
+ if (event.isError())
+ {
+ collection.status = collection.STATUS_LOADERROR;
+ }
+ else
+ {
+ collection.unserialize(event.getData());
+ collection.status = collection.STATUS_LOADED;
+ }
+
+ event.collection = collection;
+
+ if (callback)
+ {
+ callback(event);
+ }
+ }
+
+ this.rpcSend(service.Bandwagon.RPC.Constants.BANDWAGON_RPC_EVENT_TYPE_BANDWAGON_RPC_GET_COLLECTION_COMPLETE,
+ internalCallback,
+ collection.resourceURL,
+ "GET",
+ data);
+}
+
+Bandwagon.RPC.Service.prototype.newCollection = function(collection, callback)
+{
+ var service = this;
+
+ this._logger.debug("Bandwagon.RPC.Service.newCollection: creating new collection '" + collection.toString() + "' ...");
+
+ if (collection.name == "" || service._serviceDocument == null)
+ {
+ if (callback)
+ callback(new this.Bandwagon.RPC.Event());
+
+ return;
+ }
+
+ var data = {
+ name: collection.name,
+ description: collection.description,
+ nickname: collection.getNicknameFromName(),
+ listed: (collection.listed?1:0)
+ };
+
+ var internalCallback = function(event)
+ {
+ if (event.isError())
+ {
+ collection.status = collection.STATUS_LOADERROR;
+ }
+ else
+ {
+ collection.unserialize(event.getData());
+
+ collection.resourceURL = event.getData().@xmlbase.toString();
+ collection.addonsResourceURL = event.getData().@xmlbase.toString() + event.getData().addons.attribute("href").toString();
+
+ service._logger.debug("Bandwagon.RPC.Service.newCollection: create new autopub collection with resourceURL = " + collection.resourceURL);
+
+ collection.status = collection.STATUS_LOADED;
+ }
+
+ event.collection = collection;
+
+ if (callback)
+ {
+ callback(event);
+ }
+ }
+
+ this.rpcSend(service.Bandwagon.RPC.Constants.BANDWAGON_RPC_EVENT_TYPE_BANDWAGON_RPC_NEW_COLLECTION_COMPLETE,
+ internalCallback,
+ service._serviceDocument.collectionListResourceURL,
+ "POST",
+ data);
+}
+
+Bandwagon.RPC.Service.prototype.deleteCollection = function(collection, callback)
+{
+ var service = this;
+
+ this._logger.debug("Bandwagon.RPC.Service.deleteCollection: deleting collection '" + collection.toString() + "' ...");
+
+ if (collection == null)
+ {
+ if (callback)
+ callback(new this.Bandwagon.RPC.Event());
+
+ return;
+ }
+
+ this.rpcSend(service.Bandwagon.RPC.Constants.BANDWAGON_RPC_EVENT_TYPE_BANDWAGON_RPC_DELETE_COLLECTION_COMPLETE,
+ callback,
+ collection.resourceURL,
+ "DELETE",
+ null);
+}
+
+Bandwagon.RPC.Service.prototype.unsubscribeFromCollection = function(collection, callback)
+{
+ var service = this;
+
+ this._logger.debug("Bandwagon.RPC.Service.unsubscribeFromCollection: unsubscribing from collection '" + collection.toString() + "' ...");
+
+ if (collection == null)
+ {
+ if (callback)
+ callback(new this.Bandwagon.RPC.Event());
+
+ return;
+ }
+
+ var data = {
+ "subscribed": "no"
+ };
+
+ this.rpcSend(service.Bandwagon.RPC.Constants.BANDWAGON_RPC_EVENT_TYPE_BANDWAGON_RPC_UNSUBSCRIBE_FROM_COLLECTION_COMPLETE,
+ callback,
+ collection.resourceURL,
+ "PUT",
+ data);
+}
+
+Bandwagon.RPC.Service.prototype.subscribeToCollection = function(collection, callback)
+{
+ var service = this;
+
+ this._logger.debug("Bandwagon.RPC.Service.subscribeToCollection: subscribing to collection '" + collection.toString() + "' ...");
+
+ if (collection == null)
+ {
+ if (callback)
+ callback(new this.Bandwagon.RPC.Event());
+
+ return;
+ }
+
+ var data = {
+ "subscribed": "yes"
+ };
+
+ this.rpcSend(service.Bandwagon.RPC.Constants.BANDWAGON_RPC_EVENT_TYPE_BANDWAGON_RPC_SUBSCRIBE_TO_COLLECTION_COMPLETE,
+ callback,
+ collection.resourceURL,
+ "PUT",
+ data);
+}
+
+Bandwagon.RPC.Service.prototype.updateCollectionDetails = function(collection, callback)
+{
+ var service = this;
+
+ this._logger.debug("Bandwagon.RPC.Service.updateCollectionDetails: updating collection details for '" + collection.toString() + "' ...");
+
+ if (collection == null)
+ {
+ if (callback)
+ callback(new this.Bandwagon.RPC.Event());
+
+ return;
+ }
+
+ collection.status = collection.STATUS_LOADING;
+
+ var data = {
+ "name": collection.name,
+ "description": collection.description,
+ "listed": (collection.listed?"1":"0"),
+ "subscribed": (collection.subscribed?"yes":"no")
+ };
+
+ var internalCallback = function(event)
+ {
+ if (event.isError())
+ {
+ collection.status = collection.STATUS_LOADERROR;
+ }
+ else
+ {
+ collection.unserialize(event.getData());
+ collection.status = collection.STATUS_LOADED;
+ }
+
+ event.collection = collection;
+
+ if (callback)
+ {
+ callback(event);
+ }
+ }
+
+ this.rpcSend(service.Bandwagon.RPC.Constants.BANDWAGON_RPC_EVENT_TYPE_BANDWAGON_RPC_UPDATE_COLLECTION_COMPLETE,
+ internalCallback,
+ collection.resourceURL,
+ "PUT",
+ data);
+}
+
+Bandwagon.RPC.Service.prototype.removeAddonFromCollection = function(guid, collection, callback)
+{
+ var service = this;
+
+ Bandwagon.Logger.debug("Bandwagon.RPC.Service.removeAddonFromCollection: extension.guid = '" + guid + "', collection = '" + collection.resourceURL);
+
+ var internalCallback = function(event)
+ {
+ // don't need to do anything here
+ if (callback)
+ callback(event);
+ }
+
+ this.rpcSend(service.Bandwagon.RPC.Constants.BANDWAGON_RPC_EVENT_TYPE_BANDWAGON_RPC_REMOVE_ADDON_FROM_COLLECTION_COMPLETE,
+ internalCallback,
+ collection.addonsResourceURL + guid,
+ "DELETE",
+ null);
+}
+
+Bandwagon.RPC.Service.prototype.publishToCollection = function(extension, collection, personalNote, callback)
+{
+ var service = this;
+
+ Bandwagon.Logger.debug("Bandwagon.RPC.Service.publishToCollection: extension.guid = '" + extension.guid + "', extension.name = '" + extension.name + "', collection = '" + collection.resourceURL + "', personalNote = '" + personalNote + "'");
+
+ var data = {
+ "guid": extension.guid,
+ "comments": personalNote
+ };
+
+ var internalCallback = function(event)
+ {
+ // don't need to do anything here
+ if (callback)
+ callback(event);
+ }
+
+ this.rpcSend(service.Bandwagon.RPC.Constants.BANDWAGON_RPC_EVENT_TYPE_BANDWAGON_RPC_PUBLISH_COMPLETE,
+ internalCallback,
+ collection.addonsResourceURL,
+ "POST",
+ data);
+}
+
+Bandwagon.RPC.Service.prototype.shareToEmail = function(extension, emailAddress, personalNote, callback)
+{
+ var service = this;
+
+ Bandwagon.Logger.debug("Bandwagon.RPC.Service.shareToEmail: extension.guid = '" + extension.guid + "', extension.name = '" + extension.name + "', emailAddress = '" + emailAddress + "', personalNote = '" + personalNote + "'");
+
+ if (!extension.guid || extension.guid == "" || !emailAddress || emailAddress == "" || service._serviceDocument == null)
+ {
+ if (callback)
+ callback(new this.Bandwagon.RPC.Event());
+
+ return;
+ }
+
+ personalNote = personalNote.replace("\n", "\r", "gi");
+
+ var data = {
+ "guid": extension.guid,
+ "to": emailAddress,
+ "message": personalNote
+ };
+
+ var internalCallback = function(event)
+ {
+ // don't need to do anything here
+ if (callback)
+ callback(event);
+ }
+
+ this.rpcSend(service.Bandwagon.RPC.Constants.BANDWAGON_RPC_EVENT_TYPE_BANDWAGON_RPC_SHARE_TO_EMAIL_COMPLETE,
+ internalCallback,
+ service._serviceDocument.emailResourceURL,
+ "POST",
+ data);
+}
+
+
diff --git a/bandwagon/content/scripts/util.js b/bandwagon/content/scripts/util.js
new file mode 100644
index 0000000..58b41f8
--- /dev/null
+++ b/bandwagon/content/scripts/util.js
@@ -0,0 +1,424 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is bandwagon.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s): David McNamara
+ * Brian King
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+Bandwagon.Util = new function() {}
+
+Bandwagon.Util._extensionManager = null;
+Bandwagon.Util._rdfService = null;
+Bandwagon.Util._extensionsDataSource == null;
+
+Bandwagon.Util.getMainWindow = function()
+{
+ return window.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
+ .getInterface(Components.interfaces.nsIWebNavigation)
+ .QueryInterface(Components.interfaces.nsIDocShellTreeItem)
+ .rootTreeItem
+ .QueryInterface(Components.interfaces.nsIInterfaceRequestor)
+ .getInterface(Components.interfaces.nsIDOMWindow);
+}
+
+Bandwagon.Util.getExtensionVersion = function(emid)
+{
+ var bits = {major: 1, minor: 0, revision: 0, increment: 0};
+
+ var em = Components.classes["@mozilla.org/extensions/manager;1"]
+ .getService(Components.interfaces.nsIExtensionManager);
+
+ var addon = em.getItemForID(emid);
+
+ var versionString = addon.version;
+
+ return Bandwagon.Util.splitVersionString(versionString);
+}
+
+Bandwagon.Util.splitVersionString = function(versionString)
+{
+ var versionBits = versionString.split('.');
+
+ if (versionBits[0])
+ bits.major = parseInt(versionBits[0]);
+
+ if (versionBits[1])
+ bits.minor = parseInt(versionBits[1]);
+
+ if (versionBits[2])
+ bits.revision = parseInt(versionBits[2]);
+
+ if (versionBits[3])
+ bits.increment = parseInt(versionBits[3]);
+
+ return versionBits;
+}
+
+Bandwagon.Util.getHostEnvironmentInfo = function()
+{
+ // Returns "WINNT" on Windows Vista, XP, 2000, and NT systems;
+ // "Linux" on GNU/Linux; and "Darwin" on Mac OS X.
+ var osString = Components.classes["@mozilla.org/xre/app-info;1"]
+ .getService(Components.interfaces.nsIXULRuntime).OS;
+
+ var info = Components.classes["@mozilla.org/xre/app-info;1"]
+ .getService(Components.interfaces.nsIXULAppInfo);
+ // Get the name of the application running us
+ info.name; // Returns "Firefox" for Firefox
+ info.version; // Returns "2.0.0.1" for Firefox version 2.0.0.1
+
+ var hostEnvInfo =
+ {
+ os: osString,
+ appName: info.name,
+ appVersion: info.version
+ }
+
+ return hostEnvInfo;
+}
+
+
+Bandwagon.Util.compareVersions = function(versionA, versionB)
+{
+ var versionChecker = Components.classes["@mozilla.org/xpcom/version-comparator;1"]
+ .getService(Components.interfaces.nsIVersionComparator);
+
+ var result = versionChecker.compare(versionA, versionB);
+
+ //Bandwagon.Logger.debug("compared version '" + versionA + "' with version '" + versionB + "' and got: " + result);
+
+ return result;
+}
+
+Bandwagon.Util.dumpObject = function(obj, name, indent, depth)
+{
+ Bandwagon.Logger.debug(Bandwagon.Util._dumpObject(obj, name, indent, depth));
+}
+Bandwagon.Util._dumpObject = function(obj, name, indent, depth)
+{
+ if (!name) name = "object";
+ if (!indent) indent = " ";
+
+ if (depth > 10)
+ {
+ return indent + name + ": <Maximum Depth Reached>\n";
+ }
+
+ if (typeof obj == "object")
+ {
+ var child = null;
+ var output = indent + name + "\n";
+ indent += "\t";
+
+ for (var item in obj)
+ {
+ try
+ {
+ child = obj[item];
+ }
+ catch (e)
+ {
+ child = "<Unable to Evaluate>";
+ }
+
+ if (typeof child == "object")
+ {
+ output += Bandwagon.Util._dumpObject(child, item, indent, depth + 1);
+ }
+ else
+ {
+ output += indent + item + ": " + child + "\n";
+ }
+ }
+ return output;
+ }
+ else
+ {
+ return obj;
+ }
+}
+
+Bandwagon.Util.lengthOfHash = function(hash)
+{
+ var length = 0;
+
+ for (var object in hash)
+ {
+ length++;
+ }
+
+ return length;
+}
+
+Bandwagon.Util.INTERVAL_MINUTES = 1;
+Bandwagon.Util.INTERVAL_HOURS = 2;
+Bandwagon.Util.INTERVAL_DAYS = 3;
+
+Bandwagon.Util.intervalMillisecondsToUnits = function(ms)
+{
+ if (ms % (1000*60*60*24) == 0)
+ {
+ return {units: Bandwagon.Util.INTERVAL_DAYS, interval: ms/(1000*60*60*24)};
+ }
+ else if (ms % (1000*60*60) == 0)
+ {
+ return {units: Bandwagon.Util.INTERVAL_HOURS, interval: ms/(1000*60*60)};
+ }
+ else
+ {
+ return {units: Bandwagon.Util.INTERVAL_MINUTES, interval: ms/(1000*60)};
+ }
+}
+
+Bandwagon.Util.intervalUnitsToMilliseconds = function(interval, units)
+{
+ var ms = 0;
+
+ switch (units)
+ {
+ case Bandwagon.Util.INTERVAL_MINUTES:
+ ms = 1000 * 60 * interval;
+ break;
+ case Bandwagon.Util.INTERVAL_HOURS:
+ ms = 1000 * 60 * 60 * interval;
+ break;
+ case Bandwagon.Util.INTERVAL_DAYS:
+ ms = 1000 * 60 * 60 * 24 * interval;
+ break;
+ }
+
+ //Bandwagon.Logger.debug("converted interval '" + interval + " of " + units + "' into " + ms + "ms");
+
+ return ms;
+}
+
+Bandwagon.Util.getCookie = function(host, name)
+{
+ var cookieManager = Components.classes["@mozilla.org/cookiemanager;1"]
+ .getService(Components.interfaces.nsICookieManager);
+
+ var iter = cookieManager.enumerator;
+
+ while (iter.hasMoreElements())
+ {
+ var cookie = iter.getNext();
+
+ if (cookie instanceof Components.interfaces.nsICookie)
+ {
+ if (cookie.host == host && cookie.name == name)
+ return cookie.value;
+ }
+ }
+
+ return null;
+}
+
+Bandwagon.Util._initExtensionServices = function()
+{
+ if (Bandwagon.Util._extensionManager == null)
+ {
+ this._extensionManager = Components.classes["@mozilla.org/extensions/manager;1"]
+ .getService(Components.interfaces.nsIExtensionManager);
+ }
+
+ if (Bandwagon.Util._rdfService == null)
+ {
+ this._rdfService = Components.classes["@mozilla.org/rdf/rdf-service;1"]
+ .getService(Components.interfaces.nsIRDFService);
+ }
+
+ var getURLSpecFromFile = function(file)
+ {
+ var ioServ = Components.classes["@mozilla.org/network/io-service;1"]
+ .getService(Components.interfaces.nsIIOService);
+ var fph = ioServ.getProtocolHandler("file")
+ .QueryInterface(Components.interfaces.nsIFileProtocolHandler);
+ return fph.getURLSpecFromFile(file);
+ }
+
+ var getDir = function(key, pathArray)
+ {
+ var fileLocator = Components.classes["@mozilla.org/file/directory_service;1"]
+ .getService(Components.interfaces.nsIProperties);
+ var dir = fileLocator.get(key, Components.interfaces.nsILocalFile);
+ for (var i=0; i<pathArray.length; ++i)
+ {
+ dir.append(pathArray[i]);
+ }
+ dir.followLinks = false;
+ return dir;
+ }
+
+ var getFile = function(key, pathArray)
+ {
+ var file = getDir(key, pathArray.slice(0, -1));
+ file.append(pathArray[pathArray.length - 1]);
+ return file;
+ }
+
+ if (Bandwagon.Util._extensionsDataSource == null)
+ {
+ Bandwagon.Util._extensionsDataSource = this._rdfService.GetDataSourceBlocking(getURLSpecFromFile(getFile("ProfD", ["extensions.rdf"])));
+ }
+}
+
+Bandwagon.Util.getInstalledExtensions = function()
+{
+ Bandwagon.Util._initExtensionServices();
+
+ var items = this._extensionManager.getItemList(Components.interfaces.nsIUpdateItem.TYPE_ANY, { });
+
+ return items;
+}
+
+Bandwagon.Util.getExtensionProperty = function(id, propertyName)
+{
+ Bandwagon.Util._initExtensionServices();
+
+ var value;
+
+ try
+ {
+ var target = Bandwagon.Util._extensionsDataSource.GetTarget
+ (
+ this._rdfService.GetResource("urn:mozilla:item:" + id),
+ this._rdfService.GetResource("http://www.mozilla.org/2004/em-rdf#" + propertyName),
+ true
+ );
+
+ var stringData = function(literalOrResource)
+ {
+ if (literalOrResource instanceof Components.interfaces.nsIRDFLiteral)
+ return literalOrResource.Value;
+ if (literalOrResource instanceof Components.interfaces.nsIRDFResource)
+ return literalOrResource.Value;
+ return undefined;
+ }
+
+ value = stringData(target);
+ }
+ catch (e)
+ {
+ Bandwagon.Logger.error("Error getting extension property: " + e);
+ return "";
+ }
+
+ //Bandwagon.Logger.debug("Extension '" + id + "' has property '" + propertyName + "=" + value + "'");
+
+ return value === undefined ? "" : value;
+}
+
+Bandwagon.Util.ISO8601toDate = function(dString)
+{
+ var x = new Date();
+
+ var regexp = /(\d\d\d\d)(-)?(\d\d)(-)?(\d\d)(T)?(\d\d)(:)?(\d\d)(:)?(\d\d)(\.\d+)?(Z|([+-])(\d\d)(:)?(\d\d))/;
+
+ if (dString.toString().match(new RegExp(regexp))) {
+ var d = dString.match(new RegExp(regexp));
+ var offset = 0;
+
+ x.setUTCDate(1);
+ x.setUTCFullYear(parseInt(d[1],10));
+ x.setUTCMonth(parseInt(d[3],10) - 1);
+ x.setUTCDate(parseInt(d[5],10));
+ x.setUTCHours(parseInt(d[7],10));
+ x.setUTCMinutes(parseInt(d[9],10));
+ x.setUTCSeconds(parseInt(d[11],10));
+ if (d[12])
+ x.setUTCMilliseconds(parseFloat(d[12]) * 1000);
+ else
+ x.setUTCMilliseconds(0);
+ if (d[13] != 'Z') {
+ offset = (d[15] * 60) + parseInt(d[17],10);
+ offset *= ((d[14] == '-') ? -1 : 1);
+ x.setTime(x.getTime() - offset * 60 * 1000);
+ }
+ }
+ else
+ {
+ x.setTime(Date.parse(dString));
+ }
+
+ return x;
+};
+
+Bandwagon.Util.getBrowserLocale = function()
+{
+ var gmyextensionBundle = Components.classes["@mozilla.org/intl/stringbundle;1"].getService(Components.interfaces.nsIStringBundleService);
+ var bundle = gmyextensionBundle.createBundle("chrome://global/locale/intl.properties");
+
+ return bundle.GetStringFromName("general.useragent.locale");
+};
+
+Bandwagon.Util.encodeURL = function(str)
+{
+ str = encodeURIComponent(str);
+
+ //str = str.replace(/'/g, "%27");
+
+ return str;
+}
+
+Bandwagon.Util.getUserFacingOSName = function(str)
+{
+ if (str.match(/.*Darwin.*/i))
+ {
+ return "Mac OS X";
+ }
+ else if (str.match(/.*Linux.*/i))
+ {
+ return "Linux";
+ }
+ else if (str.match(/.*BSD.*/i))
+ {
+ return "BSD";
+ }
+ else if (str.match(/.*sunos.*/i))
+ {
+ return "Solaris";
+ }
+ else if (str.match(/.*solaris.*/i))
+ {
+ return "Solaris";
+ }
+ else if (str.match(/.*Win.*/i))
+ {
+ return "Windows";
+ }
+ else
+ {
+ return str;
+ }
+}
+
diff --git a/bandwagon/content/ui/bindings/bandwagon.css b/bandwagon/content/ui/bindings/bandwagon.css
new file mode 100644
index 0000000..7bb9f18
--- /dev/null
+++ b/bandwagon/content/ui/bindings/bandwagon.css
@@ -0,0 +1,16 @@
+bandwagonAddon {
+ -moz-binding: url("chrome://bandwagon/content/ui/bindings/bandwagon.xml#bandwagon-addon");
+}
+
+bandwagonAddonExpanded {
+ -moz-binding: url("chrome://bandwagon/content/ui/bindings/bandwagon.xml#bandwagon-addon-expanded");
+}
+
+bandwagonCollection {
+ -moz-binding: url("chrome://bandwagon/content/ui/bindings/bandwagon.xml#bandwagon-collection");
+}
+
+bandwagonPublishButton {
+ -moz-binding: url("chrome://bandwagon/content/ui/bindings/bandwagon.xml#bandwagon-publish-button");
+}
+
diff --git a/bandwagon/content/ui/bindings/bandwagon.xml b/bandwagon/content/ui/bindings/bandwagon.xml
new file mode 100644
index 0000000..3a3a628
--- /dev/null
+++ b/bandwagon/content/ui/bindings/bandwagon.xml
@@ -0,0 +1,766 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- ***** BEGIN LICENSE BLOCK *****
+ - Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ -
+ - The contents of this file are subject to the Mozilla Public License Version
+ - 1.1 (the "License"); you may not use this file except in compliance with
+ - the License. You may obtain a copy of the License at
+ - http://www.mozilla.org/MPL/
+ -
+ - Software distributed under the License is distributed on an "AS IS" basis,
+ - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ - for the specific language governing rights and limitations under the
+ - License.
+ -
+ - The Original Code is bandwagon.
+ -
+ - The Initial Developer of the Original Code is
+ - Mozilla Corporation.
+ - Portions created by the Initial Developer are Copyright (C) 2008
+ - the Initial Developer. All Rights Reserved.
+ -
+ - Contributor(s): David McNamara
+ - Brian King
+ -
+ - Alternatively, the contents of this file may be used under the terms of
+ - either the GNU General Public License Version 2 or later (the "GPL"), or
+ - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ - in which case the provisions of the GPL or the LGPL are applicable instead
+ - of those above. If you wish to allow use of your version of this file only
+ - under the terms of either the GPL or the LGPL, and not to allow others to
+ - use your version of this file under the terms of the MPL, indicate your
+ - decision by deleting the provisions above and replace them with the notice
+ - and other provisions required by the GPL or the LGPL. If you do not delete
+ - the provisions above, a recipient may use your version of this file under
+ - the terms of any one of the MPL, the GPL or the LGPL.
+ -
+ - ***** END LICENSE BLOCK ***** -->
+
+<!DOCTYPE bindings SYSTEM "chrome://bandwagon/locale/extensionsOverlay.dtd">
+
+<bindings id="bandwagon-bindings"
+ xmlns="http://www.mozilla.org/xbl"
+ xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+ xmlns:xbl="http://www.mozilla.org/xbl"
+ xmlns:html="http://www.w3.org/1999/xhtml">
+
+ <binding id="bandwagon-collection" extends="chrome://global/content/bindings/richlistbox.xml#richlistitem">
+
+ <resources>
+ <stylesheet src="chrome://bandwagon/skin/extensionsOverlay.css"/>
+ <stylesheet src="chrome://bandwagon/skin/extensionsOverlayIcons.css"/>
+ </resources>
+
+ <content orient="vertical">
+ <xul:vbox flex="1"> <!-- Needed to constrain the list so that it does not horizontally scroll - Bug 488403-->
+ <xul:hbox align="center">
+ <xul:image anonid="star" src="chrome://bandwagon/skin/images/star.png" style="width: 1em; height: 1em;" collapsed="true"/>
+ <xul:label anonid="name" crop="center" flex="1"/>
+ <xul:label anonid="unread" collapsed="true"/>
+ <xul:image anonid="localautopub" class="autopubimg" collapsed="true"/>
+ </xul:hbox>
+ </xul:vbox>
+ </content>
+
+ <implementation>
+ <field name="collection"/>
+ <field name="controller"/>
+
+ <constructor>
+ <![CDATA[
+ if (this.collection)
+ this.setCollection(this.collection);
+
+ setTimeout(this.controller.bindingsReady, 100);
+
+ if (this.styleWithSeparator)
+ this.setAttribute("styleWithSeparator", "true")
+ ]]>
+ </constructor>
+
+ <property name="name"
+ onget="return document.getAnonymousElementByAttribute(this, 'anonid', 'name').value"
+ onset="document.getAnonymousElementByAttribute(this, 'anonid', 'name').value = val; this.setAttribute('label', val);"
+ />
+
+ <property name="url"
+ onget="return this.getAttribute('value')"
+ onset="this.setAttribute('value', val);"
+ />
+
+ <property name="preview"
+ onget="return this.getAttribute('preview')"
+ onset="this.setAttribute('preview', val);"
+ />
+
+ <property name="writable"
+ onget="return !document.getAnonymousElementByAttribute(this, 'anonid', 'star').collapsed;"
+ onset="document.getAnonymousElementByAttribute(this, 'anonid', 'star').collapsed = !val;"
+ />
+
+ <property name="localautopub"
+ onget="return !document.getAnonymousElementByAttribute(this, 'anonid', 'localautopub').collapsed;"
+ onset="document.getAnonymousElementByAttribute(this, 'anonid', 'localautopub').collapsed = !val;"
+ />
+
+ <property name="unread"
+ onget="return !document.getAnonymousElementByAttribute(this, 'anonid', 'unread').value"
+ onset="document.getAnonymousElementByAttribute(this, 'anonid', 'unread').value = val; document.getAnonymousElementByAttribute(this, 'anonid', 'unread').collapsed = (val == 0);"
+ />
+
+ <property name="type"
+ onget="return this.getAttribute('type')"
+ onset="this.setAttribute('type', val);"
+ />
+
+ <method name="setCollection">
+ <parameter name="collection"/>
+ <body>
+ <![CDATA[
+ this.collection = collection;
+ this.name = (collection.name && collection.name !=""?collection.name:collection.resourceURL);
+ this.url = collection.resourceURL;
+ this.preview = collection.preview;
+ this.writable = collection.writable;
+ this.unread = collection.getUnreadAddons().length;
+ this.type = collection.type;
+ this.localautopub = collection.isLocalAutoPublisher();
+ ]]>
+ </body>
+ </method>
+
+ </implementation>
+ </binding>
+
+
+ <binding id="bandwagon-addon" extends="chrome://global/content/bindings/richlistbox.xml#richlistitem">
+
+ <resources>
+ <stylesheet src="chrome://bandwagon/skin/extensionsOverlay.css"/>
+ <stylesheet src="chrome://bandwagon/skin/extensionsOverlayIcons.css"/>
+ </resources>
+
+ <content>
+ <xul:stringbundle src="chrome://bandwagon/locale/bandwagonAddon.properties"
+ anonid="stringbundle"/>
+
+ <xul:hbox flex="1">
+ <xul:vbox class="addonIcon">
+ <xul:image anonid="icon" class="icon"/>
+ </xul:vbox>
+ <xul:vbox flex="1" class="addonTextBox">
+ <xul:hbox flex="1">
+ <xul:vbox flex="1">
+ <xul:hbox flex="1">
+ <xul:label anonid="name" class="name"/>
+ <xul:spacer flex="1"/>
+ <xul:hbox align="center">
+ <xul:image anonid="commenticon" class="comment-icon"/>
+ <xul:label anonid="dateadded"/>
+ </xul:hbox>
+ </xul:hbox>
+ <xul:label anonid="summary" crop="end"/>
+ </xul:vbox>
+ </xul:hbox>
+ </xul:vbox>
+ </xul:hbox>
+ </content>
+
+ <implementation>
+ <field name="addon"/>
+ <field name="_stringBundle">document.getAnonymousElementByAttribute(this, "anonid", "stringbundle");</field>
+
+ <constructor>
+ <![CDATA[
+ if (this.addon)
+ this.setAddon(this.addon);
+ ]]>
+ </constructor>
+
+ <property name="name"
+ onget="return document.getAnonymousElementByAttribute(this, 'anonid', 'name').value"
+ onset="document.getAnonymousElementByAttribute(this, 'anonid', 'name').value = val; this.setAttribute('label', val);"
+ />
+
+ <property name="guid"
+ onget="return this.getAttribute('value')"
+ onset="this.setAttribute('value', val);"
+ />
+
+ <property name="summary"
+ onget="return (document.getAnonymousElementByAttribute(this, 'anonid', 'summary')?document.getAnonymousElementByAttribute(this, 'anonid', 'summary').value:'')"
+ onset="if (document.getAnonymousElementByAttribute(this, 'anonid', 'summary')) document.getAnonymousElementByAttribute(this, 'anonid', 'summary').value = val"
+ />
+
+ <property name="iconURL"
+ onget="return document.getAnonymousElementByAttribute(this, 'anonid', 'icon').src"
+ onset="document.getAnonymousElementByAttribute(this, 'anonid', 'icon').src = val"
+ />
+
+ <property name="description"
+ onget="return (document.getAnonymousElementByAttribute(this, 'anonid', 'description')?document.getAnonymousElementByAttribute(this, 'anonid', 'description').firstChild.nodeValue:'')"
+ onset="if (document.getAnonymousElementByAttribute(this, 'anonid', 'description')) document.getAnonymousElementByAttribute(this, 'anonid', 'description').firstChild.nodeValue = val"
+ />
+
+ <property name="thumbnailURL"
+ onget="return (document.getAnonymousElementByAttribute(this, 'class', 'thumbnail')?document.getAnonymousElementByAttribute(this, 'class', 'thumbnail').src:'')">
+ <setter>
+ <![CDATA[
+ if (this._thumbnail)
+ {
+ var thumbnailURL = (val!=null&&val!=""?val:this._thumbnailMissingPlaceholder);
+
+ var self = this;
+
+ var image = new Image();
+ image.onload = function() { if (self._imageLoaded) { self._imageLoaded(image); } };
+ image.src = thumbnailURL;
+ }
+ ]]>
+ </setter>
+ </property>
+
+ <property name="authors"
+ onget="return (document.getAnonymousElementByAttribute(this, 'anonid', 'author')?document.getAnonymousElementByAttribute(this, 'anonid', 'author').value:'')">
+ <setter>
+ <![CDATA[
+ if (document.getAnonymousElementByAttribute(this, 'anonid', 'authors'))
+ {
+ var authors = "";
+
+ if (!val || val.length == 0)
+ {
+ authors = "?";
+ }
+ else
+ {
+ for each (var item in val)
+ {
+ authors += item + ", ";
+ }
+
+ if (authors.substring(authors.length-2) == ", ")
+ {
+ authors = authors.substring(0, authors.length-2);
+ }
+ }
+
+ document.getAnonymousElementByAttribute(this, 'anonid', 'authors').value = this._stringBundle.getFormattedString('bandwagon.addon.author', [authors]);
+ }
+ ]]>
+ </setter>
+ </property>
+
+ <property name="read"
+ onget="return this.getAttribute('read')"
+ onset="this.setAttribute('read', val);"
+ />
+
+ <property name="dateAdded" onget="return document.getAnonymousElementByAttribute(this, 'anonid', 'dateadded').value">
+ <setter>
+ <![CDATA[
+ // val is a js date
+ // make it a pretty relative date e.g. "2 days ago"
+
+ var now = new Date();
+ var diff = (now.getTime() - val.getTime()) / 1000;
+
+ var sbString = "";
+ var sbVal = 0;
+
+ if (diff < 60)
+ {
+ sbString = "bandwagon.addon.added.justnow";
+ }
+ else if (diff < 60 * 60)
+ {
+ sbString = "bandwagon.addon.added.minute";
+ sbVal = Math.ceil(diff/60);
+ }
+ else if (diff < 60 * 60 * 24)
+ {
+ sbString = "bandwagon.addon.added.hour";
+ sbVal = Math.floor(diff/60/60);
+ }
+ else if (diff < 60 * 60 * 24 * 7)
+ {
+ sbString = "bandwagon.addon.added.day";
+ sbVal = Math.floor(diff/60/60/24);
+ }
+ else if (diff < 60 * 60 * 24 * 30)
+ {
+ sbString = "bandwagon.addon.added.week";
+ sbVal = Math.floor(diff/60/60/24/7);
+ }
+ else if (diff < 60 * 60 * 24 * 365)
+ {
+ sbString = "bandwagon.addon.added.month";
+ sbVal = Math.floor(diff/60/60/24/30);
+ }
+ else
+ {
+ sbString = "bandwagon.addon.added.year";
+ sbVal = Math.floor(diff/60/60/24/365);
+ }
+
+ Components.utils.import("resource://gre/modules/PluralForm.jsm");
+ let [get, numForms] = PluralForm.makeGetter(this._stringBundle.getString("bandwagon.addon.pluralRule"));
+ var datestr = get(sbVal, this._stringBundle.getFormattedString(sbString, [sbVal]));
+
+ document.getAnonymousElementByAttribute(this, 'anonid', 'dateadded').value = datestr;
+ ]]>
+ </setter>
+ </property>
+
+ <property name="comment"
+ onget="return (document.getAnonymousElementByAttribute(this, 'anonid', 'commentdesc')?document.getAnonymousElementByAttribute(this, 'anonid', 'commentdesc').textContent : '')"
+ >
+ <setter>
+ <![CDATA[
+ if (document.getAnonymousElementByAttribute(this, 'anonid', 'commentdesc'))
+ document.getAnonymousElementByAttribute(this, 'anonid', 'commentdesc').textContent = this._stringBundle.getFormattedString('bandwagon.addon.comment.description', [val.comment]);
+ if (document.getAnonymousElementByAttribute(this, 'anonid', 'commentauthor'))
+ document.getAnonymousElementByAttribute(this, 'anonid', 'commentauthor').value = this._stringBundle.getFormattedString('bandwagon.addon.comment.author', [val.author]);
+ ]]>
+ </setter>
+ </property>
+
+ <property name="addedBy"
+ onget="return (document.getAnonymousElementByAttribute(this, 'anonid', 'addedby')?document.getAnonymousElementByAttribute(this, 'anonid', 'addedby').value:'')"
+ >
+ <setter>
+ <![CDATA[
+ if (document.getAnonymousElementByAttribute(this, 'anonid', 'addedby')) document.getAnonymousElementByAttribute(this, 'anonid', 'addedby').value = this._stringBundle.getFormattedString('bandwagon.addon.addedby', [val]);
+ ]]>
+ </setter>
+ </property>
+
+ <method name="setAddon">
+ <parameter name="addon"/>
+ <body>
+ <![CDATA[
+ this.addon = addon;
+ this.name = addon.name;
+ this.guid = addon.guid;
+ this.summary = addon.summary;
+ this.description = addon.summary; // Use summary and not description
+ this.iconURL = addon.icon;
+ this.thumbnailURL = addon.thumbnail;
+ this.authors = addon.authors;
+ this.dateAdded = addon.dateAdded;
+ this.read = addon.read;
+
+ if (addon.comments.length > 0)
+ {
+ if (addon.comments[0].comment.match(/\w/))
+ {
+ this.comment = addon.comments[0];
+ }
+
+ this.addedBy = addon.comments[0].author;
+ if (addon.comments[0].comment == "") // it seems each addon will have an empty comment if none was made
+ {
+ document.getAnonymousElementByAttribute(this, 'anonid', 'commenticon').setAttribute("collapsed", true);
+ if (document.getAnonymousElementByAttribute(this, 'anonid', 'commentbox')) // expanded only
+ document.getAnonymousElementByAttribute(this, 'anonid', 'commentbox').setAttribute("collapsed", true);
+ }
+ }
+ else
+ {
+ document.getAnonymousElementByAttribute(this, 'anonid', 'commenticon').setAttribute("collapsed", true);
+ if (document.getAnonymousElementByAttribute(this, 'anonid', 'commentbox')) // expanded only
+ document.getAnonymousElementByAttribute(this, 'anonid', 'commentbox').setAttribute("collapsed", true);
+ }
+
+ this.invalidateCompatibilityCheck();
+ this.invalidatePublishButton();
+ ]]>
+ </body>
+ </method>
+
+ <method name="invalidateCompatibilityCheck">
+ <body>
+ <![CDATA[
+ if (this.addon)
+ {
+ var canInstall = this.addon.canInstall(Bandwagon.Util.getHostEnvironmentInfo());
+ var requiredVersion = Bandwagon.Util.getUserFacingOSName(canInstall.requiredVersion);
+
+ this.showVersionHelper(canInstall.type, requiredVersion);
+ }
+ ]]>
+ </body>
+ </method>
+
+ <method name="invalidatePublishButton">
+ <body>
+ <![CDATA[
+ var publishButton = document.getAnonymousElementByAttribute(this, 'anonid', 'publish');
+
+ if (publishButton)
+ {
+ publishButton.emailAddresses = Bandwagon.Controller.ExtensionsOverlay._getEmailAddresses();
+ publishButton.writableCollections = Bandwagon.Controller.ExtensionsOverlay._getWritableCollections();
+ publishButton.invalidate();
+ }
+ ]]>
+ </body>
+ </method>
+
+ <method name="showVersionHelper">
+ <parameter name="type"/>
+ <parameter name="version"/>
+ <body>
+ <![CDATA[
+ if (document.getAnonymousElementByAttribute(this, 'anonid', 'addtofirefox')
+ && document.getAnonymousElementByAttribute(this, 'anonid', 'addtofirefoxwarning'))
+ {
+ var container = document.getAnonymousElementByAttribute(this, 'anonid', 'addtofirefoxwarning');
+
+ while (container.hasChildNodes())
+ {
+ container.removeChild(container.firstChild);
+ }
+
+ if (type == Bandwagon.Model.Addon.INSTALL_YES)
+ {
+ document.getAnonymousElementByAttribute(this, 'anonid', 'addtofirefox').disabled = false;
+ document.getAnonymousElementByAttribute(this, 'anonid', 'addtofirefoxwarning').collapsed = true;
+ }
+ else
+ {
+ if (type == Bandwagon.Model.Addon.INSTALL_NO_IS_EXPERIMENTAL)
+ {
+ var msg;
+
+ try
+ {
+ msg = this._stringBundle.getString("bandwagon.addon.isexperimental");
+ }
+ catch (e)
+ {
+ msg = this._stringBundle.getString("bandwagon.addon.olderversionsoffirefox");
+ }
+
+ document.getAnonymousElementByAttribute(this, 'anonid', 'addtofirefoxwarning').appendChild(
+ document.createTextNode(msg));
+ }
+ else if (type == Bandwagon.Model.Addon.INSTALL_NO_ADDON_IS_FOR_OLDER_VERSION)
+ {
+ document.getAnonymousElementByAttribute(this, 'anonid', 'addtofirefoxwarning').appendChild(
+ document.createTextNode(this._stringBundle.getString("bandwagon.addon.olderversionsoffirefox")));
+ }
+ else if (type == Bandwagon.Model.Addon.INSTALL_NO_UPGRADE_TO_USE_THIS_VERSION)
+ {
+ var atffwl = document.createElementNS("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul", "xul:label");
+ atffwl.className = "text-link";
+ atffwl.setAttribute("value", this._stringBundle.getFormattedString("bandwagon.addon.upgradetofirefoxn1", [version]));
+ atffwl.addEventListener("click", function() { Bandwagon.Controller.CollectionsPane.doUpgradeToFirefoxN(version); }, true);
+ document.getAnonymousElementByAttribute(this, 'anonid', 'addtofirefoxwarning').appendChild(atffwl);
+
+ document.getAnonymousElementByAttribute(this, 'anonid', 'addtofirefoxwarning').appendChild(
+ document.createTextNode(this._stringBundle.getString("bandwagon.addon.upgradetofirefoxn2")));
+ }
+ else if (type == Bandwagon.Model.Addon.INSTALL_NO_MUST_DOWNLOAD_BETA)
+ {
+ document.getAnonymousElementByAttribute(this, 'anonid', 'addtofirefoxwarning').appendChild(
+ document.createTextNode(this._stringBundle.getFormattedString("bandwagon.addon.requiresfirefoxbeta1", [version])));
+
+ var atffwl = document.createElementNS("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul", "xul:label");
+ atffwl.className = "text-link";
+ atffwl.setAttribute("value", this._stringBundle.getFormattedString("bandwagon.addon.requiresfirefoxbeta2", [version]));
+ atffwl.addEventListener("click", function() { Bandwagon.Controller.CollectionsPane.doDownloadFirefoxNBeta(version); }, true);
+
+ document.getAnonymousElementByAttribute(this, 'anonid', 'addtofirefoxwarning').appendChild(atffwl);
+ }
+ else if (type == Bandwagon.Model.Addon.INSTALL_NO_NOT_COMPATIBLE_OS)
+ {
+ document.getAnonymousElementByAttribute(this, 'anonid', 'addtofirefoxwarning').appendChild(
+ document.createTextNode(this._stringBundle.getFormattedString("bandwagon.addon.notcompatible", [version])));
+ }
+
+ document.getAnonymousElementByAttribute(this, 'anonid', 'addtofirefoxwarning').collapsed = false;
+
+ var isExtensionsCheckCompatibility = Bandwagon.Preferences.getGlobalPreference("extensions.checkCompatibility", true);
+ var isAllowIncompatibleInstall = Bandwagon.Preferences.getPreference("allow.incompatible.install");
+
+ if ((isExtensionsCheckCompatibility != null && isExtensionsCheckCompatibility == false)
+ && (isAllowIncompatibleInstall != null && isAllowIncompatibleInstall == true)
+ && (this.addon.getInstaller(Bandwagon.Util.getHostEnvironmentInfo().os))
+ )
+ {
+ document.getAnonymousElementByAttribute(this, 'anonid', 'addtofirefox').disabled = false;
+ }
+ else
+ {
+ document.getAnonymousElementByAttribute(this, 'anonid', 'addtofirefox').disabled = true;
+ }
+ }
+ }
+ ]]>
+ </body>
+ </method>
+
+ <method name="_imageLoaded">
+ <parameter name="image"/>
+ <body>
+ <![CDATA[
+ //Bandwagon.Logger.debug("Thumbnail image loaded, dimensions are " + image.width + "x" + image.height);
+
+ var thumbnail = this._thumbnail;
+
+ if (thumbnail)
+ {
+ var maxWidth = this._maxThumbnailWidth;
+ var maxHeight = this._maxThumbnailHeight;
+
+ var width = image.width;
+ var height = image.height;
+
+ if ((maxWidth >= image.width) &&
+ (maxHeight >= image.height))
+ {
+ width = image.width;
+ height = image.height;
+ }
+ else if (image.width > image.height)
+ {
+ width = maxWidth;
+ height = (maxHeight / image.width) * image.height;
+ }
+ else
+ {
+ height = maxHeight;
+ width = (maxWidth / image.height) * image.width;
+ }
+
+ //Bandwagon.Logger.debug("Setting thumbnail dimensions to " + width + "x" + height);
+
+ thumbnail.style.width = width + "px";
+ thumbnail.style.height = height + "px";
+ thumbnail.src = image.src;
+ }
+ ]]>
+ </body>
+ </method>
+ </implementation>
+ </binding>
+
+ <binding id="bandwagon-addon-expanded" extends="chrome://bandwagon/content/ui/bindings/bandwagon.xml#bandwagon-addon">
+
+ <content>
+ <xul:stringbundle src="chrome://bandwagon/locale/bandwagonAddon.properties"
+ anonid="stringbundle"/>
+
+ <xul:hbox flex="1">
+ <xul:vbox class="addonIcon">
+ <xul:image anonid="icon" class="icon"/>
+ </xul:vbox>
+ <xul:vbox flex="1" class="addonTextBox">
+ <xul:hbox flex="1">
+ <xul:vbox flex="1">
+ <xul:hbox flex="1" align="center">
+ <xul:label anonid="name" class="name"/>
+ <xul:spacer flex="1"/>
+ <xul:vbox align="end">
+ <xul:hbox align="center">
+ <xul:image anonid="commenticon" class="comment-icon"/>
+ <xul:label anonid="dateadded"/>
+ </xul:hbox>
+ <xul:label anonid="addedby"/>
+ </xul:vbox>
+ </xul:hbox>
+ <xul:hbox anonid="byline" flex="1">
+ <xul:label anonid="authors"/>
+ <xul:spacer flex="1"/>
+ </xul:hbox>
+ </xul:vbox>
+ </xul:hbox>
+ <xul:vbox anonid="commentbox" flex="1" class="comments unindent">
+ <xul:hbox align="center">
+ <xul:label anonid="commentauthor" flex="1"/>
+ </xul:hbox>
+ <xul:description anonid="commentdesc" flex="1"/>
+ </xul:vbox>
+ <xul:hbox align="stretch"
+ anonid="fulldesc"
+ class="collection-item-details unindent"
+ flex="1">
+ <xul:vbox pack="start">
+ <xul:hbox anonid="bandwagonThumbnailContainer"
+ class="bandwagonThumbnailContainer">
+ <xul:vbox flex="1" align="center" pack="center">
+ <xul:image anonid="thumbnail" class="thumbnail" src="chrome://global/skin/icons/loading_16.png"/>
+ </xul:vbox>
+ </xul:hbox>
+ </xul:vbox>
+ <xul:vbox flex="1">
+ <xul:description anonid="description">
+ <xul:label anonid="learnmore" class="text-link" value="&addon.moreinfo;" onclick="Bandwagon.Controller.CollectionsPane.doMoreInfo()"/>
+ </xul:description>
+ <xul:spacer flex="1"/>
+ <xul:hbox pack="end" class="publishButton">
+ <xul:bandwagonPublishButton anonid="publish" label="&publishto.label;"/>
+ <xul:button anonid="addtofirefox" label="&addon.addtofirefox;" oncommand="Bandwagon.Controller.CollectionsPane.doAddToFirefox()"/>
+ </xul:hbox>
+ <xul:description anonid="addtofirefoxwarning" class="right">
+ </xul:description>
+ </xul:vbox>
+ </xul:hbox>
+ </xul:vbox>
+ </xul:hbox>
+ </content>
+
+ <implementation implements="nsIAccessibleProvider">
+ <field name="_thumbnailContainer">
+ document.getAnonymousElementByAttribute(this, 'anonid', 'bandwagonThumbnailContainer');
+ </field>
+
+ <field name="_thumbnail">
+ document.getAnonymousElementByAttribute(this, 'anonid', 'thumbnail');
+ </field>
+
+ <field name="_maxThumbnailWidth">125</field>
+ <field name="_maxThumbnailHeight">120</field>
+ <field name="_thumbnailMissingPlaceholder">"chrome://bandwagon/skin/images/missing-thumbnail.png"</field>
+
+ </implementation>
+ </binding>
+
+
+ <binding id="bandwagon-publish-button">
+
+ <resources>
+ <stylesheet src="chrome://bandwagon/skin/extensionsOverlay.css"/>
+ <stylesheet src="chrome://bandwagon/skin/extensionsOverlayIcons.css"/>
+ </resources>
+
+ <content>
+ <xul:button label="&publishto.label;"
+ type="menu"
+ anonid="publishButton"
+ class="publishButton"
+ collapsed="true">
+ <xul:menupopup anonid="writableCollections">
+ <!-- writable collections go here -->
+ <xul:menuitem label="&new.collection.label;" oncommand="Bandwagon.Controller.ExtensionsOverlay.doNewCollection();" anonid="newCollection"/>
+ <xul:menuseparator anonid="writableCollectionSeparator"/>
+ <xul:menu label="&email.address.label;" anonid="emailAddressMenu">
+ <xul:menupopup anonid="emailAddresses">
+ <!-- email addresses go here -->
+ <xul:menuseparator anonid="emailAddressSeparator"/>
+ <xul:menuitem label="&new.email.address.label;" oncommand="Bandwagon.Controller.ExtensionsOverlay.doAddNewShareEmail();"/>
+ </xul:menupopup>
+ </xul:menu>
+ </xul:menupopup>
+ </xul:button>
+
+ </content>
+
+ <implementation>
+ <field name="emailAddresses"/>
+ <field name="writableCollections"/>
+
+ <constructor>
+ <![CDATA[
+ if (this.emailAddresses && this.writableCollections)
+ {
+ this.invalidate();
+ }
+ ]]>
+ </constructor>
+
+ <method name="invalidate">
+ <body>
+ <![CDATA[
+ const XULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
+
+ var elemWritableCollectionsPopup = document.getAnonymousElementByAttribute(this, "anonid", "writableCollections");
+ var elemWritableCollectionSeparator = document.getAnonymousElementByAttribute(this, "anonid", "writableCollectionSeparator");
+ var elemEmailAddressesPopup = document.getAnonymousElementByAttribute(this, "anonid", "emailAddresses");
+ var elemEmailAddressSeparator = document.getAnonymousElementByAttribute(this, "anonid", "emailAddressSeparator");
+ var elemEmailAddressMenu = document.getAnonymousElementByAttribute(this, "anonid", "emailAddressMenu");
+ var elemPublishButton = document.getAnonymousElementByAttribute(this, "anonid", "publishButton");
+ var elemNewCollection = document.getAnonymousElementByAttribute(this, "anonid", "newCollection");
+
+ // populate the email address menu
+
+ var activeEmailMenu = elemEmailAddressesPopup;
+ var activeEmailAddressSeparator = elemEmailAddressSeparator;
+
+ if (this.emailAddresses.length)
+ {
+ for (var i=0; i<this.emailAddresses.length; i++)
+ {
+ var email = this.emailAddresses[i];
+
+ if (document.getAnonymousElementByAttribute(this, "anonid", "bandwagon-email-" + email))
+ continue;
+
+ var callback = new Function("Bandwagon.Controller.ExtensionsOverlay.doShareToEmail('" + email + "')");
+
+ var elemEmailMenuItem = document.createElementNS(XULNS, "menuitem");
+ elemEmailMenuItem.setAttribute("label", email);
+ elemEmailMenuItem.setAttribute("anonid", "bandwagon-email-" + email);
+ elemEmailMenuItem.addEventListener("command", callback, true);
+
+ activeEmailMenu.insertBefore(elemEmailMenuItem, activeEmailAddressSeparator);
+ }
+
+ activeEmailAddressSeparator.collapsed = false;
+ }
+ else
+ {
+ // don't show the separator if there are no email addresses
+ activeEmailAddressSeparator.collapsed = true;
+ }
+
+ // populate the collections menu
+
+ function createAddToCollectionCallbackFunction(collection)
+ {
+ return function() { Bandwagon.Controller.ExtensionsOverlay.doPublishToCollection(collection); }
+ }
+
+ function createRemoveFromCollectionCallbackFunction(collection)
+ {
+ return function() { Bandwagon.Controller.ExtensionsOverlay.doRemoveFromCollection(collection); }
+ }
+
+ for (var i=0; i<this.writableCollections.length; i++)
+ {
+ var collection = this.writableCollections[i];
+
+ if (document.getAnonymousElementByAttribute(this, "anonid", "bandwagon-collection-" + collection.resourceURL))
+ continue;
+
+ var callbackAdd = createAddToCollectionCallbackFunction(collection);
+ var callbackRemove = createRemoveFromCollectionCallbackFunction(collection);
+
+ var elemWritableCollection = document.createElementNS(XULNS, "menuitem");
+ elemWritableCollection.setAttribute("label", (collection.name?collection.name:collection.resourceURL));
+ elemWritableCollection.setAttribute("anonid", "bandwagon-collection-" + collection.resourceURL);
+
+ if (collection.__containsCurrentlySelectedExtension)
+ {
+ elemWritableCollection.setAttribute("type", "checkbox");
+ elemWritableCollection.setAttribute("checked", "true");
+ elemWritableCollection.setAttribute("autocheck", "false");
+ elemWritableCollection.addEventListener("command", callbackRemove, true);
+ }
+ else
+ {
+ elemWritableCollection.addEventListener("command", callbackAdd, true);
+ }
+
+ elemWritableCollectionsPopup.insertBefore(elemWritableCollection, elemNewCollection);
+ }
+
+ elemPublishButton.collapsed = false;
+ ]]>
+ </body>
+ </method>
+ </implementation>
+ </binding>
+
+</bindings>
diff --git a/bandwagon/content/ui/collectionsPaneController.js b/bandwagon/content/ui/collectionsPaneController.js
new file mode 100644
index 0000000..af2933f
--- /dev/null
+++ b/bandwagon/content/ui/collectionsPaneController.js
@@ -0,0 +1,867 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is bandwagon.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s): David McNamara
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+Bandwagon.Controller.CollectionsPane = new function()
+{
+ this.initialized = false;
+ this.initializedBindings = false;
+
+ this.preferredCollection = null;
+
+ this.elemBandwagonCollections = null;
+ this.elemBandwagonAddons = null;
+ this.elemBandwagonButtonViewSite = null;
+ //this.elemBandwagonButtonUpdate = null;
+ this.elemBandwagonButtonRemove = null;
+ this.elemBandwagonCollectionTitle = null;
+ this.elemBandwagonCollectionDescription = null;
+ this.elemBandwagonCollectionsNotification = null;
+ this.elemBandwagonCollectionDeck = null;
+ this.stringBundle = null;
+ this.loginInProcess = false;
+
+ //this.previewNotificationVal = "bandwagon-collection-preview";
+}
+
+Bandwagon.Controller.CollectionsPane.init = function()
+{
+ if (Bandwagon.Controller.CollectionsPane.initialized == true) return;
+
+ Bandwagon.Logger.debug("Initializing Bandwagon.Controller.CollectionsPane");
+
+ this.elemBandwagonCollections = document.getElementById("bandwagon-collections-list");
+ this.elemBandwagonAddons = document.getElementById("bandwagon-addons-list");
+ this.elemBandwagonButtonViewSite = document.getElementById("bandwagon-button-viewsite");
+ //this.elemBandwagonButtonUpdate = document.getElementById("bandwagon-button-update");
+ this.elemBandwagonButtonRemove = document.getElementById("bandwagon-button-remove");
+ this.elemBandwagonExtensionsDeck = document.getElementById("bandwagon-extensions-deck");
+ this.elemBandwagonCollectionTitle = document.getElementById("bandwagon-collection-title");
+ this.elemBandwagonCollectionDescription = document.getElementById("bandwagon-collection-description");
+ this.elemBandwagonCollectionsNotification = document.getElementById("bandwagon-collections-notification");
+ this.elemBandwagonCollectionDeck = document.getElementById("bandwagon-collection-deck");
+
+ Bandwagon.Controller.CollectionsPane._repopulateCollectionsList();
+ Bandwagon.Controller.CollectionsPane.invalidate();
+
+ this.elemBandwagonCollections.addEventListener("select", Bandwagon.Controller.CollectionsPane.doShowCollection, true);
+ this.elemBandwagonAddons.addEventListener("select", Bandwagon.Controller.CollectionsPane.doExpandAddon, true);
+
+ bandwagonService.registerCollectionUpdateObserver(Bandwagon.Controller.CollectionsPane.collectionUpdateObserver);
+ bandwagonService.registerCollectionListChangeObserver(Bandwagon.Controller.CollectionsPane.collectionListChangeObserver);
+ bandwagonService.registerAuthenticationStatusChangeObserver(Bandwagon.Controller.CollectionsPane.authenticationStatusChangeObserver);
+
+ Bandwagon.Preferences.addObserver(Bandwagon.Controller.CollectionsPane.prefObserver);
+ Bandwagon.Preferences.addGlobalObserver(Bandwagon.Controller.CollectionsPane.prefObserver, "extensions.bandwagon.allow.incompatible.");
+
+ Components.classes["@mozilla.org/observer-service;1"].getService(Components.interfaces.nsIObserverService).addObserver(Bandwagon.Controller.CollectionsPane.prefObserver, "nsPref:changed", false);
+}
+
+/**
+ * Triggered when the user navigates to the collections pane from a different view in the extensions manager
+ */
+Bandwagon.Controller.CollectionsPane.onViewSelect = function()
+{
+ Bandwagon.Logger.debug("in Bandwagon.Controller.CollectionsPane.onViewSelect()");
+
+ if (Bandwagon.Controller.CollectionsPane.elemBandwagonCollections.selectedItem != null)
+ {
+ // make sure the expanded collection item is scrolled into view
+ var elemsAddonExpanded = Bandwagon.Controller.CollectionsPane.elemBandwagonAddons.getElementsByTagName("bandwagonAddonExpanded");
+
+ if (elemsAddonExpanded && elemsAddonExpanded[0])
+ {
+ try
+ {
+ Bandwagon.Controller.CollectionsPane.elemBandwagonAddons.ensureElementIsVisible(elemsAddonExpanded[0]);
+ } catch (e) {}
+ }
+ }
+}
+
+Bandwagon.Controller.CollectionsPane.bindingsReady = function()
+{
+ // the bindings are ready, do any final initialization
+
+ if (Bandwagon.Controller.CollectionsPane.initializedBindings == false)
+ {
+ Bandwagon.Controller.CollectionsPane._selectPreferredCollection();
+ Bandwagon.Controller.CollectionsPane.initializedBindings = true;
+ }
+
+ Bandwagon.Controller.CollectionsPane.initialized = true;
+}
+
+Bandwagon.Controller.CollectionsPane.uninit = function()
+{
+ if (Bandwagon.Controller.CollectionsPane.initialized != true) return;
+
+ Bandwagon.Logger.debug("Uninitializing Bandwagon.Controller.CollectionsPane");
+
+ Bandwagon.Controller.CollectionsPane.initialized = false;
+
+ bandwagonService.unregisterCollectionUpdateObserver(Bandwagon.Controller.CollectionsPane.collectionUpdateObserver);
+ bandwagonService.unregisterCollectionListChangeObserver(Bandwagon.Controller.CollectionsPane.collectionListChangeObserver);
+ bandwagonService.unregisterAuthenticationStatusChangeObserver(Bandwagon.Controller.CollectionsPane.authenticationStatusChangeObserver);
+
+ Bandwagon.Preferences.removeObserver(Bandwagon.Controller.CollectionsPane.prefObserver);
+ Bandwagon.Preferences.removeGlobalObserver(Bandwagon.Controller.CollectionsPane.prefObserver, "extensions.bandwagon.allow.incompatible.");
+
+ // now is a good time to save collections to storage
+ if (Bandwagon.COMMIT_NOW)
+ bandwagonService.commitAll();
+}
+
+/**
+ * Updates the interface disabled-ness based on the state of the selected collection, etc.
+ */
+Bandwagon.Controller.CollectionsPane.invalidate = function()
+{
+ if (Bandwagon.Controller.CollectionsPane.elemBandwagonCollections.selectedItem == null)
+ {
+ Bandwagon.Controller.CollectionsPane.elemBandwagonButtonViewSite.disabled = true;
+ //Bandwagon.Controller.CollectionsPane.elemBandwagonButtonUpdate.disabled = true;
+ Bandwagon.Controller.CollectionsPane.elemBandwagonButtonRemove.disabled = true;
+ Bandwagon.Controller.CollectionsPane.elemBandwagonCollectionTitle.collapsed = true;
+ Bandwagon.Controller.CollectionsPane.elemBandwagonCollectionDescription.collapsed = true;
+
+ Bandwagon.Controller.CollectionsPane._repopulateAddonsList(null);
+
+ Bandwagon.Controller.CollectionsPane._invalidateExtensionsDeck();
+ }
+ else
+ {
+ Bandwagon.Controller.CollectionsPane.elemBandwagonButtonViewSite.disabled = false;
+ //Bandwagon.Controller.CollectionsPane.elemBandwagonButtonUpdate.disabled = false;
+ Bandwagon.Controller.CollectionsPane.elemBandwagonButtonRemove.disabled = false;
+ Bandwagon.Controller.CollectionsPane.elemBandwagonCollectionTitle.collapsed = false;
+ Bandwagon.Controller.CollectionsPane.elemBandwagonCollectionDescription.collapsed = false;
+
+ var collection = Bandwagon.Controller.CollectionsPane.elemBandwagonCollections.selectedItem.collection;
+
+ if (collection.status == collection.STATUS_LOADING)
+ {
+ Bandwagon.Controller.CollectionsPane.elemBandwagonCollectionDeck.selectedIndex = 1;
+ }
+ else if (collection.status == collection.STATUS_LOADERROR)
+ {
+ Bandwagon.Controller.CollectionsPane.elemBandwagonCollectionDeck.selectedIndex = 3;
+ }
+ else if (collection.hasAddon() == 0)
+ {
+ Bandwagon.Controller.CollectionsPane.elemBandwagonCollectionDeck.selectedIndex = 2;
+ }
+ else
+ {
+ Bandwagon.Controller.CollectionsPane.elemBandwagonCollectionDeck.selectedIndex = 0;
+ }
+ }
+}
+
+Bandwagon.Controller.CollectionsPane._invalidateExtensionsDeck = function()
+{
+ var elemsBandwagonCollection = Bandwagon.Controller.CollectionsPane.elemBandwagonCollections.getElementsByTagName("bandwagonCollection");
+
+ if (!bandwagonService.isAuthenticated() || this.loginInProcess == true)
+ {
+ Bandwagon.Controller.CollectionsPane.elemBandwagonExtensionsDeck.selectedIndex = 2;
+ window.setTimeout(function() { document.getElementById("login").focus(); }, 200);
+ }
+ else if (elemsBandwagonCollection.length == 0)
+ {
+ Bandwagon.Controller.CollectionsPane.elemBandwagonExtensionsDeck.selectedIndex = 1;
+ }
+ else
+ {
+ Bandwagon.Controller.CollectionsPane.elemBandwagonExtensionsDeck.selectedIndex = 0;
+ }
+}
+
+Bandwagon.Controller.CollectionsPane.collectionListChangeObserver = function()
+{
+ Bandwagon.Logger.debug("In Bandwagon.Controller.CollectionsPane.collectionListChangeObserver()");
+
+ var prevCollection = null;
+
+ if (Bandwagon.Controller.CollectionsPane.elemBandwagonCollections.selectedItem)
+ {
+ prevCollection = Bandwagon.Controller.CollectionsPane.elemBandwagonCollections.selectedItem.collection;
+ }
+
+ Bandwagon.Controller.CollectionsPane._repopulateCollectionsList();
+ Bandwagon.Controller.CollectionsPane._invalidateExtensionsDeck();
+
+ if (prevCollection != null && bandwagonService.collections[prevCollection.resourceURL])
+ {
+ var retval = Bandwagon.Controller.CollectionsPane._selectCollection(prevCollection);
+
+ if (!retval)
+ Bandwagon.Controller.CollectionsPane._selectPreferredCollection();
+ }
+ else
+ {
+ Bandwagon.Controller.CollectionsPane._selectPreferredCollection();
+ }
+}
+
+Bandwagon.Controller.CollectionsPane.collectionUpdateObserver = function(collection)
+{
+ if (collection == null)
+ {
+ Bandwagon.Logger.debug("In Bandwagon.Controller.CollectionsPane.collectionUpdateObserver() with collection <null>");
+ }
+ else
+ {
+ Bandwagon.Logger.debug("In Bandwagon.Controller.CollectionsPane.collectionUpdateObserver() with collection '" + collection.toString() + "'");
+
+ // update the unread count for this collection
+
+ const XULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
+ var elemsBandwagonCollection = Bandwagon.Controller.CollectionsPane.elemBandwagonCollections.getElementsByTagNameNS(XULNS, "bandwagonCollection");
+
+ for (var i=0; i<elemsBandwagonCollection.length; i++)
+ {
+ if (elemsBandwagonCollection[i].collection.equals(collection))
+ {
+ elemsBandwagonCollection[i].unread = collection.getUnreadAddons().length;
+ break;
+ }
+ }
+
+ // if this collection is currently selected, update the view
+
+ if (Bandwagon.Controller.CollectionsPane.elemBandwagonCollections.selectedItem && collection.equals(Bandwagon.Controller.CollectionsPane.elemBandwagonCollections.selectedItem.collection))
+ {
+ Bandwagon.Controller.CollectionsPane._repopulateAddonsList(collection);
+ }
+ }
+
+ Bandwagon.Controller.CollectionsPane.invalidate();
+}
+
+Bandwagon.Controller.CollectionsPane.authenticationStatusChangeObserver = function()
+{
+ Bandwagon.Controller.CollectionsPane._invalidateExtensionsDeck();
+}
+
+Bandwagon.Controller.CollectionsPane.doUpdateAll = function(event)
+{
+ Bandwagon.Controller.CollectionsPane.elemBandwagonCollectionDeck.selectedIndex = 1;
+
+ bandwagonService.forceCheckAllForUpdatesAndUpdateCollectionsList();
+}
+
+Bandwagon.Controller.CollectionsPane.doSubscribe = function(event)
+{
+ Bandwagon.Controller.CollectionsPane._openLocalizedURL(Bandwagon.COLLECTIONSPANE_DO_SUBSCRIBE_URL);
+}
+
+Bandwagon.Controller.CollectionsPane.doLogin = function(event)
+{
+ var uname = document.getElementById("login").value;
+ var pwd = document.getElementById("password").value;
+
+ // Some client side checking for blank login details
+ if (!uname || uname == "" || !uname.match(/.*\w.*/) ||
+ !pwd || pwd == "" || !pwd.match(/.*\w.*/))
+ {
+ document.getElementById("auth-error").textContent = Bandwagon.Controller.ExtensionsOverlay.stringBundle.getString("login.error");
+ document.getElementById("auth-error").collapsed = false;
+ return;
+ }
+
+ this.loginInProcess = true;
+
+ document.getElementById("auth-button").disabled = true;
+ document.getElementById("auth-spinner").style.visibility = "visible";
+ document.getElementById("auth-error").collapsed = true;
+
+ var callback2 = function(event)
+ {
+ document.getElementById("auth-button").disabled = false;
+ document.getElementById("auth-spinner").style.visibility = "hidden";
+ document.getElementById("password").value = "";
+ Bandwagon.Controller.CollectionsPane.loginInProcess = false;
+ Bandwagon.Controller.CollectionsPane._invalidateExtensionsDeck();
+ }
+
+ var callback1 = function(event)
+ {
+ if (event.isError())
+ {
+ // show err
+ document.getElementById("auth-error").textContent = Bandwagon.Controller.ExtensionsOverlay.stringBundle.getString("login.error");
+ document.getElementById("auth-error").collapsed = false;
+ document.getElementById("auth-button").disabled = false;
+ document.getElementById("auth-spinner").style.visibility = "hidden";
+ }
+ else
+ {
+ bandwagonService.updateCollectionsList(callback2);
+ }
+ }
+
+ bandwagonService.authenticate(uname, pwd, callback1);
+}
+
+Bandwagon.Controller.CollectionsPane.doSettings = function(event)
+{
+ var prefSvc = Components.classes["@mozilla.org/preferences-service;1"].
+ getService(Components.interfaces.nsIPrefService);
+ var prefServiceCache = prefSvc.getBranch(null);
+ var instantApply = prefServiceCache.getBoolPref("browser.preferences.instantApply");
+ var flags = "chrome,titlebar,toolbar,centerscreen" + (instantApply ? ",dialog=no" : ",modal");
+
+ var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
+ .getService(Components.interfaces.nsIWindowMediator);
+ var win = wm.getMostRecentWindow("Bandwagon:Settings");
+
+ if (win)
+ {
+ win.focus();
+ }
+ else
+ {
+ window.openDialog("chrome://bandwagon/content/ui/settings.xul",
+ "bandwagonsettings",
+ flags);
+ }
+}
+
+Bandwagon.Controller.CollectionsPane.doViewSite = function(event)
+{
+ if (Bandwagon.Controller.CollectionsPane.elemBandwagonCollections.selectedItem == null)
+ return;
+
+ var collection = Bandwagon.Controller.CollectionsPane.elemBandwagonCollections.selectedItem.collection;
+
+ if (collection == null || !collection.links["view"])
+ return;
+
+ Bandwagon.Controller.CollectionsPane._openURL(collection.links["view"]);
+}
+
+Bandwagon.Controller.CollectionsPane.doUpdate = function(event)
+{
+ if (Bandwagon.Controller.CollectionsPane.elemBandwagonCollections.selectedItem == null)
+ return;
+
+ Bandwagon.Controller.CollectionsPane.elemBandwagonCollectionDeck.selectedIndex = 1;
+
+ var collection = Bandwagon.Controller.CollectionsPane.elemBandwagonCollections.selectedItem.collection;
+
+ if (collection == null)
+ return;
+
+ bandwagonService.forceCheckForUpdates(collection);
+}
+
+Bandwagon.Controller.CollectionsPane.doUnsubscribe = function(event)
+{
+ if (Bandwagon.Controller.CollectionsPane.elemBandwagonCollections.selectedItem == null)
+ return;
+
+ var collection = Bandwagon.Controller.CollectionsPane.elemBandwagonCollections.selectedItem.collection;
+
+ if (collection == null)
+ return;
+
+ var promptService = Components.classes["@mozilla.org/embedcomp/prompt-service;1"].getService(Components.interfaces.nsIPromptService);
+ var check = {value: false};
+ var flags = promptService.BUTTON_POS_0 * promptService.BUTTON_TITLE_IS_STRING + promptService.BUTTON_POS_1 * promptService.BUTTON_TITLE_IS_STRING;
+ var button = promptService.confirmEx(
+ window,
+ Bandwagon.Controller.ExtensionsOverlay.stringBundle.getString("unsubscribe.confirm.title"),
+ Bandwagon.Controller.ExtensionsOverlay.stringBundle.getString("unsubscribe.confirm.label"),
+ flags,
+ Bandwagon.Controller.ExtensionsOverlay.stringBundle.getString("unsubscribe.confirm.button0"),
+ Bandwagon.Controller.ExtensionsOverlay.stringBundle.getString("unsubscribe.confirm.button1"),
+ null,
+ null,
+ check);
+
+ if (button == 0)
+ {
+ var callback = function(event)
+ {
+ if (event.isError())
+ {
+ window.alert(Bandwagon.Controller.ExtensionsOverlay.stringBundle.getString("unsubscribe.error"));
+ }
+ }
+
+ bandwagonService.unsubscribeFromCollection(collection, callback);
+ }
+}
+
+Bandwagon.Controller.CollectionsPane.doShowCollection = function()
+{
+ var collection = null;
+
+ var selectedElemBandwagonCollection = Bandwagon.Controller.CollectionsPane.elemBandwagonCollections.selectedItem;
+
+ if (selectedElemBandwagonCollection != null)
+ {
+ collection = selectedElemBandwagonCollection.collection;
+ }
+
+ // if collection == null, then display will be cleared
+
+ // misc. ui
+
+ Bandwagon.Controller.CollectionsPane.elemBandwagonCollectionTitle.textContent = (collection?(collection.name?collection.name:collection.resourceURL):"");
+
+ if (collection && collection.description != "")
+ {
+ Bandwagon.Controller.CollectionsPane.elemBandwagonCollectionDescription.textContent = collection.description;
+ Bandwagon.Controller.CollectionsPane.elemBandwagonCollectionDescription.removeAttribute("collsaped");
+ }
+ else
+ {
+ Bandwagon.Controller.CollectionsPane.elemBandwagonCollectionDescription.setAttribute("collapsed", true);
+ }
+
+ Bandwagon.Controller.CollectionsPane.elemBandwagonCollectionsNotification.notificationsHidden = true;
+
+ // show items
+
+ Bandwagon.Controller.CollectionsPane._repopulateAddonsList(collection);
+
+ // invalidate
+
+ Bandwagon.Controller.CollectionsPane.invalidate();
+
+ // show the loading dialog if needed
+
+ if (collection && collection.status == collection.STATUS_LOADING)
+ {
+ Bandwagon.Controller.CollectionsPane.elemBandwagonCollectionDeck.selectedIndex = 1;
+ }
+
+ // set all items in this collection to be "read"
+ // if we've just opened this dialog, don't update the read count
+
+ if (collection)
+ {
+ collection.setAllRead();
+
+ if (Bandwagon.Controller.CollectionsPane.initialized)
+ {
+ Bandwagon.Controller.CollectionsPane.elemBandwagonCollections.selectedItem.unread = 0;
+ }
+ }
+}
+
+Bandwagon.Controller.CollectionsPane.doExpandAddon = function(event)
+{
+ if (event)
+ event.preventDefault();
+
+ if (Bandwagon.Controller.CollectionsPane.elemBandwagonAddons.selectedItem && Bandwagon.Controller.CollectionsPane.elemBandwagonAddons.selectedItem.nodeName == "bandwagonAddonExpanded")
+ {
+ return;
+ }
+
+ var elemsAddonExpanded = Bandwagon.Controller.CollectionsPane.elemBandwagonAddons.getElementsByTagName("bandwagonAddonExpanded");
+
+ for (var i=0; i<elemsAddonExpanded.length; i++)
+ {
+ Bandwagon.Controller.CollectionsPane.elemBandwagonAddons.removeChild(elemsAddonExpanded[i]);
+ }
+
+ var elemsAddon = Bandwagon.Controller.CollectionsPane.elemBandwagonAddons.childNodes;
+
+ for (var i=0; i<elemsAddon.length; i++)
+ {
+ elemsAddon[i].collapsed = false;
+ }
+
+ var selectedElemBandwagonAddon = Bandwagon.Controller.CollectionsPane.elemBandwagonAddons.selectedItem;
+
+ if (selectedElemBandwagonAddon != null && selectedElemBandwagonAddon.addon != null)
+ {
+ selectedElemBandwagonAddon.read = true;
+
+ var addon = selectedElemBandwagonAddon.addon;
+ addon.read = true;
+
+ Bandwagon.Controller.CollectionsPane.elemBandwagonCollections.selectedItem.unread = Bandwagon.Controller.CollectionsPane.elemBandwagonCollections.selectedItem.collection.getUnreadAddons().length;
+
+ // collapse this, show the expanded binding
+
+ const XULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
+ var elemBandwagonAddonExpanded = document.createElementNS(XULNS, "bandwagonAddonExpanded");
+
+ elemBandwagonAddonExpanded.addon = addon;
+
+ try
+ {
+ Bandwagon.Controller.CollectionsPane.elemBandwagonAddonExpanded.setAddon(addon);
+ } catch (e) {}
+
+ Bandwagon.Controller.CollectionsPane.elemBandwagonAddons.insertBefore(elemBandwagonAddonExpanded, selectedElemBandwagonAddon);
+
+ selectedElemBandwagonAddon.collapsed = true;
+ }
+}
+
+Bandwagon.Controller.CollectionsPane.doMoreInfo = function(event)
+{
+ if (event)
+ event.preventDefault();
+
+ if (Bandwagon.Controller.CollectionsPane.elemBandwagonAddons == null)
+ return;
+
+ Bandwagon.Controller.CollectionsPane._openURL(Bandwagon.Controller.CollectionsPane.elemBandwagonAddons.selectedItem.addon.learnmore);
+}
+
+Bandwagon.Controller.CollectionsPane.doAddToFirefox = function()
+{
+ if (Bandwagon.Controller.CollectionsPane.elemBandwagonAddons.selectedItem == null)
+ return;
+
+ var addon = Bandwagon.Controller.CollectionsPane.elemBandwagonAddons.selectedItem.addon;
+
+ if (!isXPInstallEnabled())
+ return;
+
+ if (addon.eula && addon.eula != "")
+ {
+ var eula = {
+ name: addon.name,
+ text: addon.eula,
+ accepted: false
+ };
+
+ window.openDialog("chrome://mozapps/content/extensions/eula.xul", "_blank",
+ "chrome,dialog,modal,centerscreen,resizable=no", eula);
+
+ if (!eula.accepted)
+ return;
+ }
+
+ var installer = addon.getInstaller(Bandwagon.Util.getHostEnvironmentInfo().os);
+
+ if (!installer)
+ {
+ Bandwagon.Logger.warn("No compatible os targets found.");
+ return;
+ }
+
+ var params = [];
+ params[addon.name] = installer;
+
+ // TODO do some user feedback here?
+
+ var callback = function(url, status)
+ {
+ Bandwagon.Logger.info("Finished installing '" + url + "'; status = " + status);
+
+ // TODO some user feedback here?
+ }
+
+ InstallTrigger.install(params, callback);
+}
+
+Bandwagon.Controller.CollectionsPane.doUpgradeToFirefoxN = function(version)
+{
+ Bandwagon.Logger.info("in Bandwagon.Controller.CollectionsPane.doUpgradeToFirefoxN() with version = " + version);
+
+ Bandwagon.Controller.CollectionsPane._openURL("http://www.mozilla.com/en-US/firefox/all.html");
+}
+
+Bandwagon.Controller.CollectionsPane.doDownloadFirefoxNBeta = function(version)
+{
+ Bandwagon.Logger.info("in Bandwagon.Controller.CollectionsPane.doDownloadFirefoxNBeta() with version = " + version);
+
+ Bandwagon.Controller.CollectionsPane._openURL("http://www.mozilla.com/en-US/firefox/all-beta.html");
+}
+
+/**
+ * Refreshes the collection pane
+ */
+Bandwagon.Controller.CollectionsPane.refresh = function()
+{
+ var selectedElemBandwagonCollection = Bandwagon.Controller.CollectionsPane.elemBandwagonCollections.selectedItem;
+
+ if (selectedElemBandwagonCollection != null)
+ {
+ collection = selectedElemBandwagonCollection.collection;
+ Bandwagon.Controller.CollectionsPane._repopulateAddonsList(collection);
+ }
+
+ Bandwagon.Controller.CollectionsPane.invalidate();
+}
+
+Bandwagon.Controller.CollectionsPane.prefObserver =
+{
+ observe: function(subject, topic, data)
+ {
+ if (topic != "nsPref:changed")
+ return;
+
+ if (data.match(/addonsperpage/))
+ {
+ Bandwagon.Logger.debug("In prefObserver; addonsperpage has changed");
+
+ Bandwagon.Controller.CollectionsPane.refresh();
+ }
+ else if (data.match(/checkCompatibility/) || data.match(/install/))
+ {
+ Bandwagon.Logger.debug("In prefObserver; checkCompatibility has changed");
+
+ if (Bandwagon.Controller.CollectionsPane.elemBandwagonAddons.selectedItem != null)
+ {
+ var elemsAddonExpanded = Bandwagon.Controller.CollectionsPane.elemBandwagonAddons.getElementsByTagName("bandwagonAddonExpanded");
+
+ if (elemsAddonExpanded && elemsAddonExpanded[0])
+ {
+ elemsAddonExpanded[0].invalidateCompatibilityCheck();
+ }
+ }
+ }
+ }
+}
+
+/**
+ * Function to select a collection ui programmatically based on its collection object.
+ */
+Bandwagon.Controller.CollectionsPane._selectCollection = function(collection)
+{
+ // select the collection and show (collection == null clears the selection)
+
+ if (collection == null)
+ {
+ Bandwagon.Controller.CollectionsPane.elemBandwagonCollections.clearSelection();
+ Bandwagon.Controller.CollectionsPane.doShowCollection();
+ return false;
+ }
+
+ // select the richlistitem
+
+ const XULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
+
+ var elemsBandwagonCollection = Bandwagon.Controller.CollectionsPane.elemBandwagonCollections.getElementsByTagNameNS(XULNS, "bandwagonCollection");
+ var elemBandwagonCollection = null;
+
+ for (var i=0; i<elemsBandwagonCollection.length; i++)
+ {
+ if (elemsBandwagonCollection[i].collection.equals(collection))
+ {
+ elemBandwagonCollection = elemsBandwagonCollection[i];
+ break;
+ }
+ }
+
+ if (elemBandwagonCollection == null)
+ {
+ Bandwagon.Logger.warn("could not find a richlistitem to select");
+ return false;
+ }
+
+ try
+ {
+ Bandwagon.Controller.CollectionsPane.elemBandwagonCollections.selectItem(elemBandwagonCollection);
+ Bandwagon.Controller.CollectionsPane.elemBandwagonCollections.ensureElementIsVisible(elemBandwagonCollection);
+ Bandwagon.Controller.CollectionsPane.elemBandwagonCollections.focus();
+ } catch (e) {}
+
+ return true;
+}
+
+Bandwagon.Controller.CollectionsPane._selectPreferredCollection = function()
+{
+ // select a collection - last selected or the first one
+ var elemsBandwagonCollection = Bandwagon.Controller.CollectionsPane.elemBandwagonCollections.getElementsByTagName("bandwagonCollection");
+
+ if (Bandwagon.Controller.CollectionsPane.preferredCollection != null && bandwagonService.collections[Bandwagon.Controller.CollectionsPane.preferredCollection.resourceURL] != null)
+ {
+ Bandwagon.Logger.debug("selecting preferred collection (defined)");
+ Bandwagon.Controller.CollectionsPane._selectCollection(Bandwagon.Controller.CollectionsPane.preferredCollection);
+ }
+ else if (elemsBandwagonCollection.length > 0)
+ {
+ Bandwagon.Logger.debug("selecting preferred collection (the first in the list)");
+ Bandwagon.Controller.CollectionsPane._selectCollection(elemsBandwagonCollection[0].collection);
+ }
+ else
+ {
+ Bandwagon.Logger.debug("preferred collection is none");
+ Bandwagon.Controller.CollectionsPane._selectCollection(null);
+ }
+}
+
+Bandwagon.Controller.CollectionsPane._repopulateCollectionsList = function()
+{
+ Bandwagon.Logger.debug("Bandwagon.Controller.CollectionsPane: about to repopulate the collections list");
+
+ // first clear the list
+
+ while (Bandwagon.Controller.CollectionsPane.elemBandwagonCollections.hasChildNodes())
+ {
+ Bandwagon.Controller.CollectionsPane.elemBandwagonCollections.removeChild(Bandwagon.Controller.CollectionsPane.elemBandwagonCollections.firstChild);
+ }
+
+ // repopulate with collections
+
+ var addCollection = function(collection, styleWithSeparator)
+ {
+ if (collection == null)
+ return;
+
+ const XULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
+ var elemBandwagonCollection = document.createElementNS(XULNS, "bandwagonCollection");
+ elemBandwagonCollection.collection = collection;
+ elemBandwagonCollection.controller = Bandwagon.Controller.CollectionsPane;
+ elemBandwagonCollection.styleWithSeparator = styleWithSeparator;
+
+ Bandwagon.Controller.CollectionsPane.elemBandwagonCollections.appendChild(elemBandwagonCollection);
+ }
+
+ var styleWithSeparator = false;
+
+ for (var id in bandwagonService.collections)
+ {
+ var collection = bandwagonService.collections[id];
+
+ if (collection.type == collection.TYPE_AUTOPUBLISHER)
+ {
+ Bandwagon.Logger.debug("Adding autopublisher collection (" + collection.toString() + ") to collection list");
+ addCollection(collection);
+
+ styleWithSeparator = true;
+ }
+ }
+
+ for (var id in bandwagonService.collections)
+ {
+ var collection = bandwagonService.collections[id];
+
+ if (collection.type != collection.TYPE_AUTOPUBLISHER)
+ {
+ Bandwagon.Logger.debug("Adding normal collection (" + collection.toString() + ") to collection list");
+ addCollection(collection, styleWithSeparator);
+
+ styleWithSeparator = false;
+ }
+ }
+}
+
+Bandwagon.Controller.CollectionsPane._repopulateAddonsList = function(collection)
+{
+ // first clear the list
+
+ while (Bandwagon.Controller.CollectionsPane.elemBandwagonAddons.hasChildNodes())
+ {
+ Bandwagon.Controller.CollectionsPane.elemBandwagonAddons.removeChild(Bandwagon.Controller.CollectionsPane.elemBandwagonAddons.firstChild);
+ }
+
+ Bandwagon.Controller.CollectionsPane.elemBandwagonAddons.clearSelection();
+
+ if (collection == null)
+ return;
+
+ Bandwagon.Logger.debug("Bandwagon.Controller.CollectionsPane: repopulating collection '" + collection.resourceURL + "'");
+
+ // sort by addon.dateAdded
+
+ var addonsSorted = collection.getSortedAddons();
+
+ // repopulate with collection items
+
+ const XULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
+
+ var addonsToDisplay;
+
+ if (Bandwagon.ENABLE_PAGINATION)
+ {
+ addonsToDisplay = Math.max(bandwagonService.getAddonsPerPage(collection), addonsSorted.length);
+ }
+ else
+ {
+ addonsToDisplay = addonsSorted.length;
+ }
+
+ for (var i=0; i<addonsToDisplay; i++)
+ {
+ var addon = collection.addons[addonsSorted[i].guid];
+
+ if (addon == null)
+ continue;
+
+ var elemBandwagonAddon = document.createElementNS(XULNS, "bandwagonAddon");
+ elemBandwagonAddon.addon = addon;
+
+ Bandwagon.Controller.CollectionsPane.elemBandwagonAddons.appendChild(elemBandwagonAddon);
+ }
+}
+
+Bandwagon.Controller.CollectionsPane._openURL = function(url)
+{
+ Bandwagon.Logger.debug("Opening URL " + url);
+
+ var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
+ .getService(Components.interfaces.nsIWindowMediator);
+ var mainWindow = wm.getMostRecentWindow("navigator:browser");
+
+ if (mainWindow)
+ {
+ var tab = mainWindow.getBrowser().addTab(url);
+ mainWindow.getBrowser().selectedTab = tab;
+ mainWindow.focus();
+ }
+ else
+ {
+ window.open(url);
+ }
+}
+
+Bandwagon.Controller.CollectionsPane._openLocalizedURL = function(url)
+{
+ var locale = Bandwagon.Util.getBrowserLocale();
+
+ Bandwagon.Logger.debug("locale = " + locale);
+
+ if (locale && locale != "")
+ url = url.replace(/en-US/, locale, "g");
+
+ Bandwagon.Controller.CollectionsPane._openURL(url);
+}
+
+// when this window closes, we do any uninit stuff
+
+window.addEventListener("unload", Bandwagon.Controller.CollectionsPane.uninit, true);
+
diff --git a/bandwagon/content/ui/dialog.js b/bandwagon/content/ui/dialog.js
new file mode 100644
index 0000000..84d096f
--- /dev/null
+++ b/bandwagon/content/ui/dialog.js
@@ -0,0 +1,77 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is bandwagon.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s): David McNamara
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+var Bandwagon;
+var bandwagonService;
+
+try
+{
+ // try and re-use the Bandwagon singletons from a recent browser window
+
+ var bw = Components.classes["@mozilla.org/appshell/window-mediator;1"]
+ .getService(Components.interfaces.nsIWindowMediator)
+ .getMostRecentWindow("navigator:browser");
+
+ if (bw)
+ {
+ Bandwagon = bw.Bandwagon;
+ }
+ else
+ {
+ // no recent browser window - load required scripts dynamically
+ var scriptLoader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"]
+ .getService(Components.interfaces.mozIJSSubScriptLoader);
+
+ scriptLoader.loadSubScript("chrome://bandwagon/content/scripts/bandwagon.js");
+ scriptLoader.loadSubScript("chrome://bandwagon/content/scripts/logger.js");
+ scriptLoader.loadSubScript("chrome://bandwagon/content/scripts/util.js");
+ scriptLoader.loadSubScript("chrome://bandwagon/content/scripts/prefs.js");
+ }
+
+ // get the service
+
+ netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
+
+ bandwagonService = Components.classes["@addons.mozilla.org/bandwagonservice;1"]
+ .getService().wrappedJSObject;
+}
+catch (e)
+{
+ Bandwagon.Logger.error("Error fixing Bandwagon refs: " + e);
+}
+
+
+
diff --git a/bandwagon/content/ui/overlays/browserOverlay.xul b/bandwagon/content/ui/overlays/browserOverlay.xul
new file mode 100644
index 0000000..cb9d0e8
--- /dev/null
+++ b/bandwagon/content/ui/overlays/browserOverlay.xul
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- ***** BEGIN LICENSE BLOCK *****
+ - Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ -
+ - The contents of this file are subject to the Mozilla Public License Version
+ - 1.1 (the "License"); you may not use this file except in compliance with
+ - the License. You may obtain a copy of the License at
+ - http://www.mozilla.org/MPL/
+ -
+ - Software distributed under the License is distributed on an "AS IS" basis,
+ - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ - for the specific language governing rights and limitations under the
+ - License.
+ -
+ - The Original Code is bandwagon.
+ -
+ - The Initial Developer of the Original Code is
+ - David McNamara.
+ - Portions created by the Initial Developer are Copyright (C) 2008
+ - the Initial Developer. All Rights Reserved.
+ -
+ - Contributor(s): Brian King <brian (at) briks (dot) si>
+ -
+ - Alternatively, the contents of this file may be used under the terms of
+ - either the GNU General Public License Version 2 or later (the "GPL"), or
+ - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ - in which case the provisions of the GPL or the LGPL are applicable instead
+ - of those above. If you wish to allow use of your version of this file only
+ - under the terms of either the GPL or the LGPL, and not to allow others to
+ - use your version of this file under the terms of the MPL, indicate your
+ - decision by deleting the provisions above and replace them with the notice
+ - and other provisions required by the GPL or the LGPL. If you do not delete
+ - the provisions above, a recipient may use your version of this file under
+ - the terms of any one of the MPL, the GPL or the LGPL.
+ -
+ - ***** END LICENSE BLOCK ***** -->
+
+<!DOCTYPE overlay SYSTEM "chrome://bandwagon/locale/browserOverlay.dtd" >
+
+<?xml-stylesheet href="chrome://bandwagon/skin/browserOverlay.css" type="text/css"?>
+
+<overlay id="bandwagon-browser-overlay"
+ xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+
+ <script src="chrome://bandwagon/content/scripts/bandwagon.js"/>
+ <script src="chrome://bandwagon/content/scripts/logger.js"/>
+ <script src="chrome://bandwagon/content/scripts/util.js"/>
+ <script src="chrome://bandwagon/content/scripts/prefs.js"/>
+ <script src="chrome://bandwagon/content/scripts/rpc/service.js"/>
+ <script src="chrome://bandwagon/content/scripts/rpc/constants.js"/>
+ <script src="chrome://bandwagon/content/scripts/rpc/error.js"/>
+ <script src="chrome://bandwagon/content/scripts/rpc/event.js"/>
+ <script src="chrome://bandwagon/content/scripts/rpc/net.js"/>
+ <script src="chrome://bandwagon/content/scripts/model/serviceDocument.js"/>
+ <script src="chrome://bandwagon/content/scripts/model/collection.js"/>
+ <script src="chrome://bandwagon/content/scripts/model/addon.js"/>
+ <script src="chrome://bandwagon/content/scripts/factory/collectionFactory.js"/>
+
+ <script src="chrome://bandwagon/content/ui/overlays/browserOverlayController.js"/>
+
+ <stringbundleset>
+ <stringbundle id="bandwagon-strings" src="chrome://bandwagon/locale/browserOverlay.properties"/>
+ </stringbundleset>
+
+ <!-- Firefox Toolbar -->
+ <toolbarpalette id="BrowserToolbarPalette">
+ <toolbarbutton id="extensions-bandwagon-button"
+ class="toolbarbutton-1 bandwagon-button"
+ oncommand="Bandwagon.Controller.BrowserOverlay.openAddons();"
+ tooltiptext="&bandwagon.tooltip;"
+ label="&bandwagon.label;" />
+ </toolbarpalette>
+
+</overlay>
diff --git a/bandwagon/content/ui/overlays/browserOverlayController.js b/bandwagon/content/ui/overlays/browserOverlayController.js
new file mode 100644
index 0000000..15105a3
--- /dev/null
+++ b/bandwagon/content/ui/overlays/browserOverlayController.js
@@ -0,0 +1,222 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is bandwagon.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s): David McNamara
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+var bandwagonService;
+
+Bandwagon.Controller.BrowserOverlay = new function() {}
+
+Bandwagon.Controller.BrowserOverlay.initBandwagon = function()
+{
+ Bandwagon.Controller.BrowserOverlay._removeLoadListener();
+
+ try
+ {
+ netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
+
+ bandwagonService = Components.classes["@addons.mozilla.org/bandwagonservice;1"]
+ .getService().wrappedJSObject;
+
+ // We can safely call init() for each new browser window; the service
+ // will only be initialized once.
+
+ // TODO should we observe "app-startup" instead?
+
+ bandwagonService.init();
+
+ // Set up uninstall observer
+ bandwagonService.startUninstallObserver();
+ }
+ catch (e)
+ {
+ Bandwagon.Logger.error("Error initializing bandwagon: " + e);
+ }
+
+ gBrowser.addEventListener("DOMContentLoaded", Bandwagon.Controller.BrowserOverlay.addSubscriptionRefreshEventListenerToDocument, true);
+}
+
+Bandwagon.Controller.BrowserOverlay.addSubscriptionRefreshEventListenerToDocument = function(event)
+{
+ Bandwagon.Logger.debug("In Bandwagon.Controller.BrowserOverlay.addSubscriptionRefreshEventListenerToDocument()");
+
+ if (event.originalTarget instanceof HTMLDocument)
+ {
+ var doc = event.originalTarget;
+
+ if (event.originalTarget.defaultView.frameElement)
+ {
+ while (doc.defaultView.frameElement)
+ {
+ doc=doc.defaultView.frameElement.ownerDocument;
+ }
+ }
+
+ if (doc && doc.defaultView && doc.defaultView.location && doc.defaultView.location.host)
+ {
+ var docHost = doc.defaultView.location.host;
+
+ if (docHost == Bandwagon.Preferences.getPreference("amo_host"))
+ {
+ Bandwagon.Logger.debug("This document is on $amo_host, will add bandwagonRefresh listener");
+
+ doc.addEventListener("bandwagonRefresh", Bandwagon.Controller.BrowserOverlay.handleSubscriptionRefreshEvent, true);
+ }
+ }
+ }
+}
+
+Bandwagon.Controller.BrowserOverlay.handleSubscriptionRefreshEvent = function(event)
+{
+ Bandwagon.Logger.info("Received bandwagon subscription refresh event");
+
+ bandwagonService.updateCollectionsList();
+}
+
+Bandwagon.Controller.BrowserOverlay._removeLoadListener = function()
+{
+ window.removeEventListener("load", Bandwagon.init, true);
+}
+
+Bandwagon.Controller.BrowserOverlay.openFirstRunLandingPage = function()
+{
+ Bandwagon.Logger.debug("opening firstrun landing page");
+
+ window.setTimeout(function()
+ {
+ var tab = window.getBrowser().addTab(Bandwagon.FIRSTRUN_LANDING_PAGE);
+ window.getBrowser().selectedTab = tab;
+ },
+ 1000);
+}
+
+/* Toolbar button action - Open add-ons window with Subscriptions tab focused */
+Bandwagon.Controller.BrowserOverlay.openAddons = function()
+{
+ var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
+ .getService(Components.interfaces.nsIWindowMediator);
+ var win = wm.getMostRecentWindow("Extension:Manager");
+ if (win) {
+ win.focus();
+ }
+ else
+ {
+ const EMURL = "chrome://mozapps/content/extensions/extensions.xul";
+ const EMFEATURES = "chrome,menubar,extra-chrome,toolbar,dialog=no,resizable";
+ window.openDialog(EMURL, "", EMFEATURES, "bandwagon-collections");
+ }
+}
+
+Bandwagon.Controller.BrowserOverlay.showNewAddonsAlert = function(collection)
+{
+ Bandwagon.Logger.debug("in showNewAddonsAlert()");
+
+ var bandwagonStrings = document.getElementById("bandwagon-strings");
+
+ var alertsService;
+
+ try
+ {
+ alertsService = Components.classes["@mozilla.org/alerts-service;1"]
+ .getService(Components.interfaces.nsIAlertsService);
+ }
+ catch (e)
+ {
+ Bandwagon.Logger.warn("Can't get a reference to the alerts service on this platform: " + e);
+ return;
+ }
+
+ var unnotifiedCount = collection.getUnnotifiedAddons().length;
+ var collectionName = (collection.name?collection.name:collection.resourceURL);
+ var collectionURL = collection.resourceURL;
+
+ var listener =
+ {
+ observe: function(subject, topic, data)
+ {
+ if (topic == "alertclickcallback")
+ {
+ var collectionURL = data;
+
+ const EMTYPE = "Extension:Manager";
+ var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
+ .getService(Components.interfaces.nsIWindowMediator);
+ var theEM = wm.getMostRecentWindow(EMTYPE);
+
+ if (theEM)
+ {
+ theEM.focus();
+ theEM.showView('bandwagon-collections');
+
+ // if the em is open, select the bandwagon-collections pane, but don't select the collection itself.
+ // the user will be notified by the unread count in the left hand side bar
+
+ //theEM.setTimeout(function() { Bandwagon.Controller.CollectionsPane._selectCollection(collection); }, 500);
+ }
+ else
+ {
+ const EMURL = "chrome://mozapps/content/extensions/extensions.xul";
+ const EMFEATURES = "chrome,menubar,extra-chrome,toolbar,dialog=no,resizable";
+
+ // the em is not open - open it, and select this collection
+
+ if (window)
+ window.openDialog(EMURL, "", EMFEATURES, {selectCollection: collectionURL});
+ else
+ Bandwagon.Logger.error("No browser windows open - can't open EM");
+ }
+
+ }
+ }
+ }
+
+ try
+ {
+ alertsService.showAlertNotification(
+ "chrome://bandwagon/skin/images/icon32.png",
+ bandwagonStrings.getString("newaddons.alert.title"),
+ bandwagonStrings.getFormattedString("newaddons.alert.text", [collectionName]),
+ true,
+ collectionURL,
+ listener
+ );
+ }
+ catch (e)
+ {
+ Bandwagon.Logger.warn("Error showing alert notification on this platform: " + e);
+ }
+}
+
+window.addEventListener("load", Bandwagon.Controller.BrowserOverlay.initBandwagon, true);
+
diff --git a/bandwagon/content/ui/overlays/extensionsOverlay.xul b/bandwagon/content/ui/overlays/extensionsOverlay.xul
new file mode 100644
index 0000000..5e1ddf2
--- /dev/null
+++ b/bandwagon/content/ui/overlays/extensionsOverlay.xul
@@ -0,0 +1,220 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!-- ***** BEGIN LICENSE BLOCK *****
+ - Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ -
+ - The contents of this file are subject to the Mozilla Public License Version
+ - 1.1 (the "License"); you may not use this file except in compliance with
+ - the License. You may obtain a copy of the License at
+ - http://www.mozilla.org/MPL/
+ -
+ - Software distributed under the License is distributed on an "AS IS" basis,
+ - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ - for the specific language governing rights and limitations under the
+ - License.
+ -
+ - The Original Code is bandwagon.
+ -
+ - The Initial Developer of the Original Code is
+ - Mozilla Corporation.
+ - Portions created by the Initial Developer are Copyright (C) 2008
+ - the Initial Developer. All Rights Reserved.
+ -
+ - Contributor(s): David McNamara
+ - Brian King <brian (at) briks (dot) si>
+ -
+ - Alternatively, the contents of this file may be used under the terms of
+ - either the GNU General Public License Version 2 or later (the "GPL"), or
+ - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ - in which case the provisions of the GPL or the LGPL are applicable instead
+ - of those above. If you wish to allow use of your version of this file only
+ - under the terms of either the GPL or the LGPL, and not to allow others to
+ - use your version of this file under the terms of the MPL, indicate your
+ - decision by deleting the provisions above and replace them with the notice
+ - and other provisions required by the GPL or the LGPL. If you do not delete
+ - the provisions above, a recipient may use your version of this file under
+ - the terms of any one of the MPL, the GPL or the LGPL.
+ -
+ - ***** END LICENSE BLOCK ***** -->
+
+<!DOCTYPE overlay SYSTEM "chrome://bandwagon/locale/extensionsOverlay.dtd" >
+
+<?xml-stylesheet href="chrome://bandwagon/skin/global.css" type="text/css"?>
+<?xml-stylesheet href="chrome://bandwagon/skin/extensionsOverlay.css" type="text/css"?>
+<?xml-stylesheet href="chrome://bandwagon/skin/extensionsOverlayIcons.css" type="text/css"?>
+<?xml-stylesheet href="chrome://bandwagon/content/ui/bindings/bandwagon.css" type="text/css"?>
+
+<overlay id="bandwagon-extensions-overlay"
+ xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+
+ <script src="chrome://bandwagon/content/ui/dialog.js"/>
+ <script src="chrome://bandwagon/content/ui/overlays/extensionsOverlayController.js"/>
+ <script src="chrome://bandwagon/content/ui/collectionsPaneController.js"/>
+
+ <stringbundleset>
+ <stringbundle id="bandwagon-strings" src="chrome://bandwagon/locale/extensionOverlay.properties"/>
+ </stringbundleset>
+
+
+ <stack id="topStackBar">
+ <radiogroup id="viewGroup">
+ <radio id="bandwagon-collections-view"
+ label="&collections.label;"
+ insertbefore="extensions-view"
+ oncommand="showView('bandwagon-collections');"
+ persist="last-selected"/>
+ <radio id="search-view"
+ label="&search.label.bandwagon;"
+ insertbefore="updates-view"
+ oncommand="showView('search');"
+ persist="last-selected"/>
+ </radiogroup>
+ </stack>
+
+ <vbox id="extensionsBox">
+ <vbox id="bandwagon-collections-panel" hidden="true" flex="1">
+ <deck id="bandwagon-extensions-deck" flex="1">
+ <hbox id="bandwagon-subscriptions-panel" flex="1">
+ <vbox id="bandwagon-collections-list-box" persist="width">
+ <richlistbox id="bandwagon-collections-list"
+ seltype="single"
+ style="min-width: 14em; width: 16em; max-width: 36em;"
+ flex="1"/>
+ <toolbox class="bandwagon-collections-toolbox">
+ <toolbar pack="start"
+ align="center">
+ <toolbarbutton id="bandwagon-button-subscribe"
+ tooltiptext="&subscribe.label;"
+ oncommand="Bandwagon.Controller.CollectionsPane.doSubscribe();"/>
+ <toolbarbutton id="bandwagon-button-update-all"
+ tooltiptext="&reload.label;"
+ oncommand="Bandwagon.Controller.CollectionsPane.doUpdateAll();"/>
+ <toolbarbutton id="bandwagon-button-settings"
+ tooltiptext="&settings.label;"
+ oncommand="Bandwagon.Controller.CollectionsPane.doSettings();"/>
+ </toolbar>
+ </toolbox>
+ </vbox>
+ <splitter id="bandwagon-sidebar-splitter" />
+ <notificationbox flex="1" id="bandwagon-collections-notification">
+ <hbox align="center">
+ <vbox>
+ <description id="bandwagon-collection-title"/>
+ </vbox>
+ <spacer flex="1"/>
+ <hbox pack="end">
+ <label id="bandwagon-button-viewsite"
+ value="&view.label;"
+ class="text-link"
+ onclick="Bandwagon.Controller.CollectionsPane.doViewSite();"/>
+ <separator id="bandwagon-link-splitter"/>
+ <label id="bandwagon-button-remove"
+ value="&unsubscribe.label;"
+ class="text-link"
+ onclick="Bandwagon.Controller.CollectionsPane.doUnsubscribe();"/>
+ </hbox>
+ </hbox>
+ <vbox>
+ <description id="bandwagon-collection-description"/>
+ </vbox>
+ <deck id="bandwagon-collection-deck" selectedIndex="0" flex="1">
+ <hbox flex="1">
+ <richlistbox id="bandwagon-addons-list"
+ seltype="single"
+ flex="1"
+ ondragenter="nsDragAndDrop.dragEnter(event, gExtensionsDNDObserver);"
+ ondragover="nsDragAndDrop.dragOver(event, gExtensionsDNDObserver);"
+ ondragdrop="nsDragAndDrop.drop(event, gExtensionsDNDObserver);"
+ />
+ </hbox>
+ <vbox flex="1" align="center" pack="center">
+ <label class="usercollectionback" value="&collectionisloading.label;"/>
+ <image src="chrome://bandwagon/skin/images/spinner.gif"/>
+ </vbox>
+ <vbox flex="1" align="center" pack="center">
+ <image src="chrome://bandwagon/skin/images/information.png"/>
+ <label class="usercollectionback" value="&collectionhasnoitems.label;"/>
+ </vbox>
+ <vbox flex="1" align="center" pack="center">
+ <image src="chrome://bandwagon/skin/images/error.png"/>
+ <label class="usercollectionback" value="&collectionhaserror.label;"/>
+ </vbox>
+ </deck>
+ </notificationbox>
+ </hbox>
+ <vbox id="nosubs-box" class="fs-info-panel" flex="1" >
+ <label id="nosubs-header" class="fs-info-panel-header" value="&nocollectionstitle.label;"/>
+ <separator/>
+ <description class="fs-info-panel-text">&nocollectionssubscribed.label;</description>
+ <separator/>
+ <hbox pack="center">
+ <button label="&clicktosubscribe.label;"
+ oncommand="Bandwagon.Controller.CollectionsPane.doSubscribe();"/>
+ </hbox>
+ </vbox>
+ <vbox id="no-amo-auth-box" class="fs-info-panel" flex="1">
+ <vbox align="start">
+ <label id="no-amo-auth-header" class="fs-info-panel-header" value="&nocollectionstitle.label;"/>
+ <separator/>
+ <description class="fs-info-panel-text">&noamoauth.label;</description>
+ <separator/>
+ </vbox>
+
+ <hbox>
+ <hbox align="start" pack="center">
+ <image src="chrome://bandwagon/skin/images/logo-login.png"/>
+ </hbox>
+ <vbox align="center">
+ <description class="bold-text">
+ &loginheading.label;
+ </description>
+ <separator class="thin"/>
+ <grid>
+ <columns>
+ <column/>
+ <column/>
+ </columns>
+
+ <rows>
+ <row align="center">
+ <label value="&username.label;" style="text-align:right;"/>
+ <textbox id="login"
+ onkeypress="if ((event.keyCode == KeyEvent.DOM_VK_RETURN) ||
+ (event.keyCode == KeyEvent.DOM_VK_ENTER)) Bandwagon.Controller.CollectionsPane.doLogin();"/>
+ </row>
+ <row align="center">
+ <label value="&password.label;" style="text-align:right;"/>
+ <textbox id="password"
+ type="password"
+ onkeypress="if ((event.keyCode == KeyEvent.DOM_VK_RETURN) ||
+ (event.keyCode == KeyEvent.DOM_VK_ENTER)) Bandwagon.Controller.CollectionsPane.doLogin();"/>
+ </row>
+ <row>
+ <hbox/>
+ <hbox>
+ <button id="auth-button" label="&clicktologin.label;"
+ oncommand="Bandwagon.Controller.CollectionsPane.doLogin();"/>
+ <vbox pack="center">
+ <image id="auth-spinner" src="chrome://bandwagon/skin/images/spinner-small.gif" style="visibility: hidden"/>
+ </vbox>
+ </hbox>
+ </row>
+ </rows>
+ </grid>
+ <separator class="thin"/>
+ <label value="&createaccount.label;"
+ class="text-link"
+ onclick="Bandwagon.Controller.ExtensionsOverlay.doCreateAccount();"/>
+ <separator class="thin"/>
+ <hbox pack="center" align="start">
+ <description id="auth-error" class="error-text" collapsed="true"/>
+ </hbox>
+ </vbox>
+ </hbox>
+
+ </vbox>
+ </deck>
+ </vbox>
+ </vbox>
+
+</overlay>
diff --git a/bandwagon/content/ui/overlays/extensionsOverlayController.js b/bandwagon/content/ui/overlays/extensionsOverlayController.js
new file mode 100644
index 0000000..092feac
--- /dev/null
+++ b/bandwagon/content/ui/overlays/extensionsOverlayController.js
@@ -0,0 +1,420 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is bandwagon.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s): David McNamara
+ * Brian King <brian (at) briks (dot) si>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+Bandwagon.Controller.ExtensionsOverlay = new function()
+{
+ this._publishButton = null;
+
+ this.stringBundle = null;
+}
+
+Bandwagon.Controller.ExtensionsOverlay.init = function()
+{
+ Bandwagon.Logger.debug("In Bandwagon.Controller.ExtensionsOverlay.init()");
+
+ Bandwagon.Controller.ExtensionsOverlay.stringBundle = document.getElementById("bandwagon-strings");
+ Bandwagon.Controller.ExtensionsOverlay._invalidatePublishButton();
+
+ // Some themes, e.g. Mac default on FF3, have no images in panel selectors
+ // Some themes have the image on the radio, not the radiogroup
+ // So lets hackily hide ours in that circumstance
+
+ var extView = document.getElementById("extensions-view");
+ var bfv = document.getElementById("bandwagon-collections-view");
+ var lsi = extView.ownerDocument.defaultView.getComputedStyle( extView, '' ).getPropertyCSSValue("list-style-image").cssText;
+
+ if (lsi == "none")
+ {
+ bfv.setAttribute("noimage", "true");
+ }
+ else
+ {
+ bfv.removeAttribute("noimage");
+ }
+
+ // Move Get Add-ons/Search to after Themes
+ Bandwagon.Controller.ExtensionsOverlay._moveSearchTab();
+
+ try
+ {
+ // If we don't do the next call, the Search tab still thinks it is at the start and it causes some display glitches
+ // dmcnamara - this is failing on linux
+ updateVisibilityFlags();
+ } catch (e) {}
+
+ // Add publish button to extension binding when selected
+
+ document.getElementById("extensionsView").addEventListener("select", Bandwagon.Controller.ExtensionsOverlay._stuffPublishUI, true);
+
+ // Bug 470268 - the Add-ons window is too narrow by default, enforce a minimum size
+ // This is a one time only deal, so get/set the pref
+
+ var w = document.documentElement.getAttribute("width");
+ var sized = Bandwagon.Preferences.getPreference("addonswindow.resized");
+
+ if (w < 700 && !sized)
+ {
+ document.documentElement.setAttribute("width", 700);
+ }
+
+ Bandwagon.Preferences.setPreference("addonswindow.resized", true);
+
+ // Handle window arguments
+
+ if (window.arguments)
+ {
+ var inArgs = window.arguments[0];
+
+ if (inArgs)
+ {
+ if (inArgs.selectCollection)
+ {
+ Bandwagon.Logger.debug("Have window argument selectCollection = " + inArgs.selectCollection);
+
+ if (bandwagonService.collections[inArgs.selectCollection])
+ {
+ Bandwagon.Controller.CollectionsPane.preferredCollection = bandwagonService.collections[inArgs.selectCollection];
+ }
+
+ setTimeout(function()
+ {
+ Bandwagon.Controller.ExtensionsOverlay._showCollectionsPaneView();
+ },
+ 500);
+ }
+ }
+ }
+}
+
+Bandwagon.Controller.ExtensionsOverlay.doPublishToCollection = function(collection)
+{
+ Bandwagon.Logger.debug("In Bandwagon.Controller.ExtensionsOverlay.doPublishToCollection() with collection = '" + collection.toString() + "'");
+
+ var extension = Bandwagon.Controller.ExtensionsOverlay._getSelectedExtension();
+
+ var params =
+ {
+ publishType: 1,
+ publishDestination: collection,
+ publishExtension: extension
+ };
+
+ Bandwagon.Controller.ExtensionsOverlay._openPublishDialog(params);
+}
+
+Bandwagon.Controller.ExtensionsOverlay.doRemoveFromCollection = function(collection)
+{
+ var extension = Bandwagon.Controller.ExtensionsOverlay._getSelectedExtension();
+
+ Bandwagon.Logger.debug("In Bandwagon.Controller.ExtensionsOverlay.doRemoveFromCollection() with collection = '" + collection.toString() + "' and extension: name = '" + extension.name + "', guid = '" + extension.guid + "'");
+
+ var promptService = Components.classes["@mozilla.org/embedcomp/prompt-service;1"].getService(Components.interfaces.nsIPromptService);
+ var check = {value: false};
+ var flags = promptService.BUTTON_POS_0 * promptService.BUTTON_TITLE_IS_STRING + promptService.BUTTON_POS_1 * promptService.BUTTON_TITLE_IS_STRING;
+ var button = promptService.confirmEx(
+ window,
+ Bandwagon.Controller.ExtensionsOverlay.stringBundle.getString("publish.remove.title"),
+ Bandwagon.Controller.ExtensionsOverlay.stringBundle.getFormattedString("publish.remove.label", [extension.name, collection.name]),
+ flags,
+ Bandwagon.Controller.ExtensionsOverlay.stringBundle.getString("publish.remove.button0"),
+ Bandwagon.Controller.ExtensionsOverlay.stringBundle.getString("publish.remove.button1"),
+ null,
+ null,
+ check);
+
+ var callback = function(event)
+ {
+ if (!event.isError())
+ {
+ bandwagonService.forceCheckForUpdates(collection);
+ }
+ }
+
+ if (button == 0)
+ {
+ bandwagonService.removeAddonFromCollection(extension.guid, collection, callback);
+ }
+}
+
+Bandwagon.Controller.ExtensionsOverlay.doShareToEmail = function(emailAddress)
+{
+ Bandwagon.Logger.debug("In Bandwagon.Controller.ExtensionsOverlay.doShareToEmail() with email = '" + emailAddress + "'");
+
+ var extension = Bandwagon.Controller.ExtensionsOverlay._getSelectedExtension();
+
+ var params =
+ {
+ publishType: 2,
+ publishDestination: emailAddress,
+ publishExtension: extension
+ };
+
+ Bandwagon.Controller.ExtensionsOverlay._openPublishDialog(params);
+}
+
+Bandwagon.Controller.ExtensionsOverlay._getSelectedExtension = function()
+{
+ var extension = {guid: "", name: ""};
+
+ if (document.getElementById("extensionsView").selectedItem)
+ {
+ var selectedAddon = document.getElementById("extensionsView").selectedItem;
+ extension.guid = selectedAddon.getAttribute("addonID");
+ extension.name = selectedAddon.getAttribute("name");
+ }
+ else if (Bandwagon.Controller.CollectionsPane && Bandwagon.Controller.CollectionsPane.elemBandwagonAddons && Bandwagon.Controller.CollectionsPane.elemBandwagonAddons.selectedItem)
+ {
+ var selectedAddon = Bandwagon.Controller.CollectionsPane.elemBandwagonAddons.selectedItem;
+ extension.guid = selectedAddon.guid;
+ extension.name = selectedAddon.name;
+ }
+ else
+ {
+ extension.name = "??";
+ }
+
+ return extension;
+}
+
+Bandwagon.Controller.ExtensionsOverlay.doNewCollection = function()
+{
+ Bandwagon.Logger.debug("In Bandwagon.Controller.ExtensionsOverlay.doNewCollection()");
+
+ var extension = Bandwagon.Controller.ExtensionsOverlay._getSelectedExtension();
+
+ if (extension && extension.guid)
+ {
+ Bandwagon.Controller.CollectionsPane._openLocalizedURL(Bandwagon.COLLECTIONSPANE_DO_NEW_COLLECTION_URL + "?guid=" + extension.guid);
+ }
+ else
+ {
+ Bandwagon.Controller.CollectionsPane._openLocalizedURL(Bandwagon.COLLECTIONSPANE_DO_NEW_COLLECTION_URL);
+ }
+}
+
+Bandwagon.Controller.ExtensionsOverlay.doAddNewShareEmail = function()
+{
+ Bandwagon.Logger.debug("In Bandwagon.Controller.ExtensionsOverlay.doAddNewShareEmail()");
+
+ var extension = Bandwagon.Controller.ExtensionsOverlay._getSelectedExtension();
+
+ var params =
+ {
+ publishType: 3,
+ publishDestination: null,
+ publishExtension: extension
+ };
+
+ Bandwagon.Controller.ExtensionsOverlay._openPublishDialog(params);
+
+ Bandwagon.Controller.ExtensionsOverlay._invalidatePublishButton();
+}
+
+Bandwagon.Controller.ExtensionsOverlay.doCreateAccount = function()
+{
+ Bandwagon.Controller.CollectionsPane._openLocalizedURL(Bandwagon.LOGINPANE_DO_NEW_ACCOUNT);
+}
+
+Bandwagon.Controller.ExtensionsOverlay._openPublishDialog = function(params)
+{
+ window.openDialog("chrome://bandwagon/content/ui/publish.xul", "",
+ "chrome,titlebar,centerscreen,modal", params);
+}
+
+Bandwagon.Controller.ExtensionsOverlay._moveSearchTab = function()
+{
+ var parNode = document.getElementById("viewGroup");
+ var newNode = document.getElementById("search-view").cloneNode(false);
+ var refNode = document.getElementById("updates-view");
+ var insertedNode = parNode.insertBefore(newNode, refNode);
+ parNode.removeChild(parNode.firstChild);
+}
+
+Bandwagon.Controller.ExtensionsOverlay._stuffPublishUI = function()
+{
+ var elemExtension = document.getElementById("extensionsView").selectedItem;
+
+ if (!elemExtension)
+ return;
+
+ var elemSelectedButtons = document.getAnonymousElementByAttribute(elemExtension, "anonid", "selectedButtons");
+
+ if (!elemSelectedButtons)
+ return;
+
+ // No publish for plugins and items that can't be updated, the latter includes the default theme
+ if (elemExtension.getAttribute("plugin") == "true" || elemExtension.getAttribute("updateable") == "false")
+ return;
+
+ if (Bandwagon.Controller.ExtensionsOverlay._publishButton && Bandwagon.Controller.ExtensionsOverlay._publishButton.parentNode)
+ {
+ Bandwagon.Controller.ExtensionsOverlay._publishButton.parentNode.removeChild(Bandwagon.Controller.ExtensionsOverlay._publishButton);
+ }
+
+ Bandwagon.Controller.ExtensionsOverlay._invalidatePublishButton();
+
+ for (var i=0; i<elemSelectedButtons.childNodes.length; i++)
+ {
+ if (elemSelectedButtons.childNodes[i]
+ && elemSelectedButtons.childNodes[i].nodeType == Node.ELEMENT_NODE
+ && (elemSelectedButtons.childNodes[i].getAttribute("class").match(/enableButton/)
+ || elemSelectedButtons.childNodes[i].getAttribute("class").match(/addonInstallButton/)))
+ {
+ elemSelectedButtons.insertBefore(Bandwagon.Controller.ExtensionsOverlay._publishButton,
+ elemSelectedButtons.childNodes[i]);
+ break;
+ }
+ }
+}
+
+Bandwagon.Controller.ExtensionsOverlay._invalidatePublishButton = function()
+{
+ if (!Bandwagon.Controller.ExtensionsOverlay._publishButton)
+ {
+ Bandwagon.Controller.ExtensionsOverlay._publishButton = document.createElement("bandwagonPublishButton");
+ }
+
+ Bandwagon.Controller.ExtensionsOverlay._publishButton.emailAddresses = Bandwagon.Controller.ExtensionsOverlay._getEmailAddresses();
+ Bandwagon.Controller.ExtensionsOverlay._publishButton.writableCollections = Bandwagon.Controller.ExtensionsOverlay._getWritableCollections();
+
+ try
+ {
+ Bandwagon.Controller.ExtensionsOverlay._publishButton.invalidate();
+ }
+ catch (e) {}
+}
+
+Bandwagon.Controller.ExtensionsOverlay._getWritableCollections = function()
+{
+ var writableCollections = [];
+
+ var extension = Bandwagon.Controller.ExtensionsOverlay._getSelectedExtension();
+
+ for (var id in bandwagonService.collections)
+ {
+ var collection = bandwagonService.collections[id];
+
+ //if (1 || (bandwagonService.collections[id].writable && !bandwagonService.collections[id].preview))
+
+ if (collection.writable)
+ {
+ // Check if extension is in collection
+ collection.__containsCurrentlySelectedExtension = false;
+
+ for (var id in collection.addons)
+ {
+ if (extension.guid == collection.addons[id].guid)
+ {
+ collection.__containsCurrentlySelectedExtension = true;
+ break;
+ }
+ }
+
+ writableCollections.push(collection);
+ }
+ }
+
+ writableCollections.sort();
+
+ return writableCollections;
+}
+
+Bandwagon.Controller.ExtensionsOverlay._getEmailAddresses = function()
+{
+ var previouslySharedEmailAddresses = bandwagonService.getPreviouslySharedEmailAddresses();
+
+ previouslySharedEmailAddresses.sort();
+
+ return previouslySharedEmailAddresses;
+}
+
+Bandwagon.Controller.ExtensionsOverlay._showCollectionsPaneView = function()
+{
+ Bandwagon.Logger.debug("in _showCollectionsPaneView()");
+
+ updateLastSelected("bandwagon-collections");
+ gView = "bandwagon-collections";
+
+ document.getElementById("installFileButton").hidden = true;
+ document.getElementById("checkUpdatesAllButton").hidden = true;
+ document.getElementById("installUpdatesAllButton").hidden = true;
+ document.getElementById("skipDialogButton").hidden = true;
+ document.getElementById("continueDialogButton").hidden = true;
+ document.getElementById("themePreviewArea").hidden = true;
+ document.getElementById("themeSplitter").hidden = true;
+ document.getElementById("showUpdateInfoButton").hidden = true;
+ document.getElementById("hideUpdateInfoButton").hidden = true;
+ document.getElementById("searchPanel").hidden = true;
+ document.getElementById("extensionsView").hidden = true;
+ document.getElementById("extensionsView").parentNode.hidden = true;
+
+ document.getElementById("continueDialogButton").removeAttribute("default");
+ document.getElementById("installUpdatesAllButton").removeAttribute("default");
+
+ AddonsViewBuilder.clearChildren(gExtensionsView);
+
+ document.getElementById("bandwagon-collections-panel").hidden = false;
+
+ updateGlobalCommands();
+
+ Bandwagon.Controller.CollectionsPane.init();
+ Bandwagon.Controller.CollectionsPane.onViewSelect();
+}
+
+// magic
+
+Bandwagon.Controller.ExtensionsOverlay._defaultShowView = showView;
+
+Bandwagon.Controller.ExtensionsOverlay._showView = function(aView)
+{
+ if (aView == "bandwagon-collections")
+ {
+ Bandwagon.Controller.ExtensionsOverlay._showCollectionsPaneView();
+ }
+ else
+ {
+ document.getElementById("bandwagon-collections-panel").hidden = true;
+ document.getElementById("extensionsView").hidden = false;
+ document.getElementById("extensionsView").parentNode.hidden = false;
+
+ Bandwagon.Controller.ExtensionsOverlay._defaultShowView(aView);
+ }
+}
+
+showView = Bandwagon.Controller.ExtensionsOverlay._showView;
+
+window.addEventListener("load", Bandwagon.Controller.ExtensionsOverlay.init, true);
diff --git a/bandwagon/content/ui/publish.xul b/bandwagon/content/ui/publish.xul
new file mode 100644
index 0000000..5718eb3
--- /dev/null
+++ b/bandwagon/content/ui/publish.xul
@@ -0,0 +1,96 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- ***** BEGIN LICENSE BLOCK *****
+ - Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ -
+ - The contents of this file are subject to the Mozilla Public License Version
+ - 1.1 (the "License"); you may not use this file except in compliance with
+ - the License. You may obtain a copy of the License at
+ - http://www.mozilla.org/MPL/
+ -
+ - Software distributed under the License is distributed on an "AS IS" basis,
+ - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ - for the specific language governing rights and limitations under the
+ - License.
+ -
+ - The Original Code is bandwagon.
+ -
+ - The Initial Developer of the Original Code is
+ - Mozilla Corporation.
+ - Portions created by the Initial Developer are Copyright (C) 2008
+ - the Initial Developer. All Rights Reserved.
+ -
+ - Contributor(s): David McNamara
+ - Brian King <brian (at) briks (dot) si>
+ -
+ - Alternatively, the contents of this file may be used under the terms of
+ - either the GNU General Public License Version 2 or later (the "GPL"), or
+ - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ - in which case the provisions of the GPL or the LGPL are applicable instead
+ - of those above. If you wish to allow use of your version of this file only
+ - under the terms of either the GPL or the LGPL, and not to allow others to
+ - use your version of this file under the terms of the MPL, indicate your
+ - decision by deleting the provisions above and replace them with the notice
+ - and other provisions required by the GPL or the LGPL. If you do not delete
+ - the provisions above, a recipient may use your version of this file under
+ - the terms of any one of the MPL, the GPL or the LGPL.
+ -
+ - ***** END LICENSE BLOCK ***** -->
+
+<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
+<?xml-stylesheet href="chrome://bandwagon/skin/publish.css" type="text/css"?>
+
+<!DOCTYPE dialog SYSTEM "chrome://bandwagon/locale/publish.dtd">
+
+<dialog id="bandwagon-publish"
+ windowtype="Bandwagon:Publish"
+ xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+ title="&window.title;"
+ style="&publish.style;"
+ buttons="accept,cancel"
+ buttonlabelcancel="&cancel.label;"
+ buttonlabelaccept="&publish.label;"
+ ondialogaccept="return Bandwagon.Controller.Publish.doAccept();"
+ ondialogcancel="return Bandwagon.Controller.Publish.doCancel();">
+
+ <script src="chrome://bandwagon/content/ui/dialog.js"/>
+ <script src="chrome://bandwagon/content/ui/publishController.js"/>
+
+ <stringbundle id="bandwagon-strings" src="chrome://bandwagon/locale/publish.properties"/>
+
+ <vbox>
+ <!--<label id="dialog-desc"/>-->
+
+ <deck id="type-deck">
+ <hbox id="publishing-to-box">
+ <label id="publishing-to" class="dialog-header"/>
+ </hbox>
+
+ <hbox id="sharing-with-box">
+ <description id="sharing-with" class="dialog-header" flex="1"/>
+ </hbox>
+
+ <groupbox id="new-email-box">
+ <caption label="&new.email.label;"/>
+ <label value="&enter.an.email.label;"/>
+ <textbox id="email-address"/>
+ <checkbox id="remember-email" label="&remember.this.email.label;" checked="true"/>
+ </groupbox>
+ </deck>
+
+ <separator class="thin"/>
+
+ <description flex="1" id="personal-email-note-label">&enter.a.personal.note.label;</description>
+ <description flex="1" id="personal-publish-note-label" collapsed="true"/>
+
+ <textbox id="personal-note" multiline="true"/>
+
+ <description id="sharing-with-new" flex="1"/>
+
+ <hbox pack="start" align="center">
+ <image id="spinner" src="chrome://bandwagon/skin/images/spinner-small.gif" collapsed="true"/>
+ <description id="error" style="color: red; visibility: hidden; height: 2em;" flex="1"/>
+ </hbox>
+
+ </vbox>
+
+</dialog>
diff --git a/bandwagon/content/ui/publishController.js b/bandwagon/content/ui/publishController.js
new file mode 100644
index 0000000..f8c805e
--- /dev/null
+++ b/bandwagon/content/ui/publishController.js
@@ -0,0 +1,261 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is bandwagon.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s): David McNamara
+ * Brian King <brian (at) briks (dot) si>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+Bandwagon.Controller.Publish = new function()
+{
+ this.stringBundle = null;
+ this.hasSubmitted = false;
+ this.hasSubmittedWithSuccess = false;
+
+ this.publishType = -1; // one of the TYPE_ constants
+ this.publishDestination = null; // email address or collection obj
+ this.publishExtension = null; // the add-on / theme obj to publish
+}
+
+Bandwagon.Controller.Publish.TYPE_COLLECTION = 1;
+Bandwagon.Controller.Publish.TYPE_EXISTING_EMAIL = 2;
+Bandwagon.Controller.Publish.TYPE_NEW_EMAIL = 3;
+
+Bandwagon.Controller.Publish.init = function()
+{
+ Bandwagon.Logger.debug("Initializing Bandwagon.Controller.Publish");
+
+ Bandwagon.Controller.Publish.stringBundle = document.getElementById("bandwagon-strings");
+
+ // Handle window arguments
+
+ var inArgs = window.arguments[0];
+
+ Bandwagon.Controller.Publish.publishType = inArgs.publishType;
+ Bandwagon.Controller.Publish.publishDestination = inArgs.publishDestination;
+ Bandwagon.Controller.Publish.publishExtension = inArgs.publishExtension;
+
+ //document.getElementById("dialog-desc").value = Bandwagon.Controller.Publish.stringBundle.getFormattedString("you.are.sharing.the.add.on", [Bandwagon.Controller.Publish.publishExtension.name]);
+ document.getElementById("type-deck").selectedIndex = Bandwagon.Controller.Publish.publishType-1;
+
+ // l10n fallback (bug 493654)
+ try
+ {
+ document.getElementById("personal-publish-note-label").textContent = Bandwagon.Controller.Publish.stringBundle.getString("enter.a.personal.publish.note.label");
+ }
+ catch (e)
+ {
+ document.getElementById("personal-publish-note-label").textContent = document.getElementById("personal-email-note-label").textContent;
+ }
+
+ switch (Bandwagon.Controller.Publish.publishType)
+ {
+ case Bandwagon.Controller.Publish.TYPE_COLLECTION:
+ document.getElementById("publishing-to").value = Bandwagon.Controller.Publish.stringBundle.getFormattedString("publishing.to", [Bandwagon.Controller.Publish.publishExtension.name, (Bandwagon.Controller.Publish.publishDestination.name?Bandwagon.Controller.Publish.publishDestination.name:Bandwagon.Controller.Publish.publishDestination.url)]);
+ document.getElementById("new-email-box").collapsed = true;
+ document.getElementById("sharing-with-box").collapsed = true;
+ document.getElementById("publishing-to-box").collapsed = false;
+ document.getElementById("sharing-with-new").collapsed = true;
+ document.getElementById("personal-email-note-label").collapsed = true;
+ document.getElementById("personal-publish-note-label").collapsed = false;
+ break;
+ case Bandwagon.Controller.Publish.TYPE_EXISTING_EMAIL:
+ document.getElementById("sharing-with").textContent = Bandwagon.Controller.Publish.stringBundle.getFormattedString("sharing.with", [Bandwagon.Controller.Publish.publishDestination, Bandwagon.Controller.Publish.publishExtension.name]);
+ document.getElementById("new-email-box").collapsed = true;
+ document.getElementById("sharing-with-box").collapsed = false;
+ document.getElementById("publishing-to-box").collapsed = true;
+ document.getElementById("sharing-with-new").collapsed = true;
+ document.getElementById("bandwagon-publish").getButton("accept").label = Bandwagon.Controller.Publish.stringBundle.getString("send.email");
+ break;
+ case Bandwagon.Controller.Publish.TYPE_NEW_EMAIL:
+ document.getElementById("sharing-with-new").textContent = Bandwagon.Controller.Publish.stringBundle.getFormattedString("sharing.with.new", [Bandwagon.Controller.Publish.publishExtension.name]);
+ document.getElementById("sharing-with-new").collapsed = false;
+ document.getElementById("new-email-box").collapsed = false;
+ document.getElementById("sharing-with-box").collapsed = true;
+ document.getElementById("publishing-to-box").collapsed = true;
+ document.getElementById("bandwagon-publish").getButton("accept").label = Bandwagon.Controller.Publish.stringBundle.getString("send.email");
+ break;
+ }
+
+ Bandwagon.Controller.Publish.invalidate();
+}
+
+Bandwagon.Controller.Publish.doAccept = function()
+{
+ Bandwagon.Logger.debug("In Bandwagon.Controller.Publish.doAccept();");
+
+ if (Bandwagon.Controller.Publish.hasSubmittedWithSuccess)
+ {
+ document.getElementById("bandwagon-publish").cancelDialog();
+ return true;
+ }
+
+ if (Bandwagon.Controller.Publish.publishType == Bandwagon.Controller.Publish.TYPE_NEW_EMAIL && document.getElementById("email-address").value == "")
+ {
+ Bandwagon.Controller.Publish._showError(Bandwagon.Controller.Publish.stringBundle.getString("please.enter.an.email.address"));
+ return false;
+ }
+
+ Bandwagon.Controller.Publish.hasSubmitted = true;
+ Bandwagon.Controller.Publish.invalidate();
+
+ switch (Bandwagon.Controller.Publish.publishType)
+ {
+ case Bandwagon.Controller.Publish.TYPE_COLLECTION:
+ Bandwagon.Controller.Publish._publishToCollection();
+ break;
+ case Bandwagon.Controller.Publish.TYPE_EXISTING_EMAIL:
+ Bandwagon.Controller.Publish._shareToExistingEmail();
+ break;
+ case Bandwagon.Controller.Publish.TYPE_NEW_EMAIL:
+ Bandwagon.Controller.Publish._shareToNewEmail();
+ break;
+ }
+
+ return false;
+}
+
+Bandwagon.Controller.Publish.doCancel = function()
+{
+ return true;
+}
+
+Bandwagon.Controller.Publish._publishToCollection = function()
+{
+ bandwagonService.publishToCollection(
+ Bandwagon.Controller.Publish.publishExtension,
+ Bandwagon.Controller.Publish.publishDestination,
+ document.getElementById("personal-note").value,
+ Bandwagon.Controller.Publish.finished
+ );
+}
+
+Bandwagon.Controller.Publish._shareToExistingEmail = function()
+{
+ bandwagonService.shareToEmail(
+ Bandwagon.Controller.Publish.publishExtension,
+ Bandwagon.Controller.Publish.publishDestination,
+ document.getElementById("personal-note").value,
+ Bandwagon.Controller.Publish.finished
+ );
+}
+
+Bandwagon.Controller.Publish._shareToNewEmail = function()
+{
+ bandwagonService.shareToEmail(
+ Bandwagon.Controller.Publish.publishExtension,
+ document.getElementById("email-address").value,
+ document.getElementById("personal-note").value,
+ Bandwagon.Controller.Publish.finished
+ );
+}
+
+Bandwagon.Controller.Publish.invalidate = function()
+{
+ document.getElementById("bandwagon-publish").getButton("accept").disabled = Bandwagon.Controller.Publish.hasSubmitted;
+ document.getElementById("email-address").disabled = Bandwagon.Controller.Publish.hasSubmitted;
+ document.getElementById("personal-note").disabled = Bandwagon.Controller.Publish.hasSubmitted;
+ document.getElementById("spinner").collapsed = !Bandwagon.Controller.Publish.hasSubmitted;
+ document.getElementById("error").style.visibility = "hidden";
+}
+
+Bandwagon.Controller.Publish.finished = function(event)
+{
+ if (event.isError())
+ {
+ Bandwagon.Controller.Publish.hasSubmitted = false;
+ Bandwagon.Controller.Publish.invalidate();
+
+ if (event.getError().getMessage() == "unknown_addon_guid")
+ {
+ Bandwagon.Controller.Publish._showError(Bandwagon.Controller.Publish.stringBundle.getString("error.unknown_addon_guid"));
+ }
+ else if (event.getError().getMessage() == "invalid_parameters")
+ {
+ // L10n fallback (bug 493656)
+ try
+ {
+ Bandwagon.Controller.Publish._showError(Bandwagon.Controller.Publish.stringBundle.getString("error.invalid_parameters"));
+ }
+ catch (e)
+ {
+ Bandwagon.Controller.Publish._showError(event.getError());
+ }
+ }
+ else
+ {
+ Bandwagon.Controller.Publish._showError(event.getError());
+ }
+
+ return;
+ }
+
+ Bandwagon.Controller.Publish.hasSubmittedWithSuccess = true;
+
+ if (Bandwagon.Controller.Publish.publishType == Bandwagon.Controller.Publish.TYPE_NEW_EMAIL
+ && document.getElementById("remember-email").checked)
+ {
+ bandwagonService.addPreviouslySharedEmailAddresses(document.getElementById("email-address").value);
+ }
+
+ if (Bandwagon.Controller.Publish.publishType == Bandwagon.Controller.Publish.TYPE_COLLECTION)
+ {
+ bandwagonService.forceCheckForUpdates(Bandwagon.Controller.Publish.publishDestination);
+
+ document.getElementById("error").textContent = Bandwagon.Controller.Publish.stringBundle.getString("the.addon.has.been.published");
+ }
+ else
+ {
+ document.getElementById("error").textContent = Bandwagon.Controller.Publish.stringBundle.getString("the.email.has.been.sent");
+ }
+
+ document.getElementById("error").style.visibility = "visible";
+ document.getElementById("error").style.color = 'green';
+ document.getElementById("spinner").collapsed = true;
+ document.getElementById("email-address").disabled = true;
+ document.getElementById("personal-note").disabled = true;
+ document.getElementById("bandwagon-publish").getButton("cancel").hidden = true;
+ document.getElementById("bandwagon-publish").getButton("accept").disabled = false;
+ document.getElementById("bandwagon-publish").getButton("accept").label = Bandwagon.Controller.Publish.stringBundle.getFormattedString("closing.in", ["2"]);
+
+ setTimeout(function() { document.getElementById("bandwagon-publish").getButton("accept").label = Bandwagon.Controller.Publish.stringBundle.getFormattedString("closing.in", ["1"]); }, 2000);
+ setTimeout(function() { document.getElementById("bandwagon-publish").cancelDialog(); }, 3000);
+}
+
+Bandwagon.Controller.Publish._showError = function(message)
+{
+ document.getElementById("error").style.visibility = "visible";
+ document.getElementById("error").textContent = message;
+}
+
+window.addEventListener("load", Bandwagon.Controller.Publish.init, true);
+
diff --git a/bandwagon/content/ui/settings.xul b/bandwagon/content/ui/settings.xul
new file mode 100644
index 0000000..53b1934
--- /dev/null
+++ b/bandwagon/content/ui/settings.xul
@@ -0,0 +1,305 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!-- ***** BEGIN LICENSE BLOCK *****
+ - Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ -
+ - The contents of this file are subject to the Mozilla Public License Version
+ - 1.1 (the "License"); you may not use this file except in compliance with
+ - the License. You may obtain a copy of the License at
+ - http://www.mozilla.org/MPL/
+ -
+ - Software distributed under the License is distributed on an "AS IS" basis,
+ - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ - for the specific language governing rights and limitations under the
+ - License.
+ -
+ - The Original Code is bandwagon.
+ -
+ - The Initial Developer of the Original Code is
+ - Mozilla Corporation.
+ - Portions created by the Initial Developer are Copyright (C) 2008
+ - the Initial Developer. All Rights Reserved.
+ -
+ - Contributor(s): David McNamara
+ - Brian King <brian (at) briks (dot) si>
+ -
+ - Alternatively, the contents of this file may be used under the terms of
+ - either the GNU General Public License Version 2 or later (the "GPL"), or
+ - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ - in which case the provisions of the GPL or the LGPL are applicable instead
+ - of those above. If you wish to allow use of your version of this file only
+ - under the terms of either the GPL or the LGPL, and not to allow others to
+ - use your version of this file under the terms of the MPL, indicate your
+ - decision by deleting the provisions above and replace them with the notice
+ - and other provisions required by the GPL or the LGPL. If you do not delete
+ - the provisions above, a recipient may use your version of this file under
+ - the terms of any one of the MPL, the GPL or the LGPL.
+ -
+ - ***** END LICENSE BLOCK ***** -->
+
+<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
+<?xml-stylesheet href="chrome://browser/skin/preferences/preferences.css"?>
+<?xml-stylesheet href="chrome://bandwagon/skin/settings.css" type="text/css"?>
+<?xml-stylesheet href="chrome://bandwagon/skin/settingsIcons.css" type="text/css"?>
+<?xml-stylesheet href="chrome://bandwagon/content/ui/bindings/bandwagon.css" type="text/css"?>
+
+<!DOCTYPE prefwindow SYSTEM "chrome://bandwagon/locale/settings.dtd">
+
+<prefwindow id="bandwagon-settings"
+ xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+ title="&window.title;"
+ ondialogaccept="return Bandwagon.Controller.Settings.doAccept();"
+ ondialogcancel="return Bandwagon.Controller.Settings.doCancel();"
+ persist="lastSelected screenX screenY">
+
+ <prefpane id="paneManage"
+ label="&manage.label;"
+ flex="1">
+ <hbox flex="1">
+ <vbox>
+ <label id="collections-list-header" crop="end" value="&subscriptions.header;"/>
+ <richlistbox id="collections-list" flex="1"/>
+ </vbox>
+ <vbox flex="1">
+ <!-- Update Interval Settings -->
+ <groupbox>
+ <caption label="&frequency.label;"/>
+ <radiogroup id="updates-group">
+ <radio id="updates-default" label="&default.label;"/>
+ <hbox align="center">
+ <radio id="updates-custom" label="&custom.label;"/>
+ <label id="checkbox-updateinterval-percollection" value="&updatesingle.label;"/>
+ <textbox id="textbox-updateinterval-quantity-percollection"
+ type="number"
+ min="1"
+ size="3"
+ maxlength="3"
+ value=""/>
+ <menulist id="menulist-updateinterval-units-percollection"
+ class=""
+ crop="none">
+ <menupopup>
+ <menuitem label="&minutes.label;" value="1"/>
+ <menuitem label="&hours.label;" value="2"/>
+ <menuitem label="&days.label;" value="3"/>
+ </menupopup>
+ </menulist>
+ </hbox>
+ </radiogroup>
+ </groupbox>
+
+ <!-- Show Notification Settings -->
+ <groupbox>
+ <caption label="&notifications.label;"/>
+ <radiogroup id="notifications-group">
+ <radio id="notifications-default" label="&default.label;"/>
+ <hbox>
+ <radio id="notifications-custom" label="&custom.label;"/>
+ <radiogroup id="checkbox-shownotifications-percollection"
+ orient="horizontal">
+ <radio id="shownotifications-percollection-on" label="&on.label;"/>
+ <radio id="shownotifications-percollection-off" label="&off.label;"/>
+ </radiogroup>
+ </hbox>
+ </radiogroup>
+ </groupbox>
+
+ <!-- Add-ons Per Page Settings -->
+ <groupbox id="pagination-box">
+ <caption label="&perpage.label;"/>
+ <radiogroup id="perpage-group">
+ <radio id="perpage-default" label="&default.label;"/>
+ <hbox align="center">
+ <radio id="perpage-custom" label="&custom.label;"/>
+ <label id="label-addonsshow-percollection"> &addonsleadin.label;</label>
+ <textbox id="textbox-addonsperpage-percollection"
+ type="number"
+ size="3"/>
+ <label id="label-addonsperpage-percollection"> &addonsperpage.label;</label>
+ </hbox>
+ </radiogroup>
+ </groupbox>
+
+ <hbox align="center" pack="end">
+ <button id="remove-button"
+ label="&remove.label;"
+ oncommand="Bandwagon.Controller.Settings.doUnsubscribe();"/>
+ </hbox>
+ </vbox>
+ </hbox>
+
+ </prefpane>
+
+ <prefpane id="paneGeneral"
+ label="&general.label;">
+ <preferences>
+ <preference id="extensions.bandwagon.global.addonsperpage"
+ name="extensions.bandwagon.global.addonsperpage"
+ type="int"/>
+ <preference id="extensions.bandwagon.global.update.interval"
+ name="extensions.bandwagon.global.update.interval"
+ type="int"/>
+ <preference id="extensions.bandwagon.global.update.units"
+ name="extensions.bandwagon.global.update.units"
+ type="int"/>
+ <preference id="extensions.bandwagon.global.notify.enabled"
+ name="extensions.bandwagon.global.notify.enabled"
+ type="bool"/>
+ <preference id="extensions.bandwagon.allow.incompatible.install"
+ name="extensions.bandwagon.allow.incompatible.install"
+ type="bool"/>
+ </preferences>
+ <groupbox>
+ <caption label="&subscriptions.label;"/>
+ <hbox align="center">
+ <label id="updateinterval-all" value="&updateall.label;"/>
+ <textbox id="textbox-updateinterval-quantity"
+ type="number"
+ min="1"
+ size="3"
+ maxlength="3"
+ value=""
+ onkeypress=""
+ onchange=""
+ preference="extensions.bandwagon.global.update.interval"/>
+ <menulist id="menulist-updateinterval-units" class="" crop="none" preference="extensions.bandwagon.global.update.units">
+ <menupopup>
+ <menuitem label="&minutes.label;" value="1"/>
+ <menuitem label="&hours.label;" value="2"/>
+ <menuitem label="&days.label;" value="3"/>
+ </menupopup>
+ </menulist>
+ </hbox>
+ <hbox align="center">
+ <label id="notify-all" value="&notifyglobal.label;"/>
+ <radiogroup id="notify-all-group" orient="horizontal" preference="extensions.bandwagon.global.notify.enabled">
+ <radio id="notify-all-on" label="&on.label;" value="true"/>
+ <radio id="notify-all-off" label="&off.label;" value="false"/>
+ </radiogroup>
+ </hbox>
+ <hbox align="center" id="global-pagination-box">
+ <label id="label-addonsshow"> &addonsleadin.label;</label>
+ <textbox id="textbox-addonsperpage-global"
+ type="number"
+ size="3"
+ preference="extensions.bandwagon.global.addonsperpage"/>
+ <label id="label-addonsperpage"> &addonsperpage.label;</label>
+ </hbox>
+ </groupbox>
+
+ <groupbox>
+ <caption label="&data.label;"/>
+ <hbox align="center" pack="start">
+ <label id="clear-emails-text" value="" />
+ <button id="clear-emails-button"
+ label="&clearemails.label;"
+ oncommand="Bandwagon.Controller.Settings.doClearEmails();"/>
+ </hbox>
+ <hbox align="center" pack="start">
+ <label id="login-status-text" value="" />
+ <button id="login-button"
+ label="&login.label;"
+ oncommand="Bandwagon.Controller.Settings.doLogin();"/>
+ <button id="logout-button"
+ label="&logout.label;"
+ oncommand="Bandwagon.Controller.Settings.doLogout();"
+ collapsed="true"/>
+ </hbox>
+ </groupbox>
+
+ <groupbox id="section-enable-on-checkcompatibilty-pref" collapsed="true">
+ <caption label="&misc.label;"/>
+ <checkbox id="allow-incompatible-install" label="&allowincompatibleinstall.label;" preference="extensions.bandwagon.allow.incompatible.install"/>
+ </groupbox>
+ </prefpane>
+
+ <prefpane id="paneAuto"
+ label="&pub.label;">
+ <preferences>
+ <preference id="extensions.bandwagon.local.autopublisher.publish.extensions"
+ name="extensions.bandwagon.local.autopublisher.publish.extensions"
+ type="bool"/>
+ <preference id="extensions.bandwagon.local.autopublisher.publish.themes"
+ name="extensions.bandwagon.local.autopublisher.publish.themes"
+ type="bool"/>
+ <preference id="extensions.bandwagon.local.autopublisher.publish.dictionaries"
+ name="extensions.bandwagon.local.autopublisher.publish.dictionaries"
+ type="bool"/>
+ <preference id="extensions.bandwagon.local.autopublisher.publish.language.packs"
+ name="extensions.bandwagon.local.autopublisher.publish.language.packs"
+ type="bool"/>
+ <preference id="extensions.bandwagon.local.autopublisher.only.publish.enabled"
+ name="extensions.bandwagon.local.autopublisher.only.publish.enabled"
+ type="bool"/>
+ </preferences>
+ <groupbox>
+ <caption label="&auto.label;"/>
+ <description>&autoleadin.label;</description>
+ <separator class="thin"/>
+ <grid>
+ <columns>
+ <column/>
+ <column/>
+ </columns>
+ <rows>
+ <row align="center">
+ <label value="&name.label;"/>
+ <textbox id="auto-name"/>
+ </row>
+ <row align="center">
+ <spacer/>
+ <checkbox id="auto-list" label="&list.label;" checked="true"/>
+ </row>
+ </rows>
+ </grid>
+ <separator class="thin"/>
+ <grid>
+ <columns>
+ <column/>
+ <column/>
+ <column/>
+ </columns>
+ <rows>
+ <row align="center">
+ <label value="&types.label;"/>
+ <checkbox id="auto-type-extensions" label="&type.extensions.label;" preference="extensions.bandwagon.local.autopublisher.publish.extensions"/>
+ <checkbox id="auto-type-themes" label="&type.themes.label;" preference="extensions.bandwagon.local.autopublisher.publish.themes"/>
+ </row>
+ <row align="center">
+ <spacer/>
+ <checkbox id="auto-type-dicts" label="&type.dicts.label;" preference="extensions.bandwagon.local.autopublisher.publish.dictionaries"/>
+ <checkbox id="auto-type-langpacks" label="&type.langpacks.label;" preference="extensions.bandwagon.local.autopublisher.publish.language.packs"/>
+ </row>
+ </rows>
+ </grid>
+ <separator class="thin"/>
+ <checkbox id="auto-only-publish-enabled" label="&onlypublishenabledaddons.label;" preference="extensions.bandwagon.local.autopublisher.only.publish.enabled"/>
+ </groupbox>
+ <hbox class="bottomBox" pack="center">
+ <groupbox id="auto-groupbox" orient="horizontal">
+ <button id="auto-create-button"
+ label="&createauto.label;"
+ oncommand="Bandwagon.Controller.Settings.doCreateAutoPublisher();"/>
+ <button id="auto-update-button"
+ label="&updateauto.label;"
+ oncommand="Bandwagon.Controller.Settings.doUpdateAutoPublisher();"
+ collapsed="true"/>
+ <button id="auto-delete-button"
+ label="&deleteauto.label;"
+ oncommand="Bandwagon.Controller.Settings.doDeleteAutoPublisher();"
+ collapsed="true"/>
+ <vbox pack="center">
+ <image id="auto-spinner" src="chrome://bandwagon/skin/images/spinner-small.gif" collapsed="true"/>
+ </vbox>
+ </groupbox>
+ </hbox>
+ <label id="auto-error" style="color: red;" value=""/>
+ </prefpane>
+
+ <stringbundle id="bandwagon-strings" src="chrome://bandwagon/locale/settings.properties"/>
+ <stringbundle id="bandwagon-strings2" src="chrome://bandwagon/locale/extensionOverlay.properties"/>
+
+ <script type="application/x-javascript" src="chrome://bandwagon/content/ui/dialog.js"/>
+ <script type="application/x-javascript" src="chrome://bandwagon/content/ui/settingsController.js"/>
+
+</prefwindow>
diff --git a/bandwagon/content/ui/settingsController.js b/bandwagon/content/ui/settingsController.js
new file mode 100644
index 0000000..cdd5ed0
--- /dev/null
+++ b/bandwagon/content/ui/settingsController.js
@@ -0,0 +1,807 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is bandwagon.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s): David McNamara
+ * Brian King <brian (at) briks (dot) si>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+Bandwagon.Controller.Settings = new function()
+{
+ this.collections = {};
+
+ this.elemBandwagonCollections = null;
+
+ this.stringBundle = null;
+ this.stringBundle2 = null;
+}
+
+Bandwagon.Controller.Settings.init = function()
+{
+ Bandwagon.Logger.debug("Initializing Bandwagon.Controller.Settings");
+
+ Bandwagon.Controller.Settings.stringBundle = document.getElementById("bandwagon-strings");
+ Bandwagon.Controller.Settings.stringBundle2 = document.getElementById("bandwagon-strings2");
+
+ Bandwagon.Controller.Settings.elemBandwagonCollections = document.getElementById("collections-list");
+ Bandwagon.Controller.Settings.elemBandwagonCollections.addEventListener("select", Bandwagon.Controller.Settings.doShowCollection, true);
+
+ // save the collection when the user chooses between global and collection scoped settings...
+
+ document.getElementById("updates-group").addEventListener("command", Bandwagon.Controller.Settings.doSaveCollection, true);
+ document.getElementById("notifications-group").addEventListener("command", Bandwagon.Controller.Settings.doSaveCollection, true);
+ document.getElementById("perpage-group").addEventListener("command", Bandwagon.Controller.Settings.doSaveCollection, true);
+
+ // ... and when the user changes the collection scoped settings.
+
+ document.getElementById("textbox-updateinterval-quantity-percollection").addEventListener("input", Bandwagon.Controller.Settings.doSaveCollection, true);
+ document.getElementById("textbox-updateinterval-quantity-percollection").addEventListener("command", Bandwagon.Controller.Settings.doSaveCollection, false);
+ document.getElementById("menulist-updateinterval-units-percollection").addEventListener("command", Bandwagon.Controller.Settings.doSaveCollection, true);
+ document.getElementById("checkbox-shownotifications-percollection").addEventListener("command", Bandwagon.Controller.Settings.doSaveCollection, true);
+ document.getElementById("textbox-addonsperpage-percollection").addEventListener("input", Bandwagon.Controller.Settings.doSaveCollection, true);
+ document.getElementById("textbox-addonsperpage-percollection").addEventListener("command", Bandwagon.Controller.Settings.doSaveCollection, true);
+
+ //document.getElementById("updates-group").addEventListener("command", Bandwagon.Controller.Settings.doUpdateIntervalScopeChange, true);
+ //document.getElementById("notifications-group").addEventListener("command", Bandwagon.Controller.Settings.doShowNotificationsScopeChange, true);
+ //document.getElementById("perpage-group").addEventListener("command", Bandwagon.Controller.Settings.doSaveCollection, true);
+
+ bandwagonService.registerCollectionListChangeObserver(Bandwagon.Controller.Settings.collectionListChangeObserver);
+ bandwagonService.registerAuthenticationStatusChangeObserver(Bandwagon.Controller.Settings.authenticationStatusChangeObserver);
+
+ setTimeout(function()
+ {
+ Bandwagon.Controller.Settings._delayedInit();
+ },
+ 10);
+}
+
+Bandwagon.Controller.Settings._delayedInit = function()
+{
+ Bandwagon.Controller.Settings._repopulateCollectionsList();
+
+ Bandwagon.Controller.Settings.invalidateEmails();
+ Bandwagon.Controller.Settings.invalidateLogin();
+ Bandwagon.Controller.Settings.invalidateAutoPublisher();
+ Bandwagon.Controller.Settings.invalidateAllowIncompatibleInstall();
+ Bandwagon.Controller.Settings.invalidateCustomizeCollectionUI();
+ Bandwagon.Controller.Settings.invalidatePaginationSettings();
+ Bandwagon.Controller.Settings.invalidate();
+}
+
+Bandwagon.Controller.Settings.bindingsReady = function()
+{
+ var elemBandwagonCollection = Bandwagon.Controller.Settings.elemBandwagonCollections.getElementsByTagName("bandwagonCollection")[0];
+
+ if (elemBandwagonCollection)
+ {
+ Bandwagon.Controller.Settings.elemBandwagonCollections.selectItem(elemBandwagonCollection);
+ Bandwagon.Controller.Settings.elemBandwagonCollections.focus();
+ }
+}
+
+Bandwagon.Controller.Settings.uninit = function()
+{
+ bandwagonService.unregisterCollectionListChangeObserver(Bandwagon.Controller.Settings.collectionListChangeObserver);
+ bandwagonService.unregisterAuthenticationStatusChangeObserver(Bandwagon.Controller.Settings.authenticationStatusChangeObserver);
+
+ // now is a good time to save collections to storage
+ if (Bandwagon.COMMIT_NOW)
+ bandwagonService.commitAll();
+}
+
+Bandwagon.Controller.Settings.collectionListChangeObserver = function()
+{
+ Bandwagon.Controller.Settings._repopulateCollectionsList();
+
+ var elemBandwagonCollection = Bandwagon.Controller.Settings.elemBandwagonCollections.getElementsByTagName("bandwagonCollection")[0];
+
+ if (elemBandwagonCollection)
+ {
+ Bandwagon.Controller.Settings.elemBandwagonCollections.selectItem(elemBandwagonCollection);
+ Bandwagon.Controller.Settings.elemBandwagonCollections.focus();
+ }
+ else
+ {
+ Bandwagon.Controller.Settings.doShowCollection();
+ }
+
+ Bandwagon.Controller.Settings.invalidate();
+}
+
+Bandwagon.Controller.Settings.authenticationStatusChangeObserver = function()
+{
+ Bandwagon.Controller.Settings.invalidateLogin();
+ Bandwagon.Controller.Settings.invalidate();
+}
+
+Bandwagon.Controller.Settings.invalidate = function()
+{
+ var collectionCount = Bandwagon.Controller.Settings.elemBandwagonCollections.getElementsByTagName("bandwagonCollection").length;
+ var collectionSelection = Bandwagon.Controller.Settings.elemBandwagonCollections.selectedItem;
+
+ var disabled = (!collectionSelection || collectionCount == 0);
+
+ document.getElementById("remove-button").disabled = disabled;
+ document.getElementById("updates-group").disabled = disabled;
+ document.getElementById("textbox-updateinterval-quantity-percollection").disabled = disabled;
+ document.getElementById("menulist-updateinterval-units-percollection").disabled = disabled;
+ document.getElementById("notifications-group").disabled = disabled;
+ document.getElementById("label-addonsshow-percollection").disabled = disabled;
+ document.getElementById("label-addonsperpage-percollection").disabled = disabled;
+ document.getElementById("textbox-addonsperpage-percollection").disabled = disabled;
+ document.getElementById("perpage-default").disabled = disabled;
+ document.getElementById("perpage-custom").disabled = disabled;
+}
+
+Bandwagon.Controller.Settings.invalidatePaginationSettings = function()
+{
+ document.getElementById("pagination-box").collapsed = (Bandwagon.ENABLE_PAGINATION?false:true);
+ document.getElementById("global-pagination-box").collapsed = (Bandwagon.ENABLE_PAGINATION?false:true);
+}
+
+Bandwagon.Controller.Settings.invalidateCustomizeCollectionUI = function()
+{
+ document.getElementById("textbox-updateinterval-quantity-percollection").disabled = (document.getElementById("updates-group").selectedIndex == 0);
+ document.getElementById("menulist-updateinterval-units-percollection").disabled = (document.getElementById("updates-group").selectedIndex == 0);
+ document.getElementById("checkbox-updateinterval-percollection").disabled = (document.getElementById("updates-group").selectedIndex == 0);
+
+ document.getElementById("checkbox-shownotifications-percollection").disabled = (document.getElementById("notifications-group").selectedIndex == 0);
+
+ document.getElementById("label-addonsshow-percollection").disabled = (document.getElementById("perpage-group").selectedIndex == 0);
+ document.getElementById("textbox-addonsperpage-percollection").disabled = (document.getElementById("perpage-group").selectedIndex == 0);
+ document.getElementById("label-addonsperpage-percollection").disabled = (document.getElementById("perpage-group").selectedIndex == 0);
+}
+
+Bandwagon.Controller.Settings.invalidateLogin = function()
+{
+ var isLoggedIn = bandwagonService.isAuthenticated();
+
+ if (isLoggedIn)
+ {
+ var loginEmail = Bandwagon.Preferences.getPreference("login");
+ document.getElementById("login-status-text").value = Bandwagon.Controller.Settings.stringBundle.getFormattedString("login.status.with.email", [loginEmail]);
+
+ document.getElementById("login-button").collapsed = true;
+ document.getElementById("logout-button").removeAttribute("collapsed");
+ }
+ else
+ {
+ document.getElementById("login-status-text").value = Bandwagon.Controller.Settings.stringBundle.getString("logout.status");
+ document.getElementById("login-button").removeAttribute("collapsed");
+ document.getElementById("logout-button").collapsed = true;
+
+ while (Bandwagon.Controller.Settings.elemBandwagonCollections.hasChildNodes())
+ {
+ Bandwagon.Controller.Settings.elemBandwagonCollections.removeChild(Bandwagon.Controller.Settings.elemBandwagonCollections.firstChild);
+ }
+ }
+
+ document.getElementById("auto-name").disabled = !isLoggedIn;
+ document.getElementById("auto-create-button").disabled = !isLoggedIn;
+ document.getElementById("auto-delete-button").disabled = !isLoggedIn;
+ document.getElementById("auto-update-button").disabled = !isLoggedIn;
+ document.getElementById("auto-list").disabled = !isLoggedIn;
+ document.getElementById("auto-only-publish-enabled").disabled = !isLoggedIn;
+ document.getElementById("auto-type-extensions").disabled = !isLoggedIn;
+ document.getElementById("auto-type-themes").disabled = !isLoggedIn;
+ document.getElementById("auto-type-dicts").disabled = !isLoggedIn;
+ document.getElementById("auto-type-langpacks").disabled = !isLoggedIn;
+}
+
+Bandwagon.Controller.Settings.invalidateAutoPublisher = function()
+{
+ var localAutoPublisher = bandwagonService.getLocalAutoPublisher();
+
+ if (localAutoPublisher != null)
+ {
+ document.getElementById("auto-spinner").collapsed = true;
+ document.getElementById("auto-create-button").collapsed = true;
+ document.getElementById("auto-delete-button").removeAttribute("collapsed");
+ document.getElementById("auto-update-button").removeAttribute("collapsed");
+ document.getElementById("auto-name").value = localAutoPublisher.name;
+ document.getElementById("auto-list").checked = localAutoPublisher.listed;
+ }
+}
+
+Bandwagon.Controller.Settings.invalidateAllowIncompatibleInstall = function()
+{
+ var isExtensionsCheckCompatibility = Bandwagon.Preferences.getGlobalPreference("extensions.checkCompatibility", true);
+
+ if (isExtensionsCheckCompatibility == null || isExtensionsCheckCompatibility == true)
+ {
+ document.getElementById("section-enable-on-checkcompatibilty-pref").setAttribute("collapsed", true);
+ }
+ else
+ {
+ document.getElementById("section-enable-on-checkcompatibilty-pref").removeAttribute("collapsed");
+ }
+}
+
+Bandwagon.Controller.Settings.invalidateEmails = function()
+{
+ var previouslySharedEmailAddresses = bandwagonService.getPreviouslySharedEmailAddresses();
+
+ document.getElementById("clear-emails-text").value = Bandwagon.Controller.Settings.stringBundle.getFormattedString("saved.emails.text", [previouslySharedEmailAddresses.length]);
+ document.getElementById("clear-emails-button").disabled = (previouslySharedEmailAddresses.length == 0);
+}
+
+Bandwagon.Controller.Settings.doShowCollection = function()
+{
+ var collection = null;
+ var selectedItem = Bandwagon.Controller.Settings.elemBandwagonCollections.selectedItem;
+
+ if (selectedItem && Bandwagon.Controller.Settings.elemBandwagonCollections.selectedItem.collection)
+ collection = Bandwagon.Controller.Settings.collections[Bandwagon.Controller.Settings.elemBandwagonCollections.selectedItem.collection.resourceURL];
+
+ Bandwagon.Logger.debug("showing collection: " + (collection?collection.name:"<none>"));
+
+ Bandwagon.Controller.Settings.invalidateCustomizeCollectionUI();
+
+ if (!collection)
+ {
+ Bandwagon.Controller.Settings.invalidate();
+ return;
+ }
+
+ // ui defaults for customizing go here
+
+ document.getElementById("textbox-updateinterval-quantity-percollection").value = document.getElementById("textbox-updateinterval-quantity").value;
+ document.getElementById("menulist-updateinterval-units-percollection").selectedIndex = document.getElementById("menulist-updateinterval-units").selectedIndex;
+ document.getElementById("checkbox-shownotifications-percollection").selectedIndex = document.getElementById("notify-all-group").selectedIndex;
+ document.getElementById("textbox-addonsperpage-percollection").value = document.getElementById("textbox-addonsperpage-global").value;
+
+ // customized update interval for this collection?
+
+ if (collection.updateInterval == -1)
+ {
+ document.getElementById("updates-group").selectedIndex = 0;
+ }
+ else
+ {
+ document.getElementById("updates-group").selectedIndex = 1;
+
+ var interval = Bandwagon.Util.intervalMillisecondsToUnits(collection.updateInterval*1000);
+ document.getElementById("textbox-updateinterval-quantity-percollection").valueNumber = interval.interval;
+ document.getElementById("menulist-updateinterval-units-percollection").selectedIndex = interval.units-1;
+ }
+
+ // customized notifications setting for this collection?
+
+ if (collection.showNotifications == -1)
+ {
+ document.getElementById("notifications-group").selectedIndex = 0;
+ }
+ else
+ {
+ document.getElementById("notifications-group").selectedIndex = 1;
+
+ if (collection.showNotifications == 1)
+ {
+ document.getElementById("checkbox-shownotifications-percollection").selectedIndex = 0;
+ }
+ else
+ {
+ document.getElementById("checkbox-shownotifications-percollection").selectedIndex = 1;
+ }
+ }
+
+ // customized addonsperpage setting for this collection?
+
+ if (collection.addonsPerPage == -1)
+ {
+ document.getElementById("perpage-group").selectedIndex = 0;
+ }
+ else
+ {
+ document.getElementById("perpage-group").selectedIndex = 1;
+
+ document.getElementById("textbox-addonsperpage-percollection").value = collection.addonsPerPage;
+ }
+
+ Bandwagon.Controller.Settings.invalidate();
+ Bandwagon.Controller.Settings.invalidateCustomizeCollectionUI();
+}
+
+Bandwagon.Controller.Settings.doSaveCollection = function()
+{
+ Bandwagon.Logger.debug("in doSaveCollection()");
+
+ // save settings to local copy of the collection objects
+
+ var collection = Bandwagon.Controller.Settings.collections[Bandwagon.Controller.Settings.elemBandwagonCollections.selectedItem.collection.resourceURL];
+
+ if (!collection)
+ return;
+
+ // save update interval
+
+ if (document.getElementById("updates-group").selectedIndex == 0)
+ {
+ collection.updateInterval = -1;
+ }
+ else
+ {
+ collection.updateInterval = Bandwagon.Util.intervalUnitsToMilliseconds(document.getElementById("textbox-updateinterval-quantity-percollection").valueNumber, document.getElementById("menulist-updateinterval-units-percollection").selectedIndex+1) / 1000;
+ }
+
+ // save notifications setting
+
+ if (document.getElementById("notifications-group").selectedIndex == 0)
+ {
+ collection.showNotifications = -1;
+ }
+ else
+ {
+ collection.showNotifications = (document.getElementById("checkbox-shownotifications-percollection").selectedIndex==0?1:0);
+ }
+
+ // save addons per page
+
+ if (document.getElementById("perpage-group").selectedIndex == 0)
+ {
+ collection.addonsPerPage = -1
+ }
+ else
+ {
+ collection.addonsPerPage = document.getElementById("textbox-addonsperpage-percollection").value;
+ }
+
+ if (document.getElementById("bandwagon-settings").instantApply)
+ {
+ Bandwagon.Controller.Settings.doAccept();
+ }
+
+ Bandwagon.Controller.Settings.invalidateCustomizeCollectionUI();
+}
+
+Bandwagon.Controller.Settings._repopulateCollectionsList = function()
+{
+ Bandwagon.Logger.debug("in _repopulateCollectionsList");
+
+ // first clear the list
+
+ while (Bandwagon.Controller.Settings.elemBandwagonCollections.hasChildNodes())
+ {
+ Bandwagon.Controller.Settings.elemBandwagonCollections.removeChild(Bandwagon.Controller.Settings.elemBandwagonCollections.firstChild);
+ }
+
+ // repopulate with collections
+
+ for (var id in bandwagonService.collections)
+ {
+ var collection = bandwagonService.collections[id];
+
+ if (collection == null)
+ return;
+
+ const XULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
+ var elemBandwagonCollection = document.createElementNS(XULNS, "bandwagonCollection");
+ elemBandwagonCollection.setAttribute("view", "settings");
+
+ elemBandwagonCollection.collection = collection;
+ elemBandwagonCollection.controller = Bandwagon.Controller.Settings;
+
+ Bandwagon.Controller.Settings.elemBandwagonCollections.appendChild(elemBandwagonCollection);
+ }
+
+ // create the local copy of the collections hash with the properties we need
+
+ Bandwagon.Controller.Settings.collections = {};
+
+ for (var id in bandwagonService.collections)
+ {
+ var collection = bandwagonService.collections[id];
+
+ Bandwagon.Controller.Settings.collections[id] =
+ {
+ name: collection.name,
+ url: collection.resourceURL,
+ updateInterval: collection.updateInterval,
+ showNotifications: collection.showNotifications,
+ addonsPerPage: collection.addonsPerPage
+ };
+ }
+}
+
+Bandwagon.Controller.Settings.doLogin = function()
+{
+ // open the extensions manager window.
+
+ const EMTYPE = "Extension:Manager";
+ var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
+ .getService(Components.interfaces.nsIWindowMediator);
+ var theEM = wm.getMostRecentWindow(EMTYPE);
+
+ if (theEM)
+ {
+ theEM.focus();
+ theEM.showView('bandwagon-collections');
+ }
+ else
+ {
+ const EMURL = "chrome://mozapps/content/extensions/extensions.xul";
+ const EMFEATURES = "chrome,menubar,extra-chrome,toolbar,dialog=no,resizable";
+ window.openDialog(EMURL, "", EMFEATURES);
+ }
+}
+
+Bandwagon.Controller.Settings.doLogout = function()
+{
+ bandwagonService.deauthenticate();
+}
+
+Bandwagon.Controller.Settings._openLocalizedURL = function(url)
+{
+ var locale = Bandwagon.Util.getBrowserLocale();
+
+ if (locale && locale != "")
+ url = url.replace(/en-US/, locale, "g");
+
+ var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
+ .getService(Components.interfaces.nsIWindowMediator);
+ var mainWindow = wm.getMostRecentWindow("navigator:browser");
+
+ if (mainWindow)
+ {
+ var tab = mainWindow.getBrowser().addTab(url);
+ mainWindow.getBrowser().selectedTab = tab;
+ mainWindow.focus();
+ }
+ else
+ {
+ window.open(url);
+ }
+}
+
+Bandwagon.Controller.Settings._autoCreateToggleUIEnabledState = function(on)
+{
+ document.getElementById("auto-create-button").disabled = on;
+ document.getElementById("auto-name").disabled = on;
+ document.getElementById("auto-list").disabled = on;
+ document.getElementById("auto-type-extensions").disabled = on;
+ document.getElementById("auto-type-themes").disabled = on;
+ document.getElementById("auto-type-dicts").disabled = on;
+ document.getElementById("auto-type-langpacks").disabled = on;
+ document.getElementById("auto-spinner").collapsed = !on;
+}
+
+Bandwagon.Controller.Settings.doCreateAutoPublisher = function()
+{
+ // check form
+ document.getElementById("auto-error").value = "";
+
+ var collectionName = document.getElementById("auto-name").value;
+
+ if (!collectionName || collectionName == "" || !collectionName.match(/.*\w.*/))
+ {
+ document.getElementById("auto-error").value = Bandwagon.Controller.Settings.stringBundle.getFormattedString("auto.invalid.name", [collectionName]);
+ return;
+ }
+
+ var autoPublishExtensions = document.getElementById("auto-type-extensions").checked;
+ var autoPublishThemes = document.getElementById("auto-type-themes").checked;
+ var autoPublishDicts = document.getElementById("auto-type-dicts").checked;
+ var autoPublishLangPacks = document.getElementById("auto-type-langpacks").checked;
+ var autoPublishDisabled = !document.getElementById("auto-only-publish-enabled").checked;
+
+ if (!autoPublishExtensions && !autoPublishThemes && !autoPublishDicts && !autoPublishLangPacks)
+ {
+ document.getElementById("auto-error").value = Bandwagon.Controller.Settings.stringBundle.getString("auto.please.select.type");
+ return;
+ }
+
+ // disable ui settings, show throbber
+
+ Bandwagon.Controller.Settings._autoCreateToggleUIEnabledState(true);
+
+ // create the collection object
+ //
+ // TODO this logic should not be in the UI controller
+
+ var collection = new Bandwagon.Model.Collection();
+
+ collection.name = collectionName;
+ collection.description = Bandwagon.Controller.Settings.stringBundle.getString("auto.create.description");
+ collection.listed = document.getElementById("auto-list").checked;
+ collection.writable = true;
+ collection.showNotifications = false;
+ collection.updateInterval = 60 * 60 * 24;
+ collection.addonsPerPage = Bandwagon.Preferences.getPreference("global.addonsperpage");
+ collection.status = collection.STATUS_NEW;
+
+ collection.autoPublishExtensions = autoPublishExtensions;
+ collection.autoPublishThemes = autoPublishThemes;
+ collection.autoPublishDicts = autoPublishDicts;
+ collection.autoPublishLangPacks = autoPublishLangPacks;
+ collection.autoPublishDisabled = autoPublishDisabled;
+
+ Bandwagon.Preferences.setPreferenceList("autopublished.extensions", []);
+
+ // send the api call
+
+ var newCollectionCallback = function(event)
+ {
+ if (event.isError())
+ {
+ if (event.getError().getMessage() == "invalid_parameters")
+ {
+ // this happens when the api doesn't like the collection name or description. TODO do we need a better error her?
+ document.getElementById("auto-error").value = Bandwagon.Controller.Settings.stringBundle.getString("auto.create.internal.error");
+ }
+ else
+ {
+ document.getElementById("auto-error").value = Bandwagon.Controller.Settings.stringBundle.getString("auto.create.internal.error");
+ }
+
+ Bandwagon.Controller.Settings._autoCreateToggleUIEnabledState(false);
+ }
+ else
+ {
+ Bandwagon.Preferences.setPreference("local.autopublisher", collection.resourceURL);
+
+ // we also need to subscribe to this collection
+ bandwagonService.subscribeToCollection(collection);
+
+ // publish extensions to this collection
+ bandwagonService.autopublishExtensions();
+
+ // on callback of above, tell user we're done
+ document.getElementById("auto-error").style.color = 'green';
+ document.getElementById("auto-error").value = Bandwagon.Controller.Settings.stringBundle.getString("auto.create.done");
+
+ // clean-up
+ document.getElementById("auto-create-button").collapsed = true;
+ document.getElementById("auto-delete-button").collapsed = false;
+ document.getElementById("auto-update-button").collapsed = false;
+ document.getElementById("auto-spinner").collapsed = true;
+ }
+ }
+
+ bandwagonService.newCollection(collection, newCollectionCallback);
+}
+
+Bandwagon.Controller.Settings.doUpdateAutoPublisher = function()
+{
+ document.getElementById("auto-error").value = "";
+
+ var collectionName = document.getElementById("auto-name").value;
+
+ if (!collectionName || collectionName == "" || !collectionName.match(/.*\w.*/))
+ {
+ document.getElementById("auto-error").value = Bandwagon.Controller.Settings.stringBundle.getFormattedString("auto.invalid.name", [collectionName]);
+ return;
+ }
+
+ var promptService;
+
+ try
+ {
+ promptService = Components.classes["@mozilla.org/embedcomp/prompt-service;1"].getService();
+ promptService = promptService.QueryInterface(Components.interfaces.nsIPromptService);
+ } catch (e) { return; }
+
+ var promptTitle = document.getElementById("auto-update-button").label;
+ var promptMsg = Bandwagon.Controller.Settings.stringBundle.getString("auto.update.confirm.message");
+ var proceed = promptService.confirm(
+ window,
+ promptTitle,
+ promptMsg
+ );
+
+ if (!proceed)
+ {
+ return;
+ }
+
+ document.getElementById("auto-spinner").collapsed = false;
+
+ var collection = bandwagonService.getLocalAutoPublisher();
+
+ collection.name = document.getElementById("auto-name").value;
+ collection.listed = document.getElementById("auto-list").checked;
+ collection.autoPublishExtensions = document.getElementById("auto-type-extensions").checked;
+ collection.autoPublishThemes = document.getElementById("auto-type-themes").checked;
+ collection.autoPublishDicts = document.getElementById("auto-type-dicts").checked;
+ collection.autoPublishLangPacks = document.getElementById("auto-type-langpacks").checked;
+ collection.autoPublishDisabled = !document.getElementById("auto-only-publish-enabled").checked;
+
+ var callback = function(event)
+ {
+ document.getElementById("auto-spinner").collapsed = true;
+
+ if (event.isError())
+ {
+ document.getElementById("auto-error").value = Bandwagon.Controller.Settings.stringBundle.getString("auto.update.internal.error");
+ }
+ else
+ {
+ Bandwagon.Preferences.setPreference("local.autopublisher", collection.resourceURL);
+
+ // on callback of above, refresh collection list
+ bandwagonService.forceCheckAllForUpdatesAndUpdateCollectionsList();
+
+ Bandwagon.Controller.Settings._autoCreateToggleUIEnabledState(false);
+
+ // on callback of above, tell user we're done
+ document.getElementById("auto-error").style.color = 'green';
+ document.getElementById("auto-error").value = Bandwagon.Controller.Settings.stringBundle.getString("auto.update.done");
+
+ // clean-up
+ document.getElementById("auto-create-button").collapsed = true;
+ document.getElementById("auto-update-button").collapsed = false;
+ document.getElementById("auto-delete-button").collapsed = false;
+ document.getElementById("auto-spinner").collapsed = true;
+ }
+ }
+
+ bandwagonService.updateCollectionDetails(collection, callback);
+}
+
+Bandwagon.Controller.Settings.doDeleteAutoPublisher = function()
+{
+ document.getElementById("auto-spinner").collapsed = false;
+
+ var localAutoPublisher = bandwagonService.getLocalAutoPublisher();
+
+ var callback = function(event)
+ {
+ document.getElementById("auto-spinner").collapsed = true;
+
+ if (event.isError())
+ {
+ document.getElementById("auto-error").value = Bandwagon.Controller.Settings.stringBundle.getString("auto.delete.internal.error");
+ }
+ else
+ {
+ Bandwagon.Preferences.setPreference("local.autopublisher", "");
+
+ // on callback of above, refresh collection list
+ bandwagonService.forceCheckAllForUpdatesAndUpdateCollectionsList();
+
+ Bandwagon.Controller.Settings._autoCreateToggleUIEnabledState(false);
+
+ // on callback of above, tell user we're done
+ document.getElementById("auto-error").style.color = 'green';
+ document.getElementById("auto-error").value = Bandwagon.Controller.Settings.stringBundle.getString("auto.delete.done");
+
+ // clean-up
+ document.getElementById("auto-create-button").collapsed = false;
+ document.getElementById("auto-update-button").collapsed = true;
+ document.getElementById("auto-delete-button").collapsed = true;
+ document.getElementById("auto-spinner").collapsed = true;
+ }
+ }
+
+ bandwagonService.deleteCollection(localAutoPublisher, callback);
+}
+
+Bandwagon.Controller.Settings.doClearEmails = function()
+{
+ bandwagonService.clearPreviouslySharedEmailAddresses();
+
+ Bandwagon.Controller.Settings.invalidateEmails();
+}
+
+Bandwagon.Controller.Settings.doAccept = function()
+{
+ Bandwagon.Logger.debug("In doAccept()");
+
+ // called:
+ // - when user clicks 'Ok' (on systems that show the ok button)
+ // - when user changes collection properties (on systems that don't show buttons)
+
+ // copy the locally update settings over the global collection settings
+
+ for (var id in Bandwagon.Controller.Settings.collections)
+ {
+ var localCollection = Bandwagon.Controller.Settings.collections[id];
+ var bwCollection = bandwagonService.collections[id];
+
+ if (!localCollection || !bwCollection)
+ continue;
+
+ if (bwCollection.addonsPerPage != localCollection.addonsPerPage)
+ {
+ bwCollection.addonsPerPage = localCollection.addonsPerPage;
+ Bandwagon.Preferences.notifyObservers("addonsperpage:" + bwCollection.resourceURL);
+ }
+
+ bwCollection.updateInterval = localCollection.updateInterval;
+ bwCollection.showNotifications = localCollection.showNotifications;
+ }
+}
+
+Bandwagon.Controller.Settings.doCancel = function()
+{
+ // nothing
+}
+
+Bandwagon.Controller.Settings.doUnsubscribe = function()
+{
+ var collection = Bandwagon.Controller.Settings.elemBandwagonCollections.selectedItem.collection;
+
+ if (collection == null)
+ return;
+
+ var promptService = Components.classes["@mozilla.org/embedcomp/prompt-service;1"].getService(Components.interfaces.nsIPromptService);
+ var check = {value: false};
+ var flags = promptService.BUTTON_POS_0 * promptService.BUTTON_TITLE_IS_STRING + promptService.BUTTON_POS_1 * promptService.BUTTON_TITLE_IS_STRING;
+ var button = promptService.confirmEx(
+ window,
+ Bandwagon.Controller.Settings.stringBundle2.getString("unsubscribe.confirm.title"),
+ Bandwagon.Controller.Settings.stringBundle2.getString("unsubscribe.confirm.label"),
+ flags,
+ Bandwagon.Controller.Settings.stringBundle2.getString("unsubscribe.confirm.button0"),
+ Bandwagon.Controller.Settings.stringBundle2.getString("unsubscribe.confirm.button1"),
+ null,
+ null,
+ check);
+
+ if (button == 0)
+ {
+ var callback = function(event)
+ {
+ if (event.isError())
+ {
+ window.alert(Bandwagon.Controller.Settings.stringBundle2.getString("unsubscribe.error"));
+ }
+ }
+
+ bandwagonService.unsubscribeFromCollection(collection, callback);
+ }
+}
+
+Bandwagon.Controller.Settings.doUpdateIntervalScopeChange = function(event)
+{
+ if (document.getElementById("updates-group").selectedIndex == 0) // Use default
+ {
+ document.getElementById("extensions.bandwagon.global.update.interval").value = document.getElementById("textbox-updateinterval-quantity").valueNumber;
+ document.getElementById("extensions.bandwagon.global.update.units").value = document.getElementById("menulist-updateinterval-units").selectedIndex + 1;
+ }
+ else
+ {
+ // Not sure if anything needs to be done here
+ }
+
+ Bandwagon.Controller.Settings.doShowCollection();
+}
+
+Bandwagon.Controller.Settings.doShowNotificationsScopeChange = function(event)
+{
+ document.getElementById("extensions.bandwagon.global.notify.enabled").value = (document.getElementById("notifications-group").selectedIndex == 0);
+
+ Bandwagon.Controller.Settings.doShowCollection();
+}
+
+
+window.addEventListener("load", Bandwagon.Controller.Settings.init, true);
+window.addEventListener("unload", Bandwagon.Controller.Settings.uninit, true);
diff --git a/bandwagon/defaults/preferences/bandwagon.js b/bandwagon/defaults/preferences/bandwagon.js
new file mode 100644
index 0000000..57b9a57
--- /dev/null
+++ b/bandwagon/defaults/preferences/bandwagon.js
@@ -0,0 +1,60 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is bandwagon.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s): David McNamara
+ * Brian King
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+pref("extensions.sharing@addons.mozilla.org.description", "chrome://bandwagon/locale/bandwagon.properties");
+pref("extensions.bandwagon.currentversion", "0.0");
+pref("extensions.bandwagon.addonswindow.resized", false);
+pref("extensions.bandwagon.debug", false);
+pref("extensions.bandwagon.firstrun", true);
+pref("extensions.bandwagon.verbose", false);
+pref("extensions.bandwagon.updateall.datelastcheck", 0);
+pref("extensions.bandwagon.publish.shared.emails", "");
+pref("extensions.bandwagon.autopublished.extensions", "");
+pref("extensions.bandwagon.local.autopublisher", "");
+pref("extensions.bandwagon.local.autopublisher.publish.extensions", true);
+pref("extensions.bandwagon.local.autopublisher.publish.themes", true);
+pref("extensions.bandwagon.local.autopublisher.publish.dictionaries", true);
+pref("extensions.bandwagon.local.autopublisher.publish.language.packs", true);
+pref("extensions.bandwagon.local.autopublisher.only.publish.enabled", true);
+pref("extensions.bandwagon.global.update.interval", 8);
+pref("extensions.bandwagon.global.update.units", 2);
+pref("extensions.bandwagon.global.addonsperpage", 20);
+pref("extensions.bandwagon.global.notify.enabled", true);
+pref("extensions.bandwagon.allow.incompatible.install", false);
+pref("extensions.bandwagon.authtoken", "");
+pref("extensions.bandwagon.login", "");
+pref("extensions.bandwagon.amo_host", "addons.mozilla.org");
diff --git a/bandwagon/install.rdf b/bandwagon/install.rdf
new file mode 100644
index 0000000..b657526
--- /dev/null
+++ b/bandwagon/install.rdf
@@ -0,0 +1,178 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:em="http://www.mozilla.org/2004/em-rdf#">
+
+ <Description about="urn:mozilla:install-manifest">
+ <em:id>sharing@addons.mozilla.org</em:id>
+ <em:name>Add-on Collector</em:name>
+ <em:version>1.0</em:version>
+ <em:creator>Mozilla Corporation</em:creator>
+ <em:contributor>BRIKS Software (http://briks.si)</em:contributor>
+ <em:translator>Mozilla Localization Teams</em:translator>
+ <em:translator>https://addons.mozilla.org/pages/credits</em:translator>
+ <em:homepageURL>https://addons.mozilla.org/collections</em:homepageURL>
+ <em:optionsURL>chrome://bandwagon/content/ui/settings.xul</em:optionsURL>
+ <em:iconURL>chrome://bandwagon/skin/images/icon32.png</em:iconURL>
+
+ <em:targetApplication>
+ <Description>
+ <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id> <!-- firefox -->
+ <em:minVersion>3.0</em:minVersion>
+ <em:maxVersion>3.5.*</em:maxVersion>
+ </Description>
+ </em:targetApplication>
+
+ <em:localized>
+ <Description>
+ <em:locale>ca</em:locale>
+ <em:name>Add-on Collector</em:name>
+ </Description>
+ </em:localized>
+ <em:localized>
+ <Description>
+ <em:locale>cs</em:locale>
+ <em:name>Add-on Collector</em:name>
+ </Description>
+ </em:localized>
+ <em:localized>
+ <Description>
+ <em:locale>da</em:locale>
+ <em:name>Tilføjelsessamleren</em:name>
+ </Description>
+ </em:localized>
+ <em:localized>
+ <Description>
+ <em:locale>de</em:locale>
+ <em:name>Add-on-Sammler</em:name>
+ </Description>
+ </em:localized>
+ <em:localized>
+ <Description>
+ <em:locale>el-GR</em:locale>
+ <em:name>Add-on Collector</em:name>
+ </Description>
+ </em:localized>
+ <em:localized>
+ <Description>
+ <em:locale>en-US</em:locale>
+ <em:name>Add-on Collector</em:name>
+ </Description>
+ </em:localized>
+ <em:localized>
+ <Description>
+ <em:locale>es-ES</em:locale>
+ <em:name>Add-on Collector</em:name>
+ </Description>
+ </em:localized>
+ <em:localized>
+ <Description>
+ <em:locale>fa</em:locale>
+ <em:name>جمع‌کنندهٔ اÙزودنی‌ها</em:name>
+ </Description>
+ </em:localized>
+ <em:localized>
+ <Description>
+ <em:locale>fr</em:locale>
+ <em:name>Add-on Collector</em:name>
+ </Description>
+ </em:localized>
+ <em:localized>
+ <Description>
+ <em:locale>fy-NL</em:locale>
+ <em:name>Tafoegingssamler</em:name>
+ </Description>
+ </em:localized>
+ <em:localized>
+ <Description>
+ <em:locale>he</em:locale>
+ <em:name>Add-on Collector</em:name>
+ </Description>
+ </em:localized>
+ <em:localized>
+ <Description>
+ <em:locale>id</em:locale>
+ <em:name>Kolektor Pengaya</em:name>
+ </Description>
+ </em:localized>
+ <em:localized>
+ <Description>
+ <em:locale>it</em:locale>
+ <em:name>Add-on Collector</em:name>
+ </Description>
+ </em:localized>
+ <em:localized>
+ <Description>
+ <em:locale>nl</em:locale>
+ <em:name>Add-on Collector</em:name>
+ </Description>
+ </em:localized>
+ <em:localized>
+ <Description>
+ <em:locale>pl-PL</em:locale>
+ <em:name>Add-on Collector</em:name>
+ </Description>
+ </em:localized>
+ <em:localized>
+ <Description>
+ <em:locale>pt-BR</em:locale>
+ <em:name>Add-on Collector</em:name>
+ </Description>
+ </em:localized>
+ <em:localized>
+ <Description>
+ <em:locale>pt-PT</em:locale>
+ <em:name>Coleccionador de extras</em:name>
+ </Description>
+ </em:localized>
+ <em:localized>
+ <Description>
+ <em:locale>ro</em:locale>
+ <em:name>Add-on Collector</em:name>
+ </Description>
+ </em:localized>
+ <em:localized>
+ <Description>
+ <em:locale>ru</em:locale>
+ <em:name>Собиратель Дополнений</em:name>
+ </Description>
+ </em:localized>
+ <em:localized>
+ <Description>
+ <em:locale>sk</em:locale>
+ <em:name>Add-on Collector</em:name>
+ </Description>
+ </em:localized>
+ <em:localized>
+ <Description>
+ <em:locale>sq</em:locale>
+ <em:name>Grumbullues Shtesash</em:name>
+ </Description>
+ </em:localized>
+ <em:localized>
+ <Description>
+ <em:locale>sv-SE</em:locale>
+ <em:name>Add-on-samlaren</em:name>
+ </Description>
+ </em:localized>
+ <em:localized>
+ <Description>
+ <em:locale>vi</em:locale>
+ <em:name>Add-on Collector</em:name>
+ </Description>
+ </em:localized>
+ <em:localized>
+ <Description>
+ <em:locale>zh-CN</em:locale>
+ <em:name>Add-on Collector</em:name>
+ </Description>
+ </em:localized>
+ <em:localized>
+ <Description>
+ <em:locale>zh-TW</em:locale>
+ <em:name>Add-on Collector</em:name>
+ </Description>
+ </em:localized>
+ </Description>
+
+</RDF>
diff --git a/bandwagon/locale/ar/bandwagon.properties b/bandwagon/locale/ar/bandwagon.properties
new file mode 100644
index 0000000..37a8281
--- /dev/null
+++ b/bandwagon/locale/ar/bandwagon.properties
@@ -0,0 +1,2 @@
+extensions.sharing@addons.mozilla.org.description=Share and discover add-ons.
+extensions.sharing@addons.mozilla.org.name=Add-on Collector
diff --git a/bandwagon/locale/ar/bandwagonAddon.properties b/bandwagon/locale/ar/bandwagonAddon.properties
new file mode 100644
index 0000000..28fb149
--- /dev/null
+++ b/bandwagon/locale/ar/bandwagonAddon.properties
@@ -0,0 +1,38 @@
+# LOCALIZATION NOTE (bandwagon.addon.pluralRule):
+# See https://developer.mozilla.org/En/Localization_and_Plurals
+bandwagon.addon.pluralRule=1
+bandwagon.category1=Extension
+# LOCALIZATION NOTE (bandwagon.addon.author):
+# %S will contain author's first and last name, or their nickname used on AMO
+bandwagon.addon.author=By %S
+# LOCALIZATION NOTE (bandwagon.addon.addedby):
+# %S will be a user's first and last name, or nickname
+bandwagon.addon.addedby=by %S
+bandwagon.addon.added.justnow=Added: Just now
+# LOCALIZATION NOTE:
+# %S will be a number of time units indicated
+bandwagon.addon.added.minute=Added: 1 minute ago;Added: %S minutes ago
+bandwagon.addon.added.hour=Added: 1 hour ago;Added: %S hours ago
+bandwagon.addon.added.day=Added: Yesterday;Added: %S days ago
+bandwagon.addon.added.week=Added: 1 week ago;Added: %S weeks ago
+bandwagon.addon.added.month=Added: 1 month ago;Added: %S months ago
+bandwagon.addon.added.year=Added: 1 year ago;Added: %S years ago
+bandwagon.addon.moreinfo=More info.
+bandwagon.addon.olderversionsoffirefox=This add-on is for older versions of Firefox.
+# LOCALIZATION NOTE (upgradetofirefoxn1):
+# %S will be a Firefox version number
+bandwagon.addon.upgradetofirefoxn1=Upgrade to Firefox %S
+bandwagon.addon.upgradetofirefoxn2=to use this add-on.
+# LOCALIZATION NOTE (bandwagon.addon.requiresfirefoxbeta1/requiresfirefoxbeta2):
+# %S will be a Firefox version number
+bandwagon.addon.requiresfirefoxbeta1=This add-on requires Firefox %S, which has not yet been released. To use this add-on, you may
+bandwagon.addon.requiresfirefoxbeta2=download Firefox %S beta.
+# LOCALIZATION NOTE (bandwagon.addon.notcompatible):
+# %S will be a platform name, such as "Windows"
+bandwagon.addon.notcompatible=This add-on is not compatible with %S.
+# LOCALIZATION NOTE (bandwagon.addon.comment.description):
+# %S will be a comment entered by the publisher of the add-on
+bandwagon.addon.comment.description=“%Sâ€
+# LOCALIZATION NOTE (bandwagon.addon.comment.author):
+# %S will be the publisher's real name or nickname
+bandwagon.addon.comment.author=Comment from %S:
diff --git a/bandwagon/locale/ar/browserOverlay.dtd b/bandwagon/locale/ar/browserOverlay.dtd
new file mode 100644
index 0000000..a665207
--- /dev/null
+++ b/bandwagon/locale/ar/browserOverlay.dtd
@@ -0,0 +1,38 @@
+<!-- ***** BEGIN LICENSE BLOCK *****
+ - Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ -
+ - The contents of this file are subject to the Mozilla Public License Version
+ - 1.1 (the "License"); you may not use this file except in compliance with
+ - the License. You may obtain a copy of the License at
+ - http://www.mozilla.org/MPL/
+ -
+ - Software distributed under the License is distributed on an "AS IS" basis,
+ - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ - for the specific language governing rights and limitations under the
+ - License.
+ -
+ - The Original Code is bandwagon.
+ -
+ - The Initial Developer of the Original Code is
+ - Mozilla Corporation.
+ - Portions created by the Initial Developer are Copyright (C) 2008
+ - the Initial Developer. All Rights Reserved.
+ -
+ - Contributor(s): Brian King <brian (at) briks (dot) si>
+ -
+ - Alternatively, the contents of this file may be used under the terms of
+ - either the GNU General Public License Version 2 or later (the "GPL"), or
+ - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ - in which case the provisions of the GPL or the LGPL are applicable instead
+ - of those above. If you wish to allow use of your version of this file only
+ - under the terms of either the GPL or the LGPL, and not to allow others to
+ - use your version of this file under the terms of the MPL, indicate your
+ - decision by deleting the provisions above and replace them with the notice
+ - and other provisions required by the GPL or the LGPL. If you do not delete
+ - the provisions above, a recipient may use your version of this file under
+ - the terms of any one of the MPL, the GPL or the LGPL.
+ -
+ - ***** END LICENSE BLOCK ***** -->
+
+<!ENTITY bandwagon.label "Add-ons">
+<!ENTITY bandwagon.tooltip "Add-ons">
diff --git a/bandwagon/locale/ar/browserOverlay.properties b/bandwagon/locale/ar/browserOverlay.properties
new file mode 100644
index 0000000..5c3b7aa
--- /dev/null
+++ b/bandwagon/locale/ar/browserOverlay.properties
@@ -0,0 +1,4 @@
+newaddons.alert.title=New Add-ons
+# LOCALIZATION NOTE (newaddons.alert.text):
+# %S will be the name of a collection
+newaddons.alert.text=There are new add-ons in your subscription "%S".
diff --git a/bandwagon/locale/ar/extensionOverlay.properties b/bandwagon/locale/ar/extensionOverlay.properties
new file mode 100644
index 0000000..03d896c
--- /dev/null
+++ b/bandwagon/locale/ar/extensionOverlay.properties
@@ -0,0 +1,14 @@
+publish.new.email.address.title=New E-mail Address
+publish.new.email.address.text=Enter a new e-mail address to share this add-on with:
+publish.remove.title=Confirmation
+# LOCALIZATION NOTE (publish.remove.label):
+# %1 is the name of an add-on. %2 is the name of a collection
+publish.remove.label=Are you sure you wish to remove %1$S from the "%2$S" collection?
+publish.remove.button1=No, cancel
+publish.remove.button0=Yes, remove the add-on
+login.error=There was an error logging in. Please check that your username and password are correct.
+unsubscribe.error=There was an error unsubscribing from this collection. Please try again later.
+unsubscribe.confirm.title=Confirm Unsubscribe
+unsubscribe.confirm.label=Unsubscribing from this collection will also remove it from your list of favorites. Are you sure you want to unsubscribe?
+unsubscribe.confirm.button1=No, cancel
+unsubscribe.confirm.button0=Yes, unsubscribe
diff --git a/bandwagon/locale/ar/extensionsOverlay.dtd b/bandwagon/locale/ar/extensionsOverlay.dtd
new file mode 100644
index 0000000..10e101b
--- /dev/null
+++ b/bandwagon/locale/ar/extensionsOverlay.dtd
@@ -0,0 +1,69 @@
+<!-- ***** BEGIN LICENSE BLOCK *****
+ - Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ -
+ - The contents of this file are subject to the Mozilla Public License Version
+ - 1.1 (the "License"); you may not use this file except in compliance with
+ - the License. You may obtain a copy of the License at
+ - http://www.mozilla.org/MPL/
+ -
+ - Software distributed under the License is distributed on an "AS IS" basis,
+ - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ - for the specific language governing rights and limitations under the
+ - License.
+ -
+ - The Original Code is bandwagon.
+ -
+ - The Initial Developer of the Original Code is
+ - Mozilla Corporation.
+ - Portions created by the Initial Developer are Copyright (C) 2008
+ - the Initial Developer. All Rights Reserved.
+ -
+ - Contributor(s): Brian King <brian (at) briks (dot) si>
+ - David McNamara
+ -
+ - Alternatively, the contents of this file may be used under the terms of
+ - either the GNU General Public License Version 2 or later (the "GPL"), or
+ - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ - in which case the provisions of the GPL or the LGPL are applicable instead
+ - of those above. If you wish to allow use of your version of this file only
+ - under the terms of either the GPL or the LGPL, and not to allow others to
+ - use your version of this file under the terms of the MPL, indicate your
+ - decision by deleting the provisions above and replace them with the notice
+ - and other provisions required by the GPL or the LGPL. If you do not delete
+ - the provisions above, a recipient may use your version of this file under
+ - the terms of any one of the MPL, the GPL or the LGPL.
+ -
+ - ***** END LICENSE BLOCK ***** -->
+
+<!ENTITY collections.label "Subscriptions">
+<!ENTITY search.label.bandwagon "Search">
+
+<!ENTITY addon.moreinfo "More info.">
+<!ENTITY addon.addtofirefox "Add to Firefox">
+<!ENTITY subscribe.label "Find Collections">
+<!ENTITY reload.label "Reload All">
+<!ENTITY settings.label "Settings">
+
+<!ENTITY view.label "View Collection">
+<!ENTITY unsubscribe.label "Unsubscribe">
+
+<!ENTITY nocollectionstitle.label "Welcome to the Add-on Collector">
+<!ENTITY nocollectionssubscribed.label "This is where collections you mark as a favorite on Mozilla Add-ons will appear so that you can easily keep track of them. It looks like you haven't yet added any favorites, so why not take a look around our Collection Directory?">
+<!ENTITY clicktosubscribe.label "Find Collections">
+
+<!ENTITY noamoauth.label "This is where collections you mark as a favorite on Mozilla Add-ons will appear so that you can easily keep track of them. You must be logged in to addons.mozilla.org to use this feature.">
+<!ENTITY username.label "Username">
+<!ENTITY password.label "Password">
+<!ENTITY clicktologin.label "Login">
+
+<!ENTITY collectionisloading.label "Retrieving subscription...">
+<!ENTITY collectionhasnoitems.label "This collection contains no add-ons.">
+<!ENTITY collectionhaserror.label "This collection cannot be displayed because it contains errors.">
+
+<!ENTITY publishto.label "Publish to">
+<!ENTITY email.address.label "E-mail Address">
+<!ENTITY new.email.address.label "New E-mail Address">
+<!ENTITY new.collection.label "New Collection">
+
+<!ENTITY createaccount.label "I don't have an account">
+<!ENTITY loginheading.label "Enter your Mozilla Add-ons account information below:">
diff --git a/bandwagon/locale/ar/publish.dtd b/bandwagon/locale/ar/publish.dtd
new file mode 100644
index 0000000..0e3ec14
--- /dev/null
+++ b/bandwagon/locale/ar/publish.dtd
@@ -0,0 +1,48 @@
+<!-- ***** BEGIN LICENSE BLOCK *****
+ - Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ -
+ - The contents of this file are subject to the Mozilla Public License Version
+ - 1.1 (the "License"); you may not use this file except in compliance with
+ - the License. You may obtain a copy of the License at
+ - http://www.mozilla.org/MPL/
+ -
+ - Software distributed under the License is distributed on an "AS IS" basis,
+ - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ - for the specific language governing rights and limitations under the
+ - License.
+ -
+ - The Original Code is bandwagon.
+ -
+ - The Initial Developer of the Original Code is
+ - Mozilla Corporation.
+ - Portions created by the Initial Developer are Copyright (C) 2008
+ - the Initial Developer. All Rights Reserved.
+ -
+ - Contributor(s): David McNamara
+ - Brian King <brian (at) briks (dot) si>
+ -
+ - Alternatively, the contents of this file may be used under the terms of
+ - either the GNU General Public License Version 2 or later (the "GPL"), or
+ - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ - in which case the provisions of the GPL or the LGPL are applicable instead
+ - of those above. If you wish to allow use of your version of this file only
+ - under the terms of either the GPL or the LGPL, and not to allow others to
+ - use your version of this file under the terms of the MPL, indicate your
+ - decision by deleting the provisions above and replace them with the notice
+ - and other provisions required by the GPL or the LGPL. If you do not delete
+ - the provisions above, a recipient may use your version of this file under
+ - the terms of any one of the MPL, the GPL or the LGPL.
+ -
+ - ***** END LICENSE BLOCK ***** -->
+
+<!-- For localisers to change the width of the window -->
+<!ENTITY publish.style "width: 35em;">
+
+<!ENTITY window.title "Publish">
+<!ENTITY cancel.label "Cancel">
+<!ENTITY publish.label "Publish">
+<!ENTITY new.email.label "New E-mail Address">
+<!ENTITY enter.an.email.label "Enter one or more e-mail addresses separated by commas:">
+<!ENTITY remember.this.email.label "Remember this e-mail address">
+<!ENTITY enter.a.personal.note.label "Optional: Enter a personal note about this add-on to be included in the e-mail">
+
diff --git a/bandwagon/locale/ar/publish.properties b/bandwagon/locale/ar/publish.properties
new file mode 100644
index 0000000..b004394
--- /dev/null
+++ b/bandwagon/locale/ar/publish.properties
@@ -0,0 +1,20 @@
+# LOCALIZATION NOTE (you.are.sharing.the.add.on):
+# %S is the name of an add-on
+you.are.sharing.the.add.on=You are sharing the add-on '%S'
+# LOCALIZATION NOTE (publishing.to):
+# %1 is the name of an add-on. %2 is the name of a collection
+publishing.to=Clicking "Publish" will add %1$S to the "%2$S" collection.
+# LOCALIZATION NOTE (sharing.with):
+# %1 is a user's email address. $2 is the name of an add-on
+sharing.with=Clicking "Send E-mail" will send %1$S an e-mail with information about %2$S
+# LOCALIZATION NOTE (sharing.with.new):
+# %S is the name of an add-on
+sharing.with.new=Clicking "Send E-mail" will send the above recipients an e-mail with information about %S
+please.enter.an.email.address=Please enter an e-mail address.
+the.addon.has.been.published=The add-on has been published.
+the.email.has.been.sent=The email has been sent.
+# LOCALIZATION NOTE (closing.in):
+# %S is the number of seconds until a window closes, counting down
+closing.in=Closing in %S...
+send.email=Send E-mail
+error.unknown_addon_guid=This add-on cannot be shared because it is not hosted on the Mozilla Add-ons website.
diff --git a/bandwagon/locale/ar/settings.dtd b/bandwagon/locale/ar/settings.dtd
new file mode 100644
index 0000000..29e5f9d
--- /dev/null
+++ b/bandwagon/locale/ar/settings.dtd
@@ -0,0 +1,108 @@
+<!-- ***** BEGIN LICENSE BLOCK *****
+ - Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ -
+ - The contents of this file are subject to the Mozilla Public License Version
+ - 1.1 (the "License"); you may not use this file except in compliance with
+ - the License. You may obtain a copy of the License at
+ - http://www.mozilla.org/MPL/
+ -
+ - Software distributed under the License is distributed on an "AS IS" basis,
+ - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ - for the specific language governing rights and limitations under the
+ - License.
+ -
+ - The Original Code is bandwagon.
+ -
+ - The Initial Developer of the Original Code is
+ - Mozilla Corporation.
+ - Portions created by the Initial Developer are Copyright (C) 2008
+ - the Initial Developer. All Rights Reserved.
+ -
+ - Contributor(s): Brian King <brian (at) briks (dot) si>
+ - David McNamara
+ -
+ - Alternatively, the contents of this file may be used under the terms of
+ - either the GNU General Public License Version 2 or later (the "GPL"), or
+ - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ - in which case the provisions of the GPL or the LGPL are applicable instead
+ - of those above. If you wish to allow use of your version of this file only
+ - under the terms of either the GPL or the LGPL, and not to allow others to
+ - use your version of this file under the terms of the MPL, indicate your
+ - decision by deleting the provisions above and replace them with the notice
+ - and other provisions required by the GPL or the LGPL. If you do not delete
+ - the provisions above, a recipient may use your version of this file under
+ - the terms of any one of the MPL, the GPL or the LGPL.
+ -
+ - ***** END LICENSE BLOCK ***** -->
+
+<!-- For localisers to change the width of the window -->
+<!ENTITY settings.style "width: 42em;">
+
+<!ENTITY window.title "Add-on Collector Settings">
+
+<!-- Tabs -->
+<!ENTITY manage.label "Manage Subscriptions">
+<!ENTITY general.label "General Settings">
+<!ENTITY pub.label "Auto-publisher Settings">
+
+<!-- Manage Subscriptions -->
+<!ENTITY subscriptions.header "Subscriptions:">
+
+<!-- Groupbox captions in Manage Subscriptions -->
+<!ENTITY frequency.label "Subscription Update Frequency">
+<!ENTITY notifications.label "New Add-on Notifications">
+<!ENTITY perpage.label "Add-ons per Page">
+
+<!ENTITY default.label "Use default setting">
+<!ENTITY custom.label "Custom:">
+
+<!ENTITY addonsleadin.label "Show">
+<!ENTITY addonsperpage.label "add-ons per page">
+<!ENTITY updatesingle.label "Update every:">
+<!ENTITY minutes.label "minute(s)">
+<!ENTITY hours.label "hour(s)">
+<!ENTITY days.label "day(s)">
+<!ENTITY autopublish.label "Auto-publish installed add-ons to subscription">
+<!ENTITY notify.label "Show notifications">
+<!ENTITY applyall.label "Apply to all subscriptions">
+<!ENTITY remove.label "Remove Subscription">
+<!ENTITY on.label "On">
+<!ENTITY off.label "Off">
+
+<!-- General -->
+
+<!-- Groupbox captions in General -->
+<!ENTITY subscriptions.label "Default Subscription Settings">
+<!ENTITY data.label "Data Management">
+
+<!ENTITY updateall.label "Check subscriptions for updates every">
+<!ENTITY notifyglobal.label "Notify me when my subscriptions have new add-ons">
+
+<!ENTITY clearemails.label "Clear">
+<!ENTITY login.label "Login">
+<!ENTITY logout.label "Logout">
+
+<!-- Auto-Publisher Settings -->
+
+<!-- Groupbox captions in Auto-Publisher Settings -->
+<!ENTITY auto.label "Auto-publisher Settings">
+
+<!ENTITY name.label "Collection Name:">
+<!ENTITY list.label "Listed in public Collection Directory">
+
+<!ENTITY autoleadin.label "Auto-publishers are special collections that are automatically updated when you install or uninstall add-ons from Firefox on this computer.">
+<!ENTITY types.label "Auto-published add-on types:">
+<!ENTITY type.extensions.label "Extensions">
+<!ENTITY type.themes.label "Themes">
+<!ENTITY type.dicts.label "Dictionaries">
+<!ENTITY type.langpacks.label "Language Packs">
+
+<!ENTITY createauto.label "Create Auto-publisher">
+<!ENTITY deleteauto.label "Delete Auto-publisher">
+<!ENTITY updateauto.label "Update Auto-publisher">
+
+<!ENTITY onlypublishenabledaddons.label "Only publish enabled add-ons">
+
+<!ENTITY misc.label "Miscellaneous">
+<!ENTITY allowincompatibleinstall.label "Allow installation of incompatible add-ons from my subscriptions">
+
diff --git a/bandwagon/locale/ar/settings.properties b/bandwagon/locale/ar/settings.properties
new file mode 100644
index 0000000..0dbf781
--- /dev/null
+++ b/bandwagon/locale/ar/settings.properties
@@ -0,0 +1,26 @@
+add.collection=Add Subscription
+enter.url.to.add.collection=Enter the URL of the subscription you want to add.
+remove.collection=Remove Subscription
+# LOCALIZATION NOTE (are.you.sure.you.want.to.remove):
+# %S is the name of a collection
+are.you.sure.you.want.to.remove=Removing this subscription will also remove the collection from your favorites list. Are you sure you wish to remove '%S'?
+# LOCALIZATION NOTE (saved.emails.text):
+# %S is a number
+saved.emails.text=You have %S saved e-mail addresses
+# LOCALIZATION NOTE (login.status.with.email):
+# %S is a user's email address
+login.status.with.email=You are logged in as %S
+login.status=You are logged in
+logout.status=You are not logged in
+# LOCALIZATION NOTE (auto.invalid.name):
+# %S is the name of a collection
+auto.invalid.name=The collection name '%S' is not valid.
+auto.please.select.type=Please select at least one add-on type to automatically publish.
+auto.create.internal.error=The collection could not be created (an internal error occurred).
+auto.create.done=Your auto-publisher collection has been created.
+auto.delete.internal.error=The collection could not be deleted (an internal error occurred).
+auto.delete.done=Your auto-publisher collection has been deleted.
+auto.create.description=An automatically generated list of my installed add-ons
+auto.update.confirm.message=Your new settings will take effect immediately, but will not affect add-ons that have already been published.
+auto.update.internal.error=The collection could not be updated (an internal error occured).
+auto.update.done=Your auto-pubisher collection has been updated.
diff --git a/bandwagon/locale/ca/bandwagon.properties b/bandwagon/locale/ca/bandwagon.properties
new file mode 100644
index 0000000..eef9b3a
--- /dev/null
+++ b/bandwagon/locale/ca/bandwagon.properties
@@ -0,0 +1,2 @@
+extensions.sharing@addons.mozilla.org.description=Compartiu i descobriu complements.
+extensions.sharing@addons.mozilla.org.name=Add-on Collector
diff --git a/bandwagon/locale/ca/bandwagonAddon.properties b/bandwagon/locale/ca/bandwagonAddon.properties
new file mode 100644
index 0000000..4177392
--- /dev/null
+++ b/bandwagon/locale/ca/bandwagonAddon.properties
@@ -0,0 +1,38 @@
+# LOCALIZATION NOTE (bandwagon.addon.pluralRule):
+# See https://developer.mozilla.org/En/Localization_and_Plurals
+bandwagon.addon.pluralRule=1
+bandwagon.category1=Extensió
+# LOCALIZATION NOTE (bandwagon.addon.author):
+# %S will contain author's first and last name, or their nickname used on AMO
+bandwagon.addon.author=Per %S
+# LOCALIZATION NOTE (bandwagon.addon.addedby):
+# %S will be a user's first and last name, or nickname
+bandwagon.addon.addedby=per %S
+bandwagon.addon.added.justnow=Afegida: ara mateix
+# LOCALIZATION NOTE:
+# %S will be a number of time units indicated
+bandwagon.addon.added.minute=Afegida: fa 1 minut;Afegida: fa %S minuts
+bandwagon.addon.added.hour=Afegida: fa 1 hora;Afegida: fa %S hores
+bandwagon.addon.added.day=Afegida: ahir;Afegida: fa %S dies
+bandwagon.addon.added.week=Afegida: fa 1 setmana;Afegida: fa %S setmanes
+bandwagon.addon.added.month=Afegida: fa 1 mes;Afegida: fa %S mesos
+bandwagon.addon.added.year=Afegida: fa 1 any;Afegida: fa %S anys
+bandwagon.addon.moreinfo=Més informació.
+bandwagon.addon.olderversionsoffirefox=Aquest complement és per a versions més antigues del Firefox.
+# LOCALIZATION NOTE (upgradetofirefoxn1):
+# %S will be a Firefox version number
+bandwagon.addon.upgradetofirefoxn1=Actualitzeu-vos al Firefox %S
+bandwagon.addon.upgradetofirefoxn2=per a utilitzar aquest.
+# LOCALIZATION NOTE (bandwagon.addon.requiresfirefoxbeta1/requiresfirefoxbeta2):
+# %S will be a Firefox version number
+bandwagon.addon.requiresfirefoxbeta1=Aquest complement requereix el Firefox %S, que encara no ha estat llançat. Per a fer servir el complement, hauríeu de
+bandwagon.addon.requiresfirefoxbeta2=baixar el Firefox %S beta.
+# LOCALIZATION NOTE (bandwagon.addon.notcompatible):
+# %S will be a platform name, such as "Windows"
+bandwagon.addon.notcompatible=Aquest complement no és compatible amb el %S.
+# LOCALIZATION NOTE (bandwagon.addon.comment.description):
+# %S will be a comment entered by the publisher of the add-on
+bandwagon.addon.comment.description=“%Sâ€
+# LOCALIZATION NOTE (bandwagon.addon.comment.author):
+# %S will be the publisher's real name or nickname
+bandwagon.addon.comment.author=Comentari de %S:
diff --git a/bandwagon/locale/ca/browserOverlay.dtd b/bandwagon/locale/ca/browserOverlay.dtd
new file mode 100644
index 0000000..a665207
--- /dev/null
+++ b/bandwagon/locale/ca/browserOverlay.dtd
@@ -0,0 +1,38 @@
+<!-- ***** BEGIN LICENSE BLOCK *****
+ - Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ -
+ - The contents of this file are subject to the Mozilla Public License Version
+ - 1.1 (the "License"); you may not use this file except in compliance with
+ - the License. You may obtain a copy of the License at
+ - http://www.mozilla.org/MPL/
+ -
+ - Software distributed under the License is distributed on an "AS IS" basis,
+ - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ - for the specific language governing rights and limitations under the
+ - License.
+ -
+ - The Original Code is bandwagon.
+ -
+ - The Initial Developer of the Original Code is
+ - Mozilla Corporation.
+ - Portions created by the Initial Developer are Copyright (C) 2008
+ - the Initial Developer. All Rights Reserved.
+ -
+ - Contributor(s): Brian King <brian (at) briks (dot) si>
+ -
+ - Alternatively, the contents of this file may be used under the terms of
+ - either the GNU General Public License Version 2 or later (the "GPL"), or
+ - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ - in which case the provisions of the GPL or the LGPL are applicable instead
+ - of those above. If you wish to allow use of your version of this file only
+ - under the terms of either the GPL or the LGPL, and not to allow others to
+ - use your version of this file under the terms of the MPL, indicate your
+ - decision by deleting the provisions above and replace them with the notice
+ - and other provisions required by the GPL or the LGPL. If you do not delete
+ - the provisions above, a recipient may use your version of this file under
+ - the terms of any one of the MPL, the GPL or the LGPL.
+ -
+ - ***** END LICENSE BLOCK ***** -->
+
+<!ENTITY bandwagon.label "Add-ons">
+<!ENTITY bandwagon.tooltip "Add-ons">
diff --git a/bandwagon/locale/ca/browserOverlay.properties b/bandwagon/locale/ca/browserOverlay.properties
new file mode 100644
index 0000000..78c864e
--- /dev/null
+++ b/bandwagon/locale/ca/browserOverlay.properties
@@ -0,0 +1,4 @@
+newaddons.alert.title=Nous complements
+# LOCALIZATION NOTE (newaddons.alert.text):
+# %S will be the name of a collection
+newaddons.alert.text=Hi ha nous complements a la vostra subscripció "%S".
diff --git a/bandwagon/locale/ca/extensionOverlay.properties b/bandwagon/locale/ca/extensionOverlay.properties
new file mode 100644
index 0000000..95379fb
--- /dev/null
+++ b/bandwagon/locale/ca/extensionOverlay.properties
@@ -0,0 +1,14 @@
+publish.new.email.address.title=Nova adreça electrònica
+publish.new.email.address.text=Entreu l'adreça de correu electrònic amb qui vulgueu compartir aquest complement:
+publish.remove.title=Confirmació
+# LOCALIZATION NOTE (publish.remove.label):
+# %1 is the name of an add-on. %2 is the name of a collection
+publish.remove.label=Segur que voleu eliminar %1$S de la col·lecció "%2$S"?
+publish.remove.button1=No, cancel·la
+publish.remove.button0=Sí, esborra el complement
+login.error=Hi ha hagut un error en iniciar la sessió. Si us plau, comproveu que el vostre nom d'usuari i contrasenya són correctes.
+unsubscribe.error=Hi ha hagut un error en donar-se de baixa d'aquesta col·lecció. Si us plau, reintenteu-ho més tard.
+unsubscribe.confirm.title=Confirm Unsubscribe
+unsubscribe.confirm.label=Unsubscribing from this collection will also remove it from your list of favorites. Are you sure you want to unsubscribe?
+unsubscribe.confirm.button1=No, cancel
+unsubscribe.confirm.button0=Yes, unsubscribe
diff --git a/bandwagon/locale/ca/extensionsOverlay.dtd b/bandwagon/locale/ca/extensionsOverlay.dtd
new file mode 100644
index 0000000..476df88
--- /dev/null
+++ b/bandwagon/locale/ca/extensionsOverlay.dtd
@@ -0,0 +1,69 @@
+<!-- ***** BEGIN LICENSE BLOCK *****
+ - Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ -
+ - The contents of this file are subject to the Mozilla Public License Version
+ - 1.1 (the "License"); you may not use this file except in compliance with
+ - the License. You may obtain a copy of the License at
+ - http://www.mozilla.org/MPL/
+ -
+ - Software distributed under the License is distributed on an "AS IS" basis,
+ - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ - for the specific language governing rights and limitations under the
+ - License.
+ -
+ - The Original Code is bandwagon.
+ -
+ - The Initial Developer of the Original Code is
+ - Mozilla Corporation.
+ - Portions created by the Initial Developer are Copyright (C) 2008
+ - the Initial Developer. All Rights Reserved.
+ -
+ - Contributor(s): Brian King <brian (at) briks (dot) si>
+ - David McNamara
+ -
+ - Alternatively, the contents of this file may be used under the terms of
+ - either the GNU General Public License Version 2 or later (the "GPL"), or
+ - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ - in which case the provisions of the GPL or the LGPL are applicable instead
+ - of those above. If you wish to allow use of your version of this file only
+ - under the terms of either the GPL or the LGPL, and not to allow others to
+ - use your version of this file under the terms of the MPL, indicate your
+ - decision by deleting the provisions above and replace them with the notice
+ - and other provisions required by the GPL or the LGPL. If you do not delete
+ - the provisions above, a recipient may use your version of this file under
+ - the terms of any one of the MPL, the GPL or the LGPL.
+ -
+ - ***** END LICENSE BLOCK ***** -->
+
+<!ENTITY collections.label "Subscripcions">
+<!ENTITY search.label.bandwagon "Cerca">
+
+<!ENTITY addon.moreinfo "Més informació.">
+<!ENTITY addon.addtofirefox "Afegeix-lo Firefox">
+<!ENTITY subscribe.label "Cerca col·lections">
+<!ENTITY reload.label "Recarrega-ho tot">
+<!ENTITY settings.label "Configuració">
+
+<!ENTITY view.label "mostra la col·lecció">
+<!ENTITY unsubscribe.label "cancel·la la subscripció">
+
+<!ENTITY nocollectionstitle.label "Benvingut al Add-on Collector">
+<!ENTITY nocollectionssubscribed.label "Aquí és on les col·leccions que marqueu com a preferides al lloc web de complements de Mozilla apareixeran, de forma que pogueu fer-ne un seguiment fàcil. Sembla que encara no n'heu afegit cap de preferida, així que per què no feu una ullada al nostre directori de col·leccions?">
+<!ENTITY clicktosubscribe.label "Cerca col·leccions">
+
+<!ENTITY noamoauth.label "Aquí és on les col·leccions que marqueu com a preferides al lloc web de complements de Mozilla apareixeran, de forma que pogueu fer-ne un seguiment fàcil. Heu d'haver iniciat sessió a addons.mozilla.org per a utilitzar aquesta funció.">
+<!ENTITY username.label "Correu electrònic">
+<!ENTITY password.label "Contrasenya">
+<!ENTITY clicktologin.label "Inicia la sessió">
+
+<!ENTITY collectionisloading.label "Recuperant la subscripció...">
+<!ENTITY collectionhasnoitems.label "Aquesta col·leció no conté cap complement.">
+<!ENTITY collectionhaserror.label "No es pot mostrar aquesta col·leció perquè conté errors.">
+
+<!ENTITY publishto.label "Publica en">
+<!ENTITY email.address.label "Correu electrònic">
+<!ENTITY new.email.address.label "Nou correu electrònic">
+<!ENTITY new.collection.label "Nova col·lecció">
+
+<!ENTITY createaccount.label "No tinc un compte">
+<!ENTITY loginheading.label "Entreu la informació del vostre compte de Mozilla Add-ons a continuació:">
diff --git a/bandwagon/locale/ca/publish.dtd b/bandwagon/locale/ca/publish.dtd
new file mode 100644
index 0000000..0e3ec14
--- /dev/null
+++ b/bandwagon/locale/ca/publish.dtd
@@ -0,0 +1,48 @@
+<!-- ***** BEGIN LICENSE BLOCK *****
+ - Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ -
+ - The contents of this file are subject to the Mozilla Public License Version
+ - 1.1 (the "License"); you may not use this file except in compliance with
+ - the License. You may obtain a copy of the License at
+ - http://www.mozilla.org/MPL/
+ -
+ - Software distributed under the License is distributed on an "AS IS" basis,
+ - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ - for the specific language governing rights and limitations under the
+ - License.
+ -
+ - The Original Code is bandwagon.
+ -
+ - The Initial Developer of the Original Code is
+ - Mozilla Corporation.
+ - Portions created by the Initial Developer are Copyright (C) 2008
+ - the Initial Developer. All Rights Reserved.
+ -
+ - Contributor(s): David McNamara
+ - Brian King <brian (at) briks (dot) si>
+ -
+ - Alternatively, the contents of this file may be used under the terms of
+ - either the GNU General Public License Version 2 or later (the "GPL"), or
+ - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ - in which case the provisions of the GPL or the LGPL are applicable instead
+ - of those above. If you wish to allow use of your version of this file only
+ - under the terms of either the GPL or the LGPL, and not to allow others to
+ - use your version of this file under the terms of the MPL, indicate your
+ - decision by deleting the provisions above and replace them with the notice
+ - and other provisions required by the GPL or the LGPL. If you do not delete
+ - the provisions above, a recipient may use your version of this file under
+ - the terms of any one of the MPL, the GPL or the LGPL.
+ -
+ - ***** END LICENSE BLOCK ***** -->
+
+<!-- For localisers to change the width of the window -->
+<!ENTITY publish.style "width: 35em;">
+
+<!ENTITY window.title "Publish">
+<!ENTITY cancel.label "Cancel">
+<!ENTITY publish.label "Publish">
+<!ENTITY new.email.label "New E-mail Address">
+<!ENTITY enter.an.email.label "Enter one or more e-mail addresses separated by commas:">
+<!ENTITY remember.this.email.label "Remember this e-mail address">
+<!ENTITY enter.a.personal.note.label "Optional: Enter a personal note about this add-on to be included in the e-mail">
+
diff --git a/bandwagon/locale/ca/publish.properties b/bandwagon/locale/ca/publish.properties
new file mode 100644
index 0000000..91a395b
--- /dev/null
+++ b/bandwagon/locale/ca/publish.properties
@@ -0,0 +1,20 @@
+# LOCALIZATION NOTE (you.are.sharing.the.add.on):
+# %S is the name of an add-on
+you.are.sharing.the.add.on=Esteu compartint el complement '%S'
+# LOCALIZATION NOTE (publishing.to):
+# %1 is the name of an add-on. %2 is the name of a collection
+publishing.to=En clicar a "Publish" s'afegirà %1$S a la col·lecció "%2$S".
+# LOCALIZATION NOTE (sharing.with):
+# %1 is a user's email address. $2 is the name of an add-on
+sharing.with=En clicar a "Envia un correu" s'enviarà a %1$S un correu electrònic amb informació sobre %2$S
+# LOCALIZATION NOTE (sharing.with.new):
+# %S is the name of an add-on
+sharing.with.new=En clicar a "Envia un correu" s'enviarà als destinataris indicats a sobre un correu electrònic amb informació sobre %S
+please.enter.an.email.address=Si us plau, entreu un correu electrònic.
+the.addon.has.been.published=El complement ha estat publicat.
+the.email.has.been.sent=El correu ha estat enviat.
+# LOCALIZATION NOTE (closing.in):
+# %S is the number of seconds until a window closes, counting down
+closing.in=La finestra es tancarà en %S...
+send.email=Envia un correu
+error.unknown_addon_guid=Aquest complement no es pot compartir perquè no és al lloc web de Complements de Mozilla.
diff --git a/bandwagon/locale/ca/settings.dtd b/bandwagon/locale/ca/settings.dtd
new file mode 100644
index 0000000..29e5f9d
--- /dev/null
+++ b/bandwagon/locale/ca/settings.dtd
@@ -0,0 +1,108 @@
+<!-- ***** BEGIN LICENSE BLOCK *****
+ - Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ -
+ - The contents of this file are subject to the Mozilla Public License Version
+ - 1.1 (the "License"); you may not use this file except in compliance with
+ - the License. You may obtain a copy of the License at
+ - http://www.mozilla.org/MPL/
+ -
+ - Software distributed under the License is distributed on an "AS IS" basis,
+ - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ - for the specific language governing rights and limitations under the
+ - License.
+ -
+ - The Original Code is bandwagon.
+ -
+ - The Initial Developer of the Original Code is
+ - Mozilla Corporation.
+ - Portions created by the Initial Developer are Copyright (C) 2008
+ - the Initial Developer. All Rights Reserved.
+ -
+ - Contributor(s): Brian King <brian (at) briks (dot) si>
+ - David McNamara
+ -
+ - Alternatively, the contents of this file may be used under the terms of
+ - either the GNU General Public License Version 2 or later (the "GPL"), or
+ - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ - in which case the provisions of the GPL or the LGPL are applicable instead
+ - of those above. If you wish to allow use of your version of this file only
+ - under the terms of either the GPL or the LGPL, and not to allow others to
+ - use your version of this file under the terms of the MPL, indicate your
+ - decision by deleting the provisions above and replace them with the notice
+ - and other provisions required by the GPL or the LGPL. If you do not delete
+ - the provisions above, a recipient may use your version of this file under
+ - the terms of any one of the MPL, the GPL or the LGPL.
+ -
+ - ***** END LICENSE BLOCK ***** -->
+
+<!-- For localisers to change the width of the window -->
+<!ENTITY settings.style "width: 42em;">
+
+<!ENTITY window.title "Add-on Collector Settings">
+
+<!-- Tabs -->
+<!ENTITY manage.label "Manage Subscriptions">
+<!ENTITY general.label "General Settings">
+<!ENTITY pub.label "Auto-publisher Settings">
+
+<!-- Manage Subscriptions -->
+<!ENTITY subscriptions.header "Subscriptions:">
+
+<!-- Groupbox captions in Manage Subscriptions -->
+<!ENTITY frequency.label "Subscription Update Frequency">
+<!ENTITY notifications.label "New Add-on Notifications">
+<!ENTITY perpage.label "Add-ons per Page">
+
+<!ENTITY default.label "Use default setting">
+<!ENTITY custom.label "Custom:">
+
+<!ENTITY addonsleadin.label "Show">
+<!ENTITY addonsperpage.label "add-ons per page">
+<!ENTITY updatesingle.label "Update every:">
+<!ENTITY minutes.label "minute(s)">
+<!ENTITY hours.label "hour(s)">
+<!ENTITY days.label "day(s)">
+<!ENTITY autopublish.label "Auto-publish installed add-ons to subscription">
+<!ENTITY notify.label "Show notifications">
+<!ENTITY applyall.label "Apply to all subscriptions">
+<!ENTITY remove.label "Remove Subscription">
+<!ENTITY on.label "On">
+<!ENTITY off.label "Off">
+
+<!-- General -->
+
+<!-- Groupbox captions in General -->
+<!ENTITY subscriptions.label "Default Subscription Settings">
+<!ENTITY data.label "Data Management">
+
+<!ENTITY updateall.label "Check subscriptions for updates every">
+<!ENTITY notifyglobal.label "Notify me when my subscriptions have new add-ons">
+
+<!ENTITY clearemails.label "Clear">
+<!ENTITY login.label "Login">
+<!ENTITY logout.label "Logout">
+
+<!-- Auto-Publisher Settings -->
+
+<!-- Groupbox captions in Auto-Publisher Settings -->
+<!ENTITY auto.label "Auto-publisher Settings">
+
+<!ENTITY name.label "Collection Name:">
+<!ENTITY list.label "Listed in public Collection Directory">
+
+<!ENTITY autoleadin.label "Auto-publishers are special collections that are automatically updated when you install or uninstall add-ons from Firefox on this computer.">
+<!ENTITY types.label "Auto-published add-on types:">
+<!ENTITY type.extensions.label "Extensions">
+<!ENTITY type.themes.label "Themes">
+<!ENTITY type.dicts.label "Dictionaries">
+<!ENTITY type.langpacks.label "Language Packs">
+
+<!ENTITY createauto.label "Create Auto-publisher">
+<!ENTITY deleteauto.label "Delete Auto-publisher">
+<!ENTITY updateauto.label "Update Auto-publisher">
+
+<!ENTITY onlypublishenabledaddons.label "Only publish enabled add-ons">
+
+<!ENTITY misc.label "Miscellaneous">
+<!ENTITY allowincompatibleinstall.label "Allow installation of incompatible add-ons from my subscriptions">
+
diff --git a/bandwagon/locale/ca/settings.properties b/bandwagon/locale/ca/settings.properties
new file mode 100644
index 0000000..eb430cd
--- /dev/null
+++ b/bandwagon/locale/ca/settings.properties
@@ -0,0 +1,26 @@
+add.collection=Afegeix una subscripció
+enter.url.to.add.collection=Entreu la URL de la subscripció que voleu afegir.
+remove.collection=Elimina subscripció
+# LOCALIZATION NOTE (are.you.sure.you.want.to.remove):
+# %S is the name of a collection
+are.you.sure.you.want.to.remove=Eliminar aquesta subscripció també suprimirà la col·lecció de la vostra llista de preferides. Segur que voleu eliminar '%S'?
+# LOCALIZATION NOTE (saved.emails.text):
+# %S is a number
+saved.emails.text=You have %S saved e-mail addresses
+# LOCALIZATION NOTE (login.status.with.email):
+# %S is a user's email address
+login.status.with.email=Heu iniciat la sessió com %S
+login.status=Sessió iniciada
+logout.status=Sessió no iniciada
+# LOCALIZATION NOTE (auto.invalid.name):
+# %S is the name of a collection
+auto.invalid.name=El nom '%S' de la col·lecció no és vàlid.
+auto.please.select.type=Si us plau, seleccioneu com a mínim un tipus de complement per a publicar automàticament.
+auto.create.internal.error=No s'ha pogut crear la col·lecció (hi ha hagut un error intern).
+auto.create.done=Your auto-publisher collection has been created.
+auto.delete.internal.error=No s'ha pogut eliminar la col·lecció (ha ocorregut un error intern).
+auto.delete.done=Your auto-publisher collection has been deleted.
+auto.create.description=Una llista generada automàticament dels meus complements instal·lats
+auto.update.confirm.message=Your new settings will take effect immediately, but will not affect add-ons that have already been published.
+auto.update.internal.error=The collection could not be updated (an internal error occured).
+auto.update.done=Your auto-pubisher collection has been updated.
diff --git a/bandwagon/locale/cs/bandwagon.properties b/bandwagon/locale/cs/bandwagon.properties
new file mode 100644
index 0000000..b105fcf
--- /dev/null
+++ b/bandwagon/locale/cs/bandwagon.properties
@@ -0,0 +1,2 @@
+extensions.sharing@addons.mozilla.org.description=Sdílení a objevování doplňků.
+extensions.sharing@addons.mozilla.org.name=Sbírky doplňků
diff --git a/bandwagon/locale/cs/bandwagonAddon.properties b/bandwagon/locale/cs/bandwagonAddon.properties
new file mode 100644
index 0000000..5e05372
--- /dev/null
+++ b/bandwagon/locale/cs/bandwagonAddon.properties
@@ -0,0 +1,38 @@
+# LOCALIZATION NOTE (bandwagon.addon.pluralRule):
+# See https://developer.mozilla.org/En/Localization_and_Plurals
+bandwagon.addon.pluralRule=8
+bandwagon.category1=Rozšíření
+# LOCALIZATION NOTE (bandwagon.addon.author):
+# %S will contain author's first and last name, or their nickname used on AMO
+bandwagon.addon.author=Autor %S
+# LOCALIZATION NOTE (bandwagon.addon.addedby):
+# %S will be a user's first and last name, or nickname
+bandwagon.addon.addedby=od %S
+bandwagon.addon.added.justnow=PÅ™idáno právÄ› teÄ
+# LOCALIZATION NOTE:
+# %S will be a number of time units indicated
+bandwagon.addon.added.minute=Přidáno před minutou;Přidáno před %S minutami;Přidáno před %S minutami
+bandwagon.addon.added.hour=Přidáno před hodinou;Přidáno před %S hodinami;Přidáno před %S hodinami
+bandwagon.addon.added.day=PÅ™idáno vÄera;PÅ™idáno pÅ™ed %S dny;PÅ™idáno pÅ™ed %S dny
+bandwagon.addon.added.week=Přidáno před týdnem;Přidáno před %S týdny;Přidáno před %S týdny
+bandwagon.addon.added.month=Přidáno před měsícem;Přidáno před %S měsíci;Přidáno před %S měsíci
+bandwagon.addon.added.year=Přidáno před rokem;Přidáno před %S roky;Přidáno před %S lety
+bandwagon.addon.moreinfo=Více informací.
+bandwagon.addon.olderversionsoffirefox=Tento doplněk je pro starší verze Firefoxu.
+# LOCALIZATION NOTE (upgradetofirefoxn1):
+# %S will be a Firefox version number
+bandwagon.addon.upgradetofirefoxn1=Aktualizujte na Firefox %S
+bandwagon.addon.upgradetofirefoxn2=, pokud chcete použít tento doplněk.
+# LOCALIZATION NOTE (bandwagon.addon.requiresfirefoxbeta1/requiresfirefoxbeta2):
+# %S will be a Firefox version number
+bandwagon.addon.requiresfirefoxbeta1=Tento doplněk vyžaduje Firefox %S, který nebyl ještě vydán. Pokud chcete použít tento doplněk,
+bandwagon.addon.requiresfirefoxbeta2=stáhněte si Firefox %S beta.
+# LOCALIZATION NOTE (bandwagon.addon.notcompatible):
+# %S will be a platform name, such as "Windows"
+bandwagon.addon.notcompatible=Tento doplněk není kompatibilní s %S.
+# LOCALIZATION NOTE (bandwagon.addon.comment.description):
+# %S will be a comment entered by the publisher of the add-on
+bandwagon.addon.comment.description=“%Sâ€
+# LOCALIZATION NOTE (bandwagon.addon.comment.author):
+# %S will be the publisher's real name or nickname
+bandwagon.addon.comment.author=Komentář od %S:
diff --git a/bandwagon/locale/cs/browserOverlay.dtd b/bandwagon/locale/cs/browserOverlay.dtd
new file mode 100644
index 0000000..6b28e4a
--- /dev/null
+++ b/bandwagon/locale/cs/browserOverlay.dtd
@@ -0,0 +1,38 @@
+<!-- ***** BEGIN LICENSE BLOCK *****
+ - Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ -
+ - The contents of this file are subject to the Mozilla Public License Version
+ - 1.1 (the "License"); you may not use this file except in compliance with
+ - the License. You may obtain a copy of the License at
+ - http://www.mozilla.org/MPL/
+ -
+ - Software distributed under the License is distributed on an "AS IS" basis,
+ - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ - for the specific language governing rights and limitations under the
+ - License.
+ -
+ - The Original Code is bandwagon.
+ -
+ - The Initial Developer of the Original Code is
+ - Mozilla Corporation.
+ - Portions created by the Initial Developer are Copyright (C) 2008
+ - the Initial Developer. All Rights Reserved.
+ -
+ - Contributor(s): Brian King <brian (at) briks (dot) si>
+ -
+ - Alternatively, the contents of this file may be used under the terms of
+ - either the GNU General Public License Version 2 or later (the "GPL"), or
+ - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ - in which case the provisions of the GPL or the LGPL are applicable instead
+ - of those above. If you wish to allow use of your version of this file only
+ - under the terms of either the GPL or the LGPL, and not to allow others to
+ - use your version of this file under the terms of the MPL, indicate your
+ - decision by deleting the provisions above and replace them with the notice
+ - and other provisions required by the GPL or the LGPL. If you do not delete
+ - the provisions above, a recipient may use your version of this file under
+ - the terms of any one of the MPL, the GPL or the LGPL.
+ -
+ - ***** END LICENSE BLOCK ***** -->
+
+<!ENTITY bandwagon.label "Doplňky">
+<!ENTITY bandwagon.tooltip "Doplňky">
diff --git a/bandwagon/locale/cs/browserOverlay.properties b/bandwagon/locale/cs/browserOverlay.properties
new file mode 100644
index 0000000..98ad510
--- /dev/null
+++ b/bandwagon/locale/cs/browserOverlay.properties
@@ -0,0 +1,4 @@
+newaddons.alert.title=Nové doplňky
+# LOCALIZATION NOTE (newaddons.alert.text):
+# %S will be the name of a collection
+newaddons.alert.text=Ve vaší sbírce "%S" jsou nové doplňky.
diff --git a/bandwagon/locale/cs/contents.rdf b/bandwagon/locale/cs/contents.rdf
new file mode 100644
index 0000000..a406982
--- /dev/null
+++ b/bandwagon/locale/cs/contents.rdf
@@ -0,0 +1,15 @@
+<?xml version="1.0"?>
+<RDF:RDF xmlns:RDF="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:chrome="http://www.mozilla.org/rdf/chrome#">
+ <RDF:Seq about="urn:mozilla:locale:root">
+ <RDF:li resource="urn:mozilla:locale:cs"/>
+ </RDF:Seq>
+ <RDF:Description about="urn:mozilla:locale:cs" chrome:name="cs" >
+ <chrome:packages>
+ <RDF:Seq about="urn:mozilla:locale:cs:packages">
+ <RDF:li resource="urn:mozilla:locale:cs:bandwagon"/>
+ </RDF:Seq>
+ </chrome:packages>
+ </RDF:Description>
+</RDF:RDF>
+
diff --git a/bandwagon/locale/cs/extensionOverlay.properties b/bandwagon/locale/cs/extensionOverlay.properties
new file mode 100644
index 0000000..ac2516c
--- /dev/null
+++ b/bandwagon/locale/cs/extensionOverlay.properties
@@ -0,0 +1,15 @@
+publish.new.email.address.title=Nová e-mailová adresa
+publish.new.email.address.text=Pro sdílení tohoto doplňku vložte novou e-mailovou adresu:
+publish.remove.title=Potvrzení
+# LOCALIZATION NOTE (publish.remove.label):
+# %1 is the name of an add-on. %2 is the name of a collection
+publish.remove.label=Opravdu chcete odebrat doplněk %1$S ze sbírky "%2$S"?
+publish.remove.button1=Ne, zrušit
+publish.remove.button0=Ano, odebrat
+login.error=Při přihlašování nastala chyba. Zkontroujte si prosím své uživatelské jméno a heslo.
+unsubscribe.error=Při odebrání této sbírky nastala chyba. Zkuste to prosím později.
+unsubscribe.confirm.title=Potvrzení odebrání
+unsubscribe.confirm.label=Odebrání této sbírky ji odstraní ze seznamu oblíbených. Opravdu ji chcete odebrat?
+unsubscribe.confirm.button1=Ne, zrušit
+unsubscribe.confirm.button0=Ano, odebrat
+
diff --git a/bandwagon/locale/cs/extensionsOverlay.dtd b/bandwagon/locale/cs/extensionsOverlay.dtd
new file mode 100644
index 0000000..ab00175
--- /dev/null
+++ b/bandwagon/locale/cs/extensionsOverlay.dtd
@@ -0,0 +1,68 @@
+<!-- ***** BEGIN LICENSE BLOCK *****
+ - Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ -
+ - The contents of this file are subject to the Mozilla Public License Version
+ - 1.1 (the "License"); you may not use this file except in compliance with
+ - the License. You may obtain a copy of the License at
+ - http://www.mozilla.org/MPL/
+ -
+ - Software distributed under the License is distributed on an "AS IS" basis,
+ - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ - for the specific language governing rights and limitations under the
+ - License.
+ -
+ - The Original Code is bandwagon.
+ -
+ - The Initial Developer of the Original Code is
+ - Mozilla Corporation.
+ - Portions created by the Initial Developer are Copyright (C) 2008
+ - the Initial Developer. All Rights Reserved.
+ -
+ - Contributor(s): Brian King <brian (at) briks (dot) si>
+ - David McNamara
+ -
+ - Alternatively, the contents of this file may be used under the terms of
+ - either the GNU General Public License Version 2 or later (the "GPL"), or
+ - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ - in which case the provisions of the GPL or the LGPL are applicable instead
+ - of those above. If you wish to allow use of your version of this file only
+ - under the terms of either the GPL or the LGPL, and not to allow others to
+ - use your version of this file under the terms of the MPL, indicate your
+ - decision by deleting the provisions above and replace them with the notice
+ - and other provisions required by the GPL or the LGPL. If you do not delete
+ - the provisions above, a recipient may use your version of this file under
+ - the terms of any one of the MPL, the GPL or the LGPL.
+ -
+ - ***** END LICENSE BLOCK ***** -->
+
+<!ENTITY collections.label "Sbírky">
+<!ENTITY search.label.bandwagon "Hledat">
+
+<!ENTITY addon.moreinfo "Více informací.">
+<!ENTITY addon.addtofirefox "Přidat do Firefoxu">
+<!ENTITY subscribe.label "Najít sbírku">
+<!ENTITY reload.label "Obnovit vše">
+<!ENTITY settings.label "Nastavení">
+
+<!ENTITY view.label "Zobrazit sbírku">
+<!ENTITY unsubscribe.label "Odhlásit odebírání">
+
+<!ENTITY nocollectionstitle.label "Vítejte ve sbÄ›raÄi doplňků">
+<!ENTITY nocollectionssubscribed.label "Zde se zobrazují sbírky, které jste na serveru Doplňky Mozilly oznaÄili jako oblíbené. Vypadáto, že zatím žádnou oblíbenou nemáte. ProÄ se tedy neporozhlédnout v adresáři sbírek?">
+<!ENTITY clicktosubscribe.label "Najít sbírku">
+
+<!ENTITY noamoauth.label "Zde se zobrazují sbírky, které jste na serveru Doplňky Mozilly oznaÄili jako oblíbené. Pro použití této funkce musíte být k serveru addons.mozilla.org pÅ™ihlášeni.">
+<!ENTITY username.label "Uživatelské jméno">
+<!ENTITY password.label "Heslo">
+<!ENTITY clicktologin.label "Přihlásit">
+
+<!ENTITY collectionisloading.label "Přijímání sbírky…">
+<!ENTITY collectionhasnoitems.label "Tato sbírka neobsahuje žádné doplňky.">
+<!ENTITY collectionhaserror.label "Tato sbírka nemůže být zobrazena, neboť obsahuje chyby.">
+
+<!ENTITY publishto.label "Publikovat">
+<!ENTITY email.address.label "E-mailová adresa">
+<!ENTITY new.email.address.label "Nová e-mailová adresa">
+<!ENTITY new.collection.label "Nová sbírka">
+<!ENTITY createaccount.label "Nemám úÄet">
+<!ENTITY loginheading.label "Vložte prosím informace o vaÅ¡em úÄtu na serveru Doplňky Mozilly:">
diff --git a/bandwagon/locale/cs/publish.dtd b/bandwagon/locale/cs/publish.dtd
new file mode 100644
index 0000000..bba1c00
--- /dev/null
+++ b/bandwagon/locale/cs/publish.dtd
@@ -0,0 +1,47 @@
+<!-- ***** BEGIN LICENSE BLOCK *****
+ - Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ -
+ - The contents of this file are subject to the Mozilla Public License Version
+ - 1.1 (the "License"); you may not use this file except in compliance with
+ - the License. You may obtain a copy of the License at
+ - http://www.mozilla.org/MPL/
+ -
+ - Software distributed under the License is distributed on an "AS IS" basis,
+ - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ - for the specific language governing rights and limitations under the
+ - License.
+ -
+ - The Original Code is bandwagon.
+ -
+ - The Initial Developer of the Original Code is
+ - Mozilla Corporation.
+ - Portions created by the Initial Developer are Copyright (C) 2008
+ - the Initial Developer. All Rights Reserved.
+ -
+ - Contributor(s): David McNamara
+ - Brian King <brian (at) briks (dot) si>
+ -
+ - Alternatively, the contents of this file may be used under the terms of
+ - either the GNU General Public License Version 2 or later (the "GPL"), or
+ - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ - in which case the provisions of the GPL or the LGPL are applicable instead
+ - of those above. If you wish to allow use of your version of this file only
+ - under the terms of either the GPL or the LGPL, and not to allow others to
+ - use your version of this file under the terms of the MPL, indicate your
+ - decision by deleting the provisions above and replace them with the notice
+ - and other provisions required by the GPL or the LGPL. If you do not delete
+ - the provisions above, a recipient may use your version of this file under
+ - the terms of any one of the MPL, the GPL or the LGPL.
+ -
+ - ***** END LICENSE BLOCK ***** -->
+
+<!-- For localisers to change the width of the window -->
+<!ENTITY publish.style "width: 35em;">
+
+<!ENTITY window.title "Publikování">
+<!ENTITY cancel.label "Zrušit">
+<!ENTITY publish.label "Publikovat">
+<!ENTITY new.email.label "Nová e-mailová adresa">
+<!ENTITY enter.an.email.label "Vložte jednu nebo více e-mailových adres oddÄ›lených Äárkou:">
+<!ENTITY remember.this.email.label "Pamatovat si tuto e-mailovou adresu">
+<!ENTITY enter.a.personal.note.label "Dobrovolné: Vložte osobní poznámku o doplňku, která bude připojena k vašemu e-mailu">
diff --git a/bandwagon/locale/cs/publish.properties b/bandwagon/locale/cs/publish.properties
new file mode 100644
index 0000000..70804b9
--- /dev/null
+++ b/bandwagon/locale/cs/publish.properties
@@ -0,0 +1,20 @@
+# LOCALIZATION NOTE (you.are.sharing.the.add.on):
+# %S is the name of an add-on
+you.are.sharing.the.add.on=Sdílíte doplněk '%S'
+# LOCALIZATION NOTE (publishing.to):
+# %1 is the name of an add-on. %2 is the name of a collection
+publishing.to=Klepnutím na "Publikovat" přidáte doplněk %1$S do sbírky "%2$S".
+# LOCALIZATION NOTE (sharing.with):
+# %1 is a user's email address. %2 is the name of an add-on
+sharing.with=Klepnutím na "Odeslat e-mail" odešlete na %1$S e-mail s informacemi o doplňku %2$S.
+# LOCALIZATION NOTE (sharing.with.new):
+# %S is the name of an add-on
+sharing.with.new=Klepnutím na "Odeslat e-mail" odešlete příjemcům výše e-mail s informacemi o doplňku %S
+please.enter.an.email.address=Vložte prosím e-mailovou adresu.
+the.addon.has.been.published=Doplněk byl publikován.
+the.email.has.been.sent=E-mail byl odeslán.
+# LOCALIZATION NOTE (closing.in):
+# %S is the number of seconds until a window closes, counting down
+closing.in=Zavře se za %S…
+send.email=Odeslat e-mail
+error.unknown_addon_guid=Tento doplněk nemůže být sdílen, neboť není hostován na serveru doplňky Mozilly.
diff --git a/bandwagon/locale/cs/settings.dtd b/bandwagon/locale/cs/settings.dtd
new file mode 100644
index 0000000..8ad1016
--- /dev/null
+++ b/bandwagon/locale/cs/settings.dtd
@@ -0,0 +1,108 @@
+<!-- ***** BEGIN LICENSE BLOCK *****
+ - Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ -
+ - The contents of this file are subject to the Mozilla Public License Version
+ - 1.1 (the "License"); you may not use this file except in compliance with
+ - the License. You may obtain a copy of the License at
+ - http://www.mozilla.org/MPL/
+ -
+ - Software distributed under the License is distributed on an "AS IS" basis,
+ - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ - for the specific language governing rights and limitations under the
+ - License.
+ -
+ - The Original Code is bandwagon.
+ -
+ - The Initial Developer of the Original Code is
+ - Mozilla Corporation.
+ - Portions created by the Initial Developer are Copyright (C) 2008
+ - the Initial Developer. All Rights Reserved.
+ -
+ - Contributor(s): Brian King <brian (at) briks (dot) si>
+ - David McNamara
+ -
+ - Alternatively, the contents of this file may be used under the terms of
+ - either the GNU General Public License Version 2 or later (the "GPL"), or
+ - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ - in which case the provisions of the GPL or the LGPL are applicable instead
+ - of those above. If you wish to allow use of your version of this file only
+ - under the terms of either the GPL or the LGPL, and not to allow others to
+ - use your version of this file under the terms of the MPL, indicate your
+ - decision by deleting the provisions above and replace them with the notice
+ - and other provisions required by the GPL or the LGPL. If you do not delete
+ - the provisions above, a recipient may use your version of this file under
+ - the terms of any one of the MPL, the GPL or the LGPL.
+ -
+ - ***** END LICENSE BLOCK ***** -->
+
+<!-- For localisers to change the width of the window -->
+<!ENTITY settings.style "width: 42em;">
+
+<!ENTITY window.title "Nastavení sbírek doplňků">
+
+<!-- Tabs -->
+<!ENTITY manage.label "Odebírání">
+<!ENTITY general.label "Obecné">
+<!ENTITY pub.label "Autopublikace">
+
+<!-- Manage Subscriptions -->
+<!ENTITY subscriptions.header "Odebírání:">
+
+<!-- Groupbox captions in Manage Subscriptions -->
+<!ENTITY frequency.label "Frekvence aktualizace">
+<!ENTITY notifications.label "Upozornění na nový doplněk">
+<!ENTITY perpage.label "Doplňků na stránku">
+
+<!ENTITY default.label "Použít výchozí nastavení">
+<!ENTITY custom.label "Vlastní:">
+
+<!ENTITY addonsleadin.label "Zobrazit">
+<!ENTITY addonsperpage.label "doplňků na stránku">
+<!ENTITY updatesingle.label "Aktualizovat každých:">
+<!ENTITY minutes.label "minut">
+<!ENTITY hours.label "hodin">
+<!ENTITY days.label "dnů">
+<!ENTITY autopublish.label "Automaticky publikovat do sbírky nově nainstalované doplňky">
+<!ENTITY notify.label "Zobrazit upozornění">
+<!ENTITY applyall.label "Použít pro všechna odebírání">
+<!ENTITY remove.label "UkonÄit odebírání">
+<!ENTITY on.label "Vypnuto">
+<!ENTITY off.label "Zapnuto">
+
+<!-- General -->
+
+<!-- Groupbox captions in General -->
+<!ENTITY subscriptions.label "Výchozí nastavení odebírání">
+<!ENTITY data.label "Správa dat">
+
+<!ENTITY updateall.label "Kontrolovat aktualizace každých">
+<!ENTITY notifyglobal.label "Upozornit pokud odebírané sbírky obsahují nový doplněk">
+
+<!ENTITY clearemails.label "Vymazat">
+<!ENTITY login.label "Přihlásit">
+<!ENTITY logout.label "Odhlásit">
+
+<!-- Auto-Publisher Settings -->
+
+<!-- Groupbox captions in Auto-Publisher Settings -->
+<!ENTITY auto.label "Nastavení autopublikace">
+
+<!ENTITY name.label "Název sbírky:">
+<!ENTITY list.label "Zobrazit ve veřejném adresáři sbírek">
+
+<!ENTITY autoleadin.label "Automaticky publikované sbírky jsou speciální sbírky, které se automaticky aktualizují pokud na tomto poÄítaÄi nainstalujte nebo odinstalujete doplnÄ›k Firefoxu.">
+<!ENTITY types.label "Typy publikovaných doplňky:">
+<!ENTITY type.extensions.label "Rozšíření">
+<!ENTITY type.themes.label "Motivy vzhledu">
+<!ENTITY type.dicts.label "Slovníky">
+<!ENTITY type.langpacks.label "Jazykové balíky">
+
+<!ENTITY createauto.label "Vytvořit automaticky publikovanou sbírku">
+<!ENTITY deleteauto.label "Smazat automaticky publikovanou sbírku">
+<!ENTITY updateauto.label "Aktualizovat automaticky publikovanou sbírku">
+
+<!ENTITY onlypublishenabledaddons.label "Publikovat pouze povolené doplňky">
+
+<!ENTITY misc.label "Různé">
+<!ENTITY allowincompatibleinstall.label "Povolit instalaci nekompletních doplňků z mých sbírek">
+
diff --git a/bandwagon/locale/cs/settings.properties b/bandwagon/locale/cs/settings.properties
new file mode 100644
index 0000000..1dbcc80
--- /dev/null
+++ b/bandwagon/locale/cs/settings.properties
@@ -0,0 +1,26 @@
+add.collection=Přidat sbírku
+enter.url.to.add.collection=Vložte adresu sbírky, kterou chcete přidat.
+remove.collection=Odebrat sbírku
+# LOCALIZATION NOTE (are.you.sure.you.want.to.remove):
+# %S is the name of a collection
+are.you.sure.you.want.to.remove=Odebrání této sbírky ji odstraní ze seznamu oblíbených. Opravdu chcete odebrat '%S'?
+# LOCALIZATION NOTE (saved.emails.text):
+# %S is a number
+saved.emails.text=Máte uloženo %S e-mailových adres
+# LOCALIZATION NOTE (login.status.with.email):
+# %S is a user's email address
+login.status.with.email=Jste přihlášen jako %S
+login.status=Přihlášen
+logout.status=Nepřihlášen
+# LOCALIZATION NOTE (auto.invalid.name):
+# %S is the name of a collection
+auto.invalid.name=Název sbírky '%S' je neplatný.
+auto.please.select.type=Zvolte prosím nejméně jeden typ doplňku, který se bude automaticky publikovat.
+auto.create.internal.error=Sbírku se nepodařilo vytvořit (nastala interní chyba).
+auto.create.done=Automaticky publikovaná sbírka byla vytvořena.
+auto.delete.internal.error=Sbírku se nepodařilo smazat (nastala interní chyba).
+auto.delete.done=Automaticky publikovaná sbírka byla smazána.
+auto.create.description=Automaticky generovaný seznam mých nainstalovaných doplňků
+auto.update.confirm.message=Nové nastavení je úÄinné okamžitÄ›, ale neovlivní doplňky, které již byly publikovány.
+auto.update.internal.error=Sbírku se nepodařilo aktualizovat (an internal error occured).
+auto.update.done=Automaticky publikovaná sbírka byla aktualizována.
diff --git a/bandwagon/locale/da/bandwagon.properties b/bandwagon/locale/da/bandwagon.properties
new file mode 100644
index 0000000..f643010
--- /dev/null
+++ b/bandwagon/locale/da/bandwagon.properties
@@ -0,0 +1,2 @@
+extensions.sharing@addons.mozilla.org.description=Del og find tilføjelser.
+extensions.sharing@addons.mozilla.org.name=Tilføjelsessamleren \ No newline at end of file
diff --git a/bandwagon/locale/da/bandwagonAddon.properties b/bandwagon/locale/da/bandwagonAddon.properties
new file mode 100644
index 0000000..9d5157d
--- /dev/null
+++ b/bandwagon/locale/da/bandwagonAddon.properties
@@ -0,0 +1,38 @@
+# LOCALIZATION NOTE (bandwagon.addon.pluralRule):
+# See https://developer.mozilla.org/En/Localization_and_Plurals
+bandwagon.addon.pluralRule=1
+bandwagon.category1=Udvidelse
+# LOCALIZATION NOTE (bandwagon.addon.author):
+# %S will contain author's first and last name, or their nickname used on AMO
+bandwagon.addon.author=Af %S
+# LOCALIZATION NOTE (bandwagon.addon.addedby):
+# %S will be a user's first and last name, or nickname
+bandwagon.addon.addedby=af %S
+bandwagon.addon.added.justnow=Tilføjet lige nu
+# LOCALIZATION NOTE:
+# %S will be a number of time units indicated
+bandwagon.addon.added.minute=Tilføjet for 1 minut siden;Tilføjet for %S minutter siden
+bandwagon.addon.added.hour=Tilføjet for 1 time siden;Tilføjet for %S timer siden
+bandwagon.addon.added.day=Tilføjet i går;Tilføjet for %S dage siden
+bandwagon.addon.added.week=Tilføjet for 1 uge siden;Tilføjet for %S uger siden
+bandwagon.addon.added.month=Tilføjet for 1 måned siden;Tilføjet for %S måneder siden
+bandwagon.addon.added.year=Tilføjet for 1 år siden;Tilføjet for %S år siden
+bandwagon.addon.moreinfo=Mere info.
+bandwagon.addon.olderversionsoffirefox=Denne tilføjelse er til ældre versioner af Firefox.
+# LOCALIZATION NOTE (upgradetofirefoxn1):
+# %S will be a Firefox version number
+bandwagon.addon.upgradetofirefoxn1=Opdater til Firefox %S
+bandwagon.addon.upgradetofirefoxn2=for at bruge denne tilføjelse.
+# LOCALIZATION NOTE (bandwagon.addon.requiresfirefoxbeta1/requiresfirefoxbeta2):
+# %S will be a Firefox version number
+bandwagon.addon.requiresfirefoxbeta1=Denne tilføjelse kræver Firefox %S, som endnu ikke er udgivet. For at bruge denne tilføjelse kan du
+bandwagon.addon.requiresfirefoxbeta2=downloade Firefox %S beta.
+# LOCALIZATION NOTE (bandwagon.addon.notcompatible):
+# %S will be a platform name, such as "Windows"
+bandwagon.addon.notcompatible=Denne tilføjelse er ikke kompatibel med %S.
+# LOCALIZATION NOTE (bandwagon.addon.comment.description):
+# %S will be a comment entered by the publisher of the add-on
+bandwagon.addon.comment.description=“%Sâ€
+# LOCALIZATION NOTE (bandwagon.addon.comment.author):
+# %S will be the publisher's real name or nickname
+bandwagon.addon.comment.author=Kommentar fra %S:
diff --git a/bandwagon/locale/da/browserOverlay.dtd b/bandwagon/locale/da/browserOverlay.dtd
new file mode 100644
index 0000000..104a8ec
--- /dev/null
+++ b/bandwagon/locale/da/browserOverlay.dtd
@@ -0,0 +1,38 @@
+<!-- ***** BEGIN LICENSE BLOCK *****
+ - Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ -
+ - The contents of this file are subject to the Mozilla Public License Version
+ - 1.1 (the "License"); you may not use this file except in compliance with
+ - the License. You may obtain a copy of the License at
+ - http://www.mozilla.org/MPL/
+ -
+ - Software distributed under the License is distributed on an "AS IS" basis,
+ - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ - for the specific language governing rights and limitations under the
+ - License.
+ -
+ - The Original Code is bandwagon.
+ -
+ - The Initial Developer of the Original Code is
+ - Mozilla Corporation.
+ - Portions created by the Initial Developer are Copyright (C) 2008
+ - the Initial Developer. All Rights Reserved.
+ -
+ - Contributor(s): Brian King <brian (at) briks (dot) si>
+ -
+ - Alternatively, the contents of this file may be used under the terms of
+ - either the GNU General Public License Version 2 or later (the "GPL"), or
+ - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ - in which case the provisions of the GPL or the LGPL are applicable instead
+ - of those above. If you wish to allow use of your version of this file only
+ - under the terms of either the GPL or the LGPL, and not to allow others to
+ - use your version of this file under the terms of the MPL, indicate your
+ - decision by deleting the provisions above and replace them with the notice
+ - and other provisions required by the GPL or the LGPL. If you do not delete
+ - the provisions above, a recipient may use your version of this file under
+ - the terms of any one of the MPL, the GPL or the LGPL.
+ -
+ - ***** END LICENSE BLOCK ***** -->
+
+<!ENTITY bandwagon.label "Tilføjelser">
+<!ENTITY bandwagon.tooltip "Tilføjelser">
diff --git a/bandwagon/locale/da/browserOverlay.properties b/bandwagon/locale/da/browserOverlay.properties
new file mode 100644
index 0000000..1053111
--- /dev/null
+++ b/bandwagon/locale/da/browserOverlay.properties
@@ -0,0 +1,4 @@
+newaddons.alert.title=Nye tilføjelser
+# LOCALIZATION NOTE (newaddons.alert.text):
+# %S will be the name of a collection
+newaddons.alert.text=Der er nye tilføjelser i dit abonnement "%S".
diff --git a/bandwagon/locale/da/extensionOverlay.properties b/bandwagon/locale/da/extensionOverlay.properties
new file mode 100644
index 0000000..b53d699
--- /dev/null
+++ b/bandwagon/locale/da/extensionOverlay.properties
@@ -0,0 +1,14 @@
+publish.new.email.address.title=Ny e-mail-adresse
+publish.new.email.address.text=Indtast en ny e-mail-adresse som denne tilføjelse skal deles med:
+publish.remove.title=Bekræft
+# LOCALIZATION NOTE (publish.remove.label):
+# %1 is the name of an add-on. %2 is the name of a collection
+publish.remove.label=Er du sikker på, at du vil fjerne %1$S fra samlingen "%2$S"?
+publish.remove.button1=Nej, annuller
+publish.remove.button0=Ja, fjern tilføjelsen
+login.error=Der skete en fejl ved login. Kontroller om dit brugernavn og din adgangskode er korrekt.
+unsubscribe.error=Der skete en fejl ved afmelding fra denne samling. Prøv igen senere.
+unsubscribe.confirm.title=Bekræft afmelding
+unsubscribe.confirm.label=Når du afmelder denne samling, vil den også blive fjernet fra din liste over favoritter. Er du sikker på, at du vil afmelde?
+unsubscribe.confirm.button1=Nej, annuller
+unsubscribe.confirm.button0=Ja, afmeld
diff --git a/bandwagon/locale/da/extensionsOverlay.dtd b/bandwagon/locale/da/extensionsOverlay.dtd
new file mode 100644
index 0000000..97f4a3e
--- /dev/null
+++ b/bandwagon/locale/da/extensionsOverlay.dtd
@@ -0,0 +1,69 @@
+<!-- ***** BEGIN LICENSE BLOCK *****
+ - Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ -
+ - The contents of this file are subject to the Mozilla Public License Version
+ - 1.1 (the "License"); you may not use this file except in compliance with
+ - the License. You may obtain a copy of the License at
+ - http://www.mozilla.org/MPL/
+ -
+ - Software distributed under the License is distributed on an "AS IS" basis,
+ - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ - for the specific language governing rights and limitations under the
+ - License.
+ -
+ - The Original Code is bandwagon.
+ -
+ - The Initial Developer of the Original Code is
+ - Mozilla Corporation.
+ - Portions created by the Initial Developer are Copyright (C) 2008
+ - the Initial Developer. All Rights Reserved.
+ -
+ - Contributor(s): Brian King <brian (at) briks (dot) si>
+ - David McNamara
+ -
+ - Alternatively, the contents of this file may be used under the terms of
+ - either the GNU General Public License Version 2 or later (the "GPL"), or
+ - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ - in which case the provisions of the GPL or the LGPL are applicable instead
+ - of those above. If you wish to allow use of your version of this file only
+ - under the terms of either the GPL or the LGPL, and not to allow others to
+ - use your version of this file under the terms of the MPL, indicate your
+ - decision by deleting the provisions above and replace them with the notice
+ - and other provisions required by the GPL or the LGPL. If you do not delete
+ - the provisions above, a recipient may use your version of this file under
+ - the terms of any one of the MPL, the GPL or the LGPL.
+ -
+ - ***** END LICENSE BLOCK ***** -->
+
+<!ENTITY collections.label "Abonnementer">
+<!ENTITY search.label.bandwagon "Søg">
+
+<!ENTITY addon.moreinfo "Mere info.">
+<!ENTITY addon.addtofirefox "Tilføj til Firefox">
+<!ENTITY subscribe.label "Find samlinger">
+<!ENTITY reload.label "Genindlæs alle">
+<!ENTITY settings.label "Indstillinger">
+
+<!ENTITY view.label "Vis samlinger">
+<!ENTITY unsubscribe.label "Afmeld">
+
+<!ENTITY nocollectionstitle.label "Velkommen til tilføjelsessamleren">
+<!ENTITY nocollectionssubscribed.label "Dette er stedet hvor samlinger, du har markeret som favoritter på Mozilla Add-ons, vil blive vist, så du nemt kan holde styr på dem. Det ser ud til at du endnu ikke har tilføjet nogen favoritter, så hvorfor ikke kigge rundt i oversigten over samlinger?">
+<!ENTITY clicktosubscribe.label "Find samlinger">
+
+<!ENTITY noamoauth.label "Dette er stedet hvor samlinger, du har markeret som favoritter på Mozilla Add-ons, vil blive vist, så du nemt kan holde styr på dem. Du skal være logget ind på addons.mozilla.org for at se samlingerne.">
+<!ENTITY username.label "E-mail-adresse">
+<!ENTITY password.label "Adgangskode">
+<!ENTITY clicktologin.label "Log ind">
+
+<!ENTITY collectionisloading.label "Henter abonnement...">
+<!ENTITY collectionhasnoitems.label "Denne samling indeholder ingen tilføjelser.">
+<!ENTITY collectionhaserror.label "Denne samling kan ikke vises, da den indeholder fejl.">
+
+<!ENTITY publishto.label "Offentliggør til">
+<!ENTITY email.address.label "E-mail-adresse">
+<!ENTITY new.email.address.label "Ny E-mail-adresse">
+<!ENTITY new.collection.label "Ny samling">
+
+<!ENTITY createaccount.label "Jeg har ikke en konto">
+<!ENTITY loginheading.label "Indtast brugernavn og adgangskode til Mozilla Add-ons herunder:">
diff --git a/bandwagon/locale/da/publish.dtd b/bandwagon/locale/da/publish.dtd
new file mode 100644
index 0000000..3937267
--- /dev/null
+++ b/bandwagon/locale/da/publish.dtd
@@ -0,0 +1,48 @@
+<!-- ***** BEGIN LICENSE BLOCK *****
+ - Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ -
+ - The contents of this file are subject to the Mozilla Public License Version
+ - 1.1 (the "License"); you may not use this file except in compliance with
+ - the License. You may obtain a copy of the License at
+ - http://www.mozilla.org/MPL/
+ -
+ - Software distributed under the License is distributed on an "AS IS" basis,
+ - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ - for the specific language governing rights and limitations under the
+ - License.
+ -
+ - The Original Code is bandwagon.
+ -
+ - The Initial Developer of the Original Code is
+ - Mozilla Corporation.
+ - Portions created by the Initial Developer are Copyright (C) 2008
+ - the Initial Developer. All Rights Reserved.
+ -
+ - Contributor(s): David McNamara
+ - Brian King <brian (at) briks (dot) si>
+ -
+ - Alternatively, the contents of this file may be used under the terms of
+ - either the GNU General Public License Version 2 or later (the "GPL"), or
+ - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ - in which case the provisions of the GPL or the LGPL are applicable instead
+ - of those above. If you wish to allow use of your version of this file only
+ - under the terms of either the GPL or the LGPL, and not to allow others to
+ - use your version of this file under the terms of the MPL, indicate your
+ - decision by deleting the provisions above and replace them with the notice
+ - and other provisions required by the GPL or the LGPL. If you do not delete
+ - the provisions above, a recipient may use your version of this file under
+ - the terms of any one of the MPL, the GPL or the LGPL.
+ -
+ - ***** END LICENSE BLOCK ***** -->
+
+<!-- For localisers to change the width of the window -->
+<!ENTITY publish.style "width: 35em;">
+
+<!ENTITY window.title "Offentliggør">
+<!ENTITY cancel.label "Annuller">
+<!ENTITY publish.label "Offentliggør">
+<!ENTITY new.email.label "Ny e-mail-adresse">
+<!ENTITY enter.an.email.label "Indtast en eller flere e-mail-adresser adskilt af kommaer:">
+<!ENTITY remember.this.email.label "Husk denne e-mail-adresse">
+<!ENTITY enter.a.personal.note.label "Valgfrit: Tilføj en personlig besked om denne tilføjelse til e-mailen">
+
diff --git a/bandwagon/locale/da/publish.properties b/bandwagon/locale/da/publish.properties
new file mode 100644
index 0000000..ee4869d
--- /dev/null
+++ b/bandwagon/locale/da/publish.properties
@@ -0,0 +1,20 @@
+# LOCALIZATION NOTE (you.are.sharing.the.add.on):
+# %S is the name of an add-on
+you.are.sharing.the.add.on=Du deler tilføjelsen '%S'
+# LOCALIZATION NOTE (publishing.to):
+# %1 is the name of an add-on. %2 is the name of a collection
+publishing.to=Når du klikker på "Offentliggør", vil vi tilføje %1$S sil samlingen "%2$S".
+# LOCALIZATION NOTE (sharing.with):
+# %1 is a user's email address. $2 is the name of an add-on
+sharing.with=Når du klikker på "Send e-mail", vil vi sende en e-mail til %1$S med information om %2$S
+# LOCALIZATION NOTE (sharing.with.new):
+# %S is the name of an add-on
+sharing.with.new=Når du klikker på "Send e-mail", vil vi sende en e-mail til ovenstående modtagere med information om %S
+please.enter.an.email.address=Indtast venligst en e-mail-adresse.
+the.addon.has.been.published=Tilføjelsen er nu offentliggjort.
+the.email.has.been.sent=E-mailen er afsendt.
+# LOCALIZATION NOTE (closing.in):
+# %S is the number of seconds until a window closes, counting down
+closing.in=Lukker om %S...
+send.email=Send e-mail
+error.unknown_addon_guid=Denne tilføjelse kan ikke deles, da den ikke har hjemme på hjemmesiden Mozilla Add-ons.
diff --git a/bandwagon/locale/da/settings.dtd b/bandwagon/locale/da/settings.dtd
new file mode 100644
index 0000000..5ce8e85
--- /dev/null
+++ b/bandwagon/locale/da/settings.dtd
@@ -0,0 +1,108 @@
+<!-- ***** BEGIN LICENSE BLOCK *****
+ - Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ -
+ - The contents of this file are subject to the Mozilla Public License Version
+ - 1.1 (the "License"); you may not use this file except in compliance with
+ - the License. You may obtain a copy of the License at
+ - http://www.mozilla.org/MPL/
+ -
+ - Software distributed under the License is distributed on an "AS IS" basis,
+ - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ - for the specific language governing rights and limitations under the
+ - License.
+ -
+ - The Original Code is bandwagon.
+ -
+ - The Initial Developer of the Original Code is
+ - Mozilla Corporation.
+ - Portions created by the Initial Developer are Copyright (C) 2008
+ - the Initial Developer. All Rights Reserved.
+ -
+ - Contributor(s): Brian King <brian (at) briks (dot) si>
+ - David McNamara
+ -
+ - Alternatively, the contents of this file may be used under the terms of
+ - either the GNU General Public License Version 2 or later (the "GPL"), or
+ - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ - in which case the provisions of the GPL or the LGPL are applicable instead
+ - of those above. If you wish to allow use of your version of this file only
+ - under the terms of either the GPL or the LGPL, and not to allow others to
+ - use your version of this file under the terms of the MPL, indicate your
+ - decision by deleting the provisions above and replace them with the notice
+ - and other provisions required by the GPL or the LGPL. If you do not delete
+ - the provisions above, a recipient may use your version of this file under
+ - the terms of any one of the MPL, the GPL or the LGPL.
+ -
+ - ***** END LICENSE BLOCK ***** -->
+
+<!-- For localisers to change the width of the window -->
+<!ENTITY settings.style "width: 42em;">
+
+<!ENTITY window.title "Indstillinger for tilføjelsessamleren">
+
+<!-- Tabs -->
+<!ENTITY manage.label "Abonnementer">
+<!ENTITY general.label "Overordnet">
+<!ENTITY pub.label "Automatisk offentliggørelse">
+
+<!-- Manage Subscriptions -->
+<!ENTITY subscriptions.header "Abonnementer:">
+
+<!-- Groupbox captions in Manage Subscriptions -->
+<!ENTITY frequency.label "Hyppighed for opdatering af abonnementer">
+<!ENTITY notifications.label "Beskeder om nye tilføjelser">
+<!ENTITY perpage.label "Tilføjelser pr. side">
+
+<!ENTITY default.label "Brug standardindstillinger">
+<!ENTITY custom.label "Brugerdefineret:">
+
+<!ENTITY addonsleadin.label "Vis">
+<!ENTITY addonsperpage.label "tilføjelser pr. side">
+<!ENTITY updatesingle.label "Tid mellem hver opdatering:">
+<!ENTITY minutes.label "minut(ter)">
+<!ENTITY hours.label "time(r)">
+<!ENTITY days.label "dag(e)">
+<!ENTITY autopublish.label "Offentliggør automatisk installerede tilføjelser til abonnement">
+<!ENTITY notify.label "Vis beskeder">
+<!ENTITY applyall.label "Andvend på alle abonnementer">
+<!ENTITY remove.label "Fjern abonnement">
+<!ENTITY on.label "Ja">
+<!ENTITY off.label "Nej">
+
+<!-- General -->
+
+<!-- Groupbox captions in General -->
+<!ENTITY subscriptions.label "Abonnementer">
+<!ENTITY data.label "Datahåndtering">
+
+<!ENTITY updateall.label "Se efter opdateringer til abonnementer for hver">
+<!ENTITY notifyglobal.label "Giv mig besked når mine abonnementer har nye tilføjelser">
+
+<!ENTITY clearemails.label "Ryd">
+<!ENTITY login.label "Log ind">
+<!ENTITY logout.label "Log ud">
+
+<!-- Auto-Publisher Settings -->
+
+<!-- Groupbox captions in Auto-Publisher Settings -->
+<!ENTITY auto.label "Automatisk offentliggørelse">
+
+<!ENTITY name.label "Samlingens navn:">
+<!ENTITY list.label "Vises i den offentlige oversigt over samlinger">
+
+<!ENTITY autoleadin.label "Automatisk offentliggjorte samlinger er specielle samlinger, der automatisk opdateres, når du installerer eller afinstallerer tilføjelser til Firefox på denne computer.">
+<!ENTITY types.label "Automatisk offentliggjorte tilføjelser:">
+<!ENTITY type.extensions.label "Udvidelser">
+<!ENTITY type.themes.label "Temaer">
+<!ENTITY type.dicts.label "Ordbøger">
+<!ENTITY type.langpacks.label "Sprogpakker">
+
+<!ENTITY createauto.label "Opret automatisk offentliggjort samling">
+<!ENTITY deleteauto.label "Slet automatisk offentliggjort samling">
+<!ENTITY updateauto.label "Opdater automatisk offentliggjort samling">
+
+<!ENTITY onlypublishenabledaddons.label "Offentliggør kun aktiverede tilføjelser">
+
+<!ENTITY misc.label "Diverse">
+<!ENTITY allowincompatibleinstall.label "Tillad installation af inkompatible tilføjelser fra mine abonnementer">
+
diff --git a/bandwagon/locale/da/settings.properties b/bandwagon/locale/da/settings.properties
new file mode 100644
index 0000000..607311a
--- /dev/null
+++ b/bandwagon/locale/da/settings.properties
@@ -0,0 +1,26 @@
+add.collection=Tilføj abonnement
+enter.url.to.add.collection=Indtast URL'en på det abonnement, du vil tilføje.
+remove.collection=Fjern abonnement
+# LOCALIZATION NOTE (are.you.sure.you.want.to.remove):
+# %S is the name of a collection
+are.you.sure.you.want.to.remove=Når du fjerner dette abonnement, vil samlingen også blive fjernet fra din liste med favoritsamlinger. Er du sikker på, at du vil fjerne '%S'?
+# LOCALIZATION NOTE (saved.emails.text):
+# %S is a number
+saved.emails.text=Du har %S gemte e-mail-adresser
+# LOCALIZATION NOTE (login.status.with.email):
+# %S is a user's email address
+login.status.with.email=Du er logget ind som %S
+login.status=Du er logget ind
+logout.status=Du er ikke logget ind
+# LOCALIZATION NOTE (auto.invalid.name):
+# %S is the name of a collection
+auto.invalid.name=Samlingens navn '%S' er ikke gyldigt.
+auto.please.select.type=Du skal markere mindst en type tilføjelser til automatisk offentliggørelse.
+auto.create.internal.error=Samlingen kunne ikke oprettes (en intern fejl opstod).
+auto.create.done=Din automatisk offentliggjorte samling blev oprettet.
+auto.delete.internal.error=Samlingen kunne ikke slettes (en intern fejl opstod).
+auto.delete.done=Din automatisk offentliggjorte samling blev slettet.
+auto.create.description=En automatisk genereret liste over mine installerede tilføjelser
+auto.update.confirm.message=Dine nye indstillinger vil træde i kraft med det samme, men vil ikke påvirke tilføjelser, som allerede er offentliggjort.
+auto.update.internal.error=Samlingen kunne ikke opdateres (en intern fejl opstod).
+auto.update.done=Din automatisk offentliggjorte samling blev opdateret.
diff --git a/bandwagon/locale/de/bandwagon.properties b/bandwagon/locale/de/bandwagon.properties
new file mode 100644
index 0000000..2e1a9c9
--- /dev/null
+++ b/bandwagon/locale/de/bandwagon.properties
@@ -0,0 +1,2 @@
+extensions.sharing@addons.mozilla.org.description=Add-ons weitergeben und entdecken.
+extensions.sharing@addons.mozilla.org.name=Add-on-Sammler
diff --git a/bandwagon/locale/de/bandwagonAddon.properties b/bandwagon/locale/de/bandwagonAddon.properties
new file mode 100644
index 0000000..e351eac
--- /dev/null
+++ b/bandwagon/locale/de/bandwagonAddon.properties
@@ -0,0 +1,38 @@
+# LOCALIZATION NOTE (bandwagon.addon.pluralRule):
+# See https://developer.mozilla.org/En/Localization_and_Plurals
+bandwagon.addon.pluralRule=1
+bandwagon.category1=Erweiterung
+# LOCALIZATION NOTE (bandwagon.addon.author):
+# %S will contain author's first and last name, or their nickname used on AMO
+bandwagon.addon.author=Von %S
+# LOCALIZATION NOTE (bandwagon.addon.addedby):
+# %S will be a user's first and last name, or nickname
+bandwagon.addon.addedby=Von %S
+bandwagon.addon.added.justnow=Hinzugefügt: Gerade eben
+# LOCALIZATION NOTE:
+# %S will be a number of time units indicated
+bandwagon.addon.added.minute=Hinzugefügt: vor 1 Minute;Hinzugefügt: vor %S Minuten
+bandwagon.addon.added.hour=Hinzugefügt: vor einer Stunde;Hinzugefügt: vor %S Stunden
+bandwagon.addon.added.day=Hinzugefügt: Gestern;Hinzugefügt: vor %S Tagen
+bandwagon.addon.added.week=Hinzugefügt: vor einer Woche;Hinzugefügt: vor %S Wochen
+bandwagon.addon.added.month=Hinzugefügt: vor einem Monat;Hinzugefügt: vor %S Monaten
+bandwagon.addon.added.year=Hinzugefügt: vor einem Jahr;Hinzugefügt: vor %S Jahren
+bandwagon.addon.moreinfo=Weitere Informationen.
+bandwagon.addon.olderversionsoffirefox=Dieses Add-on ist für ältere Versionen von Firefox.
+# LOCALIZATION NOTE (upgradetofirefoxn1):
+# %S will be a Firefox version number
+bandwagon.addon.upgradetofirefoxn1=Aktualisieren Sie auf Firefox %S
+bandwagon.addon.upgradetofirefoxn2=um dieses Add-on zu nutzen.
+# LOCALIZATION NOTE (bandwagon.addon.requiresfirefoxbeta1/requiresfirefoxbeta2):
+# %S will be a Firefox version number
+bandwagon.addon.requiresfirefoxbeta1=Dieses Add-on benötigt Firefox %S, das noch nicht veröffentlicht wurde. Um dieses Add-on zu nutzen, können Sie
+bandwagon.addon.requiresfirefoxbeta2=Firefox %S Beta herunterladen.
+# LOCALIZATION NOTE (bandwagon.addon.notcompatible):
+# %S will be a platform name, such as "Windows"
+bandwagon.addon.notcompatible=Dieses Add-on ist nicht kompatibel mit %S.
+# LOCALIZATION NOTE (bandwagon.addon.comment.description):
+# %S will be a comment entered by the publisher of the add-on
+bandwagon.addon.comment.description=“%Sâ€
+# LOCALIZATION NOTE (bandwagon.addon.comment.author):
+# %S will be the publisher's real name or nickname
+bandwagon.addon.comment.author=Kommentar von %S:
diff --git a/bandwagon/locale/de/browserOverlay.dtd b/bandwagon/locale/de/browserOverlay.dtd
new file mode 100644
index 0000000..a665207
--- /dev/null
+++ b/bandwagon/locale/de/browserOverlay.dtd
@@ -0,0 +1,38 @@
+<!-- ***** BEGIN LICENSE BLOCK *****
+ - Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ -
+ - The contents of this file are subject to the Mozilla Public License Version
+ - 1.1 (the "License"); you may not use this file except in compliance with
+ - the License. You may obtain a copy of the License at
+ - http://www.mozilla.org/MPL/
+ -
+ - Software distributed under the License is distributed on an "AS IS" basis,
+ - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ - for the specific language governing rights and limitations under the
+ - License.
+ -
+ - The Original Code is bandwagon.
+ -
+ - The Initial Developer of the Original Code is
+ - Mozilla Corporation.
+ - Portions created by the Initial Developer are Copyright (C) 2008
+ - the Initial Developer. All Rights Reserved.
+ -
+ - Contributor(s): Brian King <brian (at) briks (dot) si>
+ -
+ - Alternatively, the contents of this file may be used under the terms of
+ - either the GNU General Public License Version 2 or later (the "GPL"), or
+ - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ - in which case the provisions of the GPL or the LGPL are applicable instead
+ - of those above. If you wish to allow use of your version of this file only
+ - under the terms of either the GPL or the LGPL, and not to allow others to
+ - use your version of this file under the terms of the MPL, indicate your
+ - decision by deleting the provisions above and replace them with the notice
+ - and other provisions required by the GPL or the LGPL. If you do not delete
+ - the provisions above, a recipient may use your version of this file under
+ - the terms of any one of the MPL, the GPL or the LGPL.
+ -
+ - ***** END LICENSE BLOCK ***** -->
+
+<!ENTITY bandwagon.label "Add-ons">
+<!ENTITY bandwagon.tooltip "Add-ons">
diff --git a/bandwagon/locale/de/browserOverlay.properties b/bandwagon/locale/de/browserOverlay.properties
new file mode 100644
index 0000000..e5ce887
--- /dev/null
+++ b/bandwagon/locale/de/browserOverlay.properties
@@ -0,0 +1,4 @@
+newaddons.alert.title=Neue Add-ons
+# LOCALIZATION NOTE (newaddons.alert.text):
+# %S will be the name of a collection
+newaddons.alert.text=Es gibt neue Add-ons in Ihrem Abonnement "%S".
diff --git a/bandwagon/locale/de/extensionOverlay.properties b/bandwagon/locale/de/extensionOverlay.properties
new file mode 100644
index 0000000..31056e4
--- /dev/null
+++ b/bandwagon/locale/de/extensionOverlay.properties
@@ -0,0 +1,15 @@
+publish.new.email.address.title=Neue E-Mail-Adresse
+publish.new.email.address.text=Geben Sie eine neue E-Mail-Adresse ein, an die Sie dieses Add-on weiterempfehlen möchten:
+publish.remove.title=Bestätigung
+# LOCALIZATION NOTE (publish.remove.label):
+# %1 is the name of an add-on. %2 is the name of a collection
+publish.remove.label=Sind Sie sicher, dass Sie %1$S aus der Sammlung "%2$S" entfernen möchten?
+publish.remove.button1=Nein, abbrechen
+publish.remove.button0=Ja, Add-on entfernen
+login.error=Beim Anmelden ist ein Fehler aufgetreten. Bitte überprüfen Sie, ob Ihr Benutzername und Ihr Passwort korrekt sind.
+unsubscribe.error=Beim Abbestellen dieser Sammlung ist ein Fehler aufgetreten. Bitte versuchen Sie es später erneut.
+unsubscribe.confirm.title=Abbestellen bestätigen
+unsubscribe.confirm.label=Beim Abbestellen dieser Sammlung wird diese auch aus Ihrer Favoritenliste entfernt. Sind Sie sicher, dass Sie die Sammlung abbestellen möchten?
+unsubscribe.confirm.button1=Nein, abbrechen
+unsubscribe.confirm.button0=Ja, abbestellen
+
diff --git a/bandwagon/locale/de/extensionsOverlay.dtd b/bandwagon/locale/de/extensionsOverlay.dtd
new file mode 100644
index 0000000..f17ef26
--- /dev/null
+++ b/bandwagon/locale/de/extensionsOverlay.dtd
@@ -0,0 +1,69 @@
+<!-- ***** BEGIN LICENSE BLOCK *****
+ - Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ -
+ - The contents of this file are subject to the Mozilla Public License Version
+ - 1.1 (the "License"); you may not use this file except in compliance with
+ - the License. You may obtain a copy of the License at
+ - http://www.mozilla.org/MPL/
+ -
+ - Software distributed under the License is distributed on an "AS IS" basis,
+ - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ - for the specific language governing rights and limitations under the
+ - License.
+ -
+ - The Original Code is bandwagon.
+ -
+ - The Initial Developer of the Original Code is
+ - Mozilla Corporation.
+ - Portions created by the Initial Developer are Copyright (C) 2008
+ - the Initial Developer. All Rights Reserved.
+ -
+ - Contributor(s): Brian King <brian (at) briks (dot) si>
+ - David McNamara
+ -
+ - Alternatively, the contents of this file may be used under the terms of
+ - either the GNU General Public License Version 2 or later (the "GPL"), or
+ - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ - in which case the provisions of the GPL or the LGPL are applicable instead
+ - of those above. If you wish to allow use of your version of this file only
+ - under the terms of either the GPL or the LGPL, and not to allow others to
+ - use your version of this file under the terms of the MPL, indicate your
+ - decision by deleting the provisions above and replace them with the notice
+ - and other provisions required by the GPL or the LGPL. If you do not delete
+ - the provisions above, a recipient may use your version of this file under
+ - the terms of any one of the MPL, the GPL or the LGPL.
+ -
+ - ***** END LICENSE BLOCK ***** -->
+
+<!ENTITY collections.label "Abonnements">
+<!ENTITY search.label.bandwagon "Suchen">
+
+<!ENTITY addon.moreinfo "Weitere Informationen.">
+<!ENTITY addon.addtofirefox "Zu Firefox hinzufügen">
+<!ENTITY subscribe.label "Sammlungen suchen">
+<!ENTITY reload.label "Alle neu laden">
+<!ENTITY settings.label "Einstellungen">
+
+<!ENTITY view.label "Sammlung ansehen">
+<!ENTITY unsubscribe.label "Abbestellen">
+
+<!ENTITY nocollectionstitle.label "Willkommen zum Add-on-Sammler">
+<!ENTITY nocollectionssubscribed.label "Hier werden die Sammlungen, die Sie auf der Mozilla Add-ons-Website als Favoriten markiert haben, angezeigt, so dass Sie sie einfach im Auge behalten können. Anscheinend haben Sie bisher keine Favoriten hinzugefügt, also warum schauen Sie sich nicht mal in unserem Sammlungsverzeichnis um?">
+<!ENTITY clicktosubscribe.label "Sammlungen suchen">
+
+<!ENTITY noamoauth.label "Hier werden die Sammlungen, die Sie auf der Mozilla Add-ons-Website als Favoriten markiert haben, angezeigt, so dass Sie sie einfach im Auge behalten können. Sie müssen bei addons.mozilla.org angemeldet sein, um diese Funktion nutzen zu können.">
+<!ENTITY username.label "Benutzername">
+<!ENTITY password.label "Passwort">
+<!ENTITY clicktologin.label "Anmelden">
+
+<!ENTITY collectionisloading.label "Abonnement abholen ...">
+<!ENTITY collectionhasnoitems.label "Diese Sammlung enthält keine Add-ons.">
+<!ENTITY collectionhaserror.label "Diese Sammlung kann nicht angezeigt werden, weil sie Fehler enthält.">
+
+<!ENTITY publishto.label "Veröffentlichen an">
+<!ENTITY email.address.label "E-Mail-Adresse">
+<!ENTITY new.email.address.label "Neue E-Mail-Adresse">
+<!ENTITY new.collection.label "Neue Sammlung">
+
+<!ENTITY createaccount.label "Ich habe kein Benutzerkonto">
+<!ENTITY loginheading.label "Geben Sie die Daten Ihres Benutzerkontos bei Mozilla Add-ons an:">
diff --git a/bandwagon/locale/de/publish.dtd b/bandwagon/locale/de/publish.dtd
new file mode 100644
index 0000000..f8debe4
--- /dev/null
+++ b/bandwagon/locale/de/publish.dtd
@@ -0,0 +1,48 @@
+<!-- ***** BEGIN LICENSE BLOCK *****
+ - Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ -
+ - The contents of this file are subject to the Mozilla Public License Version
+ - 1.1 (the "License"); you may not use this file except in compliance with
+ - the License. You may obtain a copy of the License at
+ - http://www.mozilla.org/MPL/
+ -
+ - Software distributed under the License is distributed on an "AS IS" basis,
+ - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ - for the specific language governing rights and limitations under the
+ - License.
+ -
+ - The Original Code is bandwagon.
+ -
+ - The Initial Developer of the Original Code is
+ - Mozilla Corporation.
+ - Portions created by the Initial Developer are Copyright (C) 2008
+ - the Initial Developer. All Rights Reserved.
+ -
+ - Contributor(s): David McNamara
+ - Brian King <brian (at) briks (dot) si>
+ -
+ - Alternatively, the contents of this file may be used under the terms of
+ - either the GNU General Public License Version 2 or later (the "GPL"), or
+ - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ - in which case the provisions of the GPL or the LGPL are applicable instead
+ - of those above. If you wish to allow use of your version of this file only
+ - under the terms of either the GPL or the LGPL, and not to allow others to
+ - use your version of this file under the terms of the MPL, indicate your
+ - decision by deleting the provisions above and replace them with the notice
+ - and other provisions required by the GPL or the LGPL. If you do not delete
+ - the provisions above, a recipient may use your version of this file under
+ - the terms of any one of the MPL, the GPL or the LGPL.
+ -
+ - ***** END LICENSE BLOCK ***** -->
+
+<!-- For localisers to change the width of the window -->
+<!ENTITY publish.style "width: 35em;">
+
+<!ENTITY window.title "Veröffentlichen">
+<!ENTITY cancel.label "Abbrechen">
+<!ENTITY publish.label "Veröffentlichen">
+<!ENTITY new.email.label "Neue E-Mail-Adresse">
+<!ENTITY enter.an.email.label "Geben Sie eine oder mehrere E-Mail-Adressen ein (mit Kommata getrennt):">
+<!ENTITY remember.this.email.label "Diese E-Mail-Adresse merken">
+<!ENTITY enter.a.personal.note.label "Optional: Geben Sie einen persönlichen Vermerk zu diesem Add-on ein, der in der E-Mail enthalten sein soll">
+
diff --git a/bandwagon/locale/de/publish.properties b/bandwagon/locale/de/publish.properties
new file mode 100644
index 0000000..92b3810
--- /dev/null
+++ b/bandwagon/locale/de/publish.properties
@@ -0,0 +1,20 @@
+# LOCALIZATION NOTE (you.are.sharing.the.add.on):
+# %S is the name of an add-on
+you.are.sharing.the.add.on=Sie empfehlen das Add-on '%S' weiter
+# LOCALIZATION NOTE (publishing.to):
+# %1 is the name of an add-on. %2 is the name of a collection
+publishing.to=Ein Klick auf "Veröffentlichen" wird %1$S zur Sammlung "%2$S" hinzufügen.
+# LOCALIZATION NOTE (sharing.with):
+# %1 is a user's email address. $2 is the name of an add-on
+sharing.with=Ein Klick auf "E-Mail senden" wird %1$S eine E-Mail mit Informationen über %2$S senden
+# LOCALIZATION NOTE (sharing.with.new):
+# %S is the name of an add-on
+sharing.with.new=Ein Klick auf "E-Mail senden" wird %1$S eine E-Mail mit Informationen über %2$S senden
+please.enter.an.email.address=Bitte geben Sie eine E-Mail-Adresse ein.
+the.addon.has.been.published=Das Add-on wurde veröffentlicht.
+the.email.has.been.sent=Die E-Mail wurde gesendet.
+# LOCALIZATION NOTE (closing.in):
+# %S is the number of seconds until a window closes, counting down
+closing.in=Fenster wird in %S geschlossen ...
+send.email=E-Mail senden
+error.unknown_addon_guid=Dieses Add-on kann nicht weiterempfohlen werden, weil es nicht auf der Mozilla Add-ons-Website angeboten wird.
diff --git a/bandwagon/locale/de/settings.dtd b/bandwagon/locale/de/settings.dtd
new file mode 100644
index 0000000..0e2d3a3
--- /dev/null
+++ b/bandwagon/locale/de/settings.dtd
@@ -0,0 +1,108 @@
+<!-- ***** BEGIN LICENSE BLOCK *****
+ - Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ -
+ - The contents of this file are subject to the Mozilla Public License Version
+ - 1.1 (the "License"); you may not use this file except in compliance with
+ - the License. You may obtain a copy of the License at
+ - http://www.mozilla.org/MPL/
+ -
+ - Software distributed under the License is distributed on an "AS IS" basis,
+ - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ - for the specific language governing rights and limitations under the
+ - License.
+ -
+ - The Original Code is bandwagon.
+ -
+ - The Initial Developer of the Original Code is
+ - Mozilla Corporation.
+ - Portions created by the Initial Developer are Copyright (C) 2008
+ - the Initial Developer. All Rights Reserved.
+ -
+ - Contributor(s): Brian King <brian (at) briks (dot) si>
+ - David McNamara
+ -
+ - Alternatively, the contents of this file may be used under the terms of
+ - either the GNU General Public License Version 2 or later (the "GPL"), or
+ - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ - in which case the provisions of the GPL or the LGPL are applicable instead
+ - of those above. If you wish to allow use of your version of this file only
+ - under the terms of either the GPL or the LGPL, and not to allow others to
+ - use your version of this file under the terms of the MPL, indicate your
+ - decision by deleting the provisions above and replace them with the notice
+ - and other provisions required by the GPL or the LGPL. If you do not delete
+ - the provisions above, a recipient may use your version of this file under
+ - the terms of any one of the MPL, the GPL or the LGPL.
+ -
+ - ***** END LICENSE BLOCK ***** -->
+
+<!-- For localisers to change the width of the window -->
+<!ENTITY settings.style "width: 42em;">
+
+<!ENTITY window.title "Einstellungen des Add-on-Sammlers">
+
+<!-- Tabs -->
+<!ENTITY manage.label "Abonnements verwalten">
+<!ENTITY general.label "Allgemeine Einstellungen">
+<!ENTITY pub.label "Einstellungen zur Auto-Veröffentlichung">
+
+<!-- Manage Subscriptions -->
+<!ENTITY subscriptions.header "Abonnements:">
+
+<!-- Groupbox captions in Manage Subscriptions -->
+<!ENTITY frequency.label "Abstand zwischen Abonnement-Aktualisierungen">
+<!ENTITY notifications.label "Benachrichtigungen über neue Add-ons">
+<!ENTITY perpage.label "Add-ons pro Seite">
+
+<!ENTITY default.label "Standardeinstellungen verwenden">
+<!ENTITY custom.label "Benutzerdefiniert:">
+
+<!ENTITY addonsleadin.label "Anzeigen">
+<!ENTITY addonsperpage.label "Add-ons pro Seite">
+<!ENTITY updatesingle.label "Aktualisierung nach:">
+<!ENTITY minutes.label "Minute(n)">
+<!ENTITY hours.label "Stunde(n)">
+<!ENTITY days.label "Tag(en)">
+<!ENTITY autopublish.label "Installierte Add-ons automatisch im Abonnement veröffentlichen">
+<!ENTITY notify.label "Benachrichtigungen anzeigen">
+<!ENTITY applyall.label "Auf alle Abonnements anwenden">
+<!ENTITY remove.label "Abonnement entfernen">
+<!ENTITY on.label "An">
+<!ENTITY off.label "Aus">
+
+<!-- General -->
+
+<!-- Groupbox captions in General -->
+<!ENTITY subscriptions.label "Stadardeinstellungen für Abonnements">
+<!ENTITY data.label "Datenverwaltung">
+
+<!ENTITY updateall.label "Aktualisierungen für Abonnements suchen nach">
+<!ENTITY notifyglobal.label "Benachrichtigen, wenn Abonnements neue Add-ons enthalten">
+
+<!ENTITY clearemails.label "Löschen">
+<!ENTITY login.label "Anmelden">
+<!ENTITY logout.label "Abmelden">
+
+<!-- Auto-Publisher Settings -->
+
+<!-- Groupbox captions in Auto-Publisher Settings -->
+<!ENTITY auto.label "Einstellungen zur Auto-Veröffentlichung">
+
+<!ENTITY name.label "Name der Sammlung:">
+<!ENTITY list.label "In öffentlichem Sammlungsverzeichnis aufgelistet">
+
+<!ENTITY autoleadin.label "Auto-Veröffentlichungen sind spezielle Sammlungen, die automatisch aktualisiert werden, wenn Sie Firefox-Add-ons auf diesem Computer installieren oder deinstallieren.">
+<!ENTITY types.label "Automatisch veröffentlichte Add-on-Typen:">
+<!ENTITY type.extensions.label "Erweiterungen">
+<!ENTITY type.themes.label "Themes">
+<!ENTITY type.dicts.label "Wörterbücher">
+<!ENTITY type.langpacks.label "Sprachpakete">
+
+<!ENTITY createauto.label "Auto-Veröffentlichung erstellen">
+<!ENTITY deleteauto.label "Auto-Veröffentlichung entfernen">
+<!ENTITY updateauto.label "Auto-Veröffentlichung aktualisieren">
+
+<!ENTITY onlypublishenabledaddons.label "Nur aktivierte Add-ons veröffentlichen">
+
+<!ENTITY misc.label "Verschiedenes">
+<!ENTITY allowincompatibleinstall.label "Installation von inkompatiblen Add-ons aus meinen Abonnements erlauben">
+
diff --git a/bandwagon/locale/de/settings.properties b/bandwagon/locale/de/settings.properties
new file mode 100644
index 0000000..9d12466
--- /dev/null
+++ b/bandwagon/locale/de/settings.properties
@@ -0,0 +1,27 @@
+add.collection=Abonnement hinzufügen
+enter.url.to.add.collection=Geben Sie die URL des Abonnements ein, das Sie hinzufügen möchten.
+remove.collection=Abonnement entfernen
+# LOCALIZATION NOTE (are.you.sure.you.want.to.remove):
+# %S is the name of a collection
+are.you.sure.you.want.to.remove=Beim Entfernen dieses Abonnements wird die Sammlung auch aus Ihrer Favoritenliste gelöscht. Sind Sie sicher, dass Sie '%S' entfernen möchten?
+# LOCALIZATION NOTE (saved.emails.text):
+# %S is a number
+saved.emails.text=Sie haben %S gespeicherte E-Mail-Adressen
+# LOCALIZATION NOTE (login.status.with.email):
+# %S is a user's email address
+login.status.with.email=Sie sind als %S angemeldet
+login.status=Sie sind angemeldet
+logout.status=Sie sind nicht angemeldet
+# LOCALIZATION NOTE (auto.invalid.name):
+# %S is the name of a collection
+auto.invalid.name=Der Name der Sammlung '%S' ist ungültig.
+auto.please.select.type=Bitte wählen Sie mindestens einen Add-on-Typ für die Auto-Veröffentlichung.
+auto.create.internal.error=Die Sammlung konnte nicht erstellt werden (ein interner Fehler ist aufgetreten).
+auto.create.done=Ihre Sammlung zur Auto-Veröffentlichung wurde erstellt.
+auto.delete.internal.error=Die Sammlung konnte nicht gelöscht werden (ein interner Fehler ist aufgetreten).
+auto.delete.done=Ihre Sammlung zur Auto-Veröffentlichung wurde gelöscht.
+auto.create.description=Eine automatisch erzeugte Liste meiner installierten Add-ons
+auto.update.confirm.message=Ihre neuen Einstellungen werden sofort übernommen. Sie haben aber keine Auswirkung auf Add-ons, die bereits veröffentlicht wurden.
+auto.update.internal.error=Die Sammlung konnte nicht aktualisiert werden (ein interner Fehler ist aufgetreten).
+auto.update.done=Ihre Sammlung zur Auto-Veröffentlichung wurde aktualisiert.
+
diff --git a/bandwagon/locale/el-GR/bandwagon.properties b/bandwagon/locale/el-GR/bandwagon.properties
new file mode 100644
index 0000000..46556d5
--- /dev/null
+++ b/bandwagon/locale/el-GR/bandwagon.properties
@@ -0,0 +1,2 @@
+extensions.sharing@addons.mozilla.org.description=ΜοιÏαστείτε και ανακαλÏψτε Ï€Ïόσθετα.
+extensions.sharing@addons.mozilla.org.name=Add-on Collector
diff --git a/bandwagon/locale/el-GR/bandwagonAddon.properties b/bandwagon/locale/el-GR/bandwagonAddon.properties
new file mode 100644
index 0000000..bb44165
--- /dev/null
+++ b/bandwagon/locale/el-GR/bandwagonAddon.properties
@@ -0,0 +1,56 @@
+# LOCALIZATION NOTE (bandwagon.addon.pluralRule):
+
+# See https://developer.mozilla.org/En/Localization_and_Plurals
+
+bandwagon.addon.pluralRule=1
+bandwagon.category1=Επέκταση
+# LOCALIZATION NOTE (bandwagon.addon.author):
+
+# %S will contain author's first and last name, or their nickname used on AMO
+
+bandwagon.addon.author=Από %S
+# LOCALIZATION NOTE (bandwagon.addon.addedby):
+
+# %S will be a user's first and last name, or nickname
+
+bandwagon.addon.addedby=Από %S
+bandwagon.addon.added.justnow=ΠÏοστέθηκε: Μόλις Ï„ÏŽÏα
+# LOCALIZATION NOTE:
+
+# %S will be a number of time units indicated
+
+bandwagon.addon.added.minute=ΠÏοστέθηκε: Ï€Ïιν 1 λεπτό;ΠÏοστέθηκε: Ï€Ïιν %S λεπτά
+bandwagon.addon.added.hour=ΠÏοστέθηκε: Ï€Ïιν 1 ÏŽÏα;ΠÏοστέθηκε: Ï€Ïιν %S ÏŽÏες
+bandwagon.addon.added.day=ΠÏοστέθηκε: Χθές;ΠÏοστέθηκε: Ï€Ïιν %S ημέÏες
+bandwagon.addon.added.week=ΠÏοστέθηκε: Ï€Ïιν 1 εβδομάδα;ΠÏοστέθηκε: Ï€Ïιν %S εβδομάδες
+bandwagon.addon.added.month=ΠÏοστέθηκε: Ï€Ïιν 1 μήνα;ΠÏοστέθηκε: Ï€Ïιν %S μήνες
+bandwagon.addon.added.year=ΠÏοστέθηκε: Ï€Ïιν 1 έτος;ΠÏοστέθηκε: Ï€Ïιν %S έτη
+bandwagon.addon.moreinfo=ΠεÏισσότεÏες πληÏοφοÏίες
+bandwagon.addon.olderversionsoffirefox=Αυτό το Ï€Ïόσθετο λειτουÏγεί με παλιότεÏες εκδόσεις του Firefox.
+# LOCALIZATION NOTE (upgradetofirefoxn1):
+
+# %S will be a Firefox version number
+
+bandwagon.addon.upgradetofirefoxn1=Αναβαθμίστε σε Firefox %S
+bandwagon.addon.upgradetofirefoxn2=Για να χÏησιμοποιήσετε αυτό το Ï€Ïόσθετο.
+# LOCALIZATION NOTE (bandwagon.addon.requiresfirefoxbeta1/requiresfirefoxbeta2):
+
+# %S will be a Firefox version number
+
+bandwagon.addon.requiresfirefoxbeta1=Αυτό το Ï€Ïόσθετο απαιτεί την έκδοση Firefox %S, που δεν διατίθεται ακόμα επίσημα. Για να το χÏησιμοποιήσετε, μποÏείτε να
+bandwagon.addon.requiresfirefoxbeta2=κάνετε λήψη της δοκιμαστικής έκδοσης Firefox %S.
+# LOCALIZATION NOTE (bandwagon.addon.notcompatible):
+
+# %S will be a platform name, such as "Windows"
+
+bandwagon.addon.notcompatible=Αυτό το Ï€Ïόσθετο δεν είναι συμβατό με %S.
+# LOCALIZATION NOTE (bandwagon.addon.comment.description):
+
+# %S will be a comment entered by the publisher of the add-on
+
+bandwagon.addon.comment.description=«%S»
+# LOCALIZATION NOTE (bandwagon.addon.comment.author):
+
+# %S will be the publisher's real name or nickname
+
+bandwagon.addon.comment.author=Σχόλιο από %S:
diff --git a/bandwagon/locale/el-GR/browserOverlay.dtd b/bandwagon/locale/el-GR/browserOverlay.dtd
new file mode 100644
index 0000000..91890d9
--- /dev/null
+++ b/bandwagon/locale/el-GR/browserOverlay.dtd
@@ -0,0 +1,3 @@
+<!-- ***** BEGIN LICENSE BLOCK ***** - Version: MPL 1.1/GPL 2.0/LGPL 2.1 - - The contents of this file are subject to the Mozilla Public License Version - 1.1 (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - http://www.mozilla.org/MPL/ - - Software distributed under the License is distributed on an "AS IS" basis, - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - for the specific language governing rights and limitations under the - License. - - The Original Code is bandwagon. - - The Initial Developer of the Original Code is - Mozilla Corporation. - Portions created by the Initial Developer are Copyright (C) 2008 - the Initial Developer. All Rights Reserved. - - Contributor(s): Brian King <brian (at) briks (dot) si> - - Alternatively, the contents of this file may be used under the terms of - either the GNU General Public License Version 2 or later (the "GPL"), or - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - in which case the provisions of the GPL or the LGPL are applicable instead - of those above. If you wish to allow use of your version of this file only - under the terms of either the GPL or the LGPL, and not to allow others to - use your version of this file under the terms of the MPL, indicate your - decision by deleting the provisions above and replace them with the notice - and other provisions required by the GPL or the LGPL. If you do not delete - the provisions above, a recipient may use your version of this file under - the terms of any one of the MPL, the GPL or the LGPL. - - ***** END LICENSE BLOCK ***** -->
+<!ENTITY bandwagon.label "ΠÏόσθετα">
+<!ENTITY bandwagon.tooltip "ΠÏόσθετα">
diff --git a/bandwagon/locale/el-GR/browserOverlay.properties b/bandwagon/locale/el-GR/browserOverlay.properties
new file mode 100644
index 0000000..3b44a9d
--- /dev/null
+++ b/bandwagon/locale/el-GR/browserOverlay.properties
@@ -0,0 +1,6 @@
+newaddons.alert.title=Îέα Ï€Ïόσθετα
+# LOCALIZATION NOTE (newaddons.alert.text):
+
+# %S will be the name of a collection
+
+newaddons.alert.text=Δεν υπάÏχουν νέα Ï€Ïόσθετα στη συλλογή «%S».
diff --git a/bandwagon/locale/el-GR/contents.rdf b/bandwagon/locale/el-GR/contents.rdf
new file mode 100644
index 0000000..6a11c79
--- /dev/null
+++ b/bandwagon/locale/el-GR/contents.rdf
@@ -0,0 +1,15 @@
+<?xml version="1.0"?>
+<RDF:RDF xmlns:RDF="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:chrome="http://www.mozilla.org/rdf/chrome#">
+ <RDF:Seq about="urn:mozilla:locale:root">
+ <RDF:li resource="urn:mozilla:locale:el-GR"/>
+ </RDF:Seq>
+ <RDF:Description about="urn:mozilla:locale:el-GR" chrome:name="el-GR" >
+ <chrome:packages>
+ <RDF:Seq about="urn:mozilla:locale:el-GR:packages">
+ <RDF:li resource="urn:mozilla:locale:el-GR:bandwagon"/>
+ </RDF:Seq>
+ </chrome:packages>
+ </RDF:Description>
+</RDF:RDF>
+
diff --git a/bandwagon/locale/el-GR/extensionOverlay.properties b/bandwagon/locale/el-GR/extensionOverlay.properties
new file mode 100644
index 0000000..fa4f4e2
--- /dev/null
+++ b/bandwagon/locale/el-GR/extensionOverlay.properties
@@ -0,0 +1,16 @@
+publish.new.email.address.title=Îέα διεÏθυνση e-mail
+publish.new.email.address.text=Εισάγετε μια νέα διεÏθυνση e-mail για να μοιÏαστείτε αυτό το Ï€Ïόσθετο:
+publish.remove.title=Επιβεβαίωση
+# LOCALIZATION NOTE (publish.remove.label):
+
+# %1 is the name of an add-on. %2 is the name of a collection
+
+publish.remove.label=Θέλετε σίγουÏα να αφαιÏέσετε το %1$S από τη συλλογή «%2$S»;
+publish.remove.button1=Όχι, ακÏÏωση
+publish.remove.button0=Îαι, αφαίÏεση
+login.error=ΠαÏουσιάστηκε σφάλμα σÏνδεσης, ελέγξτε το όνομα χÏήστη και τον κωδικό σας.
+unsubscribe.error=ΠαÏουσιάστηκε σφάλμα κατά την διαγÏαφή της συνδÏομής σας από τη συλλογή. ΠαÏακαλοÏμε Ï€Ïοσπαθήστε ξανά αÏγότεÏα.
+unsubscribe.confirm.title=Επιβεβαίωση ακÏÏωσης
+unsubscribe.confirm.label=Η ακÏÏωση της συνδÏομής για τη συλλογή, σημαίνει και αφαίÏεση της από τη λίστα των αγαπημένων σας. Θέλετε σίγουÏα να ακυÏωθεί η συνδÏομή;
+unsubscribe.confirm.button1=Όχι, συνέχεια
+unsubscribe.confirm.button0=Îαι, ακÏÏωση συνδÏομής
diff --git a/bandwagon/locale/el-GR/extensionsOverlay.dtd b/bandwagon/locale/el-GR/extensionsOverlay.dtd
new file mode 100644
index 0000000..bd0f977
--- /dev/null
+++ b/bandwagon/locale/el-GR/extensionsOverlay.dtd
@@ -0,0 +1,26 @@
+<!-- ***** BEGIN LICENSE BLOCK ***** - Version: MPL 1.1/GPL 2.0/LGPL 2.1 - - The contents of this file are subject to the Mozilla Public License Version - 1.1 (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - http://www.mozilla.org/MPL/ - - Software distributed under the License is distributed on an "AS IS" basis, - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - for the specific language governing rights and limitations under the - License. - - The Original Code is bandwagon. - - The Initial Developer of the Original Code is - Mozilla Corporation. - Portions created by the Initial Developer are Copyright (C) 2008 - the Initial Developer. All Rights Reserved. - - Contributor(s): Brian King <brian (at) briks (dot) si> - David McNamara - - Alternatively, the contents of this file may be used under the terms of - either the GNU General Public License Version 2 or later (the "GPL"), or - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - in which case the provisions of the GPL or the LGPL are applicable instead - of those above. If you wish to allow use of your version of this file only - under the terms of either the GPL or the LGPL, and not to allow others to - use your version of this file under the terms of the MPL, indicate your - decision by deleting the provisions above and replace them with the notice - and other provisions required by the GPL or the LGPL. If you do not delete - the provisions above, a recipient may use your version of this file under - the terms of any one of the MPL, the GPL or the LGPL. - - ***** END LICENSE BLOCK ***** -->
+<!ENTITY collections.label "ΣυνδÏομές">
+<!ENTITY search.label.bandwagon "Αναζήτηση">
+<!ENTITY addon.moreinfo "ΠεÏισσότεÏες πληÏοφοÏίες">
+<!ENTITY addon.addtofirefox "ΠÏοσθήκη στον Firefox">
+<!ENTITY subscribe.label "ΕÏÏεση συλλογών">
+<!ENTITY reload.label "Ανανέωση όλων">
+<!ENTITY settings.label "Ρυθμίσεις">
+<!ENTITY view.label "ΠÏοβολή συλλογής">
+<!ENTITY unsubscribe.label "ΑκÏÏωση συνδÏομής">
+<!ENTITY nocollectionstitle.label "Καλώς ήÏθατε στο Add-on Collector">
+<!ENTITY nocollectionssubscribed.label "Εδώ θα εμφανίζονται οι συλλογές που σημειώνετε σαν αγαπημένες στα ΠÏόσθετα Mozilla ώστε να μποÏείτε να τις παÏακολουθείτε εÏκολα. Φαίνεται πως δεν έχετε Ï€Ïοσθέσει ακόμα τίποτα στα αγαπημένα σας, γιατί δεν Ïίχνετε μια ματιά στον κατάλογο συλλογών μας;">
+<!ENTITY clicktosubscribe.label "ΕÏÏεση συλλογών">
+<!ENTITY noamoauth.label "Εδώ θα εμφανίζονται οι συλλογές που σημειώνετε σαν αγαπημένες στα ΠÏόσθετα Mozilla ώστε να μποÏείτε να τις παÏακολουθείτε εÏκολα. Για να χÏησιμοποιήσετε αυτό το χαÏακτηÏιστικό, θα Ï€Ïέπει να έχετε συνδεθεί στο addons.mozilla.org">
+<!ENTITY username.label "ΔιεÏθυνση e-mail">
+<!ENTITY password.label "Κωδικός">
+<!ENTITY clicktologin.label "ΣÏνδεση">
+<!ENTITY createaccount.label "Δεν έχω λογαÏιασμό">
+<!ENTITY loginheading.label "Εισάγετε τις πληÏοφοÏίες του λογαÏÎ¹Î±ÏƒÎ¼Î¿Ï ÏƒÎ±Ï‚ στα Ï€Ïόσθετα Mozilla παÏακάτω:">
+<!ENTITY collectionisloading.label "Ανάκτηση συνδÏομής">
+<!ENTITY collectionhasnoitems.label "Αυτή η συλλογή δεν πεÏιέχει Ï€Ïόσθετα.">
+<!ENTITY collectionhaserror.label "Αυτή η συλλογή δεν μποÏεί να Ï€Ïοβληθεί γιατί πεÏιέχει σφάλματα.">
+<!ENTITY publishto.label "Δημοσίευση σε">
+<!ENTITY email.address.label "ΔιεÏθυνση e-mail">
+<!ENTITY new.email.address.label "Îέα διεÏθυνση e-mail">
+<!ENTITY new.collection.label "Îέα συλλογή">
diff --git a/bandwagon/locale/el-GR/publish.dtd b/bandwagon/locale/el-GR/publish.dtd
new file mode 100644
index 0000000..9f6bcee
--- /dev/null
+++ b/bandwagon/locale/el-GR/publish.dtd
@@ -0,0 +1,47 @@
+<!-- ***** BEGIN LICENSE BLOCK *****
+ - Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ -
+ - The contents of this file are subject to the Mozilla Public License Version
+ - 1.1 (the "License"); you may not use this file except in compliance with
+ - the License. You may obtain a copy of the License at
+ - http://www.mozilla.org/MPL/
+ -
+ - Software distributed under the License is distributed on an "AS IS" basis,
+ - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ - for the specific language governing rights and limitations under the
+ - License.
+ -
+ - The Original Code is bandwagon.
+ -
+ - The Initial Developer of the Original Code is
+ - Mozilla Corporation.
+ - Portions created by the Initial Developer are Copyright (C) 2008
+ - the Initial Developer. All Rights Reserved.
+ -
+ - Contributor(s): David McNamara
+ - Brian King <brian (at) briks (dot) si>
+ -
+ - Alternatively, the contents of this file may be used under the terms of
+ - either the GNU General Public License Version 2 or later (the "GPL"), or
+ - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ - in which case the provisions of the GPL or the LGPL are applicable instead
+ - of those above. If you wish to allow use of your version of this file only
+ - under the terms of either the GPL or the LGPL, and not to allow others to
+ - use your version of this file under the terms of the MPL, indicate your
+ - decision by deleting the provisions above and replace them with the notice
+ - and other provisions required by the GPL or the LGPL. If you do not delete
+ - the provisions above, a recipient may use your version of this file under
+ - the terms of any one of the MPL, the GPL or the LGPL.
+ -
+ - ***** END LICENSE BLOCK *****
+
+ -->
+<!-- For localisers to change the width of the window -->
+<!ENTITY publish.style "width: 35em;">
+<!ENTITY window.title "Δημοσίευση">
+<!ENTITY cancel.label "ΑκÏÏωση">
+<!ENTITY publish.label "Δημοσίευση">
+<!ENTITY new.email.label "Îέα διεÏθυνση e-mail">
+<!ENTITY enter.an.email.label "Εισάγετε μια ή πεÏισσότεÏες διευθÏνσεις e-mail διαχωÏισμένες με κόμμα:">
+<!ENTITY remember.this.email.label "Απομνημόνευση αυτής της διεÏθυνσης e-mail">
+<!ENTITY enter.a.personal.note.label "ΠÏοαιÏετικό: Εισάγετε μια Ï€Ïοσωπική σημείωση σχετικά με το Ï€Ïόσθετο για να συμπεÏιληφθεί στο μήνυμα">
diff --git a/bandwagon/locale/el-GR/publish.properties b/bandwagon/locale/el-GR/publish.properties
new file mode 100644
index 0000000..88e67d9
--- /dev/null
+++ b/bandwagon/locale/el-GR/publish.properties
@@ -0,0 +1,30 @@
+# LOCALIZATION NOTE (you.are.sharing.the.add.on):
+
+# %S is the name of an add-on
+
+you.are.sharing.the.add.on=ΜοιÏάζεστε το Ï€Ïόσθετο %S
+# LOCALIZATION NOTE (publishing.to):
+
+# %1 is the name of an add-on. %2 is the name of a collection
+
+publishing.to=Κάνοντας κλικ στο «Δημοσίευση», θα Ï€Ïοσθέσετε το %1$S στη συλλογή «%2$S».
+# LOCALIZATION NOTE (sharing.with):
+
+# %1 is a user's email address. $2 is the name of an add-on
+
+sharing.with=Αν κάνετε κλικ στο «Αποστολή e-mail», θα αποσταλεί ένα μήνυμα με πληÏοφοÏίες για το %2$S στη διεÏθυνση %1$S
+# LOCALIZATION NOTE (sharing.with.new):
+
+# %S is the name of an add-on
+
+sharing.with.new=Αν κάνετε κλικ στο «Αποστολή e-mail», θα αποσταλεί ένα μήνυμα με πληÏοφοÏίες για το %2$S στις παÏαπάνω διευθÏνσεις
+please.enter.an.email.address=ΠαÏακαλοÏμε εισάγετε μια διεÏθυνση e-mail.
+the.addon.has.been.published=Το Ï€Ïόσθετο δημοσιεÏθηκε.
+the.email.has.been.sent=Απεστάλη το μήνυμα.
+# LOCALIZATION NOTE (closing.in):
+
+# %S is the number of seconds until a window closes, counting down
+
+closing.in=Κλείσιμο σε %S...
+send.email=Αποστολή e-mail
+error.unknown_addon_guid=Αυτό το Ï€Ïόσθετο δεν μποÏεί να διαμοιÏαστεί γιατί δεν φιλοξενείται στον ιστότοπο Ï€Ïόσθετων Mozilla.
diff --git a/bandwagon/locale/el-GR/settings.dtd b/bandwagon/locale/el-GR/settings.dtd
new file mode 100644
index 0000000..f034154
--- /dev/null
+++ b/bandwagon/locale/el-GR/settings.dtd
@@ -0,0 +1,54 @@
+<!-- ***** BEGIN LICENSE BLOCK ***** - Version: MPL 1.1/GPL 2.0/LGPL 2.1 - - The contents of this file are subject to the Mozilla Public License Version - 1.1 (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - http://www.mozilla.org/MPL/ - - Software distributed under the License is distributed on an "AS IS" basis, - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - for the specific language governing rights and limitations under the - License. - - The Original Code is bandwagon. - - The Initial Developer of the Original Code is - Mozilla Corporation. - Portions created by the Initial Developer are Copyright (C) 2008 - the Initial Developer. All Rights Reserved. - - Contributor(s): Brian King <brian (at) briks (dot) si> - David McNamara - - Alternatively, the contents of this file may be used under the terms of - either the GNU General Public License Version 2 or later (the "GPL"), or - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - in which case the provisions of the GPL or the LGPL are applicable instead - of those above. If you wish to allow use of your version of this file only - under the terms of either the GPL or the LGPL, and not to allow others to - use your version of this file under the terms of the MPL, indicate your - decision by deleting the provisions above and replace them with the notice - and other provisions required by the GPL or the LGPL. If you do not delete - the provisions above, a recipient may use your version of this file under - the terms of any one of the MPL, the GPL or the LGPL. - - ***** END LICENSE BLOCK ***** -->
+<!-- For localisers to change the width of the window -->
+<!ENTITY settings.style "width: 42em;">
+<!ENTITY window.title "Ρυθμίσεις Add-on Collector">
+<!-- Tabs -->
+<!ENTITY manage.label "ΔιαχείÏιση συνδÏομών">
+<!ENTITY general.label "Γενικές Ïυθμίσεις">
+<!ENTITY pub.label "Ρυθμίσεις αυτόματης δημοσίευσης">
+<!-- Manage Subscriptions -->
+<!ENTITY subscriptions.header "ΣυνδÏομές:">
+<!-- Groupbox captions in Manage Subscriptions -->
+<!ENTITY frequency.label "Συχνότητα ενημεÏώσεων συνδÏομών">
+<!ENTITY notifications.label "Ειδοποιήσεις νέων συνδÏομών">
+<!ENTITY perpage.label "ΠÏόσθετα ανά σελίδα">
+<!ENTITY default.label "ΧÏήση αÏχικής ÏÏθμισης">
+<!ENTITY custom.label "ΠÏοσαÏμοσμένη">
+<!ENTITY addonsleadin.label "Εμφάνιση">
+<!ENTITY addonsperpage.label "Ï€Ïόσθετα ανά σελίδα">
+<!ENTITY updatesingle.label "ΕνημέÏωση κάθε:">
+<!ENTITY minutes.label "λεπτό/ά">
+<!ENTITY hours.label "ÏŽÏα/ες">
+<!ENTITY days.label "ημέÏα/ες">
+<!ENTITY autopublish.label "Αυτόματη δημοσίευση εγκατεστημένων Ï€Ïόσθετων στη συλλογή">
+<!ENTITY notify.label "Εμφάνιση ειδοποιήσεων">
+<!ENTITY applyall.label "ΕφαÏμογή σε όλες τις συνδÏομές">
+<!ENTITY remove.label "ΑφαίÏεση συνδÏομής">
+<!ENTITY on.label "Îαι">
+<!ENTITY off.label "Όχι">
+<!-- General -->
+<!-- Groupbox captions in General -->
+<!ENTITY subscriptions.label "ΑÏχικές Ïυθμίσεις συνδÏομών">
+<!ENTITY data.label "ΔιαχείÏιση δεδομένων">
+<!ENTITY updateall.label "Έλεγχος συνδÏομών για ενημεÏώσεις κάθε">
+<!ENTITY notifyglobal.label "Ειδοποίηση όταν οι συνδÏομές μου έχουν νέα Ï€Ïόσθετα">
+<!ENTITY clearemails.label "ΕκκαθάÏιση">
+<!ENTITY login.label "ΣÏνδεση">
+<!ENTITY logout.label "ΑποσÏνδεση">
+<!-- Auto-Publisher Settings -->
+<!-- Groupbox captions in Auto-Publisher Settings -->
+<!ENTITY auto.label "Ρυθμίσεις αυτόματης δημοσίευσης">
+<!ENTITY name.label "Όνομα συλλογής:">
+<!ENTITY list.label "Εμφάνιση στο δημόσιο κατάλογο συλλογών">
+<!ENTITY autoleadin.label "Οι συλλογές αυτόματης δημοσίευσης είναι ειδικές συλλογές που ενημεÏώνονται αυτόματα όταν εγκαθιστάτε ή απεγκαθιστάτε Ï€Ïόσθετα του Firefox στον υπολογιστή σας.">
+<!ENTITY types.label "ΤÏποι Ï€Ïόσθετων αυτόματης δημοσίευσης">
+<!ENTITY type.extensions.label "Επεκτάσεις">
+<!ENTITY type.themes.label "Θέματα">
+<!ENTITY type.dicts.label "Λεξικά">
+<!ENTITY type.langpacks.label "Πακέτα γλωσσών">
+<!ENTITY createauto.label "ΔημιουÏγία αυτόματης δημοσίευσης">
+<!ENTITY deleteauto.label "ΔιαγÏαφή αυτόματης δημοσίευσης">
+<!ENTITY updateauto.label "ΕνημέÏωση αυτόματης δημοσίευσης">
+<!ENTITY onlypublishenabledaddons.label "Δημοσίευση μόνο ενεÏγοποιημένων Ï€Ïόσθετων">
+<!ENTITY misc.label "ΔιάφοÏα">
+<!ENTITY allowincompatibleinstall.label "Îα επιτÏέπεται η εγκατάσταση μη συμβατών Ï€Ïόσθετων από τις συλλογές μου">
diff --git a/bandwagon/locale/el-GR/settings.properties b/bandwagon/locale/el-GR/settings.properties
new file mode 100644
index 0000000..db95db7
--- /dev/null
+++ b/bandwagon/locale/el-GR/settings.properties
@@ -0,0 +1,34 @@
+add.collection=ΠÏοσθήκη συνδÏομής
+enter.url.to.add.collection=Εισάγετε το URL της συνδÏομής που θέλετε να Ï€Ïοσθέσετε
+remove.collection=ΑφαίÏεση συνδÏομής
+# LOCALIZATION NOTE (are.you.sure.you.want.to.remove):
+
+# %S is the name of a collection
+
+are.you.sure.you.want.to.remove=Η αφαίÏεση της συνδÏομής σημαίνει και αφαίÏεση της συλλογής από τη λίστα των αγαπημένων σας. Θέλετε σίγουÏα να αφαιÏεθεί η «%S»;
+# LOCALIZATION NOTE (saved.emails.text):
+
+# %S is a number
+
+saved.emails.text=Αποθηκευμένες διευθÏνσεις e-mail: %S
+# LOCALIZATION NOTE (login.status.with.email):
+
+# %S is a user's email address
+
+login.status.with.email=Έχετε συνδεθεί ως %S
+login.status=Είστε σε σÏνδεση
+logout.status=Δεν έχετε συνδεθεί
+# LOCALIZATION NOTE (auto.invalid.name):
+
+# %S is the name of a collection
+
+auto.invalid.name=Το όνομα συλλογής «%S» δεν είναι έγκυÏο.
+auto.please.select.type=ΠαÏακαλοÏμε επιλέξτε Ï„Ïπο Ï€Ïόσθετου για αυτόματη δημοσίευση.
+auto.create.internal.error=Δεν ήταν δυνατό να δημιουÏγηθεί η συλλόγη (παÏουσιάστηκε εσωτεÏικό σφάλμα)
+auto.create.done=ΔημιουÏγήθηκε η συλλογή αυτόματης δημοσίευσης σας.
+auto.delete.internal.error=Δεν ήταν δυνατή η διαγÏαφή της συλλόγης (παÏουσιάστηκε εσωτεÏικό σφάλμα).
+auto.delete.done=ΔιαγÏάφηκε η συλλογή αυτόματης δημοσίευσης σας.
+auto.create.description=Μια αυτόματα δημιουÏγημένη λίστα εγκατεστημένων Ï€Ïόσθετων.
+auto.update.confirm.message=Οι νέες σας Ïυθμίσεις θα εφαÏμοστοÏν άμεσα αλλά δεν θα επηÏεάσουν τα ήδη δημοσιευμένα Ï€Ïόσθετα.
+auto.update.internal.error=Δεν ήταν δυνατή η ενημέÏωση της συλλογής (παÏουσιάστηκε εσωτεÏικό σφάλμα).
+auto.update.done=ΕνημεÏώθηκε η συλλογή αυτόματης δημοσίευσης.
diff --git a/bandwagon/locale/en-US/bandwagon.properties b/bandwagon/locale/en-US/bandwagon.properties
new file mode 100644
index 0000000..37a8281
--- /dev/null
+++ b/bandwagon/locale/en-US/bandwagon.properties
@@ -0,0 +1,2 @@
+extensions.sharing@addons.mozilla.org.description=Share and discover add-ons.
+extensions.sharing@addons.mozilla.org.name=Add-on Collector
diff --git a/bandwagon/locale/en-US/bandwagonAddon.properties b/bandwagon/locale/en-US/bandwagonAddon.properties
new file mode 100644
index 0000000..64ecdfc
--- /dev/null
+++ b/bandwagon/locale/en-US/bandwagonAddon.properties
@@ -0,0 +1,39 @@
+# LOCALIZATION NOTE (bandwagon.addon.pluralRule):
+# See https://developer.mozilla.org/En/Localization_and_Plurals
+bandwagon.addon.pluralRule=1
+bandwagon.category1=Extension
+# LOCALIZATION NOTE (bandwagon.addon.author):
+# %S will contain author's first and last name, or their nickname used on AMO
+bandwagon.addon.author=By %S
+# LOCALIZATION NOTE (bandwagon.addon.addedby):
+# %S will be a user's first and last name, or nickname
+bandwagon.addon.addedby=by %S
+bandwagon.addon.added.justnow=Added: Just now
+# LOCALIZATION NOTE:
+# %S will be a number of time units indicated
+bandwagon.addon.added.minute=Added: 1 minute ago;Added: %S minutes ago
+bandwagon.addon.added.hour=Added: 1 hour ago;Added: %S hours ago
+bandwagon.addon.added.day=Added: Yesterday;Added: %S days ago
+bandwagon.addon.added.week=Added: 1 week ago;Added: %S weeks ago
+bandwagon.addon.added.month=Added: 1 month ago;Added: %S months ago
+bandwagon.addon.added.year=Added: 1 year ago;Added: %S years ago
+bandwagon.addon.moreinfo=More info.
+bandwagon.addon.olderversionsoffirefox=This add-on is for older versions of Firefox.
+# LOCALIZATION NOTE (upgradetofirefoxn1):
+# %S will be a Firefox version number
+bandwagon.addon.upgradetofirefoxn1=Upgrade to Firefox %S
+bandwagon.addon.upgradetofirefoxn2=to use this add-on.
+# LOCALIZATION NOTE (bandwagon.addon.requiresfirefoxbeta1/requiresfirefoxbeta2):
+# %S will be a Firefox version number
+bandwagon.addon.requiresfirefoxbeta1=This add-on requires Firefox %S, which has not yet been released. To use this add-on, you may
+bandwagon.addon.requiresfirefoxbeta2=download Firefox %S beta.
+# LOCALIZATION NOTE (bandwagon.addon.notcompatible):
+# %S will be a platform name, such as "Windows"
+bandwagon.addon.notcompatible=This add-on is not compatible with %S.
+# LOCALIZATION NOTE (bandwagon.addon.comment.description):
+# %S will be a comment entered by the publisher of the add-on
+bandwagon.addon.comment.description=“%Sâ€
+# LOCALIZATION NOTE (bandwagon.addon.comment.author):
+# %S will be the publisher's real name or nickname
+bandwagon.addon.comment.author=Comment from %S:
+bandwagon.addon.isexperimental=This add-on is experimental.
diff --git a/bandwagon/locale/en-US/browserOverlay.dtd b/bandwagon/locale/en-US/browserOverlay.dtd
new file mode 100644
index 0000000..a665207
--- /dev/null
+++ b/bandwagon/locale/en-US/browserOverlay.dtd
@@ -0,0 +1,38 @@
+<!-- ***** BEGIN LICENSE BLOCK *****
+ - Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ -
+ - The contents of this file are subject to the Mozilla Public License Version
+ - 1.1 (the "License"); you may not use this file except in compliance with
+ - the License. You may obtain a copy of the License at
+ - http://www.mozilla.org/MPL/
+ -
+ - Software distributed under the License is distributed on an "AS IS" basis,
+ - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ - for the specific language governing rights and limitations under the
+ - License.
+ -
+ - The Original Code is bandwagon.
+ -
+ - The Initial Developer of the Original Code is
+ - Mozilla Corporation.
+ - Portions created by the Initial Developer are Copyright (C) 2008
+ - the Initial Developer. All Rights Reserved.
+ -
+ - Contributor(s): Brian King <brian (at) briks (dot) si>
+ -
+ - Alternatively, the contents of this file may be used under the terms of
+ - either the GNU General Public License Version 2 or later (the "GPL"), or
+ - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ - in which case the provisions of the GPL or the LGPL are applicable instead
+ - of those above. If you wish to allow use of your version of this file only
+ - under the terms of either the GPL or the LGPL, and not to allow others to
+ - use your version of this file under the terms of the MPL, indicate your
+ - decision by deleting the provisions above and replace them with the notice
+ - and other provisions required by the GPL or the LGPL. If you do not delete
+ - the provisions above, a recipient may use your version of this file under
+ - the terms of any one of the MPL, the GPL or the LGPL.
+ -
+ - ***** END LICENSE BLOCK ***** -->
+
+<!ENTITY bandwagon.label "Add-ons">
+<!ENTITY bandwagon.tooltip "Add-ons">
diff --git a/bandwagon/locale/en-US/browserOverlay.properties b/bandwagon/locale/en-US/browserOverlay.properties
new file mode 100644
index 0000000..5c3b7aa
--- /dev/null
+++ b/bandwagon/locale/en-US/browserOverlay.properties
@@ -0,0 +1,4 @@
+newaddons.alert.title=New Add-ons
+# LOCALIZATION NOTE (newaddons.alert.text):
+# %S will be the name of a collection
+newaddons.alert.text=There are new add-ons in your subscription "%S".
diff --git a/bandwagon/locale/en-US/contents.rdf b/bandwagon/locale/en-US/contents.rdf
new file mode 100644
index 0000000..b6b006a
--- /dev/null
+++ b/bandwagon/locale/en-US/contents.rdf
@@ -0,0 +1,15 @@
+<?xml version="1.0"?>
+<RDF:RDF xmlns:RDF="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:chrome="http://www.mozilla.org/rdf/chrome#">
+ <RDF:Seq about="urn:mozilla:locale:root">
+ <RDF:li resource="urn:mozilla:locale:en-US"/>
+ </RDF:Seq>
+ <RDF:Description about="urn:mozilla:locale:en-US" chrome:name="en-US" >
+ <chrome:packages>
+ <RDF:Seq about="urn:mozilla:locale:en-US:packages">
+ <RDF:li resource="urn:mozilla:locale:en-US:bandwagon"/>
+ </RDF:Seq>
+ </chrome:packages>
+ </RDF:Description>
+</RDF:RDF>
+
diff --git a/bandwagon/locale/en-US/extensionOverlay.properties b/bandwagon/locale/en-US/extensionOverlay.properties
new file mode 100644
index 0000000..03d896c
--- /dev/null
+++ b/bandwagon/locale/en-US/extensionOverlay.properties
@@ -0,0 +1,14 @@
+publish.new.email.address.title=New E-mail Address
+publish.new.email.address.text=Enter a new e-mail address to share this add-on with:
+publish.remove.title=Confirmation
+# LOCALIZATION NOTE (publish.remove.label):
+# %1 is the name of an add-on. %2 is the name of a collection
+publish.remove.label=Are you sure you wish to remove %1$S from the "%2$S" collection?
+publish.remove.button1=No, cancel
+publish.remove.button0=Yes, remove the add-on
+login.error=There was an error logging in. Please check that your username and password are correct.
+unsubscribe.error=There was an error unsubscribing from this collection. Please try again later.
+unsubscribe.confirm.title=Confirm Unsubscribe
+unsubscribe.confirm.label=Unsubscribing from this collection will also remove it from your list of favorites. Are you sure you want to unsubscribe?
+unsubscribe.confirm.button1=No, cancel
+unsubscribe.confirm.button0=Yes, unsubscribe
diff --git a/bandwagon/locale/en-US/extensionsOverlay.dtd b/bandwagon/locale/en-US/extensionsOverlay.dtd
new file mode 100644
index 0000000..8621ff1
--- /dev/null
+++ b/bandwagon/locale/en-US/extensionsOverlay.dtd
@@ -0,0 +1,69 @@
+<!-- ***** BEGIN LICENSE BLOCK *****
+ - Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ -
+ - The contents of this file are subject to the Mozilla Public License Version
+ - 1.1 (the "License"); you may not use this file except in compliance with
+ - the License. You may obtain a copy of the License at
+ - http://www.mozilla.org/MPL/
+ -
+ - Software distributed under the License is distributed on an "AS IS" basis,
+ - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ - for the specific language governing rights and limitations under the
+ - License.
+ -
+ - The Original Code is bandwagon.
+ -
+ - The Initial Developer of the Original Code is
+ - Mozilla Corporation.
+ - Portions created by the Initial Developer are Copyright (C) 2008
+ - the Initial Developer. All Rights Reserved.
+ -
+ - Contributor(s): Brian King <brian (at) briks (dot) si>
+ - David McNamara
+ -
+ - Alternatively, the contents of this file may be used under the terms of
+ - either the GNU General Public License Version 2 or later (the "GPL"), or
+ - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ - in which case the provisions of the GPL or the LGPL are applicable instead
+ - of those above. If you wish to allow use of your version of this file only
+ - under the terms of either the GPL or the LGPL, and not to allow others to
+ - use your version of this file under the terms of the MPL, indicate your
+ - decision by deleting the provisions above and replace them with the notice
+ - and other provisions required by the GPL or the LGPL. If you do not delete
+ - the provisions above, a recipient may use your version of this file under
+ - the terms of any one of the MPL, the GPL or the LGPL.
+ -
+ - ***** END LICENSE BLOCK ***** -->
+
+<!ENTITY collections.label "Subscriptions">
+<!ENTITY search.label.bandwagon "Search">
+
+<!ENTITY addon.moreinfo "More info.">
+<!ENTITY addon.addtofirefox "Add to Firefox">
+<!ENTITY subscribe.label "Find Collections">
+<!ENTITY reload.label "Reload All">
+<!ENTITY settings.label "Settings">
+
+<!ENTITY view.label "View Collection">
+<!ENTITY unsubscribe.label "Unsubscribe">
+
+<!ENTITY nocollectionstitle.label "Welcome to the Add-on Collector">
+<!ENTITY nocollectionssubscribed.label "This is where collections you mark as a favorite on Mozilla Add-ons will appear so that you can easily keep track of them. It looks like you haven't yet added any favorites, so why not take a look around our Collection Directory?">
+<!ENTITY clicktosubscribe.label "Find Collections">
+
+<!ENTITY noamoauth.label "This is where collections you mark as a favorite on Mozilla Add-ons will appear so that you can easily keep track of them. You must be logged in to addons.mozilla.org to use this feature.">
+<!ENTITY username.label "E-mail Address">
+<!ENTITY password.label "Password">
+<!ENTITY clicktologin.label "Log in">
+<!ENTITY createaccount.label "I don't have an account">
+<!ENTITY loginheading.label "Enter your Mozilla Add-ons account information below:">
+
+<!ENTITY collectionisloading.label "Retrieving subscription...">
+<!ENTITY collectionhasnoitems.label "This collection contains no add-ons.">
+<!ENTITY collectionhaserror.label "This collection cannot be displayed because it contains errors.">
+
+<!ENTITY publishto.label "Publish to">
+<!ENTITY email.address.label "E-mail Address">
+<!ENTITY new.email.address.label "New E-mail Address">
+<!ENTITY new.collection.label "New Collection">
+
diff --git a/bandwagon/locale/en-US/publish.dtd b/bandwagon/locale/en-US/publish.dtd
new file mode 100644
index 0000000..0e3ec14
--- /dev/null
+++ b/bandwagon/locale/en-US/publish.dtd
@@ -0,0 +1,48 @@
+<!-- ***** BEGIN LICENSE BLOCK *****
+ - Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ -
+ - The contents of this file are subject to the Mozilla Public License Version
+ - 1.1 (the "License"); you may not use this file except in compliance with
+ - the License. You may obtain a copy of the License at
+ - http://www.mozilla.org/MPL/
+ -
+ - Software distributed under the License is distributed on an "AS IS" basis,
+ - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ - for the specific language governing rights and limitations under the
+ - License.
+ -
+ - The Original Code is bandwagon.
+ -
+ - The Initial Developer of the Original Code is
+ - Mozilla Corporation.
+ - Portions created by the Initial Developer are Copyright (C) 2008
+ - the Initial Developer. All Rights Reserved.
+ -
+ - Contributor(s): David McNamara
+ - Brian King <brian (at) briks (dot) si>
+ -
+ - Alternatively, the contents of this file may be used under the terms of
+ - either the GNU General Public License Version 2 or later (the "GPL"), or
+ - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ - in which case the provisions of the GPL or the LGPL are applicable instead
+ - of those above. If you wish to allow use of your version of this file only
+ - under the terms of either the GPL or the LGPL, and not to allow others to
+ - use your version of this file under the terms of the MPL, indicate your
+ - decision by deleting the provisions above and replace them with the notice
+ - and other provisions required by the GPL or the LGPL. If you do not delete
+ - the provisions above, a recipient may use your version of this file under
+ - the terms of any one of the MPL, the GPL or the LGPL.
+ -
+ - ***** END LICENSE BLOCK ***** -->
+
+<!-- For localisers to change the width of the window -->
+<!ENTITY publish.style "width: 35em;">
+
+<!ENTITY window.title "Publish">
+<!ENTITY cancel.label "Cancel">
+<!ENTITY publish.label "Publish">
+<!ENTITY new.email.label "New E-mail Address">
+<!ENTITY enter.an.email.label "Enter one or more e-mail addresses separated by commas:">
+<!ENTITY remember.this.email.label "Remember this e-mail address">
+<!ENTITY enter.a.personal.note.label "Optional: Enter a personal note about this add-on to be included in the e-mail">
+
diff --git a/bandwagon/locale/en-US/publish.properties b/bandwagon/locale/en-US/publish.properties
new file mode 100644
index 0000000..2e39975
--- /dev/null
+++ b/bandwagon/locale/en-US/publish.properties
@@ -0,0 +1,22 @@
+# LOCALIZATION NOTE (you.are.sharing.the.add.on):
+# %S is the name of an add-on
+you.are.sharing.the.add.on=You are sharing the add-on '%S'
+# LOCALIZATION NOTE (publishing.to):
+# %1 is the name of an add-on. %2 is the name of a collection
+publishing.to=Clicking "Publish" will add %1$S to the "%2$S" collection.
+# LOCALIZATION NOTE (sharing.with):
+# %1 is a user's email address. $2 is the name of an add-on
+sharing.with=Clicking "Send E-mail" will send %1$S an e-mail with information about %2$S
+# LOCALIZATION NOTE (sharing.with.new):
+# %S is the name of an add-on
+sharing.with.new=Clicking "Send E-mail" will send the above recipients an e-mail with information about %S
+please.enter.an.email.address=Please enter an e-mail address.
+the.addon.has.been.published=The add-on has been published.
+the.email.has.been.sent=The email has been sent.
+# LOCALIZATION NOTE (closing.in):
+# %S is the number of seconds until a window closes, counting down
+closing.in=Closing in %S...
+send.email=Send E-mail
+error.unknown_addon_guid=This add-on cannot be shared because it is not hosted on the Mozilla Add-ons website.
+error.invalid_parameters=There was a problem sharing this add-on. Please check that the e-mail address and personal note are valid.
+enter.a.personal.publish.note.label=Optional: Enter a personal note about this add-on to be displayed when published
diff --git a/bandwagon/locale/en-US/settings.dtd b/bandwagon/locale/en-US/settings.dtd
new file mode 100644
index 0000000..b4cd2df
--- /dev/null
+++ b/bandwagon/locale/en-US/settings.dtd
@@ -0,0 +1,108 @@
+<!-- ***** BEGIN LICENSE BLOCK *****
+ - Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ -
+ - The contents of this file are subject to the Mozilla Public License Version
+ - 1.1 (the "License"); you may not use this file except in compliance with
+ - the License. You may obtain a copy of the License at
+ - http://www.mozilla.org/MPL/
+ -
+ - Software distributed under the License is distributed on an "AS IS" basis,
+ - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ - for the specific language governing rights and limitations under the
+ - License.
+ -
+ - The Original Code is bandwagon.
+ -
+ - The Initial Developer of the Original Code is
+ - Mozilla Corporation.
+ - Portions created by the Initial Developer are Copyright (C) 2008
+ - the Initial Developer. All Rights Reserved.
+ -
+ - Contributor(s): Brian King <brian (at) briks (dot) si>
+ - David McNamara
+ -
+ - Alternatively, the contents of this file may be used under the terms of
+ - either the GNU General Public License Version 2 or later (the "GPL"), or
+ - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ - in which case the provisions of the GPL or the LGPL are applicable instead
+ - of those above. If you wish to allow use of your version of this file only
+ - under the terms of either the GPL or the LGPL, and not to allow others to
+ - use your version of this file under the terms of the MPL, indicate your
+ - decision by deleting the provisions above and replace them with the notice
+ - and other provisions required by the GPL or the LGPL. If you do not delete
+ - the provisions above, a recipient may use your version of this file under
+ - the terms of any one of the MPL, the GPL or the LGPL.
+ -
+ - ***** END LICENSE BLOCK ***** -->
+
+<!-- For localisers to change the width of the window -->
+<!ENTITY settings.style "width: 42em;">
+
+<!ENTITY window.title "Add-on Collector Settings">
+
+<!-- Tabs -->
+<!ENTITY manage.label "Manage Subscriptions">
+<!ENTITY general.label "General Settings">
+<!ENTITY pub.label "Auto-publisher Settings">
+
+<!-- Manage Subscriptions -->
+<!ENTITY subscriptions.header "Subscriptions:">
+
+<!-- Groupbox captions in Manage Subscriptions -->
+<!ENTITY frequency.label "Subscription Update Frequency">
+<!ENTITY notifications.label "New Add-on Notifications">
+<!ENTITY perpage.label "Add-ons per Page">
+
+<!ENTITY default.label "Use default setting">
+<!ENTITY custom.label "Custom:">
+
+<!ENTITY addonsleadin.label "Show">
+<!ENTITY addonsperpage.label "add-ons per page">
+<!ENTITY updatesingle.label "Update every:">
+<!ENTITY minutes.label "minute(s)">
+<!ENTITY hours.label "hour(s)">
+<!ENTITY days.label "day(s)">
+<!ENTITY autopublish.label "Auto-publish installed add-ons to subscription">
+<!ENTITY notify.label "Show notifications">
+<!ENTITY applyall.label "Apply to all subscriptions">
+<!ENTITY remove.label "Remove Subscription">
+<!ENTITY on.label "On">
+<!ENTITY off.label "Off">
+
+<!-- General -->
+
+<!-- Groupbox captions in General -->
+<!ENTITY subscriptions.label "Default Subscription Settings">
+<!ENTITY data.label "Data Management">
+
+<!ENTITY updateall.label "Check subscriptions for updates every">
+<!ENTITY notifyglobal.label "Notify me when my subscriptions have new add-ons">
+
+<!ENTITY clearemails.label "Clear">
+<!ENTITY login.label "Log in">
+<!ENTITY logout.label "Log out">
+
+<!-- Auto-Publisher Settings -->
+
+<!-- Groupbox captions in Auto-Publisher Settings -->
+<!ENTITY auto.label "Auto-publisher Settings">
+
+<!ENTITY name.label "Collection Name:">
+<!ENTITY list.label "Listed in public Collection Directory">
+
+<!ENTITY autoleadin.label "Auto-publishers are special collections that are automatically updated when you install or uninstall add-ons from Firefox on this computer.">
+<!ENTITY types.label "Auto-published add-on types:">
+<!ENTITY type.extensions.label "Extensions">
+<!ENTITY type.themes.label "Themes">
+<!ENTITY type.dicts.label "Dictionaries">
+<!ENTITY type.langpacks.label "Language Packs">
+
+<!ENTITY createauto.label "Create Auto-publisher">
+<!ENTITY deleteauto.label "Delete Auto-publisher">
+<!ENTITY updateauto.label "Update Auto-publisher">
+
+<!ENTITY onlypublishenabledaddons.label "Only publish enabled add-ons">
+
+<!ENTITY misc.label "Miscellaneous">
+<!ENTITY allowincompatibleinstall.label "Allow installation of incompatible add-ons from my subscriptions">
+
diff --git a/bandwagon/locale/en-US/settings.properties b/bandwagon/locale/en-US/settings.properties
new file mode 100644
index 0000000..3d53195
--- /dev/null
+++ b/bandwagon/locale/en-US/settings.properties
@@ -0,0 +1,26 @@
+add.collection=Add Subscription
+enter.url.to.add.collection=Enter the URL of the subscription you want to add.
+remove.collection=Remove Subscription
+# LOCALIZATION NOTE (are.you.sure.you.want.to.remove):
+# %S is the name of a collection
+are.you.sure.you.want.to.remove=Removing this subscription will also remove the collection from your favorites list. Are you sure you wish to remove '%S'?
+# LOCALIZATION NOTE (saved.emails.text):
+# %S is a number
+saved.emails.text=You have %S saved e-mail addresses
+# LOCALIZATION NOTE (login.status.with.email):
+# %S is a user's email address
+login.status.with.email=You are logged in as %S
+login.status=You are logged in
+logout.status=You are not logged in
+# LOCALIZATION NOTE (auto.invalid.name):
+# %S is the name of a collection
+auto.invalid.name=The collection name '%S' is not valid.
+auto.please.select.type=Please select at least one add-on type to automatically publish.
+auto.create.internal.error=The collection could not be created (an internal error occurred).
+auto.create.done=Your auto-publisher collection has been created.
+auto.delete.internal.error=The collection could not be deleted (an internal error occurred).
+auto.delete.done=Your auto-publisher collection has been deleted.
+auto.create.description=An automatically generated list of my installed add-ons
+auto.update.confirm.message=Your new settings will take effect immediately, but will not affect add-ons that have already been published.
+auto.update.internal.error=The collection could not be updated (an internal error occured).
+auto.update.done=Your auto-publisher collection has been updated.
diff --git a/bandwagon/locale/es-ES/bandwagon.properties b/bandwagon/locale/es-ES/bandwagon.properties
new file mode 100644
index 0000000..c435b5c
--- /dev/null
+++ b/bandwagon/locale/es-ES/bandwagon.properties
@@ -0,0 +1,2 @@
+extensions.sharing@addons.mozilla.org.description=Comparte y descubre complementos.
+extensions.sharing@addons.mozilla.org.name=Add-on Collector
diff --git a/bandwagon/locale/es-ES/bandwagonAddon.properties b/bandwagon/locale/es-ES/bandwagonAddon.properties
new file mode 100644
index 0000000..166fe86
--- /dev/null
+++ b/bandwagon/locale/es-ES/bandwagonAddon.properties
@@ -0,0 +1,56 @@
+# LOCALIZATION NOTE (bandwagon.addon.pluralRule):
+
+# See https://developer.mozilla.org/En/Localization_and_Plurals
+
+bandwagon.addon.pluralRule=1
+bandwagon.category1=Extensión
+# LOCALIZATION NOTE (bandwagon.addon.author):
+
+# %S will contain author's first and last name, or their nickname used on AMO
+
+bandwagon.addon.author=Por %S
+# LOCALIZATION NOTE (bandwagon.addon.addedby):
+
+# %S will be a user's first and last name, or nickname
+
+bandwagon.addon.addedby=por %S
+bandwagon.addon.added.justnow=Añadido: Ahora mismo
+# LOCALIZATION NOTE:
+
+# %S will be a number of time units indicated
+
+bandwagon.addon.added.minute=Añadido: Hace 1 minuto;Añadido hace % minutos
+bandwagon.addon.added.hour=Añadido: Hace 1 hora;Añadido hace %S horas
+bandwagon.addon.added.day=Añadido: Ayer;Añadido: Hacer %S días
+bandwagon.addon.added.week=Añadido: Hace 1 semana;Añadido hace %S semanas
+bandwagon.addon.added.month=Añadido: Hace 1 mes;Añadido hace %S meses
+bandwagon.addon.added.year=Añadido: Hace 1 año;Añadido hace %S años
+bandwagon.addon.moreinfo=Más información
+bandwagon.addon.olderversionsoffirefox=Este complemento es para versiones antiguas de Firefox.
+# LOCALIZATION NOTE (upgradetofirefoxn1):
+
+# %S will be a Firefox version number
+
+bandwagon.addon.upgradetofirefoxn1=Actualiza a Firefox %S
+bandwagon.addon.upgradetofirefoxn2=para usar este complemento.
+# LOCALIZATION NOTE (bandwagon.addon.requiresfirefoxbeta1/requiresfirefoxbeta2):
+
+# %S will be a Firefox version number
+
+bandwagon.addon.requiresfirefoxbeta1=Este complemente requiere Firefox %S, el cual no se ha publicado aún. Para utilizar este complemento debe
+bandwagon.addon.requiresfirefoxbeta2=descargar Firefox %S beta.
+# LOCALIZATION NOTE (bandwagon.addon.notcompatible):
+
+# %S will be a platform name, such as "Windows"
+
+bandwagon.addon.notcompatible=Este complemento no es compatible con %S.
+# LOCALIZATION NOTE (bandwagon.addon.comment.description):
+
+# %S will be a comment entered by the publisher of the add-on
+
+bandwagon.addon.comment.description=“%Sâ€
+# LOCALIZATION NOTE (bandwagon.addon.comment.author):
+
+# %S will be the publisher's real name or nickname
+
+bandwagon.addon.comment.author=Comentario de %S:
diff --git a/bandwagon/locale/es-ES/browserOverlay.dtd b/bandwagon/locale/es-ES/browserOverlay.dtd
new file mode 100644
index 0000000..c770e33
--- /dev/null
+++ b/bandwagon/locale/es-ES/browserOverlay.dtd
@@ -0,0 +1,3 @@
+<!-- ***** BEGIN LICENSE BLOCK ***** - Version: MPL 1.1/GPL 2.0/LGPL 2.1 - - The contents of this file are subject to the Mozilla Public License Version - 1.1 (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - http://www.mozilla.org/MPL/ - - Software distributed under the License is distributed on an "AS IS" basis, - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - for the specific language governing rights and limitations under the - License. - - The Original Code is bandwagon. - - The Initial Developer of the Original Code is - Mozilla Corporation. - Portions created by the Initial Developer are Copyright (C) 2008 - the Initial Developer. All Rights Reserved. - - Contributor(s): Brian King <brian (at) briks (dot) si> - - Alternatively, the contents of this file may be used under the terms of - either the GNU General Public License Version 2 or later (the "GPL"), or - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - in which case the provisions of the GPL or the LGPL are applicable instead - of those above. If you wish to allow use of your version of this file only - under the terms of either the GPL or the LGPL, and not to allow others to - use your version of this file under the terms of the MPL, indicate your - decision by deleting the provisions above and replace them with the notice - and other provisions required by the GPL or the LGPL. If you do not delete - the provisions above, a recipient may use your version of this file under - the terms of any one of the MPL, the GPL or the LGPL. - - ***** END LICENSE BLOCK ***** -->
+<!ENTITY bandwagon.label "Complementos">
+<!ENTITY bandwagon.tooltip "Complementos">
diff --git a/bandwagon/locale/es-ES/browserOverlay.properties b/bandwagon/locale/es-ES/browserOverlay.properties
new file mode 100644
index 0000000..31a47ed
--- /dev/null
+++ b/bandwagon/locale/es-ES/browserOverlay.properties
@@ -0,0 +1,6 @@
+newaddons.alert.title=Nuevos complementos
+# LOCALIZATION NOTE (newaddons.alert.text):
+
+# %S will be the name of a collection
+
+newaddons.alert.text=Hay nuevos complementos en su suscripción "%S".
diff --git a/bandwagon/locale/es-ES/contents.rdf b/bandwagon/locale/es-ES/contents.rdf
new file mode 100644
index 0000000..331331a
--- /dev/null
+++ b/bandwagon/locale/es-ES/contents.rdf
@@ -0,0 +1,15 @@
+<?xml version="1.0"?>
+<RDF:RDF xmlns:RDF="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:chrome="http://www.mozilla.org/rdf/chrome#">
+ <RDF:Seq about="urn:mozilla:locale:root">
+ <RDF:li resource="urn:mozilla:locale:es-ES"/>
+ </RDF:Seq>
+ <RDF:Description about="urn:mozilla:locale:es-ES" chrome:name="es-ES" >
+ <chrome:packages>
+ <RDF:Seq about="urn:mozilla:locale:es-ES:packages">
+ <RDF:li resource="urn:mozilla:locale:es-ES:bandwagon"/>
+ </RDF:Seq>
+ </chrome:packages>
+ </RDF:Description>
+</RDF:RDF>
+
diff --git a/bandwagon/locale/es-ES/extensionOverlay.properties b/bandwagon/locale/es-ES/extensionOverlay.properties
new file mode 100644
index 0000000..63eb8fd
--- /dev/null
+++ b/bandwagon/locale/es-ES/extensionOverlay.properties
@@ -0,0 +1,16 @@
+publish.new.email.address.title=Nueva dirección de correo
+publish.new.email.address.text=Introduzca una nueva dirección de correo para compartir este complemento con:
+publish.remove.title=Confirmación
+# LOCALIZATION NOTE (publish.remove.label):
+
+# %1 is the name of an add-on. %2 is the name of a collection
+
+publish.remove.label=¿Está seguro que quiere borrar %1$S de la recopilación "%2$S"?
+publish.remove.button1=No, cancelar
+publish.remove.button0=Sí, borrar el complemento
+login.error=Hubo un errar al iniciar sesión. Por favor, compruebe que su nombre de usuario y contraseña son correctos.
+unsubscribe.error=Hubo un error al borrar su suscripción de esta recopilación. Por favor, inténtelo más tarde.
+unsubscribe.confirm.title=Confirmar borrado de la suscripción
+unsubscribe.confirm.label=Borrar la suscripción de esta recopilación la borrará también de su lista de favoritos. ¿Está seguro de borrar la suscripción?
+unsubscribe.confirm.button1=No, cancelar
+unsubscribe.confirm.button0=Sí, borrar suscripción
diff --git a/bandwagon/locale/es-ES/extensionsOverlay.dtd b/bandwagon/locale/es-ES/extensionsOverlay.dtd
new file mode 100644
index 0000000..16c3541
--- /dev/null
+++ b/bandwagon/locale/es-ES/extensionsOverlay.dtd
@@ -0,0 +1,26 @@
+<!-- ***** BEGIN LICENSE BLOCK ***** - Version: MPL 1.1/GPL 2.0/LGPL 2.1 - - The contents of this file are subject to the Mozilla Public License Version - 1.1 (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - http://www.mozilla.org/MPL/ - - Software distributed under the License is distributed on an "AS IS" basis, - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - for the specific language governing rights and limitations under the - License. - - The Original Code is bandwagon. - - The Initial Developer of the Original Code is - Mozilla Corporation. - Portions created by the Initial Developer are Copyright (C) 2008 - the Initial Developer. All Rights Reserved. - - Contributor(s): Brian King <brian (at) briks (dot) si> - David McNamara - - Alternatively, the contents of this file may be used under the terms of - either the GNU General Public License Version 2 or later (the "GPL"), or - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - in which case the provisions of the GPL or the LGPL are applicable instead - of those above. If you wish to allow use of your version of this file only - under the terms of either the GPL or the LGPL, and not to allow others to - use your version of this file under the terms of the MPL, indicate your - decision by deleting the provisions above and replace them with the notice - and other provisions required by the GPL or the LGPL. If you do not delete - the provisions above, a recipient may use your version of this file under - the terms of any one of the MPL, the GPL or the LGPL. - - ***** END LICENSE BLOCK ***** -->
+<!ENTITY collections.label "Suscripciones">
+<!ENTITY search.label.bandwagon "Buscar">
+<!ENTITY addon.moreinfo "Más información">
+<!ENTITY addon.addtofirefox "Añadir a Firefox">
+<!ENTITY subscribe.label "Buscar recopilaciones">
+<!ENTITY reload.label "Recargar todas">
+<!ENTITY settings.label "Preferencias">
+<!ENTITY view.label "Ver recopilación">
+<!ENTITY unsubscribe.label "Borrar suscripción">
+<!ENTITY nocollectionstitle.label "Bienvenido al recopilador de complementos">
+<!ENTITY nocollectionssubscribed.label "Aquí es donde aparecerán las recopilaciones que marque como favoritas en Mozilla Addons y así podrá seguirlas fácilmente. Parece que aún no ha añadido nada a favoritos, ¿porqué no echa un vistazo a nuestro directorio de recopilaciones?">
+<!ENTITY clicktosubscribe.label "Buscar recopilaciones">
+<!ENTITY noamoauth.label "Aquí es donde aparecerán las recopilaciones que marque como favoritas en Mozilla Addons y así podrá seguirlas fácilmente. Debe iniciar sesión en addons.mozilla.org para usar esta característica.">
+<!ENTITY username.label "Nombre de usuario">
+<!ENTITY password.label "Contraseña">
+<!ENTITY clicktologin.label "Iniciar sesión">
+<!ENTITY createaccount.label "No tengo una cuenta">
+<!ENTITY loginheading.label "Introduzca la información de su cuenta en Mozilla Addons:">
+<!ENTITY collectionisloading.label "Recuperando suscripción...">
+<!ENTITY collectionhasnoitems.label "Esta recopilación no contiene complementos.">
+<!ENTITY collectionhaserror.label "No se puede mostrar esta recopilación ya que contiene errores.">
+<!ENTITY publishto.label "Publicar en">
+<!ENTITY email.address.label "Dirección de correo">
+<!ENTITY new.email.address.label "Nueva dirección de correo">
+<!ENTITY new.collection.label "Nueva recopilación">
diff --git a/bandwagon/locale/es-ES/publish.dtd b/bandwagon/locale/es-ES/publish.dtd
new file mode 100644
index 0000000..2141f81
--- /dev/null
+++ b/bandwagon/locale/es-ES/publish.dtd
@@ -0,0 +1,47 @@
+<!-- ***** BEGIN LICENSE BLOCK *****
+ - Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ -
+ - The contents of this file are subject to the Mozilla Public License Version
+ - 1.1 (the "License"); you may not use this file except in compliance with
+ - the License. You may obtain a copy of the License at
+ - http://www.mozilla.org/MPL/
+ -
+ - Software distributed under the License is distributed on an "AS IS" basis,
+ - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ - for the specific language governing rights and limitations under the
+ - License.
+ -
+ - The Original Code is bandwagon.
+ -
+ - The Initial Developer of the Original Code is
+ - Mozilla Corporation.
+ - Portions created by the Initial Developer are Copyright (C) 2008
+ - the Initial Developer. All Rights Reserved.
+ -
+ - Contributor(s): David McNamara
+ - Brian King <brian (at) briks (dot) si>
+ -
+ - Alternatively, the contents of this file may be used under the terms of
+ - either the GNU General Public License Version 2 or later (the "GPL"), or
+ - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ - in which case the provisions of the GPL or the LGPL are applicable instead
+ - of those above. If you wish to allow use of your version of this file only
+ - under the terms of either the GPL or the LGPL, and not to allow others to
+ - use your version of this file under the terms of the MPL, indicate your
+ - decision by deleting the provisions above and replace them with the notice
+ - and other provisions required by the GPL or the LGPL. If you do not delete
+ - the provisions above, a recipient may use your version of this file under
+ - the terms of any one of the MPL, the GPL or the LGPL.
+ -
+ - ***** END LICENSE BLOCK *****
+
+ -->
+<!-- For localisers to change the width of the window -->
+<!ENTITY publish.style "width: 35em;">
+<!ENTITY window.title "Publicar">
+<!ENTITY cancel.label "Cancelar">
+<!ENTITY publish.label "Publicar">
+<!ENTITY new.email.label "Nueva dirección de correo">
+<!ENTITY enter.an.email.label "Introduzca una o varias direcciones de correo separadas por comas:">
+<!ENTITY remember.this.email.label "Recordar esta dirección de correo">
+<!ENTITY enter.a.personal.note.label "Opcional: Introduzca una nota persona sobre este complemento para que sea incluida en el correo">
diff --git a/bandwagon/locale/es-ES/publish.properties b/bandwagon/locale/es-ES/publish.properties
new file mode 100644
index 0000000..c14ff84
--- /dev/null
+++ b/bandwagon/locale/es-ES/publish.properties
@@ -0,0 +1,30 @@
+# LOCALIZATION NOTE (you.are.sharing.the.add.on):
+
+# %S is the name of an add-on
+
+you.are.sharing.the.add.on=Está compartiendo el complemento '%S'
+# LOCALIZATION NOTE (publishing.to):
+
+# %1 is the name of an add-on. %2 is the name of a collection
+
+publishing.to=Al hacer clic en "Publicar" añadirá %1$S a la recopilación "%2$S".
+# LOCALIZATION NOTE (sharing.with):
+
+# %1 is a user's email address. $2 is the name of an add-on
+
+sharing.with=Al hacer clic en "Enviar correo" enviará a %1$S un correo electrónico con información sobre %2$S
+# LOCALIZATION NOTE (sharing.with.new):
+
+# %S is the name of an add-on
+
+sharing.with.new=Al hacer clic sobre "Enviar correo" enviará a los destinatarios de arriba un correo electrónico con información sobre %S
+please.enter.an.email.address=Por favor, introduzca un dirección de correo.
+the.addon.has.been.published=Se ha publicado el complemento.
+the.email.has.been.sent=Se ha enviado el correo electrónico.
+# LOCALIZATION NOTE (closing.in):
+
+# %S is the number of seconds until a window closes, counting down
+
+closing.in=Cerrándose en %S...
+send.email=Enviar correo electrónico
+error.unknown_addon_guid=Este complemento no puede ser compartido porque no está alojado en la página web de Mozilla Addons.
diff --git a/bandwagon/locale/es-ES/settings.dtd b/bandwagon/locale/es-ES/settings.dtd
new file mode 100644
index 0000000..296ba80
--- /dev/null
+++ b/bandwagon/locale/es-ES/settings.dtd
@@ -0,0 +1,54 @@
+<!-- ***** BEGIN LICENSE BLOCK ***** - Version: MPL 1.1/GPL 2.0/LGPL 2.1 - - The contents of this file are subject to the Mozilla Public License Version - 1.1 (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - http://www.mozilla.org/MPL/ - - Software distributed under the License is distributed on an "AS IS" basis, - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - for the specific language governing rights and limitations under the - License. - - The Original Code is bandwagon. - - The Initial Developer of the Original Code is - Mozilla Corporation. - Portions created by the Initial Developer are Copyright (C) 2008 - the Initial Developer. All Rights Reserved. - - Contributor(s): Brian King <brian (at) briks (dot) si> - David McNamara - - Alternatively, the contents of this file may be used under the terms of - either the GNU General Public License Version 2 or later (the "GPL"), or - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - in which case the provisions of the GPL or the LGPL are applicable instead - of those above. If you wish to allow use of your version of this file only - under the terms of either the GPL or the LGPL, and not to allow others to - use your version of this file under the terms of the MPL, indicate your - decision by deleting the provisions above and replace them with the notice - and other provisions required by the GPL or the LGPL. If you do not delete - the provisions above, a recipient may use your version of this file under - the terms of any one of the MPL, the GPL or the LGPL. - - ***** END LICENSE BLOCK ***** -->
+<!-- For localisers to change the width of the window -->
+<!ENTITY settings.style "width: 42em;">
+<!ENTITY window.title "Preferencias del recopilador de complementos">
+<!-- Tabs -->
+<!ENTITY manage.label "Administrar suscripciones">
+<!ENTITY general.label "Preferencias generales">
+<!ENTITY pub.label "Preferencias de auto-publicado">
+<!-- Manage Subscriptions -->
+<!ENTITY subscriptions.header "Suscripciones:">
+<!-- Groupbox captions in Manage Subscriptions -->
+<!ENTITY frequency.label "Frecuencia de actualización de suscripciones">
+<!ENTITY notifications.label "Nuevas notificaciones de complementos">
+<!ENTITY perpage.label "Complementos por página">
+<!ENTITY default.label "Usar la opción por defecto">
+<!ENTITY custom.label "Personalizado:">
+<!ENTITY addonsleadin.label "Mostrar">
+<!ENTITY addonsperpage.label "complementos por página">
+<!ENTITY updatesingle.label "Actualizar cada:">
+<!ENTITY minutes.label "minuto(s)">
+<!ENTITY hours.label "hora(s)">
+<!ENTITY days.label "día(s)">
+<!ENTITY autopublish.label "Publicar automáticamente los complementos instalado a la suscripción">
+<!ENTITY notify.label "Mostrar notificaciones">
+<!ENTITY applyall.label "Aplicar a todas las suscripciones">
+<!ENTITY remove.label "Borrar suscripción">
+<!ENTITY on.label "Activado">
+<!ENTITY off.label "Desactivado">
+<!-- General -->
+<!-- Groupbox captions in General -->
+<!ENTITY subscriptions.label "Preferencias por defecto de la suscripción">
+<!ENTITY data.label "Gestión de datos">
+<!ENTITY updateall.label "Comprobar actualización de suscripciones cada">
+<!ENTITY notifyglobal.label "Informarme cuando mis suscripciones tiene nuevos complementos">
+<!ENTITY clearemails.label "Limpiar">
+<!ENTITY login.label "Iniciar sesión">
+<!ENTITY logout.label "Cerrar sesión">
+<!-- Auto-Publisher Settings -->
+<!-- Groupbox captions in Auto-Publisher Settings -->
+<!ENTITY auto.label "Preferencias de auto-publicación">
+<!ENTITY name.label "Nombre de la recopilación:">
+<!ENTITY list.label "Listado en el directorio público de recopilaciones">
+<!ENTITY autoleadin.label "Las recopilaciones auto-publicables son recopilaciones especiales que se actualizan automáticamente cuando instala o desinstala complementos en Firefox de este ordenador.">
+<!ENTITY types.label "Tipos de complementos auto-publicables:">
+<!ENTITY type.extensions.label "Extensiones">
+<!ENTITY type.themes.label "Temas">
+<!ENTITY type.dicts.label "Diccionarios">
+<!ENTITY type.langpacks.label "Paquetes de idioma">
+<!ENTITY createauto.label "Crear una recopilación auto-publicable">
+<!ENTITY deleteauto.label "Borrar una recopilación auto-publicable">
+<!ENTITY updateauto.label "Actualizar una recopilación auto-publicable">
+<!ENTITY onlypublishenabledaddons.label "Sólo publicar complementos activos">
+<!ENTITY misc.label "Miscelánea">
+<!ENTITY allowincompatibleinstall.label "Permitir la instalación de complementos incompatibles de mis suscripciones">
diff --git a/bandwagon/locale/es-ES/settings.properties b/bandwagon/locale/es-ES/settings.properties
new file mode 100644
index 0000000..b6ab8d4
--- /dev/null
+++ b/bandwagon/locale/es-ES/settings.properties
@@ -0,0 +1,34 @@
+add.collection=Añadir suscripción
+enter.url.to.add.collection=Introduzca la URL de la suscripción que quiere añadir
+remove.collection=Borrar suscripción
+# LOCALIZATION NOTE (are.you.sure.you.want.to.remove):
+
+# %S is the name of a collection
+
+are.you.sure.you.want.to.remove=Al borrar esta suscripción también borrará la recopilación de su lista de favoritos. ¿Está seguro de borrar '%S'?
+# LOCALIZATION NOTE (saved.emails.text):
+
+# %S is a number
+
+saved.emails.text=Tiene %S direcciones de correo guardadas
+# LOCALIZATION NOTE (login.status.with.email):
+
+# %S is a user's email address
+
+login.status.with.email=Ha iniciado sesión como %S
+login.status=Ha iniciado sesión
+logout.status=No ha iniciado sesión
+# LOCALIZATION NOTE (auto.invalid.name):
+
+# %S is the name of a collection
+
+auto.invalid.name=El nombre de recopilación '%S' no es válido.
+auto.please.select.type=Por favor, seleccione al menos un tipo de complemento para publicar automáticamente.
+auto.create.internal.error=No se pudo crear la recopilación (ocurrió un error interno).
+auto.create.done=Se ha creado su recopilación auto-publicable.
+auto.delete.internal.error=No se pudo borrar la recopilación (ocurrió un error interno).
+auto.delete.done=Se ha borrado su recopilación auto-publicable.
+auto.create.description=Un lista generada automáticamente de mis complementos instalados
+auto.update.confirm.message=Sus nuevas preferencias se aplicarán inmediatamente, pero no afectarán a los complementos que ya se hayan publicado.
+auto.update.internal.error=La recopilación no puede ser actualizada (sucedió un error desconocido).
+auto.update.done=Su recopilación auto-publicable ha sido actualizada.
diff --git a/bandwagon/locale/fa/bandwagon.properties b/bandwagon/locale/fa/bandwagon.properties
new file mode 100644
index 0000000..2a4639a
--- /dev/null
+++ b/bandwagon/locale/fa/bandwagon.properties
@@ -0,0 +1,2 @@
+extensions.sharing@addons.mozilla.org.description=به اشتراک گذاشتن Ùˆ کش٠اÙزودنی‌ها.
+extensions.sharing@addons.mozilla.org.name=جمع‌کنندهٔ اÙزودنی‌ها
diff --git a/bandwagon/locale/fa/bandwagonAddon.properties b/bandwagon/locale/fa/bandwagonAddon.properties
new file mode 100644
index 0000000..78b546c
--- /dev/null
+++ b/bandwagon/locale/fa/bandwagonAddon.properties
@@ -0,0 +1,38 @@
+# LOCALIZATION NOTE (bandwagon.addon.pluralRule):
+# See https://developer.mozilla.org/En/Localization_and_Plurals
+bandwagon.addon.pluralRule=1
+bandwagon.category1=ضمیمه
+# LOCALIZATION NOTE (bandwagon.addon.author):
+# %S will contain author's first and last name, or their nickname used on AMO
+bandwagon.addon.author=تهیه شده توسط %S
+# LOCALIZATION NOTE (bandwagon.addon.addedby):
+# %S will be a user's first and last name, or nickname
+bandwagon.addon.addedby=توسط %S
+bandwagon.addon.added.justnow=هم‌اکنون اÙزوده شده
+# LOCALIZATION NOTE:
+# %S will be a number of time units indicated
+bandwagon.addon.added.minute=%S دقیقهٔ پیش اÙزوده شده
+bandwagon.addon.added.hour=%S ساعت پیش اÙزوده شده
+bandwagon.addon.added.day=%S روز پیش اÙزوده شده
+bandwagon.addon.added.week=%S Ù‡Ùتهٔ پیش اÙزوده شده
+bandwagon.addon.added.month=%S ماه پیش اÙزوده شده
+bandwagon.addon.added.year=%S سال پیش اÙزوده شده
+bandwagon.addon.moreinfo=اطلاعات بیشتر.
+bandwagon.addon.olderversionsoffirefox=این اÙزودنی مخصوص نسخه‌های پیشین ÙایرÙاکس است.
+# LOCALIZATION NOTE (upgradetofirefoxn1):
+# %S will be a Firefox version number
+bandwagon.addon.upgradetofirefoxn1=ارتقا به ÙایرÙاکس %S
+bandwagon.addon.upgradetofirefoxn2=جهت استÙاده از این اÙزودنی.
+# LOCALIZATION NOTE (bandwagon.addon.requiresfirefoxbeta1/requiresfirefoxbeta2):
+# %S will be a Firefox version number
+bandwagon.addon.requiresfirefoxbeta1=این اÙزودنی نیازمند ÙایرÙاکس %S است Ú©Ù‡ هنوز منتظر نشده است. برای استÙاده از این اÙزودنی، می‌توانید
+bandwagon.addon.requiresfirefoxbeta2=نسخهٔ بتا ÙابرÙاکس %S را بارگیری کنید.
+# LOCALIZATION NOTE (bandwagon.addon.notcompatible):
+# %S will be a platform name, such as "Windows"
+bandwagon.addon.notcompatible=این اÙزودنی با %S سازگار نیست.
+# LOCALIZATION NOTE (bandwagon.addon.comment.description):
+# %S will be a comment entered by the publisher of the add-on
+bandwagon.addon.comment.description=«%S»
+# LOCALIZATION NOTE (bandwagon.addon.comment.author):
+# %S will be the publisher's real name or nickname
+bandwagon.addon.comment.author=نظر Ùرستاده شده توسط %S:
diff --git a/bandwagon/locale/fa/browserOverlay.dtd b/bandwagon/locale/fa/browserOverlay.dtd
new file mode 100644
index 0000000..4f6df55
--- /dev/null
+++ b/bandwagon/locale/fa/browserOverlay.dtd
@@ -0,0 +1,38 @@
+<!-- ***** BEGIN LICENSE BLOCK *****
+ - Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ -
+ - The contents of this file are subject to the Mozilla Public License Version
+ - 1.1 (the "License"); you may not use this file except in compliance with
+ - the License. You may obtain a copy of the License at
+ - http://www.mozilla.org/MPL/
+ -
+ - Software distributed under the License is distributed on an "AS IS" basis,
+ - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ - for the specific language governing rights and limitations under the
+ - License.
+ -
+ - The Original Code is bandwagon.
+ -
+ - The Initial Developer of the Original Code is
+ - Mozilla Corporation.
+ - Portions created by the Initial Developer are Copyright (C) 2008
+ - the Initial Developer. All Rights Reserved.
+ -
+ - Contributor(s): Brian King <brian (at) briks (dot) si>
+ -
+ - Alternatively, the contents of this file may be used under the terms of
+ - either the GNU General Public License Version 2 or later (the "GPL"), or
+ - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ - in which case the provisions of the GPL or the LGPL are applicable instead
+ - of those above. If you wish to allow use of your version of this file only
+ - under the terms of either the GPL or the LGPL, and not to allow others to
+ - use your version of this file under the terms of the MPL, indicate your
+ - decision by deleting the provisions above and replace them with the notice
+ - and other provisions required by the GPL or the LGPL. If you do not delete
+ - the provisions above, a recipient may use your version of this file under
+ - the terms of any one of the MPL, the GPL or the LGPL.
+ -
+ - ***** END LICENSE BLOCK ***** -->
+
+<!ENTITY bandwagon.label "اÙزودنی‌ها">
+<!ENTITY bandwagon.tooltip "اÙزودنی‌ها">
diff --git a/bandwagon/locale/fa/browserOverlay.properties b/bandwagon/locale/fa/browserOverlay.properties
new file mode 100644
index 0000000..cc690fa
--- /dev/null
+++ b/bandwagon/locale/fa/browserOverlay.properties
@@ -0,0 +1,4 @@
+newaddons.alert.title=اÙزودنی‌های جدید
+# LOCALIZATION NOTE (newaddons.alert.text):
+# %S will be the name of a collection
+newaddons.alert.text=اÙزودنی‌های جدیدی در آبونمان «%S» شما وجود دارند.
diff --git a/bandwagon/locale/fa/contents.rdf b/bandwagon/locale/fa/contents.rdf
new file mode 100644
index 0000000..f5a0031
--- /dev/null
+++ b/bandwagon/locale/fa/contents.rdf
@@ -0,0 +1,15 @@
+<?xml version="1.0"?>
+<RDF:RDF xmlns:RDF="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:chrome="http://www.mozilla.org/rdf/chrome#">
+ <RDF:Seq about="urn:mozilla:locale:root">
+ <RDF:li resource="urn:mozilla:locale:fa"/>
+ </RDF:Seq>
+ <RDF:Description about="urn:mozilla:locale:fa" chrome:name="fa" >
+ <chrome:packages>
+ <RDF:Seq about="urn:mozilla:locale:fa:packages">
+ <RDF:li resource="urn:mozilla:locale:fa:bandwagon"/>
+ </RDF:Seq>
+ </chrome:packages>
+ </RDF:Description>
+</RDF:RDF>
+
diff --git a/bandwagon/locale/fa/extensionOverlay.properties b/bandwagon/locale/fa/extensionOverlay.properties
new file mode 100644
index 0000000..46ef688
--- /dev/null
+++ b/bandwagon/locale/fa/extensionOverlay.properties
@@ -0,0 +1,14 @@
+publish.new.email.address.title=نشانی پست الکترونیکی جدید
+publish.new.email.address.text=نشانی پست الکترونیکی شخصی را Ú©Ù‡ مایل به اشتراک گذاشتن این اÙزودنی با او هستید وارد کنید:
+publish.remove.title=تأیید
+# LOCALIZATION NOTE (publish.remove.label):
+# %1 is the name of an add-on. %2 is the name of a collection
+publish.remove.label=آیا از حذ٠%1$S از مجموعهٔ «%2$S» اطمینان دارید؟
+publish.remove.button1=خیر، انصراÙ
+publish.remove.button0=بله، اÙزودنی حذ٠شود
+login.error=اشکال هنگام ورود پیش آمد. لطÙاً اطمینان حاصل کنید Ú©Ù‡ نام کاربری Ùˆ گذرواژه‌تان درست وارد شده باشند.
+unsubscribe.error=در قطع این آبونمان اشکالی به وجود آمد. لطÙاً بعداً دوباره تلاش کنید.
+unsubscribe.confirm.title=تأیید قطع اشتراک
+unsubscribe.confirm.label=قطع این اشتراک آن را از Ùهرست اÙزودنی‌های محبوبتان نیز حذ٠خواهد کرد. آیا از قطع اشتراک اطمینان دارید؟
+unsubscribe.confirm.button1=خیر، انصراÙ
+unsubscribe.confirm.button0=بله، اشتراک قطع شود
diff --git a/bandwagon/locale/fa/extensionsOverlay.dtd b/bandwagon/locale/fa/extensionsOverlay.dtd
new file mode 100644
index 0000000..feb54b6
--- /dev/null
+++ b/bandwagon/locale/fa/extensionsOverlay.dtd
@@ -0,0 +1,69 @@
+<!-- ***** BEGIN LICENSE BLOCK *****
+ - Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ -
+ - The contents of this file are subject to the Mozilla Public License Version
+ - 1.1 (the "License"); you may not use this file except in compliance with
+ - the License. You may obtain a copy of the License at
+ - http://www.mozilla.org/MPL/
+ -
+ - Software distributed under the License is distributed on an "AS IS" basis,
+ - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ - for the specific language governing rights and limitations under the
+ - License.
+ -
+ - The Original Code is bandwagon.
+ -
+ - The Initial Developer of the Original Code is
+ - Mozilla Corporation.
+ - Portions created by the Initial Developer are Copyright (C) 2008
+ - the Initial Developer. All Rights Reserved.
+ -
+ - Contributor(s): Brian King <brian (at) briks (dot) si>
+ - David McNamara
+ -
+ - Alternatively, the contents of this file may be used under the terms of
+ - either the GNU General Public License Version 2 or later (the "GPL"), or
+ - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ - in which case the provisions of the GPL or the LGPL are applicable instead
+ - of those above. If you wish to allow use of your version of this file only
+ - under the terms of either the GPL or the LGPL, and not to allow others to
+ - use your version of this file under the terms of the MPL, indicate your
+ - decision by deleting the provisions above and replace them with the notice
+ - and other provisions required by the GPL or the LGPL. If you do not delete
+ - the provisions above, a recipient may use your version of this file under
+ - the terms of any one of the MPL, the GPL or the LGPL.
+ -
+ - ***** END LICENSE BLOCK ***** -->
+
+<!ENTITY collections.label "آبونمان‌ها">
+<!ENTITY search.label.bandwagon "جست‌وجو">
+
+<!ENTITY addon.moreinfo "اطلاعات بیشتر.">
+<!ENTITY addon.addtofirefox "اÙزودن به ÙایرÙاکس">
+<!ENTITY subscribe.label "پیدا کردن مجموعه‌ها">
+<!ENTITY reload.label "بازآوردن همه">
+<!ENTITY settings.label "تنظیمات">
+
+<!ENTITY view.label "مشاهدهٔ مجموعه">
+<!ENTITY unsubscribe.label "قطع آبونمان">
+
+<!ENTITY nocollectionstitle.label "به مجموعه‌ساز اÙزودنی‌ها خوش آمدید">
+<!ENTITY nocollectionssubscribed.label "مجموعه‌های محبوب شما در وب‌سایت اÙزودنی‌های موزیلا در اینجا نمایش داده می‌شوند تا بتوانید به سادگی آنها را زیر نظر داشته باشید. به نظر می‌رسد Ú©Ù‡ تاکنون مجموعهٔ محبوبی انتخاب نکرده‌اید، پس پیشنهاد می‌کنیم نگاهی به Ùهرست مجموعه‌های ما بیاندازید.">
+<!ENTITY clicktosubscribe.label "پیدا کردن مجموعه‌ها">
+
+<!ENTITY noamoauth.label "مجموعه‌های محبوب شما در وب‌سایت اÙزودنی‌های موزیلا در اینجا نمایش داده می‌شوند تا بتوانید به سادگی آنها را زیر نظر داشته باشید. برای استÙاده از این قسمت باید وارد addons.mozilla.org شده باشید.">
+<!ENTITY username.label "نام کاربر">
+<!ENTITY password.label "گذرواژه">
+<!ENTITY clicktologin.label "ورود">
+
+<!ENTITY collectionisloading.label "در حال دریاÙت آبونمان‌ها…">
+<!ENTITY collectionhasnoitems.label "این مجموعه خالی است.">
+<!ENTITY collectionhaserror.label "این مجموعه قابل نمایش نیست، چون در آن اشتباهاتی وجود دارد.">
+
+<!ENTITY publishto.label "منتشر کردن در">
+<!ENTITY email.address.label "نشانی پست الکترونیکی">
+<!ENTITY new.email.address.label "نشانی پست الکترونیکی جدید">
+<!ENTITY new.collection.label "مجموعهٔ جدید">
+
+<!ENTITY createaccount.label "حساب کاربری ندارم">
+<!ENTITY loginheading.label "اطلاعات حساب کاربری وب‌گاه اÙزودنی‌های موزیلا را وارد نمایید:">
diff --git a/bandwagon/locale/fa/publish.dtd b/bandwagon/locale/fa/publish.dtd
new file mode 100644
index 0000000..e9225e0
--- /dev/null
+++ b/bandwagon/locale/fa/publish.dtd
@@ -0,0 +1,48 @@
+<!-- ***** BEGIN LICENSE BLOCK *****
+ - Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ -
+ - The contents of this file are subject to the Mozilla Public License Version
+ - 1.1 (the "License"); you may not use this file except in compliance with
+ - the License. You may obtain a copy of the License at
+ - http://www.mozilla.org/MPL/
+ -
+ - Software distributed under the License is distributed on an "AS IS" basis,
+ - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ - for the specific language governing rights and limitations under the
+ - License.
+ -
+ - The Original Code is bandwagon.
+ -
+ - The Initial Developer of the Original Code is
+ - Mozilla Corporation.
+ - Portions created by the Initial Developer are Copyright (C) 2008
+ - the Initial Developer. All Rights Reserved.
+ -
+ - Contributor(s): David McNamara
+ - Brian King <brian (at) briks (dot) si>
+ -
+ - Alternatively, the contents of this file may be used under the terms of
+ - either the GNU General Public License Version 2 or later (the "GPL"), or
+ - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ - in which case the provisions of the GPL or the LGPL are applicable instead
+ - of those above. If you wish to allow use of your version of this file only
+ - under the terms of either the GPL or the LGPL, and not to allow others to
+ - use your version of this file under the terms of the MPL, indicate your
+ - decision by deleting the provisions above and replace them with the notice
+ - and other provisions required by the GPL or the LGPL. If you do not delete
+ - the provisions above, a recipient may use your version of this file under
+ - the terms of any one of the MPL, the GPL or the LGPL.
+ -
+ - ***** END LICENSE BLOCK ***** -->
+
+<!-- For localisers to change the width of the window -->
+<!ENTITY publish.style "width: 35em;">
+
+<!ENTITY window.title "انتشار">
+<!ENTITY cancel.label "انصراÙ">
+<!ENTITY publish.label "انتشار">
+<!ENTITY new.email.label "نشانی پست الکترونیکی جدید">
+<!ENTITY enter.an.email.label "یک یا چند نشانی پست الکترونیکی وارد کنید و آنها را با ویرگول از هم جدا سازید:">
+<!ENTITY remember.this.email.label "نشانی پست الکترونیکی به خاطر سپرده شود">
+<!ENTITY enter.a.personal.note.label "اختیاری: یادداشتی شخصی دربارهٔ این اÙزودنی وارد کنید تا در نامه قرار گیرد">
+
diff --git a/bandwagon/locale/fa/publish.properties b/bandwagon/locale/fa/publish.properties
new file mode 100644
index 0000000..f215759
--- /dev/null
+++ b/bandwagon/locale/fa/publish.properties
@@ -0,0 +1,20 @@
+# LOCALIZATION NOTE (you.are.sharing.the.add.on):
+# %S is the name of an add-on
+you.are.sharing.the.add.on=شما اÙزودنی «%S» را به اشتراک گذاشته‌اید
+# LOCALIZATION NOTE (publishing.to):
+# %1 is the name of an add-on. %2 is the name of a collection
+publishing.to=کلیک کردن دکمهٔ «منتشر کردن» %1$S را به مجموعهٔ «%2$S» اضاÙÙ‡ خواهد کرد.
+# LOCALIZATION NOTE (sharing.with):
+# %1 is a user's email address. $2 is the name of an add-on
+sharing.with=کلیک کردن دکمهٔ «ارسال نامهٔ الکترونیکی» نامه‌ای حاوی اطلاعات %2$S به %1$S ارسال خواهد کرد
+# LOCALIZATION NOTE (sharing.with.new):
+# %S is the name of an add-on
+sharing.with.new=کلیک کردن دکمهٔ «ارسال نامهٔ الکترونیکی» نامه‌ای حاوی اطلاعات %2$S به اÙراد Ùوق ارسال خواهد کرد
+please.enter.an.email.address=لطÙاً یک نشانی پست الکترونیکی وارد کنید.
+the.addon.has.been.published=اÙزودنی منتشر گردید.
+the.email.has.been.sent=نامهٔ الکترونیکی Ùرستاده شد.
+# LOCALIZATION NOTE (closing.in):
+# %S is the number of seconds until a window closes, counting down
+closing.in=پس از %S ثانیه بسته خواهد شد…
+send.email=ارسال نامهٔ الکترونیکی
+error.unknown_addon_guid=قادر به اشتراک گذاشتن این اÙزودنی نیست زیرا این اÙزودنی در وب‌گاه اÙزودنی‌های موزیلا میزبانی نمی‌شود.
diff --git a/bandwagon/locale/fa/settings.dtd b/bandwagon/locale/fa/settings.dtd
new file mode 100644
index 0000000..8c6dce6
--- /dev/null
+++ b/bandwagon/locale/fa/settings.dtd
@@ -0,0 +1,108 @@
+<!-- ***** BEGIN LICENSE BLOCK *****
+ - Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ -
+ - The contents of this file are subject to the Mozilla Public License Version
+ - 1.1 (the "License"); you may not use this file except in compliance with
+ - the License. You may obtain a copy of the License at
+ - http://www.mozilla.org/MPL/
+ -
+ - Software distributed under the License is distributed on an "AS IS" basis,
+ - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ - for the specific language governing rights and limitations under the
+ - License.
+ -
+ - The Original Code is bandwagon.
+ -
+ - The Initial Developer of the Original Code is
+ - Mozilla Corporation.
+ - Portions created by the Initial Developer are Copyright (C) 2008
+ - the Initial Developer. All Rights Reserved.
+ -
+ - Contributor(s): Brian King <brian (at) briks (dot) si>
+ - David McNamara
+ -
+ - Alternatively, the contents of this file may be used under the terms of
+ - either the GNU General Public License Version 2 or later (the "GPL"), or
+ - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ - in which case the provisions of the GPL or the LGPL are applicable instead
+ - of those above. If you wish to allow use of your version of this file only
+ - under the terms of either the GPL or the LGPL, and not to allow others to
+ - use your version of this file under the terms of the MPL, indicate your
+ - decision by deleting the provisions above and replace them with the notice
+ - and other provisions required by the GPL or the LGPL. If you do not delete
+ - the provisions above, a recipient may use your version of this file under
+ - the terms of any one of the MPL, the GPL or the LGPL.
+ -
+ - ***** END LICENSE BLOCK ***** -->
+
+<!-- For localisers to change the width of the window -->
+<!ENTITY settings.style "width: 42em;">
+
+<!ENTITY window.title "تنظیمات مجموعه‌سازی از اÙزودنی‌ها">
+
+<!-- Tabs -->
+<!ENTITY manage.label "مدیریت آبونمان‌ها">
+<!ENTITY general.label "تنظیمات عمومی">
+<!ENTITY pub.label "تنظیمات منتشر شوندهٔ خودکار">
+
+<!-- Manage Subscriptions -->
+<!ENTITY subscriptions.header "آبونمان‌ها:">
+
+<!-- Groupbox captions in Manage Subscriptions -->
+<!ENTITY frequency.label "زمان به‌هنگام‌سازی آبونمان‌ها">
+<!ENTITY notifications.label "تذکر در مورد اÙزودنی‌های جدید">
+<!ENTITY perpage.label "اÙزودنی در هر صÙحه">
+
+<!ENTITY default.label "استÙاده از تنظیم پیش‌Ùرض">
+<!ENTITY custom.label "سÙارشی:">
+
+<!ENTITY addonsleadin.label "نمایش">
+<!ENTITY addonsperpage.label "اÙزودنی در هر صÙحه">
+<!ENTITY updatesingle.label "به‌هنگام‌سازی هر">
+<!ENTITY minutes.label "دقیقه یک بار">
+<!ENTITY hours.label "ساعت یک بار">
+<!ENTITY days.label "روز یک بار">
+<!ENTITY autopublish.label "اÙزودنی‌های نصب شده به صورت خودکار در آبونمان منتشر شوند">
+<!ENTITY notify.label "نمایش تذکرها">
+<!ENTITY applyall.label "اعمال در تمام آبونمان‌ها">
+<!ENTITY remove.label "حذ٠آبونمان">
+<!ENTITY on.label "روشن">
+<!ENTITY off.label "خاموش">
+
+<!-- General -->
+
+<!-- Groupbox captions in General -->
+<!ENTITY subscriptions.label "تنظیمات پیش‌Ùرض آبونمان‌ها">
+<!ENTITY data.label "مدیریت داده‌ها">
+
+<!ENTITY updateall.label "گشتن به دنبال به‌هنگام‌سازی‌های آبونمان‌ها هر">
+<!ENTITY notifyglobal.label "هنگامی Ú©Ù‡ آبونمان‌های من اÙزودنی‌های جدیدی دارند به من تذکر داده شود">
+
+<!ENTITY clearemails.label "پاک کردن">
+<!ENTITY login.label "ورود">
+<!ENTITY logout.label "خروج">
+
+<!-- Auto-Publisher Settings -->
+
+<!-- Groupbox captions in Auto-Publisher Settings -->
+<!ENTITY auto.label "تنظیمات منتشر شوندهٔ خودکار">
+
+<!ENTITY name.label "نام مجموعه:">
+<!ENTITY list.label "موجود در Ùهرست عمومی مجموعه‌ها">
+
+<!ENTITY autoleadin.label "Ùهرست‌های منتشر شوندهٔ خودکار مجموعه‌های خاصی هستند Ú©Ù‡ هنگامی Ú©Ù‡ روی این رایانه در ÙایرÙاکس اÙزودنی نصب یا عزل می‌کنید به صورت خودکار به‌هنگام می‌شوند.">
+<!ENTITY types.label "انواع اÙزودنی منتشر شونده به صورت خودکار:">
+<!ENTITY type.extensions.label "ضمیمه‌ها">
+<!ENTITY type.themes.label "تم‌ها">
+<!ENTITY type.dicts.label "واژه‌نامه‌ها">
+<!ENTITY type.langpacks.label "بسته‌های زبان">
+
+<!ENTITY createauto.label "ایجاد منتشرکنندهٔ خودکار">
+<!ENTITY deleteauto.label "حذ٠منتشر شوندهٔ خودکار">
+<!ENTITY updateauto.label "به‌هنگام‌سازی منتشر شوندهٔ خودکار">
+
+<!ENTITY onlypublishenabledaddons.label "تنها اÙزودنی‌های Ùعال منتشر شوند">
+
+<!ENTITY misc.label "متÙرقه">
+<!ENTITY allowincompatibleinstall.label "اÙزودنی‌های ناسازگار از آبونمان‌های من نصب شوند">
+
diff --git a/bandwagon/locale/fa/settings.properties b/bandwagon/locale/fa/settings.properties
new file mode 100644
index 0000000..672fae1
--- /dev/null
+++ b/bandwagon/locale/fa/settings.properties
@@ -0,0 +1,26 @@
+add.collection=آبونه شدن
+enter.url.to.add.collection=نشانی آبونمان موزد نظر خود را وارد کنید.
+remove.collection=حذ٠آبونمان
+# LOCALIZATION NOTE (are.you.sure.you.want.to.remove):
+# %S is the name of a collection
+are.you.sure.you.want.to.remove=قطع این آبونمان مجموعهٔ مربوطه را از Ùهرست مجموعه‌های محبوب‌تان نیز حذ٠خواهد نمود. آیا از حذ٠«%S» اطمینان دارید؟
+# LOCALIZATION NOTE (saved.emails.text):
+# %S is a number
+saved.emails.text=شما %S نشانی پست الکترونیکی ذخیره شده دارید
+# LOCALIZATION NOTE (login.status.with.email):
+# %S is a user's email address
+login.status.with.email=شما به عنوان %S وارد شده‌اید
+login.status=شما وارد شده‌اید
+logout.status=شما وارد نشده‌اید
+# LOCALIZATION NOTE (auto.invalid.name):
+# %S is the name of a collection
+auto.invalid.name=نام مجموعهٔ «%S» معتبر نیست.
+auto.please.select.type=لطÙاً حداقل یک نوع اÙزودنی را برای منتشر شدن خودکار انتخاب نمایید.
+auto.create.internal.error=ایجاد مجموعه ممکن نیست (یک خطای داخلی اتÙاق اÙتاده است).
+auto.create.done=مجموعهٔ منتشر شونده‌تان ایجاد شده است.
+auto.delete.internal.error=حذ٠مجموعه ممکن نبود (خطایی داخلی اتÙاق اÙتاده است).
+auto.delete.done=مجموعهٔ منتشر شوندهٔ خودکارتان حذ٠شده است.
+auto.create.description=Ùهرستی از اÙزودنی‌های نصب شدهٔ من
+auto.update.confirm.message=تنظیمات جدید شما بلاÙاصله اعمال می‌شوند، ولی اثری بر اÙزودنی‌هایی Ú©Ù‡ قبلاً منتشر شده‌اند نخواهند داشت.
+auto.update.internal.error=قادر به به‌هنگام‌سازی مجموعه نبود (خطایی داخلی اتÙاق اÙتاده است).
+auto.update.done=مجموعهٔ منتشر شوندهٔ خودکارتان به‌هنگام گردید.
diff --git a/bandwagon/locale/fr/bandwagon.properties b/bandwagon/locale/fr/bandwagon.properties
new file mode 100644
index 0000000..4319125
--- /dev/null
+++ b/bandwagon/locale/fr/bandwagon.properties
@@ -0,0 +1,2 @@
+modules.sharing@addons.mozilla.org.description=Découvrez et partagez des modules.
+modules.sharing@addons.mozilla.org.name=Add-on Collector
diff --git a/bandwagon/locale/fr/bandwagonAddon.properties b/bandwagon/locale/fr/bandwagonAddon.properties
new file mode 100644
index 0000000..7199e1d
--- /dev/null
+++ b/bandwagon/locale/fr/bandwagonAddon.properties
@@ -0,0 +1,56 @@
+# LOCALIZATION NOTE (bandwagon.addon.pluralRule):
+
+# See https://developer.mozilla.org/En/Localization_and_Plurals
+
+bandwagon.addon.pluralRule=2
+bandwagon.category1=module
+# LOCALIZATION NOTE (bandwagon.addon.author):
+
+# %S will contain author's first and last name, or their nickname used on AMO
+
+bandwagon.addon.author=Par %S
+# LOCALIZATION NOTE (bandwagon.addon.addedby):
+
+# %S will be a user's first and last name, or nickname
+
+bandwagon.addon.addedby=par %S
+bandwagon.addon.added.justnow=Ajouté : à l'instant
+# LOCALIZATION NOTE:
+
+# %S will be a number of time units indicated
+
+bandwagon.addon.added.minute=Ajouté : il y a une minute;Ajouté : il y a %S minutes
+bandwagon.addon.added.hour=Ajouté : il y a une heure;Ajouté : il y a %S heures
+bandwagon.addon.added.day=Ajouté : hier;Ajouté : il y a %S jours
+bandwagon.addon.added.week=Ajouté : il y a une semaine;Ajouté : il y a %S semaines
+bandwagon.addon.added.month=Ajouté : il y a un mois;Ajouté : il y a %S mois
+bandwagon.addon.added.year=Ajouté : il y a un an;Ajouté : il y a %S ans
+bandwagon.addon.moreinfo=En savoir plus.
+bandwagon.addon.olderversionsoffirefox=Ce module est compatible avec des versions antérieures de Firefox.
+# LOCALIZATION NOTE (upgradetofirefoxn1):
+
+# %S will be a Firefox version number
+
+bandwagon.addon.upgradetofirefoxn1=Mettez à jour vers Firefox %S
+bandwagon.addon.upgradetofirefoxn2=pour utiliser ce module.
+# LOCALIZATION NOTE (bandwagon.addon.requiresfirefoxbeta1/requiresfirefoxbeta2):
+
+# %S will be a Firefox version number
+
+bandwagon.addon.requiresfirefoxbeta1=Ce module nécessite Firefox %S, qui n'a pas encore été publié. Pour utiliser ce module, vous pouvez
+bandwagon.addon.requiresfirefoxbeta2=télécharger Firefox %S beta.
+# LOCALIZATION NOTE (bandwagon.addon.notcompatible):
+
+# %S will be a platform name, such as "Windows"
+
+bandwagon.addon.notcompatible=Ce module n'est pas compatible avec %S.
+# LOCALIZATION NOTE (bandwagon.addon.comment.description):
+
+# %S will be a comment entered by the publisher of the add-on
+
+bandwagon.addon.comment.description=« %S »
+# LOCALIZATION NOTE (bandwagon.addon.comment.author):
+
+# %S will be the publisher's real name or nickname
+
+bandwagon.addon.comment.author=Commentaires de %S :
diff --git a/bandwagon/locale/fr/browserOverlay.dtd b/bandwagon/locale/fr/browserOverlay.dtd
new file mode 100644
index 0000000..d083cb6
--- /dev/null
+++ b/bandwagon/locale/fr/browserOverlay.dtd
@@ -0,0 +1,3 @@
+<!-- ***** BEGIN LICENSE BLOCK ***** - Version: MPL 1.1/GPL 2.0/LGPL 2.1 - - The contents of this file are subject to the Mozilla Public License Version - 1.1 (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - http://www.mozilla.org/MPL/ - - Software distributed under the License is distributed on an "AS IS" basis, - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - for the specific language governing rights and limitations under the - License. - - The Original Code is bandwagon. - - The Initial Developer of the Original Code is - Mozilla Corporation. - Portions created by the Initial Developer are Copyright (C) 2008 - the Initial Developer. All Rights Reserved. - - Contributor(s): Brian King <brian (at) briks (dot) si> - - Alternatively, the contents of this file may be used under the terms of - either the GNU General Public License Version 2 or later (the "GPL"), or - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - in which case the provisions of the GPL or the LGPL are applicable instead - of those above. If you wish to allow use of your version of this file only - under the terms of either the GPL or the LGPL, and not to allow others to - use your version of this file under the terms of the MPL, indicate your - decision by deleting the provisions above and replace them with the notice - and other provisions required by the GPL or the LGPL. If you do not delete - the provisions above, a recipient may use your version of this file under - the terms of any one of the MPL, the GPL or the LGPL. - - ***** END LICENSE BLOCK ***** -->
+<!ENTITY bandwagon.label "Modules">
+<!ENTITY bandwagon.tooltip "Modules complémentaires">
diff --git a/bandwagon/locale/fr/browserOverlay.properties b/bandwagon/locale/fr/browserOverlay.properties
new file mode 100644
index 0000000..406c4c4
--- /dev/null
+++ b/bandwagon/locale/fr/browserOverlay.properties
@@ -0,0 +1,6 @@
+newaddons.alert.title=New Add-ons
+# LOCALIZATION NOTE (newaddons.alert.text):
+
+# %S will be the name of a collection
+
+newaddons.alert.text=De nouveaux modules sont disponibles pour votre collection « %S ».
diff --git a/bandwagon/locale/fr/extensionOverlay.properties b/bandwagon/locale/fr/extensionOverlay.properties
new file mode 100644
index 0000000..7b43b44
--- /dev/null
+++ b/bandwagon/locale/fr/extensionOverlay.properties
@@ -0,0 +1,16 @@
+publish.new.email.address.title=Nouvelle adresse électronique
+publish.new.email.address.text=Saisissez une nouvelle adresse électronique pour partager ce module avec :
+publish.remove.title=Confirmation
+# LOCALIZATION NOTE (publish.remove.label):
+
+# %1 is the name of an add-on. %2 is the name of a collection
+
+publish.remove.label=Voulez-vous vraiment supprimer %1$S de la collection « %2$S » ?
+publish.remove.button1=Non, annuler
+publish.remove.button0=Oui, supprimer ce module
+login.error=Une erreur s'est produite lors de la connexion. Veuillez vérifier que votre nom d'utilisateur et votre mot de passe sont valides.
+unsubscribe.error=Une erreur s'est produite lors de votre désabonnement à cette collection. Veuillez réessayer plus tard.
+unsubscribe.confirm.title=Confirmation de désabonnement
+unsubscribe.confirm.label=Vous désabonner de cette collection la supprimera également de votre liste de favoris. Voulez-vous vraiment vous désabonner ?
+unsubscribe.confirm.button1=Non, annuler
+unsubscribe.confirm.button0=Oui, me désabonner
diff --git a/bandwagon/locale/fr/extensionsOverlay.dtd b/bandwagon/locale/fr/extensionsOverlay.dtd
new file mode 100644
index 0000000..e847ada
--- /dev/null
+++ b/bandwagon/locale/fr/extensionsOverlay.dtd
@@ -0,0 +1,26 @@
+<!-- ***** BEGIN LICENSE BLOCK ***** - Version: MPL 1.1/GPL 2.0/LGPL 2.1 - - The contents of this file are subject to the Mozilla Public License Version - 1.1 (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - http://www.mozilla.org/MPL/ - - Software distributed under the License is distributed on an "AS IS" basis, - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - for the specific language governing rights and limitations under the - License. - - The Original Code is bandwagon. - - The Initial Developer of the Original Code is - Mozilla Corporation. - Portions created by the Initial Developer are Copyright (C) 2008 - the Initial Developer. All Rights Reserved. - - Contributor(s): Brian King <brian (at) briks (dot) si> - David McNamara - - Alternatively, the contents of this file may be used under the terms of - either the GNU General Public License Version 2 or later (the "GPL"), or - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - in which case the provisions of the GPL or the LGPL are applicable instead - of those above. If you wish to allow use of your version of this file only - under the terms of either the GPL or the LGPL, and not to allow others to - use your version of this file under the terms of the MPL, indicate your - decision by deleting the provisions above and replace them with the notice - and other provisions required by the GPL or the LGPL. If you do not delete - the provisions above, a recipient may use your version of this file under - the terms of any one of the MPL, the GPL or the LGPL. - - ***** END LICENSE BLOCK ***** -->
+<!ENTITY collections.label "Abonnements">
+<!ENTITY search.label.bandwagon "Rechercher">
+<!ENTITY addon.moreinfo "En savoir plus.">
+<!ENTITY addon.addtofirefox "Ajouter à Firefox">
+<!ENTITY subscribe.label "Chercher dans les collections">
+<!ENTITY reload.label "Tout recharger">
+<!ENTITY settings.label "Paramètres">
+<!ENTITY view.label "Afficher la collection">
+<!ENTITY unsubscribe.label "Se désabonner">
+<!ENTITY nocollectionstitle.label "Bienvenue dans l'extension Add-on Collector">
+<!ENTITY nocollectionssubscribed.label "C'est ici qu'apparaîtront les collections que vous choisirez comme vos favorites parmi les modules Mozilla, vous pourrez ainsi facilement en garder la trace. Apparemment, vous n'avez pas encore ajouté de modules favoris, pourquoi ne jetteriez-vous pas un coup d'oeil à notre répertoire de collections ?">
+<!ENTITY clicktosubscribe.label "Chercher dans les collections">
+<!ENTITY noamoauth.label "C'est ici qu'apparaîtront les collections que vous choisirez comme vos favorites parmi les modules Mozilla, vous pourrez ainsi facilement en garder la trace. Pour utiliser cette fonction, une connexion à addons.mozilla.org est nécessaire.">
+<!ENTITY username.label "Nom d'utilisateur">
+<!ENTITY password.label "Mot de passe">
+<!ENTITY clicktologin.label "Connexion">
+<!ENTITY createaccount.label "Je n'ai pas encore de compte">
+<!ENTITY loginheading.label "Saisissez ci-dessous les identifiants de votre compte pour les modules Mozilla :">
+<!ENTITY collectionisloading.label "Recherche des abonnements en cours…">
+<!ENTITY collectionhasnoitems.label "Cette collection ne contient aucune module.">
+<!ENTITY collectionhaserror.label "Cette collection ne peut être affichée parce qu'elle contient des erreurs.">
+<!ENTITY publishto.label "Publier vers">
+<!ENTITY email.address.label "Adresse électronique">
+<!ENTITY new.email.address.label "Nouvelle adresse électronique">
+<!ENTITY new.collection.label "Nouvelle collection">
diff --git a/bandwagon/locale/fr/publish.dtd b/bandwagon/locale/fr/publish.dtd
new file mode 100644
index 0000000..6557915
--- /dev/null
+++ b/bandwagon/locale/fr/publish.dtd
@@ -0,0 +1,46 @@
+<!-- ***** BEGIN LICENSE BLOCK *****
+ - Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ -
+ - The contents of this file are subject to the Mozilla Public License Version
+ - 1.1 (the "License"); you may not use this file except in compliance with
+ - the License. You may obtain a copy of the License at
+ - http://www.mozilla.org/MPL/
+ -
+ - Software distributed under the License is distributed on an "AS IS" basis,
+ - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ - for the specific language governing rights and limitations under the
+ - License.
+ -
+ - The Original Code is bandwagon.
+ -
+ - The Initial Developer of the Original Code is
+ - Mozilla Corporation.
+ - Portions created by the Initial Developer are Copyright (C) 2008
+ - the Initial Developer. All Rights Reserved.
+ -
+ - Contributor(s): David McNamara
+ - Brian King <brian (at) briks (dot) si>
+ -
+ - Alternatively, the contents of this file may be used under the terms of
+ - either the GNU General Public License Version 2 or later (the "GPL"), or
+ - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ - in which case the provisions of the GPL or the LGPL are applicable instead
+ - of those above. If you wish to allow use of your version of this file only
+ - under the terms of either the GPL or the LGPL, and not to allow others to
+ - use your version of this file under the terms of the MPL, indicate your
+ - decision by deleting the provisions above and replace them with the notice
+ - and other provisions required by the GPL or the LGPL. If you do not delete
+ - the provisions above, a recipient may use your version of this file under
+ - the terms of any one of the MPL, the GPL or the LGPL.
+ -
+ - ***** END LICENSE BLOCK *****
+ -->
+<!-- For localisers to change the width of the window -->
+<!ENTITY publish.style "width: 35em;">
+<!ENTITY window.title "Publier">
+<!ENTITY cancel.label "Annuler">
+<!ENTITY publish.label "Publier">
+<!ENTITY new.email.label "Nouvelle adresse électronique">
+<!ENTITY enter.an.email.label "Saisissez une ou plusieurs adresses électroniques en les séparant par des virgules :">
+<!ENTITY remember.this.email.label "Se souvenir de cette adresse électronique">
+<!ENTITY enter.a.personal.note.label "Facultatif : ajoutez à propos de ce module un message personnel qui sera inclus dans votre courrier électronique">
diff --git a/bandwagon/locale/fr/publish.properties b/bandwagon/locale/fr/publish.properties
new file mode 100644
index 0000000..7e5137a
--- /dev/null
+++ b/bandwagon/locale/fr/publish.properties
@@ -0,0 +1,30 @@
+# LOCALIZATION NOTE (you.are.sharing.the.add.on):
+
+# %S is the name of an add-on
+
+you.are.sharing.the.add.on=Vous partagez le module '%S'
+# LOCALIZATION NOTE (publishing.to):
+
+# %1 is the name of an add-on. %2 is the name of a collection
+
+publishing.to=Cliquer sur « Publier » ajoutera %1$S à la collection « %2$S ».
+# LOCALIZATION NOTE (sharing.with):
+
+# %1 is a user's email address. $2 is the name of an add-on
+
+sharing.with=Cliquer sur « Envoyer un courrier électronique » enverra à %1$S un courrier comprenant des informations sur %2$S
+# LOCALIZATION NOTE (sharing.with.new):
+
+# %S is the name of an add-on
+
+sharing.with.new=Cliquer sur « Envoyer un courrier électronique » enverra aux destinataires ci-dessus un courrier comprenant des informations sur %S
+please.enter.an.email.address=Veuillez saisir une adresse électronique.
+the.addon.has.been.published=Ce module a été publié.
+the.email.has.been.sent=Le courrier électronique a été envoyé.
+# LOCALIZATION NOTE (closing.in):
+
+# %S is the number of seconds until a window closes, counting down
+
+closing.in=Fermeture dans %S…
+send.email=Envoyer un courrier électronique
+error.unknown_addon_guid=Ce module ne peut pas être partagé parce qu'il n'est pas hébergé sur le site des modules de Mozilla.
diff --git a/bandwagon/locale/fr/settings.dtd b/bandwagon/locale/fr/settings.dtd
new file mode 100644
index 0000000..2fe7731
--- /dev/null
+++ b/bandwagon/locale/fr/settings.dtd
@@ -0,0 +1,54 @@
+<!-- ***** BEGIN LICENSE BLOCK ***** - Version: MPL 1.1/GPL 2.0/LGPL 2.1 - - The contents of this file are subject to the Mozilla Public License Version - 1.1 (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - http://www.mozilla.org/MPL/ - - Software distributed under the License is distributed on an "AS IS" basis, - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - for the specific language governing rights and limitations under the - License. - - The Original Code is bandwagon. - - The Initial Developer of the Original Code is - Mozilla Corporation. - Portions created by the Initial Developer are Copyright (C) 2008 - the Initial Developer. All Rights Reserved. - - Contributor(s): Brian King <brian (at) briks (dot) si> - David McNamara - - Alternatively, the contents of this file may be used under the terms of - either the GNU General Public License Version 2 or later (the "GPL"), or - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - in which case the provisions of the GPL or the LGPL are applicable instead - of those above. If you wish to allow use of your version of this file only - under the terms of either the GPL or the LGPL, and not to allow others to - use your version of this file under the terms of the MPL, indicate your - decision by deleting the provisions above and replace them with the notice - and other provisions required by the GPL or the LGPL. If you do not delete - the provisions above, a recipient may use your version of this file under - the terms of any one of the MPL, the GPL or the LGPL. - - ***** END LICENSE BLOCK ***** -->
+<!-- For localisers to change the width of the window -->
+<!ENTITY settings.style "width: 42em;">
+<!ENTITY window.title "Paramètres de l'extension Add-on Collector">
+<!-- Tabs -->
+<!ENTITY manage.label "Gestion des abonnements">
+<!ENTITY general.label "Paramètres généraux">
+<!ENTITY pub.label "Paramètres de publication automatique">
+<!-- Manage Subscriptions -->
+<!ENTITY subscriptions.header "Abonnements :">
+<!-- Groupbox captions in Manage Subscriptions -->
+<!ENTITY frequency.label "Fréquence des mises à jour d'abonnements">
+<!ENTITY notifications.label "Notifications pour les nouveaux modules">
+<!ENTITY perpage.label "modules par page">
+<!ENTITY default.label "Utiliser le paramètre par défaut">
+<!ENTITY custom.label "Personnaliser :">
+<!ENTITY addonsleadin.label "Afficher">
+<!ENTITY addonsperpage.label "modules par page">
+<!ENTITY updatesingle.label "Mise à jour au bout de :">
+<!ENTITY minutes.label "minute(s)">
+<!ENTITY hours.label "heure(s)">
+<!ENTITY days.label "jour(s)">
+<!ENTITY autopublish.label "Publier automatiquement les module installés dans l'abonnement">
+<!ENTITY notify.label "Afficher les notifications">
+<!ENTITY applyall.label "Appliquer à tous les abonnements">
+<!ENTITY remove.label "Supprimer l'abonnement">
+<!ENTITY on.label "Activé">
+<!ENTITY off.label "Désactivé">
+<!-- General -->
+<!-- Groupbox captions in General -->
+<!ENTITY subscriptions.label "Paramètres d'abonnement par défaut">
+<!ENTITY data.label "Gestion des données">
+<!ENTITY updateall.label "Vérifier les mises à jour d'abonnements au bout de ">
+<!ENTITY notifyglobal.label "Me signaler lorsque de nouveaux modules sont ajoutés à mes abonnements">
+<!ENTITY clearemails.label "Effacer">
+<!ENTITY login.label "Connexion">
+<!ENTITY logout.label "Déconnexion">
+<!-- Auto-Publisher Settings -->
+<!-- Groupbox captions in Auto-Publisher Settings -->
+<!ENTITY auto.label "Paramètres de publication automatique">
+<!ENTITY name.label "Nom de la collection :">
+<!ENTITY list.label "Répertoire des collections visibles par tous">
+<!ENTITY autoleadin.label "Les collections publiées automatiquement ont ceci de particulier qu'elles sont automatiquement mises à jour à chaque fois que vous installez ou désinstallez des modules pour Firefox sur votre ordinateur.">
+<!ENTITY types.label "Types de modules pour la publication automatique :">
+<!ENTITY type.extensions.label "Extensions">
+<!ENTITY type.themes.label "Thèmes">
+<!ENTITY type.dicts.label "Dictionnaires">
+<!ENTITY type.langpacks.label "Paquetages de langues">
+<!ENTITY createauto.label "Créer une collection à publier automatiquement">
+<!ENTITY deleteauto.label "Supprimer une collection à publier automatiquement">
+<!ENTITY updateauto.label "Mettre à jour une collection à publier automatiquement">
+<!ENTITY onlypublishenabledaddons.label "Ne publier que les modules activés">
+<!ENTITY misc.label "Divers">
+<!ENTITY allowincompatibleinstall.label "Autoriser l'installation de modules incompatibles dans mes abonnements">
diff --git a/bandwagon/locale/fr/settings.properties b/bandwagon/locale/fr/settings.properties
new file mode 100644
index 0000000..bcfc7c7
--- /dev/null
+++ b/bandwagon/locale/fr/settings.properties
@@ -0,0 +1,34 @@
+add.collection=Ajouter un abonnement
+enter.url.to.add.collection=Saisissez l'adresse URL de l'abonnement que vous désirez ajouter.
+remove.collection=Supprimer l'abonnement
+# LOCALIZATION NOTE (are.you.sure.you.want.to.remove):
+
+# %S is the name of a collection
+
+are.you.sure.you.want.to.remove=Supprimer cet abonnement supprimera également la collection de la liste de vos favorites. Voulez-vous vraiment supprimer « %S » ?
+# LOCALIZATION NOTE (saved.emails.text):
+
+# %S is a number
+
+saved.emails.text=Vous avez enregistré %S adresses électroniques
+# LOCALIZATION NOTE (login.status.with.email):
+
+# %S is a user's email address
+
+login.status.with.email=Vous disposez d'une connexion en tant que %S
+login.status=Vous disposez d'une connexion
+logout.status=Vous ne disposez pas d'une connexion
+# LOCALIZATION NOTE (auto.invalid.name):
+
+# %S is the name of a collection
+
+auto.invalid.name=« %S » n'est pas un nom de collection valide.
+auto.please.select.type=Veuillez sélectionner au moins un type de modules à publier automatiquement.
+auto.create.internal.error=La collection n'a pas pu être créée (une erreur interne s'est produite).
+auto.create.done=Votre collection destinée à la publication automatique a été créée.
+auto.delete.internal.error=La collection n'a pas pu être supprimée (une erreur interne s'est produite).
+auto.delete.done=Votre collection destinée à la publication automatique a été supprimée.
+auto.create.description=Une liste créée automatiquement de mes modules installés
+auto.update.confirm.message=Vos nouveaux paramètres prendront effet immédiatement, mais n'affecteront pas les modules qui ont déjà été publiés.
+auto.update.internal.error=La collection ne peut pas être mise à jour (une erreur interne s'est produite).
+auto.update.done=Votre collection destinée à la publication automatique a été mise à jour.
diff --git a/bandwagon/locale/fy-NL/bandwagon.properties b/bandwagon/locale/fy-NL/bandwagon.properties
new file mode 100644
index 0000000..4d38443
--- /dev/null
+++ b/bandwagon/locale/fy-NL/bandwagon.properties
@@ -0,0 +1,2 @@
+extensions.sharing@addons.mozilla.org.description=Diel en ûntdek tafoegings.
+extensions.sharing@addons.mozilla.org.name=Tafoegingssamler
diff --git a/bandwagon/locale/fy-NL/bandwagonAddon.properties b/bandwagon/locale/fy-NL/bandwagonAddon.properties
new file mode 100644
index 0000000..e53fbad
--- /dev/null
+++ b/bandwagon/locale/fy-NL/bandwagonAddon.properties
@@ -0,0 +1,56 @@
+# LOCALIZATION NOTE (bandwagon.addon.pluralRule):
+
+# See https://developer.mozilla.org/En/Localization_and_Plurals
+
+bandwagon.addon.pluralRule=1
+bandwagon.category1=Utwreiding
+# LOCALIZATION NOTE (bandwagon.addon.author):
+
+# %S will contain author's first and last name, or their nickname used on AMO
+
+bandwagon.addon.author=Troch %S
+# LOCALIZATION NOTE (bandwagon.addon.addedby):
+
+# %S will be a user's first and last name, or nickname
+
+bandwagon.addon.addedby=troch %S
+bandwagon.addon.added.justnow=Tafoege: Krekt
+# LOCALIZATION NOTE:
+
+# %S will be a number of time units indicated
+
+bandwagon.addon.added.minute=Tafoege: 1 minút lyn;Tafoege: %S minuten lyn
+bandwagon.addon.added.hour=Tafoege: 1 oere lyn;Tafoege: %S oeren lyn
+bandwagon.addon.added.day=Tafoege: Juster;Tafoege: %S dagen lyn
+bandwagon.addon.added.week=Tafoege: 1 wike lyn;Tafoege: %S wiken lyn
+bandwagon.addon.added.month=Tafoege: 1 moanne lyn;Tafoege: %S moannen lyn
+bandwagon.addon.added.year=Tafoege: 1 jier lyn;Tafoege: %S jierren lyn
+bandwagon.addon.moreinfo=Mear ynfo.
+bandwagon.addon.olderversionsoffirefox=Dizze tafoeging is foar âldere ferzjes fan Firefox.
+# LOCALIZATION NOTE (upgradetofirefoxn1):
+
+# %S will be a Firefox version number
+
+bandwagon.addon.upgradetofirefoxn1=Fernij nei Firefox %S
+bandwagon.addon.upgradetofirefoxn2=om dizze tafoeging te brûken.
+# LOCALIZATION NOTE (bandwagon.addon.requiresfirefoxbeta1/requiresfirefoxbeta2):
+
+# %S will be a Firefox version number
+
+bandwagon.addon.requiresfirefoxbeta1=Dizze tafoeging hat Firefox %S nedich, dy't noch net útjûn is. Om dizze tafoeging te brûken, meie jo
+bandwagon.addon.requiresfirefoxbeta2=Firefox %S beta ynlade.
+# LOCALIZATION NOTE (bandwagon.addon.notcompatible):
+
+# %S will be a platform name, such as "Windows"
+
+bandwagon.addon.notcompatible=Dizze tafoeging is net kompatibel mei %S.
+# LOCALIZATION NOTE (bandwagon.addon.comment.description):
+
+# %S will be a comment entered by the publisher of the add-on
+
+bandwagon.addon.comment.description=“%Sâ€
+# LOCALIZATION NOTE (bandwagon.addon.comment.author):
+
+# %S will be the publisher's real name or nickname
+
+bandwagon.addon.comment.author=Kommentaar fan %S:
diff --git a/bandwagon/locale/fy-NL/browserOverlay.dtd b/bandwagon/locale/fy-NL/browserOverlay.dtd
new file mode 100644
index 0000000..9f6f10b
--- /dev/null
+++ b/bandwagon/locale/fy-NL/browserOverlay.dtd
@@ -0,0 +1,3 @@
+<!-- ***** BEGIN LICENSE BLOCK ***** - Version: MPL 1.1/GPL 2.0/LGPL 2.1 - - The contents of this file are subject to the Mozilla Public License Version - 1.1 (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - http://www.mozilla.org/MPL/ - - Software distributed under the License is distributed on an "AS IS" basis, - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - for the specific language governing rights and limitations under the - License. - - The Original Code is bandwagon. - - The Initial Developer of the Original Code is - Mozilla Corporation. - Portions created by the Initial Developer are Copyright (C) 2008 - the Initial Developer. All Rights Reserved. - - Contributor(s): Brian King <brian (at) briks (dot) si> - - Alternatively, the contents of this file may be used under the terms of - either the GNU General Public License Version 2 or later (the "GPL"), or - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - in which case the provisions of the GPL or the LGPL are applicable instead - of those above. If you wish to allow use of your version of this file only - under the terms of either the GPL or the LGPL, and not to allow others to - use your version of this file under the terms of the MPL, indicate your - decision by deleting the provisions above and replace them with the notice - and other provisions required by the GPL or the LGPL. If you do not delete - the provisions above, a recipient may use your version of this file under - the terms of any one of the MPL, the GPL or the LGPL. - - ***** END LICENSE BLOCK ***** -->
+<!ENTITY bandwagon.label "Tafoegings">
+<!ENTITY bandwagon.tooltip "Tafoegings">
diff --git a/bandwagon/locale/fy-NL/browserOverlay.properties b/bandwagon/locale/fy-NL/browserOverlay.properties
new file mode 100644
index 0000000..5c8bd05
--- /dev/null
+++ b/bandwagon/locale/fy-NL/browserOverlay.properties
@@ -0,0 +1,6 @@
+newaddons.alert.title=Nije Tafoegings
+# LOCALIZATION NOTE (newaddons.alert.text):
+
+# %S will be the name of a collection
+
+newaddons.alert.text=Der binne nije tafoegings yn jo abonnemint "%S".
diff --git a/bandwagon/locale/fy-NL/contents.rdf b/bandwagon/locale/fy-NL/contents.rdf
new file mode 100644
index 0000000..c9675e2
--- /dev/null
+++ b/bandwagon/locale/fy-NL/contents.rdf
@@ -0,0 +1,15 @@
+<?xml version="1.0"?>
+<RDF:RDF xmlns:RDF="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:chrome="http://www.mozilla.org/rdf/chrome#">
+ <RDF:Seq about="urn:mozilla:locale:root">
+ <RDF:li resource="urn:mozilla:locale:fy-NL"/>
+ </RDF:Seq>
+ <RDF:Description about="urn:mozilla:locale:fy-NL" chrome:name="fy-NL" >
+ <chrome:packages>
+ <RDF:Seq about="urn:mozilla:locale:fy-NL:packages">
+ <RDF:li resource="urn:mozilla:locale:fy-NL:bandwagon"/>
+ </RDF:Seq>
+ </chrome:packages>
+ </RDF:Description>
+</RDF:RDF>
+
diff --git a/bandwagon/locale/fy-NL/extensionOverlay.properties b/bandwagon/locale/fy-NL/extensionOverlay.properties
new file mode 100644
index 0000000..ffc2fbb
--- /dev/null
+++ b/bandwagon/locale/fy-NL/extensionOverlay.properties
@@ -0,0 +1,16 @@
+publish.new.email.address.title=Nij e-mailadres
+publish.new.email.address.text=Jou in nij e-mailadres om dizze tafoeging mei te dielen:
+publish.remove.title=Befestiging
+# LOCALIZATION NOTE (publish.remove.label):
+
+# %1 is the name of an add-on. %2 is the name of a collection
+
+publish.remove.label=Binne jo wis dat jo %1$S fuortsmite wolle út de "%2$S" kolleksje?
+publish.remove.button1=Nee, annulearje
+publish.remove.button0=Ja, smyt de tafoeging fuort
+login.error=Der wie in flater mei it ynloggen. Kontrolearje asjobleaft oft jo brûkersnamme en wachtwurd goed binne.
+unsubscribe.error=Der wie in flater mei útskriuwen fan dizze kolleksje. Besykje it asjobleaft letter op 'e nij.
+unsubscribe.confirm.title=Befestich útskriuwing
+unsubscribe.confirm.label=Utsktiuwe út dizze kolleksje sil it ek fuortsmite fan jo favoritenlist. Binne jo wis dat jo útskriuwe wolle?
+unsubscribe.confirm.button1=Nee, annulearje
+unsubscribe.confirm.button0=Ja, útskriuwe
diff --git a/bandwagon/locale/fy-NL/extensionsOverlay.dtd b/bandwagon/locale/fy-NL/extensionsOverlay.dtd
new file mode 100644
index 0000000..ba708c8
--- /dev/null
+++ b/bandwagon/locale/fy-NL/extensionsOverlay.dtd
@@ -0,0 +1,26 @@
+<!-- ***** BEGIN LICENSE BLOCK ***** - Version: MPL 1.1/GPL 2.0/LGPL 2.1 - - The contents of this file are subject to the Mozilla Public License Version - 1.1 (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - http://www.mozilla.org/MPL/ - - Software distributed under the License is distributed on an "AS IS" basis, - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - for the specific language governing rights and limitations under the - License. - - The Original Code is bandwagon. - - The Initial Developer of the Original Code is - Mozilla Corporation. - Portions created by the Initial Developer are Copyright (C) 2008 - the Initial Developer. All Rights Reserved. - - Contributor(s): Brian King <brian (at) briks (dot) si> - David McNamara - - Alternatively, the contents of this file may be used under the terms of - either the GNU General Public License Version 2 or later (the "GPL"), or - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - in which case the provisions of the GPL or the LGPL are applicable instead - of those above. If you wish to allow use of your version of this file only - under the terms of either the GPL or the LGPL, and not to allow others to - use your version of this file under the terms of the MPL, indicate your - decision by deleting the provisions above and replace them with the notice - and other provisions required by the GPL or the LGPL. If you do not delete - the provisions above, a recipient may use your version of this file under - the terms of any one of the MPL, the GPL or the LGPL. - - ***** END LICENSE BLOCK ***** -->
+<!ENTITY collections.label "Abonneminten">
+<!ENTITY search.label.bandwagon "Sykje">
+<!ENTITY addon.moreinfo "Mear ynfo.">
+<!ENTITY addon.addtofirefox "Foech ta oan Firefox">
+<!ENTITY subscribe.label "Fyn kolleksjes">
+<!ENTITY reload.label "Alle op &apos;e nij lade">
+<!ENTITY settings.label "Ynstellings">
+<!ENTITY view.label "Toan kolleksje">
+<!ENTITY unsubscribe.label "Utskriuwe">
+<!ENTITY nocollectionstitle.label "Wolkom by de tafoegingssamler">
+<!ENTITY nocollectionssubscribed.label "Dit is wêr&apos;t kolleksjes dy&apos;t jo markearje as favoryt op Mozilla Add-ons ferskine sille, sa dat jo se maklik yn &apos;e gaten hâlde kinne. It liket der op dat jo noch gjin favoriten tafoege hawwe, dus wêrom sjogge jo net ris rûn yn de kolleksjemap?">
+<!ENTITY clicktosubscribe.label "Fyn kolleksjes">
+<!ENTITY noamoauth.label "Dit is wêr&apos;t kolleksjes dy&apos;t jo markearje as favoryt op Mozilla Add-ons ferskine sille, sa dat jo se maklik yn &apos;e gaten hâlde kinne. Jo moatte ynlogge wêze op addons.mozilla.org om dit te brûken.">
+<!ENTITY username.label "Brûkersnamme">
+<!ENTITY password.label "Wachtwurd">
+<!ENTITY clicktologin.label "Loch yn">
+<!ENTITY createaccount.label "Ik haw gjin account">
+<!ENTITY loginheading.label "Jou hjirûnder jo Mozilla Tafoegings accountynformaasje">
+<!ENTITY collectionisloading.label "Abonnemint ophelje...">
+<!ENTITY collectionhasnoitems.label "Dizze kolleksje befettet gjin tafoegings.">
+<!ENTITY collectionhaserror.label "Dizze kolleksje kin net toand wurde, omdat it flaters befettet.">
+<!ENTITY publishto.label "Publisearje nei">
+<!ENTITY email.address.label "E-mailadres">
+<!ENTITY new.email.address.label "Nij e-mailadrs">
+<!ENTITY new.collection.label "Nije kolleksje">
diff --git a/bandwagon/locale/fy-NL/publish.dtd b/bandwagon/locale/fy-NL/publish.dtd
new file mode 100644
index 0000000..dace821
--- /dev/null
+++ b/bandwagon/locale/fy-NL/publish.dtd
@@ -0,0 +1,47 @@
+<!-- ***** BEGIN LICENSE BLOCK *****
+ - Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ -
+ - The contents of this file are subject to the Mozilla Public License Version
+ - 1.1 (the "License"); you may not use this file except in compliance with
+ - the License. You may obtain a copy of the License at
+ - http://www.mozilla.org/MPL/
+ -
+ - Software distributed under the License is distributed on an "AS IS" basis,
+ - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ - for the specific language governing rights and limitations under the
+ - License.
+ -
+ - The Original Code is bandwagon.
+ -
+ - The Initial Developer of the Original Code is
+ - Mozilla Corporation.
+ - Portions created by the Initial Developer are Copyright (C) 2008
+ - the Initial Developer. All Rights Reserved.
+ -
+ - Contributor(s): David McNamara
+ - Brian King <brian (at) briks (dot) si>
+ -
+ - Alternatively, the contents of this file may be used under the terms of
+ - either the GNU General Public License Version 2 or later (the "GPL"), or
+ - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ - in which case the provisions of the GPL or the LGPL are applicable instead
+ - of those above. If you wish to allow use of your version of this file only
+ - under the terms of either the GPL or the LGPL, and not to allow others to
+ - use your version of this file under the terms of the MPL, indicate your
+ - decision by deleting the provisions above and replace them with the notice
+ - and other provisions required by the GPL or the LGPL. If you do not delete
+ - the provisions above, a recipient may use your version of this file under
+ - the terms of any one of the MPL, the GPL or the LGPL.
+ -
+ - ***** END LICENSE BLOCK *****
+
+ -->
+<!-- For localisers to change the width of the window -->
+<!ENTITY publish.style "width: 35em;">
+<!ENTITY window.title "Publisearje">
+<!ENTITY cancel.label "Annulearje">
+<!ENTITY publish.label "Publisearje">
+<!ENTITY new.email.label "Nij e-mailadres">
+<!ENTITY enter.an.email.label "Jou ien of mear e-mailadressen, skieden troch komma&apos;s:">
+<!ENTITY remember.this.email.label "Unthâld dit e-mailadres">
+<!ENTITY enter.a.personal.note.label "Opsjoneel: Jou in persoanlike noat oer dizze tafoeging om yn de e-mail op te nimmen">
diff --git a/bandwagon/locale/fy-NL/publish.properties b/bandwagon/locale/fy-NL/publish.properties
new file mode 100644
index 0000000..df0dad2
--- /dev/null
+++ b/bandwagon/locale/fy-NL/publish.properties
@@ -0,0 +1,30 @@
+# LOCALIZATION NOTE (you.are.sharing.the.add.on):
+
+# %S is the name of an add-on
+
+you.are.sharing.the.add.on=Jo diele dizze tafoeging '%S'
+# LOCALIZATION NOTE (publishing.to):
+
+# %1 is the name of an add-on. %2 is the name of a collection
+
+publishing.to=Op "Publisearje" klikke sil %1$S tafoegje oan de "%2$S" kolleksje.
+# LOCALIZATION NOTE (sharing.with):
+
+# %1 is a user's email address. $2 is the name of an add-on
+
+sharing.with=Op "Stjoer e-mail" klikke sil %1$S in e-mail stjoere mei ynformaasje oer %2$S
+# LOCALIZATION NOTE (sharing.with.new):
+
+# %S is the name of an add-on
+
+sharing.with.new=p "Stjoer e-mail" klikke sil de boppesteande ûntfangers in e-mail stjoere mei ynformaasje oer %S
+please.enter.an.email.address=Jou asjobleaft in e-mailadres.
+the.addon.has.been.published=De tafoeging is publisearre.
+the.email.has.been.sent=De e-mail is ferstjoerd.
+# LOCALIZATION NOTE (closing.in):
+
+# %S is the number of seconds until a window closes, counting down
+
+closing.in=Slút yn %S...
+send.email=Stjoer e-mail
+error.unknown_addon_guid=Dizze tafoeging kin net dielt wurde, omdat it net oanbean wurd troch it Mozilla Add-ons webstee.
diff --git a/bandwagon/locale/fy-NL/settings.dtd b/bandwagon/locale/fy-NL/settings.dtd
new file mode 100644
index 0000000..b5a8d4d
--- /dev/null
+++ b/bandwagon/locale/fy-NL/settings.dtd
@@ -0,0 +1,54 @@
+<!-- ***** BEGIN LICENSE BLOCK ***** - Version: MPL 1.1/GPL 2.0/LGPL 2.1 - - The contents of this file are subject to the Mozilla Public License Version - 1.1 (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - http://www.mozilla.org/MPL/ - - Software distributed under the License is distributed on an "AS IS" basis, - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - for the specific language governing rights and limitations under the - License. - - The Original Code is bandwagon. - - The Initial Developer of the Original Code is - Mozilla Corporation. - Portions created by the Initial Developer are Copyright (C) 2008 - the Initial Developer. All Rights Reserved. - - Contributor(s): Brian King <brian (at) briks (dot) si> - David McNamara - - Alternatively, the contents of this file may be used under the terms of - either the GNU General Public License Version 2 or later (the "GPL"), or - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - in which case the provisions of the GPL or the LGPL are applicable instead - of those above. If you wish to allow use of your version of this file only - under the terms of either the GPL or the LGPL, and not to allow others to - use your version of this file under the terms of the MPL, indicate your - decision by deleting the provisions above and replace them with the notice - and other provisions required by the GPL or the LGPL. If you do not delete - the provisions above, a recipient may use your version of this file under - the terms of any one of the MPL, the GPL or the LGPL. - - ***** END LICENSE BLOCK ***** -->
+<!-- For localisers to change the width of the window -->
+<!ENTITY settings.style "width: 42em;">
+<!ENTITY window.title "Tafoegingsamler ynstellings">
+<!-- Tabs -->
+<!ENTITY manage.label "Behear abonneminten">
+<!ENTITY general.label "Algemiene ynstellings">
+<!ENTITY pub.label "Auto-publisear ynstellings">
+<!-- Manage Subscriptions -->
+<!ENTITY subscriptions.header "Abonneminten">
+<!-- Groupbox captions in Manage Subscriptions -->
+<!ENTITY frequency.label "Abonnemint fernijfrekwinsje">
+<!ENTITY notifications.label "Nije tafoeging notifikaasjes">
+<!ENTITY perpage.label "Tafoeging per side">
+<!ENTITY default.label "Brûk standert ynstelling">
+<!ENTITY custom.label "Oanpast:">
+<!ENTITY addonsleadin.label "Toan">
+<!ENTITY addonsperpage.label "tafoegings per side">
+<!ENTITY updatesingle.label "Fernij elke:">
+<!ENTITY minutes.label "minuten">
+<!ENTITY hours.label "oere(n)">
+<!ENTITY days.label "dagen">
+<!ENTITY autopublish.label "Auto-publisearje ynstallearre tafoegings nei abonnemint">
+<!ENTITY notify.label "Toan notifikaasjes">
+<!ENTITY applyall.label "Tapasse op alle abonneminten">
+<!ENTITY remove.label "Abonnemint fuortsmite">
+<!ENTITY on.label "Oan">
+<!ENTITY off.label "Ut">
+<!-- General -->
+<!-- Groupbox captions in General -->
+<!ENTITY subscriptions.label "Standert abonnemintynstellings">
+<!ENTITY data.label "Gegevensbehear">
+<!ENTITY updateall.label "Kontrolearje abonneminten foar fernijings elke">
+<!ENTITY notifyglobal.label "Warskôgje my as abonneminten nije tafoegings hawwe">
+<!ENTITY clearemails.label "Wiskje">
+<!ENTITY login.label "Loch yn">
+<!ENTITY logout.label "Loch út">
+<!-- Auto-Publisher Settings -->
+<!-- Groupbox captions in Auto-Publisher Settings -->
+<!ENTITY auto.label "Auto-publisear ynstellings">
+<!ENTITY name.label "Kolleksjenamme:">
+<!ENTITY list.label "Stiet yn publike kolleksjemap">
+<!ENTITY autoleadin.label "Auto-publisearders binne spesjale kolleksjes, dy&apos;t automatysk fernijd wurde as jo tafoegings (de-)ynstallearje yn Firefox op dizze kompjûter.">
+<!ENTITY types.label "Auto-publisear tafoegingstypen:">
+<!ENTITY type.extensions.label "Utwreidings">
+<!ENTITY type.themes.label "Tema&apos;s">
+<!ENTITY type.dicts.label "Wurdboeken">
+<!ENTITY type.langpacks.label "Taalbestannen">
+<!ENTITY createauto.label "Meitsje Auto-publisearder">
+<!ENTITY deleteauto.label "Smyt Auto-publisearder fuort">
+<!ENTITY updateauto.label "Fernij Auto-publisearder">
+<!ENTITY onlypublishenabledaddons.label "Publisearje allinnich ynskeakele tafoegings">
+<!ENTITY misc.label "Wikseljend">
+<!ENTITY allowincompatibleinstall.label "Ynstallaasje fan ynkompatibele tafoegings fan myn abonneminten tastean">
diff --git a/bandwagon/locale/fy-NL/settings.properties b/bandwagon/locale/fy-NL/settings.properties
new file mode 100644
index 0000000..b965ac2
--- /dev/null
+++ b/bandwagon/locale/fy-NL/settings.properties
@@ -0,0 +1,34 @@
+add.collection=Abonnemint tafoegje
+enter.url.to.add.collection=Jou de URL fan it abonnemint dy't jo tafoegje wolle.
+remove.collection=Abonnemint fuortsmite
+# LOCALIZATION NOTE (are.you.sure.you.want.to.remove):
+
+# %S is the name of a collection
+
+are.you.sure.you.want.to.remove=As jo dit abonnemint fuortsmite sil dat ek de kolleksje fan jo favoritenlist helje. Binne jo wis dat jo '%S' fuorthelje wolle?
+# LOCALIZATION NOTE (saved.emails.text):
+
+# %S is a number
+
+saved.emails.text=Jo hawwe %S bewarre e-mailadressen
+# LOCALIZATION NOTE (login.status.with.email):
+
+# %S is a user's email address
+
+login.status.with.email=Jo binne ynlogge as %S
+login.status=Jo binne ynlogge
+logout.status=Jo binne net ynlogge
+# LOCALIZATION NOTE (auto.invalid.name):
+
+# %S is the name of a collection
+
+auto.invalid.name=De kolleksjenamme '%S' is net goed.
+auto.please.select.type=Selektearje asjobleaft ien tafoegingstype om automatysk te publisearjen.
+auto.create.internal.error=De kolleksje koe net makke wurde (der is in ynterne flater makke).
+auto.create.done=Jo auto-publisearder kolleksje is makke.
+auto.delete.internal.error=De kolleksje koe net fuortsmiten wurde (der is in ynterne flater makke).
+auto.delete.done=Jo auto-publisearder kolleksje is fuortsmiten.
+auto.create.description=In automatysk makke list fan myn ynstallearre tafoegings
+auto.update.confirm.message=Jo nije ynstellings sille daliks wurkje, mar sille gjin ynfloed hawwe op de tafoegings dy't al publisearre binne.
+auto.update.internal.error=De kolleksje koe net fernijd wurde (der is in ynterne flater makke).
+auto.update.done=Jo auto-publisearder kolleksje is fernijd.
diff --git a/bandwagon/locale/he/bandwagon.properties b/bandwagon/locale/he/bandwagon.properties
new file mode 100644
index 0000000..6f9328d
--- /dev/null
+++ b/bandwagon/locale/he/bandwagon.properties
@@ -0,0 +1,2 @@
+extensions.sharing@addons.mozilla.org.description=שתף וגלה תוספות.
+extensions.sharing@addons.mozilla.org.name=Add-on Collector
diff --git a/bandwagon/locale/he/bandwagonAddon.properties b/bandwagon/locale/he/bandwagonAddon.properties
new file mode 100644
index 0000000..5fb363c
--- /dev/null
+++ b/bandwagon/locale/he/bandwagonAddon.properties
@@ -0,0 +1,38 @@
+# LOCALIZATION NOTE (bandwagon.addon.pluralRule):
+# See https://developer.mozilla.org/En/Localization_and_Plurals
+bandwagon.addon.pluralRule=1
+bandwagon.category1=הרחבה
+# LOCALIZATION NOTE (bandwagon.addon.author):
+# %S will contain author's first and last name, or their nickname used on AMO
+bandwagon.addon.author=מ×ת %S
+# LOCALIZATION NOTE (bandwagon.addon.addedby):
+# %S will be a user's first and last name, or nickname
+bandwagon.addon.addedby=על־ידי %S
+bandwagon.addon.added.justnow=התווסף: ממש עכשיו
+# LOCALIZATION NOTE:
+# %S will be a number of time units indicated
+bandwagon.addon.added.minute=התווסף: לפני דקה ×חת; התווסף: לפני %S דקות
+bandwagon.addon.added.hour=התווסף: לפני שעה; התווסף: לפני %S שעות
+bandwagon.addon.added.day=התווסף: ×תמול; התווסף: לפני %S ימי×
+bandwagon.addon.added.week=התווסף: לפני שבוע; התווסף: לפני %S שבועות
+bandwagon.addon.added.month=התווסף: לפני חודש; התווסף: לפני %S חודשי×
+bandwagon.addon.added.year=התווסף: לפני שנה; התווסף: לפני %S שני×
+bandwagon.addon.moreinfo=מידע נוסף.
+bandwagon.addon.olderversionsoffirefox=תוספת זו מיועדת לגירס×ות ישנות יותר של Firefox.
+# LOCALIZATION NOTE (upgradetofirefoxn1):
+# %S will be a Firefox version number
+bandwagon.addon.upgradetofirefoxn1=שדרג ל־Firefox %S
+bandwagon.addon.upgradetofirefoxn2=כדי להשתמש בתוספת זו.
+# LOCALIZATION NOTE (bandwagon.addon.requiresfirefoxbeta1/requiresfirefoxbeta2):
+# %S will be a Firefox version number
+bandwagon.addon.requiresfirefoxbeta1=תוספת זו דורשת Firefox %S, ×©×˜×¨× ×©×•×—×¨×¨. כדי להשתמש בתוספת זו, ייתכן ותרצה
+bandwagon.addon.requiresfirefoxbeta2=להוריד Firefox %S beta.
+# LOCALIZATION NOTE (bandwagon.addon.notcompatible):
+# %S will be a platform name, such as "Windows"
+bandwagon.addon.notcompatible=תוספת זו ××™× ×” תו×מת ל־%S.
+# LOCALIZATION NOTE (bandwagon.addon.comment.description):
+# %S will be a comment entered by the publisher of the add-on
+bandwagon.addon.comment.description=“%Sâ€
+# LOCALIZATION NOTE (bandwagon.addon.comment.author):
+# %S will be the publisher's real name or nickname
+bandwagon.addon.comment.author=תגובה מ×ת %S:
diff --git a/bandwagon/locale/he/browserOverlay.dtd b/bandwagon/locale/he/browserOverlay.dtd
new file mode 100644
index 0000000..177b82e
--- /dev/null
+++ b/bandwagon/locale/he/browserOverlay.dtd
@@ -0,0 +1,38 @@
+<!-- ***** BEGIN LICENSE BLOCK *****
+ - Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ -
+ - The contents of this file are subject to the Mozilla Public License Version
+ - 1.1 (the "License"); you may not use this file except in compliance with
+ - the License. You may obtain a copy of the License at
+ - http://www.mozilla.org/MPL/
+ -
+ - Software distributed under the License is distributed on an "AS IS" basis,
+ - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ - for the specific language governing rights and limitations under the
+ - License.
+ -
+ - The Original Code is bandwagon.
+ -
+ - The Initial Developer of the Original Code is
+ - Mozilla Corporation.
+ - Portions created by the Initial Developer are Copyright (C) 2008
+ - the Initial Developer. All Rights Reserved.
+ -
+ - Contributor(s): Brian King <brian (at) briks (dot) si>
+ -
+ - Alternatively, the contents of this file may be used under the terms of
+ - either the GNU General Public License Version 2 or later (the "GPL"), or
+ - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ - in which case the provisions of the GPL or the LGPL are applicable instead
+ - of those above. If you wish to allow use of your version of this file only
+ - under the terms of either the GPL or the LGPL, and not to allow others to
+ - use your version of this file under the terms of the MPL, indicate your
+ - decision by deleting the provisions above and replace them with the notice
+ - and other provisions required by the GPL or the LGPL. If you do not delete
+ - the provisions above, a recipient may use your version of this file under
+ - the terms of any one of the MPL, the GPL or the LGPL.
+ -
+ - ***** END LICENSE BLOCK ***** -->
+
+<!ENTITY bandwagon.label "תוספות">
+<!ENTITY bandwagon.tooltip "תוספות">
diff --git a/bandwagon/locale/he/browserOverlay.properties b/bandwagon/locale/he/browserOverlay.properties
new file mode 100644
index 0000000..1a39be8
--- /dev/null
+++ b/bandwagon/locale/he/browserOverlay.properties
@@ -0,0 +1,4 @@
+newaddons.alert.title=תוספות חדשות
+# LOCALIZATION NOTE (newaddons.alert.text):
+# %S will be the name of a collection
+newaddons.alert.text=ישנן תוספות חדשות בהרשמה שלך ל־"%S".
diff --git a/bandwagon/locale/he/extensionOverlay.properties b/bandwagon/locale/he/extensionOverlay.properties
new file mode 100644
index 0000000..d8f2dc1
--- /dev/null
+++ b/bandwagon/locale/he/extensionOverlay.properties
@@ -0,0 +1,14 @@
+publish.new.email.address.title=כתובת דו×ר ×לקטרוני חדשה
+publish.new.email.address.text=הכנס כתובת דו×ר ×לקטרוני חדשה כדי לשתף תוספת זו ×יתה:
+publish.remove.title=×ימות
+# LOCALIZATION NOTE (publish.remove.label):
+# %1 is the name of an add-on. %2 is the name of a collection
+publish.remove.label=×”×× ×תה בטוח שברצונך להסיר ×ת %1$S מה×וסף "%2$S"?
+publish.remove.button1=ל×, בטל
+publish.remove.button0=כן, הסר תוספת זו
+login.error=התרחשה בעיה בהתחברות. בבקשה בדוק ×©×©× ×”×ž×©×ª×ž×© והסיסמה נכוני×.
+unsubscribe.error=התרחשה בעה בהסרת ההרשמה מה×וסף. ×× × × ×¡×” שנית מ×וחר יותר.
+unsubscribe.confirm.title=×ישור ביטול הרשמה
+unsubscribe.confirm.label=ביטול ההרשמה מ×וסף ×–×” ×’× ×™×¡×™×¨ ×ותו מרשימת ×”×ž×•×¢×“×¤×™× ×©×œ×š. ×”×× ×תה בטוח שברצונך לבטל ×ת ההרשמה?
+unsubscribe.confirm.button1=ל×, בטל
+unsubscribe.confirm.button0=כן, בטל הרשמה
diff --git a/bandwagon/locale/he/extensionsOverlay.dtd b/bandwagon/locale/he/extensionsOverlay.dtd
new file mode 100644
index 0000000..7a030d6
--- /dev/null
+++ b/bandwagon/locale/he/extensionsOverlay.dtd
@@ -0,0 +1,70 @@
+<!-- ***** BEGIN LICENSE BLOCK *****
+ - Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ -
+ - The contents of this file are subject to the Mozilla Public License Version
+ - 1.1 (the "License"); you may not use this file except in compliance with
+ - the License. You may obtain a copy of the License at
+ - http://www.mozilla.org/MPL/
+ -
+ - Software distributed under the License is distributed on an "AS IS" basis,
+ - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ - for the specific language governing rights and limitations under the
+ - License.
+ -
+ - The Original Code is bandwagon.
+ -
+ - The Initial Developer of the Original Code is
+ - Mozilla Corporation.
+ - Portions created by the Initial Developer are Copyright (C) 2008
+ - the Initial Developer. All Rights Reserved.
+ -
+ - Contributor(s): Brian King <brian (at) briks (dot) si>
+ - David McNamara
+ - Tomer Cohen
+ -
+ - Alternatively, the contents of this file may be used under the terms of
+ - either the GNU General Public License Version 2 or later (the "GPL"), or
+ - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ - in which case the provisions of the GPL or the LGPL are applicable instead
+ - of those above. If you wish to allow use of your version of this file only
+ - under the terms of either the GPL or the LGPL, and not to allow others to
+ - use your version of this file under the terms of the MPL, indicate your
+ - decision by deleting the provisions above and replace them with the notice
+ - and other provisions required by the GPL or the LGPL. If you do not delete
+ - the provisions above, a recipient may use your version of this file under
+ - the terms of any one of the MPL, the GPL or the LGPL.
+ -
+ - ***** END LICENSE BLOCK ***** -->
+
+<!ENTITY collections.label "הרשמות">
+<!ENTITY search.label.bandwagon "חיפוש">
+
+<!ENTITY addon.moreinfo "מידע נוסף.">
+<!ENTITY addon.addtofirefox "הוסף ל־Firefox">
+<!ENTITY subscribe.label "×ž×¦× ×וספי×">
+<!ENTITY reload.label "טען מחדש הכל">
+<!ENTITY settings.label "הגדרות">
+
+<!ENTITY view.label "הצג ×וסף">
+<!ENTITY unsubscribe.label "הסרת הרשמה">
+
+<!ENTITY nocollectionstitle.label "×‘×¨×•×›×™× ×”×‘××™× ×œ×וסף התוספות">
+<!ENTITY nocollectionssubscribed.label "×–×” ×”×ž×§×•× ×‘×• ××•×¡×¤×™× ×©×ª×¡×ž×Ÿ ×›×ž×¢×•×“×¤×™× ×‘×תר התוספות של Mozilla יופיעו כדי שתוכל לעקוב ××—×¨×™×”× ×‘×§×œ×•×ª. נר××” ×›×™ ×˜×¨× ×”×•×¡×¤×ª ×ž×•×¢×“×¤×™× ×›×œ×©×”×, ××– למה ×©×œ× ×ª×¡×ª×•×‘×‘ קצת ברשימת ×”××•×¡×¤×™× ×©×œ× ×•?">
+<!ENTITY clicktosubscribe.label "×ž×¦× ×וספי×">
+
+<!ENTITY noamoauth.label "×–×” ×”×ž×§×•× ×‘×• ××•×¡×¤×™× ×©×ª×¡×ž×Ÿ ×›×ž×¢×•×“×¤×™× ×‘×תר התוספות של Mozilla יופיעו כדי שתוכל לעקוב ××—×¨×™×”× ×‘×§×œ×•×ª. ×תה חייב להיות מחובר ל־addons.mozilla.org כדי להשתמש בתכונה זו.">
+<!ENTITY username.label "×©× ×ž×©×ª×ž×©">
+<!ENTITY password.label "סיסמה">
+<!ENTITY clicktologin.label "התחברות">
+
+<!ENTITY collectionisloading.label "מקבל הרשמות...">
+<!ENTITY collectionhasnoitems.label "×וסף ×–×” ×ינו כולל תוספות.">
+<!ENTITY collectionhaserror.label "×œ× × ×™×ª×Ÿ להציג ×וסף ×–×” מ×חר ×•×”×•× ×›×•×œ×œ שגי×ות.">
+
+<!ENTITY publishto.label "×¤×¨×¡× ×ל">
+<!ENTITY email.address.label "כתובת דו×ר ×לקטרוני">
+<!ENTITY new.email.address.label "כתובת דו×ר ×לקטרוני חדשה">
+<!ENTITY new.collection.label "×וסף חדש">
+
+<!ENTITY createaccount.label "×ין לי חשבון">
+<!ENTITY loginheading.label "הכנס ×ת פרטי ההרשמה שלך ל×תר התוספות של Mozilla ×›×ן:">
diff --git a/bandwagon/locale/he/publish.dtd b/bandwagon/locale/he/publish.dtd
new file mode 100644
index 0000000..d781e6f
--- /dev/null
+++ b/bandwagon/locale/he/publish.dtd
@@ -0,0 +1,48 @@
+<!-- ***** BEGIN LICENSE BLOCK *****
+ - Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ -
+ - The contents of this file are subject to the Mozilla Public License Version
+ - 1.1 (the "License"); you may not use this file except in compliance with
+ - the License. You may obtain a copy of the License at
+ - http://www.mozilla.org/MPL/
+ -
+ - Software distributed under the License is distributed on an "AS IS" basis,
+ - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ - for the specific language governing rights and limitations under the
+ - License.
+ -
+ - The Original Code is bandwagon.
+ -
+ - The Initial Developer of the Original Code is
+ - Mozilla Corporation.
+ - Portions created by the Initial Developer are Copyright (C) 2008
+ - the Initial Developer. All Rights Reserved.
+ -
+ - Contributor(s): David McNamara
+ - Brian King <brian (at) briks (dot) si>
+ -
+ - Alternatively, the contents of this file may be used under the terms of
+ - either the GNU General Public License Version 2 or later (the "GPL"), or
+ - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ - in which case the provisions of the GPL or the LGPL are applicable instead
+ - of those above. If you wish to allow use of your version of this file only
+ - under the terms of either the GPL or the LGPL, and not to allow others to
+ - use your version of this file under the terms of the MPL, indicate your
+ - decision by deleting the provisions above and replace them with the notice
+ - and other provisions required by the GPL or the LGPL. If you do not delete
+ - the provisions above, a recipient may use your version of this file under
+ - the terms of any one of the MPL, the GPL or the LGPL.
+ -
+ - ***** END LICENSE BLOCK ***** -->
+
+<!-- For localisers to change the width of the window -->
+<!ENTITY publish.style "width: 35em;">
+
+<!ENTITY window.title "פרס×">
+<!ENTITY cancel.label "ביטול">
+<!ENTITY publish.label "פרס×">
+<!ENTITY new.email.label "כתובת דו×ר ×לקטרוני חדשה">
+<!ENTITY enter.an.email.label "כתובת דו×ר ×לקטרוני ×חת ×ו יותר מופרדות ×¢× ×¤×¡×™×§×™×:">
+<!ENTITY remember.this.email.label "זכור כתובת דו×ר ×לקטרוני זו">
+<!ENTITY enter.a.personal.note.label "רשות: הכנס הערה ×ישית לגבי תוספת זו שתתווסף להודעה הדו×ר ×”×לקטרוני">
+
diff --git a/bandwagon/locale/he/publish.properties b/bandwagon/locale/he/publish.properties
new file mode 100644
index 0000000..6c213b2
--- /dev/null
+++ b/bandwagon/locale/he/publish.properties
@@ -0,0 +1,20 @@
+# LOCALIZATION NOTE (you.are.sharing.the.add.on):
+# %S is the name of an add-on
+you.are.sharing.the.add.on=×תה משתף ×ת התוספת '%S'
+# LOCALIZATION NOTE (publishing.to):
+# %1 is the name of an add-on. %2 is the name of a collection
+publishing.to=לחיצה על "פרס×" תוסיף ×ת %1$S ל×וסף "%2$S".
+# LOCALIZATION NOTE (sharing.with):
+# %1 is a user's email address. $2 is the name of an add-on
+sharing.with=לחיצה על "שלח דו×ר ×לקטרוני" תשלח ×ל %1$S הודעת דו×ר ×לקטרוני ×¢× ×ž×™×“×¢ ×ודות %2$S
+# LOCALIZATION NOTE (sharing.with.new):
+# %S is the name of an add-on
+sharing.with.new=לחיצה על "שלח דו×ר ×לקטרוני" תשלח ×ל ×”× ×ž×¢× ×™× ×”×‘××™× ×”×•×“×¢×ª דו×ר ×לקטרוני ×¢× ×ž×™×“×¢ ×ודות %S
+please.enter.an.email.address=בבקשה הכנס כתובת דו×ר ×לקטרוני.
+the.addon.has.been.published=התוספת התפרסמה.
+the.email.has.been.sent=הודעת הדו×ר ×”×לקטרוני נשלחה.
+# LOCALIZATION NOTE (closing.in):
+# %S is the number of seconds until a window closes, counting down
+closing.in=סוגר בעוד %S...
+send.email=שלח דו×ר ×לקטרוני
+error.unknown_addon_guid=×œ× × ×™×ª×Ÿ לשתף תוספת זו מ×חר ×•×”×™× ××™× ×” מת×רחת ב×תר התוספות של Mozilla. \ No newline at end of file
diff --git a/bandwagon/locale/he/settings.dtd b/bandwagon/locale/he/settings.dtd
new file mode 100644
index 0000000..d78cf18
--- /dev/null
+++ b/bandwagon/locale/he/settings.dtd
@@ -0,0 +1,108 @@
+<!-- ***** BEGIN LICENSE BLOCK *****
+ - Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ -
+ - The contents of this file are subject to the Mozilla Public License Version
+ - 1.1 (the "License"); you may not use this file except in compliance with
+ - the License. You may obtain a copy of the License at
+ - http://www.mozilla.org/MPL/
+ -
+ - Software distributed under the License is distributed on an "AS IS" basis,
+ - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ - for the specific language governing rights and limitations under the
+ - License.
+ -
+ - The Original Code is bandwagon.
+ -
+ - The Initial Developer of the Original Code is
+ - Mozilla Corporation.
+ - Portions created by the Initial Developer are Copyright (C) 2008
+ - the Initial Developer. All Rights Reserved.
+ -
+ - Contributor(s): Brian King <brian (at) briks (dot) si>
+ - David McNamara
+ -
+ - Alternatively, the contents of this file may be used under the terms of
+ - either the GNU General Public License Version 2 or later (the "GPL"), or
+ - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ - in which case the provisions of the GPL or the LGPL are applicable instead
+ - of those above. If you wish to allow use of your version of this file only
+ - under the terms of either the GPL or the LGPL, and not to allow others to
+ - use your version of this file under the terms of the MPL, indicate your
+ - decision by deleting the provisions above and replace them with the notice
+ - and other provisions required by the GPL or the LGPL. If you do not delete
+ - the provisions above, a recipient may use your version of this file under
+ - the terms of any one of the MPL, the GPL or the LGPL.
+ -
+ - ***** END LICENSE BLOCK ***** -->
+
+<!-- For localisers to change the width of the window -->
+<!ENTITY settings.style "width: 42em;">
+
+<!ENTITY window.title "הגדרות ×וסף התוספות">
+
+<!-- Tabs -->
+<!ENTITY manage.label "נהל הרשמות">
+<!ENTITY general.label "הגדרות כלליות">
+<!ENTITY pub.label "הגדרות ×¤×¨×¡×•× ×וטומטי">
+
+<!-- Manage Subscriptions -->
+<!ENTITY subscriptions.header "הרשמות:">
+
+<!-- Groupbox captions in Manage Subscriptions -->
+<!ENTITY frequency.label "תדירות עדכון הרשמות">
+<!ENTITY notifications.label "יידוע על תוספות חדשות">
+<!ENTITY perpage.label "תוספות בדף">
+
+<!ENTITY default.label "השתמש בהגדרות ברירת מחדל">
+<!ENTITY custom.label "מות×× ×ישית:">
+
+<!ENTITY addonsleadin.label "הצג">
+<!ENTITY addonsperpage.label "תוספות בדף">
+<!ENTITY updatesingle.label "עדכן כל:">
+<!ENTITY minutes.label "דקות">
+<!ENTITY hours.label "שעות">
+<!ENTITY days.label "ימי×">
+<!ENTITY autopublish.label "×¤×¨×¡× ×וטומטית תוספות מותקנות להרשמה">
+<!ENTITY notify.label "הצג יידועי×">
+<!ENTITY applyall.label "החל לכל ההרשמות">
+<!ENTITY remove.label "הסר הרשמה">
+<!ENTITY on.label "דולק">
+<!ENTITY off.label "כבוי">
+
+<!-- General -->
+
+<!-- Groupbox captions in General -->
+<!ENTITY subscriptions.label "הגדרות ברירת מחדל להרשמות">
+<!ENTITY data.label "ניהול נתוני×">
+
+<!ENTITY updateall.label "בדוק ×¢×“×›×•× ×™× ×œ×”×¨×©×ž×•×ª בכל">
+<!ENTITY notifyglobal.label "יידע ×ותי ×›×שר הרשמה שלי כוללת תוספות חדשות">
+
+<!ENTITY clearemails.label "מחק">
+<!ENTITY login.label "התחברות">
+<!ENTITY logout.label "התנתקות">
+
+<!-- Auto-Publisher Settings -->
+
+<!-- Groupbox captions in Auto-Publisher Settings -->
+<!ENTITY auto.label "הגדרות ×¤×¨×¡×•× ×וטומטי">
+
+<!ENTITY name.label "×©× ×”×וסף:">
+<!ENTITY list.label "מוצג בספריית ×”××•×¡×¤×™× ×”×¦×™×‘×•×¨×™×ª">
+
+<!ENTITY autoleadin.label "×¤×¨×¡×•× ×וטומטי ×”× ××•×¡×¤×™× ×ž×™×•×—×“×™× ×©×ž×ª×¢×“×›× ×™× ×וטומטית ×›×שר ×תה מתקין ×ו מסיר תוספת מ־Firefox במחשב ×–×”.">
+<!ENTITY types.label "×¤×¨×¡× ×וטומטית תוספות מסוגי×:">
+<!ENTITY type.extensions.label "הרחבות">
+<!ENTITY type.themes.label "ערכות נוש×">
+<!ENTITY type.dicts.label "מילוני×">
+<!ENTITY type.langpacks.label "חבילות שפה">
+
+<!ENTITY createauto.label "צור ×¤×¨×¡×•× ×וטומטי">
+<!ENTITY deleteauto.label "מחק ×¤×¨×¡×•× ×וטומטי">
+<!ENTITY updateauto.label "עדכן ×¤×¨×¡×•× ×וטומטי">
+
+<!ENTITY onlypublishenabledaddons.label "×¤×¨×¡× ×¨×§ תוספות פעילות">
+
+<!ENTITY misc.label "שונות">
+<!ENTITY allowincompatibleinstall.label "×פשר התקנה של תוספות ×œ× ×ª×•×מות מההרשמות שלי">
+
diff --git a/bandwagon/locale/he/settings.properties b/bandwagon/locale/he/settings.properties
new file mode 100644
index 0000000..60357a2
--- /dev/null
+++ b/bandwagon/locale/he/settings.properties
@@ -0,0 +1,26 @@
+add.collection=הוסף הרשמה
+enter.url.to.add.collection=הכנס כתובת עבור ההרשמה שברצונך להוסיף.
+remove.collection=הסר הרשמה
+# LOCALIZATION NOTE (are.you.sure.you.want.to.remove):
+# %S is the name of a collection
+are.you.sure.you.want.to.remove=הסרה של הרשמה זו תסיר ×’× ×ת ×”×וסף מרשימת ×”×ž×•×¢×“×¤×™× ×©×œ×š. ×”×× ×תה בטוח שברצונך להסיר ×ת '%S'?
+# LOCALIZATION NOTE (saved.emails.text):
+# %S is a number
+saved.emails.text=יש לך %S כתובות דו×ר ×לקטרוני שמורות
+# LOCALIZATION NOTE (login.status.with.email):
+# %S is a user's email address
+login.status.with.email=התחברת בתור %S
+login.status=×תה מחובר
+logout.status=×תה ×œ× ×ž×•×‘×¨
+# LOCALIZATION NOTE (auto.invalid.name):
+# %S is the name of a collection
+auto.invalid.name=The collection name '%S' is not valid.
+auto.please.select.type=בבקשה בחר לפחות סוג תוספות ×חד ×œ×¤×¨×¡×•× ×וטומטי..
+auto.create.internal.error=×œ× × ×™×ª×Ÿ ליצור ×ת ×”×וסף (התרחשה שגי××” פנימית)
+auto.create.done=×וסף ×”×¤×¨×¡×•× ×”×וטומטי שלך נוצר.
+auto.delete.internal.error=×œ× × ×™×ª×Ÿ למחוק ×ת ×”×וסף (התרחשה שגי××” פנימית).
+auto.delete.done=×וסף ×”×¤×¨×¡×•× ×”×וטומטי שלך נמחק.
+auto.create.description=רשימה של התוספות המותקנות שלי שנוצרה ×וטומטית
+auto.update.confirm.message=ההגדרות החדשות שלך יקבלו תוקף מיידי, ×בל ×–×” ×œ× ×™×”×™×” תקף לתוספות שכבר פורסמו.
+auto.update.internal.error=×œ× × ×™×ª×Ÿ לעדכן ×ת ×”×וסף (×ירעה שגי××” פנימית).
+auto.update.done=×וסף ×”×¤×¨×¡×•× ×”×וטומטי שלך עודכן.
diff --git a/bandwagon/locale/id/bandwagon.properties b/bandwagon/locale/id/bandwagon.properties
new file mode 100644
index 0000000..f563f12
--- /dev/null
+++ b/bandwagon/locale/id/bandwagon.properties
@@ -0,0 +1,2 @@
+extensions.sharing@addons.mozilla.org.description=Mari berbagi dan temukan pengaya.
+extensions.sharing@addons.mozilla.org.name=Kolektor Pengaya
diff --git a/bandwagon/locale/id/bandwagonAddon.properties b/bandwagon/locale/id/bandwagonAddon.properties
new file mode 100644
index 0000000..3bcf6ef
--- /dev/null
+++ b/bandwagon/locale/id/bandwagonAddon.properties
@@ -0,0 +1,38 @@
+# LOCALIZATION NOTE (bandwagon.addon.pluralRule):
+# See https://developer.mozilla.org/En/Localization_and_Plurals
+bandwagon.addon.pluralRule=1
+bandwagon.category1=Ekstensi
+# LOCALIZATION NOTE (bandwagon.addon.author):
+# %S will contain author's first and last name, or their nickname used on AMO
+bandwagon.addon.author=Oleh %S
+# LOCALIZATION NOTE (bandwagon.addon.addedby):
+# %S will be a user's first and last name, or nickname
+bandwagon.addon.addedby=oleh %S
+bandwagon.addon.added.justnow=Ditambahkan: Baru saja
+# LOCALIZATION NOTE:
+# %S will be a number of time units indicated
+bandwagon.addon.added.minute=Ditambahkan: Semenit yang lalu;Ditambahkan: %S menit yang lalu
+bandwagon.addon.added.hour=Ditambahkan: Sejam yang lalu ago;Ditambahkan: %S jam yang lalu
+bandwagon.addon.added.day=Ditambahkan: Kemarin;Ditambahkan: %S hari yang lalu
+bandwagon.addon.added.week=Ditambahkan: Seminggu yang lalu ago;Ditambahkan: %S minggu yang lalu
+bandwagon.addon.added.month=Ditambahkan: Sebulan yang lalu;Ditambahkan: %S bulan yang lalu
+bandwagon.addon.added.year=Ditambahkan: Setahun yang lalu;Ditambahkan: %S tahun yang lalu
+bandwagon.addon.moreinfo=Keterangan lebih lanjut.
+bandwagon.addon.olderversionsoffirefox=Pengaya ini hanya untuk versi lama Firefox.
+# LOCALIZATION NOTE (upgradetofirefoxn1):
+# %S will be a Firefox version number
+bandwagon.addon.upgradetofirefoxn1=Perbarui Firefox Anda ke versi %S
+bandwagon.addon.upgradetofirefoxn2=untuk menggunakan pengaya ini.
+# LOCALIZATION NOTE (bandwagon.addon.requiresfirefoxbeta1/requiresfirefoxbeta2):
+# %S will be a Firefox version number
+bandwagon.addon.requiresfirefoxbeta1=Pengaya ini membutuhkan Firefox %S, yang masih belum dirilis. Untuk menggunakan pengaya ini Anda dapat
+bandwagon.addon.requiresfirefoxbeta2=mengunduh Firefox %S beta.
+# LOCALIZATION NOTE (bandwagon.addon.notcompatible):
+# %S will be a platform name, such as "Windows"
+bandwagon.addon.notcompatible=Pengaya ini tidak kompatibel dengan %S.
+# LOCALIZATION NOTE (bandwagon.addon.comment.description):
+# %S will be a comment entered by the publisher of the add-on
+bandwagon.addon.comment.description=“%Sâ€
+# LOCALIZATION NOTE (bandwagon.addon.comment.author):
+# %S will be the publisher's real name or nickname
+bandwagon.addon.comment.author=Komentar dari %S:
diff --git a/bandwagon/locale/id/browserOverlay.dtd b/bandwagon/locale/id/browserOverlay.dtd
new file mode 100644
index 0000000..751d8eb
--- /dev/null
+++ b/bandwagon/locale/id/browserOverlay.dtd
@@ -0,0 +1,38 @@
+<!-- ***** BEGIN LICENSE BLOCK *****
+ - Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ -
+ - The contents of this file are subject to the Mozilla Public License Version
+ - 1.1 (the "License"); you may not use this file except in compliance with
+ - the License. You may obtain a copy of the License at
+ - http://www.mozilla.org/MPL/
+ -
+ - Software distributed under the License is distributed on an "AS IS" basis,
+ - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ - for the specific language governing rights and limitations under the
+ - License.
+ -
+ - The Original Code is bandwagon.
+ -
+ - The Initial Developer of the Original Code is
+ - Mozilla Corporation.
+ - Portions created by the Initial Developer are Copyright (C) 2008
+ - the Initial Developer. All Rights Reserved.
+ -
+ - Contributor(s): Brian King <brian (at) briks (dot) si>
+ -
+ - Alternatively, the contents of this file may be used under the terms of
+ - either the GNU General Public License Version 2 or later (the "GPL"), or
+ - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ - in which case the provisions of the GPL or the LGPL are applicable instead
+ - of those above. If you wish to allow use of your version of this file only
+ - under the terms of either the GPL or the LGPL, and not to allow others to
+ - use your version of this file under the terms of the MPL, indicate your
+ - decision by deleting the provisions above and replace them with the notice
+ - and other provisions required by the GPL or the LGPL. If you do not delete
+ - the provisions above, a recipient may use your version of this file under
+ - the terms of any one of the MPL, the GPL or the LGPL.
+ -
+ - ***** END LICENSE BLOCK ***** -->
+
+<!ENTITY bandwagon.label "Pengaya">
+<!ENTITY bandwagon.tooltip "Pengaya">
diff --git a/bandwagon/locale/id/browserOverlay.properties b/bandwagon/locale/id/browserOverlay.properties
new file mode 100644
index 0000000..87f6697
--- /dev/null
+++ b/bandwagon/locale/id/browserOverlay.properties
@@ -0,0 +1,4 @@
+newaddons.alert.title=Pengaya Baru
+# LOCALIZATION NOTE (newaddons.alert.text):
+# %S will be the name of a collection
+newaddons.alert.text=Ada pengaya baru pada langganan Anda "%S".
diff --git a/bandwagon/locale/id/contents.rdf b/bandwagon/locale/id/contents.rdf
new file mode 100644
index 0000000..ad3f82b
--- /dev/null
+++ b/bandwagon/locale/id/contents.rdf
@@ -0,0 +1,15 @@
+<?xml version="1.0"?>
+<RDF:RDF xmlns:RDF="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:chrome="http://www.mozilla.org/rdf/chrome#">
+ <RDF:Seq about="urn:mozilla:locale:root">
+ <RDF:li resource="urn:mozilla:locale:id"/>
+ </RDF:Seq>
+ <RDF:Description about="urn:mozilla:locale:id" chrome:name="id" >
+ <chrome:packages>
+ <RDF:Seq about="urn:mozilla:locale:id:packages">
+ <RDF:li resource="urn:mozilla:locale:id:bandwagon"/>
+ </RDF:Seq>
+ </chrome:packages>
+ </RDF:Description>
+</RDF:RDF>
+
diff --git a/bandwagon/locale/id/extensionOverlay.properties b/bandwagon/locale/id/extensionOverlay.properties
new file mode 100644
index 0000000..91f4b68
--- /dev/null
+++ b/bandwagon/locale/id/extensionOverlay.properties
@@ -0,0 +1,14 @@
+publish.new.email.address.title=Alamat Email Baru
+publish.new.email.address.text=Masukkan alamat email baru untuk berbagi pengaya ini:
+publish.remove.title=Konfirmasi
+# LOCALIZATION NOTE (publish.remove.label):
+# %1 is the name of an add-on. %2 is the name of a collection
+publish.remove.label=Yakin akan menghapus %1$S dari koleksi "%2$S"?
+publish.remove.button1=Tidak, batalkan
+publish.remove.button0=Ya, hapus pengaya ini
+login.error=Terjadi kesalahan pada proses log-masuk. Periksa nama pengguna dan kata sandi Anda apakah sudah benar.
+unsubscribe.error=Terjadi kesalahan saat akan berhenti berlangganan koleksi ini. Silakan coba lagi nanti.
+unsubscribe.confirm.title=Konfirmasi Berhenti Berlangganan
+unsubscribe.confirm.label=Dengan berhenti berlangganan dari koleksi ini juga akan menghapus koleksi dari daftar favorit Anda. Yakin akan berhenti berlangganan?
+unsubscribe.confirm.button1=Tidak, batal
+unsubscribe.confirm.button0=Ya, berhenti berlangganan
diff --git a/bandwagon/locale/id/extensionsOverlay.dtd b/bandwagon/locale/id/extensionsOverlay.dtd
new file mode 100644
index 0000000..9ea5049
--- /dev/null
+++ b/bandwagon/locale/id/extensionsOverlay.dtd
@@ -0,0 +1,69 @@
+<!-- ***** BEGIN LICENSE BLOCK *****
+ - Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ -
+ - The contents of this file are subject to the Mozilla Public License Version
+ - 1.1 (the "License"); you may not use this file except in compliance with
+ - the License. You may obtain a copy of the License at
+ - http://www.mozilla.org/MPL/
+ -
+ - Software distributed under the License is distributed on an "AS IS" basis,
+ - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ - for the specific language governing rights and limitations under the
+ - License.
+ -
+ - The Original Code is bandwagon.
+ -
+ - The Initial Developer of the Original Code is
+ - Mozilla Corporation.
+ - Portions created by the Initial Developer are Copyright (C) 2008
+ - the Initial Developer. All Rights Reserved.
+ -
+ - Contributor(s): Brian King <brian (at) briks (dot) si>
+ - David McNamara
+ -
+ - Alternatively, the contents of this file may be used under the terms of
+ - either the GNU General Public License Version 2 or later (the "GPL"), or
+ - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ - in which case the provisions of the GPL or the LGPL are applicable instead
+ - of those above. If you wish to allow use of your version of this file only
+ - under the terms of either the GPL or the LGPL, and not to allow others to
+ - use your version of this file under the terms of the MPL, indicate your
+ - decision by deleting the provisions above and replace them with the notice
+ - and other provisions required by the GPL or the LGPL. If you do not delete
+ - the provisions above, a recipient may use your version of this file under
+ - the terms of any one of the MPL, the GPL or the LGPL.
+ -
+ - ***** END LICENSE BLOCK ***** -->
+
+<!ENTITY collections.label "Langganan">
+<!ENTITY search.label.bandwagon "Cari">
+
+<!ENTITY addon.moreinfo "Keterangan lebih lanjut.">
+<!ENTITY addon.addtofirefox "Tambahkan ke Firefox">
+<!ENTITY subscribe.label "Temukan Koleksi">
+<!ENTITY reload.label "Muat Ulang Semuanya">
+<!ENTITY settings.label "Pengaturan">
+
+<!ENTITY view.label "Tampilkan Koleksi">
+<!ENTITY unsubscribe.label "Berhenti Berlangganan">
+
+<!ENTITY nocollectionstitle.label "Selamat Datang di Koleksi Pengaya">
+<!ENTITY nocollectionssubscribed.label "Koleksi Pengaya tempat di mana koleksi pengaya yang Anda tandai sebagai favorit pada Mozilla Add-ons akan tampil sehingga Anda dapat mengikuti perkembangannya dengan mudah. Nampaknya Anda belum menambahkan pengaya favorit apapun, mengapa tidak melihat-lihat Kumpulan Koleksi yang ada?">
+<!ENTITY clicktosubscribe.label "Temukan Koleksi">
+
+<!ENTITY noamoauth.label "Koleksi Pengaya tempat di mana koleksi pengaya yang Anda tandai sebagai favorit pada Mozilla Add-ons akan tampil sehingga Anda dapat mengikuti perkembangannya dengan mudah. Anda harus log-masuk ke situs addons.mozilla.org untuk menggunakan fitur ini.">
+<!ENTITY username.label "Alamat Email">
+<!ENTITY password.label "Kata Sandi">
+<!ENTITY clicktologin.label "Log-Masuk">
+<!ENTITY createaccount.label "Saya tidak memiliki akun">
+<!ENTITY loginheading.label "Masukkan informasi akun Mozilla Add-ons di bawah ini:">
+
+<!ENTITY collectionisloading.label "Mengambil langganan...">
+<!ENTITY collectionhasnoitems.label "Koleksi ini tidak mengandung pengaya apapun.">
+<!ENTITY collectionhaserror.label "Koleksi ini tidak dapat ditampilkan karena ada kesalahan.">
+
+<!ENTITY publishto.label "Terbitkan ke">
+<!ENTITY email.address.label "Alamat Email">
+<!ENTITY new.email.address.label "Alamat Email Baru">
+<!ENTITY new.collection.label "Koleksi Baru">
+
diff --git a/bandwagon/locale/id/publish.dtd b/bandwagon/locale/id/publish.dtd
new file mode 100644
index 0000000..4d0a18f
--- /dev/null
+++ b/bandwagon/locale/id/publish.dtd
@@ -0,0 +1,48 @@
+<!-- ***** BEGIN LICENSE BLOCK *****
+ - Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ -
+ - The contents of this file are subject to the Mozilla Public License Version
+ - 1.1 (the "License"); you may not use this file except in compliance with
+ - the License. You may obtain a copy of the License at
+ - http://www.mozilla.org/MPL/
+ -
+ - Software distributed under the License is distributed on an "AS IS" basis,
+ - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ - for the specific language governing rights and limitations under the
+ - License.
+ -
+ - The Original Code is bandwagon.
+ -
+ - The Initial Developer of the Original Code is
+ - Mozilla Corporation.
+ - Portions created by the Initial Developer are Copyright (C) 2008
+ - the Initial Developer. All Rights Reserved.
+ -
+ - Contributor(s): David McNamara
+ - Brian King <brian (at) briks (dot) si>
+ -
+ - Alternatively, the contents of this file may be used under the terms of
+ - either the GNU General Public License Version 2 or later (the "GPL"), or
+ - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ - in which case the provisions of the GPL or the LGPL are applicable instead
+ - of those above. If you wish to allow use of your version of this file only
+ - under the terms of either the GPL or the LGPL, and not to allow others to
+ - use your version of this file under the terms of the MPL, indicate your
+ - decision by deleting the provisions above and replace them with the notice
+ - and other provisions required by the GPL or the LGPL. If you do not delete
+ - the provisions above, a recipient may use your version of this file under
+ - the terms of any one of the MPL, the GPL or the LGPL.
+ -
+ - ***** END LICENSE BLOCK ***** -->
+
+<!-- For localisers to change the width of the window -->
+<!ENTITY publish.style "width: 35em;">
+
+<!ENTITY window.title "Terbitkan">
+<!ENTITY cancel.label "Batal">
+<!ENTITY publish.label "Terbitkan">
+<!ENTITY new.email.label "Alamat Email Baru">
+<!ENTITY enter.an.email.label "Masukkan satu atau lebih alamat email dengan dipisahkan oleh tanda koma:">
+<!ENTITY remember.this.email.label "Ingat email ini">
+<!ENTITY enter.a.personal.note.label "Opsional: Masukkan catatan pribadi tentang pengaya ini untuk disertakan dalam email Anda">
+
diff --git a/bandwagon/locale/id/publish.properties b/bandwagon/locale/id/publish.properties
new file mode 100644
index 0000000..ca51e04
--- /dev/null
+++ b/bandwagon/locale/id/publish.properties
@@ -0,0 +1,22 @@
+# LOCALIZATION NOTE (you.are.sharing.the.add.on):
+# %S is the name of an add-on
+you.are.sharing.the.add.on=Anda berbagi pengaya '%S'
+# LOCALIZATION NOTE (publishing.to):
+# %1 is the name of an add-on. %2 is the name of a collection
+publishing.to=Dengan mengklik "Terbitkan", %1$S akan ditambahkan ke koleksi "%2$S".
+# LOCALIZATION NOTE (sharing.with):
+# %1 is a user's email address. $2 is the name of an add-on
+sharing.with=Dengan mengklik "Kirim Email" akan mengirimkan email kepada %1$S dengan informasi mengenai %2$S
+# LOCALIZATION NOTE (sharing.with.new):
+# %S is the name of an add-on
+sharing.with.new=Dengan mengklik "Kirim Email" akan mengirimkan email kepada penerima di atas dengan informasi mengenai %S
+please.enter.an.email.address=Masukkan sebuah alamat email.
+the.addon.has.been.published=Pengaya ini telah diterbitkan.
+the.email.has.been.sent=Email telah dikirim.
+# LOCALIZATION NOTE (closing.in):
+# %S is the number of seconds until a window closes, counting down
+closing.in=Akan tertutup dalam %S...
+send.email=Kirim Email
+error.unknown_addon_guid=Pengaya ini tidak dapat dibagi karena tidak disediakan melalui situs web Mozilla Add-ons.
+error.invalid_parameters=Terjadi kesalahan saat berbagi pengaya ini. Periksa alamat email dan catatan pribadi apakah sudah benar.
+enter.a.personal.publish.note.label=Opsional: Masukkan catatan pribadi tentang pengaya ini yang akan ditampilkan saat diterbitkan
diff --git a/bandwagon/locale/id/settings.dtd b/bandwagon/locale/id/settings.dtd
new file mode 100644
index 0000000..701569d
--- /dev/null
+++ b/bandwagon/locale/id/settings.dtd
@@ -0,0 +1,108 @@
+<!-- ***** BEGIN LICENSE BLOCK *****
+ - Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ -
+ - The contents of this file are subject to the Mozilla Public License Version
+ - 1.1 (the "License"); you may not use this file except in compliance with
+ - the License. You may obtain a copy of the License at
+ - http://www.mozilla.org/MPL/
+ -
+ - Software distributed under the License is distributed on an "AS IS" basis,
+ - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ - for the specific language governing rights and limitations under the
+ - License.
+ -
+ - The Original Code is bandwagon.
+ -
+ - The Initial Developer of the Original Code is
+ - Mozilla Corporation.
+ - Portions created by the Initial Developer are Copyright (C) 2008
+ - the Initial Developer. All Rights Reserved.
+ -
+ - Contributor(s): Brian King <brian (at) briks (dot) si>
+ - David McNamara
+ -
+ - Alternatively, the contents of this file may be used under the terms of
+ - either the GNU General Public License Version 2 or later (the "GPL"), or
+ - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ - in which case the provisions of the GPL or the LGPL are applicable instead
+ - of those above. If you wish to allow use of your version of this file only
+ - under the terms of either the GPL or the LGPL, and not to allow others to
+ - use your version of this file under the terms of the MPL, indicate your
+ - decision by deleting the provisions above and replace them with the notice
+ - and other provisions required by the GPL or the LGPL. If you do not delete
+ - the provisions above, a recipient may use your version of this file under
+ - the terms of any one of the MPL, the GPL or the LGPL.
+ -
+ - ***** END LICENSE BLOCK ***** -->
+
+<!-- For localisers to change the width of the window -->
+<!ENTITY settings.style "width: 45em;">
+
+<!ENTITY window.title "Pengaturan Koleksi Pengaya">
+
+<!-- Tabs -->
+<!ENTITY manage.label "Kelola Langganan">
+<!ENTITY general.label "Pengaturan Umum">
+<!ENTITY pub.label "Pengaturan Penerbitan Otomatis">
+
+<!-- Manage Subscriptions -->
+<!ENTITY subscriptions.header "Langganan:">
+
+<!-- Groupbox captions in Manage Subscriptions -->
+<!ENTITY frequency.label "Frekuensi Pemutakhiran Langganan">
+<!ENTITY notifications.label "Notifikasi Pengaya Baru">
+<!ENTITY perpage.label "Item Pengaya per Halaman">
+
+<!ENTITY default.label "Gunakan pengaturan default">
+<!ENTITY custom.label "Lainnya:">
+
+<!ENTITY addonsleadin.label "Tampilkan">
+<!ENTITY addonsperpage.label "pengaya per halaman">
+<!ENTITY updatesingle.label "Perbarui setiap:">
+<!ENTITY minutes.label "menit">
+<!ENTITY hours.label "jam">
+<!ENTITY days.label "hari">
+<!ENTITY autopublish.label "Terbitkan otomatis pengaya yang terpasang pada langganan">
+<!ENTITY notify.label "Tampilkan notifikasi">
+<!ENTITY applyall.label "Untuk semua langganan">
+<!ENTITY remove.label "Hapus Langganan">
+<!ENTITY on.label "Aktif">
+<!ENTITY off.label "Mati">
+
+<!-- General -->
+
+<!-- Groupbox captions in General -->
+<!ENTITY subscriptions.label "Pengaturan Berlangganan Default">
+<!ENTITY data.label "Pengelolaan Data">
+
+<!ENTITY updateall.label "Periksa pemutakhiran langganan setiap">
+<!ENTITY notifyglobal.label "Beritahu ketika ada pengaya baru pada langganan saya">
+
+<!ENTITY clearemails.label "Bersihkan">
+<!ENTITY login.label "Log-Masuk">
+<!ENTITY logout.label "Log-Keluar">
+
+<!-- Auto-Publisher Settings -->
+
+<!-- Groupbox captions in Auto-Publisher Settings -->
+<!ENTITY auto.label "Pengaturan Penerbitan Otomatis">
+
+<!ENTITY name.label "Nama Koleksi:">
+<!ENTITY list.label "Tampil pada Kumpulan Koleksi publik">
+
+<!ENTITY autoleadin.label "Penerbitan otomatis adalah koleksi khusus yang diperbarui secara otomatis ketika Anda memasang atau menghapus pengaya Firefox pada komputer ini.">
+<!ENTITY types.label "Otomatis terbitkan untuk jenis pengaya:">
+<!ENTITY type.extensions.label "Ekstensi">
+<!ENTITY type.themes.label "Tema">
+<!ENTITY type.dicts.label "Kamus">
+<!ENTITY type.langpacks.label "Paket Bahasa">
+
+<!ENTITY createauto.label "Buat penerbitan otomatis">
+<!ENTITY deleteauto.label "Hapus penerbitan otomatis">
+<!ENTITY updateauto.label "Perbarui penerbitan otomatis">
+
+<!ENTITY onlypublishenabledaddons.label "Hanya terbitkan pengaya yang aktif">
+
+<!ENTITY misc.label "Lain-lain">
+<!ENTITY allowincompatibleinstall.label "Izinkan pengaya yang tidak kompatibel pada langganan saya">
+
diff --git a/bandwagon/locale/id/settings.properties b/bandwagon/locale/id/settings.properties
new file mode 100644
index 0000000..1e7030f
--- /dev/null
+++ b/bandwagon/locale/id/settings.properties
@@ -0,0 +1,26 @@
+add.collection=Tambah Langganan
+enter.url.to.add.collection=Masukkan alamat URL langganan yang akan ditambahkan.
+remove.collection=Hapus Langganan
+# LOCALIZATION NOTE (are.you.sure.you.want.to.remove):
+# %S is the name of a collection
+are.you.sure.you.want.to.remove=Menghapus langganan ini juga akan menghapus koleksi dari daftar favorit. Yakin akan menghapus '%S'?
+# LOCALIZATION NOTE (saved.emails.text):
+# %S is a number
+saved.emails.text=Anda memiliki %S alamat email yang disimpan
+# LOCALIZATION NOTE (login.status.with.email):
+# %S is a user's email address
+login.status.with.email=Anda log-masuk sebagai %S
+login.status=Anda sudah log-masuk
+logout.status=Anda tidak log-masuk
+# LOCALIZATION NOTE (auto.invalid.name):
+# %S is the name of a collection
+auto.invalid.name=Nama koleksi '%S' tidak sah.
+auto.please.select.type=Pilih paling tidak satu jenis pengaya untuk otomatis diterbitkan.
+auto.create.internal.error=Koleksi tidak dapat dibuat (terjadi kesalahan internal).
+auto.create.done=Koleksi penerbitan otomatis Anda telah dibuat.
+auto.delete.internal.error=Koleksi tidak dapat dihapus (terjadi kesalahan internal).
+auto.delete.done=Koleksi penerbitan otomatis Anda telah dihapus.
+auto.create.description=Daftar otomatis dari pengaya yang saya pasang
+auto.update.confirm.message=Pengaturan Anda akan langsung diaktifkan, tetap tidak berpengaruh pada pengaya yang telah diterbitkan.
+auto.update.internal.error=Koleksi tidak dapat diperbarui (terjadi kesalahan internal).
+auto.update.done=Koleksi penerbitan otomatis pengaya Anda telah diperbarui.
diff --git a/bandwagon/locale/it/bandwagon.properties b/bandwagon/locale/it/bandwagon.properties
new file mode 100644
index 0000000..a2779d1
--- /dev/null
+++ b/bandwagon/locale/it/bandwagon.properties
@@ -0,0 +1,2 @@
+extensions.sharing@addons.mozilla.org.description=Scopri e condividi componenti aggiuntivi
+extensions.sharing@addons.mozilla.org.name=Add-on Collector
diff --git a/bandwagon/locale/it/bandwagonAddon.properties b/bandwagon/locale/it/bandwagonAddon.properties
new file mode 100644
index 0000000..92437de
--- /dev/null
+++ b/bandwagon/locale/it/bandwagonAddon.properties
@@ -0,0 +1,56 @@
+# LOCALIZATION NOTE (bandwagon.addon.pluralRule):
+
+# See https://developer.mozilla.org/En/Localization_and_Plurals
+
+bandwagon.addon.pluralRule=1
+bandwagon.category1=Estensione
+# LOCALIZATION NOTE (bandwagon.addon.author):
+
+# %S will contain author's first and last name, or their nickname used on AMO
+
+bandwagon.addon.author=Di %S
+# LOCALIZATION NOTE (bandwagon.addon.addedby):
+
+# %S will be a user's first and last name, or nickname
+
+bandwagon.addon.addedby=da %S
+bandwagon.addon.added.justnow=Inserito: proprio ora
+# LOCALIZATION NOTE:
+
+# %S will be a number of time units indicated
+
+bandwagon.addon.added.minute=Inserito: 1 minuto fa; Inserito: %s minuti fa
+bandwagon.addon.added.hour=Inserito: 1 ora fa; Inserito: %s ore fa
+bandwagon.addon.added.day=Inserito: ieri; Inserito: %s giorni fa
+bandwagon.addon.added.week=Inserito: 1 settimana fa; Inserito: %s settimane fa
+bandwagon.addon.added.month=Inserito: 1 mese fa; Inserito: %s mesi fa
+bandwagon.addon.added.year=Inserito: 1 anno fa; Inserito: %s anni fa
+bandwagon.addon.moreinfo=Ulteriori informazioni.
+bandwagon.addon.olderversionsoffirefox=Questo componente aggiuntivo è compatibile con le vecchie versioni di Firefox.
+# LOCALIZATION NOTE (upgradetofirefoxn1):
+
+# %S will be a Firefox version number
+
+bandwagon.addon.upgradetofirefoxn1=Aggiorna a Firefox %S
+bandwagon.addon.upgradetofirefoxn2=per utilizzare questo componente aggiuntivo.
+# LOCALIZATION NOTE (bandwagon.addon.requiresfirefoxbeta1/requiresfirefoxbeta2):
+
+# %S will be a Firefox version number
+
+bandwagon.addon.requiresfirefoxbeta1=Questo componente aggiuntivo richiede Firefox %S, che non è ancora stato rilasciato. Per utilizzare questo componente aggiuntivo, potrebbe essere necessario
+bandwagon.addon.requiresfirefoxbeta2=scaricare Firefox %S beta.
+# LOCALIZATION NOTE (bandwagon.addon.notcompatible):
+
+# %S will be a platform name, such as "Windows"
+
+bandwagon.addon.notcompatible=Questo componente aggiuntivo non è compatibile con %S.
+# LOCALIZATION NOTE (bandwagon.addon.comment.description):
+
+# %S will be a comment entered by the publisher of the add-on
+
+bandwagon.addon.comment.description=“%Sâ€
+# LOCALIZATION NOTE (bandwagon.addon.comment.author):
+
+# %S will be the publisher's real name or nickname
+
+bandwagon.addon.comment.author=Commento da %S:
diff --git a/bandwagon/locale/it/browserOverlay.dtd b/bandwagon/locale/it/browserOverlay.dtd
new file mode 100644
index 0000000..5f425aa
--- /dev/null
+++ b/bandwagon/locale/it/browserOverlay.dtd
@@ -0,0 +1,3 @@
+<!-- ***** BEGIN LICENSE BLOCK ***** - Version: MPL 1.1/GPL 2.0/LGPL 2.1 - - The contents of this file are subject to the Mozilla Public License Version - 1.1 (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - http://www.mozilla.org/MPL/ - - Software distributed under the License is distributed on an "AS IS" basis, - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - for the specific language governing rights and limitations under the - License. - - The Original Code is bandwagon. - - The Initial Developer of the Original Code is - Mozilla Corporation. - Portions created by the Initial Developer are Copyright (C) 2008 - the Initial Developer. All Rights Reserved. - - Contributor(s): Brian King <brian (at) briks (dot) si> - - Alternatively, the contents of this file may be used under the terms of - either the GNU General Public License Version 2 or later (the "GPL"), or - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - in which case the provisions of the GPL or the LGPL are applicable instead - of those above. If you wish to allow use of your version of this file only - under the terms of either the GPL or the LGPL, and not to allow others to - use your version of this file under the terms of the MPL, indicate your - decision by deleting the provisions above and replace them with the notice - and other provisions required by the GPL or the LGPL. If you do not delete - the provisions above, a recipient may use your version of this file under - the terms of any one of the MPL, the GPL or the LGPL. - - ***** END LICENSE BLOCK ***** -->
+<!ENTITY bandwagon.label "Componenti aggiuntivi">
+<!ENTITY bandwagon.tooltip "Componenti aggiuntivi">
diff --git a/bandwagon/locale/it/browserOverlay.properties b/bandwagon/locale/it/browserOverlay.properties
new file mode 100644
index 0000000..0cd198f
--- /dev/null
+++ b/bandwagon/locale/it/browserOverlay.properties
@@ -0,0 +1,6 @@
+newaddons.alert.title=Nuovi componenti aggiuntivi
+# LOCALIZATION NOTE (newaddons.alert.text):
+
+# %S will be the name of a collection
+
+newaddons.alert.text=Risultano nuovi componenti aggiuntivi per l'iscrizione "%S".
diff --git a/bandwagon/locale/it/contents.rdf b/bandwagon/locale/it/contents.rdf
new file mode 100644
index 0000000..9266feb
--- /dev/null
+++ b/bandwagon/locale/it/contents.rdf
@@ -0,0 +1,15 @@
+<?xml version="1.0"?>
+<RDF:RDF xmlns:RDF="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:chrome="http://www.mozilla.org/rdf/chrome#">
+ <RDF:Seq about="urn:mozilla:locale:root">
+ <RDF:li resource="urn:mozilla:locale:it-IT"/>
+ </RDF:Seq>
+ <RDF:Description about="urn:mozilla:locale:it-IT" chrome:name="it-IT" >
+ <chrome:packages>
+ <RDF:Seq about="urn:mozilla:locale:it-IT:packages">
+ <RDF:li resource="urn:mozilla:locale:it-IT:bandwagon"/>
+ </RDF:Seq>
+ </chrome:packages>
+ </RDF:Description>
+</RDF:RDF>
+
diff --git a/bandwagon/locale/it/extensionOverlay.properties b/bandwagon/locale/it/extensionOverlay.properties
new file mode 100644
index 0000000..0159058
--- /dev/null
+++ b/bandwagon/locale/it/extensionOverlay.properties
@@ -0,0 +1,16 @@
+publish.new.email.address.title=Nuovo indirizzo e-mail
+publish.new.email.address.text=Inserire un nuovo indirizzo e-mail con cui condividere questo componente aggiuntivo:
+publish.remove.title=Conferma
+# LOCALIZATION NOTE (publish.remove.label):
+
+# %1 is the name of an add-on. %2 is the name of a collection
+
+publish.remove.label=Rimuovere %1$S dalla raccolta "%2$S"?
+publish.remove.button1=No, annulla
+publish.remove.button0=Sì, rimuovi
+login.error=Si è verificato un errore durante l'accesso. Verificare che il nome utente e la password siano corretti.
+unsubscribe.error=Si è verificato un errore durante l'annullamento dell'iscrizione a questa raccolta. Riprovare in seguito.
+unsubscribe.confirm.title=Conferma annullamento iscrizione
+unsubscribe.confirm.label=Annullando l'iscrizione, la raccolta verrà rimossa anche dai preferiti. Annullare l'iscrizione?
+unsubscribe.confirm.button1=No, annulla
+unsubscribe.confirm.button0=Sì, procedi
diff --git a/bandwagon/locale/it/extensionsOverlay.dtd b/bandwagon/locale/it/extensionsOverlay.dtd
new file mode 100644
index 0000000..531c6f9
--- /dev/null
+++ b/bandwagon/locale/it/extensionsOverlay.dtd
@@ -0,0 +1,26 @@
+<!-- ***** BEGIN LICENSE BLOCK ***** - Version: MPL 1.1/GPL 2.0/LGPL 2.1 - - The contents of this file are subject to the Mozilla Public License Version - 1.1 (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - http://www.mozilla.org/MPL/ - - Software distributed under the License is distributed on an "AS IS" basis, - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - for the specific language governing rights and limitations under the - License. - - The Original Code is bandwagon. - - The Initial Developer of the Original Code is - Mozilla Corporation. - Portions created by the Initial Developer are Copyright (C) 2008 - the Initial Developer. All Rights Reserved. - - Contributor(s): Brian King <brian (at) briks (dot) si> - David McNamara - - Alternatively, the contents of this file may be used under the terms of - either the GNU General Public License Version 2 or later (the "GPL"), or - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - in which case the provisions of the GPL or the LGPL are applicable instead - of those above. If you wish to allow use of your version of this file only - under the terms of either the GPL or the LGPL, and not to allow others to - use your version of this file under the terms of the MPL, indicate your - decision by deleting the provisions above and replace them with the notice - and other provisions required by the GPL or the LGPL. If you do not delete - the provisions above, a recipient may use your version of this file under - the terms of any one of the MPL, the GPL or the LGPL. - - ***** END LICENSE BLOCK ***** -->
+<!ENTITY collections.label "Iscrizioni">
+<!ENTITY search.label.bandwagon "Cerca">
+<!ENTITY addon.moreinfo "Ulteriori informazioni.">
+<!ENTITY addon.addtofirefox "Aggiungi a Firefox">
+<!ENTITY subscribe.label "Cerca raccolte">
+<!ENTITY reload.label "Ricarica tutto">
+<!ENTITY settings.label "Impostazioni">
+<!ENTITY view.label "Visualizza raccolte">
+<!ENTITY unsubscribe.label "Annulla iscrizione">
+<!ENTITY nocollectionstitle.label "Benvenuti in Add-on Collector">
+<!ENTITY nocollectionssubscribed.label "In questa sezione è possibile visualizzare e gestire le raccolte impostate come preferite su Mozilla Add-ons. Al momento non risulta presente nessuna raccolta tra i preferiti, perché non dare un&apos;occhiata alle raccolte disponibili nella galleria pubblica?">
+<!ENTITY clicktosubscribe.label "Cerca raccolte">
+<!ENTITY noamoauth.label "In questa sezione sarà possibile visualizzare e gestire le raccolte identificate come preferite su Mozilla Add-ons. Per accedere a questa funzione è necessario effettuare l&apos;accesso su addons.mozilla.org">
+<!ENTITY username.label "Indirizzo e-mail">
+<!ENTITY password.label "Password">
+<!ENTITY clicktologin.label "Accedi">
+<!ENTITY createaccount.label "Non possiedo un account">
+<!ENTITY loginheading.label "Inserire le informazioni relative all&apos;account per Mozilla Add-ons:">
+<!ENTITY collectionisloading.label "Recupero iscrizioni in corso…">
+<!ENTITY collectionhasnoitems.label "Questa raccolta non contiene componenti aggiuntivi.">
+<!ENTITY collectionhaserror.label "Questa raccolta contiene degli errori e non può essere visualizzata.">
+<!ENTITY publishto.label "Pubblica su">
+<!ENTITY email.address.label "Indirizzo e-mail">
+<!ENTITY new.email.address.label "Nuovo indirizzo e-mail">
+<!ENTITY new.collection.label "Nuova raccolta">
diff --git a/bandwagon/locale/it/publish.dtd b/bandwagon/locale/it/publish.dtd
new file mode 100644
index 0000000..1274622
--- /dev/null
+++ b/bandwagon/locale/it/publish.dtd
@@ -0,0 +1,47 @@
+<!-- ***** BEGIN LICENSE BLOCK *****
+ - Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ -
+ - The contents of this file are subject to the Mozilla Public License Version
+ - 1.1 (the "License"); you may not use this file except in compliance with
+ - the License. You may obtain a copy of the License at
+ - http://www.mozilla.org/MPL/
+ -
+ - Software distributed under the License is distributed on an "AS IS" basis,
+ - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ - for the specific language governing rights and limitations under the
+ - License.
+ -
+ - The Original Code is bandwagon.
+ -
+ - The Initial Developer of the Original Code is
+ - Mozilla Corporation.
+ - Portions created by the Initial Developer are Copyright (C) 2008
+ - the Initial Developer. All Rights Reserved.
+ -
+ - Contributor(s): David McNamara
+ - Brian King <brian (at) briks (dot) si>
+ -
+ - Alternatively, the contents of this file may be used under the terms of
+ - either the GNU General Public License Version 2 or later (the "GPL"), or
+ - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ - in which case the provisions of the GPL or the LGPL are applicable instead
+ - of those above. If you wish to allow use of your version of this file only
+ - under the terms of either the GPL or the LGPL, and not to allow others to
+ - use your version of this file under the terms of the MPL, indicate your
+ - decision by deleting the provisions above and replace them with the notice
+ - and other provisions required by the GPL or the LGPL. If you do not delete
+ - the provisions above, a recipient may use your version of this file under
+ - the terms of any one of the MPL, the GPL or the LGPL.
+ -
+ - ***** END LICENSE BLOCK *****
+
+ -->
+<!-- For localisers to change the width of the window -->
+<!ENTITY publish.style "width: 35em;">
+<!ENTITY window.title "Pubblica">
+<!ENTITY cancel.label "Annulla">
+<!ENTITY publish.label "Pubblica">
+<!ENTITY new.email.label "Nuovo indirizzo e-mail">
+<!ENTITY enter.an.email.label "Inserire uno o più indirizzi e-mail separati da virgole:">
+<!ENTITY remember.this.email.label "Ricorda questo indirizzo e-mail">
+<!ENTITY enter.a.personal.note.label "Facoltativo: inserire una nota personale da aggiungere all&apos;e-mail per questo componente aggiuntivo">
diff --git a/bandwagon/locale/it/publish.properties b/bandwagon/locale/it/publish.properties
new file mode 100644
index 0000000..c665581
--- /dev/null
+++ b/bandwagon/locale/it/publish.properties
@@ -0,0 +1,30 @@
+# LOCALIZATION NOTE (you.are.sharing.the.add.on):
+
+# %S is the name of an add-on
+
+you.are.sharing.the.add.on=Condividi '%S'
+# LOCALIZATION NOTE (publishing.to):
+
+# %1 is the name of an add-on. %2 is the name of a collection
+
+publishing.to=Fare clic su "Pubblica" per aggiungere %1$S alla raccolta "%2$S".
+# LOCALIZATION NOTE (sharing.with):
+
+# %1 is a user's email address. $2 is the name of an add-on
+
+sharing.with=Fare clic su "Invia e-mail" per inviare a %1$S un messaggio con informazioni relative a %2$S
+# LOCALIZATION NOTE (sharing.with.new):
+
+# %S is the name of an add-on
+
+sharing.with.new=Fare clic su "Invia e-mail" per inviare ai seguenti destinatari un messaggio con informazioni relative a %2$S
+please.enter.an.email.address=Inserire un indirizzo e-mail
+the.addon.has.been.published=Il componente aggiuntivo è stato pubblicato.
+the.email.has.been.sent=L'e-mail è stata inviata.
+# LOCALIZATION NOTE (closing.in):
+
+# %S is the number of seconds until a window closes, counting down
+
+closing.in=Chiusura in %S secondi…
+send.email=Invia e-mail
+error.unknown_addon_guid=Questo componente aggiuntivo non può essere condiviso in quanto non è ospitato sul sito Mozilla Add-ons.
diff --git a/bandwagon/locale/it/settings.dtd b/bandwagon/locale/it/settings.dtd
new file mode 100644
index 0000000..d874691
--- /dev/null
+++ b/bandwagon/locale/it/settings.dtd
@@ -0,0 +1,54 @@
+<!-- ***** BEGIN LICENSE BLOCK ***** - Version: MPL 1.1/GPL 2.0/LGPL 2.1 - - The contents of this file are subject to the Mozilla Public License Version - 1.1 (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - http://www.mozilla.org/MPL/ - - Software distributed under the License is distributed on an "AS IS" basis, - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - for the specific language governing rights and limitations under the - License. - - The Original Code is bandwagon. - - The Initial Developer of the Original Code is - Mozilla Corporation. - Portions created by the Initial Developer are Copyright (C) 2008 - the Initial Developer. All Rights Reserved. - - Contributor(s): Brian King <brian (at) briks (dot) si> - David McNamara - - Alternatively, the contents of this file may be used under the terms of - either the GNU General Public License Version 2 or later (the "GPL"), or - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - in which case the provisions of the GPL or the LGPL are applicable instead - of those above. If you wish to allow use of your version of this file only - under the terms of either the GPL or the LGPL, and not to allow others to - use your version of this file under the terms of the MPL, indicate your - decision by deleting the provisions above and replace them with the notice - and other provisions required by the GPL or the LGPL. If you do not delete - the provisions above, a recipient may use your version of this file under - the terms of any one of the MPL, the GPL or the LGPL. - - ***** END LICENSE BLOCK ***** -->
+<!-- For localisers to change the width of the window -->
+<!ENTITY settings.style "width: 48em;">
+<!ENTITY window.title "Impostazioni di Add-on Collector">
+<!-- Tabs -->
+<!ENTITY manage.label "Iscrizioni">
+<!ENTITY general.label "Generale">
+<!ENTITY pub.label "Pubblicazione automatica">
+<!-- Manage Subscriptions -->
+<!ENTITY subscriptions.header "Iscrizioni:">
+<!-- Groupbox captions in Manage Subscriptions -->
+<!ENTITY frequency.label "Frequenza di aggiornamento">
+<!ENTITY notifications.label "Notifiche nuovi elementi">
+<!ENTITY perpage.label "Elementi per pagina">
+<!ENTITY default.label "Usa impostazioni predefinite">
+<!ENTITY custom.label "Impostazioni personalizzate:">
+<!ENTITY addonsleadin.label "visualizza">
+<!ENTITY addonsperpage.label "elementi per pagina">
+<!ENTITY updatesingle.label "aggiorna ogni">
+<!ENTITY minutes.label "minuto(i)">
+<!ENTITY hours.label "ora(e)">
+<!ENTITY days.label "giorno(i)">
+<!ENTITY autopublish.label "Pubblica automaticamente nell&apos;iscrizione i componenti aggiuntivi installati">
+<!ENTITY notify.label "Mostra notifiche">
+<!ENTITY applyall.label "Applica a tutte le iscrizioni">
+<!ENTITY remove.label "Rimuovi iscrizione">
+<!ENTITY on.label "attivo">
+<!ENTITY off.label "disattivato">
+<!-- General -->
+<!-- Groupbox captions in General -->
+<!ENTITY subscriptions.label "Impostazioni predefinite per le iscrizioni">
+<!ENTITY data.label "Gestione dati">
+<!ENTITY updateall.label "Cerca aggiornamenti per le iscrizioni ogni">
+<!ENTITY notifyglobal.label "Avvisa quando risultano nuovi elementi nelle proprie iscrizioni:">
+<!ENTITY clearemails.label "Cancella">
+<!ENTITY login.label "Connetti">
+<!ENTITY logout.label "Disconnetti">
+<!-- Auto-Publisher Settings -->
+<!-- Groupbox captions in Auto-Publisher Settings -->
+<!ENTITY auto.label "Impostazioni pubblicazione automatica">
+<!ENTITY name.label "Nome raccolta:">
+<!ENTITY list.label "Inserisci nella galleria pubblica delle raccolte">
+<!ENTITY autoleadin.label "Le raccolte a pubblicazione automatica sono speciali raccolte che vengono aggiornate automaticamente quando si installa o si disinstalla un componente aggiuntivo di Firefox.">
+<!ENTITY types.label "Tipologie di elementi da pubblicare automaticamente:">
+<!ENTITY type.extensions.label "Estensioni">
+<!ENTITY type.themes.label "Temi">
+<!ENTITY type.dicts.label "Dizionari">
+<!ENTITY type.langpacks.label "Language pack">
+<!ENTITY createauto.label "Crea raccolta a pubblicazione automatica">
+<!ENTITY deleteauto.label "Elimina raccolta">
+<!ENTITY updateauto.label "Aggiorna raccolta">
+<!ENTITY onlypublishenabledaddons.label "Pubblica solo i componenti aggiuntivi attivi">
+<!ENTITY misc.label "Varie">
+<!ENTITY allowincompatibleinstall.label "Consenti l&apos;installazione di componenti aggiuntivi non compatibili dalle iscrizioni">
diff --git a/bandwagon/locale/it/settings.properties b/bandwagon/locale/it/settings.properties
new file mode 100644
index 0000000..d98f8f9
--- /dev/null
+++ b/bandwagon/locale/it/settings.properties
@@ -0,0 +1,34 @@
+add.collection=Aggiungi iscrizione
+enter.url.to.add.collection=Inserire l'URL dell'iscrizione da aggiungere
+remove.collection=Rimuovi iscrizione
+# LOCALIZATION NOTE (are.you.sure.you.want.to.remove):
+
+# %S is the name of a collection
+
+are.you.sure.you.want.to.remove=Rimuovendo l'iscrizione verrà eliminata anche la raccolta all'interno dei preferiti. Rimuovere '%S'?
+# LOCALIZATION NOTE (saved.emails.text):
+
+# %S is a number
+
+saved.emails.text=Sono presenti %S indirizzi e-mail salvati
+# LOCALIZATION NOTE (login.status.with.email):
+
+# %S is a user's email address
+
+login.status.with.email=Identificato come %S
+login.status=Connesso
+logout.status=Disconnesso
+# LOCALIZATION NOTE (auto.invalid.name):
+
+# %S is the name of a collection
+
+auto.invalid.name='%S' non è un nome valido per una raccolta.
+auto.please.select.type=Selezionare almeno una tipologia per la pubblicazione automatica.
+auto.create.internal.error=Impossibile creare la raccolta (si è verificato un errore interno).
+auto.create.done=La raccolta a pubblicazione automatica è stata creata correttamente.
+auto.delete.internal.error=Impossibile eliminare la raccolta (si è verificato un errore interno).
+auto.delete.done=La raccolta a pubblicazione automatica è stata eliminata correttamente.
+auto.create.description=Una lista generata automaticamente dei componenti aggiuntivi installati
+auto.update.confirm.message=Le nuove impostazioni sono già attive, ma non avranno effetto sui componenti aggiuntivi già pubblicati.
+auto.update.internal.error=Impossibile aggiornare la raccolta (si è verificato un errore interno).
+auto.update.done=La raccolta a pubblicazione automatica è stata aggiornata.
diff --git a/bandwagon/locale/ja/bandwagon.properties b/bandwagon/locale/ja/bandwagon.properties
new file mode 100644
index 0000000..37a8281
--- /dev/null
+++ b/bandwagon/locale/ja/bandwagon.properties
@@ -0,0 +1,2 @@
+extensions.sharing@addons.mozilla.org.description=Share and discover add-ons.
+extensions.sharing@addons.mozilla.org.name=Add-on Collector
diff --git a/bandwagon/locale/ja/bandwagonAddon.properties b/bandwagon/locale/ja/bandwagonAddon.properties
new file mode 100644
index 0000000..22eadb6
--- /dev/null
+++ b/bandwagon/locale/ja/bandwagonAddon.properties
@@ -0,0 +1,56 @@
+# LOCALIZATION NOTE (bandwagon.addon.pluralRule):
+
+# See https://developer.mozilla.org/En/Localization_and_Plurals
+
+bandwagon.addon.pluralRule=1
+bandwagon.category1=Extension
+# LOCALIZATION NOTE (bandwagon.addon.author):
+
+# %S will contain author's first and last name, or their nickname used on AMO
+
+bandwagon.addon.author=By %S
+# LOCALIZATION NOTE (bandwagon.addon.addedby):
+
+# %S will be a user's first and last name, or nickname
+
+bandwagon.addon.addedby=by %S
+bandwagon.addon.added.justnow=Added: Just now
+# LOCALIZATION NOTE:
+
+# %S will be a number of time units indicated
+
+bandwagon.addon.added.minute=Added: 1 minute ago;Added: %S minutes ago
+bandwagon.addon.added.hour=Added: 1 hour ago;Added: %S hours ago
+bandwagon.addon.added.day=Added: Yesterday;Added: %S days ago
+bandwagon.addon.added.week=Added: 1 week ago;Added: %S weeks ago
+bandwagon.addon.added.month=Added: 1 month ago;Added: %S months ago
+bandwagon.addon.added.year=Added: 1 year ago;Added: %S years ago
+bandwagon.addon.moreinfo=More info.
+bandwagon.addon.olderversionsoffirefox=This add-on is for older versions of Firefox.
+# LOCALIZATION NOTE (upgradetofirefoxn1):
+
+# %S will be a Firefox version number
+
+bandwagon.addon.upgradetofirefoxn1=Upgrade to Firefox %S
+bandwagon.addon.upgradetofirefoxn2=to use this add-on.
+# LOCALIZATION NOTE (bandwagon.addon.requiresfirefoxbeta1/requiresfirefoxbeta2):
+
+# %S will be a Firefox version number
+
+bandwagon.addon.requiresfirefoxbeta1=This add-on requires Firefox %S, which has not yet been released. To use this add-on, you may
+bandwagon.addon.requiresfirefoxbeta2=download Firefox %S beta.
+# LOCALIZATION NOTE (bandwagon.addon.notcompatible):
+
+# %S will be a platform name, such as "Windows"
+
+bandwagon.addon.notcompatible=This add-on is not compatible with %S.
+# LOCALIZATION NOTE (bandwagon.addon.comment.description):
+
+# %S will be a comment entered by the publisher of the add-on
+
+bandwagon.addon.comment.description=“%Sâ€
+# LOCALIZATION NOTE (bandwagon.addon.comment.author):
+
+# %S will be the publisher's real name or nickname
+
+bandwagon.addon.comment.author=Comment from %S:
diff --git a/bandwagon/locale/ja/browserOverlay.dtd b/bandwagon/locale/ja/browserOverlay.dtd
new file mode 100644
index 0000000..1fb49b7
--- /dev/null
+++ b/bandwagon/locale/ja/browserOverlay.dtd
@@ -0,0 +1,3 @@
+<!-- ***** BEGIN LICENSE BLOCK ***** - Version: MPL 1.1/GPL 2.0/LGPL 2.1 - - The contents of this file are subject to the Mozilla Public License Version - 1.1 (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - http://www.mozilla.org/MPL/ - - Software distributed under the License is distributed on an "AS IS" basis, - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - for the specific language governing rights and limitations under the - License. - - The Original Code is bandwagon. - - The Initial Developer of the Original Code is - Mozilla Corporation. - Portions created by the Initial Developer are Copyright (C) 2008 - the Initial Developer. All Rights Reserved. - - Contributor(s): Brian King <brian (at) briks (dot) si> - - Alternatively, the contents of this file may be used under the terms of - either the GNU General Public License Version 2 or later (the "GPL"), or - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - in which case the provisions of the GPL or the LGPL are applicable instead - of those above. If you wish to allow use of your version of this file only - under the terms of either the GPL or the LGPL, and not to allow others to - use your version of this file under the terms of the MPL, indicate your - decision by deleting the provisions above and replace them with the notice - and other provisions required by the GPL or the LGPL. If you do not delete - the provisions above, a recipient may use your version of this file under - the terms of any one of the MPL, the GPL or the LGPL. - - ***** END LICENSE BLOCK ***** -->
+<!ENTITY bandwagon.label "Add-ons">
+<!ENTITY bandwagon.tooltip "Add-ons">
diff --git a/bandwagon/locale/ja/browserOverlay.properties b/bandwagon/locale/ja/browserOverlay.properties
new file mode 100644
index 0000000..4ab1e95
--- /dev/null
+++ b/bandwagon/locale/ja/browserOverlay.properties
@@ -0,0 +1,6 @@
+newaddons.alert.title=New Add-ons
+# LOCALIZATION NOTE (newaddons.alert.text):
+
+# %S will be the name of a collection
+
+newaddons.alert.text=There are new add-ons in your subscription "%S".
diff --git a/bandwagon/locale/ja/extensionOverlay.properties b/bandwagon/locale/ja/extensionOverlay.properties
new file mode 100644
index 0000000..4684756
--- /dev/null
+++ b/bandwagon/locale/ja/extensionOverlay.properties
@@ -0,0 +1,16 @@
+publish.new.email.address.title=New E-mail Address
+publish.new.email.address.text=Enter a new e-mail address to share this add-on with:
+publish.remove.title=Confirmation
+# LOCALIZATION NOTE (publish.remove.label):
+
+# %1 is the name of an add-on. %2 is the name of a collection
+
+publish.remove.label=Are you sure you wish to remove %1$S from the "%2$S" collection?
+publish.remove.button1=No, cancel
+publish.remove.button0=Yes, remove the add-on
+login.error=There was an error logging in. Please check that your username and password are correct.
+unsubscribe.error=There was an error unsubscribing from this collection. Please try again later.
+unsubscribe.confirm.title=Confirm Unsubscribe
+unsubscribe.confirm.label=Unsubscribing from this collection will also remove it from your list of favorites. Are you sure you want to unsubscribe?
+unsubscribe.confirm.button1=No, cancel
+unsubscribe.confirm.button0=Yes, unsubscribe
diff --git a/bandwagon/locale/ja/extensionsOverlay.dtd b/bandwagon/locale/ja/extensionsOverlay.dtd
new file mode 100644
index 0000000..c8400e0
--- /dev/null
+++ b/bandwagon/locale/ja/extensionsOverlay.dtd
@@ -0,0 +1,26 @@
+<!-- ***** BEGIN LICENSE BLOCK ***** - Version: MPL 1.1/GPL 2.0/LGPL 2.1 - - The contents of this file are subject to the Mozilla Public License Version - 1.1 (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - http://www.mozilla.org/MPL/ - - Software distributed under the License is distributed on an "AS IS" basis, - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - for the specific language governing rights and limitations under the - License. - - The Original Code is bandwagon. - - The Initial Developer of the Original Code is - Mozilla Corporation. - Portions created by the Initial Developer are Copyright (C) 2008 - the Initial Developer. All Rights Reserved. - - Contributor(s): Brian King <brian (at) briks (dot) si> - David McNamara - - Alternatively, the contents of this file may be used under the terms of - either the GNU General Public License Version 2 or later (the "GPL"), or - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - in which case the provisions of the GPL or the LGPL are applicable instead - of those above. If you wish to allow use of your version of this file only - under the terms of either the GPL or the LGPL, and not to allow others to - use your version of this file under the terms of the MPL, indicate your - decision by deleting the provisions above and replace them with the notice - and other provisions required by the GPL or the LGPL. If you do not delete - the provisions above, a recipient may use your version of this file under - the terms of any one of the MPL, the GPL or the LGPL. - - ***** END LICENSE BLOCK ***** -->
+<!ENTITY collections.label "Subscriptions">
+<!ENTITY search.label.bandwagon "Search">
+<!ENTITY addon.moreinfo "More info.">
+<!ENTITY addon.addtofirefox "Add to Firefox">
+<!ENTITY subscribe.label "Find Collections">
+<!ENTITY reload.label "Reload All">
+<!ENTITY settings.label "Settings">
+<!ENTITY view.label "View Collection">
+<!ENTITY unsubscribe.label "Unsubscribe">
+<!ENTITY nocollectionstitle.label "Welcome to the Add-on Collector">
+<!ENTITY nocollectionssubscribed.label "This is where collections you mark as a favorite on Mozilla Add-ons will appear so that you can easily keep track of them. It looks like you haven&apos;t yet added any favorites, so why not take a look around our Collection Directory?">
+<!ENTITY clicktosubscribe.label "Find Collections">
+<!ENTITY noamoauth.label "This is where collections you mark as a favorite on Mozilla Add-ons will appear so that you can easily keep track of them. You must be logged in to addons.mozilla.org to use this feature.">
+<!ENTITY username.label "Username">
+<!ENTITY password.label "Password">
+<!ENTITY clicktologin.label "Login">
+<!ENTITY createaccount.label "I don&apos;t have an account">
+<!ENTITY loginheading.label "Enter your Mozilla Add-ons account information below:">
+<!ENTITY collectionisloading.label "Retrieving subscription...">
+<!ENTITY collectionhasnoitems.label "This collection contains no add-ons.">
+<!ENTITY collectionhaserror.label "This collection cannot be displayed because it contains errors.">
+<!ENTITY publishto.label "Publish to">
+<!ENTITY email.address.label "E-mail Address">
+<!ENTITY new.email.address.label "New E-mail Address">
+<!ENTITY new.collection.label "New Collection">
diff --git a/bandwagon/locale/ja/publish.dtd b/bandwagon/locale/ja/publish.dtd
new file mode 100644
index 0000000..43c0b2f
--- /dev/null
+++ b/bandwagon/locale/ja/publish.dtd
@@ -0,0 +1,46 @@
+<!-- ***** BEGIN LICENSE BLOCK *****
+ - Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ -
+ - The contents of this file are subject to the Mozilla Public License Version
+ - 1.1 (the "License"); you may not use this file except in compliance with
+ - the License. You may obtain a copy of the License at
+ - http://www.mozilla.org/MPL/
+ -
+ - Software distributed under the License is distributed on an "AS IS" basis,
+ - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ - for the specific language governing rights and limitations under the
+ - License.
+ -
+ - The Original Code is bandwagon.
+ -
+ - The Initial Developer of the Original Code is
+ - Mozilla Corporation.
+ - Portions created by the Initial Developer are Copyright (C) 2008
+ - the Initial Developer. All Rights Reserved.
+ -
+ - Contributor(s): David McNamara
+ - Brian King <brian (at) briks (dot) si>
+ -
+ - Alternatively, the contents of this file may be used under the terms of
+ - either the GNU General Public License Version 2 or later (the "GPL"), or
+ - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ - in which case the provisions of the GPL or the LGPL are applicable instead
+ - of those above. If you wish to allow use of your version of this file only
+ - under the terms of either the GPL or the LGPL, and not to allow others to
+ - use your version of this file under the terms of the MPL, indicate your
+ - decision by deleting the provisions above and replace them with the notice
+ - and other provisions required by the GPL or the LGPL. If you do not delete
+ - the provisions above, a recipient may use your version of this file under
+ - the terms of any one of the MPL, the GPL or the LGPL.
+ -
+ - ***** END LICENSE BLOCK *****
+ -->
+<!-- For localisers to change the width of the window -->
+<!ENTITY publish.style "width: 35em;">
+<!ENTITY window.title "Publish">
+<!ENTITY cancel.label "Cancel">
+<!ENTITY publish.label "Publish">
+<!ENTITY new.email.label "New E-mail Address">
+<!ENTITY enter.an.email.label "Enter one or more e-mail addresses separated by commas:">
+<!ENTITY remember.this.email.label "Remember this e-mail address">
+<!ENTITY enter.a.personal.note.label "Optional: Enter a personal note about this add-on to be included in the e-mail">
diff --git a/bandwagon/locale/ja/publish.properties b/bandwagon/locale/ja/publish.properties
new file mode 100644
index 0000000..3ea396f
--- /dev/null
+++ b/bandwagon/locale/ja/publish.properties
@@ -0,0 +1,30 @@
+# LOCALIZATION NOTE (you.are.sharing.the.add.on):
+
+# %S is the name of an add-on
+
+you.are.sharing.the.add.on=You are sharing the add-on '%S'
+# LOCALIZATION NOTE (publishing.to):
+
+# %1 is the name of an add-on. %2 is the name of a collection
+
+publishing.to=Clicking "Publish" will add %1$S to the "%2$S" collection.
+# LOCALIZATION NOTE (sharing.with):
+
+# %1 is a user's email address. $2 is the name of an add-on
+
+sharing.with=Clicking "Send E-mail" will send %1$S an e-mail with information about %2$S
+# LOCALIZATION NOTE (sharing.with.new):
+
+# %S is the name of an add-on
+
+sharing.with.new=Clicking "Send E-mail" will send the above recipients an e-mail with information about %S
+please.enter.an.email.address=Please enter an e-mail address.
+the.addon.has.been.published=The add-on has been published.
+the.email.has.been.sent=The email has been sent.
+# LOCALIZATION NOTE (closing.in):
+
+# %S is the number of seconds until a window closes, counting down
+
+closing.in=Closing in %S...
+send.email=Send E-mail
+error.unknown_addon_guid=This add-on cannot be shared because it is not hosted on the Mozilla Add-ons website.
diff --git a/bandwagon/locale/ja/settings.dtd b/bandwagon/locale/ja/settings.dtd
new file mode 100644
index 0000000..0d9a705
--- /dev/null
+++ b/bandwagon/locale/ja/settings.dtd
@@ -0,0 +1,54 @@
+<!-- ***** BEGIN LICENSE BLOCK ***** - Version: MPL 1.1/GPL 2.0/LGPL 2.1 - - The contents of this file are subject to the Mozilla Public License Version - 1.1 (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - http://www.mozilla.org/MPL/ - - Software distributed under the License is distributed on an "AS IS" basis, - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - for the specific language governing rights and limitations under the - License. - - The Original Code is bandwagon. - - The Initial Developer of the Original Code is - Mozilla Corporation. - Portions created by the Initial Developer are Copyright (C) 2008 - the Initial Developer. All Rights Reserved. - - Contributor(s): Brian King <brian (at) briks (dot) si> - David McNamara - - Alternatively, the contents of this file may be used under the terms of - either the GNU General Public License Version 2 or later (the "GPL"), or - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - in which case the provisions of the GPL or the LGPL are applicable instead - of those above. If you wish to allow use of your version of this file only - under the terms of either the GPL or the LGPL, and not to allow others to - use your version of this file under the terms of the MPL, indicate your - decision by deleting the provisions above and replace them with the notice - and other provisions required by the GPL or the LGPL. If you do not delete - the provisions above, a recipient may use your version of this file under - the terms of any one of the MPL, the GPL or the LGPL. - - ***** END LICENSE BLOCK ***** -->
+<!-- For localisers to change the width of the window -->
+<!ENTITY settings.style "width: 42em;">
+<!ENTITY window.title "Add-on Collector Settings">
+<!-- Tabs -->
+<!ENTITY manage.label "Manage Subscriptions">
+<!ENTITY general.label "General Settings">
+<!ENTITY pub.label "Auto-publisher Settings">
+<!-- Manage Subscriptions -->
+<!ENTITY subscriptions.header "Subscriptions:">
+<!-- Groupbox captions in Manage Subscriptions -->
+<!ENTITY frequency.label "Subscription Update Frequency">
+<!ENTITY notifications.label "New Add-on Notifications">
+<!ENTITY perpage.label "Add-ons per Page">
+<!ENTITY default.label "Use default setting">
+<!ENTITY custom.label "Custom:">
+<!ENTITY addonsleadin.label "Show">
+<!ENTITY addonsperpage.label "add-ons per page">
+<!ENTITY updatesingle.label "Update every:">
+<!ENTITY minutes.label "minute(s)">
+<!ENTITY hours.label "hour(s)">
+<!ENTITY days.label "day(s)">
+<!ENTITY autopublish.label "Auto-publish installed add-ons to subscription">
+<!ENTITY notify.label "Show notifications">
+<!ENTITY applyall.label "Apply to all subscriptions">
+<!ENTITY remove.label "Remove Subscription">
+<!ENTITY on.label "On">
+<!ENTITY off.label "Off">
+<!-- General -->
+<!-- Groupbox captions in General -->
+<!ENTITY subscriptions.label "Default Subscription Settings">
+<!ENTITY data.label "Data Management">
+<!ENTITY updateall.label "Check subscriptions for updates every">
+<!ENTITY notifyglobal.label "Notify me when my subscriptions have new add-ons">
+<!ENTITY clearemails.label "Clear">
+<!ENTITY login.label "Login">
+<!ENTITY logout.label "Logout">
+<!-- Auto-Publisher Settings -->
+<!-- Groupbox captions in Auto-Publisher Settings -->
+<!ENTITY auto.label "Auto-publisher Settings">
+<!ENTITY name.label "Collection Name:">
+<!ENTITY list.label "Listed in public Collection Directory">
+<!ENTITY autoleadin.label "Auto-publishers are special collections that are automatically updated when you install or uninstall add-ons from Firefox on this computer.">
+<!ENTITY types.label "Auto-published add-on types:">
+<!ENTITY type.extensions.label "Extensions">
+<!ENTITY type.themes.label "Themes">
+<!ENTITY type.dicts.label "Dictionaries">
+<!ENTITY type.langpacks.label "Language Packs">
+<!ENTITY createauto.label "Create Auto-publisher">
+<!ENTITY deleteauto.label "Delete Auto-publisher">
+<!ENTITY updateauto.label "Update Auto-publisher">
+<!ENTITY onlypublishenabledaddons.label "Only publish enabled add-ons">
+<!ENTITY misc.label "Miscellaneous">
+<!ENTITY allowincompatibleinstall.label "Allow installation of incompatible add-ons from my subscriptions">
diff --git a/bandwagon/locale/ja/settings.properties b/bandwagon/locale/ja/settings.properties
new file mode 100644
index 0000000..bcb7b06
--- /dev/null
+++ b/bandwagon/locale/ja/settings.properties
@@ -0,0 +1,34 @@
+add.collection=Add Subscription
+enter.url.to.add.collection=Enter the URL of the subscription you want to add.
+remove.collection=Remove Subscription
+# LOCALIZATION NOTE (are.you.sure.you.want.to.remove):
+
+# %S is the name of a collection
+
+are.you.sure.you.want.to.remove=Removing this subscription will also remove the collection from your favorites list. Are you sure you wish to remove '%S'?
+# LOCALIZATION NOTE (saved.emails.text):
+
+# %S is a number
+
+saved.emails.text=You have %S saved e-mail addresses
+# LOCALIZATION NOTE (login.status.with.email):
+
+# %S is a user's email address
+
+login.status.with.email=You are logged in as %S
+login.status=You are logged in
+logout.status=You are not logged in
+# LOCALIZATION NOTE (auto.invalid.name):
+
+# %S is the name of a collection
+
+auto.invalid.name=The collection name '%S' is not valid.
+auto.please.select.type=Please select at least one add-on type to automatically publish.
+auto.create.internal.error=The collection could not be created (an internal error occurred).
+auto.create.done=Your auto-publisher collection has been created.
+auto.delete.internal.error=The collection could not be deleted (an internal error occurred).
+auto.delete.done=Your auto-publisher collection has been deleted.
+auto.create.description=An automatically generated list of my installed add-ons
+auto.update.confirm.message=Your new settings will take effect immediately, but will not affect add-ons that have already been published.
+auto.update.internal.error=The collection could not be updated (an internal error occured).
+auto.update.done=Your auto-pubisher collection has been updated.
diff --git a/bandwagon/locale/nl/bandwagon.properties b/bandwagon/locale/nl/bandwagon.properties
new file mode 100644
index 0000000..6f72538
--- /dev/null
+++ b/bandwagon/locale/nl/bandwagon.properties
@@ -0,0 +1,2 @@
+extensions.sharing@addons.mozilla.org.description=Deel en ontdek add-ons.
+extensions.sharing@addons.mozilla.org.name=Add-on Collector
diff --git a/bandwagon/locale/nl/bandwagonAddon.properties b/bandwagon/locale/nl/bandwagonAddon.properties
new file mode 100644
index 0000000..3f8d2e5
--- /dev/null
+++ b/bandwagon/locale/nl/bandwagonAddon.properties
@@ -0,0 +1,56 @@
+# LOCALIZATION NOTE (bandwagon.addon.pluralRule):
+
+# See https://developer.mozilla.org/En/Localization_and_Plurals
+
+bandwagon.addon.pluralRule=1
+bandwagon.category1=Extensie
+# LOCALIZATION NOTE (bandwagon.addon.author):
+
+# %S will contain author's first and last name, or their nickname used on AMO
+
+bandwagon.addon.author=Door %S
+# LOCALIZATION NOTE (bandwagon.addon.addedby):
+
+# %S will be a user's first and last name, or nickname
+
+bandwagon.addon.addedby=door %S
+bandwagon.addon.added.justnow=Toegevoegd: zojuist
+# LOCALIZATION NOTE:
+
+# %S will be a number of time units indicated
+
+bandwagon.addon.added.minute=Toegevoegd: een minuut geleden;Toegevoegd: %S minuten geleden
+bandwagon.addon.added.hour=Toegevoegd: een uur geleden;Toegevoegd: %S uur geleden
+bandwagon.addon.added.day=Toegevoegd: gisteren;Toegevoegd: %S dagen geleden
+bandwagon.addon.added.week=Toegevoegd: een week geleden;Toegevoegd: %S weken geleden
+bandwagon.addon.added.month=Toegevoegd: een maand geleden;Toegevoegd: %S maanden geleden
+bandwagon.addon.added.year=Toegevoegd: een jaar geleden;Toegevoegd: %S jaar geleden
+bandwagon.addon.moreinfo=Meer informatie
+bandwagon.addon.olderversionsoffirefox=Deze add-on is voor oudere versies van Firefox.
+# LOCALIZATION NOTE (upgradetofirefoxn1):
+
+# %S will be a Firefox version number
+
+bandwagon.addon.upgradetofirefoxn1=Werk Firefox bij naar versie %S
+bandwagon.addon.upgradetofirefoxn2=om deze add-on te gebruiken.
+# LOCALIZATION NOTE (bandwagon.addon.requiresfirefoxbeta1/requiresfirefoxbeta2):
+
+# %S will be a Firefox version number
+
+bandwagon.addon.requiresfirefoxbeta1=Deze add-on vereist Firefox %S, die nog niet is gereleased. Om deze add-on te gebruiken kunt u
+bandwagon.addon.requiresfirefoxbeta2=Firefox %S beta downloaden.
+# LOCALIZATION NOTE (bandwagon.addon.notcompatible):
+
+# %S will be a platform name, such as "Windows"
+
+bandwagon.addon.notcompatible=Deze add-on is niet compatibel met %S.
+# LOCALIZATION NOTE (bandwagon.addon.comment.description):
+
+# %S will be a comment entered by the publisher of the add-on
+
+bandwagon.addon.comment.description=“%Sâ€
+# LOCALIZATION NOTE (bandwagon.addon.comment.author):
+
+# %S will be the publisher's real name or nickname
+
+bandwagon.addon.comment.author=Opmerking van %S:
diff --git a/bandwagon/locale/nl/browserOverlay.dtd b/bandwagon/locale/nl/browserOverlay.dtd
new file mode 100644
index 0000000..2bd1eba
--- /dev/null
+++ b/bandwagon/locale/nl/browserOverlay.dtd
@@ -0,0 +1,3 @@
+<!-- ***** BEGIN LICENSE BLOCK ***** - Version: MPL 1.1/GPL 2.0/LGPL 2.1 - - The contents of this file are subject to the Mozilla Public License Version - 1.1 (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - http://www.mozilla.org/MPL/ - - Software distributed under the License is distributed on an "AS IS" basis, - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - for the specific language governing rights and limitations under the - License. - - The Original Code is bandwagon. - - The Initial Developer of the Original Code is - Mozilla Corporation. - Portions created by the Initial Developer are Copyright (C) 2008 - the Initial Developer. All Rights Reserved. - - Contributor(s): Brian King <brian (at) briks (dot) si> - - Alternatively, the contents of this file may be used under the terms of - either the GNU General Public License Version 2 or later (the "GPL"), or - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - in which case the provisions of the GPL or the LGPL are applicable instead - of those above. If you wish to allow use of your version of this file only - under the terms of either the GPL or the LGPL, and not to allow others to - use your version of this file under the terms of the MPL, indicate your - decision by deleting the provisions above and replace them with the notice - and other provisions required by the GPL or the LGPL. If you do not delete - the provisions above, a recipient may use your version of this file under - the terms of any one of the MPL, the GPL or the LGPL. - - ***** END LICENSE BLOCK ***** -->
+<!ENTITY bandwagon.label "Add-ons">
+<!ENTITY bandwagon.tooltip "Add-ons">
diff --git a/bandwagon/locale/nl/browserOverlay.properties b/bandwagon/locale/nl/browserOverlay.properties
new file mode 100644
index 0000000..08e64c3
--- /dev/null
+++ b/bandwagon/locale/nl/browserOverlay.properties
@@ -0,0 +1,6 @@
+newaddons.alert.title=Nieuwe add-ons
+# LOCALIZATION NOTE (newaddons.alert.text):
+
+# %S will be the name of a collection
+
+newaddons.alert.text=Er zijn nieuwe add-ons in uw abonnement “%Sâ€.
diff --git a/bandwagon/locale/nl/contents.rdf b/bandwagon/locale/nl/contents.rdf
new file mode 100644
index 0000000..344c73b
--- /dev/null
+++ b/bandwagon/locale/nl/contents.rdf
@@ -0,0 +1,15 @@
+<?xml version="1.0"?>
+<RDF:RDF xmlns:RDF="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:chrome="http://www.mozilla.org/rdf/chrome#">
+ <RDF:Seq about="urn:mozilla:locale:root">
+ <RDF:li resource="urn:mozilla:locale:nl"/>
+ </RDF:Seq>
+ <RDF:Description about="urn:mozilla:locale:nl" chrome:name="nl" >
+ <chrome:packages>
+ <RDF:Seq about="urn:mozilla:locale:nl:packages">
+ <RDF:li resource="urn:mozilla:locale:nl:bandwagon"/>
+ </RDF:Seq>
+ </chrome:packages>
+ </RDF:Description>
+</RDF:RDF>
+
diff --git a/bandwagon/locale/nl/extensionOverlay.properties b/bandwagon/locale/nl/extensionOverlay.properties
new file mode 100644
index 0000000..10c6a8a
--- /dev/null
+++ b/bandwagon/locale/nl/extensionOverlay.properties
@@ -0,0 +1,16 @@
+publish.new.email.address.title=Nieuw e-mailadres
+publish.new.email.address.text=Voer een nieuw e-mailadres in om deze add-on mee te delen:
+publish.remove.title=Bevestigen
+# LOCALIZATION NOTE (publish.remove.label):
+
+# %1 is the name of an add-on. %2 is the name of a collection
+
+publish.remove.label=Weet u zeker dat u %1$S wilt verwijderen uit de collectie “%2$S�
+publish.remove.button1=Nee, annuleren
+publish.remove.button0=Ja, add-on verwijderen
+login.error=Er is een fout opgetreden bij het inloggen. Controleer a.u.b. of uw gebruikersnaam en wachtwoord correct zijn.
+unsubscribe.error=Er is een fout opgetreden bij het opheffen van het abonnement op deze collectie. Probeer het later a.u.b. nog eens.
+unsubscribe.confirm.title=Uitschrijven bevestigen
+unsubscribe.confirm.label=Het opheffen van het abonnement op deze collectie verwijdert deze ook uit uw favorietenlijst. Weet u zeker dat u zich wilt uitschrijven?
+unsubscribe.confirm.button1=Nee annuleren
+unsubscribe.confirm.button0=Ja, uitschrijven
diff --git a/bandwagon/locale/nl/extensionsOverlay.dtd b/bandwagon/locale/nl/extensionsOverlay.dtd
new file mode 100644
index 0000000..710c3c6
--- /dev/null
+++ b/bandwagon/locale/nl/extensionsOverlay.dtd
@@ -0,0 +1,26 @@
+<!-- ***** BEGIN LICENSE BLOCK ***** - Version: MPL 1.1/GPL 2.0/LGPL 2.1 - - The contents of this file are subject to the Mozilla Public License Version - 1.1 (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - http://www.mozilla.org/MPL/ - - Software distributed under the License is distributed on an "AS IS" basis, - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - for the specific language governing rights and limitations under the - License. - - The Original Code is bandwagon. - - The Initial Developer of the Original Code is - Mozilla Corporation. - Portions created by the Initial Developer are Copyright (C) 2008 - the Initial Developer. All Rights Reserved. - - Contributor(s): Brian King <brian (at) briks (dot) si> - David McNamara - - Alternatively, the contents of this file may be used under the terms of - either the GNU General Public License Version 2 or later (the "GPL"), or - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - in which case the provisions of the GPL or the LGPL are applicable instead - of those above. If you wish to allow use of your version of this file only - under the terms of either the GPL or the LGPL, and not to allow others to - use your version of this file under the terms of the MPL, indicate your - decision by deleting the provisions above and replace them with the notice - and other provisions required by the GPL or the LGPL. If you do not delete - the provisions above, a recipient may use your version of this file under - the terms of any one of the MPL, the GPL or the LGPL. - - ***** END LICENSE BLOCK ***** -->
+<!ENTITY collections.label "Abonnementen">
+<!ENTITY search.label.bandwagon "Zoeken">
+<!ENTITY addon.moreinfo "Meer informatie">
+<!ENTITY addon.addtofirefox "Aan Firefox toevoegen">
+<!ENTITY subscribe.label "Collecties zoeken">
+<!ENTITY reload.label "Alles opnieuw laden">
+<!ENTITY settings.label "Instellingen">
+<!ENTITY view.label "Collectie bekijken">
+<!ENTITY unsubscribe.label "Abonnement opzeggen">
+<!ENTITY nocollectionstitle.label "Welkom bij de Add-on Collector">
+<!ENTITY nocollectionssubscribed.label "Hier zullen door u op Mozilla Add-ons als favoriet gemarkeerde collecties verschijnen, zodat u ze gemakkelijk kunt volgen. Het lijkt er op dat u nog geen favorieten hebt toegevoegd, dus waarom neemt u geen kijkje in onze Collectiemap?">
+<!ENTITY clicktosubscribe.label "Collecties zoeken">
+<!ENTITY noamoauth.label "Hier zullen door u op Mozilla Add-ons als favoriet gemarkeerde collecties verschijnen, zodat u ze gemakkelijk kunt volgen. U dient ingelogd te zijn op addons.mozilla.org om deze functie te kunnen gebruiken.">
+<!ENTITY username.label "E-mailadres">
+<!ENTITY password.label "Wachtwoord">
+<!ENTITY clicktologin.label "Inloggen">
+<!ENTITY createaccount.label "Ik heb geen account">
+<!ENTITY loginheading.label "Voer hieronder de informatie van uw account bij Mozilla Add-ons in:">
+<!ENTITY collectionisloading.label "Abonnement ophalen…">
+<!ENTITY collectionhasnoitems.label "Deze collectie bevat geen add-ons.">
+<!ENTITY collectionhaserror.label "Deze collectie kan niet worden weergegeven omdat deze fouten bevat.">
+<!ENTITY publishto.label "Publiceren naar">
+<!ENTITY email.address.label "E-mailadres">
+<!ENTITY new.email.address.label "Nieuw e-mailadres">
+<!ENTITY new.collection.label "Nieuwe collectie">
diff --git a/bandwagon/locale/nl/publish.dtd b/bandwagon/locale/nl/publish.dtd
new file mode 100644
index 0000000..d9d7de1
--- /dev/null
+++ b/bandwagon/locale/nl/publish.dtd
@@ -0,0 +1,48 @@
+<!-- ***** BEGIN LICENSE BLOCK *****
+ - Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ -
+ - The contents of this file are subject to the Mozilla Public License Version
+ - 1.1 (the "License"); you may not use this file except in compliance with
+ - the License. You may obtain a copy of the License at
+ - http://www.mozilla.org/MPL/
+ -
+ - Software distributed under the License is distributed on an "AS IS" basis,
+ - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ - for the specific language governing rights and limitations under the
+ - License.
+ -
+ - The Original Code is bandwagon.
+ -
+ - The Initial Developer of the Original Code is
+ - Mozilla Corporation.
+ - Portions created by the Initial Developer are Copyright (C) 2008
+ - the Initial Developer. All Rights Reserved.
+ -
+ - Contributor(s): David McNamara
+ - Brian King <brian (at) briks (dot) si>
+ -
+ - Alternatively, the contents of this file may be used under the terms of
+ - either the GNU General Public License Version 2 or later (the "GPL"), or
+ - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ - in which case the provisions of the GPL or the LGPL are applicable instead
+ - of those above. If you wish to allow use of your version of this file only
+ - under the terms of either the GPL or the LGPL, and not to allow others to
+ - use your version of this file under the terms of the MPL, indicate your
+ - decision by deleting the provisions above and replace them with the notice
+ - and other provisions required by the GPL or the LGPL. If you do not delete
+ - the provisions above, a recipient may use your version of this file under
+ - the terms of any one of the MPL, the GPL or the LGPL.
+ -
+ - ***** END LICENSE BLOCK *****
+
+
+ -->
+<!-- For localisers to change the width of the window -->
+<!ENTITY publish.style "width: 35em;">
+<!ENTITY window.title "Publiceren">
+<!ENTITY cancel.label "Annuleren">
+<!ENTITY publish.label "Publiceren">
+<!ENTITY new.email.label "Nieuw e-mailadres">
+<!ENTITY enter.an.email.label "Voer één of meerdere e-mailadressen in, gescheiden door komma’s:">
+<!ENTITY remember.this.email.label "Dit e-mailadres onthouden">
+<!ENTITY enter.a.personal.note.label "Optioneel: Voer een persoonlijke opmerking over deze add-on in die wordt opgenomen in het e-mailbericht">
diff --git a/bandwagon/locale/nl/publish.properties b/bandwagon/locale/nl/publish.properties
new file mode 100644
index 0000000..204b592
--- /dev/null
+++ b/bandwagon/locale/nl/publish.properties
@@ -0,0 +1,30 @@
+# LOCALIZATION NOTE (you.are.sharing.the.add.on):
+
+# %S is the name of an add-on
+
+you.are.sharing.the.add.on=U deelt de add-on ‘%S’
+# LOCALIZATION NOTE (publishing.to):
+
+# %1 is the name of an add-on. %2 is the name of a collection
+
+publishing.to=Door op “Publiceren†te klikken wordt %1$S toegevoegd aan de collectie “%2$Sâ€.
+# LOCALIZATION NOTE (sharing.with):
+
+# %1 is a user's email address. $2 is the name of an add-on
+
+sharing.with=Door op “E-mailbericht verzenden†te klikken wordt een e-mailbericht verzonden aan %1$S over %2$S
+# LOCALIZATION NOTE (sharing.with.new):
+
+# %S is the name of an add-on
+
+sharing.with.new=Door op “E-mailbericht verzenden†te klikken wordt aan bovenstaande ontvangers een e-mailbericht verzonden met informatie over %S
+please.enter.an.email.address=Voer a.u.b. een e-mailadres in.
+the.addon.has.been.published=De add-on is gepubliceerd.
+the.email.has.been.sent=Het e-mailbericht is verzonden.
+# LOCALIZATION NOTE (closing.in):
+
+# %S is the number of seconds until a window closes, counting down
+
+closing.in=Afsluiten over %S…
+send.email=E-mailbericht verzenden
+error.unknown_addon_guid=Deze add-on kan niet worden gedeeld omdat deze niet wordt gehost op de Mozilla Add-onswebsite.
diff --git a/bandwagon/locale/nl/settings.dtd b/bandwagon/locale/nl/settings.dtd
new file mode 100644
index 0000000..8116b0e
--- /dev/null
+++ b/bandwagon/locale/nl/settings.dtd
@@ -0,0 +1,54 @@
+<!-- ***** BEGIN LICENSE BLOCK ***** - Version: MPL 1.1/GPL 2.0/LGPL 2.1 - - The contents of this file are subject to the Mozilla Public License Version - 1.1 (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - http://www.mozilla.org/MPL/ - - Software distributed under the License is distributed on an "AS IS" basis, - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - for the specific language governing rights and limitations under the - License. - - The Original Code is bandwagon. - - The Initial Developer of the Original Code is - Mozilla Corporation. - Portions created by the Initial Developer are Copyright (C) 2008 - the Initial Developer. All Rights Reserved. - - Contributor(s): Brian King <brian (at) briks (dot) si> - David McNamara - - Alternatively, the contents of this file may be used under the terms of - either the GNU General Public License Version 2 or later (the "GPL"), or - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - in which case the provisions of the GPL or the LGPL are applicable instead - of those above. If you wish to allow use of your version of this file only - under the terms of either the GPL or the LGPL, and not to allow others to - use your version of this file under the terms of the MPL, indicate your - decision by deleting the provisions above and replace them with the notice - and other provisions required by the GPL or the LGPL. If you do not delete - the provisions above, a recipient may use your version of this file under - the terms of any one of the MPL, the GPL or the LGPL. - - ***** END LICENSE BLOCK ***** -->
+<!-- For localisers to change the width of the window -->
+<!ENTITY settings.style "width: 42em;">
+<!ENTITY window.title "Add-on Collector instellingen">
+<!-- Tabs -->
+<!ENTITY manage.label "Abonnementen beheren">
+<!ENTITY general.label "Algemene instellingen">
+<!ENTITY pub.label "Instellingen voor autopublicatie">
+<!-- Manage Subscriptions -->
+<!ENTITY subscriptions.header "Abonnementen:">
+<!-- Groupbox captions in Manage Subscriptions -->
+<!ENTITY frequency.label "Updatefrequentie abonnementen">
+<!ENTITY notifications.label "Notificaties van nieuwe add-ons">
+<!ENTITY perpage.label "Add-ons per pagina">
+<!ENTITY default.label "Standaardinstelling gebruiken">
+<!ENTITY custom.label "Aangepast:">
+<!ENTITY addonsleadin.label "Tot">
+<!ENTITY addonsperpage.label "add-ons per pagina weergeven">
+<!ENTITY updatesingle.label "Bijwerken: elke">
+<!ENTITY minutes.label "minu(u)t(en)">
+<!ENTITY hours.label "uur">
+<!ENTITY days.label "dag(en)">
+<!ENTITY autopublish.label "Geïnstalleerde add-ons automatisch naar abonnement publiceren">
+<!ENTITY notify.label "Notificaties weergeven">
+<!ENTITY applyall.label "Toepassen op alle abonnementen">
+<!ENTITY remove.label "Abonnement verwijderen">
+<!ENTITY on.label "Aan">
+<!ENTITY off.label "Uit">
+<!-- General -->
+<!-- Groupbox captions in General -->
+<!ENTITY subscriptions.label "Standaard abonnementinstellingen">
+<!ENTITY data.label "Gegevensbeheer">
+<!ENTITY updateall.label "Abonnementen controleren op updates: elke">
+<!ENTITY notifyglobal.label "Mij berichten wanneer abonnementen nieuwe add-ons bevatten">
+<!ENTITY clearemails.label "Wissen">
+<!ENTITY login.label "Inloggen">
+<!ENTITY logout.label "Afmelden">
+<!-- Auto-Publisher Settings -->
+<!-- Groupbox captions in Auto-Publisher Settings -->
+<!ENTITY auto.label "Instellingen autopublicatie">
+<!ENTITY name.label "Collectienaam:">
+<!ENTITY list.label "Vermeld in publieke Collectiemap">
+<!ENTITY autoleadin.label "Autopublicaties zijn speciale collecties die automatisch worden bijgewerkt wanneer u add-ons installeert of deïnstalleert in Firefox op deze computer.">
+<!ENTITY types.label "Automatisch gepubliceerde add-ontypes:">
+<!ENTITY type.extensions.label "Extensies">
+<!ENTITY type.themes.label "Thema’s">
+<!ENTITY type.dicts.label "Woordenboeken">
+<!ENTITY type.langpacks.label "Taalpakketten">
+<!ENTITY createauto.label "Autopublicatie aanmaken">
+<!ENTITY deleteauto.label "Autopublicatie verwijderen">
+<!ENTITY updateauto.label "Autopublicatie bijwerken">
+<!ENTITY onlypublishenabledaddons.label "Alleen ingeschakelde add-ons publiceren">
+<!ENTITY misc.label "Diversen">
+<!ENTITY allowincompatibleinstall.label "Installatie van incompatibele add-ons in mijn abonnementen toestaan">
diff --git a/bandwagon/locale/nl/settings.properties b/bandwagon/locale/nl/settings.properties
new file mode 100644
index 0000000..ca8d6a1
--- /dev/null
+++ b/bandwagon/locale/nl/settings.properties
@@ -0,0 +1,34 @@
+add.collection=Abonnement toevoegen
+enter.url.to.add.collection=Voer de URL in van het abonnement dat u wilt toevoegen.
+remove.collection=Abonnement opzeggen
+# LOCALIZATION NOTE (are.you.sure.you.want.to.remove):
+
+# %S is the name of a collection
+
+are.you.sure.you.want.to.remove=Door opzeggen van dit abonnement wordt ook de collectie uit uw favorietenlijst verwijderd. Weet u zeker dat u ‘%S’ wilt verwijderen?
+# LOCALIZATION NOTE (saved.emails.text):
+
+# %S is a number
+
+saved.emails.text=U hebt %S opgeslagen e-mailadressen
+# LOCALIZATION NOTE (login.status.with.email):
+
+# %S is a user's email address
+
+login.status.with.email=U bent ingelogd als %S
+login.status=U bent ingelogd
+logout.status=U bent niet ingelogd
+# LOCALIZATION NOTE (auto.invalid.name):
+
+# %S is the name of a collection
+
+auto.invalid.name=De collectienaam ‘%S’ is ongeldig.
+auto.please.select.type=Selecteer a.u.b. ten minste één add-ontype om automatisch te publiceren.
+auto.create.internal.error=De collectie kon niet worden aangemaakt (er is een interne fout opgetreden).
+auto.create.done=Uw collectie voor automatisch publiceren is aangemaakt.
+auto.delete.internal.error=De collectie kon niet worden verwijderd (er is een interne fout opgetreden).
+auto.delete.done=Uw collectie voor automatisch publiceren is verwijderd.
+auto.create.description=Een automatisch aangemaakte lijst van mijn geïnstalleerde add-ons
+auto.update.confirm.message=Uw nieuwe instellingen worden direct doorgevoerd, maar hebben geen effect op add-ons die al zijn gepubliceerd.
+auto.update.internal.error=De collectie kan niet worden bijgewerkt (er is een interne fout opgetreden).
+auto.update.done=Uw collectie voor automatisch publiceren is bijgewerkt.
diff --git a/bandwagon/locale/pl/bandwagon.properties b/bandwagon/locale/pl/bandwagon.properties
new file mode 100644
index 0000000..75dc387
--- /dev/null
+++ b/bandwagon/locale/pl/bandwagon.properties
@@ -0,0 +1,2 @@
+extensions.sharing@addons.mozilla.org.description=Odkrywaj i udostępniaj dodatki.
+extensions.sharing@addons.mozilla.org.name=Add-on Collector
diff --git a/bandwagon/locale/pl/bandwagonAddon.properties b/bandwagon/locale/pl/bandwagonAddon.properties
new file mode 100644
index 0000000..2a34c50
--- /dev/null
+++ b/bandwagon/locale/pl/bandwagonAddon.properties
@@ -0,0 +1,56 @@
+# LOCALIZATION NOTE (bandwagon.addon.pluralRule):
+
+# See https://developer.mozilla.org/En/Localization_and_Plurals
+
+bandwagon.addon.pluralRule=9
+bandwagon.category1=Rozszerzenie
+# LOCALIZATION NOTE (bandwagon.addon.author):
+
+# %S will contain author's first and last name, or their nickname used on AMO
+
+bandwagon.addon.author=Autor: %S
+# LOCALIZATION NOTE (bandwagon.addon.addedby):
+
+# %S will be a user's first and last name, or nickname
+
+bandwagon.addon.addedby=dodany przez %S
+bandwagon.addon.added.justnow=Dodano: teraz
+# LOCALIZATION NOTE:
+
+# %S will be a number of time units indicated
+
+bandwagon.addon.added.minute=Dodano: minutÄ™ temu;Dodano: %S minuty temu;Dodano: %S minut temu
+bandwagon.addon.added.hour=Dodano: godzinÄ™ temu;Dodano: %S godziny temu;Dodano: %S godzin temu
+bandwagon.addon.added.day=Dodano: wczoraj;Dodano: %S dni temu;Dodano: %S dni temu
+bandwagon.addon.added.week=Dodano: tydzień temu;Dodano: %S tygodnie temu;Dodano: %S tygodni temu
+bandwagon.addon.added.month=Dodano: miesiąc temu;Dodano: %S miesiące temu;Dodano: %S miesięcy temu
+bandwagon.addon.added.year=Dodano: rok temu;Dodano: $S lata temu;Dodano: $S lat temu
+bandwagon.addon.moreinfo=Więcej informacji.
+bandwagon.addon.olderversionsoffirefox=Ten dodatek jest dla starszych wersji Firefoksa.
+# LOCALIZATION NOTE (upgradetofirefoxn1):
+
+# %S will be a Firefox version number
+
+bandwagon.addon.upgradetofirefoxn1=Zaktualizuj Firefoksa do wersji $S,
+bandwagon.addon.upgradetofirefoxn2=aby używać tego dodatku.
+# LOCALIZATION NOTE (bandwagon.addon.requiresfirefoxbeta1/requiresfirefoxbeta2):
+
+# %S will be a Firefox version number
+
+bandwagon.addon.requiresfirefoxbeta1=Ten dodatek jest przeznaczony do Firefoksa %S, który nie został jeszcze wydany. Aby używać tego dodatku, możesz
+bandwagon.addon.requiresfirefoxbeta2=pobrać Firefoksa %S beta.
+# LOCALIZATION NOTE (bandwagon.addon.notcompatible):
+
+# %S will be a platform name, such as "Windows"
+
+bandwagon.addon.notcompatible=Ten dodatek jest kompatybilny z systemem %S.
+# LOCALIZATION NOTE (bandwagon.addon.comment.description):
+
+# %S will be a comment entered by the publisher of the add-on
+
+bandwagon.addon.comment.description=„%Sâ€
+# LOCALIZATION NOTE (bandwagon.addon.comment.author):
+
+# %S will be the publisher's real name or nickname
+
+bandwagon.addon.comment.author=Komentarz dodany przez %S:
diff --git a/bandwagon/locale/pl/browserOverlay.dtd b/bandwagon/locale/pl/browserOverlay.dtd
new file mode 100644
index 0000000..5f3aa6c
--- /dev/null
+++ b/bandwagon/locale/pl/browserOverlay.dtd
@@ -0,0 +1,39 @@
+<!-- ***** BEGIN LICENSE BLOCK *****
+ - Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ -
+ - The contents of this file are subject to the Mozilla Public License Version
+ - 1.1 (the "License"); you may not use this file except in compliance with
+ - the License. You may obtain a copy of the License at
+ - http://www.mozilla.org/MPL/
+ -
+ - Software distributed under the License is distributed on an "AS IS" basis,
+ - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ - for the specific language governing rights and limitations under the
+ - License.
+ -
+ - The Original Code is bandwagon.
+ -
+ - The Initial Developer of the Original Code is
+ - Mozilla Corporation.
+ - Portions created by the Initial Developer are Copyright (C) 2008
+ - the Initial Developer. All Rights Reserved.
+ -
+ - Contributor(s): Brian King <brian (at) briks (dot) si>
+ -
+ - Alternatively, the contents of this file may be used under the terms of
+ - either the GNU General Public License Version 2 or later (the "GPL"), or
+ - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ - in which case the provisions of the GPL or the LGPL are applicable instead
+ - of those above. If you wish to allow use of your version of this file only
+ - under the terms of either the GPL or the LGPL, and not to allow others to
+ - use your version of this file under the terms of the MPL, indicate your
+ - decision by deleting the provisions above and replace them with the notice
+ - and other provisions required by the GPL or the LGPL. If you do not delete
+ - the provisions above, a recipient may use your version of this file under
+ - the terms of any one of the MPL, the GPL or the LGPL.
+ -
+ - ***** END LICENSE BLOCK *****
+
+ -->
+<!ENTITY bandwagon.label "Dodatki">
+<!ENTITY bandwagon.tooltip "Dodatki">
diff --git a/bandwagon/locale/pl/browserOverlay.properties b/bandwagon/locale/pl/browserOverlay.properties
new file mode 100644
index 0000000..c0e0111
--- /dev/null
+++ b/bandwagon/locale/pl/browserOverlay.properties
@@ -0,0 +1,6 @@
+newaddons.alert.title=Nowe dodatki
+# LOCALIZATION NOTE (newaddons.alert.text):
+
+# %S will be the name of a collection
+
+newaddons.alert.text=W subskrybowanej przez Ciebie kolekcji „%S†są nowe dodatki.
diff --git a/bandwagon/locale/pl/contents.rdf b/bandwagon/locale/pl/contents.rdf
new file mode 100644
index 0000000..dd03615
--- /dev/null
+++ b/bandwagon/locale/pl/contents.rdf
@@ -0,0 +1,15 @@
+<?xml version="1.0"?>
+<RDF:RDF xmlns:RDF="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:chrome="http://www.mozilla.org/rdf/chrome#">
+ <RDF:Seq about="urn:mozilla:locale:root">
+ <RDF:li resource="urn:mozilla:locale:pl"/>
+ </RDF:Seq>
+ <RDF:Description about="urn:mozilla:locale:pl-PL" chrome:name="pl" >
+ <chrome:packages>
+ <RDF:Seq about="urn:mozilla:locale:pl:packages">
+ <RDF:li resource="urn:mozilla:locale:pl:bandwagon"/>
+ </RDF:Seq>
+ </chrome:packages>
+ </RDF:Description>
+</RDF:RDF>
+
diff --git a/bandwagon/locale/pl/extensionOverlay.properties b/bandwagon/locale/pl/extensionOverlay.properties
new file mode 100644
index 0000000..8d323a1
--- /dev/null
+++ b/bandwagon/locale/pl/extensionOverlay.properties
@@ -0,0 +1,16 @@
+publish.new.email.address.title=Nowy adres e-mail
+publish.new.email.address.text=Wprowadź adres e-mail, aby udostępnić ten dodatek:
+publish.remove.title=Potwierdzenie
+# LOCALIZATION NOTE (publish.remove.label):
+
+# %1 is the name of an add-on. %2 is the name of a collection
+
+publish.remove.label=Czy na pewno chcesz usunąć %1$S z kolekcji „%2$S�
+publish.remove.button1=Anuluj
+publish.remove.button0=Usuń
+login.error=W trakcie logowania wystąpił błąd. Sprawdź poprawność nazwy użytkownika i hasła.
+unsubscribe.error=W trakcie rezygnowania z subskrypcji wystąpił błąd. Spróbuj ponownie później.
+unsubscribe.confirm.title=Potwierdzenie rezygnacji z subskrypcji
+unsubscribe.confirm.label=Rezygnacja z subskrybowania tej kolekcji spowoduje usunięcie jej z Twojej listy ulubionych. Czy na pewno chcesz zrezygnować?
+unsubscribe.confirm.button1=Nie
+unsubscribe.confirm.button0=Tak
diff --git a/bandwagon/locale/pl/extensionsOverlay.dtd b/bandwagon/locale/pl/extensionsOverlay.dtd
new file mode 100644
index 0000000..3146309
--- /dev/null
+++ b/bandwagon/locale/pl/extensionsOverlay.dtd
@@ -0,0 +1,63 @@
+<!-- ***** BEGIN LICENSE BLOCK *****
+ - Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ -
+ - The contents of this file are subject to the Mozilla Public License Version
+ - 1.1 (the "License"); you may not use this file except in compliance with
+ - the License. You may obtain a copy of the License at
+ - http://www.mozilla.org/MPL/
+ -
+ - Software distributed under the License is distributed on an "AS IS" basis,
+ - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ - for the specific language governing rights and limitations under the
+ - License.
+ -
+ - The Original Code is bandwagon.
+ -
+ - The Initial Developer of the Original Code is
+ - Mozilla Corporation.
+ - Portions created by the Initial Developer are Copyright (C) 2008
+ - the Initial Developer. All Rights Reserved.
+ -
+ - Contributor(s): Brian King <brian (at) briks (dot) si>
+ - David McNamara
+ -
+ - Alternatively, the contents of this file may be used under the terms of
+ - either the GNU General Public License Version 2 or later (the "GPL"), or
+ - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ - in which case the provisions of the GPL or the LGPL are applicable instead
+ - of those above. If you wish to allow use of your version of this file only
+ - under the terms of either the GPL or the LGPL, and not to allow others to
+ - use your version of this file under the terms of the MPL, indicate your
+ - decision by deleting the provisions above and replace them with the notice
+ - and other provisions required by the GPL or the LGPL. If you do not delete
+ - the provisions above, a recipient may use your version of this file under
+ - the terms of any one of the MPL, the GPL or the LGPL.
+ -
+ - ***** END LICENSE BLOCK *****
+
+ -->
+<!ENTITY collections.label "Subskrypcje">
+<!ENTITY search.label.bandwagon "Pobierz dodatki">
+<!ENTITY addon.moreinfo "Więcej informacji.">
+<!ENTITY addon.addtofirefox "Dodaj do Firefoksa">
+<!ENTITY subscribe.label "Szukaj kolekcji">
+<!ENTITY reload.label "Odśwież wszystko">
+<!ENTITY settings.label "Ustawienia">
+<!ENTITY view.label "Zobacz kolekcjÄ™">
+<!ENTITY unsubscribe.label "Rezygnuj z subskrypcji">
+<!ENTITY nocollectionstitle.label "Witamy w kolekcjonerze dodatków">
+<!ENTITY nocollectionssubscribed.label "Jest to miejsce, gdzie będą wyświetlane kolekcje oznaczone przez Ciebie na stronie dodatków Mozilli jako ulubione. Z tego miejsca można łatwo je śledzić. Wygląda na to, że jeszcze nie masz ulubionych dodatków, więc skorzystaj z naszego katalogu kolekcji.">
+<!ENTITY clicktosubscribe.label "Szukaj kolekcji">
+<!ENTITY noamoauth.label "Jest to miejsce, gdzie będą wyświetlane kolekcje oznaczone przez Ciebie na stronie dodatków Mozilli jako ulubione. Z tego miejsca można łatwo je śledzić. Aby używać tej funkcji musisz zalogować się na witrynie addons.mozilla.org.">
+<!ENTITY username.label "Nazwa użytkownika">
+<!ENTITY password.label "Hasło">
+<!ENTITY clicktologin.label "Zaloguj siÄ™">
+<!ENTITY createaccount.label "Nie mam konta">
+<!ENTITY loginheading.label "Wprowadź poniżej dane twojego konta na Mozilla Add-ons:">
+<!ENTITY collectionisloading.label "Pobieranie kolekcji…">
+<!ENTITY collectionhasnoitems.label "Ta kolekcja nie zawiera dodatków.">
+<!ENTITY collectionhaserror.label "Ta kolekcja nie może zostać wyświetlona ponieważ zawiera błędy.">
+<!ENTITY publishto.label "Wyślij do">
+<!ENTITY email.address.label "Adres e-mail">
+<!ENTITY new.email.address.label "Adres e-mail">
+<!ENTITY new.collection.label "Nowa kolekcja">
diff --git a/bandwagon/locale/pl/publish.dtd b/bandwagon/locale/pl/publish.dtd
new file mode 100644
index 0000000..7e77b6c
--- /dev/null
+++ b/bandwagon/locale/pl/publish.dtd
@@ -0,0 +1,47 @@
+<!-- ***** BEGIN LICENSE BLOCK *****
+ - Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ -
+ - The contents of this file are subject to the Mozilla Public License Version
+ - 1.1 (the "License"); you may not use this file except in compliance with
+ - the License. You may obtain a copy of the License at
+ - http://www.mozilla.org/MPL/
+ -
+ - Software distributed under the License is distributed on an "AS IS" basis,
+ - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ - for the specific language governing rights and limitations under the
+ - License.
+ -
+ - The Original Code is bandwagon.
+ -
+ - The Initial Developer of the Original Code is
+ - Mozilla Corporation.
+ - Portions created by the Initial Developer are Copyright (C) 2008
+ - the Initial Developer. All Rights Reserved.
+ -
+ - Contributor(s): David McNamara
+ - Brian King <brian (at) briks (dot) si>
+ -
+ - Alternatively, the contents of this file may be used under the terms of
+ - either the GNU General Public License Version 2 or later (the "GPL"), or
+ - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ - in which case the provisions of the GPL or the LGPL are applicable instead
+ - of those above. If you wish to allow use of your version of this file only
+ - under the terms of either the GPL or the LGPL, and not to allow others to
+ - use your version of this file under the terms of the MPL, indicate your
+ - decision by deleting the provisions above and replace them with the notice
+ - and other provisions required by the GPL or the LGPL. If you do not delete
+ - the provisions above, a recipient may use your version of this file under
+ - the terms of any one of the MPL, the GPL or the LGPL.
+ -
+ - ***** END LICENSE BLOCK *****
+
+ -->
+<!-- For localisers to change the width of the window -->
+<!ENTITY publish.style "width: 35em;">
+<!ENTITY window.title "Publikowanie">
+<!ENTITY cancel.label "Anuluj">
+<!ENTITY publish.label "Publikuj">
+<!ENTITY new.email.label "Adres e-mail">
+<!ENTITY enter.an.email.label "Wprowadź jeden lub kilka adresów e-mail oddzielając je przecinkami:">
+<!ENTITY remember.this.email.label "Zapamiętaj te adresy">
+<!ENTITY enter.a.personal.note.label "Opcjonalne: Wprowadź swoje uwagi dotyczące tego dodatku. Zostaną one dołączone do wiadomości.">
diff --git a/bandwagon/locale/pl/publish.properties b/bandwagon/locale/pl/publish.properties
new file mode 100644
index 0000000..a519c75
--- /dev/null
+++ b/bandwagon/locale/pl/publish.properties
@@ -0,0 +1,30 @@
+# LOCALIZATION NOTE (you.are.sharing.the.add.on):
+
+# %S is the name of an add-on
+
+you.are.sharing.the.add.on=UdostÄ™pniasz dodatek „%Sâ€
+# LOCALIZATION NOTE (publishing.to):
+
+# %1 is the name of an add-on. %2 is the name of a collection
+
+publishing.to=NaciÅ›niÄ™cie przycisku „Publikuj†spowoduje dodanie %1$S do kolekcji „%2$Sâ€.
+# LOCALIZATION NOTE (sharing.with):
+
+# %1 is a user's email address. $2 is the name of an add-on
+
+sharing.with=Naciśnięcie przycisku „Wyślij†spowoduje wysłanie %1$S wiadomości z informacją o %2$S
+# LOCALIZATION NOTE (sharing.with.new):
+
+# %S is the name of an add-on
+
+sharing.with.new=Naciśnięcie przycisku „Wyślij†spowoduje wysłanie powyższym odbiorcom wiadomości z informacją o %S
+please.enter.an.email.address=Wprowadź adres e-mail
+the.addon.has.been.published=Dodatek został opublikowany.
+the.email.has.been.sent=Wiadomość została wysłana.
+# LOCALIZATION NOTE (closing.in):
+
+# %S is the number of seconds until a window closes, counting down
+
+closing.in=Zamknięcie nastąpi za %S…
+send.email=Wyślij
+error.unknown_addon_guid=Tego dodatku nie można udostępnić, ponieważ nie jest przechowywany na witrynie dodatków Mozilli.
diff --git a/bandwagon/locale/pl/settings.dtd b/bandwagon/locale/pl/settings.dtd
new file mode 100644
index 0000000..bd1e71f
--- /dev/null
+++ b/bandwagon/locale/pl/settings.dtd
@@ -0,0 +1,91 @@
+<!-- ***** BEGIN LICENSE BLOCK *****
+ - Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ -
+ - The contents of this file are subject to the Mozilla Public License Version
+ - 1.1 (the "License"); you may not use this file except in compliance with
+ - the License. You may obtain a copy of the License at
+ - http://www.mozilla.org/MPL/
+ -
+ - Software distributed under the License is distributed on an "AS IS" basis,
+ - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ - for the specific language governing rights and limitations under the
+ - License.
+ -
+ - The Original Code is bandwagon.
+ -
+ - The Initial Developer of the Original Code is
+ - Mozilla Corporation.
+ - Portions created by the Initial Developer are Copyright (C) 2008
+ - the Initial Developer. All Rights Reserved.
+ -
+ - Contributor(s): Brian King <brian (at) briks (dot) si>
+ - David McNamara
+ -
+ - Alternatively, the contents of this file may be used under the terms of
+ - either the GNU General Public License Version 2 or later (the "GPL"), or
+ - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ - in which case the provisions of the GPL or the LGPL are applicable instead
+ - of those above. If you wish to allow use of your version of this file only
+ - under the terms of either the GPL or the LGPL, and not to allow others to
+ - use your version of this file under the terms of the MPL, indicate your
+ - decision by deleting the provisions above and replace them with the notice
+ - and other provisions required by the GPL or the LGPL. If you do not delete
+ - the provisions above, a recipient may use your version of this file under
+ - the terms of any one of the MPL, the GPL or the LGPL.
+ -
+ - ***** END LICENSE BLOCK *****
+
+ -->
+<!-- For localisers to change the width of the window -->
+<!ENTITY settings.style "width: 77.5ex;">
+<!ENTITY window.title "Kolekcjoner dodatków - ustawienia">
+<!-- Tabs -->
+<!ENTITY manage.label "Subskrypcje">
+<!ENTITY general.label "Ogólne">
+<!ENTITY pub.label "Autokolekcje">
+<!-- Manage Subscriptions -->
+<!ENTITY subscriptions.header "Subskrypcje:">
+<!-- Groupbox captions in Manage Subscriptions -->
+<!ENTITY frequency.label "Częstotliwość aktualizacji subskrypcji">
+<!ENTITY notifications.label "Powiadomienia o nowych dodatkach">
+<!ENTITY perpage.label "Liczba dodatków na stronie">
+<!ENTITY default.label "Ustawienia domyślne">
+<!ENTITY custom.label "WÅ‚asne">
+<!ENTITY addonsleadin.label "Wyświetlaj">
+<!ENTITY addonsperpage.label "dodatków na stronie">
+<!ENTITY updatesingle.label "Aktualizuj co:">
+<!ENTITY minutes.label "min">
+<!ENTITY hours.label "godz.">
+<!ENTITY days.label "dni">
+<!ENTITY autopublish.label "Automatycznie publikuj zainstalowane dodatki w subskrypcji">
+<!ENTITY notify.label "Wyświetlaj powiadomienia">
+<!ENTITY applyall.label "zastosuj do wszystkich subskrypcji">
+<!ENTITY remove.label "Usuń subskrypcję">
+<!ENTITY on.label "Tak">
+<!ENTITY off.label "Nie">
+<!-- General -->
+<!-- Groupbox captions in General -->
+<!ENTITY subscriptions.label "Domyślne ustawienia subskrypcji">
+<!ENTITY data.label "ZarzÄ…dzanie danymi">
+<!ENTITY updateall.label "Sprawdzaj subskrypcje co">
+<!ENTITY notifyglobal.label "Powiadamiaj, gdy w subskrypcji pojawiÄ… siÄ™ nowe dodatki">
+<!ENTITY clearemails.label "Wyczyść">
+<!ENTITY login.label "Zaloguj siÄ™">
+<!ENTITY logout.label "Wyloguj siÄ™">
+<!-- Auto-Publisher Settings -->
+<!-- Groupbox captions in Auto-Publisher Settings -->
+<!ENTITY auto.label "Ustawienia autokolekcji">
+<!ENTITY name.label "Nazwa kolekcji:">
+<!ENTITY list.label "Wyświetlaj w publicznym katalogu kolekcji">
+<!ENTITY autoleadin.label "Autokolekcje to specjalne kolekcje, które są automatycznie aktualizowane, gdy instalujesz lub dezinstalujesz dodatki z Firefoksa na tym komputerze.">
+<!ENTITY types.label "Typy dodatków autokolekcji:">
+<!ENTITY type.extensions.label "Rozszerzenia">
+<!ENTITY type.themes.label "Motywy">
+<!ENTITY type.dicts.label "SÅ‚owniki">
+<!ENTITY type.langpacks.label "Pakiety językowe">
+<!ENTITY createauto.label "Utwórz autokolekcję">
+<!ENTITY deleteauto.label "Usuń autokolekcję">
+<!ENTITY updateauto.label "Aktualizuj autokolekcjÄ™">
+<!ENTITY onlypublishenabledaddons.label "Publikuj tylko włączone dodatki">
+<!ENTITY misc.label "Różne">
+<!ENTITY allowincompatibleinstall.label "Zezwalaj na instalację niekompatybilnych dodatków z mojej subskrypcji">
diff --git a/bandwagon/locale/pl/settings.properties b/bandwagon/locale/pl/settings.properties
new file mode 100644
index 0000000..d56458c
--- /dev/null
+++ b/bandwagon/locale/pl/settings.properties
@@ -0,0 +1,34 @@
+add.collection=Subskrybuj kolekcjÄ™
+enter.url.to.add.collection=Wprowadź adres URL kolekcji, którą chcesz subskrybować.
+remove.collection=Usuń subskrypcję
+# LOCALIZATION NOTE (are.you.sure.you.want.to.remove):
+
+# %S is the name of a collection
+
+are.you.sure.you.want.to.remove=Usunięcie tej subskrypcji spowoduje również usunięcie kolekcji z Twojej listy ulubionych. Czy na pewno chcesz usunąć „%S�
+# LOCALIZATION NOTE (saved.emails.text):
+
+# %S is a number
+
+saved.emails.text=Masz zapisanych %S adresów e-mail
+# LOCALIZATION NOTE (login.status.with.email):
+
+# %S is a user's email address
+
+login.status.with.email=JesteÅ› zalogowany/zalogowana jako %S
+login.status=JesteÅ› zalogowany/zalogowana
+logout.status=Nie jesteÅ› zalogowany/zalogowana
+# LOCALIZATION NOTE (auto.invalid.name):
+
+# %S is the name of a collection
+
+auto.invalid.name=Nie ma kolekcji o nazwie „%Sâ€.
+auto.please.select.type=Aby opublikować, musisz zaznaczyć co najmniej jeden typ dodatku.
+auto.create.internal.error=Nie można utworzyć kolekcji. Wystąpił błąd wewnętrzny.
+auto.create.done=Kolekcja została utworzona.
+auto.delete.internal.error=Nie można usunąć kolekcji. Wystąpił błąd wewnętrzny.
+auto.delete.done=Kolekcja została usunięta.
+auto.create.description=Automatycznie wygenerowana lista moich zainstalowanych dodatków
+auto.update.confirm.message=Nowe ustawienia będą działały bezzwłocznie, ale nie będą miały wpływu na dodatki, które już zostały opublikowane.
+auto.update.internal.error=Kolekcja nie może zostać zaktualizowana. Wystąpił błąd wewnętrzny.
+auto.update.done=Autokolekcja została zaktualizowana.
diff --git a/bandwagon/locale/pt-BR/bandwagon.properties b/bandwagon/locale/pt-BR/bandwagon.properties
new file mode 100644
index 0000000..dce72f7
--- /dev/null
+++ b/bandwagon/locale/pt-BR/bandwagon.properties
@@ -0,0 +1,2 @@
+extensions.sharing@addons.mozilla.org.description=Compartilhe e Descubra Complementos.
+extensions.sharing@addons.mozilla.org.name=Colecionador de Complementos
diff --git a/bandwagon/locale/pt-BR/bandwagonAddon.properties b/bandwagon/locale/pt-BR/bandwagonAddon.properties
new file mode 100644
index 0000000..e79d71c
--- /dev/null
+++ b/bandwagon/locale/pt-BR/bandwagonAddon.properties
@@ -0,0 +1,38 @@
+# LOCALIZATION NOTE (bandwagon.addon.pluralRule):
+# See https://developer.mozilla.org/En/Localization_and_Plurals
+bandwagon.addon.pluralRule=1
+bandwagon.category1=Extensão
+# LOCALIZATION NOTE (bandwagon.addon.author):
+# %S will contain author's first and last name, or their nickname used on AMO
+bandwagon.addon.author=Por %S
+# LOCALIZATION NOTE (bandwagon.addon.addedby):
+# %S will be a user's first and last name, or nickname
+bandwagon.addon.addedby=Por %S
+bandwagon.addon.added.justnow=Adicionado: Recentemente
+# LOCALIZATION NOTE:
+# %S will be a number of time units indicated
+bandwagon.addon.added.minute=Adicionado: 1 minuto atrás;Adicionado: %S minutos atrás
+bandwagon.addon.added.hour=Adicionado: 1 hora atrás;Adicionado: %S horas atrás
+bandwagon.addon.added.day=Adicionado: Ontem;Adicionado: %S dias atrás
+bandwagon.addon.added.week=Adicionado: 1 semana atrás;Added: %S semanas atrás
+bandwagon.addon.added.month=Adicionado: 1 mês atrás;Added: %S meses atrás
+bandwagon.addon.added.year=Adicionado: 1 ano atrás;Added: %S anos atrás
+bandwagon.addon.moreinfo=Maiores Informações.
+bandwagon.addon.olderversionsoffirefox=Este Complemento é para versões antigas do Firefox.
+# LOCALIZATION NOTE (upgradetofirefoxn1):
+# %S will be a Firefox version number
+bandwagon.addon.upgradetofirefoxn1=Atualize para o Firefox %S
+bandwagon.addon.upgradetofirefoxn2=para utilizar este Complemento.
+# LOCALIZATION NOTE (bandwagon.addon.requiresfirefoxbeta1/requiresfirefoxbeta2):
+# %S will be a Firefox version number
+bandwagon.addon.requiresfirefoxbeta1=Este Complemento requer o Firefox %S, no qual ainda não foi lançado. Para utilizar este Complemento, você poderá
+bandwagon.addon.requiresfirefoxbeta2=fazer download do Firefox %S beta.
+# LOCALIZATION NOTE (bandwagon.addon.notcompatible):
+# %S will be a platform name, such as "Windows"
+bandwagon.addon.notcompatible=Este Complemento não é compatível com %S.
+# LOCALIZATION NOTE (bandwagon.addon.comment.description):
+# %S will be a comment entered by the publisher of the add-on
+bandwagon.addon.comment.description=“%Sâ€
+# LOCALIZATION NOTE (bandwagon.addon.comment.author):
+# %S will be the publisher's real name or nickname
+bandwagon.addon.comment.author=Comentário por %S:
diff --git a/bandwagon/locale/pt-BR/browserOverlay.dtd b/bandwagon/locale/pt-BR/browserOverlay.dtd
new file mode 100644
index 0000000..33c5c7e
--- /dev/null
+++ b/bandwagon/locale/pt-BR/browserOverlay.dtd
@@ -0,0 +1,38 @@
+<!-- ***** BEGIN LICENSE BLOCK *****
+ - Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ -
+ - The contents of this file are subject to the Mozilla Public License Version
+ - 1.1 (the "License"); you may not use this file except in compliance with
+ - the License. You may obtain a copy of the License at
+ - http://www.mozilla.org/MPL/
+ -
+ - Software distributed under the License is distributed on an "AS IS" basis,
+ - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ - for the specific language governing rights and limitations under the
+ - License.
+ -
+ - The Original Code is bandwagon.
+ -
+ - The Initial Developer of the Original Code is
+ - Mozilla Corporation.
+ - Portions created by the Initial Developer are Copyright (C) 2008
+ - the Initial Developer. All Rights Reserved.
+ -
+ - Contributor(s): Brian King <brian (at) briks (dot) si>
+ -
+ - Alternatively, the contents of this file may be used under the terms of
+ - either the GNU General Public License Version 2 or later (the "GPL"), or
+ - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ - in which case the provisions of the GPL or the LGPL are applicable instead
+ - of those above. If you wish to allow use of your version of this file only
+ - under the terms of either the GPL or the LGPL, and not to allow others to
+ - use your version of this file under the terms of the MPL, indicate your
+ - decision by deleting the provisions above and replace them with the notice
+ - and other provisions required by the GPL or the LGPL. If you do not delete
+ - the provisions above, a recipient may use your version of this file under
+ - the terms of any one of the MPL, the GPL or the LGPL.
+ -
+ - ***** END LICENSE BLOCK ***** -->
+
+<!ENTITY bandwagon.label "Complementos">
+<!ENTITY bandwagon.tooltip "Complementos">
diff --git a/bandwagon/locale/pt-BR/browserOverlay.properties b/bandwagon/locale/pt-BR/browserOverlay.properties
new file mode 100644
index 0000000..3564773
--- /dev/null
+++ b/bandwagon/locale/pt-BR/browserOverlay.properties
@@ -0,0 +1,4 @@
+newaddons.alert.title=Novos Complementos
+# LOCALIZATION NOTE (newaddons.alert.text):
+# %S will be the name of a collection
+newaddons.alert.text=Existem novos Complementos em sua assinatura "%S".
diff --git a/bandwagon/locale/pt-BR/extensionOverlay.properties b/bandwagon/locale/pt-BR/extensionOverlay.properties
new file mode 100644
index 0000000..974970a
--- /dev/null
+++ b/bandwagon/locale/pt-BR/extensionOverlay.properties
@@ -0,0 +1,14 @@
+publish.new.email.address.title=Novo Endereço de E-mail
+publish.new.email.address.text=Digite um novo endereço de e-mail para compartilhar este complemento:
+publish.remove.title=Confirmação
+# LOCALIZATION NOTE (publish.remove.label):
+# %1 is the name of an add-on. %2 is the name of a collection
+publish.remove.label=Você tem certeza que quer remover %1$S da coleção "%2$S"?
+publish.remove.button1=Não, Cancelar
+publish.remove.button0=Sim, remover o complemento
+login.error=Ocorreu um erro ao logar. Por favor confirme que seu usuário e senhas estão corretos.
+unsubscribe.error=Ocorreu um erro ao cancelar sua assinatura referente a coleção. Por favor tente novamente.
+unsubscribe.confirm.title=Confirmar Cancelamento de Assinatura
+unsubscribe.confirm.label=Cancelando a assinatura desta coleção também irá removê-la da sua lista de favoritos. Tem certeza que desejar cancelar?
+unsubscribe.confirm.button1=Não, manter assinatura
+unsubscribe.confirm.button0=Sim, remover assinatura
diff --git a/bandwagon/locale/pt-BR/extensionsOverlay.dtd b/bandwagon/locale/pt-BR/extensionsOverlay.dtd
new file mode 100644
index 0000000..558d728
--- /dev/null
+++ b/bandwagon/locale/pt-BR/extensionsOverlay.dtd
@@ -0,0 +1,69 @@
+<!-- ***** BEGIN LICENSE BLOCK *****
+ - Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ -
+ - The contents of this file are subject to the Mozilla Public License Version
+ - 1.1 (the "License"); you may not use this file except in compliance with
+ - the License. You may obtain a copy of the License at
+ - http://www.mozilla.org/MPL/
+ -
+ - Software distributed under the License is distributed on an "AS IS" basis,
+ - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ - for the specific language governing rights and limitations under the
+ - License.
+ -
+ - The Original Code is bandwagon.
+ -
+ - The Initial Developer of the Original Code is
+ - Mozilla Corporation.
+ - Portions created by the Initial Developer are Copyright (C) 2008
+ - the Initial Developer. All Rights Reserved.
+ -
+ - Contributor(s): Brian King <brian (at) briks (dot) si>
+ - David McNamara
+ -
+ - Alternatively, the contents of this file may be used under the terms of
+ - either the GNU General Public License Version 2 or later (the "GPL"), or
+ - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ - in which case the provisions of the GPL or the LGPL are applicable instead
+ - of those above. If you wish to allow use of your version of this file only
+ - under the terms of either the GPL or the LGPL, and not to allow others to
+ - use your version of this file under the terms of the MPL, indicate your
+ - decision by deleting the provisions above and replace them with the notice
+ - and other provisions required by the GPL or the LGPL. If you do not delete
+ - the provisions above, a recipient may use your version of this file under
+ - the terms of any one of the MPL, the GPL or the LGPL.
+ -
+ - ***** END LICENSE BLOCK ***** -->
+
+<!ENTITY collections.label "Assinaturas">
+<!ENTITY search.label.bandwagon "Buscar">
+
+<!ENTITY addon.moreinfo "Mais informações.">
+<!ENTITY addon.addtofirefox "Adicionar ao Firefox">
+<!ENTITY subscribe.label "Procurar Coleções">
+<!ENTITY reload.label "Recarregar Tudo">
+<!ENTITY settings.label "Configurações">
+
+<!ENTITY view.label "Visualizar Coleção">
+<!ENTITY unsubscribe.label "Cancelar Assinatura">
+
+<!ENTITY nocollectionstitle.label "Bem-vindo ao Colecionador de Complementos">
+<!ENTITY nocollectionssubscribed.label "Aqui é onde serão apresentadas as coleções do Mozilla Add-ons que você marcou como favoritas, assim você pode fazer um acompanhamento. Parece que você ainda não adicionou nenhuma como favorita! Por que não dar uma olhada geral no Diretório de Coleções?">
+<!ENTITY clicktosubscribe.label "Encontrar Coleções">
+
+<!ENTITY noamoauth.label "Aqui é onde serão apresentadas as coleções do Mozilla Add-ons que você marcou como favoritas, assim você pode fazer um acompanhamento. Você tem que estar logado no addons.mozilla.org para utilizar este recurso.">
+<!ENTITY username.label "Endereço de E-mail">
+<!ENTITY password.label "Senha">
+<!ENTITY clicktologin.label "Login">
+
+<!ENTITY collectionisloading.label "Recebendo assinatura...">
+<!ENTITY collectionhasnoitems.label "Esta coleção não possui Complementos.">
+<!ENTITY collectionhaserror.label "Esta coleção não pode ser apresentada pois contém erros.">
+
+<!ENTITY publishto.label "Publicar para">
+<!ENTITY email.address.label "Endereço de E-mail">
+<!ENTITY new.email.address.label "Novo Endereço de E-mail">
+<!ENTITY new.collection.label "Nova Coleção">
+
+<!ENTITY createaccount.label "Eu não tenho uma conta de usuário">
+<!ENTITY loginheading.label "Insira suas informações de usuário do Mozilla Add-ons abaixo:">
diff --git a/bandwagon/locale/pt-BR/publish.dtd b/bandwagon/locale/pt-BR/publish.dtd
new file mode 100644
index 0000000..ed4361f
--- /dev/null
+++ b/bandwagon/locale/pt-BR/publish.dtd
@@ -0,0 +1,48 @@
+<!-- ***** BEGIN LICENSE BLOCK *****
+ - Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ -
+ - The contents of this file are subject to the Mozilla Public License Version
+ - 1.1 (the "License"); you may not use this file except in compliance with
+ - the License. You may obtain a copy of the License at
+ - http://www.mozilla.org/MPL/
+ -
+ - Software distributed under the License is distributed on an "AS IS" basis,
+ - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ - for the specific language governing rights and limitations under the
+ - License.
+ -
+ - The Original Code is bandwagon.
+ -
+ - The Initial Developer of the Original Code is
+ - Mozilla Corporation.
+ - Portions created by the Initial Developer are Copyright (C) 2008
+ - the Initial Developer. All Rights Reserved.
+ -
+ - Contributor(s): David McNamara
+ - Brian King <brian (at) briks (dot) si>
+ -
+ - Alternatively, the contents of this file may be used under the terms of
+ - either the GNU General Public License Version 2 or later (the "GPL"), or
+ - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ - in which case the provisions of the GPL or the LGPL are applicable instead
+ - of those above. If you wish to allow use of your version of this file only
+ - under the terms of either the GPL or the LGPL, and not to allow others to
+ - use your version of this file under the terms of the MPL, indicate your
+ - decision by deleting the provisions above and replace them with the notice
+ - and other provisions required by the GPL or the LGPL. If you do not delete
+ - the provisions above, a recipient may use your version of this file under
+ - the terms of any one of the MPL, the GPL or the LGPL.
+ -
+ - ***** END LICENSE BLOCK ***** -->
+
+<!-- For localisers to change the width of the window -->
+<!ENTITY publish.style "width: 35em;">
+
+<!ENTITY window.title "Publicar">
+<!ENTITY cancel.label "Cancelar">
+<!ENTITY publish.label "Publicar">
+<!ENTITY new.email.label "Novo Endereço de E-mail">
+<!ENTITY enter.an.email.label "Entre um ou mais endereços de e-mail separados por vírgulas:">
+<!ENTITY remember.this.email.label "Relembrar este endereço de e-mail">
+<!ENTITY enter.a.personal.note.label "Opcional: Digite uma nota pessoal sobre este Complemento para ser incluída no corpo do e-mail">
+
diff --git a/bandwagon/locale/pt-BR/publish.properties b/bandwagon/locale/pt-BR/publish.properties
new file mode 100644
index 0000000..8224839
--- /dev/null
+++ b/bandwagon/locale/pt-BR/publish.properties
@@ -0,0 +1,20 @@
+# LOCALIZATION NOTE (you.are.sharing.the.add.on):
+# %S is the name of an add-on
+you.are.sharing.the.add.on=Você está compartilhando o Complemento '%S'
+# LOCALIZATION NOTE (publishing.to):
+# %1 is the name of an add-on. %2 is the name of a collection
+publishing.to=Ao clicar em "Publicar" %1$S será adicionado para a coleção "%2$S".
+# LOCALIZATION NOTE (sharing.with):
+# %1 is a user's email address. $2 is the name of an add-on
+sharing.with=Ao clicar em "Enviar E-mail" será enviado um e-mail para %1$S com informações sobre %2$S
+# LOCALIZATION NOTE (sharing.with.new):
+# %S is the name of an add-on
+sharing.with.new=Ao clicar em "Enviar E-mail" será enviado um e-mail para os destinos acima com informações sobre %S
+please.enter.an.email.address=Por favor digite um endereço de e-mail.
+the.addon.has.been.published=O complemento foi publicado.
+the.email.has.been.sent=O e-mail foi enviado.
+# LOCALIZATION NOTE (closing.in):
+# %S is the number of seconds until a window closes, counting down
+closing.in=Fechando em %S...
+send.email=Enviar E-mail
+error.unknown_addon_guid=Este Complemento não pode ser compartilhado porque não está disponível no site Mozilla Add-ons.
diff --git a/bandwagon/locale/pt-BR/settings.dtd b/bandwagon/locale/pt-BR/settings.dtd
new file mode 100644
index 0000000..662e9e3
--- /dev/null
+++ b/bandwagon/locale/pt-BR/settings.dtd
@@ -0,0 +1,108 @@
+<!-- ***** BEGIN LICENSE BLOCK *****
+ - Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ -
+ - The contents of this file are subject to the Mozilla Public License Version
+ - 1.1 (the "License"); you may not use this file except in compliance with
+ - the License. You may obtain a copy of the License at
+ - http://www.mozilla.org/MPL/
+ -
+ - Software distributed under the License is distributed on an "AS IS" basis,
+ - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ - for the specific language governing rights and limitations under the
+ - License.
+ -
+ - The Original Code is bandwagon.
+ -
+ - The Initial Developer of the Original Code is
+ - Mozilla Corporation.
+ - Portions created by the Initial Developer are Copyright (C) 2008
+ - the Initial Developer. All Rights Reserved.
+ -
+ - Contributor(s): Brian King <brian (at) briks (dot) si>
+ - David McNamara
+ -
+ - Alternatively, the contents of this file may be used under the terms of
+ - either the GNU General Public License Version 2 or later (the "GPL"), or
+ - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ - in which case the provisions of the GPL or the LGPL are applicable instead
+ - of those above. If you wish to allow use of your version of this file only
+ - under the terms of either the GPL or the LGPL, and not to allow others to
+ - use your version of this file under the terms of the MPL, indicate your
+ - decision by deleting the provisions above and replace them with the notice
+ - and other provisions required by the GPL or the LGPL. If you do not delete
+ - the provisions above, a recipient may use your version of this file under
+ - the terms of any one of the MPL, the GPL or the LGPL.
+ -
+ - ***** END LICENSE BLOCK ***** -->
+
+<!-- For localisers to change the width of the window -->
+<!ENTITY settings.style "width: 42em;">
+
+<!ENTITY window.title "Configurações do Colecionador de Complementos">
+
+<!-- Tabs -->
+<!ENTITY manage.label "Gerenciar Assinaturas">
+<!ENTITY general.label "Configurações Gerais">
+<!ENTITY pub.label "Configurações do Auto-publicador">
+
+<!-- Manage Subscriptions -->
+<!ENTITY subscriptions.header "Assinaturas:">
+
+<!-- Groupbox captions in Manage Subscriptions -->
+<!ENTITY frequency.label "Frequência de Atualização de Assinaturas">
+<!ENTITY notifications.label "Notificações sobre Novos Complementos">
+<!ENTITY perpage.label "Complementos por Página">
+
+<!ENTITY default.label "Utilizar configuração padrão">
+<!ENTITY custom.label "Customizada:">
+
+<!ENTITY addonsleadin.label "Mostrar">
+<!ENTITY addonsperpage.label "Complementos por página">
+<!ENTITY updatesingle.label "Atualização a cada:">
+<!ENTITY minutes.label "minuto(s)">
+<!ENTITY hours.label "hora(s)">
+<!ENTITY days.label "dia(s)">
+<!ENTITY autopublish.label "Auto-publicar complementos instalados na assinatura">
+<!ENTITY notify.label "Mostrar notificações">
+<!ENTITY applyall.label "Aplicar para todas as assinaturas">
+<!ENTITY remove.label "Remover Assinaturas">
+<!ENTITY on.label "Ligado">
+<!ENTITY off.label "Desligado">
+
+<!-- General -->
+
+<!-- Groupbox captions in General -->
+<!ENTITY subscriptions.label "Configurações de Assinaturas Padrão">
+<!ENTITY data.label "Gerenciamento de Dados">
+
+<!ENTITY updateall.label "Checar as assinaturas por atualizações a cada">
+<!ENTITY notifyglobal.label "Me notificar sempre que minhas assinaturas possuirem novos complementos">
+
+<!ENTITY clearemails.label "Limpar">
+<!ENTITY login.label "Login">
+<!ENTITY logout.label "Logout">
+
+<!-- Auto-Publisher Settings -->
+
+<!-- Groupbox captions in Auto-Publisher Settings -->
+<!ENTITY auto.label "Configurações do Auto-publicador">
+
+<!ENTITY name.label "Nome da Coleção:">
+<!ENTITY list.label "Listada no Diretório de Coleções Públicas">
+
+<!ENTITY autoleadin.label "Auto-publicadores são coleções especiais que são automaticamente atualizadas quando você instala ou desinstala complementos do Firefox neste computador.">
+<!ENTITY types.label "Tipos de Complementos do Auto-publicador:">
+<!ENTITY type.extensions.label "Extensões">
+<!ENTITY type.themes.label "Temas">
+<!ENTITY type.dicts.label "Dicionários">
+<!ENTITY type.langpacks.label "Pacotes de Idiomas">
+
+<!ENTITY createauto.label "Criar um Auto-publicador">
+<!ENTITY deleteauto.label "Remover um Auto-publicador">
+<!ENTITY updateauto.label "Atualizar um Auto-publicador">
+
+<!ENTITY onlypublishenabledaddons.label "Somente publicar Complementos habilitados">
+
+<!ENTITY misc.label "Diversos">
+<!ENTITY allowincompatibleinstall.label "Permitir instalação de complementos incompatíveis nas minhas assinaturas">
+
diff --git a/bandwagon/locale/pt-BR/settings.properties b/bandwagon/locale/pt-BR/settings.properties
new file mode 100644
index 0000000..43a3e1a
--- /dev/null
+++ b/bandwagon/locale/pt-BR/settings.properties
@@ -0,0 +1,26 @@
+add.collection=Adicionar Assinatura
+enter.url.to.add.collection=Entre com o URL da assinatura que você quer adicionar.
+remove.collection=Remover Assinatura
+# LOCALIZATION NOTE (are.you.sure.you.want.to.remove):
+# %S is the name of a collection
+are.you.sure.you.want.to.remove=Removendo esta assinatura também irá remover a coleção da sua lista de favoritas. Você tem certeza que quer remover '%S'?
+# LOCALIZATION NOTE (saved.emails.text):
+# %S is a number
+saved.emails.text=Você salvou %S endereços de e-mail
+# LOCALIZATION NOTE (login.status.with.email):
+# %S is a user's email address
+login.status.with.email=Você está logado como %S
+login.status=Você está logado
+logout.status=Você não está logado
+# LOCALIZATION NOTE (auto.invalid.name):
+# %S is the name of a collection
+auto.invalid.name=O nome de coleção '%S' é invalido.
+auto.please.select.type=Por favor selecione pelo menos um tipo de complemento para publicar automaticamente.
+auto.create.internal.error=A coleção não pode ser criada (ocorreu um erro interno).
+auto.create.done=Sua coleção auto-publicável foi criada.
+auto.delete.internal.error=A coleção não pode ser removida (um erro interno ocorreu).
+auto.delete.done=Sua coleção auto-publicável foi removida.
+auto.create.description=Uma lista automaticamente gerada dos meus complementos instalados
+auto.update.confirm.message=Suas novas configurações serão efetivadas imediatamente, mas complementos que já foram publicados não serão afetados.
+auto.update.internal.error=A coleção não foi atualizada ( um erro interno ocorreu).
+auto.update.done=Sua coleção auto-publicável foi atualizada.
diff --git a/bandwagon/locale/pt-PT/bandwagon.properties b/bandwagon/locale/pt-PT/bandwagon.properties
new file mode 100644
index 0000000..3ae352a
--- /dev/null
+++ b/bandwagon/locale/pt-PT/bandwagon.properties
@@ -0,0 +1,2 @@
+extensions.sharing@addons.mozilla.org.description=Partilhar e descobrir extras.
+extensions.sharing@addons.mozilla.org.name=Coleccionador de extras
diff --git a/bandwagon/locale/pt-PT/bandwagonAddon.properties b/bandwagon/locale/pt-PT/bandwagonAddon.properties
new file mode 100644
index 0000000..9dc1e4a
--- /dev/null
+++ b/bandwagon/locale/pt-PT/bandwagonAddon.properties
@@ -0,0 +1,38 @@
+# LOCALIZATION NOTE (bandwagon.addon.pluralRule):
+# See https://developer.mozilla.org/En/Localization_and_Plurals
+bandwagon.addon.pluralRule=1
+bandwagon.category1=Extensão
+# LOCALIZATION NOTE (bandwagon.addon.author):
+# %S will contain author's first and last name, or their nickname used on AMO
+bandwagon.addon.author=Por %S
+# LOCALIZATION NOTE (bandwagon.addon.addedby):
+# %S will be a user's first and last name, or nickname
+bandwagon.addon.addedby=por %S
+bandwagon.addon.added.justnow=Adicionado: Agora mesmo
+# LOCALIZATION NOTE:
+# %S will be a number of time units indicated
+bandwagon.addon.added.minute=Adicionado: à 1 minuto;Adicionado: à %S minutos
+bandwagon.addon.added.hour=Adicionado: 1 hour ago;Adicionado: à %S hours ago
+bandwagon.addon.added.day=Adicionado: Ontem;Adicionado: à %S dias
+bandwagon.addon.added.week=Adicionado: à 1 semana;Adicionado: à %S semanas
+bandwagon.addon.added.month=Adicionado: à 1 mês;Adicionado: à %S meses
+bandwagon.addon.added.year=Adicionado: à 1 ano;Adicionado: à %S anos
+bandwagon.addon.moreinfo=Mais info.
+bandwagon.addon.olderversionsoffirefox=Este extra é para versões antigas do Firefox.
+# LOCALIZATION NOTE (upgradetofirefoxn1):
+# %S will be a Firefox version number
+bandwagon.addon.upgradetofirefoxn1=Actualização para o Firefox %S
+bandwagon.addon.upgradetofirefoxn2=para usar este extra.
+# LOCALIZATION NOTE (bandwagon.addon.requiresfirefoxbeta1/requiresfirefoxbeta2):
+# %S will be a Firefox version number
+bandwagon.addon.requiresfirefoxbeta1=Este extra necessita do Firefox %S, que ainda não foi lançado. Para usar este extra, pode
+bandwagon.addon.requiresfirefoxbeta2=Transferir o Firefox %S beta.
+# LOCALIZATION NOTE (bandwagon.addon.notcompatible):
+# %S will be a platform name, such as "Windows"
+bandwagon.addon.notcompatible=Este extra não é compatível com o %S.
+# LOCALIZATION NOTE (bandwagon.addon.comment.description):
+# %S will be a comment entered by the publisher of the add-on
+bandwagon.addon.comment.description=“%Sâ€
+# LOCALIZATION NOTE (bandwagon.addon.comment.author):
+# %S will be the publisher's real name or nickname
+bandwagon.addon.comment.author=Comentário de %S:
diff --git a/bandwagon/locale/pt-PT/browserOverlay.dtd b/bandwagon/locale/pt-PT/browserOverlay.dtd
new file mode 100644
index 0000000..35308f3
--- /dev/null
+++ b/bandwagon/locale/pt-PT/browserOverlay.dtd
@@ -0,0 +1,38 @@
+<!-- ***** BEGIN LICENSE BLOCK *****
+ - Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ -
+ - The contents of this file are subject to the Mozilla Public License Version
+ - 1.1 (the "License"); you may not use this file except in compliance with
+ - the License. You may obtain a copy of the License at
+ - http://www.mozilla.org/MPL/
+ -
+ - Software distributed under the License is distributed on an "AS IS" basis,
+ - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ - for the specific language governing rights and limitations under the
+ - License.
+ -
+ - The Original Code is bandwagon.
+ -
+ - The Initial Developer of the Original Code is
+ - Mozilla Corporation.
+ - Portions created by the Initial Developer are Copyright (C) 2008
+ - the Initial Developer. All Rights Reserved.
+ -
+ - Contributor(s): Brian King <brian (at) briks (dot) si>
+ -
+ - Alternatively, the contents of this file may be used under the terms of
+ - either the GNU General Public License Version 2 or later (the "GPL"), or
+ - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ - in which case the provisions of the GPL or the LGPL are applicable instead
+ - of those above. If you wish to allow use of your version of this file only
+ - under the terms of either the GPL or the LGPL, and not to allow others to
+ - use your version of this file under the terms of the MPL, indicate your
+ - decision by deleting the provisions above and replace them with the notice
+ - and other provisions required by the GPL or the LGPL. If you do not delete
+ - the provisions above, a recipient may use your version of this file under
+ - the terms of any one of the MPL, the GPL or the LGPL.
+ -
+ - ***** END LICENSE BLOCK ***** -->
+
+<!ENTITY bandwagon.label "Extras">
+<!ENTITY bandwagon.tooltip "Extras">
diff --git a/bandwagon/locale/pt-PT/browserOverlay.properties b/bandwagon/locale/pt-PT/browserOverlay.properties
new file mode 100644
index 0000000..bb2cbaa
--- /dev/null
+++ b/bandwagon/locale/pt-PT/browserOverlay.properties
@@ -0,0 +1,4 @@
+newaddons.alert.title=Novos extras
+# LOCALIZATION NOTE (newaddons.alert.text):
+# %S will be the name of a collection
+newaddons.alert.text=Existem novos extras na sua subscrição "%S".
diff --git a/bandwagon/locale/pt-PT/extensionOverlay.properties b/bandwagon/locale/pt-PT/extensionOverlay.properties
new file mode 100644
index 0000000..25c9300
--- /dev/null
+++ b/bandwagon/locale/pt-PT/extensionOverlay.properties
@@ -0,0 +1,14 @@
+publish.new.email.address.title=Novo endereço de correio
+publish.new.email.address.text=Escreva um endereço de correio para partilhar este extra:
+publish.remove.title=Confirmação
+# LOCALIZATION NOTE (publish.remove.label):
+# %1 is the name of an add-on. %2 is the name of a collection
+publish.remove.label=Tem a certeza que deseja remover %1$S da colecção "%2$S" ?
+publish.remove.button1=Não, cancelar
+publish.remove.button0=Sim, remover o extra
+login.error=Houve um erro ao iniciar sessão. Verifique se o seu nome de utilizador e senha estão correctos.
+unsubscribe.error=Houve um erro ao des-subscrever desta colecção. Tente de novo mais tarde.
+unsubscribe.confirm.title=Confirmar des-subscrição
+unsubscribe.confirm.label=Des-subscrever desta colecção também a irá remover da sua lista de favoritos. Tem a certeza que deseja des-subscrever?
+unsubscribe.confirm.button1=Não, cancelar
+unsubscribe.confirm.button0=Sim, des-subscrever
diff --git a/bandwagon/locale/pt-PT/extensionsOverlay.dtd b/bandwagon/locale/pt-PT/extensionsOverlay.dtd
new file mode 100644
index 0000000..18e0f2d
--- /dev/null
+++ b/bandwagon/locale/pt-PT/extensionsOverlay.dtd
@@ -0,0 +1,69 @@
+<!-- ***** BEGIN LICENSE BLOCK *****
+ - Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ -
+ - The contents of this file are subject to the Mozilla Public License Version
+ - 1.1 (the "License"); you may not use this file except in compliance with
+ - the License. You may obtain a copy of the License at
+ - http://www.mozilla.org/MPL/
+ -
+ - Software distributed under the License is distributed on an "AS IS" basis,
+ - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ - for the specific language governing rights and limitations under the
+ - License.
+ -
+ - The Original Code is bandwagon.
+ -
+ - The Initial Developer of the Original Code is
+ - Mozilla Corporation.
+ - Portions created by the Initial Developer are Copyright (C) 2008
+ - the Initial Developer. All Rights Reserved.
+ -
+ - Contributor(s): Brian King <brian (at) briks (dot) si>
+ - David McNamara
+ -
+ - Alternatively, the contents of this file may be used under the terms of
+ - either the GNU General Public License Version 2 or later (the "GPL"), or
+ - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ - in which case the provisions of the GPL or the LGPL are applicable instead
+ - of those above. If you wish to allow use of your version of this file only
+ - under the terms of either the GPL or the LGPL, and not to allow others to
+ - use your version of this file under the terms of the MPL, indicate your
+ - decision by deleting the provisions above and replace them with the notice
+ - and other provisions required by the GPL or the LGPL. If you do not delete
+ - the provisions above, a recipient may use your version of this file under
+ - the terms of any one of the MPL, the GPL or the LGPL.
+ -
+ - ***** END LICENSE BLOCK ***** -->
+
+<!ENTITY collections.label "Subscrições">
+<!ENTITY search.label.bandwagon "Pesquisar">
+
+<!ENTITY addon.moreinfo "Mais info.">
+<!ENTITY addon.addtofirefox "Adicionar ao Firefox">
+<!ENTITY subscribe.label "Procurar colecções">
+<!ENTITY reload.label "Recarregar tudo">
+<!ENTITY settings.label "Definições">
+
+<!ENTITY view.label "Ver colecção">
+<!ENTITY unsubscribe.label "Des-subscrever">
+
+<!ENTITY nocollectionstitle.label "Bem-vindo ao coleccionador de extras">
+<!ENTITY nocollectionssubscribed.label "Isto é onde colecções que marca como favoritas nos Extras da Mozilla irão aparecer para que possa facilmente revê-los. Parece que ainda não adicionou nenhum favorito, por isso que tal dar uma vista de olhos à nossa colecção?">
+<!ENTITY clicktosubscribe.label "Procurar colecções">
+
+<!ENTITY noamoauth.label "Isto é onde colecções que marca como favoritos nos Extras da Mozilla irão aparecer para que possa facilmente revê-los. Tem de ter uma sessão iniciada em addons.mozilla.org para usar esta funcionalidade.">
+<!ENTITY username.label "Nome de utilizador">
+<!ENTITY password.label "Senha">
+<!ENTITY clicktologin.label "Iniciar sessão">
+
+<!ENTITY collectionisloading.label "A obter subscrições...">
+<!ENTITY collectionhasnoitems.label "Esta colecção não tem extras.">
+<!ENTITY collectionhaserror.label "Esta colecção nãopode ser apresentada porqque tem erros.">
+
+<!ENTITY publishto.label "Publicar para">
+<!ENTITY email.address.label "Endereço de correio">
+<!ENTITY new.email.address.label "Novo endereço de correio">
+<!ENTITY new.collection.label "Nova colecção">
+
+<!ENTITY createaccount.label "Não tenho uma conta">
+<!ENTITY loginheading.label "Escreva a informação da sua conta dos extras da Mozilla em baixo:">
diff --git a/bandwagon/locale/pt-PT/publish.dtd b/bandwagon/locale/pt-PT/publish.dtd
new file mode 100644
index 0000000..1a1f151
--- /dev/null
+++ b/bandwagon/locale/pt-PT/publish.dtd
@@ -0,0 +1,48 @@
+<!-- ***** BEGIN LICENSE BLOCK *****
+ - Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ -
+ - The contents of this file are subject to the Mozilla Public License Version
+ - 1.1 (the "License"); you may not use this file except in compliance with
+ - the License. You may obtain a copy of the License at
+ - http://www.mozilla.org/MPL/
+ -
+ - Software distributed under the License is distributed on an "AS IS" basis,
+ - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ - for the specific language governing rights and limitations under the
+ - License.
+ -
+ - The Original Code is bandwagon.
+ -
+ - The Initial Developer of the Original Code is
+ - Mozilla Corporation.
+ - Portions created by the Initial Developer are Copyright (C) 2008
+ - the Initial Developer. All Rights Reserved.
+ -
+ - Contributor(s): David McNamara
+ - Brian King <brian (at) briks (dot) si>
+ -
+ - Alternatively, the contents of this file may be used under the terms of
+ - either the GNU General Public License Version 2 or later (the "GPL"), or
+ - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ - in which case the provisions of the GPL or the LGPL are applicable instead
+ - of those above. If you wish to allow use of your version of this file only
+ - under the terms of either the GPL or the LGPL, and not to allow others to
+ - use your version of this file under the terms of the MPL, indicate your
+ - decision by deleting the provisions above and replace them with the notice
+ - and other provisions required by the GPL or the LGPL. If you do not delete
+ - the provisions above, a recipient may use your version of this file under
+ - the terms of any one of the MPL, the GPL or the LGPL.
+ -
+ - ***** END LICENSE BLOCK ***** -->
+
+<!-- For localisers to change the width of the window -->
+<!ENTITY publish.style "width: 44em;">
+
+<!ENTITY window.title "Publicar">
+<!ENTITY cancel.label "Cancelar">
+<!ENTITY publish.label "Publicar">
+<!ENTITY new.email.label "Novo endereço de correio">
+<!ENTITY enter.an.email.label "Escreva um ou mais endereços de correio separados por vírgulas:">
+<!ENTITY remember.this.email.label "Lembrar este endereço de correio">
+<!ENTITY enter.a.personal.note.label "Opcional: Escreva uma nota pessoal sobre este extra para ser incluído na mensagem de correio">
+
diff --git a/bandwagon/locale/pt-PT/publish.properties b/bandwagon/locale/pt-PT/publish.properties
new file mode 100644
index 0000000..b2b8fdb
--- /dev/null
+++ b/bandwagon/locale/pt-PT/publish.properties
@@ -0,0 +1,20 @@
+# LOCALIZATION NOTE (you.are.sharing.the.add.on):
+# %S is the name of an add-on
+you.are.sharing.the.add.on=Está a partilhar o extra '%S'
+# LOCALIZATION NOTE (publishing.to):
+# %1 is the name of an add-on. %2 is the name of a collection
+publishing.to=Cliar em "Publicar" irá adicionar %1$S à coleção "%2$S".
+# LOCALIZATION NOTE (sharing.with):
+# %1 is a user's email address. $2 is the name of an add-on
+sharing.with=Clicar em "Enviar correio" irá enviar a %1$S uma mensagem de correio electrónico com informação sobre %2$S
+# LOCALIZATION NOTE (sharing.with.new):
+# %S is the name of an add-on
+sharing.with.new=Clicar em "Enviar correio" irá enviar aos destinatários acima uma mensagem de correio electrónico com informação sobre %S
+please.enter.an.email.address=Escreva um endereço de correio.
+the.addon.has.been.published=O extra foi publicado.
+the.email.has.been.sent=A mensagem de correio foi enviada.
+# LOCALIZATION NOTE (closing.in):
+# %S is the number of seconds until a window closes, counting down
+closing.in=A encerrar dentro de %S...
+send.email=Enviar correio
+error.unknown_addon_guid=Este extra não pode ser partilhado porque não se encontra hospedado no sítio web dos extras da Mozilla.
diff --git a/bandwagon/locale/pt-PT/settings.dtd b/bandwagon/locale/pt-PT/settings.dtd
new file mode 100644
index 0000000..07127b7
--- /dev/null
+++ b/bandwagon/locale/pt-PT/settings.dtd
@@ -0,0 +1,108 @@
+<!-- ***** BEGIN LICENSE BLOCK *****
+ - Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ -
+ - The contents of this file are subject to the Mozilla Public License Version
+ - 1.1 (the "License"); you may not use this file except in compliance with
+ - the License. You may obtain a copy of the License at
+ - http://www.mozilla.org/MPL/
+ -
+ - Software distributed under the License is distributed on an "AS IS" basis,
+ - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ - for the specific language governing rights and limitations under the
+ - License.
+ -
+ - The Original Code is bandwagon.
+ -
+ - The Initial Developer of the Original Code is
+ - Mozilla Corporation.
+ - Portions created by the Initial Developer are Copyright (C) 2008
+ - the Initial Developer. All Rights Reserved.
+ -
+ - Contributor(s): Brian King <brian (at) briks (dot) si>
+ - David McNamara
+ -
+ - Alternatively, the contents of this file may be used under the terms of
+ - either the GNU General Public License Version 2 or later (the "GPL"), or
+ - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ - in which case the provisions of the GPL or the LGPL are applicable instead
+ - of those above. If you wish to allow use of your version of this file only
+ - under the terms of either the GPL or the LGPL, and not to allow others to
+ - use your version of this file under the terms of the MPL, indicate your
+ - decision by deleting the provisions above and replace them with the notice
+ - and other provisions required by the GPL or the LGPL. If you do not delete
+ - the provisions above, a recipient may use your version of this file under
+ - the terms of any one of the MPL, the GPL or the LGPL.
+ -
+ - ***** END LICENSE BLOCK ***** -->
+
+<!-- For localisers to change the width of the window -->
+<!ENTITY settings.style "width: 46em;">
+
+<!ENTITY window.title "Definições do extra Collector">
+
+<!-- Tabs -->
+<!ENTITY manage.label "Gerir subscrições">
+<!ENTITY general.label "Definições gerais">
+<!ENTITY pub.label "Definições da publicação auto">
+
+<!-- Manage Subscriptions -->
+<!ENTITY subscriptions.header "Subscrições:">
+
+<!-- Groupbox captions in Manage Subscriptions -->
+<!ENTITY frequency.label "Frequência da actualização da subscrição">
+<!ENTITY notifications.label "Notificações de novo extra">
+<!ENTITY perpage.label "Extras por página">
+
+<!ENTITY default.label "Usar definições pré-definidas">
+<!ENTITY custom.label "Personalizado:">
+
+<!ENTITY addonsleadin.label "Mostrar">
+<!ENTITY addonsperpage.label "extras por página">
+<!ENTITY updatesingle.label "Actualizar a cada:">
+<!ENTITY minutes.label "minuto(s)">
+<!ENTITY hours.label "hora(s)">
+<!ENTITY days.label "dia(s)">
+<!ENTITY autopublish.label "Auto-publicar extras instalados na subscrição">
+<!ENTITY notify.label "Mostrar notificações">
+<!ENTITY applyall.label "Aplicar a todas as subscrições">
+<!ENTITY remove.label "Remover subscrição">
+<!ENTITY on.label "Ligado">
+<!ENTITY off.label "Desligado">
+
+<!-- General -->
+
+<!-- Groupbox captions in General -->
+<!ENTITY subscriptions.label "Definições de subscrição pré-definidas">
+<!ENTITY data.label "Gestão de dados">
+
+<!ENTITY updateall.label "Verificar por actualizações de subscrições a cada">
+<!ENTITY notifyglobal.label "Notificar-me quando as minhas subscrições tiverem novos extras">
+
+<!ENTITY clearemails.label "Limpar">
+<!ENTITY login.label "Início de sessão">
+<!ENTITY logout.label "Terminar sessão">
+
+<!-- Auto-Publisher Settings -->
+
+<!-- Groupbox captions in Auto-Publisher Settings -->
+<!ENTITY auto.label "Definições da auto-publicação">
+
+<!ENTITY name.label "Nome da colecção:">
+<!ENTITY list.label "Listado na directoria pública de coleções">
+
+<!ENTITY autoleadin.label "Publicações auto são coleções especiais que são actualizadas automaticamente quando instala ou desinstala extras do Firefox neste computador.">
+<!ENTITY types.label "Tipos de extra auto-publicados:">
+<!ENTITY type.extensions.label "Extensões">
+<!ENTITY type.themes.label "Temas">
+<!ENTITY type.dicts.label "Dicionários">
+<!ENTITY type.langpacks.label "Pacotes de idioma">
+
+<!ENTITY createauto.label "Criar publicação auto">
+<!ENTITY deleteauto.label "Eliminar publicação auto">
+<!ENTITY updateauto.label "Actualizar publicação auto">
+
+<!ENTITY onlypublishenabledaddons.label "Publicar apenas extras activados">
+
+<!ENTITY misc.label "Miscelânea">
+<!ENTITY allowincompatibleinstall.label "Permitir a instalação das minhas subscrições de extras imcompatíveis">
+
diff --git a/bandwagon/locale/pt-PT/settings.properties b/bandwagon/locale/pt-PT/settings.properties
new file mode 100644
index 0000000..0d738aa
--- /dev/null
+++ b/bandwagon/locale/pt-PT/settings.properties
@@ -0,0 +1,26 @@
+add.collection=Adicionar subscrição
+enter.url.to.add.collection=Escreva o URL da subscrição que deseja adicionar.
+remove.collection=Remover subscrição
+# LOCALIZATION NOTE (are.you.sure.you.want.to.remove):
+# %S is the name of a collection
+are.you.sure.you.want.to.remove=Remover esta subscrição irá também remover a colecção da lista de favoritos. Tem a certeza que deseja remover '%S'?
+# LOCALIZATION NOTE (saved.emails.text):
+# %S is a number
+saved.emails.text=Tem %S endereços de correio guardados
+# LOCALIZATION NOTE (login.status.with.email):
+# %S is a user's email address
+login.status.with.email=Está ligado como %S
+login.status=Está ligado
+logout.status=Não está ligado
+# LOCALIZATION NOTE (auto.invalid.name):
+# %S is the name of a collection
+auto.invalid.name=O nome da colecção '%S' não é válido.
+auto.please.select.type=Seleccione pelo menos um tipo de extra para publicar automaticamente.
+auto.create.internal.error=A colecção não pode ser criada (ocorreu um erro interno).
+auto.create.done=A sua colecção auto-publicada foi criada.
+auto.delete.internal.error=A colecção não pode ser eliminada (ocorreu um erro interno)).
+auto.delete.done=A sua colecção auto-publicada foi eliminada.
+auto.create.description=Uma lista criada automaticamente dos meus extras instalados
+auto.update.confirm.message=As suas novas definições terão efeito imediatamente, mas não irão afectar os extras já publicados.
+auto.update.internal.error=A colecção não pôde ser actualizada (ocorreu um erro interno).
+auto.update.done=A sua colecção auto-publicada foi actualizada.
diff --git a/bandwagon/locale/ro/bandwagon.properties b/bandwagon/locale/ro/bandwagon.properties
new file mode 100644
index 0000000..91c8abc
--- /dev/null
+++ b/bandwagon/locale/ro/bandwagon.properties
@@ -0,0 +1,2 @@
+extensions.sharing@addons.mozilla.org.description=Împărtășiți și descoperiți suplimente.
+extensions.sharing@addons.mozilla.org.name=Add-on Collector
diff --git a/bandwagon/locale/ro/bandwagonAddon.properties b/bandwagon/locale/ro/bandwagonAddon.properties
new file mode 100644
index 0000000..37d7e8a
--- /dev/null
+++ b/bandwagon/locale/ro/bandwagonAddon.properties
@@ -0,0 +1,38 @@
+# LOCALIZATION NOTE (bandwagon.addon.pluralRule):
+# See https://developer.mozilla.org/En/Localization_and_Plurals
+bandwagon.addon.pluralRule=1
+bandwagon.category1=Extensie
+# LOCALIZATION NOTE (bandwagon.addon.author):
+# %S will contain author's first and last name, or their nickname used on AMO
+bandwagon.addon.author=De %S
+# LOCALIZATION NOTE (bandwagon.addon.addedby):
+# %S will be a user's first and last name, or nickname
+bandwagon.addon.addedby=de %S
+bandwagon.addon.added.justnow=Adăugat: chiar acum
+# LOCALIZATION NOTE:
+# %S will be a number of time units indicated
+bandwagon.addon.added.minute=Adăugat: acum 1 minut;Adăugat: acum %S minute
+bandwagon.addon.added.hour=Adăugat: acum o oră;Adăugat: acum %S ore
+bandwagon.addon.added.day=Adăugat: ieri;Adăugat: acum %S zile
+bandwagon.addon.added.week=Adăugat: acum o săptămână;Adăugat: acum %S săptămâni
+bandwagon.addon.added.month=Adăugat: acum o lună;Adăugat: acum %S luni
+bandwagon.addon.added.year=Adăugat: acum un an; Adăugat: acum %S ani
+bandwagon.addon.moreinfo=Mai multe informații.
+bandwagon.addon.olderversionsoffirefox=Acest supliment este pentru versiuni mai vechi de Firefox.
+# LOCALIZATION NOTE (upgradetofirefoxn1):
+# %S will be a Firefox version number
+bandwagon.addon.upgradetofirefoxn1=Avansați la Firefox %S
+bandwagon.addon.upgradetofirefoxn2=pentru a folosi acest supliment.
+# LOCALIZATION NOTE (bandwagon.addon.requiresfirefoxbeta1/requiresfirefoxbeta2):
+# %S will be a Firefox version number
+bandwagon.addon.requiresfirefoxbeta1=Acest supliment are nevoie de Firefox %S, supliment care nu a fost încă lansat. Pentru a folosi acest supliment, puteți
+bandwagon.addon.requiresfirefoxbeta2=descărca Firefox %S beta.
+# LOCALIZATION NOTE (bandwagon.addon.notcompatible):
+# %S will be a platform name, such as "Windows"
+bandwagon.addon.notcompatible=Acest supliment nu este compatibil cu %S.
+# LOCALIZATION NOTE (bandwagon.addon.comment.description):
+# %S will be a comment entered by the publisher of the add-on
+bandwagon.addon.comment.description=„%Sâ€
+# LOCALIZATION NOTE (bandwagon.addon.comment.author):
+# %S will be the publisher's real name or nickname
+bandwagon.addon.comment.author=Comentariu de la %S:
diff --git a/bandwagon/locale/ro/browserOverlay.dtd b/bandwagon/locale/ro/browserOverlay.dtd
new file mode 100644
index 0000000..485eaa2
--- /dev/null
+++ b/bandwagon/locale/ro/browserOverlay.dtd
@@ -0,0 +1,38 @@
+<!-- ***** BEGIN LICENSE BLOCK *****
+ - Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ -
+ - The contents of this file are subject to the Mozilla Public License Version
+ - 1.1 (the "License"); you may not use this file except in compliance with
+ - the License. You may obtain a copy of the License at
+ - http://www.mozilla.org/MPL/
+ -
+ - Software distributed under the License is distributed on an "AS IS" basis,
+ - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ - for the specific language governing rights and limitations under the
+ - License.
+ -
+ - The Original Code is bandwagon.
+ -
+ - The Initial Developer of the Original Code is
+ - Mozilla Corporation.
+ - Portions created by the Initial Developer are Copyright (C) 2008
+ - the Initial Developer. All Rights Reserved.
+ -
+ - Contributor(s): Brian King <brian (at) briks (dot) si>
+ -
+ - Alternatively, the contents of this file may be used under the terms of
+ - either the GNU General Public License Version 2 or later (the "GPL"), or
+ - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ - in which case the provisions of the GPL or the LGPL are applicable instead
+ - of those above. If you wish to allow use of your version of this file only
+ - under the terms of either the GPL or the LGPL, and not to allow others to
+ - use your version of this file under the terms of the MPL, indicate your
+ - decision by deleting the provisions above and replace them with the notice
+ - and other provisions required by the GPL or the LGPL. If you do not delete
+ - the provisions above, a recipient may use your version of this file under
+ - the terms of any one of the MPL, the GPL or the LGPL.
+ -
+ - ***** END LICENSE BLOCK ***** -->
+
+<!ENTITY bandwagon.label "Suplimente">
+<!ENTITY bandwagon.tooltip "Suplimente">
diff --git a/bandwagon/locale/ro/browserOverlay.properties b/bandwagon/locale/ro/browserOverlay.properties
new file mode 100644
index 0000000..89003e1
--- /dev/null
+++ b/bandwagon/locale/ro/browserOverlay.properties
@@ -0,0 +1,4 @@
+newaddons.alert.title=Suplimente noi
+# LOCALIZATION NOTE (newaddons.alert.text):
+# %S will be the name of a collection
+newaddons.alert.text=Au apărut suplimente noi pentru abonamentul „%sâ€.
diff --git a/bandwagon/locale/ro/extensionOverlay.properties b/bandwagon/locale/ro/extensionOverlay.properties
new file mode 100644
index 0000000..ff3dc04
--- /dev/null
+++ b/bandwagon/locale/ro/extensionOverlay.properties
@@ -0,0 +1,18 @@
+publish.new.email.address.title=Adresă nouă de email
+publish.new.email.address.text=Introduceți o adresă nouă de email pentru a împărtăși suplimentul cu:
+publish.remove.title=Confirmare
+# LOCALIZATION NOTE (publish.remove.label):
+# %1 is the name of an add-on. %2 is the name of a collection
+publish.remove.label=Sigur doriți să eliminați %1$S din colecția „%2$S�
+publish.remove.button1=Nu, renunță
+publish.remove.button0=Da, elimină acest supliment
+login.error=A intervenit o eroare în timpul autentificării. Vă rugăm să verificați că utilizatorul și parola sunt corecte.
+unsubscribe.error=A intervenit o eroare în timpul dezabonării de la această colecție. Vă rugăm să încercați mai târziu.
+unsubscribe.confirm.title=Confirmare dezabonare
+unsubscribe.confirm.label=Dezabonarea de la această colecție o va elimina de asemenea din lista de favorite. Sigur doriți să vă dezabonați?
+unsubscribe.confirm.button1=Nu, renunță
+unsubscribe.confirm.button0=Da, dezabonează-mă
+unsubscribe.confirm.title=Confirm Unsubscribe
+unsubscribe.confirm.label=Unsubscribing from this collection will also remove it from your list of favorites. Are you sure you want to unsubscribe?
+unsubscribe.confirm.button1=No, cancel
+unsubscribe.confirm.button0=Yes, unsubscribe
diff --git a/bandwagon/locale/ro/extensionsOverlay.dtd b/bandwagon/locale/ro/extensionsOverlay.dtd
new file mode 100644
index 0000000..2471113
--- /dev/null
+++ b/bandwagon/locale/ro/extensionsOverlay.dtd
@@ -0,0 +1,69 @@
+<!-- ***** BEGIN LICENSE BLOCK *****
+ - Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ -
+ - The contents of this file are subject to the Mozilla Public License Version
+ - 1.1 (the "License"); you may not use this file except in compliance with
+ - the License. You may obtain a copy of the License at
+ - http://www.mozilla.org/MPL/
+ -
+ - Software distributed under the License is distributed on an "AS IS" basis,
+ - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ - for the specific language governing rights and limitations under the
+ - License.
+ -
+ - The Original Code is bandwagon.
+ -
+ - The Initial Developer of the Original Code is
+ - Mozilla Corporation.
+ - Portions created by the Initial Developer are Copyright (C) 2008
+ - the Initial Developer. All Rights Reserved.
+ -
+ - Contributor(s): Brian King <brian (at) briks (dot) si>
+ - David McNamara
+ -
+ - Alternatively, the contents of this file may be used under the terms of
+ - either the GNU General Public License Version 2 or later (the "GPL"), or
+ - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ - in which case the provisions of the GPL or the LGPL are applicable instead
+ - of those above. If you wish to allow use of your version of this file only
+ - under the terms of either the GPL or the LGPL, and not to allow others to
+ - use your version of this file under the terms of the MPL, indicate your
+ - decision by deleting the provisions above and replace them with the notice
+ - and other provisions required by the GPL or the LGPL. If you do not delete
+ - the provisions above, a recipient may use your version of this file under
+ - the terms of any one of the MPL, the GPL or the LGPL.
+ -
+ - ***** END LICENSE BLOCK ***** -->
+
+<!ENTITY collections.label "Abonamente">
+<!ENTITY search.label.bandwagon "Caută">
+
+<!ENTITY addon.moreinfo "Mai multe informații.">
+<!ENTITY addon.addtofirefox "Adaugă la Firefox">
+<!ENTITY subscribe.label "Caută colecții">
+<!ENTITY reload.label "Reîncarcă tot">
+<!ENTITY settings.label "Setări">
+
+<!ENTITY view.label "Vezi colecția">
+<!ENTITY unsubscribe.label "Dezabonare">
+
+<!ENTITY nocollectionstitle.label "Bun venit la Colectorul de suplimente">
+<!ENTITY nocollectionssubscribed.label "Aici este locul unde colecțiile pe care le marcați ca favorite pe saitul Suplimente Mozilla vor apărea pentru ca să puteți ține ușor evidența lor. Se pare că nu aveți încă favorite, așa că de ce nu aruncați o privire în directorul colecțiilor ?">
+<!ENTITY clicktosubscribe.label "Caută colecții">
+
+<!ENTITY noamoauth.label "Aici este locul unde colecțiile pe care le marcați ca favorite pe saitul Suplimente Mozilla vor apărea pentru ca să puteți ține ușor evidența lor. Trebuie să fiți autentificat(ă) pe addons.mozilla.org pentru a folosi această funcționalitate.">
+<!ENTITY username.label "Utilizator">
+<!ENTITY password.label "Parolă">
+<!ENTITY clicktologin.label "Autentificare">
+
+<!ENTITY collectionisloading.label "Se obține abonamentul...">
+<!ENTITY collectionhasnoitems.label "Colecția nu are niciun supliment.">
+<!ENTITY collectionhaserror.label "Colecția nu poate fi afișată pentru că conține erori.">
+
+<!ENTITY publishto.label "Publică la">
+<!ENTITY email.address.label "Adresă de email">
+<!ENTITY new.email.address.label "Adresă nouă de email">
+<!ENTITY new.collection.label "Colecție nouă">
+
+<!ENTITY createaccount.label "I don't have an account">
+<!ENTITY loginheading.label "Enter your Mozilla Add-ons account information below:">
diff --git a/bandwagon/locale/ro/publish.dtd b/bandwagon/locale/ro/publish.dtd
new file mode 100644
index 0000000..34a1253
--- /dev/null
+++ b/bandwagon/locale/ro/publish.dtd
@@ -0,0 +1,48 @@
+<!-- ***** BEGIN LICENSE BLOCK *****
+ - Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ -
+ - The contents of this file are subject to the Mozilla Public License Version
+ - 1.1 (the "License"); you may not use this file except in compliance with
+ - the License. You may obtain a copy of the License at
+ - http://www.mozilla.org/MPL/
+ -
+ - Software distributed under the License is distributed on an "AS IS" basis,
+ - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ - for the specific language governing rights and limitations under the
+ - License.
+ -
+ - The Original Code is bandwagon.
+ -
+ - The Initial Developer of the Original Code is
+ - Mozilla Corporation.
+ - Portions created by the Initial Developer are Copyright (C) 2008
+ - the Initial Developer. All Rights Reserved.
+ -
+ - Contributor(s): David McNamara
+ - Brian King <brian (at) briks (dot) si>
+ -
+ - Alternatively, the contents of this file may be used under the terms of
+ - either the GNU General Public License Version 2 or later (the "GPL"), or
+ - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ - in which case the provisions of the GPL or the LGPL are applicable instead
+ - of those above. If you wish to allow use of your version of this file only
+ - under the terms of either the GPL or the LGPL, and not to allow others to
+ - use your version of this file under the terms of the MPL, indicate your
+ - decision by deleting the provisions above and replace them with the notice
+ - and other provisions required by the GPL or the LGPL. If you do not delete
+ - the provisions above, a recipient may use your version of this file under
+ - the terms of any one of the MPL, the GPL or the LGPL.
+ -
+ - ***** END LICENSE BLOCK ***** -->
+
+<!-- For localisers to change the width of the window -->
+<!ENTITY publish.style "width: 35em;">
+
+<!ENTITY window.title "Publică">
+<!ENTITY cancel.label "Renunță">
+<!ENTITY publish.label "Publică">
+<!ENTITY new.email.label "Adresă nouă de email">
+<!ENTITY enter.an.email.label "Introduceți una sau mai multe adrese de email separate de virgulă:">
+<!ENTITY remember.this.email.label "Memorează această adresă de email">
+<!ENTITY enter.a.personal.note.label "Opțional: introduceți un mesaj despre acest supliment pentru a fi inclus în email">
+
diff --git a/bandwagon/locale/ro/publish.properties b/bandwagon/locale/ro/publish.properties
new file mode 100644
index 0000000..25976b4
--- /dev/null
+++ b/bandwagon/locale/ro/publish.properties
@@ -0,0 +1,20 @@
+# LOCALIZATION NOTE (you.are.sharing.the.add.on):
+# %S is the name of an add-on
+you.are.sharing.the.add.on=ÃŽmpărtășiÈ›i suplimentul „%sâ€
+# LOCALIZATION NOTE (publishing.to):
+# %1 is the name of an add-on. %2 is the name of a collection
+publishing.to=Apăsând „Publică†veÈ›i adăuga %1$S la colecÈ›ia „%2$Sâ€.
+# LOCALIZATION NOTE (sharing.with):
+# %1 is a user's email address. $2 is the name of an add-on
+sharing.with=Apăsând „Trimite email†veți trimite un email către %1$S cu informații despre %2$S
+# LOCALIZATION NOTE (sharing.with.new):
+# %S is the name of an add-on
+sharing.with.new=Apăsând „Trimite email†veți trimite destinatarilor de mai sus un email cu informații despre %S
+please.enter.an.email.address=Vă rugăm să introduceți o adresă de email.
+the.addon.has.been.published=Suplimentul a fost publicat.
+the.email.has.been.sent=Emailul a fost trimis.
+# LOCALIZATION NOTE (closing.in):
+# %S is the number of seconds until a window closes, counting down
+closing.in=Închidere în %S...
+send.email=Trimite email
+error.unknown_addon_guid=Acest supliment nu poate fi împărtășit pentru că nu este găzduit pe saitul Suplimente Mozilla.
diff --git a/bandwagon/locale/ro/settings.dtd b/bandwagon/locale/ro/settings.dtd
new file mode 100644
index 0000000..da2c62c
--- /dev/null
+++ b/bandwagon/locale/ro/settings.dtd
@@ -0,0 +1,108 @@
+<!-- ***** BEGIN LICENSE BLOCK *****
+ - Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ -
+ - The contents of this file are subject to the Mozilla Public License Version
+ - 1.1 (the "License"); you may not use this file except in compliance with
+ - the License. You may obtain a copy of the License at
+ - http://www.mozilla.org/MPL/
+ -
+ - Software distributed under the License is distributed on an "AS IS" basis,
+ - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ - for the specific language governing rights and limitations under the
+ - License.
+ -
+ - The Original Code is bandwagon.
+ -
+ - The Initial Developer of the Original Code is
+ - Mozilla Corporation.
+ - Portions created by the Initial Developer are Copyright (C) 2008
+ - the Initial Developer. All Rights Reserved.
+ -
+ - Contributor(s): Brian King <brian (at) briks (dot) si>
+ - David McNamara
+ -
+ - Alternatively, the contents of this file may be used under the terms of
+ - either the GNU General Public License Version 2 or later (the "GPL"), or
+ - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ - in which case the provisions of the GPL or the LGPL are applicable instead
+ - of those above. If you wish to allow use of your version of this file only
+ - under the terms of either the GPL or the LGPL, and not to allow others to
+ - use your version of this file under the terms of the MPL, indicate your
+ - decision by deleting the provisions above and replace them with the notice
+ - and other provisions required by the GPL or the LGPL. If you do not delete
+ - the provisions above, a recipient may use your version of this file under
+ - the terms of any one of the MPL, the GPL or the LGPL.
+ -
+ - ***** END LICENSE BLOCK ***** -->
+
+<!-- For localisers to change the width of the window -->
+<!ENTITY settings.style "width: 42em;">
+
+<!ENTITY window.title "Setări pentru colecționarea de suplimente">
+
+<!-- Tabs -->
+<!ENTITY manage.label "Gestionează abonamentele">
+<!ENTITY general.label "Setări generale">
+<!ENTITY pub.label "Setări de publicare automată">
+
+<!-- Manage Subscriptions -->
+<!ENTITY subscriptions.header "Abonamente:">
+
+<!-- Groupbox captions in Manage Subscriptions -->
+<!ENTITY frequency.label "Frecvența de actualizare a abonamentului">
+<!ENTITY notifications.label "Notificare la supliment nou">
+<!ENTITY perpage.label "Suplimente pe pagină">
+
+<!ENTITY default.label "Folosește setarea implicită">
+<!ENTITY custom.label "Personalizat:">
+
+<!ENTITY addonsleadin.label "Arată">
+<!ENTITY addonsperpage.label "suplimente pe pagină">
+<!ENTITY updatesingle.label "Actualizează la fiecare:">
+<!ENTITY minutes.label "minut(e)">
+<!ENTITY hours.label "ore">
+<!ENTITY days.label "zi(le)">
+<!ENTITY autopublish.label "Publică automat suplimentele instalate în abonament">
+<!ENTITY notify.label "Arată notificări">
+<!ENTITY applyall.label "Aplică la toate abonamentele">
+<!ENTITY remove.label "Renunță la abonament">
+<!ENTITY on.label "Activată">
+<!ENTITY off.label "Dezactivată">
+
+<!-- General -->
+
+<!-- Groupbox captions in General -->
+<!ENTITY subscriptions.label "Setări implicite pentru abonare">
+<!ENTITY data.label "Gestionare date">
+
+<!ENTITY updateall.label "Caută actualizări pentru abonamente la fiecare">
+<!ENTITY notifyglobal.label "Anunță-mă când abonamentele mele au suplimente noi">
+
+<!ENTITY clearemails.label "Curăță">
+<!ENTITY login.label "Autentificare">
+<!ENTITY logout.label "Ieșire">
+
+<!-- Auto-Publisher Settings -->
+
+<!-- Groupbox captions in Auto-Publisher Settings -->
+<!ENTITY auto.label "Setări de publicare automată">
+
+<!ENTITY name.label "Nume colecție:">
+<!ENTITY list.label "Listată public în directorul de colecții">
+
+<!ENTITY autoleadin.label "Publicările automate sunt colecții speciale actualizate automat când instalați sau dezinstalați suplimente din Firefox.">
+<!ENTITY types.label "Tipuri de suplimente publicate automat:">
+<!ENTITY type.extensions.label "Extensii">
+<!ENTITY type.themes.label "Teme">
+<!ENTITY type.dicts.label "Dicționare">
+<!ENTITY type.langpacks.label "Pachete de limbă">
+
+<!ENTITY createauto.label "Creează colecția publicată automat">
+<!ENTITY deleteauto.label "Șterge colecția publicată automat">
+<!ENTITY updateauto.label "Actualizează colecția publicată automat">
+
+<!ENTITY onlypublishenabledaddons.label "Publică doar suplimentele activate">
+
+<!ENTITY misc.label "Diverse">
+<!ENTITY allowincompatibleinstall.label "Permite instalarea suplimentelor incompatibile din abonamentele mele">
+
diff --git a/bandwagon/locale/ro/settings.properties b/bandwagon/locale/ro/settings.properties
new file mode 100644
index 0000000..62642f8
--- /dev/null
+++ b/bandwagon/locale/ro/settings.properties
@@ -0,0 +1,29 @@
+add.collection=Adaugă un abonament
+enter.url.to.add.collection=Introduceți adresa abonamentului pe care doriți să-l adăugați.
+remove.collection=Renunță la abonament
+# LOCALIZATION NOTE (are.you.sure.you.want.to.remove):
+# %S is the name of a collection
+are.you.sure.you.want.to.remove=Eliminarea acestui abonament îl va elimina de asemenea din lista de favorite. Sigur doriți să eliminați „%S�
+# LOCALIZATION NOTE (saved.emails.text):
+# %S is a number
+saved.emails.text=Aveți %S adrese de email salvate
+# LOCALIZATION NOTE (login.status.with.email):
+# %S is a user's email address
+login.status.with.email=Sunteți autentificat(ă) ca %S
+login.status=Sunteți autentificat(ă)
+logout.status=Nu sunteți autentificat(ă)
+# LOCALIZATION NOTE (auto.invalid.name):
+# %S is the name of a collection
+auto.invalid.name=Numele de colecție „%S†nu este valid.
+auto.please.select.type=Vă rugăm să selectați cel puțin un tip de supliment pentru publicare automată.
+auto.create.internal.error=Colecția nu a putut fi creată (a intervenit o eroare internă).
+auto.create.done=S-a creat colecția dumneavoastră publicată automat.
+auto.delete.internal.error=Nu s-a putut șterge colecția (a intervenit o eroare internă).
+auto.delete.done=S-a șters colecția dumneavoastră publicată automat.
+auto.create.description=O listă a suplimentelor mele, generată automat
+auto.update.confirm.message=Noile setări vor avea efect imediat, dar nu vor afecta suplimentele care au fost deja publicate.
+auto.update.internal.error=Colecția nu a putut fi actualizată (a intervenit o eroare internă).
+auto.update.done=S-a actualizat colecția dumneavoastră publicată automat.
+auto.update.confirm.message=Your new settings will take effect immediately, but will not affect add-ons that have already been published.
+auto.update.internal.error=The collection could not be updated (an internal error occured).
+auto.update.done=Your auto-pubisher collection has been updated.
diff --git a/bandwagon/locale/ru/bandwagon.properties b/bandwagon/locale/ru/bandwagon.properties
new file mode 100644
index 0000000..13dd446
--- /dev/null
+++ b/bandwagon/locale/ru/bandwagon.properties
@@ -0,0 +1,2 @@
+extensions.sharing@addons.mozilla.org.description=С ним вы можете делитьÑÑ Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñми и открывать Ð´Ð»Ñ ÑÐµÐ±Ñ Ð½Ð¾Ð²Ñ‹Ðµ.
+extensions.sharing@addons.mozilla.org.name=Собиратель Дополнений
diff --git a/bandwagon/locale/ru/bandwagonAddon.properties b/bandwagon/locale/ru/bandwagonAddon.properties
new file mode 100644
index 0000000..cd9ff17
--- /dev/null
+++ b/bandwagon/locale/ru/bandwagonAddon.properties
@@ -0,0 +1,39 @@
+# LOCALIZATION NOTE (bandwagon.addon.pluralRule):
+# See https://developer.mozilla.org/En/Localization_and_Plurals
+bandwagon.addon.pluralRule=7
+bandwagon.category1=РаÑширение
+# LOCALIZATION NOTE (bandwagon.addon.author):
+# %S will contain author's first and last name, or their nickname used on AMO
+bandwagon.addon.author=По %S
+# LOCALIZATION NOTE (bandwagon.addon.addedby):
+# %S will be a user's first and last name, or nickname
+bandwagon.addon.addedby=по %S
+bandwagon.addon.added.justnow=Добавлено: ПрÑмо ÑейчаÑ
+# LOCALIZATION NOTE:
+# %S will be a number of time units indicated
+bandwagon.addon.added.minute=Добавлено: %S минуту назад;Добавлено: %S minutes назад;Добавлено: %S minutes назад
+bandwagon.addon.added.hour=Добавлено: %S Ñ‡Ð°Ñ Ð½Ð°Ð·Ð°Ð´;Добавлено: %S чаÑа назад;Добавлено: %S чаÑов назад
+bandwagon.addon.added.day=Добавлено: %S день назад;Добавлено: %S Ð´Ð½Ñ Ð½Ð°Ð·Ð°Ð´;Добавлено: %S дней назад
+bandwagon.addon.added.week=Добавлено: %S неделю назад;Добавлено: %S недели назад;Добавлено: %S недель назад
+bandwagon.addon.added.month=Добавлено: %S меÑÑц назад;Добавлено: %S меÑÑца назад;Добавлено %S меÑÑцев назад
+bandwagon.addon.added.year=Добавлено: %S год назад;Добавлено: %S года назад;Добавлено: %S лет назад
+bandwagon.addon.moreinfo=Подробнее.
+bandwagon.addon.olderversionsoffirefox=Это дополнение работает Ñо Ñтарыми верÑиÑми Firefox.
+# LOCALIZATION NOTE (upgradetofirefoxn1):
+# %S will be a Firefox version number
+bandwagon.addon.upgradetofirefoxn1=ОбновитеÑÑŒ на Firefox %S
+bandwagon.addon.upgradetofirefoxn2=чтобы иÑпользовать Ñто дополнение.
+# LOCALIZATION NOTE (bandwagon.addon.requiresfirefoxbeta1/requiresfirefoxbeta2):
+# %S will be a Firefox version number
+bandwagon.addon.requiresfirefoxbeta1=Это дополнение требует Ð´Ð»Ñ Ñ€Ð°Ð±Ð¾Ñ‚Ñ‹ Firefox %S, который ещё не вышел. Чтобы иÑпользовать Ñто дополнение, вы можете
+bandwagon.addon.requiresfirefoxbeta2=загрузить Firefox %S beta.
+# LOCALIZATION NOTE (bandwagon.addon.notcompatible):
+# %S will be a platform name, such as "Windows"
+bandwagon.addon.notcompatible=Это дополнение не ÑовмеÑтимо Ñ %S.
+# LOCALIZATION NOTE (bandwagon.addon.comment.description):
+# %S will be a comment entered by the publisher of the add-on
+bandwagon.addon.comment.description=“%Sâ€
+# LOCALIZATION NOTE (bandwagon.addon.comment.author):
+# %S will be the publisher's real name or nickname
+bandwagon.addon.comment.author=Комментарий от %S:
+bandwagon.addon.isexperimental=Это раÑширение ÑвлÑетÑÑ ÑкÑпериментальным и не может быть уÑтановлено
diff --git a/bandwagon/locale/ru/browserOverlay.dtd b/bandwagon/locale/ru/browserOverlay.dtd
new file mode 100644
index 0000000..5bc3f94
--- /dev/null
+++ b/bandwagon/locale/ru/browserOverlay.dtd
@@ -0,0 +1,38 @@
+<!-- ***** BEGIN LICENSE BLOCK *****
+ - Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ -
+ - The contents of this file are subject to the Mozilla Public License Version
+ - 1.1 (the "License"); you may not use this file except in compliance with
+ - the License. You may obtain a copy of the License at
+ - http://www.mozilla.org/MPL/
+ -
+ - Software distributed under the License is distributed on an "AS IS" basis,
+ - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ - for the specific language governing rights and limitations under the
+ - License.
+ -
+ - The Original Code is bandwagon.
+ -
+ - The Initial Developer of the Original Code is
+ - Mozilla Corporation.
+ - Portions created by the Initial Developer are Copyright (C) 2008
+ - the Initial Developer. All Rights Reserved.
+ -
+ - Contributor(s): Brian King <brian (at) briks (dot) si>
+ -
+ - Alternatively, the contents of this file may be used under the terms of
+ - either the GNU General Public License Version 2 or later (the "GPL"), or
+ - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ - in which case the provisions of the GPL or the LGPL are applicable instead
+ - of those above. If you wish to allow use of your version of this file only
+ - under the terms of either the GPL or the LGPL, and not to allow others to
+ - use your version of this file under the terms of the MPL, indicate your
+ - decision by deleting the provisions above and replace them with the notice
+ - and other provisions required by the GPL or the LGPL. If you do not delete
+ - the provisions above, a recipient may use your version of this file under
+ - the terms of any one of the MPL, the GPL or the LGPL.
+ -
+ - ***** END LICENSE BLOCK ***** -->
+
+<!ENTITY bandwagon.label "ДополнениÑ">
+<!ENTITY bandwagon.tooltip "ДополнениÑ">
diff --git a/bandwagon/locale/ru/browserOverlay.properties b/bandwagon/locale/ru/browserOverlay.properties
new file mode 100644
index 0000000..11ff86c
--- /dev/null
+++ b/bandwagon/locale/ru/browserOverlay.properties
@@ -0,0 +1,4 @@
+newaddons.alert.title=Ðовые дополнениÑ
+# LOCALIZATION NOTE (newaddons.alert.text):
+# %S will be the name of a collection
+newaddons.alert.text=Ð’ вашей подпиÑке "%S" поÑвилиÑÑŒ новые дополнениÑ.
diff --git a/bandwagon/locale/ru/contents.rdf b/bandwagon/locale/ru/contents.rdf
new file mode 100644
index 0000000..bea656e
--- /dev/null
+++ b/bandwagon/locale/ru/contents.rdf
@@ -0,0 +1,15 @@
+<?xml version="1.0"?>
+<RDF:RDF xmlns:RDF="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:chrome="http://www.mozilla.org/rdf/chrome#">
+ <RDF:Seq about="urn:mozilla:locale:root">
+ <RDF:li resource="urn:mozilla:locale:ru"/>
+ </RDF:Seq>
+ <RDF:Description about="urn:mozilla:locale:ru" chrome:name="ru" >
+ <chrome:packages>
+ <RDF:Seq about="urn:mozilla:locale:ru:packages">
+ <RDF:li resource="urn:mozilla:locale:ru:bandwagon"/>
+ </RDF:Seq>
+ </chrome:packages>
+ </RDF:Description>
+</RDF:RDF>
+
diff --git a/bandwagon/locale/ru/extensionOverlay.properties b/bandwagon/locale/ru/extensionOverlay.properties
new file mode 100644
index 0000000..d70ad43
--- /dev/null
+++ b/bandwagon/locale/ru/extensionOverlay.properties
@@ -0,0 +1,14 @@
+publish.new.email.address.title=Ðовый Ð°Ð´Ñ€ÐµÑ Ñл. почты
+publish.new.email.address.text=Введите новый Ð°Ð´Ñ€ÐµÑ Ñл. почты, чтобы поделитьÑÑ Ñтим дополнением Ñ:
+publish.remove.title=Подтверждение
+# LOCALIZATION NOTE (publish.remove.label):
+# %1 is the name of an add-on. %2 is the name of a collection
+publish.remove.label=Вы уверены, что хотите удалить %1$S из подборки "%2$S"?
+publish.remove.button1=Ðет, отменить
+publish.remove.button0=Да, удалить дополнение
+login.error=При попытке входа произошла ошибка. ПожалуйÑта, проверьте корректноÑÑ‚ÑŒ ввода вашего имени Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ð¸ паролÑ.
+unsubscribe.error=При отпиÑке от Ñтой подборки произошла ошибка. ПожалуйÑта, попробуйте позже.
+unsubscribe.confirm.title=Подтверждение отпиÑки
+unsubscribe.confirm.label=Прекращение подпиÑки на Ñту подборку приведёт также к её удалению из вашего ÑпиÑка избранных. Ð’Ñ‹ уверены, что хотите отпиÑатьÑÑ?
+unsubscribe.confirm.button1=Ðет, отменить
+unsubscribe.confirm.button0=Да, отпиÑатьÑÑ
diff --git a/bandwagon/locale/ru/extensionsOverlay.dtd b/bandwagon/locale/ru/extensionsOverlay.dtd
new file mode 100644
index 0000000..f1a3daf
--- /dev/null
+++ b/bandwagon/locale/ru/extensionsOverlay.dtd
@@ -0,0 +1,69 @@
+<!-- ***** BEGIN LICENSE BLOCK *****
+ - Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ -
+ - The contents of this file are subject to the Mozilla Public License Version
+ - 1.1 (the "License"); you may not use this file except in compliance with
+ - the License. You may obtain a copy of the License at
+ - http://www.mozilla.org/MPL/
+ -
+ - Software distributed under the License is distributed on an "AS IS" basis,
+ - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ - for the specific language governing rights and limitations under the
+ - License.
+ -
+ - The Original Code is bandwagon.
+ -
+ - The Initial Developer of the Original Code is
+ - Mozilla Corporation.
+ - Portions created by the Initial Developer are Copyright (C) 2008
+ - the Initial Developer. All Rights Reserved.
+ -
+ - Contributor(s): Brian King <brian (at) briks (dot) si>
+ - David McNamara
+ -
+ - Alternatively, the contents of this file may be used under the terms of
+ - either the GNU General Public License Version 2 or later (the "GPL"), or
+ - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ - in which case the provisions of the GPL or the LGPL are applicable instead
+ - of those above. If you wish to allow use of your version of this file only
+ - under the terms of either the GPL or the LGPL, and not to allow others to
+ - use your version of this file under the terms of the MPL, indicate your
+ - decision by deleting the provisions above and replace them with the notice
+ - and other provisions required by the GPL or the LGPL. If you do not delete
+ - the provisions above, a recipient may use your version of this file under
+ - the terms of any one of the MPL, the GPL or the LGPL.
+ -
+ - ***** END LICENSE BLOCK ***** -->
+
+<!ENTITY collections.label "ПодпиÑки">
+<!ENTITY search.label.bandwagon "ПоиÑк">
+
+<!ENTITY addon.moreinfo "Подробнее.">
+<!ENTITY addon.addtofirefox "Добавить в Firefox">
+<!ENTITY subscribe.label "Ðайти подборки">
+<!ENTITY reload.label "Перегрузить вÑе">
+<!ENTITY settings.label "ÐаÑтройки">
+
+<!ENTITY view.label "ПроÑмотреть подборку">
+<!ENTITY unsubscribe.label "ОтпиÑатьÑÑ">
+
+<!ENTITY nocollectionstitle.label "Добро пожаловать на Ñайт Подборок Дополнений">
+<!ENTITY nocollectionssubscribed.label "Ðа Ñтой Ñтранице отображаютÑÑ Ð¿Ð¾Ð´Ð±Ð¾Ñ€ÐºÐ¸ дополнений, выбранные вами на Ñайте дополнений Mozilla. Похоже, что вы пока ничего не выбрали, так что почему бы вам не оÑмотретьÑÑ Ð² нашем каталоге подборок дополнений?">
+<!ENTITY clicktosubscribe.label "Ðайти подборку">
+
+<!ENTITY noamoauth.label "Ðа Ñтой Ñтранице поÑвÑÑ‚ÑÑ Ð¿Ð¾Ð´Ð±Ð¾Ñ€ÐºÐ¸ дополнений, выбранные вами на Ñайте дополнений Mozilla. Ð”Ð»Ñ Ð¸ÑÐ¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ Ñтой возможноÑти вам необходимо зарегиÑтрироватьÑÑ Ð½Ð° Ñайте addons.mozilla.org.">
+<!ENTITY username.label "ÐÐ´Ñ€ÐµÑ Ñл. почты">
+<!ENTITY password.label "Пароль">
+<!ENTITY clicktologin.label "Войти">
+<!ENTITY createaccount.label "У Ð¼ÐµÐ½Ñ Ð½ÐµÑ‚ учётной запиÑи">
+<!ENTITY loginheading.label "Введите информацию из вашей учётной запиÑи на Ñайте дополнений Mozilla:">
+
+<!ENTITY collectionisloading.label "Идёт получение подпиÑки...">
+<!ENTITY collectionhasnoitems.label "Эта подборка не Ñодержит дополнений.">
+<!ENTITY collectionhaserror.label "Эта подборка не может быть отображена, так как Ñодержит ошибки.">
+
+<!ENTITY publishto.label "Опубликовать на">
+<!ENTITY email.address.label "ÐÐ´Ñ€ÐµÑ Ñлектронной почты">
+<!ENTITY new.email.address.label "Ðовый Ð°Ð´Ñ€ÐµÑ Ñлектронной почты">
+<!ENTITY new.collection.label "ÐÐ¾Ð²Ð°Ñ Ð¿Ð¾Ð´Ð±Ð¾Ñ€ÐºÐ°">
+
diff --git a/bandwagon/locale/ru/publish.dtd b/bandwagon/locale/ru/publish.dtd
new file mode 100644
index 0000000..bb963e0
--- /dev/null
+++ b/bandwagon/locale/ru/publish.dtd
@@ -0,0 +1,48 @@
+<!-- ***** BEGIN LICENSE BLOCK *****
+ - Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ -
+ - The contents of this file are subject to the Mozilla Public License Version
+ - 1.1 (the "License"); you may not use this file except in compliance with
+ - the License. You may obtain a copy of the License at
+ - http://www.mozilla.org/MPL/
+ -
+ - Software distributed under the License is distributed on an "AS IS" basis,
+ - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ - for the specific language governing rights and limitations under the
+ - License.
+ -
+ - The Original Code is bandwagon.
+ -
+ - The Initial Developer of the Original Code is
+ - Mozilla Corporation.
+ - Portions created by the Initial Developer are Copyright (C) 2008
+ - the Initial Developer. All Rights Reserved.
+ -
+ - Contributor(s): David McNamara
+ - Brian King <brian (at) briks (dot) si>
+ -
+ - Alternatively, the contents of this file may be used under the terms of
+ - either the GNU General Public License Version 2 or later (the "GPL"), or
+ - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ - in which case the provisions of the GPL or the LGPL are applicable instead
+ - of those above. If you wish to allow use of your version of this file only
+ - under the terms of either the GPL or the LGPL, and not to allow others to
+ - use your version of this file under the terms of the MPL, indicate your
+ - decision by deleting the provisions above and replace them with the notice
+ - and other provisions required by the GPL or the LGPL. If you do not delete
+ - the provisions above, a recipient may use your version of this file under
+ - the terms of any one of the MPL, the GPL or the LGPL.
+ -
+ - ***** END LICENSE BLOCK ***** -->
+
+<!-- For localisers to change the width of the window -->
+<!ENTITY publish.style "width: 35em;">
+
+<!ENTITY window.title "ПубликациÑ">
+<!ENTITY cancel.label "Отмена">
+<!ENTITY publish.label "Публиковать">
+<!ENTITY new.email.label "Ðовый Ð°Ð´Ñ€ÐµÑ Ñл. почты">
+<!ENTITY enter.an.email.label "Введите один или неÑколько адреÑов Ñл. почты, разделённых запÑтыми:">
+<!ENTITY remember.this.email.label "Запомнить Ñтот Ð°Ð´Ñ€ÐµÑ Ñл. почты">
+<!ENTITY enter.a.personal.note.label "ÐеобÑзательно: Введите заметку об Ñтом дополнении, ÐºÐ¾Ñ‚Ð¾Ñ€Ð°Ñ Ð±ÑƒÐ´ÐµÑ‚ включена в пиÑьмо">
+
diff --git a/bandwagon/locale/ru/publish.properties b/bandwagon/locale/ru/publish.properties
new file mode 100644
index 0000000..f999a2b
--- /dev/null
+++ b/bandwagon/locale/ru/publish.properties
@@ -0,0 +1,22 @@
+# LOCALIZATION NOTE (you.are.sharing.the.add.on):
+# %S is the name of an add-on
+you.are.sharing.the.add.on=Ð’Ñ‹ делитеÑÑŒ дополнением '%S'
+# LOCALIZATION NOTE (publishing.to):
+# %1 is the name of an add-on. %2 is the name of a collection
+publishing.to=Ðажатие кнопки "Публиковать" добавит %1$S в подборку "%2$S".
+# LOCALIZATION NOTE (sharing.with):
+# %1 is a user's email address. $2 is the name of an add-on
+sharing.with=Ðажатие кнопки "Отправить пиÑьмо" отправит по адреÑу %1$S пиÑьмо Ñ Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸ÐµÐ¹ о %2$S
+# LOCALIZATION NOTE (sharing.with.new):
+# %S is the name of an add-on
+sharing.with.new=Ðажатие кнопки "Отправить пиÑьмо" отправит вышеуказанным получателÑм пиÑьмо Ñ Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸ÐµÐ¹ о %S
+please.enter.an.email.address=ПожалуйÑта, введите Ð°Ð´Ñ€ÐµÑ Ñл. почты.
+the.addon.has.been.published=Дополнение было опубликовано.
+the.email.has.been.sent=ПиÑьмо было отправлено.
+# LOCALIZATION NOTE (closing.in):
+# %S is the number of seconds until a window closes, counting down
+closing.in=Будет закрыто через %S...
+send.email=Отправить пиÑьмо
+error.unknown_addon_guid=Этим дополнением Ð½ÐµÐ»ÑŒÐ·Ñ Ð¿Ð¾Ð´ÐµÐ»Ð¸Ñ‚ÑŒÑÑ, так как оно не размещено на Ñайте дополнений Mozilla.
+error.invalid_parameters=При попытке поделитьÑÑ Ñтим дополнением возникла проблема. ПожалуйÑта, проверьте корректноÑÑ‚ÑŒ ввода адреÑа Ñл. почты и Ñвоего примечаниÑ.
+enter.a.personal.publish.note.label=ÐеобÑзательно: Введите Ñвоё примечание об Ñтом дополнении, которое будет отображено при публикации.
diff --git a/bandwagon/locale/ru/settings.dtd b/bandwagon/locale/ru/settings.dtd
new file mode 100644
index 0000000..bbb8bf6
--- /dev/null
+++ b/bandwagon/locale/ru/settings.dtd
@@ -0,0 +1,108 @@
+<!-- ***** BEGIN LICENSE BLOCK *****
+ - Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ -
+ - The contents of this file are subject to the Mozilla Public License Version
+ - 1.1 (the "License"); you may not use this file except in compliance with
+ - the License. You may obtain a copy of the License at
+ - http://www.mozilla.org/MPL/
+ -
+ - Software distributed under the License is distributed on an "AS IS" basis,
+ - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ - for the specific language governing rights and limitations under the
+ - License.
+ -
+ - The Original Code is bandwagon.
+ -
+ - The Initial Developer of the Original Code is
+ - Mozilla Corporation.
+ - Portions created by the Initial Developer are Copyright (C) 2008
+ - the Initial Developer. All Rights Reserved.
+ -
+ - Contributor(s): Brian King <brian (at) briks (dot) si>
+ - David McNamara
+ -
+ - Alternatively, the contents of this file may be used under the terms of
+ - either the GNU General Public License Version 2 or later (the "GPL"), or
+ - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ - in which case the provisions of the GPL or the LGPL are applicable instead
+ - of those above. If you wish to allow use of your version of this file only
+ - under the terms of either the GPL or the LGPL, and not to allow others to
+ - use your version of this file under the terms of the MPL, indicate your
+ - decision by deleting the provisions above and replace them with the notice
+ - and other provisions required by the GPL or the LGPL. If you do not delete
+ - the provisions above, a recipient may use your version of this file under
+ - the terms of any one of the MPL, the GPL or the LGPL.
+ -
+ - ***** END LICENSE BLOCK ***** -->
+
+<!-- For localisers to change the width of the window -->
+<!ENTITY settings.style "width: 42em;">
+
+<!ENTITY window.title "Параметры Ð¡Ð¾Ð±Ð¸Ñ€Ð°Ñ‚ÐµÐ»Ñ Ð”Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ð¹">
+
+<!-- Tabs -->
+<!ENTITY manage.label "Управление подпиÑками">
+<!ENTITY general.label "Общие наÑтройки">
+<!ENTITY pub.label "ÐаÑтройки автоматичеÑкой публикации">
+
+<!-- Manage Subscriptions -->
+<!ENTITY subscriptions.header "ПодпиÑки:">
+
+<!-- Groupbox captions in Manage Subscriptions -->
+<!ENTITY frequency.label "ЧаÑтота Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ð¿Ð¾Ð´Ð¿Ð¸Ñки">
+<!ENTITY notifications.label "Ð£Ð²ÐµÐ´Ð¾Ð¼Ð»ÐµÐ½Ð¸Ñ Ð¾ новых дополнениÑÑ…">
+<!ENTITY perpage.label "Дополнений на Ñтраницу">
+
+<!ENTITY default.label "ИÑпользовать наÑтройку по умолчанию">
+<!ENTITY custom.label "ÐаÑтроить:">
+
+<!ENTITY addonsleadin.label "Показывать">
+<!ENTITY addonsperpage.label "дополнений на Ñтраницу">
+<!ENTITY updatesingle.label "ОбновлÑÑ‚ÑŒ каждые:">
+<!ENTITY minutes.label "минут">
+<!ENTITY hours.label "чаÑов">
+<!ENTITY days.label "дней">
+<!ENTITY autopublish.label "ÐвтоматичеÑки публиковать в подпиÑку уÑтановленные дополнениÑ">
+<!ENTITY notify.label "Показывать уведомлениÑ">
+<!ENTITY applyall.label "Применить ко вÑем подпиÑкам">
+<!ENTITY remove.label "Удалить подпиÑку">
+<!ENTITY on.label "Вкл.">
+<!ENTITY off.label "Выкл.">
+
+<!-- General -->
+
+<!-- Groupbox captions in General -->
+<!ENTITY subscriptions.label "ÐаÑтройки подпиÑки по умолчанию">
+<!ENTITY data.label "Управление данными">
+
+<!ENTITY updateall.label "ПроверÑÑ‚ÑŒ Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ð¿Ð¾Ð´Ð¿Ð¸Ñок каждые">
+<!ENTITY notifyglobal.label "УведомлÑÑ‚ÑŒ менÑ, когда в моих подпиÑках me поÑвлÑÑŽÑ‚ÑÑ Ð½Ð¾Ð²Ñ‹Ðµ дополнениÑ">
+
+<!ENTITY clearemails.label "ОчиÑтить">
+<!ENTITY login.label "Войти">
+<!ENTITY logout.label "Выйти">
+
+<!-- Auto-Publisher Settings -->
+
+<!-- Groupbox captions in Auto-Publisher Settings -->
+<!ENTITY auto.label "ÐаÑтройки авто-публикации">
+
+<!ENTITY name.label "Ð˜Ð¼Ñ Ð¿Ð¾Ð´Ð±Ð¾Ñ€ÐºÐ¸:">
+<!ENTITY list.label "ОтображаетÑÑ Ð² каталоге публичных подборок">
+
+<!ENTITY autoleadin.label "Ðвто-публикации - Ñто Ñпециальные подборки, которые автоматичеÑки обновлÑÑŽÑ‚ÑÑ, когда вы уÑтанавливаете или удалÑете Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð² Firefox на Ñтом компьютере.">
+<!ENTITY types.label "ÐвтоматичеÑки публиковать Ñледующие типы дополнений:">
+<!ENTITY type.extensions.label "РаÑширениÑ">
+<!ENTITY type.themes.label "Темы">
+<!ENTITY type.dicts.label "Словари">
+<!ENTITY type.langpacks.label "Локализации">
+
+<!ENTITY createauto.label "Создать авто-публикацию">
+<!ENTITY deleteauto.label "Удалить авто-публикацию">
+<!ENTITY updateauto.label "Обновить авто-публикацию">
+
+<!ENTITY onlypublishenabledaddons.label "Публиковать только включённые дополнениÑ">
+
+<!ENTITY misc.label "Разное">
+<!ENTITY allowincompatibleinstall.label "Разрешить уÑтановку неÑовмеÑтимых дополнений из моих подпиÑок">
+
diff --git a/bandwagon/locale/ru/settings.properties b/bandwagon/locale/ru/settings.properties
new file mode 100644
index 0000000..67bce1f
--- /dev/null
+++ b/bandwagon/locale/ru/settings.properties
@@ -0,0 +1,26 @@
+add.collection=Добавить подпиÑку
+enter.url.to.add.collection=Введите Ð°Ð´Ñ€ÐµÑ Ð¿Ð¾Ð´Ð¿Ð¸Ñки, которую вы хотите добавить.
+remove.collection=Удалить подпиÑку
+# LOCALIZATION NOTE (are.you.sure.you.want.to.remove):
+# %S is the name of a collection
+are.you.sure.you.want.to.remove=Удаление Ñтой подпиÑки приведёт также к удалению подборки из вашего ÑпиÑка избранных. Ð’Ñ‹ уверены, что хотите удалить '%S'?
+# LOCALIZATION NOTE (saved.emails.text):
+# %S is a number
+saved.emails.text=У Ð²Ð°Ñ Ð¸Ð¼ÐµÐµÑ‚ÑÑ %S Ñохранённых адреÑов Ñл. почты
+# LOCALIZATION NOTE (login.status.with.email):
+# %S is a user's email address
+login.status.with.email=Вы вошли под именем %S
+login.status=вы вошли
+logout.status=Вы не вошли
+# LOCALIZATION NOTE (auto.invalid.name):
+# %S is the name of a collection
+auto.invalid.name=Ð˜Ð¼Ñ Ð¿Ð¾Ð´Ð±Ð¾Ñ€ÐºÐ¸ '%S' некорректно.
+auto.please.select.type=ПожалуйÑта, выберите по крайней мере один тип дополнений Ð´Ð»Ñ Ð°Ð²Ñ‚Ð¾Ð¼Ð°Ñ‚Ð¸Ñ‡ÐµÑкой публикации.
+auto.create.internal.error=Ðе удалоÑÑŒ Ñоздать подборку (произошла внутреннÑÑ Ð¾ÑˆÐ¸Ð±ÐºÐ°).
+auto.create.done=Ваша подборка автоматичеÑкой публикации была уÑпешно Ñоздана.
+auto.delete.internal.error=Ðе удалоÑÑŒ удалить подборку (произошла внутреннÑÑ Ð¾ÑˆÐ¸Ð±ÐºÐ°).
+auto.delete.done=Ваша подборка автоматичеÑкой публикации была уÑпешно удалёна.
+auto.create.description=ÐвтоматичеÑки Ñгенерированный ÑпиÑок уÑтановленных у Ð¼ÐµÐ½Ñ Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ð¹
+auto.update.confirm.message=Ваши новые наÑтройки вÑтупÑÑ‚ в дейÑтвие немедленно, но не повлиÑÑŽÑ‚ на уже опубликованные дополнениÑ.
+auto.update.internal.error=Ðе удалоÑÑŒ обновить подборку (произошла внутреннÑÑ Ð¾ÑˆÐ¸Ð±ÐºÐ°).
+auto.update.done=Ваша подборка автоматичеÑкой публикации была уÑпешно обновлёна.
diff --git a/bandwagon/locale/sk/bandwagon.properties b/bandwagon/locale/sk/bandwagon.properties
new file mode 100644
index 0000000..eb6b63e
--- /dev/null
+++ b/bandwagon/locale/sk/bandwagon.properties
@@ -0,0 +1,2 @@
+extensions.sharing@addons.mozilla.org.description=Zdieľajte a objavujte doplnky.
+extensions.sharing@addons.mozilla.org.name=Add-on Collector
diff --git a/bandwagon/locale/sk/bandwagonAddon.properties b/bandwagon/locale/sk/bandwagonAddon.properties
new file mode 100644
index 0000000..5ef6f2b
--- /dev/null
+++ b/bandwagon/locale/sk/bandwagonAddon.properties
@@ -0,0 +1,56 @@
+# LOCALIZATION NOTE (bandwagon.addon.pluralRule):
+
+# See https://developer.mozilla.org/En/Localization_and_Plurals
+
+bandwagon.addon.pluralRule=8
+bandwagon.category1=Rozšírenie
+# LOCALIZATION NOTE (bandwagon.addon.author):
+
+# %S will contain author's first and last name, or their nickname used on AMO
+
+bandwagon.addon.author=Autor: %S
+# LOCALIZATION NOTE (bandwagon.addon.addedby):
+
+# %S will be a user's first and last name, or nickname
+
+bandwagon.addon.addedby=Pridal: %S
+bandwagon.addon.added.justnow=Pridané: len teraz
+# LOCALIZATION NOTE:
+
+# %S will be a number of time units indicated
+
+bandwagon.addon.added.minute=Pridané: pred minútou; Pridané: pred %S minútami;Pridané: pred %S minútami
+bandwagon.addon.added.hour=Pridané: pred minútou; Pridané: pred %S minútami;Pridané: pred %S minútami
+bandwagon.addon.added.day=Pridané: vÄera; Pridané: pred %S dňami;Pridané: pred %S dňami
+bandwagon.addon.added.week=Pridané: pred týždňom; Pridané: pred %S týždňami;Pridané: pred %S týždňami
+bandwagon.addon.added.month=Pridané: pred mesiacom; Pridané: pred %S mesiacmi;Pridané: pred %S mesiacmi
+bandwagon.addon.added.year=Pridané: pred rokom; Pridané: pred %S rokmi;Pridané: pred %S rokmi
+bandwagon.addon.moreinfo=Viac informácií
+bandwagon.addon.olderversionsoffirefox=Tento doplnok je urÄený pre starÅ¡ie verzie Firefoxu.
+# LOCALIZATION NOTE (upgradetofirefoxn1):
+
+# %S will be a Firefox version number
+
+bandwagon.addon.upgradetofirefoxn1=Ak chcete používať túto verziu, aktualizujte na Firefox %S
+bandwagon.addon.upgradetofirefoxn2=.
+# LOCALIZATION NOTE (bandwagon.addon.requiresfirefoxbeta1/requiresfirefoxbeta2):
+
+# %S will be a Firefox version number
+
+bandwagon.addon.requiresfirefoxbeta1=Tento doplnok vyžaduje Firefox %S, ktorý zatiaľ nebol oficiálne vydaný. Ak chcete tento doplnok používať, môžete si
+bandwagon.addon.requiresfirefoxbeta2=prevziať Firefox %S beta.
+# LOCALIZATION NOTE (bandwagon.addon.notcompatible):
+
+# %S will be a platform name, such as "Windows"
+
+bandwagon.addon.notcompatible=Tento doplnok nie je kompatibilný s platformou %S.
+# LOCALIZATION NOTE (bandwagon.addon.comment.description):
+
+# %S will be a comment entered by the publisher of the add-on
+
+bandwagon.addon.comment.description=“%Sâ€
+# LOCALIZATION NOTE (bandwagon.addon.comment.author):
+
+# %S will be the publisher's real name or nickname
+
+bandwagon.addon.comment.author=Komentár od %S:
diff --git a/bandwagon/locale/sk/browserOverlay.dtd b/bandwagon/locale/sk/browserOverlay.dtd
new file mode 100644
index 0000000..55663e4
--- /dev/null
+++ b/bandwagon/locale/sk/browserOverlay.dtd
@@ -0,0 +1,3 @@
+<!-- ***** BEGIN LICENSE BLOCK ***** - Version: MPL 1.1/GPL 2.0/LGPL 2.1 - - The contents of this file are subject to the Mozilla Public License Version - 1.1 (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - http://www.mozilla.org/MPL/ - - Software distributed under the License is distributed on an "AS IS" basis, - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - for the specific language governing rights and limitations under the - License. - - The Original Code is bandwagon. - - The Initial Developer of the Original Code is - Mozilla Corporation. - Portions created by the Initial Developer are Copyright (C) 2008 - the Initial Developer. All Rights Reserved. - - Contributor(s): Brian King <brian (at) briks (dot) si> - - Alternatively, the contents of this file may be used under the terms of - either the GNU General Public License Version 2 or later (the "GPL"), or - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - in which case the provisions of the GPL or the LGPL are applicable instead - of those above. If you wish to allow use of your version of this file only - under the terms of either the GPL or the LGPL, and not to allow others to - use your version of this file under the terms of the MPL, indicate your - decision by deleting the provisions above and replace them with the notice - and other provisions required by the GPL or the LGPL. If you do not delete - the provisions above, a recipient may use your version of this file under - the terms of any one of the MPL, the GPL or the LGPL. - - ***** END LICENSE BLOCK ***** -->
+<!ENTITY bandwagon.label "Doplnky">
+<!ENTITY bandwagon.tooltip "Doplnky">
diff --git a/bandwagon/locale/sk/browserOverlay.properties b/bandwagon/locale/sk/browserOverlay.properties
new file mode 100644
index 0000000..65ac8fd
--- /dev/null
+++ b/bandwagon/locale/sk/browserOverlay.properties
@@ -0,0 +1,6 @@
+newaddons.alert.title=Nové doplnky
+# LOCALIZATION NOTE (newaddons.alert.text):
+
+# %S will be the name of a collection
+
+newaddons.alert.text=Vo vašej kolekcii "%S" sa nachádzajú nové doplnky.
diff --git a/bandwagon/locale/sk/contents.rdf b/bandwagon/locale/sk/contents.rdf
new file mode 100644
index 0000000..f66e112
--- /dev/null
+++ b/bandwagon/locale/sk/contents.rdf
@@ -0,0 +1,15 @@
+<?xml version="1.0"?>
+<RDF:RDF xmlns:RDF="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:chrome="http://www.mozilla.org/rdf/chrome#">
+ <RDF:Seq about="urn:mozilla:locale:root">
+ <RDF:li resource="urn:mozilla:locale:sk"/>
+ </RDF:Seq>
+ <RDF:Description about="urn:mozilla:locale:sk" chrome:name="sk" >
+ <chrome:packages>
+ <RDF:Seq about="urn:mozilla:locale:sk:packages">
+ <RDF:li resource="urn:mozilla:locale:sk:bandwagon"/>
+ </RDF:Seq>
+ </chrome:packages>
+ </RDF:Description>
+</RDF:RDF>
+
diff --git a/bandwagon/locale/sk/extensionOverlay.properties b/bandwagon/locale/sk/extensionOverlay.properties
new file mode 100644
index 0000000..caf43d6
--- /dev/null
+++ b/bandwagon/locale/sk/extensionOverlay.properties
@@ -0,0 +1,16 @@
+publish.new.email.address.title=Nová e-mailová adresa
+publish.new.email.address.text=Zadajte novú e-mailovú adresu, s ktorou chcete tento doplnok zdieľať:
+publish.remove.title=Potvrdenie
+# LOCALIZATION NOTE (publish.remove.label):
+
+# %1 is the name of an add-on. %2 is the name of a collection
+
+publish.remove.label=Naozaj chcete odstrániť doplnok %1$S z kolekcie "%2$S"?
+publish.remove.button1=Nie, zrušiť
+publish.remove.button0=Ãno, odstrániÅ¥ doplnok
+login.error=Pri prihlasovaní sa vyskytla chyba. Uistite sa, že používateľské meno a heslo sú správne.
+unsubscribe.error=Pri odhlasovaní sa z odberu tejto kolekcie sa vyskytla chyba. Prosím, skúste to neskôr.
+unsubscribe.confirm.title=Potvrdenie odhlásenia
+unsubscribe.confirm.label=Odhlásením odberu tejto kolekcie ju tiež odstránite zo svojho zoznamu obľúbených. Naozaj sa chcete odhlásiť?
+unsubscribe.confirm.button1=Nie, zrušiť
+unsubscribe.confirm.button0=Ãno, odhlásiÅ¥
diff --git a/bandwagon/locale/sk/extensionsOverlay.dtd b/bandwagon/locale/sk/extensionsOverlay.dtd
new file mode 100644
index 0000000..2a9f852
--- /dev/null
+++ b/bandwagon/locale/sk/extensionsOverlay.dtd
@@ -0,0 +1,26 @@
+<!-- ***** BEGIN LICENSE BLOCK ***** - Version: MPL 1.1/GPL 2.0/LGPL 2.1 - - The contents of this file are subject to the Mozilla Public License Version - 1.1 (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - http://www.mozilla.org/MPL/ - - Software distributed under the License is distributed on an "AS IS" basis, - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - for the specific language governing rights and limitations under the - License. - - The Original Code is bandwagon. - - The Initial Developer of the Original Code is - Mozilla Corporation. - Portions created by the Initial Developer are Copyright (C) 2008 - the Initial Developer. All Rights Reserved. - - Contributor(s): Brian King <brian (at) briks (dot) si> - David McNamara - - Alternatively, the contents of this file may be used under the terms of - either the GNU General Public License Version 2 or later (the "GPL"), or - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - in which case the provisions of the GPL or the LGPL are applicable instead - of those above. If you wish to allow use of your version of this file only - under the terms of either the GPL or the LGPL, and not to allow others to - use your version of this file under the terms of the MPL, indicate your - decision by deleting the provisions above and replace them with the notice - and other provisions required by the GPL or the LGPL. If you do not delete - the provisions above, a recipient may use your version of this file under - the terms of any one of the MPL, the GPL or the LGPL. - - ***** END LICENSE BLOCK ***** -->
+<!ENTITY collections.label "Odbery">
+<!ENTITY search.label.bandwagon "Hľadanie">
+<!ENTITY addon.moreinfo "Viac informácií">
+<!ENTITY addon.addtofirefox "Pridať do Firefoxu">
+<!ENTITY subscribe.label "Hľadať kolekcie">
+<!ENTITY reload.label "Obnoviť všetko">
+<!ENTITY settings.label "Nastavenia">
+<!ENTITY view.label "Zobraziť kolekciu">
+<!ENTITY unsubscribe.label "Odhlásiť">
+<!ENTITY nocollectionstitle.label "Víta vás rozšírenie Add-on Collector">
+<!ENTITY nocollectionssubscribed.label "Tu sa objavia kolekcie, ktoré oznaÄíte na Mozilla Add-ons ako obľúbené, takže ich môžete jednoducho sledovaÅ¥. Zdá sa, že zatiaľ ste nepridali žiadne obľúbené doplnky, chcete sa teda porozhliadnuÅ¥ v naÅ¡om prieÄinku kolekcií?">
+<!ENTITY clicktosubscribe.label "Nájsť kolekcie">
+<!ENTITY noamoauth.label "Tu sa objavia kolekcie, ktoré oznaÄíte na Mozilla Add-ons ako obľúbené, takže ich môžete jednoducho sledovaÅ¥. Ak chcete využiÅ¥ túto funkciu, musíte byÅ¥ prihlásený.">
+<!ENTITY username.label "E-mailová adresa">
+<!ENTITY password.label "Heslo">
+<!ENTITY clicktologin.label "Prihlásiť">
+<!ENTITY createaccount.label "Nemám úÄet">
+<!ENTITY loginheading.label "Zadajte požadované informácie o svojom úÄte na Mozilla Addons:">
+<!ENTITY collectionisloading.label "Získava sa kolekcia...">
+<!ENTITY collectionhasnoitems.label "Táto kolekcia neobsahuje žiadne doplnky.">
+<!ENTITY collectionhaserror.label "Táto kolekcia nemôže byť zobrazená, pretože obsahuje chyby.">
+<!ENTITY publishto.label "Publikovať">
+<!ENTITY email.address.label "E-mailová adresa">
+<!ENTITY new.email.address.label "Nová e-mailová adresa">
+<!ENTITY new.collection.label "Nová kolekcia">
diff --git a/bandwagon/locale/sk/publish.dtd b/bandwagon/locale/sk/publish.dtd
new file mode 100644
index 0000000..8c307a2
--- /dev/null
+++ b/bandwagon/locale/sk/publish.dtd
@@ -0,0 +1,47 @@
+<!-- ***** BEGIN LICENSE BLOCK *****
+ - Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ -
+ - The contents of this file are subject to the Mozilla Public License Version
+ - 1.1 (the "License"); you may not use this file except in compliance with
+ - the License. You may obtain a copy of the License at
+ - http://www.mozilla.org/MPL/
+ -
+ - Software distributed under the License is distributed on an "AS IS" basis,
+ - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ - for the specific language governing rights and limitations under the
+ - License.
+ -
+ - The Original Code is bandwagon.
+ -
+ - The Initial Developer of the Original Code is
+ - Mozilla Corporation.
+ - Portions created by the Initial Developer are Copyright (C) 2008
+ - the Initial Developer. All Rights Reserved.
+ -
+ - Contributor(s): David McNamara
+ - Brian King <brian (at) briks (dot) si>
+ -
+ - Alternatively, the contents of this file may be used under the terms of
+ - either the GNU General Public License Version 2 or later (the "GPL"), or
+ - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ - in which case the provisions of the GPL or the LGPL are applicable instead
+ - of those above. If you wish to allow use of your version of this file only
+ - under the terms of either the GPL or the LGPL, and not to allow others to
+ - use your version of this file under the terms of the MPL, indicate your
+ - decision by deleting the provisions above and replace them with the notice
+ - and other provisions required by the GPL or the LGPL. If you do not delete
+ - the provisions above, a recipient may use your version of this file under
+ - the terms of any one of the MPL, the GPL or the LGPL.
+ -
+ - ***** END LICENSE BLOCK *****
+
+ -->
+<!-- For localisers to change the width of the window -->
+<!ENTITY publish.style "width: 35em;">
+<!ENTITY window.title "Publikovanie">
+<!ENTITY cancel.label "Zrušiť">
+<!ENTITY publish.label "Publikovať">
+<!ENTITY new.email.label "Nová e-mailová adresa">
+<!ENTITY enter.an.email.label "Zadajte jednu alebo viac e-mailových adries oddelených Äiarkami:">
+<!ENTITY remember.this.email.label "Zapamätať si túto e-mailovú adresu">
+<!ENTITY enter.a.personal.note.label "Voliteľné: Zadajte osobnú poznámku k tomuto doplnku. táto bude súÄasÅ¥ou e-mailovej správy.">
diff --git a/bandwagon/locale/sk/publish.properties b/bandwagon/locale/sk/publish.properties
new file mode 100644
index 0000000..0bcbb53
--- /dev/null
+++ b/bandwagon/locale/sk/publish.properties
@@ -0,0 +1,30 @@
+# LOCALIZATION NOTE (you.are.sharing.the.add.on):
+
+# %S is the name of an add-on
+
+you.are.sharing.the.add.on=Zdieľate doplnok '%S'
+# LOCALIZATION NOTE (publishing.to):
+
+# %1 is the name of an add-on. %2 is the name of a collection
+
+publishing.to=Kliknutím na tlaÄidlo "PublikovaÅ¥" pridáte doplnok %1$S do kolekcie "%2$S".
+# LOCALIZATION NOTE (sharing.with):
+
+# %1 is a user's email address. $2 is the name of an add-on
+
+sharing.with=Kliknutím na "Odoslať e-mail" odošlete na adresu %1$S e-mailovú správu s informáciami o doplnku "%2$S".
+# LOCALIZATION NOTE (sharing.with.new):
+
+# %S is the name of an add-on
+
+sharing.with.new=Kliknutím na "Odoslať e-mail" odošlete uvedeným príjemcom e-mailovú správu s informáciami o doplnku "%2$S".
+please.enter.an.email.address=Prosím, zadajte e-mailovú adresu.
+the.addon.has.been.published=Doplnok bol publikovaný.
+the.email.has.been.sent=E-mailová správa bola odoslaná.
+# LOCALIZATION NOTE (closing.in):
+
+# %S is the number of seconds until a window closes, counting down
+
+closing.in=Zavrieť o %S...
+send.email=Odoslať e-mail
+error.unknown_addon_guid=Tento doplnok nie je možné zdieľať, pretože nie je umiestnený na serveroch Mozilla Add-ons.
diff --git a/bandwagon/locale/sk/settings.dtd b/bandwagon/locale/sk/settings.dtd
new file mode 100644
index 0000000..73ee1ad
--- /dev/null
+++ b/bandwagon/locale/sk/settings.dtd
@@ -0,0 +1,54 @@
+<!-- ***** BEGIN LICENSE BLOCK ***** - Version: MPL 1.1/GPL 2.0/LGPL 2.1 - - The contents of this file are subject to the Mozilla Public License Version - 1.1 (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - http://www.mozilla.org/MPL/ - - Software distributed under the License is distributed on an "AS IS" basis, - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - for the specific language governing rights and limitations under the - License. - - The Original Code is bandwagon. - - The Initial Developer of the Original Code is - Mozilla Corporation. - Portions created by the Initial Developer are Copyright (C) 2008 - the Initial Developer. All Rights Reserved. - - Contributor(s): Brian King <brian (at) briks (dot) si> - David McNamara - - Alternatively, the contents of this file may be used under the terms of - either the GNU General Public License Version 2 or later (the "GPL"), or - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - in which case the provisions of the GPL or the LGPL are applicable instead - of those above. If you wish to allow use of your version of this file only - under the terms of either the GPL or the LGPL, and not to allow others to - use your version of this file under the terms of the MPL, indicate your - decision by deleting the provisions above and replace them with the notice - and other provisions required by the GPL or the LGPL. If you do not delete - the provisions above, a recipient may use your version of this file under - the terms of any one of the MPL, the GPL or the LGPL. - - ***** END LICENSE BLOCK ***** -->
+<!-- For localisers to change the width of the window -->
+<!ENTITY settings.style "width: 42em;">
+<!ENTITY window.title "Nastavenia rozšírenia Add-on Collector">
+<!-- Tabs -->
+<!ENTITY manage.label "Správa odberov">
+<!ENTITY general.label "Všeobecné nastavenia">
+<!ENTITY pub.label "Automatické publikovanie">
+<!-- Manage Subscriptions -->
+<!ENTITY subscriptions.header "Správa odberov">
+<!-- Groupbox captions in Manage Subscriptions -->
+<!ENTITY frequency.label "Frekvencia aktualizácií prihlásených kolekcií">
+<!ENTITY notifications.label "Upozornenia na nové doplnky">
+<!ENTITY perpage.label "PoÄet doplnkov na stránku">
+<!ENTITY default.label "Použiť predvolené nastavenie">
+<!ENTITY custom.label "Vlastné:">
+<!ENTITY addonsleadin.label "Zobraziť">
+<!ENTITY addonsperpage.label "doplnkov na stránku">
+<!ENTITY updatesingle.label "Aktualizovať každých:">
+<!ENTITY minutes.label "minút">
+<!ENTITY hours.label "hodín">
+<!ENTITY days.label "dní">
+<!ENTITY autopublish.label "Automaticky publikovať do kolekcie nainštalované doplnky">
+<!ENTITY notify.label "Zobraziť upozornenia">
+<!ENTITY applyall.label "Použiť pre všetky odbery">
+<!ENTITY remove.label "Odstrániť odber">
+<!ENTITY on.label "Zapnuté">
+<!ENTITY off.label "Vypnuté">
+<!-- General -->
+<!-- Groupbox captions in General -->
+<!ENTITY subscriptions.label "Predvolené nastavenia odoberania">
+<!ENTITY data.label "Správa údajov">
+<!ENTITY updateall.label "Kontrolovať aktualizácie prihlásených kolekcií každých">
+<!ENTITY notifyglobal.label "Upozorňovanie na nové doplnky v prihlásených kolekciách">
+<!ENTITY clearemails.label "Vymazať">
+<!ENTITY login.label "Prihlásiť">
+<!ENTITY logout.label "Odhlásiť">
+<!-- Auto-Publisher Settings -->
+<!-- Groupbox captions in Auto-Publisher Settings -->
+<!ENTITY auto.label "Nastavenia automatického publikovania">
+<!ENTITY name.label "Názov kolekcie">
+<!ENTITY list.label "ZobraziÅ¥ vo verejnom prieÄinku kolekcií">
+<!ENTITY autoleadin.label "Automaticky publikované kolekcie sú špeciálne kolekcie, ktoré sú aktualizované pri inštalácii alebo odinštalácii doplnok vo vašom Firefoxe.">
+<!ENTITY types.label "Typy automaticky publikovaných doplnkov:">
+<!ENTITY type.extensions.label "Rozšírenia">
+<!ENTITY type.themes.label "Témy">
+<!ENTITY type.dicts.label "Slovníky">
+<!ENTITY type.langpacks.label "Jazykové balíky">
+<!ENTITY createauto.label "Vytvoriť automaticky publikovanú kolekciu">
+<!ENTITY deleteauto.label "Odstrániť automaticky publikovanú kolekciu">
+<!ENTITY updateauto.label "Aktualizovať automaticky publikovanú kolekciu">
+<!ENTITY onlypublishenabledaddons.label "Publikovať len povolené doplnky">
+<!ENTITY misc.label "Rôzne">
+<!ENTITY allowincompatibleinstall.label "Povoliť inštaláciu nekompatibilných doplnkov z prihlásených kolekcií">
diff --git a/bandwagon/locale/sk/settings.properties b/bandwagon/locale/sk/settings.properties
new file mode 100644
index 0000000..045f748
--- /dev/null
+++ b/bandwagon/locale/sk/settings.properties
@@ -0,0 +1,34 @@
+add.collection=Pridať odber
+enter.url.to.add.collection=Zadajte adresu kolekcie, ktorú chcete pridať.
+remove.collection=Odstrániť odber
+# LOCALIZATION NOTE (are.you.sure.you.want.to.remove):
+
+# %S is the name of a collection
+
+are.you.sure.you.want.to.remove=Odstránením tohto odberu odstránite takisto kolekciu zo zoznamu obľúbených. Naozaj chcete odstrániť '%S'?
+# LOCALIZATION NOTE (saved.emails.text):
+
+# %S is a number
+
+saved.emails.text=PoÄet uložených adries: %S
+# LOCALIZATION NOTE (login.status.with.email):
+
+# %S is a user's email address
+
+login.status.with.email=Ste prihlásený ako %S
+login.status=Ste prihlásený
+logout.status=Nie ste prihlásený
+# LOCALIZATION NOTE (auto.invalid.name):
+
+# %S is the name of a collection
+
+auto.invalid.name=Názov kolekcie '%S' nie je platný.
+auto.please.select.type=Zvoľte aspoň jeden doplnok, ktorý sa má automaticky publikovať.
+auto.create.internal.error=Kolekcia nemohla byť vytvorená (interná chyba).
+auto.create.done=Vaša automaticky publikovaná kolekcia bola vytvorená.
+auto.delete.internal.error=Kolekcia nemohla byť odstránená (interná chyba).
+auto.delete.done=Vaša automaticky publikovaná kolekcia bola odstránená.
+auto.create.description=Automaticky vygenerovaný zoznam nainštalovaných doplnkov
+auto.update.confirm.message=Nové nastavenia sa použijú okamžite, ale neovplyvnia už publikované doplnky.
+auto.update.internal.error=Kolekcia nemohla byť aktualizovaná (vyskytla sa interná chyba).
+auto.update.done=Vaša automaticky publikovaná kolekcia bola aktualizovaná.
diff --git a/bandwagon/locale/sq/bandwagon.properties b/bandwagon/locale/sq/bandwagon.properties
new file mode 100644
index 0000000..91c117c
--- /dev/null
+++ b/bandwagon/locale/sq/bandwagon.properties
@@ -0,0 +1,2 @@
+extensions.sharing@addons.mozilla.org.description=Zbuloni shtesa dhe ndajini me të tjerët.
+extensions.sharing@addons.mozilla.org.name=Grumbullues Shtesash
diff --git a/bandwagon/locale/sq/bandwagonAddon.properties b/bandwagon/locale/sq/bandwagonAddon.properties
new file mode 100644
index 0000000..9116f3e
--- /dev/null
+++ b/bandwagon/locale/sq/bandwagonAddon.properties
@@ -0,0 +1,38 @@
+# LOCALIZATION NOTE (bandwagon.addon.pluralRule):
+# See https://developer.mozilla.org/En/Localization_and_Plurals
+bandwagon.addon.pluralRule=1
+bandwagon.category1=Zgjerim
+# LOCALIZATION NOTE (bandwagon.addon.author):
+# %S will contain author's first and last name, or their nickname used on AMO
+bandwagon.addon.author=Nga %S
+# LOCALIZATION NOTE (bandwagon.addon.addedby):
+# %S will be a user's first and last name, or nickname
+bandwagon.addon.addedby=nga %S
+bandwagon.addon.added.justnow=Shtuar: Sapo
+# LOCALIZATION NOTE:
+# %S will be a number of time units indicated
+bandwagon.addon.added.minute=Shtuar: 1 minutë më parë;Shtuar: %S minuta më parë
+bandwagon.addon.added.hour=Shtuar: 1 orë më parë;Shtuar: %S orë më parë
+bandwagon.addon.added.day=Shtuar: Dje;Shtuar: %S ditë më parë
+bandwagon.addon.added.week=Shtuar: 1 javë më parë;Shtuar: %S javë më parë
+bandwagon.addon.added.month=Shtuar: 1 muaj më parë;Shtuar: %S muaj më parë
+bandwagon.addon.added.year=Shtuar: 1 vit më parë;Shtuar: %S vjetë më parë
+bandwagon.addon.moreinfo=Më tepër të dhëna.
+bandwagon.addon.olderversionsoffirefox=Kjo shtesë është për versione më të vjetër të Firefox-it.
+# LOCALIZATION NOTE (upgradetofirefoxn1):
+# %S will be a Firefox version number
+bandwagon.addon.upgradetofirefoxn1=Përmirësojeni me Firefox %S
+bandwagon.addon.upgradetofirefoxn2=për të përdorur këtë shtesë.
+# LOCALIZATION NOTE (bandwagon.addon.requiresfirefoxbeta1/requiresfirefoxbeta2):
+# %S will be a Firefox version number
+bandwagon.addon.requiresfirefoxbeta1=Kjo shtesë lyp Firefox %S, i cili nuk është hedhur ende në qarkullim. Për të përdorur këtë shtesë, mundeni
+bandwagon.addon.requiresfirefoxbeta2=të shkarkoni Firefox %S beta.
+# LOCALIZATION NOTE (bandwagon.addon.notcompatible):
+# %S will be a platform name, such as "Windows"
+bandwagon.addon.notcompatible=Kjo shtesë nuk përputhet me %S.
+# LOCALIZATION NOTE (bandwagon.addon.comment.description):
+# %S will be a comment entered by the publisher of the add-on
+bandwagon.addon.comment.description=“%Sâ€
+# LOCALIZATION NOTE (bandwagon.addon.comment.author):
+# %S will be the publisher's real name or nickname
+bandwagon.addon.comment.author=Koment prej %S:
diff --git a/bandwagon/locale/sq/browserOverlay.dtd b/bandwagon/locale/sq/browserOverlay.dtd
new file mode 100644
index 0000000..0c722d4
--- /dev/null
+++ b/bandwagon/locale/sq/browserOverlay.dtd
@@ -0,0 +1,38 @@
+<!-- ***** BEGIN LICENSE BLOCK *****
+ - Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ -
+ - The contents of this file are subject to the Mozilla Public License Version
+ - 1.1 (the "License"); you may not use this file except in compliance with
+ - the License. You may obtain a copy of the License at
+ - http://www.mozilla.org/MPL/
+ -
+ - Software distributed under the License is distributed on an "AS IS" basis,
+ - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ - for the specific language governing rights and limitations under the
+ - License.
+ -
+ - The Original Code is bandwagon.
+ -
+ - The Initial Developer of the Original Code is
+ - Mozilla Corporation.
+ - Portions created by the Initial Developer are Copyright (C) 2008
+ - the Initial Developer. All Rights Reserved.
+ -
+ - Contributor(s): Brian King <brian (at) briks (dot) si>
+ -
+ - Alternatively, the contents of this file may be used under the terms of
+ - either the GNU General Public License Version 2 or later (the "GPL"), or
+ - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ - in which case the provisions of the GPL or the LGPL are applicable instead
+ - of those above. If you wish to allow use of your version of this file only
+ - under the terms of either the GPL or the LGPL, and not to allow others to
+ - use your version of this file under the terms of the MPL, indicate your
+ - decision by deleting the provisions above and replace them with the notice
+ - and other provisions required by the GPL or the LGPL. If you do not delete
+ - the provisions above, a recipient may use your version of this file under
+ - the terms of any one of the MPL, the GPL or the LGPL.
+ -
+ - ***** END LICENSE BLOCK ***** -->
+
+<!ENTITY bandwagon.label "Shtesa">
+<!ENTITY bandwagon.tooltip "Shtesa">
diff --git a/bandwagon/locale/sq/browserOverlay.properties b/bandwagon/locale/sq/browserOverlay.properties
new file mode 100644
index 0000000..0212aa4
--- /dev/null
+++ b/bandwagon/locale/sq/browserOverlay.properties
@@ -0,0 +1,4 @@
+newaddons.alert.title=Shtesë e Re
+# LOCALIZATION NOTE (newaddons.alert.text):
+# %S will be the name of a collection
+newaddons.alert.text=Ka shtesa të reja te pajtimi juaj "%S".
diff --git a/bandwagon/locale/sq/extensionOverlay.properties b/bandwagon/locale/sq/extensionOverlay.properties
new file mode 100644
index 0000000..0b88fd5
--- /dev/null
+++ b/bandwagon/locale/sq/extensionOverlay.properties
@@ -0,0 +1,14 @@
+publish.new.email.address.title=Vendndodhje E-mail e Re
+publish.new.email.address.text=Jepni vendndodhje të re e-mail me të cilën të ndahet kjo shtesë:
+publish.remove.title=Ripohim
+# LOCALIZATION NOTE (publish.remove.label):
+# %1 is the name of an add-on. %2 is the name of a collection
+publish.remove.label=Jeni i sigurt se doni të hiqet %1$S prej koleksionit "%2$S"?
+publish.remove.button1=Jo, anuloje
+publish.remove.button0=Po, hiqe shtesën
+login.error=Pati një gabim gjatë hyrjes. Ju lutem kontrolloni në janë të saktë emri juaj i përdoruesit dhe fjalëkalimi.
+unsubscribe.error=Pati një gabim gjatë çpajtimit prej këtij koleksioni. Ju lutem riprovoni.
+unsubscribe.confirm.title=Ripohoni Çpajtimin
+unsubscribe.confirm.label=Çpajtimi prej këtij koleksioni do ta heqë gjithashtu prej listës suaj të të parapëlqyerve. Jeni i sigurt që doni të çpajtoheni?
+unsubscribe.confirm.button1=Jo, anuloje
+unsubscribe.confirm.button0=Po, çpajtomë
diff --git a/bandwagon/locale/sq/extensionsOverlay.dtd b/bandwagon/locale/sq/extensionsOverlay.dtd
new file mode 100644
index 0000000..7432639
--- /dev/null
+++ b/bandwagon/locale/sq/extensionsOverlay.dtd
@@ -0,0 +1,69 @@
+<!-- ***** BEGIN LICENSE BLOCK *****
+ - Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ -
+ - The contents of this file are subject to the Mozilla Public License Version
+ - 1.1 (the "License"); you may not use this file except in compliance with
+ - the License. You may obtain a copy of the License at
+ - http://www.mozilla.org/MPL/
+ -
+ - Software distributed under the License is distributed on an "AS IS" basis,
+ - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ - for the specific language governing rights and limitations under the
+ - License.
+ -
+ - The Original Code is bandwagon.
+ -
+ - The Initial Developer of the Original Code is
+ - Mozilla Corporation.
+ - Portions created by the Initial Developer are Copyright (C) 2008
+ - the Initial Developer. All Rights Reserved.
+ -
+ - Contributor(s): Brian King <brian (at) briks (dot) si>
+ - David McNamara
+ -
+ - Alternatively, the contents of this file may be used under the terms of
+ - either the GNU General Public License Version 2 or later (the "GPL"), or
+ - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ - in which case the provisions of the GPL or the LGPL are applicable instead
+ - of those above. If you wish to allow use of your version of this file only
+ - under the terms of either the GPL or the LGPL, and not to allow others to
+ - use your version of this file under the terms of the MPL, indicate your
+ - decision by deleting the provisions above and replace them with the notice
+ - and other provisions required by the GPL or the LGPL. If you do not delete
+ - the provisions above, a recipient may use your version of this file under
+ - the terms of any one of the MPL, the GPL or the LGPL.
+ -
+ - ***** END LICENSE BLOCK ***** -->
+
+<!ENTITY collections.label "Pajtime">
+<!ENTITY search.label.bandwagon "Kërkim">
+
+<!ENTITY addon.moreinfo "Më tepër të dhëna.">
+<!ENTITY addon.addtofirefox "Shtoje te Firefox-i">
+<!ENTITY subscribe.label "Gjeni Koleksione">
+<!ENTITY reload.label "Ringarkoji të Tëra">
+<!ENTITY settings.label "Rregullime">
+
+<!ENTITY view.label "Shihni Koleksionin">
+<!ENTITY unsubscribe.label "Çpajtoje">
+
+<!ENTITY nocollectionstitle.label "Mirë se vini te Grumbulluesi i Shtesave">
+<!ENTITY nocollectionssubscribed.label "Ky është vendi ku do të shfaqen koleksionet e shënuar si të parapëlqyer te Shtesat Mozilla, që kështu t&apos;i ndiqni me lehtësi. Duket se nuk keni ende ndonjë të parapëlqyer, ndaj pse të mos hidhni një sy përqark Listës sonë të Koleksioneve?">
+<!ENTITY clicktosubscribe.label "Gjeni Koleksione">
+
+<!ENTITY noamoauth.label "Ky është vendi ku do të shfaqen koleksionet e shënuar si të parapëlqyer te Shtesat Mozilla, që kështu t&apos;i ndiqni me lehtësi. Për të përdorur këtë veçori, duhet të keni hyrë te addons.mozilla.org.">
+<!ENTITY username.label "Emër përdoruesi">
+<!ENTITY password.label "Fjalëkalim">
+<!ENTITY clicktologin.label "Hyni">
+
+<!ENTITY collectionisloading.label "Po merret pajtimi...">
+<!ENTITY collectionhasnoitems.label "Ky koleksion nuk përmban shtesa.">
+<!ENTITY collectionhaserror.label "Ky koleksion nuk shfaqet dot sepse përmban gabime.">
+
+<!ENTITY publishto.label "Botoje te">
+<!ENTITY email.address.label "Vendndodhje E-mail">
+<!ENTITY new.email.address.label "Vendndodhje E-mail e Re">
+<!ENTITY new.collection.label "Koleksion i Ri">
+
+<!ENTITY createaccount.label "Nuk kam llogari">
+<!ENTITY loginheading.label "Jepni më poshtë të dhënat tuaja të llogarisë për te Shtesa Mozilla:">
diff --git a/bandwagon/locale/sq/publish.dtd b/bandwagon/locale/sq/publish.dtd
new file mode 100644
index 0000000..0f7c051
--- /dev/null
+++ b/bandwagon/locale/sq/publish.dtd
@@ -0,0 +1,48 @@
+<!-- ***** BEGIN LICENSE BLOCK *****
+ - Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ -
+ - The contents of this file are subject to the Mozilla Public License Version
+ - 1.1 (the "License"); you may not use this file except in compliance with
+ - the License. You may obtain a copy of the License at
+ - http://www.mozilla.org/MPL/
+ -
+ - Software distributed under the License is distributed on an "AS IS" basis,
+ - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ - for the specific language governing rights and limitations under the
+ - License.
+ -
+ - The Original Code is bandwagon.
+ -
+ - The Initial Developer of the Original Code is
+ - Mozilla Corporation.
+ - Portions created by the Initial Developer are Copyright (C) 2008
+ - the Initial Developer. All Rights Reserved.
+ -
+ - Contributor(s): David McNamara
+ - Brian King <brian (at) briks (dot) si>
+ -
+ - Alternatively, the contents of this file may be used under the terms of
+ - either the GNU General Public License Version 2 or later (the "GPL"), or
+ - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ - in which case the provisions of the GPL or the LGPL are applicable instead
+ - of those above. If you wish to allow use of your version of this file only
+ - under the terms of either the GPL or the LGPL, and not to allow others to
+ - use your version of this file under the terms of the MPL, indicate your
+ - decision by deleting the provisions above and replace them with the notice
+ - and other provisions required by the GPL or the LGPL. If you do not delete
+ - the provisions above, a recipient may use your version of this file under
+ - the terms of any one of the MPL, the GPL or the LGPL.
+ -
+ - ***** END LICENSE BLOCK ***** -->
+
+<!-- For localisers to change the width of the window -->
+<!ENTITY publish.style "width: 35em;">
+
+<!ENTITY window.title "Botoje">
+<!ENTITY cancel.label "Anuloje">
+<!ENTITY publish.label "Botoje">
+<!ENTITY new.email.label "Vendndodhje E-mail e Re">
+<!ENTITY enter.an.email.label "Jepni një ose më tepër vendndodhje e-mail të ndara me presje:">
+<!ENTITY remember.this.email.label "Mbaje mend këtë vendndodhje e-mail">
+<!ENTITY enter.a.personal.note.label "Opsionale: Jepni një shënim personal rreth kësaj shtesë, të përfshihet te e-mail-i">
+
diff --git a/bandwagon/locale/sq/publish.properties b/bandwagon/locale/sq/publish.properties
new file mode 100644
index 0000000..3e0d93c
--- /dev/null
+++ b/bandwagon/locale/sq/publish.properties
@@ -0,0 +1,20 @@
+# LOCALIZATION NOTE (you.are.sharing.the.add.on):
+# %S is the name of an add-on
+you.are.sharing.the.add.on=Po ndani me të tjerët shtesën '%S'
+# LOCALIZATION NOTE (publishing.to):
+# %1 is the name of an add-on. %2 is the name of a collection
+publishing.to=Klikimi te "Botoje" do ta shtojë %1$S te koleksioni "%2$S".
+# LOCALIZATION NOTE (sharing.with):
+# %1 is a user's email address. $2 is the name of an add-on
+sharing.with=Klikimi te "Dërgo E-mail" do t'i dërgojë %1$S një e-mail me të dhëna rreth %2$S
+# LOCALIZATION NOTE (sharing.with.new):
+# %S is the name of an add-on
+sharing.with.new=Klikimi te "Dërgo E-mail" do t'u dërgojë marrësve të mësipërm një e-mail me të dhëna rreth %S
+please.enter.an.email.address=Ju lutem jepni një vendndodhje e-mail.
+the.addon.has.been.published=Shtesa u botua.
+the.email.has.been.sent=Email-i u dërgua.
+# LOCALIZATION NOTE (closing.in):
+# %S is the number of seconds until a window closes, counting down
+closing.in=Po mbyllet për %S...
+send.email=Dërgo E-mail
+error.unknown_addon_guid=Kjo shtesë nuk mund të ndahet me të tjerët sepse nuk strehohet te "site"-i web i Shtesave Mozilla.
diff --git a/bandwagon/locale/sq/settings.dtd b/bandwagon/locale/sq/settings.dtd
new file mode 100644
index 0000000..9d7c0bd
--- /dev/null
+++ b/bandwagon/locale/sq/settings.dtd
@@ -0,0 +1,108 @@
+<!-- ***** BEGIN LICENSE BLOCK *****
+ - Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ -
+ - The contents of this file are subject to the Mozilla Public License Version
+ - 1.1 (the "License"); you may not use this file except in compliance with
+ - the License. You may obtain a copy of the License at
+ - http://www.mozilla.org/MPL/
+ -
+ - Software distributed under the License is distributed on an "AS IS" basis,
+ - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ - for the specific language governing rights and limitations under the
+ - License.
+ -
+ - The Original Code is bandwagon.
+ -
+ - The Initial Developer of the Original Code is
+ - Mozilla Corporation.
+ - Portions created by the Initial Developer are Copyright (C) 2008
+ - the Initial Developer. All Rights Reserved.
+ -
+ - Contributor(s): Brian King <brian (at) briks (dot) si>
+ - David McNamara
+ -
+ - Alternatively, the contents of this file may be used under the terms of
+ - either the GNU General Public License Version 2 or later (the "GPL"), or
+ - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ - in which case the provisions of the GPL or the LGPL are applicable instead
+ - of those above. If you wish to allow use of your version of this file only
+ - under the terms of either the GPL or the LGPL, and not to allow others to
+ - use your version of this file under the terms of the MPL, indicate your
+ - decision by deleting the provisions above and replace them with the notice
+ - and other provisions required by the GPL or the LGPL. If you do not delete
+ - the provisions above, a recipient may use your version of this file under
+ - the terms of any one of the MPL, the GPL or the LGPL.
+ -
+ - ***** END LICENSE BLOCK ***** -->
+
+<!-- For localisers to change the width of the window -->
+<!ENTITY settings.style "width: 42em;">
+
+<!ENTITY window.title "Rregullime për Grumbulluesin e Shtesave">
+
+<!-- Tabs -->
+<!ENTITY manage.label "Administroni Pajtime">
+<!ENTITY general.label "Rregullime të Përgjithshme">
+<!ENTITY pub.label "Rregullime për Botuesin e Vetvetishëm">
+
+<!-- Manage Subscriptions -->
+<!ENTITY subscriptions.header "Pajtime:">
+
+<!-- Groupbox captions in Manage Subscriptions -->
+<!ENTITY frequency.label "Shpeshti Përditësimi Pajtimesh">
+<!ENTITY notifications.label "Njoftime Shtesash të Reja">
+<!ENTITY perpage.label "Shtesa për Faqe">
+
+<!ENTITY default.label "Përdor rregullimet parazgjedhje">
+<!ENTITY custom.label "Vetjake:">
+
+<!ENTITY addonsleadin.label "Shfaq">
+<!ENTITY addonsperpage.label "shtesa për faqe">
+<!ENTITY updatesingle.label "Përditësoji çdo:">
+<!ENTITY minutes.label "minutë(a)">
+<!ENTITY hours.label "orë">
+<!ENTITY days.label "ditë">
+<!ENTITY autopublish.label "Vetëboto te pajtime shtesat e instaluara">
+<!ENTITY notify.label "Shfaq njoftime">
+<!ENTITY applyall.label "Zbatoje për tërë pajtimet">
+<!ENTITY remove.label "Hiqe Pajtimin">
+<!ENTITY on.label "On">
+<!ENTITY off.label "Off">
+
+<!-- General -->
+
+<!-- Groupbox captions in General -->
+<!ENTITY subscriptions.label "Default Subscription Settings">
+<!ENTITY data.label "Data Management">
+
+<!ENTITY updateall.label "Kontrollo pajtimet për përditësime çdo">
+<!ENTITY notifyglobal.label "Njoftomë kur pajtimet e mia kanë shtesa të reja">
+
+<!ENTITY clearemails.label "Pastroje">
+<!ENTITY login.label "Hyni">
+<!ENTITY logout.label "Dilni">
+
+<!-- Auto-Publisher Settings -->
+
+<!-- Groupbox captions in Auto-Publisher Settings -->
+<!ENTITY auto.label "Rregullime Vetëbotuesi">
+
+<!ENTITY name.label "Emër Koleksioni:">
+<!ENTITY list.label "I pranishëm në Listën e Koleksioneve publike">
+
+<!ENTITY autoleadin.label "Vetëbotuesit janë koleksione speciale që përditësohen vetvetiu kur instaloni ose çinstaloni në këtë kompjuter shtesa prej Firefox-it.">
+<!ENTITY types.label "Lloje shtesash vetëbotuesi:">
+<!ENTITY type.extensions.label "Zgjerime">
+<!ENTITY type.themes.label "Tema">
+<!ENTITY type.dicts.label "Fjalorë">
+<!ENTITY type.langpacks.label "Paketa Gjuhe">
+
+<!ENTITY createauto.label "Krijo Vetëbotues">
+<!ENTITY deleteauto.label "Fshije Vetëbotuesin">
+<!ENTITY updateauto.label "Përditësoje Vetëbotuesin">
+
+<!ENTITY onlypublishenabledaddons.label "Boto vetëm shtesa të aktivizuara">
+
+<!ENTITY misc.label "Të ndryshme">
+<!ENTITY allowincompatibleinstall.label "Lejo instalim prej pajtimeve të mij të shtesave të papërputhshme">
+
diff --git a/bandwagon/locale/sq/settings.properties b/bandwagon/locale/sq/settings.properties
new file mode 100644
index 0000000..a6a37f4
--- /dev/null
+++ b/bandwagon/locale/sq/settings.properties
@@ -0,0 +1,26 @@
+add.collection=Shtoni Pajtim
+enter.url.to.add.collection=Jepni URL-në e pajtimit që dëshironi të shtohet.
+remove.collection=Hiqe Pajtimin
+# LOCALIZATION NOTE (are.you.sure.you.want.to.remove):
+# %S is the name of a collection
+are.you.sure.you.want.to.remove=Heqja e këtij pajtimi do ta heqë gjithashtu koleksionin prej listave tuaja. Jeni i sigurt që dëshironi të hiqni '%S'?
+# LOCALIZATION NOTE (saved.emails.text):
+# %S is a number
+saved.emails.text=Keni %S vendndodhje e-mail të ruajtura
+# LOCALIZATION NOTE (login.status.with.email):
+# %S is a user's email address
+login.status.with.email=Jeni futur si %S
+login.status=Jeni i futur
+logout.status=Nuk jeni i futur
+# LOCALIZATION NOTE (auto.invalid.name):
+# %S is the name of a collection
+auto.invalid.name=Emri '%S' për koleksionin nuk është i vlefshëm.
+auto.please.select.type=Ju lutem përzgjidhni të paktën një lloj shtese për botim vetvetiu.
+auto.create.internal.error=Koleksioni nuk u krijua dot (ndodhi një gabim i brendshëm).
+auto.create.done=Koleksioni juaj u vetëbotueshëm u krijua.
+auto.delete.internal.error=Koleksioni nuk u fshi dot (ndodhi një gabim i brendshëm).
+auto.delete.done=Koleksioni juaj i vetëbotueshëm u fshi.
+auto.create.description=Listë e prodhuar vetvetiu e shtesave të instaluara nga unë
+auto.update.confirm.message=Rregullimet tuaja të reja do të hyjnë në fuqi menjëherë, por nuk do të prekin shtesa tashmë të botuara.
+auto.update.internal.error=Koleksioni nuk u përditësua dot (ndodhi një gabim i brendshëm).
+auto.update.done=Koleksioni juaj i vetëbotueshëm u përditësua.
diff --git a/bandwagon/locale/sv-SE/bandwagon.properties b/bandwagon/locale/sv-SE/bandwagon.properties
new file mode 100644
index 0000000..be1610c
--- /dev/null
+++ b/bandwagon/locale/sv-SE/bandwagon.properties
@@ -0,0 +1,2 @@
+extensions.sharing@addons.mozilla.org.description=Dela och upptäck tillägg.
+extensions.sharing@addons.mozilla.org.name=Add-on-samlaren
diff --git a/bandwagon/locale/sv-SE/bandwagonAddon.properties b/bandwagon/locale/sv-SE/bandwagonAddon.properties
new file mode 100644
index 0000000..4705a72
--- /dev/null
+++ b/bandwagon/locale/sv-SE/bandwagonAddon.properties
@@ -0,0 +1,38 @@
+# LOCALIZATION NOTE (bandwagon.addon.pluralRule):
+# See https://developer.mozilla.org/En/Localization_and_Plurals
+bandwagon.addon.pluralRule=1
+bandwagon.category1=Utökning
+# LOCALIZATION NOTE (bandwagon.addon.author):
+# %S will contain author's first and last name, or their nickname used on AMO
+bandwagon.addon.author=Av %S
+# LOCALIZATION NOTE (bandwagon.addon.addedby):
+# %S will be a user's first and last name, or nickname
+bandwagon.addon.addedby=av %S
+bandwagon.addon.added.justnow=Tillagd: nyss
+# LOCALIZATION NOTE:
+# %S will be a number of time units indicated
+bandwagon.addon.added.minute=Tillagd: för 1 minut sen;Tillagd: för %S minuter sen
+bandwagon.addon.added.hour=Tillagd: för 1 hour ago;Tillagd: %S hours ago
+bandwagon.addon.added.day=Tillagd: igår;Tillagd: för %S dagar sen
+bandwagon.addon.added.week=Tillagd: för 1 vecka sen;Tillagd: för %S veckor sen
+bandwagon.addon.added.month=Tillagd: för 1 månad sen;Tillagd: för %S månader sen
+bandwagon.addon.added.year=Tillagd: för 1 år sen;Tillagd: för %S år sen
+bandwagon.addon.moreinfo=More info.
+bandwagon.addon.olderversionsoffirefox=Detta tillägg är för en äldre version av Firefox
+# LOCALIZATION NOTE (upgradetofirefoxn1):
+# %S will be a Firefox version number
+bandwagon.addon.upgradetofirefoxn1=Uppgradera till Firefox %S
+bandwagon.addon.upgradetofirefoxn2=för att använda detta tillägg.
+# LOCALIZATION NOTE (bandwagon.addon.requiresfirefoxbeta1/requiresfirefoxbeta2):
+# %S will be a Firefox version number
+bandwagon.addon.requiresfirefoxbeta1=Detta tillägg kräver Firefox %S, som inte har släppts ännu, för att använda detta tillägg kan du
+bandwagon.addon.requiresfirefoxbeta2=ladda ner Firefox %S-beta.
+# LOCALIZATION NOTE (bandwagon.addon.notcompatible):
+# %S will be a platform name, such as "Windows"
+bandwagon.addon.notcompatible=Detta tillägg är inte kompatibelt med %S.
+# LOCALIZATION NOTE (bandwagon.addon.comment.description):
+# %S will be a comment entered by the publisher of the add-on
+bandwagon.addon.comment.description=“%Sâ€
+# LOCALIZATION NOTE (bandwagon.addon.comment.author):
+# %S will be the publisher's real name or nickname
+bandwagon.addon.comment.author=Kommentar från %S:
diff --git a/bandwagon/locale/sv-SE/browserOverlay.dtd b/bandwagon/locale/sv-SE/browserOverlay.dtd
new file mode 100644
index 0000000..77e0a68
--- /dev/null
+++ b/bandwagon/locale/sv-SE/browserOverlay.dtd
@@ -0,0 +1,38 @@
+<!-- ***** BEGIN LICENSE BLOCK *****
+ - Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ -
+ - The contents of this file are subject to the Mozilla Public License Version
+ - 1.1 (the "License"); you may not use this file except in compliance with
+ - the License. You may obtain a copy of the License at
+ - http://www.mozilla.org/MPL/
+ -
+ - Software distributed under the License is distributed on an "AS IS" basis,
+ - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ - for the specific language governing rights and limitations under the
+ - License.
+ -
+ - The Original Code is bandwagon.
+ -
+ - The Initial Developer of the Original Code is
+ - Mozilla Corporation.
+ - Portions created by the Initial Developer are Copyright (C) 2008
+ - the Initial Developer. All Rights Reserved.
+ -
+ - Contributor(s): Brian King <brian (at) briks (dot) si>
+ -
+ - Alternatively, the contents of this file may be used under the terms of
+ - either the GNU General Public License Version 2 or later (the "GPL"), or
+ - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ - in which case the provisions of the GPL or the LGPL are applicable instead
+ - of those above. If you wish to allow use of your version of this file only
+ - under the terms of either the GPL or the LGPL, and not to allow others to
+ - use your version of this file under the terms of the MPL, indicate your
+ - decision by deleting the provisions above and replace them with the notice
+ - and other provisions required by the GPL or the LGPL. If you do not delete
+ - the provisions above, a recipient may use your version of this file under
+ - the terms of any one of the MPL, the GPL or the LGPL.
+ -
+ - ***** END LICENSE BLOCK ***** -->
+
+<!ENTITY bandwagon.label "Tillägg">
+<!ENTITY bandwagon.tooltip "Tillägg">
diff --git a/bandwagon/locale/sv-SE/browserOverlay.properties b/bandwagon/locale/sv-SE/browserOverlay.properties
new file mode 100644
index 0000000..045c462
--- /dev/null
+++ b/bandwagon/locale/sv-SE/browserOverlay.properties
@@ -0,0 +1,4 @@
+newaddons.alert.title=Nya tillägg
+# LOCALIZATION NOTE (newaddons.alert.text):
+# %S will be the name of a collection
+newaddons.alert.text=Det finns nya tillägg i din prenumeration "%S".
diff --git a/bandwagon/locale/sv-SE/extensionOverlay.properties b/bandwagon/locale/sv-SE/extensionOverlay.properties
new file mode 100644
index 0000000..c3d3fe6
--- /dev/null
+++ b/bandwagon/locale/sv-SE/extensionOverlay.properties
@@ -0,0 +1,14 @@
+publish.new.email.address.title=Ny e-postadress
+publish.new.email.address.text=Skriv en ny e-postadress att dela detta tillägg med:
+publish.remove.title=Bekräfta
+# LOCALIZATION NOTE (publish.remove.label):
+# %1 is the name of an add-on. %2 is the name of a collection
+publish.remove.label=Är du säker på att du vill ta bort %1$S från "%2$S"-samlingen?
+publish.remove.button1=Nej, avbryt
+publish.remove.button0=Ja, ta bort tillägget
+login.error=Det uppstod ett fel vid inloggningen. Kontrollera att ditt användarnamn och lösenord stämmer.
+unsubscribe.error=Det upppstod ett fel när prenumerationen för samlingen togs bort. Försök igen senare.
+unsubscribe.confirm.title=Bekräfta avslutning av prenumeration
+unsubscribe.confirm.label=Avslutar du din prenumeration på denna samling tas den även bort från dina favoriter. Är du säker på att du vill avsluta prenumerationen?
+unsubscribe.confirm.button1=Nej, avbryt
+unsubscribe.confirm.button0=Ja, avsluta prenumerationen
diff --git a/bandwagon/locale/sv-SE/extensionsOverlay.dtd b/bandwagon/locale/sv-SE/extensionsOverlay.dtd
new file mode 100644
index 0000000..9b81936
--- /dev/null
+++ b/bandwagon/locale/sv-SE/extensionsOverlay.dtd
@@ -0,0 +1,69 @@
+<!-- ***** BEGIN LICENSE BLOCK *****
+ - Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ -
+ - The contents of this file are subject to the Mozilla Public License Version
+ - 1.1 (the "License"); you may not use this file except in compliance with
+ - the License. You may obtain a copy of the License at
+ - http://www.mozilla.org/MPL/
+ -
+ - Software distributed under the License is distributed on an "AS IS" basis,
+ - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ - for the specific language governing rights and limitations under the
+ - License.
+ -
+ - The Original Code is bandwagon.
+ -
+ - The Initial Developer of the Original Code is
+ - Mozilla Corporation.
+ - Portions created by the Initial Developer are Copyright (C) 2008
+ - the Initial Developer. All Rights Reserved.
+ -
+ - Contributor(s): Brian King <brian (at) briks (dot) si>
+ - David McNamara
+ -
+ - Alternatively, the contents of this file may be used under the terms of
+ - either the GNU General Public License Version 2 or later (the "GPL"), or
+ - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ - in which case the provisions of the GPL or the LGPL are applicable instead
+ - of those above. If you wish to allow use of your version of this file only
+ - under the terms of either the GPL or the LGPL, and not to allow others to
+ - use your version of this file under the terms of the MPL, indicate your
+ - decision by deleting the provisions above and replace them with the notice
+ - and other provisions required by the GPL or the LGPL. If you do not delete
+ - the provisions above, a recipient may use your version of this file under
+ - the terms of any one of the MPL, the GPL or the LGPL.
+ -
+ - ***** END LICENSE BLOCK ***** -->
+
+<!ENTITY collections.label "Prenumerationer">
+<!ENTITY search.label.bandwagon "Sök">
+
+<!ENTITY addon.moreinfo "Mer information.">
+<!ENTITY addon.addtofirefox "Lägg till i Firefox">
+<!ENTITY subscribe.label "Hitta samlingar">
+<!ENTITY reload.label "Ladda om alla">
+<!ENTITY settings.label "Inställningar">
+
+<!ENTITY view.label "Visa samling">
+<!ENTITY unsubscribe.label "Avsluta prenumeration">
+
+<!ENTITY nocollectionstitle.label "Välkommen till tilläggssamlingen">
+<!ENTITY nocollectionssubscribed.label "Här hittar du samlingar du markerar som favoriter på Mozilla Add-ons så att du lätt kan hålla koll på dem. Det verkar som att du inte har lagt till några favoriter än, så varför inte titta runt lite i vår samlingskatalog?">
+<!ENTITY clicktosubscribe.label "Hitta samlingar">
+
+<!ENTITY noamoauth.label "Här hittar du samlingar du markerar som favoriter på Mozilla Add-ons så att du lätt kan hålla koll på dem. Du måste vara inloggad på addons.mozilla.org för att använda denna funktion.">
+<!ENTITY username.label "Användarnamn">
+<!ENTITY password.label "Lösenord">
+<!ENTITY clicktologin.label "Logga in">
+
+<!ENTITY collectionisloading.label "Hämtar prenumeration...">
+<!ENTITY collectionhasnoitems.label "Samlingen innehåller inga tillägg.">
+<!ENTITY collectionhaserror.label "Samlingen kan inte visas då den innehåller fel.">
+
+<!ENTITY publishto.label "Publicera till">
+<!ENTITY email.address.label "E-postadress">
+<!ENTITY new.email.address.label "Ny e-postadress">
+<!ENTITY new.collection.label "Ny samling">
+
+<!ENTITY createaccount.label "Jag har inget konto">
+<!ENTITY loginheading.label "Ange din Mozilla Add-ons-kontoinformation nedanför:">
diff --git a/bandwagon/locale/sv-SE/publish.dtd b/bandwagon/locale/sv-SE/publish.dtd
new file mode 100644
index 0000000..44b6477
--- /dev/null
+++ b/bandwagon/locale/sv-SE/publish.dtd
@@ -0,0 +1,48 @@
+<!-- ***** BEGIN LICENSE BLOCK *****
+ - Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ -
+ - The contents of this file are subject to the Mozilla Public License Version
+ - 1.1 (the "License"); you may not use this file except in compliance with
+ - the License. You may obtain a copy of the License at
+ - http://www.mozilla.org/MPL/
+ -
+ - Software distributed under the License is distributed on an "AS IS" basis,
+ - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ - for the specific language governing rights and limitations under the
+ - License.
+ -
+ - The Original Code is bandwagon.
+ -
+ - The Initial Developer of the Original Code is
+ - Mozilla Corporation.
+ - Portions created by the Initial Developer are Copyright (C) 2008
+ - the Initial Developer. All Rights Reserved.
+ -
+ - Contributor(s): David McNamara
+ - Brian King <brian (at) briks (dot) si>
+ -
+ - Alternatively, the contents of this file may be used under the terms of
+ - either the GNU General Public License Version 2 or later (the "GPL"), or
+ - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ - in which case the provisions of the GPL or the LGPL are applicable instead
+ - of those above. If you wish to allow use of your version of this file only
+ - under the terms of either the GPL or the LGPL, and not to allow others to
+ - use your version of this file under the terms of the MPL, indicate your
+ - decision by deleting the provisions above and replace them with the notice
+ - and other provisions required by the GPL or the LGPL. If you do not delete
+ - the provisions above, a recipient may use your version of this file under
+ - the terms of any one of the MPL, the GPL or the LGPL.
+ -
+ - ***** END LICENSE BLOCK ***** -->
+
+<!-- For localisers to change the width of the window -->
+<!ENTITY publish.style "width: 35em;">
+
+<!ENTITY window.title "Publicera">
+<!ENTITY cancel.label "Avbryt">
+<!ENTITY publish.label "Publicera">
+<!ENTITY new.email.label "Ny e-postadress">
+<!ENTITY enter.an.email.label "Skriv en eller flera e-postadresser separerade av komma:">
+<!ENTITY remember.this.email.label "Kom ihåg denna e-postadress">
+<!ENTITY enter.a.personal.note.label "Frivilligt: Skriv en personlig bit om det här tillägget som skickas med i brevet">
+
diff --git a/bandwagon/locale/sv-SE/publish.properties b/bandwagon/locale/sv-SE/publish.properties
new file mode 100644
index 0000000..7b97f54
--- /dev/null
+++ b/bandwagon/locale/sv-SE/publish.properties
@@ -0,0 +1,20 @@
+# LOCALIZATION NOTE (you.are.sharing.the.add.on):
+# %S is the name of an add-on
+you.are.sharing.the.add.on=Du delar tillägget '%S'
+# LOCALIZATION NOTE (publishing.to):
+# %1 is the name of an add-on. %2 is the name of a collection
+publishing.to=Om du klickar "Publicera" läggs %1$S till i "%2$S"-samlingen.
+# LOCALIZATION NOTE (sharing.with):
+# %1 is a user's email address. $2 is the name of an add-on
+sharing.with=Om du klickar "Skicka e-post" skickas %1$S brev med information om %2$S
+# LOCALIZATION NOTE (sharing.with.new):
+# %S is the name of an add-on
+sharing.with.new=Om du klickar "Skicka e-post" får ovanstående mottagare ett brev med information om %S
+please.enter.an.email.address=Ange en e-postadress.
+the.addon.has.been.published=Tillägget är publicerat.
+the.email.has.been.sent=Brev skickat.
+# LOCALIZATION NOTE (closing.in):
+# %S is the number of seconds until a window closes, counting down
+closing.in=Stänger om %S sekunder...
+send.email=Skicka e-post
+error.unknown_addon_guid=Detta tillägg kan inte delas då det inte finns på Mozilla Add-ons webbplats.
diff --git a/bandwagon/locale/sv-SE/settings.dtd b/bandwagon/locale/sv-SE/settings.dtd
new file mode 100644
index 0000000..39f3e1b
--- /dev/null
+++ b/bandwagon/locale/sv-SE/settings.dtd
@@ -0,0 +1,108 @@
+<!-- ***** BEGIN LICENSE BLOCK *****
+ - Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ -
+ - The contents of this file are subject to the Mozilla Public License Version
+ - 1.1 (the "License"); you may not use this file except in compliance with
+ - the License. You may obtain a copy of the License at
+ - http://www.mozilla.org/MPL/
+ -
+ - Software distributed under the License is distributed on an "AS IS" basis,
+ - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ - for the specific language governing rights and limitations under the
+ - License.
+ -
+ - The Original Code is bandwagon.
+ -
+ - The Initial Developer of the Original Code is
+ - Mozilla Corporation.
+ - Portions created by the Initial Developer are Copyright (C) 2008
+ - the Initial Developer. All Rights Reserved.
+ -
+ - Contributor(s): Brian King <brian (at) briks (dot) si>
+ - David McNamara
+ -
+ - Alternatively, the contents of this file may be used under the terms of
+ - either the GNU General Public License Version 2 or later (the "GPL"), or
+ - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ - in which case the provisions of the GPL or the LGPL are applicable instead
+ - of those above. If you wish to allow use of your version of this file only
+ - under the terms of either the GPL or the LGPL, and not to allow others to
+ - use your version of this file under the terms of the MPL, indicate your
+ - decision by deleting the provisions above and replace them with the notice
+ - and other provisions required by the GPL or the LGPL. If you do not delete
+ - the provisions above, a recipient may use your version of this file under
+ - the terms of any one of the MPL, the GPL or the LGPL.
+ -
+ - ***** END LICENSE BLOCK ***** -->
+
+<!-- For localisers to change the width of the window -->
+<!ENTITY settings.style "width: 42em;">
+
+<!ENTITY window.title "Tilläggsamlingsinställningar">
+
+<!-- Tabs -->
+<!ENTITY manage.label "Hantera prenumerationer">
+<!ENTITY general.label "Allmänna inställningar">
+<!ENTITY pub.label "Autopubliceringsinställningar">
+
+<!-- Manage Subscriptions -->
+<!ENTITY subscriptions.header "Prenumerationer:">
+
+<!-- Groupbox captions in Manage Subscriptions -->
+<!ENTITY frequency.label "Subscription Update Frequency">
+<!ENTITY notifications.label "Underrättelser om nya tillägg">
+<!ENTITY perpage.label "Tillägg per sida">
+
+<!ENTITY default.label "Använd standardinställning">
+<!ENTITY custom.label "Anpassad:">
+
+<!ENTITY addonsleadin.label "Visa">
+<!ENTITY addonsperpage.label "tillägg per sida">
+<!ENTITY updatesingle.label "Uppdatera var:">
+<!ENTITY minutes.label "minut(er)">
+<!ENTITY hours.label "timm(ar)">
+<!ENTITY days.label "dag(ar)">
+<!ENTITY autopublish.label "Auto-publicera installerade tillägg till prenumeration">
+<!ENTITY notify.label "Visa underrättelser">
+<!ENTITY applyall.label "Gäller för alla prenumerationer">
+<!ENTITY remove.label "Ta bort prenumeration">
+<!ENTITY on.label "PÃ¥">
+<!ENTITY off.label "Av">
+
+<!-- General -->
+
+<!-- Groupbox captions in General -->
+<!ENTITY subscriptions.label "Standardprenumerationsinställningar">
+<!ENTITY data.label "Datahantering">
+
+<!ENTITY updateall.label "Hämta uppdateringar för prenumeration var ">
+<!ENTITY notifyglobal.label "Underrätta mig när mina prenumerationer har nya tillägg">
+
+<!ENTITY clearemails.label "Rensa">
+<!ENTITY login.label "Logga in">
+<!ENTITY logout.label "Logga ut">
+
+<!-- Auto-Publisher Settings -->
+
+<!-- Groupbox captions in Auto-Publisher Settings -->
+<!ENTITY auto.label "Auto-publicerarinställningar">
+
+<!ENTITY name.label "Samlingsnamn:">
+<!ENTITY list.label "Listad i katalogen över publika samlingar">
+
+<!ENTITY autoleadin.label "Auto-publicerare är speciella samlingar som uppdateras automatiskt när ta installerar eller avinstallerar tillägg från Firefox på denna dator.">
+<!ENTITY types.label "Automatiskt publicerade tilläggstyper:">
+<!ENTITY type.extensions.label "Utökningar">
+<!ENTITY type.themes.label "Teman">
+<!ENTITY type.dicts.label "Ordlistor">
+<!ENTITY type.langpacks.label "Språkpaket">
+
+<!ENTITY createauto.label "Skapa auto-publicerare">
+<!ENTITY deleteauto.label "Ta bort auto-publicerare">
+<!ENTITY updateauto.label "Uppdatera auto-publicerare">
+
+<!ENTITY onlypublishenabledaddons.label "Publicera bara påslagna tillägg">
+
+<!ENTITY misc.label "Allmänt">
+<!ENTITY allowincompatibleinstall.label "Tillåt installering av inkompatibla tillägg från mina prenumerationer">
+
diff --git a/bandwagon/locale/sv-SE/settings.properties b/bandwagon/locale/sv-SE/settings.properties
new file mode 100644
index 0000000..be25aee
--- /dev/null
+++ b/bandwagon/locale/sv-SE/settings.properties
@@ -0,0 +1,26 @@
+add.collection=Lägg till prenumeration
+enter.url.to.add.collection=Ange URL för den prenumeration du vill lägga till.
+remove.collection=Ta bort prenumeration
+# LOCALIZATION NOTE (are.you.sure.you.want.to.remove):
+# %S is the name of a collection
+are.you.sure.you.want.to.remove=Om du tar bort denna prenumeration tar det också bort samlingen från din favoritlista. Är du säker på att du vill ta bort '%S'?
+# LOCALIZATION NOTE (saved.emails.text):
+# %S is a number
+saved.emails.text=Du har %S sparade e-postadresser
+# LOCALIZATION NOTE (login.status.with.email):
+# %S is a user's email address
+login.status.with.email=Du är inloggad som %S
+login.status=Du är inloggad
+logout.status=Du är inte inloggad
+# LOCALIZATION NOTE (auto.invalid.name):
+# %S is the name of a collection
+auto.invalid.name=Samlingsnamnet '%S' är ogiltigt.
+auto.please.select.type=Välj minst en tilläggstyp att publicera automatiskt.
+auto.create.internal.error=Samlingen kunde inte skapas (ett internt fel uppstod).
+auto.create.done=Din samling för automatisk publicering har skapats.
+auto.delete.internal.error=Samlingen kunde inte tas bort (ett internt fel uppstod).
+auto.delete.done=Din samling för automatisk publicering har tagits bort.
+auto.create.description=En automatgenererad lista över mina installerade tillägg
+auto.update.confirm.message=Dina nya inställningar gäller direkt, men påverkar inte tillägg som redan publicerats.
+auto.update.internal.error=Samlingen kunde ej uppdateras (ett internt fel uppstod).
+auto.update.done=Din autopubliceringssamling har uppdaterats.
diff --git a/bandwagon/locale/uk/bandwagon.properties b/bandwagon/locale/uk/bandwagon.properties
new file mode 100644
index 0000000..37a8281
--- /dev/null
+++ b/bandwagon/locale/uk/bandwagon.properties
@@ -0,0 +1,2 @@
+extensions.sharing@addons.mozilla.org.description=Share and discover add-ons.
+extensions.sharing@addons.mozilla.org.name=Add-on Collector
diff --git a/bandwagon/locale/uk/bandwagonAddon.properties b/bandwagon/locale/uk/bandwagonAddon.properties
new file mode 100644
index 0000000..28fb149
--- /dev/null
+++ b/bandwagon/locale/uk/bandwagonAddon.properties
@@ -0,0 +1,38 @@
+# LOCALIZATION NOTE (bandwagon.addon.pluralRule):
+# See https://developer.mozilla.org/En/Localization_and_Plurals
+bandwagon.addon.pluralRule=1
+bandwagon.category1=Extension
+# LOCALIZATION NOTE (bandwagon.addon.author):
+# %S will contain author's first and last name, or their nickname used on AMO
+bandwagon.addon.author=By %S
+# LOCALIZATION NOTE (bandwagon.addon.addedby):
+# %S will be a user's first and last name, or nickname
+bandwagon.addon.addedby=by %S
+bandwagon.addon.added.justnow=Added: Just now
+# LOCALIZATION NOTE:
+# %S will be a number of time units indicated
+bandwagon.addon.added.minute=Added: 1 minute ago;Added: %S minutes ago
+bandwagon.addon.added.hour=Added: 1 hour ago;Added: %S hours ago
+bandwagon.addon.added.day=Added: Yesterday;Added: %S days ago
+bandwagon.addon.added.week=Added: 1 week ago;Added: %S weeks ago
+bandwagon.addon.added.month=Added: 1 month ago;Added: %S months ago
+bandwagon.addon.added.year=Added: 1 year ago;Added: %S years ago
+bandwagon.addon.moreinfo=More info.
+bandwagon.addon.olderversionsoffirefox=This add-on is for older versions of Firefox.
+# LOCALIZATION NOTE (upgradetofirefoxn1):
+# %S will be a Firefox version number
+bandwagon.addon.upgradetofirefoxn1=Upgrade to Firefox %S
+bandwagon.addon.upgradetofirefoxn2=to use this add-on.
+# LOCALIZATION NOTE (bandwagon.addon.requiresfirefoxbeta1/requiresfirefoxbeta2):
+# %S will be a Firefox version number
+bandwagon.addon.requiresfirefoxbeta1=This add-on requires Firefox %S, which has not yet been released. To use this add-on, you may
+bandwagon.addon.requiresfirefoxbeta2=download Firefox %S beta.
+# LOCALIZATION NOTE (bandwagon.addon.notcompatible):
+# %S will be a platform name, such as "Windows"
+bandwagon.addon.notcompatible=This add-on is not compatible with %S.
+# LOCALIZATION NOTE (bandwagon.addon.comment.description):
+# %S will be a comment entered by the publisher of the add-on
+bandwagon.addon.comment.description=“%Sâ€
+# LOCALIZATION NOTE (bandwagon.addon.comment.author):
+# %S will be the publisher's real name or nickname
+bandwagon.addon.comment.author=Comment from %S:
diff --git a/bandwagon/locale/uk/browserOverlay.dtd b/bandwagon/locale/uk/browserOverlay.dtd
new file mode 100644
index 0000000..a665207
--- /dev/null
+++ b/bandwagon/locale/uk/browserOverlay.dtd
@@ -0,0 +1,38 @@
+<!-- ***** BEGIN LICENSE BLOCK *****
+ - Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ -
+ - The contents of this file are subject to the Mozilla Public License Version
+ - 1.1 (the "License"); you may not use this file except in compliance with
+ - the License. You may obtain a copy of the License at
+ - http://www.mozilla.org/MPL/
+ -
+ - Software distributed under the License is distributed on an "AS IS" basis,
+ - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ - for the specific language governing rights and limitations under the
+ - License.
+ -
+ - The Original Code is bandwagon.
+ -
+ - The Initial Developer of the Original Code is
+ - Mozilla Corporation.
+ - Portions created by the Initial Developer are Copyright (C) 2008
+ - the Initial Developer. All Rights Reserved.
+ -
+ - Contributor(s): Brian King <brian (at) briks (dot) si>
+ -
+ - Alternatively, the contents of this file may be used under the terms of
+ - either the GNU General Public License Version 2 or later (the "GPL"), or
+ - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ - in which case the provisions of the GPL or the LGPL are applicable instead
+ - of those above. If you wish to allow use of your version of this file only
+ - under the terms of either the GPL or the LGPL, and not to allow others to
+ - use your version of this file under the terms of the MPL, indicate your
+ - decision by deleting the provisions above and replace them with the notice
+ - and other provisions required by the GPL or the LGPL. If you do not delete
+ - the provisions above, a recipient may use your version of this file under
+ - the terms of any one of the MPL, the GPL or the LGPL.
+ -
+ - ***** END LICENSE BLOCK ***** -->
+
+<!ENTITY bandwagon.label "Add-ons">
+<!ENTITY bandwagon.tooltip "Add-ons">
diff --git a/bandwagon/locale/uk/browserOverlay.properties b/bandwagon/locale/uk/browserOverlay.properties
new file mode 100644
index 0000000..5c3b7aa
--- /dev/null
+++ b/bandwagon/locale/uk/browserOverlay.properties
@@ -0,0 +1,4 @@
+newaddons.alert.title=New Add-ons
+# LOCALIZATION NOTE (newaddons.alert.text):
+# %S will be the name of a collection
+newaddons.alert.text=There are new add-ons in your subscription "%S".
diff --git a/bandwagon/locale/uk/extensionOverlay.properties b/bandwagon/locale/uk/extensionOverlay.properties
new file mode 100644
index 0000000..03d896c
--- /dev/null
+++ b/bandwagon/locale/uk/extensionOverlay.properties
@@ -0,0 +1,14 @@
+publish.new.email.address.title=New E-mail Address
+publish.new.email.address.text=Enter a new e-mail address to share this add-on with:
+publish.remove.title=Confirmation
+# LOCALIZATION NOTE (publish.remove.label):
+# %1 is the name of an add-on. %2 is the name of a collection
+publish.remove.label=Are you sure you wish to remove %1$S from the "%2$S" collection?
+publish.remove.button1=No, cancel
+publish.remove.button0=Yes, remove the add-on
+login.error=There was an error logging in. Please check that your username and password are correct.
+unsubscribe.error=There was an error unsubscribing from this collection. Please try again later.
+unsubscribe.confirm.title=Confirm Unsubscribe
+unsubscribe.confirm.label=Unsubscribing from this collection will also remove it from your list of favorites. Are you sure you want to unsubscribe?
+unsubscribe.confirm.button1=No, cancel
+unsubscribe.confirm.button0=Yes, unsubscribe
diff --git a/bandwagon/locale/uk/extensionsOverlay.dtd b/bandwagon/locale/uk/extensionsOverlay.dtd
new file mode 100644
index 0000000..10e101b
--- /dev/null
+++ b/bandwagon/locale/uk/extensionsOverlay.dtd
@@ -0,0 +1,69 @@
+<!-- ***** BEGIN LICENSE BLOCK *****
+ - Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ -
+ - The contents of this file are subject to the Mozilla Public License Version
+ - 1.1 (the "License"); you may not use this file except in compliance with
+ - the License. You may obtain a copy of the License at
+ - http://www.mozilla.org/MPL/
+ -
+ - Software distributed under the License is distributed on an "AS IS" basis,
+ - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ - for the specific language governing rights and limitations under the
+ - License.
+ -
+ - The Original Code is bandwagon.
+ -
+ - The Initial Developer of the Original Code is
+ - Mozilla Corporation.
+ - Portions created by the Initial Developer are Copyright (C) 2008
+ - the Initial Developer. All Rights Reserved.
+ -
+ - Contributor(s): Brian King <brian (at) briks (dot) si>
+ - David McNamara
+ -
+ - Alternatively, the contents of this file may be used under the terms of
+ - either the GNU General Public License Version 2 or later (the "GPL"), or
+ - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ - in which case the provisions of the GPL or the LGPL are applicable instead
+ - of those above. If you wish to allow use of your version of this file only
+ - under the terms of either the GPL or the LGPL, and not to allow others to
+ - use your version of this file under the terms of the MPL, indicate your
+ - decision by deleting the provisions above and replace them with the notice
+ - and other provisions required by the GPL or the LGPL. If you do not delete
+ - the provisions above, a recipient may use your version of this file under
+ - the terms of any one of the MPL, the GPL or the LGPL.
+ -
+ - ***** END LICENSE BLOCK ***** -->
+
+<!ENTITY collections.label "Subscriptions">
+<!ENTITY search.label.bandwagon "Search">
+
+<!ENTITY addon.moreinfo "More info.">
+<!ENTITY addon.addtofirefox "Add to Firefox">
+<!ENTITY subscribe.label "Find Collections">
+<!ENTITY reload.label "Reload All">
+<!ENTITY settings.label "Settings">
+
+<!ENTITY view.label "View Collection">
+<!ENTITY unsubscribe.label "Unsubscribe">
+
+<!ENTITY nocollectionstitle.label "Welcome to the Add-on Collector">
+<!ENTITY nocollectionssubscribed.label "This is where collections you mark as a favorite on Mozilla Add-ons will appear so that you can easily keep track of them. It looks like you haven't yet added any favorites, so why not take a look around our Collection Directory?">
+<!ENTITY clicktosubscribe.label "Find Collections">
+
+<!ENTITY noamoauth.label "This is where collections you mark as a favorite on Mozilla Add-ons will appear so that you can easily keep track of them. You must be logged in to addons.mozilla.org to use this feature.">
+<!ENTITY username.label "Username">
+<!ENTITY password.label "Password">
+<!ENTITY clicktologin.label "Login">
+
+<!ENTITY collectionisloading.label "Retrieving subscription...">
+<!ENTITY collectionhasnoitems.label "This collection contains no add-ons.">
+<!ENTITY collectionhaserror.label "This collection cannot be displayed because it contains errors.">
+
+<!ENTITY publishto.label "Publish to">
+<!ENTITY email.address.label "E-mail Address">
+<!ENTITY new.email.address.label "New E-mail Address">
+<!ENTITY new.collection.label "New Collection">
+
+<!ENTITY createaccount.label "I don't have an account">
+<!ENTITY loginheading.label "Enter your Mozilla Add-ons account information below:">
diff --git a/bandwagon/locale/uk/publish.dtd b/bandwagon/locale/uk/publish.dtd
new file mode 100644
index 0000000..0e3ec14
--- /dev/null
+++ b/bandwagon/locale/uk/publish.dtd
@@ -0,0 +1,48 @@
+<!-- ***** BEGIN LICENSE BLOCK *****
+ - Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ -
+ - The contents of this file are subject to the Mozilla Public License Version
+ - 1.1 (the "License"); you may not use this file except in compliance with
+ - the License. You may obtain a copy of the License at
+ - http://www.mozilla.org/MPL/
+ -
+ - Software distributed under the License is distributed on an "AS IS" basis,
+ - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ - for the specific language governing rights and limitations under the
+ - License.
+ -
+ - The Original Code is bandwagon.
+ -
+ - The Initial Developer of the Original Code is
+ - Mozilla Corporation.
+ - Portions created by the Initial Developer are Copyright (C) 2008
+ - the Initial Developer. All Rights Reserved.
+ -
+ - Contributor(s): David McNamara
+ - Brian King <brian (at) briks (dot) si>
+ -
+ - Alternatively, the contents of this file may be used under the terms of
+ - either the GNU General Public License Version 2 or later (the "GPL"), or
+ - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ - in which case the provisions of the GPL or the LGPL are applicable instead
+ - of those above. If you wish to allow use of your version of this file only
+ - under the terms of either the GPL or the LGPL, and not to allow others to
+ - use your version of this file under the terms of the MPL, indicate your
+ - decision by deleting the provisions above and replace them with the notice
+ - and other provisions required by the GPL or the LGPL. If you do not delete
+ - the provisions above, a recipient may use your version of this file under
+ - the terms of any one of the MPL, the GPL or the LGPL.
+ -
+ - ***** END LICENSE BLOCK ***** -->
+
+<!-- For localisers to change the width of the window -->
+<!ENTITY publish.style "width: 35em;">
+
+<!ENTITY window.title "Publish">
+<!ENTITY cancel.label "Cancel">
+<!ENTITY publish.label "Publish">
+<!ENTITY new.email.label "New E-mail Address">
+<!ENTITY enter.an.email.label "Enter one or more e-mail addresses separated by commas:">
+<!ENTITY remember.this.email.label "Remember this e-mail address">
+<!ENTITY enter.a.personal.note.label "Optional: Enter a personal note about this add-on to be included in the e-mail">
+
diff --git a/bandwagon/locale/uk/publish.properties b/bandwagon/locale/uk/publish.properties
new file mode 100644
index 0000000..b004394
--- /dev/null
+++ b/bandwagon/locale/uk/publish.properties
@@ -0,0 +1,20 @@
+# LOCALIZATION NOTE (you.are.sharing.the.add.on):
+# %S is the name of an add-on
+you.are.sharing.the.add.on=You are sharing the add-on '%S'
+# LOCALIZATION NOTE (publishing.to):
+# %1 is the name of an add-on. %2 is the name of a collection
+publishing.to=Clicking "Publish" will add %1$S to the "%2$S" collection.
+# LOCALIZATION NOTE (sharing.with):
+# %1 is a user's email address. $2 is the name of an add-on
+sharing.with=Clicking "Send E-mail" will send %1$S an e-mail with information about %2$S
+# LOCALIZATION NOTE (sharing.with.new):
+# %S is the name of an add-on
+sharing.with.new=Clicking "Send E-mail" will send the above recipients an e-mail with information about %S
+please.enter.an.email.address=Please enter an e-mail address.
+the.addon.has.been.published=The add-on has been published.
+the.email.has.been.sent=The email has been sent.
+# LOCALIZATION NOTE (closing.in):
+# %S is the number of seconds until a window closes, counting down
+closing.in=Closing in %S...
+send.email=Send E-mail
+error.unknown_addon_guid=This add-on cannot be shared because it is not hosted on the Mozilla Add-ons website.
diff --git a/bandwagon/locale/uk/settings.dtd b/bandwagon/locale/uk/settings.dtd
new file mode 100644
index 0000000..29e5f9d
--- /dev/null
+++ b/bandwagon/locale/uk/settings.dtd
@@ -0,0 +1,108 @@
+<!-- ***** BEGIN LICENSE BLOCK *****
+ - Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ -
+ - The contents of this file are subject to the Mozilla Public License Version
+ - 1.1 (the "License"); you may not use this file except in compliance with
+ - the License. You may obtain a copy of the License at
+ - http://www.mozilla.org/MPL/
+ -
+ - Software distributed under the License is distributed on an "AS IS" basis,
+ - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ - for the specific language governing rights and limitations under the
+ - License.
+ -
+ - The Original Code is bandwagon.
+ -
+ - The Initial Developer of the Original Code is
+ - Mozilla Corporation.
+ - Portions created by the Initial Developer are Copyright (C) 2008
+ - the Initial Developer. All Rights Reserved.
+ -
+ - Contributor(s): Brian King <brian (at) briks (dot) si>
+ - David McNamara
+ -
+ - Alternatively, the contents of this file may be used under the terms of
+ - either the GNU General Public License Version 2 or later (the "GPL"), or
+ - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ - in which case the provisions of the GPL or the LGPL are applicable instead
+ - of those above. If you wish to allow use of your version of this file only
+ - under the terms of either the GPL or the LGPL, and not to allow others to
+ - use your version of this file under the terms of the MPL, indicate your
+ - decision by deleting the provisions above and replace them with the notice
+ - and other provisions required by the GPL or the LGPL. If you do not delete
+ - the provisions above, a recipient may use your version of this file under
+ - the terms of any one of the MPL, the GPL or the LGPL.
+ -
+ - ***** END LICENSE BLOCK ***** -->
+
+<!-- For localisers to change the width of the window -->
+<!ENTITY settings.style "width: 42em;">
+
+<!ENTITY window.title "Add-on Collector Settings">
+
+<!-- Tabs -->
+<!ENTITY manage.label "Manage Subscriptions">
+<!ENTITY general.label "General Settings">
+<!ENTITY pub.label "Auto-publisher Settings">
+
+<!-- Manage Subscriptions -->
+<!ENTITY subscriptions.header "Subscriptions:">
+
+<!-- Groupbox captions in Manage Subscriptions -->
+<!ENTITY frequency.label "Subscription Update Frequency">
+<!ENTITY notifications.label "New Add-on Notifications">
+<!ENTITY perpage.label "Add-ons per Page">
+
+<!ENTITY default.label "Use default setting">
+<!ENTITY custom.label "Custom:">
+
+<!ENTITY addonsleadin.label "Show">
+<!ENTITY addonsperpage.label "add-ons per page">
+<!ENTITY updatesingle.label "Update every:">
+<!ENTITY minutes.label "minute(s)">
+<!ENTITY hours.label "hour(s)">
+<!ENTITY days.label "day(s)">
+<!ENTITY autopublish.label "Auto-publish installed add-ons to subscription">
+<!ENTITY notify.label "Show notifications">
+<!ENTITY applyall.label "Apply to all subscriptions">
+<!ENTITY remove.label "Remove Subscription">
+<!ENTITY on.label "On">
+<!ENTITY off.label "Off">
+
+<!-- General -->
+
+<!-- Groupbox captions in General -->
+<!ENTITY subscriptions.label "Default Subscription Settings">
+<!ENTITY data.label "Data Management">
+
+<!ENTITY updateall.label "Check subscriptions for updates every">
+<!ENTITY notifyglobal.label "Notify me when my subscriptions have new add-ons">
+
+<!ENTITY clearemails.label "Clear">
+<!ENTITY login.label "Login">
+<!ENTITY logout.label "Logout">
+
+<!-- Auto-Publisher Settings -->
+
+<!-- Groupbox captions in Auto-Publisher Settings -->
+<!ENTITY auto.label "Auto-publisher Settings">
+
+<!ENTITY name.label "Collection Name:">
+<!ENTITY list.label "Listed in public Collection Directory">
+
+<!ENTITY autoleadin.label "Auto-publishers are special collections that are automatically updated when you install or uninstall add-ons from Firefox on this computer.">
+<!ENTITY types.label "Auto-published add-on types:">
+<!ENTITY type.extensions.label "Extensions">
+<!ENTITY type.themes.label "Themes">
+<!ENTITY type.dicts.label "Dictionaries">
+<!ENTITY type.langpacks.label "Language Packs">
+
+<!ENTITY createauto.label "Create Auto-publisher">
+<!ENTITY deleteauto.label "Delete Auto-publisher">
+<!ENTITY updateauto.label "Update Auto-publisher">
+
+<!ENTITY onlypublishenabledaddons.label "Only publish enabled add-ons">
+
+<!ENTITY misc.label "Miscellaneous">
+<!ENTITY allowincompatibleinstall.label "Allow installation of incompatible add-ons from my subscriptions">
+
diff --git a/bandwagon/locale/uk/settings.properties b/bandwagon/locale/uk/settings.properties
new file mode 100644
index 0000000..0dbf781
--- /dev/null
+++ b/bandwagon/locale/uk/settings.properties
@@ -0,0 +1,26 @@
+add.collection=Add Subscription
+enter.url.to.add.collection=Enter the URL of the subscription you want to add.
+remove.collection=Remove Subscription
+# LOCALIZATION NOTE (are.you.sure.you.want.to.remove):
+# %S is the name of a collection
+are.you.sure.you.want.to.remove=Removing this subscription will also remove the collection from your favorites list. Are you sure you wish to remove '%S'?
+# LOCALIZATION NOTE (saved.emails.text):
+# %S is a number
+saved.emails.text=You have %S saved e-mail addresses
+# LOCALIZATION NOTE (login.status.with.email):
+# %S is a user's email address
+login.status.with.email=You are logged in as %S
+login.status=You are logged in
+logout.status=You are not logged in
+# LOCALIZATION NOTE (auto.invalid.name):
+# %S is the name of a collection
+auto.invalid.name=The collection name '%S' is not valid.
+auto.please.select.type=Please select at least one add-on type to automatically publish.
+auto.create.internal.error=The collection could not be created (an internal error occurred).
+auto.create.done=Your auto-publisher collection has been created.
+auto.delete.internal.error=The collection could not be deleted (an internal error occurred).
+auto.delete.done=Your auto-publisher collection has been deleted.
+auto.create.description=An automatically generated list of my installed add-ons
+auto.update.confirm.message=Your new settings will take effect immediately, but will not affect add-ons that have already been published.
+auto.update.internal.error=The collection could not be updated (an internal error occured).
+auto.update.done=Your auto-pubisher collection has been updated.
diff --git a/bandwagon/locale/vi/bandwagon.properties b/bandwagon/locale/vi/bandwagon.properties
new file mode 100644
index 0000000..835e66c
--- /dev/null
+++ b/bandwagon/locale/vi/bandwagon.properties
@@ -0,0 +1,2 @@
+extensions.sharing@addons.mozilla.org.description=Chia sẻ và khám phá tiện ích.
+extensions.sharing@addons.mozilla.org.name=Add-on Collector (Bộ sưu tập Tiện ích)
diff --git a/bandwagon/locale/vi/bandwagonAddon.properties b/bandwagon/locale/vi/bandwagonAddon.properties
new file mode 100644
index 0000000..0a2ab99
--- /dev/null
+++ b/bandwagon/locale/vi/bandwagonAddon.properties
@@ -0,0 +1,56 @@
+# LOCALIZATION NOTE (bandwagon.addon.pluralRule):
+
+# See https://developer.mozilla.org/En/Localization_and_Plurals
+
+bandwagon.addon.pluralRule=0
+bandwagon.category1=Phần mở rộng
+# LOCALIZATION NOTE (bandwagon.addon.author):
+
+# %S will contain author's first and last name, or their nickname used on AMO
+
+bandwagon.addon.author=Bởi %S
+# LOCALIZATION NOTE (bandwagon.addon.addedby):
+
+# %S will be a user's first and last name, or nickname
+
+bandwagon.addon.addedby=bởi %S
+bandwagon.addon.added.justnow=Äược thêm: Má»›i
+# LOCALIZATION NOTE:
+
+# %S will be a number of time units indicated
+
+bandwagon.addon.added.minute=Äược thêm: %S phút trÆ°á»›c
+bandwagon.addon.added.hour=Äược thêm: %S tiếng trÆ°á»›c
+bandwagon.addon.added.day=Äược thêm: %S ngày trÆ°á»›c
+bandwagon.addon.added.week=Äược thêm: %S tuần trÆ°á»›c
+bandwagon.addon.added.month=Äược thêm: %S tháng trÆ°á»›c
+bandwagon.addon.added.year=Äược thêm: %S năm trÆ°á»›c
+bandwagon.addon.moreinfo=Thông tin thêm.
+bandwagon.addon.olderversionsoffirefox=Tiện ích này dành cho các phiên bản Firefox cũ.
+# LOCALIZATION NOTE (upgradetofirefoxn1):
+
+# %S will be a Firefox version number
+
+bandwagon.addon.upgradetofirefoxn1=Nâng cấp lên Firefox %S
+bandwagon.addon.upgradetofirefoxn2=để dùng tiện ích này.
+# LOCALIZATION NOTE (bandwagon.addon.requiresfirefoxbeta1/requiresfirefoxbeta2):
+
+# %S will be a Firefox version number
+
+bandwagon.addon.requiresfirefoxbeta1=Tiện ích này yêu cầu Firefox %S, vốn chÆ°a được phát hành. Äể dùng tiện ích này, bạn có thể
+bandwagon.addon.requiresfirefoxbeta2=tải xuống Firefox %S beta.
+# LOCALIZATION NOTE (bandwagon.addon.notcompatible):
+
+# %S will be a platform name, such as "Windows"
+
+bandwagon.addon.notcompatible=Tiện ích này không tương thích với %S.
+# LOCALIZATION NOTE (bandwagon.addon.comment.description):
+
+# %S will be a comment entered by the publisher of the add-on
+
+bandwagon.addon.comment.description="%S"
+# LOCALIZATION NOTE (bandwagon.addon.comment.author):
+
+# %S will be the publisher's real name or nickname
+
+bandwagon.addon.comment.author=Bình luận từ %S:
diff --git a/bandwagon/locale/vi/browserOverlay.dtd b/bandwagon/locale/vi/browserOverlay.dtd
new file mode 100644
index 0000000..53eacb6
--- /dev/null
+++ b/bandwagon/locale/vi/browserOverlay.dtd
@@ -0,0 +1,3 @@
+<!-- ***** BEGIN LICENSE BLOCK ***** - Version: MPL 1.1/GPL 2.0/LGPL 2.1 - - The contents of this file are subject to the Mozilla Public License Version - 1.1 (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - http://www.mozilla.org/MPL/ - - Software distributed under the License is distributed on an "AS IS" basis, - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - for the specific language governing rights and limitations under the - License. - - The Original Code is bandwagon. - - The Initial Developer of the Original Code is - Mozilla Corporation. - Portions created by the Initial Developer are Copyright (C) 2008 - the Initial Developer. All Rights Reserved. - - Contributor(s): Brian King <brian (at) briks (dot) si> - - Alternatively, the contents of this file may be used under the terms of - either the GNU General Public License Version 2 or later (the "GPL"), or - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - in which case the provisions of the GPL or the LGPL are applicable instead - of those above. If you wish to allow use of your version of this file only - under the terms of either the GPL or the LGPL, and not to allow others to - use your version of this file under the terms of the MPL, indicate your - decision by deleting the provisions above and replace them with the notice - and other provisions required by the GPL or the LGPL. If you do not delete - the provisions above, a recipient may use your version of this file under - the terms of any one of the MPL, the GPL or the LGPL. - - ***** END LICENSE BLOCK ***** -->
+<!ENTITY bandwagon.label "Tiện ích">
+<!ENTITY bandwagon.tooltip "Tiện ích">
diff --git a/bandwagon/locale/vi/browserOverlay.properties b/bandwagon/locale/vi/browserOverlay.properties
new file mode 100644
index 0000000..9612ee7
--- /dev/null
+++ b/bandwagon/locale/vi/browserOverlay.properties
@@ -0,0 +1,6 @@
+newaddons.alert.title=Thêm các Tiện ích
+# LOCALIZATION NOTE (newaddons.alert.text):
+
+# %S will be the name of a collection
+
+newaddons.alert.text=Có tiện ích trong bá»™ trá»n gói "%S" của bạn.
diff --git a/bandwagon/locale/vi/contents.rdf b/bandwagon/locale/vi/contents.rdf
new file mode 100644
index 0000000..bf15d7e
--- /dev/null
+++ b/bandwagon/locale/vi/contents.rdf
@@ -0,0 +1,15 @@
+<?xml version="1.0"?>
+<RDF:RDF xmlns:RDF="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:chrome="http://www.mozilla.org/rdf/chrome#">
+ <RDF:Seq about="urn:mozilla:locale:root">
+ <RDF:li resource="urn:mozilla:locale:vi-VN"/>
+ </RDF:Seq>
+ <RDF:Description about="urn:mozilla:locale:vi-VN" chrome:name="vi-VN" >
+ <chrome:packages>
+ <RDF:Seq about="urn:mozilla:locale:vi-VN:packages">
+ <RDF:li resource="urn:mozilla:locale:vi-VN:bandwagon"/>
+ </RDF:Seq>
+ </chrome:packages>
+ </RDF:Description>
+</RDF:RDF>
+
diff --git a/bandwagon/locale/vi/extensionOverlay.properties b/bandwagon/locale/vi/extensionOverlay.properties
new file mode 100644
index 0000000..381e9d6
--- /dev/null
+++ b/bandwagon/locale/vi/extensionOverlay.properties
@@ -0,0 +1,16 @@
+publish.new.email.address.title=Äịa chỉ Email má»›i
+publish.new.email.address.text=Nhập một địa chỉ email mới để chia sẻ tiện ích này với:
+publish.remove.title=Xác nhận
+# LOCALIZATION NOTE (publish.remove.label):
+
+# %1 is the name of an add-on. %2 is the name of a collection
+
+publish.remove.label=Bạn có chắc là mình muốn gỡ bá» %1$S khá»i bá»™ sÆ°u tập "%2$S" không?
+publish.remove.button1=Không, hủy bá»
+publish.remove.button0=Có, gỡ bỠtiện ích này
+login.error=Có lỗi khi đăng nhập. Vui lòng kiểm tra tên đăng nhập và mật khẩu.
+unsubscribe.error=Có lá»—i khi dừng đăng kí trá»n gói bá»™ sÆ°u tập này. Vui lòng thá»­ lại sau.
+unsubscribe.confirm.title=Xác nhận Dừng đăng kí
+unsubscribe.confirm.label=Dừng đăng kí bá»™ sÆ°u tập này cÅ©ng sẽ xóa nó khá»i danh sách Æ°a thích của bạn. Bạn có chắc là mình muốn dừng đăng kí không?
+unsubscribe.confirm.button1=Không, hủy bá»
+unsubscribe.confirm.button0=Có, dừng đăng kí
diff --git a/bandwagon/locale/vi/extensionsOverlay.dtd b/bandwagon/locale/vi/extensionsOverlay.dtd
new file mode 100644
index 0000000..0581d89
--- /dev/null
+++ b/bandwagon/locale/vi/extensionsOverlay.dtd
@@ -0,0 +1,26 @@
+<!-- ***** BEGIN LICENSE BLOCK ***** - Version: MPL 1.1/GPL 2.0/LGPL 2.1 - - The contents of this file are subject to the Mozilla Public License Version - 1.1 (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - http://www.mozilla.org/MPL/ - - Software distributed under the License is distributed on an "AS IS" basis, - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - for the specific language governing rights and limitations under the - License. - - The Original Code is bandwagon. - - The Initial Developer of the Original Code is - Mozilla Corporation. - Portions created by the Initial Developer are Copyright (C) 2008 - the Initial Developer. All Rights Reserved. - - Contributor(s): Brian King <brian (at) briks (dot) si> - David McNamara - - Alternatively, the contents of this file may be used under the terms of - either the GNU General Public License Version 2 or later (the "GPL"), or - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - in which case the provisions of the GPL or the LGPL are applicable instead - of those above. If you wish to allow use of your version of this file only - under the terms of either the GPL or the LGPL, and not to allow others to - use your version of this file under the terms of the MPL, indicate your - decision by deleting the provisions above and replace them with the notice - and other provisions required by the GPL or the LGPL. If you do not delete - the provisions above, a recipient may use your version of this file under - the terms of any one of the MPL, the GPL or the LGPL. - - ***** END LICENSE BLOCK ***** -->
+<!ENTITY collections.label "Bá»™ trá»n gói">
+<!ENTITY search.label.bandwagon "Tìm kiếm">
+<!ENTITY addon.moreinfo "Thêm thông tin.">
+<!ENTITY addon.addtofirefox "Thêm vào Firefox">
+<!ENTITY subscribe.label "Tìm các Bộ sưu tập">
+<!ENTITY reload.label "Tải lại Tất cả">
+<!ENTITY settings.label "Thiết lập">
+<!ENTITY view.label "Xem Bộ sưu tập">
+<!ENTITY unsubscribe.label "Dừng trá»n gói">
+<!ENTITY nocollectionstitle.label "Chào mừng đến với Sưu tập Tiện ích">
+<!ENTITY nocollectionssubscribed.label "Äây là nÆ¡i các bá»™ sÆ°u tập mà bạn đánh dấu là Æ°a thích trên Tiện ích Mozilla sẽ xuất hiện để bạn có thể dá»… dàng theo dõi chúng. Có vẻ nhÆ° bạn chÆ°a thêm bất kì mục Æ°a thích nào, vậy tại sao không thá»­ dạo quanh má»™t vòng trong ThÆ° mục Bá»™ sÆ°u tập của chúng tôi?">
+<!ENTITY clicktosubscribe.label "Tìm các Bộ sưu tập">
+<!ENTITY noamoauth.label "Äây là nÆ¡i các bá»™ sÆ°u tập mà bạn đánh dấu là Æ°a thích trên Tiện ích Mozilla sẽ xuất hiện để bạn có thể dá»… dàng theo dõi chúng. Bạn phải đăng nhập vào addons.mozilla.org để dùng tính năng này.">
+<!ENTITY username.label "Äịa chỉ Email">
+<!ENTITY password.label "Mật khẩu">
+<!ENTITY clicktologin.label "Äăng nhập">
+<!ENTITY createaccount.label "Tôi không có tài khoản">
+<!ENTITY loginheading.label "Nhập thông tin tài khoản Tiện ích Mozilla ở bên dưới:">
+<!ENTITY collectionisloading.label "Äang thu thập bá»™ trá»n gói...">
+<!ENTITY collectionhasnoitems.label "Bộ sưu tập này không chứa tiện ích nào.">
+<!ENTITY collectionhaserror.label "Bộ sưu tập này không thể được hiển thị vì nó chứa lỗi.">
+<!ENTITY publishto.label "Xuất bản sang">
+<!ENTITY email.address.label "Äịa chỉ Email">
+<!ENTITY new.email.address.label "Äịa chỉ Email má»›i">
+<!ENTITY new.collection.label "Bộ sưu tập Mới">
diff --git a/bandwagon/locale/vi/publish.dtd b/bandwagon/locale/vi/publish.dtd
new file mode 100644
index 0000000..ec1dab5
--- /dev/null
+++ b/bandwagon/locale/vi/publish.dtd
@@ -0,0 +1,47 @@
+<!-- ***** BEGIN LICENSE BLOCK *****
+ - Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ -
+ - The contents of this file are subject to the Mozilla Public License Version
+ - 1.1 (the "License"); you may not use this file except in compliance with
+ - the License. You may obtain a copy of the License at
+ - http://www.mozilla.org/MPL/
+ -
+ - Software distributed under the License is distributed on an "AS IS" basis,
+ - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ - for the specific language governing rights and limitations under the
+ - License.
+ -
+ - The Original Code is bandwagon.
+ -
+ - The Initial Developer of the Original Code is
+ - Mozilla Corporation.
+ - Portions created by the Initial Developer are Copyright (C) 2008
+ - the Initial Developer. All Rights Reserved.
+ -
+ - Contributor(s): David McNamara
+ - Brian King <brian (at) briks (dot) si>
+ -
+ - Alternatively, the contents of this file may be used under the terms of
+ - either the GNU General Public License Version 2 or later (the "GPL"), or
+ - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ - in which case the provisions of the GPL or the LGPL are applicable instead
+ - of those above. If you wish to allow use of your version of this file only
+ - under the terms of either the GPL or the LGPL, and not to allow others to
+ - use your version of this file under the terms of the MPL, indicate your
+ - decision by deleting the provisions above and replace them with the notice
+ - and other provisions required by the GPL or the LGPL. If you do not delete
+ - the provisions above, a recipient may use your version of this file under
+ - the terms of any one of the MPL, the GPL or the LGPL.
+ -
+ - ***** END LICENSE BLOCK *****
+
+ -->
+<!-- For localisers to change the width of the window -->
+<!ENTITY publish.style "width: 35em;">
+<!ENTITY window.title "Xuất bản">
+<!ENTITY cancel.label "Hủy bá»">
+<!ENTITY publish.label "Xuất bản">
+<!ENTITY new.email.label "Äịa chỉ Email má»›i">
+<!ENTITY enter.an.email.label "Nhập má»™t hoặc nhiá»u địa chỉ email, ngăn cách bởi dấu phẩy:">
+<!ENTITY remember.this.email.label "Ghi nhớ địa chỉ email này">
+<!ENTITY enter.a.personal.note.label "Phụ: Nhập một lưu ý cá nhân vỠtiện ích này để bao gồm nó trong email">
diff --git a/bandwagon/locale/vi/publish.properties b/bandwagon/locale/vi/publish.properties
new file mode 100644
index 0000000..9555c7c
--- /dev/null
+++ b/bandwagon/locale/vi/publish.properties
@@ -0,0 +1,30 @@
+# LOCALIZATION NOTE (you.are.sharing.the.add.on):
+
+# %S is the name of an add-on
+
+you.are.sharing.the.add.on=Bạn đang chia sẻ tiện ích '%S'
+# LOCALIZATION NOTE (publishing.to):
+
+# %1 is the name of an add-on. %2 is the name of a collection
+
+publishing.to=Nhấn lên "Xuất bản" sẽ thêm %1$S vào bộ sưu tập "%2$S".
+# LOCALIZATION NOTE (sharing.with):
+
+# %1 is a user's email address. $2 is the name of an add-on
+
+sharing.with=Nhấn lên "Gửi Email" sẽ gửi %1$S một email có thông tin vỠ%2$S
+# LOCALIZATION NOTE (sharing.with.new):
+
+# %S is the name of an add-on
+
+sharing.with.new=Nhấn lên "Gá»­i Email" sẽ gá»­i cho ngÆ°á»i nhận ở trên má»™t email có thông tin vá» %S
+please.enter.an.email.address=Vui lòng nhập một địa chỉ email.
+the.addon.has.been.published=Tiện ích đã được xuất bản.
+the.email.has.been.sent=Email đã được gửi.
+# LOCALIZATION NOTE (closing.in):
+
+# %S is the number of seconds until a window closes, counting down
+
+closing.in=Sẽ đóng trong %S...
+send.email=Gá»­i Email
+error.unknown_addon_guid=Tiện ích này không thể được chia sẻ vì nó không được chứa trên trang web Tiện ích Mozilla.
diff --git a/bandwagon/locale/vi/settings.dtd b/bandwagon/locale/vi/settings.dtd
new file mode 100644
index 0000000..58b3bbb
--- /dev/null
+++ b/bandwagon/locale/vi/settings.dtd
@@ -0,0 +1,54 @@
+<!-- ***** BEGIN LICENSE BLOCK ***** - Version: MPL 1.1/GPL 2.0/LGPL 2.1 - - The contents of this file are subject to the Mozilla Public License Version - 1.1 (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - http://www.mozilla.org/MPL/ - - Software distributed under the License is distributed on an "AS IS" basis, - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - for the specific language governing rights and limitations under the - License. - - The Original Code is bandwagon. - - The Initial Developer of the Original Code is - Mozilla Corporation. - Portions created by the Initial Developer are Copyright (C) 2008 - the Initial Developer. All Rights Reserved. - - Contributor(s): Brian King <brian (at) briks (dot) si> - David McNamara - - Alternatively, the contents of this file may be used under the terms of - either the GNU General Public License Version 2 or later (the "GPL"), or - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - in which case the provisions of the GPL or the LGPL are applicable instead - of those above. If you wish to allow use of your version of this file only - under the terms of either the GPL or the LGPL, and not to allow others to - use your version of this file under the terms of the MPL, indicate your - decision by deleting the provisions above and replace them with the notice - and other provisions required by the GPL or the LGPL. If you do not delete - the provisions above, a recipient may use your version of this file under - the terms of any one of the MPL, the GPL or the LGPL. - - ***** END LICENSE BLOCK ***** -->
+<!-- For localisers to change the width of the window -->
+<!ENTITY settings.style "width: 42em;">
+<!ENTITY window.title "Thiết lập Sưu tập Tiện ích">
+<!-- Tabs -->
+<!ENTITY manage.label "Quản lí Bá»™ trá»n gói">
+<!ENTITY general.label "Thiết lập Tổng quát">
+<!ENTITY pub.label "Thiết lập Tự động xuất bản">
+<!-- Manage Subscriptions -->
+<!ENTITY subscriptions.header "Bá»™ trá»n gói:">
+<!-- Groupbox captions in Manage Subscriptions -->
+<!ENTITY frequency.label "Tần suất Cập nhật Bá»™ trá»n gói">
+<!ENTITY notifications.label "Thông báo Tiện ích Mới">
+<!ENTITY perpage.label "Số tiện ích mỗi Trang">
+<!ENTITY default.label "Dùng thiết lập mặc định">
+<!ENTITY custom.label "Tùy biến:">
+<!ENTITY addonsleadin.label "Hiện">
+<!ENTITY addonsperpage.label "số tiện ích mỗi trang">
+<!ENTITY updatesingle.label "Cập nhật mỗi:">
+<!ENTITY minutes.label "phút">
+<!ENTITY hours.label "giá»">
+<!ENTITY days.label "ngày">
+<!ENTITY autopublish.label "Tá»± Ä‘á»™ng xuất bản các tiện ích đã cài vào bá»™ trá»n gói">
+<!ENTITY notify.label "Hiện thông báo">
+<!ENTITY applyall.label "Ãp dụng cho tất cả các bá»™ trá»n gói">
+<!ENTITY remove.label "Gỡ bá» Bá»™ trá»n gói">
+<!ENTITY on.label "Bật">
+<!ENTITY off.label "Tắt">
+<!-- General -->
+<!-- Groupbox captions in General -->
+<!ENTITY subscriptions.label "Thiết lập Bá»™ trá»n gói Mặc định">
+<!ENTITY data.label "Quản lí Dữ liệu">
+<!ENTITY updateall.label "Kiểm tra cập nhật cho các bá»™ trá»n gói má»—i">
+<!ENTITY notifyglobal.label "Báo tôi khi các bá»™ trá»n gói có thêm tiện ích má»›i">
+<!ENTITY clearemails.label "Xóa trắng">
+<!ENTITY login.label "Äăng nhập">
+<!ENTITY logout.label "Thoát">
+<!-- Auto-Publisher Settings -->
+<!-- Groupbox captions in Auto-Publisher Settings -->
+<!ENTITY auto.label "Thiết lập Tự động xuất bản">
+<!ENTITY name.label "Tên của Bộ sưu tập:">
+<!ENTITY list.label "Liệt kê trong Thư mục Bộ sưu tập công cộng">
+<!ENTITY autoleadin.label "Trình xuất bản tá»± Ä‘á»™ng là những bá»™ sÆ°u tập đặc biệt được tá»± Ä‘á»™ng cập nhật má»—i khi bạn cài đặt hoặc gỡ bá» tiện ích khá»i Firefox trên máy tính này.">
+<!ENTITY types.label "Kiểu tiện ích được tự động xuất bản:">
+<!ENTITY type.extensions.label "Phần mở rộng">
+<!ENTITY type.themes.label "Giao diện">
+<!ENTITY type.dicts.label "Từ điển">
+<!ENTITY type.langpacks.label "Gói ngôn ngữ">
+<!ENTITY createauto.label "Tạo Xuất-bản-Tự-động">
+<!ENTITY deleteauto.label "Xóa Xuất-bản-Tự-động">
+<!ENTITY updateauto.label "Cập nhật Xuất-bản-Tự-động">
+<!ENTITY onlypublishenabledaddons.label "Chỉ xuất bản các tiện ích được kích hoạt">
+<!ENTITY misc.label "Linh tinh">
+<!ENTITY allowincompatibleinstall.label "Cho phép cài đặt các tiện ích không tÆ°Æ¡ng thích từ bá»™ trá»n gói của tôi">
diff --git a/bandwagon/locale/vi/settings.properties b/bandwagon/locale/vi/settings.properties
new file mode 100644
index 0000000..19a9c7a
--- /dev/null
+++ b/bandwagon/locale/vi/settings.properties
@@ -0,0 +1,34 @@
+add.collection=Thêm má»™t Bá»™ trá»n gói
+enter.url.to.add.collection=Nhập URL của bá»™ trá»n gói mà bạn muốn thêm.
+remove.collection=Gỡ bá» Bá»™ trá»n gói
+# LOCALIZATION NOTE (are.you.sure.you.want.to.remove):
+
+# %S is the name of a collection
+
+are.you.sure.you.want.to.remove=Gỡ bá» bá»™ trá»n gói này cÅ©ng sẽ gỡ bá» bá»™ sÆ°u tập khá»i danh sách Æ°a thích của bạn. Bạn có chắc là bạn muốn gỡ bá» '%S' không?
+# LOCALIZATION NOTE (saved.emails.text):
+
+# %S is a number
+
+saved.emails.text=Bạn có %S địa chỉ email được lưu
+# LOCALIZATION NOTE (login.status.with.email):
+
+# %S is a user's email address
+
+login.status.with.email=Bạn đang đăng nhập bằng %S
+login.status=Bạn đang đăng nhập
+logout.status=Bạn chưa đăng nhập
+# LOCALIZATION NOTE (auto.invalid.name):
+
+# %S is the name of a collection
+
+auto.invalid.name=Tên bộ sưu tập '%S' không hợp lệ.
+auto.please.select.type=Vui lòng chá»n ít nhất má»™t kiểu tiện ích để tá»± Ä‘á»™ng xuất bản.
+auto.create.internal.error=Bộ sưu tập không thể được tạo (một lỗi nội trú đã xảy ra).
+auto.create.done=Bộ sưu tập tự-động-xuất-bản của bạn vừa được tạo.
+auto.delete.internal.error=Bộ sưu tập không thể bị xóa (một lỗi nội trú đã xảy ra).
+auto.delete.done=Bộ sưu tập tự-động-xuất-bản của bạn vừa được xóa.
+auto.create.description=Một danh sách được tạo ra tự động gồm các tiện ích đã cài đặt của tôi.
+auto.update.confirm.message=Thiết lập mới của bạn sẽ có hiệu lực ngay lập tức, nhưng sẽ không ảnh hưởng đến các tiện ích đã được xuất bản.
+auto.update.internal.error=Bộ sưu tập không thể cập nhật được (một lỗi nội trú đã xảy ra).
+auto.update.done=Bộ sưu tập tự-động-xuất-bản của bạn đã được cập nhật.
diff --git a/bandwagon/locale/zh-CN/bandwagon.properties b/bandwagon/locale/zh-CN/bandwagon.properties
new file mode 100644
index 0000000..622a6ed
--- /dev/null
+++ b/bandwagon/locale/zh-CN/bandwagon.properties
@@ -0,0 +1,2 @@
+extensions.sharing@addons.mozilla.org.description=共享和å‘现附加组件
+extensions.sharing@addons.mozilla.org.name=Add-on Collector
diff --git a/bandwagon/locale/zh-CN/bandwagonAddon.properties b/bandwagon/locale/zh-CN/bandwagonAddon.properties
new file mode 100644
index 0000000..ff1a662
--- /dev/null
+++ b/bandwagon/locale/zh-CN/bandwagonAddon.properties
@@ -0,0 +1,56 @@
+# LOCALIZATION NOTE (bandwagon.addon.pluralRule):
+
+# See https://developer.mozilla.org/En/Localization_and_Plurals
+
+bandwagon.addon.pluralRule=1
+bandwagon.category1=扩展
+# LOCALIZATION NOTE (bandwagon.addon.author):
+
+# %S will contain author's first and last name, or their nickname used on AMO
+
+bandwagon.addon.author=作者:%S
+# LOCALIZATION NOTE (bandwagon.addon.addedby):
+
+# %S will be a user's first and last name, or nickname
+
+bandwagon.addon.addedby=作者:%S
+bandwagon.addon.added.justnow=添加于:刚æ‰
+# LOCALIZATION NOTE:
+
+# %S will be a number of time units indicated
+
+bandwagon.addon.added.minute=添加于:1 åˆ†é’Ÿå‰ ; 添加于:%S 分钟å‰
+bandwagon.addon.added.hour=添加于:1å°æ—¶å‰ ; 添加于:%S å°æ—¶å‰
+bandwagon.addon.added.day=添加于:昨天 ; 添加于:%S 天以å‰
+bandwagon.addon.added.week=添加于:1å‘¨å‰ ; 添加于:%S 周å‰
+bandwagon.addon.added.month=添加于:1ä¸ªæœˆå‰ ; 添加于:%S个月å‰
+bandwagon.addon.added.year=添加于:1å¹´å‰ ; 添加于:%S å¹´å‰
+bandwagon.addon.moreinfo=更多信æ¯ã€‚
+bandwagon.addon.olderversionsoffirefox=这个附加组件是供早期版本 Firefox 使用的。
+# LOCALIZATION NOTE (upgradetofirefoxn1):
+
+# %S will be a Firefox version number
+
+bandwagon.addon.upgradetofirefoxn1=更新到 Firefox %S
+bandwagon.addon.upgradetofirefoxn2=以便使用这个附加组件。
+# LOCALIZATION NOTE (bandwagon.addon.requiresfirefoxbeta1/requiresfirefoxbeta2):
+
+# %S will be a Firefox version number
+
+bandwagon.addon.requiresfirefoxbeta1=该附加组件需è¦å°šæœªå‘布的 Firefox %S 。è¦ä½¿ç”¨è¿™ä¸ªé™„加组件,你å¯ä»¥
+bandwagon.addon.requiresfirefoxbeta2=下载 Firefox %S Beta(测试版)。
+# LOCALIZATION NOTE (bandwagon.addon.notcompatible):
+
+# %S will be a platform name, such as "Windows"
+
+bandwagon.addon.notcompatible=这个附加组件和 %S ä¸å…¼å®¹ã€‚
+# LOCALIZATION NOTE (bandwagon.addon.comment.description):
+
+# %S will be a comment entered by the publisher of the add-on
+
+bandwagon.addon.comment.description=“%Sâ€
+# LOCALIZATION NOTE (bandwagon.addon.comment.author):
+
+# %S will be the publisher's real name or nickname
+
+bandwagon.addon.comment.author=æ¥è‡ª %S 的评论:
diff --git a/bandwagon/locale/zh-CN/browserOverlay.dtd b/bandwagon/locale/zh-CN/browserOverlay.dtd
new file mode 100644
index 0000000..57468d0
--- /dev/null
+++ b/bandwagon/locale/zh-CN/browserOverlay.dtd
@@ -0,0 +1,3 @@
+<!-- ***** BEGIN LICENSE BLOCK ***** - Version: MPL 1.1/GPL 2.0/LGPL 2.1 - - The contents of this file are subject to the Mozilla Public License Version - 1.1 (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - http://www.mozilla.org/MPL/ - - Software distributed under the License is distributed on an "AS IS" basis, - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - for the specific language governing rights and limitations under the - License. - - The Original Code is bandwagon. - - The Initial Developer of the Original Code is - Mozilla Corporation. - Portions created by the Initial Developer are Copyright (C) 2008 - the Initial Developer. All Rights Reserved. - - Contributor(s): Brian King <brian (at) briks (dot) si> - - Alternatively, the contents of this file may be used under the terms of - either the GNU General Public License Version 2 or later (the "GPL"), or - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - in which case the provisions of the GPL or the LGPL are applicable instead - of those above. If you wish to allow use of your version of this file only - under the terms of either the GPL or the LGPL, and not to allow others to - use your version of this file under the terms of the MPL, indicate your - decision by deleting the provisions above and replace them with the notice - and other provisions required by the GPL or the LGPL. If you do not delete - the provisions above, a recipient may use your version of this file under - the terms of any one of the MPL, the GPL or the LGPL. - - ***** END LICENSE BLOCK ***** -->
+<!ENTITY bandwagon.label "附加组件">
+<!ENTITY bandwagon.tooltip "附加组件">
diff --git a/bandwagon/locale/zh-CN/browserOverlay.properties b/bandwagon/locale/zh-CN/browserOverlay.properties
new file mode 100644
index 0000000..b7094cb
--- /dev/null
+++ b/bandwagon/locale/zh-CN/browserOverlay.properties
@@ -0,0 +1,6 @@
+newaddons.alert.title=新附加组件
+# LOCALIZATION NOTE (newaddons.alert.text):
+
+# %S will be the name of a collection
+
+newaddons.alert.text=你订阅的收è—夹 "$S" 中有新的附加组件。
diff --git a/bandwagon/locale/zh-CN/contents.rdf b/bandwagon/locale/zh-CN/contents.rdf
new file mode 100644
index 0000000..6318d32
--- /dev/null
+++ b/bandwagon/locale/zh-CN/contents.rdf
@@ -0,0 +1,15 @@
+<?xml version="1.0"?>
+<RDF:RDF xmlns:RDF="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:chrome="http://www.mozilla.org/rdf/chrome#">
+ <RDF:Seq about="urn:mozilla:locale:root">
+ <RDF:li resource="urn:mozilla:locale:zh-CN"/>
+ </RDF:Seq>
+ <RDF:Description about="urn:mozilla:locale:zh-CN" chrome:name="zh-CN" >
+ <chrome:packages>
+ <RDF:Seq about="urn:mozilla:locale:zh-CN:packages">
+ <RDF:li resource="urn:mozilla:locale:zh-CN:bandwagon"/>
+ </RDF:Seq>
+ </chrome:packages>
+ </RDF:Description>
+</RDF:RDF>
+
diff --git a/bandwagon/locale/zh-CN/extensionOverlay.properties b/bandwagon/locale/zh-CN/extensionOverlay.properties
new file mode 100644
index 0000000..ba139fb
--- /dev/null
+++ b/bandwagon/locale/zh-CN/extensionOverlay.properties
@@ -0,0 +1,16 @@
+publish.new.email.address.title=新增邮件地å€
+publish.new.email.address.text=输入一个新的邮件地å€ä»¥å…±äº«è¯¥é™„加组件:
+publish.remove.title=确认
+# LOCALIZATION NOTE (publish.remove.label):
+
+# %1 is the name of an add-on. %2 is the name of a collection
+
+publish.remove.label=你确认è¦ä»Žæ”¶è—夹 "%2$S" 中移除 %1$S ?
+publish.remove.button1=ä¸ï¼Œå–消
+publish.remove.button0=是的,移除附加组件
+login.error=登录时出现错误。请检查你的用户å和密ç æ˜¯å¦æ­£ç¡®ã€‚
+unsubscribe.error=从收è—夹中å–消订阅时出现错误。请ç¨å€™å†è¯•ã€‚
+unsubscribe.confirm.title=确认å–消订阅
+unsubscribe.confirm.label=从这个收è—夹中å–消订阅的åŒæ—¶è¿˜ä¼šä»Žä½ çš„最爱列表中删除。你确认è¦å–消订阅?
+unsubscribe.confirm.button1=ä¸ï¼Œæ”¾å¼ƒã€‚
+unsubscribe.confirm.button0=是的,å–消订阅。
diff --git a/bandwagon/locale/zh-CN/extensionsOverlay.dtd b/bandwagon/locale/zh-CN/extensionsOverlay.dtd
new file mode 100644
index 0000000..940f8a5
--- /dev/null
+++ b/bandwagon/locale/zh-CN/extensionsOverlay.dtd
@@ -0,0 +1,26 @@
+<!-- ***** BEGIN LICENSE BLOCK ***** - Version: MPL 1.1/GPL 2.0/LGPL 2.1 - - The contents of this file are subject to the Mozilla Public License Version - 1.1 (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - http://www.mozilla.org/MPL/ - - Software distributed under the License is distributed on an "AS IS" basis, - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - for the specific language governing rights and limitations under the - License. - - The Original Code is bandwagon. - - The Initial Developer of the Original Code is - Mozilla Corporation. - Portions created by the Initial Developer are Copyright (C) 2008 - the Initial Developer. All Rights Reserved. - - Contributor(s): Brian King <brian (at) briks (dot) si> - David McNamara - - Alternatively, the contents of this file may be used under the terms of - either the GNU General Public License Version 2 or later (the "GPL"), or - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - in which case the provisions of the GPL or the LGPL are applicable instead - of those above. If you wish to allow use of your version of this file only - under the terms of either the GPL or the LGPL, and not to allow others to - use your version of this file under the terms of the MPL, indicate your - decision by deleting the provisions above and replace them with the notice - and other provisions required by the GPL or the LGPL. If you do not delete - the provisions above, a recipient may use your version of this file under - the terms of any one of the MPL, the GPL or the LGPL. - - ***** END LICENSE BLOCK ***** -->
+<!ENTITY collections.label "订阅">
+<!ENTITY search.label.bandwagon "æœç´¢">
+<!ENTITY addon.moreinfo "更多信æ¯ã€‚">
+<!ENTITY addon.addtofirefox "添加到 Firefox">
+<!ENTITY subscribe.label "查找收è—">
+<!ENTITY reload.label "é‡æ–°è½½å…¥æ‰€æœ‰">
+<!ENTITY settings.label "设置">
+<!ENTITY view.label "查看收è—">
+<!ENTITY unsubscribe.label "å–消订阅">
+<!ENTITY nocollectionstitle.label "欢迎使用 Add-on Collector">
+<!ENTITY nocollectionssubscribed.label "你在 Mozilla 附加组件上标记为最爱的附加组件会显示在这个收è—夹里以便你很容易地跟踪他们。看上去你尚未添加任何最爱,所以为什么ä¸åŽ»æˆ‘们的收è—夹目录看看呢?">
+<!ENTITY clicktosubscribe.label "查找收è—">
+<!ENTITY noamoauth.label "你在 Mozilla 附加组件上标记为最爱的附加组件会显示在这个收è—夹里以便你很容易地跟踪他们。你必须登录到 addons.mozilla.org æ‰èƒ½ä½¿ç”¨è¿™ä¸ªåŠŸèƒ½ã€‚">
+<!ENTITY username.label "用户å">
+<!ENTITY password.label "密ç ">
+<!ENTITY clicktologin.label "登录">
+<!ENTITY createaccount.label "我没有å¸å·">
+<!ENTITY loginheading.label "在下é¢è¾“入你的 Mozilla 附加组件å¸æˆ·ä¿¡æ¯ï¼š">
+<!ENTITY collectionisloading.label "接收订阅…">
+<!ENTITY collectionhasnoitems.label "收è—夹中没有附加组件。">
+<!ENTITY collectionhaserror.label "收è—夹ä¸èƒ½æ˜¾ç¤ºï¼Œå› ä¸ºå…¶ä¸­æœ‰é”™è¯¯ã€‚">
+<!ENTITY publishto.label "å‘布到">
+<!ENTITY email.address.label "电å­é‚®ä»¶åœ°å€">
+<!ENTITY new.email.address.label "新电å­é‚®ä»¶åœ°å€">
+<!ENTITY new.collection.label "新收è—夹">
diff --git a/bandwagon/locale/zh-CN/publish.dtd b/bandwagon/locale/zh-CN/publish.dtd
new file mode 100644
index 0000000..349e9b3
--- /dev/null
+++ b/bandwagon/locale/zh-CN/publish.dtd
@@ -0,0 +1,47 @@
+<!-- ***** BEGIN LICENSE BLOCK *****
+ - Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ -
+ - The contents of this file are subject to the Mozilla Public License Version
+ - 1.1 (the "License"); you may not use this file except in compliance with
+ - the License. You may obtain a copy of the License at
+ - http://www.mozilla.org/MPL/
+ -
+ - Software distributed under the License is distributed on an "AS IS" basis,
+ - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ - for the specific language governing rights and limitations under the
+ - License.
+ -
+ - The Original Code is bandwagon.
+ -
+ - The Initial Developer of the Original Code is
+ - Mozilla Corporation.
+ - Portions created by the Initial Developer are Copyright (C) 2008
+ - the Initial Developer. All Rights Reserved.
+ -
+ - Contributor(s): David McNamara
+ - Brian King <brian (at) briks (dot) si>
+ -
+ - Alternatively, the contents of this file may be used under the terms of
+ - either the GNU General Public License Version 2 or later (the "GPL"), or
+ - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ - in which case the provisions of the GPL or the LGPL are applicable instead
+ - of those above. If you wish to allow use of your version of this file only
+ - under the terms of either the GPL or the LGPL, and not to allow others to
+ - use your version of this file under the terms of the MPL, indicate your
+ - decision by deleting the provisions above and replace them with the notice
+ - and other provisions required by the GPL or the LGPL. If you do not delete
+ - the provisions above, a recipient may use your version of this file under
+ - the terms of any one of the MPL, the GPL or the LGPL.
+ -
+ - ***** END LICENSE BLOCK *****
+
+ -->
+<!-- For localisers to change the width of the window -->
+<!ENTITY publish.style "宽度: 35em;">
+<!ENTITY window.title "å‘布">
+<!ENTITY cancel.label "å–消">
+<!ENTITY publish.label "å‘布">
+<!ENTITY new.email.label "新增邮件地å€">
+<!ENTITY enter.an.email.label "输入一个或者多个电å­é‚®ä»¶åœ°å€ï¼Œä»¥é€—å·åˆ†éš”:">
+<!ENTITY remember.this.email.label "è®°ä½è¿™ä¸ªé‚®ä»¶åœ°å€">
+<!ENTITY enter.a.personal.note.label "å¯é€‰ï¼šè¾“入有关这个附加组件的ç§äººæ³¨é‡Šï¼ŒåŒ…å«åœ¨ç”µå­é‚®ä»¶ä¸­">
diff --git a/bandwagon/locale/zh-CN/publish.properties b/bandwagon/locale/zh-CN/publish.properties
new file mode 100644
index 0000000..5d8d53c
--- /dev/null
+++ b/bandwagon/locale/zh-CN/publish.properties
@@ -0,0 +1,30 @@
+# LOCALIZATION NOTE (you.are.sharing.the.add.on):
+
+# %S is the name of an add-on
+
+you.are.sharing.the.add.on=你正在共享附加组件'%S'
+# LOCALIZATION NOTE (publishing.to):
+
+# %1 is the name of an add-on. %2 is the name of a collection
+
+publishing.to=点击“å‘布â€å°† %1$S 加入收è—夹 “%2$Sâ€ã€‚
+# LOCALIZATION NOTE (sharing.with):
+
+# %1 is a user's email address. $2 is the name of an add-on
+
+sharing.with=点击“å‘é€ç”µå­é‚®ä»¶â€å°†æœ‰å…³ %2$S çš„ä¿¡æ¯é€šè¿‡ç”µå­é‚®ä»¶å‘é€ç»™ %1$S
+# LOCALIZATION NOTE (sharing.with.new):
+
+# %S is the name of an add-on
+
+sharing.with.new=点击“å‘é€ç”µå­é‚®ä»¶â€å°†æœ‰å…³ %S çš„ä¿¡æ¯é€šè¿‡ç”µå­é‚®ä»¶å‘é€ç»™ä»¥ä¸Šæ”¶ä»¶äºº
+please.enter.an.email.address=请输入电å­é‚®ä»¶åœ°å€
+the.addon.has.been.published=附加组件已å‘布。
+the.email.has.been.sent=邮件已å‘é€ã€‚
+# LOCALIZATION NOTE (closing.in):
+
+# %S is the number of seconds until a window closes, counting down
+
+closing.in=%S 秒内关闭…
+send.email=å‘é€ç”µå­é‚®ä»¶
+error.unknown_addon_guid=该附加组件ä¸èƒ½å…±äº«ï¼Œå› ä¸ºä»–没有存放在 Mozilla 附加组件网站上。
diff --git a/bandwagon/locale/zh-CN/settings.dtd b/bandwagon/locale/zh-CN/settings.dtd
new file mode 100644
index 0000000..9f8535c
--- /dev/null
+++ b/bandwagon/locale/zh-CN/settings.dtd
@@ -0,0 +1,54 @@
+<!-- ***** BEGIN LICENSE BLOCK ***** - Version: MPL 1.1/GPL 2.0/LGPL 2.1 - - The contents of this file are subject to the Mozilla Public License Version - 1.1 (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - http://www.mozilla.org/MPL/ - - Software distributed under the License is distributed on an "AS IS" basis, - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - for the specific language governing rights and limitations under the - License. - - The Original Code is bandwagon. - - The Initial Developer of the Original Code is - Mozilla Corporation. - Portions created by the Initial Developer are Copyright (C) 2008 - the Initial Developer. All Rights Reserved. - - Contributor(s): Brian King <brian (at) briks (dot) si> - David McNamara - - Alternatively, the contents of this file may be used under the terms of - either the GNU General Public License Version 2 or later (the "GPL"), or - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - in which case the provisions of the GPL or the LGPL are applicable instead - of those above. If you wish to allow use of your version of this file only - under the terms of either the GPL or the LGPL, and not to allow others to - use your version of this file under the terms of the MPL, indicate your - decision by deleting the provisions above and replace them with the notice - and other provisions required by the GPL or the LGPL. If you do not delete - the provisions above, a recipient may use your version of this file under - the terms of any one of the MPL, the GPL or the LGPL. - - ***** END LICENSE BLOCK ***** -->
+<!-- For localisers to change the width of the window -->
+<!ENTITY settings.style "宽度:42em;">
+<!ENTITY window.title "Add-on Collector 设置">
+<!-- Tabs -->
+<!ENTITY manage.label "管ç†è®¢é˜…">
+<!ENTITY general.label "常规设置">
+<!ENTITY pub.label "自动å‘布设置">
+<!-- Manage Subscriptions -->
+<!ENTITY subscriptions.header "订阅:">
+<!-- Groupbox captions in Manage Subscriptions -->
+<!ENTITY frequency.label "订阅更新频率">
+<!ENTITY notifications.label "新附加组件通知">
+<!ENTITY perpage.label "æ¯é¡µé™„加组件数">
+<!ENTITY default.label "使用默认设置">
+<!ENTITY custom.label "自定义:">
+<!ENTITY addonsleadin.label "显示">
+<!ENTITY addonsperpage.label "æ¯é¡µé™„加组件数">
+<!ENTITY updatesingle.label "更新频率(æ¯ï¼‰ï¼š">
+<!ENTITY minutes.label "分钟">
+<!ENTITY hours.label "å°æ—¶">
+<!ENTITY days.label "天">
+<!ENTITY autopublish.label "自动订阅已安装的附加组件">
+<!ENTITY notify.label "显示通知">
+<!ENTITY applyall.label "应用到所有订阅">
+<!ENTITY remove.label "移除订阅">
+<!ENTITY on.label "å¼€">
+<!ENTITY off.label "å…³">
+<!-- General -->
+<!-- Groupbox captions in General -->
+<!ENTITY subscriptions.label "默认订阅设置">
+<!ENTITY data.label "æ•°æ®ç®¡ç†">
+<!ENTITY updateall.label "检查订阅更新的频率(æ¯ï¼‰">
+<!ENTITY notifyglobal.label "订阅中有新附加组件时通知我">
+<!ENTITY clearemails.label "清除">
+<!ENTITY login.label "登录">
+<!ENTITY logout.label "退出">
+<!-- Auto-Publisher Settings -->
+<!-- Groupbox captions in Auto-Publisher Settings -->
+<!ENTITY auto.label "自动å‘布设置">
+<!ENTITY name.label "收è—夹å称:">
+<!ENTITY list.label "公开收è—夹目录中列出的">
+<!ENTITY autoleadin.label "自动å‘布是一个特殊的收è—夹,当你从本机的 Firefox 上安装或者å¸è½½é™„加组件的时候会自动更新。">
+<!ENTITY types.label "自动更新附加组件类型:">
+<!ENTITY type.extensions.label "扩展">
+<!ENTITY type.themes.label "主题">
+<!ENTITY type.dicts.label "å­—å…¸">
+<!ENTITY type.langpacks.label "语言包">
+<!ENTITY createauto.label "建立自动å‘布">
+<!ENTITY deleteauto.label "删除自动å‘布">
+<!ENTITY updateauto.label "更新自动å‘布">
+<!ENTITY onlypublishenabledaddons.label "ä»…å‘布å¯ç”¨çš„附加组件">
+<!ENTITY misc.label "æ‚项">
+<!ENTITY allowincompatibleinstall.label "å…许从我的订阅中安装ä¸å…¼å®¹çš„附加组件">
diff --git a/bandwagon/locale/zh-CN/settings.properties b/bandwagon/locale/zh-CN/settings.properties
new file mode 100644
index 0000000..ea34067
--- /dev/null
+++ b/bandwagon/locale/zh-CN/settings.properties
@@ -0,0 +1,34 @@
+add.collection=添加订阅
+enter.url.to.add.collection=输入你è¦æ·»åŠ çš„订阅的网å€ã€‚
+remove.collection=移除订阅
+# LOCALIZATION NOTE (are.you.sure.you.want.to.remove):
+
+# %S is the name of a collection
+
+are.you.sure.you.want.to.remove=移除这个订阅åŒæ—¶ä¼šä»Žä½ çš„收è—列表中移除这个收è—夹。你是å¦ç¡®è®¤è¦ç§»é™¤ '%S' ?
+# LOCALIZATION NOTE (saved.emails.text):
+
+# %S is a number
+
+saved.emails.text=你有 %S 个已ä¿å­˜çš„邮件地å€
+# LOCALIZATION NOTE (login.status.with.email):
+
+# %S is a user's email address
+
+login.status.with.email=ä½ å·²ç»ä»¥ %S 的身份登录
+login.status=你已登录
+logout.status=你尚未登录
+# LOCALIZATION NOTE (auto.invalid.name):
+
+# %S is the name of a collection
+
+auto.invalid.name=收è—夹å称 '%S' 是无效的。
+auto.please.select.type=请选择至少一个附加组件类型以供自动å‘布。
+auto.create.internal.error=收è—夹ä¸èƒ½å»ºç«‹ï¼ˆå‘生内部错误)。
+auto.create.done=你的自动å‘布收è—夹已ç»å»ºç«‹ã€‚
+auto.delete.internal.error=该收è—夹ä¸èƒ½è¢«åˆ é™¤ï¼ˆå‘生内部错误)。
+auto.delete.done=你的自动å‘布收è—夹已ç»è¢«åˆ é™¤ã€‚
+auto.create.description=自动生æˆçš„你已安装附加组件的列表
+auto.update.confirm.message=你的新设置会立刻生效,但是ä¸ä¼šå½±å“之å‰å·²ç»å‘布的附加组件。
+auto.update.internal.error=收è—夹无法更新(å‘生内部错误)。
+auto.update.done=你的自动å‘布收è—夹已ç»æ›´æ–°ã€‚
diff --git a/bandwagon/locale/zh-TW/bandwagon.properties b/bandwagon/locale/zh-TW/bandwagon.properties
new file mode 100644
index 0000000..0a6352c
--- /dev/null
+++ b/bandwagon/locale/zh-TW/bandwagon.properties
@@ -0,0 +1,2 @@
+extensions.sharing@addons.mozilla.org.description=分享與發ç¾æ›´å¤šé™„加元件。
+extensions.sharing@addons.mozilla.org.name=Add-on Collector
diff --git a/bandwagon/locale/zh-TW/bandwagonAddon.properties b/bandwagon/locale/zh-TW/bandwagonAddon.properties
new file mode 100644
index 0000000..18eb3b0
--- /dev/null
+++ b/bandwagon/locale/zh-TW/bandwagonAddon.properties
@@ -0,0 +1,56 @@
+# LOCALIZATION NOTE (bandwagon.addon.pluralRule):
+
+# See https://developer.mozilla.org/En/Localization_and_Plurals
+
+bandwagon.addon.pluralRule=0
+bandwagon.category1=擴充套件
+# LOCALIZATION NOTE (bandwagon.addon.author):
+
+# %S will contain author's first and last name, or their nickname used on AMO
+
+bandwagon.addon.author=作者: %S
+# LOCALIZATION NOTE (bandwagon.addon.addedby):
+
+# %S will be a user's first and last name, or nickname
+
+bandwagon.addon.addedby=收è—者: %S
+bandwagon.addon.added.justnow=新增: 剛新增
+# LOCALIZATION NOTE:
+
+# %S will be a number of time units indicated
+
+bandwagon.addon.added.minute=新增: %S 分é˜å‰
+bandwagon.addon.added.hour=新增: %S å°æ™‚å‰
+bandwagon.addon.added.day=新增: %S 天å‰
+bandwagon.addon.added.week=新增: %S 星期å‰
+bandwagon.addon.added.month=新增: %S 月å‰
+bandwagon.addon.added.year=新增: %S å¹´å‰
+bandwagon.addon.moreinfo=更多資訊。
+bandwagon.addon.olderversionsoffirefox=這個附加元件僅供舊版 Firefox 使用。
+# LOCALIZATION NOTE (upgradetofirefoxn1):
+
+# %S will be a Firefox version number
+
+bandwagon.addon.upgradetofirefoxn1=å‡ç´šåˆ° Firefox %S
+bandwagon.addon.upgradetofirefoxn2=以使用此附加元件。
+# LOCALIZATION NOTE (bandwagon.addon.requiresfirefoxbeta1/requiresfirefoxbeta2):
+
+# %S will be a Firefox version number
+
+bandwagon.addon.requiresfirefoxbeta1=é€™å€‹é™„åŠ å…ƒä»¶éœ€è¦ Firefox %S,目å‰å°šæœªæŽ¨å‡ºæ­£å¼ç‰ˆã€‚è¦ä½¿ç”¨é€™å€‹é™„加元件,你å¯ä»¥
+bandwagon.addon.requiresfirefoxbeta2=下載 Firefox %S beta。
+# LOCALIZATION NOTE (bandwagon.addon.notcompatible):
+
+# %S will be a platform name, such as "Windows"
+
+bandwagon.addon.notcompatible=這個附加元件與 %S ä¸ç›¸å®¹ã€‚
+# LOCALIZATION NOTE (bandwagon.addon.comment.description):
+
+# %S will be a comment entered by the publisher of the add-on
+
+bandwagon.addon.comment.description=「%Sã€
+# LOCALIZATION NOTE (bandwagon.addon.comment.author):
+
+# %S will be the publisher's real name or nickname
+
+bandwagon.addon.comment.author=來自 %S çš„æ„見:
diff --git a/bandwagon/locale/zh-TW/browserOverlay.dtd b/bandwagon/locale/zh-TW/browserOverlay.dtd
new file mode 100644
index 0000000..25aa1b7
--- /dev/null
+++ b/bandwagon/locale/zh-TW/browserOverlay.dtd
@@ -0,0 +1,3 @@
+<!-- ***** BEGIN LICENSE BLOCK ***** - Version: MPL 1.1/GPL 2.0/LGPL 2.1 - - The contents of this file are subject to the Mozilla Public License Version - 1.1 (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - http://www.mozilla.org/MPL/ - - Software distributed under the License is distributed on an "AS IS" basis, - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - for the specific language governing rights and limitations under the - License. - - The Original Code is bandwagon. - - The Initial Developer of the Original Code is - Mozilla Corporation. - Portions created by the Initial Developer are Copyright (C) 2008 - the Initial Developer. All Rights Reserved. - - Contributor(s): Brian King <brian (at) briks (dot) si> - - Alternatively, the contents of this file may be used under the terms of - either the GNU General Public License Version 2 or later (the "GPL"), or - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - in which case the provisions of the GPL or the LGPL are applicable instead - of those above. If you wish to allow use of your version of this file only - under the terms of either the GPL or the LGPL, and not to allow others to - use your version of this file under the terms of the MPL, indicate your - decision by deleting the provisions above and replace them with the notice - and other provisions required by the GPL or the LGPL. If you do not delete - the provisions above, a recipient may use your version of this file under - the terms of any one of the MPL, the GPL or the LGPL. - - ***** END LICENSE BLOCK ***** -->
+<!ENTITY bandwagon.label "附加元件">
+<!ENTITY bandwagon.tooltip "附加元件">
diff --git a/bandwagon/locale/zh-TW/browserOverlay.properties b/bandwagon/locale/zh-TW/browserOverlay.properties
new file mode 100644
index 0000000..c74fe1b
--- /dev/null
+++ b/bandwagon/locale/zh-TW/browserOverlay.properties
@@ -0,0 +1,6 @@
+newaddons.alert.title=新附加元件
+# LOCALIZATION NOTE (newaddons.alert.text):
+
+# %S will be the name of a collection
+
+newaddons.alert.text=您訂閱的收è—集新增了附加元件「%Sã€ã€‚
diff --git a/bandwagon/locale/zh-TW/contents.rdf b/bandwagon/locale/zh-TW/contents.rdf
new file mode 100644
index 0000000..c0fdfc3
--- /dev/null
+++ b/bandwagon/locale/zh-TW/contents.rdf
@@ -0,0 +1,15 @@
+<?xml version="1.0"?>
+<RDF:RDF xmlns:RDF="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:chrome="http://www.mozilla.org/rdf/chrome#">
+ <RDF:Seq about="urn:mozilla:locale:root">
+ <RDF:li resource="urn:mozilla:locale:zh-TW"/>
+ </RDF:Seq>
+ <RDF:Description about="urn:mozilla:locale:zh-TW" chrome:name="zh-TW" >
+ <chrome:packages>
+ <RDF:Seq about="urn:mozilla:locale:zh-TW:packages">
+ <RDF:li resource="urn:mozilla:locale:zh-TW:bandwagon"/>
+ </RDF:Seq>
+ </chrome:packages>
+ </RDF:Description>
+</RDF:RDF>
+
diff --git a/bandwagon/locale/zh-TW/extensionOverlay.properties b/bandwagon/locale/zh-TW/extensionOverlay.properties
new file mode 100644
index 0000000..fac48fd
--- /dev/null
+++ b/bandwagon/locale/zh-TW/extensionOverlay.properties
@@ -0,0 +1,16 @@
+publish.new.email.address.title=æ–° E-mail 地å€
+publish.new.email.address.text=輸入一個新的 E-mail 地å€ä¾†èˆ‡ä¹‹åˆ†äº«æ­¤é™„加元件:
+publish.remove.title=確èª
+# LOCALIZATION NOTE (publish.remove.label):
+
+# %1 is the name of an add-on. %2 is the name of a collection
+
+publish.remove.label=你確定è¦å¾žã€Œ%2$Sã€æ”¶è—集移除 %1$S?
+publish.remove.button1=å¦, å–消
+publish.remove.button0=是, 移除此附加元件
+login.error=登入時發生錯誤。請檢查您的帳號與密碼是å¦æ­£ç¢ºã€‚
+unsubscribe.error=退訂此收è—集時發生錯誤。請å†è©¦ä¸€æ¬¡ã€‚
+unsubscribe.confirm.title=退訂確èª
+unsubscribe.confirm.label=退訂此收è—集會將其從你的最愛列表中刪除。確定è¦é€€è¨‚?
+unsubscribe.confirm.button1=å¦, å–消
+unsubscribe.confirm.button0=是, 退訂此收è—集
diff --git a/bandwagon/locale/zh-TW/extensionsOverlay.dtd b/bandwagon/locale/zh-TW/extensionsOverlay.dtd
new file mode 100644
index 0000000..117cccd
--- /dev/null
+++ b/bandwagon/locale/zh-TW/extensionsOverlay.dtd
@@ -0,0 +1,26 @@
+<!-- ***** BEGIN LICENSE BLOCK ***** - Version: MPL 1.1/GPL 2.0/LGPL 2.1 - - The contents of this file are subject to the Mozilla Public License Version - 1.1 (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - http://www.mozilla.org/MPL/ - - Software distributed under the License is distributed on an "AS IS" basis, - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - for the specific language governing rights and limitations under the - License. - - The Original Code is bandwagon. - - The Initial Developer of the Original Code is - Mozilla Corporation. - Portions created by the Initial Developer are Copyright (C) 2008 - the Initial Developer. All Rights Reserved. - - Contributor(s): Brian King <brian (at) briks (dot) si> - David McNamara - - Alternatively, the contents of this file may be used under the terms of - either the GNU General Public License Version 2 or later (the "GPL"), or - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - in which case the provisions of the GPL or the LGPL are applicable instead - of those above. If you wish to allow use of your version of this file only - under the terms of either the GPL or the LGPL, and not to allow others to - use your version of this file under the terms of the MPL, indicate your - decision by deleting the provisions above and replace them with the notice - and other provisions required by the GPL or the LGPL. If you do not delete - the provisions above, a recipient may use your version of this file under - the terms of any one of the MPL, the GPL or the LGPL. - - ***** END LICENSE BLOCK ***** -->
+<!ENTITY collections.label "訂閱">
+<!ENTITY search.label.bandwagon "æœå°‹">
+<!ENTITY addon.moreinfo "更多說明">
+<!ENTITY addon.addtofirefox "增加到 Firefox">
+<!ENTITY subscribe.label "尋找更多收è—集">
+<!ENTITY reload.label "全部é‡æ–°è¼‰å…¥">
+<!ENTITY settings.label "設定">
+<!ENTITY view.label "檢視收è—集">
+<!ENTITY unsubscribe.label "退訂">
+<!ENTITY nocollectionstitle.label "歡迎來到 Add-on Collector">
+<!ENTITY nocollectionssubscribed.label "你在 Mozilla 附加元件網站標為最愛的收è—集會顯示在此,供你追蹤修改。看來你還沒é¸å®šä»»ä½•æœ€æ„›æ”¶è—集,ä¸å¦‚到我們的收è—集目錄看看å§ã€‚">
+<!ENTITY clicktosubscribe.label "尋找收è—集">
+<!ENTITY noamoauth.label "你在 Mozilla 附加元件網站標為最愛的收è—集會顯示在此,供你追蹤修改。你必需è¦ç™»å…¥ addons.mozilla.org 以使用此功能。">
+<!ENTITY username.label "E-mail 地å€">
+<!ENTITY password.label "密碼">
+<!ENTITY clicktologin.label "登入">
+<!ENTITY createaccount.label "我還沒有帳號">
+<!ENTITY loginheading.label "在此輸入你的 Mozilla 附加元件網站的帳號資訊:">
+<!ENTITY collectionisloading.label "å–得訂閱列表…">
+<!ENTITY collectionhasnoitems.label "這個收è—集沒有任何附加元件。">
+<!ENTITY collectionhaserror.label "這個收è—集因為å«æœ‰éŒ¯èª¤ï¼Œæ•…無法顯示。">
+<!ENTITY publishto.label "發表給">
+<!ENTITY email.address.label "E-mail 地å€">
+<!ENTITY new.email.address.label "æ–° E-mail 地å€">
+<!ENTITY new.collection.label "新收è—集">
diff --git a/bandwagon/locale/zh-TW/publish.dtd b/bandwagon/locale/zh-TW/publish.dtd
new file mode 100644
index 0000000..b4d1f65
--- /dev/null
+++ b/bandwagon/locale/zh-TW/publish.dtd
@@ -0,0 +1,46 @@
+<!-- ***** BEGIN LICENSE BLOCK *****
+ - Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ -
+ - The contents of this file are subject to the Mozilla Public License Version
+ - 1.1 (the "License"); you may not use this file except in compliance with
+ - the License. You may obtain a copy of the License at
+ - http://www.mozilla.org/MPL/
+ -
+ - Software distributed under the License is distributed on an "AS IS" basis,
+ - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ - for the specific language governing rights and limitations under the
+ - License.
+ -
+ - The Original Code is bandwagon.
+ -
+ - The Initial Developer of the Original Code is
+ - Mozilla Corporation.
+ - Portions created by the Initial Developer are Copyright (C) 2008
+ - the Initial Developer. All Rights Reserved.
+ -
+ - Contributor(s): David McNamara
+ - Brian King <brian (at) briks (dot) si>
+ -
+ - Alternatively, the contents of this file may be used under the terms of
+ - either the GNU General Public License Version 2 or later (the "GPL"), or
+ - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ - in which case the provisions of the GPL or the LGPL are applicable instead
+ - of those above. If you wish to allow use of your version of this file only
+ - under the terms of either the GPL or the LGPL, and not to allow others to
+ - use your version of this file under the terms of the MPL, indicate your
+ - decision by deleting the provisions above and replace them with the notice
+ - and other provisions required by the GPL or the LGPL. If you do not delete
+ - the provisions above, a recipient may use your version of this file under
+ - the terms of any one of the MPL, the GPL or the LGPL.
+ -
+ - ***** END LICENSE BLOCK *****
+ -->
+<!-- For localisers to change the width of the window -->
+<!ENTITY publish.style "width: 35em;">
+<!ENTITY window.title "發表">
+<!ENTITY cancel.label "å–消">
+<!ENTITY publish.label "發表">
+<!ENTITY new.email.label "æ–° E-mail 地å€">
+<!ENTITY enter.an.email.label "輸入一個或多個 E-mail, 使用逗點分隔:">
+<!ENTITY remember.this.email.label "記ä½é€™å€‹ E-mail 地å€">
+<!ENTITY enter.a.personal.note.label "éžå¿…è¦: 輸入å°é€™å€‹é™„加元件的個人附註,隨 E-mail 寄é€">
diff --git a/bandwagon/locale/zh-TW/publish.properties b/bandwagon/locale/zh-TW/publish.properties
new file mode 100644
index 0000000..7a764af
--- /dev/null
+++ b/bandwagon/locale/zh-TW/publish.properties
@@ -0,0 +1,30 @@
+# LOCALIZATION NOTE (you.are.sharing.the.add.on):
+
+# %S is the name of an add-on
+
+you.are.sharing.the.add.on=你已分享附加元件「%Sã€
+# LOCALIZATION NOTE (publishing.to):
+
+# %1 is the name of an add-on. %2 is the name of a collection
+
+publishing.to=點é¸ã€Œç™¼è¡¨ã€æœƒå°‡ %1$S 加入「%2$Sã€æ”¶è—集
+# LOCALIZATION NOTE (sharing.with):
+
+# %1 is a user's email address. $2 is the name of an add-on
+
+sharing.with=點é¸ã€Œå¯„é€ E-mailã€æœƒå°‡é—œæ–¼ %2$S 的資訊寄é€çµ¦ %1$S
+# LOCALIZATION NOTE (sharing.with.new):
+
+# %S is the name of an add-on
+
+sharing.with.new=點é¸ã€Œå¯„é€ E-mailã€æœƒå°‡é—œæ–¼ %S 的資訊寄é€çµ¦ä»¥ä¸Šæ”¶ä»¶äºº
+please.enter.an.email.address=請輸入 E-mail 地å€ã€‚
+the.addon.has.been.published=附加元件已發表。
+the.email.has.been.sent=E-mail 己寄出。
+# LOCALIZATION NOTE (closing.in):
+
+# %S is the number of seconds until a window closes, counting down
+
+closing.in=%S 秒後關閉…
+send.email=å‚³é€ E-mail
+error.unknown_addon_guid=此附加元件無法分享,因為該元件並沒有放在 Mozilla 附加元件網站上。
diff --git a/bandwagon/locale/zh-TW/settings.dtd b/bandwagon/locale/zh-TW/settings.dtd
new file mode 100644
index 0000000..230efa6
--- /dev/null
+++ b/bandwagon/locale/zh-TW/settings.dtd
@@ -0,0 +1,54 @@
+<!-- ***** BEGIN LICENSE BLOCK ***** - Version: MPL 1.1/GPL 2.0/LGPL 2.1 - - The contents of this file are subject to the Mozilla Public License Version - 1.1 (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - http://www.mozilla.org/MPL/ - - Software distributed under the License is distributed on an "AS IS" basis, - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - for the specific language governing rights and limitations under the - License. - - The Original Code is bandwagon. - - The Initial Developer of the Original Code is - Mozilla Corporation. - Portions created by the Initial Developer are Copyright (C) 2008 - the Initial Developer. All Rights Reserved. - - Contributor(s): Brian King <brian (at) briks (dot) si> - David McNamara - - Alternatively, the contents of this file may be used under the terms of - either the GNU General Public License Version 2 or later (the "GPL"), or - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - in which case the provisions of the GPL or the LGPL are applicable instead - of those above. If you wish to allow use of your version of this file only - under the terms of either the GPL or the LGPL, and not to allow others to - use your version of this file under the terms of the MPL, indicate your - decision by deleting the provisions above and replace them with the notice - and other provisions required by the GPL or the LGPL. If you do not delete - the provisions above, a recipient may use your version of this file under - the terms of any one of the MPL, the GPL or the LGPL. - - ***** END LICENSE BLOCK ***** -->
+<!-- For localisers to change the width of the window -->
+<!ENTITY settings.style "width: 42em;">
+<!ENTITY window.title "Add-on Collector 設定">
+<!-- Tabs -->
+<!ENTITY manage.label "訂閱管ç†">
+<!ENTITY general.label "一般設定">
+<!ENTITY pub.label "自動發表設定">
+<!-- Manage Subscriptions -->
+<!ENTITY subscriptions.header "訂閱列表:">
+<!-- Groupbox captions in Manage Subscriptions -->
+<!ENTITY frequency.label "訂閱更新頻率">
+<!ENTITY notifications.label "新附加元件通知">
+<!ENTITY perpage.label "æ¯é åˆ—出附加元件數">
+<!ENTITY default.label "使用é è¨­è¨­å®š">
+<!ENTITY custom.label "自訂:">
+<!ENTITY addonsleadin.label "æ¯é åˆ—出">
+<!ENTITY addonsperpage.label "個附加元件">
+<!ENTITY updatesingle.label "æ›´æ–°: æ¯">
+<!ENTITY minutes.label "分é˜">
+<!ENTITY hours.label "å°æ™‚">
+<!ENTITY days.label "天">
+<!ENTITY autopublish.label "自動發表你安è£çš„附加元件">
+<!ENTITY notify.label "顯示通知">
+<!ENTITY applyall.label "套用到所有訂閱">
+<!ENTITY remove.label "退訂">
+<!ENTITY on.label "é–‹å•Ÿ">
+<!ENTITY off.label "關閉">
+<!-- General -->
+<!-- Groupbox captions in General -->
+<!ENTITY subscriptions.label "é è¨­è¨‚閱設定">
+<!ENTITY data.label "資料管ç†">
+<!ENTITY updateall.label "檢查訂閱更新æ¯">
+<!ENTITY notifyglobal.label "當有新附加元件出ç¾æ™‚通知我">
+<!ENTITY clearemails.label "清除">
+<!ENTITY login.label "登入">
+<!ENTITY logout.label "登出">
+<!-- Auto-Publisher Settings -->
+<!-- Groupbox captions in Auto-Publisher Settings -->
+<!ENTITY auto.label "自動發表設定">
+<!ENTITY name.label "收è—集å稱:">
+<!ENTITY list.label "在公開收è—集目錄中列出">
+<!ENTITY autoleadin.label "自動更新是特別的收è—集,會在你在這å°é›»è…¦çš„ Firefox 上安è£èˆ‡ç§»é™¤é™„加元件時自動更新">
+<!ENTITY types.label "自動發表下列類型的附加元件:">
+<!ENTITY type.extensions.label "擴充套件">
+<!ENTITY type.themes.label "佈景主題">
+<!ENTITY type.dicts.label "字典套件">
+<!ENTITY type.langpacks.label "語言包">
+<!ENTITY createauto.label "建立自動發表">
+<!ENTITY deleteauto.label "刪除自動發表">
+<!ENTITY updateauto.label "更新自動發表">
+<!ENTITY onlypublishenabledaddons.label "åªç™¼è¡¨å·²å•Ÿç”¨çš„附加元件">
+<!ENTITY misc.label "其他">
+<!ENTITY allowincompatibleinstall.label "容許從我的訂閱中安è£ä¸ç›¸å®¹çš„附加元件">
diff --git a/bandwagon/locale/zh-TW/settings.properties b/bandwagon/locale/zh-TW/settings.properties
new file mode 100644
index 0000000..f84971b
--- /dev/null
+++ b/bandwagon/locale/zh-TW/settings.properties
@@ -0,0 +1,34 @@
+add.collection=新增訂閱
+enter.url.to.add.collection=輸入您想è¦è¨‚閱的收è—集的網å€ã€‚
+remove.collection=退訂
+# LOCALIZATION NOTE (are.you.sure.you.want.to.remove):
+
+# %S is the name of a collection
+
+are.you.sure.you.want.to.remove=退訂此收è—集會將其從您的最愛列表中移除。你確定è¦ç§»é™¤ã€Œ%Sã€ï¼Ÿ
+# LOCALIZATION NOTE (saved.emails.text):
+
+# %S is a number
+
+saved.emails.text=你已儲存 E-mail åœ°å€ %S
+# LOCALIZATION NOTE (login.status.with.email):
+
+# %S is a user's email address
+
+login.status.with.email=你已登入為 %S
+login.status=你已登入
+logout.status=你尚未登入
+# LOCALIZATION NOTE (auto.invalid.name):
+
+# %S is the name of a collection
+
+auto.invalid.name=收è—集å稱「%Sã€ç„¡æ³•ä½¿ç”¨
+auto.please.select.type=請至少é¸æ“‡ä¸€å€‹è¦ç™¼è¡¨çš„附加元件類型
+auto.create.internal.error=無法建立此收è—集(發生內部錯誤)。
+auto.create.done=你的自動發表收è—集已建立。
+auto.delete.internal.error=無法刪除此收è—集(發生內部錯誤)。
+auto.delete.done=你的自動發表收è—集已刪除。
+auto.create.description=從我安è£çš„附加元件自動產生的清單
+auto.update.confirm.message=你的新設定會立刻套用,但ä¸æœƒå½±éŸ¿åˆ°å·²ç¶“發表的附加元件。
+auto.update.internal.error=無法更新此收è—集(發生內部錯誤)。
+auto.update.done=你的自動發表收è—集已更新。
diff --git a/bandwagon/skin/extensionsOverlay.css b/bandwagon/skin/extensionsOverlay.css
new file mode 100644
index 0000000..ece7f42
--- /dev/null
+++ b/bandwagon/skin/extensionsOverlay.css
@@ -0,0 +1,276 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is bandwagon.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s): David McNamara
+ * Brian King
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#bandwagon-link-splitter {
+ border-left: 1px solid #7A8490;
+ border-right: 1px solid #FEFEFE;
+ margin-left: 0.4em;
+ margin-right: 0.4em;
+}
+
+#bandwagon-sidebar-splitter {
+ -moz-border-start: none;
+ -moz-border-end: 1px solid #404040;
+ min-width: 1px;
+ width: 1px;
+ background-image: none !important;
+}
+
+#bandwagon-collections-list {
+ margin-top: 0;
+ margin-left: 0;
+}
+
+#bandwagon-addons-list {
+ border: 2px solid;
+ border-left: 0px !important;
+ -moz-border-top-colors: ThreeDShadow ThreeDDarkShadow;
+ -moz-border-right-colors: ThreeDHighlight ThreeDLightShadow;
+ -moz-border-bottom-colors: ThreeDHighlight ThreeDLightShadow;
+ margin: 0;
+ /*overflow: auto;*/
+}
+
+#bandwagon-collection-title {
+ font-size: 150%;
+}
+
+#bandwagon-collections-notification {
+ padding-top: 0.5em;
+}
+
+#bandwagon-collection-description {
+ margin-bottom: 5px;
+}
+
+#bandwagon-collection-title,
+#bandwagon-collection-description {
+ margin-left: 10px;
+ margin-right: 10px;
+}
+
+bandwagonCollection {
+ padding-top: 6px;
+ padding-bottom: 6px;
+ -moz-padding-start: 7px;
+ -moz-padding-end: 7px;
+ min-height: 25px;
+}
+
+bandwagonCollection[view="settings"] {
+ padding-top: 0;
+ padding-bottom: 0;
+ -moz-padding-start: 0;
+ -moz-padding-end: 0;
+ min-height: 0;
+}
+
+bandwagonCollection[selected="true"] {
+ background-color: -moz-cellhighlight;
+ color: -moz-cellhighlighttext;
+}
+
+bandwagonCollection[preview="true"] label[anonid="name"] {
+ font-style: italic;
+}
+
+bandwagonCollection[type="autopublisher"] {
+ /* TODO */
+}
+
+bandwagonCollection[styleWithSeparator="true"] {
+ border-top: 2px dashed black;
+}
+
+bandwagonCollection image[anonid="star"] {
+ /* to enable star on writable images comment following */
+ display: none;
+}
+
+richlistbox:focus > bandwagonCollection[selected="true"] {
+ background-color: Highlight;
+ color: HighlightText;
+}
+
+bandwagonCollection label[anonid="unread"] {
+ background-color: blue;
+ color: white;
+ min-width: 1.7em;
+ text-align: center;
+ -moz-border-radius: 40%;
+}
+
+bandwagonCollection[view="settings"] label[anonid="unread"] {
+ display: none;
+}
+
+bandwagonAddon,
+bandwagonAddonExpanded {
+ padding-top: 6px;
+ padding-bottom: 6px;
+ -moz-padding-start: 7px;
+ -moz-padding-end: 7px;
+ min-height: 25px;
+ border-bottom: 1px dotted #C0C0C0;
+}
+
+bandwagonAddonExpanded {
+ background-color: -moz-cellhighlight;
+ color: -moz-cellhighlighttext;
+}
+
+richlistbox:focus > bandwagonAddonExpanded {
+ background-color: Highlight;
+ color: HighlightText;
+}
+
+bandwagonAddon[read="false"] {
+ background-color: #fdf2ab;
+ color: #585620;
+}
+
+bandwagonAddon .right,
+bandwagonAddonExpanded .right {
+ text-align: right;
+}
+
+bandwagonAddon .icon,
+bandwagonAddonExpanded .icon {
+ width: 32px;
+ height: 32px;
+ max-width: 32px;
+ max-height: 32px;
+ min-width: 32px;
+ min-height: 32px;
+}
+
+bandwagonAddon .name,
+bandwagonAddonExpanded .name {
+ font-size: 130%;
+}
+
+description[anonid="commentdesc"]
+{
+ font-style: italic;
+}
+
+label[anonid="dateadded"],
+label[anonid="addedby"]
+{
+ font-size: 90%;
+}
+
+bandwagonAddonExpanded .unindent {
+ margin-left: -1em;
+}
+
+bandwagonAddonExpanded .comments {
+ margin-top: 1em;
+}
+
+.addonIcon {
+ -moz-margin-end: 2px;
+ width: 32px;
+ height: 32px;
+}
+
+.addon-details {
+ margin-top: 5px;
+ margin-bottom: 5px;
+ -moz-margin-start: 6px;
+ -moz-margin-end: 0;
+}
+
+.bandwagonThumbnailContainer {
+ background: window;
+ padding: 5px;
+ border: 2px solid ActiveBorder;
+ width: 135px;
+ min-height: 104px;
+ -moz-margin-end: 5px;
+}
+
+/*
+.bandwagonAddonThrobber {
+ -moz-margin-start: 5px;
+ width: 16px;
+ height: 16px;
+ list-style-image: url("chrome://global/skin/icons/loading_16.png");
+}
+*/
+
+.publishButton,
+[anonid="addtofirefox"]
+{
+ margin-top: 0;
+ margin-bottom: 0;
+}
+
+.userfeedback
+{
+ font-size: 150%;
+ font-weight: bold;
+ margin-top: 1em;
+ margin-bottom: 1em;
+}
+
+.fs-info-panel
+{
+ margin: 20px;
+ overflow: auto;
+}
+
+.fs-info-panel-header
+{
+ margin-left: 0px;
+ font-size: larger;
+ font-weight: bold;
+}
+
+.fs-info-panel-text
+{
+ margin-left: 0px;
+}
+
+.bold-text {
+ font-weight: bold;
+}
+
+.error-text {
+ color: red;
+ width: 20em;
+}
diff --git a/bandwagon/skin/global.css b/bandwagon/skin/global.css
new file mode 100644
index 0000000..461c0cb
--- /dev/null
+++ b/bandwagon/skin/global.css
@@ -0,0 +1,41 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is bandwagon.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s): Brian King
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+.bandwagon-collections-toolbox {
+ -moz-appearance: none;
+ background-color: transparent !important;
+ border: 0px;
+}
diff --git a/bandwagon/skin/images/addon-toolbar.png b/bandwagon/skin/images/addon-toolbar.png
new file mode 100644
index 0000000..a31028a
--- /dev/null
+++ b/bandwagon/skin/images/addon-toolbar.png
Binary files differ
diff --git a/bandwagon/skin/images/addons_autoUp_sm.png b/bandwagon/skin/images/addons_autoUp_sm.png
new file mode 100644
index 0000000..0b14128
--- /dev/null
+++ b/bandwagon/skin/images/addons_autoUp_sm.png
Binary files differ
diff --git a/bandwagon/skin/images/addons_comments_sm.png b/bandwagon/skin/images/addons_comments_sm.png
new file mode 100644
index 0000000..0b3e513
--- /dev/null
+++ b/bandwagon/skin/images/addons_comments_sm.png
Binary files differ
diff --git a/bandwagon/skin/images/addons_prefs_autoUp.png b/bandwagon/skin/images/addons_prefs_autoUp.png
new file mode 100644
index 0000000..8464f44
--- /dev/null
+++ b/bandwagon/skin/images/addons_prefs_autoUp.png
Binary files differ
diff --git a/bandwagon/skin/images/addons_prefs_general.png b/bandwagon/skin/images/addons_prefs_general.png
new file mode 100644
index 0000000..bab58c8
--- /dev/null
+++ b/bandwagon/skin/images/addons_prefs_general.png
Binary files differ
diff --git a/bandwagon/skin/images/addons_prefs_logo.png b/bandwagon/skin/images/addons_prefs_logo.png
new file mode 100644
index 0000000..45124d9
--- /dev/null
+++ b/bandwagon/skin/images/addons_prefs_logo.png
Binary files differ
diff --git a/bandwagon/skin/images/error.png b/bandwagon/skin/images/error.png
new file mode 100755
index 0000000..628cf2d
--- /dev/null
+++ b/bandwagon/skin/images/error.png
Binary files differ
diff --git a/bandwagon/skin/images/gear.png b/bandwagon/skin/images/gear.png
new file mode 100644
index 0000000..735104b
--- /dev/null
+++ b/bandwagon/skin/images/gear.png
Binary files differ
diff --git a/bandwagon/skin/images/icon32.png b/bandwagon/skin/images/icon32.png
new file mode 100644
index 0000000..6525a90
--- /dev/null
+++ b/bandwagon/skin/images/icon32.png
Binary files differ
diff --git a/bandwagon/skin/images/information.png b/bandwagon/skin/images/information.png
new file mode 100755
index 0000000..12cd1ae
--- /dev/null
+++ b/bandwagon/skin/images/information.png
Binary files differ
diff --git a/bandwagon/skin/images/logo-login.png b/bandwagon/skin/images/logo-login.png
new file mode 100644
index 0000000..ba50b7b
--- /dev/null
+++ b/bandwagon/skin/images/logo-login.png
Binary files differ
diff --git a/bandwagon/skin/images/missing-thumbnail.png b/bandwagon/skin/images/missing-thumbnail.png
new file mode 100644
index 0000000..7d54b75
--- /dev/null
+++ b/bandwagon/skin/images/missing-thumbnail.png
Binary files differ
diff --git a/bandwagon/skin/images/plus.png b/bandwagon/skin/images/plus.png
new file mode 100644
index 0000000..25f66fe
--- /dev/null
+++ b/bandwagon/skin/images/plus.png
Binary files differ
diff --git a/bandwagon/skin/images/reload.png b/bandwagon/skin/images/reload.png
new file mode 100644
index 0000000..8c24c27
--- /dev/null
+++ b/bandwagon/skin/images/reload.png
Binary files differ
diff --git a/bandwagon/skin/images/spinner-small.gif b/bandwagon/skin/images/spinner-small.gif
new file mode 100644
index 0000000..5b33f7e
--- /dev/null
+++ b/bandwagon/skin/images/spinner-small.gif
Binary files differ
diff --git a/bandwagon/skin/images/spinner.gif b/bandwagon/skin/images/spinner.gif
new file mode 100644
index 0000000..3288d10
--- /dev/null
+++ b/bandwagon/skin/images/spinner.gif
Binary files differ
diff --git a/bandwagon/skin/images/star.png b/bandwagon/skin/images/star.png
new file mode 100644
index 0000000..0a34484
--- /dev/null
+++ b/bandwagon/skin/images/star.png
Binary files differ
diff --git a/bandwagon/skin/images/twisty-clsd.png b/bandwagon/skin/images/twisty-clsd.png
new file mode 100644
index 0000000..7fe7fb5
--- /dev/null
+++ b/bandwagon/skin/images/twisty-clsd.png
Binary files differ
diff --git a/bandwagon/skin/images/twisty-open.png b/bandwagon/skin/images/twisty-open.png
new file mode 100644
index 0000000..11e2c71
--- /dev/null
+++ b/bandwagon/skin/images/twisty-open.png
Binary files differ
diff --git a/bandwagon/skin/platform/linux/browserOverlay.css b/bandwagon/skin/platform/linux/browserOverlay.css
new file mode 100644
index 0000000..deff4d3
--- /dev/null
+++ b/bandwagon/skin/platform/linux/browserOverlay.css
@@ -0,0 +1,56 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is bandwagon.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s): Brian King <brian (at) briks (dot) si>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* ToolbarButton */
+#extensions-bandwagon-button {
+ list-style-image: url("chrome://bandwagon/skin/images/addon-toolbar.png");
+}
+
+.bandwagon-button {
+ -moz-image-region: rect(0px, 72px, 24px, 48px);
+}
+
+.bandwagon-button:hover {
+ -moz-image-region: rect(0px, 72px, 24px, 48px);
+}
+
+[iconsize="small"] .bandwagon-button {
+ -moz-image-region: rect(0px, 120px, 16px, 104px);
+}
+
+[iconsize="small"] .bandwagon-button:hover {
+ -moz-image-region: rect(0px, 120px, 16px, 104px);
+}
diff --git a/bandwagon/skin/platform/linux/extensionsOverlayIcons.css b/bandwagon/skin/platform/linux/extensionsOverlayIcons.css
new file mode 100644
index 0000000..7ab1f32
--- /dev/null
+++ b/bandwagon/skin/platform/linux/extensionsOverlayIcons.css
@@ -0,0 +1,72 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is bandwagon.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s): David McNamara
+ * Brian King
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+radio#bandwagon-collections-view {
+ list-style-image: url("chrome://bandwagon/skin/images/icon32.png");
+ -moz-image-region: rect(0px, 32px, 32px, 0px);
+}
+
+radio#bandwagon-collections-view:hover, radio#bandwagon-collections-view[selected="true"] {
+ -moz-image-region: rect(0px, 32px, 32px, 0px);
+}
+
+radio[noimage="true"]#bandwagon-collections-view {
+ list-style-image: none;
+ -moz-image-region: rect(0 0 0 0);
+}
+
+#bandwagon-button-subscribe {
+ list-style-image: url("chrome://bandwagon/skin/images/plus.png");
+}
+
+#bandwagon-button-update-all {
+ list-style-image: url("chrome://bandwagon/skin/images/reload.png");
+}
+
+#bandwagon-button-settings {
+ list-style-image: url("chrome://bandwagon/skin/images/gear.png");
+}
+
+.autopubimg {
+ list-style-image: url("chrome://bandwagon/skin/images/addons_autoUp_sm.png");
+ -moz-image-region: rect(0px, 64px, 16px, 48px);
+}
+
+.comment-icon {
+ list-style-image: url("chrome://bandwagon/skin/images/addons_comments_sm.png");
+ -moz-image-region: rect(0px, 64px, 16px, 48px);
+}
diff --git a/bandwagon/skin/platform/linux/settingsIcons.css b/bandwagon/skin/platform/linux/settingsIcons.css
new file mode 100644
index 0000000..d32c56a
--- /dev/null
+++ b/bandwagon/skin/platform/linux/settingsIcons.css
@@ -0,0 +1,50 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is bandwagon.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s): Brian King <brian (at) briks (dot) si>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+radio[pane=paneManage] {
+ list-style-image: url("chrome://bandwagon/skin/images/addons_prefs_logo.png");
+ -moz-image-region: rect(0px, 32px, 32px, 0px);
+}
+
+radio[pane=paneGeneral] {
+ list-style-image: url("chrome://bandwagon/skin/images/addons_prefs_general.png");
+ -moz-image-region: rect(0px, 128px, 32px, 96px);
+}
+
+radio[pane=paneAuto] {
+ list-style-image: url("chrome://bandwagon/skin/images/addons_prefs_autoUp.png");
+ -moz-image-region: rect(0px, 128px, 32px, 96px);
+}
diff --git a/bandwagon/skin/platform/mac/browserOverlay.css b/bandwagon/skin/platform/mac/browserOverlay.css
new file mode 100644
index 0000000..590dcb2
--- /dev/null
+++ b/bandwagon/skin/platform/mac/browserOverlay.css
@@ -0,0 +1,64 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is bandwagon.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s): Brian King <brian (at) briks (dot) si>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* ToolbarButton */
+#extensions-bandwagon-button {
+ list-style-image: url("chrome://bandwagon/skin/images/addon-toolbar.png");
+}
+
+.bandwagon-button {
+ -moz-image-region: rect(0px, 156px, 23px, 120px);
+}
+
+.bandwagon-button[disabled="true"] {
+ -moz-image-region: rect(23px, 156px, 46px, 120px);
+}
+
+.bandwagon-button:hover:active {
+ -moz-image-region: rect(46px, 156px, 69px, 120px);
+}
+
+[iconsize="small"] .bandwagon-button {
+ -moz-image-region: rect(0px, 156px, 23px, 120px);
+}
+
+[iconsize="small"] .bandwagon-button[disabled="true"] {
+ -moz-image-region: rect(23px, 156px, 46px, 120px);
+}
+
+[iconsize="small"] .bandwagon-button:hover:active {
+ -moz-image-region: rect(46px, 156px, 69px, 120px);
+}
diff --git a/bandwagon/skin/platform/mac/extensionsOverlayIcons.css b/bandwagon/skin/platform/mac/extensionsOverlayIcons.css
new file mode 100644
index 0000000..9885f2a
--- /dev/null
+++ b/bandwagon/skin/platform/mac/extensionsOverlayIcons.css
@@ -0,0 +1,72 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is bandwagon.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s): David McNamara
+ * Brian King
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+radio#bandwagon-collections-view {
+ list-style-image: url("chrome://bandwagon/skin/images/icon32.png");
+ -moz-image-region: rect(0px, 32px, 32px, 0px);
+}
+
+radio#bandwagon-collections-view:hover, radio#bandwagon-collections-view[selected="true"] {
+ -moz-image-region: rect(0px, 32px, 32px, 0px);
+}
+
+radio[noimage="true"]#bandwagon-collections-view {
+ list-style-image: none;
+ -moz-image-region: rect(0 0 0 0);
+}
+
+#bandwagon-button-subscribe {
+ list-style-image: url("chrome://bandwagon/skin/images/plus.png");
+}
+
+#bandwagon-button-update-all {
+ list-style-image: url("chrome://bandwagon/skin/images/reload.png");
+}
+
+#bandwagon-button-settings {
+ list-style-image: url("chrome://bandwagon/skin/images/gear.png");
+}
+
+.autopubimg {
+ list-style-image: url("chrome://bandwagon/skin/images/addons_autoUp_sm.png");
+ -moz-image-region: rect(0px, 16px, 16px, 0px);
+}
+
+.comment-icon {
+ list-style-image: url("chrome://bandwagon/skin/images/addons_comments_sm.png");
+ -moz-image-region: rect(0px, 16px, 16px, 0px);
+}
diff --git a/bandwagon/skin/platform/mac/settingsIcons.css b/bandwagon/skin/platform/mac/settingsIcons.css
new file mode 100644
index 0000000..53cf986
--- /dev/null
+++ b/bandwagon/skin/platform/mac/settingsIcons.css
@@ -0,0 +1,62 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is bandwagon.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s): Brian King <brian (at) briks (dot) si>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+radio[pane=paneManage] {
+ list-style-image: url("chrome://bandwagon/skin/images/addons_prefs_logo.png");
+ -moz-image-region: rect(0px, 32px, 32px, 0px);
+}
+
+radio[pane=paneManage]:hover:active {
+ -moz-image-region: rect(0px, 96px, 32px, 64px);
+}
+
+radio[pane=paneGeneral] {
+ list-style-image: url("chrome://bandwagon/skin/images/addons_prefs_general.png");
+ -moz-image-region: rect(0px, 32px, 32px, 0px);
+}
+
+radio[pane=paneGeneral]:hover:active {
+ -moz-image-region: rect(32px, 32px, 64px, 0px);
+}
+
+radio[pane=paneAuto] {
+ list-style-image: url("chrome://bandwagon/skin/images/addons_prefs_autoUp.png");
+ -moz-image-region: rect(0px, 32px, 32px, 0px);
+}
+
+radio[pane=paneAuto]:hover:active {
+ -moz-image-region: rect(32px, 32px, 64px, 0px);
+}
diff --git a/bandwagon/skin/platform/vista/browserOverlay.css b/bandwagon/skin/platform/vista/browserOverlay.css
new file mode 100644
index 0000000..2cc8903
--- /dev/null
+++ b/bandwagon/skin/platform/vista/browserOverlay.css
@@ -0,0 +1,56 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is bandwagon.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s): Brian King <brian (at) briks (dot) si>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* ToolbarButton */
+#extensions-bandwagon-button {
+ list-style-image: url("chrome://bandwagon/skin/images/addon-toolbar.png");
+}
+
+.bandwagon-button {
+ -moz-image-region: rect(0px, 24px, 24px, 0px);
+}
+
+.bandwagon-button:hover {
+ -moz-image-region: rect(0px, 24px, 24px, 0px);
+}
+
+[iconsize="small"] .bandwagon-button {
+ -moz-image-region: rect(0px, 88px, 16px, 72px);
+}
+
+[iconsize="small"] .bandwagon-button:hover {
+ -moz-image-region: rect(0px, 88px, 16px, 72px);
+}
diff --git a/bandwagon/skin/platform/vista/extensionsOverlayIcons.css b/bandwagon/skin/platform/vista/extensionsOverlayIcons.css
new file mode 100644
index 0000000..0be12e1
--- /dev/null
+++ b/bandwagon/skin/platform/vista/extensionsOverlayIcons.css
@@ -0,0 +1,72 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is bandwagon.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s): David McNamara
+ * Brian King
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+radio#bandwagon-collections-view {
+ list-style-image: url("chrome://bandwagon/skin/images/icon32.png");
+ -moz-image-region: rect(0px, 32px, 32px, 0px);
+}
+
+radio#bandwagon-collections-view:hover, radio#bandwagon-collections-view[selected="true"] {
+ -moz-image-region: rect(0px, 32px, 32px, 0px);
+}
+
+radio[noimage="true"]#bandwagon-collections-view {
+ list-style-image: none;
+ -moz-image-region: rect(0 0 0 0);
+}
+
+#bandwagon-button-subscribe {
+ list-style-image: url("chrome://bandwagon/skin/images/plus.png");
+}
+
+#bandwagon-button-update-all {
+ list-style-image: url("chrome://bandwagon/skin/images/reload.png");
+}
+
+#bandwagon-button-settings {
+ list-style-image: url("chrome://bandwagon/skin/images/gear.png");
+}
+
+.autopubimg {
+ list-style-image: url("chrome://bandwagon/skin/images/addons_autoUp_sm.png");
+ -moz-image-region: rect(0px, 32px, 16px, 16px);
+}
+
+.comment-icon {
+ list-style-image: url("chrome://bandwagon/skin/images/addons_comments_sm.png");
+ -moz-image-region: rect(0px, 32px, 16px, 16px);
+}
diff --git a/bandwagon/skin/platform/vista/settingsIcons.css b/bandwagon/skin/platform/vista/settingsIcons.css
new file mode 100644
index 0000000..b1dc785
--- /dev/null
+++ b/bandwagon/skin/platform/vista/settingsIcons.css
@@ -0,0 +1,58 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is bandwagon.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s): Brian King <brian (at) briks (dot) si>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+radio[pane=paneManage] {
+ list-style-image: url("chrome://bandwagon/skin/images/addons_prefs_logo.png");
+ -moz-image-region: rect(0px, 32px, 32px, 0px);
+}
+
+radio[pane=paneGeneral] {
+ list-style-image: url("chrome://bandwagon/skin/images/addons_prefs_general.png");
+ -moz-image-region: rect(0px, 64px, 32px, 32px);
+}
+
+radio[pane=paneGeneral]:hover {
+ -moz-image-region: rect(32px, 64px, 64px, 32px);
+}
+
+radio[pane=paneAuto] {
+ list-style-image: url("chrome://bandwagon/skin/images/addons_prefs_autoUp.png");
+ -moz-image-region: rect(0px, 64px, 32px, 32px);
+}
+
+radio[pane=paneAuto]:hover {
+ -moz-image-region: rect(32px, 64px, 64px, 32px);
+}
diff --git a/bandwagon/skin/platform/xp/browserOverlay.css b/bandwagon/skin/platform/xp/browserOverlay.css
new file mode 100644
index 0000000..4b66025
--- /dev/null
+++ b/bandwagon/skin/platform/xp/browserOverlay.css
@@ -0,0 +1,56 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is bandwagon.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s): Brian King <brian (at) briks (dot) si>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* ToolbarButton */
+#extensions-bandwagon-button {
+ list-style-image: url("chrome://bandwagon/skin/images/addon-toolbar.png");
+}
+
+.bandwagon-button {
+ -moz-image-region: rect(0px, 48px, 24px, 24px);
+}
+
+.bandwagon-button:hover {
+ -moz-image-region: rect(24px, 48px, 48px, 24px);
+}
+
+[iconsize="small"] .bandwagon-button {
+ -moz-image-region: rect(0px, 104px, 16px, 88px);
+}
+
+[iconsize="small"] .bandwagon-button:hover {
+ -moz-image-region: rect(16px, 104px, 32px, 88px);
+}
diff --git a/bandwagon/skin/platform/xp/extensionsOverlayIcons.css b/bandwagon/skin/platform/xp/extensionsOverlayIcons.css
new file mode 100644
index 0000000..5ab81e4
--- /dev/null
+++ b/bandwagon/skin/platform/xp/extensionsOverlayIcons.css
@@ -0,0 +1,76 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is bandwagon.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s): David McNamara
+ * Brian King
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+radio#bandwagon-collections-view {
+ list-style-image: url("chrome://bandwagon/skin/images/icon32.png");
+ -moz-image-region: rect(0px, 32px, 32px, 0px);
+}
+
+radio#bandwagon-collections-view:hover, radio#bandwagon-collections-view[selected="true"] {
+ -moz-image-region: rect(0px, 32px, 32px, 0px);
+}
+
+radio[noimage="true"]#bandwagon-collections-view {
+ list-style-image: none;
+ -moz-image-region: rect(0 0 0 0);
+}
+
+#bandwagon-button-subscribe {
+ list-style-image: url("chrome://bandwagon/skin/images/plus.png");
+}
+
+#bandwagon-button-update-all {
+ list-style-image: url("chrome://bandwagon/skin/images/reload.png");
+}
+
+#bandwagon-button-settings {
+ list-style-image: url("chrome://bandwagon/skin/images/gear.png");
+}
+
+.autopubimg {
+ list-style-image: url("chrome://bandwagon/skin/images/addons_autoUp_sm.png");
+ -moz-image-region: rect(0px, 48px, 16px, 32px);
+}
+
+.autopubimg:hover {
+ -moz-image-region: rect(16px, 48px, 32px, 32px);
+}
+
+.comment-icon {
+ list-style-image: url("chrome://bandwagon/skin/images/addons_comments_sm.png");
+ -moz-image-region: rect(0px, 48px, 16px, 32px);
+}
diff --git a/bandwagon/skin/platform/xp/settingsIcons.css b/bandwagon/skin/platform/xp/settingsIcons.css
new file mode 100644
index 0000000..0653d38
--- /dev/null
+++ b/bandwagon/skin/platform/xp/settingsIcons.css
@@ -0,0 +1,62 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is bandwagon.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s): Brian King <brian (at) briks (dot) si>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+radio[pane=paneManage] {
+ list-style-image: url("chrome://bandwagon/skin/images/addons_prefs_logo.png");
+ -moz-image-region: rect(0px, 32px, 32px, 0px);
+}
+
+radio[pane=paneManage]:hover {
+ -moz-image-region: rect(0px, 64px, 32px, 32px);
+}
+
+radio[pane=paneGeneral] {
+ list-style-image: url("chrome://bandwagon/skin/images/addons_prefs_general.png");
+ -moz-image-region: rect(0px, 96px, 32px, 64px);
+}
+
+radio[pane=paneGeneral]:hover {
+ -moz-image-region: rect(32px, 96px, 64px, 64px);
+}
+
+radio[pane=paneAuto] {
+ list-style-image: url("chrome://bandwagon/skin/images/addons_prefs_autoUp.png");
+ -moz-image-region: rect(0px, 96px, 32px, 64px);
+}
+
+radio[pane=paneAuto]:hover {
+ -moz-image-region: rect(32px, 96px, 64px, 64px);
+}
diff --git a/bandwagon/skin/publish.css b/bandwagon/skin/publish.css
new file mode 100644
index 0000000..e6ffc65
--- /dev/null
+++ b/bandwagon/skin/publish.css
@@ -0,0 +1,40 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is bandwagon.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s): David McNamara
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+.dialog-header
+{
+ font-weight: bold;
+}
diff --git a/bandwagon/skin/settings.css b/bandwagon/skin/settings.css
new file mode 100644
index 0000000..ae36c74
--- /dev/null
+++ b/bandwagon/skin/settings.css
@@ -0,0 +1,62 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is bandwagon.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s): David McNamara
+ * Brian King <brian (at) briks (dot) si>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#collections-list {
+ min-width: 10em;
+ max-width: 10em;
+}
+
+#collection-name {
+ font-weight: bold;
+ font-size: larger;
+}
+
+prefwindow description {
+ width: 30em;
+}
+
+/* No caption for this groupbox (there to fix a clipping issue), so hide the border */
+#auto-groupbox {
+ border: none;
+}
+
+/* Hack so that bottom is not cut off for auto-pub error
+ https://bugzilla.mozilla.org/show_bug.cgi?id=394793
+*/
+prefpane > .content-box {
+ overflow: -moz-hidden-unscrollable;
+}
diff --git a/bandwagon/utils/merge-to-locales.sh b/bandwagon/utils/merge-to-locales.sh
new file mode 100755
index 0000000..8f4163a
--- /dev/null
+++ b/bandwagon/utils/merge-to-locales.sh
@@ -0,0 +1,14 @@
+# This script adds new strings to a file in every locale of a certain type
+# usage: ./merge-to-locales.sh {locale file to merge into} {new strings to add}
+# example: ./merge-to-locales.sh extensionsOverlay.dtd new.txt
+
+svn_locales=(ar ca cs da de fa fr he ja pt-BR pt-PT ro sq sv-SE uk)
+bz_locales=(el-GR es-ES fy-NL id it nl pl sk vi zh-CN zh-TW)
+
+for locale in ${svn_locales[@]}
+do
+ echo "adding strings from $2 to ../locale/$locale/$1"
+ cat $2 >> "../locale/$locale/$1"
+done
+
+echo "done" \ No newline at end of file
diff --git a/bandwagon/utils/new.txt b/bandwagon/utils/new.txt
new file mode 100644
index 0000000..ca45b9b
--- /dev/null
+++ b/bandwagon/utils/new.txt
@@ -0,0 +1,4 @@
+unsubscribe.confirm.title=Confirm Unsubscribe
+unsubscribe.confirm.label=Unsubscribing from this collection will also remove it from your list of favorites. Are you sure you want to unsubscribe?
+unsubscribe.confirm.button1=No, cancel
+unsubscribe.confirm.button0=Yes, unsubscribe
diff --git a/bandwagon/utils/read-locales.sh b/bandwagon/utils/read-locales.sh
new file mode 100755
index 0000000..665cbc2
--- /dev/null
+++ b/bandwagon/utils/read-locales.sh
@@ -0,0 +1,16 @@
+svn_locales=(ar ca cs da de fa fr he ja pt-BR pt-PT ro ru sq sv-SE uk)
+bz_locales=(el-GR es-ES fy-NL id it nl pl sk vi zh-CN zh-TW)
+
+for locale in ${svn_locales[@]}
+do
+ echo "[svn] $locale:"
+ cat "../locale/$locale/bandwagon.properties"
+done
+
+for locale in ${bz_locales[@]}
+do
+ echo "[bz] $locale:"
+ cat "../locale/$locale/bandwagon.properties"
+done
+
+echo "done"
diff --git a/bin/README b/bin/README
new file mode 100644
index 0000000..b0a1bfe
--- /dev/null
+++ b/bin/README
@@ -0,0 +1,11 @@
+/**
+ * build.sh path_to_jre
+ *
+ * Optimize and concatenate JS/CSS
+ *
+ * Parameters:
+ * path_to_jre - the path to your java binary, example: ../jre1.6.0_06/bin/java (or if java is installed, `which java`)
+ *
+ * Notes:
+ * JRE can be obtained from http://www.java.com/en/download/
+ **/
diff --git a/bin/blank.png b/bin/blank.png
new file mode 100644
index 0000000..04d23fc
--- /dev/null
+++ b/bin/blank.png
Binary files differ
diff --git a/bin/build.py b/bin/build.py
new file mode 100755
index 0000000..7400d7f
--- /dev/null
+++ b/bin/build.py
@@ -0,0 +1,288 @@
+#!/usr/bin/env python
+"""Mozilla Add-ons build script
+
+If you update this script to touch a file in SVN you MUST update clean.sh
+to remove that file. On preview things are run in the following order:
+ `./clean.sh` then `svn up` then `./build.py`
+"""
+
+__license__ = """\
+***** BEGIN LICENSE BLOCK *****
+Version: MPL 1.1/GPL 2.0/LGPL 2.1
+
+The contents of this file are subject to the Mozilla Public License Version
+1.1 (the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+http://www.mozilla.org/MPL/
+
+Software distributed under the License is distributed on an "AS IS" basis,
+WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+for the specific language governing rights and limitations under the
+License.
+
+The Original Code is the addons.mozilla.org site.
+
+The Initial Developer of the Original Code is
+Frederic Wenzel <fwenzel@mozilla.com>.
+Portions created by the Initial Developer are Copyright (C) 2008
+the Initial Developer. All Rights Reserved.
+
+Contributor(s):
+ Brian Krausz <bkrausz@mozilla.com>
+
+Alternatively, the contents of this file may be used under the terms of
+either the GNU General Public License Version 2 or later (the "GPL"), or
+the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+in which case the provisions of the GPL or the LGPL are applicable instead
+of those above. If you wish to allow use of your version of this file only
+under the terms of either the GPL or the LGPL, and not to allow others to
+use your version of this file under the terms of the MPL, indicate your
+decision by deleting the provisions above and replace them with the notice
+and other provisions required by the GPL or the LGPL. If you do not delete
+the provisions above, a recipient may use your version of this file under
+the terms of any one of the MPL, the GPL or the LGPL.
+
+***** END LICENSE BLOCK *****
+"""
+
+import sys, os
+from subprocess import Popen, PIPE
+import xml.parsers.expat
+from tempfile import mkstemp
+
+MINIFY_PRODUCTS = {
+ 'js': {
+ 'js/__utm.min.js': [
+ { 'file':'js/__utm.js' }
+ ],
+ 'js/jquery.addons.min.js': [
+ { 'file':'js/jquery-compressed.js' },
+ { 'file':'js/addons.js' }
+ ],
+ 'js/amo2009/amo2009.min.js': [
+ # This list is repeated in site/app/views/layouts/amo2009.thtml
+ { 'file':'js/jquery-compressed.js' },
+ { 'file':'js/jquery.cookie.js' },
+ { 'file':'js/amo2009/global.js' },
+ { 'file':'js/amo2009/slimbox2.js' },
+ { 'file':'js/amo2009/addons.js' },
+ { 'file':'js/amo2009/global-mozilla.js' }
+ ]
+ },
+ 'css': {
+ 'css/style.min.css': [
+ { 'file':'css/type.css' },
+ { 'file':'css/color.css' },
+ { 'file':'css/screen.css', 'prefix':'@media screen, projection {', 'suffix':'}' },
+ { 'file':'css/print.css', 'prefix':'@media print {', 'suffix':'}' },
+ ],
+ 'css/amo2009/style.min.css': [
+ { 'file':'css/amo2009/main.css' },
+ { 'file':'css/amo2009/slimbox2.css' },
+ { 'file':'css/amo2009/main-mozilla.css' },
+ { 'file':'css/amo2009/legacy.css' }
+ ]
+ }
+}
+
+# contants
+REVISIONS_PHP_TEMPLATE = """\
+<?php
+define('REVISION', %d);
+define('CSS_REVISION', %d);
+define('JS_REVISION', %d);
+?>"""
+
+
+# globals
+script_dir = os.path.dirname(sys.argv[0])
+java = None # path to Java runtime
+
+
+class RevisionParser(object):
+ """XML parser to get latest SVN revision off 'svn info'"""
+ parser = None
+ __rev = 0
+
+ def __createParser(self):
+ """create XML parser object"""
+ self.__rev = 0
+ self.parser = xml.parsers.expat.ParserCreate()
+ self.parser.StartElementHandler = self.__revisionElementParser
+
+ def __revisionElementParser(self, name, attrs):
+ """Element parser, pulling latest revision out of elements passed to it by expat"""
+ if name == "commit":
+ self.__rev = attrs['revision']
+
+ def getLatestRevision(self, repo):
+ """For a given SVN repository, find the latest changed revision
+
+ returns the revision number (int), or 0 in the case of error"""
+ try:
+ self.__createParser()
+ svninfo = Popen(["svn", "info", "--xml", repo], stdout=PIPE).communicate()[0]
+ self.parser.Parse(svninfo, True)
+ return int(self.__rev)
+ except:
+ return 0
+
+ def getMaxRevision(self, repos):
+ """From a list of SVN repositories, get their maximum revision"""
+ return max([self.getLatestRevision(repo) for repo in repos])
+
+
+class Minifier(object):
+ """Concatenate and minify JS and CSS files"""
+
+ def concatFiles(self, destName=None, sourceNames=[]):
+ """concatenate some source files into a destination file
+
+ Parameters:
+ destName -- path of destination file; if None, temporary file is created
+ sourceNames -- list of: String (source file path) or Dict {prefix, file, suffix}
+ Returns: destination file path or None if no source files provided
+ """
+ if not sourceNames: return None
+ try:
+ try:
+ destinationFile = open(destName, "w")
+ except TypeError: # can't open None
+ tempfile = mkstemp()
+ destinationFile = os.fdopen(tempfile[0], "w")
+ destName = tempfile[1]
+ try:
+ for source in sourceNames:
+
+ # source expected to be either a plain string, or a
+ # dict describing filename / prefix / suffix
+ prefix = suffix = ''
+ if type(source) != dict:
+ sourceFileName = source
+ else:
+ sourceFileName = source['file']
+ if source.has_key('prefix'):
+ prefix = source['prefix']
+ if source.has_key('suffix'):
+ suffix = source['suffix']
+
+ sourceFile = open(sourceFileName)
+ try:
+ destinationFile.write(prefix)
+ destinationFile.writelines(sourceFile)
+ destinationFile.write(suffix)
+ finally:
+ sourceFile.close()
+ finally:
+ destinationFile.close()
+ return destName
+ except Exception, e:
+ try:
+ os.remove(tempfile[1])
+ except:
+ pass
+ print e
+
+ def minify(self, type, source, destination):
+ """minify a JS or CSS file
+
+ Parameters:
+ type -- either 'js' or 'css'
+ source -- path of source file
+ destination -- path of destination file
+ """
+ compressor = Popen([java, '-jar', os.path.join(script_dir, 'yuicompressor-2.3.4', 'build', 'yuicompressor-2.3.4.jar'),
+ '--type', type, source], stdout=PIPE)
+ destFile = open(destination, 'w')
+ destFile.writelines(compressor.stdout)
+ destFile.close()
+
+
+def updateRevisions():
+ """Find latest revisions for tree, CSS and JS, and write them to revisions.php"""
+ print "Updating Revisions"
+
+ rp = RevisionParser()
+
+ tree_rev = rp.getLatestRevision('https://svn.mozilla.org/addons/trunk/')
+ print "Latest Tree Revision:", tree_rev
+
+ repo = 'https://svn.mozilla.org/addons/trunk/site/app/webroot/'
+ revs = {}
+ for rev_type in ('js', 'css'):
+ files = []
+ for fn, parts in MINIFY_PRODUCTS[rev_type].iteritems():
+ for part in parts:
+ files.append((type(part) == dict) and part['file'] or part)
+ revs[rev_type] = rp.getMaxRevision([ repo + file for file in files ])
+ print "%s Revision: %s" % (rev_type, revs[rev_type])
+
+ revs_file = os.path.join(script_dir, '..', 'site', 'app', 'config', 'revisions.php')
+ try:
+ rf = open(revs_file, 'w')
+ rf.write(REVISIONS_PHP_TEMPLATE % (tree_rev, revs['css'], revs['js']))
+ rf.close()
+ except IOError, e:
+ print "Error writing revision.php file:", e
+
+
+def concatAndMinify():
+ """concatenate and minify JS and CSS files"""
+ minifier = Minifier()
+
+ webroot = os.path.join(script_dir, '..', 'site', 'app', 'webroot')
+
+ for product_type, products in MINIFY_PRODUCTS.iteritems():
+ for product_fn, product_parts in products.iteritems():
+
+ # Make the final product path absolute.
+ product_fn = os.path.join(webroot, *product_fn.split('/'))
+
+ # Make all product part file paths absolute.
+ abs_parts = []
+ for spec in product_parts:
+ spec['file'] = os.path.join(webroot, *spec['file'].split('/'))
+ abs_parts.append(spec)
+
+ # Concatenate all the product parts to a temp file.
+ print 'Concatenating %s (%s)' % (product_type, product_fn)
+ print "\n".join([" * %s" % x['file'] for x in abs_parts])
+ concat_fn = minifier.concatFiles(sourceNames=abs_parts)
+
+ # Minify the temp file for product type, dump into final
+ # product path.
+ print 'Minifying %s (%s)' % (product_type, product_fn)
+ minifier.minify(product_type, concat_fn, product_fn)
+
+ # Clean up the intermediate temp file.
+ os.remove(concat_fn)
+
+def compilePo():
+ """compile all .po files to Gettext .mo files"""
+ print 'Compiling .po Files'
+ localedir = os.path.join(script_dir, '..', 'site', 'app', 'locale')
+ Popen([os.path.join(localedir, 'compile-mo.sh'), localedir])
+
+
+def main(argv = None):
+ global java
+
+ if argv is None:
+ argv = sys.argv
+
+ try:
+ java = argv[1]
+ except IndexError:
+ java = Popen(["which", "java"], stdout=PIPE).communicate()[0].strip()
+ if not java:
+ print "Usage: %s path_to_jre" % argv[0]
+ sys.exit(1)
+
+ updateRevisions()
+ concatAndMinify()
+ compilePo()
+ print 'Done.'
+
+
+if __name__ == "__main__":
+ main()
diff --git a/bin/check_stats.php b/bin/check_stats.php
new file mode 100644
index 0000000..0243c21
--- /dev/null
+++ b/bin/check_stats.php
@@ -0,0 +1,154 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Justin Scott <fligtar@mozilla.com> (Original Author)
+ *
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/**
+ * This script checks the integrity of the add-on download and updateping counts
+ * obtained from parsing logs.
+ *
+ * The script checks a number of popular add-ons for several things:
+ * - Does the download count from 2 days ago exist?
+ * - If so, is there a difference of greater or less than 50% from the
+ * previous 2 counts?
+ * - If it's Saturday, does the update ping count from Wednesday exist?
+ * - If so, is there a difference of greater or less than 50% from the
+ * previous 2 counts?
+ *
+ * Download counter runs every night and can go into the next morning.
+ * Accounting for a potential 24 hour log delay from the CDN, this is checked
+ * 2 days after.
+ *
+ * Update ping counter is only run on Thursday nights and can go into Friday
+ * mornings. Accounting for a potential 24 hour log delay from the CDN, this
+ * will be checked on Saturdays.
+ */
+
+// Prevent running from the web
+if (isset($_SERVER['HTTP_HOST'])) {
+ exit;
+}
+
+// Include class files
+require_once('database.class.php');
+
+$db = new Database();
+
+define('DAY_SUNDAY', 0);
+define('DAY_MONDAY', 1);
+define('DAY_TUESDAY', 2);
+define('DAY_WEDNESDAY', 3);
+define('DAY_THURSDAY', 4);
+define('DAY_FRIDAY', 5);
+define('DAY_SATURDAY', 6);
+
+// Some popular add-ons to analyze
+$addons = array(
+ 1865 => 'Adblock Plus',
+ 722 => 'NoScript',
+ 201 => 'DownThemAll'
+);
+
+foreach ($addons as $addon_id => $addon_name) {
+ // DOWNLOADS
+ $date = date('Y-m-d', mktime(0, 0, 0, date('m'), date('d')-2, date('Y')));
+ // Does download count from 2 days ago exist?
+ $qry_2day = $db->read("SELECT count FROM download_counts WHERE date='{$date}' AND addon_id={$addon_id}");
+ if (mysql_num_rows($qry_2day) > 0) {
+ $count_2day = mysql_fetch_array($qry_2day);
+ output('PASS', "[Downloads] Count from 2 days ago ({$date}) exists: {$count_2day['count']}", $addon_name);
+
+ // Does that count have a 50% + or - difference from previous 2 counts?
+ $qry_last2 = $db->read("SELECT date, count FROM download_counts WHERE addon_id={$addon_id} AND date < '{$date}' ORDER BY date DESC LIMIT 2");
+ if (mysql_num_rows($qry_last2) > 0) {
+ while ($row = mysql_fetch_array($qry_last2)) {
+ $change = ceil(abs(($count_2day['count'] - $row['count']) / $row['count']) * 100);
+ if ($change >= 50) {
+ output('FAIL', "[Downloads] Count from 2 days ago changed by {$change}% from {$row['date']} count of {$row['count']}", $addon_name);
+ }
+ else {
+ output('PASS', "[Downloads] Count from 2 days ago changed by {$change}% from {$row['date']} count of {$row['count']}", $addon_name);
+ }
+ }
+ }
+ }
+ else {
+ output('FAIL', "[Downloads] Count from 2 days ago ({$date}) does not exist", $addon_name);
+ }
+
+ // UPDATE PINGS
+ if (date('w') == DAY_SATURDAY) {
+ $wed = date('Y-m-d', mktime(0, 0, 0, date('m'), date('d')-3, date('Y')));
+
+ // Does update ping count from wednesday exist?
+ $qry_wed = $db->read("SELECT count FROM update_counts WHERE date='{$wed}' AND addon_id={$addon_id}");
+ if (mysql_num_rows($qry_wed) > 0) {
+ $count_wed = mysql_fetch_array($qry_wed);
+ output('PASS', "[Update Pings] Count from Wednesday ({$wed}) exists: {$count_wed['count']}", $addon_name);
+
+ // Does that count have a 50% + or - difference from previous 2 counts?
+ $qry_last2 = $db->read("SELECT date, count FROM update_counts WHERE addon_id={$addon_id} AND date < '{$wed}' ORDER BY date DESC LIMIT 2");
+ if (mysql_num_rows($qry_last2) > 0) {
+ while ($row = mysql_fetch_array($qry_last2)) {
+ $change = ceil(abs(($count_wed['count'] - $row['count'])/ $row['count']) * 100);
+ if ($change >= 50) {
+ output('FAIL', "[Update Pings] Count from Wednesday changed by {$change}% from {$row['date']} count of {$row['count']}", $addon_name);
+ }
+ else {
+ output('PASS', "[Update Pings] Count from Wednesday changed by {$change}% from {$row['date']} count of {$row['count']}", $addon_name);
+ }
+ }
+ }
+ }
+ else {
+ output('FAIL', "[Update Pings] Count from Wednesday ({$wed}) does not exist", $addon_name);
+ }
+ }
+ else {
+ output('NOTICE', "[Update Pings] Update ping integrity not checked because today is ".date('l'), $addon_name);
+ }
+}
+
+
+function output($result, $message, $addon_name = '') {
+ echo "[{$result}]";
+ if (!empty($addon_name))
+ echo "[{$addon_name}] ";
+ echo "{$message}\n";
+}
+
+?>
diff --git a/bin/clean.sh b/bin/clean.sh
new file mode 100755
index 0000000..a1ae6b3
--- /dev/null
+++ b/bin/clean.sh
@@ -0,0 +1,26 @@
+#!/bin/bash
+
+# This file deletes modifications done by build.sh to avoid svn conflicts
+
+echo "Cleaning Build Files"
+
+cd ../site/app/
+
+rm -f config/revisions.php
+
+rm -f webroot/js/__utm.min.js
+rm -f webroot/js/jquery.addons.min.js
+
+rm -f webroot/css/style.min.css
+
+# Clean caches
+rm -rf tmp/cache/models/*
+rm -rf tmp/cache/persistent/*
+rm -rf tmp/cache/views/*
+
+# Remove all .mo files
+# Not doing this probably wouldn't cause a conflict, but better to be safe
+find locale/ -name *.mo -exec rm -f {} \;
+
+echo "Done"
+
diff --git a/bin/compatibility_report.php b/bin/compatibility_report.php
new file mode 100644
index 0000000..3b6128f
--- /dev/null
+++ b/bin/compatibility_report.php
@@ -0,0 +1,214 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Justin Scott <fligtar@mozilla.com> (Original Author)
+ *
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+// Prevent running from the web
+if (isset($_SERVER['HTTP_HOST'])) {
+ exit;
+}
+
+// Include class files
+require_once('database.class.php');
+require_once('../site/app/controllers/components/versioncompare.php');
+
+// for VersionCompare
+class Object {}
+
+$db = new Database();
+$versioncompare = new VersioncompareComponent();
+
+/**
+ * Returns the SQL where-clause to find versions (and aliases) compatible
+ * with $compatibility_version.
+ */
+function compatibleVersions($compatibility_version) {
+ global $version_aliases, $versioncompare;
+ $aliases = $versioncompare->_versionAlias($compatibility_version, $version_aliases);
+ $compat_versions = array();
+ foreach ($aliases as $alias) {
+ $compat_versions[] = "version like '{$alias}%'";
+ }
+ return implode(' OR ', $compat_versions);
+}
+
+// Get latest update pings date
+$date_qry = $db->read("SELECT date FROM update_counts ORDER BY date DESC LIMIT 1");
+$date_array = mysql_fetch_assoc($date_qry);
+$latest_date = $date_array['date'];
+
+// Get all add-ons with Firefox compatibility ordered by active users descending
+$addon_qry = $db->read("
+ SELECT
+ addons.id,
+ translations.localized_string AS name,
+ versions.version,
+ appversions.version AS maxversion,
+ update_counts.count AS updatepings,
+ IF(features.id IS NULL, '0', '1') AS featured
+ FROM update_counts
+ INNER JOIN addons ON addons.id = update_counts.addon_id
+ INNER JOIN versions ON versions.addon_id = addons.id
+ INNER JOIN applications_versions ON applications_versions.version_id = versions.id
+ INNER JOIN translations ON addons.name = translations.id
+ INNER JOIN appversions ON applications_versions.max = appversions.id
+ LEFT JOIN features ON addons.id = features.addon_id
+ WHERE
+ update_counts.date = '{$latest_date}' AND
+ applications_versions.application_id = 1 AND
+ translations.locale = 'en-US' AND
+ versions.id = (
+ SELECT id FROM versions WHERE addon_id = addons.id ORDER BY created DESC LIMIT 1
+ )
+ GROUP BY
+ addons.id
+ ORDER BY
+ update_counts.count DESC
+ ");
+
+$all_addons = array();
+// Sum all update pings to establish total active users
+while ($addon = mysql_fetch_assoc($addon_qry)) {
+ $all_addons[] = $addon;
+}
+
+// set in site/app/config/config.php
+global $compatibility_versions;
+
+// Previous version defaults to 2.0 because 3.0 is the first compat version we have available
+$previous_version = '2.0';
+
+/**
+ * iterate through each major compatibility version and make an individual
+ * report based on above general info
+ */
+foreach ($compatibility_versions as $compatibility_version) {
+ $compat_addons = array();
+ $adu_total = 0;
+ foreach ($all_addons as $addon) {
+ // Only count this add-on if it is compatible with the major/minor release before
+ if (!empty($previous_version) &&
+ $versioncompare->compareVersions($addon['maxversion'], $previous_version) < 0)
+ continue;
+
+ $compat_addons[] = $addon;
+ $adu_total += $addon['updatepings'];
+ }
+
+ $adu_top95 = floor($adu_total * .95);
+
+ $totals = array(
+ COMPAT_LATEST => array(
+ 'count' => 0,
+ 'adu' => 0
+ ),
+ COMPAT_BETA => array(
+ 'count' => 0,
+ 'adu' => 0
+ ),
+ COMPAT_ALPHA => array(
+ 'count' => 0,
+ 'adu' => 0
+ ),
+ COMPAT_OTHER => array(
+ 'count' => 0,
+ 'adu' => 0
+ )
+ );
+
+ $versions_qry = $db->read("SELECT id, version
+ FROM appversions
+ WHERE application_id = ".APP_FIREFOX." AND
+ (".compatibleVersions($compatibility_version).")
+ ORDER BY version");
+ $versions = array();
+ while ($version = mysql_fetch_assoc($versions_qry)) {
+ $versions[$version['id']] = $version['version'];
+ }
+
+ $appversions = $versioncompare->getCompatibilityGrades($compatibility_version, $versions);
+
+
+ $adu_counter = 0;
+ $addons = array();
+
+ // Iterate through each add-on
+ foreach ($compat_addons as $addon) {
+ // Only include add-ons that make up the top 95%
+ if ($adu_counter >= $adu_top95) break;
+
+ $classification = $versioncompare->gradeCompatibility($addon['maxversion'], $compatibility_version, $appversions);
+
+ $totals[$classification]['count']++;
+ $totals[$classification]['adu'] += $addon['updatepings'];
+
+ $addons[] = array(
+ 'id' => $addon['id'],
+ 'name' => $addon['name'],
+ 'maxversion' => $addon['maxversion'],
+ 'featured' => $addon['featured'],
+ 'percentage' => ($addon['updatepings'] / $adu_top95),
+ 'classification' => $classification
+ );
+
+ $adu_counter += $addon['updatepings'];
+ }
+
+ $totals['adu95'] = $adu_top95;
+ $totals['adu'] = $adu_total;
+ $totals['addons95'] = count($addons);
+ $totals['addons'] = mysql_num_rows($addon_qry);
+
+ echo "Report for Firefox {$compatibility_version}\n";
+ echo "Using data from {$latest_date}\n";
+ echo "{$totals['adu']} total active users; {$totals['adu95']} making up top 95%\n";
+ echo "{$totals['addons']} rows returned; {$totals['addons95']} addons counted\n\n";
+
+ $output = array(
+ 'addons' => $addons,
+ 'totals' => $totals,
+ 'appversions' => $appversions
+ );
+
+ print_r($output);
+
+ file_put_contents(NETAPP_STORAGE.'/compatibility-fx-'.$compatibility_version.'.serialized', serialize($output));
+
+ $previous_version = $compatibility_version;
+}
+
+?>
diff --git a/bin/database.class.php b/bin/database.class.php
new file mode 100644
index 0000000..c83e72c
--- /dev/null
+++ b/bin/database.class.php
@@ -0,0 +1,156 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Justin Scott <fligtar@mozilla.com> (Original Author)
+ * Wil Clouser <wclouser@mozilla.com>
+ *
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+// Include config file
+$root = dirname(dirname(__FILE__));
+require_once("{$root}/site/app/config/config.php");
+require_once("{$root}/site/app/config/constants.php");
+
+/**
+ * Database class for services
+ */
+class Database {
+ var $write; // Writable database
+ var $read; // Read-only database
+
+ /**
+ * Connect to databases
+ */
+ function Database($write_config=array(), $read_config=array()) {
+
+ if (empty($write_config)) {
+ $write_config = array(
+ 'host' => DB_HOST,
+ 'user' => DB_USER,
+ 'pass' => DB_PASS,
+ 'name' => DB_NAME
+ );
+ }
+
+ if (empty($read_config)) {
+ $read_config = array(
+ 'host' => SHADOW_DB_HOST,
+ 'user' => SHADOW_DB_USER,
+ 'pass' => SHADOW_DB_PASS,
+ 'name' => SHADOW_DB_NAME
+ );
+ }
+
+ $this->connectWrite($write_config['host'], $write_config['user'], $write_config['pass'], $write_config['name']);
+ $this->connectRead($read_config['host'], $read_config['user'], $read_config['pass'], $read_config['name']);
+ }
+
+ /**
+ * Connects to read-only database
+ */
+ function connectRead($host, $username, $password, $database) {
+ $this->read = mysql_connect($host, $username, $password) or die('Could not connect: '.mysql_error());
+ mysql_select_db($database, $this->read) or die("Could not select read-only database {$database}");
+ }
+
+ /**
+ * Connects to writable database
+ */
+ function connectWrite($host, $username, $password, $database) {
+ $this->write = mysql_connect($host, $username, $password) or die('Could not connect: '.mysql_error());
+ mysql_select_db($database, $this->write) or die("Could not select writable database {$database}");
+ }
+
+ /**
+ * Runs the query against the slave db, so you should only do reads here.
+ */
+ function read($q) {
+ return $this->query($q);
+ }
+
+ /**
+ * Runs the query against the master db, which is where we want our writes.
+ */
+ function write($q) {
+ return $this->query($q, true);
+ }
+
+ /**
+ * Performs query using read-only database by default
+ *
+ * @param str $qry the query to execute
+ * @param bool $useWrite whether to use the writable database
+ */
+ function query($qry, $useWrite = false) {
+ if (!$result = mysql_query($qry, ($useWrite ? $this->write : $this->read))) {
+ trigger_error('MySQL Error '.mysql_errno().': '.mysql_error()."\nQuery was: [".$qry.']', E_USER_NOTICE);
+ return false;
+ }
+
+ return $result;
+ }
+
+ /**
+ * Sets the stats_updating config value to prevent the Stats Dashboard from
+ * showing inaccurate data while a script is running.
+ */
+ function lockStats() {
+ if ($this->write("UPDATE `config` SET `value`='1' WHERE `key`='stats_updating'"))
+ return true;
+ else
+ return false;
+ }
+
+ /**
+ * Rests the stats_updating config value to make the Stats Dashboard function
+ * again
+ */
+ function unlockStats() {
+ if ($this->write("UPDATE `config` SET `value`='0' WHERE `key`='stats_updating'"))
+ return true;
+ else
+ return false;
+ }
+
+ /**
+ * Close database connections
+ */
+ function close() {
+ mysql_close($this->write);
+ mysql_close($this->read);
+ }
+}
+
+?>
diff --git a/bin/fix_ratings.php b/bin/fix_ratings.php
new file mode 100755
index 0000000..1bbb4eb
--- /dev/null
+++ b/bin/fix_ratings.php
@@ -0,0 +1,45 @@
+<?php
+ /**
+ * Run-once script to fix our rating migration problems (bug 375809).
+ * @author Wil Clouser <clouserw@gmail.com>
+ */
+ require_once '../site/app/config/config.php';
+ require_once '../site/app/config/constants.php';
+
+ $dbh = mysql_connect(DB_HOST.':'.DB_PORT,DB_USER,DB_PASS);
+
+ if (!is_resource($dbh)) {
+ die('MySQL connection to DB failed.');
+ } elseif (!@mysql_select_db(DB_NAME, $dbh)) {
+ die('Could not select database '.DB_NAME.'.');
+ }
+
+
+ // Reset all ratings to zero
+ $_query = "UPDATE addons SET averagerating=0";
+
+ if (!mysql_query($_query)) {
+ die('Failed to clear ratings: '.mysql_error());
+ }
+
+ $_query = "SELECT
+ addon_id,
+ ROUND(SUM(rating) / COUNT(version_id),2) AS averagerating
+ FROM reviews JOIN versions on versions.id = reviews.version_id
+ GROUP BY version_id;";
+
+ $res = mysql_query($_query);
+
+ if (!$res) {
+ die('Failed to retrieve new ratings: '.mysql_error());
+ }
+
+ while ($row = mysql_fetch_row($res)) {
+ // can't update many rows at the same time, so we've got a query in a loop.
+ // this is a run-once script though, so I'm not too worried.
+ if (!mysql_query("UPDATE addons SET averagerating = '{$row[1]}' WHERE id = {$row[0]}")) {
+ echo "Failing update: ".mysql_error()."\n";
+ }
+ }
+
+?>
diff --git a/bin/installck.pl b/bin/installck.pl
new file mode 100755
index 0000000..5026fb0
--- /dev/null
+++ b/bin/installck.pl
@@ -0,0 +1,80 @@
+#!/usr/bin/perl -wnT
+use LWP 5.66; #
+use File::Basename;
+use Archive::Zip qw( :ERROR_CODES :CONSTANTS );
+
+#
+# Script to check for the presence of install.js in Plugin XPIs
+# Should be run from the command line with a line like:
+#
+# ./installck file_containing_list_of_plugin_urls
+#
+# the n flag in the perl line at top of file will cause the running
+# of the script below once for each line of the supplied file.
+
+my $TMP_PREFIX = "tmp"; # prefix we prepend to XPIs when we download them
+ # should choose so we don't overwrite anything useful in current dir.
+
+my $ua = LWP::UserAgent->new;
+my $url = $_;
+my $test_failed = 0;
+chop($url);
+
+
+print "\n\nURL is: $url\n";
+
+#
+# if possible extract the name of the XPI from the currently supplied URL
+#
+if ($url =~ m/.*\/(.*.xpi)/) {
+ $fname = $TMP_PREFIX.$1; #set up tmp filename we will download to
+ print "URL format test .... [PASSED]\n";
+} else {
+ print "URL format test .... [FAILED]\n";
+ print "Remaining tests .... [SKIPPED]\n";
+ next;
+}
+
+#
+# try to download the XPI in question
+#
+my $response = $ua->get($url, ':content_file' => $fname);
+
+print "GET request status ".$response->status_line.", so test .... ";
+
+if($response->is_success) {
+ print "[PASSED]\n";
+} else {
+ print "[FAILED]\n";
+ $test_failed = 1;
+}
+
+#
+# try to read the XPI archive
+#
+my $xpi = Archive::Zip->new();
+
+if($test_failed) {
+ print "Read XPI test .... [SKIPPED]\n";
+} elsif ($xpi->read( $fname ) == AZ_OK ) {
+ print "Read XPI test .... [PASSED]\n";
+} else {
+ print "Read XPI test .... [FAILED]\n";
+ $test_failed = 1;
+}
+
+#
+# Check XPI Archive for install.js file
+#
+if($test_failed) {
+ print "Contains install.js check ... [SKIPPED]\n";
+} elsif ($xpi->memberNamed("install.js")) {
+ print "Contains install.js check .... [FILE PRESENT]\n";
+} else {
+ print "Contains install.js check .... [FILE NOT PRESENT]\n";
+}
+
+ #
+ # Clean up tmp file
+ #
+ unlink($fname); \ No newline at end of file
diff --git a/bin/load_tests.sh b/bin/load_tests.sh
new file mode 100755
index 0000000..70e0d31
--- /dev/null
+++ b/bin/load_tests.sh
@@ -0,0 +1,24 @@
+ab -t 30 -n 999999 -c 25 -v 1 "http://preview.addons.mozilla.org/" > home.out
+sleep 20
+ab -t 30 -n 999999 -c 25 -v 1 "http://preview.addons.mozilla.org/en-US/search/?q=web+developer" > search.out
+sleep 20
+ab -t 30 -n 999999 -c 25 -v 1 "http://preview.addons.mozilla.org/en-US/addons/browse/type:1/" > browse1.out
+sleep 20
+ab -t 30 -n 999999 -c 25 -v 1 "http://preview.addons.mozilla.org/en-US/addons/browse/type:4/" > browse4.out
+sleep 20
+ab -t 30 -n 999999 -c 25 -v 1 "http://preview.addons.mozilla.org/en-US/addons/browse/type:1/cat:all/" > browseall.out
+sleep 20
+ab -t 30 -n 999999 -c 25 -v 1 "http://preview.addons.mozilla.org/en-US/addons/display/60/" > display.out
+sleep 20
+ab -t 30 -n 999999 -c 25 -v 1 "http://preview.addons.mozilla.org/en-US/reviews/display/60/" > reviews.out
+sleep 20
+ab -t 30 -n 999999 -c 25 -v 1 "http://preview.addons.mozilla.org/en-US/addons/rss/newest/" > rss.out
+sleep 20
+ab -t 30 -n 999999 -c 25 -v 1 "http://preview.addons.mozilla.org/en-US/discussions/comments.php?DiscussionID=12&page=1#Item_0" > discuss1.out
+sleep 20
+ab -t 30 -n 999999 -c 25 -v 1 "http://preview.addons.mozilla.org/en-US/discussions/?AddOnID=7" > discuss2.out
+sleep 20
+ab -t 30 -n 999999 -c 25 -v 1 "http://preview-services.addons.mozilla.org/update.php?reqVersion=1&id={c45c406e-ab73-11d8-be73-000a95be3b12}&version=1.0.2&maxAppVersion=2.0.0.*&status=userEnabled&appID={ec8030f7-c20a-464f-9b0e-13a3a9e97384}&appVersion=2.0.0.2pre&appOS=Darwin&appABI=x86-gcc3" > update.out
+sleep 20
+ab -t 30 -n 999999 -c 25 -v 1 "http://preview-services.addons.mozilla.org/pfs.php?mimetype=application/x-shockwave-flash&appID={ec8030f7-c20a-464f-9b0e-13a3a9e97384}&appVersion=2007020307&clientOS=Windows%20XP&chromeLocale=en-US" > pfs.out
+sleep 20
diff --git a/bin/maintenance.php b/bin/maintenance.php
new file mode 100755
index 0000000..293249d
--- /dev/null
+++ b/bin/maintenance.php
@@ -0,0 +1,632 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Mike Morgan <morgamic@mozilla.com>
+ * Andrei Hajdukewycz <sancus@off.net>
+ * Justin Scott <fligtar@mozilla.com>
+ * Frederic Wenzel <fwenzel@mozilla.com>
+ * Les Orchard <lorchard@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/**
+ * Maintenance script for addons.mozilla.org.
+ *
+ * The purpose of this document is to perform periodic tasks that should not be
+ * done everytime a download occurs in install.php. This should reduce
+ * unnecessary DELETE and UPDATE queries and lighten the load on the database
+ * backend.
+ *
+ * This script should not ever be accessed over HTTP, and instead run via cron.
+ * Only sysadmins should be responsible for operating this script.
+ *
+ * @package amo
+ * @subpackage bin
+ */
+
+
+// Before doing anything, test to see if we are calling this from the command
+// line. If this is being called from the web, HTTP environment variables will
+// be automatically set by Apache. If these are found, exit immediately.
+if (isset($_SERVER['HTTP_HOST'])) {
+ exit;
+}
+
+require_once('database.class.php');
+
+/**
+ * If you want to change some data, use $db->write. It talks to the master db.
+ * If you're just reading, use $db->read. It talks to a slave.
+ */
+
+
+/**
+ * * Get time as a float.
+ * * @return float
+ * */
+function getmicrotime() {
+ list($usec, $sec) = explode(" ", microtime());
+ return ((float)$usec + (float)$sec);
+}
+
+// Start our timer.
+$start = getmicrotime();
+
+// New database class
+$db = new Database();
+
+// Get our action.
+$action = isset($_SERVER['argv'][1]) ? $_SERVER['argv'][1] : '';
+
+// Perform specified task. If a task is not properly defined, exit.
+switch ($action) {
+
+ /**
+ * Update weekly addon counts.
+ */
+ case 'weekly':
+ // Lock stats dashboard
+ $db->lockStats();
+
+ $seven_day_counts = array();
+
+ $addons_sql = "SELECT id FROM addons";
+ echo "Retrieving all add-on ids...\n";
+ $addons_result = $db->read($addons_sql);
+
+ $affected_rows = mysql_num_rows($addons_result);
+
+ if ($affected_rows > 0 ) {
+ while ($row = mysql_fetch_array($addons_result)) {
+ $seven_day_counts[$row['id']] = 0;
+ }
+ }
+
+ // Get 7 day counts from the download table.
+ $seven_day_count_sql = "
+ SELECT
+ download_counts.addon_id as addon_id,
+ SUM(download_counts.count) as seven_day_count
+ FROM
+ `download_counts`
+ WHERE
+ `date` >= DATE_SUB(CURDATE(), INTERVAL 7 DAY)
+ GROUP BY
+ download_counts.addon_id
+ ORDER BY
+ download_counts.addon_id
+ ";
+
+ echo 'Retrieving seven-day counts from `download_counts` ...'."\n";
+ $seven_day_count_result = $db->read($seven_day_count_sql);
+
+ $affected_rows = mysql_num_rows($seven_day_count_result);
+
+ if ($affected_rows > 0 ) {
+ while ($row = mysql_fetch_array($seven_day_count_result)) {
+ $seven_day_counts[$row['addon_id']] = ($row['seven_day_count']>0) ? $row['seven_day_count'] : 0;
+ }
+
+ echo 'Updating seven day counts in `main` ...'."\n";
+
+ foreach ($seven_day_counts as $id=>$seven_day_count) {
+ $seven_day_count_update_sql = "
+ UPDATE `addons` SET `weeklydownloads`='{$seven_day_count}' WHERE `id`='{$id}'
+ ";
+
+ $seven_day_count_update_result =
+ $db->write($seven_day_count_update_sql);
+ }
+ }
+
+ // Unlock stats dashboard
+ $db->unlockStats();
+ break;
+
+ /**
+ * Update total addon counts.
+ */
+ case 'total':
+ // Lock stats dashboard
+ $db->lockStats();
+
+ // Get total counts from the download table.
+ $total_count_sql = "
+ SELECT
+ download_counts.addon_id as addon_id,
+ SUM(download_counts.count) as total_count
+ FROM
+ `download_counts`
+ GROUP BY
+ download_counts.addon_id
+ ORDER BY
+ download_counts.addon_id
+ ";
+
+ echo 'Retrieving total counts from `download_counts` ...'."\n";
+ $total_count_result = $db->read($total_count_sql);
+
+ $affected_rows = mysql_num_rows($total_count_result);
+
+ if ($affected_rows > 0 ) {
+ $total_counts = array();
+ while ($row = mysql_fetch_array($total_count_result)) {
+ $total_counts[$row['addon_id']] = ($row['total_count'] > 0) ? $row['total_count'] : 0;
+ }
+
+ foreach ($total_counts as $id => $total_count) {
+ $total_count_update_sql = "
+ UPDATE `addons` SET `totaldownloads`='{$total_count}' WHERE `id`='{$id}'
+ ";
+
+ $total_count_update_result =
+ $db->write($total_count_update_sql);
+ }
+ }
+
+ // Unlock stats dashboard
+ $db->unlockStats();
+ break;
+
+ /**
+ * Garbage collection for all records that are older than 8 days.
+ */
+ case 'gc':
+ echo 'Starting garbage collection ...'."\n";
+ $affected_rows = 0;
+
+ /* Disabling download count clean-up for better statistics
+ echo 'Cleaning up download_counts table ...'."\n";
+ $gc_sql = "
+ DELETE FROM
+ `download_counts`
+ WHERE
+ `date` < DATE_SUB(CURDATE(), INTERVAL 31 DAY)
+ ";
+ $gc_result = mysql_query($gc_sql, $write)
+ or trigger_error('MySQL Error '.mysql_errno().': '.mysql_error()."",
+ E_USER_NOTICE);
+
+ $affected_rows = mysql_affected_rows($write);*/
+
+ echo 'Cleaning up sessions table ...'."\n";
+ $session_sql = "
+ DELETE FROM
+ `cake_sessions`
+ WHERE
+ `expires` < DATE_SUB(CURDATE(), INTERVAL 2 DAY)
+ ";
+ $session_result = $db->write($session_sql);
+
+ $affected_rows += mysql_affected_rows($db->write);
+
+ break;
+
+
+
+ /**
+ * Copy all public files to the public repository.
+ * If files already exist, overwrite them.
+ */
+ case 'publish_files':
+ echo 'Starting public file copy ...'."\n";
+
+ $files_sql = "
+ SELECT DISTINCT
+ addons.id as addon_id,
+ files.filename as filename
+ FROM
+ versions
+ INNER JOIN addons ON versions.addon_id = addons.id AND addons.status = 4 AND addons.inactive = 0
+ INNER JOIN files ON files.version_id = versions.id AND files.status = 4
+ ORDER BY
+ addons.id DESC
+ ";
+
+ // Get file names and IDs of all files to copy.
+ $files_result = $db->read($files_sql);
+
+ $affected_rows = 0;
+
+ while ($row = mysql_fetch_array($files_result)) {
+ // For each valid file, copy it from REPO_PATH to STAGING_PUBLIC_PATH.
+ if (copyFileToPublic($row['addon_id'],$row['filename'],true)) {
+ echo 'Copy SUCCEEDED for add-on '.$row['addon_id'].' file '.$row['filename']."\n";
+ } else {
+ echo 'Copy FAILED for add-on '.$row['addon_id'].' file '.$row['filename']."\n";
+ }
+ }
+
+ break;
+
+
+
+ /**
+ * Get review totals and update addons table.
+ */
+ case 'reviews':
+ echo 'Starting review total updates...'."\n";
+
+ $reviews_sql = "
+ UPDATE addons AS a
+ INNER JOIN (
+ SELECT
+ versions.addon_id as addon_id,
+ COUNT(*) as count
+ FROM reviews
+ INNER JOIN versions ON reviews.version_id = versions.id
+ WHERE reviews.reply_to IS NULL
+ AND reviews.rating > 0
+ GROUP BY versions.addon_id
+ ) AS c ON (a.id = c.addon_id)
+ SET a.totalreviews = c.count
+ ";
+ $reviews_result = $db->write($reviews_sql);
+
+ $affected_rows = mysql_affected_rows();
+
+ break;
+
+
+
+ /**
+ * Get average ratings and update addons table.
+ */
+ case 'ratings':
+ echo 'Updating average ratings...'."\n";
+ $rating_sql = "
+ UPDATE addons AS a
+ INNER JOIN (
+ SELECT
+ versions.addon_id as addon_id,
+ AVG(rating) as avg_rating
+ FROM reviews
+ INNER JOIN versions ON reviews.version_id = versions.id
+ WHERE reviews.reply_to IS NULL
+ AND reviews.rating > 0
+ GROUP BY versions.addon_id
+ ) AS c ON (a.id = c.addon_id)
+ SET a.averagerating = ROUND(c.avg_rating, 2)
+ ";
+ $rating_result = $db->write($rating_sql);
+
+ echo 'Updating bayesian ratings...'."\n";
+ // get average review count and average rating
+ $rows = $db->read("
+ SELECT AVG(a.cnt) AS avg_cnt
+ FROM (
+ SELECT COUNT(*) AS cnt
+ FROM reviews AS r
+ INNER JOIN versions AS v ON (r.version_id = v.id)
+ WHERE reply_to IS NULL
+ AND rating > 0
+ GROUP BY v.addon_id
+ ) AS a
+ ");
+ $row = mysql_fetch_array($rows);
+ $avg_num_votes = $row['avg_cnt'];
+
+ $rows = $db->read("
+ SELECT AVG(a.addon_rating) AS avg_rating
+ FROM (
+ SELECT AVG(rating) AS addon_rating
+ FROM reviews AS r
+ INNER JOIN versions AS v ON (r.version_id = v.id)
+ WHERE reply_to IS NULL
+ AND rating > 0
+ GROUP BY v.addon_id
+ ) AS a
+ ");
+ $row = mysql_fetch_array($rows);
+ $avg_rating = $row['avg_rating'];
+
+ // calculate and store bayesian rating
+ $rating_sql = "
+ UPDATE addons AS a
+ SET a.bayesianrating =
+ IF (a.totalreviews > 0, (
+ ( ({$avg_num_votes} * {$avg_rating}) + (a.totalreviews * a.averagerating) ) /
+ ({$avg_num_votes} + a.totalreviews)
+ ), 0)
+ ";
+ $rating_result = $db->write($rating_sql);
+
+ $affected_rows = mysql_affected_rows();
+
+ break;
+
+
+
+ /**
+ * Delete user accounts that have not been confirmed for two weeks
+ */
+ case 'unconfirmed':
+ echo "Removing user accounts that haven't been confirmed for two weeks...\n";
+ $unconfirmed_sql = "
+ DELETE users
+ FROM users
+ LEFT JOIN addons_users on users.id = addons_users.user_id
+ WHERE created < DATE_SUB(CURDATE(), INTERVAL 2 WEEK)
+ AND confirmationcode != ''
+ AND addons_users.user_id IS NULL
+ ";
+ $res = $db->write($unconfirmed_sql);
+
+ $affected_rows = mysql_affected_rows();
+ break;
+
+
+
+ /**
+ * Delete password reset codes that have expired.
+ */
+ case 'expired_resetcode':
+ echo "Removing reset codes that have expired...\n";
+ $db->write("UPDATE users
+ SET resetcode=DEFAULT,
+ resetcode_expires=DEFAULT
+ WHERE resetcode_expires < NOW()");
+ $affected_rows = mysql_affected_rows();
+ break;
+
+
+
+ /**
+ * Update addon-collection download totals.
+ */
+ case 'addons_collections_total':
+ echo "Starting addon_collection totals update...\n";
+ $addons_collections_total = "
+ UPDATE
+ addons_collections AS ac
+ INNER JOIN (
+ SELECT
+ stats.addon_id as addon_id,
+ stats.collection_id as collection_id,
+ SUM(stats.count) AS sum
+ FROM
+ stats_addons_collections_counts AS stats
+ GROUP BY
+ stats.addon_id, stats.collection_id
+ ) AS j ON (ac.addon_id = j.addon_id AND
+ ac.collection_id = j.collection_id)
+ SET
+ ac.downloads = j.sum
+ ";
+ $db->write($addons_collections_total);
+ $affected_rows = mysql_affected_rows();
+ break;
+
+
+
+ /**
+ * Update collection downloads total.
+ */
+ case 'collections_total':
+ echo "Starting collection totals update...\n";
+ $collections_sql = "
+ UPDATE
+ collections AS c
+ INNER JOIN (
+ SELECT
+ stats.collection_id AS collection_id,
+ SUM(stats.count) AS sum
+ FROM
+ stats_collections_counts AS stats
+ GROUP BY
+ stats.collection_id
+ ) AS j ON (c.id = j.collection_id)
+ SET
+ c.downloads = j.sum
+ ";
+ $db->write($collections_sql);
+ $affected_rows = mysql_affected_rows();
+ break;
+
+
+
+
+ /**
+ * Update tag counts for sidebar navigation
+ */
+ case 'tag_totals':
+ echo "Starting tag counts update...\n";
+ // HACK: Wish I had $valid_status from constants.php
+ $valid_status = join(',', array(1, 2, 3, 4));
+ // Modified query inspired by countAddonsInAllCategories()
+ // in site/app/models/addon.php
+ $tag_counts_sql = "
+ UPDATE
+ tags AS t
+ INNER JOIN (
+ SELECT
+ at.tag_id,
+ COUNT(DISTINCT Addon.id) AS ct
+ FROM
+ addons AS Addon
+ INNER JOIN versions AS Version
+ ON (Addon.id = Version.addon_id)
+ INNER JOIN applications_versions AS av
+ ON (av.version_id = Version.id)
+ INNER JOIN addons_tags AS at
+ ON (at.addon_id = Addon.id)
+ INNER JOIN files AS File
+ ON (Version.id = File.version_id
+ AND File.status IN ({$valid_status}))
+ WHERE
+ Addon.status IN ({$valid_status})
+ AND Addon.inactive = 0
+ GROUP BY at.tag_id
+ ) AS j ON (t.id = j.tag_id)
+ SET
+ t.count = j.ct
+ ";
+ $db->write($tag_counts_sql);
+ $affected_rows = mysql_affected_rows();
+ break;
+
+
+
+
+ /**
+ * Update global stats counters
+ */
+ case 'global_stats':
+ echo "Starting global stats update...\n";
+ $affected_rows = 0;
+ $db->write("
+ REPLACE INTO global_stats
+ (name, count, modified)
+ VALUES
+ ('addons_downloaded', (
+ SELECT SUM(count)
+ FROM download_counts
+ ), now())
+ ");
+ $affected_rows += mysql_affected_rows();
+ $db->write("
+ REPLACE INTO global_stats
+ (name, count, modified)
+ VALUES
+ ('addons_in_use', (
+ SELECT SUM(count)
+ FROM update_counts
+ WHERE date > ((SELECT MAX(date) FROM update_counts) - INTERVAL 1 DAY)
+ ), now())
+ ");
+ $affected_rows += mysql_affected_rows();
+ break;
+
+
+
+ /**
+ * Collection weekly and monthly subscriber counts
+ */
+ case 'collection_subscribers':
+ echo "Starting collection subscriber update...\n";
+ // Clear out existing data.
+ $db->write("UPDATE collections
+ SET weekly_subscribers = 0, monthly_subscribers = 0");
+ $woohoo = "
+ UPDATE collections AS c
+ INNER JOIN (
+ SELECT
+ COUNT(collection_id) AS count,
+ collection_id
+ FROM collection_subscriptions
+ WHERE created >= DATE_SUB(CURDATE(), INTERVAL 7 DAY)
+ GROUP BY collection_id
+ ) AS weekly ON (c.id = weekly.collection_id)
+ INNER JOIN (
+ SELECT
+ COUNT(collection_id) AS count,
+ collection_id
+ FROM collection_subscriptions
+ WHERE created >= DATE_SUB(CURDATE(), INTERVAL 31 DAY)
+ GROUP BY collection_id
+ ) AS monthly ON (c.id = monthly.collection_id)
+ SET c.weekly_subscribers = weekly.count,
+ c.monthly_subscribers = monthly.count
+ ";
+ $result = $db->write($woohoo);
+ $affected_rows = mysql_affected_rows();
+ break;
+
+ /**
+ * Unknown command.
+ */
+ default:
+ echo 'Command not found. Exiting ...'."\n";
+ exit;
+ break;
+}
+// End switch.
+
+
+
+// How long did it take to run?
+$exectime = getmicrotime() - $start;
+
+
+
+// Display script output.
+echo 'Affected rows: '.$affected_rows.' ';
+echo 'Time: '.$exectime."\n";
+echo 'Exiting ...'."\n";
+
+
+
+/**
+* Copy a file to the rsync location for updates
+* @param int $addon_id the add-on id
+* @param string $filename the filename
+* @param boolean $overwrite whether to overwrite the destination file
+* @return boolean
+*/
+function copyFileToPublic($addon_id, $filename, $overwrite = true) {
+ // Only copy if the path has been defined
+ if (!defined('PUBLIC_STAGING_PATH')) {
+ // return true because false indicates error
+ return false;
+ }
+
+ $currentFile = REPO_PATH."/{$addon_id}/{$filename}";
+ $newDir = PUBLIC_STAGING_PATH."/{$addon_id}";
+ $newFile = $newDir."/{$filename}";
+
+ // Make sure source file exists
+ if (!file_exists($currentFile)) {
+ return false;
+ }
+
+ // If we don't want to overwrite, make sure we don't
+ if (!$overwrite && file_exists($newFile)) {
+ // return true because this is not treated as an error
+ return false;
+ }
+
+ // Make directory if necessary
+ if (!file_exists($newDir)) {
+ if (!mkdir($newDir)) {
+ return false;
+ }
+ }
+
+ return copy($currentFile, $newFile);
+}
+
+
+
+exit;
+?>
diff --git a/bin/migration.py b/bin/migration.py
new file mode 100644
index 0000000..ab31f13
--- /dev/null
+++ b/bin/migration.py
@@ -0,0 +1,1429 @@
+#!/usr/bin/python
+
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is addons.mozilla.org site.
+#
+# The Initial Developer of the Original Code is
+# The Mozilla Foundation.
+# Portions created by the Initial Developer are Copyright (C) 2006
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+# Lars Lohn <lars@mozilla.com> (Original Author)
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+import cse.Database
+import cse.MySQLDatabase
+import cse.TabularData
+
+from Crypto.Hash import *
+
+import mx.DateTime
+import os.path
+import urllib2
+import urllib
+import Image
+
+import sys
+import os
+import traceback
+
+version = "0.7"
+
+standardError = sys.stderr
+#standardError = sys.stdout
+#sys.stderr = sys.stdout
+
+class MigrationException(Exception):
+ pass
+
+#-----------------------------------------------------------------------------------------------------------
+# imageAndThumbFromURL
+#-----------------------------------------------------------------------------------------------------------
+def imageAndThumbFromURL (aURL, xThumbSize=200, yThumbSize=150, scratchDirectory=".", transparentPngPathName="./blank.png"):
+ urlReader = urllib2.urlopen(aURL)
+ contentType = urlReader.info()['Content-Type']
+ content = urlReader.read()
+
+ temporaryFileName = ("%s/i.%s" % (scratchDirectory, aURL[-3:])).replace("//", "/")
+ temporaryThumbFileName = ("%s/t.png" % (scratchDirectory, )).replace("//", "/")
+ f = open(temporaryFileName, "w")
+ try:
+ f.write(content)
+ f.close()
+
+ im = Image.open(temporaryFileName)
+ try:
+ im.thumbnail((xThumbSize, yThumbSize), Image.ANTIALIAS)
+ targetImage = Image.open(transparentPngPathName)
+ targetImage.paste(im, ((xThumbSize - im.size[0]) / 2, (yThumbSize - im.size[1]) / 2))
+ targetImage.save(temporaryThumbFileName)
+
+ f = open(temporaryThumbFileName)
+ thumbContent = f.read()
+ f.close()
+ finally:
+ os.unlink(temporaryThumbFileName)
+ finally:
+ os.unlink(temporaryFileName)
+ return (content, contentType, thumbContent, "image/png")
+
+#-----------------------------------------------------------------------------------------------------------
+# sha1Hash
+#-----------------------------------------------------------------------------------------------------------
+def sha1Hash (aURL, addonID, cachePath):
+ basename = os.path.basename(aURL)
+ try:
+ f = open ("%s/%d/%s" % (cachePath, addonID, basename))
+ #print "getting from cache"
+ block = f.read()
+ f.close()
+ fromCache = True
+ except:
+ #print "getting from web"
+ fromCache = False
+ aURL = urllib.quote(aURL, "/:")
+ urlReader = urllib2.urlopen(aURL)
+ block = urlReader.read()
+ shaCalculator = SHA.new()
+ shaCalculator.update(block)
+ if not fromCache and cachePath:
+ try:
+ f = open("%s/%d/%s" % (cachePath, addonID, basename), "w")
+ except:
+ #print "missing directory %s/%d" % (cachePath, addonID)
+ os.mkdir("%s/%d" % (cachePath, addonID))
+ f = open("%s/%d/%s" % (cachePath, addonID, basename), "w")
+ #print "putting to cache"
+ f.write(block)
+ f.close()
+
+ return "sha1:%s" % shaCalculator.hexdigest()
+
+#-----------------------------------------------------------------------------------------------------------
+# firstWords
+#-----------------------------------------------------------------------------------------------------------
+def firstWords (originalString, maxCharacters = 250, maxSearchBack = 20):
+ """This function returns the first maxCharacters of originalString making sure that the end of the
+ string was cut on a word break and elipsis (...) was appended.
+
+ input:
+ originalString - the string
+ maxCharacters - the maximum number of characters to return
+ maxSearchBack - if no word break was found after searching back this many characters, give up and
+ return the maximum number of characters
+ """
+ try:
+ originalString = originalString.lstrip()
+ if len(originalString) <= maxCharacters:
+ maxCharacters = len(originalString)
+ breakIndex = maxCharacters - 3
+ maximumSearchBackIndex = breakIndex - maxSearchBack
+ if maximumSearchBackIndex < 0:
+ maximumSearchBackIndex = 0
+ firstLineBreak = min(originalString.find('\n'), originalString.find('\r'))
+ if -1 < firstLineBreak < breakIndex:
+ breakIndex = firstLineBreak
+ while breakIndex > maximumSearchBackIndex and not (originalString[breakIndex] == " " and originalString[breakIndex-1] != " "):
+ breakIndex -= 1
+ if breakIndex == maximumSearchBackIndex:
+ breakIndex = maxCharacters - 3
+ try:
+ if originalString[breakIndex - 1] in ".,:\"'!":
+ breakIndex -= 1
+ returnPhrase = "%s..." % originalString[:breakIndex]
+ except IndexError:
+ returnPhrase = ""
+ assert(len(returnPhrase) <= maxCharacters)
+ return returnPhrase
+ except AssertionError:
+ print "%d [[[%s]]]" % (len(originalString), originalString)
+ print "%d <<<%s>>>" % (len(returnPhrase), returnPhrase)
+ except TypeError, x:
+ print >>standardError, x
+ print >>standardError, " %s passed in as a string" % originalString
+ except Exception, x:
+ print >>standardError, x
+ traceback.print_exc(file=standardError)
+
+#-----------------------------------------------------------------------------------------------------------
+# yesNoEnumToTinyIntMappings
+#-----------------------------------------------------------------------------------------------------------
+yesNoEnumToTinyIntMappingForApproval = { "YES": 4, "NO": 1, "?":2, "DISABLED":5 }
+yesNoEnumToTinyIntMappingForHighlight = { "YES": 1, "NO": 0 }
+
+
+#-----------------------------------------------------------------------------------------------------------
+# nullToEmptyString
+#-----------------------------------------------------------------------------------------------------------
+def nullToEmptyString (aString):
+ if aString is None:
+ return ""
+ return aString
+
+#-----------------------------------------------------------------------------------------------------------
+# nullToEmptyDate
+#-----------------------------------------------------------------------------------------------------------
+def nullToEmptyDate (aDate):
+ if aDate is None:
+ return "0000-00-00 00:00:00"
+ return aDate
+
+#-----------------------------------------------------------------------------------------------------------
+# addTranslation
+#-----------------------------------------------------------------------------------------------------------
+def addTranslation (newDB, aTransalationString, aLocaleString):
+ """adds a new translation to the translations table and returns the index"""
+
+ newDB.executeSql("UPDATE translations_seq SET id=LAST_INSERT_ID(id+1)")
+ newID = newDB.singleValueSql("SELECT LAST_INSERT_ID()")
+ newDB.commit()
+ newDB.executeManySql("insert into translations (id, locale, localized_string, created) values (%s, %s, %s, %s)", [(newID, aLocaleString, aTransalationString, mx.DateTime.now())] )
+ newDB.commit()
+ return newID
+
+#-----------------------------------------------------------------------------------------------------------
+# cleanMetaDataTables
+#-----------------------------------------------------------------------------------------------------------
+def cleanMetaDataTables (newDB, workingEnvironment):
+ if "verbose" in workingEnvironment: print >>standardError, "%s\tclearing metadata tables..." % mx.DateTime.now()
+ listOfTranslationsToDelete = newDB.executeSql("""
+ select name from applications
+ union
+ select shortname from applications
+ union
+ select name from platforms
+ union
+ select shortname from platforms
+ union
+ select name from tags
+ union
+ select description from tags""").contents[1]
+ newDB.executeSql("delete from tags")
+ newDB.executeSql("delete from appversions")
+ newDB.executeSql("delete from applications")
+ newDB.executeSql("delete from platforms")
+ newDB.executeSql("delete from addons_users")
+ newDB.executeSql("delete from users")
+ newDB.executeManySql("delete from translations where id = %s", listOfTranslationsToDelete)
+ newDB.commit()
+
+ if "verbose" in workingEnvironment: print >>standardError, "\t\t\tdone."
+
+
+#-----------------------------------------------------------------------------------------------------------
+# applicationsToApplications
+#-----------------------------------------------------------------------------------------------------------
+appversionCorrection = { "Firefox": { "0.9.x":"0.9.3",
+ "1.0PR":"0.10",
+ "1.5.0.4":"1.5.0.*",
+ "1.6a1":"1.5.0.*",
+ "Deer Park":"1.0+"
+ },
+ "Thunderbird": { "1.5.0.5": "1.5.0.*",
+ "1.5beta": "1.5b",
+ "1.6a1": "1.5.0.*"
+ }
+ }
+
+appversionCorrectionForMin = { "Firefox": { ".9":"0.9",
+ "0.1":"0.10",
+ "0.80":"0.8",
+ "0.9.6":"0.10",
+ "0.9.x":"0.10",
+ "00.8":"0.8",
+ "1.0PR":"0.10",
+ "1.4.0":"1.4",
+ "1.5*":"1.5",
+ "1.5.0.*":"1.5",
+ "1.5.0.4":"1.5",
+ "1.6":"2.0a1",
+ "2.0b1":"2.0b2",
+ "Deer Park":"1.5"
+ },
+ "Flock": { "0.1":"0.1",
+ "0.4.0":"0.4"
+ },
+ "Mozilla": { "-": "1.0",
+ "1":"1.0",
+ "1.8+":"1.8"
+ },
+ "Netscape": { "8":"8.0"
+ },
+ "Nvu": { "1.0":"1.1"
+ },
+ "SeaMonkey": { "1.0":"1.1"
+ },
+ "Sunbird": { "0.3.1":"0.3a1"
+ },
+ "Thunderbird": { "1.4":"1.5",
+ "1.4.1":"1.5",
+ "1.5.0.*":"1.5",
+ "1.5.0.2":"1.5",
+ "1.5.0.4":"1.5",
+ "1.5.0.5":"1.5",
+ "1.6":"2.0"
+ }
+ }
+appversionCorrectionForMax = { "Firefox": { "0.10.1":"0.10",
+ "0.10.1+":"0.10.1",
+ "0.11":"0.10",
+ "01.6":"1.5.0.*",
+ "1.1":"1.0.8",
+ "1.5":"1.5.0.*",
+ "1.5.0.*":"1.5.0.*",
+ "1.5.0.4":"1.5.0.*",
+ "1.6":"1.5.0.*",
+ "1.6a1":"1.5.0.*",
+ "2.0":"2.0.0.*",
+ "2.0.0.*":"2.0.0.*",
+ "2.0.0.a3":"2.0a3",
+ "2.0.0.b1":"2.0b1",
+ "3.0":"3.0a1",
+ "3.0.0.a1":"3.0a1",
+ "Deer Park":"1.0+"
+ },
+ "Flock": { "0.*":"0.5.*",
+ "0.8.x":"0.8.*",
+ "10.0":"1.0",
+ "6.02":"6.0",
+ "9999.0+":"1.0+"
+ },
+ "Mozilla": { "-":"1.0",
+ "1":"1.0",
+ "1.5.0.*":"1.5",
+ },
+ "SeaMonkey": { "1.5.0.a":"1.5a"
+ },
+ "Sunbird": { "0.3.1":"0.3a1"
+ },
+ "Thunderbird": { "0.10":"0.9",
+ "0.9.0+":"0.9+",
+ "1.2":"1.1a1",
+ "1.4":"1.5b1",
+ "1.4.1":"1.5b2",
+ "1.5":"1.5.0.*",
+ "1.5.0.2":"1.5.0.*",
+ "1.5.0.4":"1.5.0.*",
+ "1.6":"1.5.0.*",
+ "1.6a1":"1.5.0.*",
+ "2.0":"2.0.0.*",
+ "3.0":"3.0a1",
+ "3.0a1":"3.0a1"
+ }
+ }
+#-----------------------------------------------------------------------------------------------------------
+# correctAppversion
+#-----------------------------------------------------------------------------------------------------------
+def correctAppversion (appName, versionName, correctionDictionary):
+ try:
+ return correctionDictionary[appName][versionName]
+ except KeyError:
+ return versionName
+
+#-----------------------------------------------------------------------------------------------------------
+# applicationsToApplications
+#-----------------------------------------------------------------------------------------------------------
+applicationsInsertSql = """
+ insert into applications (id, guid, name, shortname, supported, created)
+ values (%s, %s, %s, %s, %s, %s)"""
+appversionsInsertSql = """
+ insert into appversions (id, application_id, version, created)
+ values (%s, %s, %s, %s)"""
+def applicationsToApplications (oldDB, newDB, workingEnvironment):
+ if "verbose" in workingEnvironment: print >>standardError, "%s\tbeginning applicationsToApplications..." % mx.DateTime.now()
+ applicationsAlreadyInserted = {}
+ appversionsAlreadyInserted = {}
+ for a in oldDB.executeSqlNoCache("select * from applications"):
+ if a.AppName not in applicationsAlreadyInserted:
+ newDB.executeManySql(applicationsInsertSql, [
+ (a.AppID, #id
+ a.GUID, #guid
+ addTranslation(newDB, a.AppName, "en-US"), #name
+ addTranslation(newDB, a.AppName, "en-US"), #shortname
+ a.supported, #supported
+ mx.DateTime.now()) #created
+ ] )
+ applicationsAlreadyInserted[a.AppName] = a.AppID
+ appversionsAlreadyInserted[a.AppName] = {}
+ correctedAppversion = correctAppversion(a.AppName, a.Version, appversionCorrection)
+ if correctedAppversion not in appversionsAlreadyInserted[a.AppName]:
+ newDB.executeManySql(appversionsInsertSql, [
+ (a.AppID, #id
+ applicationsAlreadyInserted[a.AppName], #application_id
+ correctedAppversion, #version
+ mx.DateTime.now()) #created
+ ] )
+ appversionsAlreadyInserted[a.AppName][correctedAppversion] = True
+ newDB.commit()
+ if "verbose" in workingEnvironment: print >>standardError, "\t\t\tdone."
+
+
+#-----------------------------------------------------------------------------------------------------------
+# categoriesToTags
+#-----------------------------------------------------------------------------------------------------------
+tagsInsertSql = """
+ insert into tags (id, name, description, addontype_id, application_id, created)
+ values (%s, %s, %s, %s, %s, %s)"""
+typeEnumToTypeNameMapping = {'E': 'Extension',
+ 'T': 'Theme',
+ 'P': 'Plugin' }
+def categoriesToTags (oldDB, newDB, workingEnvironment):
+ if "verbose" in workingEnvironment: print >>standardError, "%s\tbeginning categoriesToTags..." % mx.DateTime.now()
+ for c in oldDB.executeSqlNoCache("select * from categories"):
+ newDB.executeManySql(tagsInsertSql, [ (c.CategoryID, #id
+ addTranslation(newDB, c.CatName, workingEnvironment["locale"]), #name
+ addTranslation(newDB, c.CatDesc, workingEnvironment["locale"]), #description
+ newDB.singleValueSql("select a.id from addontypes a join translations t on a.name = t.id and t.locale = 'en-US' and localized_string = '%s'"
+ % typeEnumToTypeNameMapping[c.CatType]), #addontype_id
+ newDB.singleValueSql("select a.id from applications a join translations t on a.name = t.id and t.locale = 'en-US' and localized_string = '%s'" % c.CatApp), #application_id
+ mx.DateTime.now()) #created
+ ] )
+ newDB.commit()
+ if "verbose" in workingEnvironment: print >>standardError, "\t\t\tdone."
+
+
+#-----------------------------------------------------------------------------------------------------------
+# osToPlatforms
+#-----------------------------------------------------------------------------------------------------------
+plaformsInsertSql = """
+ insert into platforms (id, name, shortname, created)
+ values (%s, %s, %s, %s)"""
+def osToPlatforms (oldDB, newDB, workingEnvironment):
+ if "verbose" in workingEnvironment: print >>standardError, "%s\tbeginning osToPlatforms..." % mx.DateTime.now()
+ for o in oldDB.executeSqlNoCache("select * from os"):
+ newDB.executeManySql(plaformsInsertSql, [
+ (o.OSID, #id
+ addTranslation(newDB, o.OSName, "en-US"), #name
+ addTranslation(newDB, o.OSName, "en-US"), #shortname
+ mx.DateTime.now()) #created
+ ] )
+ newDB.commit()
+ if "verbose" in workingEnvironment: print >>standardError, "\t\t\tdone."
+
+
+#-----------------------------------------------------------------------------------------------------------
+# userprofilesToUsers
+#-----------------------------------------------------------------------------------------------------------
+usersInsertSql = """
+ insert into users (id, firstname, lastname, nickname, email, homepage, password, emailhidden, confirmationcode, created, notes)
+ values (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)"""
+def userprofilesToUsers (oldDB, newDB, workingEnvironment):
+ if "verbose" in workingEnvironment: print >>standardError, "%s\tbeginning userprofilesToUsers..." % mx.DateTime.now()
+ for u in oldDB.executeSqlNoCache("select * from userprofiles"):
+ splitName = u.UserName.split()
+ try:
+ lastName = splitName[-1]
+ except:
+ lastName = "?"
+ try:
+ firstName = ' '.join(splitName[:-1])
+ except:
+ firstname = "?"
+ newDB.executeManySql(usersInsertSql, [
+ (u.UserID, #id
+ firstName, #firstname
+ lastName, #lastname
+ '', #nickname
+ u.UserEmail, #email
+ u.UserWebsite, #homepage
+ u.UserPass, #password
+ u.UserEmailHide, #emailhidden
+ u.ConfirmationCode, #confirmationcode
+ mx.DateTime.now(), #created
+ None) #notes
+ ] )
+ newDB.commit()
+ if "verbose" in workingEnvironment: print >>standardError, "\t\t\tdone."
+
+
+#-----------------------------------------------------------------------------------------------------------
+# cleanAddonsTables
+#-----------------------------------------------------------------------------------------------------------
+def cleanAddonsTables (newDB, workingEnvironment):
+ if "verbose" in workingEnvironment: print >>standardError, "%s\tclearing addons tables..." % mx.DateTime.now()
+ if "all" in workingEnvironment["addons"]:
+ listOfTranslationsToDelete = newDB.executeSql("""
+ select caption from previews
+ union
+ select releasenotes from versions
+ union
+ select name from addons
+ union
+ select homepage from addons
+ union
+ select description from addons
+ union
+ select summary from addons
+ union
+ select developercomments from addons
+ union
+ select eula from addons
+ union
+ select privacypolicy from addons
+ """).contents[1]
+ newDB.executeSql("delete from previews")
+ newDB.executeSql("delete from addons_tags")
+ newDB.executeSql("delete from applications_versions")
+ newDB.executeSql("delete from files")
+ newDB.executeSql("delete from versions")
+ newDB.executeSql("delete from addons_users")
+ newDB.executeSql("delete from addons")
+ else:
+ listOfTranslationsToDelete = newDB.executeSql("""
+ select caption from previews where addon_id in (select id from addonSelections)
+ union
+ select releasenotes from versions where addon_id in (select id from addonSelections)
+ union
+ select name from addons where id in (select id from addonSelections)
+ union
+ select homepage from addons where id in (select id from addonSelections)
+ union
+ select description from addons where id in (select id from addonSelections)
+ union
+ select summary from addons where id in (select id from addonSelections)
+ union
+ select developercomments from addons where id in (select id from addonSelections)
+ union
+ select eula from addons where id in (select id from addonSelections)
+ union
+ select privacypolicy from addons where id in (select id from addonSelections)
+ """).contents[1]
+ newDB.executeSql("delete from previews where addon_id in (select id from addonSelections)")
+ newDB.executeSql("delete from addons_tags where addon_id in (select id from addonSelections)")
+ newDB.executeSql("delete from applications_versions where version_id in (select v.id from versions v where addon_id in (select id from addonSelections))")
+ newDB.executeSql("delete from files where version_id in (select v.id from versions v where addon_id in (select id from addonSelections))")
+ newDB.executeSql("delete from versions where addon_id in (select id from addonSelections)")
+ newDB.executeSql("delete from addons_users where addon_id in (select id from addonSelections)")
+ newDB.executeSql("delete from addons where id in (select id from addonSelections)")
+
+ newDB.executeManySql("delete from translations where id = %s", listOfTranslationsToDelete)
+ newDB.commit()
+ if "verbose" in workingEnvironment: print >>standardError, "\t\t\tdone."
+
+
+#-----------------------------------------------------------------------------------------------------------
+# mainToAddOns
+#-----------------------------------------------------------------------------------------------------------
+addonsInsertSql = """
+ insert into addons (id, guid, name, addontype_id, created, homepage, description, averagerating,
+ weeklydownloads, totaldownloads, developercomments, summary,
+ eula, privacypolicy)
+ values (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)"""
+def mainToAddOns (oldDB, newDB, workingEnvironment):
+ if "verbose" in workingEnvironment: print >>standardError, "%s\tbeginning mainToAddOns..." % mx.DateTime.now()
+ if "all" in workingEnvironment["addons"]:
+ sql = "select m.* from main m"
+ else:
+ sql = "select m.* from main m where m.ID in (select id from addonSelections)"
+ currentLocale = workingEnvironment["locale"]
+ for a in oldDB.executeSqlNoCache(sql):
+ #print a.ID, sql
+ x = (a.ID, #id
+ a.GUID, #guid
+ addTranslation(newDB, a.Name, currentLocale), #name
+ newDB.singleValueSql("select a.id from addontypes a join translations t on a.name = t.id and t.locale = 'en-US' and localized_string = '%s'"
+ % typeEnumToTypeNameMapping[a.Type]), #addontype_id
+ mx.DateTime.now(), #created
+ addTranslation(newDB, a.Homepage, currentLocale), #homepage
+ addTranslation(newDB, a.Description, currentLocale), #description
+ a.Rating, #averagerating
+ a.downloadcount, #weeklydownloads
+ a.TotalDownloads, #totaldownloads
+ addTranslation(newDB, a.devcomments, currentLocale), #developercomments
+ addTranslation(newDB, firstWords(a.Description, 250), currentLocale), #summary
+ None, #eula
+ None) #privacypolicy
+ newDB.executeManySql(addonsInsertSql, [ x ] )
+ newDB.commit()
+ if "verbose" in workingEnvironment: print >>standardError, "\t\t\tdone."
+
+
+#-----------------------------------------------------------------------------------------------------------
+# authorxrefToAddons_users
+#-----------------------------------------------------------------------------------------------------------
+addons_usersInsertSql = """
+ insert into addons_users (addon_id, user_id)
+ values (%s, %s)"""
+def authorxrefToAddons_users (oldDB, newDB, workingEnvironment):
+ if "verbose" in workingEnvironment: print >>standardError, "%s\tbeginning authorxrefToAddons_users..." % mx.DateTime.now()
+ if "all" in workingEnvironment["addons"]:
+ sql = "select * from authorxref"
+ else:
+ sql = "select * from authorxref where id in (select id from addonSelections)"
+ for u in oldDB.executeSqlNoCache(sql):
+ newDB.executeManySql(addons_usersInsertSql, [ (u.ID, u.UserID) ] )
+ newDB.commit()
+ if "verbose" in workingEnvironment: print >>standardError, "\t\t\tdone."
+
+
+#-----------------------------------------------------------------------------------------------------------
+# versionToVerions
+#-----------------------------------------------------------------------------------------------------------
+versionsInsertSql = """
+ insert into versions (id, addon_id, version, releasenotes, approvalnotes, created, modified)
+ values (%s, %s, %s, %s, %s, %s, %s)"""
+applications_versionsInsertSql = """
+ insert into applications_versions (application_id, version_id, min, max)
+ values (%s, %s, %s, %s)"""
+applications_versionsUpdateSql = """
+ update applications_versions set min = %s, max = %s where application_id =%s and version_id = %s"""
+filesInsertSql = """
+ insert into files (version_id, platform_id, filename, size, hash, status, datestatuschanged, created)
+ values (%s, %s, %s, %s, %s, %s, %s, %s)"""
+filesUpdateSql = """
+ update files set size = %s, hash = %s, status = %s, datestatuschanged = %s, created = %s
+ where version_id = %s and platform_id = %s and filename = %s"""
+findAppVersionSql = """select id from appversions where application_id = %d and version = '%s'"""
+findAppNameSql = """select appname from applications where AppID = %d"""
+findNewAppIDSql = "select a.id from applications a join translations t on a.name = t.id and t.locale = 'en-US' and localized_string = '%s'"
+appversionsInsertWithNewIDSql = """
+ insert into appversions (application_id, version, created)
+ values (%s, %s, %s)"""
+addonUpdateForStatus = """update addons set status = %s where id = %s"""
+def versionToVerions (oldDB, newDB, workingEnvironment):
+ if "verbose" in workingEnvironment: print >>standardError, "%s\tbeginning versionToVerions..." % mx.DateTime.now()
+ if "all" in workingEnvironment["addons"]:
+ if "verbose" in workingEnvironment: print >>standardError, "\t\t\t(this may take over ten minutes)"
+ # for duplicates of the same Addon, Version, OS and Application, take only the latest
+ #sql = "select * from version where vID in (select max(vID) from version group by ID, Version, OSID, AppID) order by ID, vID"
+ sql = "select * from version order by ID, vID"
+ else:
+ #sql = "select * from version where id in (select id from addonSelections) and vID in (select max(vID) from version group by ID, Version, OSID, AppID) order by ID, vID"
+ sql = "select * from version where id in (select id from addonSelections) order by ID, vID"
+ versionsAlreadyInserted = {}
+ applications_versionsAlreadyInserted = {}
+ filesAlreadyInserted = {}
+ fileStatusKeyedByAddon = {}
+ for v in filterVersionsAndFilesGenerator(sql, oldDB, newDB):
+ #print v
+ try:
+ if v.ID in fileStatusKeyedByAddon:
+ fileStatusKeyedByAddon[v.ID].append(yesNoEnumToTinyIntMappingForApproval[v.approved])
+ else:
+ fileStatusKeyedByAddon[v.ID] = [yesNoEnumToTinyIntMappingForApproval[v.approved]]
+
+ if v.AppID == 79: v.AppID = 1 #hack hack hack
+ if (v.ID, v.Version) not in versionsAlreadyInserted:
+ newDB.executeManySql(versionsInsertSql, [
+ (v.vID, #id
+ v.ID, #addon_id
+ v.Version, #version
+ addTranslation(newDB, v.Notes, workingEnvironment["locale"]), #releasenotes
+ "", #approvalnotes
+ v.DateAdded, #created
+ nullToEmptyDate(v.DateUpdated)) #modified
+ ] )
+ versionId = versionsAlreadyInserted[(v.ID, v.Version)] = v.vID
+ else:
+ versionId = versionsAlreadyInserted[(v.ID, v.Version)]
+ applicationName = oldDB.singleValueSql(findAppNameSql % v.AppID)
+ #newAppId = newDB.singleValueSql(findNewAppIDSql % applicationName)
+ newAppId = v.newAppId
+
+ appversionIdForMin = newDB.singleValueSql(findAppVersionSql % (newAppId, v.MinAppVer))
+ if not appversionIdForMin:
+ translatedVersion = correctAppversion(applicationName, v.MinAppVer, appversionCorrectionForMin)
+ appversionIdForMin = newDB.singleValueSql(findAppVersionSql % (newAppId, translatedVersion))
+ if not appversionIdForMin:
+ newDB.executeManySql(appversionsInsertWithNewIDSql, [ (newAppId, translatedVersion , mx.DateTime.now()) ] )
+ appversionIdForMin = newDB.singleValueSql(findAppVersionSql % (newAppId, translatedVersion))
+
+ appversionIdForMax = newDB.singleValueSql(findAppVersionSql % (newAppId, v.MaxAppVer))
+ if not appversionIdForMax:
+ translatedVersion = correctAppversion(applicationName, v.MaxAppVer, appversionCorrectionForMax)
+ appversionIdForMax = newDB.singleValueSql(findAppVersionSql % (newAppId, translatedVersion))
+ if not appversionIdForMax:
+ newDB.executeManySql(appversionsInsertWithNewIDSql, [ (newAppId, translatedVersion, mx.DateTime.now()) ] )
+ appversionIdForMax = newDB.singleValueSql(findAppVersionSql % (newAppId, translatedVersion))
+
+ if (v.AppID, versionId) not in applications_versionsAlreadyInserted:
+ newDB.executeManySql(applications_versionsInsertSql, [ (v.AppID, versionId, appversionIdForMin, appversionIdForMax) ] )
+ applications_versionsAlreadyInserted[(v.AppID, versionId)] = (appversionIdForMin, appversionIdForMax)
+ elif applications_versionsAlreadyInserted[(v.AppID, versionId)] != (appversionIdForMin, appversionIdForMax):
+ print >>standardError, "%s\tWARNING -- version ID %d of addon %s for application %d has a min/max appversion conflict" % (mx.DateTime.now(), v.vID, v.ID, v.AppID)
+ print >>standardError, " old values: %s are superceded by new values: %s," % (applications_versionsAlreadyInserted[(v.AppID, versionId)], (appversionIdForMin, appversionIdForMax))
+ newDB.executeManySql(applications_versionsUpdateSql, [ (appversionIdForMin, appversionIdForMax, v.AppID, versionId) ] )
+ applications_versionsAlreadyInserted[(v.AppID, versionId)] = (appversionIdForMin, appversionIdForMax)
+
+ baseFileName = os.path.basename(v.URI)
+ #print "considering:", (versionId, v.OSID, baseFileName, v.AppID), v.URI
+ #if (versionId, v.OSID, baseFileName, v.AppID) not in filesAlreadyInserted:
+ if 'ignoreHash' not in workingEnvironment and ("recalculateHash" in workingEnvironment or v.hash == "" or v.hash is None):
+ try:
+ newHash = sha1Hash(v.URI, v.ID, workingEnvironment["fileCachePath"])
+ except Exception, x:
+ print >>standardError, "%s\tWARNING -- version ID %d of addon %s for application %d has a URL problem - %s: %s -- No hash value has been computed" % (mx.DateTime.now(), v.vID, v.ID, v.AppID, x, v.URI)
+ newHash = ""
+ else:
+ newHash = v.hash
+ if (versionId, v.OSID, baseFileName) not in filesAlreadyInserted:
+ newDB.executeManySql(filesInsertSql, [
+ (versionId, #version_id
+ v.OSID, #platform_id
+ baseFileName, #filename
+ v.Size, #size
+ newHash, #hash
+ yesNoEnumToTinyIntMappingForApproval[v.approved], #status
+ nullToEmptyDate(v.DateApproved), #datestatuschanged
+ mx.DateTime.now()) #created
+ ] )
+ #filesAlreadyInserted[(versionId, v.OSID, baseFileName, v.AppID)] = None
+ filesAlreadyInserted[(versionId, v.OSID, baseFileName)] = None
+ else:
+ #print >>standardError, "%s\tWARNING -- version ID %d of addon %s for application %d has a duplicate file - the later one supercedes the older one" % (mx.DateTime.now(), versionId, v.ID, v.AppID)
+ newDB.executeManySql(filesUpdateSql, [
+ (v.Size, #size
+ newHash, #hash
+ yesNoEnumToTinyIntMappingForApproval[v.approved], #status
+ nullToEmptyDate(v.DateApproved), #datestatuschanged
+ mx.DateTime.now(), #created
+ versionId, #version_id
+ v.OSID, #platform_id
+ baseFileName ) #filename
+ ] )
+ newDB.commit()
+ except KeyboardInterrupt, x:
+ raise x
+ except Exception, x:
+ print >>standardError, "%s\tWARNING -- version ID %d of addon %s for application %d fails to migrate.\n\t\t\t%s" % (mx.DateTime.now(), v.vID, v.ID, v.AppID, x)
+ traceback.print_exc(file=standardError)
+ newDB.rollback()
+
+ if "verbose" in workingEnvironment: print >>standardError, "\t\t\tupdating addon status..."
+ try:
+ for addonId, listOfFileApprovals in fileStatusKeyedByAddon.iteritems():
+ #print addonId, listOfFileApprovals,
+ if 4 in listOfFileApprovals: #if any files approved
+ newAddonStatus = workingEnvironment["addonStatusWhenSomeFilesApproved"]
+ #print "any", newAddonStatus
+ else:
+ newAddonStatus = workingEnvironment["addonStatusWhenNoFilesApproved"]
+ #print "all", newAddonStatus
+ newDB.executeManySql (addonUpdateForStatus, [(newAddonStatus, addonId)])
+ except Exception, x:
+ newDB.rollback()
+ raise x
+ newDB.commit()
+
+ if "verbose" in workingEnvironment: print >>standardError, "\t\t\tdone."
+
+def onlyFirefoxUnlessThereIsNoFirefox (versionFileListForOneVersion):
+
+ differentFilesFound = False
+ try:
+ initialURI = versionFileListForOneVersion[0].URI
+ except IndexError:
+ return
+ for x in versionFileListForOneVersion:
+ differentFilesFound = initialURI != x.URI
+ if differentFilesFound: break
+
+ if differentFilesFound:
+ firefoxFound = False
+ for aVersionFile in versionFileListForOneVersion:
+ if aVersionFile.AppID == 1: #Firefox
+ #print "FF only", aVersionFile
+ #if len(versionFileListForOneVersion) > 1:
+ # print aVersionFile.ID, aVersionFile.Version
+ yield aVersionFile
+ firefoxFound = True
+ if not firefoxFound:
+ for aVersionFile in versionFileListForOneVersion:
+ #print "NO FF", aVersionFile
+ yield aVersionFile
+ else:
+ for aVersionFile in versionFileListForOneVersion:
+ #print "NO FF", aVersionFile
+ yield aVersionFile
+
+def filterVersionsAndFilesGenerator (sqlToFetchVersionFiles, oldDB, newDB):
+ previousVersion = None
+ currentVersion = None
+ versionFileList = []
+ for aVersionFileRow in oldDB.executeSqlNoCache(sqlToFetchVersionFiles):
+ applicationName = oldDB.singleValueSql(findAppNameSql % aVersionFileRow.AppID)
+ newAppId = newDB.singleValueSql(findNewAppIDSql % applicationName)
+ aVersionFileRow.__dict__["newAppId"] = newAppId
+ currentVersion = (aVersionFileRow.ID, aVersionFileRow.Version, aVersionFileRow.OSID)
+ if previousVersion != currentVersion:
+ for x in onlyFirefoxUnlessThereIsNoFirefox(versionFileList):
+ yield x
+ previousVersion = currentVersion
+ versionFileList = []
+ versionFileList.append(aVersionFileRow)
+ for x in onlyFirefoxUnlessThereIsNoFirefox(versionFileList):
+ yield x
+
+#-----------------------------------------------------------------------------------------------------------
+# categoryxrefToAddons_tags
+#-----------------------------------------------------------------------------------------------------------
+addons_tagsInsertSql = """
+ insert into addons_tags (addon_id, tag_id)
+ values (%s, %s)"""
+def categoryxrefToAddons_tags (oldDB, newDB, workingEnvironment):
+ if "verbose" in workingEnvironment: print >>standardError, "%s\tbeginning categoryxrefToAddons_tags..." % mx.DateTime.now()
+ if "all" in workingEnvironment["addons"]:
+ sql = "select * from categoryxref"
+ else:
+ sql = "select * from categoryxref where id in (select id from addonSelections)"
+ for c in oldDB.executeSqlNoCache(sql):
+ #print c.ID, c.CategoryID
+ try:
+ newDB.executeManySql(addons_tagsInsertSql, [ (c.ID, c.CategoryID) ] )
+ except:
+ pass
+ newDB.commit()
+ if "verbose" in workingEnvironment: print >>standardError, "\t\t\tdone."
+
+
+#-----------------------------------------------------------------------------------------------------------
+# previewsToPreviews
+#-----------------------------------------------------------------------------------------------------------
+previewsInsertSql = """
+ insert into previews (id, addon_id, filedata, filetype, thumbdata, thumbtype, caption, highlight, created)
+ values (%s, %s, %s, %s, %s, %s, %s, %s, %s)"""
+def previewsToPreviews (oldDB, newDB, workingEnvironment):
+ if "verbose" in workingEnvironment: print >>standardError, "%s\tbeginning previewsToPreviews..." % mx.DateTime.now()
+ if "all" in workingEnvironment["addons"]:
+ sql = "select * from previews"
+ else:
+ sql = "select * from previews where id in (select id from addonSelections)"
+ for p in oldDB.executeSqlNoCache(sql):
+ contentType = thumbType = ""
+ content = thumbContent = None
+ if 'noPreviewImageProcessing' not in workingEnvironment:
+ try:
+ content, contentType, thumbContent, thumbType = imageAndThumbFromURL("%s%s" % (workingEnvironment["previewURIPrefix"], p.PreviewURI))
+ except Exception, x:
+ print >>standardError, "%s\tWARNING -- Error downloading %s%s for addon_id %d, preview.id %s - %s" % (mx.DateTime.now(), workingEnvironment["previewURIPrefix"], p.PreviewURI, p.ID, p.PreviewID, x)
+
+ newDB.executeManySql(previewsInsertSql, [
+ (p.PreviewID, #id
+ p.ID, #addon_id
+ content, #filedata
+ contentType, #filetype
+ thumbContent, #thumbdata
+ thumbType, #thumbtype
+ addTranslation(newDB, p.caption, workingEnvironment["locale"]), #caption
+ yesNoEnumToTinyIntMappingForHighlight[p.preview], #caption
+ mx.DateTime.now()) #created
+ ] )
+ newDB.commit()
+ if "verbose" in workingEnvironment: print >>standardError, "\t\t\tdone."
+
+
+#-----------------------------------------------------------------------------------------------------------
+# setupAddonSelectionTable
+#-----------------------------------------------------------------------------------------------------------
+def setupAddonSelectionTable(oldDB, newDB, workingEnvironment):
+ if "all" in workingEnvironment["addons"]: return
+
+ if "verbose" in workingEnvironment: print >>standardError, "%s\tbeginning setupAddonSelectionTable..." % mx.DateTime.now()
+
+ cleanupAddonSelectionTable(oldDB, newDB, workingEnvironment)
+ oldDB.executeSql("create table addonSelections (id int, primary key (id))")
+ newDB.executeSql("create table addonSelections (id int, primary key (id))")
+
+ try:
+ listOfAddons = [x.strip() for x in workingEnvironment["addons"].split(",")]
+ if "not" in workingEnvironment:
+ for anAddon in oldDB.executeSqlNoCache("select ID from main"):
+ if str(anAddon.ID) not in listOfAddons:
+ oldDB.executeSql("insert into addonSelections (id) values (%d)" % anAddon.ID)
+ newDB.executeSql("insert into addonSelections (id) values (%d)" % anAddon.ID)
+ else:
+ oldDB.executeManySql("insert into addonSelections (id) values (%s)", listOfAddons)
+ newDB.executeManySql("insert into addonSelections (id) values (%s)", listOfAddons)
+ except Exception, x:
+ cleanupAddonSelectionTable(oldDB, newDB, workingEnvironment)
+ raise x
+
+ if "verbose" in workingEnvironment: print >>standardError, "\t\t\tdone."
+
+
+#-----------------------------------------------------------------------------------------------------------
+# cleanupAddonSelectionTable
+#-----------------------------------------------------------------------------------------------------------
+def cleanupAddonSelectionTable (oldDB, newDB, workingEnvironment):
+ if "all" in workingEnvironment["addons"]: return
+ oldDB.executeSql("drop table if exists addonSelections")
+ newDB.executeSql("drop table if exists addonSelections")
+
+
+#-----------------------------------------------------------------------------------------------------------
+# cleanMetaDataTables_test
+#-----------------------------------------------------------------------------------------------------------
+def cleanMetaDataTables_test(newDB, workingEnvironment):
+ print >>standardError, "cleanMetaDataTables_test"
+ errorCount = 0
+ try:
+ cleanAddonsTables(newDB, workingEnvironment)
+ cleanMetaDataTables(newDB, workingEnvironment)
+ except Exception, x:
+ print >>standardError, " ***Failure*** cleanMetaDataTables: %s" % x
+ errorCount += 1
+ try:
+ if newDB.singleValueSql("select count(*) from tags") != 0:
+ print >>standardError, " ***Failure*** cleanMetaDataTables: tags table not cleared"
+ errorCount += 1
+ if newDB.singleValueSql("select count(*) from appversions") != 0:
+ print >>standardError, " ***Failure*** cleanMetaDataTables: appversions table not cleared"
+ errorCount += 1
+ if newDB.singleValueSql("select count(*) from applications") != 0:
+ print >>standardError, " ***Failure*** cleanMetaDataTables: applications table not cleared"
+ errorCount += 1
+ if newDB.singleValueSql("select count(*) from platforms") != 0:
+ print >>standardError, " ***Failure*** cleanMetaDataTables: platforms table not cleared"
+ errorCount += 1
+ if newDB.singleValueSql("select count(*) from addons_users") != 0:
+ print >>standardError, " ***Failure*** cleanMetaDataTables: addons_users table not cleared"
+ errorCount += 1
+ if newDB.singleValueSql("select count(*) from users") != 0:
+ print >>standardError, " ***Failure*** cleanMetaDataTables: users table not cleared"
+ errorCount += 1
+ #if newDB.singleValueSql("select count(*) from addontypes") != 2:
+ # print >>standardError, " ***Failure*** cleanMetaDataTables: addontypes not initialized properly"
+ # errorCount += 1
+ except Exception, x:
+ print >>standardError, " ***Failure*** cleanMetaDataTables: Testing system failure: %s" % x
+ print >>standardError, " %d errors" % errorCount
+
+
+#-----------------------------------------------------------------------------------------------------------
+# applicationsToApplications_test
+#-----------------------------------------------------------------------------------------------------------
+def applicationsToApplications_test(oldDB, newDB, workingEnvironment):
+ print >>standardError, "applicationsToApplications_test"
+ errorCount = 0
+ try:
+ cleanMetaDataTables(newDB, workingEnvironment)
+ applicationsToApplications(oldDB, newDB, workingEnvironment)
+ except Exception, x:
+ print >>standardError, " ***Failure*** applicationsToApplications: %s" % x
+ errorCount += 1
+ try:
+ for anApplication in oldDB.executeSqlNoCache("select distinct AppName from applications"):
+ if newDB.singleValueSql("select count(*) from applications a join translations t on a.name = t.id and t.locale = 'en-US' where t.localized_string = '%s'" % anApplication.AppName) != 1:
+ print >>standardError, " ***Failure*** applicationsToApplications: %s not in new database" % anApplication.AppName
+ errorCount += 1
+ for anApplication in oldDB.executeSqlNoCache("select * from applications"):
+ sql = """
+ select
+ count(*)
+ from
+ applications a join appversions av on a.id = av.application_id
+ where av.id = %d""" % anApplication.AppID
+ result = newDB.executeSql(sql)
+ if len(result.content) == 0:
+ print >>standardError, " ***Failure*** applicationsToApplications: %s - %s %s not in new database" % (anApplication.AppID, anApplication.AppName, anApplication.Version)
+ errorCount += 1
+ if len(result.content) > 1:
+ print >>standardError, " ***Failure*** applicationsToApplications: %s - %s %s duplicated in new database" % (anApplication.AppID, anApplication.AppName, anApplication.Version)
+ errorCount += 1
+ except Exception, x:
+ print >>standardError, " ***Failure*** applicationsToApplications: Testing system failure: %s" % x
+ print >>standardError, " %d errors" % errorCount
+
+
+#-----------------------------------------------------------------------------------------------------------
+# categoriesToTags_test
+#-----------------------------------------------------------------------------------------------------------
+def categoriesToTags_test(oldDB, newDB, workingEnvironment):
+ print >>standardError, "categoriesToTags_test"
+ errorCount = 0
+ try:
+ cleanMetaDataTables(newDB, workingEnvironment)
+ applicationsToApplications(oldDB, newDB, workingEnvironment)
+ categoriesToTags(oldDB, newDB, workingEnvironment)
+ except Exception, x:
+ print >>standardError, " ***Failure*** categoriesToTags: %s" % x
+ errorCount += 1
+ try:
+ for x in zip(oldDB.executeSql("select * from categories order by CategoryID"),
+ newDB.executeSql("select * from tags order by id")):
+ if (x[0].CategoryID != x[1].id):
+ print >>standardError, " ***Failure*** categoriesToTags: %s - %s missing in new database" % (x[0].CategoryID, x[0].CatName)
+ errorCount += 1
+ break
+ except Exception, x:
+ print >>standardError, " ***Failure*** categoriesToTags: Testing system failure: %s" % x
+ print >>standardError, " %d errors" % errorCount
+
+
+#-----------------------------------------------------------------------------------------------------------
+# osToPlatforms_test
+#-----------------------------------------------------------------------------------------------------------
+def osToPlatforms_test(oldDB, newDB, workingEnvironment):
+ print >>standardError, "osToPlatforms_test"
+ errorCount = 0
+ try:
+ cleanMetaDataTables(newDB, workingEnvironment)
+ osToPlatforms(oldDB, newDB, workingEnvironment)
+ except Exception, x:
+ print >>standardError, " ***Failure*** osToPlatforms: %s" % x
+ errorCount += 1
+ try:
+ for x in zip(oldDB.executeSql("select * from os order by OSID"),
+ newDB.executeSql("select * from platforms order by id")):
+ if (x[0].OSID != x[1].id):
+ print >>standardError, " ***Failure*** osToPlatforms: %s - %s missing in new database" % (x[0].OSID, x[0].OSName)
+ errorCount += 1
+ break
+ except Exception, x:
+ print >>standardError, " ***Failure*** osToPlatforms: Testing system failure: %s" % x
+ print >>standardError, " %d errors" % errorCount
+
+
+#-----------------------------------------------------------------------------------------------------------
+# userprofilesToUsers_test
+#-----------------------------------------------------------------------------------------------------------
+def userprofilesToUsers_test(oldDB, newDB, workingEnvironment):
+ print >>standardError, "userprofilesToUsers_test"
+ errorCount = 0
+ try:
+ cleanMetaDataTables(newDB, workingEnvironment)
+ userprofilesToUsers(oldDB, newDB, workingEnvironment)
+ except Exception, x:
+ print >>standardError, " ***Failure*** userprofilesToUsers: %s" % x
+ errorCount += 1
+ try:
+ for x in zip(oldDB.executeSql("select * from userprofiles order by UserID"),
+ newDB.executeSql("select * from users order by id")):
+ if (x[0].UserID != x[1].id):
+ print >>standardError, " ***Failure*** userprofilesToUsers: %s - %s missing in new database" % (x[0].UserID, x[0].UserName)
+ errorCount += 1
+ break
+ except Exception, x:
+ print >>standardError, " ***Failure*** userprofilesToUsers: Testing system failure: %s" % x
+ print >>standardError, " %d errors" % errorCount
+
+
+#-----------------------------------------------------------------------------------------------------------
+# cleanAddonsTables_test
+#-----------------------------------------------------------------------------------------------------------
+def cleanAddonsTables_test(newDB, workingEnvironment):
+ print >>standardError, 'cleanAddonsTables_test ("all" phase)'
+ errorCount = 0
+ theTables = [ "previews", "addons_tags", "applications_versions", "files", "versions", "addons_users", "addons" ]
+ try:
+ workingEnvironment["addons"] = "all"
+ cleanAddonsTables(newDB, workingEnvironment)
+ except Exception, x:
+ print >>standardError, " ***Failure*** cleanAddonsTables: %s" % x
+ errorCount += 1
+ try:
+ for aTableName in theTables:
+ if newDB.singleValueSql("select count(*) from %s" % aTableName) != 0:
+ print >>standardError, " ***Failure*** cleanAddonsTables: %s table not cleared" % aTableName
+ errorCount += 1
+ except Exception, x:
+ print >>standardError, ' ***Failure*** cleanAddonsTables: Testing system failure during "all" phase: %s' % x
+ print >>standardError, " %d errors" % errorCount
+
+ print >>standardError, 'cleanAddonsTables_test ("subset" phase)'
+ errorCount = 0
+ try:
+ workingEnvironment["addons"] = "all"
+ cleanAddonsTables(newDB, workingEnvironment)
+ cleanMetaDataTables(newDB, workingEnvironment)
+ applicationsToApplications (oldDatabase, newDatabase, workingEnvironment)
+ categoriesToTags (oldDatabase, newDatabase, workingEnvironment)
+ osToPlatforms (oldDatabase, newDatabase, workingEnvironment)
+ userprofilesToUsers (oldDatabase, newDatabase, workingEnvironment)
+ mainToAddOns (oldDatabase, newDatabase, workingEnvironment)
+ authorxrefToAddons_users (oldDatabase, newDatabase, workingEnvironment)
+ versionToVerions (oldDatabase, newDatabase, workingEnvironment)
+ categoryxrefToAddons_tags (oldDatabase, newDatabase, workingEnvironment)
+ previewsToPreviews (oldDatabase, newDatabase, workingEnvironment)
+
+ delimitedListOfAddons = workingEnvironment["addons"] = "3110,3112,3115"
+ delimitedListOfVersionIdsThatShouldBeDeleted = ",".join((str(x.id) for x in newDB.executeSql("select v.id from versions v where addon_id in (%s)" % delimitedListOfAddons)))
+ setupAddonSelectionTable(oldDatabase, newDatabase, workingEnvironment)
+ try:
+ cleanAddonsTables(newDB, workingEnvironment)
+ finally:
+ cleanupAddonSelectionTable (oldDatabase, newDatabase, workingEnvironment)
+ except Exception, x:
+ print >>standardError, " ***Failure*** cleanAddonsTables: %s" % x
+ errorCount += 1
+ try:
+ if newDB.singleValueSql("select count(*) from addons where id in (%s)" % delimitedListOfAddons) != 0:
+ print >>standardError, " ***Failure*** cleanAddonsTables: one or more of deleted addon_id values %s found in addons table" % delimitedListOfAddons
+ errorCount += 1
+ if newDB.singleValueSql("select count(*) from versions where addon_id in (%s)" % delimitedListOfAddons) != 0:
+ print >>standardError, " ***Failure*** cleanAddonsTables: one or more of deleted addon_id values %s found in versions table" % delimitedListOfAddons
+ errorCount += 1
+ if newDB.singleValueSql("select count(*) from applications_versions where version_id in (%s)" % delimitedListOfVersionIdsThatShouldBeDeleted) != 0:
+ print >>standardError, " ***Failure*** cleanAddonsTables: one or more of deleted version values %s found in applications_versions table" % delimitedListOfVersionIdsThatShouldBeDeleted
+ errorCount += 1
+ if newDB.singleValueSql("select count(*) from files where version_id in (%s)" % delimitedListOfVersionIdsThatShouldBeDeleted) != 0:
+ print >>standardError, " ***Failure*** cleanAddonsTables: one or more of deleted version values %s found in files table" % delimitedListOfVersionIdsThatShouldBeDeleted
+ errorCount += 1
+ if newDB.singleValueSql("select count(*) from addons_tags where addon_id in (%s)" % delimitedListOfAddons) != 0:
+ print >>standardError, " ***Failure*** cleanAddonsTables: one or more of deleted addon_id values %s found in addons_tags table" % delimitedListOfAddons
+ errorCount += 1
+ if newDB.singleValueSql("select count(*) from previews where addon_id in (%s)" % delimitedListOfAddons) != 0:
+ print >>standardError, " ***Failure*** cleanAddonsTables: one or more of deleted addon_id values %s found in previews table" % delimitedListOfAddons
+ errorCount += 1
+ except Exception, x:
+ print >>standardError, ' ***Failure*** cleanAddonsTables: Testing system failure during "subset" phase: %s' % x
+ traceback.print_exc(file=standardError)
+ print >>standardError, " %d errors" % errorCount
+
+
+#-----------------------------------------------------------------------------------------------------------
+# mainToAddOnsTables_test
+#-----------------------------------------------------------------------------------------------------------
+
+def mainToAddOnsTables_test (oldDB, newDB, workingEnvironment):
+ print >>standardError, 'mainToAddOns_test ("all" phase)'
+ errorCount = 0
+ theTables = [ "previews", "addons_tags", "applications_versions", "files", "versions", "addons_users", "addons" ]
+ try:
+ workingEnvironment["addons"] = "all"
+ cleanAddonsTables(newDB, workingEnvironment)
+ cleanMetaDataTables(newDB, workingEnvironment)
+ applicationsToApplications (oldDatabase, newDatabase, workingEnvironment)
+ categoriesToTags (oldDatabase, newDatabase, workingEnvironment)
+ osToPlatforms (oldDatabase, newDatabase, workingEnvironment)
+ userprofilesToUsers (oldDatabase, newDatabase, workingEnvironment)
+
+ mainToAddOns (oldDatabase, newDatabase, workingEnvironment)
+ authorxrefToAddons_users (oldDatabase, newDatabase, workingEnvironment)
+ versionToVerions (oldDatabase, newDatabase, workingEnvironment)
+ categoryxrefToAddons_tags (oldDatabase, newDatabase, workingEnvironment)
+ previewsToPreviews (oldDatabase, newDatabase, workingEnvironment)
+ except Exception, x:
+ print >>standardError, " ***Failure*** mainToAddOns: %s" % x
+ errorCount += 1
+ try:
+ # check addons Table
+ for anAddonFromOldDB in oldDB.executeSql("select * from main"):
+ try:
+ newDB.executeSql("select * from addons where id = %d" % anAddonFromOldDB.ID).__iter__().next()
+ except StopIteration:
+ print >>standardError, ' ***Failure*** mainToAddOns: addon %d missing from new database "all" phase' % anAddonFromOldDB.ID
+ errorCount += 1
+ # check addons_users Table
+ for anAuthorxrefFromOldDB in oldDB.executeSql("select * from authorxref"):
+ try:
+ newDB.executeSql("select * from addons_users where addon_id = %d and user_id = %d" % (anAuthorxrefFromOldDB.ID, anAuthorxrefFromOldDB.UserID)).__iter__().next()
+ except StopIteration:
+ print >>standardError, ' ***Failure*** mainToAddOns: addons_users %d, %d missing from new database "all" phase' % (anAuthorxrefFromOldDB.ID, anAuthorxrefFromOldDB.UserID)
+ errorCount += 1
+ # check versions, files, applications_versions tables
+ ##TESTED ONLY IN SUBSET PHASE##
+ #for aVersionFromOldDB in oldDB.executeSql("select * from version"):
+ # try:
+ # aVersionFromNewDB = newDB.executeSql("select * from versions where id = %d" % aVersionFromOldDB.vID).__iter__().next()
+ # except StopIteration:
+ # print >>standardError, ' ***Failure*** mainToAddOns: versions %d missing from new database "all" phase' % aVersionFromOldDB.vID
+ # errorCount += 1
+ # try:
+ # newDB.executeSql("select * from applications_versions where application_id = %d and version_id = %d" % (aVersionFromOldDB.AppID, aVersionFromOldDB.vID)).__iter__().next()
+ # except StopIteration:
+ # print >>standardError, ' ***Failure*** mainToAddOns: applications_versions %d, %d missing from new database "all" phase' % (aVersionFromOldDB.AppID, aVersionFromOldDB.vID)
+ # errorCount += 1
+ # try:
+ # newDB.executeSql("select * from files where version_id = %d" % aVersionFromOldDB.vID).__iter__().next()
+ # except StopIteration:
+ # print >>standardError, ' ***Failure*** mainToAddOns: files entry for version %d missing from new database "all" phase' % aVersionFromOldDB.vID
+ # errorCount += 1
+ # check categoryxref Table
+ for aCategoryxrefFromOldDB in oldDB.executeSql("select * from categoryxref"):
+ try:
+ newDB.executeSql("select * from addons_tags where addon_id = %d and tag_id = %d" % (aCategoryxrefFromOldDB.ID, aCategoryxrefFromOldDB.CategoryID)).__iter__().next()
+ except StopIteration:
+ print >>standardError, ' ***Failure*** mainToAddOns: addons_tags %d, %d missing from new database "all" phase' % (aCategoryxrefFromOldDB.ID, aCategoryxrefFromOldDB.CategoryID)
+ errorCount += 1
+ # check previews Table
+ for aPreviewsFromOldDB in oldDB.executeSql("select * from previews"):
+ try:
+ newDB.executeSql("select * from previews where id = %d " % aPreviewsFromOldDB.PreviewID).__iter__().next()
+ except StopIteration:
+ print >>standardError, ' ***Failure*** mainToAddOns: previews %d missing from new database "all" phase' % aPreviewsFromOldDB.PreviewID
+ errorCount += 1
+ except Exception, x:
+ print >>standardError, ' ***Failure*** mainToAddOns: Testing system failure during "all" phase: %s' % x
+ print >>standardError, " %d errors" % errorCount
+
+ print >>standardError, 'mainToAddOns_test ("subset" phase)'
+ errorCount = 0
+ try:
+ workingEnvironment["addons"] = "all"
+ cleanAddonsTables(newDB, workingEnvironment)
+ cleanMetaDataTables(newDB, workingEnvironment)
+
+ applicationsToApplications (oldDatabase, newDatabase, workingEnvironment)
+ categoriesToTags (oldDatabase, newDatabase, workingEnvironment)
+ osToPlatforms (oldDatabase, newDatabase, workingEnvironment)
+ userprofilesToUsers (oldDatabase, newDatabase, workingEnvironment)
+
+ delimitedListOfAddons = workingEnvironment["addons"] = "3110,3112,3115"
+ delimitedListOfVersionIdsThatShouldBeDeleted = ",".join((str(x.id) for x in newDB.executeSql("select v.id from versions v where addon_id in (%s)" % delimitedListOfAddons)))
+ setupAddonSelectionTable(oldDatabase, newDatabase, workingEnvironment)
+
+ try:
+ mainToAddOns (oldDatabase, newDatabase, workingEnvironment)
+ authorxrefToAddons_users (oldDatabase, newDatabase, workingEnvironment)
+ versionToVerions (oldDatabase, newDatabase, workingEnvironment)
+ categoryxrefToAddons_tags (oldDatabase, newDatabase, workingEnvironment)
+ previewsToPreviews (oldDatabase, newDatabase, workingEnvironment)
+ finally:
+ cleanupAddonSelectionTable (oldDatabase, newDatabase, workingEnvironment)
+ except Exception, x:
+ print >>standardError, " ***Failure*** mainToAddOns: %s" % x
+ errorCount += 1
+ try:
+ # check addons Table
+ for anAddonFromOldDB in oldDB.executeSql("select * from main where id in (%s)" % delimitedListOfAddons):
+ try:
+ newDB.executeSql("select * from addons where id = %d" % anAddonFromOldDB.ID).__iter__().next()
+ except StopIteration:
+ print >>standardError, ' ***Failure*** mainToAddOns: addon %d missing from new database "subset" phase' % anAddonFromOldDB.ID
+ errorCount += 1
+ # check addons_users Table
+ for anAuthorxrefFromOldDB in oldDB.executeSql("select * from authorxref where id in (%s)" % delimitedListOfAddons):
+ try:
+ newDB.executeSql("select * from addons_users where addon_id = %d and user_id = %d" % (anAuthorxrefFromOldDB.ID, anAuthorxrefFromOldDB.UserID)).__iter__().next()
+ except StopIteration:
+ print >>standardError, ' ***Failure*** mainToAddOns: addons_users %d, %d missing from new database "subset" phase' % (anAuthorxrefFromOldDB.ID, anAuthorxrefFromOldDB.UserID)
+ errorCount += 1
+ # check versions, files, applications_versions tables
+ for aVersionFromOldDB in oldDB.executeSql("select * from version where id in (%s)" % delimitedListOfAddons):
+ try:
+ aVersionFromNewDB = newDB.executeSql("select * from versions where id = %d" % aVersionFromOldDB.vID).__iter__().next()
+ except StopIteration:
+ print >>standardError, ' ***Failure*** mainToAddOns: versions %d missing from new database "subset" phase' % aVersionFromOldDB.vID
+ errorCount += 1
+ try:
+ newDB.executeSql("select * from applications_versions where application_id = %d and version_id = %d" % (aVersionFromOldDB.AppID, aVersionFromOldDB.vID)).__iter__().next()
+ except StopIteration:
+ print >>standardError, ' ***Failure*** mainToAddOns: applications_versions %d, %d missing from new database "subset" phase' % (aVersionFromOldDB.AppID, aVersionFromOldDB.vID)
+ errorCount += 1
+ try:
+ newDB.executeSql("select * from files where version_id = %d" % aVersionFromOldDB.vID).__iter__().next()
+ except StopIteration:
+ print >>standardError, ' ***Failure*** mainToAddOns: files entry for version %d missing from new database "subset" phase' % aVersionFromOldDB.vID
+ errorCount += 1
+ # check categoryxref Table
+ for aCategoryxrefFromOldDB in oldDB.executeSql("select * from categoryxref where id in (%s)" % delimitedListOfAddons):
+ try:
+ newDB.executeSql("select * from addons_tags where addon_id = %d and tag_id = %d" % (aCategoryxrefFromOldDB.ID, aCategoryxrefFromOldDB.CategoryID)).__iter__().next()
+ except StopIteration:
+ print >>standardError, ' ***Failure*** mainToAddOns: addons_tags %d, %d missing from new database "all" phase' % (aCategoryxrefFromOldDB.ID, aCategoryxrefFromOldDB.CategoryID)
+ errorCount += 1
+ # check previews Table
+ for aPreviewsFromOldDB in oldDB.executeSql("select * from previews where id in (%s)" % delimitedListOfAddons):
+ try:
+ newDB.executeSql("select * from previews where id = %d " % aPreviewsFromOldDB.PreviewID).__iter__().next()
+ except StopIteration:
+ print >>standardError, ' ***Failure*** mainToAddOns: previews %d missing from new database "all" phase' % aPreviewsFromOldDB.PreviewID
+ errorCount += 1
+ except Exception, x:
+ print >>standardError, ' ***Failure*** mainToAddOns: Testing system failure during "subset" phase: %s' % x
+ traceback.print_exc(file=standardError)
+ print >>standardError, " %d errors" % errorCount
+
+
+#-----------------------------------------------------------------------------------------------------------
+# runTests
+#-----------------------------------------------------------------------------------------------------------
+def runTests (oldDB, newDB, workingEnvironment):
+ cleanMetaDataTables_test(newDB, workingEnvironment)
+ applicationsToApplications_test(oldDB, newDB, workingEnvironment)
+ categoriesToTags_test(oldDB, newDB, workingEnvironment)
+ osToPlatforms_test(oldDB, newDB, workingEnvironment)
+ userprofilesToUsers_test(oldDB, newDB, workingEnvironment)
+ cleanAddonsTables_test(newDB, workingEnvironment)
+ mainToAddOnsTables_test(oldDB, newDB, workingEnvironment)
+
+#-----------------------------------------------------------------------------------------------------------
+# addBogusTranslations
+#-----------------------------------------------------------------------------------------------------------
+def addBogusTranslations (newDB):
+ counter = 1
+ for aTranslationIDRow in newDB.executeSqlNoCache("select distinct id from translations"):
+ for aLocale in ['de', 'ru', 'nl']:
+ newDB.executeManySql("insert into translations (id, locale, localized_string) values (%s, %s, %s)", [(aTranslationIDRow.id, aLocale, "bogus translation #%06d" % counter)])
+ newDB.commit()
+ counter += 1
+
+#-----------------------------------------------------------------------------------------------------------
+# removeBogusTranslations
+#-----------------------------------------------------------------------------------------------------------
+def removeBogusTranslations (newDB):
+ newDB.executeSql ("delete from translations where localized_string like 'bogus translation #%'")
+ newDB.commit()
+
+#===========================================================================================================
+# main
+#===========================================================================================================
+if __name__ == "__main__":
+
+ import cse.ConfigurationManager
+
+ try:
+
+ options = [ ('?', 'help', False, None, 'print this message'),
+ ('c', 'config', True, './migration.conf', 'specify the location and name of the config file'),
+ (None, 'oldDatabaseName', True, "", 'the name of the old database within the server'),
+ (None, 'oldServerName', True, "", 'the name of the old database server'),
+ (None, 'oldUserName', True, "", 'the name of the user in the old database'),
+ (None, 'oldPassword', True, "", 'the password for the user in the old database'),
+ (None, 'newDatabaseName', True, "", 'the name of the new database within the server'),
+ (None, 'newServerName', True, "", 'the name of the new database server'),
+ (None, 'newUserName', True, "", 'the name of the user in the new database'),
+ (None, 'newPassword', True, "", 'the password for the user in the new database'),
+ ('a', 'addons', True, "all", 'a quoted comma delimited list of the ids of addons OR the word "all"'),
+ ('n', 'not', False, None, """reverses the meaning of the "addon" option. If the "addon" option has a list, then specify everything except what's on the list"""),
+ ('M', 'migrateMetaData', False, None, 'if present, this switch causes the metadata tables to be migrated'),
+ ('A', 'migrateAddons', False, None, 'if present, this switch causes the addons in the "addons" option list to be migrated'),
+ ('v', 'verbose', False, None, 'print status information as it runs to stderr'),
+ ('l', 'locale', True, "en-US", 'set the locale for addons being migrated'),
+ (None, 'clear', False, None, 'clear all exisiting information from the new database'),
+ (None, 'clearAddons', False, None, 'clear all exisiting addons in the "addons" option list information from the new database'),
+ (None, 'test', False, None, 'run the test cases'),
+ (None, 'show', False, None, 'echo the configuration to stdout and then quit'),
+ (None, 'bogusTranslationsInsert', False, None, 'fill out the translations table with a full set of locales for all entries for load testing'),
+ (None, 'bogusTranslationsRemove', False, None, 'remove any bogus translations from the translations table'),
+ (None, 'logPathName', True, "./migration.log", 'a progressive log of all runs of the migration script'),
+ (None, 'addonStatusWhenNoFilesApproved', True, "sandbox", 'the status to set an addon if no files approved (null, sandbox, pending, nominated, public, disabled)'),
+ (None, 'addonStatusWhenSomeFilesApproved', True, "public", 'the status to set an addon if some files approved (null, sandbox, pending, nominated, public, disabled)'),
+ (None, 'noPreviewImageProcessing', False, "", 'do not process preview images'),
+ (None, 'previewURIPrefix', True, "https://addons.mozilla.org", 'a prefix to add to the URI in the preview table to enable downloading'),
+ (None, 'fileCachePath', True, "", 'a path for the caching of files (blank for no cache)'),
+ (None, 'recalculateHash', False, "", 'force the recaclulation of the hash for the xpi files'),
+ (None, 'ignoreHash', False, "", 'no not allow the migration to touch the hash'),
+
+ ]
+
+ workingEnvironment = cse.ConfigurationManager.ConfigurationManager(options)
+ #workingEnvironment["version"] = version
+
+ if 'help' in workingEnvironment:
+ print >>standardError, "migration %s\nThis routine migrates data from the old AMO database schema to the new one." % version
+ workingEnvironment.outputCommandSummary(standardError, 1)
+ sys.exit()
+
+ if 'show' in workingEnvironment:
+ workingEnvironment.output(sys.stdout)
+ sys.exit()
+
+ except cse.ConfigurationManager.ConfigurationManagerNotAnOption, x:
+ print >>standardError, "m1 %s\n%s\nFor usage, try --help" % (version, x)
+ sys.exit()
+
+
+ try:
+ useLogFile = open(workingEnvironment["logPathName"], "a")
+ print >>useLogFile, mx.DateTime.now()
+ workingEnvironment.output(useLogFile)
+ useLogFile.close()
+
+ if "verbose" in workingEnvironment:
+ print >>standardError, "%s beginning migration version %s with options:" % (mx.DateTime.now(), version)
+ workingEnvironment.output(standardError)
+
+ validStatusStates = {"null": 0, "sandbox": 1, "pending": 2, "nominated": 3, "public": 4, "disabled": 5}
+ try:
+ workingEnvironment["addonStatusWhenNoFilesApproved"] = validStatusStates[workingEnvironment["addonStatusWhenNoFilesApproved"]]
+ except KeyError:
+ print >>standardError, "%s is not a valid value for addonStatusWhenNoFilesApproved. See --help" % workingEnvironment["addonStatusWhenNoFilesApproved"]
+ sys.exit()
+ try:
+ workingEnvironment["addonStatusWhenSomeFilesApproved"] = validStatusStates[workingEnvironment["addonStatusWhenSomeFilesApproved"]]
+ except KeyError:
+ print >>standardError, "%s is not a valid value for addonStatusWhenSomeFilesApproved. See --help" % workingEnvironment["addonStatusWhenSomeFilesApproved"]
+ sys.exit()
+
+ oldDatabase = cse.MySQLDatabase.MySQLDatabase(workingEnvironment["oldDatabaseName"], workingEnvironment["oldServerName"],
+ workingEnvironment["oldUserName"], workingEnvironment["oldPassword"])
+ newDatabase = cse.MySQLDatabase.MySQLDatabase(workingEnvironment["newDatabaseName"], workingEnvironment["newServerName"],
+ workingEnvironment["newUserName"], workingEnvironment["newPassword"])
+
+ if "test" in workingEnvironment:
+ runTests(oldDatabase, newDatabase, workingEnvironment)
+ else:
+ setupAddonSelectionTable(oldDatabase, newDatabase, workingEnvironment)
+
+ try:
+ if "clear" in workingEnvironment:
+ originalAddonsOption = workingEnvironment["addons"]
+ workingEnvironment["addons"] = "all"
+ cleanAddonsTables(newDatabase, workingEnvironment)
+ cleanMetaDataTables(newDatabase, workingEnvironment)
+ workingEnvironment["addons"] = originalAddonsOption
+ elif "clearAddons" in workingEnvironment:
+ cleanAddonsTables(newDatabase, workingEnvironment)
+
+ if "migrateMetaData" in workingEnvironment:
+ if "verbose" in workingEnvironment: print >>standardError, "%s beginning metadata migration" % mx.DateTime.now()
+ try:
+ cleanMetaDataTables (newDatabase, workingEnvironment)
+ except:
+ raise MigrationException("Migrating MetaData implies clearing MetaData tables, but there appears to be Addon data in the database. Clear the Addon data before trying to migrate MetaData.")
+ applicationsToApplications (oldDatabase, newDatabase, workingEnvironment)
+ categoriesToTags (oldDatabase, newDatabase, workingEnvironment)
+ osToPlatforms (oldDatabase, newDatabase, workingEnvironment)
+ userprofilesToUsers (oldDatabase, newDatabase, workingEnvironment)
+
+ if "migrateAddons" in workingEnvironment:
+ if "verbose" in workingEnvironment: print >>standardError, "%s beginning addons migration" % mx.DateTime.now()
+ cleanAddonsTables (newDatabase, workingEnvironment)
+ mainToAddOns (oldDatabase, newDatabase, workingEnvironment)
+ categoryxrefToAddons_tags (oldDatabase, newDatabase, workingEnvironment)
+ authorxrefToAddons_users (oldDatabase, newDatabase, workingEnvironment)
+ versionToVerions (oldDatabase, newDatabase, workingEnvironment)
+ #categoryxrefToAddons_tags (oldDatabase, newDatabase, workingEnvironment)
+ previewsToPreviews (oldDatabase, newDatabase, workingEnvironment)
+
+ if "bogusTranslationsInsert" in workingEnvironment:
+ if "verbose" in workingEnvironment: print >>standardError, "%s creating bogus translations" % mx.DateTime.now()
+ addBogusTranslations(newDatabase)
+
+ if "bogusTranslationsRemove" in workingEnvironment:
+ if "verbose" in workingEnvironment: print >>standardError, "%s removing bogus translations" % mx.DateTime.now()
+ removeBogusTranslations(newDatabase)
+
+ finally:
+ cleanupAddonSelectionTable (oldDatabase, newDatabase, workingEnvironment)
+
+ except KeyboardInterrupt:
+ print >>standardError, "Interrupted..."
+ pass
+
+ except MigrationException, x:
+ print >>standardError, x
+
+ except Exception, x:
+ print >>standardError, x
+ traceback.print_exc(file=standardError)
+
+ if "verbose" in workingEnvironment: print >>standardError, "done."
diff --git a/bin/parse_logs/count_downloads.class.php b/bin/parse_logs/count_downloads.class.php
new file mode 100644
index 0000000..9274654
--- /dev/null
+++ b/bin/parse_logs/count_downloads.class.php
@@ -0,0 +1,195 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Justin Scott <fligtar@mozilla.com> (Original Author)
+ * Andrei Hajdukewycz <sancus@off.net>
+ * Wil Clouser <wclouser@mozilla.com>
+ *
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/**
+ * Counts downloads from access logs and stores in database
+ */
+class Count_Downloads {
+ var $countedIPs = array(); // list of counted IP addresses
+ var $db;
+ var $totalSkipped = array('blacklist' => 0, 'SJ' => 0, 'NL' => 0, 'CN' => 0);
+ var $totalCounted = 0;
+ var $counts = array( 'totdown' => array(), 'perday' => array(), 'collections_and_addons' => array() );
+
+ /**
+ * Initializes download count parser
+ */
+ function Count_Downloads(&$db) {
+ $this->db =& $db;
+ }
+
+ /**
+ * Increment relevant properties of each add-on for each date
+ *
+ //@TODO XXX: Currently the collection ID isn't passed back to us so we have no way of knowing what collection an add-on came from.
+ // Convienently, we only have one collection ID at the moment so this is hardcoded to 1 in this function. This needs to be fixed
+ // before bandwagon starts!
+ *
+ * @param array $details details from the parsed log line
+ */
+ function count($details) {
+ // Clean up IP array
+ $this->cleanIPs($details['unixtime']);
+
+ // Make sure IP is not in blacklist and is not coming from Mozilla .nl
+ if (isset($this->countedIPs[$details['ip']])) {
+ $this->totalSkipped['blacklist']++;
+ outputIfVerbose("[DownloadCounter] IP ({$details['ip']}) in blacklist; skipped");
+ return;
+ }
+
+ $_addon_ids = array();
+
+ if ($details['type'] == 'collections' && !empty($details['addon_ids'])) {
+ if (!empty($this->counts['collections_and_addons'][1]['total'])) {
+ $this->counts['collections_and_addons'][1]['total'] += 1;
+ } else {
+ $this->counts['collections_and_addons'][1]['total'] = 1;
+ }
+ $_addon_ids = $details['addon_ids'];
+ } elseif (!empty($details['fileid'])) {
+ $addon_id_result = $this->db->read("SELECT versions.addon_id FROM files LEFT JOIN versions ON files.version_id = versions.id WHERE files.id={$details['fileid']}");
+ $addon_id = mysql_fetch_array($addon_id_result);
+
+ if (!empty($addon_id['addon_id'])) {
+ $_addon_ids = array($addon_id['addon_id']);
+ }
+ }
+
+ if (empty($_addon_ids)) {
+ outputIfVerbose("[DownloadCounter] No add-on ids found in path: {$details['path']}");
+ }
+
+ // Increment stats for each downloaded add-on
+ foreach ($_addon_ids as $_addon_id) {
+
+ // If it's a collection it gets counted in that group too
+ if ($details['type'] == 'collections') {
+ // This array is in the format:
+ // [collections_and_addons] => Array
+ // (
+ // [$collection_id] => Array
+ // (
+ // [total] => 4
+ // [addon_ids] => Array
+ // (
+ // [$addon_id] => $total_downloads_of_this_addon_from_that_collection
+ // ...
+ // )
+ // )
+ // )
+ if (!empty($this->counts['collections_and_addons'][1]['addon_ids'][$_addon_id])) {
+ $this->counts['collections_and_addons'][1]['addon_ids'][$_addon_id] += 1;
+ } else {
+ $this->counts['collections_and_addons'][1]['addon_ids'][$_addon_id] = 1;
+ }
+ }
+
+ // update total downloads
+ if (!empty($this->counts['totdown'][$_addon_id])) {
+ $this->counts['totdown'][$_addon_id] += 1;
+ } else {
+ $this->counts['totdown'][$_addon_id] = 1;
+ }
+
+ // update per-day
+ if ( !isset( $this->counts['perday'][$_addon_id] ) ) {
+ $this->counts['perday'][$_addon_id] = array();
+ }
+
+ if (!empty($this->counts['perday'][$_addon_id][date('Y-m-d', $details['unixtime'])])) {
+ $this->counts['perday'][$_addon_id][date('Y-m-d', $details['unixtime'])] += 1;
+ } else {
+ $this->counts['perday'][$_addon_id][date('Y-m-d', $details['unixtime'])] = 1;
+ }
+
+ $this->totalCounted++;
+ outputIfVerbose("[DownloadCounter] Updated count for add-on id: {$_addon_id}");
+ }
+
+ // Blacklist IP from being counted again for 30 seconds
+ $this->countedIPs[$details['ip']] = $details['unixtime'];
+ }
+
+ /**
+ * Cleans array of blacklisted IPs of IPs that downloaded over 30 seconds ago
+ */
+ function cleanIPs($currentTime) {
+ foreach ($this->countedIPs as $ip => $downloadTime) {
+ if (($currentTime - $downloadTime) > 30)
+ unset($this->countedIPs[$ip]);
+ }
+ }
+
+ /**
+ * Callback for after a logfile is parsed.
+ */
+ function logfileParsedCallback() {
+ // update total downloads
+ foreach ( $this->counts['totdown'] as $id => $ct ) {
+ $this->db->write("UPDATE addons SET totaldownloads=totaldownloads+{$ct} WHERE id={$id}");
+ }
+
+ // now the dailies
+ foreach ( $this->counts['perday'] as $id => $days ) {
+ foreach ( $days as $day => $ct ) {
+ $this->db->write("INSERT INTO download_counts(addon_id, count, date) VALUES({$id}, {$ct}, '{$day}')
+ ON DUPLICATE KEY UPDATE count=count+{$ct}");
+ }
+ }
+
+ // now the collections
+ foreach ( $this->counts['collections_and_addons'] as $collection_id => $details) {
+ $this->db->write("UPDATE collections SET downloads = downloads + {$details['total']} WHERE id={$collection_id} LIMIT 1");
+ foreach ($details['addon_ids'] as $addon_id => $count ) {
+ $this->db->write("UPDATE addons_collections SET downloads = downloads + {$count} WHERE addon_id={$addon_id} AND collection_id={$collection_id} LIMIT 1");
+ }
+ }
+
+ // Garbage collection on counts array after the log file is parsed and
+ // database is updated.
+ $this->counts['totdown'] = array();
+ $this->counts['perday'] = array();
+ $this->counts['collections_and_addons'] = array();
+ }
+}
+
+?>
diff --git a/bin/parse_logs/count_update_pings.class.php b/bin/parse_logs/count_update_pings.class.php
new file mode 100644
index 0000000..e7b1f66
--- /dev/null
+++ b/bin/parse_logs/count_update_pings.class.php
@@ -0,0 +1,276 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Justin Scott <fligtar@mozilla.com> (Original Author)
+ *
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/**
+ * Counts update pings and stores detailed data for statistics use
+ */
+class Count_Update_Pings {
+ var $db;
+ var $guids = array(); // array of GUIDs and add-on ids
+ var $counts = array(); // array of update ping counts
+ var $totalSkipped = array('incorrect_date' => 0, 'unknown_guid' => 0, 'SJ' => 0, 'NL' => 0, 'CN' => 0);
+ var $totalCounted = 0;
+ var $date; // Only count hits for this date (format: %Y-%m-%d)
+
+ /**
+ * Retain reference to database connection and cache GUIDs
+ */
+ function Count_Update_Pings(&$db, $date) {
+ $this->db =& $db;
+ $this->date = $date;
+
+ $this->cacheGUIDs();
+ }
+
+ /**
+ * Pulls all GUIDs and add-on IDs from database for quick lookup
+ */
+ function cacheGUIDs() {
+ $guid_query = $this->db->read("SELECT id, guid FROM addons");
+ while ($guid_row = mysql_fetch_array($guid_query)) {
+ $guids[$guid_row['guid']] = $guid_row['id'];
+ }
+
+ $this->guids = $guids;
+ }
+
+ /**
+ * Increment relevant properties of each add-on for each date
+ *
+ * @param array $details details from the parsed log line
+ */
+ function count($details) {
+ // Make sure GUID is known
+ if (empty($this->guids[$details['addon']['guid']])) {
+ $this->totalSkipped['unknown_guid']++;
+ outputIfVerbose("[UpdatePingCounter] Unknown GUID skipped: {$details['addon']['guid']}");
+ }
+ else {
+ $addon_id = $this->guids[$details['addon']['guid']];
+ $date = date('Y-m-d', $details['unixtime']);
+
+ // Bug 468570
+ if ($date != $this->date) {
+ $this->totalSkipped['incorrect_date']++;
+ outputIfVerbose("[UpdatePingCounter] Skipping out of range date {$date} for add-on id {$addon_id}");
+ return;
+ }
+
+ if (empty($this->counts[$date]))
+ $this->counts[$date] = array();
+
+ $count =& $this->counts[$date][$addon_id];
+
+ // Total
+ if (!empty($count['total']))
+ $count['total']++;
+ else
+ $count['total'] = 1;
+
+ // Versions
+ if (!empty($details['addon']['version'])) {
+ if (!empty($count['version'][$details['addon']['version']]))
+ $count['version'][$details['addon']['version']]++;
+ else
+ $count['version'][$details['addon']['version']] = 1;
+ }
+
+ // Status
+ if (!empty($details['addon']['status'])) {
+ if (!empty($count['status'][$details['addon']['status']]))
+ $count['status'][$details['addon']['status']]++;
+ else
+ $count['status'][$details['addon']['status']] = 1;
+ }
+
+ // Application
+ if (!empty($details['addon']['appID']) && !empty($details['addon']['appVersion'])) {
+ if (!empty($count['app'][$details['addon']['appID']][$details['addon']['appVersion']]))
+ $count['app'][$details['addon']['appID']][$details['addon']['appVersion']]++;
+ else
+ $count['app'][$details['addon']['appID']][$details['addon']['appVersion']] = 1;
+ }
+
+ // OS
+ if (!empty($details['addon']['appOS'])) {
+ if (!empty($count['os'][$details['addon']['appOS']]))
+ $count['os'][$details['addon']['appOS']]++;
+ else
+ $count['os'][$details['addon']['appOS']] = 1;
+ }
+
+ $this->totalCounted++;
+ outputIfVerbose("[UpdatePingCounter] Locally updated counts for add-on ID: {$addon_id}");
+ }
+ }
+
+ /**
+ * Writes saved counts to the database
+ */
+ function updateCounts() {
+ if (!empty($this->counts)) {
+ echo "\n[UpdatePingCounter] WRITING COUNTS TO DATABASE...\n";
+ foreach ($this->counts as $date => $addons) {
+ foreach ($addons as $addon_id => $counts) {
+ $existing_entry_qry = $this->db->read("SELECT * FROM update_counts WHERE addon_id='{$addon_id}' AND date='{$date}'");
+ $existing_result = mysql_fetch_array($existing_entry_qry);
+
+ // If row does not exist for date and add-on, insert new row
+ if (empty($existing_result)) {
+ $counts = $this->serializeCounts($counts);
+
+ $this->db->write("
+ INSERT INTO update_counts (
+ addon_id,
+ count,
+ version,
+ status,
+ application,
+ os,
+ date
+ ) VALUES(
+ '{$addon_id}',
+ {$counts['total']},
+ '{$counts['version']}',
+ '{$counts['status']}',
+ '{$counts['app']}',
+ '{$counts['os']}',
+ '{$date}'
+ )");
+
+ outputIfVerbose("[UpdatePingCounter] Created record for: {$date} / {$addon_id}");
+ }
+ // If row does exist, add the totals together
+ else {
+ $counts = $this->unserializeAndTotalCounts($counts, $existing_result);
+
+ $this->db->write("
+ UPDATE update_counts
+ SET
+ count = {$counts['total']},
+ version = '{$counts['version']}',
+ status = '{$counts['status']}',
+ application = '{$counts['app']}',
+ os = '{$counts['os']}'
+ WHERE
+ addon_id='{$addon_id}' AND
+ date='{$date}'
+ ");
+
+ outputIfVerbose("[UpdatePingCounter] Updated record for: {$date} / {$addon_id}");
+ }
+ }
+ }
+
+ // Now that counts have been written, we can clear the array for future counting
+ $this->counts = array();
+ }
+ }
+
+ /**
+ * Serializes the array of counts and escapes for SQL query
+ *
+ * @param array $counts the count totals for an add-on
+ */
+ function serializeCounts($counts) {
+ $counts['version'] = !empty($counts['version']) ? mysql_real_escape_string(serialize($counts['version'])) : '';
+ $counts['status'] = !empty($counts['status']) ? mysql_real_escape_string(serialize($counts['status'])) : '';
+ $counts['app'] = !empty($counts['app']) ? mysql_real_escape_string(serialize($counts['app'])) : '';
+ $counts['os'] = !empty($counts['os']) ? mysql_real_escape_string(serialize($counts['os'])) : '';
+
+ return $counts;
+ }
+
+ /**
+ * Unserializes existing counts from the database and totals the existing
+ * counts with the new counts from this session's parsing.
+ *
+ * @param array $counts the session's counts
+ * @param array $existing the existing counts
+ */
+ function unserializeAndTotalCounts($counts, $existing) {
+ // Unserialize existing data from database
+ $existing = array(
+ 'total' => $existing['count'],
+ 'version' => unserialize($existing['version']),
+ 'status' => unserialize($existing['status']),
+ 'app' => unserialize($existing['application']),
+ 'os' => unserialize($existing['os'])
+ );
+
+ // Merge the two arrays into a new array
+ $totalCounts = array_merge_recursive($counts, $existing);
+
+ // If there are duplicate key names, an array will be created, so
+ // we loop through and find such occurrences
+ foreach ($totalCounts as $property => $items) {
+ if ($property == 'total') {
+ $totalCounts[$property] = array_sum($items);
+ }
+ elseif (!empty($items)) {
+ foreach ($items as $item => $count) {
+ if ($property != 'app') {
+ if (is_array($count)) {
+ $totalCounts[$property][$item] = array_sum($count);
+ }
+ }
+ elseif (!empty($count)) {
+ // the app property has an additional level of elements
+ foreach ($count as $appVersion => $appVersionCount) {
+ if (is_array($appVersionCount)) {
+ $totalCounts[$property][$item][$appVersion] = array_sum($appVersionCount);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return $this->serializeCounts($totalCounts);
+ }
+
+ /**
+ * Callback for after a logfile is parsed.
+ */
+ function logfileParsedCallback() {
+ $this->updateCounts();
+ }
+}
+
+?>
diff --git a/bin/parse_logs/log_parser.class.php b/bin/parse_logs/log_parser.class.php
new file mode 100644
index 0000000..c596c44
--- /dev/null
+++ b/bin/parse_logs/log_parser.class.php
@@ -0,0 +1,321 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Justin Scott <fligtar@mozilla.com> (Original Author)
+ * Andrei Hajdukewycz <sancus@off.net>
+ * Wil Clouser <wclouser@mozilla.com>
+ *
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+// Mozilla datacenter IPs to filter
+$datacenters = array(
+ 'NL' => array('63.245.213.'),
+ 'CN' => array('59.151.50.')
+ );
+
+// Include class files
+$root = dirname(dirname(dirname(__FILE__)));
+require_once "{$root}/bin/database.class.php";
+require_once "{$root}/bin/parse_logs/count_downloads.class.php";
+require_once "{$root}/bin/parse_logs/count_update_pings.class.php";
+
+/**
+ * Outputs message if script has been called with verbose flag
+ */
+function outputIfVerbose($message) {
+ global $verbose;
+
+ if ($verbose)
+ print "{$message}\n";
+}
+
+/**
+ * Parses the access logs and hands off to counting classes
+ */
+class Log_Parser {
+ var $tmpDir; // writable directory for temp file
+ var $logDir; // directory of the access logs
+ var $date = ''; // date of updateping logs to parse
+ var $type; // type of parsing
+ var $db;
+ var $counter; // the counter class
+ var $geo = '';
+
+ /**
+ * Initiates parser and database connection
+ *
+ * @param string $logDir access log directory
+ * @param string $tmpDir temporary file directory
+ * @param string $parseType the type of parsing to be done
+ * @param string $date the date of updateping logs to parse
+ */
+ function Log_Parser($logDir, $tmpDir, $parseType, $geo, $date = '') {
+ $this->tmpDir = $tmpDir;
+ $this->logDir = $logDir;
+ $this->type = $parseType;
+ $this->geo = $geo;
+
+ $this->db =& new Database();
+
+ $this->db->write("SET wait_timeout=28800");
+
+ if ($parseType == 'downloads' || $parseType == 'collections') {
+ $this->counter =& new Count_Downloads($this->db);
+ }
+ elseif ($parseType == 'updatepings') {
+ if (empty($date)) {
+ echo "\nUpdate ping counts must specify date parameter.\n";
+ exit;
+ }
+
+ $this->date = $date;
+ $this->counter =& new Count_Update_Pings($this->db, $this->date);
+ }
+ }
+
+ /**
+ * Finds all logfiles in the selected directory and if they have not already
+ * been parsed, passes to parsing function.
+ */
+ function start() {
+ echo "\n---------- [ BEGIN ACCESS LOG PARSING FOR {$this->geo}] ----------\n";
+ exec("find {$this->logDir} -name \"access_{$this->date}*.gz\" -type f", $loglist);
+
+ if (!empty($loglist)) {
+ foreach ($loglist as $logfile) {
+ if (!empty($logfile)) {
+ $logfile_query = $this->db->read("SELECT * FROM logs_parsed WHERE name='".mysql_real_escape_string(basename($logfile))."' AND geo='".mysql_real_escape_string($this->geo)."'");
+ $logfile_result = mysql_fetch_array($logfile_query);
+
+ if ($logfile_result["{$this->type}_done"] == 1)
+ echo basename($logfile)." has already been parsed for {$this->geo}!\n";
+ else {
+ if (empty($logfile_result))
+ $this->db->write("INSERT INTO logs_parsed (name, geo) VALUES('".mysql_real_escape_string(basename($logfile))."', '".mysql_real_escape_string($this->geo)."')");
+
+ $this->parse($logfile);
+ }
+ }
+ }
+ }
+ else
+ echo "No logfiles found in {$this->logDir}\n";
+
+ echo "\n---------- [ END ACCESS LOG PARSING ] ----------\n";
+
+ $this->finish();
+ }
+
+ /**
+ * Extracts log to temp file and begins matching line patterns and hands off
+ * to counters.
+ *
+ * @todo this function should be split up because it's hard to test this way.
+ * @param string $logfile the name of the current logfile
+ */
+ function parse($logfile) {
+ echo "\n---------- [ Copying {$logfile} ] ----------\n";
+ $tempFile = "{$this->tmpDir}/addon_log_file_".str_replace(' ', '_', microtime());
+
+ if ($this->type == 'downloads')
+ $pattern = 'downloads/file/';
+ elseif ($this->type == 'updatepings')
+ $pattern = 'VersionCheck.php';
+ elseif ($this->type == 'collections')
+ $pattern = 'GET [A-Za-z/-]*collections';
+
+ // Strip relevant lines out of log file and write to a temp file
+ exec("gzip -cd {$logfile} | grep '{$pattern}' > {$tempFile}");
+ if (!$fp = fopen($tempFile, 'r'))
+ die('Failed to open temp file');
+
+ echo "\n---------- [ Parsing {$logfile} in {$this->geo}] ----------\n";
+
+ while ($line = fgets($fp)) {
+
+ $lineDetails = $this->parseLine($line);
+
+ if (!is_array($lineDetails))
+ continue;
+
+ if ($geoFound = $this->fromMozillaDatacenter($lineDetails['ip'])) {
+ $this->counter->totalSkipped[$geoFound]++;
+ outputIfVerbose("[{$this->type}Counter] IP ({$lineDetails['ip']}) from Mozilla {$geoFound}; skipped");
+ continue;
+ }
+
+ if ($this->type == $lineDetails['type'])
+ $this->counter->count($lineDetails);
+ }
+
+ // Logfile post-parse callback
+ $this->counter->logfileParsedCallback();
+
+ // Mark file as finished parsing
+ $this->db->write("UPDATE logs_parsed SET {$this->type}_done=1 WHERE name='".mysql_real_escape_string(basename($logfile))."' AND geo='".mysql_real_escape_string($this->geo)."'");
+
+ fclose($fp);
+
+ // Delete temp file
+ unlink($tempFile);
+
+ echo "\n---------- [ Finished parsing {$logfile} ] ----------\n";
+ }
+
+ /**
+ * Split log line into the chunks we need
+ */
+ function parseLine($line) {
+
+ if (empty($line))
+ return false;
+
+ // Match line patterns
+ preg_match("/^(\S+) (\S+) (\S+)\s+\[([^:]+):(\d+:\d+:\d+) ([^\]]+)\] \"(\S+) (.*?) (\S+)\" (\S+) (\S+) (\".*?\") (\".*?\") (\".*?\")$/", $line, $matches);
+
+ if (empty($matches[0])) {
+ outputIfVerbose("Could not match log entry to pattern: {$line}\n");
+ return false;
+ } else {
+
+ $lineDetails = log_parser::getLineDetails($matches);
+
+ return $lineDetails;
+ }
+ }
+
+ /**
+ * Breaks pattern matches into relevant descriptions
+ */
+ function getLineDetails($matches) {
+ // Break matches up
+ $log_data = array();
+ $log_data['ip'] = $matches[1];
+ $log_data['identity'] = $matches[2];
+ $log_data['user'] = $matches[2];
+ $log_data['date'] = $matches[4];
+ $log_data['time'] = $matches[5];
+ $log_data['timezone'] = $matches[6];
+ $log_data['method'] = $matches[7];
+ $log_data['path'] = $matches[8];
+ $log_data['protocol'] = $matches[9];
+ $log_data['status'] = $matches[10];
+ $log_data['bytes'] = $matches[11];
+ $log_data['referer'] = $matches[12];
+ $log_data['agent'] = $matches[13];
+ $log_data['otherstuff'] = $matches[14];
+
+ // It's awesome that strtotime can't parse a standard apache timestamp
+ $log_data['unixtime'] = strtotime(str_replace('/', ' ', $log_data['date'])." {$log_data['time']}");
+
+ // Break up URL into pieces we need for download counts or update pings
+ preg_match("/(file|VersionCheck\.php)(\/([0-9]*))?(\?reqVersion=([^&]+)&id=([^&]+)(&version=([^&]+))?(&maxAppVersion=([^&]+))?(&status=([^&]+))?(&appID=([^&]+))?(&appVersion=([^&]+))?(&appOS=([^&]+))?(&appABI=(\S*))?)?/", $log_data['path'], $matches);
+
+ if (empty($matches)) {
+ // If that first crazy regex fails, let's see if it's a collection
+ preg_match("/(collections)\/success\?i=([0-9,].+)/", $log_data['path'], $matches);
+
+ if (empty($matches))
+ return false;
+ }
+
+ // Set request type
+ if ($matches[1] == 'file')
+ $log_data['type'] = 'downloads';
+ elseif ($matches[1] == 'VersionCheck.php')
+ $log_data['type'] = 'updatepings';
+ elseif ($matches[1] == 'collections')
+ $log_data['type'] = 'collections';
+
+ // If a download, get the file id out
+ if ($log_data['type'] == 'downloads') {
+ $log_data['fileid'] = mysql_real_escape_string($matches[3]);
+ }
+ // If it's an update ping, get out all of the details
+ elseif ($log_data['type'] == 'updatepings') {
+ $log_data['addon']['reqVersion'] = !empty($matches[5]) ? $matches[5] : null;
+ $log_data['addon']['guid'] = !empty($matches[6]) ? $matches[6] : null;
+ $log_data['addon']['version'] = !empty($matches[8]) ? $matches[8] : null;
+ $log_data['addon']['maxAppVersion'] = !empty($matches[10]) ? $matches[10] : null;
+ $log_data['addon']['status'] = !empty($matches[12]) ? $matches[12] : null;
+ $log_data['addon']['appID'] = !empty($matches[14]) ? $matches[14] : null;
+ $log_data['addon']['appVersion'] = !empty($matches[16]) ? $matches[16] : null;
+ $log_data['addon']['appOS'] = !empty($matches[18]) ? $matches[18] : null;
+ $log_data['addon']['appABI'] = !empty($matches[20]) ? $matches[20] : null;
+ }
+ // If it's a collection update, parse out the add-on ids
+ elseif ($log_data['type'] == 'collections') {
+ $_ids = explode(',', $matches[2]);
+
+ // Filter for numbers. We can use ctype_* because explode() returns strings
+ $log_data['addon_ids'] = array_filter($_ids, 'ctype_digit');
+ }
+
+ return $log_data;
+ }
+
+ /**
+ * Determines if an IP is from a Mozilla datacenter
+ */
+ function fromMozillaDatacenter($ip) {
+ global $datacenters;
+
+ if (empty($datacenters))
+ return false;
+
+ foreach ($datacenters as $geo => $datacenter_ips) {
+ foreach ($datacenter_ips as $datacenter_ip) {
+ if (strpos($ip, $datacenter_ip) !== false)
+ return $geo;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Called when finished parsing all logfiles to update counts in the database
+ */
+ function finish() {
+ echo "\n{$this->type} counted: {$this->counter->totalCounted}\n";
+ foreach ($this->counter->totalSkipped as $skipped => $count) {
+ echo "\tSkipped because of {$skipped}: {$count}\n";
+ }
+
+ $this->db->close();
+ }
+}
+
+?>
diff --git a/bin/parse_logs/parse_logs.php b/bin/parse_logs/parse_logs.php
new file mode 100644
index 0000000..c89bc20
--- /dev/null
+++ b/bin/parse_logs/parse_logs.php
@@ -0,0 +1,108 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Justin Scott <fligtar@mozilla.com> (Original Author)
+ * Andrei Hajdukewycz <sancus@off.net>
+ * Wil Clouser <wclouser@mozilla.com>
+ *
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/**
+ * AMO Log Parsing
+ * Call without paramaters for usage.
+ * Ex: php -f parse_logs.php
+ *
+ * This file handles the command-line script and starts up the
+ * parser for the real work, which then hands off to other classes
+ * for counting.
+ */
+
+$start = microtime();
+$start = explode(' ', $start);
+$start = $start[1] + $start[0];
+
+// Prevent running from the web
+if (isset($_SERVER['HTTP_HOST'])) {
+ exit;
+}
+
+// Include log parser class
+require_once('log_parser.class.php');
+
+// Arguments aren't always in $_GET in some environments
+if ($argv) {
+ for ($i = 1; $i < count($argv); $i++) {
+ $param = split('=', $argv[$i]);
+ $_GET[$param[0]] = $param[1];
+ }
+}
+
+$verbose = array_key_exists('v', $_GET);
+
+// Validate arguments
+if (!empty($_GET['logs']) && !empty($_GET['temp']) && !empty($_GET['type']) && !empty($_GET['geo'])) {
+ if (is_readable($_GET['logs']) && is_writable($_GET['temp'])) {
+ if (in_array($_GET['type'], array('collections', 'downloads', 'updatepings'))) {
+ $parser = new Log_Parser($_GET['logs'], $_GET['temp'], $_GET['type'], $_GET['geo'], !empty($_GET['date']) ? $_GET['date'] : '');
+ $parser->start();
+
+ $finished = true;
+ }
+ }
+ else
+ echo "ERROR: Could not read log dir and/or could not write to temp dir.\n\n";
+}
+
+if (empty($finished)) {
+ // Output usage instructions
+ print "usage:\n";
+ print "php -f parse_logs.php logs=[log_dir] temp=[tmp_dir] type=[parse_type] geo=[geo] date=[date] [v=v]\n";
+ print "\tlog_dir:\tDirectory with the access log files\n";
+ print "\ttmp_dir:\tDirectory for the temp file to be written\n";
+ print "\tparse_type:\tdownloads or updatepings or collections\n";
+ print "\tgeo:\tdatacenter from which logs are being parsed\n";
+ print "\tdate:\tsingle date for which to parse update pings, in YYYY-MM-DD format\n";
+ print "\tv:\tverbose output of progress\n";
+ print "sample usage:\n";
+ print "\tphp -f parse_logs.php logs=/data/addons.mozilla.org temp=/tmp type=updatepings date=`date --date='yesterday' +%Y-%m-%d` geo=CN v=v\n";
+}
+
+$end = microtime();
+$end = explode(' ', $end);
+$end = $end[1] + $end[0];
+
+echo "\nExecution time: ".($end - $start)."\n";
+
+?>
diff --git a/bin/reset_alpha.pl-default b/bin/reset_alpha.pl-default
new file mode 100755
index 0000000..891d795
--- /dev/null
+++ b/bin/reset_alpha.pl-default
@@ -0,0 +1,113 @@
+#! /usr/bin/perl -w
+
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is addons.mozilla.org site.
+#
+# The Initial Developer of the Original Code is
+# The Mozilla Foundation.
+# Portions created by the Initial Developer are Copyright (C) 2006
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+# Wil Clouser <clouserw@mozilla.com> (Original Author)
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+# This script is for the staging version of AMO 3 (remora). It will reset the
+# database and files to the defaults for our alpha version (a specific selection of
+# addons)
+#
+
+use DBI;
+use File::Path;
+
+sub fail_with_error;
+
+# Fill in the database information for $default from ../../site/app/config/database.php
+my $db_database = "";
+my $db_host = "";
+my $db_user = "";
+my $db_pass = "";
+
+# Other local variables - you shouldn't have to touch any of this.
+my $sql_file = "../../site/app/config/sql/remora_alpha_release.sql";
+my $addons_archive = "../../site/app/config/data/remora_alpha_addons.tar.gz";
+my $addons_directory = "../../site/app/webroot/files";
+
+# Sanity checks
+if (! -r $sql_file) {
+ fail_with_error("Couldn't read the sql file: $sql_file");
+}
+if (! -r $addons_archive) {
+ fail_with_error("Couldn't read the addons archive: $addons_archive");
+}
+if (! -w $addons_directory) {
+ fail_with_error("Couldn't write to the addon's directory: $addons_directory");
+}
+my $dbh = DBI->connect("dbi:mysql:$db_database:$db_host", "$db_user", "$db_pass")
+ or fail_with_error("Couldn't connect to database: $DBI::errstr");
+
+
+# Reset the database. We can't use Perl::DBI here because the "source" commands are
+# mysql specific, and will result in a parse error here. If putting the user/pass on
+# the command line is too big of a security risk, we'll open the file and walk
+# through it running the lines with Perl::DBI.
+my $sql_command = "mysql --user=$db_user --password=$db_pass --host=$db_host $db_database < $sql_file";
+if (system($sql_command) != 0) {
+ fail_with_error("Error replacing database: $?");
+}
+
+# Clear out all the files. We're walking through the directory this way because we
+# only want to remove the addon's directories, not anything else.
+opendir(ADDONS,$addons_directory);
+
+while(defined ($filename = readdir(ADDONS))) {
+ if ($filename =~ /(\d+)/) {
+ rmtree("$addons_directory/$filename");
+ }
+}
+
+closedir(ADDONS);
+
+# Untar default addons
+my $tar_command = "tar --extract --gunzip --directory $addons_directory --file $addons_archive";
+
+if (system($tar_command) != 0) {
+ fail_with_error("Error extracting addons: $?");
+}
+
+# done
+exit 0;
+
+
+# If something goes (fatally) wrong, call this subroutine with a helpful message.
+sub fail_with_error() {
+ my $message = shift;
+ print "$message\n";
+ print "Aborting.\n";
+ exit 1;
+}
diff --git a/bin/run_once/calculate_undated_totals.php b/bin/run_once/calculate_undated_totals.php
new file mode 100644
index 0000000..8f33d8e
--- /dev/null
+++ b/bin/run_once/calculate_undated_totals.php
@@ -0,0 +1,67 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Justin Scott <fligtar@mozilla.com> (Original Author)
+ *
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+// Prevent running from the web
+if (isset($_SERVER['HTTP_HOST'])) {
+ exit;
+}
+
+// Include class files
+require_once('../database.class.php');
+
+$db = new Database();
+
+$addon_qry = $db->read("SELECT id, totaldownloads FROM addons");
+
+while ($addon = mysql_fetch_array($addon_qry)) {
+ echo "# [Add-on {$addon['id']}]";
+ $sum_qry = $db->read("SELECT SUM(count) FROM download_counts WHERE addon_id={$addon['id']} AND date != '0000-00-00'");
+ $sum = mysql_fetch_array($sum_qry);
+ if ($sum[0] > 0) {
+ $undated = $addon['totaldownloads'] - $sum[0];
+ echo " {$addon['totaldownloads']} total - {$sum[0]} dated = {$undated} undated";
+ if ($undated > 0) {
+ //$db->write("INSERT INTO download_counts (addon_id, count, date) VALUES({$addon['id']}, $undated, '0000-00-00')");
+ echo "\nINSERT INTO download_counts (addon_id, count, date) VALUES({$addon['id']}, $undated, '0000-00-00');";
+ }
+ }
+ echo "\n";
+}
+
+?>
diff --git a/bin/run_once/combine_daily_downloads.php b/bin/run_once/combine_daily_downloads.php
new file mode 100644
index 0000000..34d9fa4
--- /dev/null
+++ b/bin/run_once/combine_daily_downloads.php
@@ -0,0 +1,69 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Justin Scott <fligtar@mozilla.com> (Original Author)
+ *
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+// Prevent running from the web
+if (isset($_SERVER['HTTP_HOST'])) {
+ exit;
+}
+
+// Include class files
+require_once('../database.class.php');
+
+$db = new Database();
+
+$addon_qry = $db->read("SELECT id FROM addons");
+
+while ($addon = mysql_fetch_array($addon_qry)) {
+ echo "[Add-on {$addon['id']}]";
+ $count_qry = $db->read("SELECT COUNT(*), date FROM download_counts WHERE addon_id={$addon['id']} GROUP BY date");
+ while ($count = mysql_fetch_array($count_qry)) {
+ if ($count[0] > 1) {
+ echo " ... {$count['date']} has {$count[0]} rows";
+ $sum_qry = $db->read("SELECT SUM(count) FROM download_counts WHERE addon_id={$addon['id']} AND date='{$count['date']}'");
+ $sum = mysql_fetch_array($sum_qry);
+
+ $db->write("DELETE FROM download_counts WHERE addon_id={$addon['id']} AND date='{$count['date']}'");
+ $db->write("INSERT INTO download_counts (addon_id, count, date) VALUES({$addon['id']}, $sum[0], '{$count['date']}')");
+ echo " - deleted rows and updated count to {$sum[0]}";
+ }
+ }
+ echo "\n";
+}
+
+?>
diff --git a/bin/run_once/delete_duplicate_daily_downloads.php b/bin/run_once/delete_duplicate_daily_downloads.php
new file mode 100644
index 0000000..136c8ea
--- /dev/null
+++ b/bin/run_once/delete_duplicate_daily_downloads.php
@@ -0,0 +1,78 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Justin Scott <fligtar@mozilla.com> (Original Author)
+ * Mike Morgan <morgamic@mozilla.com>
+ *
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+// Prevent running from the web
+if (isset($_SERVER['HTTP_HOST'])) {
+ exit;
+}
+
+// Include class files
+require_once('../database.class.php');
+
+$db = new Database();
+
+$addon_qry = $db->read("SELECT id FROM addons");
+
+$dates = array(
+ '2008-09-23',
+ '2008-09-24',
+ '2008-09-25',
+ '2008-09-26',
+ '2008-09-27',
+ '2008-09-28'
+);
+
+while ($addon = mysql_fetch_array($addon_qry)) {
+
+ foreach ($dates as $date) {
+ echo "[{$date} Add-on {$addon['id']}]";
+ $count_qry = $db->read("SELECT count(*), MIN(id) FROM download_counts WHERE addon_id={$addon['id']} AND date='{$date}'");
+ $count = mysql_fetch_array($count_qry);
+ if ($count[0] > 1) {
+ echo " ... {$date} has {$count[0]} rows on {$date}";
+ $db->write("DELETE FROM download_counts WHERE id > {$count[1]} AND addon_id={$addon['id']} AND date='{$date}'");
+ echo " - deleted duplicate rows";
+ } else {
+ echo " - is OK";
+ }
+ echo "\n";
+ }
+}
+?>
diff --git a/bin/run_once/fix_entities.php b/bin/run_once/fix_entities.php
new file mode 100644
index 0000000..75e0e29
--- /dev/null
+++ b/bin/run_once/fix_entities.php
@@ -0,0 +1,82 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Justin Scott <fligtar@mozilla.com> (Original Author)
+ *
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+// Prevent running from the web
+if (isset($_SERVER['HTTP_HOST'])) {
+ exit;
+}
+
+// Include class files
+require_once('../database.class.php');
+
+$db = new Database();
+
+$_translations = $db->read("SELECT * FROM translations WHERE localized_string LIKE '%&amp;%'");
+
+while ($translation = mysql_fetch_array($_translations)) {
+ echo "[Translation {$translation['id']} ({$translation['locale']})]";
+
+ $new = $translation['localized_string'];
+
+ // Many translations ended up like &amp;amp;amp;amp;umlaut;
+ while (strpos($new, '&amp;') !== false) {
+ $new = str_replace('&amp;', '&', $new);
+ }
+
+ $new = html_entity_decode($new);
+
+ // Some translations had HTMl code we don't want to inject
+ // <textarea> => &lt;textarea&gt; (we can't tell where the author had entities and where cake screwed stuff up)
+ $new = str_replace('<', '&lt;', $new);
+ $new = str_replace('>', '&gt;', $new);
+
+ $qry = "UPDATE translations SET localized_string='".mysql_real_escape_string($new)."' WHERE id={$translation['id']} AND locale='{$translation['locale']}' LIMIT 1";
+
+ if ($argv[1] == 'dryrun') {
+ echo "Query would be: [{$qry}]";
+ }
+ else {
+ $db->write($qry);
+ echo "Query run.";
+ }
+
+ echo "\n";
+}
+
+?>
diff --git a/bin/update-hashes.php b/bin/update-hashes.php
new file mode 100644
index 0000000..f7300d5
--- /dev/null
+++ b/bin/update-hashes.php
@@ -0,0 +1,123 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Mike Morgan <morgamic@mozilla.com>
+ * Justin Scott <fligtar@gmail.com>
+ * Reed Loden <reed@reedloden.com>
+ *
+ *
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/**
+ * The purpose of this script is to retro-actively update existing add-ons
+ * with valid hashes.
+ *
+ * We may not necessarily use this, but it was written just in case we need
+ * to run the update in the future.
+ *
+ * This script should not ever be accessed over HTTP, and instead run via cron.
+ * Only sysadmins should be responsible for operating this script.
+ *
+ * @package amo
+ * @subpackage bin
+ */
+
+
+// Before doing anything, test to see if we are calling this from the command
+// line. If this is being called from the web, HTTP environment variables will
+// be automatically set by Apache. If these are found, exit immediately.
+if (isset($_SERVER['HTTP_HOST'])) {
+ exit;
+}
+
+require_once('database.class.php');
+
+// New database class
+$db = new Database();
+
+$versions = array();
+$hashes = array();
+
+$fileQry_sql = "SELECT
+ addons.id as addon_id,
+ translations.localized_string as name,
+ versions.version,
+ files.id as file_id,
+ files.filename,
+ files.hash,
+ files.size
+ FROM files
+ INNER JOIN versions ON files.version_id=versions.id
+ INNER JOIN addons ON versions.addon_id=addons.id
+ INNER JOIN translations ON addons.name=translations.id
+ WHERE
+ translations.locale='en-US'";
+
+$fileQry_result = $db->read($fileQry_sql);
+
+while ($fileInfo = mysql_fetch_array($fileQry_result)) {
+
+ $file = REPO_PATH."/{$fileInfo['addon_id']}/{$fileInfo['filename']}";
+
+ // If the file exists, get its sum and update its record.
+ if (file_exists($file) && is_file($file)) {
+ $hash = hash_file("sha256", $file);
+ $size = round((filesize($file) / 1024), 0); //in KB
+
+ echo "{$fileInfo['name']} {$fileInfo['version']} (file {$fileInfo['file_id']}): ";
+ if ('sha256:'.$hash != $fileInfo['hash'] || $size != $fileInfo['size']) {
+ $hash_update_sql = "UPDATE files SET hash='sha256:{$hash}', size='{$size}' WHERE id={$fileInfo['file_id']}";
+ $hash_update_result = $db->write($hash_update_sql);
+
+ if ('sha256:'.$hash != $fileInfo['hash']) {
+ echo "HASH - new: sha256:{$hash}; old: {$fileInfo['hash']}";
+ }
+
+ if ($size != $fileInfo['size']) {
+ echo "SIZE - new: {$size} KB; old: {$fileInfo['size']} KB";
+ }
+ echo "\n";
+ }
+ else {
+ echo "No update needed.\n";
+ }
+ }
+}
+
+// Close our db connection
+$db->close();
+
+exit;
+?>
diff --git a/bin/update-search-views.php b/bin/update-search-views.php
new file mode 100644
index 0000000..f1ef504
--- /dev/null
+++ b/bin/update-search-views.php
@@ -0,0 +1,156 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Chris Pollett (cpollett@gmail.com)
+ * Mike Morgan <morgamic@mozilla.com>
+ * Justin Scott <fligtar@gmail.com>
+ *
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/**
+ * The script should be run as a cron job to periodically update the text_search_view
+ * and versions_most_recent view in the amo database.
+ *
+ * This script should not ever be accessed over HTTP, and instead run via cron.
+ * Only sysadmins should be responsible for operating this script.
+ *
+ * @package amo
+ * @subpackage bin
+ */
+
+
+// Before doing anything, test to see if we are calling this from the command
+// line. If this is being called from the web, HTTP environment variables will
+// be automatically set by Apache. If these are found, exit immediately.
+if (isset($_SERVER['HTTP_HOST'])) {
+ exit;
+}
+
+// If we get here, we're on the command line, which means we can continue.
+// Include config file
+require_once('../site/app/config/config.php');
+require_once('../site/app/config/constants.php');
+
+global $valid_status;
+
+/*
+ First, we set up an array of sql commands we will execute to update our two views that are used by search
+ In testing it seemed faster to delete the table completely and rebuild it rather than incrementally maintain it
+*/
+$sql_commands = array();
+$sql_commands[] = "BEGIN";
+$sql_commands[] = "DELETE FROM `text_search_summary`";
+
+$sql_commands[] = "INSERT INTO `text_search_summary`
+ SELECT a.id AS id,
+ `tr_name`.locale AS locale,
+ a.addontype_id AS addontype,
+ a.status AS status,
+ a.inactive AS inactive,
+ a.averagerating AS averagerating,
+ a.weeklydownloads AS weeklydownloads,
+ `tr_name`.localized_string AS name,
+ `tr_summary`.localized_string AS summary,
+ `tr_description`.localized_string AS description
+ FROM addons AS a
+ LEFT JOIN translations AS `tr_name` ON (`tr_name`.id = a.`name`)
+ LEFT JOIN translations AS `tr_summary` ON (`tr_summary`.id = a.`summary` AND `tr_name`.locale = `tr_summary`.locale)
+ LEFT JOIN translations AS `tr_description`
+ ON (`tr_description`.id = a.`description` AND `tr_name`.locale = `tr_description`.locale)
+ WHERE `tr_name`.locale IS NOT NULL AND (
+ `tr_name`.localized_string IS NOT NULL
+ OR `tr_summary`.localized_string IS NOT NULL
+ OR `tr_description`.localized_string IS NOT NULL
+ )
+ ORDER BY a.id ASC, locale DESC;";
+
+//the purpose of the temporary table is to get the most recently created version of an addon (avoiding sub-selects which are mysql 4 bad)
+$sql_commands[] = "DROP TABLE IF EXISTS `most_recent_version`"; //I am being paranoid to make sure temp table does not exist (it shouldn't by below)
+
+$sql_commands[] = "CREATE TEMPORARY TABLE `most_recent_version` (
+ `addon_id` int(11) NOT NULL,
+ `created` DATETIME NOT NULL
+ ) DEFAULT CHARSET=utf8";
+
+$sql_commands[] = "DELETE FROM `versions_summary`";
+
+$sql_commands[] = "INSERT INTO `most_recent_version`
+ SELECT DISTINCT v.addon_id, MAX(v.created)
+ FROM versions AS v
+ INNER JOIN files AS f ON (f.version_id = v.id AND f.status IN (".implode(',',$valid_status)."))
+ GROUP BY v.addon_id";
+
+
+$sql_commands[] = "INSERT INTO `versions_summary`
+ SELECT DISTINCT v.addon_id, v.id, av.application_id, v.created, v.modified, av.min, av.max
+ FROM (most_recent_version AS mrv NATURAL JOIN versions AS v) LEFT JOIN applications_versions AS av
+ ON (av.version_id = v.id )";
+
+$sql_commands[] = "DROP TABLE `most_recent_version`";
+
+$sql_commands[] = "DELETE FROM `collections_search_summary`";
+
+$sql_commands[] = "INSERT INTO `collections_search_summary`
+ SELECT `c`.`id` AS `id`,
+ `tr_name`.`locale` AS `locale`,
+ `tr_name`.`localized_string` AS `name`,
+ `tr_description`.`localized_string` AS `description`
+ FROM `collections` AS `c`
+ LEFT JOIN `translations` AS `tr_name` ON (`tr_name`.`id` = `c`.`name`)
+ LEFT JOIN `translations` AS `tr_description`
+ ON (`tr_description`.`id` = `c`.`description` AND `tr_name`.`locale` = `tr_description`.`locale`)
+ WHERE `tr_name`.`locale` IS NOT NULL AND (
+ `tr_name`.`localized_string` IS NOT NULL
+ OR `tr_description`.`localized_string` IS NOT NULL
+ )
+ ORDER BY `c`.`id` ASC, `locale` DESC";
+
+$sql_commands[] = "COMMIT";
+
+// Connect to our database and execute the command list above.
+
+$write = mysql_connect(DB_HOST, DB_USER, DB_PASS) or die('Could not connect: ' . mysql_error());
+mysql_select_db(DB_NAME, $write) or die('Could not select database '.DB_NAME);
+
+foreach($sql_commands as $sql_command) {
+ if(!mysql_query($sql_command)) {
+ mysql_query("ROLLBACK");
+ die("The update '$sql_command' failed: ".mysql_error());
+ }
+}
+
+mysql_close();
+exit;
+?>
diff --git a/bin/yuicompressor-2.3.4/build/yuicompressor-2.3.4.jar b/bin/yuicompressor-2.3.4/build/yuicompressor-2.3.4.jar
new file mode 100644
index 0000000..a247b62
--- /dev/null
+++ b/bin/yuicompressor-2.3.4/build/yuicompressor-2.3.4.jar
Binary files differ
diff --git a/bin/yuicompressor-2.3.4/doc/CHANGELOG b/bin/yuicompressor-2.3.4/doc/CHANGELOG
new file mode 100644
index 0000000..f522918
--- /dev/null
+++ b/bin/yuicompressor-2.3.4/doc/CHANGELOG
@@ -0,0 +1,186 @@
+YUI Compressor 2.3.4, 2008-02-07
+--------------------------------
+
++ Expanded the list of reserved words used by isValidIdentifier()
+
+YUI Compressor 2.3.3, 2008-02-04
+--------------------------------
+
++ C-style comments starting with /*! are preserved. This is especially
+ useful with comments containing copyright/license information.
+
+YUI Compressor 2.3.2, 2008-02-01
+--------------------------------
+
++ Compressing an empty JS file throws an error [SourceForge bug #1884207]
++ When a string is the first token in a function body, it was removed from
+ the compressed file [SourceForge bug #1884314]
+
+YUI Compressor 2.3.1, 2008-01-30
+--------------------------------
+
++ Added test against list of reserved words in method isValidIdentifier.
+
+YUI Compressor 2.3, 2008-01-28
+------------------------------
+
++ Always output a ';' at the end of a minified JavaScript file. This allows
+ the concatenating of several minified files without the fear of introducing
+ a syntax error.
++ Removed all System.exit() statements. Throw exceptions instead. This is
+ especially useful when running the compressor from within a J2EE container.
+ [SourceForge bug #1834750]
++ Transform obj["foo"] into obj.foo whenever possible, saving 3 bytes.
++ Transform 'foo': ... into foo: ... whenever possible, saving 2 bytes.
++ Added support for multi-line string literals [SourceForge bug #1871453]
++ Added support for unescaped slashes inside character classes in regexp.
++ Minor performance improvements.
++ Preserve the escaping for an octal representation of a character in string
+ literals [SourceForge bug #1844894]
+
+ var a = '\001';
+
++ CSS: Preserve comments that hide CSS rules from IE Mac:
+
+ /* Hides from IE-mac \*/
+ ...
+ /* End hide from IE-mac */
+
++ CSS: Added support for box model hack [SourceForge bug #1862107]
+
+ div.content {
+ width:400px;
+ voice-family: "\"}\"";
+ voice-family:inherit;
+ width:300px;
+ }
+
+YUI Compressor 2.2.5, 2007-10-09
+--------------------------------
+
++ Remove line terminator after escape in string literals.
+
+YUI Compressor 2.2.4, 2007-10-01
+--------------------------------
+
++ Fixed the way quote characters are counted in string literals
+ [SourceForge bug #1804576]
++ Do not use a regular expression using non-greedy matching to remove CSS
+ comments (if the comment is more than 800 characters long or so, a stack
+ overflow exception gets thrown) Instead, use good old parsing...
++ Fix unnecessary quote escaping in string literals.
+
+YUI Compressor 2.2.3, 2007-09-28
+--------------------------------
+
++ Transform </script into <\/script instead of replacing all </ into <\/.
++ Fixed bug related to the shortening of hexadecimal color codes (the string
+ "1px solid #aabbcc" became "1px solid#abc", missing a required white space)
++ Added --preserve-strings option to specify that concatenated string literals
+ should never be merged.
++ Do not convert \uXXXX and \xXX escape sequences to their unicode equivalent.
+
+YUI Compressor 2.2.2, 2007-09-27
+--------------------------------
+
++ Fixed regression related to the optimization of the amount of escaping
+ in string literals and the concatenation of string literals.
++ Modified the Rhino tokenizer to handle JScript conditional comments
+ natively (instead of hacking around the fact that Rhino is not keeping
+ track of comments)
++ Transform </ into <\/ in string literals. This is especially useful if the
+ code is written to a script block in an HTML document. This renders the old
+ hack '<scr'+'ipt ...><'+'/script>' completely useless.
++ When converting decimal rgb color values to hexadecimal color values,
+ prepend a '0' if the value is less than 16. Otherwise, rgb(0,124,114)
+ for instance becomes #07c72, which is incorrect.
++ In CSS files, do not change color names into their corresponding color
+ codes (and vice-versa) due to the high potential of introducing bugs
+ (rolled back from 2.2.1)
+
+YUI Compressor 2.2.1, 2007-09-25
+--------------------------------
+
++ Optimize quote escaping in JavaScript string literals by using the best quote
+ character (' or " depending on the occurrence of this character in the string)
++ Fixed minor bug in the CSS compressor. Colors should not be shortened in
+ filter: chroma(color="#FFFFFF");
+ Otherwise, it makes the filter break in Internet Explorer.
++ In CSS files, change color names into their corresponding color codes
+ (and vice-versa) if that change yields any savings.
+
+YUI Compressor 2.2, 2007-09-18
+------------------------------
+
++ Don't obfuscate function argument named $super if it is the first function
+ argument listed. This is to support Prototype 1.6's heretic implementation.
++ Added support for stdin/stdout (see README for more info)
++ Shorten colors from rgb(51,102,153) to #336699 in CSS files.
++ Shorten values from 0.8em to .8em in CSS files.
++ Added support for Internet Explorer's conditional comments in JavaScript
+ files. Note that the presence of a conditional comment inside a function
+ (i.e. not in the global scope) will reduce the level of compression for the
+ same reason the use of 'eval' or 'with' reduces the level of compression
+ (conditional comments, which do not get parsed, may refer to local variables,
+ which get obfuscated) In any case, the use of Internet Explorer's conditional
+ comment is to be avoided.
+
+YUI Compressor 2.1.2, 2007-08-31
+--------------------------------
+
++ Added --preserve-semi option
++ Modified --line-break option
+
+YUI Compressor 2.1.1, 2007-08-30
+--------------------------------
+
++ Fixed missing space in CSS background:url('foo.png')no-repeat
+ causing a background not to appear on Internet Explorer.
+
+YUI Compressor 2.1, 2007-08-29
+------------------------------
+
++ Pass the --line-break option to the CSS compressor.
++ Allow the output file to overwrite the input file (with version 2.0,
+ in this case, the output file was always empty)
++ Remove spaces before and after '(' and ')' as in background:url('xxx');
++ Merge (if possible) string literals that are appended in JavaScript files.
+ This not only makes the code smaller, it makes the code faster,
+ but allows you to maintain some readability in your source code.
++ Handle constructs such as a + ++ b or a + + "1" (in which case the
+ space between the operators must be kept!) and other similar cases...
++ Pass ErrorReporter instance to the constructor of class JavaScriptCompressor
+ (as suggested by David Bernard for his integration of the YUI Compressor
+ as a maven plugin)
+
+YUI Compressor 2.0, 2007-08-27
+------------------------------
+
++ Switched from Rhino 1.6R6 to Rhino 1.6R7
++ Integrated Isaac Schlueter's CSS compressor.
++ Refactored code to make it easier to use the compressor from a servlet
+ environment or another Java app (no need to pass in file names anymore)
++ Output a white-space character after 'throw' only when necessary.
++ Output a white-space character after 'break' and 'continue' when followed
+ by a label.
+
+YUI Compressor 1.1, 2007-08-20
+------------------------------
+
++ Java source now in package com.yahoo.platform.yui.compressor
++ Added --line-break option that adds a line feed character after each
+ semi-colon character (may help debugging with the MS Script debugger)
++ Added support for missing JavaScript features (get, set, const)
++ Do not show the entire stack trace when the input file cannot be found.
++ Removed the randomization of obfuscated symbols. When compressed code is
+ checked in CVS, unchanged files would otherwise end up being versioned.
++ Added web-based front-end to the YUI Compressor as part of the dist package.
++ Added a public entry point that makes the YUI Compressor easy to integrate
+ with an already existing Java application.
++ Simplified code by using the same parsing routines used to build the symbol
+ tree while looking for undeclared symbols.
++ Count how many times each identifier is used, and display a warning when an
+ identifier seems to be unused (code cannot safely be removed automatically)
++ Remove ';' when followed by a '}'. This yields an additional ~1.5% savings
+ on yahoo-dom-event.js compared to the JSMin version.
++ Output a white-space character after 'return' and 'case' only when necessary.
diff --git a/bin/yuicompressor-2.3.4/doc/README b/bin/yuicompressor-2.3.4/doc/README
new file mode 100644
index 0000000..8da3c6c
--- /dev/null
+++ b/bin/yuicompressor-2.3.4/doc/README
@@ -0,0 +1,135 @@
+==============================================================================
+YUI Compressor
+==============================================================================
+
+NAME
+
+ YUI Compressor - The Yahoo! JavaScript and CSS Compressor
+
+SYNOPSIS
+
+ Usage: java -jar yuicompressor-x.y.z.jar [options] [input file]
+
+ Global Options
+ -h, --help Displays this information
+ --type <js|css> Specifies the type of the input file
+ --charset <charset> Read the input file using <charset>
+ --line-break <column> Insert a line break after the specified column number
+ -v, --verbose Display informational messages and warnings
+ -o <file> Place the output into <file>. Defaults to stdout.
+
+ JavaScript Options
+ --nomunge Minify only, do not obfuscate
+ --preserve-semi Preserve all semicolons
+ --disable-optimizations Disable all micro optimizations
+
+DESCRIPTION
+
+ The YUI Compressor is a JavaScript compressor which, in addition to removing
+ comments and white-spaces, obfuscates local variables using the smallest
+ possible variable name. This obfuscation is safe, even when using constructs
+ such as 'eval' or 'with' (although the compression is not optimal is those
+ cases) Compared to jsmin, the average savings is around 20%.
+
+ The YUI Compressor is also able to safely compress CSS files. The decision
+ on which compressor is being used is made on the file extension (js or css)
+
+GLOBAL OPTIONS
+
+ -h, --help
+ Prints help on how to use the YUI Compressor
+
+ --line-break
+ Some source control tools don't like files containing lines longer than,
+ say 8000 characters. The linebreak option is used in that case to split
+ long lines after a specific column. It can also be used to make the code
+ more readable, easier to debug (especially with the MS Script Debugger)
+ Specify 0 to get a line break after each semi-colon in JavaScript, and
+ after each rule in CSS.
+
+ --type js|css
+ The type of compressor (JavaScript or CSS) is chosen based on the
+ extension of the input file name (.js or .css) This option is required
+ if no input file has been specified. Otherwise, this option is only
+ required if the input file extension is neither 'js' nor 'css'.
+
+ --charset character-set
+ If a supported character set is specified, the YUI Compressor will use it
+ to read the input file. Otherwise, it will assume that the platform's
+ default character set is being used. The output file is encoded using
+ the same character set.
+
+ -o outfile
+ Place output in file outfile. If not specified, the YUI Compressor will
+ default to the standard output, which you can redirect to a file.
+
+ -v, --verbose
+ Display informational messages and warnings.
+
+JAVASCRIPT ONLY OPTIONS
+
+ --nomunge
+ Minify only. Do not obfuscate local symbols.
+
+ --preserve-semi
+ Preserve unnecessary semicolons (such as right before a '}') This option
+ is useful when compressed code has to be run through JSLint (which is the
+ case of YUI for example)
+
+ --disable-optimizations
+ Disable all the built-in micro optimizations.
+
+NOTES
+
+ + If no input file is specified, it defaults to stdin.
+
+ + The YUI Compressor requires Java version >= 1.4.
+
+ + It is possible to prevent a local variable, nested function or function
+ argument from being obfuscated by using "hints". A hint is a string that
+ is located at the very beginning of a function body like so:
+
+ function fn (arg1, arg2, arg3) {
+ "arg2:nomunge, localVar:nomunge, nestedFn:nomunge";
+
+ ...
+ var localVar;
+ ...
+
+ function nestedFn () {
+ ....
+ }
+
+ ...
+ }
+
+ The hint itself disappears from the compressed file.
+
+ + C-style comments starting with /*! are preserved. This is useful with
+ comments containing copyright/license information. For example:
+
+ /*!
+ * TERMS OF USE - EASING EQUATIONS
+ * Open source under the BSD License.
+ * Copyright 2001 Robert Penner All rights reserved.
+ */
+
+ becomes:
+
+ /*
+ * TERMS OF USE - EASING EQUATIONS
+ * Open source under the BSD License.
+ * Copyright 2001 Robert Penner All rights reserved.
+ */
+
+AUTHOR
+
+ The YUI Compressor was written and is maintained by:
+ Julien Lecomte <jlecomte@yahoo-inc.com>
+ The CSS portion is a port of Isaac Schlueter's cssmin utility.
+
+COPYRIGHT
+
+ Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+ Code licensed under the BSD License:
+ http://developer.yahoo.net/yui/license.txt
diff --git a/bin/yuicompressor-2.3.4/lib/jargs-1.0.jar b/bin/yuicompressor-2.3.4/lib/jargs-1.0.jar
new file mode 100644
index 0000000..cdbc80b
--- /dev/null
+++ b/bin/yuicompressor-2.3.4/lib/jargs-1.0.jar
Binary files differ
diff --git a/bin/yuicompressor-2.3.4/lib/rhino-1.6R7.jar b/bin/yuicompressor-2.3.4/lib/rhino-1.6R7.jar
new file mode 100644
index 0000000..2e0d1e8
--- /dev/null
+++ b/bin/yuicompressor-2.3.4/lib/rhino-1.6R7.jar
Binary files differ
diff --git a/bin/yuicompressor-2.3.4/src/com/yahoo/platform/yui/compressor/CssCompressor.java b/bin/yuicompressor-2.3.4/src/com/yahoo/platform/yui/compressor/CssCompressor.java
new file mode 100644
index 0000000..f4cf89c
--- /dev/null
+++ b/bin/yuicompressor-2.3.4/src/com/yahoo/platform/yui/compressor/CssCompressor.java
@@ -0,0 +1,176 @@
+/*
+ * YUI Compressor
+ * Author: Julien Lecomte <jlecomte@yahoo-inc.com>
+ * Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+ * Code licensed under the BSD License:
+ * http://developer.yahoo.net/yui/license.txt
+ *
+ * This code is a port of Isaac Schlueter's cssmin utility.
+ */
+
+package com.yahoo.platform.yui.compressor;
+
+import java.io.IOException;
+import java.io.Reader;
+import java.io.Writer;
+import java.util.regex.Pattern;
+import java.util.regex.Matcher;
+
+public class CssCompressor {
+
+ private StringBuffer srcsb = new StringBuffer();
+
+ public CssCompressor(Reader in) throws IOException {
+ // Read the stream...
+ int c;
+ while ((c = in.read()) != -1) {
+ srcsb.append((char) c);
+ }
+ }
+
+ public void compress(Writer out, int linebreakpos)
+ throws IOException {
+
+ Pattern p;
+ Matcher m;
+ String css;
+ StringBuffer sb;
+ int startIndex, endIndex;
+
+ // Remove all comment blocks...
+ startIndex = 0;
+ boolean iemac = false;
+ sb = new StringBuffer(srcsb.toString());
+ while ((startIndex = sb.indexOf("/*", startIndex)) >= 0) {
+ endIndex = sb.indexOf("*/", startIndex + 2);
+ if (endIndex >= startIndex + 2) {
+ if (sb.charAt(endIndex-1) == '\\') {
+ // Looks like a comment to hide rules from IE Mac.
+ // Leave this comment, and the following one, alone...
+ startIndex = endIndex + 2;
+ iemac = true;
+ } else if (iemac) {
+ startIndex = endIndex + 2;
+ iemac = false;
+ } else {
+ sb.delete(startIndex, endIndex + 2);
+ }
+ }
+ }
+
+ css = sb.toString();
+
+ // Normalize all whitespace strings to single spaces. Easier to work with that way.
+ css = css.replaceAll("\\s+", " ");
+
+ // Make a pseudo class for the Box Model Hack
+ css = css.replaceAll("\"\\\\\"}\\\\\"\"", "___PSEUDOCLASSBMH___");
+
+ // Remove the spaces before the things that should not have spaces before them.
+ // But, be careful not to turn "p :link {...}" into "p:link{...}"
+ // Swap out any pseudo-class colons with the token, and then swap back.
+ sb = new StringBuffer();
+ p = Pattern.compile("(^|\\})(([^\\{:])+:)+([^\\{]*\\{)");
+ m = p.matcher(css);
+ while (m.find()) {
+ String s = m.group();
+ s = s.replaceAll(":", "___PSEUDOCLASSCOLON___");
+ m.appendReplacement(sb, s);
+ }
+ m.appendTail(sb);
+ css = sb.toString();
+ css = css.replaceAll("\\s+([!{};:>+\\(\\)\\],])", "$1");
+ css = css.replaceAll("___PSEUDOCLASSCOLON___", ":");
+
+ // Remove the spaces after the things that should not have spaces after them.
+ css = css.replaceAll("([!{}:;>+\\(\\[,])\\s+", "$1");
+
+ // Add the semicolon where it's missing.
+ css = css.replaceAll("([^;\\}])}", "$1;}");
+
+ // Replace 0(px,em,%) with 0.
+ css = css.replaceAll("([\\s:])(0)(px|em|%|in|cm|mm|pc|pt|ex)", "$1$2");
+
+ // Replace 0 0 0 0; with 0.
+ css = css.replaceAll(":0 0 0 0;", ":0;");
+ css = css.replaceAll(":0 0 0;", ":0;");
+ css = css.replaceAll(":0 0;", ":0;");
+ // Replace background-position:0; with background-position:0 0;
+ css = css.replaceAll("background-position:0;", "background-position:0 0;");
+
+ // Replace 0.6 to .6, but only when preceded by : or a white-space
+ css = css.replaceAll("(:|\\s)0+\\.(\\d+)", "$1.$2");
+
+ // Shorten colors from rgb(51,102,153) to #336699
+ // This makes it more likely that it'll get further compressed in the next step.
+ p = Pattern.compile("rgb\\s*\\(\\s*([0-9,\\s]+)\\s*\\)");
+ m = p.matcher(css);
+ sb = new StringBuffer();
+ while (m.find()) {
+ String[] rgbcolors = m.group(1).split(",");
+ StringBuffer hexcolor = new StringBuffer("#");
+ for (int i = 0; i < rgbcolors.length; i++) {
+ int val = Integer.parseInt(rgbcolors[i]);
+ if (val < 16) {
+ hexcolor.append("0");
+ }
+ hexcolor.append(Integer.toHexString(val));
+ }
+ m.appendReplacement(sb, hexcolor.toString());
+ }
+ m.appendTail(sb);
+ css = sb.toString();
+
+ // Shorten colors from #AABBCC to #ABC. Note that we want to make sure
+ // the color is not preceded by either ", " or =. Indeed, the property
+ // filter: chroma(color="#FFFFFF");
+ // would become
+ // filter: chroma(color="#FFF");
+ // which makes the filter break in IE.
+ p = Pattern.compile("([^\"'=\\s])(\\s*)#([0-9a-fA-F])([0-9a-fA-F])([0-9a-fA-F])([0-9a-fA-F])([0-9a-fA-F])([0-9a-fA-F])");
+ m = p.matcher(css);
+ sb = new StringBuffer();
+ while (m.find()) {
+ // Test for AABBCC pattern
+ if (m.group(3).equalsIgnoreCase(m.group(4)) &&
+ m.group(5).equalsIgnoreCase(m.group(6)) &&
+ m.group(7).equalsIgnoreCase(m.group(8))) {
+ m.appendReplacement(sb, m.group(1) + m.group(2) + "#" + m.group(3) + m.group(5) + m.group(7));
+ } else {
+ m.appendReplacement(sb, m.group());
+ }
+ }
+ m.appendTail(sb);
+ css = sb.toString();
+
+ // Remove empty rules.
+ css = css.replaceAll("[^\\}]+\\{;\\}", "");
+
+ if (linebreakpos >= 0) {
+ // Some source control tools don't like it when files containing lines longer
+ // than, say 8000 characters, are checked in. The linebreak option is used in
+ // that case to split long lines after a specific column.
+ int i = 0;
+ int linestartpos = 0;
+ sb = new StringBuffer(css);
+ while (i < sb.length()) {
+ char c = sb.charAt(i++);
+ if (c == '}' && i - linestartpos > linebreakpos) {
+ sb.insert(i, '\n');
+ linestartpos = i;
+ }
+ }
+
+ css = sb.toString();
+ }
+
+ // Replace the pseudo class for the Box Model Hack
+ css = css.replaceAll("___PSEUDOCLASSBMH___", "\"\\\\\"}\\\\\"\"");
+
+ // Trim the final string (for any leading or trailing white spaces)
+ css = css.trim();
+
+ // Write the output...
+ out.write(css);
+ }
+}
diff --git a/bin/yuicompressor-2.3.4/src/com/yahoo/platform/yui/compressor/JavaScriptCompressor.java b/bin/yuicompressor-2.3.4/src/com/yahoo/platform/yui/compressor/JavaScriptCompressor.java
new file mode 100644
index 0000000..88cfa59
--- /dev/null
+++ b/bin/yuicompressor-2.3.4/src/com/yahoo/platform/yui/compressor/JavaScriptCompressor.java
@@ -0,0 +1,1309 @@
+/*
+ * YUI Compressor
+ * Author: Julien Lecomte <jlecomte@yahoo-inc.com>
+ * Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+ * Code licensed under the BSD License:
+ * http://developer.yahoo.net/yui/license.txt
+ */
+
+package com.yahoo.platform.yui.compressor;
+
+import org.mozilla.javascript.*;
+
+import java.io.IOException;
+import java.io.Reader;
+import java.io.Writer;
+import java.util.*;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class JavaScriptCompressor {
+
+ static final ArrayList ones;
+ static final ArrayList twos;
+ static final ArrayList threes;
+
+ static final Set builtin = new HashSet();
+ static final Map literals = new Hashtable();
+ static final Set reserved = new HashSet();
+
+ static {
+
+ // This list contains all the 3 characters or less built-in global
+ // symbols available in a browser. Please add to this list if you
+ // see anything missing.
+ builtin.add("NaN");
+ builtin.add("top");
+
+ ones = new ArrayList();
+ for (char c = 'A'; c <= 'Z'; c++)
+ ones.add(Character.toString(c));
+ for (char c = 'a'; c <= 'z'; c++)
+ ones.add(Character.toString(c));
+
+ twos = new ArrayList();
+ for (int i = 0; i < ones.size(); i++) {
+ String one = (String) ones.get(i);
+ for (char c = 'A'; c <= 'Z'; c++)
+ twos.add(one + Character.toString(c));
+ for (char c = 'a'; c <= 'z'; c++)
+ twos.add(one + Character.toString(c));
+ for (char c = '0'; c <= '9'; c++)
+ twos.add(one + Character.toString(c));
+ }
+
+ // Remove two-letter JavaScript reserved words and built-in globals...
+ twos.remove("as");
+ twos.remove("is");
+ twos.remove("do");
+ twos.remove("if");
+ twos.remove("in");
+ twos.removeAll(builtin);
+
+ threes = new ArrayList();
+ for (int i = 0; i < twos.size(); i++) {
+ String two = (String) twos.get(i);
+ for (char c = 'A'; c <= 'Z'; c++)
+ threes.add(two + Character.toString(c));
+ for (char c = 'a'; c <= 'z'; c++)
+ threes.add(two + Character.toString(c));
+ for (char c = '0'; c <= '9'; c++)
+ threes.add(two + Character.toString(c));
+ }
+
+ // Remove three-letter JavaScript reserved words and built-in globals...
+ threes.remove("for");
+ threes.remove("int");
+ threes.remove("new");
+ threes.remove("try");
+ threes.remove("use");
+ threes.remove("var");
+ threes.removeAll(builtin);
+
+ // That's up to ((26+26)*(1+(26+26+10)))*(1+(26+26+10))-8
+ // (206,380 symbols per scope)
+
+ // The following list comes from org/mozilla/javascript/Decompiler.java...
+ literals.put(new Integer(Token.GET), "get ");
+ literals.put(new Integer(Token.SET), "set ");
+ literals.put(new Integer(Token.TRUE), "true");
+ literals.put(new Integer(Token.FALSE), "false");
+ literals.put(new Integer(Token.NULL), "null");
+ literals.put(new Integer(Token.THIS), "this");
+ literals.put(new Integer(Token.FUNCTION), "function ");
+ literals.put(new Integer(Token.COMMA), ",");
+ literals.put(new Integer(Token.LC), "{");
+ literals.put(new Integer(Token.RC), "}");
+ literals.put(new Integer(Token.LP), "(");
+ literals.put(new Integer(Token.RP), ")");
+ literals.put(new Integer(Token.LB), "[");
+ literals.put(new Integer(Token.RB), "]");
+ literals.put(new Integer(Token.DOT), ".");
+ literals.put(new Integer(Token.NEW), "new ");
+ literals.put(new Integer(Token.DELPROP), "delete ");
+ literals.put(new Integer(Token.IF), "if");
+ literals.put(new Integer(Token.ELSE), "else");
+ literals.put(new Integer(Token.FOR), "for");
+ literals.put(new Integer(Token.IN), " in ");
+ literals.put(new Integer(Token.WITH), "with");
+ literals.put(new Integer(Token.WHILE), "while");
+ literals.put(new Integer(Token.DO), "do");
+ literals.put(new Integer(Token.TRY), "try");
+ literals.put(new Integer(Token.CATCH), "catch");
+ literals.put(new Integer(Token.FINALLY), "finally");
+ literals.put(new Integer(Token.THROW), "throw ");
+ literals.put(new Integer(Token.SWITCH), "switch");
+ literals.put(new Integer(Token.BREAK), "break ");
+ literals.put(new Integer(Token.CONTINUE), "continue ");
+ literals.put(new Integer(Token.CASE), "case ");
+ literals.put(new Integer(Token.DEFAULT), "default");
+ literals.put(new Integer(Token.RETURN), "return ");
+ literals.put(new Integer(Token.VAR), "var ");
+ literals.put(new Integer(Token.SEMI), ";");
+ literals.put(new Integer(Token.ASSIGN), "=");
+ literals.put(new Integer(Token.ASSIGN_ADD), "+=");
+ literals.put(new Integer(Token.ASSIGN_SUB), "-=");
+ literals.put(new Integer(Token.ASSIGN_MUL), "*=");
+ literals.put(new Integer(Token.ASSIGN_DIV), "/=");
+ literals.put(new Integer(Token.ASSIGN_MOD), "%=");
+ literals.put(new Integer(Token.ASSIGN_BITOR), "|=");
+ literals.put(new Integer(Token.ASSIGN_BITXOR), "^=");
+ literals.put(new Integer(Token.ASSIGN_BITAND), "&=");
+ literals.put(new Integer(Token.ASSIGN_LSH), "<<=");
+ literals.put(new Integer(Token.ASSIGN_RSH), ">>=");
+ literals.put(new Integer(Token.ASSIGN_URSH), ">>>=");
+ literals.put(new Integer(Token.HOOK), "?");
+ literals.put(new Integer(Token.OBJECTLIT), ":");
+ literals.put(new Integer(Token.COLON), ":");
+ literals.put(new Integer(Token.OR), "||");
+ literals.put(new Integer(Token.AND), "&&");
+ literals.put(new Integer(Token.BITOR), "|");
+ literals.put(new Integer(Token.BITXOR), "^");
+ literals.put(new Integer(Token.BITAND), "&");
+ literals.put(new Integer(Token.SHEQ), "===");
+ literals.put(new Integer(Token.SHNE), "!==");
+ literals.put(new Integer(Token.EQ), "==");
+ literals.put(new Integer(Token.NE), "!=");
+ literals.put(new Integer(Token.LE), "<=");
+ literals.put(new Integer(Token.LT), "<");
+ literals.put(new Integer(Token.GE), ">=");
+ literals.put(new Integer(Token.GT), ">");
+ literals.put(new Integer(Token.INSTANCEOF), " instanceof ");
+ literals.put(new Integer(Token.LSH), "<<");
+ literals.put(new Integer(Token.RSH), ">>");
+ literals.put(new Integer(Token.URSH), ">>>");
+ literals.put(new Integer(Token.TYPEOF), "typeof ");
+ literals.put(new Integer(Token.VOID), "void ");
+ literals.put(new Integer(Token.CONST), "const ");
+ literals.put(new Integer(Token.NOT), "!");
+ literals.put(new Integer(Token.BITNOT), "~");
+ literals.put(new Integer(Token.POS), "+");
+ literals.put(new Integer(Token.NEG), "-");
+ literals.put(new Integer(Token.INC), "++");
+ literals.put(new Integer(Token.DEC), "--");
+ literals.put(new Integer(Token.ADD), "+");
+ literals.put(new Integer(Token.SUB), "-");
+ literals.put(new Integer(Token.MUL), "*");
+ literals.put(new Integer(Token.DIV), "/");
+ literals.put(new Integer(Token.MOD), "%");
+ literals.put(new Integer(Token.COLONCOLON), "::");
+ literals.put(new Integer(Token.DOTDOT), "..");
+ literals.put(new Integer(Token.DOTQUERY), ".(");
+ literals.put(new Integer(Token.XMLATTR), "@");
+
+ // See http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Reserved_Words
+
+ // JavaScript 1.5 reserved words
+ reserved.add("break");
+ reserved.add("case");
+ reserved.add("catch");
+ reserved.add("continue");
+ reserved.add("default");
+ reserved.add("delete");
+ reserved.add("do");
+ reserved.add("else");
+ reserved.add("finally");
+ reserved.add("for");
+ reserved.add("function");
+ reserved.add("if");
+ reserved.add("in");
+ reserved.add("instanceof");
+ reserved.add("new");
+ reserved.add("return");
+ reserved.add("switch");
+ reserved.add("this");
+ reserved.add("throw");
+ reserved.add("try");
+ reserved.add("typeof");
+ reserved.add("var");
+ reserved.add("void");
+ reserved.add("while");
+ reserved.add("with");
+ // Words reserved for future use
+ reserved.add("abstract");
+ reserved.add("boolean");
+ reserved.add("byte");
+ reserved.add("char");
+ reserved.add("class");
+ reserved.add("const");
+ reserved.add("debugger");
+ reserved.add("double");
+ reserved.add("enum");
+ reserved.add("export");
+ reserved.add("extends");
+ reserved.add("final");
+ reserved.add("float");
+ reserved.add("goto");
+ reserved.add("implements");
+ reserved.add("import");
+ reserved.add("int");
+ reserved.add("interface");
+ reserved.add("long");
+ reserved.add("native");
+ reserved.add("package");
+ reserved.add("private");
+ reserved.add("protected");
+ reserved.add("public");
+ reserved.add("short");
+ reserved.add("static");
+ reserved.add("super");
+ reserved.add("synchronized");
+ reserved.add("throws");
+ reserved.add("transient");
+ reserved.add("volatile");
+ // These are not reserved, but should be taken into account
+ // in isValidIdentifier (See jslint source code)
+ reserved.add("arguments");
+ reserved.add("eval");
+ reserved.add("true");
+ reserved.add("false");
+ reserved.add("Infinity");
+ reserved.add("NaN");
+ reserved.add("null");
+ reserved.add("undefined");
+ }
+
+ private static int countChar(String haystack, char needle) {
+ int idx = 0;
+ int count = 0;
+ int length = haystack.length();
+ while (idx < length) {
+ char c = haystack.charAt(idx++);
+ if (c == needle) {
+ count++;
+ }
+ }
+ return count;
+ }
+
+ private static int printSourceString(String source, int offset, StringBuffer sb) {
+ int length = source.charAt(offset);
+ ++offset;
+ if ((0x8000 & length) != 0) {
+ length = ((0x7FFF & length) << 16) | source.charAt(offset);
+ ++offset;
+ }
+ if (sb != null) {
+ String str = source.substring(offset, offset + length);
+ sb.append(str);
+ }
+ return offset + length;
+ }
+
+ private static int printSourceNumber(String source,
+ int offset, StringBuffer sb) {
+ double number = 0.0;
+ char type = source.charAt(offset);
+ ++offset;
+ if (type == 'S') {
+ if (sb != null) {
+ number = source.charAt(offset);
+ }
+ ++offset;
+ } else if (type == 'J' || type == 'D') {
+ if (sb != null) {
+ long lbits;
+ lbits = (long) source.charAt(offset) << 48;
+ lbits |= (long) source.charAt(offset + 1) << 32;
+ lbits |= (long) source.charAt(offset + 2) << 16;
+ lbits |= (long) source.charAt(offset + 3);
+ if (type == 'J') {
+ number = lbits;
+ } else {
+ number = Double.longBitsToDouble(lbits);
+ }
+ }
+ offset += 4;
+ } else {
+ // Bad source
+ throw new RuntimeException();
+ }
+ if (sb != null) {
+ sb.append(ScriptRuntime.numberToString(number, 10));
+ }
+ return offset;
+ }
+
+ private static ArrayList parse(Reader in, ErrorReporter reporter)
+ throws IOException, EvaluatorException {
+
+ CompilerEnvirons env = new CompilerEnvirons();
+ Parser parser = new Parser(env, reporter);
+ parser.parse(in, null, 1);
+ String source = parser.getEncodedSource();
+
+ int offset = 0;
+ int length = source.length();
+ ArrayList tokens = new ArrayList();
+ StringBuffer sb = new StringBuffer();
+
+ while (offset < length) {
+ int tt = source.charAt(offset++);
+ switch (tt) {
+
+ case Token.SPECIALCOMMENT:
+ case Token.NAME:
+ case Token.REGEXP:
+ case Token.STRING:
+ sb.setLength(0);
+ offset = printSourceString(source, offset, sb);
+ tokens.add(new JavaScriptToken(tt, sb.toString()));
+ break;
+
+ case Token.NUMBER:
+ sb.setLength(0);
+ offset = printSourceNumber(source, offset, sb);
+ tokens.add(new JavaScriptToken(tt, sb.toString()));
+ break;
+
+ default:
+ String literal = (String) literals.get(new Integer(tt));
+ if (literal != null) {
+ tokens.add(new JavaScriptToken(tt, literal));
+ }
+ break;
+ }
+ }
+
+ return tokens;
+ }
+
+ private static void processStringLiterals(ArrayList tokens, boolean merge) {
+
+ String tv;
+ int i, length = tokens.size();
+ JavaScriptToken token, prevToken, nextToken;
+
+ if (merge) {
+
+ // Concatenate string literals that are being appended wherever
+ // it is safe to do so. Note that we take care of the case:
+ // "a" + "b".toUpperCase()
+
+ for (i = 0; i < length; i++) {
+ token = (JavaScriptToken) tokens.get(i);
+ switch (token.getType()) {
+
+ case Token.ADD:
+ if (i > 0 && i < length) {
+ prevToken = (JavaScriptToken) tokens.get(i - 1);
+ nextToken = (JavaScriptToken) tokens.get(i + 1);
+ if (prevToken.getType() == Token.STRING && nextToken.getType() == Token.STRING &&
+ (i == length - 1 || ((JavaScriptToken) tokens.get(i + 2)).getType() != Token.DOT)) {
+ tokens.set(i - 1, new JavaScriptToken(Token.STRING,
+ prevToken.getValue() + nextToken.getValue()));
+ tokens.remove(i + 1);
+ tokens.remove(i);
+ i = i - 1;
+ length = length - 2;
+ break;
+ }
+ }
+ }
+ }
+
+ }
+
+ // Second pass...
+
+ for (i = 0; i < length; i++) {
+ token = (JavaScriptToken) tokens.get(i);
+ if (token.getType() == Token.STRING) {
+ tv = token.getValue();
+
+ // Finally, add the quoting characters and escape the string. We use
+ // the quoting character that minimizes the amount of escaping to save
+ // a few additional bytes.
+
+ char quotechar;
+ int singleQuoteCount = countChar(tv, '\'');
+ int doubleQuoteCount = countChar(tv, '"');
+ if (doubleQuoteCount <= singleQuoteCount) {
+ quotechar = '"';
+ } else {
+ quotechar = '\'';
+ }
+
+ tv = quotechar + escapeString(tv, quotechar) + quotechar;
+
+ // String concatenation transforms the old script scheme:
+ // '<scr'+'ipt ...><'+'/script>'
+ // into the following:
+ // '<script ...></script>'
+ // which breaks if this code is embedded inside an HTML document.
+ // Since this is not the right way to do this, let's fix the code by
+ // transforming all "</script" into "<\/script"
+
+ if (tv.indexOf("</script") >= 0) {
+ tv = tv.replaceAll("<\\/script", "<\\\\/script");
+ }
+
+ tokens.set(i, new JavaScriptToken(Token.STRING, tv));
+ }
+ }
+ }
+
+ // Add necessary escaping that was removed in Rhino's tokenizer.
+ private static String escapeString(String s, char quotechar) {
+
+ assert quotechar == '"' || quotechar == '\'';
+
+ if (s == null) {
+ return null;
+ }
+
+ StringBuffer sb = new StringBuffer();
+ for (int i = 0, L = s.length(); i < L; i++) {
+ int c = s.charAt(i);
+ if (c == quotechar) {
+ sb.append("\\");
+ }
+ sb.append((char) c);
+ }
+
+ return sb.toString();
+ }
+
+ /*
+ * Simple check to see whether a string is a valid identifier name.
+ * If a string matches this pattern, it means it IS a valid
+ * identifier name. If a string doesn't match it, it does not
+ * necessarily mean it is not a valid identifier name.
+ */
+ private static final Pattern SIMPLE_IDENTIFIER_NAME_PATTERN = Pattern.compile("^[a-zA-Z_][a-zA-Z0-9_]*$");
+
+ private static boolean isValidIdentifier(String s) {
+ Matcher m = SIMPLE_IDENTIFIER_NAME_PATTERN.matcher(s);
+ return (m.matches() && !reserved.contains(s));
+ }
+
+ /*
+ * Transforms obj["foo"] into obj.foo whenever possible, saving 3 bytes.
+ */
+ private static void optimizeObjectMemberAccess(ArrayList tokens) {
+
+ String tv;
+ int i, length;
+ JavaScriptToken token;
+
+ for (i = 0, length = tokens.size(); i < length; i++) {
+
+ if (((JavaScriptToken) tokens.get(i)).getType() == Token.LB &&
+ i > 0 && i < length - 2 &&
+ ((JavaScriptToken) tokens.get(i - 1)).getType() == Token.NAME &&
+ ((JavaScriptToken) tokens.get(i + 1)).getType() == Token.STRING &&
+ ((JavaScriptToken) tokens.get(i + 2)).getType() == Token.RB) {
+ token = (JavaScriptToken) tokens.get(i + 1);
+ tv = token.getValue();
+ tv = tv.substring(1, tv.length() - 1);
+ if (isValidIdentifier(tv)) {
+ tokens.set(i, new JavaScriptToken(Token.DOT, "."));
+ tokens.set(i + 1, new JavaScriptToken(Token.NAME, tv));
+ tokens.remove(i + 2);
+ i = i + 2;
+ length = length - 1;
+ }
+ }
+ }
+ }
+
+ /*
+ * Transforms 'foo': ... into foo: ... whenever possible, saving 2 bytes.
+ */
+ private static void optimizeObjLitMemberDecl(ArrayList tokens) {
+
+ String tv;
+ int i, length;
+ JavaScriptToken token;
+
+ for (i = 0, length = tokens.size(); i < length; i++) {
+ if (((JavaScriptToken) tokens.get(i)).getType() == Token.OBJECTLIT &&
+ i > 0 && ((JavaScriptToken) tokens.get(i - 1)).getType() == Token.STRING) {
+ token = (JavaScriptToken) tokens.get(i - 1);
+ tv = token.getValue();
+ tv = tv.substring(1, tv.length() - 1);
+ if (isValidIdentifier(tv)) {
+ tokens.set(i - 1, new JavaScriptToken(Token.NAME, tv));
+ }
+ }
+ }
+ }
+
+ private ErrorReporter logger;
+
+ private boolean munge;
+ private boolean verbose;
+
+ private static final int BUILDING_SYMBOL_TREE = 1;
+ private static final int CHECKING_SYMBOL_TREE = 2;
+
+ private int mode;
+ private int offset;
+ private int braceNesting;
+ private ArrayList tokens;
+ private Stack scopes = new Stack();
+ private ScriptOrFnScope globalScope = new ScriptOrFnScope(-1, null);
+ private Hashtable indexedScopes = new Hashtable();
+
+ public JavaScriptCompressor(Reader in, ErrorReporter reporter)
+ throws IOException, EvaluatorException {
+
+ this.logger = reporter;
+ this.tokens = parse(in, reporter);
+ }
+
+ public void compress(Writer out, int linebreak, boolean munge, boolean verbose,
+ boolean preserveAllSemiColons, boolean disableOptimizations)
+ throws IOException {
+
+ this.munge = munge;
+ this.verbose = verbose;
+
+ processStringLiterals(this.tokens, !disableOptimizations);
+
+ if (!disableOptimizations) {
+ optimizeObjectMemberAccess(this.tokens);
+ optimizeObjLitMemberDecl(this.tokens);
+ }
+
+ buildSymbolTree();
+ mungeSymboltree();
+ StringBuffer sb = printSymbolTree(linebreak, preserveAllSemiColons);
+
+ out.write(sb.toString());
+ }
+
+ private ScriptOrFnScope getCurrentScope() {
+ return (ScriptOrFnScope) scopes.peek();
+ }
+
+ private void enterScope(ScriptOrFnScope scope) {
+ scopes.push(scope);
+ }
+
+ private void leaveCurrentScope() {
+ scopes.pop();
+ }
+
+ private JavaScriptToken consumeToken() {
+ return (JavaScriptToken) tokens.get(offset++);
+ }
+
+ private JavaScriptToken getToken(int delta) {
+ return (JavaScriptToken) tokens.get(offset + delta);
+ }
+
+ /*
+ * Returns the identifier for the specified symbol defined in
+ * the specified scope or in any scope above it. Returns null
+ * if this symbol does not have a corresponding identifier.
+ */
+ private JavaScriptIdentifier getIdentifier(String symbol, ScriptOrFnScope scope) {
+ JavaScriptIdentifier identifier;
+ while (scope != null) {
+ identifier = scope.getIdentifier(symbol);
+ if (identifier != null) {
+ return identifier;
+ }
+ scope = scope.getParentScope();
+ }
+ return null;
+ }
+
+ /*
+ * If either 'eval' or 'with' is used in a local scope, we must make
+ * sure that all containing local scopes don't get munged. Otherwise,
+ * the obfuscation would potentially introduce bugs.
+ */
+ private void protectScopeFromObfuscation(ScriptOrFnScope scope) {
+ assert scope != null;
+
+ if (scope == globalScope) {
+ // The global scope does not get obfuscated,
+ // so we don't need to worry about it...
+ return;
+ }
+
+ // Find the highest local scope containing the specified scope.
+ while (scope.getParentScope() != globalScope) {
+ scope = scope.getParentScope();
+ }
+
+ assert scope.getParentScope() == globalScope;
+ scope.preventMunging();
+ }
+
+ private String getDebugString(int max) {
+ assert max > 0;
+ StringBuffer result = new StringBuffer();
+ int start = Math.max(offset - max, 0);
+ int end = Math.min(offset + max, tokens.size());
+ for (int i = start; i < end; i++) {
+ JavaScriptToken token = (JavaScriptToken) tokens.get(i);
+ if (i == offset - 1) {
+ result.append(" ---> ");
+ }
+ result.append(token.getValue());
+ if (i == offset - 1) {
+ result.append(" <--- ");
+ }
+ }
+ return result.toString();
+ }
+
+ private void warn(String message, boolean showDebugString) {
+ if (verbose) {
+ if (showDebugString) {
+ message = message + "\n" + getDebugString(10);
+ }
+ logger.warning(message, null, -1, null, -1);
+ }
+ }
+
+ private void parseFunctionDeclaration() {
+
+ String symbol;
+ JavaScriptToken token;
+ ScriptOrFnScope currentScope, fnScope;
+ JavaScriptIdentifier identifier;
+
+ currentScope = getCurrentScope();
+
+ token = consumeToken();
+ if (token.getType() == Token.NAME) {
+ if (mode == BUILDING_SYMBOL_TREE) {
+ // Get the name of the function and declare it in the current scope.
+ symbol = token.getValue();
+ if (currentScope.getIdentifier(symbol) != null) {
+ warn("The function " + symbol + " has already been declared in the same scope...", true);
+ }
+ currentScope.declareIdentifier(symbol);
+ }
+ token = consumeToken();
+ }
+
+ assert token.getType() == Token.LP;
+ if (mode == BUILDING_SYMBOL_TREE) {
+ fnScope = new ScriptOrFnScope(braceNesting, currentScope);
+ indexedScopes.put(new Integer(offset), fnScope);
+ } else {
+ fnScope = (ScriptOrFnScope) indexedScopes.get(new Integer(offset));
+ }
+
+ // Parse function arguments.
+ int argpos = 0;
+ while ((token = consumeToken()).getType() != Token.RP) {
+ assert token.getType() == Token.NAME ||
+ token.getType() == Token.COMMA;
+ if (token.getType() == Token.NAME && mode == BUILDING_SYMBOL_TREE) {
+ symbol = token.getValue();
+ identifier = fnScope.declareIdentifier(symbol);
+ if (symbol.equals("$super") && argpos == 0) {
+ // Exception for Prototype 1.6...
+ identifier.preventMunging();
+ }
+ argpos++;
+ }
+ }
+
+ token = consumeToken();
+ assert token.getType() == Token.LC;
+ braceNesting++;
+
+ token = getToken(0);
+ if (token.getType() == Token.STRING &&
+ getToken(1).getType() == Token.SEMI) {
+ // This is a hint. Hints are empty statements that look like
+ // "localvar1:nomunge, localvar2:nomunge"; They allow developers
+ // to prevent specific symbols from getting obfuscated (some heretic
+ // implementations, such as Prototype 1.6, require specific variable
+ // names, such as $super for example, in order to work appropriately.
+ // Note: right now, only "nomunge" is supported in the right hand side
+ // of a hint. However, in the future, the right hand side may contain
+ // other values.
+ consumeToken();
+ String hints = token.getValue();
+ // Remove the leading and trailing quotes...
+ hints = hints.substring(1, hints.length() - 1).trim();
+ StringTokenizer st1 = new StringTokenizer(hints, ",");
+ while (st1.hasMoreTokens()) {
+ String hint = st1.nextToken();
+ int idx = hint.indexOf(':');
+ if (idx <= 0 || idx >= hint.length() - 1) {
+ if (mode == BUILDING_SYMBOL_TREE) {
+ // No need to report the error twice, hence the test...
+ warn("Invalid hint syntax: " + hint, true);
+ }
+ break;
+ }
+ String variableName = hint.substring(0, idx).trim();
+ String variableType = hint.substring(idx + 1).trim();
+ if (mode == BUILDING_SYMBOL_TREE) {
+ fnScope.addHint(variableName, variableType);
+ } else if (mode == CHECKING_SYMBOL_TREE) {
+ identifier = fnScope.getIdentifier(variableName);
+ if (identifier != null) {
+ if (variableType.equals("nomunge")) {
+ identifier.preventMunging();
+ } else {
+ warn("Unsupported hint value: " + hint, true);
+ }
+ } else {
+ warn("Hint refers to an unknown identifier: " + hint, true);
+ }
+ }
+ }
+ }
+
+ parseScope(fnScope);
+ }
+
+ private void parseCatch() {
+
+ String symbol;
+ JavaScriptToken token;
+ ScriptOrFnScope currentScope;
+ JavaScriptIdentifier identifier;
+
+ token = getToken(-1);
+ assert token.getType() == Token.CATCH;
+ token = consumeToken();
+ assert token.getType() == Token.LP;
+ token = consumeToken();
+ assert token.getType() == Token.NAME;
+
+ symbol = token.getValue();
+ currentScope = getCurrentScope();
+
+ if (mode == BUILDING_SYMBOL_TREE) {
+ // We must declare the exception identifier in the containing function
+ // scope to avoid errors related to the obfuscation process. No need to
+ // display a warning if the symbol was already declared here...
+ currentScope.declareIdentifier(symbol);
+ } else {
+ identifier = getIdentifier(symbol, currentScope);
+ identifier.incrementRefcount();
+ }
+
+ token = consumeToken();
+ assert token.getType() == Token.RP;
+ }
+
+ private void parseExpression() {
+
+ // Parse the expression until we encounter a comma or a semi-colon
+ // in the same brace nesting, bracket nesting and paren nesting.
+ // Parse functions if any...
+
+ String symbol;
+ JavaScriptToken token;
+ ScriptOrFnScope currentScope;
+ JavaScriptIdentifier identifier;
+
+ int expressionBraceNesting = braceNesting;
+ int bracketNesting = 0;
+ int parensNesting = 0;
+
+ int length = tokens.size();
+
+ while (offset < length) {
+
+ token = consumeToken();
+ currentScope = getCurrentScope();
+
+ switch (token.getType()) {
+
+ case Token.SEMI:
+ case Token.COMMA:
+ if (braceNesting == expressionBraceNesting &&
+ bracketNesting == 0 &&
+ parensNesting == 0) {
+ return;
+ }
+ break;
+
+ case Token.FUNCTION:
+ parseFunctionDeclaration();
+ break;
+
+ case Token.LC:
+ braceNesting++;
+ break;
+
+ case Token.RC:
+ braceNesting--;
+ assert braceNesting >= expressionBraceNesting;
+ break;
+
+ case Token.LB:
+ bracketNesting++;
+ break;
+
+ case Token.RB:
+ bracketNesting--;
+ break;
+
+ case Token.LP:
+ parensNesting++;
+ break;
+
+ case Token.RP:
+ parensNesting--;
+ break;
+
+ case Token.SPECIALCOMMENT:
+ if (mode == BUILDING_SYMBOL_TREE) {
+ protectScopeFromObfuscation(currentScope);
+ warn("Using JScript conditional comments is not recommended." + (munge ? " Moreover, using JScript conditional comments reduces the level of compression!" : ""), true);
+ }
+ break;
+
+ case Token.NAME:
+ symbol = token.getValue();
+
+ if (mode == BUILDING_SYMBOL_TREE) {
+
+ if (symbol.equals("eval")) {
+
+ protectScopeFromObfuscation(currentScope);
+ warn("Using 'eval' is not recommended." + (munge ? " Moreover, using 'eval' reduces the level of compression!" : ""), true);
+
+ }
+
+ } else if (mode == CHECKING_SYMBOL_TREE) {
+
+ if ((offset < 2 ||
+ (getToken(-2).getType() != Token.DOT &&
+ getToken(-2).getType() != Token.GET &&
+ getToken(-2).getType() != Token.SET)) &&
+ getToken(0).getType() != Token.OBJECTLIT) {
+
+ identifier = getIdentifier(symbol, currentScope);
+
+ if (identifier == null) {
+
+ if (symbol.length() <= 3 && !builtin.contains(symbol)) {
+ // Here, we found an undeclared and un-namespaced symbol that is
+ // 3 characters or less in length. Declare it in the global scope.
+ // We don't need to declare longer symbols since they won't cause
+ // any conflict with other munged symbols.
+ globalScope.declareIdentifier(symbol);
+ warn("Found an undeclared symbol: " + symbol, true);
+ }
+
+ } else {
+
+ identifier.incrementRefcount();
+ }
+ }
+ }
+ break;
+ }
+ }
+ }
+
+ private void parseScope(ScriptOrFnScope scope) {
+
+ String symbol;
+ JavaScriptToken token;
+ JavaScriptIdentifier identifier;
+
+ int length = tokens.size();
+
+ enterScope(scope);
+
+ while (offset < length) {
+
+ token = consumeToken();
+
+ switch (token.getType()) {
+
+ case Token.VAR:
+ case Token.CONST:
+
+ // The var keyword is followed by at least one symbol name.
+ // If several symbols follow, they are comma separated.
+ for (; ;) {
+ token = consumeToken();
+
+ assert token.getType() == Token.NAME;
+
+ if (mode == BUILDING_SYMBOL_TREE) {
+ symbol = token.getValue();
+ if (scope.getIdentifier(symbol) == null) {
+ scope.declareIdentifier(symbol);
+ } else {
+ warn("The variable " + symbol + " has already been declared in the same scope...", true);
+ }
+ }
+
+ token = getToken(0);
+
+ assert token.getType() == Token.SEMI ||
+ token.getType() == Token.ASSIGN ||
+ token.getType() == Token.COMMA ||
+ token.getType() == Token.IN;
+
+ if (token.getType() == Token.IN) {
+ break;
+ } else {
+ parseExpression();
+ token = getToken(-1);
+ if (token.getType() == Token.SEMI) {
+ break;
+ }
+ }
+ }
+ break;
+
+ case Token.FUNCTION:
+ parseFunctionDeclaration();
+ break;
+
+ case Token.LC:
+ braceNesting++;
+ break;
+
+ case Token.RC:
+ braceNesting--;
+ assert braceNesting >= scope.getBraceNesting();
+ if (braceNesting == scope.getBraceNesting()) {
+ leaveCurrentScope();
+ return;
+ }
+ break;
+
+ case Token.WITH:
+ if (mode == BUILDING_SYMBOL_TREE) {
+ // Inside a 'with' block, it is impossible to figure out
+ // statically whether a symbol is a local variable or an
+ // object member. As a consequence, the only thing we can
+ // do is turn the obfuscation off for the highest scope
+ // containing the 'with' block.
+ protectScopeFromObfuscation(scope);
+ warn("Using 'with' is not recommended." + (munge ? " Moreover, using 'with' reduces the level of compression!" : ""), true);
+ }
+ break;
+
+ case Token.CATCH:
+ parseCatch();
+ break;
+
+ case Token.SPECIALCOMMENT:
+ if (mode == BUILDING_SYMBOL_TREE) {
+ protectScopeFromObfuscation(scope);
+ warn("Using JScript conditional comments is not recommended." + (munge ? " Moreover, using JScript conditional comments reduces the level of compression." : ""), true);
+ }
+ break;
+
+ case Token.NAME:
+ symbol = token.getValue();
+
+ if (mode == BUILDING_SYMBOL_TREE) {
+
+ if (symbol.equals("eval")) {
+
+ protectScopeFromObfuscation(scope);
+ warn("Using 'eval' is not recommended." + (munge ? " Moreover, using 'eval' reduces the level of compression!" : ""), true);
+
+ }
+
+ } else if (mode == CHECKING_SYMBOL_TREE) {
+
+ if ((offset < 2 || getToken(-2).getType() != Token.DOT) &&
+ getToken(0).getType() != Token.OBJECTLIT) {
+
+ identifier = getIdentifier(symbol, scope);
+
+ if (identifier == null) {
+
+ if (symbol.length() <= 3 && !builtin.contains(symbol)) {
+ // Here, we found an undeclared and un-namespaced symbol that is
+ // 3 characters or less in length. Declare it in the global scope.
+ // We don't need to declare longer symbols since they won't cause
+ // any conflict with other munged symbols.
+ globalScope.declareIdentifier(symbol);
+ warn("Found an undeclared symbol: " + symbol, true);
+ }
+
+ } else {
+
+ identifier.incrementRefcount();
+ }
+ }
+ }
+ break;
+ }
+ }
+ }
+
+ private void buildSymbolTree() {
+ offset = 0;
+ braceNesting = 0;
+ scopes.clear();
+ indexedScopes.clear();
+ indexedScopes.put(new Integer(0), globalScope);
+ mode = BUILDING_SYMBOL_TREE;
+ parseScope(globalScope);
+ }
+
+ private void mungeSymboltree() {
+
+ if (!munge) {
+ return;
+ }
+
+ // One problem with obfuscation resides in the use of undeclared
+ // and un-namespaced global symbols that are 3 characters or less
+ // in length. Here is an example:
+ //
+ // var declaredGlobalVar;
+ //
+ // function declaredGlobalFn() {
+ // var localvar;
+ // localvar = abc; // abc is an undeclared global symbol
+ // }
+ //
+ // In the example above, there is a slim chance that localvar may be
+ // munged to 'abc', conflicting with the undeclared global symbol
+ // abc, creating a potential bug. The following code detects such
+ // global symbols. This must be done AFTER the entire file has been
+ // parsed, and BEFORE munging the symbol tree. Note that declaring
+ // extra symbols in the global scope won't hurt.
+ //
+ // Note: Since we go through all the tokens to do this, we also use
+ // the opportunity to count how many times each identifier is used.
+
+ offset = 0;
+ braceNesting = 0;
+ scopes.clear();
+ mode = CHECKING_SYMBOL_TREE;
+ parseScope(globalScope);
+ globalScope.munge();
+ }
+
+ private StringBuffer printSymbolTree(int linebreakpos, boolean preserveAllSemiColons)
+ throws IOException {
+
+ offset = 0;
+ braceNesting = 0;
+ scopes.clear();
+
+ String symbol;
+ JavaScriptToken token;
+ ScriptOrFnScope currentScope;
+ JavaScriptIdentifier identifier;
+
+ int length = tokens.size();
+ StringBuffer result = new StringBuffer();
+
+ int linestartpos = 0;
+
+ enterScope(globalScope);
+
+ while (offset < length) {
+
+ token = consumeToken();
+ symbol = token.getValue();
+ currentScope = getCurrentScope();
+
+ switch (token.getType()) {
+
+ case Token.NAME:
+
+ if (offset >= 2 && getToken(-2).getType() == Token.DOT ||
+ getToken(0).getType() == Token.OBJECTLIT) {
+
+ result.append(symbol);
+
+ } else {
+
+ identifier = getIdentifier(symbol, currentScope);
+ if (identifier != null) {
+ if (identifier.getMungedValue() != null) {
+ result.append(identifier.getMungedValue());
+ } else {
+ result.append(symbol);
+ }
+ if (currentScope != globalScope && identifier.getRefcount() == 0) {
+ warn("The symbol " + symbol + " is declared but is apparently never used.\nThis code can probably be written in a more efficient way.", true);
+ }
+ } else {
+ result.append(symbol);
+ }
+ }
+ break;
+
+ case Token.REGEXP:
+ case Token.NUMBER:
+ case Token.STRING:
+ result.append(symbol);
+ break;
+
+ case Token.ADD:
+ case Token.SUB:
+ result.append((String) literals.get(new Integer(token.getType())));
+ if (offset < length) {
+ token = getToken(0);
+ if (token.getType() == Token.INC ||
+ token.getType() == Token.DEC ||
+ token.getType() == Token.ADD ||
+ token.getType() == Token.DEC) {
+ // Handle the case x +/- ++/-- y
+ // We must keep a white space here. Otherwise, x +++ y would be
+ // interpreted as x ++ + y by the compiler, which is a bug (due
+ // to the implicit assignment being done on the wrong variable)
+ result.append(' ');
+ } else if (token.getType() == Token.POS && getToken(-1).getType() == Token.ADD ||
+ token.getType() == Token.NEG && getToken(-1).getType() == Token.SUB) {
+ // Handle the case x + + y and x - - y
+ result.append(' ');
+ }
+ }
+ break;
+
+ case Token.FUNCTION:
+ result.append("function");
+ token = consumeToken();
+ if (token.getType() == Token.NAME) {
+ result.append(' ');
+ symbol = token.getValue();
+ identifier = getIdentifier(symbol, currentScope);
+ assert identifier != null;
+ if (identifier.getMungedValue() != null) {
+ result.append(identifier.getMungedValue());
+ } else {
+ result.append(symbol);
+ }
+ if (currentScope != globalScope && identifier.getRefcount() == 0) {
+ warn("The symbol " + symbol + " is declared but is apparently never used.\nThis code can probably be written in a more efficient way.", true);
+ }
+ token = consumeToken();
+ }
+ assert token.getType() == Token.LP;
+ result.append('(');
+ currentScope = (ScriptOrFnScope) indexedScopes.get(new Integer(offset));
+ enterScope(currentScope);
+ while ((token = consumeToken()).getType() != Token.RP) {
+ assert token.getType() == Token.NAME || token.getType() == Token.COMMA;
+ if (token.getType() == Token.NAME) {
+ symbol = token.getValue();
+ identifier = getIdentifier(symbol, currentScope);
+ assert identifier != null;
+ if (identifier.getMungedValue() != null) {
+ result.append(identifier.getMungedValue());
+ } else {
+ result.append(symbol);
+ }
+ } else if (token.getType() == Token.COMMA) {
+ result.append(',');
+ }
+ }
+ result.append(')');
+ token = consumeToken();
+ assert token.getType() == Token.LC;
+ result.append('{');
+ braceNesting++;
+ token = getToken(0);
+ if (token.getType() == Token.STRING &&
+ getToken(1).getType() == Token.SEMI) {
+ // This is a hint. Skip it!
+ consumeToken();
+ consumeToken();
+ }
+ break;
+
+ case Token.RETURN:
+ result.append("return");
+ // No space needed after 'return' when followed
+ // by '(', '[', '{', a string or a regexp.
+ if (offset < length) {
+ token = getToken(0);
+ if (token.getType() != Token.LP &&
+ token.getType() != Token.LB &&
+ token.getType() != Token.LC &&
+ token.getType() != Token.STRING &&
+ token.getType() != Token.REGEXP) {
+ result.append(' ');
+ }
+ }
+ break;
+
+ case Token.CASE:
+ result.append("case");
+ // White-space needed after 'case' when not followed by a string.
+ if (offset < length && getToken(0).getType() != Token.STRING) {
+ result.append(' ');
+ }
+ break;
+
+ case Token.THROW:
+ // White-space needed after 'throw' when not followed by a string.
+ result.append("throw");
+ if (offset < length && getToken(0).getType() != Token.STRING) {
+ result.append(' ');
+ }
+ break;
+
+ case Token.BREAK:
+ result.append("break");
+ if (offset < length && getToken(0).getType() != Token.SEMI) {
+ // If 'break' is not followed by a semi-colon, it must be
+ // followed by a label, hence the need for a white space.
+ result.append(' ');
+ }
+ break;
+
+ case Token.CONTINUE:
+ result.append("continue");
+ if (offset < length && getToken(0).getType() != Token.SEMI) {
+ // If 'continue' is not followed by a semi-colon, it must be
+ // followed by a label, hence the need for a white space.
+ result.append(' ');
+ }
+ break;
+
+ case Token.LC:
+ result.append('{');
+ braceNesting++;
+ break;
+
+ case Token.RC:
+ result.append('}');
+ braceNesting--;
+ assert braceNesting >= currentScope.getBraceNesting();
+ if (braceNesting == currentScope.getBraceNesting()) {
+ leaveCurrentScope();
+ }
+ break;
+
+ case Token.SEMI:
+ // No need to output a semi-colon if the next character is a right-curly...
+ if (preserveAllSemiColons || offset < length && getToken(0).getType() != Token.RC) {
+ result.append(';');
+ }
+
+ if (linebreakpos >= 0 && result.length() - linestartpos > linebreakpos) {
+ // Some source control tools don't like it when files containing lines longer
+ // than, say 8000 characters, are checked in. The linebreak option is used in
+ // that case to split long lines after a specific column.
+ result.append('\n');
+ linestartpos = result.length();
+ }
+ break;
+
+ case Token.SPECIALCOMMENT:
+ if (result.length() > 0 && result.charAt(result.length() - 1) != '\n') {
+ result.append("\n");
+ }
+ result.append("/*");
+ result.append(symbol);
+ result.append("*/\n");
+ break;
+
+ default:
+ String literal = (String) literals.get(new Integer(token.getType()));
+ if (literal != null) {
+ result.append(literal);
+ } else {
+ warn("This symbol cannot be printed: " + symbol, true);
+ }
+ break;
+ }
+ }
+
+ // Append a semi-colon at the end, even if unnecessary semi-colons are
+ // supposed to be removed. This is especially useful when concatenating
+ // several minified files (the absence of an ending semi-colon at the
+ // end of one file may very likely cause a syntax error)
+ if (!preserveAllSemiColons && result.length() > 0) {
+ if (result.charAt(result.length() - 1) == '\n') {
+ result.setCharAt(result.length() - 1, ';');
+ } else {
+ result.append(';');
+ }
+ }
+
+ return result;
+ }
+}
diff --git a/bin/yuicompressor-2.3.4/src/com/yahoo/platform/yui/compressor/JavaScriptIdentifier.java b/bin/yuicompressor-2.3.4/src/com/yahoo/platform/yui/compressor/JavaScriptIdentifier.java
new file mode 100644
index 0000000..127fe23
--- /dev/null
+++ b/bin/yuicompressor-2.3.4/src/com/yahoo/platform/yui/compressor/JavaScriptIdentifier.java
@@ -0,0 +1,55 @@
+/*
+ * YUI Compressor
+ * Author: Julien Lecomte <jlecomte@yahoo-inc.com>
+ * Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+ * Code licensed under the BSD License:
+ * http://developer.yahoo.net/yui/license.txt
+ */
+
+package com.yahoo.platform.yui.compressor;
+
+import org.mozilla.javascript.Token;
+
+/**
+ * JavaScriptIdentifier represents a variable/function identifier.
+ */
+class JavaScriptIdentifier extends JavaScriptToken {
+
+ private int refcount = 0;
+ private String mungedValue;
+ private ScriptOrFnScope declaredScope;
+ private boolean markedForMunging = true;
+
+ JavaScriptIdentifier(String value, ScriptOrFnScope declaredScope) {
+ super(Token.NAME, value);
+ this.declaredScope = declaredScope;
+ }
+
+ ScriptOrFnScope getDeclaredScope() {
+ return declaredScope;
+ }
+
+ void setMungedValue(String value) {
+ mungedValue = value;
+ }
+
+ String getMungedValue() {
+ return mungedValue;
+ }
+
+ void preventMunging() {
+ markedForMunging = false;
+ }
+
+ boolean isMarkedForMunging() {
+ return markedForMunging;
+ }
+
+ void incrementRefcount() {
+ refcount++;
+ }
+
+ int getRefcount() {
+ return refcount;
+ }
+}
diff --git a/bin/yuicompressor-2.3.4/src/com/yahoo/platform/yui/compressor/JavaScriptToken.java b/bin/yuicompressor-2.3.4/src/com/yahoo/platform/yui/compressor/JavaScriptToken.java
new file mode 100644
index 0000000..fee21d9
--- /dev/null
+++ b/bin/yuicompressor-2.3.4/src/com/yahoo/platform/yui/compressor/JavaScriptToken.java
@@ -0,0 +1,28 @@
+/*
+ * YUI Compressor
+ * Author: Julien Lecomte <jlecomte@yahoo-inc.com>
+ * Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+ * Code licensed under the BSD License:
+ * http://developer.yahoo.net/yui/license.txt
+ */
+
+package com.yahoo.platform.yui.compressor;
+
+public class JavaScriptToken {
+
+ private int type;
+ private String value;
+
+ JavaScriptToken(int type, String value) {
+ this.type = type;
+ this.value = value;
+ }
+
+ int getType() {
+ return type;
+ }
+
+ String getValue() {
+ return value;
+ }
+}
diff --git a/bin/yuicompressor-2.3.4/src/com/yahoo/platform/yui/compressor/ScriptOrFnScope.java b/bin/yuicompressor-2.3.4/src/com/yahoo/platform/yui/compressor/ScriptOrFnScope.java
new file mode 100644
index 0000000..c338e21
--- /dev/null
+++ b/bin/yuicompressor-2.3.4/src/com/yahoo/platform/yui/compressor/ScriptOrFnScope.java
@@ -0,0 +1,154 @@
+/*
+ * YUI Compressor
+ * Author: Julien Lecomte <jlecomte@yahoo-inc.com>
+ * Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+ * Code licensed under the BSD License:
+ * http://developer.yahoo.net/yui/license.txt
+ */
+
+package com.yahoo.platform.yui.compressor;
+
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.Hashtable;
+
+class ScriptOrFnScope {
+
+ private int braceNesting;
+ private ScriptOrFnScope parentScope;
+ private ArrayList subScopes;
+ private Hashtable identifiers = new Hashtable();
+ private Hashtable hints = new Hashtable();
+ private boolean markedForMunging = true;
+
+ ScriptOrFnScope(int braceNesting, ScriptOrFnScope parentScope) {
+ this.braceNesting = braceNesting;
+ this.parentScope = parentScope;
+ this.subScopes = new ArrayList();
+ if (parentScope != null) {
+ parentScope.subScopes.add(this);
+ }
+ }
+
+ int getBraceNesting() {
+ return braceNesting;
+ }
+
+ ScriptOrFnScope getParentScope() {
+ return parentScope;
+ }
+
+ JavaScriptIdentifier declareIdentifier(String symbol) {
+ JavaScriptIdentifier identifier = (JavaScriptIdentifier) identifiers.get(symbol);
+ if (identifier == null) {
+ identifier = new JavaScriptIdentifier(symbol, this);
+ identifiers.put(symbol, identifier);
+ }
+ return identifier;
+ }
+
+ JavaScriptIdentifier getIdentifier(String symbol) {
+ return (JavaScriptIdentifier) identifiers.get(symbol);
+ }
+
+ void addHint(String variableName, String variableType) {
+ hints.put(variableName, variableType);
+ }
+
+ void preventMunging() {
+ if (parentScope != null) {
+ // The symbols in the global scope don't get munged,
+ // but the sub-scopes it contains do get munged.
+ markedForMunging = false;
+ }
+ }
+
+ private ArrayList getUsedSymbols() {
+ ArrayList result = new ArrayList();
+ Enumeration elements = identifiers.elements();
+ while (elements.hasMoreElements()) {
+ JavaScriptIdentifier identifier = (JavaScriptIdentifier) elements.nextElement();
+ String mungedValue = identifier.getMungedValue();
+ if (mungedValue == null) {
+ mungedValue = identifier.getValue();
+ }
+ result.add(mungedValue);
+ }
+ return result;
+ }
+
+ private ArrayList getAllUsedSymbols() {
+ ArrayList result = new ArrayList();
+ ScriptOrFnScope scope = this;
+ while (scope != null) {
+ result.addAll(scope.getUsedSymbols());
+ scope = scope.parentScope;
+ }
+ return result;
+ }
+
+ void munge() {
+
+ if (!markedForMunging) {
+ // Stop right here if this scope was flagged as unsafe for munging.
+ return;
+ }
+
+ int pickFromSet = 1;
+
+ // Do not munge symbols in the global scope!
+ if (parentScope != null) {
+
+ ArrayList freeSymbols = new ArrayList();
+
+ freeSymbols.addAll(JavaScriptCompressor.ones);
+ freeSymbols.removeAll(getAllUsedSymbols());
+ if (freeSymbols.size() == 0) {
+ pickFromSet = 2;
+ freeSymbols.addAll(JavaScriptCompressor.twos);
+ freeSymbols.removeAll(getAllUsedSymbols());
+ }
+ if (freeSymbols.size() == 0) {
+ pickFromSet = 3;
+ freeSymbols.addAll(JavaScriptCompressor.threes);
+ freeSymbols.removeAll(getAllUsedSymbols());
+ }
+ if (freeSymbols.size() == 0) {
+ throw new IllegalStateException("The YUI Compressor ran out of symbols. Aborting...");
+ }
+
+ Enumeration elements = identifiers.elements();
+ while (elements.hasMoreElements()) {
+ if (freeSymbols.size() == 0) {
+ pickFromSet++;
+ if (pickFromSet == 2) {
+ freeSymbols.addAll(JavaScriptCompressor.twos);
+ } else if (pickFromSet == 3) {
+ freeSymbols.addAll(JavaScriptCompressor.threes);
+ } else {
+ throw new IllegalStateException("The YUI Compressor ran out of symbols. Aborting...");
+ }
+ // It is essential to remove the symbols already used in
+ // the containing scopes, or some of the variables declared
+ // in the containing scopes will be redeclared, which can
+ // lead to errors.
+ freeSymbols.removeAll(getAllUsedSymbols());
+ }
+
+ String mungedValue;
+ JavaScriptIdentifier identifier = (JavaScriptIdentifier) elements.nextElement();
+ if (identifier.isMarkedForMunging()) {
+ mungedValue = (String) freeSymbols.remove(0);
+ } else {
+ mungedValue = identifier.getValue();
+ }
+ identifier.setMungedValue(mungedValue);
+ }
+ }
+
+ for (int i = 0; i < subScopes.size(); i++) {
+ ScriptOrFnScope scope = (ScriptOrFnScope) subScopes.get(i);
+ scope.munge();
+ }
+ }
+}
diff --git a/bin/yuicompressor-2.3.4/src/com/yahoo/platform/yui/compressor/YUICompressor.java b/bin/yuicompressor-2.3.4/src/com/yahoo/platform/yui/compressor/YUICompressor.java
new file mode 100644
index 0000000..f4ee010
--- /dev/null
+++ b/bin/yuicompressor-2.3.4/src/com/yahoo/platform/yui/compressor/YUICompressor.java
@@ -0,0 +1,240 @@
+/*
+ * YUI Compressor
+ * Author: Julien Lecomte <jlecomte@yahoo-inc.com>
+ * Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+ * Code licensed under the BSD License:
+ * http://developer.yahoo.net/yui/license.txt
+ */
+
+package com.yahoo.platform.yui.compressor;
+
+import jargs.gnu.CmdLineParser;
+import org.mozilla.javascript.ErrorReporter;
+import org.mozilla.javascript.EvaluatorException;
+
+import java.io.*;
+import java.nio.charset.Charset;
+
+public class YUICompressor {
+
+ public static void main(String args[]) {
+
+ CmdLineParser parser = new CmdLineParser();
+ CmdLineParser.Option typeOpt = parser.addStringOption("type");
+ CmdLineParser.Option verboseOpt = parser.addBooleanOption('v', "verbose");
+ CmdLineParser.Option nomungeOpt = parser.addBooleanOption("nomunge");
+ CmdLineParser.Option linebreakOpt = parser.addStringOption("line-break");
+ CmdLineParser.Option preserveSemiOpt = parser.addBooleanOption("preserve-semi");
+ CmdLineParser.Option disableOptimizationsOpt = parser.addBooleanOption("disable-optimizations");
+ CmdLineParser.Option helpOpt = parser.addBooleanOption('h', "help");
+ CmdLineParser.Option charsetOpt = parser.addStringOption("charset");
+ CmdLineParser.Option outputFilenameOpt = parser.addStringOption('o', "output");
+
+ Reader in = null;
+ Writer out = null;
+
+ try {
+
+ parser.parse(args);
+
+ Boolean help = (Boolean) parser.getOptionValue(helpOpt);
+ if (help != null && help.booleanValue()) {
+ usage();
+ System.exit(0);
+ }
+
+ boolean verbose = parser.getOptionValue(verboseOpt) != null;
+
+ // Check the JVM vendor
+ if (verbose) {
+ String jvmVendor = System.getProperty("java.vendor");
+ if (!jvmVendor.equalsIgnoreCase("Sun Microsystems Inc.")) {
+ System.err.println("\n[INFO] It is recommended to use Sun Microsystems' JVM [java.vendor = " + jvmVendor + "]");
+ }
+ }
+
+ String charset = (String) parser.getOptionValue(charsetOpt);
+ if (charset == null || !Charset.isSupported(charset)) {
+ charset = System.getProperty("file.encoding");
+ if (charset == null) {
+ charset = "UTF-8";
+ }
+ if (verbose) {
+ System.err.println("\n[INFO] Using charset " + charset);
+ }
+ }
+
+ String[] fileArgs = parser.getRemainingArgs();
+ String type = (String) parser.getOptionValue(typeOpt);
+
+ if (fileArgs.length == 0) {
+
+ if (type == null || !type.equalsIgnoreCase("js") && !type.equalsIgnoreCase("css")) {
+ usage();
+ System.exit(1);
+ }
+
+ in = new InputStreamReader(System.in, charset);
+
+ } else {
+
+ if (type != null && !type.equalsIgnoreCase("js") && !type.equalsIgnoreCase("css")) {
+ usage();
+ System.exit(1);
+ }
+
+ String inputFilename = fileArgs[0];
+
+ if (type == null) {
+ int idx = inputFilename.lastIndexOf('.');
+ if (idx >= 0 && idx < inputFilename.length() - 1) {
+ type = inputFilename.substring(idx + 1);
+ }
+ }
+
+ if (type == null || !type.equalsIgnoreCase("js") && !type.equalsIgnoreCase("css")) {
+ usage();
+ System.exit(1);
+ }
+
+ in = new InputStreamReader(new FileInputStream(inputFilename), charset);
+ }
+
+ int linebreakpos = -1;
+ String linebreakstr = (String) parser.getOptionValue(linebreakOpt);
+ if (linebreakstr != null) {
+ try {
+ linebreakpos = Integer.parseInt(linebreakstr, 10);
+ } catch (NumberFormatException e) {
+ usage();
+ System.exit(1);
+ }
+ }
+
+ String outputFilename = (String) parser.getOptionValue(outputFilenameOpt);
+
+ if (type.equalsIgnoreCase("js")) {
+
+ try {
+
+ JavaScriptCompressor compressor = new JavaScriptCompressor(in, new ErrorReporter() {
+
+ public void warning(String message, String sourceName,
+ int line, String lineSource, int lineOffset) {
+ if (line < 0) {
+ System.err.println("\n[WARNING] " + message);
+ } else {
+ System.err.println("\n[WARNING] " + line + ':' + lineOffset + ':' + message);
+ }
+ }
+
+ public void error(String message, String sourceName,
+ int line, String lineSource, int lineOffset) {
+ if (line < 0) {
+ System.err.println("\n[ERROR] " + message);
+ } else {
+ System.err.println("\n[ERROR] " + line + ':' + lineOffset + ':' + message);
+ }
+ }
+
+ public EvaluatorException runtimeError(String message, String sourceName,
+ int line, String lineSource, int lineOffset) {
+ error(message, sourceName, line, lineSource, lineOffset);
+ return new EvaluatorException(message);
+ }
+ });
+
+ // Close the input stream first, and then open the output stream,
+ // in case the output file should override the input file.
+ in.close(); in = null;
+
+ if (outputFilename == null) {
+ out = new OutputStreamWriter(System.out, charset);
+ } else {
+ out = new OutputStreamWriter(new FileOutputStream(outputFilename), charset);
+ }
+
+ boolean munge = parser.getOptionValue(nomungeOpt) == null;
+ boolean preserveAllSemiColons = parser.getOptionValue(preserveSemiOpt) != null;
+ boolean disableOptimizations = parser.getOptionValue(disableOptimizationsOpt) != null;
+
+ compressor.compress(out, linebreakpos, munge, verbose,
+ preserveAllSemiColons, disableOptimizations);
+
+ } catch (EvaluatorException e) {
+
+ e.printStackTrace();
+ // Return a special error code used specifically by the web front-end.
+ System.exit(2);
+
+ }
+
+ } else if (type.equalsIgnoreCase("css")) {
+
+ CssCompressor compressor = new CssCompressor(in);
+
+ // Close the input stream first, and then open the output stream,
+ // in case the output file should override the input file.
+ in.close(); in = null;
+
+ if (outputFilename == null) {
+ out = new OutputStreamWriter(System.out, charset);
+ } else {
+ out = new OutputStreamWriter(new FileOutputStream(outputFilename), charset);
+ }
+
+ compressor.compress(out, linebreakpos);
+ }
+
+ } catch (CmdLineParser.OptionException e) {
+
+ usage();
+ System.exit(1);
+
+ } catch (IOException e) {
+
+ e.printStackTrace();
+ System.exit(1);
+
+ } finally {
+
+ if (in != null) {
+ try {
+ in.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ if (out != null) {
+ try {
+ out.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ }
+
+ private static void usage() {
+ System.out.println(
+ "\nUsage: java -jar yuicompressor-x.y.z.jar [options] [input file]\n\n"
+
+ + "Global Options\n"
+ + " -h, --help Displays this information\n"
+ + " --type <js|css> Specifies the type of the input file\n"
+ + " --charset <charset> Read the input file using <charset>\n"
+ + " --line-break <column> Insert a line break after the specified column number\n"
+ + " -v, --verbose Display informational messages and warnings\n"
+ + " -o <file> Place the output into <file>. Defaults to stdout.\n\n"
+
+ + "JavaScript Options\n"
+ + " --nomunge Minify only, do not obfuscate\n"
+ + " --preserve-semi Preserve all semicolons\n"
+ + " --disable-optimizations Disable all micro optimizations\n\n"
+
+ + "If no input file is specified, it defaults to stdin. In this case, the 'type'\n"
+ + "option is required. Otherwise, the 'type' option is required only if the input\n"
+ + "file extension is neither 'js' nor 'css'.");
+ }
+}
diff --git a/bin/yuicompressor-2.3.4/src/org/mozilla/javascript/Decompiler.java b/bin/yuicompressor-2.3.4/src/org/mozilla/javascript/Decompiler.java
new file mode 100644
index 0000000..b5f7e50
--- /dev/null
+++ b/bin/yuicompressor-2.3.4/src/org/mozilla/javascript/Decompiler.java
@@ -0,0 +1,916 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Mike Ang
+ * Igor Bukanov
+ * Bob Jervis
+ * Mike McCabe
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.javascript;
+
+/**
+ * The following class save decompilation information about the source.
+ * Source information is returned from the parser as a String
+ * associated with function nodes and with the toplevel script. When
+ * saved in the constant pool of a class, this string will be UTF-8
+ * encoded, and token values will occupy a single byte.
+
+ * Source is saved (mostly) as token numbers. The tokens saved pretty
+ * much correspond to the token stream of a 'canonical' representation
+ * of the input program, as directed by the parser. (There were a few
+ * cases where tokens could have been left out where decompiler could
+ * easily reconstruct them, but I left them in for clarity). (I also
+ * looked adding source collection to TokenStream instead, where I
+ * could have limited the changes to a few lines in getToken... but
+ * this wouldn't have saved any space in the resulting source
+ * representation, and would have meant that I'd have to duplicate
+ * parser logic in the decompiler to disambiguate situations where
+ * newlines are important.) The function decompile expands the
+ * tokens back into their string representations, using simple
+ * lookahead to correct spacing and indentation.
+ *
+ * Assignments are saved as two-token pairs (Token.ASSIGN, op). Number tokens
+ * are stored inline, as a NUMBER token, a character representing the type, and
+ * either 1 or 4 characters representing the bit-encoding of the number. String
+ * types NAME, STRING and OBJECT are currently stored as a token type,
+ * followed by a character giving the length of the string (assumed to
+ * be less than 2^16), followed by the characters of the string
+ * inlined into the source string. Changing this to some reference to
+ * to the string in the compiled class' constant pool would probably
+ * save a lot of space... but would require some method of deriving
+ * the final constant pool entry from information available at parse
+ * time.
+ */
+public class Decompiler
+{
+ /**
+ * Flag to indicate that the decompilation should omit the
+ * function header and trailing brace.
+ */
+ public static final int ONLY_BODY_FLAG = 1 << 0;
+
+ /**
+ * Flag to indicate that the decompilation generates toSource result.
+ */
+ public static final int TO_SOURCE_FLAG = 1 << 1;
+
+ /**
+ * Decompilation property to specify initial ident value.
+ */
+ public static final int INITIAL_INDENT_PROP = 1;
+
+ /**
+ * Decompilation property to specify default identation offset.
+ */
+ public static final int INDENT_GAP_PROP = 2;
+
+ /**
+ * Decompilation property to specify identation offset for case labels.
+ */
+ public static final int CASE_GAP_PROP = 3;
+
+ // Marker to denote the last RC of function so it can be distinguished from
+ // the last RC of object literals in case of function expressions
+ private static final int FUNCTION_END = Token.LAST_TOKEN + 1;
+
+ String getEncodedSource()
+ {
+ return sourceToString(0);
+ }
+
+ int getCurrentOffset()
+ {
+ return sourceTop;
+ }
+
+ int markFunctionStart(int functionType)
+ {
+ int savedOffset = getCurrentOffset();
+ addToken(Token.FUNCTION);
+ append((char)functionType);
+ return savedOffset;
+ }
+
+ int markFunctionEnd(int functionStart)
+ {
+ int offset = getCurrentOffset();
+ append((char)FUNCTION_END);
+ return offset;
+ }
+
+ void addToken(int token)
+ {
+ if (!(0 <= token && token <= Token.LAST_TOKEN))
+ throw new IllegalArgumentException();
+
+ append((char)token);
+ }
+
+ void addEOL(int token)
+ {
+ if (!(0 <= token && token <= Token.LAST_TOKEN))
+ throw new IllegalArgumentException();
+
+ append((char)token);
+ append((char)Token.EOL);
+ }
+
+ void addName(String str)
+ {
+ addToken(Token.NAME);
+ appendString(str);
+ }
+
+ void addString(String str)
+ {
+ addToken(Token.STRING);
+ appendString(str);
+ }
+
+ void addRegexp(String regexp, String flags)
+ {
+ addToken(Token.REGEXP);
+ appendString('/' + regexp + '/' + flags);
+ }
+
+ void addJScriptConditionalComment(String str)
+ {
+ addToken(Token.SPECIALCOMMENT);
+ appendString(str);
+ }
+
+ void addNumber(double n)
+ {
+ addToken(Token.NUMBER);
+
+ /* encode the number in the source stream.
+ * Save as NUMBER type (char | char char char char)
+ * where type is
+ * 'D' - double, 'S' - short, 'J' - long.
+
+ * We need to retain float vs. integer type info to keep the
+ * behavior of liveconnect type-guessing the same after
+ * decompilation. (Liveconnect tries to present 1.0 to Java
+ * as a float/double)
+ * OPT: This is no longer true. We could compress the format.
+
+ * This may not be the most space-efficient encoding;
+ * the chars created below may take up to 3 bytes in
+ * constant pool UTF-8 encoding, so a Double could take
+ * up to 12 bytes.
+ */
+
+ long lbits = (long)n;
+ if (lbits != n) {
+ // if it's floating point, save as a Double bit pattern.
+ // (12/15/97 our scanner only returns Double for f.p.)
+ lbits = Double.doubleToLongBits(n);
+ append('D');
+ append((char)(lbits >> 48));
+ append((char)(lbits >> 32));
+ append((char)(lbits >> 16));
+ append((char)lbits);
+ }
+ else {
+ // we can ignore negative values, bc they're already prefixed
+ // by NEG
+ if (lbits < 0) Kit.codeBug();
+
+ // will it fit in a char?
+ // this gives a short encoding for integer values up to 2^16.
+ if (lbits <= Character.MAX_VALUE) {
+ append('S');
+ append((char)lbits);
+ }
+ else { // Integral, but won't fit in a char. Store as a long.
+ append('J');
+ append((char)(lbits >> 48));
+ append((char)(lbits >> 32));
+ append((char)(lbits >> 16));
+ append((char)lbits);
+ }
+ }
+ }
+
+ private void appendString(String str)
+ {
+ int L = str.length();
+ int lengthEncodingSize = 1;
+ if (L >= 0x8000) {
+ lengthEncodingSize = 2;
+ }
+ int nextTop = sourceTop + lengthEncodingSize + L;
+ if (nextTop > sourceBuffer.length) {
+ increaseSourceCapacity(nextTop);
+ }
+ if (L >= 0x8000) {
+ // Use 2 chars to encode strings exceeding 32K, were the highest
+ // bit in the first char indicates presence of the next byte
+ sourceBuffer[sourceTop] = (char)(0x8000 | (L >>> 16));
+ ++sourceTop;
+ }
+ sourceBuffer[sourceTop] = (char)L;
+ ++sourceTop;
+ str.getChars(0, L, sourceBuffer, sourceTop);
+ sourceTop = nextTop;
+ }
+
+ private void append(char c)
+ {
+ if (sourceTop == sourceBuffer.length) {
+ increaseSourceCapacity(sourceTop + 1);
+ }
+ sourceBuffer[sourceTop] = c;
+ ++sourceTop;
+ }
+
+ private void increaseSourceCapacity(int minimalCapacity)
+ {
+ // Call this only when capacity increase is must
+ if (minimalCapacity <= sourceBuffer.length) Kit.codeBug();
+ int newCapacity = sourceBuffer.length * 2;
+ if (newCapacity < minimalCapacity) {
+ newCapacity = minimalCapacity;
+ }
+ char[] tmp = new char[newCapacity];
+ System.arraycopy(sourceBuffer, 0, tmp, 0, sourceTop);
+ sourceBuffer = tmp;
+ }
+
+ private String sourceToString(int offset)
+ {
+ if (offset < 0 || sourceTop < offset) Kit.codeBug();
+ return new String(sourceBuffer, offset, sourceTop - offset);
+ }
+
+ /**
+ * Decompile the source information associated with this js
+ * function/script back into a string. For the most part, this
+ * just means translating tokens back to their string
+ * representations; there's a little bit of lookahead logic to
+ * decide the proper spacing/indentation. Most of the work in
+ * mapping the original source to the prettyprinted decompiled
+ * version is done by the parser.
+ *
+ * @param source encoded source tree presentation
+ *
+ * @param flags flags to select output format
+ *
+ * @param properties indentation properties
+ *
+ */
+ public static String decompile(String source, int flags,
+ UintMap properties)
+ {
+ int length = source.length();
+ if (length == 0) { return ""; }
+
+ int indent = properties.getInt(INITIAL_INDENT_PROP, 0);
+ if (indent < 0) throw new IllegalArgumentException();
+ int indentGap = properties.getInt(INDENT_GAP_PROP, 4);
+ if (indentGap < 0) throw new IllegalArgumentException();
+ int caseGap = properties.getInt(CASE_GAP_PROP, 2);
+ if (caseGap < 0) throw new IllegalArgumentException();
+
+ StringBuffer result = new StringBuffer();
+ boolean justFunctionBody = (0 != (flags & Decompiler.ONLY_BODY_FLAG));
+ boolean toSource = (0 != (flags & Decompiler.TO_SOURCE_FLAG));
+
+ // Spew tokens in source, for debugging.
+ // as TYPE number char
+ if (printSource) {
+ System.err.println("length:" + length);
+ for (int i = 0; i < length; ++i) {
+ // Note that tokenToName will fail unless Context.printTrees
+ // is true.
+ String tokenname = null;
+ if (Token.printNames) {
+ tokenname = Token.name(source.charAt(i));
+ }
+ if (tokenname == null) {
+ tokenname = "---";
+ }
+ String pad = tokenname.length() > 7
+ ? "\t"
+ : "\t\t";
+ System.err.println
+ (tokenname
+ + pad + (int)source.charAt(i)
+ + "\t'" + ScriptRuntime.escapeString
+ (source.substring(i, i+1))
+ + "'");
+ }
+ System.err.println();
+ }
+
+ int braceNesting = 0;
+ boolean afterFirstEOL = false;
+ int i = 0;
+ int topFunctionType;
+ if (source.charAt(i) == Token.SCRIPT) {
+ ++i;
+ topFunctionType = -1;
+ } else {
+ topFunctionType = source.charAt(i + 1);
+ }
+
+ if (!toSource) {
+ // add an initial newline to exactly match js.
+ result.append('\n');
+ for (int j = 0; j < indent; j++)
+ result.append(' ');
+ } else {
+ if (topFunctionType == FunctionNode.FUNCTION_EXPRESSION) {
+ result.append('(');
+ }
+ }
+
+ while (i < length) {
+ switch(source.charAt(i)) {
+ case Token.GET:
+ case Token.SET:
+ result.append(source.charAt(i) == Token.GET ? "get " : "set ");
+ ++i;
+ i = printSourceString(source, i + 1, false, result);
+ // Now increment one more to get past the FUNCTION token
+ ++i;
+ break;
+
+ case Token.NAME:
+ case Token.REGEXP: // re-wrapped in '/'s in parser...
+ i = printSourceString(source, i + 1, false, result);
+ continue;
+
+ case Token.STRING:
+ i = printSourceString(source, i + 1, true, result);
+ continue;
+
+ case Token.NUMBER:
+ i = printSourceNumber(source, i + 1, result);
+ continue;
+
+ case Token.TRUE:
+ result.append("true");
+ break;
+
+ case Token.FALSE:
+ result.append("false");
+ break;
+
+ case Token.NULL:
+ result.append("null");
+ break;
+
+ case Token.THIS:
+ result.append("this");
+ break;
+
+ case Token.FUNCTION:
+ ++i; // skip function type
+ result.append("function ");
+ break;
+
+ case FUNCTION_END:
+ // Do nothing
+ break;
+
+ case Token.COMMA:
+ result.append(", ");
+ break;
+
+ case Token.LC:
+ ++braceNesting;
+ if (Token.EOL == getNext(source, length, i))
+ indent += indentGap;
+ result.append('{');
+ break;
+
+ case Token.RC: {
+ --braceNesting;
+ /* don't print the closing RC if it closes the
+ * toplevel function and we're called from
+ * decompileFunctionBody.
+ */
+ if (justFunctionBody && braceNesting == 0)
+ break;
+
+ result.append('}');
+ switch (getNext(source, length, i)) {
+ case Token.EOL:
+ case FUNCTION_END:
+ indent -= indentGap;
+ break;
+ case Token.WHILE:
+ case Token.ELSE:
+ indent -= indentGap;
+ result.append(' ');
+ break;
+ }
+ break;
+ }
+ case Token.LP:
+ result.append('(');
+ break;
+
+ case Token.RP:
+ result.append(')');
+ if (Token.LC == getNext(source, length, i))
+ result.append(' ');
+ break;
+
+ case Token.LB:
+ result.append('[');
+ break;
+
+ case Token.RB:
+ result.append(']');
+ break;
+
+ case Token.EOL: {
+ if (toSource) break;
+ boolean newLine = true;
+ if (!afterFirstEOL) {
+ afterFirstEOL = true;
+ if (justFunctionBody) {
+ /* throw away just added 'function name(...) {'
+ * and restore the original indent
+ */
+ result.setLength(0);
+ indent -= indentGap;
+ newLine = false;
+ }
+ }
+ if (newLine) {
+ result.append('\n');
+ }
+
+ /* add indent if any tokens remain,
+ * less setback if next token is
+ * a label, case or default.
+ */
+ if (i + 1 < length) {
+ int less = 0;
+ int nextToken = source.charAt(i + 1);
+ if (nextToken == Token.CASE
+ || nextToken == Token.DEFAULT)
+ {
+ less = indentGap - caseGap;
+ } else if (nextToken == Token.RC) {
+ less = indentGap;
+ }
+
+ /* elaborate check against label... skip past a
+ * following inlined NAME and look for a COLON.
+ */
+ else if (nextToken == Token.NAME) {
+ int afterName = getSourceStringEnd(source, i + 2);
+ if (source.charAt(afterName) == Token.COLON)
+ less = indentGap;
+ }
+
+ for (; less < indent; less++)
+ result.append(' ');
+ }
+ break;
+ }
+ case Token.DOT:
+ result.append('.');
+ break;
+
+ case Token.NEW:
+ result.append("new ");
+ break;
+
+ case Token.DELPROP:
+ result.append("delete ");
+ break;
+
+ case Token.IF:
+ result.append("if ");
+ break;
+
+ case Token.ELSE:
+ result.append("else ");
+ break;
+
+ case Token.FOR:
+ result.append("for ");
+ break;
+
+ case Token.IN:
+ result.append(" in ");
+ break;
+
+ case Token.WITH:
+ result.append("with ");
+ break;
+
+ case Token.WHILE:
+ result.append("while ");
+ break;
+
+ case Token.DO:
+ result.append("do ");
+ break;
+
+ case Token.TRY:
+ result.append("try ");
+ break;
+
+ case Token.CATCH:
+ result.append("catch ");
+ break;
+
+ case Token.FINALLY:
+ result.append("finally ");
+ break;
+
+ case Token.THROW:
+ result.append("throw ");
+ break;
+
+ case Token.SWITCH:
+ result.append("switch ");
+ break;
+
+ case Token.BREAK:
+ result.append("break");
+ if (Token.NAME == getNext(source, length, i))
+ result.append(' ');
+ break;
+
+ case Token.CONTINUE:
+ result.append("continue");
+ if (Token.NAME == getNext(source, length, i))
+ result.append(' ');
+ break;
+
+ case Token.CASE:
+ result.append("case ");
+ break;
+
+ case Token.DEFAULT:
+ result.append("default");
+ break;
+
+ case Token.RETURN:
+ result.append("return");
+ if (Token.SEMI != getNext(source, length, i))
+ result.append(' ');
+ break;
+
+ case Token.VAR:
+ result.append("var ");
+ break;
+
+ case Token.SEMI:
+ result.append(';');
+ if (Token.EOL != getNext(source, length, i)) {
+ // separators in FOR
+ result.append(' ');
+ }
+ break;
+
+ case Token.ASSIGN:
+ result.append(" = ");
+ break;
+
+ case Token.ASSIGN_ADD:
+ result.append(" += ");
+ break;
+
+ case Token.ASSIGN_SUB:
+ result.append(" -= ");
+ break;
+
+ case Token.ASSIGN_MUL:
+ result.append(" *= ");
+ break;
+
+ case Token.ASSIGN_DIV:
+ result.append(" /= ");
+ break;
+
+ case Token.ASSIGN_MOD:
+ result.append(" %= ");
+ break;
+
+ case Token.ASSIGN_BITOR:
+ result.append(" |= ");
+ break;
+
+ case Token.ASSIGN_BITXOR:
+ result.append(" ^= ");
+ break;
+
+ case Token.ASSIGN_BITAND:
+ result.append(" &= ");
+ break;
+
+ case Token.ASSIGN_LSH:
+ result.append(" <<= ");
+ break;
+
+ case Token.ASSIGN_RSH:
+ result.append(" >>= ");
+ break;
+
+ case Token.ASSIGN_URSH:
+ result.append(" >>>= ");
+ break;
+
+ case Token.HOOK:
+ result.append(" ? ");
+ break;
+
+ case Token.OBJECTLIT:
+ // pun OBJECTLIT to mean colon in objlit property
+ // initialization.
+ // This needs to be distinct from COLON in the general case
+ // to distinguish from the colon in a ternary... which needs
+ // different spacing.
+ result.append(':');
+ break;
+
+ case Token.COLON:
+ if (Token.EOL == getNext(source, length, i))
+ // it's the end of a label
+ result.append(':');
+ else
+ // it's the middle part of a ternary
+ result.append(" : ");
+ break;
+
+ case Token.OR:
+ result.append(" || ");
+ break;
+
+ case Token.AND:
+ result.append(" && ");
+ break;
+
+ case Token.BITOR:
+ result.append(" | ");
+ break;
+
+ case Token.BITXOR:
+ result.append(" ^ ");
+ break;
+
+ case Token.BITAND:
+ result.append(" & ");
+ break;
+
+ case Token.SHEQ:
+ result.append(" === ");
+ break;
+
+ case Token.SHNE:
+ result.append(" !== ");
+ break;
+
+ case Token.EQ:
+ result.append(" == ");
+ break;
+
+ case Token.NE:
+ result.append(" != ");
+ break;
+
+ case Token.LE:
+ result.append(" <= ");
+ break;
+
+ case Token.LT:
+ result.append(" < ");
+ break;
+
+ case Token.GE:
+ result.append(" >= ");
+ break;
+
+ case Token.GT:
+ result.append(" > ");
+ break;
+
+ case Token.INSTANCEOF:
+ result.append(" instanceof ");
+ break;
+
+ case Token.LSH:
+ result.append(" << ");
+ break;
+
+ case Token.RSH:
+ result.append(" >> ");
+ break;
+
+ case Token.URSH:
+ result.append(" >>> ");
+ break;
+
+ case Token.TYPEOF:
+ result.append("typeof ");
+ break;
+
+ case Token.VOID:
+ result.append("void ");
+ break;
+
+ case Token.CONST:
+ result.append("const ");
+ break;
+
+ case Token.NOT:
+ result.append('!');
+ break;
+
+ case Token.BITNOT:
+ result.append('~');
+ break;
+
+ case Token.POS:
+ result.append('+');
+ break;
+
+ case Token.NEG:
+ result.append('-');
+ break;
+
+ case Token.INC:
+ result.append("++");
+ break;
+
+ case Token.DEC:
+ result.append("--");
+ break;
+
+ case Token.ADD:
+ result.append(" + ");
+ break;
+
+ case Token.SUB:
+ result.append(" - ");
+ break;
+
+ case Token.MUL:
+ result.append(" * ");
+ break;
+
+ case Token.DIV:
+ result.append(" / ");
+ break;
+
+ case Token.MOD:
+ result.append(" % ");
+ break;
+
+ case Token.COLONCOLON:
+ result.append("::");
+ break;
+
+ case Token.DOTDOT:
+ result.append("..");
+ break;
+
+ case Token.DOTQUERY:
+ result.append(".(");
+ break;
+
+ case Token.XMLATTR:
+ result.append('@');
+ break;
+
+ default:
+ // If we don't know how to decompile it, raise an exception.
+ throw new RuntimeException("Token: " +
+ Token.name(source.charAt(i)));
+ }
+ ++i;
+ }
+
+ if (!toSource) {
+ // add that trailing newline if it's an outermost function.
+ if (!justFunctionBody)
+ result.append('\n');
+ } else {
+ if (topFunctionType == FunctionNode.FUNCTION_EXPRESSION) {
+ result.append(')');
+ }
+ }
+
+ return result.toString();
+ }
+
+ private static int getNext(String source, int length, int i)
+ {
+ return (i + 1 < length) ? source.charAt(i + 1) : Token.EOF;
+ }
+
+ private static int getSourceStringEnd(String source, int offset)
+ {
+ return printSourceString(source, offset, false, null);
+ }
+
+ private static int printSourceString(String source, int offset,
+ boolean asQuotedString,
+ StringBuffer sb)
+ {
+ int length = source.charAt(offset);
+ ++offset;
+ if ((0x8000 & length) != 0) {
+ length = ((0x7FFF & length) << 16) | source.charAt(offset);
+ ++offset;
+ }
+ if (sb != null) {
+ String str = source.substring(offset, offset + length);
+ if (!asQuotedString) {
+ sb.append(str);
+ } else {
+ sb.append('"');
+ sb.append(ScriptRuntime.escapeString(str));
+ sb.append('"');
+ }
+ }
+ return offset + length;
+ }
+
+ private static int printSourceNumber(String source, int offset,
+ StringBuffer sb)
+ {
+ double number = 0.0;
+ char type = source.charAt(offset);
+ ++offset;
+ if (type == 'S') {
+ if (sb != null) {
+ int ival = source.charAt(offset);
+ number = ival;
+ }
+ ++offset;
+ } else if (type == 'J' || type == 'D') {
+ if (sb != null) {
+ long lbits;
+ lbits = (long)source.charAt(offset) << 48;
+ lbits |= (long)source.charAt(offset + 1) << 32;
+ lbits |= (long)source.charAt(offset + 2) << 16;
+ lbits |= source.charAt(offset + 3);
+ if (type == 'J') {
+ number = lbits;
+ } else {
+ number = Double.longBitsToDouble(lbits);
+ }
+ }
+ offset += 4;
+ } else {
+ // Bad source
+ throw new RuntimeException();
+ }
+ if (sb != null) {
+ sb.append(ScriptRuntime.numberToString(number, 10));
+ }
+ return offset;
+ }
+
+ private char[] sourceBuffer = new char[128];
+
+// Per script/function source buffer top: parent source does not include a
+// nested functions source and uses function index as a reference instead.
+ private int sourceTop;
+
+// whether to do a debug print of the source information, when decompiling.
+ private static final boolean printSource = false;
+
+}
diff --git a/bin/yuicompressor-2.3.4/src/org/mozilla/javascript/Decompiler.java.orig b/bin/yuicompressor-2.3.4/src/org/mozilla/javascript/Decompiler.java.orig
new file mode 100644
index 0000000..cdb00b7
--- /dev/null
+++ b/bin/yuicompressor-2.3.4/src/org/mozilla/javascript/Decompiler.java.orig
@@ -0,0 +1,910 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Mike Ang
+ * Igor Bukanov
+ * Bob Jervis
+ * Mike McCabe
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.javascript;
+
+/**
+ * The following class save decompilation information about the source.
+ * Source information is returned from the parser as a String
+ * associated with function nodes and with the toplevel script. When
+ * saved in the constant pool of a class, this string will be UTF-8
+ * encoded, and token values will occupy a single byte.
+
+ * Source is saved (mostly) as token numbers. The tokens saved pretty
+ * much correspond to the token stream of a 'canonical' representation
+ * of the input program, as directed by the parser. (There were a few
+ * cases where tokens could have been left out where decompiler could
+ * easily reconstruct them, but I left them in for clarity). (I also
+ * looked adding source collection to TokenStream instead, where I
+ * could have limited the changes to a few lines in getToken... but
+ * this wouldn't have saved any space in the resulting source
+ * representation, and would have meant that I'd have to duplicate
+ * parser logic in the decompiler to disambiguate situations where
+ * newlines are important.) The function decompile expands the
+ * tokens back into their string representations, using simple
+ * lookahead to correct spacing and indentation.
+ *
+ * Assignments are saved as two-token pairs (Token.ASSIGN, op). Number tokens
+ * are stored inline, as a NUMBER token, a character representing the type, and
+ * either 1 or 4 characters representing the bit-encoding of the number. String
+ * types NAME, STRING and OBJECT are currently stored as a token type,
+ * followed by a character giving the length of the string (assumed to
+ * be less than 2^16), followed by the characters of the string
+ * inlined into the source string. Changing this to some reference to
+ * to the string in the compiled class' constant pool would probably
+ * save a lot of space... but would require some method of deriving
+ * the final constant pool entry from information available at parse
+ * time.
+ */
+public class Decompiler
+{
+ /**
+ * Flag to indicate that the decompilation should omit the
+ * function header and trailing brace.
+ */
+ public static final int ONLY_BODY_FLAG = 1 << 0;
+
+ /**
+ * Flag to indicate that the decompilation generates toSource result.
+ */
+ public static final int TO_SOURCE_FLAG = 1 << 1;
+
+ /**
+ * Decompilation property to specify initial ident value.
+ */
+ public static final int INITIAL_INDENT_PROP = 1;
+
+ /**
+ * Decompilation property to specify default identation offset.
+ */
+ public static final int INDENT_GAP_PROP = 2;
+
+ /**
+ * Decompilation property to specify identation offset for case labels.
+ */
+ public static final int CASE_GAP_PROP = 3;
+
+ // Marker to denote the last RC of function so it can be distinguished from
+ // the last RC of object literals in case of function expressions
+ private static final int FUNCTION_END = Token.LAST_TOKEN + 1;
+
+ String getEncodedSource()
+ {
+ return sourceToString(0);
+ }
+
+ int getCurrentOffset()
+ {
+ return sourceTop;
+ }
+
+ int markFunctionStart(int functionType)
+ {
+ int savedOffset = getCurrentOffset();
+ addToken(Token.FUNCTION);
+ append((char)functionType);
+ return savedOffset;
+ }
+
+ int markFunctionEnd(int functionStart)
+ {
+ int offset = getCurrentOffset();
+ append((char)FUNCTION_END);
+ return offset;
+ }
+
+ void addToken(int token)
+ {
+ if (!(0 <= token && token <= Token.LAST_TOKEN))
+ throw new IllegalArgumentException();
+
+ append((char)token);
+ }
+
+ void addEOL(int token)
+ {
+ if (!(0 <= token && token <= Token.LAST_TOKEN))
+ throw new IllegalArgumentException();
+
+ append((char)token);
+ append((char)Token.EOL);
+ }
+
+ void addName(String str)
+ {
+ addToken(Token.NAME);
+ appendString(str);
+ }
+
+ void addString(String str)
+ {
+ addToken(Token.STRING);
+ appendString(str);
+ }
+
+ void addRegexp(String regexp, String flags)
+ {
+ addToken(Token.REGEXP);
+ appendString('/' + regexp + '/' + flags);
+ }
+
+ void addNumber(double n)
+ {
+ addToken(Token.NUMBER);
+
+ /* encode the number in the source stream.
+ * Save as NUMBER type (char | char char char char)
+ * where type is
+ * 'D' - double, 'S' - short, 'J' - long.
+
+ * We need to retain float vs. integer type info to keep the
+ * behavior of liveconnect type-guessing the same after
+ * decompilation. (Liveconnect tries to present 1.0 to Java
+ * as a float/double)
+ * OPT: This is no longer true. We could compress the format.
+
+ * This may not be the most space-efficient encoding;
+ * the chars created below may take up to 3 bytes in
+ * constant pool UTF-8 encoding, so a Double could take
+ * up to 12 bytes.
+ */
+
+ long lbits = (long)n;
+ if (lbits != n) {
+ // if it's floating point, save as a Double bit pattern.
+ // (12/15/97 our scanner only returns Double for f.p.)
+ lbits = Double.doubleToLongBits(n);
+ append('D');
+ append((char)(lbits >> 48));
+ append((char)(lbits >> 32));
+ append((char)(lbits >> 16));
+ append((char)lbits);
+ }
+ else {
+ // we can ignore negative values, bc they're already prefixed
+ // by NEG
+ if (lbits < 0) Kit.codeBug();
+
+ // will it fit in a char?
+ // this gives a short encoding for integer values up to 2^16.
+ if (lbits <= Character.MAX_VALUE) {
+ append('S');
+ append((char)lbits);
+ }
+ else { // Integral, but won't fit in a char. Store as a long.
+ append('J');
+ append((char)(lbits >> 48));
+ append((char)(lbits >> 32));
+ append((char)(lbits >> 16));
+ append((char)lbits);
+ }
+ }
+ }
+
+ private void appendString(String str)
+ {
+ int L = str.length();
+ int lengthEncodingSize = 1;
+ if (L >= 0x8000) {
+ lengthEncodingSize = 2;
+ }
+ int nextTop = sourceTop + lengthEncodingSize + L;
+ if (nextTop > sourceBuffer.length) {
+ increaseSourceCapacity(nextTop);
+ }
+ if (L >= 0x8000) {
+ // Use 2 chars to encode strings exceeding 32K, were the highest
+ // bit in the first char indicates presence of the next byte
+ sourceBuffer[sourceTop] = (char)(0x8000 | (L >>> 16));
+ ++sourceTop;
+ }
+ sourceBuffer[sourceTop] = (char)L;
+ ++sourceTop;
+ str.getChars(0, L, sourceBuffer, sourceTop);
+ sourceTop = nextTop;
+ }
+
+ private void append(char c)
+ {
+ if (sourceTop == sourceBuffer.length) {
+ increaseSourceCapacity(sourceTop + 1);
+ }
+ sourceBuffer[sourceTop] = c;
+ ++sourceTop;
+ }
+
+ private void increaseSourceCapacity(int minimalCapacity)
+ {
+ // Call this only when capacity increase is must
+ if (minimalCapacity <= sourceBuffer.length) Kit.codeBug();
+ int newCapacity = sourceBuffer.length * 2;
+ if (newCapacity < minimalCapacity) {
+ newCapacity = minimalCapacity;
+ }
+ char[] tmp = new char[newCapacity];
+ System.arraycopy(sourceBuffer, 0, tmp, 0, sourceTop);
+ sourceBuffer = tmp;
+ }
+
+ private String sourceToString(int offset)
+ {
+ if (offset < 0 || sourceTop < offset) Kit.codeBug();
+ return new String(sourceBuffer, offset, sourceTop - offset);
+ }
+
+ /**
+ * Decompile the source information associated with this js
+ * function/script back into a string. For the most part, this
+ * just means translating tokens back to their string
+ * representations; there's a little bit of lookahead logic to
+ * decide the proper spacing/indentation. Most of the work in
+ * mapping the original source to the prettyprinted decompiled
+ * version is done by the parser.
+ *
+ * @param source encoded source tree presentation
+ *
+ * @param flags flags to select output format
+ *
+ * @param properties indentation properties
+ *
+ */
+ public static String decompile(String source, int flags,
+ UintMap properties)
+ {
+ int length = source.length();
+ if (length == 0) { return ""; }
+
+ int indent = properties.getInt(INITIAL_INDENT_PROP, 0);
+ if (indent < 0) throw new IllegalArgumentException();
+ int indentGap = properties.getInt(INDENT_GAP_PROP, 4);
+ if (indentGap < 0) throw new IllegalArgumentException();
+ int caseGap = properties.getInt(CASE_GAP_PROP, 2);
+ if (caseGap < 0) throw new IllegalArgumentException();
+
+ StringBuffer result = new StringBuffer();
+ boolean justFunctionBody = (0 != (flags & Decompiler.ONLY_BODY_FLAG));
+ boolean toSource = (0 != (flags & Decompiler.TO_SOURCE_FLAG));
+
+ // Spew tokens in source, for debugging.
+ // as TYPE number char
+ if (printSource) {
+ System.err.println("length:" + length);
+ for (int i = 0; i < length; ++i) {
+ // Note that tokenToName will fail unless Context.printTrees
+ // is true.
+ String tokenname = null;
+ if (Token.printNames) {
+ tokenname = Token.name(source.charAt(i));
+ }
+ if (tokenname == null) {
+ tokenname = "---";
+ }
+ String pad = tokenname.length() > 7
+ ? "\t"
+ : "\t\t";
+ System.err.println
+ (tokenname
+ + pad + (int)source.charAt(i)
+ + "\t'" + ScriptRuntime.escapeString
+ (source.substring(i, i+1))
+ + "'");
+ }
+ System.err.println();
+ }
+
+ int braceNesting = 0;
+ boolean afterFirstEOL = false;
+ int i = 0;
+ int topFunctionType;
+ if (source.charAt(i) == Token.SCRIPT) {
+ ++i;
+ topFunctionType = -1;
+ } else {
+ topFunctionType = source.charAt(i + 1);
+ }
+
+ if (!toSource) {
+ // add an initial newline to exactly match js.
+ result.append('\n');
+ for (int j = 0; j < indent; j++)
+ result.append(' ');
+ } else {
+ if (topFunctionType == FunctionNode.FUNCTION_EXPRESSION) {
+ result.append('(');
+ }
+ }
+
+ while (i < length) {
+ switch(source.charAt(i)) {
+ case Token.GET:
+ case Token.SET:
+ result.append(source.charAt(i) == Token.GET ? "get " : "set ");
+ ++i;
+ i = printSourceString(source, i + 1, false, result);
+ // Now increment one more to get past the FUNCTION token
+ ++i;
+ break;
+
+ case Token.NAME:
+ case Token.REGEXP: // re-wrapped in '/'s in parser...
+ i = printSourceString(source, i + 1, false, result);
+ continue;
+
+ case Token.STRING:
+ i = printSourceString(source, i + 1, true, result);
+ continue;
+
+ case Token.NUMBER:
+ i = printSourceNumber(source, i + 1, result);
+ continue;
+
+ case Token.TRUE:
+ result.append("true");
+ break;
+
+ case Token.FALSE:
+ result.append("false");
+ break;
+
+ case Token.NULL:
+ result.append("null");
+ break;
+
+ case Token.THIS:
+ result.append("this");
+ break;
+
+ case Token.FUNCTION:
+ ++i; // skip function type
+ result.append("function ");
+ break;
+
+ case FUNCTION_END:
+ // Do nothing
+ break;
+
+ case Token.COMMA:
+ result.append(", ");
+ break;
+
+ case Token.LC:
+ ++braceNesting;
+ if (Token.EOL == getNext(source, length, i))
+ indent += indentGap;
+ result.append('{');
+ break;
+
+ case Token.RC: {
+ --braceNesting;
+ /* don't print the closing RC if it closes the
+ * toplevel function and we're called from
+ * decompileFunctionBody.
+ */
+ if (justFunctionBody && braceNesting == 0)
+ break;
+
+ result.append('}');
+ switch (getNext(source, length, i)) {
+ case Token.EOL:
+ case FUNCTION_END:
+ indent -= indentGap;
+ break;
+ case Token.WHILE:
+ case Token.ELSE:
+ indent -= indentGap;
+ result.append(' ');
+ break;
+ }
+ break;
+ }
+ case Token.LP:
+ result.append('(');
+ break;
+
+ case Token.RP:
+ result.append(')');
+ if (Token.LC == getNext(source, length, i))
+ result.append(' ');
+ break;
+
+ case Token.LB:
+ result.append('[');
+ break;
+
+ case Token.RB:
+ result.append(']');
+ break;
+
+ case Token.EOL: {
+ if (toSource) break;
+ boolean newLine = true;
+ if (!afterFirstEOL) {
+ afterFirstEOL = true;
+ if (justFunctionBody) {
+ /* throw away just added 'function name(...) {'
+ * and restore the original indent
+ */
+ result.setLength(0);
+ indent -= indentGap;
+ newLine = false;
+ }
+ }
+ if (newLine) {
+ result.append('\n');
+ }
+
+ /* add indent if any tokens remain,
+ * less setback if next token is
+ * a label, case or default.
+ */
+ if (i + 1 < length) {
+ int less = 0;
+ int nextToken = source.charAt(i + 1);
+ if (nextToken == Token.CASE
+ || nextToken == Token.DEFAULT)
+ {
+ less = indentGap - caseGap;
+ } else if (nextToken == Token.RC) {
+ less = indentGap;
+ }
+
+ /* elaborate check against label... skip past a
+ * following inlined NAME and look for a COLON.
+ */
+ else if (nextToken == Token.NAME) {
+ int afterName = getSourceStringEnd(source, i + 2);
+ if (source.charAt(afterName) == Token.COLON)
+ less = indentGap;
+ }
+
+ for (; less < indent; less++)
+ result.append(' ');
+ }
+ break;
+ }
+ case Token.DOT:
+ result.append('.');
+ break;
+
+ case Token.NEW:
+ result.append("new ");
+ break;
+
+ case Token.DELPROP:
+ result.append("delete ");
+ break;
+
+ case Token.IF:
+ result.append("if ");
+ break;
+
+ case Token.ELSE:
+ result.append("else ");
+ break;
+
+ case Token.FOR:
+ result.append("for ");
+ break;
+
+ case Token.IN:
+ result.append(" in ");
+ break;
+
+ case Token.WITH:
+ result.append("with ");
+ break;
+
+ case Token.WHILE:
+ result.append("while ");
+ break;
+
+ case Token.DO:
+ result.append("do ");
+ break;
+
+ case Token.TRY:
+ result.append("try ");
+ break;
+
+ case Token.CATCH:
+ result.append("catch ");
+ break;
+
+ case Token.FINALLY:
+ result.append("finally ");
+ break;
+
+ case Token.THROW:
+ result.append("throw ");
+ break;
+
+ case Token.SWITCH:
+ result.append("switch ");
+ break;
+
+ case Token.BREAK:
+ result.append("break");
+ if (Token.NAME == getNext(source, length, i))
+ result.append(' ');
+ break;
+
+ case Token.CONTINUE:
+ result.append("continue");
+ if (Token.NAME == getNext(source, length, i))
+ result.append(' ');
+ break;
+
+ case Token.CASE:
+ result.append("case ");
+ break;
+
+ case Token.DEFAULT:
+ result.append("default");
+ break;
+
+ case Token.RETURN:
+ result.append("return");
+ if (Token.SEMI != getNext(source, length, i))
+ result.append(' ');
+ break;
+
+ case Token.VAR:
+ result.append("var ");
+ break;
+
+ case Token.SEMI:
+ result.append(';');
+ if (Token.EOL != getNext(source, length, i)) {
+ // separators in FOR
+ result.append(' ');
+ }
+ break;
+
+ case Token.ASSIGN:
+ result.append(" = ");
+ break;
+
+ case Token.ASSIGN_ADD:
+ result.append(" += ");
+ break;
+
+ case Token.ASSIGN_SUB:
+ result.append(" -= ");
+ break;
+
+ case Token.ASSIGN_MUL:
+ result.append(" *= ");
+ break;
+
+ case Token.ASSIGN_DIV:
+ result.append(" /= ");
+ break;
+
+ case Token.ASSIGN_MOD:
+ result.append(" %= ");
+ break;
+
+ case Token.ASSIGN_BITOR:
+ result.append(" |= ");
+ break;
+
+ case Token.ASSIGN_BITXOR:
+ result.append(" ^= ");
+ break;
+
+ case Token.ASSIGN_BITAND:
+ result.append(" &= ");
+ break;
+
+ case Token.ASSIGN_LSH:
+ result.append(" <<= ");
+ break;
+
+ case Token.ASSIGN_RSH:
+ result.append(" >>= ");
+ break;
+
+ case Token.ASSIGN_URSH:
+ result.append(" >>>= ");
+ break;
+
+ case Token.HOOK:
+ result.append(" ? ");
+ break;
+
+ case Token.OBJECTLIT:
+ // pun OBJECTLIT to mean colon in objlit property
+ // initialization.
+ // This needs to be distinct from COLON in the general case
+ // to distinguish from the colon in a ternary... which needs
+ // different spacing.
+ result.append(':');
+ break;
+
+ case Token.COLON:
+ if (Token.EOL == getNext(source, length, i))
+ // it's the end of a label
+ result.append(':');
+ else
+ // it's the middle part of a ternary
+ result.append(" : ");
+ break;
+
+ case Token.OR:
+ result.append(" || ");
+ break;
+
+ case Token.AND:
+ result.append(" && ");
+ break;
+
+ case Token.BITOR:
+ result.append(" | ");
+ break;
+
+ case Token.BITXOR:
+ result.append(" ^ ");
+ break;
+
+ case Token.BITAND:
+ result.append(" & ");
+ break;
+
+ case Token.SHEQ:
+ result.append(" === ");
+ break;
+
+ case Token.SHNE:
+ result.append(" !== ");
+ break;
+
+ case Token.EQ:
+ result.append(" == ");
+ break;
+
+ case Token.NE:
+ result.append(" != ");
+ break;
+
+ case Token.LE:
+ result.append(" <= ");
+ break;
+
+ case Token.LT:
+ result.append(" < ");
+ break;
+
+ case Token.GE:
+ result.append(" >= ");
+ break;
+
+ case Token.GT:
+ result.append(" > ");
+ break;
+
+ case Token.INSTANCEOF:
+ result.append(" instanceof ");
+ break;
+
+ case Token.LSH:
+ result.append(" << ");
+ break;
+
+ case Token.RSH:
+ result.append(" >> ");
+ break;
+
+ case Token.URSH:
+ result.append(" >>> ");
+ break;
+
+ case Token.TYPEOF:
+ result.append("typeof ");
+ break;
+
+ case Token.VOID:
+ result.append("void ");
+ break;
+
+ case Token.CONST:
+ result.append("const ");
+ break;
+
+ case Token.NOT:
+ result.append('!');
+ break;
+
+ case Token.BITNOT:
+ result.append('~');
+ break;
+
+ case Token.POS:
+ result.append('+');
+ break;
+
+ case Token.NEG:
+ result.append('-');
+ break;
+
+ case Token.INC:
+ result.append("++");
+ break;
+
+ case Token.DEC:
+ result.append("--");
+ break;
+
+ case Token.ADD:
+ result.append(" + ");
+ break;
+
+ case Token.SUB:
+ result.append(" - ");
+ break;
+
+ case Token.MUL:
+ result.append(" * ");
+ break;
+
+ case Token.DIV:
+ result.append(" / ");
+ break;
+
+ case Token.MOD:
+ result.append(" % ");
+ break;
+
+ case Token.COLONCOLON:
+ result.append("::");
+ break;
+
+ case Token.DOTDOT:
+ result.append("..");
+ break;
+
+ case Token.DOTQUERY:
+ result.append(".(");
+ break;
+
+ case Token.XMLATTR:
+ result.append('@');
+ break;
+
+ default:
+ // If we don't know how to decompile it, raise an exception.
+ throw new RuntimeException("Token: " +
+ Token.name(source.charAt(i)));
+ }
+ ++i;
+ }
+
+ if (!toSource) {
+ // add that trailing newline if it's an outermost function.
+ if (!justFunctionBody)
+ result.append('\n');
+ } else {
+ if (topFunctionType == FunctionNode.FUNCTION_EXPRESSION) {
+ result.append(')');
+ }
+ }
+
+ return result.toString();
+ }
+
+ private static int getNext(String source, int length, int i)
+ {
+ return (i + 1 < length) ? source.charAt(i + 1) : Token.EOF;
+ }
+
+ private static int getSourceStringEnd(String source, int offset)
+ {
+ return printSourceString(source, offset, false, null);
+ }
+
+ private static int printSourceString(String source, int offset,
+ boolean asQuotedString,
+ StringBuffer sb)
+ {
+ int length = source.charAt(offset);
+ ++offset;
+ if ((0x8000 & length) != 0) {
+ length = ((0x7FFF & length) << 16) | source.charAt(offset);
+ ++offset;
+ }
+ if (sb != null) {
+ String str = source.substring(offset, offset + length);
+ if (!asQuotedString) {
+ sb.append(str);
+ } else {
+ sb.append('"');
+ sb.append(ScriptRuntime.escapeString(str));
+ sb.append('"');
+ }
+ }
+ return offset + length;
+ }
+
+ private static int printSourceNumber(String source, int offset,
+ StringBuffer sb)
+ {
+ double number = 0.0;
+ char type = source.charAt(offset);
+ ++offset;
+ if (type == 'S') {
+ if (sb != null) {
+ int ival = source.charAt(offset);
+ number = ival;
+ }
+ ++offset;
+ } else if (type == 'J' || type == 'D') {
+ if (sb != null) {
+ long lbits;
+ lbits = (long)source.charAt(offset) << 48;
+ lbits |= (long)source.charAt(offset + 1) << 32;
+ lbits |= (long)source.charAt(offset + 2) << 16;
+ lbits |= source.charAt(offset + 3);
+ if (type == 'J') {
+ number = lbits;
+ } else {
+ number = Double.longBitsToDouble(lbits);
+ }
+ }
+ offset += 4;
+ } else {
+ // Bad source
+ throw new RuntimeException();
+ }
+ if (sb != null) {
+ sb.append(ScriptRuntime.numberToString(number, 10));
+ }
+ return offset;
+ }
+
+ private char[] sourceBuffer = new char[128];
+
+// Per script/function source buffer top: parent source does not include a
+// nested functions source and uses function index as a reference instead.
+ private int sourceTop;
+
+// whether to do a debug print of the source information, when decompiling.
+ private static final boolean printSource = false;
+
+}
diff --git a/bin/yuicompressor-2.3.4/src/org/mozilla/javascript/Parser.java b/bin/yuicompressor-2.3.4/src/org/mozilla/javascript/Parser.java
new file mode 100644
index 0000000..e92f44d
--- /dev/null
+++ b/bin/yuicompressor-2.3.4/src/org/mozilla/javascript/Parser.java
@@ -0,0 +1,2170 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Mike Ang
+ * Igor Bukanov
+ * Yuh-Ruey Chen
+ * Ethan Hugg
+ * Bob Jervis
+ * Terry Lucas
+ * Mike McCabe
+ * Milen Nankov
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.javascript;
+
+import java.io.Reader;
+import java.io.IOException;
+import java.util.Hashtable;
+
+/**
+ * This class implements the JavaScript parser.
+ *
+ * It is based on the C source files jsparse.c and jsparse.h
+ * in the jsref package.
+ *
+ * @see TokenStream
+ *
+ * @author Mike McCabe
+ * @author Brendan Eich
+ */
+
+public class Parser
+{
+ // TokenInformation flags : currentFlaggedToken stores them together
+ // with token type
+ final static int
+ CLEAR_TI_MASK = 0xFFFF, // mask to clear token information bits
+ TI_AFTER_EOL = 1 << 16, // first token of the source line
+ TI_CHECK_LABEL = 1 << 17; // indicates to check for label
+
+ CompilerEnvirons compilerEnv;
+ private ErrorReporter errorReporter;
+ private String sourceURI;
+ boolean calledByCompileFunction;
+
+ private TokenStream ts;
+ private int currentFlaggedToken;
+ private int syntaxErrorCount;
+
+ private IRFactory nf;
+
+ private int nestingOfFunction;
+
+ private Decompiler decompiler;
+ private String encodedSource;
+
+// The following are per function variables and should be saved/restored
+// during function parsing.
+// XXX Move to separated class?
+ ScriptOrFnNode currentScriptOrFn;
+ private int nestingOfWith;
+ private Hashtable labelSet; // map of label names into nodes
+ private ObjArray loopSet;
+ private ObjArray loopAndSwitchSet;
+ private boolean hasReturnValue;
+ private int functionEndFlags;
+// end of per function variables
+
+ // Exception to unwind
+ private static class ParserException extends RuntimeException
+ {
+ static final long serialVersionUID = 5882582646773765630L;
+ }
+
+ public Parser(CompilerEnvirons compilerEnv, ErrorReporter errorReporter)
+ {
+ this.compilerEnv = compilerEnv;
+ this.errorReporter = errorReporter;
+ }
+
+ protected Decompiler createDecompiler(CompilerEnvirons compilerEnv)
+ {
+ return new Decompiler();
+ }
+
+ void addStrictWarning(String messageId, String messageArg)
+ {
+ if (compilerEnv.isStrictMode())
+ addWarning(messageId, messageArg);
+ }
+
+ void addWarning(String messageId, String messageArg)
+ {
+ String message = ScriptRuntime.getMessage1(messageId, messageArg);
+ if (compilerEnv.reportWarningAsError()) {
+ ++syntaxErrorCount;
+ errorReporter.error(message, sourceURI, ts.getLineno(),
+ ts.getLine(), ts.getOffset());
+ } else
+ errorReporter.warning(message, sourceURI, ts.getLineno(),
+ ts.getLine(), ts.getOffset());
+ }
+
+ void addError(String messageId)
+ {
+ ++syntaxErrorCount;
+ String message = ScriptRuntime.getMessage0(messageId);
+ errorReporter.error(message, sourceURI, ts.getLineno(),
+ ts.getLine(), ts.getOffset());
+ }
+
+ void addError(String messageId, String messageArg)
+ {
+ ++syntaxErrorCount;
+ String message = ScriptRuntime.getMessage1(messageId, messageArg);
+ errorReporter.error(message, sourceURI, ts.getLineno(),
+ ts.getLine(), ts.getOffset());
+ }
+
+ RuntimeException reportError(String messageId)
+ {
+ addError(messageId);
+
+ // Throw a ParserException exception to unwind the recursive descent
+ // parse.
+ throw new ParserException();
+ }
+
+ private int peekToken()
+ throws IOException
+ {
+ int tt = currentFlaggedToken;
+ if (tt == Token.EOF) {
+
+ while ((tt = ts.getToken()) == Token.SPECIALCOMMENT) {
+ /* Support for JScript conditional comments */
+ decompiler.addJScriptConditionalComment(ts.getString());
+ }
+
+ if (tt == Token.EOL) {
+ do {
+ tt = ts.getToken();
+
+ if (tt == Token.SPECIALCOMMENT) {
+ /* Support for JScript conditional comments */
+ decompiler.addJScriptConditionalComment(ts.getString());
+ }
+
+ } while (tt == Token.EOL || tt == Token.SPECIALCOMMENT);
+ tt |= TI_AFTER_EOL;
+ }
+ currentFlaggedToken = tt;
+ }
+ return tt & CLEAR_TI_MASK;
+ }
+
+ private int peekFlaggedToken()
+ throws IOException
+ {
+ peekToken();
+ return currentFlaggedToken;
+ }
+
+ private void consumeToken()
+ {
+ currentFlaggedToken = Token.EOF;
+ }
+
+ private int nextToken()
+ throws IOException
+ {
+ int tt = peekToken();
+ consumeToken();
+ return tt;
+ }
+
+ private int nextFlaggedToken()
+ throws IOException
+ {
+ peekToken();
+ int ttFlagged = currentFlaggedToken;
+ consumeToken();
+ return ttFlagged;
+ }
+
+ private boolean matchToken(int toMatch)
+ throws IOException
+ {
+ int tt = peekToken();
+ if (tt != toMatch) {
+ return false;
+ }
+ consumeToken();
+ return true;
+ }
+
+ private int peekTokenOrEOL()
+ throws IOException
+ {
+ int tt = peekToken();
+ // Check for last peeked token flags
+ if ((currentFlaggedToken & TI_AFTER_EOL) != 0) {
+ tt = Token.EOL;
+ }
+ return tt;
+ }
+
+ private void setCheckForLabel()
+ {
+ if ((currentFlaggedToken & CLEAR_TI_MASK) != Token.NAME)
+ throw Kit.codeBug();
+ currentFlaggedToken |= TI_CHECK_LABEL;
+ }
+
+ private void mustMatchToken(int toMatch, String messageId)
+ throws IOException, ParserException
+ {
+ if (!matchToken(toMatch)) {
+ reportError(messageId);
+ }
+ }
+
+ private void mustHaveXML()
+ {
+ if (!compilerEnv.isXmlAvailable()) {
+ reportError("msg.XML.not.available");
+ }
+ }
+
+ public String getEncodedSource()
+ {
+ return encodedSource;
+ }
+
+ public boolean eof()
+ {
+ return ts.eof();
+ }
+
+ boolean insideFunction()
+ {
+ return nestingOfFunction != 0;
+ }
+
+ private Node enterLoop(Node loopLabel)
+ {
+ Node loop = nf.createLoopNode(loopLabel, ts.getLineno());
+ if (loopSet == null) {
+ loopSet = new ObjArray();
+ if (loopAndSwitchSet == null) {
+ loopAndSwitchSet = new ObjArray();
+ }
+ }
+ loopSet.push(loop);
+ loopAndSwitchSet.push(loop);
+ return loop;
+ }
+
+ private void exitLoop()
+ {
+ loopSet.pop();
+ loopAndSwitchSet.pop();
+ }
+
+ private Node enterSwitch(Node switchSelector, int lineno)
+ {
+ Node switchNode = nf.createSwitch(switchSelector, lineno);
+ if (loopAndSwitchSet == null) {
+ loopAndSwitchSet = new ObjArray();
+ }
+ loopAndSwitchSet.push(switchNode);
+ return switchNode;
+ }
+
+ private void exitSwitch()
+ {
+ loopAndSwitchSet.pop();
+ }
+
+ /*
+ * Build a parse tree from the given sourceString.
+ *
+ * @return an Object representing the parsed
+ * program. If the parse fails, null will be returned. (The
+ * parse failure will result in a call to the ErrorReporter from
+ * CompilerEnvirons.)
+ */
+ public ScriptOrFnNode parse(String sourceString,
+ String sourceURI, int lineno)
+ {
+ this.sourceURI = sourceURI;
+ this.ts = new TokenStream(this, null, sourceString, lineno);
+ try {
+ return parse();
+ } catch (IOException ex) {
+ // Should never happen
+ throw new IllegalStateException();
+ }
+ }
+
+ /*
+ * Build a parse tree from the given sourceString.
+ *
+ * @return an Object representing the parsed
+ * program. If the parse fails, null will be returned. (The
+ * parse failure will result in a call to the ErrorReporter from
+ * CompilerEnvirons.)
+ */
+ public ScriptOrFnNode parse(Reader sourceReader,
+ String sourceURI, int lineno)
+ throws IOException
+ {
+ this.sourceURI = sourceURI;
+ this.ts = new TokenStream(this, sourceReader, null, lineno);
+ return parse();
+ }
+
+ private ScriptOrFnNode parse()
+ throws IOException
+ {
+ this.decompiler = createDecompiler(compilerEnv);
+ this.nf = new IRFactory(this);
+ currentScriptOrFn = nf.createScript();
+ int sourceStartOffset = decompiler.getCurrentOffset();
+ this.encodedSource = null;
+ decompiler.addToken(Token.SCRIPT);
+
+ this.currentFlaggedToken = Token.EOF;
+ this.syntaxErrorCount = 0;
+
+ int baseLineno = ts.getLineno(); // line number where source starts
+
+ /* so we have something to add nodes to until
+ * we've collected all the source */
+ Node pn = nf.createLeaf(Token.BLOCK);
+
+ try {
+ for (;;) {
+ int tt = peekToken();
+
+ if (tt <= Token.EOF) {
+ break;
+ }
+
+ Node n;
+ if (tt == Token.FUNCTION) {
+ consumeToken();
+ try {
+ n = function(calledByCompileFunction
+ ? FunctionNode.FUNCTION_EXPRESSION
+ : FunctionNode.FUNCTION_STATEMENT);
+ } catch (ParserException e) {
+ break;
+ }
+ } else {
+ n = statement();
+ }
+ nf.addChildToBack(pn, n);
+ }
+ } catch (StackOverflowError ex) {
+ String msg = ScriptRuntime.getMessage0(
+ "msg.too.deep.parser.recursion");
+ throw Context.reportRuntimeError(msg, sourceURI,
+ ts.getLineno(), null, 0);
+ }
+
+ if (this.syntaxErrorCount != 0) {
+ String msg = String.valueOf(this.syntaxErrorCount);
+ msg = ScriptRuntime.getMessage1("msg.got.syntax.errors", msg);
+ throw errorReporter.runtimeError(msg, sourceURI, baseLineno,
+ null, 0);
+ }
+
+ currentScriptOrFn.setSourceName(sourceURI);
+ currentScriptOrFn.setBaseLineno(baseLineno);
+ currentScriptOrFn.setEndLineno(ts.getLineno());
+
+ int sourceEndOffset = decompiler.getCurrentOffset();
+ currentScriptOrFn.setEncodedSourceBounds(sourceStartOffset,
+ sourceEndOffset);
+
+ nf.initScript(currentScriptOrFn, pn);
+
+ if (compilerEnv.isGeneratingSource()) {
+ encodedSource = decompiler.getEncodedSource();
+ }
+ this.decompiler = null; // It helps GC
+
+ return currentScriptOrFn;
+ }
+
+ /*
+ * The C version of this function takes an argument list,
+ * which doesn't seem to be needed for tree generation...
+ * it'd only be useful for checking argument hiding, which
+ * I'm not doing anyway...
+ */
+ private Node parseFunctionBody()
+ throws IOException
+ {
+ ++nestingOfFunction;
+ Node pn = nf.createBlock(ts.getLineno());
+ try {
+ bodyLoop: for (;;) {
+ Node n;
+ int tt = peekToken();
+ switch (tt) {
+ case Token.ERROR:
+ case Token.EOF:
+ case Token.RC:
+ break bodyLoop;
+
+ case Token.FUNCTION:
+ consumeToken();
+ n = function(FunctionNode.FUNCTION_STATEMENT);
+ break;
+ default:
+ n = statement();
+ break;
+ }
+ nf.addChildToBack(pn, n);
+ }
+ } catch (ParserException e) {
+ // Ignore it
+ } finally {
+ --nestingOfFunction;
+ }
+
+ return pn;
+ }
+
+ private Node function(int functionType)
+ throws IOException, ParserException
+ {
+ int syntheticType = functionType;
+ int baseLineno = ts.getLineno(); // line number where source starts
+
+ int functionSourceStart = decompiler.markFunctionStart(functionType);
+ String name;
+ Node memberExprNode = null;
+ if (matchToken(Token.NAME)) {
+ name = ts.getString();
+ decompiler.addName(name);
+ if (!matchToken(Token.LP)) {
+ if (compilerEnv.isAllowMemberExprAsFunctionName()) {
+ // Extension to ECMA: if 'function <name>' does not follow
+ // by '(', assume <name> starts memberExpr
+ Node memberExprHead = nf.createName(name);
+ name = "";
+ memberExprNode = memberExprTail(false, memberExprHead);
+ }
+ mustMatchToken(Token.LP, "msg.no.paren.parms");
+ }
+ } else if (matchToken(Token.LP)) {
+ // Anonymous function
+ name = "";
+ } else {
+ name = "";
+ if (compilerEnv.isAllowMemberExprAsFunctionName()) {
+ // Note that memberExpr can not start with '(' like
+ // in function (1+2).toString(), because 'function (' already
+ // processed as anonymous function
+ memberExprNode = memberExpr(false);
+ }
+ mustMatchToken(Token.LP, "msg.no.paren.parms");
+ }
+
+ if (memberExprNode != null) {
+ syntheticType = FunctionNode.FUNCTION_EXPRESSION;
+ }
+
+ boolean nested = insideFunction();
+
+ FunctionNode fnNode = nf.createFunction(name);
+ if (nested || nestingOfWith > 0) {
+ // 1. Nested functions are not affected by the dynamic scope flag
+ // as dynamic scope is already a parent of their scope.
+ // 2. Functions defined under the with statement also immune to
+ // this setup, in which case dynamic scope is ignored in favor
+ // of with object.
+ fnNode.itsIgnoreDynamicScope = true;
+ }
+
+ int functionIndex = currentScriptOrFn.addFunction(fnNode);
+
+ int functionSourceEnd;
+
+ ScriptOrFnNode savedScriptOrFn = currentScriptOrFn;
+ currentScriptOrFn = fnNode;
+ int savedNestingOfWith = nestingOfWith;
+ nestingOfWith = 0;
+ Hashtable savedLabelSet = labelSet;
+ labelSet = null;
+ ObjArray savedLoopSet = loopSet;
+ loopSet = null;
+ ObjArray savedLoopAndSwitchSet = loopAndSwitchSet;
+ loopAndSwitchSet = null;
+ boolean savedHasReturnValue = hasReturnValue;
+ int savedFunctionEndFlags = functionEndFlags;
+
+ Node body;
+ try {
+ decompiler.addToken(Token.LP);
+ if (!matchToken(Token.RP)) {
+ boolean first = true;
+ do {
+ if (!first)
+ decompiler.addToken(Token.COMMA);
+ first = false;
+ mustMatchToken(Token.NAME, "msg.no.parm");
+ String s = ts.getString();
+ if (fnNode.hasParamOrVar(s)) {
+ addWarning("msg.dup.parms", s);
+ }
+ fnNode.addParam(s);
+ decompiler.addName(s);
+ } while (matchToken(Token.COMMA));
+
+ mustMatchToken(Token.RP, "msg.no.paren.after.parms");
+ }
+ decompiler.addToken(Token.RP);
+
+ mustMatchToken(Token.LC, "msg.no.brace.body");
+ decompiler.addEOL(Token.LC);
+ body = parseFunctionBody();
+ mustMatchToken(Token.RC, "msg.no.brace.after.body");
+
+ if (compilerEnv.isStrictMode() && !body.hasConsistentReturnUsage())
+ {
+ String msg = name.length() > 0 ? "msg.no.return.value"
+ : "msg.anon.no.return.value";
+ addStrictWarning(msg, name);
+ }
+
+ decompiler.addToken(Token.RC);
+ functionSourceEnd = decompiler.markFunctionEnd(functionSourceStart);
+ if (functionType != FunctionNode.FUNCTION_EXPRESSION) {
+ // Add EOL only if function is not part of expression
+ // since it gets SEMI + EOL from Statement in that case
+ decompiler.addToken(Token.EOL);
+ }
+ }
+ finally {
+ hasReturnValue = savedHasReturnValue;
+ functionEndFlags = savedFunctionEndFlags;
+ loopAndSwitchSet = savedLoopAndSwitchSet;
+ loopSet = savedLoopSet;
+ labelSet = savedLabelSet;
+ nestingOfWith = savedNestingOfWith;
+ currentScriptOrFn = savedScriptOrFn;
+ }
+
+ fnNode.setEncodedSourceBounds(functionSourceStart, functionSourceEnd);
+ fnNode.setSourceName(sourceURI);
+ fnNode.setBaseLineno(baseLineno);
+ fnNode.setEndLineno(ts.getLineno());
+
+ if (name != null) {
+ int index = currentScriptOrFn.getParamOrVarIndex(name);
+ if (index >= 0 && index < currentScriptOrFn.getParamCount())
+ addStrictWarning("msg.var.hides.arg", name);
+ }
+
+ Node pn = nf.initFunction(fnNode, functionIndex, body, syntheticType);
+ if (memberExprNode != null) {
+ pn = nf.createAssignment(Token.ASSIGN, memberExprNode, pn);
+ if (functionType != FunctionNode.FUNCTION_EXPRESSION) {
+ // XXX check JScript behavior: should it be createExprStatement?
+ pn = nf.createExprStatementNoReturn(pn, baseLineno);
+ }
+ }
+ return pn;
+ }
+
+ private Node statements()
+ throws IOException
+ {
+ Node pn = nf.createBlock(ts.getLineno());
+
+ int tt;
+ while((tt = peekToken()) > Token.EOF && tt != Token.RC) {
+ nf.addChildToBack(pn, statement());
+ }
+
+ return pn;
+ }
+
+ private Node condition()
+ throws IOException, ParserException
+ {
+ mustMatchToken(Token.LP, "msg.no.paren.cond");
+ decompiler.addToken(Token.LP);
+ Node pn = expr(false);
+ mustMatchToken(Token.RP, "msg.no.paren.after.cond");
+ decompiler.addToken(Token.RP);
+
+ // Report strict warning on code like "if (a = 7) ...". Suppress the
+ // warning if the condition is parenthesized, like "if ((a = 7)) ...".
+ if (pn.getProp(Node.PARENTHESIZED_PROP) == null &&
+ (pn.getType() == Token.SETNAME || pn.getType() == Token.SETPROP ||
+ pn.getType() == Token.SETELEM))
+ {
+ addStrictWarning("msg.equal.as.assign", "");
+ }
+ return pn;
+ }
+
+ // match a NAME; return null if no match.
+ private Node matchJumpLabelName()
+ throws IOException, ParserException
+ {
+ Node label = null;
+
+ int tt = peekTokenOrEOL();
+ if (tt == Token.NAME) {
+ consumeToken();
+ String name = ts.getString();
+ decompiler.addName(name);
+ if (labelSet != null) {
+ label = (Node)labelSet.get(name);
+ }
+ if (label == null) {
+ reportError("msg.undef.label");
+ }
+ }
+
+ return label;
+ }
+
+ private Node statement()
+ throws IOException
+ {
+ try {
+ Node pn = statementHelper(null);
+ if (pn != null) {
+ if (compilerEnv.isStrictMode() && !pn.hasSideEffects())
+ addStrictWarning("msg.no.side.effects", "");
+ return pn;
+ }
+ } catch (ParserException e) { }
+
+ // skip to end of statement
+ int lineno = ts.getLineno();
+ guessingStatementEnd: for (;;) {
+ int tt = peekTokenOrEOL();
+ consumeToken();
+ switch (tt) {
+ case Token.ERROR:
+ case Token.EOF:
+ case Token.EOL:
+ case Token.SEMI:
+ break guessingStatementEnd;
+ }
+ }
+ return nf.createExprStatement(nf.createName("error"), lineno);
+ }
+
+ /**
+ * Whether the "catch (e: e instanceof Exception) { ... }" syntax
+ * is implemented.
+ */
+
+ private Node statementHelper(Node statementLabel)
+ throws IOException, ParserException
+ {
+ Node pn = null;
+
+ int tt;
+
+ tt = peekToken();
+
+ switch(tt) {
+ case Token.IF: {
+ consumeToken();
+
+ decompiler.addToken(Token.IF);
+ int lineno = ts.getLineno();
+ Node cond = condition();
+ decompiler.addEOL(Token.LC);
+ Node ifTrue = statement();
+ Node ifFalse = null;
+ if (matchToken(Token.ELSE)) {
+ decompiler.addToken(Token.RC);
+ decompiler.addToken(Token.ELSE);
+ decompiler.addEOL(Token.LC);
+ ifFalse = statement();
+ }
+ decompiler.addEOL(Token.RC);
+ pn = nf.createIf(cond, ifTrue, ifFalse, lineno);
+ return pn;
+ }
+
+ case Token.SWITCH: {
+ consumeToken();
+
+ decompiler.addToken(Token.SWITCH);
+ int lineno = ts.getLineno();
+ mustMatchToken(Token.LP, "msg.no.paren.switch");
+ decompiler.addToken(Token.LP);
+ pn = enterSwitch(expr(false), lineno);
+ try {
+ mustMatchToken(Token.RP, "msg.no.paren.after.switch");
+ decompiler.addToken(Token.RP);
+ mustMatchToken(Token.LC, "msg.no.brace.switch");
+ decompiler.addEOL(Token.LC);
+
+ boolean hasDefault = false;
+ switchLoop: for (;;) {
+ tt = nextToken();
+ Node caseExpression;
+ switch (tt) {
+ case Token.RC:
+ break switchLoop;
+
+ case Token.CASE:
+ decompiler.addToken(Token.CASE);
+ caseExpression = expr(false);
+ mustMatchToken(Token.COLON, "msg.no.colon.case");
+ decompiler.addEOL(Token.COLON);
+ break;
+
+ case Token.DEFAULT:
+ if (hasDefault) {
+ reportError("msg.double.switch.default");
+ }
+ decompiler.addToken(Token.DEFAULT);
+ hasDefault = true;
+ caseExpression = null;
+ mustMatchToken(Token.COLON, "msg.no.colon.case");
+ decompiler.addEOL(Token.COLON);
+ break;
+
+ default:
+ reportError("msg.bad.switch");
+ break switchLoop;
+ }
+
+ Node block = nf.createLeaf(Token.BLOCK);
+ while ((tt = peekToken()) != Token.RC
+ && tt != Token.CASE
+ && tt != Token.DEFAULT
+ && tt != Token.EOF)
+ {
+ nf.addChildToBack(block, statement());
+ }
+
+ // caseExpression == null => add default lable
+ nf.addSwitchCase(pn, caseExpression, block);
+ }
+ decompiler.addEOL(Token.RC);
+ nf.closeSwitch(pn);
+ } finally {
+ exitSwitch();
+ }
+ return pn;
+ }
+
+ case Token.WHILE: {
+ consumeToken();
+ decompiler.addToken(Token.WHILE);
+
+ Node loop = enterLoop(statementLabel);
+ try {
+ Node cond = condition();
+ decompiler.addEOL(Token.LC);
+ Node body = statement();
+ decompiler.addEOL(Token.RC);
+ pn = nf.createWhile(loop, cond, body);
+ } finally {
+ exitLoop();
+ }
+ return pn;
+ }
+
+ case Token.DO: {
+ consumeToken();
+ decompiler.addToken(Token.DO);
+ decompiler.addEOL(Token.LC);
+
+ Node loop = enterLoop(statementLabel);
+ try {
+ Node body = statement();
+ decompiler.addToken(Token.RC);
+ mustMatchToken(Token.WHILE, "msg.no.while.do");
+ decompiler.addToken(Token.WHILE);
+ Node cond = condition();
+ pn = nf.createDoWhile(loop, body, cond);
+ } finally {
+ exitLoop();
+ }
+ // Always auto-insert semicon to follow SpiderMonkey:
+ // It is required by EMAScript but is ignored by the rest of
+ // world, see bug 238945
+ matchToken(Token.SEMI);
+ decompiler.addEOL(Token.SEMI);
+ return pn;
+ }
+
+ case Token.FOR: {
+ consumeToken();
+ boolean isForEach = false;
+ decompiler.addToken(Token.FOR);
+
+ Node loop = enterLoop(statementLabel);
+ try {
+
+ Node init; // Node init is also foo in 'foo in Object'
+ Node cond; // Node cond is also object in 'foo in Object'
+ Node incr = null; // to kill warning
+ Node body;
+
+ // See if this is a for each () instead of just a for ()
+ if (matchToken(Token.NAME)) {
+ decompiler.addName(ts.getString());
+ if (ts.getString().equals("each")) {
+ isForEach = true;
+ } else {
+ reportError("msg.no.paren.for");
+ }
+ }
+
+ mustMatchToken(Token.LP, "msg.no.paren.for");
+ decompiler.addToken(Token.LP);
+ tt = peekToken();
+ if (tt == Token.SEMI) {
+ init = nf.createLeaf(Token.EMPTY);
+ } else {
+ if (tt == Token.VAR) {
+ // set init to a var list or initial
+ consumeToken(); // consume the 'var' token
+ init = variables(Token.FOR);
+ }
+ else {
+ init = expr(true);
+ }
+ }
+
+ if (matchToken(Token.IN)) {
+ decompiler.addToken(Token.IN);
+ // 'cond' is the object over which we're iterating
+ cond = expr(false);
+ } else { // ordinary for loop
+ mustMatchToken(Token.SEMI, "msg.no.semi.for");
+ decompiler.addToken(Token.SEMI);
+ if (peekToken() == Token.SEMI) {
+ // no loop condition
+ cond = nf.createLeaf(Token.EMPTY);
+ } else {
+ cond = expr(false);
+ }
+
+ mustMatchToken(Token.SEMI, "msg.no.semi.for.cond");
+ decompiler.addToken(Token.SEMI);
+ if (peekToken() == Token.RP) {
+ incr = nf.createLeaf(Token.EMPTY);
+ } else {
+ incr = expr(false);
+ }
+ }
+
+ mustMatchToken(Token.RP, "msg.no.paren.for.ctrl");
+ decompiler.addToken(Token.RP);
+ decompiler.addEOL(Token.LC);
+ body = statement();
+ decompiler.addEOL(Token.RC);
+
+ if (incr == null) {
+ // cond could be null if 'in obj' got eaten
+ // by the init node.
+ pn = nf.createForIn(loop, init, cond, body, isForEach);
+ } else {
+ pn = nf.createFor(loop, init, cond, incr, body);
+ }
+ } finally {
+ exitLoop();
+ }
+ return pn;
+ }
+
+ case Token.TRY: {
+ consumeToken();
+ int lineno = ts.getLineno();
+
+ Node tryblock;
+ Node catchblocks = null;
+ Node finallyblock = null;
+
+ decompiler.addToken(Token.TRY);
+ decompiler.addEOL(Token.LC);
+ tryblock = statement();
+ decompiler.addEOL(Token.RC);
+
+ catchblocks = nf.createLeaf(Token.BLOCK);
+
+ boolean sawDefaultCatch = false;
+ int peek = peekToken();
+ if (peek == Token.CATCH) {
+ while (matchToken(Token.CATCH)) {
+ if (sawDefaultCatch) {
+ reportError("msg.catch.unreachable");
+ }
+ decompiler.addToken(Token.CATCH);
+ mustMatchToken(Token.LP, "msg.no.paren.catch");
+ decompiler.addToken(Token.LP);
+
+ mustMatchToken(Token.NAME, "msg.bad.catchcond");
+ String varName = ts.getString();
+ decompiler.addName(varName);
+
+ Node catchCond = null;
+ if (matchToken(Token.IF)) {
+ decompiler.addToken(Token.IF);
+ catchCond = expr(false);
+ } else {
+ sawDefaultCatch = true;
+ }
+
+ mustMatchToken(Token.RP, "msg.bad.catchcond");
+ decompiler.addToken(Token.RP);
+ mustMatchToken(Token.LC, "msg.no.brace.catchblock");
+ decompiler.addEOL(Token.LC);
+
+ nf.addChildToBack(catchblocks,
+ nf.createCatch(varName, catchCond,
+ statements(),
+ ts.getLineno()));
+
+ mustMatchToken(Token.RC, "msg.no.brace.after.body");
+ decompiler.addEOL(Token.RC);
+ }
+ } else if (peek != Token.FINALLY) {
+ mustMatchToken(Token.FINALLY, "msg.try.no.catchfinally");
+ }
+
+ if (matchToken(Token.FINALLY)) {
+ decompiler.addToken(Token.FINALLY);
+ decompiler.addEOL(Token.LC);
+ finallyblock = statement();
+ decompiler.addEOL(Token.RC);
+ }
+
+ pn = nf.createTryCatchFinally(tryblock, catchblocks,
+ finallyblock, lineno);
+
+ return pn;
+ }
+
+ case Token.THROW: {
+ consumeToken();
+ if (peekTokenOrEOL() == Token.EOL) {
+ // ECMAScript does not allow new lines before throw expression,
+ // see bug 256617
+ reportError("msg.bad.throw.eol");
+ }
+
+ int lineno = ts.getLineno();
+ decompiler.addToken(Token.THROW);
+ pn = nf.createThrow(expr(false), lineno);
+ break;
+ }
+
+ case Token.BREAK: {
+ consumeToken();
+ int lineno = ts.getLineno();
+
+ decompiler.addToken(Token.BREAK);
+
+ // matchJumpLabelName only matches if there is one
+ Node breakStatement = matchJumpLabelName();
+ if (breakStatement == null) {
+ if (loopAndSwitchSet == null || loopAndSwitchSet.size() == 0) {
+ reportError("msg.bad.break");
+ return null;
+ }
+ breakStatement = (Node)loopAndSwitchSet.peek();
+ }
+ pn = nf.createBreak(breakStatement, lineno);
+ break;
+ }
+
+ case Token.CONTINUE: {
+ consumeToken();
+ int lineno = ts.getLineno();
+
+ decompiler.addToken(Token.CONTINUE);
+
+ Node loop;
+ // matchJumpLabelName only matches if there is one
+ Node label = matchJumpLabelName();
+ if (label == null) {
+ if (loopSet == null || loopSet.size() == 0) {
+ reportError("msg.continue.outside");
+ return null;
+ }
+ loop = (Node)loopSet.peek();
+ } else {
+ loop = nf.getLabelLoop(label);
+ if (loop == null) {
+ reportError("msg.continue.nonloop");
+ return null;
+ }
+ }
+ pn = nf.createContinue(loop, lineno);
+ break;
+ }
+
+ case Token.WITH: {
+ consumeToken();
+
+ decompiler.addToken(Token.WITH);
+ int lineno = ts.getLineno();
+ mustMatchToken(Token.LP, "msg.no.paren.with");
+ decompiler.addToken(Token.LP);
+ Node obj = expr(false);
+ mustMatchToken(Token.RP, "msg.no.paren.after.with");
+ decompiler.addToken(Token.RP);
+ decompiler.addEOL(Token.LC);
+
+ ++nestingOfWith;
+ Node body;
+ try {
+ body = statement();
+ } finally {
+ --nestingOfWith;
+ }
+
+ decompiler.addEOL(Token.RC);
+
+ pn = nf.createWith(obj, body, lineno);
+ return pn;
+ }
+
+ case Token.CONST:
+ case Token.VAR: {
+ consumeToken();
+ pn = variables(tt);
+ break;
+ }
+
+ case Token.RETURN: {
+ if (!insideFunction()) {
+ reportError("msg.bad.return");
+ }
+ consumeToken();
+ decompiler.addToken(Token.RETURN);
+ int lineno = ts.getLineno();
+
+ Node retExpr;
+ /* This is ugly, but we don't want to require a semicolon. */
+ tt = peekTokenOrEOL();
+ switch (tt) {
+ case Token.SEMI:
+ case Token.RC:
+ case Token.EOF:
+ case Token.EOL:
+ case Token.ERROR:
+ retExpr = null;
+ break;
+ default:
+ retExpr = expr(false);
+ hasReturnValue = true;
+ }
+ pn = nf.createReturn(retExpr, lineno);
+
+ // see if we need a strict mode warning
+ if (retExpr == null) {
+ if (functionEndFlags == Node.END_RETURNS_VALUE)
+ addStrictWarning("msg.return.inconsistent", "");
+
+ functionEndFlags |= Node.END_RETURNS;
+ } else {
+ if (functionEndFlags == Node.END_RETURNS)
+ addStrictWarning("msg.return.inconsistent", "");
+
+ functionEndFlags |= Node.END_RETURNS_VALUE;
+ }
+
+ break;
+ }
+
+ case Token.LC:
+ consumeToken();
+ if (statementLabel != null) {
+ decompiler.addToken(Token.LC);
+ }
+ pn = statements();
+ mustMatchToken(Token.RC, "msg.no.brace.block");
+ if (statementLabel != null) {
+ decompiler.addEOL(Token.RC);
+ }
+ return pn;
+
+ case Token.ERROR:
+ // Fall thru, to have a node for error recovery to work on
+ case Token.SEMI:
+ consumeToken();
+ pn = nf.createLeaf(Token.EMPTY);
+ return pn;
+
+ case Token.FUNCTION: {
+ consumeToken();
+ pn = function(FunctionNode.FUNCTION_EXPRESSION_STATEMENT);
+ return pn;
+ }
+
+ case Token.DEFAULT :
+ consumeToken();
+ mustHaveXML();
+
+ decompiler.addToken(Token.DEFAULT);
+ int nsLine = ts.getLineno();
+
+ if (!(matchToken(Token.NAME)
+ && ts.getString().equals("xml")))
+ {
+ reportError("msg.bad.namespace");
+ }
+ decompiler.addName(" xml");
+
+ if (!(matchToken(Token.NAME)
+ && ts.getString().equals("namespace")))
+ {
+ reportError("msg.bad.namespace");
+ }
+ decompiler.addName(" namespace");
+
+ if (!matchToken(Token.ASSIGN)) {
+ reportError("msg.bad.namespace");
+ }
+ decompiler.addToken(Token.ASSIGN);
+
+ Node expr = expr(false);
+ pn = nf.createDefaultNamespace(expr, nsLine);
+ break;
+
+ case Token.NAME: {
+ int lineno = ts.getLineno();
+ String name = ts.getString();
+ setCheckForLabel();
+ pn = expr(false);
+ if (pn.getType() != Token.LABEL) {
+ pn = nf.createExprStatement(pn, lineno);
+ } else {
+ // Parsed the label: push back token should be
+ // colon that primaryExpr left untouched.
+ if (peekToken() != Token.COLON) Kit.codeBug();
+ consumeToken();
+ // depend on decompiling lookahead to guess that that
+ // last name was a label.
+ decompiler.addName(name);
+ decompiler.addEOL(Token.COLON);
+
+ if (labelSet == null) {
+ labelSet = new Hashtable();
+ } else if (labelSet.containsKey(name)) {
+ reportError("msg.dup.label");
+ }
+
+ boolean firstLabel;
+ if (statementLabel == null) {
+ firstLabel = true;
+ statementLabel = pn;
+ } else {
+ // Discard multiple label nodes and use only
+ // the first: it allows to simplify IRFactory
+ firstLabel = false;
+ }
+ labelSet.put(name, statementLabel);
+ try {
+ pn = statementHelper(statementLabel);
+ } finally {
+ labelSet.remove(name);
+ }
+ if (firstLabel) {
+ pn = nf.createLabeledStatement(statementLabel, pn);
+ }
+ return pn;
+ }
+ break;
+ }
+
+ default: {
+ int lineno = ts.getLineno();
+ pn = expr(false);
+ pn = nf.createExprStatement(pn, lineno);
+ break;
+ }
+ }
+
+ int ttFlagged = peekFlaggedToken();
+ switch (ttFlagged & CLEAR_TI_MASK) {
+ case Token.SEMI:
+ // Consume ';' as a part of expression
+ consumeToken();
+ break;
+ case Token.ERROR:
+ case Token.EOF:
+ case Token.RC:
+ // Autoinsert ;
+ break;
+ default:
+ if ((ttFlagged & TI_AFTER_EOL) == 0) {
+ // Report error if no EOL or autoinsert ; otherwise
+ reportError("msg.no.semi.stmt");
+ }
+ break;
+ }
+ decompiler.addEOL(Token.SEMI);
+
+ return pn;
+ }
+
+ /**
+ * Parse a 'var' or 'const' statement, or a 'var' init list in a for
+ * statement.
+ * @param context A token value: either VAR, CONST or FOR depending on
+ * context.
+ * @return The parsed statement
+ * @throws IOException
+ * @throws ParserException
+ */
+ private Node variables(int context)
+ throws IOException, ParserException
+ {
+ Node pn;
+ boolean first = true;
+
+ if (context == Token.CONST){
+ pn = nf.createVariables(Token.CONST, ts.getLineno());
+ decompiler.addToken(Token.CONST);
+ } else {
+ pn = nf.createVariables(Token.VAR, ts.getLineno());
+ decompiler.addToken(Token.VAR);
+ }
+
+ for (;;) {
+ Node name;
+ Node init;
+ mustMatchToken(Token.NAME, "msg.bad.var");
+ String s = ts.getString();
+
+ if (!first)
+ decompiler.addToken(Token.COMMA);
+ first = false;
+
+ decompiler.addName(s);
+
+ if (context == Token.CONST) {
+ if (!currentScriptOrFn.addConst(s)) {
+ // We know it's already defined, since addConst passes if
+ // it's not defined at all. The addVar call just confirms
+ // what it is.
+ if (currentScriptOrFn.addVar(s) != ScriptOrFnNode.DUPLICATE_CONST)
+ addError("msg.var.redecl", s);
+ else
+ addError("msg.const.redecl", s);
+ }
+ } else {
+ int dupState = currentScriptOrFn.addVar(s);
+ if (dupState == ScriptOrFnNode.DUPLICATE_CONST)
+ addError("msg.const.redecl", s);
+ else if (dupState == ScriptOrFnNode.DUPLICATE_PARAMETER)
+ addStrictWarning("msg.var.hides.arg", s);
+ else if (dupState == ScriptOrFnNode.DUPLICATE_VAR)
+ addStrictWarning("msg.var.redecl", s);
+ }
+ name = nf.createName(s);
+
+ // omitted check for argument hiding
+
+ if (matchToken(Token.ASSIGN)) {
+ decompiler.addToken(Token.ASSIGN);
+
+ init = assignExpr(context == Token.FOR);
+ nf.addChildToBack(name, init);
+ }
+ nf.addChildToBack(pn, name);
+ if (!matchToken(Token.COMMA))
+ break;
+ }
+ return pn;
+ }
+
+ private Node expr(boolean inForInit)
+ throws IOException, ParserException
+ {
+ Node pn = assignExpr(inForInit);
+ while (matchToken(Token.COMMA)) {
+ decompiler.addToken(Token.COMMA);
+ if (compilerEnv.isStrictMode() && !pn.hasSideEffects())
+ addStrictWarning("msg.no.side.effects", "");
+ pn = nf.createBinary(Token.COMMA, pn, assignExpr(inForInit));
+ }
+ return pn;
+ }
+
+ private Node assignExpr(boolean inForInit)
+ throws IOException, ParserException
+ {
+ Node pn = condExpr(inForInit);
+
+ int tt = peekToken();
+ if (Token.FIRST_ASSIGN <= tt && tt <= Token.LAST_ASSIGN) {
+ consumeToken();
+ decompiler.addToken(tt);
+ pn = nf.createAssignment(tt, pn, assignExpr(inForInit));
+ }
+
+ return pn;
+ }
+
+ private Node condExpr(boolean inForInit)
+ throws IOException, ParserException
+ {
+ Node pn = orExpr(inForInit);
+
+ if (matchToken(Token.HOOK)) {
+ decompiler.addToken(Token.HOOK);
+ Node ifTrue = assignExpr(false);
+ mustMatchToken(Token.COLON, "msg.no.colon.cond");
+ decompiler.addToken(Token.COLON);
+ Node ifFalse = assignExpr(inForInit);
+ return nf.createCondExpr(pn, ifTrue, ifFalse);
+ }
+
+ return pn;
+ }
+
+ private Node orExpr(boolean inForInit)
+ throws IOException, ParserException
+ {
+ Node pn = andExpr(inForInit);
+ if (matchToken(Token.OR)) {
+ decompiler.addToken(Token.OR);
+ pn = nf.createBinary(Token.OR, pn, orExpr(inForInit));
+ }
+
+ return pn;
+ }
+
+ private Node andExpr(boolean inForInit)
+ throws IOException, ParserException
+ {
+ Node pn = bitOrExpr(inForInit);
+ if (matchToken(Token.AND)) {
+ decompiler.addToken(Token.AND);
+ pn = nf.createBinary(Token.AND, pn, andExpr(inForInit));
+ }
+
+ return pn;
+ }
+
+ private Node bitOrExpr(boolean inForInit)
+ throws IOException, ParserException
+ {
+ Node pn = bitXorExpr(inForInit);
+ while (matchToken(Token.BITOR)) {
+ decompiler.addToken(Token.BITOR);
+ pn = nf.createBinary(Token.BITOR, pn, bitXorExpr(inForInit));
+ }
+ return pn;
+ }
+
+ private Node bitXorExpr(boolean inForInit)
+ throws IOException, ParserException
+ {
+ Node pn = bitAndExpr(inForInit);
+ while (matchToken(Token.BITXOR)) {
+ decompiler.addToken(Token.BITXOR);
+ pn = nf.createBinary(Token.BITXOR, pn, bitAndExpr(inForInit));
+ }
+ return pn;
+ }
+
+ private Node bitAndExpr(boolean inForInit)
+ throws IOException, ParserException
+ {
+ Node pn = eqExpr(inForInit);
+ while (matchToken(Token.BITAND)) {
+ decompiler.addToken(Token.BITAND);
+ pn = nf.createBinary(Token.BITAND, pn, eqExpr(inForInit));
+ }
+ return pn;
+ }
+
+ private Node eqExpr(boolean inForInit)
+ throws IOException, ParserException
+ {
+ Node pn = relExpr(inForInit);
+ for (;;) {
+ int tt = peekToken();
+ switch (tt) {
+ case Token.EQ:
+ case Token.NE:
+ case Token.SHEQ:
+ case Token.SHNE:
+ consumeToken();
+ int decompilerToken = tt;
+ int parseToken = tt;
+ if (compilerEnv.getLanguageVersion() == Context.VERSION_1_2) {
+ // JavaScript 1.2 uses shallow equality for == and != .
+ // In addition, convert === and !== for decompiler into
+ // == and != since the decompiler is supposed to show
+ // canonical source and in 1.2 ===, !== are allowed
+ // only as an alias to ==, !=.
+ switch (tt) {
+ case Token.EQ:
+ parseToken = Token.SHEQ;
+ break;
+ case Token.NE:
+ parseToken = Token.SHNE;
+ break;
+ case Token.SHEQ:
+ decompilerToken = Token.EQ;
+ break;
+ case Token.SHNE:
+ decompilerToken = Token.NE;
+ break;
+ }
+ }
+ decompiler.addToken(decompilerToken);
+ pn = nf.createBinary(parseToken, pn, relExpr(inForInit));
+ continue;
+ }
+ break;
+ }
+ return pn;
+ }
+
+ private Node relExpr(boolean inForInit)
+ throws IOException, ParserException
+ {
+ Node pn = shiftExpr();
+ for (;;) {
+ int tt = peekToken();
+ switch (tt) {
+ case Token.IN:
+ if (inForInit)
+ break;
+ // fall through
+ case Token.INSTANCEOF:
+ case Token.LE:
+ case Token.LT:
+ case Token.GE:
+ case Token.GT:
+ consumeToken();
+ decompiler.addToken(tt);
+ pn = nf.createBinary(tt, pn, shiftExpr());
+ continue;
+ }
+ break;
+ }
+ return pn;
+ }
+
+ private Node shiftExpr()
+ throws IOException, ParserException
+ {
+ Node pn = addExpr();
+ for (;;) {
+ int tt = peekToken();
+ switch (tt) {
+ case Token.LSH:
+ case Token.URSH:
+ case Token.RSH:
+ consumeToken();
+ decompiler.addToken(tt);
+ pn = nf.createBinary(tt, pn, addExpr());
+ continue;
+ }
+ break;
+ }
+ return pn;
+ }
+
+ private Node addExpr()
+ throws IOException, ParserException
+ {
+ Node pn = mulExpr();
+ for (;;) {
+ int tt = peekToken();
+ if (tt == Token.ADD || tt == Token.SUB) {
+ consumeToken();
+ decompiler.addToken(tt);
+ // flushNewLines
+ pn = nf.createBinary(tt, pn, mulExpr());
+ continue;
+ }
+ break;
+ }
+
+ return pn;
+ }
+
+ private Node mulExpr()
+ throws IOException, ParserException
+ {
+ Node pn = unaryExpr();
+ for (;;) {
+ int tt = peekToken();
+ switch (tt) {
+ case Token.MUL:
+ case Token.DIV:
+ case Token.MOD:
+ consumeToken();
+ decompiler.addToken(tt);
+ pn = nf.createBinary(tt, pn, unaryExpr());
+ continue;
+ }
+ break;
+ }
+
+ return pn;
+ }
+
+ private Node unaryExpr()
+ throws IOException, ParserException
+ {
+ int tt;
+
+ tt = peekToken();
+
+ switch(tt) {
+ case Token.VOID:
+ case Token.NOT:
+ case Token.BITNOT:
+ case Token.TYPEOF:
+ consumeToken();
+ decompiler.addToken(tt);
+ return nf.createUnary(tt, unaryExpr());
+
+ case Token.ADD:
+ consumeToken();
+ // Convert to special POS token in decompiler and parse tree
+ decompiler.addToken(Token.POS);
+ return nf.createUnary(Token.POS, unaryExpr());
+
+ case Token.SUB:
+ consumeToken();
+ // Convert to special NEG token in decompiler and parse tree
+ decompiler.addToken(Token.NEG);
+ return nf.createUnary(Token.NEG, unaryExpr());
+
+ case Token.INC:
+ case Token.DEC:
+ consumeToken();
+ decompiler.addToken(tt);
+ return nf.createIncDec(tt, false, memberExpr(true));
+
+ case Token.DELPROP:
+ consumeToken();
+ decompiler.addToken(Token.DELPROP);
+ return nf.createUnary(Token.DELPROP, unaryExpr());
+
+ case Token.ERROR:
+ consumeToken();
+ break;
+
+ // XML stream encountered in expression.
+ case Token.LT:
+ if (compilerEnv.isXmlAvailable()) {
+ consumeToken();
+ Node pn = xmlInitializer();
+ return memberExprTail(true, pn);
+ }
+ // Fall thru to the default handling of RELOP
+
+ default:
+ Node pn = memberExpr(true);
+
+ // Don't look across a newline boundary for a postfix incop.
+ tt = peekTokenOrEOL();
+ if (tt == Token.INC || tt == Token.DEC) {
+ consumeToken();
+ decompiler.addToken(tt);
+ return nf.createIncDec(tt, true, pn);
+ }
+ return pn;
+ }
+ return nf.createName("err"); // Only reached on error. Try to continue.
+
+ }
+
+ private Node xmlInitializer() throws IOException
+ {
+ int tt = ts.getFirstXMLToken();
+ if (tt != Token.XML && tt != Token.XMLEND) {
+ reportError("msg.syntax");
+ return null;
+ }
+
+ /* Make a NEW node to append to. */
+ Node pnXML = nf.createLeaf(Token.NEW);
+
+ String xml = ts.getString();
+ boolean fAnonymous = xml.trim().startsWith("<>");
+
+ Node pn = nf.createName(fAnonymous ? "XMLList" : "XML");
+ nf.addChildToBack(pnXML, pn);
+
+ pn = null;
+ Node expr;
+ for (;;tt = ts.getNextXMLToken()) {
+ switch (tt) {
+ case Token.XML:
+ xml = ts.getString();
+ decompiler.addName(xml);
+ mustMatchToken(Token.LC, "msg.syntax");
+ decompiler.addToken(Token.LC);
+ expr = (peekToken() == Token.RC)
+ ? nf.createString("")
+ : expr(false);
+ mustMatchToken(Token.RC, "msg.syntax");
+ decompiler.addToken(Token.RC);
+ if (pn == null) {
+ pn = nf.createString(xml);
+ } else {
+ pn = nf.createBinary(Token.ADD, pn, nf.createString(xml));
+ }
+ if (ts.isXMLAttribute()) {
+ /* Need to put the result in double quotes */
+ expr = nf.createUnary(Token.ESCXMLATTR, expr);
+ Node prepend = nf.createBinary(Token.ADD,
+ nf.createString("\""),
+ expr);
+ expr = nf.createBinary(Token.ADD,
+ prepend,
+ nf.createString("\""));
+ } else {
+ expr = nf.createUnary(Token.ESCXMLTEXT, expr);
+ }
+ pn = nf.createBinary(Token.ADD, pn, expr);
+ break;
+ case Token.XMLEND:
+ xml = ts.getString();
+ decompiler.addName(xml);
+ if (pn == null) {
+ pn = nf.createString(xml);
+ } else {
+ pn = nf.createBinary(Token.ADD, pn, nf.createString(xml));
+ }
+
+ nf.addChildToBack(pnXML, pn);
+ return pnXML;
+ default:
+ reportError("msg.syntax");
+ return null;
+ }
+ }
+ }
+
+ private void argumentList(Node listNode)
+ throws IOException, ParserException
+ {
+ boolean matched;
+ matched = matchToken(Token.RP);
+ if (!matched) {
+ boolean first = true;
+ do {
+ if (!first)
+ decompiler.addToken(Token.COMMA);
+ first = false;
+ nf.addChildToBack(listNode, assignExpr(false));
+ } while (matchToken(Token.COMMA));
+
+ mustMatchToken(Token.RP, "msg.no.paren.arg");
+ }
+ decompiler.addToken(Token.RP);
+ }
+
+ private Node memberExpr(boolean allowCallSyntax)
+ throws IOException, ParserException
+ {
+ int tt;
+
+ Node pn;
+
+ /* Check for new expressions. */
+ tt = peekToken();
+ if (tt == Token.NEW) {
+ /* Eat the NEW token. */
+ consumeToken();
+ decompiler.addToken(Token.NEW);
+
+ /* Make a NEW node to append to. */
+ pn = nf.createCallOrNew(Token.NEW, memberExpr(false));
+
+ if (matchToken(Token.LP)) {
+ decompiler.addToken(Token.LP);
+ /* Add the arguments to pn, if any are supplied. */
+ argumentList(pn);
+ }
+
+ /* XXX there's a check in the C source against
+ * "too many constructor arguments" - how many
+ * do we claim to support?
+ */
+
+ /* Experimental syntax: allow an object literal to follow a new expression,
+ * which will mean a kind of anonymous class built with the JavaAdapter.
+ * the object literal will be passed as an additional argument to the constructor.
+ */
+ tt = peekToken();
+ if (tt == Token.LC) {
+ nf.addChildToBack(pn, primaryExpr());
+ }
+ } else {
+ pn = primaryExpr();
+ }
+
+ return memberExprTail(allowCallSyntax, pn);
+ }
+
+ private Node memberExprTail(boolean allowCallSyntax, Node pn)
+ throws IOException, ParserException
+ {
+ tailLoop:
+ for (;;) {
+ int tt = peekToken();
+ switch (tt) {
+
+ case Token.DOT:
+ case Token.DOTDOT:
+ {
+ int memberTypeFlags;
+ String s;
+
+ consumeToken();
+ decompiler.addToken(tt);
+ memberTypeFlags = 0;
+ if (tt == Token.DOTDOT) {
+ mustHaveXML();
+ memberTypeFlags = Node.DESCENDANTS_FLAG;
+ }
+ if (!compilerEnv.isXmlAvailable()) {
+ mustMatchToken(Token.NAME, "msg.no.name.after.dot");
+ s = ts.getString();
+ decompiler.addName(s);
+ pn = nf.createPropertyGet(pn, null, s, memberTypeFlags);
+ break;
+ }
+
+ tt = nextToken();
+ switch (tt) {
+ // handles: name, ns::name, ns::*, ns::[expr]
+ case Token.NAME:
+ s = ts.getString();
+ decompiler.addName(s);
+ pn = propertyName(pn, s, memberTypeFlags);
+ break;
+
+ // handles: *, *::name, *::*, *::[expr]
+ case Token.MUL:
+ decompiler.addName("*");
+ pn = propertyName(pn, "*", memberTypeFlags);
+ break;
+
+ // handles: '@attr', '@ns::attr', '@ns::*', '@ns::*',
+ // '@::attr', '@::*', '@*', '@*::attr', '@*::*'
+ case Token.XMLATTR:
+ decompiler.addToken(Token.XMLATTR);
+ pn = attributeAccess(pn, memberTypeFlags);
+ break;
+
+ default:
+ reportError("msg.no.name.after.dot");
+ }
+ }
+ break;
+
+ case Token.DOTQUERY:
+ consumeToken();
+ mustHaveXML();
+ decompiler.addToken(Token.DOTQUERY);
+ pn = nf.createDotQuery(pn, expr(false), ts.getLineno());
+ mustMatchToken(Token.RP, "msg.no.paren");
+ decompiler.addToken(Token.RP);
+ break;
+
+ case Token.LB:
+ consumeToken();
+ decompiler.addToken(Token.LB);
+ pn = nf.createElementGet(pn, null, expr(false), 0);
+ mustMatchToken(Token.RB, "msg.no.bracket.index");
+ decompiler.addToken(Token.RB);
+ break;
+
+ case Token.LP:
+ if (!allowCallSyntax) {
+ break tailLoop;
+ }
+ consumeToken();
+ decompiler.addToken(Token.LP);
+ pn = nf.createCallOrNew(Token.CALL, pn);
+ /* Add the arguments to pn, if any are supplied. */
+ argumentList(pn);
+ break;
+
+ default:
+ break tailLoop;
+ }
+ }
+ return pn;
+ }
+
+ /*
+ * Xml attribute expression:
+ * '@attr', '@ns::attr', '@ns::*', '@ns::*', '@*', '@*::attr', '@*::*'
+ */
+ private Node attributeAccess(Node pn, int memberTypeFlags)
+ throws IOException
+ {
+ memberTypeFlags |= Node.ATTRIBUTE_FLAG;
+ int tt = nextToken();
+
+ switch (tt) {
+ // handles: @name, @ns::name, @ns::*, @ns::[expr]
+ case Token.NAME:
+ {
+ String s = ts.getString();
+ decompiler.addName(s);
+ pn = propertyName(pn, s, memberTypeFlags);
+ }
+ break;
+
+ // handles: @*, @*::name, @*::*, @*::[expr]
+ case Token.MUL:
+ decompiler.addName("*");
+ pn = propertyName(pn, "*", memberTypeFlags);
+ break;
+
+ // handles @[expr]
+ case Token.LB:
+ decompiler.addToken(Token.LB);
+ pn = nf.createElementGet(pn, null, expr(false), memberTypeFlags);
+ mustMatchToken(Token.RB, "msg.no.bracket.index");
+ decompiler.addToken(Token.RB);
+ break;
+
+ default:
+ reportError("msg.no.name.after.xmlAttr");
+ pn = nf.createPropertyGet(pn, null, "?", memberTypeFlags);
+ break;
+ }
+
+ return pn;
+ }
+
+ /**
+ * Check if :: follows name in which case it becomes qualified name
+ */
+ private Node propertyName(Node pn, String name, int memberTypeFlags)
+ throws IOException, ParserException
+ {
+ String namespace = null;
+ if (matchToken(Token.COLONCOLON)) {
+ decompiler.addToken(Token.COLONCOLON);
+ namespace = name;
+
+ int tt = nextToken();
+ switch (tt) {
+ // handles name::name
+ case Token.NAME:
+ name = ts.getString();
+ decompiler.addName(name);
+ break;
+
+ // handles name::*
+ case Token.MUL:
+ decompiler.addName("*");
+ name = "*";
+ break;
+
+ // handles name::[expr]
+ case Token.LB:
+ decompiler.addToken(Token.LB);
+ pn = nf.createElementGet(pn, namespace, expr(false),
+ memberTypeFlags);
+ mustMatchToken(Token.RB, "msg.no.bracket.index");
+ decompiler.addToken(Token.RB);
+ return pn;
+
+ default:
+ reportError("msg.no.name.after.coloncolon");
+ name = "?";
+ }
+ }
+
+ pn = nf.createPropertyGet(pn, namespace, name, memberTypeFlags);
+ return pn;
+ }
+
+ private Node primaryExpr()
+ throws IOException, ParserException
+ {
+ Node pn;
+
+ int ttFlagged = nextFlaggedToken();
+ int tt = ttFlagged & CLEAR_TI_MASK;
+
+ switch(tt) {
+
+ case Token.FUNCTION:
+ return function(FunctionNode.FUNCTION_EXPRESSION);
+
+ case Token.LB: {
+ ObjArray elems = new ObjArray();
+ int skipCount = 0;
+ decompiler.addToken(Token.LB);
+ boolean after_lb_or_comma = true;
+ for (;;) {
+ tt = peekToken();
+
+ if (tt == Token.COMMA) {
+ consumeToken();
+ decompiler.addToken(Token.COMMA);
+ if (!after_lb_or_comma) {
+ after_lb_or_comma = true;
+ } else {
+ elems.add(null);
+ ++skipCount;
+ }
+ } else if (tt == Token.RB) {
+ consumeToken();
+ decompiler.addToken(Token.RB);
+ break;
+ } else {
+ if (!after_lb_or_comma) {
+ reportError("msg.no.bracket.arg");
+ }
+ elems.add(assignExpr(false));
+ after_lb_or_comma = false;
+ }
+ }
+ return nf.createArrayLiteral(elems, skipCount);
+ }
+
+ case Token.LC: {
+ ObjArray elems = new ObjArray();
+ decompiler.addToken(Token.LC);
+ if (!matchToken(Token.RC)) {
+
+ boolean first = true;
+ commaloop:
+ do {
+ Object property;
+
+ if (!first)
+ decompiler.addToken(Token.COMMA);
+ else
+ first = false;
+
+ tt = peekToken();
+ switch(tt) {
+ case Token.NAME:
+ case Token.STRING:
+ consumeToken();
+ // map NAMEs to STRINGs in object literal context
+ // but tell the decompiler the proper type
+ String s = ts.getString();
+ if (tt == Token.NAME) {
+ if (s.equals("get") &&
+ peekToken() == Token.NAME) {
+ decompiler.addToken(Token.GET);
+ consumeToken();
+ s = ts.getString();
+ decompiler.addName(s);
+ property = ScriptRuntime.getIndexObject(s);
+ if (!getterSetterProperty(elems, property,
+ true))
+ break commaloop;
+ break;
+ } else if (s.equals("set") &&
+ peekToken() == Token.NAME) {
+ decompiler.addToken(Token.SET);
+ consumeToken();
+ s = ts.getString();
+ decompiler.addName(s);
+ property = ScriptRuntime.getIndexObject(s);
+ if (!getterSetterProperty(elems, property,
+ false))
+ break commaloop;
+ break;
+ }
+ decompiler.addName(s);
+ } else {
+ decompiler.addString(s);
+ }
+ property = ScriptRuntime.getIndexObject(s);
+ plainProperty(elems, property);
+ break;
+
+ case Token.NUMBER:
+ consumeToken();
+ double n = ts.getNumber();
+ decompiler.addNumber(n);
+ property = ScriptRuntime.getIndexObject(n);
+ plainProperty(elems, property);
+ break;
+
+ case Token.RC:
+ // trailing comma is OK.
+ break commaloop;
+ default:
+ reportError("msg.bad.prop");
+ break commaloop;
+ }
+ } while (matchToken(Token.COMMA));
+
+ mustMatchToken(Token.RC, "msg.no.brace.prop");
+ }
+ decompiler.addToken(Token.RC);
+ return nf.createObjectLiteral(elems);
+ }
+
+ case Token.LP:
+
+ /* Brendan's IR-jsparse.c makes a new node tagged with
+ * TOK_LP here... I'm not sure I understand why. Isn't
+ * the grouping already implicit in the structure of the
+ * parse tree? also TOK_LP is already overloaded (I
+ * think) in the C IR as 'function call.' */
+ decompiler.addToken(Token.LP);
+ pn = expr(false);
+ pn.putProp(Node.PARENTHESIZED_PROP, Boolean.TRUE);
+ decompiler.addToken(Token.RP);
+ mustMatchToken(Token.RP, "msg.no.paren");
+ return pn;
+
+ case Token.XMLATTR:
+ mustHaveXML();
+ decompiler.addToken(Token.XMLATTR);
+ pn = attributeAccess(null, 0);
+ return pn;
+
+ case Token.NAME: {
+ String name = ts.getString();
+ if ((ttFlagged & TI_CHECK_LABEL) != 0) {
+ if (peekToken() == Token.COLON) {
+ // Do not consume colon, it is used as unwind indicator
+ // to return to statementHelper.
+ // XXX Better way?
+ return nf.createLabel(ts.getLineno());
+ }
+ }
+
+ decompiler.addName(name);
+ if (compilerEnv.isXmlAvailable()) {
+ pn = propertyName(null, name, 0);
+ } else {
+ pn = nf.createName(name);
+ }
+ return pn;
+ }
+
+ case Token.NUMBER: {
+ double n = ts.getNumber();
+ decompiler.addNumber(n);
+ return nf.createNumber(n);
+ }
+
+ case Token.STRING: {
+ String s = ts.getString();
+ decompiler.addString(s);
+ return nf.createString(s);
+ }
+
+ case Token.DIV:
+ case Token.ASSIGN_DIV: {
+ // Got / or /= which should be treated as regexp in fact
+ ts.readRegExp(tt);
+ String flags = ts.regExpFlags;
+ ts.regExpFlags = null;
+ String re = ts.getString();
+ decompiler.addRegexp(re, flags);
+ int index = currentScriptOrFn.addRegexp(re, flags);
+ return nf.createRegExp(index);
+ }
+
+ case Token.NULL:
+ case Token.THIS:
+ case Token.FALSE:
+ case Token.TRUE:
+ decompiler.addToken(tt);
+ return nf.createLeaf(tt);
+
+ case Token.RESERVED:
+ reportError("msg.reserved.id");
+ break;
+
+ case Token.ERROR:
+ /* the scanner or one of its subroutines reported the error. */
+ break;
+
+ case Token.EOF:
+ reportError("msg.unexpected.eof");
+ break;
+
+ default:
+ reportError("msg.syntax");
+ break;
+ }
+ return null; // should never reach here
+ }
+
+ private void plainProperty(ObjArray elems, Object property)
+ throws IOException {
+ mustMatchToken(Token.COLON, "msg.no.colon.prop");
+
+ // OBJLIT is used as ':' in object literal for
+ // decompilation to solve spacing ambiguity.
+ decompiler.addToken(Token.OBJECTLIT);
+ elems.add(property);
+ elems.add(assignExpr(false));
+ }
+
+ private boolean getterSetterProperty(ObjArray elems, Object property,
+ boolean isGetter) throws IOException {
+ Node f = function(FunctionNode.FUNCTION_EXPRESSION);
+ if (f.getType() != Token.FUNCTION) {
+ reportError("msg.bad.prop");
+ return false;
+ }
+ int fnIndex = f.getExistingIntProp(Node.FUNCTION_PROP);
+ FunctionNode fn = currentScriptOrFn.getFunctionNode(fnIndex);
+ if (fn.getFunctionName().length() != 0) {
+ reportError("msg.bad.prop");
+ return false;
+ }
+ elems.add(property);
+ if (isGetter) {
+ elems.add(nf.createUnary(Token.GET, f));
+ } else {
+ elems.add(nf.createUnary(Token.SET, f));
+ }
+ return true;
+ }
+}
diff --git a/bin/yuicompressor-2.3.4/src/org/mozilla/javascript/Parser.java.orig b/bin/yuicompressor-2.3.4/src/org/mozilla/javascript/Parser.java.orig
new file mode 100644
index 0000000..628bb42
--- /dev/null
+++ b/bin/yuicompressor-2.3.4/src/org/mozilla/javascript/Parser.java.orig
@@ -0,0 +1,2159 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Mike Ang
+ * Igor Bukanov
+ * Yuh-Ruey Chen
+ * Ethan Hugg
+ * Bob Jervis
+ * Terry Lucas
+ * Mike McCabe
+ * Milen Nankov
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.javascript;
+
+import java.io.Reader;
+import java.io.IOException;
+import java.util.Hashtable;
+
+/**
+ * This class implements the JavaScript parser.
+ *
+ * It is based on the C source files jsparse.c and jsparse.h
+ * in the jsref package.
+ *
+ * @see TokenStream
+ *
+ * @author Mike McCabe
+ * @author Brendan Eich
+ */
+
+public class Parser
+{
+ // TokenInformation flags : currentFlaggedToken stores them together
+ // with token type
+ final static int
+ CLEAR_TI_MASK = 0xFFFF, // mask to clear token information bits
+ TI_AFTER_EOL = 1 << 16, // first token of the source line
+ TI_CHECK_LABEL = 1 << 17; // indicates to check for label
+
+ CompilerEnvirons compilerEnv;
+ private ErrorReporter errorReporter;
+ private String sourceURI;
+ boolean calledByCompileFunction;
+
+ private TokenStream ts;
+ private int currentFlaggedToken;
+ private int syntaxErrorCount;
+
+ private IRFactory nf;
+
+ private int nestingOfFunction;
+
+ private Decompiler decompiler;
+ private String encodedSource;
+
+// The following are per function variables and should be saved/restored
+// during function parsing.
+// XXX Move to separated class?
+ ScriptOrFnNode currentScriptOrFn;
+ private int nestingOfWith;
+ private Hashtable labelSet; // map of label names into nodes
+ private ObjArray loopSet;
+ private ObjArray loopAndSwitchSet;
+ private boolean hasReturnValue;
+ private int functionEndFlags;
+// end of per function variables
+
+ // Exception to unwind
+ private static class ParserException extends RuntimeException
+ {
+ static final long serialVersionUID = 5882582646773765630L;
+ }
+
+ public Parser(CompilerEnvirons compilerEnv, ErrorReporter errorReporter)
+ {
+ this.compilerEnv = compilerEnv;
+ this.errorReporter = errorReporter;
+ }
+
+ protected Decompiler createDecompiler(CompilerEnvirons compilerEnv)
+ {
+ return new Decompiler();
+ }
+
+ void addStrictWarning(String messageId, String messageArg)
+ {
+ if (compilerEnv.isStrictMode())
+ addWarning(messageId, messageArg);
+ }
+
+ void addWarning(String messageId, String messageArg)
+ {
+ String message = ScriptRuntime.getMessage1(messageId, messageArg);
+ if (compilerEnv.reportWarningAsError()) {
+ ++syntaxErrorCount;
+ errorReporter.error(message, sourceURI, ts.getLineno(),
+ ts.getLine(), ts.getOffset());
+ } else
+ errorReporter.warning(message, sourceURI, ts.getLineno(),
+ ts.getLine(), ts.getOffset());
+ }
+
+ void addError(String messageId)
+ {
+ ++syntaxErrorCount;
+ String message = ScriptRuntime.getMessage0(messageId);
+ errorReporter.error(message, sourceURI, ts.getLineno(),
+ ts.getLine(), ts.getOffset());
+ }
+
+ void addError(String messageId, String messageArg)
+ {
+ ++syntaxErrorCount;
+ String message = ScriptRuntime.getMessage1(messageId, messageArg);
+ errorReporter.error(message, sourceURI, ts.getLineno(),
+ ts.getLine(), ts.getOffset());
+ }
+
+ RuntimeException reportError(String messageId)
+ {
+ addError(messageId);
+
+ // Throw a ParserException exception to unwind the recursive descent
+ // parse.
+ throw new ParserException();
+ }
+
+ private int peekToken()
+ throws IOException
+ {
+ int tt = currentFlaggedToken;
+ if (tt == Token.EOF) {
+ tt = ts.getToken();
+ if (tt == Token.EOL) {
+ do {
+ tt = ts.getToken();
+ } while (tt == Token.EOL);
+ tt |= TI_AFTER_EOL;
+ }
+ currentFlaggedToken = tt;
+ }
+ return tt & CLEAR_TI_MASK;
+ }
+
+ private int peekFlaggedToken()
+ throws IOException
+ {
+ peekToken();
+ return currentFlaggedToken;
+ }
+
+ private void consumeToken()
+ {
+ currentFlaggedToken = Token.EOF;
+ }
+
+ private int nextToken()
+ throws IOException
+ {
+ int tt = peekToken();
+ consumeToken();
+ return tt;
+ }
+
+ private int nextFlaggedToken()
+ throws IOException
+ {
+ peekToken();
+ int ttFlagged = currentFlaggedToken;
+ consumeToken();
+ return ttFlagged;
+ }
+
+ private boolean matchToken(int toMatch)
+ throws IOException
+ {
+ int tt = peekToken();
+ if (tt != toMatch) {
+ return false;
+ }
+ consumeToken();
+ return true;
+ }
+
+ private int peekTokenOrEOL()
+ throws IOException
+ {
+ int tt = peekToken();
+ // Check for last peeked token flags
+ if ((currentFlaggedToken & TI_AFTER_EOL) != 0) {
+ tt = Token.EOL;
+ }
+ return tt;
+ }
+
+ private void setCheckForLabel()
+ {
+ if ((currentFlaggedToken & CLEAR_TI_MASK) != Token.NAME)
+ throw Kit.codeBug();
+ currentFlaggedToken |= TI_CHECK_LABEL;
+ }
+
+ private void mustMatchToken(int toMatch, String messageId)
+ throws IOException, ParserException
+ {
+ if (!matchToken(toMatch)) {
+ reportError(messageId);
+ }
+ }
+
+ private void mustHaveXML()
+ {
+ if (!compilerEnv.isXmlAvailable()) {
+ reportError("msg.XML.not.available");
+ }
+ }
+
+ public String getEncodedSource()
+ {
+ return encodedSource;
+ }
+
+ public boolean eof()
+ {
+ return ts.eof();
+ }
+
+ boolean insideFunction()
+ {
+ return nestingOfFunction != 0;
+ }
+
+ private Node enterLoop(Node loopLabel)
+ {
+ Node loop = nf.createLoopNode(loopLabel, ts.getLineno());
+ if (loopSet == null) {
+ loopSet = new ObjArray();
+ if (loopAndSwitchSet == null) {
+ loopAndSwitchSet = new ObjArray();
+ }
+ }
+ loopSet.push(loop);
+ loopAndSwitchSet.push(loop);
+ return loop;
+ }
+
+ private void exitLoop()
+ {
+ loopSet.pop();
+ loopAndSwitchSet.pop();
+ }
+
+ private Node enterSwitch(Node switchSelector, int lineno)
+ {
+ Node switchNode = nf.createSwitch(switchSelector, lineno);
+ if (loopAndSwitchSet == null) {
+ loopAndSwitchSet = new ObjArray();
+ }
+ loopAndSwitchSet.push(switchNode);
+ return switchNode;
+ }
+
+ private void exitSwitch()
+ {
+ loopAndSwitchSet.pop();
+ }
+
+ /*
+ * Build a parse tree from the given sourceString.
+ *
+ * @return an Object representing the parsed
+ * program. If the parse fails, null will be returned. (The
+ * parse failure will result in a call to the ErrorReporter from
+ * CompilerEnvirons.)
+ */
+ public ScriptOrFnNode parse(String sourceString,
+ String sourceURI, int lineno)
+ {
+ this.sourceURI = sourceURI;
+ this.ts = new TokenStream(this, null, sourceString, lineno);
+ try {
+ return parse();
+ } catch (IOException ex) {
+ // Should never happen
+ throw new IllegalStateException();
+ }
+ }
+
+ /*
+ * Build a parse tree from the given sourceString.
+ *
+ * @return an Object representing the parsed
+ * program. If the parse fails, null will be returned. (The
+ * parse failure will result in a call to the ErrorReporter from
+ * CompilerEnvirons.)
+ */
+ public ScriptOrFnNode parse(Reader sourceReader,
+ String sourceURI, int lineno)
+ throws IOException
+ {
+ this.sourceURI = sourceURI;
+ this.ts = new TokenStream(this, sourceReader, null, lineno);
+ return parse();
+ }
+
+ private ScriptOrFnNode parse()
+ throws IOException
+ {
+ this.decompiler = createDecompiler(compilerEnv);
+ this.nf = new IRFactory(this);
+ currentScriptOrFn = nf.createScript();
+ int sourceStartOffset = decompiler.getCurrentOffset();
+ this.encodedSource = null;
+ decompiler.addToken(Token.SCRIPT);
+
+ this.currentFlaggedToken = Token.EOF;
+ this.syntaxErrorCount = 0;
+
+ int baseLineno = ts.getLineno(); // line number where source starts
+
+ /* so we have something to add nodes to until
+ * we've collected all the source */
+ Node pn = nf.createLeaf(Token.BLOCK);
+
+ try {
+ for (;;) {
+ int tt = peekToken();
+
+ if (tt <= Token.EOF) {
+ break;
+ }
+
+ Node n;
+ if (tt == Token.FUNCTION) {
+ consumeToken();
+ try {
+ n = function(calledByCompileFunction
+ ? FunctionNode.FUNCTION_EXPRESSION
+ : FunctionNode.FUNCTION_STATEMENT);
+ } catch (ParserException e) {
+ break;
+ }
+ } else {
+ n = statement();
+ }
+ nf.addChildToBack(pn, n);
+ }
+ } catch (StackOverflowError ex) {
+ String msg = ScriptRuntime.getMessage0(
+ "msg.too.deep.parser.recursion");
+ throw Context.reportRuntimeError(msg, sourceURI,
+ ts.getLineno(), null, 0);
+ }
+
+ if (this.syntaxErrorCount != 0) {
+ String msg = String.valueOf(this.syntaxErrorCount);
+ msg = ScriptRuntime.getMessage1("msg.got.syntax.errors", msg);
+ throw errorReporter.runtimeError(msg, sourceURI, baseLineno,
+ null, 0);
+ }
+
+ currentScriptOrFn.setSourceName(sourceURI);
+ currentScriptOrFn.setBaseLineno(baseLineno);
+ currentScriptOrFn.setEndLineno(ts.getLineno());
+
+ int sourceEndOffset = decompiler.getCurrentOffset();
+ currentScriptOrFn.setEncodedSourceBounds(sourceStartOffset,
+ sourceEndOffset);
+
+ nf.initScript(currentScriptOrFn, pn);
+
+ if (compilerEnv.isGeneratingSource()) {
+ encodedSource = decompiler.getEncodedSource();
+ }
+ this.decompiler = null; // It helps GC
+
+ return currentScriptOrFn;
+ }
+
+ /*
+ * The C version of this function takes an argument list,
+ * which doesn't seem to be needed for tree generation...
+ * it'd only be useful for checking argument hiding, which
+ * I'm not doing anyway...
+ */
+ private Node parseFunctionBody()
+ throws IOException
+ {
+ ++nestingOfFunction;
+ Node pn = nf.createBlock(ts.getLineno());
+ try {
+ bodyLoop: for (;;) {
+ Node n;
+ int tt = peekToken();
+ switch (tt) {
+ case Token.ERROR:
+ case Token.EOF:
+ case Token.RC:
+ break bodyLoop;
+
+ case Token.FUNCTION:
+ consumeToken();
+ n = function(FunctionNode.FUNCTION_STATEMENT);
+ break;
+ default:
+ n = statement();
+ break;
+ }
+ nf.addChildToBack(pn, n);
+ }
+ } catch (ParserException e) {
+ // Ignore it
+ } finally {
+ --nestingOfFunction;
+ }
+
+ return pn;
+ }
+
+ private Node function(int functionType)
+ throws IOException, ParserException
+ {
+ int syntheticType = functionType;
+ int baseLineno = ts.getLineno(); // line number where source starts
+
+ int functionSourceStart = decompiler.markFunctionStart(functionType);
+ String name;
+ Node memberExprNode = null;
+ if (matchToken(Token.NAME)) {
+ name = ts.getString();
+ decompiler.addName(name);
+ if (!matchToken(Token.LP)) {
+ if (compilerEnv.isAllowMemberExprAsFunctionName()) {
+ // Extension to ECMA: if 'function <name>' does not follow
+ // by '(', assume <name> starts memberExpr
+ Node memberExprHead = nf.createName(name);
+ name = "";
+ memberExprNode = memberExprTail(false, memberExprHead);
+ }
+ mustMatchToken(Token.LP, "msg.no.paren.parms");
+ }
+ } else if (matchToken(Token.LP)) {
+ // Anonymous function
+ name = "";
+ } else {
+ name = "";
+ if (compilerEnv.isAllowMemberExprAsFunctionName()) {
+ // Note that memberExpr can not start with '(' like
+ // in function (1+2).toString(), because 'function (' already
+ // processed as anonymous function
+ memberExprNode = memberExpr(false);
+ }
+ mustMatchToken(Token.LP, "msg.no.paren.parms");
+ }
+
+ if (memberExprNode != null) {
+ syntheticType = FunctionNode.FUNCTION_EXPRESSION;
+ }
+
+ boolean nested = insideFunction();
+
+ FunctionNode fnNode = nf.createFunction(name);
+ if (nested || nestingOfWith > 0) {
+ // 1. Nested functions are not affected by the dynamic scope flag
+ // as dynamic scope is already a parent of their scope.
+ // 2. Functions defined under the with statement also immune to
+ // this setup, in which case dynamic scope is ignored in favor
+ // of with object.
+ fnNode.itsIgnoreDynamicScope = true;
+ }
+
+ int functionIndex = currentScriptOrFn.addFunction(fnNode);
+
+ int functionSourceEnd;
+
+ ScriptOrFnNode savedScriptOrFn = currentScriptOrFn;
+ currentScriptOrFn = fnNode;
+ int savedNestingOfWith = nestingOfWith;
+ nestingOfWith = 0;
+ Hashtable savedLabelSet = labelSet;
+ labelSet = null;
+ ObjArray savedLoopSet = loopSet;
+ loopSet = null;
+ ObjArray savedLoopAndSwitchSet = loopAndSwitchSet;
+ loopAndSwitchSet = null;
+ boolean savedHasReturnValue = hasReturnValue;
+ int savedFunctionEndFlags = functionEndFlags;
+
+ Node body;
+ try {
+ decompiler.addToken(Token.LP);
+ if (!matchToken(Token.RP)) {
+ boolean first = true;
+ do {
+ if (!first)
+ decompiler.addToken(Token.COMMA);
+ first = false;
+ mustMatchToken(Token.NAME, "msg.no.parm");
+ String s = ts.getString();
+ if (fnNode.hasParamOrVar(s)) {
+ addWarning("msg.dup.parms", s);
+ }
+ fnNode.addParam(s);
+ decompiler.addName(s);
+ } while (matchToken(Token.COMMA));
+
+ mustMatchToken(Token.RP, "msg.no.paren.after.parms");
+ }
+ decompiler.addToken(Token.RP);
+
+ mustMatchToken(Token.LC, "msg.no.brace.body");
+ decompiler.addEOL(Token.LC);
+ body = parseFunctionBody();
+ mustMatchToken(Token.RC, "msg.no.brace.after.body");
+
+ if (compilerEnv.isStrictMode() && !body.hasConsistentReturnUsage())
+ {
+ String msg = name.length() > 0 ? "msg.no.return.value"
+ : "msg.anon.no.return.value";
+ addStrictWarning(msg, name);
+ }
+
+ decompiler.addToken(Token.RC);
+ functionSourceEnd = decompiler.markFunctionEnd(functionSourceStart);
+ if (functionType != FunctionNode.FUNCTION_EXPRESSION) {
+ // Add EOL only if function is not part of expression
+ // since it gets SEMI + EOL from Statement in that case
+ decompiler.addToken(Token.EOL);
+ }
+ }
+ finally {
+ hasReturnValue = savedHasReturnValue;
+ functionEndFlags = savedFunctionEndFlags;
+ loopAndSwitchSet = savedLoopAndSwitchSet;
+ loopSet = savedLoopSet;
+ labelSet = savedLabelSet;
+ nestingOfWith = savedNestingOfWith;
+ currentScriptOrFn = savedScriptOrFn;
+ }
+
+ fnNode.setEncodedSourceBounds(functionSourceStart, functionSourceEnd);
+ fnNode.setSourceName(sourceURI);
+ fnNode.setBaseLineno(baseLineno);
+ fnNode.setEndLineno(ts.getLineno());
+
+ if (name != null) {
+ int index = currentScriptOrFn.getParamOrVarIndex(name);
+ if (index >= 0 && index < currentScriptOrFn.getParamCount())
+ addStrictWarning("msg.var.hides.arg", name);
+ }
+
+ Node pn = nf.initFunction(fnNode, functionIndex, body, syntheticType);
+ if (memberExprNode != null) {
+ pn = nf.createAssignment(Token.ASSIGN, memberExprNode, pn);
+ if (functionType != FunctionNode.FUNCTION_EXPRESSION) {
+ // XXX check JScript behavior: should it be createExprStatement?
+ pn = nf.createExprStatementNoReturn(pn, baseLineno);
+ }
+ }
+ return pn;
+ }
+
+ private Node statements()
+ throws IOException
+ {
+ Node pn = nf.createBlock(ts.getLineno());
+
+ int tt;
+ while((tt = peekToken()) > Token.EOF && tt != Token.RC) {
+ nf.addChildToBack(pn, statement());
+ }
+
+ return pn;
+ }
+
+ private Node condition()
+ throws IOException, ParserException
+ {
+ mustMatchToken(Token.LP, "msg.no.paren.cond");
+ decompiler.addToken(Token.LP);
+ Node pn = expr(false);
+ mustMatchToken(Token.RP, "msg.no.paren.after.cond");
+ decompiler.addToken(Token.RP);
+
+ // Report strict warning on code like "if (a = 7) ...". Suppress the
+ // warning if the condition is parenthesized, like "if ((a = 7)) ...".
+ if (pn.getProp(Node.PARENTHESIZED_PROP) == null &&
+ (pn.getType() == Token.SETNAME || pn.getType() == Token.SETPROP ||
+ pn.getType() == Token.SETELEM))
+ {
+ addStrictWarning("msg.equal.as.assign", "");
+ }
+ return pn;
+ }
+
+ // match a NAME; return null if no match.
+ private Node matchJumpLabelName()
+ throws IOException, ParserException
+ {
+ Node label = null;
+
+ int tt = peekTokenOrEOL();
+ if (tt == Token.NAME) {
+ consumeToken();
+ String name = ts.getString();
+ decompiler.addName(name);
+ if (labelSet != null) {
+ label = (Node)labelSet.get(name);
+ }
+ if (label == null) {
+ reportError("msg.undef.label");
+ }
+ }
+
+ return label;
+ }
+
+ private Node statement()
+ throws IOException
+ {
+ try {
+ Node pn = statementHelper(null);
+ if (pn != null) {
+ if (compilerEnv.isStrictMode() && !pn.hasSideEffects())
+ addStrictWarning("msg.no.side.effects", "");
+ return pn;
+ }
+ } catch (ParserException e) { }
+
+ // skip to end of statement
+ int lineno = ts.getLineno();
+ guessingStatementEnd: for (;;) {
+ int tt = peekTokenOrEOL();
+ consumeToken();
+ switch (tt) {
+ case Token.ERROR:
+ case Token.EOF:
+ case Token.EOL:
+ case Token.SEMI:
+ break guessingStatementEnd;
+ }
+ }
+ return nf.createExprStatement(nf.createName("error"), lineno);
+ }
+
+ /**
+ * Whether the "catch (e: e instanceof Exception) { ... }" syntax
+ * is implemented.
+ */
+
+ private Node statementHelper(Node statementLabel)
+ throws IOException, ParserException
+ {
+ Node pn = null;
+
+ int tt;
+
+ tt = peekToken();
+
+ switch(tt) {
+ case Token.IF: {
+ consumeToken();
+
+ decompiler.addToken(Token.IF);
+ int lineno = ts.getLineno();
+ Node cond = condition();
+ decompiler.addEOL(Token.LC);
+ Node ifTrue = statement();
+ Node ifFalse = null;
+ if (matchToken(Token.ELSE)) {
+ decompiler.addToken(Token.RC);
+ decompiler.addToken(Token.ELSE);
+ decompiler.addEOL(Token.LC);
+ ifFalse = statement();
+ }
+ decompiler.addEOL(Token.RC);
+ pn = nf.createIf(cond, ifTrue, ifFalse, lineno);
+ return pn;
+ }
+
+ case Token.SWITCH: {
+ consumeToken();
+
+ decompiler.addToken(Token.SWITCH);
+ int lineno = ts.getLineno();
+ mustMatchToken(Token.LP, "msg.no.paren.switch");
+ decompiler.addToken(Token.LP);
+ pn = enterSwitch(expr(false), lineno);
+ try {
+ mustMatchToken(Token.RP, "msg.no.paren.after.switch");
+ decompiler.addToken(Token.RP);
+ mustMatchToken(Token.LC, "msg.no.brace.switch");
+ decompiler.addEOL(Token.LC);
+
+ boolean hasDefault = false;
+ switchLoop: for (;;) {
+ tt = nextToken();
+ Node caseExpression;
+ switch (tt) {
+ case Token.RC:
+ break switchLoop;
+
+ case Token.CASE:
+ decompiler.addToken(Token.CASE);
+ caseExpression = expr(false);
+ mustMatchToken(Token.COLON, "msg.no.colon.case");
+ decompiler.addEOL(Token.COLON);
+ break;
+
+ case Token.DEFAULT:
+ if (hasDefault) {
+ reportError("msg.double.switch.default");
+ }
+ decompiler.addToken(Token.DEFAULT);
+ hasDefault = true;
+ caseExpression = null;
+ mustMatchToken(Token.COLON, "msg.no.colon.case");
+ decompiler.addEOL(Token.COLON);
+ break;
+
+ default:
+ reportError("msg.bad.switch");
+ break switchLoop;
+ }
+
+ Node block = nf.createLeaf(Token.BLOCK);
+ while ((tt = peekToken()) != Token.RC
+ && tt != Token.CASE
+ && tt != Token.DEFAULT
+ && tt != Token.EOF)
+ {
+ nf.addChildToBack(block, statement());
+ }
+
+ // caseExpression == null => add default lable
+ nf.addSwitchCase(pn, caseExpression, block);
+ }
+ decompiler.addEOL(Token.RC);
+ nf.closeSwitch(pn);
+ } finally {
+ exitSwitch();
+ }
+ return pn;
+ }
+
+ case Token.WHILE: {
+ consumeToken();
+ decompiler.addToken(Token.WHILE);
+
+ Node loop = enterLoop(statementLabel);
+ try {
+ Node cond = condition();
+ decompiler.addEOL(Token.LC);
+ Node body = statement();
+ decompiler.addEOL(Token.RC);
+ pn = nf.createWhile(loop, cond, body);
+ } finally {
+ exitLoop();
+ }
+ return pn;
+ }
+
+ case Token.DO: {
+ consumeToken();
+ decompiler.addToken(Token.DO);
+ decompiler.addEOL(Token.LC);
+
+ Node loop = enterLoop(statementLabel);
+ try {
+ Node body = statement();
+ decompiler.addToken(Token.RC);
+ mustMatchToken(Token.WHILE, "msg.no.while.do");
+ decompiler.addToken(Token.WHILE);
+ Node cond = condition();
+ pn = nf.createDoWhile(loop, body, cond);
+ } finally {
+ exitLoop();
+ }
+ // Always auto-insert semicon to follow SpiderMonkey:
+ // It is required by EMAScript but is ignored by the rest of
+ // world, see bug 238945
+ matchToken(Token.SEMI);
+ decompiler.addEOL(Token.SEMI);
+ return pn;
+ }
+
+ case Token.FOR: {
+ consumeToken();
+ boolean isForEach = false;
+ decompiler.addToken(Token.FOR);
+
+ Node loop = enterLoop(statementLabel);
+ try {
+
+ Node init; // Node init is also foo in 'foo in Object'
+ Node cond; // Node cond is also object in 'foo in Object'
+ Node incr = null; // to kill warning
+ Node body;
+
+ // See if this is a for each () instead of just a for ()
+ if (matchToken(Token.NAME)) {
+ decompiler.addName(ts.getString());
+ if (ts.getString().equals("each")) {
+ isForEach = true;
+ } else {
+ reportError("msg.no.paren.for");
+ }
+ }
+
+ mustMatchToken(Token.LP, "msg.no.paren.for");
+ decompiler.addToken(Token.LP);
+ tt = peekToken();
+ if (tt == Token.SEMI) {
+ init = nf.createLeaf(Token.EMPTY);
+ } else {
+ if (tt == Token.VAR) {
+ // set init to a var list or initial
+ consumeToken(); // consume the 'var' token
+ init = variables(Token.FOR);
+ }
+ else {
+ init = expr(true);
+ }
+ }
+
+ if (matchToken(Token.IN)) {
+ decompiler.addToken(Token.IN);
+ // 'cond' is the object over which we're iterating
+ cond = expr(false);
+ } else { // ordinary for loop
+ mustMatchToken(Token.SEMI, "msg.no.semi.for");
+ decompiler.addToken(Token.SEMI);
+ if (peekToken() == Token.SEMI) {
+ // no loop condition
+ cond = nf.createLeaf(Token.EMPTY);
+ } else {
+ cond = expr(false);
+ }
+
+ mustMatchToken(Token.SEMI, "msg.no.semi.for.cond");
+ decompiler.addToken(Token.SEMI);
+ if (peekToken() == Token.RP) {
+ incr = nf.createLeaf(Token.EMPTY);
+ } else {
+ incr = expr(false);
+ }
+ }
+
+ mustMatchToken(Token.RP, "msg.no.paren.for.ctrl");
+ decompiler.addToken(Token.RP);
+ decompiler.addEOL(Token.LC);
+ body = statement();
+ decompiler.addEOL(Token.RC);
+
+ if (incr == null) {
+ // cond could be null if 'in obj' got eaten
+ // by the init node.
+ pn = nf.createForIn(loop, init, cond, body, isForEach);
+ } else {
+ pn = nf.createFor(loop, init, cond, incr, body);
+ }
+ } finally {
+ exitLoop();
+ }
+ return pn;
+ }
+
+ case Token.TRY: {
+ consumeToken();
+ int lineno = ts.getLineno();
+
+ Node tryblock;
+ Node catchblocks = null;
+ Node finallyblock = null;
+
+ decompiler.addToken(Token.TRY);
+ decompiler.addEOL(Token.LC);
+ tryblock = statement();
+ decompiler.addEOL(Token.RC);
+
+ catchblocks = nf.createLeaf(Token.BLOCK);
+
+ boolean sawDefaultCatch = false;
+ int peek = peekToken();
+ if (peek == Token.CATCH) {
+ while (matchToken(Token.CATCH)) {
+ if (sawDefaultCatch) {
+ reportError("msg.catch.unreachable");
+ }
+ decompiler.addToken(Token.CATCH);
+ mustMatchToken(Token.LP, "msg.no.paren.catch");
+ decompiler.addToken(Token.LP);
+
+ mustMatchToken(Token.NAME, "msg.bad.catchcond");
+ String varName = ts.getString();
+ decompiler.addName(varName);
+
+ Node catchCond = null;
+ if (matchToken(Token.IF)) {
+ decompiler.addToken(Token.IF);
+ catchCond = expr(false);
+ } else {
+ sawDefaultCatch = true;
+ }
+
+ mustMatchToken(Token.RP, "msg.bad.catchcond");
+ decompiler.addToken(Token.RP);
+ mustMatchToken(Token.LC, "msg.no.brace.catchblock");
+ decompiler.addEOL(Token.LC);
+
+ nf.addChildToBack(catchblocks,
+ nf.createCatch(varName, catchCond,
+ statements(),
+ ts.getLineno()));
+
+ mustMatchToken(Token.RC, "msg.no.brace.after.body");
+ decompiler.addEOL(Token.RC);
+ }
+ } else if (peek != Token.FINALLY) {
+ mustMatchToken(Token.FINALLY, "msg.try.no.catchfinally");
+ }
+
+ if (matchToken(Token.FINALLY)) {
+ decompiler.addToken(Token.FINALLY);
+ decompiler.addEOL(Token.LC);
+ finallyblock = statement();
+ decompiler.addEOL(Token.RC);
+ }
+
+ pn = nf.createTryCatchFinally(tryblock, catchblocks,
+ finallyblock, lineno);
+
+ return pn;
+ }
+
+ case Token.THROW: {
+ consumeToken();
+ if (peekTokenOrEOL() == Token.EOL) {
+ // ECMAScript does not allow new lines before throw expression,
+ // see bug 256617
+ reportError("msg.bad.throw.eol");
+ }
+
+ int lineno = ts.getLineno();
+ decompiler.addToken(Token.THROW);
+ pn = nf.createThrow(expr(false), lineno);
+ break;
+ }
+
+ case Token.BREAK: {
+ consumeToken();
+ int lineno = ts.getLineno();
+
+ decompiler.addToken(Token.BREAK);
+
+ // matchJumpLabelName only matches if there is one
+ Node breakStatement = matchJumpLabelName();
+ if (breakStatement == null) {
+ if (loopAndSwitchSet == null || loopAndSwitchSet.size() == 0) {
+ reportError("msg.bad.break");
+ return null;
+ }
+ breakStatement = (Node)loopAndSwitchSet.peek();
+ }
+ pn = nf.createBreak(breakStatement, lineno);
+ break;
+ }
+
+ case Token.CONTINUE: {
+ consumeToken();
+ int lineno = ts.getLineno();
+
+ decompiler.addToken(Token.CONTINUE);
+
+ Node loop;
+ // matchJumpLabelName only matches if there is one
+ Node label = matchJumpLabelName();
+ if (label == null) {
+ if (loopSet == null || loopSet.size() == 0) {
+ reportError("msg.continue.outside");
+ return null;
+ }
+ loop = (Node)loopSet.peek();
+ } else {
+ loop = nf.getLabelLoop(label);
+ if (loop == null) {
+ reportError("msg.continue.nonloop");
+ return null;
+ }
+ }
+ pn = nf.createContinue(loop, lineno);
+ break;
+ }
+
+ case Token.WITH: {
+ consumeToken();
+
+ decompiler.addToken(Token.WITH);
+ int lineno = ts.getLineno();
+ mustMatchToken(Token.LP, "msg.no.paren.with");
+ decompiler.addToken(Token.LP);
+ Node obj = expr(false);
+ mustMatchToken(Token.RP, "msg.no.paren.after.with");
+ decompiler.addToken(Token.RP);
+ decompiler.addEOL(Token.LC);
+
+ ++nestingOfWith;
+ Node body;
+ try {
+ body = statement();
+ } finally {
+ --nestingOfWith;
+ }
+
+ decompiler.addEOL(Token.RC);
+
+ pn = nf.createWith(obj, body, lineno);
+ return pn;
+ }
+
+ case Token.CONST:
+ case Token.VAR: {
+ consumeToken();
+ pn = variables(tt);
+ break;
+ }
+
+ case Token.RETURN: {
+ if (!insideFunction()) {
+ reportError("msg.bad.return");
+ }
+ consumeToken();
+ decompiler.addToken(Token.RETURN);
+ int lineno = ts.getLineno();
+
+ Node retExpr;
+ /* This is ugly, but we don't want to require a semicolon. */
+ tt = peekTokenOrEOL();
+ switch (tt) {
+ case Token.SEMI:
+ case Token.RC:
+ case Token.EOF:
+ case Token.EOL:
+ case Token.ERROR:
+ retExpr = null;
+ break;
+ default:
+ retExpr = expr(false);
+ hasReturnValue = true;
+ }
+ pn = nf.createReturn(retExpr, lineno);
+
+ // see if we need a strict mode warning
+ if (retExpr == null) {
+ if (functionEndFlags == Node.END_RETURNS_VALUE)
+ addStrictWarning("msg.return.inconsistent", "");
+
+ functionEndFlags |= Node.END_RETURNS;
+ } else {
+ if (functionEndFlags == Node.END_RETURNS)
+ addStrictWarning("msg.return.inconsistent", "");
+
+ functionEndFlags |= Node.END_RETURNS_VALUE;
+ }
+
+ break;
+ }
+
+ case Token.LC:
+ consumeToken();
+ if (statementLabel != null) {
+ decompiler.addToken(Token.LC);
+ }
+ pn = statements();
+ mustMatchToken(Token.RC, "msg.no.brace.block");
+ if (statementLabel != null) {
+ decompiler.addEOL(Token.RC);
+ }
+ return pn;
+
+ case Token.ERROR:
+ // Fall thru, to have a node for error recovery to work on
+ case Token.SEMI:
+ consumeToken();
+ pn = nf.createLeaf(Token.EMPTY);
+ return pn;
+
+ case Token.FUNCTION: {
+ consumeToken();
+ pn = function(FunctionNode.FUNCTION_EXPRESSION_STATEMENT);
+ return pn;
+ }
+
+ case Token.DEFAULT :
+ consumeToken();
+ mustHaveXML();
+
+ decompiler.addToken(Token.DEFAULT);
+ int nsLine = ts.getLineno();
+
+ if (!(matchToken(Token.NAME)
+ && ts.getString().equals("xml")))
+ {
+ reportError("msg.bad.namespace");
+ }
+ decompiler.addName(" xml");
+
+ if (!(matchToken(Token.NAME)
+ && ts.getString().equals("namespace")))
+ {
+ reportError("msg.bad.namespace");
+ }
+ decompiler.addName(" namespace");
+
+ if (!matchToken(Token.ASSIGN)) {
+ reportError("msg.bad.namespace");
+ }
+ decompiler.addToken(Token.ASSIGN);
+
+ Node expr = expr(false);
+ pn = nf.createDefaultNamespace(expr, nsLine);
+ break;
+
+ case Token.NAME: {
+ int lineno = ts.getLineno();
+ String name = ts.getString();
+ setCheckForLabel();
+ pn = expr(false);
+ if (pn.getType() != Token.LABEL) {
+ pn = nf.createExprStatement(pn, lineno);
+ } else {
+ // Parsed the label: push back token should be
+ // colon that primaryExpr left untouched.
+ if (peekToken() != Token.COLON) Kit.codeBug();
+ consumeToken();
+ // depend on decompiling lookahead to guess that that
+ // last name was a label.
+ decompiler.addName(name);
+ decompiler.addEOL(Token.COLON);
+
+ if (labelSet == null) {
+ labelSet = new Hashtable();
+ } else if (labelSet.containsKey(name)) {
+ reportError("msg.dup.label");
+ }
+
+ boolean firstLabel;
+ if (statementLabel == null) {
+ firstLabel = true;
+ statementLabel = pn;
+ } else {
+ // Discard multiple label nodes and use only
+ // the first: it allows to simplify IRFactory
+ firstLabel = false;
+ }
+ labelSet.put(name, statementLabel);
+ try {
+ pn = statementHelper(statementLabel);
+ } finally {
+ labelSet.remove(name);
+ }
+ if (firstLabel) {
+ pn = nf.createLabeledStatement(statementLabel, pn);
+ }
+ return pn;
+ }
+ break;
+ }
+
+ default: {
+ int lineno = ts.getLineno();
+ pn = expr(false);
+ pn = nf.createExprStatement(pn, lineno);
+ break;
+ }
+ }
+
+ int ttFlagged = peekFlaggedToken();
+ switch (ttFlagged & CLEAR_TI_MASK) {
+ case Token.SEMI:
+ // Consume ';' as a part of expression
+ consumeToken();
+ break;
+ case Token.ERROR:
+ case Token.EOF:
+ case Token.RC:
+ // Autoinsert ;
+ break;
+ default:
+ if ((ttFlagged & TI_AFTER_EOL) == 0) {
+ // Report error if no EOL or autoinsert ; otherwise
+ reportError("msg.no.semi.stmt");
+ }
+ break;
+ }
+ decompiler.addEOL(Token.SEMI);
+
+ return pn;
+ }
+
+ /**
+ * Parse a 'var' or 'const' statement, or a 'var' init list in a for
+ * statement.
+ * @param context A token value: either VAR, CONST or FOR depending on
+ * context.
+ * @return The parsed statement
+ * @throws IOException
+ * @throws ParserException
+ */
+ private Node variables(int context)
+ throws IOException, ParserException
+ {
+ Node pn;
+ boolean first = true;
+
+ if (context == Token.CONST){
+ pn = nf.createVariables(Token.CONST, ts.getLineno());
+ decompiler.addToken(Token.CONST);
+ } else {
+ pn = nf.createVariables(Token.VAR, ts.getLineno());
+ decompiler.addToken(Token.VAR);
+ }
+
+ for (;;) {
+ Node name;
+ Node init;
+ mustMatchToken(Token.NAME, "msg.bad.var");
+ String s = ts.getString();
+
+ if (!first)
+ decompiler.addToken(Token.COMMA);
+ first = false;
+
+ decompiler.addName(s);
+
+ if (context == Token.CONST) {
+ if (!currentScriptOrFn.addConst(s)) {
+ // We know it's already defined, since addConst passes if
+ // it's not defined at all. The addVar call just confirms
+ // what it is.
+ if (currentScriptOrFn.addVar(s) != ScriptOrFnNode.DUPLICATE_CONST)
+ addError("msg.var.redecl", s);
+ else
+ addError("msg.const.redecl", s);
+ }
+ } else {
+ int dupState = currentScriptOrFn.addVar(s);
+ if (dupState == ScriptOrFnNode.DUPLICATE_CONST)
+ addError("msg.const.redecl", s);
+ else if (dupState == ScriptOrFnNode.DUPLICATE_PARAMETER)
+ addStrictWarning("msg.var.hides.arg", s);
+ else if (dupState == ScriptOrFnNode.DUPLICATE_VAR)
+ addStrictWarning("msg.var.redecl", s);
+ }
+ name = nf.createName(s);
+
+ // omitted check for argument hiding
+
+ if (matchToken(Token.ASSIGN)) {
+ decompiler.addToken(Token.ASSIGN);
+
+ init = assignExpr(context == Token.FOR);
+ nf.addChildToBack(name, init);
+ }
+ nf.addChildToBack(pn, name);
+ if (!matchToken(Token.COMMA))
+ break;
+ }
+ return pn;
+ }
+
+ private Node expr(boolean inForInit)
+ throws IOException, ParserException
+ {
+ Node pn = assignExpr(inForInit);
+ while (matchToken(Token.COMMA)) {
+ decompiler.addToken(Token.COMMA);
+ if (compilerEnv.isStrictMode() && !pn.hasSideEffects())
+ addStrictWarning("msg.no.side.effects", "");
+ pn = nf.createBinary(Token.COMMA, pn, assignExpr(inForInit));
+ }
+ return pn;
+ }
+
+ private Node assignExpr(boolean inForInit)
+ throws IOException, ParserException
+ {
+ Node pn = condExpr(inForInit);
+
+ int tt = peekToken();
+ if (Token.FIRST_ASSIGN <= tt && tt <= Token.LAST_ASSIGN) {
+ consumeToken();
+ decompiler.addToken(tt);
+ pn = nf.createAssignment(tt, pn, assignExpr(inForInit));
+ }
+
+ return pn;
+ }
+
+ private Node condExpr(boolean inForInit)
+ throws IOException, ParserException
+ {
+ Node pn = orExpr(inForInit);
+
+ if (matchToken(Token.HOOK)) {
+ decompiler.addToken(Token.HOOK);
+ Node ifTrue = assignExpr(false);
+ mustMatchToken(Token.COLON, "msg.no.colon.cond");
+ decompiler.addToken(Token.COLON);
+ Node ifFalse = assignExpr(inForInit);
+ return nf.createCondExpr(pn, ifTrue, ifFalse);
+ }
+
+ return pn;
+ }
+
+ private Node orExpr(boolean inForInit)
+ throws IOException, ParserException
+ {
+ Node pn = andExpr(inForInit);
+ if (matchToken(Token.OR)) {
+ decompiler.addToken(Token.OR);
+ pn = nf.createBinary(Token.OR, pn, orExpr(inForInit));
+ }
+
+ return pn;
+ }
+
+ private Node andExpr(boolean inForInit)
+ throws IOException, ParserException
+ {
+ Node pn = bitOrExpr(inForInit);
+ if (matchToken(Token.AND)) {
+ decompiler.addToken(Token.AND);
+ pn = nf.createBinary(Token.AND, pn, andExpr(inForInit));
+ }
+
+ return pn;
+ }
+
+ private Node bitOrExpr(boolean inForInit)
+ throws IOException, ParserException
+ {
+ Node pn = bitXorExpr(inForInit);
+ while (matchToken(Token.BITOR)) {
+ decompiler.addToken(Token.BITOR);
+ pn = nf.createBinary(Token.BITOR, pn, bitXorExpr(inForInit));
+ }
+ return pn;
+ }
+
+ private Node bitXorExpr(boolean inForInit)
+ throws IOException, ParserException
+ {
+ Node pn = bitAndExpr(inForInit);
+ while (matchToken(Token.BITXOR)) {
+ decompiler.addToken(Token.BITXOR);
+ pn = nf.createBinary(Token.BITXOR, pn, bitAndExpr(inForInit));
+ }
+ return pn;
+ }
+
+ private Node bitAndExpr(boolean inForInit)
+ throws IOException, ParserException
+ {
+ Node pn = eqExpr(inForInit);
+ while (matchToken(Token.BITAND)) {
+ decompiler.addToken(Token.BITAND);
+ pn = nf.createBinary(Token.BITAND, pn, eqExpr(inForInit));
+ }
+ return pn;
+ }
+
+ private Node eqExpr(boolean inForInit)
+ throws IOException, ParserException
+ {
+ Node pn = relExpr(inForInit);
+ for (;;) {
+ int tt = peekToken();
+ switch (tt) {
+ case Token.EQ:
+ case Token.NE:
+ case Token.SHEQ:
+ case Token.SHNE:
+ consumeToken();
+ int decompilerToken = tt;
+ int parseToken = tt;
+ if (compilerEnv.getLanguageVersion() == Context.VERSION_1_2) {
+ // JavaScript 1.2 uses shallow equality for == and != .
+ // In addition, convert === and !== for decompiler into
+ // == and != since the decompiler is supposed to show
+ // canonical source and in 1.2 ===, !== are allowed
+ // only as an alias to ==, !=.
+ switch (tt) {
+ case Token.EQ:
+ parseToken = Token.SHEQ;
+ break;
+ case Token.NE:
+ parseToken = Token.SHNE;
+ break;
+ case Token.SHEQ:
+ decompilerToken = Token.EQ;
+ break;
+ case Token.SHNE:
+ decompilerToken = Token.NE;
+ break;
+ }
+ }
+ decompiler.addToken(decompilerToken);
+ pn = nf.createBinary(parseToken, pn, relExpr(inForInit));
+ continue;
+ }
+ break;
+ }
+ return pn;
+ }
+
+ private Node relExpr(boolean inForInit)
+ throws IOException, ParserException
+ {
+ Node pn = shiftExpr();
+ for (;;) {
+ int tt = peekToken();
+ switch (tt) {
+ case Token.IN:
+ if (inForInit)
+ break;
+ // fall through
+ case Token.INSTANCEOF:
+ case Token.LE:
+ case Token.LT:
+ case Token.GE:
+ case Token.GT:
+ consumeToken();
+ decompiler.addToken(tt);
+ pn = nf.createBinary(tt, pn, shiftExpr());
+ continue;
+ }
+ break;
+ }
+ return pn;
+ }
+
+ private Node shiftExpr()
+ throws IOException, ParserException
+ {
+ Node pn = addExpr();
+ for (;;) {
+ int tt = peekToken();
+ switch (tt) {
+ case Token.LSH:
+ case Token.URSH:
+ case Token.RSH:
+ consumeToken();
+ decompiler.addToken(tt);
+ pn = nf.createBinary(tt, pn, addExpr());
+ continue;
+ }
+ break;
+ }
+ return pn;
+ }
+
+ private Node addExpr()
+ throws IOException, ParserException
+ {
+ Node pn = mulExpr();
+ for (;;) {
+ int tt = peekToken();
+ if (tt == Token.ADD || tt == Token.SUB) {
+ consumeToken();
+ decompiler.addToken(tt);
+ // flushNewLines
+ pn = nf.createBinary(tt, pn, mulExpr());
+ continue;
+ }
+ break;
+ }
+
+ return pn;
+ }
+
+ private Node mulExpr()
+ throws IOException, ParserException
+ {
+ Node pn = unaryExpr();
+ for (;;) {
+ int tt = peekToken();
+ switch (tt) {
+ case Token.MUL:
+ case Token.DIV:
+ case Token.MOD:
+ consumeToken();
+ decompiler.addToken(tt);
+ pn = nf.createBinary(tt, pn, unaryExpr());
+ continue;
+ }
+ break;
+ }
+
+ return pn;
+ }
+
+ private Node unaryExpr()
+ throws IOException, ParserException
+ {
+ int tt;
+
+ tt = peekToken();
+
+ switch(tt) {
+ case Token.VOID:
+ case Token.NOT:
+ case Token.BITNOT:
+ case Token.TYPEOF:
+ consumeToken();
+ decompiler.addToken(tt);
+ return nf.createUnary(tt, unaryExpr());
+
+ case Token.ADD:
+ consumeToken();
+ // Convert to special POS token in decompiler and parse tree
+ decompiler.addToken(Token.POS);
+ return nf.createUnary(Token.POS, unaryExpr());
+
+ case Token.SUB:
+ consumeToken();
+ // Convert to special NEG token in decompiler and parse tree
+ decompiler.addToken(Token.NEG);
+ return nf.createUnary(Token.NEG, unaryExpr());
+
+ case Token.INC:
+ case Token.DEC:
+ consumeToken();
+ decompiler.addToken(tt);
+ return nf.createIncDec(tt, false, memberExpr(true));
+
+ case Token.DELPROP:
+ consumeToken();
+ decompiler.addToken(Token.DELPROP);
+ return nf.createUnary(Token.DELPROP, unaryExpr());
+
+ case Token.ERROR:
+ consumeToken();
+ break;
+
+ // XML stream encountered in expression.
+ case Token.LT:
+ if (compilerEnv.isXmlAvailable()) {
+ consumeToken();
+ Node pn = xmlInitializer();
+ return memberExprTail(true, pn);
+ }
+ // Fall thru to the default handling of RELOP
+
+ default:
+ Node pn = memberExpr(true);
+
+ // Don't look across a newline boundary for a postfix incop.
+ tt = peekTokenOrEOL();
+ if (tt == Token.INC || tt == Token.DEC) {
+ consumeToken();
+ decompiler.addToken(tt);
+ return nf.createIncDec(tt, true, pn);
+ }
+ return pn;
+ }
+ return nf.createName("err"); // Only reached on error. Try to continue.
+
+ }
+
+ private Node xmlInitializer() throws IOException
+ {
+ int tt = ts.getFirstXMLToken();
+ if (tt != Token.XML && tt != Token.XMLEND) {
+ reportError("msg.syntax");
+ return null;
+ }
+
+ /* Make a NEW node to append to. */
+ Node pnXML = nf.createLeaf(Token.NEW);
+
+ String xml = ts.getString();
+ boolean fAnonymous = xml.trim().startsWith("<>");
+
+ Node pn = nf.createName(fAnonymous ? "XMLList" : "XML");
+ nf.addChildToBack(pnXML, pn);
+
+ pn = null;
+ Node expr;
+ for (;;tt = ts.getNextXMLToken()) {
+ switch (tt) {
+ case Token.XML:
+ xml = ts.getString();
+ decompiler.addName(xml);
+ mustMatchToken(Token.LC, "msg.syntax");
+ decompiler.addToken(Token.LC);
+ expr = (peekToken() == Token.RC)
+ ? nf.createString("")
+ : expr(false);
+ mustMatchToken(Token.RC, "msg.syntax");
+ decompiler.addToken(Token.RC);
+ if (pn == null) {
+ pn = nf.createString(xml);
+ } else {
+ pn = nf.createBinary(Token.ADD, pn, nf.createString(xml));
+ }
+ if (ts.isXMLAttribute()) {
+ /* Need to put the result in double quotes */
+ expr = nf.createUnary(Token.ESCXMLATTR, expr);
+ Node prepend = nf.createBinary(Token.ADD,
+ nf.createString("\""),
+ expr);
+ expr = nf.createBinary(Token.ADD,
+ prepend,
+ nf.createString("\""));
+ } else {
+ expr = nf.createUnary(Token.ESCXMLTEXT, expr);
+ }
+ pn = nf.createBinary(Token.ADD, pn, expr);
+ break;
+ case Token.XMLEND:
+ xml = ts.getString();
+ decompiler.addName(xml);
+ if (pn == null) {
+ pn = nf.createString(xml);
+ } else {
+ pn = nf.createBinary(Token.ADD, pn, nf.createString(xml));
+ }
+
+ nf.addChildToBack(pnXML, pn);
+ return pnXML;
+ default:
+ reportError("msg.syntax");
+ return null;
+ }
+ }
+ }
+
+ private void argumentList(Node listNode)
+ throws IOException, ParserException
+ {
+ boolean matched;
+ matched = matchToken(Token.RP);
+ if (!matched) {
+ boolean first = true;
+ do {
+ if (!first)
+ decompiler.addToken(Token.COMMA);
+ first = false;
+ nf.addChildToBack(listNode, assignExpr(false));
+ } while (matchToken(Token.COMMA));
+
+ mustMatchToken(Token.RP, "msg.no.paren.arg");
+ }
+ decompiler.addToken(Token.RP);
+ }
+
+ private Node memberExpr(boolean allowCallSyntax)
+ throws IOException, ParserException
+ {
+ int tt;
+
+ Node pn;
+
+ /* Check for new expressions. */
+ tt = peekToken();
+ if (tt == Token.NEW) {
+ /* Eat the NEW token. */
+ consumeToken();
+ decompiler.addToken(Token.NEW);
+
+ /* Make a NEW node to append to. */
+ pn = nf.createCallOrNew(Token.NEW, memberExpr(false));
+
+ if (matchToken(Token.LP)) {
+ decompiler.addToken(Token.LP);
+ /* Add the arguments to pn, if any are supplied. */
+ argumentList(pn);
+ }
+
+ /* XXX there's a check in the C source against
+ * "too many constructor arguments" - how many
+ * do we claim to support?
+ */
+
+ /* Experimental syntax: allow an object literal to follow a new expression,
+ * which will mean a kind of anonymous class built with the JavaAdapter.
+ * the object literal will be passed as an additional argument to the constructor.
+ */
+ tt = peekToken();
+ if (tt == Token.LC) {
+ nf.addChildToBack(pn, primaryExpr());
+ }
+ } else {
+ pn = primaryExpr();
+ }
+
+ return memberExprTail(allowCallSyntax, pn);
+ }
+
+ private Node memberExprTail(boolean allowCallSyntax, Node pn)
+ throws IOException, ParserException
+ {
+ tailLoop:
+ for (;;) {
+ int tt = peekToken();
+ switch (tt) {
+
+ case Token.DOT:
+ case Token.DOTDOT:
+ {
+ int memberTypeFlags;
+ String s;
+
+ consumeToken();
+ decompiler.addToken(tt);
+ memberTypeFlags = 0;
+ if (tt == Token.DOTDOT) {
+ mustHaveXML();
+ memberTypeFlags = Node.DESCENDANTS_FLAG;
+ }
+ if (!compilerEnv.isXmlAvailable()) {
+ mustMatchToken(Token.NAME, "msg.no.name.after.dot");
+ s = ts.getString();
+ decompiler.addName(s);
+ pn = nf.createPropertyGet(pn, null, s, memberTypeFlags);
+ break;
+ }
+
+ tt = nextToken();
+ switch (tt) {
+ // handles: name, ns::name, ns::*, ns::[expr]
+ case Token.NAME:
+ s = ts.getString();
+ decompiler.addName(s);
+ pn = propertyName(pn, s, memberTypeFlags);
+ break;
+
+ // handles: *, *::name, *::*, *::[expr]
+ case Token.MUL:
+ decompiler.addName("*");
+ pn = propertyName(pn, "*", memberTypeFlags);
+ break;
+
+ // handles: '@attr', '@ns::attr', '@ns::*', '@ns::*',
+ // '@::attr', '@::*', '@*', '@*::attr', '@*::*'
+ case Token.XMLATTR:
+ decompiler.addToken(Token.XMLATTR);
+ pn = attributeAccess(pn, memberTypeFlags);
+ break;
+
+ default:
+ reportError("msg.no.name.after.dot");
+ }
+ }
+ break;
+
+ case Token.DOTQUERY:
+ consumeToken();
+ mustHaveXML();
+ decompiler.addToken(Token.DOTQUERY);
+ pn = nf.createDotQuery(pn, expr(false), ts.getLineno());
+ mustMatchToken(Token.RP, "msg.no.paren");
+ decompiler.addToken(Token.RP);
+ break;
+
+ case Token.LB:
+ consumeToken();
+ decompiler.addToken(Token.LB);
+ pn = nf.createElementGet(pn, null, expr(false), 0);
+ mustMatchToken(Token.RB, "msg.no.bracket.index");
+ decompiler.addToken(Token.RB);
+ break;
+
+ case Token.LP:
+ if (!allowCallSyntax) {
+ break tailLoop;
+ }
+ consumeToken();
+ decompiler.addToken(Token.LP);
+ pn = nf.createCallOrNew(Token.CALL, pn);
+ /* Add the arguments to pn, if any are supplied. */
+ argumentList(pn);
+ break;
+
+ default:
+ break tailLoop;
+ }
+ }
+ return pn;
+ }
+
+ /*
+ * Xml attribute expression:
+ * '@attr', '@ns::attr', '@ns::*', '@ns::*', '@*', '@*::attr', '@*::*'
+ */
+ private Node attributeAccess(Node pn, int memberTypeFlags)
+ throws IOException
+ {
+ memberTypeFlags |= Node.ATTRIBUTE_FLAG;
+ int tt = nextToken();
+
+ switch (tt) {
+ // handles: @name, @ns::name, @ns::*, @ns::[expr]
+ case Token.NAME:
+ {
+ String s = ts.getString();
+ decompiler.addName(s);
+ pn = propertyName(pn, s, memberTypeFlags);
+ }
+ break;
+
+ // handles: @*, @*::name, @*::*, @*::[expr]
+ case Token.MUL:
+ decompiler.addName("*");
+ pn = propertyName(pn, "*", memberTypeFlags);
+ break;
+
+ // handles @[expr]
+ case Token.LB:
+ decompiler.addToken(Token.LB);
+ pn = nf.createElementGet(pn, null, expr(false), memberTypeFlags);
+ mustMatchToken(Token.RB, "msg.no.bracket.index");
+ decompiler.addToken(Token.RB);
+ break;
+
+ default:
+ reportError("msg.no.name.after.xmlAttr");
+ pn = nf.createPropertyGet(pn, null, "?", memberTypeFlags);
+ break;
+ }
+
+ return pn;
+ }
+
+ /**
+ * Check if :: follows name in which case it becomes qualified name
+ */
+ private Node propertyName(Node pn, String name, int memberTypeFlags)
+ throws IOException, ParserException
+ {
+ String namespace = null;
+ if (matchToken(Token.COLONCOLON)) {
+ decompiler.addToken(Token.COLONCOLON);
+ namespace = name;
+
+ int tt = nextToken();
+ switch (tt) {
+ // handles name::name
+ case Token.NAME:
+ name = ts.getString();
+ decompiler.addName(name);
+ break;
+
+ // handles name::*
+ case Token.MUL:
+ decompiler.addName("*");
+ name = "*";
+ break;
+
+ // handles name::[expr]
+ case Token.LB:
+ decompiler.addToken(Token.LB);
+ pn = nf.createElementGet(pn, namespace, expr(false),
+ memberTypeFlags);
+ mustMatchToken(Token.RB, "msg.no.bracket.index");
+ decompiler.addToken(Token.RB);
+ return pn;
+
+ default:
+ reportError("msg.no.name.after.coloncolon");
+ name = "?";
+ }
+ }
+
+ pn = nf.createPropertyGet(pn, namespace, name, memberTypeFlags);
+ return pn;
+ }
+
+ private Node primaryExpr()
+ throws IOException, ParserException
+ {
+ Node pn;
+
+ int ttFlagged = nextFlaggedToken();
+ int tt = ttFlagged & CLEAR_TI_MASK;
+
+ switch(tt) {
+
+ case Token.FUNCTION:
+ return function(FunctionNode.FUNCTION_EXPRESSION);
+
+ case Token.LB: {
+ ObjArray elems = new ObjArray();
+ int skipCount = 0;
+ decompiler.addToken(Token.LB);
+ boolean after_lb_or_comma = true;
+ for (;;) {
+ tt = peekToken();
+
+ if (tt == Token.COMMA) {
+ consumeToken();
+ decompiler.addToken(Token.COMMA);
+ if (!after_lb_or_comma) {
+ after_lb_or_comma = true;
+ } else {
+ elems.add(null);
+ ++skipCount;
+ }
+ } else if (tt == Token.RB) {
+ consumeToken();
+ decompiler.addToken(Token.RB);
+ break;
+ } else {
+ if (!after_lb_or_comma) {
+ reportError("msg.no.bracket.arg");
+ }
+ elems.add(assignExpr(false));
+ after_lb_or_comma = false;
+ }
+ }
+ return nf.createArrayLiteral(elems, skipCount);
+ }
+
+ case Token.LC: {
+ ObjArray elems = new ObjArray();
+ decompiler.addToken(Token.LC);
+ if (!matchToken(Token.RC)) {
+
+ boolean first = true;
+ commaloop:
+ do {
+ Object property;
+
+ if (!first)
+ decompiler.addToken(Token.COMMA);
+ else
+ first = false;
+
+ tt = peekToken();
+ switch(tt) {
+ case Token.NAME:
+ case Token.STRING:
+ consumeToken();
+ // map NAMEs to STRINGs in object literal context
+ // but tell the decompiler the proper type
+ String s = ts.getString();
+ if (tt == Token.NAME) {
+ if (s.equals("get") &&
+ peekToken() == Token.NAME) {
+ decompiler.addToken(Token.GET);
+ consumeToken();
+ s = ts.getString();
+ decompiler.addName(s);
+ property = ScriptRuntime.getIndexObject(s);
+ if (!getterSetterProperty(elems, property,
+ true))
+ break commaloop;
+ break;
+ } else if (s.equals("set") &&
+ peekToken() == Token.NAME) {
+ decompiler.addToken(Token.SET);
+ consumeToken();
+ s = ts.getString();
+ decompiler.addName(s);
+ property = ScriptRuntime.getIndexObject(s);
+ if (!getterSetterProperty(elems, property,
+ false))
+ break commaloop;
+ break;
+ }
+ decompiler.addName(s);
+ } else {
+ decompiler.addString(s);
+ }
+ property = ScriptRuntime.getIndexObject(s);
+ plainProperty(elems, property);
+ break;
+
+ case Token.NUMBER:
+ consumeToken();
+ double n = ts.getNumber();
+ decompiler.addNumber(n);
+ property = ScriptRuntime.getIndexObject(n);
+ plainProperty(elems, property);
+ break;
+
+ case Token.RC:
+ // trailing comma is OK.
+ break commaloop;
+ default:
+ reportError("msg.bad.prop");
+ break commaloop;
+ }
+ } while (matchToken(Token.COMMA));
+
+ mustMatchToken(Token.RC, "msg.no.brace.prop");
+ }
+ decompiler.addToken(Token.RC);
+ return nf.createObjectLiteral(elems);
+ }
+
+ case Token.LP:
+
+ /* Brendan's IR-jsparse.c makes a new node tagged with
+ * TOK_LP here... I'm not sure I understand why. Isn't
+ * the grouping already implicit in the structure of the
+ * parse tree? also TOK_LP is already overloaded (I
+ * think) in the C IR as 'function call.' */
+ decompiler.addToken(Token.LP);
+ pn = expr(false);
+ pn.putProp(Node.PARENTHESIZED_PROP, Boolean.TRUE);
+ decompiler.addToken(Token.RP);
+ mustMatchToken(Token.RP, "msg.no.paren");
+ return pn;
+
+ case Token.XMLATTR:
+ mustHaveXML();
+ decompiler.addToken(Token.XMLATTR);
+ pn = attributeAccess(null, 0);
+ return pn;
+
+ case Token.NAME: {
+ String name = ts.getString();
+ if ((ttFlagged & TI_CHECK_LABEL) != 0) {
+ if (peekToken() == Token.COLON) {
+ // Do not consume colon, it is used as unwind indicator
+ // to return to statementHelper.
+ // XXX Better way?
+ return nf.createLabel(ts.getLineno());
+ }
+ }
+
+ decompiler.addName(name);
+ if (compilerEnv.isXmlAvailable()) {
+ pn = propertyName(null, name, 0);
+ } else {
+ pn = nf.createName(name);
+ }
+ return pn;
+ }
+
+ case Token.NUMBER: {
+ double n = ts.getNumber();
+ decompiler.addNumber(n);
+ return nf.createNumber(n);
+ }
+
+ case Token.STRING: {
+ String s = ts.getString();
+ decompiler.addString(s);
+ return nf.createString(s);
+ }
+
+ case Token.DIV:
+ case Token.ASSIGN_DIV: {
+ // Got / or /= which should be treated as regexp in fact
+ ts.readRegExp(tt);
+ String flags = ts.regExpFlags;
+ ts.regExpFlags = null;
+ String re = ts.getString();
+ decompiler.addRegexp(re, flags);
+ int index = currentScriptOrFn.addRegexp(re, flags);
+ return nf.createRegExp(index);
+ }
+
+ case Token.NULL:
+ case Token.THIS:
+ case Token.FALSE:
+ case Token.TRUE:
+ decompiler.addToken(tt);
+ return nf.createLeaf(tt);
+
+ case Token.RESERVED:
+ reportError("msg.reserved.id");
+ break;
+
+ case Token.ERROR:
+ /* the scanner or one of its subroutines reported the error. */
+ break;
+
+ case Token.EOF:
+ reportError("msg.unexpected.eof");
+ break;
+
+ default:
+ reportError("msg.syntax");
+ break;
+ }
+ return null; // should never reach here
+ }
+
+ private void plainProperty(ObjArray elems, Object property)
+ throws IOException {
+ mustMatchToken(Token.COLON, "msg.no.colon.prop");
+
+ // OBJLIT is used as ':' in object literal for
+ // decompilation to solve spacing ambiguity.
+ decompiler.addToken(Token.OBJECTLIT);
+ elems.add(property);
+ elems.add(assignExpr(false));
+ }
+
+ private boolean getterSetterProperty(ObjArray elems, Object property,
+ boolean isGetter) throws IOException {
+ Node f = function(FunctionNode.FUNCTION_EXPRESSION);
+ if (f.getType() != Token.FUNCTION) {
+ reportError("msg.bad.prop");
+ return false;
+ }
+ int fnIndex = f.getExistingIntProp(Node.FUNCTION_PROP);
+ FunctionNode fn = currentScriptOrFn.getFunctionNode(fnIndex);
+ if (fn.getFunctionName().length() != 0) {
+ reportError("msg.bad.prop");
+ return false;
+ }
+ elems.add(property);
+ if (isGetter) {
+ elems.add(nf.createUnary(Token.GET, f));
+ } else {
+ elems.add(nf.createUnary(Token.SET, f));
+ }
+ return true;
+ }
+}
diff --git a/bin/yuicompressor-2.3.4/src/org/mozilla/javascript/Token.java b/bin/yuicompressor-2.3.4/src/org/mozilla/javascript/Token.java
new file mode 100644
index 0000000..e1285b4
--- /dev/null
+++ b/bin/yuicompressor-2.3.4/src/org/mozilla/javascript/Token.java
@@ -0,0 +1,420 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Roger Lawrence
+ * Mike McCabe
+ * Igor Bukanov
+ * Bob Jervis
+ * Milen Nankov
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.javascript;
+
+/**
+ * This class implements the JavaScript scanner.
+ *
+ * It is based on the C source files jsscan.c and jsscan.h
+ * in the jsref package.
+ *
+ * @see org.mozilla.javascript.Parser
+ *
+ * @author Mike McCabe
+ * @author Brendan Eich
+ */
+
+public class Token
+{
+
+ // debug flags
+ public static final boolean printTrees = false;
+ static final boolean printICode = false;
+ static final boolean printNames = printTrees || printICode;
+
+ /**
+ * Token types. These values correspond to JSTokenType values in
+ * jsscan.c.
+ */
+
+ public final static int
+ // start enum
+ ERROR = -1, // well-known as the only code < EOF
+ EOF = 0, // end of file token - (not EOF_CHAR)
+ EOL = 1, // end of line
+
+ // Interpreter reuses the following as bytecodes
+ FIRST_BYTECODE_TOKEN = 2,
+
+ ENTERWITH = 2,
+ LEAVEWITH = 3,
+ RETURN = 4,
+ GOTO = 5,
+ IFEQ = 6,
+ IFNE = 7,
+ SETNAME = 8,
+ BITOR = 9,
+ BITXOR = 10,
+ BITAND = 11,
+ EQ = 12,
+ NE = 13,
+ LT = 14,
+ LE = 15,
+ GT = 16,
+ GE = 17,
+ LSH = 18,
+ RSH = 19,
+ URSH = 20,
+ ADD = 21,
+ SUB = 22,
+ MUL = 23,
+ DIV = 24,
+ MOD = 25,
+ NOT = 26,
+ BITNOT = 27,
+ POS = 28,
+ NEG = 29,
+ NEW = 30,
+ DELPROP = 31,
+ TYPEOF = 32,
+ GETPROP = 33,
+ SETPROP = 34,
+ GETELEM = 35,
+ SETELEM = 36,
+ CALL = 37,
+ NAME = 38,
+ NUMBER = 39,
+ STRING = 40,
+ NULL = 41,
+ THIS = 42,
+ FALSE = 43,
+ TRUE = 44,
+ SHEQ = 45, // shallow equality (===)
+ SHNE = 46, // shallow inequality (!==)
+ REGEXP = 47,
+ BINDNAME = 48,
+ THROW = 49,
+ RETHROW = 50, // rethrow caught execetion: catch (e if ) use it
+ IN = 51,
+ INSTANCEOF = 52,
+ LOCAL_LOAD = 53,
+ GETVAR = 54,
+ SETVAR = 55,
+ CATCH_SCOPE = 56,
+ ENUM_INIT_KEYS = 57,
+ ENUM_INIT_VALUES = 58,
+ ENUM_NEXT = 59,
+ ENUM_ID = 60,
+ THISFN = 61,
+ RETURN_RESULT = 62, // to return prevoisly stored return result
+ ARRAYLIT = 63, // array literal
+ OBJECTLIT = 64, // object literal
+ GET_REF = 65, // *reference
+ SET_REF = 66, // *reference = something
+ DEL_REF = 67, // delete reference
+ REF_CALL = 68, // f(args) = something or f(args)++
+ REF_SPECIAL = 69, // reference for special properties like __proto
+
+ // For XML support:
+ DEFAULTNAMESPACE = 70, // default xml namespace =
+ ESCXMLATTR = 71,
+ ESCXMLTEXT = 72,
+ REF_MEMBER = 73, // Reference for x.@y, x..y etc.
+ REF_NS_MEMBER = 74, // Reference for x.ns::y, x..ns::y etc.
+ REF_NAME = 75, // Reference for @y, @[y] etc.
+ REF_NS_NAME = 76; // Reference for ns::y, @ns::y@[y] etc.
+
+ // End of interpreter bytecodes
+ public final static int
+ LAST_BYTECODE_TOKEN = REF_NS_NAME,
+
+ TRY = 77,
+ SEMI = 78, // semicolon
+ LB = 79, // left and right brackets
+ RB = 80,
+ LC = 81, // left and right curlies (braces)
+ RC = 82,
+ LP = 83, // left and right parentheses
+ RP = 84,
+ COMMA = 85, // comma operator
+
+ ASSIGN = 86, // simple assignment (=)
+ ASSIGN_BITOR = 87, // |=
+ ASSIGN_BITXOR = 88, // ^=
+ ASSIGN_BITAND = 89, // |=
+ ASSIGN_LSH = 90, // <<=
+ ASSIGN_RSH = 91, // >>=
+ ASSIGN_URSH = 92, // >>>=
+ ASSIGN_ADD = 93, // +=
+ ASSIGN_SUB = 94, // -=
+ ASSIGN_MUL = 95, // *=
+ ASSIGN_DIV = 96, // /=
+ ASSIGN_MOD = 97; // %=
+
+ public final static int
+ FIRST_ASSIGN = ASSIGN,
+ LAST_ASSIGN = ASSIGN_MOD,
+
+ HOOK = 98, // conditional (?:)
+ COLON = 99,
+ OR = 100, // logical or (||)
+ AND = 101, // logical and (&&)
+ INC = 102, // increment/decrement (++ --)
+ DEC = 103,
+ DOT = 104, // member operator (.)
+ FUNCTION = 105, // function keyword
+ EXPORT = 106, // export keyword
+ IMPORT = 107, // import keyword
+ IF = 108, // if keyword
+ ELSE = 109, // else keyword
+ SWITCH = 110, // switch keyword
+ CASE = 111, // case keyword
+ DEFAULT = 112, // default keyword
+ WHILE = 113, // while keyword
+ DO = 114, // do keyword
+ FOR = 115, // for keyword
+ BREAK = 116, // break keyword
+ CONTINUE = 117, // continue keyword
+ VAR = 118, // var keyword
+ WITH = 119, // with keyword
+ CATCH = 120, // catch keyword
+ FINALLY = 121, // finally keyword
+ VOID = 122, // void keyword
+ RESERVED = 123, // reserved keywords
+
+ EMPTY = 124,
+
+ /* types used for the parse tree - these never get returned
+ * by the scanner.
+ */
+
+ BLOCK = 125, // statement block
+ LABEL = 126, // label
+ TARGET = 127,
+ LOOP = 128,
+ EXPR_VOID = 129, // expression statement in functions
+ EXPR_RESULT = 130, // expression statement in scripts
+ JSR = 131,
+ SCRIPT = 132, // top-level node for entire script
+ TYPEOFNAME = 133, // for typeof(simple-name)
+ USE_STACK = 134,
+ SETPROP_OP = 135, // x.y op= something
+ SETELEM_OP = 136, // x[y] op= something
+ LOCAL_BLOCK = 137,
+ SET_REF_OP = 138, // *reference op= something
+
+ // For XML support:
+ DOTDOT = 139, // member operator (..)
+ COLONCOLON = 140, // namespace::name
+ XML = 141, // XML type
+ DOTQUERY = 142, // .() -- e.g., x.emps.emp.(name == "terry")
+ XMLATTR = 143, // @
+ XMLEND = 144,
+
+ // Optimizer-only-tokens
+ TO_OBJECT = 145,
+ TO_DOUBLE = 146,
+
+ GET = 147, // JS 1.5 get pseudo keyword
+ SET = 148, // JS 1.5 set pseudo keyword
+ CONST = 149,
+ SETCONST = 150,
+ SETCONSTVAR = 151,
+
+ SPECIALCOMMENT = 152, // Internet Explorer conditional comment
+
+ LAST_TOKEN = 153;
+
+ public static String name(int token)
+ {
+ if (!printNames) {
+ return String.valueOf(token);
+ }
+ switch (token) {
+ case ERROR: return "ERROR";
+ case EOF: return "EOF";
+ case EOL: return "EOL";
+ case ENTERWITH: return "ENTERWITH";
+ case LEAVEWITH: return "LEAVEWITH";
+ case RETURN: return "RETURN";
+ case GOTO: return "GOTO";
+ case IFEQ: return "IFEQ";
+ case IFNE: return "IFNE";
+ case SETNAME: return "SETNAME";
+ case BITOR: return "BITOR";
+ case BITXOR: return "BITXOR";
+ case BITAND: return "BITAND";
+ case EQ: return "EQ";
+ case NE: return "NE";
+ case LT: return "LT";
+ case LE: return "LE";
+ case GT: return "GT";
+ case GE: return "GE";
+ case LSH: return "LSH";
+ case RSH: return "RSH";
+ case URSH: return "URSH";
+ case ADD: return "ADD";
+ case SUB: return "SUB";
+ case MUL: return "MUL";
+ case DIV: return "DIV";
+ case MOD: return "MOD";
+ case NOT: return "NOT";
+ case BITNOT: return "BITNOT";
+ case POS: return "POS";
+ case NEG: return "NEG";
+ case NEW: return "NEW";
+ case DELPROP: return "DELPROP";
+ case TYPEOF: return "TYPEOF";
+ case GETPROP: return "GETPROP";
+ case SETPROP: return "SETPROP";
+ case GETELEM: return "GETELEM";
+ case SETELEM: return "SETELEM";
+ case CALL: return "CALL";
+ case NAME: return "NAME";
+ case NUMBER: return "NUMBER";
+ case STRING: return "STRING";
+ case NULL: return "NULL";
+ case THIS: return "THIS";
+ case FALSE: return "FALSE";
+ case TRUE: return "TRUE";
+ case SHEQ: return "SHEQ";
+ case SHNE: return "SHNE";
+ case REGEXP: return "OBJECT";
+ case BINDNAME: return "BINDNAME";
+ case THROW: return "THROW";
+ case RETHROW: return "RETHROW";
+ case IN: return "IN";
+ case INSTANCEOF: return "INSTANCEOF";
+ case LOCAL_LOAD: return "LOCAL_LOAD";
+ case GETVAR: return "GETVAR";
+ case SETVAR: return "SETVAR";
+ case CATCH_SCOPE: return "CATCH_SCOPE";
+ case ENUM_INIT_KEYS: return "ENUM_INIT_KEYS";
+ case ENUM_INIT_VALUES: return "ENUM_INIT_VALUES";
+ case ENUM_NEXT: return "ENUM_NEXT";
+ case ENUM_ID: return "ENUM_ID";
+ case THISFN: return "THISFN";
+ case RETURN_RESULT: return "RETURN_RESULT";
+ case ARRAYLIT: return "ARRAYLIT";
+ case OBJECTLIT: return "OBJECTLIT";
+ case GET_REF: return "GET_REF";
+ case SET_REF: return "SET_REF";
+ case DEL_REF: return "DEL_REF";
+ case REF_CALL: return "REF_CALL";
+ case REF_SPECIAL: return "REF_SPECIAL";
+ case DEFAULTNAMESPACE:return "DEFAULTNAMESPACE";
+ case ESCXMLTEXT: return "ESCXMLTEXT";
+ case ESCXMLATTR: return "ESCXMLATTR";
+ case REF_MEMBER: return "REF_MEMBER";
+ case REF_NS_MEMBER: return "REF_NS_MEMBER";
+ case REF_NAME: return "REF_NAME";
+ case REF_NS_NAME: return "REF_NS_NAME";
+ case TRY: return "TRY";
+ case SEMI: return "SEMI";
+ case LB: return "LB";
+ case RB: return "RB";
+ case LC: return "LC";
+ case RC: return "RC";
+ case LP: return "LP";
+ case RP: return "RP";
+ case COMMA: return "COMMA";
+ case ASSIGN: return "ASSIGN";
+ case ASSIGN_BITOR: return "ASSIGN_BITOR";
+ case ASSIGN_BITXOR: return "ASSIGN_BITXOR";
+ case ASSIGN_BITAND: return "ASSIGN_BITAND";
+ case ASSIGN_LSH: return "ASSIGN_LSH";
+ case ASSIGN_RSH: return "ASSIGN_RSH";
+ case ASSIGN_URSH: return "ASSIGN_URSH";
+ case ASSIGN_ADD: return "ASSIGN_ADD";
+ case ASSIGN_SUB: return "ASSIGN_SUB";
+ case ASSIGN_MUL: return "ASSIGN_MUL";
+ case ASSIGN_DIV: return "ASSIGN_DIV";
+ case ASSIGN_MOD: return "ASSIGN_MOD";
+ case HOOK: return "HOOK";
+ case COLON: return "COLON";
+ case OR: return "OR";
+ case AND: return "AND";
+ case INC: return "INC";
+ case DEC: return "DEC";
+ case DOT: return "DOT";
+ case FUNCTION: return "FUNCTION";
+ case EXPORT: return "EXPORT";
+ case IMPORT: return "IMPORT";
+ case IF: return "IF";
+ case ELSE: return "ELSE";
+ case SWITCH: return "SWITCH";
+ case CASE: return "CASE";
+ case DEFAULT: return "DEFAULT";
+ case WHILE: return "WHILE";
+ case DO: return "DO";
+ case FOR: return "FOR";
+ case BREAK: return "BREAK";
+ case CONTINUE: return "CONTINUE";
+ case VAR: return "VAR";
+ case WITH: return "WITH";
+ case CATCH: return "CATCH";
+ case FINALLY: return "FINALLY";
+ case RESERVED: return "RESERVED";
+ case EMPTY: return "EMPTY";
+ case BLOCK: return "BLOCK";
+ case LABEL: return "LABEL";
+ case TARGET: return "TARGET";
+ case LOOP: return "LOOP";
+ case EXPR_VOID: return "EXPR_VOID";
+ case EXPR_RESULT: return "EXPR_RESULT";
+ case JSR: return "JSR";
+ case SCRIPT: return "SCRIPT";
+ case TYPEOFNAME: return "TYPEOFNAME";
+ case USE_STACK: return "USE_STACK";
+ case SETPROP_OP: return "SETPROP_OP";
+ case SETELEM_OP: return "SETELEM_OP";
+ case LOCAL_BLOCK: return "LOCAL_BLOCK";
+ case SET_REF_OP: return "SET_REF_OP";
+ case DOTDOT: return "DOTDOT";
+ case COLONCOLON: return "COLONCOLON";
+ case XML: return "XML";
+ case DOTQUERY: return "DOTQUERY";
+ case XMLATTR: return "XMLATTR";
+ case XMLEND: return "XMLEND";
+ case TO_OBJECT: return "TO_OBJECT";
+ case TO_DOUBLE: return "TO_DOUBLE";
+ case GET: return "GET";
+ case SET: return "SET";
+ case CONST: return "CONST";
+ case SETCONST: return "SETCONST";
+ }
+
+ // Token without name
+ throw new IllegalStateException(String.valueOf(token));
+ }
+}
diff --git a/bin/yuicompressor-2.3.4/src/org/mozilla/javascript/Token.java.orig b/bin/yuicompressor-2.3.4/src/org/mozilla/javascript/Token.java.orig
new file mode 100644
index 0000000..7f7cdc2
--- /dev/null
+++ b/bin/yuicompressor-2.3.4/src/org/mozilla/javascript/Token.java.orig
@@ -0,0 +1,417 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Roger Lawrence
+ * Mike McCabe
+ * Igor Bukanov
+ * Bob Jervis
+ * Milen Nankov
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.javascript;
+
+/**
+ * This class implements the JavaScript scanner.
+ *
+ * It is based on the C source files jsscan.c and jsscan.h
+ * in the jsref package.
+ *
+ * @see org.mozilla.javascript.Parser
+ *
+ * @author Mike McCabe
+ * @author Brendan Eich
+ */
+
+public class Token
+{
+
+ // debug flags
+ public static final boolean printTrees = false;
+ static final boolean printICode = false;
+ static final boolean printNames = printTrees || printICode;
+
+ /**
+ * Token types. These values correspond to JSTokenType values in
+ * jsscan.c.
+ */
+
+ public final static int
+ // start enum
+ ERROR = -1, // well-known as the only code < EOF
+ EOF = 0, // end of file token - (not EOF_CHAR)
+ EOL = 1, // end of line
+
+ // Interpreter reuses the following as bytecodes
+ FIRST_BYTECODE_TOKEN = 2,
+
+ ENTERWITH = 2,
+ LEAVEWITH = 3,
+ RETURN = 4,
+ GOTO = 5,
+ IFEQ = 6,
+ IFNE = 7,
+ SETNAME = 8,
+ BITOR = 9,
+ BITXOR = 10,
+ BITAND = 11,
+ EQ = 12,
+ NE = 13,
+ LT = 14,
+ LE = 15,
+ GT = 16,
+ GE = 17,
+ LSH = 18,
+ RSH = 19,
+ URSH = 20,
+ ADD = 21,
+ SUB = 22,
+ MUL = 23,
+ DIV = 24,
+ MOD = 25,
+ NOT = 26,
+ BITNOT = 27,
+ POS = 28,
+ NEG = 29,
+ NEW = 30,
+ DELPROP = 31,
+ TYPEOF = 32,
+ GETPROP = 33,
+ SETPROP = 34,
+ GETELEM = 35,
+ SETELEM = 36,
+ CALL = 37,
+ NAME = 38,
+ NUMBER = 39,
+ STRING = 40,
+ NULL = 41,
+ THIS = 42,
+ FALSE = 43,
+ TRUE = 44,
+ SHEQ = 45, // shallow equality (===)
+ SHNE = 46, // shallow inequality (!==)
+ REGEXP = 47,
+ BINDNAME = 48,
+ THROW = 49,
+ RETHROW = 50, // rethrow caught execetion: catch (e if ) use it
+ IN = 51,
+ INSTANCEOF = 52,
+ LOCAL_LOAD = 53,
+ GETVAR = 54,
+ SETVAR = 55,
+ CATCH_SCOPE = 56,
+ ENUM_INIT_KEYS = 57,
+ ENUM_INIT_VALUES = 58,
+ ENUM_NEXT = 59,
+ ENUM_ID = 60,
+ THISFN = 61,
+ RETURN_RESULT = 62, // to return prevoisly stored return result
+ ARRAYLIT = 63, // array literal
+ OBJECTLIT = 64, // object literal
+ GET_REF = 65, // *reference
+ SET_REF = 66, // *reference = something
+ DEL_REF = 67, // delete reference
+ REF_CALL = 68, // f(args) = something or f(args)++
+ REF_SPECIAL = 69, // reference for special properties like __proto
+
+ // For XML support:
+ DEFAULTNAMESPACE = 70, // default xml namespace =
+ ESCXMLATTR = 71,
+ ESCXMLTEXT = 72,
+ REF_MEMBER = 73, // Reference for x.@y, x..y etc.
+ REF_NS_MEMBER = 74, // Reference for x.ns::y, x..ns::y etc.
+ REF_NAME = 75, // Reference for @y, @[y] etc.
+ REF_NS_NAME = 76; // Reference for ns::y, @ns::y@[y] etc.
+
+ // End of interpreter bytecodes
+ public final static int
+ LAST_BYTECODE_TOKEN = REF_NS_NAME,
+
+ TRY = 77,
+ SEMI = 78, // semicolon
+ LB = 79, // left and right brackets
+ RB = 80,
+ LC = 81, // left and right curlies (braces)
+ RC = 82,
+ LP = 83, // left and right parentheses
+ RP = 84,
+ COMMA = 85, // comma operator
+
+ ASSIGN = 86, // simple assignment (=)
+ ASSIGN_BITOR = 87, // |=
+ ASSIGN_BITXOR = 88, // ^=
+ ASSIGN_BITAND = 89, // |=
+ ASSIGN_LSH = 90, // <<=
+ ASSIGN_RSH = 91, // >>=
+ ASSIGN_URSH = 92, // >>>=
+ ASSIGN_ADD = 93, // +=
+ ASSIGN_SUB = 94, // -=
+ ASSIGN_MUL = 95, // *=
+ ASSIGN_DIV = 96, // /=
+ ASSIGN_MOD = 97; // %=
+
+ public final static int
+ FIRST_ASSIGN = ASSIGN,
+ LAST_ASSIGN = ASSIGN_MOD,
+
+ HOOK = 98, // conditional (?:)
+ COLON = 99,
+ OR = 100, // logical or (||)
+ AND = 101, // logical and (&&)
+ INC = 102, // increment/decrement (++ --)
+ DEC = 103,
+ DOT = 104, // member operator (.)
+ FUNCTION = 105, // function keyword
+ EXPORT = 106, // export keyword
+ IMPORT = 107, // import keyword
+ IF = 108, // if keyword
+ ELSE = 109, // else keyword
+ SWITCH = 110, // switch keyword
+ CASE = 111, // case keyword
+ DEFAULT = 112, // default keyword
+ WHILE = 113, // while keyword
+ DO = 114, // do keyword
+ FOR = 115, // for keyword
+ BREAK = 116, // break keyword
+ CONTINUE = 117, // continue keyword
+ VAR = 118, // var keyword
+ WITH = 119, // with keyword
+ CATCH = 120, // catch keyword
+ FINALLY = 121, // finally keyword
+ VOID = 122, // void keyword
+ RESERVED = 123, // reserved keywords
+
+ EMPTY = 124,
+
+ /* types used for the parse tree - these never get returned
+ * by the scanner.
+ */
+
+ BLOCK = 125, // statement block
+ LABEL = 126, // label
+ TARGET = 127,
+ LOOP = 128,
+ EXPR_VOID = 129, // expression statement in functions
+ EXPR_RESULT = 130, // expression statement in scripts
+ JSR = 131,
+ SCRIPT = 132, // top-level node for entire script
+ TYPEOFNAME = 133, // for typeof(simple-name)
+ USE_STACK = 134,
+ SETPROP_OP = 135, // x.y op= something
+ SETELEM_OP = 136, // x[y] op= something
+ LOCAL_BLOCK = 137,
+ SET_REF_OP = 138, // *reference op= something
+
+ // For XML support:
+ DOTDOT = 139, // member operator (..)
+ COLONCOLON = 140, // namespace::name
+ XML = 141, // XML type
+ DOTQUERY = 142, // .() -- e.g., x.emps.emp.(name == "terry")
+ XMLATTR = 143, // @
+ XMLEND = 144,
+
+ // Optimizer-only-tokens
+ TO_OBJECT = 145,
+ TO_DOUBLE = 146,
+
+ GET = 147, // JS 1.5 get pseudo keyword
+ SET = 148, // JS 1.5 set pseudo keyword
+ CONST = 149,
+ SETCONST = 150,
+ SETCONSTVAR = 151,
+ LAST_TOKEN = 152;
+
+ public static String name(int token)
+ {
+ if (!printNames) {
+ return String.valueOf(token);
+ }
+ switch (token) {
+ case ERROR: return "ERROR";
+ case EOF: return "EOF";
+ case EOL: return "EOL";
+ case ENTERWITH: return "ENTERWITH";
+ case LEAVEWITH: return "LEAVEWITH";
+ case RETURN: return "RETURN";
+ case GOTO: return "GOTO";
+ case IFEQ: return "IFEQ";
+ case IFNE: return "IFNE";
+ case SETNAME: return "SETNAME";
+ case BITOR: return "BITOR";
+ case BITXOR: return "BITXOR";
+ case BITAND: return "BITAND";
+ case EQ: return "EQ";
+ case NE: return "NE";
+ case LT: return "LT";
+ case LE: return "LE";
+ case GT: return "GT";
+ case GE: return "GE";
+ case LSH: return "LSH";
+ case RSH: return "RSH";
+ case URSH: return "URSH";
+ case ADD: return "ADD";
+ case SUB: return "SUB";
+ case MUL: return "MUL";
+ case DIV: return "DIV";
+ case MOD: return "MOD";
+ case NOT: return "NOT";
+ case BITNOT: return "BITNOT";
+ case POS: return "POS";
+ case NEG: return "NEG";
+ case NEW: return "NEW";
+ case DELPROP: return "DELPROP";
+ case TYPEOF: return "TYPEOF";
+ case GETPROP: return "GETPROP";
+ case SETPROP: return "SETPROP";
+ case GETELEM: return "GETELEM";
+ case SETELEM: return "SETELEM";
+ case CALL: return "CALL";
+ case NAME: return "NAME";
+ case NUMBER: return "NUMBER";
+ case STRING: return "STRING";
+ case NULL: return "NULL";
+ case THIS: return "THIS";
+ case FALSE: return "FALSE";
+ case TRUE: return "TRUE";
+ case SHEQ: return "SHEQ";
+ case SHNE: return "SHNE";
+ case REGEXP: return "OBJECT";
+ case BINDNAME: return "BINDNAME";
+ case THROW: return "THROW";
+ case RETHROW: return "RETHROW";
+ case IN: return "IN";
+ case INSTANCEOF: return "INSTANCEOF";
+ case LOCAL_LOAD: return "LOCAL_LOAD";
+ case GETVAR: return "GETVAR";
+ case SETVAR: return "SETVAR";
+ case CATCH_SCOPE: return "CATCH_SCOPE";
+ case ENUM_INIT_KEYS: return "ENUM_INIT_KEYS";
+ case ENUM_INIT_VALUES: return "ENUM_INIT_VALUES";
+ case ENUM_NEXT: return "ENUM_NEXT";
+ case ENUM_ID: return "ENUM_ID";
+ case THISFN: return "THISFN";
+ case RETURN_RESULT: return "RETURN_RESULT";
+ case ARRAYLIT: return "ARRAYLIT";
+ case OBJECTLIT: return "OBJECTLIT";
+ case GET_REF: return "GET_REF";
+ case SET_REF: return "SET_REF";
+ case DEL_REF: return "DEL_REF";
+ case REF_CALL: return "REF_CALL";
+ case REF_SPECIAL: return "REF_SPECIAL";
+ case DEFAULTNAMESPACE:return "DEFAULTNAMESPACE";
+ case ESCXMLTEXT: return "ESCXMLTEXT";
+ case ESCXMLATTR: return "ESCXMLATTR";
+ case REF_MEMBER: return "REF_MEMBER";
+ case REF_NS_MEMBER: return "REF_NS_MEMBER";
+ case REF_NAME: return "REF_NAME";
+ case REF_NS_NAME: return "REF_NS_NAME";
+ case TRY: return "TRY";
+ case SEMI: return "SEMI";
+ case LB: return "LB";
+ case RB: return "RB";
+ case LC: return "LC";
+ case RC: return "RC";
+ case LP: return "LP";
+ case RP: return "RP";
+ case COMMA: return "COMMA";
+ case ASSIGN: return "ASSIGN";
+ case ASSIGN_BITOR: return "ASSIGN_BITOR";
+ case ASSIGN_BITXOR: return "ASSIGN_BITXOR";
+ case ASSIGN_BITAND: return "ASSIGN_BITAND";
+ case ASSIGN_LSH: return "ASSIGN_LSH";
+ case ASSIGN_RSH: return "ASSIGN_RSH";
+ case ASSIGN_URSH: return "ASSIGN_URSH";
+ case ASSIGN_ADD: return "ASSIGN_ADD";
+ case ASSIGN_SUB: return "ASSIGN_SUB";
+ case ASSIGN_MUL: return "ASSIGN_MUL";
+ case ASSIGN_DIV: return "ASSIGN_DIV";
+ case ASSIGN_MOD: return "ASSIGN_MOD";
+ case HOOK: return "HOOK";
+ case COLON: return "COLON";
+ case OR: return "OR";
+ case AND: return "AND";
+ case INC: return "INC";
+ case DEC: return "DEC";
+ case DOT: return "DOT";
+ case FUNCTION: return "FUNCTION";
+ case EXPORT: return "EXPORT";
+ case IMPORT: return "IMPORT";
+ case IF: return "IF";
+ case ELSE: return "ELSE";
+ case SWITCH: return "SWITCH";
+ case CASE: return "CASE";
+ case DEFAULT: return "DEFAULT";
+ case WHILE: return "WHILE";
+ case DO: return "DO";
+ case FOR: return "FOR";
+ case BREAK: return "BREAK";
+ case CONTINUE: return "CONTINUE";
+ case VAR: return "VAR";
+ case WITH: return "WITH";
+ case CATCH: return "CATCH";
+ case FINALLY: return "FINALLY";
+ case RESERVED: return "RESERVED";
+ case EMPTY: return "EMPTY";
+ case BLOCK: return "BLOCK";
+ case LABEL: return "LABEL";
+ case TARGET: return "TARGET";
+ case LOOP: return "LOOP";
+ case EXPR_VOID: return "EXPR_VOID";
+ case EXPR_RESULT: return "EXPR_RESULT";
+ case JSR: return "JSR";
+ case SCRIPT: return "SCRIPT";
+ case TYPEOFNAME: return "TYPEOFNAME";
+ case USE_STACK: return "USE_STACK";
+ case SETPROP_OP: return "SETPROP_OP";
+ case SETELEM_OP: return "SETELEM_OP";
+ case LOCAL_BLOCK: return "LOCAL_BLOCK";
+ case SET_REF_OP: return "SET_REF_OP";
+ case DOTDOT: return "DOTDOT";
+ case COLONCOLON: return "COLONCOLON";
+ case XML: return "XML";
+ case DOTQUERY: return "DOTQUERY";
+ case XMLATTR: return "XMLATTR";
+ case XMLEND: return "XMLEND";
+ case TO_OBJECT: return "TO_OBJECT";
+ case TO_DOUBLE: return "TO_DOUBLE";
+ case GET: return "GET";
+ case SET: return "SET";
+ case CONST: return "CONST";
+ case SETCONST: return "SETCONST";
+ }
+
+ // Token without name
+ throw new IllegalStateException(String.valueOf(token));
+ }
+}
diff --git a/bin/yuicompressor-2.3.4/src/org/mozilla/javascript/TokenStream.java b/bin/yuicompressor-2.3.4/src/org/mozilla/javascript/TokenStream.java
new file mode 100644
index 0000000..38a10fd
--- /dev/null
+++ b/bin/yuicompressor-2.3.4/src/org/mozilla/javascript/TokenStream.java
@@ -0,0 +1,1381 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Roger Lawrence
+ * Mike McCabe
+ * Igor Bukanov
+ * Ethan Hugg
+ * Bob Jervis
+ * Terry Lucas
+ * Milen Nankov
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.javascript;
+
+import java.io.*;
+
+/**
+ * This class implements the JavaScript scanner.
+ *
+ * It is based on the C source files jsscan.c and jsscan.h
+ * in the jsref package.
+ *
+ * @see org.mozilla.javascript.Parser
+ *
+ * @author Mike McCabe
+ * @author Brendan Eich
+ */
+
+class TokenStream
+{
+ /*
+ * For chars - because we need something out-of-range
+ * to check. (And checking EOF by exception is annoying.)
+ * Note distinction from EOF token type!
+ */
+ private final static int
+ EOF_CHAR = -1;
+
+ TokenStream(Parser parser, Reader sourceReader, String sourceString,
+ int lineno)
+ {
+ this.parser = parser;
+ this.lineno = lineno;
+ if (sourceReader != null) {
+ if (sourceString != null) Kit.codeBug();
+ this.sourceReader = sourceReader;
+ this.sourceBuffer = new char[512];
+ this.sourceEnd = 0;
+ } else {
+ if (sourceString == null) Kit.codeBug();
+ this.sourceString = sourceString;
+ this.sourceEnd = sourceString.length();
+ }
+ this.sourceCursor = 0;
+ }
+
+ /* This function uses the cached op, string and number fields in
+ * TokenStream; if getToken has been called since the passed token
+ * was scanned, the op or string printed may be incorrect.
+ */
+ String tokenToString(int token)
+ {
+ if (Token.printTrees) {
+ String name = Token.name(token);
+
+ switch (token) {
+ case Token.STRING:
+ case Token.REGEXP:
+ case Token.NAME:
+ return name + " `" + this.string + "'";
+
+ case Token.NUMBER:
+ return "NUMBER " + this.number;
+ }
+
+ return name;
+ }
+ return "";
+ }
+
+ static boolean isKeyword(String s)
+ {
+ return Token.EOF != stringToKeyword(s);
+ }
+
+ private static int stringToKeyword(String name)
+ {
+// #string_id_map#
+// The following assumes that Token.EOF == 0
+ final int
+ Id_break = Token.BREAK,
+ Id_case = Token.CASE,
+ Id_continue = Token.CONTINUE,
+ Id_default = Token.DEFAULT,
+ Id_delete = Token.DELPROP,
+ Id_do = Token.DO,
+ Id_else = Token.ELSE,
+ Id_export = Token.EXPORT,
+ Id_false = Token.FALSE,
+ Id_for = Token.FOR,
+ Id_function = Token.FUNCTION,
+ Id_if = Token.IF,
+ Id_in = Token.IN,
+ Id_new = Token.NEW,
+ Id_null = Token.NULL,
+ Id_return = Token.RETURN,
+ Id_switch = Token.SWITCH,
+ Id_this = Token.THIS,
+ Id_true = Token.TRUE,
+ Id_typeof = Token.TYPEOF,
+ Id_var = Token.VAR,
+ Id_void = Token.VOID,
+ Id_while = Token.WHILE,
+ Id_with = Token.WITH,
+
+ // the following are #ifdef RESERVE_JAVA_KEYWORDS in jsscan.c
+ Id_abstract = Token.RESERVED,
+ Id_boolean = Token.RESERVED,
+ Id_byte = Token.RESERVED,
+ Id_catch = Token.CATCH,
+ Id_char = Token.RESERVED,
+ Id_class = Token.RESERVED,
+ Id_const = Token.CONST,
+ Id_debugger = Token.RESERVED,
+ Id_double = Token.RESERVED,
+ Id_enum = Token.RESERVED,
+ Id_extends = Token.RESERVED,
+ Id_final = Token.RESERVED,
+ Id_finally = Token.FINALLY,
+ Id_float = Token.RESERVED,
+ Id_goto = Token.RESERVED,
+ Id_implements = Token.RESERVED,
+ Id_import = Token.IMPORT,
+ Id_instanceof = Token.INSTANCEOF,
+ Id_int = Token.RESERVED,
+ Id_interface = Token.RESERVED,
+ Id_long = Token.RESERVED,
+ Id_native = Token.RESERVED,
+ Id_package = Token.RESERVED,
+ Id_private = Token.RESERVED,
+ Id_protected = Token.RESERVED,
+ Id_public = Token.RESERVED,
+ Id_short = Token.RESERVED,
+ Id_static = Token.RESERVED,
+ Id_super = Token.RESERVED,
+ Id_synchronized = Token.RESERVED,
+ Id_throw = Token.THROW,
+ Id_throws = Token.RESERVED,
+ Id_transient = Token.RESERVED,
+ Id_try = Token.TRY,
+ Id_volatile = Token.RESERVED;
+
+ int id;
+ String s = name;
+// #generated# Last update: 2001-06-01 17:45:01 CEST
+ L0: { id = 0; String X = null; int c;
+ L: switch (s.length()) {
+ case 2: c=s.charAt(1);
+ if (c=='f') { if (s.charAt(0)=='i') {id=Id_if; break L0;} }
+ else if (c=='n') { if (s.charAt(0)=='i') {id=Id_in; break L0;} }
+ else if (c=='o') { if (s.charAt(0)=='d') {id=Id_do; break L0;} }
+ break L;
+ case 3: switch (s.charAt(0)) {
+ case 'f': if (s.charAt(2)=='r' && s.charAt(1)=='o') {id=Id_for; break L0;} break L;
+ case 'i': if (s.charAt(2)=='t' && s.charAt(1)=='n') {id=Id_int; break L0;} break L;
+ case 'n': if (s.charAt(2)=='w' && s.charAt(1)=='e') {id=Id_new; break L0;} break L;
+ case 't': if (s.charAt(2)=='y' && s.charAt(1)=='r') {id=Id_try; break L0;} break L;
+ case 'v': if (s.charAt(2)=='r' && s.charAt(1)=='a') {id=Id_var; break L0;} break L;
+ } break L;
+ case 4: switch (s.charAt(0)) {
+ case 'b': X="byte";id=Id_byte; break L;
+ case 'c': c=s.charAt(3);
+ if (c=='e') { if (s.charAt(2)=='s' && s.charAt(1)=='a') {id=Id_case; break L0;} }
+ else if (c=='r') { if (s.charAt(2)=='a' && s.charAt(1)=='h') {id=Id_char; break L0;} }
+ break L;
+ case 'e': c=s.charAt(3);
+ if (c=='e') { if (s.charAt(2)=='s' && s.charAt(1)=='l') {id=Id_else; break L0;} }
+ else if (c=='m') { if (s.charAt(2)=='u' && s.charAt(1)=='n') {id=Id_enum; break L0;} }
+ break L;
+ case 'g': X="goto";id=Id_goto; break L;
+ case 'l': X="long";id=Id_long; break L;
+ case 'n': X="null";id=Id_null; break L;
+ case 't': c=s.charAt(3);
+ if (c=='e') { if (s.charAt(2)=='u' && s.charAt(1)=='r') {id=Id_true; break L0;} }
+ else if (c=='s') { if (s.charAt(2)=='i' && s.charAt(1)=='h') {id=Id_this; break L0;} }
+ break L;
+ case 'v': X="void";id=Id_void; break L;
+ case 'w': X="with";id=Id_with; break L;
+ } break L;
+ case 5: switch (s.charAt(2)) {
+ case 'a': X="class";id=Id_class; break L;
+ case 'e': X="break";id=Id_break; break L;
+ case 'i': X="while";id=Id_while; break L;
+ case 'l': X="false";id=Id_false; break L;
+ case 'n': c=s.charAt(0);
+ if (c=='c') { X="const";id=Id_const; }
+ else if (c=='f') { X="final";id=Id_final; }
+ break L;
+ case 'o': c=s.charAt(0);
+ if (c=='f') { X="float";id=Id_float; }
+ else if (c=='s') { X="short";id=Id_short; }
+ break L;
+ case 'p': X="super";id=Id_super; break L;
+ case 'r': X="throw";id=Id_throw; break L;
+ case 't': X="catch";id=Id_catch; break L;
+ } break L;
+ case 6: switch (s.charAt(1)) {
+ case 'a': X="native";id=Id_native; break L;
+ case 'e': c=s.charAt(0);
+ if (c=='d') { X="delete";id=Id_delete; }
+ else if (c=='r') { X="return";id=Id_return; }
+ break L;
+ case 'h': X="throws";id=Id_throws; break L;
+ case 'm': X="import";id=Id_import; break L;
+ case 'o': X="double";id=Id_double; break L;
+ case 't': X="static";id=Id_static; break L;
+ case 'u': X="public";id=Id_public; break L;
+ case 'w': X="switch";id=Id_switch; break L;
+ case 'x': X="export";id=Id_export; break L;
+ case 'y': X="typeof";id=Id_typeof; break L;
+ } break L;
+ case 7: switch (s.charAt(1)) {
+ case 'a': X="package";id=Id_package; break L;
+ case 'e': X="default";id=Id_default; break L;
+ case 'i': X="finally";id=Id_finally; break L;
+ case 'o': X="boolean";id=Id_boolean; break L;
+ case 'r': X="private";id=Id_private; break L;
+ case 'x': X="extends";id=Id_extends; break L;
+ } break L;
+ case 8: switch (s.charAt(0)) {
+ case 'a': X="abstract";id=Id_abstract; break L;
+ case 'c': X="continue";id=Id_continue; break L;
+ case 'd': X="debugger";id=Id_debugger; break L;
+ case 'f': X="function";id=Id_function; break L;
+ case 'v': X="volatile";id=Id_volatile; break L;
+ } break L;
+ case 9: c=s.charAt(0);
+ if (c=='i') { X="interface";id=Id_interface; }
+ else if (c=='p') { X="protected";id=Id_protected; }
+ else if (c=='t') { X="transient";id=Id_transient; }
+ break L;
+ case 10: c=s.charAt(1);
+ if (c=='m') { X="implements";id=Id_implements; }
+ else if (c=='n') { X="instanceof";id=Id_instanceof; }
+ break L;
+ case 12: X="synchronized";id=Id_synchronized; break L;
+ }
+ if (X!=null && X!=s && !X.equals(s)) id = 0;
+ }
+// #/generated#
+// #/string_id_map#
+ if (id == 0) { return Token.EOF; }
+ return id & 0xff;
+ }
+
+ final int getLineno() { return lineno; }
+
+ final String getString() { return string; }
+
+ final double getNumber() { return number; }
+
+ final boolean eof() { return hitEOF; }
+
+ final int getToken() throws IOException
+ {
+ int c;
+
+ retry:
+ for (;;) {
+ // Eat whitespace, possibly sensitive to newlines.
+ for (;;) {
+ c = getChar();
+ if (c == EOF_CHAR) {
+ return Token.EOF;
+ } else if (c == '\n') {
+ dirtyLine = false;
+ return Token.EOL;
+ } else if (!isJSSpace(c)) {
+ if (c != '-') {
+ dirtyLine = true;
+ }
+ break;
+ }
+ }
+
+ if (c == '@') return Token.XMLATTR;
+
+ // identifier/keyword/instanceof?
+ // watch out for starting with a <backslash>
+ boolean identifierStart;
+ boolean isUnicodeEscapeStart = false;
+ if (c == '\\') {
+ c = getChar();
+ if (c == 'u') {
+ identifierStart = true;
+ isUnicodeEscapeStart = true;
+ stringBufferTop = 0;
+ } else {
+ identifierStart = false;
+ ungetChar(c);
+ c = '\\';
+ }
+ } else {
+ identifierStart = Character.isJavaIdentifierStart((char)c);
+ if (identifierStart) {
+ stringBufferTop = 0;
+ addToString(c);
+ }
+ }
+
+ if (identifierStart) {
+ boolean containsEscape = isUnicodeEscapeStart;
+ for (;;) {
+ if (isUnicodeEscapeStart) {
+ // strictly speaking we should probably push-back
+ // all the bad characters if the <backslash>uXXXX
+ // sequence is malformed. But since there isn't a
+ // correct context(is there?) for a bad Unicode
+ // escape sequence in an identifier, we can report
+ // an error here.
+ int escapeVal = 0;
+ for (int i = 0; i != 4; ++i) {
+ c = getChar();
+ escapeVal = Kit.xDigitToInt(c, escapeVal);
+ // Next check takes care about c < 0 and bad escape
+ if (escapeVal < 0) { break; }
+ }
+ if (escapeVal < 0) {
+ parser.addError("msg.invalid.escape");
+ return Token.ERROR;
+ }
+ addToString(escapeVal);
+ isUnicodeEscapeStart = false;
+ } else {
+ c = getChar();
+ if (c == '\\') {
+ c = getChar();
+ if (c == 'u') {
+ isUnicodeEscapeStart = true;
+ containsEscape = true;
+ } else {
+ parser.addError("msg.illegal.character");
+ return Token.ERROR;
+ }
+ } else {
+ if (c == EOF_CHAR
+ || !Character.isJavaIdentifierPart((char)c))
+ {
+ break;
+ }
+ addToString(c);
+ }
+ }
+ }
+ ungetChar(c);
+
+ String str = getStringFromBuffer();
+ if (!containsEscape) {
+ // OPT we shouldn't have to make a string (object!) to
+ // check if it's a keyword.
+
+ // Return the corresponding token if it's a keyword
+ int result = stringToKeyword(str);
+ if (result != Token.EOF) {
+ if (result != Token.RESERVED) {
+ return result;
+ } else if (!parser.compilerEnv.
+ isReservedKeywordAsIdentifier())
+ {
+ return result;
+ } else {
+ // If implementation permits to use future reserved
+ // keywords in violation with the EcmaScript,
+ // treat it as name but issue warning
+ parser.addWarning("msg.reserved.keyword", str);
+ }
+ }
+ }
+ this.string = (String)allStrings.intern(str);
+ return Token.NAME;
+ }
+
+ // is it a number?
+ if (isDigit(c) || (c == '.' && isDigit(peekChar()))) {
+
+ stringBufferTop = 0;
+ int base = 10;
+
+ if (c == '0') {
+ c = getChar();
+ if (c == 'x' || c == 'X') {
+ base = 16;
+ c = getChar();
+ } else if (isDigit(c)) {
+ base = 8;
+ } else {
+ addToString('0');
+ }
+ }
+
+ if (base == 16) {
+ while (0 <= Kit.xDigitToInt(c, 0)) {
+ addToString(c);
+ c = getChar();
+ }
+ } else {
+ while ('0' <= c && c <= '9') {
+ /*
+ * We permit 08 and 09 as decimal numbers, which
+ * makes our behavior a superset of the ECMA
+ * numeric grammar. We might not always be so
+ * permissive, so we warn about it.
+ */
+ if (base == 8 && c >= '8') {
+ parser.addWarning("msg.bad.octal.literal",
+ c == '8' ? "8" : "9");
+ base = 10;
+ }
+ addToString(c);
+ c = getChar();
+ }
+ }
+
+ boolean isInteger = true;
+
+ if (base == 10 && (c == '.' || c == 'e' || c == 'E')) {
+ isInteger = false;
+ if (c == '.') {
+ do {
+ addToString(c);
+ c = getChar();
+ } while (isDigit(c));
+ }
+ if (c == 'e' || c == 'E') {
+ addToString(c);
+ c = getChar();
+ if (c == '+' || c == '-') {
+ addToString(c);
+ c = getChar();
+ }
+ if (!isDigit(c)) {
+ parser.addError("msg.missing.exponent");
+ return Token.ERROR;
+ }
+ do {
+ addToString(c);
+ c = getChar();
+ } while (isDigit(c));
+ }
+ }
+ ungetChar(c);
+ String numString = getStringFromBuffer();
+
+ double dval;
+ if (base == 10 && !isInteger) {
+ try {
+ // Use Java conversion to number from string...
+ dval = Double.valueOf(numString).doubleValue();
+ }
+ catch (NumberFormatException ex) {
+ parser.addError("msg.caught.nfe");
+ return Token.ERROR;
+ }
+ } else {
+ dval = ScriptRuntime.stringToNumber(numString, 0, base);
+ }
+
+ this.number = dval;
+ return Token.NUMBER;
+ }
+
+ // is it a string?
+ if (c == '"' || c == '\'') {
+ // We attempt to accumulate a string the fast way, by
+ // building it directly out of the reader. But if there
+ // are any escaped characters in the string, we revert to
+ // building it out of a StringBuffer.
+
+ int quoteChar = c;
+ stringBufferTop = 0;
+
+ c = getChar();
+ while (c != quoteChar) {
+ if (c == '\n' || c == EOF_CHAR) {
+ ungetChar(c);
+ parser.addError("msg.unterminated.string.lit");
+ return Token.ERROR;
+ }
+
+ if (c == '\\') {
+ // We've hit an escaped character
+
+ c = getChar();
+
+ switch (c) {
+
+ case '\\': // backslash
+ case 'b': // backspace
+ case 'f': // form feed
+ case 'n': // line feed
+ case 'r': // carriage return
+ case 't': // horizontal tab
+ case 'v': // vertical tab
+ case 'd': // octal sequence
+ case 'u': // unicode sequence
+ case 'x': // hexadecimal sequence
+ // Only keep the '\' character for those
+ // characters that need to be escaped...
+ // Don't escape quoting characters...
+ addToString('\\');
+ addToString(c);
+ break;
+
+ case '\n':
+ // Remove line terminator after escape
+ break;
+
+ default:
+ if (isDigit(c)) {
+ // Octal representation of a character.
+ // Preserve the escaping (see Y! bug #1637286)
+ addToString('\\');
+ }
+ addToString(c);
+ break;
+ }
+
+ } else {
+
+ addToString(c);
+ }
+
+ c = getChar();
+ }
+
+ String str = getStringFromBuffer();
+ this.string = (String)allStrings.intern(str);
+ return Token.STRING;
+ }
+
+ switch (c) {
+ case ';': return Token.SEMI;
+ case '[': return Token.LB;
+ case ']': return Token.RB;
+ case '{': return Token.LC;
+ case '}': return Token.RC;
+ case '(': return Token.LP;
+ case ')': return Token.RP;
+ case ',': return Token.COMMA;
+ case '?': return Token.HOOK;
+ case ':':
+ if (matchChar(':')) {
+ return Token.COLONCOLON;
+ } else {
+ return Token.COLON;
+ }
+ case '.':
+ if (matchChar('.')) {
+ return Token.DOTDOT;
+ } else if (matchChar('(')) {
+ return Token.DOTQUERY;
+ } else {
+ return Token.DOT;
+ }
+
+ case '|':
+ if (matchChar('|')) {
+ return Token.OR;
+ } else if (matchChar('=')) {
+ return Token.ASSIGN_BITOR;
+ } else {
+ return Token.BITOR;
+ }
+
+ case '^':
+ if (matchChar('=')) {
+ return Token.ASSIGN_BITXOR;
+ } else {
+ return Token.BITXOR;
+ }
+
+ case '&':
+ if (matchChar('&')) {
+ return Token.AND;
+ } else if (matchChar('=')) {
+ return Token.ASSIGN_BITAND;
+ } else {
+ return Token.BITAND;
+ }
+
+ case '=':
+ if (matchChar('=')) {
+ if (matchChar('='))
+ return Token.SHEQ;
+ else
+ return Token.EQ;
+ } else {
+ return Token.ASSIGN;
+ }
+
+ case '!':
+ if (matchChar('=')) {
+ if (matchChar('='))
+ return Token.SHNE;
+ else
+ return Token.NE;
+ } else {
+ return Token.NOT;
+ }
+
+ case '<':
+ /* NB:treat HTML begin-comment as comment-till-eol */
+ if (matchChar('!')) {
+ if (matchChar('-')) {
+ if (matchChar('-')) {
+ skipLine();
+ continue retry;
+ }
+ ungetChar('-');
+ }
+ ungetChar('!');
+ }
+ if (matchChar('<')) {
+ if (matchChar('=')) {
+ return Token.ASSIGN_LSH;
+ } else {
+ return Token.LSH;
+ }
+ } else {
+ if (matchChar('=')) {
+ return Token.LE;
+ } else {
+ return Token.LT;
+ }
+ }
+
+ case '>':
+ if (matchChar('>')) {
+ if (matchChar('>')) {
+ if (matchChar('=')) {
+ return Token.ASSIGN_URSH;
+ } else {
+ return Token.URSH;
+ }
+ } else {
+ if (matchChar('=')) {
+ return Token.ASSIGN_RSH;
+ } else {
+ return Token.RSH;
+ }
+ }
+ } else {
+ if (matchChar('=')) {
+ return Token.GE;
+ } else {
+ return Token.GT;
+ }
+ }
+
+ case '*':
+ if (matchChar('=')) {
+ return Token.ASSIGN_MUL;
+ } else {
+ return Token.MUL;
+ }
+
+ case '/':
+ // is it a // comment?
+ if (matchChar('/')) {
+ skipLine();
+ continue retry;
+ }
+ if (matchChar('*')) {
+ boolean lookForSlash = false;
+ StringBuffer sb = new StringBuffer();
+ for (;;) {
+ c = getChar();
+ if (c == EOF_CHAR) {
+ parser.addError("msg.unterminated.comment");
+ return Token.ERROR;
+ }
+ sb.append((char) c);
+ if (c == '*') {
+ lookForSlash = true;
+ } else if (c == '/') {
+ if (lookForSlash) {
+ sb.delete(sb.length()-2, sb.length());
+ String s = sb.toString();
+ if (s.startsWith("!") ||
+ s.startsWith("@cc_on") ||
+ s.startsWith("@if") ||
+ s.startsWith("@elif") ||
+ s.startsWith("@else") ||
+ s.startsWith("@end")) {
+ if (s.startsWith("!")) {
+ // Remove the leading '!'
+ this.string = s.substring(1);
+ } else {
+ this.string = s;
+ }
+ return Token.SPECIALCOMMENT;
+ } else {
+ continue retry;
+ }
+ }
+ } else {
+ lookForSlash = false;
+ }
+ }
+ }
+
+ if (matchChar('=')) {
+ return Token.ASSIGN_DIV;
+ } else {
+ return Token.DIV;
+ }
+
+ case '%':
+ if (matchChar('=')) {
+ return Token.ASSIGN_MOD;
+ } else {
+ return Token.MOD;
+ }
+
+ case '~':
+ return Token.BITNOT;
+
+ case '+':
+ if (matchChar('=')) {
+ return Token.ASSIGN_ADD;
+ } else if (matchChar('+')) {
+ return Token.INC;
+ } else {
+ return Token.ADD;
+ }
+
+ case '-':
+ if (matchChar('=')) {
+ c = Token.ASSIGN_SUB;
+ } else if (matchChar('-')) {
+ if (!dirtyLine) {
+ // treat HTML end-comment after possible whitespace
+ // after line start as comment-utill-eol
+ if (matchChar('>')) {
+ skipLine();
+ continue retry;
+ }
+ }
+ c = Token.DEC;
+ } else {
+ c = Token.SUB;
+ }
+ dirtyLine = true;
+ return c;
+
+ default:
+ parser.addError("msg.illegal.character");
+ return Token.ERROR;
+ }
+ }
+ }
+
+ private static boolean isAlpha(int c)
+ {
+ // Use 'Z' < 'a'
+ if (c <= 'Z') {
+ return 'A' <= c;
+ } else {
+ return 'a' <= c && c <= 'z';
+ }
+ }
+
+ static boolean isDigit(int c)
+ {
+ return '0' <= c && c <= '9';
+ }
+
+ /* As defined in ECMA. jsscan.c uses C isspace() (which allows
+ * \v, I think.) note that code in getChar() implicitly accepts
+ * '\r' == \u000D as well.
+ */
+ static boolean isJSSpace(int c)
+ {
+ if (c <= 127) {
+ return c == 0x20 || c == 0x9 || c == 0xC || c == 0xB;
+ } else {
+ return c == 0xA0
+ || Character.getType((char)c) == Character.SPACE_SEPARATOR;
+ }
+ }
+
+ private static boolean isJSFormatChar(int c)
+ {
+ return c > 127 && Character.getType((char)c) == Character.FORMAT;
+ }
+
+ /**
+ * Parser calls the method when it gets / or /= in literal context.
+ */
+ void readRegExp(int startToken)
+ throws IOException
+ {
+ stringBufferTop = 0;
+ if (startToken == Token.ASSIGN_DIV) {
+ // Miss-scanned /=
+ addToString('=');
+ } else {
+ if (startToken != Token.DIV) Kit.codeBug();
+ }
+
+ int c;
+ boolean inClass = false;
+ while ((c = getChar()) != '/' || inClass) {
+ if (c == '\n' || c == EOF_CHAR) {
+ ungetChar(c);
+ throw parser.reportError("msg.unterminated.re.lit");
+ }
+ if (c == '\\') {
+ addToString(c);
+ c = getChar();
+ } else if (c == '[') {
+ inClass = true;
+ } else if (c == ']') {
+ inClass = false;
+ }
+
+ addToString(c);
+ }
+ int reEnd = stringBufferTop;
+
+ while (true) {
+ if (matchChar('g'))
+ addToString('g');
+ else if (matchChar('i'))
+ addToString('i');
+ else if (matchChar('m'))
+ addToString('m');
+ else
+ break;
+ }
+
+ if (isAlpha(peekChar())) {
+ throw parser.reportError("msg.invalid.re.flag");
+ }
+
+ this.string = new String(stringBuffer, 0, reEnd);
+ this.regExpFlags = new String(stringBuffer, reEnd,
+ stringBufferTop - reEnd);
+ }
+
+ boolean isXMLAttribute()
+ {
+ return xmlIsAttribute;
+ }
+
+ int getFirstXMLToken() throws IOException
+ {
+ xmlOpenTagsCount = 0;
+ xmlIsAttribute = false;
+ xmlIsTagContent = false;
+ ungetChar('<');
+ return getNextXMLToken();
+ }
+
+ int getNextXMLToken() throws IOException
+ {
+ stringBufferTop = 0; // remember the XML
+
+ for (int c = getChar(); c != EOF_CHAR; c = getChar()) {
+ if (xmlIsTagContent) {
+ switch (c) {
+ case '>':
+ addToString(c);
+ xmlIsTagContent = false;
+ xmlIsAttribute = false;
+ break;
+ case '/':
+ addToString(c);
+ if (peekChar() == '>') {
+ c = getChar();
+ addToString(c);
+ xmlIsTagContent = false;
+ xmlOpenTagsCount--;
+ }
+ break;
+ case '{':
+ ungetChar(c);
+ this.string = getStringFromBuffer();
+ return Token.XML;
+ case '\'':
+ case '"':
+ addToString(c);
+ if (!readQuotedString(c)) return Token.ERROR;
+ break;
+ case '=':
+ addToString(c);
+ xmlIsAttribute = true;
+ break;
+ case ' ':
+ case '\t':
+ case '\r':
+ case '\n':
+ addToString(c);
+ break;
+ default:
+ addToString(c);
+ xmlIsAttribute = false;
+ break;
+ }
+
+ if (!xmlIsTagContent && xmlOpenTagsCount == 0) {
+ this.string = getStringFromBuffer();
+ return Token.XMLEND;
+ }
+ } else {
+ switch (c) {
+ case '<':
+ addToString(c);
+ c = peekChar();
+ switch (c) {
+ case '!':
+ c = getChar(); // Skip !
+ addToString(c);
+ c = peekChar();
+ switch (c) {
+ case '-':
+ c = getChar(); // Skip -
+ addToString(c);
+ c = getChar();
+ if (c == '-') {
+ addToString(c);
+ if(!readXmlComment()) return Token.ERROR;
+ } else {
+ // throw away the string in progress
+ stringBufferTop = 0;
+ this.string = null;
+ parser.addError("msg.XML.bad.form");
+ return Token.ERROR;
+ }
+ break;
+ case '[':
+ c = getChar(); // Skip [
+ addToString(c);
+ if (getChar() == 'C' &&
+ getChar() == 'D' &&
+ getChar() == 'A' &&
+ getChar() == 'T' &&
+ getChar() == 'A' &&
+ getChar() == '[')
+ {
+ addToString('C');
+ addToString('D');
+ addToString('A');
+ addToString('T');
+ addToString('A');
+ addToString('[');
+ if (!readCDATA()) return Token.ERROR;
+
+ } else {
+ // throw away the string in progress
+ stringBufferTop = 0;
+ this.string = null;
+ parser.addError("msg.XML.bad.form");
+ return Token.ERROR;
+ }
+ break;
+ default:
+ if(!readEntity()) return Token.ERROR;
+ break;
+ }
+ break;
+ case '?':
+ c = getChar(); // Skip ?
+ addToString(c);
+ if (!readPI()) return Token.ERROR;
+ break;
+ case '/':
+ // End tag
+ c = getChar(); // Skip /
+ addToString(c);
+ if (xmlOpenTagsCount == 0) {
+ // throw away the string in progress
+ stringBufferTop = 0;
+ this.string = null;
+ parser.addError("msg.XML.bad.form");
+ return Token.ERROR;
+ }
+ xmlIsTagContent = true;
+ xmlOpenTagsCount--;
+ break;
+ default:
+ // Start tag
+ xmlIsTagContent = true;
+ xmlOpenTagsCount++;
+ break;
+ }
+ break;
+ case '{':
+ ungetChar(c);
+ this.string = getStringFromBuffer();
+ return Token.XML;
+ default:
+ addToString(c);
+ break;
+ }
+ }
+ }
+
+ stringBufferTop = 0; // throw away the string in progress
+ this.string = null;
+ parser.addError("msg.XML.bad.form");
+ return Token.ERROR;
+ }
+
+ /**
+ *
+ */
+ private boolean readQuotedString(int quote) throws IOException
+ {
+ for (int c = getChar(); c != EOF_CHAR; c = getChar()) {
+ addToString(c);
+ if (c == quote) return true;
+ }
+
+ stringBufferTop = 0; // throw away the string in progress
+ this.string = null;
+ parser.addError("msg.XML.bad.form");
+ return false;
+ }
+
+ /**
+ *
+ */
+ private boolean readXmlComment() throws IOException
+ {
+ for (int c = getChar(); c != EOF_CHAR;) {
+ addToString(c);
+ if (c == '-' && peekChar() == '-') {
+ c = getChar();
+ addToString(c);
+ if (peekChar() == '>') {
+ c = getChar(); // Skip >
+ addToString(c);
+ return true;
+ } else {
+ continue;
+ }
+ }
+ c = getChar();
+ }
+
+ stringBufferTop = 0; // throw away the string in progress
+ this.string = null;
+ parser.addError("msg.XML.bad.form");
+ return false;
+ }
+
+ /**
+ *
+ */
+ private boolean readCDATA() throws IOException
+ {
+ for (int c = getChar(); c != EOF_CHAR;) {
+ addToString(c);
+ if (c == ']' && peekChar() == ']') {
+ c = getChar();
+ addToString(c);
+ if (peekChar() == '>') {
+ c = getChar(); // Skip >
+ addToString(c);
+ return true;
+ } else {
+ continue;
+ }
+ }
+ c = getChar();
+ }
+
+ stringBufferTop = 0; // throw away the string in progress
+ this.string = null;
+ parser.addError("msg.XML.bad.form");
+ return false;
+ }
+
+ /**
+ *
+ */
+ private boolean readEntity() throws IOException
+ {
+ int declTags = 1;
+ for (int c = getChar(); c != EOF_CHAR; c = getChar()) {
+ addToString(c);
+ switch (c) {
+ case '<':
+ declTags++;
+ break;
+ case '>':
+ declTags--;
+ if (declTags == 0) return true;
+ break;
+ }
+ }
+
+ stringBufferTop = 0; // throw away the string in progress
+ this.string = null;
+ parser.addError("msg.XML.bad.form");
+ return false;
+ }
+
+ /**
+ *
+ */
+ private boolean readPI() throws IOException
+ {
+ for (int c = getChar(); c != EOF_CHAR; c = getChar()) {
+ addToString(c);
+ if (c == '?' && peekChar() == '>') {
+ c = getChar(); // Skip >
+ addToString(c);
+ return true;
+ }
+ }
+
+ stringBufferTop = 0; // throw away the string in progress
+ this.string = null;
+ parser.addError("msg.XML.bad.form");
+ return false;
+ }
+
+ private String getStringFromBuffer()
+ {
+ return new String(stringBuffer, 0, stringBufferTop);
+ }
+
+ private void addToString(int c)
+ {
+ int N = stringBufferTop;
+ if (N == stringBuffer.length) {
+ char[] tmp = new char[stringBuffer.length * 2];
+ System.arraycopy(stringBuffer, 0, tmp, 0, N);
+ stringBuffer = tmp;
+ }
+ stringBuffer[N] = (char)c;
+ stringBufferTop = N + 1;
+ }
+
+ private void ungetChar(int c)
+ {
+ // can not unread past across line boundary
+ if (ungetCursor != 0 && ungetBuffer[ungetCursor - 1] == '\n')
+ Kit.codeBug();
+ ungetBuffer[ungetCursor++] = c;
+ }
+
+ private boolean matchChar(int test) throws IOException
+ {
+ int c = getChar();
+ if (c == test) {
+ return true;
+ } else {
+ ungetChar(c);
+ return false;
+ }
+ }
+
+ private int peekChar() throws IOException
+ {
+ int c = getChar();
+ ungetChar(c);
+ return c;
+ }
+
+ private int getChar() throws IOException
+ {
+ if (ungetCursor != 0) {
+ return ungetBuffer[--ungetCursor];
+ }
+
+ for(;;) {
+ int c;
+ if (sourceString != null) {
+ if (sourceCursor == sourceEnd) {
+ hitEOF = true;
+ return EOF_CHAR;
+ }
+ c = sourceString.charAt(sourceCursor++);
+ } else {
+ if (sourceCursor == sourceEnd) {
+ if (!fillSourceBuffer()) {
+ hitEOF = true;
+ return EOF_CHAR;
+ }
+ }
+ c = sourceBuffer[sourceCursor++];
+ }
+
+ if (lineEndChar >= 0) {
+ if (lineEndChar == '\r' && c == '\n') {
+ lineEndChar = '\n';
+ continue;
+ }
+ lineEndChar = -1;
+ lineStart = sourceCursor - 1;
+ lineno++;
+ }
+
+ if (c <= 127) {
+ if (c == '\n' || c == '\r') {
+ lineEndChar = c;
+ c = '\n';
+ }
+ } else {
+ if (isJSFormatChar(c)) {
+ continue;
+ }
+ if (ScriptRuntime.isJSLineTerminator(c)) {
+ lineEndChar = c;
+ c = '\n';
+ }
+ }
+ return c;
+ }
+ }
+
+ private void skipLine() throws IOException
+ {
+ // skip to end of line
+ int c;
+ while ((c = getChar()) != EOF_CHAR && c != '\n') { }
+ ungetChar(c);
+ }
+
+ final int getOffset()
+ {
+ int n = sourceCursor - lineStart;
+ if (lineEndChar >= 0) { --n; }
+ return n;
+ }
+
+ final String getLine()
+ {
+ if (sourceString != null) {
+ // String case
+ int lineEnd = sourceCursor;
+ if (lineEndChar >= 0) {
+ --lineEnd;
+ } else {
+ for (; lineEnd != sourceEnd; ++lineEnd) {
+ int c = sourceString.charAt(lineEnd);
+ if (ScriptRuntime.isJSLineTerminator(c)) {
+ break;
+ }
+ }
+ }
+ return sourceString.substring(lineStart, lineEnd);
+ } else {
+ // Reader case
+ int lineLength = sourceCursor - lineStart;
+ if (lineEndChar >= 0) {
+ --lineLength;
+ } else {
+ // Read until the end of line
+ for (;; ++lineLength) {
+ int i = lineStart + lineLength;
+ if (i == sourceEnd) {
+ try {
+ if (!fillSourceBuffer()) { break; }
+ } catch (IOException ioe) {
+ // ignore it, we're already displaying an error...
+ break;
+ }
+ // i recalculuation as fillSourceBuffer can move saved
+ // line buffer and change lineStart
+ i = lineStart + lineLength;
+ }
+ int c = sourceBuffer[i];
+ if (ScriptRuntime.isJSLineTerminator(c)) {
+ break;
+ }
+ }
+ }
+ return new String(sourceBuffer, lineStart, lineLength);
+ }
+ }
+
+ private boolean fillSourceBuffer() throws IOException
+ {
+ if (sourceString != null) Kit.codeBug();
+ if (sourceEnd == sourceBuffer.length) {
+ if (lineStart != 0) {
+ System.arraycopy(sourceBuffer, lineStart, sourceBuffer, 0,
+ sourceEnd - lineStart);
+ sourceEnd -= lineStart;
+ sourceCursor -= lineStart;
+ lineStart = 0;
+ } else {
+ char[] tmp = new char[sourceBuffer.length * 2];
+ System.arraycopy(sourceBuffer, 0, tmp, 0, sourceEnd);
+ sourceBuffer = tmp;
+ }
+ }
+ int n = sourceReader.read(sourceBuffer, sourceEnd,
+ sourceBuffer.length - sourceEnd);
+ if (n < 0) {
+ return false;
+ }
+ sourceEnd += n;
+ return true;
+ }
+
+ // stuff other than whitespace since start of line
+ private boolean dirtyLine;
+
+ String regExpFlags;
+
+ // Set this to an inital non-null value so that the Parser has
+ // something to retrieve even if an error has occured and no
+ // string is found. Fosters one class of error, but saves lots of
+ // code.
+ private String string = "";
+ private double number;
+
+ private char[] stringBuffer = new char[128];
+ private int stringBufferTop;
+ private ObjToIntMap allStrings = new ObjToIntMap(50);
+
+ // Room to backtrace from to < on failed match of the last - in <!--
+ private final int[] ungetBuffer = new int[3];
+ private int ungetCursor;
+
+ private boolean hitEOF = false;
+
+ private int lineStart = 0;
+ private int lineno;
+ private int lineEndChar = -1;
+
+ private String sourceString;
+ private Reader sourceReader;
+ private char[] sourceBuffer;
+ private int sourceEnd;
+ private int sourceCursor;
+
+ // for xml tokenizer
+ private boolean xmlIsAttribute;
+ private boolean xmlIsTagContent;
+ private int xmlOpenTagsCount;
+
+ private Parser parser;
+}
diff --git a/bin/yuicompressor-2.3.4/src/org/mozilla/javascript/TokenStream.java.orig b/bin/yuicompressor-2.3.4/src/org/mozilla/javascript/TokenStream.java.orig
new file mode 100644
index 0000000..c276894
--- /dev/null
+++ b/bin/yuicompressor-2.3.4/src/org/mozilla/javascript/TokenStream.java.orig
@@ -0,0 +1,1398 @@
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1997-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Roger Lawrence
+ * Mike McCabe
+ * Igor Bukanov
+ * Ethan Hugg
+ * Bob Jervis
+ * Terry Lucas
+ * Milen Nankov
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.javascript;
+
+import java.io.*;
+
+/**
+ * This class implements the JavaScript scanner.
+ *
+ * It is based on the C source files jsscan.c and jsscan.h
+ * in the jsref package.
+ *
+ * @see org.mozilla.javascript.Parser
+ *
+ * @author Mike McCabe
+ * @author Brendan Eich
+ */
+
+class TokenStream
+{
+ /*
+ * For chars - because we need something out-of-range
+ * to check. (And checking EOF by exception is annoying.)
+ * Note distinction from EOF token type!
+ */
+ private final static int
+ EOF_CHAR = -1;
+
+ TokenStream(Parser parser, Reader sourceReader, String sourceString,
+ int lineno)
+ {
+ this.parser = parser;
+ this.lineno = lineno;
+ if (sourceReader != null) {
+ if (sourceString != null) Kit.codeBug();
+ this.sourceReader = sourceReader;
+ this.sourceBuffer = new char[512];
+ this.sourceEnd = 0;
+ } else {
+ if (sourceString == null) Kit.codeBug();
+ this.sourceString = sourceString;
+ this.sourceEnd = sourceString.length();
+ }
+ this.sourceCursor = 0;
+ }
+
+ /* This function uses the cached op, string and number fields in
+ * TokenStream; if getToken has been called since the passed token
+ * was scanned, the op or string printed may be incorrect.
+ */
+ String tokenToString(int token)
+ {
+ if (Token.printTrees) {
+ String name = Token.name(token);
+
+ switch (token) {
+ case Token.STRING:
+ case Token.REGEXP:
+ case Token.NAME:
+ return name + " `" + this.string + "'";
+
+ case Token.NUMBER:
+ return "NUMBER " + this.number;
+ }
+
+ return name;
+ }
+ return "";
+ }
+
+ static boolean isKeyword(String s)
+ {
+ return Token.EOF != stringToKeyword(s);
+ }
+
+ private static int stringToKeyword(String name)
+ {
+// #string_id_map#
+// The following assumes that Token.EOF == 0
+ final int
+ Id_break = Token.BREAK,
+ Id_case = Token.CASE,
+ Id_continue = Token.CONTINUE,
+ Id_default = Token.DEFAULT,
+ Id_delete = Token.DELPROP,
+ Id_do = Token.DO,
+ Id_else = Token.ELSE,
+ Id_export = Token.EXPORT,
+ Id_false = Token.FALSE,
+ Id_for = Token.FOR,
+ Id_function = Token.FUNCTION,
+ Id_if = Token.IF,
+ Id_in = Token.IN,
+ Id_new = Token.NEW,
+ Id_null = Token.NULL,
+ Id_return = Token.RETURN,
+ Id_switch = Token.SWITCH,
+ Id_this = Token.THIS,
+ Id_true = Token.TRUE,
+ Id_typeof = Token.TYPEOF,
+ Id_var = Token.VAR,
+ Id_void = Token.VOID,
+ Id_while = Token.WHILE,
+ Id_with = Token.WITH,
+
+ // the following are #ifdef RESERVE_JAVA_KEYWORDS in jsscan.c
+ Id_abstract = Token.RESERVED,
+ Id_boolean = Token.RESERVED,
+ Id_byte = Token.RESERVED,
+ Id_catch = Token.CATCH,
+ Id_char = Token.RESERVED,
+ Id_class = Token.RESERVED,
+ Id_const = Token.CONST,
+ Id_debugger = Token.RESERVED,
+ Id_double = Token.RESERVED,
+ Id_enum = Token.RESERVED,
+ Id_extends = Token.RESERVED,
+ Id_final = Token.RESERVED,
+ Id_finally = Token.FINALLY,
+ Id_float = Token.RESERVED,
+ Id_goto = Token.RESERVED,
+ Id_implements = Token.RESERVED,
+ Id_import = Token.IMPORT,
+ Id_instanceof = Token.INSTANCEOF,
+ Id_int = Token.RESERVED,
+ Id_interface = Token.RESERVED,
+ Id_long = Token.RESERVED,
+ Id_native = Token.RESERVED,
+ Id_package = Token.RESERVED,
+ Id_private = Token.RESERVED,
+ Id_protected = Token.RESERVED,
+ Id_public = Token.RESERVED,
+ Id_short = Token.RESERVED,
+ Id_static = Token.RESERVED,
+ Id_super = Token.RESERVED,
+ Id_synchronized = Token.RESERVED,
+ Id_throw = Token.THROW,
+ Id_throws = Token.RESERVED,
+ Id_transient = Token.RESERVED,
+ Id_try = Token.TRY,
+ Id_volatile = Token.RESERVED;
+
+ int id;
+ String s = name;
+// #generated# Last update: 2001-06-01 17:45:01 CEST
+ L0: { id = 0; String X = null; int c;
+ L: switch (s.length()) {
+ case 2: c=s.charAt(1);
+ if (c=='f') { if (s.charAt(0)=='i') {id=Id_if; break L0;} }
+ else if (c=='n') { if (s.charAt(0)=='i') {id=Id_in; break L0;} }
+ else if (c=='o') { if (s.charAt(0)=='d') {id=Id_do; break L0;} }
+ break L;
+ case 3: switch (s.charAt(0)) {
+ case 'f': if (s.charAt(2)=='r' && s.charAt(1)=='o') {id=Id_for; break L0;} break L;
+ case 'i': if (s.charAt(2)=='t' && s.charAt(1)=='n') {id=Id_int; break L0;} break L;
+ case 'n': if (s.charAt(2)=='w' && s.charAt(1)=='e') {id=Id_new; break L0;} break L;
+ case 't': if (s.charAt(2)=='y' && s.charAt(1)=='r') {id=Id_try; break L0;} break L;
+ case 'v': if (s.charAt(2)=='r' && s.charAt(1)=='a') {id=Id_var; break L0;} break L;
+ } break L;
+ case 4: switch (s.charAt(0)) {
+ case 'b': X="byte";id=Id_byte; break L;
+ case 'c': c=s.charAt(3);
+ if (c=='e') { if (s.charAt(2)=='s' && s.charAt(1)=='a') {id=Id_case; break L0;} }
+ else if (c=='r') { if (s.charAt(2)=='a' && s.charAt(1)=='h') {id=Id_char; break L0;} }
+ break L;
+ case 'e': c=s.charAt(3);
+ if (c=='e') { if (s.charAt(2)=='s' && s.charAt(1)=='l') {id=Id_else; break L0;} }
+ else if (c=='m') { if (s.charAt(2)=='u' && s.charAt(1)=='n') {id=Id_enum; break L0;} }
+ break L;
+ case 'g': X="goto";id=Id_goto; break L;
+ case 'l': X="long";id=Id_long; break L;
+ case 'n': X="null";id=Id_null; break L;
+ case 't': c=s.charAt(3);
+ if (c=='e') { if (s.charAt(2)=='u' && s.charAt(1)=='r') {id=Id_true; break L0;} }
+ else if (c=='s') { if (s.charAt(2)=='i' && s.charAt(1)=='h') {id=Id_this; break L0;} }
+ break L;
+ case 'v': X="void";id=Id_void; break L;
+ case 'w': X="with";id=Id_with; break L;
+ } break L;
+ case 5: switch (s.charAt(2)) {
+ case 'a': X="class";id=Id_class; break L;
+ case 'e': X="break";id=Id_break; break L;
+ case 'i': X="while";id=Id_while; break L;
+ case 'l': X="false";id=Id_false; break L;
+ case 'n': c=s.charAt(0);
+ if (c=='c') { X="const";id=Id_const; }
+ else if (c=='f') { X="final";id=Id_final; }
+ break L;
+ case 'o': c=s.charAt(0);
+ if (c=='f') { X="float";id=Id_float; }
+ else if (c=='s') { X="short";id=Id_short; }
+ break L;
+ case 'p': X="super";id=Id_super; break L;
+ case 'r': X="throw";id=Id_throw; break L;
+ case 't': X="catch";id=Id_catch; break L;
+ } break L;
+ case 6: switch (s.charAt(1)) {
+ case 'a': X="native";id=Id_native; break L;
+ case 'e': c=s.charAt(0);
+ if (c=='d') { X="delete";id=Id_delete; }
+ else if (c=='r') { X="return";id=Id_return; }
+ break L;
+ case 'h': X="throws";id=Id_throws; break L;
+ case 'm': X="import";id=Id_import; break L;
+ case 'o': X="double";id=Id_double; break L;
+ case 't': X="static";id=Id_static; break L;
+ case 'u': X="public";id=Id_public; break L;
+ case 'w': X="switch";id=Id_switch; break L;
+ case 'x': X="export";id=Id_export; break L;
+ case 'y': X="typeof";id=Id_typeof; break L;
+ } break L;
+ case 7: switch (s.charAt(1)) {
+ case 'a': X="package";id=Id_package; break L;
+ case 'e': X="default";id=Id_default; break L;
+ case 'i': X="finally";id=Id_finally; break L;
+ case 'o': X="boolean";id=Id_boolean; break L;
+ case 'r': X="private";id=Id_private; break L;
+ case 'x': X="extends";id=Id_extends; break L;
+ } break L;
+ case 8: switch (s.charAt(0)) {
+ case 'a': X="abstract";id=Id_abstract; break L;
+ case 'c': X="continue";id=Id_continue; break L;
+ case 'd': X="debugger";id=Id_debugger; break L;
+ case 'f': X="function";id=Id_function; break L;
+ case 'v': X="volatile";id=Id_volatile; break L;
+ } break L;
+ case 9: c=s.charAt(0);
+ if (c=='i') { X="interface";id=Id_interface; }
+ else if (c=='p') { X="protected";id=Id_protected; }
+ else if (c=='t') { X="transient";id=Id_transient; }
+ break L;
+ case 10: c=s.charAt(1);
+ if (c=='m') { X="implements";id=Id_implements; }
+ else if (c=='n') { X="instanceof";id=Id_instanceof; }
+ break L;
+ case 12: X="synchronized";id=Id_synchronized; break L;
+ }
+ if (X!=null && X!=s && !X.equals(s)) id = 0;
+ }
+// #/generated#
+// #/string_id_map#
+ if (id == 0) { return Token.EOF; }
+ return id & 0xff;
+ }
+
+ final int getLineno() { return lineno; }
+
+ final String getString() { return string; }
+
+ final double getNumber() { return number; }
+
+ final boolean eof() { return hitEOF; }
+
+ final int getToken() throws IOException
+ {
+ int c;
+
+ retry:
+ for (;;) {
+ // Eat whitespace, possibly sensitive to newlines.
+ for (;;) {
+ c = getChar();
+ if (c == EOF_CHAR) {
+ return Token.EOF;
+ } else if (c == '\n') {
+ dirtyLine = false;
+ return Token.EOL;
+ } else if (!isJSSpace(c)) {
+ if (c != '-') {
+ dirtyLine = true;
+ }
+ break;
+ }
+ }
+
+ if (c == '@') return Token.XMLATTR;
+
+ // identifier/keyword/instanceof?
+ // watch out for starting with a <backslash>
+ boolean identifierStart;
+ boolean isUnicodeEscapeStart = false;
+ if (c == '\\') {
+ c = getChar();
+ if (c == 'u') {
+ identifierStart = true;
+ isUnicodeEscapeStart = true;
+ stringBufferTop = 0;
+ } else {
+ identifierStart = false;
+ ungetChar(c);
+ c = '\\';
+ }
+ } else {
+ identifierStart = Character.isJavaIdentifierStart((char)c);
+ if (identifierStart) {
+ stringBufferTop = 0;
+ addToString(c);
+ }
+ }
+
+ if (identifierStart) {
+ boolean containsEscape = isUnicodeEscapeStart;
+ for (;;) {
+ if (isUnicodeEscapeStart) {
+ // strictly speaking we should probably push-back
+ // all the bad characters if the <backslash>uXXXX
+ // sequence is malformed. But since there isn't a
+ // correct context(is there?) for a bad Unicode
+ // escape sequence in an identifier, we can report
+ // an error here.
+ int escapeVal = 0;
+ for (int i = 0; i != 4; ++i) {
+ c = getChar();
+ escapeVal = Kit.xDigitToInt(c, escapeVal);
+ // Next check takes care about c < 0 and bad escape
+ if (escapeVal < 0) { break; }
+ }
+ if (escapeVal < 0) {
+ parser.addError("msg.invalid.escape");
+ return Token.ERROR;
+ }
+ addToString(escapeVal);
+ isUnicodeEscapeStart = false;
+ } else {
+ c = getChar();
+ if (c == '\\') {
+ c = getChar();
+ if (c == 'u') {
+ isUnicodeEscapeStart = true;
+ containsEscape = true;
+ } else {
+ parser.addError("msg.illegal.character");
+ return Token.ERROR;
+ }
+ } else {
+ if (c == EOF_CHAR
+ || !Character.isJavaIdentifierPart((char)c))
+ {
+ break;
+ }
+ addToString(c);
+ }
+ }
+ }
+ ungetChar(c);
+
+ String str = getStringFromBuffer();
+ if (!containsEscape) {
+ // OPT we shouldn't have to make a string (object!) to
+ // check if it's a keyword.
+
+ // Return the corresponding token if it's a keyword
+ int result = stringToKeyword(str);
+ if (result != Token.EOF) {
+ if (result != Token.RESERVED) {
+ return result;
+ } else if (!parser.compilerEnv.
+ isReservedKeywordAsIdentifier())
+ {
+ return result;
+ } else {
+ // If implementation permits to use future reserved
+ // keywords in violation with the EcmaScript,
+ // treat it as name but issue warning
+ parser.addWarning("msg.reserved.keyword", str);
+ }
+ }
+ }
+ this.string = (String)allStrings.intern(str);
+ return Token.NAME;
+ }
+
+ // is it a number?
+ if (isDigit(c) || (c == '.' && isDigit(peekChar()))) {
+
+ stringBufferTop = 0;
+ int base = 10;
+
+ if (c == '0') {
+ c = getChar();
+ if (c == 'x' || c == 'X') {
+ base = 16;
+ c = getChar();
+ } else if (isDigit(c)) {
+ base = 8;
+ } else {
+ addToString('0');
+ }
+ }
+
+ if (base == 16) {
+ while (0 <= Kit.xDigitToInt(c, 0)) {
+ addToString(c);
+ c = getChar();
+ }
+ } else {
+ while ('0' <= c && c <= '9') {
+ /*
+ * We permit 08 and 09 as decimal numbers, which
+ * makes our behavior a superset of the ECMA
+ * numeric grammar. We might not always be so
+ * permissive, so we warn about it.
+ */
+ if (base == 8 && c >= '8') {
+ parser.addWarning("msg.bad.octal.literal",
+ c == '8' ? "8" : "9");
+ base = 10;
+ }
+ addToString(c);
+ c = getChar();
+ }
+ }
+
+ boolean isInteger = true;
+
+ if (base == 10 && (c == '.' || c == 'e' || c == 'E')) {
+ isInteger = false;
+ if (c == '.') {
+ do {
+ addToString(c);
+ c = getChar();
+ } while (isDigit(c));
+ }
+ if (c == 'e' || c == 'E') {
+ addToString(c);
+ c = getChar();
+ if (c == '+' || c == '-') {
+ addToString(c);
+ c = getChar();
+ }
+ if (!isDigit(c)) {
+ parser.addError("msg.missing.exponent");
+ return Token.ERROR;
+ }
+ do {
+ addToString(c);
+ c = getChar();
+ } while (isDigit(c));
+ }
+ }
+ ungetChar(c);
+ String numString = getStringFromBuffer();
+
+ double dval;
+ if (base == 10 && !isInteger) {
+ try {
+ // Use Java conversion to number from string...
+ dval = Double.valueOf(numString).doubleValue();
+ }
+ catch (NumberFormatException ex) {
+ parser.addError("msg.caught.nfe");
+ return Token.ERROR;
+ }
+ } else {
+ dval = ScriptRuntime.stringToNumber(numString, 0, base);
+ }
+
+ this.number = dval;
+ return Token.NUMBER;
+ }
+
+ // is it a string?
+ if (c == '"' || c == '\'') {
+ // We attempt to accumulate a string the fast way, by
+ // building it directly out of the reader. But if there
+ // are any escaped characters in the string, we revert to
+ // building it out of a StringBuffer.
+
+ int quoteChar = c;
+ stringBufferTop = 0;
+
+ c = getChar();
+ strLoop: while (c != quoteChar) {
+ if (c == '\n' || c == EOF_CHAR) {
+ ungetChar(c);
+ parser.addError("msg.unterminated.string.lit");
+ return Token.ERROR;
+ }
+
+ if (c == '\\') {
+ // We've hit an escaped character
+ int escapeVal;
+
+ c = getChar();
+ switch (c) {
+ case 'b': c = '\b'; break;
+ case 'f': c = '\f'; break;
+ case 'n': c = '\n'; break;
+ case 'r': c = '\r'; break;
+ case 't': c = '\t'; break;
+
+ // \v a late addition to the ECMA spec,
+ // it is not in Java, so use 0xb
+ case 'v': c = 0xb; break;
+
+ case 'u':
+ // Get 4 hex digits; if the u escape is not
+ // followed by 4 hex digits, use 'u' + the
+ // literal character sequence that follows.
+ int escapeStart = stringBufferTop;
+ addToString('u');
+ escapeVal = 0;
+ for (int i = 0; i != 4; ++i) {
+ c = getChar();
+ escapeVal = Kit.xDigitToInt(c, escapeVal);
+ if (escapeVal < 0) {
+ continue strLoop;
+ }
+ addToString(c);
+ }
+ // prepare for replace of stored 'u' sequence
+ // by escape value
+ stringBufferTop = escapeStart;
+ c = escapeVal;
+ break;
+ case 'x':
+ // Get 2 hex digits, defaulting to 'x'+literal
+ // sequence, as above.
+ c = getChar();
+ escapeVal = Kit.xDigitToInt(c, 0);
+ if (escapeVal < 0) {
+ addToString('x');
+ continue strLoop;
+ } else {
+ int c1 = c;
+ c = getChar();
+ escapeVal = Kit.xDigitToInt(c, escapeVal);
+ if (escapeVal < 0) {
+ addToString('x');
+ addToString(c1);
+ continue strLoop;
+ } else {
+ // got 2 hex digits
+ c = escapeVal;
+ }
+ }
+ break;
+
+ case '\n':
+ // Remove line terminator after escape to follow
+ // SpiderMonkey and C/C++
+ c = getChar();
+ continue strLoop;
+
+ default:
+ if ('0' <= c && c < '8') {
+ int val = c - '0';
+ c = getChar();
+ if ('0' <= c && c < '8') {
+ val = 8 * val + c - '0';
+ c = getChar();
+ if ('0' <= c && c < '8' && val <= 037) {
+ // c is 3rd char of octal sequence only
+ // if the resulting val <= 0377
+ val = 8 * val + c - '0';
+ c = getChar();
+ }
+ }
+ ungetChar(c);
+ c = val;
+ }
+ }
+ }
+ addToString(c);
+ c = getChar();
+ }
+
+ String str = getStringFromBuffer();
+ this.string = (String)allStrings.intern(str);
+ return Token.STRING;
+ }
+
+ switch (c) {
+ case ';': return Token.SEMI;
+ case '[': return Token.LB;
+ case ']': return Token.RB;
+ case '{': return Token.LC;
+ case '}': return Token.RC;
+ case '(': return Token.LP;
+ case ')': return Token.RP;
+ case ',': return Token.COMMA;
+ case '?': return Token.HOOK;
+ case ':':
+ if (matchChar(':')) {
+ return Token.COLONCOLON;
+ } else {
+ return Token.COLON;
+ }
+ case '.':
+ if (matchChar('.')) {
+ return Token.DOTDOT;
+ } else if (matchChar('(')) {
+ return Token.DOTQUERY;
+ } else {
+ return Token.DOT;
+ }
+
+ case '|':
+ if (matchChar('|')) {
+ return Token.OR;
+ } else if (matchChar('=')) {
+ return Token.ASSIGN_BITOR;
+ } else {
+ return Token.BITOR;
+ }
+
+ case '^':
+ if (matchChar('=')) {
+ return Token.ASSIGN_BITXOR;
+ } else {
+ return Token.BITXOR;
+ }
+
+ case '&':
+ if (matchChar('&')) {
+ return Token.AND;
+ } else if (matchChar('=')) {
+ return Token.ASSIGN_BITAND;
+ } else {
+ return Token.BITAND;
+ }
+
+ case '=':
+ if (matchChar('=')) {
+ if (matchChar('='))
+ return Token.SHEQ;
+ else
+ return Token.EQ;
+ } else {
+ return Token.ASSIGN;
+ }
+
+ case '!':
+ if (matchChar('=')) {
+ if (matchChar('='))
+ return Token.SHNE;
+ else
+ return Token.NE;
+ } else {
+ return Token.NOT;
+ }
+
+ case '<':
+ /* NB:treat HTML begin-comment as comment-till-eol */
+ if (matchChar('!')) {
+ if (matchChar('-')) {
+ if (matchChar('-')) {
+ skipLine();
+ continue retry;
+ }
+ ungetChar('-');
+ }
+ ungetChar('!');
+ }
+ if (matchChar('<')) {
+ if (matchChar('=')) {
+ return Token.ASSIGN_LSH;
+ } else {
+ return Token.LSH;
+ }
+ } else {
+ if (matchChar('=')) {
+ return Token.LE;
+ } else {
+ return Token.LT;
+ }
+ }
+
+ case '>':
+ if (matchChar('>')) {
+ if (matchChar('>')) {
+ if (matchChar('=')) {
+ return Token.ASSIGN_URSH;
+ } else {
+ return Token.URSH;
+ }
+ } else {
+ if (matchChar('=')) {
+ return Token.ASSIGN_RSH;
+ } else {
+ return Token.RSH;
+ }
+ }
+ } else {
+ if (matchChar('=')) {
+ return Token.GE;
+ } else {
+ return Token.GT;
+ }
+ }
+
+ case '*':
+ if (matchChar('=')) {
+ return Token.ASSIGN_MUL;
+ } else {
+ return Token.MUL;
+ }
+
+ case '/':
+ // is it a // comment?
+ if (matchChar('/')) {
+ skipLine();
+ continue retry;
+ }
+ if (matchChar('*')) {
+ boolean lookForSlash = false;
+ for (;;) {
+ c = getChar();
+ if (c == EOF_CHAR) {
+ parser.addError("msg.unterminated.comment");
+ return Token.ERROR;
+ } else if (c == '*') {
+ lookForSlash = true;
+ } else if (c == '/') {
+ if (lookForSlash) {
+ continue retry;
+ }
+ } else {
+ lookForSlash = false;
+ }
+ }
+ }
+
+ if (matchChar('=')) {
+ return Token.ASSIGN_DIV;
+ } else {
+ return Token.DIV;
+ }
+
+ case '%':
+ if (matchChar('=')) {
+ return Token.ASSIGN_MOD;
+ } else {
+ return Token.MOD;
+ }
+
+ case '~':
+ return Token.BITNOT;
+
+ case '+':
+ if (matchChar('=')) {
+ return Token.ASSIGN_ADD;
+ } else if (matchChar('+')) {
+ return Token.INC;
+ } else {
+ return Token.ADD;
+ }
+
+ case '-':
+ if (matchChar('=')) {
+ c = Token.ASSIGN_SUB;
+ } else if (matchChar('-')) {
+ if (!dirtyLine) {
+ // treat HTML end-comment after possible whitespace
+ // after line start as comment-utill-eol
+ if (matchChar('>')) {
+ skipLine();
+ continue retry;
+ }
+ }
+ c = Token.DEC;
+ } else {
+ c = Token.SUB;
+ }
+ dirtyLine = true;
+ return c;
+
+ default:
+ parser.addError("msg.illegal.character");
+ return Token.ERROR;
+ }
+ }
+ }
+
+ private static boolean isAlpha(int c)
+ {
+ // Use 'Z' < 'a'
+ if (c <= 'Z') {
+ return 'A' <= c;
+ } else {
+ return 'a' <= c && c <= 'z';
+ }
+ }
+
+ static boolean isDigit(int c)
+ {
+ return '0' <= c && c <= '9';
+ }
+
+ /* As defined in ECMA. jsscan.c uses C isspace() (which allows
+ * \v, I think.) note that code in getChar() implicitly accepts
+ * '\r' == \u000D as well.
+ */
+ static boolean isJSSpace(int c)
+ {
+ if (c <= 127) {
+ return c == 0x20 || c == 0x9 || c == 0xC || c == 0xB;
+ } else {
+ return c == 0xA0
+ || Character.getType((char)c) == Character.SPACE_SEPARATOR;
+ }
+ }
+
+ private static boolean isJSFormatChar(int c)
+ {
+ return c > 127 && Character.getType((char)c) == Character.FORMAT;
+ }
+
+ /**
+ * Parser calls the method when it gets / or /= in literal context.
+ */
+ void readRegExp(int startToken)
+ throws IOException
+ {
+ stringBufferTop = 0;
+ if (startToken == Token.ASSIGN_DIV) {
+ // Miss-scanned /=
+ addToString('=');
+ } else {
+ if (startToken != Token.DIV) Kit.codeBug();
+ }
+
+ int c;
+ while ((c = getChar()) != '/') {
+ if (c == '\n' || c == EOF_CHAR) {
+ ungetChar(c);
+ throw parser.reportError("msg.unterminated.re.lit");
+ }
+ if (c == '\\') {
+ addToString(c);
+ c = getChar();
+ }
+
+ addToString(c);
+ }
+ int reEnd = stringBufferTop;
+
+ while (true) {
+ if (matchChar('g'))
+ addToString('g');
+ else if (matchChar('i'))
+ addToString('i');
+ else if (matchChar('m'))
+ addToString('m');
+ else
+ break;
+ }
+
+ if (isAlpha(peekChar())) {
+ throw parser.reportError("msg.invalid.re.flag");
+ }
+
+ this.string = new String(stringBuffer, 0, reEnd);
+ this.regExpFlags = new String(stringBuffer, reEnd,
+ stringBufferTop - reEnd);
+ }
+
+ boolean isXMLAttribute()
+ {
+ return xmlIsAttribute;
+ }
+
+ int getFirstXMLToken() throws IOException
+ {
+ xmlOpenTagsCount = 0;
+ xmlIsAttribute = false;
+ xmlIsTagContent = false;
+ ungetChar('<');
+ return getNextXMLToken();
+ }
+
+ int getNextXMLToken() throws IOException
+ {
+ stringBufferTop = 0; // remember the XML
+
+ for (int c = getChar(); c != EOF_CHAR; c = getChar()) {
+ if (xmlIsTagContent) {
+ switch (c) {
+ case '>':
+ addToString(c);
+ xmlIsTagContent = false;
+ xmlIsAttribute = false;
+ break;
+ case '/':
+ addToString(c);
+ if (peekChar() == '>') {
+ c = getChar();
+ addToString(c);
+ xmlIsTagContent = false;
+ xmlOpenTagsCount--;
+ }
+ break;
+ case '{':
+ ungetChar(c);
+ this.string = getStringFromBuffer();
+ return Token.XML;
+ case '\'':
+ case '"':
+ addToString(c);
+ if (!readQuotedString(c)) return Token.ERROR;
+ break;
+ case '=':
+ addToString(c);
+ xmlIsAttribute = true;
+ break;
+ case ' ':
+ case '\t':
+ case '\r':
+ case '\n':
+ addToString(c);
+ break;
+ default:
+ addToString(c);
+ xmlIsAttribute = false;
+ break;
+ }
+
+ if (!xmlIsTagContent && xmlOpenTagsCount == 0) {
+ this.string = getStringFromBuffer();
+ return Token.XMLEND;
+ }
+ } else {
+ switch (c) {
+ case '<':
+ addToString(c);
+ c = peekChar();
+ switch (c) {
+ case '!':
+ c = getChar(); // Skip !
+ addToString(c);
+ c = peekChar();
+ switch (c) {
+ case '-':
+ c = getChar(); // Skip -
+ addToString(c);
+ c = getChar();
+ if (c == '-') {
+ addToString(c);
+ if(!readXmlComment()) return Token.ERROR;
+ } else {
+ // throw away the string in progress
+ stringBufferTop = 0;
+ this.string = null;
+ parser.addError("msg.XML.bad.form");
+ return Token.ERROR;
+ }
+ break;
+ case '[':
+ c = getChar(); // Skip [
+ addToString(c);
+ if (getChar() == 'C' &&
+ getChar() == 'D' &&
+ getChar() == 'A' &&
+ getChar() == 'T' &&
+ getChar() == 'A' &&
+ getChar() == '[')
+ {
+ addToString('C');
+ addToString('D');
+ addToString('A');
+ addToString('T');
+ addToString('A');
+ addToString('[');
+ if (!readCDATA()) return Token.ERROR;
+
+ } else {
+ // throw away the string in progress
+ stringBufferTop = 0;
+ this.string = null;
+ parser.addError("msg.XML.bad.form");
+ return Token.ERROR;
+ }
+ break;
+ default:
+ if(!readEntity()) return Token.ERROR;
+ break;
+ }
+ break;
+ case '?':
+ c = getChar(); // Skip ?
+ addToString(c);
+ if (!readPI()) return Token.ERROR;
+ break;
+ case '/':
+ // End tag
+ c = getChar(); // Skip /
+ addToString(c);
+ if (xmlOpenTagsCount == 0) {
+ // throw away the string in progress
+ stringBufferTop = 0;
+ this.string = null;
+ parser.addError("msg.XML.bad.form");
+ return Token.ERROR;
+ }
+ xmlIsTagContent = true;
+ xmlOpenTagsCount--;
+ break;
+ default:
+ // Start tag
+ xmlIsTagContent = true;
+ xmlOpenTagsCount++;
+ break;
+ }
+ break;
+ case '{':
+ ungetChar(c);
+ this.string = getStringFromBuffer();
+ return Token.XML;
+ default:
+ addToString(c);
+ break;
+ }
+ }
+ }
+
+ stringBufferTop = 0; // throw away the string in progress
+ this.string = null;
+ parser.addError("msg.XML.bad.form");
+ return Token.ERROR;
+ }
+
+ /**
+ *
+ */
+ private boolean readQuotedString(int quote) throws IOException
+ {
+ for (int c = getChar(); c != EOF_CHAR; c = getChar()) {
+ addToString(c);
+ if (c == quote) return true;
+ }
+
+ stringBufferTop = 0; // throw away the string in progress
+ this.string = null;
+ parser.addError("msg.XML.bad.form");
+ return false;
+ }
+
+ /**
+ *
+ */
+ private boolean readXmlComment() throws IOException
+ {
+ for (int c = getChar(); c != EOF_CHAR;) {
+ addToString(c);
+ if (c == '-' && peekChar() == '-') {
+ c = getChar();
+ addToString(c);
+ if (peekChar() == '>') {
+ c = getChar(); // Skip >
+ addToString(c);
+ return true;
+ } else {
+ continue;
+ }
+ }
+ c = getChar();
+ }
+
+ stringBufferTop = 0; // throw away the string in progress
+ this.string = null;
+ parser.addError("msg.XML.bad.form");
+ return false;
+ }
+
+ /**
+ *
+ */
+ private boolean readCDATA() throws IOException
+ {
+ for (int c = getChar(); c != EOF_CHAR;) {
+ addToString(c);
+ if (c == ']' && peekChar() == ']') {
+ c = getChar();
+ addToString(c);
+ if (peekChar() == '>') {
+ c = getChar(); // Skip >
+ addToString(c);
+ return true;
+ } else {
+ continue;
+ }
+ }
+ c = getChar();
+ }
+
+ stringBufferTop = 0; // throw away the string in progress
+ this.string = null;
+ parser.addError("msg.XML.bad.form");
+ return false;
+ }
+
+ /**
+ *
+ */
+ private boolean readEntity() throws IOException
+ {
+ int declTags = 1;
+ for (int c = getChar(); c != EOF_CHAR; c = getChar()) {
+ addToString(c);
+ switch (c) {
+ case '<':
+ declTags++;
+ break;
+ case '>':
+ declTags--;
+ if (declTags == 0) return true;
+ break;
+ }
+ }
+
+ stringBufferTop = 0; // throw away the string in progress
+ this.string = null;
+ parser.addError("msg.XML.bad.form");
+ return false;
+ }
+
+ /**
+ *
+ */
+ private boolean readPI() throws IOException
+ {
+ for (int c = getChar(); c != EOF_CHAR; c = getChar()) {
+ addToString(c);
+ if (c == '?' && peekChar() == '>') {
+ c = getChar(); // Skip >
+ addToString(c);
+ return true;
+ }
+ }
+
+ stringBufferTop = 0; // throw away the string in progress
+ this.string = null;
+ parser.addError("msg.XML.bad.form");
+ return false;
+ }
+
+ private String getStringFromBuffer()
+ {
+ return new String(stringBuffer, 0, stringBufferTop);
+ }
+
+ private void addToString(int c)
+ {
+ int N = stringBufferTop;
+ if (N == stringBuffer.length) {
+ char[] tmp = new char[stringBuffer.length * 2];
+ System.arraycopy(stringBuffer, 0, tmp, 0, N);
+ stringBuffer = tmp;
+ }
+ stringBuffer[N] = (char)c;
+ stringBufferTop = N + 1;
+ }
+
+ private void ungetChar(int c)
+ {
+ // can not unread past across line boundary
+ if (ungetCursor != 0 && ungetBuffer[ungetCursor - 1] == '\n')
+ Kit.codeBug();
+ ungetBuffer[ungetCursor++] = c;
+ }
+
+ private boolean matchChar(int test) throws IOException
+ {
+ int c = getChar();
+ if (c == test) {
+ return true;
+ } else {
+ ungetChar(c);
+ return false;
+ }
+ }
+
+ private int peekChar() throws IOException
+ {
+ int c = getChar();
+ ungetChar(c);
+ return c;
+ }
+
+ private int getChar() throws IOException
+ {
+ if (ungetCursor != 0) {
+ return ungetBuffer[--ungetCursor];
+ }
+
+ for(;;) {
+ int c;
+ if (sourceString != null) {
+ if (sourceCursor == sourceEnd) {
+ hitEOF = true;
+ return EOF_CHAR;
+ }
+ c = sourceString.charAt(sourceCursor++);
+ } else {
+ if (sourceCursor == sourceEnd) {
+ if (!fillSourceBuffer()) {
+ hitEOF = true;
+ return EOF_CHAR;
+ }
+ }
+ c = sourceBuffer[sourceCursor++];
+ }
+
+ if (lineEndChar >= 0) {
+ if (lineEndChar == '\r' && c == '\n') {
+ lineEndChar = '\n';
+ continue;
+ }
+ lineEndChar = -1;
+ lineStart = sourceCursor - 1;
+ lineno++;
+ }
+
+ if (c <= 127) {
+ if (c == '\n' || c == '\r') {
+ lineEndChar = c;
+ c = '\n';
+ }
+ } else {
+ if (isJSFormatChar(c)) {
+ continue;
+ }
+ if (ScriptRuntime.isJSLineTerminator(c)) {
+ lineEndChar = c;
+ c = '\n';
+ }
+ }
+ return c;
+ }
+ }
+
+ private void skipLine() throws IOException
+ {
+ // skip to end of line
+ int c;
+ while ((c = getChar()) != EOF_CHAR && c != '\n') { }
+ ungetChar(c);
+ }
+
+ final int getOffset()
+ {
+ int n = sourceCursor - lineStart;
+ if (lineEndChar >= 0) { --n; }
+ return n;
+ }
+
+ final String getLine()
+ {
+ if (sourceString != null) {
+ // String case
+ int lineEnd = sourceCursor;
+ if (lineEndChar >= 0) {
+ --lineEnd;
+ } else {
+ for (; lineEnd != sourceEnd; ++lineEnd) {
+ int c = sourceString.charAt(lineEnd);
+ if (ScriptRuntime.isJSLineTerminator(c)) {
+ break;
+ }
+ }
+ }
+ return sourceString.substring(lineStart, lineEnd);
+ } else {
+ // Reader case
+ int lineLength = sourceCursor - lineStart;
+ if (lineEndChar >= 0) {
+ --lineLength;
+ } else {
+ // Read until the end of line
+ for (;; ++lineLength) {
+ int i = lineStart + lineLength;
+ if (i == sourceEnd) {
+ try {
+ if (!fillSourceBuffer()) { break; }
+ } catch (IOException ioe) {
+ // ignore it, we're already displaying an error...
+ break;
+ }
+ // i recalculuation as fillSourceBuffer can move saved
+ // line buffer and change lineStart
+ i = lineStart + lineLength;
+ }
+ int c = sourceBuffer[i];
+ if (ScriptRuntime.isJSLineTerminator(c)) {
+ break;
+ }
+ }
+ }
+ return new String(sourceBuffer, lineStart, lineLength);
+ }
+ }
+
+ private boolean fillSourceBuffer() throws IOException
+ {
+ if (sourceString != null) Kit.codeBug();
+ if (sourceEnd == sourceBuffer.length) {
+ if (lineStart != 0) {
+ System.arraycopy(sourceBuffer, lineStart, sourceBuffer, 0,
+ sourceEnd - lineStart);
+ sourceEnd -= lineStart;
+ sourceCursor -= lineStart;
+ lineStart = 0;
+ } else {
+ char[] tmp = new char[sourceBuffer.length * 2];
+ System.arraycopy(sourceBuffer, 0, tmp, 0, sourceEnd);
+ sourceBuffer = tmp;
+ }
+ }
+ int n = sourceReader.read(sourceBuffer, sourceEnd,
+ sourceBuffer.length - sourceEnd);
+ if (n < 0) {
+ return false;
+ }
+ sourceEnd += n;
+ return true;
+ }
+
+ // stuff other than whitespace since start of line
+ private boolean dirtyLine;
+
+ String regExpFlags;
+
+ // Set this to an inital non-null value so that the Parser has
+ // something to retrieve even if an error has occured and no
+ // string is found. Fosters one class of error, but saves lots of
+ // code.
+ private String string = "";
+ private double number;
+
+ private char[] stringBuffer = new char[128];
+ private int stringBufferTop;
+ private ObjToIntMap allStrings = new ObjToIntMap(50);
+
+ // Room to backtrace from to < on failed match of the last - in <!--
+ private final int[] ungetBuffer = new int[3];
+ private int ungetCursor;
+
+ private boolean hitEOF = false;
+
+ private int lineStart = 0;
+ private int lineno;
+ private int lineEndChar = -1;
+
+ private String sourceString;
+ private Reader sourceReader;
+ private char[] sourceBuffer;
+ private int sourceEnd;
+ private int sourceCursor;
+
+ // for xml tokenizer
+ private boolean xmlIsAttribute;
+ private boolean xmlIsTagContent;
+ private int xmlOpenTagsCount;
+
+ private Parser parser;
+}
diff --git a/site/.htaccess b/site/.htaccess
new file mode 100644
index 0000000..f23dbaf
--- /dev/null
+++ b/site/.htaccess
@@ -0,0 +1,5 @@
+<IfModule mod_rewrite.c>
+ RewriteEngine on
+ RewriteRule ^$ app/webroot/ [L]
+ RewriteRule (.*) app/webroot/$1 [L]
+</IfModule> \ No newline at end of file
diff --git a/site/app/.htaccess b/site/app/.htaccess
new file mode 100644
index 0000000..0ed8662
--- /dev/null
+++ b/site/app/.htaccess
@@ -0,0 +1,5 @@
+<IfModule mod_rewrite.c>
+ RewriteEngine on
+ RewriteRule ^$ webroot/ [L]
+ RewriteRule (.*) webroot/$1 [L]
+ </IfModule> \ No newline at end of file
diff --git a/site/app/app_controller.php b/site/app/app_controller.php
new file mode 100644
index 0000000..964e55b
--- /dev/null
+++ b/site/app/app_controller.php
@@ -0,0 +1,483 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Andrei Hajdukewycz <sancus@off.net> (Original Author)
+ * Frederic Wenzel <fwenzel@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+class AppController extends Controller
+{
+ var $components = array('Amo','SimpleAuth','SimpleAcl');
+ var $uses = array('Config', 'User', 'Group', 'Addontype', 'Platform');
+ var $view = 'Addons';
+
+ // allow named arguments, default on
+ var $namedArgs = true;
+ var $argSeparator = ":";
+ var $beforeFilter = array('checkCSRF', 'getNamedArgs', 'checkAdvancedSearch');
+
+ /**
+ * Used to determine the current security level for the class
+ *
+ * @var string 'high' or 'low'
+ */
+ var $securityLevel = 'medium';
+
+ /**
+ * array keys not to be sanitized when using publish()
+ */
+ var $dontsanitize = array('icondata', 'locale','locale_html', 'created',
+ 'modified', 'datestatuschanged', 'DateLastActive',
+ 'dateadded', 'filedata', 'thumbdata');
+
+ function __construct() {
+ parent::__construct();
+
+ if (DEV) {
+ // Not using && to help with APC caching, but I don't know
+ // if it actually helps. voodoo++
+ if (array_key_exists('X-Amo-Test', getallheaders())){
+ DATABASE_CONFIG::useTestConfig();
+ // In downloads_controller.test we check that the returned
+ // content matches a file on disk. If we're appending query
+ // logs and microtime to the page, those aren't going to match.
+ Configure::getInstance()->debug = 0;
+ define('NO_MICROTIME', 1);
+ }
+ }
+ $this->setSecurityLevel($this->securityLevel);
+ }
+
+ function startup() {
+ $this->SimpleAuth->startup($this);
+ $this->SimpleAcl->startup($this);
+ }
+
+ /**
+ * Enables sandbox access when requested, via the status named argument.
+ * add "_checkSandbox" to beforeFilter array to enable sandbox context
+ * in a controller
+ */
+
+ function _checkSandbox() {
+
+ // The current status according the to the controller.
+ // In places, this is pulled and used in IN() clauses,
+ // so this should always be an array, if though it's annoying.
+ $this->status = array(STATUS_PUBLIC);
+
+ // Whether or not a user has agreed to the sandbox terms,
+ // according to their session data. Default is false.
+ $this->sandboxAccess = false;
+
+ if ($this->Session->check('User')) {
+ $sessionuser = $this->Session->read('User');
+
+ if (isset($sessionuser['sandboxshown']) && $sessionuser['sandboxshown'] == 1) {
+ $this->sandboxAccess = true;
+ }
+ }
+
+ if (isset($this->namedArgs['status']) && $this->namedArgs['status'] == STATUS_SANDBOX) {
+ if (!$this->Session->check('User')) {
+ $target_url = str_replace(LANG . '/' . APP_SHORTNAME . '/','',$this->params['url']['url']);
+ $this->redirect('/users/login?to=' . urlencode($target_url) . "&m=2");
+ return;
+ }
+ if ($this->sandboxAccess)
+ $this->status = array(STATUS_SANDBOX, STATUS_PENDING, STATUS_NOMINATED);
+ }
+
+ // This is either PUBLIC or SANDBOX and is used for view switching.
+ // Since morgamic is a jerk we have to check the status array.
+ if (in_array(STATUS_SANDBOX, $this->status)) {
+ $this->set('addonStatus', STATUS_SANDBOX);
+ } else {
+ $this->set('addonStatus', STATUS_PUBLIC);
+ }
+
+ // This is a boolean for our controllers.
+ $this->set('sandboxAccess', $this->sandboxAccess);
+ }
+
+ /**
+ * Checks for 'advancedsearch=true' in url to show advanced search (non-js fallback)
+ */
+ function checkAdvancedSearch() {
+ $advancedSearch = false;
+
+ if(isset($this->params['url']['advancedsearch']) && $this->params['url']['advancedsearch'] == 1) {
+ $advancedSearch = true;
+ }
+
+ $this->set('advancedSearch', $advancedSearch);
+ return true;
+ }
+
+ /**
+ * locale-aware redirect function
+ */
+ function redirect($url, $status = null, $addLocale = true, $addApp = true) {
+ $oldBase = $this->base;
+ if ($addLocale) $this->base = $this->_getLocaleBase();
+ if ($addApp) $this->base .= '/' . APP_SHORTNAME;
+
+ $ret = parent::redirect($url, $status);
+
+ $this->base = $oldBase;
+ return $ret;
+ }
+
+ /**
+ * locale-aware flash function
+ */
+ function flash($message, $url, $pause = null, $addLocale = true, $addApp = true) {
+ $oldBase = $this->base;
+ if ($addLocale) $this->base = $this->_getLocaleBase();
+ if ($addApp) $this->base .= '/' . APP_SHORTNAME;
+
+ $ret = parent::flash($message, $url, $pause);
+
+ $this->base = $oldBase;
+ return $ret;
+ }
+
+ /**
+ * locale-aware url function
+ */
+ function url($url) {
+ if ($url[0] != '/') {
+ $url = '/'.$url;
+ }
+ return $this->base.'/'.LANG.'/'.APP_SHORTNAME.$url;
+ }
+
+ /**
+ * locale-aware referer
+ */
+ function referer($default = null, $local = false, $addLocale = true, $addApp = true) {
+ $oldRoot = $this->webroot;
+ if ($addLocale) $this->webroot = $this->_getLocaleWebRoot();
+ if ($addApp) $this->webroot .= '/' . APP_SHORTNAME;
+
+ $ret = parent::referer($default, $local);
+
+ $this->webroot = $oldRoot;
+ return $ret;
+ }
+
+ /**
+ * A callback function to populate the namedArgs array if activated
+ * This should be triggered in the beforeFilter
+ *
+ * method suggested in http://bakery.cakephp.org/articles/view/129
+ *
+ * @return TRUE always
+ */
+ function getNamedArgs() {
+ $doNamedArgs = $this->namedArgs;
+ $this->namedArgs = array();
+
+ if ($doNamedArgs) {
+ if (!empty($this->params['pass'])) {
+ foreach ($this->params['pass'] as $param) {
+ if (strpos($param, $this->argSeparator)) {
+ list($name, $val) = explode($this->argSeparator, $param, 2);
+ $this->namedArgs[$name] = $val;
+ }
+ }
+ }
+ }
+ //check for sandbox status in the url
+ if (!empty($this->params['url']['status']) && empty($this->namedArgs['status']))
+ $this->namedArgs['status'] = $this->params['url']['status'];
+
+ $this->Amo->clean($this->namedArgs);
+
+ return true;
+ }
+
+ /**
+ * checks to make sure POSTed data has a hidden field sessionCheck as
+ * defined in:
+ *
+ * @see AddonsHtmlHelper::hiddenSession
+ *
+ * this is used to guard against cross-site request forgeries. We don't
+ * rely on cake stuff as this had been causing session issues.
+ *
+ * This method should be added to any new controller whose $beforeFilter
+ * overrides the default one above to ensure CSRF detection is done.
+ *
+ * For posted data where a session is not yet established use the
+ * array $exceptionCSRF to explicitly create an array of allowed
+ * URLs which you do not want checkCSRF to apply to.
+ */
+ function checkCSRF() {
+ global $csrf_old_session_id;
+
+ if ($_SERVER['REQUEST_METHOD'] != 'POST') return;
+
+ if (isset($this->exceptionCSRF)) {
+ foreach ($this->exceptionCSRF as $exception) {
+ if (stristr($_SERVER['REQUEST_URI'], $exception))
+ return;
+ }
+ }
+ $sessionuser = $this->Session->read('User');
+ $id = $sessionuser['id'];
+
+ $current_epoch = (int)(time()/CAKE_SESSION_TIMEOUT);
+ // this is to mitigate against where a session starts at an epoch boundary:
+ $previous_epoch = $current_epoch - 1;
+
+ // if our ID was regenerated during session spin-up, we check against the previous value
+ // see bug 458763
+ if (!empty($csrf_old_session_id))
+ $session_id = $csrf_old_session_id;
+ else
+ $session_id = session_id();
+
+ $currentMd5 = md5($session_id.$id.$current_epoch);
+ $previousMd5 = md5($session_id.$id.$previous_epoch);
+
+ if (!isset($_POST['sessionCheck']) ||
+ ($_POST['sessionCheck'] != $currentMd5 && $_POST['sessionCheck'] != $previousMd5)) {
+
+ header('HTTP/1.1 400 Bad Request');
+ $this->flash( _('error_formerrors'), '/' , 3); //error string is a little non-informative
+ exit();
+ }
+ }
+
+ /**
+ * get $this->base with locale included
+ */
+ function _getLocaleBase() {
+ $base = $this->base;
+ $base .= '/'.LANG;
+ return $base;
+ }
+
+ /**
+ * get $this->webroot with locale included
+ */
+ function _getLocaleWebRoot() {
+ $webroot = $this->webroot;
+ $webroot .= LANG.'/'; // not the trailing slash, as opposed to base
+ return $webroot;
+ }
+
+ function setLayoutForFormat($default = 'mozilla') {
+ if (array_key_exists('format', $this->namedArgs) &&
+ $this->namedArgs['format'] == 'rss') {
+ $this->layout = 'rss';
+ } else {
+ $this->layout = $default;
+ }
+ return $this->layout;
+ }
+
+ function disableCache() {
+ header('Cache-Control: no-store, must-revalidate, post-check=0, pre-check=0, private, max-age=0');
+ header('Pragma: private');
+ }
+
+ function forceCache() {
+ header('Cache-Control: public, max-age=' . HOUR);
+ header('Last-modified: ' . gmdate("D, j M Y H:i:s", time()) . " GMT");
+ header('Expires: ' . gmdate("D, j M Y H:i:s", time() + HOUR) . " GMT");
+ }
+
+ /**
+ * set() replacement that automatically santitzes (html-encodes) data
+ * and passes it to the view, to avoid repetitive and error-prone manual
+ * data sanitization in the view or controllers.
+ *
+ * @param string viewvar Variable name to be made available in the view
+ * @param mixed array or string data to be assigned to the variable name
+ * @param bool sanitizeme do data sanitization on the value before setting it?
+ * @param bool sanitizekeys clean array keys also?
+ * @return void
+ */
+ function publish($viewvar, $value, $sanitizeme = true, $sanitizekeys = false) {
+ if ($sanitizeme)
+ $this->_sanitizeArray($value, $sanitizekeys);
+ $this->set($viewvar, $value);
+ }
+
+ /**
+ * beforeRender callback. Sanitizes Cake's built-in data array containing
+ * form data, as it is automatically pushed back to the view unsanitized,
+ * circumventing the publish() function.
+ */
+ function beforeRender() {
+ $this->set('AmoTags', $this->Amo->getNavCategories());
+ $this->set('AmoVersions', $this->Amo->getApplicationVersions());
+ $this->set('AmoPlatforms', $this->Platform->getNames());
+ $this->set('AmoAddonTypes', $this->Addontype->getNames());
+
+ // User name for Welcome message
+ if ($session = $this->Session->read('User')) {
+ if (!empty($session['firstname']))
+ $welcomeName = $session['firstname'];
+ elseif (!empty($session['nickname']))
+ $welcomeName = $session['nickname'];
+ elseif (!empty($session['lastname']))
+ $welcomeName = $session['lastname'];
+ else
+ $welcomeName = '';
+
+ $this->publish('welcomeName', $welcomeName);
+ }
+
+ if (isset($this->data))
+ $this->_sanitizeArray($this->data, false);
+
+ return parent::beforeRender();
+ }
+
+ /**
+ * afterFilter callback.Called after every action is completed.
+ * Flushes object cache objects if necessary.
+ */
+ function afterFilter() {
+ if (!QUERY_CACHE || !is_object($this->Config->Cache))
+ return parent::afterFilter();
+
+ global $flush_lists;
+ if (!empty($flush_lists))
+ $this->Config->Cache->flushMarkedLists();
+
+ return parent::afterFilter();
+ }
+
+ /**
+ * html-encode an array, recursively
+ *
+ * @param mixed the data array (or string) to be html-encoded (by reference)
+ * @param bool clean the array keys as well?
+ * @return void
+ */
+ function _sanitizeArray(&$data, $cleankeys = false) {
+ global $sanitize_patterns;
+
+ if (is_array($data)) {
+ if (empty($data)) return; // prevents removal of empty arrays
+ // recurse through the array to get all values
+ foreach ($data as $key => $value) {
+ // @todo This if() statement is a temporary solution until we come up with
+ // a better way of excluding fields from being sanitized. This
+ // particular array keeps the translations locale strings from
+ // becoming entities
+ if (!in_array($key, $this->dontsanitize, true)) {
+ $this->_sanitizeArray($data[$key], $cleankeys);
+ }
+ }
+
+ // change the keys if necessary
+ if ($cleankeys) {
+ $keys = array_keys($data);
+ $this->_sanitizeArray($keys, false);
+ $data = array_combine($keys, array_values($data));
+ }
+
+ } elseif (is_string($data)) {
+ // encode the string
+ if (!empty($data)) {
+ $data = iconv('UTF-8', 'UTF-8//IGNORE', $data);
+ $data = htmlspecialchars($data, ENT_QUOTES, 'UTF-8');
+ $data = preg_replace($sanitize_patterns['patterns'], $sanitize_patterns['replacements'], $data);
+ }
+ }
+ // otherwise, we don't do anything (with ints or null etc.).
+ }
+
+ /**
+ * When CAKE_SECURITY is set to high, cake will automatically set
+ * session.referer_check to the current host. This is good for some of our
+ * pages, but not good for others. Since the Session component is
+ * automatically-included-no-matter-what, we can't override that, so we'll change
+ * the ini setting ourselves here. Default is high, but we'll override it in all
+ * the controllers that can use a more relaxed level.
+ *
+ * @param string level to set the security at, 'low' or 'high'
+ * @return void
+ */
+ function setSecurityLevel($level) {
+ if (defined('CAKE_SECURITY')) return;
+ switch ($level) {
+
+ case 'low':
+ define('CAKE_SECURITY', 'low');
+ break;
+
+ case 'medium':
+ define('CAKE_SECURITY', 'medium');
+ break;
+
+ case 'high':
+ default:
+ define('CAKE_SECURITY', 'high');
+ break;
+ }
+ }
+
+ /**
+ * Forces use of the shadowDb.
+ */
+ function forceShadowDb() {
+ foreach ($this->uses as $model) {
+ $this->{$model}->useDbConfig = 'shadow';
+ $this->setToShadow($this->{$model});
+ }
+ }
+
+ /**
+ * Sets a passed model to recursively use the shadow db.
+ */
+ function setToShadow(&$m) {
+ $m->useDbConfig = 'shadow';
+ if (is_array($m->__associations) and !empty($m->__associations)) {
+ foreach ($m->__associations as $association) {
+ foreach ($m->{$association} as $boundModel) {
+ $_n = $boundModel['className'];
+ $m->$_n->useDbConfig = 'shadow';
+ }
+ }
+ }
+ }
+}
+?>
diff --git a/site/app/app_model.php b/site/app/app_model.php
new file mode 100644
index 0000000..2b484f2
--- /dev/null
+++ b/site/app/app_model.php
@@ -0,0 +1,793 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Frederic Wenzel <fwenzel@mozilla.com> (Original Author)
+ * Justin Scott <fligtar@gmail.com>
+ * Mike Shaver <shaver@mozilla.org>
+ * Wil Clouser <clouserw@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+class AppModel extends Model
+{
+ var $translate = true; // run dl10n magic?
+ var $translationReplace = true; // replace translation indexes with translations
+ var $Cache; // holds the cache object
+ var $caching = QUERY_CACHE; // query caching enabled?
+ var $default_fields = null; // if none are selected, which fields will we fetch for this model? Null means "all".
+
+ /**
+ * Constructor
+ */
+ function __construct($id = false, $table = null, $ds = null) {
+ if ($this->caching) {
+ loadModel('Memcaching');
+ $this->Cache = new Memcaching();
+ }
+ return parent::__construct($id, $table, $ds);
+ }
+
+ /**
+ * This function will dynamically join translations into the current find operation,
+ * according to whichever fields it finds in $this->translated_fields.
+ * Please also see: http://wiki.mozilla.org/Update:Remora_Localization
+ *
+ * @param array queryData as defined in cake's Model->findAll()
+ * @return boolean will always return true
+ */
+ function beforeFind(&$queryData) {
+
+ // Tell the user they are bad because they don't have a model name.
+ if (!isset($this->name)) {
+ trigger_error('No model name was found for class: '.$get_class($this).'.', E_NOTICE);
+ }
+
+ if (!$this->translate) return true; // don't do anything if translation was deactivated
+
+ // This will build a finderQuery for the translations, and bind our current model to the translations table on the fly
+ if (isset($this->translated_fields) && is_array($this->translated_fields)) {
+
+ // Allow querying for a locale other than currently set
+ $lang = $this->getLang();
+
+ // fallback language is usually English. If we are selecting addons however,
+ // we fall back to what's defined for that addon.
+ if ($this->name == 'Addon') {
+ $fb_locale = '`Addon`.`defaultlocale`';
+ } else {
+ $fb_locale = "'en-US'";
+ }
+
+ // These parts are separated due to the way the query is built
+ $_query = '';
+ $_joins = array();
+
+ // Generate a field list just like Cake would do it, so that we
+ // know which translations to join in.
+ // If the user didn't give us a field list, we use the default field
+ // list set for this Model. We have to have cake
+ // generate the list for us now, because once we set a fields
+ // array, Cake won't select any other fields anymore than the ones
+ // we request.
+ if (!empty($queryData['fields']))
+ $_fields = $queryData['fields'];
+ else
+ $_fields = $this->default_fields;
+
+ // if it's a string only, wrap it into an array so all the
+ // following array magic works with it as well
+ if (is_string($_fields)) $_fields = array($_fields);
+ $db =& ConnectionManager::getDataSource($this->useDbConfig);
+ $_fields = $db->fields($this, $this->name, $_fields);
+
+ foreach ($this->translated_fields as $field) {
+ // only handle translatable fields that are actually selected
+ if (false === $pos = array_search("`{$this->name}`.`{$field}`", $_fields)) {
+ continue;
+ }
+
+ // for each translated field, we select the localized string,
+ // automatically falling back to en-US if nothing is found.
+ // We also fetch the locale, which will be the requested
+ // locale if found and en-US in case of fallback.
+ // naming is {fieldname} and {fieldname}_locale resp., which
+ // means, fallback is transparent.
+ $_select = "IFNULL(`tr_{$field}`.localized_string, `fb_{$field}`.localized_string) AS `{$field}`";
+
+ // replace the translation id with the translation unless explicitly opted out of
+ if ($this->translationReplace === false) {
+ // append the translation
+ $_fields[] = $_select;
+ } else {
+ // replace the translation index field
+ $_fields[$pos] = $_select;
+ }
+ // add the respective locale field to the end of the list
+ // (that is: the requested locale if the localized string
+ // is not null, otherwise the fallback locale)
+ $_fields[] = "IF(!ISNULL(`tr_{$field}`.localized_string), `tr_{$field}`.locale, `fb_{$field}`.locale) AS `{$field}_locale`";
+
+
+ // Our query design requires us to join on the same table repeatedly.
+ // Each join requires a different table name, so we're actually
+ // calling our tables the same things as the fields. We're also
+ // creating a string for the fallback versions (usually en-US).
+ // The requested locale has the prefix "tr_" (as "translation")
+ // and the fallback has the prefix "fb_".
+ $_joins[] = "LEFT JOIN translations AS `tr_{$field}` ON (`{$this->name}`.`{$field}` = `tr_{$field}`.id AND `tr_{$field}`.locale='{$lang}')";
+ $_joins[] = "LEFT JOIN translations AS `fb_{$field}` ON (`{$this->name}`.`{$field}` = `fb_{$field}`.id AND `fb_{$field}`.locale={$fb_locale})";
+ }
+
+ // if we didn't actually translate anything, return now.
+ if (empty($_joins)) return true;
+
+ // magically replace translated fields in query conditions by
+ // their more complicated counterparts, since MySQL apparently
+ // can't back-reference the "AS" names from the where clause.
+ $queryData['conditions'] = $this->_resolveTranslation($queryData['conditions']);
+ $queryData['order'] = $this->_resolveTranslation($queryData['order']);
+
+ // add our translation join magic to the query that's about to be executed
+ $queryData['joins'] = array_merge($queryData['joins'], $_joins);
+ $queryData['fields'] = $_fields;
+ }
+
+ // If this is false, the find won't execute.
+ // DO return $queryData here. Changing the array by reference up there
+ // does not imply PHP4 actually keeping it changed after we return. :(
+ return $queryData;
+ }
+
+ /**
+ * Take a condition or "order by" string and replace Translation.* by
+ * the fallback queries.
+ */
+ function _resolveTranslation($subject) {
+ $patterns = array(
+ '/`?Translation`?\.([\w_]+)_locale/', // query locales first, because they match the second pattern as well!
+ '/`?Translation`?\.([\w_]+)/'
+ );
+ $replacements = array(
+ 'IF(!ISNULL(`tr_\\1`.`localized_string`), `tr_\\1`.`locale`, `fb_\\1`.`locale`)',
+ 'IFNULL(`tr_\\1`.`localized_string`, `fb_\\1`.`localized_string`)'
+ );
+ if (is_array($subject)) {
+ foreach($subject as $key => $value) {
+ $new_key = $this->_resolveTranslation($key);
+ $new_value = $this->_resolveTranslation($value);
+ // set the new replaced value
+ $subject[$new_key] = $new_value;
+ // if the key changed, remove the old one
+ if ($key != $new_key) {
+ unset($subject[$key]);
+ }
+ }
+ return $subject;
+
+ } else {
+ return preg_replace($patterns, $replacements, $subject);
+ }
+ }
+
+ /**
+ * findAll(), checking for cached result objects.
+ */
+ function findAll($conditions = null, $fields = null, $order = null, $limit = null, $page = 1, $recursive = null) {
+ if ($this->caching && isset($this->name)) {
+ $cachekey = func_get_args();
+ $cachekey = $this->_cachekey('findAll:'.serialize($cachekey));
+ // if this was already cached, return it immediately
+ if (false !== $cached = $this->Cache->get($cachekey)) {
+ return $cached;
+ }
+ }
+
+ // else fetch the result normally
+ $result = parent::findAll($conditions, $fields, $order, $limit, $page, $recursive);
+ if ($this->caching && $result !== false) {
+ // cache it
+ $this->Cache->set($cachekey, $result);
+ }
+ // and return the result
+ return $result;
+ }
+
+ /**
+ * query(), checking for cached result objects (only on select queries,
+ * of course).
+ * Note: If you execute multiple queries in one line with a select query
+ * first, followed by some writing (insert or so), this *will* break.
+ * Don't do this.
+ */
+ function query($query = null, $use_shadow_database = false, $cakeCaching = true) {
+ if ($this->caching
+ && is_string($query)
+ && (0 === strpos(strtolower(ltrim($query)), 'select'))
+ && isset($this->name)) {
+
+ $cachekey = $this->_cachekey('query:'.$query);
+ if ($cached = $this->Cache->get($cachekey)) return $cached;
+ }
+
+ if ($use_shadow_database && !defined('SHADOW_DISABLED')) {
+ $this->useDbConfig = 'shadow';
+ $result = parent::query($query, $cakeCaching);
+ $this->useDbConfig = 'default';
+ } else {
+ $result = parent::query($query, $cakeCaching);
+ }
+
+ if ($this->caching && !empty($cachekey) && $result !== false) {
+ // cache it (if it's a select query, otherwise $cachekey
+ // would be empty)
+ $res = $this->Cache->set($cachekey, $result);
+ }
+ // and return the result
+ return $result;
+ }
+
+ /**
+ * generate a cache key for memcaching queries
+ * @param string additional key uniqueness factors (SQL query etc)
+ * @deprecated since 4.0.1
+ */
+ function _cachekey($key = '') {
+ // attach some unique factors to the key
+ $key .= $this->name.':';
+ $key .= LANG.':'.APP_ID.':';
+
+ // serialize the bound model names
+ $params = array('belongsTo', 'hasMany', 'hasAndBelongsToMany');
+ foreach ($params as $param)
+ $key .= serialize(array_keys($this->$param));
+
+ return MEMCACHE_PREFIX.md5($key);
+ }
+
+
+ /**
+ * Allowed querying for a locale other than currently set.
+ * Gets locale set by setLang()
+ * @return string $lang The language code to use
+ */
+ function getLang() {
+ if (!empty($this->useLang)) {
+ $lang = $this->useLang;
+ }
+ else {
+ $lang = LANG;
+ }
+
+ return $lang;
+ }
+
+ /**
+ * Sets current language to use in queries
+ * @param string $lang The language code to use
+ * @param object &$controller Reference to the controller
+ * @return boolean true
+ */
+ function setLang($lang, &$controller = null) {
+ $this->useLang = $lang;
+
+ if (isset($controller) && is_object($controller->Translation)) {
+ $controller->Translation->useLang = $lang;
+ }
+
+ return true;
+ }
+
+ /**
+ * extended field validation: allow arbitrary validation functions
+ * to use, add 'fieldname' => VALID_NOT_EMPTY or similar to $this->$validate,
+ * then add a method clean_fieldname($input) which in the case of invalidity
+ * calls $this->invalidate('fieldname') or amends $this->validationErrors.
+ *
+ * @param array $data data to be validated, $this->data by default
+ * @return array validationError, array() if none
+ */
+ function invalidFields($data=array()) {
+ if (!$this->beforeValidate()) {
+ return false;
+ }
+ parent::invalidFields($data);
+ if (empty($data)) {
+ $data = $this->data;
+ }
+ foreach (array_keys($this->validate) as $field) {
+ $func = 'clean_'.$field;
+ if (method_exists($this, $func) && isset($data[$this->name][$field])) {
+ call_user_func(array($this, $func), $data[$this->name][$field]);
+ }
+ }
+ return $this->validationErrors;
+ }
+
+ /**
+ * validation shortcut: maximum field length
+ */
+ function maxLength($field, $input, $max, $msg) {
+ if (strlen($input) > $max) {
+ $this->validationErrors[$field] = $msg;
+ }
+ }
+
+ var $hasMany_full = array();
+ var $hasAndBelongsToMany_full = array();
+ var $belongsTo_full = array();
+
+ function bindFully() {
+ $this->bindModel(array('hasMany' => $this->hasMany_full,
+ 'hasAndBelongsToMany' => $this->hasAndBelongsToMany_full,
+ 'belongsTo' => $this->belongsTo_full));
+ }
+
+ /**
+ * Index associations by model name.
+ *
+ * @return array $model => ($association, $definition)
+ */
+ function _bindings() {
+ $assoc = array('belongsTo', 'hasOne', 'hasMany', 'hasAndBelongsToMany');
+ $relations = array();
+ foreach ($assoc as $a) {
+ if (isset($this->$a)) {
+ foreach ($this->$a as $rel => $def) {
+ $relations[$rel] = array($a, $def);
+ }
+ }
+ }
+ return $relations;
+ }
+
+ /**
+ * Unbinds all models, then rebinds only the models passed as arguments.
+ * >>> $this->Addon->bindOnly('Users', 'Framlings')
+ * @param mixed [Model,...]
+ */
+ function bindOnly() {
+ // Make sure all the associations are available before introspection.
+ $this->__resetAssociations();
+ $bindings = $this->_bindings();
+ $this->unbindFully();
+
+ $models = func_get_args();
+ foreach ($models as $model) {
+ list($assoc, $def) = $bindings[$model];
+ $this->bindModel(array($assoc => array($model => $def)));
+ }
+ }
+
+ function unbindFully() {
+ $unbind = array();
+ foreach ($this->belongsTo as $model=>$info) {
+ $unbind['belongsTo'][] = $model;
+ }
+ foreach ($this->hasOne as $model=>$info) {
+ $unbind['hasOne'][] = $model;
+ }
+ foreach ($this->hasMany as $model=>$info) {
+ $unbind['hasMany'][] = $model;
+ }
+ foreach ($this->hasAndBelongsToMany as $model=>$info) {
+ $unbind['hasAndBelongsToMany'][] = $model;
+ }
+ $this->unbindModel($unbind);
+ }
+
+ /**
+ * Updates a table without requiring a primary key
+ * @param mixed $update Array of fields and values to update or the update string
+ * @param mixed $where Array of fields and values to match or the where string
+ * @param int $limit Limit of rows to affect
+ */
+ function update($update, $where, $limit = 0) {
+ //Return if no fields to update or if no where clause
+ if (empty($update) || empty($where)) {
+ return false;
+ }
+
+ $db =& ConnectionManager::getDataSource($this->useDbConfig);
+
+ //Create update string from array
+ if (is_array($update)) {
+ foreach ($update as $field => $value) {
+ if (empty($updateQry)) {
+ $updateQry = "`{$field}`='{$value}'";
+ }
+ else {
+ $updateQry .= ", `{$field}`='{$value}'";
+ }
+ }
+ }
+ elseif (is_string($update)) {
+ $updateQry = $update;
+ }
+
+ //Create where clause from array
+ if (is_array($where)) {
+ foreach ($where as $field => $value) {
+ if (empty($whereQry)) {
+ $whereQry = "`{$field}`='{$value}'";
+ }
+ else {
+ $whereQry .= " AND `{$field}`='{$value}'";
+ }
+ }
+ }
+ elseif (is_string($where)) {
+ $whereQry = $where;
+ }
+
+ $limitQry = empty($limit) ? '' : " LIMIT {$limit}";
+
+ return $db->execute("UPDATE ".$db->name($db->fullTableName($this))." SET {$updateQry} WHERE {$whereQry}{$limitQry}");
+ }
+
+ /**
+ * save dynamically localized strings to translation table
+ * before storing actual data
+ */
+ function beforeSave() {
+ if (!isset($this->translated_fields) || empty($this->translated_fields)) {
+ return true;
+ } else {
+ // we don't need this magic if none of the translated fields are to be saved
+ $_tr_fields_tobestored = array_intersect($this->translated_fields, array_keys($this->data[$this->name]));
+ if (empty($_tr_fields_tobestored)) return true;
+ }
+
+ // copy the data we intend to save
+ $data = $this->data;
+
+ // Allow querying for a locale other than currently set
+ $lang = $this->getLang();
+
+ // Make sure translation ids are returned
+ $this->translationReplace = false;
+
+ // start a transaction
+ $db =& ConnectionManager::getDataSource($this->useDbConfig);
+ $this->begin();
+
+ if ($this->exists()) {
+ // editing an existing record
+ $olddata = $this->findById($this->id);
+ } else {
+ $olddata = false;
+ }
+
+ // try to store all translated strings
+ $errors = false;
+ foreach ($this->translated_fields as $tr_field) {
+ if (!isset($data[$this->name][$tr_field])) continue;
+
+ // remove existing translation if empty
+ $_remove = (empty($data[$this->name][$tr_field]));
+
+ // see if there is a row for us to update, otherwise we'll insert a new one
+ if ($olddata && !empty($olddata[$this->name][$tr_field])) {
+ $_res = $db->execute("SELECT * FROM translations WHERE id = {$olddata[$this->name][$tr_field]} AND locale = '{$lang}';");
+ $_update = ($_res !== false && ($db->lastNumRows() > 0));
+ $_trans_id = $olddata[$this->name][$tr_field];
+ } else {
+ // if we would remove it anyway, don't make a new ID
+ if ($_remove) {
+ unset($data[$this->name][$tr_field]);
+ continue;
+ }
+
+ $_update = false;
+ // generate a new primary key id
+ $db->execute('UPDATE translations_seq SET id=LAST_INSERT_ID(id+1);');
+ $_res = $db->execute('SELECT LAST_INSERT_ID() AS id FROM translations_seq;');
+ if ($_row = $db->fetchRow()) {
+ $_trans_id = $_row[0]['id'];
+ } else {
+ $_trans_id = false;
+ }
+ }
+
+ // don't create a new but empty translation
+ if (!$_update && $_remove) {
+ unset($data[$this->name][$tr_field]);
+ continue;
+ }
+ if ($_update) {
+ // update an existing translation
+ if ($_remove) {
+ $_string = 'NULL';
+ } else {
+ $_string = "'{$data[$this->name][$tr_field]}'";
+ }
+ $_res = $db->execute("UPDATE translations SET "
+ ."localized_string = {$_string}, "
+ ."modified = NOW() "
+ ."WHERE id = {$_trans_id} AND locale = '{$lang}';");
+ $this->commit();
+ } else {
+ // insert a new translation
+ $sql = "INSERT INTO translations (id, locale, localized_string, created) VALUES "
+ ."({$_trans_id}, '{$lang}', '{$data[$this->name][$tr_field]}', NOW());";
+ $_res = $db->execute($sql);
+ }
+
+ // errors? don't go on
+ if ($_res === false) {
+ $errors = true;
+ break;
+ }
+
+ // replace localized string by localization id in data to be saved
+ $data[$this->name][$tr_field] = $_trans_id;
+ }
+
+ // return to default
+ $this->translationReplace = true;
+ // if something went wrong, roll back
+ if ($errors) {
+ $this->rollback();
+ return false;
+ } else {
+ $this->data = $data;
+ return true;
+ }
+ }
+
+ /**
+ * after saving successfully, commit the transaction
+ */
+ function afterSave() {
+ $db =& ConnectionManager::getDataSource($this->useDbConfig);
+ if ($db->_transactionStarted) {
+ return $this->commit();
+ } else {
+ return true;
+ }
+ }
+
+ /**
+ * start a transaction
+ */
+ function begin() {
+ $db =& ConnectionManager::getDataSource($this->useDbConfig);
+ if (!$db->_transactionStarted) {
+ if ($db->execute("START TRANSACTION") !== false) {
+ $db->_transactionStarted = true;
+ return true;
+ } else {
+ return false;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * rollback a transaction
+ */
+ function rollback() {
+ $db =& ConnectionManager::getDataSource($this->useDbConfig);
+ if ($db->_transactionStarted) {
+ $db->_transactionStarted = false;
+ return ($db->execute("ROLLBACK") !== false);
+ }
+ return false;
+ }
+
+ /**
+ * commit a transaction
+ */
+ function commit() {
+ $db =& ConnectionManager::getDataSource($this->useDbConfig);
+ if ($db->_transactionStarted) {
+ $db->_transactionStarted = false;
+ return ($db->execute("COMMIT") !== false);
+ }
+ return false;
+ }
+
+ /**
+ * Gets translations for all locales for the specific record and fields
+ * @param int $id the primary key to pull from
+ * @param array $fields optional array of fields to pull
+ * @param bool $includeIDs whether to return the translation ids as well
+ * @return array translations
+ */
+ function getAllTranslations($id, $fields = array(), $includeNULL = false, $returnIDs = false, $cache = false) {
+ // If no fields passed, use all localizable fields in this model
+ if (empty($fields) || !is_array($fields)) {
+ $fields = $this->translated_fields;
+ }
+
+ $translations = array();
+
+ // Pull the translation ids for the selected fields
+ $tableInfo = $this->query("SELECT ".implode($fields, ', ')." FROM {$this->table} AS {$this->name} WHERE {$this->name}.id={$id}", $cache, $cache);
+ if (!empty($tableInfo)) {
+ foreach ($tableInfo[0][$this->name] as $field => $translation_id) {
+ // If there's a translation id, add it to list to pull
+ if (!empty($translation_id)) {
+ $translation_ids[$field] = $translation_id;
+ }
+
+ $translations[$field] = array();
+ }
+ }
+
+ // Pull translations for all ids
+ if (!empty($translation_ids)) {
+ $where = $includeNULL ? '' : ' AND Translation.localized_string IS NOT NULL';
+ $results = $this->query("SELECT * FROM translations AS Translation WHERE Translation.id IN (".implode($translation_ids, ',')."){$where}", $cache, $cache);
+ if (!empty($results)) {
+ foreach ($results as $result) {
+ $field = array_search($result['Translation']['id'], $translation_ids);
+ $translations[$field][$result['Translation']['locale']] = $result['Translation']['localized_string'];
+ }
+ }
+ }
+ else {
+ // No translations found
+ if ($returnIDs) {
+ return array($translations, array());
+ }
+ else {
+ return $translations;
+ }
+ }
+
+ if ($returnIDs) {
+ return array($translations, $translation_ids);
+ }
+ else {
+ return $translations;
+ }
+ }
+
+ /**
+ * Save translations for new, updated, and deleted locales.
+ * This should only be used for mass updating and is more efficient
+ * for mass updating than normal save()ing
+ * @param int $id id to update
+ * @param array $rawData array of translation data not escaped
+ * @param array $data array of translation data escaped
+ */
+ function saveTranslations($id, $rawData, $data) {
+ // Pull all existing translations for fields to save
+ $fields = array_keys($data);
+ list($existing, $translation_ids) = $this->getAllTranslations($id, $fields, true, true);
+
+ // Handle updated and deleted translations
+ if (!empty($existing)) {
+ foreach ($existing as $field => $translations) {
+ if (!empty($translations)) {
+ foreach ($translations as $locale => $translation) {
+ if (isset($data[$field][$locale]) && empty($data[$field][$locale]) && !empty($translation)) {
+ // Translation was deleted
+ $this->execute("UPDATE translations SET localized_string=NULL, modified=NOW() WHERE id={$translation_ids[$field]} AND locale='{$locale}'");
+ }
+ elseif (!empty($rawData[$field][$locale]) && $rawData[$field][$locale] != $translation) {
+ // If not the same, the translation was updated
+ $this->execute("UPDATE translations SET localized_string='{$data[$field][$locale]}', modified=NOW() WHERE id={$translation_ids[$field]} AND locale='{$locale}'");
+ }
+ // Else, no changes
+
+ unset($data[$field][$locale]);
+ }
+ }
+ }
+ }
+
+ // Handle new translations
+ if (!empty($data)) {
+ foreach ($data as $field => $translations) {
+ if (!empty($translations)) {
+ foreach ($translations as $locale => $translation) {
+ if (!empty($translation)) {
+ // Add new locale
+ if (!empty($translation_ids[$field])) {
+ // Translation id already set for this field
+ $this->execute("INSERT INTO translations (id, locale, localized_string, created) VALUES({$translation_ids[$field]}, '{$locale}', '{$data[$field][$locale]}', NOW())");
+ }
+ else {
+ // Translation id not yet set for this field, so we hand off to normal beforeSave() magic
+ if (in_array($field, $this->translated_fields)) {
+ $this->setLang($locale);
+ $this->id = $id;
+ $save = array($field => $data[$field][$locale]);
+ $this->save($save, false);
+ $this->setLang(LANG);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Validate localized fields from translation box
+ * @param array $data unescaped translation data
+ * @return bool all data validated
+ */
+ function validateTranslations($data) {
+ foreach ($data as $field => $translations) {
+ if (!in_array($field, $this->translated_fields)) continue;
+ foreach ($translations as $locale => $translation) {
+ $this->invalidFields(array($this->name => array($field => $translation)));
+ if (!empty($this->validationErrors)) return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Separates an array of data into localized fields and unlocalized fields
+ */
+ function splitLocalizedFields($data) {
+ $localizedFields = array();
+ $unlocalizedFields = array();
+
+ if (!empty($data)) {
+ foreach ($data as $field => $value) {
+ if (in_array($field, $this->translated_fields)) {
+ $localizedFields[$field] = $value;
+ }
+ else {
+ $unlocalizedFields[$field] = $value;
+ }
+ }
+ }
+
+ return array($localizedFields, $unlocalizedFields);
+ }
+
+ /**
+ * Strips fields that aren't in the specified whitelist
+ */
+ function stripFields($data, $allowedFields) {
+ $safe = array();
+ if (!empty($data)) {
+ foreach ($data as $field => $value) {
+ if (in_array($field, $allowedFields)) {
+ $safe[$field] = $value;
+ }
+ }
+ }
+
+ return $safe;
+ }
+
+}
+?>
diff --git a/site/app/config/acl.ini.php b/site/app/config/acl.ini.php
new file mode 100644
index 0000000..bc584f3
--- /dev/null
+++ b/site/app/config/acl.ini.php
@@ -0,0 +1,76 @@
+;<?php die() ?>
+; SVN FILE: $Id: acl.ini.php,v 1.1.1.1 2006/08/14 23:54:56 sancus%off.net Exp $
+;/**
+; * Short description for file.
+; *
+; *
+; * PHP versions 4 and 5
+; *
+; * CakePHP : Rapid Development Framework <http://www.cakephp.org/>
+; * Copyright (c) 2006, Cake Software Foundation, Inc.
+; * 1785 E. Sahara Avenue, Suite 490-204
+; * Las Vegas, Nevada 89104
+; *
+; * Licensed under The MIT License
+; * Redistributions of files must retain the above copyright notice.
+; *
+; * @filesource
+; * @copyright Copyright (c) 2006, Cake Software Foundation, Inc.
+; * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP Project
+; * @package cake
+; * @subpackage cake.app.config
+; * @since CakePHP v 0.10.0.1076
+; * @version $Revision: 1.1.1.1 $
+; * @modifiedby $LastChangedBy: phpnut $
+; * @lastmodified $Date: 2006/08/14 23:54:56 $
+; * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+; */
+
+; acl.ini.php - Cake ACL Configuration
+; ---------------------------------------------------------------------
+; Use this file to specify user permissions.
+; aco = access control object (something in your application)
+; aro = access request object (something requesting access)
+;
+; User records are added as follows:
+;
+; [uid]
+; groups = group1, group2, group3
+; allow = aco1, aco2, aco3
+; deny = aco4, aco5, aco6
+;
+; Group records are added in a similar manner:
+;
+; [gid]
+; allow = aco1, aco2, aco3
+; deny = aco4, aco5, aco6
+;
+; The allow, deny, and groups sections are all optional.
+; NOTE: groups names *cannot* ever be the same as usernames!
+;
+; ACL permissions are checked in the following order:
+; 1. Check for user denies (and DENY if specified)
+; 2. Check for user allows (and ALLOW if specified)
+; 3. Gather user's groups
+; 4. Check group denies (and DENY if specified)
+; 5. Check group allows (and ALLOW if specified)
+; 6. If no aro, aco, or group information is found, DENY
+;
+; ---------------------------------------------------------------------
+
+;-------------------------------------
+;Users
+;-------------------------------------
+
+[username-goes-here]
+groups = group1, group2
+deny = aco1, aco2
+allow = aco3, aco4
+
+;-------------------------------------
+;Groups
+;-------------------------------------
+
+[groupname-goes-here]
+deny = aco5, aco6
+allow = aco7, aco8 \ No newline at end of file
diff --git a/site/app/config/bootstrap.php b/site/app/config/bootstrap.php
new file mode 100644
index 0000000..2b3525c
--- /dev/null
+++ b/site/app/config/bootstrap.php
@@ -0,0 +1,306 @@
+<?php
+/* SVN FILE: $Id: bootstrap.php,v 1.4 2006/08/26 03:29:13 wclouser%mozilla.com Exp $ */
+/**
+ * Short description for file.
+ *
+ * Long description for file
+ *
+ * PHP versions 4 and 5
+ *
+ * CakePHP : Rapid Development Framework <http://www.cakephp.org/>
+ * Copyright (c) 2006, Cake Software Foundation, Inc.
+ * 1785 E. Sahara Avenue, Suite 490-204
+ * Las Vegas, Nevada 89104
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright Copyright (c) 2006, Cake Software Foundation, Inc.
+ * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP Project
+ * @package cake
+ * @subpackage cake.app.config
+ * @since CakePHP v 0.10.8.2117
+ * @version $Revision: 1.4 $
+ * @modifiedby $LastChangedBy: phpnut $
+ * @lastmodified $Date: 2006/08/26 03:29:13 $
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+/**
+ *
+ * This file is loaded automatically by the app/webroot/index.php file after the core bootstrap.php is loaded
+ * This is an application wide file to load any function that is not used within a class define.
+ * You can also use this to include or require any files in your application.
+ *
+ */
+/**
+ * The settings below can be used to set additional paths to models, views and controllers.
+ * This is related to Ticket #470 (https://trac.cakephp.org/ticket/470)
+ *
+ * $modelPaths = array('full path to models', 'second full path to models', 'etc...');
+ * $viewPaths = array('this path to views', 'second full path to views', 'etc...');
+ * $controllerPaths = array('this path to controllers', 'second full path to controllers', 'etc...');
+ *
+ */
+
+// Make the app and l10n play nice with Windows.
+if (substr(PHP_OS, 0, 3) == 'WIN')
+ define('WINDOWS', 1);
+
+// Load database and URL configuration.
+require_once ROOT.DS.APP_DIR.DS.'config'.DS.'config.php';
+
+// Require global constants.
+require_once ROOT.DS.APP_DIR.DS.'config'.DS.'constants.php';
+
+// Required for translating the templates (using gettext)
+require_once ROOT.DS.APP_DIR.DS.'config'.DS.'language.php';
+
+// Require language config file, containing arrays for valid, right-to-left,
+// and native language strings.
+require_once ROOT.DS.APP_DIR.DS.'config'.DS.'language.inc.php';
+
+// Indicate which node is serving the request, for debugging assistance in a
+// load-balanced environment.
+header('X-AMO-ServedBy: ' . php_uname('n'));
+
+if (DISABLE_AMO) {
+ if ($_GET['url'] != 'en-US/firefox/disabled.php') {
+ global $webpath;
+ if (is_null($webpath)) {
+ require_once(CAKE.DS.'dispatcher.php');
+ $_dispatcher = new Dispatcher();
+ $_dispatcher->parseParams('');
+ $_appDirName = str_replace('/', '\/', preg_quote(APP_DIR));
+ $webpath = preg_replace('/'.$_appDirName.'.*/','',$_dispatcher->baseUrl());
+ }
+
+ $fullbaseurl = FULL_BASE_URL;
+ if (isset($_SERVER['HTTPS']) && !empty($_SERVER['HTTPS']))
+ preg_replace('/^http:/i', 'https:', $fullbaseurl);
+ if ($webpath{0} != '/' && substr($fullbaseurl, -1) != '/')
+ $fullbaseurl .= '/';
+
+ $target = $fullbaseurl.$webpath.'/disabled.php';
+
+ header('Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0, private');
+ header('Pragma: no-cache');
+ header('Location: '.$target);
+ }
+
+ exit;
+}
+
+if (defined('FB_ENABLED') && FB_ENABLED == 'true') {
+ if (defined('FB_BOUNCE_PERCENTAGE') && FB_BOUNCE_PERCENTAGE > 0) {
+ if (rand(1, 100) <= FB_BOUNCE_PERCENTAGE && strpos($_SERVER['REQUEST_URI'], 'outage') === false) {
+ die('<fb:ref url="'.SITE_URL.'/facebook/outage" />');
+ }
+ }
+}
+
+global $webpath;
+$webpath = null; // Relative webpath.
+$buf = array(); // Temp array.
+
+// Build our language_config object. This won't go through the steps to actually
+// set the language, since we might just be redirecting shortly
+$language_config = new LANGUAGE_CONFIG($valid_languages, $supported_languages, false);
+
+// Grab a language (will attempt to detect, otherwise, fallback)
+$lang = $language_config->detectCurrentLanguage();
+
+// XSS check - if there are weird symbols in this, they lose their chance, and
+// they get a "bad request" response
+// We don't run this test on the API: preg only considers \w that
+// applies to the currently running PHP locale and hence thinks non en
+// characters are non word characters. This doesn't affect regular AMO
+// urls because the url format is different (?foo=bar as opposed to
+// /bar/. The GET params are not included in the $_GET['url'] as
+// generated by Cake.
+// The API has its own parameter santization which is UTF-8 aware.
+// This comment is now longer than the code change.
+if (array_key_exists('url',$_GET) &&
+ !preg_match('/\/api\//', $_GET['url']) &&
+ preg_match('/[^\w\d\/\.\-_!: ]/u',$_GET['url'])) {
+ header("HTTP/1.1 400 Bad Request");
+ exit;
+}
+if (isset($_SERVER['HTTP_MOZ_REQ_METHOD']) && $_SERVER['HTTP_MOZ_REQ_METHOD'] == 'HTTPS') {
+ $_SERVER['HTTPS'] = 'on';
+}
+
+function redirectWithNewLocaleAndExit($pathParts) {
+ // we need this pile of code right before we
+ // redirect, so we can get our "base web path".
+ global $webpath, $valid_languages;
+ if (is_null($webpath)) {
+ require_once(CAKE.DS.'dispatcher.php');
+ $_dispatcher = new Dispatcher();
+ $_dispatcher->parseParams('');
+ $_appDirName = str_replace('/', '\/', preg_quote(APP_DIR));
+ $webpath = preg_replace('/'.$_appDirName.'.*/','',$_dispatcher->baseUrl());
+ }
+
+ if (empty($pathParts))
+ $location = '/';
+ else
+ $location = implode('/', $pathParts);
+
+ if ((substr($webpath,-1) != '/') && ($location{0} != '/'))
+ $webpath .= '/';
+
+ // make sure the redirection base url is https if https is applicable
+ $fullbaseurl = FULL_BASE_URL;
+ if (isset($_SERVER['HTTPS']) && !empty($_SERVER['HTTPS']))
+ preg_replace('/^http:/i', 'https:', $fullbaseurl);
+ if ($webpath{0} != '/' && substr($fullbaseurl, -1) != '/')
+ $fullbaseurl .= '/';
+
+ // preserve GET variables if present
+ $ignore_get_variables = array('url', 'origurl', 'lang', 'addons-author-addons-select'); // GET variable names not to be preserved
+ $myget = array();
+ foreach ($_GET as $key => $value) {
+ if (in_array($key, $ignore_get_variables)) continue;
+ $myget[] = urlencode($key) .'='. urlencode($value);
+ }
+
+ // build redirection target
+ $target = $fullbaseurl.$webpath.$location;
+ if (!empty($myget)) $target .= '?'.implode('&', $myget);
+
+ // If they are requesting a language, don't send the no-cache headers
+ if (!(array_key_exists('lang', $_GET) && array_key_exists($_GET['lang'], $valid_languages))) {
+ header('Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0, private');
+ header('Pragma: no-cache');
+ }
+ header('Location: '.$target);
+ exit;
+}
+
+// If it is not set, we are at the root
+if (!array_key_exists('url', $_GET) || empty($_GET['url'])) {
+ // Refresh the language, detecting it from the browser
+ $lang = $language_config->detectCurrentLanguage(true);
+ redirectWithNewLocaleAndExit(array($lang, ''));
+}
+
+// If someone goes to a URL without a language, we need to redirect them to one with
+// a language, so caching works correctly. If url is set, replace current locale
+// with new locale and send the user along.
+
+$buf = explode('/', $_GET['url']);
+
+global $app_shortnames, $valid_layouts, $other_layouts;
+
+// If we already have a set locale, overwrite it.
+if (array_key_exists($buf[0],$valid_languages)) {
+ // Only redirect if we're going to a different language
+ if ($buf[0] != $lang) {
+ $buf[0] = $lang;
+ redirectWithNewLocaleAndExit($buf);
+ }
+} elseif (!empty($buf[1]) && array_key_exists($buf[1], $valid_layouts)) {
+ // The first URL param isn't a language but the second one is an application/layout.
+ // Best guess is they went to an unsupported language, like /xx/firefox/
+ array_shift($buf);
+ $lang = $language_config->detectCurrentLanguage(true);
+ array_unshift($buf, $lang);
+ redirectWithNewLocaleAndExit($buf);
+
+} else {
+ // The first URL param isn't a language and the second one isn't an application.
+ // We'll give it a language for now and it'll get an app with the next redirect
+ // (would be better to do this all in one go)
+ $lang = $language_config->detectCurrentLanguage(true);
+ array_unshift($buf, $lang);
+ redirectWithNewLocaleAndExit($buf);
+}
+
+// Now make sure that there's a known app/layout in the second position.
+if (count($buf) < 2 || !array_key_exists($buf[1], $valid_layouts)) {
+ // No app or unknown app, so we see if this is seamonkey, otherwise stick
+ // firefox in the place of honour and redirect.
+ if (array_key_exists('HTTP_USER_AGENT', $_SERVER) &&
+ strpos($_SERVER['HTTP_USER_AGENT'], 'SeaMonkey') !== false) {
+ array_splice($buf, 1, 0, "seamonkey");
+ } else {
+ array_splice($buf, 1, 0, "firefox");
+ }
+ redirectWithNewLocaleAndExit($buf);
+}
+
+// For other functions/classes
+define('SITE_LAYOUT', $buf[1]);
+
+if (array_key_exists(SITE_LAYOUT, $other_layouts)) {
+ // If this is a non-app layout, see if the previous app layout was set
+
+ if (!empty($_COOKIE['AMOappName']) && array_key_exists($_COOKIE['AMOappName'], $app_shortnames)) {
+ define('APP_SHORTNAME', $_COOKIE['AMOappName']);
+ }
+ else {
+ // App wasn't set, so default to Firefox
+ define('APP_SHORTNAME', 'firefox');
+ }
+ define('LAYOUT_NAME', $other_layouts[SITE_LAYOUT]);
+}
+else {
+ define('APP_SHORTNAME', $buf[1]);
+ define('LAYOUT_NAME', $buf[1]);
+
+ // If app cookie is set and it's different from the current app, update the
+ // cookie
+ if (!empty($_COOKIE['AMOappName']) && $_COOKIE['AMOappName'] != APP_SHORTNAME) {
+ setcookie('AMOappName', APP_SHORTNAME, 0, '/');
+ }
+}
+
+define('APP_ID', $app_shortnames[APP_SHORTNAME]);
+// Sets up all the gettext functions for our language
+$language_config->setCurrentLanguage(array($lang));
+
+// For other functions/classes
+define('LANG', $lang);
+
+if (in_array(LANG, $rtl_languages)) {
+ define('TEXTDIR','rtl');
+} else {
+ define('TEXTDIR','ltr');
+}
+
+global $app_prettynames;
+$app_prettynames = array(
+ 'firefox' => ___('main_prettyname_firefox'),
+ 'thunderbird' => ___('main_prettyname_thunderbird'),
+ 'sunbird' => ___('main_prettyname_sunbird'),
+ 'seamonkey' => ___('main_prettyname_seamonkey'),
+ 'fennec' => ___('main_prettyname_fennec')
+ );
+define('APP_PRETTYNAME', $app_prettynames[APP_SHORTNAME]);
+
+// Get rid of the temp vars
+unset($webpath, $buf, $lang, $language_config);
+
+/**
+ * @var flush_lists list of cache list ids to flush (Not their cache keys!)
+ * See AppController::afterFilter()
+ */
+global $flush_lists;
+$flush_lists = array();
+
+/**
+ * We depend on the order of these licenses, so this list is append-only.
+ */
+global $licenses;
+$licenses = array(
+ ___('licenses_mpl_1.1'),
+ ___('licenses_gpl_2.0'),
+ ___('licenses_gpl_3.0'),
+ ___('licenses_lgpl_2.1'),
+ ___('licenses_lgpl_3.0'),
+ ___('licenses_mit'),
+ ___('licenses_bsd')
+);
+//EOF
+?>
diff --git a/site/app/config/config.php.default b/site/app/config/config.php.default
new file mode 100644
index 0000000..60d0f87
--- /dev/null
+++ b/site/app/config/config.php.default
@@ -0,0 +1,232 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Wil Clouser <wclouser@mozilla.com> (Original Author)
+ * Mike Morgan <morgamic@mozilla.com>
+ * Justin Scott <fligtar@gmail.com>
+ * Frederic Wenzel <fwenzel@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+
+
+/**
+ * Global configuration document.
+ *
+ * This document covers both the CakePHP based site (/site) and its service scripts.
+ * Unless otherwise noted, trailing slashes should not be used.
+ * @package amo
+ */
+
+/**
+ * Site URL
+ * Example: http://addons.mozilla.org
+ * Example: http://khan-vm.mozilla.org (dev)
+ * Example of getting a full controller url:
+ * echo SITE_URL.$html->url('/users/register');
+ * Will default to http://addons.mozilla.org unless defined below
+ */
+// define('SITE_URL', '');
+
+/**
+ * Services URL.
+ * Example: http://addons.mozilla.org/services
+ * Example: http://khan-vm.mozilla.org/amo/services (dev)
+ */
+define('SERVICE_URL','');
+
+/**
+ * Site State
+ * Example: production
+ * Example: staging
+ * Example: dev
+ * All uses should default to dev
+ */
+//define('SITE_STATE', 'production');
+
+/**
+ * Files
+ * The application uses these paths to piece together the URL for files.
+ *
+ * HOST and URL are separated because CakePHP has $html->webroot, and only appends
+ * FILES_URL while the services need both since it doesn't have
+ * Cake's context.
+ *
+ * No trailing slashes.
+ */
+
+/**
+ * Host, including http://. Should be everything leading up to addon ids.
+ * Example: http://releases.mozilla.org/addons
+ */
+define('FILES_HOST', 'http://releases.mozilla.org/pub/mozilla.org/addons');
+
+/**
+ * Relative web path of the files directory. Tacking this on to FILES_HOST should get you
+ * the complete URL where your files are. This is the location of the downloads controller
+ * and it should not normally need to be changed, the default is set in constants.php,
+ * and shown commented out here.
+ *
+ * Example: downloads/file
+ */
+// define('FILES_URL', 'downloads/file');
+
+/**
+ * File path for storing XPI/JAR files (or any files associated with an add-on).
+ * Example: /data/www/app/webroot/files
+ */
+define('REPO_PATH', '');
+
+/**
+ * File path for storing public files to be rsynced for updates
+ * If left commented out, files will not be copied there and will use only REPO_PATH
+ */
+//define('PUBLIC_STAGING_PATH', '');
+
+/**
+ * The path to the gnu diff program (or any diff program able to create a unified diff).
+ * If left commented out, it will use the xdiff package
+ */
+//define('DIFF_PATH', '/usr/bin/diff');
+
+/**
+ * Path to directory where detailed logfiles are kept. Files will be created in
+ * this directory in the format: {DETAILED_LOG_PATH}/Y-M-D.txt
+ */
+//define('DETAILED_LOG_PATH', '');
+
+/**
+ * Path to directory for misc. AMO storage accessible by all webheads.
+ */
+define('NETAPP_STORAGE', '');
+
+/**
+ * Facebook Configuration
+ */
+// Whether the Facebook controller is enabled
+define('FB_ENABLED', 'false');
+
+// Facebook API keys
+define('FB_API_KEY', '');
+define('FB_API_SECRET', '');
+
+// Facebook App URL
+define('FB_URL', 'http://apps.facebook.com/add-ons');
+
+// Facebook Image site - where images are pulled from
+define('FB_IMAGE_SITE', 'https://addons.mozilla.org');
+
+// Facebook Install site - where the add-on install page goes
+define('FB_INSTALL_SITE', 'https://addons.mozilla.org');
+
+// Facebook Bounce Percentage - percent of hits to bounce
+//define('FB_BOUNCE_PERCENTAGE', 0);
+
+/**
+ * Database configuration.
+ */
+
+/**
+ * DB_USER, DB_PASS, DB_NAME, DB_HOST, DB_PORT
+ * This database has read/write capabilities. Host and port default to localhost and 3306.
+ */
+define('DB_USER','');
+define('DB_PASS','');
+define('DB_NAME','');
+
+/**
+ * SHADOW_DB_USER, SHADOW_DB_PASS, SHADOW_DB_NAME, SHADOW_DB_HOST, SHADOW_DB_PORT
+ * Array of shadow databases that have read-only access.
+ * - If left alone, will default to DB_* above.
+ * - DB_WEIGHTs must sum to 1. i.e., a weight of 0 will never get hit, a weight
+ * of .50 will get hit half of the time, and a weight of 1 will always get hit.
+ * - The array keys need not be numeric and could be used for descriptive purposes
+ * that would appear in the monitor script.
+ */
+global $shadow_databases;
+$shadow_databases = array(
+ 0 => array(
+ 'DB_HOST' => '',
+ 'DB_PORT' => 3306,
+ 'DB_NAME' => '',
+ 'DB_USER' => '',
+ 'DB_PASS' => '',
+ 'DB_WEIGHT' => 0
+ )
+);
+
+/**
+ * TEST_DB_USER, TEST_DB_PASS, TEST_DB_NAME, TEST_DB_HOST, TEST_DB_PORT
+ * The test database. All fields default to their DB_* counterparts, except
+ * for TEST_DB_NAME, which is DB_NAME . "-test".
+ */
+
+/**
+ * memcache configuration.
+ *
+ * The memcache_config array lists all possible memcached servers to use in case the default server does not have the appropriate key.
+ */
+global $memcache_config;
+$memcache_config = array(
+ 'localhost' => array(
+ 'port' => '11211',
+ 'persistent' => true,
+ 'weight' => '1',
+ 'timeout' => '1',
+ 'retry_interval' => 15
+ )
+);
+
+/**
+ * Recaptcha (recaptcha.net) configuration
+ */
+define('RECAPTCHA_ENABLED', false);
+define('RECAPTCHA_PRIVATE_KEY', '...');
+define('RECAPTCHA_PUBLIC_KEY', '...');
+
+/**
+ * Compatibility Center Versions
+ */
+define('COMPAT_DEFAULT_VERSION', '3.5');
+global $compatibility_versions;
+$compatibility_versions = array(
+ '3.0', '3.5', '3.6'
+);
+// Consider all the mapped versions to be the same as the key.
+global $version_aliases;
+$version_aliases = array(
+ '3.5' => array('3.1', '3.5')
+);
+
+?>
diff --git a/site/app/config/constants.php b/site/app/config/constants.php
new file mode 100644
index 0000000..705946c
--- /dev/null
+++ b/site/app/config/constants.php
@@ -0,0 +1,309 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Wil Clouser <wclouser@mozilla.com> (Original Author)
+ * Mike Morgan <morgamic@mozilla.com>
+ * Justin Scott <fligtar@gmail.com>
+ * Frederic Wenzel <fwenzel@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/**
+ * Site URL default
+ */
+if (!defined('SITE_URL'))
+ define('SITE_URL', 'https://addons.mozilla.org');
+
+/**
+ * Site State default
+ */
+if (!defined('SITE_STATE'))
+ define('SITE_STATE', 'dev');
+
+/**
+ * Database config defaults and cascade.
+ */
+if (!defined('DB_HOST'))
+ define('DB_HOST','localhost');
+if (!defined('DB_PORT'))
+ define('DB_PORT', '3306');
+
+/**
+ * File, image, etc defaults
+ */
+if (!defined('DEFAULT_ADDON_ICON'))
+ define('DEFAULT_ADDON_ICON', 'default_icon.png');
+if (!defined('DEFAULT_THEME_ICON'))
+ define('DEFAULT_THEME_ICON', 'theme.png');
+
+/**
+ * Include shadow database selector
+ * The shadow db selector is here so that services and bin can benefit
+ * from it, although they won't benefit from the downtime detection */
+require_once('shadowdb.inc.php');
+if (!empty($shadow_databases)) {
+ select_shadow_database($shadow_databases);
+}
+
+/**
+ * SHADOW_DB_USER, SHADOW_DB_PASS, SHADOW_DB_NAME, SHADOW_DB_HOST, SHADOW_DB_PORT
+ * The shadow_db has read-only access. Default to the same as DB_* above.
+ */
+if (!defined('SHADOW_DB_USER'))
+ define('SHADOW_DB_USER', DB_USER);
+if (!defined('SHADOW_DB_PASS'))
+ define('SHADOW_DB_PASS', DB_PASS);
+if (!defined('SHADOW_DB_HOST'))
+ define('SHADOW_DB_HOST', DB_HOST);
+if (!defined('SHADOW_DB_NAME'))
+ define('SHADOW_DB_NAME', DB_NAME);
+if (!defined('SHADOW_DB_PORT'))
+ define('SHADOW_DB_PORT', DB_PORT);
+
+/**
+ * TEST_DB_USER, TEST_DB_PASS, TEST_DB_NAME, TEST_DB_HOST, TEST_DB_PORT
+ * The test database. All fields default to their DB_* counterparts, except
+ * for TEST_DB_NAME, which is DB_NAME . "-test".
+ */
+if (!defined('TEST_DB_USER'))
+ define('TEST_DB_USER', DB_USER);
+if (!defined('TEST_DB_PASS'))
+ define('TEST_DB_PASS', DB_PASS);
+if (!defined('TEST_DB_HOST'))
+ define('TEST_DB_HOST', DB_HOST);
+if (!defined('TEST_DB_NAME'))
+ define('TEST_DB_NAME', DB_NAME . '-test');
+if (!defined('TEST_DB_PORT'))
+ define('TEST_DB_PORT', DB_PORT);
+
+// Settings for query caching
+if (!defined('QUERY_CACHE'))
+ define('QUERY_CACHE', true); // are we caching queries?
+if (!defined('CACHE_PAGES_FOR'))
+ define('CACHE_PAGES_FOR', 60); // seconds
+
+// This string will be prepended to all memcache keys.
+if (!defined('MEMCACHE_PREFIX'))
+ define('MEMCACHE_PREFIX', 'AMO_');
+
+/**
+ * Downloads
+ */
+// This is the url to the download controller
+if (!defined('FILES_URL'))
+ define('FILES_URL', 'downloads/file');
+
+// This is the table to use in the downloads controller. We put this in to
+// temporarily redirect downloads in the event where we have to alter the
+// downloads table. The table defined in config is a tmp table so we don't
+// lose data. If it's not there, we set the default here.
+if (!defined('DOWNLOADS_TABLE'))
+ define('DOWNLOADS_TABLE','downloads');
+
+// Amount of time in minutes that is waited until files that were just made
+// public are served from the download (mirror) location rather than straight
+// from the application. This allows for mirror propagation time.
+if (!defined('MIRROR_DELAY'))
+ define('MIRROR_DELAY', 30);
+
+if (!defined('DISABLE_AMO'))
+ define('DISABLE_AMO', false);
+
+/**
+ * Applications
+ */
+define('APP_FIREFOX', 1);
+define('APP_THUNDERBIRD', 18);
+define('APP_SEAMONKEY', 59);
+define('APP_SUNBIRD', 52);
+define('APP_FENNEC', 60);
+global $app_shortnames; // shortnames are used in URLs
+$app_shortnames = array(
+ 'firefox' => APP_FIREFOX,
+ 'thunderbird' => APP_THUNDERBIRD,
+ 'seamonkey' => APP_SEAMONKEY,
+ 'sunbird' => APP_SUNBIRD,
+ 'fennec' => APP_FENNEC
+ );
+global $app_prettynames;
+$app_prettynames = array( // Overridden with L10n in bootstrap.php
+ 'firefox' => "Firefox",
+ 'thunderbird' => "Thunderbird",
+ 'seamonkey' => "SeaMonkey",
+ 'sunbird' => "Sunbird",
+ 'fennec' => "Fennec"
+ );
+global $browser_apps; // browser applications; for non-browser apps, use !in_array()
+$browser_apps = array(
+ APP_FIREFOX,
+ APP_SEAMONKEY
+);
+global $other_layouts; // non-app top-level layouts in URLs
+// controller => header
+$other_layouts = array(
+ 'admin' => 'generic',
+ 'developers' => 'developers',
+ 'editors' => 'generic',
+ 'localizers' => 'generic',
+ 'statistics' => 'developers'
+);
+global $valid_layouts; // used in URLs, like /en-US/firefox or /en-US/developers
+$valid_layouts = array_merge($other_layouts, $app_shortnames);
+
+/**
+ * Addontypes
+ */
+define('ADDON_ANY', '-1'); // default of advanced search
+define('ADDON_EXTENSION', '1');
+define('ADDON_THEME', '2');
+define('ADDON_DICT', '3');
+define('ADDON_SEARCH', '4');
+define('ADDON_LPAPP', '5');
+define('ADDON_LPADDON', '6');
+define('ADDON_PLUGIN', '7');
+define('ADDON_API', '8'); // not actually a type but used to identify extensions + themes
+
+define('COUNT_ADDON_PLUGIN', 7); // Since the plugin page is static, define a static count here,
+
+/**
+ * Add-on Author Roles
+ */
+define('AUTHOR_ROLE_ADMINOWNER', 7);
+define('AUTHOR_ROLE_ADMIN', 6);
+define('AUTHOR_ROLE_OWNER', 5);
+define('AUTHOR_ROLE_DEV', 4);
+define('AUTHOR_ROLE_VIEWER', 1);
+define('AUTHOR_ROLE_NONE', 0);
+
+/**
+ * Collection Author Roles
+ */
+define('COLLECTION_ROLE_OWNER', 2);
+define('COLLECTION_ROLE_ADMIN', 1);
+define('COLLECTION_ROLE_PUBLISHER', 0);
+
+define('COLLECTOR_ID', 11950);
+
+/* hybrid categories (extensions + other add-on types) */
+global $hybrid_categories;
+$hybrid_categories = array(
+ APP_FIREFOX => array(
+ 13 => ADDON_SEARCH
+ ),
+ APP_SEAMONKEY => array(
+ 47 => ADDON_SEARCH
+ )
+);
+
+// We could pull these out of the database based on whether or not there are any of a given
+// type that are compatible with the application in question, but that would be a lot of slow
+// for very little gain.
+global $app_listedtypes;
+$app_listedtypes = array(
+ APP_FIREFOX => array(ADDON_EXTENSION, ADDON_THEME, ADDON_DICT, ADDON_SEARCH, ADDON_PLUGIN),
+ APP_THUNDERBIRD => array(ADDON_EXTENSION, ADDON_THEME, ADDON_DICT),
+ APP_SEAMONKEY => array(ADDON_EXTENSION, ADDON_THEME, ADDON_DICT, ADDON_SEARCH, ADDON_PLUGIN),
+ APP_SUNBIRD => array(ADDON_EXTENSION, ADDON_THEME, ADDON_DICT)
+ );
+
+/**
+ * Add-on and File Statuses
+ */
+define('STATUS_NULL', '0');
+define('STATUS_SANDBOX', '1');
+define('STATUS_PENDING', '2');
+define('STATUS_NOMINATED', '3');
+define('STATUS_PUBLIC', '4');
+define('STATUS_DISABLED', '5');
+global $experimental_status, $valid_status;
+$experimental_status = array(STATUS_SANDBOX, STATUS_PENDING, STATUS_NOMINATED);
+$valid_status = array(STATUS_SANDBOX, STATUS_PENDING, STATUS_NOMINATED, STATUS_PUBLIC);
+
+/**
+ * Platforms
+ * This was placed here for use mainly in the update service.
+ */
+define('PLATFORM_ANY', '-1'); //used by advanced search
+define('PLATFORM_ALL', '1');
+define('PLATFORM_LINUX', '2');
+define('PLATFORM_MAC', '3');
+define('PLATFORM_BSD', '4');
+define('PLATFORM_WIN', '5');
+define('PLATFORM_SUN', '6');
+
+/**
+ * Default ACL user. They have access to nothing.
+ */
+define('DEFAULT_ACL_USER','nobody@addons.mozilla.org');
+
+/**
+ * Regular expressions used in model validations.
+ */
+// URL address (basic domain name with optional port followed by optional slash anything)
+define('VALID_URL_REQ','/^https?:\/\/([a-z0-9][a-z0-9-]*\.)+([a-z]+)(:[0-9]+)?(\/|$)/i');
+define('VALID_URL_OPT','/(^$)|(^https?:\/\/([a-z0-9][a-z0-9-]*\.)+([a-z]+)(:[0-9]+)?(\/|$))/i');
+// EMAIL optional validator
+define('VALID_EMAIL_OPT', '/(^$)|\\A(?:^([a-z0-9][a-z0-9_\\-\\.\\+]*)@([a-z0-9][a-z0-9\\.\\-]{0,63}\\.(com|org|net|biz|info|name|net|pro|aero|coop|museum|[a-z]{2,4}))$)\\z/i');
+// UUID required validator
+define('VALID_UUID_REQ','/^[0-9a-fA-F]{8}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{12}$/');
+// regex to preg_replace() the bad characters in uploaded filenames
+define('INVALID_FILENAME_CHARS', '/[^\w\d\.\-_!+]/');
+// invalid collection nicknames
+define('INVALID_COLLECTION_NICKNAME_CHARS', INVALID_FILENAME_CHARS);
+
+/**
+ * entities to be sanitized by publish()
+ */
+global $sanitize_patterns, $unsanitize_patterns;
+$sanitize_patterns = array(
+ 'patterns' => array("/%/u", "/\(/u", "/\)/u", "/\+/u", "/-/u"),
+ 'replacements' => array("&#37;", "&#40;", "&#41;", "&#43;", "&#45;")
+ );
+$unsanitize_patterns = array(
+ 'patterns' => array("/\&amp;/u", "/\&#37;/u", "/\&lt;/u", "/\&gt;/u", "/\&quot;/u", "/\&#039;/u", "/\&#40;/u", "/\&#41;/u", "/\&#43;/u", "/\&#45;/u"),
+ 'replacements' => array("&", "%", "<", ">", '"', "'", "(", ")", "+", "-")
+ );
+
+/**
+ * CSS & JS Last Changed Revision values, used to fix issues with long-term caching
+ */
+if(defined('ROOT')) {
+ include_once ROOT.DS.APP_DIR.DS.'config'.DS.'revisions.php';
+}
+
+/**
+ * Password Reset Expires: the number of days before a resetcode expires.
+ */
+define('PASSWORD_RESET_EXPIRES', 3);
+?>
diff --git a/site/app/config/core.php b/site/app/config/core.php
new file mode 100644
index 0000000..cdfe6ce
--- /dev/null
+++ b/site/app/config/core.php
@@ -0,0 +1,242 @@
+<?php
+/* SVN FILE: $Id: core.php,v 1.1.1.1 2006/08/14 23:54:56 sancus%off.net Exp $ */
+/**
+ * This is core configuration file.
+ *
+ * Use it to configure core behaviour ofCake.
+ *
+ * PHP versions 4 and 5
+ *
+ * CakePHP : Rapid Development Framework <http://www.cakephp.org/>
+ * Copyright (c) 2006, Cake Software Foundation, Inc.
+ * 1785 E. Sahara Avenue, Suite 490-204
+ * Las Vegas, Nevada 89104
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright Copyright (c) 2006, Cake Software Foundation, Inc.
+ * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP Project
+ * @package cake
+ * @subpackage cake.app.config
+ * @since CakePHP v 0.2.9
+ * @version $Revision: 1.1.1.1 $
+ * @modifiedby $LastChangedBy: phpnut $
+ * @lastmodified $Date: 2006/08/14 23:54:56 $
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+/**
+ * Include non-default defines from config-local.php.
+ * If you want to set global variables just for your install, use this method.
+ */
+if (file_exists(ROOT.DS.APP_DIR.DS.'config'.DS.'config-local.php')) {
+ require_once('config-local.php');
+}
+
+/**
+ * If you do not have mod rewrite on your system
+ * or if you prefer to use CakePHP pretty urls.
+ * uncomment the line below.
+ * Note: If you do have mod rewrite but prefer the
+ * CakePHP pretty urls, you also have to remove the
+ * .htaccess files
+ * release/.htaccess
+ * release/app/.htaccess
+ * release/app/webroot/.htaccess
+ */
+ //define ('BASE_URL', env('SCRIPT_NAME'));
+/**
+ * Set debug level here:
+ * - 0: production
+ * - 1: development
+ * - 2: full debug with sql
+ * - 3: full debug with sql and dump of the current object
+ *
+ * In production, the "flash messages" redirect after a time interval.
+ * With the other debug levels you get to click the "flash message" to continue.
+ *
+ */
+if (!defined('DEBUG'))
+ define('DEBUG', 0);
+
+/**
+ * Development mode
+ * If this is off, you will not see links to not-yet-released features and such.
+ */
+if (!defined('DEV'))
+ define('DEV', false);
+
+/**
+ * Turn of caching checking wide.
+ * You must still use the controller var cacheAction inside you controller class.
+ * You can either set it controller wide, or in each controller method.
+ * use var $cacheAction = true; or in the controller method $this->cacheAction = true;
+ */
+ define('CACHE_CHECK', false);
+
+/**
+ * Error constant. Used for differentiating error logging and debugging.
+ * Currently PHP supports LOG_DEBUG
+ */
+ define('LOG_ERROR', 2);
+/**
+ * CakePHP includes 3 types of session saves
+ * database or file. Set this to your preferred method.
+ * If you want to use your own save handler place it in
+ * app/config/name.php DO NOT USE file or database as the name.
+ * and use just the name portion below.
+ *
+ * Setting this to cake will save files to /cakedistro/tmp directory
+ * Setting it to php will use the php default save path
+ * Setting it to database will use the database
+ *
+ *
+ */
+ define('CAKE_SESSION_SAVE', 'database');
+/**
+ * If using you own table name for storing sessions
+ * set the table name here.
+ * DO NOT INCLUDE PREFIX IF YOU HAVE SET ONE IN database.php
+ *
+ */
+ define('CAKE_SESSION_TABLE', 'cake_sessions');
+/**
+ * Set a random string of used in session.
+ *
+ */
+ define('CAKE_SESSION_STRING', 'DYhG93b0qyJfIxfs2guVoUubWwvniR2G0FgaC9mi');
+/**
+ * Set the name of session cookie
+ *
+ */
+ define('CAKE_SESSION_COOKIE', 'AMOv3');
+/**
+ * Set level of Cake security. This is now set in the app_controller, because it
+ * needs to be dynamic based on the page we are on.
+ *
+ */
+ //define('CAKE_SECURITY', 'high');
+/**
+ * Set Cake Session time out.
+ * If CAKE_SECURITY define is set
+ * high: multiplied by 10
+ * medium: is multiplied by 100
+ * low is: multiplied by 300
+ *
+ * Number below is seconds.
+ */
+ define('CAKE_SESSION_TIMEOUT', '8640');
+/**
+ * Uncomment the define below to use cake built in admin routes.
+ * You can set this value to anything you want.
+ * All methods related to the admin route should be prefixed with the
+ * name you set CAKE_ADMIN to.
+ * For example: admin_index, admin_edit
+ */
+// define('CAKE_ADMIN', 'admin');
+/**
+ * The define below is used to turn cake built webservices
+ * on or off. Default setting is off.
+ */
+ define('WEBSERVICES', 'off');
+/**
+ * Compress output CSS (removing comments, whitespace, repeating tags etc.)
+ * This requires a/var/cache directory to be writable by the web server (caching).
+ * To use, prefix the CSS link URL with '/ccss/' instead of '/css/' or use Controller::cssTag().
+ */
+ define('COMPRESS_CSS', false);
+/**
+ * If set to true, helpers would output data instead of returning it.
+ */
+ define('AUTO_OUTPUT', false);
+/**
+ * If set to false, session would not automatically be started.
+ */
+ define('AUTO_SESSION', false);
+/**
+ * Set the max size of file to use md5() .
+ */
+ define('MAX_MD5SIZE', (5 * 1024) * 1024);
+/**
+ * To use Access Control Lists with Cake...
+ */
+ define('ACL_CLASSNAME', 'DB_ACL');
+ define('ACL_FILENAME', 'dbacl' . DS . 'db_acl');
+
+/** modified gettext
+ *
+ * @param $to_translate -- token to look for locale translation
+ * @param $fall_translation -- if no translation for current locale output this
+ *
+ * @return translation -- if no fallback and no translation then uses English
+ *
+ */
+function ___($to_translate, $fallback_translation ="") {
+ if(_($to_translate) != $to_translate) return _($to_translate);
+ if($fallback_translation != "") return $fallback_translation;
+
+ global $valid_languages;
+
+ putenv('LANG=en_US');
+ setlocale(LC_COLLATE, 'en_US');
+ setlocale(LC_MONETARY, 'en_US');
+ setlocale(LC_NUMERIC, 'en_US');
+ setlocale(LC_TIME, 'en_US');
+ if (defined('LC_MESSAGES')) {
+ setlocale(LC_MESSAGES, 'en_US');
+ }
+ $output = _($to_translate);
+
+ $lang = $valid_languages[LANG];
+ putenv("LANG=".$lang);
+ setlocale(LC_COLLATE, $lang);
+ setlocale(LC_MONETARY, $lang);
+ setlocale(LC_NUMERIC, $lang);
+ setlocale(LC_TIME, $lang);
+ if (defined('LC_MESSAGES')) {
+ setlocale(LC_MESSAGES, $lang);
+ }
+
+ return $output;
+}
+
+/** modified ngettext
+ *
+ * @param $to_translate -- token to look for locale translation
+ * @param $plural_to_translate -- plural token; useless for AMO, used merely so xgettext works
+ * @param $fall_translation -- if no translation for current locale output this
+ *
+ * @return translation -- if no fallback and no translation then uses English
+ *
+ */
+function n___($to_translate, $plural_to_translate, $num, $fallback_translation ="") {
+ $translation = ngettext($to_translate, $plural_to_translate, $num);
+ if($translation != $to_translate) return $translation;
+ if($fallback_translation != "") return $fallback_translation;
+
+ global $valid_languages;
+
+ putenv('LANG=en_US');
+ setlocale(LC_COLLATE, 'en_US');
+ setlocale(LC_MONETARY, 'en_US');
+ setlocale(LC_NUMERIC, 'en_US');
+ setlocale(LC_TIME, 'en_US');
+ if (defined('LC_MESSAGES')) {
+ setlocale(LC_MESSAGES, 'en_US');
+ }
+ $output = ngettext($to_translate, $plural_to_translate, $num);
+
+ $lang = $valid_languages[LANG];
+ putenv("LANG=".$lang);
+ setlocale(LC_COLLATE, $lang);
+ setlocale(LC_MONETARY, $lang);
+ setlocale(LC_NUMERIC, $lang);
+ setlocale(LC_TIME, $lang);
+ if (defined('LC_MESSAGES')) {
+ setlocale(LC_MESSAGES, $lang);
+ }
+
+ return $output;
+}
+?>
diff --git a/site/app/config/database.php b/site/app/config/database.php
new file mode 100644
index 0000000..0d84c1e
--- /dev/null
+++ b/site/app/config/database.php
@@ -0,0 +1,131 @@
+<?php
+/* SVN FILE: $Id: database.php.default,v 1.1.1.1 2006/08/14 23:54:56 sancus%off.net Exp $ */
+/**
+ * This is core configuration file.
+ *
+ * Use it to configure core behaviour ofCake.
+ *
+ * PHP versions 4 and 5
+ *
+ * CakePHP : Rapid Development Framework <http://www.cakephp.org/>
+ * Copyright (c) 2006, Cake Software Foundation, Inc.
+ * 1785 E. Sahara Avenue, Suite 490-204
+ * Las Vegas, Nevada 89104
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright Copyright (c) 2006, Cake Software Foundation, Inc.
+ * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP Project
+ * @package cake
+ * @subpackage cake.app.config
+ * @since CakePHP v 0.2.9
+ * @version $Revision: 1.1.1.1 $
+ * @modifiedby $LastChangedBy: phpnut $
+ * @lastmodified $Date: 2006/08/14 23:54:56 $
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+/**
+ * In this file you set up your database connection details.
+ *
+ * @package cake
+ * @subpackage cake.config
+ */
+/**
+ * Database configuration class.
+ * You can specify multiple configurations for production, development and testing.
+ *
+ * driver =>
+ * mysql, postgres, sqlite, adodb, pear-drivername
+ *
+ * connect =>
+ * MySQL set the connect to either mysql_pconnect of mysql_connect
+ * PostgreSQL set the connect to either pg_pconnect of pg_connect
+ * SQLite set the connect to sqlite_popen sqlite_open
+ * ADOdb set the connect to one of these
+ * (http://phplens.com/adodb/supported.databases.html) and
+ * append it '|p' for persistent connection. (mssql|p for example, or just mssql for not persistent)
+ *
+ * host =>
+ * the host you connect to the database
+ * MySQL 'localhost' to add a port number use 'localhost:port#'
+ * PostgreSQL 'localhost' to add a port number use 'localhost port=5432'
+ *
+ * Note: Driver has been changed to amo_mysql to add support for fetching l10n data because of a problem
+ * caused by a CakePHP bug (https://trac.cakephp.org/ticket/1183) which as of 1.2 is not fixed.
+ *
+ *
+ * How the database is configured:
+
+ * The ConnectionManager is a singleton object that manages loading database
+ * connections according to the named configurations in app/config/database.php.
+ * When it gets instantiated, it creates an instance of our DATABASE_CONFIG so
+ * it can access the configurations as member variables. We have three
+ * configurations: $default, $test, and $shadow.
+ *
+ * cake/libs/model/connection_manager.php:ConnectionManager.__construct:
+ * $this->config = new DATABASE_CONFIG();
+ *
+ * Clients call ConnectionManager::getDataSource($name), which translates into
+ * <DATABASE_CONFIG instance>->$name. All the calls are for 'default' or
+ * 'shadow', never 'test'. Usually the $name comes from $this->useDbConfig.
+ *
+ * Once ConnectionManager has been instantiated, we're stuck with the
+ * configuration since it's bound to the instance. The easiest way to point
+ * tests at the test database is to reconfigure DATABASE_CONFIG before any
+ * instances are created.
+ *
+ * The named configurations are static class variables so they can be
+ * manipulated by the class, but that means they can't be accessed as member
+ * variables. The constructor manually binds each static var to the new
+ * instance so they're accessible on the object.
+ *
+ * AMO has two kinds of tests: unit tests and web tests. Unit tests run in
+ * same process as the test manager so switching to the test config is easy.
+ * Web tests, however, invoke real requests through the server; we can't tell
+ * that tests are running. We send an X-Amo-Test header during web testing to
+ * switch on the test database.
+ */
+class DATABASE_CONFIG
+{
+ static $default = array('driver' => 'amo_mysql',
+ 'connect' => 'mysql_connect',
+ 'host' => DB_HOST,
+ 'login' => DB_USER,
+ 'password' => DB_PASS,
+ 'database' => DB_NAME,
+ 'prefix' => ''
+ );
+
+ static $test = array( 'driver' => 'amo_mysql',
+ 'connect' => 'mysql_connect',
+ 'host' => TEST_DB_HOST,
+ 'login' => TEST_DB_USER,
+ 'password' => TEST_DB_PASS,
+ 'database' => TEST_DB_NAME,
+ 'prefix' => ''
+ );
+
+ static $shadow = array( 'driver' => 'amo_mysql',
+ 'connect' => 'mysql_connect',
+ 'host' => SHADOW_DB_HOST,
+ 'login' => SHADOW_DB_USER,
+ 'password' => SHADOW_DB_PASS,
+ 'database' => SHADOW_DB_NAME,
+ 'prefix' => '',
+ 'shadow' => true
+ );
+
+ function __construct() {
+ $this->default = self::$default;
+ $this->test = self::$test;
+ $this->shadow = self::$shadow;
+ }
+
+ function useTestConfig() {
+ self::$default = self::$test;
+ self::$shadow = self::$test;
+ }
+}
+?>
diff --git a/site/app/config/inflections.php b/site/app/config/inflections.php
new file mode 100644
index 0000000..e6dfbbb
--- /dev/null
+++ b/site/app/config/inflections.php
@@ -0,0 +1,72 @@
+<?php
+/* SVN FILE: $Id: inflections.php,v 1.1.1.1 2006/08/14 23:54:56 sancus%off.net Exp $ */
+/**
+ * Custom Inflected Words.
+ *
+ * This file is used to hold words that are not matched in the normail Inflector::pluralize() and
+ * Inflector::singularize()
+ *
+ * PHP versions 4 and %
+ *
+ * CakePHP : Rapid Development Framework <http://www.cakephp.org/>
+ * Copyright (c) 2006, Cake Software Foundation, Inc.
+ * 1785 E. Sahara Avenue, Suite 490-204
+ * Las Vegas, Nevada 89104
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright Copyright (c) 2006, Cake Software Foundation, Inc.
+ * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP Project
+ * @package cake
+ * @subpackage cake.app.config
+ * @since CakePHP v 1.0.0.2312
+ * @version $Revision: 1.1.1.1 $
+ * @modifiedby $LastChangedBy: phpnut $
+ * @lastmodified $Date: 2006/08/14 23:54:56 $
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+/**
+ * This is a key => value array of regex used to match words.
+ * If key matches then the value is returned.
+ *
+ * $pluralRules = array('/(s)tatus$/i' => '\1\2tatuses', '/^(ox)$/i' => '\1\2en', '/([m|l])ouse$/i' => '\1ice');
+ */
+ $pluralRules = array();
+/**
+ * This is a key only array of plural words that should not be inflected.
+ * Notice the last comma
+ *
+ * $uninflectedPlural = array('.*[nrlm]ese', '.*deer', '.*fish', '.*measles', '.*ois', '.*pox');
+ */
+ $uninflectedPlural = array('blog', 'facebook_data', 'facebook_detected');
+/**
+ * This is a key => value array of plural irregular words.
+ * If key matches then the value is returned.
+ *
+ * $irregularPlural = array('atlas' => 'atlases', 'beef' => 'beefs', 'brother' => 'brothers')
+ */
+ $irregularPlural = array();
+/**
+ * This is a key => value array of regex used to match words.
+ * If key matches then the value is returned.
+ *
+ * $singularRules = array('/(s)tatuses$/i' => '\1\2tatus', '/(matr)ices$/i' =>'\1ix','/(vert|ind)ices$/i')
+ */
+ $singularRules = array();
+/**
+ * This is a key only array of singular words that should not be inflected.
+ * You should not have to change this value below if you do change it use same format
+ * as the $uninflectedPlural above.
+ */
+ $uninflectedSingular = $uninflectedPlural;
+/**
+ * This is a key => value array of singular irregular words.
+ * Most of the time this will be a reverse of the above $irregularPlural array
+ * You should not have to change this value below if you do change it use same format
+ *
+ * $irregularSingular = array('atlases' => 'atlas', 'beefs' => 'beef', 'brothers' => 'brother')
+ */
+ $irregularSingular = array_flip($irregularPlural);
+?>
diff --git a/site/app/config/language.inc.php b/site/app/config/language.inc.php
new file mode 100644
index 0000000..94c0d14
--- /dev/null
+++ b/site/app/config/language.inc.php
@@ -0,0 +1,225 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Wil Clouser <wclouser@mozilla.com> (Original Author)
+ * Mike Morgan <morgamic@mozilla.com>
+ * Justin Scott <fligtar@gmail.com>
+ * Frederic Wenzel <fwenzel@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/**
+ * Load the Mozilla locale details class from our product-details external.
+ */
+vendor('product-details/localeDetails.class');
+$localeDetails = new localeDetails();
+
+/**
+ * This is declared global because we need it in routes.php. This is the main
+ * language array! If you have a language you want to add, this is the place to do
+ * it. Make sure you add the appropriate /\.(m|p)o/ files as well under /locale/
+ */
+global $valid_languages;
+global $supported_languages;
+global $rtl_languages;
+
+/**
+ * This array is in the form:
+ * $original => $mapping
+ * Where $original is what is in the url, and $mapping is the locale on your server.
+ * For example, the URL moz.com/de/browse/21 would make $original="de". If you have
+ * a "de" locale on your server, awesome, make $mapping="de" and you're done. If you
+ * want it to map to de_DE or de_DE.utf8, then change the mapping to be one of those.
+ * You can see what locales you have installed on your server with `localedef
+ * --list-archive`. If you pick a mapping that doesn't exist, your pages will come
+ * out in your default language (set in the LANGUAGE_CONFIG class). Also note the
+ * mapping uses underscores not dashes - chances are good this is what you want.
+ */
+$supported_languages = array(
+ 'ar' => 'ar_EG.utf8',
+ 'ca' => 'ca_ES.utf8',
+ 'cs' => 'cs_CZ.utf8',
+ 'da' => 'da_DK.utf8',
+ 'de' => 'de_DE.utf8',
+ 'en-US' => 'en_US.utf8',
+ 'el' => 'el_GR.utf8',
+ 'es-ES' => 'es_ES.utf8',
+ 'eu' => 'eu_ES.utf8',
+ 'fa' => 'fa_IR.utf8',
+ 'fi' => 'fi_FI.utf8',
+ 'fr' => 'fr_FR.utf8',
+ 'ga-IE' => 'ga_IE.utf8',
+ 'he' => 'he_IL.utf8',
+ 'hu' => 'hu_HU.utf8',
+ 'id' => 'id_ID.utf8',
+ 'it' => 'it_IT.utf8',
+ 'ja' => 'ja_JP.utf8',
+ 'ko' => 'ko_KR.utf8',
+ 'mn' => 'mn_MN.utf8',
+ 'nl' => 'nl_NL.utf8',
+ 'pl' => 'pl_PL.utf8',
+ 'pt-BR' => 'pt_BR.utf8',
+ 'pt-PT' => 'pt_PT.utf8',
+ 'ro' => 'ro_RO.utf8',
+ 'ru' => 'ru_RU.utf8',
+ 'sk' => 'sk_SK.utf8',
+ 'sq' => 'sq_AL.utf8',
+ 'sv-SE' => 'sv_SE.utf8',
+ 'uk' => 'uk_UA.utf8',
+ 'vi' => 'vi_VN.utf8',
+ 'zh-CN' => 'zh_CN.utf8',
+ 'zh-TW' => 'zh_TW.utf8'
+);
+
+// Languages that work, but to which we won't send a user ourselves (dropdown, lang sniffing)
+$valid_languages = array(
+ 'cy' => 'cy_GB.utf8',
+ 'tr' => 'tr_TR.utf8'
+);
+
+/**
+ * If a supported language is displayed right to left, add it to this array.
+ */
+$rtl_languages = array( 'ar', 'fa', 'fa-IR', 'he' );
+
+/**
+ * Windows uses ISO Alpha-3 locales found here:
+ * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclib/html/_crt_language_strings.asp
+ * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclib/html/_crt_country_strings.asp
+ * http://www.microsoft.com/globaldev/reference/winxp/langtla.mspx
+ * or http://www.unicode.org/onlinedat/countries.html
+ * and http://unicode.org/onlinedat/languages.html
+ * So we redeclare the array using those if WINDOWS is set in bootstrap
+ */
+if (defined('WINDOWS')) {
+ $supported_languages = array(
+ // ar
+ //'ca' => '', // I couldn't find this language
+ 'cs' => 'csy_CZE',
+ 'da' => 'dan_DNK',
+ 'de' => 'deu_DEU',
+ 'en-US' => 'usa_USA',
+ 'el' => 'ell_GRC',
+ 'es-ES' => 'esp_ESP',
+ 'eu' => 'baq_ESP',
+ // fa
+ 'fi' => 'fin_FIN',
+ 'fr' => 'fra_FRA',
+ //'ga-IE' => '', // Not sure
+ 'he' => 'heb', // someone with windows double check?
+ 'id' => 'ind_IND',
+ 'it' => 'ita_ITA',
+ 'ja' => 'jpn_JPN',
+ 'ko' => 'kor_KOR',
+ 'mn' => 'mon_MNG',
+ 'nl' => 'nld_NLD',
+ 'pl' => 'plk_POL',
+ 'pt-BR' => 'ptb_BRA',
+ 'pt-PT' => 'ptb_PRT',
+ 'ro' => 'rou_ROU',
+ 'ru' => 'rus_RUS',
+ 'sk' => 'sky_SVK',
+ 'sq' => 'sqi_ALB',
+ //'sv-SE' => '' // unknown
+ 'uk' => 'ukr_UKR',
+ 'zh-CN' => 'chs_CHN',
+ 'zh-TW' => 'cht_TWN'
+ );
+
+ $valid_languages = array(
+ //cy
+ 'tr' => 'trk_TUR',
+ //'vi' => 'vi_VN.utf8'
+ );
+
+ global $language_returns;
+
+ /**
+ * We also need to have language returns which are returned upon successful
+ * loading of the language.
+ * http://msdn2.microsoft.com/en-us/library/system.globalization.cultureinfo(VS.80).aspx
+ */
+ $language_returns = array(
+ // ar
+ //'ca' => '', // I couldn't find this language
+ //cy
+ 'Czech_Czech Republic' => 'cs',
+ 'Danish_Denmark' => 'da_DK',
+ 'Dutch_Netherlands' => 'nl',
+ 'German_Germany' => 'de',
+ 'English_United States' => 'en_US',
+ 'Spanish_Spain' => 'es_ES',
+ 'Greek' => 'el', // someone with windows double check?
+ //'ga-IE' => '', // Not sure
+ 'Basque_Basque' => 'eu',
+ 'Finnish_Finland' => 'fi',
+ 'French_France' => 'fr',
+ 'Hebrew' => 'he', // someone with windows double check?
+ 'Indonesian_Indonesia' => 'id',
+ 'Italian_Italy' => 'it',
+ 'Japanese_Japan' => 'ja',
+ 'Korean_Korea' => 'ko',
+ 'Mongolian_Mongolia' => 'mn',
+ 'Polish_Poland' => 'pl',
+ 'Portuguese_Brazil' => 'pt_BR',
+ 'Portuguese_Portugal' => 'pt_PT',
+ 'Romanian_Romania' => 'ro',
+ 'Russian_Russia' => 'ru',
+ 'Slovak_Slovakia' => 'sk',
+ 'Albanian_Albania' => 'sq',
+ 'Turkish_Turkey' => 'tr',
+ 'Ukranian_Ukraine' => 'uk',
+ //vi
+ 'Chinese_China' => 'zh_CN',
+ 'Chinese_Taiwan' => 'zh_TW'
+ );
+}
+
+// If we're not on preview or DEBUG isn't set then remove languages that aren't ready to be
+// supported on the site. This lets localizers preview their languages but prevents them from
+// appearing on the live site.
+if (! (DEBUG || $_SERVER['HTTP_HOST'] == 'preview.addons.mozilla.org') ) {
+ $valid_languages = array();
+}
+
+$valid_languages = array_merge($supported_languages, $valid_languages);
+
+/**
+ * This is declared global so it can be used in views. It is used specifically in the
+ * site footer and developer/localizer/admin pages.
+ */
+global $native_languages;
+$native_languages = $localeDetails->languages;
+
+?>
diff --git a/site/app/config/language.php b/site/app/config/language.php
new file mode 100644
index 0000000..f21adcf
--- /dev/null
+++ b/site/app/config/language.php
@@ -0,0 +1,379 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Wil Clouser <wclouser@mozilla.com> (Original Author)
+ * Justin Scott <fligtar@gmail.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/**
+ * This will setup cake to handle language/locales passed in via $_GET['lang'].
+ * Keeping with the cake style, this is a class.
+ */
+
+class LANGUAGE_CONFIG
+{
+
+ var $default_language = 'en-US';
+
+ var $_default_domain = 'messages';
+
+ var $text_domain = null;
+
+ var $current_language = null;
+
+ /**
+ * If you add a language it needs to be in this array
+ */
+ var $_valid_languages = array();
+
+ /*
+ * Languages for which we will sniff and redirect.
+ */
+ var $_supported_languages = array();
+
+ /**
+ * This fills in the text_domain (telling where the .mo files are), as well as
+ * optionally setting the current language
+ *
+ * @param array valid_languages array of languages that are available (with mapping)
+ * @param array valid_languages array of languages that are shown in the dropdown at the bottom of the footer
+ * @param boolean set_language If true, we'll detect and set the current language
+ */
+ function LANGUAGE_CONFIG($valid_languages, $supported_languages, $set_language=false)
+ {
+ // This is where our .mo files are.
+ $this->text_domain = ROOT.DS.APP_DIR.DS.'locale';
+
+ $this->_valid_languages = $valid_languages;
+ $this->_supported_languages = $supported_languages;
+
+ if ($set_language == true) {
+ $this->setCurrentLanguage(array($this->detectCurrentLanguage()));
+ }
+
+ }
+
+ /**
+ * Will look at the following, in order for a valid language:
+ * 1) $_GET['lang']
+ * 2) the current QUERY_STRING
+ * 4) (if $checkAcceptLang) HTTP_ACCEPT_LANG header
+ * 3) $this->default_language (fallback)
+ *
+ * @param boolean check the accept lang header? Only do this if the redirect isn't cached!
+ * @return string language (eg. 'en-US' or 'ru')
+ */
+ function detectCurrentLanguage($checkAcceptLang = false)
+ {
+ $_match = array();
+
+ $_lang_candidate = null;
+
+ // First check $_GET['lang']
+ if (array_key_exists('lang', $_GET)) {
+ $_lang_candidate = $_GET['lang'];
+ }
+
+ // Second check the URL
+ if (is_null($_lang_candidate)) {
+ // Cake:
+ // the QUERY_STRING comes in in the form (eg.):
+ // url=de-DE/addons/display/1
+ // or simply url=de with end of line ($) afterwards
+ preg_match('/=(.+?)(\/|$)/', $_SERVER['QUERY_STRING'], $_match);
+
+ if (!empty($_match[1])) {
+ $_lang_candidate = $_match[1];
+ }
+ }
+
+ // SpecialCase++
+ if (strtolower($_lang_candidate) == 'ja-jp-mac') {
+ $_lang_candidate = 'ja';
+ }
+
+ if ($checkAcceptLang && is_null($_lang_candidate)) {
+ if ( array_key_exists('HTTP_ACCEPT_LANGUAGE', $_SERVER) && !empty($_SERVER['HTTP_ACCEPT_LANGUAGE']) ) {
+
+ $acclang = explode(',', $_SERVER['HTTP_ACCEPT_LANGUAGE']);
+
+ foreach ($acclang as $val) {
+ // The value of the accept language could have a semi-colon in it (for
+ // priority). If it does, we explode, grab the first value, trim the
+ // whitespace, and we've got the locale.
+ $language = trim(array_shift(explode(';', $val)));
+
+ // Check if the language is one we support
+ if (in_array(strtolower($language), array_map('strtolower', array_keys($this->_supported_languages)))) {
+
+ $_lang_candidate = $language;
+ break; // found one
+
+ } else {
+
+ // If there is a dash, this will grab the short language name
+ $language = array_shift(explode('-', $language));
+
+ if (in_array(strtolower($language), array_map('strtolower',array_keys($this->_supported_languages)))) {
+ $_lang_candidate = $language;
+ break; // found one
+ } else {
+ $_lang_candidate = null; // (it's already null, but hey..)
+ }
+ }
+ }
+ }
+
+ }
+
+ // Third, if no detection worked, give the fallback
+ if (is_null($_lang_candidate) || !in_array($_lang_candidate, array_keys($this->_valid_languages))) {
+ $_lang_candidate = $this->getFallbackLanguage();
+ }
+
+ $this->current_language = $_lang_candidate;
+
+ return $this->current_language;
+ }
+
+ /**
+ * Simply returns the current language, or the default if one isn't set.
+ *
+ * @return string current language
+ */
+ function getCurrentLanguage()
+ {
+ if (empty($this->current_language)) {
+ return $this->getFallbackLanguage();
+ }
+
+ return $this->current_language;
+ }
+
+ /**
+ * Runs all the appropriate gettext functions for setting the current language to
+ * whatever is passed in (or the default).
+ *
+ * @param array languages to try (eg. array('en-US', 'ru'))
+ * @param string domain basically, what is the name of your .mo file? (before the .)
+ * @return boolean true on success, false on failure
+ */
+ function setCurrentLanguage($langs=array(), $domain=null)
+ {
+ // Used below - will fill with valid language mappings to try via setlocale()
+ $languages_to_try = array();
+
+ if (empty($langs)) {
+ $langs = array($this->default_language);
+ }
+
+ if (empty($domain)) {
+ $domain = $this->_default_domain;
+ }
+
+ // Setup text domains - these don't care what the language is.
+ bindtextdomain($domain, $this->text_domain);
+ bind_textdomain_codeset($domain, 'UTF-8');
+ textdomain($domain);
+
+ foreach ($langs as $lang) {
+ // Double check they know what they are talking about.
+ if (!in_array($lang, array_keys($this->_valid_languages))) {
+ // Perhaps we should fallback to the default?
+ continue;
+ } else {
+ // Our language exists, add _the mapping_ to our testing array
+ $languages_to_try[] = $this->_valid_languages[$lang];
+ }
+ }
+
+ // The locales on the local machine use underscores. Verify this if you like
+ // by typing `localedef --list-archive` at a prompt
+ $languages_to_try = str_replace('-','_',$languages_to_try);
+
+ // Set the language. We can't use LC_ALL here because it includes LC_CTYPE
+ // and some languages (I'm looking at you Turkish!) will break php when
+ // string functions are used
+ $lang = setlocale(LC_COLLATE, $languages_to_try);
+ if ($lang != false) {
+ setlocale(LC_MONETARY, $lang);
+ setlocale(LC_NUMERIC, $lang);
+ setlocale(LC_TIME, $lang);
+ if (defined('LC_MESSAGES')) {
+ setlocale(LC_MESSAGES, $lang);
+ }
+ }
+
+ // If this is failing, chances are good you don't have the locale installed
+ // on your machine. Run `localedef --list-archive` to see a list of
+ // installed locales.
+ if ($lang === false) {
+
+ // Fallback to defaults
+ $lang = trim(str_replace('-','_',$this->default_language));
+
+ setlocale(LC_COLLATE, $lang);
+ setlocale(LC_MONETARY, $lang);
+ setlocale(LC_NUMERIC, $lang);
+ setlocale(LC_TIME, $lang);
+ if (defined('LC_MESSAGES')) {
+ setlocale(LC_MESSAGES, $lang);
+ }
+
+ // Right now this is just used to give the language to the <head> block,
+ // so it would be accurate to set it here, since we'll be using it to
+ // draw the page. This could lead to pages where the user has specified
+ // $lang, but everything is coming up in en-US. If this line is removed,
+ // the page will think it's displaying $lang, and will display everything
+ // it can in $lang, but english will appear to fill in the gaps.
+ // Hopefully this is a corner case.
+ $this->current_language = $this->default_language;
+
+ // In reality, we should have still successfully set the language - it's
+ // just not the language we wanted, so I'm returning false.
+ return false;
+ }
+
+ // setlocale() has returned what it considers the language. However, we're
+ // remapping the languages in $valid_languages, and setlocale() has returned
+ // a mapping - not the original language. So, we need to lookup the old
+ // value, and reset our $lang to the real language, not the mapping.
+ if (in_array($lang,array_values($this->_valid_languages))) {
+ $lang = array_search($lang,$this->_valid_languages);
+ }
+
+ // Set LANG environmental variable. This is not optional for Windows.
+ if (defined('WINDOWS')) {
+ global $language_returns;
+
+ // In order to find out what language was returned, we have to use a
+ // different array of returned strings. They are in the format
+ // German_Germany.1252
+ if (preg_match("/^(.+)\./", $lang, $matches)) {
+ $lang = $language_returns[$matches[1]];
+ putenv("LANG={$lang}");
+ }
+ }
+
+ // Switch our underscore back to a dash
+ $this->current_language = str_replace('_','-',$lang);
+
+ return true;
+ }
+
+ /**
+ * Try to get a fallback language from the accept-language HTTP header.
+ * If that fails, just go for the default.
+ */
+ function getFallbackLanguage() {
+ // if we don't have a hint, fall back to default
+ if (!array_key_exists('HTTP_ACCEPT_LANGUAGE', $_SERVER))
+ return $this->default_language;
+
+ $_al = $_SERVER['HTTP_ACCEPT_LANGUAGE'];
+ $_alparts = explode(',', $_al, 2);
+ $_alparts = array_map('strtolower', $_alparts);
+ $_alparts = array_map('trim', $_alparts);
+
+ $_langscores = array();
+ $_additional_langs = array();
+ foreach ($_alparts as $_part) {
+ if (strpos($_part, ';') !== false) {
+ $_scoresplit = explode(';', $_part, 2);
+ $_score = explode('=', $_scoresplit[1], 2);
+ $_langscores[$_scoresplit[0]] = $_score[1];
+
+ // if the requested lang is dashed, also allow more general form
+ if (strpos($_scoresplit[0], '-') !== false) {
+ $_lang = substr($_scoresplit[0], 0, strpos($_scoresplit[0], '-'));
+ $_langscores[$_lang] = $_score[1];
+ }
+ } else {
+ $_langscores[$_part] = 1;
+ // if the requested lang is dashed, also allow more general form
+ if (strpos($_part, '-') !== false) {
+ $_lang = substr($_part, 0, strpos($_part, '-'));
+ $_langscores[$_lang] = 1;
+ }
+ }
+
+ }
+ arsort($_langscores, SORT_NUMERIC);
+
+ foreach ($_langscores as $_lang => $_score) {
+ foreach ($this->_supported_languages as $_valid_lang => $_mapping) {
+ // O(n*m), sorry. But don't worry, the arrays are small.
+ if (strpos(strtolower($_valid_lang), $_lang) === 0) return $_valid_lang;
+ }
+ }
+
+ // if we get here we are really out of luck: just return the default
+ return $this->default_language;
+ }
+
+ /**
+ * Return an array of all valid languages. This is safe to set() instead of publish().
+ *
+ * @param string names either 'english' or 'native' - how to return the full names
+ * @param boolean includeAll whether to include an "All" option at the beginning of the array
+ */
+ static function getAllValidLanguages($names='english', $includeAll=false) {
+ global $valid_languages;
+
+ $localeDetails = new localeDetails();
+
+ $xx_YY = array_keys($valid_languages);
+
+ if ($includeAll) {
+ array_unshift($xx_YY, 'all');
+ }
+
+ $locales = array();
+
+ foreach ($xx_YY as $locale) {
+ if ($locale == 'all') {
+ $locales[$locale] = ___('general_languages_all_locales','All Locales');
+ } else if ($names == 'english') {
+ $locales[$locale] = $localeDetails->getEnglishNameForLocale($locale);
+ } else if ($names == 'native') {
+ $locales[$locale] = $localeDetails->getNativeNameForLocale($locale);
+ }
+ }
+
+ return $locales;
+
+ }
+}
+?>
diff --git a/site/app/config/revisions.php b/site/app/config/revisions.php
new file mode 100644
index 0000000..505b965
--- /dev/null
+++ b/site/app/config/revisions.php
@@ -0,0 +1,5 @@
+<?php
+define('REVISION', 27430);
+define('CSS_REVISION', 27396);
+define('JS_REVISION', 27226);
+?> \ No newline at end of file
diff --git a/site/app/config/routes.php b/site/app/config/routes.php
new file mode 100644
index 0000000..867e5ea
--- /dev/null
+++ b/site/app/config/routes.php
@@ -0,0 +1,131 @@
+<?php
+/* SVN FILE: $Id: routes.php,v 1.1.1.1 2006/08/14 23:54:56 sancus%off.net Exp $ */
+/**
+ * Short description for file.
+ *
+ * In this file, you set up routes to your controllers and their actions.
+ * Routes are very important mechanism that allows you to freely connect
+ * different urls to chosen controllers and their actions (functions).
+ *
+ * PHP versions 4 and 5
+ *
+ * CakePHP : Rapid Development Framework <http://www.cakephp.org/>
+ * Copyright (c) 2006, Cake Software Foundation, Inc.
+ * 1785 E. Sahara Avenue, Suite 490-204
+ * Las Vegas, Nevada 89104
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright Copyright (c) 2006, Cake Software Foundation, Inc.
+ * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP Project
+ * @package cake
+ * @subpackage cake.app.config
+ * @since CakePHP v 0.2.9
+ * @version $Revision: 1.1.1.1 $
+ * @modifiedby $LastChangedBy: phpnut $
+ * @lastmodified $Date: 2006/08/14 23:54:56 $
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+
+/**
+ * Here, we are connecting '/' (base path) to controller called 'Pages',
+ * its action called 'display', and we pass a param to select the view file
+ * to use (in this case, /app/views/pages/home.thtml)...
+ */
+
+ $Route->connect('/', array('controller' => 'addons', 'action' => 'home'));
+
+/**
+ * ...and connect the rest of 'Pages' controller's urls.
+ */
+ $Route->connect('/pages/*', array('controller' => 'pages', 'action' => 'display'));
+
+/**
+ * Then we connect url '/test' to our test controller. This is helpful in
+ * developement.
+ */
+ $Route->connect('/tests', array('controller' => 'tests', 'action' => 'index'));
+
+ // Connect the routes for app and lang. The order of these are important!
+ // The first one that matches is what it will use. If LANG and APP_SHORTNAME
+ // aren't defined, bootstrap will be redirecting the person. We're all pretty
+ // sure these routes don't need to be added every time...
+
+ if (defined('LANG') && defined('SITE_LAYOUT')) {
+ global $other_layouts;
+
+ if (array_key_exists(SITE_LAYOUT, $other_layouts)) {
+ $prefix = LANG;
+ }
+ else {
+ $prefix = LANG . '/' . SITE_LAYOUT;
+ }
+
+ // If they just go to /$lang/$app/
+ $Route->connect("/{$prefix}", array('controller' => 'addons', 'action' => 'home'));
+
+ // connect localized, static pages
+ $Route->connect("/{$prefix}/pages/*", array('controller' => 'pages', 'action' => 'display'));
+
+ // Setup old URL handlers. These all are in the $lang's section because they
+ // get redirected here in bootstrap.php. Original redirects can be seen at:
+ // http://lxr.mozilla.org/mozilla/source/webtools/addons/public/htaccess.dist
+
+ // v2: section prefixes (eg. /extensions/)
+ $Route->connect("/{$prefix}/extensions/", array('controller' => 'legacy_url', 'action' => 'oldSection', 'extensions'));
+ $Route->connect("/{$prefix}/themes/", array('controller' => 'legacy_url', 'action' => 'oldSection', 'themes'));
+ $Route->connect("/{$prefix}/plugins/", array('controller' => 'legacy_url', 'action' => 'oldSection', 'plugins'));
+ $Route->connect("/{$prefix}/search-engines/", array('controller' => 'legacy_url', 'action' => 'oldSection', 'search-engines'));
+ $Route->connect("/{$prefix}/dictionaries/", array('controller' => 'legacy_url', 'action' => 'oldSection', 'dictionaries'));
+ $Route->connect("/{$prefix}/bookmarks/", array('controller' => 'legacy_url', 'action' => 'oldSection', 'bookmarks'));
+
+ // Redirect for firefox 1.5
+ $Route->connect("/{$prefix}/search-engines.php", array('controller' => 'addons', 'action' => 'browse', 'type:4'));
+
+ // Some pleasant short forms
+ $Route->connect("/{$prefix}/browse/*", array('controller' => 'addons', 'action' => 'browse'));
+ $Route->connect("/{$prefix}/recommended/*", array('controller' => 'addons', 'action' => 'recommended'));
+ $Route->connect("/{$prefix}/user/*", array('controller' => 'users', 'action' => 'info'));
+ $Route->connect("/{$prefix}/addon/share/*", array('controller' => 'addons', 'action' => 'share'));
+ $Route->connect("/{$prefix}/addon/*", array('controller' => 'addons', 'action' => 'display'));
+ $Route->connect("/{$prefix}/blog/*", array('controller' => 'blog', 'action' => 'view'));
+ $Route->connect("/{$prefix}/collection/*", array('controller' => 'collections', 'action' => 'view'));
+
+ // API hookup
+ $Route->connect("/{$prefix}/api/addon/*", array('controller' => 'api', 'action'=>'addon'));
+ $Route->connect("/{$prefix}/api/list/*", array('controller' => 'api', 'action'=>'list_addons'));
+
+ // Add API versioning support
+ $Route->connect("/{$prefix}/api/[\d\.]*/addon/*", array('controller' => 'api', 'action'=>'addon'));
+ $Route->connect("/{$prefix}/api/[\d\.]*/list/*", array('controller' => 'api', 'action'=>'list_addons'));
+ $Route->connect("/{$prefix}/api/[\d\.]*/search/*", array('controller' => 'api', 'action'=>'search'));
+ $Route->connect("/{$prefix}/api/[\d\.]*/get_language_packs/*", array('controller' => 'api', 'action'=>'get_language_packs'));
+
+ // Bandwagon sharing API
+ $Route->connect("/{$prefix}/api/[\d\.]*/sharing/collections/*/addons/", array('controller' => 'sharing_api', 'action'=>'collection_addons'));
+ $Route->connect("/{$prefix}/api/[\d\.]*/sharing/collections/*/addons/*", array('controller' => 'sharing_api', 'action'=>'collection_addon_detail'));
+ $Route->connect("/{$prefix}/api/[\d\.]*/sharing/collections/", array('controller' => 'sharing_api', 'action'=>'collections'));
+ $Route->connect("/{$prefix}/api/[\d\.]*/sharing/collections/*", array('controller' => 'sharing_api', 'action'=>'collection_detail'));
+ $Route->connect("/{$prefix}/api/[\d\.]*/sharing/auth", array('controller' => 'sharing_api', 'action'=>'auth'));
+ $Route->connect("/{$prefix}/api/[\d\.]*/sharing/auth/*", array('controller' => 'sharing_api', 'action'=>'auth_detail'));
+ $Route->connect("/{$prefix}/api/[\d\.]*/sharing/email", array('controller' => 'sharing_api', 'action'=>'email'));
+ $Route->connect("/{$prefix}/api/[\d\.]*/sharing", array('controller' => 'sharing_api', 'action'=>'service_doc'));
+
+ // Bandwagon/collections
+ $Route->connect("/{$prefix}/fashionyourfirefox/", array('controller' => 'collections', 'action' => 'interactive'));
+
+ // Forward old DevCP links to new DevCP
+ $Route->connect("/{$prefix}/developers(/|/index)?", array('controller' => 'developers', 'action' => 'dashboard'));
+ $Route->connect("/{$prefix}/developers/details/*", array('controller' => 'developers', 'action' => 'dashboard'));
+ $Route->connect("/{$prefix}/developers/edit/*", array('controller' => 'developers', 'action' => 'addon', 'edit'));
+ $Route->connect("/{$prefix}/developers/add/*", array('controller' => 'developers', 'action' => 'versions' ,'add'));
+ $Route->connect("/{$prefix}/developers/editversion/*", array('controller' => 'developers', 'action' => 'versions', 'edit'));
+
+ // Magical undocumented routing syntax - if nothing has matched up till now, it'll hit this
+ $Route->connect("/{$prefix}/:controller/:action/*", array('controller' => 'pages', 'action' => 'index'));
+ }
+//}}
+
+?>
diff --git a/site/app/config/shadowdb.inc.php b/site/app/config/shadowdb.inc.php
new file mode 100644
index 0000000..f96b18c
--- /dev/null
+++ b/site/app/config/shadowdb.inc.php
@@ -0,0 +1,76 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Justin Scott <fligtar@mozilla.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/**
+ * Select a shadow database to use for this request
+ * @param array $databases The weighted database possibilities
+ * @param bool $set_constants Whether to set the constants (false for testing)
+ */
+function select_shadow_database($databases, $set_constants = true) {
+ if (!empty($databases)) {
+ $database_keys = array();
+ // Store shadow db keys in an array proportionate to their weight
+ foreach ($databases as $k => $shadow_database) {
+ if ($shadow_database['DB_WEIGHT'] > 0)
+ $database_keys = array_merge($database_keys, array_fill(0, $shadow_database['DB_WEIGHT'] * 100, $k));
+ }
+
+ if (!empty($database_keys)) {
+ // Select random database from weighted array
+ $shadow_database = $databases[$database_keys[array_rand($database_keys)]];
+
+ // Constants shouldn't be set if we're testing because they can't be
+ // changed or unset
+ if ($set_constants) {
+ define('SHADOW_DB_USER', $shadow_database['DB_USER']);
+ define('SHADOW_DB_PASS', $shadow_database['DB_PASS']);
+ define('SHADOW_DB_HOST', $shadow_database['DB_HOST']);
+ define('SHADOW_DB_NAME', $shadow_database['DB_NAME']);
+ define('SHADOW_DB_PORT', $shadow_database['DB_PORT']);
+ }
+
+ unset($database_keys);
+
+ return $shadow_database;
+ }
+ }
+
+ return array();
+}
+
+?>
diff --git a/site/app/config/sql/anonymize.sql b/site/app/config/sql/anonymize.sql
new file mode 100644
index 0000000..4bd7ed6
--- /dev/null
+++ b/site/app/config/sql/anonymize.sql
@@ -0,0 +1,18 @@
+-- To be run when you want to anonymize an AMO database. Note that this does NOT
+-- clear out all confidential information and should not be considered approval to
+-- distribute AMO databases openly. This just clears out the bare minimum of data.
+-- Talk to clouserw if you have questions.
+
+UPDATE users SET
+ email=CONCAT('user',id,'@nowhere'),
+ password='sha512$santized',
+ lastname=SUBSTRING(lastname,1,1),
+ bio=NULL,
+ confirmationcode='',
+ resetcode='',
+ resetcode_expires='0000-00-00 00:00:00',
+ notes='';
+
+TRUNCATE cache;
+
+TRUNCATE cake_sessions;
diff --git a/site/app/config/sql/remora.sql b/site/app/config/sql/remora.sql
new file mode 100644
index 0000000..71b7c65
--- /dev/null
+++ b/site/app/config/sql/remora.sql
@@ -0,0 +1,1250 @@
+-- MySQL dump 10.9
+--
+-- Host: localhost Database: c_remora
+-- ------------------------------------------------------
+-- Server version 4.1.20
+
+/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
+/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
+/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
+/*!40101 SET NAMES utf8 */;
+/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
+/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
+/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
+/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
+
+SET FOREIGN_KEY_CHECKS = 0;
+
+--
+-- Table structure for table `addons`
+--
+
+DROP TABLE IF EXISTS `addons`;
+CREATE TABLE `addons` (
+ `id` int(11) unsigned NOT NULL auto_increment,
+ `guid` varchar(255) NOT NULL default '',
+ `name` int(11) unsigned default NULL,
+ `defaultlocale` varchar(10) NOT NULL default 'en-US',
+ `addontype_id` int(11) unsigned NOT NULL default '0',
+ `status` tinyint(2) unsigned NOT NULL default '0',
+ `higheststatus` tinyint(2) unsigned NOT NULL default '0',
+ `icondata` blob,
+ `icontype` varchar(25) NOT NULL default '',
+ `homepage` int(11) unsigned default NULL,
+ `description` int(11) unsigned default NULL,
+ `summary` int(11) unsigned default NULL,
+ `supportemail` int(11) unsigned DEFAULT NULL,
+ `supporturl` int(11) unsigned DEFAULT NULL,
+ `averagerating` varchar(255) default NULL,
+ `bayesianrating` float NOT NULL default '0',
+ `totalreviews` int(11) unsigned NOT NULL default '0',
+ `weeklydownloads` int(11) unsigned NOT NULL default '0',
+ `totaldownloads` int(11) unsigned NOT NULL default '0',
+ `sharecount` int(11) unsigned NOT NULL,
+ `developercomments` int(11) unsigned default NULL,
+ `inactive` tinyint(1) unsigned NOT NULL default '0',
+ `trusted` tinyint(1) unsigned NOT NULL default '0',
+ `viewsource` tinyint(1) unsigned NOT NULL default '0',
+ `publicstats` tinyint(1) unsigned NOT NULL default '0',
+ `prerelease` tinyint(1) unsigned NOT NULL default '0',
+ `adminreview` tinyint(1) unsigned NOT NULL default '0',
+ `sitespecific` tinyint(1) unsigned NOT NULL default '0',
+ `externalsoftware` tinyint(1) unsigned NOT NULL default '0',
+ `binary` tinyint(1) unsigned NOT NULL default '0',
+ `eula` int(11) unsigned default NULL,
+ `privacypolicy` int(11) unsigned default NULL,
+ `nominationmessage` text,
+ `target_locale` varchar(25) default NULL,
+ `locale_disambiguation` varchar(255) default NULL,
+ `nominationdate` datetime NOT NULL default '0000-00-00 00:00:00',
+ `dev_agreement` tinyint(1) unsigned NOT NULL default '0',
+ `created` datetime NOT NULL default '0000-00-00 00:00:00',
+ `modified` datetime NOT NULL default '0000-00-00 00:00:00',
+ PRIMARY KEY (`id`),
+ KEY `addontype_id` (`addontype_id`),
+ KEY `addons_ibfk_2` (`name`),
+ KEY `addons_ibfk_3` (`homepage`),
+ KEY `addons_ibfk_4` (`supportemail`),
+ KEY `addons_ibfk_5` (`supporturl`),
+ KEY `addons_ibfk_6` (`description`),
+ KEY `addons_ibfk_7` (`summary`),
+ KEY `addons_ibfk_8` (`developercomments`),
+ KEY `addons_ibfk_9` (`eula`),
+ KEY `addons_ibfk_10` (`privacypolicy`),
+ KEY `status` (`status`),
+ KEY `guid` (`guid`),
+ KEY `inactive` (`inactive`),
+ KEY `target_locale` (`target_locale`),
+ KEY `bayesianrating` (`bayesianrating`),
+ KEY `sharecount` (`sharecount`),
+ CONSTRAINT `addons_ibfk_1` FOREIGN KEY (`addontype_id`) REFERENCES `addontypes` (`id`),
+ CONSTRAINT `addons_ibfk_2` FOREIGN KEY (`name`) REFERENCES `translations` (`id`),
+ CONSTRAINT `addons_ibfk_3` FOREIGN KEY (`homepage`) REFERENCES `translations` (`id`),
+ CONSTRAINT `addons_ibfk_4` FOREIGN KEY (`supportemail`) REFERENCES `translations` (`id`),
+ CONSTRAINT `addons_ibfk_5` FOREIGN KEY (`supporturl`) REFERENCES `translations` (`id`),
+ CONSTRAINT `addons_ibfk_6` FOREIGN KEY (`description`) REFERENCES `translations` (`id`),
+ CONSTRAINT `addons_ibfk_7` FOREIGN KEY (`summary`) REFERENCES `translations` (`id`),
+ CONSTRAINT `addons_ibfk_8` FOREIGN KEY (`developercomments`) REFERENCES `translations` (`id`),
+ CONSTRAINT `addons_ibfk_9` FOREIGN KEY (`eula`) REFERENCES `translations` (`id`),
+ CONSTRAINT `addons_ibfk_10` FOREIGN KEY (`privacypolicy`) REFERENCES `translations` (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+
+--
+-- Table structure for table `addons_tags`
+--
+
+DROP TABLE IF EXISTS `addons_tags`;
+CREATE TABLE `addons_tags` (
+ `addon_id` int(11) unsigned NOT NULL default '0',
+ `tag_id` int(11) unsigned NOT NULL default '0',
+ `feature` int(1) unsigned NOT NULL default '0',
+ `feature_locales` varchar(255) default NULL,
+ PRIMARY KEY (`addon_id`,`tag_id`),
+ KEY `tag_id` (`tag_id`),
+ CONSTRAINT `addons_tags_ibfk_3` FOREIGN KEY (`addon_id`) REFERENCES `addons` (`id`),
+ CONSTRAINT `addons_tags_ibfk_4` FOREIGN KEY (`tag_id`) REFERENCES `tags` (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+--
+-- Table structure for table `addons_users`
+--
+
+DROP TABLE IF EXISTS `addons_users`;
+CREATE TABLE `addons_users` (
+ `addon_id` int(11) unsigned NOT NULL default '0',
+ `user_id` int(11) unsigned NOT NULL default '0',
+ `role` tinyint(2) unsigned NOT NULL default '5',
+ `listed` tinyint(1) unsigned NOT NULL default '1',
+ `position` int(11) unsigned NOT NULL default '0',
+ PRIMARY KEY (`addon_id`,`user_id`),
+ KEY `user_id` (`user_id`),
+ CONSTRAINT `addons_users_ibfk_1` FOREIGN KEY (`addon_id`) REFERENCES `addons` (`id`),
+ CONSTRAINT `addons_users_ibfk_2` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+--
+-- Table structure for table `addontypes`
+--
+
+DROP TABLE IF EXISTS `addontypes`;
+CREATE TABLE `addontypes` (
+ `id` int(11) unsigned NOT NULL auto_increment,
+ `created` datetime NOT NULL default '0000-00-00 00:00:00',
+ `modified` datetime NOT NULL default '0000-00-00 00:00:00',
+ PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+--
+-- Table structure for table `applications`
+--
+
+DROP TABLE IF EXISTS `applications`;
+CREATE TABLE `applications` (
+ `id` int(11) unsigned NOT NULL auto_increment,
+ `guid` varchar(255) NOT NULL default '',
+ `name` int(11) unsigned NOT NULL default '0',
+ `icondata` blob,
+ `icontype` varchar(25) NOT NULL default '',
+ `shortname` int(11) unsigned NOT NULL default '0',
+ `supported` tinyint(1) NOT NULL default '0',
+ `created` datetime NOT NULL default '0000-00-00 00:00:00',
+ `modified` datetime NOT NULL default '0000-00-00 00:00:00',
+ PRIMARY KEY (`id`),
+ KEY `applications_ibfk_1` (`name`),
+ KEY `applications_ibfk_2` (`shortname`),
+ KEY `guid` (`guid`),
+ CONSTRAINT `applications_ibfk_1` FOREIGN KEY (`name`) REFERENCES `translations` (`id`),
+ CONSTRAINT `applications_ibfk_2` FOREIGN KEY (`shortname`) REFERENCES `translations` (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+--
+-- Table structure for table `applications_versions`
+--
+
+DROP TABLE IF EXISTS `applications_versions`;
+CREATE TABLE `applications_versions` (
+ `application_id` int(11) unsigned NOT NULL default '0',
+ `version_id` int(11) unsigned NOT NULL default '0',
+ `min` int(11) unsigned NOT NULL default '0',
+ `max` int(11) unsigned NOT NULL default '0',
+ PRIMARY KEY (`application_id`,`version_id`),
+ KEY `version_id` (`version_id`),
+ KEY `min` (`min`),
+ KEY `max` (`max`),
+ CONSTRAINT `applications_versions_ibfk_3` FOREIGN KEY (`application_id`) REFERENCES `applications` (`id`),
+ CONSTRAINT `applications_versions_ibfk_4` FOREIGN KEY (`version_id`) REFERENCES `versions` (`id`),
+ CONSTRAINT `applications_versions_ibfk_5` FOREIGN KEY (`min`) REFERENCES `appversions` (`id`),
+ CONSTRAINT `applications_versions_ibfk_6` FOREIGN KEY (`max`) REFERENCES `appversions` (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+--
+-- Table structure for table `approvals`
+--
+
+DROP TABLE IF EXISTS `approvals`;
+CREATE TABLE `approvals` (
+ `id` int(11) unsigned NOT NULL auto_increment,
+ `created` datetime NOT NULL default '0000-00-00 00:00:00',
+ `reply_to` int(11) unsigned default NULL,
+ `user_id` int(11) unsigned NOT NULL default '0',
+ `reviewtype` varchar(10) NOT NULL default 'pending',
+ `action` int(11) NOT NULL default '0',
+ `addon_id` int(11) unsigned NOT NULL default '0',
+ `file_id` int(11) unsigned NOT NULL default '0',
+ `os` varchar(255) NOT NULL default '',
+ `applications` varchar(255) NOT NULL default '',
+ `comments` text NOT NULL,
+ PRIMARY KEY (`id`),
+ KEY `user_id` (`user_id`),
+ KEY `file_id` (`file_id`),
+ KEY `addon_id` (`addon_id`),
+ KEY `reply_to` (`reply_to`),
+ CONSTRAINT `approvals_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`),
+ CONSTRAINT `approvals_ibfk_2` FOREIGN KEY (`file_id`) REFERENCES `files` (`id`),
+ CONSTRAINT `approvals_ibfk_3` FOREIGN KEY (`addon_id`) REFERENCES `addons` (`id`),
+ CONSTRAINT `approvals_ibfk_4` FOREIGN KEY (`reply_to`) REFERENCES `approvals` (`id`) ON DELETE CASCADE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+--
+-- Table structure for table `appversions`
+--
+
+DROP TABLE IF EXISTS `appversions`;
+CREATE TABLE `appversions` (
+ `id` int(11) unsigned NOT NULL auto_increment,
+ `application_id` int(11) unsigned NOT NULL default '0',
+ `version` varchar(255) NOT NULL default '',
+ `created` datetime NOT NULL default '0000-00-00 00:00:00',
+ `modified` datetime NOT NULL default '0000-00-00 00:00:00',
+ PRIMARY KEY (`id`),
+ KEY `application_id` (`application_id`),
+ KEY `version` (`version`),
+ CONSTRAINT `appversions_ibfk_1` FOREIGN KEY (`application_id`) REFERENCES `applications` (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+--
+-- Table structure for table `api_auth_tokens`
+--
+
+DROP TABLE IF EXISTS `api_auth_tokens`;
+CREATE TABLE `api_auth_tokens` (
+ `id` int(11) unsigned NOT NULL auto_increment,
+ `user_id` int(11) unsigned NOT NULL default '0',
+ `token` varchar(64) NOT NULL,
+ `user_agent_hash` varchar(64) NOT NULL,
+ `user_profile_hash` varchar(64) NOT NULL,
+ `created` datetime NOT NULL default '0000-00-00 00:00:00',
+ `modified` datetime NOT NULL default '0000-00-00 00:00:00',
+ PRIMARY KEY (`id`),
+ KEY `user_id` (`user_id`),
+ KEY `token` (`token`),
+ CONSTRAINT `api_auth_tokens_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+--
+-- Table structure for table `blapps`
+--
+
+DROP TABLE IF EXISTS `blapps`;
+CREATE TABLE `blapps` (
+ `id` int(11) unsigned NOT NULL auto_increment,
+ `blitem_id` int(11) unsigned NOT NULL default '0',
+ `guid` varchar(255) default NULL,
+ `min` varchar(255) default NULL,
+ `max` varchar(255) default NULL,
+ `created` datetime NOT NULL default '0000-00-00 00:00:00',
+ `modified` datetime NOT NULL default '0000-00-00 00:00:00',
+ PRIMARY KEY (`id`),
+ KEY `blitem_id` (`blitem_id`),
+ KEY `guid` (`guid`),
+ CONSTRAINT `blapps_ibfk_1` FOREIGN KEY (`blitem_id`) REFERENCES `blitems` (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+--
+-- Table structure for table `blitems`
+--
+
+DROP TABLE IF EXISTS `blitems`;
+CREATE TABLE `blitems` (
+ `id` int(11) unsigned NOT NULL auto_increment,
+ `guid` varchar(255) NOT NULL default '',
+ `min` varchar(255) default NULL,
+ `max` varchar(255) default NULL,
+ `os` varchar(255) default NULL,
+ `created` datetime NOT NULL default '0000-00-00 00:00:00',
+ `modified` datetime NOT NULL default '0000-00-00 00:00:00',
+ PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+--
+-- Table structure for table `blplugins`
+--
+
+DROP TABLE IF EXISTS `blplugins`;
+CREATE TABLE `blplugins` (
+ `id` int(11) unsigned NOT NULL auto_increment,
+ `name` varchar(255) default NULL,
+ `guid` varchar(255) default NULL,
+ `min` varchar(255) default NULL,
+ `max` varchar(255) NOT NULL default '',
+ `os` varchar(255) default NULL,
+ `xpcomabi` varchar(255) default NULL,
+ `description` varchar(255) default NULL,
+ `filename` varchar(255) default NULL,
+ `created` datetime NOT NULL default '0000-00-00 00:00:00',
+ `modified` datetime NOT NULL default '0000-00-00 00:00:00',
+ PRIMARY KEY (`id`),
+ KEY `guid` (`guid`(128),`min`(128))
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+--
+-- Table structure for table `blog`
+--
+
+DROP TABLE IF EXISTS `blog`;
+CREATE TABLE `blog` (
+ `id` int(11) unsigned NOT NULL auto_increment,
+ `user_id` int(11) unsigned NOT NULL default '0',
+ `title` int(11) unsigned NOT NULL default '0',
+ `body` int(11) unsigned NOT NULL default '0',
+ `hidden` tinyint(1) NOT NULL default '0',
+ `created` datetime NOT NULL default '0000-00-00 00:00:00',
+ PRIMARY KEY (`id`),
+ KEY `user_id` (`user_id`),
+ KEY `blog_ibfk_2` (`title`),
+ KEY `blog_ibfk_3` (`body`),
+ CONSTRAINT `blog_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`),
+ CONSTRAINT `blog_ibfk_2` FOREIGN KEY (`title`) REFERENCES `translations` (`id`),
+ CONSTRAINT `blog_ibfk_3` FOREIGN KEY (`body`) REFERENCES `translations` (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+--
+-- Table structure for table `cache`
+--
+
+DROP TABLE IF EXISTS `cache`;
+CREATE TABLE `cache` (
+ `id` varchar(32) NOT NULL default '',
+ `data` mediumblob NOT NULL,
+ `expire` datetime NOT NULL default '0000-00-00 00:00:00',
+ PRIMARY KEY (`id`)
+) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='Cake Cache table for query caches';
+
+--
+-- Table structure for table `cake_sessions`
+--
+
+DROP TABLE IF EXISTS `cake_sessions`;
+CREATE TABLE `cake_sessions` (
+ `id` varchar(255) NOT NULL default '',
+ `data` text,
+ `expires` int(11) default NULL,
+ PRIMARY KEY (`id`),
+ KEY `expires` (`expires`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+--
+-- Table structure for table `cannedresponses`
+--
+
+DROP TABLE IF EXISTS `cannedresponses`;
+CREATE TABLE `cannedresponses` (
+ `id` int(11) unsigned NOT NULL auto_increment,
+ `name` int(11) unsigned NOT NULL default '0',
+ `response` int(11) unsigned NOT NULL default '0',
+ `created` datetime NOT NULL default '0000-00-00 00:00:00',
+ `modified` datetime NOT NULL default '0000-00-00 00:00:00',
+ PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+--
+-- Table structure for table `config`
+--
+
+DROP TABLE IF EXISTS `config`;
+CREATE TABLE `config` (
+ `key` varchar(255) NOT NULL default '',
+ `value` text NOT NULL,
+ PRIMARY KEY (`key`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+
+INSERT INTO `config` ( `key` , `value` )
+VALUES ('site_notice', ''),
+('submissions_disabled', '0'),
+('queues_disabled', '0'),
+('search_disabled', '0'),
+('api_disabled', '0'),
+('stats_updating', '0'),
+('firefox_notice_version', ''),
+('firefox_notice_url', ''),
+('stats_disabled', '0');
+
+-- --------------------------------------------------------
+
+--
+-- Table structure for table `download_counts`
+--
+
+DROP TABLE IF EXISTS `download_counts`;
+CREATE TABLE `download_counts` (
+ `id` int(10) unsigned NOT NULL auto_increment,
+ `addon_id` int(10) unsigned NOT NULL default '0',
+ `count` int(10) unsigned NOT NULL default '0',
+ `date` date NOT NULL default '0000-00-00',
+ PRIMARY KEY (`id`),
+ KEY `addon_id` (`addon_id`),
+ KEY `count` (`count`),
+ KEY `date` (`date`),
+ CONSTRAINT `download_counts_ibfk_1` FOREIGN KEY (`addon_id`) REFERENCES `addons` (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+
+--
+-- Table structure for table `downloads`
+--
+
+DROP TABLE IF EXISTS `downloads`;
+CREATE TABLE `downloads` (
+ `id` int(11) unsigned NOT NULL auto_increment,
+ `file_id` int(11) unsigned default NULL,
+ `addon_id` int(11) unsigned default NULL,
+ `userip` varchar(255) NOT NULL default '',
+ `useragent` varchar(255) NOT NULL default '',
+ `counted` tinyint(1) unsigned NOT NULL default '0',
+ `created` datetime NOT NULL default '0000-00-00 00:00:00',
+ PRIMARY KEY (`id`),
+ KEY `file_id` (`file_id`),
+ KEY `addon_id` (`addon_id`),
+ KEY `date_created` (`created`,`addon_id`),
+ KEY `date_counted` (`counted`,`addon_id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+--
+-- Table structure for table `downloads_tmp`
+--
+
+DROP TABLE IF EXISTS `downloads_tmp`;
+CREATE TABLE `downloads_tmp` (
+ `id` int(11) unsigned NOT NULL auto_increment,
+ `file_id` int(11) unsigned default NULL,
+ `addon_id` int(11) unsigned default NULL,
+ `userip` varchar(255) NOT NULL default '',
+ `useragent` varchar(255) NOT NULL default '',
+ `counted` tinyint(1) unsigned NOT NULL default '0',
+ `created` datetime NOT NULL default '0000-00-00 00:00:00',
+ PRIMARY KEY (`id`),
+ KEY `file_id` (`file_id`),
+ KEY `addon_id` (`addon_id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+--
+-- Table structure for table `editor_subscriptions`
+--
+
+DROP TABLE IF EXISTS `editor_subscriptions`;
+CREATE TABLE `editor_subscriptions` (
+ `user_id` int(11) unsigned NOT NULL,
+ `addon_id` int(11) unsigned NOT NULL,
+ PRIMARY KEY (`user_id`,`addon_id`),
+ KEY `user_id` (`user_id`),
+ KEY `addon_id` (`addon_id`),
+ CONSTRAINT `editor_subscriptions_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE,
+ CONSTRAINT `editor_subscriptions_ibfk_2` FOREIGN KEY (`addon_id`) REFERENCES `addons` (`id`) ON DELETE CASCADE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Editor subscriptions for add-on updates';
+
+--
+-- Table structure for table `eventlog`
+--
+
+DROP TABLE IF EXISTS `eventlog`;
+CREATE TABLE `eventlog` (
+ `id` int(11) unsigned NOT NULL auto_increment,
+ `type` varchar(20) NOT NULL default '',
+ `action` varchar(40) NOT NULL default '',
+ `field` varchar(20) default NULL,
+ `user_id` int(11) unsigned NOT NULL default '0',
+ `changed_id` int(11) unsigned NOT NULL default '0',
+ `added` varchar(255) default NULL,
+ `removed` varchar(255) default NULL,
+ `notes` text,
+ `created` datetime NOT NULL default '0000-00-00 00:00:00',
+ PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+
+--
+-- Table structure for table `facebook_data`
+--
+
+DROP TABLE IF EXISTS `facebook_data`;
+CREATE TABLE `facebook_data` (
+ `trait` varchar(255) NOT NULL default '',
+ `count_current` int(11) unsigned NOT NULL default '0',
+ `count_ever` int(11) unsigned NOT NULL default '0',
+ PRIMARY KEY (`trait`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+--
+-- Table structure for table `facebook_detected`
+--
+
+DROP TABLE IF EXISTS `facebook_detected`;
+CREATE TABLE `facebook_detected` (
+ `id` int(11) unsigned NOT NULL auto_increment,
+ `fb_user` int(11) unsigned NOT NULL default '0',
+ `addon_guid` varchar(255) NOT NULL default '',
+ `disabled` tinyint(1) unsigned NOT NULL default '0',
+ `sequence` int(11) unsigned NOT NULL default '0',
+ `created` datetime NOT NULL default '0000-00-00 00:00:00',
+ PRIMARY KEY (`id`),
+ KEY `fb_user` (`fb_user`),
+ KEY `addon_guid` (`addon_guid`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+--
+-- Table structure for table `facebook_favorites`
+--
+
+DROP TABLE IF EXISTS `facebook_favorites`;
+CREATE TABLE `facebook_favorites` (
+ `id` int(11) unsigned NOT NULL auto_increment,
+ `fb_user` int(11) unsigned NOT NULL default '0',
+ `addon_id` int(11) unsigned NOT NULL default '0',
+ `imported` tinyint(1) unsigned NOT NULL default '0',
+ `created` datetime NOT NULL default '0000-00-00 00:00:00',
+ PRIMARY KEY (`id`),
+ KEY `fb_user` (`fb_user`),
+ KEY `addon_id` (`addon_id`),
+ CONSTRAINT `facebook_favorites_ibfk_1` FOREIGN KEY (`addon_id`) REFERENCES `addons` (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+--
+-- Table structure for table `facebook_sessions`
+--
+
+DROP TABLE IF EXISTS `facebook_sessions`;
+CREATE TABLE `facebook_sessions` (
+ `session_key` varchar(255) NOT NULL default '',
+ `fb_user` int(11) unsigned NOT NULL default '0',
+ `created` datetime NOT NULL default '0000-00-00 00:00:00',
+ PRIMARY KEY (`session_key`),
+ KEY `fb_user` (`fb_user`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+--
+-- Table structure for table `facebook_users`
+--
+
+DROP TABLE IF EXISTS `facebook_users`;
+CREATE TABLE `facebook_users` (
+ `fb_user` int(11) unsigned NOT NULL default '0',
+ `added` datetime NOT NULL default '0000-00-00 00:00:00',
+ `removed` datetime NOT NULL default '0000-00-00 00:00:00',
+ `lastactivity` datetime NOT NULL default '0000-00-00 00:00:00',
+ PRIMARY KEY (`fb_user`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+--
+-- Table structure for table `favorites`
+--
+
+DROP TABLE IF EXISTS `favorites`;
+CREATE TABLE `favorites` (
+ `id` int(11) unsigned NOT NULL auto_increment,
+ `user_id` int(11) unsigned NOT NULL default '0',
+ `addon_id` int(11) unsigned NOT NULL default '0',
+ `favorite` tinyint(1) unsigned NOT NULL default '0',
+ `reviewfavorite` tinyint(1) unsigned NOT NULL default '0',
+ `created` datetime NOT NULL default '0000-00-00 00:00:00',
+ `modified` datetime NOT NULL default '0000-00-00 00:00:00',
+ PRIMARY KEY (`id`),
+ KEY `addon_id` (`addon_id`),
+ KEY `user_id` (`user_id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+--
+-- Table structure for table `features`
+--
+
+DROP TABLE IF EXISTS `features`;
+CREATE TABLE `features` (
+ `id` int(11) unsigned NOT NULL auto_increment,
+ `addon_id` int(11) unsigned NOT NULL default '0',
+ `start` datetime NOT NULL default '0000-00-00 00:00:00',
+ `end` datetime NOT NULL default '0000-00-00 00:00:00',
+ `created` datetime NOT NULL default '0000-00-00 00:00:00',
+ `modified` datetime NOT NULL default '0000-00-00 00:00:00',
+ `locale` varchar(10) default NULL,
+ `application_id` int(11) unsigned NOT NULL default '0',
+ PRIMARY KEY (`id`),
+ KEY `addon_id` (`addon_id`),
+ KEY `application_id` (`application_id`),
+ CONSTRAINT `features_ibfk_1` FOREIGN KEY (`addon_id`) REFERENCES `addons` (`id`),
+ CONSTRAINT `features_ibfk_2` FOREIGN KEY (`application_id`) REFERENCES `applications` (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+--
+-- Table structure for table `files`
+--
+
+DROP TABLE IF EXISTS `files`;
+CREATE TABLE `files` (
+ `id` int(11) unsigned NOT NULL auto_increment,
+ `version_id` int(11) unsigned NOT NULL default '0',
+ `platform_id` int(11) unsigned NOT NULL default '0',
+ `filename` varchar(255) NOT NULL default '',
+ `size` int(11) unsigned NOT NULL default '0',
+ `hash` varchar(255) default NULL,
+ `codereview` tinyint(1) unsigned NOT NULL default '0',
+ `status` tinyint(2) unsigned NOT NULL default '0',
+ `datestatuschanged` datetime NOT NULL default '0000-00-00 00:00:00',
+ `created` datetime NOT NULL default '0000-00-00 00:00:00',
+ `modified` datetime NOT NULL default '0000-00-00 00:00:00',
+ PRIMARY KEY (`id`),
+ KEY `version_id` (`version_id`),
+ KEY `platform_id` (`platform_id`),
+ KEY `status` (`status`),
+ CONSTRAINT `files_ibfk_1` FOREIGN KEY (`version_id`) REFERENCES `versions` (`id`),
+ CONSTRAINT `files_ibfk_2` FOREIGN KEY (`platform_id`) REFERENCES `platforms` (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+--
+-- Table structure for table `global_stats`
+--
+
+DROP TABLE IF EXISTS `global_stats`;
+CREATE TABLE `global_stats` (
+ `id` int(11) unsigned NOT NULL auto_increment,
+ `name` varchar(255) NOT NULL default '',
+ `count` int(10) unsigned NOT NULL default '0',
+ `modified` datetime NOT NULL default '0000-00-00 00:00:00',
+ UNIQUE KEY `name` (`name`),
+ PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+--
+-- Table structure for table `groups`
+--
+
+DROP TABLE IF EXISTS `groups`;
+CREATE TABLE `groups` (
+ `id` int(11) unsigned NOT NULL auto_increment,
+ `name` varchar(255) NOT NULL default '',
+ `rules` text,
+ `created` datetime NOT NULL default '0000-00-00 00:00:00',
+ `modified` datetime NOT NULL default '0000-00-00 00:00:00',
+ PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+--
+-- Table structure for table `groups_users`
+--
+
+DROP TABLE IF EXISTS `groups_users`;
+CREATE TABLE `groups_users` (
+ `group_id` int(11) unsigned NOT NULL default '0',
+ `user_id` int(11) unsigned NOT NULL default '0',
+ PRIMARY KEY (`group_id`,`user_id`),
+ KEY `user_id` (`user_id`),
+ CONSTRAINT `groups_users_ibfk_3` FOREIGN KEY (`group_id`) REFERENCES `groups` (`id`) ON DELETE CASCADE,
+ CONSTRAINT `groups_users_ibfk_4` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+--
+-- Table structure for table `licenses`
+--
+
+DROP TABLE IF EXISTS `licenses`;
+CREATE TABLE `licenses` (
+ `id` int(11) unsigned NOT NULL auto_increment,
+ `name` int(1) NOT NULL default '-1',
+ `text` int(11) unsigned default NULL,
+ `created` datetime NOT NULL default '0000-00-00 00:00:00',
+ `modified` datetime NOT NULL default '0000-00-00 00:00:00',
+ PRIMARY KEY (`id`),
+ KEY `text` (`text`),
+ CONSTRAINT `licenses_ibfk_1` FOREIGN KEY (`text`) REFERENCES `translations` (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+--
+-- Table structure for table `logs_parsed`
+--
+
+DROP TABLE IF EXISTS `logs_parsed`;
+CREATE TABLE `logs_parsed` (
+ `id` int(10) unsigned NOT NULL auto_increment,
+ `name` varchar(255) NOT NULL default '',
+ `geo` varchar(10) NOT NULL default '',
+ `downloads_done` tinyint(1) unsigned NOT NULL default '0',
+ `updatepings_done` tinyint(1) unsigned NOT NULL default '0',
+ `collections_done` tinyint(1) unsigned NOT NULL default '0',
+ PRIMARY KEY (`id`),
+ UNIQUE KEY `name` (`name`, `geo`)
+) ENGINE=MyISAM DEFAULT CHARSET=utf8;
+
+--
+-- Table structure for table `platforms`
+--
+
+DROP TABLE IF EXISTS `platforms`;
+CREATE TABLE `platforms` (
+ `id` int(11) unsigned NOT NULL auto_increment,
+ `name` int(11) unsigned NOT NULL default '0',
+ `shortname` int(11) unsigned NOT NULL default '0',
+ `icondata` blob,
+ `icontype` varchar(25) NOT NULL default '',
+ `created` datetime NOT NULL default '0000-00-00 00:00:00',
+ `modified` datetime NOT NULL default '0000-00-00 00:00:00',
+ PRIMARY KEY (`id`),
+ KEY `platforms_ibfk_1` (`name`),
+ KEY `platforms_ibfk_2` (`shortname`),
+ CONSTRAINT `platforms_ibfk_1` FOREIGN KEY (`name`) REFERENCES `translations` (`id`),
+ CONSTRAINT `platforms_ibfk_2` FOREIGN KEY (`shortname`) REFERENCES `translations` (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+--
+-- Table structure for table `previews`
+--
+
+DROP TABLE IF EXISTS `previews`;
+CREATE TABLE `previews` (
+ `id` int(11) unsigned NOT NULL auto_increment,
+ `addon_id` int(11) unsigned NOT NULL default '0',
+ `filedata` mediumblob,
+ `filetype` varchar(25) NOT NULL default '',
+ `thumbdata` blob,
+ `thumbtype` varchar(25) NOT NULL default '',
+ `caption` int(11) unsigned default NULL,
+ `highlight` tinyint(1) unsigned NOT NULL default '0',
+ `created` datetime NOT NULL default '0000-00-00 00:00:00',
+ `modified` datetime NOT NULL default '0000-00-00 00:00:00',
+ PRIMARY KEY (`id`),
+ KEY `addon_id` (`addon_id`),
+ KEY `previews_ibfk_2` (`caption`),
+ CONSTRAINT `previews_ibfk_1` FOREIGN KEY (`addon_id`) REFERENCES `addons` (`id`),
+ CONSTRAINT `previews_ibfk_2` FOREIGN KEY (`caption`) REFERENCES `translations` (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+--
+-- Table structure for table `reviewratings`
+--
+
+DROP TABLE IF EXISTS `reviewratings`;
+CREATE TABLE `reviewratings` (
+ `review_id` int(11) unsigned NOT NULL default '0',
+ `user_id` int(11) unsigned NOT NULL default '0',
+ `helpful` tinyint(1) unsigned NOT NULL default '0',
+ `created` datetime NOT NULL default '0000-00-00 00:00:00',
+ PRIMARY KEY (`review_id`,`user_id`),
+ KEY `user_id` (`user_id`),
+ CONSTRAINT `reviewratings_ibfk_1` FOREIGN KEY (`review_id`) REFERENCES `reviews` (`id`),
+ CONSTRAINT `reviewratings_ibfk_2` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+--
+-- Table structure for table `reviews`
+--
+
+DROP TABLE IF EXISTS `reviews`;
+CREATE TABLE `reviews` (
+ `id` int(11) unsigned NOT NULL auto_increment,
+ `version_id` int(11) unsigned NOT NULL default '0',
+ `user_id` int(11) unsigned NOT NULL default '0',
+ `reply_to` int(11) unsigned default NULL,
+ `rating` tinyint(3) unsigned default NULL,
+ `title` int(11) unsigned NOT NULL default '0',
+ `body` int(11) unsigned NOT NULL default '0',
+ `editorreview` tinyint(1) unsigned NOT NULL default '0',
+ `flag` tinyint(1) unsigned NOT NULL default '0',
+ `sandbox` tinyint(1) unsigned NOT NULL default '0',
+ `created` datetime NOT NULL default '0000-00-00 00:00:00',
+ `modified` datetime NOT NULL default '0000-00-00 00:00:00',
+ PRIMARY KEY (`id`),
+ UNIQUE KEY `reply_to` (`reply_to`),
+ UNIQUE KEY `one_review_per_user` (`version_id`,`user_id`,`reply_to`),
+ KEY `version_id` (`version_id`),
+ KEY `reviews_ibfk_2` (`user_id`),
+ KEY `reviews_ibfk_3` (`title`),
+ KEY `reviews_ibfk_4` (`body`),
+ CONSTRAINT `reviews_ibfk_1` FOREIGN KEY (`version_id`) REFERENCES `versions` (`id`),
+ CONSTRAINT `reviews_ibfk_2` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`),
+ CONSTRAINT `reviews_ibfk_3` FOREIGN KEY (`title`) REFERENCES `translations` (`id`),
+ CONSTRAINT `reviews_ibfk_4` FOREIGN KEY (`body`) REFERENCES `translations` (`id`),
+ CONSTRAINT `reviews_reply` FOREIGN KEY (`reply_to`) REFERENCES `reviews` (`id`) ON DELETE CASCADE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+--
+-- Table structure for table `reviews_moderation_flags`
+--
+DROP TABLE IF EXISTS `reviews_moderation_flags`;
+CREATE TABLE `reviews_moderation_flags` (
+ `id` int(11) NOT NULL auto_increment,
+ `review_id` int(11) unsigned NOT NULL default '0',
+ `user_id` int(11) unsigned NOT NULL default '0',
+ `flag_name` varchar(64) NOT NULL default 'review_flag_reason_other',
+ `flag_notes` varchar(100) NOT NULL default '',
+ `created` datetime NOT NULL default '0000-00-00 00:00:00',
+ `modified` datetime NOT NULL default '0000-00-00 00:00:00',
+ PRIMARY KEY (`id`),
+ UNIQUE KEY `index_review_user` (`review_id`,`user_id`),
+ KEY `index_user` (`user_id`),
+ KEY `index_review` (`review_id`),
+ KEY `index_modified` (`modified`),
+ CONSTRAINT `reviews_moderation_flags_ibfk_1` FOREIGN KEY (`review_id`) REFERENCES `reviews` (`id`),
+ CONSTRAINT `reviews_moderation_flags_ibfk_2` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+--
+-- Table structure for table `stats_share_counts`
+--
+
+DROP TABLE IF EXISTS `stats_share_counts`;
+CREATE TABLE `stats_share_counts` (
+ `id` int(11) unsigned NOT NULL auto_increment,
+ `addon_id` int(11) unsigned NOT NULL default '0',
+ `count` int(11) unsigned NOT NULL default '0',
+ `service` varchar(128),
+ `date` date NOT NULL default '0000-00-00',
+ PRIMARY KEY (`id`),
+ KEY `addon_id` (`addon_id`),
+ KEY `count` (`count`),
+ KEY `date` (`date`),
+ UNIQUE KEY `one_count_per_addon_service_and_date` (`addon_id`,`service`,`date`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+--
+-- Table structure for table `tags`
+--
+
+DROP TABLE IF EXISTS `tags`;
+CREATE TABLE `tags` (
+ `id` int(11) unsigned NOT NULL auto_increment,
+ `name` int(11) unsigned default NULL,
+ `description` int(11) unsigned default NULL,
+ `addontype_id` int(11) unsigned NOT NULL default '0',
+ `application_id` int(11) unsigned default NULL,
+ `created` datetime NOT NULL default '0000-00-00 00:00:00',
+ `modified` datetime NOT NULL default '0000-00-00 00:00:00',
+ `count` int(11) NOT NULL DEFAULT '0',
+ `weight` int(11) NOT NULL DEFAULT '0',
+ PRIMARY KEY (`id`),
+ KEY `addontype_id` (`addontype_id`),
+ KEY `application_id` (`application_id`),
+ KEY `tags_ibfk_3` (`name`),
+ KEY `tags_ibfk_4` (`description`),
+ CONSTRAINT `tags_ibfk_1` FOREIGN KEY (`addontype_id`) REFERENCES `addontypes` (`id`),
+ CONSTRAINT `tags_ibfk_2` FOREIGN KEY (`application_id`) REFERENCES `applications` (`id`),
+ CONSTRAINT `tags_ibfk_3` FOREIGN KEY (`name`) REFERENCES `translations` (`id`),
+ CONSTRAINT `tags_ibfk_4` FOREIGN KEY (`description`) REFERENCES `translations` (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+--
+-- Table structure for table `translations`
+--
+
+DROP TABLE IF EXISTS `translations`;
+CREATE TABLE `translations` (
+ `id` int(11) unsigned NOT NULL default '0',
+ `locale` varchar(10) NOT NULL default '',
+ `localized_string` text,
+ `created` datetime default NULL,
+ `modified` datetime default NULL,
+ PRIMARY KEY (`id`,`locale`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+--
+-- Table structure for table `translations_seq`
+--
+
+DROP TABLE IF EXISTS `translations_seq`;
+CREATE TABLE `translations_seq` (
+ `id` int(11) NOT NULL default '0'
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+--
+-- Table structure for table `update_counts`
+--
+
+DROP TABLE IF EXISTS `update_counts`;
+CREATE TABLE `update_counts` (
+ `id` int(11) unsigned NOT NULL auto_increment,
+ `addon_id` int(11) unsigned NOT NULL default '0',
+ `count` int(11) unsigned NOT NULL default '0',
+ `version` text,
+ `status` text,
+ `application` text,
+ `os` text,
+ `date` date NOT NULL default '0000-00-00',
+ PRIMARY KEY (`id`),
+ KEY `addon_id` (`addon_id`),
+ KEY `count` (`count`),
+ KEY `date` (`date`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+-- --------------------------------------------------------
+
+--
+-- Table structure for table `users`
+--
+
+DROP TABLE IF EXISTS `users`;
+CREATE TABLE `users` (
+ `id` int(11) unsigned NOT NULL auto_increment,
+ `email` varchar(255) NULL default '',
+ `password` varchar(255) NOT NULL default '',
+ `firstname` varchar(255) NOT NULL default '',
+ `lastname` varchar(255) NOT NULL default '',
+ `nickname` varchar(255) NOT NULL default '',
+ `bio` int(11) UNSIGNED default NULL,
+ `emailhidden` tinyint(1) unsigned NOT NULL default '0',
+ `sandboxshown` tinyint(1) unsigned NOT NULL default '0',
+ `homepage` varchar(255) default NULL,
+ `display_collections` tinyint(1) unsigned NOT NULL default '0',
+ `display_collections_fav` tinyint(1) unsigned NOT NULL default '0',
+ `confirmationcode` varchar(255) NOT NULL default '',
+ `resetcode` varchar(255) NOT NULL default '',
+ `resetcode_expires` datetime NOT NULL default '0000-00-00 00:00:00',
+ `notifycompat` tinyint(1) unsigned NOT NULL default '1',
+ `notifyevents` tinyint(1) unsigned NOT NULL default '1',
+ `created` datetime NOT NULL default '0000-00-00 00:00:00',
+ `modified` datetime NOT NULL default '0000-00-00 00:00:00',
+ `notes` text,
+ PRIMARY KEY (`id`),
+ UNIQUE KEY `email` (`email`),
+ KEY `unconfirmed` (`created`,`confirmationcode`),
+ KEY `notifycompat` (`notifycompat`),
+ KEY `notifyevents` (`notifyevents`),
+ KEY `bio` (`bio`),
+ CONSTRAINT `users_ibfk_1` FOREIGN KEY (`bio`) REFERENCES `translations` (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+--
+-- Table structure for table `versions`
+--
+
+DROP TABLE IF EXISTS `versions`;
+CREATE TABLE `versions` (
+ `id` int(11) unsigned NOT NULL auto_increment,
+ `addon_id` int(11) unsigned NOT NULL default '0',
+ `license_id` int(11) unsigned default NULL,
+ `version` varchar(255) NOT NULL default '',
+ `approvalnotes` text,
+ `releasenotes` int(11) unsigned default NULL,
+ `created` datetime NOT NULL default '0000-00-00 00:00:00',
+ `modified` datetime NOT NULL default '0000-00-00 00:00:00',
+ PRIMARY KEY (`id`),
+ KEY `addon_id` (`addon_id`),
+ KEY `versions_ibfk_2` (`releasenotes`),
+ KEY `license_id` (`license_id`),
+ CONSTRAINT `versions_ibfk_1` FOREIGN KEY (`addon_id`) REFERENCES `addons` (`id`),
+ CONSTRAINT `versions_ibfk_2` FOREIGN KEY (`releasenotes`) REFERENCES `translations` (`id`),
+ CONSTRAINT `versions_ibfk_3` FOREIGN KEY (`license_id`) REFERENCES `licenses` (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+--
+-- Table structure for table `text_search_summary`
+-- This materialized view maintains a indexed summary of the text data in an addon to make search faster
+--
+
+DROP TABLE IF EXISTS `text_search_summary`;
+CREATE TABLE `text_search_summary` (
+ `id` int(11) NOT NULL,
+ `locale` varchar(10) NOT NULL,
+ `addontype` int(11) NOT NULL,
+ `status` int(11) NOT NULL,
+ `inactive` int(11) NOT NULL,
+ `averagerating` varchar(255),
+ `weeklydownloads` int(11) UNSIGNED ,
+ `name` text,
+ `summary` text,
+ `description` text,
+ FULLTEXT KEY `name` (`name`,`summary`,`description`)
+) ENGINE=MyISAM DEFAULT CHARSET=utf8;
+
+--
+-- Table structure for table `version_summary`
+-- This materialized view maintains a summary of information about the most recently created version of an addon
+--
+
+DROP TABLE IF EXISTS `versions_summary`;
+CREATE TABLE `versions_summary` (
+ `addon_id` int(11) NOT NULL,
+ `version_id` int(11) NOT NULL,
+ `application_id` int(11),
+ `created` DATETIME NOT NULL,
+ `modified`DATETIME NOT NULL,
+ `min` int(11) unsigned,
+ `max` int(11) unsigned,
+ INDEX (addon_id)
+) ENGINE=MyISAM DEFAULT CHARSET=utf8;
+
+--
+-- Table structure for table `collections_search_summary`
+-- This materialized view maintains a indexed summary of the text data in a collection to make search faster
+--
+
+DROP TABLE IF EXISTS `collections_search_summary`;
+CREATE TABLE `collections_search_summary` (
+ `id` int(11) NOT NULL,
+ `locale` varchar(10) NOT NULL,
+ `name` text,
+ `description` text,
+ FULLTEXT KEY `name` (`name`,`description`)
+) ENGINE=MyISAM DEFAULT CHARSET=utf8;
+
+--
+-- Table structure for table `tshirt_requests`
+-- Used to store addresses of developers who claimed a T-shirt in
+-- T-Shirt promotion.
+--
+
+DROP TABLE IF EXISTS `tshirt_requests`;
+CREATE TABLE `tshirt_requests` (
+ `id` int(11) unsigned NOT NULL auto_increment,
+ `user_id` int(11) unsigned NOT NULL,
+ `full_name` varchar(255) NOT NULL,
+ `email` varchar(255) NOT NULL,
+ `country` varchar(255) NOT NULL,
+ `address` varchar(255) NOT NULL,
+ `address2` varchar(255) NOT NULL,
+ `city` varchar(255) NOT NULL,
+ `region_province` varchar(255) NOT NULL,
+ `state` varchar(255) NOT NULL,
+ `zip_postal_code` varchar(255) NOT NULL,
+ `telephone` varchar(255) NOT NULL,
+ `tshirt_size` varchar(10) NOT NULL,
+ `comment` varchar(1000) NOT NULL,
+ KEY `user_id` (`user_id`),
+ PRIMARY KEY `id` (`id`),
+ CONSTRAINT `tshirt_requests_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 ;
+
+
+DROP TABLE IF EXISTS `collections`;
+CREATE TABLE `collections` (
+ `id` int(11) unsigned NOT NULL auto_increment,
+ `uuid` char(36) NOT NULL default '',
+ `name` int(11) unsigned NOT NULL,
+ `collection_type` int(11) unsigned NOT NULL DEFAULT '0',
+ `icondata` blob,
+ `icontype` varchar(25) NOT NULL default '',
+ `nickname` varchar(30) NULL,
+ `description` int(11) unsigned NOT NULL,
+ `access` tinyint(1) NOT NULL DEFAULT '0',
+ `listed` tinyint(1) NOT NULL DEFAULT '1',
+ `password` varchar(255) NOT NULL,
+ `subscribers` int(11) unsigned NOT NULL DEFAULT '0',
+ `created` datetime NOT NULL default '0000-00-00 00:00:00',
+ `modified` datetime NOT NULL default '0000-00-00 00:00:00',
+ `downloads` int(11) unsigned NOT NULL DEFAULT '0',
+ `application_id` int(10) unsigned default NULL,
+ `weekly_subscribers` int(11) unsigned NOT NULL default '0',
+ `monthly_subscribers` int(11) unsigned NOT NULL default '0',
+ `addonCount` int(11) unsigned NOT NULL default '0',
+ PRIMARY KEY `id` (`id`),
+ UNIQUE KEY `uuid` (`uuid`),
+ UNIQUE KEY `nickname` (`nickname`),
+ KEY (`listed`),
+ KEY `application_id` (`application_id`),
+ KEY `name` (`name`),
+ KEY `description` (`description`),
+ CONSTRAINT `collections_ibfk_1` FOREIGN KEY (`application_id`) REFERENCES `applications` (`id`),
+ CONSTRAINT `collections_ibfk_2` FOREIGN KEY (`name`) REFERENCES `translations` (`id`),
+ CONSTRAINT `collections_ibfk_3` FOREIGN KEY (`description`) REFERENCES `translations` (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 ;
+
+DROP TABLE IF EXISTS `addons_collections`;
+CREATE TABLE `addons_collections` (
+ `addon_id` int(11) unsigned NOT NULL ,
+ `collection_id` int(11) unsigned NOT NULL ,
+ `user_id` int(11) unsigned default NULL,
+ `added` datetime NOT NULL default '0000-00-00 00:00:00',
+ `modified` datetime NOT NULL default '0000-00-00 00:00:00',
+ `category` tinyint(4) unsigned default NULL COMMENT 'for interactive collections template',
+ `comments` int(11) unsigned default NULL,
+ `downloads` int(11) unsigned NOT NULL DEFAULT '0',
+ PRIMARY KEY ( `addon_id` , `collection_id` ),
+ KEY `addon_id` (`addon_id`),
+ KEY `user_id` (`user_id`),
+ KEY `collection_id` (`collection_id`),
+ KEY `comments` (`comments`),
+ CONSTRAINT `addons_collections_ibfk_1` FOREIGN KEY (`addon_id`) REFERENCES `addons` (`id`),
+ CONSTRAINT `addons_collections_ibfk_2` FOREIGN KEY (`collection_id`) REFERENCES `collections` (`id`),
+ CONSTRAINT `addons_collections_ibfk_3` FOREIGN KEY (`comments`) REFERENCES `translations` (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 ;
+
+--
+-- Table structure for table `collection_promos`
+-- Named that way because it's not actually a join.
+--
+
+DROP TABLE IF EXISTS `collection_promos`;
+CREATE TABLE `collection_promos` (
+ `id` int(11) unsigned NOT NULL auto_increment,
+ `collection_id` int(11) unsigned NOT NULL default '0',
+ `locale` varchar(10) default NULL,
+ `title_tagline` int(11) unsigned NOT NULL default '0',
+ `created` datetime NOT NULL default '0000-00-00 00:00:00',
+ `modified` datetime NOT NULL default '0000-00-00 00:00:00',
+ PRIMARY KEY (`id`),
+ KEY `collection_id` (`collection_id`),
+ UNIQUE KEY `one_collection_per_tagline_per_locale` (`collection_id`,`locale`,`title_tagline`),
+ CONSTRAINT `collection_features_ibfk_1` FOREIGN KEY (`collection_id`) REFERENCES `collections` (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+DROP TABLE IF EXISTS `collections_tags`;
+CREATE TABLE `collections_tags` (
+ `collection_id` int(11) unsigned NOT NULL ,
+ `tag_id` int(11) unsigned NOT NULL ,
+ PRIMARY KEY ( `collection_id` , `tag_id` ),
+ KEY `collection_id` (`collection_id`),
+ KEY `tag_id` (`tag_id`),
+ CONSTRAINT `collections_tags_ibfk_1` FOREIGN KEY (`collection_id`) REFERENCES `addons` (`id`),
+ CONSTRAINT `collections_tags_ibfk_2` FOREIGN KEY (`tag_id`) REFERENCES `tags` (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 ;
+
+DROP TABLE IF EXISTS `collection_subscriptions`;
+CREATE TABLE `collection_subscriptions` (
+ `user_id` int(11) unsigned NOT NULL,
+ `collection_id` int(11) unsigned NOT NULL,
+ `created` datetime NOT NULL default '0000-00-00 00:00:00',
+ `modified` datetime NOT NULL default '0000-00-00 00:00:00',
+ PRIMARY KEY (`user_id`, `collection_id`),
+ CONSTRAINT `collections_subscriptions_ibfk_1` FOREIGN KEY (`collection_id`) REFERENCES `collections` (`id`),
+ CONSTRAINT `collections_subscriptions_ibfk_2` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+DROP TABLE IF EXISTS `collections_users`;
+CREATE TABLE `collections_users` (
+ `collection_id` int(11) unsigned NOT NULL default '0',
+ `user_id` int(11) unsigned NOT NULL default '0',
+ `role` tinyint(2) unsigned NOT NULL default '5',
+ PRIMARY KEY (`collection_id`,`user_id`),
+ KEY `user_id` (`user_id`),
+ CONSTRAINT `collections_users_ibfk_1` FOREIGN KEY (`collection_id`) REFERENCES `collections` (`id`),
+ CONSTRAINT `collections_users_ibfk_2` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+
+DROP TABLE IF EXISTS `mimes`;
+CREATE TABLE `mimes` (
+ `id` int(11) unsigned NOT NULL auto_increment,
+ `mime` varchar(255) NOT NULL,
+ `description` text NOT NULL,
+ `suffixes` varchar(255) NOT NULL,
+ PRIMARY KEY (`id`,`mime`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+DROP TABLE IF EXISTS `plugins`;
+CREATE TABLE `plugins` (
+ `id` int(11) unsigned NOT NULL auto_increment,
+ `name` varchar(255) NOT NULL,
+ `version` varchar(255) NOT NULL,
+ `filename` varchar(255) NOT NULL,
+ `vendor` varchar(255) NOT NULL,
+ `url` varchar(255) NOT NULL,
+ `icon_url` varchar(255) NOT NULL,
+ `latest_version` varchar(255) NOT NULL,
+ `installer_location` varchar(255) NOT NULL,
+ `installer_hash` varchar(255) NOT NULL,
+ `installer_shows_ui` tinyint(1) NOT NULL,
+ `license_url` varchar(255) NOT NULL,
+ `needs_restart` tinyint(1) NOT NULL,
+ `description` text NOT NULL,
+ `min` varchar(255) default NULL,
+ `max` varchar(255) default NULL,
+ `os` varchar(255) default NULL,
+ `xpcomabi` varchar(255) default NULL,
+ `created` datetime NOT NULL,
+ `modified` datetime NOT NULL,
+ PRIMARY KEY (`id`,`name`,`filename`,`version`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+DROP TABLE IF EXISTS `plugins_mimes`;
+CREATE TABLE `plugins_mimes` (
+ `mime_id` int(11) unsigned NOT NULL,
+ `plugin_id` int(11) unsigned NOT NULL,
+ PRIMARY KEY (`mime_id`,`plugin_id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+
+--
+-- Default data that doesn't change over time (or isn't supposed to anyway).
+--
+
+--
+-- Dumping data for table `addontypes`
+--
+INSERT INTO `addontypes` (`id`, `created`, `modified`) VALUES
+(1, '2006-08-21 23:53:19', '2006-08-21 23:53:19'),
+(2, '2006-08-21 23:53:24', '2006-08-21 23:53:24'),
+(3, '2006-08-21 23:53:30', '2006-08-21 23:53:30'),
+(4, '2006-08-21 23:53:36', '2006-08-21 23:53:36'),
+(5, '2006-08-21 23:53:58', '2006-08-21 23:53:58'),
+(6, '2006-08-21 23:54:09', '2006-08-21 23:54:09'),
+(7, '2007-01-19 14:00:00', '2007-01-19 14:00:00');
+
+--
+-- Dumping data for table `facebook_data`
+--
+INSERT INTO `facebook_data` (trait) VALUES
+('age_under12'), ('age_12to15'), ('age_16to19'), ('age_20to23'),
+('age_24to27'), ('age_28to31'), ('age_32to35'), ('age_36to39'),
+('age_40to49'), ('age_50to59'), ('age_above60'), ('sex_male'),
+('sex_female');
+
+--
+-- Initialize `translations_seq` to be the number of the last entry
+-- in the `translations` table
+--
+
+-- INSERT INTO `translations_seq` (id) SELECT MAX(id) from `translations`;
+INSERT INTO `translations_seq` (id) values (1000);
+
+-- Old tables. Remove these lines sometime.
+DROP TABLE IF EXISTS `acos`;
+DROP TABLE IF EXISTS `activeusers`;
+DROP TABLE IF EXISTS `addonevents`;
+DROP TABLE IF EXISTS `aros`;
+DROP TABLE IF EXISTS `aros_acos`;
+DROP TABLE IF EXISTS `downloads-tmp`;
+DROP TABLE IF EXISTS `features_tags`;
+DROP TABLE IF EXISTS `foo`;
+DROP TABLE IF EXISTS `userevents`;
+
+/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
+/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
+/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
+/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
+/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
+/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
+/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
+
+/* These are my TRIGGERS. */
+
+CREATE TRIGGER collections_update_addon_count_insert
+ AFTER INSERT ON addons_collections
+ FOR EACH ROW
+ UPDATE collections AS c
+ SET c.addonCount = c.addonCount + 1
+ WHERE c.id=NEW.collection_id;
+
+CREATE TRIGGER collections_update_addon_count_delete
+ AFTER DELETE ON addons_collections
+ FOR EACH ROW
+ UPDATE collections AS c
+ SET c.addonCount = c.addonCount - 1
+ WHERE c.id=OLD.collection_id;
+
+CREATE TRIGGER collections_update_subscriber_count_insert
+ AFTER INSERT ON collection_subscriptions
+ FOR EACH ROW
+ UPDATE collections AS c
+ SET c.subscribers = c.subscribers + 1
+ WHERE c.id=NEW.collection_id;
+
+CREATE TRIGGER collections_update_subscriber_count_delete
+ AFTER DELETE ON collection_subscriptions
+ FOR EACH ROW
+ UPDATE collections AS c
+ SET c.subscribers = c.subscribers - 1
+ WHERE c.id=OLD.collection_id;
diff --git a/site/app/config/tags.ini.php b/site/app/config/tags.ini.php
new file mode 100644
index 0000000..23d77d5
--- /dev/null
+++ b/site/app/config/tags.ini.php
@@ -0,0 +1,34 @@
+;<?php die() ?>
+; SVN FILE: $Id$
+;/**
+; * Short description for file.
+; *
+; * In this file, you can set up 'templates' for every tag generated by the tag
+; * generator.
+; *
+; * PHP versions 4 and 5
+; *
+; * CakePHP : Rapid Development Framework <http://www.cakephp.org/>
+; * Copyright (c) 2006, Cake Software Foundation, Inc.
+; * 1785 E. Sahara Avenue, Suite 490-204
+; * Las Vegas, Nevada 89104
+; *
+; * Licensed under The MIT License
+; * Redistributions of files must retain the above copyright notice.
+; *
+; * @filesource
+; *
+; * @copyright Copyright (c) 2006, Cake Software Foundation, Inc.
+; * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP Project
+; * @package cake
+; * @subpackage cake.cake.app.config
+; * @since CakePHP v 0.10.0.1076
+; * @version $Revision$
+; * @modifiedby $LastChangedBy$
+; * @lastmodified $Date$
+; * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+; */
+
+
+; Tag template for image submit button
+submitimage = "<input type="image" src="%s" %s/>"
diff --git a/site/app/controllers/addons_controller.php b/site/app/controllers/addons_controller.php
new file mode 100644
index 0000000..0cca0c3
--- /dev/null
+++ b/site/app/controllers/addons_controller.php
@@ -0,0 +1,1570 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Andrei Hajdukewycz <sancus@off.net> (Original Author)
+ * Justin Scott <fligtar@gmail.com>
+ * Wil Clouser <wclouser@mozilla.com>
+ * Frederic Wenzel <fwenzel@mozilla.com>
+ * Mike Morgan <morgamic@mozilla.com>
+ * Chris Pollett <cpollett@gmail.com>
+ * Ryan Doherty <rdoherty@mozilla.com>
+ * Laura Thomson <lthomson@mozilla.com>
+ * Les Orchard <lorchard@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+class AddonsController extends AppController
+{
+ var $name = 'Addons';
+ var $beforeFilter = array('checkCSRF', 'getNamedArgs', '_checkSandbox', 'checkAdvancedSearch');
+ var $uses = array('Addon', 'AddonCollection', 'AddonTag', 'Addontype', 'Application',
+ 'Feature', 'File', 'GlobalStat', 'License', 'Platform', 'Preview', 'Tag', 'Translation',
+ 'Review', 'Version', 'Collection', 'CollectionPromo');
+ var $components = array('Amo', 'Image', 'Pagination', 'Session', 'Userfunc');
+ var $helpers = array('Html', 'Link', 'Time', 'Localization', 'Ajax', 'Number', 'Pagination');
+ var $namedArgs = true;
+
+ var $securityLevel = 'low';
+
+ var $link_sharing_services;
+
+ function beforeFilter() {
+ // Disable ACLs because this controller is entirely public.
+ $this->SimpleAuth->enabled = false;
+ $this->SimpleAcl->enabled = false;
+
+ if (array_key_exists('addons-author-addons-select', $this->params['url']) && ctype_digit($this->params['url']['addons-author-addons-select'])) {
+ redirectWithNewLocaleAndExit(array('addon',$this->params['url']['addons-author-addons-select']));
+ }
+
+ // Set of available link sharing services with associated labels and
+ // submission URL templates.
+ // @TODO: Move this to a model class when share counts are enabled in DB
+ $this->link_sharing_services = array(
+
+ // see: http://digg.com/tools/integrate#3
+ 'digg' => array(
+ 'label' => ___('addons_share_label_digg', 'Digg this!'),
+ 'url' => 'http://digg.com/submit?url={URL}&title={TITLE}&bodytext={DESCRIPTION}&media=news&topic=tech_news'
+ ),
+
+ // see: http://www.facebook.com/share_options.php
+ 'facebook' => array(
+ 'label' => ___('addons_share_label_facebook', 'Post to Facebook'),
+ 'url' => 'http://www.facebook.com/share.php?u={URL}&t={TITLE}'
+ ),
+
+ // see: http://delicious.com/help/savebuttons
+ 'delicious' => array(
+ 'label' => ___('addons_share_label_delicious', 'Add to Delicious'),
+ 'url' => 'http://delicious.com/save?url={URL}&title={TITLE}&notes={DESCRIPTION}'
+ ),
+
+ // see: http://www.myspace.com/posttomyspace
+ 'myspace' => array(
+ 'label' => ___('addons_share_label_myspace', 'Post to MySpace'),
+ 'url' => 'http://www.myspace.com/index.cfm?fuseaction=postto&t={TITLE}&c={DESCRIPTION}&u={URL}&l=1'
+ ),
+
+ // see: http://friendfeed.com/embed/link
+ 'friendfeed' => array(
+ 'label' => ___('addons_share_label_friendfeed', 'Share on FriendFeed'),
+ 'url' => 'http://friendfeed.com/?url={URL}&title={TITLE}'
+ )
+
+ );
+
+ }
+
+ /**
+ * Share an addon with a link sharing service.
+ * @param int $id the id of the addon
+ */
+ function share($id = null) {
+ global $valid_status;
+
+ $_conditions = array(
+ 'Addon.id' => $id,
+ 'Addon.inactive' => 0,
+ 'Addon.addontype_id' => array(
+ ADDON_EXTENSION, ADDON_THEME, ADDON_DICT,
+ ADDON_SEARCH, ADDON_LPAPP, ADDON_PLUGIN
+ ),
+ 'Addon.status' => $valid_status
+ );
+ $addon = $this->Addon->find($_conditions, null , null , 1);
+
+ $service = @$this->link_sharing_services[$_GET['service']];
+
+ // Panic if either the addon or the sharing service is not found.
+ if (empty($addon) || empty($service)) {
+ $this->flash(_('error_addon_notfound'), '/', 3);
+ return;
+ }
+
+ $this->publish('addon_id', $id);
+
+ // Build a suitable link title based on the addon name, version, and
+ // the site title.
+ $title =
+ sprintf(
+ _('addons_display_pagetitle'),
+ $addon['Translation']['name']['string'].' '.
+ $addon['Version'][0]['version']
+ ) .
+ ' :: '.
+ sprintf(
+ _('addons_home_pagetitle'),
+ APP_PRETTYNAME
+ );
+
+ $this->publish('share_title', $title);
+
+ // Come up with description text from the summary
+ $this->publish('description', $addon['Translation']['summary']['string']);
+
+ $this->publish('service_url', $service['url']);
+
+ $this->layout = 'ajax';
+ }
+
+ /**
+ * Display an addon
+ * @param int $id the id of the addon
+ */
+ function display($id = null) {
+ global $valid_status;
+ $this->publish('jsAdd', array('jquery-ui/ui.lightbox'));
+ $this->publish('cssAdd', array('jquery-lightbox'));
+ $this->layout = 'amo2009';
+ $this->set('bodyclass', 'inverse');
+
+ $this->forceShadowDb();
+ $this->Amo->clean($id);
+
+ $this->publish('bigHeader', true);
+ $this->publish('bigHeaderText', sprintf(_('addons_home_header_details'), APP_PRETTYNAME));
+
+ $loggedIn = $this->Session->check('User')? true : false;
+ $this->set('loggedIn', $loggedIn);
+
+ if (!$id || !is_numeric($id)) {
+ $this->flash(sprintf(_('error_missing_argument'), 'addon_id'), '/', 3);
+ return;
+ }
+
+ $_conditions = array(
+ 'Addon.id' => $id,
+ 'Addon.inactive' => 0,
+ 'Addon.addontype_id' => array(ADDON_EXTENSION, ADDON_THEME, ADDON_DICT, ADDON_SEARCH, ADDON_LPAPP, ADDON_PLUGIN),
+ 'Addon.status' => $valid_status
+ );
+
+ $this->Addon->bindOnly('User', 'Version', 'Tag', 'AddonTag');
+ $addon_data = $this->Addon->find($_conditions, null , null , 1);
+
+ if (empty($addon_data)) {
+ $this->flash(_('error_addon_notfound'), '/', 3);
+ return;
+ }
+
+ // sandbox check
+ if ($addon_data['Addon']['status'] != STATUS_PUBLIC) {
+ $this->publish('addonStatus', STATUS_SANDBOX);
+ $this->status = $valid_status;
+ }
+
+ $_latest_version = $this->Version->getVersionByAddonId($addon_data['Addon']['id'], $this->status);
+ if ($_latest_version > 0) {
+ $version = $this->Version->findAllById($_latest_version, null, "Version.created DESC", 0);
+ $addon_data['Version'] = $version;
+ $this->publish('hasversion', true);
+ $compat_apps = $this->Version->getCompatibleApps($_latest_version);
+ $this->publish('compatible_apps', array_slice($compat_apps, 0, 1));
+ $addon_data['compatible_apps'] = $compat_apps;
+ }
+
+ // if the latest version is incompatible with the current app, redirect
+ // to a the first valid, compatible version.
+ if (!empty($compat_apps)) {
+ $is_compatible = false;
+ foreach ($compat_apps as $app) {
+ if ($app['Application']['application_id'] == APP_ID) {
+ $is_compatible = true;
+ break;
+ }
+ }
+ if (!$is_compatible) {
+ global $app_shortnames;
+ $targetapp = array_search($compat_apps[0]['Application']['application_id'], $app_shortnames);
+ $this->redirect("/{$targetapp}/addon/{$id}", null, true, false);
+ return;
+ }
+ }
+
+ // TODO: Look up the current share totals for this addon.
+ // $share_counts = $this->ShareCount->getTotalCountsForAddon(
+ // $addon_data['Addon']['id']
+ // );
+ // $this->set('link_sharing_counts', $share_counts);
+
+ // Not using publish() here because this will all be app constants,
+ // localized strings with placeholders, or counts from the DB.
+ $this->set('link_sharing_services', $this->link_sharing_services);
+
+ if($loggedIn) {
+ $isauthor = $this->Amo->checkOwnership($id, $addon_data['Addon'], true);
+ $this->publish('isAuthor', $isauthor);
+ }
+ else {
+ $this->publish('isAuthor', false);
+ }
+
+ // get other addons for the author(s)
+ foreach ($addon_data['User'] as $_user)
+ $_userids[] = $_user['id'];
+ $_addonids = $this->Addon->getAddonsForAuthors($_userids);
+
+ if (!empty($_addonids)) {
+ // re-fetch the addons to get the translations too
+ $_addoncriteria = array(
+ 'Addon.id' => $_addonids,
+ 'Addon.inactive' => 0,
+ 'Addon.status' => $valid_status
+ );
+ $authorAddons = $this->Addon->findAll($_addoncriteria, null, 'Translation.name');
+ } else {
+ $authorAddons = array();
+ }
+ $this->publish('authorAddons',$authorAddons);
+
+ if (in_array($addon_data['Addon']['addontype_id'], array(ADDON_PLUGIN))) {
+ $this->redirect('/browse/type:' . $addon_data['Addon']['addontype_id']);
+ }
+
+ $this->publish('previews', $this->Preview->findAllByAddonId($id, array('id', 'addon_id', 'caption'), 'highlight desc'));
+
+ $this->publish('addon', $addon_data);
+ $this->publish('addonIconPath', $this->Image->getAddonIconURL($id), false);
+ $this->publish('addonPreviewPath', $this->Image->getHighlightedPreviewURL($id));
+ $this->pageTitle = sprintf(_('addons_display_pagetitle'), $addon_data['Translation']['name']['string']). ' :: '.sprintf(_('addons_home_pagetitle'), APP_PRETTYNAME);
+
+ // get the tags that are related to the addon, so that they have translation data
+ $_related_tag_ids = array();
+ foreach ($addon_data['Tag'] as $tagvalue){
+ $_related_tag_ids[] = $tagvalue['id'];
+ }
+
+ if (!empty($_related_tag_ids))
+ $related_tags = $this->Tag->findAll("Tag.id IN (".implode(',', $_related_tag_ids).") AND (Tag.application_id = ".APP_ID." OR Tag.application_id IS NULL)");
+ else
+ $related_tags = array();
+
+ $this->publish('relatedTags', $related_tags);
+
+ // The platforms section is necessary because of CakePHP bug #1183 (https://trac.cakephp.org/ticket/1183). We
+ // need the translated strings in the model to offer the right platform to users.
+ $this->Platform->unbindFully();
+ $platforms = $this->Platform->findAll();
+ $this->publish('platforms', $platforms);
+
+ // Grab the latest 3 reviews by ID, one per user.
+ $review_ids = array();
+ $_latest_reviews =
+ $this->Review->findLatestReviewsForAddon($addon_data['Addon']['id'], 3, 1);
+ foreach($_latest_reviews as $_r)
+ $review_ids[] = $_r['id'];
+
+ // Fetch the actual reviews from IDs
+ if (!empty($review_ids))
+ $reviews = $this->Review->getReviews($review_ids);
+ else
+ $reviews = array();
+
+ $this->publish('reviews', $reviews);
+ $this->publish('review_count', empty($reviews) ? 0 : $addon_data['Addon']['totalreviews']);
+
+ // does user have a review already?
+ $user = $this->Session->read('User');
+ if (!empty($user) && $_latest_version > 0) {
+ $user_revcount = $this->Review->findCount("Review.user_id = {$user['id']} AND Review.version_id = {$_latest_version}");
+ $this->publish('hasreview', ($user_revcount>0));
+ } else {
+ $this->publish('hasreview', false);
+ }
+
+ // find collections this add-on is in
+ $pop_collections = array();
+ $_pop_coll_ids = $this->AddonCollection->getPopularCollectionsForAddon($id, 3, APP_ID);
+ if (!empty($_pop_coll_ids)) {
+ $pop_collections = $this->Collection->findAllById($_pop_coll_ids,
+ array('id', 'uuid', 'nickname', 'name'),
+ 'FIELD(Collection.id,'.implode(',', $_pop_coll_ids).')', null, null, -1);
+ }
+ $this->publish('pop_collections', $pop_collections);
+ $collection_count = $this->AddonCollection->getCollectionCountForAddon($id, APP_ID);
+ $this->publish('collection_count', $collection_count, false);
+
+ // Fetch user's collections if logged in
+ $userCollections = false;
+ if (!empty($user)) {
+ $userCollectionIds = $this->User->getCollections($user['id'], APP_ID, array($id));
+ $userCollections = $this->Collection->findAll(array(
+ 'Collection.id' => $userCollectionIds,
+ 'Collection.collection_type' => '<> '.Collection::COLLECTION_TYPE_AUTOPUBLISHER
+ ), array('id', 'name', 'uuid', 'nickname'));
+ $this->publish('userCollections', $userCollections);
+
+ // if an addon was just added to a collection, display a success message
+ if (false !== ($coll_uuid = $this->Session->read('collection_addon_added'))) {
+ $collection_id = $this->Collection->getIdForUUID($coll_uuid);
+ $coll_addon_added = $this->Collection->findById($collection_id, null, null, -1);
+ $this->Session->delete('collection_addon_added');
+ $this->publish('coll_addon_added', $coll_addon_added);
+ }
+ }
+
+ // Collapse categories menu
+ $this->publish('collapse_categories', true);
+ }
+
+ /**
+ * Display the home page for the entire site.
+ */
+ function home() {
+ $this->forceShadowDb();
+
+ $this->layout='amo2009';
+ $this->pageTitle = sprintf(_('addons_home_pagetitle'), APP_PRETTYNAME);
+
+ $this->publish('stats_downloaded',
+ $this->GlobalStat->getNamedCount('addons_downloaded'));
+ $this->publish('stats_inuse',
+ $this->GlobalStat->getNamedCount('addons_in_use'));
+
+ $this->publish('teaser_collection_promos', $this->_findTeaserCollections());
+ $this->publish('teaser_collections_categories', $this->CollectionPromo->titles_and_taglines);
+ $this->publish('popular_collections', $this->_findPopularCollections());
+ $this->publish('promoted_collections', $this->_findCollectionPromoList(true));
+
+ list($featured_type, $featured_addons) = $this->_getFeatured();
+ $this->publish('featured_type', $featured_type);
+ $this->publish('featured_addons', $featured_addons);
+
+ // The platforms section is necessary because of CakePHP bug #1183
+ // (https://trac.cakephp.org/ticket/1183). We need the translated
+ // strings in the model to offer the right platform to users.
+ $this->Platform->unbindFully();
+ $platforms = $this->Platform->findAll();
+ $this->publish('platforms', $platforms);
+
+ $this->publish('baseurl', $this->base);
+ $this->publish('bigHeader', true);
+ $this->publish('bigHeaderText', sprintf(_('addons_home_header_details'), APP_PRETTYNAME));
+
+ // add rss links to global feeds
+ $this->publish('rssAdd', array(
+ array('/browse/type:1/cat:all/format:rss?sort=newest', _('rss_newestaddons')),
+ array('/browse/type:1/cat:all/format:rss?sort=updated', ___('rss_updatedaddons', 'Updated Add-ons')),
+ array('/browse/type:1/cat:all/format:rss?sort=popular', ___('rss_popularaddons', 'Popular Add-ons')),
+ array('/recommended/format:rss', _('rss_featuredaddons')),
+ ));
+ }
+
+ /* Used to populate the homepage addons by xhr. */
+ function ajaxy() {
+ list($featured_type, $featured_addons) = $this->_getFeatured();
+ $this->publish('featured_type', $featured_type);
+ $this->publish('featured_addons', $featured_addons);
+ $this->Platform->unbindFully();
+ $platforms = $this->Platform->findAll();
+ $this->publish('platforms', $platforms);
+ }
+
+ function _getFeatured() {
+ global $app_listedtypes;
+
+ $associations = array(
+ 'single_tag', 'all_tags', 'authors', 'compatible_apps', 'files',
+ 'latest_version', 'list_details'
+ );
+ $list_num = 5;
+
+ $featured_type = isset($_GET['featured']) ?
+ $_GET['featured'] : 'recommended';
+ switch ($featured_type) {
+ case 'popular':
+ $featured_addon_ids = $this->Addon->getAddonsFromCategory(
+ STATUS_PUBLIC, $app_listedtypes[APP_ID], 'all', 'popular',
+ 'DESC', $list_num, 1, '', false
+ );
+ break;
+ case 'added':
+ $featured_addon_ids = $this->Addon->getAddonsFromCategory(
+ STATUS_PUBLIC, $app_listedtypes[APP_ID], 'all', 'newest',
+ 'DESC', $list_num, 1, '', false
+ );
+ break;
+ case 'updated':
+ $featured_addon_ids = $this->Addon->getAddonsFromCategory(
+ STATUS_PUBLIC, $app_listedtypes[APP_ID], 'all', 'updated',
+ 'DESC', $list_num, 1, '', false
+ );
+ break;
+ case 'recommended':
+ default:
+ $featured_addon_ids = $this->Addon->getRecommendedAddons($list_num);
+ break;
+ }
+ $featured_addons = $this->Addon->getAddonList($featured_addon_ids, $associations);
+
+ return array($featured_type, $featured_addons);
+ }
+
+ /**
+ * Assemble collections for the teaser section of the home page.
+ *
+ * @return array
+ */
+ function _findTeaserCollections() {
+
+ if (APP_ID != APP_FIREFOX) {
+
+ // FYF collections for teaser are only appropriate for Firefox.
+ return array();
+
+ } else {
+ $promoCatList = $this->_findCollectionPromoList();
+ $teaser_collections = array();
+
+ $associations = array(
+ 'single_tag', 'all_tags', 'authors', 'compatible_apps', 'files',
+ 'latest_version', 'list_details'
+ );
+
+ foreach($promoCatList as $index => $collectionId) {
+ $addons = $this->Addon->getAddonsFromCollection($collectionId, 'RAND()', null, 3);
+ $teaser_collections[] = $this->Addon->getAddonList($addons, $associations);
+ }
+
+ return $teaser_collections;
+ }
+
+ }
+
+ /**
+ * Assemble list of collections promoted per promotion category
+ *
+ * @return array
+ **/
+ function _findCollectionPromoList($bindFully = false) {
+ $collectionPromos = $this->CollectionPromo->findAll();
+ $promoCats = $this->CollectionPromo->titles_and_taglines;
+ $promoCatList = array();
+
+ //Doing this to merge collection ids into promotion categories and allow locale-specific selections to override
+ for($i = 0; $i < count($promoCats); $i++) {
+ $collection = false;
+
+ if(isset($collectionPromos[LANG][$i])) {
+ $collection = $collectionPromos[LANG][$i];
+ } elseif(isset($collectionPromos['all'][$i])) {
+ $collection = $collectionPromos['all'][$i];
+ }
+
+ if($collection) {
+ $id = array_keys($collection);
+ $id = $id[0];
+
+ if($bindFully) {
+ $promoCatList[] = $this->Collection->findById($id);
+ } else {
+ $promoCatList[] = $id;
+ }
+ }
+ }
+
+ return $promoCatList;
+ }
+
+
+
+
+
+ /**
+ * Fetch top 5 popular collections by subscriber count, return a
+ * stripped-down data structure for use by view.
+ *
+ * @return array
+ */
+ function _findPopularCollections() {
+
+ // Unbind and re-bind with just users and addons, then look up top 5
+ // popular collections in descending order.
+ $this->Collection->unbindFully();
+ $this->Collection->bindModel(array(
+ 'hasAndBelongsToMany' => array(
+ 'Users' => $this->Collection->hasAndBelongsToMany_full['Users'],
+ 'Addon' => $this->Collection->hasAndBelongsToMany_full['Addon']
+ )
+ ));
+ $collections = $this->Collection->findAll(array(
+ 'Collection.listed' => 1,
+ 'Collection.application_id' => APP_ID
+ ), null, 'Collection.subscribers DESC', 5);
+
+ // Reduce the results from the model to the minimal set needed
+ // by the view, because escaping is expensive.
+ $pop_collections = array();
+ foreach ($collections as $c) {
+ $authors = array();
+ foreach ($c['Users'] as $u) {
+ $authors[] = array(
+ 'id' => $u['id'],
+ 'firstname' => $u['firstname'],
+ 'lastname' => $u['lastname'],
+ 'nickname' => $u['nickname']
+ );
+ }
+ $pop_collections[] = array(
+ 'uuid' => $c['Collection']['uuid'],
+ 'nickname' => $c['Collection']['nickname'],
+ 'authors' => $authors,
+ 'icon_url' => $this->Image->getCollectionIconURL($c['Collection']['id']),
+ 'name' => $c['Translation']['name']['string'],
+ 'description' => $c['Translation']['description']['string'],
+ 'subscribers' => $c['Collection']['subscribers'],
+ 'addons_count' => count($c['Addon'])
+ );
+ }
+
+ return $pop_collections;
+ }
+
+ /**
+ * Build a grid of thumbnails and names, mainly for themes.
+ */
+ function _browseThumbs() {
+ global $valid_status;
+
+ // Get the type of addon, defaulting to themes
+ $addontype = isset($this->namedArgs['type']) ?
+ $this->namedArgs['type'] : ADDON_THEME;
+
+ // Get the addon category, defaulting to 'all'
+ $category = isset($this->namedArgs['cat']) ?
+ $this->namedArgs['cat'] : 'all';
+
+ $this->Tag->unbindFully();
+ $this_tag = $this->Tag->findById($category);
+
+ // show experimental add-ons?
+ if (isset($this->params['url']['exp'])) {
+ /* experimental add-ons requested */
+ $show_exp = true;
+ $this->Userfunc->toggleSandboxPref(true); // store preference
+ } elseif (isset($this->params['url']['show'])) {
+ $show_exp = false;
+ $this->Userfunc->toggleSandboxPref(false); // store preference
+ } elseif ($this->Session->check('User')) {
+ /* read preference */
+ $sessionuser = $this->Session->read('User');
+ $show_exp = ($sessionuser['sandboxshown'] == 1);
+ } else {
+ /* default to experimental add-ons not shown */
+ $show_exp = false;
+ }
+ $this->set('show_exp', $show_exp);
+ $displaystatuses = ($show_exp ? $valid_status : array(STATUS_PUBLIC));
+
+ // fetch a list of all subcategories
+ $subcats = $this->Amo->getTags(APP_ID, $addontype);
+
+ // fetch counts for all categories
+ $subcat_totals = $this->Addon->countAddonsInAllCategories(
+ $displaystatuses, $addontype
+ );
+ $all_total = $this->Addon->countAddonsInCategory(
+ $displaystatuses, $addontype
+ );
+ $subcat_totals['all'] = $all_total;
+
+ // determine list sort order
+ if (isset($this->params['url']['sort']))
+ $sort_by = $this->params['url']['sort'];
+ elseif (isset($this->namedArgs['sort']))
+ $sort_by = $this->namedArgs['sort'];
+ else
+ $sort_by = '';
+
+ $allowed_sort_by = array(
+ 'name', 'updated', 'newest', 'popular', 'rated'
+ );
+ if (!in_array($sort_by, $allowed_sort_by)) {
+ $sort_by = 'updated';
+ }
+
+ switch ($sort_by) {
+ case 'popular':
+ case 'updated':
+ case 'newest':
+ case 'rated':
+ $sort_dir = 'desc';
+ break;
+ case 'name':
+ default:
+ $sort_dir = 'asc';
+ break;
+ }
+
+ // initialize pagination component
+ $this->Pagination->total = $subcat_totals[$category];
+ $this->Pagination->sortBy = $sort_by;
+ $this->Pagination->direction = $sort_dir;
+ list($_order,$_limit,$_page) = $this->Pagination->init();
+
+ $addons = $this->Addon->getAddonsByCategory(
+ null, $displaystatuses, $addontype, $category,
+ $sort_by, $sort_dir, $_limit, $_page, '', true
+ );
+
+ $this->set('type', $addontype);
+ $this->set('this_tag', $this_tag);
+
+ $this->publish('addons', $addons);
+ $this->publish('show_limit', $_limit);
+ $this->publish('sort_by', $sort_by);
+ $this->publish('subcats', $subcats);
+ $this->publish('all_total', $all_total);
+ $this->publish('subcat_totals', $subcat_totals);
+
+ $format = (isset($this->namedArgs['format']) ? $this->namedArgs['format'] : 'html');
+
+ $this->set('content_wide', true); // display 2 features next to each other
+
+ $this->publish('collapse_categories', true);
+
+ switch($addontype) {
+ case ADDON_THEME:
+ $this->pageTitle = sprintf(___('addons_browse_categories_header_theme'), $this_tag['Translation']['name']['string'], APP_PRETTYNAME);
+ break;
+ default:
+ $this->pageTitle = sprintf(_('addons_home_pagetitle'), APP_PRETTYNAME);
+ }
+
+ $this->publish('bigHeader', true);
+ $this->publish('bigHeaderText', sprintf(_('addons_home_header_details'), APP_PRETTYNAME));
+
+ $this->layout = 'mozilla';
+
+ $this->render('browse_thumbs');
+ }
+
+ /**
+ * Category listing and landing pages.
+ */
+ function browse() {
+ global $app_listedtypes, $hybrid_categories;
+
+ $this->forceShadowDb();
+ if (!isset($this->namedArgs['type'])) {
+ // @TODO throw a 404 error
+ $this->redirect('/');
+ return;
+ }
+ $type = $this->namedArgs['type'];
+
+ // allow addontype pages only for applicable types
+ if (!in_array($type, $app_listedtypes[APP_ID])) {
+ // @TODO throw some error
+ $this->redirect('/');
+ break;
+ }
+
+ if (!isset($this->namedArgs['cat'])) {
+ switch ($this->namedArgs['type']) {
+ case ADDON_SEARCH:
+ $this->_searchengines();
+ break;
+ /* @TODO: Do something with the plugin page; note, if the plugin pages
+ * are re-enabled, we need to make sure they are added to the
+ * app_listedtypes array in constants.php too.*/
+ case ADDON_PLUGIN: // undeleted this -cpollett
+ $this->_plugins();
+ break;
+
+ case ADDON_DICT:
+ $this->_dictionaries();
+ break;
+ case ADDON_THEME:
+ $this->_themes();
+ break;
+ default:
+ // @TODO throw some error
+ $this->redirect('/');
+ break;
+ }
+ return;
+ }
+
+ /* redirect category hybrids to respective addontype page
+ * (unless we have selected a full listing page (?sort=something)) */
+ $cat = $this->namedArgs['cat'];
+ if (isset($hybrid_categories[APP_ID][$cat])
+ && !isset($_GET['sort']) && !isset($this->namedArgs['sort'])) {
+ $this->redirect("/browse/type:{$hybrid_categories[APP_ID][$cat]}");
+ return;
+ }
+
+ /* display generic cat landing page or full category listing page */
+ if (isset($_GET['sort']) || isset($this->namedArgs['sort'])) {
+
+
+ if ($type == ADDON_THEME && (empty($this->namedArgs['format']) || $this->namedArgs['format']!='rss')) {
+ return $this->_browseThumbs();
+ }
+
+ // category listing page
+ $this->_browseAddonsInCategory();
+ } else {
+ // category landing page
+ $this->_categoryLanding();
+ }
+ }
+
+ function _buildMinimalAddonDetails($addons) {
+ $view_data = array();
+
+ foreach ($addons as $addon) {
+ $addon_id = $addon['Addon']['id'];
+
+ $r = array(
+ 'icon_url' =>
+ $this->Image->getAddonIconURL($addon_id),
+ 'preview_url' =>
+ $this->Image->getHighlightedPreviewURL($addon_id),
+ 'version' =>
+ $addon['Version'][0]['version']
+ );
+
+ $a_fields = array(
+ 'id','guid','averagerating','created','modified',
+ 'weeklydownloads','totaldownloads'
+ );
+ foreach ($a_fields as $field)
+ $r[$field] = $addon['Addon'][$field];
+
+ $t_fields = array('name','summary','description');
+ foreach ($t_fields as $field)
+ $r[$field] = $addon['Translation'][$field]['string'];
+
+ $u_fields = array('id', 'firstname', 'lastname', 'nickname');
+ $r['authors'] = array();
+ if (!empty($addon['User'])) foreach ($addon['User'] as $idx=>$user) {
+ foreach ($u_fields as $field)
+ $r['authors'][$idx][$field] = $user[$field];
+ }
+
+ $r['latestversion'] = $addon['Version'][0]['version'];
+
+ $view_data[] = $r;
+ }
+
+ return $view_data;
+ }
+
+ /**
+ * Generic landing page for a specific add-on category
+ *
+ * Relevant URL format: /browse/type:1/cat:12
+ *
+ * @access private
+ */
+ function _categoryLanding() {
+ global $valid_status, $app_listedtypes;
+
+ $valid_status = array(STATUS_PUBLIC);
+
+ $format = $this->setLayoutForFormat();
+
+ $addontype = $this->namedArgs['type'];
+ $this->Amo->clean($addontype);
+ $this->publish('type_id', $addontype);
+
+ $category = $this->namedArgs['cat'];
+ $this->Amo->clean($category);
+ $this->publish('cat_id', $category);
+
+ $this->Tag->unbindFully();
+ $this_tag = $this->Tag->findById($category);
+ $this->publish('this_tag', $this_tag);
+
+ // Build a minimal set of addon details for publishing to view.
+ $_feat_ids = $this->AddonTag->getRandomAddons($category, true, 6);
+ if (count($_feat_ids) > 0) {
+ $_order_by = 'FIELD(Addon.id, '.implode(',', $_feat_ids).')';
+ } else {
+ $_order_by = 'Addon.id';
+ }
+ $featureAddons = $this->Addon->getListAddons($_feat_ids, $valid_status, $_order_by, true);
+
+ $this->publish('featured_addons', $featureAddons);
+
+ $list_num = 10;
+
+ $pop_addon_ids = $this->Addon->getAddonsFromCategory(
+ STATUS_PUBLIC, $app_listedtypes[APP_ID], $category,
+ 'popular', 'DESC', $list_num, 1, '', false
+ );
+ $pop_addons = $this->_buildMinimalAddonDetails(
+ $this->Addon->getListAddons($pop_addon_ids, $valid_status, 'Addon.weeklydownloads DESC')
+ );
+
+ $this->publish('popular_addons', $pop_addons);
+
+ $new_addon_ids = $this->Addon->getAddonsFromCategory(
+ STATUS_PUBLIC, $app_listedtypes[APP_ID], $category, 'newest',
+ 'DESC', $list_num, 1, '', false
+ );
+ $new_addons = $this->_buildMinimalAddonDetails(
+ $this->Addon->getListAddons($new_addon_ids, $valid_status, 'Addon.created DESC')
+ );
+
+ $this->publish('new_addons', $new_addons);
+
+ $upd_addon_ids = $this->Addon->getAddonsFromCategory(
+ STATUS_PUBLIC, $app_listedtypes[APP_ID], $category,
+ 'rated', 'DESC', $list_num, 1, '', false
+ );
+ $upd_addons = $this->_buildMinimalAddonDetails(
+ $this->Addon->getListAddons($upd_addon_ids, $valid_status, 'Addon.bayesianrating DESC')
+ );
+
+ $this->publish('updated_addons', $upd_addons);
+
+ // fetch all platforms
+ $this->Platform->unbindFully();
+ $platforms = $this->Platform->findAll();
+ $this->publish('platforms', $platforms);
+
+ $this->set('content_wide', false); // display features next to each other
+ $this->publish('collapse_categories', false);
+
+ // set layout details
+ $this->publish('bigHeader', true);
+ $this->publish('bigHeaderText',
+ sprintf(_('addons_home_header_details'), APP_PRETTYNAME));
+
+ $this->pageTitle = $this_tag['Translation']['name']['string']. " :: " .
+ sprintf(_('addons_home_pagetitle'), APP_PRETTYNAME);
+ $this->publish('rssAdd', array(
+ "/browse/type:{$addontype}/cat:{$category}/format:rss?sort=updated"
+ ));
+ $this->render('category_landing');
+ }
+
+ /**
+ * Add-on listing page for a specific category
+ *
+ * Relevant URL format: /browse/type:1/cat:15?sort=name
+ *
+ * @access private
+ */
+ function _browseAddonsInCategory() {
+ global $valid_status, $app_listedtypes;
+
+ $addontype = $this->namedArgs['type'];
+ $category = $this->namedArgs['cat'];
+ $format = $this->setLayoutForFormat();
+
+ // type:1 && cat:all shows a global add-ons list (not extensions only)
+ if ($addontype == ADDON_EXTENSION && $category == 'all') {
+ $this_tag = array();
+ $addontype = $app_listedtypes[APP_ID];
+ } else {
+ $this->Tag->unbindFully();
+ $this_tag = $this->Tag->findById($category);
+ }
+
+ // determine list sort order
+ if (isset($this->params['url']['sort']))
+ $sort_by = $this->params['url']['sort'];
+ elseif (isset($this->namedArgs['sort']))
+ $sort_by = $this->namedArgs['sort'];
+ else
+ $sort_by = '';
+ $allowed_sort_by = array('name', 'updated', 'newest', 'popular', 'rated');
+ if (!in_array($sort_by, $allowed_sort_by)) {
+ // default sort order
+ $sort_by = 'updated';
+ }
+ switch ($sort_by) {
+ case 'popular':
+ case 'updated':
+ case 'newest':
+ case 'rated':
+ $sort_dir = 'desc';
+ break;
+ case 'name':
+ default:
+ $sort_dir = 'asc';
+ break;
+ }
+
+ // show experimental add-ons?
+ if (isset($this->params['url']['exp'])) {
+ /* experimental add-ons requested */
+ $show_exp = true;
+ $this->Userfunc->toggleSandboxPref(true); // store preference
+ } elseif (isset($this->params['url']['show'])) {
+ /* intentionally disabled */
+ // XXX: checking for "show" to be set is cheesy but the only way
+ // to determine if the button was intentionally disabled or if we
+ // just followed a link
+ $show_exp = false;
+ $this->Userfunc->toggleSandboxPref(false); // store preference
+ } elseif ($this->Session->check('User')) {
+ /* read preference */
+ $sessionuser = $this->Session->read('User');
+ $show_exp = ($sessionuser['sandboxshown'] == 1);
+ } else {
+ /* default to experimental add-ons not shown */
+ $show_exp = false;
+ }
+ $this->set('show_exp', $show_exp);
+ $displaystatuses = ($show_exp ? $valid_status : array(STATUS_PUBLIC));
+
+ if ($format != 'rss') {
+ // initialize pagination component
+ $this->Pagination->total = $this->Addon->countAddonsInCategory(
+ $displaystatuses, $addontype, $category);
+ $this->Pagination->sortBy = $sort_by;
+ $this->Pagination->direction = $sort_dir;
+ list($_order,$_limit,$_page) = $this->Pagination->init();
+ } else {
+ // display the 20 most recently changed addons
+ $_order = '';
+ $_limit = 20;
+ $_page = 1;
+ }
+
+ // get enough addons for one page.
+ $addons = $this->Addon->getAddonsByCategory(null, $displaystatuses,
+ $addontype, $category, $sort_by, $sort_dir, $_limit, $_page, '', true);
+ if ($category!='all' && empty($this_tag) || empty($addons)) {
+ $this->flash(_('error_browse_no_addons'), '/browse/type:' . $addontype, 3);
+ return;
+ }
+ $this->publish('addons', $addons);
+
+ // get platforms (if we are not in RSS mode)
+ if ($format != 'rss') {
+ $this->Platform->unbindFully();
+ $platforms = $this->Platform->findAll();
+ $this->publish('platforms', $platforms);
+ }
+
+ // get other categories list (or all, if this is a complete list)
+ $_tags = $this->Tag->query("SELECT DISTINCT t.id FROM tags AS t "
+ ."INNER JOIN addons_tags AS at ON (t.id = at.tag_id) "
+ ."WHERE ".($category == 'all'?'1':"t.id <> '{$category}'")." "
+ ."AND t.addontype_id = '{$addontype}' AND t.application_id = " . APP_ID . ";"
+ );
+ $tag_list = array();
+ if (!empty($_tags)) {
+ $_tag_ids = array();
+ foreach($_tags as $_tag) $_tag_ids[] = $_tag['t']['id'];
+ $this->Tag->unbindFully();
+ $tag_list = $this->Tag->findAllById($_tag_ids);
+ // sort tags by name
+ $_tag_names = array();
+ foreach($tag_list as $_tag) $_tag_names[] = $_tag['Translation']['name']['string'];
+ array_multisort($_tag_names, SORT_ASC, $tag_list);
+ }
+
+ // set data available to view
+ $this->publish('this_tag', $this_tag);
+ $this->set('type', $addontype);
+ $this->publish('tagList', $tag_list);
+
+ // set layout details and render view
+ if ($category == 'all') {
+ switch ($sort_by) {
+ case 'popular': $_title = ___('browse_addons_popular'); break;
+ case 'updated': $_title = ___('browse_addons_updated'); break;
+ case 'newest': $_title = ___('browse_addons_newest'); break;
+ case 'rated': $_title = ___('browse_addons_rated'); break;
+ case 'name': $_title = ___('browse_addons_name'); break;
+ default: $_title = ''; break;
+ }
+ } else {
+ $_title = sprintf(_('addons_browse_browse_category'), $this_tag['Translation']['name']['string']);
+ }
+ if ($format != 'rss') {
+ $this->pageTitle = $_title . " :: " . sprintf(_('addons_home_pagetitle'), APP_PRETTYNAME);
+ $this->publish('subpagetitle', $_title);
+
+ // preserve GET variables in RSS feed URLs
+ $_rss_get = array();
+ foreach($_GET as $_getkey => $_getitem)
+ if ($_getkey != 'url') $_rss_get[] = urlencode($_getkey).'='.urlencode($_getitem);
+ $this->publish('rssAdd', array("/browse/type:{$this->namedArgs['type']}/cat:{$category}/format:rss?".implode('&', $_rss_get)));
+
+ $this->set('collapse_categories', true);
+
+ $this->render('browse');
+ } else {
+ // RSS feed
+ $this->publish('sort_by', $sort_by, false);
+ $this->publish('rss_title', $_title . " :: " . sprintf(_('addons_home_pagetitle'), APP_PRETTYNAME));
+ $this->publish('rss_description', '');
+ $this->render('rss/addons');
+ }
+ }
+
+ /**
+ * search tools / search engines hybrid landing page
+ * @access private
+ */
+ function _searchengines() {
+ global $hybrid_categories, $valid_status;
+
+ $valid_status = array(STATUS_PUBLIC);
+
+ $format = (isset($this->namedArgs['format']) ? $this->namedArgs['format'] : 'html');
+
+ // fetch the category belonging to this hybrid page
+ $category = array_search(ADDON_SEARCH, $hybrid_categories[APP_ID]);
+ if ($category) {
+ $this->Tag->unbindfully();
+ $this_tag = $this->Tag->findById($category);
+ } else {
+ $this_tag = null;
+ }
+ $this->publish('this_tag', $this_tag);
+
+ // fetch a list of all subcategories
+ $subcats = $this->Amo->getTags(APP_ID, ADDON_SEARCH);
+ $this->publish('subcats', $subcats);
+
+ // make subcategory ID list to grab recommendations from
+ $subcat_ids = array();
+ foreach ($subcats as $subcat)
+ $subcat_ids[] = $subcat['Tag']['id'];
+ // add hybrid category for possible other recommendations
+ $subcat_ids[] = $this_tag['Tag']['id'];
+
+ // fetch up to 4 recommended add-ons
+ $_feat_ids = $this->AddonTag->getRandomAddons($subcat_ids, true, 4);
+ if (!empty($_feat_ids)) {
+ $featureAddons = $this->Addon->getListAddons($_feat_ids, $valid_status,
+ null, true);
+ } else {
+ $featureAddons = array();
+ }
+ $this->publish('featureAddons', $featureAddons);
+
+ // fetch all platforms
+ $this->Platform->unbindFully();
+ $platforms = $this->Platform->findAll();
+ $this->publish('platforms', $platforms);
+
+ if ($format != 'rss') {
+ $this->set('content_wide', true); // display 2 features next to each other
+ $this->set('collapse_categories', true);
+ $this->pageTitle = _('addons_searchengines_pagetitle').' :: '
+ .sprintf(_('addons_home_pagetitle'), APP_PRETTYNAME);
+ $this->publish('bigHeader', true);
+ $this->publish('bigHeaderText', sprintf(_('addons_home_header_details'), APP_PRETTYNAME));
+ $this->layout='mozilla';
+ //$this->publish('rssAdd', array("/browse/type:".ADDON_SEARCH."/format:rss"));
+
+ $this->render('searchengines');
+ } else {
+ // RSS feed
+ $this->publish('rss_title', _('addons_searchengines_pagetitle'));
+ $this->publish('rss_description', '');
+ $this->render('rss/searchengines', 'rss');
+ }
+ }
+
+ /**
+ * page to display plugins, which is static for now
+ */
+ function _plugins() {
+ $this->layout = 'mozilla';
+ $this->pageTitle = _('addons_plugins_pagetitle').' :: '.sprintf(_('addons_home_pagetitle'), APP_PRETTYNAME);
+ $this->publish('subpagetitle', sprintf(_('addons_plugins_main_header'), APP_PRETTYNAME));
+ $this->render('plugins');
+ return;
+ }
+
+ /**
+ * dictionaries / language tools landing page
+ */
+ function _dictionaries() {
+ global $valid_status, $native_languages;
+
+ $format = (isset($this->namedArgs['format']) ? $this->namedArgs['format'] : 'html');
+
+ // get list of target locales
+ $conditions = array(
+ 'Addon.addontype_id' => array(ADDON_DICT, ADDON_LPAPP),
+ 'Addon.status' => STATUS_PUBLIC,
+ 'Addon.inactive' => 0
+ );
+ $this->Addon->unbindfully();
+ $target_locales_raw = $this->Addon->findAll($conditions, "DISTINCT(LOWER(`target_locale`)) as 'target_locale'");
+ $target_locales = array();
+ foreach ($target_locales_raw as $tloc) $target_locales[] = $tloc[0]['target_locale'];
+ unset($target_locales_raw);
+
+ // get list of dictionaries and language packs for each target locale
+ $dicts = array();
+ foreach($target_locales as $tloc) {
+ // prepare results array for this target locale
+ $dicts[$tloc] = array(
+ ADDON_DICT => array(),
+ ADDON_LPAPP => array()
+ );
+
+ // get addons for this target locale
+ $conditions = array(
+ 'LOWER(Addon.target_locale)' => $tloc,
+ 'Addon.addontype_id' => array(ADDON_DICT, ADDON_LPAPP),
+ 'Addon.status' => STATUS_PUBLIC,
+ 'Addon.inactive' => 0
+ );
+ $this->Addon->unbindfully();
+ $dicts_raw = $this->Addon->findAll($conditions, null, null, null, null, 2);
+
+ $_dict_ids = array();
+ foreach ($dicts_raw as $_dict)
+ $_dict_ids[] = $_dict['Addon']['id'];
+ $tloc_dicts = array();
+ $this->Addon->unbindFully();
+ $tloc_dicts = $this->Addon->getListAddons($_dict_ids, array(STATUS_PUBLIC), null, true);
+ foreach ($tloc_dicts as $dict) { // add add-ons to results array
+ if (empty($dict['File'])) continue;
+
+ // purge add-ons incompatible with this app
+ $compat = $this->Version->getCompatibleApps($dict['Version'][0]['id']);
+ $thisapp_compat = false;
+ foreach ($compat as $compat_app)
+ $thisapp_compat = $thisapp_compat || ($compat_app['Application']['application_id'] == APP_ID);
+ if (!$thisapp_compat) continue;
+
+ $dicts[$tloc][$dict['Addon']['addontype_id']][] = $dict;
+ }
+ unset($dict, $compat, $thisapp_compat, $compat_app);
+
+ /* determine the effective display name for this target locale */
+ $locale_parts = explode('-', strtolower(str_replace('_', '-', $tloc)));
+ // normalize region part
+ if (isset($locale_parts[1])) $locale_parts[1] = strtoupper($locale_parts[1]);
+ $normalized_locale = implode('-', $locale_parts);
+
+ $displayname = false;
+ while (true) {
+ $locale = strtolower(implode('-', $locale_parts));
+ if (in_array($locale, array_map('strtolower', array_keys($native_languages)))) {
+ $_temp = array_change_key_case($native_languages, CASE_LOWER);
+ $displayname = $_temp[$locale]['English'];
+ $localname = $_temp[$locale]['native'];
+ break;
+ }
+ /* shorten locale code if possible, then try again */
+ array_pop($locale_parts);
+ if (empty($locale_parts)) break;
+ }
+ if (!$displayname) {
+ /* no locale found, use add-on name and add locale code */
+ if (!empty($dicts[$tloc][ADDON_DICT])) {
+ $_dict = $dicts[$tloc][ADDON_DICT][0];
+ } elseif (!empty($dicts[$tloc][ADDON_LPAPP])) {
+ $_dict = $dicts[$tloc][ADDON_LPAPP][0];
+ } else {
+ // empty locale? shouldn't happen, drop it.
+ unset($dicts[$tloc]);
+ continue;
+ }
+ $displayname = $_dict['Translation']['name']['string']." ({$normalized_locale})";
+ $localname = '';
+ unset($_dict);
+ }
+ /* if we had to shorten the locale, add the code to the local
+ * name to disambiguate different regional dialects
+ */
+ if (!empty($localname) && strtolower($locale) != strtolower($normalized_locale))
+ $localname .= " ({$normalized_locale})";
+ /* store values in result array for view to use */
+ $dicts[$tloc]['displayname'] = $displayname;
+ $dicts[$tloc]['localname'] = $localname;
+ }
+ // sort dictionary list by effective display name
+ uasort($dicts, create_function('$a,$b', 'return strcasecmp($a["displayname"],$b["displayname"]);'));
+ $this->publish('dicts', $dicts);
+
+ // fetch all platforms
+ $this->Platform->unbindFully();
+ $platforms = $this->Platform->findAll();
+ $this->publish('platforms', $platforms);
+
+ // set layout details
+ $this->pageTitle = _('langtools_header_dicts_and_langpacks') .' :: '
+ . sprintf(_('addons_home_pagetitle'), APP_PRETTYNAME);
+ $this->publish('bigHeader', true);
+ $this->publish('bigHeaderText', sprintf(_('addons_home_header_details'), APP_PRETTYNAME));
+ $this->layout = 'mozilla';
+ $this->set('collapse_categories', true);
+
+ $this->render('dictionaries');
+ }
+
+ /**
+ * Themes/Interface Customizations landing page
+ */
+ function _themes() {
+ global $valid_status;
+
+ $valid_status = array(STATUS_PUBLIC);
+
+ $format = (isset($this->namedArgs['format']) ? $this->namedArgs['format'] : 'html');
+
+ // fetch a list of all subcategories
+ $subcats = $this->Amo->getTags(APP_ID, ADDON_THEME);
+ $this->publish('subcats', $subcats);
+
+ // make subcategory ID list to grab recommendations from
+ $subcat_ids = array();
+ foreach ($subcats as $subcat)
+ $subcat_ids[] = $subcat['Tag']['id'];
+
+ // fetch up to 2 recommended add-ons
+ $_feat_ids = $this->AddonTag->getRandomAddons($subcat_ids, true, 4);
+ if (!empty($_feat_ids)) {
+ $featureAddons = $this->Addon->getListAddons($_feat_ids, $valid_status,
+ null, true);
+ } else {
+ $featureAddons = array();
+ }
+ $this->publish('featureAddons', $featureAddons);
+
+ // fetch all platforms
+ $this->Platform->unbindFully();
+ $platforms = $this->Platform->findAll();
+ $this->publish('platforms', $platforms);
+
+ // set layout details
+ $this->set('content_wide', true); // display 2 features next to each other
+ $this->set('collapse_categories', true);
+ $this->pageTitle = sprintf(___('addons_browse_all_themes_title'), APP_PRETTYNAME);
+ $this->publish('bigHeader', true);
+ $this->publish('bigHeaderText', sprintf(_('addons_home_header_details'), APP_PRETTYNAME));
+ $this->layout = 'mozilla';
+
+ $this->render('themes_landing');
+ }
+
+ /**
+ * page with recommended addons
+ */
+ function recommended() {
+
+ $this->forceShadowDb();
+
+ //override sandbox, recommended page is only public
+ $this->publish('addonStatus', array(STATUS_PUBLIC));
+ $this->status = array(STATUS_PUBLIC);
+
+ $criteria = "Feature.start < NOW() AND Feature.end > NOW() AND Feature.application_id ='" . APP_ID . "' AND "
+ ."(Feature.locale = '" . LANG . "' or Feature.locale IS NULL)";
+ if (isset($this->namedArgs['format']) && $this->namedArgs['format'] == 'rss') {
+ $isrss = true;
+ $order = "Addon.name ASC";
+ } else {
+ $isrss = false;
+ $order = "RAND()";
+ }
+
+ $_addon_ids = array();
+
+
+ if(isset($this->namedArgs['cat']))
+ {
+ $category = $this->namedArgs['cat'];
+ $this->Amo->clean($category);
+ $criteria = "feature > 0 AND tag_id='".$category."'";
+ $featAddons = $this->AddonTag->findAll($criteria);
+
+ foreach ($featAddons as $_addon)
+ $_addon_ids[] = $_addon['AddonTag']['addon_id'];
+
+ } else {
+ $featAddons = $this->Feature->findAll($criteria);
+ foreach ($featAddons as $_addon)
+ $_addon_ids[] = $_addon['Addon']['id'];
+ }
+ if (!empty($_addon_ids)) {
+ $featAddons = $this->Addon->getListAddons($_addon_ids, $this->status, $order, true);
+ } else {
+ $featAddons = array();
+ }
+
+
+ if (!$isrss) {
+ // get platforms (if we are not in RSS mode)
+ $this->Platform->unbindFully();
+ $platforms = $this->Platform->findAll();
+ $this->publish('platforms', $platforms);
+
+ $this->layout='mozilla';
+ $this->pageTitle = _('addons_recommended_pagetitle').' :: '.sprintf(_('addons_home_pagetitle'), APP_PRETTYNAME);
+ $this->publish('addons', $featAddons);
+ $this->publish('rssAdd', array('/recommended/format:rss'));
+ $this->publish('subpagetitle', _('addons_recommended_title'));
+ $this->render();
+ } else {
+ $this->publish('addons', $featAddons);
+ $this->publish('rss_title', _('addons_recommended_pagetitle').' :: '.sprintf(_('addons_home_pagetitle'), APP_PRETTYNAME));
+ $this->publish('rss_description', _('addons_recommended_introduction'));
+ $this->render('rss/addons', 'rss');
+ }
+ }
+
+ /**
+ * page to display eula prior to installation
+ */
+ function policy($lightbox, $addon_id, $file_id=null) {
+ $this->Amo->clean($lightbox);
+ $this->Amo->clean($addon_id);
+ $this->Amo->clean($file_id);
+
+ $this->layout='amo2009';
+
+ if (!$addon_id || !is_numeric($addon_id)) {
+ $this->flash(sprintf(_('error_missing_argument'), 'addon_id'), '/', 3);
+ return;
+ }
+
+ $this->Addon->unbindFully();
+ $this->Addon->bindModel(
+ array(
+ 'hasAndBelongsToMany' => array(
+ 'Tag' => array(
+ 'className' => 'Tag',
+ 'joinTable' => 'addons_tags',
+ 'foreignKey' => 'addon_id',
+ 'associationForeignKey'=> 'tag_id'
+ ),
+ 'User' => array(
+ 'className' => 'User',
+ 'joinTable' => 'addons_users',
+ 'foreignKey' => 'addon_id',
+ 'associationForeignKey'=> 'user_id'
+ )
+ )
+ )
+ );
+
+ $this_addon = $this->Addon->findById($addon_id);
+ if (empty($this_addon)) {
+ $this->flash(_('error_addon_notfound'), '/', 3);
+ return;
+ }
+
+ if (isset($file_id)) {
+ $this->File->unbindFully();
+ $this_file = $this->File->findById($file_id);
+ $this_addon['Version'] = $this->Version->findAllById($this_file['File']['version_id'], null, null, 0);
+
+ // is this the latest public version?
+ if ($this_addon['Addon']['status'] == STATUS_PUBLIC) {
+ $latest_version_id = $this->Version->getVersionByAddonId($addon_id, $this_addon['Addon']['status']);
+ $this->publish('is_latest', ($latest_version_id === $this_addon['Version'][0]['Version']['id']), false);
+ } else {
+ $this->publish('is_latest', false, false);
+ }
+
+ $this->Platform->unbindFully();
+ $platforms = $this->Platform->findAllById($this_file['File']['platform_id']);
+ $this->publish('platforms', $platforms);
+ }
+ else {
+ $this->publish('policy', 1);
+ }
+ // get the tags that are related to the addon, so that they have translation data
+ $_related_tag_ids = array();
+ foreach ($this_addon['Tag'] as $tagvalue) {
+ $_related_tag_ids[] = $tagvalue['id'];
+ }
+ $related_tags = $this->Tag->findAll(array('Tag.id' => $_related_tag_ids, 'Tag.application_id' => APP_ID));
+ unset($_related_tag_ids);
+
+
+ $this->publish('relatedTags', $related_tags);
+ $this->publish('addon', $this_addon);
+ $this->pageTitle = sprintf(_('addons_display_pagetitle'), $this_addon['Translation']['name']['string']). ' :: '.sprintf(_('addons_home_pagetitle'), APP_PRETTYNAME);
+
+
+ }
+
+ /**
+ * Display previews for an addon
+ */
+ function previews($id) {
+ $this->Amo->clean($id);
+ $this->layout = 'mozilla';
+
+ if (!$id || !is_numeric($id)) {
+ $this->flash(sprintf(_('error_missing_argument'), 'addon_id'), '/', 3);
+ return;
+ }
+
+ $addon_data = $this->Addon->find(array(
+ 'Addon.id' => $id,
+ 'Addon.inactive' => '0',
+ 'Addon.status' => array(STATUS_PUBLIC, STATUS_SANDBOX, STATUS_NOMINATED)),
+ null , null , 1);
+ if (empty($addon_data)) {
+ $this->flash(_('error_addon_notfound'), '/', 3);
+ return;
+ }
+ if ($addon_data['Addon']['status'] != STATUS_PUBLIC && !$this->sandboxAccess) {
+ $this->flash(_('error_addon_notfound'), '/', 3);
+ return;
+ }
+
+ $previews = $this->Preview->findAllByAddon_Id($id, array('id', 'addon_id', 'caption'));
+ $this->publish('previews', $previews);
+ $this->publish('addon', $addon_data);
+ $_title = sprintf(_('addons_previews_pagetitle'), $addon_data['Translation']['name']['string']);
+ $this->pageTitle = $_title. ' :: '.sprintf(_('addons_home_pagetitle'), APP_PRETTYNAME);
+ $this->publish('subpagetitle', $_title);
+
+ // Pretty previews
+ $this->set('includeSlimbox', 1);
+ $this->set('suppressJQuery', 1);
+
+ $this->render();
+ }
+
+ /**
+ * Display previously released versions of an addon
+ */
+ function versions($id) {
+ global $valid_status;
+
+ $this->Amo->clean($id);
+
+ // unbind addon from all references but its authors
+ $bindusers = array('hasAndBelongsToMany' => array('User' => $this->Addon->hasAndBelongsToMany['User']));
+ $this->Addon->unbindFully();
+ $this->Addon->bindModel($bindusers);
+ $addon = $this->Addon->find(array('Addon.id'=>$id,
+ 'Addon.status'=>$valid_status, 'Addon.inactive'=>0), null, null,
+ null, null, 0);
+ if (empty($addon)) {
+ $this->flash(_('error_addon_notfound'), '/', 3);
+ return;
+ }
+
+ // show all valid (even experimental) statuses on versions page
+ $version_list = $this->Version->getVersionIdsByAddonId($id, $valid_status);
+ //reformat the returned versions array
+ $version_ids = array();
+ $comp_apps_by_id = array();
+ foreach ($version_list as $single_id) {
+ $cur_id = $single_id['Version']['id'];
+ $version_ids[] = $cur_id;
+ $compat_apps = $this->Version->getCompatibleApps($cur_id);
+ $comp_apps_by_id[$cur_id] = array_slice($compat_apps, 0, 1);
+ }
+
+ if (!empty($version_ids)) {
+ $versions = $this->Version->findAllById($version_ids, null, "Version.created DESC", null, null, 1);
+
+ for($i =0 ; $i < count($versions); $i++) {
+ $versions[$i]['Compatibility'] = $comp_apps_by_id[$versions[$i]['Version']['id'] ];
+ }
+ }
+ else
+ $versions = array();
+
+ $this->Platform->unbindFully();
+ $platforms = $this->Platform->findAll();
+ $this->publish('addon', $addon);
+ $this->publish('versions', $versions);
+ $this->publish('platforms', $platforms);
+
+ $_title = sprintf(_('addons_versions_pagetitle'), $addon['Translation']['name']['string']);
+ if (!isset($this->namedArgs['format']) || $this->namedArgs['format'] != 'rss') {
+ $this->publish('addonIconPath', $this->Image->getAddonIconURL($id));
+ $this->pageTitle = $_title. ' :: '.sprintf(_('addons_home_pagetitle'), APP_PRETTYNAME);
+ $this->publish('subpagetitle', $_title);
+ $this->publish('rssAdd', array("/addons/versions/{$id}/format:rss"));
+
+ $this->publish('breadcrumbs', array(
+ sprintf(___('addons_home_pagetitle'), APP_PRETTYNAME) => '/',
+ $addon['Translation']['name']['string'] => "/addon/{$id}"
+ ));
+ $this->render();
+ } else {
+ $this->publish('rss_title', $_title);
+ $this->publish('rss_description', _('addons_versions_history'));
+ $this->render('rss/versions', 'rss');
+ }
+ }
+
+ /**
+ * provide global rss feeds (deprecated)
+ */
+ function rss($type='') {
+ $this->Amo->clean($type);
+ $type = strtolower($type);
+
+ switch($type) {
+ case 'newest':
+ $this->redirect('/browse/type:1/cat:all/format:rss?sort=newest');
+ return;
+ break;
+
+ default:
+ $this->redirect('/');
+ return;
+ }
+ }
+
+}
+
+?>
diff --git a/site/app/controllers/admin_controller.php b/site/app/controllers/admin_controller.php
new file mode 100644
index 0000000..77d305c
--- /dev/null
+++ b/site/app/controllers/admin_controller.php
@@ -0,0 +1,1840 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/e
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * Justin Scott <fligtar@gmail.com>.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Frederic Wenzel <fwenzel@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+class AdminController extends AppController
+{
+ var $name = 'Admin';
+ var $uses = array('Addon', 'Addontype', 'Application', 'Approval', 'Appversion', 'Cannedresponse', 'Collection', 'CollectionPromo', 'Eventlog', 'Feature', 'File', 'Group', 'Platform', 'Tag', 'Translation', 'User', 'Version', 'Memcaching');
+ var $components = array('Amo', 'Audit', 'Developers', 'Error', 'Versioncompare');
+ var $helpers = array('Html', 'Javascript');
+ //These defer to their own access checks
+ var $aclExceptions = array('index', 'summary',
+ 'addonLookup', 'userLookup',
+ 'addontypes', 'tags', 'platforms', 'responses');
+
+ /**
+ * Require login for all actions
+ */
+ function beforeFilter() {
+ //beforeFilter() is apparently called before components are initialized. Cake++
+ $this->Amo->startup($this);
+
+ $this->Amo->checkLoggedIn();
+
+ //Clean post data
+ $this->Amo->clean($this->data, false);
+
+ $this->layout = 'mozilla';
+ $this->pageTitle = 'Mozilla Add-ons :: Admin Control Panel';
+
+ $this->cssAdd = array('admin', 'developers');
+ $this->set('cssAdd', $this->cssAdd);
+
+ $this->set('jsAdd', array('developers',
+ 'jquery-compressed.js',
+ 'jquery.autocomplete.pack.js'));
+ $this->set('suppressJQuery', 1);
+
+ $this->breadcrumbs = array('Admin Control Panel' => '/admin/index');
+ $this->set('breadcrumbs', $this->breadcrumbs);
+
+ $this->set('subpagetitle', 'Admin Control Panel');
+
+ // disable query caching so devcp changes are visible immediately
+ foreach ($this->uses as $_model) {
+ $this->$_model->caching = false;
+ }
+
+ //Get flagged add-on count
+ $flagged = $this->Addon->query("SELECT COUNT(*) FROM addons WHERE adminreview=1");
+ $this->set('flaggedCount', $flagged[0][0]['COUNT(*)']);
+
+ // Used for Feature Manager
+ global $valid_languages;
+
+ //First, see if locale was submitted by form
+ if (!empty($_GET['userlang']) && array_key_exists($_GET['userlang'], $valid_languages)) {
+ define('USERLANG', $_GET['userlang']);
+ }
+ elseif (!empty($_GET['userlang']) && $_GET['userlang'] == 'Unspecified') {
+ define('USERLANG', null);
+ }
+ //Next, try looking in the session
+ elseif ($lsession = $this->Session->read('Features')) {
+ define('USERLANG', $lsession['userlang']);
+ }
+
+ if (!defined('USERLANG')) {
+ define('USERLANG', LANG);
+ }
+
+ //See if application was submitted by form (this is an ID)
+ if (!empty($_GET['userapp'])) {
+ define('USERAPP', $_GET['userapp']);
+ }
+ //Next, try looking in the session
+ elseif ($lsession = $this->Session->read('Features')) {
+ define('USERAPP', $lsession['userapp']);
+ }
+
+ if (!defined('USERAPP')) {
+ define('USERAPP', 1); // Firefox
+ }
+
+ $this->Session->write('Features', array('userlang' => USERLANG, 'userapp' => USERAPP));
+ }
+
+ /**
+ * Index - Show summary
+ */
+ function index() {
+ $this->summary();
+ }
+
+ /**
+ * Admin Summary
+ */
+ function summary() {
+ if (!$this->SimpleAcl->actionAllowed('Admin', '%', $this->Session->read('User'))) {
+ $this->Amo->accessDenied();
+ }
+
+ $this->cssAdd[] = 'summary';
+ $this->publish('cssAdd', $this->cssAdd);
+
+ //Most translations
+ $topLocales = $this->Translation->query("SELECT locale, COUNT(*) as total FROM translations GROUP BY locale ORDER BY total DESC LIMIT 5");
+ $this->set('topLocales', $topLocales);
+
+ //Last 24 hours
+ $timestamp = date('Y-m-d H:i:s', (time() - 86400));
+ $last24['newAddons'] = $this->Addon->query("SELECT COUNT(*) FROM addons WHERE created >= '{$timestamp}'");
+ $last24['updatedAddons'] = $this->Addon->query("SELECT COUNT(*) FROM addons WHERE modified >= '{$timestamp}'");
+ $last24['versions'] = $this->Addon->query("SELECT COUNT(*) FROM versions WHERE created >= '{$timestamp}'");
+ $last24['users'] = $this->Addon->query("SELECT COUNT(*) FROM users WHERE created >= '{$timestamp}'");
+ $last24['reviews'] = $this->Addon->query("SELECT COUNT(*) FROM reviews WHERE created >= '{$timestamp}'");
+ $this->set('last24', $last24);
+
+ //Counts
+ $count['extensions'] = $this->Addon->query("SELECT COUNT(*) FROM addons WHERE addontype_id=".ADDON_EXTENSION);
+ $count['themes'] = $this->Addon->query("SELECT COUNT(*) FROM addons WHERE addontype_id=".ADDON_THEME);
+ $count['dictionaries'] = $this->Addon->query("SELECT COUNT(*) FROM addons WHERE addontype_id=".ADDON_DICT);
+ $count['searchengines'] = $this->Addon->query("SELECT COUNT(*) FROM addons WHERE addontype_id=".ADDON_SEARCH);
+ $now = time();
+ $count['activeSessions'] = $this->Addon->query("SELECT COUNT(*) FROM cake_sessions WHERE expires > {$now}");
+ $this->set('count', $count);
+
+ //Recent activity
+ $logs = $this->Eventlog->findAll(array('type' => 'admin'), null, 'Eventlog.created DESC', 5);
+ $logs = $this->Audit->explainLog($logs);
+ $this->set('logs', $logs);
+
+ $this->set('page', 'summary');
+ $this->render('summary');
+ }
+
+ /**
+ * Add-on Manager
+ */
+ function addons($action = '', $id = 0, $file_id = 0) {
+ $this->breadcrumbs['Add-on Manager'] = '/admin/addons';
+ $this->set('breadcrumbs', $this->breadcrumbs);
+
+ if (!empty($id)) {
+ $this->Amo->clean($id);
+ $this->Addon->id = $id;
+
+ if ($action == 'status') {
+ $this->_addonStatus($id);
+ return;
+ }
+ elseif ($action == 'hash') {
+ $this->_addonHash($id, $file_id);
+ return;
+ }
+ }
+
+ if (!empty($_GET['q'])) {
+ $q = $_GET['q'];
+ $this->Amo->clean($q);
+
+ //See if query has an add-on id in brackets
+ if (preg_match('/\[(\d+)\]/', $q, $matches)) {
+ $this->Addon->id = $matches[1];
+ $this->_addonStatus($this->Addon->id);
+ return;
+ }
+ //Find add-on by exact name. If not found, use next closest
+ elseif ($addon = $this->Addon->query("SELECT addons.id FROM addons LEFT JOIN translations ON addons.name=translations.id WHERE translations.locale='".LANG."' AND translations.localized_string='{$q}' LIMIT 1")) {
+ $this->data = '';
+ $this->Addon->id = $addon[0]['addons']['id'];
+ $this->_addonStatus($this->Addon->id);
+ return;
+ }
+ elseif ($addon = $this->Addon->query("SELECT addons.id FROM addons LEFT JOIN translations ON addons.name=translations.id WHERE translations.locale='".LANG."' AND translations.localized_string LIKE '%{$q}%' LIMIT 1")) {
+ $this->data = '';
+ $this->Addon->id = $addon[0]['addons']['id'];
+ $this->_addonStatus($this->Addon->id);
+ return;
+ }
+ }
+
+ $this->set('page', 'addons');
+ $this->render('addons');
+ }
+
+ /**
+ * Manage add-on statuses
+ */
+ function _addonStatus($id) {
+ if (!empty($this->data)) {
+ $this->Addon->save($this->data['Addon']);
+
+ //Log admin action
+ $this->Eventlog->log($this, 'admin', 'addon_status', 'status', $id, $this->data['Addon']['status']);
+
+ if (!empty($this->data['File'])) {
+ foreach ($this->data['File']['id'] as $k => $file_id) {
+ $this->File->id = $file_id;
+ $file = $this->File->read();
+ if ($file['File']['status'] != $this->data['File']['status'][$k]) {
+ // status was changed
+ $this->File->save(array(
+ 'status' => $this->data['File']['status'][$k],
+ 'datestatuschanged' => $this->Amo->getNOW()
+ ));
+
+ // If public, move to public rsync area
+ if ($this->data['File']['status'][$k] == STATUS_PUBLIC) {
+ $this->Amo->copyFileToPublic($id, $file['File']['filename']);
+ }
+ }
+ }
+ }
+
+ $this->flash('Statuses updated!', '/admin/addons/status/'.$id);
+ return;
+ }
+
+ $platforms = $this->Amo->getPlatformName();
+ $this->set('platforms', $platforms);
+
+ $statuses = $this->Amo->getApprovalStatus();
+ $this->set('addonStatuses', array(
+ STATUS_NULL => $statuses[STATUS_NULL],
+ STATUS_SANDBOX => $statuses[STATUS_SANDBOX],
+ STATUS_NOMINATED => $statuses[STATUS_NOMINATED],
+ STATUS_PUBLIC => $statuses[STATUS_PUBLIC],
+ STATUS_DISABLED => $statuses[STATUS_DISABLED]
+ ));
+ $this->set('fileStatuses', array(
+ STATUS_NULL => $statuses[STATUS_NULL],
+ STATUS_SANDBOX => $statuses[STATUS_SANDBOX],
+ STATUS_PENDING => $statuses[STATUS_PENDING],
+ STATUS_PUBLIC => $statuses[STATUS_PUBLIC],
+ STATUS_DISABLED => $statuses[STATUS_DISABLED]
+ ));
+
+ if ($addon = $this->Addon->read()) {
+ foreach ($addon['Version'] as $k => $version) {
+ $files = $this->File->findAllByVersion_id($version['id']);
+ $addon['Version'][$k]['File'] = $files;
+ }
+ }
+
+ $this->set('addon', $addon);
+
+ $this->set('page', 'addons');
+ $this->render('addons_status');
+ }
+
+ /**
+ * Recalculate file hash and size
+ */
+ function _addonHash($id, $file_id) {
+ $this->File->id = $file_id;
+ $file = $this->File->read();
+
+ $file = REPO_PATH.'/'.$id.'/'.$file['File']['filename'];
+ if (file_exists($file)) {
+ $size = round(filesize($file)/1024, 0); //in KB
+ $hash = 'sha256:'.hash_file("sha256", $file);
+
+ $this->File->save(array('size' => $size, 'hash' => $hash));
+
+ //Log admin action
+ $this->Eventlog->log($this, 'admin', 'file_recalchash', null, $file_id);
+
+ $this->flash('File hash and size recalculated!', '/admin/addons/status/'.$id);
+ }
+ else {
+ $this->flash('File does not exist.', '/admin/addons/status/'.$id);
+ }
+ return;
+ }
+
+ /**
+ * Application Manager
+ */
+ function applications($action = '', $id = 0) {
+ $this->breadcrumbs['Application Manager'] = '/admin/applications';
+ $this->set('breadcrumbs', $this->breadcrumbs);
+
+ if (!empty($action)) {
+ $this->Amo->clean($id);
+ $this->Amo->clean($_POST);
+
+ if ($action != 'versions') {
+ if ($action == 'edit') {
+ $this->_applicationEdit($id);
+ }
+ elseif ($action == 'create') {
+ $this->_applicationCreate();
+ }
+ return;
+ }
+
+ //Add new version
+ if (!empty($_POST['add'])) {
+ $version = $_POST['app'.$id.'_new'];
+ if (!empty($version)) {
+ $this->Appversion->execute("INSERT INTO appversions (application_id, version) VALUES('{$id}', '{$version}')");
+
+ //Log admin action
+ $this->Eventlog->log($this, 'admin', 'appversion_create', null, mysql_insert_id(), $version, null, $id);
+
+ $this->flash('Version successfully added!', '/admin/applications');
+ return;
+ }
+ else {
+ $this->Error->addError('Cannot add empty version.');
+ }
+ }
+
+ //Remove version
+ if (!empty($_POST['remove'])) {
+ $vid = $_POST['app'.$id.'_remove'];
+ if (!empty($vid)) {
+ //Pull appversion for log
+ $this->Appversion->id = $vid;
+ $appversion = $this->Appversion->read();
+
+ $count = $this->Appversion->query("SELECT COUNT(*) FROM applications_versions WHERE min='{$vid}' OR max='{$vid}'");
+
+ if ($count[0][0]['COUNT(*)'] == 0) {
+ $this->Appversion->execute("DELETE FROM appversions WHERE id='{$vid}' LIMIT 1");
+
+ //Log admin action
+ $this->Eventlog->log($this, 'admin', 'appversion_delete', null, $vid, null, $appversion['Appversion']['version'], $id);
+
+ $this->flash('Version successfully removed!', '/admin/applications');
+ }
+ else {
+ $this->flash('Cannot delete application version: files still associated with it.', '/admin/applications');
+ }
+ return;
+ }
+ else {
+ $this->Error->addError('Please select a version to remove.');
+ }
+ }
+ }
+
+ if ($applications = $this->Application->findAll(null, null, null, null, null, -1)) {
+ foreach ($applications as $k => $application) {
+ $appversions = $this->Appversion->findAllByApplication_id($application['Application']['id'], null, null, null);
+ $this->Versioncompare->sortAppversionArray($appversions);
+ $applications[$k]['Appversions'] = $appversions;
+ }
+ }
+
+ $this->set('applications', $applications);
+ $this->set('errors', $this->Error->errors);
+ $this->set('page', 'applications');
+ $this->render('applications');
+ }
+
+ /**
+ * Edit Applications
+ */
+ function _applicationEdit($id) {
+ $this->breadcrumbs['Edit Application'] = '/admin/applications/edit/'.$id;
+ $this->set('breadcrumbs', $this->breadcrumbs);
+
+ $this->Application->id = $id;
+
+ if (!empty($this->data)) {
+ $this->Application->save($this->data['Application']);
+
+ //Save translated fields (name, shortname)
+ $this->Developers->saveTranslations($this->data, array('Application'));
+
+ //Log admin action
+ $this->Eventlog->log($this, 'admin', 'application_edit', null, $id);
+
+ $this->flash('Application updated!', '/admin/applications');
+ return;
+ }
+
+ $application = $this->Application->findById($this->Application->id, null, null, -1);
+
+ $this->set('application', $application);
+
+ $localizedFields = array(
+ 'name' => array(
+ 'type' => 'input',
+ 'display' => 'Application Name',
+ 'model' => 'Application',
+ 'field' => 'name',
+ 'attributes' => array(
+ 'size' => 40
+ )
+ ),
+ 'shortname' => array(
+ 'type' => 'input',
+ 'display' => 'Application Shortname',
+ 'model' => 'Application',
+ 'field' => 'shortname',
+ 'attributes' => array()
+ )
+ );
+
+ //Retrieve language arrays from bootstrap.
+ global $valid_languages, $native_languages;
+ foreach (array_keys($valid_languages) as $key) {
+ $languages[$key] = $native_languages[$key]['native'];
+
+ $this->Application->setLang($key, $this);
+ $appL = $this->Application->findById($this->Application->id, null, null, -1);
+
+ foreach ($appL['Translation'] as $field => $translation) {
+ if ($translation['locale'] == $key) {
+ $info[$key][$field] = $translation['string'];
+ }
+ else {
+ $info[$key][$field] = '';
+ }
+ }
+ }
+
+ //Set up localebox info
+ $this->set('localebox', array('info' => $info,
+ 'defaultLocale' => 'en-US',
+ 'languages' => $languages,
+ 'localizedFields' => $localizedFields));
+
+ $this->set('page', 'applications');
+ $this->render('applications_edit');
+ }
+
+ /**
+ * Create Application
+ */
+ function _applicationCreate() {
+ $this->breadcrumbs['Create Application'] = '/admin/applications/create';
+ $this->set('breadcrumbs', $this->breadcrumbs);
+
+ if (!empty($this->data)) {
+ $this->Application->save($this->data['Application']);
+
+ //Log admin action
+ $this->Eventlog->log($this, 'admin', 'application_create', null, $this->Application->getLastInsertID());
+
+ //Save translated fields (name, description)
+ $this->Developers->saveTranslations($this->data, array('Application'));
+
+ $this->flash('Application created!', '/admin/applications');
+ return;
+ }
+
+ $localizedFields = array(
+ 'name' => array(
+ 'type' => 'input',
+ 'display' => 'Application Name',
+ 'model' => 'Application',
+ 'field' => 'name',
+ 'attributes' => array(
+ 'size' => 40
+ )
+ ),
+ 'shortname' => array(
+ 'type' => 'input',
+ 'display' => 'Application Shortname',
+ 'model' => 'Application',
+ 'field' => 'shortname',
+ 'attributes' => array()
+ )
+ );
+
+ //Retrieve language arrays from bootstrap.
+ global $valid_languages, $native_languages;
+ foreach (array_keys($valid_languages) as $key) {
+ $languages[$key] = $native_languages[$key]['native'];
+
+ $this->Application->setLang($key, $this);
+
+ foreach ($this->Application->translated_fields as $field) {
+ $info[$key][$field] = '';
+ }
+ }
+
+ //Set up localebox info
+ $this->set('localebox', array('info' => $info,
+ 'defaultLocale' => 'en-US',
+ 'languages' => $languages,
+ 'localizedFields' => $localizedFields));
+
+ $this->set('page', 'applications');
+ $this->render('applications_create');
+ }
+
+ /**
+ * Collections Manager
+ */
+ function collections($action='') {
+ switch($action) {
+ case 'promobox':
+ $this->_collectionsPromoBox();
+ break;
+ default:
+ $this->set('page', 'collections');
+ $this->render('collections');
+ break;
+ }
+ }
+
+ function _collectionsPromoBox() {
+
+ if (!empty($_POST)) {
+ switch ($_POST['action']) {
+ case 'add':
+ global $valid_languages;
+ // It's easiest just to split out the stuff we need here and pass it into a custom function.
+ if (preg_match('/\[(\d+)\]/', $this->data['Collection']['name'], $matches)) {
+ $_collection_id = $matches[1];
+ } else {
+ $this->Error->addError('Collection ID must be specified in brackets.');
+ }
+
+ if (in_array($_POST['locale'], array_keys($valid_languages))) {
+ $_locale = $_POST['locale'];
+ } else if ($_POST['locale'] == 'all') {
+ $_locale = '';
+ } else {
+ $this->Error->addError('Invalid locale specified.');
+ }
+
+ if (in_array($_POST['titletagline'], array_keys($this->CollectionPromo->titles_and_taglines))) {
+ $_titletagline = $_POST['titletagline'];
+ } else {
+ $this->Error->addError('Invalid Title/TagLine specified.');
+ }
+
+ if ($this->Error->noErrors()) {
+ $this->CollectionPromo->promoteCollection($_collection_id, $_titletagline, $_locale);
+ $this->data = array(); // reset so it doesn't prefill the box again
+ $this->publish('changeSuccess', true);
+ }
+ break;
+ case 'delete':
+ list($_collection_id, $_titletagline, $_locale) = explode('--',$_POST['target']);
+ $_locale = ($_locale == 'all') ? '' : $_locale;
+
+ if ($this->CollectionPromo->demoteCollection($_collection_id, $_titletagline, $_locale) === false) {
+ $this->Error->addError('Failed to demote collection.');
+ } else {
+ $this->publish('changeSuccess', true);
+ }
+ break;
+ }
+ }
+
+ $this->set('titles_and_taglines', $this->CollectionPromo->titles_and_taglines);
+ $this->publish('promoted_collections', $this->CollectionPromo->findAll());
+ $this->set('locales', LANGUAGE_CONFIG::getAllValidLanguages('english',true));
+
+ $this->set('errors', $this->Error->errors);
+ $this->set('page', 'collections');
+ $this->set('subpage', 'promobox');
+ $this->render('collections_promobox');
+ }
+
+ /**
+ * Category Manager
+ */
+ function tags($action = '', $id = 0) {
+ //Part of the Lists permission
+ if (!$this->SimpleAcl->actionAllowed('Admin', 'lists', $this->Session->read('User'))) {
+ $this->Amo->accessDenied();
+ }
+
+ $this->breadcrumbs['Category Manager'] = '/admin/tags';
+ $this->set('breadcrumbs', $this->breadcrumbs);
+
+ $applications = array('All');
+ $_applications = $this->Amo->getApplicationName();
+ if (!empty($_applications)) {
+ foreach ($_applications as $app_id => $app_name) {
+ $applications[$app_id] = $app_name;
+ }
+ }
+ $this->set('applications', $applications);
+
+ $addontypes = $this->Addontype->getNames();
+ $this->set('addontypes', $addontypes);
+
+ if (!empty($action)) {
+ $this->Amo->clean($id);
+
+ if ($action == 'edit') {
+ $this->_tagEdit($id);
+ return;
+ }
+ elseif ($action == 'create') {
+ $this->_tagCreate($id);
+ return;
+ }
+ }
+
+ $tags = $this->Tag->findAll();
+
+ foreach ($tags as $k => $tag) {
+ $tags[$k]['application'] = !empty($applications[$tag['Tag']['application_id']]) ? $applications[$tag['Tag']['application_id']] : 'All';
+ $tags[$k]['addontype'] = $addontypes[$tag['Tag']['addontype_id']];
+
+ $count = $this->Tag->query("SELECT COUNT(*) FROM addons_tags WHERE tag_id='{$tag['Tag']['id']}'");
+ $tags[$k]['count'] = $count[0][0]['COUNT(*)'];
+ }
+
+ $this->set('tags', $tags);
+ $this->set('page', 'lists');
+ $this->set('subpage', 'tags');
+ $this->render('tags');
+ }
+
+ /**
+ * Edit Tags
+ */
+ function _tagEdit($id) {
+ $this->breadcrumbs['Edit Category'] = '/admin/tags/edit/'.$id;
+ $this->set('breadcrumbs', $this->breadcrumbs);
+
+ $this->Tag->id = $id;
+
+ if (!empty($this->data)) {
+ //Delete
+ if (!empty($_POST['delete'])) {
+ //Retrieve tag to store name in log
+ $tag = $this->Tag->read();
+
+ $this->Group->execute("DELETE FROM addons_tags WHERE tag_id='{$id}'");
+ $this->Group->execute("DELETE FROM tags WHERE id='{$id}'");
+
+ //Log admin action
+ $this->Eventlog->log($this, 'admin', 'tag_delete', null, $id, null, $tag['Translation']['name']['string']);
+
+ $this->flash('Category deleted successfully.', '/admin/tags');
+ return;
+ }
+ //Edit
+ else {
+ // Must manually set application id to null if "All" is selected
+ if (empty($this->data['Tag']['application_id']))
+ $this->data['Tag']['application_id'] = NULL;
+
+ $this->Tag->save($this->data['Tag']);
+ $this->Tag->execute("UPDATE tags SET weight='".$this->data['Tag']['weight']."' WHERE id='{$id}'");
+
+ //Log admin action
+ $this->Eventlog->log($this, 'admin', 'tag_edit', null, $id);
+
+ //Save translated fields (name, description)
+ $this->Developers->saveTranslations($this->data, array('Tag'));
+
+ $this->flash('Category updated!', '/admin/tags');
+ return;
+ }
+ }
+
+ $tag = $this->Tag->read();
+
+ $this->set('tag', $tag);
+
+ $localizedFields = array(
+ 'name' => array(
+ 'type' => 'input',
+ 'display' => 'Category Name',
+ 'model' => 'Tag',
+ 'field' => 'name',
+ 'attributes' => array(
+ 'size' => 40
+ )
+ ),
+ 'description' => array(
+ 'type' => 'textarea',
+ 'display' => 'Category Description',
+ 'model' => 'Tag',
+ 'field' => 'description',
+ 'attributes' => array(
+ 'cols' => 60,
+ 'rows' => 3
+ )
+ )
+ );
+
+ //Retrieve language arrays from bootstrap.
+ global $valid_languages, $native_languages;
+ foreach (array_keys($valid_languages) as $key) {
+ $languages[$key] = $native_languages[$key]['native'];
+
+ $this->Tag->setLang($key, $this);
+ $tagL = $this->Tag->read();
+
+ foreach ($tagL['Translation'] as $field => $translation) {
+ if ($translation['locale'] == $key) {
+ $info[$key][$field] = $translation['string'];
+ }
+ else {
+ $info[$key][$field] = '';
+ }
+ }
+ }
+
+ //Set up localebox info
+ $this->set('localebox', array('info' => $info,
+ 'defaultLocale' => 'en-US',
+ 'languages' => $languages,
+ 'localizedFields' => $localizedFields));
+
+ $this->set('page', 'lists');
+ $this->set('subpage', 'tags');
+ $this->render('tags_edit');
+ }
+
+ /**
+ * Create Tags
+ */
+ function _tagCreate() {
+ $this->breadcrumbs['Create Category'] = '/admin/tags/create';
+ $this->set('breadcrumbs', $this->breadcrumbs);
+
+ if (!empty($this->data)) {
+ // Must manually set application id to null if "All" is selected
+ if (empty($this->data['Tag']['application_id']))
+ $this->data['Tag']['application_id'] = NULL;
+
+ $this->Tag->save($this->data['Tag']);
+
+ //Log admin action
+ $this->Eventlog->log($this, 'admin', 'tag_create', null, $this->Tag->getLastInsertID());
+
+ //Save translated fields (name, description)
+ $this->Developers->saveTranslations($this->data, array('Tag'));
+
+ $this->flash('Category created!', '/admin/tags');
+ return;
+ }
+
+ $localizedFields = array(
+ 'name' => array(
+ 'type' => 'input',
+ 'display' => 'Category Name',
+ 'model' => 'Tag',
+ 'field' => 'name',
+ 'attributes' => array(
+ 'size' => 40
+ )
+ ),
+ 'description' => array(
+ 'type' => 'textarea',
+ 'display' => 'Category Description',
+ 'model' => 'Tag',
+ 'field' => 'description',
+ 'attributes' => array(
+ 'cols' => 60,
+ 'rows' => 3
+ )
+ )
+ );
+
+ //Retrieve language arrays from bootstrap.
+ global $valid_languages, $native_languages;
+ foreach (array_keys($valid_languages) as $key) {
+ $languages[$key] = $native_languages[$key]['native'];
+
+ $this->Tag->setLang($key, $this);
+
+ foreach ($this->Tag->translated_fields as $field) {
+ $info[$key][$field] = '';
+ }
+ }
+
+ //Set up localebox info
+ $this->set('localebox', array('info' => $info,
+ 'defaultLocale' => 'en-US',
+ 'languages' => $languages,
+ 'localizedFields' => $localizedFields));
+
+ $this->set('page', 'lists');
+ $this->set('subpage', 'tags');
+ $this->render('tags_create');
+ }
+
+
+ /**
+ * Platform Manager
+ */
+ function platforms($action = '', $id = 0) {
+ //Part of the Lists permission
+ if (!$this->SimpleAcl->actionAllowed('Admin', 'lists', $this->Session->read('User'))) {
+ $this->Amo->accessDenied();
+ }
+
+ $this->breadcrumbs['Platform Manager'] = '/admin/platforms';
+ $this->set('breadcrumbs', $this->breadcrumbs);
+
+ if (!empty($action)) {
+ $this->Amo->clean($id);
+
+ if ($action == 'edit') {
+ $this->_platformEdit($id);
+ return;
+ }
+ elseif ($action == 'create') {
+ $this->_platformCreate($id);
+ return;
+ }
+ }
+
+ $platforms = $this->Platform->findAll(null, null, null, null, null, -1);
+
+ $this->set('platforms', $platforms);
+ $this->set('page', 'lists');
+ $this->set('subpage', 'platforms');
+ $this->render('platforms');
+ }
+
+ /**
+ * Edit Platforms
+ */
+ function _platformEdit($id) {
+ $this->breadcrumbs['Edit Platform'] = '/admin/platforms/edit/'.$id;
+ $this->set('breadcrumbs', $this->breadcrumbs);
+
+ $this->Platform->id = $id;
+
+ if (!empty($this->data)) {
+ //Delete
+ if (!empty($_POST['delete'])) {
+ //Retrieve platform to store name in log
+ $platform = $this->Platform->findById($this->Platform->id, null, null, -1);
+
+ $this->Group->execute("DELETE FROM platforms WHERE id='{$id}'");
+
+ //Log admin action
+ $this->Eventlog->log($this, 'admin', 'platform_delete', null, $id, null, $platform['Translation']['name']['string']);
+
+ $this->flash('Platform deleted successfully.', '/admin/platforms');
+ return;
+ }
+ //Edit
+ else {
+ //Save translated fields (name, description)
+ $this->Developers->saveTranslations($this->data, array('Platform'));
+
+ //Log admin action
+ $this->Eventlog->log($this, 'admin', 'platform_edit', null, $id);
+
+ $this->flash('Platform updated!', '/admin/platforms');
+ return;
+ }
+ }
+
+ $platform = $this->Platform->findById($this->Platform->id, null, null, -1);
+
+ $this->set('platform', $platform);
+
+ $localizedFields = array(
+ 'name' => array(
+ 'type' => 'input',
+ 'display' => 'Name',
+ 'model' => 'Platform',
+ 'field' => 'name',
+ 'attributes' => array(
+ 'size' => 40
+ )
+ ),
+ 'shortname' => array(
+ 'type' => 'input',
+ 'display' => 'Shortname',
+ 'model' => 'Platform',
+ 'field' => 'shortname',
+ 'attributes' => array(
+ 'size' => 40
+ )
+ )
+ );
+
+ //Retrieve language arrays from bootstrap.
+ global $valid_languages, $native_languages;
+ foreach (array_keys($valid_languages) as $key) {
+ $languages[$key] = $native_languages[$key]['native'];
+
+ $this->Platform->setLang($key, $this);
+ $platformL = $this->Platform->read();
+
+ foreach ($platformL['Translation'] as $field => $translation) {
+ if ($translation['locale'] == $key) {
+ $info[$key][$field] = $translation['string'];
+ }
+ else {
+ $info[$key][$field] = '';
+ }
+ }
+ }
+
+ //Set up localebox info
+ $this->set('localebox', array('info' => $info,
+ 'defaultLocale' => 'en-US',
+ 'languages' => $languages,
+ 'localizedFields' => $localizedFields));
+
+ $this->set('page', 'lists');
+ $this->set('subpage', 'platforms');
+ $this->render('platforms_edit');
+ }
+
+ /**
+ * Create Platforms
+ */
+ function _platformCreate() {
+ $this->breadcrumbs['Create Platform'] = '/admin/platforms/create';
+ $this->set('breadcrumbs', $this->breadcrumbs);
+
+ if (!empty($this->data)) {
+ //Save translated fields (name, description)
+ $this->Developers->saveTranslations($this->data, array('Platform'));
+
+ //Log admin action
+ $this->Eventlog->log($this, 'admin', 'platform_create', null, $this->Tag->getLastInsertID());
+
+ $this->flash('Platform created!', '/admin/platforms');
+ return;
+ }
+
+ $localizedFields = array(
+ 'name' => array(
+ 'type' => 'input',
+ 'display' => 'Name',
+ 'model' => 'Platform',
+ 'field' => 'name',
+ 'attributes' => array(
+ 'size' => 40
+ )
+ ),
+ 'shortname' => array(
+ 'type' => 'input',
+ 'display' => 'Shortname',
+ 'model' => 'Platform',
+ 'field' => 'shortname',
+ 'attributes' => array(
+ 'size' => 40
+ )
+ )
+ );
+
+ //Retrieve language arrays from bootstrap.
+ global $valid_languages, $native_languages;
+ foreach (array_keys($valid_languages) as $key) {
+ $languages[$key] = $native_languages[$key]['native'];
+
+ $this->Tag->setLang($key, $this);
+
+ foreach ($this->Tag->translated_fields as $field) {
+ $info[$key][$field] = '';
+ }
+ }
+
+ //Set up localebox info
+ $this->set('localebox', array('info' => $info,
+ 'defaultLocale' => 'en-US',
+ 'languages' => $languages,
+ 'localizedFields' => $localizedFields));
+
+ $this->set('page', 'lists');
+ $this->set('subpage', 'platforms');
+ $this->render('platforms_create');
+ }
+
+ /**
+ * Feature Manager
+ */
+ function features($action = '', $id = 0) {
+ global $valid_languages;
+ $this->breadcrumbs['Feature Manager'] = '/admin/features';
+ $this->set('breadcrumbs', $this->breadcrumbs);
+
+ if (!empty($action)) {
+
+ switch ($action) {
+ case 'update':
+ if (!empty($_POST['save']) && is_numeric($id)) {
+
+ $_feature['id'] = $id;
+ $_feature['start'] = $_POST['feature'.$id.'_startdate'];
+ $_feature['end'] = $_POST['feature'.$id.'_enddate'];
+
+
+ if ($this->Feature->save($_feature)) {
+ //Log admin action
+ $this->Eventlog->log($this, 'admin', 'feature_edit', null, $id);
+
+ $this->flash('Feature modified', '/admin/features');
+ return;
+ } else {
+ $this->Error->addError('Could not modify feature (invalid data?)');
+ }
+ }
+ if (!empty($_POST['remove']) && is_numeric($id)) {
+ $this->Feature->execute("DELETE FROM features WHERE id='{$id}' LIMIT 1");
+
+ //Log admin action
+ $this->Eventlog->log($this, 'admin', 'feature_remove', null, $id, null, $id);
+
+ $this->flash("Feature successfully removed ({$id})", '/admin/features');
+ return;
+
+ }
+ break;
+ case 'create':
+ if (!empty($_POST['add'])) {
+ if (preg_match('/\[(\d+)\]/', $_POST['q'], $matches)) {
+ $this->data['Feature']['addon_id'] = $matches[1];
+ } else {
+ $this->Feature->invalidate('id');
+ $this->Error->addError('Add-on ID must be specified in brackets.');
+ }
+ $_addon = $this->Addon->getAddon($this->data['Feature']['addon_id']);
+ if (!isset($_addon['Addon']['status']) || $_addon['Addon']['status'] != STATUS_PUBLIC) {
+ $this->Feature->invalidate('id');
+ $this->Error->addError('Only public add-ons may be added.');
+ }
+ if (empty($this->data['Feature']['start'])) {
+ $this->data['Feature']['start'] = date('Y-m-d H:i:s');
+ }
+ if (empty($this->data['Feature']['end'])) {
+ $this->data['Feature']['end'] = date('Y-m-d H:i:s', strtotime('+6 months'));
+ }
+ if (USERLANG == 'Unspecified') {
+ $this->data['Feature']['locale'] = null;
+ } else {
+ $this->data['Feature']['locale'] = USERLANG;
+ }
+
+ $this->data['Feature']['application_id'] = USERAPP;
+
+ if ($this->Feature->save($this->data)) {
+ //Log admin action
+ $this->Eventlog->log($this, 'admin', 'feature_add', null, $this->Feature->getLastInsertId());
+
+ $this->flash('Feature added!', '/admin/features');
+ return;
+ } else {
+ $this->Error->addError('Could not add feature (invalid data?)');
+ }
+ }
+ break;
+ }
+ }
+
+ $features = $this->Feature->findAll(array('locale' => USERLANG, 'application_id' => USERAPP), null, null, null, null, -1);
+ $applications = $this->Application->findAll(array('supported' => 1), null, null, null, null, -1);
+
+ foreach ($features as $key => $feature) {
+ $features[$key]['Addon']['name'] = $this->Addon->getAddonName($feature['Feature']['addon_id']);
+ }
+
+ $this->set('page', 'features');
+ $this->set('features', $features);
+ $this->set('locales', $valid_languages);
+ $this->set('applications', $applications);
+ $this->set('errors', $this->Error->errors);
+ $this->render('features');
+ }
+
+ /**
+ * Group Manager
+ */
+ function groups($action = '', $id = 0) {
+ $this->breadcrumbs['Group Manager'] = '/admin/groups';
+ $this->set('breadcrumbs', $this->breadcrumbs);
+
+ if (!empty($action)) {
+ $this->Amo->clean($id);
+ $this->Amo->clean($_POST);
+
+ if ($action != 'members') {
+ if ($action == 'edit') {
+ $this->_groupEdit($id);
+ }
+ elseif ($action == 'create') {
+ $this->_groupCreate();
+ }
+ return;
+ }
+
+ //Add new member
+ if (!empty($_POST['add'])) {
+ $email = $_POST['group'.$id.'_new'];
+ if ($user = $this->User->findByEmail($email)) {
+ $this->User->execute("INSERT INTO groups_users (group_id, user_id) VALUES('{$id}', '{$user['User']['id']}')");
+
+ //Log admin action
+ $this->Eventlog->log($this, 'admin', 'group_addmember', null, $id, $user['User']['id']);
+
+ $this->flash("{$user['User']['email']} successfully added to group {$id}", '/admin/groups');
+ return;
+ }
+ else {
+ $this->Error->addError('Could not find user '.$email);
+ }
+ }
+
+ //Remove member
+ if (!empty($_POST['remove'])) {
+ $uid = $_POST['group'.$id.'_remove'];
+ $this->User->execute("DELETE FROM groups_users WHERE group_id='{$id}' AND user_id='{$uid}' LIMIT 1");
+
+ //Log admin action
+ $this->Eventlog->log($this, 'admin', 'group_removemember', null, $id, null, $uid);
+
+ $this->flash("User successfully removed from group {$id}", '/admin/groups');
+ return;
+ }
+ }
+
+ $groups = $this->Group->findAll();
+
+ $this->set('groups', $groups);
+ $this->set('errors', $this->Error->errors);
+ $this->set('page', 'groups');
+ $this->render('groups');
+ }
+
+ /**
+ * Edit group
+ */
+ function _groupEdit($id) {
+ $this->breadcrumbs['Edit Group'] = '/admin/groups/edit/'.$id;
+ $this->set('breadcrumbs', $this->breadcrumbs);
+
+ $this->Group->id = $id;
+
+ if ($id == 1) {
+ $this->Error->addError('Group 1 cannot be modified.');
+
+ //Log security action
+ $this->Eventlog->log($this, 'security', 'modify_locked_group', null, $id);
+ }
+ elseif (!empty($this->data)) {
+ //Delete group
+ if (!empty($_POST['delete'])) {
+ //Get group info for log
+ $group = $this->Group->read();
+
+ $this->Group->execute("DELETE FROM groups_users WHERE group_id='{$id}'");
+ $this->Group->execute("DELETE FROM groups WHERE id='{$id}'");
+
+ //Log admin action
+ $this->Eventlog->log($this, 'admin', 'group_delete', null, $id, null, $group['Group']['name']);
+
+ $this->flash('Group deleted successfully.', '/admin/groups');
+ return;
+ }
+ //Edit group
+ elseif (!empty($this->data['Group']['name']) && !empty($this->data['Group']['rules'])) {
+ if ($this->Group->save($this->data['Group'])) {
+ //Log admin action
+ $this->Eventlog->log($this, 'admin', 'group_edit', null, $id);
+
+ $this->flash('Group settings saved!', '/admin/groups');
+ return;
+ }
+ else {
+ $this->Error->addError('Validation error.');
+ }
+ }
+ else {
+ $this->Error->addError('All fields are required.');
+ }
+ }
+
+ $group = $this->Group->read();
+
+ $this->set('group', $group);
+ $this->set('errors', $this->Error->errors);
+ $this->set('page', 'groups');
+ $this->render('groups_edit');
+ }
+
+ /**
+ * Create group
+ */
+ function _groupCreate() {
+ $this->breadcrumbs['Create Group'] = '/admin/groups/create';
+ $this->set('breadcrumbs', $this->breadcrumbs);
+
+ if (!empty($this->data)) {
+ if (!empty($this->data['Group']['name']) && !empty($this->data['Group']['rules'])) {
+ if ($this->Group->save($this->data['Group'])) {
+ //Log admin action
+ $this->Eventlog->log($this, 'admin', 'group_create', null, $this->Group->getLastInsertID());
+
+ $this->flash('Group created!', '/admin/groups');
+ return;
+ }
+ else {
+ $this->Error->addError('Validation error.');
+ }
+ }
+ else {
+ $this->Error->addError('All fields are required.');
+ }
+ }
+
+ $this->set('errors', $this->Error->errors);
+ $this->set('page', 'groups');
+ $this->render('groups_create');
+ }
+
+ /**
+ * Response Manager
+ */
+ function responses($action = '', $id = 0) {
+ //Part of the Lists permission
+ if (!$this->SimpleAcl->actionAllowed('Admin', 'lists', $this->Session->read('User'))) {
+ $this->Amo->accessDenied();
+ }
+
+ $this->breadcrumbs['Response Manager'] = '/admin/responses';
+ $this->set('breadcrumbs', $this->breadcrumbs);
+
+ if (!empty($action)) {
+ $this->Amo->clean($id);
+
+ if ($action == 'edit') {
+ $this->_responseEdit($id);
+ return;
+ }
+ elseif ($action == 'create') {
+ $this->_responseCreate($id);
+ return;
+ }
+ }
+
+ $responses = $this->Cannedresponse->findAll();
+
+ $this->set('responses', $responses);
+ $this->set('page', 'lists');
+ $this->set('subpage', 'responses');
+ $this->render('responses');
+ }
+
+ /**
+ * Edit Responses
+ */
+ function _responseEdit($id) {
+ $this->breadcrumbs['Edit Responses'] = '/admin/responses/edit/'.$id;
+ $this->set('breadcrumbs', $this->breadcrumbs);
+
+ $this->Cannedresponse->id = $id;
+
+ if (!empty($this->data)) {
+ //Delete
+ if (!empty($_POST['delete'])) {
+ //Get info for log
+ $response = $this->Cannedresponse->read();
+
+ $this->Group->execute("DELETE FROM cannedresponses WHERE id='{$id}'");
+
+ //Log admin action
+ $this->Eventlog->log($this, 'admin', 'response_delete', null, $id, null, $response['Translation']['name']['string']);
+
+ $this->flash('Response deleted successfully.', '/admin/responses');
+ return;
+ }
+ //Edit
+ else {
+ //Save translated fields (name, description)
+ $this->Developers->saveTranslations($this->data, array('Cannedresponse'));
+
+ //Log admin action
+ $this->Eventlog->log($this, 'admin', 'response_edit', null, $id);
+
+ $this->flash('Response updated!', '/admin/responses');
+ return;
+ }
+ }
+
+ $response = $this->Cannedresponse->read();
+
+ $this->set('response', $response);
+
+ $localizedFields = array(
+ 'name' => array(
+ 'type' => 'input',
+ 'display' => 'Response Name',
+ 'model' => 'Cannedresponse',
+ 'field' => 'name',
+ 'attributes' => array(
+ 'size' => 40
+ )
+ ),
+ 'response' => array(
+ 'type' => 'textarea',
+ 'display' => 'Response',
+ 'model' => 'Cannedresponse',
+ 'field' => 'response',
+ 'attributes' => array(
+ 'cols' => 60,
+ 'rows' => 3
+ )
+ )
+ );
+
+ //Retrieve language arrays from bootstrap.
+ global $valid_languages, $native_languages;
+ foreach (array_keys($valid_languages) as $key) {
+ $languages[$key] = $native_languages[$key]['native'];
+
+ $this->Cannedresponse->setLang($key, $this);
+ $crL = $this->Cannedresponse->read();
+
+ foreach ($crL['Translation'] as $field => $translation) {
+ if ($translation['locale'] == $key) {
+ $info[$key][$field] = $translation['string'];
+ }
+ else {
+ $info[$key][$field] = '';
+ }
+ }
+ }
+
+ //Set up localebox info
+ $this->set('localebox', array('info' => $info,
+ 'defaultLocale' => 'en-US',
+ 'languages' => $languages,
+ 'localizedFields' => $localizedFields));
+
+ $this->set('page', 'lists');
+ $this->set('subpage', 'responses');
+ $this->render('responses_edit');
+ }
+
+ /**
+ * Create Tags
+ */
+ function _responseCreate() {
+ $this->breadcrumbs['Create Response'] = '/admin/responses/create';
+ $this->set('breadcrumbs', $this->breadcrumbs);
+
+ if (!empty($this->data)) {
+ //Save translated fields (name, response)
+ $this->Developers->saveTranslations($this->data, array('Cannedresponse'));
+
+ //Log admin action
+ $this->Eventlog->log($this, 'admin', 'response_create', null, $this->Cannedresponse->getLastInsertID());
+
+ $this->flash('Response created!', '/admin/responses');
+ return;
+ }
+
+ $localizedFields = array(
+ 'name' => array(
+ 'type' => 'input',
+ 'display' => 'Response Name',
+ 'model' => 'Cannedresponse',
+ 'field' => 'name',
+ 'attributes' => array(
+ 'size' => 40
+ )
+ ),
+ 'response' => array(
+ 'type' => 'textarea',
+ 'display' => 'Response',
+ 'model' => 'Cannedresponse',
+ 'field' => 'response',
+ 'attributes' => array(
+ 'cols' => 60,
+ 'rows' => 3
+ )
+ )
+ );
+
+ //Retrieve language arrays from bootstrap.
+ global $valid_languages, $native_languages;
+ foreach (array_keys($valid_languages) as $key) {
+ $languages[$key] = $native_languages[$key]['native'];
+
+ $this->Cannedresponse->setLang($key, $this);
+
+ foreach ($this->Cannedresponse->translated_fields as $field) {
+ $info[$key][$field] = '';
+ }
+ }
+
+ //Set up localebox info
+ $this->set('localebox', array('info' => $info,
+ 'defaultLocale' => 'en-US',
+ 'languages' => $languages,
+ 'localizedFields' => $localizedFields));
+
+ $this->set('page', 'lists');
+ $this->set('subpage', 'responses');
+ $this->render('responses_create');
+ }
+
+ /**
+ * Display logs
+ * @param int $id log id to view
+ */
+ function logs($id = 0) {
+ $this->breadcrumbs['Log Manager'] = '/admin/logs';
+ $this->set('breadcrumbs', $this->breadcrumbs);
+
+ //if id passed, show details for that id
+ if (!empty($id)) {
+ $this->_logDetails($id);
+ return;
+ }
+
+ $conditions = array();
+
+ if (!empty($this->data)) {
+ $filter = explode(':', $this->data['Eventlog']['filter']);
+ $conditions['type'] = $filter[0];
+
+ if ($filter[1] != '*') {
+ $conditions['action'] = $filter[1];
+ }
+ }
+
+ $logs = $this->Eventlog->findAll($conditions, null, 'Eventlog.created DESC');
+
+ $logs = $this->Audit->explainLog($logs);
+
+ $this->set('logs', $logs);
+
+ $this->set('page', 'logs');
+ $this->render('logs');
+ }
+
+ /**
+ * Display log details
+ * @param int $id the log id
+ */
+ function _logDetails($id) {
+ $this->Eventlog->id = $id;
+ $entry = $this->Eventlog->read();
+
+ $this->set('entry', $entry);
+
+ $this->set('page', 'logs');
+ $this->render('log_details');
+ }
+
+ /**
+ * Display server statistics.
+ */
+ function serverstatus() {
+ $this->breadcrumbs['Server Status'] = '/admin/serverstatus';
+ $this->set('breadcrumbs', $this->breadcrumbs);
+
+ $data = array();
+
+ // Get cache servers statistics.
+ $data['memcache'] = $this->Memcaching->getExtendedStats();
+
+ $this->set('data', $data);
+ $this->set('page', 'serverstatus');
+ $this->render('serverstatus');
+ }
+
+ /**
+ * Flush memcache.
+ * This connects to each server individually and flushes them manually.
+ * Should be used sparingly.
+ */
+ function serverflush() {
+ if ($this->Memcaching->flush()) {
+ $this->flash('Memcache flushed!', '/admin/serverstatus');
+ } else {
+ $this->flash('Memcache could NOT be flushed!', '/admin/serverstatus');
+ }
+ }
+
+ function config() {
+ $this->breadcrumbs['Site Config'] = '/admin/config';
+ $this->set('breadcrumbs', $this->breadcrumbs);
+
+ $config = $this->Config->getConfig();
+
+ if (!empty($this->data)) {
+ $sessionConfig = $this->Session->read('Config');
+
+ if (!empty($this->data['Config'])) {
+ if ($this->data['Session']['rand'] == $sessionConfig['rand']) {
+ //Because of the sensitivity, we will only save fields that have changed.
+ foreach ($this->data['Config'] as $key => $value) {
+ if ($config[$key] != $value) {
+ //There has been a change
+
+ $this->Config->save(array('key' => $key, 'value' => $value));
+
+ //Log admin action
+ $this->Eventlog->log($this, 'admin', 'config', $key, 0, $value, $config[$key]);
+ }
+ }
+
+ $this->flash('Config updated!', '/admin/config');
+ }
+ else {
+ $this->flash('There was a problem with your authentication. Please try again.', '/admin/config');
+ }
+ return;
+ }
+
+ if (!empty($this->data['User']['password'])) {
+ $session = $this->Session->read('User');
+ if ($this->User->checkPassword($session, $this->data['User']['password'])) {
+ $this->set('config', $config);
+ $this->set('rand', $sessionConfig['rand']);
+
+ $this->set('page', 'config');
+ $this->render('config');
+ return;
+ }
+ else {
+ //Log failure
+ $this->Eventlog->log($this, 'security', 'reauthentication_failure', null, 1, null, null, 'Site Config');
+
+ //Log user out
+ $this->Session->stop();
+ $this->flash('Incorrect password! You have been logged out.', '/');
+ return;
+ }
+ }
+ }
+
+ $this->set('page', 'config');
+ $this->render('config_login');
+ }
+
+ function variables() {
+
+ $_constants = get_defined_constants(true);
+ $_constants = $_constants['user'];
+ ksort($_constants);
+
+ $_constants['ANON_BIND_PW'] = '--removed--';
+ $_constants['DB_USER'] = '--removed--';
+ $_constants['DB_PASS'] = '--removed--';
+ $_constants['SHADOW_DB_USER'] = '--removed--';
+ $_constants['SHADOW_DB_PASS'] = '--removed--';
+ $_constants['TEST_DB_USER'] = '--removed--';
+ $_constants['TEST_DB_PASS'] = '--removed--';
+ $_constants['CAKE_SESSION_STRING'] = '--removed--';
+ $_constants['RECAPTCHA_PRIVATE_KEY'] = '--removed--';
+
+ $this->set('constants', $_constants);
+
+ $this->set('page', 'variables');
+ $this->set('subpage', '');
+ $this->render('variables');
+ }
+
+ /**
+ * List Manager
+ */
+ function lists() {
+ $this->breadcrumbs['List Manager'] = '/admin/lists';
+ $this->set('breadcrumbs', $this->breadcrumbs);
+
+ $this->set('page', 'lists');
+ $this->set('subpage', '');
+ $this->render('lists');
+ }
+
+ /**
+ * Flagged add-ons
+ */
+ function flagged() {
+ $this->breadcrumbs['Flagged Add-ons'] = '/admin/flagged';
+ $this->set('breadcrumbs', $this->breadcrumbs);
+
+ $this->cssAdd[] = 'editors';
+ $this->set('cssAdd', $this->cssAdd);
+
+ // Process any unflag requests
+ if (!empty($this->data)) {
+ $unflagged = 0;
+ foreach ($this->data['Addon']['unflag'] as $addon_id) {
+ $this->Addon->id = $addon_id;
+ if ($this->Addon->save(array('adminreview' => 0)))
+ $unflagged++;
+ }
+ $this->publish('unflagged', $unflagged);
+ }
+
+ //Pull any add-ons that have adminreview=1
+ $flagged = $this->Addon->findAllByAdminreview(1,
+ array('Addon.id', 'Addon.name', 'Addon.defaultlocale',
+ 'Addon.created'
+ ), 'Addon.created DESC', null, null, 0);
+ if (!empty($flagged)) {
+ foreach ($flagged as $k => $addon) {
+ $version = $this->Version->findByAddon_id($addon['Addon']['id'],
+ array('Version.id', 'Version.addon_id', 'Version.version'),
+ 'Version.created DESC');
+ if (!$version) $version = array();
+ $flagged[$k] = array_merge_recursive($flagged[$k], $version);
+
+ $history = $this->Approval->find(
+ "Approval.addon_id={$addon['Addon']['id']} AND
+ ((Approval.reviewtype='nominated' AND Approval.action=".STATUS_NOMINATED.") OR
+ (Approval.reviewtype='pending' AND Approval.action=".STATUS_PENDING."))",
+ null, 'Approval.created DESC');
+ if (!$history) $history = array();
+ $flagged[$k] = array_merge_recursive($flagged[$k], $history);
+ }
+ }
+ $this->set('addons', $flagged);
+
+ $this->publish('addontypes', $this->Addontype->getNames());
+
+ $this->set('page', 'flagged');
+ $this->render('flagged_queue');
+ }
+
+ /**
+ * User Manager
+ */
+ function users($user_id = 0, $type = 'edit') {
+ $this->breadcrumbs['User Manager'] = '/admin/users';
+ $this->set('breadcrumbs', $this->breadcrumbs);
+ $this->set('suppressJQuery', 0);
+
+ if (!empty($user_id)) {
+ $this->Amo->clean($user_id);
+ $this->User->id = $user_id;
+
+ if (!empty($_POST)) {
+ switch ($type) {
+ case 'delete':
+ switch ($_POST['deletetype']) {
+ case 'all':
+ // check if user owns add-ons
+ if ($this->User->getAddonCount($user_id) > 0) {
+ $this->flash('You cannot delete a user who owns add-ons!', "/admin/users/{$user_id}");
+ return;
+ }
+
+ $this->User->bindModel(array('hasMany' => array('Review' => $this->User->hasMany_full['Review'])));
+ $success = $this->User->del($user_id, true);
+ if ($success) {
+ $this->flash('User successfully deleted!', "/admin/users/");
+ return;
+ }
+ break;
+
+ case 'anon':
+ $success = $this->User->anonymize($user_id);
+ if ($success) {
+ $this->flash('User account successfully made anonymous!', "/admin/users/{$user_id}");
+ return;
+ }
+ break;
+
+ default:
+ $this->flash('Please choose a deletion type!', "/admin/users/{$user_id}");
+ return;
+ }
+
+ if (!$success) {
+ $this->flash('Error deleting user!', "/admin/users/{$user_id}");
+ return;
+ }
+ break;
+
+ case 'edit':
+ default:
+ $this->User->save($this->data['User']);
+
+ // save author "about me"
+ list($localizedFields, $unlocalizedFields) = $this->User->splitLocalizedFields($this->data['User']);
+ $this->User->saveTranslations($user_id, $this->params['form']['data']['User'], $localizedFields);
+
+ //Log admin action
+ $this->Eventlog->log($this, 'admin', 'user_edit', null, $user_id);
+
+ $this->flash('User info updated!', "/admin/users/{$user_id}");
+ return;
+ }
+
+ } else {
+ $user = $this->User->read();
+ // grab translated fields
+ $translations = $this->User->getAllTranslations($user_id);
+ $this->set('translations', $translations);
+ }
+ }
+ elseif (!empty($_GET['q'])) {
+ $q = $_GET['q'];
+ $this->Amo->clean($q);
+
+ if (!$user = $this->User->findByEmail($q)) {
+ $this->flash('E-mail not found.', '/admin/users');
+ return;
+ }
+ // grab translated fields
+ $translations = $this->User->getAllTranslations($user['User']['id']);
+ $this->set('translations', $translations);
+ }
+ $this->set('page', 'users');
+
+ if (!empty($user)) {
+ $this->set('user', $user);
+ $this->render('users_edit');
+ }
+ else {
+ $this->render('users');
+ }
+ }
+
+ /**
+ * AJAX User lookup
+ */
+ function userLookup() {
+ if (!$this->SimpleAcl->actionAllowed('Admin', '%', $this->Session->read('User'))) {
+ $this->Amo->accessDenied();
+ }
+
+ $text = $_REQUEST['q'];
+ $this->Amo->clean($text);
+
+ if ($users = $this->User->query("SELECT id, firstname, lastname, email FROM users WHERE email LIKE '%{$text}%'")) {
+ foreach ($users as $user) {
+ $results[] = "{$user['users']['email']}|{$user['users']['firstname']} {$user['users']['lastname']}";
+ }
+ }
+
+ $this->set('results', $results);
+ $this->render('userlookup', 'ajax');
+ }
+
+ /**
+ * AJAX Add-on lookup
+ */
+ function addonLookup() {
+ if (!$this->SimpleAcl->actionAllowed('Admin', '%', $this->Session->read('User')) ||
+ !$this->SimpleAcl->actionAllowed('Editor', '*', $this->Session->read('User')) ) {
+ $this->Amo->accessDenied();
+ }
+
+ global $valid_status;
+
+ $text = $_REQUEST['q'];
+ $this->Amo->clean($text);
+ $results = array();
+
+ $_query = "SELECT addons.id, translations.localized_string, addons.status
+ FROM addons LEFT JOIN translations ON addons.name=translations.id
+ WHERE translations.locale='".LANG."' AND translations.localized_string LIKE '%{$text}%'";
+ if (array_key_exists('s', $_REQUEST) && in_array($_REQUEST['s'], $valid_status)) {
+ $_query .= " AND addons.status={$_REQUEST['s']}";
+ }
+ $_query .= " ORDER BY translations.localized_string";
+
+ //Check if an add-on id
+ if (preg_match('/\[(\d+)\]/', $text, $matches)) {
+ $addon = $this->Addon->findById($matches[1], array('Addon.name', 'Addon.status'));
+ $results[] = "{$addon['Translation']['name']['string']}|ID: {$matches[1]}; Status: ".$this->Amo->getApprovalStatus($addon['Addon']['status'])."|{$addon['Translation']['name']['string']} [{$matches[1]}]";
+ } elseif ($addons = $this->Addon->query($_query)) {
+ foreach ($addons as $addon) {
+ $results[] = "{$addon['translations']['localized_string']}|ID: {$addon['addons']['id']}; Status: ".$this->Amo->getApprovalStatus($addon['addons']['status'])."|{$addon['translations']['localized_string']} [{$addon['addons']['id']}]";
+ }
+ }
+
+ $this->set('results', $results);
+ $this->render('userlookup', 'ajax');
+ }
+
+ /**
+ * AJAX Collection lookup. Matches either name or nickname
+ */
+ function collectionLookup() {
+ if (!$this->SimpleAcl->actionAllowed('Admin', '%', $this->Session->read('User')) ||
+ !$this->SimpleAcl->actionAllowed('Editor', '*', $this->Session->read('User')) ) {
+ $this->Amo->accessDenied();
+ }
+ global $app_shortnames;
+
+ $text = $_REQUEST['q'];
+ $this->Amo->clean($text);
+ $results = array();
+
+ $_query = "SELECT
+ collections.id, translations.localized_string, collections.nickname, collections.application_id
+ FROM collections LEFT JOIN translations ON collections.name=translations.id
+ WHERE (translations.locale='".LANG."'
+ AND translations.localized_string LIKE '%{$text}%')
+ OR collections.nickname LIKE '%{$text}%'
+ ORDER BY translations.localized_string";
+
+ if ($collections = $this->Collection->query($_query)) {
+ foreach ($collections as $collection) {
+ $_application = array_search($collection['collections']['application_id'], $app_shortnames);
+ $results[] = "{$collection['translations']['localized_string']}|ID: {$collection['collections']['id']}|App: {$_application}|nickname: {$collection['collections']['nickname']};";
+ }
+ }
+
+ $this->set('results', $results);
+ $this->render('userlookup', 'ajax');
+ }
+}
+?>
diff --git a/site/app/controllers/api_controller.php b/site/app/controllers/api_controller.php
new file mode 100644
index 0000000..33a85ce
--- /dev/null
+++ b/site/app/controllers/api_controller.php
@@ -0,0 +1,1134 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Laura Thomson <lthomson@mozilla.com> (Original Author)
+ * l.m.orchard <lorchard@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+uses('sanitize');
+
+class ApiController extends AppController
+{
+
+ var $name = 'Api';
+
+ // bump for new releases
+ // 0 or unspecified is for Fx3b3
+ // 0.9 is for Fx3b4
+ var $newest_api_version = 1.4;
+
+ // cribbed from addonscontroller
+ // some of this is excessive but will likely be needed as
+ // development continues
+ var $beforeFilter = array('checkCSRF', 'getNamedArgs', '_checkSandbox', 'checkAdvancedSearch');
+ var $uses = array('Addon', 'AddonCollection', 'Addontype', 'Application', 'Collection', 'File', 'Platform', 'Tag', 'Translation', /*'Review',*/ 'UpdateCount', 'Version');
+ var $components = array('Amo', 'Image', 'Pagination', 'Search', 'Session', 'Versioncompare');
+ var $helpers = array('Html', 'Link', 'Time', 'Localization', 'Ajax', 'Number', 'Pagination');
+ var $namedArgs = true;
+ var $exceptionCSRF = array("/feed");
+
+ var $securityLevel = 'low';
+
+ function beforeFilter() {
+
+ if ($this->Config->getValue('api_disabled') == 1) {
+ header('HTTP/1.1 503 Service Unavailable');
+ header('Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0, private');
+ header('Pragma: no-cache');
+ exit;
+ }
+
+ $this->forceShadowDb();
+
+ // Disable ACLs; API is public for now
+ // we may add keys later on
+ $this->SimpleAuth->enabled = false;
+ $this->SimpleAcl->enabled = false;
+
+ // extract API version
+ $url = $_SERVER['REQUEST_URI'];
+
+ $matches = array();
+ if (preg_match('/api\/([\d\.]*)\//', $url, $matches)) {
+ $this->api_version = $matches[1];
+ if (!is_numeric($this->api_version)) {
+ $this->api_version = $this->newest_api_version;
+ }
+ } else {
+ // nothing supplied: assume Fx3b3
+ $this->api_version = 0;
+ }
+
+ // set up translation table for os names
+ // this is hardcoded in
+ $this->os_translation = array(
+ 'ALL' => 'ALL',
+ 'bsd' => 'BSD_OS',
+ 'BSD' => 'BSD_OS',
+ 'Linux' => 'Linux',
+ 'macosx' => 'Darwin',
+ 'MacOSX' => 'Darwin',
+ 'Solaris' => 'SunOS',
+ 'win' => 'WINNT',
+ 'Windows' => 'WINNT',
+ );
+ }
+
+ /**
+ * Return details of an addon
+ * See requirement DTL-1 in
+ * [http://wiki.mozilla.org/index.php?title=Update:RequirementsV33]
+ *
+ * @param int $id the id of the addon
+ */
+ function addon($id) {
+ $this->Amo->clean($id);
+ $this->layout='rest';
+ $this->_getAddons(array($id));
+ if (isset($this->viewVars['addonsdata'][$id])) {
+ $this->publish('addon', $this->viewVars['addonsdata'][$id]);
+ } else {
+ $error = ___('error_addon_notfound');
+ $this->publish('error', $error);
+ return;
+ }
+ // get real app names
+ $app_names = $this->Application->getIDList();
+ $this->publish('app_names', $app_names);
+ $guids = array_flip($this->Application->getGUIDList());
+ $this->publish('guids', $guids);
+ $this->publish('api_version', $this->api_version);
+ $this->publish('os_translation', $this->os_translation);
+ }
+
+ /**
+ * Search for matching addons
+ * See requirement SRCH-1 in
+ * [http://wiki.mozilla.org/index.php?title=Update:RequirementsV33]
+ *
+ * @param string $term searchterm
+ */
+ function search($term, $searchtype=NULL, $maxresults = 10, $search_os = null, $search_version=null) {
+
+ $this->layout = 'rest';
+ $this->Sanitize = new Sanitize();
+
+ // if we're passed a version do something with it
+ if (isset($search_version)) {
+ $all_appversions = $this->Amo->getVersionIdsByApp(APP_ID);
+ foreach($all_appversions as $appversion => $appvid) {
+ if($this->Versioncompare->versionBetween($appversion, $search_version, $search_version)) {
+ $versions[] = $appvid; // remora version ids needed
+ }
+ }
+ } else {
+ $versions=NULL;
+ }
+
+ // if we're passed an OS, check it's valid
+ $platforms = $this->Platform->getNames();
+ $platform_id = -1;
+ if(isset($search_os) && ($search_os != 'ALL') && ($search_os != 'all')) {
+ $ids = array_flip($platforms);
+ $client_platforms = array_flip($this->os_translation);
+ if (@isset($ids[$client_platforms[$search_os]])) {
+ $platform_id = $ids[$client_platforms[$search_os]];
+ }
+ }
+
+ if ($searchtype==NULL || $searchtype =='all') {
+ $searchtype = ADDON_API;
+ }
+
+ $result_ids = $this->Search->search($term, $searchtype, 0, STATUS_PUBLIC,
+ $versions , -1, false, -1, $platform_id);
+ if (is_array($result_ids)) {
+ $total_results = count($result_ids);
+ } else {
+ $total_results = 0;
+ }
+
+ // get the total number of addons that would be returned
+ // if we did a regular search on AMO
+ $amo_result_ids = $this->Search->search($term); /*, NULL, 0, NULL,
+ -1, -1, false, -1, -1); */
+
+ if (is_array($amo_result_ids)) {
+ $amo_total_results = count($amo_result_ids);
+ } else {
+ $amo_total_results = 0;
+ }
+
+
+ $this->_getAddons(array_slice($result_ids, 0, $maxresults));
+
+ if ($this->api_version < 0.9) {
+ // hack to make the count work right in the API
+ // TODO: to be fixed properly for Fx3 b4
+ $hack_array = $this->viewVars['addonsdata'];
+ $extras_needed = $total_results - $maxresults;
+ for ($count=0; $count < $extras_needed; $count++) {
+ $hack_array[] = 'dummy';
+ }
+
+ $this->set('addonsdata' , $hack_array);
+ }
+
+ // get real app names
+ $app_names = $this->Application->getIDList();
+ $guids = array_flip($this->Application->getGUIDList());
+ $this->publish('guids', $guids);
+ $this->publish('app_names', $app_names);
+ $this->publish('api_version', $this->api_version);
+ $this->publish('total_results', $amo_total_results);
+ $this->publish('os_translation', $this->os_translation);
+ $this->publish('addonsdata', $this->viewVars['addonsdata']);
+ }
+
+ /**
+ * List addons
+ * See requirements LIST-1..3 in
+ * [http://wiki.mozilla.org/index.php?title=Update:RequirementsV33]
+ * routes from api/list but list is a reserved word in PHP
+ *
+ * @param string $listtype (recommended, featured, new)
+ * @param string $addontype (all, extension, theme, plugin, dictionary, searchengine)
+ * @param int $number maximum number of results to return
+ */
+ function list_addons($listtype='recommended', $addontype='all',
+ $number = 3, $list_os=null, $list_version=null) {
+
+ $this->layout = 'rest';
+
+ // process listtype
+ switch ($listtype) {
+ case 'new' :
+ // new is less than ten days old
+ $select = 'distinct a.id ';
+ $days_since_creation = 10;
+ $list_criteria = '(datediff(a.created, NOW()) < '.$days_since_creation.')';
+ $tables = 'addons as a';
+ break;
+ case 'recommended':
+ case 'featured' :
+ default :
+ $select = ' f.addon_id ';
+ $list_criteria = ' f.start < NOW()
+ AND f.end > NOW()
+ AND f.application_id = \''
+ . APP_ID . '\'
+ AND (f.locale = \''
+ . LANG .'\'
+ OR f.locale IS NULL)
+ AND a.status = \''.STATUS_PUBLIC.'\' ';
+ $tables = ' features as f LEFT JOIN
+ addons as a on
+ f.addon_id = a.id ';
+ break;
+ }
+
+ // process addon type
+ switch ($addontype) {
+ case 'extension' :
+ $addontype_sql = ADDON_EXTENSION;
+ break;
+ case 'theme' :
+ $addontype_sql = ADDON_THEME;
+ break;
+ case 'plugin' :
+ $addontype_sql = ADDON_PLUGIN;
+ break;
+ case 'dictionary' :
+ $addontype_sql = ADDON_DICT;
+ break;
+ case 'searchengine' :
+ $addontype_sql = ADDON_SEARCH;
+ break;
+ default:
+ $addontype_sql = NULL;
+
+ }
+ $addon_criteria = '';
+ if ($addontype_sql) {
+ $addon_criteria = ' AND a.addontype_id = '. $addontype_sql.' ';
+ }
+
+ // platforms
+ if ($list_os && $list_os != 'ALL' && $list_os != 'all') {
+ $platforms = $this->Platform->getNames();
+ $ids = array_flip($platforms);
+ $client_platforms = array_flip($this->os_translation);
+ if (isset($client_platforms[$list_os])
+ && isset($ids[$client_platforms[$list_os]])
+ && $ids[$client_platforms[$list_os]] != NULL ) {
+ $platform_id = $ids[$client_platforms[$list_os]];
+ $all_id = $ids[$client_platforms['ALL']];
+ //echo "platform id is |$platform_id|"; exit;
+ $tables .= 'JOIN versions AS v
+ ON v.addon_id = a.id
+ INNER JOIN files
+ ON files.platform_id IN ('.$platform_id.',
+ '.$all_id.')
+ AND v.id = files.version_id';
+ }
+ }
+
+ // versions
+ if ($list_version) {
+ $all_appversions = $this->Amo->getVersionIdsByApp(APP_ID);
+ $versions_wanted = array();
+ $below_wanted = array();
+ $above_wanted = array();
+ foreach($all_appversions as $appversion => $appvid) {
+ $compare = $this->Versioncompare->compareVersions($appversion, $list_version);
+ if ($compare < 0) {
+ $below_wanted[] = $appvid;
+ } else if ($compare > 0) {
+ $above_wanted[] = $appvid;
+ } else {
+ $versions_wanted[] = $appvid;
+ }
+ }
+ if (count($versions_wanted)) {
+ $tables .= ' JOIN versions_summary AS vs
+ ON f.addon_id = vs.addon_id ';
+ //$addon_criteria .= ' AND vs.min IN ('.$version_list.')
+ // OR vs.max IN ('.$version_list.') ';
+ $_ver_string = "('".implode("', '", $versions_wanted) ."') ";
+ $versions_criteria = " AND ((vs.min IN ".$_ver_string
+ ." OR vs.max IN ".$_ver_string. ") ";
+ $_below_string = "('".implode("', '", $below_wanted) ."') ";
+ $_above_string = "('".implode("', '", $above_wanted) ."') ";
+ $versions_criteria .= " OR (vs.min IN ".$_below_string
+ ." AND vs.max IN ".$_above_string."))";
+ $addon_criteria .= $versions_criteria;
+ } else {
+ $versions_criteria ='';
+ }
+ }
+ // process number
+ if (!is_numeric($number)) {
+ // revert to default value for this param if passed garbage
+ $number = 3;
+ }
+
+ $sql = 'SELECT '. $select .'
+ FROM '.$tables
+ .' WHERE '
+ . $list_criteria
+ . $addon_criteria ;
+
+ if ($listtype =='recommended') {
+ $sql .= ' UNION SELECT DISTINCT(f.addon_id)
+ FROM ';
+ $tables2 = ' addons_tags AS f LEFT JOIN addons AS a ON f.addon_id = a.id ';
+ $where2 = ' WHERE f.feature = 1
+ AND a.status =\''.STATUS_PUBLIC.'\' ';
+ if ($list_os && $list_os != 'all' && $list_os != 'ALL'
+ && isset($platform_id)) {
+ // omg, query++
+ $tables2 .= '
+ JOIN versions AS v
+ ON v.addon_id = f.addon_id
+ INNER JOIN files
+ ON files.platform_id IN ('.$platform_id.' ,
+ '.$all_id.')
+ AND v.id = files.version_id ';
+ }
+ if ($list_version && count($versions_wanted)) {
+ $tables2 .= ' JOIN versions_summary AS vs
+ ON f.addon_id = vs.addon_id ';
+ }
+ $sql .= $tables2 . $where2;
+ if (isset($versions_criteria)) {
+ $sql .= $versions_criteria;
+ }
+ }
+ $addons = $this->Addon->query($sql, true);
+ $addon_ids = array();
+ foreach ($addons as $addon) {
+ if ($listtype=='new')
+ $addon_ids[] = $addon['a']['id'];
+ else if ($listtype == 'recommended')
+ $addon_ids[] = $addon[0]['addon_id'];
+ else
+ $addon_ids[] = $addon['f']['addon_id'];
+ }
+
+ shuffle($addon_ids);
+ $addon_ids = array_slice($addon_ids, 0, $number);
+
+ $this->_getAddons($addon_ids);
+
+ // get real app names
+ $app_names = $this->Application->getIDList();
+ $this->publish('app_names', $app_names);
+ $guids = array_flip($this->Application->getGUIDList());
+ $this->publish('guids', $guids);
+ $this->publish('ids', $addon_ids);
+ $this->publish('addonsdata', $this->viewVars['addonsdata']);
+ $this->publish('api_version', $this->api_version);
+ $this->publish('os_translation', $this->os_translation);
+ }
+
+ /**
+ * List addons in a collection
+ *
+ * @param string $id
+ * @param string $passwd_hash
+ */
+ function collections_feed($id, $passwd_hash=null) {
+ $this->layout = 'rest';
+
+ $addon_ids = array();
+ $addon_collections = array();
+
+ // Try looking up just the identified collection.
+ $this->Collection->unbindFully();
+ $collection = $this->Collection->find(array(
+ 'Collection.id' => $id
+ ));
+ if (!$collection) {
+ $error = ___('error_collection_feed_notfound', 'Addon feed not found');
+ $this->publish('error', $error);
+ return;
+ }
+
+ if ($_SERVER['REQUEST_METHOD'] == 'POST') {
+ // POST request method is treated as a write attempt.
+ if (! $this->collections_feed_write($collection, $passwd_hash) )
+ return;
+ }
+
+ // Publish the collection details for the feed.
+ $this->publish('feed_id',
+ $collection['Collection']['id']);
+ $this->publish('feed_created',
+ $collection['Collection']['created']);
+ $this->publish('feed_modified',
+ $collection['Collection']['modified']);
+ $this->publish('feed_closed',
+ !!$collection['Collection']['password']);
+ $this->publish('feed_name',
+ $collection['Translation']['name']['string']);
+ $this->publish('feed_description',
+ $collection['Translation']['description']['string']);
+
+ // Now, attempt to look up all the addon references in the
+ // collection. Collate the details by addon ID and extract
+ // a list of those addon IDs.
+ $collection_items = $this->AddonCollection->findAll(array(
+ 'AddonCollection.collection_id' => $id
+ ));
+ foreach ($collection_items as $item) {
+ $id = $item['AddonCollection']['addon_id'];
+ $addon_ids[] = $id;
+ $addon_collections[$id] = $item;
+ }
+
+ // Fetch the addons for the feed, first tearing down the model bindings
+ // and selectively rebuilding them.
+ $this->Addon->unbindFully();
+ $this->Addon->bindModel(array(
+ 'hasAndBelongsToMany' => array(
+ 'User' => array(
+ 'className' => 'User',
+ 'joinTable' => 'addons_users',
+ 'foreignKey' => 'addon_id',
+ 'associationForeignKey'=> 'user_id',
+ 'conditions' => 'addons_users.listed=1',
+ 'order' => 'addons_users.position'
+ ),
+ 'Tag' => array(
+ 'className' => 'Tag',
+ 'joinTable' => 'addons_tags',
+ 'foreignKey' => 'addon_id',
+ 'associationForeignKey'=> 'tag_id'
+ )
+ )
+ ));
+ $addons_data = $this->Addon->findAll(array(
+ 'Addon.id' => $addon_ids,
+ 'Addon.inactive' => 0,
+ 'Addon.addontype_id' => array(
+ ADDON_EXTENSION, ADDON_THEME, ADDON_DICT,
+ ADDON_SEARCH, ADDON_PLUGIN
+ )
+ ));
+
+ // Rather than trying to join tags and addon types in SQL, collect IDs
+ // and make a pair of queries to fetch them.
+ $tag_ids = array();
+ $addon_type_ids = array();
+ foreach ($addons_data as $addon) {
+ $addon_type_ids[$addon['Addon']['addontype_id']] = true;
+ foreach ($addon['Tag'] as $tag)
+ $tag_ids[$tag['id']] = true;
+ }
+
+ // Query for addon types found in this set of addons, assemble a map
+ // for an in-code join later.
+ $addon_type_rows = $this->Addontype->findAll(array(
+ 'Addontype.id' => array_keys($addon_type_ids)
+ ));
+ $addon_types = array();
+ foreach ($addon_type_rows as $row) {
+ $addon_types[$row['Addontype']['id']] = $row;
+ }
+
+ // Query for addon types found in this set of tags, assemble a map
+ // for an in-code join later.
+ $tag_rows = $this->Tag->findAll(array(
+ 'Tag.id' => array_keys($tag_ids)
+ ));
+ $all_tags = array();
+ foreach ($tag_rows as $row) {
+ $all_tags[$row['Tag']['id']] = $row;
+ }
+
+ $app_names = $this->Application->getIDList();
+ $guids = array_flip($this->Application->getGUIDList());
+
+ $this->publish('app_names', $app_names);
+ $this->publish('guids', $guids);
+ $this->publish('ids', $addon_ids);
+ $this->publish('api_version', $this->api_version);
+ $this->publish('os_translation', $this->os_translation);
+
+ // Process addons list to produce a much flatter and more easily
+ // sanitized array structure for the view, sprinkling in details
+ // like tags and version information along the way.
+ //
+ // TODO: Reconcile this with the _getAddons() method from which this
+ // was refactored but not replaced.
+ $addons_out = array();
+ for ($i=0; $i<count($addons_data); $i++) {
+
+ $addon = $addons_data[$i];
+ $id = $addon['Addon']['id'];
+
+ $addontype_id = $addon['Addon']['addontype_id'];
+
+ // make sure reported latest version matches version of file
+ $install_version = $this->Version->getVersionByAddonId(
+ $addon['Addon']['id'], STATUS_PUBLIC
+ );
+
+ // get filename for install
+ $fileinfo = $this->File->findAllByVersion_id(
+ $install_version, null, null, null, null, 0
+ );
+ if (!is_array($fileinfo) || count($fileinfo)==0) {
+ continue;
+ }
+
+ // Start constructing a flat minimal list of addon details made up of only
+ // what the view will need.
+ $addon_out = array(
+ 'collection_added' =>
+ $addon_collections[$id]['AddonCollection']['added'],
+ 'collection_comments' =>
+ $addon_collections[$id]['Translation']['comments']['string'],
+ 'id' => $addon['Addon']['id'],
+ 'guid' => $addon['Addon']['guid'],
+ 'name' => $addon['Translation']['name']['string'],
+ 'summary' => $addon['Translation']['summary']['string'],
+ 'description' =>
+ $addon['Translation']['description']['string'],
+ 'addontype_id' => $addontype_id,
+ 'addontype_name' =>
+ $addon_types[$addontype_id]['Translation']['name']['string'],
+ 'icon' =>
+ $this->Image->getAddonIconURL($id),
+ 'thumbnail' =>
+ $this->Image->getHighlightedPreviewURL($id),
+ 'install_version' => $install_version,
+ 'status' => $addon['Addon']['status'],
+ 'users' => $addon['User'],
+ 'eula' => $addon['Translation']['eula']['string'],
+ 'averagerating' => $addon['Addon']['averagerating'],
+ 'tags' => array(),
+ 'compatible_apps' => array(),
+ 'all_compatible_os' => array(),
+ 'fileinfo' => array()
+ );
+
+ // Add the list of tags into the addon details
+ foreach ($addon['Tag'] as $x) {
+ $x = $all_tags[ $x['id'] ];
+ $addon_out['tags'][] = array(
+ 'id' => $x['Tag']['id'],
+ 'name' => $x['Translation']['name']['string']
+ );
+ }
+
+ // Add the list of compatible apps into the addon details
+ $compatible_apps =
+ $this->Version->getCompatibleApps($install_version);
+ foreach ($compatible_apps as $x) {
+ $addon_out['compatible_apps'][] = array(
+ 'id' => $x['Application']['application_id'],
+ 'name' => $app_names[ $x['Application']['application_id']],
+ 'guid' => $guids[$app_names[$x['Application']['application_id']]],
+ 'min_version' => $x['Min_Version']['version'],
+ 'max_version' => $x['Max_Version']['version']
+ );
+ }
+
+ // Gather a list of platforms for files
+ $this->Platform->unbindFully();
+ $platforms = array();
+ foreach($fileinfo as &$file) {
+ $this_plat = $this->Platform->findById($file['Platform']['id']);
+ $file['Platform']['apiname'] = $this_plat['Translation']['name']['string'];
+ $platforms[] = $this_plat;
+ }
+
+ if ($this->api_version > 0 ) {
+ // return an array of compatible os names
+ // right now logic is still wrong, but this enables
+ // xml changes and logic will be fixed later
+ if (empty($platforms)) {
+ $all_compatible_os = array();
+ } else {
+ $all_compatible_os = $platforms;
+ }
+ foreach ($all_compatible_os as $x) {
+ $addon_out['all_compatible_os'][] =
+ $this->os_translation[ $x['Translation']['name']['string'] ];
+ }
+ }
+
+ // Add in the list of files available for the addon.
+ foreach ($fileinfo as $x) {
+ $addon_out['fileinfo'][] = array(
+ 'id' => $x['File']['id'],
+ 'filename' => $x['File']['filename'],
+ 'hash' => $x['File']['hash'],
+ 'os' => $this->os_translation[ $x['Platform']['apiname'] ],
+ );
+ }
+
+ // Finally, add this set of addon details to the list intended for
+ // the view.
+ $addons_out[] = $addon_out;
+ }
+
+ $this->publish('addonsdata', $addons_out);
+ }
+
+ /**
+ * Append an addon to a collection
+ *
+ * @param object $collection
+ * @param string $passwd_hash
+ */
+ function collections_feed_write($collection, $passwd_hash=null) {
+ try {
+
+ // Try getting content type and length from the headers.
+ $content_type = isset($_SERVER['CONTENT_TYPE']) ?
+ $_SERVER['CONTENT_TYPE'] : 'application/json';
+ $content_length = isset($_SERVER['CONTENT_LENGTH']) ?
+ $_SERVER['CONTENT_LENGTH'] : FALSE;
+
+ // If there's content waiting, try fetching it.
+ if (!$content_length)
+ throw new Exception('No addon data submitted');
+ $data = file_get_contents('php://input');
+
+ // Verify the password hash, if necessary.
+ if ($collection['Collection']['password']) {
+ if ($passwd_hash != $collection['Collection']['password'])
+ throw new Exception('Password hash mismatch');
+ }
+
+ if ($content_type == 'text/xml') {
+ // If the request claims to be submitting XML, attempt to
+ // extract the details from it.
+ $doc = new SimpleXMLElement($data);
+ $req_addon = array(
+ 'guid' => (string)$doc->guid,
+ 'comments' => (string)$doc->comments
+ );
+ } else {
+ // Otherwise, assume the incoming request is JSON.
+ $req_addon = json_decode($data, TRUE);
+ }
+
+ // If there's no addon data, or the GUID is missing, abort.
+ if (!$req_addon)
+ throw new Exception('Invalid request data');
+
+ if (!isset($req_addon['guid']) || !$req_addon['guid'])
+ throw new Exception('Missing addon GUID');
+
+ // Try to find the requested addon, abort if not found.
+ $addon = $this->Addon->find(array(
+ 'Addon.guid' => $req_addon['guid']
+ ));
+ if (!$addon)
+ throw new Exception('No addon found for GUID');
+
+ // Check if the addon is already in the collection.
+ $existing_item = $this->AddonCollection->findAll(array(
+ 'AddonCollection.collection_id' =>
+ $collection['Collection']['id'],
+ 'AddonCollection.addon_id' =>
+ $addon['Addon']['id']
+ ));
+ if ($existing_item)
+ throw new Exception('Addon already in collection');
+
+ // Finally, add the addon to the collection and bump the
+ // modification timestamp.
+ $this->AddonCollection->save(array(
+ 'collection_id' => $collection['Collection']['id'],
+ 'addon_id' => $addon['Addon']['id'],
+ 'comments' => $req_addon['comments'],
+ 'added' => date('Y-m-d h:i:s', time())
+ ));
+ $this->Collection->save(array(
+ 'id' => $collection['Collection']['id'],
+ 'modified' => date('Y-m-d h:i:s', time())
+ ));
+
+ return TRUE;
+
+ } catch (Exception $e) {
+ // In the case of any exceptions, toss an error back as a response.
+ $error = $e->getMessage();
+ $this->publish('error', $error);
+ return FALSE;
+ }
+ }
+
+ /**
+ * Retrieve cumulative downloads for an addon
+ * See requirement DOWN-2 in
+ * [http://wiki.mozilla.org/index.php?title=Update:RequirementsV33]
+ * @param int $id id of the addon
+ */
+ function cumulative_downloads($id) {
+ $this->Amo->clean($id);
+ $this->layout='rest';
+ $_conditions = array(
+ 'Addon.id' => $id,
+ 'Addon.inactive' => 0,
+ 'Addon.addontype_id' => array(ADDON_EXTENSION, ADDON_THEME,
+ ADDON_DICT, ADDON_SEARCH, ADDON_PLUGIN)
+ );
+
+ // get basic addon data
+ // same criteria as used by the amo display action
+ $addon_data = $this->Addon->find($_conditions, null , null , 1);
+
+ if (empty($addon_data)) {
+ $error = ___('error_addon_notfound');
+ $this->publish('error', $error);
+ return;
+ }
+
+ // get download count
+ $downloads = $addon_data['Addon']['totaldownloads'];
+
+ $this->publish('id', $id);
+ $this->publish('downloads', $downloads);
+ }
+
+ /**
+ * Retrieve update pings for an addon
+ * See requirement USE-2 in
+ * [http://wiki.mozilla.org/index.php?title=Update:RequirementsV33]
+ * @param int $id id of the addon
+ * @param string $period day, month, year: period to report on
+ * @param string $querydate date on which reporting period ENDS
+ */
+/*
+// update_pings off for now
+ function update_pings($id, $period='day', $querydate='') {
+ $this->Amo->clean($id);
+ $this->layout='rest';
+
+ // date handling
+ if ($querydate == '') {
+ //$querydate = 'foo'; // today
+ $querydate = date('Y-m-d'); // today
+ } else {
+ if (!($checkdate = strtotime($querydate))) {
+ // if it's not a valid date fall back to today
+ $querydate = date('Y-m-d'); // today
+ } else {
+ $querydate = date('Y-m-d', $checkdate);
+ }
+ }
+
+ // period handling
+ switch ($period) {
+ case 'week':
+ $days = 7;
+ break;
+ case 'month':
+ $days = 30;
+ break;
+ case 'day':
+ default:
+ $period = 'day';
+ $days = 1;
+ }
+
+ $daylength = 24*60*60;
+ $startdate = date('Y-m-d', (strtotime($querydate)-($days*$daylength)));
+ $date_sql = ' and date <= \''
+ . $querydate
+ .'\' and date > \''
+ . $startdate .'\'';
+
+
+ $sql = 'select *
+ from update_counts
+ where addon_id = '.$id
+ . $date_sql
+ ;
+
+ // run the query
+ $update_counts = $this->UpdateCount->query($sql);
+
+ // extract and unmunge serialized data
+ $total_count = 0;
+ $version_counts = array();
+ $status_counts = array();
+ $application_counts = array();
+ $os_counts = array();
+
+ // get real app names
+ $app_names = $this->Application->getGUIDList();
+
+ foreach ($update_counts as $update_count) {
+ $total_count += $update_count['update_counts']['count'];
+
+ $vc = unserialize($update_counts[0]['update_counts']['version']);
+ foreach ($vc as $version => $count) {
+ if (!isset($version_counts["$version"])) {
+ $version_counts["$version"] = $count;
+ } else {
+ $version_counts["$version"] += $count;
+ }
+ }
+
+ $s = unserialize($update_count['update_counts']['status']);
+ foreach ($s as $status => $count) {
+ @$status_counts["$status"] += $count;
+ }
+
+ $apps = unserialize($update_count['update_counts']['application']);
+ foreach ($apps as $app => $details) {
+ foreach ($details as $version => $count) {
+ @$application_counts[$app][$version] += $count;
+ }
+ }
+
+ $os = unserialize($update_count['update_counts']['os']);
+ foreach ($os as $os => $count) {
+ @$os_counts["$os"] += $count;
+ }
+ }
+
+ // output
+ $this->publish('app_names', $app_names);
+ $this->publish('id', $id);
+ $this->publish('period', $period);
+ $this->publish('querydate', $querydate);
+ $this->publish('total_count', $total_count);
+ $this->publish('version_counts', $version_counts);
+ $this->publish('status_counts', $status_counts);
+ $this->publish('application_counts', $application_counts);
+ $this->publish('os_counts', $os_counts);
+ }
+*/
+
+ /**
+ * Return a complete list of available language packs
+ *
+ */
+ function get_language_packs() {
+
+ $this->layout = 'rest';
+
+ $conditions = array(
+ 'Addon.addontype_id' => array(ADDON_LPAPP),
+ 'Addon.status' => STATUS_PUBLIC,
+ 'Addon.inactive' => 0
+ );
+
+ $this->Addon->unbindfully();
+ $lang_packs = $this->Addon->findAll($conditions, 'Addon.id');
+ $ids = array();
+ foreach ($lang_packs as $lp) {
+ $ids[] = $lp['Addon']['id'];
+ }
+
+ $this->_getAddons($ids);
+
+ // get real app names
+ $app_names = $this->Application->getIDList();
+ $guids = array_flip($this->Application->getGUIDList());
+ $this->publish('guids', $guids);
+ $this->publish('app_names', $app_names);
+ $this->publish('os_translation', $this->os_translation);
+ $this->publish('api_version', $this->api_version);
+ $this->publish('addonsdata', $this->viewVars['addonsdata']);
+ }
+
+/* Utility functions follow */
+
+ /**
+ * Given an array of addon ids, return details for those addons
+ *
+ * @param array $ids ids of the addons to retrieve
+ */
+ function _getAddons($ids) {
+ $addonsdata = array();
+ foreach ($ids as $id) {
+ $_conditions = array(
+ 'Addon.id' => $id,
+ 'Addon.inactive' => 0,
+ 'Addon.addontype_id' => array(ADDON_EXTENSION, ADDON_THEME, ADDON_DICT, ADDON_SEARCH, ADDON_PLUGIN, ADDON_LPAPP)
+ );
+
+ // get basic addon data
+ // same criteria as used by the amo display action
+ $addon_data = $this->Addon->find($_conditions, null , null , 1);
+
+ if (empty($addon_data)) {
+ // this covers the case where we turned up something in the requested set that
+ // was invalid for whatever reason.
+ continue;
+ }
+
+ // get addon type
+ $this_addon_type = $this->Addontype->findById($addon_data['Addon']['addontype_id']);
+ $addon_data['Addon_type'] = $this_addon_type;
+/*
+// getting rid of reviews for now
+ // get reviews
+ $all_version_ids =
+ $this->Version->getVersionIdsByAddonId($addon_data['Addon']['id'],
+ $this->status);
+ $_review_versions = array();
+ foreach ($all_version_ids as $_version) {
+ $_review_versions[] = $_version['Version']['id'];
+ }
+ if (!empty($_review_versions)) {
+ $reviews = $this->Review->findAll(array(
+ "Review.version_id" => $_review_versions,
+ 'Review.reply_to IS NULL',
+ 'Translation.body_locale' => array(LANG, 'en-US')),
+ array('Review.id',
+ 'Review.version_id',
+ 'Review.body',
+ 'Review.created',
+ 'Review.title',
+ 'Review.rating',
+ 'User.id',
+ 'User.nickname',
+ 'User.firstname',
+ 'User.lastname'),
+ "Review.created DESC", null, null, 1);
+ } else {
+ $reviews = array();
+ }
+
+ $addon_data['Reviews'] = array_slice($reviews, 0, 3);
+*/
+ // make sure reported latest version matches version of file
+ $install_version
+ = $this->Version->getVersionByAddonId($addon_data['Addon']['id'],
+ STATUS_PUBLIC);
+ // find the addon version to report to user
+ foreach ($addon_data['Version'] as $v) {
+ if ($v['id'] == $install_version) {
+ $addon_data['install_version'] = $v['version'];
+ break;
+ }
+ }
+
+ // get filename for install
+ $fileinfo = $this->File->findAllByVersion_id(
+ $install_version, null, null, null, null, 0);
+
+ if (!is_array($fileinfo) || count($fileinfo)==0) {
+ // don't return addons that don't have a valid
+ // file associated with them
+ continue;
+ }
+
+ // get compatible apps
+ $compatible_apps = $this->Version->getCompatibleApps($install_version);
+ $addon_data['Compatible_apps'] = $compatible_apps;
+
+
+ // get compatible platforms
+ $this->Platform->unbindFully();
+
+ foreach($fileinfo as &$file) {
+ $this_plat = $this->Platform->findById($file['Platform']['id']);
+ $file['Platform']['apiname'] = $this_plat['Translation']['name']['string'];
+ $platforms[] = $this_plat;
+ }
+
+ if ($this->api_version > 0 ) {
+ // return an array of compatible os names
+ // right now logic is still wrong, but this enables
+ // xml changes and logic will be fixed later
+ if (empty($platforms)) {
+ $addon_data['all_compatible_os'] = array();
+ } else {
+ $addon_data['all_compatible_os'] = $platforms;
+ }
+
+
+ }
+
+
+
+ // pull highlighted preview thumbnail url
+ $addon_data['Thumbnail'] = $this->Image->getHighlightedPreviewURL($id);
+
+ // the icon
+ $addon_data['Icon'] = $this->Image->getAddonIconURL($id);
+
+ $addon_data['fileinfo'] = $fileinfo;
+
+ // add data to array
+ $addonsdata[$id] = $addon_data;
+ }
+ $this->set('addonsdata' , $addonsdata);
+ }
+
+ /**
+ * API specific publish
+ * Uses XML encoding and is UTF-8 safe
+ * @param mixed the data array (or string) to be html-encoded (by reference)
+ * @param bool clean the array keys as well?
+ * @return void
+ */
+ function publish($viewvar, $value, $sanitizeme = true) {
+ if ($sanitizeme) {
+ if (is_array($value)) {
+ $this->_sanitizeArrayForXML($value);
+ } else {
+ $tmp = array($value);
+ $this->_sanitizeArrayForXML($tmp);
+ $value = $tmp[0];
+ }
+ }
+ $this->set($viewvar, $value);
+ }
+
+ /**
+ * API specific sanitize
+ * xml-encode an array, recursively
+ * UTF-8 safe
+ *
+ * @param mixed the data array to be encoded
+ * @param bool clean the array keys as well?
+ * @return void
+ */
+ var $sanitize_patterns = array(
+ "/\&/u", "/</u", "/>/u",
+ '/"/u', "/'/u",
+ '/[\cA-\cL]/u',
+ '/[\cN-\cZ]/u',
+ );
+ var $sanitize_replacements = array(
+ "&amp;", "&lt;", "&gt;",
+ "&quot;", "&#39;",
+ "",
+ ""
+ );
+ var $sanitize_field_exceptions = array(
+ 'id'=>1, 'guid'=>1, 'addontype_id'=>1, 'status'=>1, 'higheststatus'=>1,
+ 'icontype'=>1, 'version_id'=>1, 'platform_id'=>1, 'size'=>1, 'hash'=>1,
+ 'codereview'=>1, 'password'=>1, 'emailhidden'=>1, 'sandboxshown'=>1,
+ 'averagerating'=>1, 'textdir'=>1, 'locale'=>1, 'locale_html'=>1,
+ 'created'=>1, 'modified'=>1, 'datestatuschanged'=>1
+ );
+ function _sanitizeArrayForXML(&$data, $cleankeys = false) {
+
+ if (empty($data)) return;
+
+ foreach ($data as $key => $value) {
+ if (isset($this->sanitize_field_exceptions[$key])) {
+ // @todo This if() statement is a temporary solution until we come up with
+ // a better way of excluding fields from being sanitized.
+ continue;
+ } else if (empty($value)) {
+ continue;
+ } else if (is_array($value)) {
+ $this->_sanitizeArrayForXML($data[$key], $cleankeys);
+ } else {
+ $data[$key] = preg_replace(
+ $this->sanitize_patterns,
+ $this->sanitize_replacements,
+ $data[$key]
+ );
+ }
+ }
+
+ // change the keys if necessary
+ if ($cleankeys) {
+ $keys = array_keys($data);
+ $this->_sanitizeArrayForXML($keys, false);
+ $data = array_combine($keys, array_values($data));
+ }
+
+ }
+
+ /**
+ * Standalone string sanitize for XML
+ *
+ * @param string
+ * @return string
+ */
+ function sanitizeForXML($value) {
+ return preg_replace(
+ $this->sanitize_patterns,
+ $this->sanitize_replacements,
+ $value
+ );
+ }
+
+}
diff --git a/site/app/controllers/collections_controller.php b/site/app/controllers/collections_controller.php
new file mode 100644
index 0000000..6a23ecc
--- /dev/null
+++ b/site/app/controllers/collections_controller.php
@@ -0,0 +1,1067 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Ryan Doherty <rdoherty@mozilla.com>
+ * Frederic Wenzel <fwenzel@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+class CollectionsController extends AppController
+{
+ var $name = 'Collections';
+ var $beforeFilter = array('checkCSRF', 'getNamedArgs', '_checkSandbox', 'checkAdvancedSearch');
+ var $uses = array('Addon', 'AddonCollection', 'Application', 'Collection', 'File',
+ 'Platform', 'Preview', 'Translation', 'Version');
+ var $components = array('Amo', 'CollectionsListing', 'Developers', 'Error', 'Helper', 'Image', 'Pagination', 'Session');
+ var $actionHelpers = array('Html');
+ var $helpers = array('Html', 'Link', 'Listing', 'Time', 'Localization', 'Pagination', 'Number', 'Form');
+ var $exceptionCSRF = array("/collections/install");
+ var $namedArgs = true;
+
+ var $securityLevel = 'low';
+
+ function beforeFilter() {
+ $this->layout='mozilla';
+ $this->publish('collapse_categories', true);
+ $this->publish('collectionSearch', true);
+ $this->pageTitle = 'Collections' . " :: " . sprintf(_('addons_home_pagetitle'), APP_PRETTYNAME);
+ $this->publish('jsAdd', array('jquery.autocomplete.pack.js'), false);
+ // Disable ACLs because this controller is entirely public.
+ $this->SimpleAuth->enabled = false;
+ $this->SimpleAcl->enabled = false;
+
+ $this->publish('jsAdd', array('amo2009/collections', 'jquery-ui/jqModal.js'));
+ }
+
+ function index() {
+ /* TODO: preserve get params */
+ $this->redirect('/collections/editors_picks');
+ }
+
+ function _listing($collections, $pagination_options=array()) {
+ $ids = array();
+ foreach ($collections as $c) $ids[] = $c['Collection']['id'];
+
+ $collections = $this->CollectionsListing->fetchPage($ids, $pagination_options);
+ list($sort_opts, $sortby) = $this->CollectionsListing->sorting();
+
+ $this->publish('sort_opts', $sort_opts);
+ $this->publish('sortby', $sortby);
+ $this->publish('collections', $collections);
+ $this->set('tabs', $this->_collectionTabs());
+
+ // if a collection was just deleted, show success message
+ $this->publish('collection_deleted', $this->Session->delete('collection_deleted'), false);
+
+ $this->publish('breadcrumbs', array(
+ sprintf(___('addons_home_pagetitle'), APP_PRETTYNAME) => '/',
+ ));
+
+ $this->render('listing');
+ }
+
+ function _collectionTabs() {
+ $tabs = array(
+ array('href' => 'editors_picks',
+ 'text' => ___('collections_index_li_editors')),
+ array('href' => 'popular',
+ 'text' => ___('collections_index_li_popular')),
+ );
+
+ if ($this->Session->check('User')) {
+ $tabs = array_merge($tabs, array(
+ array('href' => 'mine',
+ 'text' => ___('collections_index_li_mine')),
+ array('href' => 'favorites',
+ 'text' => ___('collections_index_li_favorites')),
+ ));
+ }
+ return $tabs;
+ }
+
+
+ function editors_picks() {
+ $this->set('selected', 'editors_picks');
+ $conditions = array('Collection.collection_type' => Collection::COLLECTION_TYPE_EDITORSPICK);
+ $this->Collection->unbindFully();
+ $collections = $this->Collection->findAll($conditions, 'Collection.id');
+ $this->_listing($collections);
+ }
+
+ function popular() {
+ $this->set('selected', 'popular');
+ $this->Collection->unbindFully();
+ $collections = $this->Collection->findAll(null, 'Collection.id');
+ $pagination = array('sortBy' => 'subscribers DESC');
+ $this->_listing($collections, $pagination);
+ }
+
+ function mine() {
+ $this->Amo->checkLoggedIn();
+
+ $this->set('selected', 'mine');
+ $this->set('filler', sprintf(___('collections_index_filler_mine'),
+ $this->Html->url('/collections/add')));
+
+ $user = $this->Session->read('User');
+ $collections = $this->Collection->execute(
+ "SELECT Collection.id
+ FROM collections AS Collection JOIN collections_users
+ ON Collection.id = collections_users.collection_id
+ WHERE collections_users.user_id = " . $user['id']);
+ $this->_listing($collections);
+ }
+
+ function favorites() {
+ $this->Amo->checkLoggedIn();
+ $this->set('selected', 'favorites');
+ $this->set('filler', sprintf(___('collections_index_filler_favorites'),
+ $this->Html->url('/pages/collector')));
+
+ $user = $this->Session->read('User');
+ $collections = $this->Collection->execute(
+ "SELECT Collection.id
+ FROM collections AS Collection JOIN collection_subscriptions
+ ON Collection.id = collection_subscriptions.collection_id
+ WHERE collection_subscriptions.user_id = " . $user['id']);
+ $this->_listing($collections);
+ }
+
+ /**
+ * Creates a collection if POSTed to, otherwise shows a collection creation form
+ */
+ function add() {
+ $this->Amo->checkLoggedIn(); // must be logged in
+
+ // view setup
+ $this->layout = 'amo2009'; // TODO: remove this when the entire controller is amo2009-based
+ $this->set('bodyclass', 'inverse collections-page');
+ $this->publish('jsAdd', array('jquery.autocomplete.pack.js'));
+ $this->publish('breadcrumbs', array(
+ sprintf(___('addons_home_pagetitle'), APP_PRETTYNAME) => '/',
+ ___('collections_breadcrumb') => '/collections'
+ ));
+
+ $initial_addons = array();
+ if (!empty($this->params['url']['addons'])) {
+ $_init_ids = explode(',', $this->params['url']['addons']);
+ foreach ($_init_ids as &$_init_id) {
+ if (!is_numeric($_init_id)) continue;
+ $_addon = $this->Addon->getAddon($_init_id);
+ if (empty($_addon)) continue;
+ $initial_addons[] = array(
+ 'id' => $_addon['Addon']['id'],
+ 'name' => $_addon['Translation']['name']['string'],
+ 'preview' => $this->Image->getAddonIconURL($_init_id)
+ );
+ }
+ }
+ $this->publish('initial_addons', $initial_addons);
+
+ if (isset($this->data['Collection'])) {
+ // clean up whitespace
+ $this->data['Collection']['name'] = trim($this->data['Collection']['name']);
+ $this->data['Collection']['description'] = trim($this->data['Collection']['description']);
+
+ $user = $this->Session->read('User');
+ $this->data['Collection']['user_id'] = $user['id'];
+ $this->data['Collection']['application_id'] = APP_ID; // defaults to current app
+
+ $data = $this->data['Collection'];
+ $this->Amo->clean($data);
+ if ($this->Collection->save($data)) {
+ $collectionid = $this->Collection->id; // new collection id
+ $_coll = $this->Collection->findById($collectionid, array('Collection.uuid'));
+
+ $this->Collection->addUser($this->Collection->id, $user['id'], COLLECTION_ROLE_OWNER);
+
+ if (!empty($this->params['form']['addons'])) {
+ // add-ons preselected
+ $this->Amo->clean($this->params['form']['addons']);
+ foreach ($this->params['form']['addons'] as &$addon) {
+ $this->Collection->addAddonToCollection($collectionid, $user['id'], $addon);
+ }
+ }
+
+ $this->Session->write('collection_created', $collectionid);
+ $this->redirect("/collections/view/{$_coll['Collection']['uuid']}");
+ return;
+ } else {
+ $this->set('form_errors', true);
+ }
+ }
+ }
+
+ /**
+ * Non-JS only: Adds an add-on to a collection, then redirects to display page
+ */
+ function addtocollection() {
+ $this->Amo->checkLoggedIn(); // must be logged in
+
+ if (empty($this->data['addon_id']) || empty($this->data['collection_uuid'])) {
+ $this->flash(sprintf(_('error_missing_argument'), 'addon_id or collection_id'), '/', 3);
+ return;
+ }
+
+ // create new collection if requested
+ if ($this->data['collection_uuid'] == 'new') {
+ if (is_array($this->data['addon_id']))
+ $addonids = implode(',', $this->data['addon_id']);
+ else
+ $addonids = $this->data['addon_id'];
+ $addonids = urlencode($addonids);
+ $this->redirect("/collections/add/?addons={$addonids}");
+ return;
+ }
+
+ $this->Amo->clean($this->data);
+ $addon_id = $this->data['addon_id'];
+ $collection_id = $this->Collection->getIdForUUID($this->data['collection_uuid']);
+ if (!is_numeric($addon_id) || !$collection_id) {
+ $this->flash(sprintf(_('error_missing_argument'), 'addon_id or collection_id'), '/', 3);
+ return;
+ }
+ $user = $this->Session->read('User');
+ $added = $this->Collection->addAddonToCollection($collection_id, $user['id'], $addon_id);
+ // go to add-on's display page and display success message
+ $this->Session->write('collection_addon_added', $this->data['collection_uuid']);
+ $this->redirect("/addon/{$addon_id}");
+ return;
+ }
+
+ function _getSortedAddons($collection_id) {
+ $sort_options = array(
+ 'date-added' => ___('collections_detail_sort_date'),
+ 'name' => ___('collections_detail_sort_name'),
+ 'popularity' => ___('collections_detail_sort_popularity')
+ );
+
+ // Fetch #1. What's in the collection?
+ $addonIds = $this->Addon->getAddonsFromCollection($collection_id);
+
+ // Set up pagination
+ $this->Pagination->total = count($addonIds);
+ $this->Pagination->show = 7;
+ list($order, $limit, $page) = $this->Pagination->init();
+
+ // Default sorting is by date added to Collection.
+ if (isset($_GET['sortby']) && array_key_exists($_GET['sortby'], $sort_options)) {
+ $sortby = $_GET['sortby'];
+ } else {
+ $sortby = 'date-added';
+ }
+
+ // Fetch #2. Sort and fetch paged addon ids.
+ if ($sortby == 'date-added') {
+ $field = 'addons_collections.added DESC';
+ $extra = 'JOIN addons_collections ON Addon.id = addons_collections.addon_id';
+ $pagedIds = $this->Addon->sorted($addonIds, $field, $limit, $page, $extra);
+ } else {
+ if ($sortby == 'popularity') {
+ $field = 'weeklydownloads DESC';
+ } else if ($sortby == 'name') {
+ $field = 'name';
+ }
+ $pagedIds = $this->Addon->sorted($addonIds, $field, $limit, $page);
+ }
+
+ // Fetch #3! Pull useful addon data this time.
+ $addons = $this->Addon->getAddonList($pagedIds,array(
+ 'all_tags', 'authors', 'compatible_apps', 'files', 'latest_version',
+ 'list_details'));
+
+ foreach($addons as &$addon) {
+ $a = &$addon['Addon'];
+ // Get publish details for each add-on
+ $publishDetails = $this->Addon->getCollectionPublishDetails($a['id'], $collection_id);
+ $a = array_merge($a, $publishDetails);
+ }
+
+ return array($addons, $sort_options, $sortby);
+ }
+
+ function view($uuid = NULL) {
+ if (!$uuid) {
+ $this->flash(sprintf(_('error_missing_argument'), 'collection_id'), '/', 3);
+ return;
+ }
+
+ $id = $this->Collection->getIdForUuidOrNickname($uuid);
+ if (!$id) {
+ $this->flash(_('collection_not_found'), '/', 3);
+ return;
+ }
+ $_conditions['Collection.id'] = $id;
+
+ $collection = $this->Collection->find($_conditions, null, null, 1);
+
+ list($addons, $sort_options, $sortby) = $this->_getSortedAddons($collection['Collection']['id']);
+
+ $this->publish('addons', $addons);
+ $this->publish('collection', $collection);
+ $this->publish('sort_options', $sort_options);
+ $this->publish('sortby', $sortby);
+ $this->pageTitle = $collection['Translation']['name']['string'] . " :: " . sprintf(_('addons_home_pagetitle'), APP_PRETTYNAME);
+
+ // User-specific stuff.
+ if ($this->Session->check('User')) {
+ $user = $this->Session->read('User');
+ $is_subscribed = $this->Collection->isSubscribed($id, $user['id']);
+ if ($is_subscribed) {
+ $action = $this->Collection->getUnsubscribeUrl();
+ } else {
+ $action = $this->Collection->getSubscribeUrl();
+ }
+ $this->publish('is_subscribed', $is_subscribed);
+ $this->publish('subscribe_action', $action);
+ $this->_getUserRights($user, $id);
+ } else {
+ // Use 0 as a dummy user.
+ $this->_getUserRights(array('id' => 0), $id);
+ }
+
+ // was the collection just created? show success message
+ $collection_created = $this->Session->read('collection_created');
+ if ($collection_created == $id) $this->Session->delete('collection_created');
+ $this->publish('collection_created', ($collection_created == $id));
+
+ $rss_url = sprintf('/collection/%s?format=rss', $collection['Collection']['uuid']);
+ $this->publish('rssAdd', array(
+ array($rss_url,
+ sprintf(___('collection_detail_rss_title'),
+ $collection['Translation']['name']['string']))
+ ));
+
+ if (isset($_GET['format']) && $_GET['format'] == 'rss') {
+ $this->publish('atom_self', $rss_url);
+ $this->publish('rss_title', $collection['Translation']['name']['string']);
+ $this->publish('rss_description', $collection['Translation']['description']['string']);
+ return $this->render('rss/collection', 'rss');
+ }
+
+ $this->publish('breadcrumbs', array(
+ sprintf(___('addons_home_pagetitle'), APP_PRETTYNAME) => '/',
+ ___('collections_breadcrumb') => '/collections'
+ ));
+
+ $this->render('detail');
+ }
+
+ /**
+ * Subscribes user to the collection
+ */
+ function subscribe($ajax = null) {
+ $this->_subscribe_unsubscribe($ajax);
+ }
+
+ /**
+ * Unsubscribe a user from a collection
+ */
+ function unsubscribe($ajax = null) {
+ $this->_subscribe_unsubscribe($ajax);
+ }
+
+ /**
+ * Combined function for subscribing/unsubscribing. Action is determined by
+ * $this->action.
+ * @access private
+ * @param string $ajax undefined or 'ajax' for no-frills rendering
+ * @return bool render()ed successfully?
+ */
+ function _subscribe_unsubscribe($ajax = null) {
+ $this->Amo->checkLoggedIn(); // must be logged in
+
+ $this->publish('is_ajax', ($ajax == 'ajax'));
+
+ if (!in_array($this->action, array('subscribe', 'unsubscribe'))) {
+ $this->flash(___('error_access_denied'), '/', 3);
+ return;
+ }
+
+ if (empty($this->params['form']['uuid'])) { // uuid needs to be POSTed
+ $this->flash(sprintf(_('error_missing_argument'), 'uuid'), '/', 3);
+ return;
+ }
+ $uuid = $this->params['form']['uuid'];
+ $id = $this->Collection->getIdForUuidOrNickname($uuid);
+ if (!$id || !is_numeric($id)) {
+ $this->set('success', false);
+ return $this->render('subscribe');
+ }
+
+ $user = $this->Session->read('User');
+ if ($this->action == 'subscribe') {
+ $result = $this->Collection->subscribe($id, $user['id']);
+ } else {
+ $result = $this->Collection->unsubscribe($id, $user['id']);
+ }
+ $collection = $this->Collection->findById($id, array('id', 'name'), null, -1);
+ $this->set('success', $result);
+
+ $this->publish('collection', $collection);
+
+ // set up view and render result
+ $this->publish('breadcrumbs', array(
+ sprintf(___('addons_home_pagetitle'), APP_PRETTYNAME) => '/',
+ ___('collections_breadcrumb') => '/collections'
+ ));
+ return $this->render('subscribe');
+ }
+
+ /**
+ * Edit collection
+ */
+ function edit($uuid = null) {
+ $this->Amo->checkLoggedIn(); // must be logged in
+
+ // disable query caching so changes are visible immediately
+ $this->Collection->caching = false;
+
+ if (empty($uuid)) {
+ $this->flash(sprintf(_('error_missing_argument'), 'collection_id'), '/', 3);
+ return;
+ }
+ $id = $this->Collection->getIdForUuidOrNickname($uuid);
+ if (!$id) {
+ $this->flash(_('collection_not_found'), '/', 3);
+ return;
+ }
+
+ // access rights
+ $user = $this->Session->read('User');
+ $this->publish('user', $user);
+ $rights = $this->_getUserRights($user, $id);
+ if (!($rights['writable'] || $rights['isadmin'])) {
+ $this->flash(___('error_access_denied'), '/', 3);
+ return;
+ }
+
+ if (!empty($this->data)) {
+ // Delete collection?
+ if (isset($this->data['action']) && $this->data['action'] == 'delete-coll') {
+ if (!$rights['atleast_owner']) {
+ $this->flash(___('error_access_denied'), '/', 3);
+ return;
+ }
+ $this->Collection->delete($id);
+ $this->Session->write('collection_deleted', true);
+ $this->redirect("/collections");
+ return;
+ }
+
+ // regular save
+ $success = $this->_saveCollectionEdit($id, $rights);
+
+ if ($success) {
+ // grab updated collection nickname/uuid
+ $updated = $this->Collection->findById($id, array('nickname', 'uuid'));
+ $this->publish('collection_saved', true, false);
+ if (empty($updated['Collection']['nickname']))
+ $this->publish('collection_url', "/collection/{$updated['Collection']['uuid']}");
+ else
+ $this->publish('collection_url', "/collection/{$updated['Collection']['nickname']}");
+ } else {
+ $this->set('form_errors', true);
+ }
+ }
+
+ // get collection data for display (and publish to view)
+ $this->_getCollectionDataForView($id);
+
+ // view setup
+ $this->layout = 'amo2009'; // TODO: remove this when the entire controller is amo2009-based
+ $this->set('bodyclass', 'inverse collections-page');
+ $this->publish('jsAdd', array('jquery-ui/ui.core.min', 'jquery-ui/ui.tabs.min',
+ 'jquery.autocomplete.pack.js'));
+ $this->publish('breadcrumbs', array(
+ sprintf(___('addons_home_pagetitle'), APP_PRETTYNAME) => '/',
+ ___('collections_breadcrumb') => '/collections'
+ ));
+ }
+
+ /**
+ * get collection data for collection edit page (and publish it to view)
+ * @param int $id collection ID
+ * @return void
+ * @access private
+ */
+ function _getCollectionDataForView($id) {
+ $this->Collection->unbindModel(array('hasAndBelongsToMany'=>array('Addon')));
+ $collection = $this->Collection->findById($id);
+ $this->data['Collection'] = $collection;
+
+ // translations
+ $translations = $this->Collection->getAllTranslations($id);
+ $this->publish('translations', $translations);
+
+ // addons
+ $addons = $this->AddonCollection->getAddonsFromCollection($id);
+ $this->publish('addons', $addons);
+ $addons_noscript = array();
+ foreach ($addons as &$addon) {
+ $addons_noscript[$addon['AddonCollection']['addon_id']] = $addon['Addon']['Translation']['name']['string'];
+ }
+ $this->publish('addons_noscript', $addons_noscript);
+
+ // collection icon
+ $this->publish('iconurl', $this->Image->getCollectionIconURL($id), false);
+
+ // prepare applications
+ global $app_shortnames, $app_prettynames;
+ $appoptions = array();
+ foreach ($app_shortnames as $sn => &$no) {
+ $appoptions[$no] = $app_prettynames[$sn];
+ }
+ $this->publish('appoptions', $appoptions, false);
+
+ // prepare collection types
+ $this->publish('collection_types', array(
+ Collection::COLLECTION_TYPE_NORMAL => ___('collections_type_normal'),
+ Collection::COLLECTION_TYPE_AUTOPUBLISHER => ___('collections_type_autopublisher'),
+ Collection::COLLECTION_TYPE_EDITORSPICK => ___('collections_type_editorspick')
+ ), false);
+
+ // get existing publishers and managers
+ $publishers = $this->Collection->getUsers($id, array(COLLECTION_ROLE_PUBLISHER));
+ $publishers_noscript = $managers_noscript = array();
+ foreach ($publishers as &$p) {
+ $publishers_noscript[$p['User']['id']] = $p['User']['email'];
+ }
+ $managers = $this->Collection->getUsers($id, array(COLLECTION_ROLE_ADMIN));
+ foreach ($managers as &$m) {
+ $managers_noscript[$m['User']['id']] = $m['User']['email'];
+ }
+ $this->publish('publishers', $publishers);
+ $this->publish('publishers_noscript', $publishers_noscript);
+ $this->data['Publishers']['p_onlyme'] = (int)empty($publishers);
+ $this->publish('managers', $managers);
+ $this->publish('managers_noscript', $managers_noscript);
+ $this->data['Managers']['m_onlyme'] = (int)empty($managers);
+ }
+
+ /**
+ * save collection data from edit page
+ *
+ * @param int $id Collection ID
+ * @param array $rights user rights array from _getUserRights()
+ * @return bool successfully saved?
+ * @access private
+ */
+ function _saveCollectionEdit($id, $rights) {
+ $disallowed_fields = array('uuid', 'access', 'subscribers',
+ 'created', 'modified', 'downloads');
+ if (!$rights['isadmin']) $allowed_fields[] = 'collection_type';
+ $collectiondata = $this->Amo->filterFields($this->data['Collection'],
+ array(), $disallowed_fields);
+ $this->Collection->id = $id;
+
+ list($localizedFields, $unlocalizedFields) = $this->Collection->splitLocalizedFields($collectiondata);
+ // clean up whitespace
+ foreach ($localizedFields as $field => &$translations) {
+ foreach ($translations as $lang => &$l_string) {
+ $l_string = trim($l_string);
+ $this->params['form']['data']['Collection'][$field][$lang] = $l_string;
+ }
+ }
+
+ $valid_translations = $this->Collection->validateTranslations($localizedFields);
+ if ($valid_translations) {
+ $this->Amo->clean($localizedFields);
+ $this->Collection->saveTranslations($id, $this->params['form']['data']['Collection'], $localizedFields);
+ }
+
+ // handle icon removal/upload
+ if (!empty($this->data['Icon']['delete'])) {
+ $unlocalizedFields['icontype'] = '';
+ $unlocalizedFields['icondata'] = null;
+ } elseif (!empty($_FILES['icon']['name'])) {
+ $iconData = $this->Developers->validateIcon($_FILES['icon']);
+ if (is_array($iconData)) {
+ $unlocalizedFields = array_merge($unlocalizedFields, $iconData);
+ }
+ }
+
+ // field post-processing
+ if (!isset($unlocalizedFields['listed'])) $unlocalizedFields['listed'] = 0;
+ if (!empty($unlocalizedFields['nickname']))
+ $unlocalizedFields['nickname'] = preg_replace(INVALID_COLLECTION_NICKNAME_CHARS,
+ '_', mb_strtolower(trim($unlocalizedFields['nickname'])));
+
+ if ($success = $this->Collection->save($unlocalizedFields)) {
+ // save noscript data
+ if ($rights['atleast_manager']) {
+ // save users
+ $this->_saveCollectionEditUserData($id, 'Publishers');
+ $this->_saveCollectionEditUserData($id, 'Managers');
+ } // at least manager
+
+ // add-ons
+ // remove old add-ons
+ if (!empty($this->data['Addons']['delete'])) {
+ foreach ($this->data['Addons']['delete'] as &$_aid) {
+ $this->AddonCollection->deleteByAddonIdAndCollectionId($_aid, $id, ($rights['atleast_manager'] ? null : $user['id']));
+ }
+ }
+ // add new add-ons
+ if (!empty($this->params['form']['q'])) {
+ $_aids = explode(',', $this->params['form']['q']);
+ foreach ($_aids as &$_aid) {
+ $_aid = trim($_aid);
+ if (!empty($_aid)) {
+ $_addon = $this->Addon->getAddon($_aid);
+ if (!empty($_addon) && in_array($_addon['Addon']['status'], $valid_status))
+ $this->Collection->addAddonToCollection($id, $user['id'], $_aid);
+ }
+ }
+ }
+ }
+ return $success;
+ }
+
+ /**
+ * save user data (managers/publishers) for collection edit
+ * @param int $id collection ID
+ * @param string $type "Publishers" or "Managers"
+ * @return void
+ * @access private
+ */
+ function _saveCollectionEditUserData($id, $type) {
+ switch ($type) {
+ case 'Publishers':
+ $onlyme_fieldid = 'p_onlyme';
+ $role = COLLECTION_ROLE_PUBLISHER;
+ break;
+ case 'Managers':
+ $onlyme_fieldid = 'm_onlyme';
+ $role = COLLECTION_ROLE_ADMIN;
+ break;
+ default:
+ return;
+ }
+
+ if (isset($this->data[$type][$onlyme_fieldid]) && $this->data[$type][$onlyme_fieldid]) {
+ // remove all existing users with this role
+ $this->Collection->removeAllUsersByRole($id, $role);
+ } else {
+ // remove old users
+ if (!empty($this->data[$type]['delete'])) {
+ foreach ($this->data[$type]['delete'] as &$_pid) {
+ $this->Collection->removeUser($id, $_pid);
+ }
+ }
+ // save new users
+ if (!empty($this->data[$type]['new'])) {
+ $_emails = explode(',', $this->data[$type]['new']);
+ foreach ($_emails as &$_em) {
+ $_em = trim($_em);
+ if (empty($_em)) continue;
+ $_uid = $this->User->findByEmail($_em, array('id'));
+ if (empty($_uid)) continue;
+ $this->Collection->addUser($id, $_uid['User']['id'], $role);
+ }
+ }
+ // don't publish them back to the view
+ $this->data[$type]['new'] = '';
+ }
+ }
+
+ /**
+ * get user rights for a specific collection
+ * @param array $user array from user model
+ * @param int $collection_id
+ * @return array of booleans ('writable', 'isadmin', 'atleast_manager',
+ * 'atleast_owner', 'role')
+ * @access private
+ */
+ function _getUserRights($user, $collection_id) {
+ $writable = $this->Collection->isWritableByUser($collection_id, $user['id']);
+ $isadmin = $this->SimpleAcl->actionAllowed('Admin', 'EditAnyCollection', $user);
+ $role = $this->Collection->getUserRole($collection_id, $user['id']);
+ $atleast_manager = ($isadmin || in_array($role, array(COLLECTION_ROLE_ADMIN, COLLECTION_ROLE_OWNER)));
+ $atleast_owner = ($isadmin || $role == COLLECTION_ROLE_OWNER);
+
+ $this->publish('writable', $writable, false);
+ $this->publish('isadmin', $isadmin, false);
+ $this->publish('atleast_manager', $atleast_manager, false);
+ $this->publish('atleast_owner', $atleast_owner, false);
+ $this->publish('role', $role, false);
+
+ return array(
+ 'writable' => $writable,
+ 'isadmin' => $isadmin,
+ 'atleast_manager' => $atleast_manager,
+ 'atleast_owner' => $atleast_owner,
+ 'role' => $role
+ );
+ }
+
+
+ /*** Fashion Your Firefox ***/
+
+ /**
+ * Special "interactive collections" page for first-time users
+ */
+ function interactive() {
+ // this is Firefox only, for now.
+ if (APP_ID != APP_FIREFOX) {
+ $this->redirect('/');
+ exit();
+ }
+
+ // XXX: for accessibility (bug 462411), we use a hand-bundled accordion
+ // + core jquery UI file. Once jquery UI is updated to post-1.6.2rc2,
+ // the regular jquery UI accordion should be used (cf. jquery ui bug
+ // 3553, http://ui.jquery.com/bugs/ticket/3553)
+ $this->set('jsAdd', array('jquery-ui/jq-ui-162rc2-accordion-bundle-a11y.min.js', 'jquery-ui/jqModal.js'));
+ $this->set('cssAdd', array('collection-style'));
+
+ $addonIds = $this->Addon->getCategorizedAddonsFromCollection(1); // special collection ID
+ $addons = array();
+ foreach ($addonIds as $catid => $cataddons) {
+ $addons[$catid] = $this->Addon->getAddonList($cataddons, array('files', 'latest_version', 'list_details'));
+ }
+ $this->publish('addons', $addons);
+
+ // prepare view, then render
+ $this->publish('suppressHeader', true, false);
+ $this->publish('suppressLanguageSelector', true, false);
+ $this->publish('suppressCredits', true, false);
+ $this->pageTitle = 'Fashion Your Firefox';
+ }
+
+ /**
+ * installation dialog for collections
+ * @param string $method 'html' (with layout) or 'ajax' (without)
+ */
+ function install($method = 'html') {
+ $addons = array();
+ if (!empty($_POST['addon'])) {
+ $addons = $this->Addon->getAddonList($_POST['addon'], array(
+ 'compatible_apps', 'files', 'latest_version', 'list_details'));
+
+ // XXX: ugly hack allowing signed add-ons to be installed separately
+ // due to bug 462108 and 453545. The DB doesn't know which ones are
+ // signed or not so we need to hardcode them here.
+ $signed_addons = array(
+ 5579, // Cooliris
+ 3615, // Delicious
+ 8384, // Digg
+ 5202, // Ebay
+ 2410, // Foxmarks
+ 1512 // LinkedIn
+ );
+ foreach ($addons as &$addon) {
+ $addon['Addon']['signed_xpi'] = in_array($addon['Addon']['id'], $signed_addons);
+ }
+ }
+ $this->publish('addons', $addons);
+
+ // fetch all platforms
+ $this->Platform->unbindFully();
+ $platforms_all = $this->Platform->findAll();
+ $platforms = array();
+ foreach ($platforms_all as $pf) {
+ $platforms[$pf['Platform']['id']] = $pf['Translation']['name']['string'];
+ }
+ $this->publish('platforms', $platforms);
+
+ // prepare and display view
+ $this->pageTitle = 'Collections' . " :: " . sprintf(_('addons_home_pagetitle'), APP_PRETTYNAME);
+ $is_ajax = ($method=='ajax');
+ $this->publish('is_ajax', $is_ajax, false);
+ $this->publish('suppressHeader', true, false);
+ $this->publish('suppressLanguageSelector', true, false);
+ if ($is_ajax) {
+ $this->layout = null;
+ $this->render('install', false);
+ } else {
+ $this->render();
+ }
+ }
+
+ /**
+ * "Success!" screen
+ */
+ function success() {
+ if (isset($_GET['i'])) {
+ $installed = explode(',', $_GET['i']);
+ $installed = array_filter($installed, 'is_numeric');
+ if (!empty($installed)) {
+ $addons = $this->Addon->getAddonList($installed);
+ } else {
+ $addons = array();
+ }
+ } else {
+ $addons = array();
+ }
+ $this->publish('addons', $addons);
+
+ $this->set('cssAdd', array('collection-style'));
+ $this->publish('suppressHeader', true, false);
+ $this->publish('suppressLanguageSelector', true, false);
+ $this->publish('suppressCredits', true, false);
+ $this->pageTitle = 'Fashion Your Firefox';
+ }
+
+ /*** END Fashion Your Firefox ***/
+
+
+ /*** AJAX Handlers ***/
+
+ /**
+ * AJAX action for looking up add-ons to add to a collection
+ */
+ function addonLookup() {
+ global $valid_status;
+
+ // Rather than change our cake parameter regex, use a normal get var
+ $name = $_GET['q'];
+ $this->Amo->clean($name);
+
+ // search conditions
+ $conditions = array(
+ 'Addon.status' => $valid_status,
+ 'Addon.inactive' => 0
+ );
+ if (mb_strlen($name) >= 4) { // fuzzy matching on long names only
+ $conditions['Translation.name'] = "LIKE %{$name}%";
+ } else {
+ $conditions['Translation.name'] = $name;
+ }
+
+ $addons = $this->Addon->findAll($conditions,
+ array('Addon.id', 'Addon.name'), 'Translation.name');
+ if (!empty($addons)) {
+ foreach ($addons as &$_addon) {
+ // add icons
+ $_addon['Addon']['iconpath'] = $this->Image->getAddonIconURL($_addon['Addon']['id']);
+ }
+ } else {
+ $addons = false;
+ }
+
+ $this->publish('addons', $addons);
+ $this->render('ajax/addon_lookup', 'ajax');
+ }
+
+ /**
+ * central JSON dispatcher for AJAX requests
+ */
+ function json($action, $additional = '') {
+ switch ($action) {
+ case 'nickname':
+ $json = $this->_checkNickname();
+ break;
+
+ case 'user':
+ $json = $this->_handleUser($additional);
+ break;
+
+ case 'addon':
+ $json = $this->_handleAddon($additional);
+ break;
+
+ default: $json = array(); break;
+ }
+
+ $this->publish('json', $json, false);
+ $this->render('json', 'ajax');
+ }
+
+ /**
+ * AJAX: check if collection nickname is already used
+ */
+ function _checkNickname() {
+ $this->Amo->checkLoggedIn(); // must be logged in
+ if (empty($this->params['url']['nickname'])) {
+ return $this->Error->getJSONforError(sprintf(_('error_missing_argument'), 'nickname'));
+ }
+ $nickname = preg_replace(INVALID_COLLECTION_NICKNAME_CHARS, '_',
+ mb_strtolower(trim($this->params['url']['nickname'])));
+ if ($nickname != mb_strtolower($this->params['url']['nickname']))
+ return array(
+ 'error' => 1,
+ 'error_message' => ___('collections_edit_nickname_error'),
+ 'nickname' => $nickname
+ );
+
+ $taken = $this->Collection->isNicknameTaken($this->params['url']['nickname']);
+ return array(
+ 'error' => 0,
+ 'nickname' => $nickname,
+ 'taken' => (int)$taken
+ );
+ }
+
+ /**
+ * AJAX: Add / remove user to/from this collection's roles
+ */
+ function _handleUser($action) {
+ if (empty($action)) return $this->Error->getJSONforError(sprintf(_('error_missing_argument'), 'action'));
+ if (empty($this->params['form']['collection_id'])) return $this->Error->getJSONforError(sprintf(_('error_missing_argument'), 'collection_id'));
+
+ $this->Amo->checkLoggedIn(); // must be logged in
+
+ $collection_id = $this->params['form']['collection_id'];
+ $role = @$this->params['form']['role'];
+ $email = @$this->params['form']['email'];
+ $user_id = @$this->params['form']['user_id'];
+
+ $user = $this->Session->read('User');
+ $rights = $this->_getUserRights($user, $collection_id);
+ if (!$rights['atleast_manager']) return $this->Error->getJSONforError(___('error_access_denied'));
+
+ switch ($action) {
+ case 'add':
+ if (empty($email)) return $this->Error->getJSONforError(sprintf(_('error_missing_argument'), 'email'));
+ $roles = array('publishers' => COLLECTION_ROLE_PUBLISHER, 'managers' => COLLECTION_ROLE_ADMIN);
+ if (empty($role)) return $this->Error->getJSONforError(sprintf(_('error_missing_argument'), 'role'));
+
+ $newuser = $this->User->findByEmail($email, array('id'));
+ if (!empty($newuser)) {
+ if ($this->Collection->getUserRole($collection_id, $newuser['User']['id']) === false) {
+ $this->Collection->addUser($collection_id, $newuser['User']['id'], $roles[$role]);
+ return array('id' => $newuser['User']['id'], 'email' => $email);
+ } else {
+ return $this->Error->getJSONforError(___('error_user_exists'));
+ }
+ } else {
+ return $this->Error->getJSONforError(___('error_user_notfound'));
+ }
+ break;
+
+ case 'del':
+ if (empty($user_id))
+ return $this->Error->getJSONforError(sprintf(_('error_missing_argument'), 'user_id'));
+ if ($this->Collection->removeUser($collection_id, $user_id) !== false) {
+ return array('id' => $user_id);
+ } else {
+ return $this->Error->getJSONforError(___('error_user_notfound'));
+ }
+ break;
+
+ default:
+ return $this->Error->getJSONforError(sprintf(_('error_missing_argument'), 'action'));
+ }
+ }
+
+ /**
+ * AJAX: Add / remove add-on to/from this collection
+ * @param string action one of add, del, savecomment
+ * @param int collection_id (optional)
+ * @param string collection_uuid (optional)
+ * Either collection_id or collection_uuid must be specified, but not both.
+ * @param int addon_id
+ */
+ function _handleAddon($action) {
+ global $valid_status;
+
+ if (empty($action)) return $this->Error->getJSONforError(sprintf(_('error_missing_argument'), 'action'));
+ if (empty($this->params['form']['addon_id']) || !is_numeric($this->params['form']['addon_id'])) return $this->Error->getJSONforError(sprintf(_('error_missing_argument'), 'addon_id'));
+ if (!empty($this->params['form']['collection_id']) && is_numeric($this->params['form']['collection_id'])) {
+ $collection_id = $this->params['form']['collection_id'];
+ } elseif (!empty($this->params['form']['collection_uuid']) &&
+ ($collection_id = $this->Collection->getIdForUuidOrNickname($this->params['form']['collection_uuid'])) > 0) {
+ // no-op
+ } else {
+ return $this->Error->getJSONforError(sprintf(_('error_missing_argument'), 'collection_id'));
+ }
+
+ $this->Amo->checkLoggedIn(); // must be logged in
+
+ $addon_id = $this->params['form']['addon_id'];
+
+ $user = $this->Session->read('User');
+ $rights = $this->_getUserRights($user, $collection_id);
+
+ if (!($rights['writable'] || $rights['isadmin'])) return $this->Error->getJSONforError(___('error_access_denied'));
+
+ switch ($action) {
+ case 'add':
+ if ($this->AddonCollection->isAddonInCollection($addon_id, $collection_id))
+ return $this->Error->getJSONforError(___('error_addon_exists'));
+ $addon = $this->Addon->getAddon($addon_id);
+ if (empty($addon) || !in_array($addon['Addon']['status'], $valid_status))
+ return $this->Error->getJSONforError(___('error_addon_notfound'));
+ if (false !== $this->Collection->addAddonToCollection($collection_id, $user['id'], $addon_id)) {
+ return array(
+ 'id' => $addon_id,
+ 'name' => $addon['Translation']['name']['string'],
+ 'iconURL' => $this->Image->getAddonIconURL($addon_id),
+ 'date' => strftime(_('date'), mktime()),
+ 'publisher' => $this->Html->linkUserFromModel($user)
+ );
+ } else {
+ return $this->Error->getJSONforError(___('collection_error_saving_addon'));
+ }
+ break;
+
+ case 'del':
+ if (!$rights['isadmin'] && !$rights['atleast_manager']) {
+ // publisher's own add-on?
+ $res = $this->AddonCollection->deleteByAddonIdAndCollectionId($addon_id, $collection_id, $user['id']);
+ } else {
+ $res = $this->AddonCollection->deleteByAddonIdAndCollectionId($addon_id, $collection_id);
+ }
+ if ($res) {
+ return array('id' => $addon_id);
+ } else {
+ return $this->Error->getJSONforError(___('collection_error_deleting_addon'));
+ }
+ break;
+
+ case 'savecomment':
+ if (!isset($this->params['form']['comment'])) return $this->Error->getJSONforError(sprintf(_('error_missing_argument'), 'comment'));
+ $comment = strip_tags(trim($this->params['form']['comment']));
+
+ $addon = $this->AddonCollection->find(array('addon_id'=>$addon_id, 'collection_id'=>$collection_id), array('user_id'));
+ if (empty($addon)) return $this->Error->getJSONforError(___('error_addon_notfound'));
+ if (!$rights['isadmin'] && !$rights['atleast_manager']) {
+ // publisher's own add-on?
+ if ($addon['AddonCollection']['user_id'] != $user['id']) return $this->Error->getJSONforError(___('error_access_denied'));
+ }
+ if (!$this->AddonCollection->setComment($collection_id, $addon_id, $comment)) {
+ return $this->Error->getJSONforError(___('collection_error_saving_comment'));
+ } else {
+ return array(
+ 'addon_id' => $addon_id,
+ 'comment' => $comment
+ );
+ }
+ break;
+
+ default:
+ return $this->Error->getJSONforError(sprintf(_('error_missing_argument'), 'action'));
+ }
+ }
+}
diff --git a/site/app/controllers/compatibility_controller.php b/site/app/controllers/compatibility_controller.php
new file mode 100644
index 0000000..fbf3cf3
--- /dev/null
+++ b/site/app/controllers/compatibility_controller.php
@@ -0,0 +1,202 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/e
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Justin Scott <fligtar@mozilla.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/**
+ This controller requires the bin/compatibility_report.php script to be
+ run first to create NETAPP_STORAGE/compatibility.serialized. This script
+ should be run once an hour to refresh the data.
+
+ To add a new version to the compatibility dashboard:
+ 1. Add the version to $compatibility_versions array in config.php
+ 2. Change the COMPAT_DEFAULT_VERSION to the new version in config.php
+ 3. Add 2 sizes of the wordmark to app/webroot/images/wordmarks
+*/
+
+class CompatibilityController extends AppController
+{
+ var $name = 'Compatibility';
+ var $uses = array('Addon', 'Appversion');
+ var $components = array('Amo','Versioncompare');
+ var $helpers = array('Html', 'Localization');
+
+ /**
+ * Require login for all actions
+ */
+ function beforeFilter() {
+ // Disable ACLs because this controller is entirely public.
+ $this->SimpleAuth->enabled = false;
+ $this->SimpleAcl->enabled = false;
+
+ $this->cssAdd = array('compatibility');
+ $this->publish('cssAdd', $this->cssAdd);
+
+ $this->jsAdd = array('compatibility.js');
+ $this->publish('jsAdd', $this->jsAdd);
+
+ $this->layout = 'amo2009';
+ $this->pageTitle = ___('compatibility_dashboard_center_header', 'Add-on Compatibility Center').' :: '.sprintf(_('addons_home_pagetitle'), APP_PRETTYNAME);
+
+ $this->publish('expand_categories', true);
+ }
+
+ /**
+ * Index - Redirects to dashboard()
+ */
+ function index($version = COMPAT_DEFAULT_VERSION, $view = '') {
+ $this->setAction('dashboard', $version, $view);
+ }
+
+ /**
+ * Compatibility Dashboard
+ */
+ function dashboard($version = COMPAT_DEFAULT_VERSION, $view = '') {
+ global $compatibility_versions;
+ if (!in_array($version, $compatibility_versions)) $version = COMPAT_DEFAULT_VERSION;
+
+ $data = unserialize(file_get_contents(NETAPP_STORAGE.'/compatibility-fx-'.$version.'.serialized'));
+
+ $this->publish('totals', $data['totals']);
+ $this->publish('percentages', $this->_percentages($data['totals']));
+ $this->publish('version', $version);
+
+ $session = $this->Session->read('User');
+ $this->publish('loggedin', !empty($session));
+ $this->render('dashboard');
+ }
+
+ /**
+ * Detailed Report of add-ons
+ * @param string $version Firefox version to report on
+ * @param string $format Can be "ajax" to hide formatting
+ */
+ function report($version = COMPAT_DEFAULT_VERSION, $format = 'html') {
+ global $compatibility_versions;
+ if (!in_array($version, $compatibility_versions)) $version = COMPAT_DEFAULT_VERSION;
+
+ $data = unserialize(file_get_contents(NETAPP_STORAGE.'/compatibility-fx-'.$version.'.serialized'));
+
+ $this->publish('addons', $data['addons']);
+ $this->publish('totals', $data['totals']);
+ $this->publish('format', $format);
+ $this->publish('version', $version);
+
+ if ($format == 'ajax')
+ $this->render('report', 'ajax');
+ else
+ $this->render('report', 'amo2009');
+ }
+
+ function developers($version = COMPAT_DEFAULT_VERSION, $format = 'html') {
+ global $compatibility_versions;
+ if (!in_array($version, $compatibility_versions)) $version = COMPAT_DEFAULT_VERSION;
+ $session = $this->Session->read('User');
+
+ if (!empty($session)) {
+ $addon_ids = $this->Addon->getAddonsByUser($session['id']);
+ $addons = array();
+
+ if (!empty($addon_ids)) {
+ $relatedVersions = $this->Appversion->getRelatedVersions($version);
+ $appversions = $this->Versioncompare->getCompatibilityGrades($version, $relatedVersions[APP_FIREFOX]);
+
+ foreach ($addon_ids as $addon_id => $addon_name) {
+ $stats = $this->Addon->query("SELECT date, count, application FROM update_counts WHERE addon_id = {$addon_id} ORDER BY date DESC LIMIT 1");
+ $updatepings = unserialize($stats[0]['update_counts']['application']);
+
+ $addons[$addon_id] = array(
+ 'name' => $addon_name,
+ 'totalCount' => $stats[0]['update_counts']['count'],
+ 'date' => $stats[0]['update_counts']['date'],
+ 'versionCount' => 0
+ );
+
+ // Tally active users of clients using the specified version
+ if (!empty($updatepings['{ec8030f7-c20a-464f-9b0e-13a3a9e97384}'])) {
+ foreach ($updatepings['{ec8030f7-c20a-464f-9b0e-13a3a9e97384}'] as $appversion => $count) {
+ if (strpos($appversion, $version) !== false) {
+ $addons[$addon_id]['versionCount'] += $count;
+ }
+ }
+ }
+
+ $addons[$addon_id]['percentage'] = round(($addons[$addon_id]['versionCount'] / $addons[$addon_id]['totalCount'] * 100), 2);
+
+ // Get latest version's compatibility
+ $compat = $this->Addon->query("SELECT appversions.version, versions.id FROM versions INNER JOIN applications_versions ON applications_versions.version_id = versions.id INNER JOIN appversions ON appversions.id = applications_versions.max WHERE versions.addon_id={$addon_id} AND applications_versions.application_id = ".APP_FIREFOX." ORDER BY versions.created DESC LIMIT 1");
+
+ $addons[$addon_id]['appversion'] = $compat[0]['appversions']['version'];
+ $addons[$addon_id]['latestVersion'] = $compat[0]['versions']['id'];
+ $addons[$addon_id]['grade'] = $this->Versioncompare->gradeCompatibility($addons[$addon_id]['appversion'], $version, $appversions);
+ }
+ }
+
+ $this->publish('addons', $addons);
+ }
+
+ $this->publish('loggedin', !empty($session));
+ $this->publish('format', $format);
+ $this->publish('version', $version);
+
+ if ($format == 'ajax')
+ $this->render('developers', 'ajax');
+ else
+ $this->render('developers', 'amo2009');
+ }
+
+ function users($version = COMPAT_DEFAULT_VERSION) {
+ $this->publish('version', $version);
+ $this->render('users');
+ }
+
+ /* Calculate compatibility percentages, making sure they add up to 100. */
+ function _percentages($totals) {
+ $k = array(COMPAT_OTHER, COMPAT_ALPHA, COMPAT_BETA, COMPAT_LATEST);
+ $percentages = array();
+
+ foreach ($k as $compat) {
+ $p = $totals[$compat]['adu'] / $totals['adu95'];
+ // Round to 1 decimal place.
+ $percentages[$compat] = round($p * 100, 1);
+ }
+ // Put any over/under flow into COMPAT_LATEST, somewhat arbitrary.
+ $percentages[COMPAT_LATEST] += 100 - array_sum($percentages);
+ return $percentages;
+ }
+}
+
+?>
diff --git a/site/app/controllers/components/amo.php b/site/app/controllers/components/amo.php
new file mode 100644
index 0000000..fa24b1a
--- /dev/null
+++ b/site/app/controllers/components/amo.php
@@ -0,0 +1,753 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * Justin Scott <fligtar@gmail.com>.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Frederic Wenzel <fwenzel@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+class AmoComponent extends Object {
+ var $controller;
+ var $platforms;
+ var $applications;
+ var $versionIds;
+ var $navCategories;
+
+ /**
+ * Save a reference to the controller on startup
+ * @param object &$controller the controller using this component
+ */
+ function startup(&$controller) {
+ $this->controller =& $controller;
+ }
+
+ /**
+ * Checks if user has permissions for an addon
+ * @param int $id the add-on id
+ * @param array $addonInfo array of add-on data so we don't have to pull it
+ * @param bool $requireOwner whether we're checking for actual ownership
+ */
+ function checkOwnership($id, $addonInfo = array(), $requireOwner = false) {
+ $session = $this->controller->Session->read('User');
+ if (empty($session['id'])) return false;
+
+ //Check if user is an admin
+ if ($this->controller->SimpleAcl->actionAllowed('Admin', 'EditAnyAddon', $session) && !$requireOwner) {
+ return true;
+ }
+
+ //See if add-on data was passed; if not, retrieve it
+ if (empty($addonInfo['status'])) {
+ $addon = $this->controller->Addon->findById($id, null, null, -1);
+ $addonInfo = $addon['Addon'];
+ }
+
+ //Check if add-on is disabled
+ if ($addonInfo['status'] == STATUS_DISABLED) {
+ return false;
+ }
+
+ //check if user is an author of the add-on
+ if ($this->controller->Addon->query("SELECT * FROM addons_users WHERE addon_id={$id} AND user_id={$session['id']}")) {
+ return true;
+ }
+ else {
+ return false;
+ }
+ }
+
+ /**
+ * Gets the author role of the current user for the given add-on
+ * @param int $addon_id id of the add-on
+ */
+ function getAuthorRole($addon_id) {
+ $session = $this->controller->Session->read('User');
+ if (empty($session['id'])) return AUTHOR_ROLE_NONE;
+
+ // Get role from database
+ $role = $this->controller->Addon->query("SELECT role FROM addons_users WHERE addon_id={$addon_id} AND user_id={$session['id']}");
+ if (!empty($role)) {
+ $role = $role[0]['addons_users']['role'];
+ }
+
+ // Check if user has permissions to edit any add-on
+ if ($this->controller->SimpleAcl->actionAllowed('Admin', 'EditAnyAddon', $session)) {
+ if ($role == AUTHOR_ROLE_OWNER) {
+ return AUTHOR_ROLE_ADMINOWNER;
+ }
+ else {
+ return AUTHOR_ROLE_ADMIN;
+ }
+ }
+
+ // Check if add-on is disabled
+ $status = $this->controller->Addon->findById($addon_id, array('Addon.status'), null, -1);
+ if (!empty($status['Addon']['status'])) {
+ if ($status['Addon']['status'] == STATUS_DISABLED) {
+ return AUTHOR_ROLE_NONE;
+ }
+ }
+
+ // If not an admin and not disabled, return db role if we found one
+ if (!empty($role)) {
+ return $role;
+ }
+
+ return AUTHOR_ROLE_NONE;
+ }
+
+ /**
+ * Cleans an array or string for SQL and HTML, by reference
+ *
+ * @param mixed &$subject
+ */
+ function clean(&$subject, $stripTags = true) {
+ if (isset($subject)) {
+ if (is_array($subject)) {
+ foreach ($subject as $k => $v) {
+ $this->clean($subject[$k], $stripTags);
+ }
+ }
+ else {
+ if ($stripTags)
+ $subject = strip_tags($subject);
+ $subject = mysql_real_escape_string($subject);
+ }
+ }
+ }
+
+ /**
+ * Strips slashes from subject in return (NOT by reference)
+ * @param string $subject
+ */
+ function unclean($subject) {
+ if (is_array($subject)) {
+ $uncleaned = array();
+ foreach ($subject as $k => $v) {
+ $uncleaned[$k] = $this->unclean($v);
+ }
+ } else {
+ $uncleaned = stripslashes($subject);
+ }
+
+ return $uncleaned;
+ }
+
+ /**
+ * Ensures that any quotes are turned into entities
+ * @param mixed &$subject
+ */
+ function convertQuotes(&$subject) {
+ if (isset($subject)) {
+ if (is_array($subject)) {
+ foreach ($subject as $k => $v) {
+ $this->convertQuotes($subject[$k]);
+ }
+ }
+ else {
+ $subject = str_replace("'", "&#39;", $subject);
+ }
+ }
+ }
+
+ /**
+ * Returns a string representation of the Approval Status id
+ * @param int $status
+ * @deprecated since 3.5 - use Amo->getStatusNames()
+ */
+ function getApprovalStatus($status = '') {
+ //If a status id is specified, return the string
+ if ($status != '') {
+ switch ($status) {
+ case STATUS_NULL: $string = ___('addons_status_incomplete', 'Incomplete Version');
+ break;
+ case STATUS_SANDBOX: $string = ___('addons_status_sandbox', 'In Sandbox');
+ break;
+ case STATUS_PENDING: $string = ___('addons_status_pending', 'In Sandbox; Pending Review');
+ break;
+ case STATUS_NOMINATED: $string = ___('addons_status_nominated', 'In Sandbox; Public Nomination');
+ break;
+ case STATUS_PUBLIC: $string = ___('addons_status_public', 'Public');
+ break;
+ case STATUS_DISABLED: $string = ___('addons_status_disabled', 'Disabled');
+ break;
+ default: $string = ___('addons_status_unknown', 'Unknown');
+ break;
+ }
+ return $string;
+ }
+ else {
+ //If no status was passed, return an array of all statuses
+ $array = array();
+ for ($s = 0; $s <= 6; $s++) {
+ //The id must be passed as a string
+ $array[$s] = $this->getApprovalStatus("$s");
+ }
+ return $array;
+ }
+ }
+
+ /**
+ * Returns an array of possible add-on and file statuses and names
+ */
+ function getStatusNames() {
+ return array(
+ STATUS_NULL => ___('addons_status_incomplete', 'Incomplete'),
+ STATUS_SANDBOX => ___('addons_status_sandbox', 'In Sandbox'),
+ STATUS_PENDING => ___('addons_status_pending', 'In Sandbox; Pending Review'),
+ STATUS_NOMINATED => ___('addons_status_nominated', 'In Sandbox; Public Nomination'),
+ STATUS_PUBLIC => ___('addons_status_public', 'Public'),
+ STATUS_DISABLED => ___('addons_status_disabled', 'Admin Disabled')
+ );
+ }
+
+ /**
+ * Returns the name of a platform by Id, or an array of platforms
+ * The purpose of this is to reduce unnecessary database queries
+ * @param int $platform
+ * @deprecated since 3.5 - use Platform->getNames()
+ */
+ function getPlatformName($platform = '', $shortnames = false) {
+ //If platform id is set, get the name for it
+ if ($platform != '') {
+ //If the array of platforms was already retrieved, use it
+ if (!empty($this->platforms)) {
+ return $this->platforms[$platform];
+ }
+ //Otherwise, retrieve the array and save it
+ else {
+ $this->platforms = $this->getPlatformName();
+ return $this->platforms[$platform];
+ }
+ }
+ //If no id is set, return the array of platforms
+ else {
+ $model =& new Platform();
+ $model->useDbConfig = 'shadow';
+ $platforms = $model->findAll(null, null, null, null, null, -1);
+
+ $platformArray = array();
+ foreach ($platforms as $platform) {
+ if ($shortnames == true) {
+ $platformArray[$platform['Platform']['id']]['name'] = $platform['Translation']['name']['string'];
+ $platformArray[$platform['Platform']['id']]['shortname'] = $platform['Translation']['shortname']['string'];
+ }
+ else {
+ $platformArray[$platform['Platform']['id']] = $platform['Translation']['name']['string'];
+ }
+ }
+
+ return $platformArray;
+ }
+ }
+
+ /**
+ * Returns the name of an application by Id, or an array of applications
+ * The purpose of this is to reduce unnecessary database queries
+ * @param int $application
+ */
+ function getApplicationName($application = '', $shortnames = false) {
+ //If application id is set, get the name for it
+ if ($application != '') {
+ //If the array of applications was already retrieved, use it
+ if (!empty($this->applications)) {
+ return $this->applications[$application];
+ }
+ //Otherwise, retrieve the array and save it
+ else {
+ $this->applications = $this->getApplicationName();
+ return $this->applications[$application];
+ }
+ }
+ //If no id is set, return the array of applications
+ else {
+ $model =& new Application();
+ $model->useDbConfig = 'shadow';
+ $applications = $model->findAll(null, null, null, null, null, -1);
+
+ $applicationArray = array();
+ foreach ($applications as $application) {
+ if ($shortnames == true) {
+ $applicationArray[$application['Application']['id']]['name'] = $application['Translation']['name']['string'];
+ $applicationArray[$application['Application']['id']]['shortname'] = $application['Translation']['shortname']['string'];
+ }
+ else {
+ $applicationArray[$application['Application']['id']] = $application['Translation']['name']['string'];
+ }
+ }
+
+ return $applicationArray;
+ }
+ }
+
+ /**
+ * Returns the versions of an application by Id, or an array versions for all applications
+ * The purpose of this is again to reduce unnecessary database queries <br />
+ * so is on practically every page (used in advance search in search view)
+ * This code also has the side effect of memo-izing the version id's for each version of an application
+ * @param int $application -- the application id to get versions for
+ */
+ function getApplicationVersions($application = '') {
+ // If application id is set, get the name for it
+ if ($application != '') {
+ // If the array of applications was already retrieved, use it
+ if (!empty($this->applications)) {
+ return $this->applications[$application];
+ }
+ // Otherwise, retrieve the array and save it
+ else {
+ $this->applications = $this->getApplicationVersions();
+ return $this->applications[$application];
+ }
+ }
+ // If no id is set, return the array of applications
+ else {
+ $applicationModel =& new Application();
+ $applicationModel->useDbConfig = 'shadow';
+
+ loadComponent('Versioncompare');
+ $versionCompare =& new VersioncompareComponent();
+
+ $applicationModel->unbindModel(array('hasAndBelongsToMany' => array('Version'), 'hasMany' => array('Tag')));
+ $applications = $applicationModel->findAll('Application.supported=1', null, null, null, null, 2);
+ $appvids = array();
+ $versions = array();
+ foreach ($applications as $application) {
+ if (!empty($application['Appversion'])) {
+ $appversions = array();
+ //Change array structure for sorting
+ foreach ($application['Appversion'] as $appversion) {
+ $appversions[]['Appversion']['version'] = $appversion['version'];
+ $appvids[$appversion['application_id']][$appversion['version']] = $appversion['id'];
+ }
+ $versionCompare->sortAppversionArray($appversions);
+ foreach ($appversions as $appversion) {
+ $versions[$application['Application']['id']][] = $appversion['Appversion']['version'];
+ }
+ }
+ }
+ $this->versionIds = $appvids;
+ return $versions;
+ }
+ }
+
+ /**
+ * Returns the version => versionIds pairs corresponding to a particular application
+ * It is used by the SearchController
+ * @param $appid -- the application id of the application
+ * @return -- arrays of version => versionIds pairs
+ */
+ function getVersionIdsByApp($appid) {
+ if (!empty($this->versionIds)) {
+ return $this->versionIds[$appid];
+ } else {
+ $this->getApplicationVersions();
+ return $this->versionIds[$appid];
+ }
+ }
+
+ /**
+ * check if the user is logged in. If not, refer them to the login page,
+ * optionally passing on where they wanted to go to in the first place.
+ * @param string cake-relative path to refer to after login
+ * @return mixed bool true if logged in, void otherwise
+ */
+ function checkLoggedIn($whereTo = '') {
+ $session = $this->controller->Session->read('User');
+ if (!empty($session)) {
+ return true;
+ } else {
+ if ($whereTo) {
+ $_get_part = $whereTo;
+ } else {
+ $_get_part = $this->controller->params['url']['url'];
+ // strip locale and app
+ $_get_part = preg_replace('|^' . LANG . '/' . APP_SHORTNAME . '|', '', $_get_part);
+ }
+ $_get_part = '?to='.urlencode($_get_part);
+ $this->controller->redirect('/users/login'.$_get_part);
+ exit;
+ }
+ }
+
+ /**
+ * Returns information on the min and max versions for a version because Cake
+ * does not consider non-key fields in HasAndBelongsToMany tables.
+ * @param int $version The version id
+ * @return array
+ * @deprecated since 3.5 - use Version->getCompatibleApps()
+ */
+ function getMinMaxVersions($version) {
+ return $this->controller->Application->query("
+ SELECT * FROM `applications_versions`
+ LEFT JOIN `applications` ON `applications_versions`.`application_id`=`applications`.`id`
+ JOIN `translations` ON `applications`.`name`=`translations`.`id`
+ JOIN `appversions` AS `min` ON `applications_versions`.`min`=`min`.`id`
+ JOIN `appversions` AS `max` ON `applications_versions`.`max`=`max`.`id`
+ WHERE
+ `applications_versions`.`version_id`='{$version}' AND
+ `translations`.`locale`='en-US'
+ ",true);
+ }
+
+ /**
+ * Updates min/max version information manually
+ * @param int $version The version id
+ * @param array $data The array of targetApp information
+ * @return boolean true
+ * @deprecated since 3.5 - use Version->saveCompatibleApps()
+ */
+ function saveMinMaxVersions($version, $data) {
+ if (!empty($data)) {
+ foreach ($data['id'] as $id => $application_id) {
+ $this->controller->Application->execute("
+ UPDATE `applications_versions` SET
+ `min`='{$data['minVersion'][$id]}',
+ `max`='{$data['maxVersion'][$id]}'
+ WHERE
+ `application_id`='{$application_id}' AND
+ `version_id`='{$version}'
+ LIMIT 1
+ ");
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * Return the install trigger string for the specified addontype
+ * @param int $addontype The addontype of the file
+ * @param string $uri The url of the file
+ * @param string $name The name of the item
+ * @param string $icon The url of the icon
+ * @param string $hash The hash of the file
+ */
+ function installTrigger($addontype, $uri, $name = '', $icon = '', $hash = '') {
+ $xpi = array(ADDON_EXTENSION, ADDON_DICT, ADDON_LPAPP, ADDON_LPADDON);
+ $chrome = array(ADDON_THEME);
+ $search = array(ADDON_SEARCH);
+
+ $uri = str_replace("'", "\'", $uri);
+ $name = str_replace("'", "\'", $name);
+ $icon = str_replace("'", "\'", $icon);
+ $hash = str_replace("'", "\'", $hash);
+
+ if (in_array($addontype, $xpi)) {
+ return "InstallTrigger.install('{$uri}', '{$name}', '{$icon}', '{$hash}');";
+ }
+ elseif (in_array($addontype, $chrome)) {
+ return "InstallTrigger.installChrome(InstallTrigger.SKIN, '{$uri}', '{$name}');";
+ }
+ elseif (in_array($addontype, $search)) {
+ return "window.external.AddSearchProvider('{$uri}');";
+ }
+ }
+
+ /**
+ * Copies an array, returning only specifically allowed fields to be saved
+ * @param array $array the array to filter
+ * @param array $allowedFields the fields to be allowed
+ * @param array $disallowedFields the fields disallowed
+ * @return array
+ */
+ function filterFields($array, $allowedFields = array(), $disallowedFields = array()) {
+ $newArray = array();
+
+ if (!empty($array)) {
+ foreach ($array as $k => $item) {
+ if ((empty($allowedFields) || in_array($k, $allowedFields, true)) && !in_array($k, $disallowedFields, true)) {
+ if (is_array($item)) {
+ $newArray[$k] = $this->filterFields($item, $allowedFields, $disallowedFields);
+ }
+ else {
+ $newArray[$k] = $item;
+ }
+ }
+ }
+ }
+
+ return $newArray;
+ }
+
+ /**
+ * @deprecated
+ */
+ function LEGACY_describeVersionStatus($files) {
+ if (count($files) == 0) {
+ return ___('error_no_files_in_addon', 'Incomplete - No Files');
+ }
+ elseif (count($files) == 1) {
+ return $this->getApprovalStatus($files[0]['File']['status']);
+ }
+ else {
+ $statuses = array();
+ foreach ($files as $file) {
+ if (empty($statuses[$file['File']['status']])) {
+ $statuses[$file['File']['status']] = 1;
+ }
+ else {
+ $statuses[$file['File']['status']]++;
+ }
+ }
+ if (count($statuses) == 1) {
+
+ }
+
+ return 'Multiple Files';
+ }
+ }
+
+ function describeVersionStatus($files) {
+ if (count($files) == 0) {
+ return ___('error_no_files_in_addon', 'No Files');
+ }
+ else {
+ $statuses = $this->getStatusNames();
+ $fileStatuses = array();
+ $counts = array();
+
+ foreach ($files as $file) {
+ if (!empty($fileStatuses[$file['status']])) {
+ $fileStatuses[$file['status']]++;
+ }
+ else {
+ $fileStatuses[$file['status']] = 1;
+ }
+ }
+
+ foreach ($fileStatuses as $status => $count) {
+ $string = n___('devcp_describe_version_status', 'devcp_describe_version_status', $count);
+ $counts[] = sprintf($string, $count, $statuses[$status]);
+ }
+
+ return implode('; ', $counts);
+ }
+ }
+
+ /**
+ * Returns the date in MySQL NOW() format
+ */
+ function getNOW() {
+ return date('Y-m-d H:i:s');
+ }
+
+ /**
+ * Copy a file to the rsync location for updates
+ * @param int $addon_id the add-on id
+ * @param string $filename the filename
+ * @param boolean $overwrite whether to overwrite the destination file
+ * @return boolean
+ */
+ function copyFileToPublic($addon_id, $filename, $overwrite = true) {
+ // Only copy if the path has been defined
+ if (!defined('PUBLIC_STAGING_PATH')) {
+ // return true because false indicates error
+ return true;
+ }
+
+ $currentFile = REPO_PATH."/{$addon_id}/{$filename}";
+ $newDir = PUBLIC_STAGING_PATH."/{$addon_id}";
+ $newFile = $newDir."/{$filename}";
+
+ // Make sure source file exists
+ if (!file_exists($currentFile)) {
+ return false;
+ }
+
+ // If we don't want to overwrite, make sure we don't
+ if (!$overwrite && file_exists($newFile)) {
+ // return true because this is not treated as an error
+ return false;
+ }
+
+ // Make directory if necessary
+ if (!file_exists($newDir)) {
+ if (!mkdir($newDir)) {
+ return false;
+ }
+ }
+
+ return copy($currentFile, $newFile);
+ }
+
+ function accessDenied() {
+ header('HTTP/1.1 401 Unauthorized');
+
+ $this->controller->layout = 'mozilla';
+ $this->controller->pageTitle = _('error_access_denied') . ' :: ' . sprintf(_('addons_home_pagetitle'), APP_PRETTYNAME);
+ $this->controller->set('breadcrumbs', _('error_access_denied'));
+ $this->controller->set('subpagetitle', _('error_access_denied'));
+ $this->controller->viewPath = 'errors';
+ $this->controller->render('error401');
+
+ exit;
+ }
+
+ /**
+ * Logs detailed information to a specific logfile
+ * @param string $message Log message
+ * @param bool $dumpData whether to dump the controller's data in the entry
+ * @deprecated
+ */
+ function detailedLog($message, $dumpData = true) {
+ if (!defined('DETAILED_LOG_PATH')) {
+ return false;
+ }
+
+ $logfile = DETAILED_LOG_PATH.'/'.date('Y-m-d');
+
+ $fp = fopen($logfile, 'a');
+ fwrite($fp, "[".date('r')."] (".php_uname('n').") {$message}\n");
+ if ($dumpData) {
+ fwrite($fp, print_r($this->controller->data, true)."\n");
+ }
+ fclose($fp);
+ }
+
+
+ /**
+ * Get a list of tags in alphabetical order.
+ */
+ function getTags($app=APP_ID,$type=ADDON_EXTENSION) {
+
+ if (!isset($this->controller->Tag)) {
+ loadModel('Tag');
+ $this->controller->Tag =& new Tag();
+ // for CakePHP 1.2 this would be:
+ // $this->controller->loadModel('Tag');
+ }
+
+ $this->controller->Tag->unbindFully();
+
+ return $this->controller->Tag->findAll(
+ array(
+ 'application_id' => $app,
+ 'addontype_id' => $type
+ ),
+ null,
+ 'Tag.weight, Translation.name'
+ );
+ }
+
+ /**
+ * Get categories/addon types list for global navigation menu
+ * @return array Category list, style:
+ * array(
+ * array(name=>"abc", link="browse/type:1/cat:1"),
+ * ...
+ * )
+ */
+ function getNavCategories() {
+ global $hybrid_categories, $app_listedtypes, $valid_status;
+
+ if (!empty($this->navCategories)) return $this->navCategories;
+
+ // addon type list to be added to regular categories list
+ // get "Themes" category name
+ if (!isset($this->controller->Addontype)) {
+ loadModel('Addontype');
+ $this->controller->Addontype = new Addontype();
+ }
+
+ $names = $this->controller->Addontype->getNames();
+ $_themes_name = $names[ADDON_THEME];
+
+ $catlist = array(
+ array('name' => ___('langtools_header_dicts_and_langpacks'),
+ 'type' => ADDON_DICT,
+ 'cat' => 0,
+ 'weight' => 0),
+ array('name' => $_themes_name,
+ 'type' => ADDON_THEME,
+ 'cat' => 0,
+ 'weight' => 0)
+ );
+
+ // add plugins where appropriate
+ if (in_array(ADDON_PLUGIN, $app_listedtypes[APP_ID])) {
+ $catlist[] = array(
+ 'name' => ___('addons_plugins_pagetitle'),
+ 'type' => ADDON_PLUGIN,
+ 'cat' => 0,
+ 'weight' => 0,
+ 'count' => COUNT_ADDON_PLUGIN,
+ );
+ }
+
+ // create two sort arrays that we can use with array_multisort later
+ $_weights = array();
+ $_names = array();
+ foreach ($catlist as $_item) {
+ $_weights[] = $_item['weight'];
+ $_names[] = strtolower($_item['name']);
+ }
+
+ // add regular categories to list
+ $tags = $this->getTags();
+ foreach ($tags as $_tag) {
+ /* support hybrid categories */
+ if (isset($hybrid_categories[APP_ID][$_tag['Tag']['id']])) {
+ $_type = $hybrid_categories[APP_ID][$_tag['Tag']['id']];
+ $_cat = 0;
+ } else {
+ $_type = $_tag['Tag']['addontype_id'];
+ $_cat = $_tag['Tag']['id'];
+ }
+
+ $_name = $_tag['Translation']['name']['string'];
+ $_weight = $_tag['Tag']['weight'];
+ $_count = $_tag['Tag']['count'];
+
+ // add item to results array
+ $catlist[] = array(
+ 'name' => $_name,
+ 'type' => $_type,
+ 'cat' => $_cat,
+ 'weight' => $_weight,
+ 'count' => $_count
+ );
+
+ // add item to sort arrays too
+ $_names[] = strtolower($_name);
+ $_weights[] = $_weight;
+ }
+
+ // sort results array by weight and name, then return.
+ array_multisort($_weights, SORT_ASC, SORT_NUMERIC,
+ $_names, SORT_ASC, SORT_STRING, $catlist);
+ // TODO: Use memcache here?
+ $this->navCategories = $catlist; // cache result for subsequent calls
+ return $catlist;
+ }
+}
+?>
diff --git a/site/app/controllers/components/audit.php b/site/app/controllers/components/audit.php
new file mode 100644
index 0000000..2a2d0b3
--- /dev/null
+++ b/site/app/controllers/components/audit.php
@@ -0,0 +1,332 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * Justin Scott <fligtar@gmail.com>.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+class AuditComponent extends Object {
+ var $controller;
+
+ /**
+ * Save a reference to the controller on startup
+ * @param object &$controller the controller using this component
+ */
+ function startup(&$controller) {
+ $this->controller =& $controller;
+ }
+
+ /**
+ * Helper for creating an HTML link.
+ */
+ function link($title, $url) {
+ return "<a href=\"{$this->controller->url($url)}\">{$title}</a>";
+ }
+
+ /**
+ * Helper for creating a link where the title is the end of the URL.
+ * NOTE: $urlBase should have a trailing slash.
+ */
+ function linkTitle($id, $urlBase) {
+ return $this->link($id, $urlBase.$id);
+ }
+
+ function explainLog($logs) {
+ $newLog = array();
+
+ if (!empty($logs)) {
+ foreach ($logs as $log) {
+ $userInfo = $this->controller->User->findById($log['Eventlog']['user_id'], null, null, -1);
+ $user = $this->link($userInfo['User']['firstname'].' '.$userInfo['User']['lastname'], '/users/info/'.$log['Eventlog']['user_id']);
+
+ switch ($log['Eventlog']['type']) {
+ case 'admin':
+ switch ($log['Eventlog']['action']) {
+ case 'addon_status':
+ $status = $this->controller->Amo->getApprovalStatus($log['Eventlog']['added']);
+ $addonInfo = $this->controller->Addon->findById($log['Eventlog']['changed_id'], null, null, -1);
+ $addon = $this->link($addonInfo['Translation']['name']['string'], '/admin/addons/status/'.$log['Eventlog']['changed_id']);
+
+ $entry = sprintf(___('audit_addon_status'), $user, $addon, $status);
+ break;
+
+ case 'file_recalchash':
+ $entry = sprintf(___('audit_file_recalchash'), $user, $log['Eventlog']['changed_id']);
+ break;
+
+ case 'application_create':
+ case 'application_edit':
+ $applicationInfo = $this->controller->Application->findById($log['Eventlog']['changed_id'], null, null, -1);
+ $application = $this->link($applicationInfo['Translation']['name']['string'], '/admin/applications');
+
+ if ($log['Eventlog']['action'] == 'application_create') {
+ $entry = sprintf(___('audit_application_create'), $user, $application);
+ }
+ elseif ($log['Eventlog']['action'] == 'application_edit') {
+ $entry = sprintf(___('audit_application_edit'), $user, $application);
+ }
+ break;
+
+ case 'appversion_create':
+ case 'appversion_delete':
+ $applicationInfo = $this->controller->Application->findById($log['Eventlog']['notes'], null, null, -1);
+ $application = $this->link($applicationInfo['Translation']['name']['string'], '/admin/applications');
+
+ if ($log['Eventlog']['action'] == 'appversion_create') {
+ $entry = sprintf(___('audit_appversion_create'), $user, $log['Eventlog']['added'], $application);
+ }
+ elseif ($log['Eventlog']['action'] == 'appversion_delete') {
+ $entry = sprintf(___('audit_appversion_delete'), $user, $log['Eventlog']['removed'], $application);
+ }
+ break;
+
+ case 'tag_create':
+ case 'tag_edit':
+ $tagInfo = $this->controller->Tag->findById($log['Eventlog']['changed_id'], null, null, -1);
+ $tag = $this->link($tagInfo['Translation']['name']['string'], '/admin/tags');
+
+ if ($log['Eventlog']['action'] == 'tag_create') {
+ $entry = sprintf(___('audit_tag_create'), $user, $tag);
+ }
+ elseif ($log['Eventlog']['action'] == 'tag_edit') {
+ $entry = sprintf(___('audit_tag_edit'), $user, $tag);
+ }
+ break;
+
+ case 'tag_delete':
+ $entry = sprintf(___('audit_tag_delete'), $user, $log['Eventlog']['removed'], $log['Eventlog']['changed_id']);
+ break;
+
+ case 'platform_create':
+ case 'platform_edit':
+ $platformInfo = $this->controller->Platform->findById($log['Eventlog']['changed_id'], null, null, -1);
+ $platform = $this->link($platformInfo['Translation']['name']['string'], '/admin/platforms');
+
+ if ($log['Eventlog']['action'] == 'platform_create') {
+ $entry = sprintf(___('audit_platform_create'), $user, $platform);
+ }
+ elseif ($log['Eventlog']['action'] == 'platform_edit') {
+ $entry = sprintf(___('audit_platform_edit'), $user, $platform);
+ }
+ break;
+
+ case 'platform_delete':
+ $entry = sprintf(___('audit_platform_delete'), $user, $log['Eventlog']['removed'], $log['Eventlog']['changed_id']);
+ break;
+
+ case 'feature_add':
+ case 'feature_edit':
+ $featureInfo = $this->controller->Feature->findById($log['Eventlog']['changed_id'], null, null, -1);
+ $entry = sprintf(___('audit_feature_edit'), $user, $featureInfo['Feature']['locale']);
+ break;
+
+ case 'feature_remove':
+ $entry = sprintf(___('audit_admin_feature_remove'), $user, $log['Eventlog']['removed']);
+ break;
+
+ case 'group_create':
+ case 'group_edit':
+ $groupInfo = $this->controller->Group->findById($log['Eventlog']['changed_id'], null, null, -1);
+ $group = $this->link($groupInfo['Group']['name'], '/admin/groups');
+
+ if ($log['Eventlog']['action'] == 'group_create') {
+ $entry = sprintf(___('audit_group_create'), $user, $group);
+ }
+ elseif ($log['Eventlog']['action'] == 'group_edit') {
+ $entry = sprintf(___('audit_group_edit'), $user, $group);
+ }
+ break;
+
+ case 'group_delete':
+ $entry = sprintf(___('audit_group_delete'), $user, $log['Eventlog']['removed'], $log['Eventlog']['changed_id']);
+ break;
+
+ case 'group_addmember':
+ case 'group_removemember':
+ $groupInfo = $this->controller->Group->findById($log['Eventlog']['changed_id'], null, null, -1);
+ $group = $this->link($groupInfo['Group']['name'], '/admin/groups');
+
+ if ($log['Eventlog']['action'] == 'group_addmember') {
+ $memberInfo = $this->controller->User->findById($log['Eventlog']['added'], null, null, -1);
+ $member = $this->link($memberInfo['User']['firstname'].' '.$memberInfo['User']['lastname'], '/admin/users/'.$log['Eventlog']['added']);
+
+ $entry = sprintf(___('audit_group_addmember'), $user, $member, $group);
+ }
+ elseif ($log['Eventlog']['action'] == 'group_removemember') {
+ $memberInfo = $this->controller->User->findById($log['Eventlog']['removed'], null, null, -1);
+ $member = $this->link($memberInfo['User']['firstname'].' '.$memberInfo['User']['lastname'], '/admin/users/'.$log['Eventlog']['removed']);
+
+ $entry = sprintf(___('audit_group_removemember'), $user, $member, $group);
+ }
+ break;
+
+ case 'response_create':
+ case 'response_edit':
+ $responseInfo = $this->controller->Cannedresponse->findById($log['Eventlog']['changed_id'], null, null, -1);
+ $response = $this->link($responseInfo['Translation']['name']['string'], '/admin/responses');
+
+ if ($log['Eventlog']['action'] == 'response_create') {
+ $entry = sprintf(___('audit_response_create'), $user, $response);
+ }
+ elseif ($log['Eventlog']['action'] == 'response_edit') {
+ $entry = sprintf(___('audit_response_edit'), $user, $response);
+ }
+ break;
+
+ case 'response_delete':
+ $entry = sprintf(___('audit_response_delete'), $user, $log['Eventlog']['removed'], $log['Eventlog']['changed_id']);
+ break;
+
+ case 'config':
+ $entry = sprintf(___('audit_config'), $user, $log['Eventlog']['field'], $log['Eventlog']['removed'], $log['Eventlog']['added']);
+ break;
+
+ case 'user_edit':
+ $userInfo = $this->controller->User->findById($log['Eventlog']['changed_id'], null, null, -1);
+ $userLink = $this->link($userInfo['User']['firstname'].' '.$userInfo['User']['lastname'], '/admin/users/'.$log['Eventlog']['changed_id']);
+
+ $entry = sprintf(___('audit_user_edit'), $user, $userLink);
+ break;
+
+ default:
+ $entry = sprintf(___('audit_admin_default'), $user, $log['Eventlog']['action'], $log['Eventlog']['changed_id']);
+ break;
+ }
+ break;
+
+ case 'editor':
+
+ switch ($log['Eventlog']['action']) {
+ case 'feature_add':
+ $addonLink = $this->linkTitle($log['Eventlog']['added'], '/addon/');
+ $entry = sprintf(___('audit_feature_add'), $user, $addonLink);
+ break;
+
+ case 'feature_remove':
+ $addonLink = $this->linkTitle($log['Eventlog']['removed'], '/addon/');
+ $entry = sprintf(___('audit_editor_feature_remove'), $user, $addonLink);
+ break;
+
+ case 'feature_locale_change':
+ $addonLink = $this->linkTitle($log['Eventlog']['changed_id'], '/addon/');
+ $entry = sprintf(___('audit_feature_locale_change'), $user, $addonLink);
+ break;
+
+ case 'review_approve':
+ $entry = sprintf(___('audit_review_approve'), $user, $log['Eventlog']['changed_id']);
+ break;
+
+ case 'review_delete':
+ if ($this->controller->SimpleAcl->actionAllowed('Admin', 'logs', $this->controller->Session->read('User'))) {
+ $entry = sprintf(___('audit_review_delete'), $user, $this->link($log['Eventlog']['changed_id'], "/admin/logs/{$log['Eventlog']['id']}"));
+ }
+ else {
+ $entry = sprintf(___('audit_review_delete'), $user, $log['Eventlog']['changed_id']);
+ }
+ break;
+
+ default:
+ $entry = sprintf(___('audit_editor_default'), $user, $log['Eventlog']['action'], $log['Eventlog']['changed_id']);
+ break;
+ }
+ break;
+
+ case 'l10n':
+ switch ($log['Eventlog']['action']) {
+ case 'update_applications':
+ $entry = sprintf(___('audit_update_applications'), $user, $this->linkTitle($log['Eventlog']['notes'], "/localizers/applications/?userlang="));
+ break;
+
+ case 'update_tags':
+ $entry = sprintf(___('audit_update_tags'), $user, $this->linkTitle($log['Eventlog']['notes'], "/localizers/tags/?userlang="));
+ break;
+
+ case 'update_platforms':
+ $entry = sprintf(___('audit_update_platforms'), $user, $this->linkTitle($log['Eventlog']['notes'], "/localizers/platforms/?userlang="));
+ break;
+ case 'update_blog':
+ $entry = sprintf(___('audit_update_blog'), $user, $this->linkTitle($log['Eventlog']['notes'], "/localizers/platforms/?userlang="));
+ break;
+ default:
+ $entry = sprintf(___('audit_l10n_default'), $user, $log['Eventlog']['action'], $log['Eventlog']['notes']);
+ break;
+ }
+ break;
+
+ case 'security':
+ switch ($log['Eventlog']['action']) {
+ case 'reauthentication_failure':
+ $entry = sprintf(___('audit_reauthentication_failure'), $user, $log['Eventlog']['notes']);
+ break;
+
+ case 'modify_locked_group':
+ $groupInfo = $this->controller->Group->findById($log['Eventlog']['changed_id'], null, null, -1);
+ $group = $this->link($groupInfo['Group']['name'], '/admin/groups');
+
+ $entry = sprintf(___('audit_modify_locked_group'), $user, $group);
+ break;
+
+ case 'modify_other_locale':
+ $entry = sprintf(___('audit_modify_other_locale'), $user, $log['Eventlog']['notes']);
+ break;
+
+ default:
+ $entry = sprintf(___('audit_security_default'), $user, $log['Eventlog']['action'], $log['Eventlog']['changed_id']);
+ break;
+ }
+ break;
+
+ case 'user':
+ switch ($log['Eventlog']['action']) {
+ case 'group_associated':
+ $groupInfo = $this->controller->Group->findById($log['Eventlog']['changed_id'], null, null, -1);
+ $group = $this->link($groupInfo['Group']['name'], '/admin/groups');
+ $entry = sprintf(___('audit_group_associated'), $user, $group);
+ break;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ $newLog[] = array(
+ 'time' => $log['Eventlog']['created'],
+ 'entry' => $entry
+ );
+ }
+ }
+
+ return $newLog;
+ }
+}
+?>
diff --git a/site/app/controllers/components/collections_listing.php b/site/app/controllers/components/collections_listing.php
new file mode 100644
index 0000000..75c68a3
--- /dev/null
+++ b/site/app/controllers/components/collections_listing.php
@@ -0,0 +1,102 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Ryan Doherty <rdoherty@mozilla.com>
+ * Frederic Wenzel <fwenzel@mozilla.com>
+ * Jeff Balogh <jbalogh@mozilla.com>
+ * Scott McCammon <smccammon@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+class CollectionsListingComponent extends Object {
+
+ var $controller;
+
+ /**
+ * Save a reference to the controller on startup
+ * @param object &$controller the controller using this component
+ */
+ function startup(&$controller) {
+ $this->controller =& $controller;
+ }
+
+ /**
+ * Get localized sort options and current sort
+ * @return array array(sortOptionsArray, sortBy)
+ */
+ function sorting() {
+ $sort_default = 'weekly';
+ $sort_opts = array(
+ 'weekly' => array(
+ 'text' => ___('collections_index_option_week'),
+ 'sort' => 'weekly_subscribers'),
+ 'monthly' => array(
+ 'text' => ___('collections_index_option_month'),
+ 'sort' => 'monthly_subscribers'),
+ 'all' => array(
+ 'text' => ___('collections_index_option_all'),
+ 'sort' => 'subscribers'),
+ 'newest' => array(
+ 'text' => ___('collections_index_option_newest'),
+ 'sort' => 'created'),
+ );
+ $sortby = isset($_GET['sortby']) ? $_GET['sortby'] : $sort_default;
+ if (!array_key_exists($sortby, $sort_opts))
+ $sortby = $sort_default;
+ return array($sort_opts, $sortby);
+ }
+
+ /**
+ * Fetch a sorted page of collections
+ * @param array $ids array of collection ids
+ * @param array array of pagination options
+ * @return array Collections query result
+ */
+ function fetchPage($ids, $pagination_options=array()) {
+ $conditions = array('Collection.listed' => '1',
+ 'Collection.id' => $ids);
+
+ list($sort_opts, $sortby) = $this->sorting();
+
+ $opts = array_merge(array('show' => 7, 'modelClass' => 'Collection'),
+ $pagination_options);
+ $opts['sortBy'] = $sort_opts[$sortby]['sort'] . ' DESC';
+
+ list($order, $limit, $page) = $this->controller->Pagination->init($conditions, array(), $opts);
+ $this->controller->Collection->bindOnly('Users');
+
+ return $this->controller->Collection->findAll($conditions, null, $order, $limit, $page);
+ }
+
+}
diff --git a/site/app/controllers/components/developers.php b/site/app/controllers/components/developers.php
new file mode 100644
index 0000000..15ae6b8
--- /dev/null
+++ b/site/app/controllers/components/developers.php
@@ -0,0 +1,1251 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * Justin Scott <fligtar@gmail.com>.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Frederic Wenzel <fwenzel@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+class DevelopersComponent extends Object {
+ var $controller;
+ var $imageExtensions = array('.png', '.jpg', '.gif');
+
+ /**
+ * Save a reference to the controller on startup
+ * @param object &$controller the controller using this component
+ */
+ function startup(&$controller) {
+ $this->controller =& $controller;
+ }
+
+ /**
+ * Make sure at least one but no more than 5 tags selected
+ * @param array $tags post data of selected tags
+ */
+ function validateTags($tags) {
+ $errors =& $this->controller->Error;
+
+ //Must have at least one tag selected, but no more than 5
+ if (empty($tags)) {
+ $errors->addError(_('devcp_error_one_category'), 'Tag/Tag');
+ $this->controller->Tag->invalidate('Tag');
+ return false;
+ }
+ elseif (count($tags) > 5) {
+ $errors->addError(_('devcp_error_five_categories'), 'Tag/Tag');
+ $this->controller->Tag->invalidate('Tag');
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Remove duplicates and make sure at least one user selected
+ * @param array &$users post data of selected users
+ */
+ function validateUsers(&$users) {
+ $errors =& $this->controller->Error;
+
+ //Remove deleted and duplicate entries from authors
+ $authors = array();
+ if (!empty($users)) {
+ foreach($users as $user) {
+ if ($user != "" && !in_array($user, $authors)) {
+ $authors[] = $user;
+ }
+ }
+ }
+ $users = $authors;
+
+ //Make sure there is at least one author
+ if (empty($users)) {
+ $errors->addError(_('devcp_error_one_user'), 'User/User');
+ $this->controller->User->invalidate('User');
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Save users to addons_users table. For some reason, Cake refuses to save
+ * this properly the normal way.
+ * @param array $users The users
+ */
+ function saveUsers($users) {
+ $this->controller->User->execute("DELETE FROM addons_users WHERE addon_id={$this->controller->Addon->id}");
+
+ if (!empty($users)) {
+ foreach ($users as $user) {
+ $this->controller->User->execute("INSERT INTO addons_users (addon_id, user_id) VALUES({$this->controller->Addon->id}, {$user})");
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * Get all tags for an addontype
+ * @param int $addontypeId the addontype ID
+ * @param array $applicationIds the ids of supported applications
+ * @return array $tags the tags
+ */
+ function getTags($addontypeId, $applicationIds) {
+ //Get tags based on addontype
+ $applicationIdQry = !empty($applicationIds) ? "Tag.application_id IN (".implode(', ', $applicationIds).") OR" : '';
+
+ // Override for search engines. They have no application restrictions (bug 417727)
+ if ($addontypeId == ADDON_SEARCH) {
+ $applicationIdQry = 'Tag.application_id IS NOT NULL OR';
+ }
+
+ $tagsQry = $this->controller->Tag->findAll("Tag.addontype_id='{$addontypeId}' AND ({$applicationIdQry} Tag.application_id IS NULL)");
+
+ if ($tagsQry) {
+ // show (APP) behind name?
+ $add_apps = (is_array($applicationIds) && count($applicationIds)>1);
+ if ($add_apps) {
+ global $app_shortnames, $app_prettynames;
+ $appnames = array();
+ foreach($applicationIds as $app) {
+ $sn = array_search($app,$app_shortnames);
+ if ($sn!==false)
+ $appnames[$app] = $app_prettynames[$sn];
+ }
+ }
+
+ foreach ($tagsQry as $k => $v) {
+ $tags['names'][$v['Tag']['id']] = $v['Translation']['name']['string'];
+ if ($add_apps && !is_null($v['Tag']['application_id']))
+ $tags['names'][$v['Tag']['id']] .= " ({$appnames[$v['Tag']['application_id']]})";
+ $tags['descriptions'][] = $v['Tag']['id'].': "'.addslashes($v['Translation']['description']['string']).'"';
+ }
+ }
+
+ if (!empty($tags)) {
+ asort($tags['names']);
+ return $tags;
+ }
+
+ return array();
+ }
+
+ /**
+ * Get all selected tags in order of post data, existing data, default
+ * @param array $currentTags currently selected tags
+ * @return array $selectedTags the selected tags
+ */
+ function getSelectedTags($currentTags) {
+ //post data
+ if (!empty($this->controller->data['Tag']['Tag'])) {
+ foreach($this->controller->data['Tag']['Tag'] as $tag) {
+ $selectedTags[] = $tag;
+ }
+ }
+ //current data
+ elseif (!empty($currentTags)) {
+ foreach ($currentTags as $tag) {
+ $selectedTags[] = $tag['id'];
+ }
+ }
+ //default data
+ else {
+ $selectedTags = array();
+ }
+
+ return $selectedTags;
+ }
+
+ /**
+ * Get authors in order of post data, existing data, default
+ * @param array $currentUsers currently selected users
+ * @param boolean $defaultToSession whether to default to current user
+ * @return array $authors the authors
+ */
+ function getAuthors($currentUsers, $defaultToSession = true) {
+ //post data
+ if (!empty($this->controller->data['User']['User']) && !in_array('0', $this->controller->data['User']['User'])) {
+ foreach($this->controller->data['User']['User'] as $user) {
+ if ($user != "") {
+ $this->controller->User->id = $user;
+ $userinfo = $this->controller->User->read();
+ $authors[$user] = $userinfo['User']['firstname'].' '.$userinfo['User']['lastname'].' ['.$userinfo['User']['email'].']';
+ }
+ }
+ }
+ //current users
+ elseif (!empty($currentUsers)) {
+ foreach ($currentUsers as $user) {
+ $authors[$user['id']] = $user['firstname'].' '.$user['lastname'].' ['.$user['email'].']';
+ }
+ }
+ //default to logged in
+ elseif ($defaultToSession == true) {
+ //default to current user
+ $session = $this->controller->Session->read('User');
+ $authors[$session['id']] = $session['firstname'].' '.$session['lastname'].' ['.$session['email'].']';
+ }
+ //default to empty
+ else {
+ $authors = array();
+ }
+
+ return $authors;
+ }
+
+ /**
+ * Detect addontype based on file information
+ * @param array $file array of PHP file info
+ * @return int addontype id
+ */
+ function detectAddontype($file) {
+ $extension = substr($file['name'], strrpos($file['name'], '.'));
+ switch ($extension) {
+ case '.xpi':
+ // Dictionaries have a .dic file in the dictionaries directory
+ $zip = new Archive_Zip($file['tmp_name']);
+ $dicFile = $zip->extract(array('extract_as_string' => true, 'by_preg' => "/dictionaries\/.+\.dic/i"));
+
+ // if the .dic file is present, it is a dictionary, otherwise it's an extension
+ if (count($dicFile) > 0) {
+ return ADDON_DICT;
+ }
+ else {
+ return ADDON_EXTENSION;
+ }
+ break;
+
+ case '.jar':
+ return ADDON_THEME;
+ break;
+
+ case '.xml':
+ return ADDON_SEARCH;
+ break;
+
+ default:
+ return 0;
+ break;
+ }
+ }
+
+ /**
+ * Validate the uploaded files
+ * @deprecated
+ */
+ function validateFiles() {
+ $errors =& $this->controller->Error;
+
+ //Make sure the first file was uploaded
+ if (empty($this->controller->data['File']['file1']['name'])) {
+ $errors->addError(_('devcp_error_upload_file'), 'File/file1');
+ $this->controller->File->invalidate('file1');
+ return false;
+ }
+
+ $errorCount = 0;
+
+ //Loop through the files
+ for ($f = 1; $f <= 4; $f++) {
+ $file = (!empty($this->controller->data['File']['file'.$f])) ? $this->controller->data['File']['file'.$f] : array();
+
+ if (!empty($file['name'])) {
+ //File 4 is the icon file
+ if ($f != 4) {
+ //Make sure platform selected
+ if (empty($this->controller->data['File']['platform_id'.$f])) {
+ $errors->addError(_('devcp_error_no_platform'), 'File/platform_id'.$f);
+ $this->controller->File->invalidate('platform_id'.$f);
+ $errorCount++;
+ }
+
+ //Validate the file
+ $files[$f] = $this->validateFile($this->controller->data['File']['file'.$f], $this->controller->data);
+ }
+ else {
+ //Validate the image
+ $files[$f] = $this->validateIcon($this->controller->data['File']['file'.$f]);
+ }
+
+ //If an array is not returned, an error occurred
+ if (!is_array($files[$f])) {
+ $errors->addError($files[$f], 'File/file'.$f);
+ $this->controller->File->invalidate('file'.$f);
+ $errorCount++;
+ }
+ else {
+ if ($f != 4) {
+ $files[$f]['platform_id'] = $this->controller->data['File']['platform_id'.$f];
+ }
+ }
+ }
+ }
+
+ //Collect all file errors before returning
+ if ($errorCount > 0) {
+ return false;
+ }
+ else {
+ foreach ($files as $f => $fileInfo) {
+ $this->controller->addVars['file'.$f] = $fileInfo;
+ }
+ return true;
+ }
+ }
+
+ /**
+ * Validate a file for basic problems with the upload
+ * @param array $file PHP info on the file
+ * @param array $addon data already saved about the add-on
+ * @return array if no errors
+ * @return string if error
+ */
+ function validateFile($file, $addon) {
+ $uploadErrors = array(
+ '1' => _('devcp_error_http_maxupload'),
+ '2' => _('devcp_error_http_maxupload'),
+ '3' => _('devcp_error_http_incomplete'),
+ '4' => _('devcp_error_http_nofile')
+ );
+ $allowedExtensions = $this->getAllowedExtensions($addon['Addon']['addontype_id']);
+
+ // Check for file upload errors
+ if (!empty($file['error'])) {
+ return $uploadErrors[$file['error']];
+ }
+
+ // Set file properties to be used later
+ $fileInfo['filename'] = $file['name'];
+ $fileInfo['size'] = round($file['size']/1024, 0); // in KB
+ $fileInfo['extension'] = substr($file['name'], strrpos($file['name'], '.'));
+ $fileInfo['hash'] = 'sha256:'.hash_file("sha256", $file['tmp_name']);
+
+ // Check for file extension match
+ if (!in_array(strtolower($fileInfo['extension']), $allowedExtensions)) {
+ return sprintf(_('devcp_error_file_extension'), $fileInfo['extension'], implode(', ', $allowedExtensions));
+ }
+
+ // Move temporary file to repository
+ $uploadedFile = $this->controller->Amo->unclean($file['tmp_name']);
+ $tempLocation = REPO_PATH.'/temp/'.$fileInfo['filename'];
+
+ // Make sure file doesn't overwrite anything
+ if (file_exists($tempLocation)) {
+ $fileInfo['filename'] = str_replace('0.', '', microtime()).$fileInfo['extension'];
+ $tempLocation = REPO_PATH.'/temp/'.$fileInfo['filename'];
+ }
+
+ if (move_uploaded_file($uploadedFile, $tempLocation)) {
+ chmod($tempLocation, 0644);
+ $fileInfo['path'] = $tempLocation;
+ }
+ else {
+ return _('devcp_error_move_file');
+ }
+
+ return $fileInfo;
+ }
+
+ /**
+ * Validate the icon file
+ * @param array $file the icon file array
+ * @param array $fileErrors the HTTP file error associations
+ * @param array $allowedExtensions allowed file extensions
+ */
+ function validateIcon($icon) {
+ $uploadErrors = array(
+ '1' => _('devcp_error_http_maxupload'),
+ '2' => _('devcp_error_http_maxupload'),
+ '3' => _('devcp_error_http_incomplete'),
+ '4' => _('devcp_error_http_nofile')
+ );
+
+ // Check for file upload errors
+ if (!empty($icon['error'])) {
+ return $uploadErrors[$icon['error']];
+ }
+
+ // Check for file extension match
+ $extension = substr($icon['name'], strrpos($icon['name'], '.'));
+ if (!in_array(strtolower($extension), $this->imageExtensions)) {
+ return sprintf(_('devcp_error_icon_extension'), $extension, implode(', ', $this->imageExtensions));
+ }
+
+ $fileInfo['icondata'] = file_get_contents($icon['tmp_name']);
+ $fileInfo['icontype'] = $icon['type'];
+
+ // Get icon size
+ list($sourceWidth, $sourceHeight) = getimagesize($icon['tmp_name']);
+
+ // Resize to 32x32
+ $fileInfo['icondata'] = $this->resizeImage($fileInfo['icondata'], $sourceWidth, $sourceHeight, 32, 32);
+
+ return $fileInfo;
+ }
+
+ /**
+ * Resizes an image to specified size
+ * @param string $sourceData the image data
+ * @param int $sourceWidth original width
+ * @param int $sourceHeight original height
+ * @param int $newWidth width of the new image
+ * @param int $newHeight height of the new image
+ * @return string new image data
+ */
+ function resizeImage($sourceData, $sourceWidth, $sourceHeight, $newWidth = 200, $newHeight = 150) {
+ $sourceImage = imagecreatefromstring($sourceData);
+ imagesavealpha($sourceImage, true);
+
+ // Determine width/height aspect ratio
+ $sourceRatio = $sourceWidth / $sourceHeight;
+ $newRatio = $newWidth / $newHeight;
+
+ if ($newRatio > $sourceRatio) {
+ $newWidth = $newHeight * $sourceRatio;
+ }
+ else {
+ $newHeight = $newWidth / $sourceRatio;
+ }
+
+ // Only make image smaller, not larger
+ if ($newWidth >= $sourceWidth && $newHeight >= $sourceHeight) {
+ $newImage = $sourceImage;
+ } else {
+ $newImage = imagecreatetruecolor($newWidth, $newHeight);
+
+ // Make a new transparent image and turn off alpha blending to keep the alpha channel
+ $background = imagecolorallocatealpha($newImage, 255, 255, 255, 127);
+ imagecolortransparent($newImage, $background);
+ imagealphablending($newImage, false);
+ imagesavealpha($newImage, true);
+
+ imagecopyresampled($newImage, $sourceImage, 0, 0, 0, 0, $newWidth, $newHeight, $sourceWidth, $sourceHeight);
+ }
+
+ // Output new image to buffer to save and clear it
+ ob_start();
+ imagepng($newImage);
+ $newData = ob_get_contents();
+ ob_end_clean();
+
+ @imagedestroy($sourceImage);
+ @imagedestroy($newImage);
+
+ return $newData;
+ }
+
+ /**
+ * Get allowed file extensions based on addontype
+ * @param int $addontype the addontype
+ * @return array $allowed allowed extensions
+ */
+ function getAllowedExtensions($addontype) {
+ switch ($addontype) {
+ case ADDON_EXTENSION: $allowed = array('.xpi');
+ break;
+ case ADDON_THEME: $allowed = array('.jar', '.xpi');
+ break;
+ case ADDON_DICT: $allowed = array('.xpi');
+ break;
+ case ADDON_SEARCH: $allowed = array('.xml');
+ break;
+ case ADDON_LPAPP: $allowed = array('.xpi');
+ break;
+ case ADDON_LPADDON: $allowed = array('.xpi');
+ break;
+ default: $allowed = array();
+ break;
+ }
+ return $allowed;
+ }
+
+ /**
+ * Validate the install.rdf manifest data
+ * @param array $manifestData the manifest contents
+ * @return string if error
+ * @return boolean true if no error
+ */
+ function validateManifestData($manifestData) {
+ // If the data is a string, it is an error message
+ if (is_string($manifestData)) {
+ return sprintf(_('devcp_error_manifest_parse'), $manifestData);
+ }
+
+ // Check if install.rdf has an updateURL
+ if (isset($manifestData['updateURL'])) {
+ return _('devcp_error_updateurl');
+ }
+
+ // Check if install.rdf has an updateKey
+ if (isset($manifestData['updateKey'])) {
+ return _('devcp_error_updatekey');
+ }
+
+ // Check the GUID for existence
+ if (!isset($manifestData['id'])) {
+ return _('devcp_error_no_guid');
+ }
+
+ // Validate GUID
+ if (!preg_match('/^(\{[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\}|[a-z0-9-\._]*\@[a-z0-9-\._]+)$/i', $manifestData['id'])) {
+ return sprintf(_('devcp_error_invalid_guid'), $manifestData['id']);
+ }
+
+ // Make sure GUID is not an application's GUID
+ if ($this->controller->Application->findByGuid($manifestData['id'])) {
+ return _('devcp_error_guid_application');
+ }
+
+ // Make sure version has no spaces
+ if (!isset($manifestData['version']) || preg_match('/.*\s.*/', $manifestData['version'])) {
+ return _('devcp_error_invalid_version_spaces');
+ }
+
+ // Validate version
+ if (!preg_match('/^\d+(\+|\w+)?(\.\d+(\+|\w+)?)*$/', $manifestData['version'])) {
+ return _('devcp_error_invalid_version');
+ }
+
+ return true;
+ }
+
+ /**
+ * Validate the target applications
+ * @param array $targetApps the targetApps from install.rdf
+ * @return string if error
+ * @return array if no errors
+ */
+ function validateTargetApplications($targetApps) {
+ $noMozApps = true;
+ $versionErrors = array();
+
+ if (count($targetApps) > 0) {
+ $i = 0;
+
+ // Iterate through each target app and find it in the DB
+ foreach ($targetApps as $appKey => $appVal) {
+ if ($matchingApp = $this->controller->Application->find(array('guid' => $appKey), null, null, -1)) {
+ $return[$i]['application_id'] = $matchingApp['Application']['id'];
+
+ // Mark as Moz-app if supported
+ if ($matchingApp['Application']['supported'] == 1) {
+ $noMozApps = false;
+ }
+
+ // Check if the minVersion is valid
+ $matchingMinVers = $this->controller->Appversion->find("application_id={$matchingApp['Application']['id']} AND version='{$appVal['minVersion']}'", null, null, -1);
+
+ if (empty($matchingMinVers)) {
+ $versionErrors[] = sprintf(_('devcp_error_invalid_appversion'), $appVal['minVersion'], $matchingApp['Translation']['name']['string']);
+ }
+ elseif (strpos($appVal['minVersion'], '*') !== false) {
+ $versionErrors[] = sprintf(_('devcp_error_invalid_minversion'), $appVal['minVersion'], $matchingApp['Translation']['name']['string']);
+ }
+ else {
+ $return[$i]['min'] = $matchingMinVers['Appversion']['id'];
+ }
+
+ // Check if the maxVersion is valid
+ $matchingMaxVers = $this->controller->Appversion->find("application_id={$matchingApp['Application']['id']} AND version='{$appVal['maxVersion']}'", null, null, -1);
+ if (empty($matchingMaxVers)) {
+ $versionErrors[] = sprintf(_('devcp_error_invalid_appversion'), $appVal['maxVersion'], $matchingApp['Translation']['name']['string']);
+ }
+ else {
+ $return[$i]['max'] = $matchingMaxVers['Appversion']['id'];
+ }
+ $i++;
+ }
+ }
+ }
+
+ $validAppReference = sprintf(_('devcp_error_appversion_reference_link'), '<a href="'.$this->controller->url('/pages/appversions').'">'._('devcp_error_appversion_reference_link_text').'</a>');
+
+ // Must have at least one Mozilla app
+ if ($noMozApps === true) {
+ return _('devcp_error_mozilla_application').'<br />'.$validAppReference;
+ }
+
+ // Max/min version errors
+ if (count($versionErrors) > 0) {
+ $errorStr = implode($versionErrors, '<br />');
+ return _('devcp_error_install_manifest').'<br />'.$errorStr.'<br />'.$validAppReference;
+ }
+
+ return $return;
+ }
+
+ /**
+ * Renames and moves a file out of temp repository
+ * @param array $data array of data in model format
+ */
+ function moveFile($data) {
+ $fileUpdates = array();
+ $applications = $this->controller->Application->getShortNames();
+ $platforms = $this->controller->Platform->getShortNames();
+
+ // Construct new filename with name, version, supported apps, and OS
+ $filename = preg_replace(INVALID_FILENAME_CHARS, '_', $data['Addon']['name']);
+
+ $filename .= '-'.$data['Version']['version'];
+
+ if ($data['Addon']['addontype_id'] != ADDON_SEARCH) {
+ $filename .= '-';
+ $appString = '';
+ foreach ($data['appversions'] as $appversion) {
+ if ($appString != "") {
+ $appString .= '+'.$applications[$appversion['application_id']];
+ }
+ else {
+ $appString = $applications[$appversion['application_id']];
+ }
+ }
+ $filename .= $appString;
+
+ if ($data['File']['db']['platform_id'] != PLATFORM_ALL) {
+ $filename .= '-'.$platforms[$data['File']['db']['platform_id']];
+ }
+ }
+
+ $filename .= $data['File']['details']['extension'];
+ $filename = strtolower($filename);
+
+ // File paths
+ $currentPath = $data['File']['details']['path'];
+ $dirPath = REPO_PATH.'/'.$data['Addon']['id'];
+ $newPath = $dirPath.'/'.$filename;
+
+ // Create directory if necessary
+ if (!file_exists($dirPath)) {
+ if (!mkdir($dirPath)) {
+ return sprintf(_('devcp_error_moving_file'), $data['File']['db']['filename']);
+ }
+ }
+
+ // Move file
+ if (file_exists($currentPath)) {
+ // Bail if the file exists. See bug 470652 for a rough explanation
+ if (file_exists($newPath)) {
+ return sprintf(___('devcp_error_file_exists'), $filename);
+ }
+ // We must copy instead of rename now in case there are other platforms
+ if (!copy($currentPath, $newPath)) {
+ return sprintf(_('devcp_error_moving_file'), $data['File']['db']['filename']);
+ }
+ $fileUpdates['filename'] = $filename;
+ }
+ else {
+ return sprintf(_('devcp_error_moving_file'), $data['File']['db']['filename']);
+ }
+
+ // Copy file to rsync area if public
+ if ($data['File']['db']['status'] == STATUS_PUBLIC) {
+ $this->controller->Amo->copyFileToPublic($data['Addon']['id'], $filename);
+ }
+
+ return $fileUpdates;
+ }
+
+ /**
+ * Create new file name and move files from temp to approval
+ * @param array $version version information
+ * @deprecated since 3.5
+ */
+ function moveFiles($version, $addontype_id) {
+ $errors =& $this->controller->Error;
+ $fileUpdates = array();
+ $applications = $this->controller->Amo->getApplicationName(null, true);
+ $this->controller->Addon->id = $version['Version']['addon_id'];
+ $addon = $this->controller->Addon->read();
+
+ // Construct new filename with name, version, supported apps, and OS
+ $baseFilename = preg_replace(INVALID_FILENAME_CHARS, '_', $addon['Translation']['name']['string']);
+
+ if ($addontype_id != ADDON_SEARCH) {
+ $baseFilename .= '-'.$version['Version']['version'].'-';
+ $appString = '';
+ foreach ($version['Application'] as $app) {
+ if ($appString != "") {
+ $appString .= '+'.$applications[$app['id']]['shortname'];
+ }
+ else {
+ $appString = $applications[$app['id']]['shortname'];
+ }
+ }
+ $baseFilename .= $appString;
+
+ //Get platforms with shortnames
+ $platforms = $this->controller->Amo->getPlatformName('', true);
+ }
+
+ foreach ($version['File'] as $file) {
+ $newFilename = $baseFilename;
+ $extension = substr($file['filename'], strrpos($file['filename'], '.'));
+ if ($file['platform_id'] != 1 && $addontype_id != ADDON_SEARCH) {
+ $newFilename .= '-'.$platforms[$file['platform_id']]['shortname'];
+ }
+ $newFilename .= $extension;
+ $newFilename = strtolower($newFilename);
+
+ //File paths
+ $currentPath = REPO_PATH.'/temp/'.$file['filename'];
+ $dirPath = REPO_PATH.'/'.$addon['Addon']['id'];
+ $newPath = $dirPath.'/'.$newFilename;
+
+ //Create directory if necessary
+ if (!file_exists($dirPath)) {
+ if (!mkdir($dirPath)) {
+ $errors->addError(sprintf(_('devcp_error_moving_file'), $file['filename']));
+ }
+ }
+
+ //Move file
+ if (file_exists($currentPath)) {
+ //Delete file if one already exists
+ if (file_exists($newPath)) {
+ unlink($newPath);
+ }
+ if (!rename($currentPath, $newPath)) {
+ $errors->addError(sprintf(_('devcp_error_moving_file'), $file['filename']));
+ }
+ $fileUpdates[$file['id']]['filename'] = $newFilename;
+ }
+ else {
+ $errors->addError(sprintf(_('devcp_error_moving_file'), $file['filename']));
+ }
+ }
+
+ return $fileUpdates;
+ }
+
+ /**
+ * Determine if all required fields are set in order to skip reviewing add-on info
+ */
+ function noReviewRequired() {
+
+ if ($this->controller->addVars['newAddon'] == true) {
+ return false;
+ }
+ else {
+ return true;
+ }
+ }
+
+ /**
+ * To be run after a file is deleted to ensure nominated add-ons
+ * have files
+ */
+ function postDelete($addon_id) {
+ $addon = $this->controller->Addon->findById($addon_id, array('status'), null, -1);
+ $file = $this->controller->File->query("SELECT File.id FROM files AS File INNER JOIN versions as Version ON Version.id = File.version_id AND Version.addon_id = {$addon_id}");
+
+ if ($addon['Addon']['status'] == STATUS_NOMINATED && empty($file)) {
+ $addonData = array('status' => STATUS_SANDBOX);
+ $this->controller->Addon->id = $addon_id;
+ $this->controller->Addon->save($addonData);
+ }
+ }
+
+ /**
+ * Deletes a file from disk and database
+ * ENSURE USER HAS ALL NECESSARY PERMISSIONS BEFORE USING THIS METHOD
+ * @param int $file_id file id to delete
+ * @param int $addon_id add-on id the file belongs to
+ */
+ function deleteFile($file_id, $addon_id) {
+ $file = $this->controller->File->findById($file_id);
+
+ // Delete files from disk
+ $path = "/{$addon_id}/{$file['File']['filename']}";
+ if (defined('REPO_PATH') && file_exists(REPO_PATH.$path)) {
+ unlink(REPO_PATH.$path);
+ }
+ if (defined('PUBLIC_STAGING_PATH') && file_exists(PUBLIC_STAGING_PATH.$path)) {
+ unlink(PUBLIC_STAGING_PATH.$path);
+ }
+
+ // Delete approvals
+ $this->controller->File->execute("DELETE FROM approvals WHERE file_id='{$file_id}'");
+
+ // Delete file
+ $this->controller->File->execute("DELETE FROM files WHERE id='{$file_id}' LIMIT 1");
+ }
+
+ /**
+ * Deletes a version along with all dependent files, reviews, etc
+ * ENSURE USER HAS ALL NECESSARY PERMISSIONS BEFORE USING THIS METHOD
+ * @param int $version_id version id to delete
+ */
+ function deleteVersion($version_id) {
+ // Pull version info without translations
+ $this->controller->Version->translationReplace = false;
+ $version = $this->controller->Version->findById($version_id);
+ $this->controller->Version->translationReplace = true;
+
+ // Get translation ids of any translated fields of versions
+ $translation_ids = array();
+ if (!empty($this->controller->Version->translated_fields)) {
+ foreach ($this->controller->Version->translated_fields as $translatedField) {
+ if (!empty($version['Version'][$translatedField])) {
+ $translation_ids[] = $version['Version'][$translatedField];
+ }
+ }
+ }
+
+ // Delete any files
+ if (!empty($version['File'])) {
+ foreach ($version['File'] as $file) {
+ $this->deleteFile($file['id'], $version['Version']['addon_id']);
+ }
+ }
+
+ // Delete applications_versions rows
+ $this->controller->Version->execute("DELETE FROM applications_versions WHERE version_id={$version_id}");
+
+ // Delete reviews
+ $review_ids = array();
+ if (!empty($this->controller->Review->translated_fields)) {
+ foreach ($this->controller->Review->translated_fields as $translatedField) {
+ if (!empty($version['Review'])) {
+ foreach ($version['Review'] as $review) {
+ $review_ids[] = $review['id'];
+ if (!empty($review[$translatedField])) {
+ $translation_ids[] = $review[$translatedField];
+ }
+ }
+ }
+ }
+ }
+
+ if (!empty($review_ids)) {
+ foreach ($review_ids as $review_id) {
+ $this->controller->Review->execute("DELETE FROM reviewratings WHERE review_id={$review_id}");
+ $this->controller->Review->execute("DELETE FROM reviews WHERE id={$review_id}");
+ }
+ }
+
+ // Delete version
+ $this->controller->Version->execute("DELETE FROM versions WHERE id={$version_id}");
+
+ // Delete translations
+ if (!empty($translation_ids)) {
+ $this->controller->Version->execute("DELETE FROM translations WHERE id IN (".implode(',', $translation_ids).")");
+ }
+ }
+
+ /**
+ * Delete an addon, along with its versions, files, reviews, previews,
+ * favorites, features, tags, and translations
+ * @param int $id the add-on id
+ * @return boolean
+ */
+ function deleteAddon($id) {
+ //Double-check permissions
+ if (!$this->controller->Amo->checkOwnership($id)) {
+ return false;
+ }
+
+ $this->controller->Addon->id = $id;
+ $addon = $this->controller->Addon->read();
+
+ //Get translation ids of any translated fields
+ if (!empty($this->controller->Addon->translated_fields)) {
+ foreach ($this->controller->Addon->translated_fields as $translatedField) {
+ if (!empty($addon['Addon'][$translatedField])) {
+ $translationIds[] = $addon['Addon'][$translatedField];
+ }
+ }
+ }
+
+ //Loop through and delete versions
+ if (!empty($addon['Version'])) {
+ foreach ($addon['Version'] as $version) {
+ $this->deleteVersion($version['id']);
+ }
+ }
+
+ //Delete addons_tags rows
+ $this->controller->Addon->execute("DELETE FROM addons_tags WHERE addon_id='{$id}'");
+
+ //Delete addons_users rows
+ $this->controller->Addon->execute("DELETE FROM addons_users WHERE addon_id='{$id}'");
+
+ //Delete favorites
+ $this->controller->Addon->execute("DELETE FROM favorites WHERE addon_id='{$id}'");
+
+ //Delete features
+ $this->controller->Addon->execute("DELETE FROM features WHERE addon_id='{$id}'");
+
+ //Delete previews
+ $this->controller->Addon->execute("DELETE FROM previews WHERE addon_id='{$id}'");
+
+ //Loop through reviews
+ if (!empty($addon['Review'])) {
+ foreach ($addon['Review'] as $review) {
+ //Delete review ratings
+ $this->controller->Addon->execute("DELETE FROM reviewratings WHERE review_id='{$review['id']}'");
+
+ //Delete review
+ $this->controller->Addon->execute("DELETE FROM reviews WHERE id='{$review['id']}'");
+ }
+ }
+
+ //Delete add-on
+ $this->controller->Addon->execute("DELETE FROM addons WHERE id='{$id}' LIMIT 1");
+
+ //Delete translations
+ if (!empty($translationIds)) {
+ $this->controller->Addon->execute("DELETE FROM translations WHERE id IN (".implode(',', $translationIds).")");
+ }
+
+ return true;
+ }
+
+ /**
+ * Save localebox-formatted translations to their appropriate locales
+ * Post data is in the format:
+ * [Locales] => Array
+ * (
+ * [0] => en-US
+ * [1] => de
+ * )
+ * [Addon] => Array
+ * (
+ * [name] => Array
+ * (
+ * [0] => English Name
+ * [1] => German Name
+ * )
+ * )
+ * So we convert that into an array like:
+ * [en-US] => Array
+ * (
+ * [Addon] => Array
+ * (
+ * [name] => English Name
+ * )
+ * )
+ * and save it.
+ * @param array $data The post data to save
+ * @param array $models The models to process
+ */
+ function saveTranslations($data, $models = array()) {
+ if (empty($models)) {
+ $models = array('Addon', 'Preview', 'Version');
+ }
+
+ $translations = array();
+ $errors = 0;
+
+ if (!empty($data['Locales'])) {
+ foreach ($data['Locales'] as $id => $locale) {
+ // Reformat each model's array
+ foreach ($models as $model) {
+ if (!empty($data[$model])) {
+ foreach ($data[$model] as $field => $values) {
+ if (!in_array($field, $this->controller->{$model}->translated_fields)) continue;
+ $translations[$locale][$model][$field] = $values[$id];
+ }
+ }
+ }
+ }
+
+ // Update translations
+ if (!empty($translations)) {
+ foreach ($translations as $locale => $translation) {
+ foreach ($models as $model) {
+ if (!empty($translation[$model])) {
+ $this->controller->{$model}->setLang($locale, $this->controller);
+ $theData = $this->controller->Amo->filterFields($translation[$model], array(),
+ array('id', 'guid', 'status'));
+ if (!empty($theData)) {
+ //Save without validation (validation causes problems!)
+ if (!$this->controller->{$model}->save($theData, false)) {
+ $errors++;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // Reset langs
+ foreach ($models as $model) {
+ $this->controller->{$model}->setLang(LANG, $this->controller);
+ }
+
+ if (!empty($errors)) {
+ return false;
+ }
+ else {
+ return true;
+ }
+ }
+ else {
+ return false;
+ }
+ }
+
+ /**
+ * Strip localized fields from post data
+ * @param array $data The post data to strip
+ */
+ function stripLocalized($data) {
+
+ if (!empty($data['Addon'])) {
+ foreach ($this->controller->Addon->translated_fields as $field) {
+ unset($data['Addon'][$field]);
+ }
+ }
+
+ if (!empty($data['Version'])) {
+ foreach ($this->controller->Version->translated_fields as $field) {
+ unset($data['Version'][$field]);
+ }
+ }
+
+ unset($data['Locales']);
+
+ return $data;
+ }
+
+ /**
+ * Highlight another preview because the current is being removed/deleted
+ * @param array $preview The current preview data
+ * @param array $addon The current addon data
+ */
+ function highlightNextPreview($preview, $addon) {
+ $oldId = $this->controller->Preview->id;
+
+ foreach ($addon['Preview'] as $prev) {
+ if ($prev['id'] != $preview['Preview']['id']) {
+ $this->controller->Preview->id = $prev['id'];
+ $this->controller->Preview->save(array('highlight' => 1));
+ break;
+ }
+ }
+
+ $this->controller->Preview->id = $oldId;
+ }
+
+ /**
+ * Remove highlight from highlighted previews
+ * @param int $addon_id Add-on's id
+ */
+ function unhighlightOtherPreviews($addon_id) {
+ $this->controller->Preview->execute("UPDATE previews SET highlight=0 WHERE addon_id='{$addon_id}'");
+ }
+
+ function addPreview($addon_id, $data) {
+ $previewData = array('addon_id' => $addon_id,
+ 'filedata' => file_get_contents($data['File']['tmp_name']),
+ 'filetype' => $data['File']['type'],
+ 'highlight' => $data['highlight'],
+ 'thumbtype' => 'image/png'
+ );
+
+ //Check for allowed file extensions
+ $allowedImage = array('.png', '.jpg', '.gif');
+ $extension = substr($data['File']['name'], strrpos($data['File']['name'], '.'));
+ if (!in_array($extension, $allowedImage)) {
+ $errors =& $this->controller->Error;
+ $errors->addError(sprintf(_('devcp_error_preview_extension'), $extension, implode(', ', $allowedImage)), 'main');
+ return false;
+ }
+
+ list($sourceWidth, $sourceHeight) = getimagesize($data['File']['tmp_name']);
+
+ //Generate thumbnail (200 x 150) if necessary
+ if ($sourceHeight < 150 && $sourceWidth < 200) {
+ $previewData['thumbdata'] = $previewData['filedata'];
+ }
+ else {
+ $previewData['thumbdata'] = $this->resizeImage($previewData['filedata'], $sourceWidth, $sourceHeight, 200, 150);
+ }
+
+ //Resize preview if too large (700 x 525)
+ if ($sourceWidth > 700 || $sourceHeight > 525) {
+ $previewData['filedata'] = $this->resizeImage($previewData['filedata'], $sourceWidth, $sourceHeight, 700, 525);
+ $previewData['filetype'] = 'image/png';
+ }
+
+ /*
+ //Debug preview adjustments
+ $full = fopen(REPO_PATH.'/full.png', 'wb');
+ fwrite($full, $previewData['filedata']);
+ fclose($full);
+
+ $new = fopen(REPO_PATH.'/new.png', 'wb');
+ fwrite($new, $previewData['thumbdata']);
+ fclose($new);
+
+ echo '<img src="../../../files/full.png">';
+ echo '<img src="../../../files/new.png">';
+ //pr($previewData);
+ */
+
+ return $previewData;
+ }
+
+ /**
+ * Determine file status based on submission information
+ * @param array $addon Addon informaiton
+ * @return int $fileStatus the file status
+ */
+ function determineFileStatus($addon) {
+ //If a trusted public add-on, go to sandbox unless specified public
+ if ($addon['trusted'] == 1 && $addon['status'] == STATUS_PUBLIC) {
+ if (!empty($this->controller->data['File']['status'])) {
+ if ($this->controller->data['File']['status'] == 'public') {
+ $fileStatus = STATUS_PUBLIC;
+ }
+ else {
+ $fileStatus = STATUS_SANDBOX;
+ }
+ }
+ elseif ($version = $this->controller->Version->read()) {
+ $fileStatus = $version['File'][0]['status'];
+ }
+ else {
+ $fileStatus = STATUS_SANDBOX;
+ }
+ }
+ //If an update to an untrusted public add-on, STATUS_PENDING
+ elseif ($addon['status'] == STATUS_PUBLIC) {
+ $fileStatus = STATUS_PENDING;
+ }
+ //In all other cases (new add-on and update to non-public add-on), STATUS_SANDBOX
+ else {
+ $fileStatus = STATUS_SANDBOX;
+ }
+
+ return $fileStatus;
+ }
+
+ function getAllowedAddonTypes($autoDetect, $isAdmin) {
+ $addontypes = array(
+ ADDON_EXTENSION => $this->controller->Addontype->getName(ADDON_EXTENSION),
+ ADDON_THEME => $this->controller->Addontype->getName(ADDON_THEME),
+ ADDON_DICT => $this->controller->Addontype->getName(ADDON_DICT),
+ ADDON_LPAPP => $this->controller->Addontype->getName(ADDON_LPAPP)
+ );
+
+ if ($autoDetect == true) {
+ $addontypes[0] = _('devcp_additem_addontype_autodetect');
+ }
+
+ if ($isAdmin == true) {
+ $addontypes[ADDON_SEARCH] = $this->controller->Addontype->getName(ADDON_SEARCH);
+ }
+
+ ksort($addontypes);
+
+ return $addontypes;
+ }
+
+ function getLicenses($version_id=null) {
+ if ($version_id != null) {
+ $version = $this->controller->Version->findById($version_id);
+ $version = $version['Version'];
+ $license = $this->controller->License->findById($version['license_id']);
+ }
+
+ // Add 'Please Choose...' only if no license has been selected.
+ if (!isset($version['license_id'])) {
+ $licenses['null'] = array(
+ 'name' => ___('devcp_uploader_please_choose'),
+ 'selected' => True);
+ }
+
+ // Grab all the pre-approved licenses.
+ foreach ($this->controller->License->getNames() as $num => $builtin) {
+ $licenses['builtin_'.$num] = array(
+ 'name' => $builtin,
+ 'selected' => isset($license) && (string)$num === $license['License']['name']);
+ }
+
+ // The trans array holds translations for all the custom licenses we'll
+ // be displaying. `other` starts off empty, for creating new licenses.
+ $trans['other']['text']['en-US'] = '';
+
+ if ($version_id != null) {
+ // Find all the custom licenses in use by this add-on.
+ $q = "SELECT Version.version, Version.license_id
+ FROM versions AS Version INNER JOIN licenses AS License
+ ON Version.license_id = License.id
+ WHERE Version.addon_id = {$version['addon_id']}
+ AND Version.license_id IS NOT NULL
+ AND License.name = -1
+ GROUP BY License.id
+ ORDER BY Version.id DESC";
+ foreach ($this->controller->Version->execute($q) as $existing) {
+ $existing = $existing['Version'];
+ $t = ___('devcp_license_existing');
+ $val = 'existing_'.$existing['license_id'];
+ $licenses[$val] = array(
+ 'name' => sprintf($t, $version['addon_id'], $existing['version']),
+ 'selected' => $existing['license_id'] == $version['license_id']);
+ $trans[$val] = $this->controller->License->getAllTranslations($existing['license_id']);
+ }
+ }
+
+ $licenses['other'] = array('name' => ___('devcp_uploader_option_other'),
+ 'selected' => False);
+ return array($licenses, $trans);
+ }
+
+ function saveLicense($licenseData, $text, $params) {
+ $License = $this->controller->License;
+ if ($licenseData['name'] != 'null') {
+ $license = $licenseData['name'];
+ // If the license is pre-approved, we prefixed the id with builtin_.
+ if (preg_match('/^builtin_(\d+)$/', $license, $matches)) {
+ $license_id = $License->getBuiltin($matches[1]);
+ } else if ($license == 'other' ||
+ preg_match('/^existing_(\d+)$/', $license, $matches)) {
+ // If it's 'other', we need to create a new license.
+ if ($license == 'other') {
+ $data['License']['name'] = -1;
+ $License->save($data);
+ $license_id = $License->getLastInsertId();
+ } else {
+ $license_id = $matches[1];
+ }
+ // Save any changed translation text.
+ $localized['text'] = $text;
+ $License->saveTranslations($license_id, $params, $localized);
+ }
+ return $license_id;
+ }
+ }
+}
+?>
diff --git a/site/app/controllers/components/diff.php b/site/app/controllers/components/diff.php
new file mode 100644
index 0000000..e30f2ad
--- /dev/null
+++ b/site/app/controllers/components/diff.php
@@ -0,0 +1,180 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Cesar Oliveira <a.sacred.line@gmail.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+class DiffComponent extends Object {
+
+ /**
+ * Parses a unified diff output
+ * @param array $_text an entire section of a unified diff (between @@ lines)
+ * @param char $_check a '+' or '-' denoting whether we're looking for lines
+ * added or removed
+ * @return
+ */
+ function parse_diff($_text, $_check) {
+ $start = 0; // Start of the diff
+ $length = 0; // number of lines to recurse
+ $changes = array(); // all the changes
+
+ $regs = array();
+
+ if (preg_match("/^@@ ([\+\-])([0-9]+)(?:,([0-9]+))? [\+\-]([0-9]+)(?:,([0-9]+))? @@$/", array_shift($_text), $regs) == false) {
+ return;
+ }
+
+ $start = $regs[4];
+
+ $length = count($_text);
+ $instance = new Changes();
+
+ /* We don't count removed lines when looking at start of a change. For
+ * example, we have this :
+ * - foo
+ * + bar
+ * bar starts at line 1, not line 2.
+ */
+ $minus = 0;
+
+ for ($i = 0; $i < $length; $i++) {
+ $line = $_text[$i];
+
+ // empty line? EOF?
+ if (strlen($line) == 0) {
+ if ($instance->length > 0) {
+ array_push($changes, $instance);
+ $instance = new Changes();
+ }
+ continue;
+ }
+
+ if ($_check == '-' && $_check == $line[0]) {
+ if ($instance->length == 0) {
+ $instance->line = $start + $i - $minus;
+ $instance->symbol = $line[0];
+ $instance->length++;
+ }
+ array_push($instance->oldline, substr($line, 1));
+ }
+ elseif ($_check == '+' && $_check == $line[0]) {
+ if ($instance->length == 0) {
+ $instance->line = $start + $i - $minus;
+ $instance->symbol = $line[0];
+ }
+ $instance->length++;
+ }
+ else {
+ if ($instance->length > 0) {
+ array_push($changes, $instance);
+ $instance = new Changes();
+ }
+ }
+
+ if ($line[0] == '-')
+ $minus++;
+ }
+
+ if ($instance->length > 0) {
+ array_push($changes, $instance);
+ $instance = new Changes();
+ }
+
+ return $changes;
+ }
+
+ /**
+ * Appends or Replaces text
+ * @param array &$_text Array of Line objects
+ * @param array $_change Array of Change objects
+ * @param int &$offset how many lines to skip due to previous additions
+ */
+ function apply_change(&$_text, $_change, &$offset = 0) {
+ $index = 0;
+
+ // $i is the change we are on
+ for ($i = 0; $i < count($_change); $i++) {
+ $lines = $_change[$i];
+ // $j is the line within the change
+ for ($j = 0; $j < $lines->length; $j++) {
+ $linenum = $lines->line - 1;
+ $line = $_text[$linenum+$j+$offset];
+ $color = "green";
+
+ if (strlen(ltrim($line->text)) == 0) {
+ continue;
+ }
+
+ if ($lines->symbol == '-') {
+ $add = $lines->oldline;
+ array_splice($_text, $linenum + $j + $offset, 0, $add);
+ // $k is the counter for the old lines we
+ // removed from the previous version
+ for ($k = 0; $k < count($add); $k++) {
+ $l = new Line();
+ $l->changed = true;
+ $l->symbol = '-';
+ $l->text = sprintf("%s <span class='diff-remove'>%s</span>\n", "-", rtrim($add[$k], "\r\n"));
+
+ $_text[$linenum+$j+$k+$offset] = $l;
+ }
+ $offset += count($add);
+ } else {
+ $l = new Line();
+ $l->symbol = '+';
+ $l->changed = true;
+ $l->text = sprintf("%s <span class='diff-add'>%s</span>\n", $lines->symbol, rtrim($line->text, "\r\n"));
+ $_text[$linenum+$j] = $l;
+ }
+ }
+ }
+ }
+
+}
+
+class Changes {
+ public $line = 0;
+ public $length = 0;
+ public $symbol;
+ public $oldline = array(); // only for code removed
+}
+
+// This object is created for every line of text in the file.
+// It was either this, or some funk string changes
+class Line {
+ public $text = '';
+ public $symbol = '';
+ public $changed = false;
+}
+?>
diff --git a/site/app/controllers/components/editors.php b/site/app/controllers/components/editors.php
new file mode 100644
index 0000000..2992af2
--- /dev/null
+++ b/site/app/controllers/components/editors.php
@@ -0,0 +1,753 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * Justin Scott <fligtar@gmail.com>.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+class EditorsComponent extends Object {
+ var $controller;
+
+ /**
+ * Save a reference to the controller on startup
+ * @param object &$controller the controller using this component
+ */
+ function startup(&$controller) {
+ $this->controller =& $controller;
+ }
+
+ /**
+ * Process review for a nominated add-on.
+ * Update add-on, approval, and file info and send emails
+ * @param array $addon add-on information
+ * @param array $data POST data
+ */
+ function reviewNominatedAddon($addon, $data) {
+ //Make sure add-on is actually nominated
+ if ($addon['Addon']['status'] != STATUS_NOMINATED) {
+ $this->controller->Error->addError(___('editor_review_error_addon_not_nominated', 'This add-on has not been nominated'));
+ return false;
+ }
+
+ $this->controller->Addon->id = $addon['Addon']['id'];
+ $addonData = array();
+
+ //Get most recent version
+ $version = $this->controller->Version->findByAddon_id($this->controller->Addon->id, null, 'Version.created DESC');
+
+ if ($data['Approval']['ActionField'] == 'public') {
+ $addonData['status'] = STATUS_PUBLIC;
+ $addonData['higheststatus'] = STATUS_PUBLIC;
+ }
+ elseif ($data['Approval']['ActionField'] == 'sandbox') {
+ $addonData['status'] = STATUS_SANDBOX;
+ }
+ elseif ($data['Approval']['ActionField'] == 'superreview') {
+ $addonData['adminreview'] = 1;
+ $addonData['status'] = STATUS_NOMINATED;
+ }
+ else {
+ $this->controller->Error->addError(___('editor_review_error_no_action', 'Please select a review action.'));
+ return false;
+ }
+
+ if (empty($data['Approval']['comments'])) {
+ $this->controller->Error->addError(___('editor_review_error_no_comments', 'Please enter review comments.'));
+ return false;
+ }
+
+ $session = $this->controller->Session->read('User');
+
+ $approvalData = array('user_id' => $session['id'],
+ 'reviewtype' => 'nominated',
+ 'action' => $addonData['status'],
+ 'addon_id' => $this->controller->Addon->id,
+ 'comments' => $data['Approval']['comments'],
+ 'file_id' => $version['File'][0]['id']
+ );
+
+ if ($this->controller->Error->noErrors()) {
+ if ($data['Approval']['ActionField'] == 'public') {
+ //Make files of most recent version public
+ if (!empty($version['File'])) {
+ foreach ($version['File'] as $file) {
+ $this->controller->File->id = $file['id'];
+ $fileData = array('status' => STATUS_PUBLIC, 'datestatuschanged' => $this->controller->Amo->getNOW());
+ $this->controller->File->save($fileData);
+
+ // Move to public rsync repo
+ $file = $this->controller->File->read();
+ $this->controller->Amo->copyFileToPublic($approvalData['addon_id'], $file['File']['filename']);
+ }
+ }
+ }
+
+ $this->controller->Approval->save($approvalData);
+ $this->controller->Addon->save($addonData);
+ }
+ else {
+ return false;
+ }
+
+ if (!empty($addon['User'])) {
+ foreach ($addon['User'] as $user) {
+ $authors[] = $user['email'];
+ }
+ }
+
+ $emailInfo = array('name' => $addon['Translation']['name']['string'],
+ 'id' => $this->controller->Addon->id,
+ 'reviewer' => $session['firstname'].' '.$session['lastname'],
+ 'email' => implode(', ', $authors),
+ 'comments' => $data['Approval']['comments'],
+ 'version' => !empty($version) ? $version['Version']['version'] : ''
+ );
+
+ $this->controller->set('info', $emailInfo);
+
+ if ($data['Approval']['ActionField'] != 'superreview') {
+ $this->controller->Email->template = 'email/nominated/'.$data['Approval']['ActionField'];
+ $this->controller->Email->to = $emailInfo['email'];
+ $this->controller->Email->subject = sprintf('Mozilla Add-ons: %s Nomination', $emailInfo['name']);
+ }
+ else {
+ $this->controller->Email->template = 'email/superreview';
+ $this->controller->Email->to = 'amo-senior-editors@mozilla.org';
+ //Doesn't need to be localized
+ $this->controller->Email->subject = "Super-review requested: {$emailInfo['name']}";
+ }
+ $result = $this->controller->Email->send();
+
+ return true;
+ }
+
+ /**
+ * Process review for pending files
+ * Update approval and file info and send emails
+ * @param array $addon add-on information
+ * @param array $data POST data
+ */
+ function reviewPendingFiles($addon, $data) {
+ if (empty($data['Approval']['File'])) {
+ $this->controller->addError(___('editor_review_error_no_files', 'Please select at least one file to review.'));
+ return false;
+ }
+
+ $this->controller->Addon->id = $addon['Addon']['id'];
+ $fileData = array('datestatuschanged' => $this->controller->Amo->getNOW());
+
+ //Get most recent version
+ $version = $this->controller->Version->findByAddon_id($this->controller->Addon->id, null, 'Version.created DESC');
+
+ if ($data['Approval']['ActionField'] == 'public') {
+ $fileData['status'] = STATUS_PUBLIC;
+ }
+ elseif ($data['Approval']['ActionField'] == 'sandbox') {
+ $fileData['status'] = STATUS_SANDBOX;
+ }
+ elseif ($data['Approval']['ActionField'] == 'superreview') {
+ $addonData = array('adminreview' => 1);
+ $fileData['status'] = STATUS_PENDING;
+ }
+ else {
+ $this->controller->Error->addError(___('editor_review_error_no_action', 'Please select a review action.'));
+ return false;
+ }
+
+ if (empty($data['Approval']['comments'])) {
+ $this->controller->Error->addError(___('editor_review_error_no_comments', 'Please enter review comments.'));
+ return false;
+ }
+
+ if (empty($data['Approval']['applications'])) {
+ $this->controller->Error->addError(___('editor_review_error_no_applications', 'Please enter the tested applications.'));
+ return false;
+ }
+
+ if (empty($data['Approval']['os'])) {
+ $this->controller->Error->addError(___('editor_review_error_no_operating_system', 'Please enter the tested operating systems.'));
+ return false;
+ }
+
+ $session = $this->controller->Session->read('User');
+ $platforms = $this->controller->Amo->getPlatformName();
+ $files = array();
+
+ // Loop through checked files
+ foreach ($data['Approval']['File'] as $file_id) {
+ if ($file_id > 0) {
+ $this->controller->File->id = $file_id;
+ $file = $this->controller->File->read();
+
+ // Make sure file is pending review
+ if ($file['File']['status'] != STATUS_PENDING) {
+ $this->controller->Error->addError(___('editor_review_error_file_not_pending', 'File not pending review.'));
+ return false;
+ }
+
+ $approvalData = array('user_id' => $session['id'],
+ 'reviewtype' => 'pending',
+ 'action' => $fileData['status'],
+ 'addon_id' => $this->controller->Addon->id,
+ 'file_id' => $file_id,
+ 'comments' => $data['Approval']['comments'],
+ 'os' => $data['Approval']['os'],
+ 'applications' => $data['Approval']['applications']
+ );
+
+ if ($this->controller->Error->noErrors()) {
+ // Save approval log and new file status
+ $this->controller->Approval->save($approvalData);
+ $this->controller->File->save($fileData);
+
+ // Move to public rsync repo
+ if ($fileData['status'] == STATUS_PUBLIC) {
+ $this->controller->Amo->copyFileToPublic($approvalData['addon_id'], $file['File']['filename']);
+ }
+
+ if (!empty($addonData)) {
+ $this->controller->Addon->save($addonData);
+ }
+
+ $files[] = $addon['Translation']['name']['string'].' '.$version['Version']['version'].' - '.$platforms[$file['File']['platform_id']];
+ }
+ else {
+ return false;
+ }
+ }
+ }
+
+ if (!empty($addon['User'])) {
+ foreach ($addon['User'] as $user) {
+ $authors[] = $user['email'];
+ }
+ }
+
+ $emailInfo = array('name' => $addon['Translation']['name']['string'],
+ 'id' => $this->controller->Addon->id,
+ 'reviewer' => $session['firstname'].' '.$session['lastname'],
+ 'email' => implode(', ', $authors),
+ 'comments' => $data['Approval']['comments'],
+ 'os' => $data['Approval']['os'],
+ 'apps' => $data['Approval']['applications'],
+ 'version' => !empty($version) ? $version['Version']['version'] : '',
+ 'files' => $files
+ );
+ $this->controller->set('info', $emailInfo);
+
+ if ($data['Approval']['ActionField'] != 'superreview') {
+ $this->controller->Email->template = 'email/pending/'.$data['Approval']['ActionField'];
+ $this->controller->Email->to = $emailInfo['email'];
+ $this->controller->Email->subject = sprintf('Mozilla Add-ons: %s %s', $emailInfo['name'], $emailInfo['version']);
+ }
+ else {
+ $this->controller->Email->template = 'email/superreview';
+ $this->controller->Email->to = 'amo-senior-editors@mozilla.org';
+ //Doesn't need to be localized
+ $this->controller->Email->subject = "Super-review requested: {$emailInfo['name']}";
+ }
+ $result = $this->controller->Email->send();
+
+ return true;
+ }
+
+ /**
+ * Request more information from an author regarding an update/nomination
+ * request
+ */
+ function requestInformation($addon, $data) {
+ global $valid_status;
+
+ // store information request
+ $session = $this->controller->Session->read('User');
+ foreach($data['Approval']['File'] as $_fid) {
+ if ($_fid > 0) {
+ $file_id = $_fid;
+ break;
+ }
+ }
+ $approvalData = array(
+ 'user_id' => $session['id'],
+ 'reviewtype' => 'info',
+ 'action' => 0,
+ 'addon_id' => $addon['Addon']['id'],
+ 'comments' => $data['Approval']['comments']
+ );
+ $this->controller->Approval->save($approvalData);
+ $infoid = $this->controller->Approval->getLastInsertID();
+
+ // send email to all authors
+ $authors = array();
+ foreach ($addon['User'] as &$user) $authors[] = $user['email'];
+
+ $versionid = $this->controller->Version->getVersionByAddonId($addon['Addon']['id'], $valid_status);
+ $version = $this->controller->Version->findById($versionid, null, null, -1);
+
+ $emailInfo = array(
+ 'name' => $addon['Translation']['name']['string'],
+ 'infoid' => $infoid,
+ 'reviewer' => $session['firstname'].' '.$session['lastname'],
+ 'comments' => $data['Approval']['comments'],
+ 'version' => !empty($version) ? $version['Version']['version'] : ''
+ );
+ $this->controller->publish('info', $emailInfo, false);
+ $this->controller->Email->template = 'email/inforequest';
+ $this->controller->Email->to = implode(', ', $authors);
+ $this->controller->Email->subject = sprintf('Mozilla Add-ons: %s %s', $emailInfo['name'], $emailInfo['version']);
+ $this->controller->Email->send();
+ }
+
+ /**
+ * Jump to specific item in queue
+ * redirects to review page if item was found, to queue otherwise
+ * @param string $listtype 'nominated' or 'pending'
+ * @param int $rank list entry to jump to
+ * @return void
+ */
+ function redirectByQueueRank($listtype, $rank) {
+ switch($listtype) {
+ case 'nominated':
+ case 'pending':
+ $rank = intval($rank);
+ $offset = ($rank > 0) ? $rank - 1 : 0;
+ $sql = $this->buildQueueFilterQuery($listtype);
+ $queue_sql = "SELECT `Version`.`id`
+ {$sql['FROM']}
+ {$sql['JOIN']}
+ {$sql['WHERE']}
+ {$sql['ORDER']}
+ LIMIT 1 OFFSET {$offset}";
+
+ if ($result = $this->controller->Addon->query($queue_sql)) {
+ $review_id = $result[0]['Version']['id'];
+ $this->controller->redirect("/editors/review/{$review_id}?num={$rank}");
+ return;
+ }
+ break;
+
+ default:
+ return false;
+ }
+
+ // if we did not find anything, redirect to queue
+ $this->controller->redirect("/editors/queue/{$listtype}");
+ }
+
+ /**
+ * Notify subscribed editors of an add-on's update
+ * @param int $addonid ID of add-on that was updated
+ * @param int $versionid ID of the add-on's new version
+ */
+ function updateNotify($addonid, $versionid) {
+ $_ids = $this->controller->EditorSubscription->getSubscribers($addonid);
+ if (empty($_ids)) return;
+ $subscribers = $this->controller->User->findAllById($_ids, null, null, null, null, -1);
+
+ $addon = $this->controller->Addon->getAddon($addonid);
+ $version = $this->controller->Version->findById($versionid, null, null, null, null, -1);
+
+ // send out notification email(s)
+ $emailInfo = array(
+ 'id' => $addonid,
+ 'name' => $addon['Translation']['name']['string'],
+ 'versionid' => $versionid,
+ 'version' => $version['Version']['version']
+ );
+ $this->controller->publish('info', $emailInfo, false);
+
+ $this->controller->Email->template = '../editors/email/notify_update';
+ $this->controller->Email->subject = sprintf('Mozilla Add-ons: %s Updated', $emailInfo['name']);
+
+ foreach ($subscribers as &$subscriber) {
+ $this->controller->Email->to = $subscriber['User']['email'];
+ $result = $this->controller->Email->send();
+ // unsubscribe user from further updates
+ $this->controller->EditorSubscription->cancelUpdates($subscriber['User']['id'], $addonid);
+ }
+
+ }
+
+ /**
+ * Determine if the specified queue is filterable
+ * Queues currently filterable are: 'nominated' and 'pending'
+ * @param string $queue name of queue
+ * @return bool
+ */
+ function isFilterableQueue($queue) {
+ return in_array($queue, array('pending', 'nominated'));
+ }
+
+ /**
+ * Build query components for filtering the specified queue
+ * Returns empty array for unfilterable queues
+ * @param string $queue name of queue
+ * @return array array('FROM'=>string, 'JOIN'=>string, 'WHERE'=>string, 'ORDER'=>string)
+ * @TODO: for cake >=1.2, return compatible 'joins' and 'conditions' arrays
+ */
+ function buildQueueFilterQuery($queue='pending') {
+ if (!$this->isFilterableQueue($queue)) {
+ return array();
+ }
+
+ // Setup query components
+ $base_components = $this->baseQueueFilterQuery($queue);
+ $from = $base_components['FROM'];
+ $joins = $base_components['JOIN'];
+ $where = $base_components['WHERE'];
+ $order = 'ORDER BY';
+
+ // Fetch and apply filter
+ if ($filter = $this->getQueueFilter($queue)) {
+ $this->controller->Amo->clean($filter, false);
+
+ if (isset($filter['AddonOrAuthor']) && strlen($filter['AddonOrAuthor']) > 0) {
+ // search addons.name (localized), addons.supportemail (localized) and users.email
+ $where .= "\nAND (`Version`.`addon_id` IN(
+ SELECT `a`.`id` FROM `addons` AS `a`
+ LEFT JOIN `translations` AS `ntr_l` ON
+ (`ntr_l`.`id`=`a`.`name` AND `ntr_l`.`locale`='".LANG."')
+ LEFT JOIN `translations` AS `ntr_en` ON
+ (`ntr_en`.`id`=`a`.`name` AND `ntr_en`.`locale`=`a`.`defaultlocale`)
+ LEFT JOIN `translations` AS `etr_l` ON
+ (`etr_l`.`id`=`a`.`supportemail` AND `etr_l`.`locale`='".LANG."')
+ LEFT JOIN `translations` AS `etr_en` ON
+ (`etr_en`.`id`=`a`.`supportemail` AND `etr_en`.`locale`=`a`.`defaultlocale`)
+ WHERE
+ IFNULL(`ntr_l`.`localized_string`, `ntr_en`.`localized_string`)
+ LIKE '%{$filter['AddonOrAuthor']}%'
+ OR IFNULL(`etr_l`.`localized_string`, `etr_en`.`localized_string`)
+ LIKE '%{$filter['AddonOrAuthor']}%'
+
+ ) OR `Version`.`addon_id` IN(
+ SELECT `a`.`id` FROM `addons` AS `a`
+ LEFT JOIN `addons_users` AS `au` ON (`a`.`id`=`au`.`addon_id`)
+ LEFT JOIN `users` AS `u` ON (`au`.`user_id`=`u`.`id`)
+ WHERE
+ `au`.`role` IN(".AUTHOR_ROLE_ADMINOWNER.","
+ .AUTHOR_ROLE_ADMIN.","
+ .AUTHOR_ROLE_OWNER.","
+ .AUTHOR_ROLE_DEV.")
+ AND `u`.`email` LIKE '%{$filter['AddonOrAuthor']}%'
+ ))";
+ }
+
+ if (!empty($filter['Application'])) {
+ $joins .= "\nLEFT JOIN `applications_versions`
+ ON (`Version`.`id`=`applications_versions`.`version_id`)";
+ $where .= "\nAND (
+ `applications_versions`.`application_id`='{$filter['Application']}')";
+
+ if (!empty($filter['MaxVersion'])) {
+ $where .= "\nAND (`applications_versions`.`max`='{$filter['MaxVersion']}')";
+ }
+ }
+
+ if (!empty($filter['SubmissionAge'])) {
+ $age = $filter['SubmissionAge'];
+ $age_op = '='; // exact match by default
+
+ if (substr($age, -1) == '+') {
+ // values like '10+' magically turn into a '>=10' comparison
+ $age_op = '>=';
+ $age = substr($age, 0, -1);
+ } elseif ($age === '1') {
+ // make '1 day' include less than 1 as well
+ $age_op = '<=';
+ }
+
+ if ($queue == 'pending') {
+ $where .= "\nAND (TIMESTAMPDIFF(DAY, `Version`.`created`, NOW()){$age_op}'{$age}')";
+ } elseif ($queue == 'nominated') {
+ $where .= "\nAND (TIMESTAMPDIFF(DAY, `Addon`.`nominationdate`, NOW()){$age_op}'{$age}')";
+ }
+ }
+
+ if (!empty($filter['Addontype'])) {
+ if (is_array($filter['Addontype'])) {
+ $filter_vals = $filter['Addontype'];
+ } else {
+ $filter_vals = array($filter['Addontype']);
+ }
+
+ $where .= "\nAND (`Addon`.`addontype_id` IN('"
+ . implode("','", $filter_vals) ."'))";
+ }
+
+ if (!empty($filter['Platform'])) {
+ if (is_array($filter['Platform'])) {
+ $filter_vals = $filter['Platform'];
+ } else {
+ $filter_vals = array($filter['Platform']);
+ }
+
+ // only available to pending queue for now
+ if ($queue == 'pending') {
+ $where .= "\nAND (`File`.`platform_id` IN('"
+ . implode("','", $filter_vals) ."'))";
+ }
+ }
+ }
+ //End apply filter
+
+ // Sorting
+ $theSort = $this->getQueueSort($queue);
+ switch ($theSort['sortby']) {
+ case 'name':
+ $joins .= "\nLEFT JOIN `translations` AS `tr_l` ON
+ (`tr_l`.`id` = `Addon`.`name` AND `tr_l`.`locale` = '".LANG."')"
+ ."\nLEFT JOIN `translations` AS `tr_en` ON
+ (`tr_en`.`id` = `Addon`.`name` AND `tr_en`.`locale` = `Addon`.`defaultlocale`)";
+ $order .= ' IFNULL(tr_l.localized_string, tr_en.localized_string)';
+ $order .= strtoupper($theSort['direction'] == 'DESC') ? ' DESC' : ' ASC';
+ break;
+
+ case 'type':
+ $joins .= "\nLEFT JOIN addontypes AS `Addontype` ON
+ (`Addon`.`addontype_id`=`Addontype`.`id`)"
+ ."\nLEFT JOIN translations AS `tr_l` ON
+ (`tr_l`.`id` = `Addontype`.`name` AND `tr_l`.`locale` = '".LANG."')"
+ ."\nLEFT JOIN translations AS tr_en ON
+ (`tr_en`.`id` = `Addontype`.`name` AND `tr_en`.`locale` = 'en-US')";
+ $order .= ' IFNULL(`tr_l`.`localized_string`, `tr_en`.`localized_string`)';
+ $order .= strtoupper($theSort['direction'] == 'DESC') ? ' DESC' : ' ASC';
+ // secondary sort by age
+ if ($queue == 'pending') {
+ $order .= ', `Version`.`created` ASC';
+ } else {
+ $order .= ', `Addon`.`nominationdate` ASC';
+ }
+ break;
+
+ case 'age':
+ default:
+ if ($queue == 'pending') {
+ $order .= ' `Version`.`created`';
+ } else {
+ $order .= ' `Addon`.`nominationdate`';
+ }
+ $order .= strtoupper($theSort['direction'] == 'DESC') ? ' DESC' : ' ASC';
+ break;
+ }
+
+ return array('FROM'=>$from, 'JOIN'=>$joins, 'WHERE'=>$where, 'ORDER'=>$order);
+ }
+
+ /**
+ * Return base query components for filtering the specified queue
+ * Returns empty array for unfilterable queues
+ * @param string $queue name of queue
+ * @return array array('FROM'=>string, 'JOIN'=>string, 'WHERE'=>string)
+ * @TODO: for cake >=1.2, return compatible 'joins' and 'conditions' arrays
+ */
+ function baseQueueFilterQuery($queue='pending') {
+ if (!$this->isFilterableQueue($queue)) {
+ return array();
+ }
+
+ // Setup query components
+ if ($queue == 'pending') {
+ $from = "FROM `files` AS `File`";
+ $joins = "LEFT JOIN `versions` AS `Version` ON (`File`.`version_id`=`Version`.`id`)";
+ $joins .= "\nINNER JOIN `addons` AS `Addon` ON (`Version`.`addon_id`=`Addon`.`id`)";
+ $where = "WHERE `File`.`status`='".STATUS_PENDING."'";
+
+ } elseif ($queue == 'nominated') {
+ $from = "FROM `addons` AS `Addon`";
+ $joins = "INNER JOIN `versions` AS `Version` ON (`Addon`.`id`=`Version`.`addon_id`)";
+ $where = "WHERE `Addon`.`status`='".STATUS_NOMINATED."'";
+
+ // This makes sure we get only the most recent version
+ // "Find the version where no other version exists for the same addon and a greater creation date"
+ // http://stackoverflow.com/questions/157459/problem-joining-on-the-highest-value-in-mysql-table
+ $joins .= "\nLEFT JOIN `versions` AS `v2` ON (
+ `Version`.`addon_id`=`v2`.`addon_id` AND
+ `Version`.`created`<`v2`.`created`)";
+ $where .= "\nAND (`v2`.`id` IS NULL)";
+ }
+
+ return array('FROM'=>$from, 'JOIN'=>$joins, 'WHERE'=>$where);
+ }
+
+ /**
+ * Get the active filter for the specified queue
+ * @param string $queue name of queue
+ * @return array filter array or empty array if none exists
+ */
+ function getQueueFilter($queue) {
+ if (!$this->isFilterableQueue($queue)) {
+ return array();
+ }
+
+ $filter = array();
+ $queue_filters = $this->controller->Session->read('editor_queue_filters');
+ if (isset($queue_filters[$queue])) {
+ $filter = $queue_filters[$queue];
+ }
+ return $filter;
+ }
+
+ /**
+ * Set the active filter for the specified queue
+ * Only known fields are saved into the filter
+ * @param string $queue name of queue
+ * @return array empty array, or valid saved filter
+ */
+ function setQueueFilter($queue, $new_filter) {
+ if (!$this->isFilterableQueue($queue)) {
+ return array();
+ }
+
+ // known filter fields
+ $filter_fields = array('Addontype', 'Application', 'MaxVersion',
+ 'Platform', 'SubmissionAge', 'AddonOrAuthor');
+ $filter = array();
+
+ if (is_array($new_filter)) {
+ foreach ($new_filter as $k => $val) {
+ // only save known filter fields
+ if (!empty($val) && in_array($k, $filter_fields)) {
+ $filter[$k] = $val;
+ }
+ }
+ }
+
+ // get or create array of filters
+ $queue_filters = $this->controller->Session->read('editor_queue_filters');
+ if (!is_array($queue_filters)) {
+ $queue_filters = array();
+ }
+
+ if ($filter) {
+ // update filter
+ $queue_filters[$queue] = $filter;
+ } else {
+ // clear filter
+ unset($queue_filters[$queue]);
+ }
+
+ // save all filters
+ $this->controller->Session->write('editor_queue_filters', $queue_filters);
+
+ return $filter;
+ }
+
+ /**
+ * Determine if the specified queue is sortable
+ * @param string $queue name of queue
+ * @return bool
+ */
+ function isSortableQueue($queue) {
+ return in_array($queue, array('pending', 'nominated'));
+ }
+
+ /**
+ * Get current sort order parameters for specified queue
+ * @param string $queue name of queue
+ * @param string $default return default filter instead of saved - defaults to false
+ * @return array
+ */
+ function getQueueSort($queue, $default=false) {
+ if (!$this->isSortableQueue($queue)) {
+ return array();
+ }
+
+ $defaults = array(
+ 'pending' => array('sortby'=>'age', 'direction'=>'ASC'),
+ 'nominated' => array('sortby'=>'age', 'direction'=>'ASC'),
+ );
+
+ if (!$default) {
+ $queue_sorts = $this->controller->Session->read('editor_queue_sorts');
+ if (isset($queue_sorts[$queue])) {
+ return $queue_sorts[$queue];
+ }
+ }
+
+ return $defaults[$queue];
+ }
+
+ /**
+ * Set sort order parameters on specified queue
+ * @param string $queue
+ * @param string $sortby
+ * @param string $direction
+ * @return bool
+ */
+ function setQueueSort($queue, $sortby='default', $direction='default') {
+ if (!$this->isSortableQueue($queue)) {
+ return array();
+ }
+
+ // valid sorts for the queues, each sort containing default directions
+ $validSorts = array(
+ 'pending' => array(
+ 'age' => array('direction'=>'ASC'),
+ 'type' => array('direction'=>'ASC'),
+ 'name' => array('direction'=>'ASC'),
+ ),
+ 'nominated' => array(
+ 'age' => array('direction'=>'ASC'),
+ 'type' => array('direction'=>'ASC'),
+ 'name' => array('direction'=>'ASC'),
+ ),
+ );
+
+ $queueSorts = $this->controller->Session->read('editor_queue_sorts');
+ if (!is_array($queueSorts)) {
+ $queueSorts = array();
+ }
+
+ // reset to default
+ if ($sortby == 'default') {
+ unset($queueSorts[$queue]);
+ $this->controller->Session->write('editor_queue_sorts', $queueSorts);
+
+ // set to a known sort
+ } elseif (array_key_exists($sortby, $validSorts[$queue])) {
+ $newSort = $validSorts[$queue][$sortby];
+ $newSort['sortby'] = $sortby;
+ // use default direction unless...
+ if (in_array(strtoupper($direction), array('DESC', 'ASC'))) {
+ $newSort['direction'] = strtoupper($direction);
+ }
+ $queueSorts[$queue] = $newSort;
+ $this->controller->Session->write('editor_queue_sorts', $queueSorts);
+
+ // unknown sort
+ } else {
+ return false;
+ }
+
+ return true;
+ }
+}
+?>
diff --git a/site/app/controllers/components/email.php b/site/app/controllers/components/email.php
new file mode 100644
index 0000000..b62f9f7
--- /dev/null
+++ b/site/app/controllers/components/email.php
@@ -0,0 +1,104 @@
+<?php
+/**
+ * This is a component to send email from CakePHP using PHPMailer
+ * @link http://wiki.cakephp.org/tutorials:sending_email_with_phpmailer
+ * @see http://wiki.cakephp.org/tutorials:sending_email
+ */
+
+class EmailComponent
+{
+/**
+ * Send email using SMTP Auth by default.
+ */
+ var $from = 'nobody@mozilla.org';
+ var $fromName = 'Mozilla Add-ons';
+ var $sender = null;
+ //var $smtpUserName = 'username'; // SMTP username
+ //var $smtpPassword = 'password'; // SMTP password
+ //var $smtpHostNames= "smtp1.example.com;smtp2.example.com"; // specify main and backup server
+ var $text_body = null;
+ var $html_body = null;
+ var $to = null;
+ var $toName = null;
+ var $subject = null;
+ var $cc = null;
+ var $bcc = null;
+ var $template = null; // rendering template for email
+
+ var $controller;
+
+ function startup( &$controller ) {
+ $this->controller = &$controller;
+ }
+
+ function bodyText() {
+ /**
+ * This is the body in plain text for non-HTML mail client
+ */
+ $temp_layout = $this->controller->layout;
+ $this->controller->layout = ""; // turn off the layout wrapping
+ ob_start();
+ $this->controller->render($this->template.'_plain');
+ $mail = ob_get_clean();
+ $this->controller->layout = $temp_layout;
+ return $mail;
+ }
+
+ function bodyHTML() {
+ /**
+ * This is HTML body text for HTML-enabled mail clients
+ */
+ $temp_layout = $this->controller->layout;
+ $this->controller->layout = ""; // add html wrapper for emails here if necessary
+ ob_start();
+ $this->controller->render($this->template.'_html');
+ $mail = ob_get_clean();
+ $this->controller->layout = $temp_layout;
+ return $mail;
+ }
+
+
+ function send($html = false)
+ {
+ vendor('phpmailer'.DS.'class.phpmailer');
+
+ $mail = new PHPMailer();
+
+ $mail->IsMail(); // set mailer to use PHP's mail()
+ //$mail->IsSMTP(); // set mailer to use SMTP
+ //$mail->SMTPAuth = true; // turn on SMTP authentication
+ //$mail->Host = $this->smtpHostNames;
+ //$mail->Username = $this->smtpUserName;
+ //$mail->Password = $this->smtpPassword;
+
+ $mail->From = $this->from;
+ // if "Sender" field is set, add correct Sender header (cf. RFC5322 § 3.6.2)
+ if (!empty($this->sender)) {
+ $mail->Sender = $this->sender;
+ $mail->AddCustomHeader("Sender: {$this->sender}");
+ } else {
+ $mail->Sender = $this->from;
+ }
+ $mail->FromName = $this->fromName;
+ $mail->AddAddress($this->to, $this->toName );
+ $mail->AddReplyTo($this->from, $this->fromName );
+
+ $mail->CharSet = 'UTF-8';
+ //$mail->WordWrap = 50; // set word wrap to 50 characters
+ //$mail->AddAttachment("/var/tmp/file.tar.gz"); // add attachments
+ //$mail->AddAttachment("/tmp/image.jpg", "new.jpg"); // optional name
+ $mail->IsHTML($html); // set email format to HTML
+
+ $mail->Subject = $this->subject;
+ if ($html) {
+ $mail->Body = $this->bodyHTML();
+ $mail->AltBody = $this->bodyText();
+ } else {
+ $mail->Body = $this->bodyText();
+ }
+
+ $success = $mail->Send();
+ return $success;
+ }
+}
+?>
diff --git a/site/app/controllers/components/error.php b/site/app/controllers/components/error.php
new file mode 100644
index 0000000..070a74c
--- /dev/null
+++ b/site/app/controllers/components/error.php
@@ -0,0 +1,110 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * Justin Scott <fligtar@gmail.com>.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+class ErrorComponent extends Object {
+ var $controller;
+ var $errors = array();
+
+ /**
+ * Save a reference to the controller on startup and reset errors
+ * @param object &$controller the controller using this component
+ */
+ function startup(&$controller) {
+ $this->controller =& $controller;
+ $this->resetErrors();
+ }
+
+ /**
+ * Resets errors to defaults to prevent notices
+ */
+ function resetErrors() {
+ $this->errors = array(
+ 'Addon/icon' => '',
+ 'File/file1' => '',
+ 'File/file2' => '',
+ 'File/file3' => '',
+ 'File/file4' => '',
+ 'main' => '',
+ 'Preview/File' => '',
+ 'Tag/Tag' => '',
+ 'User/User' => '',
+ 'Version/releasenotes' => ''
+ );
+ }
+
+ /**
+ * Add an error to the errors array
+ * @param string $error The error message
+ * @param string $field The offending field
+ */
+ function addError($error, $field = 'main') {
+ $this->errors[$field] = $error;
+ }
+
+ /**
+ * Check if any errors have been logged
+ * @param object &$controller The controller
+ */
+ function noErrors() {
+ $errors = false;
+
+ if (count($this->errors) > 0) {
+ foreach ($this->errors as $error) {
+ if (!empty($error)) {
+ $errors = true;
+ }
+ }
+ }
+
+ if ($errors == false) {
+ return true;
+ }
+ else {
+ if (!empty($this->errors['main'])) {
+ $this->controller->Addon->invalidate('main');
+ }
+ return false;
+ }
+ }
+
+ function getJSONforError($error) {
+ return array(
+ 'error' => true,
+ 'error_message' => $error
+ );
+ }
+}
+?>
diff --git a/site/app/controllers/components/filebrowser.php b/site/app/controllers/components/filebrowser.php
new file mode 100644
index 0000000..a195385
--- /dev/null
+++ b/site/app/controllers/components/filebrowser.php
@@ -0,0 +1,104 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * Justin Scott <fligtar@gmail.com>.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+class FilebrowserComponent extends Object {
+ var $controller;
+
+ /**
+ * Save a reference to the controller on startup
+ * @param object &$controller the controller using this component
+ */
+ function startup(&$controller) {
+ $this->controller =& $controller;
+ }
+
+ function buildContentsArray($filename, $directory, $changed, &$array) {
+ $nodes = explode('/', $filename);
+ $current =& $array;
+ if (!empty($nodes)) {
+ foreach ($nodes as $node) {
+ if (!empty($node)) {
+ if (!array_key_exists($node, $current)) {
+ $current['dir'] = 1;
+ $current[$node] = array(
+ 'filename' => $node,
+ 'path' => $filename,
+ 'dir' => $directory,
+ 'changed' => $changed
+ );
+ }
+ if ($changed)
+ $current[$node]['changed'] = $changed;
+ $current =& $current[$node];
+ }
+ }
+ }
+ }
+
+ function getJarContents($jarpath, $content, $filename = '') {
+ $fp = fopen($jarpath, 'w');
+ fwrite($fp, $content);
+ fclose($fp);
+
+ $jar = new Archive_Zip($jarpath);
+
+ if (!empty($filename)) {
+ $params = array('extract_as_string' => true, 'by_name' => array($filename));
+ }
+ else {
+ $params = array('extract_as_string' => true);
+ }
+
+ $jarcontents = $jar->extract($params);
+
+ unlink($jarpath);
+ return $jarcontents;
+ }
+
+ /* Given the zip contents (array), tries to find the filename and
+ * returns the index within the zip contents
+ */
+ function getFilenameIndex($contents, $filename) {
+ $length = count($contents);
+ for ($i = 0; $i < $length; $i++) {
+ if ($contents[$i]['filename'] == $filename)
+ return $i;
+ }
+
+ return -1;
+ }
+}
+?>
diff --git a/site/app/controllers/components/helper.php b/site/app/controllers/components/helper.php
new file mode 100644
index 0000000..3690cde
--- /dev/null
+++ b/site/app/controllers/components/helper.php
@@ -0,0 +1,74 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is http://m3nt0r.de/blog/2007/08/12/cakephp-helpercomponent/.
+ *
+ * The Initial Developer of the Original Code is
+ * Kjell
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Frederic Wenzel <fwenzel@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/**
+ * This component allows helpers to be used as if they were components. This
+ * is useful in the rare case that helper functionality is needed outside a
+ * view, inside a controller, in order not to duplicate code.
+ *
+ * Usage:
+ * Add this component, and an array like:
+ * var $actionHelpers = array('html');
+ * to your controller, then use the respective helper(s) like components.
+ */
+class HelperComponent extends Object {
+ var $controller;
+
+ function startup(&$controller) {
+ $this->controller = $controller;
+ if (isset($controller->actionHelpers)) {
+ $this->pushHelpers();
+ }
+ }
+
+ function pushHelpers() {
+ foreach($this->controller->actionHelpers as &$helper) {
+ $_helper = ucfirst($helper);
+ loadHelper($_helper);
+ if ($_helper == 'Html') { // replace regular HTML helper with Addons HTML helper
+ loadHelper('AddonsHtml');
+ $_helperClassName = 'AddonsHtmlHelper';
+ } else {
+ $_helperClassName = $helper.'Helper';
+ }
+ $this->controller->{$helper} = new $_helperClassName();
+ $this->controller->{$helper}->base = $this->controller->base; // for URL magic
+ }
+ }
+}
+?>
diff --git a/site/app/controllers/components/image.php b/site/app/controllers/components/image.php
new file mode 100644
index 0000000..2329f9f
--- /dev/null
+++ b/site/app/controllers/components/image.php
@@ -0,0 +1,243 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Andrei Hajdukewycz <sancus@off.net> (Original Author)
+ * Wil Clouser <clouserw@mozilla.com>
+ * Mike Morgan <morgamic@mozilla.com>
+ * Frederic Wenzel <fwenzel@mozilla.com>
+ * Justin Scott <fligtar@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+class ImageComponent extends Object {
+
+ /**
+ * Startup method
+ */
+ function startup(&$controller) {
+ $this->controller =& $controller;
+
+ if (!defined('NO_MICROTIME'))
+ define('NO_MICROTIME', true);
+ }
+
+ /**
+ * Renders the specified image data
+ * @param string $data the image data
+ * @param string $type the mime type
+ */
+ function renderImage($data, $mime) {
+ header('Content-length: '.strlen($data));
+ header("Content-type: {$mime}");
+
+ $expires = time() + 60 * 60 * 24 * 365 * 10;
+ header("Expires: ".gmstrftime("%a, %d %b %Y %T GMT", $expires));
+
+ echo $data;
+ exit;
+ }
+
+ /**
+ * Renders the icon for the add-on
+ * @param int $addon_id the add-on ID
+ */
+ function renderAddonIcon($addon_id) {
+ $addon = $this->controller->Addon->findById($addon_id, array('icondata', 'icontype'), null, -1);
+
+ $this->renderImage($addon['Addon']['icondata'], $addon['Addon']['icontype']);
+ }
+
+ /**
+ * Renders the icon for a collection
+ * @param int $collection_id the add-on ID
+ */
+ function renderCollectionIcon($collection_id) {
+ $collection = $this->controller->Collection->findById($collection_id, array('icondata', 'icontype'), null, -1);
+
+ $this->renderImage($collection['Collection']['icondata'], $collection['Collection']['icontype']);
+ }
+
+ /**
+ * Renders the preview or thumbnail for an add-on
+ * @param int $preview_id the preview id
+ * @param string $type type of image -- full or thumbnail
+ */
+ function renderAddonPreview($preview_id, $type = 'full') {
+ if ($type == 'full') {
+ $fields = array(
+ 'data' => 'filedata',
+ 'type' => 'filetype'
+ );
+ }
+ elseif ($type == 'thumbnail') {
+ $fields = array(
+ 'data' => 'thumbdata',
+ 'type' => 'thumbtype'
+ );
+ }
+
+ $preview = $this->controller->Preview->findById($preview_id, array($fields['data'], $fields['type']));
+
+ $this->renderImage($preview['Preview'][$fields['data']], $preview['Preview'][$fields['type']]);
+ }
+
+ /**
+ * Gets the URL for the icon of the specified add-on
+ * @param int $addon_id the add-on id
+ * @return string the URL
+ */
+ function getAddonIconURL($addon_id) {
+ $addon = $this->controller->Addon->findById($addon_id, array('addontype_id', 'icontype', 'modified'), null, -1);
+
+ if (empty($addon['Addon']['icontype'])) {
+ if ($addon['Addon']['addontype_id'] == ADDON_THEME) {
+ return "{$this->controller->base}/img/theme.png";
+ }
+ else {
+ return "{$this->controller->base}/img/default_icon.png";
+ }
+ }
+ else {
+ return "{$this->controller->base}/en-US/firefox/images/addon_icon/{$addon_id}/".strtotime($addon['Addon']['modified']);
+ }
+ }
+
+ /**
+ * Gets the URL for the icon of the specified collection
+ * @param int $addon_id the add-on id
+ * @return string the URL
+ */
+ function getCollectionIconURL($collection_id) {
+ $collection = $this->controller->Collection->findById(
+ $collection_id, array(
+ 'icontype', 'collection_type', 'uuid', 'modified'
+ ), null, -1
+ );
+
+ if (empty($collection['Collection']['icontype'])) {
+ return "{$this->controller->base}/img/collection.png";
+ } else {
+ return "{$this->controller->base}/en-US/firefox/images/collection_icon/{$collection_id}/".strtotime($collection['Collection']['modified']);
+ }
+ }
+
+ /**
+ * Gets the URL for the highlighted preview for an add-on
+ * @param int $addon_id add-on ID
+ * @param string $type type of preview
+ * @return string the url
+ */
+ function getHighlightedPreviewURL($addon_id, $type = 'thumbnail') {
+ // Make sure preview model is loaded
+ $this->_loadPreviewModel();
+
+ $preview = $this->controller->Preview->find("addon_id={$addon_id}", array('id'), 'highlight DESC, created', null, -1);
+
+ return $this->getPreviewURL($preview['Preview']['id'], $type);
+ }
+
+ /**
+ * Gets the URL for the specified preview
+ * @param int $preview_id id of the preview
+ * @param string $type type of preview -- full or thumbnail
+ * @return string the URL
+ */
+ function getPreviewURL($preview_id, $type = 'thumbnail') {
+ // Make sure preview model is loaded
+ $this->_loadPreviewModel();
+
+ if ($type == 'full') {
+ $type = array(
+ 'type' => 'full',
+ 'url' => 'p',
+ 'field' => 'filetype'
+ );
+ }
+ elseif ($type == 'thumbnail') {
+ $type = array(
+ 'type' => 'thumbnail',
+ 'url' => 't',
+ 'field' => 'thumbtype'
+ );
+ }
+
+ $preview = $this->controller->Preview->findById($preview_id, array($type['field'], 'modified'));
+
+ if (empty($preview['Preview'][$type['field']])) {
+ return "{$this->controller->base}/img/no-preview.png";
+ }
+ else {
+ // Always use en-US and firefox and append modified timestamp for
+ // best caching results. Serves 150-200 million. Refrigerate after serving.
+ return "{$this->controller->base}/en-US/firefox/images/{$type['url']}/{$preview_id}/".strtotime($preview['Preview']['modified']);
+ }
+ }
+
+ /**
+ * Loads the Preview model if it's not already loaded
+ */
+ function _loadPreviewModel() {
+ if (!isset($this->controller->Preview)) {
+ loadModel('Preview');
+ $this->controller->Preview = new Preview();
+ }
+ }
+
+ /**
+ * Deprecated; do not use.
+ * @deprecated
+ */
+ function LEGACY_renderAddonPreview($addon, $previewNum) {
+ $entry = $this->controller->Preview->findAll(array("Addon_id" => $addon),
+ array("filedata", "filetype"),
+ "Preview.highlight DESC, Preview.id ASC", 1, $previewNum, null);
+ $entry = $entry[0]['Preview'];
+
+ $this->renderImage($entry['filedata'], $entry['filetype']);
+ }
+
+ /**
+ * Deprecated; do not use.
+ * @deprecated
+ */
+ function LEGACY_renderAddonThumbnail($addon, $previewNum) {
+ $entry = $this->controller->Preview->findAll(array("Addon_id" => $addon),
+ array("thumbdata", "thumbtype"),
+ "Preview.highlight DESC, Preview.id ASC", 1, $previewNum, null);
+ $entry = $entry[0]['Preview'];
+
+ $this->renderImage($entry['thumbdata'], $entry['thumbtype']);
+ }
+}
+?>
diff --git a/site/app/controllers/components/includes/rdf_parser.php b/site/app/controllers/components/includes/rdf_parser.php
new file mode 100644
index 0000000..7b6b249
--- /dev/null
+++ b/site/app/controllers/components/includes/rdf_parser.php
@@ -0,0 +1,1639 @@
+<?php
+// ##################################################################################
+// Title : Class Rdf_parser
+// Version : 1.0
+// Author : Jason Diammond -repat RDF parser-
+// : Luis Argerich -PHP version of repat- (lrargerich@yahoo.com)
+// Last modification date : 06-13-2002
+// Description : A port to PHP of the Repat an RDF parser.
+// This parser based on expat parses RDF files producing events
+// proper of RDF documents.
+// ##################################################################################
+// History:
+// 06-13-2002 : First version of this class.
+// 07-17-2002 Minor bugfix (Leandro Mariano Lopez)
+// 08-16-2006 Allowed for user callback function to be in a class
+// (Justin Scott)
+// ##################################################################################
+// To-Dos:
+//
+// ##################################################################################
+// How to use it:
+// Read the documentation in rdf_parser.html
+// ##################################################################################
+
+if(defined("_class_rdf_is_included")) {
+ // do nothing since the class is already included
+} else {
+ define("_class_rdf_is_included",1);
+
+/* First we define some constants */
+define("XML_NAMESPACE_URI","http://www.w3.org/XML/1998/namespace" );
+define("XML_LANG","lang");
+define("RDF_NAMESPACE_URI","http://www.w3.org/1999/02/22-rdf-syntax-ns#" );
+define("RDF_RDF","RDF");
+define("RDF_DESCRIPTION","Description");
+define("RDF_ID","ID");
+define("RDF_ABOUT","about");
+define("RDF_ABOUT_EACH","aboutEach");
+define("RDF_ABOUT_EACH_PREFIX","aboutEachPrefix");
+define("RDF_BAG_ID","bagID");
+define("RDF_RESOURCE","resource");
+define("RDF_VALUE","value");
+define("RDF_PARSE_TYPE","parseType");
+define("RDF_PARSE_TYPE_LITERAL","Literal");
+define("RDF_PARSE_TYPE_RESOURCE","Resource");
+define("RDF_TYPE","type");
+define("RDF_BAG","Bag");
+define("RDF_SEQ","Seq");
+define("RDF_ALT","Alt");
+define("RDF_LI","li");
+define("RDF_STATEMENT","Statement");
+define("RDF_SUBJECT","subject");
+define("RDF_PREDICATE","predicate");
+define("RDF_OBJECT","object");
+
+define("NAMESPACE_SEPARATOR_CHAR",'^');
+define("NAMESPACE_SEPARATOR_STRING","^");
+//define("FALSE",0);
+//define("TRUE",1);
+define("IN_TOP_LEVEL",0);
+define("IN_RDF",1);
+define("IN_DESCRIPTION",2);
+define("IN_PROPERTY_UNKNOWN_OBJECT",3);
+define("IN_PROPERTY_RESOURCE",4);
+define("IN_PROPERTY_EMPTY_RESOURCE",5);
+define("IN_PROPERTY_LITERAL",6);
+define("IN_PROPERTY_PARSE_TYPE_LITERAL",7);
+define("IN_PROPERTY_PARSE_TYPE_RESOURCE",8);
+define("IN_XML",9);
+define("IN_UNKNOWN",10);
+//define("IN_PROPERTY_PARSE_TYPE_LITERAL",9);
+
+define("RDF_SUBJECT_TYPE_URI",0);
+define("RDF_SUBJECT_TYPE_DISTRIBUTED",1);
+define("RDF_SUBJECT_TYPE_PREFIX",2);
+define("RDF_SUBJECT_TYPE_ANONYMOUS",3);
+
+define("RDF_OBJECT_TYPE_RESOURCE",0);
+define("RDF_OBJECT_TYPE_LITERAL",1);
+define("RDF_OBJECT_TYPE_XML",2);
+
+class Rdf_parser {
+
+var $rdf_parser;
+
+/* Private Methods */
+
+function _new_element()
+{
+ $e["parent"]=Array(); // Parent is a blank Array
+ //$this->clear_element($e["parent"]);
+ $e["state"]=0;
+ $e["has_property_atributes"]=0;
+ $e["has_member_attributes"]=0;
+ $e["subject_type"]=0;
+ $e["subject"]='';
+ $e["predicate"]='';
+ $e["ordinal"]=0;
+ $e["members"]=0;
+ $e["data"]='';
+ $e["xml_lang"]='';
+ $e["bag_id"]='';
+ $e["statements"]=0;
+ $e["statement_id"]='';
+
+ return $e;
+}
+
+function _copy_element($source, &$destination )
+{
+ if( $source )
+ {
+ $destination["parent"] = $source;
+ $destination["state"] = $source["state"];
+ $destination["xml_lang"] = $source["xml_lang"];
+ }
+}
+
+function _clear_element(&$e)
+{
+ $e["subject"]='';
+ $e["predicate"]='';
+ $e["data"]='';
+ $e["bag_id"]='';
+ $e["statement_id"]='';
+
+ if(isset($e["parent"])) {
+ if( $e["parent"] )
+ {
+ if( $e["parent"]["xml_lang"] != $e["xml_lang"] )
+ {
+ $e["xml_lang"]='';
+ }
+ }
+ else
+ {
+ $e["xml_lang"]='';
+ }
+ } else {
+ $e["xml_lang"]='';
+ }
+ //memset( e, 0, strlen( _rdf_element ) );
+ $e["parent"]=Array();
+ $e["state"]=0;
+ $e["has_property_attributes"]=0;
+ $e["has_member_attributes"]=0;
+ $e["subject_type"]=0;
+ $e["subject"]='';
+ $e["predicate"]='';
+ $e["ordinal"]=0;
+ $e["members"]=0;
+ $e["data"]='';
+ $e["xml_lang"]='';
+ $e["bag_id"]='';
+ $e["statements"]=0;
+ $e["statement_id"]='';
+
+}
+
+function _push_element()
+{
+ if(!isset($this->rdf_parser["free"])) {
+ $this->rdf_parser["free"]=Array();
+ }
+ if(count($this->rdf_parser["free"])>0)
+ {
+ $e = $this->rdf_parser["free"];
+ if(isset($e["parent"])) {
+ $this->rdf_parser["free"] = $e["parent"];
+ } else {
+ $this->rdf_parser["free"]=$this->_new_element();
+ }
+ }
+ else
+ {
+ $e = $this->_new_element();
+ }
+ if(!isset($this->rdf_parser["top"])) {
+ $this->rdf_parser["top"]=Array();
+ }
+ $this->_copy_element( $this->rdf_parser["top"], $e );
+ $this->rdf_parser["top"] = $e;
+}
+
+
+function _pop_element()
+{
+ $e = $this->rdf_parser["top"];
+ $this->rdf_parser["top"] = $e["parent"];
+ $this->_clear_element( $e );
+ /*
+ if(isset($this->rdf_parser["free"])) {
+ $e["parent"] = $this->rdf_parser["free"];
+ } else {
+ $e["parent"]=0;
+ }
+ */
+ $this->rdf_parser["free"] = $e;
+}
+
+function _delete_elements()
+{
+}
+
+
+function _is_rdf_property_attribute_resource($local_name )
+{
+ return ( $local_name == RDF_TYPE );
+}
+
+function _is_rdf_property_attribute_literal($local_name )
+{
+ return ( $local_name == RDF_VALUE );
+}
+
+function _is_rdf_ordinal( $local_name )
+{
+ $ordinal = -1;
+
+ //if($local_name{0}=='_')
+ if( $local_name{0} == '_' )
+ {
+ $ordinal = substr($local_name,1) + 1 ;
+ }
+
+ return ( $ordinal > 0 ) ? $ordinal : 0;
+}
+
+function _is_rdf_property_attribute( $local_name )
+{
+ return $this->_is_rdf_property_attribute_resource( $local_name )
+ || $this->_is_rdf_property_attribute_literal( $local_name );
+}
+
+function _is_rdf_property_element( $local_name )
+{
+ return ( $local_name == RDF_TYPE )
+ || ( $local_name == RDF_SUBJECT )
+ || ( $local_name == RDF_PREDICATE )
+ || ( $local_name == RDF_OBJECT )
+ || ( $local_name == RDF_VALUE )
+ || ( $local_name == RDF_LI )
+ || ( $local_name{0} == '_' );
+}
+
+function _istalnum($val) {
+ return ereg("[A-Za-z0-9]",$val);
+}
+
+function _istalpha($val) {
+ return ereg("[A-Za-z]",$val);
+}
+
+
+function _is_absolute_uri($uri )
+{
+ $result = false;
+ $uri_p=0;
+ if( $uri && $this->_istalpha( $uri{$uri_p} ) )
+ {
+ ++$uri_p;
+
+ while( ($uri_p<strlen($uri))
+ && ( $this->_istalnum( $uri{$uri_p} )
+ || ( $uri{$uri_p} == '+' )
+ || ( $uri{$uri_p} == '-' )
+ || ( $uri{$uri_p} == '.' ) ) )
+ {
+ ++$uri_p;
+ }
+
+ $result = ( $uri{$uri_p} == ':' );
+ }
+ return $result;
+}
+
+
+/*
+This function returns an associative array returning any of the various components of the URL that are present. This includes the
+$arr=parse_url($url)
+scheme - e.g. http
+host
+port
+user
+pass
+path
+query - after the question mark ?
+fragment - after the hashmark #
+*/
+function _parse_uri($uri,$buffer,$len,&$scheme,&$authority,&$path,&$query,&$fragment ) {
+ $parsed=parse_url($uri);
+ if(isset($parsed["scheme"])) {
+ $scheme=$parsed["scheme"];} else {
+ $scheme='';
+ }
+ if(isset($parsed["host"])) {
+ $host=$parsed["host"];} else {
+ $host='';
+ }
+ if(isset($parsed["host"])) {
+ $authority=$parsed["host"];} else {
+ $authority='';
+ }
+ if(isset($parsed["path"])) {
+ $path=$parsed["path"];} else {
+ $path='';
+ }
+ if(isset($parsed["query"])) {
+ $query=$parsed["query"];} else {
+ $query='';
+ }
+ if(isset($parsed["fragment"])) {
+ $fragment=$parsed["fragment"];} else {
+ $fragment='';
+ }
+
+}
+
+
+function _resolve_uri_reference($base_uri,$reference_uri,&$buffer,$length )
+{
+ $base_buffer='';
+ $reference_buffer='';
+ $path_buffer='';
+
+ $buffer = '';
+
+ $this->_parse_uri($reference_uri,$reference_buffer,strlen( $reference_buffer ),$reference_scheme,$reference_authority,
+ $reference_path,$reference_query,$reference_fragment );
+
+ if( $reference_scheme == ''
+ && $reference_authority == ''
+ && $reference_path == ''
+ && $reference_query == '' )
+ {
+ $buffer=$base_uri;
+
+ if( $reference_fragment != '' )
+ {
+ $buffer.= "#" ;
+ $buffer.=$reference_fragment;
+ }
+ }
+ else if( $reference_scheme != '' )
+ {
+ $buffer=$reference_uri;
+ }
+ else
+ {
+ $this->_parse_uri(
+ $base_uri,
+ $base_buffer,
+ strlen( $base_buffer ),
+ $base_scheme,
+ $base_authority,
+ $base_path,
+ $base_query,
+ $base_fragment );
+
+ $result_scheme = $base_scheme;
+
+ if( $reference_authority != '' )
+ {
+ $result_authority = $reference_authority;
+ }
+ else
+ {
+ $result_authority = $base_authority;
+
+ if( $reference_path != ''
+ && ( ($reference_path{0} == '/')
+ || ($reference_path{0} == '\\') ) )
+ {
+ $result_path = $reference_path;
+ }
+ else
+ {
+ $p = '';
+
+ $result_path = $path_buffer;
+
+ $path_buffer='';
+
+ $p = strstr( $base_path, '/' );
+
+ if( !$p )
+ {
+ $p = strstr( $base_path, '\\' );
+ }
+
+ if( $p )
+ {
+
+ $path_buffer.=$base_path;
+
+ //while( s <= p )
+ //{
+ // *d++ = *s++;
+ //}
+
+ //*d++ = 0;
+
+ }
+
+ if( $reference_path != '' )
+ {
+ $path_buffer.=$reference_path;
+ }
+
+ {
+ //remove all occurrences of "./"
+ //print($path_buffer);
+ $path_buffer=preg_replace("/\/\.\//","/",$path_buffer);
+ $path_buffer=preg_replace("/\/([^\/\.])*\/..$/","/",$path_buffer);
+ while(preg_match("/\.\./",$path_buffer)) {
+ $path_buffer=preg_replace("/\/([^\/\.]*)\/..\//","/",$path_buffer);
+ }
+ $path_buffer=preg_replace("/\.$/","",$path_buffer);
+
+ }
+
+ }
+ }
+
+ // This replaces the C pointer assignament
+
+ $result_path = $path_buffer;
+ if( $result_scheme != '' )
+ {
+ $buffer=$result_scheme;
+ $buffer.=":";
+ }
+
+ if( $result_authority != '' )
+ {
+ $buffer.="//";
+ $buffer.=$result_authority;
+ }
+
+ if( $result_path != '' )
+ {
+
+ $buffer.=$result_path;
+ }
+
+ if( $reference_query != '' )
+ {
+ $buffer.="?";
+ $buffer.=$reference_query;
+ }
+
+ if( $reference_fragment != '' )
+ {
+ $buffer.="#";
+ $buffer.=$reference_fragment;
+ }
+ }
+}
+
+
+
+function is_valid_id($id )
+{
+ $result = false;
+ $p = $id;
+ $p_p=0;
+
+ if( $id != '' )
+ {
+ if( $this->_istalpha( $p )
+ || $p{0} == '_'
+ || $p{0} == ':' )
+ {
+ $result = true;
+
+ while( $result != false && ( $p{++$p_p} != 0 ) )
+ {
+ if( ! ( $this->_istalnum( $p{$p_p} )
+ || $p{$p_p} == '.'
+ || $p{$p_p} == '-'
+ || $p{$p_p} == '_'
+ || $p{$p_p} == ':' ) )
+ {
+ $result = false;
+ }
+ }
+ }
+ }
+
+ return $result;
+}
+
+function _resolve_id($id,&$buffer,$length )
+{
+ $id_buffer='';
+
+ if( $this->is_valid_id( $id ) == true )
+ {
+ $id_buffer="#$id";
+ }
+ else
+ {
+ $this->report_warning( "bad ID attribute: ".$id_buffer."#_bad_ID_attribute_");
+ }
+
+ $this->_resolve_uri_reference( $this->rdf_parser["base_uri"], $id_buffer, $buffer, $length );
+}
+
+function _split_name($name, &$buffer, $len,&$namespace_uri, &$local_name )
+{
+
+ static $nul = 0;
+ $buffer=$name;
+
+
+
+
+ if( strstr( $buffer, NAMESPACE_SEPARATOR_CHAR ) )
+ {
+ $cosas=explode(NAMESPACE_SEPARATOR_CHAR,$buffer);
+ $namespace_uri = $cosas[0];
+ $local_name = $cosas[1];
+ }
+ else
+ {
+ if( ( $buffer{ 0 } == 'x' )
+ && ( $buffer{ 1 } == 'm' )
+ && ( $buffer{ 2 } == 'l' )
+ && ( $buffer{ 3 } == ':' ) )
+ {
+ $namespace_uri = XML_NAMESPACE_URI;
+ $local_name = substr($buffer,4);
+ }
+ else
+ {
+ $namespace_uri = '';
+ $local_name = $buffer;
+ }
+ }
+
+
+}
+
+function _generate_anonymous_uri(&$buf, $len )
+{
+ $id='';
+ if(!isset($this->rdf_parser["anonymous_id"])) {
+ $this->rdf_parser["anonymous_id"]=0;
+ }
+ $this->rdf_parser["anonymous_id"]++;
+
+ $id="#genid".$this->rdf_parser["anonymous_id"];
+ $this->_resolve_uri_reference( $this->rdf_parser["base_uri"], $id, $buf, $len );
+
+}
+
+function _report_statement( $subject_type, $subject, $predicate, $ordinal, $object_type, $object, $xml_lang, $bag_id, $statements, $statement_id )
+{
+ $statement_id_type = RDF_SUBJECT_TYPE_URI;
+ $statement_id_buffer='';
+ $predicate_buffer='';
+
+ if( $this->rdf_parser["statement_handler"] )
+ {
+ $this->rdf_parser["user_data"] = call_user_func($this->rdf_parser["statement_handler"], $this->rdf_parser["user_data"], $subject_type, $subject, $predicate, $ordinal, $object_type, $object, $xml_lang);
+ // $this->rdf_parser["statement_handler"]($this->rdf_parser["user_data"],$subject_type,$subject,$predicate,$ordinal,$object_type,$object,$xml_lang )
+ if( $bag_id )
+ {
+ if( $statements == '' )
+ {
+ $this->_report_statement(RDF_SUBJECT_TYPE_URI,
+ $bag_id,
+ RDF_NAMESPACE_URI.RDF_TYPE,
+ 0,
+ RDF_OBJECT_TYPE_RESOURCE,
+ RDF_NAMESPACE_URI.RDF_BAG,
+ '',
+ '',
+ '',
+ '' );
+ }
+
+ if( ! $statement_id )
+ {
+ $statement_id_type = RDF_SUBJECT_TYPE_ANONYMOUS;
+ $this->_generate_anonymous_uri(
+ $statement_id_buffer,
+ strlen( $statement_id_buffer ) );
+ $statement_id = $statement_id_buffer;
+ }
+ $statements++;
+ $predicate_buffer="RDF_NAMESPACE_URI_".$statements;
+
+ $this->_report_statement(
+ RDF_SUBJECT_TYPE_URI,
+ $bag_id,
+ $predicate_buffer,
+ $statements,
+ RDF_OBJECT_TYPE_RESOURCE,
+ $statement_id,
+ '',
+ '',
+ '',
+ '' );
+ }
+
+ if( $statement_id )
+ {
+ // rdf:type = rdf:Statement
+ $this->_report_statement(
+ $statement_id_type,
+ $statement_id,
+ RDF_NAMESPACE_URI.RDF_TYPE,
+ 0,
+ RDF_OBJECT_TYPE_RESOURCE,
+ RDF_NAMESPACE_URI.RDF_STATEMENT,
+ '',
+ '',
+ '',
+ '' );
+
+ // rdf:subject
+ $this->_report_statement(
+ $statement_id_type,
+ $statement_id,
+ RDF_NAMESPACE_URI.RDF_SUBJECT,
+ 0,
+ RDF_OBJECT_TYPE_RESOURCE,
+ $subject,
+ '',
+ '',
+ '',
+ '' );
+
+ // rdf:predicate
+ $this->_report_statement(
+ $statement_id_type,
+ $statement_id,
+ RDF_NAMESPACE_URI.RDF_PREDICATE,
+ 0,
+ RDF_OBJECT_TYPE_RESOURCE,
+ $predicate,
+ '',
+ '',
+ '',
+ '' );
+
+ // rdf:object
+ $this->_report_statement(
+ $statement_id_type,
+ $statement_id,
+ RDF_NAMESPACE_URI.RDF_OBJECT,
+ 0,
+ $object_type,
+ $object,
+ '',
+ '',
+ '',
+ '' );
+ }
+ }
+}
+
+function _report_start_parse_type_literal()
+{
+ if( $this->rdf_parser["start_parse_type_literal_handler"] )
+ {
+ $this->rdf_parser["start_parse_type_literal_handler"](
+ $this->rdf_parser["user_data"] );
+ }
+}
+
+function _report_end_parse_type_literal()
+{
+ if( $this->rdf_parser["end_parse_type_literal_handler"] )
+ {
+ $this->rdf_parser["end_parse_type_literal_handler"](
+ $this->rdf_parser["user_data"] );
+ }
+}
+
+function _handle_property_attributes($subject_type, $subject, $attributes, $xml_lang, $bag_id, $statements )
+{
+ $i=0;
+
+ $attribute='';
+ $predicate='';
+
+ $attribute_namespace_uri='';
+ $attribute_local_name='';
+ $attribute_value='';
+
+ $ordinal=0;
+
+ for( $i = 0; isset($attributes[ $i ]); $i += 2 )
+ {
+ $this->_split_name(
+ $attributes[ $i ],
+ $attribute,
+ strlen( $attribute ),
+ $attribute_namespace_uri,
+ $attribute_local_name );
+
+ $attribute_value = $attributes[ $i + 1 ];
+
+ $predicate=$attribute_namespace_uri;
+ $predicate.=$attribute_local_name;
+
+ if( RDF_NAMESPACE_URI == $attribute_namespace_uri )
+ {
+ if( $this->_is_rdf_property_attribute_literal( $attribute_local_name ) )
+ {
+ $this->_report_statement(
+ $subject_type,
+ $subject,
+ $predicate,
+ 0,
+ RDF_OBJECT_TYPE_LITERAL,
+ $attribute_value,
+ $xml_lang,
+ $bag_id,
+ $statements,
+ '' );
+ }
+ else if( $this->_is_rdf_property_attribute_resource( $attribute_local_name ) )
+ {
+ $this->_report_statement(
+ $subject_type,
+ $subject,
+ $predicate,
+ 0,
+ RDF_OBJECT_TYPE_RESOURCE,
+ $attribute_value,
+ '',
+ $bag_id,
+ $statements,
+ '' );
+ }
+ else if( ( $ordinal = $this->_is_rdf_ordinal( $attribute_local_name ) ) != 0 )
+ {
+ $this->_report_statement(
+ $subject_type,
+ $subject,
+ $predicate,
+ $ordinal,
+ RDF_OBJECT_TYPE_LITERAL,
+ $attribute_value,
+ $xml_lang,
+ $bag_id,
+ $statements,
+ '' );
+ }
+ }
+ else if( XML_NAMESPACE_URI == $attribute_namespace_uri )
+ {
+ //do nothing
+ }
+ else if( $attribute_namespace_uri )
+ {
+ // is it required that property attributes be in an explicit namespace?
+
+ $this->_report_statement(
+ $subject_type,
+ $subject,
+ $predicate,
+ 0,
+ RDF_OBJECT_TYPE_LITERAL,
+ $attribute_value,
+ $xml_lang,
+ $bag_id,
+ $statements,
+ '' );
+ }
+ }
+}
+
+function _report_start_element( $name, $attributes )
+{
+ if( isset($this->rdf_parser["start_element_handler"]) )
+ {
+ $this->rdf_parser["start_element_handler"](
+ $this->rdf_parser["user_data"],
+ $name,
+ $attributes );
+ }
+}
+
+function _report_end_element( $name )
+{
+ if( isset($this->rdf_parser["end_element_handler"]) )
+ {
+ $this->rdf_parser["end_element_handler"](
+ $this->rdf_parser["user_data"],
+ $name );
+ }
+}
+
+function _report_character_data($s,$len )
+{
+ if( isset($this->rdf_parser["character_data_handler"]) )
+ {
+ $this->rdf_parser["character_data_handler"](
+ $this->rdf_parser["user_data"],
+ $s,
+ $len );
+ }
+}
+
+function _report_warning( $warning)
+{
+
+ // rdf_parser->top->state = IN_UNKNOWN;
+
+ if( isset($this->rdf_parser["warning_handler"]) )
+ {
+ $this->rdf_parser["warning_handler"] (
+ $warning);
+ }
+}
+
+function _handle_resource_element( $namespace_uri, $local_name, $attributes, $parent )
+{
+ $subjects_found = 0;
+ $aux=$attributes;
+ $aux2=Array();
+ foreach($attributes as $atkey=>$atvalue) {
+ $aux2[]=$atkey;
+ $aux2[]=$atvalue;
+ }
+ $attributes=$aux2;
+ $id = '';
+ $about = '';
+ $about_each = '';
+ $about_each_prefix = '';
+
+ $bag_id = '';
+
+ $i=0;
+
+ $attribute='';
+
+ $attribute_namespace_uri='';
+ $attribute_local_name='';
+ $attribute_value='';
+
+ $id_buffer='';
+
+ $type='';
+
+ $this->rdf_parser["top"]["has_property_attributes"] = false;
+ $this->rdf_parser["top"]["has_member_attributes"] = false;
+
+ // examine each attribute for the standard RDF "keywords"
+ for( $i = 0; isset($attributes[$i]); $i += 2 )
+ {
+ $this->_split_name(
+ $attributes[ $i ],
+ $attribute,
+ strlen( $attribute ),
+ $attribute_namespace_uri,
+ $attribute_local_name );
+
+ $attribute_value = $attributes[ $i + 1 ];
+
+ // if the attribute is not in any namespace
+ // or the attribute is in the RDF namespace
+ if( ( $attribute_namespace_uri == '' )
+ || ( $attribute_namespace_uri == RDF_NAMESPACE_URI ))
+ {
+ if( $attribute_local_name == RDF_ID )
+ {
+ $id = $attribute_value;
+ ++$subjects_found;
+ }
+ else if( $attribute_local_name == RDF_ABOUT )
+ {
+ $about = $attribute_value;
+ ++$subjects_found;
+ }
+ else if( $attribute_local_name == RDF_ABOUT_EACH )
+ {
+ $about_each = $attribute_value;
+ ++$subjects_found;
+ }
+ else if( $attribute_local_name == RDF_ABOUT_EACH_PREFIX )
+ {
+ $about_each_prefix = $attribute_value;
+ ++$subjects_found;
+ }
+ else if( $attribute_local_name == RDF_BAG_ID)
+ {
+ $bag_id = $attribute_value;
+ }
+ else if( $this->_is_rdf_property_attribute( $attribute_local_name ) )
+ {
+ $this->rdf_parser["top"]["has_property_attributes"] = true;
+ }
+ else if( $this->_is_rdf_ordinal( $attribute_local_name ) )
+ {
+ $this->rdf_parser["top"]["has_property_attributes"] = true;
+ $this->rdf_parser["top"]["has_member_attributes"] = true;
+ }
+ else
+ {
+ $this->_report_warning(
+ "unknown or out of context rdf attribute:".$attribute_local_name );
+ }
+ }
+ else if( $attribute_namespace_uri == XML_NAMESPACE_URI )
+ {
+ if( $attribute_local_name == XML_LANG )
+ {
+ $this->rdf_parser["top"]["xml_lang"] = $attribute_value;
+ }
+ }
+ else if( $attribute_namespace_uri )
+ {
+ $this->rdf_parser["top"]["has_property_attributes"] = true;
+ }
+ }
+
+ // if no subjects were found, generate one.
+ if( $subjects_found == 0 )
+ {
+ $this->_generate_anonymous_uri( $id_buffer, strlen( $id_buffer ) );
+ $this->rdf_parser["top"]["subject"]=$id_buffer;
+ $this->rdf_parser["top"]["subject_type"] = RDF_SUBJECT_TYPE_ANONYMOUS;
+ }
+ else if( $subjects_found > 1 )
+ {
+ $this->_report_warning(
+ "ID, about, aboutEach, and aboutEachPrefix are mutually exclusive" );
+ return;
+ }
+ else if( $id )
+ {
+ $this->_resolve_id( $id, $id_buffer, strlen( $id_buffer ) );
+ $this->rdf_parser["top"]["subject_type"] = RDF_SUBJECT_TYPE_URI;
+ $this->rdf_parser["top"]["subject"]=$id_buffer;
+ }
+ else if( $about )
+ {
+ $this->_resolve_uri_reference( $this->rdf_parser["base_uri"], $about, $id_buffer, strlen( $id_buffer ) );
+ $this->rdf_parser["top"]["subject_type"] = RDF_SUBJECT_TYPE_URI;
+ $this->rdf_parser["top"]["subject"]=$id_buffer;
+ }
+ else if( $about_each )
+ {
+ $this->rdf_parser["top"]["subject_type"] = RDF_SUBJECT_TYPE_DISTRIBUTED;
+ $this->rdf_parser["top"]["subject"]=$about_each;
+ }
+ else if( $about_each_prefix )
+ {
+ $this->rdf_parser["top"]["subject_type"] = RDF_SUBJECT_TYPE_PREFIX;
+ $this->rdf_parser["top"]["subject"]=$about_each_prefix;
+ }
+
+ // if the subject is empty, assign it the document uri
+ if( $this->rdf_parser["top"]["subject"] == '' )
+ {
+ $len = 0;
+
+ $this->rdf_parser["top"]["subject"]=$this->rdf_parser["base_uri"];
+
+ // now remove the trailing '#'
+
+ $len = strlen( $this->rdf_parser["top"]["subject"]);
+
+ if( $len > 0 )
+ {
+ //$rdf_parser["top"]["subject"][" len - 1 "] = 0;
+ }
+ }
+
+ if( $bag_id )
+ {
+ $this->_resolve_id( $bag_id, $id_buffer, strlen( $id_buffer ) );
+ $this->rdf_parser["top"]["bag_id"]=$id_buffer;
+ }
+
+ // only report the type for non-rdf:Description elements.
+ if( ($local_name != RDF_DESCRIPTION )
+ || ( $namespace_uri != RDF_NAMESPACE_URI ) )
+ {
+ $type=$namespace_uri;
+ $type.=$local_name;
+
+ $this->_report_statement(
+ $this->rdf_parser["top"]["subject_type"],
+ $this->rdf_parser["top"]["subject"],
+ RDF_NAMESPACE_URI.RDF_TYPE,
+ 0,
+ RDF_OBJECT_TYPE_RESOURCE,
+ $type,
+ '',
+ $this->rdf_parser["top"]["bag_id"],
+ $this->rdf_parser["top"]["statements"],
+ '' );
+
+ }
+
+ // if this element is the child of some property,
+ // report the appropriate statement.
+ if( $parent )
+ {
+ $this->_report_statement(
+ $parent["parent"]["subject_type"],
+ $parent["parent"]["subject"],
+ $parent["predicate"],
+ $parent["ordinal"],
+ RDF_OBJECT_TYPE_RESOURCE,
+ $this->rdf_parser["top"]["subject"],
+ '',
+ $parent["parent"]["bag_id"],
+ $parent["parent"]["statements"],
+ $parent["statement_id"] );
+
+ }
+
+ if( $this->rdf_parser["top"]["has_property_attributes"] )
+ {
+ $this->_handle_property_attributes(
+ $this->rdf_parser["top"]["subject_type"],
+ $this->rdf_parser["top"]["subject"],
+ $attributes,
+ $this->rdf_parser["top"]["xml_lang"],
+ $this->rdf_parser["top"]["bag_id"],
+ $this->rdf_parser["top"]["statements"] );
+ }
+}
+
+function _handle_property_element( &$namespace_uri, &$local_name, &$attributes )
+{
+ $buffer='';
+
+ $i=0;
+
+ $aux=$attributes;
+ $aux2=Array();
+ foreach($attributes as $atkey=>$atvalue) {
+ $aux2[]=$atkey;
+ $aux2[]=$atvalue;
+ }
+ $attributes=$aux2;
+
+ $attribute_namespace_uri='';
+ $attribute_local_name='';
+ $attribute_value = '';
+
+ $resource = '';
+ $statement_id = '';
+ $bag_id = '';
+ $parse_type = '';
+
+ $this->rdf_parser["top"]["ordinal"] = 0;
+
+ if( $namespace_uri == RDF_NAMESPACE_URI )
+ {
+ if( ($this->rdf_parser["top"]["ordinal"] = ( $this->_is_rdf_ordinal( $local_name ) ) != 0 ) )
+ {
+ if( $this->rdf_parser["top"]["ordinal"] > $this->rdf_parser["top"]["parent"]["members"] )
+ {
+ $this->rdf_parser["top"]["parent"]["members"] = $this->rdf_parser["top"]["ordinal"];
+ }
+ }
+ else if( ! $this->_is_rdf_property_element( $local_name ) )
+ {
+ $this->_report_warning(
+ "unknown or out of context rdf property element: ".$local_name );
+ return;
+ }
+ }
+
+ $buffer=$namespace_uri;
+
+ if( ( $namespace_uri == RDF_NAMESPACE_URI )
+ && ( $local_name == RDF_LI ) )
+ {
+ //$ordinal='';
+ $this->rdf_parser["top"]["parent"]["members"]++;
+ $this->rdf_parser["top"]["ordinal"] = $this->rdf_parser["top"]["parent"]["members"];
+
+
+ $this->rdf_parser["top"]["ordinal"]=$this->rdf_parser["top"]["ordinal"];
+ //$ordinal{ 0 } = '_' ;
+
+ $buffer.='_'.$this->rdf_parser["top"]["ordinal"];
+ }
+ else
+ {
+ $buffer.=$local_name;
+ }
+
+ $this->rdf_parser["top"]["predicate"]=$buffer;
+
+ $this->rdf_parser["top"]["has_property_attributes"] = false;
+ $this->rdf_parser["top"]["has_member_attributes"] = false;
+
+ for( $i = 0; isset($attributes[$i]); $i += 2 )
+ {
+ $this->_split_name(
+ $attributes[$i],
+ $buffer,
+ strlen( $buffer ),
+ $attribute_namespace_uri,
+ $attribute_local_name );
+
+ $attribute_value = $attributes[$i + 1];
+
+ // if the attribute is not in any namespace
+ // or the attribute is in the RDF namespace
+ if( ( $attribute_namespace_uri == '' )
+ || ( $attribute_namespace_uri == RDF_NAMESPACE_URI ) )
+ {
+ if( ( $attribute_local_name == RDF_ID ) )
+ {
+ $statement_id = $attribute_value;
+ }
+ else if( $attribute_local_name == RDF_PARSE_TYPE )
+ {
+ $parse_type = $attribute_value;
+ }
+ else if( $attribute_local_name == RDF_RESOURCE )
+ {
+ $resource = $attribute_value;
+ }
+ else if( $attribute_local_name == RDF_BAG_ID )
+ {
+ $bag_id = $attribute_value;
+ }
+ else if( $this->_is_rdf_property_attribute( $attribute_local_name ) )
+ {
+ $this->rdf_parser["top"]["has_property_attributes"] = true;
+ }
+ else
+ {
+ $this->_report_warning(
+ "unknown rdf attribute: ".$attribute_local_name );
+ return;
+ }
+ }
+ else if( $attribute_namespace_uri == XML_NAMESPACE_URI )
+ {
+ if( $attribute_local_name == XML_LANG )
+ {
+ $this->rdf_parser["top"]["xml_lang"] = $attribute_value;
+ }
+ }
+ else if( $attribute_namespace_uri )
+ {
+ $this->rdf_parser["top"]["has_property_attributes"] = true;
+ }
+ }
+
+ // this isn't allowed by the M&S but I think it should be
+ if( $statement_id && $resource )
+ {
+ $this->_report_warning(
+ "rdf:ID and rdf:resource are mutually exclusive" );
+ return;
+ }
+
+ if( $statement_id )
+ {
+ $this->_resolve_id($statement_id, $buffer, strlen( $buffer ) );
+ $this->rdf_parser["top"]["statement_id"]=$buffer;
+ }
+
+ if( $parse_type )
+ {
+ if( $resource )
+ {
+ $this->_report_warning(
+ "property elements with rdf:parseType do not allow rdf:resource" );
+ return;
+ }
+
+ if( $bag_id )
+ {
+ $this->_report_warning(
+ "property elements with rdf:parseType do not allow rdf:bagID" );
+ return;
+ }
+
+ if( $this->rdf_parser["top"]["has_property_attributes"] )
+ {
+ $this->_report_warning(
+ "property elements with rdf:parseType do not allow property attributes");
+ return;
+ }
+
+ if( $attribute_value == RDF_PARSE_TYPE_RESOURCE )
+ {
+ $this->_generate_anonymous_uri( $buffer, strlen( $buffer ) );
+
+ // since we are sure that this is now a resource property we can report it
+ $this->_report_statement(
+ $this->rdf_parser["top"]["parent"]["subject_type"],
+ $this->rdf_parser["top"]["parent"]["subject"],
+ $this->rdf_parser["top"]["predicate"],
+ 0,
+ RDF_OBJECT_TYPE_RESOURCE,
+ $buffer,
+ '',
+ $this->rdf_parser["top"]["parent"]["bag_id"],
+ $this->rdf_parser["top"]["parent"]["statements"],
+ $statement_id );
+
+ $this->_push_element( );
+
+ $this->rdf_parser["top"]["state"] = IN_PROPERTY_PARSE_TYPE_RESOURCE;
+ $this->rdf_parser["top"]["subject_type"] = RDF_SUBJECT_TYPE_ANONYMOUS;
+ $this->rdf_parser["top"]["subject"]=$buffer;
+ $this->rdf_parser["top"]["bag_id"]='';
+ }
+ else
+ {
+ $this->_report_statement(
+ $this->rdf_parser["top"]["parent"]["subject_type"],
+ $this->rdf_parser["top"]["parent"]["subject"],
+ $this->rdf_parser["top"]["predicate"],
+ 0,
+ RDF_OBJECT_TYPE_XML,
+ '',
+ '',
+ $this->rdf_parser["top"]["parent"]["bag_id"],
+ $this->rdf_parser["top"]["parent"]["statements"],
+ $statement_id );
+
+ $this->rdf_parser["top"]["state"] = IN_PROPERTY_PARSE_TYPE_LITERAL;
+ $this->_report_start_parse_type_literal();
+ }
+ }
+ else if( $resource || $bag_id || $this->rdf_parser["top"]["has_property_attributes"] )
+ {
+
+
+ if( $resource != '' )
+ {
+ $subject_type = RDF_SUBJECT_TYPE_URI;
+ $this->_resolve_uri_reference( $this->rdf_parser["base_uri"], $resource, $buffer, strlen( $buffer ) );
+ }
+ else
+ {
+ $subject_type = RDF_SUBJECT_TYPE_ANONYMOUS;
+ $this->_generate_anonymous_uri( $buffer, strlen( $buffer ) );
+ }
+
+ $this->rdf_parser["top"]["state"] = IN_PROPERTY_EMPTY_RESOURCE;
+
+ // since we are sure that this is now a resource property we can report it.
+ $this->_report_statement(
+ $this->rdf_parser["top"]["parent"]["subject_type"],
+ $this->rdf_parser["top"]["parent"]["subject"],
+ $this->rdf_parser["top"]["predicate"],
+ $this->rdf_parser["top"]["ordinal"],
+ RDF_OBJECT_TYPE_RESOURCE,
+ $buffer,
+ '',
+ $this->rdf_parser["top"]["parent"]["bag_id"],
+ $this->rdf_parser["top"]["parent"]["statements"],
+ '' ); // should we allow IDs?
+
+ if( $bag_id )
+ {
+ $this->_resolve_id( $bag_id, $buffer, strlen( $buffer ) );
+ $this->rdf_parser["top"]["bag_id"]=$buffer;
+ }
+
+ if( $this->rdf_parser["top"]["has_property_attributes"] )
+ {
+ $this->_handle_property_attributes(
+ $subject_type,
+ $buffer,
+ $attributes,
+ $this->rdf_parser["top"]["xml_lang"],
+ $this->rdf_parser["top"]["bag_id"],
+ $this->rdf_parser["top"]["statements"] );
+ }
+ }
+}
+
+
+function _start_element_handler($parser, $name, $attributes )
+{
+
+
+ $buffer='';
+
+ $namespace_uri='';
+ $local_name='';
+
+/*
+ if( rdf_parser->top != '' && rdf_parser->top->state != IN_TOP_LEVEL )
+ {
+ ++rdf_parser->anonymous_id;
+ }
+*/
+
+ $this->_push_element();
+
+
+ $this->_split_name(
+ $name,
+ $buffer,
+ strlen( $buffer ),
+ $namespace_uri,
+ $local_name );
+
+ switch( $this->rdf_parser["top"]["state"] )
+ {
+ case IN_TOP_LEVEL:
+ if( RDF_NAMESPACE_URI.NAMESPACE_SEPARATOR_STRING.RDF_RDF == $name )
+ {
+ $this->rdf_parser["top"]["state"] = IN_RDF;
+ }
+ else
+ {
+ $this->_report_start_element( $name, $attributes );
+ }
+ break;
+ case IN_RDF:
+ $this->rdf_parser["top"]["state"] = IN_DESCRIPTION;
+ $this->_handle_resource_element( $namespace_uri, $local_name, $attributes, '' );
+ break;
+ case IN_DESCRIPTION:
+ case IN_PROPERTY_PARSE_TYPE_RESOURCE:
+ $this->rdf_parser["top"]["state"] = IN_PROPERTY_UNKNOWN_OBJECT;
+ $this->_handle_property_element( $namespace_uri, $local_name, $attributes );
+ break;
+ case IN_PROPERTY_UNKNOWN_OBJECT:
+ /* if we're in a property with an unknown object type and we encounter
+ an element, the object must be a resource, */
+ $this->rdf_parser["top"]["data"]='';
+ $this->rdf_parser["top"]["parent"]["state"] = IN_PROPERTY_RESOURCE;
+ $this->rdf_parser["top"]["state"] = IN_DESCRIPTION;
+ $this->_handle_resource_element(
+ $namespace_uri,
+ $local_name,
+ $attributes,
+ $this->rdf_parser["top"]["parent"] );
+ break;
+ case IN_PROPERTY_LITERAL:
+ $this->_report_warning( "no markup allowed in literals" );
+ break;
+ case IN_PROPERTY_PARSE_TYPE_LITERAL:
+ $this->rdf_parser["top"]["state"] = IN_XML;
+ /* fall through */
+ case IN_XML:
+ $this->_report_start_element( $name, $attributes );
+ break;
+ case IN_PROPERTY_RESOURCE:
+ $this->_report_warning(
+ "only one element allowed inside a property element" );
+ break;
+ case IN_PROPERTY_EMPTY_RESOURCE:
+ $this->_report_warning(
+ "no content allowed in property with rdf:resource, rdf:bagID, or property attributes" );
+ break;
+ case IN_UNKNOWN:
+ break;
+ }
+}
+
+/*
+ this is only called when we're in the IN_PROPERTY_UNKNOWN_OBJECT state.
+ the only time we won't know what type of object a statement has is
+ when we encounter property statements without property attributes or
+ content:
+
+ <foo:property />
+ <foo:property ></foo:property>
+ <foo:property> </foo:property>
+
+ notice that the state doesn't switch to IN_PROPERTY_LITERAL when
+ there is only whitespace between the start and end tags. this isn't
+ a very useful statement since the object is anonymous and can't
+ have any statements with it as the subject but it is allowed.
+*/
+
+function _end_empty_resource_property()
+{
+ $buffer='';
+
+ $this->_generate_anonymous_uri($buffer, strlen( $buffer ) );
+
+ $this->_report_statement(
+ $this->rdf_parser["top"]["parent"]["subject_type"],
+ $this->rdf_parser["top"]["parent"]["subject"],
+ $this->rdf_parser["top"]["predicate"],
+ $this->rdf_parser["top"]["ordinal"],
+ RDF_OBJECT_TYPE_RESOURCE,
+ $buffer,
+ $this->rdf_parser["top"]["xml_lang"],
+ $this->rdf_parser["top"]["parent"]["bag_id"],
+ $this->rdf_parser["top"]["parent"]["statements"],
+ $this->rdf_parser["top"]["statement_id"] );
+}
+
+/*
+ property elements with text only as content set the state to
+ IN_PROPERTY_LITERAL. as character data is received from expat,
+ it is saved in a buffer and reported when the end tag is
+ received.
+*/
+function _end_literal_property()
+{
+ if(!isset($this->rdf_parser["top"]["statement_id"])) {
+ $this->rdf_parser["top"]["statement_id"]='';
+ }
+ if(!isset($this->rdf_parser["top"]["parent"]["subject_type"])) {
+ $this->rdf_parser["top"]["parent"]["subject_type"]='';
+ }
+ if(!isset($this->rdf_parser["top"]["parent"]["subject"])) {
+ $this->rdf_parser["top"]["parent"]["subject"]='';
+ }
+ if(!isset($this->rdf_parser["top"]["parent"]["bag_id"])) {
+ $this->rdf_parser["top"]["parent"]["bag_id"]='';
+ }
+ if(!isset($this->rdf_parser["top"]["parent"]["statements"])) {
+ $this->rdf_parser["top"]["parent"]["statements"]=0;
+ }
+ if(!isset($this->rdf_parser["top"]["predicate"])) {
+ $this->rdf_parser["top"]["predicate"]='';
+ }
+ if(!isset($this->rdf_parser["top"]["ordinal"])) {
+ $this->rdf_parser["top"]["ordinal"]=0;
+ }
+ $this->_report_statement(
+ $this->rdf_parser["top"]["parent"]["subject_type"],
+ $this->rdf_parser["top"]["parent"]["subject"],
+ $this->rdf_parser["top"]["predicate"],
+ $this->rdf_parser["top"]["ordinal"],
+ RDF_OBJECT_TYPE_LITERAL,
+ $this->rdf_parser["top"]["data"],
+ $this->rdf_parser["top"]["xml_lang"],
+ $this->rdf_parser["top"]["parent"]["bag_id"],
+ $this->rdf_parser["top"]["parent"]["statements"],
+ $this->rdf_parser["top"]["statement_id"] );
+}
+
+function _end_element_handler( $parser, $name )
+{
+
+
+ switch( $this->rdf_parser["top"]["state"] )
+ {
+ case IN_TOP_LEVEL:
+ /* fall through */
+ case IN_XML:
+ $this->_report_end_element( $name );
+ break;
+ case IN_PROPERTY_UNKNOWN_OBJECT:
+ $this->_end_empty_resource_property();
+ break;
+ case IN_PROPERTY_LITERAL:
+ $this->_end_literal_property( );
+ break;
+ case IN_PROPERTY_PARSE_TYPE_RESOURCE:
+ $this->_pop_element( );
+ break;
+ case IN_PROPERTY_PARSE_TYPE_LITERAL:
+ $this->_report_end_parse_type_literal();
+ break;
+ case IN_RDF:
+ case IN_DESCRIPTION:
+ case IN_PROPERTY_RESOURCE:
+ case IN_PROPERTY_EMPTY_RESOURCE:
+ case IN_UNKNOWN:
+ break;
+ }
+
+ $this->_pop_element();
+}
+
+function _character_data_handler( $parser,$s)
+{
+ $len=strlen($s);
+ switch( $this->rdf_parser["top"]["state"] )
+ {
+ case IN_PROPERTY_LITERAL:
+ case IN_PROPERTY_UNKNOWN_OBJECT:
+ if( isset($this->rdf_parser["top"]["data"]) )
+ {
+ $n = strlen( $this->rdf_parser["top"]["data"] );
+ $this->rdf_parser["top"]["data"].= $s;
+
+ }
+ else
+ {
+ $this->rdf_parser["top"]["data"]=$s;
+ }
+
+ if( $this->rdf_parser["top"]["state"] == IN_PROPERTY_UNKNOWN_OBJECT )
+ {
+ /* look for non-whitespace */
+ for( $i = 0; (( $i < $len ) && ( ereg(" |\n|\t",$s{ $i }) )); $i++ );
+ $i++;
+ /* if we found non-whitespace, this is a literal */
+ if( $i <= $len )
+ {
+ $this->rdf_parser["top"]["state"] = IN_PROPERTY_LITERAL;
+ }
+ }
+
+ break;
+ case IN_TOP_LEVEL:
+ case IN_PROPERTY_PARSE_TYPE_LITERAL:
+ case IN_XML:
+ $this->_report_character_data(
+ $s,
+ strlen($s) );
+ break;
+ case IN_RDF:
+ case IN_DESCRIPTION:
+ case IN_PROPERTY_RESOURCE:
+ case IN_PROPERTY_EMPTY_RESOURCE:
+ case IN_PROPERTY_PARSE_TYPE_RESOURCE:
+ case IN_UNKNOWN:
+ break;
+ }
+}
+
+/* public functions */
+
+
+function rdf_parser_create( $encoding )
+{
+
+ $parser = xml_parser_create_ns( $encoding, NAMESPACE_SEPARATOR_CHAR );
+ xml_parser_set_option($parser,XML_OPTION_CASE_FOLDING,0);
+ $this->rdf_parser["xml_parser"] = $parser;
+
+ xml_set_object($this->rdf_parser["xml_parser"], $this);
+ xml_set_element_handler( $this->rdf_parser["xml_parser"], "_start_element_handler", "_end_element_handler" );
+ xml_set_character_data_handler( $this->rdf_parser["xml_parser"], "_character_data_handler" );
+
+ return $this->rdf_parser;
+}
+
+function rdf_parser_free( )
+{
+ $z=3;
+// xml_parser_free( $this->rdf_parser["xml_parser"] );
+
+ $this->rdf_parser["base_uri"]='';
+
+ $this->_delete_elements( $this->rdf_parser );
+
+ unset( $this->rdf_parser );
+}
+
+function rdf_set_user_data( &$user_data )
+{
+ $this->rdf_parser["user_data"] = &$user_data;
+}
+
+function rdf_get_user_data( )
+{
+ return ( $this->rdf_parser["$user_data"] );
+}
+
+function rdf_set_statement_handler($handler )
+{
+ $this->rdf_parser["statement_handler"] = $handler;
+}
+
+function rdf_set_parse_type_literal_handler($start,$end )
+{
+ $this->rdf_parser["start_parse_type_literal_handler"] = $start;
+ $this->rdf_parser["end_parse_type_literal_handler"] = $end;
+}
+
+function rdf_set_element_handler($start,$end)
+{
+ $this->rdf_parser["_start_element_handler"] = $start;
+ $this->rdf_parser["_end_element_handler"] = $end;
+}
+
+function rdf_set_character_data_handler( $handler)
+{
+ $this->rdf_parser["_character_data_handler"] = $handler;
+}
+
+function rdf_set_warning_handler($handler )
+{
+ $this->rdf_parser["warning_handler"] = $handler;
+}
+
+function rdf_parse( $s, $len, $is_final )
+{
+ return XML_Parse( $this->rdf_parser["xml_parser"], $s, $is_final );
+}
+
+function rdf_get_xml_parser()
+{
+ return ( $this->rdf_parser["xml_parser"]);
+}
+
+function rdf_set_base($base )
+{
+
+ //tcscpy( buffer, base );
+
+/*
+ if( buffer[" tcslen( buffer ) - 1 "] != T( '#' ) )
+ {
+ tcscat( buffer, T( "#" ) );
+ }
+*/
+
+ /* check for out of memory */
+ $this->rdf_parser["base_uri"]=$base;
+
+ return 0;
+}
+
+function rdf_get_base()
+{
+ return $this->rdf_parser["base_uri"];
+}
+
+function rdf_resolve_uri($uri_reference,&$buffer)
+{
+ _resolve_uri_reference( $this->rdf_parser["base_uri"], $uri_reference, $buffer, strlen($buffer) );
+}
+
+}
+
+
+
+
+
+
+
+
+
+}
+?>
diff --git a/site/app/controllers/components/ldap.php b/site/app/controllers/components/ldap.php
new file mode 100644
index 0000000..a6a6318
--- /dev/null
+++ b/site/app/controllers/components/ldap.php
@@ -0,0 +1,82 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Justin Scott <fligtar@mozilla.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+class LdapComponent extends Object {
+ var $controller;
+
+ /**
+ * Save a reference to the controller on startup
+ * @param object &$controller the controller using this component
+ */
+ function startup(&$controller) {
+ $this->controller =& $controller;
+ }
+
+ function connect($username, $password) {
+ if (!$this->ds = ldap_connect(LDAP_HOST))
+ return false;
+ if(!ldap_bind($this->ds, $this->initDnFromUsername($username), $password))
+ return false;
+
+ return true;
+ }
+
+ function initDnFromUsername($username) {
+ if(!ldap_bind($this->ds, ANON_BIND, ANON_BIND_PW))
+ return false;
+
+ return $this->getDnFromUsername($username);
+ }
+
+ function getDnFromUsername($username) {
+ $search = ldap_search($this->ds, "dc=mozilla","mail=$username");
+ $search_results = ldap_get_entries($this->ds,$search);
+ if($search_results['count'] != 1)
+ return false;
+ return $search_results[0]['dn'];
+ }
+
+ function hasAccount($email, $type) {
+ $search = ldap_search($this->ds,"dc=mozilla","mail=$email");
+ $search_results = ldap_get_entries($this->ds,$search);
+ if($search_results['count'] == 1 && in_array($type, $search_results[0]['objectclass']) )
+ return true;
+ else
+ return false;
+ }
+}
+?>
diff --git a/site/app/controllers/components/newsfeed.php b/site/app/controllers/components/newsfeed.php
new file mode 100644
index 0000000..ffdacdc
--- /dev/null
+++ b/site/app/controllers/components/newsfeed.php
@@ -0,0 +1,385 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Justin Scott <fligtar@mozilla.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+class NewsfeedComponent extends Object {
+ var $controller;
+
+ /**
+ * Save a reference to the controller on startup
+ * @param object &$controller the controller using this component
+ */
+ function startup(&$controller) {
+ $this->controller =& $controller;
+ }
+
+ /**
+ * Generates add-on newsfeed for user
+ */
+ function generate($fbUser, $friends, $favorites, $days = 7) {
+ $newsfeed = array();
+
+ $newVersionsOfFavorites = $this->_getNewVersionsOfFavorites($favorites, $days);
+ $friendFavoriteUpdates = $this->_getFriendFavoriteUpdates($friends, $days);
+ $f_recommendations = $this->_getFriendRecommendations($friends, $favorites);
+ $newUsers = $this->_getNewFriendUsers($friends, $days);
+ //$s_recommendations = $this->_getSimilarRecommendations($fbUser, $favorites);
+
+ // Include up to 2 new user stories
+ $newsfeed = array_merge($newsfeed, $this->_pullStories($newUsers, 2));
+
+ // Include up to 2 new version stories
+ $newsfeed = array_merge($newsfeed, $this->_pullStories($newVersionsOfFavorites, 2));
+
+ // Include 1 friend recommendation
+ $newsfeed = array_merge($newsfeed, $this->_pullStories($f_recommendations, 1));
+
+ // Fill the rest with favorite updates
+ $newsfeed = array_merge($newsfeed, $this->_pullStories($friendFavoriteUpdates, (10 - count($newsfeed))));
+
+ // randomize stories
+ shuffle($newsfeed);
+
+ return $newsfeed;
+ }
+
+ function _pullStories($stories, $number) {
+ // If no stories, return none
+ if (empty($stories)) {
+ return array();
+ }
+
+ // If more stories requested than available, return all stories
+ if (count($stories) < $number) {
+ return $stories;
+ }
+
+ // Otherwise, pull the appropriate number of stories randomly
+ $newsfeed = array();
+ $rand = array_rand($stories, $number);
+ if (is_array($rand)) {
+ foreach ($rand as $key) {
+ $newsfeed[] = $stories[$key];
+ }
+ }
+ else {
+ $newsfeed[] = $stories[$rand];
+ }
+
+ return $newsfeed;
+ }
+
+ /**
+ * Gets stories for any new versions of the user's favorite add-ons
+ */
+ function _getNewVersionsOfFavorites($favorites, $days) {
+ // If no favorites, return
+ if (empty($favorites))
+ return array();
+
+ $stories = array();
+
+ $favorites_string = implode(',', $favorites);
+
+ $results = $this->controller->Addon->query("
+ SELECT
+ addons.id,
+ versions.version,
+ files.datestatuschanged,
+ translations.localized_string AS name
+ FROM addons
+ INNER JOIN versions ON addons.id=versions.addon_id
+ INNER JOIN files ON versions.id=files.version_id
+ INNER JOIN translations ON addons.name=translations.id
+ WHERE
+ addons.id IN ({$favorites_string}) AND
+ files.status = 4 AND
+ translations.locale = 'en-US' AND
+ files.datestatuschanged >= DATE_SUB(NOW(), INTERVAL {$days} DAY)
+ GROUP BY addons.id
+ ORDER BY files.datestatuschanged DESC
+ ", true);
+
+ if (!empty($results)) {
+ foreach ($results as $result) {
+ $stories[] = array(
+ 'type' => 'story',
+ 'icon' => 'newversion.png',
+ 'story' => 'Version '.$result['versions']['version'].' of <a href="'.FB_URL.'/view/'.$result['addons']['id'].'?ref=afnv">'.$result['translations']['name'].'</a> is now available.',
+ 'timestamp' => $result['files']['datestatuschanged']
+ );
+ }
+ }
+
+ return $stories;
+ }
+
+ /**
+ * Gets friends that recently added the app
+ */
+ function _getNewFriendUsers($friends, $days) {
+ // If no friends, return
+ if (empty($friends))
+ return array();
+
+ $stories = array();
+
+ $results = $this->controller->FacebookFavorite->query("
+ SELECT
+ fb_user
+ FROM facebook_users
+ WHERE
+ added >= DATE_SUB(NOW(), INTERVAL {$days} DAY) AND
+ fb_user IN ({$friends}) AND
+ removed = '0000-00-00 00:00:00'
+ ORDER BY added DESC
+ LIMIT 5
+ ", true);
+
+ if (!empty($results)) {
+ foreach ($results as $result) {
+ $stories[] = array(
+ 'type' => 'story',
+ 'icon' => 'addedfavorite.png',
+ 'story' => '<a href="'.FB_URL.'/favorites/user/'.$result['facebook_users']['fb_user'].'"><fb:name uid="'.$result['facebook_users']['fb_user'].'" linked="false" shownetwork="false" /></a> added the Rock Your Firefox application.'
+ );
+ }
+ }
+
+ return $stories;
+ }
+
+ /**
+ * Gets updates for any friend activity
+ */
+ function _getFriendFavoriteUpdates($friends, $days) {
+ // If no friends, return
+ if (empty($friends))
+ return array();
+
+ $stories = array();
+
+ $results = $this->controller->FacebookFavorite->query("
+ SELECT
+ addons.id,
+ GROUP_CONCAT(facebook_favorites.fb_user) AS friends,
+ facebook_favorites.created,
+ translations.localized_string AS name
+ FROM facebook_favorites
+ INNER JOIN addons ON facebook_favorites.addon_id=addons.id
+ INNER JOIN translations ON translations.id=addons.name
+ WHERE
+ facebook_favorites.created >= DATE_SUB(NOW(), INTERVAL {$days} DAY) AND
+ translations.locale = 'en-US' AND
+ facebook_favorites.fb_user IN ({$friends})
+ GROUP BY addons.id
+ ORDER BY facebook_favorites.created DESC
+ LIMIT 5
+ ", true);
+
+ if (!empty($results)) {
+ foreach ($results as $result) {
+ $ffriends = explode(',', $result[0]['friends']);
+ if (count($ffriends) == 1) {
+ $possessive = '<fb:pronoun uid="'.$ffriends[0].'" possessive="true" />';
+ $names = '<a href="'.FB_URL.'/favorites/user/'.$ffriends[0].'"><fb:name uid="'.$ffriends[0].'" linked="false" /></a>';
+ }
+ else {
+ $possessive = 'their';
+ if (count($ffriends) == 2) {
+ $names = '<a href="'.FB_URL.'/favorites/user/'.$ffriends[0].'"><fb:name uid="'.$ffriends[0].'" linked="false" /></a>';
+ $names .= ' and <a href="'.FB_URL.'/favorites/user/'.$ffriends[1].'"><fb:name uid="'.$ffriends[1].'" linked="false" /></a>';
+ }
+ else {
+ $names = '<a href="'.FB_URL.'/favorites/addon/'.$result['addons']['id'].'">'.count($ffriends).' friends</a>';
+ }
+ }
+
+ $stories[] = array(
+ 'type' => 'story',
+ 'icon' => 'addedfavorite.png',
+ 'story' => $names.' added <a href="'.FB_URL.'/view/'.$result['addons']['id'].'?ref=aff">'.$result['translations']['name'].'</a> to '.$possessive.' favorite add-ons.',
+ 'timestamp' => $result['facebook_favorites']['created']
+ );
+ }
+ }
+
+ return $stories;
+ }
+
+ /**
+ * Tries to recommend add-ons based on friends' favorites
+ */
+ function _getFriendRecommendations($friends, $favorites) {
+ // If no friends, return
+ if (empty($friends))
+ return array();
+
+ $stories = array();
+ $favorites_string = implode(',', $favorites);
+
+ $results = $this->controller->FacebookFavorite->query("
+ SELECT
+ addons.id,
+ COUNT(*) AS favorited,
+ translations_n.localized_string AS name,
+ translations_s.localized_string AS summary,
+ (SELECT COUNT(*) FROM previews WHERE previews.addon_id=addons.id) AS pcount
+ FROM facebook_favorites
+ INNER JOIN addons ON facebook_favorites.addon_id=addons.id
+ INNER JOIN translations AS translations_n ON translations_n.id=addons.name
+ INNER JOIN translations AS translations_s ON translations_s.id=addons.summary
+ WHERE
+ translations_n.locale = 'en-US' AND
+ translations_s.locale = 'en-US' AND
+ facebook_favorites.fb_user IN ({$friends}) AND
+ ".(!empty($favorites_string) ? "addons.id NOT IN ({$favorites_string}) AND" : "")."
+ addons.inactive = 0 AND
+ addons.status = ".STATUS_PUBLIC."
+ GROUP BY addons.id
+ ORDER BY favorited DESC
+ LIMIT 5
+ ", true);
+
+ if (!empty($results)) {
+ foreach ($results as $result) {
+ if ($result[0]['favorited'] > 1) {
+ $stories[] = array(
+ 'type' => 'fullstory',
+ 'icon' => 'recommendation.png',
+ 'story' => '<span class="title">Recommendation:</span> <a href="'.FB_URL.'/favorites/addon/'.$result['addons']['id'].'?ref=affr">'.$result[0]['favorited'].' of your friends</a> like <a href="'.FB_URL.'/view/'.$result['addons']['id'].'">'.$result['translations_n']['name'].'</a>. Have you tried it?',
+ 'body' => $this->controller->_trimSummary($result['translations_s']['summary'], 200),
+ 'image' => ($result[0]['pcount'] > 0 ? FB_IMAGE_SITE.'/images/addon_preview/'.$result['addons']['id'].'/1' : ''),
+ 'image_url' => FB_URL.'/view/'.$result['addons']['id'].'?ref=affri'
+ );
+ }
+ }
+ }
+
+ return $stories;
+ }
+
+ /**
+ * Tries to recommend add-ons based on similar users' favorites
+ * As in, "people who had these add-ons favorited also liked ____"
+ */
+ /*function _getSimilarRecommendations($fbUser, $favorites) {
+ // If no favorites, return
+ if (empty($favorites))
+ return array();
+
+ $stories = array();
+ $favorites_string = implode(',', $favorites);
+
+ // Get top 2 favorited add-ons that user has favorited
+ $top2 = $this->controller->FacebookFavorite->query("
+ SELECT
+ addon_id,
+ COUNT(*) AS favorited
+ FROM facebook_favorites
+ WHERE
+ addon_id IN ({$favorites_string})
+ GROUP BY addon_id
+ ORDER BY favorited DESC
+ LIMIT 2
+ ", true);
+
+ pr($top2);
+
+ // Find other users who have favorited all 2
+ $similarUsers = $this->controller->FacebookFavorite->query("
+ SELECT
+ fb.fb_user
+ FROM facebook_favorites AS fb
+ LEFT JOIN facebook_favorites AS addon1 ON addon1.fb_user=fb.fb_user
+ LEFT JOIN facebook_favorites AS addon2 ON addon2.fb_user=fb.fb_user
+ WHERE
+ addon1.addon_id = {$top2[0]['facebook_favorites']['addon_id']} AND
+ addon2.addon_id = {$top2[1]['facebook_favorites']['addon_id']}
+ GROUP BY fb.fb_user
+ ", true);
+
+ pr($similarUsers);
+
+ if (!empty($results)) {
+ foreach ($results as $result) {
+ $stories[] = array(
+ 'icon' => 'favorite_recommend.png',
+ 'story' => '<b>Recommendation:</b> <a href="'.FB_URL.'/favorites/addon/'.$result['addons']['id'].'">'.$result[0]['favorited'].'</a> of your friends like <a href="'.FB_URL.'/view/'.$result['addons']['id'].'">'.$result['translations']['name'].'</a>. Have you tried it?',
+ 'timestamp' => 0
+ );
+ }
+ }
+
+ return $stories;
+ }*/
+
+ /**
+ * Counts new add-ons since last favorite added
+ */
+ function getNewAddonCount($fbUser) {
+ // Get date of last added favorite
+ $lastadded = $this->controller->FacebookFavorite->query("
+ SELECT
+ facebook_favorites.created
+ FROM facebook_favorites
+ WHERE
+ facebook_favorites.fb_user = '{$fbUser}'
+ ORDER BY facebook_favorites.created DESC
+ LIMIT 1
+ ");
+
+ if (!empty($lastadded)) {
+ $daysSince = (time() - strtotime($lastadded[0]['facebook_favorites']['created'])) / 86400;
+
+ if (!empty($lastadded) && $daysSince >= 14) {
+ // Get count of add-ons added after last favorite
+ $count = $this->controller->Addon->query("
+ SELECT
+ COUNT(*) as num
+ FROM addons
+ WHERE
+ created > '{$lastadded[0]['facebook_favorites']['created']}'
+ ", true);
+
+ return 'There are '.$count[0][0]['num'].' new add-ons since you last added a favorite. <a href="'.FB_URL.'/browse?ref=afsb">Find your next favorite!</a>';
+ }
+ }
+
+ return '';
+ }
+}
+?>
diff --git a/site/app/controllers/components/opensearch.php b/site/app/controllers/components/opensearch.php
new file mode 100644
index 0000000..6d23be7
--- /dev/null
+++ b/site/app/controllers/components/opensearch.php
@@ -0,0 +1,492 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Gavin Sharp <gavin@gavinsharp.com> (Original author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+class OpenSearchEngineUrl extends Object {
+ var $params = array();
+ var $method, $template;
+
+ function OpenSearchEngineUrl($method, $template) {
+ $this->method = $method;
+ $this->template = $template;
+ }
+
+ /**
+ * Adds a parameter to this URL.
+ * @param string $name
+ * @param string $value
+ */
+ function addParam($name, $value) {
+ if ($name != '' && $value != '') {
+ array_push($this->params, array($name, $value));
+ }
+ }
+
+ /**
+ * Performs OpenSearch parameter replacement on $str.
+ * This function is meant to eliminate dynamic parameters from the
+ * OpenSearch description so that it can be serialized to Sherlock, which
+ * doesn't support any dynamic parameters. This function uses the same
+ * logic as Firefox to choose reasonable default values for required
+ * parameters in the input string. See:
+ * http://bonsai.mozilla.org/cvsblame.cgi?file=mozilla/browser/components/search/nsSearchService.js&rev=1.88#754
+ * @param string $inputEncoding the value used to replace the
+ * {inputEncoding} parameter, if present.
+ * @param string $str the string containing the dynamic parameters to
+ * replace.
+ */
+ function paramSubstitution($inputEncoding, $str) {
+ // Insert the OpenSearch parameters we're confident about
+ $supportedParams = array('/\{inputEncoding\??\}/', '/\{language\??\}/',
+ '/\{outputEncoding\??\}/');
+
+ // Specified inputEncoding, "*" for "all languages", and "UTF-8" for
+ // outputEncoding. This matches the values Firefox uses by default.
+ $values = array($inputEncoding, '*', 'UTF-8');
+
+ // Replace supported parameters
+ $str = preg_replace($supportedParams, $values, $str);
+
+ // Remove all optional parameters (any parameter with a trailing "?")
+ $str = preg_replace('/\{\w+\?\}/', '', $str);
+
+ // Replace any remaining parameters that we recognize with reasonable
+ // default values.
+ $otherParams = array('/\{count\}/', '/\{startIndex\}/',
+ '/\{startPage\}/');
+
+ // 20 search results, start at page 1, index 1. These values are also
+ // based on Firefox's defaults.
+ $str = preg_replace($otherParams, array('20', '1', '1'), $str);
+
+ return $str;
+ }
+
+ function getTemplate($inputEncoding) {
+ return $this->paramSubstitution($inputEncoding, $this->template);
+ }
+
+ function getParams($inputEncoding) {
+ $params = array();
+ foreach ($this->params as $param) {
+ $name = $param[0];
+ $value = $this->paramSubstitution($inputEncoding, $param[1]);
+
+ if ($value) {
+ array_push($params, array($name, $value));
+ }
+ }
+
+ return $params;
+ }
+}
+
+class OpenSearchEngine extends Object {
+ var $urls = array();
+ var $name, $alias, $description, $inputEncoding, $outputEncoding;
+ var $searchForm, $updateInterval, $updateUrl, $iconUpdateUrl;
+ var $imageUrl;
+
+ /**
+ * Gets an array of parameters corresponding to a given URL.
+ * @param string $urlType the content type of the URL
+ * Returns NULL if this engine has no URL of type $urlType.
+ */
+ function getParams($urlType) {
+ if (!isset($this->urls[$urlType])) {
+ return NULL;
+ }
+
+ return $this->urls[$urlType]->getParams($this->inputEncoding);
+ }
+
+ /**
+ * Gets the template parameter for a given URL.
+ * @param string $urlType the content type of the URL
+ * Returns NULL if this engine has no URL of type $urlType.
+ */
+ function getTemplate($urlType) {
+ if (!isset($this->urls[$urlType])) {
+ return NULL;
+ }
+
+ return $this->urls[$urlType]->getTemplate($this->inputEncoding);
+ }
+
+ // Utility function to print a Sherlock attribute.
+ function prAttr($attr, $val) {
+ if ($val) {
+ return " $attr=\"" . $val . "\"\n";
+ }
+
+ return '';
+ }
+
+ /**
+ * Serialize this engine to a to a valid Sherlock string. Returns NULL if
+ * the engine can't be represented by a Sherlock description file.
+ */
+ function toSherlock() {
+ $htmlUrl =& $this->urls['text/html'];
+
+ if ($htmlUrl->method != 'GET') {
+ // Sherlock only supports GET plugins
+ return NULL;
+ }
+
+ $template = $this->getTemplate('text/html');
+ $firstInput = '';
+ $foundUserInput = false;
+ if (preg_match('/{searchTerms}/', $template)) {
+ if (!preg_match('/{searchTerms}$/', $template)) {
+ // Sherlock can't deal with templates that have the search
+ // terms embedded in them, unless the search terms are simply
+ // appended to the template.
+ return NULL;
+ }
+
+ $template = preg_replace('/{searchTerms}$/', '', $template);
+
+ // Add a special input that tells Firefox to simply append the
+ // user's search terms to the end of the template. This has to be
+ // the first input for this to work. See:
+ // http://bonsai.mozilla.org/cvsblame.cgi?file=mozilla/xpfe/components/search/src/nsInternetSearchService.cpp&rev=1.251#4637
+ $firstInput = "<input user>\n";
+ $foundUserInput = true;
+ }
+
+ $queryCharset = $this->inputEncoding;
+
+ // Search section
+ $srcString = "<SEARCH\n";
+ $srcString .= $this->prAttr('name', $this->name);
+ $srcString .= $this->prAttr('action', $template);
+ $srcString .= $this->prAttr('method', $htmlUrl->method);
+ $srcString .= $this->prAttr('searchForm', $this->searchForm);
+ $srcString .= $this->prAttr('description', $this->description);
+ $srcString .= $this->prAttr('queryCharset', $queryCharset);
+ $srcString .= ">\n";
+
+ // print inputs
+ $srcString .= $firstInput;
+
+ $params = $this->getParams('text/html');
+ foreach ($params as $param) {
+ $name = $param[0]; $value = $param[1];
+
+ if (preg_match('/{searchTerms}/', $value)) {
+ if (!preg_match('/^{searchTerms}$/', $value)) {
+ return NULL;
+ }
+
+ $srcString .= "<input name=\"$name\" user>\n";
+ $foundUserInput = true;
+ } else {
+ $srcString .= "<input name=\"$name\" value=\"$value\">\n";
+ }
+ }
+
+ // Check that we found a valid user input
+ if (!$foundUserInput) {
+ return NULL;
+ }
+
+ $srcString .= "</SEARCH>\n";
+
+ // Browser section (Mozilla extension to Sherlock, used for updates)
+ if ($this->updateUrl || $this->iconUpdateUrl || $this->updateInterval) {
+ $srcString .= "\n<BROWSER\n";
+ $srcString .= $this->prAttr('update', $this->updateUrl);
+ $srcString .= $this->prAttr('updateIcon', $this->iconUpdateUrl);
+ $srcString .= $this->prAttr('updateCheckDays', $this->updateInterval);
+ $srcString .= ">\n";
+ }
+
+ return $srcString;
+ }
+
+ // Returns raw bytes of the engine's image, if it has one, or NULL
+ // otherwise
+ function getImage() {
+ if (!$this->imageUrl ||
+ !preg_match('/^data\:/', $this->imageUrl)) {
+ return NULL;
+ }
+
+ $base64Str = preg_replace('/^data\:.+base64,/', '', $this->imageUrl);
+ if (!($bytes = base64_decode($base64Str))) {
+ return NULL;
+ }
+
+ return $bytes;
+ }
+}
+
+class OpensearchComponent extends Object {
+ // Initialize variables
+ var $in = false;
+ var $wasIn = false;
+ var $curEl = NULL;
+ var $curUrlType = NULL;
+ var $attrs = array();
+ var $tagCount = array();
+ var $gotData = array();
+ var $depth = 0;
+ var $engine = NULL;
+
+ /**
+ * XML parsing callback functions.
+ */
+ function start_element($parser, $name, $attrs) {
+ if ($name == "OpenSearchDescription") {
+ if ($this->in || $this->wasIn) {
+ // Multiple OpenSearchDescription elements - bail out
+ return;
+ }
+
+ // Test the namespace
+ // These are the namespaces that Firefox supports
+ $validNamespaces =
+ array("http://a9.com/-/spec/opensearch/1.0/",
+ "http://a9.com/-/spec/opensearch/1.1/",
+ "http://a9.com/-/spec/opensearchdescription/1.1/",
+ "http://a9.com/-/spec/opensearchdescription/1.0/");
+ if (isset($attrs['xmlns']) &&
+ in_array($attrs['xmlns'], $validNamespaces)) {
+ $this->in = true;
+ $this->wasIn = true;
+ $this->engine =& new OpenSearchEngine();
+ return;
+ }
+ }
+
+ if (!$this->in) {
+ return;
+ }
+
+ $this->depth++;
+
+ // Since <Url>s are the only elements that can have child elements, and
+ // their only valid child elements are <Param>s, we can ignore this
+ // element if it has a depth greater than 1 and isn't a <Param> that's
+ // a child of a <Url>.
+ $processingParam = ($this->curUrlType && $name == "Param");
+ if ($this->depth != 1 && !$processingParam) {
+ return;
+ }
+
+ if ($processingParam) {
+ $urls =& $this->engine->urls;
+ $urls[$this->curUrlType]->addParam($attrs['name'], $attrs['value']);
+ return;
+ }
+
+ switch ($name) {
+ case "ShortName":
+ case "Description":
+ case "InputEncoding":
+ case "UpdateUrl":
+ case "UpdateInterval":
+ case "IconUpdateUrl":
+ case "Alias":
+ case "SearchForm":
+ case "OutputEncoding":
+ $this->tagCount[$name]++;
+ $this->curEl = $name;
+ break;
+ case "Image":
+ // Ignore image elements that aren't supported by Firefox
+ if (isset($attrs["width"]) && $attrs["width"] == 16 &&
+ isset($attrs["height"]) && $attrs["height"] == 16) {
+ $this->tagCount[$name]++;
+ $this->curEl = $name;
+ }
+ break;
+ case "Url":
+ // Validate the URL element. We only care about https?://
+ // templates, and text/html types.
+ $OS_SUPPORTED_TYPES = array("text/html", "application/x-suggestions+json");
+ $OS_SUPPORTED_METHODS = array("POST", "GET");
+
+ $type = strtolower($attrs["type"]);
+ $method = (isset($attrs["method"])) ? strtoupper($attrs["method"])
+ : 'GET';
+ $template = $attrs["template"];
+
+ if (preg_match('/^https?/i', $template) &&
+ in_array($type, $OS_SUPPORTED_TYPES) &&
+ in_array($method, $OS_SUPPORTED_METHODS)) {
+
+ $this->curUrlType = $type;
+ $this->engine->urls[$type] =& new OpenSearchEngineUrl($method, $template);
+ }
+ break;
+ }
+ }
+
+ function stop_element($parser, $name) {
+ if ($name == "OpenSearchDescription") {
+ $this->in = false;
+ return;
+ }
+
+ $this->depth--;
+
+ $this->curEl = NULL;
+ if ($name == "Url") {
+ $this->curUrlType = NULL;
+ }
+ }
+
+ function char_data($parser, $data) {
+ if ($this->curEl) {
+ $name = $this->curEl;
+ if (!$this->gotData[$name]) {
+ $this->gotData[$name] = $this->tagCount[$name];
+ }
+
+ if ($this->gotData[$name] != $this->tagCount[$name]) {
+ // We hit a new tag, clobber the existing data.
+ $this->attrs[$name] = $data;
+ $this->gotData[$name] = $this->tagCount[$name];
+ } else {
+ $this->attrs[$name] .= $data;
+ }
+ }
+ }
+
+ /**
+ * Resets the component's state so that it's ready to parse another file.
+ */
+ function reset() {
+ $this->in = false;
+ $this->wasIn = false;
+ $this->curEl = NULL;
+ $this->curUrlType = NULL;
+
+ // Define empty elements to avoid "undefined index" errors
+ // Surely there is a better way to do this?
+ $this->attrs = array('ShortName' => '',
+ 'Description' => '',
+ 'InputEncoding' => '',
+ 'UpdateUrl' => '',
+ 'UpdateInterval' => '',
+ 'IconUpdateUrl' => '',
+ 'Alias' => '',
+ 'SearchForm' => '',
+ 'OutputEncoding' => '',
+ 'Image' => '');
+ $this->tagCount = array('ShortName' => '',
+ 'Description' => '',
+ 'InputEncoding' => '',
+ 'UpdateUrl' => '',
+ 'UpdateInterval' => '',
+ 'IconUpdateUrl' => '',
+ 'Alias' => '',
+ 'SearchForm' => '',
+ 'OutputEncoding' => '',
+ 'Image' => '');
+ $this->gotData = array('ShortName' => '',
+ 'Description' => '',
+ 'InputEncoding' => '',
+ 'UpdateUrl' => '',
+ 'UpdateInterval' => '',
+ 'IconUpdateUrl' => '',
+ 'Alias' => '',
+ 'SearchForm' => '',
+ 'OutputEncoding' => '',
+ 'Image' => '');
+ $this->depth = 0;
+ $this->engine = NULL;
+ }
+
+ /**
+ * Parses OpenSearch description files and returns an OpenSearchEngine
+ * object.
+ * @param $file either a filename pointing to an XML OpenSearch
+ * description file, or a string containing an OS description file's
+ * contents.
+ */
+ function parse($file) {
+ // Reset state
+ $this->reset();
+
+ if (file_exists($file)) {
+ $contents = file_get_contents($file);
+ } else {
+ $contents = $file;
+ }
+
+ // Create Expat parser
+ $parser = xml_parser_create();
+
+ // Set handler functions
+ xml_set_object($parser, $this);
+ xml_set_element_handler($parser, "start_element", "stop_element");
+ xml_set_character_data_handler($parser, "char_data");
+ xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0);
+
+ // Parse the file
+ $ret = xml_parse($parser, $contents);
+ xml_parser_free($parser);
+
+ if (!$ret) {
+ return NULL;
+ }
+
+ // Check to ensure we found all required elements (name and valid Url)
+ if ($this->attrs['ShortName'] == '' ||
+ !isset($this->engine->urls['text/html'])) {
+
+ return NULL;
+ }
+
+ $this->engine->name = $this->attrs['ShortName'];
+ $this->engine->alias = $this->attrs['Alias'];
+ $this->engine->inputEncoding = $this->attrs['InputEncoding'];
+ $this->engine->updateUrl = $this->attrs['UpdateUrl'];
+ $this->engine->description = $this->attrs['Description'];
+ $this->engine->updateInterval = $this->attrs['UpdateInterval'];
+ $this->engine->iconUpdateUrl = $this->attrs['IconUpdateUrl'];
+ $this->engine->searchForm = $this->attrs['SearchForm'];
+ $this->engine->outputEncoding = $this->attrs['OutputEncoding'];
+ $this->engine->imageUrl = $this->attrs['Image'];
+
+ return $this->engine;
+ }
+}
+?>
diff --git a/site/app/controllers/components/pagination.php b/site/app/controllers/components/pagination.php
new file mode 100644
index 0000000..a6f6685
--- /dev/null
+++ b/site/app/controllers/components/pagination.php
@@ -0,0 +1,489 @@
+<?php
+/**
+ * Pagination Component, responsible for managing the DATA required for pagination.
+ */
+class PaginationComponent extends Object
+{
+ // Configuration/Default variables
+/**
+ * Specify whether the component will use AJAX links if available.
+ * Tests for the presence of the RequestHandler component and if present will generate
+ * AJAX links. However, if the prototype library js has not been included, normal updates
+ * will take place.
+ *
+ * @var boolean
+ * @access public
+ */
+ var $ajaxAutoDetect = true;
+/**
+ * Specify the div to update if using ajax updates
+ *
+ * @var string
+ * @access public
+ */
+ var $ajaxDivUpdate = "content";
+/**
+ * The id of a form ID to be submitted with all pagination ajax links.
+ *
+ * @var string
+ * @access public
+ */
+ var $ajaxFormId = NULL;
+/**
+ * Specify link style
+ *
+ * @var string "html"/"ajax"
+ * @access public
+ */
+ var $style = "html";
+/**
+ * Specify link parameter style
+ *
+ * @var string "get"/"pretty"
+ * @access public
+ */
+ var $paramStyle = "get";
+/**
+ * Used only for pretty style urls - must match the
+ *
+ * @var string "get"/"pretty"
+ * @access public
+ */
+ var $paramSeperator = "/";
+/**
+ * Specify DEFAULT start page number
+ *
+ * @var integer
+ * @access public
+ */
+ var $page = 1;
+/**
+ * Specify DEFAULT number of items to be displayed per page. Also used as the limit
+ * for the subsequent SQL search.
+ *
+ * @var integer
+ * @access public
+ */
+ var $show = 20;
+/**
+ * Specify DEFAULT sort column.
+ *
+ * @var string
+ * @access public
+ */
+ var $sortBy = 'id';
+/**
+ * Specify DEFAULT sort direction.
+ *
+ * @var string
+ * @access public
+ */
+ var $direction = 'ASC';
+/**
+ * Specify the maximum number of pages to be included in the list of pages. Should be an odd number, otherwise rounded down.
+ *
+ * @var integer
+ * @access public
+ */
+ var $maxPages = 10;
+/**
+ * Options for results per page.
+ *
+ * @var array
+ * @access public
+ */
+ var $resultsPerPage = array(5,10,20,50,100);
+/**
+ * Show links to the first and last page, if the number of pages exceeds the maxPage count.
+ *
+ * @var boolean
+ * @access public
+ */
+ var $showLimits = true;
+/**
+ * An array of parameter names which cannot be specified by the url
+ *
+ * @var array
+ * @access public
+ */
+ var $privateParams = array();
+
+ // Do not edit below this line unless you wish to customize the core functionality of this Component
+/**
+ * Place holder for the sort class. Irrelavent for models without associations
+ *
+ * @var boolean
+ * @access private
+ */
+ var $sortByClass = NULL;
+/**
+ * Place holder for the model class.
+ *
+ * @var boolean
+ * @access private
+ */
+ var $modelClass = NULL;
+/**
+ * Place holder for the base url
+ *
+ * @var boolean
+ * @access private
+ */
+ var $url = NULL;
+/**
+ * Place holder for the controller
+ *
+ * @var boolean
+ * @access private
+ */
+ var $controller = true;
+/**
+ * Place holder for the sanitize object
+ *
+ * @var boolean
+ * @access private
+ */
+ var $sanitize = true;
+/**
+ * Place holder for the data array passed to the view
+ *
+ * @var boolean
+ * @access private
+ */
+ var $paging;
+
+/**
+ * Startup - Link the component to the controller.
+ *
+ * @param controller
+ */
+ function startup(&$controller)
+ {
+ $this->controller =& $controller;
+ }
+/**
+ * Initialize the pagination data.
+ *
+ * @param unknown
+ * @param array
+ * @options array
+ * @return array
+ */
+ function init($criteria=NULL,$parameters=array(),$options=array())
+ {
+ uses('sanitize');
+ $this->Sanitize = &new Sanitize;
+
+ $this->_initFields($options);
+ $this->_checkAjax();
+ $this->_initSort();
+ $this->_initPaging($parameters);
+ $this->_initURL();
+
+ $this->_setParameter("show",$parameters);
+ // If the number of results per page isn't in the list, reset to default
+ if ((isset($this->paging["show"]))&&(!in_array($this->paging["show"],$this->resultsPerPage)))
+ {
+ $this->paging["show"]=$this->paging['Defaults']['show'];
+ }
+
+ $this->_setParameter("page",$parameters);
+ $this->_setParameter("sortBy",$parameters);
+ $this->_setParameter("sortByClass",$parameters); // Overriding the model class if specified.
+ $this->_setParameter("direction",$parameters);
+
+ $this->_check4Form();
+
+ $this->_setPrivateParameter("ajaxDivUpdate");
+ $this->_setPrivateParameter("ajaxFormId");
+ $this->_setPrivateParameter("maxPages");
+ $this->_setPrivateParameter("showLimits");
+ $this->_setPrivateParameter("style");
+ $this->_setPrivateParameter("paramStyle");
+ $this->_setPrivateParameter("paramSeperator");
+ $this->_setPrivateParameter("url");
+
+ if (isset($this->total)) // If the field is already set, we passed in the options the total number of results
+ {
+ $count = $this->total;
+ }
+ else
+ {
+ $count = $this->controller->{$this->modelClass}->findCount($criteria,0);
+ }
+ $this->checkPage($count);
+ $this->paging['total'] = $count;
+ //$this->trimResultsPerPage($count);
+
+ $this->_setPrivateParameter("resultsPerPage");
+
+ $this->paging['pageCount'] = ceil($count / $this->paging['show'] );
+
+ $this->controller->set('paging',$this->paging);
+
+ $this->order = $this->paging['sortByClass'].".".$this->paging['sortBy'].' '.strtoupper($this->paging['direction']);
+
+ // For backwards compatability & clarity
+ $this->limit = $this->paging['show'];
+ $this->page = $this->paging['page'];
+
+ // For less code in the calling method.
+ return (array($this->order,$this->paging['show'],$this->paging['page']));
+ }
+
+/**
+ * Don't give the choice to display pages with no results
+ *
+ * @param integer
+ */
+ function trimResultsPerPage ($count = 0)
+ {
+ while (($limit = current($this->resultsPerPage))&&(!isset($capKey)))
+ {
+ if ($limit >= $count)
+ {
+ $capKey = key($this->resultsPerPage);
+ }
+ next($this->resultsPerPage);
+
+ if (isset($capKey))
+ {
+ array_splice($this->resultsPerPage, ($capKey+1));
+ }
+ }
+ }
+
+/**
+ * Set the page to the last if there would be no results, and to 1 if a negetive
+ * page number is specified
+ *
+ * @param integer
+ */
+ function checkPage ($count = 0)
+ {
+ if ((($this->paging['page']-1)*$this->paging['show'])>=$count)
+ {
+ $this->paging['page'] = floor($count/$this->paging['show']+0.99);
+ }
+ }
+
+/**
+ * Set Object fields
+ *
+ * @param unknown
+ */
+ function _initFields($options)
+ {
+ foreach($options as $option=>$val)
+ {
+ $this->$option = $val;
+ }
+ }
+/**
+ * Set Pagination with default Parameters
+ *
+ * @param unknown
+ */
+ function _initPaging($parameters)
+ {
+ $this->paging['importParams']=$parameters;
+ $this->paging['Defaults'] = array (
+ "page"=>$this->page,
+ "show"=>$this->show,
+ "sortBy"=>$this->sortBy,
+ "sortByClass"=>$this->sortByClass,
+ "direction"=>$this->direction
+ );
+ }
+/**
+ * If everything is in place, use Ajax by default
+ *
+ * @param unknown
+ */
+ function _checkAjax()
+ {
+ if (($this->ajaxAutoDetect==true)&&(isset($this->controller->RequestHandler)&&(in_array("Ajax",$this->controller->helpers))))
+ {
+ $this->style = "ajax";
+ }
+ }
+
+/**
+ * Set the DEFAULT sort class
+ *
+ * @param unknown
+ */
+ function _initSort()
+ {
+ if (!$this->modelClass)
+ {
+ $ModelClass = $this->modelClass = $this->controller->modelClass;
+ }
+ else
+ {
+ $ModelClass = $this->modelClass;
+ }
+ if (!$this->sortBy) {
+ $this->sortBy = $this->controller->$ModelClass->primaryKey;
+ }
+ if (!$this->sortByClass)
+ {
+ $this->sortByClass = $ModelClass;
+ }
+ }
+
+/**
+ * Set the base url for updates.
+ *
+ * @param unknown
+ */
+ function _initURL()
+ {
+ if ($this->url) // A url was specified in the paramters
+ {
+ if (substr($this->url, -1, 1)<>"/")
+ {
+ $this->url .= "/";
+ }
+ }
+ else // No url in the parameters, derive it.
+ {
+ if ($this->paramStyle=="get")
+ {
+ $this->url = str_replace($this->controller->webroot,"/",$this->controller->here);
+ }
+ else
+ {
+ $this->url = "";
+ if (isset($this->controller->params['admin']))
+ {
+ $this->url .= "/".$this->controller->params['admin'];
+ $action = substr($this->controller->action, strlen($this->controller->params['admin']."_"));
+ }
+ else
+ {
+ $action = $this->controller->action;
+ }
+ if ($this->controller->plugin)
+ {
+ $this->url .= "/".$this->controller->plugin;
+ }
+ $this->url .= "/".$this->controller->name;
+ $this->url .= "/".$action;
+ if (isset($this->paging['importParams']['_unamedParameters']))
+ {
+ $unnamedString = implode ("/", $this->paging['importParams']['_unamedParameters']);
+ $this->url .= "/".$unnamedString;
+ unset($this->paging['importParams']['_unamedParameters']);
+ }
+ $this->url .= "/";
+ }
+ }
+ if (defined('BASE_URL')) { // Hack for no mod_rewrite
+ $this->url = preg_replace( "!".BASE_URL."!", '', $this->url); // Remove the base from the url
+ $this->url = preg_replace("!\?.*!", '', $this->url); // Remove the get parameters
+ }
+ }
+
+/**
+ * If the parameters have been changed/set by a form action, update the params array.
+ * Would perhaps be best to redirect to the equivalent url, which isn't implemented as
+ * the relavent method is in the helper and as such inaccessible here.
+ *
+ * @param unknown
+ */
+ function _check4Form()
+ {
+ if(isset($this->controller->data['pagination']))
+ {
+ if (isset($this->controller->data['pagination']['sortByComposite']))
+ {
+ $Composite = array();
+ $Composite = explode("::",$this->controller->data['pagination']['sortByComposite']);
+ if (isset($Composite[0]))
+ {
+ $this->controller->data['pagination']['sortBy'] = $Composite[0];
+ }
+ if (isset($Composite[1]))
+ {
+ $this->controller->data['pagination']['direction'] = $Composite[1];
+ }
+ if (isset($Composite[2]))
+ {
+ $this->controller->data['pagination']['sortByClass'] = $Composite[2];
+ }
+ else
+ {
+ $this->controller->data['pagination']['sortByClass'] = $this->paging['Defaults']['sortByClass'];
+ }
+ unset($this->controller->data['pagination']['sortByComposite']);
+ }
+ foreach($this->controller->data['pagination'] as $parameter=>$value)
+ {
+
+ if (!in_array($parameter, $this->privateParams))
+ {
+ $this->paging[$parameter] = $this->Sanitize->paranoid($value);
+ }
+ }
+ }
+ }
+
+/**
+ * Set a parameter to be passed to the view which cannot be specified/overriden from the url.
+ *
+ * @param unknown
+ */
+ function _setPrivateParameter($parameter)
+ {
+ $this->paging[$parameter]= $this->$parameter;
+ }
+
+/**
+ * Set a parameter to be passed to the view overriden from the url if present.
+ *
+ * @param unknown
+ * @param array
+ * @param field
+ */
+ function _setParameter($parameter,$parameters=array(),$field=NULL)
+ {
+ $field = $field?$field:$parameter;
+
+ if (in_array($parameter, $this->privateParams))
+ {
+ $this->paging[$field] = $this->paging['Defaults'][$field];
+ }
+ else
+ {
+ if ($this->paramStyle=="get")
+ {
+ if (isset($_GET[$parameter]))
+ {
+ $this->paging[$field] = $this->Sanitize->paranoid($_GET[$parameter]);
+ }
+ else
+ {
+ $this->paging[$field]= $this->$field;
+ }
+ }
+ elseif ($this->paramStyle=="pretty")
+ {
+ if (isset($parameters[$parameter]))
+ {
+ $this->paging[$field] = $this->Sanitize->paranoid($parameters[$parameter]);
+ }
+ else
+ {
+ $this->paging[$field]= $this->$field;
+ }
+ }
+ else
+ {
+ echo ("parameter error");
+ die;
+ }
+ }
+ }
+}
+?>
diff --git a/site/app/controllers/components/rdf.php b/site/app/controllers/components/rdf.php
new file mode 100644
index 0000000..49a017a
--- /dev/null
+++ b/site/app/controllers/components/rdf.php
@@ -0,0 +1,124 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * Justin Scott <fligtar@gmail.com>.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+require_once('includes/rdf_parser.php');
+define('EM_NS', 'http://www.mozilla.org/2004/em-rdf#');
+define('MF_RES', 'urn:mozilla:install-manifest');
+
+class RdfComponent extends Object {
+ /**
+ * Parses install.rdf using Rdf_parser class
+ * @param string $manifestData
+ * @return array $data["manifest"]
+ */
+ function parseInstallManifest($manifestData) {
+ $data = array();
+
+ $rdf = new Rdf_parser();
+ $rdf->rdf_parser_create(null);
+ $rdf->rdf_set_user_data($data);
+ $rdf->rdf_set_statement_handler(array('RdfComponent', 'mfStatementHandler'));
+ $rdf->rdf_set_base('');
+
+ if (!$rdf->rdf_parse($manifestData, strlen($manifestData), true)) {
+ return xml_error_string(xml_get_error_code($rdf->rdf_parser['xml_parser']));
+ }
+
+ // Set the targetApplication data
+ $targetArray = array();
+ if (!empty($data['manifest']['targetApplication']) && is_array($data['manifest']['targetApplication'])) {
+ foreach ($data['manifest']['targetApplication'] as $targetApp) {
+ $id = $data[$targetApp][EM_NS."id"];
+ $targetArray[$id]['minVersion'] = $data[$targetApp][EM_NS.'minVersion'];
+ $targetArray[$id]['maxVersion'] = $data[$targetApp][EM_NS.'maxVersion'];
+ }
+ }
+
+ $data['manifest']['targetApplication'] = $targetArray;
+
+ $rdf->rdf_parser_free();
+
+ return $data['manifest'];
+ }
+
+ /**
+ * Parses install.rdf for our desired properties
+ * @param array &$data
+ * @param string $subjectType
+ * @param string $subject
+ * @param string $predicate
+ * @param int $ordinal
+ * @param string $objectType
+ * @param string $object
+ * @param string $xmlLang
+ */
+ function mfStatementHandler(&$data, $subjectType, $subject, $predicate,
+ $ordinal, $objectType, $object, $xmlLang) {
+ //single properties - ignoring: iconURL, optionsURL, aboutURL, and anything not listed
+ $singleProps = array('id' => 1, 'type' => 1, 'version' => 1, 'creator' => 1, 'homepageURL' => 1, 'updateURL' => 1, 'updateKey' => 1);
+ //multiple properties - ignoring: File
+ $multiProps = array('contributor' => 1, 'targetApplication' => 1, 'requires' => 1);
+ //localizable properties
+ $l10nProps = array('name' => 1, 'description' => 1);
+
+ //Look for properties on the install manifest itself
+ if ($subject == MF_RES) {
+ //we're only really interested in EM properties
+ $length = strlen(EM_NS);
+ if (strncmp($predicate, EM_NS, $length) == 0) {
+ $prop = substr($predicate, $length, strlen($predicate)-$length);
+
+ if (array_key_exists($prop, $singleProps) ) {
+ $data['manifest'][$prop] = $object;
+ }
+ elseif (array_key_exists($prop, $multiProps)) {
+ $data['manifest'][$prop][] = $object;
+ }
+ elseif (array_key_exists($prop, $l10nProps)) {
+ $lang = ($xmlLang) ? $xmlLang : 'en-US';
+ $data['manifest'][$prop][$lang] = $object;
+ }
+ }
+ }
+ else {
+ //save it anyway
+ $data[$subject][$predicate] = $object;
+ }
+ return $data;
+ }
+}
+?>
diff --git a/site/app/controllers/components/recaptcha.php b/site/app/controllers/components/recaptcha.php
new file mode 100644
index 0000000..871bf6b
--- /dev/null
+++ b/site/app/controllers/components/recaptcha.php
@@ -0,0 +1,145 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is licensed under the MIT license (see below).
+ *
+ * The Initial Developer of the Original Code is R. Wong.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Frederic Wenzel <fwenzel@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*****************************************************************************
+The MIT License
+
+Copyright (c) 2007 R. Wong (Lick)
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*****************************************************************************/
+
+// Get "recaptchalib.php" from http://code.google.com/p/recaptcha/downloads/list?q=label:phplib-Latest
+// and place it in "vendors/recaptcha".
+vendor('recaptcha/recaptchalib');
+
+
+class RecaptchaComponent extends Object
+{
+ var $controller = true;
+ var $disableStartup = true;
+
+ var $enabled = false;
+
+ function __construct() {
+ if (defined('RECAPTCHA_ENABLED') && RECAPTCHA_ENABLED
+ && defined('RECAPTCHA_PRIVATE_KEY') && defined('RECAPTCHA_PUBLIC_KEY'))
+ $this->enabled = true;
+
+ return parent::__construct();
+ }
+
+ function display()
+ {
+ if (!$this->enabled) return '';
+
+ return recaptcha_get_html(RECAPTCHA_PUBLIC_KEY);
+ }
+
+
+ function is_valid($form)
+ {
+ if (!$this->enabled) return false;
+
+ // grab remote IP through forwarded-for header when served by cache
+ if (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
+ $client_ips = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
+ $client_ip = trim($client_ips[0]);
+ } else {
+ $client_ip = $_SERVER['REMOTE_ADDR'];
+ }
+
+ if (isset($form['recaptcha_challenge_field']) &&
+ isset($form['recaptcha_response_field']) )
+ {
+ $resp = recaptcha_check_answer(
+ RECAPTCHA_PRIVATE_KEY,
+ $client_ip,
+ $form['recaptcha_challenge_field'],
+ $form['recaptcha_response_field']
+ );
+
+ if ($resp->is_valid)
+ return true;
+ }
+
+ return false;
+ }
+}
+
+
+/*****************************************************************************
+Example:
+
+class ExampleController extends AppController
+{
+ var $uses = array();
+ var $components = array('Recaptcha');
+ var $autoLayout = false;
+
+ function index()
+ {
+ $message = 'Invalid reCAPTCHA.';
+
+ if (isset($this->params['form']) && $this->Recaptcha->is_valid($this->params['form']) )
+ {
+ $message = 'Valid reCAPTCHA!';
+ }
+
+ $this->set('message', $message);
+ $this->set('recaptcha', $this->Recaptcha->display());
+ }
+}
+*****************************************************************************/
+
+?>
diff --git a/site/app/controllers/components/search.php b/site/app/controllers/components/search.php
new file mode 100644
index 0000000..25393d6
--- /dev/null
+++ b/site/app/controllers/components/search.php
@@ -0,0 +1,458 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Justin Scott <fligtar@mozilla.com>
+ * Wil Clouser <wclouser@mozilla.com>
+ * Frederic Wenzel <fwenzel@mozilla.com>
+ * Laura Thomson <lthomson@mozilla.com>
+ * Chris Pollett <cpollett@gmail.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+class SearchComponent extends Object {
+
+ var $controller;
+
+ /**
+ * Save a reference to the controller on startup
+ * @param object &$controller the controller using this component
+ */
+ function startup(&$controller) {
+ $this->controller =& $controller;
+ }
+
+ /**
+ * An associative array holding the tables/fields to search (by default)
+ *
+ * Example:
+ * $search_fields = array(
+ * array(
+ * 'table' => 'Addon',
+ * 'field' => 'name',
+ * 'priority' => 8,
+ * 'localized' => false
+ * ),
+ * array(
+ * 'table' => 'Addon',
+ * 'field' => 'description',
+ * 'priority' => 5,
+ * 'localized' => true
+ * )
+ * );
+ *
+ * @var array
+ */
+ var $search_fields = array(
+ /**
+ * these priorities are totally arbitrary
+ * @todo currently, searching for anything but addons will likely break
+ */
+ array(
+ 'table' => 'Addon',
+ 'field' => 'name',
+ 'priority' => 8,
+ 'localized' => true
+ ),
+ array(
+ 'table' => 'Addon',
+ 'field' => 'description',
+ 'priority' => 5,
+ 'localized' => true
+ ),
+ array(
+ 'table' => 'Addon',
+ 'field' => 'summary',
+ 'priority' => 5,
+ 'localized' => true
+ )
+ );
+
+ /**
+ * RegEx to split searches at spaces, respecting quotes
+ */
+ var $search_term_regex = '/([^" ]+)|(?:"([^"]*)")/';
+
+ /**
+ * The core search function. (This was named 'find' but that caused problems
+ * with simpletest)
+ *
+ * The parameters after the fourth are typically supplied by the advance search form.
+ *
+ * Note: For $atype and $platform it is assumed that -1 won't be used for an addon or platform id.
+ *
+ * @todo write tests for advance search
+ * @todo we need to be able to specify what fields to search
+ *
+ * @param string terms to search for
+ * @param string type of addon to search for, used by API
+ * @param int category to search in (0 means no restriction)
+ * @param lver, hver - version range addon version should intersect with
+ * @param vfuz - make the matching of addon range fuzzy. (so 3.0 behaves more like 3.0*, this is used because with JS enabled
+ * adv search form only gives approximate version ranges.
+ * @param atype is the addon type for advanced search
+ * @param platform is the platform id internal to Remora
+ * @param lup is the latest update time for advanced search
+ * @param sort is used to specify sort order for advanced search
+ * @param locale controls whether we search within only the current locale and en-US (faster) or all locales
+ * @return array of information about results (modified cake results)
+ */
+ function search($terms, $searchtype=NULL, $category=0, $status=NULL,
+ $lver = -1, $hver = -1, $vfuz =false, $atype = ADDON_ANY,
+ $platform= PLATFORM_ANY, $lup = "", $sort = "", $locale=false) {
+ global $valid_status, $hybrid_categories, $app_listedtypes;
+
+ if (isset($status)) {
+ switch ($status) {
+ case STATUS_PUBLIC:
+ case STATUS_SANDBOX:
+ case STATUS_PENDING:
+ case STATUS_NOMINATED:
+ $sql_status = $status;
+ break;
+ default:
+ $sql_status = implode(',',$valid_status);
+ break;
+ }
+ } else {
+ $sql_status = implode(',',$valid_status);
+ }
+
+ /* prepare SQL query */
+
+ // fields to search in
+ $fields = array('name', 'summary', 'description');
+ $_termarray = array();
+
+ // first prepare text terms
+ if (is_string($terms) && !empty($terms)) {
+ // UTF-8 aware case-insensitive search
+ $terms = mb_strtolower($terms, 'UTF-8');
+
+ // split string into single terms
+ preg_match_all($this->search_term_regex, $terms, $_termmatches);
+
+ // remove quotes around split terms and sanitize them
+ foreach ($_termmatches[0] as $term) {
+ $term = trim($term, ' "');
+ $term = $this->controller->Sanitize->sql($term);
+ if ($term) $_termarray[] = $term;
+ }
+ // now strip duplicates
+ $_termarray = array_unique($_termarray);
+ $_search_termarray = array();
+ foreach ($_termarray as $term) {
+ if (false !== strpos($term, ' ')) $term = '"'.$term.'"'; // enclose "literal phrases" in quotes
+ $_search_termarray[] = '+'.$term."*";
+ }
+
+ $text_score = " MATCH(a.".implode(', a.',$fields).") AGAINST ('".implode(" ", $_termarray)."')";
+ $boolean_score = " MATCH(a.".implode(', a.',$fields).") AGAINST ('".implode(" ", $_search_termarray)."' IN BOOLEAN MODE)";
+ } else { //in this case enumerate all addons. this allows advanced search to act as a filter
+ $text_score = "TRUE";
+ $boolean_score = "TRUE";
+ }
+
+ // now initialize compoents of SQL query
+ $_selects = $_orderby = $_joins = $_where = array();
+
+ $_orderby[] = '(LOWER(a.name) = \''.$terms.'\') DESC';
+ $_orderby[] = '(a.status='.STATUS_PUBLIC.') DESC'; // show public add-ons first
+ $_orderby[] = "(a.name LIKE '%".implode(' ', $_termarray)."%') DESC"; // sort exact name hits first
+
+ if (!$locale) {
+ $_matches = "(a.locale = '".LANG."' OR a.locale = 'en-US' ) AND ";
+ }
+ $_matches .= $boolean_score;
+
+ foreach ($fields as $field) {
+ // select strings
+ $_selects[] = "a.".$field;
+ }
+ if ($text_score !== "TRUE") {
+ $_selects[] = $text_score." AS text_score";
+ $_orderby[] = 'text_score DESC';
+ }
+ switch ($searchtype) {
+ case ADDON_EXTENSION:
+ $_addon_types = ADDON_EXTENSION;
+ break;
+ case ADDON_THEME:
+ $_addon_types = ADDON_THEME;
+ break;
+ case ADDON_PLUGIN:
+ $_addon_types = ADDON_PLUGIN;
+ break;
+ case ADDON_DICT:
+ $_addon_types = array(ADDON_DICT, ADDON_LPAPP, ADDON_LPADDON);
+ break;
+ case ADDON_SEARCH:
+ $_addon_types = ADDON_SEARCH;
+ break;
+ case ADDON_API:
+ $_addon_types = array(ADDON_EXTENSION, ADDON_THEME);
+ break;
+ default:
+ // do not show anything but extensions and themes to API users
+ // unless explicitly asked for
+ if (in_array($searchtype, $app_listedtypes[APP_ID]))
+ $_addon_types = $searchtype;
+ else {
+ $_addon_types = array(ADDON_EXTENSION, ADDON_THEME, ADDON_SEARCH, ADDON_DICT, ADDON_LPAPP, ADDON_LPADDON);
+ }
+ }
+ if (!is_array($_addon_types)) $_addon_types = array($_addon_types);
+
+ // override the odd-on type if the advanced search parameter $atype sent. Notice am assuming -1 not an add-on type
+ if ($atype != -1) $_addon_types = array($atype);
+
+ // restrict by category if necessary
+ if ($category > 0) {
+ if (!isset($hybrid_categories[APP_ID][$category])) {
+ // regular category restriction
+ $_joins[] = "INNER JOIN addons_tags AS atags ON (atags.addon_id = id AND atags.tag_id = '{$category}')";
+ } else {
+ // hybrid category
+ $_hybrid_type = $hybrid_categories[APP_ID][$category];
+ if (!in_array($_hybrid_type, $_addon_types)) $_addon_types[] = $_hybrid_type;
+
+ $_joins[] = "LEFT JOIN addons_tags AS atags ON (atags.addon_id = id AND atags.tag_id = '{$category}')";
+ $_where[] = "(a.addontype = ".$_hybrid_type." OR atags.tag_id IS NOT NULL)";
+ }
+ }
+
+ //set the last update criteria for advanced search
+ $_last_update = ($lup == "") ? "" : " AND TO_DAYS(v.created) > TO_DAYS(CURDATE() ".$lup.") ";
+
+ // per-application only (for all but search engines)
+ $_selects[] = " v.created AS created ";
+ $_joins[] = ' INNER JOIN `versions_summary` AS v ON (v.addon_id = a.id) ';
+ $_app_compat = ' v.application_id = '.APP_ID.' ';
+
+ // prepare a check for platform type (for advanced search)
+ if ($platform != PLATFORM_ANY) {
+ $_joins[] = "INNER JOIN files ON (files.platform_id IN (".PLATFORM_ALL.", $platform) AND v.version_id = files.version_id)";
+ }
+
+ /* Prepare a check for application versions (for advanced search).
+ It is hard to directly compare versions in SQL (versionCompare is a recursive method) so we are relying on preprocessing magic.
+ Suppose we are looking for addons in the version interval [A, B]. We first compute all the version ID that are contained
+ in this interval. Call this $range_wanted. We also find the ids of the intervals (-infty, A) as $below_wanted, and (B, infty)
+ as $above_wanted. Let v.min and v.max be the version range of a particular addon. We check that one of the following
+ happens: (1) v.min is in $below_wanted and v.max is in $above_wanted, so the range of the addon includes $range_wanted, or (2)
+ one of v.min or v.max is in $range_wanted. Each of the three array is used in SQL in clauses which are probably implemented
+ by mysql with in-memory hash tables so should be fast checks.
+ */
+ if ($lver != -1 && $hver != -1 ) {
+ $range_wanted = array();
+ $below_wanted = array();
+ $above_wanted = array();
+ $all_appversions = $this->controller->Amo->getVersionIdsByApp(APP_ID);
+
+ $lver = $this->controller->Sanitize->sql($lver);
+ $hver = $this->controller->Sanitize->sql($hver);
+
+ $fuz = "";
+ if (isset($this->params['url']['vfuz']) && $this->params['url']['vfuz'] == true)
+ $fuz = "*";
+
+ $vcompare = $this->controller->Versioncompare;
+
+ foreach($all_appversions as $appversion => $appvid) {
+ // because of version fuzziness may be used, the three cases below are not necessarily disjoint
+ if ($vcompare->compareVersions($appversion, $lver) < 0) {
+ $below_wanted[] = $appvid;
+ }
+ if (($vcompare->compareVersions($lver, $appversion) <= 0 || $vcompare->compareVersions($lver.$fuz, $appversion) <= 0 || $lver == 'any') &&
+ ($vcompare->compareVersions($appversion, $hver) <= 0 || $vcompare->compareVersions($appversion, $hver.$fuz) <= 0 || $hver == 'any')) {
+ $range_wanted[] = $appvid; //note we want the version id's not the version numbers
+ }
+ if ($vcompare->compareVersions($appversion, $lver) > 0) {
+ $above_wanted[] = $appvid;
+ }
+ }
+
+ $_ver_string = "('".implode("', '", $range_wanted) ."') ";
+ $vcheck = " v.min IN ".$_ver_string." OR v.max IN ".$_ver_string;
+ $_ver_string = "('".implode("', '", $below_wanted) ."') ";
+ $_ver_string2 = "('".implode("', '", $above_wanted) ."') ";
+ $vcheck .= " OR (v.min IN ".$_ver_string." AND v.max IN ".$_ver_string2.")";
+
+ if (in_array(ADDON_SEARCH, $_addon_types) ) {
+ $vcheck = "(a.addontype = ".ADDON_SEARCH." OR ".$vcheck.")";
+ }
+ $_where[] = $vcheck;
+ }
+
+ //set the last update criteria for advanced search
+ if ($lup != "") {
+ $_where[] = " TO_DAYS(v.created) > TO_DAYS(CURDATE() ".$lup.") ";
+ }
+
+ // add order-by clauses for advanced search
+ switch($sort) {
+ case 'averagerating':
+ case 'weeklydownloads':
+ array_unshift($_orderby, "a.$sort DESC");
+ break;
+ case 'name':
+ array_unshift($_orderby, "a.name ASC");
+ break;
+ case 'newest':
+ // ordering by newest version for advanced search means joining the versions table
+ array_unshift($_orderby, "created DESC");
+ break;
+ }
+
+ if (!in_array(ADDON_SEARCH, $_addon_types))
+ $_where[] = $_app_compat;
+ elseif (count($_addon_types) > 1) // mixed types (search + other)
+ $_where[] = '(a.addontype = '.ADDON_SEARCH." OR {$_app_compat})";
+ // else: only search engines => do not restrict by application
+
+ $sql = "SELECT DISTINCT a.id, " . implode(', ', $_selects)
+ ." FROM text_search_summary AS a " . implode(' ', $_joins)
+ ." WHERE $_matches "
+ ."AND a.addontype IN (" . implode(',', $_addon_types) . ") "
+ ."AND a.status IN(".$sql_status.") AND a.inactive = 0 "
+ .(empty($_where) ? '' : 'AND ('.implode(' AND ', $_where).') ')
+ ."ORDER BY ".implode(', ', $_orderby);
+
+ // query the db and return the ids found
+ $_results = $this->controller->Addon->query($sql, true);
+
+ $_result_ids = array();
+ foreach ($_results as $_result) $_result_ids[] = $_result['a']['id'];
+ return $_result_ids;
+ }
+
+
+ /**
+ * The collection search function.
+ *
+ * @param string terms to search for
+ * @param sort is used to specify sort order
+ * @param locale controls whether we search within only the current locale and en-US (faster) or all locales
+ * @return array of collection ids
+ */
+ function searchCollections($terms, $sort='', $locale=false) {
+ // fields to search in
+ $fields = array('name', 'description');
+ $_termarray = array();
+
+ // first prepare text terms
+ if (is_string($terms) && !empty($terms)) {
+ // UTF-8 aware case-insensitive search
+ $terms = mb_strtolower($terms, 'UTF-8');
+
+ // split string into single terms
+ preg_match_all($this->search_term_regex, $terms, $_termmatches);
+
+ // remove quotes around split terms and sanitize them
+ foreach ($_termmatches[0] as $term) {
+ $term = trim($term, ' "');
+ $term = $this->controller->Sanitize->sql($term);
+ if ($term) $_termarray[] = $term;
+ }
+ // now strip duplicates
+ $_termarray = array_unique($_termarray);
+ $_search_termarray = array();
+ foreach ($_termarray as $term) {
+ if (false !== strpos($term, ' ')) $term = '"'.$term.'"'; // enclose "literal phrases" in quotes
+ $_search_termarray[] = '+'.$term."*";
+ }
+
+ $text_score = " MATCH(c.".implode(', c.',$fields).") AGAINST ('".implode(" ", $_termarray)."')";
+ $boolean_score = " MATCH(c.".implode(', c.',$fields).") AGAINST ('".implode(" ", $_search_termarray)."' IN BOOLEAN MODE)";
+ } else { //in this case enumerate all collections. this allows advanced search to act as a filter
+ $text_score = "TRUE";
+ $boolean_score = "TRUE";
+ }
+
+ // now initialize compoents of SQL query
+ $_selects = $_orderby = $_where = array();
+
+ $_orderby[] = '(LOWER(c.name) = \''.$terms.'\') DESC';
+ $_orderby[] = "(c.name LIKE '%".implode(' ', $_termarray)."%') DESC"; // sort exact name hits first
+
+ if (!$locale) {
+ $_matches = "(c.locale = '".LANG."' OR c.locale = 'en-US' ) AND ";
+ }
+ $_matches .= $boolean_score;
+
+ foreach ($fields as $field) {
+ // select strings
+ $_selects[] = "c.".$field;
+ }
+ if ($text_score !== "TRUE") {
+ $_selects[] = $text_score." AS text_score";
+ $_orderby[] = 'text_score DESC';
+ }
+
+ $_where[] = "`Collection`.`application_id`='".APP_ID."'";
+ $_where[] = "`Collection`.`listed`='1'";
+
+ // sorting
+ switch($sort) {
+ case 'all':
+ array_unshift($_orderby, "`Collection`.`subscribers` DESC");
+ break;
+ case 'weekly':
+ array_unshift($_orderby, "`Collection`.`weekly_subscribers` DESC");
+ break;
+ case 'monthly':
+ array_unshift($_orderby, "`Collection`.`monthly_subscribers` DESC");
+ break;
+ case 'newest':
+ array_unshift($_orderby, "`Collection`.`created` DESC");
+ break;
+ }
+
+ // build and run query
+ $sql = "SELECT DISTINCT `c`.`id`, " . implode(', ', $_selects) . "
+ FROM `collections_search_summary` AS `c`
+ INNER JOIN `collections` AS `Collection` ON (`Collection`.`id` = `c`.`id`)
+ WHERE {$_matches}
+ ".(empty($_where) ? '' : 'AND ('.implode(' AND ', $_where).') ')."
+ ORDER BY ".implode(', ', $_orderby);
+ $_results = $this->controller->Addon->query($sql, true);
+
+ // return the ids found
+ $_result_ids = array();
+ foreach ($_results as $_result) {
+ $_result_ids[] = $_result['c']['id'];
+ }
+ return $_result_ids;
+ }
+}
+?>
diff --git a/site/app/controllers/components/simple_acl.php b/site/app/controllers/components/simple_acl.php
new file mode 100644
index 0000000..dfce478
--- /dev/null
+++ b/site/app/controllers/components/simple_acl.php
@@ -0,0 +1,172 @@
+<?php
+
+/**
+ * Created: Sun Sep 17 10:51:46 CEST 2006
+ *
+ * DESCRIPTION
+ *
+ * PHP versions 4 and 5
+ *
+ * Copyright (c) Felix Geisendörfer <info@fg-webdesign.de>
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright (c) 2006, Felix Geisendörfer.
+ * @link http://www.fg-webdesign.de/
+ * @link http://www.thinkingphp.org/
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+class SimpleAclComponent extends Object
+{
+ var $Controller;
+
+ /**
+ * You can set this to false in your AppController's beforeFilter to deactivate this Component
+ *
+ * @var boolean
+ */
+ var $enabled = true;
+
+ /**
+ * Here you can register a callback in case the User tries to access an action he's not
+ * allowed to access.
+ *
+ * @var mixed
+ */
+ var $actionDeniedCallback = null;
+
+ /**
+ * If $this->activeUser is empty, this component will be accessed to get the activeUser
+ * data. The component must support a function getActiveUser();.
+ *
+ * I would recommend you to use my SimpleAuth component for this job ; ).
+ *
+ * @var string
+ */
+ var $authComponent = 'SimpleAuth';
+
+ /**
+ * Can contain the current User data
+ *
+ * @var unknown_type
+ */
+ var $activeUser = null;
+
+ function startup(&$Controller)
+ {
+ $this->Controller = &$Controller;
+
+ // The name of the Controller and action we want to check permission for
+ $controller = $this->Controller->name;
+ $action = $this->Controller->action;
+
+ // If the component got disabled, exit.
+ if ($this->enabled===false)
+ return;
+
+ if (empty($this->activeUser) && (isset($this->Controller->{$this->authComponent})))
+ $this->activeUser = $this->Controller->{$this->authComponent}->getActiveUser();
+
+ // Check if there is an action and if we are (not) allowed to access it.
+ if (!empty($this->Controller->action) && !$this->actionAllowed($controller, $action))
+ {
+ // If there is no actionDeniedCallback defined, invoke a simple default error template (errors/permission_denied.ctp)
+ if (!$this->actionDeniedCallback)
+ {
+ header('HTTP/1.1 401 Unauthorized');
+ $this->Controller->set(compact('controller', 'action'));
+
+ $this->Controller->layout = 'mozilla';
+ $this->Controller->pageTitle = _('error_access_denied') . ' :: ' . sprintf(_('addons_home_pagetitle'), APP_PRETTYNAME);
+ $this->Controller->set('breadcrumbs', _('error_access_denied'));
+ $this->Controller->set('subpagetitle', _('error_access_denied'));
+ $this->Controller->viewPath = 'errors';
+ $this->Controller->render('error401');
+
+ // Exit here, because we're effing done.
+ exit;
+
+ }
+ else // Call the actionDeniedCallback
+ return call_user_func_array($this->actionDeniedCallback, array($controller, $action, &$this));
+ }
+ }
+
+ function actionAllowed($controller, $action, $user = null)
+ {
+ // People are not allowed by default.
+ $allowed = false;
+
+ // If our controller action is in the exceptions list, return true so the page can execute freely.
+ if (!empty($this->Controller->aclExceptions) && is_array($this->Controller->aclExceptions) && in_array($action,$this->Controller->aclExceptions)) {
+ return true;
+ }
+
+ if (empty($user) && !empty($this->activeUser))
+ $user = $this->activeUser;
+
+ if (isset($user[$this->Controller->{$this->authComponent}->groupModel]) && is_array($user[$this->Controller->{$this->authComponent}->groupModel]))
+ {
+ foreach ($user[$this->Controller->{$this->authComponent}->groupModel] as $group) {
+
+ // If we find at least one group that grants access, we can set groupAllowed to true and break the loop.
+ // We've found what we're looking for.
+ if ($this->requestAllowed($controller, $action, $group['rules'])) {
+ $allowed = true;
+ break;
+ }
+ }
+ }
+
+ return $allowed;
+ }
+
+ /**
+ * This function decides whether a given $objects's $property can be accessed based
+ * on a list of $rules. If the list of $rules is empty or doesn't match $object/$property
+ * the decision is made based on the $default value.
+ *
+ * @param string $object
+ * @param string $property
+ * @param string $rules
+ * @param boolean $allowedDefault
+ * @return boolean
+ */
+ function requestAllowed($object, $property, $rules, $default = false)
+ {
+ // The default value to return if no rule matching $object/$property can be found
+ $allowed = $default;
+
+ // This Regex converts a string of rules like "objectA:actionA,objectB:actionB,..." into the array $matches.
+ preg_match_all('/([^:,]+):([^,:]+)/is', $rules, $matches, PREG_SET_ORDER);
+ foreach ($matches as $match)
+ {
+ list($rawMatch, $allowedObject, $allowedProperty) = $match;
+
+ $allowedObject = str_replace('*', '.*', $allowedObject);
+ $allowedProperty = str_replace('*', '.*', $allowedProperty);
+
+ if (substr($allowedObject, 0, 1)=='!')
+ {
+ $allowedObject = substr($allowedObject, 1);
+ $negativeCondition = true;
+ }
+ else
+ $negativeCondition = false;
+
+ if (preg_match('/^'.$allowedObject.'$/i', $object) &&
+ ($property == '%' ||
+ preg_match('/^'.$allowedProperty.'$/i', $property)))
+ {
+ if ($negativeCondition)
+ $allowed = false;
+ else
+ $allowed = true;
+ }
+ }
+ return $allowed;
+ }
+}
+
+?>
diff --git a/site/app/controllers/components/simple_auth.php b/site/app/controllers/components/simple_auth.php
new file mode 100644
index 0000000..2cae6e3
--- /dev/null
+++ b/site/app/controllers/components/simple_auth.php
@@ -0,0 +1,163 @@
+<?php
+/**
+ * Created: Sun Sep 17 14:44:50 CEST 2006
+ *
+ * DESCRIPTION
+ *
+ * PHP versions 4 and 5
+ *
+ * Copyright (c) Felix Geisendörfer <info@fg-webdesign.de>
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright (c) 2006, Felix Geisendörfer.
+ * @link http://www.fg-webdesign.de/
+ * @link http://www.thinkingphp.org/
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+
+class SimpleAuthComponent extends Object
+{
+ /**
+ * You can set this to false in your AppController's beforeFilter to deactivate this Component
+ *
+ * @var boolean
+ */
+ var $enabled = true;
+
+ /**
+ * If you use a different Model for your users table, change this value in your
+ * AppController's beforeFilter.
+ *
+ * @var string
+ */
+ var $userModel = 'User';
+
+ /**
+ * If you use a different Model for your groups table, change this value in your
+ * AppController's beforeFilter.
+ *
+ * @var string
+ */
+ var $groupModel = 'Group';
+
+ /**
+ * Name of the field a User can be uniquely identified besides the id field.
+ *
+ * @var string
+ */
+ var $userIdentifier = 'email';
+
+ /**
+ * The $userIdentifier (name) of the default user which *has* to exist in the
+ * $userModel and is used if there is no active (logged in) user yet as the default
+ * account.
+ *
+ * @var string
+ */
+ var $defaultUser = DEFAULT_ACL_USER;
+
+ /**
+ * In case the $defaultUser couldn't be found can can provide a callback that handles this
+ * situation or leave this empty in which case a fatal php error will show up (the one
+ * already mentioned on the variable above).
+ *
+ * @var mixed
+ */
+ var $criticalErrorCallback = null;
+
+ /**
+ * Contains all data associated to the active user
+ *
+ * @var array
+ */
+ var $activeUser = null;
+
+ /**
+ * Contains the reference to the Controller.
+ *
+ * @var object
+ */
+ var $Controller;
+
+ function startup(&$Controller)
+ {
+ $this->Controller = &$Controller;
+
+ // If the component got disabled, exit.
+ if ($this->enabled===false)
+ return;
+
+ // In case a cakeError is raised, this will make sure our class continues to work
+ if (!isset($this->Controller->{$this->userModel}))
+ $this->Controller->constructClasses();
+
+ // Get the activeUser (array)
+ $this->activeUser = $this->getActiveUser();
+
+ // If no activeUser, not even the default one, could be found, raise an error
+ if (empty($this->activeUser))
+ {
+ // In case there is no registered Callback, print a simple php error message.
+ if (empty($this->criticalErrorCallback))
+ {
+ trigger_error('Unable to find a user account "'.$this->defaultUser.'". Permission Denied for security reasons.', E_USER_ERROR);
+
+ // This exit should not be needed, but since I'm not sure if there is a way you can mess things up in php.ini this stays here
+ exit;
+ }
+ else // Otherwise, call the callback function and return
+ return call_user_func_array($this->criticalErrorCallback, array($controller, $action, &$this));
+ }
+ }
+
+ function getActiveUser()
+ {
+ // If we already have an activeUser set, return it
+ if (!empty($this->activeUser))
+ return $this->activeUser;
+
+ // In case a cakeError is raised, this will make sure our class continues to work
+ if (!isset($this->Controller->{$this->userModel}))
+ $this->Controller->constructClasses();
+
+ // See if the activeUserId is stored in our session and fetch the User for it if so
+ if ($activeUserId=$this->Controller->Session->read($this->userModel.'.id'))
+ $user = $this->Controller->{$this->userModel}->findById($activeUserId);
+
+ // If no activeUserId was set, or it couldn't be found, fall back to the defaultUser account
+ if (!isset($user) || empty($user))
+ $user = $this->Controller->{$this->userModel}->find(array($this->userModel.'.'.$this->userIdentifier => $this->defaultUser));
+
+ return $user;
+ }
+
+ function setActiveUser($id, $refresh = false)
+ {
+ // If no $refresh is required, check if $id already is the active User
+ if (($refresh==false) && !empty($this->activeUser) && ($this->activeUser[$this->userModel]['id']==$id))
+ return true;
+
+ // If a numeric $id was given, find the corresponding user
+ if (is_numeric($id))
+ $user = $this->Controller->{$this->userModel}->findById($id);
+ else // Or if not, find the default User
+ $user = $this->Controller->{$this->userModel}->find(array($this->userModel.'.'.$this->userIdentifier => $this->defaultUser));
+
+ // If we couldn't find any User to make active return false
+ if (empty($user))
+ return false;
+
+ // Set the activeUser for this class
+ $this->activeUser = $user;
+
+ // And save our activeUser to the Session
+ $this->Controller->Session->write($this->userModel.'.id', $user[$this->userModel]['id']);
+
+ // Job complete
+ return true;
+ }
+}
+
+?>
diff --git a/site/app/controllers/components/src.php b/site/app/controllers/components/src.php
new file mode 100644
index 0000000..f97741d
--- /dev/null
+++ b/site/app/controllers/components/src.php
@@ -0,0 +1,72 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * Justin Scott <fligtar@gmail.com>.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+class SrcComponent extends Object {
+ /**
+ * Parses install.rdf using Rdf_parser class
+ * @param string $manifestData
+ * @return array $data["manifest"]
+ */
+ function parse($file) {
+ //If the file doesn't exist, we assume the file contents are being passed directly
+ if (file_exists($file)) {
+ $contents = file_get_contents($file);
+ }
+ else {
+ $contents = $file;
+ }
+
+ $contents = utf8_encode($contents);
+ $contents = str_replace("\n", "", $contents);
+
+ //Get the attributes of the search element
+ if (preg_match("/<search([^<]*)>/i", $contents, $matches)) {
+ $search = $matches[1];
+ //Get the description to be used as the add-on name
+ if (preg_match("/description=\"([^\"]*)\"/", $search, $matches)) {
+ return $matches[1];
+ }
+ else {
+ return false;
+ }
+ }
+ else {
+ return false;
+ }
+ }
+}
+?>
diff --git a/site/app/controllers/components/stats.php b/site/app/controllers/components/stats.php
new file mode 100644
index 0000000..3702a3c
--- /dev/null
+++ b/site/app/controllers/components/stats.php
@@ -0,0 +1,611 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Justin Scott <fligtar@mozilla.com> (Original Author)
+ * l.m.orchard <lorchard@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+class StatsComponent extends Object {
+ var $controller;
+
+ var $date_group_column_map = array(
+ 'date' => '',
+ 'month' => 'date_format(`date`, "month:%Y-%m") as `date_month`,',
+ 'week' => 'date_format(`date`, "week:%X-%V") as `date_week`,'
+ );
+
+ var $date_group_by_map = array(
+ 'date' => 'date',
+ 'month' => 'date_month',
+ 'week' => 'date_week'
+ );
+
+ /**
+ * Save a reference to the controller on startup
+ * @param object &$controller the controller using this component
+ */
+ function startup(&$controller) {
+ $this->controller =& $controller;
+ }
+
+ function historicalPlot($addon_id, $plot, $date_grouping='date') {
+
+ // Constrain the date grouping choice to valid set
+ if (!array_key_exists($date_grouping, $this->date_group_column_map)) {
+ $date_grouping = 'date';
+ }
+ $date_group_column = $this->date_group_column_map[$date_grouping];
+ $date_group_by = $this->date_group_by_map[$date_grouping];
+
+ $model =& $this->controller->Addon;
+
+ $csv = array();
+ $totalCounts = array();
+ $dynamicFields = array();
+ $dates = array();
+
+ // Warning: extensive use of ` ahead. We keenly named columns after
+ // MySQL functions
+
+ switch ($plot) {
+ // Summary of downloads and update pings per day
+ case 'summary':
+ if ($data = $model->query("
+ SELECT
+ `download_counts`.`date`,
+ `download_counts`.`count`,
+ `update_counts`.`count`
+ FROM
+ `download_counts`
+ LEFT JOIN `update_counts` ON
+ `download_counts`.`date`=`update_counts`.`date` AND
+ `download_counts`.`addon_id`=`update_counts`.`addon_id`
+ WHERE
+ `download_counts`.`addon_id`={$addon_id} AND
+ `download_counts`.`date` >= DATE_SUB(NOW(), INTERVAL 30 DAY)
+ ORDER BY
+ `download_counts`.`date`
+ ", true)) {
+ foreach ($data as $date) {
+ $csv[] = array('date' => $date['download_counts']['date'],
+ 'downloads' => $date['download_counts']['count'],
+ 'updatepings' => $date['update_counts']['count']
+ );
+ }
+ }
+
+ break;
+
+ // Downloads per day
+ case 'downloads':
+ if ($data = $model->query("
+ SELECT `date`, {$date_group_column} sum(`count`) as `count`
+ FROM `download_counts`
+ WHERE `addon_id`={$addon_id} AND date != '0000-00-00'
+ GROUP BY `{$date_group_by}`
+ ORDER BY `date`
+ ", true)) {
+ foreach ($data as $download) {
+ $csv[] = array('date' => $download['download_counts']['date'],
+ 'count' => $download['0']['count']);
+ }
+ }
+ break;
+
+ // Update pings per day
+ case 'updatepings':
+ // Since summing update pings per day isn't as useful as summing
+ // the other data points, we're taking an average here instead.
+ if ($data = $model->query("
+ SELECT `date`, {$date_group_column} AVG(`count`) as `count`
+ FROM `update_counts`
+ WHERE `addon_id`={$addon_id} AND date != '0000-00-00'
+ GROUP BY `{$date_group_by}`
+ ORDER BY `date`
+ ", true)) {
+ foreach ($data as $download) {
+ $csv[] = array('date' => $download['update_counts']['date'],
+ 'count' => $download['0']['count']);
+ }
+ }
+ break;
+
+ // Add-on versions in use per day
+ case 'version':
+ if ($data = $model->query("
+ SELECT `date`, {$date_group_column} `count`, `version`
+ FROM `update_counts`
+ WHERE `addon_id`={$addon_id} AND date != '0000-00-00'
+ ORDER BY `date`
+ ", true)) {
+ foreach ($data as $download) {
+ $date = $download['update_counts']['date'];
+
+ // Add static fields for CSV
+ $dates[$date] = array(
+ 'date' => $date,
+ 'count' => $download['update_counts']['count']
+ );
+
+ if ($date_group_by != 'date')
+ $dates[$date]['group_by'] = $download['0'][$date_group_by];
+
+ // Loop through dynamic fields
+ $items = unserialize($download['update_counts']['version']);
+ if (!empty($items)) {
+ foreach ($items as $item => $count) {
+ // Update total count for sorting
+ if (empty($dynamicFields[$item]))
+ $dynamicFields[$item] = $count;
+ else
+ $dynamicFields[$item] += $count;
+
+ $dates[$date]['dynamic'][$item] = $count;
+ }
+ }
+ }
+
+ if ($date_group_by != 'date')
+ $dates = $this->_groupAndSumDynamicFields($dates);
+
+ }
+ break;
+
+ // Application versions in use per day
+ case 'application':
+ if ($data = $model->query("
+ SELECT `date`, {$date_group_column} `count`, `application`
+ FROM `update_counts`
+ WHERE `addon_id`={$addon_id} AND date != '0000-00-00'
+ ORDER BY `date`
+ ", true)) {
+ foreach ($data as $download) {
+ $date = $download['update_counts']['date'];
+
+ // Add static fields for CSV
+ $dates[$date] = array(
+ 'date' => $date,
+ 'count' => $download['update_counts']['count']
+ );
+
+ if ($date_group_by != 'date')
+ $dates[$date]['group_by'] = $download['0'][$date_group_by];
+
+ // Loop through dynamic fields
+ $items = unserialize($download['update_counts']['application']);
+ if (!empty($items)) {
+ foreach ($items as $app => $versions) {
+ foreach ($versions as $version => $count) {
+ // Combine app GUID with version
+ $item = "{$app}/{$version}";
+
+ // Update total count for sorting
+ if (empty($dynamicFields[$item]))
+ $dynamicFields[$item] = $count;
+ else
+ $dynamicFields[$item] += $count;
+
+ $dates[$date]['dynamic'][$item] = $count;
+ }
+ }
+ }
+ }
+
+ if ($date_group_by != 'date')
+ $dates = $this->_groupAndSumDynamicFields($dates);
+
+ }
+ break;
+
+ // Status of add-ons in use per day
+ case 'status':
+ if ($data = $model->query("
+ SELECT `date`, {$date_group_column} `count`, `status`
+ FROM `update_counts`
+ WHERE `addon_id`={$addon_id} AND date != '0000-00-00'
+ ORDER BY `date`
+ ", true)) {
+ foreach ($data as $download) {
+ $date = $download['update_counts']['date'];
+
+ // Add static fields for CSV
+ $dates[$date] = array(
+ 'date' => $date,
+ 'count' => $download['update_counts']['count']
+ );
+
+ if ($date_group_by != 'date')
+ $dates[$date]['group_by'] = $download['0'][$date_group_by];
+
+ // Loop through dynamic fields
+ $items = unserialize($download['update_counts']['status']);
+ if (!empty($items)) {
+ foreach ($items as $item => $count) {
+ // Update total count for sorting
+ if (empty($dynamicFields[$item]))
+ $dynamicFields[$item] = $count;
+ else
+ $dynamicFields[$item] += $count;
+
+ $dates[$date]['dynamic'][$item] = $count;
+ }
+ }
+ }
+
+ if ($date_group_by != 'date')
+ $dates = $this->_groupAndSumDynamicFields($dates);
+
+ }
+ break;
+
+ // Operating Systems in use per day
+ case 'os':
+ if ($data = $model->query("
+ SELECT `date`, {$date_group_column} `count`, `os`
+ FROM `update_counts`
+ WHERE `addon_id`={$addon_id} AND date != '0000-00-00'
+ ORDER BY `date`
+ ", true)) {
+ foreach ($data as $download) {
+ $date = $download['update_counts']['date'];
+
+ // Add static fields for CSV
+ $dates[$date] = array(
+ 'date' => $date,
+ 'count' => $download['update_counts']['count']
+ );
+
+ if ($date_group_by != 'date')
+ $dates[$date]['group_by'] = $download['0'][$date_group_by];
+
+ // Loop through dynamic fields
+ $items = unserialize($download['update_counts']['os']);
+ if (!empty($items)) {
+ foreach ($items as $item => $count) {
+ // Update total count for sorting
+ if (empty($dynamicFields[$item]))
+ $dynamicFields[$item] = $count;
+ else
+ $dynamicFields[$item] += $count;
+
+ $dates[$date]['dynamic'][$item] = $count;
+ }
+ }
+ }
+
+ if ($date_group_by != 'date')
+ $dates = $this->_groupAndSumDynamicFields($dates);
+
+ }
+ break;
+ }
+
+ arsort($dynamicFields);
+
+ // Loop through dates and add each field to the CSV array
+ foreach ($dates as $date => $items) {
+ $record = array();
+
+ foreach ($items as $item => $value) {
+ // If item is a "normal" field like date or count, add it
+ if ($item != 'dynamic') {
+ $record[$item] = $value;
+ }
+ // If it's the array of dynamic fields, go in pre-determined order
+ else {
+ foreach ($dynamicFields as $dynamicField => $count) {
+ if (!empty($value[$dynamicField]))
+ $record[$dynamicField] = $value[$dynamicField];
+ else
+ $record[$dynamicField] = 0;
+ }
+ }
+ }
+
+ $csv[] = $record;
+ }
+
+ return $csv;
+ }
+
+ /**
+ * Aggregate all counts and dynamic field counts using the value of
+ * group by fields.
+ */
+ function _groupAndSumDynamicFields($dates) {
+
+ // Run through all the flat date-indexed results and aggregate the
+ // counts by the group_by field
+ $agg = array();
+ foreach ($dates as $date=>$stats) {
+ $group_by = $stats['group_by'];
+
+ if (!isset($agg[$group_by])) {
+ // Empty aggregate, so start off with the current stats row.
+ $agg[$group_by] = $stats;
+ } else {
+ // Add the current count to aggregate.
+ $agg[$group_by]['count'] += $stats['count'];
+ // Add all the dynamic field values to the aggregate.
+ foreach ($stats['dynamic'] as $key=>$value) {
+ if (!isset($agg[$group_by]['dynamic'][$key])) {
+ // Empty aggregate value, use current value.
+ $agg[$group_by]['dynamic'][$key] = $value;
+ } else {
+ // Add current value to aggregate.
+ $agg[$group_by]['dynamic'][$key] += $value;
+ }
+ }
+ }
+ }
+
+ // Re-index the aggregates by the date field, return results.
+ $new_dates = array();
+ foreach ($agg as $group_by=>$stats) {
+ unset($stats['group_by']);
+ $new_dates[$stats['date']] = $stats;
+ }
+ return $new_dates;
+ }
+
+ function getSummary($addon_id) {
+ $json = array(
+ 'downloads' => array(
+ 'availableDates' => array()
+ ),
+ 'updatepings' => array(
+ 'availableDates' => array(),
+ 'plotFields' => array(
+ 'version' => array(),
+ 'application' => array(),
+ 'status' => array(),
+ 'os' => array()
+ )
+ ),
+ 'prettyNames' => array(
+ 'version' => _('statistics_longnames_version'),
+ 'application' => _('statistics_longnames_application'),
+ 'status' => _('statistics_longnames_status'),
+ 'os' => _('statistics_longnames_os'),
+ 'unknown' => _('statistics_longnames_unknown')
+ ),
+ 'shortNames' => array(
+ 'version' => _('statistics_shortnames_version'),
+ 'application' => _('statistics_shortnames_application'),
+ 'status' => _('statistics_shortnames_status'),
+ 'os' => _('statistics_shortnames_os'),
+ 'unknown' => _('statistics_shortnames_unknown'),
+ )
+ );
+ $appShortnames = $this->controller->Amo->getApplicationName(null, true);
+ foreach ($appShortnames as $appShortname) {
+ $json['shortNames'][$appShortname['name']] = ucwords($appShortname['shortname']);
+ }
+
+ $appNames = $this->controller->Application->getGUIDList();
+ $json['prettyNames'] = array_merge($json['prettyNames'], $appNames);
+
+ // Downloads
+ if ($data = $this->controller->Addon->query("SELECT date FROM `download_counts` WHERE `addon_id`={$addon_id} AND date != '0000-00-00' ORDER BY `date`", true)) {
+ foreach ($data as $date) {
+ // if date isn't recorded, record it
+ if (!in_array($date['download_counts']['date'], $json['downloads']['availableDates']))
+ $json['downloads']['availableDates'][] = $date['download_counts']['date'];
+ }
+ }
+
+ // Update pings
+ if ($data = $this->controller->Addon->query("SELECT * FROM `update_counts` WHERE `addon_id`={$addon_id} AND date != '0000-00-00' ORDER BY `date`", true)) {
+ foreach ($data as $date) {
+ // if date isn't recorded, record it
+ if (!in_array($date['update_counts']['date'], $json['updatepings']['availableDates']))
+ $json['updatepings']['availableDates'][] = $date['update_counts']['date'];
+
+ // record dynamic field names
+ foreach (array_keys($json['updatepings']['plotFields']) as $dynamicField) {
+ $field = unserialize($date['update_counts'][$dynamicField]);
+
+ if (!empty($field)) {
+ foreach ($field as $name => $count) {
+ if (!is_array($count)) {
+ // fields that are only 1 level deep
+ if (empty($json['updatepings']['plotFields'][$dynamicField][$name]))
+ $json['updatepings']['plotFields'][$dynamicField][$name] = $count;
+ else
+ $json['updatepings']['plotFields'][$dynamicField][$name] += $count;
+ }
+ else {
+ // applications are 2 levels deep
+ foreach ($count as $appVersion => $appcount) {
+ // $name == app GUID
+ // make sure app is added
+ if (!array_key_exists($name, $json['updatepings']['plotFields'][$dynamicField]))
+ $json['updatepings']['plotFields'][$dynamicField][$name] = array();
+
+ // make sure app version is added
+ if (empty($json['updatepings']['plotFields'][$dynamicField][$name][$appVersion]))
+ $json['updatepings']['plotFields'][$dynamicField][$name][$appVersion] = $appcount;
+ else
+ $json['updatepings']['plotFields'][$dynamicField][$name][$appVersion] += $appcount;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // sort each field by total count
+ foreach (array_keys($json['updatepings']['plotFields']) as $dynamicField) {
+ if ($dynamicField == 'application') {
+ foreach ($json['updatepings']['plotFields'][$dynamicField] as $app => $appversions) {
+ // Causing a warning because one of the elements is 0=>false
+ if (is_array($json['updatepings']['plotFields'][$dynamicField][$app]))
+ arsort($json['updatepings']['plotFields'][$dynamicField][$app]);
+ }
+ }
+ else
+ arsort($json['updatepings']['plotFields'][$dynamicField]);
+ }
+
+ return $json;
+ }
+
+ function getEventsApp($app) {
+ if ($app == 'firefox') {
+ vendor('product-details/history/firefoxHistory.class');
+ $history = new firefoxHistory();
+ }
+ elseif ($app == 'thunderbird') {
+ vendor('product-details/history/thunderbirdHistory.class');
+ $history = new thunderbirdHistory();
+ }
+
+ $releases = $history->getReleaseDates();
+ $xml = array();
+
+ if (!empty($releases)) {
+ foreach ($releases as $version => $date) {
+ $title = sprintf(_('statistics_events_app_released'), ucwords($app)." {$version}");
+ $xml[] = '<event start="'.date('M d Y H:i:s \G\M\TO', strtotime($date)).'" title="'.$title.'" />';
+ }
+ }
+
+ return $xml;
+ }
+
+ function getEventsAddon($addon_id) {
+ $xml = array();
+
+ $name = $this->controller->Addon->getAddonName($addon_id);
+
+ $versions = $this->controller->Version->findAll(
+ "Version.addon_id={$addon_id}",
+ array('Version.version', 'Version.created'));
+
+ if (!empty($versions)) {
+ foreach ($versions as $version) {
+ $title = sprintf(_('statistics_events_addon_created'), "{$name} {$version['Version']['version']}");
+ $xml[] = '<event start="'.date('M d Y H:i:s \G\M\TO', strtotime($version['Version']['created'])).'" title="'.$title.'" />';
+ }
+ }
+
+ return $xml;
+ }
+
+ /**
+ * @return array Array of count results for the current day.
+ */
+ function getDailyStats() {
+
+ $yesterday = date('Y-m-d', strtotime('yesterday'));
+ $after = $yesterday.' 00:00:00';
+ $before = $yesterday.' 23:59:59';
+
+ $ret = array(
+ 'nomination' => '',
+ 'pending' => '',
+ 'flagged' => '',
+ 'reviews' => '',
+ 'dailyAddons' => '',
+ 'totalAddons' => '',
+ 'dailyVersions' => '',
+ 'dailyUsers' => '',
+ 'dailyImages' => '',
+ 'dailyDownloads' => '',
+ 'after' => $after,
+ 'before' => $before
+ );
+
+ $model =& $this->controller->Addon;
+
+ if ($buf = $model->query("SELECT COUNT(*) as nomination FROM addons WHERE status=3", true)) {
+ $ret['nomination'] = $buf[0][0]['nomination'];
+ unset($buf);
+ }
+
+ if ($buf = $model->query("SELECT COUNT(*) as pending FROM files WHERE status=2", true)) {
+ $ret['pending'] = $buf[0][0]['pending'];
+ unset($buf);
+ }
+
+ if ($buf = $model->query("SELECT COUNT(*) as flagged FROM addons WHERE adminreview=1", true)) {
+ $ret['flagged'] = $buf[0][0]['flagged'];
+ unset($buf);
+ }
+
+ if ($buf = $model->query("SELECT COUNT(*) as reviews FROM reviews WHERE editorreview=1", true)) {
+ $ret['reviews'] = $buf[0][0]['reviews'];
+ unset($buf);
+ }
+
+ if ($buf = $model->query("SELECT COUNT(*) as total FROM addons WHERE created >= '{$after}' AND created <= '{$before}'", true)) {
+ $ret['dailyAddons'] = $buf[0][0]['total'];
+ unset($buf);
+ }
+
+ if ($buf = $model->query("SELECT COUNT(*) as total FROM addons", true)) {
+ $ret['totalAddons'] = $buf[0][0]['total'];
+ unset($buf);
+ }
+
+ if ($buf = $model->query("SELECT COUNT(*) as total FROM versions WHERE created >= '{$after}' AND created <= '{$before}'", true)) {
+ $ret['dailyVersions'] = $buf[0][0]['total'];
+ unset($buf);
+ }
+
+ if ($buf = $model->query("SELECT COUNT(*) as total FROM users WHERE created >= '{$after}' AND created <= '{$before}'", true)) {
+ $ret['dailyUsers'] = $buf[0][0]['total'];
+ unset($buf);
+ }
+
+ if ($buf = $model->query("SELECT COUNT(*) as total FROM reviews WHERE created >= '{$after}' AND created <= '{$before}'", true)) {
+ $ret['dailyReviews'] = $buf[0][0]['total'];
+ unset($buf);
+ }
+
+ if ($buf = $model->query("SELECT COUNT(*) as total FROM previews WHERE created >= '{$after}' AND created <= '{$before}'", true)) {
+ $ret['dailyImages'] = $buf[0][0]['total'];
+ unset($buf);
+ }
+
+ if ($buf = $model->query("SELECT SUM(count) as count FROM download_counts WHERE date = '{$yesterday}'", true)) {
+ $ret['dailyDownloads'] = $buf[0][0]['count'];
+ unset($buf);
+ }
+
+ return $ret;
+ }
+}
+?>
diff --git a/site/app/controllers/components/userfunc.php b/site/app/controllers/components/userfunc.php
new file mode 100644
index 0000000..0808459
--- /dev/null
+++ b/site/app/controllers/components/userfunc.php
@@ -0,0 +1,90 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * Frederic Wenzel <fwenzel@mozilla.com>
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/**
+ * The User Functions Component provides helper functions for user/login related stuff.
+ */
+class UserfuncComponent extends Object {
+ var $components = array('Session');
+ var $controller;
+
+ /**
+ * Save a reference to the controller on startup
+ * @param object &$controller the controller using this component
+ */
+ function startup(&$controller) {
+ $this->controller =& $controller;
+ }
+
+ /**
+ * Toggles the currently logged in user's sandbox preference in the DB
+ * if necessary.
+ * @param bool sandbox enabled?
+ * @return bool success
+ */
+ function toggleSandboxPref($enable = false) {
+ if (!$this->Session->check('User'))
+ return;
+
+ $session = $this->Session->read('User');
+ if ($session['sandboxshown'] == $enable)
+ return;
+
+ /* store new preference */
+ if (!isset($this->controller->User)) {
+ loadModel('User');
+ $this->controller->User =& new User();
+ }
+ $newpref = array('User' => array(
+ 'id' => $session['id'],
+ 'sandboxshown' => ($enable?'1':'0')
+ ));
+ if (!$this->controller->User->save($newpref))
+ return false;
+
+ /* re-fetch session information */
+ $newprofile = $this->controller->User->findById($session['id']);
+ if (!empty($newprofile)) {
+ $this->Session->write('User', $newprofile['User']);
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+}
+?>
diff --git a/site/app/controllers/components/versioncompare.php b/site/app/controllers/components/versioncompare.php
new file mode 100644
index 0000000..34adc1e
--- /dev/null
+++ b/site/app/controllers/components/versioncompare.php
@@ -0,0 +1,285 @@
+<?php
+// ***** BEGIN LICENSE BLOCK *****
+// Version: MPL 1.1/GPL 2.0/LGPL 2.1
+//
+// The contents of this file are subject to the Mozilla Public License Version
+// 1.1 (the "License"); you may not use this file except in compliance with
+// the License. You may obtain a copy of the License at
+// http://www.mozilla.org/MPL/
+//
+// Software distributed under the License is distributed on an "AS IS" basis,
+// WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+// for the specific language governing rights and limitations under the
+// License.
+//
+// The Original Code is Mozilla Update.
+//
+// Contributor(s):
+// Benjamin Smedberg
+// Mike Morgan
+// Justin Scott
+// Mike Shaver
+//
+// Alternatively, the contents of this file may be used under the terms of
+// either the GNU General Public License Version 2 or later (the "GPL"), or
+// the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+// in which case the provisions of the GPL or the LGPL are applicable instead
+// of those above. If you wish to allow use of your version of this file only
+// under the terms of either the GPL or the LGPL, and not to allow others to
+// use your version of this file under the terms of the MPL, indicate your
+// decision by deleting the provisions above and replace them with the notice
+// and other provisions required by the GPL or the LGPL. If you do not delete
+// the provisions above, a recipient may use your version of this file under
+// the terms of any one of the MPL, the GPL or the LGPL.
+//
+// ***** END LICENSE BLOCK *****
+
+/**
+ * Version comparison script. The purpose of this file is to mimic the C++
+ * version comparison algorithm so version comparisons in VersionCheck.php are
+ * properly executed with expected results. This could have been accomplished
+ * by establishing a standardized versioning scheme across all Mozilla
+ * operations, but although that would make more sense, it's simply too late
+ * for that now. We cannot escape this.
+ *
+ * @package umo
+ * @subpackage core
+ */
+
+define('COMPAT_LATEST', 'latest');
+define('COMPAT_BETA', 'beta');
+define('COMPAT_ALPHA', 'alpha');
+define('COMPAT_OTHER', 'other');
+
+class VersioncompareComponent extends Object {
+ /**
+ * Parse a version part.
+ * @return array $r parsed version part.
+ */
+ function parseVersionPart($p) {
+ if ($p == '*') {
+ return array('numA' => 2147483647,
+ 'strB' => '',
+ 'numC' => 0,
+ 'extraD' => '');
+ }
+
+ preg_match('/^([-\d]*)([^-\d]*)([-\d]*)(.*)$/', $p, $m);
+
+ $r = array('numA' => intval($m[1]),
+ 'strB' => $m[2],
+ 'numC' => intval($m[3]),
+ 'extraD' => $m[4]);
+
+ if ($r['strB'] == '+') {
+ ++$r['numA'];
+ $r['strB'] = 'pre';
+ }
+
+ return $r;
+ }
+
+ /**
+ * Compare parsed version parts.
+ * @param string $an
+ * @param string $bp
+ * @return int $r
+ */
+ function cmp($an, $bn) {
+ if ($an < $bn)
+ return -1;
+
+ if ($an > $bn)
+ return 1;
+
+ return 0;
+ }
+
+ /**
+ * Recursive string comparison.
+ * @param string $as
+ * @param string $bs
+ * @return int $r
+ */
+ function strcmp($as, $bs) {
+ if ($as == $bs)
+ return 0;
+
+ if ($as == '')
+ return 1;
+
+ if ($bs == '')
+ return -1;
+
+ return strcmp($as, $bs);
+ }
+
+ /**
+ * Compare parsed version numbers.
+ * @param string $ap
+ * @param string $bp
+ * @return int $r -1|0|1
+ */
+ function compareVersionParts($ap, $bp) {
+ $avp = $this->parseVersionPart($ap);
+ $bvp = $this->parseVersionPart($bp);
+
+ $r = $this->cmp($avp['numA'], $bvp['numA']);
+ if ($r)
+ return $r;
+
+ $r = $this->strcmp($avp['strB'], $bvp['strB']);
+ if ($r)
+ return $r;
+
+ $r = $this->cmp($avp['numC'], $bvp['numC']);
+ if ($r)
+ return $r;
+
+ return $this->strcmp($avp['extraD'], $bvp['extraD']);
+ }
+
+ /**
+ * Master comparison function.
+ * @param string $a complete version string.
+ * @param string $b complete version string.
+ * @return int $r -1|0|1
+ */
+ function compareVersions($a, $b) {
+ $al = explode('.', $a);
+ $bl = explode('.', $b);
+
+ while (count($al) || count($bl)) {
+ $ap = array_shift($al);
+ $bp = array_shift($bl);
+
+ $r = $this->compareVersionParts($ap, $bp);
+ if ($r != 0)
+ return $r;
+ }
+
+ return 0;
+ }
+
+ /**
+ * Is $test between $lower and $upper (inclusive)?
+ * @param string $test complete version under test
+ * @param string $lower complete version of lower bound
+ * @param string $upper complete version of upper bound
+ */
+ function versionBetween($test, $lower, $upper) {
+ if ($this->compareVersions($test, $lower) == -1) {
+ return false;
+ }
+
+ if ($this->compareVersions($test, $upper) == 1) {
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Sort a version array, using this version comparison component
+ * @param Appversion model result array
+ * @return bool success
+ */
+ function sortAppversionArray(&$a) {
+ if (is_array(current($a))) {
+ return uasort($a, array(&$this, '_compareCakeResultVersions'));
+ }
+ else {
+ return uasort($a, array(&$this, 'compareVersions'));
+ }
+ }
+
+ /**
+ * Wrapper for compareVersions (respecting Cake's result arrays)
+ */
+ function _compareCakeResultVersions($a,$b) {
+ return $this->CompareVersions($a['Appversion']['version'], $b['Appversion']['version']);
+ }
+
+ /**
+ * Grades an array of appversions relative to their compatibility with a
+ * major version.
+ * @param string $compatibility_version major version, like 3.0 or 3.1
+ * @param array $versions array of version strings to grade
+ * @return array appversion => grade
+ */
+ function getCompatibilityGrades($compatibility_version, $versions) {
+ $this->sortAppversionArray($versions);
+ $versions = array_reverse($versions, true);
+
+ $appversions = array();
+ $highestFound = false;
+
+ foreach ($versions as $version) {
+ // If highest version hasn't been found but this is pre, count it anyway
+ if (!$highestFound && strpos($version, 'pre') !== false) {
+ $appversions[$version] = COMPAT_LATEST;
+ continue;
+ }
+ // This version is the highest without pre, so mark highest as found
+ if (!$highestFound) {
+ $appversions[$version] = COMPAT_LATEST;
+ $highestFound = true;
+ continue;
+ }
+ if (strpos($version, 'b') !== false) {
+ $appversions[$version] = COMPAT_BETA;
+ continue;
+ }
+ if (strpos($version, 'a') !== false) {
+ $appversions[$version] = COMPAT_ALPHA;
+ continue;
+ }
+ // Release candidates and final (3.1, 3.1pre, 3.1rc1) are colored as beta
+ if (strpos($version, 'rc') !== false || $version == $compatibility_version || $version == "{$compatibility_version}pre") {
+ $appversions[$version] = COMPAT_BETA;
+ continue;
+ }
+
+ $appversions[$version] = COMPAT_OTHER;
+ }
+
+ return $appversions;
+ }
+
+ /**
+ * Grades an appversion relative to a major version.
+ * @param string $version the version to grade
+ * @param string $compatibility_version the major version
+ * @param array $gradedArray array of existing grades, output from getCompatibilityGrades()
+ * @return string compatibility grade constant
+ */
+ function gradeCompatibility($version, $compatibility_version, $gradedArray) {
+ // See if maxversion is identified as related to this major version
+ if (array_key_exists($version, $gradedArray))
+ return $gradedArray[$version];
+ elseif ($this->compareVersions($version, $compatibility_version) > 0)
+ return COMPAT_LATEST;
+ else
+ return COMPAT_OTHER;
+ }
+
+ /**
+ * Returns an array of version strings corresponding to the $aliases map
+ * $version => (x, y)
+ */
+ function _versionAlias($version, $aliases) {
+ // Just return the version if there aren't any aliases.
+ if (!array_key_exists($version, $aliases)) {
+ return array($version);
+ }
+ else {
+ $alias = $aliases[$version];
+ // Make sure $version is in the returned array.
+ if (!in_array($version, $alias)) {
+ array_push($alias, $version);
+ }
+ return $alias;
+ }
+ }
+}
+?>
diff --git a/site/app/controllers/developers_controller.php b/site/app/controllers/developers_controller.php
new file mode 100644
index 0000000..308ea36
--- /dev/null
+++ b/site/app/controllers/developers_controller.php
@@ -0,0 +1,1511 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/e
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * Justin Scott <fligtar@gmail.com>.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Frederic Wenzel <fwenzel@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+require_once('Archive/Zip.php');
+
+/**
+ * Returns $object[$name], or $default if that's not set.
+ *
+ * If $name is a string of dot-separated names like 'foo.bar.baz',
+ * $object['foo']['bar']['baz'] will be returned. If any name
+ * along the way is not set, $default will be returned.
+ *
+ * If you want to fetch a name with embedded dots, look elsewhere.
+ */
+function getitem($object, $name, $default=null) {
+ $split = explode('.', $name, 2);
+ if (count($split) == 2) {
+ list($a, $b) = $split;
+ return isset($object[$a]) ? getitem($object[$a], $b, $default)
+ : $default;
+ } else {
+ return isset($object[$name]) ? $object[$name] : $default;
+ }
+}
+
+class DevelopersController extends AppController
+{
+ var $name = 'Developers';
+ var $uses = array('Addon', 'Addontype', 'Application', 'Approval', 'Appversion',
+ 'EditorSubscription', 'Eventlog', 'File', 'License', 'Platform', 'Preview', 'Review',
+ 'Tag', 'Translation', 'User', 'Version');
+ var $components = array('Amo', 'Developers', 'Editors', 'Email', 'Error',
+ 'Image', 'Opensearch', 'Rdf', 'Src', 'Versioncompare');
+ var $helpers = array('Html', 'Javascript', 'Ajax', 'Link', 'Listing', 'Localization', 'Form');
+ var $addVars = array(); //variables accessible to all additem steps
+
+ /**
+ * Require login for all actions
+ */
+ function beforeFilter() {
+ // Disable ACLs because this controller is entirely public.
+ $this->SimpleAuth->enabled = false;
+ $this->SimpleAcl->enabled = false;
+
+ // beforeFilter() is apparently called before components are initialized. Cake++
+ $this->Amo->startup($this);
+ $this->Amo->checkLoggedIn();
+
+ // Clean post data
+ $this->Amo->clean($this->data);
+
+ $this->layout = 'mozilla';
+ $this->pageTitle = _('devcp_pagetitle').' :: '.sprintf(_('addons_home_pagetitle'), APP_PRETTYNAME);
+
+ $this->cssAdd = array('developers');
+ $this->publish('cssAdd', $this->cssAdd);
+
+ $this->jsAdd = array('developers', 'json');
+ $this->publish('jsAdd', $this->jsAdd);
+
+ $this->publish('expand_categories', true);
+
+ $this->breadcrumbs = array(_('devcp_pagetitle') => '/developers/index');
+ $this->publish('breadcrumbs', $this->breadcrumbs);
+
+ $this->publish('subpagetitle', _('devcp_pagetitle'));
+
+ global $native_languages;
+ $this->set('nativeLanguages', $native_languages);
+
+ // disable query caching so devcp changes are visible immediately
+ foreach ($this->uses as $_model) {
+ $this->$_model->caching = false;
+ }
+
+ // Default "My Add-ons" sidebar data
+ $session = $this->Session->read('User');
+ $this->publish('all_addons', $this->Addon->getAddonsByUser($session['id']));
+
+ // Include the dev_agreement column on developer pages.
+ array_push($this->Addon->default_fields, 'dev_agreement');
+ }
+
+ /**
+ * Developer Dashboard
+ */
+ function dashboard() {
+ $session = $this->Session->read('User');
+
+ $addon_ids = $this->Addon->getAddonsByUser($session['id']);
+ $addons = array();
+
+ if (!empty($addon_ids)) {
+ foreach ($addon_ids as $addon_id => $addon_name) {
+ $addon = $this->Addon->find("Addon.id={$addon_id}");
+
+ if (!empty($addon['Version'][0])) {
+ $files = $this->File->findAll("File.version_id={$addon['Version'][0]['id']}");
+
+ if (!empty($files)) {
+ foreach ($files as $file) {
+ $addon['Version'][0]['File'][] = $file['File'];
+ }
+ }
+ }
+
+ $addon['Addon']['updatepings'] = $this->Addon->getMostRecentUpdatePingCount($addon_id);
+
+ $addons[] = $addon;
+ }
+ }
+
+ $this->publish('addons', $addons);
+ $this->publish('statuses', $this->Amo->getStatusNames());
+ $this->publish('addontypes', $this->Addontype->getNames());
+
+ $this->render('dashboard');
+ }
+
+ function json($action, $additional = '') {
+ switch ($action) {
+ case 'fileupload':
+ if ($additional == 'new') {
+ $json = $this->_newAddonFromFile();
+ }
+ elseif ($additional == 'update') {
+ $json = $this->_updateAddonFromFile($additional);
+ }
+ elseif ($additional == 'file') {
+ $json = $this->_updateAddonFromFile($additional);
+ }
+
+ $this->publish('encapsulate', true);
+ break;
+
+ case 'verifyauthor':
+ $json = $this->_verifyAuthor($_GET['email']);
+ break;
+ }
+
+ $this->set('json', $json);
+ $this->render('json', 'ajax');
+ }
+
+ /**
+ * Handler for add-on-centric actions
+ * @param string $action action to take
+ * @param int $addon_id add-on id, if necessary
+ * @param string $additional additional parameter (e.g. subaction)
+ */
+ function addon($action, $addon_id = 0, $additional = null) {
+ if (!empty($addon_id)) {
+ // Make sure user has some permissions to view this add-on
+ $role = $this->Amo->getAuthorRole($addon_id);
+ if (empty($role)) {
+ $this->Amo->accessDenied();
+ }
+
+ $addon_name = $this->Addon->getAddonName($addon_id);
+ if ($addon_name !== false) {
+ $this->publish('author_role', $role);
+ $this->publish('addon_name', $addon_name);
+ $this->publish('addon_id', $addon_id);
+ }
+ else {
+ $this->flash(_('error_addon_notfound'), '/developers/dashboard');
+ return;
+ }
+ }
+
+ switch ($action) {
+ case 'details':
+ $this->setAction('_addonDetails', $addon_id);
+ break;
+
+ case 'edit':
+ $this->setAction('_editAddon', $addon_id, $additional);
+ break;
+
+ case 'status':
+ $this->setAction('_changeAddonStatus', $addon_id, $additional);
+ break;
+
+ case 'submit':
+ $this->setAction('_submitAddon');
+ break;
+ }
+ }
+
+ /**
+ * Shows add-on details
+ */
+ function _addonDetails($addon_id) {
+ $this->publish('action', 'details');
+
+ $this->render('addon_details');
+ }
+
+ /**
+ * Displays uploader for submitting add-ons
+ */
+ function _submitAddon() {
+ $this->publish('type', 'new');
+ $this->publish('hasAgreement', false);
+
+ $this->render('uploader');
+ }
+
+ /**
+ * Called via AJAX to handle creation of a new add-on
+ */
+ function _newAddonFromFile() {
+ $data = $this->_validateUpload();
+ if ($data['error'] == 1) {
+ return $data;
+ }
+
+ // For non-search-engines
+ if ($data['Addon']['addontype_id'] != ADDON_SEARCH) {
+ // Make sure GUID doesn't exist already
+ if ($existing = $this->Addon->findAll("Addon.guid='{$data['Addon']['guid']}'")) {
+ return $this->Error->getJSONforError(sprintf(___('devcp_new_addon_error'), $data['Addon']['guid'], $this->url("/developers/versions/add/{$existing[0]['Addon']['id']}")));
+ }
+ }
+
+ // Insert new add-on row
+ $this->Addon->id = 0;
+ $this->Addon->save($data['Addon']);
+ $data['Addon']['id'] = $this->Addon->getLastInsertId();
+
+ // Add user as author
+ $session = $this->Session->read('User');
+ $this->Addon->saveAuthor($data['Addon']['id'], $session['id']);
+
+ // Save License
+ $license_id = $this->Developers->saveLicense(
+ $this->data['License'],
+ getitem($this->data, 'License.text'),
+ getitem($this->params, 'form.data.License'));
+ $this->Addon->saveField('dev_agreement', 1);
+
+ // Add Version
+ $this->Version->id = 0;
+ $data['Version']['addon_id'] = $data['Addon']['id'];
+ $data['Version']['license_id'] = $license_id;
+ $this->Version->save($data['Version']);
+ $data['Version']['id'] = $this->Version->getLastInsertId();
+
+ // Save appversions
+ if (!empty($data['appversions'])) {
+ foreach ($data['appversions'] as $appversion) {
+ $this->Version->addCompatibleApp($data['Version']['id'], $appversion['application_id'], $appversion['min'], $appversion['max']);
+ }
+ }
+
+ // Add Files
+ $data['File']['db']['version_id'] = $data['Version']['id'];
+ $platforms = $data['File']['db']['platform_id'];
+ foreach ($platforms as $platform_id) {
+ $this->File->id = 0;
+ $data['File']['db']['platform_id'] = $platform_id;
+ $validate = $this->Developers->moveFile($data);
+ if (is_string($validate)) {
+ // If a string is returned, there was an error
+ return $this->Error->getJSONforError($validate);
+ }
+ $data['File']['db']['filename'] = $validate['filename'];
+ $this->File->save($data['File']['db']);
+ }
+ // Remove temp file
+ $tempFile = $data['File']['details']['path'];
+ if (file_exists($tempFile)) {
+ unlink($tempFile);
+ }
+
+ return array(
+ 'error' => 0,
+ 'uploadtype' => 'new',
+ 'addon_id' => $data['Addon']['id']
+ );
+ }
+
+ /**
+ * Called via AJAX to handle updating of an add-on
+ * @param string $type whether an update or new file
+ */
+ function _updateAddonFromFile($type = '') {
+ // Validate file for content problems
+ $data = $this->_validateUpload();
+ if ($data['error'] == 1) {
+ return $data;
+ }
+
+ $addon_id = $this->data['Addon']['id'];
+ $data['Addon']['id'] = $addon_id;
+
+ // Make sure user has upload permissions
+ $role = $this->Amo->getAuthorRole($addon_id);
+ if (empty($role) || $role < AUTHOR_ROLE_DEV) {
+ return $this->Error->getJSONforError(___('devcp_update_addon_priv_error'));
+ }
+
+ $addon = $this->Addon->findById($addon_id);
+
+ // For non-search-engines
+ if ($data['Addon']['addontype_id'] != ADDON_SEARCH) {
+ // Make sure GUID matches add-on ID
+ if ($addon['Addon']['guid'] != $data['Addon']['guid']) {
+ return $this->Error->getJSONforError(sprintf(___('devcp_update_addon_guid_error'), $data['Addon']['guid'], $addon['Addon']['guid']));
+ }
+ }
+
+ if ($type == 'update') {
+ // Make sure version doesn't exist already
+ $vcheck = $this->Version->find("Version.addon_id={$addon_id} AND Version.version='{$data['Version']['version']}'");
+ if (!empty($vcheck)) {
+ return $this->Error->getJSONforError(sprintf(___('devcp_update_addon_version_exists_error'), $data['Version']['version'], $this->url('/developers/versions/addfile/'.$vcheck['Version']['id'])));
+ }
+
+ // Save License
+ if ($addon['Addon']['dev_agreement'] == true) {
+ // If we already have an agreement, we didn't show the license
+ // picker, so use the previously selected license.
+ global $valid_status;
+ $old_id = $this->Version->getVersionByAddonId($addon_id, $valid_status);
+ $oldVersion = $this->Version->findById($old_id);
+ $license_id = $oldVersion['Version']['license_id'];
+ } else {
+ $license_id = $this->Developers->saveLicense(
+ $this->data['License'],
+ getitem($this->data, 'License.text'),
+ getitem($this->params, 'form.data.License'));
+ }
+ $this->Addon->save(array('Addon' => array('id' => $addon_id,
+ 'dev_agreement' => 1)));
+
+ // Add Version
+ $this->Version->id = 0;
+ $data['Version']['addon_id'] = $addon_id;
+ $data['Version']['license_id'] = $license_id;
+ $this->Version->save($data['Version']);
+ $version_id = $this->Version->getLastInsertId();
+
+ // If add-on is public, cancel any pending files
+ if ($addon['Addon']['status'] == STATUS_PUBLIC) {
+ $this->Addon->execute("UPDATE files SET status = ".STATUS_SANDBOX." WHERE files.version_id IN (SELECT id FROM versions WHERE versions.addon_id={$addon_id}) AND files.status = ".STATUS_PENDING);
+ }
+
+ // Save appversions
+ if (!empty($data['appversions'])) {
+ foreach ($data['appversions'] as $appversion) {
+ $this->Version->addCompatibleApp($version_id, $appversion['application_id'], $appversion['min'], $appversion['max']);
+ }
+ }
+
+ // notify subscribed editors of update (if any)
+ $this->Editors->updateNotify($addon['Addon']['id'], $version_id);
+ }
+ elseif ($type == 'file') {
+ $version_id = $this->data['Version']['id'];
+
+ // Make sure version id belongs to this add-on
+ $vcheck = $this->Version->find("Version.id={$version_id} AND Version.addon_id={$addon_id}");
+ if (empty($vcheck)) {
+ return $this->Error->getJSONforError(sprintf(___('devcp_update_addon_version_belong_error'), $version_id, $addon_id));
+ return $this->Error->getJSONforError(sprintf('The specified version (%1$s) does not belong to this add-on (%2$s).', $version_id, $addon_id));
+ }
+
+ // Make sure version number matches
+ if ($vcheck['Version']['version'] != $data['Version']['version']) {
+ return $this->Error->getJSONforError(sprintf(___('devcp_update_addon_version_match_error'), $data['Version']['version'], $vcheck['Version']['version']));
+ }
+ }
+ $data['Version']['id'] = $version_id;
+
+ // Add Files
+ $data['File']['db']['version_id'] = $version_id;
+ $platforms = $data['File']['db']['platform_id'];
+
+ // Make trusted add-ons public
+ if ($addon['Addon']['trusted'] == 1) {
+ $data['File']['db']['status'] = STATUS_PUBLIC;
+ }
+ elseif ($addon['Addon']['status'] == STATUS_PUBLIC) {
+ $data['File']['db']['status'] = STATUS_PENDING;
+ }
+ else {
+ $data['File']['db']['status'] = STATUS_SANDBOX;
+ }
+
+ foreach ($platforms as $platform_id) {
+ $this->File->id = 0;
+ $data['File']['db']['platform_id'] = $platform_id;
+ $validate = $this->Developers->moveFile($data);
+ if (is_string($validate)) {
+ // If a string is returned, there was an error
+ return $this->Error->getJSONforError($validate);
+ }
+ $data['File']['db']['filename'] = $validate['filename'];
+ $this->File->save($data['File']['db']);
+ }
+ // Remove temp file
+ $tempFile = $data['File']['details']['path'];
+ if (file_exists($tempFile)) {
+ unlink($tempFile);
+ }
+
+ $pending = $this->Addon->query("SELECT COUNT(*) AS pending FROM files WHERE status=".STATUS_PENDING." GROUP BY status");
+ $pendingCount = (!empty($pending[0][0]['pending']) ? ($pending[0][0]['pending'] - 1) : 0);
+
+ return array(
+ 'error' => 0,
+ 'uploadtype' => $type,
+ 'addon_id' => $addon_id,
+ 'version_id' => $version_id,
+ 'version' => (string) $data['Version']['version'],
+ 'status' => $data['File']['db']['status'],
+ 'queuecount' => $pendingCount
+ );
+ }
+
+ /**
+ * Validates the file upload for all types of uploads
+ */
+ function _validateUpload() {
+ // This will store all data to be saved
+ $addon = array();
+
+ // Make sure a file was uploaded
+ if (empty($_FILES['file']['name'])) {
+ return $this->Error->getJSONforError(_('devcp_error_upload_file'));
+ }
+
+ // Detect add-on type based on file
+ $addon['Addon']['addontype_id'] = $this->Developers->detectAddontype($_FILES['file']);
+ if (empty($addon['Addon']['addontype_id'])) {
+ // Default to extension if add-on type undetectable. If this isn't
+ // an add-on at all, it will be caught later with extension checks.
+ $addon['Addon']['addontype_id'] = ADDON_EXTENSION;
+ }
+
+ // Validate file upload for basic errors and get some info
+ $validate = $this->Developers->validateFile($_FILES['file'], $addon);
+ if (is_string($validate)) {
+ // If a string is returned, there was an error
+ return $this->Error->getJSONforError($validate);
+ }
+ else {
+ // If an array is returned, there were no errors
+ $addon['File']['details'] = $validate;
+ $addon['File']['db'] = array(
+ 'platform_id' => !empty($this->data['File']['platform_id']) ? $this->data['File']['platform_id'] : array(PLATFORM_ALL),
+ 'size' => $validate['size'],
+ 'filename' => $validate['filename'],
+ 'hash' => $validate['hash'],
+ 'status' => STATUS_SANDBOX,
+ 'datestatuschanged' => $this->Amo->getNOW()
+ );
+ }
+
+ // Parse install.rdf file if not a search plugin
+ if ($addon['Addon']['addontype_id'] != ADDON_SEARCH) {
+ // Extract install.rdf from xpi or jar
+ $zip = new Archive_Zip($addon['File']['details']['path']);
+ $extraction = $zip->extract(array('extract_as_string' => true, 'by_name' => array('install.rdf')));
+
+ // Make sure install.rdf is present
+ if (empty($extraction)) {
+ $validAppReference = sprintf(_('devcp_valid_app_reference'), '<a href=\''.$this->url('/pages/appversions').'\'>'._('devcp_valid_app_reference_linktext').'</a>');
+ return $this->Error->getJSONforError(_('devcp_error_index_rdf_notfound').'<br />'.$validAppReference);
+ }
+
+ $fileContents = $extraction[0]['content'];
+
+ // Use RDF Component to parse install.rdf
+ $manifestData = $this->Rdf->parseInstallManifest($fileContents);
+
+ // Clean manifest data
+ $this->Amo->clean($manifestData);
+
+ // Validate manifest data
+ $validate = $this->Developers->validateManifestData($manifestData);
+ if (is_string($validate)) {
+ // If a string is returned, there was an error
+ return $this->Error->getJSONforError($validate);
+ }
+
+ // Last minute add-on type correction
+ if ($manifestData['type'] == 8) {
+ $addon['Addon']['addontype_id'] = ADDON_LPAPP;
+ }
+ elseif ($manifestData['type'] == 4) {
+ $addon['Addon']['addontype_id'] = ADDON_THEME;
+ }
+
+ $addon['Addon']['guid'] = $manifestData['id'];
+ $addon['Addon']['name'] = $manifestData['name']['en-US'];
+ $addon['Addon']['summary'] = $manifestData['description']['en-US'];
+ $addon['Addon']['homepage'] = $manifestData['homepageURL'];
+ $addon['Version']['version'] = $manifestData['version'];
+
+ // Validate target applications
+ $validate = $this->Developers->validateTargetApplications($manifestData['targetApplication']);
+ if (is_string($validate)) {
+ // If a string is returned, there was an error
+ return $this->Error->getJSONforError($validate);
+ }
+ else {
+ // If an array is returned, there were no errors
+ $addon['appversions'] = $validate;
+ }
+ }
+ elseif ($addon['Addon']['addontype_id'] == ADDON_SEARCH) {
+ // Get search engine properties
+ $search = $this->Opensearch->parse($addon['File']['details']['path']);
+
+ // There was a parse error, the name was empty, etc. Bad things.
+ if ($search == null) {
+ return $this->Error->getJSONforError(___('devcp_verify_search_engine_error','Either the XML is invalid or required fields are missing. Please <a href="https://developer.mozilla.org/en/Creating_OpenSearch_plugins_for_Firefox">read the documentation</a>, verify your add-on, and try again.'));
+ }
+
+ $addon['Addon']['name'] = $search->name;
+ $addon['Addon']['summary'] = $search->description;
+ $addon['Version']['version'] = date('Ymd');
+
+ // Clean search engine data
+ $this->Amo->clean($addon);
+ }
+
+ $addon['error'] = 0;
+ return $addon;
+ }
+
+ function _verifyAuthor($email) {
+ $this->Amo->clean($email);
+
+ $result = $this->User->findByEmail($email);
+
+ if (!empty($result)) {
+ return array(
+ 'error' => 0,
+ 'id' => $result['User']['id'],
+ 'displayname' => "{$result['User']['firstname']} {$result['User']['lastname']} ({$result['User']['email']})"
+ );
+ }
+ else {
+ return $this->Error->getJSONforError(___('devcp_verify_author_error'));
+ }
+ }
+
+ /**
+ * Handler for subactions of editing an add-on
+ * @param int $addon_id the add-on id
+ * @param string $action the subaction to edit
+ */
+ function _editAddon($addon_id = 0, $action = null) {
+ // Make sure add-on ID was passed
+ if (empty($addon_id)) {
+ $this->flash(_('error_addon_notfound'), '/developers', 6);
+ return;
+ }
+
+ $this->publish('action', 'edit');
+ $this->publish('subaction', $action);
+
+ switch ($action) {
+ case 'properties':
+ $this->setAction('_editAddonProperties', $addon_id);
+ break;
+
+ case 'descriptions':
+ $this->setAction('_editAddonDescriptions', $addon_id);
+ break;
+
+ case 'categories':
+ $this->setAction('_editAddonCategories', $addon_id);
+ break;
+
+ case 'authors':
+ $this->setAction('_editAddonAuthors', $addon_id);
+ break;
+
+ default:
+ $this->render('addon_edit');
+ break;
+ }
+
+ return;
+ }
+
+ /**
+ * Edit Add-on Properties
+ * @param int $addon_id the add-on id
+ */
+ function _editAddonProperties($addon_id) {
+ // Save translations if POST data
+ if (!empty($this->data['Addon']) && $this->viewVars['author_role'] >= AUTHOR_ROLE_DEV) {
+ // Split localized fields from other fields
+ list($localizedFields, $unlocalizedFields) = $this->Addon->splitLocalizedFields($this->data['Addon']);
+
+ // Handle icon before non-db fields are stripped
+ if (!empty($unlocalizedFields['icon']['name'])) {
+ $iconData = $this->Developers->validateIcon($unlocalizedFields['icon']);
+ if (is_string($iconData)) {
+ $errors['icon'] = $iconData;
+ }
+ else {
+ $unlocalizedFields = array_merge($unlocalizedFields, $iconData);
+ }
+ }
+ elseif (!empty($unlocalizedFields['deleteIcon'])) {
+ // Delete icon if requested
+ $unlocalizedFields['icontype'] = '';
+ $unlocalizedFields['icondata'] = '';
+ }
+
+ // Make sure only allowed fields are saved
+ $allowedFields = array('defaultlocale', 'viewsource', 'prerelease',
+ 'sitespecific', 'externalsoftware', 'binary',
+ 'icondata', 'icontype');
+
+ // If an admin, allow additional fields
+ if ($this->SimpleAcl->actionAllowed('Admin', 'ConfigureAnyAddon', $this->Session->read('User'))) {
+ $allowedFields = array_merge($allowedFields, array(
+ 'addontype_id', 'trusted', 'target_locale', 'locale_disambiguation', 'guid'
+ ));
+ }
+
+ $unlocalizedFields = $this->Addon->stripFields($unlocalizedFields, $allowedFields);
+
+ // Make sure all checkbox fields have values
+ $checkboxes = array('prerelease', 'sitespecific', 'externalsoftware',
+ 'binary');
+ foreach ($checkboxes as $checkbox) {
+ if (!isset($unlocalizedFields[$checkbox])) {
+ $unlocalizedFields[$checkbox] = 0;
+ }
+ }
+
+ $this->Addon->id = $addon_id;
+ $this->Addon->saveTranslations($addon_id, $this->params['form']['data']['Addon'], $localizedFields);
+ $this->Addon->save($unlocalizedFields);
+
+ if (empty($errors)) {
+ $this->publish('success', true);
+ }
+ else {
+ $this->publish('errors', $errors);
+ }
+ }
+
+ $translations = $this->Addon->getAllTranslations($addon_id);
+ $this->set('translations', $translations);
+
+ $addon = $this->Addon->findById($addon_id);
+ $this->set('addon', $addon);
+
+ $this->set('addontypes', $this->Addontype->getNames());
+
+ $this->render('addon_edit_properties');
+ }
+
+ /**
+ * Edit Add-on Descriptions
+ * @param int $addon_id the add-on id
+ */
+ function _editAddonDescriptions($addon_id) {
+ // Save translations if POST data
+ if (!empty($this->data['Addon']) && $this->viewVars['author_role'] >= AUTHOR_ROLE_DEV) {
+ $this->Addon->saveTranslations($addon_id, $this->params['form']['data']['Addon'], $this->data['Addon']);
+ // flush cached add-on objects
+ if (QUERY_CACHE) $this->Addon->Cache->markListForFlush("addon:{$addon_id}");
+
+ $this->publish('success', true);
+ }
+
+ $translations = $this->Addon->getAllTranslations($addon_id);
+ $this->set('translations', $translations);
+
+ $addon = $this->Addon->findById($addon_id);
+ $this->set('addon', $addon);
+
+ $this->render('addon_edit_descriptions');
+ }
+
+ function _editAddonCategories($addon_id) {
+ // Save categories if POST data
+ if (!empty($this->data['Tag']) && $this->viewVars['author_role'] >= AUTHOR_ROLE_DEV) {
+ $this->Tag->saveCategories($addon_id, $this->data['Tag']);
+ // flush cached add-on objects
+ if (QUERY_CACHE) $this->Addon->Cache->markListForFlush("addon:{$addon_id}");
+
+ $this->publish('success', true);
+ }
+
+ $addon = $this->Addon->findById($addon_id);
+
+ if ($addon['Addon']['addontype_id'] == ADDON_SEARCH) {
+ // Search engines don't have supported applications
+ $supportedApps = array(
+ 0 => array(
+ 'Application' => array(
+ 'id' => APP_FIREFOX
+ )
+ )
+ );
+ }
+ else {
+ // Get all applications the add-on has ever supported
+ $supportedApps = $this->Addon->getApplicationsEverSupported($addon_id);
+ }
+
+ // All tags for add-on's type and supported applications
+ $tagDescriptions = array();
+ $sortedTags = array();
+ if (!empty($supportedApps)) {
+ foreach ($supportedApps as $supportedApp) {
+ $tags = $this->Tag->findAll("Tag.addontype_id={$addon['Addon']['addontype_id']} AND Tag.application_id={$supportedApp['Application']['id']}");
+
+ $sorted = array();
+ if (!empty($tags)) {
+ foreach ($tags as $tag) {
+ $sorted[$tag['Tag']['id']] = $tag['Translation']['name']['string'];
+ $tagDescriptions[$tag['Tag']['id']] = $tag['Translation']['description']['string'];
+ }
+ asort($sorted);
+ }
+
+ $sortedTags[$supportedApp['Application']['id']] = $sorted;
+ }
+ }
+
+ $this->set('sortedTags', $sortedTags);
+ $this->set('tagDescriptions', $tagDescriptions);
+
+ // Currently selected tags
+ $currentTags = array();
+ if (!empty($addon['Tag'])) {
+ foreach ($addon['Tag'] as $tag) {
+ $currentTags[] = $tag['id'];
+ }
+ }
+ $this->publish('currentTags', $currentTags);
+
+ $this->publish('applications', $this->Application->getIDList());
+
+ // The "Other" category for each application that has one
+ if ($addon['Addon']['addontype_id'] == ADDON_SEARCH) {
+ $otherTags = array(
+ 1 => 82
+ );
+ }
+ else {
+ $otherTags = array(
+ 1 => 73,
+ 59 => 49,
+ 18 => 50,
+ );
+ }
+ $this->publish('otherTags', $otherTags);
+
+ $this->render('addon_edit_categories');
+ }
+
+ /**
+ * Edit Add-on Authors
+ * @param int $addon_id the add-on id
+ */
+ function _editAddonAuthors($addon_id) {
+
+ // Save authors if POST data
+ if (!empty($this->data['addons_users']) && $this->viewVars['author_role'] >= AUTHOR_ROLE_OWNER) {
+ // Start a transaction
+ $this->Addon->begin();
+
+ // Clear current authors
+ $this->Addon->clearAuthors($addon_id);
+
+ // Add back authors
+ $position = 1;
+ foreach ($this->data['addons_users'] as $user_id => $fields) {
+ $this->Amo->clean($user_id);
+ $allowedRoles = array(AUTHOR_ROLE_OWNER, AUTHOR_ROLE_DEV, AUTHOR_ROLE_VIEWER);
+
+ $role = $fields['role'];
+ $role = in_array($role, $allowedRoles) ? $role : AUTHOR_ROLE_OWNER;
+ $listed = !empty($fields['listed']) ? 1 : 0;
+
+ $this->Addon->saveAuthor($addon_id, $user_id, $role, $listed, $position);
+ $position++;
+ }
+
+ // Commit the transaction
+ $this->Addon->commit();
+
+ $this->publish('success', true);
+ }
+
+ $authors = $this->Addon->getAuthors($addon_id, false);
+ $this->publish('authors', $authors);
+
+ $this->render('addon_edit_authors');
+ }
+
+ /**
+ * Change Add-on Status
+ * @param int $addon_id the add-on id
+ */
+ function _changeAddonStatus($addon_id, $action = '') {
+ $this->publish('action', 'status');
+
+ if (!empty($action)) {
+ $this->Addon->id = $addon_id;
+ if (!$this->_addonStatusAction($action)) {
+ return;
+ }
+ }
+
+ $addon = $this->Addon->findById($addon_id, array('id', 'addontype_id', 'inactive', 'trusted', 'status', 'higheststatus'), null, -1);
+ $this->set('addon', $addon);
+ $this->publish('statuses', $this->Amo->getStatusNames());
+
+ $this->publish('criteria', $this->_checkCriteria($addon_id));
+
+ $nominated = $this->Addon->query("SELECT COUNT(*) AS nominated FROM addons WHERE status=".STATUS_NOMINATED." GROUP BY status");
+ $this->publish('nominationCount', !empty($nominated[0][0]['nominated']) ? ($nominated[0][0]['nominated'] - 1) : 0);
+
+ $this->render('addon_status');
+ }
+
+ /**
+ * Checks criteria for add-on completion and nomination
+ * @param int $addon_id the add-on id
+ */
+ function _checkCriteria($addon_id) {
+ $addon = $this->Addon->findById($addon_id);
+ $previews = $this->Preview->findAllByAddon_id($addon_id);
+ $versions = array();
+ if (!empty($addon)) {
+ foreach ($addon['Version'] as $version) {
+ $versions[] = $version['id'];
+ }
+ }
+ if (!empty($versions)) {
+ $versions = implode(',', $versions);
+ $reviews = $this->Review->findAll("Review.version_id IN ({$versions})");
+ }
+
+ $criteria = array();
+ $criteria['name'] = !empty($addon['Translation']['name']['string']);
+ $criteria['summary'] = !empty($addon['Translation']['summary']['string']);
+ $criteria['description'] = !empty($addon['Translation']['description']['string']);
+ $criteria['category'] = !empty($addon['Tag']);
+ $criteria['previews'] = !empty($previews);
+ $criteria['prerelease'] = !empty($addon['Addon']['prerelease']) ? false : true;
+
+ return $criteria;
+ }
+
+ /**
+ * Handles actions for changing statuses
+ * @param string $action the action
+ */
+ function _addonStatusAction($action) {
+ $this->publish('subaction', $action);
+
+ $addon = $this->Addon->findById($this->viewVars['addon_id'], array('id', 'addontype_id', 'nominationmessage', 'status', 'higheststatus'), null, -1);
+ $this->publish('addon', $addon);
+
+ // Complete an add-on
+ if ($action == 'complete' && $addon['Addon']['status'] == STATUS_NULL) {
+ $criteria = $this->_checkCriteria($this->viewVars['addon_id']);
+
+ // Make sure criteria is fulfilled
+ if (!$criteria['name'] || !$criteria['summary'] || !$criteria['description'] || !$criteria['category']) {
+ return true;
+ }
+
+ $addonData = array('status' => STATUS_SANDBOX, 'higheststatus' => STATUS_SANDBOX);
+ $this->Addon->save($addonData);
+ $this->publish('success', true);
+ if (QUERY_CACHE) $this->Addon->Cache->markListForFlush("addon:{$addon['Addon']['id']}");
+ return true;
+ }
+
+ // Other actions
+ if (!empty($_POST['confirmed']) && $this->viewVars['author_role'] >= AUTHOR_ROLE_DEV) {
+ if ($action == 'inactive') {
+ $addonData = array('inactive' => 1);
+ $this->Addon->save($addonData);
+ $this->publish('success', true);
+ }
+ elseif ($action == 'active') {
+ $addonData = array('inactive' => 0);
+ $this->Addon->save($addonData);
+ $this->publish('success', true);
+ }
+ elseif ($action == 'sandbox') {
+ if ($addon['Addon']['status'] == STATUS_PUBLIC) {
+ $addonData = array('status' => STATUS_SANDBOX);
+ $this->Addon->save($addonData);
+ $this->publish('success', true);
+ }
+ }
+ elseif ($action == 'public') {
+ if ($addon['Addon']['higheststatus'] == STATUS_PUBLIC && $addon['Addon']['status'] == STATUS_SANDBOX) {
+ $addonData = array('status' => STATUS_PUBLIC);
+ $this->Addon->save($addonData);
+ $this->publish('success', true);
+ }
+ }
+ elseif ($action == 'nominate') {
+ if ($addon['Addon']['status'] == STATUS_SANDBOX) {
+ $criteria = $this->_checkCriteria($this->viewVars['addon_id']);
+
+ if ((in_array($addon['Addon']['addontype_id'], array(ADDON_EXTENSION, ADDON_THEME)) && !$criteria['previews']) || !$criteria['prerelease']) {
+ return true;
+ }
+
+ if (empty($this->data['Addon']['nominationmessage'])) {
+ $this->publish('errors', true);
+ $this->render('addon_status_nominate');
+ return false;
+ }
+ $addonData = array('status' => STATUS_NOMINATED, 'nominationmessage' => $this->params['form']['data']['Addon']['nominationmessage'], 'nominationdate' => date('Y-m-d H:i:s'));
+ $this->Addon->save($addonData);
+ $this->publish('success', true);
+
+ // notify subscribed editors of update
+ global $valid_status;
+ $version_id = $this->Version->getVersionByAddonId($addon['Addon']['id'], $valid_status);
+ $this->Editors->updateNotify($addon['Addon']['id'], $version_id);
+ }
+ }
+
+ return true;
+ }
+
+ if ($action == 'nominate') {
+ $this->render('addon_status_nominate');
+ }
+ else {
+ $this->render('addon_status_confirm');
+ }
+
+ return false;
+ }
+
+ /**
+ * Handler for version-centric actions
+ * @param string $action the action (in some cases this may be an add-on id)
+ * @param int $version_id the version id
+ */
+ function versions($action, $version_id = 0) {
+ $this->publish('action', 'versions');
+ $this->publish('subaction', $action);
+
+ // Get version information and add-on id
+ if (!empty($version_id) && $action != 'add') {
+ $version = $this->Version->findById($version_id, array('Version.id', 'Version.addon_id', 'Version.version'), null, -1);
+ $addon_id = $version['Version']['addon_id'];
+ }
+ elseif ($action == 'add') {
+ $addon_id = $version_id;
+ }
+ else {
+ $addon_id = $action;
+ }
+
+ if (!empty($addon_id)) {
+ // Make sure user has some permissions to view this add-on
+ $role = $this->Amo->getAuthorRole($addon_id);
+ if (empty($role)) {
+ $this->Amo->accessDenied();
+ }
+
+ $this->publish('author_role', $role);
+ $this->publish('addon_name', $this->Addon->getAddonName($addon_id));
+ $this->publish('addon_id', $addon_id);
+ }
+ else {
+ $this->flash(_('error_addon_notfound'), '/developers', 6);
+ return;
+ }
+
+ switch ($action) {
+ case 'add':
+ $this->setAction('_addVersion', $addon_id);
+ break;
+
+ case 'addfile':
+ $this->setAction('_addVersion', $addon_id, $version);
+ break;
+
+ case 'delete':
+ $this->setAction('_deleteVersion', $version);
+ break;
+
+ case 'edit':
+ $this->setAction('_editVersion', $version);
+ break;
+
+ default:
+ $this->setAction('_versionsIndex', $addon_id);
+ break;
+ }
+ }
+
+ /**
+ * Versions listing/index
+ * @param int $addon_id the add-on id
+ */
+ function _versionsIndex($addon_id) {
+ $addon = $this->Addon->findById($addon_id);
+ $this->set('addon', $addon);
+
+ $versions = $this->Version->findAll("Version.addon_id={$addon_id}", null, 'Version.created DESC');
+ $this->set('versions', $versions);
+
+ $this->publish('statuses', $this->Amo->getStatusNames());
+
+ $this->render('versions');
+ }
+
+ /**
+ * Add a Version
+ * @param int $addon_id the add-on id
+ * @param array $version the version info
+ */
+ function _addVersion($addon_id, $version = '') {
+ $type = !empty($version) ? 'file' : 'update';
+ $this->publish('type', $type);
+
+ if (!empty($version)) {
+ $this->publish('version_id', $version['Version']['id']);
+ $this->publish('version', $version['Version']['version']);
+ }
+
+ $addon = $this->Addon->findById($addon_id, array('Addon.dev_agreement'));
+ $this->publish('hasAgreement', $addon['Addon']['dev_agreement']);
+
+ $this->render('uploader');
+ }
+
+ /**
+ * Delete a Version
+ * @param array $version the version info
+ */
+ function _deleteVersion($version) {
+ $version_id = $version['Version']['id'];
+ $addon_id = $version['Version']['addon_id'];
+
+ // Make sure user has permission
+ if ($this->viewVars['author_role'] < AUTHOR_ROLE_DEV) {
+ $this->flash(___('devcp_delete_version_priv_error'), '/developers/versions/edit/'.$version_id, 6);
+ return;
+ }
+
+ // Get all version info
+ $version = $this->Version->findById($version_id);
+
+ if (empty($version['File']) || !empty($_POST['confirmDelete'])) {
+ // If there are no files, we can delete without confirmation
+ $this->Developers->deleteVersion($version_id);
+ $this->Developers->postDelete($addon_id);
+
+ // flush cached add-on objects
+ if (QUERY_CACHE) $this->Addon->Cache->markListForFlush("addon:{$addon_id}");
+
+ $this->publish('deleteSuccess', true);
+ $this->publish('deletedVersion', $version['Version']['version']);
+ $this->_versionsIndex($addon_id);
+ return;
+ }
+ else {
+ // If there are files or if user hasn't confirmed, show confirmation view
+ $this->set('version', $version);
+ $this->render('versions_delete');
+ }
+ }
+
+ /**
+ * Edit a Version
+ * @param array $version the version info
+ */
+ function _editVersion($version) {
+ $version_id = $version['Version']['id'];
+ $addon_id = $version['Version']['addon_id'];
+
+ // Save data if POST data
+ if (!empty($this->data['Version']) && $this->viewVars['author_role'] >= AUTHOR_ROLE_DEV) {
+ // Save translated fields (only releasenotes)
+ list($localizedFields, $unlocalizedFields) = $this->Version->splitLocalizedFields($this->data['Version']);
+ $this->Version->saveTranslations($version_id, $this->params['form']['data']['Version'], $localizedFields);
+
+ // Save Version fields (only approvalnotes)
+ $this->Version->id = $version_id;
+ $this->Version->save(array(
+ 'approvalnotes' => $unlocalizedFields['approvalnotes']
+ ));
+
+ // Save target apps
+ if (!empty($this->data['Application'])) {
+ foreach ($this->data['Application'] as $application_id => $app) {
+ if (!empty($app['delete'])) {
+ // Remove the app
+ $this->Version->removeCompatibleApp($version_id, $application_id);
+ }
+ if (!empty($app['new'])) {
+ // Add a new app
+ $this->Version->addCompatibleApp($version_id, $application_id, $app['min'], $app['max']);
+ }
+
+ if (empty($app['delete']) && empty($app['new'])) {
+ // Normal update
+ $this->Version->updateCompatibility($version_id, $application_id, $app['min'], $app['max']);
+ }
+ }
+ }
+
+ // Save file fields (only platform and deletion)
+ if (!empty($this->data['File'])) {
+ $allowedFileIDs = $this->Version->getFileIDs($version_id);
+
+ foreach ($this->data['File'] as $file_id => $fields) {
+ if (!in_array($file_id, $allowedFileIDs)) {
+ // Make sure the file ID belongs to this version
+ continue;
+ }
+
+ // Delete if requested, otherwise update platform
+ if (!empty($fields['delete'])) {
+ $this->Developers->deleteFile($file_id, $addon_id);
+ $this->Developers->postDelete($addon_id);
+ }
+ else {
+ $this->File->id = $file_id;
+ $this->File->save(array(
+ 'platform_id' => $fields['platform_id']
+ ));
+ }
+ }
+ }
+
+ // Save license.
+ $license_id = $this->Developers->saveLicense(
+ $this->data['License'],
+ getitem($this->data, 'Version.License.text'),
+ getitem($this->params, 'form.data.Version.License'));
+ $this->Version->saveField('license_id', $license_id);
+
+ // flush cached add-on objects
+ if (QUERY_CACHE) $this->Addon->Cache->markListForFlush("addon:{$addon_id}");
+
+ $this->publish('success', true);
+ }
+
+ // Get all version info
+ $version = $this->Version->findById($version_id);
+
+ // Get add-on info
+ $addon = $this->Addon->findById($addon_id);
+ $this->set('addon', $addon);
+
+ $this->set('version', $version);
+
+ // Get target app info
+ $this->publish('targetApps', $this->Version->getCompatibleAppIds($version_id));
+ $possibleVersions = $this->Appversion->getAllVersions();
+ if (!empty($possibleVersions)) {
+ foreach ($possibleVersions as $k => $v) {
+ $this->Versioncompare->sortAppversionArray($possibleVersions[$k]);
+ }
+ }
+ $this->publish('possibleVersions', $possibleVersions);
+
+ // Get all translations
+ $translations = $this->Version->getAllTranslations($version_id);
+ if (isset($version['Version']['license_id'])) {
+ $trans = $this->License->getAllTranslations($version['Version']['license_id']);
+ $translations['license_text'] = $trans['text'];
+ } else {
+ $translations['license_text'] = array();
+ }
+
+ $this->set('translations', $translations);
+
+ // Other info
+ $this->publish('applications', $this->Application->getNames());
+ $this->publish('statuses', $this->Amo->getStatusNames());
+ $this->publish('platforms', $this->Platform->getNames());
+
+ $this->render('versions_edit');
+ }
+
+ /**
+ * Handler for preview-centric actions
+ * @param string $action the action
+ * @param int $preview_id the preview id
+ */
+ function previews($action, $preview_id = 0) {
+ $this->publish('action', 'previews');
+ $this->publish('subaction', $action);
+
+ // Get addon id
+ if (!empty($preview_id)) {
+ $preview = $this->Preview->findById($preview_id);
+ $addon_id = $preview['Preview']['addon_id'];
+ }
+ else {
+ $addon_id = $action;
+ }
+
+ // Make sure user has some permissions to view this add-on
+ $role = $this->Amo->getAuthorRole($addon_id);
+ if (empty($role)) {
+ $this->Amo->accessDenied();
+ }
+
+ $this->publish('author_role', $role);
+ $this->publish('addon_name', $this->Addon->getAddonName($addon_id));
+ $this->publish('addon_id', $addon_id);
+
+ switch ($action) {
+ case 'add':
+ $this->setAction('_addPreview', $addon_id);
+ break;
+
+ case 'delete':
+ $this->setAction('_deletePreview', $preview);
+ break;
+
+ case 'edit':
+ $this->setAction('_editPreview', $preview);
+ break;
+
+ default:
+ $this->setAction('_previewsIndex', $addon_id);
+ break;
+ }
+ }
+
+ function _previewsIndex($addon_id) {
+ // If post data is present, dispatch accordingly
+ if (!empty($this->data['Preview']) && $this->viewVars['author_role'] >= AUTHOR_ROLE_DEV) {
+ $messages = array('success', 'errors');
+
+ // Check if we're adding any previews
+ if (!empty($this->data['Preview']['New'])) {
+ $addReturn = $this->_addPreviews($addon_id);
+ $messages = array_merge_recursive($messages, $addReturn);
+ }
+
+ // Check if we're replacing any previews
+ if (!empty($this->data['Preview']['Replace'])) {
+ $replaceReturn = $this->_addPreviews($addon_id);
+ $messages = array_merge_recursive($messages, $replaceReturn);
+ }
+
+ // Save translated fields (only caption)
+ foreach ($this->data['Preview'] as $preview_id => $fields) {
+ if (!is_numeric($preview_id)) continue;
+
+ list($localizedFields, $unlocalizedFields) = $this->Preview->splitLocalizedFields($fields);
+ $this->Preview->saveTranslations($preview_id, $this->params['form']['data']['Preview'][$preview_id], $localizedFields);
+ }
+
+ // Check if we're deleting any previews
+ if (!empty($this->data['Preview']['Delete'])) {
+ $deleteReturn = $this->_deletePreviews($addon_id);
+ $messages = array_merge_recursive($messages, $deleteReturn);
+ }
+
+ // Update the highlighted preview
+ $this->Preview->saveHighlight($addon_id, $this->data['Preview']['highlight']);
+
+ // flush cached add-on objects
+ if (QUERY_CACHE) $this->Addon->Cache->markListForFlush("addon:{$addon_id}");
+
+ // inform about cache lag, if any of the changes were successful
+ if (!empty($messages['success'])) $messages['success'][] = ___('devcp_several_hours');
+
+ $this->publish('messages', $messages);
+ }
+
+ // Get add-on previews
+ $previews = $this->Preview->findAllByAddon_id($addon_id);
+ $this->set('previews', $previews);
+
+ $translations = array();
+
+ if (!empty($previews)) {
+ foreach ($previews as $preview) {
+ $translations[$preview['Preview']['id']] = $this->Preview->getAllTranslations($preview['Preview']['id']);
+ }
+ }
+ $this->set('translations', $translations);
+
+ $addon = $this->Addon->findById($addon_id);
+ $this->set('addon', $addon);
+
+ $this->render('previews');
+ }
+
+ function _addPreviews($addon_id) {
+ $return = array();
+
+ // Get IDs of existing previews
+ $existing = $this->Preview->getIDsForAddon($addon_id);
+
+ // Loop through each new preview
+ foreach ($this->data['Preview']['New']['name'] as $id => $name) {
+ if (empty($name)) continue;
+
+ $tmp_name = $this->data['Preview']['New']['tmp_name'][$id];
+
+ $previewData = array('addon_id' => $addon_id,
+ 'filedata' => file_get_contents($tmp_name),
+ 'filetype' => $this->data['Preview']['New']['type'][$id],
+ 'highlight' => 0,
+ 'thumbtype' => 'image/png'
+ );
+
+ // Check for allowed file extensions
+ $extension = strtolower(substr($name, strrpos($name, '.')));
+ if (!in_array($extension, $this->Developers->imageExtensions)) {
+ $return['errors'][] = sprintf(___('devcp_add_previews_extension_error'), $name, $extension, implode(', ', $this->Developers->imageExtensions));
+ continue;
+ }
+
+ // Get image dimensions
+ list($sourceWidth, $sourceHeight) = getimagesize($tmp_name);
+
+ // Generate thumbnail (200 x 150)
+ $previewData['thumbdata'] = $this->Developers->resizeImage($previewData['filedata'], $sourceWidth, $sourceHeight, 200, 150);
+
+ // Resize preview if too large (700 x 525)
+ if ($sourceWidth > 700 || $sourceHeight > 525) {
+ $previewData['filedata'] = $this->Developers->resizeImage($previewData['filedata'], $sourceWidth, $sourceHeight, 700, 525);
+ $previewData['filetype'] = 'image/png';
+ }
+
+ if (in_array($id, $existing)) {
+ // Replacing existing preview
+ $this->Preview->id = $id;
+ }
+ else {
+ // Adding new preview
+ $this->Preview->id = 0;
+ }
+
+ // Save preview to db
+ if ($this->Preview->save($previewData)) {
+ if (in_array($id, $existing))
+ $return['success'][] = sprintf(___('devcp_add_previews_success_replace'), $id, $name);
+ else
+ $return['success'][] = sprintf(___('devcp_add_previews_success_upload'), $name);
+ }
+ else
+ $return['errors'][] = sprintf(___('devcp_add_previews_save_error'), $name);
+ }
+
+ return $return;
+ }
+
+ function _deletePreviews($addon_id) {
+ $return = array();
+
+ // Get IDs of existing previews
+ $existing = $this->Preview->getIDsForAddon($addon_id);
+
+ // Loop through each preview
+ foreach ($this->data['Preview']['Delete'] as $id => $delete) {
+ if ($delete !== 'true') continue;
+
+ // Delete the preview
+ $this->Preview->id = $id;
+ if ($this->Preview->delete())
+ $return['success'][] = sprintf(___('devcp_delete_previews_success'), $id);
+ else
+ $return['errors'][] = sprintf(___('devcp_delete_previews_error'), $id);
+ }
+
+ return $return;
+ }
+
+ /**
+ * Discuss a review request with an editor
+ */
+ function discuss($infoid) {
+ global $valid_status;
+
+ $inforequest = $this->Approval->findById($infoid);
+ if (empty($inforequest)) {
+ $this->flash(_('error_addon_notfound'), '/developers/index');
+ return;
+ }
+ // Make sure user has some permissions to view this add-on
+ $session = $this->Session->read('User');
+ $isEditor = $this->SimpleAcl->actionAllowed('Editors', '*', $session);
+ $role = $this->Amo->getAuthorRole($inforequest['Approval']['addon_id']);
+ if (!$isEditor && empty($role)) $this->Amo->accessDenied();
+
+ $this->publish('inforequest', $inforequest);
+
+ $addon = $this->Addon->getAddon($inforequest['Approval']['addon_id'], array('authors'));
+ $this->publish('addonName', $addon['Translation']['name']['string']);
+
+ $versionid = $this->Version->getVersionByAddonId($addon['Addon']['id'], $valid_status);
+ $version = $this->Version->findById($versionid, null, null, -1);
+ $this->publish('versionno', $version['Version']['version']);
+
+ // grab replies
+ $replies = $this->Approval->findAll(array('reply_to' => $infoid), null, 'Approval.created');
+ $this->publish('replies', $replies);
+
+ if (!empty($this->data)) {
+ $session = $this->Session->read('User');
+
+ //Auto-detect addontype if necessary
+ if ($this->data['Addon']['addontype_id'] == 0) {
+ $this->data['Addon']['addontype_id'] = $this->Developers->detectAddontype($this->data['File']['file1']);
+ $this->publish('autoDetected', $this->Addontype->getName($this->data['Addon']['addontype_id']));
+ }
+
+ //Make sure addontype is allowed
+ $allowedAddonTypes = $this->Developers->getAllowedAddonTypes(false, $this->SimpleAcl->actionAllowed('*', '*', $this->Session->read('User')));
+ if (!array_key_exists($this->data['Addon']['addontype_id'], $allowedAddonTypes)) {
+ $this->Error->addError(_('devcp_error_invalid_addontype'));
+ }
+
+ //Validate files
+ $this->Developers->validateFiles();
+
+ // reply submitted
+ $approvalData = array(
+ 'user_id' => $session['id'],
+ 'reviewtype' => 'info',
+ 'action' => 0,
+ 'reply_to' => $infoid,
+ 'addon_id' => $addon['Addon']['id'],
+ 'comments' => $this->data['Approval']['comments']
+ );
+ if (true === $this->Approval->save($approvalData)) {
+ $this->set('success', true);
+
+ // add this to the replies set
+ $replies[] = $this->Approval->findById($this->Approval->getLastInsertID());
+ $this->publish('replies', $replies);
+
+ // send email to all authors and the editor, but not the current user
+ $recipients = array();
+ foreach ($addon['User'] as &$user) $recipients[] = $user['email'];
+ $recipients[] = $inforequest['User']['email'];
+ foreach ($replies as &$reply) $recipients[] = $reply['User']['email'];
+ $recipients = array_diff(array_unique($recipients), array($session['email'])); // remove current user
+
+ $emailInfo = array(
+ 'name' => $addon['Translation']['name']['string'],
+ 'infoid' => $infoid,
+ 'sender' => $session['firstname'].' '.$session['lastname'],
+ 'comments' => $this->data['Approval']['comments'],
+ 'version' => !empty($version) ? $version['Version']['version'] : ''
+ );
+ $this->publish('info', $emailInfo, false);
+ $this->Email->template = '../editors/email/inforequest_reply';
+ $this->Email->subject = sprintf('Mozilla Add-ons: %s %s', $emailInfo['name'], $emailInfo['version']);
+ foreach ($recipients as &$recipient) {
+ $this->Email->to = $recipient;
+ $this->Email->send();
+ }
+ }
+ }
+ $this->render();
+ }
+}
+?>
diff --git a/site/app/controllers/downloads_controller.php b/site/app/controllers/downloads_controller.php
new file mode 100644
index 0000000..0057a4d
--- /dev/null
+++ b/site/app/controllers/downloads_controller.php
@@ -0,0 +1,169 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Andrei Hajdukewycz <sancus@off.net> (Original Author)
+ * Justin Scott <fligtar@gmail.com>
+ * Frederic Wenzel <fwenzel@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+class DownloadsController extends AppController
+{
+ var $name = 'Downloads';
+ var $beforeFilter = array('getNamedArgs', '_checkSandbox');
+ var $uses = array('Addon', 'Download', 'File', 'Translation');
+ var $components = array('Amo', 'Session');
+ var $namedArgs = true;
+
+ var $securityLevel = 'low';
+
+ function beforeFilter() {
+ // Disable ACLs because this controller is entirely public.
+ $this->SimpleAuth->enabled = false;
+ $this->SimpleAcl->enabled = false;
+ }
+
+ function file($id = null, $type = 'xpi') {
+
+ if (empty($this->namedArgs['update']))
+ $this->namedArgs['update'] = null;
+
+ $this->Amo->clean($id);
+ $this->layout=null;
+ if (!$id || !is_numeric($id)) {
+ $this->flash(sprintf(_('error_missing_argument'), 'file_id'), '/', 3);
+ return;
+ }
+
+ $file_data = $this->File->FindbyId($id);
+
+ if (!empty($file_data)) {
+
+ $this->Addon->unbindFully();
+ $addon_data = $this->Addon->FindbyId($file_data['Version']['addon_id']);
+
+ $file_loc = REPO_PATH . '/' . $file_data['Version']['addon_id'] . '/' . $file_data['File']['filename'];
+
+ // If add-on is in sandbox, make sure sandbox is enabled. If disabled, make sure admin or author.
+ // If _GET['confirmed'] exists, then a user confirmed a sandbox download via JS, bug 441739
+ if (($addon_data['Addon']['status'] == STATUS_SANDBOX ||
+ $addon_data['Addon']['status'] == STATUS_NOMINATED ||
+ $file_data['File']['status'] == STATUS_PENDING)
+ && !$this->Session->check('User') && !isset($_GET['confirmed'])) {
+
+ $target_url = str_replace(LANG . '/' . APP_SHORTNAME . '/','',$this->params['url']['url']);
+ $this->redirect('/users/login?to=' . urlencode($target_url) . "&m=1");
+ return;
+ } elseif ($addon_data['Addon']['status'] == STATUS_DISABLED &&
+ !$this->Amo->checkOwnership($addon_data['Addon']['id'])) {
+
+ $this->flash(_('downloads_disable_warning'), '/', 3);
+ return;
+ }
+ } else {
+ $this->flash(_('error_addon_notfound'), '/', 3);
+ return;
+ }
+
+ if (file_exists($file_loc))
+ $this->set('fileLoc', $file_loc);
+ else {
+ $this->flash(_('error_addon_notfound'), '/', 3);
+ return;
+ }
+
+ // force local delivery for non-browser apps
+ global $browser_apps;
+ if (!in_array(APP_ID, $browser_apps) || $type == 'attachment') {
+ $forceLocal = true;
+ $this->set('attachment', true);
+ } else {
+ $forceLocal = false;
+ $this->set('attachment', false);
+ }
+
+ $this->set('fileName', $file_data['File']['filename']);
+
+ if (!DEV && !$forceLocal && $addon_data['Addon']['status'] == STATUS_PUBLIC
+ && $file_data['File']['status'] == STATUS_PUBLIC
+ && (strtotime($file_data['File']['datestatuschanged']) <= strtotime('-'.MIRROR_DELAY.' minutes'))) {
+ // serve file from releases mirror only if we are not in dev mode
+ // and if the file is public and sufficient time has passed to allow
+ // its propagation to the mirror system
+ $this->forceCache();
+ $this->redirect(FILES_HOST . '/' . $addon_data['Addon']['id'] . '/' . $file_data['File']['filename']);
+ return;
+ } else {
+ // serve file locally
+ $this->disableCache();
+ $this->render('file');
+ }
+ }
+
+ /**
+ * Retrieves public file for latest version of an add-on, regardless of compatibility
+ * Example URL: /downloads/latest/1865/type:attachment/platform:5/
+ * @param int $addon_id the add-on id
+ */
+ function latest($addon_id) {
+ $platform_id = (!empty($this->namedArgs['platform']) && is_numeric($this->namedArgs['platform'])) ? $this->namedArgs['platform'] : null;
+
+ $type = !empty($this->namedArgs['type']) ? $this->namedArgs['type'] : 'xpi';
+
+ // Get the id of the latest public file
+ $file_id = $this->File->getLatestFileByAddonId($addon_id, $platform_id);
+ $file_data = $this->File->findById($file_id);
+
+ if (!empty($file_id)) {
+ // Use normal download method if file is found
+ $target = "/downloads/file/{$file_id}/{$type}/{$file_data['File']['filename']}";
+ if (count($this->params['url']) > 1) { // re-append query string
+ $getvars = array();
+ foreach ($this->params['url'] as $k => $v) {
+ if ($k == 'url') continue;
+ $getvars[] = "$k=$v";
+ }
+ $qs = implode(',', $getvars);
+ $target .= "?$qs";
+ }
+ $this->redirect($target);
+ }
+ else {
+ // File wasn't found
+ $this->flash(_('error_addon_notfound'), '/', 3);
+ }
+ }
+}
+
+?>
diff --git a/site/app/controllers/editors_controller.php b/site/app/controllers/editors_controller.php
new file mode 100644
index 0000000..3a97e51
--- /dev/null
+++ b/site/app/controllers/editors_controller.php
@@ -0,0 +1,1534 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/e
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * Justin Scott <fligtar@gmail.com>.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Wil Clouser <clouserw@gmail.com>
+ * Frederic Wenzel <fwenzel@mozilla.com>
+ * Les Orchard <lorchard@mozilla.com>
+ * Cesar Oliveira <a.sacred.line@gmail.com>
+ * Scott McCammon <smccammon@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+class EditorsController extends AppController
+{
+ var $name = 'Editors';
+ var $uses = array('Addon', 'AddonTag', 'Addontype', 'Application', 'Approval',
+ 'Appversion', 'Cannedresponse', 'EditorSubscription', 'Eventlog', 'Favorite',
+ 'File', 'Platform', 'Review', 'ReviewsModerationFlag', 'Tag', 'Translation',
+ 'User', 'Version');
+ var $components = array('Amo', 'Audit', 'Developers', 'Editors', 'Email', 'Error', 'Image', 'Pagination');
+ var $helpers = array('Html', 'Javascript', 'Ajax', 'Listing', 'Localization', 'Pagination');
+
+ /**
+ * Require login for all actions
+ */
+ function beforeFilter() {
+ //beforeFilter() is apparently called before components are initialized. Cake++
+ $this->Amo->startup($this);
+ $this->Editors->startup($this);
+
+ $this->Amo->checkLoggedIn();
+
+ $this->layout = 'mozilla';
+ $this->pageTitle = _('editors_pagetitle').' :: '.sprintf(_('addons_home_pagetitle'), APP_PRETTYNAME);
+
+ $this->cssAdd = array('editors', 'admin');
+ $this->publish('cssAdd', $this->cssAdd);
+
+ $this->publish('jsAdd', array('jquery-compressed.js',
+ 'jquery.autocomplete.pack.js',
+ 'jquery.tablesorter.min.js',
+ 'jquery.flot.js',
+ 'jquery.sparkline.min.js',
+ 'editors'));
+
+ $this->breadcrumbs = array(_('editors_pagetitle') => '/editors/index');
+ $this->publish('breadcrumbs', $this->breadcrumbs);
+ $this->publish('suppressJQuery', 1);
+
+ $this->publish('subpagetitle', _('editors_pagetitle'));
+
+ // disable query caching so devcp changes are visible immediately
+ foreach ($this->uses as $_model) {
+ $this->$_model->caching = false;
+ }
+
+ //Get counts
+ $count['pending'] = $this->_getCount('pending');
+ $count['nominated'] = $this->_getCount('nominated');
+ $count['reviews'] = $this->_getCount('reviews');
+ $this->publish('count', $count);
+ }
+
+ /**
+ * Index
+ */
+ function index() {
+ $this->summary();
+ }
+
+ /**
+ * Summary
+ */
+ function summary() {
+ $this->cssAdd[] = 'summary';
+ $this->publish('cssAdd', $this->cssAdd);
+
+ //Total reviews
+ $totalReviews = $this->Approval->query("SELECT users.firstname, users.lastname, COUNT(*) as total FROM approvals LEFT JOIN users ON users.id=approvals.user_id GROUP BY approvals.user_id ORDER BY total DESC LIMIT 5");
+ $this->set('totalReviews', $totalReviews);
+
+ //Reviews this month
+ $monthStart = date('Y-m-01');
+ $monthReviews = $this->Approval->query("SELECT users.firstname, users.lastname, COUNT(*) as total FROM approvals LEFT JOIN users ON users.id=approvals.user_id WHERE approvals.created >= '{$monthStart} 00:00:00' GROUP BY approvals.user_id ORDER BY total DESC LIMIT 5");
+ $this->set('monthReviews', $monthReviews);
+
+ //New editors
+ $newEditors = $this->Eventlog->query("SELECT users.firstname, users.lastname, eventlog.created FROM eventlog LEFT JOIN users ON eventlog.added=users.id WHERE eventlog.type='admin' AND eventlog.action='group_addmember' AND eventlog.changed_id='2' ORDER BY eventlog.created DESC LIMIT 5");
+ $this->set('newEditors', $newEditors);
+
+ //Recent activity
+ $logs = $this->Eventlog->findAll(array('type' => 'editor'), null, 'Eventlog.created DESC', 5);
+ $logs = $this->Audit->explainLog($logs);
+ $this->set('logs', $logs);
+
+ $this->set('page', 'summary');
+ $this->render('summary');
+ }
+
+ /**
+ * Review queue
+ */
+ function queue($mode = 'pending') {
+ //If queues are disabled, show appropriate error
+ if ($this->Config->getValue('queues_disabled') == 1 && !$this->SimpleAcl->actionAllowed('*', '*', $this->Session->read('User'))) {
+ $this->flash(_('editors_queues_disabled'), '/', 3);
+ return;
+ }
+
+ // if num=... argument is set, jump to specific item in queue
+ if (isset($this->params['url']['num']) && is_numeric($this->params['url']['num']))
+ $this->Editors->redirectByQueueRank($mode, $this->params['url']['num']);
+
+ $this->publish('collapse_categories', true);
+
+ $this->Amo->clean($mode);
+ $this->breadcrumbs[_('editors_review_queue_pagetitle')] = '/editors/queue';
+ $this->publish('breadcrumbs', $this->breadcrumbs);
+ $this->publish('subpagetitle', _('editors_review_queue_pagetitle'));
+
+ $this->publish('mode', $mode);
+
+ // Setup queue filter
+ if (array_key_exists('filter', $this->params['form'])) {
+ // set a new filter on this queue
+ $filter = $this->Editors->setQueueFilter($mode, $this->data['Filter']);
+
+ } elseif (array_key_exists('clear', $this->params['form'])) {
+ // clear existing filter on this queue
+ $filter = $this->Editors->setQueueFilter($mode, null);
+
+ // clear sorting
+ $this->Editors->setQueueSort($mode, 'default');
+
+ } else {
+ // fetch existing filter
+ $filter = $this->Editors->getQueueFilter($mode);
+ }
+
+ // Handle changes to sorting
+ if (isset($this->params['url']['sort'])) {
+ if (isset($this->params['url']['dir'])) {
+ $this->Editors->setQueueSort($mode, $this->params['url']['sort'], $this->params['url']['dir']);
+ } else {
+ $this->Editors->setQueueSort($mode, $this->params['url']['sort']);
+ }
+ }
+
+ // Build the queue
+ if ($mode == 'pending' || $mode == 'nominated') {
+ $addons = $this->_buildQueue($mode);
+ }
+ elseif ($mode == 'reviews') {
+ $this->_reviews($this->_getCount('reviews'));
+ return;
+ }
+ else {
+ $this->redirect('/editors');
+ return;
+ }
+
+ //Setup filter form fields
+ $selected = array('Application'=>'', 'MaxVersion'=>'',
+ 'SubmissionAge'=>'', 'Addontype'=>'', 'Platform'=>'',);
+ if (is_array($filter)) {
+ foreach ($filter as $k => $val) {
+ if (array_key_exists($k, $selected)) {
+ $selected[$k] = $val;
+ }
+ }
+ }
+
+ $addonOrAuthor = isset($filter['AddonOrAuthor']) ? $filter['AddonOrAuthor'] : '';
+
+ $maxVersions = array();
+ if (!empty($filter['Application'])) {
+ $app_versions = $this->Appversion->findAllByApplicationId($filter['Application'],
+ array('Appversion.id', 'Appversion.version'), 'Appversion.version DESC');
+ foreach ($app_versions as $av) {
+ $maxVersions[$av['Appversion']['id']] = $av['Appversion']['version'];
+ }
+ }
+
+ $submissionAges = array('1' => '1', '2' => '2', '3' => '3', '4' => '4', '5' => '5',
+ '6' => '6', '7' => '7', '8' => '8', '9' => '9', '10+' => '10+');
+ $platforms = $this->Amo->getPlatformName();
+ $applications = $this->Amo->getApplicationName();
+
+ $filtered = !empty($filter);
+ $filterChanged = $filtered && array_key_exists('filter', $this->params['form']);
+ $filteredCount = $this->_getCount($mode, true);
+
+ $sortOpts = $this->Editors->getQueueSort($mode);
+
+ // raw values for selectTags
+ $this->set('selected', $selected);
+ $this->set('platforms', $platforms);
+ $this->set('addontypes', $this->Addontype->getNames());
+ $this->set('applications', $applications);
+ $this->set('maxVersions', $maxVersions);
+ $this->set('submissionAges', $submissionAges);
+
+ $this->publish('addonOrAuthor', $addonOrAuthor);
+ $this->publish('filtered', $filtered);
+ $this->publish('filterChanged', $filterChanged);
+ $this->publish('filteredCount', $filteredCount);
+ $this->publish('sortBy', $sortOpts['sortby']);
+ $this->publish('sortDir', $sortOpts['direction']);
+
+ $this->publish('mode', $mode);
+ $this->publish('addons', $addons);
+ $this->render('queue');
+ }
+
+ /**
+ * Review a specific version
+ * @param int $id The version id
+ */
+ function review($id) {
+ $this->Amo->clean($id);
+ $this->publish('subpagetitle', _('editors_addon_review_pagetitle'));
+ $this->breadcrumbs[_('editors_addon_review_pagetitle')] = '/editors/review/'.$id;
+ $this->publish('breadcrumbs', $this->breadcrumbs);
+ $this->publish('collapse_categories', true);
+
+ //Bind necessary models
+ $this->User->bindFully();
+ $this->Addontype->bindFully();
+ $this->Version->bindFully();
+ $this->Addon->bindFully();
+
+ if (!$version = $this->Version->findById($id, null, null, 1)) {
+ $this->flash(_('error_version_notfound'), '/editors/queue');
+ return;
+ }
+
+ if (!$addon = $this->Addon->findById($version['Version']['addon_id'])) {
+ $this->flash(_('error_addon_notfound'), '/editors/queue');
+ return;
+ }
+
+ //Make sure user is not an author (or is an admin)
+ $session = $this->Session->read('User');
+ if (!$this->SimpleAcl->actionAllowed('*', '*', $session)) {
+ foreach ($addon['User'] as $author) {
+ if ($author['id'] == $session['id']) {
+ $this->flash(_('editors_error_self_reviews_forbidden'), '/editors/queue');
+ return;
+ }
+ }
+ }
+
+ if (!empty($this->data)) {
+ //pr($this->data);
+ if ($this->data['Approval']['ActionField'] == 'info') {
+ // request more information
+ $this->Editors->requestInformation($addon, $this->data);
+ }
+ elseif ($this->data['Approval']['Type'] == 'nominated') {
+ $this->Editors->reviewNominatedAddon($addon, $this->data);
+ }
+ else {
+ $this->Editors->reviewPendingFiles($addon, $this->data);
+ }
+
+ if ($this->Error->noErrors()) {
+ // if editor chose to be reminded of the next upcoming update, save this
+ if ($this->data['Approval']['subscribe'])
+ $this->EditorSubscription->subscribeToUpdates($session['id'], $addon['Addon']['id']);
+
+ $this->flash(_('editors_reviewed_successfully'), '/editors/queue/'.$this->data['Approval']['Type']);
+ return;
+ }
+ }
+
+ $this->pageTitle = $addon['Translation']['name']['string'] . ' :: ' . $this->pageTitle;
+
+ if (!empty($addon['Tag'])) {
+ foreach ($addon['Tag'] as $tag) {
+ $tags[] = $tag['id'];
+ }
+ $addon['Tags'] = $this->Tag->findAll("Tag.id IN (".implode(', ', $tags).")");
+ }
+ else
+ $addon['Tags'] = array();
+
+ $platforms = $this->Amo->getPlatformName();
+
+ //get min/max versions
+ if ($targetApps = $this->Amo->getMinMaxVersions($id)) {
+ foreach ($targetApps as $targetApp) {
+ $appName = $targetApp['translations']['localized_string'];
+ $addon['targetApps'][$appName]['min'] = $targetApp['min']['version'];
+ $addon['targetApps'][$appName]['max'] = $targetApp['max']['version'];
+ }
+ }
+
+ if (!empty($version['File'])) {
+ $version['pendingCount'] = 0;
+ foreach ($version['File'] as $k => $file) {
+ if ($file['status'] == STATUS_PENDING) {
+ $version['File'][$k]['disabled'] = 'false';
+ $version['pendingCount']++;
+ }
+ else {
+ $version['File'][$k]['disabled'] = 'true';
+ }
+ }
+ }
+
+ if ($responses = $this->Cannedresponse->findAll()) {
+ foreach ($responses as $response) {
+ $cannedresponses[$response['Translation']['response']['string']] = $response['Translation']['name']['string'];
+ }
+ $this->publish('cannedresponses', $cannedresponses);
+ }
+
+ $this->publish('jsLocalization', array( 'action' => _('editors_review_action'),
+ 'comments' => _('editors_review_comments'),
+ 'os' => _('editors_tested_os'),
+ 'applications' => _('editors_tested_app'),
+ 'errors' => _('editors_error_js-formerror'),
+ 'files' => _('editors_error_review_one_file')
+ ));
+
+ //Review History
+ if ($history = $this->Approval->findAll(array('Approval.addon_id' => $addon['Addon']['id'], 'reply_to IS NULL'))) {
+ foreach ($history as $k => &$hist) {
+ if (!empty($hist['File']['id'])) {
+ $vLookup = $this->Version->findById($hist['File']['version_id'], array('Version.version'));
+ $history[$k] = array_merge_recursive($history[$k], $vLookup);
+ }
+
+ // add replies to information requests
+ if ($hist['Approval']['reviewtype'] == 'info') {
+ $hist['replies'] = $this->Approval->findAll(array('Approval.reply_to' => $hist['Approval']['id']), null, 'Approval.created');
+ }
+ }
+ }
+
+ //pr($history);
+
+ if ($addon['Addon']['status'] == STATUS_NOMINATED) {
+ $reviewType = 'nominated';
+ } else {
+ $reviewType = 'pending';
+ }
+
+ // count of filtered queue
+ $filtered = (true && $this->Editors->getQueueFilter($reviewType));
+ $filteredCount = $this->_getCount($reviewType, true);
+
+ // rank in nomination/update queue
+ if (isset($this->params['url']['num']) && is_numeric($this->params['url']['num']))
+ $queueRank = $this->params['url']['num'];
+ else
+ $queueRank = false;
+ $this->publish('queueRank', $queueRank);
+
+ $this->publish('has_public', $this->File->getLatestFileByAddonId($addon['Addon']['id']) != 0);
+ $this->publish('addon', $addon);
+ $this->publish('version', $version);
+ $this->publish('platforms', $platforms);
+ $this->publish('addontypes', $this->Addontype->getNames());
+ $this->publish('addontype', $addon['Addon']['addontype_id']);
+ $this->publish('approval', $this->Amo->getApprovalStatus());
+ $this->publish('history', $history);
+ $this->publish('errors', $this->Error->errors);
+ $this->publish('reviewType', $reviewType, false);
+ $this->publish('filtered', $filtered);
+ $this->publish('filteredCount', $filteredCount);
+
+ $this->render('review');
+ }
+
+ /**
+ * Reads the approval file
+ * @param int $id The file id
+ */
+ function file($id) {
+ $this->Amo->clean($id);
+ $this->File->id = $id;
+
+ if (!$file = $this->File->read()) {
+ $this->flash(_('error_file_notfound'), '/editors/queue');
+ }
+
+ $this->Addon->id = $file['Version']['addon_id'];
+ $this->Version->id = $file['Version']['id'];
+
+ $filename = $file['File']['filename'];
+ $file = REPO_PATH.'/'.$this->Addon->id.'/'.$filename;
+
+ if (file_exists($file)) {
+ header('Content-Description: File Transfer');
+ header('Content-Type: application/octet-stream');
+ header('Content-Length: ' . filesize($file));
+ header('Content-Disposition: attachment; filename=' . $filename);
+
+ readfile($file);
+ }
+ else {
+ $this->flash(sprintf(_('error_file_x_notfound'), $file), '/editors/review/'.$this->Version->id);
+ }
+ exit;
+ }
+
+
+ /**
+ * Performance reports jump off point
+ * Handles report selection, and user parameter
+ */
+ function performance($mode = '') {
+ $session = $this->Session->read('User');
+ if (!$this->SimpleAcl->actionAllowed('Editor', '*', $session)) {
+ $this->Amo->accessDenied();
+ }
+
+ //Senior Editors can generate reports on anyone
+ $isSenior = $this->SimpleAcl->actionAllowed('Admin', 'EditAnyAddon', $session);
+ if ($isSenior && !empty($this->params['url']['user'])) {
+ $user = $this->User->findByEmail($this->params['url']['user']);
+ if (empty($user)) {
+ header('HTTP/1.1 404 Not Found');
+ $this->flash(___('editors_performance_user_not_found', 'User not found'), "/editors/performance/{$mode}");
+ return;
+ }
+ } else {
+ $user = $this->User->findById($session['id']);
+ }
+
+ //Chart AJAX
+ // @TODO: enable this and make charts use ajax to load new data
+ if (false && $mode == 'chartData') {
+ $summary = !empty($this->params['url']['sum']) ? $this->params['url']['sum'] : '';
+
+ if ($summary == 'month') {
+ $data = $this->_performanceSummaryByMonth($user['User']['id'], 12);
+ }
+ elseif ($summary == 'cat') {
+ $year = null;
+ $month = null;
+ if (!empty($this->params['url']['year'])) {
+ $year = intval($this->params['url']['year']);
+ }
+ if (!empty($this->params['url']['month'])) {
+ $month = intval($this->params['url']['month']);
+ }
+ $data = $this->_performanceSummaryByCategory($user['User']['id'], $year, $month);
+ }
+
+ $this->set('json', $data);
+ $this->render('ajax/json', 'ajax');
+ return;
+ }
+
+ // display name (or email if not set)
+ $userName = trim("{$user['User']['firstname']} {$user['User']['lastname']}");
+ if ($userName == '') {
+ $userName = $user['User']['email'];
+ }
+
+ $this->publish('mode', $mode);
+ $this->publish('user', $user);
+ $this->publish('userName', $userName);
+ $this->publish('showUserLookup', $isSenior);
+ $this->publish('editors', $isSenior ? $this->_recentEditors() : array());
+ $this->publish('collapse_categories', false);
+ $this->publish('subpagetitle', ___('editors_performance_pagetitle', 'Performance Reports'));
+ $this->set('page', 'performance');
+
+ //Standard text report
+ if ($mode == '') {
+ $this->_performanceTable($user['User']['id']);
+
+ //Charts
+ } elseif ($mode == 'charts') {
+ $this->_performanceCharts($user['User']['id']);
+
+ } else {
+ $this->redirect('/editors/performance');
+ }
+ return;
+ }
+
+
+ /**
+ * Generate a detailed performance report with weekly totals and team averages
+ * @param int $userId user to generate report for
+ */
+ function _performanceTable($userId) {
+ // Initialize report data
+ $myApprovals = array();
+ $myTotal = 0;
+ $teamTotal = 0;
+ $teamSize = 0;
+ $teamAverage = 0;
+ $weeklyTotals = array();
+ $myMtdTotal = 0;
+ $teamMtdTotal = 0;
+ $teamMtdAverage = 0;
+ $myYtdTotal = 0;
+ $teamYtdTotal = 0;
+ $teamYtdSize = 0;
+ $teamYtdAverage = 0;
+
+ //Default conditions are the current month
+ $ytdEndTime = strtotime('tomorrow');
+ $startDate = date('Y-m-01');
+ $startTime = strtotime($startDate);
+ $endDate = ___('editors_date_filter_placeholder', 'YYYY-MM-DD');
+ $endTime = $ytdEndTime;
+
+ //If user has specified own conditions, use those
+ if (!empty($this->params['url']['start'])) {
+ $ts = strtotime($this->params['url']['start']);
+ if ($ts !== false && $ts != -1) {
+ $startTime = $ts;
+ $startDate = $this->params['url']['start'];
+ }
+ }
+ if (!empty($this->params['url']['end'])) {
+ $ts = strtotime($this->params['url']['end']);
+ if ($ts !== false && $ts != -1) {
+ $endTime = strtotime('+1 day', $ts);
+ $endDate = $this->params['url']['end'];
+ }
+ }
+
+ //Initialize weekly data
+ $week = array('from' => $startTime,
+ 'to' => min(strtotime('next Monday', $startTime), $endTime)-1,
+ 'myTotal' => 0, 'teamTotal' => 0, 'teamAverage' => 0);
+ while ($week['from'] < $endTime) {
+ $weeklyKey = $this->_makeYearWeekKey($week['from']);
+ $weeklyTotals[$weeklyKey] = $week;
+
+ $week = array('from' => $week['to']+1,
+ 'to' => min(strtotime('+7 day', $week['to']), $endTime-1),
+ 'myTotal' => 0, 'teamTotal' => 0, 'teamAverage' => 0);
+ }
+
+ //Fetch approvals over specified date range
+ $conditions = array("Approval.created >= FROM_UNIXTIME('{$startTime}')",
+ "Approval.created < FROM_UNIXTIME('{$endTime}')");
+
+ $order = '`Approval`.`created` ASC';
+ if ($approvals = $this->Approval->findAll($conditions, null, $order)) {
+ foreach ($approvals as $k => $approval) {
+ $weeklyKey = $this->_makeYearWeekKey(strtotime($approval['Approval']['created']));
+ if (!array_key_exists($weeklyKey, $weeklyTotals)) {
+ // this should never happen, but better to let there be obvious gaps in
+ // weekly totals than seemingly legit (but probably bogus) counts
+ continue;
+ }
+
+ //Fetch addon details for approvals by the report user
+ if ($approval['User']['id'] == $userId) {
+ $approval['Addon'] = $this->Addon->getAddon($approval['Approval']['addon_id'],
+ array('list_details'));
+ $myApprovals[] = $approval;
+ $myTotal++;
+ $weeklyTotals[$weeklyKey]['myTotal']++;
+ }
+ $teamTotal++;
+ $weeklyTotals[$weeklyKey]['teamTotal']++;
+ }
+ }
+
+ /* add formatting to aid in debugging
+ foreach ($weeklyTotals as $k => $w) {
+ $weeklyTotals[$k]['formatted'] =
+ date('Y-m-d H:i:s', $w['from']).' - '.date('Y-m-d H:i:s', $w['to']);
+ }
+ pr($weeklyTotals); /**/
+
+ // YTD and MTD calculations
+ $sql = "SELECT MONTH(`Approval`.`created`) AS `month`, `User`.`id`, COUNT(*) AS `total`
+ FROM `approvals` AS `Approval`
+ LEFT JOIN `users` AS `User` ON (`User`.`id`=`Approval`.`user_id`)
+ WHERE `Approval`.`created` >= '".date('Y')."-01-01 00:00:00'
+ AND `Approval`.`created` < FROM_UNIXTIME('{$ytdEndTime}')
+ GROUP BY `month`, `Approval`.`user_id`";
+ if ($results = $this->Approval->query($sql)) {
+ $thisMonth = date('m');
+ foreach ($results as $row) {
+ $teamYtdTotal += $row[0]['total'];
+ $teamMtdTotal += ($row[0]['month'] == $thisMonth) ? $row[0]['total'] : 0;
+ if ($row['User']['id'] == $userId) {
+ $myYtdTotal += $row[0]['total'];
+ $myMtdTotal += ($row[0]['month'] == $thisMonth) ? $row[0]['total'] : 0;
+ }
+ }
+ }
+
+ //Calculate averages
+ $teamSize = $this->_teamSize($endTime);
+ if ($teamSize) {
+ $teamAverage = $teamTotal / $teamSize;
+ foreach ($weeklyTotals as $k => $week) {
+ $weeklyTotals[$k]['teamAverage'] = $week['teamTotal'] / $teamSize;
+ }
+ }
+ $teamYtdSize = $this->_teamSize($ytdEndTime);
+ if ($teamYtdSize) {
+ $teamYtdAverage = $teamYtdTotal / $teamYtdSize;
+ $teamMtdAverage = $teamMtdTotal / $teamYtdSize;
+ }
+
+ // Publish and render
+ $this->publish('startDate', $startDate);
+ $this->publish('endDate', $endDate);
+
+ $this->publish('addonTypes', $this->Addontype->getNames());
+ $this->publish('myApprovals', $myApprovals);
+ $this->publish('myTotal', $myTotal);
+ $this->publish('teamAverage', $teamAverage);
+ $this->publish('weeklyTotals', $weeklyTotals);
+ $this->publish('myMtdTotal', $myMtdTotal);
+ $this->publish('teamMtdAverage', $teamMtdAverage);
+ $this->publish('myYtdTotal', $myYtdTotal);
+ $this->publish('teamYtdAverage', $teamYtdAverage);
+
+ $this->render('performance_table');
+ }
+
+
+ /**
+ * Generate charts showing yearly activity and category breakdowns
+ * @param int $userId user to generate report for
+ */
+ function _performanceCharts($userId) {
+ $byMonthData = $this->_performanceSummaryByMonth($userId, 12);
+ $teamSize = $this->_teamSize(time());
+
+ // category breakdown can be for an entire year, or a specific
+ // month and year
+ $year = date('Y');
+ $month = null;
+ if (!empty($this->params['url']['year'])) {
+ $year = intval($this->params['url']['year']);
+ }
+ if (!empty($this->params['url']['month'])) {
+ $month = intval($this->params['url']['month']);
+ }
+ $byCatData = $this->_performanceSummaryByCategory($userId, $year, $month);
+
+ // points for x-axis labels (javascript)
+ $monthlyTicks = array();
+ foreach ($byMonthData['labels'] as $i => $label) {
+ $this->_sanitizeArray($label);
+ $monthlyTicks[] = "[{$i},'{$label}']";
+ }
+
+ // points for user activity (javascript)
+ $userPoints = array();
+ foreach ($byMonthData['usercount'] as $i => $n) {
+ $userPoints[] = "[{$i},{$n}]";
+ }
+
+ // points for team activity (javascript)
+ $teamPoints = array();
+ foreach ($byMonthData['teamcount'] as $i => $n) {
+ $n = $n / $teamSize;
+ $teamPoints[] = "[{$i},{$n}]";
+ }
+
+ // pie chart color-scheme (javascript)
+ $sliceColors = array("'#6d746a'","'#205f9a'","'#3d8128'","'#63522b'",
+ "'#dc5313'","'#f3c01c'","'#bc1c39'");
+
+ // pie chart labels (javascript)
+ $sliceLabels = array();
+ foreach ($byCatData['labels'] as $i => $label) {
+ $this->_sanitizeArray($label);
+ $sliceLabels[] = "'{$label}'";
+ }
+
+ // pie chart date title
+ if ($month) {
+ $pieTitleDate = strftime('%B %Y', mktime(12,0,0,$month,1,$year));
+ } else {
+ $pieTitleDate = $year;
+ }
+
+ // months for filter select
+ $monthSelect = array(''=>'');
+ for ($n = 1; $n<=12; $n++) {
+ $monthSelect[$n] = strftime('%B', mktime(12,0,0,$n,1));
+ }
+
+ $this->set('monthlyTicksJS', implode(',', $monthlyTicks));
+ $this->set('monthlyUserPointsJS', implode(',', $userPoints));
+ $this->set('monthlyTeamPointsJS', implode(',', $teamPoints));
+ $this->set('sliceColorsJS', implode(',', $sliceColors));
+ $this->set('sliceLabelsJS', implode(',', $sliceLabels));
+ $this->set('userPieDataJS', implode(',', $byCatData['usercount']));
+ $this->set('teamPieDataJS', implode(',', $byCatData['teamcount']));
+ $this->publish('year', $year);
+ $this->publish('month', $month);
+ $this->publish('monthSelect', $monthSelect);
+ $this->publish('pieTitleDate', $pieTitleDate);
+ $this->render('performance_charts');
+ }
+
+
+ /**
+ * Generate data for monthly summary of user and team activity
+ * @param int $userId user to generate report for
+ * @param int $months number of months
+ * @param int $endMonth last month of report (default current month)
+ * @param int $endYear year of last month of report (default current year)
+ * @return array
+ */
+ function _performanceSummaryByMonth($userId, $months=12, $endMonth=null, $endYear=null) {
+ $user = $this->User->findById($userId);
+ $data = array(
+ 'email' => $user['User']['email'],
+ 'firstname' => $user['User']['firstname'],
+ 'lastname' => $user['User']['lastname'],
+ 'labels' => array(),
+ 'usercount' => array(),
+ 'teamcount' => array());
+
+ if (is_null($endMonth)) {
+ $endMonth = date('n');
+ }
+ if (is_null($endYear)) {
+ $endYear = date('Y');
+ }
+
+ $endTime = strtotime(sprintf('%04d-%02d-01 00:00:00 +1 month', $endYear, $endMonth));
+ $startTime = strtotime(sprintf('-%d month', $months), $endTime);
+
+ $sql = "SELECT DATE_FORMAT(`Approval`.`created`, '%Y-%m') AS yearmonth,
+ `Approval`.`created`, `User`.`id`, COUNT(*) AS `total`
+ FROM `approvals` AS `Approval`
+ LEFT JOIN `users` AS `User` ON (`User`.`id`=`Approval`.`user_id`)
+ WHERE `Approval`.`created` >= FROM_UNIXTIME('{$startTime}')
+ AND `Approval`.`created` < FROM_UNIXTIME('{$endTime}')
+ GROUP BY yearmonth, `Approval`.`user_id`";
+
+ $results = $this->Approval->query($sql);
+ foreach ($results as $row) {
+ $label = strftime('%b %Y', strtotime($row['Approval']['created']));
+ if (!in_array($label, $data['labels'])) {
+ $data['labels'][] = $label;
+ $data['teamcount'][] = 0;
+ $data['usercount'][] = 0;
+ }
+ $i = count($data['labels']) - 1;
+ $data['teamcount'][$i] += $row[0]['total'];
+ if ($row['User']['id'] == $userId) {
+ $data['usercount'][$i] += $row[0]['total'];
+ }
+ }
+
+ return $data;
+ }
+
+
+ /**
+ * Generate data for category breakdown summary for user and team
+ * @param int $userId user to generate report for
+ * @param int $year year (default: current year)
+ * @param int $month month to summarize (default: generate data for entire year)
+ * @return array
+ */
+ function _performanceSummaryByCategory($userId, $year=null, $month=null) {
+ $user = $this->User->findById($userId);
+ $data = array(
+ 'email' => $user['User']['email'],
+ 'firstname' => $user['User']['firstname'],
+ 'lastname' => $user['User']['lastname'],
+ 'labels' => array(),
+ 'usercount' => array(),
+ 'teamcount' => array());
+
+ $addonTypes = $this->Addontype->getNames();
+ asort($addonTypes);
+
+ $addonTypeKeys = array();
+ foreach ($addonTypes as $key => $val) {
+ $addonTypeKeys[] = $key;
+ $data['labels'][] = $val;
+ $data['usercount'][] = 0;
+ $data['teamcount'][] = 0;
+ }
+
+ // single month or year summary breakdown by category
+ // default date range is current year
+ if (is_null($year)) {
+ $year = date('Y');
+ }
+
+ if ($month > 0) {
+ $startTime = strtotime(sprintf('%d-%02d-01 00:00:00', $year, $month));
+ $endTime = strtotime('+1 month', $startTime);
+ } else {
+ $startTime = strtotime(sprintf('%d-01-01 00:00:00', $year));
+ $endTime = strtotime('+1 year', $startTime);
+ }
+
+ $sql = "SELECT `Addon`.`addontype_id`, `User`.`id`, COUNT(*) AS `total`
+ FROM `approvals` AS `Approval`
+ LEFT JOIN `users` AS `User` ON (`User`.`id`=`Approval`.`user_id`)
+ LEFT JOIN `addons` AS `Addon` ON (`Addon`.`id`=`Approval`.`addon_id`)
+ WHERE `Approval`.`created` >= FROM_UNIXTIME('{$startTime}')
+ AND `Approval`.`created` < FROM_UNIXTIME('{$endTime}')
+ GROUP BY `Approval`.`user_id`, `Addon`.`addontype_id`";
+
+ $results = $this->Approval->query($sql);
+ foreach ($results as $row) {
+ $i = array_search($row['Addon']['addontype_id'], $addonTypeKeys);
+ if ($i === false) {
+ continue; // approvals should always have a known addontype ?
+ }
+ $data['teamcount'][$i] += $row[0]['total'];
+ if ($row['User']['id'] == $userId) {
+ $data['usercount'][$i] += $row[0]['total'];
+ }
+ }
+
+ return $data;
+ }
+
+
+ /**
+ * AJAX Add-on and Author email lookup
+ */
+ function addonAndAuthorLookup($queue='pending') {
+ if (!$this->SimpleAcl->actionAllowed('Admin', '%', $this->Session->read('User')) ||
+ !$this->SimpleAcl->actionAllowed('Editor', '*', $this->Session->read('User')) ) {
+ $this->Amo->accessDenied();
+ }
+
+ $text = $_REQUEST['q'];
+ $this->Amo->clean($text, false);
+ $addonsAndEmails = array();
+
+ if (strlen($text) > 0 && in_array($queue, array('pending', 'nominated'))) {
+ // Use the base filter components to limit results to those in the queue
+ $sql_base = $this->Editors->baseQueueFilterQuery($queue);
+
+ // search localized addon names
+ $sql = "SELECT DISTINCT IFNULL(`tr_l`.`localized_string`, `tr_en`.`localized_string`) AS `lname`
+ {$sql_base['FROM']}
+ {$sql_base['JOIN']}
+ LEFT JOIN `translations` AS `tr_l` ON
+ (`tr_l`.`id`=`Addon`.`name` AND `tr_l`.`locale`='".LANG."')
+ LEFT JOIN `translations` AS `tr_en` ON
+ (`tr_en`.`id`=`Addon`.`name` AND `tr_en`.`locale`=`Addon`.`defaultlocale`)
+ {$sql_base['WHERE']}
+ AND IFNULL(`tr_l`.`localized_string`, `tr_en`.`localized_string`) LIKE '%{$text}%'
+ ORDER BY `lname` ASC";
+
+ $results = $this->Version->query($sql);
+ if (!empty($results)) {
+ foreach ($results as $row) {
+ $addonsAndEmails[] = $row[0]['lname'];
+ }
+ }
+
+ // search localized addon support emails
+ $emails = array();
+ $sql = "SELECT IFNULL(`tr_l`.`localized_string`, `tr_en`.`localized_string`) AS `lemail`
+ {$sql_base['FROM']}
+ {$sql_base['JOIN']}
+ LEFT JOIN `translations` AS `tr_l` ON
+ (`tr_l`.`id`=`Addon`.`supportemail` AND `tr_l`.`locale`='".LANG."')
+ LEFT JOIN `translations` AS `tr_en` ON
+ (`tr_en`.`id`=`Addon`.`supportemail` AND `tr_en`.`locale`=`Addon`.`defaultlocale`)
+ {$sql_base['WHERE']}
+ AND IFNULL(`tr_l`.`localized_string`, `tr_en`.`localized_string`) LIKE '%{$text}%'";
+
+ $results = $this->Version->query($sql);
+ if (!empty($results)) {
+ foreach ($results as $row) {
+ $emails[] = $row[0]['lemail'];
+ }
+ }
+
+ // search author emails
+ $sql = "SELECT `User`.`email`
+ {$sql_base['FROM']}
+ {$sql_base['JOIN']}
+ LEFT JOIN `addons_users` AS `au` ON (`Addon`.`id`=`au`.`addon_id`)
+ LEFT JOIN `users` AS `User` ON (`au`.`user_id`=`User`.`id`)
+ {$sql_base['WHERE']}
+ AND `au`.`role` IN(".AUTHOR_ROLE_ADMINOWNER.","
+ .AUTHOR_ROLE_ADMIN.","
+ .AUTHOR_ROLE_OWNER.","
+ .AUTHOR_ROLE_DEV.")
+ AND `User`.`email` LIKE '%{$text}%'";
+
+ $results = $this->Version->query($sql);
+ if (!empty($results)) {
+ foreach ($results as $row) {
+ $emails[] = $row['User']['email'];
+ }
+ }
+
+ // sort, dedup, and merge
+ sort($emails);
+ $emails = array_unique($emails);
+ $addonsAndEmails = array_merge($addonsAndEmails, $emails);
+ }
+
+ $this->set('addonsAndEmails', $addonsAndEmails);
+ $this->render('ajax/addon_and_author_lookup', 'ajax');
+ }
+
+ /**
+ * AJAX action for looking up appversions for the specified app
+ * @param int $app_id The application id
+ */
+ function appversionLookup($app_id) {
+ $this->Amo->clean($app_id);
+ $results = $this->Appversion->findAllByApplicationId($app_id,
+ array('Appversion.id', 'Appversion.version'), 'Appversion.version DESC');
+ $appversions = array();
+ foreach ($results as $av) {
+ $appversions[] = $av['Appversion'];
+ }
+
+ $this->publish('appversions', $appversions);
+ $this->render('ajax/appversion_lookup', 'ajax');
+ }
+
+ /**
+ * Count the number of (possibly filtered) items in the specified queue
+ * @param string $queue
+ * @param bool $useFilter (default=false)
+ * @return int
+ * @todo possibly cache results
+ */
+ function _getCount($queue, $useFilter=false) {
+ $result = null;
+
+ if ($useFilter && $this->Editors->buildQueueFilterQuery($queue)) {
+ $sql = $this->Editors->buildQueueFilterQuery($queue);
+ $result = $this->Addon->query(
+ "SELECT COUNT(*) {$sql['FROM']} {$sql['JOIN']} {$sql['WHERE']}");
+
+ } elseif ($queue == 'pending') {
+ $result = $this->File->query(
+ "SELECT COUNT(*) FROM `files` WHERE `status`=".STATUS_PENDING." GROUP BY `status`");
+
+ } elseif ($queue == 'nominated') {
+ $result = $this->Addon->query(
+ "SELECT COUNT(*) FROM `addons` WHERE `status`=".STATUS_NOMINATED." GROUP BY `status`");
+
+ } elseif ($queue == 'reviews') {
+ $result = $this->Review->query(
+ "SELECT COUNT(*) FROM `reviews` WHERE `editorreview`=1 GROUP BY `editorreview`");
+ }
+
+ $count = !empty($result) ? $result[0][0]['COUNT(*)'] : 0;
+
+ return $count;
+ }
+
+ /**
+ * Fetch an array of (possibly filtered) addons for the specified queue
+ * @param string $queue
+ * @return array
+ */
+ function _buildQueue($queue) {
+ if (!in_array($queue, array('pending', 'nominated'))) {
+ return array();
+ }
+
+ $sql = $this->Editors->buildQueueFilterQuery($queue);
+
+ // Setup pagination
+ $this->Pagination->total = $this->_getCount($queue, true);
+
+ $_pagination_options = array();
+ if ($queue == 'pending') {
+ if (!array_key_exists('show', $_GET) && $this->Session->read('editor_queue_pending_show')) {
+ $_pagination_options['show'] = $this->Session->read('editor_queue_pending_show');
+ } else {
+ // If $_GET['show'] exists it overrides this in the pagination component
+ $_pagination_options['show'] = 50;
+ }
+ list($not_used,$_limit,$_page) = $this->Pagination->init(null, null, $_pagination_options);
+ $this->Session->write('editor_queue_pending_show', $_limit);
+
+ } else {
+ if (!array_key_exists('show', $_GET) && $this->Session->read('editor_queue_nominated_show')) {
+ $_pagination_options['show'] = $this->Session->read('editor_queue_nominated_show');
+ } else {
+ // If $_GET['show'] exists it overrides this in the pagination component
+ $_pagination_options['show'] = 50;
+ }
+ list($not_used,$_limit,$_page) = $this->Pagination->init(null,null,$_pagination_options);
+ $this->Session->write('editor_queue_nominated_show', $_limit);
+ }
+
+ $_offset = ($_page > 0) ? $_limit * ($_page-1) : 0; // no negative offsets, thank you
+
+ $extra_fields = '';
+ if ($queue == 'pending') {
+ $extra_fields .= ", `File`.`id`, `File`.`platform_id`";
+ }
+
+ // Fetch the queue
+ $queue_sql = "SELECT
+ `Version`.`id`,
+ `Version`.`addon_id`,
+ `Version`.`version`,
+ `Version`.`created`,
+ `Version`.`modified`
+ {$extra_fields}
+ {$sql['FROM']}
+ {$sql['JOIN']}
+ {$sql['WHERE']}
+ {$sql['ORDER']}
+ LIMIT {$_limit} OFFSET {$_offset}";
+
+ $addons = $this->Version->query($queue_sql);
+
+ //Merge in Addon details
+ if (!empty($addons)) {
+ foreach ($addons as $k => $addon) {
+ $addon = $this->Addon->findById($addon['Version']['addon_id'],
+ array('Addon.id',
+ 'Addon.name', 'Addon.defaultlocale',
+ 'Addon.addontype_id', 'Addon.prerelease',
+ 'Addon.sitespecific', 'Addon.externalsoftware',
+ 'Addon.created', 'Addon.nominationdate'), '', 0);
+ $addons[$k] = array_merge_recursive($addons[$k], $addon);
+ }
+ }
+
+ $platforms = $this->Amo->getPlatformName();
+ $applications = $this->Amo->getApplicationName();
+
+ //make modifications to the queue array
+ if (!empty($addons)) {
+ foreach ($addons as $k => $addon) {
+ //get min/max versions
+ if ($targetApps = $this->Amo->getMinMaxVersions($addon['Version']['id'])) {
+ foreach ($targetApps as $targetApp) {
+ $appName = $targetApp['translations']['localized_string'];
+ $addons[$k]['targetApps'][$appName]['min'] = $targetApp['min']['version'];
+ $addons[$k]['targetApps'][$appName]['max'] = $targetApp['max']['version'];
+ }
+ }
+
+ //Age
+ if ($queue == 'pending') {
+ $age = time() - strtotime($addon['Version']['created']);
+ }
+ elseif ($queue == 'nominated') {
+ $age = time() - strtotime($addon['Addon']['created']);
+ $nominationage = time() - strtotime($addon['Addon']['nominationdate']);
+ $addons[$k]['nominationage'] = $this->_humanizeAge($nominationage);
+ }
+
+ $addons[$k]['age'] = $this->_humanizeAge($age);
+
+ //Generate any additional notes
+ $addons[$k]['notes'] = array();
+
+ //Platform-specific?
+ if (!empty($addon['Version'][0]['File'][0]['platform_id']) && $addon['Version'][0]['File'][0]['platform_id'] != 1) {
+ $os = array();
+ foreach ($addon['Version'][0]['File'] as $file) {
+ $os[] = $platforms[$file['platform_id']];
+ }
+ $addons[$k]['notes'][] = sprintf(_('editors_platform_x_only'), implode(', ', $os));
+ }
+ elseif (!empty($addon['File']['platform_id']) && $addon['File']['platform_id'] != 1) {
+ $addons[$k]['notes'][] = sprintf(_('editors_platform_x_only'), $platforms[$addon['File']['platform_id']]);
+ }
+
+ //Featured?
+ //@TODO
+
+ //Site specific?
+ if ($addon['Addon']['sitespecific'] == 1) {
+ $addons[$k]['notes'][] = _('editors_site_specific');
+ }
+ //Pre-release?
+ if ($addon['Addon']['prerelease'] == 1) {
+ $addons[$k]['notes'][] = _('editors_pre-release');
+ }
+ //External software?
+ if ($addon['Addon']['externalsoftware'] == 1) {
+ $addons[$k]['notes'][] = _('editors_external_software');
+ }
+ }
+ }
+ //pr($addons);
+
+ return $addons;
+ }
+
+ /**
+ * Moderated Reviews Queue
+ */
+ function _reviews($count) {
+ if (!empty($this->data)) {
+ foreach ($this->data['Reviews'] as $k => $review) {
+ if ($review != 'skip') {
+ preg_match("/^review(\d+)$/", $k, $matches);
+ $this->Review->id = intval($matches[1]);
+
+ if ($review == 'approve') {
+ //Log editor action
+ $this->Eventlog->log($this, 'editor', 'review_approve', null, $this->Review->id);
+
+ $this->Review->save(array('editorreview' => 0));
+ // HACK: not sure how this is done without deleteAll()
+ $reviews_flags = $this->ReviewsModerationFlag->query(
+ 'DELETE FROM reviews_moderation_flags WHERE review_id='.$this->Review->id
+ );
+ }
+ elseif ($review == 'delete') {
+ //Pull review for log
+ $this->Review->setLang('en-US', $this);
+ $review = $this->Review->read();
+ $this->Review->setLang(LANG, $this);
+
+ $reviewArray = array('title' => $review['Translation']['title']['string'],
+ 'body' => $review['Translation']['body']['string']);
+ //Log editor action
+ $this->Eventlog->log($this, 'editor', 'review_delete', null, $this->Review->id, null, null, serialize($reviewArray));
+
+ // HACK: not sure how this is done without deleteAll()
+ $reviews_flags = $this->ReviewsModerationFlag->query(
+ 'DELETE FROM reviews_moderation_flags WHERE review_id='.$this->Review->id
+ );
+ $this->Review->delete();
+ }
+ }
+ }
+
+ $this->flash(_('editors_reviews_processed'), '/editors/queue/reviews');
+ return;
+ }
+
+ $criteria = array('Review.editorreview' => '1');
+
+ // initialize pagination
+ $this->Pagination->total = $count;
+ if (!array_key_exists('show', $_GET) && $this->Session->read('editor_queue_reviews_show')) {
+ // Have to modify $_GET because pagination component pulls directly from it
+ $_GET['show'] = $this->Session->read('editor_queue_reviews_show');
+ }
+ list($order,$limit,$page) = $this->Pagination->init($criteria);
+ $this->Session->write('editor_queue_reviews_show', $limit);
+
+ $_reviews = $this->Review->findAll($criteria, "Review.id", 'Review.modified ASC', $limit, $page, -1);
+ $_review_ids = array();
+ foreach ($_reviews as $_id) $_review_ids[] = $_id['Review']['id'];
+ unset($_reviews);
+ $reviews = $this->Review->getReviews($_review_ids, true);
+ foreach ($reviews as $k => $review) {
+ $reviews[$k]['Addon'] = $this->Addon->findById($review['Review']['addon_id'], array('id', 'name'), null, -1);
+ if (!empty($review['Review']['reply_to'])) {
+ $_replyto = $this->Review->getReviews($review['Review']['reply_to']);
+ if (!empty($_replyto))
+ $reviews[$k]['Review']['reply_to'] = $_replyto[0];
+ }
+ }
+ unset($_replyto);
+
+ // Gather and collate all available flags per review on the page.
+ // NOTE: User info isn't included here, keeping things anonymous.
+ $reviews_flags = array();
+ $reviews_flags_notes = array();
+ $this->ReviewsModerationFlag->unbindFully();
+ $_reviews_flags = $this->ReviewsModerationFlag->findAll(array(
+ 'ReviewsModerationFlag.review_id' => $_review_ids
+ ));
+ foreach ($_reviews_flags as $flag) {
+ $review_id = $flag['ReviewsModerationFlag']['review_id'];
+ $flag_name = $flag['ReviewsModerationFlag']['flag_name'];
+
+ // Count the occurrences of each flag per review, building
+ // the data structure as we go.
+ if (!isset($reviews_flags[$review_id]))
+ $reviews_flags[$review_id] = array();
+ if (!isset($reviews_flags[$review_id][$flag_name]))
+ $reviews_flags[$review_id][$flag_name] = 1;
+ else
+ $reviews_flags[$review_id][$flag_name] += 1;
+
+ // Collect freeform notes in a separate list.
+ if ($flag_name == 'review_flag_reason_other') {
+ if (!isset($reviews_flags_notes[$review_id]))
+ $reviews_flags_notes[$review_id] = array();
+ $reviews_flags_notes[$review_id][] =
+ $flag['ReviewsModerationFlag']['flag_notes'];
+ }
+ }
+
+ $this->publish('reviews', $reviews);
+ $this->publish('reviews_flags', $reviews_flags);
+ $this->publish('reviews_flags_notes', $reviews_flags_notes);
+ $this->publish('review_flag_reasons',
+ $this->ReviewsModerationFlag->reasons);
+
+ $this->render('reviews_queue');
+ }
+
+ /**
+ * Featured Add-ons
+ * params are for ajax callbacks
+ */
+ function featured($command=null, $ajax=null) {
+ $this->Amo->clean($this->data);
+
+ switch($command) {
+ case 'add':
+ if (preg_match('/\[(\d+)\]/', $this->data['Addon']['id'], $matches)) {
+ $this->data['Addon']['id'] = $matches[1];
+ }
+
+ if (!is_numeric($this->data['Addon']['id']) || !is_numeric($this->data['Tag']['id'])) {
+ header('HTTP/1.1 400 Bad Request');
+ $this->flash(_('editors_featured_addon_add_failure'), '/editors/featured');
+ return;
+ }
+
+ $_addon = $this->Addon->getAddon($this->data['Addon']['id']);
+ if ($_addon['Addon']['status'] != STATUS_PUBLIC) {
+ header('HTTP/1.1 400 Bad Request');
+ $this->flash(_('editors_featured_addon_edit_failure'), '/editors/featured');
+ return;
+ }
+
+ // If the add-on isn't in the category, we'll add it.
+ $_new_feature_query = "REPLACE INTO addons_tags (addon_id, tag_id, feature) VALUES ( '{$this->data['Addon']['id']}', '{$this->data['Tag']['id']}', 1)";
+
+ if ($this->AddonTag->query($_new_feature_query)) {
+ header('HTTP/1.1 400 Bad Request');
+ $this->flash(_('editors_featured_addon_add_failure'), '/editors/featured');
+ } else {
+ $this->Eventlog->log($this, 'editor', 'feature_add', '', $this->data['Addon']['id'], $this->data['Addon']['id']);
+ $this->flash(_('editors_featured_addon_add_success'), '/editors/featured', 3);
+ }
+
+ return;
+ case 'edit':
+ global $valid_languages;
+
+ if (!empty($this->data['AddonTag']['feature_locales'])) {
+ if (count(array_diff(explode(',',$this->data['AddonTag']['feature_locales']), array_keys($valid_languages))) > 0) {
+ header('HTTP/1.1 400 Bad Request');
+ $this->flash(_('editors_featured_addon_invalid_locale'), '/editors/featured');
+ return;
+ }
+ }
+
+ if (!is_numeric($this->data['Addon']['id']) || !is_numeric($this->data['Tag']['id']) || preg_match('/[^A-Za-z,-]/',$this->data['AddonTag']['feature_locales'])) {
+ header('HTTP/1.1 400 Bad Request');
+ $this->flash(_('editors_featured_addon_edit_failure'), '/editors/featured');
+ return;
+ }
+
+ $this->Eventlog->log($this, 'editor', 'feature_locale_change', 'feature-locales', $this->data['Addon']['id']);
+
+ // Reorder the locales
+ $_locales = array_unique(explode(',', $this->data['AddonTag']['feature_locales']));
+ sort($_locales);
+ $this->data['AddonTag']['feature_locales'] = implode(',',$_locales);
+
+ $_edit_feature_query = "UPDATE addons_tags
+ SET feature_locales='{$this->data['AddonTag']['feature_locales']}'
+ WHERE addon_id='{$this->data['Addon']['id']}'
+ AND tag_id='{$this->data['Tag']['id']}'";
+
+ if ($this->AddonTag->query($_edit_feature_query)) {
+ header('HTTP/1.1 400 Bad Request');
+ $this->flash(_('editors_featured_addon_edit_failure'), '/editors/featured');
+ } else {
+ $this->flash(_('editors_featured_addon_edit_success'), '/editors/featured', 3);
+ }
+ return;
+
+ case 'remove':
+ if (is_numeric($this->data['Tag']['id']) && is_numeric($this->data['Addon']['id'])) {
+
+ $this->Eventlog->log($this, 'editor', 'feature_remove', null, $this->data['Addon']['id'], null, $this->data['Addon']['id']);
+
+ // Neither query() nor execute() return success from a DELETE call, even when the row is deleted. wtf.
+ $this->AddonTag->execute("DELETE FROM `addons_tags` WHERE addon_id='{$this->data['Addon']['id']}' AND tag_id='{$this->data['Tag']['id']}' AND feature=1 LIMIT 1");
+
+ // Assume we succeeded
+ $this->flash(_('editors_featured_addon_remove_success'), '/editors/featured', 3);
+ return;
+ }
+
+ header('HTTP/1.1 400 Bad Request');
+ $this->flash(_('editors_featured_addon_remove_failure'), '/editors/featured');
+
+ return;
+
+ default:
+ break;
+ }
+
+ // Setup title and breadcrumbs
+ $this->breadcrumbs[_('editors_featured_addons_pagetitle')] = '/editors/featured';
+ $this->publish('breadcrumbs', $this->breadcrumbs);
+ $this->publish('subpagetitle', _('editors_featured_addons_pagetitle'));
+
+ // Get all featured Addons
+ $features = $this->AddonTag->findAllByFeature(1, array('addon_id'));
+ $_addon_ids = $addons_by_tag = array();
+
+ if (!empty($features)) {
+ foreach ($features as $feature) { $_addon_ids[] = $feature['AddonTag']['addon_id']; }
+ $_addon_ids = array_unique($_addon_ids);
+
+ // Big ol' array
+ $features = $this->Addon->findAll(array('Addon.id' => $_addon_ids), array('Addon.id', 'Addon.name', 'Addon.addontype_id'), 'Translation.name');
+
+ foreach ($features as $feature) {
+ // Dump them into the array sorted by category
+ foreach ($feature['AddonTag'] as $attributes) {
+ if ($attributes['feature'] == 1) {
+ // override the AddonTag array for the view. Even though an add-on will have multiple tags, we only want one for this view
+ $feature['AddonTag'] = array( 0 => $attributes );
+
+ $addons_by_tag[$attributes['tag_id']][] = $feature;
+ }
+
+ }
+
+ }
+ }
+
+ // Reorganize the tags so it's easier to use them in the view. TheLittleThingsWearMeDown++ :(
+ $tags = array();
+ foreach ($this->Tag->findAll('', null, array('Tag.application_id', 'Tag.addontype_id', 'Translation.name')) as $tag) {
+ $tags[$tag['Tag']['id']] = $tag;
+ }
+
+ $this->set('applications', $this->Amo->getApplicationName());
+ $this->set('addontypes', $this->Addontype->getNames());
+ $this->set('tags', $tags);
+ $this->set('mode', 'featured');
+ $this->publish('addons_by_tag', $addons_by_tag);
+ $this->render('featured');
+
+ }
+
+ /**
+ * Display logs
+ */
+ function logs() {
+ $this->breadcrumbs[_('editorcp_logs_page_heading')] = '/editors/logs';
+ $this->set('breadcrumbs', $this->breadcrumbs);
+
+ $conditions = array();
+
+ if (!empty($this->data)) {
+ $filter = explode(':', $this->data['Eventlog']['filter']);
+ $conditions['type'] = $filter[0];
+
+ if ($filter[1] != '*') {
+ $conditions['action'] = $filter[1];
+ }
+ }
+ $conditions['type'] = 'editor';
+
+ $logs = $this->Eventlog->findAll($conditions, null, 'Eventlog.created DESC');
+
+ $logs = $this->Audit->explainLog($logs);
+
+ $this->set('logs', $logs);
+
+ $this->set('page', 'logs');
+ $this->render('logs');
+ }
+
+ function reviewlog() {
+ //Default conditions are the current month
+ $monthStart = date('Y-m-01');
+ $conditions = "Approval.created >= '{$monthStart} 00:00:00'";
+ $startdate = $monthStart;
+ $enddate = 'YYYY-MM-DD';
+
+ //If user has specified own conditions, use those
+ if (!empty($this->params['url']['start'])) {
+ $start_time = strtotime($this->params['url']['start']);
+ $end_time = strtotime($this->params['url']['end']);
+ if ($start_time !== false && $start_time != -1) {
+ $conditions = array(
+ "Approval.created >= FROM_UNIXTIME('{$start_time}')"
+ );
+ $startdate = $this->params['url']['start'];
+
+ if ($end_time !== false && $end_time != -1) {
+ $conditions[] = "Approval.created < FROM_UNIXTIME('".strtotime('+1 day', $end_time)."')";
+ $enddate = $this->params['url']['end'];
+ }
+ }
+ }
+
+ // set up pagination
+ list($order,$limit,$page) = $this->Pagination->init($conditions, null,
+ array('modelClass'=>'Approval', 'show'=>50));
+
+ $approvals = $this->Approval->findAll($conditions, null, $order, $limit, $page);
+ foreach ($approvals as $k => $approval) {
+ $approvals[$k]['Addon'] = $this->Addon->getAddon($approval['Approval']['addon_id']);
+ }
+
+ $this->publish('approvals', $approvals);
+ $this->publish('startdate', $startdate);
+ $this->publish('enddate', $enddate);
+
+ $this->set('page', 'reviewlog');
+ $this->render('reviewlog');
+ }
+
+ /* Humanizes a Unix Timestamp */
+ function _humanizeAge($age) {
+ $humanized = '';
+
+ //days
+ if ($age >= (60*60*24*2)) {
+ $humanized = sprintf(_('editors_x_days'), floor($age/(60*60*24)));
+ }
+ //1 day
+ elseif ($age >= (60*60*24)) {
+ $humanized = _('editors_one_day');
+ }
+ //hours
+ elseif ($age >= (60*60*2)) {
+ $humanized = sprintf(_('editors_x_hours'), floor($age/(60*60)));
+ }
+ //hour
+ elseif ($age >= (60*60)) {
+ $humanized = _('editors_one_hour');
+ }
+ //minutes
+ elseif ($age > 60) {
+ $humanized = sprintf(_('editors_x_minutes'), floor($age/60));
+ }
+ //minute
+ else {
+ $humanized = _('editors_one_minute');
+ }
+
+ return $humanized;
+ }
+
+ /* Generate a sortable key from the given timestamp in the form of 'YYYY-WW' */
+ function _makeYearWeekKey($timestamp) {
+ $year = date('Y', $timestamp);
+ $week = date('W', $timestamp);
+
+ // the end of December is often part of the first week for the following year
+ if ($week == '01' && date('m', $timestamp) == '12') {
+ $year++;
+ }
+ return "{$year}-{$week}";
+ }
+
+ /* Approximate team size at a point in time */
+ function _teamSize($timestamp) {
+ $this->Amo->clean($timestamp);
+
+ // Count the number of unique users that submitted a review during
+ // the 60 days leading up to the time specified.
+ $teamSize = 0;
+ $sql = "SELECT COUNT(DISTINCT `Approval`.`user_id`) AS `teamSize`
+ FROM `approvals` AS `Approval`
+ WHERE `Approval`.`created` < FROM_UNIXTIME('{$timestamp}')
+ AND `Approval`.`created` >= FROM_UNIXTIME('".strtotime('-60 day', $timestamp)."')";
+ if ($results = $this->Approval->query($sql)) {
+ $teamSize = $results[0][0]['teamSize'];
+ }
+ return $teamSize;
+ }
+
+ /* Fetch emails of all editors active in the last reviewDays days */
+ function _recentEditors($reviewDays=90) {
+ $this->Amo->clean($reviewDays);
+
+ $sql = "SELECT DISTINCT `User`.`email`
+ FROM `approvals` AS `Approval`
+ INNER JOIN `users` AS `User` ON (`User`.`id`=`Approval`.`user_id`)
+ WHERE `Approval`.`created` >= FROM_UNIXTIME('".strtotime("-{$reviewDays} day")."')
+ ORDER BY `User`.`email` ASC";
+
+ $editors = array();
+ if ($results = $this->Approval->query($sql)) {
+ foreach ($results as $user) {
+ $editors[] = $user['User']['email'];
+ }
+ }
+
+ return $editors;
+ }
+}
+
+?>
diff --git a/site/app/controllers/facebook_controller.php b/site/app/controllers/facebook_controller.php
new file mode 100644
index 0000000..30ea0c6
--- /dev/null
+++ b/site/app/controllers/facebook_controller.php
@@ -0,0 +1,805 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Justin Scott <fligtar@mozilla.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+define('RESULTS_PER_PAGE', 8);
+
+class FacebookController extends AppController
+{
+ var $name = 'Facebook';
+ var $beforeFilter = array('checkCSRF', 'getNamedArgs');
+ var $uses = array('Addon', 'Application', 'FacebookData', 'FacebookFavorite', 'FacebookSession', 'FacebookUser', 'File', 'Preview', 'Tag', 'User', 'Version');
+ var $components = array('Amo', 'Image', 'Newsfeed', 'Search');
+ var $helpers = array('Html', 'Facebook');
+
+ var $securityLevel = 'low';
+
+ /**
+ * Initialize API and permission checks
+ */
+ function beforeFilter() {
+ // Disable ACLs because this controller is entirely public.
+ $this->SimpleAuth->enabled = false;
+ $this->SimpleAcl->enabled = false;
+
+ $this->Amo->startup($this);
+ // Require API to be enabled
+ if ((!defined('FB_ENABLED') || FB_ENABLED == 'false')) {
+ $this->Amo->accessDenied();
+ exit;
+ }
+
+ vendor('facebook'.DS.'facebook');
+
+ // New facebook API
+ $this->facebook = new Facebook(FB_API_KEY, FB_API_SECRET);
+ $this->fbUser = $this->facebook->get_loggedin_user();
+
+ $this->set('fbUser', $this->fbUser);
+
+ $publicActions = array('app', 'outage', 'faq', 'wallpaper', 'updatenotes');
+ if (!in_array($this->action, $publicActions)) {
+ $this->facebook->require_add();
+
+ /*/ While in development, require user to be in the Mozilla or Facebook networks
+ if (!$this->_inMozillaOrFacebookNetworks()) {
+ die("<fb:error><fb:message>Coming soon!</fb:message>Sorry, this application isn't available for public use quite yet. Please check back soon!</fb:error>");
+ }*/
+ }
+
+ if ($this->action != 'app') {
+ $this->FacebookUser->updateActivity($this->fbUser);
+ }
+
+ // Use shadow db for all add-on related reading
+ $this->Addon->useDbConfig = 'shadow';
+ $this->File->useDbConfig = 'shadow';
+ $this->Version->useDbConfig = 'shadow';
+ $this->FacebookFavorite->caching = false;
+ }
+
+ /**
+ * Main page
+ */
+ function index() {
+ return $this->home();
+ }
+
+ /**
+ * Home
+ */
+ function home($dialog = '') {
+ // Get friends
+ $friends = implode(', ', $this->facebook->api_client->friends_get());
+
+ // Get favorites
+ $favorites = $this->FacebookFavorite->getFavoriteIds($this->fbUser, true);
+
+ // Get newsfeed
+ $newsfeed = $this->Newsfeed->generate($this->fbUser, $friends, $favorites);
+ $this->set('newsfeed', $newsfeed);
+
+ // Get new add-on count since last favorite
+ $newAddonCount = $this->Newsfeed->getNewAddonCount($this->fbUser);
+ $this->set('newAddonCount', $newAddonCount);
+
+ // If user just added the app, show getting started message
+ if ($dialog == 'gettingstarted') {
+ $successMessage = 'Rock Your Firefox helps you discover new add-ons and share them with your friends by keeping track of your favorite add-ons. Add-ons you mark as favorites will be designated and recommended to your friends.<br><br>';
+ $successMessage .= 'If you already have add-ons installed in Firefox, you can <a href="'.FB_URL.'/import?ref=gs">import them as favorites</a>.';
+ $successMessage .= ' If not, you can <a href="'.FB_URL.'/browse?ref=gs">start browsing!</a>';
+ $this->set('successTitle', 'Getting Started');
+ $this->set('successMessage', $successMessage);
+ $this->set('justAdded', true);
+ }
+
+ // If user invited friends, show confirmation
+ if ($dialog == 'invited') {
+ $successMessage = 'Your invitations have been sent.';
+ $this->set('successTitle', 'Invitations Sent!');
+ $this->set('successMessage', $successMessage);
+ }
+
+ $this->set('page', 'home');
+ $this->render('home', 'facebook');
+ }
+
+ /**
+ * Post-add and post-remove
+ */
+ function app($action) {
+ if ($action == 'add') {
+ $this->FacebookUser->add($this->fbUser);
+
+ $this->FacebookData->updateData('add', $this->fbUser, $this->facebook->api_client);
+
+ $this->home('gettingstarted');
+ }
+ elseif ($action == 'remove') {
+ $this->FacebookUser->remove($this->fbUser);
+
+ $this->FacebookData->updateData('remove', $this->fbUser, $this->facebook->api_client);
+ }
+ }
+
+ /**
+ * View a specific addon in a display window
+ * @param int $addon_id the add-on id to display
+ */
+ function view($addon_id) {
+ $this->Amo->clean($addon_id);
+
+ if (empty($this->isFavorite)) {
+ $this->isFavorite = $this->FacebookFavorite->isFavorite($this->fbUser, $addon_id);
+ }
+
+ $this->Addon->id = $addon_id;
+ $addon = $this->Addon->read();
+
+ foreach ($addon['User'] as $author) {
+ $authors[] = "{$author['firstname']} {$author['lastname']}";
+ }
+ $this->set('addon_authors', $authors);
+
+ $previews = $this->Preview->findAll("Preview.addon_id='{$addon_id}'", array('caption'));
+ $this->set('previewCount', count($previews));
+ $this->set('previewCaptions', $previews);
+
+ // Get friends
+ $friends = implode(', ', $this->facebook->api_client->friends_get());
+ $addon['friendRecommended'] = $this->FacebookFavorite->findCount("FacebookFavorite.fb_user IN ({$friends}) AND FacebookFavorite.addon_id={$addon['Addon']['id']}");
+ $addon['allRecommended'] = $this->FacebookFavorite->findAll("FacebookFavorite.addon_id={$addon['Addon']['id']}", null, "RAND()");
+
+ $version_id = $this->Version->getVersionByAddonId($addon['Addon']['id']);
+ $version = $this->Version->findById($version_id);
+
+ $this->set('addon', $addon);
+ $this->set('version', $version);
+ $this->set('id', $addon_id);
+ $this->set('isFavorite', $this->isFavorite);
+ $this->set('page', 'view');
+ $this->render('view', 'facebook');
+ }
+
+ /**
+ * Import
+ */
+ function import() {
+ $this->set('key', $this->FacebookSession->generateKey($this->fbUser));
+
+ $this->set('page', 'import');
+ $this->render('import_info', 'facebook');
+ }
+
+ /**
+ * Search add-ons
+ */
+ function search() {
+ $type = !empty($this->namedArgs['type']) ? $this->namedArgs['type'] : 'none';
+ $page = !empty($this->namedArgs['page']) ? $this->namedArgs['page'] : 1;
+ $current = array('type' => $type,
+ 'page' => $page);
+ $this->set('current', $current);
+
+ uses('sanitize');
+ $this->Sanitize = new Sanitize();
+
+ if ($results = $this->Search->search($_GET['q'])) {
+ $results = implode(',', $results);
+ $criteria = "Addon.id IN (".$results.") AND Addon.status=".STATUS_PUBLIC." AND Addon.inactive=0";
+
+ $typeCriteria = '';
+ if ($type == ADDON_EXTENSION || $type == ADDON_THEME) {
+ $typeCriteria = " AND Addon.addontype_id={$type}";
+ }
+ elseif ($type == 'friends') {
+ //something
+ }
+
+ $addons = $this->Addon->findAll($criteria.$typeCriteria, null, 'FIELD(Addon.id,'.$results.')', RESULTS_PER_PAGE, $page);
+
+ $count['total'] = $this->Addon->findCount("{$criteria} AND (Addon.addontype_id=".ADDON_EXTENSION." OR Addon.addontype_id=".ADDON_THEME.")");
+ $count['extensions'] = $this->Addon->findCount("{$criteria} AND Addon.addontype_id=".ADDON_EXTENSION);
+ $count['themes'] = $this->Addon->findCount("{$criteria} AND Addon.addontype_id=".ADDON_THEME);
+ $count['friends'] = 0;
+ $count['pages'] = ceil($count['total'] / RESULTS_PER_PAGE);
+
+ // Get friends
+ $friends = implode(', ', $this->facebook->api_client->friends_get());
+ foreach ($addons as $k => $addon) {
+ $addons[$k]['FacebookFavorite'] = $this->FacebookFavorite->findAll("FacebookFavorite.fb_user IN ({$friends}) AND FacebookFavorite.addon_id={$addon['Addon']['id']}");
+ $addons[$k]['previewCount'] = $this->Preview->findCount("Preview.addon_id='{$addon['Addon']['id']}'");
+ }
+ }
+ else {
+ $addons = array();
+ $count = array('total' => 0,
+ 'extensions' => 0,
+ 'themes' => 0,
+ 'friends' => 0,
+ 'pages' => 0);
+ }
+
+ $this->set('addons', $addons);
+ $this->set('count', $count);
+
+ $this->Amo->clean($_GET['q']);
+ $this->publish('q', stripslashes($_GET['q']));
+
+ $this->set('page', 'search');
+ $this->render('search', 'facebook');
+ }
+
+ /**
+ * Browse add-ons via named parameters
+ */
+ function browse() {
+ $this->Amo->clean($_GET);
+
+ if (isset($_GET['sort']))
+ $this->namedArgs['sort'] = $_GET['sort'];
+
+ if (isset($_GET['cat']))
+ $this->namedArgs['cat'] = $_GET['cat'];
+
+ $sort = !empty($this->namedArgs['sort']) ? $this->namedArgs['sort'] : 'popular';
+ $type = !empty($this->namedArgs['type']) ? $this->namedArgs['type'] : 'none';
+ $cat = !empty($this->namedArgs['cat']) ? $this->namedArgs['cat'] : 'all';
+ $fbUser = !empty($this->namedArgs['fid']) ? $this->namedArgs['fid'] : '';
+ $page = !empty($this->namedArgs['page']) ? $this->namedArgs['page'] : 1;
+ $order = ($sort == 'name') ? 'ASC' : 'DESC';
+
+ $current = array('sort' => $sort,
+ 'type' => $type,
+ 'cat' => $cat,
+ 'page' => $page,
+ 'order' => $order,
+ 'fbUser' => $fbUser);
+ $this->set('current', $current);
+
+ if ($type == 'none')
+ $currentType = 'total';
+ elseif ($type == ADDON_EXTENSION)
+ $currentType = 'extensions';
+ elseif ($type == ADDON_THEME)
+ $currentType = 'themes';
+ elseif ($type == 'friends')
+ $currentType = 'friends';
+
+ if ($type == 'friends') {
+ // Get friends
+ $friends = implode(', ', $this->facebook->api_client->friends_get());
+ }
+ else
+ $friends = '';
+
+ if ($type == 'none' || $type == 'friends') {
+ $type = array(ADDON_EXTENSION, ADDON_THEME);
+ }
+
+ $this->Addon->bindFully();
+ if ($addons = $this->Addon->getAddonsByCategory(null, array(STATUS_PUBLIC), $type, $cat, $sort, $order, RESULTS_PER_PAGE, $page, $friends)) {
+ if (empty($friends)) {
+ // Get friends
+ $friends = implode(', ', $this->facebook->api_client->friends_get());
+ }
+
+ $count['total'] = $this->Addon->countAddonsInCategory(array(STATUS_PUBLIC), array(ADDON_EXTENSION, ADDON_THEME), $cat);
+ $count['extensions'] = $this->Addon->countAddonsInCategory(array(STATUS_PUBLIC), array(ADDON_EXTENSION), $cat);
+ $count['themes'] = $this->Addon->countAddonsInCategory(array(STATUS_PUBLIC), array(ADDON_THEME), $cat);
+ $count['friends'] = $this->Addon->countAddonsInCategory(array(STATUS_PUBLIC), array(ADDON_EXTENSION, ADDON_THEME), $cat, $friends);
+ $count['pages'] = ceil($count[$currentType]/ RESULTS_PER_PAGE);
+
+ foreach ($addons as $k => $addon) {
+ if (!empty($friends))
+ $addons[$k]['FacebookFavorite'] = $this->FacebookFavorite->findAll("FacebookFavorite.fb_user IN ({$friends}) AND FacebookFavorite.addon_id={$addon['Addon']['id']}");
+ $addons[$k]['previewCount'] = $this->Preview->findCount("Preview.addon_id='{$addon['Addon']['id']}'");
+ }
+ }
+ else {
+ $addons = array();
+ }
+
+ if ($type == ADDON_EXTENSION || (is_array($type) && in_array(ADDON_EXTENSION, $type))) {
+ // Extension tags
+ if ($extension_tags = $this->Tag->findAll(array('application_id' => APP_ID, 'addontype_id' => ADDON_EXTENSION))) {
+ foreach ($extension_tags as $extension_tag) {
+ $tags[$extension_tag['Tag']['id']] = (is_array($type) ? 'Extensions: ' : '').$extension_tag['Translation']['name']['string'];
+ }
+ }
+ }
+ if ($type == ADDON_THEME || (is_array($type) && in_array(ADDON_THEME, $type))) {
+ // Theme tags
+ if ($theme_tags = $this->Tag->findAll(array('application_id' => APP_ID, 'addontype_id' => ADDON_THEME))) {
+ foreach ($theme_tags as $theme_tag) {
+ $tags[$theme_tag['Tag']['id']] = (is_array($type) ? 'Themes: ' : '').$theme_tag['Translation']['name']['string'];
+ }
+ }
+ }
+
+ $tags[0] = ' Filter by Category';
+ asort($tags);
+ $this->set('tags', $tags);
+
+ $this->set('addons', $addons);
+ $this->set('count', $count);
+ $this->set('page', 'browse');
+ $this->render('browse', 'facebook');
+ }
+
+ /**
+ * Manage Favorites
+ * @param string $action what action to take with addon id $id
+ * @param int $id the addon_id to add/remove as favorite
+ */
+ function favorite($action, $id, $return_to = 'favorites') {
+ $this->Amo->clean($id);
+
+ $addon = $this->Addon->findById($id, array('name', 'summary'));
+
+ // Add a new favorite
+ if ($action == 'add') {
+ if ($this->FacebookFavorite->isFavorite($this->fbUser, $id)) {
+ $this->set('errorTitle', 'Could not add favorite');
+ $this->set('errorMessage', "<a href=\"".FB_URL."/view/{$id}\">{$addon[0]['name']}</a> is already on your favorites list.");
+ }
+ else {
+ $this->FacebookFavorite->addFavorite($this->fbUser, $id);
+ $this->isFavorite = true;
+
+ $this->set('successTitle', 'Favorite Added');
+ $this->set('successMessage', "<a href=\"".FB_URL."/view/{$id}\">{$addon[0]['name']}</a> has been successfully added to your favorite add-ons list and will now appear in your <a href=\"http://www.facebook.com/profile.php?id={$this->fbUser}\">profile</a>.");
+
+ $pCount = $this->Preview->findCount("addon_id = '{$id}'");
+
+ // Publish feed story
+ $this->_publishStory($id, $addon[0]['name'], $addon[0]['summary'], $pCount);
+
+ // Update profile FBML
+ $this->_updateProfileFBML();
+ }
+ }
+ // Remove a favorite
+ elseif ($action == 'remove') {
+ if (!$this->FacebookFavorite->isFavorite($this->fbUser, $id)) {
+ $this->set('errorTitle', 'Could not remove favorite');
+ $this->set('errorMessage', "<a href=\"".FB_URL."/view/{$id}\">{$addon[0]['name']}</a> is not on your favorites list.");
+ }
+ else {
+ $this->FacebookFavorite->removeFavorite($this->fbUser, $id);
+ $this->isFavorite = false;
+
+ $this->set('successTitle', 'Favorite Removed');
+ $this->set('successMessage', "<a href=\"".FB_URL."/view/{$id}\">{$addon[0]['name']}</a> has been successfully removed from your favorite add-ons list. (<a href=\"".FB_URL."/favorite/add/{$id}\">Undo?</a>)");
+
+ // Update profile FBML
+ $this->_updateProfileFBML();
+ }
+ }
+
+ if ($return_to == 'favorites') {
+ $this->favorites('mine');
+ }
+ elseif ($return_to = 'addon') {
+ $this->view($id);
+ }
+
+ return;
+ }
+
+ /**
+ * View Favorites
+ */
+ function favorites($action = 'mine', $id = 0, $view = 'all') {
+ $this->Amo->clean($id);
+
+ // If added is set, user imported add-ons to favorites
+ if (!empty($_GET['added'])) {
+ $this->Amo->clean($_GET['added']);
+ $added = explode(',', $_GET['added']);
+
+ $this->set('successTitle', 'Favorite'.(count($added) != 1 ? 's' : '').' Imported');
+
+ $addonNames = $this->Addon->findAll("Addon.id IN ({$_GET['added']})", array('Addon.id', 'Addon.name', 'Addon.summary'), null, null, null, -1);
+
+ // If there's only one imported favorite, show the normal feed story
+ if (count($added) == 1) {
+ $this->set('successMessage', "<a href=\"".FB_URL."/view/{$addonNames[0]['Addon']['id']}\">{$addonNames[0]['Translation']['name']['string']}</a> has been successfully added to your favorite add-ons list and will now appear in your <a href=\"http://www.facebook.com/profile.php?id={$this->fbUser}\">profile</a>.");
+
+ // Publish feed story
+ $pCount = $this->Preview->findCount("addon_id = '{$addonNames[0]['Addon']['id']}'");
+ $this->_publishStory($addonNames[0]['Addon']['id'], $addonNames[0]['Translation']['name']['string'], $addonNames[0]['Translation']['summary']['string'], $pCount);
+ }
+ // If there's more than one imported favorite, show a combined story
+ else {
+ $this->set('successMessage', count($added)." add-ons have been successfully added to your favorite add-ons list and will now appear in your <a href=\"http://www.facebook.com/profile.php?id={$this->fbUser}\">profile</a>.");
+
+ // Publish feed story
+ $this->_publishImportStory($addonNames);
+ }
+
+ // Update profile FBML
+ $this->_updateProfileFBML();
+ }
+
+ $page = !empty($this->namedArgs['page']) ? $this->namedArgs['page'] : 1;
+
+ $fbFriends = implode(', ', $this->facebook->api_client->friends_get());
+
+ if ($action == 'addon') {
+ $addon = $this->Addon->findById($id);
+ $this->set('addon', $addon);
+
+ if ($view == 'all') {
+ $all = array();
+ if ($all_q = $this->FacebookFavorite->findAllByAddon_id($id, null, 'RAND()')) {
+ foreach ($all_q as $all_r) {
+ $all[] = $all_r['FacebookFavorite']['fb_user'];
+ }
+ }
+ $this->set('all', $all);
+ }
+
+ $friends = array();
+ if ($friends_q = $this->FacebookFavorite->findAll("addon_id='{$id}' AND fb_user IN ({$fbFriends})", null, 'RAND()')) {
+ foreach ($friends_q as $friends_r) {
+ $friends[] = $friends_r['FacebookFavorite']['fb_user'];
+ }
+ }
+ $this->set('friends', $friends);
+
+ }
+ elseif ($action == 'user') {
+ if ($addons = $this->FacebookFavorite->getDetailedFavoriteList($id, $page)) {
+ $this->set('addons', $addons);
+ }
+ $total = $this->FacebookFavorite->countFavorites($id);
+ $this->set('count', array('total' => $total, 'pages' => ceil($total / RESULTS_PER_PAGE)));
+ $this->set('user_id', $id);
+ }
+ elseif ($action == 'mine') {
+ if ($addons = $this->FacebookFavorite->getFavoriteList($this->fbUser)) {
+ $this->set('addons', $addons);
+ }
+ }
+ elseif ($action == 'friends') {
+ if ($addons = $this->FacebookFavorite->getFriendFavorites($fbFriends, $page)) {
+ $this->set('addons', $addons);
+ }
+ $total = $this->FacebookFavorite->countFriendFavorites($fbFriends);
+ $this->set('count', array('total' => $total, 'pages' => ceil($total / RESULTS_PER_PAGE)));
+ }
+
+ $this->set('current', array('page' => $page));
+ $this->set('action', $action);
+ $this->set('view', $view);
+ $this->set('page', 'favorites');
+ $this->render('favorites', 'facebook');
+ }
+
+ /**
+ * Display outage page
+ */
+ function outage() {
+ $this->render('outage', 'ajax');
+ }
+
+ /**
+ * Invite friends to add the app
+ */
+ function invite() {
+ $exclude = array();
+
+ // Get friends who have added application to exclude
+ $friends_added = $this->facebook->api_client->fql_query("SELECT uid FROM user WHERE has_added_app=1 and uid IN (SELECT uid2 FROM friend WHERE uid1 = {$this->fbUser})");
+ if (!empty($friends_added)) {
+ foreach ($friends_added as $friend) {
+ $exclude[] = $friend['uid'];
+ }
+ $exclude = implode(',', $exclude);
+ }
+
+ $this->publish('exclude', $exclude);
+
+ $this->render('invite', 'facebook');
+ }
+
+ /**
+ * Share a specific add-on with a specific friend
+ */
+ function share($action = 'form') {
+ if ($action == 'submit') {
+ if (!empty($_POST['addon_id'])) {
+ $addon_id = $_POST['addon_id'];
+ $this->Amo->clean($addon_id);
+
+ $addon = $this->Addon->findById($addon_id);
+ $addon['previewCount'] = $this->Preview->findCount("Preview.addon_id='{$addon['Addon']['id']}'");
+ $this->set('addon', $addon);
+ }
+ else
+ $this->set('error', 'No add-on was selected.');
+ }
+ elseif ($action == 'form') {
+ if ($favorites = $this->FacebookFavorite->getFavoriteList($this->fbUser)) {
+ $this->set('favorites', $favorites);
+ }
+ }
+
+ $this->set('action', $action);
+ $this->render('share', 'ajax');
+ }
+
+ /**
+ * FAQ
+ */
+ function faq() {
+ $this->set('page', 'faq');
+ $this->render('faq', 'facebook');
+ }
+
+ /**
+ * Update Notes
+ */
+ function updatenotes() {
+ $this->set('page', 'updatenotes');
+ $this->render('updatenotes', 'facebook');
+ }
+
+ /**
+ * Wallpaper
+ */
+ function wallpaper() {
+ $this->set('page', 'wallpaper');
+ $this->render('wallpaper', 'facebook');
+ }
+
+ /* Utility Functions */
+
+ /**
+ * Update FBML for profile box
+ */
+ function _updateProfileFBML() {
+ $fbml = '';
+
+ if ($addons = $this->FacebookFavorite->getFavoriteList($this->fbUser, 'RAND()')) {
+ $fbml = '<fb:subtitle seeallurl="'.FB_URL.'/favorites/user/'.$this->fbUser.'?ref=pbsa">';
+ $fbml .= '<fb:wide>Displaying '.(count($addons) >= 5 ? '5' : count($addons)).'</fb:wide>';
+ $fbml .= '<fb:narrow>'.(count($addons) >= 3 ? '3' : count($addons)).'</fb:narrow>';
+ $fbml .= ' of <a href="'.FB_URL.'/favorites/user/'.$this->fbUser.'?ref=pbc">'.count($addons).' add-on'.(count($addons) != 1 ? 's' : '').'</a>.</fb:subtitle>';
+ $fbml .= '<table><tr>';
+ foreach ($addons as $k => $addon) {
+ if ($k > 4) continue;
+ if ($k == 3)
+ $fbml .= '<fb:wide>';
+ $fbml .= '<td width="60" style="text-align: center;"><a href="'.FB_URL.'/view/'.$addon['addons']['id'].'?ref=pba">';
+ $fbml .= '<img src="'.FB_IMAGE_SITE.$this->Image->getAddonIconURL($addon['addons']['id']).'" border=0></a>';
+ $fbml .= '<br/><a href="'.FB_URL.'/view/'.$addon['addons']['id'].'?ref=pba">'.$addon['translations']['name'].'</a></td>';
+ if ($k == 4)
+ $fbml .= '</fb:wide>';
+ }
+ $fbml .= '</tr></table>';
+ }
+
+ try {
+ $this->facebook->api_client->profile_setFBML($fbml);
+ } catch(Exception $e) {
+ error_log("_updateProfileFBML [{$this->fbUser}]: ".$e->getMessage());
+ }
+ }
+
+ /**
+ * Publish newsfeed story
+ */
+ function _publishStory($addon_id, $addon_name, $addon_summary, $pCount) {
+ try {
+ //$feed_title = 'rocked <fb:pronoun uid="'.$this->fbUser.'" useyou="false" possessive="true"/> Firefox with <a href="'.FB_URL.'/view/'.$addon_id.'?ref=nf">'.$addon_name.'</a>.';
+ $feed_body = $this->_trimSummary($addon_summary, 200);
+ if ($pCount > 0)
+ $preview = FB_IMAGE_SITE.'/images/addon_preview/'.$addon_id.'/1';
+ else
+ $preview = FB_IMAGE_SITE.'/img/facebook/no-preview.png';
+ $preview_link = FB_URL.'/view/'.$addon_id.'?ref=nfi';
+
+ $title_template = '{actor} rocked <fb:if-multiple-actors>their<fb:else><fb:pronoun uid="{uid}" possessive="true" useyou="false" /></fb:else></fb:if-multiple-actors> Firefox with <a href="{addon_url}">{addon_name}</a>.';
+ $title_data = '{"addon_name": "'.$addon_name.'", "addon_url": "'.FB_URL.'/view/'.$addon_id.'?ref=nf", "uid": "'.$this->fbUser.'"}';
+ $body_template = '{description}';
+ $body_data = '{"description": "'.$feed_body.'"}';
+
+ //$this->facebook->api_client->feed_publishActionOfUser($feed_title, $feed_body, $preview, $preview_link);
+ //$this->facebook->api_client->feed_publishStoryToUser($feed_title, $feed_body, $preview, $preview_link);
+ $this->facebook->api_client->feed_publishTemplatizedAction(
+ $this->fbUser, $title_template, $title_data,
+ $body_template, $body_data, null,
+ $preview, $preview_link);
+ } catch(Exception $e) {
+ error_log("_publishStory [{$this->fbUser}]: ".$e->getMessage());
+ }
+ }
+
+ /**
+ * Publish import story
+ */
+ function _publishImportStory($addon_names) {
+ try {
+ //$feed_title = 'rocked <fb:pronoun uid="'.$this->fbUser.'" useyou="false" possessive="true"/> Firefox with <a href="'.FB_URL.'/favorites/user/'.$this->fbUser.'?ref=nf">'.count($addon_names).' add-ons</a>.';
+ //$feed_body = '<fb:name uid="'.$this->fbUser.'" firstnameonly="true" linked="false" shownetwork="false" useyou="false" /> now recommends ';
+ $addons = array();
+
+ foreach ($addon_names as $addon_name) {
+ $addons[] = '<a href="'.FB_URL.'/view/'.$addon_name['Addon']['id'].'">'.$addon_name['Translation']['name']['string'].'</a>';
+ }
+ //$feed_body .= implode(', ', $addons);
+
+ $title_template = '{actor} rocked <fb:if-multiple-actors>their<fb:else><fb:pronoun uid="{uid}" possessive="true" useyou="false" /></fb:else></fb:if-multiple-actors> Firefox with <a href="{url}">{count} add-ons</a>.';
+ $title_data = '{"count": "'.count($addon_names).'", "url": "'.FB_URL.'/favorites/user/'.$this->fbUser.'?ref=nf", "uid": "'.$this->fbUser.'"}';
+ $body_template = '{actor} now recommends {addons}';
+ $body_data = '{"addons": "'.addslashes(implode(', ', $addons)).'"}';
+
+ //$this->facebook->api_client->feed_publishActionOfUser($feed_title, $feed_body);
+ //$this->facebook->api_client->feed_publishStoryToUser($feed_title, $feed_body);
+ $this->facebook->api_client->feed_publishTemplatizedAction(
+ $this->fbUser, $title_template, $title_data,
+ $body_template, $body_data, '');
+ } catch(Exception $e) {
+ error_log("_publishImportStory [{$this->fbUser}]: ".$e->getMessage());
+ }
+ }
+
+ /**
+ * Check if user is in the Mozilla or Facebook network
+ */
+ function _inMozillaOrFacebookNetworks() {
+ $fql = $this->facebook->api_client->fql_query("SELECT affiliations, first_name FROM user WHERE uid='{$this->fbUser}'");
+ if (!empty($fql[0]['affiliations'])) {
+ foreach ($fql[0]['affiliations'] as $network) {
+ if ($network['name'] == 'Mozilla' || $network['name'] == 'Facebook') {
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Checks if a user is in the admin group
+ */
+ function _inAdminGroup() {
+ $members = $this->facebook->api_client->groups_getMembers(2651677376);
+
+ if (is_array($members) && in_array($this->fbUser, $members['members'])) {
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * Checks if a user is using a supported browser
+ */
+ function _usingSupportedBrowser() {
+ $allowedBrowser = false;
+ $allowedUserAgents = array('Firefox', 'Minefield', 'BonEcho', 'GranParadiso', 'Shiretoko');
+ foreach ($allowedUserAgents as $allowedUserAgent) {
+ if (strpos($_SERVER['HTTP_USER_AGENT'], $allowedUserAgent) !== false) {
+ $allowedBrowser = true;
+ break;
+ }
+ }
+
+ $disallowedUserAgents = array('Flock');
+ foreach ($disallowedUserAgents as $disallowedUserAgent) {
+ if (strpos($_SERVER['HTTP_USER_AGENT'], $disallowedUserAgent) !== false) {
+ $allowedBrowser = false;
+ break;
+ }
+ }
+
+ return $allowedBrowser;
+ }
+
+ /**
+ * Trims a string to a specified number of characters and attempts to break
+ * without cutting off words.
+ * @param string $summary
+ * @param int $maxLength
+ */
+ function _trimSummary($summary, $maxLength = 250) {
+ // Only do work if we need to
+ if (strlen($summary) > $maxLength) {
+ $summary = substr($summary, 0, $maxLength);
+
+ // If we broke on punctuation or a space, we're done
+ $allowedBreaks = array('.', ' ', '!', '?', ')');
+ if (!in_array($summary[$maxLength - 1], $allowedBreaks)) {
+ // If we didn't, we need to break on the last space and add an elipsis
+ $lastSpace = strrpos($summary, ' ');
+ $summary = substr($summary, 0, $lastSpace).'...';
+ }
+ }
+
+ return $summary;
+ }
+
+ /**
+ * Admin tools
+ */
+ function admin($action = '') {
+ if (!$this->_inAdminGroup()) {
+ die('Access denied.');
+ }
+
+ if ($action == 'flushCache') {
+ $urls = array(
+ SITE_URL.'/css/facebook.php',
+ SITE_URL.'/css/facebook.php?'.date('Ymd'),
+ SITE_URL.'/facebook/outage'
+ );
+ try {
+ foreach ($urls as $url) {
+ $this->facebook->api_client->fbml_refreshRefUrl($url);
+ }
+ } catch(Exception $e) {
+ die("Error: {$e}");
+ }
+ $this->set('urls', $urls);
+ }
+ elseif ($action == 'activeUsers') {
+
+ $this->set('activeUsers', array(
+ 'last_1d' => $this->FacebookUser->getUsersInInterval('lastactivity', '1 DAY'),
+ 'last_1h' => $this->FacebookUser->getUsersInInterval('lastactivity', '1 HOUR'),
+ 'last_10m' => $this->FacebookUser->getUsersInInterval('lastactivity', '10 MINUTE'),
+ 'last_5m' => $this->FacebookUser->getUsersInInterval('lastactivity', '5 MINUTE'),
+ 'last_1m' => $this->FacebookUser->getUsersInInterval('lastactivity', '1 MINUTE'),
+ 'last_30s' => $this->FacebookUser->getUsersInInterval('lastactivity', '30 SECOND'),
+ 'last_1s' => $this->FacebookUser->getUsersInInterval('lastactivity', '1 SECOND'),
+ 'add_1d' => $this->FacebookUser->getUsersInInterval('added', '1 DAY'),
+ 'remove_1d' => $this->FacebookUser->getUsersInInterval('removed', '1 DAY'),
+ 'total' => $this->FacebookUser->getUsersTotal(),
+ 'ever' => $this->FacebookUser->getUsersEver()
+ ));
+ }
+
+ $this->set('action', $action);
+
+ $this->render('admin', 'facebook');
+ }
+}
+
+?>
diff --git a/site/app/controllers/facebookinstall_controller.php b/site/app/controllers/facebookinstall_controller.php
new file mode 100644
index 0000000..d74f913
--- /dev/null
+++ b/site/app/controllers/facebookinstall_controller.php
@@ -0,0 +1,126 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Justin Scott <fligtar@mozilla.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+class FacebookinstallController extends AppController
+{
+ var $name = 'Facebookinstall';
+ var $uses = array('Addon', 'Application', 'FacebookDetected', 'FacebookFavorite', 'FacebookSession', 'File', 'Version');
+ var $components = array('Amo', 'Image');
+ var $exceptionCSRF = array('/facebookinstall/import');
+ var $securityLevel = 'low';
+
+ /**
+ * Initialize API and permission checks
+ */
+ function beforeFilter() {
+ // Disable ACLs because this controller is entirely public.
+ $this->SimpleAuth->enabled = false;
+ $this->SimpleAcl->enabled = false;
+
+ $this->Amo->startup($this);
+ $this->viewPath = 'facebook';
+ }
+
+ /**
+ * Install
+ */
+ function install($file_id) {
+ $this->Amo->clean($file_id);
+
+ if (!$file = $this->File->findById($file_id)) {
+ $this->redirect(FB_URL);
+ return;
+ }
+
+ $addon = $this->Addon->findById($file['Version']['addon_id']);
+
+ $this->set('file', $file);
+ $this->set('addon', $addon);
+
+ $this->render('install', 'ajax');
+ }
+
+ /**
+ * Detect automatically installed add-ons to add as favorites
+ */
+ function import($fbUserSession, $action = '') {
+ $this->Amo->clean($fbUser);
+ if (!$fbUser = $this->FacebookSession->retrieveUser($fbUserSession)) {
+ $this->redirect(FB_URL.'/import');
+ return;
+ }
+
+ // If we are viewing detected results, delete the cookies and display results
+ if ($action == 'results') {
+ $this->set('detected', $this->FacebookDetected->getDetectedAddons($fbUser));
+ setcookie('AMOfbUser', false, time() - 3600, '/', '.addons.mozilla.org');
+ setcookie('AMOfbSequence', false, time() - 3600, '/', '.addons.mozilla.org');
+
+ }
+ // If the form has been submitted, save the new favorite add-ons
+ elseif ($action == 'favorites') {
+ $this->Amo->clean($_POST['addons']);
+ if (!empty($_POST['addons'])) {
+ foreach ($_POST['addons'] as $addon_id => $val) {
+ if (!$this->FacebookFavorite->isFavorite($fbUser, $addon_id, true)) {
+ $this->FacebookFavorite->addFavorite($fbUser, $addon_id, true);
+ }
+ }
+ }
+
+ $this->redirect(FB_URL.'/favorites/?added='.implode(',', array_keys($_POST['addons'])));
+ return;
+ }
+ // Default to setting the cookies before detection
+ else {
+ // Set cookie with user's facebook id
+ setcookie('AMOfbUser', $fbUser, 0, '/', '.addons.mozilla.org');
+
+ // Set cookie with unique detection sequence
+ setcookie('AMOfbSequence', time(), 0, '/', '.addons.mozilla.org');
+ }
+
+ $this->set('action', $action);
+ $this->set('fbUser', $fbUser);
+ $this->set('fbUserSession', $fbUserSession);
+ $this->render('import', 'ajax');
+ }
+
+}
+
+?>
diff --git a/site/app/controllers/favorites_controller.php b/site/app/controllers/favorites_controller.php
new file mode 100644
index 0000000..ab7b44c
--- /dev/null
+++ b/site/app/controllers/favorites_controller.php
@@ -0,0 +1,55 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * Justin Scott <fligtar@gmail.com>.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+class FavoritesController extends AppController
+{
+ var $name = 'Favorites';
+ var $components = array('Amo');
+
+ var $securityLevel = 'low';
+
+ /**
+ * Require login for all actions
+ */
+ function beforeFilter() {
+ //beforeFilter() is apparently called before components are initialized. Cake++
+ $this->Amo->startup($this);
+
+ $this->Amo->checkLoggedIn();
+ }
+}
+
+?>
diff --git a/site/app/controllers/features_controller.php b/site/app/controllers/features_controller.php
new file mode 100644
index 0000000..ed869b0
--- /dev/null
+++ b/site/app/controllers/features_controller.php
@@ -0,0 +1,59 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Andrei Hajdukewycz <sancus@off.net> (Original Author)
+ * Wil Clouser <clouserw@mozilla.com>
+ * Justin Scott <fligtar@gmail.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+class FeaturesController extends AppController
+{
+ var $name = 'Features';
+ var $components = array('Amo');
+
+ var $securityLevel = 'low';
+
+ /**
+ * Require login for all actions
+ */
+ function beforeFilter() {
+ //beforeFilter() is apparently called before components are initialized. Cake++
+ $this->Amo->startup($this);
+
+ $this->Amo->checkLoggedIn();
+ }
+}
+
+?>
diff --git a/site/app/controllers/files_controller.php b/site/app/controllers/files_controller.php
new file mode 100644
index 0000000..da78b3c
--- /dev/null
+++ b/site/app/controllers/files_controller.php
@@ -0,0 +1,446 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Andrei Hajdukewycz <sancus@off.net> (Original Author)
+ * Wil Clouser <clouserw@mozilla.com>
+ * Justin Scott <fligtar@gmail.com>
+ * Frederic Wenzel <fwenzel@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+require_once('Archive/Zip.php');
+
+class FilesController extends AppController
+{
+ var $name = 'Files';
+ var $uses = array('Version', 'Addon', 'File');
+ var $components = array('Amo', 'Filebrowser', 'Diff');
+ var $helpers = array('Html', 'Javascript', 'Ajax', 'Listing');
+
+ var $securityLevel = 'low';
+
+ /**
+ * Require login for all actions
+ */
+ function beforeFilter() {
+ // Disable ACLs because this controller is entirely public.
+ $this->SimpleAuth->enabled = false;
+ $this->SimpleAcl->enabled = false;
+
+ //beforeFilter() is apparently called before components are initialized. Cake++
+ $this->Amo->startup($this);
+
+ $this->Amo->checkLoggedIn();
+ }
+
+ /**
+ * Browse the contents of a package
+ * @param int $id the file
+ */
+ function browse($file_id, $review = 0) {
+ $this->Amo->clean($file_id);
+
+ $this->File->id = $file_id;
+ if (!$file = $this->File->read()) {
+ $this->flash(_('error_file_notfound'), '/');
+ return;
+ }
+ $this->Addon->id = $file['Version']['addon_id'];
+ $addon = $this->Addon->read();
+
+ //Only display add-on if opted in or if the user is a reviewer
+ if ($addon['Addon']['viewsource'] != 1 && !$this->SimpleAcl->actionAllowed('Editors', '*', $this->Session->read('User'))) {
+ $this->flash(_('error_addon_notviewable'), '/addon/'.$this->Addon->id);
+ return;
+ }
+
+ $addontype = $addon['Addon']['addontype_id'];
+ $startfile = 'install.rdf';
+ $path = REPO_PATH.'/'.$this->Addon->id.'/'.$file['File']['filename'];
+
+ if (!file_exists($path)) {
+ if ($review == 1) {
+ $this->flash(_('error_file_notfound'), '/reviewers/review/'.$this->Addon->id);
+ }
+ else {
+ $this->flash(_('error_file_notfound'), '/addon/'.$this->Addon->id);
+ }
+ return;
+ }
+
+ //If a specific file is requested, show it
+ if (!empty($_GET['view'])) {
+ $this->_view($path, $_GET['view'], $addontype);
+ return;
+ }
+
+ $files = array();
+
+ if ($addontype === ADDON_SEARCH) {
+ $startfile = $file['File']['filename'];
+ $this->Filebrowser->buildContentsArray($startfile, false, false, $files);
+ } else {
+ $zip = new Archive_Zip($path);
+ $contents = $zip->listContent();
+
+ foreach ($contents as $content) {
+ $isJar = false;
+
+ if (substr($content['filename'], strrpos($content['filename'], '.')) == '.jar') {
+ $content['folder'] = 1;
+ $isJar = true;
+ }
+
+ $this->Filebrowser->buildContentsArray($content['filename'], $content['folder'], false, $files);
+
+ if ($isJar == true) {
+ $filename = substr($content['filename'], strrpos($content['filename'], '/'));
+ $jarfile = $zip->extract(array('extract_as_string' => true, 'by_name' => array($content['filename'])));
+
+ //write a .jar file with the .jar contents to extract in a new Archive_Zip
+ //I spent a long time trying to figure out an easier way, but no such luck
+ $jarcontents = $this->Filebrowser->getJarContents(REPO_PATH.'/temp'.$filename, $jarfile[0]['content']);
+
+ foreach ($jarcontents as $jarcontent) {
+ $this->Filebrowser->buildContentsArray($content['filename'].'/'.$jarcontent['filename'], $jarcontent['folder'], false, $files);
+ }
+
+ }
+ }
+ }
+
+ $this->publish('id', $file_id);
+ $this->publish('files', $files);
+ $this->publish('version', $file['Version']['id']);
+ $this->publish('addon', $this->Addon->id);
+ $this->publish('addonname', $addon['Translation']['name']['string']);
+ $this->publish('review', $review);
+ $this->publish('addontype', $addontype);
+ $this->publish('startfile', $startfile);
+ $this->render('browse', 'ajax');
+ }
+
+ /**
+ * View a specific file of the package
+ * @param string $path the package
+ * @param string $file the file
+ */
+ function _view($path, $file, $addontype) {
+ $file = html_entity_decode(urldecode($file), ENT_QUOTES, 'UTF-8');
+ $contents = $this->_get_contents($path, $file, $addontype);
+
+ if (is_bool($contents) && $contents == false) {
+ $this->flash(_('error_file_notfound'), '/');
+ return;
+ }
+ $this->publish('filename', $file);
+ $this->publish('contents', $contents);
+ $this->render('view', 'ajax');
+ }
+
+ function diff($file_id) {
+ $this->Amo->clean($file_id);
+
+ $this->File->id = $file_id;
+ if (!$file = $this->File->read()) {
+ $this->flash(_('error_file_notfound'), '/');
+ return;
+ }
+
+ $sandbox_file = $file;
+ $prev = $this->Version->getVersionIdsByAddonId($file['Version']['addon_id'],
+ array(STATUS_PUBLIC));
+
+ if (count($prev) == 0) {
+ $this->flash(_('error_file_notfound'), '/');
+ return;
+ }
+ $this->Version->id = $prev[0]['Version']['id'];
+ $public_file = $this->Version->read();
+
+ $this->Addon->id = $file['Version']['addon_id'];
+ $addon = $this->Addon->read();
+
+ //Only display add-on if opted in or if the user is a reviewer
+ if ($addon['Addon']['viewsource'] != 1 && !$this->SimpleAcl->actionAllowed('Editors', '*', $this->Session->read('User'))) {
+ $this->flash(_('error_addon_notviewable'), '/addon/'.$this->Addon->id);
+ return;
+ }
+
+ $addontype = $addon['Addon']['addontype_id'];
+ $path = REPO_PATH.'/'.$this->Addon->id.'/'.$file['File']['filename'];
+
+ if (!file_exists($path)) {
+ $this->flash(_('error_file_notfound'), '/reviewers/review/'.$this->Addon->id);
+ return;
+ }
+
+ if (!empty($_GET['compare'])) {
+ $public_path = REPO_PATH.'/'.$this->Addon->id.'/'.$public_file['File'][0]['filename'];
+ $sandbox_path = REPO_PATH.'/'.$this->Addon->id.'/'.$sandbox_file['File']['filename'];
+ $this->_compare($sandbox_path, $public_path, html_entity_decode($_GET['compare'], ENT_QUOTES, 'UTF-8'), $addontype);
+
+ return;
+ }
+
+ $zip = new Archive_Zip($path);
+ $zip_public = new Archive_Zip(REPO_PATH.'/'.$this->Addon->id.'/'.$public_file['File'][0]['filename']);
+ $contents = $zip->extract(array('extract_as_string' => true));
+ $contents_public = $zip_public->extract(array('extract_as_string' => true));
+
+ $files = array();
+ foreach ($contents as $content) {
+ $isJar = false;
+ $changed = false;
+
+ /* Checks if this file exists in the recent public version */
+ $i = $this->Filebrowser->getFilenameIndex($contents_public, $content['filename']);
+
+ if (substr($content['filename'], strrpos($content['filename'], '.')) == '.jar') {
+ $content['folder'] = 1;
+ $isJar = true;
+ } else if ($content['folder'] == false) {
+
+ if ($i != -1) {
+ $sha1_public = sha1($contents_public[$i]['content']);
+ $sha1 = sha1($content['content']);
+ $changed = ($sha1_public != $sha1);
+ } else {
+ $changed = true;
+ }
+ }
+
+ $this->Filebrowser->buildContentsArray($content['filename'], $content['folder'], $changed, $files);
+
+ if ($isJar == true) {
+ $changed = false;
+ $filename = substr($content['filename'], strrpos($content['filename'], '/'));
+
+ //write a .jar file with the .jar contents to extract in a new Archive_Zip
+ //I spent a long time trying to figure out an easier way, but no such luck
+ $jarcontents = $this->Filebrowser->getJarContents(REPO_PATH.'/temp'.$filename, $content['content']);
+ $jarcontents_public = $this->Filebrowser->getJarContents(REPO_PATH.'/temp'.$filename . '-public', $contents_public[$i]['content']);
+
+ foreach ($jarcontents as $jarcontent) {
+ $changed = false;
+ $j = $this->Filebrowser->getFilenameIndex($jarcontents_public, $jarcontent['filename']);
+
+ if ($jarcontent['folder'] == false) {
+ if ($j != -1) {
+ $sha1_public = sha1($jarcontents_public[$j]['content']);
+ $sha1 = sha1($jarcontent['content']);
+ $changed = ($sha1_public != $sha1);
+ } else {
+ $changed = true;
+ }
+ }
+
+ $this->Filebrowser->buildContentsArray($content['filename'].'/'.$jarcontent['filename'], $jarcontent['folder'], $changed, $files);
+ }
+
+ }
+
+ if ($isJar || $content['filename'][ strlen($content['filename']) - 1 ] == '/')
+ $content['content'] = '';
+ }
+
+ $this->publish('id', $file_id);
+ $this->publish('contents', $contents);
+ $this->publish('files', $files);
+ $this->publish('version', $file['Version']['id']);
+ $this->publish('addon', $this->Addon->id);
+ $this->publish('review', 1);
+ $this->publish('is_diff', true);
+ $this->publish('startfile', 'install.rdf');
+ $this->render('browse', 'ajax');
+ }
+
+ function _compare($sandbox_path, $public_path, $file, $addontype) {
+ $sandbox_contents = $this->_get_contents($sandbox_path, $file, $addontype);
+ $public_contents = $this->_get_contents($public_path, $file, $addontype);
+ $diff = "";
+
+ if ($sandbox_contents === false) {
+ $this->flash('Something went horribly wrong! Please file a bug mentioning the addon you were trying to diff', "/");
+ return;
+ }
+
+ if (!defined("DIFF_PATH")) {
+ $diff = xdiff_string_diff($public_contents, $sandbox_contents);
+ $diff = split("[\n]", $diff);
+ }
+ else {
+ $public_file = tempnam(REPO_PATH.'/temp/', 'pdiff-');
+ $sandbox_file = tempnam(REPO_PATH.'/temp/', 'sdiff-');
+
+ $handler = fopen($public_file, "w");
+ fwrite($handler, $public_contents);
+ fclose($handler);
+
+ $handler = fopen($sandbox_file, "w");
+ fwrite($handler, $sandbox_contents);
+ fclose($handler);
+
+ $status = exec(DIFF_PATH . ' -u --ignore-tab-expansion --ignore-blank-lines ' .
+ ' --ignore-space-change '.$public_file. ' ' . $sandbox_file, $diff);
+
+ unlink($public_file);
+ unlink($sandbox_file);
+ }
+
+ // santizes any html/xul that is present
+ $contents = htmlspecialchars($sandbox_contents);
+ $contents = split("[\n]", $contents);
+
+ $total_lines = count($contents);
+ for ($i = 0; $i < $total_lines; $i++) {
+ $l = new Line();
+ $l->text = $contents[$i];
+ $contents[$i] = $l;
+ }
+
+ // Parses the changes
+ $changes = array();
+ for ($i = 0; $i < count($diff); $i++) {
+ if (strncmp($diff[$i], "@@", 2) == 0) {
+ $section = array();
+ array_push($section, $diff[$i]);
+ for ($j = $i+1; $j < count($diff); $j++) {
+ if (strncmp($diff[$j], "@@", 2) == 0) {
+ break;
+ }
+ else {
+ array_push($section, htmlspecialchars($diff[$j]));
+ }
+ }
+ array_push($changes, $section);
+ }
+ }
+
+ foreach ($changes as $item) {
+ $tmp = $item;
+ $change = $this->Diff->parse_diff($tmp, '+');
+ $this->Diff->apply_change($contents, $change);
+ }
+
+ // When we apply new lines, it skews the array index which is used to
+ // track line numbers. So we have to keep track of how many lines we
+ // added
+ $offset = 0;
+ foreach ($changes as $item) {
+ $tmp = $item;
+ $change = $this->Diff->parse_diff($tmp, '-');
+ $this->Diff->apply_change($contents, $change, $offset);
+ }
+
+ $linenum = 1;
+ $shift = " ";
+ $output = array();
+
+ foreach ($contents as $line) {
+ $linen = "$linenum";
+ $space = " ";
+
+ // Do not write line numbers for code removed
+ if ($line->changed && $line->symbol == '-') {
+ $linen = str_repeat(' ', strlen($linen));
+ }
+ else {
+ $linenum++;
+ }
+
+ // code that hasn't been touched needs the extra space. This
+ // just fixes alignment issues
+ if ($line->changed) {
+ $space = "";
+ }
+
+ // Remove excess whitespace. We'll put in our own newline
+ $line->text = rtrim($line->text);
+
+ if ($linen == 10 || $linen == 100 || $linen === 1000) {
+ // alignment fix
+ $shift = substr($shift, 0, -1);
+ }
+ array_push($output, "<b>$linen</b> $shift$space$line->text\n");
+ }
+
+ $this->publish('contents', $output, false);
+ $this->publish('filename', $file);
+ $this->render('view', 'ajax');
+ }
+
+ /* $path must refer to a file that exists */
+ function _get_contents($path, $file, $addontype) {
+ $this->Amo->clean($path);
+
+ // Search engine. Safe to output directly
+ if ($addontype === ADDON_SEARCH) {
+ // We have to make sure that the file in $path and $file match.
+ // Otherwise we reproduce bug 461253
+ if (substr($path, -(strlen($file))) == $file) {
+ return file_get_contents($path);
+ } else {
+ return false;
+ }
+ }
+
+ if (preg_match("/^(.+\.jar)\/(.+)$/is", $file, $matches)) {
+ $file = $matches[1];
+ $jarfile = $matches[2];
+ $jarfilename = substr($file, strrpos($file, '/'));
+ }
+ $zip = new Archive_Zip($path);
+ $extraction = $zip->extract(array('extract_as_string' => true, 'by_name' => array($file)));
+
+ if (is_array($extraction) && count($extraction) > 0) {
+ $contents = (string)$extraction[0]['content'];
+ }
+ else {
+ return false;
+ }
+
+ if (!empty($jarfile)) {
+ $jarcontents = $this->Filebrowser->getJarContents(REPO_PATH.'/temp'.$jarfilename, $contents, $jarfile);
+ if (is_array($jarcontents) && count($jarcontents) > 0) {
+ $contents = (string)$jarcontents[0]['content'];
+ }
+ else {
+ $contents = false;
+ }
+ }
+
+ return $contents;
+ }
+}
+?>
diff --git a/site/app/controllers/groups_controller.php b/site/app/controllers/groups_controller.php
new file mode 100644
index 0000000..e3917d1
--- /dev/null
+++ b/site/app/controllers/groups_controller.php
@@ -0,0 +1,122 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Mike Morgan <morgamic@mozilla.com> (Original Developer)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+class GroupsController extends AppController {
+
+ var $name = 'Groups';
+ var $components = array('Session');
+ var $helpers = array('Html', 'Form');
+ var $layout = 'mozilla';
+
+ /**
+ * Require login for all actions
+ */
+ function beforeFilter() {
+
+ //beforeFilter() is apparently called before components are initialized. Cake++
+ $this->Amo->startup($this);
+ $this->Amo->checkLoggedIn();
+
+ $this->breadcrumbs = array('Groups' => '/groups');
+ $this->set('breadcrumbs', $this->breadcrumbs);
+
+ global $native_languages;
+ $this->set('nativeLanguages', $native_languages);
+
+ $this->set('cssAdd', array('forms'));
+ }
+
+ function index() {
+ $this->pageTitle = _('admin_group_pagetitle').' :: '.sprintf(_('addons_home_pagetitle'), APP_PRETTYNAME);
+ $this->Group->recursive = 0;
+ $this->set('groups', $this->Group->findAll());
+ }
+
+ function add() {
+ $this->pageTitle = _('admin_group_add_pagetitle').' :: '.sprintf(_('addons_home_pagetitle'), APP_PRETTYNAME);
+ if(empty($this->data)) {
+ $this->render();
+ } else {
+ $this->cleanUpFields();
+ if($this->Group->save($this->data)) {
+ $this->Session->setFlash(_('admin_group_saved'));
+ $this->redirect('/groups/index');
+ } else {
+ $this->Session->setFlash(_('error_formerrors'));
+ }
+ }
+ }
+
+ /**
+ * @param int $id
+ */
+ function edit($id = null) {
+ $this->pageTitle = _('admin_group_edit_pagetitle').' :: '.sprintf(_('addons_home_pagetitle'), APP_PRETTYNAME);
+ if(empty($this->data)) {
+ if(!$id) {
+ $this->Session->setFlash(_('admin_group_error_invalid_id'));
+ $this->redirect('/groups/index');
+ }
+ $this->data = $this->Group->read(null, $id);
+ } else {
+ $this->cleanUpFields();
+ if($this->Group->save($this->data)) {
+ $this->Session->setFlash(_('admin_group_saved'));
+ $this->redirect('/groups/index');
+ } else {
+ $this->Session->setFlash(_('error_formerrors'));
+ }
+ }
+ }
+
+ /**
+ * @param int $id
+ */
+ function delete($id = null) {
+ $this->pageTitle = _('admin_group_delete_pagetitle').' :: '.sprintf(_('addons_home_pagetitle'), APP_PRETTYNAME);
+ if(!$id) {
+ $this->Session->setFlash(_('admin_group_error_invalid_id'));
+ $this->redirect('/groups/index');
+ }
+ if($this->Group->del($id)) {
+ $this->Session->setFlash(sprintf(_('admin_group_deleted'), $id));
+ $this->redirect('/groups/index');
+ }
+ }
+}
+?>
diff --git a/site/app/controllers/images_controller.php b/site/app/controllers/images_controller.php
new file mode 100644
index 0000000..b25ec59
--- /dev/null
+++ b/site/app/controllers/images_controller.php
@@ -0,0 +1,159 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Andrei Hajdukewycz <sancus@off.net> (Original Author)
+ * Justin Scott <fligtar@mozilla.com>
+ * Frederic Wenzel <fwenzel@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+class ImagesController extends AppController
+{
+ var $name = 'Images';
+ var $uses = array('Addon', 'Collection', 'Preview');
+ var $components = array('Image');
+ var $autoRender = false;
+
+ var $securityLevel = 'low';
+
+ function beforeFilter() {
+ // Disable ACLs because this controller is entirely public.
+ $this->SimpleAuth->enabled = false;
+ $this->SimpleAcl->enabled = false;
+ }
+
+ /**
+ * Renders the icon for the specified add-on
+ * @param int $addon_id ID of the add-on
+ * @param int $timestamp timestamp of last update (optional)
+ * @param bool $cache whether to memcache or not (optional)
+ */
+ function addon_icon($addon_id, $timestamp = '', $cache = true) {
+ if ($cache !== true) {
+ $this->Addon->caching = false;
+ }
+
+ if (!empty($addon_id)) {
+ $this->Image->renderAddonIcon($addon_id);
+ }
+ }
+
+ /**
+ * Renders the icon for the specified add-on
+ * @param int $addon_id ID of the add-on
+ * @param int $timestamp timestamp of last update (optional)
+ * @param bool $cache whether to memcache or not (optional)
+ */
+ function collection_icon($collection_id, $timestamp = '', $cache = true) {
+ if ($cache !== true) {
+ $this->Collection->caching = false;
+ }
+
+ if (!empty($collection_id)) {
+ $this->Image->renderCollectionIcon($collection_id);
+ }
+ }
+
+ /**
+ * Renders the full-size preview with the ID specified
+ * @param int $preview_id ID of the preview to render
+ * @param int $timestamp timestamp of last update (optional)
+ * @param bool $cache whether to memcache or not (optional)
+ */
+ function p($preview_id, $timestamp = '', $cache = true) {
+ if ($cache !== true) {
+ $this->Preview->caching = false;
+ }
+
+ if (!empty($preview_id)) {
+ $this->Image->renderAddonPreview($preview_id, 'full');
+ }
+ }
+
+ /**
+ * Renders the thumbnail preview with the ID specified
+ * @param int $preview_id ID of the thumbnail to render
+ * @param int $timestamp timestamp of last update (optional)
+ * @param bool $cache whether to memcache or not (optional)
+ */
+ function t($preview_id, $timestamp = '', $cache = true) {
+ if ($cache !== true) {
+ $this->Preview->caching = false;
+ }
+
+ if (!empty($preview_id)) {
+ $this->Image->renderAddonPreview($preview_id, 'thumbnail');
+ }
+ }
+
+ /**
+ * Supports the deprecated URL structure using incremental preview numbers.
+ * *** Do not create any more URLs that use this; use t() instead
+ * @deprecated
+ */
+ function addon_preview($addon_id, $preview_num) {
+ $this->Image->LEGACY_renderAddonThumbnail($addon_id, $preview_num);
+ }
+
+ /**
+ * Supports the deprecated URL structure using incremental preview numbers.
+ * *** Do not create any more URLs that use this; use p() instead
+ * @deprecated
+ */
+ function preview($addon_id, $preview_num) {
+ $this->Image->LEGACY_renderAddonPreview($addon_id, $preview_num);
+ }
+
+ /**
+ * Return a localized image, as stored in app/locale/images/name.png
+ * @param string $name The image name
+ */
+ function localized_image($name) {
+ $image_path = APP.'locale'.DS.'%s'.DS.'images'.DS.$name;
+
+ $lang = str_replace('-', '_', LANG);
+ if (file_exists(sprintf($image_path, $lang))) {
+ $image = sprintf($image_path, $lang);
+ } elseif (file_exists(sprintf($image_path, 'en_US'))) {
+ $image = sprintf($image_path, 'en_US');
+ } else {
+ return ''; // no luck!
+ }
+ $imageData = file_get_contents($image);
+
+ $this->publish('imagedata', $imageData, false);
+ $this->publish('mimetype', 'image/png');
+ $this->render('show', 'ajax');
+ }
+}
+?>
diff --git a/site/app/controllers/legacy_url_controller.php b/site/app/controllers/legacy_url_controller.php
new file mode 100644
index 0000000..399382b
--- /dev/null
+++ b/site/app/controllers/legacy_url_controller.php
@@ -0,0 +1,89 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Andrei Hajdukewycz <sancus@off.net> (Original Author)
+ * Wil Clouser <clouserw@mozilla.com>
+ * Justin Scott <fligtar@gmail.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+class LegacyUrlController extends AppController
+{
+ var $name = 'LegacyUrlController';
+ var $components = array('Amo');
+
+ var $securityLevel = 'low';
+
+ function beforeFilter() {
+ // Disable ACLs because this controller is entirely public.
+ $this->SimpleAuth->enabled = false;
+ $this->SimpleAcl->enabled = false;
+ }
+
+ /**
+ * If someone gets to this controller, but can't go further, this function is
+ * called. This would indicate a bug in the routing or some other config!
+ */
+ function _defaultAction() {
+ // Go to the home page
+ $this->redirect('/');
+ }
+
+ function oldSection($section) {
+ switch($section) {
+ case "extensions":
+ return $this->redirect("/browse/type:" . ADDON_EXTENSION);
+ case "themes":
+ return $this->redirect("/browse/type:" . ADDON_THEME);
+ case "dictionaries":
+ return $this->redirect("/browse/type:" . ADDON_DICT);
+ case "plugins":
+ return $this->redirect("/browse/type:" . ADDON_PLUGIN);
+
+ // Need to show the "browse all search engines" page (bug 426085)
+ case "search-engines":
+ return $this->redirect("/browse/type:".ADDON_SEARCH."/cat:all?sort=name");
+
+ // Firefox has a default bookmark that says "Get Bookmark Add-ons". And
+ // yeah, I hardcoded that category to 22. :(
+ case "bookmarks":
+ return $this->redirect("/browse/type:".ADDON_EXTENSION."/cat:22/sort:popular");
+ default:
+ return $this->_defaultAction();
+ }
+ }
+
+
+}
+
+?>
diff --git a/site/app/controllers/localizers_controller.php b/site/app/controllers/localizers_controller.php
new file mode 100644
index 0000000..4585333
--- /dev/null
+++ b/site/app/controllers/localizers_controller.php
@@ -0,0 +1,449 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/e
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * Justin Scott <fligtar@gmail.com>.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+class LocalizersController extends AppController
+{
+ var $name = 'Localizers';
+ var $uses = array('Addon', 'Addontype', 'Application', 'Approval', 'Appversion', 'Eventlog', 'Platform','Tag', 'Translation', 'User', 'Version');
+ var $components = array('Amo', 'Audit', 'Error', 'Pagination');
+ var $helpers = array('Html', 'Javascript', 'Pagination');
+
+ var $writeAccess = false;
+
+ /**
+ * Require login for all actions
+ */
+ function beforeFilter() {
+ // Disable ACLs because permissions are assigned per locale here
+ $this->SimpleAuth->enabled = false;
+ $this->SimpleAcl->enabled = false;
+
+ //beforeFilter() is apparently called before components are initialized. Cake++
+ $this->Amo->startup($this);
+ $this->SimpleAuth->startup($this);
+ $this->SimpleAcl->startup($this);
+
+ $session = $this->Session->read('User');
+
+ //Make sure user is a localizer of SOMETHING
+ if (!$this->SimpleAcl->actionAllowed('Localizers', '%', $session)) {
+ $this->Amo->accessDenied();
+ }
+
+ $this->Amo->checkLoggedIn();
+
+ $this->Amo->clean($this->data);
+
+ $this->layout = 'mozilla';
+ $this->pageTitle = 'Localizer Control Panel :: '.sprintf(_('addons_home_pagetitle'), APP_PRETTYNAME);
+
+ $this->cssAdd = array('localizers');
+ $this->publish('cssAdd', $this->cssAdd);
+
+ $this->breadcrumbs = array('Localizer Control Panel' => '/localizers/index');
+ $this->publish('breadcrumbs', $this->breadcrumbs);
+
+ $this->publish('subpagetitle', 'Localizer Control Panel');
+
+ // disable query caching so devcp changes are visible immediately
+ foreach ($this->uses as $_model) {
+ $this->$_model->caching = false;
+ }
+
+ global $valid_languages;
+ //First, see if locale was submitted by form
+ if (!empty($_GET['userlang']) && array_key_exists($_GET['userlang'], $valid_languages)) {
+ $this->Session->write('Localizers', array('userlang' => $_GET['userlang']));
+ define('USERLANG', $_GET['userlang']);
+ }
+ //Next, try looking in the session
+ elseif ($lsession = $this->Session->read('Localizers')) {
+ define('USERLANG', $lsession['userlang']);
+ }
+
+ //Determine language access based on group membership
+ if ($this->SimpleAcl->actionAllowed('Admin', 'EditAnyLocale', $session)) {
+ $this->writeAccess = true;
+ }
+ else {
+ foreach ($session['Group'] as $group) {
+ if (strpos($group['rules'], 'Localizers') !== false) {
+ $rules = explode(':', $group['rules']);
+
+ //If user doesn't have a lang set yet, we set this one
+ if (!defined('USERLANG')) {
+ define('USERLANG', $rules[1]);
+ }
+
+ //If user in group, can write
+ if (USERLANG == $rules[1]) {
+ $this->writeAccess = true;
+ }
+ }
+ }
+ }
+
+ //If user is not in any locale groups, use current locale
+ if (!defined('USERLANG')) {
+ define('USERLANG', LANG);
+ }
+
+ $this->set('writeAccess', $this->writeAccess);
+ }
+
+ /**
+ * Index - summary
+ */
+ function index() {
+ $this->summary();
+ }
+
+ /**
+ * Summary
+ */
+ function summary() {
+ $this->cssAdd = array('summary', 'localizers');
+ $this->publish('cssAdd', $this->cssAdd);
+
+ $ids = array();
+
+ //Pull application translation ids
+ if ($applications = $this->Application->query("SELECT name, shortname FROM applications")) {
+ foreach ($applications as $application) {
+ if (!empty($application['applications']['name'])) {
+ $ids[] = $application['applications']['name'];
+ }
+ if (!empty($application['applications']['shortname'])) {
+ $ids[] = $application['applications']['shortname'];
+ }
+ }
+ }
+
+ //Pull tag translation ids
+ if ($tags = $this->Tag->query("SELECT name, description FROM tags")) {
+ foreach ($tags as $tag) {
+ if (!empty($tag['tags']['name'])) {
+ $ids[] = $tag['tags']['name'];
+ }
+ if (!empty($tag['tags']['description'])) {
+ $ids[] = $tag['tags']['description'];
+ }
+ }
+ }
+
+ //Pull platform translation ids
+ if ($platforms = $this->Platform->query("SELECT name, shortname FROM platforms")) {
+ foreach ($platforms as $platform) {
+ if (!empty($platform['platforms']['name'])) {
+ $ids[] = $platform['platforms']['name'];
+ }
+ if (!empty($platform['platforms']['shortname'])) {
+ $ids[] = $platform['platforms']['shortname'];
+ }
+ }
+ }
+
+ //Locale stats
+ $ids = implode(', ', $ids);
+ global $valid_languages;
+ foreach ($valid_languages as $lang => $language) {
+ $localeStats[$lang] = $this->Translation->query("SELECT COUNT(*) FROM translations WHERE id IN ({$ids}) AND locale='{$lang}'");
+ }
+
+ $this->set('localeStats', $localeStats);
+
+ //Recent activity
+ $logs = $this->Eventlog->findAll(array('type' => 'l10n'), null, 'Eventlog.created DESC', 5);
+ $logs = $this->Audit->explainLog($logs);
+ $this->set('logs', $logs);
+
+ $this->set('page', 'summary');
+ $this->render('summary');
+ }
+
+ /**
+ * Application Localization
+ */
+ function applications() {
+ $this->breadcrumbs['Application Localization'] = '/localizers/application';
+ $this->set('breadcrumbs', $this->breadcrumbs);
+
+ if (!empty($this->data['Application'])) {
+ //Make sure user has write access
+ if (!$this->writeAccess) {
+ //Log
+ $this->Eventlog->log($this, 'security', 'modify_other_locale', null, 1, null, null, USERLANG);
+
+ $this->flash('You do not have permission to modify this locale!', '/localizers/applications');
+ return;
+ }
+
+ $this->Application->setLang(USERLANG, $this);
+ foreach ($this->data['Application'] as $id => $data) {
+ $this->Application->id = $id;
+ $this->Application->save($data);
+ }
+
+ //Log l10n action
+ $this->Eventlog->log($this, 'l10n', 'update_applications', null, 1, null, null, USERLANG);
+
+ $this->flash('Translations updated!', '/localizers/applications');
+ return;
+ }
+
+ $this->Application->setLang(USERLANG, $this);
+ $applications[USERLANG] = $this->Application->findAll(null, null, null, null, null, 0);
+
+ $this->Application->setLang('en-US', $this);
+ $applications['en-US'] = $this->Application->findAll(null, null, null, null, null, 0);
+
+ $this->set('applications', $applications);
+ $this->set('page', 'applications');
+ $this->render('applications');
+ }
+
+ /**
+ * Category Localization
+ */
+ function tags() {
+ $this->breadcrumbs['Tag Localization'] = '/localizers/tags';
+ $this->set('breadcrumbs', $this->breadcrumbs);
+
+ if (!empty($this->data['Tag'])) {
+ //Make sure user has write access
+ if (!$this->writeAccess) {
+ //Log
+ $this->Eventlog->log($this, 'security', 'modify_other_locale', null, 1, null, null, USERLANG);
+
+ $this->flash('You do not have permission to modify this locale!', '/localizers/tags');
+ return;
+ }
+
+ $this->Tag->setLang(USERLANG, $this);
+ foreach ($this->data['Tag'] as $id => $data) {
+ $this->Tag->id = $id;
+ $this->Tag->save($data);
+ }
+
+ //Log l10n action
+ $this->Eventlog->log($this, 'l10n', 'update_tags', null, 1, null, null, USERLANG);
+
+ $this->flash('Translations updated!', '/localizers/tags');
+ return;
+ }
+
+ $this->Tag->setLang(USERLANG, $this);
+ $tags[USERLANG] = $this->Tag->findAll(null, null, null, null, null, 0);
+
+ $this->Tag->setLang('en-US', $this);
+ $tags['en-US'] = $this->Tag->findAll(null, null, null, null, null, 0);
+
+ $this->set('tags', $tags);
+ $this->set('page', 'tags');
+ $this->render('tags');
+ }
+
+ /**
+ * Platform Localization
+ */
+ function platforms() {
+ //Only admins can modify platforms
+ if (!$this->SimpleAcl->actionAllowed('Admin', 'lists', $this->Session->read('User'))) {
+ $this->Amo->accessDenied();
+ return;
+ }
+
+ $this->breadcrumbs['Platform Localization'] = '/localizers/platforms';
+ $this->set('breadcrumbs', $this->breadcrumbs);
+
+ if (!empty($this->data['Platform'])) {
+ //Make sure user has write access
+ if (!$this->writeAccess) {
+ //Log
+ $this->Eventlog->log($this, 'security', 'modify_other_locale', null, 1, null, null, USERLANG);
+
+ $this->flash('You do not have permission to modify this locale!', '/localizers/platforms');
+ return;
+ }
+
+ $this->Platform->setLang(USERLANG, $this);
+ foreach ($this->data['Platform'] as $id => $data) {
+ $this->Platform->id = $id;
+ $this->Platform->save($data);
+ }
+
+ //Log l10n action
+ $this->Eventlog->log($this, 'l10n', 'update_platforms', null, 1, null, null, USERLANG);
+
+ $this->flash('Translations updated!', '/localizers/platforms');
+ return;
+ }
+
+ $this->Platform->setLang(USERLANG, $this);
+ $platforms[USERLANG] = $this->Platform->findAll(null, null, null, null, null, 0);
+
+ $this->Platform->setLang('en-US', $this);
+ $platforms['en-US'] = $this->Platform->findAll(null, null, null, null, null, 0);
+
+ $this->set('platforms', $platforms);
+ $this->set('page', 'platforms');
+ $this->render('platforms');
+ }
+
+ /**
+ * Display log for locale
+ */
+ function logs() {
+ $this->breadcrumbs['Log'] = '/localizers/logs';
+ $this->set('breadcrumbs', $this->breadcrumbs);
+
+ $logs = $this->Eventlog->findAll(array('notes' => USERLANG), null, 'Eventlog.created DESC');
+
+ $logs = $this->Audit->explainLog($logs);
+
+ $this->set('logs', $logs);
+
+ $this->set('page', 'logs');
+ $this->render('logs');
+ }
+
+ /**
+ * Pages
+ */
+ function pages() {
+ $this->breadcrumbs['Pages'] = '/localizers/pages';
+ $this->set('breadcrumbs', $this->breadcrumbs);
+
+ //This is not automatic because not all pages should be translated, yo
+ $pages = array(
+ 0 => array('page' => 'developer_agreement.thtml',
+ 'url' => '/developers/add'
+ ),
+ 1 => array('page' => 'error404.thtml',
+ 'url' => '/thispage/doesnotexist'
+ ),
+ 2 => array('page' => 'nomination.thtml',
+ 'url' => ''
+ ),
+ 3 => array('page' => 'policy.thtml',
+ 'url' => '/pages/policy'
+ ),
+ 4 => array('page' => 'sandbox.thtml',
+ 'url' => '/pages/sandbox'
+ ),
+ 5 => array('page' => 'submission_help.thtml',
+ 'url' => '/pages/submissionhelp'
+ )
+ );
+
+ $images = array(
+ 0 => array('image' => 'sandbox-review.png',
+ 'url' => '/pages/sandbox'
+ )
+ );
+
+ $userlang = str_replace('-', '_', USERLANG);
+
+ //Check for page existence
+ foreach ($pages as $k => $page) {
+ if (file_exists(APP.'locale'.DS.$userlang.DS.'pages'.DS.$page['page'])) {
+ $pages[$k]['exists'] = true;
+ }
+ else {
+ $pages[$k]['exists'] = false;
+ }
+ }
+
+ //Check for image existence
+ foreach ($images as $k => $image) {
+ if (file_exists(APP.'locale'.DS.$userlang.DS.'images'.DS.$image['image'])) {
+ $images[$k]['exists'] = true;
+ }
+ else {
+ $images[$k]['exists'] = false;
+ }
+ }
+
+ $this->set('pages', $pages);
+ $this->set('images', $images);
+
+ $this->set('page', 'pages');
+ $this->render('pages');
+ }
+
+ /**
+ * Gettext
+ */
+ function gettext() {
+ $this->breadcrumbs['Gettext'] = '/localizers/gettext';
+ $this->set('breadcrumbs', $this->breadcrumbs);
+
+ $userlang = str_replace('-', '_', USERLANG);
+
+ //Get .po files
+ $enus = file_get_contents(APP.'locale'.DS.'en_US'.DS.'LC_MESSAGES'.DS.'messages.po');
+ $locale = file_get_contents(APP.'locale'.DS.$userlang.DS.'LC_MESSAGES'.DS.'messages.po');
+
+ //Remove header information
+ $enus = substr($enus, strpos($enus, "\n\n"));
+ $locale = substr($locale, strpos($locale, "\n\n"));
+
+ //Parse strings
+ preg_match_all('/msgid\s+"(.+?)"\s*(msgid_plural\s+"(.+?)"\s*)?(msgstr(\[\d+\])? "(.+?)"\s*)+(#|msg)/is', $enus, $enusMatches, PREG_SET_ORDER);
+ preg_match_all('/msgid\s+"(.+?)"\s*(msgid_plural\s+"(.+?)"\s*)?(msgstr(\[\d+\])? "(.+?)"\s*)+(#|msg)/is', $locale, $localeMatches, PREG_SET_ORDER);
+
+ //Make pretty key => value arrays
+ foreach ($enusMatches as $enusMatch) {
+ $enusStrings[$enusMatch[1]] = $enusMatch[6];
+ }
+ foreach ($localeMatches as $localeMatch) {
+ $localeStrings[$localeMatch[1]] = $localeMatch[6];
+ }
+
+ //Compare
+ $untranslated = array_intersect_assoc($enusStrings, $localeStrings);
+
+ $this->set('untranslated', $untranslated);
+ $this->set('total', count($enusStrings));
+ $this->set('userlang', $userlang);
+
+ $this->set('page', 'gettext');
+ $this->render('gettext');
+ }
+}
+
+?>
diff --git a/site/app/controllers/pages_controller.php b/site/app/controllers/pages_controller.php
new file mode 100644
index 0000000..2dd39d0
--- /dev/null
+++ b/site/app/controllers/pages_controller.php
@@ -0,0 +1,140 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Frederic Wenzel <fwenzel@mozilla.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/**
+ * This Pages controller is largely identical to the cake one, but it
+ * had to be copied in order to load additional helpers.
+ */
+class PagesController extends AppController{
+
+ var $name = 'Pages';
+ var $helpers = array('Html', 'Localization');
+ var $components = array('Image', 'Pagination');
+ var $uses = array('Addon', 'Collection', 'File', 'Platform', 'User');
+
+ var $securityLevel = 'low';
+
+ function beforeFilter() {
+ // Disable ACLs because this controller is entirely public.
+ $this->SimpleAuth->enabled = false;
+ $this->SimpleAcl->enabled = false;
+ }
+
+/**
+ * Displays a view
+ *
+ */
+ function display() {
+ if (!func_num_args()) {
+ $this->redirect('/');
+ }
+
+ $path = func_get_args();
+ $path_string = join('/', $path);
+
+ if (!count($path) || ($path[0] == 'home')) {
+ $this->redirect('/');
+ }
+
+ $count =count($path);
+ $page =null;
+ $subpage=null;
+ $title =null;
+
+ if (!empty($path[0])) {
+ $page = $path[0];
+ }
+
+ if (!empty($path[1])) {
+ $subpage = $path[1];
+ }
+
+ // settings titles for individual pages
+ switch ($path_string) {
+ case 'appversions':
+ $title = ___('page_title_appversions', _('pages_appversions_header')); break;
+ case 'credits':
+ $title = ___('page_title_credits', 'Credits'); break;
+ case 'fashionyourfirefox_faq':
+ $title = ___('page_title_fashionyourfirefox_faq', 'Fashion your Firefox FAQ');
+ $this->set('cssAdd', array('collection-style'));
+ $this->publish('suppressHeader', true, false);
+ $this->publish('suppressLanguageSelector', true, false);
+ $this->publish('suppressCredits', true, false);
+ break;
+ case 'policy':
+ $title = ___('page_title_policy', 'Add-ons Policy'); break;
+ case 'privacy':
+ $title = ___('page_title_privacy', 'Mozilla Privacy Policy'); break;
+ case 'review_guide':
+ $title = ___('page_title_review_guide', 'Review Guidelines'); break;
+ case 'sandbox':
+ $title = ___('page_title_sandbox', 'Sandbox Review System'); break;
+ case 'submissionhelp':
+ $title = ___('page_title_submissionhelp', 'Submission Help'); break;
+ case 'faq':
+ $title = ___('page_title_faq', 'Frequently Asked Questions'); break;
+ case 'developer_faq':
+ $title = ___('page_title_developer_faq'); break;
+ case 'collector':
+ $title = ___('page_title_collector');
+ $this->publish('collectionSearch', true); break;
+ case 'collector_faq':
+ $title = ___('page_title_collector_faq');
+ $this->publish('collectionSearch', true); break;
+ case 'collector_features':
+ $title = ___('page_title_collector_features');
+ $this->publish('collectionSearch', true); break;
+ case 'collector_firstrun':
+ $this->set('jsAdd', array('amo2009/collections'));
+ $title = ___('page_title_collector_firstrun');
+ $this->publish('collectionSearch', true); break;
+ default:
+ if (!empty($path[$count - 1])) {
+ $title = ucfirst($path[$count - 1]);
+ }
+ break;
+ }
+
+ $this->publish('page', $page);
+ $this->publish('subpage', $subpage);
+ $this->set('title', $title .' :: '.sprintf(_('addons_home_pagetitle'), APP_PRETTYNAME));
+ $this->render($path_string);
+ }
+}
+?>
diff --git a/site/app/controllers/previews_controller.php b/site/app/controllers/previews_controller.php
new file mode 100644
index 0000000..ba1291b
--- /dev/null
+++ b/site/app/controllers/previews_controller.php
@@ -0,0 +1,328 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Andrei Hajdukewycz <sancus@off.net> (Original Author)
+ * Wil Clouser <clouserw@mozilla.com>
+ * Justin Scott <fligtar@gmail.com>
+ * Frederic Wenzel <fwenzel@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+class PreviewsController extends AppController
+{
+ var $name = 'Previews';
+ var $uses = array('Addon', 'Addontype', 'Preview', 'Translation');
+ var $components = array('Amo', 'Developers', 'Error', 'Image');
+ var $helpers = array('Html', 'Javascript', 'Localization');
+
+ var $securityLevel = 'low';
+
+ /**
+ * Require login for all actions
+ */
+ function beforeFilter() {
+ // Disable ACLs because this controller is entirely public.
+ $this->SimpleAuth->enabled = false;
+ $this->SimpleAcl->enabled = false;
+
+ //beforeFilter() is apparently called before components are initialized. Cake++
+ $this->Amo->startup($this);
+ $this->Amo->checkLoggedIn();
+
+ //Clean post data
+ $this->Amo->clean($this->data);
+
+ $this->layout = 'mozilla';
+ $this->pageTitle = _('devcp_pagetitle').' :: '.sprintf(_('addons_home_pagetitle'), APP_PRETTYNAME);
+
+ $this->cssAdd = array('developers');
+ $this->publish('cssAdd', $this->cssAdd);
+
+ $this->publish('suppressJQuery', 1);
+ $this->jsAdd = array('developers',
+ 'scriptaculous/prototype',
+ 'scriptaculous/scriptaculous.js?load=effects'
+ ,'jquery-compressed.js');
+ $this->publish('jsAdd', $this->jsAdd);
+
+ $this->breadcrumbs = array(_('devcp_pagetitle') => '/developers/index');
+ $this->publish('breadcrumbs', $this->breadcrumbs);
+
+ $this->publish('subpagetitle', _('devcp_pagetitle'));
+
+ global $native_languages;
+ $this->publish('nativeLanguages', $native_languages);
+
+ // Default "My Add-ons" sidebar data
+ $session = $this->Session->read('User');
+ $this->publish('all_addons', $this->Addon->getAddonsByUser($session['id']));
+
+ // disable query caching so devcp changes are visible immediately
+ foreach ($this->uses as $_model) {
+ $this->$_model->caching = false;
+ }
+ }
+
+ /**
+ * Add a preview
+ * @param int $addon_id The add-on id
+ */
+ function add($addon_id) {
+ $this->Amo->clean($addon_id);
+ $this->publish('subpagetitle', _('devcp_preview_add_pagetitle'));
+ $this->breadcrumbs[_('devcp_preview_add_pagetitle')] = '/previews/add/'.$addon_id;
+ $this->publish('breadcrumbs', $this->breadcrumbs);
+
+ if (!$this->Amo->checkOwnership($addon_id)) {
+ $this->flash(_('devcp_error_addon_access_denied'), '/developers/index');
+ return;
+ }
+
+ $this->Addon->bindFully();
+ $this->Addon->id = $addon_id;
+ if (!$addon = $this->Addon->read()) {
+ $this->flash(_('error_addon_notfound'), '/developers/index');
+ return;
+ }
+
+ $this->Preview->id = 0;
+ $this->publish('id', $addon_id);
+
+ if (!empty($this->data)) {
+
+ //If highlighting, remove other highlights
+ if (!empty($this->data['Preview']['highlight']) && empty($preview['Preview']['highlight'])) {
+ $this->Developers->unhighlightOtherPreviews($addon['Addon']['id']);
+ }
+
+ if ($previewData = $this->Developers->addPreview($addon_id, $this->data['Preview'])) {
+ $this->Preview->save($previewData);
+ $id = $this->Preview->getLastInsertId();
+
+ $this->Developers->saveTranslations($this->data, array('Preview'));
+
+ $this->flash(_('devcp_preview_added_successfully'), '/previews/edit/'.$id);
+ return;
+ }
+ }
+
+ if (count($addon['Preview']) > 0) {
+ $highlightCheckbox = array('onClick' => 'return confirmMakeDefault(this);');
+ }
+ else {
+ $highlightCheckbox = array('checked' => 'checked', 'disabled' => 'disabled');
+ }
+ $this->publish('highlightCheckbox', $highlightCheckbox);
+
+ //Retrieve language arrays from bootstrap.
+ global $valid_languages, $native_languages;
+ foreach (array_keys($valid_languages) as $key) {
+ $languages[$key] = $native_languages[$key]['native'];
+
+ $this->Preview->setLang($key, $this);
+ $previewL = $this->Preview->read();
+
+ foreach ($this->Preview->translated_fields as $field) {
+ $info[$key][$field] = '';
+ }
+ }
+ $this->Preview->setLang(LANG, $this);
+ $this->publish('errors', $this->Error->errors);
+
+ $this->publish('addon', $addon);
+
+ $localizedFields = array(
+ 'caption' => array(
+ 'type' => 'input',
+ 'display' => _('devcp_addon_field_preview_caption_displaytitle'),
+ 'model' => 'Preview',
+ 'field' => 'caption',
+ 'attributes' => array(
+ 'size' => 40
+ )
+ )
+ );
+
+ //Set up localebox info
+ $this->set('localebox', array('info' => $info,
+ 'defaultLocale' => $addon['Addon']['defaultlocale'],
+ 'languages' => $languages,
+ 'localizedFields' => $localizedFields));
+ //Javascript localization
+ $this->publish('jsLocalization', array(
+ 'makeDefaultNotice' => _('devcp_notice_makedefault')
+ ));
+ }
+
+ /**
+ * Edit a preview
+ * @param int $id Preview id
+ */
+ function edit($id) {
+ $this->Amo->clean($id);
+ $this->set ('subpagetitle', _('devcp_preview_edit_pagetitle'));
+ $this->breadcrumbs[_('devcp_preview_edit_pagetitle')] = '/previews/edit/'.$id;
+ $this->publish('breadcrumbs', $this->breadcrumbs);
+
+ $this->Preview->id = $id;
+ if (!$preview = $this->Preview->read()) {
+ $this->flash(_('error_preview_notfound'), '/developers/index');
+ return;
+ }
+
+ $this->Addon->id = $preview['Preview']['addon_id'];
+ if (!$addon = $this->Addon->read()) {
+ $this->flash(_('error_addon_notfound'), '/developers/index');
+ return;
+ }
+
+ if (!$this->Amo->checkOwnership($this->Addon->id)) {
+ $this->flash(_('devcp_error_addon_access_denied'), '/developers/index');
+ return;
+ }
+
+ if (!empty($this->data)) {
+ if (!empty($_POST['delete'])) {
+ $this->_delete($id);
+ return;
+ }
+
+ //If removing highlight, hightlight another preview
+ if (empty($this->data['Preview']['highlight']) && !empty($preview['Preview']['highlight'])) {
+ $this->Developers->highlightNextPreview($preview, $addon);
+ }
+
+ //If highlighting, remove other highlights
+ if (!empty($this->data['Preview']['highlight']) && empty($preview['Preview']['highlight'])) {
+ $this->Developers->unhighlightOtherPreviews($addon['Addon']['id']);
+ }
+
+ $previewData = $this->Amo->filterFields($this->data['Preview'], array('highlight'));
+ $this->Preview->save($previewData);
+
+ //Save translated fields (caption)
+ $this->Developers->saveTranslations($this->data, array('Preview'));
+
+ $this->flash(_('devcp_preview_updated_successfully'), '/previews/edit/'.$id);
+ return;
+ }
+
+ if (!empty($preview['Preview']['highlight'])) {
+ $highlightCheckbox = array('value' => '1', 'checked' => 'checked', 'onClick' => 'return confirmClearDefault(this);');
+ }
+ else {
+ $highlightCheckbox = array('onClick' => 'return confirmMakeDefault(this);');
+ }
+ $this->publish('highlightCheckbox', $highlightCheckbox);
+
+ //Javascript localization
+ $this->publish('jsLocalization', array(
+ 'makeDefaultNotice' => _('devcp_notice_makedefault'),
+ 'clearDefaultNotice' => _('devcp_notice_cleardefault')
+ ));
+
+ //Retrieve language arrays from bootstrap.
+ global $valid_languages, $native_languages;
+ foreach (array_keys($valid_languages) as $key) {
+ $languages[$key] = $native_languages[$key]['native'];
+
+ $this->Preview->setLang($key, $this);
+ $previewL = $this->Preview->read();
+
+ foreach ($previewL['Translation'] as $field => $translation) {
+ if ($translation['locale'] == $key) {
+ $info[$key][$field] = $translation['string'];
+ }
+ else {
+ $info[$key][$field] = '';
+ }
+ }
+ }
+ $this->Preview->setLang(LANG, $this);
+
+ $localizedFields = array(
+ 'caption' => array(
+ 'type' => 'input',
+ 'display' => _('devcp_addon_field_preview_caption_displaytitle'),
+ 'model' => 'Preview',
+ 'field' => 'caption',
+ 'attributes' => array(
+ 'size' => 40
+ )
+ )
+ );
+
+ //Set up localebox info
+ $this->set('localebox', array('info' => $info,
+ 'defaultLocale' => $addon['Addon']['defaultlocale'],
+ 'languages' => $languages,
+ 'localizedFields' => $localizedFields));
+ $this->publish('id', $id);
+ $this->publish('addon', $addon);
+ $this->publish('previewUrl', $this->Image->getPreviewURL($id));
+ }
+
+ /**
+ * Delete a preview
+ * @param int $id Preview id
+ */
+ function _delete($id) {
+ $this->Amo->clean($id);
+ $this->Preview->id = $id;
+ $preview = $this->Preview->read();
+
+ $this->Addon->id = $preview['Preview']['addon_id'];
+ if (!$addon = $this->Addon->read()) {
+ $this->flash(_('error_addon_notfound'), '/developers/index');
+ return;
+ }
+
+ if (!$this->Amo->checkOwnership($addon['Addon']['id'])) {
+ $this->flash(_('devcp_error_addon_access_denied'), '/developers/index');
+ return;
+ }
+
+ //If currently highlighted, hightlight another preview
+ if (!empty($preview['Preview']['highlight'])) {
+ $this->Developers->highlightNextPreview($preview, $addon);
+ }
+
+ $this->Preview->delete();
+
+ $this->flash(_('devcp_preview_deleted_successfully'), '/developers/index/'.$addon['Addon']['id']);
+ return;
+ }
+}
+
+?>
diff --git a/site/app/controllers/reviews_controller.php b/site/app/controllers/reviews_controller.php
new file mode 100644
index 0000000..a62c557
--- /dev/null
+++ b/site/app/controllers/reviews_controller.php
@@ -0,0 +1,579 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Andrei Hajdukewycz <sancus@off.net> (Original Author)
+ * Wil Clouser <clouserw@mozilla.com>
+ * Justin Scott <fligtar@gmail.com>
+ * Frederic Wenzel <fwenzel@mozilla.com>
+ * Les Orchard <lorchard@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+class ReviewsController extends AppController
+{
+ var $name = 'Reviews';
+ var $layout = 'mozilla';
+ var $uses = array('Addon', 'Eventlog', 'Review', 'Translation', 'Version', 'ReviewsModerationFlag');
+ var $components = array('Amo', 'Pagination', 'Session');
+ var $helpers = array('Html', 'Link', 'Localization', 'Pagination', 'Time');
+ var $namedArgs = true;
+ var $beforeFilter = array('checkCSRF', 'getNamedArgs', '_checkSandbox', 'checkAdvancedSearch');
+
+ var $securityLevel = 'low';
+
+ function beforeFilter() {
+ // Disable ACLs because this controller is entirely public.
+ $this->SimpleAuth->enabled = false;
+ $this->SimpleAcl->enabled = false;
+ }
+
+ /**
+ * Display/add reviews
+ */
+ function display($id = null) {
+ global $valid_status;
+
+ $this->Amo->clean($id);
+ $format = (isset($this->namedArgs['format']) ? $this->namedArgs['format'] : 'html');
+
+ if (!$id || !is_numeric($id)) {
+ $this->flash(sprintf(_('error_missing_argument'), 'addon_id'), '/', 3);
+ return;
+ }
+
+ $addon = $this->Addon->findById($id);
+ if (empty($addon)) {
+ $this->flash(_('error_addon_notfound'), '/', 3);
+ return;
+ }
+ $this->publish('addon', $addon);
+
+ // user logged in?
+ $user = $this->Session->read('User');
+ $this->publish('loggedin', !empty($user));
+ if (!empty($user)) {
+ // does user have a review already?
+ $user_revcount = $this->Review->findCount("Review.user_id = {$user['id']} AND Review.version_id = {$addon['Version'][0]['id']}", null, null, null, null, 0);
+ $this->publish('hasreview', ($user_revcount > 0));
+
+ // is user an admin?
+ $isadmin = $this->SimpleAcl->actionAllowed('Admin', 'EditAnyAddon', $user);
+ $this->publish('isAdmin', $isadmin);
+
+ // is user author of this addon?
+ $isauthor = $this->Amo->checkOwnership($id, $addon['Addon'], true);
+ $this->publish('isAuthor', $isauthor);
+ } else {
+ $this->publish('hasreview', false);
+ $this->publish('isAdmin', false);
+ $this->publish('isAuthor', false);
+ }
+
+ // can delete reviews?
+ $this->publish('canDelete', $this->SimpleAcl->actionAllowed('Editors', 'DeleteAnyReview', $user));
+
+ $this->status = $valid_status;
+
+ $reviews_flagged = array();
+ $others_counts = array();
+ $reviews = array();
+
+ // get all version ids for this addon
+ $_versions = $this->Version->findAll(array('Version.addon_id' => $id),
+ 'Version.id', null, null, null, -1);
+ $_version_ids = array();
+ foreach ($_versions as $_version) $_version_ids[] = $_version['Version']['id'];
+
+ if (!empty($_versions)) {
+ $criteria = array(
+ 'Review.version_id' => $_version_ids,
+ 'Review.reply_to IS NULL'
+ );
+
+ $_review_ids = array();
+ $others_counts = array();
+
+ $this->Review->unbindfully();
+
+ if (isset($_GET['user_id'])) {
+
+ // Given a user_id parameter, load reviews only for that user.
+ $_reviews = $this->Review->findAll(array_merge($criteria, array(
+ 'Review.user_id' => $_GET['user_id']
+ )), 'Review.id', 'Review.created DESC', NULL, 0, -1);
+ $_review_ids = array();
+ foreach($_reviews as $_id)
+ $_review_ids[] = $_id['Review']['id'];
+
+ if (isset($_GET['bare'])) {
+ // In the Ajax use case, avoid using a layout wrapper.
+ $this->layout = NULL;
+ }
+ if (isset($_GET['skip_first'])) {
+ // Skip the first review given the ?skip_first option.
+ array_shift($_review_ids);
+ }
+
+ $this->Pagination->total = count($_review_ids);
+ list($order,$limit,$page) =
+ $this->Pagination->init($criteria);
+
+ } else {
+
+ // Count and fetch reviews for the addon, only the latest per user.
+ $this->Pagination->total =
+ $this->Review->countLatestReviewsForAddon($id);
+ list($order,$limit,$page) =
+ $this->Pagination->init($criteria);
+ $_latest_reviews =
+ $this->Review->findLatestReviewsForAddon($id, $limit, $page);
+
+ foreach($_latest_reviews as $_r) {
+ $_id = $_r['id'];
+ $_review_ids[] = $_id;
+ $others_counts[$_id] = $_r['others_count'];
+ }
+
+ }
+
+ $reviews = $this->Review->getReviews($_review_ids);
+
+ // fetch possible developer replies
+ foreach ($reviews as $_rid => $_review) {
+ $reply = $this->Review->find(array(
+ 'Review.reply_to' => $_review['Review']['id'],
+ ), "Review.id");
+ if (!empty($reply)) {
+ $reply = $this->Review->getReviews($reply['Review']['id']);
+ $reviews[$_rid]['Review']['reply'] = $reply[0];
+ }
+ }
+
+ // Fetch reviews flagged for moderation by this user, if any.
+ if (!empty($user)) {
+ $_flags = $this->ReviewsModerationFlag->findAll(array(
+ 'ReviewsModerationFlag.user_id' => $user['id'],
+ 'Review.version_id' => $_version_ids
+ ));
+ foreach ($_flags as $flag) {
+ $reviews_flagged[$flag['ReviewsModerationFlag']['review_id']] =
+ $flag['ReviewsModerationFlag'];
+ }
+ }
+
+ }
+
+ $this->publish('reviews_flagged', $reviews_flagged);
+ $this->publish('reviews_others_counts', $others_counts);
+ $this->publish('reviews', $reviews);
+
+ $_title = sprintf(_('addon_review_pagetitle'), $addon['Translation']['name']['string']);
+
+ if ($format != 'rss') {
+ $this->pageTitle = $_title.' :: '.sprintf(_('addons_home_pagetitle'), APP_PRETTYNAME);
+ $this->publish('rssAdd', array("/reviews/display/{$id}/format:rss"));
+ $this->publish('breadcrumbs', array(
+ $addon['Translation']['name']['string'] => "/addon/{$addon['Addon']['id']}",
+ $_title => "/reviews/display/$id"
+ ));
+ $this->publish('review_flag_reasons', $this->ReviewsModerationFlag->reasons);
+ $this->render();
+ return;
+ } else {
+ $this->publish('rss_title', $_title);
+ $this->publish('rss_description', $_title);
+ $this->render('rss/reviews', 'rss');
+ return;
+ }
+ }
+
+ /**
+ * Add a new review
+ */
+ function add($id) {
+ global $valid_status;
+
+ $this->Amo->clean($id);
+ $this->Amo->checkLoggedIn(); // must be logged in
+
+ $this->publish('cssAdd', array('forms'));
+ $this->set('reviewRating', 0);
+
+ if (!$id || !is_numeric($id)) {
+ $this->flash(sprintf(_('error_missing_argument'), 'addon_id'), '/', 3);
+ return;
+ }
+
+ $addon = $this->Addon->findById($id);
+ if (empty($addon)) {
+ $this->flash(_('error_addon_notfound'), '/', 3);
+ return;
+ }
+
+ $isauthor = $this->Amo->checkOwnership($id, $addon['Addon'], true);
+ if($isauthor) {
+ $this->flash(_('error_addon_selfreview'), '/', 3);
+ }
+
+ $this->publish('addon', $addon);
+ $_title = sprintf(_('addon_review_pagetitle'), $addon['Translation']['name']['string']);
+ $this->pageTitle = $_title .' :: '.sprintf(_('addons_home_pagetitle'), APP_PRETTYNAME);
+
+ // fetch user object from session
+ $user = $this->Session->read('User');
+
+
+ $this->publish('breadcrumbs', array(
+ $addon['Translation']['name']['string'] => "/addon/{$addon['Addon']['id']}",
+ $_title => "/reviews/add/$id"
+ ));
+
+ // add/edit review if submitted
+ if (isset($this->data['Review'])) {
+ $old_title = $this->data['Review']['title'];
+ $old_body = $this->data['Review']['body'];
+ $this->Amo->clean($this->data['Review']);
+
+ // validate rating
+ if ($this->data['Review']['rating'] < 0 || $this->data['Review']['rating'] > 5) {
+ $this->Review->invalidate('rating');
+ return;
+ }
+
+ $this->data['Review']['version_id'] = $this->Version->getVersionByAddonId($addon['Addon']['id'], $valid_status); // add version id to data array
+ $this->data['Review']['user_id'] = $user['id'];
+ $this->data['Review']['editorreview'] = 0; // auto-approve review
+
+ // if id is set, check if it's valid
+ if ($this->data['Review']['id'] !== 0) {
+ $oldreview = $this->Review->find("Version.addon_id = {$id} AND Review.user_id = {$user['id']}");
+ if (!isset($oldreview['Review']['id']) || $oldreview['Review']['id'] === $this->data['Review']['id'])
+ $this->Review->invalidate('id');
+ }
+
+ if ($this->Review->save($this->data)) {
+ $this->Review->updateBayesianRating(array($id));
+ $this->render('review_added');
+ return;
+ } else {
+ $this->data['Review']['title'] = $old_title;
+ $this->data['Review']['body'] = $old_body;
+ $this->publish('errorMessage', true);
+ }
+ } else {
+ // edit a previous review if present
+ $oldreview = $this->Review->find("Version.addon_id = {$id} AND Review.user_id = {$user['id']}");
+ if (!empty($oldreview)) {
+ $this->data['Review'] = $oldreview['Review'];
+ $this->set('reviewRating', $oldreview['Review']['rating']);
+ // drop in localized strings
+ if ($oldreview['Translation']['title']['locale'] == LANG) {
+ $this->data['Review']['title'] = htmlentities($oldreview['Translation']['title']['string']);
+ $this->data['Review']['body'] = htmlentities($oldreview['Translation']['body']['string']);
+ } else {
+ $this->data['Review']['title'] = '';
+ $this->data['Review']['body'] = '';
+ }
+ $this->publish('editreview', true);
+ }
+ }
+ }
+
+ /**
+ * Developer reply to a review
+ *
+ * @param int review ID to reply to
+ */
+ function reply($id) {
+ $this->Amo->clean($id);
+ $this->Amo->checkLoggedIn(); // must be logged in
+
+ $this->publish('cssAdd', array('forms'));
+
+ if (!$id || !is_numeric($id)) {
+ $this->flash(sprintf(_('error_missing_argument'), 'addon_id'), '/', 3);
+ return;
+ }
+
+ // find review we're replying to (only where reply_to is null, i.e. no replies to replies)
+ $review = $this->Review->find("Review.id = $id AND Review.reply_to IS NULL", null, null, 2);
+ if (empty($review)) {
+ $this->flash(_('error_addon_notfound'), '/', 3);
+ return;
+ }
+ $this->publish('reply_to', $review);
+
+ $version = $this->Version->findById($review['Review']['version_id']);
+ $addon = $this->Addon->findById($version['Version']['addon_id']);
+ if (empty($addon)) {
+ $this->flash(_('error_addon_notfound'), '/', 3);
+ return;
+ }
+ $this->publish('addon', $addon);
+
+ $_title = sprintf(_('addon_review_pagetitle'), $addon['Translation']['name']['string']);
+ $this->pageTitle = $_title .' :: '.sprintf(_('addons_home_pagetitle'), APP_PRETTYNAME);
+
+ // fetch user object from session
+ $user = $this->Session->read('User');
+
+ // only authors are allowed to reply to reviews
+ if (!$this->Amo->checkOwnership($addon['Addon']['id'], $addon['Addon'])) {
+ $this->flash(_('error_access_denied'), '/', 3);
+ return;
+ }
+
+ $this->publish('breadcrumbs', array(
+ $addon['Translation']['name']['string'] => "/addon/{$addon['Addon']['id']}",
+ $_title => "/reviews/display/".$addon['Addon']['id']
+ ));
+
+ // if the developer already replied to this, fetch the reply
+ $oldreply = $this->Review->find(array('Review.reply_to' => $id));
+
+ // add review if submitted
+ if (isset($this->data['Review'])) {
+ $this->Amo->clean($this->data['Review']);
+
+ $this->data['Review']['version_id'] = $review['Version']['id']; // add version id to data array
+ $this->data['Review']['user_id'] = $user['id'];
+ $this->data['Review']['editorreview'] = 0; // auto-approve replies
+ $this->data['Review']['rating'] = null;
+
+ // set reply id
+ if (!empty($oldreply))
+ $this->data['Review']['id'] = $oldreply['Review']['id'];
+ else
+ unset($this->data['Review']['id']);
+ // set review id we're replying to
+ $this->data['Review']['reply_to'] = $id;
+
+ if ($this->Review->save($this->data)) {
+ $this->render('review_added');
+ return;
+ } else {
+ $this->publish('errorMessage', true);
+ }
+ } else {
+ // edit a previous reply if present
+ if (!empty($oldreply)) {
+ $this->data['Review'] = $oldreply['Review'];
+ // drop in localized strings
+ if ($oldreply['Translation']['title']['locale'] == LANG
+ && $oldreply['Translation']['title']['locale'] == LANG) {
+ $this->data['Review']['title'] = $oldreply['Translation']['title']['string'];
+ $this->data['Review']['body'] = $oldreply['Translation']['body']['string'];
+ } else {
+ $this->data['Review']['title'] = '';
+ $this->data['Review']['body'] = '';
+ }
+ $this->publish('editreview', true);
+ }
+ }
+ $this->render('add');
+ }
+
+ function delete($id) {
+ // disable query caching
+ foreach ($this->uses as $_model) {
+ $this->$_model->caching = false;
+ }
+
+ // Make sure user has access
+ if (!$this->SimpleAcl->actionAllowed('Editors', 'DeleteAnyReview', $this->Session->read('User'))) {
+ $this->Amo->accessDenied();
+ return;
+ }
+
+ $this->Review->id = $id;
+
+ $review = $this->Review->findById($id, null, null, 2);
+ $review['Addon'] = $this->Addon->findById($review['Version']['addon_id'], array('id', 'name'), null, -1);
+
+ $_title = sprintf(_('addon_review_pagetitle'), $review['Addon']['Translation']['name']['string']);
+ $this->pageTitle = $_title .' :: '.sprintf(_('addons_home_pagetitle'), APP_PRETTYNAME);
+
+ $this->publish('breadcrumbs', array(
+ $review['Addon']['Translation']['name']['string'] => "/addon/{$review['Addon']['Addon']['id']}",
+ $_title => "/reviews/display/{$review['Addon']['Addon']['id']}"
+ ));
+
+ if (!empty($_POST['yes'])) {
+ //Pull review for log (in en-US)
+ $this->Review->setLang('en-US', $this);
+ $reviewInfo = $this->Review->read();
+ $this->Review->setLang(LANG, $this);
+
+ $reviewArray = array('title' => $reviewInfo['Translation']['title']['string'],
+ 'body' => $reviewInfo['Translation']['body']['string']);
+ //Log editor action
+ $this->Eventlog->log($this, 'editor', 'review_delete', null, $id, null, null, serialize($reviewArray));
+
+ $this->Review->delete();
+
+ // update average ratings
+ debug($review['Addon']['Addon']['id']);
+ $this->Review->updateBayesianRating(array($review['Addon']['Addon']['id']));
+
+ $this->flash(_('addon_review_deleted_successfully'), "/reviews/display/{$review['Version']['addon_id']}");
+ return;
+ }
+
+ if (!empty($_POST['no'])) {
+ $this->redirect("/reviews/display/{$review['Version']['addon_id']}");
+ return;
+ }
+
+ $this->publish('review', $review);
+
+ $this->render('delete', 'mozilla');
+ }
+
+ /**
+ * Flag a review as inappropriate.
+ *
+ * (if called as .../ajax, this is an ajax action)
+ */
+ function flag($ajax = null) {
+ $this->publish('ajaxreply', $ajax);
+ if (!isset($this->data['Review']['id']) || !is_numeric($this->data['Review']['id'])) {
+ header('HTTP/1.1 400 Bad Request');
+ if (!$ajax)
+ $this->flash(_('error_missing_argument'), "/");
+ else {
+ $this->publish('msg', _('error_missing_argument'));
+ $this->render('flag', 'ajax');
+ }
+ return;
+ }
+ // must be logged in to flag something
+ if (!$this->Session->check('User')) {
+ if (!$ajax)
+ $this->Amo->checkLoggedIn();
+ else {
+ $this->publish('msg', _('error_access_denied'));
+ $this->render('flag', 'ajax');
+ }
+ return;
+ }
+
+ $error = FALSE;
+ $user = $this->Session->read('User');
+ $reviewid = $this->data['Review']['id'];
+ $flag_name = $this->data['ReviewsModerationFlag']['flag_name'];
+
+ // Check for freeform notes, forcing the flag to 'other' if present.
+ $flag_notes = @$this->data['ReviewsModerationFlag']['flag_notes'];
+ if ($flag_notes) $flag_name = 'review_flag_reason_other';
+
+ // Ensure that the incoming flag reason is one of the defined set
+ if (!array_key_exists($flag_name, $this->ReviewsModerationFlag->reasons)) {
+
+ // Discard the flag if it's not in the defined set.
+ $flag_name = '';
+ $error = TRUE;
+
+ } else {
+
+ // Attempt to fetch an existing flag for this user and
+ // this review.
+ $this->ReviewsModerationFlag->unbindFully();
+ $user_flag = $this->ReviewsModerationFlag->find(array(
+ 'ReviewsModerationFlag.user_id' => $user['id'],
+ 'ReviewsModerationFlag.review_id' => $reviewid
+ ));
+
+ if (!$user_flag) {
+ // No flag found for this user and review, so start
+ // preparing a fresh record.
+ $user_flag = array(
+ 'ReviewsModerationFlag' => array(
+ 'user_id' => $user['id'],
+ 'review_id' => $reviewid,
+ 'created' => date('Y-m-d h:i:s', time())
+ )
+ );
+ }
+
+ $user_flag['ReviewsModerationFlag']['flag_name'] =
+ $flag_name;
+ $user_flag['ReviewsModerationFlag']['modified'] =
+ date('Y-m-d h:i:s', time());
+
+ // Accept only between 10 and 100 characters of free form flag notes,
+ // when the 'other' flag is chosen.
+ if ($flag_name == 'review_flag_reason_other') {
+ if (!$flag_notes || strlen($flag_notes) < 10 || strlen($flag_notes) > 100) {
+ $error = TRUE;
+ $this->publish('msg', sprintf( ___('addon_review_flag_error_other_length',
+ 'Problem flagging review: Notes for flagged reviews are limited to between ' .
+ '10 and 100 characters; your character length was %s.'),
+ strlen($flag_notes) ) );
+ } else {
+ $user_flag['ReviewsModerationFlag']['flag_notes'] = $flag_notes;
+ }
+ }
+
+ if (!$error)
+ $this->ReviewsModerationFlag->save($user_flag);
+ }
+
+ // mark review for editor approval
+ $this->Review->id = $reviewid;
+ if (!$error && $this->Review->saveField('editorreview', 1)) {
+ $this->publish('msg', ___('review_flag_success',
+ 'Thanks; this review has been flagged for editor approval.'));
+ } else {
+ if (!isset($this->viewVars['msg']))
+ $this->publish('msg', ___('review_flag_error',
+ 'Error flagging this review!'));
+ }
+
+ if (!$ajax) {
+ $review = $this->Review->findById($reviewid);
+ if (!empty($review)) {
+ $version = $this->Version->findById($review['Review']['version_id'], 'Version.addon_id');
+ $addon = $this->Addon->findById($version['Version']['addon_id']);
+ $this->publish('addon', $addon);
+ } else
+ $this->publish('addon', false);
+ $this->render();
+ } else {
+ if ($error) header('HTTP/1.1 400 Bad Request');
+ $this->render('flag', 'ajax');
+ }
+ }
+}
+
+?>
diff --git a/site/app/controllers/search_controller.php b/site/app/controllers/search_controller.php
new file mode 100644
index 0000000..65e8ebd
--- /dev/null
+++ b/site/app/controllers/search_controller.php
@@ -0,0 +1,301 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Wil Clouser <wclouser@mozilla.com> (Original Author)
+ * Cameron Roy <licensing@justcameron.com>
+ * Frederic Wenzel <fwenzel@mozilla.com>
+ * Chris Pollett <cpollett@gmail.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+uses('sanitize');
+
+class SearchController extends AppController
+{
+
+ /**
+ * Cake Requirement for php4
+ * @var
+ */
+ var $name = 'Search';
+
+ /**
+ * Cake array for what tables this controller accesses
+ */
+ var $uses = array('Addon', 'Addontype', 'Collection', 'File', 'Translation', 'Platform', );
+ var $beforeFilter = array('checkCSRF', 'getNamedArgs', '_checkSandbox', 'checkAdvancedSearch');
+
+ /**
+ * Holds the sanitize component, used to clean variables in our custom queries
+ * @var object
+ */
+ var $Sanitize;
+
+ // helper for javascript links
+ var $helpers = array('Javascript', 'Pagination', 'Time');
+
+ // components to be used by this controller
+ var $components = array('Image', 'Pagination', 'Search', "Versioncompare", "Amo", "CollectionsListing");
+
+ // view layout
+ var $layout = 'mozilla';
+
+ var $securityLevel = 'low';
+
+ /**
+ * Constructor. Declared so we can initialize Sanitize.
+ *
+ */
+ function SearchController() {
+
+ parent::__construct();
+
+ $this->Sanitize = new Sanitize();
+ }
+
+ function beforeFilter() {
+
+ $this->forceShadowDb();
+
+ // Disable ACLs because this controller is entirely public.
+ $this->SimpleAuth->enabled = false;
+ $this->SimpleAcl->enabled = false;
+
+ // If search is disabled, show appropriate error
+ if ($this->Config->getValue('search_disabled') == 1
+ && !$this->SimpleAcl->actionAllowed('*', '*', $this->Session->read('User'))) {
+
+ $this->flash(_('search_disabled'), '/', 3);
+ exit;
+ }
+ }
+
+ function index() {
+ global $valid_status, $app_shortnames;
+ if (!empty($this->params['url']['q'])) {
+ $_terms = $this->params['url']['q'];
+ } else {
+ $_terms = '';
+ }
+ $this->publish('search_terms', $_terms);
+
+ //if advanced search appid set, use it
+ $appname = "";
+ if (isset( $this->params['url']['appid']) &&
+ in_array($this->params['url']['appid'], array_values($app_shortnames) ) ) {
+ $appname = array_search($this->params['url']['appid'], $app_shortnames);
+ $redirect = str_replace(APP_SHORTNAME, $appname, $_SERVER['REQUEST_URI']);
+
+ if($this->params['url']['appid'] != APP_ID) { $this->redirect("http://".$_SERVER["HTTP_HOST"].$redirect, null, true); }
+ }
+ $this->publish('appid', APP_ID); //publish for element caching
+
+ // collection search is a special case
+ if (!empty($this->params['url']['cat']) && ($this->params['url']['cat'] == 'collections')) {
+ $this->_collections($_terms);
+ return;
+ }
+
+ if (!empty($this->params['url']['cat'])) {
+ $category = explode(',', $this->params['url']['cat']);
+ if (count($category) != 2 || !is_numeric($category[0]) ||
+ !is_numeric($category[1]))
+ $category = array(0,0);
+ } else
+ $category = array(0,0);
+ $this->publish('category', $category);
+
+ //if advanced search atype set, use it.
+ $atype = -1;
+ $addon_types = $this->Addontype->getNames();
+ if (isset($this->params['url']['atype']) &&
+ in_array($this->params['url']['atype'], array_keys($addon_types))) { $atype = $this->params['url']['atype']; }
+ $this->publish('atype', $atype); //publish for element caching
+
+ //if advanced search pid (platform id) set, use it.
+ $pid = -1;
+ $platforms = $this->Amo->getPlatformName();
+ if (isset( $this->params['url']['pid']) &&
+ in_array($this->params['url']['pid'], array_keys($platforms))) { $pid = $this->params['url']['pid']; }
+ $this->publish('pid', $pid); //publish for element caching
+
+ //if advanced search last update requirement set, use it
+ $lup = "";
+ $updates = array('- INTERVAL 1 DAY', '- INTERVAL 1 WEEK', '- INTERVAL 1 MONTH', '- INTERVAL 3 MONTH', '- INTERVAL 6 MONTH', '- INTERVAL 1 YEAR');
+
+ if (isset( $this->params['url']['lup']) &&
+ in_array($this->params['url']['lup'], $updates) ) { $lup = $this->params['url']['lup']; }
+ $this->publish('lup', $lup); //publish for element caching
+
+ //if advanced search sort_order set, use it
+ $sort = "";
+ $sort_orders = array('newest', 'name', 'averagerating', 'weeklydownloads');
+ if (isset( $this->params['url']['sort']) &&
+ in_array($this->params['url']['sort'], $sort_orders) ) { $sort = $this->params['url']['sort']; }
+ $this->publish('sort', $sort); //publish for element caching
+
+ //if advanced search hver and lver set (for version range), use the
+ $hver = 'any';
+ $lver = -1;
+ $vfuz = false;
+ if (isset($this->params['url']['lver']) && isset( $this->params['url']['hver']) && isset( $this->params['url']['vfuz'])) {
+ $hver = $this->params['url']['hver'];
+ $lver = $this->params['url']['lver'];
+ $vfuz = $this->params['url']['vfuz'];
+ }
+ $this->publish('hver', $hver); //publish for element caching
+ $this->publish('lver', $lver);
+ $this->publish('vfuz', $vfuz);
+
+ // execute this search
+ $_result_ids = $this->Search->search($_terms, $category[0], $category[1], NULL, $lver, $hver, $vfuz, $atype, $pid, $lup, $sort);
+
+ if ($this->params['action'] != 'rss') {
+ $this->pageTitle = _('search_pagetitle').' :: '.sprintf(_('addons_home_pagetitle'), APP_PRETTYNAME);
+ $this->publish('cssAdd', array('forms'));
+ $this->params['url']['q'] = urlencode( $this->params['url']['q']);
+
+ $this->Pagination->total = count($_result_ids);
+
+ //if advanced search pagination set, use it.
+ $pp= 20;
+ if (isset( $this->params['url']['pp']) && in_array($this->params['url']['pp'], $this->Pagination->resultsPerPage)) {
+ $pp = $this->Pagination->show = $this->params['url']['pp'];
+ }
+ $this->publish('pp', $pp); //publish for element caching
+
+ list($order,$limit,$page) = $this->Pagination->init();
+
+ // cut the appropriate slice out of the results array
+ $offset = ($page-1)*$limit;
+ $_result_ids = array_slice($_result_ids, $offset, $limit);
+
+ if (!empty($_terms)) {
+ $rssurl = '/search/rss/?q='.urlencode($_terms);
+ $this->publish('rssAdd', array($rssurl));
+ $this->publish('bookmark_url', $rssurl);
+ }
+
+ if (!empty($_result_ids)) {
+ $results = $this->Addon->getListAddons($_result_ids, $valid_status,
+ 'FIELD(Addon.id,'.implode(',', $_result_ids).')', true);
+ } else {
+ $results = array();
+ }
+
+ $this->publish('bigHeader', true);
+ $this->publish('bigHeaderText', sprintf(_('addons_home_header_details'), APP_PRETTYNAME));
+ // Collapse categories menu, unless no results were found
+ $this->publish('collapse_categories', !empty($results));
+
+ /* pull in platforms for install button */
+ $this->Platform->unbindFully();
+ $platforms = $this->Platform->findAll();
+ $this->publish('platforms', $platforms);
+
+ $this->publish('search_results', $results);
+ $this->forceCache();
+ $this->render();
+ return;
+
+ } else {
+ if (!empty($_result_ids)) {
+ $_search_ids = array_slice($_result_ids, 0, 20);
+ $results = $this->Addon->getListAddons($_search_ids, $valid_status,
+ 'FIELD(Addon.id,'.implode(',', $_search_ids).')');
+ } else {
+ $results = array();
+ }
+ $this->publish('search_results', $results);
+ $this->publish('rss_title', sprintf(_('search_rss_results_for'), $_terms));
+ $this->publish('rss_description', _('search_rss_description'));
+ $this->render('rss/index', 'rss');
+ return;
+ }
+
+
+ }
+
+ /**
+ * Show RSS feed for given search
+ */
+ function rss() {
+ return $this->index(); // let index handle rss action
+ }
+
+
+ /**
+ * Search collections
+ */
+ function _collections($terms = '') {
+ //search
+ $_result_ids = $this->Search->searchCollections($terms);
+
+ //if advanced search pagination set, use it.
+ $pp = 10;
+ if (isset( $this->params['url']['pp']) && in_array($this->params['url']['pp'], $this->Pagination->resultsPerPage)) {
+ $pp = $this->params['url']['pp'];
+ }
+ $this->publish('pp', $pp); //publish for element caching
+
+ // Fetch a sorted page of collections
+ $page_options = array('show' => $pp);
+ $collections = $this->CollectionsListing->fetchPage($_result_ids, $page_options);
+
+ // Our view needs the current sort options
+ list($sort_opts, $sortby) = $this->CollectionsListing->sorting();
+
+ // Prep and render the view
+ $this->pageTitle = ___('search_collections_pagetitle', 'Collection Search Results').' :: '.sprintf(_('addons_home_pagetitle'), APP_PRETTYNAME);
+
+ $this->publish('jsAdd', array('amo2009/collections', 'jquery-ui/jqModal.js'));
+ $this->publish('breadcrumbs', array(
+ sprintf(___('addons_home_pagetitle'), APP_PRETTYNAME) => '/',
+ ___('collections_breadcrumb') => '/collections'
+ ));
+
+ $this->publish('collapse_categories', true);
+ $this->publish('collectionSearch', true);
+ $this->publish('query', $terms);
+ $this->publish('sort_opts', $sort_opts);
+ $this->publish('sortby', $sortby);
+ $this->publish('collections', $collections);
+ $this->forceCache();
+ $this->render('collections');
+ return;
+ }
+
+}
+
+?>
diff --git a/site/app/controllers/sharing_api_controller.php b/site/app/controllers/sharing_api_controller.php
new file mode 100644
index 0000000..5832401
--- /dev/null
+++ b/site/app/controllers/sharing_api_controller.php
@@ -0,0 +1,1517 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * l.m.orchard <lorchard@mozilla.com> (Original Author)
+ * Frederic Wenzel <fwenzel@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+uses('sanitize');
+
+/**
+ * Controller implementing addon sharing API
+ * see: https://wiki.mozilla.org/User:LesOrchard/BandwagonAPI
+ */
+class SharingApiController extends AppController
+{
+ var $name = 'SharingApi';
+
+ // bump for new releases
+ // 0 or unspecified is for Fx3b3
+ // 0.9 is for Fx3b4
+ var $newest_api_version = 1.4;
+
+ var $beforeFilter = array(
+ '_checkSandbox'
+ );
+ var $uses = array(
+ 'Addon', 'AddonCollection', 'Addontype', 'ApiAuthToken',
+ 'Application', 'Collection', 'File', 'Platform', 'Tag', 'Translation',
+ 'UpdateCount', 'Version'
+ );
+ var $components = array(
+ 'Amo', 'Developers', 'Email', 'Image', 'Pagination', 'Search', 'Session',
+ 'Versioncompare'
+ );
+ var $helpers = array(
+ 'Html', 'Link', 'Time', 'Localization', 'Ajax', 'Number',
+ 'Pagination'
+ );
+
+ var $securityLevel = 'low';
+
+ const STATUS_OK = '200 OK';
+ const STATUS_CREATED = '201 Created';
+ const STATUS_ACCEPTED = '202 Accepted';
+ const STATUS_FOUND = '302 Found';
+ const STATUS_SEE_OTHER = '303 See Other';
+ const STATUS_NOT_MODIFIED = '304 Not Modified';
+ const STATUS_BAD_REQUEST = '400 Bad Request';
+ const STATUS_UNAUTHORIZED = '401 Unauthorized';
+ const STATUS_FORBIDDEN = '403 Forbidden';
+ const STATUS_NOT_FOUND = '404 Not Found';
+ const STATUS_METHOD_NOT_ALLOWED = '405 Method Not Allowed';
+ const STATUS_CONFLICT = '409 Conflict';
+ const STATUS_GONE = '410 Gone';
+ const STATUS_UNSUPPORTED_MEDIA = '415 Unsupported Media Type';
+ const STATUS_ERROR = '500 Internal Server Error';
+
+ var $cache_lifetime = 10; // 10 seconds
+
+ function forceCache() {
+ header('Cache-Control: public, max-age=' . $this->cache_lifetime);
+ header('Last-Modified: ' . gmdate("D, j M Y H:i:s", $this->last_modified) . " GMT");
+ header('Expires: ' . gmdate("D, j M Y H:i:s", $this->last_modified + $this->cache_lifetime) . " GMT");
+ }
+
+ function beforeFilter() {
+ Configure::write('Session.checkAgent', false);
+
+ $this->last_modified = time();
+
+ $this->layout = 'rest';
+
+ $this->forceShadowDb();
+
+ // HACK: No cache invalidation on write, so disable caching on these
+ // models for now.
+ $this->Collection->caching = false;
+ $this->AddonCollection->caching = false;
+ $this->User->caching = false;
+ $this->ApiAuthToken->caching = false;
+
+ $this->SimpleAuth->enabled = false;
+ $this->SimpleAcl->enabled = false;
+
+ // extract API version
+ $url = $_SERVER['REQUEST_URI'];
+
+ $matches = array();
+ if (preg_match('/api\/([\d\.]*)\//', $url, $matches)) {
+ $this->api_version = $matches[1];
+ if (!is_numeric($this->api_version)) {
+ $this->api_version = $this->newest_api_version;
+ }
+ } else {
+ // nothing supplied: assume Fx3b3
+ $this->api_version = 0;
+ }
+
+ // set up translation table for os names
+ // this is hardcoded in
+ $this->os_translation = array(
+ 'ALL' => 'ALL',
+ 'bsd' => 'BSD_OS',
+ 'BSD' => 'BSD_OS',
+ 'Linux' => 'Linux',
+ 'macosx' => 'Darwin',
+ 'MacOSX' => 'Darwin',
+ 'Solaris' => 'SunOS',
+ 'win' => 'WINNT',
+ 'Windows' => 'WINNT',
+ );
+
+ // Establish a base URL for this request.
+ $this->base_url = ( empty($_SERVER['HTTPS']) ? 'http' : 'https' ) .
+ '://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
+ if ( ($qpos = strpos($this->base_url, '?')) !== FALSE) {
+ // Toss out any query parameters.
+ $this->base_url = substr($this->base_url, 0, $qpos);
+ }
+ $this->publish('base_url', $this->base_url);
+
+ $pos = strpos($this->base_url, 'api/');
+ $this->site_base_url = substr($this->base_url, 0, $pos);
+ $this->publish('site_base_url', $this->site_base_url);
+
+ // Attempt to get an auth user.
+ $this->auth_user = $this->getAuthUser();
+ if (!$this->auth_user) {
+ header('HTTP/1.1 401 Unauthorized');
+ header('WWW-Authenticate: Basic realm="AMO"');
+ $this->publish('reason', 'unauthorized');
+ $this->publish('href', $this->base_url . 'auth');
+ $this->render('error');
+ exit();
+ }
+ $this->publish('auth_user', $this->auth_user);
+ }
+
+ /**
+ * Service doc resource dispatch
+ */
+ function service_doc() {
+ $args = func_get_args();
+ return $this->dispatchHttpMethod(array(
+ 'GET' => 'service_doc_GET',
+ ), $args);
+ }
+
+ /**
+ * Service doc resource
+ */
+ function service_doc_GET($context) {
+ extract($context);
+
+ $this->User->bindModel(array(
+ 'hasAndBelongsToMany' => array(
+ 'Collections' =>
+ $this->User->hasAndBelongsToMany_full['Collections'],
+ 'CollectionSubscriptions' =>
+ $this->User->hasAndBelongsToMany_full['CollectionSubscriptions'],
+ )
+ ));
+ $user = $this->User->findById($this->auth_user['id']);
+
+ $collection_ids = array();
+ foreach ($user['Collections'] as $row)
+ $collection_ids[$row['id']] = 1;
+ foreach ($user['CollectionSubscriptions'] as $row)
+ $collection_ids[$row['id']] = 1;
+ $collection_ids = array_keys($collection_ids);
+
+ // Collect last-modified times for collections known to the user.
+ $modifieds = array();
+ foreach ($collection_ids as $id)
+ $modifieds[] =
+ $this->Collection->getLastModifiedForCollection($id);
+
+ if (!empty($modifieds)) {
+ // Set last-modified to newest stamp available.
+ rsort($modifieds);
+ $this->last_modified = $modifieds[0];
+ if ($this->isNotModifiedSince()) return;
+ }
+
+ $collections = $this->publishCollections(
+ 'collections', $collection_ids
+ );
+ }
+
+ /**
+ * Dispatcher for collections resource.
+ */
+ function collections() {
+ $args = func_get_args();
+ return $this->dispatchHttpMethod(array(
+ 'POST' => 'collections_POST'
+ ), $args);
+ }
+
+ /**
+ * Create a collection
+ */
+ function collections_POST($context) {
+ global $app_shortnames;
+
+ extract($context);
+
+ $params = $this->getParams(array(
+ 'name' => '',
+ 'description' => '',
+ 'nickname' => '',
+ 'type' => 'autopublisher',
+ 'app' => 'firefox',
+ 'listed' => 1
+ ));
+
+ // Convert from a type name to a type constant.
+ switch ($params['type']) {
+ case 'normal':
+ $type = Collection::COLLECTION_TYPE_NORMAL; break;
+ case 'editorspick':
+ $type = Collection::COLLECTION_TYPE_EDITORSPICK; break;
+ case 'autopublisher':
+ default:
+ $type = Collection::COLLECTION_TYPE_AUTOPUBLISHER; break;
+ };
+
+ // Convert app name to a constant
+ if (!empty($app_shortnames[$params['app']])) {
+ $appid = $app_shortnames[$params['app']];
+ } else {
+ $appid = APP_FIREFOX;
+ }
+
+ $data = array(
+ 'Collection' => array(
+ 'name' => $params['name'],
+ 'description' => $params['description'],
+ 'nickname' => $params['nickname'],
+ 'collection_type' => $type,
+ 'application_id' => $appid,
+ 'listed' =>
+ ($params['listed'] === '1' || $params['listed'] == 'yes') ?
+ 1 : 0
+ )
+ );
+ $this->Amo->clean($data);
+
+ // handle icon upload
+ if (!empty($_FILES['icon']['name'])) {
+ $iconData = $this->Developers->validateIcon($_FILES['icon']);
+ if (is_array($iconData)) {
+ $data['Collection'] = array_merge($data['Collection'], $iconData);
+ }
+ }
+
+ if (!$this->Collection->validates($data) ||
+ !$this->Collection->save($data)) {
+ $invalid = $this->Collection->invalidFields();
+ return $this->renderStatus(
+ self::STATUS_BAD_REQUEST, 'error',
+ array(
+ 'reason' => 'invalid_parameters',
+ 'details' => join(',', array_keys($invalid))
+ )
+ );
+ }
+
+ $new_collection = $this->Collection->findById($this->Collection->id);
+
+ // Make the auth user owner of this new collection.
+ $this->Collection->addUser(
+ $new_collection['Collection']['id'], $this->auth_user['id'], COLLECTION_ROLE_OWNER
+ );
+
+ $new_url = ( empty($_SERVER['HTTPS']) ? 'http' : 'https' ) .
+ '://' . $_SERVER['HTTP_HOST'] .
+ $this->resolveUrl($_SERVER['REQUEST_URI'], $new_collection['Collection']['uuid'].'/');
+ $this->publish('base_url', $new_url);
+
+ $collections = $this->publishCollections(
+ 'collections', array( $new_collection['Collection']['id'] ), true
+ );
+ return $this->renderStatus(
+ self::STATUS_CREATED, 'collection_detail', array(), $new_url
+ );
+ }
+
+ /**
+ * Dispatcher for collection detail resource.
+ */
+ function collection_detail($uuid) {
+
+ // Attempt to set the last-modified header, throwing a 404 if no
+ // last-modified could be found.
+ $this->last_modified =
+ $this->Collection->getLastModifiedForCollection(null, $uuid);
+ if (null === $this->last_modified) {
+ return $this->renderStatus(
+ self::STATUS_NOT_FOUND, 'error',
+ array('reason' => 'collection_unknown')
+ );
+ }
+ if ($this->isNotModifiedSince()) return;
+
+ // Try to find the collection by the ID in the URL. Kick out a 404
+ // error if not found.
+ $collection = $this->Collection->findByUuid($uuid);
+ if (empty($collection)) {
+ return $this->renderStatus(
+ self::STATUS_NOT_FOUND, 'error',
+ array('reason' => 'collection_unknown')
+ );
+ }
+
+ $writable = $this->Collection->isWritableByUser(
+ $collection['Collection']['id'], $this->auth_user['id']
+ );
+ $method = $this->getHttpMethod();
+ if (('PUT' !== $method) && $this->isWriteHttpMethod()) {
+ if (!$writable) {
+ return $this->renderStatus(
+ self::STATUS_FORBIDDEN, 'error',
+ array('reason' => 'not_writable')
+ );
+ }
+ }
+
+ $args = func_get_args();
+ return $this->dispatchHttpMethod(
+ array(
+ 'GET' => 'collection_detail_GET',
+ 'PUT' => 'collection_detail_PUT',
+ 'DELETE' => 'collection_detail_DELETE'
+ ),
+ $args,
+ compact('collection', 'writable')
+ );
+ }
+
+ /**
+ * Produce collection details.
+ */
+ function collection_detail_GET($context, $uuid) {
+ extract($context);
+
+ $collections = $this->publishCollections(
+ 'collections', array( $collection['Collection']['id'] ), true
+ );
+ }
+
+ /**
+ * Update details in a collection.
+ */
+ function collection_detail_PUT($context) {
+ extract($context);
+
+ $params = $this->getParams(array(
+ 'name' => $collection['Translation']['name']['string'],
+ 'description' => $collection['Translation']['description']['string'],
+ 'nickname' => $collection['Collection']['nickname'],
+ 'listed' => $collection['Collection']['listed'],
+ 'subscribed' => NULL
+ ));
+
+ // Whether the user can write to this collection in general, they
+ // should be able to modify their own subscription status...
+ switch ($params['subscribed']) {
+
+ case 'yes':
+ // Subscribe the user to the collection on subscribed=yes
+ $this->Collection->subscribe(
+ $collection['Collection']['id'],
+ $this->auth_user['id']
+ );
+ break;
+
+ case 'no':
+ // Unsubscribe the user from the collection on subscribed=no
+ $this->Collection->unsubscribe(
+ $collection['Collection']['id'],
+ $this->auth_user['id']
+ );
+ break;
+
+ case NULL:
+ default:
+ // If this collection is not writable, the user has no business
+ // trying to change anything beyond the subscribed flag.
+ if (!$writable) {
+ return $this->renderStatus(
+ self::STATUS_FORBIDDEN, 'error',
+ array('reason' => 'not_writable')
+ );
+ }
+ break;
+
+ }
+
+ if ($writable) {
+ // Beyond subscription changes above, accept further changes to
+ // collection if the user is allowed.
+
+ $data = array(
+ 'Collection' => array(
+ 'id' => $collection['Collection']['id'],
+ 'name' => $params['name'],
+ 'description' => $params['description'],
+ 'nickname' => $params['nickname'],
+ 'listed' => ($params['listed'] === '1' || $params['listed'] == 'yes') ? 1 : 0
+ )
+ );
+ $this->Amo->clean($data);
+
+ if (!$this->Collection->validates($data) ||
+ !$this->Collection->save($data)) {
+ $invalid = $this->Collection->invalidFields();
+ return $this->renderStatus(
+ self::STATUS_BAD_REQUEST, 'error',
+ array(
+ 'reason' => 'invalid_parameters',
+ 'details' => join(',', array_keys($invalid))
+ )
+ );
+ }
+
+ }
+
+ $collections = $this->publishCollections(
+ 'collections', array( $collection['Collection']['id'] ), true
+ );
+ }
+
+ /**
+ * Delete a collection.
+ */
+ function collection_detail_DELETE($context, $uuid) {
+ extract($context);
+ $this->Collection->del($collection['Collection']['id']);
+ return $this->renderStatus(self::STATUS_GONE, 'empty');
+ }
+
+ /**
+ * Dispatcher for collection detail resource.
+ */
+ function collection_addons($uuid) {
+
+ // Try to find the collection by the ID in the URL. Kick out a 404
+ // error if not found.
+ $collection = $this->Collection->findByUuid($uuid);
+ if (empty($collection)) {
+ return $this->renderStatus(
+ self::STATUS_NOT_FOUND, 'error',
+ array('reason' => 'collection_unknown')
+ );
+ }
+
+ if ($this->isWriteHttpMethod()) {
+ $writable = $this->Collection->isWritableByUser(
+ $collection['Collection']['id'], $this->auth_user['id']
+ );
+ if (!$writable) {
+ return $this->renderStatus(
+ self::STATUS_FORBIDDEN, 'error',
+ array('reason' => 'not_writable')
+ );
+ }
+ }
+
+ $args = func_get_args();
+ return $this->dispatchHttpMethod(
+ array(
+ 'POST' => 'collection_addons_POST'
+ ),
+ $args,
+ compact('collection')
+ );
+ }
+
+ /**
+ * Produce collection details.
+ */
+ function collection_addons_POST($context, $uuid) {
+ extract($context);
+
+ $params = $this->getParams(array(
+ 'guid' => '',
+ 'comments' => ''
+ ));
+
+ // Look for the addon, throwing an error if there's none found.
+ $addon = $this->Addon->findByGuid($params['guid']);
+ if (empty($addon)) {
+ return $this->renderStatus(
+ self::STATUS_BAD_REQUEST, 'error',
+ array('reason' => 'unknown_addon_guid')
+ );
+ }
+
+ // Check to see if this addon already exists in the collection, and
+ // throw an error if so.
+ $added = $this->AddonCollection->find(array(
+ 'AddonCollection.collection_id' =>
+ $collection['Collection']['id'],
+ 'AddonCollection.addon_id' =>
+ $addon['Addon']['id'],
+ ), null, null, 1);
+ if (!empty($added)) {
+ return $this->renderStatus(
+ self::STATUS_CONFLICT, 'error',
+ array('reason' => 'addon_already_in_collection')
+ );
+ }
+
+ // Build the fields for adding the addon to the collection.
+ $data = array(
+ 'AddonCollection' => array(
+ 'collection_id' => $collection['Collection']['id'],
+ 'user_id' => $this->auth_user['id'],
+ 'addon_id' => $addon['Addon']['id'],
+ 'added' => date('c'),
+ 'comments' => $params['comments']
+ )
+ );
+ $this->Amo->clean($data);
+
+ // Validate the fields.
+ if (!$this->AddonCollection->validates($data)) {
+ $invalid = $this->AddonCollection->invalidFields();
+ return $this->renderStatus(
+ self::STATUS_BAD_REQUEST, 'error',
+ array(
+ 'reason' => 'invalid_parameters',
+ 'details' => join(',', array_keys($invalid))
+ )
+ );
+ }
+
+ // Finally, try adding the addon.
+ if (!$this->AddonCollection->save($data)) {
+ $invalid = $this->AddonCollection->invalidFields();
+ return $this->renderStatus(
+ self::STATUS_BAD_REQUEST, 'error',
+ array(
+ 'reason' => 'invalid_parameters',
+ 'details' => join(',', array_keys($invalid))
+ )
+ );
+ }
+
+ // Build the URL where the new addon can be found in the collection and
+ // return it.
+ $new_url = ( empty($_SERVER['HTTPS']) ? 'http' : 'https' ) .
+ '://' . $_SERVER['HTTP_HOST'] .
+ $this->resolveUrl(
+ $_SERVER['REQUEST_URI'],
+ rawurlencode($addon['Addon']['guid'])
+ );
+ $this->publish('base_url', $new_url);
+
+ $addons = $this->getCollectionAddonsForView(
+ $collection['Collection']['id'], $addon['Addon']['id']
+ );
+ $this->publish('addon', $addons[0]);
+
+ return $this->renderStatus(
+ self::STATUS_CREATED, 'addon', array(), $new_url
+ );
+ }
+
+ /**
+ * Dispatcher for collection detail resource.
+ */
+ function collection_addon_detail($collection_uuid, $addon_guid) {
+
+ // Try to find the collection by the ID in the URL. Kick out a 404
+ // error if not found.
+ $collection = $this->Collection->findByUuid($collection_uuid);
+ if (empty($collection)) {
+ return $this->renderStatus(
+ self::STATUS_NOT_FOUND, 'error',
+ array('reason' => 'collection_unknown')
+ );
+ }
+
+ $addon = $this->Addon->findByGuid($addon_guid);
+ $addon_collection = $this->AddonCollection->find(array(
+ 'AddonCollection.collection_id' => $collection['Collection']['id'],
+ 'AddonCollection.addon_id' => $addon['Addon']['id']
+ ));
+ if (empty($addon_collection)) {
+ return $this->renderStatus(
+ self::STATUS_NOT_FOUND, 'error',
+ array('reason' => 'addon_not_in_collection')
+ );
+ }
+
+ $this->last_modified =
+ strtotime($addon_collection['AddonCollection']['modified']);
+ if ($this->isNotModifiedSince()) return;
+
+ // Enforce role access for write HTTP methods.
+ if ($this->isWriteHttpMethod()) {
+ $writable = $this->Collection->isWritableByUser(
+ $collection['Collection']['id'], $this->auth_user['id']
+ );
+ if (!$writable) {
+ return $this->renderStatus(
+ self::STATUS_FORBIDDEN, 'error',
+ array('reason' => 'not_writable')
+ );
+ }
+ }
+
+ $args = func_get_args();
+ return $this->dispatchHttpMethod(
+ array(
+ 'GET' => 'collection_addon_detail_GET',
+ 'PUT' => 'collection_addon_detail_PUT',
+ 'DELETE' => 'collection_addon_detail_DELETE'
+ ),
+ $args,
+ compact('collection', 'addon', 'addon_collection')
+ );
+ }
+
+ /**
+ * Get details on a single addon in a collection.
+ */
+ function collection_addon_detail_GET($context, $collection_uuid, $addon_guid) {
+ extract($context);
+
+ $addons = $this->getCollectionAddonsForView(
+ $collection['Collection']['id'], $addon['Addon']['id']
+ );
+ $this->publish('addon', $addons[0]);
+ return $this->render('addon');
+ }
+
+ /**
+ * Update details for an addon in a collection
+ */
+ function collection_addon_detail_PUT($context, $collection_uuid, $addon_guid) {
+ extract($context);
+
+ $params = $this->getParams(array(
+ 'comments' => $addon_collection['AddonCollection']['comments']
+ ));
+
+ // HACK: Re-add the addon after deletion, because it's the easiest way
+ // to re-trigger the translated fields update.
+ $this->AddonCollection->deleteByAddonIdAndCollectionId(
+ $addon['Addon']['id'], $collection['Collection']['id']
+ );
+ $data = array(
+ 'AddonCollection' => array(
+ 'collection_id' => $collection['Collection']['id'],
+ 'user_id' => $this->auth_user['id'],
+ 'addon_id' => $addon['Addon']['id'],
+ 'added' => $addon_collection['AddonCollection']['added'],
+ 'comments' => $params['comments']
+ )
+ );
+ $this->Amo->clean($data);
+ $this->AddonCollection->save($data);
+
+ // Finally, render the addon with changes.
+ $addons = $this->getCollectionAddonsForView(
+ $collection['Collection']['id'], $addon['Addon']['id']
+ );
+ $this->publish('addon', $addons[0]);
+ return $this->render('addon');
+ }
+
+ /**
+ * Delete an addon from a collection.
+ */
+ function collection_addon_detail_DELETE($context, $collection_uuid, $addon_guid) {
+ extract($context);
+ $this->AddonCollection->deleteByAddonIdAndCollectionId(
+ $addon['Addon']['id'], $collection['Collection']['id']
+ );
+ return $this->renderStatus(self::STATUS_GONE, 'empty');
+ }
+
+ /**
+ * Dispatcher for email notification resource.
+ */
+ function email() {
+ $args = func_get_args();
+ return $this->dispatchHttpMethod(array(
+ 'POST' => 'email_POST'
+ ), $args);
+ }
+
+ /**
+ * Email recommendations
+ */
+ function email_POST($context) {
+ extract($context);
+
+ $params = $this->getParams(array(
+ 'to' => NULL,
+ 'guid' => NULL,
+ 'message' => ''
+ ));
+
+ // Gripe if no email addresses supplied.
+ if (empty($params['to'])) {
+ return $this->renderStatus(
+ self::STATUS_BAD_REQUEST, 'error',
+ array(
+ 'reason' => 'invalid_parameters',
+ 'details' => 'to'
+ )
+ );
+ }
+
+ // Split up and validate comma-separated email addresses.
+ $emails = array();
+ $parts = explode(',', $params['to']);
+ foreach ($parts as $em) {
+ $em = trim($em);
+ if (preg_match(VALID_EMAIL, $em) === 0) {
+ return $this->renderStatus(
+ self::STATUS_BAD_REQUEST, 'error',
+ array(
+ 'reason' => 'invalid_parameters',
+ 'details' => 'to['.$em.']'
+ )
+ );
+ }
+ $emails[] = $em;
+ }
+
+ // Look for the addon, throwing an error if there's none found.
+ $addon = $this->Addon->findByGuid($params['guid']);
+ if (empty($addon)) {
+ return $this->renderStatus(
+ self::STATUS_BAD_REQUEST, 'error',
+ array('reason' => 'unknown_addon_guid')
+ );
+ }
+ $this->publish('addon', $addon, false);
+
+ $senderemail = $this->auth_user['email'];
+ $this->set('senderemail', $senderemail);
+
+ // Send recommendation email(s)
+ $this->publish('message', $params['message'], false);
+ $this->Email->fromName = null;
+ $this->Email->from = $senderemail;
+ $this->Email->sender = '"Mozilla Add-ons" <nobody@mozilla.org>';
+ $this->Email->template = 'email/recommend_email';
+ $this->Email->subject = sprintf('%1$s recommends %2$s',
+ $this->auth_user['email'], $addon['Translation']['name']['string']);
+
+ foreach ($emails as $em) {
+ $this->Email->to = $em;
+ $result = $this->Email->send();
+ }
+
+ // save stats
+ $this->Addon->increaseShareCount($addon['Addon']['id'], count($emails));
+
+ return $this->renderStatus(
+ self::STATUS_ACCEPTED, 'empty', array()
+ );
+ }
+
+ /**
+ * Dispatcher for auth token resource.
+ */
+ function auth() {
+ $args = func_get_args();
+ return $this->dispatchHttpMethod(array(
+ 'POST' => 'auth_POST'
+ ), $args);
+ }
+
+ /**
+ * Generate a new auth token for the authenticated user.
+ */
+ function auth_POST($context) {
+ extract($context);
+
+ $data = array(
+ 'ApiAuthToken' => array(
+ 'user_id' => $this->auth_user['id']
+ )
+ );
+ $this->Amo->clean($data);
+ $this->ApiAuthToken->save($data);
+
+ $new_token = $this->ApiAuthToken->findById($this->ApiAuthToken->id);
+ $token_value = $new_token['ApiAuthToken']['token'];
+ $token_url = $this->base_url . '/' . $token_value;
+
+ return $this->renderStatus(
+ self::STATUS_CREATED, 'auth_token', array(
+ 'value' => $token_value,
+ 'url' => $token_url
+ ), $token_url
+ );
+ }
+
+ /**
+ * Dispatcher for auth token detail resource.
+ */
+ function auth_detail($token) {
+ $args = func_get_args();
+ return $this->dispatchHttpMethod(array(
+ 'DELETE' => 'auth_detail_DELETE'
+ ), $args);
+ }
+
+ /**
+ * Delete an existing token, rendering it unusable in the future. (eg. for
+ * logout)
+ */
+ function auth_detail_DELETE($context, $token) {
+ extract($context);
+
+ $rv = $this->ApiAuthToken->deleteByUserIdAndToken(
+ $this->auth_user['id'], $token
+ );
+
+ if ($rv) {
+ return $this->renderStatus(self::STATUS_GONE, 'empty');
+ } else {
+ return $this->renderStatus(
+ self::STATUS_NOT_FOUND, 'error',
+ array('reason' => 'token_unknown')
+ );
+ }
+ }
+
+ /**
+ * Prepare a set of rows from the Collection model for use by the view.
+ *
+ * @param string View variable name
+ * @param array Authenticated user details
+ * @param array Rows from the Collection model
+ * @return array Collection details published to view.
+ */
+ function publishCollections($name, $collection_ids, $addons_detail=FALSE) {
+ global $app_shortnames;
+
+ // Minimize the amount of data pulled back.
+ $this->Collection->unbindFully();
+
+ if ($addons_detail) {
+ // If addons detail was requested, add a binding for Addons.
+ $this->Collection->bindModel(array(
+ 'hasAndBelongsToMany' => array(
+ 'Addon' =>
+ $this->Collection->hasAndBelongsToMany_full['Addon']
+ )
+ ));
+ }
+
+ // Assemble IDs for the user's subscriptions for use in detecting
+ // subscriptions in the collection set.
+ $subs = $this->User->getSubscriptions($this->auth_user['id']);
+ $sub_ids = array();
+ foreach ($subs as $sub)
+ $sub_ids[] = $sub['Collection']['id'];
+
+ $collections_out = array();
+ $collection_rows = $this->Collection->findAllById($collection_ids);
+
+ foreach ($collection_rows as $row) {
+
+ // Come up with values for collection status flags
+ $listed = $row['Collection']['listed'];
+ $subscribed = in_array($row['Collection']['id'], $sub_ids);
+ $writable = $this->Collection->isWritableByUser(
+ $row['Collection']['id'], $this->auth_user['id']
+ );
+
+ // Try to look up the owner user for this collection and
+ // derive a name.
+ $owner_users = $this->Collection->getUsers(
+ $row['Collection']['id'], array( COLLECTION_ROLE_OWNER )
+ );
+ if (empty($owner_users)) {
+ $creator_name = '';
+ } else {
+ $u = $owner_users[0]['User'];
+ $creator_name = !empty($u['nickname']) ?
+ $u['nickname'] : "{$u['firstname']} {$u['lastname']}";
+ }
+
+ // Add a minimal set of details to the array for the view.
+ $c_data = array(
+ 'id' => $row['Collection']['id'],
+ 'uuid' => $row['Collection']['uuid'],
+ 'icon' => SITE_URL.$this->Image->getCollectionIconURL($row['Collection']['id']),
+ 'name' => $row['Translation']['name']['string'],
+ 'description' => $row['Translation']['description']['string'],
+ 'creator' => $creator_name,
+ 'app' => array_search($row['Collection']['application_id'], $app_shortnames),
+ 'listed' => ($listed) ? 'yes' : 'no',
+ 'writable' => ($writable) ? 'yes' : 'no',
+ 'subscribed' => ($subscribed) ? 'yes' : 'no',
+ 'lastmodified' =>
+ date('c', $this->Collection->getLastModifiedForCollection(
+ $row['Collection']['id']
+ ))
+ );
+
+ // Convert the collection type into a name.
+ switch (@$row['Collection']['collection_type']) {
+ case Collection::COLLECTION_TYPE_EDITORSPICK:
+ $c_data['type'] = 'editorspick'; break;
+ case Collection::COLLECTION_TYPE_AUTOPUBLISHER:
+ $c_data['type'] = 'autopublisher'; break;
+ case Collection::COLLECTION_TYPE_NORMAL:
+ default:
+ $c_data['type'] = 'normal'; break;
+ }
+
+ // If addon details were requested, look up and add the addons for
+ // this collection.
+ if ($addons_detail) {
+ $addon_ids = array();
+ foreach ($row['Addon'] as $addon_row)
+ $addon_ids[] = $addon_row['id'];
+ $c_data['addons'] = $this->getCollectionAddonsForView(
+ $row['Collection']['id'], $addon_ids
+ );
+ }
+
+ $collections_out[] = $c_data;
+ }
+
+ $this->publish($name, $collections_out);
+ return $collections_out;
+ }
+
+ /**
+ * Assemble view data for addons identified by ID
+ *
+ * @param array addon IDs
+ * @return array
+ */
+ function getCollectionAddonsForView($collection_id, $addon_ids) {
+
+ // Fetch the addons for the feed, first tearing down the model bindings
+ // and selectively rebuilding them.
+ $this->Addon->unbindFully();
+ $this->Addon->bindModel(array(
+ 'hasAndBelongsToMany' => array(
+ 'User' => array(
+ 'className' => 'User',
+ 'joinTable' => 'addons_users',
+ 'foreignKey' => 'addon_id',
+ 'associationForeignKey'=> 'user_id',
+ 'conditions' => 'addons_users.listed=1',
+ 'order' => 'addons_users.position'
+ ),
+ 'Tag' => array(
+ 'className' => 'Tag',
+ 'joinTable' => 'addons_tags',
+ 'foreignKey' => 'addon_id',
+ 'associationForeignKey'=> 'tag_id'
+ )
+ )
+ ));
+
+ $conditions = array(
+ 'Addon.id' => $addon_ids,
+ 'Addon.inactive' => 0,
+ 'Addon.addontype_id' => array(
+ ADDON_EXTENSION, ADDON_THEME, ADDON_DICT,
+ ADDON_SEARCH, ADDON_PLUGIN
+ )
+ );
+
+ $addons_data = $this->Addon->findAll($conditions);
+
+ // Rather than trying to join tags and addon types in SQL, collect IDs
+ // and make a pair of queries to fetch them.
+ $tag_ids = array();
+ $addon_type_ids = array();
+ $addon_ids = array();
+ foreach ($addons_data as $addon) {
+ $addon_ids[] = $addon['Addon']['id'];
+ $addon_type_ids[$addon['Addon']['addontype_id']] = true;
+ foreach ($addon['Tag'] as $tag)
+ $tag_ids[$tag['id']] = true;
+ }
+
+ $user_names = array();
+
+ $addon_collections = array();
+ $collection_rows = $this->AddonCollection->findAll(array(
+ 'AddonCollection.collection_id' => $collection_id,
+ 'AddonCollection.addon_id' => $addon_ids
+ ));
+ foreach ($collection_rows as $c) {
+ $user_id = $c['AddonCollection']['user_id'];
+ if (!isset($user_names[$user_id])) {
+ $user = $this->User->findById($user_id);
+ $user_names[$user_id] =
+ !empty($user['User']['nickname']) ?
+ $user['User']['nickname'] :
+ "{$user['User']['firstname']} {$user['User']['lastname']}";
+ }
+ $c['addedby'] = $user_names[$user_id];
+ $addon_collections[$c['AddonCollection']['addon_id']] = $c;
+ }
+
+ // Query for addon types found in this set of addons, assemble a map
+ // for an in-code join later.
+ $addon_type_rows = $this->Addontype->findAll(array(
+ 'Addontype.id' => array_keys($addon_type_ids)
+ ));
+ $addon_types = array();
+ foreach ($addon_type_rows as $row) {
+ $addon_types[$row['Addontype']['id']] = $row;
+ }
+
+ // Query for addon types found in this set of tags, assemble a map
+ // for an in-code join later.
+ $tag_rows = $this->Tag->findAll(array(
+ 'Tag.id' => array_keys($tag_ids)
+ ));
+ $all_tags = array();
+ foreach ($tag_rows as $row) {
+ $all_tags[$row['Tag']['id']] = $row;
+ }
+
+ $app_names = $this->Application->getIDList();
+ $guids = array_flip($this->Application->getGUIDList());
+
+ $collection = $this->Collection->findById($collection_id, 'uuid', null, null, -1);
+ $this->publish('collection_uuid', $collection['Collection']['uuid']);
+
+ $this->publish('app_names', $app_names);
+ $this->publish('guids', $guids);
+ $this->publish('ids', $addon_ids);
+ $this->publish('api_version', $this->api_version);
+ $this->publish('os_translation', $this->os_translation);
+
+ // Process addons list to produce a much flatter and more easily
+ // sanitized array structure for the view, sprinkling in details
+ // like tags and version information along the way.
+ $addons_out = array();
+ for ($i=0; $i<count($addons_data); $i++) {
+
+ $addon = $addons_data[$i];
+ $id = $addon['Addon']['id'];
+
+ $addontype_id = $addon['Addon']['addontype_id'];
+
+ // make sure reported latest version matches version of file
+ global $valid_status;
+ $install_version = $this->Version->getVersionByAddonId(
+ $addon['Addon']['id'], $valid_status
+ );
+
+ if (!isset($addon_collections[$id])) {
+ // Skip addons that were found yet somehow not a part of a
+ // collection.
+ continue;
+ }
+
+ // Start constructing a flat minimal list of addon details made up of only
+ // what the view will need.
+ $addon_out = array(
+ 'collection_added' =>
+ date('c', strtotime($addon_collections[$id]['AddonCollection']['added'])),
+ 'collection_addedby' =>
+ $addon_collections[$id]['addedby'],
+ 'collection_comments' =>
+ $addon_collections[$id]['Translation']['comments']['string'],
+ 'id' => $addon['Addon']['id'],
+ 'guid' => $addon['Addon']['guid'],
+ 'name' => $addon['Translation']['name']['string'],
+ 'summary' => $addon['Translation']['summary']['string'],
+ 'description' =>
+ $addon['Translation']['description']['string'],
+ 'addontype_id' => $addontype_id,
+ 'addontype_name' =>
+ $this->Addontype->getName($addontype_id),
+ 'icon' =>
+ $this->Image->getAddonIconURL($id),
+ 'thumbnail' =>
+ $this->Image->getHighlightedPreviewURL($id),
+ 'install_version' => $install_version,
+ 'status' => $addon['Addon']['status'],
+ 'users' => $addon['User'],
+ 'eula' => $addon['Translation']['eula']['string'],
+ 'averagerating' => $addon['Addon']['averagerating'],
+ 'tags' => array(),
+ 'compatible_apps' => array(),
+ 'all_compatible_os' => array(),
+ 'fileinfo' => array()
+ );
+
+ // Add the list of tags into the addon details
+ foreach ($addon['Tag'] as $x) {
+ $x = $all_tags[ $x['id'] ];
+ $addon_out['tags'][] = array(
+ 'id' => $x['Tag']['id'],
+ 'name' => $x['Translation']['name']['string']
+ );
+ }
+
+ // Add the list of compatible apps into the addon details
+ $compatible_apps =
+ $this->Version->getCompatibleApps($install_version);
+ foreach ($compatible_apps as $x) {
+ $addon_out['compatible_apps'][] = array(
+ 'id' => $x['Application']['application_id'],
+ 'name' => $app_names[ $x['Application']['application_id']],
+ 'guid' => $guids[$app_names[$x['Application']['application_id']]],
+ 'min_version' => $x['Min_Version']['version'],
+ 'max_version' => $x['Max_Version']['version']
+ );
+ }
+
+ // Gather a list of platforms for files
+ $fileinfo = $this->File->findAllByVersion_id(
+ $install_version, null, null, null, null, 0
+ );
+ $this->Platform->unbindFully();
+ $platforms = array();
+ foreach($fileinfo as &$file) {
+ $this_plat = $this->Platform->findById($file['Platform']['id']);
+ $file['Platform']['apiname'] = $this_plat['Translation']['name']['string'];
+ $platforms[] = $this_plat;
+ }
+
+ if ($this->api_version > 0 ) {
+ // return an array of compatible os names
+ // right now logic is still wrong, but this enables
+ // xml changes and logic will be fixed later
+ if (empty($platforms)) {
+ $all_compatible_os = array();
+ } else {
+ $all_compatible_os = $platforms;
+ }
+ foreach ($all_compatible_os as $x) {
+ $addon_out['all_compatible_os'][] =
+ $this->os_translation[ $x['Translation']['name']['string'] ];
+ }
+ }
+
+ // Add in the list of files available for the addon.
+ foreach ($fileinfo as $x) {
+ $addon_out['fileinfo'][] = array(
+ 'id' => $x['File']['id'],
+ 'filename' => $x['File']['filename'],
+ 'hash' => $x['File']['hash'],
+ 'os' => $this->os_translation[ $x['Platform']['apiname'] ],
+ );
+ }
+
+ // Finally, add this set of addon details to the list intended for
+ // the view.
+ $addons_out[] = $addon_out;
+ }
+
+ return $addons_out;
+ }
+
+ /**
+ * API specific publish
+ * Uses XML encoding and is UTF-8 safe
+ * @param mixed the data array (or string) to be html-encoded (by reference)
+ * @param bool clean the array keys as well?
+ * @return void
+ */
+ function publish($viewvar, $value, $sanitizeme = true) {
+ if ($sanitizeme) {
+ if (is_array($value)) {
+ $this->_sanitizeArrayForXML($value);
+ } else {
+ $tmp = array($value);
+ $this->_sanitizeArrayForXML($tmp);
+ $value = $tmp[0];
+ }
+ }
+ $this->set($viewvar, $value);
+ }
+
+ /**
+ * API specific sanitize
+ * xml-encode an array, recursively
+ * UTF-8 safe
+ *
+ * @param mixed the data array to be encoded
+ * @param bool clean the array keys as well?
+ * @return void
+ */
+ var $sanitize_patterns = array(
+ "/\&/u", "/</u", "/>/u",
+ '/"/u', "/'/u",
+ '/[\cA-\cL]/u',
+ '/[\cN-\cZ]/u',
+ );
+ var $sanitize_replacements = array(
+ "&amp;", "&lt;", "&gt;",
+ "&quot;", "&#39;",
+ "",
+ ""
+ );
+ var $sanitize_field_exceptions = array(
+ 'id'=>1, 'guid'=>1, 'addontype_id'=>1, 'status'=>1, 'higheststatus'=>1,
+ 'icontype'=>1, 'version_id'=>1, 'platform_id'=>1, 'size'=>1, 'hash'=>1,
+ 'codereview'=>1, 'password'=>1, 'emailhidden'=>1, 'sandboxshown'=>1,
+ 'averagerating'=>1, 'textdir'=>1, 'locale'=>1, 'locale_html'=>1,
+ 'created'=>1, 'modified'=>1, 'datestatuschanged'=>1
+ );
+ function _sanitizeArrayForXML(&$data, $cleankeys = false) {
+
+ if (empty($data)) return;
+
+ foreach ($data as $key => $value) {
+ if (isset($this->sanitize_field_exceptions[$key])) {
+ // @todo This if() statement is a temporary solution until we come up with
+ // a better way of excluding fields from being sanitized.
+ continue;
+ } else if (empty($value)) {
+ continue;
+ } else if (is_array($value)) {
+ $this->_sanitizeArrayForXML($data[$key], $cleankeys);
+ } else {
+ $data[$key] = preg_replace(
+ $this->sanitize_patterns,
+ $this->sanitize_replacements,
+ $data[$key]
+ );
+ }
+ }
+
+ // change the keys if necessary
+ if ($cleankeys) {
+ $keys = array_keys($data);
+ $this->_sanitizeArrayForXML($keys, false);
+ $data = array_combine($keys, array_values($data));
+ }
+
+ }
+
+ /**
+ * Render an HTTP status along with optional template and location.
+ *
+ * @param string HTTP status
+ * @param string (optional) Name of a view to render
+ * @param array (optional) Vars to be published to the template
+ * @param string (optional) URL for Location: header
+ */
+ function renderStatus($status, $view=null, $ns=null, $location=null) {
+ $this->layout = ($view == 'empty') ? '' : 'rest';
+ header('HTTP/1.1 ' . $status);
+ if (!empty($ns)) foreach ($ns as $k=>$v)
+ $this->publish($k, $v);
+ if (null !== $location)
+ header('Location: '.$location);
+ if (null !== $view)
+ return $this->render($view);
+ }
+
+ /**
+ * Dispatch to the appropriate handler based on HTTP method and a map of
+ * handlers.
+ */
+ function dispatchHttpMethod($map, $args=NULL, $context=null) {
+
+ if (null == $args) $args = array();
+ if (null == $context) $context = array();
+
+ $method = $this->getHttpMethod();
+
+ if ('OPTIONS' == $method) {
+ header('Allow: ' . join(', ', array_keys($map)));
+ $this->publish('methods', array_keys($map));
+ return $this->render('options');
+ }
+
+ if (!isset($map[$method])) {
+ return $this->renderStatus(
+ self::STATUS_METHOD_NOT_ALLOWED, 'error',
+ array('reason' => $method . '_not_allowed')
+ );
+ }
+
+ return call_user_func_array(
+ array($this, $map[$method]),
+ array_merge(array($context), $args)
+ );
+ }
+
+ /**
+ * Grab named keys from POST parameters. Missing parameters will be
+ * set as null.
+ *
+ * @param array list of named parameters.
+ */
+ function getParams($list) {
+ $params = array();
+ $raw = array();
+ if ($this->getHttpMethod() != 'PUT') {
+ $raw = array_merge($_GET, $_POST);
+ } else {
+ $raw = array();
+ if (!empty($_SERVER['CONTENT_LENGTH'])) {
+ // HACK: $_POST isn't populated by PUT
+ $data = file_get_contents('php://input');
+ mb_parse_str($data, $raw);
+ }
+ $raw = array_merge($_GET, $raw);
+ }
+ foreach ($list as $name=>$default) {
+ $params[$name] = isset($raw[$name]) ?
+ $raw[$name] : $default;
+ }
+ return $params;
+ }
+
+ /**
+ * Figure out the current HTTP method, with overrides accepted in a _method
+ * parameter (GET/POST) or in an X_HTTP_METHOD_OVERRIDE header ala Google
+ */
+ function getHttpMethod() {
+ if (!empty($_POST['_method']))
+ return strtoupper($_POST['method']);
+ if (!empty($_GET['_method']))
+ return strtoupper($_GET['method']);
+ if (!empty($_SERVER['X_HTTP_METHOD_OVERRIDE']))
+ return strtoupper($_SERVER['X_HTTP_METHOD_OVERRIDE']);
+ if (!empty($_SERVER['REQUEST_METHOD']))
+ return strtoupper($_SERVER['REQUEST_METHOD']);
+ }
+
+ /**
+ * Return whether the current HTTP method is a request to write in some
+ * way.
+ */
+ function isWriteHttpMethod() {
+ return in_array($this->getHttpMethod(), array('POST', 'DELETE', 'PUT'));
+ }
+
+ /**
+ * If an if-modified-since header was provided, return a 304 if the
+ * collection indeed has not been modified since the given time.
+ */
+ function isNotModifiedSince() {
+ $since = @$_SERVER['HTTP_IF_MODIFIED_SINCE'];
+ if ('GET' == $this->getHttpMethod() && $since) {
+ if ($this->last_modified <= strtotime($since)) {
+ return $this->renderStatus(
+ self::STATUS_NOT_MODIFIED, 'empty'
+ );
+ }
+ }
+ }
+
+ /**
+ * Return the current authenticated user, or return null and set 401
+ * Unauthorized headers.
+ *
+ * @return mixed Authenticated user details.
+ */
+ function getAuthUser() {
+ $auth_user = null;
+
+ if (null == $auth_user && !empty($_SERVER['HTTP_X_API_AUTH'])) {
+ // Try accepting an API auth token in a header.
+ $token = $_SERVER['HTTP_X_API_AUTH'];
+ $auth_user = $this->ApiAuthToken->getUserForAuthToken($token);
+ }
+
+ if (null == $auth_user && $this->Session->check('User')) {
+ // Try grabbing the user from a logged in session.
+ $auth_user = $this->Session->read('User');
+ }
+
+ if (null == $auth_user &&
+ !empty($_SERVER['PHP_AUTH_USER']) &&
+ !empty($_SERVER['PHP_AUTH_PW'])) {
+ // Try validating the user by HTTP Basic auth username and password.
+ $someone = $this->User->findByEmail($_SERVER['PHP_AUTH_USER']);
+ if ($this->User->checkPassword($someone['User'], $_SERVER['PHP_AUTH_PW'])) {
+ $auth_user = $someone['User'];
+ $auth_user['Group'] = $someone['Group'];
+ }
+ }
+
+ return $auth_user;
+ }
+
+ /**
+ * Standalone string sanitize for XML
+ *
+ * @param string
+ * @return string
+ */
+ function sanitizeForXML($value) {
+ return preg_replace(
+ $this->sanitize_patterns,
+ $this->sanitize_replacements,
+ $value
+ );
+ }
+
+ /**
+ * Given a base URL and a relative URL, produce an absolute URL.
+ * see: http://us.php.net/manual/en/function.parse-url.php#76979
+ */
+ function resolveUrl($base, $url) {
+ if (!strlen($base)) return $url;
+ if (!strlen($url)) return $base;
+ if (preg_match('!^[a-z]+:!i', $url)) return $url;
+
+ $base = parse_url($base);
+ if ($url{0} == "#") {
+ $base['fragment'] = substr($url, 1);
+ return $this->unparseUrl($base);
+ }
+ unset($base['fragment']);
+ unset($base['query']);
+
+ if (substr($url, 0, 2) == "//") {
+ return $this->unparseUrl(array(
+ 'scheme'=>$base['scheme'],
+ 'path'=>substr($url,2),
+ ));
+ } else if ($url{0} == "/") {
+ $base['path'] = $url;
+ } else {
+ $path = explode('/', $base['path']);
+ $url_path = explode('/', $url);
+ array_pop($path);
+ $end = array_pop($url_path);
+ foreach ($url_path as $segment) {
+ if ($segment == '.') {
+ // skip
+ } else if ($segment == '..' && $path && $path[sizeof($path)-1] != '..') {
+ array_pop($path);
+ } else {
+ $path[] = $segment;
+ }
+ }
+ if ($end == '.') {
+ $path[] = '';
+ } else if ($end == '..' && $path && $path[sizeof($path)-1] != '..') {
+ $path[sizeof($path)-1] = '';
+ } else {
+ $path[] = $end;
+ }
+ $base['path'] = join('/', $path);
+
+ }
+ return $this->unparseUrl($base);
+ }
+
+ /**
+ * Given the results of parse_url, produce a URL.
+ * see: http://us.php.net/manual/en/function.parse-url.php#85963
+ */
+ function unparseUrl($parsed)
+ {
+ if (!is_array($parsed)) return false;
+
+ $uri = isset($parsed['scheme']) ? $parsed['scheme'].':'.((strtolower($parsed['scheme']) == 'mailto') ? '' : '//') : '';
+ $uri .= isset($parsed['user']) ? $parsed['user'].(isset($parsed['pass']) ? ':'.$parsed['pass'] : '').'@' : '';
+ $uri .= isset($parsed['host']) ? $parsed['host'] : '';
+ $uri .= isset($parsed['port']) ? ':'.$parsed['port'] : '';
+
+ if (isset($parsed['path'])) {
+ $uri .= (substr($parsed['path'], 0, 1) == '/') ?
+ $parsed['path'] : ((!empty($uri) ? '/' : '' ) . $parsed['path']);
+ }
+
+ $uri .= isset($parsed['query']) ? '?'.$parsed['query'] : '';
+ $uri .= isset($parsed['fragment']) ? '#'.$parsed['fragment'] : '';
+
+ return $uri;
+ }
+
+}
diff --git a/site/app/controllers/statistics_controller.php b/site/app/controllers/statistics_controller.php
new file mode 100644
index 0000000..b6a7ffd
--- /dev/null
+++ b/site/app/controllers/statistics_controller.php
@@ -0,0 +1,410 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/e
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Justin Scott <fligtar@mozilla.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+class StatisticsController extends AppController
+{
+ var $name = 'Statistics';
+ var $uses = array('Addon', 'Addontype', 'Application', 'User', 'Version');
+ var $components = array('Amo', 'Image', 'Stats');
+ var $helpers = array('Html', 'Javascript', 'Listing', 'Localization', 'Statistics', 'Time');
+
+ /**
+ * Require login for all actions
+ */
+ function beforeFilter() {
+ $this->SimpleAuth->enabled = false;
+ $this->SimpleAcl->enabled = false;
+
+ // beforeFilter() is apparently called before components are initialized. Cake++
+ $this->Amo->startup($this);
+
+ // Clean post data
+ $this->Amo->clean($this->data);
+
+ $this->layout = 'amo2009';
+ $this->pageTitle = _('statistics_pagetitle').' :: '.sprintf(_('addons_home_pagetitle'), APP_PRETTYNAME);
+
+ $this->cssAdd = array('stats/stats');
+ $this->publish('cssAdd', $this->cssAdd);
+
+ $this->jsAdd = array('stats/stats.js',);
+ $this->publish('jsAdd', $this->jsAdd);
+
+ $prescriptJS = "var statsURL = '".$this->url('/statistics/')."';";
+ $this->set('prescriptJS', $prescriptJS);
+
+ $this->breadcrumbs = array(_('statistics_pagetitle') => '/statistics/index');
+ $this->publish('breadcrumbs', $this->breadcrumbs);
+
+ $this->publish('subpagetitle', _('statistics_pagetitle'));
+ }
+
+ /**
+ * Index
+ */
+ function index($addon_id = 0) {
+
+ // Get public stats for dashboard.
+ $this->publish('dailyStats',$this->Stats->getDailyStats());
+
+ // If add-on id was specified, go to its statistics
+ if (!empty($addon_id) || !empty($_GET['data']['Addon']['id'])) {
+ if (!empty($addon_id))
+ $this->addon($addon_id);
+ elseif (!empty($_GET['data']['Addon']['id']))
+ $this->addon($_GET['data']['Addon']['id']);
+
+ return;
+ }
+ // If not, figure out what to do
+ else {
+ $session = $this->Session->read('User');
+ if ($session) {
+ $addons = $this->Addon->getAddonsByUser($session['id']);
+ } else {
+ $addons = array();
+ }
+ $this->publish('addons', $addons);
+
+ // If user can access all add-on stats, pull all
+ if ($this->SimpleAcl->actionAllowed('Admin', 'ViewAnyStats', $this->Session->read('User'))) {
+ $otherAddons = $this->Addon->findAll(null, array('Addon.id', 'Addon.name'), null, null, null, -1);
+ }
+ else {
+ // Otherwise, pull all public stats add-ons
+ $otherAddons = $this->Addon->findAll("Addon.publicstats=1", array('Addon.id', 'Addon.name'), null, null, null, -1);
+ }
+
+ if (!empty($otherAddons)) {
+ foreach ($otherAddons as $otherAddon) {
+ $name = trim($otherAddon['Translation']['name']['string']);
+ if (!empty($name))
+ $other_addons[$otherAddon['Addon']['id']] = substr($name, 0, 50);
+ }
+ asort($other_addons);
+
+ $this->set('otherAddons', $other_addons);
+ }
+ }
+ }
+
+ /**
+ * Add-on Statistics
+ */
+ function addon($addon_id) {
+ $this->Amo->clean($addon_id);
+ $this->publish('addon_id', $addon_id);
+
+ $this->Addon->id = $addon_id;
+ if (!$addon = $this->Addon->read()) {
+ $this->flash(_('error_addon_notfound'), '/statistics/index');
+ return;
+ }
+
+ if (isset($this->namedArgs['format']) && $this->namedArgs['format'] == 'rss')
+ $rss = true;
+ else
+ $rss = false;
+
+ // Make sure user has permission to view this add-on's stats
+ if (!$this->_checkAccess($addon_id, $addon) &&
+ !($rss && !empty($this->namedArgs['key']) && md5($addon['Addon']['created']) == $this->namedArgs['key'])) {
+ $this->flash(_('devcp_error_addon_access_denied'), '/developers/index');
+ return;
+ }
+
+ $this->jsAdd = array(
+ //'simile/timeplot/timeplot-api.js?local',
+ 'jquery-compressed.js',
+ //'simile/amo-bundle.compressed.js',
+ 'strftime-min-1.3.js',
+ 'simile/amo-bundle.js',
+ 'stats/stats.js',
+ 'stats/dropdowns.js',
+ 'stats/colors.js',
+ 'stats/plot-selection.js',
+ 'stats/plot-tables.js',
+ 'stats/plots.js'
+ );
+ $this->publish('jsAdd', $this->jsAdd);
+
+ $this->cssAdd = array(
+ 'simile/bundle',
+ 'stats/stats',
+ 'stats/dropdowns'
+ );
+ $this->publish('cssAdd', $this->cssAdd);
+
+ // We only show the RSS key if the user could access if it wasn't public
+ if ($this->Amo->checkOwnership($addon_id, $addon, true) || $this->SimpleAcl->actionAllowed('Admin', 'ViewAnyStats', $this->Session->read('User')))
+ $key = "/key:".md5($addon['Addon']['created']);
+ else
+ $key = '';
+ $this->publish('key', $key);
+ $this->publish('rssAdd', array("/statistics/addon/{$addon['Addon']['id']}/format:rss{$key}"));
+
+ $this->publish('addon', $addon);
+ $this->publish('addon_name', $addon['Translation']['name']['string']);
+
+ $this->breadcrumbs[sprintf(_('statistics_title_addon_stats'), $addon['Translation']['name']['string'])] = '/statistics/addon/'.$addon_id;
+ $this->publish('breadcrumbs', $this->breadcrumbs);
+
+ $prescriptJS = "var Simile_urlPrefix = '".SITE_URL.$this->base.'/js/simile'."';";
+ $this->set('prescriptJS', $prescriptJS);
+
+ $session = $this->Session->read('User');
+ $this->publish('email', $session['email']);
+ $this->set('all_addons', empty($session['id']) ?
+ array() : $this->Addon->getAddonsByUser($session['id']));
+
+ // Add-on icon
+ $addonIcon = $this->Image->getAddonIconURL($addon_id);
+ $this->publish('addonIcon', $addonIcon);
+
+ // Data for overview
+ $stats = array('totaldownloads' => 0);
+ if (!$this->Config->getValue('stats_disabled') || $this->SimpleAcl->actionAllowed('*', '*', $this->Session->read('User'))) {
+ if ($statsQry = $this->Addon->query("SELECT totaldownloads, weeklydownloads FROM addons WHERE id={$addon_id}", true)) {
+ $stats['totaldownloads'] = $statsQry[0]['addons']['totaldownloads'];
+ $stats['weeklydownloads'] = $statsQry[0]['addons']['weeklydownloads'];
+ }
+ if ($statsQry = $this->Addon->query("SELECT AVG(count) FROM update_counts WHERE addon_id={$addon_id}", true))
+ $stats['avg_updatepings'] = $statsQry[0][0]['AVG(count)'];
+ if ($statsQry = $this->Addon->query("SELECT AVG(count) FROM download_counts WHERE addon_id={$addon_id}", true))
+ $stats['avg_downloads'] = $statsQry[0][0]['AVG(count)'];
+ if ($statsQry = $this->Addon->query("SELECT count, date FROM update_counts WHERE addon_id={$addon_id} ORDER BY date DESC LIMIT 2" ,true)) {
+ $stats['last_updatepings'] = $statsQry[0]['update_counts']['count'];
+ $stats['last_updatepings_date'] = $statsQry[0]['update_counts']['date'];
+ $stats['previous_updatepings'] = $statsQry[1]['update_counts']['count'];
+ $stats['previous_updatepings_date'] = $statsQry[1]['update_counts']['date'];
+ $stats['updateping_change'] = (($stats['last_updatepings'] - $stats['previous_updatepings']) / $stats['previous_updatepings']) * 100;
+ }
+ if ($statsQry = $this->Addon->query("SELECT count, date FROM download_counts WHERE addon_id={$addon_id} ORDER BY date DESC LIMIT 1", true)) {
+ $stats['last_downloads'] = $statsQry[0]['download_counts']['count'];
+ $stats['last_downloads_date'] = $statsQry[0]['download_counts']['date'];
+ }
+ // Grouping by week is not quite what we want, since the current
+ // week is going to be shorter than (the complete) last week.
+ // If you know how to get (now, now - 7), (now - 8, now - 14) ranges
+ // in a group by, feel free to improve this.
+ $thisWeek = $this->Addon->query("SELECT AVG(count) as `count` FROM update_counts
+ WHERE addon_id={$addon_id}
+ AND date >= DATE_SUB(CURDATE(), INTERVAL 7 DAY)");
+ $prevWeek = $this->Addon->query("SELECT AVG(count) as `count` FROM update_counts
+ WHERE addon_id={$addon_id}
+ AND date <= DATE_SUB(CURDATE(), INTERVAL 7 DAY)
+ AND date >= DATE_SUB(CURDATE(), INTERVAL 14 DAY)");
+ if ($thisWeek && $prevWeek) {
+ $thisWeek = $thisWeek[0][0]['count'];
+ $prevWeek = $prevWeek[0][0]['count'];
+ $stats['weekly_updatepings'] = $thisWeek;
+ $stats['weekly_updatepings_change'] = $prevWeek > 0 ? (($thisWeek - $prevWeek) / $prevWeek) * 100 : 0;
+ }
+ }
+ $this->set('stats', $stats);
+ $this->pageTitle = $addon['Translation']['name']['string'].' :: '._('statistics_pagetitle').' :: '.sprintf(_('addons_home_pagetitle'), APP_PRETTYNAME);
+
+ if (!$rss) {
+ $this->publish('jsLocalization', array(
+ 'date' => _('date'),
+ 'statistics_js_dropdowns_removeplot' => _('statistics_js_dropdowns_removeplot'),
+ 'statistics_js_dropdowns_none' => _('statistics_js_dropdowns_none'),
+ 'statistics_js_download_csv' => ___('statistics_js_download_csv', 'View this table in CSV format'),
+ 'statistics_js_groupby_selector_date' => ___('statistics_js_groupby_selector_date', 'Group by: Day'),
+ 'statistics_js_groupby_selector_week' => ___('statistics_js_groupby_selector_week', 'Group by: Week'),
+ 'statistics_js_groupby_selector_week_over_week' => ___('statistics_js_groupby_selector_week_over_week', 'Compare by: Week'),
+ 'statistics_js_groupby_selector_month' => ___('statistics_js_groupby_selector_month', 'Group by: Month'),
+ 'statistics_js_plotselection_selector_summary' => _('statistics_js_plotselection_selector_summary'),
+ 'statistics_js_plotselection_selector_downloads' => _('statistics_js_plotselection_selector_downloads'),
+ 'statistics_js_plotselection_selector_adu' => _('statistics_js_plotselection_selector_adu'),
+ 'statistics_js_plotselection_selector_version' => _('statistics_js_plotselection_selector_version'),
+ 'statistics_js_plotselection_selector_application' => _('statistics_js_plotselection_selector_application'),
+ 'statistics_js_plotselection_selector_status' => _('statistics_js_plotselection_selector_status'),
+ 'statistics_js_plotselection_selector_os' => _('statistics_js_plotselection_selector_os'),
+ 'statistics_js_plotselection_selector_custom' => _('statistics_js_plotselection_selector_custom'),
+ 'statistics_js_plotselection_foundinrange' => _('statistics_js_plotselection_foundinrange'),
+ 'statistics_js_plotselection_options_count_name_checked' => _('statistics_js_plotselection_options_count_name_checked'),
+ 'statistics_js_plotselection_options_count_name_unchecked' => _('statistics_js_plotselection_options_count_name_unchecked'),
+ 'statistics_js_plotselection_options_count_tooltip' => _('statistics_js_plotselection_options_count_tooltip'),
+ 'statistics_js_plotselection_options_events_firefox_name_checked' => _('statistics_js_plotselection_options_events_firefox_name_checked'),
+ 'statistics_js_plotselection_options_events_firefox_name_unchecked' => _('statistics_js_plotselection_options_events_firefox_name_unchecked'),
+ 'statistics_js_plotselection_options_events_firefox_tooltip' => _('statistics_js_plotselection_options_events_firefox_tooltip'),
+ 'statistics_js_plotselection_options_events_addon_name_checked' => _('statistics_js_plotselection_options_events_addon_name_checked'),
+ 'statistics_js_plotselection_options_events_addon_name_unchecked' => _('statistics_js_plotselection_options_events_addon_name_unchecked'),
+ 'statistics_js_plotselection_options_events_addon_tooltip' => _('statistics_js_plotselection_options_events_addon_tooltip'),
+ 'statistics_js_plotselection_options_addplot_name' => _('statistics_js_plotselection_options_addplot_name'),
+ 'statistics_js_plotselection_options_addplot_tooltip' => _('statistics_js_plotselection_options_addplot_tooltip'),
+ 'statistics_js_plotselection_options_resize_name_checked' => _('statistics_js_plotselection_options_resize_name_checked'),
+ 'statistics_js_plotselection_options_resize_name_unchecked' => _('statistics_js_plotselection_options_resize_name_unchecked'),
+ 'statistics_js_plotselection_options_resize_tooltip' => _('statistics_js_plotselection_options_resize_tooltip'),
+ 'statistics_js_plotselection_options_csv_name' => _('statistics_js_plotselection_options_csv_name'),
+ 'statistics_js_plotselection_options_csv_tooltip' => _('statistics_js_plotselection_options_csv_tooltip')
+ ));
+
+ $this->render('addon', 'amo2009');
+ }
+ else {
+ $this->publish('rss_title', sprintf(_('statistics_title_addon_stats'), $addon['Translation']['name']['string']));
+ $this->publish('rss_description', sprintf(_('statistics_rss_description'), $addon['Translation']['name']['string']));
+ $this->render('rss/summary', 'rss');
+ }
+ }
+
+ /**
+ * CSV data
+ */
+ function csv($addon_id, $plot) {
+ $this->publish('addon_id', $addon_id);
+ $this->publish('plot', $plot);
+
+ $addon = $this->Addon->find("Addon.id={$addon_id}", null, null, -1);
+
+ // Make sure user has permission to view this add-on's stats
+ if (!$this->_checkAccess($addon_id, $addon)) {
+ $this->Amo->accessDenied();
+ return;
+ }
+
+ $csv = $this->Stats->historicalPlot($addon_id, $plot, @$_GET['group_by']);
+
+ $this->set('csv', $csv);
+ $this->render('csv', 'ajax');
+ }
+
+ /**
+ * JSON data
+ */
+ function json($addon_id, $type) {
+ $this->publish('addon_id', $addon_id);
+
+ $addon = $this->Addon->find("Addon.id={$addon_id}", null, null, -1);
+
+ // Make sure user has permission to view this add-on's stats
+ if (!$this->_checkAccess($addon_id, $addon))
+ return;
+
+ if ($type == 'summary')
+ $json = $this->Stats->getSummary($addon_id);
+
+ $this->set('json', $json);
+ $this->render('json', 'ajax');
+ }
+
+ /**
+ * XML data
+ */
+ function xml($action, $type, $addon_id = 0) {
+ $addon = $this->Addon->find("Addon.id={$addon_id}", null, null, -1);
+
+ if ($action == 'events') {
+ if ($type == 'addon') {
+ $xml = $this->Stats->getEventsAddon($addon_id);
+ }
+ else {
+ $xml = $this->Stats->getEventsApp($type);
+ }
+ }
+
+ $this->set('xml', $xml);
+ $this->render('xml', 'ajax');
+ }
+
+ /**
+ * Change dashboard settings
+ */
+ function settings($addon_id) {
+ $this->Amo->clean($addon_id);
+ $this->publish('addon_id', $addon_id);
+
+ // Disable query caching
+ foreach ($this->uses as $_model) {
+ $this->$_model->caching = false;
+ }
+
+ // Make sure user is owner in order to change this setting
+ if (!$this->Amo->checkOwnership($addon_id, null, true)) {
+ $this->flash(_('devcp_error_addon_access_denied'), '/statistics/addon/'.$addon_id);
+ return;
+ }
+
+ $this->Addon->id = $addon_id;
+
+ // Save data if POSTed
+ if (!empty($this->data)) {
+ $this->Addon->save($this->data);
+
+ $this->redirect('/statistics/addon/'.$addon_id.'/?settings');
+ return;
+ }
+
+ $addon = $this->Addon->read();
+ $this->publish('addon', $addon);
+
+ $session = $this->Session->read('User');
+ $this->publish('all_addons', $this->Addon->getAddonsByUser($session['id']));
+
+ $this->render('settings');
+ }
+
+ /**
+ * Determines if a user has access to view the add-on's stats
+ */
+ function _checkAccess($addon_id, $addon) {
+ // If add-on has opted-in to public stats, allow access
+ if ($addon['Addon']['publicstats'] == 1)
+ return true;
+
+ // If not publicstats, make sure logged in
+ if (!$this->Session->check('User'))
+ return false;
+
+ // If user can view any add-on's stats, allow access
+ if ($this->SimpleAcl->actionAllowed('Admin', 'ViewAnyStats', $this->Session->read('User')))
+ return true;
+
+ // If user is the add-on's author, allow access
+ if ($this->Amo->checkOwnership($addon_id, $addon))
+ return true;
+
+ // If no access yet, no access at all
+ return false;
+ }
+
+}
+
+?>
diff --git a/site/app/controllers/tests_controller.php b/site/app/controllers/tests_controller.php
new file mode 100644
index 0000000..05893ca
--- /dev/null
+++ b/site/app/controllers/tests_controller.php
@@ -0,0 +1,243 @@
+<?php
+/* SVN FILE: $Id: tests_controller.php,v 1.1 2006/08/16 07:10:51 sancus%off.net Exp $ */
+/**
+ * Short description for file.
+ *
+ * Long description for file
+ *
+ * PHP versions 4 and 5
+ *
+ * CakePHP Test Suite <https://trac.cakephp.org/wiki/Developement/TestSuite>
+ * Copyright (c) 2006, Larry E. Masters Shorewood, IL. 60431
+ * Author(s): Larry E. Masters aka PhpNut <phpnut@gmail.com>
+ * Justin Scott aka fligtar <fligtar@gmail.com>
+ *
+ * Licensed under The Open Group Test Suite License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @author Larry E. Masters aka PhpNut <phpnut@gmail.com>
+ * @copyright Copyright (c) 2006, Larry E. Masters Shorewood, IL. 60431
+ * @link http://www.phpnut.com/projects/
+ * @package cake
+ * @subpackage cake.app.controllers
+ * @since CakePHP Test Suite v 1.0.0.0
+ * @version $Revision: 1.1 $
+ * @modifiedby $LastChangedBy: phpnut $
+ * @lastmodified $Date: 2006/08/16 07:10:51 $
+ * @license http://www.opensource.org/licenses/opengroup.php The Open Group Test Suite License
+ */
+/**
+ * Short description for class.
+ *
+ * Long description for class
+ *
+ * @package cake
+ * @subpackage cake.app.controllers
+ */
+vendor('simpletest/reporter');
+vendor('simpletest'.DS.'unit_tester', 'simpletest'.DS.'web_tester', 'simpletest'.DS.'mock_objects', 'simpletest'.DS.'xml', 'simpletest'.DS.'remote');
+vendor('phpQuery/phpQuery');
+require_once(TESTS.'test_manager.php');
+require_once(TESTS.'groups.php');
+require_once(TESTS.'cake_reporter.php');
+require_once(TESTS.'bot_reporter.php');
+require_once(TESTS.'test_helper_unit.php');
+require_once(TESTS.'test_helper_web.php');
+define('TEST_DATA', TESTS.'data');
+
+
+/* XXX Copied from test_helper_web.php, shoot me. */
+
+function hostPrefix() {
+ $http = (!empty($_SERVER["HTTP_MOZ_REQ_METHOD"]) && $_SERVER["HTTP_MOZ_REQ_METHOD"] == 'HTTPS') ? 'https://' : 'http://';
+ $uriBase = $http . $_SERVER['HTTP_HOST'];
+ return $uriBase;
+}
+
+function actionPath($action) {
+ return preg_replace('/\/tests.*/', $action, setUri());
+}
+
+/* end copying shame */
+
+class TestsController extends AppController {
+ var $uses = array('Addon', 'Addontype', 'Application', 'Approval', 'Appversion', 'Cannedresponse', 'Favorite', 'Feature', 'File',
+ 'Platform', 'Preview', 'Review', 'Reviewrating', 'Tag', 'Translation', 'User', 'Version');
+ var $helpers = array('Html', 'Ajax', 'Javascript');
+ var $aclExceptions = array('bot');
+ // Disable permissions if we're in a DEV sandbox.
+ function beforeFilter() {
+ if (DEV == true) {
+ $this->SimpleAcl->enabled = false;
+ $this->SimpleAuth->enabled = false;
+ }
+
+ // disable query caching so devcp changes are visible immediately
+ foreach ($this->uses as $_model) {
+ $this->$_model->caching = false;
+ }
+ }
+
+ function constructClasses() {
+ global $TestController;
+ $TestController = $this;
+ parent::constructClasses();
+ }
+
+ function index() {
+ if (!empty($_GET['case'])) {
+ $this->_case($_GET['case']);
+ }
+ elseif (!empty($_GET['directory'])) {
+ $this->_directory($_GET['directory']);
+ }
+ else {
+ $this->render('index', 'tests');
+ }
+ }
+
+ function split_all() {
+ function get_directory($path) {
+ $split = explode('/', $path, 2);
+ return $split[0];
+ }
+
+ $testlist = TestManager::getTestCaseList();
+ $dirlist = array_unique(array_map('get_directory', $testlist));
+
+ $test =& new GroupTest('All Test Cases (split)');
+ $baseurl = hostPrefix() . actionPath("/tests/xml?");
+ foreach ($dirlist as $dir) {
+ $testurl = $baseurl;
+ if (strpos($dir, '.') === false) {
+ $testurl .= 'directory=';
+ } else {
+ $testurl .= 'case=';
+ }
+ $testurl .= urlencode($dir);
+ $test->addTestCase(new RemoteTestCase($testurl, $testurl . '&dry=1'));
+ }
+
+ $reporter = new CakeHtmlReporter();
+ $reporter->sendNoCacheHeaders();
+ ob_start();
+ $test->run($reporter);
+ $this->set('output', $reporter->output);
+ $this->render('group', 'tests');
+ }
+
+ function xml() {
+ $reporter = new XmlReporter();
+ /* in lieu of $reporter->sendNoCacheHeaders(); */
+ if (! headers_sent()) {
+ header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
+ header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
+ header("Cache-Control: no-store, no-cache, must-revalidate");
+ header("Cache-Control: post-check=0, pre-check=0", false);
+ header("Pragma: no-cache");
+ }
+
+ if (!empty($_GET['dry'])) {
+ $reporter->makeDry();
+ }
+ if (!empty($_GET['case'])) {
+ TestManager::runTestCase($_GET['case'], $reporter);
+ }
+ elseif (!empty($_GET['directory'])) {
+ TestManager::runDirectory($_GET['directory'], $reporter);
+ }
+ elseif (!empty($_GET['group'])) {
+ TestManager::runGroup($_GET['groups'][$_GET['group']], $reporter);
+ }
+ elseif (!empty($_GET['discover'])) {
+ $this->render('discover', 'ajax');
+ }
+ exit();
+ }
+
+ function _case($case) {
+ $reporter = new CakeHtmlReporter();
+ $reporter->sendNoCacheHeaders();
+ ob_start();
+
+ TestManager::runTestCase($case, $reporter);
+ $this->set('svn', $reporter->SVNLink());
+ $this->set('output', $reporter->output);
+ $this->render('case', 'tests');
+ }
+
+ function group($group) {
+ $reporter = new CakeHtmlReporter();
+ $reporter->sendNoCacheHeaders();
+ ob_start();
+
+ TestManager::runGroup($_GET['groups'][$group], $reporter);
+
+ $this->set('output', $reporter->output);
+ $this->render('group', 'tests');
+ }
+
+ function _directory($directory) {
+ $reporter = new CakeHtmlReporter();
+ $reporter->sendNoCacheHeaders();
+ ob_start();
+
+ TestManager::runDirectory($directory, $reporter);
+
+ $this->set('output', $reporter->output);
+ $this->render('group', 'tests');
+ }
+
+ function all() {
+ $reporter = new CakeHtmlReporter();
+ $reporter->sendNoCacheHeaders();
+ ob_start();
+
+ TestManager::runAllTests($reporter);
+
+ $this->set('output', $reporter->output);
+ $this->render('group', 'tests');
+ }
+
+ function bot() {
+ $reporter = new BotReporter();
+ $reporter->sendNoCacheHeaders();
+ ob_start();
+
+ TestManager::runAllTests($reporter);
+
+ $this->set('output', $reporter->output);
+ $this->render('case', 'ajax');
+ }
+
+ function search() {
+ $text = $_REQUEST['q'];
+ $tests = TestManager::getTestCaseList();
+
+ sort($tests);
+ foreach ($tests as $test) {
+ if (strpos($test, $text) !== false) {
+ $results[] = $test;
+ }
+ }
+
+ $this->set('results', $results);
+ $this->render('search', 'ajax');
+ }
+
+ function passes($mode) {
+ if ($mode == 'on') {
+ $data = array('Passes' => true);
+ }
+ elseif ($mode == 'off') {
+ $data = array('Passes' => false);
+ }
+ $this->Session->write('Tests', $data);
+
+ $referer = str_replace('&', '?', $_GET['r']);
+
+ $this->redirect($referer);
+ }
+}
+?>
diff --git a/site/app/controllers/users_controller.php b/site/app/controllers/users_controller.php
new file mode 100644
index 0000000..b906d1e
--- /dev/null
+++ b/site/app/controllers/users_controller.php
@@ -0,0 +1,855 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Andrei Hajdukewycz <sancus@off.net> (Original Author)
+ * Wil Clouser <clouserw@mozilla.com>
+ * Frederic Wenzel <fwenzel@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+class UsersController extends AppController
+{
+ var $name = 'Users';
+ var $uses = array('User', 'Addon', 'Collection', 'Eventlog', 'Review', 'Version');
+ var $components = array('Amo', 'Email', 'Ldap', 'Session', 'Pagination', 'Recaptcha');
+ var $helpers = array('Html', 'Link', 'Javascript');
+ var $beforeFilter = array('checkCSRF', 'getNamedArgs', '_checkSandbox', 'checkAdvancedSearch');
+ var $exceptionCSRF = array("/users/login", "/users/register", "/users/pwreset");
+ var $layout = 'amo2009';
+ var $namedArgs = true;
+
+ var $securityLevel = 'high';
+
+ function beforeFilter() {
+ // Disable ACLs because this controller is entirely public.
+ $this->SimpleAuth->enabled = false;
+ $this->SimpleAcl->enabled = false;
+
+ // Disable memcache for user queries except in public display page
+ if ($this->action != 'info') {
+ $this->User->caching = false;
+ }
+ }
+
+ /**
+ * Directly calling the user index page just forwards us to the most
+ * userful place. For guests, that's the login page. For users, it's
+ * their editing page.
+ */
+ function index() {
+ if ($this->Session->check('User')) {
+ // logged in
+ $this->redirect('/users/edit');
+ return;
+
+ } else {
+ // guest
+ $this->redirect('/users/login');
+ return;
+ }
+ }
+
+
+ /**
+ * Register a new user
+ */
+ function register() {
+ $this->disableCache();
+
+ $this->pageTitle = _('users_register_pagetitle'). ' :: '. sprintf(_('addons_home_pagetitle'), APP_PRETTYNAME);
+ $this->publish('cssAdd', array('forms'));
+ $this->publish('breadcrumbs', array(_('users_register_pagetitle') => '/users/register'));
+ $this->publish('subpagetitle', _('user_form_registration'));
+ if (empty($this->data)) {
+ $this->render();
+ return;
+
+ } else {
+ // filter nickname characters
+ $this->data['User']['nickname'] = $this->_filterNick($this->data['User']['nickname']);
+
+ // check captcha
+ if ($this->Recaptcha->enabled && (!isset($this->params['form']) ||
+ !$this->Recaptcha->is_valid($this->params['form']))) {
+ $this->User->invalidate('captcha');
+ }
+
+ $this->data['User']['confirmationcode'] = md5(mt_rand());
+
+ $this->Amo->clean($this->data);
+ $this->User->data = $this->data;
+ // hash password(s)
+ $this->User->data['User']['password'] = $this->User->createPassword($this->User->data['User']['password']);
+
+ // compare passwords
+ if ($this->data['User']['password'] !== $this->data['User']['confirmpw'])
+ $this->User->invalidate('confirmpw');
+ // no empty pw
+ if ($this->data['User']['password'] == '')
+ $this->User->invalidate('password');
+ // email has to be unique
+ $allemail = $this->User->findAllByEmail($this->data['User']['email']);
+ if (!empty($allemail)) {
+ $this->User->invalidate('email');
+ $this->publish('error_email_notunique', true);
+ }
+ // if nickname is defined it has to be unique
+ if (!$this->data['User']['nickname'] == '') {
+ $allnicks = $this->User->findAllByNickname($this->data['User']['nickname']);
+ if (!empty($allnicks))
+ $this->User->invalidate('nickname');
+ }
+
+ // any errors? Get out of here.
+ if (!$this->User->save()) {
+ $this->publish('errorMessage', true);
+ $this->render();
+ return;
+ }
+
+ // send confirmation email
+ $this->_sendConfirmationCode($this->User->getLastInsertId());
+
+ // show success message
+ $this->render('register_complete');
+ // @TODO enable default user access
+ }
+ }
+
+ /**
+ * Send the user his confirmation code by email
+ * @param int user id
+ * @return true on success
+ */
+ function _sendConfirmationCode($id) {
+ $data = $this->User->findById($id);
+
+ // don't allow sending an email to already confirmed users.
+ if (empty($data['User']['confirmationcode'])) {
+ $this->flash(_('error_user_already_confirmed'), '/', 3);
+ return false;
+ }
+
+ $this->publish('userid', $id);
+ $this->publish('data', $data);
+ $this->Email->template = 'email/confirm';
+ $this->Email->to = $data['User']['email'];
+ $this->Email->subject = sprintf(_('user_email_confirm_subject'), APP_PRETTYNAME);
+ $result = $this->Email->send();
+ return true;
+ }
+
+
+ /**
+ * To verify a user's email they get sent a verification link. This checks
+ * if the accessed url is correct and unlocks the user.
+ * @param int $id the user's id
+ * @param string $code the verification code sent in the email
+ */
+ function verify($id = 0, $code = '') {
+ $this->Amo->clean($id);
+ $this->Amo->clean($code);
+
+ if (!$id || !$code) {
+ $this->flash(sprintf(_('error_missing_argument'), 'user_id or code'), '/', 3);
+ return;
+ }
+
+ $thisuser = $this->User->findById($id);
+ if (empty($thisuser)) {
+ $this->flash(_('error_user_notfound'), '/', 3);
+ return;
+ }
+
+ if ($code == 'resend') { // resend the confirmation code to the user's email address
+ if (true === $this->_sendConfirmationCode($id))
+ $this->flash(_('user_confirmationcode_resent'), '/', 3);
+ return;
+ }
+
+ if ($code !== $thisuser['User']['confirmationcode']) {
+ $this->flash(_('error_user_badconfirmationcode'), '/', 3);
+ return;
+ }
+
+ // remove confirmation code from DB
+ $this->User->id = $id;
+ $this->User->saveField('confirmationcode', '');
+ $this->flash(_('user_verified_okay'), '/users/login?to='.urlencode('/'), 3);
+ }
+
+
+ /**
+ * Request a password reset. The user gets sent an email with a url. When they
+ * access it, they can change their password.
+ * @param int $id user id
+ * @param string $code the password reset code sent in the email
+ */
+ function pwreset($id = 0, $code = '') {
+ $this->Amo->clean($id);
+ $this->Amo->clean($code);
+
+ $this->pageTitle = _('users_pwreset_pagetitle').' :: '.sprintf(_('addons_home_pagetitle'), APP_PRETTYNAME);
+ $this->publish('cssAdd', array('forms'));
+ $this->publish('breadcrumbs', array(_('users_pwreset_pagetitle') => '/users/pwreset'));
+ $this->publish('subpagetitle', _('user_pwreset_header'));
+ if (!$id && !$code) {
+ if (!isset($this->data['User']['email'])) {
+ $this->render(); // display 'enter email' form
+
+ } else {
+
+ $thisuser = $this->User->findByEmail($this->data['User']['email']);
+ if (empty($thisuser)) {
+ // user not found
+ $this->User->invalidate('email');
+ $this->render();
+ } else {
+ // user found: send pw reset URL via email
+ $this->publish('data', $thisuser);
+ $resetCode = $this->User->setResetCode($thisuser['User']['id']);
+ $this->publish('resetcode', $resetCode);
+ $this->Email->template = 'email/pwreset';
+ $this->Email->to = $this->data['User']['email'];
+ $this->Email->subject = sprintf(_('user_email_pwreset_subject'), APP_PRETTYNAME);
+ $result = $this->Email->send();
+
+ $this->flash(_('user_pwreset_link_sent'), '/', 3);
+ }
+ }
+ return;
+ }
+
+ // id and/or code was sent, make sure the page isn't cached.
+ $this->disableCache();
+
+ // Remove 'id/resetcode' from the URI so it doesn't get echoed.
+ $_SERVER['REQUEST_URI'] = preg_replace('@pwreset/.*$@', 'pwreset/', $_SERVER['REQUEST_URI']);
+ if (isset($this->params['url']['url'])) {
+ $this->params['url']['url'] = preg_replace('@pwreset/.*$@', 'pwreset/', $this->params['url']['url']);
+ }
+
+ if (!$id || !$code) {
+ $this->flash(sprintf(_('error_missing_argument'), 'user_id or code'), '/', 3);
+ return;
+ }
+
+ $thisuser = $this->User->findById($id);
+ if (empty($thisuser)) {
+ $this->flash(_('error_user_notfound'), '/', 3);
+ return;
+ }
+
+ if (!$this->User->checkResetCode($id, $code)) {
+ // TODO: update message re: expiration
+ $this->flash(_('error_user_badconfirmationcode'), '/', 3);
+ return;
+ }
+
+ $this->publish('email', $thisuser['User']['email']);
+ if (isset($this->data['User']['confirmpw'])) {
+ // confirm passwords
+ if ($this->data['User']['password'] !== $this->data['User']['confirmpw']) {
+ $this->User->invalidate('confirmpw');
+ $this->data['User']['password'] = '';
+ $this->data['User']['confirmpw'] = '';
+ $this->render();
+ return;
+ }
+ if ($this->data['User']['password'] == '') {
+ $this->User->invalidate('password');
+ $this->data['User']['password'] = '';
+ $this->data['User']['confirmpw'] = '';
+ $this->render();
+ return;
+ }
+
+ // store new pw
+ $newpw = array();
+ $newpw['User']['password'] = $this->User->createPassword($this->data['User']['password']);
+ $this->User->id = $id;
+ $this->User->save($newpw);
+ // success
+ $this->flash(_('user_pwreset_okay'), '/users/login', 3);
+ }
+ }
+
+
+ /**
+ * Give the user a log in form and actually log them in.
+ */
+ function login() {
+ // clean up referer
+ if (!isset($this->data['Login']['referer'])) {
+ $referer = $this->referer('/', true);
+ } else {
+ $referer = html_entity_decode($this->data['Login']['referer']);
+ // Don't need any referrers that have :// or newlines in them
+ if (preg_match("/(:\/\/|\r|\n)/", $referer)) {
+ $referer = '/'; // evil referer: forward to front page instead
+ }
+ }
+
+ // if we are logged in, go to the main page
+ if ($this->Session->check('User')) {
+ $this->redirect($this->referer('/', true));
+ return;
+ }
+
+ $this->pageTitle = _('users_login_pagetitle').' :: '.sprintf(_('addons_home_pagetitle'), APP_PRETTYNAME);
+ $this->publish('cssAdd', array('forms'));
+ $this->publish('breadcrumbs', array(_('users_login_pagetitle') => '/users/login'));
+ $this->publish('subpagetitle', _('user_form_login'));
+ $this->publish('loginerror', false);
+
+ // by default, just give them a login screen
+ if (!isset($this->data['Login']['email']) || !isset($this->data['Login']['password'])) {
+ $this->render();
+ return;
+ }
+
+ // if any field is empty, return error
+ if (empty($this->data['Login']['email']) || empty($this->data['Login']['password'])) {
+ $this->data['Login']['password'] = '';
+ $this->publish('loginerror', true);
+ $this->render();
+ return;
+ }
+
+ $someone = $this->User->findByEmail($this->data['Login']['email']);
+ if (!empty($someone['User']['id']) && $someone['User']['confirmationcode'] != '') {
+ // user not confirmed yet
+ $this->publish('userid', $someone['User']['id']);
+ $this->publish('email', $someone['User']['email']);
+ $this->render('activatefirst');
+ return;
+ }
+
+ if ($this->User->checkPassword($someone['User'], $this->data['Login']['password'])) {
+
+ //Set expiration to two weeks if they check 'remember me'
+ $expirationTime = isset($this->data['Login']['remember']) ? 60*60*24*7*2 : 0;
+
+ // correct credentials
+ $someone['User']['Group'] = $someone['Group'];
+ $this->Session->start($expirationTime);
+ $this->Session->write('User', $someone['User']);
+
+ // Set app cookie
+ setcookie('AMOappName', APP_SHORTNAME, 0, '/');
+
+ $this->redirect($referer, null, false, false);
+ return;
+
+ } else {
+ $this->data['Login']['password'] = '';
+ $this->publish('loginerror', true);
+ }
+ }
+
+
+ /**
+ * Log the user out (destroy their session and such).
+ */
+ function logout() {
+ if (array_key_exists('to', $_GET)) {
+ $_to = html_entity_decode($_GET['to']);
+ if (preg_match("/(:\/\/|developers|editors|localizers|admin|users|\r|\n)/", $_to)) {
+ $_to = '/';
+ }
+ }
+
+ $_to = isset($_to) ? $_to : $this->referer('/', true);
+
+ // remove our user from the session table
+ if ($this->Session->valid())
+ $this->Session->stop();
+
+ $this->redirect($_to, null, false, false);
+ }
+
+
+ /**
+ * Have the user edit their user details
+ */
+ function edit() {
+ if (!$this->Session->check('User')) {
+ $this->redirect('/users/login');
+ return;
+ }
+
+ $sessionuser = $this->Session->read('User');
+
+ $this->pageTitle = _('users_edit_pagetitle').' :: '.sprintf(_('addons_home_pagetitle'), APP_PRETTYNAME);
+ $this->publish('cssAdd', array('forms', 'jquery-ui/flora/flora.tabs'));
+ $this->publish('jsAdd', array('jquery-ui/ui.core.min', 'jquery-ui/ui.tabs.min'));
+
+ $translations = $this->User->getAllTranslations($sessionuser['id']);
+ $this->set('translations', $translations);
+
+ if (empty($this->data)) {
+ $this->publish('userAddons', $this->Addon->getAddonsByUser($sessionuser['id']));
+
+ $this->data['User'] = $sessionuser;
+ $this->data['User']['password'] = '';
+ $this->render();
+ return;
+ }
+
+ // build array for edited fields
+ $changed = array();
+ $changed['firstname'] = $this->data['User']['firstname'];
+ $changed['lastname'] = $this->data['User']['lastname'];
+ $changed['nickname'] = $this->data['User']['nickname'];
+ $changed['emailhidden'] = $this->data['User']['emailhidden'];
+ $changed['homepage'] = $this->data['User']['homepage'];
+ $changed['display_collections'] = $this->data['User']['display_collections'];
+ $changed['display_collections_fav'] = $this->data['User']['display_collections_fav'];
+
+ if (!empty($this->data['User']['password']) &&
+ !empty($this->data['User']['newpassword'])) {
+
+ // trying to change the password
+ if (!$this->User->checkPassword($sessionuser, $this->data['User']['password']))
+ $this->User->invalidate('password');
+ if ($this->data['User']['newpassword'] != $this->data['User']['confirmpw'])
+ $this->User->invalidate('confirmpw');
+
+ // store the new chosen pw to the "edited" array.
+ // If we invalidated fields up here, it's not going to be
+ // stored anyway.
+ $changed['password'] = $this->User->createPassword($this->data['User']['newpassword']);
+ }
+
+ // nickname has to be unique
+ if ($changed['nickname'] != '') {
+ // filter nickname characters
+ $this->data['User']['nickname'] = $this->_filterNick($this->data['User']['nickname']);
+
+ $allnicks = $this->User->findAllByNickname($changed['nickname']);
+ if (count($allnicks) > 1 ||
+ (count($allnicks) == 1 && $allnicks[0]['User']['id'] != $sessionuser['id'])) {
+ $this->User->invalidate('nickname');
+ }
+ }
+
+ // email change?
+ if (empty($this->data['User']['email'])) {
+ $this->User->invalidate('email');
+ $this->publish('error_email_empty', true);
+
+ } elseif ($this->data['User']['email'] != $sessionuser['email']) {
+
+ $newemail = $this->data['User']['email'];
+
+ // check email format
+ if (!preg_match(VALID_EMAIL, $newemail))
+ $this->User->invalidate('email');
+
+ // email has to be unique
+ if ($this->User->findCount(array('User.email' => $newemail)) > 0) {
+ $this->User->invalidate('email');
+ $this->publish('error_email_notunique', true);
+ }
+ } else {
+ $newemail = false;
+ }
+
+ // notifications
+ $changed['notifycompat'] = $this->data['User']['notifycompat'];
+ $changed['notifyevents'] = $this->data['User']['notifyevents'];
+
+ // save it
+ $this->User->id = $sessionuser['id'];
+ $this->User->data['User'] = $changed;
+ if (!$this->User->save()) {
+ // wipe password fields before returning
+ $this->data['User']['password'] = '';
+ $this->data['User']['newpassword'] = '';
+ $this->data['User']['confirmpw'] = '';
+ // re-attach the email to the data so it can be displayed
+ if (!empty($newemail))
+ $this->data['User']['email'] = $newemail;
+ else
+ $this->data['User']['email'] = $sessionuser['email'];
+
+ $this->publish('errorMessage', true);
+ $this->render();
+ return;
+ }
+ // if we get here, the data was saved successfully
+
+ // save author "about me"
+ list($localizedFields, $unlocalizedFields) = $this->User->splitLocalizedFields($this->data['User']);
+ $this->Amo->clean($localizedFields);
+ $this->User->saveTranslations($sessionuser['id'], $this->params['form']['data']['User'], $localizedFields);
+
+ // send out confirmation email if necessary
+ if ($newemail !== false) {
+ $this->set('newemail', $newemail);
+ $this->set('userid', $sessionuser['id']);
+ // generate email change code
+ $changedata = array($sessionuser['email'], $newemail, time());
+ $token = implode(',', $changedata);
+ // hash with a secret to be able to check for validity later
+ $secret = $this->_getSecret();
+ $changecode = base64_encode($token) . md5($token.$secret);
+ $this->set('changecode', $changecode);
+
+ // send out the confirmation email
+ $this->Email->template = 'email/emailchange';
+ $this->Email->to = $newemail;
+ $this->Email->subject = sprintf(___('user_emailchange_subject'), APP_PRETTYNAME);
+ $result = $this->Email->send();
+ }
+
+ $newprofile = $this->User->findById($sessionuser['id']);
+ if (!empty($newprofile)) {
+ $this->Session->write('User', $newprofile['User']);
+ $this->publish('confirmation_message', _('user_profile_saved'));
+ } else {
+ // this should never happen, but anyway...
+ $this->publish('confirmation_message', _('user_profile_edit_error'));
+ }
+ $this->publish('confirmation_page', true);
+
+ $this->render();
+ }
+
+ /**
+ * Process an email change request
+ * This URL sent to users by email to confirm their new address.
+ * @param int id user id
+ * @param string confirmcode Confirmation code (to be parsed and verified)
+ */
+ function emailchange($id = '') {
+ $this->Amo->clean($id);
+ if (!(int)$id || !$this->params['url']['code']) {
+ $this->flash(sprintf(_('error_missing_argument'), 'user_id or code'), '/', 3);
+ return;
+ }
+ $code = $this->params['url']['code'];
+
+ // the arguments may not be empty and since an MD5 hash is 32 chars long
+ // and a very short token takes 32 chars in base64, we need at least 64
+ // characters, or anything bigger but mod 4 = 0 as base64 generates
+ // multiples of four chars.
+ if (strlen($code) < 64 || strlen($code)%4 != 0) {
+ $this->publish('errormsg', _('error_user_badconfirmationcode'));
+ $this->render();
+ return;
+ }
+
+ // split code into token and hash
+ $token = substr($code, 0, -32);
+ $hash = substr($code, -32);
+
+ // decode and hash-check the token
+ $token = base64_decode($token);
+ if (!$token || md5($token.$this->_getSecret()) != $hash) {
+ $this->publish('errormsg', _('error_user_badconfirmationcode'));
+ $this->render();
+ return;
+ }
+ $changedata = explode(',', $token);
+ if (!$changedata || count($changedata) != 3) {
+ $this->publish('errormsg', _('error_user_badconfirmationcode'));
+ $this->render();
+ return;
+ }
+ $this->Amo->clean($changedata);
+ $this->publish('newemail', $changedata[1]);
+
+ // is the token expired (48 hours max)?
+ if (time()-$changedata[2] > 48*60*60) {
+ $this->publish('errormsg', ___('error_user_emailchange_expired'));
+ $this->render();
+ return;
+ }
+
+ $thisuser = $this->User->findById($id);
+ if (empty($thisuser)) {
+ $this->publish('errormsg', _('error_user_notfound'));
+ $this->render();
+ return;
+ }
+
+ // does old email still match?
+ if ($thisuser['User']['email'] != $changedata[0]) {
+ $this->publish('errormsg', _('error_user_badconfirmationcode'));
+ $this->render();
+ return;
+ }
+
+ // is new email address still unique?
+ if ($this->User->findCount(array('User.email' => $changedata[1])) > 0) {
+ $this->publish('errormsg', _('error_user_email_notunique'));
+ $this->render();
+ return;
+ }
+
+ // finally, change the mail address and return success message.
+ if (!$this->User->save(array('User' => array(
+ 'id' => $id,
+ 'email' => $changedata[1]
+ )))) {
+ $this->publish('errormsg', _('error_user_badconfirmationcode'));
+ }
+ // fetch new user profile
+ if ($this->Session->check('User')) {
+ $currentprofile = $this->Session->read('User');
+ if ($currentprofile['id'] == $id) {
+ $newprofile = $this->User->find(array('User.id' => $id));
+ if (!empty($newprofile)) {
+ $this->Session->write('User', $newprofile['User']);
+ }
+ }
+ }
+ $this->render();
+ }
+
+ /**
+ * Show a user info page
+ * @param int user id
+ * @return void
+ */
+ function info($userid = null) {
+ global $valid_status;
+
+ $this->Amo->clean($userid);
+
+ if (!is_numeric($userid)) {
+ $this->flash(sprintf(_('error_missing_argument'), 'user_id'), '/', 3);
+ return;
+ }
+ $this->User->bindFully(); // we need their addons as well
+ $thisuser = $this->User->findById($userid);
+ if (empty($thisuser)) {
+ $this->flash(_('error_user_notfound'), '/', 3);
+ return;
+ }
+
+ // re-fetch the addons to get the translations too
+ $_addonids = array();
+ foreach($thisuser['Addon'] as $_addon) $_addonids[] = $_addon['id'];
+ if (!empty($_addonids)) {
+ $_addoncriteria = array(
+ 'Addon.id' => $_addonids,
+ 'Addon.addontype_id' => array(ADDON_EXTENSION, ADDON_THEME),
+ 'Addon.inactive' => 0,
+ 'Addon.status' => $valid_status
+ );
+ $addons = $this->Addon->findAll($_addoncriteria, null, 'Translation.name');
+ } else {
+ $addons = array();
+ }
+
+ // get all reviews made by user
+ $reviews = $this->Review->findAll("Review.user_id = {$userid} AND Review.reply_to IS NULL");
+ foreach ($reviews as &$_review) {
+ $_version = $this->Version->findById($_review['Review']['version_id'], 'Version.addon_id');
+ if (!empty($_version)) {
+ $_addon = $this->Addon->getAddon($_version['Version']['addon_id'], array('compatible_apps', 'latest_version'));
+ $_review['Addon'] = $_addon;
+ }
+ }
+ $this->publish('reviews', $reviews);
+
+ // get user's own and favorite collections, if they allowed that
+ if ($thisuser['User']['display_collections']) {
+ $coll_ids = $this->Collection->getCollectionsByUser($thisuser['User']['id']);
+ $coll = $this->Collection->findAll(array('Collection.id'=>$coll_ids, 'listed'=>1),
+ array('name', 'description', 'uuid', 'nickname', 'application_id'), 'Translation.name');
+ $this->publish('coll', $coll);
+ }
+ if ($thisuser['User']['display_collections_fav']) {
+ $coll_ids = $this->Collection->getSubscriptionsByUser($thisuser['User']['id']);
+ $coll_fav = $this->Collection->findAll(array('Collection.id'=>$coll_ids, 'listed'=>1),
+ array('name', 'description', 'uuid', 'nickname', 'application_id'), 'Translation.name');
+ $this->publish('coll_fav', $coll_fav);
+ }
+
+ if (!empty($thisuser['User']['nickname']))
+ $name = $thisuser['User']['nickname'];
+ else
+ $name = $thisuser['User']['firstname'].' '.$thisuser['User']['lastname'];
+ $_title = sprintf(_('users_info_pagetitle'), $name);
+ $this->pageTitle = $_title.' :: '.sprintf(_('addons_home_pagetitle'), APP_PRETTYNAME);
+ $this->publish('breadcrumbs', array($_title => "/user/{$userid}"));
+ $this->publish('subpagetitle', $_title);
+ $this->publish('profile', $thisuser);
+ $this->publish('addons', $addons);
+ $this->render();
+ }
+
+ /**
+ * (User-facing:) Delete a user account
+ * Anonymizes a user account (does not delete the row off the database)
+ */
+ function delete() {
+ $this->Amo->checkLoggedIn();
+
+ $this->pageTitle = ___('users_delete_pagetitle', 'Delete User Account').' :: '.sprintf(_('addons_home_pagetitle'), APP_PRETTYNAME);
+ $this->publish('cssAdd', array('forms'));
+
+ $deluser = $this->Session->read('User');
+ $this->publish('useremail', $deluser['email']);
+ $this->set('userid', $deluser['id']);
+
+ if (!empty($this->data['User'])) {
+ // deletion requested
+
+ // checkbox checked?
+ if (empty($this->data['User']['reallydelete'])) {
+ $this->set('deleteerror', 'checkbox');
+ return;
+ }
+
+ // password entered correctly?
+ if (!$this->User->checkPassword($deluser, $this->data['User']['password'])) {
+ $this->set('deleteerror', 'password');
+ $this->data['User']['password'] = ''; // do not post back password
+ return;
+ }
+
+ // disallow users that have add-ons to delete their accounts
+ if ($this->User->getAddonCount($deluser['id']) > 0) {
+ $this->set('deleteerror', 'addons');
+ return;
+ }
+
+ // delete user (includes anonymizing reviews)
+ if (!$this->User->anonymize($deluser['id'])) {
+ // failure
+ $this->set('deleteerror', 'unknown');
+ return;
+ } else {
+ // success: wipe session, display success message
+ $this->Session->stop();
+ $this->set('success', true);
+ return;
+ }
+ }
+ }
+
+ /**
+ * Associate AMO account with an LDAP group
+ * @param string $group The group name
+ */
+ function associateGroup($group) {
+ // Make sure logged into AMO
+ $this->Amo->checkLoggedIn("/users/associateGroup/{$group}");
+
+ // Make sure entered LDAP info
+ if (!isset($_SERVER['PHP_AUTH_USER'])) {
+ header('WWW-Authenticate: Basic realm="Mozilla Corporation - LDAP Login"');
+ header('HTTP/1.0 401 Unauthorized');
+ $this->flash('You must authenticate to view this page.', '/', 3);
+ return;
+ }
+
+ // Connect to LDAP
+ if (!$this->Ldap->connect($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW'])) {
+ $this->flash('Could not authenticate', '/', 3);
+ return;
+ }
+
+ // Check if in group
+ if (!$this->Ldap->hasAccount($_SERVER['PHP_AUTH_USER'], $group)) {
+ $this->flash('Not a member of requested group', '/', 3);
+ return;
+ }
+
+ $groups = array(
+ '4247a32ebaed692a8d72cea6382f8c5b' => 38
+ );
+
+ $group_id = $groups[md5($group)];
+ $user = $this->Session->read('User');
+
+ if (!empty($group_id)) {
+ // Make sure not already in group
+ if (!empty($user['Group'])) {
+ foreach ($user['Group'] as $user_group) {
+ if ($user_group['id'] == $group_id) {
+ $this->flash('You are already a member of this group!', '/', 3);
+ return;
+ }
+ }
+ }
+
+ $this->User->execute("INSERT INTO groups_users (group_id, user_id) VALUES('{$group_id}', '{$user['id']}')");
+
+ // Log user action
+ $this->Eventlog->log($this, 'user', 'group_associated', null, $group_id);
+
+ $this->flash("You have been successfully added to the {$group} group. You must log out and back in for this to take effect.", '/users/logout', 5);
+ }
+
+ return;
+ }
+
+ /**
+ * return the secret to generate and validate email changes.
+ * If necessary, generate it once.
+ */
+ function _getSecret() {
+ $secret = $this->Config->getValue('emailchange_secret');
+ if (empty($secret)) {
+ // generate a secret for the first time
+ $len = mt_rand(10, 255);
+ $secret = '';
+ while (strlen($secret) < $len)
+ $secret .= md5(mt_rand());
+ $secret = substr($secret, 0, $len);
+
+ // store it in the DB for the future
+ $this->Config->save(array('Config' => array(
+ 'key' => 'emailchange_secret',
+ 'value' => $secret)));
+ }
+ return $secret;
+ }
+
+ /**
+ * Remove forbidden characters from nicknames
+ */
+ function _filterNick($nickname) {
+ $nickname = str_replace(html_entity_decode('&#8203;', ENT_NOQUOTES, 'UTF-8'), '', $nickname); // zero-break space: bug 412694
+ return trim($nickname);
+ }
+
+}
+
+?>
diff --git a/site/app/controllers/versions_controller.php b/site/app/controllers/versions_controller.php
new file mode 100644
index 0000000..9e7cbdc
--- /dev/null
+++ b/site/app/controllers/versions_controller.php
@@ -0,0 +1,95 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Justin Scott <fligtar@mozilla.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+class VersionsController extends AppController
+{
+ var $name = 'Versions';
+ var $uses = array('Addon', 'License', 'Translation', 'Version');
+ var $components = array('Amo', 'Pagination');
+
+ function beforeFilter() {
+ // Disable ACLs because this controller is entirely public.
+ $this->SimpleAuth->enabled = false;
+ $this->SimpleAcl->enabled = false;
+ }
+
+ function license($version_id) {
+ $version = $this->Version->findById($version_id);
+ $addon = $this->Addon->getAddon($version['Version']['addon_id']);
+ $license_text = $this->License->getText($version['Version']['license_id']);
+ $this->set('version', $version);
+ $this->publish('addon', $addon);
+ $this->publish('license_text', $license_text);
+
+ // set up view, then render
+ $this->layout = 'amo2009';
+ $this->pageTitle = sprintf(___('versions_license_header_source'),
+ $addon['Translation']['name']['string'], $version['Version']['version'])
+ .' :: '.sprintf(_('addons_home_pagetitle'), APP_PRETTYNAME);
+ }
+
+ /**
+ * Displays a version's releasenotes in the form requested for updateInfoURLs
+ * See http://developer.mozilla.org/en/docs/Extension_Versioning%2C_Update_and_Compatibility
+ * @param int $version_id version's id
+ * @param string $locale locale of the client
+ */
+ function updateInfo($version_id, $locale = '') {
+ /**
+ * If the client's locale is different from our auto-detected locale, it's
+ * probably not supported by AMO, but just in case, we see if it is and
+ * switch appropriately.
+ */
+ if (!empty($locale) && $locale != LANG) {
+ global $supported_languages;
+ if (array_key_exists($locale, $supported_languages)) {
+ $this->Version->setLang($locale, $this);
+ }
+ }
+
+ $version = $this->Version->findById($version_id, array('Version.releasenotes'), null, -1);
+
+ $updateInfo = $version[0]['releasenotes'];
+
+ $this->publish('updateInfo', $updateInfo);
+ $this->render('update_info', 'ajax');
+ }
+
+}
+
+?>
diff --git a/site/app/index.php b/site/app/index.php
new file mode 100644
index 0000000..8abdb71
--- /dev/null
+++ b/site/app/index.php
@@ -0,0 +1,26 @@
+<?php
+/* SVN FILE: $Id: index.php,v 1.1.1.1 2006/08/14 23:54:56 sancus%off.net Exp $ */
+/**
+ * PHP versions 4 and 5
+ *
+ * CakePHP : Rapid Development Framework <http://www.cakephp.org/>
+ * Copyright (c) 2006, Cake Software Foundation, Inc.
+ * 1785 E. Sahara Avenue, Suite 490-204
+ * Las Vegas, Nevada 89104
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright Copyright (c) 2006, Cake Software Foundation, Inc.
+ * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP Project
+ * @package cake
+ * @subpackage cake.app
+ * @since CakePHP v 0.10.0.1076
+ * @version $Revision: 1.1.1.1 $
+ * @modifiedby $LastChangedBy: phpnut $
+ * @lastmodified $Date: 2006/08/14 23:54:56 $
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+require 'webroot' . DIRECTORY_SEPARATOR . 'index.php';
+?> \ No newline at end of file
diff --git a/site/app/locale/af/LC_MESSAGES/messages.mo b/site/app/locale/af/LC_MESSAGES/messages.mo
new file mode 100644
index 0000000..49ec6ae
--- /dev/null
+++ b/site/app/locale/af/LC_MESSAGES/messages.mo
Binary files differ
diff --git a/site/app/locale/af/LC_MESSAGES/messages.po b/site/app/locale/af/LC_MESSAGES/messages.po
new file mode 100644
index 0000000..83d68ac
--- /dev/null
+++ b/site/app/locale/af/LC_MESSAGES/messages.po
@@ -0,0 +1,9471 @@
+# Remora Preliminary Language File
+# Copyright (C) 2006 Mozilla Corporation
+# This file is distributed under the same license as the REMORA package.
+# Wil Clouser <clouserw@mozilla.com>, 2006.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: REMORA 0.1\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2009-01-16 11:45-0800\n"
+"PO-Revision-Date: 2008-09-22 13:20-0700\n"
+"Last-Translator: Wil Clouser <wclouser@mozilla.com>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=n != 1;\n"
+"X-Generator: Pootle 1.1.0\n"
+
+#: views/addons/policy.thtml:98
+#, fuzzy
+msgid "a_cancel_installation"
+msgstr "Cancel Installation"
+
+#. This is the text that appears on buttons to download add-ons.
+#. %$1s is an optional string that only appears if the add-on is only available for
+#. a certain platform. Examples: (Windows) or (Linux)
+#. Note that the parentheses are included in the string. :(
+#: views/elements/amo2009/install.thtml:126
+#: views/elements/amo2009/install.thtml:227
+#: views/elements/amo2009/install.thtml:257
+#: views/elements/amo2009/install.thtml:300
+#: views/elements/amo2009/install.thtml:312 views/elements/install.thtml:73
+#: views/elements/install.thtml:181 views/elements/install.thtml:205
+#: views/elements/install.thtml:248 views/elements/install.thtml:260
+#: views/addons/plugins.thtml:66 views/addons/plugins.thtml:76
+#: views/addons/plugins.thtml:86 views/addons/plugins.thtml:96
+#: views/addons/plugins.thtml:119
+#, fuzzy, php-format
+msgid "a_download"
+msgstr "Download Now %s"
+
+#: views/addons/policy.thtml:72
+#, fuzzy
+msgid "a_eula_download"
+msgstr "Accept and Download"
+
+#: views/addons/policy.thtml:74
+#, fuzzy
+msgid "a_eula_install"
+msgstr "Accept and Install"
+
+#: views/elements/header.thtml:76 views/elements/header.thtml:82
+#: views/api/api_addon.thtml:55 views/api/collections_feed.thtml:75
+#: views/sharing_api/addon.thtml:64
+#, fuzzy
+msgid "a_header_public"
+msgstr "Public"
+
+#: views/elements/header.thtml:58 views/elements/header.thtml:75
+#: views/elements/header.thtml:80 views/api/api_addon.thtml:57
+#: views/api/collections_feed.thtml:77 views/sharing_api/addon.thtml:66
+#, fuzzy
+msgid "a_header_sandbox"
+msgstr "Sandbox"
+
+#. %s is a date in the _('date') format
+#: views/elements/amo2009/homepage_addon.thtml:115
+#: views/elements/addon_listitem.thtml:122 views/elements/feature.thtml:106
+#: views/addons/display.thtml:104 views/addons/browse_thumbs.thtml:73
+#, fuzzy
+msgid "addon_detail_last_updated"
+msgstr "Updated %s"
+
+#. %s is the version of the add-on. Example: 3.2a1
+#: views/elements/amo2009/addon_version_detail.thtml:51
+#: views/elements/addon_version_detail.thtml:51
+#, fuzzy, php-format
+msgid "addon_display_header_version"
+msgstr "Version %s"
+
+#: views/addons/browse_thumbs.thtml:80
+#, fuzzy
+msgid "addon_downloads"
+msgstr "downloads"
+
+#: views/addons/display.thtml:147
+#, fuzzy
+msgid "addon_downloads_total"
+msgstr "total downloads"
+
+#: views/elements/amo2009/homepage_addon.thtml:106
+#: views/elements/addon_listitem.thtml:115 views/elements/feature.thtml:101
+#: views/addons/category_landing.thtml:157 views/addons/display.thtml:146
+#: views/addons/browse_thumbs.thtml:80
+#, fuzzy
+msgid "addon_downloads_weekly"
+msgstr "weekly downloads"
+
+#. %1 is the add-on count, %2 the category name
+#: views/addons/browse_thumbs.thtml:104 views/addons/browse.thtml:60
+#, fuzzy, php-format
+msgid "addon_list_category_totalcount"
+msgid_plural "addon_list_category_totalcount"
+msgstr[0] "%1$s add-on"
+msgstr[1] "%1$s add-ons"
+
+#: views/elements/amo2009/addon_list_options.thtml:103
+#: views/elements/pagination.thtml:67
+#: views/elements/addon_list_options.thtml:94
+#, fuzzy
+msgid "addon_list_perpage"
+msgstr "per page"
+
+#: views/elements/amo2009/addon_list_options.thtml:84
+#: views/elements/addon_list_options.thtml:98
+#, fuzzy
+msgid "addon_list_sortby"
+msgstr "Sort by:"
+
+#: views/helpers/addons_html.php:568 views/elements/amo2009/install.thtml:321
+#: views/elements/feature.thtml:89
+#, fuzzy
+msgid "addon_listitem_flag_experimental"
+msgstr "experimental"
+
+#: views/helpers/addons_html.php:570
+#, fuzzy
+msgid "addon_listitem_flag_recommended"
+msgstr "recommended"
+
+#. %1 is the add-on name, %2 is the platform
+#: views/pages/js_constants.js.thtml:66
+#, fuzzy
+msgid "addon_not_available_for_platform"
+msgstr "%1$s is not available for %2$s."
+
+#. %1 is the add-on name
+#: views/addons/policy.thtml:101 views/addons/previews.thtml:60
+#: views/addons/versions.thtml:130 views/reviews/flag.thtml:61
+#: views/reviews/add.thtml:114 views/reviews/display.thtml:216
+#: views/reviews/review_added.thtml:57
+#, fuzzy, php-format
+msgid "addon_review_a_back_to_addon_x"
+msgstr "Back to %1$s..."
+
+#. %1 is the add-on name
+#: views/reviews/flag.thtml:60 views/reviews/add.thtml:113
+#: views/reviews/review_added.thtml:56
+#, fuzzy, php-format
+msgid "addon_review_a_back_to_reviews"
+msgstr "Back to the reviews..."
+
+#: views/reviews/add.thtml:85
+#, fuzzy
+msgid "addon_review_add_rating_field"
+msgstr "Rating:"
+
+#: views/reviews/add.thtml:102
+#, fuzzy
+msgid "addon_review_add_review_field"
+msgstr "Review:"
+
+#: views/reviews/add.thtml:107
+#, fuzzy
+msgid "addon_review_add_submit"
+msgstr "Submit your review"
+
+#. %s is the name of the add-on
+#: views/reviews/add.thtml:51
+#, fuzzy, php-format
+msgid "addon_review_add_title"
+msgstr "Add a review for %s"
+
+#: views/reviews/add.thtml:78
+#, fuzzy
+msgid "addon_review_add_title_field"
+msgstr "Title/Summary:"
+
+#: views/reviews/display.thtml:77 views/reviews/display.thtml:161
+#, fuzzy
+msgid "addon_review_admin_delete"
+msgstr "Delete"
+
+#: views/reviews/display.thtml:76
+#, fuzzy
+msgid "addon_review_author_reply_link"
+msgstr "Reply"
+
+#: views/reviews/delete.thtml:62
+#, fuzzy
+msgid "addon_review_confirm_delete"
+msgstr "Are you sure you wish to delete this review?"
+
+#: views/reviews/delete.thtml:63
+#, fuzzy
+msgid "addon_review_confirm_no"
+msgstr "No"
+
+#: views/reviews/delete.thtml:64
+#, fuzzy
+msgid "addon_review_confirm_yes"
+msgstr "Yes"
+
+#: views/reviews/delete.thtml:48
+#, fuzzy
+msgid "addon_review_delete_header"
+msgstr "Delete Review"
+
+#: controllers/reviews_controller.php:449
+#, fuzzy
+msgid "addon_review_deleted_successfully"
+msgstr "Review deleted successfully."
+
+#. %s is the name of the add-on
+#: views/reviews/add.thtml:51
+#, fuzzy, php-format
+msgid "addon_review_edit_title"
+msgstr "Edit Review for %s"
+
+#. %1 is the count of characters entered as notes for the review flag reason.
+#: controllers/reviews_controller.php:539
+#, fuzzy
+msgid "addon_review_flag_error_other_length"
+msgstr ""
+"Problem flagging review: Notes for flagged reviews are limited to between 10 "
+"and 100 characters; your character length was %1$s."
+
+#. Removing an extra comma
+#: views/reviews/review_added.thtml:53
+#, fuzzy
+msgid "addon_review_in_moderation"
+msgstr ""
+"Please note: Before your review shows up on the public site it will be "
+"moderated by an editor."
+
+#: views/reviews/add.thtml:57
+#, fuzzy
+msgid "addon_review_in_reply_to"
+msgstr "Developer reply to:"
+
+#. %1 is the review count, %2 is the nickname or full name of the user.
+#: views/reviews/display.thtml:131
+#, fuzzy, php-format
+msgid "addon_review_others_by_user"
+msgid_plural "addon_review_others_by_user"
+msgstr[0] "See %1$s previous review submitted by %2$s for this add-on."
+msgstr[1] "See %1$s previous reviews submitted by %2$s for this add-on."
+
+#. %1 is the add-on name
+#: controllers/reviews_controller.php:201
+#: controllers/reviews_controller.php:250
+#: controllers/reviews_controller.php:345
+#: controllers/reviews_controller.php:424
+#, fuzzy, php-format
+msgid "addon_review_pagetitle"
+msgstr "Reviews for %s"
+
+#. %1 is the user, %2 is the (localized) date
+#: views/reviews/display.thtml:160
+#, fuzzy, php-format
+msgid "addon_review_reply_on_x_by_y"
+msgstr "Reply by %1$s on %2$s"
+
+#: views/reviews/display.thtml:157
+#, fuzzy
+msgid "addon_review_reply_prefix"
+msgstr "Developer Reply:"
+
+#: views/reviews/review_added.thtml:51
+#, fuzzy
+msgid "addon_review_saved_successfully"
+msgstr "Your review was saved successfully. Thanks!"
+
+#: views/addons/display.thtml:354 views/reviews/display.thtml:72
+#, fuzzy
+msgid "addon_reviewed_by_u_on_d"
+msgstr "by %1$s on %2$s"
+
+#. %1 is the user, %2 is the (localized) date, %3 is the rating
+#: views/editors/reviews_queue.thtml:57 views/editors/reviews_queue.thtml:68
+#: views/reviews/add.thtml:63 views/reviews/delete.thtml:54
+#, fuzzy, php-format
+msgid "addon_reviewed_on_x_rated_y"
+msgstr "by %1$s on %2$s (rated %3$s)"
+
+#: views/elements/amo2009/addon_version_detail.thtml:52
+#: views/elements/addon_version_detail.thtml:52
+#, fuzzy
+msgid "addon_version_permalink"
+msgstr "Permanent link to this version"
+
+#. %1 is the current Application name (e.g. Firefox)
+#. %2 is the Application's version number
+#: views/addons/versions.thtml:140
+#, fuzzy
+msgid "addon_versions_getlatestversion"
+msgstr "The most recent version compatible with %1$s %2$s"
+
+#: views/addons/display.thtml:447
+#, fuzzy
+msgid "addons_author_addons_submit"
+msgstr "Go"
+
+#: views/elements/amo2009/homepage_addon.thtml:100
+#: views/elements/feature.thtml:95
+#, fuzzy
+msgid "addons_author_tooltip"
+msgstr "View Author's Profile"
+
+#. %1 is the name of the Application (eg. Firefox)
+#: controllers/addons_controller.php:1296
+#, fuzzy
+msgid "addons_browse_all_themes_title"
+msgstr "Browse all Themes :: %1$s Add-ons"
+
+#. %s is the name of the category
+#: controllers/addons_controller.php:1016
+#, fuzzy, php-format
+msgid "addons_browse_browse_category"
+msgstr "Browse %s"
+
+#. %1 is the name of the theme category (eg. Modern)
+#. %2 is the name of the Application (eg. Firefox)
+#: controllers/addons_controller.php:664
+#, fuzzy
+msgid "addons_browse_categories_header_theme"
+msgstr "Browse %1$s Themes :: %2$s Add-ons"
+
+#: views/addons/display.thtml:249
+#, fuzzy
+msgid "addons_display_a_license_what"
+msgstr "What's this?"
+
+#: views/reviews/display.thtml:222
+#, fuzzy
+msgid "addons_display_add_review"
+msgstr "Add a review"
+
+#: views/addons/display.thtml:294
+#, fuzzy
+msgid "addons_display_advanced_details"
+msgstr "Advanced Details"
+
+#: views/addons/display.thtml:98
+#, fuzzy
+msgid "addons_display_categories"
+msgstr "Categories"
+
+#: views/addons/display.thtml:482
+#, fuzzy
+msgid "addons_display_collection_add"
+msgstr "Add to a collection:"
+
+#: views/addons/display.thtml:491
+#, fuzzy
+msgid "addons_display_collection_add_new"
+msgstr "New Collection..."
+
+#: views/addons/display.thtml:487
+#, fuzzy
+msgid "addons_display_collection_add_select_one"
+msgstr "Select a collection..."
+
+#: views/addons/display.thtml:493
+#, fuzzy
+msgid "addons_display_collection_add_submit"
+msgstr "Publish"
+
+#. %1$s is the add-on name
+#. %2$s is the collection name, linked to the collection's page
+#: views/pages/js_constants.js.thtml:103 views/addons/display.thtml:61
+#, fuzzy
+msgid "addons_display_collection_publish_success"
+msgstr "%1$s has been added to the %2$s collection."
+
+#: views/addons/display.thtml:483
+#, fuzzy
+msgid "addons_display_collection_whatsthis"
+msgstr "What's this?"
+
+#. %1$s is a number
+#: views/addons/display.thtml:473
+#, fuzzy
+msgid "addons_display_collections_more"
+msgid_plural "addons_display_collections_more"
+msgstr[0] "and %1$s more collection"
+msgstr[1] "and %1$s more collections"
+
+#: views/addons/display.thtml:403
+#, fuzzy
+msgid "addons_display_detailed_review"
+msgstr "detailed review"
+
+#: views/reviews/add.thtml:89 views/reviews/add.thtml:90
+#, fuzzy
+msgid "addons_display_dont_like_it"
+msgstr "Don't like it"
+
+#: views/reviews/display.thtml:220
+#, fuzzy
+msgid "addons_display_edit_review"
+msgstr "Edit your review"
+
+#: views/addons/display.thtml:132
+#, fuzzy
+msgid "addons_display_has_privacy"
+msgstr "This add-on has a privacy policy."
+
+#: views/reviews/add.thtml:87 views/reviews/add.thtml:88
+#, fuzzy
+msgid "addons_display_hate_it"
+msgstr "Hate it"
+
+#: views/addons/display.thtml:462
+#, fuzzy
+msgid "addons_display_header_collections"
+msgstr "Related Collections"
+
+#: views/addons/display.thtml:297
+#, fuzzy
+msgid "addons_display_header_developer_comments"
+msgstr "Developer Comments"
+
+#: views/addons/display.thtml:230
+#, fuzzy
+msgid "addons_display_header_homepage"
+msgstr "Homepage"
+
+#: views/addons/display.thtml:247 views/addons/versions.thtml:110
+#, fuzzy
+msgid "addons_display_header_license"
+msgstr "Source Code License"
+
+#: views/addons/display.thtml:337
+#, fuzzy
+msgid "addons_display_header_reviews"
+msgstr "Reviews"
+
+#: views/addons/display.thtml:261
+#, fuzzy
+msgid "addons_display_header_support"
+msgstr "Support"
+
+#: views/reviews/add.thtml:91 views/reviews/add.thtml:92
+#, fuzzy
+msgid "addons_display_like_it"
+msgstr "Like it"
+
+#: views/addons/display.thtml:210
+#, fuzzy
+msgid "addons_display_long_description"
+msgstr "Long Description"
+
+#: views/reviews/add.thtml:95 views/reviews/add.thtml:96
+#, fuzzy
+msgid "addons_display_love_it"
+msgstr "Love it"
+
+#: views/addons/display.thtml:178
+#, fuzzy
+msgid "addons_display_more_images"
+msgstr "More Images"
+
+#: views/addons/display.thtml:465
+#, fuzzy
+msgid "addons_display_nocollections"
+msgstr "This add-on is not yet in any collections."
+
+#. %1$s is either an author's name or a comma separated list of authors. Using
+#. the list doesn't make sense in the English plural form so we ignore the
+#. variable.
+#: views/addons/display.thtml:436
+#, fuzzy
+msgid "addons_display_other_addons_by"
+msgid_plural "addons_display_other_addons_by"
+msgstr[0] "Other add-ons by %1$s"
+msgstr[1] "Other add-ons by these authors"
+
+#. %s is the name of the add-on and the add-on section. Example:
+#. Some Add-on :: Firefox Add-ons
+#. This should not be concatenated in the code and should be fixed.
+#: controllers/addons_controller.php:141 controllers/addons_controller.php:280
+#: controllers/addons_controller.php:1442
+#, fuzzy, php-format
+msgid "addons_display_pagetitle"
+msgstr "%s"
+
+#. %s is an email address
+#: views/addons/display.thtml:286
+#, fuzzy, php-format
+msgid "addons_display_paragraph_supportinfoemail"
+msgstr "Support for this add-on is provided by the developer at %s"
+
+#. %$1s is a URL
+#. %$2s is an email address
+#: views/addons/display.thtml:269
+#, fuzzy, php-format
+msgid "addons_display_paragraph_supportinfoemailurl"
+msgstr ""
+"Support for this add-on is provided by the developer at %s or by sending an "
+"e-mail to %s"
+
+#. %s is a URL
+#: views/addons/display.thtml:278
+#, fuzzy, php-format
+msgid "addons_display_paragraph_supportinfourl"
+msgstr "Support for this add-on is provided by the developer at %s"
+
+#: views/addons/display.thtml:383
+#, fuzzy
+msgid "addons_display_rate_it"
+msgstr "Rate It"
+
+#: views/reviews/add.thtml:93 views/reviews/add.thtml:94
+#, fuzzy
+msgid "addons_display_really_like_it"
+msgstr "Really like it"
+
+#: views/addons/display.thtml:410
+#, fuzzy
+msgid "addons_display_review_etiquette"
+msgstr ""
+"Please do not post bug reports in reviews. We do not make your email address "
+"available to add-on developers and they may need to contact you to help "
+"resolve your issue."
+
+#. %1 is the review guidelines link
+#: views/addons/display.thtml:417
+#, fuzzy
+msgid "addons_display_review_guidelines_link"
+msgstr "<a href=\"%s\">Review Guidelines</a>"
+
+#. %1 is the support section link
+#: views/addons/display.thtml:414
+#, fuzzy
+msgid "addons_display_review_see_support"
+msgstr ""
+"See the <a href=\"%1$s\">support section</a> to find out where to get "
+"assistance for this add-on."
+
+#: views/addons/display.thtml:404
+#, fuzzy
+msgid "addons_display_review_submit"
+msgstr "Save"
+
+#: views/addons/display.thtml:430
+#, fuzzy, php-format
+msgid "addons_display_see_all_addons"
+msgstr "See All %1$s Add-ons"
+
+#. %1 is the number of reviews
+#: views/addons/display.thtml:364
+#, fuzzy, php-format
+msgid "addons_display_see_all_reviews"
+msgstr "See all reviews (%1$s)"
+
+#: views/addons/display.thtml:219
+#, fuzzy
+msgid "addons_display_see_all_versions"
+msgstr "See All Versions"
+
+#: views/addons/display.thtml:321 views/addons/versions.thtml:117
+#, fuzzy
+msgid "addons_display_view_source"
+msgstr "View the source"
+
+#: views/addons/display.thtml:324
+#, fuzzy
+msgid "addons_display_view_stats"
+msgstr "View statistics"
+
+#: views/addons/display.thtml:376
+#, fuzzy
+msgid "addons_display_what_do_you_think"
+msgstr "What do you think?"
+
+#: views/elements/app_compatibility.thtml:49
+#, fuzzy
+msgid "addons_display_workswith"
+msgstr "Works with:"
+
+#: views/addons/home.thtml:112
+#, fuzzy
+msgid "addons_home_browse_new"
+msgstr "Just Added"
+
+#: views/addons/home.thtml:110
+#, fuzzy
+msgid "addons_home_browse_popular"
+msgstr "Popular"
+
+#: views/addons/home.thtml:108
+#, fuzzy
+msgid "addons_home_browse_recommended"
+msgstr "Recommended"
+
+#: views/addons/home.thtml:127 views/addons/home.thtml:134
+#: views/addons/home.thtml:141 views/addons/home.thtml:148
+#, fuzzy
+msgid "addons_home_browse_subscribe"
+msgstr "Subscribe"
+
+#: views/addons/home.thtml:101
+#, fuzzy
+msgid "addons_home_browse_title"
+msgstr "Browse Add-ons"
+
+#: views/addons/home.thtml:114
+#, fuzzy
+msgid "addons_home_browse_updated"
+msgstr "Updated"
+
+#: views/elements/amo2009/homepage_addon.thtml:100
+#: views/elements/addon_discussionheader.thtml:83
+#: views/elements/addon_listitem.thtml:109 views/elements/feature.thtml:95
+#: views/addons/category_landing.thtml:66 views/addons/policy.thtml:57
+#: views/addons/display.thtml:70 views/addons/home.thtml:178
+#, fuzzy
+msgid "addons_home_by"
+msgstr "by"
+
+#: views/addons/home.thtml:169
+#, fuzzy
+msgid "addons_home_collection_popular_title"
+msgstr "Popular Collections"
+
+#: views/elements/amo2009/categories.thtml:69 views/addons/home.thtml:160
+#, fuzzy
+msgid "addons_home_collections"
+msgstr "Collections"
+
+#. %1$s is the count of addons in a collection
+#: views/elements/amo2009/collection_listing_item.thtml:51
+#: views/addons/home.thtml:185
+#, fuzzy
+msgid "addons_home_collections_addon_count"
+msgid_plural "addons_home_collections_addon_count"
+msgstr[0] "<strong>%1$s</strong> add-on"
+msgstr[1] "<strong>%1$s</strong> add-ons"
+
+#: views/addons/home.thtml:196
+#, fuzzy
+msgid "addons_home_collections_all"
+msgstr "View All Collections"
+
+#: views/addons/home.thtml:162
+#, fuzzy
+msgid "addons_home_collections_intro"
+msgstr ""
+"Collections are a way for you to categorize, mix, match and mingle add-ons. "
+"Subscribe to collections created by other users or create your own."
+
+#. %1$s is the count of subscribers for a collection
+#: views/elements/amo2009/collection_listing_item.thtml:58
+#: views/collections/detail.thtml:96 views/addons/home.thtml:189
+#, fuzzy
+msgid "addons_home_collections_subscribers"
+msgid_plural "addons_home_collections_subscribers"
+msgstr[0] "<strong>%1$s</strong> subscriber"
+msgstr[1] "<strong>%1$s</strong> subscribers"
+
+#: views/addons/searchengines.thtml:54 views/addons/themes_landing.thtml:49
+#, fuzzy
+msgid "addons_home_feature_head"
+msgstr "We Recommend"
+
+#: controllers/search_controller.php:218 controllers/addons_controller.php:176
+#: controllers/addons_controller.php:428 controllers/addons_controller.php:671
+#: controllers/addons_controller.php:871
+#: controllers/addons_controller.php:1103
+#: controllers/addons_controller.php:1242
+#: controllers/addons_controller.php:1298
+#, fuzzy, php-format
+msgid "addons_home_header_details"
+msgstr ""
+"Add-ons extend %1$s, letting you personalize your browsing experience. Take "
+"a look around and make %1$s your own."
+
+#. %1$s is the HTML collection name link.
+#: views/elements/amo2009/teaser_collections.thtml:107
+#, fuzzy
+msgid "addons_home_introduction_collection_link"
+msgstr "Like these? Find more add-ons in %1$s."
+
+#: views/elements/amo2009/teaser_collections.thtml:60
+#, fuzzy
+msgid "addons_home_introduction_extras"
+msgstr ""
+"<strong>Over 5000 free extras</strong> that let you to customize and extend "
+"Firefox to meet your needs."
+
+#: views/elements/amo2009/teaser_collections.thtml:55
+#, fuzzy
+msgid "addons_home_introduction_header"
+msgstr "What are Add-ons?"
+
+#: views/elements/amo2009/teaser_collections.thtml:72
+#, fuzzy
+msgid "addons_home_introduction_install"
+msgstr ""
+"<strong>Easy to install</strong>, get notified when updates are available."
+
+#: views/elements/amo2009/teaser_collections.thtml:45
+#, fuzzy
+msgid "addons_home_introduction_name"
+msgstr "Introduction"
+
+#: views/elements/amo2009/teaser_collections.thtml:66
+#, fuzzy
+msgid "addons_home_introduction_themes"
+msgstr ""
+"Toolbars, themes and search providers that <strong>help you perform common "
+"tasks.</strong>"
+
+#: views/addons/home.thtml:161
+#, fuzzy
+msgid "addons_home_new_indicator"
+msgstr "NEW!"
+
+#: views/elements/app_chooser.thtml:48 views/layouts/amo2009.thtml:257
+#, fuzzy
+msgid "addons_home_other_applications"
+msgstr "Other Applications"
+
+#. %1$s is the application the user is browsing. Examples: Thunderbird, Firefox,
+#. Sunbird
+#: views/pages/collector_faq.thtml:49 views/pages/collector_firstrun.thtml:42
+#: views/pages/collector.thtml:46 views/pages/collector_features.thtml:54
+#: controllers/developers_controller.php:87
+#: controllers/compatibility_controller.php:72
+#: controllers/components/simple_acl.php:81 controllers/components/amo.php:607
+#: controllers/statistics_controller.php:60
+#: controllers/statistics_controller.php:240
+#: controllers/previews_controller.php:67 controllers/users_controller.php:90
+#: controllers/users_controller.php:223 controllers/users_controller.php:330
+#: controllers/users_controller.php:414 controllers/users_controller.php:708
+#: controllers/users_controller.php:723 controllers/reviews_controller.php:204
+#: controllers/reviews_controller.php:251
+#: controllers/reviews_controller.php:346
+#: controllers/reviews_controller.php:425
+#: controllers/search_controller.php:185 controllers/search_controller.php:297
+#: controllers/search_controller.php:301 controllers/addons_controller.php:147
+#: controllers/addons_controller.php:280 controllers/addons_controller.php:370
+#: controllers/addons_controller.php:667 controllers/addons_controller.php:874
+#: controllers/addons_controller.php:1019
+#: controllers/addons_controller.php:1034
+#: controllers/addons_controller.php:1101
+#: controllers/addons_controller.php:1121
+#: controllers/addons_controller.php:1240
+#: controllers/addons_controller.php:1357
+#: controllers/addons_controller.php:1364
+#: controllers/addons_controller.php:1442
+#: controllers/addons_controller.php:1477
+#: controllers/addons_controller.php:1538
+#: controllers/addons_controller.php:1543
+#: controllers/editors_controller.php:64 controllers/pages_controller.php:132
+#: controllers/groups_controller.php:65 controllers/groups_controller.php:71
+#: controllers/groups_controller.php:89 controllers/groups_controller.php:111
+#: controllers/collections_controller.php:57
+#: controllers/collections_controller.php:121
+#: controllers/collections_controller.php:205
+#: controllers/collections_controller.php:365
+#: controllers/collections_controller.php:404
+#: controllers/collections_controller.php:466
+#: controllers/collections_controller.php:538
+#: controllers/collections_controller.php:828
+#: controllers/localizers_controller.php:72
+#, fuzzy, php-format
+msgid "addons_home_pagetitle"
+msgstr "%1$s Add-ons"
+
+#. %1$s is the number of addons downloaded
+#: views/addons/home.thtml:57
+#, fuzzy, php-format
+msgid "addons_home_stats_downloaded"
+msgid_plural "addons_home_stats_downloaded"
+msgstr[0] "<strong>%1$s</strong> <span>add-on downloaded</span>"
+msgstr[1] "<strong>%1$s</strong> <span>add-ons downloaded</span>"
+
+#. %1$s is the number of addons in use
+#: views/addons/home.thtml:63
+#, fuzzy, php-format
+msgid "addons_home_stats_inuse"
+msgid_plural "addons_home_stats_inuse"
+msgstr[0] "<strong>%1$s</strong> <span>add-on in use</span>"
+msgstr[1] "<strong>%1$s</strong> <span>add-ons in use</span>"
+
+#: views/addons/home.thtml:136
+#, fuzzy
+msgid "addons_home_view_all_newest_title"
+msgstr "View all newly created add-ons"
+
+#: views/addons/home.thtml:129
+#, fuzzy
+msgid "addons_home_view_all_popular_title"
+msgstr "View all popular add-ons"
+
+#: views/addons/home.thtml:150
+#, fuzzy
+msgid "addons_home_view_all_recommended_title"
+msgstr "View all recommended add-ons"
+
+#: views/addons/home.thtml:143
+#, fuzzy
+msgid "addons_home_view_all_updated_title"
+msgstr "View all recently updated add-ons"
+
+#: views/elements/amo2009/install.thtml:334 views/elements/install.thtml:112
+#, fuzzy
+msgid "addons_install_in_sunbird"
+msgstr ""
+"<ol><li>Click the link below to save the file.</li><li>In Mozilla Sunbird, "
+"open Add-ons from the Tools menu.</li><li>Click the Install button, and "
+"locate/select the file you downloaded and click \"OK\".</li></ol>"
+
+#: views/elements/amo2009/install.thtml:333 views/elements/install.thtml:111
+#, fuzzy
+msgid "addons_install_in_sunbird_title"
+msgstr "How to Install in Sunbird"
+
+#: views/elements/amo2009/install.thtml:331 views/elements/install.thtml:106
+#, fuzzy
+msgid "addons_install_in_thunderbird"
+msgstr ""
+"<ol><li>Right-click the link below and choose \"Save Link As...\" to "
+"download and save the file to your hard disk.</li><li>In Mozilla "
+"Thunderbird, open Add-ons from the Tools menu.</li><li>Click the Install "
+"button, and locate/select the file you downloaded and click \"OK\".</li></ol>"
+
+#: views/elements/amo2009/install.thtml:330 views/elements/install.thtml:105
+#, fuzzy
+msgid "addons_install_in_thunderbird_title"
+msgstr "How to Install in Thunderbird"
+
+#: views/elements/amo2009/addon_list_options.thtml:108
+#: views/elements/addon_list_options.thtml:105
+#, fuzzy
+msgid "addons_options_show_experimental"
+msgstr "show experimental add-ons"
+
+#: views/elements/amo2009/addon_list_options.thtml:113
+#: views/elements/addon_list_options.thtml:109
+#, fuzzy
+msgid "addons_options_submit"
+msgstr "Go"
+
+#: views/addons/plugins.thtml:63 views/addons/plugins.thtml:73
+#: views/addons/plugins.thtml:83 views/addons/plugins.thtml:93
+#: views/addons/plugins.thtml:103 views/addons/plugins.thtml:116
+#: views/addons/plugins.thtml:126
+#, fuzzy
+msgid "addons_plugins_by"
+msgstr "By"
+
+#: views/addons/plugins.thtml:107
+#, fuzzy
+msgid "addons_plugins_for_linux"
+msgstr "for Linux"
+
+#: views/addons/plugins.thtml:108 views/addons/plugins.thtml:131
+#, fuzzy
+msgid "addons_plugins_for_macosx"
+msgstr "for Mac OS X"
+
+#: views/addons/plugins.thtml:106 views/addons/plugins.thtml:129
+#: views/addons/plugins.thtml:130
+#, fuzzy
+msgid "addons_plugins_for_windows"
+msgstr "for Windows"
+
+#. %1$s is a URL
+#: views/addons/plugins.thtml:139
+#, fuzzy, php-format
+msgid "addons_plugins_looking_for_more"
+msgstr ""
+"This page only lists some of the most common and most popular plugins. For "
+"more information about other plugins available for Mozilla-based Browsers, "
+"visit %1$s"
+
+#: views/addons/plugins.thtml:137
+#, fuzzy
+msgid "addons_plugins_looking_for_plugin"
+msgstr "Looking for a plugin not listed here?"
+
+#: views/addons/plugins.thtml:58
+#, fuzzy
+msgid "addons_plugins_main_description"
+msgstr ""
+"Plugins help your browser perform specific functions like viewing special "
+"graphic formats or playing multimedia files. Plugins are slightly different "
+"from extensions, which modify or add to existing functionality."
+
+#. %1$s is the application name. Example: Firefox, Thunderbird, Sunbird
+#: controllers/addons_controller.php:1122
+#, fuzzy, php-format
+msgid "addons_plugins_main_header"
+msgstr "Common Plugins for %1$s"
+
+#: controllers/components/amo.php:698 controllers/addons_controller.php:1121
+#, fuzzy
+msgid "addons_plugins_pagetitle"
+msgstr "Plugins"
+
+#: views/addons/plugins.thtml:68 views/addons/plugins.thtml:78
+#: views/addons/plugins.thtml:88 views/addons/plugins.thtml:98
+#: views/addons/plugins.thtml:110 views/addons/plugins.thtml:121
+#: views/addons/plugins.thtml:133
+#, fuzzy
+msgid "addons_plugins_support_documentation"
+msgstr "Support Documentation: "
+
+#. %s is the name of the add-on
+#: views/addons/policy.thtml:61
+#, fuzzy, php-format
+msgid "addons_policy_eula_require"
+msgstr ""
+"%s requires that you accept the following End-User License Agreement before "
+"installation can proceed:"
+
+#. %1 is the add-on name
+#: controllers/addons_controller.php:1476
+#, fuzzy, php-format
+msgid "addons_previews_pagetitle"
+msgstr "Previews for %s"
+
+#: views/addons/category_landing.thtml:135
+#, fuzzy
+msgid "addons_recently_added"
+msgstr "Recently Added"
+
+#: views/addons/recommended.thtml:51 controllers/addons_controller.php:1365
+#, fuzzy
+msgid "addons_recommended_introduction"
+msgstr ""
+"With so many great add-ons available, there's something for everyone. To get "
+"you started, here's a list of some of the most popular. Enjoy!"
+
+#: controllers/addons_controller.php:1357
+#: controllers/addons_controller.php:1364
+#, fuzzy
+msgid "addons_recommended_pagetitle"
+msgstr "Recommended Add-ons"
+
+#: controllers/addons_controller.php:1360
+#, fuzzy
+msgid "addons_recommended_title"
+msgstr "Recommended Add-ons"
+
+#: views/addons/searchengines.thtml:136
+#, fuzzy
+msgid "addons_searchengines_additional_resources"
+msgstr "Additional Resources"
+
+#. link text devmo
+#: views/addons/searchengines.thtml:141
+#, fuzzy
+msgid "addons_searchengines_devmo_link"
+msgstr "Mozilla Developer Center"
+
+#: views/pages/js_constants.js.thtml:67
+#, fuzzy
+msgid "addons_searchengines_error_mozilla_browser_required"
+msgstr ""
+"Sorry, you need a Mozilla-based browser (such as Firefox) to install a "
+"search plugin."
+
+#: views/addons/searchengines.thtml:49
+#, fuzzy
+msgid "addons_searchengines_error_nojavascript"
+msgstr ""
+"JavaScript is required to install plugins, but it looks like you have it "
+"disabled. Please enable JavaScript before trying to install any of the "
+"search plugins below."
+
+#. %1 is "make your own" link
+#. %2 is MDC link
+#: views/addons/searchengines.thtml:139
+#, fuzzy
+msgid "addons_searchengines_learn_howto"
+msgstr "Learn how to %1$s at the %2$s."
+
+#. link path to search plugins instructions, relative to devmo
+#: views/addons/searchengines.thtml:140
+#, fuzzy
+msgid "addons_searchengines_makeyourown_href"
+msgstr "/en/docs/Creating_OpenSearch_plugins_for_Firefox"
+
+#. link text for "make your own" (opensearch engine)
+#: views/addons/searchengines.thtml:140
+#, fuzzy
+msgid "addons_searchengines_makeyourown_link"
+msgstr "make your own"
+
+#. %1 is the link to mycroft.mozdev.org
+#: views/addons/searchengines.thtml:138
+#, fuzzy
+msgid "addons_searchengines_more"
+msgstr "Browse through more search engines at %1$s"
+
+#. link text to mycroft.mozdev.org
+#: views/addons/searchengines.thtml:138
+#, fuzzy
+msgid "addons_searchengines_mycroft_link"
+msgstr "mycroft.mozdev.org"
+
+#: controllers/addons_controller.php:1100
+#: controllers/addons_controller.php:1110
+#, fuzzy
+msgid "addons_searchengines_pagetitle"
+msgstr "Search Engines"
+
+#: views/addons/searchengines.thtml:143
+#, fuzzy
+msgid "addons_searchengines_thanks"
+msgstr ""
+"Special thanks to the Mycroft Project for their work on Firefox Search "
+"Engines."
+
+#: views/addons/display.thtml:154
+#, fuzzy
+msgid "addons_share_button_text"
+msgstr "Share this"
+
+#: controllers/addons_controller.php:89
+#, fuzzy
+msgid "addons_share_label_delicious"
+msgstr "Add to Delicious"
+
+#: controllers/addons_controller.php:77
+#, fuzzy
+msgid "addons_share_label_digg"
+msgstr "Digg this!"
+
+#: controllers/addons_controller.php:83
+#, fuzzy
+msgid "addons_share_label_facebook"
+msgstr "Post to Facebook"
+
+#: controllers/addons_controller.php:101
+#, fuzzy
+msgid "addons_share_label_friendfeed"
+msgstr "Share on FriendFeed"
+
+#: controllers/addons_controller.php:95
+#, fuzzy
+msgid "addons_share_label_myspace"
+msgstr "Post to MySpace"
+
+#: controllers/components/amo.php:201 controllers/components/amo.php:229
+#, fuzzy
+msgid "addons_status_disabled"
+msgstr "Disabled"
+
+#: controllers/components/amo.php:191 controllers/components/amo.php:224
+#, fuzzy
+msgid "addons_status_incomplete"
+msgstr "Incomplete Version"
+
+#: controllers/components/amo.php:197 controllers/components/amo.php:227
+#, fuzzy
+msgid "addons_status_nominated"
+msgstr "In Sandbox; Public Nomination"
+
+#: views/pages/js_constants.js.thtml:80 controllers/components/amo.php:195
+#: controllers/components/amo.php:226
+#, fuzzy
+msgid "addons_status_pending"
+msgstr "In Sandbox; Pending Review"
+
+#: views/pages/js_constants.js.thtml:78 controllers/components/amo.php:199
+#: controllers/components/amo.php:228
+#, fuzzy
+msgid "addons_status_public"
+msgstr "Public"
+
+#: views/pages/js_constants.js.thtml:79 controllers/components/amo.php:193
+#: controllers/components/amo.php:225
+#, fuzzy
+msgid "addons_status_sandbox"
+msgstr "In Sandbox"
+
+#: controllers/components/amo.php:203
+#, fuzzy
+msgid "addons_status_unknown"
+msgstr "Unknown"
+
+#: views/elements/amo2009/teaser_collections.thtml:91
+#: views/elements/amo2009/homepage_addon.thtml:99
+#: views/elements/feature.thtml:94
+#, fuzzy
+msgid "addons_title_tooltip"
+msgstr "Learn more about this add-on"
+
+#: views/addons/category_landing.thtml:151
+#, fuzzy
+msgid "addons_top_downloads"
+msgstr "Top Downloads"
+
+#: views/addons/category_landing.thtml:165
+#, fuzzy
+msgid "addons_top_rated"
+msgstr "Top Rated"
+
+#: views/addons/versions.thtml:62
+#, fuzzy
+msgid "addons_versions_careful"
+msgstr "Be Careful With Old Versions"
+
+#: views/addons/versions.thtml:63
+#, fuzzy
+msgid "addons_versions_careful_introduction"
+msgstr ""
+"These versions are displayed for reference and testing purposes. You should "
+"always use the latest version of an add-on."
+
+#: controllers/addons_controller.php:1549
+#, fuzzy
+msgid "addons_versions_history"
+msgstr "Version History with Changelogs"
+
+#. %1$s is the add-on name
+#: controllers/addons_controller.php:1535
+#, fuzzy, php-format
+msgid "addons_versions_pagetitle"
+msgstr "%1$s Version History"
+
+#: controllers/groups_controller.php:71
+#, fuzzy
+msgid "admin_group_add_pagetitle"
+msgstr "Add Group"
+
+#: controllers/groups_controller.php:111
+#, fuzzy
+msgid "admin_group_delete_pagetitle"
+msgstr "Delete Group"
+
+#. %s is a number to identify the group
+#: controllers/groups_controller.php:117
+#, fuzzy, php-format
+msgid "admin_group_deleted"
+msgstr "The Group with id %s was deleted"
+
+#: controllers/groups_controller.php:89
+#, fuzzy
+msgid "admin_group_edit_pagetitle"
+msgstr "Edit Group"
+
+#: controllers/groups_controller.php:92 controllers/groups_controller.php:113
+#, fuzzy
+msgid "admin_group_error_invalid_id"
+msgstr "Invalid id for Group"
+
+#: controllers/groups_controller.php:65
+#, fuzzy
+msgid "admin_group_pagetitle"
+msgstr "Group Admin"
+
+#: controllers/groups_controller.php:77 controllers/groups_controller.php:99
+#, fuzzy
+msgid "admin_group_saved"
+msgstr "The Group has been saved"
+
+#: views/elements/amo2009/search.thtml:257 views/elements/search.thtml:239
+#, fuzzy
+msgid "advanced_search_form"
+msgstr "Advanced"
+
+#: views/elements/amo2009/search.thtml:126 views/elements/search.thtml:125
+#, fuzzy
+msgid "advanced_search_form_any_time"
+msgstr "Any time"
+
+#: views/elements/amo2009/search.thtml:97
+#: views/elements/amo2009/search.thtml:110 views/elements/search.thtml:96
+#: views/elements/search.thtml:109
+#, fuzzy
+msgid "advanced_search_form_any_type"
+msgstr "Any"
+
+#: views/elements/amo2009/search.thtml:275 views/elements/search.thtml:254
+#, fuzzy
+msgid "advanced_search_form_any_version"
+msgstr "Any"
+
+#: views/elements/amo2009/search.thtml:217 views/elements/search.thtml:212
+#, fuzzy
+msgid "advanced_search_form_application"
+msgstr "Application"
+
+#: views/elements/amo2009/search.thtml:143 views/elements/search.thtml:142
+#, fuzzy
+msgid "advanced_search_form_keyword_match"
+msgstr "Keyword Match"
+
+#: views/elements/amo2009/search.thtml:251 views/elements/search.thtml:225
+#, fuzzy
+msgid "advanced_search_form_lastupdate"
+msgstr "Last Updated"
+
+#: views/elements/amo2009/search.thtml:145 views/elements/search.thtml:144
+#, fuzzy
+msgid "advanced_search_form_name"
+msgstr "Name"
+
+#: views/elements/amo2009/search.thtml:144 views/elements/search.thtml:143
+#, fuzzy
+msgid "advanced_search_form_newest"
+msgstr "Newest"
+
+#: views/elements/amo2009/search.thtml:130 views/elements/search.thtml:129
+#, fuzzy
+msgid "advanced_search_form_past_3_months"
+msgstr "Past 3 months"
+
+#: views/elements/amo2009/search.thtml:131 views/elements/search.thtml:130
+#, fuzzy
+msgid "advanced_search_form_past_6_months"
+msgstr "Past 6 months"
+
+#: views/elements/amo2009/search.thtml:127 views/elements/search.thtml:126
+#, fuzzy
+msgid "advanced_search_form_past_day"
+msgstr "Past Day"
+
+#: views/elements/amo2009/search.thtml:129 views/elements/search.thtml:128
+#, fuzzy
+msgid "advanced_search_form_past_month"
+msgstr "Past month"
+
+#: views/elements/amo2009/search.thtml:128 views/elements/search.thtml:127
+#, fuzzy
+msgid "advanced_search_form_past_week"
+msgstr "Past week"
+
+#: views/elements/amo2009/search.thtml:132 views/elements/search.thtml:131
+#, fuzzy
+msgid "advanced_search_form_past_year"
+msgstr "Past year"
+
+#: views/elements/amo2009/search.thtml:239 views/elements/search.thtml:230
+#, fuzzy
+msgid "advanced_search_form_perpage"
+msgstr "Per Page"
+
+#: views/elements/amo2009/search.thtml:243 views/elements/search.thtml:224
+#, fuzzy
+msgid "advanced_search_form_platform"
+msgstr "Platform"
+
+#: views/elements/amo2009/search.thtml:147 views/elements/search.thtml:146
+#, fuzzy
+msgid "advanced_search_form_popularity"
+msgstr "Popularity"
+
+#: views/elements/amo2009/search.thtml:146 views/elements/search.thtml:145
+#, fuzzy
+msgid "advanced_search_form_rating"
+msgstr "Rating"
+
+#: views/elements/amo2009/search.thtml:247 views/elements/search.thtml:231
+#, fuzzy
+msgid "advanced_search_form_sortby"
+msgstr "Sort By"
+
+#: views/elements/amo2009/search.thtml:227 views/elements/search.thtml:216
+#, fuzzy
+msgid "advanced_search_form_to"
+msgstr "to"
+
+#: views/elements/amo2009/search.thtml:257 views/elements/search.thtml:237
+#, fuzzy
+msgid "advanced_search_form_toggle_tooltip"
+msgstr "Toggle advanced search mode"
+
+#: views/elements/amo2009/search.thtml:235 views/elements/search.thtml:223
+#, fuzzy
+msgid "advanced_search_form_type"
+msgstr "Type"
+
+#: views/elements/amo2009/search.thtml:222 views/elements/search.thtml:214
+#, fuzzy
+msgid "advanced_search_form_version"
+msgstr "version"
+
+#: views/elements/amo2009/pagination.thtml:42
+#, fuzzy
+msgid "amo2009_pagination_next_page"
+msgstr "Next"
+
+#: views/elements/amo2009/pagination.thtml:41
+#, fuzzy
+msgid "amo2009_pagination_previous_page"
+msgstr "Prev"
+
+#: views/pages/js_constants.js.thtml:96
+#, fuzzy
+msgid "app_compat_ignore_check"
+msgstr "Ignore version check"
+
+#: views/pages/js_constants.js.thtml:72
+#, fuzzy
+msgid "app_compat_older_firefox_only"
+msgstr "This add-on is for older versions of Firefox"
+
+#. %1$s and %2$s are URLs
+#: views/pages/js_constants.js.thtml:74
+#, fuzzy
+msgid "app_compat_older_version_or_ignore_check"
+msgstr ""
+"You can <a href=\"%1$s\">try an older version</a> or <a href=\"#\" onclick="
+"\"%2$s\">ignore this check</a>"
+
+#. %1$s is a URL
+#: views/pages/js_constants.js.thtml:71
+#, fuzzy
+msgid "app_compat_try_old_version"
+msgstr "An <a href=\"%1$s\">older version</a> may work"
+
+#. %1$s is a URL
+#. %2$s is a version number. Example: 3.1
+#: views/pages/js_constants.js.thtml:73
+#, fuzzy
+msgid "app_compat_unreleased_version"
+msgstr ""
+"This add-on requires the not-yet released <a href=\"%1$s\">Firefox %2$s</a>"
+
+#: views/pages/js_constants.js.thtml:70
+#, fuzzy
+msgid "app_compat_update_firefox"
+msgstr ""
+"<a href=\"http://getfirefox.com\">Upgrade Firefox</a> to use this add-on"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#. %3$s is a status, like Public.
+#: controllers/components/audit.php:79
+#, fuzzy
+msgid "audit_addon_status"
+msgstr "%1$s changed the status of %2$s to %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:221
+#, fuzzy
+msgid "audit_admin_default"
+msgstr "%1$s committed unknown admin action %2$s to ID %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:153
+#, fuzzy
+msgid "audit_admin_feature_remove"
+msgstr "%1$s removed feature %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is an application, like Firefox.
+#: controllers/components/audit.php:92
+#, fuzzy
+msgid "audit_application_create"
+msgstr "%1$s created application %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is an application, like Firefox.
+#: controllers/components/audit.php:95
+#, fuzzy
+msgid "audit_application_edit"
+msgstr "%1$s edited application %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a version number, like 3.5.
+#. %3$s is an application, like Firefox.
+#: controllers/components/audit.php:105
+#, fuzzy
+msgid "audit_appversion_create"
+msgstr "%1$s created version %2$s for %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a version number, like 3.5.
+#. %3$s is an application, like Firefox.
+#: controllers/components/audit.php:108
+#, fuzzy
+msgid "audit_appversion_delete"
+msgstr "%1$s deleted version %2$s for %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a config field, like "awesomeness".
+#. %3$s is a config value, like "off".
+#. %4$s is a config value, like "on".
+#: controllers/components/audit.php:210
+#, fuzzy
+msgid "audit_config"
+msgstr "%1$s changed config '%2$s' from '%3$s' to '%4$s'"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:258
+#, fuzzy
+msgid "audit_editor_default"
+msgstr "%1$s committed unknown editor action %2$s to ID %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#: controllers/components/audit.php:236
+#, fuzzy
+msgid "audit_editor_feature_remove"
+msgstr "%1$s removed addon %2$s from feature list"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#: controllers/components/audit.php:231
+#, fuzzy
+msgid "audit_feature_add"
+msgstr "%1$s added addon %2$s to feature list"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:149
+#, fuzzy
+msgid "audit_feature_edit"
+msgstr "%1$s changed a feature for %2$s locale"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#: controllers/components/audit.php:241
+#, fuzzy
+msgid "audit_feature_locale_change"
+msgstr "%1$s changed locales for addon %2$s on feature list"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:83
+#, fuzzy
+msgid "audit_file_recalchash"
+msgstr "%1$s recalculated the hash for file %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>user name</a>
+#. %3$s is <a>group name</a>
+#: controllers/components/audit.php:182
+#, fuzzy
+msgid "audit_group_addmember"
+msgstr "%1$s added %2$s to group %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:313
+#, fuzzy
+msgid "audit_group_associated"
+msgstr "%1$s associated themselves with %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:162
+#, fuzzy
+msgid "audit_group_create"
+msgstr "%1s created group %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:170
+#, fuzzy
+msgid "audit_group_delete"
+msgstr "%1$s deleted group %2$s (ID %3$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:165
+#, fuzzy
+msgid "audit_group_edit"
+msgstr "%1$s edited group %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>user name</a>
+#. %3$s is <a>group name</a>
+#: controllers/components/audit.php:188
+#, fuzzy
+msgid "audit_group_removemember"
+msgstr "%1$s removed %2$s from group %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:280
+#, fuzzy
+msgid "audit_l10n_default"
+msgstr "%1$s committed unknown action %2$s for %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:295
+#, fuzzy
+msgid "audit_modify_locked_group"
+msgstr "%1$s attempted to modify locked group %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:299
+#, fuzzy
+msgid "audit_modify_other_locale"
+msgstr "%1$s attempted to modify translations in %2$s without permission"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a platform, like <a>Windows</a>
+#: controllers/components/audit.php:135
+#, fuzzy
+msgid "audit_platform_create"
+msgstr "%1$s created platform %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a platform, like <a>Windows</a>
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:143
+#, fuzzy
+msgid "audit_platform_delete"
+msgstr "%1$s deleted platform %2$s (ID %3$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a platform, like <a>Windows</a>
+#: controllers/components/audit.php:138
+#, fuzzy
+msgid "audit_platform_edit"
+msgstr "%1$s edited platform %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a part of the admin, like 'Site Config'
+#: controllers/components/audit.php:288
+#, fuzzy
+msgid "audit_reauthentication_failure"
+msgstr "%1$s failed to re-authenticate to access %2$s."
+
+#. %1$s is <a>user name</a>
+#. %2$s is the name of a canned response, like 'Ready for the public'
+#: controllers/components/audit.php:198
+#, fuzzy
+msgid "audit_response_create"
+msgstr "%1$s created response %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is the name of a canned response, like 'Ready for the public'
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:206
+#, fuzzy
+msgid "audit_response_delete"
+msgstr "%1$s deleted response %2$s (ID %3$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is the name of a canned response, like 'Ready for the public'
+#: controllers/components/audit.php:201
+#, fuzzy
+msgid "audit_response_edit"
+msgstr "%1$s edited response %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:245
+#, fuzzy
+msgid "audit_review_approve"
+msgstr "%1$s approved review %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:250 controllers/components/audit.php:253
+#, fuzzy
+msgid "audit_review_delete"
+msgstr "%1$s deleted review %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:303
+#, fuzzy
+msgid "audit_security_default"
+msgstr "%1$s committed unknown security action %2$s to ID %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a category name, like <a>Search Tools</a>
+#: controllers/components/audit.php:118
+#, fuzzy
+msgid "audit_tag_create"
+msgstr "%1$s created tag %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a category name, like <a>Search Tools</a>
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:126
+#, fuzzy
+msgid "audit_tag_delete"
+msgstr "%1$s deleted category %2$s (ID %3$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a category name, like <a>Search Tools</a>
+#: controllers/components/audit.php:121
+#, fuzzy
+msgid "audit_tag_edit"
+msgstr "%1$s edited category %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:266
+#, fuzzy
+msgid "audit_update_applications"
+msgstr "%1$s updated application translations for %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:277
+#, fuzzy
+msgid "audit_update_blog"
+msgstr "%1$s updated blog post translations for %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:274
+#, fuzzy
+msgid "audit_update_platforms"
+msgstr "%1$s updated platform translations for %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:270
+#, fuzzy
+msgid "audit_update_tags"
+msgstr "%1$s updated category translations for %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>user name</a>
+#: controllers/components/audit.php:217
+#, fuzzy
+msgid "audit_user_edit"
+msgstr "%1$s edited %2$s's user information"
+
+#: controllers/addons_controller.php:1012
+#, fuzzy
+msgid "browse_addons_name"
+msgstr "Add-ons by Name"
+
+#: controllers/addons_controller.php:1010
+#, fuzzy
+msgid "browse_addons_newest"
+msgstr "Newest Add-ons"
+
+#: controllers/addons_controller.php:1008
+#, fuzzy
+msgid "browse_addons_popular"
+msgstr "Popular Add-ons"
+
+#: controllers/addons_controller.php:1011
+#, fuzzy
+msgid "browse_addons_rated"
+msgstr "Add-ons by Rating"
+
+#: controllers/addons_controller.php:1009
+#, fuzzy
+msgid "browse_addons_updated"
+msgstr "Recently Updated Add-ons"
+
+#: views/elements/categories.thtml:73 views/elements/categories.thtml:82
+#, fuzzy
+msgid "categories_current_title"
+msgstr "Current Category"
+
+#: views/elements/categories.thtml:50
+#: views/elements/amo2009/categories.thtml:43
+#: views/elements/amo2009/categories.thtml:45
+#, fuzzy
+msgid "categories_header"
+msgstr "Categories"
+
+#: views/elements/categories.thtml:50
+#: views/elements/amo2009/categories.thtml:41
+#, fuzzy
+msgid "categories_header_title"
+msgstr "Choose a category"
+
+#. %1$s is the category name
+#: views/addons/searchengines.thtml:129
+#, fuzzy, php-format
+msgid "category_extra_see_all"
+msgstr "See All %1$s"
+
+#. %1$s is a number.
+#: models/collection.php:130
+#, fuzzy
+msgid "collection_description_limit"
+msgstr "The description should be less than %1$s characters."
+
+#. %1$s is the name of the collection
+#: controllers/collections_controller.php:392
+#, fuzzy
+msgid "collection_detail_rss_title"
+msgstr "%s Collection"
+
+#: controllers/collections_controller.php:1065
+#, fuzzy
+msgid "collection_error_deleting_addon"
+msgstr "Error deleting add-on!"
+
+#: controllers/collections_controller.php:1051
+#, fuzzy
+msgid "collection_error_saving_addon"
+msgstr "Error saving add-on!"
+
+#: controllers/collections_controller.php:1080
+#, fuzzy
+msgid "collection_error_saving_comment"
+msgstr "Error saving comment!"
+
+#. %1$s is a number.
+#: models/collection.php:122
+#, fuzzy
+msgid "collection_name_limit"
+msgstr "The name should be less than %1$s characters."
+
+#: controllers/collections_controller.php:352
+#: controllers/collections_controller.php:487
+#, fuzzy
+msgid "collection_not_found"
+msgstr "Collection not found!"
+
+#. %1$s is the text on the "create collection" button
+#: views/collections/add.thtml:91
+#, fuzzy
+msgid "collections_add_formfield_addons_description"
+msgstr ""
+"If you already know which add-ons you want to add to your collection, just "
+"start typing their names below. If you'd rather wait and do this later, just "
+"click %1$s now."
+
+#: views/collections/add.thtml:90
+#, fuzzy
+msgid "collections_add_formfield_firstaddons"
+msgstr "Choose your first add-ons"
+
+#: views/collections/add.thtml:48
+#, fuzzy
+msgid "collections_add_header"
+msgstr "Create a Collection"
+
+#: views/collections/add.thtml:97
+#, fuzzy
+msgid "collections_add_header_selectedaddons"
+msgstr "Selected Add-ons"
+
+#: views/collections/add.thtml:50
+#, fuzzy
+msgid "collections_add_intro"
+msgstr ""
+"It's easy to create your own collection of add-ons by filling in a few "
+"fields below."
+
+#: views/collections/add.thtml:92 views/collections/add.thtml:103
+#, fuzzy
+msgid "collections_add_submit"
+msgstr "Create Collection"
+
+#: views/pages/collector_faq.thtml:50 views/pages/collector_firstrun.thtml:43
+#: views/pages/collector.thtml:47 views/pages/collector_features.thtml:55
+#: controllers/search_controller.php:302
+#: controllers/collections_controller.php:206
+#: controllers/collections_controller.php:405
+#: controllers/collections_controller.php:467
+#: controllers/collections_controller.php:539
+#, fuzzy
+msgid "collections_breadcrumb"
+msgstr "Collections"
+
+#: views/collections/detail.thtml:185
+#, fuzzy
+msgid "collections_detail_a_learn"
+msgstr "Learn More"
+
+#: views/elements/amo2009/collection_add_form.thtml:53
+#: views/elements/amo2009/collections_js_init.thtml:68
+#: views/pages/collector_firstrun.thtml:64
+#, fuzzy
+msgid "collections_detail_button_add"
+msgstr "Add to Favorites"
+
+#: views/elements/amo2009/collection_add_form.thtml:50
+#: views/elements/amo2009/collections_js_init.thtml:71
+#, fuzzy
+msgid "collections_detail_button_remove"
+msgstr "Remove from Favorites"
+
+#. %1$s is a URL.
+#. %2$s is a full <a href>.
+#: views/collections/detail.thtml:62
+#, fuzzy
+msgid "collections_detail_created_desc"
+msgstr ""
+"<p>You can view your new collection below. If you'd like to set a collection "
+"nickname, upload an icon, or change additional settings, please visit the <a "
+"href='%1$s'>Manage Collections</a> page.</p><p>Your collection can be "
+"accessed at this location: %2$s</p>"
+
+#: views/collections/detail.thtml:61
+#, fuzzy
+msgid "collections_detail_created_msg"
+msgstr "Your collection is now ready!"
+
+#: views/collections/detail.thtml:109
+#, fuzzy
+msgid "collections_detail_header_about"
+msgstr "About This Collection"
+
+#. %1$s is a number.
+#: views/collections/detail.thtml:126
+#, fuzzy
+msgid "collections_detail_header_count"
+msgid_plural "collections_detail_header_count"
+msgstr[0] "%1$s Add-on in this Collection"
+msgstr[1] "%1$s Add-ons in this Collection"
+
+#: views/collections/detail.thtml:113
+#, fuzzy
+msgid "collections_detail_info_created"
+msgstr "<strong>Created by:</strong> %1$s"
+
+#: views/collections/detail.thtml:117
+#, fuzzy
+msgid "collections_detail_info_updated"
+msgstr "<strong>Updated:</strong>"
+
+#: views/elements/amo2009/collections_js_init.thtml:62
+#, fuzzy
+msgid "collections_detail_js_adding"
+msgstr "Adding to Favorites&hellip;"
+
+#: views/elements/amo2009/collections_js_init.thtml:65
+#, fuzzy
+msgid "collections_detail_js_removing"
+msgstr "Removing Favorite&hellip;"
+
+#. %1$s is a URL
+#: views/collections/detail.thtml:90
+#, fuzzy
+msgid "collections_detail_login"
+msgstr "<a href=\"%1$s\">Log in</a> to add this collection to your favorites."
+
+#: views/collections/detail.thtml:104
+#, fuzzy
+msgid "collections_detail_manage"
+msgstr "Manage Collection"
+
+#: controllers/collections_controller.php:298
+#, fuzzy
+msgid "collections_detail_sort_date"
+msgstr "Date Added"
+
+#: controllers/collections_controller.php:299
+#, fuzzy
+msgid "collections_detail_sort_name"
+msgstr "Name"
+
+#: controllers/collections_controller.php:300
+#, fuzzy
+msgid "collections_detail_sort_popularity"
+msgstr "Popularity"
+
+#. %1$s is a number.
+#: views/collections/detail.thtml:166
+#, fuzzy
+msgid "collections_detail_weekly_downloads"
+msgid_plural "collections_detail_weekly_downloads"
+msgstr[0] "%1$s download this week"
+msgstr[1] "%1$s downloads this week"
+
+#: views/collections/edit.thtml:255
+#, fuzzy
+msgid "collections_edit_addons_delete_noscript"
+msgstr "Selected add-ons will be removed upon Save"
+
+#: views/collections/edit.thtml:247
+#, fuzzy
+msgid "collections_edit_addons_description"
+msgstr ""
+"To publish new add-ons to this collection, start typing their names below."
+
+#: views/collections/edit.thtml:248
+#, fuzzy
+msgid "collections_edit_addons_description_noscript"
+msgstr ""
+"To publish new add-ons to this collection, enter a comma-separated list of "
+"Add-on IDs below."
+
+#: views/collections/edit.thtml:247 views/collections/edit.thtml:248
+#, fuzzy
+msgid "collections_edit_addons_description_publish_detailspage"
+msgstr "You can also publish an add-on from its normal listing page."
+
+#. %1$s is the date the add-on was added to the collection
+#. %1$s is the name of the user who added the add-on to the collection
+#: views/collections/edit.thtml:260
+#, fuzzy
+msgid "collections_edit_addons_listitem_added"
+msgstr "Added %1$s by %2$s"
+
+#: views/collections/edit.thtml:263
+#, fuzzy
+msgid "collections_edit_addons_listitem_comment_add"
+msgstr "Add publisher comment"
+
+#: views/collections/edit.thtml:266
+#, fuzzy
+msgid "collections_edit_addons_listitem_comment_delete"
+msgstr "Delete publisher comment"
+
+#: views/collections/edit.thtml:265
+#, fuzzy
+msgid "collections_edit_addons_listitem_comment_edit"
+msgstr "Edit publisher comment"
+
+#: views/collections/edit.thtml:271
+#, fuzzy
+msgid "collections_edit_addons_listitem_comment_note"
+msgstr ""
+"Note: Comment will appear as though written by original publisher on the "
+"original publication date"
+
+#: views/collections/edit.thtml:270
+#, fuzzy
+msgid "collections_edit_addons_listitem_comment_submit"
+msgstr "Save Comment"
+
+#: views/collections/edit.thtml:261
+#, fuzzy
+msgid "collections_edit_addons_listitem_remove"
+msgstr "Remove"
+
+#: views/collections/edit.thtml:250
+#, fuzzy
+msgid "collections_edit_addons_submit"
+msgstr "Add to Collection"
+
+#: views/collections/edit.thtml:153
+#, fuzzy
+msgid "collections_edit_check_nickname"
+msgstr "Check Availability"
+
+#: views/collections/edit.thtml:299
+#, fuzzy
+msgid "collections_edit_confirm_deletecollection"
+msgstr "Yes, I would like to delete this collection."
+
+#. %1$s is the label of the edit form's submit button
+#: views/collections/edit.thtml:300
+#, fuzzy
+msgid "collections_edit_confirm_deletecollection_description"
+msgstr "Check the box, then click on \"%1$s\" to delete this collection."
+
+#. %1$s is the "delete" submit button text
+#. %2$s is the title of the "advanced" tab
+#: views/collections/edit.thtml:95
+#, fuzzy
+msgid "collections_edit_delete_upon_submit"
+msgstr ""
+"Upon clicking \"%1$s\" below, your collection will be deleted. If you do not "
+"want to delete your collection, uncheck the confirmation box in the \"%2$s\" "
+"tab and continue editing your collection. If you leave this page without "
+"saving, your collection will also not be deleted."
+
+#: views/collections/edit.thtml:94
+#, fuzzy
+msgid "collections_edit_delete_warning"
+msgstr "Your collection is about to be deleted!"
+
+#: views/collections/add.thtml:76 views/collections/edit.thtml:144
+#, fuzzy
+msgid "collections_edit_form_error_description"
+msgstr "You must provide a description of your collection."
+
+#: views/collections/edit.thtml:181
+#, fuzzy
+msgid "collections_edit_form_error_icon"
+msgstr "There was an error uploading your icon."
+
+#: views/collections/add.thtml:69 views/collections/edit.thtml:130
+#, fuzzy
+msgid "collections_edit_form_error_name"
+msgstr "You must give your collection a name."
+
+#: views/collections/edit.thtml:158
+#, fuzzy
+msgid "collections_edit_form_error_nickname"
+msgstr "If you choose a nickname, it must be unique."
+
+#: views/collections/add.thtml:93 views/collections/edit.thtml:249
+#, fuzzy
+msgid "collections_edit_formfield_addons"
+msgstr "Add-on name:"
+
+#: views/collections/edit.thtml:281
+#, fuzzy
+msgid "collections_edit_formfield_application"
+msgstr "Associated Application"
+
+#: views/collections/edit.thtml:282
+#, fuzzy
+msgid "collections_edit_formfield_application_description"
+msgstr "Select the application that your collection supports."
+
+#: views/collections/edit.thtml:288
+#, fuzzy
+msgid "collections_edit_formfield_collectiontype"
+msgstr "Collection Type"
+
+#: views/collections/edit.thtml:295
+#, fuzzy
+msgid "collections_edit_formfield_deletecollection"
+msgstr "Delete Collection"
+
+#: views/collections/edit.thtml:296
+#, fuzzy
+msgid "collections_edit_formfield_deletecollection_description"
+msgstr "Deleting your collection will permanently erase it."
+
+#: views/collections/add.thtml:73 views/collections/edit.thtml:140
+#, fuzzy
+msgid "collections_edit_formfield_description"
+msgstr "Collection Description"
+
+#: views/collections/add.thtml:74 views/collections/edit.thtml:141
+#, fuzzy
+msgid "collections_edit_formfield_description_description"
+msgstr "Briefly describe your collection and the kind of add-ons in it"
+
+#: views/collections/edit.thtml:162
+#, fuzzy
+msgid "collections_edit_formfield_icon"
+msgstr "Icon"
+
+#: views/collections/edit.thtml:163
+#, fuzzy
+msgid "collections_edit_formfield_icon_description"
+msgstr ""
+"You can upload a JPG, GIF or PNG icon that will be resized to 32x32 pixels."
+
+#: views/collections/add.thtml:80 views/collections/edit.thtml:189
+#, fuzzy
+msgid "collections_edit_formfield_listed"
+msgstr "Who can view your collection?"
+
+#: views/collections/add.thtml:81 views/collections/edit.thtml:190
+#, fuzzy
+msgid "collections_edit_formfield_listed_description"
+msgstr ""
+"By default, collections appear in the public Collection Directory and are "
+"discoverable by anyone. If you want to restrict your collection to be "
+"viewable only by people who are given a special link, choose that option "
+"below."
+
+#: views/collections/add.thtml:84 views/collections/edit.thtml:193
+#, fuzzy
+msgid "collections_edit_formfield_listed_false"
+msgstr "Only people I invite can view my collection"
+
+#: views/collections/add.thtml:83 views/collections/edit.thtml:192
+#, fuzzy
+msgid "collections_edit_formfield_listed_true"
+msgstr "Everyone can view my collection in the directory"
+
+#: views/collections/edit.thtml:223
+#, fuzzy
+msgid "collections_edit_formfield_managers"
+msgstr "Who can manage my collection?"
+
+#: views/collections/edit.thtml:224
+#, fuzzy
+msgid "collections_edit_formfield_managers_description"
+msgstr ""
+"These users can publish add-ons to your collection, manage all add-ons and "
+"settings, and grant other users permission."
+
+#: views/collections/add.thtml:66 views/collections/edit.thtml:126
+#, fuzzy
+msgid "collections_edit_formfield_name"
+msgstr "Collection Name"
+
+#: views/collections/add.thtml:67 views/collections/edit.thtml:127
+#, fuzzy
+msgid "collections_edit_formfield_name_description"
+msgstr ""
+"Give your collection a descriptive name, such as \"Dave's Favorite Travel "
+"Add-ons\""
+
+#: views/collections/edit.thtml:148
+#, fuzzy
+msgid "collections_edit_formfield_nickname"
+msgstr "Collection Nickname"
+
+#: views/collections/edit.thtml:149
+#, fuzzy
+msgid "collections_edit_formfield_nickname_description"
+msgstr "Optionally, give your collection a unique nickname for quick access:"
+
+#: views/collections/edit.thtml:201
+#, fuzzy
+msgid "collections_edit_formfield_publishers"
+msgstr "Who can publish add-ons to your collection?"
+
+#: views/collections/edit.thtml:202
+#, fuzzy
+msgid "collections_edit_formfield_publishers_description"
+msgstr ""
+"These users can publish add-ons to your collection and remove add-ons that "
+"they publish."
+
+#: views/collections/edit.thtml:210 views/collections/edit.thtml:232
+#, fuzzy
+msgid "collections_edit_formfield_users_add"
+msgstr "Enter the e-mail address of a Firefox Add-ons account:"
+
+#: views/collections/edit.thtml:216 views/collections/edit.thtml:238
+#, fuzzy
+msgid "collections_edit_formfield_users_delete_noscript"
+msgstr "Selected accounts will be removed upon Save"
+
+#: views/collections/edit.thtml:215 views/collections/edit.thtml:237
+#, fuzzy
+msgid "collections_edit_formfield_users_new_noscript"
+msgstr ""
+"Enter a comma-separated list of e-mail addresses of Firefox Add-ons accounts"
+
+#: views/collections/edit.thtml:204 views/collections/edit.thtml:226
+#, fuzzy
+msgid "collections_edit_formfield_users_onlyme"
+msgstr "Only me"
+
+#: views/collections/edit.thtml:205 views/collections/edit.thtml:227
+#, fuzzy
+msgid "collections_edit_formfield_users_otherusers"
+msgstr "Myself and these users:"
+
+#: views/collections/edit.thtml:211 views/collections/edit.thtml:233
+#, fuzzy
+msgid "collections_edit_formfield_users_submit"
+msgstr "Add"
+
+#. %1$s is the name of the collection
+#: views/collections/edit.thtml:68
+#, fuzzy
+msgid "collections_edit_header"
+msgstr "Manage %1$s"
+
+#: views/collections/edit.thtml:246
+#, fuzzy
+msgid "collections_edit_header_addons"
+msgstr "Manage Collection Contents"
+
+#: views/collections/edit.thtml:253 views/collections/edit.thtml:258
+#, fuzzy
+msgid "collections_edit_header_addons_current"
+msgstr "Current Add-ons:"
+
+#: views/collections/edit.thtml:279
+#, fuzzy
+msgid "collections_edit_header_advanced"
+msgstr "Advanced Settings"
+
+#: views/collections/edit.thtml:186
+#, fuzzy
+msgid "collections_edit_header_permissions"
+msgstr "Manage Collection Permissions"
+
+#: views/collections/edit.thtml:170
+#, fuzzy
+msgid "collections_edit_icon_cancel"
+msgstr "Cancel"
+
+#: views/collections/edit.thtml:174 views/collections/edit.thtml:179
+#, fuzzy
+msgid "collections_edit_icon_delete"
+msgstr "Delete Icon"
+
+#: views/collections/edit.thtml:178
+#, fuzzy
+msgid "collections_edit_icon_replace"
+msgstr "Replace Icon"
+
+#. %1$s is the label of the edit form's submit button
+#: views/collections/edit.thtml:169
+#, fuzzy
+msgid "collections_edit_icon_toberemoved"
+msgstr "Icon will be removed when \"%1$s\" is clicked below"
+
+#: views/collections/edit.thtml:155
+#, fuzzy
+msgid "collections_edit_nickname_available"
+msgstr "Nickname Available"
+
+#: controllers/collections_controller.php:943
+#, fuzzy
+msgid "collections_edit_nickname_error"
+msgstr ""
+"Your nickname contained invalid characters and was corrected. Please try "
+"again."
+
+#: views/collections/edit.thtml:156
+#, fuzzy
+msgid "collections_edit_nickname_taken"
+msgstr "Nickname Taken"
+
+#. This string is followed by a URL pointing to the collection's view page
+#: views/collections/edit.thtml:75
+#, fuzzy
+msgid "collections_edit_saved_nextstep"
+msgstr "Your collection can be accessed at this location:"
+
+#: views/collections/edit.thtml:74
+#, fuzzy
+msgid "collections_edit_saved_success"
+msgstr "Your collection was successfully saved!"
+
+#: views/collections/edit.thtml:169 views/collections/edit.thtml:300
+#: views/collections/edit.thtml:308 views/pages/js_constants.js.thtml:99
+#, fuzzy
+msgid "collections_edit_submit"
+msgstr "Update Collection"
+
+#: views/collections/edit.thtml:96 views/collections/edit.thtml:297
+#: views/pages/js_constants.js.thtml:100
+#, fuzzy
+msgid "collections_edit_submit_deletecollection"
+msgstr "Delete Collection"
+
+#: views/collections/edit.thtml:111
+#, fuzzy
+msgid "collections_edit_tabheader_addons"
+msgstr "Add-ons"
+
+#: views/collections/edit.thtml:97 views/collections/edit.thtml:113
+#, fuzzy
+msgid "collections_edit_tabheader_advanced"
+msgstr "Advanced"
+
+#: views/collections/edit.thtml:108
+#, fuzzy
+msgid "collections_edit_tabheader_details"
+msgstr "Name &amp; Details"
+
+#: views/collections/edit.thtml:109
+#, fuzzy
+msgid "collections_edit_tabheader_permissions"
+msgstr "Permissions"
+
+#: models/collection_promo.php:53
+#, fuzzy
+msgid "collections_family_tagline"
+msgstr "Add-ons can keep an eye on your kids and your calendar."
+
+#: models/collection_promo.php:53
+#, fuzzy
+msgid "collections_family_title"
+msgstr "Family Organizer"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:70
+#, fuzzy
+msgid "collections_index_a_check_out"
+msgstr "Check out Add-on Collector"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:52
+#, fuzzy
+msgid "collections_index_a_create"
+msgstr "Create a Collection"
+
+#: views/collections/detail.thtml:139 views/collections/listing.thtml:85
+#: views/search/collections.thtml:84
+#, fuzzy
+msgid "collections_index_button_go"
+msgstr "Go"
+
+#. %1$s is a URL.
+#: controllers/collections_controller.php:182
+#, fuzzy
+msgid "collections_index_filler_favorites"
+msgstr ""
+"<p><strong>You don't have any favorite collections yet.</strong></p> "
+"<p>Collections you mark as favorites can be quickly accessed from this page, "
+"and will appear in the <a href='%1$s'>Add-on Collector</a> if you've "
+"installed it.</p>"
+
+#. %1$s is a URL.
+#: controllers/collections_controller.php:167
+#, fuzzy
+msgid "collections_index_filler_mine"
+msgstr ""
+"<p>You haven't created any collections yet. Collections are easy to create "
+"and fill with your favorite add-ons. <a href='%1$s'>Try it out</a>!</p>"
+
+#: views/collections/listing.thtml:51
+#, fuzzy
+msgid "collections_index_header_collections"
+msgstr "Collections"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:60
+#, fuzzy
+msgid "collections_index_header_collector"
+msgstr "Add-on Collector"
+
+#. %1$s is a comma-separated list of author names
+#: views/elements/amo2009/collection_listing_item.thtml:84
+#: views/collections/detail.thtml:151
+#, fuzzy
+msgid "collections_index_header_created"
+msgstr "created by %1$s"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:47
+#, fuzzy
+msgid "collections_index_header_what"
+msgstr "What are Collections?"
+
+#: views/collections/detail.thtml:132 views/collections/listing.thtml:78
+#: views/search/collections.thtml:66
+#, fuzzy
+msgid "collections_index_label_sortby"
+msgstr "Sort by"
+
+#: controllers/collections_controller.php:130
+#, fuzzy
+msgid "collections_index_li_editors"
+msgstr "Editor's Picks"
+
+#: views/collections/subscribe.thtml:64
+#: controllers/collections_controller.php:140
+#, fuzzy
+msgid "collections_index_li_favorites"
+msgstr "My Favorites"
+
+#: controllers/collections_controller.php:138
+#, fuzzy
+msgid "collections_index_li_mine"
+msgstr "My Collections"
+
+#: controllers/collections_controller.php:132
+#, fuzzy
+msgid "collections_index_li_popular"
+msgstr "Popular"
+
+#: views/search/collections.thtml:74 controllers/collections_controller.php:81
+#, fuzzy
+msgid "collections_index_option_all"
+msgstr "Most popular all time"
+
+#: views/search/collections.thtml:72 controllers/collections_controller.php:78
+#, fuzzy
+msgid "collections_index_option_month"
+msgstr "Most popular this month"
+
+#: views/search/collections.thtml:76 controllers/collections_controller.php:84
+#, fuzzy
+msgid "collections_index_option_newest"
+msgstr "Newest"
+
+#: views/search/collections.thtml:70 controllers/collections_controller.php:75
+#, fuzzy
+msgid "collections_index_option_week"
+msgstr "Most popular this week"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:67
+#, fuzzy
+msgid "collections_index_p_collector"
+msgstr ""
+"There's a new way to manage and find favorite add-ons. Comment, share and "
+"sync collections, all from your browser"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:48
+#, fuzzy
+msgid "collections_index_p_what_are"
+msgstr "Collections are groups of related add-ons assembled for easy sharing."
+
+#. %s is a date in the _('date') format
+#: views/elements/collections_interactive_addon.thtml:85
+#, fuzzy, php-format
+msgid "collections_interactive_addon_added"
+msgstr "Added %s"
+
+#: models/collection_promo.php:55
+#, fuzzy
+msgid "collections_reference_tagline"
+msgstr "Add-ons can do better research online."
+
+#: models/collection_promo.php:55
+#, fuzzy
+msgid "collections_reference_title"
+msgstr "Reference Desk"
+
+#: models/collection_promo.php:52
+#, fuzzy
+msgid "collections_social_tagline"
+msgstr "Add-ons can manage your social network."
+
+#: models/collection_promo.php:52
+#, fuzzy
+msgid "collections_social_title"
+msgstr "Social Circuit"
+
+#: views/collections/subscribe.thtml:91
+#, fuzzy
+msgid "collections_subscribe_button_close"
+msgstr "Close"
+
+#: views/collections/subscribe.thtml:70
+#, fuzzy
+msgid "collections_subscribe_error"
+msgstr ""
+"An error occurred trying to add a favorite collection. Is this collection "
+"already a favorite?"
+
+#: views/collections/subscribe.thtml:96
+#, fuzzy
+msgid "collections_subscribe_label_bothersome"
+msgstr "Don't show me this message again."
+
+#. %1$s is the collection name
+#: views/collections/subscribe.thtml:60
+#, fuzzy
+msgid "collections_subscribe_success"
+msgstr "%1$s has been added to your favorite collections."
+
+#. %1$s is the link to the "My Favorites" tab on the main collections page
+#. %2$s is the localized title of the "My Favorites" tab
+#. %3$s is the link URL to the collector add-on
+#: views/collections/subscribe.thtml:62
+#, fuzzy
+msgid "collections_subscribe_success_desc"
+msgstr ""
+"You can now quickly find this collection from the <a href=\"%1$s\">%2$s</a> "
+"tab in the directory. For an even easier way to keep track of your favorite "
+"collections, try out our <a href=\"%3$s\">Add-on Collector</a> extension for "
+"Firefox."
+
+#: views/collections/listing.thtml:55
+#, fuzzy
+msgid "collections_success_delete"
+msgstr "The collection has been deleted."
+
+#: models/collection_promo.php:54
+#, fuzzy
+msgid "collections_travel_tagline"
+msgstr "Add-ons can turn you into a travel agent."
+
+#: models/collection_promo.php:54
+#, fuzzy
+msgid "collections_travel_title"
+msgstr "The Traveler's Pack"
+
+#. A collection of add-ons that is automatically built for a user. They are "automatically published" to this collection.
+#: controllers/collections_controller.php:581
+#, fuzzy
+msgid "collections_type_autopublisher"
+msgstr "Auto-publisher"
+
+#. A collection that has been chosen by an Editor as notable or exceptional
+#: controllers/collections_controller.php:582
+#, fuzzy
+msgid "collections_type_editorspick"
+msgstr "Editor's Pick"
+
+#: controllers/collections_controller.php:580
+#, fuzzy
+msgid "collections_type_normal"
+msgstr "Normal"
+
+#: views/collections/subscribe.thtml:84
+#, fuzzy
+msgid "collections_unsubscribe_error"
+msgstr ""
+"An error occurred trying to remove a favorite collection. Was this "
+"collection not a favorite?"
+
+#. %1$s is the collection name
+#: views/collections/subscribe.thtml:78
+#, fuzzy
+msgid "collections_unsubscribe_success"
+msgstr "%1$s has been removed from your favorite collections."
+
+#: models/collection_promo.php:56
+#, fuzzy
+msgid "collections_webdev_tagline"
+msgstr "Add-ons make it easier to build the perfect website."
+
+#: models/collection_promo.php:56
+#, fuzzy
+msgid "collections_webdev_title"
+msgstr "Web Developer's Toolbox"
+
+#: views/elements/amo2009/collections_sidebar_whatare.thtml:40
+#, fuzzy
+msgid "collections_whatare_header"
+msgstr "What are Collections?"
+
+#: views/elements/amo2009/collections_sidebar_whatare.thtml:45
+#, fuzzy
+msgid "collections_whatare_learnmore"
+msgstr "Read the FAQ"
+
+#: views/elements/amo2009/collections_sidebar_whatare.thtml:44
+#, fuzzy
+msgid "collections_whatare_text"
+msgstr ""
+"There’s a new way to manage and find favorite add-ons. Comment, share and "
+"sync collections, all from your browser."
+
+#: views/pages/collector_faq.thtml:61 views/pages/collector_features.thtml:67
+#, fuzzy
+msgid "collector_features_a_home"
+msgstr "Add-on Collector Home"
+
+#: views/elements/amo2009/collector_sidebar_download.thtml:46
+#, fuzzy
+msgid "collector_features_heading_download"
+msgstr "Download the Add-on Collector:"
+
+#: views/elements/amo2009/collector_sidebar_download.thtml:43
+#: views/pages/collector_firstrun.thtml:116 views/pages/collector.thtml:69
+#, fuzzy
+msgid "collector_features_img_logo"
+msgstr "Add-on Collector Logo"
+
+#: views/compatibility/dashboard.thtml:49
+#: controllers/compatibility_controller.php:72
+#, fuzzy
+msgid "compatibility_dashboard_center_header"
+msgstr "Add-on Compatibility Center"
+
+#. %1$s is the name of an application and a version. Example: Firefox 3.0
+#. %2$s is the name of an application. Example: Firefox
+#: views/compatibility/dashboard.thtml:50
+#, fuzzy
+msgid "compatibility_dashboard_intro"
+msgstr ""
+"Be prepared for the release of %1$s with the tools and information available "
+"for the %2$s Add-ons community found below."
+
+#: views/compatibility/dashboard.thtml:103
+#, fuzzy
+msgid "compatibility_dashboard_loading"
+msgstr "Loading data..."
+
+#: views/compatibility/dashboard.thtml:45
+#, fuzzy
+msgid "compatibility_dashboard_main_link"
+msgstr "Back to Main"
+
+#: views/compatibility/dashboard.thtml:100 views/compatibility/report.thtml:43
+#, fuzzy
+msgid "compatibility_dashboard_report"
+msgstr "Add-on Compatibility Report"
+
+#: views/compatibility/dashboard.thtml:53
+#: views/compatibility/dashboard.thtml:110
+#: views/compatibility/developers.thtml:43
+#, fuzzy
+msgid "compatibility_developer_info"
+msgstr "Information for Add-on Developers"
+
+#: views/compatibility/developers.thtml:66
+#, fuzzy
+msgid "compatibility_developers_adjust_maxversion"
+msgstr "Adjust maxVersion without uploading"
+
+#: views/compatibility/dashboard.thtml:124
+#, fuzzy
+msgid "compatibility_developers_check_status"
+msgstr "Check Status of My Add-ons"
+
+#. %1$s is a URL
+#. %2$s is an application and version. Example: Firefox 3.0
+#: views/compatibility/dashboard.thtml:126
+#, fuzzy
+msgid "compatibility_developers_login_first"
+msgstr ""
+"If you have add-ons hosted on Mozilla Add-ons, <a href=\"%1$s\">please "
+"login</a> to analyze the status of your add-ons for %2$s."
+
+#: views/compatibility/dashboard.thtml:114
+#, fuzzy
+msgid "compatibility_developers_mdclogo_alt"
+msgstr "Mozilla Developer Center Logo"
+
+#: views/compatibility/developers.thtml:73
+#, fuzzy
+msgid "compatibility_developers_no_addons"
+msgstr "You do not have any add-ons hosted on Mozilla Add-ons."
+
+#: views/compatibility/dashboard.thtml:133
+#: views/compatibility/developers.thtml:55
+#, fuzzy
+msgid "compatibility_developers_results"
+msgstr "Add-on Status Check Results"
+
+#: views/compatibility/dashboard.thtml:137
+#, fuzzy
+msgid "compatibility_developers_retrieving"
+msgstr "Retrieving status of hosted add-ons..."
+
+#. %1$s is a number
+#. %2$s is an application name
+#. %3$s is a number.
+#. Full example: 50 Firefox users (10% of total)
+#: views/compatibility/developers.thtml:65
+#, fuzzy
+msgid "compatibility_developers_user_count"
+msgstr "%1$s %2$s users (%3$s&#37; of total)"
+
+#: views/compatibility/report.thtml:45
+#, fuzzy
+msgid "compatibility_report_detail_intro"
+msgstr ""
+"The add-ons below make up 95% of add-on usage known to Mozilla and are "
+"ordered by their usage size."
+
+#: views/compatibility/dashboard.thtml:94
+#, fuzzy
+msgid "compatibility_report_detailed_link"
+msgstr "View Detailed Report"
+
+#. %1$s and %2$s are numbers
+#. %3$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:65
+#, fuzzy
+msgid "compatibility_report_intro"
+msgstr ""
+"Of the %1$s add-ons that make up 95&#37; of add-on usage known to Mozilla, "
+"<b>%2$s&#37;</b> are currently considered compatible with the latest builds "
+"of %3$s."
+
+#: views/compatibility/dashboard.thtml:81
+#, fuzzy
+msgid "compatibility_report_legend_alpha"
+msgstr "Alpha Versions"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:81
+#, fuzzy
+msgid "compatibility_report_legend_alpha_description"
+msgstr "Add-ons compatible with an alpha version of %1$s"
+
+#: views/compatibility/dashboard.thtml:85
+#, fuzzy
+msgid "compatibility_report_legend_beta"
+msgstr "Beta Versions"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:85
+#, fuzzy
+msgid "compatibility_report_legend_beta_description"
+msgstr "Add-ons compatible with a beta version or release candidate of %1$s"
+
+#: views/compatibility/dashboard.thtml:89
+#, fuzzy
+msgid "compatibility_report_legend_latest"
+msgstr "Latest Version"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:89
+#, fuzzy
+msgid "compatibility_report_legend_latest_description"
+msgstr "Add-ons up-to-date with the latest builds of %1$s"
+
+#: views/compatibility/dashboard.thtml:77
+#, fuzzy
+msgid "compatibility_report_legend_other"
+msgstr "Other Versions"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:77
+#, fuzzy
+msgid "compatibility_report_legend_other_description"
+msgstr "Add-ons not compatible with any version of %1$s"
+
+#: views/compatibility/dashboard.thtml:62
+#, fuzzy
+msgid "compatibility_report_title"
+msgstr "Add-on Compatibility Report"
+
+#: views/compatibility/dashboard.thtml:54
+#: views/compatibility/dashboard.thtml:144 views/compatibility/users.thtml:42
+#, fuzzy
+msgid "compatibility_user_info"
+msgstr "Information for Add-on Users"
+
+#: views/compatibility/dashboard.thtml:52
+#, fuzzy
+msgid "compatibility_view_report"
+msgstr "View Compatibility Report"
+
+#. %s is a URL
+#: views/pages/credits.thtml:142
+#, fuzzy, php-format
+msgid "credits_contributing"
+msgstr "For information on contributing, please see our %s."
+
+#: views/pages/credits.thtml:142
+#, fuzzy
+msgid "credits_contributing_wikipage"
+msgstr "wiki page"
+
+#: views/pages/credits.thtml:99
+#, fuzzy
+msgid "credits_intro"
+msgstr ""
+"Mozilla would like to thank the following people for their contributions to "
+"the addons.mozilla.org project over the years:"
+
+#: views/pages/credits.thtml:103
+#, fuzzy
+msgid "credits_section_developers"
+msgstr "Developers"
+
+#: views/pages/credits.thtml:115
+#, fuzzy
+msgid "credits_section_editors"
+msgstr "Editors"
+
+#: views/pages/credits.thtml:109
+#, fuzzy
+msgid "credits_section_localizers"
+msgstr "Localizers"
+
+#: views/pages/credits.thtml:121
+#, fuzzy
+msgid "credits_section_other_contributors"
+msgstr "Other Contributors"
+
+#: views/pages/credits.thtml:127
+#, fuzzy
+msgid "credits_section_past_developers"
+msgstr "Past Developers"
+
+#: views/pages/credits.thtml:133
+#, fuzzy
+msgid "credits_section_software"
+msgstr "Software and Images"
+
+#: views/pages/credits.thtml:136
+#, fuzzy
+msgid "credits_software_famfamfam"
+msgstr ""
+"Some icons used are from the <a href=\"http://www.famfamfam.com/lab/icons/"
+"silk/\">famfamfam Silk Icon Set</a>, licensed under a <a href=\"http://"
+"creativecommons.org/licenses/by/2.5/\">Creative Commons Attribution 2.5 "
+"License</a>."
+
+#: views/pages/credits.thtml:137
+#, fuzzy
+msgid "credits_software_timeplot"
+msgstr ""
+"Some pages use elements of <a href=\"http://www.simile-widgets.org/timeplot/"
+"\">Timeplot</a>, licensed under a <a href=\"http://simile.mit.edu/license."
+"html\">BSD License</a>."
+
+#. date format string as used in PHP's strftime():
+#. http://php.net/strftime
+#: views/elements/collections_interactive_addon.thtml:85
+#: views/elements/amo2009/addon_version_detail.thtml:53
+#: views/elements/amo2009/homepage_addon.thtml:115
+#: views/elements/addon_version_detail.thtml:54
+#: views/elements/addon_listitem.thtml:124 views/elements/feature.thtml:106
+#: views/collections/detail.thtml:118 views/collections/edit.thtml:325
+#: views/users/info.thtml:76 views/editors/reviews_queue.thtml:57
+#: views/editors/reviews_queue.thtml:68 views/developers/dashboard.thtml:65
+#: views/developers/versions_edit.thtml:208 views/developers/versions.thtml:67
+#: views/search/rss/index.thtml:5 views/addons/rss/versions.thtml:42
+#: views/addons/display.thtml:104 views/addons/display.thtml:356
+#: views/addons/browse_thumbs.thtml:75 views/reviews/add.thtml:63
+#: views/reviews/display.thtml:74 views/reviews/display.thtml:160
+#: views/reviews/delete.thtml:54 controllers/statistics_controller.php:244
+#: controllers/collections_controller.php:1047
+#, fuzzy
+msgid "date"
+msgstr "%B %e, %Y"
+
+#. date and time format string (strftime)
+#. http://php.net/strftime
+#: views/elements/addon_version_detail.thtml:53
+#: views/developers/discuss.thtml:52 views/developers/discuss.thtml:62
+#: views/admin/addons_status.thtml:57
+#, fuzzy
+msgid "datetime"
+msgstr "%B %e, %Y, %I:%M %p"
+
+#: views/elements/developers/actionbar.thtml:47
+#, fuzzy
+msgid "devcp_actionbar_link_details"
+msgstr "Detailed Info"
+
+#: views/elements/developers/actionbar.thtml:42
+#: views/elements/developers/actionbar.thtml:50
+#: views/developers/dashboard.thtml:64
+#, fuzzy
+msgid "devcp_actionbar_link_edit"
+msgstr "Edit Add-on"
+
+#: views/elements/developers/actionbar.thtml:51
+#, fuzzy
+msgid "devcp_actionbar_link_newversion"
+msgstr "Upload New Version"
+
+#: views/elements/developers/actionbar.thtml:44
+#: views/elements/developers/actionbar.thtml:49
+#: views/developers/dashboard.thtml:73
+#, fuzzy
+msgid "devcp_actionbar_link_stats"
+msgstr "Statistics Dashboard"
+
+#. %1$s is a filename, e.g. "foo.txt"
+#. %2$s is the extension, e.g. ".txt"
+#. %3$s is a list of valid extensions, like ".png, .jpg, .gif"
+#: controllers/developers_controller.php:1361
+#, fuzzy
+msgid "devcp_add_previews_extension_error"
+msgstr "File %1$s has an invalid extension (%2$s). Allowed extensions: %3$s"
+
+#. %s is the filename.
+#: controllers/developers_controller.php:1394
+#, fuzzy
+msgid "devcp_add_previews_save_error"
+msgstr "File %s could not be saved to the database. Please try again."
+
+#. %1$s is the preview ID number, %2$s is the filename.
+#: controllers/developers_controller.php:1389
+#, fuzzy
+msgid "devcp_add_previews_success_replace"
+msgstr "Preview %1$s was replaced with file %2$s successfully."
+
+#. %s is the filename.
+#: controllers/developers_controller.php:1391
+#, fuzzy
+msgid "devcp_add_previews_success_upload"
+msgstr "File %s was uploaded successfully. You can add a caption below."
+
+#: controllers/components/developers.php:1163
+#, fuzzy
+msgid "devcp_additem_addontype_autodetect"
+msgstr "(auto-detect)"
+
+#: views/elements/developers/additem.thtml:76
+#, fuzzy
+msgid "devcp_additem_linktitle_opensin_newwindow"
+msgstr "Opens in a new window"
+
+#: views/elements/developers/additem.thtml:41
+#, fuzzy
+msgid "devcp_additem_sidebar_title"
+msgstr "Submit Add-on"
+
+#: views/elements/developers/additem.thtml:53
+#, fuzzy
+msgid "devcp_additem_step0_newlink"
+msgstr "Developer Agreement"
+
+#: views/elements/developers/additem.thtml:46
+#, fuzzy
+msgid "devcp_additem_step1_link"
+msgstr "Step 1: Upload"
+
+#: views/elements/developers/additem.thtml:47
+#, fuzzy
+msgid "devcp_additem_step2_link"
+msgstr "Step 2: Add-on Details"
+
+#: views/elements/developers/additem.thtml:48
+#, fuzzy
+msgid "devcp_additem_step3_link"
+msgstr "Step 3: Version Details"
+
+#: views/elements/developers/additem.thtml:49
+#, fuzzy
+msgid "devcp_additem_step4_link"
+msgstr "Step 4: Localization"
+
+#: views/elements/developers/additem.thtml:50
+#, fuzzy
+msgid "devcp_additem_step5_link"
+msgstr "Step 5: Success"
+
+#: views/elements/developers/additem.thtml:76
+#, fuzzy
+msgid "devcp_additem_submissionhelp_link"
+msgstr "Submission Help"
+
+#: controllers/previews_controller.php:168
+#: controllers/previews_controller.php:277
+#, fuzzy
+msgid "devcp_addon_field_preview_caption_displaytitle"
+msgstr "Preview Caption"
+
+#: views/developers/addon_status.thtml:177
+#, fuzzy
+msgid "devcp_addon_status_action_activate"
+msgstr "Make Active"
+
+#: views/developers/addon_status.thtml:178
+#, fuzzy
+msgid "devcp_addon_status_action_activate_description"
+msgstr ""
+"Make your add-on active for it to show up in public listings and enable the "
+"update check service."
+
+#: views/developers/addon_status.thtml:135
+#, fuzzy
+msgid "devcp_addon_status_action_complete"
+msgstr "Complete Add-on"
+
+#: views/developers/addon_status.thtml:136
+#, fuzzy
+msgid "devcp_addon_status_action_complete_description"
+msgstr "Complete your add-on and move to the Sandbox"
+
+#: views/developers/addon_status.thtml:181
+#, fuzzy
+msgid "devcp_addon_status_action_deactivate"
+msgstr "Make Inactive"
+
+#: views/developers/addon_status.thtml:182
+#, fuzzy
+msgid "devcp_addon_status_action_deactivate_description"
+msgstr ""
+"Make your add-on inactive to hide it from all public listings and disable "
+"the update check service."
+
+#: views/developers/addon_status.thtml:143
+#, fuzzy
+msgid "devcp_addon_status_action_move"
+msgstr "Move to Sandbox"
+
+#: views/developers/addon_status.thtml:144
+#, fuzzy
+msgid "devcp_addon_status_action_move_description"
+msgstr "Move your add-on back to the Sandbox. This is reversible."
+
+#: views/developers/addon_status.thtml:139
+#, fuzzy
+msgid "devcp_addon_status_action_nominate"
+msgstr "Nominate for Public"
+
+#: views/developers/addon_status.thtml:140
+#, fuzzy
+msgid "devcp_addon_status_action_nominate_description"
+msgstr "Nominate your add-on to become Public"
+
+#: views/developers/addon_status.thtml:147
+#, fuzzy
+msgid "devcp_addon_status_action_public"
+msgstr "Make Public"
+
+#: views/developers/addon_status.thtml:148
+#, fuzzy
+msgid "devcp_addon_status_action_public_description"
+msgstr "Make your add-on Public again."
+
+#: views/developers/addon_status.thtml:169
+#, fuzzy
+msgid "devcp_addon_status_active"
+msgstr ""
+"Your add-on is <span class=\"inactive-0\">Active</span>. This means your add-"
+"on is showing up in all available listings appropriate for its status above."
+
+#: views/developers/addon_status.thtml:111
+#, fuzzy
+msgid "devcp_addon_status_completion_disabled"
+msgstr ""
+"Please fulfill the criteria above before you can complete your add-on and "
+"move it to the <span class=\"status-1\">Sandbox</span>."
+
+#: views/developers/addon_status.thtml:108
+#, fuzzy
+msgid "devcp_addon_status_completion_enabled"
+msgstr ""
+"You may now complete your add-on and move it to the <span class=\"status-1"
+"\">Sandbox</span> by clicking the button below."
+
+#: views/developers/addon_status.thtml:102
+#, fuzzy
+msgid "devcp_addon_status_criteria_category"
+msgstr "At least one category selected"
+
+#: views/developers/addon_status.thtml:101
+#, fuzzy
+msgid "devcp_addon_status_criteria_description"
+msgstr "Add-on Description required"
+
+#: views/developers/addon_status.thtml:99
+#, fuzzy
+msgid "devcp_addon_status_criteria_name"
+msgstr "Add-on Name required"
+
+#: views/developers/addon_status.thtml:120
+#, fuzzy
+msgid "devcp_addon_status_criteria_prerelease"
+msgstr "Add-on is not marked as pre-release."
+
+#: views/developers/addon_status.thtml:119
+#, fuzzy
+msgid "devcp_addon_status_criteria_preview"
+msgstr "At least one preview image required for extensions and themes."
+
+#: views/developers/addon_status.thtml:100
+#, fuzzy
+msgid "devcp_addon_status_criteria_summary"
+msgstr "Add-on Summary required"
+
+#. %s is the status in a span, e.g. "<span>_('Public')</span>".
+#: views/developers/addon_status.thtml:58
+#, fuzzy
+msgid "devcp_addon_status_header"
+msgstr "Add-on Status: %s"
+
+#: views/developers/addon_status.thtml:152
+#: views/developers/addon_status.thtml:173
+#, fuzzy
+msgid "devcp_addon_status_header_actions"
+msgstr "Available Actions"
+
+#: views/developers/addon_status.thtml:168
+#, fuzzy
+msgid "devcp_addon_status_header_active"
+msgstr "Active Status: <span class=\"inactive-0\">Active</span>"
+
+#: views/developers/addon_status.thtml:97
+#, fuzzy
+msgid "devcp_addon_status_header_criteria"
+msgstr "Add-on Completion Criteria"
+
+#: views/developers/addon_status.thtml:164
+#, fuzzy
+msgid "devcp_addon_status_header_inactive"
+msgstr "Active Status: <span class=\"inactive-1\">Inactive</span>"
+
+#: views/developers/addon_status.thtml:117
+#, fuzzy
+msgid "devcp_addon_status_header_nomination"
+msgstr "Public Nomination Criteria"
+
+#: views/developers/addon_status.thtml:190
+#, fuzzy
+msgid "devcp_addon_status_header_trusted"
+msgstr "Trusted Status: <span class=\"status-4\">Trusted</span>"
+
+#: views/developers/addon_status.thtml:165
+#, fuzzy
+msgid "devcp_addon_status_inactive"
+msgstr ""
+"Your add-on is <span class=\"inactive-1\">Inactive</span>. This means your "
+"add-on will not show up in any listing, regardless of its status above. "
+"Updates are <b>not</b> being provided to your add-on through the update "
+"check service."
+
+#: views/developers/addon_status.thtml:128
+#, fuzzy
+msgid "devcp_addon_status_nominate_disabled"
+msgstr ""
+"Please fulfill the criteria above before nominating your add-on to become "
+"<span class=\"status-4\">Public</span>."
+
+#: views/developers/addon_status.thtml:125
+#, fuzzy
+msgid "devcp_addon_status_nominate_enabled"
+msgstr ""
+"You may now nominate your add-on for <span class=\"status-4\">Public</span> "
+"by clicking the button below."
+
+#: views/developers/addon_status.thtml:64
+#, fuzzy
+msgid "devcp_addon_status_public"
+msgstr "Public"
+
+#: views/developers/addon_status.thtml:63
+#, fuzzy
+msgid "devcp_addon_status_sandbox"
+msgstr "Sandbox"
+
+#. %s is an email address.
+#: views/developers/addon_status.thtml:89
+#, fuzzy
+msgid "devcp_addon_status_switch_disabled"
+msgstr ""
+"Your add-on was <span class=\"status-5\">Disabled</span> by an administrator "
+"and cannot be used. If you have any questions, please e-mail %s."
+
+#: views/developers/addon_status.thtml:67
+#, fuzzy
+msgid "devcp_addon_status_switch_incomplete"
+msgstr ""
+"Your add-on is currently <span class=\"status-0\">Incomplete</span>. This "
+"means your add-on is not showing up on any portion of the site or update "
+"check service. You may come to this page to complete your add-on after it "
+"meets the criteria below for completion and transfer to the <span class="
+"\"status-1\">Sandbox</span>."
+
+#. %s is a number, perhaps 42.
+#: views/developers/addon_status.thtml:77
+#, fuzzy
+msgid "devcp_addon_status_switch_nominated"
+msgstr ""
+"Your add-on is currently nominated to become <span class=\"status-4"
+"\">Public</span> and is awaiting editor review. There are currently %s other "
+"add-ons in the nomination queue."
+
+#. %s is an email address.
+#: views/developers/addon_status.thtml:81
+#, fuzzy
+msgid "devcp_addon_status_switch_pending"
+msgstr ""
+"Your add-on is pending. This shouldn't have happened. Please e-mail %s with "
+"your add-on ID and state this error."
+
+#: views/developers/addon_status.thtml:85
+#, fuzzy
+msgid "devcp_addon_status_switch_public"
+msgstr ""
+"Your add-on is <span class=\"status-4\">Public</span>, which means it will "
+"show up in all listings and searches and can be downloaded without "
+"restriction. Updates are being provided to your add-on through the update "
+"check service."
+
+#: views/developers/addon_status.thtml:71
+#: views/developers/addon_status.thtml:75
+#, fuzzy
+msgid "devcp_addon_status_switch_sandbox"
+msgstr ""
+"Your add-on is in the <span class=\"status-1\">Sandbox</span>, which means "
+"it will show up in listings and searches, but users must log in to download "
+"it. Updates are <b>not</b> being provided to your add-on through the update "
+"check service."
+
+#. %s is the add-on name.
+#: views/developers/addon_status_nominate.thtml:43
+#: views/developers/addon_status_confirm.thtml:43
+#: views/developers/addon_status.thtml:43
+#, fuzzy
+msgid "devcp_addon_status_title"
+msgstr "%s Status"
+
+#: views/developers/addon_status.thtml:191
+#, fuzzy
+msgid "devcp_addon_status_trusted"
+msgstr ""
+"Your add-on is <span class=\"status-4\">Trusted</span>. This means you can "
+"submit updates to your add-on without editor review."
+
+#: views/developers/dashboard.thtml:68
+#, fuzzy
+msgid "devcp_dashboard_active"
+msgstr "Active"
+
+#. %1$s is the add-on type string
+#. %2$s is Inactive or Active in a <span>
+#. %3$s is the addon's public status (Public, In Sandbox, ...) in a <span>
+#: views/developers/dashboard.thtml:69
+#, fuzzy
+msgid "devcp_dashboard_addontype_status"
+msgstr "%1$s currenty %2$s and %3$s"
+
+#: views/developers/dashboard.thtml:67
+#, fuzzy
+msgid "devcp_dashboard_change_status"
+msgstr "Change Status"
+
+#. %s is the addons email address.
+#: views/developers/dashboard.thtml:99
+#, fuzzy
+msgid "devcp_dashboard_disabled_questions"
+msgstr ""
+"Your add-on was disabled by an administrator and cannot be used. If you "
+"have any questions, please email %s."
+
+#. %s is the (localized) add-on status string in a span, e.g. "Disabled"
+#: views/developers/dashboard.thtml:98
+#, fuzzy
+msgid "devcp_dashboard_disabled_status"
+msgstr "Add-on Status: %s"
+
+#: views/developers/dashboard.thtml:43
+#, fuzzy
+msgid "devcp_dashboard_header_main"
+msgstr "Developer Dashboard"
+
+#: views/developers/dashboard.thtml:110
+#, fuzzy
+msgid "devcp_dashboard_header_welcome"
+msgstr "Welcome to the Developer Dashboard"
+
+#: views/developers/dashboard.thtml:68
+#, fuzzy
+msgid "devcp_dashboard_inactive"
+msgstr "Inactive"
+
+#. %s is a date in the _('date') format
+#: views/developers/dashboard.thtml:65
+#, fuzzy
+msgid "devcp_dashboard_last_edited"
+msgstr "Last edited on %s"
+
+#: views/developers/dashboard.thtml:111
+#, fuzzy
+msgid "devcp_dashboard_learn"
+msgstr ""
+"You don't currently have any add-ons hosted on Mozilla Add-ons. To learn how "
+"the process works and submit your first add-on, click Get Started below."
+
+#: views/developers/dashboard.thtml:112
+#, fuzzy
+msgid "devcp_dashboard_start"
+msgstr "Get Started"
+
+#: views/developers/dashboard.thtml:82
+#, fuzzy
+msgid "devcp_dashboard_versions"
+msgstr "Versions and Files"
+
+#: views/developers/dashboard.thtml:91
+#, fuzzy
+msgid "devcp_dashboard_versions_new"
+msgstr "Upload a new version"
+
+#. %s is the preview ID number.
+#: controllers/developers_controller.php:1415
+#, fuzzy
+msgid "devcp_delete_previews_error"
+msgstr "Preview %s could not be deleted from the database. Please try again."
+
+#. %s is the preview ID number.
+#: controllers/developers_controller.php:1413
+#, fuzzy
+msgid "devcp_delete_previews_success"
+msgstr "Preview %s has been deleted successfully."
+
+#: controllers/developers_controller.php:1089
+#, fuzzy
+msgid "devcp_delete_version_priv_error"
+msgstr "You do not have privileges to delete versions or files."
+
+#. %1$s is the count of files, a number
+#. %2$s is a status string like _('Public') or _('Incomplete')
+#: controllers/components/amo.php:549
+#, fuzzy
+msgid "devcp_describe_version_status"
+msgid_plural "devcp_describe_version_status"
+msgstr[0] "%1$s %2$s file"
+msgstr[1] "%1$s %2$s files"
+
+#. %s is a version number. Example: 3.0
+#: views/developers/versions.thtml:65
+#, fuzzy, php-format
+msgid "devcp_details_version"
+msgstr "Version %s"
+
+#: views/developers/discuss.thtml:68
+#, fuzzy
+msgid "devcp_discuss_addreply_header"
+msgstr "Add Reply"
+
+#: views/developers/discuss.thtml:57
+#, fuzzy
+msgid "devcp_discuss_allreplies_header"
+msgstr "Replies"
+
+#. notice when an error occurs saving a discussion reply
+#. %1 is the email address (linked) for the amo-editors list
+#: views/developers/discuss.thtml:70
+#, fuzzy
+msgid "devcp_discuss_error_notice"
+msgstr ""
+"There was an error saving your reply. Please contact %1$s about the issue."
+
+#. %1 is the add-on name, %2 is the add-on's version number currently being reviewed by an editor
+#: views/developers/discuss.thtml:46
+#, fuzzy
+msgid "devcp_discuss_intro"
+msgstr ""
+"A Mozilla Add-ons Editor requested further information from you regarding "
+"version %2$s of your add-on %1$s."
+
+#. %1 is the add-on name
+#: views/developers/discuss.thtml:43
+#, fuzzy
+msgid "devcp_discuss_pagetitle"
+msgstr "Provide More Information For the Add-on Review of %1$s"
+
+#. submit button text
+#: views/developers/discuss.thtml:79
+#, fuzzy
+msgid "devcp_discuss_submit_reply"
+msgstr "Submit Reply"
+
+#: views/developers/discuss.thtml:72
+#, fuzzy
+msgid "devcp_discuss_success_message"
+msgstr ""
+"Your reply was successfully saved. The other participants of the discussion "
+"will be notified by email."
+
+#. in an author/editor discussion about an add-on to be reviewed:
+#. %1 is the commenter's user name (linked).
+#. %2 is the full date the comment was made.
+#: views/developers/discuss.thtml:52 views/developers/discuss.thtml:62
+#, fuzzy
+msgid "devcp_discuss_writtenby"
+msgstr "written by %1$s on %2$s"
+
+#: views/developers/addon_edit_authors.thtml:72
+#: views/developers/addon_edit_authors.thtml:81
+#, fuzzy
+msgid "devcp_edit_authors_add_author"
+msgstr "Add New Author"
+
+#: views/developers/addon_edit_authors.thtml:96
+#, fuzzy
+msgid "devcp_edit_authors_add_author_button"
+msgstr "Add Author"
+
+#: views/developers/addon_edit_authors.thtml:83
+#, fuzzy
+msgid "devcp_edit_authors_add_email"
+msgstr "Author Account Email:"
+
+#: views/developers/addon_edit_authors.thtml:98
+#, fuzzy
+msgid "devcp_edit_authors_add_loading"
+msgstr "Checking account email..."
+
+#: views/developers/addon_edit_authors.thtml:70
+#, fuzzy
+msgid "devcp_edit_authors_click_save"
+msgstr "Click the Update Authors button below to save."
+
+#: views/developers/addon_edit_authors.thtml:58
+#, fuzzy
+msgid "devcp_edit_authors_header_current"
+msgstr "Current Authors"
+
+#: views/developers/addon_edit_authors.thtml:50
+#, fuzzy
+msgid "devcp_edit_authors_header_manage"
+msgstr "Manage Add-on Authors"
+
+#: views/developers/addon_edit_authors.thtml:93
+#, fuzzy
+msgid "devcp_edit_authors_label_add_listed"
+msgstr "List as author in pubilc display pages"
+
+#: views/developers/addon_edit_authors.thtml:89
+#, fuzzy
+msgid "devcp_edit_authors_label_developer"
+msgstr ""
+"<strong>Developer</strong> - Can manage all aspects of the add-on listing, "
+"except for adding and removing other authors."
+
+#: views/developers/addon_edit_authors.thtml:88
+#, fuzzy
+msgid "devcp_edit_authors_label_owner"
+msgstr ""
+"<strong>Owner</strong> - Can manage all aspects of the add-on listing, "
+"including adding and removing other authors."
+
+#: views/developers/addon_edit_authors.thtml:90
+#, fuzzy
+msgid "devcp_edit_authors_label_viewer"
+msgstr ""
+"<strong>Viewer</strong> - Can view add-on developer listing and statistics, "
+"but can't make any changes."
+
+#. Placeholder for the empty option in a <select>.
+#: views/developers/addon_edit_categories.thtml:69
+#, fuzzy
+msgid "devcp_edit_authors_option_empty"
+msgstr "----------------"
+
+#: views/developers/addon_edit_authors.thtml:86
+#, fuzzy
+msgid "devcp_edit_authors_select_role"
+msgstr "Select a role for the author:"
+
+#. Column name in a table.
+#: views/developers/addon_edit_authors.thtml:62
+#, fuzzy
+msgid "devcp_edit_authors_th_author"
+msgstr "Author"
+
+#. Column name in a table.
+#: views/developers/addon_edit_authors.thtml:64
+#, fuzzy
+msgid "devcp_edit_authors_th_listed"
+msgstr "Listed"
+
+#. Column name in a table.
+#: views/developers/addon_edit_authors.thtml:63
+#, fuzzy
+msgid "devcp_edit_authors_th_role"
+msgstr "Role"
+
+#: views/developers/addon_edit_authors.thtml:77
+#, fuzzy
+msgid "devcp_edit_authors_update_author"
+msgstr "Update authors"
+
+#: views/developers/addon_edit_categories.thtml:99
+#, fuzzy
+msgid "devcp_edit_categories_button_update"
+msgstr "Update Categories"
+
+#: views/developers/addon_edit_categories.thtml:88
+#, fuzzy
+msgid "devcp_edit_categories_does_not_fit"
+msgstr "My add-on doesn't fit into any available categories."
+
+#. %s is the application name (Firefox, Thunderbird).
+#: views/developers/addon_edit_categories.thtml:61
+#, fuzzy
+msgid "devcp_edit_categories_header_application"
+msgstr "%s Categories"
+
+#: views/developers/addon_edit_categories.thtml:49
+#, fuzzy
+msgid "devcp_edit_categories_header_manage"
+msgstr "Manage Add-on Categories"
+
+#: views/developers/addon_edit_categories.thtml:91
+#, fuzzy
+msgid "devcp_edit_categories_hover"
+msgstr "Hover over a category to see its description."
+
+#. %s is the category number (1, 2, 3).
+#: views/developers/addon_edit_categories.thtml:67
+#, fuzzy
+msgid "devcp_edit_categories_label_category_num"
+msgstr "Category %s"
+
+#: views/developers/addon_edit_categories.thtml:94
+#: views/developers/addon_edit_categories.thtml:103
+#, fuzzy
+msgid "devcp_edit_categories_none_available"
+msgstr "No categories are available for this add-on type and application."
+
+#: views/developers/addon_edit_categories.thtml:86
+#, fuzzy
+msgid "devcp_edit_categories_other"
+msgstr ""
+"Place your add-on into this category only if it does not fit into any other "
+"available categories."
+
+#. %s is the application name (Firefox, Thunderbird).
+#: views/developers/addon_edit_categories.thtml:63
+#, fuzzy
+msgid "devcp_edit_categories_select_application_categories"
+msgstr "Select up to three %s categories for your add-on"
+
+#: views/developers/addon_edit.thtml:47
+#, fuzzy
+msgid "devcp_edit_dd_manage_authors"
+msgstr "Add or remove users that can manage this add-on."
+
+#: views/developers/addon_edit.thtml:49
+#, fuzzy
+msgid "devcp_edit_dd_manage_categories"
+msgstr ""
+"Select the relevant categories for each application your add-on supports."
+
+#: views/developers/addon_edit.thtml:51
+#, fuzzy
+msgid "devcp_edit_dd_manage_description"
+msgstr ""
+"Add and modify translations for your add-on's summary, description, end-user "
+"license, and privacy policy."
+
+#: views/developers/addon_edit.thtml:53
+#, fuzzy
+msgid "devcp_edit_dd_manage_properties"
+msgstr "Change your add-on's name, homepage, icon, and other flags."
+
+#: views/developers/addon_edit_descriptions.thtml:116
+#, fuzzy
+msgid "devcp_edit_description_button_update"
+msgstr "Update Descriptions"
+
+#: views/developers/addon_edit_descriptions.thtml:115
+#, fuzzy
+msgid "devcp_edit_description_correct_error"
+msgstr "Please correct the errors above indicated in red."
+
+#: views/developers/addon_edit_descriptions.thtml:51
+#, fuzzy
+msgid "devcp_edit_descriptions_header"
+msgstr "Edit Add-on Descriptions"
+
+#: views/developers/addon_edit_descriptions.thtml:94
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_comments_description"
+msgstr ""
+"Any information end users may want to know that isn't necessarily applicable "
+"to the add-on summary or description. Common uses include listing known "
+"major bugs, information on how to report bugs, anticipated release date of a "
+"new version, etc."
+
+#: views/developers/addon_edit_descriptions.thtml:93
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_comments_name"
+msgstr "Developer Comments"
+
+#: views/developers/addon_edit_descriptions.thtml:86
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_description_description"
+msgstr ""
+"The description of your add-on is a longer explanation of features, "
+"functionality, and other relevant information. It is displayed under the "
+"summary on the add-on's display page."
+
+#: views/developers/addon_edit_descriptions.thtml:85
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_description_name"
+msgstr "Add-on Description"
+
+#: views/developers/addon_edit_descriptions.thtml:103
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_eula_description"
+msgstr ""
+"If your add-on has an End-User License Agreement (EULA), please enter its "
+"text below. If set below, users will be required to agree to this before "
+"installing your add-on. Please note that a EULA is not the same as a code "
+"license such as GPL or MPL."
+
+#: views/developers/addon_edit_descriptions.thtml:102
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_eula_name"
+msgstr "End-User License Agreement"
+
+#: views/developers/addon_edit_descriptions.thtml:112
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_privacy_description"
+msgstr ""
+"If your add-on has a privacy policy, enter its text here. Your add-on's "
+"display page will display a link to the policy."
+
+#: views/developers/addon_edit_descriptions.thtml:111
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_privacy_name"
+msgstr "Privacy Policy"
+
+#: views/developers/addon_edit_descriptions.thtml:78
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_summary_description"
+msgstr ""
+"The summary is a short explanation of your add-on's basic functionality that "
+"is displayed in search and browse listings, as well as at the top of your "
+"add-on's display page. <strong>Limit of 250 characters.</strong>"
+
+#: views/developers/addon_edit_descriptions.thtml:77
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_summary_name"
+msgstr "Add-on Summary"
+
+#: views/developers/addon_edit.thtml:46
+#, fuzzy
+msgid "devcp_edit_dt_manage_authors"
+msgstr "Manage Add-on Authors"
+
+#: views/developers/addon_edit.thtml:48
+#, fuzzy
+msgid "devcp_edit_dt_manage_categories"
+msgstr "Manage Add-on Categories"
+
+#: views/developers/addon_edit.thtml:50
+#, fuzzy
+msgid "devcp_edit_dt_manage_descriptions"
+msgstr "Manage Add-on Descriptions"
+
+#: views/developers/addon_edit.thtml:52
+#, fuzzy
+msgid "devcp_edit_dt_manage_properties"
+msgstr "Manage Add-on Properties"
+
+#: views/developers/addon_edit_properties.thtml:170
+#, fuzzy
+msgid "devcp_edit_label_externalsoftware"
+msgstr "This add-on requires external software"
+
+#: views/developers/addon_edit_properties.thtml:205
+#, fuzzy
+msgid "devcp_edit_label_locale_disambiguation"
+msgstr "Additional Locale Info"
+
+#: views/developers/addon_edit_properties.thtml:168
+#, fuzzy
+msgid "devcp_edit_label_prerelease"
+msgstr "This is a pre-release"
+
+#: views/developers/addon_edit_properties.thtml:169
+#, fuzzy
+msgid "devcp_edit_label_sitespecific"
+msgstr "This is a site-specific add-on"
+
+#: views/developers/addon_edit_properties.thtml:202
+#, fuzzy
+msgid "devcp_edit_label_target_locale"
+msgstr "Target Locale"
+
+#: views/developers/addon_edit_properties.thtml:212
+#, fuzzy
+msgid "devcp_edit_properties_button_update"
+msgstr "Update Properties"
+
+#: views/developers/addon_edit_properties.thtml:198
+#, fuzzy
+msgid "devcp_edit_properties_change_guid"
+msgstr "Only change if you understand all of the consequences."
+
+#: views/developers/addon_edit_properties.thtml:109
+#, fuzzy
+msgid "devcp_edit_properties_current_icon"
+msgstr "Current Icon"
+
+#: views/developers/addon_edit_properties.thtml:85
+#, fuzzy
+msgid "devcp_edit_properties_default_locale"
+msgstr ""
+"An add-on's default locale is the main locale in which translations must be "
+"present. If translations for your add-on's descriptions are unavailable in a "
+"user's selected language, they will fall back to this default locale."
+
+#: views/developers/addon_edit_properties.thtml:167
+#, fuzzy
+msgid "devcp_edit_properties_flags"
+msgstr "These flags are used to filter and classify add-ons."
+
+#: views/developers/addon_edit_properties.thtml:174
+#, fuzzy
+msgid "devcp_edit_properties_guid"
+msgstr ""
+"The GUID of your add-on is specified in its install.rdf and uniquely "
+"identifies it. You cannot change your GUID once it is listed on Mozilla Add-"
+"ons."
+
+#: views/developers/addon_edit_properties.thtml:53
+#, fuzzy
+msgid "devcp_edit_properties_header"
+msgstr "Edit Add-on Properties"
+
+#: views/developers/addon_edit_properties.thtml:186
+#, fuzzy
+msgid "devcp_edit_properties_header_addon_type"
+msgstr "Add-on Type"
+
+#: views/developers/addon_edit_properties.thtml:181
+#, fuzzy
+msgid "devcp_edit_properties_header_admin_settings"
+msgstr "Admin Settings"
+
+#: views/developers/addon_edit_properties.thtml:84
+#, fuzzy
+msgid "devcp_edit_properties_header_default_locale"
+msgstr "Default Locale"
+
+#: views/developers/addon_edit_properties.thtml:166
+#, fuzzy
+msgid "devcp_edit_properties_header_flags"
+msgstr "Add-on Flags"
+
+#: views/developers/addon_edit_properties.thtml:173
+#: views/developers/addon_edit_properties.thtml:197
+#, fuzzy
+msgid "devcp_edit_properties_header_guid"
+msgstr "Add-on GUID"
+
+#: views/developers/addon_edit_properties.thtml:104
+#, fuzzy
+msgid "devcp_edit_properties_header_icon"
+msgstr "Add-on Icon"
+
+#: views/developers/addon_edit_properties.thtml:159
+#, fuzzy
+msgid "devcp_edit_properties_header_other_settings"
+msgstr "Other Settings"
+
+#. A header on the admin page to toggle trusted status.
+#: views/developers/addon_edit_properties.thtml:182
+#, fuzzy
+msgid "devcp_edit_properties_header_trusted"
+msgstr "Trusted Add-on?"
+
+#: views/developers/addon_edit_properties.thtml:160
+#, fuzzy
+msgid "devcp_edit_properties_header_view_source"
+msgstr "View Source Online"
+
+#. %s is a comma-separated list of image extensions ".png, .jpg"
+#: views/developers/addon_edit_properties.thtml:106
+#, fuzzy
+msgid "devcp_edit_properties_icon"
+msgstr ""
+"The add-on icon is a small image that is displayed next to your add-on's "
+"name in browse and search results, display pages, and in the add-on "
+"installation dialog. The image will automatically be resized to 32 x 32 "
+"pixels. Please use one of the following image types: %s"
+
+#: views/developers/addon_edit_properties.thtml:171
+#, fuzzy
+msgid "devcp_edit_properties_label_binary"
+msgstr "This add-on contains binary components"
+
+#: views/developers/addon_edit_properties.thtml:185
+#, fuzzy
+msgid "devcp_edit_properties_label_not_trusted"
+msgstr "Not Trusted"
+
+#: views/developers/addon_edit_properties.thtml:184
+#, fuzzy
+msgid "devcp_edit_properties_label_trusted"
+msgstr "Trusted"
+
+#: views/developers/addon_edit_properties.thtml:110
+#, fuzzy
+msgid "devcp_edit_properties_new_icon"
+msgstr "New Icon"
+
+#: views/developers/addon_edit_properties.thtml:118
+#, fuzzy
+msgid "devcp_edit_properties_remove_icon"
+msgstr "Remove Icon"
+
+#: views/developers/addon_edit_properties.thtml:136
+#, fuzzy
+msgid "devcp_edit_properties_transbox_homepage_description"
+msgstr ""
+"If your add-on has another homepage, enter its address here. Adding other "
+"translations is not necessary unless your website is localized into other "
+"languages."
+
+#: views/developers/addon_edit_properties.thtml:135
+#, fuzzy
+msgid "devcp_edit_properties_transbox_homepage_name"
+msgstr "Add-on Homepage"
+
+#: views/developers/addon_edit_properties.thtml:79
+#, fuzzy
+msgid "devcp_edit_properties_transbox_name_description"
+msgstr "The name of your add-on is displayed everywhere your add-on is listed."
+
+#: views/developers/addon_edit_properties.thtml:78
+#, fuzzy
+msgid "devcp_edit_properties_transbox_name_name"
+msgstr "Add-on Name"
+
+#: views/developers/addon_edit_properties.thtml:145
+#, fuzzy
+msgid "devcp_edit_properties_transbox_supportemail_description"
+msgstr ""
+"If you have an email address for support inquiries, enter it here. Adding "
+"other translations is not necessary unless you have different email "
+"addresses for different languages."
+
+#: views/developers/addon_edit_properties.thtml:144
+#, fuzzy
+msgid "devcp_edit_properties_transbox_supportemail_name"
+msgstr "Support Email Address"
+
+#: views/developers/addon_edit_properties.thtml:154
+#, fuzzy
+msgid "devcp_edit_properties_transbox_supporturl_description"
+msgstr ""
+"If your add-on has a support website or forum, enter its address here. "
+"Adding other translations is not necessary unless your website is localized "
+"into other languages."
+
+#: views/developers/addon_edit_properties.thtml:153
+#, fuzzy
+msgid "devcp_edit_properties_transbox_supporturl_name"
+msgstr "Support Website"
+
+#: views/developers/addon_edit_properties.thtml:183
+#, fuzzy
+msgid "devcp_edit_properties_trusted"
+msgstr "Trusted add-ons can become public without Editor review."
+
+#. %s is href="..." and should stay in the <a> tag.
+#: views/developers/addon_edit_properties.thtml:119
+#, fuzzy
+msgid "devcp_edit_properties_undelete"
+msgstr "Icon will be deleted on save. <a %s>Cancel?</a>"
+
+#: views/developers/addon_edit_properties.thtml:161
+#, fuzzy
+msgid "devcp_edit_properties_view_source"
+msgstr ""
+"The source of your add-on files can be viewed online by any logged in user "
+"if you wish."
+
+#: views/developers/addon_edit_properties.thtml:162
+#, fuzzy
+msgid "devcp_edit_properties_view_source_allow"
+msgstr "Allow online source viewing"
+
+#: views/developers/addon_edit_properties.thtml:163
+#, fuzzy
+msgid "devcp_edit_properties_view_source_do_not_allow"
+msgstr "Do not allow online source viewing"
+
+#: views/elements/developers/editbox.thtml:46
+#, fuzzy
+msgid "devcp_editbox_authors"
+msgstr "Authors"
+
+#: views/elements/developers/editbox.thtml:47
+#, fuzzy
+msgid "devcp_editbox_categories"
+msgstr "Categories"
+
+#: views/elements/developers/editbox.thtml:52
+#, fuzzy
+msgid "devcp_editbox_change_status"
+msgstr "Change Status"
+
+#: views/elements/developers/editbox.thtml:48
+#, fuzzy
+msgid "devcp_editbox_descriptions"
+msgstr "Descriptions"
+
+#: views/elements/developers/editbox.thtml:43
+#, fuzzy
+msgid "devcp_editbox_edit_addon"
+msgstr "Edit Add-on"
+
+#: views/elements/developers/editbox.thtml:57
+#, fuzzy
+msgid "devcp_editbox_new_version"
+msgstr "New Version"
+
+#: views/elements/developers/editbox.thtml:49
+#, fuzzy
+msgid "devcp_editbox_properties"
+msgstr "Properties"
+
+#: views/elements/developers/editbox.thtml:60
+#, fuzzy
+msgid "devcp_editbox_screenshots"
+msgstr "Preview Screenshots"
+
+#: views/elements/developers/editbox.thtml:53
+#, fuzzy
+msgid "devcp_editbox_statistics_dashboard"
+msgstr "Statistics Dashboard"
+
+#: views/elements/developers/editbox.thtml:54
+#, fuzzy
+msgid "devcp_editbox_versions"
+msgstr "Versions and Files"
+
+#: views/elements/developers/editbox.thtml:42
+#, fuzzy
+msgid "devcp_editbox_view_listing"
+msgstr "View Listing"
+
+#: views/elements/developers/editorsmenu.thtml:59
+#, fuzzy
+msgid "devcp_editorsqueue_featured"
+msgstr "Featured Add-ons"
+
+#. %1 is the review count
+#: views/elements/developers/editorsqueue.thtml:42
+#: views/elements/developers/editorsmenu.thtml:56
+#, fuzzy, php-format
+msgid "devcp_editorsqueue_moderatedreviews"
+msgid_plural "devcp_editorsqueue_moderatedreviews"
+msgstr[0] "Moderated Reviews (%s)"
+msgstr[1] "Moderated Reviews (%s)"
+
+#. %1 is the nominated addons count
+#: views/elements/developers/editorsqueue.thtml:44
+#: views/elements/developers/editorsmenu.thtml:58
+#, fuzzy, php-format
+msgid "devcp_editorsqueue_nominated"
+msgid_plural "devcp_editorsqueue_nominated"
+msgstr[0] "Nominated Add-ons (%s)"
+msgstr[1] "Nominated Add-ons (%s)"
+
+#. %1 is the update count
+#: views/elements/developers/editorsqueue.thtml:43
+#: views/elements/developers/editorsmenu.thtml:57
+#, fuzzy, php-format
+msgid "devcp_editorsqueue_pendingupdates"
+msgid_plural "devcp_editorsqueue_pendingupdates"
+msgstr[0] "Pending Updates (%s)"
+msgstr[1] "Pending Updates (%s)"
+
+#: controllers/statistics_controller.php:147
+#: controllers/statistics_controller.php:361
+#: controllers/previews_controller.php:108
+#: controllers/previews_controller.php:211
+#: controllers/previews_controller.php:312
+#, fuzzy
+msgid "devcp_error_addon_access_denied"
+msgstr "You do not have access to that add-on."
+
+#. %s is a complete URL with the text from devcp_error_appversion_reference_link_text
+#. in the <a> tag. This should be fixed.
+#: controllers/components/developers.php:591
+#, fuzzy, php-format
+msgid "devcp_error_appversion_reference_link"
+msgstr "Please see %s for reference."
+
+#. This is the link text in the <a> for devcp_error_appversion_reference_link. This
+#. should be fixed.
+#: controllers/components/developers.php:591
+#, fuzzy
+msgid "devcp_error_appversion_reference_link_text"
+msgstr "this page"
+
+#: views/developers/addon_edit_authors.thtml:76
+#, fuzzy
+msgid "devcp_error_empty_authors"
+msgstr "Your add-on must have at least one owner."
+
+#. %1$s is the name of the file
+#: controllers/components/developers.php:658
+#, fuzzy
+msgid "devcp_error_file_exists"
+msgstr ""
+"A version of that addon already exists. To replace it, you must delete the "
+"file %1$s first."
+
+#. %1$s is a file extension. Example: .exe
+#. %2$s is a comma separated list of extensions. Example: .xpi, .jar
+#: controllers/components/developers.php:355
+#, fuzzy, php-format
+msgid "devcp_error_file_extension"
+msgstr ""
+"That file extension (%s) is not allowed for the selected add-on type. Please "
+"use one of the following: %s"
+
+#: controllers/components/developers.php:64
+#, fuzzy
+msgid "devcp_error_five_categories"
+msgstr "Please select no more than five categories."
+
+#: controllers/components/developers.php:526
+#, fuzzy
+msgid "devcp_error_guid_application"
+msgstr "The ID of this add-on is already used by an application."
+
+#: controllers/components/developers.php:337
+#: controllers/components/developers.php:389
+#, fuzzy
+msgid "devcp_error_http_incomplete"
+msgstr "Incomplete transfer"
+
+#: controllers/components/developers.php:335
+#: controllers/components/developers.php:336
+#: controllers/components/developers.php:387
+#: controllers/components/developers.php:388
+#, fuzzy
+msgid "devcp_error_http_maxupload"
+msgstr "Exceeds maximum upload size"
+
+#: controllers/components/developers.php:338
+#: controllers/components/developers.php:390
+#, fuzzy
+msgid "devcp_error_http_nofile"
+msgstr "No file uploaded"
+
+#. %1$s is a file extension. Example: .exe
+#. %2$s is a comma separated list of extensions. Example: .xpi, .jar
+#: controllers/components/developers.php:401
+#, fuzzy, php-format
+msgid "devcp_error_icon_extension"
+msgstr ""
+"That file extension (%s) is not allowed for an icon. Please use one of the "
+"following: %s"
+
+#: controllers/developers_controller.php:504
+#, fuzzy
+msgid "devcp_error_index_rdf_notfound"
+msgstr "No install.rdf present."
+
+#: controllers/components/developers.php:601
+#, fuzzy
+msgid "devcp_error_install_manifest"
+msgstr "The following errors were found in install.rdf:"
+
+#: controllers/developers_controller.php:1463
+#, fuzzy
+msgid "devcp_error_invalid_addontype"
+msgstr "Please select a valid add-on type."
+
+#. %$1s is a version. Example: 3.1.1
+#. %$2s is an add-on name.
+#: controllers/components/developers.php:569
+#: controllers/components/developers.php:581
+#, fuzzy, php-format
+msgid "devcp_error_invalid_appversion"
+msgstr "%s is not a valid version for %s"
+
+#. %s is a string
+#: controllers/components/developers.php:521
+#, fuzzy, php-format
+msgid "devcp_error_invalid_guid"
+msgstr "The ID of this add-on is invalid: %s"
+
+#. %$1s is a version. Example: 3.1.1
+#. %$2s is an add-on name.
+#: controllers/components/developers.php:572
+#, fuzzy, php-format
+msgid "devcp_error_invalid_minversion"
+msgstr "%s is not a valid version for %s: minimum versions cannot contain *"
+
+#: controllers/components/developers.php:536
+#, fuzzy
+msgid "devcp_error_invalid_version"
+msgstr ""
+"The version of this add-on is invalid: please see the <a href=\"http://"
+"developer.mozilla.org/en/docs/Toolkit_version_format\">specification</a>"
+
+#: controllers/components/developers.php:531
+#, fuzzy
+msgid "devcp_error_invalid_version_spaces"
+msgstr "The version of this add-on is invalid: versions cannot contain spaces."
+
+#. %s is an error message from the parser.
+#: controllers/components/developers.php:501
+#, fuzzy, php-format
+msgid "devcp_error_manifest_parse"
+msgstr "The following error occurred while parsing install.rdf: %s"
+
+#: controllers/components/developers.php:373
+#, fuzzy
+msgid "devcp_error_move_file"
+msgstr "Could not move file"
+
+#. %s is the name of a file
+#: controllers/components/developers.php:650
+#: controllers/components/developers.php:662
+#: controllers/components/developers.php:667
+#: controllers/components/developers.php:727
+#: controllers/components/developers.php:738
+#: controllers/components/developers.php:743
+#, fuzzy, php-format
+msgid "devcp_error_moving_file"
+msgstr "An error occurred moving %s."
+
+#: controllers/components/developers.php:595
+#, fuzzy
+msgid "devcp_error_mozilla_application"
+msgstr "You must have at least one valid Mozilla target application."
+
+#: controllers/components/developers.php:516
+#, fuzzy
+msgid "devcp_error_no_guid"
+msgstr "No ID could be found for this add-on in install.rdf."
+
+#: controllers/components/developers.php:287
+#, fuzzy
+msgid "devcp_error_no_platform"
+msgstr "No platform selected"
+
+#: controllers/components/developers.php:59
+#, fuzzy
+msgid "devcp_error_one_category"
+msgstr "Please select at least one category."
+
+#: controllers/components/developers.php:92
+#, fuzzy
+msgid "devcp_error_one_user"
+msgstr "There must be at least one author for this add-on."
+
+#. %1$s is a file extension. Example: .exe
+#. %2$s is a comma separated list of extensions. Example: .xpi, .jar
+#: controllers/components/developers.php:1081
+#, fuzzy, php-format
+msgid "devcp_error_preview_extension"
+msgstr ""
+"That file extension (%s) is not allowed for a preview. Please use one of the "
+"following: %s"
+
+#: controllers/components/developers.php:511
+#, fuzzy
+msgid "devcp_error_updatekey"
+msgstr ""
+"Add-ons cannot use an updateKey. Please remove this from install.rdf and try "
+"again."
+
+#: controllers/components/developers.php:506
+#, fuzzy
+msgid "devcp_error_updateurl"
+msgstr ""
+"Add-ons cannot use an external updateURL. Please remove this from install."
+"rdf and try again."
+
+#: controllers/developers_controller.php:465
+#: controllers/components/developers.php:271
+#, fuzzy
+msgid "devcp_error_upload_file"
+msgstr "Please upload a file."
+
+#: views/developers/uploader.thtml:135
+#, fuzzy
+msgid "devcp_input_upload_file"
+msgstr "Upload File"
+
+#: views/pages/js_constants.js.thtml:89
+#, fuzzy
+msgid "devcp_js_a_cancel"
+msgstr "Cancel"
+
+#: views/pages/js_constants.js.thtml:90
+#, fuzzy
+msgid "devcp_js_add_email"
+msgstr "Please enter the account email of the author you wish to add."
+
+#. alt text for a down-arrow image.
+#: views/pages/js_constants.js.thtml:81
+#, fuzzy
+msgid "devcp_js_img_move_down"
+msgstr "Move Down"
+
+#. alt text for an up-arrow image.
+#: views/pages/js_constants.js.thtml:82
+#, fuzzy
+msgid "devcp_js_img_move_up"
+msgstr "Move Up"
+
+#: views/pages/js_constants.js.thtml:91
+#, fuzzy
+msgid "devcp_js_img_remove_compat"
+msgstr "Remove Application Compatibility"
+
+#: views/pages/js_constants.js.thtml:86
+#, fuzzy
+msgid "devcp_js_input_list_author"
+msgstr "List as author in public listings"
+
+#: views/pages/js_constants.js.thtml:92
+#, fuzzy
+msgid "devcp_js_license_select"
+msgstr "Please select a license."
+
+#: views/pages/js_constants.js.thtml:93
+#, fuzzy
+msgid "devcp_js_license_text"
+msgstr "Please enter text for your license."
+
+#. <option> text in a <select> for Author role in an add-on.
+#: views/pages/js_constants.js.thtml:84
+#, fuzzy
+msgid "devcp_js_option_developer"
+msgstr "Developer"
+
+#. <option> text in a <select> for Author role in an add-on.
+#: views/pages/js_constants.js.thtml:83
+#, fuzzy
+msgid "devcp_js_option_owner"
+msgstr "Owner"
+
+#. <option> text in a <select> for Author role in an add-on.
+#: views/pages/js_constants.js.thtml:85
+#, fuzzy
+msgid "devcp_js_option_viewer"
+msgstr "Viewer"
+
+#: views/pages/js_constants.js.thtml:88
+#, fuzzy
+msgid "devcp_js_remove_author"
+msgstr "Remove Author"
+
+#: views/pages/js_constants.js.thtml:87
+#, fuzzy
+msgid "devcp_js_sure_remove"
+msgstr "Are you <strong>sure</strong> you wish to remove this author?"
+
+#: views/pages/js_constants.js.thtml:77
+#, fuzzy
+msgid "devcp_js_upload_alert"
+msgstr "You must select a file to upload."
+
+#. %1$s is an addon id, like 32.
+#. %2$s is a version number, like 3.5.
+#: controllers/components/developers.php:1212
+#, fuzzy
+msgid "devcp_license_existing"
+msgstr "Custom license for add-on %1$s v%2$s"
+
+#: views/elements/developers/localebox.thtml:44
+#, fuzzy
+msgid "devcp_localebox_header_localizedfields"
+msgstr "Localized Fields"
+
+#. %1 is the default locale
+#: views/elements/developers/localebox.thtml:48
+#, fuzzy, php-format
+msgid "devcp_localebox_intro"
+msgstr ""
+"Some of the fields on this page are localized to appear in the end-user's "
+"native language. Select a locale below to edit your add-on's details in that "
+"language. If a translation for a locale is not available, it will fall back "
+"to the selected default locale (%s)."
+
+#: views/elements/developers/sidebar.thtml:68
+#: views/elements/developers/myaddons.thtml:75
+#, fuzzy
+msgid "devcp_myaddons_admincp_link"
+msgstr "Admin Tools"
+
+#: views/elements/developers/sidebar.thtml:65
+#: views/elements/developers/myaddons.thtml:72
+#, fuzzy
+msgid "devcp_myaddons_editorcp_link"
+msgstr "Editor Tools"
+
+#: views/elements/developers/myaddons.thtml:52
+#, fuzzy
+msgid "devcp_myaddons_link"
+msgstr "My Add-ons"
+
+#: views/elements/developers/sidebar.thtml:70
+#: views/elements/developers/myaddons.thtml:77
+#, fuzzy
+msgid "devcp_myaddons_mainpage_link"
+msgstr "Back to Main"
+
+#: views/elements/developers/sidebar.thtml:63
+#: views/elements/developers/myaddons.thtml:70
+#, fuzzy
+msgid "devcp_myaddons_statistics_link"
+msgstr "Statistics Dashboard"
+
+#: views/elements/developers/sidebar.thtml:62
+#: views/elements/developers/myaddons.thtml:69
+#, fuzzy
+msgid "devcp_myaddons_submitaddon_link"
+msgstr "Submit Add-on"
+
+#: views/elements/developers/sidebar.thtml:48
+#: views/elements/developers/myaddons.thtml:67
+#, fuzzy
+msgid "devcp_myaddons_title"
+msgstr "Developer Tools"
+
+#. %1$s is an add-on ID, perhaps 167.
+#. %2$s is a URL.
+#: controllers/developers_controller.php:256
+#, fuzzy
+msgid "devcp_new_addon_error"
+msgstr ""
+"This add-on ID (%1$s) already exists in the database. If this is your add-"
+"on, you can <a href=\"%2$s\">upload a new version</a>."
+
+#: views/developers/addon_status_nominate.thtml:62
+#, fuzzy
+msgid "devcp_nominate_cancel"
+msgstr "Cancel and return"
+
+#. %1 is the add-on name
+#: views/developers/addon_status_nominate.thtml:61
+#, fuzzy, php-format
+msgid "devcp_nominate_submit_nominate"
+msgstr "Nominate %s"
+
+#: views/developers/addon_edit_properties.thtml:50
+#: views/developers/addon_status.thtml:49
+#: views/developers/versions_edit.thtml:50
+#, fuzzy
+msgid "devcp_notice_changes_error"
+msgstr ""
+"<span>One or more of your changes couldn't be saved.</span><br />Please look "
+"for the errors below. The rest of your changes were successfully saved."
+
+#: views/developers/addon_edit_authors.thtml:47
+#: views/developers/addon_edit_properties.thtml:47
+#: views/developers/addon_status.thtml:46
+#: views/developers/addon_edit_descriptions.thtml:47
+#: views/developers/versions_edit.thtml:47
+#: views/developers/addon_edit_categories.thtml:46
+#, fuzzy
+msgid "devcp_notice_changes_saved"
+msgstr ""
+"<span>Your changes have been saved.</span><br />Please note that some "
+"changes may take several hours to appear in all areas of the website."
+
+#: controllers/previews_controller.php:252
+#, fuzzy
+msgid "devcp_notice_cleardefault"
+msgstr ""
+"Removing this as the default preview will cause another preview to "
+"automatically become the default preview."
+
+#: controllers/previews_controller.php:184
+#: controllers/previews_controller.php:251
+#, fuzzy
+msgid "devcp_notice_makedefault"
+msgstr ""
+"Making this the default preview will remove default status from the current "
+"default preview."
+
+#: views/developers/addon_edit_authors.thtml:70
+#, fuzzy
+msgid "devcp_notice_unsaved_changes"
+msgstr "You have unsaved changes."
+
+#: controllers/developers_controller.php:87
+#: controllers/developers_controller.php:97
+#: controllers/developers_controller.php:100
+#: controllers/previews_controller.php:67
+#: controllers/previews_controller.php:79
+#: controllers/previews_controller.php:82
+#, fuzzy
+msgid "devcp_pagetitle"
+msgstr "Developer Tools"
+
+#: controllers/previews_controller.php:103
+#: controllers/previews_controller.php:104
+#, fuzzy
+msgid "devcp_preview_add_pagetitle"
+msgstr "Add Preview"
+
+#: controllers/previews_controller.php:135
+#, fuzzy
+msgid "devcp_preview_added_successfully"
+msgstr "Preview added successfully."
+
+#: controllers/previews_controller.php:323
+#, fuzzy
+msgid "devcp_preview_deleted_successfully"
+msgstr "Preview deleted successfully."
+
+#: controllers/previews_controller.php:194
+#: controllers/previews_controller.php:195
+#, fuzzy
+msgid "devcp_preview_edit_pagetitle"
+msgstr "Edit Preview"
+
+#: controllers/previews_controller.php:237
+#, fuzzy
+msgid "devcp_preview_updated_successfully"
+msgstr "Preview updated successfully."
+
+#: views/developers/previews.thtml:120
+#, fuzzy
+msgid "devcp_previews_a_another"
+msgstr "Add Another Preview"
+
+#: views/developers/previews.thtml:96
+#, fuzzy
+msgid "devcp_previews_a_delete"
+msgstr "Delete Preview"
+
+#: views/developers/previews.thtml:95
+#, fuzzy
+msgid "devcp_previews_a_replace"
+msgstr "Replace Preview"
+
+#: views/developers/previews.thtml:126
+#, fuzzy
+msgid "devcp_previews_a_update"
+msgstr "Update Previews"
+
+#: views/developers/previews.thtml:115 views/developers/previews.thtml:124
+#, fuzzy
+msgid "devcp_previews_add_new"
+msgstr "Add New Preview"
+
+#. %s is a list of file extensions, e.g. ".png, .gif"
+#: views/developers/previews.thtml:116
+#, fuzzy
+msgid "devcp_previews_add_select"
+msgstr ""
+"Select an image to upload below. Images larger than the maximum size of 700 "
+"pixels wide by 525 pixels tall will be resized. Allowed file types: %s"
+
+#: views/developers/previews.thtml:121
+#, fuzzy
+msgid "devcp_previews_click_below"
+msgstr "Click Update Previews below to upload."
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/previews.thtml:102
+#, fuzzy
+msgid "devcp_previews_click_update"
+msgstr ""
+"Click the Update Previews button below to save this image. (<a %s>Cancel?</"
+"a>)"
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/previews.thtml:107
+#, fuzzy
+msgid "devcp_previews_error_message"
+msgstr ""
+"This preview will be deleted when Update Previews is clicked below. (<a %"
+"s>Cancel?</a>)"
+
+#: views/previews/add.thtml:45
+#, fuzzy
+msgid "devcp_previews_filetype_info"
+msgstr ""
+"Use the form below to upload a PNG, JPG, or GIF screenshot of your add-on. "
+"Images larger than 700 pixels wide and 525 pixels high will automatically be "
+"resized."
+
+#: views/previews/add.thtml:43
+#, fuzzy
+msgid "devcp_previews_header_add"
+msgstr "Add Preview"
+
+#: views/developers/previews.thtml:80
+#, fuzzy
+msgid "devcp_previews_header_caption"
+msgstr "Preview Caption"
+
+#: views/previews/edit.thtml:43
+#, fuzzy
+msgid "devcp_previews_header_edit"
+msgstr "Edit Preview"
+
+#: views/developers/previews.thtml:93
+#, fuzzy
+msgid "devcp_previews_label_default"
+msgstr "Default Preview"
+
+#: views/previews/add.thtml:54
+#, fuzzy
+msgid "devcp_previews_label_file"
+msgstr "Preview File"
+
+#: views/previews/add.thtml:59 views/previews/edit.thtml:50
+#, fuzzy
+msgid "devcp_previews_label_makedefault"
+msgstr "Make this the default preview image"
+
+#: views/developers/previews.thtml:100
+#, fuzzy
+msgid "devcp_previews_label_new"
+msgstr "New image:"
+
+#: views/developers/previews.thtml:118
+#, fuzzy
+msgid "devcp_previews_label_upload"
+msgstr "Upload Preview: "
+
+#: views/developers/previews.thtml:50
+#, fuzzy
+msgid "devcp_previews_notice_error"
+msgstr "One or more of your new previews could not be saved."
+
+#: views/developers/previews.thtml:47
+#, fuzzy
+msgid "devcp_previews_notice_success"
+msgstr "Your previews have been updated successfully."
+
+#: views/developers/previews.thtml:59
+#, fuzzy
+msgid "devcp_previews_p_screenshots"
+msgstr ""
+"The preview screenshots for your add-on are shown below. You can make "
+"changes to captions or images below. The Default Preview is the preview that "
+"is displayed next to your add-on in search and browse listings."
+
+#: views/previews/edit.thtml:55
+#, fuzzy
+msgid "devcp_previews_submit_delete"
+msgstr "Delete Preview"
+
+#: views/previews/edit.thtml:55
+#, fuzzy
+msgid "devcp_previews_submit_delete_confirm"
+msgstr "Are you sure you wish to delete this preview?"
+
+#: views/previews/edit.thtml:54
+#, fuzzy
+msgid "devcp_previews_submit_edit"
+msgstr "Edit Preview"
+
+#: views/previews/add.thtml:63
+#, fuzzy
+msgid "devcp_previews_submit_upload"
+msgstr "Upload Preview"
+
+#: views/developers/previews.thtml:78
+#, fuzzy
+msgid "devcp_previews_thumbnail"
+msgstr "Thumbnail"
+
+#. %s is the add-on name.
+#: views/developers/previews.thtml:44
+#, fuzzy
+msgid "devcp_previews_title"
+msgstr "%s Preview Manager"
+
+#: views/developers/uploader.thtml:74
+#, fuzzy
+msgid "devcp_review_agreement_please"
+msgstr ""
+"Please review and accept the following Developer Agreement before proceeding."
+
+#: views/elements/developers/rolecheck.thtml:42
+#, fuzzy
+msgid "devcp_rolecheck_no_privs"
+msgstr ""
+"<span>You do not have sufficient privileges to make changes on this page.</"
+"span><br />Contact the Add-on Owner if you need to make changes."
+
+#: controllers/developers_controller.php:1315
+#, fuzzy
+msgid "devcp_several_hours"
+msgstr ""
+"Please note that some changes may take several hours to appear in all areas "
+"of the website."
+
+#: views/elements/developers/sidebar.thtml:52
+#, fuzzy
+msgid "devcp_sidebar_a_dashboard"
+msgstr "Dashboard"
+
+#. %s is a number
+#: views/elements/developers/statsbar.thtml:45
+#: views/developers/dashboard.thtml:79
+#, fuzzy, php-format
+msgid "devcp_statsbar_adu"
+msgstr "<em>%s</em> Active Daily Users"
+
+#. %s is a number
+#: views/elements/developers/statsbar.thtml:41
+#: views/developers/dashboard.thtml:75
+#, fuzzy, php-format
+msgid "devcp_statsbar_total_downloads"
+msgstr "<em>%s</em> Total Downloads"
+
+#. %s is a number
+#: views/elements/developers/statsbar.thtml:43
+#: views/developers/dashboard.thtml:77
+#, fuzzy, php-format
+msgid "devcp_statsbar_weekly_downloads"
+msgstr "<em>%s</em> Weekly Downloads"
+
+#: views/developers/addon_status_confirm.thtml:59
+#, fuzzy
+msgid "devcp_status_confirm_active"
+msgstr ""
+"Marking this add-on active will cause it to show up in public areas "
+"appropriate for its status, including search and browse listings. It will be "
+"downloadable from the website and could be returned in client update checks, "
+"depending on its status. You will be able to return here and disable it "
+"again at your convenience."
+
+#: views/developers/addon_status_confirm.thtml:59
+#, fuzzy
+msgid "devcp_status_confirm_active_sure"
+msgstr "Are you sure you wish to mark this add-on active?"
+
+#: views/developers/addon_status_confirm.thtml:50
+#, fuzzy
+msgid "devcp_status_confirm_header_sure"
+msgstr "Are you sure?"
+
+#: views/developers/addon_status_confirm.thtml:55
+#, fuzzy
+msgid "devcp_status_confirm_inactive"
+msgstr ""
+"Marking this add-on inactive will prevent it from showing up in any public "
+"areas, including search and browse listings. It will not be downloadable "
+"from the website and will not be returned in client update checks. You will "
+"be able to return here and re-enable it at your convenience."
+
+#: views/developers/addon_status_confirm.thtml:55
+#, fuzzy
+msgid "devcp_status_confirm_inactive_sure"
+msgstr "Are you sure you wish to mark this add-on inactive?'"
+
+#: views/developers/addon_status_confirm.thtml:74
+#, fuzzy
+msgid "devcp_status_confirm_no"
+msgstr "No, cancel"
+
+#: views/developers/addon_status_confirm.thtml:67
+#, fuzzy
+msgid "devcp_status_confirm_public"
+msgstr ""
+"Making this add-on public will make it available for anyone to download and "
+"will begin offering updates to existing users."
+
+#: views/developers/addon_status_confirm.thtml:67
+#, fuzzy
+msgid "devcp_status_confirm_public_sure"
+msgstr "Are you sure you wish to make this add-on public?"
+
+#: views/developers/addon_status_confirm.thtml:63
+#, fuzzy
+msgid "devcp_status_confirm_sandbox"
+msgstr ""
+"Moving this add-on back to the sandbox will require users to login before "
+"downloading and updates will no longer be offered to existing users. Because "
+"your add-on is currently public, you will be able to return here at any time "
+"to make it public again."
+
+#: views/developers/addon_status_confirm.thtml:63
+#, fuzzy
+msgid "devcp_status_confirm_sandbox_sure"
+msgstr "Are you sure you wish to move this add-on to the sandbox?"
+
+#: views/developers/addon_status_confirm.thtml:73
+#, fuzzy
+msgid "devcp_status_confirm_yes"
+msgstr "Yes, I'm Sure"
+
+#: views/developers/addon_status_nominate.thtml:46
+#, fuzzy
+msgid "devcp_status_nominate_error_notice"
+msgstr ""
+"<span>A nomination message is required.</span><br />Please fill in the text "
+"box with the requested information and try again."
+
+#: views/developers/addon_status_nominate.thtml:55
+#, fuzzy
+msgid "devcp_status_nominate_header"
+msgstr "Add-on Nomination"
+
+#: views/developers/dashboard.thtml:85
+#, fuzzy
+msgid "devcp_summary_lastversion"
+msgstr "Latest Version:"
+
+#. %s is the add-on name.
+#: views/developers/addon_edit.thtml:43
+#: views/developers/addon_edit_authors.thtml:44
+#: views/developers/versions_delete.thtml:43
+#: views/developers/addon_edit_properties.thtml:44
+#: views/developers/addon_edit_descriptions.thtml:44
+#: views/developers/versions_edit.thtml:44
+#: views/developers/addon_edit_categories.thtml:43
+#: views/developers/versions.thtml:43
+#, fuzzy
+msgid "devcp_title_edit_addon"
+msgstr "Edit %s"
+
+#. title attribute for a javascript link that pops up a help dialog.
+#: views/elements/translationbox.thtml:68
+#, fuzzy
+msgid "devcp_transbox_a_title_help"
+msgstr "Help (does not leave page)"
+
+#: views/elements/translationbox.thtml:68
+#, fuzzy
+msgid "devcp_transbox_alt_help"
+msgstr "Help"
+
+#. %1$s is <span>17</span>, %2$s is 42.
+#: views/elements/translationbox.thtml:101
+#, fuzzy
+msgid "devcp_transbox_chars_used"
+msgstr "Characters used: %1$s / %2$s"
+
+#: views/elements/translationbox.thtml:132
+#, fuzzy
+msgid "devcp_transbox_delete_sure"
+msgstr "Are you sure you wish to delete this translation?"
+
+#. %s is a locale, like en-US.
+#: views/elements/translationbox.thtml:143
+#, fuzzy
+msgid "devcp_transbox_help_header_tabs"
+msgstr "What are these %s tabs?"
+
+#: views/elements/translationbox.thtml:145
+#, fuzzy
+msgid "devcp_transbox_help_header_what"
+msgstr "What if I don't have any translations?"
+
+#: views/elements/translationbox.thtml:147
+#, fuzzy
+msgid "devcp_transbox_help_hide"
+msgstr "Hide Help"
+
+#: views/elements/translationbox.thtml:146
+#, fuzzy
+msgid "devcp_transbox_help_if"
+msgstr ""
+"If a user browses the site and a translation isn't available in their own "
+"language, it will fall back to your add-on's Default Locale, specified in "
+"the Edit Add-on Properties area. If you don't have any translations, just "
+"enter what you can into your Default Locale, which should be a language you "
+"speak."
+
+#: views/elements/translationbox.thtml:144
+#, fuzzy
+msgid "devcp_transbox_help_transbox"
+msgstr ""
+"This is a <i>Translation Box</i>. It allows you to localize a specific field "
+"into any other languages for which you might have a translation. You can "
+"add, edit, and remove translations using the locale tabs."
+
+#: views/elements/translationbox.thtml:85
+#, fuzzy
+msgid "devcp_transbox_img_add_trans"
+msgstr "Add Translation"
+
+#: views/elements/translationbox.thtml:86
+#, fuzzy
+msgid "devcp_transbox_img_remove_trans"
+msgstr "Remove Translation"
+
+#: views/elements/translationbox.thtml:123
+#, fuzzy
+msgid "devcp_transbox_input_add_all"
+msgstr "Add Locale to All"
+
+#: views/elements/translationbox.thtml:122
+#, fuzzy
+msgid "devcp_transbox_input_add_locale"
+msgstr "Add Locale"
+
+#: views/elements/translationbox.thtml:124
+#: views/elements/translationbox.thtml:135
+#, fuzzy
+msgid "devcp_transbox_input_cancel"
+msgstr "Cancel"
+
+#: views/elements/translationbox.thtml:134
+#, fuzzy
+msgid "devcp_transbox_input_delete"
+msgstr "Delete It"
+
+#: views/elements/translationbox.thtml:113
+#, fuzzy
+msgid "devcp_transbox_select_locale"
+msgstr "Select the locale of the translation to add:"
+
+#. %1$s and %2$s are GUIDs.
+#: controllers/developers_controller.php:343
+#, fuzzy
+msgid "devcp_update_addon_guid_error"
+msgstr ""
+"The add-on GUID used in this file (%1$s) does not match the existing GUID "
+"for this add-on (%2$s)."
+
+#: controllers/developers_controller.php:334
+#, fuzzy
+msgid "devcp_update_addon_priv_error"
+msgstr "You do not have sufficient privileges to update this add-on."
+
+#. %1$s is a version number, %2$s is an add-on ID.
+#: controllers/developers_controller.php:399
+#, fuzzy
+msgid "devcp_update_addon_version_belong_error"
+msgstr "The specified version (%1$s) does not belong to this add-on (%2$s)."
+
+#. %1$s is a version number, maybe 1.1.
+#. %2$s is a URL.
+#: controllers/developers_controller.php:351
+#, fuzzy
+msgid "devcp_update_addon_version_exists_error"
+msgstr ""
+"The version number uploaded (%1$s) already exists for this add-on. If you "
+"are trying to add another file to this version, <a href=\"%2$s\">click here</"
+"a>."
+
+#. %1$s and %2$s are version numbers.
+#: controllers/developers_controller.php:405
+#, fuzzy
+msgid "devcp_update_addon_version_match_error"
+msgstr ""
+"The uploaded version number (%1$s) does not match the existing version "
+"number (%2$s)."
+
+#: views/developers/uploader.thtml:68
+#, fuzzy
+msgid "devcp_uploader_a_start"
+msgstr "Get Started"
+
+#: views/developers/uploader.thtml:137
+#, fuzzy
+msgid "devcp_uploader_ajax_loading"
+msgstr "Uploading file..."
+
+#: views/developers/uploader.thtml:82
+#, fuzzy
+msgid "devcp_uploader_button_agree"
+msgstr "Agree and continue"
+
+#: views/developers/uploader.thtml:157
+#, fuzzy
+msgid "devcp_uploader_button_edit"
+msgstr "Edit My Add-on"
+
+#: views/developers/uploader.thtml:158
+#, fuzzy
+msgid "devcp_uploader_button_later"
+msgstr "I'll complete my add-on later."
+
+#: views/developers/uploader.thtml:168
+#, fuzzy
+msgid "devcp_uploader_button_release"
+msgstr "Add Release Notes"
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/uploader.thtml:156
+#, fuzzy
+msgid "devcp_uploader_created_results"
+msgstr ""
+"<p>Your add-on listing has been successfully created. The basic information "
+"obtained from your uploaded file has been stored, but there's a lot more to "
+"your listing that can be customized.</p><p>Your add-on is currently marked "
+"as <strong>Incomplete</strong>. In order to complete your add-on, you'll "
+"need to make sure it has an accurate name, summary, and description, as well "
+"as at least one selected category. You can edit your add-on's information "
+"using the link below and check the status of your add-on at any time on the "
+"<a %s>status page</a>."
+
+#: views/developers/uploader.thtml:143
+#, fuzzy
+msgid "devcp_uploader_error_correct"
+msgstr "Please correct this problem and upload your file again."
+
+#. %1$s is a version number, %2$s is a status, e.g Public or Incomplete.
+#: views/developers/uploader.thtml:175
+#, fuzzy
+msgid "devcp_uploader_file_created"
+msgstr ""
+"Your new file has been added to version %1$s and is currently marked as %2$s."
+
+#: views/developers/uploader.thtml:154
+#, fuzzy
+msgid "devcp_uploader_header_created"
+msgstr "Add-on Created!"
+
+#: views/developers/uploader.thtml:141
+#, fuzzy
+msgid "devcp_uploader_header_error"
+msgstr "Oops! There seems to be a problem with this file..."
+
+#: views/developers/uploader.thtml:173
+#, fuzzy
+msgid "devcp_uploader_header_file_added"
+msgstr "File Added!"
+
+#: views/developers/uploader.thtml:66
+#, fuzzy
+msgid "devcp_uploader_header_how"
+msgstr "How does it all work?"
+
+#. %s is the version number, e.g. 3.2.
+#: views/developers/uploader.thtml:163
+#, fuzzy
+msgid "devcp_uploader_header_update_created"
+msgstr "Version %s Created"
+
+#: views/developers/uploader.thtml:117
+#, fuzzy
+msgid "devcp_uploader_header_upload"
+msgstr "Upload Your File"
+
+#: views/developers/uploader.thtml:67
+#, fuzzy
+msgid "devcp_uploader_how"
+msgstr ""
+"<p>Thanks for your interest in submitting your add-on to Mozilla Add-ons. "
+"Hosting your add-on on Mozilla Add-ons is the easiest way to handle "
+"distribution of your add-on. Here's what you'll get:</p><ul><li>Each add-on "
+"will have a public display page with information you provide, such as a "
+"brief summary of the add-on's functionality, an optional longer description, "
+"and a showcase of preview screenshots of your add-on.</li><li>Your add-on "
+"will appear in search and browse listings across the site, and even in the "
+"Add-ons Manager of Firefox 3.</li><li>We'll take care of hosting all of your "
+"downloads and providing automatic updates to users when you upload a new "
+"version.</li><li>You'll have access to a statistics dashboard with detailed "
+"information about your user base.</li></ul><p>Add-ons hosted on the site "
+"must be reviewed by a Mozilla Add-ons Editor before they will have all of "
+"the features listed above. If you're ready to start the process and have "
+"your add-on package ready for upload, just click on Get Started below!</p>"
+
+#: views/developers/uploader.thtml:125
+#, fuzzy
+msgid "devcp_uploader_label_platformtype"
+msgstr "Supported Platforms:"
+
+#: views/developers/uploader.thtml:124
+#, fuzzy
+msgid "devcp_uploader_label_upload_field"
+msgstr "Add-on File: "
+
+#: controllers/components/developers.php:1221
+#, fuzzy
+msgid "devcp_uploader_option_other"
+msgstr "Other"
+
+#. %1$s is a number, %2$s is href="..." and should stay in the <a> tag.
+#: views/developers/uploader.thtml:176
+#, fuzzy
+msgid "devcp_uploader_p_pending_file"
+msgstr ""
+"The new file will be available to the public as soon as an editor is able to "
+"review it. There are currently %1$s other add-ons in the queue. Want to be "
+"reviewed faster? Consider <a %2$s>becoming an editor</a>."
+
+#. %1$s is a number, %2$s is href="..." and should stay in the <a> tag.
+#: views/developers/uploader.thtml:166
+#, fuzzy
+msgid "devcp_uploader_p_pending_version"
+msgstr ""
+"The new version will be available to the public as soon as an editor is able "
+"to review it. There are currently %1$s other add-ons in the queue. Want to "
+"be reviewed faster? Consider <a %2$s>becoming an editor</a>."
+
+#. %s is a status, e.g Public or Incomplete.
+#: views/developers/uploader.thtml:165
+#, fuzzy
+msgid "devcp_uploader_p_update_created"
+msgstr "Your new version has been created and is currently marked as %s."
+
+#. %1$s is href="..." and should stay in the 'Versions and Files' <a> tag.
+#. %2$s is href="..." and should stay in the 'current status' <a> tag.
+#: views/developers/uploader.thtml:177
+#, fuzzy
+msgid "devcp_uploader_p_update_file"
+msgstr ""
+"View your new file in the <a %1$s>Versions and Files page</a>, check out "
+"your add-on's <a %2$s>current status</a>, or <b>add release notes</b> by "
+"clicking the button below (highly recommended)."
+
+#. %1$s is href="..." and should stay in the 'Versions and Files' <a> tag.
+#. %2$s is href="..." and should stay in the 'current status' <a> tag.
+#: views/developers/uploader.thtml:167
+#, fuzzy
+msgid "devcp_uploader_p_update_version"
+msgstr ""
+"View your new version in the <a %1$s>Versions and Files page</a>, check out "
+"your add-on's <a %2$s>current status</a>, or <b>add release notes</b> by "
+"clicking the button below (highly recommended)."
+
+#: views/developers/uploader.thtml:118
+#, fuzzy
+msgid "devcp_uploader_p_upload"
+msgstr ""
+"Upload your add-on file using the form below. If you have multiple, platform-"
+"specific files to upload, choose a single file and then upload the others "
+"using the Versions and Files Manager."
+
+#: views/developers/uploader.thtml:125
+#, fuzzy
+msgid "devcp_uploader_platformtype_all"
+msgstr "All"
+
+#: views/developers/uploader.thtml:126
+#, fuzzy
+msgid "devcp_uploader_platformtype_specific"
+msgstr "Specific:"
+
+#. Used as first item in a <select>.
+#: controllers/components/developers.php:1185
+#, fuzzy
+msgid "devcp_uploader_please_choose"
+msgstr "Please Choose..."
+
+#. %1$s is the add-on name, %2$s is the version number.
+#: views/developers/uploader.thtml:57
+#, fuzzy
+msgid "devcp_uploader_title_file"
+msgstr "Add File to %1$s %2$s"
+
+#: views/developers/uploader.thtml:50
+#, fuzzy
+msgid "devcp_uploader_title_submit"
+msgstr "Submit New Add-on"
+
+#. %s is the add-on name.
+#: views/developers/uploader.thtml:54
+#, fuzzy
+msgid "devcp_uploader_title_update"
+msgstr "Update %s"
+
+#. %s is a full <a> tag
+#: controllers/developers_controller.php:503
+#, fuzzy, php-format
+msgid "devcp_valid_app_reference"
+msgstr "Please see %s for reference."
+
+#. This is the text in the <a> tag for devcp_valid_app_reference. This should be
+#. fixed.
+#: controllers/developers_controller.php:503
+#, fuzzy
+msgid "devcp_valid_app_reference_linktext"
+msgstr "this page"
+
+#: controllers/developers_controller.php:581
+#, fuzzy
+msgid "devcp_verify_author_error"
+msgstr "No account found for that email address."
+
+#: controllers/developers_controller.php:553
+#, fuzzy
+msgid "devcp_verify_search_engine_error"
+msgstr ""
+"Either the XML is invalid or required fields are missing. Please <a href="
+"\"https://developer.mozilla.org/en/Creating_OpenSearch_plugins_for_Firefox"
+"\">read the documentation</a>, verify your add-on, and try again."
+
+#: views/developers/versions.thtml:75
+#, fuzzy
+msgid "devcp_versions_a_cancel"
+msgstr "Cancel"
+
+#: views/developers/versions.thtml:79
+#, fuzzy
+msgid "devcp_versions_a_delete"
+msgstr "Delete Version"
+
+#: views/developers/versions.thtml:74
+#, fuzzy
+msgid "devcp_versions_a_empty"
+msgstr "Remove Empty Version"
+
+#: views/developers/versions.thtml:71
+#, fuzzy
+msgid "devcp_versions_a_remove"
+msgstr "Remove?"
+
+#: views/developers/versions.thtml:91
+#, fuzzy
+msgid "devcp_versions_add"
+msgstr "Add New Version"
+
+#: views/developers/versions_delete.thtml:58
+#, fuzzy
+msgid "devcp_versions_delete_a_cancel"
+msgstr "Cancel"
+
+#: views/developers/versions_delete.thtml:56
+#, fuzzy
+msgid "devcp_versions_delete_a_delete"
+msgstr "Delete Version"
+
+#. Followed by a list of reviews and files that will be removed.
+#: views/developers/versions_delete.thtml:50
+#, fuzzy
+msgid "devcp_versions_delete_also"
+msgstr "This will also delete:"
+
+#: views/developers/versions_delete.thtml:53
+#, fuzzy
+msgid "devcp_versions_delete_files"
+msgid_plural "devcp_versions_delete_files"
+msgstr[0] "%s file"
+msgstr[1] "%s files"
+
+#. %s is the version number.
+#: views/developers/versions_delete.thtml:48
+#, fuzzy
+msgid "devcp_versions_delete_header"
+msgstr "Delete Version %s?"
+
+#: views/developers/versions_delete.thtml:52
+#, fuzzy
+msgid "devcp_versions_delete_reviews"
+msgid_plural "devcp_versions_delete_reviews"
+msgstr[0] "%s review"
+msgstr[1] "%s reviews"
+
+#. %s is the version number.
+#: views/developers/versions_delete.thtml:49
+#, fuzzy
+msgid "devcp_versions_delete_sure"
+msgstr "Are you sure you want to permanently delete version %s?"
+
+#: views/developers/versions_edit.thtml:102
+#: views/developers/versions_edit.thtml:155
+#, fuzzy
+msgid "devcp_versions_edit_a_cancel"
+msgstr "Cancel"
+
+#: views/developers/versions_edit.thtml:101
+#, fuzzy
+msgid "devcp_versions_edit_a_delete"
+msgstr "Delete File"
+
+#: views/developers/versions_edit.thtml:165
+#, fuzzy
+msgid "devcp_versions_edit_a_new_app"
+msgstr "Add New Application"
+
+#: views/developers/versions_edit.thtml:154
+#, fuzzy
+msgid "devcp_versions_edit_a_remove_app"
+msgstr "Remove Application"
+
+#: views/developers/versions_edit.thtml:114
+#, fuzzy
+msgid "devcp_versions_edit_add"
+msgstr "Add New File"
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/versions_edit.thtml:121
+#, fuzzy
+msgid "devcp_versions_edit_adjust"
+msgstr ""
+"Adjusting application information here will allow users to install your add-"
+"on even if the install.rdf in the package indicates that the add-on is "
+"incompatible. <a %s>List of supported applications</a>"
+
+#: views/developers/versions_edit.thtml:153
+#, fuzzy
+msgid "devcp_versions_edit_compat_sure"
+msgstr ""
+"Are you <b>sure</b> you wish to remove compatibility with this application?"
+
+#: views/developers/versions_edit.thtml:100
+#, fuzzy
+msgid "devcp_versions_edit_delete_sure"
+msgstr "Are you <b>sure</b> you wish to permanently delete this file?"
+
+#: views/developers/versions_edit.thtml:203
+#, fuzzy
+msgid "devcp_versions_edit_header_approval"
+msgstr "Approval Information"
+
+#: views/developers/versions_edit.thtml:120
+#, fuzzy
+msgid "devcp_versions_edit_header_compat"
+msgstr "Compatible Applications"
+
+#: views/developers/versions_edit.thtml:74
+#, fuzzy
+msgid "devcp_versions_edit_header_file"
+msgstr "File Information"
+
+#: views/developers/versions_edit.thtml:189
+#, fuzzy
+msgid "devcp_versions_edit_header_license"
+msgstr "License"
+
+#. %s is the version number.
+#: views/developers/versions_edit.thtml:53
+#, fuzzy
+msgid "devcp_versions_edit_header_manage"
+msgstr "Manage Version %s"
+
+#: views/developers/versions_edit.thtml:212
+#, fuzzy
+msgid "devcp_versions_edit_header_notes"
+msgstr "Approval Notes"
+
+#: views/developers/versions_edit.thtml:98
+#, fuzzy
+msgid "devcp_versions_edit_img_delete"
+msgstr "Delete File"
+
+#. %1$s is the file id, e.g. 18723.
+#. %2$s is the platform name, e.g. ALL or Windows.
+#. %3$s is the _('date) created.
+#. %4$s is the status, e.g. "In Sandbox" or "Public".
+#. %5$s is the _('date') status was changed.
+#: views/developers/versions_edit.thtml:208
+#, fuzzy
+msgid "devcp_versions_edit_li_file"
+msgstr "File %1$s (%2$s) created on %3$s and changed to %4$s on %5$s"
+
+#: views/developers/versions_edit.thtml:190
+#, fuzzy
+msgid "devcp_versions_edit_license_description"
+msgstr ""
+"Please select the appropriate license for your add-on. This license "
+"specifies the rights you grant on your source code."
+
+#: views/developers/versions_edit.thtml:111
+#, fuzzy
+msgid "devcp_versions_edit_no_files"
+msgstr "No files found."
+
+#: views/developers/versions_edit.thtml:213
+#, fuzzy
+msgid "devcp_versions_edit_optional"
+msgstr "Optional information for the Editor that reviews this version."
+
+#: views/developers/versions_edit.thtml:151
+#, fuzzy
+msgid "devcp_versions_edit_remove_compat"
+msgstr "Remove Application Compatibility"
+
+#: views/developers/versions_edit.thtml:167
+#, fuzzy
+msgid "devcp_versions_edit_select_app"
+msgstr "Please Select an Application"
+
+#: views/developers/versions_edit.thtml:78
+#, fuzzy
+msgid "devcp_versions_edit_th_file"
+msgstr "File"
+
+#: views/developers/versions_edit.thtml:79
+#, fuzzy
+msgid "devcp_versions_edit_th_platform"
+msgstr "Platform"
+
+#: views/developers/versions_edit.thtml:80
+#, fuzzy
+msgid "devcp_versions_edit_th_size"
+msgstr "Size"
+
+#: views/developers/versions_edit.thtml:81
+#, fuzzy
+msgid "devcp_versions_edit_th_status"
+msgstr "Status"
+
+#: views/developers/versions_edit.thtml:183
+#, fuzzy
+msgid "devcp_versions_edit_transbox_releasenotes_description"
+msgstr ""
+"Information about changes in this release, new features, known bugs, and "
+"other useful information specific to this release/version. This information "
+"will also be available to users updating the add-on in the Firefox 3 Add-ons "
+"Manager interface."
+
+#: views/developers/versions_edit.thtml:182
+#, fuzzy
+msgid "devcp_versions_edit_transbox_releasenotes_name"
+msgstr "Release Notes"
+
+#: views/developers/versions_edit.thtml:164
+#, fuzzy
+msgid "devcp_versions_edit_unsaved_compat"
+msgstr ""
+"<strong>You have unsaved changes.</strong> Compatibility will not be deleted "
+"until you click Update Version below."
+
+#: views/developers/versions_edit.thtml:113
+#, fuzzy
+msgid "devcp_versions_edit_unsaved_files"
+msgstr ""
+"<strong>You have unsaved changes.</strong> Files will not be deleted until "
+"you click Update Version below."
+
+#: views/developers/versions_edit.thtml:218
+#, fuzzy
+msgid "devcp_versions_edit_update"
+msgstr "Update Versions"
+
+#: views/developers/versions.thtml:49
+#, fuzzy
+msgid "devcp_versions_header_manage"
+msgstr "Manage Versions and Files"
+
+#: views/developers/versions.thtml:87
+#, fuzzy
+msgid "devcp_versions_no_versions"
+msgstr "No versions."
+
+#. %s is a version number, base 10.
+#: views/developers/versions.thtml:46
+#, fuzzy
+msgid "devcp_versions_notice_success"
+msgstr "Version %s deleted successfully."
+
+#: views/developers/versions.thtml:73
+#, fuzzy
+msgid "devcp_versions_p_remove"
+msgstr ""
+"This version has no files associated with it and can be removed. Would you "
+"like to remove this version?"
+
+#: views/developers/versions.thtml:58
+#, fuzzy
+msgid "devcp_versions_th_created"
+msgstr "Created"
+
+#: views/developers/versions.thtml:57
+#, fuzzy
+msgid "devcp_versions_th_status"
+msgstr "Status"
+
+#: views/developers/versions.thtml:56
+#, fuzzy
+msgid "devcp_versions_th_version"
+msgstr "Version"
+
+#: controllers/downloads_controller.php:91
+#, fuzzy
+msgid "downloads_disable_warning"
+msgstr "This add-on is disabled"
+
+#: controllers/components/editors.php:57
+#, fuzzy
+msgid "editor_review_error_addon_not_nominated"
+msgstr "This add-on has not been nominated."
+
+#: controllers/components/editors.php:213
+#, fuzzy
+msgid "editor_review_error_file_not_pending"
+msgstr "This file is not pending review."
+
+#. Actions are, for example: approving or rejecting
+#: controllers/components/editors.php:79
+#: controllers/components/editors.php:182
+#, fuzzy
+msgid "editor_review_error_no_action"
+msgstr "Please select a review action."
+
+#: controllers/components/editors.php:192
+#, fuzzy
+msgid "editor_review_error_no_applications"
+msgstr "Please enter the applications you tested."
+
+#. Comments are required when an editor approves or rejects an add-on.
+#: controllers/components/editors.php:84
+#: controllers/components/editors.php:187
+#, fuzzy
+msgid "editor_review_error_no_comments"
+msgstr "Please enter review comments."
+
+#: controllers/components/editors.php:161
+#, fuzzy
+msgid "editor_review_error_no_files"
+msgstr "Please select at least one file to review."
+
+#: controllers/components/editors.php:197
+#, fuzzy
+msgid "editor_review_error_no_operating_system"
+msgstr "Please enter the operating systems you tested."
+
+#: views/editors/logs.thtml:51
+#, fuzzy
+msgid "editorcp_logs_button_filter"
+msgstr "Filter"
+
+#: views/editors/logs.thtml:44
+#, fuzzy
+msgid "editorcp_logs_filter_by"
+msgstr "Filter by type/action"
+
+#: views/editors/logs.thtml:42 controllers/editors_controller.php:964
+#, fuzzy
+msgid "editorcp_logs_page_heading"
+msgstr "Event Log"
+
+#: views/elements/developers/editorsmenu.thtml:60
+#, fuzzy
+msgid "editorcp_menu_eventlog_link"
+msgstr "Event Log"
+
+#: views/elements/developers/editorsmenu.thtml:62
+#, fuzzy
+msgid "editorcp_menu_mainpage_link"
+msgstr "Back to Main"
+
+#: views/elements/developers/editorsmenu.thtml:61
+#, fuzzy
+msgid "editorcp_menu_reviewlog_link"
+msgstr "Review Log"
+
+#: views/elements/developers/editorsmenu.thtml:55
+#, fuzzy
+msgid "editorcp_menu_summary_link"
+msgstr "Editor Summary"
+
+#: views/elements/developers/editorsmenu.thtml:52
+#, fuzzy
+msgid "editorcp_menu_title"
+msgstr "Editor Tools"
+
+#: views/editors/reviewlog.thtml:49
+#, fuzzy
+msgid "editorcp_reviewlog_button_filter"
+msgstr "Filter"
+
+#: views/editors/reviewlog.thtml:58
+#, fuzzy
+msgid "editorcp_reviewlog_column_action"
+msgstr "Action"
+
+#: views/editors/reviewlog.thtml:56
+#, fuzzy
+msgid "editorcp_reviewlog_column_addon"
+msgstr "Add-on"
+
+#: views/editors/reviewlog.thtml:55
+#, fuzzy
+msgid "editorcp_reviewlog_column_date"
+msgstr "Date"
+
+#: views/editors/reviewlog.thtml:57
+#, fuzzy
+msgid "editorcp_reviewlog_column_editor"
+msgstr "Editor"
+
+#: views/editors/reviewlog.thtml:94
+#, fuzzy
+msgid "editorcp_reviewlog_comments_hide"
+msgstr "Hide Comments"
+
+#: views/editors/reviewlog.thtml:93
+#, fuzzy
+msgid "editorcp_reviewlog_comments_show"
+msgstr "Show Comments"
+
+#. %1$s and %2$s are full <input> tags for dates
+#: views/editors/reviewlog.thtml:45
+#, fuzzy, php-format
+msgid "editorcp_reviewlog_entries_between"
+msgstr "View entries between %s and %s"
+
+#: views/editors/reviewlog.thtml:104
+#, fuzzy
+msgid "editorcp_reviewlog_none_found"
+msgstr "No reviews found for this period."
+
+#: views/editors/reviewlog.thtml:42
+#, fuzzy
+msgid "editorcp_reviewlog_page_heading"
+msgstr "Review Log"
+
+#: views/editors/summary.thtml:61
+#, fuzzy
+msgid "editorcp_summary_monthreviews_heading"
+msgstr "Month Reviews"
+
+#: views/editors/summary.thtml:77
+#, fuzzy
+msgid "editorcp_summary_neweditors_heading"
+msgstr "New Editors"
+
+#: views/editors/summary.thtml:42
+#, fuzzy
+msgid "editorcp_summary_page_heading"
+msgstr "Editor Summary"
+
+#: views/editors/summary.thtml:94
+#, fuzzy
+msgid "editorcp_summary_recentactivity_heading"
+msgstr "Recent Editor Activity"
+
+#: views/editors/summary.thtml:45
+#, fuzzy
+msgid "editorcp_summary_totalreviews_heading"
+msgstr "Total Reviews"
+
+#: controllers/editors_controller.php:248
+#: controllers/editors_controller.php:249
+#, fuzzy
+msgid "editors_addon_review_pagetitle"
+msgstr "Review Add-on"
+
+#: controllers/editors_controller.php:349
+#, fuzzy
+msgid "editors_error_js-formerror"
+msgstr "Please complete the following fields:"
+
+#: controllers/editors_controller.php:350
+#, fuzzy
+msgid "editors_error_review_one_file"
+msgstr "Please select at least one file to review."
+
+#: controllers/editors_controller.php:274
+#, fuzzy
+msgid "editors_error_self_reviews_forbidden"
+msgstr "Self-reviews are not allowed."
+
+#: controllers/editors_controller.php:699
+#, fuzzy
+msgid "editors_external_software"
+msgstr "External Software"
+
+#: views/editors/featured.thtml:120 views/editors/featured.thtml:121
+#, fuzzy
+msgid "editors_featured_add_feature"
+msgstr "Add feature"
+
+#: views/editors/featured.thtml:126
+#, fuzzy
+msgid "editors_featured_add_feature_submit"
+msgstr "Add"
+
+#: views/editors/featured.thtml:49 controllers/editors_controller.php:832
+#: controllers/editors_controller.php:848
+#, fuzzy
+msgid "editors_featured_addon_add_failure"
+msgstr "Failed to add feature."
+
+#: controllers/editors_controller.php:851
+#, fuzzy
+msgid "editors_featured_addon_add_success"
+msgstr "Successfully added feature."
+
+#: views/editors/featured.thtml:50 controllers/editors_controller.php:839
+#: controllers/editors_controller.php:868
+#: controllers/editors_controller.php:886
+#, fuzzy
+msgid "editors_featured_addon_edit_failure"
+msgstr "Failed to edit feature."
+
+#: views/editors/featured.thtml:51 controllers/editors_controller.php:888
+#, fuzzy
+msgid "editors_featured_addon_edit_success"
+msgstr "Successfully edited feature."
+
+#: views/editors/featured.thtml:53 controllers/editors_controller.php:861
+#, fuzzy
+msgid "editors_featured_addon_invalid_locale"
+msgstr "One or more locales are invalid."
+
+#: views/editors/featured.thtml:52 controllers/editors_controller.php:906
+#, fuzzy
+msgid "editors_featured_addon_remove_failure"
+msgstr "Failed to remove feature."
+
+#: controllers/editors_controller.php:901
+#, fuzzy
+msgid "editors_featured_addon_remove_success"
+msgstr "Successfully removed feature."
+
+#: controllers/editors_controller.php:915
+#: controllers/editors_controller.php:917
+#, fuzzy
+msgid "editors_featured_addons_pagetitle"
+msgstr "Featured Add-ons"
+
+#: views/editors/featured.thtml:54 views/editors/featured.thtml:107
+#, fuzzy
+msgid "editors_featured_edit_feature_submit"
+msgstr "Go"
+
+#: views/editors/featured.thtml:90 views/editors/featured.thtml:91
+#, fuzzy
+msgid "editors_featured_remove_feature"
+msgstr "Remove feature"
+
+#: views/editors/queue.thtml:46
+#, fuzzy
+msgid "editors_filter_queue"
+msgstr "Filter Queue"
+
+#: views/editors/queue.thtml:182
+#, fuzzy
+msgid "editors_helpful_links"
+msgstr "Helpful Links"
+
+#: views/editors/queue.thtml:182
+#, fuzzy
+msgid "editors_link_guide"
+msgstr "Editors' Guide"
+
+#: views/editors/queue.thtml:182
+#, fuzzy
+msgid "editors_link_policy"
+msgstr "Add-on Policy"
+
+#: views/editors/queue.thtml:47
+#, fuzzy
+msgid "editors_notice_filter_session"
+msgstr "These filters will remain in place for this session or until cleared."
+
+#. %1 is the queue mode
+#: views/editors/queue.thtml:177 views/admin/flagged_queue.thtml:89
+#, fuzzy
+msgid "editors_notice_none_found"
+msgstr "There are currently no add-ons of this type to review."
+
+#: controllers/editors_controller.php:1040
+#, fuzzy
+msgid "editors_one_day"
+msgstr "1 day"
+
+#: controllers/editors_controller.php:1048
+#, fuzzy
+msgid "editors_one_hour"
+msgstr "1 hour"
+
+#: controllers/editors_controller.php:1056
+#, fuzzy
+msgid "editors_one_minute"
+msgstr "1 minute"
+
+#: controllers/editors_controller.php:64 controllers/editors_controller.php:73
+#: controllers/editors_controller.php:77
+#, fuzzy
+msgid "editors_pagetitle"
+msgstr "Editor Tools"
+
+#. %s is a comma separated list of platforms. Example: Windows, OS X
+#: controllers/editors_controller.php:680
+#: controllers/editors_controller.php:683
+#, fuzzy, php-format
+msgid "editors_platform_x_only"
+msgstr "%s only"
+
+#: controllers/editors_controller.php:695
+#, fuzzy
+msgid "editors_pre-release"
+msgstr "Pre-release"
+
+#. %1 is the app name
+#: views/editors/queue.thtml:131
+#, fuzzy, php-format
+msgid "editors_queue_app_compatibility"
+msgstr "%s Compatibility"
+
+#: views/editors/queue.thtml:51
+#, fuzzy
+msgid "editors_queue_filter_label_addon"
+msgstr "Add-on or Author Email"
+
+#: views/editors/queue.thtml:72
+#, fuzzy
+msgid "editors_queue_filter_label_addontypes"
+msgstr "Add-on Types"
+
+#: views/editors/queue.thtml:56
+#, fuzzy
+msgid "editors_queue_filter_label_application"
+msgstr "Application"
+
+#: views/editors/queue.thtml:61
+#, fuzzy
+msgid "editors_queue_filter_label_maxversion"
+msgstr "Max. Version"
+
+#: views/editors/queue.thtml:78
+#, fuzzy
+msgid "editors_queue_filter_label_platforms"
+msgstr "Platforms"
+
+#: views/editors/queue.thtml:66
+#, fuzzy
+msgid "editors_queue_filter_label_submissionage"
+msgstr "Age of Submission (days)"
+
+#. %1$s is a number
+#: views/editors/queue.thtml:90
+#, fuzzy
+msgid "editors_queue_filter_result_count"
+msgid_plural "editors_queue_filter_result_count"
+msgstr[0] "Results of your filtered search: <strong>%1$s</strong> Add-on"
+msgstr[1] "Results of your filtered search: <strong>%1$s</strong> Add-ons"
+
+#: views/editors/queue.thtml:84
+#, fuzzy
+msgid "editors_queue_submit_clean"
+msgstr "Clear"
+
+#: views/editors/queue.thtml:83
+#, fuzzy
+msgid "editors_queue_submit_filter"
+msgstr "Filter"
+
+#: controllers/editors_controller.php:133
+#, fuzzy
+msgid "editors_queues_disabled"
+msgstr ""
+"All review queues are currently disabled. Please check back at a later time."
+
+#: views/editors/review.thtml:149
+#, fuzzy
+msgid "editors_review_a_edit_item"
+msgstr "Edit Item"
+
+#: views/editors/review.thtml:146
+#, fuzzy
+msgid "editors_review_a_item_history"
+msgstr "Item History"
+
+#: views/editors/review.thtml:148
+#, fuzzy
+msgid "editors_review_a_item_homepage"
+msgstr "Item Homepage"
+
+#: views/editors/review.thtml:145
+#, fuzzy
+msgid "editors_review_a_item_overview"
+msgstr "Item Overview"
+
+#: views/editors/review.thtml:147
+#, fuzzy
+msgid "editors_review_a_previews"
+msgstr "Previews"
+
+#: controllers/editors_controller.php:345
+#, fuzzy
+msgid "editors_review_action"
+msgstr "Review Action"
+
+#: views/editors/review.thtml:159
+#, fuzzy
+msgid "editors_review_action_info"
+msgstr "Request More Information"
+
+#: views/editors/review.thtml:157
+#, fuzzy
+msgid "editors_review_action_public"
+msgstr "Push to Public"
+
+#: views/editors/review.thtml:160
+#, fuzzy
+msgid "editors_review_action_request_superreview"
+msgstr "Request Super-Review"
+
+#: views/editors/review.thtml:158
+#, fuzzy
+msgid "editors_review_action_sandbox"
+msgstr "Retain in Sandbox"
+
+#: controllers/editors_controller.php:346
+#, fuzzy
+msgid "editors_review_comments"
+msgstr "Review Comments"
+
+#: views/editors/review.thtml:182
+#, fuzzy
+msgid "editors_review_details_info_request"
+msgstr ""
+"Use this form to request more information from the author. They will receive "
+"an email and be able to answer here. You will be notified by email when they "
+"reply."
+
+#: views/editors/review.thtml:174
+#, fuzzy
+msgid "editors_review_details_nominated_public"
+msgstr ""
+"This will mark the add-on and its most recent version and files as public. "
+"Future versions will go into the sandbox until they are reviewed by an "
+"editor."
+
+#: views/editors/review.thtml:177
+#, fuzzy
+msgid "editors_review_details_nominated_sandbox"
+msgstr "This will retain the add-on in the sandbox."
+
+#: views/editors/review.thtml:166
+#, fuzzy
+msgid "editors_review_details_pending_public"
+msgstr ""
+"This will approve a sandboxed version of a public add-on to appear on the "
+"public side."
+
+#: views/editors/review.thtml:169
+#, fuzzy
+msgid "editors_review_details_pending_sandbox"
+msgstr ""
+"This will cause a sandboxed version of a public add-on to remain in the "
+"sandbox."
+
+#: views/editors/review.thtml:185
+#, fuzzy
+msgid "editors_review_details_superreview"
+msgstr ""
+"If you have concerns about this add-on's security, copyright issues, or "
+"other concerns that an administrator should look into, enter your comments "
+"in the area below. They will be sent to administrators, not the author."
+
+#: views/editors/review.thtml:134
+#, fuzzy
+msgid "editors_review_file_diff_link"
+msgstr "Compare with public version"
+
+#: views/editors/review.thtml:131
+#, fuzzy
+msgid "editors_review_file_viewcontents_link"
+msgstr "View Contents"
+
+#: views/editors/review.thtml:65
+#, fuzzy
+msgid "editors_review_header_authors"
+msgstr "Authors:"
+
+#: views/editors/review.thtml:79
+#, fuzzy
+msgid "editors_review_header_categories"
+msgstr "Categories:"
+
+#: views/editors/review.thtml:92
+#, fuzzy
+msgid "editors_review_header_compatibility"
+msgstr "Compatibility:"
+
+#: views/editors/review.thtml:251
+#, fuzzy
+msgid "editors_review_header_description"
+msgstr "Description"
+
+#: views/editors/review.thtml:275
+#, fuzzy
+msgid "editors_review_header_devcomments"
+msgstr "Developer Comments"
+
+#: views/editors/review.thtml:263
+#, fuzzy
+msgid "editors_review_header_eula"
+msgstr "EULA"
+
+#: views/editors/review.thtml:115
+#, fuzzy
+msgid "editors_review_header_files"
+msgstr "Files:"
+
+#: views/editors/review.thtml:284
+#, fuzzy
+msgid "editors_review_header_itemhistory"
+msgstr "Item History"
+
+#: views/editors/review.thtml:232
+#, fuzzy
+msgid "editors_review_header_nominationmessage"
+msgstr "Nomination Message"
+
+#: views/editors/review.thtml:311
+#, fuzzy
+msgid "editors_review_header_previews"
+msgstr "Previews"
+
+#: views/editors/review.thtml:269
+#, fuzzy
+msgid "editors_review_header_privacy"
+msgstr "Privacy Policy"
+
+#. %1 is the add-on name and version
+#: views/editors/review.thtml:56
+#, fuzzy, php-format
+msgid "editors_review_header_review"
+msgstr "Review %s"
+
+#: views/editors/review.thtml:239
+#, fuzzy
+msgid "editors_review_header_reviewernotes"
+msgstr "Notes to Reviewer"
+
+#: views/editors/review.thtml:245
+#, fuzzy
+msgid "editors_review_header_summary"
+msgstr "Summary"
+
+#: views/editors/review.thtml:257
+#, fuzzy
+msgid "editors_review_header_versionnotes"
+msgstr "Version Notes"
+
+#. a noun: shown in an add-on's editor review history
+#: views/elements/developers/editors_review_history_item.thtml:80
+#, fuzzy
+msgid "editors_review_history_info_reply"
+msgstr "Reply"
+
+#: views/elements/developers/editors_review_history_item.thtml:78
+#, fuzzy
+msgid "editors_review_history_info_request"
+msgstr "Information Request"
+
+#: views/elements/developers/editors_review_history_item.thtml:62
+#: views/editors/reviewlog.thtml:77
+#, fuzzy
+msgid "editors_review_history_nominated_adminreview"
+msgstr "Admin Review"
+
+#: views/elements/developers/editors_review_history_item.thtml:56
+#: views/editors/reviewlog.thtml:71
+#, fuzzy
+msgid "editors_review_history_nominated_approved"
+msgstr "Nomination Approved/Public"
+
+#: views/elements/developers/editors_review_history_item.thtml:59
+#: views/editors/reviewlog.thtml:74
+#, fuzzy
+msgid "editors_review_history_nominated_denied"
+msgstr "Nomination Denied/Sandbox"
+
+#: views/editors/review.thtml:303
+#, fuzzy
+msgid "editors_review_history_nonefound"
+msgstr "No previous review entries could be found."
+
+#: views/elements/developers/editors_review_history_item.thtml:73
+#: views/editors/reviewlog.thtml:88
+#, fuzzy
+msgid "editors_review_history_pending_adminreview"
+msgstr "Admin Review"
+
+#: views/elements/developers/editors_review_history_item.thtml:67
+#: views/editors/reviewlog.thtml:82
+#, fuzzy
+msgid "editors_review_history_pending_approved"
+msgstr "Approved/Public"
+
+#: views/elements/developers/editors_review_history_item.thtml:70
+#: views/editors/reviewlog.thtml:85
+#, fuzzy
+msgid "editors_review_history_pending_denied"
+msgstr "Denied/Sandbox"
+
+#. link text in an add-on's editor review history, allowing to hide and show an information request's replies
+#. %1 is the number of replies
+#: views/elements/developers/editors_review_history_item.thtml:90
+#, fuzzy
+msgid "editors_review_history_show_hide_replies"
+msgid_plural "editors_review_history_show_hide_replies"
+msgstr[0] "Show/Hide Replies (%1$s)"
+msgstr[1] "Show/Hide Replies (%1$s)"
+
+#: views/editors/review.thtml:208
+#, fuzzy
+msgid "editors_review_label_applications"
+msgstr "Applications:"
+
+#: views/editors/review.thtml:196
+#, fuzzy
+msgid "editors_review_label_cannedresponse"
+msgstr "or select a canned response:"
+
+#: views/editors/review.thtml:190
+#, fuzzy
+msgid "editors_review_label_comments"
+msgstr "Comments:"
+
+#: views/editors/review.thtml:204
+#, fuzzy
+msgid "editors_review_label_operating_systems"
+msgstr "Operating Systems:"
+
+#: views/editors/review.thtml:285 views/editors/review.thtml:312
+#, fuzzy
+msgid "editors_review_link_pagetop"
+msgstr "Top"
+
+#: views/editors/review.thtml:141
+#, fuzzy
+msgid "editors_review_mulitple_notice"
+msgstr ""
+"Notice: Only review more than one file if you have tested EVERY file you "
+"select."
+
+#: views/editors/review.thtml:51
+#, fuzzy
+msgid "editors_review_next_link"
+msgstr "next &raquo;"
+
+#: views/editors/review.thtml:322
+#, fuzzy
+msgid "editors_review_previews_notfound"
+msgstr "No previews found."
+
+#: views/editors/review.thtml:50
+#, fuzzy
+msgid "editors_review_previous_link"
+msgstr "&laquo; prev"
+
+#: controllers/editors_controller.php:144
+#: controllers/editors_controller.php:146
+#, fuzzy
+msgid "editors_review_queue_pagetitle"
+msgstr "Review Queue"
+
+#. %1 is the add-ons rank in the queue, %2 is the total queue length
+#: views/editors/review.thtml:47
+#, fuzzy
+msgid "editors_review_rank_in_queue"
+msgstr "<strong># %1$s</strong> of %2$s in queue"
+
+#. %1 is the add-ons rank in the queue, %2 is the total queue length. Both numbers
+#: views/editors/review.thtml:45
+#, fuzzy
+msgid "editors_review_rank_in_queue_filtered"
+msgstr "<strong># %1$s</strong> of %2$s in queue (filtered)"
+
+#: views/editors/review.thtml:223
+#, fuzzy
+msgid "editors_review_submit_process_action"
+msgstr "Process Action"
+
+#: views/editors/review.thtml:293
+#, fuzzy
+msgid "editors_review_th_action"
+msgstr "Action"
+
+#: views/editors/review.thtml:294
+#, fuzzy
+msgid "editors_review_th_comments"
+msgstr "Comments"
+
+#: views/editors/review.thtml:291
+#, fuzzy
+msgid "editors_review_th_date"
+msgstr "Date"
+
+#: views/editors/review.thtml:292
+#, fuzzy
+msgid "editors_review_th_reviewer"
+msgstr "Reviewer"
+
+#: views/editors/review.thtml:290
+#, fuzzy
+msgid "editors_review_th_version_file"
+msgstr "Version/File"
+
+#: views/editors/review.thtml:217
+#, fuzzy
+msgid "editors_review_update_notify_once"
+msgstr ""
+"Notify me the next time this add-on is updated. (Subsequent updates will not "
+"generate an email)"
+
+#: controllers/editors_controller.php:298
+#, fuzzy
+msgid "editors_reviewed_successfully"
+msgstr "Review successfully processed."
+
+#: views/editors/reviews_queue.thtml:106
+#, fuzzy
+msgid "editors_reviews_action_delete_review"
+msgstr "Delete review"
+
+#: views/editors/reviews_queue.thtml:104
+#, fuzzy
+msgid "editors_reviews_action_keep"
+msgstr "Remove flags; keep review"
+
+#: views/editors/reviews_queue.thtml:102
+#, fuzzy
+msgid "editors_reviews_action_skip"
+msgstr "Skip"
+
+#: views/editors/reviews_queue.thtml:100
+#, fuzzy
+msgid "editors_reviews_header_action"
+msgstr "Action"
+
+#: views/editors/reviews_queue.thtml:67
+#, fuzzy
+msgid "editors_reviews_in_reply_to"
+msgstr "In reply to:"
+
+#: controllers/editors_controller.php:748
+#, fuzzy
+msgid "editors_reviews_processed"
+msgstr "Reviews processed successfully!"
+
+#: views/editors/reviews_queue.thtml:117
+#, fuzzy
+msgid "editors_reviews_queue_empty"
+msgstr "There are currently no reviews in moderation."
+
+#: views/editors/reviews_queue.thtml:111
+#, fuzzy
+msgid "editors_reviews_submit_process_reviews"
+msgstr "Process Reviews"
+
+#: controllers/editors_controller.php:691
+#, fuzzy
+msgid "editors_site_specific"
+msgstr "Site Specific"
+
+#: controllers/editors_controller.php:348
+#, fuzzy
+msgid "editors_tested_app"
+msgstr "Tested Application"
+
+#: controllers/editors_controller.php:347
+#, fuzzy
+msgid "editors_tested_os"
+msgstr "Tested Operating Systems"
+
+#: views/editors/queue.thtml:151
+#, fuzzy
+msgid "editors_th_additional_info"
+msgstr "Additional Information"
+
+#: views/editors/featured.thtml:63 views/editors/queue.thtml:109
+#: views/admin/flagged_queue.thtml:53
+#, fuzzy
+msgid "editors_th_addon"
+msgstr "Add-on"
+
+#: views/editors/queue.thtml:125
+#, fuzzy
+msgid "editors_th_addontype"
+msgstr "Type"
+
+#: views/editors/featured.thtml:64
+#, fuzzy
+msgid "editors_th_locales"
+msgstr "Restrict to locales?"
+
+#: views/editors/queue.thtml:148
+#, fuzzy
+msgid "editors_th_nomination_age"
+msgstr "Time in Queue"
+
+#: views/editors/queue.thtml:101 views/editors/queue.thtml:117
+#: views/editors/queue.thtml:144
+#, fuzzy
+msgid "editors_th_sort_ascending"
+msgstr "Ascending sort"
+
+#: views/editors/queue.thtml:105 views/editors/queue.thtml:121
+#: views/editors/queue.thtml:140
+#, fuzzy
+msgid "editors_th_sort_descending"
+msgstr "Descending sort"
+
+#. %s is a number
+#: controllers/editors_controller.php:1036
+#, fuzzy, php-format
+msgid "editors_x_days"
+msgstr "%s days"
+
+#. %s is a number
+#: controllers/editors_controller.php:1044
+#, fuzzy, php-format
+msgid "editors_x_hours"
+msgstr "%s hours"
+
+#. %s is a number
+#: controllers/editors_controller.php:1052
+#, fuzzy, php-format
+msgid "editors_x_minutes"
+msgstr "%s minutes"
+
+#: views/errors/error401.thtml:50 controllers/components/simple_acl.php:81
+#: controllers/components/simple_acl.php:82
+#: controllers/components/simple_acl.php:83 controllers/components/amo.php:607
+#: controllers/components/amo.php:608 controllers/components/amo.php:609
+#: controllers/reviews_controller.php:353
+#: controllers/reviews_controller.php:485
+#: controllers/collections_controller.php:438
+#: controllers/collections_controller.php:496
+#: controllers/collections_controller.php:504
+#: controllers/collections_controller.php:971
+#: controllers/collections_controller.php:1034
+#: controllers/collections_controller.php:1077
+#, fuzzy
+msgid "error_access_denied"
+msgstr "Access Denied"
+
+#: views/errors/error401.thtml:52
+#, fuzzy
+msgid "error_access_denied_message"
+msgstr "You are not authorized to view this page."
+
+#: controllers/collections_controller.php:1039
+#, fuzzy
+msgid "error_addon_exists"
+msgstr "Add-on already exists!"
+
+#: controllers/developers_controller.php:200
+#: controllers/developers_controller.php:593
+#: controllers/developers_controller.php:1016
+#: controllers/developers_controller.php:1429
+#: controllers/downloads_controller.php:95
+#: controllers/downloads_controller.php:102
+#: controllers/downloads_controller.php:164
+#: controllers/statistics_controller.php:135
+#: controllers/previews_controller.php:115
+#: controllers/previews_controller.php:206
+#: controllers/previews_controller.php:307
+#: controllers/reviews_controller.php:77
+#: controllers/reviews_controller.php:240
+#: controllers/reviews_controller.php:332
+#: controllers/reviews_controller.php:340 controllers/api_controller.php:123
+#: controllers/api_controller.php:759 controllers/addons_controller.php:131
+#: controllers/addons_controller.php:197
+#: controllers/addons_controller.php:1407
+#: controllers/addons_controller.php:1465
+#: controllers/addons_controller.php:1469
+#: controllers/addons_controller.php:1503
+#: controllers/editors_controller.php:265
+#: controllers/collections_controller.php:1041
+#: controllers/collections_controller.php:1074
+#, fuzzy
+msgid "error_addon_notfound"
+msgstr "Add-on not found!"
+
+#: controllers/files_controller.php:83 controllers/files_controller.php:196
+#, fuzzy
+msgid "error_addon_notviewable"
+msgstr "This add-on is not viewable here."
+
+#: controllers/reviews_controller.php:246
+#, fuzzy
+msgid "error_addon_selfreview"
+msgstr "You cannot review your own add-on."
+
+#: controllers/addons_controller.php:970
+#, fuzzy
+msgid "error_browse_no_addons"
+msgstr "No add-ons in this category!"
+
+#: controllers/api_controller.php:424
+#, fuzzy
+msgid "error_collection_feed_notfound"
+msgstr "Add-on feed not found."
+
+#: views/users/register.thtml:65 views/users/edit.thtml:194
+#, fuzzy
+msgid "error_email_invalid"
+msgstr "This is not a valid email address."
+
+#: views/users/pwreset.thtml:74 views/users/register.thtml:70
+#: views/users/register.thtml:80 views/users/register.thtml:86
+#: views/users/edit.thtml:105 views/users/edit.thtml:111
+#: views/users/edit.thtml:192 views/admin/users_edit.thtml:78
+#: views/admin/users_edit.thtml:83 views/reviews/add.thtml:80
+#: views/reviews/add.thtml:104
+#, fuzzy
+msgid "error_field_required"
+msgstr "This field must not be empty."
+
+#: controllers/files_controller.php:75 controllers/files_controller.php:93
+#: controllers/files_controller.php:96 controllers/files_controller.php:163
+#: controllers/files_controller.php:176 controllers/files_controller.php:185
+#: controllers/files_controller.php:204 controllers/editors_controller.php:412
+#, fuzzy
+msgid "error_file_notfound"
+msgstr "File not found!"
+
+#. %s is a filename
+#: controllers/editors_controller.php:430
+#, fuzzy, php-format
+msgid "error_file_x_notfound"
+msgstr "File error: %s does not exist."
+
+#: views/collections/add.thtml:55 views/collections/edit.thtml:89
+#: views/users/register.thtml:54 views/users/edit.thtml:81
+#: views/reviews/add.thtml:70 controllers/groups_controller.php:80
+#: controllers/groups_controller.php:102
+#, fuzzy
+msgid "error_formerrors"
+msgstr "There are errors in this form. Please correct them and resubmit."
+
+#: views/users/register.thtml:109
+#, fuzzy
+msgid "error_invalid_captcha"
+msgstr "Invalid captcha, please try again!"
+
+#: views/users/register.thtml:100 views/users/edit.thtml:125
+#: views/admin/users_edit.thtml:101
+#, fuzzy
+msgid "error_invalid_url"
+msgstr ""
+"This URL has an invalid format. Valid URLs look like http://example.com/"
+"my_page."
+
+#. %s is a string representing what's missing. Example: file_id
+#: controllers/downloads_controller.php:65
+#: controllers/users_controller.php:185 controllers/users_controller.php:264
+#: controllers/users_controller.php:559 controllers/users_controller.php:653
+#: controllers/reviews_controller.php:71
+#: controllers/reviews_controller.php:234
+#: controllers/reviews_controller.php:325
+#: controllers/reviews_controller.php:473
+#: controllers/reviews_controller.php:475
+#: controllers/addons_controller.php:182
+#: controllers/addons_controller.php:1381
+#: controllers/addons_controller.php:1455
+#: controllers/collections_controller.php:266
+#: controllers/collections_controller.php:285
+#: controllers/collections_controller.php:346
+#: controllers/collections_controller.php:443
+#: controllers/collections_controller.php:482
+#: controllers/collections_controller.php:936
+#: controllers/collections_controller.php:959
+#: controllers/collections_controller.php:960
+#: controllers/collections_controller.php:975
+#: controllers/collections_controller.php:977
+#: controllers/collections_controller.php:994
+#: controllers/collections_controller.php:1003
+#: controllers/collections_controller.php:1016
+#: controllers/collections_controller.php:1017
+#: controllers/collections_controller.php:1024
+#: controllers/collections_controller.php:1070
+#: controllers/collections_controller.php:1090
+#, fuzzy, php-format
+msgid "error_missing_argument"
+msgstr "Missing argument: %s"
+
+#: controllers/components/amo.php:507 controllers/components/amo.php:532
+#, fuzzy
+msgid "error_no_files_in_addon"
+msgstr "No Files"
+
+#: controllers/previews_controller.php:200
+#, fuzzy
+msgid "error_preview_notfound"
+msgstr "Preview not found!"
+
+#: views/addons/display.thtml:400 views/reviews/add.thtml:98
+#, fuzzy
+msgid "error_review_rating_required"
+msgstr "You must select a rating."
+
+#: controllers/users_controller.php:160
+#, fuzzy
+msgid "error_user_already_confirmed"
+msgstr "This user account is already confirmed."
+
+#: controllers/users_controller.php:202 controllers/users_controller.php:276
+#: controllers/users_controller.php:569 controllers/users_controller.php:581
+#: controllers/users_controller.php:587 controllers/users_controller.php:610
+#: controllers/users_controller.php:627
+#, fuzzy
+msgid "error_user_badconfirmationcode"
+msgstr "Invalid confirmation code!"
+
+#: views/users/pwreset.thtml:79 views/users/register.thtml:75
+#: views/users/edit.thtml:183
+#, fuzzy
+msgid "error_user_confirmpw_nomatch"
+msgstr "The passwords did not match."
+
+#: views/users/register.thtml:65 views/users/edit.thtml:190
+#: controllers/users_controller.php:617
+#, fuzzy
+msgid "error_user_email_notunique"
+msgstr "This email address is already taken by another user."
+
+#: controllers/users_controller.php:596
+#, fuzzy
+msgid "error_user_emailchange_expired"
+msgstr ""
+"The email change has expired. Please change your email address again in your "
+"user profile and click the link in the confirmation email as soon as you "
+"receive it."
+
+#: controllers/collections_controller.php:985
+#, fuzzy
+msgid "error_user_exists"
+msgstr ""
+"Users can only have one role at a time. Please remove the user from any "
+"existing roles before continuing."
+
+#: views/users/register.thtml:91 views/users/edit.thtml:116
+#: views/admin/users_edit.thtml:88
+#, fuzzy
+msgid "error_user_nickname_notunique"
+msgstr "This nickname is already taken."
+
+#: views/users/pwreset.thtml:54 controllers/users_controller.php:191
+#: controllers/users_controller.php:270 controllers/users_controller.php:603
+#: controllers/users_controller.php:659
+#: controllers/collections_controller.php:988
+#: controllers/collections_controller.php:998
+#, fuzzy
+msgid "error_user_notfound"
+msgstr "User not found!"
+
+#: views/users/activatefirst.thtml:47
+#, fuzzy
+msgid "error_user_unconfirmed"
+msgstr ""
+"Please confirm your user account first with the code you received by email."
+
+#: views/users/login.thtml:67
+#, fuzzy
+msgid "error_username_or_pw_wrong"
+msgstr "Wrong username or password!"
+
+#: controllers/editors_controller.php:260
+#, fuzzy
+msgid "error_version_notfound"
+msgstr "Version not found!"
+
+#: views/users/delete.thtml:125 views/users/edit.thtml:173
+#, fuzzy
+msgid "error_wrong_password"
+msgstr "Wrong password entered!"
+
+#: views/elements/amo2009/homepage_addon.thtml:122
+#: views/elements/feature.thtml:122
+#, fuzzy
+msgid "feature_learnmore"
+msgstr "Learn more"
+
+#. %1 is the add-on name
+#: views/elements/amo2009/homepage_addon.thtml:123
+#: views/elements/feature.thtml:123
+#, fuzzy, php-format
+msgid "feature_learnmore_about_addon"
+msgstr "Learn more about %1$s"
+
+#. %1$s is a number
+#: views/elements/amo2009/reviews.thtml:52
+#: views/elements/addon_listitem.thtml:112 views/elements/feature.thtml:99
+#: views/addons/browse_thumbs.thtml:86
+#, fuzzy, php-format
+msgid "feature_reviews"
+msgid_plural "feature_reviews"
+msgstr[0] "%1$s review"
+msgstr[1] "%1$s reviews"
+
+#: views/elements/amo2009/homepage_addon.thtml:127
+#: views/elements/feature.thtml:127
+#, fuzzy
+msgid "feature_view_more_from_category"
+msgstr "View more from"
+
+#. This appears on a page that views the source of an add-on. This link will return
+#. the user to the add-on's main page
+#: views/files/browse.thtml:65
+#, fuzzy
+msgid "file_browser_link_addon"
+msgstr "Back to add-on"
+
+#. There is a list of directories and files on the page. Clicking this will show the
+#. contents of all the directories (normally you would click on each one to see the
+#. contents)
+#: views/files/browse.thtml:67
+#, fuzzy
+msgid "file_browser_link_expand_all"
+msgstr "Expand all"
+
+#. This appears on a page that views the source of an add-on. This link will return
+#. the user to the add-on's review page (it only appears if the add-on is being
+#. reviewed)
+#: views/files/browse.thtml:64
+#, fuzzy
+msgid "file_browser_link_review"
+msgstr "Back to review"
+
+#. The title of the page for viewing an add-on's source.
+#. %1$s is the name of the add-on
+#. %2$s is the name of the current application (e.g. Firefox or Thunderbird)
+#: views/files/browse.thtml:46
+#, fuzzy
+msgid "file_browser_title"
+msgstr "%1$s :: File Browser :: %2$s Add-ons"
+
+#. This appears on a page that views the source of an add-on. There is a list of
+#. directories and files on the page. Clicking this link will toggle between an
+#. expanded or a collapsed list. This string should be kept short.
+#: views/files/browse.thtml:68
+#, fuzzy
+msgid "file_browser_toggle_expand_collapse"
+msgstr "+/-"
+
+#. Link text for the AMO About page.
+#: views/elements/footer.thtml:72 views/layouts/amo2009.thtml:341
+#, fuzzy
+msgid "footer_a_about"
+msgstr "About"
+
+#. Link text to the AMO blog.
+#: views/elements/footer.thtml:74 views/layouts/amo2009.thtml:343
+#, fuzzy
+msgid "footer_a_blog"
+msgstr "Blog"
+
+#. Link text to the Frequently Asked Questions page.
+#: views/elements/footer.thtml:73 views/layouts/amo2009.thtml:342
+#, fuzzy
+msgid "footer_a_faq"
+msgstr "FAQ"
+
+#. Full text for the FAQ abbreviation.
+#: views/elements/footer.thtml:73 views/pages/collector_features.thtml:72
+#: views/layouts/amo2009.thtml:342
+#, fuzzy
+msgid "footer_abbr_faq"
+msgstr "Frequently Asked Questions"
+
+#: views/elements/footer.thtml:67 views/layouts/amo2009.thtml:336
+#, fuzzy
+msgid "footer_all_rights_reserved"
+msgstr "All rights reserved."
+
+#: views/elements/footer.thtml:67 views/layouts/amo2009.thtml:336
+#, fuzzy
+msgid "footer_copyright"
+msgstr "Copyright"
+
+#: views/elements/footer.thtml:71 views/layouts/amo2009.thtml:340
+#, fuzzy
+msgid "footer_credits"
+msgstr "Credits"
+
+#: views/elements/footer.thtml:76 views/layouts/amo2009.thtml:346
+#, fuzzy
+msgid "footer_disclaimer"
+msgstr ""
+"Mozilla is providing links to these applications as a courtesy, and makes no "
+"representations regarding the applications or any information related there "
+"to. Any questions, complaints or claims regarding the applications must be "
+"directed to the appropriate software vendor."
+
+#: views/elements/footer.thtml:61 views/layouts/amo2009.thtml:332
+#, fuzzy
+msgid "footer_lang_form_lang_submit_go"
+msgstr "Go"
+
+#: views/elements/footer.thtml:70 views/layouts/amo2009.thtml:339
+#, fuzzy
+msgid "footer_legal_notices"
+msgstr "Legal Notices"
+
+#: views/elements/footer.thtml:50 views/layouts/amo2009.thtml:321
+#, fuzzy
+msgid "footer_other_languages"
+msgstr "Other languages:"
+
+#: views/elements/footer.thtml:69 views/layouts/amo2009.thtml:338
+#, fuzzy
+msgid "footer_privacy_policy"
+msgstr "Privacy Policy"
+
+#: models/addontype.php:79
+#, fuzzy
+msgid "general_addontype_dict"
+msgstr "Dictionary"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:100
+#, fuzzy
+msgid "general_addontype_dict_plural"
+msgstr "Dictionaries"
+
+#: models/addontype.php:75
+#, fuzzy
+msgid "general_addontype_extension"
+msgstr "Extension"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:98
+#, fuzzy
+msgid "general_addontype_extension_plural"
+msgstr "Extensions"
+
+#: models/addontype.php:85
+#, fuzzy
+msgid "general_addontype_lpaddon"
+msgstr "Language Pack (Add-on)"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:103
+#, fuzzy
+msgid "general_addontype_lpaddon_plural"
+msgstr "Language Packs (Add-on)"
+
+#: models/addontype.php:83
+#, fuzzy
+msgid "general_addontype_lpapp"
+msgstr "Language Pack (Application)"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:102
+#, fuzzy
+msgid "general_addontype_lpapp_plural"
+msgstr "Language Packs (Application)"
+
+#: models/addontype.php:87
+#, fuzzy
+msgid "general_addontype_plugin"
+msgstr "Plugin"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:104
+#, fuzzy
+msgid "general_addontype_plugin_plural"
+msgstr "Plugins"
+
+#: models/addontype.php:81
+#, fuzzy
+msgid "general_addontype_search"
+msgstr "Search Engine"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:101
+#, fuzzy
+msgid "general_addontype_search_plural"
+msgstr "Search Engines"
+
+#: models/addontype.php:77
+#, fuzzy
+msgid "general_addontype_theme"
+msgstr "Theme"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:99
+#, fuzzy
+msgid "general_addontype_theme_plural"
+msgstr "Themes"
+
+#: config/language.php:367
+#, fuzzy
+msgid "general_languages_all_locales"
+msgstr "All Locales"
+
+#: views/layouts/amo2009.thtml:249
+#, fuzzy
+msgid "header_brand_name"
+msgstr "Mozilla"
+
+#. %1$s is the application name. Example: Firefox
+#: views/elements/header.thtml:111 views/elements/header.thtml:122
+#: views/layouts/amo2009.thtml:248
+#, fuzzy, php-format
+msgid "header_home_tooltip"
+msgstr "Return to the %1$s Add-ons homepage"
+
+#: views/elements/header.thtml:87
+#, fuzzy
+msgid "header_main_firefox_header"
+msgstr "Firefox Add-ons"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:218
+#, fuzzy
+msgid "header_main_firefox_header_with_logo"
+msgstr ""
+"Add-ons <em>for</em> <img alt=\"Firefox\" src=\"%1$s\" /> <strong>Firefox</"
+"strong>"
+
+#: views/elements/header.thtml:99
+#, fuzzy
+msgid "header_main_header"
+msgstr "Add-ons"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:242
+#, fuzzy
+msgid "header_main_header_with_logo"
+msgstr "Add-ons <img alt=\"Add-ons\" src=\"%1$s\" />"
+
+#: views/elements/header.thtml:90
+#, fuzzy
+msgid "header_main_seamonkey_header"
+msgstr "Seamonkey Add-ons"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:224
+#, fuzzy
+msgid "header_main_seamonkey_header_with_logo"
+msgstr ""
+"Add-ons <em>for</em> <img alt=\"seamonkey\" src=\"%1$s\" /> "
+"<strong>SeaMonkey</strong>"
+
+#: views/elements/header.thtml:93
+#, fuzzy
+msgid "header_main_sunbird_header"
+msgstr "Sunbird Add-ons"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:230
+#, fuzzy
+msgid "header_main_sunbird_header_with_logo"
+msgstr ""
+"Add-ons <em>for</em> <img alt=\"sunbird\" src=\"%1$s\" /> <strong>Sunbird</"
+"strong>"
+
+#: views/elements/header.thtml:96
+#, fuzzy
+msgid "header_main_thunderbird_header"
+msgstr "Thunderbird Add-ons"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:236
+#, fuzzy
+msgid "header_main_thunderbird_header_with_logo"
+msgstr ""
+"Add-ons <em>for</em> <img alt=\"thunderbird\" src=\"%1$s\" /> "
+"<strong>Thunderbird</strong>"
+
+#: views/layouts/amo2009.thtml:205
+#, fuzzy
+msgid "header_navaccess_applications_menu"
+msgstr "Skip to other applications menu"
+
+#: views/layouts/amo2009.thtml:204
+#, fuzzy
+msgid "header_navaccess_categories_menu"
+msgstr "Skip to categories menu"
+
+#: views/layouts/amo2009.thtml:202
+#, fuzzy
+msgid "header_navaccess_main_content"
+msgstr "Skip to main content"
+
+#: views/layouts/amo2009.thtml:203
+#, fuzzy
+msgid "header_navaccess_search_form"
+msgstr "Skip to search form"
+
+#: views/elements/header.thtml:62
+#, fuzzy
+msgid "header_navlink_addons"
+msgstr "Add-ons"
+
+#: views/elements/developers/sidebar.thtml:72
+#: views/elements/developers/myaddons.thtml:50 views/elements/header.thtml:159
+#: views/addons/display.thtml:378
+#, fuzzy
+msgid "header_navlink_login"
+msgstr "Log in"
+
+#: views/elements/header.thtml:156 views/layouts/amo2009.thtml:304
+#, fuzzy
+msgid "header_navlink_logout"
+msgstr "Log out"
+
+#: views/elements/header.thtml:145 views/layouts/amo2009.thtml:303
+#, fuzzy
+msgid "header_navlink_myaccount"
+msgstr "My Account"
+
+#: views/elements/header.thtml:158
+#, fuzzy
+msgid "header_navlink_register"
+msgstr "Register"
+
+#. %1 is the URL to the registration page
+#. %2 is the URL to the login page
+#: views/layouts/amo2009.thtml:278
+#, fuzzy
+msgid "header_navlink_register_or_login"
+msgstr "<a href=\"%1$s\">Register</a> or <a href=\"%2$s\">Log in</a>"
+
+#: views/layouts/amo2009.thtml:285
+#, fuzzy
+msgid "header_navlink_tools"
+msgstr "Tools"
+
+#. %s is the add-on name
+#: views/elements/collections_interactive_addon.thtml:62
+#: views/elements/amo2009/homepage_addon.thtml:77
+#: views/elements/addon_discussionheader.thtml:62
+#: views/elements/addon_listitem.thtml:67 views/elements/feature.thtml:84
+#: views/addons/category_landing.thtml:87 views/addons/browse_thumbs.thtml:60
+#, fuzzy, php-format
+msgid "img_preview_of"
+msgstr "Preview Image of %s"
+
+#. %1 is the login URL for the link tag
+#. %2 is the link to an explanatory page.
+#: views/elements/amo2009/install.thtml:307 views/elements/install.thtml:255
+#, fuzzy
+msgid "install_a_login_to_install"
+msgstr ""
+"<a href=\"%1$s\">Log in</a> to install this experimental add-on. <a href=\"%2"
+"$s\">Why</a>?"
+
+#. %1 is the URL for the Experimental Add-ons section of the FAQ page
+#: views/elements/amo2009/install.thtml:283 views/elements/install.thtml:232
+#, fuzzy
+msgid "install_button_confirm_exp_install"
+msgstr ""
+"Let me install this experimental add-on. <a href=\"%1$s\">What's this?</a>"
+
+#. %1$s is the application name. Example: Firefox
+#. %2$s is an optional string used to specify a platform. Example: (Windows)
+#: views/elements/amo2009/install.thtml:128 views/elements/install.thtml:75
+#, fuzzy, php-format
+msgid "install_button_text"
+msgstr "Add to %s %s"
+
+#. %1 is the add-on name, %2 is the app name
+#: views/elements/amo2009/install.thtml:191
+#: views/elements/amo2009/install.thtml:206
+#: views/elements/amo2009/install.thtml:249
+#: views/elements/amo2009/install.thtml:298 views/elements/install.thtml:150
+#: views/elements/install.thtml:165 views/elements/install.thtml:202
+#: views/elements/install.thtml:246
+#, fuzzy, php-format
+msgid "install_button_title"
+msgstr "Add %1$s to %2$s"
+
+#. %1$s is the add-on name
+#: views/elements/amo2009/install.thtml:200 views/elements/install.thtml:159
+#, fuzzy, php-format
+msgid "install_download"
+msgstr "Download %1$s"
+
+#: views/elements/amo2009/install.thtml:147 views/elements/install.thtml:94
+#, fuzzy
+msgid "install_error_addon_not_found"
+msgstr "This add-on is not available."
+
+#: views/addons/dictionaries.thtml:65
+#, fuzzy
+msgid "langtools_a11y_tablesummary"
+msgstr "List of language packs and dictionaries."
+
+#: views/addons/dictionaries.thtml:47
+#, fuzzy
+msgid "langtools_download_dictionary"
+msgstr "Download Dictionary"
+
+#: views/addons/dictionaries.thtml:48
+#, fuzzy
+msgid "langtools_download_langpack"
+msgstr "Download Language Pack"
+
+#: views/addons/dictionaries.thtml:63 controllers/components/amo.php:685
+#: controllers/addons_controller.php:1239
+#, fuzzy
+msgid "langtools_header_dicts_and_langpacks"
+msgstr "Dictionaries & Language Packs"
+
+#: views/addons/dictionaries.thtml:44
+#, fuzzy
+msgid "langtools_install_dictionary"
+msgstr "Install Dictionary"
+
+#: views/addons/dictionaries.thtml:45
+#, fuzzy
+msgid "langtools_install_langpack"
+msgstr "Install Language Pack"
+
+#: views/addons/dictionaries.thtml:69
+#, fuzzy
+msgid "langtools_tableheader_dictionary"
+msgstr "Dictionary"
+
+#: views/addons/dictionaries.thtml:70
+#, fuzzy
+msgid "langtools_tableheader_langpack"
+msgstr "Language Pack"
+
+#: views/addons/dictionaries.thtml:68
+#, fuzzy
+msgid "langtools_tableheader_language"
+msgstr "Language"
+
+#: models/license.php:65
+#, fuzzy
+msgid "license_custom"
+msgstr "Custom License"
+
+#: config/bootstrap.php:303
+#, fuzzy
+msgid "licenses_bsd"
+msgstr "BSD License"
+
+#: config/bootstrap.php:298
+#, fuzzy
+msgid "licenses_gpl_2.0"
+msgstr "GNU General Public License, version 2.0"
+
+#: config/bootstrap.php:299
+#, fuzzy
+msgid "licenses_gpl_3.0"
+msgstr "GNU General Public License, version 3.0"
+
+#: config/bootstrap.php:300
+#, fuzzy
+msgid "licenses_lgpl_2.1"
+msgstr "GNU Lesser General Public License, version 2.1"
+
+#: config/bootstrap.php:301
+#, fuzzy
+msgid "licenses_lgpl_3.0"
+msgstr "GNU Lesser General Public License, version 3.0"
+
+#: config/bootstrap.php:302
+#, fuzzy
+msgid "licenses_mit"
+msgstr "MIT/X11 License"
+
+#: config/bootstrap.php:297
+#, fuzzy
+msgid "licenses_mpl_1.1"
+msgstr "Mozilla Public License, version 1.1"
+
+#: views/users/emailchange.thtml:51 views/users/delete.thtml:55
+#: views/users/delete.thtml:137 views/users/edit.thtml:74
+#: views/reviews/flag.thtml:54
+#, fuzzy
+msgid "link_return_to_front_page"
+msgstr "Click here to return to the front page."
+
+#: views/elements/amo2009/addon_list_options.thtml:46
+#: views/elements/addon_list_options.thtml:46
+#, fuzzy
+msgid "list_sortby_date"
+msgstr "Date"
+
+#: views/elements/amo2009/addon_list_options.thtml:47
+#: views/elements/addon_list_options.thtml:47
+#, fuzzy
+msgid "list_sortby_downloads"
+msgstr "Downloads"
+
+#: views/elements/amo2009/addon_list_options.thtml:45
+#: views/elements/addon_list_options.thtml:45
+#, fuzzy
+msgid "list_sortby_name"
+msgstr "Add-on Name"
+
+#: views/elements/amo2009/addon_list_options.thtml:48
+#: views/elements/addon_list_options.thtml:48
+#, fuzzy
+msgid "list_sortby_rating"
+msgstr "Rating"
+
+#: config/bootstrap.php:278
+#, fuzzy
+msgid "main_prettyname_fennec"
+msgstr "Fennec"
+
+#: config/bootstrap.php:274
+#, fuzzy
+msgid "main_prettyname_firefox"
+msgstr "Firefox"
+
+#: config/bootstrap.php:277
+#, fuzzy
+msgid "main_prettyname_seamonkey"
+msgstr "SeaMonkey"
+
+#: config/bootstrap.php:276
+#, fuzzy
+msgid "main_prettyname_sunbird"
+msgstr "Sunbird"
+
+#: config/bootstrap.php:275
+#, fuzzy
+msgid "main_prettyname_thunderbird"
+msgstr "Thunderbird"
+
+#: views/elements/addon_categories.thtml:52
+#, fuzzy
+msgid "nav_category_dicts_langpacks"
+msgstr "Dictionaries & Language Packs"
+
+#: views/elements/addon_categories.thtml:55
+#, fuzzy
+msgid "nav_category_themes"
+msgstr "Themes"
+
+#: views/elements/app_chooser.thtml:47 views/layouts/amo2009.thtml:255
+#, fuzzy
+msgid "other_apps_tooltip"
+msgstr "Find add-ons for other applications"
+
+#. In a user list: user 1, user 2, "others"
+#: views/helpers/addons_html.php:222
+#, fuzzy
+msgid "other_users"
+msgstr "others"
+
+#: controllers/pages_controller.php:90
+#, fuzzy
+msgid "page_title_appversions"
+msgstr "Application Versions"
+
+#: controllers/pages_controller.php:115
+#, fuzzy
+msgid "page_title_collector"
+msgstr "Add-on Collector"
+
+#: controllers/pages_controller.php:117
+#, fuzzy
+msgid "page_title_collector_faq"
+msgstr "Add-on Collector FAQ"
+
+#: controllers/pages_controller.php:119
+#, fuzzy
+msgid "page_title_collector_features"
+msgstr "Add-on Collector Features"
+
+#: controllers/pages_controller.php:122
+#, fuzzy
+msgid "page_title_collector_firstrun"
+msgstr "Welcome to the Add-on Collector"
+
+#: controllers/pages_controller.php:92
+#, fuzzy
+msgid "page_title_credits"
+msgstr "Credits"
+
+#: controllers/pages_controller.php:113
+#, fuzzy
+msgid "page_title_developer_faq"
+msgstr "Developer FAQ"
+
+#: controllers/pages_controller.php:111
+#, fuzzy
+msgid "page_title_faq"
+msgstr "Frequently Asked Questions"
+
+#: controllers/pages_controller.php:94
+#, fuzzy
+msgid "page_title_fashionyourfirefox_faq"
+msgstr "Fashion your Firefox FAQ"
+
+#: controllers/pages_controller.php:101
+#, fuzzy
+msgid "page_title_policy"
+msgstr "Add-ons Policy"
+
+#: controllers/pages_controller.php:103
+#, fuzzy
+msgid "page_title_privacy"
+msgstr "Mozilla Privacy Policy"
+
+#: controllers/pages_controller.php:105
+#, fuzzy
+msgid "page_title_review_guide"
+msgstr "Review Guidelines"
+
+#: controllers/pages_controller.php:107
+#, fuzzy
+msgid "page_title_sandbox"
+msgstr "Sandbox Review System"
+
+#: controllers/pages_controller.php:109
+#, fuzzy
+msgid "page_title_submissionhelp"
+msgstr "Submission Help"
+
+#: views/pages/appversions.thtml:87
+#, fuzzy
+msgid "pages_appversions_guid"
+msgstr "GUID"
+
+#: views/pages/appversions.thtml:79 controllers/pages_controller.php:90
+#, fuzzy
+msgid "pages_appversions_header"
+msgstr "Valid Application Versions"
+
+#: views/pages/appversions.thtml:80
+#, fuzzy
+msgid "pages_appversions_intro"
+msgstr ""
+"Add-ons submitted to Mozilla Add-ons must have an install.rdf file with at "
+"least one of the below applications supported. Only the versions listed "
+"below are allowed for these applications."
+
+#. %s is a full <a> tag
+#: views/pages/appversions.thtml:93
+#, fuzzy, php-format
+msgid "pages_appversions_required_files"
+msgstr ""
+"If your supported application does not require an install.rdf file, you "
+"still must include one with the required properties as specified %s."
+
+#. this is the text inside of an <a> tag for pages_appversions_required_files. This
+#. should be fixed.
+#: views/pages/appversions.thtml:93
+#, fuzzy
+msgid "pages_appversions_required_files_link"
+msgstr "here"
+
+#: views/pages/appversions.thtml:88
+#, fuzzy
+msgid "pages_appversions_versions"
+msgstr "Versions"
+
+#: views/pages/policy.thtml:51
+#, fuzzy
+msgid "pages_policy_sandbox_link"
+msgstr "Sandbox Information Page"
+
+#: views/elements/pagination.thtml:53
+#, fuzzy
+msgid "pagination_next_page"
+msgstr "next"
+
+#: views/elements/pagination.thtml:52
+#, fuzzy
+msgid "pagination_previous_page"
+msgstr "previous"
+
+#: views/elements/recaptcha.thtml:65
+#, fuzzy
+msgid "recaptcha_enter_both_words"
+msgstr ""
+"Please enter <strong>both words</strong> below, <strong>separated by a "
+"space</strong>."
+
+#: views/elements/recaptcha.thtml:83
+#, fuzzy
+msgid "recaptcha_enter_here"
+msgstr "Enter your answer here:"
+
+#: views/elements/recaptcha.thtml:74
+#, fuzzy
+msgid "recaptcha_enter_whatyouhear"
+msgstr "Please type what you hear."
+
+#. %1 is the link switching refreshing the captcha
+#. %2 is the link switching to a text captcha
+#: views/elements/recaptcha.thtml:77
+#, fuzzy
+msgid "recaptcha_hardtohear_text"
+msgstr ""
+"If this is hard to understand, you can <a href=\"%1$s\">listen to something "
+"else</a> or <a href=\"%2$s\">switch back to text</a>."
+
+#. %1 is the link switching refreshing the captcha
+#. %2 is the link switching to an audio captcha
+#: views/elements/recaptcha.thtml:68
+#, fuzzy
+msgid "recaptcha_hardtoread_text"
+msgstr ""
+"If this is hard to read, you can <a href=\"%1$s\">try different words</a> or "
+"<a href=\"%2$s\">listen to something</a> instead."
+
+#: views/users/register.thtml:105
+#, fuzzy
+msgid "recaptcha_label"
+msgstr "Are you human?"
+
+#: views/users/register.thtml:106
+#, fuzzy
+msgid "recaptcha_whatsthis"
+msgstr "What's this?"
+
+#: controllers/reviews_controller.php:559
+#, fuzzy
+msgid "review_flag_error"
+msgstr "Error flagging this review!"
+
+#: models/reviews_moderation_flag.php:69
+#, fuzzy
+msgid "review_flag_reason_bug_support"
+msgstr "Misplaced bug report or support request"
+
+#: views/reviews/display.thtml:103 views/reviews/display.thtml:186
+#, fuzzy
+msgid "review_flag_reason_instructions"
+msgstr "Report this review (select a reason)"
+
+#: models/reviews_moderation_flag.php:67
+#, fuzzy
+msgid "review_flag_reason_language"
+msgstr "Inappropriate language/dialog"
+
+#: models/reviews_moderation_flag.php:71
+#, fuzzy
+msgid "review_flag_reason_other"
+msgstr "Other (please specify)"
+
+#: models/reviews_moderation_flag.php:65
+#, fuzzy
+msgid "review_flag_reason_spam"
+msgstr "Spam or otherwise non-review content"
+
+#: views/reviews/display.thtml:91 views/reviews/display.thtml:175
+#: controllers/reviews_controller.php:555
+#, fuzzy
+msgid "review_flag_success"
+msgstr "Thanks; this review has been flagged for editor approval."
+
+#: views/reviews/display.thtml:41
+#, fuzzy
+msgid "review_flag_this"
+msgstr "Report this review"
+
+#: views/reviews/display.thtml:42
+#, fuzzy
+msgid "review_flag_this_titletip"
+msgstr ""
+"Is this review inappropriate, inaccurate or spam? Click here to flag it for "
+"editor review."
+
+#. %1 is the URL of the support section, %2 for the review guidelines
+#: views/reviews/add.thtml:53
+#, fuzzy
+msgid "review_guidelines_short"
+msgstr ""
+"<p>Keep these tips in mind:</p><ul><li>Write like you're telling a friend "
+"about your experience with the add-on. Give specifics and helpful details, "
+"such as what features you liked and/or disliked, how easy to use it is, and "
+"any disadvantages it has. Avoid generic language such as calling it \"Great"
+"\" or \"Bad\" unless you can give reasons why you believe this is so.</"
+"li><li>Please do not post bug reports in reviews. We do not make your email "
+"address available to add-on developers and they may need to contact you to "
+"help resolve your issue. See the <a href=\"%1$s\">support section</a> to "
+"find out where to get assistance for this add-on.</li><li>Please keep "
+"reviews clean, avoid the use of improper language and do not post any "
+"personal information.</li></ul><p>Please read the <a href=\"%2$s\">Review "
+"Guidelines</a> for more detail about user add-on reviews.</p>"
+
+#. %1 is the add-on name
+#: views/reviews/flag.thtml:56 views/reviews/display.thtml:55
+#: views/reviews/review_added.thtml:50
+#, fuzzy, php-format
+msgid "reviews_header"
+msgstr "Reviews for %s"
+
+#: controllers/addons_controller.php:435
+#, fuzzy
+msgid "rss_featuredaddons"
+msgstr "Featured Add-ons"
+
+#: controllers/addons_controller.php:432
+#, fuzzy
+msgid "rss_newestaddons"
+msgstr "Newest Add-ons"
+
+#: controllers/addons_controller.php:434
+#, fuzzy
+msgid "rss_popularaddons"
+msgstr "Popular Add-ons"
+
+#: controllers/addons_controller.php:433
+#, fuzzy
+msgid "rss_updatedaddons"
+msgstr "Updated Add-ons"
+
+#: views/elements/search_mini.thtml:70
+#, fuzzy
+msgid "search"
+msgstr "Search"
+
+#: views/search/collections.thtml:51
+#, fuzzy
+msgid "search_collections_header"
+msgstr "Collection Search Results"
+
+#: controllers/search_controller.php:297
+#, fuzzy
+msgid "search_collections_pagetitle"
+msgstr "Collection Search Results"
+
+#: controllers/search_controller.php:99
+#, fuzzy
+msgid "search_disabled"
+msgstr "Search is currently disabled. Please try again later."
+
+#: views/elements/amo2009/search.thtml:188 views/elements/search.thtml:187
+#: views/elements/search_mini.thtml:54
+#, fuzzy
+msgid "search_form_all_addons"
+msgstr "all add-ons"
+
+#. This string is in the main category dropdown when searching
+#: views/elements/amo2009/search.thtml:204
+#, fuzzy
+msgid "search_form_all_collections"
+msgstr "all collections"
+
+#: views/elements/amo2009/search.thtml:184
+#: views/elements/amo2009/search.thtml:385
+#: views/elements/amo2009/search.thtml:408 views/elements/search.thtml:171
+#: views/elements/search.thtml:183 views/elements/search_mini.thtml:43
+#: views/elements/search_mini.thtml:49 views/layouts/mozilla.thtml:188
+#, fuzzy
+msgid "search_form_default_text"
+msgstr "search for add-ons"
+
+#: views/elements/amo2009/search.thtml:184
+#: views/elements/amo2009/search.thtml:404
+#, fuzzy
+msgid "search_form_default_text_collections"
+msgstr "search for collections"
+
+#: views/elements/amo2009/search.thtml:206 views/elements/search.thtml:202
+#, fuzzy
+msgid "search_form_submit_tooltip"
+msgstr "Search for add-ons"
+
+#: views/elements/amo2009/search.thtml:184 views/elements/search.thtml:183
+#: views/elements/search_mini.thtml:49
+#, fuzzy
+msgid "search_form_tooltip"
+msgstr "Click to enter search terms"
+
+#: views/elements/amo2009/search.thtml:186 views/elements/search.thtml:185
+#: views/elements/search_mini.thtml:52
+#, fuzzy
+msgid "search_form_within"
+msgstr "within"
+
+#: views/addons/searchengines.thtml:118
+#, fuzzy
+msgid "search_landing_all_search_engines"
+msgstr "All Search Engines"
+
+#: views/addons/searchengines.thtml:114
+#, fuzzy
+msgid "search_landing_browse_search_engines"
+msgstr "Browse Search Engines"
+
+#: views/search/collections.thtml:58 views/search/index.thtml:59
+#, fuzzy
+msgid "search_nothing_found"
+msgstr "No results found."
+
+#: controllers/search_controller.php:185
+#, fuzzy
+msgid "search_pagetitle"
+msgstr "Search Add-ons"
+
+#: controllers/search_controller.php:242
+#, fuzzy
+msgid "search_rss_description"
+msgstr "Search results feed"
+
+#. %s is the terms the user is searching for (a string)
+#: controllers/search_controller.php:241
+#, fuzzy, php-format
+msgid "search_rss_results_for"
+msgstr "Search results for: %s"
+
+#: views/elements/header.thtml:154 views/layouts/amo2009.thtml:296
+#, fuzzy
+msgid "sidebar_navlink_admin_tools"
+msgstr "Admin Tools"
+
+#: views/elements/header.thtml:146 views/layouts/amo2009.thtml:288
+#, fuzzy
+msgid "sidebar_navlink_developer_tools"
+msgstr "Developer Tools"
+
+#: views/elements/header.thtml:148 views/layouts/amo2009.thtml:290
+#, fuzzy
+msgid "sidebar_navlink_editor_tools"
+msgstr "Editor Tools"
+
+#: views/layouts/amo2009.thtml:302
+#, fuzzy
+msgid "sidebar_navlink_welcome"
+msgstr "Welcome"
+
+#. %s is the user's name
+#: views/layouts/amo2009.thtml:302
+#, fuzzy, php-format
+msgid "sidebar_navlink_welcome_name"
+msgstr "Welcome, %s"
+
+#: views/elements/pitch.thtml:50 views/elements/pitch.thtml:55
+#, fuzzy
+msgid "sidebar_pitch_dictionary"
+msgstr "Dictionary"
+
+#: views/elements/pitch.thtml:72
+#, fuzzy
+msgid "sidebar_pitch_featured_addons"
+msgstr "Featured Add-ons"
+
+#: views/elements/pitch.thtml:61
+#, fuzzy
+msgid "sidebar_pitch_looking_for"
+msgstr "I am looking for a:"
+
+#: views/elements/pitch.thtml:70
+#, fuzzy
+msgid "sidebar_pitch_newest_addons"
+msgstr "Newest Add-ons"
+
+#: views/elements/pitch.thtml:49
+#, fuzzy
+msgid "sidebar_pitch_search"
+msgstr "Search Plugin"
+
+#: views/elements/pitch.thtml:69
+#, fuzzy
+msgid "sidebar_pitch_subscribe_to"
+msgstr "Subscribe to"
+
+#: views/elements/pitch.thtml:48 views/elements/pitch.thtml:54
+#, fuzzy
+msgid "sidebar_pitch_theme"
+msgstr "Theme"
+
+#: views/elements/pitch.thtml:71
+#, fuzzy
+msgid "sidebar_pitch_updated_addons"
+msgstr "Updated Add-ons"
+
+#. %1$s is a number
+#: views/helpers/localization.php:65 views/developers/versions_edit.thtml:95
+#: views/addons/dictionaries.thtml:92
+#, fuzzy, php-format
+msgid "size_kb"
+msgstr "%1$s KB"
+
+#: views/elements/amo2009/stars.thtml:57 views/elements/stars.thtml:63
+#, fuzzy
+msgid "stars_not_yet_rated"
+msgstr "Not yet rated"
+
+#. %1 is the number of stars this add-on has
+#: views/elements/amo2009/stars.thtml:49 views/elements/stars.thtml:54
+#, fuzzy, php-format
+msgid "stars_rated_x_outof_5"
+msgstr "Rated %s out of 5 stars"
+
+#: views/statistics/addon.thtml:59
+#, fuzzy
+msgid "statistics_addon_dashboard_link"
+msgstr "Dashboard Home"
+
+#: views/statistics/addon.thtml:58
+#, fuzzy
+msgid "statistics_addon_developertools_link"
+msgstr "Developer Tools"
+
+#: views/statistics/addon.thtml:53
+#, fuzzy
+msgid "statistics_addon_switch"
+msgstr "Switch Add-on"
+
+#. This is a date format.
+#. http://php.net/strftime
+#: views/statistics/rss/summary.thtml:54 views/statistics/addon.thtml:181
+#, fuzzy
+msgid "statistics_date_shortmonth"
+msgstr "%b. %e"
+
+#. This is a date format.
+#. http://php.net/strftime
+#: views/statistics/rss/summary.thtml:40 views/statistics/addon.thtml:152
+#, fuzzy
+msgid "statistics_date_shortmonthwithyear"
+msgstr "%b. %e, %Y"
+
+#. This is a date format.
+#. http://php.net/strftime
+#: views/statistics/rss/summary.thtml:41 views/statistics/rss/summary.thtml:48
+#: views/statistics/addon.thtml:161 views/statistics/addon.thtml:172
+#, fuzzy
+msgid "statistics_date_weekdayshortmonth"
+msgstr "%A, %b. %e"
+
+#. %1$s is an add-on name and version. Example: Add-on 3.5
+#: controllers/components/stats.php:519
+#, fuzzy, php-format
+msgid "statistics_events_addon_created"
+msgstr "%1$s created"
+
+#. %1$s is an application name and version. Example: Firefox 3.5
+#: controllers/components/stats.php:500
+#, fuzzy, php-format
+msgid "statistics_events_app_released"
+msgstr "%1$s released"
+
+#: views/statistics/addon.thtml:71
+#, fuzzy
+msgid "statistics_help_close_link"
+msgstr "Close"
+
+#: views/statistics/addon.thtml:60
+#, fuzzy
+msgid "statistics_help_link"
+msgstr "Help"
+
+#: views/statistics/index.thtml:83
+#, fuzzy
+msgid "statistics_index_anotheraddon"
+msgstr "or, select another add-on"
+
+#: views/statistics/index.thtml:85
+#, fuzzy
+msgid "statistics_index_anotheraddon_public"
+msgstr "or, select an add-on with public statistics"
+
+#: views/statistics/index.thtml:71
+#, fuzzy
+msgid "statistics_index_myaddons"
+msgstr "Select one of your add-ons to view its statistics"
+
+#: views/statistics/index.thtml:89
+#, fuzzy
+msgid "statistics_index_selectaddon"
+msgstr "Select an add-on to view its statistics"
+
+#: views/statistics/index.thtml:91
+#, fuzzy
+msgid "statistics_index_selectaddon_public"
+msgstr "Select an add-on with public statistics"
+
+#: views/statistics/index.thtml:39
+#, fuzzy
+msgid "statistics_index_title"
+msgstr "Statistics Dashboard"
+
+#: views/statistics/index.thtml:97
+#, fuzzy
+msgid "statistics_index_view_button"
+msgstr "View Statistics"
+
+#: views/statistics/addon.thtml:222 controllers/statistics_controller.php:247
+#, fuzzy
+msgid "statistics_js_download_csv"
+msgstr "View this table in CSV format"
+
+#: controllers/statistics_controller.php:246
+#, fuzzy
+msgid "statistics_js_dropdowns_none"
+msgstr "none"
+
+#: controllers/statistics_controller.php:245
+#, fuzzy
+msgid "statistics_js_dropdowns_removeplot"
+msgstr "Remove this plot"
+
+#: controllers/statistics_controller.php:248
+#, fuzzy
+msgid "statistics_js_groupby_selector_date"
+msgstr "Group by: Day"
+
+#: controllers/statistics_controller.php:251
+#, fuzzy
+msgid "statistics_js_groupby_selector_month"
+msgstr "Group by: Month"
+
+#: controllers/statistics_controller.php:249
+#, fuzzy
+msgid "statistics_js_groupby_selector_week"
+msgstr "Group by: Week"
+
+#: controllers/statistics_controller.php:250
+#, fuzzy
+msgid "statistics_js_groupby_selector_week_over_week"
+msgstr "Compare by: Week"
+
+#: controllers/statistics_controller.php:260
+#, fuzzy
+msgid "statistics_js_plotselection_foundinrange"
+msgstr "%s found in range"
+
+#: controllers/statistics_controller.php:270
+#, fuzzy
+msgid "statistics_js_plotselection_options_addplot_name"
+msgstr "Add Plot"
+
+#: controllers/statistics_controller.php:271
+#, fuzzy
+msgid "statistics_js_plotselection_options_addplot_tooltip"
+msgstr "Add another plot to this graph"
+
+#: controllers/statistics_controller.php:261
+#, fuzzy
+msgid "statistics_js_plotselection_options_count_name_checked"
+msgstr "Hide Total Count"
+
+#: controllers/statistics_controller.php:262
+#, fuzzy
+msgid "statistics_js_plotselection_options_count_name_unchecked"
+msgstr "Show Total Count"
+
+#: controllers/statistics_controller.php:263
+#, fuzzy
+msgid "statistics_js_plotselection_options_count_tooltip"
+msgstr "Plot the total count on this graph"
+
+#: controllers/statistics_controller.php:275
+#, fuzzy
+msgid "statistics_js_plotselection_options_csv_name"
+msgstr "View Data (CSV)"
+
+#: controllers/statistics_controller.php:276
+#, fuzzy
+msgid "statistics_js_plotselection_options_csv_tooltip"
+msgstr "Get a Comma Separated Values file of this data"
+
+#: controllers/statistics_controller.php:267
+#, fuzzy
+msgid "statistics_js_plotselection_options_events_addon_name_checked"
+msgstr "Hide %s Events"
+
+#: controllers/statistics_controller.php:268
+#, fuzzy
+msgid "statistics_js_plotselection_options_events_addon_name_unchecked"
+msgstr "Show %s Events"
+
+#: controllers/statistics_controller.php:269
+#, fuzzy
+msgid "statistics_js_plotselection_options_events_addon_tooltip"
+msgstr "Overlay add-on release dates on the plots"
+
+#: controllers/statistics_controller.php:264
+#, fuzzy
+msgid "statistics_js_plotselection_options_events_firefox_name_checked"
+msgstr "Hide Firefox Events"
+
+#: controllers/statistics_controller.php:265
+#, fuzzy
+msgid "statistics_js_plotselection_options_events_firefox_name_unchecked"
+msgstr "Show Firefox Events"
+
+#: controllers/statistics_controller.php:266
+#, fuzzy
+msgid "statistics_js_plotselection_options_events_firefox_tooltip"
+msgstr "Overlay Firefox release dates on the plots"
+
+#: controllers/statistics_controller.php:272
+#, fuzzy
+msgid "statistics_js_plotselection_options_resize_name_checked"
+msgstr "Collapse Graph"
+
+#: controllers/statistics_controller.php:273
+#, fuzzy
+msgid "statistics_js_plotselection_options_resize_name_unchecked"
+msgstr "Expand Graph"
+
+#: controllers/statistics_controller.php:274
+#, fuzzy
+msgid "statistics_js_plotselection_options_resize_tooltip"
+msgstr "Resize the graph"
+
+#: controllers/statistics_controller.php:254
+#, fuzzy
+msgid "statistics_js_plotselection_selector_adu"
+msgstr "Active Daily Users"
+
+#: controllers/statistics_controller.php:256
+#, fuzzy
+msgid "statistics_js_plotselection_selector_application"
+msgstr "Application"
+
+#: controllers/statistics_controller.php:259
+#, fuzzy
+msgid "statistics_js_plotselection_selector_custom"
+msgstr "Custom"
+
+#: controllers/statistics_controller.php:253
+#, fuzzy
+msgid "statistics_js_plotselection_selector_downloads"
+msgstr "Downloads"
+
+#: controllers/statistics_controller.php:258
+#, fuzzy
+msgid "statistics_js_plotselection_selector_os"
+msgstr "Operating System"
+
+#: controllers/statistics_controller.php:257
+#, fuzzy
+msgid "statistics_js_plotselection_selector_status"
+msgstr "Add-on Status"
+
+#: controllers/statistics_controller.php:252
+#, fuzzy
+msgid "statistics_js_plotselection_selector_summary"
+msgstr "Summary"
+
+#: controllers/statistics_controller.php:255
+#, fuzzy
+msgid "statistics_js_plotselection_selector_version"
+msgstr "Add-on Version"
+
+#: controllers/components/stats.php:398
+#, fuzzy
+msgid "statistics_longnames_application"
+msgstr "Application"
+
+#: controllers/components/stats.php:400
+#, fuzzy
+msgid "statistics_longnames_os"
+msgstr "Operating System"
+
+#: controllers/components/stats.php:399
+#, fuzzy
+msgid "statistics_longnames_status"
+msgstr "Add-on Status"
+
+#: controllers/components/stats.php:401
+#, fuzzy
+msgid "statistics_longnames_unknown"
+msgstr "Unknown"
+
+#: controllers/components/stats.php:397
+#, fuzzy
+msgid "statistics_longnames_version"
+msgstr "Add-on Version"
+
+#: views/statistics/addon.thtml:118
+#, fuzzy
+msgid "statistics_notice_data_insufficient"
+msgstr ""
+"There is not yet enough data to display this graph. Please check back later."
+
+#: views/statistics/addon.thtml:130
+#, fuzzy
+msgid "statistics_notice_data_none"
+msgstr ""
+"We don't have any data for your add-on yet. Please check back in a few days."
+
+#: views/statistics/addon.thtml:41
+#, fuzzy
+msgid "statistics_notice_data_updating"
+msgstr ""
+"Add-on statistics are currently in the process of being updated. Recent data "
+"may be incomplete as our scripts work to update this information. Please "
+"check back in a few minutes."
+
+#: views/statistics/addon.thtml:136
+#, fuzzy
+msgid "statistics_notice_disabled"
+msgstr ""
+"The Statistics Dashboard is currently disabled. Please check back later."
+
+#: views/statistics/addon.thtml:123
+#, fuzzy
+msgid "statistics_notice_nojavascript"
+msgstr "JavaScript is required to view the Statistics Dashboard graphs."
+
+#: views/statistics/addon.thtml:44
+#, fuzzy
+msgid "statistics_notice_settings_updated"
+msgstr "Your settings have been updated!"
+
+#: controllers/statistics_controller.php:60
+#: controllers/statistics_controller.php:71
+#: controllers/statistics_controller.php:74
+#: controllers/statistics_controller.php:240
+#, fuzzy
+msgid "statistics_pagetitle"
+msgstr "Statistics Dashboard"
+
+#: views/statistics/addon.thtml:99
+#, fuzzy
+msgid "statistics_plot_legend_adu"
+msgstr "Active Daily Users"
+
+#: views/statistics/addon.thtml:95
+#, fuzzy
+msgid "statistics_plot_legend_downloads"
+msgstr "Daily Downloads"
+
+#: views/statistics/addon.thtml:107
+#, fuzzy
+msgid "statistics_plot_options_zoomin_alt"
+msgstr "Zoom In"
+
+#: views/statistics/addon.thtml:106
+#, fuzzy
+msgid "statistics_plot_options_zoomin_title"
+msgstr "Zoom in one month"
+
+#: views/statistics/addon.thtml:110
+#, fuzzy
+msgid "statistics_plot_options_zoomout_alt"
+msgstr "Zoom Out"
+
+#: views/statistics/addon.thtml:109
+#, fuzzy
+msgid "statistics_plot_options_zoomout_title"
+msgstr "Zoom out one month"
+
+#: controllers/statistics_controller.php:283
+#, fuzzy, php-format
+msgid "statistics_rss_description"
+msgstr "Daily summary of statistics for %1$s"
+
+#: views/statistics/rss/summary.thtml:68
+#, fuzzy
+msgid "statistics_rss_title_fulldate"
+msgstr "%A, %B %e, %Y"
+
+#: views/statistics/rss/summary.thtml:68
+#, fuzzy, php-format
+msgid "statistics_rss_title_statsfordate"
+msgstr "Statistics for %1$s"
+
+#: views/statistics/settings.thtml:49
+#, fuzzy
+msgid "statistics_settings_access_description"
+msgstr ""
+"By default, only you and Mozilla can access the information in your "
+"dashboard. You can open this up to the public so that anyone can view your "
+"add-on's data."
+
+#: views/statistics/settings.thtml:48
+#, fuzzy
+msgid "statistics_settings_access_heading"
+msgstr "Dashboard Access"
+
+#: views/statistics/settings.thtml:51
+#, fuzzy
+msgid "statistics_settings_access_private"
+msgstr "Private"
+
+#: views/statistics/settings.thtml:51
+#, fuzzy
+msgid "statistics_settings_access_private_description"
+msgstr "Only you and Mozilla can view this add-on's statistics"
+
+#: views/statistics/settings.thtml:52
+#, fuzzy
+msgid "statistics_settings_access_public"
+msgstr "Public"
+
+#: views/statistics/settings.thtml:52
+#, fuzzy
+msgid "statistics_settings_access_public_description"
+msgstr "Anyone can view this add-on's statistics"
+
+#: views/statistics/addon.thtml:251
+#, fuzzy
+msgid "statistics_settings_change_link"
+msgstr "Change Settings"
+
+#: views/statistics/addon.thtml:253
+#, fuzzy
+msgid "statistics_settings_confidential"
+msgstr "Please treat this information as confidential."
+
+#: views/statistics/addon.thtml:245
+#, fuzzy
+msgid "statistics_settings_currently_private"
+msgstr "This dashboard is currently <b>private</b>."
+
+#: views/statistics/addon.thtml:241
+#, fuzzy
+msgid "statistics_settings_currently_public"
+msgstr "This dashboard is currently <b>public</b>."
+
+#: views/statistics/addon.thtml:246
+#, fuzzy
+msgid "statistics_settings_locked_alt"
+msgstr "Locked"
+
+#: views/statistics/settings.thtml:57
+#, fuzzy
+msgid "statistics_settings_return_link"
+msgstr "Return to Dashboard"
+
+#: views/statistics/settings.thtml:56
+#, fuzzy
+msgid "statistics_settings_save_button"
+msgstr "Save Settings"
+
+#: views/statistics/settings.thtml:46
+#, fuzzy, php-format
+msgid "statistics_settings_title"
+msgstr "Statistics Dashboard Settings for %1$s"
+
+#: views/statistics/addon.thtml:242
+#, fuzzy
+msgid "statistics_settings_unlocked_alt"
+msgstr "Unlocked"
+
+#: controllers/components/stats.php:405
+#, fuzzy
+msgid "statistics_shortnames_application"
+msgstr "App"
+
+#: controllers/components/stats.php:407
+#, fuzzy
+msgid "statistics_shortnames_os"
+msgstr "OS"
+
+#: controllers/components/stats.php:406
+#, fuzzy
+msgid "statistics_shortnames_status"
+msgstr "St"
+
+#: controllers/components/stats.php:408
+#, fuzzy
+msgid "statistics_shortnames_unknown"
+msgstr "Uk"
+
+#: controllers/components/stats.php:404
+#, fuzzy
+msgid "statistics_shortnames_version"
+msgstr "Ver"
+
+#: views/statistics/rss/summary.thtml:42 views/statistics/addon.thtml:192
+#, fuzzy
+msgid "statistics_summary_downloads_average"
+msgstr "Average Daily Downloads"
+
+#: views/statistics/rss/summary.thtml:39
+#, fuzzy
+msgid "statistics_summary_downloads_heading"
+msgstr "Downloads"
+
+#: views/statistics/rss/summary.thtml:41 views/statistics/addon.thtml:171
+#, fuzzy
+msgid "statistics_summary_downloads_lastcount"
+msgstr "Last Day Count"
+
+#: views/statistics/rss/summary.thtml:43 views/statistics/addon.thtml:199
+#, fuzzy
+msgid "statistics_summary_downloads_lastweek"
+msgstr "Downloads in the last 7 days"
+
+#: views/statistics/rss/summary.thtml:40 views/statistics/addon.thtml:151
+#, fuzzy
+msgid "statistics_summary_downloads_total"
+msgstr "Total Downloads"
+
+#: views/statistics/rss/summary.thtml:40 views/statistics/addon.thtml:152
+#, fuzzy, php-format
+msgid "statistics_summary_downloads_total_sincedate"
+msgstr "Since %1$s"
+
+#: views/statistics/rss/summary.thtml:50 views/statistics/rss/summary.thtml:56
+#: views/statistics/addon.thtml:163 views/statistics/addon.thtml:183
+#, fuzzy
+msgid "statistics_summary_nodata"
+msgstr "No data yet"
+
+#: views/statistics/rss/summary.thtml:60 views/statistics/addon.thtml:195
+#, fuzzy
+msgid "statistics_summary_updatepings_average"
+msgstr "Average Daily Active Users"
+
+#: views/statistics/rss/summary.thtml:52 views/statistics/addon.thtml:177
+#, fuzzy
+msgid "statistics_summary_updatepings_changefromprevious"
+msgstr "Change from previous count"
+
+#: views/statistics/rss/summary.thtml:54 views/statistics/addon.thtml:181
+#, fuzzy, php-format
+msgid "statistics_summary_updatepings_changefromprevious_ondate"
+msgstr "%1$s on %2$s"
+
+#: views/statistics/rss/summary.thtml:45
+#, fuzzy
+msgid "statistics_summary_updatepings_heading"
+msgstr "Active Daily Users"
+
+#: views/statistics/rss/summary.thtml:46 views/statistics/addon.thtml:157
+#, fuzzy
+msgid "statistics_summary_updatepings_total"
+msgstr "Active Daily Users"
+
+#: views/statistics/rss/summary.thtml:48 views/statistics/addon.thtml:161
+#, fuzzy, php-format
+msgid "statistics_summary_updatepings_total_ondate"
+msgstr "On %1$s"
+
+#: views/statistics/rss/summary.thtml:61 views/statistics/addon.thtml:203
+#, fuzzy
+msgid "statistics_summary_updatepings_weekly_average"
+msgstr "Average Daily Users this Week"
+
+#. %s is a percentage, like '+22.33%'. It sits next to another number, so
+#. the implied meaning is 'percentage change' from the previous stat point.
+#: views/statistics/rss/summary.thtml:62 views/statistics/addon.thtml:205
+#, fuzzy
+msgid "statistics_summary_updatepings_weekly_change"
+msgstr "%s from last week"
+
+#: views/statistics/addon.thtml:65 controllers/statistics_controller.php:184
+#: controllers/statistics_controller.php:282
+#, fuzzy, php-format
+msgid "statistics_title_addon_stats"
+msgstr "%1$s Statistics"
+
+#: views/addons/themes_landing.thtml:113
+#, fuzzy
+msgid "themes_landing_all_themes"
+msgstr "All Themes"
+
+#: views/addons/themes_landing.thtml:109
+#, fuzzy
+msgid "themes_landing_browse_themes"
+msgstr "Browse Themes"
+
+#: views/users/edit.thtml:185
+#, fuzzy
+msgid "user_change_email"
+msgstr "Change Email Address"
+
+#: views/users/edit.thtml:169
+#, fuzzy
+msgid "user_change_password"
+msgstr "Change password"
+
+#: views/users/edit.thtml:96
+#, fuzzy
+msgid "user_change_password_or_email"
+msgstr "Change Password or Email"
+
+#: controllers/users_controller.php:197
+#, fuzzy
+msgid "user_confirmationcode_resent"
+msgstr "The confirmation code was resent!"
+
+#. %1 is the email address, %2 is the URL of the user registration page
+#: views/users/delete.thtml:51
+#, fuzzy
+msgid "user_del_account_deleted"
+msgstr ""
+"Your user account %1$s has been successfully deleted. If you want to come "
+"back some time, you can re-register on the <a href=\"%2$s\">user "
+"registration page</a>."
+
+#: views/users/delete.thtml:102
+#, fuzzy
+msgid "user_del_community_sad"
+msgstr "The Mozilla Add-ons community is sad to see you go."
+
+#: views/users/delete.thtml:123
+#, fuzzy
+msgid "user_del_confirm_password"
+msgstr "Confirm Password"
+
+#: views/users/delete.thtml:134
+#, fuzzy
+msgid "user_del_deletenow"
+msgstr "Delete my user account now"
+
+#. %1 is the URL of the user's info page
+#: views/users/delete.thtml:64
+#, fuzzy
+msgid "user_del_error_addons"
+msgstr ""
+"You cannot delete your account if you are listed as an <a href=\"%1$s"
+"\">author of any add-ons</a>. To delete your account, please have another "
+"person in your development group delete you from the list of authors for "
+"your add-ons. Afterwards you will be able to delete your account here."
+
+#. %1 is a link to the amo-editors mailing list
+#: views/users/delete.thtml:71
+#, fuzzy
+msgid "user_del_error_addons_more_questions"
+msgstr "If you have additional questions, please contact %1$s for assistance."
+
+#: views/users/delete.thtml:78
+#, fuzzy
+msgid "user_del_error_checkbox"
+msgstr ""
+"You need to check the box \"I understand...\" before we can delete your "
+"account."
+
+#: views/users/delete.thtml:84
+#, fuzzy
+msgid "user_del_error_password"
+msgstr "Please enter your password correctly in order to perform this step."
+
+#. %1 is a link to the amo-admins mailing list
+#: views/users/delete.thtml:91
+#, fuzzy
+msgid "user_del_error_unknown"
+msgstr ""
+"An unknown error occured deleting your account. Please contact %1$s with the "
+"issue and we will delete it for you. We apologize for the inconvenience."
+
+#: views/users/delete.thtml:110
+#, fuzzy
+msgid "user_del_header_confirm_deletion"
+msgstr "Confirm account deletion"
+
+#. %1 is the user's email address
+#: views/users/delete.thtml:100
+#, fuzzy
+msgid "user_del_header_delete_account"
+msgstr "Delete User Account %1$s"
+
+#: views/users/delete.thtml:50
+#, fuzzy
+msgid "user_del_header_farewell"
+msgstr "Farewell!"
+
+#: views/users/delete.thtml:115
+#, fuzzy
+msgid "user_del_nologin"
+msgstr "You will not be able to log into Mozilla Add-ons anymore."
+
+#: views/users/delete.thtml:112
+#, fuzzy
+msgid "user_del_permanently_removed_means"
+msgstr ""
+"By clicking \"delete\" your account is going to be <strong>permanently "
+"removed</strong>. That means:"
+
+#: views/users/delete.thtml:116
+#, fuzzy
+msgid "user_del_reviews_anonymized"
+msgstr ""
+"Your reviews and ratings will not be deleted, but they will no longer be "
+"associated with you."
+
+#. %1 is a link to the amo-editors mailing list
+#: views/users/delete.thtml:104
+#, fuzzy
+msgid "user_del_specific_problem_editors"
+msgstr ""
+"If you have a specific problem we may help you with, please do not delete "
+"your account now, but contact us at %1$s and we will do our best to assist "
+"you in solving it."
+
+#: views/users/delete.thtml:130
+#, fuzzy
+msgid "user_del_understand_permanent"
+msgstr "I understand that this step cannot be undone."
+
+#: views/helpers/addons_html.php:192
+#, fuzzy
+msgid "user_deleted_nickname"
+msgstr "Deleted User"
+
+#. %1 is the new email address
+#: views/users/edit.thtml:71
+#, fuzzy
+msgid "user_edit_confirm_email_sent"
+msgstr ""
+"An email has been sent to %1$s to confirm your new email address. For the "
+"change to take effect, you need to click on the link provided in this email. "
+"Until then, you can keep logging in with your current email address."
+
+#: views/users/edit.thtml:201
+#, fuzzy
+msgid "user_edit_delete_user"
+msgstr "Delete user account"
+
+#. This contains the email sent to users when they signed up for a new
+#. account:
+#. %1 is the confirmation URL, %2 is the current app
+#: views/users/email/confirm_plain.thtml:6
+#, fuzzy, php-format
+msgid "user_email_confirm_account_nopass"
+msgstr ""
+"Welcome to %2$s Add-ons.\n"
+"\n"
+"Before you can use your new account you must activate it - this ensures the "
+"e-mail address you used is valid and belongs to you.\n"
+"To activate your account, click the link below or copy and paste the whole "
+"thing into your browser's location bar:\n"
+"\n"
+"%1$s\n"
+"\n"
+"Once you successfully activated your account, you can throw away this e-"
+"mail.\n"
+"\n"
+"Thanks for joining %2$s Add-ons\n"
+"-- %2$s Add-ons Staff"
+
+#. %1 is the confirmation url, %2 is the application name
+#: views/users/email/emailchange_plain.thtml:5
+#, fuzzy
+msgid "user_email_confirm_emailchange"
+msgstr ""
+"You requested a change to your email address at %2$s Add-ons.\n"
+"\n"
+"In order to confirm the new address, please click the link below or copy and "
+"paste the whole thing into your browser's location bar:\n"
+"\n"
+"%1$s\n"
+"\n"
+"You have 48 hours to confirm the new address. If you do not want to change "
+"the address anymore, you can just ignore this email.\n"
+"\n"
+"Thanks!\n"
+"-- %2$s Add-ons Staff"
+
+#: controllers/users_controller.php:168
+#, fuzzy, php-format
+msgid "user_email_confirm_subject"
+msgstr "Thanks for joining %s Add-ons"
+
+#. This is the password reset email
+#. %1 is the pw reset URL, %2 is the application
+#: views/users/email/pwreset_plain.thtml:5
+#, fuzzy, php-format
+msgid "user_email_pwreset"
+msgstr ""
+"%2$s Add-ons Password Reset\n"
+"\n"
+"A request was received to reset the password for this account on addons."
+"mozilla.org. To change this password please click on the following link, or "
+"paste it into your browser's location bar:\n"
+"\n"
+"%1$s\n"
+"\n"
+"If you did not request this email there is no need for further action.\n"
+"\n"
+"Thanks,\n"
+"-- %2$s Add-ons Staff"
+
+#: controllers/users_controller.php:245
+#, fuzzy, php-format
+msgid "user_email_pwreset_subject"
+msgstr "Reset your %s Add-ons password"
+
+#: views/users/emailchange.thtml:50
+#, fuzzy
+msgid "user_emailchange_error"
+msgstr "Error!"
+
+#. %1 is the application name
+#: controllers/users_controller.php:533
+#, fuzzy
+msgid "user_emailchange_subject"
+msgstr "Please confirm your email address change at %1$s Add-ons"
+
+#: views/users/emailchange.thtml:48
+#, fuzzy
+msgid "user_emailchange_success"
+msgstr "Success!"
+
+#. %1 is the new email address
+#: views/users/emailchange.thtml:49
+#, fuzzy
+msgid "user_emailchange_successful_description"
+msgstr ""
+"Your email address was changed successfully. From now on, please use %1$s to "
+"log in."
+
+#: views/users/edit.thtml:134 views/admin/users_edit.thtml:111
+#, fuzzy
+msgid "user_form_bio"
+msgstr "About me"
+
+#: views/users/edit.thtml:135 views/admin/users_edit.thtml:112
+#, fuzzy
+msgid "user_form_bio_description"
+msgstr ""
+"Introduce yourself to the community, if you like! This text will appear "
+"publicly on your user info page. Line breaks will be preserved, but no HTML "
+"is allowed."
+
+#: views/users/pwreset.thtml:77 views/users/register.thtml:73
+#: views/users/edit.thtml:181
+#, fuzzy
+msgid "user_form_confirmpassword"
+msgstr "Confirm password"
+
+#: views/users/edit.thtml:145
+#, fuzzy
+msgid "user_form_display_collections"
+msgstr "Display the collections I have created in my user profile"
+
+#: views/users/edit.thtml:149
+#, fuzzy
+msgid "user_form_display_collections_fav"
+msgstr "Display my favorite collections in my user profile"
+
+#: views/users/edit.thtml:86
+#, fuzzy, php-format
+msgid "user_form_editprofile"
+msgstr "Edit user profile for %s"
+
+#: views/users/pwreset.thtml:52 views/users/login.thtml:81
+#: views/users/register.thtml:63 views/users/edit.thtml:187
+#, fuzzy
+msgid "user_form_email"
+msgstr "Email address"
+
+#: views/users/register.thtml:78 views/users/edit.thtml:103
+#: views/admin/users_edit.thtml:76
+#, fuzzy
+msgid "user_form_firstname"
+msgstr "First name"
+
+#: views/users/register.thtml:94 views/users/edit.thtml:119
+#: views/admin/users_edit.thtml:91
+#, fuzzy
+msgid "user_form_hideemail"
+msgstr "Hide email address"
+
+#: views/users/register.thtml:98 views/users/edit.thtml:123
+#: views/admin/users_edit.thtml:99
+#, fuzzy
+msgid "user_form_homepage"
+msgstr "Website URL"
+
+#: views/users/register.thtml:84 views/users/edit.thtml:109
+#: views/admin/users_edit.thtml:81
+#, fuzzy
+msgid "user_form_lastname"
+msgstr "Last name"
+
+#: controllers/users_controller.php:333
+#, fuzzy
+msgid "user_form_login"
+msgstr "User Login"
+
+#: views/users/pwreset.thtml:72 views/users/edit.thtml:176
+#, fuzzy
+msgid "user_form_newpassword"
+msgstr "New password"
+
+#: views/users/register.thtml:89 views/users/edit.thtml:114
+#: views/admin/users_edit.thtml:86
+#, fuzzy
+msgid "user_form_nickname"
+msgstr "Nickname"
+
+#: views/users/edit.thtml:171
+#, fuzzy
+msgid "user_form_oldpassword"
+msgstr "Old password"
+
+#: views/users/edit.thtml:97 views/users/edit.thtml:200
+#, fuzzy
+msgid "user_form_otheractions"
+msgstr "Other Actions"
+
+#: views/users/login.thtml:85 views/users/register.thtml:68
+#, fuzzy
+msgid "user_form_password"
+msgstr "Password"
+
+#: controllers/users_controller.php:93
+#, fuzzy
+msgid "user_form_registration"
+msgstr "New User Registration"
+
+#: views/users/login.thtml:90
+#, fuzzy
+msgid "user_form_remember_me"
+msgstr "Remember me on this computer"
+
+#: views/admin/users_edit.thtml:95
+#, fuzzy
+msgid "user_form_showsandbox"
+msgstr "Show sandbox?"
+
+#: views/users/edit.thtml:205
+#, fuzzy
+msgid "user_form_submit_edit"
+msgstr "Save"
+
+#: views/users/login.thtml:93
+#, fuzzy
+msgid "user_form_submit_login"
+msgstr "Log in"
+
+#: views/users/register.thtml:113
+#, fuzzy
+msgid "user_form_submit_register"
+msgstr "Register"
+
+#: views/users/info.thtml:75
+#, fuzzy, php-format
+msgid "user_info_usersince"
+msgstr "%s Add-ons user since"
+
+#: views/users/login.thtml:102
+#, fuzzy
+msgid "user_login_register_link"
+msgstr "Create a new user account"
+
+#: views/users/edit.thtml:160
+#, fuzzy
+msgid "user_notifications_item_compat"
+msgstr "Add-on Compatibility (strongly recommended)"
+
+#: views/users/edit.thtml:161
+#, fuzzy
+msgid "user_notifications_item_events"
+msgstr "Upcoming events and contests"
+
+#: views/users/edit.thtml:156
+#, fuzzy
+msgid "user_notifications_none_available"
+msgstr "There are currently no notifications available for you to configure."
+
+#: views/users/edit.thtml:158
+#, fuzzy
+msgid "user_notifications_select_topics"
+msgstr ""
+"From time to time, Mozilla may send you email about upcoming releases and "
+"add-on events. Please select the topics you are interested in below:"
+
+#: views/users/edit.thtml:164
+#, fuzzy
+msgid "user_notifications_specific_contact"
+msgstr ""
+"Mozilla reserves the right to contact you individually about specific "
+"concerns with your hosted add-ons."
+
+#: controllers/users_controller.php:543
+#, fuzzy
+msgid "user_profile_edit_error"
+msgstr ""
+"There were errors in the changes you made. Please correct them and resubmit."
+
+#: controllers/users_controller.php:540
+#, fuzzy
+msgid "user_profile_saved"
+msgstr "Profile updated."
+
+#: views/users/pwreset.thtml:65
+#, fuzzy, php-format
+msgid "user_pwreset_for_email"
+msgstr "Password reset for %s"
+
+#: controllers/users_controller.php:226
+#, fuzzy
+msgid "user_pwreset_header"
+msgstr "Password Reset"
+
+#: views/users/login.thtml:103
+#, fuzzy
+msgid "user_pwreset_link"
+msgstr "Forgot your password?"
+
+#: controllers/users_controller.php:248
+#, fuzzy
+msgid "user_pwreset_link_sent"
+msgstr "The password reset link was sent to your email address."
+
+#: controllers/users_controller.php:304
+#, fuzzy
+msgid "user_pwreset_okay"
+msgstr "Password successfully reset."
+
+#: views/users/pwreset.thtml:82
+#, fuzzy
+msgid "user_pwreset_submit_changepw"
+msgstr "Submit password change"
+
+#: views/users/pwreset.thtml:57
+#, fuzzy
+msgid "user_pwreset_submit_sendlink"
+msgstr "Send password reset link"
+
+#: views/users/register_complete.thtml:51
+#, fuzzy, php-format
+msgid "user_register_amo_link"
+msgstr "%s Add-ons"
+
+#. %1 is the user's email address, %2 is the current app
+#: views/users/activatefirst.thtml:49
+#, fuzzy, php-format
+msgid "user_register_click_confirm_link"
+msgstr ""
+"A link to activate your user account was sent by email to your address %1$s. "
+"You have to click it before you can log into %2$s Add-ons."
+
+#. %1 is the user's email address
+#: views/users/register_complete.thtml:49
+#, fuzzy, php-format
+msgid "user_register_confirm_email_sent"
+msgstr ""
+"An email has been sent to your address %1$s to confirm your account. Before "
+"you can log in, you have to activate your account by clicking on the link "
+"provided in this email."
+
+#: views/users/activatefirst.thtml:51
+#, fuzzy
+msgid "user_register_confirmation_link_text"
+msgstr "resend the confirmation message"
+
+#: views/users/register_complete.thtml:47
+#, fuzzy
+msgid "user_register_congratulations"
+msgstr "Congratulations! Your user account was successfully created."
+
+#: views/users/register.thtml:50
+#, fuzzy
+msgid "user_register_details"
+msgstr ""
+"<p>Registration on AMO is <strong>not required</strong> if you simply want "
+"to download and install public add-ons.</p><p>You only need to register if:</"
+"p><ul><li>You want to submit reviews for add-ons</li><li>You are an add-on "
+"developer and want to upload your add-on for hosting on AMO</li></ul><p>Upon "
+"successful registration, you will be sent a confirmation email to the "
+"address you provided. Please follow the instructions there to confirm your "
+"account.</p><p>If you like, you can read our <a href='%1$s' title='Legal "
+"Notices'>Legal Notices</a> and <a href='%2$s' title='Privacy Policy'>Privacy "
+"Policy</a>.</p>"
+
+#. %1 is the link to the "resend confirmation code" page
+#: views/users/activatefirst.thtml:51
+#, fuzzy, php-format
+msgid "user_register_resend_confirmation_link"
+msgstr ""
+"If you did not receive the confirmation email, make sure your email service "
+"did not mark it as \"junk mail\" or \"spam\". If you need to, you can have "
+"us %1$s to your email address mentioned above."
+
+#. %1 is the link to the Mozilla Add-ons front page
+#: views/users/register_complete.thtml:51
+#, fuzzy, php-format
+msgid "user_register_welcome"
+msgstr "Thanks for registering and welcome to %1$s!"
+
+#: views/users/register.thtml:49
+#, fuzzy
+msgid "user_register_welcome_header"
+msgstr "Welcome to addons.mozilla.org (AMO)!"
+
+#: views/users/register.thtml:81 views/users/edit.thtml:106
+#, fuzzy
+msgid "user_required_firstlast_or_nickname"
+msgstr "A first name, last name or nickname is required."
+
+#: views/users/edit.thtml:94 views/users/edit.thtml:142
+#, fuzzy
+msgid "user_tab_collections"
+msgstr "Collections"
+
+#: views/users/edit.thtml:95 views/users/edit.thtml:154
+#, fuzzy
+msgid "user_tab_notifications"
+msgstr "Notifications"
+
+#: views/users/edit.thtml:93 views/users/edit.thtml:101
+#, fuzzy
+msgid "user_tab_profile"
+msgstr "User Profile"
+
+#: controllers/users_controller.php:209
+#, fuzzy
+msgid "user_verified_okay"
+msgstr "Successfully verified!"
+
+#: controllers/users_controller.php:723
+#, fuzzy
+msgid "users_delete_pagetitle"
+msgstr "Delete User Account"
+
+#: controllers/users_controller.php:414
+#, fuzzy
+msgid "users_edit_pagetitle"
+msgstr "User Account Editing"
+
+#: views/users/info.thtml:71
+#, fuzzy
+msgid "users_info_aboutme"
+msgstr "About Me"
+
+#: views/users/info.thtml:96
+#, fuzzy, php-format
+msgid "users_info_addons_by_user"
+msgstr "Add-ons by %1$s"
+
+#: views/users/info.thtml:51
+#, fuzzy
+msgid "users_info_author_name"
+msgstr "Name"
+
+#: views/users/info.thtml:48
+#, fuzzy
+msgid "users_info_author_profile"
+msgstr "User Profile"
+
+#. %s is the user name
+#: views/users/info.thtml:137
+#, fuzzy
+msgid "users_info_collections_by_user"
+msgstr "Collections by %s"
+
+#: views/users/info.thtml:66
+#, fuzzy
+msgid "users_info_email"
+msgstr "Email address"
+
+#: views/users/info.thtml:155
+#, fuzzy
+msgid "users_info_fav_collections_by_user"
+msgstr "Favorite Collections"
+
+#: views/users/info.thtml:61
+#, fuzzy
+msgid "users_info_homepage"
+msgstr "Homepage"
+
+#: views/users/info.thtml:56
+#, fuzzy
+msgid "users_info_nickname"
+msgstr "Nickname"
+
+#: controllers/users_controller.php:707
+#, fuzzy, php-format
+msgid "users_info_pagetitle"
+msgstr "User Info for %1$s"
+
+#. %1 is the user's name
+#: views/users/info.thtml:116
+#, fuzzy
+msgid "users_info_reviews_by_user"
+msgstr "Reviews by %s"
+
+#: controllers/users_controller.php:330 controllers/users_controller.php:332
+#, fuzzy
+msgid "users_login_pagetitle"
+msgstr "User Login"
+
+#. %1 is the link to the sandbox/policy explanation page
+#. This message is for a specific add-on not found
+#: views/users/login.thtml:53
+#, fuzzy, php-format
+msgid "users_login_sandbox_display_warning"
+msgstr ""
+"The add-on you're looking for is currently in the sandbox. If you already "
+"have an account on Mozilla Add-ons, please log in, or <a href=\"%1$s\">learn "
+"more about the sandbox.</a>"
+
+#. %1 is the link to the sandbox/policy explanation page
+#. This message is for any given sandbox-related page not found
+#: views/users/login.thtml:56
+#, fuzzy, php-format
+msgid "users_login_sandbox_page_warning"
+msgstr ""
+"The page you're looking for is part of the sandbox. If you already have an "
+"account on Mozilla Add-ons, please log in, or <a href=\"%1$s\">learn more "
+"about the sandbox.</a>"
+
+#: controllers/users_controller.php:223 controllers/users_controller.php:225
+#, fuzzy
+msgid "users_pwreset_pagetitle"
+msgstr "User Password Reset"
+
+#: controllers/users_controller.php:90 controllers/users_controller.php:92
+#, fuzzy
+msgid "users_register_pagetitle"
+msgstr "New User Registration"
+
+#. %1$s is an addon name, like <a>Firebug</a>
+#. %2$s is a version number, like <a>1.2</a>
+#: views/versions/license.thtml:52
+#, fuzzy
+msgid "versions_license_header_source"
+msgstr "Source code license for %1$s %2$s"
+
+#: views/addons/category_landing.thtml:147
+#, fuzzy
+msgid "view_recently_added"
+msgstr "View all recently added"
+
+#: views/addons/category_landing.thtml:161
+#, fuzzy
+msgid "view_top_downloads"
+msgstr "View all top downloads"
+
+#: views/addons/category_landing.thtml:175
+#, fuzzy
+msgid "view_top_rated"
+msgstr "View all top rated"
+
+#, fuzzy
+#~ msgid "addon_slider_tooltip_next"
+#~ msgstr "Next Add-on"
+
+#, fuzzy
+#~ msgid "addon_slider_tooltip_previous"
+#~ msgstr "Previous Add-on"
+
+#, fuzzy
+#~ msgid "addons_display_version_history"
+#~ msgstr "Complete Version History"
+
+#, fuzzy
+#~ msgid "addons_home_newest_header"
+#~ msgstr "Newest:"
+
+#, fuzzy
+#~ msgid "addons_home_popular_header"
+#~ msgstr "Most Popular:"
+
+#, fuzzy
+#~ msgid "addons_home_recommended_header"
+#~ msgstr "We Recommend:"
+
+#, fuzzy
+#~ msgid "addons_home_updated_header"
+#~ msgstr "Recently Updated:"
+
+#, fuzzy
+#~ msgid "addons_home_view_all"
+#~ msgstr "View all"
+
+#, fuzzy
+#~ msgid "category_extra_allrecommended"
+#~ msgstr "See All Recommended Add-ons"
+
+#, fuzzy
+#~ msgid "category_extra_highestrated"
+#~ msgstr "Highest Rated First"
+
+#, fuzzy
+#~ msgid "category_extra_lastupdated"
+#~ msgstr "Last Updated First"
+
+#, fuzzy
+#~ msgid "category_extra_mostpopular"
+#~ msgstr "Most Popular First"
+
+#, fuzzy
+#~ msgid "collections_detail_js_loading"
+#~ msgstr "Loading"
+
+#, fuzzy
+#~ msgid "collections_detail_more_info"
+#~ msgstr "Show More Info"
+
+#, fuzzy
+#~ msgid "devcp_additem_firefox_notice"
+#~ msgstr ""
+#~ "This version of your add-on does not claim compatibility with Firefox %1"
+#~ "$s. Mozilla is expecting the next version of Firefox to be released soon, "
+#~ "so please test your add-on in the new version and update compatibility "
+#~ "information. You can find out more about this <a href=\"%2$s\">here</a>. "
+#~ "This is only a notice and you may continue to submit this version to "
+#~ "addons.mozilla.org."
+
+#, fuzzy
+#~ msgid "devcp_addon_disabled_successfully"
+#~ msgstr "Add-on disabled successfully"
+
+#, fuzzy
+#~ msgid "devcp_addon_edit_pagetitle"
+#~ msgstr "Edit Add-on"
+
+#, fuzzy
+#~ msgid "devcp_addon_enabled_successfully"
+#~ msgstr "Add-on enabled successfully"
+
+#, fuzzy
+#~ msgid "devcp_addon_field_description_displaytitle"
+#~ msgstr "Add-on Description"
+
+#, fuzzy
+#~ msgid "devcp_addon_field_eula_displaytitle"
+#~ msgstr "EULA"
+
+#, fuzzy
+#~ msgid "devcp_addon_field_homepage_displaytitle"
+#~ msgstr "Add-on Homepage"
+
+#, fuzzy
+#~ msgid "devcp_addon_field_name_displaytitle"
+#~ msgstr "Add-on Name"
+
+#, fuzzy
+#~ msgid "devcp_addon_field_privacy_displaytitle"
+#~ msgstr "Privacy Policy"
+
+#, fuzzy
+#~ msgid "devcp_addon_field_summary_displaytitle"
+#~ msgstr "Add-on Summary"
+
+#, fuzzy
+#~ msgid "devcp_addon_field_supportemail_displaytitle"
+#~ msgstr "Support Email"
+
+#, fuzzy
+#~ msgid "devcp_addon_field_supporturl_displaytitle"
+#~ msgstr "Support URL"
+
+#, fuzzy
+#~ msgid "devcp_addon_field_versionnotes_displaytitle"
+#~ msgstr "Version Notes"
+
+#, fuzzy
+#~ msgid "devcp_addon_nominate_pagetitle"
+#~ msgstr "Nominate Add-on"
+
+#, fuzzy
+#~ msgid "devcp_addon_nominated_successfully"
+#~ msgstr "Add-on nominated successfully!"
+
+#, fuzzy
+#~ msgid "devcp_addon_status_criteria_review"
+#~ msgstr "Several user reviews of the add-on (may be external reviews)."
+
+#, fuzzy
+#~ msgid "devcp_addon_submission_makechanges"
+#~ msgstr ""
+#~ "Visit the %1$s page to make changes to your submission, or %2$s to return "
+#~ "to the Developer Tools."
+
+#, fuzzy
+#~ msgid "devcp_addon_submission_makechanges_devcp_link"
+#~ msgstr "click here"
+
+#, fuzzy
+#~ msgid "devcp_addon_submission_makechanges_link"
+#~ msgstr "Edit Add-on"
+
+#, fuzzy
+#~ msgid "devcp_addon_submission_pending"
+#~ msgstr ""
+#~ "This version has been placed in the sandbox while it awaits review from "
+#~ "sandbox testers and a Mozilla Add-ons editor. You will be notified by e-"
+#~ "mail when action has been taken."
+
+#, fuzzy
+#~ msgid "devcp_addon_submission_sandbox_readmore"
+#~ msgstr "You can read more about the Sandbox Review System %s."
+
+#, fuzzy
+#~ msgid "devcp_addon_submission_sandbox_readmore_link"
+#~ msgstr "here"
+
+#, fuzzy
+#~ msgid "devcp_addon_submission_sandboxed"
+#~ msgstr ""
+#~ "This version has been placed in the sandbox for use by experienced users. "
+#~ "In order for it to be shown on the public site, you must %s your add-on "
+#~ "and undergo a review process."
+
+#, fuzzy
+#~ msgid "devcp_addon_submission_sandboxed_nominate_link"
+#~ msgstr "nominate"
+
+#, fuzzy
+#~ msgid "devcp_addon_submission_success"
+#~ msgstr "Your add-on submission has been completed successfully."
+
+#, fuzzy
+#~ msgid "devcp_addon_submission_trusted_public"
+#~ msgstr ""
+#~ "Because your add-on is trusted, this version has automatically been "
+#~ "approved for the public area."
+
+#, fuzzy
+#~ msgid "devcp_addon_submit_pagetitle"
+#~ msgstr "Submit Add-on"
+
+#, fuzzy
+#~ msgid "devcp_addon_updated_successfully"
+#~ msgstr "Add-on updated successfully"
+
+#, fuzzy
+#~ msgid "devcp_addon_upload_preview"
+#~ msgstr "You may wish to %s to increase interest in your add-on."
+
+#, fuzzy
+#~ msgid "devcp_addon_upload_preview_link"
+#~ msgstr "upload a preview"
+
+#, fuzzy
+#~ msgid "devcp_author_lookup_none_found"
+#~ msgstr "No author found [%s]"
+
+#, fuzzy
+#~ msgid "devcp_author_lookup_remove"
+#~ msgstr "Remove"
+
+#, fuzzy
+#~ msgid "devcp_button_cancel"
+#~ msgstr "Cancel"
+
+#, fuzzy
+#~ msgid "devcp_button_cancel_confirm"
+#~ msgstr "Are you sure you wish to cancel your submission?"
+
+#, fuzzy
+#~ msgid "devcp_button_next"
+#~ msgstr "Next"
+
+#, fuzzy
+#~ msgid "devcp_change_addontype"
+#~ msgstr "Change add-on type:"
+
+#, fuzzy
+#~ msgid "devcp_comments_updated"
+#~ msgstr "Developer Comments updated."
+
+#, fuzzy
+#~ msgid "devcp_details_addpreview_link"
+#~ msgstr "Add Preview"
+
+#, fuzzy
+#~ msgid "devcp_details_author"
+#~ msgstr "Author"
+
+#, fuzzy
+#~ msgid "devcp_details_authors"
+#~ msgstr "Authors"
+
+#, fuzzy
+#~ msgid "devcp_details_authors_none"
+#~ msgstr "None"
+
+#, fuzzy
+#~ msgid "devcp_details_categories"
+#~ msgstr "Categories"
+
+#, fuzzy
+#~ msgid "devcp_details_category"
+#~ msgstr "Category"
+
+#, fuzzy
+#~ msgid "devcp_details_description"
+#~ msgstr "Description"
+
+#, fuzzy
+#~ msgid "devcp_details_disabled"
+#~ msgstr "Disabled"
+
+#, fuzzy
+#~ msgid "devcp_details_guid"
+#~ msgstr "GUID"
+
+#, fuzzy
+#~ msgid "devcp_details_header_details"
+#~ msgstr "Details"
+
+#, fuzzy
+#~ msgid "devcp_details_header_devcomments"
+#~ msgstr "Developer Comments"
+
+#, fuzzy
+#~ msgid "devcp_details_header_previews"
+#~ msgstr "Previews"
+
+#, fuzzy
+#~ msgid "devcp_details_header_versions"
+#~ msgstr "Versions"
+
+#, fuzzy
+#~ msgid "devcp_details_homepage"
+#~ msgstr "Homepage"
+
+#, fuzzy
+#~ msgid "devcp_details_homepage_none"
+#~ msgstr "None"
+
+#, fuzzy
+#~ msgid "devcp_details_preview_nocaption"
+#~ msgstr "No caption"
+
+#, fuzzy
+#~ msgid "devcp_details_previews_nonefound"
+#~ msgstr "No previews found."
+
+#, fuzzy
+#~ msgid "devcp_details_submit_update"
+#~ msgstr "Update"
+
+#, fuzzy
+#~ msgid "devcp_details_supportemail"
+#~ msgstr "Support Email"
+
+#, fuzzy
+#~ msgid "devcp_details_supportemail_none"
+#~ msgstr "No support email provided by developer."
+
+#, fuzzy
+#~ msgid "devcp_details_supporturl"
+#~ msgstr "Support URL"
+
+#, fuzzy
+#~ msgid "devcp_details_supporturl_none"
+#~ msgstr "No support url provided by developer."
+
+#, fuzzy
+#~ msgid "devcp_details_trusted"
+#~ msgstr "Trusted"
+
+#, fuzzy
+#~ msgid "devcp_details_versions_none_found"
+#~ msgstr "No versions found."
+
+#, fuzzy
+#~ msgid "devcp_disable_cancel"
+#~ msgstr "Cancel and go back"
+
+#, fuzzy
+#~ msgid "devcp_disable_disable_button"
+#~ msgstr "Yes, disable it"
+
+#, fuzzy
+#~ msgid "devcp_disable_disable_confirm"
+#~ msgstr "Are you sure you want to disable this add-on?"
+
+#, fuzzy
+#~ msgid "devcp_disable_disable_description"
+#~ msgstr ""
+#~ "Disabling this add-on will hide it from searches and listings. It will "
+#~ "not be downloadable from the website and will not be returned in client "
+#~ "update checks. The add-on will effectively be deleted, although you will "
+#~ "be able to return here and re-enable it at your convenience."
+
+#, fuzzy
+#~ msgid "devcp_disable_disable_title"
+#~ msgstr "Disable %s"
+
+#, fuzzy
+#~ msgid "devcp_disable_enable_button"
+#~ msgstr "Yes, enable it"
+
+#, fuzzy
+#~ msgid "devcp_disable_enable_confirm"
+#~ msgstr "Are you sure you want to enable this add-on?"
+
+#, fuzzy
+#~ msgid "devcp_disable_enable_description"
+#~ msgstr ""
+#~ "Enabling this add-on will cause it to once again appear in searches and "
+#~ "listings. It will be downloadable both from the website and from client "
+#~ "update checks."
+
+#, fuzzy
+#~ msgid "devcp_disable_enable_title"
+#~ msgstr "Enable %s"
+
+#, fuzzy
+#~ msgid "devcp_edit_author_add"
+#~ msgstr "Add Author"
+
+#, fuzzy
+#~ msgid "devcp_edit_author_email"
+#~ msgstr "Author's Email Address"
+
+#, fuzzy
+#~ msgid "devcp_edit_author_remove"
+#~ msgstr "Remove"
+
+#, fuzzy
+#~ msgid "devcp_edit_error_categories_unavailable"
+#~ msgstr "No categories available for this add-on type."
+
+#, fuzzy
+#~ msgid "devcp_edit_file_error_incomplete"
+#~ msgstr "Incomplete transfer"
+
+#, fuzzy
+#~ msgid "devcp_edit_file_error_no"
+#~ msgstr "No file uploaded"
+
+#, fuzzy
+#~ msgid "devcp_edit_file_error_size"
+#~ msgstr "Exceeds maximum upload size"
+
+#, fuzzy
+#~ msgid "devcp_edit_header_authors"
+#~ msgstr "Authors"
+
+#, fuzzy
+#~ msgid "devcp_edit_icon_add_link"
+#~ msgstr "Add Icon"
+
+#, fuzzy
+#~ msgid "devcp_edit_icon_change_link"
+#~ msgstr "Change Icon"
+
+#, fuzzy
+#~ msgid "devcp_edit_label_allow_viewsource"
+#~ msgstr "Allow users to view the source files online"
+
+#, fuzzy
+#~ msgid "devcp_edit_label_categories"
+#~ msgstr "Categories"
+
+#, fuzzy
+#~ msgid "devcp_edit_label_defaultlocale"
+#~ msgstr "Default Locale"
+
+#, fuzzy
+#~ msgid "devcp_edit_label_icon_delete"
+#~ msgstr "Only clear the existing icon"
+
+#, fuzzy
+#~ msgid "devcp_edit_label_icon_new"
+#~ msgstr "New Icon File"
+
+#, fuzzy
+#~ msgid "devcp_edit_label_info"
+#~ msgstr "Icon"
+
+#, fuzzy
+#~ msgid "devcp_edit_locale_disambiguation_explanation"
+#~ msgstr "short additional info (such as a local dialect name)"
+
+#, fuzzy
+#~ msgid "devcp_edit_submit_update"
+#~ msgstr "Update"
+
+#, fuzzy
+#~ msgid "devcp_edit_target_locale_explanation"
+#~ msgstr ""
+#~ "<a href=\"http://wiki.mozilla.org/L10n:Simple_locale_names\">simple "
+#~ "locale name</a>, such as 'en-US'"
+
+#, fuzzy
+#~ msgid "devcp_editversion_checkedfiles_delete"
+#~ msgstr "Checked files will be deleted."
+
+#, fuzzy
+#~ msgid "devcp_editversion_filename_size"
+#~ msgstr "%1$s (%2$s)"
+
+#, fuzzy
+#~ msgid "devcp_editversion_label_files"
+#~ msgstr "Files"
+
+#, fuzzy
+#~ msgid "devcp_editversion_label_targetapps"
+#~ msgstr "Target Applications"
+
+#, fuzzy
+#~ msgid "devcp_editversion_nofiles"
+#~ msgstr "No files."
+
+#, fuzzy
+#~ msgid "devcp_editversion_reviewernotes"
+#~ msgstr "Notes to Reviewer"
+
+#, fuzzy
+#~ msgid "devcp_editversion_submit_update"
+#~ msgstr "Update"
+
+#, fuzzy
+#~ msgid "devcp_error_addon_field_summary_toolong"
+#~ msgstr ""
+#~ "Summaries are limited to a maximum of 250 characters.\n"
+#~ "(You entered %s)"
+
+#, fuzzy
+#~ msgid "devcp_error_addonname_not_unique"
+#~ msgstr ""
+#~ "The name for your add-on already exists in the database. Please make sure "
+#~ "that: <br /><li>Your GUIDs match. The most common cause for this error is "
+#~ "mismatched GUIDs.</li><li>You do not have a duplicate entry in the "
+#~ "database. If you do, you should update that entry or delete it and try "
+#~ "again.</li>"
+
+#, fuzzy
+#~ msgid "devcp_error_describe_changes"
+#~ msgstr "Please describe the changes made in this add-on update."
+
+#, fuzzy
+#~ msgid "devcp_error_file_guids_dont_match"
+#~ msgstr "Not all file GUIDs match"
+
+#, fuzzy
+#~ msgid "devcp_error_identical_version_exists"
+#~ msgstr ""
+#~ "An identical version (%s) already exists for this add-on and platform."
+
+#, fuzzy
+#~ msgid "devcp_error_nominate_message"
+#~ msgstr "You must supply the requested details for nomination."
+
+#, fuzzy
+#~ msgid "devcp_error_nominate_no_prerelease"
+#~ msgstr "You cannot nominate a pre-release add-on."
+
+#, fuzzy
+#~ msgid "devcp_error_nominate_sandbox_only"
+#~ msgstr "You can only nominate add-ons currently in the sandbox."
+
+#, fuzzy
+#~ msgid "devcp_error_saving"
+#~ msgstr "An error occurred trying to save your data."
+
+#, fuzzy
+#~ msgid "devcp_error_update_access_denied"
+#~ msgstr "You do not have permission to update this add-on."
+
+#, fuzzy
+#~ msgid "devcp_file_addanother"
+#~ msgstr "Add Another Platform File"
+
+#, fuzzy
+#~ msgid "devcp_form_author_add"
+#~ msgstr "Add Author"
+
+#, fuzzy
+#~ msgid "devcp_form_author_remove"
+#~ msgstr "Remove"
+
+#, fuzzy
+#~ msgid "devcp_form_categories_nextstep"
+#~ msgstr ""
+#~ "Categories for your new add-on type will be available in the next step."
+
+#, fuzzy
+#~ msgid "devcp_form_error_categories_unavailable"
+#~ msgstr "No categories available for this add-on type."
+
+#, fuzzy
+#~ msgid "devcp_form_error_description_notempty"
+#~ msgstr "Please enter a description of your add-on."
+
+#, fuzzy
+#~ msgid "devcp_form_error_name_required"
+#~ msgstr "Please enter the name of your add-on."
+
+#, fuzzy
+#~ msgid "devcp_form_error_select_addontype"
+#~ msgstr "Please select the type of add-on you are submitting."
+
+#, fuzzy
+#~ msgid "devcp_form_error_summary_notempty"
+#~ msgstr "Please enter a summary of your add-on."
+
+#, fuzzy
+#~ msgid "devcp_form_label_addonfile"
+#~ msgstr "Add-on File"
+
+#, fuzzy
+#~ msgid "devcp_form_label_addonfile2"
+#~ msgstr "Add-on File 2"
+
+#, fuzzy
+#~ msgid "devcp_form_label_addonfile3"
+#~ msgstr "Add-on File 3"
+
+#, fuzzy
+#~ msgid "devcp_form_label_addontype"
+#~ msgstr "Add-on Type"
+
+#, fuzzy
+#~ msgid "devcp_form_label_allow_viewsource"
+#~ msgstr "Allow users to view the source files online"
+
+#, fuzzy
+#~ msgid "devcp_form_label_author_email"
+#~ msgstr "Author's Email Address"
+
+#, fuzzy
+#~ msgid "devcp_form_label_authors"
+#~ msgstr "Authors"
+
+#, fuzzy
+#~ msgid "devcp_form_label_categories"
+#~ msgstr "Categories"
+
+#, fuzzy
+#~ msgid "devcp_form_label_defaultlocale"
+#~ msgstr "Default Locale"
+
+#, fuzzy
+#~ msgid "devcp_form_label_description"
+#~ msgstr "Description"
+
+#, fuzzy
+#~ msgid "devcp_form_label_eula"
+#~ msgstr "End-User License Agreement (EULA)"
+
+#, fuzzy
+#~ msgid "devcp_form_label_externalsoftware"
+#~ msgstr "This add-on requires external software"
+
+#, fuzzy
+#~ msgid "devcp_form_label_files"
+#~ msgstr "Files"
+
+#, fuzzy
+#~ msgid "devcp_form_label_homepage"
+#~ msgstr "Homepage"
+
+#, fuzzy
+#~ msgid "devcp_form_label_iconfile"
+#~ msgstr "Icon File"
+
+#, fuzzy
+#~ msgid "devcp_form_label_name"
+#~ msgstr "Name"
+
+#, fuzzy
+#~ msgid "devcp_form_label_platforms"
+#~ msgstr "Supported Platforms"
+
+#, fuzzy
+#~ msgid "devcp_form_label_prerelease"
+#~ msgstr "This is a pre-release"
+
+#, fuzzy
+#~ msgid "devcp_form_label_privacy"
+#~ msgstr "Privacy Policy"
+
+#, fuzzy
+#~ msgid "devcp_form_label_sitespecific"
+#~ msgstr "This is a site-specific add-on"
+
+#, fuzzy
+#~ msgid "devcp_form_label_summary"
+#~ msgstr "Summary"
+
+#, fuzzy
+#~ msgid "devcp_form_label_supportemail"
+#~ msgstr "Support Email"
+
+#, fuzzy
+#~ msgid "devcp_form_label_supporturl"
+#~ msgstr "Support URL"
+
+#, fuzzy
+#~ msgid "devcp_form_label_target_applications"
+#~ msgstr "Target Applications"
+
+#, fuzzy
+#~ msgid "devcp_form_label_version"
+#~ msgstr "Version"
+
+#, fuzzy
+#~ msgid "devcp_form_label_versionnotes"
+#~ msgstr "Version Notes"
+
+#, fuzzy
+#~ msgid "devcp_form_no_target_apps"
+#~ msgstr "None"
+
+#, fuzzy
+#~ msgid "devcp_form_reviewernotes"
+#~ msgstr "Notes to Reviewer"
+
+#, fuzzy
+#~ msgid "devcp_form_trustedaddon_destination"
+#~ msgstr ""
+#~ "Because your add-on is trusted, please choose where this version should "
+#~ "go:"
+
+#, fuzzy
+#~ msgid "devcp_form_trustedaddon_destination_public"
+#~ msgstr "Public"
+
+#, fuzzy
+#~ msgid "devcp_form_trustedaddon_destination_sandbox"
+#~ msgstr "Sandbox"
+
+#, fuzzy
+#~ msgid "devcp_header_developer_agreement"
+#~ msgstr "Developer Agreement"
+
+#, fuzzy
+#~ msgid "devcp_header_step1"
+#~ msgstr "Step 1"
+
+#, fuzzy
+#~ msgid "devcp_header_step1_upload"
+#~ msgstr "Upload File"
+
+#, fuzzy
+#~ msgid "devcp_header_step2"
+#~ msgstr "Step 2"
+
+#, fuzzy
+#~ msgid "devcp_header_step2_addondetails"
+#~ msgstr "Add-on Details"
+
+#, fuzzy
+#~ msgid "devcp_header_step3"
+#~ msgstr "Step 3"
+
+#, fuzzy
+#~ msgid "devcp_header_step3_versiondetails"
+#~ msgstr "Version Details"
+
+#, fuzzy
+#~ msgid "devcp_header_step4"
+#~ msgstr "Step 4"
+
+#, fuzzy
+#~ msgid "devcp_header_step4_localization"
+#~ msgstr "Localization"
+
+#, fuzzy
+#~ msgid "devcp_header_step5"
+#~ msgstr "Step 5"
+
+#, fuzzy
+#~ msgid "devcp_header_step5_success"
+#~ msgstr "Success"
+
+#, fuzzy
+#~ msgid "devcp_index_header_myaddons"
+#~ msgstr "My Add-ons"
+
+#, fuzzy
+#~ msgid "devcp_nominate_link_returnto_details"
+#~ msgstr "Return to add-on details"
+
+#, fuzzy
+#~ msgid "devcp_notice_autodetected_addontype"
+#~ msgstr "Automatically detected add-on type: %s."
+
+#, fuzzy
+#~ msgid "devcp_notice_different_defaultlocale"
+#~ msgstr ""
+#~ "The default locale of this add-on (%1$s [%2$s]) is different from your "
+#~ "currently selected locale (%3$s [%4$s]). The fields below should be "
+#~ "completed in %1$s."
+
+#, fuzzy
+#~ msgid "devcp_question_addontype_incorrect"
+#~ msgstr "Incorrect?"
+
+#, fuzzy
+#~ msgid "devcp_question_delete_file"
+#~ msgstr "Are you sure you want to delete this file?"
+
+#, fuzzy
+#~ msgid "devcp_skip_reviewing_addon_info"
+#~ msgstr "Skip updating my current add-on information"
+
+#, fuzzy
+#~ msgid "devcp_submissions_disabled"
+#~ msgstr ""
+#~ "Add-on submissions are currently disabled. Please check back at a later "
+#~ "time."
+
+#, fuzzy
+#~ msgid "devcp_submit_accept_dev_agreement"
+#~ msgstr "I Accept"
+
+#, fuzzy
+#~ msgid "devcp_submit_decline_dev_agreement"
+#~ msgstr "I Decline"
+
+#, fuzzy
+#~ msgid "devcp_summary_admin_disabled"
+#~ msgstr "This add-on has been disabled by an administrator."
+
+#, fuzzy
+#~ msgid "devcp_summary_header_disabled"
+#~ msgstr "Disabled"
+
+#, fuzzy
+#~ msgid "devcp_summary_header_trusted"
+#~ msgstr "Trusted"
+
+#, fuzzy
+#~ msgid "devcp_summary_noaddons_submit_one"
+#~ msgstr "You don't have any add-ons. Click %s to submit one."
+
+#, fuzzy
+#~ msgid "devcp_summary_noaddons_submit_one_link"
+#~ msgstr "here"
+
+#, fuzzy
+#~ msgid "devcp_theme_upload_preview"
+#~ msgstr "Please be sure to %s for your theme."
+
+#, fuzzy
+#~ msgid "devcp_theme_upload_preview_link"
+#~ msgstr "upload a preview"
+
+#, fuzzy
+#~ msgid "devcp_version_edit_pagetitle"
+#~ msgstr "Edit Version"
+
+#, fuzzy
+#~ msgid "devcp_version_updated_successfully"
+#~ msgstr "Version updated successfully."
+
+#, fuzzy
+#~ msgid "editors_submissiontype_new"
+#~ msgstr "New"
+
+#, fuzzy
+#~ msgid "editors_submissiontype_updated"
+#~ msgstr "Updated"
+
+#, fuzzy
+#~ msgid "editors_th_addon_age"
+#~ msgstr "Addon Age"
+
+#, fuzzy
+#~ msgid "editors_th_addontypes"
+#~ msgstr "Add-on Types"
+
+#, fuzzy
+#~ msgid "editors_th_age"
+#~ msgstr "Age"
+
+#, fuzzy
+#~ msgid "editors_th_applications"
+#~ msgstr "Applications"
+
+#, fuzzy
+#~ msgid "editors_th_platforms"
+#~ msgstr "Platforms"
+
+#, fuzzy
+#~ msgid "editors_th_submissiontypes"
+#~ msgstr "Submission Types"
+
+#, fuzzy
+#~ msgid "error_notice"
+#~ msgstr "Notice"
+
+#, fuzzy
+#~ msgid "forum_save"
+#~ msgstr "Save"
+
+#, fuzzy
+#~ msgid "home"
+#~ msgstr "home"
+
+#, fuzzy
+#~ msgid "nav_category_plugins"
+#~ msgstr "Plugins"
+
+#, fuzzy
+#~ msgid "page_title_experimental_addons"
+#~ msgstr "Experimental Add-ons"
+
+#, fuzzy
+#~ msgid "pages_experimental_addons_backbutton"
+#~ msgstr "Back to the previous page"
+
+#, fuzzy
+#~ msgid "pagination_page_number_title"
+#~ msgstr "This is page %1$s of %2$s"
+
+#, fuzzy
+#~ msgid "search_matching_addons_number"
+#~ msgid_plural "search_matching_addons_number"
+#~ msgstr[0] "%s matching add-on"
+#~ msgstr[1] "%s matching add-ons"
+
+#, fuzzy
+#~ msgid "statistics_rss_icon_title"
+#~ msgstr "RSS feed of summary data"
diff --git a/site/app/locale/ar/LC_MESSAGES/messages.mo b/site/app/locale/ar/LC_MESSAGES/messages.mo
new file mode 100644
index 0000000..2266088
--- /dev/null
+++ b/site/app/locale/ar/LC_MESSAGES/messages.mo
Binary files differ
diff --git a/site/app/locale/ar/LC_MESSAGES/messages.po b/site/app/locale/ar/LC_MESSAGES/messages.po
new file mode 100644
index 0000000..2226023
--- /dev/null
+++ b/site/app/locale/ar/LC_MESSAGES/messages.po
@@ -0,0 +1,8524 @@
+# translation of messages.po to Arabic
+# Remora Preliminary Language File
+# Copyright (C) 2006 Mozilla Corporation
+# This file is distributed under the same license as the REMORA package.
+#
+# Wil Clouser <clouserw@mozilla.com>, 2006.
+# Anas Husseini <linux.anas@gmail.com>, 2009.
+# Khaled Hosny <khaledhosny@eglug.org>, 2009.
+msgid ""
+msgstr ""
+"Project-Id-Version: messages\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2009-01-16 11:45-0800\n"
+"PO-Revision-Date: 2009-03-10 09:25+0200\n"
+"Last-Translator: Anas Husseini <linux.anas@gmail.com>\n"
+"Language-Team: Arabic <doc@arabeyes.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 "
+"&& n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;\n"
+"X-Generator: KBabel 1.11.4\n"
+
+#: views/addons/policy.thtml:98
+msgid "a_cancel_installation"
+msgstr "ألغ٠التثبيت"
+
+#. This is the text that appears on buttons to download add-ons.
+#. %$1s is an optional string that only appears if the add-on is only available for
+#. a certain platform. Examples: (Windows) or (Linux)
+#. Note that the parentheses are included in the string. :(
+#: views/elements/amo2009/install.thtml:126
+#: views/elements/amo2009/install.thtml:227
+#: views/elements/amo2009/install.thtml:257
+#: views/elements/amo2009/install.thtml:300
+#: views/elements/amo2009/install.thtml:312 views/elements/install.thtml:73
+#: views/elements/install.thtml:181 views/elements/install.thtml:205
+#: views/elements/install.thtml:248 views/elements/install.thtml:260
+#: views/addons/plugins.thtml:66 views/addons/plugins.thtml:76
+#: views/addons/plugins.thtml:86 views/addons/plugins.thtml:96
+#: views/addons/plugins.thtml:119
+#, php-format
+msgid "a_download"
+msgstr "نزّل الآن %s"
+
+#: views/addons/policy.thtml:72
+msgid "a_eula_download"
+msgstr "اقبل ونزّل"
+
+#: views/addons/policy.thtml:74
+msgid "a_eula_install"
+msgstr "اقبل وثبّت"
+
+#: views/elements/header.thtml:76 views/elements/header.thtml:82
+#: views/api/api_addon.thtml:55 views/api/collections_feed.thtml:75
+#: views/sharing_api/addon.thtml:64
+msgid "a_header_public"
+msgstr "عام"
+
+#: views/elements/header.thtml:58 views/elements/header.thtml:75
+#: views/elements/header.thtml:80 views/api/api_addon.thtml:57
+#: views/api/collections_feed.thtml:77 views/sharing_api/addon.thtml:66
+msgid "a_header_sandbox"
+msgstr "ساحة اللعب"
+
+#. %s is a date in the _('date') format
+#: views/elements/amo2009/homepage_addon.thtml:115
+#: views/elements/addon_listitem.thtml:122 views/elements/feature.thtml:106
+#: views/addons/display.thtml:104 views/addons/browse_thumbs.thtml:73
+msgid "addon_detail_last_updated"
+msgstr "Ø­Ùدّثت ÙÙŠ %s"
+
+#. %s is the version of the add-on. Example: 3.2a1
+#: views/elements/amo2009/addon_version_detail.thtml:51
+#: views/elements/addon_version_detail.thtml:51
+#, php-format
+msgid "addon_display_header_version"
+msgstr "الإصدارة %s"
+
+#: views/addons/browse_thumbs.thtml:80
+msgid "addon_downloads"
+msgstr "التنزيلات"
+
+#: views/addons/display.thtml:147
+msgid "addon_downloads_total"
+msgstr "مجموع التنزيلات"
+
+#: views/elements/amo2009/homepage_addon.thtml:106
+#: views/elements/addon_listitem.thtml:115 views/elements/feature.thtml:101
+#: views/addons/category_landing.thtml:157 views/addons/display.thtml:146
+#: views/addons/browse_thumbs.thtml:80
+msgid "addon_downloads_weekly"
+msgstr "التنزيلات الأسبوعية"
+
+#. %1 is the add-on count, %2 the category name
+#: views/addons/browse_thumbs.thtml:104 views/addons/browse.thtml:60
+#, php-format
+msgid "addon_list_category_totalcount"
+msgid_plural "addon_list_category_totalcount"
+msgstr[0] "لا إضاÙات"
+msgstr[1] "إضاÙØ© واحدة"
+msgstr[2] "إضاÙتان"
+msgstr[3] "%1$s إضاÙات"
+msgstr[4] "%1$s إضاÙØ©"
+msgstr[5] "%1$s إضاÙØ©"
+
+#: views/elements/amo2009/addon_list_options.thtml:103
+#: views/elements/pagination.thtml:67
+#: views/elements/addon_list_options.thtml:94
+msgid "addon_list_perpage"
+msgstr "ÙÙŠ الصÙحة"
+
+#: views/elements/amo2009/addon_list_options.thtml:84
+#: views/elements/addon_list_options.thtml:98
+msgid "addon_list_sortby"
+msgstr "ترتيب حسب:"
+
+#: views/helpers/addons_html.php:568 views/elements/amo2009/install.thtml:321
+#: views/elements/feature.thtml:89
+msgid "addon_listitem_flag_experimental"
+msgstr "تجريبية"
+
+#: views/helpers/addons_html.php:570
+msgid "addon_listitem_flag_recommended"
+msgstr "مزكَّاة"
+
+#. %1 is the add-on name, %2 is the platform
+#: views/pages/js_constants.js.thtml:66
+msgid "addon_not_available_for_platform"
+msgstr "%1$s غير متاحة ل†%2$s."
+
+#. %1 is the add-on name
+#: views/addons/policy.thtml:101 views/addons/previews.thtml:60
+#: views/addons/versions.thtml:130 views/reviews/flag.thtml:61
+#: views/reviews/add.thtml:114 views/reviews/display.thtml:216
+#: views/reviews/review_added.thtml:57
+#, php-format
+msgid "addon_review_a_back_to_addon_x"
+msgstr "عودة إلى %1$s..."
+
+#. %1 is the add-on name
+#: views/reviews/flag.thtml:60 views/reviews/add.thtml:113
+#: views/reviews/review_added.thtml:56
+#, php-format
+msgid "addon_review_a_back_to_reviews"
+msgstr "عودة إلى المراجعات..."
+
+#: views/reviews/add.thtml:85
+msgid "addon_review_add_rating_field"
+msgstr "التقييم:"
+
+#: views/reviews/add.thtml:102
+msgid "addon_review_add_review_field"
+msgstr "المراجعة:"
+
+#: views/reviews/add.thtml:107
+msgid "addon_review_add_submit"
+msgstr "أرسل مراجعتك"
+
+#. %s is the name of the add-on
+#: views/reviews/add.thtml:51
+#, php-format
+msgid "addon_review_add_title"
+msgstr "أض٠مراجعة ل†%s"
+
+#: views/reviews/add.thtml:78
+msgid "addon_review_add_title_field"
+msgstr "العنوان/الملخص:"
+
+#: views/reviews/display.thtml:77 views/reviews/display.thtml:161
+msgid "addon_review_admin_delete"
+msgstr "احذÙ"
+
+#: views/reviews/display.thtml:76
+msgid "addon_review_author_reply_link"
+msgstr "ردّ"
+
+#: views/reviews/delete.thtml:62
+msgid "addon_review_confirm_delete"
+msgstr "أمتأكد أنك تريد حذ٠هذه المراجعة؟"
+
+#: views/reviews/delete.thtml:63
+msgid "addon_review_confirm_no"
+msgstr "لا"
+
+#: views/reviews/delete.thtml:64
+msgid "addon_review_confirm_yes"
+msgstr "نعم"
+
+#: views/reviews/delete.thtml:48
+msgid "addon_review_delete_header"
+msgstr "حذ٠المراجعة"
+
+#: controllers/reviews_controller.php:449
+msgid "addon_review_deleted_successfully"
+msgstr "Ø­ÙØ°Ùت المراجعة بنجاح."
+
+#. %s is the name of the add-on
+#: views/reviews/add.thtml:51
+#, php-format
+msgid "addon_review_edit_title"
+msgstr "تحرير مراجعة %s"
+
+#. %1 is the count of characters entered as notes for the review flag reason.
+#: controllers/reviews_controller.php:539
+msgid "addon_review_flag_error_other_length"
+msgstr ""
+"مشكلة ÙÙŠ المراجعة المعلّمة: طول الملاحظات ÙÙŠ المراجعات المعلّمة محصور بين 10 Ùˆ "
+"100 حرÙ. عدد الأحر٠لديك هو %1$s."
+
+#. Removing an extra comma
+#: views/reviews/review_added.thtml:53
+msgid "addon_review_in_moderation"
+msgstr "ÙŠÙرجى ملاحظة أنّ مراجعتك سيشر٠عليها أحد المحررين قبل أن تÙنشر على الملأ."
+
+#: views/reviews/add.thtml:57
+msgid "addon_review_in_reply_to"
+msgstr "ردّ المطوّر على:"
+
+#. %1 is the review count, %2 is the nickname or full name of the user.
+#: views/reviews/display.thtml:131
+#, php-format
+msgid "addon_review_others_by_user"
+msgid_plural "addon_review_others_by_user"
+msgstr[0] "انظر إلى لا مراجعات سابقة كتبها %2$s عن هذه الإضاÙØ©."
+msgstr[1] "انظر إلى المراجعة السابقة التي كتبها %2$s عن هذه الإضاÙØ©."
+msgstr[2] "انظر إلى المراجعتين السابقتين اللتين كتبهما %2$s عن هذه الإضاÙØ©."
+msgstr[3] "انظر إلى %1$s مراجعات سابقة كتبها %2$s عن هذه الإضاÙØ©."
+msgstr[4] "انظر إلى %1$s مراجعة سابقة كتبها %2$s عن هذه الإضاÙØ©."
+msgstr[5] "انظر إلى %1$s مراجعة سابقة كتبها %2$s عن هذه الإضاÙØ©."
+
+#. %1 is the add-on name
+#: controllers/reviews_controller.php:201
+#: controllers/reviews_controller.php:250
+#: controllers/reviews_controller.php:345
+#: controllers/reviews_controller.php:424
+#, php-format
+msgid "addon_review_pagetitle"
+msgstr "مراجعة ل†%s"
+
+#. %1 is the user, %2 is the (localized) date
+#: views/reviews/display.thtml:160
+#, php-format
+msgid "addon_review_reply_on_x_by_y"
+msgstr "ردّ من %1$s على %2$s"
+
+#: views/reviews/display.thtml:157
+msgid "addon_review_reply_prefix"
+msgstr "ردّ المطوّر:"
+
+#: views/reviews/review_added.thtml:51
+msgid "addon_review_saved_successfully"
+msgstr "Ø­ÙÙظت مراجعتك بنجاح. شكرًا!"
+
+#: views/addons/display.thtml:354 views/reviews/display.thtml:72
+msgid "addon_reviewed_by_u_on_d"
+msgstr "من %1$s ÙÙŠ %2$s"
+
+#. %1 is the user, %2 is the (localized) date, %3 is the rating
+#: views/editors/reviews_queue.thtml:57 views/editors/reviews_queue.thtml:68
+#: views/reviews/add.thtml:63 views/reviews/delete.thtml:54
+#, php-format
+msgid "addon_reviewed_on_x_rated_y"
+msgstr "من %1$s ÙÙŠ %2$s (بتقييم %3$s)"
+
+#: views/elements/amo2009/addon_version_detail.thtml:52
+#: views/elements/addon_version_detail.thtml:52
+msgid "addon_version_permalink"
+msgstr "رابط دائم لهذه الإصدارة"
+
+#. %1 is the current Application name (e.g. Firefox)
+#. %2 is the Application's version number
+#: views/addons/versions.thtml:140
+msgid "addon_versions_getlatestversion"
+msgstr "أحدث نسخة متواÙقة مع %1$s %2$s"
+
+#: views/addons/display.thtml:447
+msgid "addons_author_addons_submit"
+msgstr "اذهب"
+
+#: views/elements/amo2009/homepage_addon.thtml:100
+#: views/elements/feature.thtml:95
+msgid "addons_author_tooltip"
+msgstr "شاهد مل٠المؤلÙ"
+
+#. %1 is the name of the Application (eg. Firefox)
+#: controllers/addons_controller.php:1296
+msgid "addons_browse_all_themes_title"
+msgstr "استعرض كل السمات :: إضاÙات %1$s"
+
+#. %s is the name of the category
+#: controllers/addons_controller.php:1016
+#, php-format
+msgid "addons_browse_browse_category"
+msgstr "استعرض %s"
+
+#. %1 is the name of the theme category (eg. Modern)
+#. %2 is the name of the Application (eg. Firefox)
+#: controllers/addons_controller.php:664
+msgid "addons_browse_categories_header_theme"
+msgstr "استعرض سمات %1$s :: إضاÙات %2$s"
+
+#: views/addons/display.thtml:249
+#, fuzzy
+msgid "addons_display_a_license_what"
+msgstr "What's this?"
+
+#: views/reviews/display.thtml:222
+msgid "addons_display_add_review"
+msgstr "أضÙ٠مراجعة"
+
+#: views/addons/display.thtml:294
+msgid "addons_display_advanced_details"
+msgstr "تÙاصيل متقدمة"
+
+#: views/addons/display.thtml:98
+msgid "addons_display_categories"
+msgstr "التصنيÙات"
+
+#: views/addons/display.thtml:482
+#, fuzzy
+msgid "addons_display_collection_add"
+msgstr "Add to a collection:"
+
+#: views/addons/display.thtml:491
+#, fuzzy
+msgid "addons_display_collection_add_new"
+msgstr "New Collection..."
+
+#: views/addons/display.thtml:487
+#, fuzzy
+msgid "addons_display_collection_add_select_one"
+msgstr "Select a collection..."
+
+#: views/addons/display.thtml:493
+#, fuzzy
+msgid "addons_display_collection_add_submit"
+msgstr "Publish"
+
+#. %1$s is the add-on name
+#. %2$s is the collection name, linked to the collection's page
+#: views/pages/js_constants.js.thtml:103 views/addons/display.thtml:61
+#, fuzzy
+msgid "addons_display_collection_publish_success"
+msgstr "%1$s has been added to the %2$s collection."
+
+#: views/addons/display.thtml:483
+#, fuzzy
+msgid "addons_display_collection_whatsthis"
+msgstr "What's this?"
+
+#. %1$s is a number
+#: views/addons/display.thtml:473
+#, fuzzy
+msgid "addons_display_collections_more"
+msgid_plural "addons_display_collections_more"
+msgstr[0] "and %1$s more collection"
+msgstr[1] "and %1$s more collections"
+
+#: views/addons/display.thtml:403
+msgid "addons_display_detailed_review"
+msgstr "مراجعة Ù…Ùصلة"
+
+#: views/reviews/add.thtml:89 views/reviews/add.thtml:90
+msgid "addons_display_dont_like_it"
+msgstr "لا تعجبني"
+
+#: views/reviews/display.thtml:220
+msgid "addons_display_edit_review"
+msgstr "حرّر مراجعتك"
+
+#: views/addons/display.thtml:132
+msgid "addons_display_has_privacy"
+msgstr "لهذه الإضاÙØ© سياسة خصوصية."
+
+#: views/reviews/add.thtml:87 views/reviews/add.thtml:88
+msgid "addons_display_hate_it"
+msgstr "أكرهها"
+
+#: views/addons/display.thtml:462
+#, fuzzy
+msgid "addons_display_header_collections"
+msgstr "Related Collections"
+
+#: views/addons/display.thtml:297
+msgid "addons_display_header_developer_comments"
+msgstr "تعليقات المطوّر"
+
+#: views/addons/display.thtml:230
+msgid "addons_display_header_homepage"
+msgstr "صÙحة البداية"
+
+#: views/addons/display.thtml:247 views/addons/versions.thtml:110
+#, fuzzy
+msgid "addons_display_header_license"
+msgstr "Source Code License"
+
+#: views/addons/display.thtml:337
+msgid "addons_display_header_reviews"
+msgstr "المراجعات"
+
+#: views/addons/display.thtml:261
+msgid "addons_display_header_support"
+msgstr "الدعم"
+
+#: views/reviews/add.thtml:91 views/reviews/add.thtml:92
+msgid "addons_display_like_it"
+msgstr "تعجبني"
+
+#: views/addons/display.thtml:210
+msgid "addons_display_long_description"
+msgstr "الوص٠المطوّل"
+
+#: views/reviews/add.thtml:95 views/reviews/add.thtml:96
+msgid "addons_display_love_it"
+msgstr "أحبّها"
+
+#: views/addons/display.thtml:178
+msgid "addons_display_more_images"
+msgstr "المزيد من الصور"
+
+#: views/addons/display.thtml:465
+#, fuzzy
+msgid "addons_display_nocollections"
+msgstr "This add-on is not yet in any collections."
+
+#. %1$s is either an author's name or a comma separated list of authors. Using
+#. the list doesn't make sense in the English plural form so we ignore the
+#. variable.
+#: views/addons/display.thtml:436
+msgid "addons_display_other_addons_by"
+msgid_plural "addons_display_other_addons_by"
+msgstr[0] "إضاÙات أخرى أعدّها %1$s"
+msgstr[1] "إضاÙات أخرى أعدّها المؤل٠%1$s"
+msgstr[2] "إضاÙات أخرى أعدّها المؤلÙان %1$s"
+msgstr[3] "إضاÙات أخرى أعدّها المؤلÙون %1$s"
+msgstr[4] "إضاÙات أخرى أعدّها المؤلÙون %1$s"
+msgstr[5] "إضاÙات أخرى أعدّها المؤلÙون %1$s"
+
+#. %s is the name of the add-on and the add-on section. Example:
+#. Some Add-on :: Firefox Add-ons
+#. This should not be concatenated in the code and should be fixed.
+#: controllers/addons_controller.php:141 controllers/addons_controller.php:280
+#: controllers/addons_controller.php:1442
+#, php-format
+msgid "addons_display_pagetitle"
+msgstr "%s"
+
+#. %s is an email address
+#: views/addons/display.thtml:286
+#, php-format
+msgid "addons_display_paragraph_supportinfoemail"
+msgstr "يقدّم المطوّر دعمًا لهذه الإضاÙØ© بمراسلة البريد الإلكتروني %s"
+
+#. %$1s is a URL
+#. %$2s is an email address
+#: views/addons/display.thtml:269
+#, php-format
+msgid "addons_display_paragraph_supportinfoemailurl"
+msgstr "يقدّم المطوّر دعمًا لهذه الإضاÙØ© ÙÙŠ %s أو بمراسلة البريد الإلكتروني %s"
+
+#. %s is a URL
+#: views/addons/display.thtml:278
+#, php-format
+msgid "addons_display_paragraph_supportinfourl"
+msgstr "يقدّم المطوّر دعمًا لهذه الإضاÙØ© ÙÙŠ %s"
+
+#: views/addons/display.thtml:383
+msgid "addons_display_rate_it"
+msgstr "قيّمها"
+
+#: views/reviews/add.thtml:93 views/reviews/add.thtml:94
+msgid "addons_display_really_like_it"
+msgstr "تعجبني حقًا"
+
+#: views/addons/display.thtml:410
+msgid "addons_display_review_etiquette"
+msgstr ""
+"رجاءً لا تبلّغ عن العلل ÙÙŠ المراجعات. نحن لا ننشر بريدك الإنترنت أمام "
+"المطوّرين، وهم قد يحتاجون إلى التواصل معك للمساعدة ÙÙŠ حل مشكلتك."
+
+#. %1 is the review guidelines link
+#: views/addons/display.thtml:417
+msgid "addons_display_review_guidelines_link"
+msgstr "<a href=\"%s\">إرشادات المراجعات</a>"
+
+#. %1 is the support section link
+#: views/addons/display.thtml:414
+msgid "addons_display_review_see_support"
+msgstr ""
+"انظر <a href=\"%1$s\">قسم الدعم</a> لمعرÙØ© أين يمكنك الحصول على مساعدة بشأن "
+"هذه الإضاÙØ©."
+
+#: views/addons/display.thtml:404
+msgid "addons_display_review_submit"
+msgstr "احÙظ"
+
+#: views/addons/display.thtml:430
+#, php-format
+msgid "addons_display_see_all_addons"
+msgstr "شاهد كل الإضاÙات ال†%1$s"
+
+#. %1 is the number of reviews
+#: views/addons/display.thtml:364
+#, php-format
+msgid "addons_display_see_all_reviews"
+msgstr "شاهد كل المراجعات (%1$s)"
+
+#: views/addons/display.thtml:219
+msgid "addons_display_see_all_versions"
+msgstr "شاهد كل الإصدارات"
+
+#: views/addons/display.thtml:321 views/addons/versions.thtml:117
+msgid "addons_display_view_source"
+msgstr "شاهد المصدر"
+
+#: views/addons/display.thtml:324
+msgid "addons_display_view_stats"
+msgstr "شاهد الإحصائيات"
+
+#: views/addons/display.thtml:376
+msgid "addons_display_what_do_you_think"
+msgstr "ما رأيك؟"
+
+#: views/elements/app_compatibility.thtml:49
+msgid "addons_display_workswith"
+msgstr "تعمل مع:"
+
+#: views/addons/home.thtml:112
+#, fuzzy
+msgid "addons_home_browse_new"
+msgstr "Just Added"
+
+#: views/addons/home.thtml:110
+#, fuzzy
+msgid "addons_home_browse_popular"
+msgstr "Popular"
+
+#: views/addons/home.thtml:108
+#, fuzzy
+msgid "addons_home_browse_recommended"
+msgstr "Recommended"
+
+#: views/addons/home.thtml:127 views/addons/home.thtml:134
+#: views/addons/home.thtml:141 views/addons/home.thtml:148
+#, fuzzy
+msgid "addons_home_browse_subscribe"
+msgstr "Subscribe"
+
+#: views/addons/home.thtml:101
+#, fuzzy
+msgid "addons_home_browse_title"
+msgstr "Browse Add-ons"
+
+#: views/addons/home.thtml:114
+#, fuzzy
+msgid "addons_home_browse_updated"
+msgstr "Updated"
+
+#: views/elements/amo2009/homepage_addon.thtml:100
+#: views/elements/addon_discussionheader.thtml:83
+#: views/elements/addon_listitem.thtml:109 views/elements/feature.thtml:95
+#: views/addons/category_landing.thtml:66 views/addons/policy.thtml:57
+#: views/addons/display.thtml:70 views/addons/home.thtml:178
+msgid "addons_home_by"
+msgstr "من"
+
+#: views/addons/home.thtml:169
+#, fuzzy
+msgid "addons_home_collection_popular_title"
+msgstr "Popular Collections"
+
+#: views/elements/amo2009/categories.thtml:69 views/addons/home.thtml:160
+#, fuzzy
+msgid "addons_home_collections"
+msgstr "Collections"
+
+#. %1$s is the count of addons in a collection
+#: views/elements/amo2009/collection_listing_item.thtml:51
+#: views/addons/home.thtml:185
+#, fuzzy
+msgid "addons_home_collections_addon_count"
+msgid_plural "addons_home_collections_addon_count"
+msgstr[0] "<strong>%1$s</strong> add-on"
+msgstr[1] "<strong>%1$s</strong> add-ons"
+
+#: views/addons/home.thtml:196
+#, fuzzy
+msgid "addons_home_collections_all"
+msgstr "View All Collections"
+
+#: views/addons/home.thtml:162
+#, fuzzy
+msgid "addons_home_collections_intro"
+msgstr ""
+"Collections are a way for you to categorize, mix, match and mingle add-ons. "
+"Subscribe to collections created by other users or create your own."
+
+#. %1$s is the count of subscribers for a collection
+#: views/elements/amo2009/collection_listing_item.thtml:58
+#: views/collections/detail.thtml:96 views/addons/home.thtml:189
+#, fuzzy
+msgid "addons_home_collections_subscribers"
+msgid_plural "addons_home_collections_subscribers"
+msgstr[0] "<strong>%1$s</strong> subscriber"
+msgstr[1] "<strong>%1$s</strong> subscribers"
+
+#: views/addons/searchengines.thtml:54 views/addons/themes_landing.thtml:49
+msgid "addons_home_feature_head"
+msgstr "نزكّي"
+
+#: controllers/search_controller.php:218 controllers/addons_controller.php:176
+#: controllers/addons_controller.php:428 controllers/addons_controller.php:671
+#: controllers/addons_controller.php:871
+#: controllers/addons_controller.php:1103
+#: controllers/addons_controller.php:1242
+#: controllers/addons_controller.php:1298
+#, php-format
+msgid "addons_home_header_details"
+msgstr ""
+"تزيد الإضاÙات قدرات %1$sØŒ متيحة لك تطويع تصÙحك للوب. خذ جولة ÙÙŠ المكان واجعل "
+"من %1$s شيئًا ينتمي إليك."
+
+#. %1$s is the HTML collection name link.
+#: views/elements/amo2009/teaser_collections.thtml:107
+#, fuzzy
+msgid "addons_home_introduction_collection_link"
+msgstr "Like these? Find more add-ons in %1$s."
+
+#: views/elements/amo2009/teaser_collections.thtml:60
+#, fuzzy
+msgid "addons_home_introduction_extras"
+msgstr ""
+"<strong>Over 5000 free extras</strong> that let you customize and extend "
+"Firefox to meet your needs."
+
+#: views/elements/amo2009/teaser_collections.thtml:55
+#, fuzzy
+msgid "addons_home_introduction_header"
+msgstr "What are Add-ons?"
+
+#: views/elements/amo2009/teaser_collections.thtml:72
+#, fuzzy
+msgid "addons_home_introduction_install"
+msgstr ""
+"<strong>Easy to install</strong>, get notified when updates are available."
+
+#: views/elements/amo2009/teaser_collections.thtml:45
+#, fuzzy
+msgid "addons_home_introduction_name"
+msgstr "Introduction"
+
+#: views/elements/amo2009/teaser_collections.thtml:66
+#, fuzzy
+msgid "addons_home_introduction_themes"
+msgstr ""
+"Toolbars, themes and search providers that <strong>help you perform common "
+"tasks.</strong>"
+
+#: views/addons/home.thtml:161
+#, fuzzy
+msgid "addons_home_new_indicator"
+msgstr "NEW!"
+
+#: views/elements/app_chooser.thtml:48 views/layouts/amo2009.thtml:257
+msgid "addons_home_other_applications"
+msgstr "تطبيقات أخرى"
+
+#. %1$s is the application the user is browsing. Examples: Thunderbird, Firefox,
+#. Sunbird
+#: views/pages/collector_faq.thtml:49 views/pages/collector_firstrun.thtml:42
+#: views/pages/collector.thtml:46 views/pages/collector_features.thtml:54
+#: controllers/developers_controller.php:87
+#: controllers/compatibility_controller.php:72
+#: controllers/components/simple_acl.php:81 controllers/components/amo.php:607
+#: controllers/statistics_controller.php:60
+#: controllers/statistics_controller.php:240
+#: controllers/previews_controller.php:67 controllers/users_controller.php:90
+#: controllers/users_controller.php:223 controllers/users_controller.php:330
+#: controllers/users_controller.php:414 controllers/users_controller.php:708
+#: controllers/users_controller.php:723 controllers/reviews_controller.php:204
+#: controllers/reviews_controller.php:251
+#: controllers/reviews_controller.php:346
+#: controllers/reviews_controller.php:425
+#: controllers/search_controller.php:185 controllers/search_controller.php:297
+#: controllers/search_controller.php:301 controllers/addons_controller.php:147
+#: controllers/addons_controller.php:280 controllers/addons_controller.php:370
+#: controllers/addons_controller.php:667 controllers/addons_controller.php:874
+#: controllers/addons_controller.php:1019
+#: controllers/addons_controller.php:1034
+#: controllers/addons_controller.php:1101
+#: controllers/addons_controller.php:1121
+#: controllers/addons_controller.php:1240
+#: controllers/addons_controller.php:1357
+#: controllers/addons_controller.php:1364
+#: controllers/addons_controller.php:1442
+#: controllers/addons_controller.php:1477
+#: controllers/addons_controller.php:1538
+#: controllers/addons_controller.php:1543
+#: controllers/editors_controller.php:64 controllers/pages_controller.php:132
+#: controllers/groups_controller.php:65 controllers/groups_controller.php:71
+#: controllers/groups_controller.php:89 controllers/groups_controller.php:111
+#: controllers/collections_controller.php:57
+#: controllers/collections_controller.php:121
+#: controllers/collections_controller.php:205
+#: controllers/collections_controller.php:365
+#: controllers/collections_controller.php:404
+#: controllers/collections_controller.php:466
+#: controllers/collections_controller.php:538
+#: controllers/collections_controller.php:828
+#: controllers/localizers_controller.php:72
+#, php-format
+msgid "addons_home_pagetitle"
+msgstr "إضاÙات %1$s"
+
+#. %1$s is the number of addons downloaded
+#: views/addons/home.thtml:57
+#, fuzzy, php-format
+msgid "addons_home_stats_downloaded"
+msgid_plural "addons_home_stats_downloaded"
+msgstr[0] "<strong>%1$s</strong> <span>add-on downloaded</span>"
+msgstr[1] "<strong>%1$s</strong> <span>add-ons downloaded</span>"
+
+#. %1$s is the number of addons in use
+#: views/addons/home.thtml:63
+#, fuzzy, php-format
+msgid "addons_home_stats_inuse"
+msgid_plural "addons_home_stats_inuse"
+msgstr[0] "<strong>%1$s</strong> <span>add-on in use</span>"
+msgstr[1] "<strong>%1$s</strong> <span>add-ons in use</span>"
+
+#: views/addons/home.thtml:136
+msgid "addons_home_view_all_newest_title"
+msgstr "شاهد كل الإضاÙات الجديدة"
+
+#: views/addons/home.thtml:129
+msgid "addons_home_view_all_popular_title"
+msgstr "شاهد كل الإضاÙات الشعبية"
+
+#: views/addons/home.thtml:150
+msgid "addons_home_view_all_recommended_title"
+msgstr "شاهد كل الإضاÙات المزكَّاة"
+
+#: views/addons/home.thtml:143
+msgid "addons_home_view_all_updated_title"
+msgstr "شاهد كل الإضاÙات المحدّثة مؤخرًا"
+
+#: views/elements/amo2009/install.thtml:334 views/elements/install.thtml:112
+msgid "addons_install_in_sunbird"
+msgstr ""
+"<ol><li>انقر على الرابط أدناه لحÙظ الملÙ.</li><li>ÙÙŠ موزيلا صنبÙرد، اÙتح "
+"الإضاÙات من قائمة الأدوات.</li><li>انقر على زر التثبيت وحدّد المل٠الذي تريد "
+"تنزيله ثم انقر على \"مواÙÙ‚\".</li></ol>"
+
+#: views/elements/amo2009/install.thtml:333 views/elements/install.thtml:111
+msgid "addons_install_in_sunbird_title"
+msgstr "كيÙية التثبيت ÙÙŠ صَنْبÙرْد"
+
+#: views/elements/amo2009/install.thtml:331 views/elements/install.thtml:106
+msgid "addons_install_in_thunderbird"
+msgstr ""
+"<ol><li>انقر بالزر الأيمن على الرابط أدناه واختر \"احÙظ الوصلة Ùƒâ€...\" لتنزيل "
+"وحÙظ المل٠على قرصك الصلب.</li><li>ÙÙŠ موزيلا ثندÙربÙرد، اÙتح الإضاÙات من قائمة "
+"الأدوات.</li><li>انقر على زر التثبيت واختر المل٠الذي نزّلته ثم انقر على "
+"\"مواÙÙ‚\".</li></ol>"
+
+#: views/elements/amo2009/install.thtml:330 views/elements/install.thtml:105
+msgid "addons_install_in_thunderbird_title"
+msgstr "كيÙية التثبيت ÙÙŠ ثَندÙربÙرد"
+
+#: views/elements/amo2009/addon_list_options.thtml:108
+#: views/elements/addon_list_options.thtml:105
+msgid "addons_options_show_experimental"
+msgstr "أظهÙر الإضاÙات التجريبية"
+
+#: views/elements/amo2009/addon_list_options.thtml:113
+#: views/elements/addon_list_options.thtml:109
+msgid "addons_options_submit"
+msgstr "اذهب"
+
+#: views/addons/plugins.thtml:63 views/addons/plugins.thtml:73
+#: views/addons/plugins.thtml:83 views/addons/plugins.thtml:93
+#: views/addons/plugins.thtml:103 views/addons/plugins.thtml:116
+#: views/addons/plugins.thtml:126
+msgid "addons_plugins_by"
+msgstr "من"
+
+#: views/addons/plugins.thtml:107
+msgid "addons_plugins_for_linux"
+msgstr "للينكس"
+
+#: views/addons/plugins.thtml:108 views/addons/plugins.thtml:131
+msgid "addons_plugins_for_macosx"
+msgstr "لماك أو إس"
+
+#: views/addons/plugins.thtml:106 views/addons/plugins.thtml:129
+#: views/addons/plugins.thtml:130
+msgid "addons_plugins_for_windows"
+msgstr "لويندوز"
+
+#. %1$s is a URL
+#: views/addons/plugins.thtml:139
+#, php-format
+msgid "addons_plugins_looking_for_more"
+msgstr ""
+"تسرد هذه الصÙحة Ùقط بعض الملحقات الأكثر شعبية. للمزيد من المعلومات عن "
+"الملحقات الأخرى المتاحة للمتصÙحات المرتكزة على موزيلا، ÙŠÙرجى زيارة %1$s"
+
+#: views/addons/plugins.thtml:137
+msgid "addons_plugins_looking_for_plugin"
+msgstr "أتبحث عن ملحق غير موجود هنا؟"
+
+#: views/addons/plugins.thtml:58
+msgid "addons_plugins_main_description"
+msgstr ""
+"تساعد الملحقات متصÙحك على القيام بوظائ٠معينة، كمشاهدة تنسيقات رسومية معينة "
+"أو تشغيل ملÙات الوسائط المتعددة. تختل٠الملحقات عن الامتدادات قليلًا لأنّ "
+"الأخير تضي٠أو تعدّل على الوظيÙØ© الموجودة."
+
+#. %1$s is the application name. Example: Firefox, Thunderbird, Sunbird
+#: controllers/addons_controller.php:1122
+#, php-format
+msgid "addons_plugins_main_header"
+msgstr "الملحقات الشائعة ل†%1$s"
+
+#: controllers/components/amo.php:698 controllers/addons_controller.php:1121
+msgid "addons_plugins_pagetitle"
+msgstr "الملحقات"
+
+#: views/addons/plugins.thtml:68 views/addons/plugins.thtml:78
+#: views/addons/plugins.thtml:88 views/addons/plugins.thtml:98
+#: views/addons/plugins.thtml:110 views/addons/plugins.thtml:121
+#: views/addons/plugins.thtml:133
+msgid "addons_plugins_support_documentation"
+msgstr "وثائق الدعم: "
+
+#. %s is the name of the add-on
+#: views/addons/policy.thtml:61
+#, php-format
+msgid "addons_policy_eula_require"
+msgstr ""
+"يتطلب %s منك أن تقبل اتÙاقية ترخيص المستخدم التالية قبل متابعة التثبيت:"
+
+#. %1 is the add-on name
+#: controllers/addons_controller.php:1476
+#, php-format
+msgid "addons_previews_pagetitle"
+msgstr "معاينات %s"
+
+#: views/addons/category_landing.thtml:135
+#, fuzzy
+msgid "addons_recently_added"
+msgstr "Recently Added"
+
+#: views/addons/recommended.thtml:51 controllers/addons_controller.php:1365
+msgid "addons_recommended_introduction"
+msgstr ""
+"مع كل هذا العدد من الإضاÙات العظيمة، هناك شيء ما لكل شخص. كبداية، هذه قائمة "
+"من الإضاÙات الأكثر شعبية. استمتع!"
+
+#: controllers/addons_controller.php:1357
+#: controllers/addons_controller.php:1364
+msgid "addons_recommended_pagetitle"
+msgstr "الإضاÙات المزكَّاة"
+
+#: controllers/addons_controller.php:1360
+msgid "addons_recommended_title"
+msgstr "الإضاÙات التي نزكّيها"
+
+#: views/addons/searchengines.thtml:136
+msgid "addons_searchengines_additional_resources"
+msgstr "موارد إضاÙية"
+
+#. link text devmo
+#: views/addons/searchengines.thtml:141
+msgid "addons_searchengines_devmo_link"
+msgstr "مركز مطوّري موزيلا"
+
+#: views/pages/js_constants.js.thtml:67
+msgid "addons_searchengines_error_mozilla_browser_required"
+msgstr "عذرًا، تحتاج إلى متصÙØ­ مرتكز على موزيلا (مثل ÙَيَرÙÙكس) لتثبيت ملحق البحث."
+
+#: views/addons/searchengines.thtml:49
+msgid "addons_searchengines_error_nojavascript"
+msgstr ""
+"جاÙاسكربت مطلوبة لتثبيت الملحقات، ولكن يبدو أنك قد عطلتها. رجاءً مكّن "
+"جاÙاسكربت قبل محاولة تثبيت أي من ملحقات البحث أدناه."
+
+#. %1 is "make your own" link
+#. %2 is MDC link
+#: views/addons/searchengines.thtml:139
+msgid "addons_searchengines_learn_howto"
+msgstr "تعلم كي٠%1$s ÙÙŠ %2$s."
+
+#. link path to search plugins instructions, relative to devmo
+#: views/addons/searchengines.thtml:140
+msgid "addons_searchengines_makeyourown_href"
+msgstr "/ar/docs/Creating_OpenSearch_plugins_for_Firefox"
+
+#. link text for "make your own" (opensearch engine)
+#: views/addons/searchengines.thtml:140
+msgid "addons_searchengines_makeyourown_link"
+msgstr "تصنع واحدة خاصة بك"
+
+#. %1 is the link to mycroft.mozdev.org
+#: views/addons/searchengines.thtml:138
+msgid "addons_searchengines_more"
+msgstr "تصÙØ­ من خلال المزيد من محركات البحث ÙÙŠ %1$s"
+
+#. link text to mycroft.mozdev.org
+#: views/addons/searchengines.thtml:138
+msgid "addons_searchengines_mycroft_link"
+msgstr "mycroft.mozdev.org"
+
+#: controllers/addons_controller.php:1100
+#: controllers/addons_controller.php:1110
+msgid "addons_searchengines_pagetitle"
+msgstr "محركات البحث"
+
+#: views/addons/searchengines.thtml:143
+msgid "addons_searchengines_thanks"
+msgstr "شكر خاص لمشروع مايكروÙت على عملهم ÙÙŠ محركات بحث ÙَيَرÙÙكس."
+
+#: views/addons/display.thtml:154
+#, fuzzy
+msgid "addons_share_button_text"
+msgstr "Share this"
+
+#: controllers/addons_controller.php:89
+#, fuzzy
+msgid "addons_share_label_delicious"
+msgstr "Add to Delicious"
+
+#: controllers/addons_controller.php:77
+#, fuzzy
+msgid "addons_share_label_digg"
+msgstr "Digg this!"
+
+#: controllers/addons_controller.php:83
+#, fuzzy
+msgid "addons_share_label_facebook"
+msgstr "Post to Facebook"
+
+#: controllers/addons_controller.php:101
+#, fuzzy
+msgid "addons_share_label_friendfeed"
+msgstr "Share on FriendFeed"
+
+#: controllers/addons_controller.php:95
+#, fuzzy
+msgid "addons_share_label_myspace"
+msgstr "Post to MySpace"
+
+#: controllers/components/amo.php:201 controllers/components/amo.php:229
+msgid "addons_status_disabled"
+msgstr "معطّلة"
+
+#: controllers/components/amo.php:191 controllers/components/amo.php:224
+msgid "addons_status_incomplete"
+msgstr "إصدارة غير مكتملة"
+
+#: controllers/components/amo.php:197 controllers/components/amo.php:227
+msgid "addons_status_nominated"
+msgstr "ÙÙŠ ساحة اللعب؛ ترشيح عام"
+
+#: views/pages/js_constants.js.thtml:80 controllers/components/amo.php:195
+#: controllers/components/amo.php:226
+msgid "addons_status_pending"
+msgstr "ÙÙŠ ساحة اللعب؛ بانتظار المراجعات"
+
+#: views/pages/js_constants.js.thtml:78 controllers/components/amo.php:199
+#: controllers/components/amo.php:228
+msgid "addons_status_public"
+msgstr "عام"
+
+#: views/pages/js_constants.js.thtml:79 controllers/components/amo.php:193
+#: controllers/components/amo.php:225
+msgid "addons_status_sandbox"
+msgstr "ÙÙŠ ساحة اللعب"
+
+#: controllers/components/amo.php:203
+msgid "addons_status_unknown"
+msgstr "مجهول"
+
+#: views/elements/amo2009/teaser_collections.thtml:91
+#: views/elements/amo2009/homepage_addon.thtml:99
+#: views/elements/feature.thtml:94
+msgid "addons_title_tooltip"
+msgstr "اعر٠المزيد عن هذه الإضاÙØ©"
+
+#: views/addons/category_landing.thtml:151
+#, fuzzy
+msgid "addons_top_downloads"
+msgstr "Top Downloads"
+
+#: views/addons/category_landing.thtml:165
+#, fuzzy
+msgid "addons_top_rated"
+msgstr "Top Rated"
+
+#: views/addons/versions.thtml:62
+msgid "addons_versions_careful"
+msgstr "كن حذرًا مع الإصدارات القديمة"
+
+#: views/addons/versions.thtml:63
+msgid "addons_versions_careful_introduction"
+msgstr ""
+"هذه الإصدارات معروضة لتكون مرجعًا ومن أجل أغراض اختبارية. ينبغي عليك دائمًا أن "
+"تستخدم أحدث إصدارة من الإضاÙØ©."
+
+#: controllers/addons_controller.php:1549
+msgid "addons_versions_history"
+msgstr "تاريخ الإصدارات مع سجل التغييرات"
+
+#. %1$s is the add-on name
+#: controllers/addons_controller.php:1535
+#, php-format
+msgid "addons_versions_pagetitle"
+msgstr "تاريخ إصدارات %1$s"
+
+#: controllers/groups_controller.php:71
+msgid "admin_group_add_pagetitle"
+msgstr "إضاÙØ© مجموعة"
+
+#: controllers/groups_controller.php:111
+msgid "admin_group_delete_pagetitle"
+msgstr "حذ٠مجموعة"
+
+#. %s is a number to identify the group
+#: controllers/groups_controller.php:117
+#, php-format
+msgid "admin_group_deleted"
+msgstr "Ø­ÙØ°Ùت المجموعة ذات المعرّ٠%s"
+
+#: controllers/groups_controller.php:89
+msgid "admin_group_edit_pagetitle"
+msgstr "تحرير مجموعة"
+
+#: controllers/groups_controller.php:92 controllers/groups_controller.php:113
+msgid "admin_group_error_invalid_id"
+msgstr "معرّ٠المجموعة غير صالح"
+
+#: controllers/groups_controller.php:65
+msgid "admin_group_pagetitle"
+msgstr "مدير المجموعة"
+
+#: controllers/groups_controller.php:77 controllers/groups_controller.php:99
+msgid "admin_group_saved"
+msgstr "Ø­ÙÙظت المجموعة"
+
+#: views/elements/amo2009/search.thtml:257 views/elements/search.thtml:239
+msgid "advanced_search_form"
+msgstr "متقدم"
+
+#: views/elements/amo2009/search.thtml:126 views/elements/search.thtml:125
+msgid "advanced_search_form_any_time"
+msgstr "أي وقت"
+
+#: views/elements/amo2009/search.thtml:97
+#: views/elements/amo2009/search.thtml:110 views/elements/search.thtml:96
+#: views/elements/search.thtml:109
+msgid "advanced_search_form_any_type"
+msgstr "أي نوع"
+
+#: views/elements/amo2009/search.thtml:275 views/elements/search.thtml:254
+msgid "advanced_search_form_any_version"
+msgstr "أي إصدارة"
+
+#: views/elements/amo2009/search.thtml:217 views/elements/search.thtml:212
+msgid "advanced_search_form_application"
+msgstr "التطبيق"
+
+#: views/elements/amo2009/search.thtml:143 views/elements/search.thtml:142
+msgid "advanced_search_form_keyword_match"
+msgstr "تطابق الكلمات الأساسية"
+
+#: views/elements/amo2009/search.thtml:251 views/elements/search.thtml:225
+msgid "advanced_search_form_lastupdate"
+msgstr "المحدّثة مؤخرًا"
+
+#: views/elements/amo2009/search.thtml:145 views/elements/search.thtml:144
+msgid "advanced_search_form_name"
+msgstr "الاسم"
+
+#: views/elements/amo2009/search.thtml:144 views/elements/search.thtml:143
+msgid "advanced_search_form_newest"
+msgstr "الأحدث"
+
+#: views/elements/amo2009/search.thtml:130 views/elements/search.thtml:129
+msgid "advanced_search_form_past_3_months"
+msgstr "ÙÙŠ الشهور الثلاثة الماضية"
+
+#: views/elements/amo2009/search.thtml:131 views/elements/search.thtml:130
+msgid "advanced_search_form_past_6_months"
+msgstr "ÙÙŠ الشهور الستة الماضية"
+
+#: views/elements/amo2009/search.thtml:127 views/elements/search.thtml:126
+msgid "advanced_search_form_past_day"
+msgstr "البارحة"
+
+#: views/elements/amo2009/search.thtml:129 views/elements/search.thtml:128
+msgid "advanced_search_form_past_month"
+msgstr "الشهر الماضي"
+
+#: views/elements/amo2009/search.thtml:128 views/elements/search.thtml:127
+msgid "advanced_search_form_past_week"
+msgstr "الأسبوع الماضي"
+
+#: views/elements/amo2009/search.thtml:132 views/elements/search.thtml:131
+msgid "advanced_search_form_past_year"
+msgstr "السنة الماضية"
+
+#: views/elements/amo2009/search.thtml:239 views/elements/search.thtml:230
+msgid "advanced_search_form_perpage"
+msgstr "ÙÙŠ الصÙحة"
+
+#: views/elements/amo2009/search.thtml:243 views/elements/search.thtml:224
+msgid "advanced_search_form_platform"
+msgstr "منصة التشغيل"
+
+#: views/elements/amo2009/search.thtml:147 views/elements/search.thtml:146
+msgid "advanced_search_form_popularity"
+msgstr "الشعبية"
+
+#: views/elements/amo2009/search.thtml:146 views/elements/search.thtml:145
+msgid "advanced_search_form_rating"
+msgstr "التقييم"
+
+#: views/elements/amo2009/search.thtml:247 views/elements/search.thtml:231
+msgid "advanced_search_form_sortby"
+msgstr "ترتيب حسب"
+
+#: views/elements/amo2009/search.thtml:227 views/elements/search.thtml:216
+msgid "advanced_search_form_to"
+msgstr "إلى"
+
+#: views/elements/amo2009/search.thtml:257 views/elements/search.thtml:237
+msgid "advanced_search_form_toggle_tooltip"
+msgstr "انتقل إلى نمط البحث المتقدم"
+
+#: views/elements/amo2009/search.thtml:235 views/elements/search.thtml:223
+msgid "advanced_search_form_type"
+msgstr "النوع"
+
+#: views/elements/amo2009/search.thtml:222 views/elements/search.thtml:214
+msgid "advanced_search_form_version"
+msgstr "الإصدارة"
+
+#: views/elements/amo2009/pagination.thtml:42
+#, fuzzy
+msgid "amo2009_pagination_next_page"
+msgstr "Next"
+
+#: views/elements/amo2009/pagination.thtml:41
+#, fuzzy
+msgid "amo2009_pagination_previous_page"
+msgstr "Prev"
+
+#: views/pages/js_constants.js.thtml:96
+msgid "app_compat_ignore_check"
+msgstr "تجاهل Ùحص الإصدارة"
+
+#: views/pages/js_constants.js.thtml:72
+msgid "app_compat_older_firefox_only"
+msgstr "هذه الإضاÙØ© هي من أجل إصدارات أقدم من ÙَيَرÙÙكس"
+
+#. %1$s and %2$s are URLs
+#: views/pages/js_constants.js.thtml:74
+msgid "app_compat_older_version_or_ignore_check"
+msgstr ""
+"يمكنك أن <a href=\"%1$s\">تجرّب إصدارة أقدم</a> أو <a href=\"#\" onclick=\"%2"
+"$s\">تتجاهل هذا الÙحص</a>"
+
+#. %1$s is a URL
+#: views/pages/js_constants.js.thtml:71
+msgid "app_compat_try_old_version"
+msgstr "قد تعمل <a href=\"%1$s\">الإصدارة الأقدم</a>"
+
+#. %1$s is a URL
+#. %2$s is a version number. Example: 3.1
+#: views/pages/js_constants.js.thtml:73
+msgid "app_compat_unreleased_version"
+msgstr ""
+"هذه الإضاÙØ© تتطلب النسخة التي لم تصدر بعد من <a href=\"%1$s\">ÙَيَرÙÙكس %2$s</a>"
+
+#: views/pages/js_constants.js.thtml:70
+msgid "app_compat_update_firefox"
+msgstr ""
+"<a href=\"http://getfirefox.com\">قم بترقية ÙَيَرÙÙكس</a> لاستخدام هذه الإضاÙØ©"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#. %3$s is a status, like Public.
+#: controllers/components/audit.php:79
+#, fuzzy
+msgid "audit_addon_status"
+msgstr "%1$s changed the status of %2$s to %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:221
+#, fuzzy
+msgid "audit_admin_default"
+msgstr "%1$s committed unknown admin action %2$s to ID %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:153
+#, fuzzy
+msgid "audit_admin_feature_remove"
+msgstr "%1$s removed feature %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is an application, like Firefox.
+#: controllers/components/audit.php:92
+#, fuzzy
+msgid "audit_application_create"
+msgstr "%1$s created application %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is an application, like Firefox.
+#: controllers/components/audit.php:95
+#, fuzzy
+msgid "audit_application_edit"
+msgstr "%1$s edited application %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a version number, like 3.5.
+#. %3$s is an application, like Firefox.
+#: controllers/components/audit.php:105
+#, fuzzy
+msgid "audit_appversion_create"
+msgstr "%1$s created version %2$s for %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a version number, like 3.5.
+#. %3$s is an application, like Firefox.
+#: controllers/components/audit.php:108
+#, fuzzy
+msgid "audit_appversion_delete"
+msgstr "%1$s deleted version %2$s for %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a config field, like "awesomeness".
+#. %3$s is a config value, like "off".
+#. %4$s is a config value, like "on".
+#: controllers/components/audit.php:210
+#, fuzzy
+msgid "audit_config"
+msgstr "%1$s changed config '%2$s' from '%3$s' to '%4$s'"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:258
+#, fuzzy
+msgid "audit_editor_default"
+msgstr "%1$s committed unknown editor action %2$s to ID %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#: controllers/components/audit.php:236
+#, fuzzy
+msgid "audit_editor_feature_remove"
+msgstr "%1$s removed addon %2$s from feature list"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#: controllers/components/audit.php:231
+#, fuzzy
+msgid "audit_feature_add"
+msgstr "%1$s added addon %2$s to feature list"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:149
+#, fuzzy
+msgid "audit_feature_edit"
+msgstr "%1$s changed a feature for %2$s locale"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#: controllers/components/audit.php:241
+#, fuzzy
+msgid "audit_feature_locale_change"
+msgstr "%1$s changed locales for addon %2$s on feature list"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:83
+#, fuzzy
+msgid "audit_file_recalchash"
+msgstr "%1$s recalculated the hash for file %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>user name</a>
+#. %3$s is <a>group name</a>
+#: controllers/components/audit.php:182
+#, fuzzy
+msgid "audit_group_addmember"
+msgstr "%1$s added %2$s to group %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:313
+#, fuzzy
+msgid "audit_group_associated"
+msgstr "%1$s associated themselves with %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:162
+#, fuzzy
+msgid "audit_group_create"
+msgstr "%1s created group %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:170
+#, fuzzy
+msgid "audit_group_delete"
+msgstr "%1$s deleted group %2$s (ID %3$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:165
+#, fuzzy
+msgid "audit_group_edit"
+msgstr "%1$s edited group %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>user name</a>
+#. %3$s is <a>group name</a>
+#: controllers/components/audit.php:188
+#, fuzzy
+msgid "audit_group_removemember"
+msgstr "%1$s removed %2$s from group %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:280
+#, fuzzy
+msgid "audit_l10n_default"
+msgstr "%1$s committed unknown action %2$s for %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:295
+#, fuzzy
+msgid "audit_modify_locked_group"
+msgstr "%1$s attempted to modify locked group %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:299
+#, fuzzy
+msgid "audit_modify_other_locale"
+msgstr "%1$s attempted to modify translations in %2$s without permission"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a platform, like <a>Windows</a>
+#: controllers/components/audit.php:135
+#, fuzzy
+msgid "audit_platform_create"
+msgstr "%1$s created platform %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a platform, like <a>Windows</a>
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:143
+#, fuzzy
+msgid "audit_platform_delete"
+msgstr "%1$s deleted platform %2$s (ID %3$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a platform, like <a>Windows</a>
+#: controllers/components/audit.php:138
+#, fuzzy
+msgid "audit_platform_edit"
+msgstr "%1$s edited platform %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a part of the admin, like 'Site Config'
+#: controllers/components/audit.php:288
+#, fuzzy
+msgid "audit_reauthentication_failure"
+msgstr "%1$s failed to re-authenticate to access %2$s."
+
+#. %1$s is <a>user name</a>
+#. %2$s is the name of a canned response, like 'Ready for the public'
+#: controllers/components/audit.php:198
+#, fuzzy
+msgid "audit_response_create"
+msgstr "%1$s created response %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is the name of a canned response, like 'Ready for the public'
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:206
+#, fuzzy
+msgid "audit_response_delete"
+msgstr "%1$s deleted response %2$s (ID %3$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is the name of a canned response, like 'Ready for the public'
+#: controllers/components/audit.php:201
+#, fuzzy
+msgid "audit_response_edit"
+msgstr "%1$s edited response %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:245
+#, fuzzy
+msgid "audit_review_approve"
+msgstr "%1$s approved review %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:250 controllers/components/audit.php:253
+#, fuzzy
+msgid "audit_review_delete"
+msgstr "%1$s deleted review %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:303
+#, fuzzy
+msgid "audit_security_default"
+msgstr "%1$s committed unknown security action %2$s to ID %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a category name, like <a>Search Tools</a>
+#: controllers/components/audit.php:118
+#, fuzzy
+msgid "audit_tag_create"
+msgstr "%1$s created tag %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a category name, like <a>Search Tools</a>
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:126
+#, fuzzy
+msgid "audit_tag_delete"
+msgstr "%1$s deleted category %2$s (ID %3$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a category name, like <a>Search Tools</a>
+#: controllers/components/audit.php:121
+#, fuzzy
+msgid "audit_tag_edit"
+msgstr "%1$s edited category %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:266
+#, fuzzy
+msgid "audit_update_applications"
+msgstr "%1$s updated application translations for %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:277
+#, fuzzy
+msgid "audit_update_blog"
+msgstr "%1$s updated blog post translations for %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:274
+#, fuzzy
+msgid "audit_update_platforms"
+msgstr "%1$s updated platform translations for %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:270
+#, fuzzy
+msgid "audit_update_tags"
+msgstr "%1$s updated category translations for %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>user name</a>
+#: controllers/components/audit.php:217
+#, fuzzy
+msgid "audit_user_edit"
+msgstr "%1$s edited %2$s's user information"
+
+#: controllers/addons_controller.php:1012
+msgid "browse_addons_name"
+msgstr "الإضاÙات حسب الاسم"
+
+#: controllers/addons_controller.php:1010
+msgid "browse_addons_newest"
+msgstr "الإضاÙات الأحدث"
+
+#: controllers/addons_controller.php:1008
+msgid "browse_addons_popular"
+msgstr "الإضاÙات الأكثر شعبية"
+
+#: controllers/addons_controller.php:1011
+msgid "browse_addons_rated"
+msgstr "الإضاÙات حسب التقييم"
+
+#: controllers/addons_controller.php:1009
+msgid "browse_addons_updated"
+msgstr "الإضاÙات المحدّثة مؤخرًا"
+
+#: views/elements/categories.thtml:73 views/elements/categories.thtml:82
+msgid "categories_current_title"
+msgstr "التصني٠الحالي"
+
+#: views/elements/categories.thtml:50
+#: views/elements/amo2009/categories.thtml:43
+#: views/elements/amo2009/categories.thtml:45
+msgid "categories_header"
+msgstr "التصنيÙات"
+
+#: views/elements/categories.thtml:50
+#: views/elements/amo2009/categories.thtml:41
+msgid "categories_header_title"
+msgstr "اختر تصنيÙًا"
+
+#. %1$s is the category name
+#: views/addons/searchengines.thtml:129
+#, php-format
+msgid "category_extra_see_all"
+msgstr "شاهد كل %1$s"
+
+#. %1$s is a number.
+#: models/collection.php:130
+#, fuzzy
+msgid "collection_description_limit"
+msgstr "The description should be less than %1$s characters."
+
+#. %1$s is the name of the collection
+#: controllers/collections_controller.php:392
+#, fuzzy
+msgid "collection_detail_rss_title"
+msgstr "%s Collection"
+
+#: controllers/collections_controller.php:1065
+#, fuzzy
+msgid "collection_error_deleting_addon"
+msgstr "Error deleting add-on!"
+
+#: controllers/collections_controller.php:1051
+#, fuzzy
+msgid "collection_error_saving_addon"
+msgstr "Error saving add-on!"
+
+#: controllers/collections_controller.php:1080
+#, fuzzy
+msgid "collection_error_saving_comment"
+msgstr "Error saving comment!"
+
+#. %1$s is a number.
+#: models/collection.php:122
+#, fuzzy
+msgid "collection_name_limit"
+msgstr "The name should be less than %1$s characters."
+
+#: controllers/collections_controller.php:352
+#: controllers/collections_controller.php:487
+msgid "collection_not_found"
+msgstr "المجموعة غير موجودة!"
+
+#. %1$s is the text on the "create collection" button
+#: views/collections/add.thtml:91
+#, fuzzy
+msgid "collections_add_formfield_addons_description"
+msgstr ""
+"If you already know which add-ons you want to add to your collection, just "
+"start typing their names below. If you'd rather wait and do this later, just "
+"click %1$s now."
+
+#: views/collections/add.thtml:90
+#, fuzzy
+msgid "collections_add_formfield_firstaddons"
+msgstr "Choose your first add-ons"
+
+#: views/collections/add.thtml:48
+#, fuzzy
+msgid "collections_add_header"
+msgstr "Create a Collection"
+
+#: views/collections/add.thtml:97
+#, fuzzy
+msgid "collections_add_header_selectedaddons"
+msgstr "Selected Add-ons"
+
+#: views/collections/add.thtml:50
+#, fuzzy
+msgid "collections_add_intro"
+msgstr ""
+"It's easy to create your own collection of add-ons by filling in a few "
+"fields below."
+
+#: views/collections/add.thtml:92 views/collections/add.thtml:103
+#, fuzzy
+msgid "collections_add_submit"
+msgstr "Create Collection"
+
+#: views/pages/collector_faq.thtml:50 views/pages/collector_firstrun.thtml:43
+#: views/pages/collector.thtml:47 views/pages/collector_features.thtml:55
+#: controllers/search_controller.php:302
+#: controllers/collections_controller.php:206
+#: controllers/collections_controller.php:405
+#: controllers/collections_controller.php:467
+#: controllers/collections_controller.php:539
+#, fuzzy
+msgid "collections_breadcrumb"
+msgstr "Collections"
+
+#: views/collections/detail.thtml:185
+#, fuzzy
+msgid "collections_detail_a_learn"
+msgstr "Learn More"
+
+#: views/elements/amo2009/collection_add_form.thtml:53
+#: views/elements/amo2009/collections_js_init.thtml:68
+#: views/pages/collector_firstrun.thtml:64
+#, fuzzy
+msgid "collections_detail_button_add"
+msgstr "Add to Favorites"
+
+#: views/elements/amo2009/collection_add_form.thtml:50
+#: views/elements/amo2009/collections_js_init.thtml:71
+#, fuzzy
+msgid "collections_detail_button_remove"
+msgstr "Remove from Favorites"
+
+#. %1$s is a URL.
+#. %2$s is a full <a href>.
+#: views/collections/detail.thtml:62
+#, fuzzy
+msgid "collections_detail_created_desc"
+msgstr ""
+"<p>You can view your new collection below. If you'd like to set a collection "
+"nickname, upload an icon, or change additional settings, please visit the <a "
+"href='%1$s'>Manage Collections</a> page.</p><p>Your collection can be "
+"accessed at this location: %2$s</p>"
+
+#: views/collections/detail.thtml:61
+#, fuzzy
+msgid "collections_detail_created_msg"
+msgstr "Your collection is now ready!"
+
+#: views/collections/detail.thtml:109
+#, fuzzy
+msgid "collections_detail_header_about"
+msgstr "About This Collection"
+
+#. %1$s is a number.
+#: views/collections/detail.thtml:126
+#, fuzzy
+msgid "collections_detail_header_count"
+msgid_plural "collections_detail_header_count"
+msgstr[0] "%1$s Add-on in this Collection"
+msgstr[1] "%1$s Add-ons in this Collection"
+
+#: views/collections/detail.thtml:113
+#, fuzzy
+msgid "collections_detail_info_created"
+msgstr "<strong>Created by:</strong> %1$s"
+
+#: views/collections/detail.thtml:117
+#, fuzzy
+msgid "collections_detail_info_updated"
+msgstr "<strong>Updated:</strong>"
+
+#: views/elements/amo2009/collections_js_init.thtml:62
+#, fuzzy
+msgid "collections_detail_js_adding"
+msgstr "Adding to Favorites&hellip;"
+
+#: views/elements/amo2009/collections_js_init.thtml:65
+#, fuzzy
+msgid "collections_detail_js_removing"
+msgstr "Removing Favorite&hellip;"
+
+#. %1$s is a URL
+#: views/collections/detail.thtml:90
+#, fuzzy
+msgid "collections_detail_login"
+msgstr "<a href=\"%1$s\">Log in</a> to add this collection to your favorites."
+
+#: views/collections/detail.thtml:104
+#, fuzzy
+msgid "collections_detail_manage"
+msgstr "Manage Collection"
+
+#: controllers/collections_controller.php:298
+#, fuzzy
+msgid "collections_detail_sort_date"
+msgstr "Date Added"
+
+#: controllers/collections_controller.php:299
+#, fuzzy
+msgid "collections_detail_sort_name"
+msgstr "Name"
+
+#: controllers/collections_controller.php:300
+#, fuzzy
+msgid "collections_detail_sort_popularity"
+msgstr "Popularity"
+
+#. %1$s is a number.
+#: views/collections/detail.thtml:166
+#, fuzzy
+msgid "collections_detail_weekly_downloads"
+msgid_plural "collections_detail_weekly_downloads"
+msgstr[0] "%1$s download this week"
+msgstr[1] "%1$s downloads this week"
+
+#: views/collections/edit.thtml:255
+#, fuzzy
+msgid "collections_edit_addons_delete_noscript"
+msgstr "Selected add-ons will be removed upon Save"
+
+#: views/collections/edit.thtml:247
+#, fuzzy
+msgid "collections_edit_addons_description"
+msgstr ""
+"To publish new add-ons to this collection, start typing their names below."
+
+#: views/collections/edit.thtml:248
+#, fuzzy
+msgid "collections_edit_addons_description_noscript"
+msgstr ""
+"To publish new add-ons to this collection, enter a comma-separated list of "
+"Add-on IDs below."
+
+#: views/collections/edit.thtml:247 views/collections/edit.thtml:248
+#, fuzzy
+msgid "collections_edit_addons_description_publish_detailspage"
+msgstr "You can also publish an add-on from its normal listing page."
+
+#. %1$s is the date the add-on was added to the collection
+#. %1$s is the name of the user who added the add-on to the collection
+#: views/collections/edit.thtml:260
+#, fuzzy
+msgid "collections_edit_addons_listitem_added"
+msgstr "Added %1$s by %2$s"
+
+#: views/collections/edit.thtml:263
+#, fuzzy
+msgid "collections_edit_addons_listitem_comment_add"
+msgstr "Add publisher comment"
+
+#: views/collections/edit.thtml:266
+#, fuzzy
+msgid "collections_edit_addons_listitem_comment_delete"
+msgstr "Delete publisher comment"
+
+#: views/collections/edit.thtml:265
+#, fuzzy
+msgid "collections_edit_addons_listitem_comment_edit"
+msgstr "Edit publisher comment"
+
+#: views/collections/edit.thtml:271
+#, fuzzy
+msgid "collections_edit_addons_listitem_comment_note"
+msgstr ""
+"Note: Comment will appear as though written by original publisher on the "
+"original publication date"
+
+#: views/collections/edit.thtml:270
+#, fuzzy
+msgid "collections_edit_addons_listitem_comment_submit"
+msgstr "Save Comment"
+
+#: views/collections/edit.thtml:261
+#, fuzzy
+msgid "collections_edit_addons_listitem_remove"
+msgstr "Remove"
+
+#: views/collections/edit.thtml:250
+#, fuzzy
+msgid "collections_edit_addons_submit"
+msgstr "Add to Collection"
+
+#: views/collections/edit.thtml:153
+#, fuzzy
+msgid "collections_edit_check_nickname"
+msgstr "Check Availability"
+
+#: views/collections/edit.thtml:299
+#, fuzzy
+msgid "collections_edit_confirm_deletecollection"
+msgstr "Yes, I would like to delete this collection."
+
+#. %1$s is the label of the edit form's submit button
+#: views/collections/edit.thtml:300
+#, fuzzy
+msgid "collections_edit_confirm_deletecollection_description"
+msgstr "Check the box, then click on \"%1$s\" to delete this collection."
+
+#. %1$s is the "delete" submit button text
+#. %2$s is the title of the "advanced" tab
+#: views/collections/edit.thtml:95
+#, fuzzy
+msgid "collections_edit_delete_upon_submit"
+msgstr ""
+"Upon clicking \"%1$s\" below, your collection will be deleted. If you do not "
+"want to delete your collection, uncheck the confirmation box in the \"%2$s\" "
+"tab and continue editing your collection. If you leave this page without "
+"saving, your collection will also not be deleted."
+
+#: views/collections/edit.thtml:94
+#, fuzzy
+msgid "collections_edit_delete_warning"
+msgstr "Your collection is about to be deleted!"
+
+#: views/collections/add.thtml:76 views/collections/edit.thtml:144
+#, fuzzy
+msgid "collections_edit_form_error_description"
+msgstr "You must provide a description of your collection."
+
+#: views/collections/edit.thtml:181
+#, fuzzy
+msgid "collections_edit_form_error_icon"
+msgstr "There was an error uploading your icon."
+
+#: views/collections/add.thtml:69 views/collections/edit.thtml:130
+#, fuzzy
+msgid "collections_edit_form_error_name"
+msgstr "You must give your collection a name."
+
+#: views/collections/edit.thtml:158
+#, fuzzy
+msgid "collections_edit_form_error_nickname"
+msgstr "If you choose a nickname, it must be unique."
+
+#: views/collections/add.thtml:93 views/collections/edit.thtml:249
+#, fuzzy
+msgid "collections_edit_formfield_addons"
+msgstr "Add-on name:"
+
+#: views/collections/edit.thtml:281
+#, fuzzy
+msgid "collections_edit_formfield_application"
+msgstr "Associated Application"
+
+#: views/collections/edit.thtml:282
+#, fuzzy
+msgid "collections_edit_formfield_application_description"
+msgstr "Select the application that your collection supports."
+
+#: views/collections/edit.thtml:288
+#, fuzzy
+msgid "collections_edit_formfield_collectiontype"
+msgstr "Collection Type"
+
+#: views/collections/edit.thtml:295
+#, fuzzy
+msgid "collections_edit_formfield_deletecollection"
+msgstr "Delete Collection"
+
+#: views/collections/edit.thtml:296
+#, fuzzy
+msgid "collections_edit_formfield_deletecollection_description"
+msgstr "Deleting your collection will permanently erase it."
+
+#: views/collections/add.thtml:73 views/collections/edit.thtml:140
+#, fuzzy
+msgid "collections_edit_formfield_description"
+msgstr "Collection Description"
+
+#: views/collections/add.thtml:74 views/collections/edit.thtml:141
+#, fuzzy
+msgid "collections_edit_formfield_description_description"
+msgstr "Briefly describe your collection and the kind of add-ons in it"
+
+#: views/collections/edit.thtml:162
+#, fuzzy
+msgid "collections_edit_formfield_icon"
+msgstr "Icon"
+
+#: views/collections/edit.thtml:163
+#, fuzzy
+msgid "collections_edit_formfield_icon_description"
+msgstr ""
+"You can upload a JPG, GIF or PNG icon that will be resized to 32x32 pixels."
+
+#: views/collections/add.thtml:80 views/collections/edit.thtml:189
+#, fuzzy
+msgid "collections_edit_formfield_listed"
+msgstr "Who can view your collection?"
+
+#: views/collections/add.thtml:81 views/collections/edit.thtml:190
+#, fuzzy
+msgid "collections_edit_formfield_listed_description"
+msgstr ""
+"By default, collections appear in the public Collection Directory and are "
+"discoverable by anyone. If you want to restrict your collection to be "
+"viewable only by people who are given a special link, choose that option "
+"below."
+
+#: views/collections/add.thtml:84 views/collections/edit.thtml:193
+#, fuzzy
+msgid "collections_edit_formfield_listed_false"
+msgstr "Only people I invite can view my collection"
+
+#: views/collections/add.thtml:83 views/collections/edit.thtml:192
+#, fuzzy
+msgid "collections_edit_formfield_listed_true"
+msgstr "Everyone can view my collection in the directory"
+
+#: views/collections/edit.thtml:223
+#, fuzzy
+msgid "collections_edit_formfield_managers"
+msgstr "Who can manage my collection?"
+
+#: views/collections/edit.thtml:224
+#, fuzzy
+msgid "collections_edit_formfield_managers_description"
+msgstr ""
+"These users can publish add-ons to your collection, manage all add-ons and "
+"settings, and grant other users permission."
+
+#: views/collections/add.thtml:66 views/collections/edit.thtml:126
+#, fuzzy
+msgid "collections_edit_formfield_name"
+msgstr "Collection Name"
+
+#: views/collections/add.thtml:67 views/collections/edit.thtml:127
+#, fuzzy
+msgid "collections_edit_formfield_name_description"
+msgstr ""
+"Give your collection a descriptive name, such as \"Dave's Favorite Travel "
+"Add-ons\""
+
+#: views/collections/edit.thtml:148
+#, fuzzy
+msgid "collections_edit_formfield_nickname"
+msgstr "Collection Nickname"
+
+#: views/collections/edit.thtml:149
+#, fuzzy
+msgid "collections_edit_formfield_nickname_description"
+msgstr "Optionally, give your collection a unique nickname for quick access:"
+
+#: views/collections/edit.thtml:201
+#, fuzzy
+msgid "collections_edit_formfield_publishers"
+msgstr "Who can publish add-ons to your collection?"
+
+#: views/collections/edit.thtml:202
+#, fuzzy
+msgid "collections_edit_formfield_publishers_description"
+msgstr ""
+"These users can publish add-ons to your collection and remove add-ons that "
+"they publish."
+
+#: views/collections/edit.thtml:210 views/collections/edit.thtml:232
+#, fuzzy
+msgid "collections_edit_formfield_users_add"
+msgstr "Enter the e-mail address of a Firefox Add-ons account:"
+
+#: views/collections/edit.thtml:216 views/collections/edit.thtml:238
+#, fuzzy
+msgid "collections_edit_formfield_users_delete_noscript"
+msgstr "Selected accounts will be removed upon Save"
+
+#: views/collections/edit.thtml:215 views/collections/edit.thtml:237
+#, fuzzy
+msgid "collections_edit_formfield_users_new_noscript"
+msgstr ""
+"Enter a comma-separated list of e-mail addresses of Firefox Add-ons accounts"
+
+#: views/collections/edit.thtml:204 views/collections/edit.thtml:226
+#, fuzzy
+msgid "collections_edit_formfield_users_onlyme"
+msgstr "Only me"
+
+#: views/collections/edit.thtml:205 views/collections/edit.thtml:227
+#, fuzzy
+msgid "collections_edit_formfield_users_otherusers"
+msgstr "Myself and these users:"
+
+#: views/collections/edit.thtml:211 views/collections/edit.thtml:233
+#, fuzzy
+msgid "collections_edit_formfield_users_submit"
+msgstr "Add"
+
+#. %1$s is the name of the collection
+#: views/collections/edit.thtml:68
+#, fuzzy
+msgid "collections_edit_header"
+msgstr "Manage %1$s"
+
+#: views/collections/edit.thtml:246
+#, fuzzy
+msgid "collections_edit_header_addons"
+msgstr "Manage Collection Contents"
+
+#: views/collections/edit.thtml:253 views/collections/edit.thtml:258
+#, fuzzy
+msgid "collections_edit_header_addons_current"
+msgstr "Current Add-ons:"
+
+#: views/collections/edit.thtml:279
+#, fuzzy
+msgid "collections_edit_header_advanced"
+msgstr "Advanced Settings"
+
+#: views/collections/edit.thtml:186
+#, fuzzy
+msgid "collections_edit_header_permissions"
+msgstr "Manage Collection Permissions"
+
+#: views/collections/edit.thtml:170
+#, fuzzy
+msgid "collections_edit_icon_cancel"
+msgstr "Cancel"
+
+#: views/collections/edit.thtml:174 views/collections/edit.thtml:179
+#, fuzzy
+msgid "collections_edit_icon_delete"
+msgstr "Delete Icon"
+
+#: views/collections/edit.thtml:178
+#, fuzzy
+msgid "collections_edit_icon_replace"
+msgstr "Replace Icon"
+
+#. %1$s is the label of the edit form's submit button
+#: views/collections/edit.thtml:169
+#, fuzzy
+msgid "collections_edit_icon_toberemoved"
+msgstr "Icon will be removed when \"%1$s\" is clicked below"
+
+#: views/collections/edit.thtml:155
+#, fuzzy
+msgid "collections_edit_nickname_available"
+msgstr "Nickname Available"
+
+#: controllers/collections_controller.php:943
+#, fuzzy
+msgid "collections_edit_nickname_error"
+msgstr ""
+"Your nickname contained invalid characters and was corrected. Please try "
+"again."
+
+#: views/collections/edit.thtml:156
+#, fuzzy
+msgid "collections_edit_nickname_taken"
+msgstr "Nickname Taken"
+
+#. This string is followed by a URL pointing to the collection's view page
+#: views/collections/edit.thtml:75
+#, fuzzy
+msgid "collections_edit_saved_nextstep"
+msgstr "Your collection can be accessed at this location:"
+
+#: views/collections/edit.thtml:74
+#, fuzzy
+msgid "collections_edit_saved_success"
+msgstr "Your collection was successfully saved!"
+
+#: views/collections/edit.thtml:169 views/collections/edit.thtml:300
+#: views/collections/edit.thtml:308 views/pages/js_constants.js.thtml:99
+#, fuzzy
+msgid "collections_edit_submit"
+msgstr "Update Collection"
+
+#: views/collections/edit.thtml:96 views/collections/edit.thtml:297
+#: views/pages/js_constants.js.thtml:100
+#, fuzzy
+msgid "collections_edit_submit_deletecollection"
+msgstr "Delete Collection"
+
+#: views/collections/edit.thtml:111
+#, fuzzy
+msgid "collections_edit_tabheader_addons"
+msgstr "Add-ons"
+
+#: views/collections/edit.thtml:97 views/collections/edit.thtml:113
+#, fuzzy
+msgid "collections_edit_tabheader_advanced"
+msgstr "Advanced"
+
+#: views/collections/edit.thtml:108
+#, fuzzy
+msgid "collections_edit_tabheader_details"
+msgstr "Name &amp; Details"
+
+#: views/collections/edit.thtml:109
+#, fuzzy
+msgid "collections_edit_tabheader_permissions"
+msgstr "Permissions"
+
+#: models/collection_promo.php:53
+#, fuzzy
+msgid "collections_family_tagline"
+msgstr "Add-ons can keep an eye on your kids and your calendar."
+
+#: models/collection_promo.php:53
+#, fuzzy
+msgid "collections_family_title"
+msgstr "Family Organizer"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:70
+#, fuzzy
+msgid "collections_index_a_check_out"
+msgstr "Check out Add-on Collector"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:52
+#, fuzzy
+msgid "collections_index_a_create"
+msgstr "Create a Collection"
+
+#: views/collections/detail.thtml:139 views/collections/listing.thtml:85
+#: views/search/collections.thtml:84
+#, fuzzy
+msgid "collections_index_button_go"
+msgstr "Go"
+
+#. %1$s is a URL.
+#: controllers/collections_controller.php:182
+#, fuzzy
+msgid "collections_index_filler_favorites"
+msgstr ""
+"<p><strong>You don't have any favorite collections yet.</strong></p> "
+"<p>Collections you mark as favorites can be quickly accessed from this page, "
+"and will appear in the <a href='%1$s'>Add-on Collector</a> if you've "
+"installed it.</p>"
+
+#. %1$s is a URL.
+#: controllers/collections_controller.php:167
+#, fuzzy
+msgid "collections_index_filler_mine"
+msgstr ""
+"<p>You haven't created any collections yet. Collections are easy to create "
+"and fill with your favorite add-ons. <a href='%1$s'>Try it out</a>!</p>"
+
+#: views/collections/listing.thtml:51
+#, fuzzy
+msgid "collections_index_header_collections"
+msgstr "Collections"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:60
+#, fuzzy
+msgid "collections_index_header_collector"
+msgstr "Add-on Collector"
+
+#. %1$s is a comma-separated list of author names
+#: views/elements/amo2009/collection_listing_item.thtml:84
+#: views/collections/detail.thtml:151
+#, fuzzy
+msgid "collections_index_header_created"
+msgstr "created by %1$s"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:47
+#, fuzzy
+msgid "collections_index_header_what"
+msgstr "What are Collections?"
+
+#: views/collections/detail.thtml:132 views/collections/listing.thtml:78
+#: views/search/collections.thtml:66
+#, fuzzy
+msgid "collections_index_label_sortby"
+msgstr "Sort by"
+
+#: controllers/collections_controller.php:130
+#, fuzzy
+msgid "collections_index_li_editors"
+msgstr "Editor's Picks"
+
+#: views/collections/subscribe.thtml:64
+#: controllers/collections_controller.php:140
+#, fuzzy
+msgid "collections_index_li_favorites"
+msgstr "My Favorites"
+
+#: controllers/collections_controller.php:138
+#, fuzzy
+msgid "collections_index_li_mine"
+msgstr "My Collections"
+
+#: controllers/collections_controller.php:132
+#, fuzzy
+msgid "collections_index_li_popular"
+msgstr "Popular"
+
+#: views/search/collections.thtml:74 controllers/collections_controller.php:81
+#, fuzzy
+msgid "collections_index_option_all"
+msgstr "Most popular all time"
+
+#: views/search/collections.thtml:72 controllers/collections_controller.php:78
+#, fuzzy
+msgid "collections_index_option_month"
+msgstr "Most popular this month"
+
+#: views/search/collections.thtml:76 controllers/collections_controller.php:84
+#, fuzzy
+msgid "collections_index_option_newest"
+msgstr "Newest"
+
+#: views/search/collections.thtml:70 controllers/collections_controller.php:75
+#, fuzzy
+msgid "collections_index_option_week"
+msgstr "Most popular this week"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:67
+#, fuzzy
+msgid "collections_index_p_collector"
+msgstr ""
+"There's a new way to manage and find favorite add-ons. Comment, share and "
+"sync collections, all from your browser"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:48
+#, fuzzy
+msgid "collections_index_p_what_are"
+msgstr "Collections are groups of related add-ons assembled for easy sharing."
+
+#. %s is a date in the _('date') format
+#: views/elements/collections_interactive_addon.thtml:85
+#, php-format
+msgid "collections_interactive_addon_added"
+msgstr "أضيÙت %s"
+
+#: models/collection_promo.php:55
+#, fuzzy
+msgid "collections_reference_tagline"
+msgstr "Add-ons can do better research online."
+
+#: models/collection_promo.php:55
+#, fuzzy
+msgid "collections_reference_title"
+msgstr "Reference Desk"
+
+#: models/collection_promo.php:52
+#, fuzzy
+msgid "collections_social_tagline"
+msgstr "Add-ons can manage your social network."
+
+#: models/collection_promo.php:52
+#, fuzzy
+msgid "collections_social_title"
+msgstr "Social Circuit"
+
+#: views/collections/subscribe.thtml:91
+#, fuzzy
+msgid "collections_subscribe_button_close"
+msgstr "Close"
+
+#: views/collections/subscribe.thtml:70
+#, fuzzy
+msgid "collections_subscribe_error"
+msgstr ""
+"An error occurred trying to add a favorite collection. Is this collection "
+"already a favorite?"
+
+#: views/collections/subscribe.thtml:96
+#, fuzzy
+msgid "collections_subscribe_label_bothersome"
+msgstr "Don't show me this message again."
+
+#. %1$s is the collection name
+#: views/collections/subscribe.thtml:60
+#, fuzzy
+msgid "collections_subscribe_success"
+msgstr "%1$s has been added to your favorite collections."
+
+#. %1$s is the link to the "My Favorites" tab on the main collections page
+#. %2$s is the localized title of the "My Favorites" tab
+#. %3$s is the link URL to the collector add-on
+#: views/collections/subscribe.thtml:62
+#, fuzzy
+msgid "collections_subscribe_success_desc"
+msgstr ""
+"You can now quickly find this collection from the <a href=\"%1$s\">%2$s</a> "
+"tab in the directory. For an even easier way to keep track of your favorite "
+"collections, try out our <a href=\"%3$s\">Add-on Collector</a> extension for "
+"Firefox."
+
+#: views/collections/listing.thtml:55
+#, fuzzy
+msgid "collections_success_delete"
+msgstr "The collection has been deleted."
+
+#: models/collection_promo.php:54
+#, fuzzy
+msgid "collections_travel_tagline"
+msgstr "Add-ons can turn you into a travel agent."
+
+#: models/collection_promo.php:54
+#, fuzzy
+msgid "collections_travel_title"
+msgstr "The Traveler's Pack"
+
+#. A collection of add-ons that is automatically built for a user. They are "automatically published" to this collection.
+#: controllers/collections_controller.php:581
+#, fuzzy
+msgid "collections_type_autopublisher"
+msgstr "Auto-publisher"
+
+#. A collection that has been chosen by an Editor as notable or exceptional
+#: controllers/collections_controller.php:582
+#, fuzzy
+msgid "collections_type_editorspick"
+msgstr "Editor's Pick"
+
+#: controllers/collections_controller.php:580
+#, fuzzy
+msgid "collections_type_normal"
+msgstr "Normal"
+
+#: views/collections/subscribe.thtml:84
+#, fuzzy
+msgid "collections_unsubscribe_error"
+msgstr ""
+"An error occurred trying to remove a favorite collection. Was this "
+"collection not a favorite?"
+
+#. %1$s is the collection name
+#: views/collections/subscribe.thtml:78
+#, fuzzy
+msgid "collections_unsubscribe_success"
+msgstr "%1$s has been removed from your favorite collections."
+
+#: models/collection_promo.php:56
+#, fuzzy
+msgid "collections_webdev_tagline"
+msgstr "Add-ons make it easier to build the perfect website."
+
+#: models/collection_promo.php:56
+#, fuzzy
+msgid "collections_webdev_title"
+msgstr "Web Developer's Toolbox"
+
+#: views/elements/amo2009/collections_sidebar_whatare.thtml:40
+#, fuzzy
+msgid "collections_whatare_header"
+msgstr "What are Collections?"
+
+#: views/elements/amo2009/collections_sidebar_whatare.thtml:45
+#, fuzzy
+msgid "collections_whatare_learnmore"
+msgstr "Read the FAQ"
+
+#: views/elements/amo2009/collections_sidebar_whatare.thtml:44
+#, fuzzy
+msgid "collections_whatare_text"
+msgstr ""
+"There’s a new way to manage and find favorite add-ons. Comment, share and "
+"sync collections, all from your browser."
+
+#: views/pages/collector_faq.thtml:61 views/pages/collector_features.thtml:67
+#, fuzzy
+msgid "collector_features_a_home"
+msgstr "Add-on Collector Home"
+
+#: views/elements/amo2009/collector_sidebar_download.thtml:46
+#, fuzzy
+msgid "collector_features_heading_download"
+msgstr "Download the Add-on Collector:"
+
+#: views/elements/amo2009/collector_sidebar_download.thtml:43
+#: views/pages/collector_firstrun.thtml:116 views/pages/collector.thtml:69
+#, fuzzy
+msgid "collector_features_img_logo"
+msgstr "Add-on Collector Logo"
+
+#: views/compatibility/dashboard.thtml:49
+#: controllers/compatibility_controller.php:72
+msgid "compatibility_dashboard_center_header"
+msgstr "مركز تواÙقية الإضاÙات"
+
+#. %1$s is the name of an application and a version. Example: Firefox 3.0
+#. %2$s is the name of an application. Example: Firefox
+#: views/compatibility/dashboard.thtml:50
+msgid "compatibility_dashboard_intro"
+msgstr ""
+"كن مستعدًا لإصدار %1$s مع الأدوات والمعلومات المتاحة لمجتمع إضاÙات %2$s "
+"الموجودة أدناه."
+
+#: views/compatibility/dashboard.thtml:103
+msgid "compatibility_dashboard_loading"
+msgstr "يجري تحميل البيانات..."
+
+#: views/compatibility/dashboard.thtml:45
+msgid "compatibility_dashboard_main_link"
+msgstr "عودة إلى الرئيسية"
+
+#: views/compatibility/dashboard.thtml:100 views/compatibility/report.thtml:43
+msgid "compatibility_dashboard_report"
+msgstr "تقرير تواÙقية الإضاÙØ©"
+
+#: views/compatibility/dashboard.thtml:53
+#: views/compatibility/dashboard.thtml:110
+#: views/compatibility/developers.thtml:43
+msgid "compatibility_developer_info"
+msgstr "معلومات لمطوّري الإضاÙات"
+
+#: views/compatibility/developers.thtml:66
+msgid "compatibility_developers_adjust_maxversion"
+msgstr "صحّح الإصدارة القصوى دون أن تعيد الرÙع"
+
+#: views/compatibility/dashboard.thtml:124
+msgid "compatibility_developers_check_status"
+msgstr "تحقق من حالة إضاÙاتي"
+
+#. %1$s is a URL
+#. %2$s is an application and version. Example: Firefox 3.0
+#: views/compatibility/dashboard.thtml:126
+msgid "compatibility_developers_login_first"
+msgstr ""
+"إن كان لديك إضاÙات مستضاÙØ© ÙÙŠ موقع إضاÙات موزيلا، <a href=\"%1$s\">سجّل دخولك "
+"رجاءً</a> لتحليل حالة إضاÙاتك ل†%2$s."
+
+#: views/compatibility/dashboard.thtml:114
+msgid "compatibility_developers_mdclogo_alt"
+msgstr "شعار مركز تطوير موزيلا"
+
+#: views/compatibility/developers.thtml:73
+msgid "compatibility_developers_no_addons"
+msgstr "ليس لديك أي إضاÙات مستضاÙØ© ÙÙŠ موقع إضاÙات موزيلا."
+
+#: views/compatibility/dashboard.thtml:133
+#: views/compatibility/developers.thtml:55
+msgid "compatibility_developers_results"
+msgstr "نتائج التحقق من حالة الإضاÙات"
+
+#: views/compatibility/dashboard.thtml:137
+msgid "compatibility_developers_retrieving"
+msgstr "يجري استخلاص حالة الإضاÙات المستضاÙØ©..."
+
+#. %1$s is a number
+#. %2$s is an application name
+#. %3$s is a number.
+#. Full example: 50 Firefox users (10% of total)
+#: views/compatibility/developers.thtml:65
+msgid "compatibility_developers_user_count"
+msgstr "%1$s مستخدمًا ل†%2$s (%3$s&#37; من الكل)"
+
+#: views/compatibility/report.thtml:45
+msgid "compatibility_report_detail_intro"
+msgstr ""
+"الإضاÙات أدناه تشكّل 95% من استخدام الإضاÙات المعرو٠لموزيلا، وهي مرتبة حسب "
+"مقدار الاستخدام."
+
+#: views/compatibility/dashboard.thtml:94
+msgid "compatibility_report_detailed_link"
+msgstr "شاهد التقرير المÙصّل"
+
+#. %1$s and %2$s are numbers
+#. %3$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:65
+msgid "compatibility_report_intro"
+msgstr ""
+"من بين %1$s إضاÙØ© تشكّل 95% من استخدام الإضاÙات المعرو٠لموزيلا، تÙعتبر <b>%2"
+"$s&#37;</b> منها متواÙقة حاليًا مع آخر إصدارات %3$s."
+
+#: views/compatibility/dashboard.thtml:81
+msgid "compatibility_report_legend_alpha"
+msgstr "إصدارات ألÙا"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:81
+msgid "compatibility_report_legend_alpha_description"
+msgstr "الإضاÙات المتواÙقة مع إصدارة ألÙا من %1$s"
+
+#: views/compatibility/dashboard.thtml:85
+msgid "compatibility_report_legend_beta"
+msgstr "إصدارات بيتا"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:85
+msgid "compatibility_report_legend_beta_description"
+msgstr "الإضاÙات المتواÙقة مع إصدارة بيتا أو إصدارة مرشحة من %1$s"
+
+#: views/compatibility/dashboard.thtml:89
+msgid "compatibility_report_legend_latest"
+msgstr "آخر إصدارة"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:89
+msgid "compatibility_report_legend_latest_description"
+msgstr "الإضاÙات المحدّثة لآخر إصدارات %1$s"
+
+#: views/compatibility/dashboard.thtml:77
+msgid "compatibility_report_legend_other"
+msgstr "إصدارات أخرى"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:77
+msgid "compatibility_report_legend_other_description"
+msgstr "الإضاÙات غير المتواÙقة مع أي إصدارات من %1$s"
+
+#: views/compatibility/dashboard.thtml:62
+msgid "compatibility_report_title"
+msgstr "تقرير تواÙقية الإضاÙØ©"
+
+#: views/compatibility/dashboard.thtml:54
+#: views/compatibility/dashboard.thtml:144 views/compatibility/users.thtml:42
+msgid "compatibility_user_info"
+msgstr "معلومات لمستخدمي الإضاÙØ©"
+
+#: views/compatibility/dashboard.thtml:52
+msgid "compatibility_view_report"
+msgstr "شاهد تقرير التواÙقية"
+
+#. %s is a URL
+#: views/pages/credits.thtml:142
+#, php-format
+msgid "credits_contributing"
+msgstr "لمعرÙØ© معلومات عن المشاركة، انظر %s."
+
+#: views/pages/credits.thtml:142
+msgid "credits_contributing_wikipage"
+msgstr "صÙحة الويكي"
+
+#: views/pages/credits.thtml:99
+msgid "credits_intro"
+msgstr ""
+"تودّ موزيلا أن تشكر الأشخاص التالية أسماؤهم لمساهمتهم ÙÙŠ مشروع addons.mozilla."
+"org project خلال هذه السنوات:"
+
+#: views/pages/credits.thtml:103
+msgid "credits_section_developers"
+msgstr "المطوّرون"
+
+#: views/pages/credits.thtml:115
+msgid "credits_section_editors"
+msgstr "المحرّرون"
+
+#: views/pages/credits.thtml:109
+msgid "credits_section_localizers"
+msgstr "المترجمون"
+
+#: views/pages/credits.thtml:121
+msgid "credits_section_other_contributors"
+msgstr "مشاركون آخرون"
+
+#: views/pages/credits.thtml:127
+msgid "credits_section_past_developers"
+msgstr "مطوّرون سابقون"
+
+#: views/pages/credits.thtml:133
+msgid "credits_section_software"
+msgstr "البرنامج والصور"
+
+#: views/pages/credits.thtml:136
+msgid "credits_software_famfamfam"
+msgstr ""
+"بعض الأيقونات المستخدمة مأخوذة من <a href=\"http://www.famfamfam.com/lab/"
+"icons/silk/\">مجموعة أيقونات famfamfam Silk</a>ØŒ والمرخصة ÙˆÙÙ‚ <a href="
+"\"http://creativecommons.org/licenses/by/2.5/\">Creative Commons Attribution "
+"2.5 License</a>."
+
+#: views/pages/credits.thtml:137
+#, fuzzy
+msgid "credits_software_timeplot"
+msgstr ""
+"Some pages use elements of <a href=\"http://www.simile-widgets.org/timeplot/"
+"\">Timeplot</a>, licensed under a <a href=\"http://simile.mit.edu/license."
+"html\">BSD License</a>."
+
+#. date format string as used in PHP's strftime():
+#. http://php.net/strftime
+#: views/elements/collections_interactive_addon.thtml:85
+#: views/elements/amo2009/addon_version_detail.thtml:53
+#: views/elements/amo2009/homepage_addon.thtml:115
+#: views/elements/addon_version_detail.thtml:54
+#: views/elements/addon_listitem.thtml:124 views/elements/feature.thtml:106
+#: views/collections/detail.thtml:118 views/collections/edit.thtml:325
+#: views/users/info.thtml:76 views/editors/reviews_queue.thtml:57
+#: views/editors/reviews_queue.thtml:68 views/developers/dashboard.thtml:65
+#: views/developers/versions_edit.thtml:208 views/developers/versions.thtml:67
+#: views/search/rss/index.thtml:5 views/addons/rss/versions.thtml:42
+#: views/addons/display.thtml:104 views/addons/display.thtml:356
+#: views/addons/browse_thumbs.thtml:75 views/reviews/add.thtml:63
+#: views/reviews/display.thtml:74 views/reviews/display.thtml:160
+#: views/reviews/delete.thtml:54 controllers/statistics_controller.php:244
+#: controllers/collections_controller.php:1047
+msgid "date"
+msgstr "%e %B، %Y"
+
+#. date and time format string (strftime)
+#. http://php.net/strftime
+#: views/elements/addon_version_detail.thtml:53
+#: views/developers/discuss.thtml:52 views/developers/discuss.thtml:62
+#: views/admin/addons_status.thtml:57
+msgid "datetime"
+msgstr "%e %B، %Y، %I:%M %p"
+
+#: views/elements/developers/actionbar.thtml:47
+msgid "devcp_actionbar_link_details"
+msgstr "معلومات Ù…Ùصلة"
+
+#: views/elements/developers/actionbar.thtml:42
+#: views/elements/developers/actionbar.thtml:50
+#: views/developers/dashboard.thtml:64
+msgid "devcp_actionbar_link_edit"
+msgstr "حرّر الإضاÙØ©"
+
+#: views/elements/developers/actionbar.thtml:51
+msgid "devcp_actionbar_link_newversion"
+msgstr "ارÙع إصدارة جديدة"
+
+#: views/elements/developers/actionbar.thtml:44
+#: views/elements/developers/actionbar.thtml:49
+#: views/developers/dashboard.thtml:73
+msgid "devcp_actionbar_link_stats"
+msgstr "لوحة الإحصائيات"
+
+#. %1$s is a filename, e.g. "foo.txt"
+#. %2$s is the extension, e.g. ".txt"
+#. %3$s is a list of valid extensions, like ".png, .jpg, .gif"
+#: controllers/developers_controller.php:1361
+#, fuzzy
+msgid "devcp_add_previews_extension_error"
+msgstr "File %1$s has an invalid extension (%2$s). Allowed extensions: %3$s"
+
+#. %s is the filename.
+#: controllers/developers_controller.php:1394
+#, fuzzy
+msgid "devcp_add_previews_save_error"
+msgstr "File %s could not be saved to the database. Please try again."
+
+#. %1$s is the preview ID number, %2$s is the filename.
+#: controllers/developers_controller.php:1389
+#, fuzzy
+msgid "devcp_add_previews_success_replace"
+msgstr "Preview %1$s was replaced with file %2$s successfully."
+
+#. %s is the filename.
+#: controllers/developers_controller.php:1391
+#, fuzzy
+msgid "devcp_add_previews_success_upload"
+msgstr "File %s was uploaded successfully. You can add a caption below."
+
+#: controllers/components/developers.php:1163
+msgid "devcp_additem_addontype_autodetect"
+msgstr "(اكتشاÙ-تلقائي)"
+
+#: views/elements/developers/additem.thtml:76
+msgid "devcp_additem_linktitle_opensin_newwindow"
+msgstr "ÙŠÙتح ÙÙŠ ناÙذة جديدة"
+
+#: views/elements/developers/additem.thtml:41
+msgid "devcp_additem_sidebar_title"
+msgstr "أرسÙÙ„ الإضاÙØ©"
+
+#: views/elements/developers/additem.thtml:53
+msgid "devcp_additem_step0_newlink"
+msgstr "اتÙاقية المطوّر"
+
+#: views/elements/developers/additem.thtml:46
+msgid "devcp_additem_step1_link"
+msgstr "الخطوة الأولى: رÙع الملÙ"
+
+#: views/elements/developers/additem.thtml:47
+msgid "devcp_additem_step2_link"
+msgstr "الخطوة الثانية: تÙاصيل الملÙ"
+
+#: views/elements/developers/additem.thtml:48
+msgid "devcp_additem_step3_link"
+msgstr "الخطوة الثالثة: تÙاصيل الإصدارة"
+
+#: views/elements/developers/additem.thtml:49
+msgid "devcp_additem_step4_link"
+msgstr "الخطة الرابعة: الترجمة"
+
+#: views/elements/developers/additem.thtml:50
+msgid "devcp_additem_step5_link"
+msgstr "الخطوة الخامسة: نجاح"
+
+#: views/elements/developers/additem.thtml:76
+msgid "devcp_additem_submissionhelp_link"
+msgstr "مساعدة الإرسال"
+
+#: controllers/previews_controller.php:168
+#: controllers/previews_controller.php:277
+msgid "devcp_addon_field_preview_caption_displaytitle"
+msgstr "معاينة العنوان"
+
+#: views/developers/addon_status.thtml:177
+#, fuzzy
+msgid "devcp_addon_status_action_activate"
+msgstr "Make Active"
+
+#: views/developers/addon_status.thtml:178
+#, fuzzy
+msgid "devcp_addon_status_action_activate_description"
+msgstr ""
+"Make your add-on active for it to show up in public listings and enable the "
+"update check service."
+
+#: views/developers/addon_status.thtml:135
+#, fuzzy
+msgid "devcp_addon_status_action_complete"
+msgstr "Complete Add-on"
+
+#: views/developers/addon_status.thtml:136
+#, fuzzy
+msgid "devcp_addon_status_action_complete_description"
+msgstr "Complete your add-on and move to the Sandbox"
+
+#: views/developers/addon_status.thtml:181
+#, fuzzy
+msgid "devcp_addon_status_action_deactivate"
+msgstr "Make Inactive"
+
+#: views/developers/addon_status.thtml:182
+#, fuzzy
+msgid "devcp_addon_status_action_deactivate_description"
+msgstr ""
+"Make your add-on inactive to hide it from all public listings and disable "
+"the update check service."
+
+#: views/developers/addon_status.thtml:143
+#, fuzzy
+msgid "devcp_addon_status_action_move"
+msgstr "Move to Sandbox"
+
+#: views/developers/addon_status.thtml:144
+#, fuzzy
+msgid "devcp_addon_status_action_move_description"
+msgstr "Move your add-on back to the Sandbox. This is reversible."
+
+#: views/developers/addon_status.thtml:139
+#, fuzzy
+msgid "devcp_addon_status_action_nominate"
+msgstr "Nominate for Public"
+
+#: views/developers/addon_status.thtml:140
+#, fuzzy
+msgid "devcp_addon_status_action_nominate_description"
+msgstr "Nominate your add-on to become Public"
+
+#: views/developers/addon_status.thtml:147
+#, fuzzy
+msgid "devcp_addon_status_action_public"
+msgstr "Make Public"
+
+#: views/developers/addon_status.thtml:148
+#, fuzzy
+msgid "devcp_addon_status_action_public_description"
+msgstr "Make your add-on Public again."
+
+#: views/developers/addon_status.thtml:169
+#, fuzzy
+msgid "devcp_addon_status_active"
+msgstr ""
+"Your add-on is <span class=\"inactive-0\">Active</span>. This means your add-"
+"on is showing up in all available listings appropriate for its status above."
+
+#: views/developers/addon_status.thtml:111
+#, fuzzy
+msgid "devcp_addon_status_completion_disabled"
+msgstr ""
+"Please fulfill the criteria above before you can complete your add-on and "
+"move it to the <span class=\"status-1\">Sandbox</span>."
+
+#: views/developers/addon_status.thtml:108
+#, fuzzy
+msgid "devcp_addon_status_completion_enabled"
+msgstr ""
+"You may now complete your add-on and move it to the <span class=\"status-1"
+"\">Sandbox</span> by clicking the button below."
+
+#: views/developers/addon_status.thtml:102
+#, fuzzy
+msgid "devcp_addon_status_criteria_category"
+msgstr "At least one category selected"
+
+#: views/developers/addon_status.thtml:101
+#, fuzzy
+msgid "devcp_addon_status_criteria_description"
+msgstr "Add-on Description required"
+
+#: views/developers/addon_status.thtml:99
+#, fuzzy
+msgid "devcp_addon_status_criteria_name"
+msgstr "Add-on Name required"
+
+#: views/developers/addon_status.thtml:120
+#, fuzzy
+msgid "devcp_addon_status_criteria_prerelease"
+msgstr "Add-on is not marked as pre-release."
+
+#: views/developers/addon_status.thtml:119
+#, fuzzy
+msgid "devcp_addon_status_criteria_preview"
+msgstr "At least one preview image required for extensions and themes."
+
+#: views/developers/addon_status.thtml:100
+#, fuzzy
+msgid "devcp_addon_status_criteria_summary"
+msgstr "Add-on Summary required"
+
+#. %s is the status in a span, e.g. "<span>_('Public')</span>".
+#: views/developers/addon_status.thtml:58
+#, fuzzy
+msgid "devcp_addon_status_header"
+msgstr "Add-on Status: %s"
+
+#: views/developers/addon_status.thtml:152
+#: views/developers/addon_status.thtml:173
+#, fuzzy
+msgid "devcp_addon_status_header_actions"
+msgstr "Available Actions"
+
+#: views/developers/addon_status.thtml:168
+#, fuzzy
+msgid "devcp_addon_status_header_active"
+msgstr "Active Status: <span class=\"inactive-0\">Active</span>"
+
+#: views/developers/addon_status.thtml:97
+#, fuzzy
+msgid "devcp_addon_status_header_criteria"
+msgstr "Add-on Completion Criteria"
+
+#: views/developers/addon_status.thtml:164
+#, fuzzy
+msgid "devcp_addon_status_header_inactive"
+msgstr "Active Status: <span class=\"inactive-1\">Inactive</span>"
+
+#: views/developers/addon_status.thtml:117
+#, fuzzy
+msgid "devcp_addon_status_header_nomination"
+msgstr "Public Nomination Criteria"
+
+#: views/developers/addon_status.thtml:190
+#, fuzzy
+msgid "devcp_addon_status_header_trusted"
+msgstr "Trusted Status: <span class=\"status-4\">Trusted</span>"
+
+#: views/developers/addon_status.thtml:165
+#, fuzzy
+msgid "devcp_addon_status_inactive"
+msgstr ""
+"Your add-on is <span class=\"inactive-1\">Inactive</span>. This means your "
+"add-on will not show up in any listing, regardless of its status above. "
+"Updates are <b>not</b> being provided to your add-on through the update "
+"check service."
+
+#: views/developers/addon_status.thtml:128
+#, fuzzy
+msgid "devcp_addon_status_nominate_disabled"
+msgstr ""
+"Please fulfill the criteria above before nominating your add-on to become "
+"<span class=\"status-4\">Public</span>."
+
+#: views/developers/addon_status.thtml:125
+#, fuzzy
+msgid "devcp_addon_status_nominate_enabled"
+msgstr ""
+"You may now nominate your add-on for <span class=\"status-4\">Public</span> "
+"by clicking the button below."
+
+#: views/developers/addon_status.thtml:64
+#, fuzzy
+msgid "devcp_addon_status_public"
+msgstr "Public"
+
+#: views/developers/addon_status.thtml:63
+#, fuzzy
+msgid "devcp_addon_status_sandbox"
+msgstr "Sandbox"
+
+#. %s is an email address.
+#: views/developers/addon_status.thtml:89
+#, fuzzy
+msgid "devcp_addon_status_switch_disabled"
+msgstr ""
+"Your add-on was <span class=\"status-5\">Disabled</span> by an administrator "
+"and cannot be used. If you have any questions, please e-mail %s."
+
+#: views/developers/addon_status.thtml:67
+#, fuzzy
+msgid "devcp_addon_status_switch_incomplete"
+msgstr ""
+"Your add-on is currently <span class=\"status-0\">Incomplete</span>. This "
+"means your add-on is not showing up on any portion of the site or update "
+"check service. You may come to this page to complete your add-on after it "
+"meets the criteria below for completion and transfer to the <span class="
+"\"status-1\">Sandbox</span>."
+
+#. %s is a number, perhaps 42.
+#: views/developers/addon_status.thtml:77
+#, fuzzy
+msgid "devcp_addon_status_switch_nominated"
+msgstr ""
+"Your add-on is currently nominated to become <span class=\"status-4"
+"\">Public</span> and is awaiting editor review. There are currently %s other "
+"add-ons in the nomination queue."
+
+#. %s is an email address.
+#: views/developers/addon_status.thtml:81
+#, fuzzy
+msgid "devcp_addon_status_switch_pending"
+msgstr ""
+"Your add-on is pending. This shouldn't have happened. Please e-mail %s with "
+"your add-on ID and state this error."
+
+#: views/developers/addon_status.thtml:85
+#, fuzzy
+msgid "devcp_addon_status_switch_public"
+msgstr ""
+"Your add-on is <span class=\"status-4\">Public</span>, which means it will "
+"show up in all listings and searches and can be downloaded without "
+"restriction. Updates are being provided to your add-on through the update "
+"check service."
+
+#: views/developers/addon_status.thtml:71
+#: views/developers/addon_status.thtml:75
+#, fuzzy
+msgid "devcp_addon_status_switch_sandbox"
+msgstr ""
+"Your add-on is in the <span class=\"status-1\">Sandbox</span>, which means "
+"it will show up in listings and searches, but users must log in to download "
+"it. Updates are <b>not</b> being provided to your add-on through the update "
+"check service."
+
+#. %s is the add-on name.
+#: views/developers/addon_status_nominate.thtml:43
+#: views/developers/addon_status_confirm.thtml:43
+#: views/developers/addon_status.thtml:43
+#, fuzzy
+msgid "devcp_addon_status_title"
+msgstr "%s Status"
+
+#: views/developers/addon_status.thtml:191
+#, fuzzy
+msgid "devcp_addon_status_trusted"
+msgstr ""
+"Your add-on is <span class=\"status-4\">Trusted</span>. This means you can "
+"submit updates to your add-on without editor review."
+
+#: views/developers/dashboard.thtml:68
+#, fuzzy
+msgid "devcp_dashboard_active"
+msgstr "Active"
+
+#. %1$s is the add-on type string
+#. %2$s is Inactive or Active in a <span>
+#. %3$s is the addon's public status (Public, In Sandbox, ...) in a <span>
+#: views/developers/dashboard.thtml:69
+#, fuzzy
+msgid "devcp_dashboard_addontype_status"
+msgstr "%1$s currenty %2$s and %3$s"
+
+#: views/developers/dashboard.thtml:67
+#, fuzzy
+msgid "devcp_dashboard_change_status"
+msgstr "Change Status"
+
+#. %s is the addons email address.
+#: views/developers/dashboard.thtml:99
+#, fuzzy
+msgid "devcp_dashboard_disabled_questions"
+msgstr ""
+"Your add-on was disabled by an administrator and cannot be used. If you "
+"have any questions, please email %s."
+
+#. %s is the (localized) add-on status string in a span, e.g. "Disabled"
+#: views/developers/dashboard.thtml:98
+#, fuzzy
+msgid "devcp_dashboard_disabled_status"
+msgstr "Add-on Status: %s"
+
+#: views/developers/dashboard.thtml:43
+#, fuzzy
+msgid "devcp_dashboard_header_main"
+msgstr "Developer Dashboard"
+
+#: views/developers/dashboard.thtml:110
+#, fuzzy
+msgid "devcp_dashboard_header_welcome"
+msgstr "Welcome to the Developer Dashboard"
+
+#: views/developers/dashboard.thtml:68
+#, fuzzy
+msgid "devcp_dashboard_inactive"
+msgstr "Inactive"
+
+#. %s is a date in the _('date') format
+#: views/developers/dashboard.thtml:65
+#, fuzzy
+msgid "devcp_dashboard_last_edited"
+msgstr "Last edited on %s"
+
+#: views/developers/dashboard.thtml:111
+#, fuzzy
+msgid "devcp_dashboard_learn"
+msgstr ""
+"You don't currently have any add-ons hosted on Mozilla Add-ons. To learn how "
+"the process works and submit your first add-on, click Get Started below."
+
+#: views/developers/dashboard.thtml:112
+#, fuzzy
+msgid "devcp_dashboard_start"
+msgstr "Get Started"
+
+#: views/developers/dashboard.thtml:82
+#, fuzzy
+msgid "devcp_dashboard_versions"
+msgstr "Versions and Files"
+
+#: views/developers/dashboard.thtml:91
+#, fuzzy
+msgid "devcp_dashboard_versions_new"
+msgstr "Upload a new version"
+
+#. %s is the preview ID number.
+#: controllers/developers_controller.php:1415
+#, fuzzy
+msgid "devcp_delete_previews_error"
+msgstr "Preview %s could not be deleted from the database. Please try again."
+
+#. %s is the preview ID number.
+#: controllers/developers_controller.php:1413
+#, fuzzy
+msgid "devcp_delete_previews_success"
+msgstr "Preview %s has been deleted successfully."
+
+#: controllers/developers_controller.php:1089
+#, fuzzy
+msgid "devcp_delete_version_priv_error"
+msgstr "You do not have privileges to delete versions or files."
+
+#. %1$s is the count of files, a number
+#. %2$s is a status string like _('Public') or _('Incomplete')
+#: controllers/components/amo.php:549
+#, fuzzy
+msgid "devcp_describe_version_status"
+msgid_plural "devcp_describe_version_status"
+msgstr[0] "%1$s %2$s file"
+msgstr[1] "%1$s %2$s files"
+
+#. %s is a version number. Example: 3.0
+#: views/developers/versions.thtml:65
+#, php-format
+msgid "devcp_details_version"
+msgstr "الإصدارة %s"
+
+#: views/developers/discuss.thtml:68
+msgid "devcp_discuss_addreply_header"
+msgstr "إضاÙØ© ردّ"
+
+#: views/developers/discuss.thtml:57
+msgid "devcp_discuss_allreplies_header"
+msgstr "الردود"
+
+#. notice when an error occurs saving a discussion reply
+#. %1 is the email address (linked) for the amo-editors list
+#: views/developers/discuss.thtml:70
+msgid "devcp_discuss_error_notice"
+msgstr "حصل خطأ عند Ø­Ùظ ردّك. تواصل رجاءً مع %1$s وأخبره عن هذه المشكلة."
+
+#. %1 is the add-on name, %2 is the add-on's version number currently being reviewed by an editor
+#: views/developers/discuss.thtml:46
+msgid "devcp_discuss_intro"
+msgstr ""
+"يطلب محرر إضاÙات موزيلا منك المزيد من المعلومات بخصوص الإصدارة %2$s من "
+"إضاÙتك %1$s."
+
+#. %1 is the add-on name
+#: views/developers/discuss.thtml:43
+msgid "devcp_discuss_pagetitle"
+msgstr "قدّم المزيد من المعلومات ÙÙŠ مراجعة الإضاÙØ© %1$s"
+
+#. submit button text
+#: views/developers/discuss.thtml:79
+msgid "devcp_discuss_submit_reply"
+msgstr "أرسÙÙ„ الردّ"
+
+#: views/developers/discuss.thtml:72
+msgid "devcp_discuss_success_message"
+msgstr "Ø£Ùرسل ردّك بنجاح. سيستلم المشاركون ÙÙŠ المناقشة إشعارًا بريديًا بذلك."
+
+#. in an author/editor discussion about an add-on to be reviewed:
+#. %1 is the commenter's user name (linked).
+#. %2 is the full date the comment was made.
+#: views/developers/discuss.thtml:52 views/developers/discuss.thtml:62
+msgid "devcp_discuss_writtenby"
+msgstr "كتبه %1$s ÙÙŠ %2$s"
+
+#: views/developers/addon_edit_authors.thtml:72
+#: views/developers/addon_edit_authors.thtml:81
+#, fuzzy
+msgid "devcp_edit_authors_add_author"
+msgstr "Add New Author"
+
+#: views/developers/addon_edit_authors.thtml:96
+#, fuzzy
+msgid "devcp_edit_authors_add_author_button"
+msgstr "Add Author"
+
+#: views/developers/addon_edit_authors.thtml:83
+#, fuzzy
+msgid "devcp_edit_authors_add_email"
+msgstr "Author Account Email:"
+
+#: views/developers/addon_edit_authors.thtml:98
+#, fuzzy
+msgid "devcp_edit_authors_add_loading"
+msgstr "Checking account email..."
+
+#: views/developers/addon_edit_authors.thtml:70
+#, fuzzy
+msgid "devcp_edit_authors_click_save"
+msgstr "Click the Update Authors button below to save."
+
+#: views/developers/addon_edit_authors.thtml:58
+#, fuzzy
+msgid "devcp_edit_authors_header_current"
+msgstr "Current Authors"
+
+#: views/developers/addon_edit_authors.thtml:50
+#, fuzzy
+msgid "devcp_edit_authors_header_manage"
+msgstr "Manage Add-on Authors"
+
+#: views/developers/addon_edit_authors.thtml:93
+#, fuzzy
+msgid "devcp_edit_authors_label_add_listed"
+msgstr "List as author in pubilc display pages"
+
+#: views/developers/addon_edit_authors.thtml:89
+#, fuzzy
+msgid "devcp_edit_authors_label_developer"
+msgstr ""
+"<strong>Developer</strong> - Can manage all aspects of the add-on listing, "
+"except for adding and removing other authors."
+
+#: views/developers/addon_edit_authors.thtml:88
+#, fuzzy
+msgid "devcp_edit_authors_label_owner"
+msgstr ""
+"<strong>Owner</strong> - Can manage all aspects of the add-on listing, "
+"including adding and removing other authors."
+
+#: views/developers/addon_edit_authors.thtml:90
+#, fuzzy
+msgid "devcp_edit_authors_label_viewer"
+msgstr ""
+"<strong>Viewer</strong> - Can view add-on developer listing and statistics, "
+"but can't make any changes."
+
+#. Placeholder for the empty option in a <select>.
+#: views/developers/addon_edit_categories.thtml:69
+#, fuzzy
+msgid "devcp_edit_authors_option_empty"
+msgstr "----------------"
+
+#: views/developers/addon_edit_authors.thtml:86
+#, fuzzy
+msgid "devcp_edit_authors_select_role"
+msgstr "Select a role for the author:"
+
+#. Column name in a table.
+#: views/developers/addon_edit_authors.thtml:62
+#, fuzzy
+msgid "devcp_edit_authors_th_author"
+msgstr "Author"
+
+#. Column name in a table.
+#: views/developers/addon_edit_authors.thtml:64
+#, fuzzy
+msgid "devcp_edit_authors_th_listed"
+msgstr "Listed"
+
+#. Column name in a table.
+#: views/developers/addon_edit_authors.thtml:63
+#, fuzzy
+msgid "devcp_edit_authors_th_role"
+msgstr "Role"
+
+#: views/developers/addon_edit_authors.thtml:77
+#, fuzzy
+msgid "devcp_edit_authors_update_author"
+msgstr "Update authors"
+
+#: views/developers/addon_edit_categories.thtml:99
+#, fuzzy
+msgid "devcp_edit_categories_button_update"
+msgstr "Update Categories"
+
+#: views/developers/addon_edit_categories.thtml:88
+#, fuzzy
+msgid "devcp_edit_categories_does_not_fit"
+msgstr "My add-on doesn't fit into any available categories."
+
+#. %s is the application name (Firefox, Thunderbird).
+#: views/developers/addon_edit_categories.thtml:61
+#, fuzzy
+msgid "devcp_edit_categories_header_application"
+msgstr "%s Categories"
+
+#: views/developers/addon_edit_categories.thtml:49
+#, fuzzy
+msgid "devcp_edit_categories_header_manage"
+msgstr "Manage Add-on Categories"
+
+#: views/developers/addon_edit_categories.thtml:91
+#, fuzzy
+msgid "devcp_edit_categories_hover"
+msgstr "Hover over a category to see its description."
+
+#. %s is the category number (1, 2, 3).
+#: views/developers/addon_edit_categories.thtml:67
+#, fuzzy
+msgid "devcp_edit_categories_label_category_num"
+msgstr "Category %s"
+
+#: views/developers/addon_edit_categories.thtml:94
+#: views/developers/addon_edit_categories.thtml:103
+#, fuzzy
+msgid "devcp_edit_categories_none_available"
+msgstr "No categories are available for this add-on type and application."
+
+#: views/developers/addon_edit_categories.thtml:86
+#, fuzzy
+msgid "devcp_edit_categories_other"
+msgstr ""
+"Place your add-on into this category only if it does not fit into any other "
+"available categories."
+
+#. %s is the application name (Firefox, Thunderbird).
+#: views/developers/addon_edit_categories.thtml:63
+#, fuzzy
+msgid "devcp_edit_categories_select_application_categories"
+msgstr "Select up to three %s categories for your add-on"
+
+#: views/developers/addon_edit.thtml:47
+#, fuzzy
+msgid "devcp_edit_dd_manage_authors"
+msgstr "Add or remove users that can manage this add-on."
+
+#: views/developers/addon_edit.thtml:49
+#, fuzzy
+msgid "devcp_edit_dd_manage_categories"
+msgstr ""
+"Select the relevant categories for each application your add-on supports."
+
+#: views/developers/addon_edit.thtml:51
+#, fuzzy
+msgid "devcp_edit_dd_manage_description"
+msgstr ""
+"Add and modify translations for your add-on's summary, description, end-user "
+"license, and privacy policy."
+
+#: views/developers/addon_edit.thtml:53
+#, fuzzy
+msgid "devcp_edit_dd_manage_properties"
+msgstr "Change your add-on's name, homepage, icon, and other flags."
+
+#: views/developers/addon_edit_descriptions.thtml:116
+#, fuzzy
+msgid "devcp_edit_description_button_update"
+msgstr "Update Descriptions"
+
+#: views/developers/addon_edit_descriptions.thtml:115
+#, fuzzy
+msgid "devcp_edit_description_correct_error"
+msgstr "Please correct the errors above indicated in red."
+
+#: views/developers/addon_edit_descriptions.thtml:51
+#, fuzzy
+msgid "devcp_edit_descriptions_header"
+msgstr "Edit Add-on Descriptions"
+
+#: views/developers/addon_edit_descriptions.thtml:94
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_comments_description"
+msgstr ""
+"Any information end users may want to know that isn't necessarily applicable "
+"to the add-on summary or description. Common uses include listing known "
+"major bugs, information on how to report bugs, anticipated release date of a "
+"new version, etc."
+
+#: views/developers/addon_edit_descriptions.thtml:93
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_comments_name"
+msgstr "Developer Comments"
+
+#: views/developers/addon_edit_descriptions.thtml:86
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_description_description"
+msgstr ""
+"The description of your add-on is a longer explanation of features, "
+"functionality, and other relevant information. It is displayed under the "
+"summary on the add-on's display page."
+
+#: views/developers/addon_edit_descriptions.thtml:85
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_description_name"
+msgstr "Add-on Description"
+
+#: views/developers/addon_edit_descriptions.thtml:103
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_eula_description"
+msgstr ""
+"If your add-on has an End-User License Agreement (EULA), please enter its "
+"text below. If set below, users will be required to agree to this before "
+"installing your add-on. Please note that a EULA is not the same as a code "
+"license such as GPL or MPL."
+
+#: views/developers/addon_edit_descriptions.thtml:102
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_eula_name"
+msgstr "End-User License Agreement"
+
+#: views/developers/addon_edit_descriptions.thtml:112
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_privacy_description"
+msgstr ""
+"If your add-on has a privacy policy, enter its text here. Your add-on's "
+"display page will display a link to the policy."
+
+#: views/developers/addon_edit_descriptions.thtml:111
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_privacy_name"
+msgstr "Privacy Policy"
+
+#: views/developers/addon_edit_descriptions.thtml:78
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_summary_description"
+msgstr ""
+"The summary is a short explanation of your add-on's basic functionality that "
+"is displayed in search and browse listings, as well as at the top of your "
+"add-on's display page. <strong>Limit of 250 characters.</strong>"
+
+#: views/developers/addon_edit_descriptions.thtml:77
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_summary_name"
+msgstr "Add-on Summary"
+
+#: views/developers/addon_edit.thtml:46
+#, fuzzy
+msgid "devcp_edit_dt_manage_authors"
+msgstr "Manage Add-on Authors"
+
+#: views/developers/addon_edit.thtml:48
+#, fuzzy
+msgid "devcp_edit_dt_manage_categories"
+msgstr "Manage Add-on Categories"
+
+#: views/developers/addon_edit.thtml:50
+#, fuzzy
+msgid "devcp_edit_dt_manage_descriptions"
+msgstr "Manage Add-on Descriptions"
+
+#: views/developers/addon_edit.thtml:52
+#, fuzzy
+msgid "devcp_edit_dt_manage_properties"
+msgstr "Manage Add-on Properties"
+
+#: views/developers/addon_edit_properties.thtml:170
+msgid "devcp_edit_label_externalsoftware"
+msgstr "هذه الإضاÙØ© تتطلب برنامجًا خارجيًا"
+
+#: views/developers/addon_edit_properties.thtml:205
+msgid "devcp_edit_label_locale_disambiguation"
+msgstr "معلومات إضاÙية عن اللغة"
+
+#: views/developers/addon_edit_properties.thtml:168
+msgid "devcp_edit_label_prerelease"
+msgstr "هذه ما-قبل-الإصدارة"
+
+#: views/developers/addon_edit_properties.thtml:169
+msgid "devcp_edit_label_sitespecific"
+msgstr "هذه إضاÙØ© خاصة بمواقع معينة"
+
+#: views/developers/addon_edit_properties.thtml:202
+msgid "devcp_edit_label_target_locale"
+msgstr "اللغة الهدÙ"
+
+#: views/developers/addon_edit_properties.thtml:212
+#, fuzzy
+msgid "devcp_edit_properties_button_update"
+msgstr "Update Properties"
+
+#: views/developers/addon_edit_properties.thtml:198
+#, fuzzy
+msgid "devcp_edit_properties_change_guid"
+msgstr "Only change if you understand all of the consequences."
+
+#: views/developers/addon_edit_properties.thtml:109
+#, fuzzy
+msgid "devcp_edit_properties_current_icon"
+msgstr "Current Icon"
+
+#: views/developers/addon_edit_properties.thtml:85
+#, fuzzy
+msgid "devcp_edit_properties_default_locale"
+msgstr ""
+"An add-on's default locale is the main locale in which translations must be "
+"present. If translations for your add-on's descriptions are unavailable in a "
+"user's selected language, they will fall back to this default locale."
+
+#: views/developers/addon_edit_properties.thtml:167
+#, fuzzy
+msgid "devcp_edit_properties_flags"
+msgstr "These flags are used to filter and classify add-ons."
+
+#: views/developers/addon_edit_properties.thtml:174
+#, fuzzy
+msgid "devcp_edit_properties_guid"
+msgstr ""
+"The GUID of your add-on is specified in its install.rdf and uniquely "
+"identifies it. You cannot change your GUID once it is listed on Mozilla Add-"
+"ons."
+
+#: views/developers/addon_edit_properties.thtml:53
+#, fuzzy
+msgid "devcp_edit_properties_header"
+msgstr "Edit Add-on Properties"
+
+#: views/developers/addon_edit_properties.thtml:186
+#, fuzzy
+msgid "devcp_edit_properties_header_addon_type"
+msgstr "Add-on Type"
+
+#: views/developers/addon_edit_properties.thtml:181
+#, fuzzy
+msgid "devcp_edit_properties_header_admin_settings"
+msgstr "Admin Settings"
+
+#: views/developers/addon_edit_properties.thtml:84
+#, fuzzy
+msgid "devcp_edit_properties_header_default_locale"
+msgstr "Default Locale"
+
+#: views/developers/addon_edit_properties.thtml:166
+#, fuzzy
+msgid "devcp_edit_properties_header_flags"
+msgstr "Add-on Flags"
+
+#: views/developers/addon_edit_properties.thtml:173
+#: views/developers/addon_edit_properties.thtml:197
+#, fuzzy
+msgid "devcp_edit_properties_header_guid"
+msgstr "Add-on GUID"
+
+#: views/developers/addon_edit_properties.thtml:104
+#, fuzzy
+msgid "devcp_edit_properties_header_icon"
+msgstr "Add-on Icon"
+
+#: views/developers/addon_edit_properties.thtml:159
+#, fuzzy
+msgid "devcp_edit_properties_header_other_settings"
+msgstr "Other Settings"
+
+#. A header on the admin page to toggle trusted status.
+#: views/developers/addon_edit_properties.thtml:182
+#, fuzzy
+msgid "devcp_edit_properties_header_trusted"
+msgstr "Trusted Add-on?"
+
+#: views/developers/addon_edit_properties.thtml:160
+#, fuzzy
+msgid "devcp_edit_properties_header_view_source"
+msgstr "View Source Online"
+
+#. %s is a comma-separated list of image extensions ".png, .jpg"
+#: views/developers/addon_edit_properties.thtml:106
+#, fuzzy
+msgid "devcp_edit_properties_icon"
+msgstr ""
+"The add-on icon is a small image that is displayed next to your add-on's "
+"name in browse and search results, display pages, and in the add-on "
+"installation dialog. The image will automatically be resized to 32 x 32 "
+"pixels. Please use one of the following image types: %s"
+
+#: views/developers/addon_edit_properties.thtml:171
+#, fuzzy
+msgid "devcp_edit_properties_label_binary"
+msgstr "This add-on contains binary components"
+
+#: views/developers/addon_edit_properties.thtml:185
+#, fuzzy
+msgid "devcp_edit_properties_label_not_trusted"
+msgstr "Not Trusted"
+
+#: views/developers/addon_edit_properties.thtml:184
+#, fuzzy
+msgid "devcp_edit_properties_label_trusted"
+msgstr "Trusted"
+
+#: views/developers/addon_edit_properties.thtml:110
+#, fuzzy
+msgid "devcp_edit_properties_new_icon"
+msgstr "New Icon"
+
+#: views/developers/addon_edit_properties.thtml:118
+#, fuzzy
+msgid "devcp_edit_properties_remove_icon"
+msgstr "Remove Icon"
+
+#: views/developers/addon_edit_properties.thtml:136
+#, fuzzy
+msgid "devcp_edit_properties_transbox_homepage_description"
+msgstr ""
+"If your add-on has another homepage, enter its address here. Adding other "
+"translations is not necessary unless your website is localized into other "
+"languages."
+
+#: views/developers/addon_edit_properties.thtml:135
+#, fuzzy
+msgid "devcp_edit_properties_transbox_homepage_name"
+msgstr "Add-on Homepage"
+
+#: views/developers/addon_edit_properties.thtml:79
+#, fuzzy
+msgid "devcp_edit_properties_transbox_name_description"
+msgstr "The name of your add-on is displayed everywhere your add-on is listed."
+
+#: views/developers/addon_edit_properties.thtml:78
+#, fuzzy
+msgid "devcp_edit_properties_transbox_name_name"
+msgstr "Add-on Name"
+
+#: views/developers/addon_edit_properties.thtml:145
+#, fuzzy
+msgid "devcp_edit_properties_transbox_supportemail_description"
+msgstr ""
+"If you have an email address for support inquiries, enter it here. Adding "
+"other translations is not necessary unless you have different email "
+"addresses for different languages."
+
+#: views/developers/addon_edit_properties.thtml:144
+#, fuzzy
+msgid "devcp_edit_properties_transbox_supportemail_name"
+msgstr "Support Email Address"
+
+#: views/developers/addon_edit_properties.thtml:154
+#, fuzzy
+msgid "devcp_edit_properties_transbox_supporturl_description"
+msgstr ""
+"If your add-on has a support website or forum, enter its address here. "
+"Adding other translations is not necessary unless your website is localized "
+"into other languages."
+
+#: views/developers/addon_edit_properties.thtml:153
+#, fuzzy
+msgid "devcp_edit_properties_transbox_supporturl_name"
+msgstr "Support Website"
+
+#: views/developers/addon_edit_properties.thtml:183
+#, fuzzy
+msgid "devcp_edit_properties_trusted"
+msgstr "Trusted add-ons can become public without Editor review."
+
+#. %s is href="..." and should stay in the <a> tag.
+#: views/developers/addon_edit_properties.thtml:119
+#, fuzzy
+msgid "devcp_edit_properties_undelete"
+msgstr "Icon will be deleted on save. <a %s>Cancel?</a>"
+
+#: views/developers/addon_edit_properties.thtml:161
+#, fuzzy
+msgid "devcp_edit_properties_view_source"
+msgstr ""
+"The source of your add-on files can be viewed online by any logged in user "
+"if you wish."
+
+#: views/developers/addon_edit_properties.thtml:162
+#, fuzzy
+msgid "devcp_edit_properties_view_source_allow"
+msgstr "Allow online source viewing"
+
+#: views/developers/addon_edit_properties.thtml:163
+#, fuzzy
+msgid "devcp_edit_properties_view_source_do_not_allow"
+msgstr "Do not allow online source viewing"
+
+#: views/elements/developers/editbox.thtml:46
+#, fuzzy
+msgid "devcp_editbox_authors"
+msgstr "Authors"
+
+#: views/elements/developers/editbox.thtml:47
+#, fuzzy
+msgid "devcp_editbox_categories"
+msgstr "Categories"
+
+#: views/elements/developers/editbox.thtml:52
+#, fuzzy
+msgid "devcp_editbox_change_status"
+msgstr "Change Status"
+
+#: views/elements/developers/editbox.thtml:48
+#, fuzzy
+msgid "devcp_editbox_descriptions"
+msgstr "Descriptions"
+
+#: views/elements/developers/editbox.thtml:43
+#, fuzzy
+msgid "devcp_editbox_edit_addon"
+msgstr "Edit Add-on"
+
+#: views/elements/developers/editbox.thtml:57
+#, fuzzy
+msgid "devcp_editbox_new_version"
+msgstr "New Version"
+
+#: views/elements/developers/editbox.thtml:49
+#, fuzzy
+msgid "devcp_editbox_properties"
+msgstr "Properties"
+
+#: views/elements/developers/editbox.thtml:60
+#, fuzzy
+msgid "devcp_editbox_screenshots"
+msgstr "Preview Screenshots"
+
+#: views/elements/developers/editbox.thtml:53
+#, fuzzy
+msgid "devcp_editbox_statistics_dashboard"
+msgstr "Statistics Dashboard"
+
+#: views/elements/developers/editbox.thtml:54
+#, fuzzy
+msgid "devcp_editbox_versions"
+msgstr "Versions and Files"
+
+#: views/elements/developers/editbox.thtml:42
+#, fuzzy
+msgid "devcp_editbox_view_listing"
+msgstr "View Listing"
+
+#: views/elements/developers/editorsmenu.thtml:59
+msgid "devcp_editorsqueue_featured"
+msgstr "الإضاÙات المميزة"
+
+#. %1 is the review count
+#: views/elements/developers/editorsqueue.thtml:42
+#: views/elements/developers/editorsmenu.thtml:56
+#, php-format
+msgid "devcp_editorsqueue_moderatedreviews"
+msgid_plural "devcp_editorsqueue_moderatedreviews"
+msgstr[0] "لا مراجعات تحت الإشراÙ"
+msgstr[1] "مراجعة واحدة تحت الإشراÙ"
+msgstr[2] "مراجعتان تحت الإشراÙ"
+msgstr[3] "%s مراجعات تحت الإشراÙ"
+msgstr[4] "%s مراجعة تحت الإشراÙ"
+msgstr[5] "%s مراجعة تحت الإشراÙ"
+
+#. %1 is the nominated addons count
+#: views/elements/developers/editorsqueue.thtml:44
+#: views/elements/developers/editorsmenu.thtml:58
+#, php-format
+msgid "devcp_editorsqueue_nominated"
+msgid_plural "devcp_editorsqueue_nominated"
+msgstr[0] "لا إضاÙات مرشحة"
+msgstr[1] "إضاÙØ© واحدة مرشحة"
+msgstr[2] "إضاÙتان مرشحتان"
+msgstr[3] "%s إضاÙات مرشحة"
+msgstr[4] "%s إضاÙØ© مرشحة"
+msgstr[5] "%s إضاÙØ© مرشحة"
+
+#. %1 is the update count
+#: views/elements/developers/editorsqueue.thtml:43
+#: views/elements/developers/editorsmenu.thtml:57
+#, php-format
+msgid "devcp_editorsqueue_pendingupdates"
+msgid_plural "devcp_editorsqueue_pendingupdates"
+msgstr[0] "لا تحديثات تنتظر"
+msgstr[1] "تحديث واحد ينتظر"
+msgstr[2] "تحديثان ينتظران"
+msgstr[3] "%s تحديثات تنتظر"
+msgstr[4] "%s تحديثًا ينتظر"
+msgstr[5] "%s تحديث ينتظر"
+
+#: controllers/statistics_controller.php:147
+#: controllers/statistics_controller.php:361
+#: controllers/previews_controller.php:108
+#: controllers/previews_controller.php:211
+#: controllers/previews_controller.php:312
+msgid "devcp_error_addon_access_denied"
+msgstr "أنت لا تملك إذن الوصول إلى هذه الإضاÙØ©."
+
+#. %s is a complete URL with the text from devcp_error_appversion_reference_link_text
+#. in the <a> tag. This should be fixed.
+#: controllers/components/developers.php:591
+#, php-format
+msgid "devcp_error_appversion_reference_link"
+msgstr "رجاءً انظر إلى %s كمرجع."
+
+#. This is the link text in the <a> for devcp_error_appversion_reference_link. This
+#. should be fixed.
+#: controllers/components/developers.php:591
+msgid "devcp_error_appversion_reference_link_text"
+msgstr "هذه الصÙحة"
+
+#: views/developers/addon_edit_authors.thtml:76
+#, fuzzy
+msgid "devcp_error_empty_authors"
+msgstr "Your add-on must have at least one owner."
+
+#. %1$s is the name of the file
+#: controllers/components/developers.php:658
+#, fuzzy
+msgid "devcp_error_file_exists"
+msgstr ""
+"هناك إصدارة موجودة مسبقًا من هذه الإضاÙØ©. لاستبدالها، عليك حذ٠المل٠%1$s "
+"أولاً."
+
+#. %1$s is a file extension. Example: .exe
+#. %2$s is a comma separated list of extensions. Example: .xpi, .jar
+#: controllers/components/developers.php:355
+#, php-format
+msgid "devcp_error_file_extension"
+msgstr ""
+"امتداد المل٠(%s) غير مسموح لنوع الإضاÙات المحدّد. رجاءً اختر واحدًا من الأنواع "
+"التالية: %s"
+
+#: controllers/components/developers.php:64
+msgid "devcp_error_five_categories"
+msgstr "لا تختر رجاءً أكثر من خمسة تصنيÙات."
+
+#: controllers/components/developers.php:526
+msgid "devcp_error_guid_application"
+msgstr "معرّ٠هذه الإضاÙØ© يستخدمه أحد التطبيقات."
+
+#: controllers/components/developers.php:337
+#: controllers/components/developers.php:389
+msgid "devcp_error_http_incomplete"
+msgstr "نقل غير مكتمل"
+
+#: controllers/components/developers.php:335
+#: controllers/components/developers.php:336
+#: controllers/components/developers.php:387
+#: controllers/components/developers.php:388
+msgid "devcp_error_http_maxupload"
+msgstr "تجاوز الحد الأقصى لحجم الرÙع"
+
+#: controllers/components/developers.php:338
+#: controllers/components/developers.php:390
+msgid "devcp_error_http_nofile"
+msgstr "لم ÙŠÙرÙع أي ملÙ"
+
+#. %1$s is a file extension. Example: .exe
+#. %2$s is a comma separated list of extensions. Example: .xpi, .jar
+#: controllers/components/developers.php:401
+#, php-format
+msgid "devcp_error_icon_extension"
+msgstr "امتداد المل٠(%s) غير مسموح للأيقونات. اختر رجاءً أحد هذه الأنواع: %s"
+
+#: controllers/developers_controller.php:504
+msgid "devcp_error_index_rdf_notfound"
+msgstr "مل٠install.rdf Ù…Ùقود."
+
+#: controllers/components/developers.php:601
+msgid "devcp_error_install_manifest"
+msgstr "ÙˆÙجدت الأخطاء التالية ÙÙŠ مل٠install.rdf:"
+
+#: controllers/developers_controller.php:1463
+msgid "devcp_error_invalid_addontype"
+msgstr "اختر رجاءً نوع إضاÙØ© صالح."
+
+#. %$1s is a version. Example: 3.1.1
+#. %$2s is an add-on name.
+#: controllers/components/developers.php:569
+#: controllers/components/developers.php:581
+#, php-format
+msgid "devcp_error_invalid_appversion"
+msgstr "%s ليست إصدارة صالحة ل†%s"
+
+#. %s is a string
+#: controllers/components/developers.php:521
+#, php-format
+msgid "devcp_error_invalid_guid"
+msgstr "معرّ٠هذه الإضاÙØ© غير صالح: %s"
+
+#. %$1s is a version. Example: 3.1.1
+#. %$2s is an add-on name.
+#: controllers/components/developers.php:572
+#, php-format
+msgid "devcp_error_invalid_minversion"
+msgstr "%s ليست إصدارة صالحة ل†%s: الإصدارات الدنيا لا يمكن أن تحتوي *"
+
+#: controllers/components/developers.php:536
+msgid "devcp_error_invalid_version"
+msgstr ""
+"إصدارة هذه الإضاÙØ© غير صالحة: انظر رجاءً إلى <a href=\"http://developer."
+"mozilla.org/en/docs/Toolkit_version_format\">المواصÙات</a>"
+
+#: controllers/components/developers.php:531
+msgid "devcp_error_invalid_version_spaces"
+msgstr "إصدارة هذه الإضاÙØ© غير صالحة: الإصدارات لا يمكن أن تحوي على Ùراغات."
+
+#. %s is an error message from the parser.
+#: controllers/components/developers.php:501
+#, php-format
+msgid "devcp_error_manifest_parse"
+msgstr "حصل الخطأ التالي أثناء تحليل install.rdf: %s"
+
+#: controllers/components/developers.php:373
+msgid "devcp_error_move_file"
+msgstr "تعذر نقل الملÙ"
+
+#. %s is the name of a file
+#: controllers/components/developers.php:650
+#: controllers/components/developers.php:662
+#: controllers/components/developers.php:667
+#: controllers/components/developers.php:727
+#: controllers/components/developers.php:738
+#: controllers/components/developers.php:743
+#, php-format
+msgid "devcp_error_moving_file"
+msgstr "حصل خطأ أثناء نقل %s."
+
+#: controllers/components/developers.php:595
+msgid "devcp_error_mozilla_application"
+msgstr "يجب أن يكون لديك تطبيق هد٠لموزيلا صالح، واحد على الأقل."
+
+#: controllers/components/developers.php:516
+msgid "devcp_error_no_guid"
+msgstr "تعذر إيجاد معرّ٠لهذه الإضاÙØ© ÙÙŠ install.rdf."
+
+#: controllers/components/developers.php:287
+msgid "devcp_error_no_platform"
+msgstr "لم تحدّد منصة التشغيل"
+
+#: controllers/components/developers.php:59
+msgid "devcp_error_one_category"
+msgstr "اختر رجاءً تصنيÙًا واحدًا على الأقل."
+
+#: controllers/components/developers.php:92
+msgid "devcp_error_one_user"
+msgstr "يجب أن يكون لهذه الإضاÙØ© مؤل٠واحد على الأقل."
+
+#. %1$s is a file extension. Example: .exe
+#. %2$s is a comma separated list of extensions. Example: .xpi, .jar
+#: controllers/components/developers.php:1081
+#, php-format
+msgid "devcp_error_preview_extension"
+msgstr ""
+"امتداد المل٠(%s) غير مسموح ÙÙŠ المعاينات. اختر رجاءً أحد هذه الأنواع: %s"
+
+#: controllers/components/developers.php:511
+msgid "devcp_error_updatekey"
+msgstr ""
+"الإضاÙات لا يمكنها استخدام updateKey. رجاءً أزÙÙ„ ذلك من install.rdf وحاول "
+"مجددًا."
+
+#: controllers/components/developers.php:506
+msgid "devcp_error_updateurl"
+msgstr ""
+"الإضاÙات لا يمكنها استخدام updateURL خارجي. رجاءً أزÙÙ„ ذلك من install.rdf "
+"وحاول مجددًا."
+
+#: controllers/developers_controller.php:465
+#: controllers/components/developers.php:271
+msgid "devcp_error_upload_file"
+msgstr "رجاءً ارÙع ملÙًا."
+
+#: views/developers/uploader.thtml:135
+#, fuzzy
+msgid "devcp_input_upload_file"
+msgstr "Upload File"
+
+#: views/pages/js_constants.js.thtml:89
+#, fuzzy
+msgid "devcp_js_a_cancel"
+msgstr "Cancel"
+
+#: views/pages/js_constants.js.thtml:90
+#, fuzzy
+msgid "devcp_js_add_email"
+msgstr "Please enter the account email of the author you wish to add."
+
+#. alt text for a down-arrow image.
+#: views/pages/js_constants.js.thtml:81
+#, fuzzy
+msgid "devcp_js_img_move_down"
+msgstr "Move Down"
+
+#. alt text for an up-arrow image.
+#: views/pages/js_constants.js.thtml:82
+#, fuzzy
+msgid "devcp_js_img_move_up"
+msgstr "Move Up"
+
+#: views/pages/js_constants.js.thtml:91
+#, fuzzy
+msgid "devcp_js_img_remove_compat"
+msgstr "Remove Application Compatibility"
+
+#: views/pages/js_constants.js.thtml:86
+#, fuzzy
+msgid "devcp_js_input_list_author"
+msgstr "List as author in public listings"
+
+#: views/pages/js_constants.js.thtml:92
+#, fuzzy
+msgid "devcp_js_license_select"
+msgstr "Please select a license."
+
+#: views/pages/js_constants.js.thtml:93
+#, fuzzy
+msgid "devcp_js_license_text"
+msgstr "Please enter text for your license."
+
+#. <option> text in a <select> for Author role in an add-on.
+#: views/pages/js_constants.js.thtml:84
+#, fuzzy
+msgid "devcp_js_option_developer"
+msgstr "Developer"
+
+#. <option> text in a <select> for Author role in an add-on.
+#: views/pages/js_constants.js.thtml:83
+#, fuzzy
+msgid "devcp_js_option_owner"
+msgstr "Owner"
+
+#. <option> text in a <select> for Author role in an add-on.
+#: views/pages/js_constants.js.thtml:85
+#, fuzzy
+msgid "devcp_js_option_viewer"
+msgstr "Viewer"
+
+#: views/pages/js_constants.js.thtml:88
+#, fuzzy
+msgid "devcp_js_remove_author"
+msgstr "Remove Author"
+
+#: views/pages/js_constants.js.thtml:87
+#, fuzzy
+msgid "devcp_js_sure_remove"
+msgstr "Are you <strong>sure</strong> you wish to remove this author?"
+
+#: views/pages/js_constants.js.thtml:77
+#, fuzzy
+msgid "devcp_js_upload_alert"
+msgstr "You must select a file to upload."
+
+#. %1$s is an addon id, like 32.
+#. %2$s is a version number, like 3.5.
+#: controllers/components/developers.php:1212
+#, fuzzy
+msgid "devcp_license_existing"
+msgstr "Custom license for add-on %1$s v%2$s"
+
+#: views/elements/developers/localebox.thtml:44
+msgid "devcp_localebox_header_localizedfields"
+msgstr "الحقول المترجمة"
+
+#. %1 is the default locale
+#: views/elements/developers/localebox.thtml:48
+#, php-format
+msgid "devcp_localebox_intro"
+msgstr ""
+"بعض الحقول ÙÙŠ هذه الصÙحة تÙرجمت لتظهر بلغة المستخدم الأصلية. اختر لغة من "
+"الأسÙÙ„ لتحرير تÙاصيل الإضاÙØ© بهذه اللغة. إن لم تكن الترجمة إلى إحدى اللغات "
+"متاحة، سيظهر النص باللغة المبدئية (%s)."
+
+#: views/elements/developers/sidebar.thtml:68
+#: views/elements/developers/myaddons.thtml:75
+msgid "devcp_myaddons_admincp_link"
+msgstr "أدوات المدير"
+
+#: views/elements/developers/sidebar.thtml:65
+#: views/elements/developers/myaddons.thtml:72
+msgid "devcp_myaddons_editorcp_link"
+msgstr "أدوات المحرّر"
+
+#: views/elements/developers/myaddons.thtml:52
+msgid "devcp_myaddons_link"
+msgstr "إضاÙاتي"
+
+#: views/elements/developers/sidebar.thtml:70
+#: views/elements/developers/myaddons.thtml:77
+msgid "devcp_myaddons_mainpage_link"
+msgstr "عودة إلى الرئيسية"
+
+#: views/elements/developers/sidebar.thtml:63
+#: views/elements/developers/myaddons.thtml:70
+msgid "devcp_myaddons_statistics_link"
+msgstr "لوحة الإحصائيات"
+
+#: views/elements/developers/sidebar.thtml:62
+#: views/elements/developers/myaddons.thtml:69
+msgid "devcp_myaddons_submitaddon_link"
+msgstr "أرسÙÙ„ الإضاÙØ©"
+
+#: views/elements/developers/sidebar.thtml:48
+#: views/elements/developers/myaddons.thtml:67
+msgid "devcp_myaddons_title"
+msgstr "أدوات المطوّر"
+
+#. %1$s is an add-on ID, perhaps 167.
+#. %2$s is a URL.
+#: controllers/developers_controller.php:256
+#, fuzzy
+msgid "devcp_new_addon_error"
+msgstr ""
+"This add-on ID (%1$s) already exists in the database. If this is your add-"
+"on, you can <a href=\"%2$s\">upload a new version</a>."
+
+#: views/developers/addon_status_nominate.thtml:62
+#, fuzzy
+msgid "devcp_nominate_cancel"
+msgstr "Cancel and return"
+
+#. %1 is the add-on name
+#: views/developers/addon_status_nominate.thtml:61
+#, php-format
+msgid "devcp_nominate_submit_nominate"
+msgstr "رشّح %s"
+
+#: views/developers/addon_edit_properties.thtml:50
+#: views/developers/addon_status.thtml:49
+#: views/developers/versions_edit.thtml:50
+#, fuzzy
+msgid "devcp_notice_changes_error"
+msgstr ""
+"<span>One or more of your changes couldn't be saved.</span><br />Please look "
+"for the errors below. The rest of your changes were successfully saved."
+
+#: views/developers/addon_edit_authors.thtml:47
+#: views/developers/addon_edit_properties.thtml:47
+#: views/developers/addon_status.thtml:46
+#: views/developers/addon_edit_descriptions.thtml:47
+#: views/developers/versions_edit.thtml:47
+#: views/developers/addon_edit_categories.thtml:46
+#, fuzzy
+msgid "devcp_notice_changes_saved"
+msgstr ""
+"<span>Your changes have been saved.</span><br />Please note that some "
+"changes may take several hours to appear in all areas of the website."
+
+#: controllers/previews_controller.php:252
+msgid "devcp_notice_cleardefault"
+msgstr ""
+"إزالة هذه المعاينة المبدئية سيؤدي آليًا إلى أن تصبح معاينة أخرى هي المعاينة "
+"المبدئية."
+
+#: controllers/previews_controller.php:184
+#: controllers/previews_controller.php:251
+msgid "devcp_notice_makedefault"
+msgstr ""
+"سيؤدي تعيين هذه المعاينة كمعاينة مبدئية إلى إزالة حالة المبدئية عن المعاينة "
+"المبدئية الحالية."
+
+#: views/developers/addon_edit_authors.thtml:70
+#, fuzzy
+msgid "devcp_notice_unsaved_changes"
+msgstr "You have unsaved changes."
+
+#: controllers/developers_controller.php:87
+#: controllers/developers_controller.php:97
+#: controllers/developers_controller.php:100
+#: controllers/previews_controller.php:67
+#: controllers/previews_controller.php:79
+#: controllers/previews_controller.php:82
+msgid "devcp_pagetitle"
+msgstr "أدوات المطوّر"
+
+#: controllers/previews_controller.php:103
+#: controllers/previews_controller.php:104
+msgid "devcp_preview_add_pagetitle"
+msgstr "إضاÙØ© معاينة"
+
+#: controllers/previews_controller.php:135
+msgid "devcp_preview_added_successfully"
+msgstr "أضيÙت المعاينة بنجاح."
+
+#: controllers/previews_controller.php:323
+msgid "devcp_preview_deleted_successfully"
+msgstr "Ø­ÙØ°Ùت المعاينة بنجاح."
+
+#: controllers/previews_controller.php:194
+#: controllers/previews_controller.php:195
+msgid "devcp_preview_edit_pagetitle"
+msgstr "تحرير المعاينة"
+
+#: controllers/previews_controller.php:237
+msgid "devcp_preview_updated_successfully"
+msgstr "Ø­Ùدّثت المعاينة بنجاح."
+
+#: views/developers/previews.thtml:120
+#, fuzzy
+msgid "devcp_previews_a_another"
+msgstr "Add Another Preview"
+
+#: views/developers/previews.thtml:96
+#, fuzzy
+msgid "devcp_previews_a_delete"
+msgstr "Delete Preview"
+
+#: views/developers/previews.thtml:95
+#, fuzzy
+msgid "devcp_previews_a_replace"
+msgstr "Replace Preview"
+
+#: views/developers/previews.thtml:126
+#, fuzzy
+msgid "devcp_previews_a_update"
+msgstr "Update Previews"
+
+#: views/developers/previews.thtml:115 views/developers/previews.thtml:124
+#, fuzzy
+msgid "devcp_previews_add_new"
+msgstr "Add New Preview"
+
+#. %s is a list of file extensions, e.g. ".png, .gif"
+#: views/developers/previews.thtml:116
+#, fuzzy
+msgid "devcp_previews_add_select"
+msgstr ""
+"Select an image to upload below. Images larger than the maximum size of 700 "
+"pixels wide by 525 pixels tall will be resized. Allowed file types: %s"
+
+#: views/developers/previews.thtml:121
+#, fuzzy
+msgid "devcp_previews_click_below"
+msgstr "Click Update Previews below to upload."
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/previews.thtml:102
+#, fuzzy
+msgid "devcp_previews_click_update"
+msgstr ""
+"Click the Update Previews button below to save this image. (<a %s>Cancel?</"
+"a>)"
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/previews.thtml:107
+#, fuzzy
+msgid "devcp_previews_error_message"
+msgstr ""
+"This preview will be deleted when Update Previews is clicked below. (<a %"
+"s>Cancel?</a>)"
+
+#: views/previews/add.thtml:45
+msgid "devcp_previews_filetype_info"
+msgstr ""
+"استخدم النموذج أدناه لرÙع لقطات صور لإضاÙتك من نوع PNG أو JPG أو GIF. الصور "
+"التي يزيد عرضها عن 700 بكسل وطولها عن 525 بكسلًا سو٠يÙعاد تحجيمها تلقائيًا."
+
+#: views/previews/add.thtml:43
+msgid "devcp_previews_header_add"
+msgstr "أضÙ٠معاينة"
+
+#: views/developers/previews.thtml:80
+#, fuzzy
+msgid "devcp_previews_header_caption"
+msgstr "Preview Caption"
+
+#: views/previews/edit.thtml:43
+msgid "devcp_previews_header_edit"
+msgstr "حرّر المعاينة"
+
+#: views/developers/previews.thtml:93
+#, fuzzy
+msgid "devcp_previews_label_default"
+msgstr "Default Preview"
+
+#: views/previews/add.thtml:54
+msgid "devcp_previews_label_file"
+msgstr "مل٠المعاينة"
+
+#: views/previews/add.thtml:59 views/previews/edit.thtml:50
+msgid "devcp_previews_label_makedefault"
+msgstr "اجعل هذه هي صورة المعاينة المبدئية"
+
+#: views/developers/previews.thtml:100
+#, fuzzy
+msgid "devcp_previews_label_new"
+msgstr "New image:"
+
+#: views/developers/previews.thtml:118
+#, fuzzy
+msgid "devcp_previews_label_upload"
+msgstr "Upload Preview: "
+
+#: views/developers/previews.thtml:50
+#, fuzzy
+msgid "devcp_previews_notice_error"
+msgstr "One or more of your new previews could not be saved."
+
+#: views/developers/previews.thtml:47
+#, fuzzy
+msgid "devcp_previews_notice_success"
+msgstr "Your previews have been updated successfully."
+
+#: views/developers/previews.thtml:59
+#, fuzzy
+msgid "devcp_previews_p_screenshots"
+msgstr ""
+"The preview screenshots for your add-on are shown below. You can make "
+"changes to captions or images below. The Default Preview is the preview that "
+"is displayed next to your add-on in search and browse listings."
+
+#: views/previews/edit.thtml:55
+msgid "devcp_previews_submit_delete"
+msgstr "احذ٠المعاينة"
+
+#: views/previews/edit.thtml:55
+msgid "devcp_previews_submit_delete_confirm"
+msgstr "أمتأكد أنك تريد حذ٠هذه المعاينة؟"
+
+#: views/previews/edit.thtml:54
+msgid "devcp_previews_submit_edit"
+msgstr "حرّر المعاينة"
+
+#: views/previews/add.thtml:63
+msgid "devcp_previews_submit_upload"
+msgstr "ارÙع المعاينة"
+
+#: views/developers/previews.thtml:78
+#, fuzzy
+msgid "devcp_previews_thumbnail"
+msgstr "Thumbnail"
+
+#. %s is the add-on name.
+#: views/developers/previews.thtml:44
+#, fuzzy
+msgid "devcp_previews_title"
+msgstr "%s Preview Manager"
+
+#: views/developers/uploader.thtml:74
+msgid "devcp_review_agreement_please"
+msgstr "ÙŠÙرجى مراجعة وقبول اتÙاقية المطوّر التالية قبل المتابعة."
+
+#: views/elements/developers/rolecheck.thtml:42
+#, fuzzy
+msgid "devcp_rolecheck_no_privs"
+msgstr ""
+"<span>You do not have sufficient privileges to make changes on this page.</"
+"span><br />Contact the Add-on Owner if you need to make changes."
+
+#: controllers/developers_controller.php:1315
+#, fuzzy
+msgid "devcp_several_hours"
+msgstr ""
+"Please note that some changes may take several hours to appear in all areas "
+"of the website."
+
+#: views/elements/developers/sidebar.thtml:52
+#, fuzzy
+msgid "devcp_sidebar_a_dashboard"
+msgstr "Dashboard"
+
+#. %s is a number
+#: views/elements/developers/statsbar.thtml:45
+#: views/developers/dashboard.thtml:79
+#, php-format
+msgid "devcp_statsbar_adu"
+msgstr "<em>%s</em> مستخدمًا نشطًا يوميًا"
+
+#. %s is a number
+#: views/elements/developers/statsbar.thtml:41
+#: views/developers/dashboard.thtml:75
+#, php-format
+msgid "devcp_statsbar_total_downloads"
+msgstr "عدد التنزيلات الكامل <em>%s</em>"
+
+#. %s is a number
+#: views/elements/developers/statsbar.thtml:43
+#: views/developers/dashboard.thtml:77
+#, php-format
+msgid "devcp_statsbar_weekly_downloads"
+msgstr "التنزيلات الأسبوعية <em>%s</em>"
+
+#: views/developers/addon_status_confirm.thtml:59
+#, fuzzy
+msgid "devcp_status_confirm_active"
+msgstr ""
+"Marking this add-on active will cause it to show up in public areas "
+"appropriate for its status, including search and browse listings. It will be "
+"downloadable from the website and could be returned in client update checks, "
+"depending on its status. You will be able to return here and disable it "
+"again at your convenience."
+
+#: views/developers/addon_status_confirm.thtml:59
+#, fuzzy
+msgid "devcp_status_confirm_active_sure"
+msgstr "Are you sure you wish to mark this add-on active?"
+
+#: views/developers/addon_status_confirm.thtml:50
+#, fuzzy
+msgid "devcp_status_confirm_header_sure"
+msgstr "Are you sure?"
+
+#: views/developers/addon_status_confirm.thtml:55
+#, fuzzy
+msgid "devcp_status_confirm_inactive"
+msgstr ""
+"Marking this add-on inactive will prevent it from showing up in any public "
+"areas, including search and browse listings. It will not be downloadable "
+"from the website and will not be returned in client update checks. You will "
+"be able to return here and re-enable it at your convenience."
+
+#: views/developers/addon_status_confirm.thtml:55
+#, fuzzy
+msgid "devcp_status_confirm_inactive_sure"
+msgstr "Are you sure you wish to mark this add-on inactive?'"
+
+#: views/developers/addon_status_confirm.thtml:74
+#, fuzzy
+msgid "devcp_status_confirm_no"
+msgstr "No, cancel"
+
+#: views/developers/addon_status_confirm.thtml:67
+#, fuzzy
+msgid "devcp_status_confirm_public"
+msgstr ""
+"Making this add-on public will make it available for anyone to download and "
+"will begin offering updates to existing users."
+
+#: views/developers/addon_status_confirm.thtml:67
+#, fuzzy
+msgid "devcp_status_confirm_public_sure"
+msgstr "Are you sure you wish to make this add-on public?"
+
+#: views/developers/addon_status_confirm.thtml:63
+#, fuzzy
+msgid "devcp_status_confirm_sandbox"
+msgstr ""
+"Moving this add-on back to the sandbox will require users to login before "
+"downloading and updates will no longer be offered to existing users. Because "
+"your add-on is currently public, you will be able to return here at any time "
+"to make it public again."
+
+#: views/developers/addon_status_confirm.thtml:63
+#, fuzzy
+msgid "devcp_status_confirm_sandbox_sure"
+msgstr "Are you sure you wish to move this add-on to the sandbox?"
+
+#: views/developers/addon_status_confirm.thtml:73
+#, fuzzy
+msgid "devcp_status_confirm_yes"
+msgstr "Yes, I'm Sure"
+
+#: views/developers/addon_status_nominate.thtml:46
+#, fuzzy
+msgid "devcp_status_nominate_error_notice"
+msgstr ""
+"<span>A nomination message is required.</span><br />Please fill in the text "
+"box with the requested information and try again."
+
+#: views/developers/addon_status_nominate.thtml:55
+#, fuzzy
+msgid "devcp_status_nominate_header"
+msgstr "Add-on Nomination"
+
+#: views/developers/dashboard.thtml:85
+msgid "devcp_summary_lastversion"
+msgstr "الإصدارة الأخيرة:"
+
+#. %s is the add-on name.
+#: views/developers/addon_edit.thtml:43
+#: views/developers/addon_edit_authors.thtml:44
+#: views/developers/versions_delete.thtml:43
+#: views/developers/addon_edit_properties.thtml:44
+#: views/developers/addon_edit_descriptions.thtml:44
+#: views/developers/versions_edit.thtml:44
+#: views/developers/addon_edit_categories.thtml:43
+#: views/developers/versions.thtml:43
+#, fuzzy
+msgid "devcp_title_edit_addon"
+msgstr "Edit %s"
+
+#. title attribute for a javascript link that pops up a help dialog.
+#: views/elements/translationbox.thtml:68
+#, fuzzy
+msgid "devcp_transbox_a_title_help"
+msgstr "Help (does not leave page)"
+
+#: views/elements/translationbox.thtml:68
+#, fuzzy
+msgid "devcp_transbox_alt_help"
+msgstr "Help"
+
+#. %1$s is <span>17</span>, %2$s is 42.
+#: views/elements/translationbox.thtml:101
+#, fuzzy
+msgid "devcp_transbox_chars_used"
+msgstr "Characters used: %1$s / %2$s"
+
+#: views/elements/translationbox.thtml:132
+#, fuzzy
+msgid "devcp_transbox_delete_sure"
+msgstr "Are you sure you wish to delete this translation?"
+
+#. %s is a locale, like en-US.
+#: views/elements/translationbox.thtml:143
+#, fuzzy
+msgid "devcp_transbox_help_header_tabs"
+msgstr "What are these %s tabs?"
+
+#: views/elements/translationbox.thtml:145
+#, fuzzy
+msgid "devcp_transbox_help_header_what"
+msgstr "What if I don't have any translations?"
+
+#: views/elements/translationbox.thtml:147
+#, fuzzy
+msgid "devcp_transbox_help_hide"
+msgstr "Hide Help"
+
+#: views/elements/translationbox.thtml:146
+#, fuzzy
+msgid "devcp_transbox_help_if"
+msgstr ""
+"If a user browses the site and a translation isn't available in their own "
+"language, it will fall back to your add-on's Default Locale, specified in "
+"the Edit Add-on Properties area. If you don't have any translations, just "
+"enter what you can into your Default Locale, which should be a language you "
+"speak."
+
+#: views/elements/translationbox.thtml:144
+#, fuzzy
+msgid "devcp_transbox_help_transbox"
+msgstr ""
+"This is a <i>Translation Box</i>. It allows you to localize a specific field "
+"into any other languages for which you might have a translation. You can "
+"add, edit, and remove translations using the locale tabs."
+
+#: views/elements/translationbox.thtml:85
+#, fuzzy
+msgid "devcp_transbox_img_add_trans"
+msgstr "Add Translation"
+
+#: views/elements/translationbox.thtml:86
+#, fuzzy
+msgid "devcp_transbox_img_remove_trans"
+msgstr "Remove Translation"
+
+#: views/elements/translationbox.thtml:123
+#, fuzzy
+msgid "devcp_transbox_input_add_all"
+msgstr "Add Locale to All"
+
+#: views/elements/translationbox.thtml:122
+#, fuzzy
+msgid "devcp_transbox_input_add_locale"
+msgstr "Add Locale"
+
+#: views/elements/translationbox.thtml:124
+#: views/elements/translationbox.thtml:135
+#, fuzzy
+msgid "devcp_transbox_input_cancel"
+msgstr "Cancel"
+
+#: views/elements/translationbox.thtml:134
+#, fuzzy
+msgid "devcp_transbox_input_delete"
+msgstr "Delete It"
+
+#: views/elements/translationbox.thtml:113
+#, fuzzy
+msgid "devcp_transbox_select_locale"
+msgstr "Select the locale of the translation to add:"
+
+#. %1$s and %2$s are GUIDs.
+#: controllers/developers_controller.php:343
+#, fuzzy
+msgid "devcp_update_addon_guid_error"
+msgstr ""
+"The add-on GUID used in this file (%1$s) does not match the existing GUID "
+"for this add-on (%2$s)."
+
+#: controllers/developers_controller.php:334
+#, fuzzy
+msgid "devcp_update_addon_priv_error"
+msgstr "You do not have sufficient privileges to update this add-on."
+
+#. %1$s is a version number, %2$s is an add-on ID.
+#: controllers/developers_controller.php:399
+#, fuzzy
+msgid "devcp_update_addon_version_belong_error"
+msgstr "The specified version (%1$s) does not belong to this add-on (%2$s)."
+
+#. %1$s is a version number, maybe 1.1.
+#. %2$s is a URL.
+#: controllers/developers_controller.php:351
+#, fuzzy
+msgid "devcp_update_addon_version_exists_error"
+msgstr ""
+"The version number uploaded (%1$s) already exists for this add-on. If you "
+"are trying to add another file to this version, <a href=\"%2$s\">click here</"
+"a>."
+
+#. %1$s and %2$s are version numbers.
+#: controllers/developers_controller.php:405
+#, fuzzy
+msgid "devcp_update_addon_version_match_error"
+msgstr ""
+"The uploaded version number (%1$s) does not match the existing version "
+"number (%2$s)."
+
+#: views/developers/uploader.thtml:68
+#, fuzzy
+msgid "devcp_uploader_a_start"
+msgstr "Get Started"
+
+#: views/developers/uploader.thtml:137
+#, fuzzy
+msgid "devcp_uploader_ajax_loading"
+msgstr "Uploading file..."
+
+#: views/developers/uploader.thtml:82
+#, fuzzy
+msgid "devcp_uploader_button_agree"
+msgstr "Agree and continue"
+
+#: views/developers/uploader.thtml:157
+#, fuzzy
+msgid "devcp_uploader_button_edit"
+msgstr "Edit My Add-on"
+
+#: views/developers/uploader.thtml:158
+#, fuzzy
+msgid "devcp_uploader_button_later"
+msgstr "I'll complete my add-on later."
+
+#: views/developers/uploader.thtml:168
+#, fuzzy
+msgid "devcp_uploader_button_release"
+msgstr "Add Release Notes"
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/uploader.thtml:156
+#, fuzzy
+msgid "devcp_uploader_created_results"
+msgstr ""
+"<p>Your add-on listing has been successfully created. The basic information "
+"obtained from your uploaded file has been stored, but there's a lot more to "
+"your listing that can be customized.</p><p>Your add-on is currently marked "
+"as <strong>Incomplete</strong>. In order to complete your add-on, you'll "
+"need to make sure it has an accurate name, summary, and description, as well "
+"as at least one selected category. You can edit your add-on's information "
+"using the link below and check the status of your add-on at any time on the "
+"<a %s>status page</a>."
+
+#: views/developers/uploader.thtml:143
+#, fuzzy
+msgid "devcp_uploader_error_correct"
+msgstr "Please correct this problem and upload your file again."
+
+#. %1$s is a version number, %2$s is a status, e.g Public or Incomplete.
+#: views/developers/uploader.thtml:175
+#, fuzzy
+msgid "devcp_uploader_file_created"
+msgstr ""
+"Your new file has been added to version %1$s and is currently marked as %2$s."
+
+#: views/developers/uploader.thtml:154
+#, fuzzy
+msgid "devcp_uploader_header_created"
+msgstr "Add-on Created!"
+
+#: views/developers/uploader.thtml:141
+#, fuzzy
+msgid "devcp_uploader_header_error"
+msgstr "Oops! There seems to be a problem with this file..."
+
+#: views/developers/uploader.thtml:173
+#, fuzzy
+msgid "devcp_uploader_header_file_added"
+msgstr "File Added!"
+
+#: views/developers/uploader.thtml:66
+#, fuzzy
+msgid "devcp_uploader_header_how"
+msgstr "How does it all work?"
+
+#. %s is the version number, e.g. 3.2.
+#: views/developers/uploader.thtml:163
+#, fuzzy
+msgid "devcp_uploader_header_update_created"
+msgstr "Version %s Created"
+
+#: views/developers/uploader.thtml:117
+#, fuzzy
+msgid "devcp_uploader_header_upload"
+msgstr "Upload Your File"
+
+#: views/developers/uploader.thtml:67
+#, fuzzy
+msgid "devcp_uploader_how"
+msgstr ""
+"<p>Thanks for your interest in submitting your add-on to Mozilla Add-ons. "
+"Hosting your add-on on Mozilla Add-ons is the easiest way to handle "
+"distribution of your add-on. Here's what you'll get:</p><ul><li>Each add-on "
+"will have a public display page with information you provide, such as a "
+"brief summary of the add-on's functionality, an optional longer description, "
+"and a showcase of preview screenshots of your add-on.</li><li>Your add-on "
+"will appear in search and browse listings across the site, and even in the "
+"Add-ons Manager of Firefox 3.</li><li>We'll take care of hosting all of your "
+"downloads and providing automatic updates to users when you upload a new "
+"version.</li><li>You'll have access to a statistics dashboard with detailed "
+"information about your user base.</li></ul><p>Add-ons hosted on the site "
+"must be reviewed by a Mozilla Add-ons Editor before they will have all of "
+"the features listed above. If you're ready to start the process and have "
+"your add-on package ready for upload, just click on Get Started below!</p>"
+
+#: views/developers/uploader.thtml:125
+#, fuzzy
+msgid "devcp_uploader_label_platformtype"
+msgstr "Supported Platforms:"
+
+#: views/developers/uploader.thtml:124
+#, fuzzy
+msgid "devcp_uploader_label_upload_field"
+msgstr "Add-on File: "
+
+#: controllers/components/developers.php:1221
+#, fuzzy
+msgid "devcp_uploader_option_other"
+msgstr "Other"
+
+#. %1$s is a number, %2$s is href="..." and should stay in the <a> tag.
+#: views/developers/uploader.thtml:176
+#, fuzzy
+msgid "devcp_uploader_p_pending_file"
+msgstr ""
+"The new file will be available to the public as soon as an editor is able to "
+"review it. There are currently %1$s other add-ons in the queue. Want to be "
+"reviewed faster? Consider <a %2$s>becoming an editor</a>."
+
+#. %1$s is a number, %2$s is href="..." and should stay in the <a> tag.
+#: views/developers/uploader.thtml:166
+#, fuzzy
+msgid "devcp_uploader_p_pending_version"
+msgstr ""
+"The new version will be available to the public as soon as an editor is able "
+"to review it. There are currently %1$s other add-ons in the queue. Want to "
+"be reviewed faster? Consider <a %2$s>becoming an editor</a>."
+
+#. %s is a status, e.g Public or Incomplete.
+#: views/developers/uploader.thtml:165
+#, fuzzy
+msgid "devcp_uploader_p_update_created"
+msgstr "Your new version has been created and is currently marked as %s."
+
+#. %1$s is href="..." and should stay in the 'Versions and Files' <a> tag.
+#. %2$s is href="..." and should stay in the 'current status' <a> tag.
+#: views/developers/uploader.thtml:177
+#, fuzzy
+msgid "devcp_uploader_p_update_file"
+msgstr ""
+"View your new file in the <a %1$s>Versions and Files page</a>, check out "
+"your add-on's <a %2$s>current status</a>, or <b>add release notes</b> by "
+"clicking the button below (highly recommended)."
+
+#. %1$s is href="..." and should stay in the 'Versions and Files' <a> tag.
+#. %2$s is href="..." and should stay in the 'current status' <a> tag.
+#: views/developers/uploader.thtml:167
+#, fuzzy
+msgid "devcp_uploader_p_update_version"
+msgstr ""
+"View your new version in the <a %1$s>Versions and Files page</a>, check out "
+"your add-on's <a %2$s>current status</a>, or <b>add release notes</b> by "
+"clicking the button below (highly recommended)."
+
+#: views/developers/uploader.thtml:118
+#, fuzzy
+msgid "devcp_uploader_p_upload"
+msgstr ""
+"Upload your add-on file using the form below. If you have multiple, platform-"
+"specific files to upload, choose a single file and then upload the others "
+"using the Versions and Files Manager."
+
+#: views/developers/uploader.thtml:125
+#, fuzzy
+msgid "devcp_uploader_platformtype_all"
+msgstr "All"
+
+#: views/developers/uploader.thtml:126
+#, fuzzy
+msgid "devcp_uploader_platformtype_specific"
+msgstr "Specific:"
+
+#. Used as first item in a <select>.
+#: controllers/components/developers.php:1185
+#, fuzzy
+msgid "devcp_uploader_please_choose"
+msgstr "Please Choose..."
+
+#. %1$s is the add-on name, %2$s is the version number.
+#: views/developers/uploader.thtml:57
+#, fuzzy
+msgid "devcp_uploader_title_file"
+msgstr "Add File to %1$s %2$s"
+
+#: views/developers/uploader.thtml:50
+#, fuzzy
+msgid "devcp_uploader_title_submit"
+msgstr "Submit New Add-on"
+
+#. %s is the add-on name.
+#: views/developers/uploader.thtml:54
+#, fuzzy
+msgid "devcp_uploader_title_update"
+msgstr "Update %s"
+
+#. %s is a full <a> tag
+#: controllers/developers_controller.php:503
+#, php-format
+msgid "devcp_valid_app_reference"
+msgstr "ÙŠÙرجى الاطلاع على %s كمرجع."
+
+#. This is the text in the <a> tag for devcp_valid_app_reference. This should be
+#. fixed.
+#: controllers/developers_controller.php:503
+msgid "devcp_valid_app_reference_linktext"
+msgstr "هذه الصÙحة"
+
+#: controllers/developers_controller.php:581
+#, fuzzy
+msgid "devcp_verify_author_error"
+msgstr "No account found for that email address."
+
+#: controllers/developers_controller.php:553
+#, fuzzy
+msgid "devcp_verify_search_engine_error"
+msgstr ""
+"Either the XML is invalid or required fields are missing. Please <a href="
+"\"https://developer.mozilla.org/en/Creating_OpenSearch_plugins_for_Firefox"
+"\">read the documentation</a>, verify your add-on, and try again."
+
+#: views/developers/versions.thtml:75
+#, fuzzy
+msgid "devcp_versions_a_cancel"
+msgstr "Cancel"
+
+#: views/developers/versions.thtml:79
+#, fuzzy
+msgid "devcp_versions_a_delete"
+msgstr "Delete Version"
+
+#: views/developers/versions.thtml:74
+#, fuzzy
+msgid "devcp_versions_a_empty"
+msgstr "Remove Empty Version"
+
+#: views/developers/versions.thtml:71
+#, fuzzy
+msgid "devcp_versions_a_remove"
+msgstr "Remove?"
+
+#: views/developers/versions.thtml:91
+#, fuzzy
+msgid "devcp_versions_add"
+msgstr "Add New Version"
+
+#: views/developers/versions_delete.thtml:58
+#, fuzzy
+msgid "devcp_versions_delete_a_cancel"
+msgstr "Cancel"
+
+#: views/developers/versions_delete.thtml:56
+#, fuzzy
+msgid "devcp_versions_delete_a_delete"
+msgstr "Delete Version"
+
+#. Followed by a list of reviews and files that will be removed.
+#: views/developers/versions_delete.thtml:50
+#, fuzzy
+msgid "devcp_versions_delete_also"
+msgstr "This will also delete:"
+
+#: views/developers/versions_delete.thtml:53
+#, fuzzy
+msgid "devcp_versions_delete_files"
+msgid_plural "devcp_versions_delete_files"
+msgstr[0] "%s file"
+msgstr[1] "%s files"
+
+#. %s is the version number.
+#: views/developers/versions_delete.thtml:48
+#, fuzzy
+msgid "devcp_versions_delete_header"
+msgstr "Delete Version %s?"
+
+#: views/developers/versions_delete.thtml:52
+#, fuzzy
+msgid "devcp_versions_delete_reviews"
+msgid_plural "devcp_versions_delete_reviews"
+msgstr[0] "%s review"
+msgstr[1] "%s reviews"
+
+#. %s is the version number.
+#: views/developers/versions_delete.thtml:49
+#, fuzzy
+msgid "devcp_versions_delete_sure"
+msgstr "Are you sure you want to permanently delete version %s?"
+
+#: views/developers/versions_edit.thtml:102
+#: views/developers/versions_edit.thtml:155
+#, fuzzy
+msgid "devcp_versions_edit_a_cancel"
+msgstr "Cancel"
+
+#: views/developers/versions_edit.thtml:101
+#, fuzzy
+msgid "devcp_versions_edit_a_delete"
+msgstr "Delete File"
+
+#: views/developers/versions_edit.thtml:165
+#, fuzzy
+msgid "devcp_versions_edit_a_new_app"
+msgstr "Add New Application"
+
+#: views/developers/versions_edit.thtml:154
+#, fuzzy
+msgid "devcp_versions_edit_a_remove_app"
+msgstr "Remove Application"
+
+#: views/developers/versions_edit.thtml:114
+#, fuzzy
+msgid "devcp_versions_edit_add"
+msgstr "Add New File"
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/versions_edit.thtml:121
+#, fuzzy
+msgid "devcp_versions_edit_adjust"
+msgstr ""
+"Adjusting application information here will allow users to install your add-"
+"on even if the install.rdf in the package indicates that the add-on is "
+"incompatible. <a %s>List of supported applications</a>"
+
+#: views/developers/versions_edit.thtml:153
+#, fuzzy
+msgid "devcp_versions_edit_compat_sure"
+msgstr ""
+"Are you <b>sure</b> you wish to remove compatibility with this application?"
+
+#: views/developers/versions_edit.thtml:100
+#, fuzzy
+msgid "devcp_versions_edit_delete_sure"
+msgstr "Are you <b>sure</b> you wish to permanently delete this file?"
+
+#: views/developers/versions_edit.thtml:203
+#, fuzzy
+msgid "devcp_versions_edit_header_approval"
+msgstr "Approval Information"
+
+#: views/developers/versions_edit.thtml:120
+#, fuzzy
+msgid "devcp_versions_edit_header_compat"
+msgstr "Compatible Applications"
+
+#: views/developers/versions_edit.thtml:74
+#, fuzzy
+msgid "devcp_versions_edit_header_file"
+msgstr "File Information"
+
+#: views/developers/versions_edit.thtml:189
+#, fuzzy
+msgid "devcp_versions_edit_header_license"
+msgstr "License"
+
+#. %s is the version number.
+#: views/developers/versions_edit.thtml:53
+#, fuzzy
+msgid "devcp_versions_edit_header_manage"
+msgstr "Manage Version %s"
+
+#: views/developers/versions_edit.thtml:212
+#, fuzzy
+msgid "devcp_versions_edit_header_notes"
+msgstr "Approval Notes"
+
+#: views/developers/versions_edit.thtml:98
+#, fuzzy
+msgid "devcp_versions_edit_img_delete"
+msgstr "Delete File"
+
+#. %1$s is the file id, e.g. 18723.
+#. %2$s is the platform name, e.g. ALL or Windows.
+#. %3$s is the _('date) created.
+#. %4$s is the status, e.g. "In Sandbox" or "Public".
+#. %5$s is the _('date') status was changed.
+#: views/developers/versions_edit.thtml:208
+#, fuzzy
+msgid "devcp_versions_edit_li_file"
+msgstr "File %1$s (%2$s) created on %3$s and changed to %4$s on %5$s"
+
+#: views/developers/versions_edit.thtml:190
+#, fuzzy
+msgid "devcp_versions_edit_license_description"
+msgstr ""
+"Please select the appropriate license for your add-on. This license "
+"specifies the rights you grant on your source code."
+
+#: views/developers/versions_edit.thtml:111
+#, fuzzy
+msgid "devcp_versions_edit_no_files"
+msgstr "No files found."
+
+#: views/developers/versions_edit.thtml:213
+#, fuzzy
+msgid "devcp_versions_edit_optional"
+msgstr "Optional information for the Editor that reviews this version."
+
+#: views/developers/versions_edit.thtml:151
+#, fuzzy
+msgid "devcp_versions_edit_remove_compat"
+msgstr "Remove Application Compatibility"
+
+#: views/developers/versions_edit.thtml:167
+#, fuzzy
+msgid "devcp_versions_edit_select_app"
+msgstr "Please Select an Application"
+
+#: views/developers/versions_edit.thtml:78
+#, fuzzy
+msgid "devcp_versions_edit_th_file"
+msgstr "File"
+
+#: views/developers/versions_edit.thtml:79
+#, fuzzy
+msgid "devcp_versions_edit_th_platform"
+msgstr "Platform"
+
+#: views/developers/versions_edit.thtml:80
+#, fuzzy
+msgid "devcp_versions_edit_th_size"
+msgstr "Size"
+
+#: views/developers/versions_edit.thtml:81
+#, fuzzy
+msgid "devcp_versions_edit_th_status"
+msgstr "Status"
+
+#: views/developers/versions_edit.thtml:183
+#, fuzzy
+msgid "devcp_versions_edit_transbox_releasenotes_description"
+msgstr ""
+"Information about changes in this release, new features, known bugs, and "
+"other useful information specific to this release/version. This information "
+"will also be available to users updating the add-on in the Firefox 3 Add-ons "
+"Manager interface."
+
+#: views/developers/versions_edit.thtml:182
+#, fuzzy
+msgid "devcp_versions_edit_transbox_releasenotes_name"
+msgstr "Release Notes"
+
+#: views/developers/versions_edit.thtml:164
+#, fuzzy
+msgid "devcp_versions_edit_unsaved_compat"
+msgstr ""
+"<strong>You have unsaved changes.</strong> Compatibility will not be deleted "
+"until you click Update Version below."
+
+#: views/developers/versions_edit.thtml:113
+#, fuzzy
+msgid "devcp_versions_edit_unsaved_files"
+msgstr ""
+"<strong>You have unsaved changes.</strong> Files will not be deleted until "
+"you click Update Version below."
+
+#: views/developers/versions_edit.thtml:218
+#, fuzzy
+msgid "devcp_versions_edit_update"
+msgstr "Update Versions"
+
+#: views/developers/versions.thtml:49
+#, fuzzy
+msgid "devcp_versions_header_manage"
+msgstr "Manage Versions and Files"
+
+#: views/developers/versions.thtml:87
+#, fuzzy
+msgid "devcp_versions_no_versions"
+msgstr "No versions."
+
+#. %s is a version number, base 10.
+#: views/developers/versions.thtml:46
+#, fuzzy
+msgid "devcp_versions_notice_success"
+msgstr "Version %s deleted successfully."
+
+#: views/developers/versions.thtml:73
+#, fuzzy
+msgid "devcp_versions_p_remove"
+msgstr ""
+"This version has no files associated with it and can be removed. Would you "
+"like to remove this version?"
+
+#: views/developers/versions.thtml:58
+#, fuzzy
+msgid "devcp_versions_th_created"
+msgstr "Created"
+
+#: views/developers/versions.thtml:57
+#, fuzzy
+msgid "devcp_versions_th_status"
+msgstr "Status"
+
+#: views/developers/versions.thtml:56
+#, fuzzy
+msgid "devcp_versions_th_version"
+msgstr "Version"
+
+#: controllers/downloads_controller.php:91
+msgid "downloads_disable_warning"
+msgstr "هذه الإضاÙØ© معطّلة"
+
+#: controllers/components/editors.php:57
+msgid "editor_review_error_addon_not_nominated"
+msgstr "رÙشّحت الإضاÙØ©."
+
+#: controllers/components/editors.php:213
+msgid "editor_review_error_file_not_pending"
+msgstr "المل٠لا ينتظر المراجعة."
+
+#. Actions are, for example: approving or rejecting
+#: controllers/components/editors.php:79
+#: controllers/components/editors.php:182
+msgid "editor_review_error_no_action"
+msgstr "اختر إجراء مراجعة رجاءً."
+
+#: controllers/components/editors.php:192
+msgid "editor_review_error_no_applications"
+msgstr "أدخÙÙ„ رجاءً التطبيقات التي اختبرتها."
+
+#. Comments are required when an editor approves or rejects an add-on.
+#: controllers/components/editors.php:84
+#: controllers/components/editors.php:187
+msgid "editor_review_error_no_comments"
+msgstr "أدخÙÙ„ رجاءً تعليقات المراجعة."
+
+#: controllers/components/editors.php:161
+msgid "editor_review_error_no_files"
+msgstr "اختر رجاءً ملÙًا واحدًا على الأقل لمراجعته."
+
+#: controllers/components/editors.php:197
+msgid "editor_review_error_no_operating_system"
+msgstr "أدخÙÙ„ رجاءً أنظمة التشغيل التي اختبرت عليها."
+
+#: views/editors/logs.thtml:51
+msgid "editorcp_logs_button_filter"
+msgstr "تصÙية"
+
+#: views/editors/logs.thtml:44
+msgid "editorcp_logs_filter_by"
+msgstr "تصÙية حسب النوع/الإجراء"
+
+#: views/editors/logs.thtml:42 controllers/editors_controller.php:964
+msgid "editorcp_logs_page_heading"
+msgstr "سجلّ الأحداث"
+
+#: views/elements/developers/editorsmenu.thtml:60
+msgid "editorcp_menu_eventlog_link"
+msgstr "سجلّ الأحداث"
+
+#: views/elements/developers/editorsmenu.thtml:62
+msgid "editorcp_menu_mainpage_link"
+msgstr "عودة إلى الرئيسية"
+
+#: views/elements/developers/editorsmenu.thtml:61
+msgid "editorcp_menu_reviewlog_link"
+msgstr "سجلّ المراجعات"
+
+#: views/elements/developers/editorsmenu.thtml:55
+msgid "editorcp_menu_summary_link"
+msgstr "ملخص المحرّر"
+
+#: views/elements/developers/editorsmenu.thtml:52
+msgid "editorcp_menu_title"
+msgstr "أدوات المحرّر"
+
+#: views/editors/reviewlog.thtml:49
+msgid "editorcp_reviewlog_button_filter"
+msgstr "تصÙية"
+
+#: views/editors/reviewlog.thtml:58
+msgid "editorcp_reviewlog_column_action"
+msgstr "الإجراء"
+
+#: views/editors/reviewlog.thtml:56
+msgid "editorcp_reviewlog_column_addon"
+msgstr "الإضاÙØ©"
+
+#: views/editors/reviewlog.thtml:55
+msgid "editorcp_reviewlog_column_date"
+msgstr "التاريخ"
+
+#: views/editors/reviewlog.thtml:57
+msgid "editorcp_reviewlog_column_editor"
+msgstr "المحرّر"
+
+#: views/editors/reviewlog.thtml:94
+msgid "editorcp_reviewlog_comments_hide"
+msgstr "أخÙ٠التعليقات"
+
+#: views/editors/reviewlog.thtml:93
+msgid "editorcp_reviewlog_comments_show"
+msgstr "أظهÙر التعليقات"
+
+#. %1$s and %2$s are full <input> tags for dates
+#: views/editors/reviewlog.thtml:45
+#, php-format
+msgid "editorcp_reviewlog_entries_between"
+msgstr "اعرض الإدخالات بين %s و %s"
+
+#: views/editors/reviewlog.thtml:104
+msgid "editorcp_reviewlog_none_found"
+msgstr "لا يوجد مراجعات ÙÙŠ هذه الÙترة."
+
+#: views/editors/reviewlog.thtml:42
+msgid "editorcp_reviewlog_page_heading"
+msgstr "سجلّ المراجعات"
+
+#: views/editors/summary.thtml:61
+msgid "editorcp_summary_monthreviews_heading"
+msgstr "مراجعات الشهر"
+
+#: views/editors/summary.thtml:77
+msgid "editorcp_summary_neweditors_heading"
+msgstr "المحرّرون الجدد"
+
+#: views/editors/summary.thtml:42
+msgid "editorcp_summary_page_heading"
+msgstr "ملخص المحرّر"
+
+#: views/editors/summary.thtml:94
+msgid "editorcp_summary_recentactivity_heading"
+msgstr "نشاط المحرّر مؤخرًا"
+
+#: views/editors/summary.thtml:45
+msgid "editorcp_summary_totalreviews_heading"
+msgstr "كل المراجعات"
+
+#: controllers/editors_controller.php:248
+#: controllers/editors_controller.php:249
+msgid "editors_addon_review_pagetitle"
+msgstr "مراجعة الإضاÙØ©"
+
+#: controllers/editors_controller.php:349
+msgid "editors_error_js-formerror"
+msgstr "أكمÙÙ„ رجاءً الحقول التالية:"
+
+#: controllers/editors_controller.php:350
+msgid "editors_error_review_one_file"
+msgstr "اختر رجاءً ملÙًا واحدًا على الأقل لمراجعته."
+
+#: controllers/editors_controller.php:274
+msgid "editors_error_self_reviews_forbidden"
+msgstr "مراجعاتك لإضاÙتك غير مسموحة."
+
+#: controllers/editors_controller.php:699
+msgid "editors_external_software"
+msgstr "برنامج خارجي"
+
+#: views/editors/featured.thtml:120 views/editors/featured.thtml:121
+msgid "editors_featured_add_feature"
+msgstr "أضÙ٠ميزة"
+
+#: views/editors/featured.thtml:126
+msgid "editors_featured_add_feature_submit"
+msgstr "أضÙÙ"
+
+#: views/editors/featured.thtml:49 controllers/editors_controller.php:832
+#: controllers/editors_controller.php:848
+msgid "editors_featured_addon_add_failure"
+msgstr "Ùشلت إضاÙØ© الميزة."
+
+#: controllers/editors_controller.php:851
+msgid "editors_featured_addon_add_success"
+msgstr "أضيÙت الميزة بنجاح."
+
+#: views/editors/featured.thtml:50 controllers/editors_controller.php:839
+#: controllers/editors_controller.php:868
+#: controllers/editors_controller.php:886
+msgid "editors_featured_addon_edit_failure"
+msgstr "Ùشل تحرير الميزة."
+
+#: views/editors/featured.thtml:51 controllers/editors_controller.php:888
+msgid "editors_featured_addon_edit_success"
+msgstr "Ø­Ùرّرت الميزة بنجاح."
+
+#: views/editors/featured.thtml:53 controllers/editors_controller.php:861
+msgid "editors_featured_addon_invalid_locale"
+msgstr "هناك لغة واحدة أو أكثر غير صالحة."
+
+#: views/editors/featured.thtml:52 controllers/editors_controller.php:906
+msgid "editors_featured_addon_remove_failure"
+msgstr "Ùشلت إزالة الميزة."
+
+#: controllers/editors_controller.php:901
+msgid "editors_featured_addon_remove_success"
+msgstr "أزيلت الميزة بنجاح."
+
+#: controllers/editors_controller.php:915
+#: controllers/editors_controller.php:917
+msgid "editors_featured_addons_pagetitle"
+msgstr "الإضاÙات المميّزة"
+
+#: views/editors/featured.thtml:54 views/editors/featured.thtml:107
+msgid "editors_featured_edit_feature_submit"
+msgstr "اذهب"
+
+#: views/editors/featured.thtml:90 views/editors/featured.thtml:91
+msgid "editors_featured_remove_feature"
+msgstr "أزÙÙ„ الميزة"
+
+#: views/editors/queue.thtml:46
+msgid "editors_filter_queue"
+msgstr "تصÙية الطابور"
+
+#: views/editors/queue.thtml:182
+msgid "editors_helpful_links"
+msgstr "وصلات Ù…Ùيدة"
+
+#: views/editors/queue.thtml:182
+msgid "editors_link_guide"
+msgstr "مرشد المحرّرين"
+
+#: views/editors/queue.thtml:182
+msgid "editors_link_policy"
+msgstr "سياسة الإضاÙØ©"
+
+#: views/editors/queue.thtml:47
+msgid "editors_notice_filter_session"
+msgstr "ستبقى هذه المصÙّيات طوال هذه الجلسة أو حتى مسحها."
+
+#. %1 is the queue mode
+#: views/editors/queue.thtml:177 views/admin/flagged_queue.thtml:89
+msgid "editors_notice_none_found"
+msgstr "لا يوجد إضاÙات من هذا النوع حاليًا لمراجعتها."
+
+#: controllers/editors_controller.php:1040
+msgid "editors_one_day"
+msgstr "يوم واحد"
+
+#: controllers/editors_controller.php:1048
+msgid "editors_one_hour"
+msgstr "ساعة واحدة"
+
+#: controllers/editors_controller.php:1056
+msgid "editors_one_minute"
+msgstr "دقيقة واحدة"
+
+#: controllers/editors_controller.php:64 controllers/editors_controller.php:73
+#: controllers/editors_controller.php:77
+msgid "editors_pagetitle"
+msgstr "أدوات المحرّر"
+
+#. %s is a comma separated list of platforms. Example: Windows, OS X
+#: controllers/editors_controller.php:680
+#: controllers/editors_controller.php:683
+#, php-format
+msgid "editors_platform_x_only"
+msgstr "%s Ùقط"
+
+#: controllers/editors_controller.php:695
+msgid "editors_pre-release"
+msgstr "ما-قبل-الإصدارة"
+
+#. %1 is the app name
+#: views/editors/queue.thtml:131
+#, php-format
+msgid "editors_queue_app_compatibility"
+msgstr "التواÙÙ‚ مع %s"
+
+#: views/editors/queue.thtml:51
+#, fuzzy
+msgid "editors_queue_filter_label_addon"
+msgstr "Add-on or Author Email"
+
+#: views/editors/queue.thtml:72
+#, fuzzy
+msgid "editors_queue_filter_label_addontypes"
+msgstr "Add-on Types"
+
+#: views/editors/queue.thtml:56
+#, fuzzy
+msgid "editors_queue_filter_label_application"
+msgstr "Application"
+
+#: views/editors/queue.thtml:61
+#, fuzzy
+msgid "editors_queue_filter_label_maxversion"
+msgstr "Max. Version"
+
+#: views/editors/queue.thtml:78
+#, fuzzy
+msgid "editors_queue_filter_label_platforms"
+msgstr "Platforms"
+
+#: views/editors/queue.thtml:66
+#, fuzzy
+msgid "editors_queue_filter_label_submissionage"
+msgstr "Age of Submission (days)"
+
+#. %1$s is a number
+#: views/editors/queue.thtml:90
+#, fuzzy
+msgid "editors_queue_filter_result_count"
+msgid_plural "editors_queue_filter_result_count"
+msgstr[0] "Results of your filtered search: <strong>%1$s</strong> Add-on"
+msgstr[1] "Results of your filtered search: <strong>%1$s</strong> Add-ons"
+
+#: views/editors/queue.thtml:84
+msgid "editors_queue_submit_clean"
+msgstr "امسح"
+
+#: views/editors/queue.thtml:83
+msgid "editors_queue_submit_filter"
+msgstr "صَÙÙ‘Ù"
+
+#: controllers/editors_controller.php:133
+msgid "editors_queues_disabled"
+msgstr "جميع طوابير المراجعات معطلة حاليًا. ÙŠÙرجى إعادة المحاولة لاحقًا."
+
+#: views/editors/review.thtml:149
+#, fuzzy
+msgid "editors_review_a_edit_item"
+msgstr "Edit Item"
+
+#: views/editors/review.thtml:146
+#, fuzzy
+msgid "editors_review_a_item_history"
+msgstr "Item History"
+
+#: views/editors/review.thtml:148
+#, fuzzy
+msgid "editors_review_a_item_homepage"
+msgstr "Item Homepage"
+
+#: views/editors/review.thtml:145
+#, fuzzy
+msgid "editors_review_a_item_overview"
+msgstr "Item Overview"
+
+#: views/editors/review.thtml:147
+#, fuzzy
+msgid "editors_review_a_previews"
+msgstr "Previews"
+
+#: controllers/editors_controller.php:345
+msgid "editors_review_action"
+msgstr "إجراء المراجعة"
+
+#: views/editors/review.thtml:159
+msgid "editors_review_action_info"
+msgstr "اطلب المزيد من المعلومات"
+
+#: views/editors/review.thtml:157
+msgid "editors_review_action_public"
+msgstr "انشر على العموم"
+
+#: views/editors/review.thtml:160
+msgid "editors_review_action_request_superreview"
+msgstr "اطلب مراجعة ممتازة"
+
+#: views/editors/review.thtml:158
+msgid "editors_review_action_sandbox"
+msgstr "أبْقÙها ÙÙŠ ساحة اللعب"
+
+#: controllers/editors_controller.php:346
+msgid "editors_review_comments"
+msgstr "تعليقات المراجعة"
+
+#: views/editors/review.thtml:182
+msgid "editors_review_details_info_request"
+msgstr ""
+"استخدم هذا النموذج لطلب المزيد من المعلومات من المؤلÙ. سيستلم المؤل٠رسالة "
+"ليتمكن من الإجابة هنا، وستستلم إشعارًا بريديًا عندما يجيب."
+
+#: views/editors/review.thtml:174
+msgid "editors_review_details_nominated_public"
+msgstr ""
+"هذا سيضي٠علامة النشر للعموم على الإضاÙØ© وإصدارتها الأخيرة وملÙاتها. ستوضع "
+"الإصدارات المستقبلية ÙÙŠ ساحة اللعب حتى يراجعها أحد المحرّرين."
+
+#: views/editors/review.thtml:177
+msgid "editors_review_details_nominated_sandbox"
+msgstr "هذا سيبقي الإضاÙØ© ÙÙŠ ساحة اللعب."
+
+#: views/editors/review.thtml:166
+msgid "editors_review_details_pending_public"
+msgstr ""
+"هذا سيعطي الإذن لنسخة ساحة لعب من إضاÙØ© عامة بأن تÙنشر ÙÙŠ الساحة العامة."
+
+#: views/editors/review.thtml:169
+msgid "editors_review_details_pending_sandbox"
+msgstr "هذا سيجبر نسخة ساحة لعب من إضاÙØ© عامة على البقاء ÙÙŠ ساحة اللعب."
+
+#: views/editors/review.thtml:185
+msgid "editors_review_details_superreview"
+msgstr ""
+"إن كنتَ مهتمًا بخصوص أمن هذه الإضاÙØ© أو شؤون حقوق نسخها أو أي أمور أخرى ينبغي "
+"للمدير أن يطلع عليها، أدخÙÙ„ تعليقاتك ÙÙŠ المساحة أدناه، وستÙرسل إلى المدراء لا "
+"إلى المؤلÙ."
+
+#: views/editors/review.thtml:134
+msgid "editors_review_file_diff_link"
+msgstr "قارÙÙ† مع النسخة العامة"
+
+#: views/editors/review.thtml:131
+msgid "editors_review_file_viewcontents_link"
+msgstr "اعرض المحتويات"
+
+#: views/editors/review.thtml:65
+msgid "editors_review_header_authors"
+msgstr "المؤلÙون:"
+
+#: views/editors/review.thtml:79
+msgid "editors_review_header_categories"
+msgstr "التصنيÙات:"
+
+#: views/editors/review.thtml:92
+msgid "editors_review_header_compatibility"
+msgstr "التواÙقية:"
+
+#: views/editors/review.thtml:251
+msgid "editors_review_header_description"
+msgstr "الوصÙ"
+
+#: views/editors/review.thtml:275
+msgid "editors_review_header_devcomments"
+msgstr "تعليقات المطوّر"
+
+#: views/editors/review.thtml:263
+msgid "editors_review_header_eula"
+msgstr "اتÙاقية ترخيص المستخدم"
+
+#: views/editors/review.thtml:115
+msgid "editors_review_header_files"
+msgstr "الملÙات:"
+
+#: views/editors/review.thtml:284
+msgid "editors_review_header_itemhistory"
+msgstr "تاريخ العناصر"
+
+#: views/editors/review.thtml:232
+msgid "editors_review_header_nominationmessage"
+msgstr "رسالة الترشيح"
+
+#: views/editors/review.thtml:311
+msgid "editors_review_header_previews"
+msgstr "المعاينات"
+
+#: views/editors/review.thtml:269
+msgid "editors_review_header_privacy"
+msgstr "سياسة الخصوصية"
+
+#. %1 is the add-on name and version
+#: views/editors/review.thtml:56
+#, php-format
+msgid "editors_review_header_review"
+msgstr "راجع %s"
+
+#: views/editors/review.thtml:239
+msgid "editors_review_header_reviewernotes"
+msgstr "ملاحظات للمراجع"
+
+#: views/editors/review.thtml:245
+msgid "editors_review_header_summary"
+msgstr "الملخص"
+
+#: views/editors/review.thtml:257
+msgid "editors_review_header_versionnotes"
+msgstr "ملاحظات الإصدارة"
+
+#. a noun: shown in an add-on's editor review history
+#: views/elements/developers/editors_review_history_item.thtml:80
+msgid "editors_review_history_info_reply"
+msgstr "ردّ"
+
+#: views/elements/developers/editors_review_history_item.thtml:78
+msgid "editors_review_history_info_request"
+msgstr "طلب معلومات"
+
+#: views/elements/developers/editors_review_history_item.thtml:62
+#: views/editors/reviewlog.thtml:77
+msgid "editors_review_history_nominated_adminreview"
+msgstr "مراجعة للمدير"
+
+#: views/elements/developers/editors_review_history_item.thtml:56
+#: views/editors/reviewlog.thtml:71
+msgid "editors_review_history_nominated_approved"
+msgstr "الترشيح مقبول/الساحة العامة"
+
+#: views/elements/developers/editors_review_history_item.thtml:59
+#: views/editors/reviewlog.thtml:74
+msgid "editors_review_history_nominated_denied"
+msgstr "الترشيح مرÙوض/ساحة اللعب"
+
+#: views/editors/review.thtml:303
+msgid "editors_review_history_nonefound"
+msgstr "تعذر إيجاد إدخالات مراجعات سابقة."
+
+#: views/elements/developers/editors_review_history_item.thtml:73
+#: views/editors/reviewlog.thtml:88
+msgid "editors_review_history_pending_adminreview"
+msgstr "مراجعة للمدير"
+
+#: views/elements/developers/editors_review_history_item.thtml:67
+#: views/editors/reviewlog.thtml:82
+msgid "editors_review_history_pending_approved"
+msgstr "مقبولة/الساحة العامة"
+
+#: views/elements/developers/editors_review_history_item.thtml:70
+#: views/editors/reviewlog.thtml:85
+msgid "editors_review_history_pending_denied"
+msgstr "مرÙوضة/ساحة اللعب"
+
+#. link text in an add-on's editor review history, allowing to hide and show an information request's replies
+#. %1 is the number of replies
+#: views/elements/developers/editors_review_history_item.thtml:90
+msgid "editors_review_history_show_hide_replies"
+msgid_plural "editors_review_history_show_hide_replies"
+msgstr[0] "أظهÙر/أخÙ٠الردود (%1$s)"
+msgstr[1] "أظهÙر/أخÙ٠الردّ (%1$s)"
+msgstr[2] "أظهÙر/أخÙ٠الردّين (%1$s)"
+msgstr[3] "أظهÙر/أخÙ٠الردود (%1$s)"
+msgstr[4] "أظهÙر/أخÙ٠الردود (%1$s)"
+msgstr[5] "أظهÙر/أخÙ٠الردود (%1$s)"
+
+#: views/editors/review.thtml:208
+msgid "editors_review_label_applications"
+msgstr "التطبيقات:"
+
+#: views/editors/review.thtml:196
+msgid "editors_review_label_cannedresponse"
+msgstr "أو اختر ردًا معلبًا:"
+
+#: views/editors/review.thtml:190
+msgid "editors_review_label_comments"
+msgstr "التعليقات:"
+
+#: views/editors/review.thtml:204
+msgid "editors_review_label_operating_systems"
+msgstr "أنظمة التشغيل:"
+
+#: views/editors/review.thtml:285 views/editors/review.thtml:312
+msgid "editors_review_link_pagetop"
+msgstr "Ùوق"
+
+#: views/editors/review.thtml:141
+#, fuzzy
+msgid "editors_review_mulitple_notice"
+msgstr ""
+"Notice: Only review more than one file if you have tested EVERY file you "
+"select."
+
+#: views/editors/review.thtml:51
+msgid "editors_review_next_link"
+msgstr "تالي &raquo;"
+
+#: views/editors/review.thtml:322
+msgid "editors_review_previews_notfound"
+msgstr "لا معاينات موجودة."
+
+#: views/editors/review.thtml:50
+msgid "editors_review_previous_link"
+msgstr "&laquo; سابق"
+
+#: controllers/editors_controller.php:144
+#: controllers/editors_controller.php:146
+msgid "editors_review_queue_pagetitle"
+msgstr "طابور المراجعات"
+
+#. %1 is the add-ons rank in the queue, %2 is the total queue length
+#: views/editors/review.thtml:47
+msgid "editors_review_rank_in_queue"
+msgstr "<strong># %1$s</strong> من أصل %2$s ÙÙŠ الطابور"
+
+#. %1 is the add-ons rank in the queue, %2 is the total queue length. Both numbers
+#: views/editors/review.thtml:45
+#, fuzzy
+msgid "editors_review_rank_in_queue_filtered"
+msgstr "<strong># %1$s</strong> of %2$s in queue (filtered)"
+
+#: views/editors/review.thtml:223
+msgid "editors_review_submit_process_action"
+msgstr "Ù‚ÙÙ… بالإجراء"
+
+#: views/editors/review.thtml:293
+msgid "editors_review_th_action"
+msgstr "الإجراء"
+
+#: views/editors/review.thtml:294
+msgid "editors_review_th_comments"
+msgstr "التعليقات"
+
+#: views/editors/review.thtml:291
+msgid "editors_review_th_date"
+msgstr "التاريخ"
+
+#: views/editors/review.thtml:292
+msgid "editors_review_th_reviewer"
+msgstr "المÙراجع"
+
+#: views/editors/review.thtml:290
+msgid "editors_review_th_version_file"
+msgstr "إصدارة/ملÙ"
+
+#: views/editors/review.thtml:217
+msgid "editors_review_update_notify_once"
+msgstr ""
+"نبّهني عند وجود تحديث لهذه الإضاÙØ© (التحديثات اللاحقة لن تتسبب بإرسال رسالة)."
+
+#: controllers/editors_controller.php:298
+msgid "editors_reviewed_successfully"
+msgstr "عولجت المراجعة بنجاح."
+
+#: views/editors/reviews_queue.thtml:106
+msgid "editors_reviews_action_delete_review"
+msgstr "احذ٠المراجعة"
+
+#: views/editors/reviews_queue.thtml:104
+msgid "editors_reviews_action_keep"
+msgstr "أزÙÙ„ الأعلام؛ أبْق٠المراجعة"
+
+#: views/editors/reviews_queue.thtml:102
+msgid "editors_reviews_action_skip"
+msgstr "تجاوز"
+
+#: views/editors/reviews_queue.thtml:100
+msgid "editors_reviews_header_action"
+msgstr "الإجراء"
+
+#: views/editors/reviews_queue.thtml:67
+msgid "editors_reviews_in_reply_to"
+msgstr "ردًا على:"
+
+#: controllers/editors_controller.php:748
+msgid "editors_reviews_processed"
+msgstr "عولجت المراجعات بنجاح!"
+
+#: views/editors/reviews_queue.thtml:117
+msgid "editors_reviews_queue_empty"
+msgstr "لا يوجد مراجعات تحت الإشرا٠حاليًا."
+
+#: views/editors/reviews_queue.thtml:111
+msgid "editors_reviews_submit_process_reviews"
+msgstr "عالج المراجعات"
+
+#: controllers/editors_controller.php:691
+msgid "editors_site_specific"
+msgstr "مختص بموقع معيّن"
+
+#: controllers/editors_controller.php:348
+msgid "editors_tested_app"
+msgstr "تطبيق مجرَّب"
+
+#: controllers/editors_controller.php:347
+msgid "editors_tested_os"
+msgstr "أنظمة تشغيل مجرَّبة"
+
+#: views/editors/queue.thtml:151
+msgid "editors_th_additional_info"
+msgstr "معلومات إضاÙية"
+
+#: views/editors/featured.thtml:63 views/editors/queue.thtml:109
+#: views/admin/flagged_queue.thtml:53
+msgid "editors_th_addon"
+msgstr "الإضاÙØ©"
+
+#: views/editors/queue.thtml:125
+msgid "editors_th_addontype"
+msgstr "النوع"
+
+#: views/editors/featured.thtml:64
+msgid "editors_th_locales"
+msgstr "حصرها باللغات؟"
+
+#: views/editors/queue.thtml:148
+#, fuzzy
+msgid "editors_th_nomination_age"
+msgstr "Time in Queue"
+
+#: views/editors/queue.thtml:101 views/editors/queue.thtml:117
+#: views/editors/queue.thtml:144
+#, fuzzy
+msgid "editors_th_sort_ascending"
+msgstr "Ascending sort"
+
+#: views/editors/queue.thtml:105 views/editors/queue.thtml:121
+#: views/editors/queue.thtml:140
+#, fuzzy
+msgid "editors_th_sort_descending"
+msgstr "Descending sort"
+
+#. %s is a number
+#: controllers/editors_controller.php:1036
+#, php-format
+msgid "editors_x_days"
+msgstr "%s يومًا"
+
+#. %s is a number
+#: controllers/editors_controller.php:1044
+#, php-format
+msgid "editors_x_hours"
+msgstr "%s ساعة"
+
+#. %s is a number
+#: controllers/editors_controller.php:1052
+#, php-format
+msgid "editors_x_minutes"
+msgstr "%s دقيقة"
+
+#: views/errors/error401.thtml:50 controllers/components/simple_acl.php:81
+#: controllers/components/simple_acl.php:82
+#: controllers/components/simple_acl.php:83 controllers/components/amo.php:607
+#: controllers/components/amo.php:608 controllers/components/amo.php:609
+#: controllers/reviews_controller.php:353
+#: controllers/reviews_controller.php:485
+#: controllers/collections_controller.php:438
+#: controllers/collections_controller.php:496
+#: controllers/collections_controller.php:504
+#: controllers/collections_controller.php:971
+#: controllers/collections_controller.php:1034
+#: controllers/collections_controller.php:1077
+msgid "error_access_denied"
+msgstr "الوصول ممنوع"
+
+#: views/errors/error401.thtml:52
+msgid "error_access_denied_message"
+msgstr "غير مسموح لك بمشاهدة هذه الصÙحة."
+
+#: controllers/collections_controller.php:1039
+#, fuzzy
+msgid "error_addon_exists"
+msgstr "Add-on already exists!"
+
+#: controllers/developers_controller.php:200
+#: controllers/developers_controller.php:593
+#: controllers/developers_controller.php:1016
+#: controllers/developers_controller.php:1429
+#: controllers/downloads_controller.php:95
+#: controllers/downloads_controller.php:102
+#: controllers/downloads_controller.php:164
+#: controllers/statistics_controller.php:135
+#: controllers/previews_controller.php:115
+#: controllers/previews_controller.php:206
+#: controllers/previews_controller.php:307
+#: controllers/reviews_controller.php:77
+#: controllers/reviews_controller.php:240
+#: controllers/reviews_controller.php:332
+#: controllers/reviews_controller.php:340 controllers/api_controller.php:123
+#: controllers/api_controller.php:759 controllers/addons_controller.php:131
+#: controllers/addons_controller.php:197
+#: controllers/addons_controller.php:1407
+#: controllers/addons_controller.php:1465
+#: controllers/addons_controller.php:1469
+#: controllers/addons_controller.php:1503
+#: controllers/editors_controller.php:265
+#: controllers/collections_controller.php:1041
+#: controllers/collections_controller.php:1074
+msgid "error_addon_notfound"
+msgstr "الإضاÙØ© غير موجودة!"
+
+#: controllers/files_controller.php:83 controllers/files_controller.php:196
+msgid "error_addon_notviewable"
+msgstr "لا يمكن مشاهدة هذه الإضاÙØ© هنا."
+
+#: controllers/reviews_controller.php:246
+msgid "error_addon_selfreview"
+msgstr "لا يمكنك أن تضع مراجعة لإضاÙتك الشخصية."
+
+#: controllers/addons_controller.php:970
+msgid "error_browse_no_addons"
+msgstr "لا يوجد إضاÙات ÙÙŠ هذا التصنيÙ!"
+
+#: controllers/api_controller.php:424
+msgid "error_collection_feed_notfound"
+msgstr "تلقيم الإضاÙØ© غير موجود"
+
+#: views/users/register.thtml:65 views/users/edit.thtml:194
+msgid "error_email_invalid"
+msgstr "هذا ليس بريدًا إلكترونيًا صالحًا."
+
+#: views/users/pwreset.thtml:74 views/users/register.thtml:70
+#: views/users/register.thtml:80 views/users/register.thtml:86
+#: views/users/edit.thtml:105 views/users/edit.thtml:111
+#: views/users/edit.thtml:192 views/admin/users_edit.thtml:78
+#: views/admin/users_edit.thtml:83 views/reviews/add.thtml:80
+#: views/reviews/add.thtml:104
+msgid "error_field_required"
+msgstr "يجب أن يكون هذا الحقل غير Ùارغ."
+
+#: controllers/files_controller.php:75 controllers/files_controller.php:93
+#: controllers/files_controller.php:96 controllers/files_controller.php:163
+#: controllers/files_controller.php:176 controllers/files_controller.php:185
+#: controllers/files_controller.php:204 controllers/editors_controller.php:412
+msgid "error_file_notfound"
+msgstr "المل٠غير موجود!"
+
+#. %s is a filename
+#: controllers/editors_controller.php:430
+#, php-format
+msgid "error_file_x_notfound"
+msgstr "خطا ÙÙŠ الملÙ: %s غير موجود."
+
+#: views/collections/add.thtml:55 views/collections/edit.thtml:89
+#: views/users/register.thtml:54 views/users/edit.thtml:81
+#: views/reviews/add.thtml:70 controllers/groups_controller.php:80
+#: controllers/groups_controller.php:102
+msgid "error_formerrors"
+msgstr "هناك أخطاء ÙÙŠ هذا النموذج. ÙŠÙرجى تصحيح الأخطاء ثم إعادة الإرسال."
+
+#: views/users/register.thtml:109
+msgid "error_invalid_captcha"
+msgstr "الكابتشا غير صالحة، ÙŠÙرجى المحاولة ثانية!"
+
+#: views/users/register.thtml:100 views/users/edit.thtml:125
+#: views/admin/users_edit.thtml:101
+msgid "error_invalid_url"
+msgstr ""
+"هذا العنوان غير صالح. العناوين الصالحة تكون على نسق http://example.com/"
+"my_page."
+
+#. %s is a string representing what's missing. Example: file_id
+#: controllers/downloads_controller.php:65
+#: controllers/users_controller.php:185 controllers/users_controller.php:264
+#: controllers/users_controller.php:559 controllers/users_controller.php:653
+#: controllers/reviews_controller.php:71
+#: controllers/reviews_controller.php:234
+#: controllers/reviews_controller.php:325
+#: controllers/reviews_controller.php:473
+#: controllers/reviews_controller.php:475
+#: controllers/addons_controller.php:182
+#: controllers/addons_controller.php:1381
+#: controllers/addons_controller.php:1455
+#: controllers/collections_controller.php:266
+#: controllers/collections_controller.php:285
+#: controllers/collections_controller.php:346
+#: controllers/collections_controller.php:443
+#: controllers/collections_controller.php:482
+#: controllers/collections_controller.php:936
+#: controllers/collections_controller.php:959
+#: controllers/collections_controller.php:960
+#: controllers/collections_controller.php:975
+#: controllers/collections_controller.php:977
+#: controllers/collections_controller.php:994
+#: controllers/collections_controller.php:1003
+#: controllers/collections_controller.php:1016
+#: controllers/collections_controller.php:1017
+#: controllers/collections_controller.php:1024
+#: controllers/collections_controller.php:1070
+#: controllers/collections_controller.php:1090
+#, php-format
+msgid "error_missing_argument"
+msgstr "المعامل ناقص: %s"
+
+#: controllers/components/amo.php:507 controllers/components/amo.php:532
+msgid "error_no_files_in_addon"
+msgstr "لا ملÙات"
+
+#: controllers/previews_controller.php:200
+msgid "error_preview_notfound"
+msgstr "المعاينة غير موجودة!"
+
+#: views/addons/display.thtml:400 views/reviews/add.thtml:98
+msgid "error_review_rating_required"
+msgstr "يجب عليك اختيار تقييم."
+
+#: controllers/users_controller.php:160
+msgid "error_user_already_confirmed"
+msgstr "حساب المستخدم هذا قد أكّÙد مسبقًا."
+
+#: controllers/users_controller.php:202 controllers/users_controller.php:276
+#: controllers/users_controller.php:569 controllers/users_controller.php:581
+#: controllers/users_controller.php:587 controllers/users_controller.php:610
+#: controllers/users_controller.php:627
+msgid "error_user_badconfirmationcode"
+msgstr "رمز التأكيد غير صحيح!"
+
+#: views/users/pwreset.thtml:79 views/users/register.thtml:75
+#: views/users/edit.thtml:183
+msgid "error_user_confirmpw_nomatch"
+msgstr "كلمات السر لا تتطابق."
+
+#: views/users/register.thtml:65 views/users/edit.thtml:190
+#: controllers/users_controller.php:617
+msgid "error_user_email_notunique"
+msgstr "هذا البريد الإلكتروني مأخوذ من Ù‚Ùبَل مستخدم آخر."
+
+#: controllers/users_controller.php:596
+msgid "error_user_emailchange_expired"
+msgstr ""
+"انتهت مهلة تغيير البريد الإلكتروني. ÙŠÙرجى تغيير البريد الإلكتروني مجددًا ÙÙŠ "
+"مل٠المستخدم الشخصي والنقر على الوصلة ÙÙŠ رسالة التأكيد حالما تستلمها."
+
+#: controllers/collections_controller.php:985
+#, fuzzy
+msgid "error_user_exists"
+msgstr ""
+"Users can only have one role at a time. Please remove the user from any "
+"existing roles before continuing."
+
+#: views/users/register.thtml:91 views/users/edit.thtml:116
+#: views/admin/users_edit.thtml:88
+msgid "error_user_nickname_notunique"
+msgstr "هذا الاسم المستعار مأخوذ مسبقًا."
+
+#: views/users/pwreset.thtml:54 controllers/users_controller.php:191
+#: controllers/users_controller.php:270 controllers/users_controller.php:603
+#: controllers/users_controller.php:659
+#: controllers/collections_controller.php:988
+#: controllers/collections_controller.php:998
+msgid "error_user_notfound"
+msgstr "المستخدم غير موجود!"
+
+#: views/users/activatefirst.thtml:47
+msgid "error_user_unconfirmed"
+msgstr ""
+"ÙŠÙرجى تأكيد حساب المستخدم أولًا من خلال الرمز الذي استلمته بالبريد الإلكتروني."
+
+#: views/users/login.thtml:67
+msgid "error_username_or_pw_wrong"
+msgstr "اسم المستخدم أو كلمة السر خطأ!"
+
+#: controllers/editors_controller.php:260
+msgid "error_version_notfound"
+msgstr "الإصدارة غير موجودة!"
+
+#: views/users/delete.thtml:125 views/users/edit.thtml:173
+msgid "error_wrong_password"
+msgstr "كلمة السر التي أدخلتها خطأ!"
+
+#: views/elements/amo2009/homepage_addon.thtml:122
+#: views/elements/feature.thtml:122
+msgid "feature_learnmore"
+msgstr "اعر٠المزيد"
+
+#. %1 is the add-on name
+#: views/elements/amo2009/homepage_addon.thtml:123
+#: views/elements/feature.thtml:123
+#, php-format
+msgid "feature_learnmore_about_addon"
+msgstr "اعر٠المزيد عن %1$s"
+
+#. %1$s is a number
+#: views/elements/amo2009/reviews.thtml:52
+#: views/elements/addon_listitem.thtml:112 views/elements/feature.thtml:99
+#: views/addons/browse_thumbs.thtml:86
+#, php-format
+msgid "feature_reviews"
+msgid_plural "feature_reviews"
+msgstr[0] "لا مراجعات"
+msgstr[1] "مراجعة واحدة"
+msgstr[2] "مراجعتان"
+msgstr[3] "%1$s مراجعات"
+msgstr[4] "%1$s مراجعة"
+msgstr[5] "%1$s مراجعة"
+
+#: views/elements/amo2009/homepage_addon.thtml:127
+#: views/elements/feature.thtml:127
+msgid "feature_view_more_from_category"
+msgstr "شاهد المزيد من"
+
+#. This appears on a page that views the source of an add-on. This link will return
+#. the user to the add-on's main page
+#: views/files/browse.thtml:65
+msgid "file_browser_link_addon"
+msgstr "عودة إلى الإضاÙØ©"
+
+#. There is a list of directories and files on the page. Clicking this will show the
+#. contents of all the directories (normally you would click on each one to see the
+#. contents)
+#: views/files/browse.thtml:67
+msgid "file_browser_link_expand_all"
+msgstr "وسّع الكل"
+
+#. This appears on a page that views the source of an add-on. This link will return
+#. the user to the add-on's review page (it only appears if the add-on is being
+#. reviewed)
+#: views/files/browse.thtml:64
+msgid "file_browser_link_review"
+msgstr "عودة إلى المراجعة"
+
+#. The title of the page for viewing an add-on's source.
+#. %1$s is the name of the add-on
+#. %2$s is the name of the current application (e.g. Firefox or Thunderbird)
+#: views/files/browse.thtml:46
+msgid "file_browser_title"
+msgstr "%1$s :: مستعرض الملÙات :: إضاÙات %2$s"
+
+#. This appears on a page that views the source of an add-on. There is a list of
+#. directories and files on the page. Clicking this link will toggle between an
+#. expanded or a collapsed list. This string should be kept short.
+#: views/files/browse.thtml:68
+msgid "file_browser_toggle_expand_collapse"
+msgstr "+/-"
+
+#. Link text for the AMO About page.
+#: views/elements/footer.thtml:72 views/layouts/amo2009.thtml:341
+#, fuzzy
+msgid "footer_a_about"
+msgstr "About"
+
+#. Link text to the AMO blog.
+#: views/elements/footer.thtml:74 views/layouts/amo2009.thtml:343
+#, fuzzy
+msgid "footer_a_blog"
+msgstr "Blog"
+
+#. Link text to the Frequently Asked Questions page.
+#: views/elements/footer.thtml:73 views/layouts/amo2009.thtml:342
+#, fuzzy
+msgid "footer_a_faq"
+msgstr "FAQ"
+
+#. Full text for the FAQ abbreviation.
+#: views/elements/footer.thtml:73 views/pages/collector_features.thtml:72
+#: views/layouts/amo2009.thtml:342
+#, fuzzy
+msgid "footer_abbr_faq"
+msgstr "Frequently Asked Questions"
+
+#: views/elements/footer.thtml:67 views/layouts/amo2009.thtml:336
+msgid "footer_all_rights_reserved"
+msgstr "جميع الحقوق محÙوظة."
+
+#: views/elements/footer.thtml:67 views/layouts/amo2009.thtml:336
+msgid "footer_copyright"
+msgstr "حقوق النسخ"
+
+#: views/elements/footer.thtml:71 views/layouts/amo2009.thtml:340
+msgid "footer_credits"
+msgstr "المساهمون"
+
+#: views/elements/footer.thtml:76 views/layouts/amo2009.thtml:346
+msgid "footer_disclaimer"
+msgstr ""
+"تزوّد موزيلا وصلات لهذه التطبيقات من باب المجاملة، ولكنها لا تقدّم أيّ تعريÙات "
+"بهذه التطبيقات ولا معلومات متعلقة بها. يجب توجيه أي أسئلة أو شكاوى أو "
+"احتجاجات بخصوص هذه التطبيقات إلى بائع البرنامج."
+
+#: views/elements/footer.thtml:61 views/layouts/amo2009.thtml:332
+msgid "footer_lang_form_lang_submit_go"
+msgstr "اذهب"
+
+#: views/elements/footer.thtml:70 views/layouts/amo2009.thtml:339
+msgid "footer_legal_notices"
+msgstr "ملاحظات قانونية"
+
+#: views/elements/footer.thtml:50 views/layouts/amo2009.thtml:321
+msgid "footer_other_languages"
+msgstr "لغات أخرى:"
+
+#: views/elements/footer.thtml:69 views/layouts/amo2009.thtml:338
+msgid "footer_privacy_policy"
+msgstr "سياسة الخصوصية"
+
+#: models/addontype.php:79
+msgid "general_addontype_dict"
+msgstr "قاموس"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:100
+msgid "general_addontype_dict_plural"
+msgstr "قواميس"
+
+#: models/addontype.php:75
+msgid "general_addontype_extension"
+msgstr "امتداد"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:98
+msgid "general_addontype_extension_plural"
+msgstr "امتدادات"
+
+#: models/addontype.php:85
+msgid "general_addontype_lpaddon"
+msgstr "حزمة لغة (إضاÙØ©)"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:103
+msgid "general_addontype_lpaddon_plural"
+msgstr "حزمات لغات (إضاÙØ©)"
+
+#: models/addontype.php:83
+msgid "general_addontype_lpapp"
+msgstr "حزمة لغة (تطبيق)"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:102
+msgid "general_addontype_lpapp_plural"
+msgstr "حزمات لغات (تطبيق)"
+
+#: models/addontype.php:87
+msgid "general_addontype_plugin"
+msgstr "ملحق"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:104
+msgid "general_addontype_plugin_plural"
+msgstr "ملحقات"
+
+#: models/addontype.php:81
+msgid "general_addontype_search"
+msgstr "محرك بحث"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:101
+msgid "general_addontype_search_plural"
+msgstr "محركات بحث"
+
+#: models/addontype.php:77
+msgid "general_addontype_theme"
+msgstr "سمة"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:99
+msgid "general_addontype_theme_plural"
+msgstr "سمات"
+
+#: config/language.php:367
+#, fuzzy
+msgid "general_languages_all_locales"
+msgstr "All Locales"
+
+#: views/layouts/amo2009.thtml:249
+#, fuzzy
+msgid "header_brand_name"
+msgstr "Mozilla"
+
+#. %1$s is the application name. Example: Firefox
+#: views/elements/header.thtml:111 views/elements/header.thtml:122
+#: views/layouts/amo2009.thtml:248
+#, php-format
+msgid "header_home_tooltip"
+msgstr "عÙد إلى صÙحة بداية إضاÙات %1$s"
+
+#: views/elements/header.thtml:87
+msgid "header_main_firefox_header"
+msgstr "إضاÙات ÙَيَرÙÙكس"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:218
+#, fuzzy
+msgid "header_main_firefox_header_with_logo"
+msgstr ""
+"Add-ons <em>for</em> <img alt=\"Firefox\" src=\"%1$s\" /> <strong>Firefox</"
+"strong>"
+
+#: views/elements/header.thtml:99
+msgid "header_main_header"
+msgstr "الإضاÙات"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:242
+#, fuzzy
+msgid "header_main_header_with_logo"
+msgstr "Add-ons <img alt=\"Add-ons\" src=\"%1$s\" />"
+
+#: views/elements/header.thtml:90
+msgid "header_main_seamonkey_header"
+msgstr "إضاÙات سÙيمَنكي"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:224
+#, fuzzy
+msgid "header_main_seamonkey_header_with_logo"
+msgstr ""
+"Add-ons <em>for</em> <img alt=\"seamonkey\" src=\"%1$s\" /> "
+"<strong>SeaMonkey</strong>"
+
+#: views/elements/header.thtml:93
+msgid "header_main_sunbird_header"
+msgstr "إضاÙات صَنبÙرد"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:230
+#, fuzzy
+msgid "header_main_sunbird_header_with_logo"
+msgstr ""
+"Add-ons <em>for</em> <img alt=\"sunbird\" src=\"%1$s\" /> <strong>Sunbird</"
+"strong>"
+
+#: views/elements/header.thtml:96
+msgid "header_main_thunderbird_header"
+msgstr "إضاÙات ثندÙربÙرد"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:236
+#, fuzzy
+msgid "header_main_thunderbird_header_with_logo"
+msgstr ""
+"Add-ons <em>for</em> <img alt=\"thunderbird\" src=\"%1$s\" /> "
+"<strong>Thunderbird</strong>"
+
+#: views/layouts/amo2009.thtml:205
+#, fuzzy
+msgid "header_navaccess_applications_menu"
+msgstr "Skip to other applications menu"
+
+#: views/layouts/amo2009.thtml:204
+#, fuzzy
+msgid "header_navaccess_categories_menu"
+msgstr "Skip to categories menu"
+
+#: views/layouts/amo2009.thtml:202
+#, fuzzy
+msgid "header_navaccess_main_content"
+msgstr "Skip to main content"
+
+#: views/layouts/amo2009.thtml:203
+#, fuzzy
+msgid "header_navaccess_search_form"
+msgstr "Skip to search form"
+
+#: views/elements/header.thtml:62
+msgid "header_navlink_addons"
+msgstr "الإضاÙات"
+
+#: views/elements/developers/sidebar.thtml:72
+#: views/elements/developers/myaddons.thtml:50 views/elements/header.thtml:159
+#: views/addons/display.thtml:378
+msgid "header_navlink_login"
+msgstr "دخول"
+
+#: views/elements/header.thtml:156 views/layouts/amo2009.thtml:304
+msgid "header_navlink_logout"
+msgstr "خروج"
+
+#: views/elements/header.thtml:145 views/layouts/amo2009.thtml:303
+msgid "header_navlink_myaccount"
+msgstr "حسابي"
+
+#: views/elements/header.thtml:158
+msgid "header_navlink_register"
+msgstr "تسجيل"
+
+#. %1 is the URL to the registration page
+#. %2 is the URL to the login page
+#: views/layouts/amo2009.thtml:278
+#, fuzzy
+msgid "header_navlink_register_or_login"
+msgstr "<a href=\"%1$s\">Register</a> or <a href=\"%2$s\">Log in</a>"
+
+#: views/layouts/amo2009.thtml:285
+#, fuzzy
+msgid "header_navlink_tools"
+msgstr "Tools"
+
+#. %s is the add-on name
+#: views/elements/collections_interactive_addon.thtml:62
+#: views/elements/amo2009/homepage_addon.thtml:77
+#: views/elements/addon_discussionheader.thtml:62
+#: views/elements/addon_listitem.thtml:67 views/elements/feature.thtml:84
+#: views/addons/category_landing.thtml:87 views/addons/browse_thumbs.thtml:60
+#, php-format
+msgid "img_preview_of"
+msgstr "صورة معاينة ل†%s"
+
+#. %1 is the login URL for the link tag
+#. %2 is the link to an explanatory page.
+#: views/elements/amo2009/install.thtml:307 views/elements/install.thtml:255
+msgid "install_a_login_to_install"
+msgstr ""
+"<a href=\"%1$s\">سجّل دخولك</a> لتثبيت هذه الإضاÙØ© التجريبية. <a href=\"%2$s"
+"\">لماذا</a>؟"
+
+#. %1 is the URL for the Experimental Add-ons section of the FAQ page
+#: views/elements/amo2009/install.thtml:283 views/elements/install.thtml:232
+#, fuzzy
+msgid "install_button_confirm_exp_install"
+msgstr ""
+"Let me install this experimental add-on. <a href=\"%1$s\">What's this?</a>"
+
+#. %1$s is the application name. Example: Firefox
+#. %2$s is an optional string used to specify a platform. Example: (Windows)
+#: views/elements/amo2009/install.thtml:128 views/elements/install.thtml:75
+#, php-format
+msgid "install_button_text"
+msgstr "أضÙ٠إلى %s %s"
+
+#. %1 is the add-on name, %2 is the app name
+#: views/elements/amo2009/install.thtml:191
+#: views/elements/amo2009/install.thtml:206
+#: views/elements/amo2009/install.thtml:249
+#: views/elements/amo2009/install.thtml:298 views/elements/install.thtml:150
+#: views/elements/install.thtml:165 views/elements/install.thtml:202
+#: views/elements/install.thtml:246
+#, php-format
+msgid "install_button_title"
+msgstr "أضÙÙ %1$s إلى %2$s"
+
+#. %1$s is the add-on name
+#: views/elements/amo2009/install.thtml:200 views/elements/install.thtml:159
+#, php-format
+msgid "install_download"
+msgstr "نزّÙÙ„ %1$s"
+
+#: views/elements/amo2009/install.thtml:147 views/elements/install.thtml:94
+msgid "install_error_addon_not_found"
+msgstr "هذه الإضاÙØ© غير متاحة."
+
+#: views/addons/dictionaries.thtml:65
+msgid "langtools_a11y_tablesummary"
+msgstr "قائمة من حزمات اللغات والقواميس."
+
+#: views/addons/dictionaries.thtml:47
+msgid "langtools_download_dictionary"
+msgstr "نزّل القاموس"
+
+#: views/addons/dictionaries.thtml:48
+msgid "langtools_download_langpack"
+msgstr "نزّل حزمة اللغة"
+
+#: views/addons/dictionaries.thtml:63 controllers/components/amo.php:685
+#: controllers/addons_controller.php:1239
+msgid "langtools_header_dicts_and_langpacks"
+msgstr "القواميس وحزمات اللغات"
+
+#: views/addons/dictionaries.thtml:44
+msgid "langtools_install_dictionary"
+msgstr "ثبّت القاموس"
+
+#: views/addons/dictionaries.thtml:45
+msgid "langtools_install_langpack"
+msgstr "ثبّت حزمة اللغة"
+
+#: views/addons/dictionaries.thtml:69
+msgid "langtools_tableheader_dictionary"
+msgstr "القاموس"
+
+#: views/addons/dictionaries.thtml:70
+msgid "langtools_tableheader_langpack"
+msgstr "حزمة اللغة"
+
+#: views/addons/dictionaries.thtml:68
+msgid "langtools_tableheader_language"
+msgstr "اللغة"
+
+#: models/license.php:65
+#, fuzzy
+msgid "license_custom"
+msgstr "Custom License"
+
+#: config/bootstrap.php:303
+#, fuzzy
+msgid "licenses_bsd"
+msgstr "BSD License"
+
+#: config/bootstrap.php:298
+#, fuzzy
+msgid "licenses_gpl_2.0"
+msgstr "GNU General Public License, version 2.0"
+
+#: config/bootstrap.php:299
+#, fuzzy
+msgid "licenses_gpl_3.0"
+msgstr "GNU General Public License, version 3.0"
+
+#: config/bootstrap.php:300
+#, fuzzy
+msgid "licenses_lgpl_2.1"
+msgstr "GNU Lesser General Public License, version 2.1"
+
+#: config/bootstrap.php:301
+#, fuzzy
+msgid "licenses_lgpl_3.0"
+msgstr "GNU Lesser General Public License, version 3.0"
+
+#: config/bootstrap.php:302
+#, fuzzy
+msgid "licenses_mit"
+msgstr "MIT/X11 License"
+
+#: config/bootstrap.php:297
+#, fuzzy
+msgid "licenses_mpl_1.1"
+msgstr "Mozilla Public License, version 1.1"
+
+#: views/users/emailchange.thtml:51 views/users/delete.thtml:55
+#: views/users/delete.thtml:137 views/users/edit.thtml:74
+#: views/reviews/flag.thtml:54
+msgid "link_return_to_front_page"
+msgstr "انقر هنا للعودة إلى صÙحة الواجهة."
+
+#: views/elements/amo2009/addon_list_options.thtml:46
+#: views/elements/addon_list_options.thtml:46
+msgid "list_sortby_date"
+msgstr "التاريخ"
+
+#: views/elements/amo2009/addon_list_options.thtml:47
+#: views/elements/addon_list_options.thtml:47
+msgid "list_sortby_downloads"
+msgstr "التنزيلات"
+
+#: views/elements/amo2009/addon_list_options.thtml:45
+#: views/elements/addon_list_options.thtml:45
+msgid "list_sortby_name"
+msgstr "اسم الإضاÙØ©"
+
+#: views/elements/amo2009/addon_list_options.thtml:48
+#: views/elements/addon_list_options.thtml:48
+msgid "list_sortby_rating"
+msgstr "التقييم"
+
+#: config/bootstrap.php:278
+msgid "main_prettyname_fennec"
+msgstr "ÙÙنّÙÙƒ"
+
+#: config/bootstrap.php:274
+msgid "main_prettyname_firefox"
+msgstr "ÙَيَرÙÙكس"
+
+#: config/bootstrap.php:277
+msgid "main_prettyname_seamonkey"
+msgstr "سÙيمانكي"
+
+#: config/bootstrap.php:276
+msgid "main_prettyname_sunbird"
+msgstr "صَنْبÙرد"
+
+#: config/bootstrap.php:275
+msgid "main_prettyname_thunderbird"
+msgstr "ثندرÙبÙرد"
+
+#: views/elements/addon_categories.thtml:52
+msgid "nav_category_dicts_langpacks"
+msgstr "القواميس وحزمات اللغات"
+
+#: views/elements/addon_categories.thtml:55
+msgid "nav_category_themes"
+msgstr "السمات"
+
+#: views/elements/app_chooser.thtml:47 views/layouts/amo2009.thtml:255
+msgid "other_apps_tooltip"
+msgstr "ابحث عن إضاÙات لتطبيقات أخرى"
+
+#. In a user list: user 1, user 2, "others"
+#: views/helpers/addons_html.php:222
+msgid "other_users"
+msgstr "أخرى"
+
+#: controllers/pages_controller.php:90
+msgid "page_title_appversions"
+msgstr "إصدارات التطبيقات"
+
+#: controllers/pages_controller.php:115
+#, fuzzy
+msgid "page_title_collector"
+msgstr "Add-on Collector"
+
+#: controllers/pages_controller.php:117
+#, fuzzy
+msgid "page_title_collector_faq"
+msgstr "Add-on Collector FAQ"
+
+#: controllers/pages_controller.php:119
+#, fuzzy
+msgid "page_title_collector_features"
+msgstr "Add-on Collector Features"
+
+#: controllers/pages_controller.php:122
+#, fuzzy
+msgid "page_title_collector_firstrun"
+msgstr "Welcome to the Add-on Collector"
+
+#: controllers/pages_controller.php:92
+msgid "page_title_credits"
+msgstr "المساهمون"
+
+#: controllers/pages_controller.php:113
+#, fuzzy
+msgid "page_title_developer_faq"
+msgstr "Developer FAQ"
+
+#: controllers/pages_controller.php:111
+msgid "page_title_faq"
+msgstr "الأسئلة الأكثر تكرارًا"
+
+#: controllers/pages_controller.php:94
+msgid "page_title_fashionyourfirefox_faq"
+msgstr "الأسئلة الأكثر شيوعًا عن جعل ÙَيَرÙÙكس عصريًا"
+
+#: controllers/pages_controller.php:101
+msgid "page_title_policy"
+msgstr "سياسة الإضاÙات"
+
+#: controllers/pages_controller.php:103
+msgid "page_title_privacy"
+msgstr "سياسة خصوصية موزيلا"
+
+#: controllers/pages_controller.php:105
+msgid "page_title_review_guide"
+msgstr "إرشادات المراجعات"
+
+#: controllers/pages_controller.php:107
+msgid "page_title_sandbox"
+msgstr "نظام مراجعات ساحة اللعب"
+
+#: controllers/pages_controller.php:109
+msgid "page_title_submissionhelp"
+msgstr "مساعدة الإرسال"
+
+#: views/pages/appversions.thtml:87
+msgid "pages_appversions_guid"
+msgstr "المعرّ٠الÙريد"
+
+#: views/pages/appversions.thtml:79 controllers/pages_controller.php:90
+msgid "pages_appversions_header"
+msgstr "إصدارات التطبيقات الصالحة"
+
+#: views/pages/appversions.thtml:80
+msgid "pages_appversions_intro"
+msgstr ""
+"يجب أن تحتوي الإضاÙات المرسَلة إلى موزيلا على مل٠install.rdf يحوي على الأقل "
+"تطبيقًا واحدًا مدعومًا من التطبيقات أدناه. الإصدارات المسرودة أدناه Ùقط هي "
+"المسموح بها لهذه التطبيقات."
+
+#. %s is a full <a> tag
+#: views/pages/appversions.thtml:93
+#, php-format
+msgid "pages_appversions_required_files"
+msgstr ""
+"إن كان تطبيقك المدعوم لا يحتاج مل٠install.rdfØŒ Ùما زال عليك أن تضمّن واحدًا "
+"Ùيه الخصائص المطلوبة كما هو موضح %s."
+
+#. this is the text inside of an <a> tag for pages_appversions_required_files. This
+#. should be fixed.
+#: views/pages/appversions.thtml:93
+msgid "pages_appversions_required_files_link"
+msgstr "هنا"
+
+#: views/pages/appversions.thtml:88
+msgid "pages_appversions_versions"
+msgstr "الإصدارات"
+
+#: views/pages/policy.thtml:51
+msgid "pages_policy_sandbox_link"
+msgstr "صÙحة معلومات ساحة اللعب"
+
+#: views/elements/pagination.thtml:53
+msgid "pagination_next_page"
+msgstr "تالي"
+
+#: views/elements/pagination.thtml:52
+msgid "pagination_previous_page"
+msgstr "سابق"
+
+#: views/elements/recaptcha.thtml:65
+msgid "recaptcha_enter_both_words"
+msgstr ""
+"أدخÙÙ„ رجاءً <strong>كلتا الكلمتين</strong>أدناه، <strong>واÙصل بينهما بÙراغ</"
+"strong>."
+
+#: views/elements/recaptcha.thtml:83
+msgid "recaptcha_enter_here"
+msgstr "أدخÙÙ„ إجابتك هنا:"
+
+#: views/elements/recaptcha.thtml:74
+msgid "recaptcha_enter_whatyouhear"
+msgstr "اكتب رجاءً ما تسمعه."
+
+#. %1 is the link switching refreshing the captcha
+#. %2 is the link switching to a text captcha
+#: views/elements/recaptcha.thtml:77
+msgid "recaptcha_hardtohear_text"
+msgstr ""
+"إن كان صعبًا عليك أن تÙهمها، يمكنك <a href=\"%1$s\">الاستماع إلى شيء آخر</a> "
+"أو <a href=\"%2$s\">العودة إلى النص</a>."
+
+#. %1 is the link switching refreshing the captcha
+#. %2 is the link switching to an audio captcha
+#: views/elements/recaptcha.thtml:68
+msgid "recaptcha_hardtoread_text"
+msgstr ""
+"إن كان صعبًا عليك قراءتها، يمكنك <a href=\"%1$s\">تجربة كلمات مختلÙØ©</a> أو "
+"<a href=\"%2$s\">الاستماع إلى شيء ما</a> عوضًا عن ذلك."
+
+#: views/users/register.thtml:105
+msgid "recaptcha_label"
+msgstr "هل أنت إنسان؟"
+
+#: views/users/register.thtml:106
+msgid "recaptcha_whatsthis"
+msgstr "ما هذا؟"
+
+#: controllers/reviews_controller.php:559
+msgid "review_flag_error"
+msgstr "حصل خطأ عند تعليم هذه المراجعة!"
+
+#: models/reviews_moderation_flag.php:69
+msgid "review_flag_reason_bug_support"
+msgstr "التبليغ عن العلة أو طلب الدعم موضوع ÙÙŠ غير مكانه"
+
+#: views/reviews/display.thtml:103 views/reviews/display.thtml:186
+msgid "review_flag_reason_instructions"
+msgstr "بلّغ عن هذه المراجعة (اختر سببًا)"
+
+#: models/reviews_moderation_flag.php:67
+msgid "review_flag_reason_language"
+msgstr "اللغة/الحوار غير ملائم"
+
+#: models/reviews_moderation_flag.php:71
+msgid "review_flag_reason_other"
+msgstr "سبب آخر (ÙŠÙرجى التحديد)"
+
+#: models/reviews_moderation_flag.php:65
+msgid "review_flag_reason_spam"
+msgstr "سÙخام أو محتوى غير متعلق بالمراجعات"
+
+#: views/reviews/display.thtml:91 views/reviews/display.thtml:175
+#: controllers/reviews_controller.php:555
+msgid "review_flag_success"
+msgstr "شكرًا؛ لقد عÙلّمتْ هذه المراجعة انتظارًا لمواÙقة المحرّر."
+
+#: views/reviews/display.thtml:41
+msgid "review_flag_this"
+msgstr "بلّغ عن هذه المراجعة"
+
+#: views/reviews/display.thtml:42
+msgid "review_flag_this_titletip"
+msgstr ""
+"هل هذه المراجعة غير ملائمة أو غير دقيقة أو سÙخام؟ انقر هنا لتعليمها لكي "
+"يراجعها المحرّر."
+
+#. %1 is the URL of the support section, %2 for the review guidelines
+#: views/reviews/add.thtml:53
+msgid "review_guidelines_short"
+msgstr ""
+"<p>أبق٠هذه التلميحات ÙÙŠ ذهنك:</p><ul><li>اكتب وكأنك تخبر صديقًا عن تجربتك "
+"للإضاÙØ©. أعط٠تÙاصيل محددة ومÙيدة، كالميزات التي أعجبتك أو لم تعجبك، وكم هو "
+"سهل استخدامها، وما هي السيئات التي Ùيها. تجنّب الألÙاظ العامة مثل \"رائعة\" "
+"و \"سيئة\" إلا إن كان بإمكانك إعطاء سبب لاعتقادك هذا.</li><li>رجاءً لا تنشر "
+"بلاغات العلل ÙÙŠ المراجعات. نحن لا نطلع مطوّري الإضاÙات على بريدك الإلكتروني، "
+"وهم قد يحتاجون التواصل معك لمساعدتك على حل مشكلتك. راجع <a href=\"%1$s\">Ù‚Ùسم "
+"الدعم</a> لمعرÙØ© أين يمكنك الحصول على مساعدة ÙÙŠ هذه الإضاÙØ©.</li><li>رجاءً "
+"حاÙظ على الأدب ÙÙŠ المراجعات، وتجنّب الألÙاظ النابية، ولا تنشر أي معلومات "
+"شخصية.</li></ul><p>اقرأ رجاءً <a href=\"%2$s\">إرشادات المراجعات</a> لمزيد من "
+"التÙاصيل عن مراجعات المستخدم للإضاÙات.</p>"
+
+#. %1 is the add-on name
+#: views/reviews/flag.thtml:56 views/reviews/display.thtml:55
+#: views/reviews/review_added.thtml:50
+#, php-format
+msgid "reviews_header"
+msgstr "مراجعات ل†%s"
+
+#: controllers/addons_controller.php:435
+msgid "rss_featuredaddons"
+msgstr "الإضاÙات المميزة"
+
+#: controllers/addons_controller.php:432
+msgid "rss_newestaddons"
+msgstr "الإضاÙات الأحدث"
+
+#: controllers/addons_controller.php:434
+#, fuzzy
+msgid "rss_popularaddons"
+msgstr "Popular Add-ons"
+
+#: controllers/addons_controller.php:433
+msgid "rss_updatedaddons"
+msgstr "الإضاÙات المحدّثة"
+
+#: views/elements/search_mini.thtml:70
+#, fuzzy
+msgid "search"
+msgstr "Search"
+
+#: views/search/collections.thtml:51
+#, fuzzy
+msgid "search_collections_header"
+msgstr "Collection Search Results"
+
+#: controllers/search_controller.php:297
+#, fuzzy
+msgid "search_collections_pagetitle"
+msgstr "Collection Search Results"
+
+#: controllers/search_controller.php:99
+msgid "search_disabled"
+msgstr "البحث معطل حاليًا، ÙŠÙرجى إعادة المحاولة لاحقًا."
+
+#: views/elements/amo2009/search.thtml:188 views/elements/search.thtml:187
+#: views/elements/search_mini.thtml:54
+msgid "search_form_all_addons"
+msgstr "كل الإضاÙات"
+
+#. This string is in the main category dropdown when searching
+#: views/elements/amo2009/search.thtml:204
+#, fuzzy
+msgid "search_form_all_collections"
+msgstr "all collections"
+
+#: views/elements/amo2009/search.thtml:184
+#: views/elements/amo2009/search.thtml:385
+#: views/elements/amo2009/search.thtml:408 views/elements/search.thtml:171
+#: views/elements/search.thtml:183 views/elements/search_mini.thtml:43
+#: views/elements/search_mini.thtml:49 views/layouts/mozilla.thtml:188
+msgid "search_form_default_text"
+msgstr "ابحث عن الإضاÙات"
+
+#: views/elements/amo2009/search.thtml:184
+#: views/elements/amo2009/search.thtml:404
+#, fuzzy
+msgid "search_form_default_text_collections"
+msgstr "search for collections"
+
+#: views/elements/amo2009/search.thtml:206 views/elements/search.thtml:202
+msgid "search_form_submit_tooltip"
+msgstr "ابحث عن الإضاÙات"
+
+#: views/elements/amo2009/search.thtml:184 views/elements/search.thtml:183
+#: views/elements/search_mini.thtml:49
+msgid "search_form_tooltip"
+msgstr "انقر لإدخال كلمات البحث"
+
+#: views/elements/amo2009/search.thtml:186 views/elements/search.thtml:185
+#: views/elements/search_mini.thtml:52
+msgid "search_form_within"
+msgstr "ضمن"
+
+#: views/addons/searchengines.thtml:118
+msgid "search_landing_all_search_engines"
+msgstr "كل محركات البحث"
+
+#: views/addons/searchengines.thtml:114
+msgid "search_landing_browse_search_engines"
+msgstr "استعرض محركات البحث"
+
+#: views/search/collections.thtml:58 views/search/index.thtml:59
+msgid "search_nothing_found"
+msgstr "لا نتائج."
+
+#: controllers/search_controller.php:185
+msgid "search_pagetitle"
+msgstr "بحث عن الإضاÙات"
+
+#: controllers/search_controller.php:242
+msgid "search_rss_description"
+msgstr "تلقيم نتائج البحث"
+
+#. %s is the terms the user is searching for (a string)
+#: controllers/search_controller.php:241
+#, php-format
+msgid "search_rss_results_for"
+msgstr "نتائج البحث Ù„â€: %s"
+
+#: views/elements/header.thtml:154 views/layouts/amo2009.thtml:296
+msgid "sidebar_navlink_admin_tools"
+msgstr "أدوات المدير"
+
+#: views/elements/header.thtml:146 views/layouts/amo2009.thtml:288
+msgid "sidebar_navlink_developer_tools"
+msgstr "أدوات المطوّر"
+
+#: views/elements/header.thtml:148 views/layouts/amo2009.thtml:290
+msgid "sidebar_navlink_editor_tools"
+msgstr "أدوات المحرّر"
+
+#: views/layouts/amo2009.thtml:302
+msgid "sidebar_navlink_welcome"
+msgstr "أهلًا وسهلًا"
+
+#. %s is the user's name
+#: views/layouts/amo2009.thtml:302
+#, php-format
+msgid "sidebar_navlink_welcome_name"
+msgstr "أهلًا بك، %s"
+
+#: views/elements/pitch.thtml:50 views/elements/pitch.thtml:55
+msgid "sidebar_pitch_dictionary"
+msgstr "القاموس"
+
+#: views/elements/pitch.thtml:72
+msgid "sidebar_pitch_featured_addons"
+msgstr "الإضاÙات المميزة"
+
+#: views/elements/pitch.thtml:61
+msgid "sidebar_pitch_looking_for"
+msgstr "أنا أبحث عن:"
+
+#: views/elements/pitch.thtml:70
+msgid "sidebar_pitch_newest_addons"
+msgstr "الإضاÙات الأحدث"
+
+#: views/elements/pitch.thtml:49
+msgid "sidebar_pitch_search"
+msgstr "ابحث عن ملحق"
+
+#: views/elements/pitch.thtml:69
+msgid "sidebar_pitch_subscribe_to"
+msgstr "اشترك ÙÙŠ"
+
+#: views/elements/pitch.thtml:48 views/elements/pitch.thtml:54
+msgid "sidebar_pitch_theme"
+msgstr "السمة"
+
+#: views/elements/pitch.thtml:71
+msgid "sidebar_pitch_updated_addons"
+msgstr "الإضاÙات المحدّثة"
+
+#. %1$s is a number
+#: views/helpers/localization.php:65 views/developers/versions_edit.thtml:95
+#: views/addons/dictionaries.thtml:92
+#, php-format
+msgid "size_kb"
+msgstr "%1$s ك.بايت"
+
+#: views/elements/amo2009/stars.thtml:57 views/elements/stars.thtml:63
+msgid "stars_not_yet_rated"
+msgstr "بلا تقييم حتى الآن"
+
+#. %1 is the number of stars this add-on has
+#: views/elements/amo2009/stars.thtml:49 views/elements/stars.thtml:54
+#, php-format
+msgid "stars_rated_x_outof_5"
+msgstr "تقييمه %s من أصل 5 نجوم"
+
+#: views/statistics/addon.thtml:59
+msgid "statistics_addon_dashboard_link"
+msgstr "لوحة القيادة"
+
+#: views/statistics/addon.thtml:58
+msgid "statistics_addon_developertools_link"
+msgstr "أدوات المطوّر"
+
+#: views/statistics/addon.thtml:53
+msgid "statistics_addon_switch"
+msgstr "بدّل الإضاÙØ©"
+
+#. This is a date format.
+#. http://php.net/strftime
+#: views/statistics/rss/summary.thtml:54 views/statistics/addon.thtml:181
+msgid "statistics_date_shortmonth"
+msgstr "%e %b"
+
+#. This is a date format.
+#. http://php.net/strftime
+#: views/statistics/rss/summary.thtml:40 views/statistics/addon.thtml:152
+msgid "statistics_date_shortmonthwithyear"
+msgstr "%e %b، %Y"
+
+#. This is a date format.
+#. http://php.net/strftime
+#: views/statistics/rss/summary.thtml:41 views/statistics/rss/summary.thtml:48
+#: views/statistics/addon.thtml:161 views/statistics/addon.thtml:172
+msgid "statistics_date_weekdayshortmonth"
+msgstr "%A %e %b"
+
+#. %1$s is an add-on name and version. Example: Add-on 3.5
+#: controllers/components/stats.php:519
+#, php-format
+msgid "statistics_events_addon_created"
+msgstr "أنشÙئت %1$s"
+
+#. %1$s is an application name and version. Example: Firefox 3.5
+#: controllers/components/stats.php:500
+#, php-format
+msgid "statistics_events_app_released"
+msgstr "أصدÙر %1$s"
+
+#: views/statistics/addon.thtml:71
+msgid "statistics_help_close_link"
+msgstr "أغلÙÙ‚"
+
+#: views/statistics/addon.thtml:60
+msgid "statistics_help_link"
+msgstr "مساعدة"
+
+#: views/statistics/index.thtml:83
+msgid "statistics_index_anotheraddon"
+msgstr "أو اختر إضاÙØ© أخرى"
+
+#: views/statistics/index.thtml:85
+msgid "statistics_index_anotheraddon_public"
+msgstr "أو اختر إضاÙØ© لها إحصائيات عامة"
+
+#: views/statistics/index.thtml:71
+msgid "statistics_index_myaddons"
+msgstr ""
+"اختر واحدة من إضاÙاتك لعرض إحصائياتهاSelect one of your add-ons to view its "
+"statistics"
+
+#: views/statistics/index.thtml:89
+msgid "statistics_index_selectaddon"
+msgstr "اختر إضاÙØ© لعرض إحصائياتها"
+
+#: views/statistics/index.thtml:91
+msgid "statistics_index_selectaddon_public"
+msgstr "اختر إضاÙØ© لها إحصائيات عامة"
+
+#: views/statistics/index.thtml:39
+msgid "statistics_index_title"
+msgstr "لوحة الإحصائيات"
+
+#: views/statistics/index.thtml:97
+msgid "statistics_index_view_button"
+msgstr "اعرض الإحصائيات"
+
+#: views/statistics/addon.thtml:222 controllers/statistics_controller.php:247
+msgid "statistics_js_download_csv"
+msgstr "اعرض هذا الجدول ÙÙŠ تنسيق CSV"
+
+#: controllers/statistics_controller.php:246
+msgid "statistics_js_dropdowns_none"
+msgstr "لا شيء"
+
+#: controllers/statistics_controller.php:245
+msgid "statistics_js_dropdowns_removeplot"
+msgstr "أزÙÙ„ هذا المخطّط"
+
+#: controllers/statistics_controller.php:248
+msgid "statistics_js_groupby_selector_date"
+msgstr "تجميع حسب: اليوم"
+
+#: controllers/statistics_controller.php:251
+msgid "statistics_js_groupby_selector_month"
+msgstr "تجميع حسب: الشهر"
+
+#: controllers/statistics_controller.php:249
+msgid "statistics_js_groupby_selector_week"
+msgstr "تجميع حسب: الأسبوع"
+
+#: controllers/statistics_controller.php:250
+msgid "statistics_js_groupby_selector_week_over_week"
+msgstr "قارÙÙ† حسب: الأسبوع"
+
+#: controllers/statistics_controller.php:260
+msgid "statistics_js_plotselection_foundinrange"
+msgstr "ÙˆÙجد %s ÙÙŠ المجال"
+
+#: controllers/statistics_controller.php:270
+msgid "statistics_js_plotselection_options_addplot_name"
+msgstr "أضÙ٠مخططًا"
+
+#: controllers/statistics_controller.php:271
+msgid "statistics_js_plotselection_options_addplot_tooltip"
+msgstr "أضÙ٠مخططًا آخر لهذا الرسم البياني"
+
+#: controllers/statistics_controller.php:261
+msgid "statistics_js_plotselection_options_count_name_checked"
+msgstr "أخÙ٠المجموع الكامل"
+
+#: controllers/statistics_controller.php:262
+msgid "statistics_js_plotselection_options_count_name_unchecked"
+msgstr "أظهÙر المجموع الكامل"
+
+#: controllers/statistics_controller.php:263
+msgid "statistics_js_plotselection_options_count_tooltip"
+msgstr "أضÙ٠المجموع الكامل ÙÙŠ هذا الرسم البياني"
+
+#: controllers/statistics_controller.php:275
+msgid "statistics_js_plotselection_options_csv_name"
+msgstr "شاهد البيانات (CSV)"
+
+#: controllers/statistics_controller.php:276
+msgid "statistics_js_plotselection_options_csv_tooltip"
+msgstr "احصل على مل٠من هذه البيانات Ù‚ÙÙŠÙŽÙ…ÙÙ‡Ù Ù…Ùصولة بÙاصلة"
+
+#: controllers/statistics_controller.php:267
+msgid "statistics_js_plotselection_options_events_addon_name_checked"
+msgstr "أخÙ٠أحداث %s"
+
+#: controllers/statistics_controller.php:268
+msgid "statistics_js_plotselection_options_events_addon_name_unchecked"
+msgstr "أظهÙر أحداث %s"
+
+#: controllers/statistics_controller.php:269
+msgid "statistics_js_plotselection_options_events_addon_tooltip"
+msgstr "أظهÙر تواريخ إصدار الإضاÙØ© على المخططات"
+
+#: controllers/statistics_controller.php:264
+msgid "statistics_js_plotselection_options_events_firefox_name_checked"
+msgstr "أخÙ٠أحداث ÙَيَرÙÙكس"
+
+#: controllers/statistics_controller.php:265
+msgid "statistics_js_plotselection_options_events_firefox_name_unchecked"
+msgstr "أظهÙر أحداث ÙَيَرÙÙكس"
+
+#: controllers/statistics_controller.php:266
+msgid "statistics_js_plotselection_options_events_firefox_tooltip"
+msgstr "عيّن تواريخ إصدار ÙَيَرÙÙكس على المخططات"
+
+#: controllers/statistics_controller.php:272
+msgid "statistics_js_plotselection_options_resize_name_checked"
+msgstr "قلّص الرسم البياني"
+
+#: controllers/statistics_controller.php:273
+msgid "statistics_js_plotselection_options_resize_name_unchecked"
+msgstr "وسّع الرسم البياني"
+
+#: controllers/statistics_controller.php:274
+msgid "statistics_js_plotselection_options_resize_tooltip"
+msgstr "غيّر حجم الرسم البياني"
+
+#: controllers/statistics_controller.php:254
+msgid "statistics_js_plotselection_selector_adu"
+msgstr "المستخدمون النشطون يوميًا"
+
+#: controllers/statistics_controller.php:256
+msgid "statistics_js_plotselection_selector_application"
+msgstr "التطبيق"
+
+#: controllers/statistics_controller.php:259
+msgid "statistics_js_plotselection_selector_custom"
+msgstr "مخصص"
+
+#: controllers/statistics_controller.php:253
+msgid "statistics_js_plotselection_selector_downloads"
+msgstr "التنزيلات"
+
+#: controllers/statistics_controller.php:258
+msgid "statistics_js_plotselection_selector_os"
+msgstr "نظام التشغيل"
+
+#: controllers/statistics_controller.php:257
+msgid "statistics_js_plotselection_selector_status"
+msgstr "حالة الإضاÙØ©"
+
+#: controllers/statistics_controller.php:252
+msgid "statistics_js_plotselection_selector_summary"
+msgstr "الملخص"
+
+#: controllers/statistics_controller.php:255
+msgid "statistics_js_plotselection_selector_version"
+msgstr "إصدارة الإضاÙØ©"
+
+#: controllers/components/stats.php:398
+msgid "statistics_longnames_application"
+msgstr "التطبيق"
+
+#: controllers/components/stats.php:400
+msgid "statistics_longnames_os"
+msgstr "نظام التشغيل"
+
+#: controllers/components/stats.php:399
+msgid "statistics_longnames_status"
+msgstr "حالة الإضاÙØ©"
+
+#: controllers/components/stats.php:401
+msgid "statistics_longnames_unknown"
+msgstr "مجهول"
+
+#: controllers/components/stats.php:397
+msgid "statistics_longnames_version"
+msgstr "إصدارة الإضاÙØ©"
+
+#: views/statistics/addon.thtml:118
+msgid "statistics_notice_data_insufficient"
+msgstr ""
+"لا يوجد بيانات كاÙية حاليًا لعرض هذا الرسم البياني. ÙŠÙرجى إعادة المحاولة لاحقًا."
+
+#: views/statistics/addon.thtml:130
+msgid "statistics_notice_data_none"
+msgstr "نحن لا نملك أي بيانات عن إضاÙتك بعد. ÙŠÙرجى إعادة التحقق بعد عدة أيام."
+
+#: views/statistics/addon.thtml:41
+msgid "statistics_notice_data_updating"
+msgstr ""
+"يتمّ تحديث إحصائيات الإضاÙØ© ÙÙŠ الوقت الحالي. المعلومات الأخيرة قد تكون غير "
+"مكتملة لأن نصوصنا البرمجية تعمل على تحديث هذه المعلومات. يرجى إعادة المحاولة "
+"بعد دقائق."
+
+#: views/statistics/addon.thtml:136
+msgid "statistics_notice_disabled"
+msgstr "لوحة الإحصائيات معطلة حاليًا. ÙŠÙرجى معاودة المحاولة لاحقًا."
+
+#: views/statistics/addon.thtml:123
+msgid "statistics_notice_nojavascript"
+msgstr "جاÙاسكربت مطلوبة لمشاهدة الرسوم البيانية للوحة الإحصائيات."
+
+#: views/statistics/addon.thtml:44
+msgid "statistics_notice_settings_updated"
+msgstr "لقد Ø­Ùدّثت إعداداتك!"
+
+#: controllers/statistics_controller.php:60
+#: controllers/statistics_controller.php:71
+#: controllers/statistics_controller.php:74
+#: controllers/statistics_controller.php:240
+msgid "statistics_pagetitle"
+msgstr "لوحة الإحصائيات"
+
+#: views/statistics/addon.thtml:99
+msgid "statistics_plot_legend_adu"
+msgstr "المستخدمون النشطون يوميًا"
+
+#: views/statistics/addon.thtml:95
+msgid "statistics_plot_legend_downloads"
+msgstr "التنزيلات اليومية"
+
+#: views/statistics/addon.thtml:107
+msgid "statistics_plot_options_zoomin_alt"
+msgstr "رؤية أقرب"
+
+#: views/statistics/addon.thtml:106
+msgid "statistics_plot_options_zoomin_title"
+msgstr "رؤية أقرب بشهر واحد"
+
+#: views/statistics/addon.thtml:110
+msgid "statistics_plot_options_zoomout_alt"
+msgstr "رؤية أبعد"
+
+#: views/statistics/addon.thtml:109
+msgid "statistics_plot_options_zoomout_title"
+msgstr "رؤية أبعد بشهر واحد"
+
+#: controllers/statistics_controller.php:283
+#, php-format
+msgid "statistics_rss_description"
+msgstr "ملخص الإحصاءات اليومية ل†%1$s"
+
+#: views/statistics/rss/summary.thtml:68
+msgid "statistics_rss_title_fulldate"
+msgstr "%A، %e %B، %Y"
+
+#: views/statistics/rss/summary.thtml:68
+#, php-format
+msgid "statistics_rss_title_statsfordate"
+msgstr "إحصائيات %1$s"
+
+#: views/statistics/settings.thtml:49
+msgid "statistics_settings_access_description"
+msgstr ""
+"بشكل اÙتراضي، لا ÙŠÙسمح إلا لك ولموزيلا Ùقط بالوصول إلى المعلومات التي ÙÙŠ لوحة "
+"قيادتك. غير أنه بإمكانك Ùتح ذلك للعموم ليتمكّن أي شخص من مشاهدة بيانات إضاÙتك."
+
+#: views/statistics/settings.thtml:48
+msgid "statistics_settings_access_heading"
+msgstr "حقّ الوصول إلى لوحة القيادة"
+
+#: views/statistics/settings.thtml:51
+msgid "statistics_settings_access_private"
+msgstr "خاص"
+
+#: views/statistics/settings.thtml:51
+msgid "statistics_settings_access_private_description"
+msgstr "أنت وموزيلا Ùقط تستطيعان مشاهدة إحصائيات الإضاÙØ©"
+
+#: views/statistics/settings.thtml:52
+msgid "statistics_settings_access_public"
+msgstr "عام"
+
+#: views/statistics/settings.thtml:52
+msgid "statistics_settings_access_public_description"
+msgstr "أيّ شخص يمكنه مشاهدة إحصائيات هذه الإضاÙØ©"
+
+#: views/statistics/addon.thtml:251
+msgid "statistics_settings_change_link"
+msgstr "غيّر الإعدادات"
+
+#: views/statistics/addon.thtml:253
+msgid "statistics_settings_confidential"
+msgstr "تعامل رجاءً مع هذه المعلومات على أنها سرّية."
+
+#: views/statistics/addon.thtml:245
+msgid "statistics_settings_currently_private"
+msgstr "لوحة القيادة هذه <b>خاصة</b> حاليًا."
+
+#: views/statistics/addon.thtml:241
+msgid "statistics_settings_currently_public"
+msgstr "لوحة القيادة هذه <b>عامة</b> حاليًا."
+
+#: views/statistics/addon.thtml:246
+msgid "statistics_settings_locked_alt"
+msgstr "مقÙلة"
+
+#: views/statistics/settings.thtml:57
+msgid "statistics_settings_return_link"
+msgstr "عÙد إلى لوحة القيادة"
+
+#: views/statistics/settings.thtml:56
+msgid "statistics_settings_save_button"
+msgstr "احÙظ الإعدادات"
+
+#: views/statistics/settings.thtml:46
+#, php-format
+msgid "statistics_settings_title"
+msgstr "إعدادات لوحة الإحصائيات ل†%1$s"
+
+#: views/statistics/addon.thtml:242
+msgid "statistics_settings_unlocked_alt"
+msgstr "غير مقÙلة"
+
+#: controllers/components/stats.php:405
+msgid "statistics_shortnames_application"
+msgstr "تطبيق"
+
+#: controllers/components/stats.php:407
+msgid "statistics_shortnames_os"
+msgstr "نظام تشغيل"
+
+#: controllers/components/stats.php:406
+msgid "statistics_shortnames_status"
+msgstr "حالة"
+
+#: controllers/components/stats.php:408
+msgid "statistics_shortnames_unknown"
+msgstr "مجهول"
+
+#: controllers/components/stats.php:404
+msgid "statistics_shortnames_version"
+msgstr "إصدارة"
+
+#: views/statistics/rss/summary.thtml:42 views/statistics/addon.thtml:192
+msgid "statistics_summary_downloads_average"
+msgstr "متوسط التنزيلات اليومية"
+
+#: views/statistics/rss/summary.thtml:39
+msgid "statistics_summary_downloads_heading"
+msgstr "التنزيلات"
+
+#: views/statistics/rss/summary.thtml:41 views/statistics/addon.thtml:171
+msgid "statistics_summary_downloads_lastcount"
+msgstr "إحصاء آخر يوم"
+
+#: views/statistics/rss/summary.thtml:43 views/statistics/addon.thtml:199
+msgid "statistics_summary_downloads_lastweek"
+msgstr "التنزيلات ÙÙŠ آخر 7 أيام"
+
+#: views/statistics/rss/summary.thtml:40 views/statistics/addon.thtml:151
+msgid "statistics_summary_downloads_total"
+msgstr "كامل التنزيلات"
+
+#: views/statistics/rss/summary.thtml:40 views/statistics/addon.thtml:152
+#, php-format
+msgid "statistics_summary_downloads_total_sincedate"
+msgstr "منذ %1$s"
+
+#: views/statistics/rss/summary.thtml:50 views/statistics/rss/summary.thtml:56
+#: views/statistics/addon.thtml:163 views/statistics/addon.thtml:183
+msgid "statistics_summary_nodata"
+msgstr "لا بيانات حتى الآن"
+
+#: views/statistics/rss/summary.thtml:60 views/statistics/addon.thtml:195
+msgid "statistics_summary_updatepings_average"
+msgstr "متوسط المستخدمين النشطين يوميًا"
+
+#: views/statistics/rss/summary.thtml:52 views/statistics/addon.thtml:177
+msgid "statistics_summary_updatepings_changefromprevious"
+msgstr "التغيّر عن الإحصاء السابق"
+
+#: views/statistics/rss/summary.thtml:54 views/statistics/addon.thtml:181
+#, php-format
+msgid "statistics_summary_updatepings_changefromprevious_ondate"
+msgstr "%1$s ÙÙŠ %2$s"
+
+#: views/statistics/rss/summary.thtml:45
+msgid "statistics_summary_updatepings_heading"
+msgstr "المستخدمون النشطون يوميًا"
+
+#: views/statistics/rss/summary.thtml:46 views/statistics/addon.thtml:157
+msgid "statistics_summary_updatepings_total"
+msgstr "المستخدمون النشطون يوميًا"
+
+#: views/statistics/rss/summary.thtml:48 views/statistics/addon.thtml:161
+#, php-format
+msgid "statistics_summary_updatepings_total_ondate"
+msgstr "ÙÙŠ %1$s"
+
+#: views/statistics/rss/summary.thtml:61 views/statistics/addon.thtml:203
+#, fuzzy
+msgid "statistics_summary_updatepings_weekly_average"
+msgstr "Average Daily Users this Week"
+
+#. %s is a percentage, like '+22.33%'. It sits next to another number, so
+#. the implied meaning is 'percentage change' from the previous stat point.
+#: views/statistics/rss/summary.thtml:62 views/statistics/addon.thtml:205
+#, fuzzy
+msgid "statistics_summary_updatepings_weekly_change"
+msgstr "%s from last week"
+
+#: views/statistics/addon.thtml:65 controllers/statistics_controller.php:184
+#: controllers/statistics_controller.php:282
+#, php-format
+msgid "statistics_title_addon_stats"
+msgstr "إحصائيات %1$s"
+
+#: views/addons/themes_landing.thtml:113
+msgid "themes_landing_all_themes"
+msgstr "كل السمات"
+
+#: views/addons/themes_landing.thtml:109
+msgid "themes_landing_browse_themes"
+msgstr "استعرض السمات"
+
+#: views/users/edit.thtml:185
+msgid "user_change_email"
+msgstr "غيّر البريد الإلكتروني"
+
+#: views/users/edit.thtml:169
+msgid "user_change_password"
+msgstr "غيّر كلمة السر"
+
+#: views/users/edit.thtml:96
+#, fuzzy
+msgid "user_change_password_or_email"
+msgstr "Change Password or Email"
+
+#: controllers/users_controller.php:197
+msgid "user_confirmationcode_resent"
+msgstr "أرسÙÙ„ رمز التأكيد!"
+
+#. %1 is the email address, %2 is the URL of the user registration page
+#: views/users/delete.thtml:51
+msgid "user_del_account_deleted"
+msgstr ""
+"Ø­Ùذ٠حساب مستخدمك %1$s بنجاح. إن أردت العودة ÙÙŠ وقت لاحق، يمكنك إعادة التسجيل "
+"ÙÙŠ <a href=\"%2$s\">صÙحة تسجيل المستخدم</a>."
+
+#: views/users/delete.thtml:102
+msgid "user_del_community_sad"
+msgstr "مجتمع إضاÙات موزيلا حزين لرؤيتك ترحل."
+
+#: views/users/delete.thtml:123
+msgid "user_del_confirm_password"
+msgstr "أكّد كلمة السر"
+
+#: views/users/delete.thtml:134
+msgid "user_del_deletenow"
+msgstr "احذ٠حساب المستخدم الآن"
+
+#. %1 is the URL of the user's info page
+#: views/users/delete.thtml:64
+msgid "user_del_error_addons"
+msgstr ""
+"لا يمكنك حذ٠حسابك إن كنت أحد <a href=\"%1$s\">المؤلÙين لأي إضاÙØ©</a>. لحذ٠"
+"حسابك، عليك أن تطلب من شخص آخر ÙÙŠ مجموعة المطوّرين لديك أن يزيل اسمك من قائمة "
+"المؤلÙين لإضاÙاتك، ثم يمكنك بعدها أن تحذ٠حسابك هنا."
+
+#. %1 is a link to the amo-editors mailing list
+#: views/users/delete.thtml:71
+msgid "user_del_error_addons_more_questions"
+msgstr "إن كان لديك أسئلة إضاÙية، تواصل مع %1$s للحصول على المساعدة."
+
+#: views/users/delete.thtml:78
+msgid "user_del_error_checkbox"
+msgstr "عليك أن تؤشّر على الصندوق \"Ø£Ùهم ذلك...\" لكي نستطيع أن نحذ٠لك حسابك."
+
+#: views/users/delete.thtml:84
+msgid "user_del_error_password"
+msgstr "أدخÙÙ„ رجاءً كلمة سرّك بشكل صحيح ليمكن القيام بهذه الخطوة."
+
+#. %1 is a link to the amo-admins mailing list
+#: views/users/delete.thtml:91
+msgid "user_del_error_unknown"
+msgstr ""
+"حصل خطأ غير معرو٠أثناء حذ٠حسابك. تواصل رجاءً مع %1$s وبلّغه عن المشكلة وسو٠"
+"نحذÙÙ‡ من أجلك. نعتذر عن هذا الخطأ."
+
+#: views/users/delete.thtml:110
+msgid "user_del_header_confirm_deletion"
+msgstr "تأكيد حذ٠الحساب"
+
+#. %1 is the user's email address
+#: views/users/delete.thtml:100
+msgid "user_del_header_delete_account"
+msgstr "حذ٠حساب المستخدم %1$s"
+
+#: views/users/delete.thtml:50
+msgid "user_del_header_farewell"
+msgstr "وداعًا!"
+
+#: views/users/delete.thtml:115
+msgid "user_del_nologin"
+msgstr "لن يعود باستطاعتك تسجيل دخولك إلى إضاÙات موزيلا بعد ذلك."
+
+#: views/users/delete.thtml:112
+msgid "user_del_permanently_removed_means"
+msgstr ""
+"عند النقر على \"احذÙ\"ØŒ <strong>سيÙحذ٠حسابك نهائيًا</strong>ØŒ وهذا يعني:"
+
+#: views/users/delete.thtml:116
+msgid "user_del_reviews_anonymized"
+msgstr "أنّ مراجعاتك وتقييماتك لن تÙحذÙØŒ ولكنها لن تعود مرتبطة بك بعد ذلك."
+
+#. %1 is a link to the amo-editors mailing list
+#: views/users/delete.thtml:104
+msgid "user_del_specific_problem_editors"
+msgstr ""
+"إن كان لديك مشكلة ميّنة Ùقد نستطيع المساعدة. رجاءً لا تحذ٠حسابك الآم، ولكن "
+"تواصل معنا ÙÙŠ %1$s وسنبذل جهدنا لمساعدتك ÙÙŠ حل مشكلتك."
+
+#: views/users/delete.thtml:130
+msgid "user_del_understand_permanent"
+msgstr "أنا Ø£Ùهم أنه لا يمكن التراجع عن هذه الخطوة."
+
+#: views/helpers/addons_html.php:192
+msgid "user_deleted_nickname"
+msgstr "مستخدم محذوÙ"
+
+#. %1 is the new email address
+#: views/users/edit.thtml:71
+msgid "user_edit_confirm_email_sent"
+msgstr ""
+"أرسÙلت رسالة إلى %1$s لتأكيد بريدك الإلكتروني الجديد. ليأخذ التغيير Ù…Ùعوله، "
+"عليك أن تنقر على الوصلة الموجودة ÙÙŠ تلك الرسالة. حتى ذلك الوقت، يمكنك "
+"المتابعة مع بريدك الإلكتروني الحالي."
+
+#: views/users/edit.thtml:201
+msgid "user_edit_delete_user"
+msgstr "احذ٠حساب المستخدم"
+
+#. This contains the email sent to users when they signed up for a new
+#. account:
+#. %1 is the confirmation URL, %2 is the current app
+#: views/users/email/confirm_plain.thtml:6
+#, php-format
+msgid "user_email_confirm_account_nopass"
+msgstr ""
+"مرحبًا ÙÙŠ إضاÙات %2$s.\n"
+"\n"
+"قبل أن يمكنك استخدام حسابك، عليك أن تÙعّله - ذلك يضمن أن بريدك الإلكتروني "
+"الذي تستخدمه صالح وتعود ملكيته إليك.\n"
+"لتÙعيل حسابك، انقر على الرابط أدناه أو انسخه إلى شريط تحديد الموقع ÙÙŠ "
+"متصÙحك:\n"
+"\n"
+"%1$s\n"
+"\n"
+"حالما تنتهي من تÙعيل حسابك، يمكنك حذ٠هذه الرسالة.\n"
+"\n"
+"شكرًا لانضمامك إلى إضاÙات %2$s\n"
+"-- Ùريق عمل إضاÙات %2$s"
+
+#. %1 is the confirmation url, %2 is the application name
+#: views/users/email/emailchange_plain.thtml:5
+msgid "user_email_confirm_emailchange"
+msgstr ""
+"لقد طلبت تغيير بريدك الإلكتروني ÙÙŠ إضاÙات %2$s.\n"
+"\n"
+"من أجل التأكيد على البريد الإلكتروني الجديد، انقر على الرابط أدناه أو انسخه "
+"إلى شريط تحديد الموقع ÙÙŠ متصÙحك:\n"
+"\n"
+"%1$s\n"
+"\n"
+"أمامك 24 ساعة حتى تؤكّد البريد الجديد. إن لم تعد تريد تغيير البريد "
+"الإلكتروني، بإمكانك تجاهل هذه الرسالة حينها.\n"
+"\n"
+"شكرًا!\n"
+"-- Ùريق عمل إضاÙات %2$s"
+
+#: controllers/users_controller.php:168
+#, php-format
+msgid "user_email_confirm_subject"
+msgstr "شكرًا لانضمامك إلى إضاÙات %s"
+
+#. This is the password reset email
+#. %1 is the pw reset URL, %2 is the application
+#: views/users/email/pwreset_plain.thtml:5
+#, php-format
+msgid "user_email_pwreset"
+msgstr ""
+"%2$s Add-ons Password Reset\n"
+"\n"
+"استلمنا طلبًا منك لإعادة تعيين كلمة السر لهذا الحساب ÙÙŠ addons.mozilla.org. "
+"لتغيير كلمة السر، انقر على الرابط أدناه أو انسخه إلى شريط تحديد الموقع ÙÙŠ "
+"متصÙحك:\n"
+"\n"
+"%1$s\n"
+"\n"
+"إن لم تطلب هذه الرسالة، Ùليس هناك حاجة للقيام بأي شيء.\n"
+"\n"
+"شكرًا،\n"
+"-- Ùريق عمل إضاÙات %2$s"
+
+#: controllers/users_controller.php:245
+#, php-format
+msgid "user_email_pwreset_subject"
+msgstr "إعادة تعيين كلمة السر لإضاÙات %s"
+
+#: views/users/emailchange.thtml:50
+msgid "user_emailchange_error"
+msgstr "خطأ!"
+
+#. %1 is the application name
+#: controllers/users_controller.php:533
+msgid "user_emailchange_subject"
+msgstr "ÙŠÙرجى منك تأكيد تغييرك للبريد الإلكتروني ÙÙŠ إضاÙات %1$s"
+
+#: views/users/emailchange.thtml:48
+msgid "user_emailchange_success"
+msgstr "نجحت!"
+
+#. %1 is the new email address
+#: views/users/emailchange.thtml:49
+msgid "user_emailchange_successful_description"
+msgstr ""
+"لقد غيّرت بريدك الإلكتروني بنجاح. استخدم %1$s من الآن Ùصاعدًا لتسجيل دخولك."
+
+#: views/users/edit.thtml:134 views/admin/users_edit.thtml:111
+#, fuzzy
+msgid "user_form_bio"
+msgstr "About me"
+
+#: views/users/edit.thtml:135 views/admin/users_edit.thtml:112
+#, fuzzy
+msgid "user_form_bio_description"
+msgstr ""
+"Introduce yourself to the community, if you like! This text will appear "
+"publicly on your user info page. Line breaks will be preserved, but no HTML "
+"is allowed."
+
+#: views/users/pwreset.thtml:77 views/users/register.thtml:73
+#: views/users/edit.thtml:181
+msgid "user_form_confirmpassword"
+msgstr "أكّد كلمة السرّ"
+
+#: views/users/edit.thtml:145
+#, fuzzy
+msgid "user_form_display_collections"
+msgstr "Display the collections I have created in my user profile"
+
+#: views/users/edit.thtml:149
+#, fuzzy
+msgid "user_form_display_collections_fav"
+msgstr "Display my favorite collections in my user profile"
+
+#: views/users/edit.thtml:86
+#, php-format
+msgid "user_form_editprofile"
+msgstr "حرّر مل٠المستخدم الشخصي ل†%s"
+
+#: views/users/pwreset.thtml:52 views/users/login.thtml:81
+#: views/users/register.thtml:63 views/users/edit.thtml:187
+msgid "user_form_email"
+msgstr "البريد الإلكتروني"
+
+#: views/users/register.thtml:78 views/users/edit.thtml:103
+#: views/admin/users_edit.thtml:76
+msgid "user_form_firstname"
+msgstr "الاسم الأول"
+
+#: views/users/register.thtml:94 views/users/edit.thtml:119
+#: views/admin/users_edit.thtml:91
+msgid "user_form_hideemail"
+msgstr "أخÙ٠البريد الإلكتروني"
+
+#: views/users/register.thtml:98 views/users/edit.thtml:123
+#: views/admin/users_edit.thtml:99
+msgid "user_form_homepage"
+msgstr "عنوان موقع الوب"
+
+#: views/users/register.thtml:84 views/users/edit.thtml:109
+#: views/admin/users_edit.thtml:81
+msgid "user_form_lastname"
+msgstr "الاسم الأخير"
+
+#: controllers/users_controller.php:333
+msgid "user_form_login"
+msgstr "تسجيل دخول المستخدم"
+
+#: views/users/pwreset.thtml:72 views/users/edit.thtml:176
+msgid "user_form_newpassword"
+msgstr "كلمة السر الجديدة"
+
+#: views/users/register.thtml:89 views/users/edit.thtml:114
+#: views/admin/users_edit.thtml:86
+msgid "user_form_nickname"
+msgstr "الاسم المستعار"
+
+#: views/users/edit.thtml:171
+msgid "user_form_oldpassword"
+msgstr "كلمة السر القديمة"
+
+#: views/users/edit.thtml:97 views/users/edit.thtml:200
+msgid "user_form_otheractions"
+msgstr "إجراءات أخرى"
+
+#: views/users/login.thtml:85 views/users/register.thtml:68
+msgid "user_form_password"
+msgstr "كلمة السر"
+
+#: controllers/users_controller.php:93
+msgid "user_form_registration"
+msgstr "تسجيل المستخدم الجديد"
+
+#: views/users/login.thtml:90
+msgid "user_form_remember_me"
+msgstr "تذكّرني على هذا الحاسوب"
+
+#: views/admin/users_edit.thtml:95
+msgid "user_form_showsandbox"
+msgstr "إظهار ساحة اللعب؟"
+
+#: views/users/edit.thtml:205
+msgid "user_form_submit_edit"
+msgstr "احÙظ"
+
+#: views/users/login.thtml:93
+msgid "user_form_submit_login"
+msgstr "سجّل دخولي"
+
+#: views/users/register.thtml:113
+msgid "user_form_submit_register"
+msgstr "سجّل"
+
+#: views/users/info.thtml:75
+#, php-format
+msgid "user_info_usersince"
+msgstr "مستخدم لإضاÙات %s منذ"
+
+#: views/users/login.thtml:102
+msgid "user_login_register_link"
+msgstr "أنشئ حساب مستخدم جديد"
+
+#: views/users/edit.thtml:160
+msgid "user_notifications_item_compat"
+msgstr "تواÙقية الإضاÙØ© (Ù…Ùزكَّاة بقوة)"
+
+#: views/users/edit.thtml:161
+msgid "user_notifications_item_events"
+msgstr "الأحداث والمسابقات القادمة"
+
+#: views/users/edit.thtml:156
+msgid "user_notifications_none_available"
+msgstr "لا يوجد حاليًا تنبيهات متاحة لك لإعدادها."
+
+#: views/users/edit.thtml:158
+msgid "user_notifications_select_topics"
+msgstr ""
+"قد ترسل لك موزيلا، من وقت لآخر، رسالة تتكلم عن الإصدارات القادمة وأحداث "
+"الإضاÙات. اختر رجاءً المواضيع التي تهتم بها مما يلي:"
+
+#: views/users/edit.thtml:164
+msgid "user_notifications_specific_contact"
+msgstr ""
+"تحتÙظ موزيلا بحقها ÙÙŠ التواصل معك شخصيًا بخصوص أمور معينة تتعلق بإضاÙاتك "
+"المÙستضاÙØ© عندها."
+
+#: controllers/users_controller.php:543
+msgid "user_profile_edit_error"
+msgstr "هناك أخطاء ÙÙŠ التعديلات التي أجريتها. صحّحها رجاءً ثمّ أعد الإرسال."
+
+#: controllers/users_controller.php:540
+msgid "user_profile_saved"
+msgstr "Ø­Ùدّث المل٠الشخصي."
+
+#: views/users/pwreset.thtml:65
+#, php-format
+msgid "user_pwreset_for_email"
+msgstr "أعÙد تعيين كلمة السر ل†%s"
+
+#: controllers/users_controller.php:226
+msgid "user_pwreset_header"
+msgstr "إعادة تعيين كلمة السر"
+
+#: views/users/login.thtml:103
+msgid "user_pwreset_link"
+msgstr "نسيتَ كلمة سرّك؟"
+
+#: controllers/users_controller.php:248
+msgid "user_pwreset_link_sent"
+msgstr "أرسÙلت وصلة إعادة تعيين كلمة السر إلى بريدك الإلكتروني."
+
+#: controllers/users_controller.php:304
+msgid "user_pwreset_okay"
+msgstr "Ø£Ùعيدَ تعيين كلمة السر بنجاح."
+
+#: views/users/pwreset.thtml:82
+msgid "user_pwreset_submit_changepw"
+msgstr "أرسÙÙ„ تعديل كلمة السر"
+
+#: views/users/pwreset.thtml:57
+msgid "user_pwreset_submit_sendlink"
+msgstr "أرسÙÙ„ وصلة إعادة تعيين كلمة السر"
+
+#: views/users/register_complete.thtml:51
+#, php-format
+msgid "user_register_amo_link"
+msgstr "إضاÙات %s"
+
+#. %1 is the user's email address, %2 is the current app
+#: views/users/activatefirst.thtml:49
+#, php-format
+msgid "user_register_click_confirm_link"
+msgstr ""
+"أرسÙلت وصلة لتÙعيل حساب مستخدمك إلى بريدك الإلكتروني %1$s. عليك أن تنقر عليها "
+"لتتمكن من تسجيل دخولك إلى إضاÙات %2$s."
+
+#. %1 is the user's email address
+#: views/users/register_complete.thtml:49
+#, php-format
+msgid "user_register_confirm_email_sent"
+msgstr ""
+"أرسÙلت رسالة إلى بريدك الإلكتروني %1$s لتأكيد حسابك. قبل أن تستطيع تسجيل "
+"الدخول، عليك أن تÙعّل حسابك بالنقر على الوصلة الموجودة ÙÙŠ الرسالة."
+
+#: views/users/activatefirst.thtml:51
+msgid "user_register_confirmation_link_text"
+msgstr "نعيد إرسال رسالة التأكيد"
+
+#: views/users/register_complete.thtml:47
+msgid "user_register_congratulations"
+msgstr "تهانينا! لقد أنشئ حساب مستخدمك بنجاح."
+
+#: views/users/register.thtml:50
+#, fuzzy
+msgid "user_register_details"
+msgstr ""
+"<p>Registration on AMO is <strong>not required</strong> if you simply want "
+"to download and install public add-ons.</p><p>You only need to register if:</"
+"p><ul><li>You want to submit reviews for add-ons</li><li>You are an add-on "
+"developer and want to upload your add-on for hosting on AMO</li></ul><p>Upon "
+"successful registration, you will be sent a confirmation email to the "
+"address you provided. Please follow the instructions there to confirm your "
+"account.</p><p>If you like, you can read our <a href='%1$s' title='Legal "
+"Notices'>Legal Notices</a> and <a href='%2$s' title='Privacy Policy'>Privacy "
+"Policy</a>.</p>"
+
+#. %1 is the link to the "resend confirmation code" page
+#: views/users/activatefirst.thtml:51
+#, php-format
+msgid "user_register_resend_confirmation_link"
+msgstr ""
+"إن لم تستلم رسالة التأكيد، تأكّد أن خدمة بريدك لم تعتبر الرسالة \"سÙخامًا\" أو "
+"\"بريدًا مزعجًا\". إن دعت الحاجة، يمكننا أن %1$s إلى بريدك الإلكتروني المذكور "
+"ÙÙŠ الأعلى."
+
+#. %1 is the link to the Mozilla Add-ons front page
+#: views/users/register_complete.thtml:51
+#, php-format
+msgid "user_register_welcome"
+msgstr "شكرًا على تسجيلك معنا ومرحبًا بك ÙÙŠ %1$s!"
+
+#: views/users/register.thtml:49
+#, fuzzy
+msgid "user_register_welcome_header"
+msgstr "Welcome to addons.mozilla.org (AMO)!"
+
+#: views/users/register.thtml:81 views/users/edit.thtml:106
+msgid "user_required_firstlast_or_nickname"
+msgstr "مطلوب منك أن تÙدخل اسمك الأول أو الأخير أو الاسم المستعار."
+
+#: views/users/edit.thtml:94 views/users/edit.thtml:142
+#, fuzzy
+msgid "user_tab_collections"
+msgstr "Collections"
+
+#: views/users/edit.thtml:95 views/users/edit.thtml:154
+msgid "user_tab_notifications"
+msgstr "التنبيهات"
+
+#: views/users/edit.thtml:93 views/users/edit.thtml:101
+msgid "user_tab_profile"
+msgstr "مل٠المستخدم الشخصي"
+
+#: controllers/users_controller.php:209
+msgid "user_verified_okay"
+msgstr "جرى التحقق منه بنجاح!"
+
+#: controllers/users_controller.php:723
+msgid "users_delete_pagetitle"
+msgstr "حذ٠حساب المستخدم"
+
+#: controllers/users_controller.php:414
+msgid "users_edit_pagetitle"
+msgstr "تحرير حساب المستخدم"
+
+#: views/users/info.thtml:71
+#, fuzzy
+msgid "users_info_aboutme"
+msgstr "About Me"
+
+#: views/users/info.thtml:96
+#, php-format
+msgid "users_info_addons_by_user"
+msgstr "الإضاÙات من %1$s"
+
+#: views/users/info.thtml:51
+msgid "users_info_author_name"
+msgstr "الاسم"
+
+#: views/users/info.thtml:48
+msgid "users_info_author_profile"
+msgstr "مل٠المستخدم الشخصي"
+
+#. %s is the user name
+#: views/users/info.thtml:137
+#, fuzzy
+msgid "users_info_collections_by_user"
+msgstr "Collections by %s"
+
+#: views/users/info.thtml:66
+msgid "users_info_email"
+msgstr "البريد الإلكتروني"
+
+#: views/users/info.thtml:155
+#, fuzzy
+msgid "users_info_fav_collections_by_user"
+msgstr "Favorite Collections"
+
+#: views/users/info.thtml:61
+msgid "users_info_homepage"
+msgstr "صÙحة البداية"
+
+#: views/users/info.thtml:56
+msgid "users_info_nickname"
+msgstr "الاسم المستعار"
+
+#: controllers/users_controller.php:707
+#, php-format
+msgid "users_info_pagetitle"
+msgstr "معلومات المستخدم ل†%1$s"
+
+#. %1 is the user's name
+#: views/users/info.thtml:116
+msgid "users_info_reviews_by_user"
+msgstr "مراجعات ل†%s"
+
+#: controllers/users_controller.php:330 controllers/users_controller.php:332
+msgid "users_login_pagetitle"
+msgstr "تسجيل دخول المستخدم"
+
+#. %1 is the link to the sandbox/policy explanation page
+#. This message is for a specific add-on not found
+#: views/users/login.thtml:53
+#, php-format
+msgid "users_login_sandbox_display_warning"
+msgstr ""
+"الإضاÙØ© التي تبحث عنها هي حاليًا ÙÙŠ ساحة اللعب. إن كنت تملك حسابًا ÙÙŠ إضاÙات "
+"موزيلا ÙÙŠÙرجى منك تسجيل دخولك، أو <a href=\"%1$s\">اعر٠المزيد عن ساحة اللعب</"
+"a>."
+
+#. %1 is the link to the sandbox/policy explanation page
+#. This message is for any given sandbox-related page not found
+#: views/users/login.thtml:56
+#, php-format
+msgid "users_login_sandbox_page_warning"
+msgstr ""
+"الصÙحة التي تبحث عنها هي جزء من ساحة اللعب. إن كنت تملك حسابًا ÙÙŠ إضاÙات "
+"موزيلا ÙÙŠÙرجى منك تسجيل دخولك، أو <a href=\"%1$s\">اعر٠المزيد عن ساحة اللعب</"
+"a>."
+
+#: controllers/users_controller.php:223 controllers/users_controller.php:225
+msgid "users_pwreset_pagetitle"
+msgstr "إعادة تعيين كلمة سر المستخدم"
+
+#: controllers/users_controller.php:90 controllers/users_controller.php:92
+msgid "users_register_pagetitle"
+msgstr "تسجيل المستخدم الجديد"
+
+#. %1$s is an addon name, like <a>Firebug</a>
+#. %2$s is a version number, like <a>1.2</a>
+#: views/versions/license.thtml:52
+#, fuzzy
+msgid "versions_license_header_source"
+msgstr "Source code license for %1$s %2$s"
+
+#: views/addons/category_landing.thtml:147
+#, fuzzy
+msgid "view_recently_added"
+msgstr "View all recently added"
+
+#: views/addons/category_landing.thtml:161
+#, fuzzy
+msgid "view_top_downloads"
+msgstr "View all top downloads"
+
+#: views/addons/category_landing.thtml:175
+#, fuzzy
+msgid "view_top_rated"
+msgstr "View all top rated"
+
+#~ msgid "addon_slider_tooltip_next"
+#~ msgstr "الإضاÙØ© التالية"
+
+#~ msgid "addon_slider_tooltip_previous"
+#~ msgstr "الإضاÙØ© السابقة"
+
+#~ msgid "addon_versions_getlatesttext"
+#~ msgstr "أحدث إصدارة متواÙقة مع"
+
+#~ msgid "addons_display_version_history"
+#~ msgstr "تاريخ الإصدارات الكامل"
+
+#~ msgid "addons_home_newest_header"
+#~ msgstr "الأحدث:"
+
+#~ msgid "addons_home_popular_header"
+#~ msgstr "الأكثر شعبية:"
+
+#~ msgid "addons_home_recommended_header"
+#~ msgstr "نزكّي:"
+
+#~ msgid "addons_home_updated_header"
+#~ msgstr "المحدّثة مؤخرًا:"
+
+#~ msgid "addons_home_view_all"
+#~ msgstr "شاهد الكل"
+
+#~ msgid "category_extra_allrecommended"
+#~ msgstr "شاهد كل الإضاÙات المزكَّاة"
+
+#~ msgid "category_extra_highestrated"
+#~ msgstr "ذات التقييم الأعلى أولًا"
+
+#~ msgid "category_extra_lastupdated"
+#~ msgstr "المحدّثة مؤخرًا أولًا"
+
+#~ msgid "category_extra_mostpopular"
+#~ msgstr "الأكثر شعبية أولًا"
+
+#, fuzzy
+#~ msgid "collections_detail_js_loading"
+#~ msgstr "Loading"
+
+#, fuzzy
+#~ msgid "collections_detail_more_info"
+#~ msgstr "Show More Info"
+
+#~ msgid "devcp_additem_firefox_notice"
+#~ msgstr ""
+#~ "لا تعلن هذه الإصدارة من إضاÙتك توÙقيتها مع ÙيرÙكس %1$s. تتوقع موزيلا صدور "
+#~ "النسخة القادمة من ÙيرÙكس قريبا، Ùمن Ùضلك اختبر إضاÙتك مع النسخة الجديدة "
+#~ "ثم حدّث معلومات التواÙقية. طالع المزيد عن هذا <a href=\"%2$s\">هنا</a>. "
+#~ "هذا مجرد إخطار، وتستطيع مواصلة إرسال هذه النسخة إلى addons.mozilla.org."
+
+#~ msgid "devcp_addon_disabled_successfully"
+#~ msgstr "عÙطّلت الإضاÙØ© بنجاح"
+
+#~ msgid "devcp_addon_edit_pagetitle"
+#~ msgstr "تحرير الإضاÙØ©"
+
+#~ msgid "devcp_addon_enabled_successfully"
+#~ msgstr "ÙÙعّÙلت الإضاÙØ© بنجاح"
+
+#~ msgid "devcp_addon_field_description_displaytitle"
+#~ msgstr "وص٠الإضاÙØ©"
+
+#~ msgid "devcp_addon_field_eula_displaytitle"
+#~ msgstr "اتÙاقية ترخيص المستخدم"
+
+#~ msgid "devcp_addon_field_homepage_displaytitle"
+#~ msgstr "صÙحة بداية الإضاÙØ©"
+
+#~ msgid "devcp_addon_field_name_displaytitle"
+#~ msgstr "اسم الإضاÙØ©"
+
+#~ msgid "devcp_addon_field_privacy_displaytitle"
+#~ msgstr "سياسة الخصوصية"
+
+#~ msgid "devcp_addon_field_summary_displaytitle"
+#~ msgstr "ملخص الإضاÙØ©"
+
+#~ msgid "devcp_addon_field_supportemail_displaytitle"
+#~ msgstr "بريد الدعم"
+
+#~ msgid "devcp_addon_field_supporturl_displaytitle"
+#~ msgstr "موقع الدعم"
+
+#~ msgid "devcp_addon_field_versionnotes_displaytitle"
+#~ msgstr "ملاحظات الإصدارة"
+
+#~ msgid "devcp_addon_nominate_pagetitle"
+#~ msgstr "ترشيح الإصدارة"
+
+#~ msgid "devcp_addon_nominated_successfully"
+#~ msgstr "رÙشّحت الإصدارة!"
+
+#, fuzzy
+#~ msgid "devcp_addon_status_criteria_review"
+#~ msgstr "Several user reviews of the add-on (may be external reviews)."
+
+#~ msgid "devcp_addon_submission_makechanges"
+#~ msgstr ""
+#~ "زÙر صÙحة %1$s للقيام بتعديلات على ما أرسلته، أو %2$s للعودة إلى أدوات "
+#~ "المطوّرين."
+
+#~ msgid "devcp_addon_submission_makechanges_devcp_link"
+#~ msgstr "انقر هنا"
+
+#~ msgid "devcp_addon_submission_makechanges_link"
+#~ msgstr "حرّر الإضاÙØ©"
+
+#~ msgid "devcp_addon_submission_pending"
+#~ msgstr ""
+#~ "هذه النسخة ÙˆÙضعت ÙÙŠ ساحة اللعب ريثما تنتظر المراجعة من المختبرين ÙÙŠ ساحة "
+#~ "اللعب Ùˆ محرّر إضاÙات موزيلا. سو٠تÙنبّه بريديًا عند حصول أي حدث."
+
+#~ msgid "devcp_addon_submission_sandbox_readmore"
+#~ msgstr "يمكنك قراءة المزيد عن نظام ساحة اللعب %s."
+
+#~ msgid "devcp_addon_submission_sandbox_readmore_link"
+#~ msgstr "هنا"
+
+#~ msgid "devcp_addon_submission_sandboxed"
+#~ msgstr ""
+#~ "ÙˆÙضÙعت هذه النسخة ÙÙŠ ساحة اللعب ليستخدمها المستخدمين الخبراء. يجب عليك أن %"
+#~ "s إضاÙتك وأن تخضع للمراجعة، لتنشر ÙÙŠ الموقع العام."
+
+#~ msgid "devcp_addon_submission_sandboxed_nominate_link"
+#~ msgstr "رشّح"
+
+#~ msgid "devcp_addon_submission_success"
+#~ msgstr "إرسالك للإضاÙØ© قد اكتمل بنجاح."
+
+#~ msgid "devcp_addon_submission_trusted_public"
+#~ msgstr ""
+#~ "لأن إضاÙتك موثوق بها، سو٠يÙواÙÙŽÙ‚ على نشر هذه الإصدارة آليًا على الملأ."
+
+#~ msgid "devcp_addon_submit_pagetitle"
+#~ msgstr "إرسال الإضاÙØ©"
+
+#~ msgid "devcp_addon_updated_successfully"
+#~ msgstr "Ø­Ùدّثت الإضاÙØ© بنجاح"
+
+#~ msgid "devcp_addon_upload_preview"
+#~ msgstr "قد ترغب ب†%s من أجل زيادة الاهتمام بإضاÙتك."
+
+#~ msgid "devcp_addon_upload_preview_link"
+#~ msgstr "ارÙع معاينة"
+
+#~ msgid "devcp_author_lookup_none_found"
+#~ msgstr "تعذر إيجاد المؤل٠[%s]"
+
+#~ msgid "devcp_author_lookup_remove"
+#~ msgstr "أزÙÙ„"
+
+#~ msgid "devcp_button_cancel"
+#~ msgstr "ألغÙ"
+
+#~ msgid "devcp_button_cancel_confirm"
+#~ msgstr "أمتأكد أنك تريد إلغاء الإرسال؟"
+
+#~ msgid "devcp_button_next"
+#~ msgstr "التالي"
+
+#~ msgid "devcp_change_addontype"
+#~ msgstr "غيّر نوع الإضاÙØ©:"
+
+#~ msgid "devcp_comments_updated"
+#~ msgstr "Ø­Ùدّثت تعليقات المطوّر."
+
+#~ msgid "devcp_details_addpreview_link"
+#~ msgstr "أضÙ٠معاينة"
+
+#~ msgid "devcp_details_author"
+#~ msgstr "المؤلÙ"
+
+#~ msgid "devcp_details_authors"
+#~ msgstr "المؤلÙون"
+
+#~ msgid "devcp_details_authors_none"
+#~ msgstr "لا أحد"
+
+#~ msgid "devcp_details_categories"
+#~ msgstr "التصنيÙات"
+
+#~ msgid "devcp_details_category"
+#~ msgstr "التصنيÙ"
+
+#~ msgid "devcp_details_description"
+#~ msgstr "الوصÙ"
+
+#~ msgid "devcp_details_disabled"
+#~ msgstr "Ù…Ùعطّل"
+
+#~ msgid "devcp_details_guid"
+#~ msgstr "المعرّ٠الÙريد"
+
+#~ msgid "devcp_details_header_details"
+#~ msgstr "التÙاصيل"
+
+#~ msgid "devcp_details_header_devcomments"
+#~ msgstr "تعليقات المطوّر"
+
+#~ msgid "devcp_details_header_previews"
+#~ msgstr "المعاينات"
+
+#~ msgid "devcp_details_header_versions"
+#~ msgstr "الإصدارات"
+
+#~ msgid "devcp_details_homepage"
+#~ msgstr "صÙحة البداية"
+
+#~ msgid "devcp_details_homepage_none"
+#~ msgstr "لا يوجد"
+
+#~ msgid "devcp_details_preview_nocaption"
+#~ msgstr "لا عنوان"
+
+#~ msgid "devcp_details_previews_nonefound"
+#~ msgstr "لا يوجد معاينات."
+
+#~ msgid "devcp_details_submit_update"
+#~ msgstr "تحديث"
+
+#~ msgid "devcp_details_supportemail"
+#~ msgstr "بريد الدعم"
+
+#~ msgid "devcp_details_supportemail_none"
+#~ msgstr "لم يزوّد المطوّر بريدًا للدعم."
+
+#~ msgid "devcp_details_supporturl"
+#~ msgstr "موقع الدعم"
+
+#~ msgid "devcp_details_supporturl_none"
+#~ msgstr "لم يزوّد المطوّر موقعًا للدعم."
+
+#~ msgid "devcp_details_trusted"
+#~ msgstr "موثوق بها"
+
+#~ msgid "devcp_details_versions_none_found"
+#~ msgstr "لا إصدارات موجودة."
+
+#~ msgid "devcp_disable_cancel"
+#~ msgstr "ألغ٠وعÙد إلى الخلÙ"
+
+#~ msgid "devcp_disable_disable_button"
+#~ msgstr "نعم، عطّلها"
+
+#~ msgid "devcp_disable_disable_confirm"
+#~ msgstr "أمتأكد أنك تريد أن تعطّل الإضاÙة؟"
+
+#~ msgid "devcp_disable_disable_description"
+#~ msgstr ""
+#~ "تعطيل هذه الإضاÙØ© سيخÙيها عن البحث ومن القوائم، ولن يعود بالإمكان تنزيلها "
+#~ "من موقع الوب كما لن تظهر ÙÙŠ التماسات التحديثات عند العميل. عمليًا، ستصبح "
+#~ "الإضاÙØ© ÙÙŠ حكم المحذوÙØ©ØŒ غير أنه بإمكانك العودة إلى هنا وإعادة تمكينها "
+#~ "وقتما تشاء."
+
+#~ msgid "devcp_disable_disable_title"
+#~ msgstr "تعطيل %s"
+
+#~ msgid "devcp_disable_enable_button"
+#~ msgstr "نعم، مكّنها"
+
+#~ msgid "devcp_disable_enable_confirm"
+#~ msgstr "أمتأكد أنك تريد تمكين هذه الإضاÙة؟"
+
+#~ msgid "devcp_disable_enable_description"
+#~ msgstr ""
+#~ "تمكين هذه الإضاÙØ© سيعيد إظهارها عند البحث ÙˆÙÙŠ القوائم. سيصبح تنزيلها "
+#~ "ممكنًا من موقع الوب أو عن طريق التماس التحديث من Ù‚Ùبَل العميل."
+
+#~ msgid "devcp_disable_enable_title"
+#~ msgstr "تمكين %s"
+
+#~ msgid "devcp_edit_author_add"
+#~ msgstr "أض٠المؤلÙ"
+
+#~ msgid "devcp_edit_author_email"
+#~ msgstr "بريد المؤل٠الإلكتروني"
+
+#~ msgid "devcp_edit_author_remove"
+#~ msgstr "أزÙÙ„"
+
+#~ msgid "devcp_edit_error_categories_unavailable"
+#~ msgstr "لا يوجد تصنيÙات متاحة لهذا النوع من الإضاÙات."
+
+#, fuzzy
+#~ msgid "devcp_edit_file_error_incomplete"
+#~ msgstr "Incomplete transfer"
+
+#, fuzzy
+#~ msgid "devcp_edit_file_error_no"
+#~ msgstr "No file uploaded"
+
+#, fuzzy
+#~ msgid "devcp_edit_file_error_size"
+#~ msgstr "Exceeds maximum upload size"
+
+#~ msgid "devcp_edit_header_authors"
+#~ msgstr "المؤلÙون"
+
+#~ msgid "devcp_edit_icon_add_link"
+#~ msgstr "أضÙ٠أيقونة"
+
+#~ msgid "devcp_edit_icon_change_link"
+#~ msgstr "غيّر الأيقونة"
+
+#~ msgid "devcp_edit_label_allow_viewsource"
+#~ msgstr "اسمح للمستخدمين بتصÙØ­ مصدر المل٠وهم على اتصال"
+
+#~ msgid "devcp_edit_label_categories"
+#~ msgstr "التصنيÙات"
+
+#~ msgid "devcp_edit_label_defaultlocale"
+#~ msgstr "اللغة المبدئية"
+
+#~ msgid "devcp_edit_label_icon_delete"
+#~ msgstr "امسح Ùقط الأيقونة الموجودة"
+
+#~ msgid "devcp_edit_label_icon_new"
+#~ msgstr "مل٠أيقونة جديد"
+
+#~ msgid "devcp_edit_label_info"
+#~ msgstr "أيقونة"
+
+#~ msgid "devcp_edit_locale_disambiguation_explanation"
+#~ msgstr "قليل من المعلومات الإضاÙية (مثل اسم اللهجة المحلية)"
+
+#~ msgid "devcp_edit_submit_update"
+#~ msgstr "حدّث"
+
+#~ msgid "devcp_edit_target_locale_explanation"
+#~ msgstr ""
+#~ "<a href=\"http://wiki.mozilla.org/L10n:Simple_locale_names\">الاسم "
+#~ "المختصر للغة</a>، مثل 'ar'"
+
+#~ msgid "devcp_editversion_checkedfiles_delete"
+#~ msgstr "الملÙات المؤشّر عليها سو٠تÙحذÙ."
+
+#~ msgid "devcp_editversion_filename_size"
+#~ msgstr "%1$s (%2$s)"
+
+#~ msgid "devcp_editversion_label_files"
+#~ msgstr "الملÙات"
+
+#~ msgid "devcp_editversion_label_targetapps"
+#~ msgstr "التطبيقات الهدÙ"
+
+#~ msgid "devcp_editversion_nofiles"
+#~ msgstr "لا ملÙات."
+
+#~ msgid "devcp_editversion_reviewernotes"
+#~ msgstr "ملاحظات إلى المراجع"
+
+#~ msgid "devcp_editversion_submit_update"
+#~ msgstr "حدّث"
+
+#~ msgid "devcp_error_addon_field_summary_toolong"
+#~ msgstr ""
+#~ "الملخصات محدودة بعدد حرو٠أقصى هو 250 حرÙًا.\n"
+#~ "(لقد أدخلتَ %s)"
+
+#~ msgid "devcp_error_addonname_not_unique"
+#~ msgstr ""
+#~ "اسم الإضاÙØ© موجود مسبقًا ÙÙŠ قاعدة البيانات. رجاءً تأكد أن: <br /"
+#~ "><li>المعرّÙات الÙريدة متطابقة، إذ أن السبب الشائع لهذا الخطأ هو عدم تطابق "
+#~ "المعرّÙات الÙريدة.</li><li>ليس لديك إدخال آخر بنÙس الاسم ÙÙŠ قاعدة "
+#~ "البيانات. إن كان لديك واحد، Ùعليك تحديثه، أو حذÙÙ‡ والمحاولة من جديد.</li>"
+
+#~ msgid "devcp_error_describe_changes"
+#~ msgstr "صÙ٠رجاءً التعديلات التي يتضمنها تحديث هذه الإضاÙØ©."
+
+#~ msgid "devcp_error_file_guids_dont_match"
+#~ msgstr "ليست كل معرّÙات الملÙات الÙريدة متطابقة"
+
+#~ msgid "devcp_error_identical_version_exists"
+#~ msgstr "هناك إصدارة مشابهة (%s) موجودة مسبقًا من هذه الإضاÙØ© لهذه المنصة."
+
+#~ msgid "devcp_error_nominate_message"
+#~ msgstr "يجب أن تزوّد التÙاصيل المطلوبة من أجل الترشيح."
+
+#~ msgid "devcp_error_nominate_no_prerelease"
+#~ msgstr "لا يمكنك ترشيح إضاÙØ© ÙÙŠ مرحلة ما قبل الإصدار."
+
+#~ msgid "devcp_error_nominate_sandbox_only"
+#~ msgstr "يمكنك ترشيح الإضاÙات التي ÙÙŠ ساحة اللعب Ùقط."
+
+#~ msgid "devcp_error_saving"
+#~ msgstr "حصل خطأ عند محاولة Ø­Ùظ بياناتك."
+
+#~ msgid "devcp_error_update_access_denied"
+#~ msgstr "أنت لا تملك الصلاحيات لتحديث هذه الإضاÙØ©."
+
+#~ msgid "devcp_file_addanother"
+#~ msgstr "أضÙ٠مل٠منصة تشغيل آخر"
+
+#~ msgid "devcp_form_author_add"
+#~ msgstr "أضÙ٠مؤلÙًا"
+
+#~ msgid "devcp_form_author_remove"
+#~ msgstr "أزÙÙ„"
+
+#~ msgid "devcp_form_categories_nextstep"
+#~ msgstr "تصنيÙات نوع الإضاÙØ© الجديد ستكون متاحة ÙÙŠ الخطوة التالية."
+
+#~ msgid "devcp_form_error_categories_unavailable"
+#~ msgstr "لا تصنيÙات متاحة لهذا النوع من الإضاÙات."
+
+#~ msgid "devcp_form_error_description_notempty"
+#~ msgstr "رجاءً أدخÙÙ„ وصÙًا لإضاÙتك."
+
+#~ msgid "devcp_form_error_name_required"
+#~ msgstr "رجاءً أدخÙÙ„ اسمًا لإضاÙتك."
+
+#~ msgid "devcp_form_error_select_addontype"
+#~ msgstr "اختر رجاءً نوع الإضاÙØ© التي ترسلها."
+
+#~ msgid "devcp_form_error_summary_notempty"
+#~ msgstr "أدخÙÙ„ رجاءً ملخصًا لإضاÙتك."
+
+#~ msgid "devcp_form_label_addonfile"
+#~ msgstr "مل٠الإضاÙØ©"
+
+#~ msgid "devcp_form_label_addonfile2"
+#~ msgstr "مل٠الإضاÙØ© 2"
+
+#~ msgid "devcp_form_label_addonfile3"
+#~ msgstr "مل٠الإضاÙØ© 3"
+
+#~ msgid "devcp_form_label_addontype"
+#~ msgstr "نوع الإضاÙØ©"
+
+#~ msgid "devcp_form_label_allow_viewsource"
+#~ msgstr "اسمح للمستخدمين برؤية مصدر الملÙات وهم على اتصال"
+
+#~ msgid "devcp_form_label_author_email"
+#~ msgstr "بريد المؤل٠الإلكتروني"
+
+#~ msgid "devcp_form_label_authors"
+#~ msgstr "المؤلÙون"
+
+#~ msgid "devcp_form_label_categories"
+#~ msgstr "التصنيÙات"
+
+#~ msgid "devcp_form_label_defaultlocale"
+#~ msgstr "اللغة المبدئية"
+
+#~ msgid "devcp_form_label_description"
+#~ msgstr "الوصÙ"
+
+#~ msgid "devcp_form_label_eula"
+#~ msgstr "اتÙاقية ترخيص المستخدم (EULA)"
+
+#~ msgid "devcp_form_label_externalsoftware"
+#~ msgstr "هذه الإضاÙØ© تتطلب برنامجًا خارجيًا"
+
+#~ msgid "devcp_form_label_files"
+#~ msgstr "الملÙات"
+
+#~ msgid "devcp_form_label_homepage"
+#~ msgstr "صÙحة البداية"
+
+#~ msgid "devcp_form_label_iconfile"
+#~ msgstr "مل٠الأيقونة"
+
+#~ msgid "devcp_form_label_name"
+#~ msgstr "الاسم"
+
+#~ msgid "devcp_form_label_platforms"
+#~ msgstr "منصات التشغيل المدعومة"
+
+#~ msgid "devcp_form_label_prerelease"
+#~ msgstr "هذه ما-قبل-إصدارة"
+
+#~ msgid "devcp_form_label_privacy"
+#~ msgstr "سياسة الخصوصية"
+
+#~ msgid "devcp_form_label_sitespecific"
+#~ msgstr "هذه إضاÙØ© خاصة بمواقع معينة"
+
+#~ msgid "devcp_form_label_summary"
+#~ msgstr "الملخص"
+
+#~ msgid "devcp_form_label_supportemail"
+#~ msgstr "بريد الدعم"
+
+#~ msgid "devcp_form_label_supporturl"
+#~ msgstr "موقع الدعم"
+
+#~ msgid "devcp_form_label_target_applications"
+#~ msgstr "التطبيقات الهدÙ"
+
+#~ msgid "devcp_form_label_version"
+#~ msgstr "الإصدارة"
+
+#~ msgid "devcp_form_label_versionnotes"
+#~ msgstr "ملاحظات الإصدارة"
+
+#~ msgid "devcp_form_no_target_apps"
+#~ msgstr "لا شيء"
+
+#~ msgid "devcp_form_reviewernotes"
+#~ msgstr "ملاحظات للمÙراجع"
+
+#~ msgid "devcp_form_trustedaddon_destination"
+#~ msgstr ""
+#~ "لأنّ إضاÙتك موثوق بها، ÙŠÙرجى منك اختيار المكان الذي ستذهب إليه هذه الإصدارة:"
+
+#~ msgid "devcp_form_trustedaddon_destination_public"
+#~ msgstr "الساحة العامة"
+
+#~ msgid "devcp_form_trustedaddon_destination_sandbox"
+#~ msgstr "ساحة اللعب"
+
+#~ msgid "devcp_header_developer_agreement"
+#~ msgstr "اتÙاقية المطوّر"
+
+#~ msgid "devcp_header_step1"
+#~ msgstr "الخطوة الأولى"
+
+#~ msgid "devcp_header_step1_upload"
+#~ msgstr "رÙع الملÙ"
+
+#~ msgid "devcp_header_step2"
+#~ msgstr "الخطوة الثانية"
+
+#~ msgid "devcp_header_step2_addondetails"
+#~ msgstr "تÙاصيل الإضاÙØ©"
+
+#~ msgid "devcp_header_step3"
+#~ msgstr "الخطوة الثالثة"
+
+#~ msgid "devcp_header_step3_versiondetails"
+#~ msgstr "تÙاصيل الإصدارة"
+
+#~ msgid "devcp_header_step4"
+#~ msgstr "الخطوة الرابعة"
+
+#~ msgid "devcp_header_step4_localization"
+#~ msgstr "الترجمة"
+
+#~ msgid "devcp_header_step5"
+#~ msgstr "الخطوة الخامسة"
+
+#~ msgid "devcp_header_step5_success"
+#~ msgstr "نجاح"
+
+#~ msgid "devcp_index_header_myaddons"
+#~ msgstr "إضاÙاتي"
+
+#~ msgid "devcp_nominate_link_returnto_details"
+#~ msgstr "عÙد إلى تÙاصيل الإضاÙØ©"
+
+#~ msgid "devcp_notice_autodetected_addontype"
+#~ msgstr "نوع الإضاÙØ© المكتشَ٠آليًا: %s."
+
+#~ msgid "devcp_notice_different_defaultlocale"
+#~ msgstr ""
+#~ "اللغة الاÙتراضية لهذه الإضاÙØ© (%1$s [%2$s]) تختل٠عن لغتك التي اخترتها (%3"
+#~ "$s [%4$s]). يجب أن تÙكمل الحقول أدناه باللغة %1$s."
+
+#~ msgid "devcp_question_addontype_incorrect"
+#~ msgstr "غير صحيح؟"
+
+#~ msgid "devcp_question_delete_file"
+#~ msgstr "أمتأكد أنك تريد حذ٠هذا الملÙØŸ"
+
+#~ msgid "devcp_skip_reviewing_addon_info"
+#~ msgstr "تغاضَ عن تحديث معلوماتي الحالية عن الإضاÙØ©"
+
+#~ msgid "devcp_submissions_disabled"
+#~ msgstr "إرسال الإضاÙات معطل حاليًا. ÙŠÙرجى إعادة المحاولة لاحقًا."
+
+#~ msgid "devcp_submit_accept_dev_agreement"
+#~ msgstr "أواÙÙ‚"
+
+#~ msgid "devcp_submit_decline_dev_agreement"
+#~ msgstr "أرÙض"
+
+#~ msgid "devcp_summary_admin_disabled"
+#~ msgstr "لقد عطّل المدير هذه الإضاÙØ©."
+
+#~ msgid "devcp_summary_header_disabled"
+#~ msgstr "معطّلة"
+
+#~ msgid "devcp_summary_header_trusted"
+#~ msgstr "موثوق بها"
+
+#~ msgid "devcp_summary_noaddons_submit_one"
+#~ msgstr "أنت لا تملك أي إضاÙات. انقر %s لإرسال واحدة."
+
+#~ msgid "devcp_summary_noaddons_submit_one_link"
+#~ msgstr "هنا"
+
+#~ msgid "devcp_theme_upload_preview"
+#~ msgstr "تأكّد رجاءً من %s Ù„ÙسÙمَتÙÙƒ."
+
+#~ msgid "devcp_theme_upload_preview_link"
+#~ msgstr "رÙع معاينة"
+
+#~ msgid "devcp_version_edit_pagetitle"
+#~ msgstr "تحرير الإصدارة"
+
+#~ msgid "devcp_version_updated_successfully"
+#~ msgstr "Ø­Ùدّثت الإصدارة بنجاح."
+
+#~ msgid "editors_submissiontype_new"
+#~ msgstr "جديد"
+
+#~ msgid "editors_submissiontype_updated"
+#~ msgstr "Ù…Ùحدَّث"
+
+#, fuzzy
+#~ msgid "editors_th_addon_age"
+#~ msgstr "Addon Age"
+
+#~ msgid "editors_th_addontypes"
+#~ msgstr "أنواع الإضاÙات"
+
+#~ msgid "editors_th_age"
+#~ msgstr "العمر"
+
+#~ msgid "editors_th_applications"
+#~ msgstr "التطبيقات"
+
+#~ msgid "editors_th_platforms"
+#~ msgstr "المنصات"
+
+#~ msgid "editors_th_submissiontypes"
+#~ msgstr "أنواع الإرسال"
+
+#~ msgid "error_notice"
+#~ msgstr "ملاحظة"
+
+#~ msgid "forum_save"
+#~ msgstr "احÙظ"
+
+#, fuzzy
+#~ msgid "home"
+#~ msgstr "home"
+
+#~ msgid "nav_category_plugins"
+#~ msgstr "الملحقات"
+
+#~ msgid "page_title_experimental_addons"
+#~ msgstr "الإضاÙات التجريبية"
+
+#~ msgid "pages_experimental_addons_backbutton"
+#~ msgstr "عودة إلى الصÙحة السابقة"
+
+#~ msgid "pagination_page_number_title"
+#~ msgstr "هذه هي الصÙحة %1$s من اصل %2$s"
+
+#~ msgid "search_matching_addons_number"
+#~ msgid_plural "search_matching_addons_number"
+#~ msgstr[0] "لا إضاÙات مطابقة"
+#~ msgstr[1] "إضاÙØ© واحدة مطابقة"
+#~ msgstr[2] "إضاÙتان مطابقتان"
+#~ msgstr[3] "%s إضاÙات مطابقة"
+#~ msgstr[4] "%s إضاÙØ© مطابقة"
+#~ msgstr[5] "%s إضاÙØ© مطابقة"
+
+#~ msgid "statistics_rss_icon_title"
+#~ msgstr "تلقيم RSS لبيانات الملخص"
diff --git a/site/app/locale/ar/images/sandbox-review.png b/site/app/locale/ar/images/sandbox-review.png
new file mode 100644
index 0000000..f97825c
--- /dev/null
+++ b/site/app/locale/ar/images/sandbox-review.png
Binary files differ
diff --git a/site/app/locale/ar/pages/error404.thtml b/site/app/locale/ar/pages/error404.thtml
new file mode 100644
index 0000000..1bad2f0
--- /dev/null
+++ b/site/app/locale/ar/pages/error404.thtml
@@ -0,0 +1,16 @@
+<h1>عذرًا، ولكنا لم نستطع إيجاد ما تبحث عنه</h1>
+
+<p>الصÙحة التي تبحث عنها غير موجودة ÙÙŠ موقعنا. من المحتمل أنك نقرت على وصلة قديمة، أو أدخلت العنوان بشكل غير صحيح.</p>
+
+<ul>
+<li>إن كنت أنت من كتب العنوان، تحقق مرة أخرى من عدم وجود خطأ Ùيه.</li>
+<li>إن كنت قد نقرت على وصلة ÙÙŠ مكان ما، ÙأعلÙمنا بذلك من خلال <a href="mailto:webmaster@mozilla.com" title="صÙحة غير موجودة ÙÙŠ Mozilla.com">webmaster@mozilla.com</a>. أخبرنا بالضبط ÙÙŠ أيّ موقع كنت وما الذي كنت تبحث عنه، وسنبذل جهدنا لحل المشكلة.</li>
+</ul>
+
+<p>أو بإمكانك ببساطة أن تجرّب الاطلاع على بعض الصÙحات الشعبية ÙÙŠ موقعنا.</p>
+
+<ul>
+<li>هل يهمك أن تطّلع على <a href="%1$s">قائمة من الإضاÙات الشعبية</a>ØŸ</li>
+<li>هل تريد أن <a href="%2$s">تبحث عن إضاÙات</a>ØŸ يمكنك الذهاب إلى <a href="%2$s">صÙحة البحث</a> أو استخدام حقل البحث ÙÙŠ الأعلى.</li>
+<li>إن كنت تÙضل الانطلاق من البداية، Ùعليك بالتوجه إلى <a href="%3$s">صÙحة واجهة الإضاÙات</a>.</li>
+</ul>
diff --git a/site/app/locale/ar/pages/nomination.thtml b/site/app/locale/ar/pages/nomination.thtml
new file mode 100644
index 0000000..cc79917
--- /dev/null
+++ b/site/app/locale/ar/pages/nomination.thtml
@@ -0,0 +1,10 @@
+<p>يمكن ترشيح إضاÙØ© موجودة حاليًا ÙÙŠ ساحة اللعب لتصبح جزءًا ÙÙŠ الموقع العام ومتاحة لجميع المستخدمين بعد أن تخضع لمراجعة أحد المحرّرين. للحصول على Ø£Ùضل النتائج، ÙŠÙرجى ملاحظة التالي:</p>
+<ul>
+ <li>صور المعاينات مطلوبة للسمات، ومنصوح بها بشدّة لانواع الإضاÙات الأخرى.</li>
+ <li>ينبغي أن تمضي الإضاÙØ© وقتًا كاÙيًا ÙÙŠ ساحة اللعب لتحصل عى المراجعات والتعليقات من Ù‚Ùبَل المستخدمين. <b>المراجعات مطلوبة لكي تصبح الإضاÙØ© ÙÙŠ الساحة العامة.</b></li>
+ <li>الإضاÙات العامة لديها شريط جودة أكبر من إضاÙات ساحة اللعب، وينبغي عليها أن تحسّن الوب.</li>
+ <li>معايير الترشيح الكاملة متاحة ÙÙŠ <a href="%s">سياسة الإضاÙØ©</a>.</li>
+</ul>
+<p>إن كانت المعايير أعلاه تنطبق على إضاÙتك، يمكنك ترشيحها من خلال إكمال الحقل أدناه. سيتمّ تنبيهك بريديًا بخصوص حالة الترشيح.</p>
+
+<p>لترشيح إضاÙتك، ÙŠÙرجى منك أن تصÙ٠كي٠تمّ اختبارها (ويتضمّن ذلك أنها خالية من الأخطاء والتحذيرات)ØŒ وكي٠ستكون Ù…Ùيدة لشبكة الوب الواسعة. يمكنك أن تضي٠أيضًا وصلات لمراجعات خارجية لإضاÙتك..</p>
diff --git a/site/app/locale/ar/pages/policy.thtml b/site/app/locale/ar/pages/policy.thtml
new file mode 100755
index 0000000..709a2c2
--- /dev/null
+++ b/site/app/locale/ar/pages/policy.thtml
@@ -0,0 +1,110 @@
+<h1>سياسة الإضاÙات</h1>
+
+<h2>ما هي ساحة اللعب؟</h2>
+<p>راجع %s.</p>
+
+<h2>ما الإضاÙات التي تكون ÙÙŠ ساحة اللعب؟</h2>
+<p>ساحة اللعب هي مكان وضع جميع الإضاÙات التي يستضيÙها الموقع ÙÙŠ البداية؛ إنها تحتوي على الإصدارات الحديثة من الإضاÙات العامة، وجميع إصدارات الإضاÙات التي لم تصبح عامة بعد.عندما تÙرسل إضاÙØ© جديدة أو تحديث لإضاÙØ© موجودة إلى الموقع، تÙوضع عندئذ ÙÙŠ ساحة اللعب.</p>
+
+<p>بعض الإضاÙات وإصدارات معينة لها تصبح عامة إذا نتج عن عملية مراجعتها أنها صالحة لتÙنشر على الملأ. أما بقية الإضاÙات Ùتبقى ÙÙŠ ساحة اللعب، حيث يمكن للمستخدمين تصÙØ­ اللائحة هناك واختبار تلك الإضاÙات.</p>
+
+<h2>كي٠تصبح الإضاÙات عامة؟</h2>
+
+<p>بعض المساهمين من مستخدمي موقع الإضاÙات يراجعون الإضاÙات الموجودة ÙÙŠ ساحة اللعب ويختبرون الحزمات الموجودة هناك. ستحدد المراجعات التي يكتبها مستخدمو الموقع Ùيما إذا كانت الإضاÙØ© Ù…Ùيدة ÙƒÙاية ومكتوبة بشكل جيد وجاهزة لطرحها أمام جميع مستخدمي ÙَيَرÙÙكس. هذه المراجعات، إضاÙةً إلى مراجعات أخرى وتحريات يجريها Ùريق موقع الإضاÙات، ستحدد إن كانت الإضاÙØ© ستصبح عامة، أو إن كانت تحتاج المزيد من التحسين قبل أن تÙنشر على الملأ، أو Ùيما إذا كانت غير صالحة للترقية إلى إضاÙØ© عامة ÙÙŠ موقع الإضاÙات.</p>
+
+<h2>كي٠أستطيع ترقية إضاÙتي لتصبح عامة؟</h2>
+
+<p>إن كنت تعتقد أنّ إضاÙتك (وسلوكك!) يتواÙقان مع معايير الإضاÙØ© العامة، يمكنك عندئذ ترشيح الإضاÙØ© من خلال أدوات المطوّر.</p>
+
+<h2>ما هي معايير الإضاÙات العامة؟</h2>
+
+<p>يجب أن تكون الإضاÙØ© العامة ÙÙŠ موقع الإضاÙات ذات جودة عالية، وتزيد من خبرة المستخدمين ÙÙŠ الوب. نحن نركّز على الأمور التالية عند اتخاذ القرار بوضع الإضاÙØ© ÙÙŠ الساحة العامة أو لا:</p>
+
+<h3>هل أنت متجاوب؟</h3>
+
+<p>نحن نتوقع من المؤل٠الذي يرقي إضاÙته أن يكون متجاوبًا مع بلاغات المشكلات، وأن يبقي معلةمات الاتصال به متوÙرة، وأن يحدّث إضاÙته باستمرار لتتماشى من إصدارات ÙَيَرÙÙكس والتغييرات ÙÙŠ سياسات موقع الإضاÙات. هذا لا يعني أنّ عليك أن تجيب على كل سؤال ÙŠÙطرح ÙÙŠ المناقشات، أو أن تصلح كل علة ÙŠÙبلَّغ عنها، ولكننا نتوقع منك التجاوب بشكل يتلاءم مع خطورة المشكلة التي تÙبلَّغ إليك.</p>
+
+<h3>هل وص٠الإضاÙØ© واضح ودقيق؟</h3>
+
+<p>من المهم جدًا لنا أن يحصل المستخدمون على ما يتوقعونه عند تجربتهم لإضاÙØ© جديدة. يجب أن يحتوي وصÙÙƒ على تÙاصيل ما تÙعله الإضاÙØ© وكي٠يستطيع المستخدم الاستÙادة منها وماذا عليه أن يتوقع عند تثبيتها. لا بأس بوضع وصلات إلى مستندات خارجية Ùيها تÙاصيل أكثر، ولكن ينبغي أن يشمل الوص٠جميع الأساسيات ويجعل المستخدم على ثقة من معرÙته بما سيحصل عليه.</p>
+
+<p>من المهم أيضًا أن تعتني بملاحظات الإصدارات بشكل مناسب كلما حسّنتَ وغيّرتَ ÙÙŠ إضاÙتك. المطلوب أن يتمكن المستخدمون من معرÙØ© ما هو جديد ÙÙŠ إضاÙØ© قد يكونوا جربوها قديمًا، وأن يعلموا بالتغييرات التي قد تؤثر ÙÙŠ استخدامهم الحالي للإضاÙØ© بعد تحديثها. (حاليًا، لا يرى المستخدمون ملاحظات الإصدار عند حثهم على تحديث الإضاÙØ© ÙÙŠ المتصÙØ­ØŒ ولكننا سنعمل على حل هذا. إن اعتنيت بملاحظات الإصدارات جيدًا ÙستÙيد مستخدميك كثيرًا قبل إتمام هذا العمل وبعده).</p>
+
+<h3>هل Ø°Ùكرتْ جميع اعتبارات الأمن والخصوصية بوضوح؟</h3>
+
+<p>هذا ÙŠÙعدّ ضمن مظاهر الوص٠الواضح والدقيق، ولكن أحببنا أن Ù†Ùرده بكلام خاص نظرًا لأهميته. بعض الإضاÙات المÙيدة والمهمة جدًا تتعامل مع بيانات المستخدم أو قد تؤدي إلى ثغرات أمنية إن Ø£Ùسيء استخدامها. هذا النوع من الإضاÙات مقبول ÙÙŠ الساحة العامة من موقع الإضاÙات، ولكن يجب عليها أن توضح للمستخدمين المخاطر التي قد يواجهونها، وكي٠يستطيعون حماية أنÙسهم من ذلك.</p>
+
+<h3>هل اختÙبرتْ الإضاÙØ© جيدًا، وهل هي خالية من العيوب الواضحة أو الجديّة؟</h3>
+
+<p>أحد الأمور الهامة التي نأخذها بعين الاعتبار عند نقل إضاÙØ© إلى الساحة العامة هو Ùيما إذا كانت مراجعات ساحة اللعب تشير إلى أن الإضاÙØ© اختÙبرت بشكل شامل، وأن ليس Ùيها مشكلات خطيرة أو تأثيرات سلبية على المتصÙØ­. إن بلّغ المراجعون عن مشكلات أساسية ÙÙŠ الأداء أو انهيارات أو مشكلات متكررة عند استخدام وظائ٠الإضاÙØ© أو رسائل كثيرة ÙÙŠ معراض الأخطاء، ينبغي عليك حينئذ أن تضع حلّ هذه المشكلات Ù†Ùصب عينيك، وأن تعيد ترشيح الإضاÙØ© بعد أن تبذل ما بوسعك لإزالة المشكلات. لسنا نطلب منك أن تكون إضاÙتك نقية من العلل تمامًا -- يخضع ÙَيَرÙÙكس إلى تحسين مستمر ÙÙŠ هذه المجالات -- ولكننا نريد ان تبذل جهودًا معتبرة ÙÙŠ تقليل النواحي السلبية، وتوضيح العلل الأخرى التي قد يتÙاجأ المستخدمون بوجودها.</p>
+
+<p>إن اختÙبرت إضاÙتك خارج ساحة لعب موقع الإضاÙات، من Ù‚Ùبَل مجموعة من مستخدمي خدمتك أو Ùريق تأكد من الجودة تابع لك مثلًا، Ùعليك أن تشير إلى ذلك ÙÙŠ رسالة ترشيحك. ذلك سيÙيدنا حتمًا ÙÙŠ معرÙØ© مستوى ذلك الاختبار، كما سيساعد ÙÙŠ إيصال إضاÙتك إلى الموقع العام.</p>
+
+<h3>هل الإضاÙØ© ومؤلÙها يعاملان المستخدم باحترام؟</h3>
+
+<p>ينبغي أن لا يتدخل برنامجك ÙÙŠ شؤون المستخدم أو يحاول خداعه أو يخÙÙŠ أيًا من نشاطاته عنه. أحيانًا يكون المستخدمون (وغير المستخدمين) وقحين ÙÙŠ ردودهم، ورغم أننا نحاول جهدنا تصÙية هذه التعليقات عندما Ù†Ùبلَّغ عنها، Ùإننا نتوقع من المؤلÙين تجنّب الردّ بأسلوب وقح انتقامي.</p>
+
+<h3>هل الإضاÙØ© Ù…Ùيدة لقسم لا بأس به من مستخدمي ÙَيَرÙÙكس؟</h3>
+
+<p>ليس بالضرورة أن تكون إضاÙتك مثل Greasemonkey أو FirebugØŒ ولكن إن كانت Ùائدتها محصورة بالأشخاص الذين يعملون ÙÙŠ شركتك أو بجزء صغير من مجتمع الوب Ùقد نشعر أنه من غير الملائم طرحها أمام جميع مستخدمي ÙَيَرÙÙكس.</p>
+
+<p>نحن نبحث باستمرار عن طرق تحسين تنظيم الموقع لمواكبة Ø£Ùضل للإضاÙات التي تكون نموذجية من نواح٠أخرى ولكنها موجّهة إلى عدد قليل من المستخدمين الممكنين. سيساعدنا التصني٠الصحيح لإضاÙتك واعتناؤك ببيانات التعري٠على معرÙØ© كي٠نوصÙÙ„ هذا النوع من الإضاÙات إلى الأشخاص الذين ÙŠÙرجَّح استÙادتهم منها.</p>
+
+<p>إن كانت إضاÙتك تحتوي علامات مرجعية أو وصلات لموقعك، Ùمن غير المرجّح أن تكون ملائمة للعرض ÙÙŠ القسمالعام من الموقع. نحن نحب تطبيقات الوب وخدمات الوب الجديدة - كما ÙÙŠ باقي أقسام مشروع موزيلا - ولكن هد٠إضاÙات ÙَيَرÙÙكس أن تزيد خبرة الوب عند المستخدم، لا أن تكون مجرد وسيلة للإعلان عن موقع أو خدمة جديدين من خلال قوائم موقع الإضاÙات. إن كان وصÙÙƒ للإضاÙØ© متركزًا على الخدمة أكثر من التحسينات التي ستأخذ مكانها ÙÙŠ خبرة تصÙØ­ المستخدم، Ùمعنى هذا أنك لستَ على الطريق الصحيح على الأرجح.</p>
+
+<h3>هل الإضاÙØ© خالية من حقوق النسخ أو العلامات التجارية غير المرخصة؟</h3>
+
+<p>رغم أنك قد لا تتعمد إلحاق الضرر بصاحب العلامة التجارية أو بمالك عمل له حقوقه، إلا أنه ليس بوسعنا استضاÙØ© الإضاÙات التي تنتهك العلامات التجارية أو حقوق النسخ. لذا إن كنت لا تملك إذنًا باستخدام اسم أو صورة لعلامة تجارية، Ùلا ترسل إضاÙتك إلى موقع الإضاÙات. إن احتوت إضاÙتك على كود تتبع حقوقه لشخص آخر وليس مسموحًا لك باستخدامها ÙÙŠ إضاÙتك، Ùلا ترسل إضاÙتك إلينا كذلك. (عندما يعترض مالك الحقوق أو العلامة التجارية على استخدامها، سنقدّم طلبًا ÙÙŠ الغالب لإزالتها يراجعه المجلس، وسنزيل الإضاÙØ© إن اعتÙبر ذلك ضروريًا من الناحية القانونية. هذا الإجراء مكل٠من ناحية الوقت والمال، لذا نرجو منك أن تطبّق هذا البند وتعÙينا من الصعوبات غير المطلوبة).</p>
+
+<p>إن كنت غير متأكد Ùيما إذا كان اسم إضاÙتك أو شيء بداخلها قد يمنعها من أن تÙعرض ÙÙŠ قوائم الموقع، يمكنك استشارة amo-editors@mozilla.org وطلب رأيهم. مهم: ÙŠÙرجى ملاحظة أن هذه المجمعة غير قادرة على إعطاء استشارة قانونية، وحتى لو واÙقت على Ùعلك Ùقد تضطر لتغيير قرارها ÙÙŠ حال وجود شكاوى من مالكي الحقوق أو إرشاد من المجلس القانوني.</p>
+
+<p>بخصوص إعادة استخدام كود من إضاÙات أخرى، إن لم ينصّ المؤل٠بوضوح على السماح لك باستخدام ما كتبه ÙÙŠ عملك الخاص - عن طريق ترخيص عمله برخصة حرة مثلًا - Ùعليك أن تÙترض أنه ليس لديك الحق بذلك. باستطاعتك التواصل مع المؤل٠لطلب هذا الإذن، ولكن لا يمكننا إعطاؤك أي حقوق خاصة لأن إضاÙتك موجودة ÙÙŠ موقع الإضاÙات أو لأن المؤل٠لا يردّ على طلبك. (من جديد، لا نستطيع تقديم استشارة قانونية، بل مجرد إرشاد عن كيÙية تÙاعل إضاÙتك مع سياسات الموقع).</p>
+
+<p>ينطبق هذا على علامات مؤسسة موزيلا التجارية كذلك، ومنها "Mozilla" Ùˆ "Firefox" Ùˆ "Thunderbird". تÙستخدم سياسة موزيلا للعلامات التجارية ÙÙŠ الحماية من التخليط ÙˆÙÙŠ منع سرقة العلامات التجارية او تشويه صورتها. احترم هذه الحاجة إلى الحماية رجاءً، وساعدْنا على المحاÙظة على بعض أثمن الأصول ÙÙŠ مؤسسة موزيلا.</p>
+
+<h2>ما الذي يحصل بعد أن أرشح شيئًا؟</h2>
+
+<p>عندما ترشح إضاÙتك، يتولى Ùريق من محرري موقع الإضاÙات تقييمها ÙˆÙقًا للمعايير المذكورة أعلاه. إن وجدوا أنها جاهزة للعرض على الملأ، ستوضع ÙÙŠ الساحة العامة حالما يكتمل تقييمها، وسيÙرسل إلك تنبيه بريدي.</p>
+
+<p>إن شعرنا أن الإضاÙØ© غير ملائمة للقسم العام من موقع الإضاÙات ÙÙŠ هذا الوقت، Ùستستلم إشعارًا بريديًا نذكر Ùيه السبب، وستÙزال إضاÙتك من طابور الترشيح. عندما تشعر أنك حللت المشكلات المذكورة ÙÙŠ ذلك الإشعار وتريد أن ÙŠÙعاد تقييم إضاÙتك، يمكنك ترشيحها مجددًا على راحتك. نحن لا ننظر بعين الرضى إلى الترشيحات المتكررة التي ليس Ùيها تحسينات ذات معنى، ÙÙعلك لذلك سيغضبنا Ùضلًا عن أنه يزيد من إتعابنا.</p>
+
+<h2>هل يمكنني ترشيح إضاÙØ© شخص آخر؟</h2>
+
+<p>نحن نطلب حاليًا من المؤلÙين أن يرشحوا إضاÙاتهم الخاصة لتصبح عامة، لأننا نريد التأكد أن المؤل٠يحسّ بأن حالة إضاÙته الحالية تؤهلها للعرض على الملأ وتعكس جودة عمله. إن كنتَ تعتقد أن الإضاÙØ© قد انتهى صقلها وأن المؤل٠ملتزم بروح ومغزى سياسة موقع الإضاÙات، وأنها ستÙيد ÙَيَرÙÙكس ومستخدمينا والوب بشكل عام، Ùالحرية لك ÙÙŠ تشجيع مؤل٠الإضاÙØ© على ترشيح إبداعه.</p>
+
+<h2>مرّ وقت طويل على إضاÙتي وهي ÙÙŠ قائمة الترشيح، Ùهل تكرهونني؟</h2>
+
+<p>نحن لا نكرهك، بل نحن نحب مطوّري الإضاÙات، ونعمل جاهدين لإسعادهم وزيادة إنتاجيتهم، لكي يستÙيد المستخدمون من أنحاء العالم من جهودهم. ولكننا نهتم بالساحة العامة من موقع الإضاÙات، Ùذلك قيمة مهمة عندنا، لذا لا يمكننا الاستعجال باتخاذ القرارات. نحن نتÙهم أن انتظارك لتقييمنا قد يكون محبطًا، ونسعى لتقليل هذا الوقت قدر الإمكان. كلما زاد الناس من وضوح مراجعاتهم ÙÙŠ ساحة اللعب، كلما كان التقييم أسهل، ويمكنك مساعدتنا ÙÙŠ هذه الناحية إن أردت.</p>
+
+<h2>اكتشÙت٠علة خطيرة ÙÙŠ إضاÙتي وأريد أن أصلحها بسرعة. ماذا عليّ أن Ø£Ùعل؟</h2>
+
+<p>ÙÙŠ حال وجود على خطيرة (ÙÙŠ الامن أو الثبات أو مشكلة ÙÙŠ وظيÙØ© أساسية) ÙÙŠ إضاÙتك وتريد تحديثها على الÙور، ينبغي عليك حينئذ ذكر ذلك ÙÙŠ "ملاحظات المطوّر" عندما ترسل التحديث، ÙˆÙÙŠ ملاحظات الإصدارة بالطبع! قد رغب أيضًا بأن تطلب من بعض مستخدمي إضاÙتك أن يجرّبوا التحديث ويبلغوا عن النتيجة بالتÙصيل ÙÙŠ ساحة اللعب. Ø°Ùكر ذلك ÙÙŠ قناة #addons ÙÙŠ irc.mozilla.org سيساعد على تعري٠الناس بالوضعية، ولكن نرجو منك أن تكون صبورًا ومهذبًا عند Ùعل ذلك.</p>
+
+<p>رجاءً لا تلعب دور الثعلب الماكر، Ùنحن نحاول أن نعجّل بالتحديثات ذات الأولوية العالية، ولكن ذلك يأخذ من وقتنا على حساب الإضاÙات والإصدارات المرشحة الأخرى، ويحرمنا غالبًا من النوم أو قضاء الوقت مع عائلتنا وأصدقائنا، لذا Ùإننا نأخذ Ùكرة سيئة عن أولئك الذين يستغلون هذا الأمر لمحاولة تجاوز دورهم ÙÙŠ الطابور. إن كنت غير متأكد هل عليك سلوك هذه الطريق ام لا، اسأل ÙÙŠ قناة #addons ÙÙŠ irc.mozilla.org وسنساعدك على اتخاذ القرار.</p>
+
+<h2>أعتقد أنني لم أعامَل بإنصا٠عند تقييم إضاÙتي. ماذا بوسعي أن Ø£Ùعل؟</h2>
+
+<p>إن كنت تعتقد أن إضاÙتك لم تÙقيَّم بشكل صحيح، وأنها Ù…Ùنعت من العرض ÙÙŠ القسم العام بطريق الخطأ، يمكنك مراسلة amo-editors@mozilla.org وذكر تÙاصيل عن سبب اعتقادك هذا. ÙƒÙÙ† مهذبًا وواضحًا ÙÙŠ رسالتك رجاءً، وتأكد من ذكر تÙاصيل إساءة الحÙكم على الإضاÙØ©.</p>
+
+<p>(إن كنت قد أصلحت *كل* المشكلات المذكورة ÙÙŠ الإشعار البريدي، Ùلا داعي حينذاك أن تحتجّ على التقييم، بل عليك أن تعيد الترشيح من خلال أدوات المطوّر ليÙعاد النظر ÙÙŠ إضاÙتك).</p>
+
+<h2>كانت إضاÙتي ÙÙŠ الساحة العامة، وهي الآن موجودة ÙÙŠ ساحة اللعب Ùقط. ما الذي حصل؟</h2>
+
+<p>إن لم تعد الإضاÙØ© تتواÙÙ‚ مع معايير وضعها ÙÙŠ الساحة العامة، Ùقد نعيدها إلى ساحة اللعب. ÙÙŠ حال عدم وجود مانع قضائي، سنبلغك بريديًا عند حصول ذلك، ذاكرين أسباب هذا الÙعل.</p>
+
+<p>من الممكن أيضًا أن سبب ذلك يعود إلى وجود علة ÙÙŠ الموقع. بلّغ عن ذلك مستخدمًا بَغزيلا (Bugzilla)ØŒ واستخدم اسم المنتج "addons.mozilla.org" واسم المكوّن "Public Pages" ÙÙŠ بلاغك، وأضÙ٠من التÙاصيل قدر ما تستطيع.</p>
+
+<h2>إضاÙتي ÙÙŠ الساحة العامة، ويبدو أن الناس معجبون بها. كي٠أستطيع ضمّها إلى قائمة الإضاÙات المنصوح بها؟</h2>
+
+<p>إن كنت ترى أنّ إضاÙتك هي نموذج لامع لقوة الإضاÙات، وأنها تبرهن وتزيد من قيمة موزيلا من وجهة نظر الوب الذي يتحكم به المستخدم، وأنها تزيد من خبرة المستخدمين، يمكنك أن تطلب وضعها ÙÙŠ قائمة الإضاÙات المنصوح بها. Ù„Ùعل ذلك، ينبغي عليك إرسال رسالة إلى amo-editors@mozilla.org توضح Ùيها سبب عظمة إضاÙتك.</p>
+
+<p>يجب أن تحتوي رسالتك <b>على الأقل</b> معلومات عن الأمور التالية:</p>
+<ul>
+<li>كيÙية زيادتها لخبرة الوب عند المستخدمين</li>
+<li>كي٠أن إضاÙتك ملائمة لقسم كبير من مستخدمي ÙَيَرÙÙكس</li>
+<li>كي٠تبرهن إضاÙتك Ùˆ/أو تخدم Ù‚ÙÙŠÙŽÙ… مشروع موزيلا، بخصوص وضع المستخدم Ù†Ùصب عينيها، وحماية الخصوصية والأمان، والوصول العالمي إلى الوب، والمعايير المÙتوحة والبيانات</li>
+<li>كي٠تختل٠إضÙاتك عن بقية الإضاÙات المشابهة (حسناتها وسيئاتها)</li>
+<li>ما هي ردات Ùعل المستخدمين والمراجعين والمدوّنين وحتى رواد الÙضاء وحيواناتك الأليÙØ© تجاه إضاÙتك، بجانبيها الإيجابي والسلبي</li>
+</ul></p>
+
+<p>كلما زادت المعلومات التي ÙÙŠ طلبك كلما زادت قدرتنا على منحك ما تطلبه، رغم أنه لا ضمان لوضع Ø£Ùضل التطبيقات وأوÙاها ÙÙŠ قائمة الإضاÙات المنصوح بها. بشكل أساسي، هذه القائمة يجب أن تكون إدارتها - وهي كذلك - تحت تصر٠موزيلا، وخبرة المستخدم وحمايته تطغى على أي شيء آخر.</p>
diff --git a/site/app/locale/ar/pages/reviewguide.thtml b/site/app/locale/ar/pages/reviewguide.thtml
new file mode 100644
index 0000000..f4dba31
--- /dev/null
+++ b/site/app/locale/ar/pages/reviewguide.thtml
@@ -0,0 +1,66 @@
+<h1>إرشادات المراجعات</h1>
+<p>مراجعات الإضاÙات هي إحدى الطرق ليتشارك مستخدمو الإضاÙات آراءهم ÙÙŠ الإضاÙات التي ثبّتوها واستخدموها. يحتÙظ المحرّرون بحق رÙض أو إزالة أي مراجعة لا تمتثل لهذه التوجيهات.</p>
+
+<div class="corner-box">
+ <h2>بعض التلميحات لكتابة مراجعة رائعة</h2>
+
+<h3><b>Ù‚ÙÙ… بالتالي:</b></h3>
+<ul>
+<li>اكتب وكأنك تخبر صديقًا عن خبرتك مع الإضاÙØ©.</li>
+<li>أبق٠المراجعات مختصرة وسهلة على الÙهم.</li>
+<li>قدّم تÙاصيل Ù…Ùيدة ومحددة. كمثال:
+<ul>
+ <li>هل عملت الإضاÙØ© كما توقعتها أن تÙعل؟</li>
+ <li>ما الميزات التي أعجبتك أو لم تعجبك؟</li>
+ <li>أكانت Ù…Ùيدة؟</li>
+ <li>أكانت سهلة الاستخدام؟</li>
+ <li>هل ستستمرّ باستخدام هذه الإضاÙة؟</li>
+</ul></li>
+
+<li>اقرأ مراجعتك لدقيقة أخرى قبل أن ترسلها، وذلك تجنبًا للأخطاء الإملائية والنحوية المحرجة.</li>
+
+<li>تجنّب ذكر مراجع مؤقتة، لأنّ المراجعات تبقى ÙÙŠ الموقع لوقت طويل.</li>
+</ul>
+
+<h3><b>لا تقÙÙ… بالتالي:</b></h3>
+<ul>
+<li>إرسال مراجعات بسيطة مثل "عظيمة!" أو "رائعة" أو "سيئة" بدون توضيحات أخرى.</li>
+<li>نشر العلل أو التبليغ عن المشكلات ÙÙŠ المراجعات. استخدم خيارات الدعم المتاحة لكل إضاÙØ©.</li>
+<li>كتابة المراجعات للإضاÙات التي لم تستخدمها بنÙسك.</li>
+<li>استخدام ألÙاظ نابية أو مخلة بالآداب، أو كتابة كلام Ùيه حقد وكراهية.</li>
+<li>تضمين HTML أو وصلات إلى برامج خبيثة أو شيÙرة مصدر أو مقتطÙات كود. المراجعات ÙˆÙضعت لتحتوي على نصّ Ùقط.</li>
+<li>الاÙتراء على مؤلÙÙŠ الإضاÙات أو الاستهزاء بهم أو شتمهم.</li>
+<li>استخدام المراجعات كوسيلة لطلب الدعم لإصدارة معينة من ÙَيَرÙÙكس (أو برنامج آخر).</li>
+<li>تضمين بريدك الإلمتروني أو رقم هاتÙÙƒ أو أيّ معلومات شخصية أخرى.</li>
+<li>نشر مراجعات لإضاÙØ© أنت أو شركتك من كتبها أو قدّمها.</li>
+</ul>
+</div>
+
+<div class="corner-box">
+ <h2>توجيهات تقييم الإضاÙات</h2>
+
+<p>ينبغي أن يكون تقييم الإضاÙات عادلاً ويعطي صورة واضحة عن جودتها ÙˆÙائدتها بشكل شامل. لا تمنحها 5 نجوم إن أعجبتك Ùˆ نجمة واحدة إن لم تعجبك، Ùالتقييم المتناسق هو جزء مهم من أيّ مراجعة.</p>
+
+<ul>
+<li><b>5 نجوم: ممتازة.</b> إضاÙØ© إلى قيامها بما تدعي القيام به، Ùهي أكثر Ùائدة بكثير من العديد من الإضاÙات الأخرى. هذه الإضاÙØ© هي على الأرجح من النوع الذي تستخدمه غالبًا وتنصح به بشدة.</li>
+<li><b>4 نجوم: جيدة.</b> Ù…Ùيدة وسهلة الاستخدام، ولكن ليس بالضرورة وجود شيء مميز Ùيها. هذه الإضاÙØ© ÙŠÙنصح بها ولكنها قد تناسب أناسًا أكثر من غيرهم.</li>
+<li><b>3 نجوم: مقبولة.</b> قد يكون Ùيها بعض المشكلات ÙÙŠ التصميم Ùˆ/أو بعض الميزات الناقصة. المشكلات التي Ùيها ليست كبيرة بحيث تنصح المرء بعدم استخدامها، Ùبعض الناس قد يجدونها Ù…Ùيدة. انصح بها الأشخاص الذين يحتاجونها ويودّون تجربتها.</li>
+<li><b>نجمتان: ضعيÙØ©.</b> الإضاÙØ© ذات جودة ضعيÙØ© ÙˆÙائدة قليلة، أو أنها لا تقوم بما تزعم أنها تÙعله. أنت لا تنصح باستخدام هذه الإضاÙØ©ØŒ مع ملاحظة أنها قد تحوي بعض الÙائدة للقليل من الناس.</li>
+<li><b>نجمة واحدة: سيئة.</b> إما أنها لا تعمل بشكل صحيح أو أنها عديمة الÙائدة تمامًا. لا يمكنك التÙكير بسبب قوي يحملك على تجربتها، كما تنصح بتجنبها بشكل كلّيّ.</li>
+</ul>
+
+<p>ليس هناك خطأ ÙÙŠ كتابة مراجعة إيجابية أو سلبية عن إضاÙØ© ما. أخبرنا Ùقط بسبب ذلك، Ùالنجوم وحدها لا تعني شيئًا إن لم تخبرنا بالسبب.</p>
+</div>
+
+<div class="corner-box">
+ <h2>الأسئلة الأكثر شيوعًا عن الإضاÙات</h2>
+
+<h3>كي٠يمكنني التبليغ عن مراجعة مسببة للمشاكل</h3>
+<p>يرجى منك التبليغ أو التأشير على هذا النوع من المراجعات بالنقر على "بلّغ عن هذه المراجعة"ØŒ وسيÙرسل بلاغك إلى الموقع للاطلاع عليه. سيستخدم المحرّرون توجيهات المراجعات لتحديد ما إذا كانوا سيحذÙون المراجعة أو يعيدونها إلى الموقع.</p>
+
+<h3>أنا مؤل٠لإضاÙØ©ØŒ هل يمكنني الردّ على المراجعات؟</h3>
+<p>نعم، مؤل٠الإضاÙØ© يمكنه أن يردّ ردًا واحدًا على كل مراجعة. إن احتاج الأمر إلى مزيد من المناقشات أو الردود، Ùلينتقل الحوار إلى منتدى الدعم أو مجموعة المناقشات.</p>
+
+<h3>أنا مؤل٠لإضاÙة،هل يمكنني حذ٠المراجعات والتقييمات غير المستحبّة؟</h3>
+<p>بشكل عام، لا. ولكن إن اكنت المراجعة تخال٠توجيهات المراجعات المذكورة ÙÙŠ الأعلى، يمكنك النقر على "بلّغ عن هذه المراجعة" ليطلع عليها أحد المحرّرين. إن كانت المراجعة تحوي شكوى لم تعد صالحة بسبب إصدارة جديدة من إضاÙتك، Ùقد ننظر ÙÙŠ أمر حذ٠هذه المراجعة. أرسÙÙ„ طلبك المÙصّل إلى amo-editors@mozilla.org.</p>
+</div>
diff --git a/site/app/locale/ar/pages/sandbox.thtml b/site/app/locale/ar/pages/sandbox.thtml
new file mode 100644
index 0000000..537d82d
--- /dev/null
+++ b/site/app/locale/ar/pages/sandbox.thtml
@@ -0,0 +1,13 @@
+<h1>نظام مراجعات ساحة اللعب</h1>
+<h2>ما هي ساحة اللعب؟</h2>
+<p>ساحة اللعب هي مساحة للمستخدمين المتقدمين ليختبروا الإضاÙات قبل مراجعتها لتصبح ÙÙŠ الاستخدام العام. للوصول إلى ساحة اللعب، عليك أن تمكّن ذلك ÙÙŠ إعدادات حسابك. يجب أن تحذر عند تثبيت إضاÙات ساحة اللعب، إذ لم يختبرها أحد المحرّرين بعد، لذا Ùقد يتعرض حاسوبك لبعض الضرر.</p>
+
+<h2>كي٠أوصÙÙ„ إضاÙتي إلى الساحة العامة؟</h2>
+<!-- To localize the flowchart image, see http://wiki.mozilla.org/Update:Remora_Sandbox_Flowchart -->
+<div style="text-align: center;">%s</div>
+<ol>
+ <li><b>أرسÙÙ„ إضاÙتك باستخدام أدوات المطوّر.</b> سو٠تظهر الإضاÙØ© مباشرة ÙÙŠ جزء "ساحة اللعب" من إضاÙات موزيلا، حيث سيختبرها المستخدمون الخبراء ويضعون ردودوهم عليها. لمشاهدة ساحة اللعب، عليك أن تمكّن ذلك من إعدادات حسابك.</li>
+ <li><b>رشّح إضاÙتك لتصبح عامة.</b> ÙÙŠ أدوات المطوّر، ستحد وصلة لترشيح إضاÙتك. بعد ترشيحها، ستظهر إضاÙتك ÙÙŠ طابور الترشيح عند المحرّر ليراجعها.</li>
+ <li><b>يراجع أحد المحرّرين إضاÙتك.</b> سيثبّت محرّر إضاÙات موزيلا إضاÙاتك ويختبر عملها. سينظر المحرّر أيضًا إلى المراجعات التي كتبها المختبرون ÙÙŠ ساحة اللعب.</li>
+ <li><b>تÙنقل إضاÙتك إلى الساحة العامة أو تبقى ÙÙŠ ساحة اللعب.</b> بد ذلك، سينقل المحرّر إضاÙتك إلى الساحة العامة أو يبقيها ÙÙŠ ساحة اللعب. إن بقيت ÙÙŠ ساحة اللعب، يمكنك إعادة ترشيحها بعد القيام بالتعديلات التي اقترحها المحرّر ÙÙŠ تعليقاته. إن Ù†Ùقلت إلى الساحة العامة، ستوضع الإصدارات المستقبلية من إضاÙتك ÙÙŠ ساحة اللعب حتى يأتي محرّر وينقلها إلى الساحة العامة. عندما تصبح إضاÙتك عامة، لا حاجة لترشيحها مجددًا، إذ ستوضع الإصدارات القادمة تلقائيًا ÙÙŠ طابور الانتظار ليراجعها أحد ما.</li>
+</ol>
diff --git a/site/app/locale/ar/pages/statistics_help.thtml b/site/app/locale/ar/pages/statistics_help.thtml
new file mode 100644
index 0000000..b4aab8e
--- /dev/null
+++ b/site/app/locale/ar/pages/statistics_help.thtml
@@ -0,0 +1,7 @@
+<h3>مساعدة</h3>
+<p>لوحة الإحصائيات تعرض البيانات المجموعة عن عدد التنزيلات والتحديثات لإضاÙتك.</p>
+<h4>التنزيلات</h4>
+<p>إحصاء التنزيلات ÙŠÙحدّث يوميًا ويشمل Ùقط عدد التنزيلات الأصلية دون التحديثات.</p>
+
+<h4>طلبات التحديثات</h4>
+<p>الإضاÙات المنزّلة من هذا الموقع تلتمس التحديثات مرة يوميًا، وعدد طلبات التحديثات هذه ÙŠÙسمّى بعدد المستخدمين النشطين يوميًا. يمكن تقسيم المستخدمين النشطين يوميًا حسب إصدارة الإضاÙØ© أو نظام التشغيل أو حالة الإضاÙØ© أو التطبيق. تÙجمع هذه المعلومات ÙÙŠ يوم واحد من كل أسبوع، وهو يوم الأربعاء.</p> \ No newline at end of file
diff --git a/site/app/locale/ar/pages/submission_help.thtml b/site/app/locale/ar/pages/submission_help.thtml
new file mode 100644
index 0000000..b464a3d
--- /dev/null
+++ b/site/app/locale/ar/pages/submission_help.thtml
@@ -0,0 +1,35 @@
+<h1>مساعدة الإرسال</h1>
+الحقول المطلوبة مكتوبة <b>بالخط العريض</b>. الخطوط الاختيارية مكتوبة <i>بالخط المائل</i>.
+<h2 id="step1">الخطوة 1: الرÙع</h2>
+<ul class="submissionHelp">
+ <li><span class="required">نوع الإضاÙØ©</span> - مبدئيًا، سيÙحدَّد نوع الإضاÙØ© تلقائيًا بناءً على المل٠المرÙوع. لا ينبغي أن تحتاج إلى تغيير هذا الحقل.</li>
+ <li><span class="required">مل٠الإضاÙØ©</span> - مل٠الحزمة الذي يحوي إضاÙاتك، متضمنًا مل٠install.rdf. إن كان هذا المل٠يعمل ÙÙŠ منصة تشغيل محددة Ùقط، سيؤدي اختيار هذه المنصة إلى السماح لك برÙع عدة ملÙات دÙعة واحدة.</li>
+ <li><span class="optional">مل٠الأيقونة</span> - ستÙعرض الأيقونة بجانب اسم الإضاÙØ© ÙÙŠ صÙحة العرض وستظهر أيضًا ÙÙŠ ناÙذة تثبيت الإضاÙØ©. سيÙعاد تحجيمها تلقائيًا إلى 32×32 بكسلاً، مع المحاÙظة على نسبة العرض إلى الطول.</li>
+ <li><span class="required">اللغة المبدئية</span> - لغة الإضاÙØ© المبدئية هي لغتها الرئيسية. إن اختار المستخدم لغة غير متاحة ÙÙŠ الإضاÙØ©ØŒ ستظهر الترجمة باللغة المبدئية.</li>
+ <li><span class="optional">تجاوز مراجعة معلومات إضاÙتي الحالية</span> - إن كنت تحدّث إضاÙØ© موجودة، سيظهر هذا الحقل أمامك. من خلال التأشير على هذا المربع، ستتمكن من التغاضي عن الخطوة الثالثة حيث إدخال معلومات متعلقة بالإصدارة.</li>
+</ul>
+
+<h2 id="step2">الخطوة 2: تÙاصيل الإضاÙØ©</h2>
+<ul class="submissionHelp">
+ <li><span class="required">الاسم</span> - اسم الإضاÙØ© باللغة المبدئية.</li>
+ <li><span class="required">المؤلÙون</span> - كل المستخدمين الذي يملكون حق تعديل مكونات الإضاÙØ© ومعلوماتها ستÙذكر أسماؤهم كمؤلÙين ÙÙŠ صÙحة العرض.</li>
+ <li><span class="required">التصنيÙات</span> - التصنيÙات التي تنتمي إليها الإضاÙØ©.</li>
+ <li><span class="optional">صÙحة البداية</span> - موقع وب الإضاÙØ© باللغة المبدئية.</li>
+ <li><span class="required">الملخص</span> - ملخص عن الإضاÙØ© باللغة المبدئية. الحد الأقصة لهذا الحقل هو 250 حرÙًا، وسيظهر ÙÙŠ صÙحة عرض الإضاÙØ©ØŒ ÙˆÙÙŠ نتائج البحث والاستعراض أيضًا.</li>
+ <li><span class="required">الوصÙ</span> - وص٠للإضاÙØ© باللغة المبدئية. سيظهر هذا ÙÙŠ صÙحة عرض الإضاÙØ© تحت الملخص.</li>
+ <li><span class="optional">اتÙاقية ترخيص المستخدم</span> - اتÙاقية ترخيص المستخدم التي ÙŠÙطلب من المستخدمين المواÙقة عليها قبل التنزيل، باللغة المبدئية.</li>
+ <li><span class="optional">سياسة الخصوصية</span> - سياسة خصوصية الإضاÙØ©ØŒ باللغة المبدئية. تشرح سياسات الخصوصية كيÙية التعامل مع معلومات المستخدم الشخصية، وستظهر وصلة لها بجانب زر التثبيت ÙÙŠ صÙحة عرض الإضاÙØ©. لمزيد من المعلومات عمّا ينبغي أن تحتويه سياسة خصوصية ÙˆÙيما إذا كانت إضاÙتك تحتاج واحدة، اقرأ <a href="%s">سياسة الإضاÙØ©</a>.</li>
+ <li><span class="optional">السماح للمستخدمين برؤية المصدر وهم على اتصال</span> - تأشير هذا المربع سيسمح للمستخدمين بتصÙØ­ ملÙات المصدر ÙÙŠ إضاÙتك مباشرة ÙÙŠ الوب.</li>
+ <li><span class="optional">هذه ما-قبل-إصدارة</span> - تأشير هذا المربع سيدلّ أن هذه الإضاÙØ© ÙÙŠ مرحلة ما قبل الإصدار أو ÙÙŠ إصدارة "بيتا". ينبغي أن تبقى الإضاÙات من نوع ما-قبل-الإصدارة ÙÙŠ ساحة اللعب، ولا يمكن ترشيحها لتصبح عامة حتى ÙŠÙزال هذا التأشير عنها.</li>
+ <li><span class="optional">هذه إضاÙØ© متعلقة بموقع محدد</span> - تأشير هذا المربع سيدلّ أنّ هذه الإضاÙØ© خاصة بموقع وب واحد، كإضاÙØ© تغيّر مظهر موقع وب معيّن أو تعرض محتوى من موقع وب محدّد. هذا الحقل Ù…Ùيد للمحرّرين، ويمكن استخدامه لتصÙية نتائج البحث ÙÙŠ المستقبل.</li>
+ <li><span class="optional">هذه الإضاÙØ© تتطلب برنامجًا خارجيًا</span> - تأشير هذا المريع يعني أن الإضاÙØ© تحتاج برنامجًا خارجيًا. هذا الحقل Ù…Ùيد للمحرّرين، ويمكن استخدامه لتصÙية نتائج البحث ÙÙŠ المستقب.</li>
+</ul>
+
+<h2 id="step3">الخطوة 3: تÙاصيل الإصدارة</h2>
+<ul class="submissionHelp">
+ <li><span class="required optional">ملاحظات الإصدارة</span> - ملخص أو لائحة بالتغييرات الحاصلة ÙÙŠ هذه الإصدارة. هذا الحقل اختياري للإرسالات الجديدة، ولكنه مطلوب للتحديثات.</li>
+ <li><span class="optional">ملاحظات إلى المÙراجع</span> - هذا الحقل ÙŠÙستخدم لإيصال بعض المعلومات للمحرّرين الذين سيراجعون إضاÙتك. معلومات حساب التجارب والملاخظات الخاصة ينبغي وضعها هنا.</li>
+</ul>
+
+<h2 id="step4">الخطوة 4: الترجمة</h2>
+هنا يمكن ترجمة حقول الإضاÙØ© إلى جميع اللغات المدعومة. اضغط على لغة ما لإدخال الترجمة. \ No newline at end of file
diff --git a/site/app/locale/ca/LC_MESSAGES/messages.mo b/site/app/locale/ca/LC_MESSAGES/messages.mo
new file mode 100644
index 0000000..c41f885
--- /dev/null
+++ b/site/app/locale/ca/LC_MESSAGES/messages.mo
Binary files differ
diff --git a/site/app/locale/ca/LC_MESSAGES/messages.po b/site/app/locale/ca/LC_MESSAGES/messages.po
new file mode 100644
index 0000000..2d8aa0a
--- /dev/null
+++ b/site/app/locale/ca/LC_MESSAGES/messages.po
@@ -0,0 +1,8027 @@
+# translation of c.po to Catalan
+# Remora Preliminary Language File
+# Copyright (C) 2006 Mozilla Corporation
+# This file is distributed under the same license as the REMORA package.
+# Catalan translators:
+# Wil Clouser <clouserw@mozilla.com>, 2006.
+# Joaquim Pérez Noguer <noguer@gmail.com>, 2007,2008.
+# Toni Hermoso Pulido <toniher@softcatala.org>, 2007.
+# Quim Perez i Noguer <noguer@gmail.com>, 2008.
+# Joaquim Perez Noguer <noguer@gmail.com>, 2009.
+msgid ""
+msgstr ""
+"Project-Id-Version: c\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2009-01-16 11:45-0800\n"
+"PO-Revision-Date: 2009-02-24 23:08+0100\n"
+"Last-Translator: Joaquim Perez Noguer <noguer@gmail.com>\n"
+"Language-Team: Catalan <gnome@lists.softcatala.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: ca\n"
+"Plural-Forms: nplurals=2; plural=n != 1;\n"
+"X-Generator: Lokalize 0.2\n"
+
+#: views/addons/policy.thtml:98
+msgid "a_cancel_installation"
+msgstr "Cancel·la la instal·lació"
+
+#. This is the text that appears on buttons to download add-ons.
+#. %$1s is an optional string that only appears if the add-on is only available for
+#. a certain platform. Examples: (Windows) or (Linux)
+#. Note that the parentheses are included in the string. :(
+#: views/elements/amo2009/install.thtml:126
+#: views/elements/amo2009/install.thtml:227
+#: views/elements/amo2009/install.thtml:257
+#: views/elements/amo2009/install.thtml:300
+#: views/elements/amo2009/install.thtml:312 views/elements/install.thtml:73
+#: views/elements/install.thtml:181 views/elements/install.thtml:205
+#: views/elements/install.thtml:248 views/elements/install.thtml:260
+#: views/addons/plugins.thtml:66 views/addons/plugins.thtml:76
+#: views/addons/plugins.thtml:86 views/addons/plugins.thtml:96
+#: views/addons/plugins.thtml:119
+#, php-format
+msgid "a_download"
+msgstr "Baixa ara el %s"
+
+#: views/addons/policy.thtml:72
+msgid "a_eula_download"
+msgstr "Accepta i baixa"
+
+#: views/addons/policy.thtml:74
+msgid "a_eula_install"
+msgstr "Accepta i instal·la"
+
+#: views/elements/header.thtml:76 views/elements/header.thtml:82
+#: views/api/api_addon.thtml:55 views/api/collections_feed.thtml:75
+#: views/sharing_api/addon.thtml:64
+msgid "a_header_public"
+msgstr "Públic"
+
+#: views/elements/header.thtml:58 views/elements/header.thtml:75
+#: views/elements/header.thtml:80 views/api/api_addon.thtml:57
+#: views/api/collections_feed.thtml:77 views/sharing_api/addon.thtml:66
+msgid "a_header_sandbox"
+msgstr "Entorn de proves"
+
+#. %s is a date in the _('date') format
+#: views/elements/amo2009/homepage_addon.thtml:115
+#: views/elements/addon_listitem.thtml:122 views/elements/feature.thtml:106
+#: views/addons/display.thtml:104 views/addons/browse_thumbs.thtml:73
+msgid "addon_detail_last_updated"
+msgstr "Actualitza %s"
+
+#. %s is the version of the add-on. Example: 3.2a1
+#: views/elements/amo2009/addon_version_detail.thtml:51
+#: views/elements/addon_version_detail.thtml:51
+#, php-format
+msgid "addon_display_header_version"
+msgstr "Versió %s"
+
+#: views/addons/browse_thumbs.thtml:80
+msgid "addon_downloads"
+msgstr "baixades"
+
+#: views/addons/display.thtml:147
+msgid "addon_downloads_total"
+msgstr "baixades en total"
+
+#: views/elements/amo2009/homepage_addon.thtml:106
+#: views/elements/addon_listitem.thtml:115 views/elements/feature.thtml:101
+#: views/addons/category_landing.thtml:157 views/addons/display.thtml:146
+#: views/addons/browse_thumbs.thtml:80
+msgid "addon_downloads_weekly"
+msgstr "baixades per setmana"
+
+#. %1 is the add-on count, %2 the category name
+#: views/addons/browse_thumbs.thtml:104 views/addons/browse.thtml:60
+#, php-format
+msgid "addon_list_category_totalcount"
+msgid_plural "addon_list_category_totalcount"
+msgstr[0] "%1$s complement"
+msgstr[1] "%1$s complements"
+
+#: views/elements/amo2009/addon_list_options.thtml:103
+#: views/elements/pagination.thtml:67
+#: views/elements/addon_list_options.thtml:94
+msgid "addon_list_perpage"
+msgstr "per pàgina"
+
+#: views/elements/amo2009/addon_list_options.thtml:84
+#: views/elements/addon_list_options.thtml:98
+msgid "addon_list_sortby"
+msgstr "Ordenat per:"
+
+#: views/helpers/addons_html.php:568 views/elements/amo2009/install.thtml:321
+#: views/elements/feature.thtml:89
+msgid "addon_listitem_flag_experimental"
+msgstr "experimental"
+
+#: views/helpers/addons_html.php:570
+msgid "addon_listitem_flag_recommended"
+msgstr "recomanat"
+
+#. %1 is the add-on name, %2 is the platform
+#: views/pages/js_constants.js.thtml:66
+msgid "addon_not_available_for_platform"
+msgstr "%1$s no està disponible per al %2$s."
+
+#. %1 is the add-on name
+#: views/addons/policy.thtml:101 views/addons/previews.thtml:60
+#: views/addons/versions.thtml:130 views/reviews/flag.thtml:61
+#: views/reviews/add.thtml:114 views/reviews/display.thtml:216
+#: views/reviews/review_added.thtml:57
+#, php-format
+msgid "addon_review_a_back_to_addon_x"
+msgstr "Torna a %1$s..."
+
+#. %1 is the add-on name
+#: views/reviews/flag.thtml:60 views/reviews/add.thtml:113
+#: views/reviews/review_added.thtml:56
+#, php-format
+msgid "addon_review_a_back_to_reviews"
+msgstr "Torna a les revisions..."
+
+#: views/reviews/add.thtml:85
+msgid "addon_review_add_rating_field"
+msgstr "Valoració:"
+
+#: views/reviews/add.thtml:102
+msgid "addon_review_add_review_field"
+msgstr "Comentari:"
+
+#: views/reviews/add.thtml:107
+msgid "addon_review_add_submit"
+msgstr "Envieu el vostre comentari"
+
+#. %s is the name of the add-on
+#: views/reviews/add.thtml:51
+#, php-format
+msgid "addon_review_add_title"
+msgstr "Envia una revisió per a %s"
+
+#: views/reviews/add.thtml:78
+msgid "addon_review_add_title_field"
+msgstr "Títol/resum:"
+
+#: views/reviews/display.thtml:77 views/reviews/display.thtml:161
+msgid "addon_review_admin_delete"
+msgstr "Suprimeix"
+
+#: views/reviews/display.thtml:76
+msgid "addon_review_author_reply_link"
+msgstr "Respon"
+
+#: views/reviews/delete.thtml:62
+msgid "addon_review_confirm_delete"
+msgstr "Voleu suprimir aquesta revisió?"
+
+#: views/reviews/delete.thtml:63
+msgid "addon_review_confirm_no"
+msgstr "No"
+
+#: views/reviews/delete.thtml:64
+msgid "addon_review_confirm_yes"
+msgstr "Sí"
+
+#: views/reviews/delete.thtml:48
+msgid "addon_review_delete_header"
+msgstr "Suprimeix la revisió"
+
+#: controllers/reviews_controller.php:449
+msgid "addon_review_deleted_successfully"
+msgstr "La revisió s'ha suprimit satisfactòriament."
+
+#. %s is the name of the add-on
+#: views/reviews/add.thtml:51
+#, php-format
+msgid "addon_review_edit_title"
+msgstr "Edita una revisió per a %s"
+
+#. %1 is the count of characters entered as notes for the review flag reason.
+#: controllers/reviews_controller.php:539
+msgid "addon_review_flag_error_other_length"
+msgstr ""
+"S'ha produït un problema marcant la revisió: les notes de les revisions "
+"estan limitades entre 10 i 100 caràcters; la vostra en té %1$s."
+
+#. Removing an extra comma
+#: views/reviews/review_added.thtml:53
+msgid "addon_review_in_moderation"
+msgstr ""
+"Atenció: abans que es publiqui la vostra revisió en el lloc web públic, es "
+"moderarà per un editor."
+
+#: views/reviews/add.thtml:57
+msgid "addon_review_in_reply_to"
+msgstr "Resposta al desenvolupador:"
+
+#. %1 is the review count, %2 is the nickname or full name of the user.
+#: views/reviews/display.thtml:131
+#, php-format
+msgid "addon_review_others_by_user"
+msgid_plural "addon_review_others_by_user"
+msgstr[0] "Mostra la última revisió d'aquest complement enviada per %2$s."
+msgstr[1] ""
+"Mostra les %1$s últimes revisions d'aquest complement enviades per %2$s."
+
+#. %1 is the add-on name
+#: controllers/reviews_controller.php:201
+#: controllers/reviews_controller.php:250
+#: controllers/reviews_controller.php:345
+#: controllers/reviews_controller.php:424
+#, php-format
+msgid "addon_review_pagetitle"
+msgstr "Revisions de %s"
+
+#. %1 is the user, %2 is the (localized) date
+#: views/reviews/display.thtml:160
+#, php-format
+msgid "addon_review_reply_on_x_by_y"
+msgstr "resposta per en/la %1$s el %2$s"
+
+#: views/reviews/display.thtml:157
+msgid "addon_review_reply_prefix"
+msgstr "Resposta del desenvolupador:"
+
+#: views/reviews/review_added.thtml:51
+msgid "addon_review_saved_successfully"
+msgstr "La vostra revisió s'ha desat satisfactòriament. Gràcies."
+
+#: views/addons/display.thtml:354 views/reviews/display.thtml:72
+msgid "addon_reviewed_by_u_on_d"
+msgstr "per %1$s el %2$s"
+
+#. %1 is the user, %2 is the (localized) date, %3 is the rating
+#: views/editors/reviews_queue.thtml:57 views/editors/reviews_queue.thtml:68
+#: views/reviews/add.thtml:63 views/reviews/delete.thtml:54
+#, php-format
+msgid "addon_reviewed_on_x_rated_y"
+msgstr "per %1$s el %2$s (valoració %3$s)"
+
+#: views/elements/amo2009/addon_version_detail.thtml:52
+#: views/elements/addon_version_detail.thtml:52
+msgid "addon_version_permalink"
+msgstr "Enllaç permanent a aquesta versió"
+
+#. %1 is the current Application name (e.g. Firefox)
+#. %2 is the Application's version number
+#: views/addons/versions.thtml:140
+msgid "addon_versions_getlatestversion"
+msgstr "La versió més recent compatible amb el %1$s %2$s"
+
+#: views/addons/display.thtml:447
+msgid "addons_author_addons_submit"
+msgstr "Accepta"
+
+#: views/elements/amo2009/homepage_addon.thtml:100
+#: views/elements/feature.thtml:95
+msgid "addons_author_tooltip"
+msgstr "Mostra el perfil de l'autor"
+
+#. %1 is the name of the Application (eg. Firefox)
+#: controllers/addons_controller.php:1296
+msgid "addons_browse_all_themes_title"
+msgstr "Mostra tots els temes :: Complements del %1$s"
+
+#. %s is the name of the category
+#: controllers/addons_controller.php:1016
+#, php-format
+msgid "addons_browse_browse_category"
+msgstr "Mostra %s"
+
+#. %1 is the name of the theme category (eg. Modern)
+#. %2 is the name of the Application (eg. Firefox)
+#: controllers/addons_controller.php:664
+msgid "addons_browse_categories_header_theme"
+msgstr "Mostra %1$s temes :: Complements del %2$s"
+
+#: views/addons/display.thtml:249
+msgid "addons_display_a_license_what"
+msgstr "Què és això?"
+
+#: views/reviews/display.thtml:222
+msgid "addons_display_add_review"
+msgstr "Afegeix una revisió"
+
+#: views/addons/display.thtml:294
+msgid "addons_display_advanced_details"
+msgstr "Detalls avançats"
+
+#: views/addons/display.thtml:98
+msgid "addons_display_categories"
+msgstr "Categories"
+
+#: views/addons/display.thtml:482
+msgid "addons_display_collection_add"
+msgstr "Afegeix-ho a una col·lecció:"
+
+#: views/addons/display.thtml:491
+msgid "addons_display_collection_add_new"
+msgstr "Col·lecció nova..."
+
+#: views/addons/display.thtml:487
+msgid "addons_display_collection_add_select_one"
+msgstr "Selecciona una col·lecció..."
+
+#: views/addons/display.thtml:493
+msgid "addons_display_collection_add_submit"
+msgstr "Publica"
+
+#. %1$s is the add-on name
+#. %2$s is the collection name, linked to the collection's page
+#: views/pages/js_constants.js.thtml:103 views/addons/display.thtml:61
+msgid "addons_display_collection_publish_success"
+msgstr "%1$s s'ha afegit a la col·lecció %2$s."
+
+#: views/addons/display.thtml:483
+msgid "addons_display_collection_whatsthis"
+msgstr "Què és això?"
+
+#. %1$s is a number
+#: views/addons/display.thtml:473
+msgid "addons_display_collections_more"
+msgid_plural "addons_display_collections_more"
+msgstr[0] "i %1$s col·lecció més"
+msgstr[1] "i %1$s col·leccions més"
+
+#: views/addons/display.thtml:403
+msgid "addons_display_detailed_review"
+msgstr "revisió detallada"
+
+#: views/reviews/add.thtml:89 views/reviews/add.thtml:90
+msgid "addons_display_dont_like_it"
+msgstr "No ha agradat"
+
+#: views/reviews/display.thtml:220
+msgid "addons_display_edit_review"
+msgstr "Editeu la vostra revisió"
+
+#: views/addons/display.thtml:132
+msgid "addons_display_has_privacy"
+msgstr "Aquest complement té una política de privadesa."
+
+#: views/reviews/add.thtml:87 views/reviews/add.thtml:88
+msgid "addons_display_hate_it"
+msgstr "No ha agradat gens"
+
+#: views/addons/display.thtml:462
+msgid "addons_display_header_collections"
+msgstr "Col·leccions relacionades"
+
+#: views/addons/display.thtml:297
+msgid "addons_display_header_developer_comments"
+msgstr "Comentaris del desenvolupador"
+
+#: views/addons/display.thtml:230
+msgid "addons_display_header_homepage"
+msgstr "Pàgina web"
+
+#: views/addons/display.thtml:247 views/addons/versions.thtml:110
+msgid "addons_display_header_license"
+msgstr "Llicència del codi font"
+
+#: views/addons/display.thtml:337
+msgid "addons_display_header_reviews"
+msgstr "Revisions"
+
+#: views/addons/display.thtml:261
+msgid "addons_display_header_support"
+msgstr "Ajuda"
+
+#: views/reviews/add.thtml:91 views/reviews/add.thtml:92
+msgid "addons_display_like_it"
+msgstr "Ha agradat"
+
+#: views/addons/display.thtml:210
+msgid "addons_display_long_description"
+msgstr "Descripció llarga"
+
+#: views/reviews/add.thtml:95 views/reviews/add.thtml:96
+msgid "addons_display_love_it"
+msgstr "Ha agradat molt"
+
+#: views/addons/display.thtml:178
+msgid "addons_display_more_images"
+msgstr "Més imatges"
+
+#: views/addons/display.thtml:465
+msgid "addons_display_nocollections"
+msgstr "Aquest complement encara no està a cap col·lecció."
+
+#. %1$s is either an author's name or a comma separated list of authors. Using
+#. the list doesn't make sense in the English plural form so we ignore the
+#. variable.
+#: views/addons/display.thtml:436
+msgid "addons_display_other_addons_by"
+msgid_plural "addons_display_other_addons_by"
+msgstr[0] "Altres complements fets per %1$s"
+msgstr[1] "Altres complements fets pels autors següents: %1$s"
+
+#. %s is the name of the add-on and the add-on section. Example:
+#. Some Add-on :: Firefox Add-ons
+#. This should not be concatenated in the code and should be fixed.
+#: controllers/addons_controller.php:141 controllers/addons_controller.php:280
+#: controllers/addons_controller.php:1442
+#, php-format
+msgid "addons_display_pagetitle"
+msgstr "%s"
+
+#. %s is an email address
+#: views/addons/display.thtml:286
+#, php-format
+msgid "addons_display_paragraph_supportinfoemail"
+msgstr "El desenvolupador ofereix ajuda per a aquesta extensió a %s"
+
+#. %$1s is a URL
+#. %$2s is an email address
+#: views/addons/display.thtml:269
+#, php-format
+msgid "addons_display_paragraph_supportinfoemailurl"
+msgstr ""
+"El desenvolupador ofereix ajuda per a aquesta extensió a %s, o bé enviant-li "
+"un missatge a %s"
+
+#. %s is a URL
+#: views/addons/display.thtml:278
+#, php-format
+msgid "addons_display_paragraph_supportinfourl"
+msgstr "El desenvolupador ofereix ajuda per a aquesta extensió a %s"
+
+#: views/addons/display.thtml:383
+msgid "addons_display_rate_it"
+msgstr "Valoreu-lo"
+
+#: views/reviews/add.thtml:93 views/reviews/add.thtml:94
+msgid "addons_display_really_like_it"
+msgstr "Ha agradat de debò"
+
+#: views/addons/display.thtml:410
+msgid "addons_display_review_etiquette"
+msgstr ""
+"No envieu cap problema o error als comentaris. Ja que la vostra adreça de "
+"correu electrònica no l'enviarem als desenvolupadors del complement i en "
+"canvi els hi farà falta per a posar-se en contacte amb vostè per a "
+"solucionar el vostre problema."
+
+#. %1 is the review guidelines link
+#: views/addons/display.thtml:417
+msgid "addons_display_review_guidelines_link"
+msgstr "<a href=\"%s\">Guia per a revisions</a>"
+
+#. %1 is the support section link
+#: views/addons/display.thtml:414
+msgid "addons_display_review_see_support"
+msgstr ""
+"Vegeu la <a href=\"%1$s\">secció d'ajuda</a> per a saber on podeu trobar "
+"ajuda per a aquest complement."
+
+#: views/addons/display.thtml:404
+msgid "addons_display_review_submit"
+msgstr "Desa"
+
+#: views/addons/display.thtml:430
+#, php-format
+msgid "addons_display_see_all_addons"
+msgstr "Mostra tots els %1$s complements"
+
+#. %1 is the number of reviews
+#: views/addons/display.thtml:364
+#, php-format
+msgid "addons_display_see_all_reviews"
+msgstr "Mostra totes les revisions (%1$s)"
+
+#: views/addons/display.thtml:219
+msgid "addons_display_see_all_versions"
+msgstr "Mostra totes les versions"
+
+#: views/addons/display.thtml:321 views/addons/versions.thtml:117
+msgid "addons_display_view_source"
+msgstr "Visualitza el codi font"
+
+#: views/addons/display.thtml:324
+msgid "addons_display_view_stats"
+msgstr "Mostra les estadístiques"
+
+#: views/addons/display.thtml:376
+msgid "addons_display_what_do_you_think"
+msgstr "Què en penseu?"
+
+#: views/elements/app_compatibility.thtml:49
+msgid "addons_display_workswith"
+msgstr "Funciona amb:"
+
+#: views/addons/home.thtml:112
+msgid "addons_home_browse_new"
+msgstr "Acabat d'afegir"
+
+#: views/addons/home.thtml:110
+msgid "addons_home_browse_popular"
+msgstr "Popular"
+
+#: views/addons/home.thtml:108
+msgid "addons_home_browse_recommended"
+msgstr "Recomanat"
+
+#: views/addons/home.thtml:127 views/addons/home.thtml:134
+#: views/addons/home.thtml:141 views/addons/home.thtml:148
+msgid "addons_home_browse_subscribe"
+msgstr "Subscriu"
+
+#: views/addons/home.thtml:101
+msgid "addons_home_browse_title"
+msgstr "Examina els complements"
+
+#: views/addons/home.thtml:114
+msgid "addons_home_browse_updated"
+msgstr "Actualitzat"
+
+#: views/elements/amo2009/homepage_addon.thtml:100
+#: views/elements/addon_discussionheader.thtml:83
+#: views/elements/addon_listitem.thtml:109 views/elements/feature.thtml:95
+#: views/addons/category_landing.thtml:66 views/addons/policy.thtml:57
+#: views/addons/display.thtml:70 views/addons/home.thtml:178
+msgid "addons_home_by"
+msgstr "per"
+
+#: views/addons/home.thtml:169
+msgid "addons_home_collection_popular_title"
+msgstr "Col·leccions populars"
+
+#: views/elements/amo2009/categories.thtml:69 views/addons/home.thtml:160
+msgid "addons_home_collections"
+msgstr "Col·leccions"
+
+#. %1$s is the count of addons in a collection
+#: views/elements/amo2009/collection_listing_item.thtml:51
+#: views/addons/home.thtml:185
+msgid "addons_home_collections_addon_count"
+msgid_plural "addons_home_collections_addon_count"
+msgstr[0] "<strong>%1$s</strong> complement"
+msgstr[1] "<strong>%1$s</strong> complements"
+
+#: views/addons/home.thtml:196
+msgid "addons_home_collections_all"
+msgstr "Mostra totes les col·leccions"
+
+#: views/addons/home.thtml:162
+msgid "addons_home_collections_intro"
+msgstr ""
+"Les col·leccions són una manera de categoritzar, barrejar, trobar i combinar "
+"complements. Podeu subscriure-us a les col·leccions que han creat altres "
+"usuaris o bé crear-ne un vostre."
+
+#. %1$s is the count of subscribers for a collection
+#: views/elements/amo2009/collection_listing_item.thtml:58
+#: views/collections/detail.thtml:96 views/addons/home.thtml:189
+msgid "addons_home_collections_subscribers"
+msgid_plural "addons_home_collections_subscribers"
+msgstr[0] "<strong>%1$s</strong> subscriptor"
+msgstr[1] "<strong>%1$s</strong> subscriptors"
+
+#: views/addons/searchengines.thtml:54 views/addons/themes_landing.thtml:49
+msgid "addons_home_feature_head"
+msgstr "Recomanem"
+
+#: controllers/search_controller.php:218 controllers/addons_controller.php:176
+#: controllers/addons_controller.php:428 controllers/addons_controller.php:671
+#: controllers/addons_controller.php:871
+#: controllers/addons_controller.php:1103
+#: controllers/addons_controller.php:1242
+#: controllers/addons_controller.php:1298
+#, php-format
+msgid "addons_home_header_details"
+msgstr ""
+"Els complements amplien el %1$s, i us permeten personalitzar la vostra "
+"experiència de navegació per Internet. Feu-ne una ullada i feu-vos vostre el "
+"%1$s."
+
+#. %1$s is the HTML collection name link.
+#: views/elements/amo2009/teaser_collections.thtml:107
+msgid "addons_home_introduction_collection_link"
+msgstr "Com aquest? Trobeu més complements a %1$s."
+
+#: views/elements/amo2009/teaser_collections.thtml:60
+msgid "addons_home_introduction_extras"
+msgstr ""
+"<strong>Hi ha més de 5000 extres</strong> que us permetran personalitzar i "
+"ampliar el Firefox com us faci falta."
+
+#: views/elements/amo2009/teaser_collections.thtml:55
+msgid "addons_home_introduction_header"
+msgstr "Què són els complements?"
+
+#: views/elements/amo2009/teaser_collections.thtml:72
+msgid "addons_home_introduction_install"
+msgstr ""
+"<strong>Fàcil d'instal·lar</strong>, rebreu una avis quan hi hagin "
+"actualitzacions disponibles."
+
+#: views/elements/amo2009/teaser_collections.thtml:45
+msgid "addons_home_introduction_name"
+msgstr "Introducció"
+
+#: views/elements/amo2009/teaser_collections.thtml:66
+msgid "addons_home_introduction_themes"
+msgstr ""
+"Barres d'eines, temes i cercadors que <strong>us ajudaran a realitzar les "
+"tasques del dia a dia.</strong>"
+
+#: views/addons/home.thtml:161
+msgid "addons_home_new_indicator"
+msgstr "NOU!"
+
+#: views/elements/app_chooser.thtml:48 views/layouts/amo2009.thtml:257
+msgid "addons_home_other_applications"
+msgstr "Altres aplicacions"
+
+#. %1$s is the application the user is browsing. Examples: Thunderbird, Firefox,
+#. Sunbird
+#: views/pages/collector_faq.thtml:49 views/pages/collector_firstrun.thtml:42
+#: views/pages/collector.thtml:46 views/pages/collector_features.thtml:54
+#: controllers/developers_controller.php:87
+#: controllers/compatibility_controller.php:72
+#: controllers/components/simple_acl.php:81 controllers/components/amo.php:607
+#: controllers/statistics_controller.php:60
+#: controllers/statistics_controller.php:240
+#: controllers/previews_controller.php:67 controllers/users_controller.php:90
+#: controllers/users_controller.php:223 controllers/users_controller.php:330
+#: controllers/users_controller.php:414 controllers/users_controller.php:708
+#: controllers/users_controller.php:723 controllers/reviews_controller.php:204
+#: controllers/reviews_controller.php:251
+#: controllers/reviews_controller.php:346
+#: controllers/reviews_controller.php:425
+#: controllers/search_controller.php:185 controllers/search_controller.php:297
+#: controllers/search_controller.php:301 controllers/addons_controller.php:147
+#: controllers/addons_controller.php:280 controllers/addons_controller.php:370
+#: controllers/addons_controller.php:667 controllers/addons_controller.php:874
+#: controllers/addons_controller.php:1019
+#: controllers/addons_controller.php:1034
+#: controllers/addons_controller.php:1101
+#: controllers/addons_controller.php:1121
+#: controllers/addons_controller.php:1240
+#: controllers/addons_controller.php:1357
+#: controllers/addons_controller.php:1364
+#: controllers/addons_controller.php:1442
+#: controllers/addons_controller.php:1477
+#: controllers/addons_controller.php:1538
+#: controllers/addons_controller.php:1543
+#: controllers/editors_controller.php:64 controllers/pages_controller.php:132
+#: controllers/groups_controller.php:65 controllers/groups_controller.php:71
+#: controllers/groups_controller.php:89 controllers/groups_controller.php:111
+#: controllers/collections_controller.php:57
+#: controllers/collections_controller.php:121
+#: controllers/collections_controller.php:205
+#: controllers/collections_controller.php:365
+#: controllers/collections_controller.php:404
+#: controllers/collections_controller.php:466
+#: controllers/collections_controller.php:538
+#: controllers/collections_controller.php:828
+#: controllers/localizers_controller.php:72
+#, php-format
+msgid "addons_home_pagetitle"
+msgstr "Complements del %1$s "
+
+#. %1$s is the number of addons downloaded
+#: views/addons/home.thtml:57
+#, php-format
+msgid "addons_home_stats_downloaded"
+msgid_plural "addons_home_stats_downloaded"
+msgstr[0] "<strong>%1$s</strong> <span>complement baixat</span>"
+msgstr[1] "<strong>%1$s</strong> <span>complements baixats</span>"
+
+#. %1$s is the number of addons in use
+#: views/addons/home.thtml:63
+#, php-format
+msgid "addons_home_stats_inuse"
+msgid_plural "addons_home_stats_inuse"
+msgstr[0] "<strong>%1$s</strong> <span>complement fent-se servir</span>"
+msgstr[1] "<strong>%1$s</strong> <span>complements fent-se servir</span>"
+
+#: views/addons/home.thtml:136
+msgid "addons_home_view_all_newest_title"
+msgstr "Mostra tots els complements creats recentment"
+
+#: views/addons/home.thtml:129
+msgid "addons_home_view_all_popular_title"
+msgstr "Mostra tots els complements famosos"
+
+#: views/addons/home.thtml:150
+msgid "addons_home_view_all_recommended_title"
+msgstr "Mostra tots els complements recomanats"
+
+#: views/addons/home.thtml:143
+msgid "addons_home_view_all_updated_title"
+msgstr "Mostra tots els complements actualitzats recentment"
+
+#: views/elements/amo2009/install.thtml:334 views/elements/install.thtml:112
+msgid "addons_install_in_sunbird"
+msgstr ""
+"<ol><li>Cliqueu l'enllaç següent per a desar el fitxer.</li><li>En el "
+"Mozilla Sunbird, obriu Complements des del menú Eines.</li><li>Cliqueu el "
+"botó Instal·la, cerqueu el fitxer que us heu baixat i cliqueu \"D'acord\".</"
+"li></ol>"
+
+#: views/elements/amo2009/install.thtml:333 views/elements/install.thtml:111
+msgid "addons_install_in_sunbird_title"
+msgstr "Com instal·lar-ho al Sunbird"
+
+#: views/elements/amo2009/install.thtml:331 views/elements/install.thtml:106
+msgid "addons_install_in_thunderbird"
+msgstr ""
+"<ol><li>Cliqueu amb el botó dret a l'enllaç de sota i escolliu \"Anomena i "
+"desa...\" per a baixar-vos el fitxer i desar-lo al disc.</li><li>En el "
+"Mozilla Thunderbird, obriu Complements des del menú Eines.</li><li>Cliqueu "
+"el botó Instal·la, cerqueu el fitxer que us heu baixat i cliqueu \"D'acord\"."
+"</li></ol>"
+
+#: views/elements/amo2009/install.thtml:330 views/elements/install.thtml:105
+msgid "addons_install_in_thunderbird_title"
+msgstr "Com instal·lar-ho en el Thunderbird"
+
+#: views/elements/amo2009/addon_list_options.thtml:108
+#: views/elements/addon_list_options.thtml:105
+msgid "addons_options_show_experimental"
+msgstr "mostra els complements experimentals"
+
+#: views/elements/amo2009/addon_list_options.thtml:113
+#: views/elements/addon_list_options.thtml:109
+msgid "addons_options_submit"
+msgstr "D'acord"
+
+#: views/addons/plugins.thtml:63 views/addons/plugins.thtml:73
+#: views/addons/plugins.thtml:83 views/addons/plugins.thtml:93
+#: views/addons/plugins.thtml:103 views/addons/plugins.thtml:116
+#: views/addons/plugins.thtml:126
+msgid "addons_plugins_by"
+msgstr "Per"
+
+#: views/addons/plugins.thtml:107
+msgid "addons_plugins_for_linux"
+msgstr "per a Linux"
+
+#: views/addons/plugins.thtml:108 views/addons/plugins.thtml:131
+msgid "addons_plugins_for_macosx"
+msgstr "per a Mac OS X"
+
+#: views/addons/plugins.thtml:106 views/addons/plugins.thtml:129
+#: views/addons/plugins.thtml:130
+msgid "addons_plugins_for_windows"
+msgstr "per a Windows"
+
+#. %1$s is a URL
+#: views/addons/plugins.thtml:139
+#, php-format
+msgid "addons_plugins_looking_for_more"
+msgstr ""
+"Aquesta pàgina només llista algunes dels connectors més típics i populars. "
+"Per a més informació sobre altres connectors disponibles per a navegadors "
+"basats en Mozilla, visiteu %1$s"
+
+#: views/addons/plugins.thtml:137
+msgid "addons_plugins_looking_for_plugin"
+msgstr "Cerqueu un connector que no està en aquesta llista?"
+
+#: views/addons/plugins.thtml:58
+msgid "addons_plugins_main_description"
+msgstr ""
+"Els connectors ajuden al vostre navegador a desenvolupar funcions "
+"específiques com per exemple visualitzar formats gràfics especials o "
+"mostrar contingut multimèdia. Els connectors són força diferents de les "
+"extensions, les quals modifiquen o s'afegeixen a les funcionalitats "
+"existents."
+
+#. %1$s is the application name. Example: Firefox, Thunderbird, Sunbird
+#: controllers/addons_controller.php:1122
+#, php-format
+msgid "addons_plugins_main_header"
+msgstr "Connectors típics per al %1$s"
+
+#: controllers/components/amo.php:698 controllers/addons_controller.php:1121
+msgid "addons_plugins_pagetitle"
+msgstr "Connectors"
+
+#: views/addons/plugins.thtml:68 views/addons/plugins.thtml:78
+#: views/addons/plugins.thtml:88 views/addons/plugins.thtml:98
+#: views/addons/plugins.thtml:110 views/addons/plugins.thtml:121
+#: views/addons/plugins.thtml:133
+msgid "addons_plugins_support_documentation"
+msgstr "Documentació d'ajuda: "
+
+#. %s is the name of the add-on
+#: views/addons/policy.thtml:61
+#, php-format
+msgid "addons_policy_eula_require"
+msgstr ""
+"El %s requereix que accepteu la següent Acord de llicència d'usuari final "
+"abans de procedir amb la instal·lació:"
+
+#. %1 is the add-on name
+#: controllers/addons_controller.php:1476
+#, php-format
+msgid "addons_previews_pagetitle"
+msgstr "Previsualitzacions del %s"
+
+#: views/addons/category_landing.thtml:135
+msgid "addons_recently_added"
+msgstr "Afegit recentment"
+
+#: views/addons/recommended.thtml:51 controllers/addons_controller.php:1365
+msgid "addons_recommended_introduction"
+msgstr ""
+"Amb tants fantàstics complements disponibles, hi ha sempre alguna cosa per a "
+"tothom. Per a començar, ací teniu una llista dels més populars. Gaudiu-los! "
+
+#: controllers/addons_controller.php:1357
+#: controllers/addons_controller.php:1364
+msgid "addons_recommended_pagetitle"
+msgstr "Complements recomanats"
+
+#: controllers/addons_controller.php:1360
+msgid "addons_recommended_title"
+msgstr "Complements recomanats"
+
+#: views/addons/searchengines.thtml:136
+msgid "addons_searchengines_additional_resources"
+msgstr "Recursos addicionals"
+
+#. link text devmo
+#: views/addons/searchengines.thtml:141
+msgid "addons_searchengines_devmo_link"
+msgstr "Centre de desenvolupament de Mozilla"
+
+#: views/pages/js_constants.js.thtml:67
+msgid "addons_searchengines_error_mozilla_browser_required"
+msgstr ""
+"Perdoneu, necessiteu un navegador basat amb Mozilla (com el Firefox) per a "
+"instal·lar aquest connector."
+
+#: views/addons/searchengines.thtml:49
+msgid "addons_searchengines_error_nojavascript"
+msgstr ""
+"Es necessita el Javascript per a instal·lar connectors, però sembla que no "
+"ho tingueu habilitat. Heu d'habilitar el Javascript abans d'intentar "
+"d'instal·lar cap dels connectors de cerca següents."
+
+#. %1 is "make your own" link
+#. %2 is MDC link
+#: views/addons/searchengines.thtml:139
+msgid "addons_searchengines_learn_howto"
+msgstr "Apreneu com %1$s al %2$s."
+
+#. link path to search plugins instructions, relative to devmo
+#: views/addons/searchengines.thtml:140
+msgid "addons_searchengines_makeyourown_href"
+msgstr "/ca/docs/Creating_OpenSearch_plugins_for_Firefox"
+
+#. link text for "make your own" (opensearch engine)
+#: views/addons/searchengines.thtml:140
+msgid "addons_searchengines_makeyourown_link"
+msgstr "feu-vos el vostre propi"
+
+#. %1 is the link to mycroft.mozdev.org
+#: views/addons/searchengines.thtml:138
+msgid "addons_searchengines_more"
+msgstr "Cerqueu més motors de cerca a %1$s"
+
+#. link text to mycroft.mozdev.org
+#: views/addons/searchengines.thtml:138
+msgid "addons_searchengines_mycroft_link"
+msgstr "mycroft.mozdev.org"
+
+#: controllers/addons_controller.php:1100
+#: controllers/addons_controller.php:1110
+msgid "addons_searchengines_pagetitle"
+msgstr "Motors de cerca"
+
+#: views/addons/searchengines.thtml:143
+msgid "addons_searchengines_thanks"
+msgstr ""
+"S'agraeix especialment el projecte Mycroft per a la seva feina amb els "
+"Motors de cerca del Firefox."
+
+#: views/addons/display.thtml:154
+msgid "addons_share_button_text"
+msgstr "Comparteix-ho"
+
+#: controllers/addons_controller.php:89
+msgid "addons_share_label_delicious"
+msgstr "Afegeix-ho al Delicious"
+
+#: controllers/addons_controller.php:77
+msgid "addons_share_label_digg"
+msgstr "Posa-ho al Digg"
+
+#: controllers/addons_controller.php:83
+msgid "addons_share_label_facebook"
+msgstr "Publica-ho al Facebook"
+
+#: controllers/addons_controller.php:101
+msgid "addons_share_label_friendfeed"
+msgstr "Comparteix-ho al FriendFeed"
+
+#: controllers/addons_controller.php:95
+msgid "addons_share_label_myspace"
+msgstr "Publica-ho al MySpace"
+
+#: controllers/components/amo.php:201 controllers/components/amo.php:229
+msgid "addons_status_disabled"
+msgstr "Deshabilitat"
+
+#: controllers/components/amo.php:191 controllers/components/amo.php:224
+msgid "addons_status_incomplete"
+msgstr "Versió incompleta"
+
+#: controllers/components/amo.php:197 controllers/components/amo.php:227
+msgid "addons_status_nominated"
+msgstr "A l'entorn de proves; nominació pública"
+
+#: views/pages/js_constants.js.thtml:80 controllers/components/amo.php:195
+#: controllers/components/amo.php:226
+msgid "addons_status_pending"
+msgstr "A l'entorn de proves; pendent de revisió"
+
+#: views/pages/js_constants.js.thtml:78 controllers/components/amo.php:199
+#: controllers/components/amo.php:228
+msgid "addons_status_public"
+msgstr "Públic"
+
+#: views/pages/js_constants.js.thtml:79 controllers/components/amo.php:193
+#: controllers/components/amo.php:225
+msgid "addons_status_sandbox"
+msgstr "A l'entorn de proves"
+
+#: controllers/components/amo.php:203
+msgid "addons_status_unknown"
+msgstr "Desconegut"
+
+#: views/elements/amo2009/teaser_collections.thtml:91
+#: views/elements/amo2009/homepage_addon.thtml:99
+#: views/elements/feature.thtml:94
+msgid "addons_title_tooltip"
+msgstr "Mostra més informació sobre el complement"
+
+#: views/addons/category_landing.thtml:151
+msgid "addons_top_downloads"
+msgstr "Els més baixats"
+
+#: views/addons/category_landing.thtml:165
+msgid "addons_top_rated"
+msgstr "Els més ben valorats"
+
+#: views/addons/versions.thtml:62
+msgid "addons_versions_careful"
+msgstr "Aneu amb compte amb les versions antigues"
+
+#: views/addons/versions.thtml:63
+msgid "addons_versions_careful_introduction"
+msgstr ""
+"Aquestes versions es mostren només com a referència i per a fer proves. "
+"Sempre heu d'utilitzar les darreres versions dels complements."
+
+#: controllers/addons_controller.php:1549
+msgid "addons_versions_history"
+msgstr "Historial de versions amb el registre de canvis"
+
+#. %1$s is the add-on name
+#: controllers/addons_controller.php:1535
+#, php-format
+msgid "addons_versions_pagetitle"
+msgstr "Historial de versions del %1$s"
+
+#: controllers/groups_controller.php:71
+msgid "admin_group_add_pagetitle"
+msgstr "Afegeix un grup"
+
+#: controllers/groups_controller.php:111
+msgid "admin_group_delete_pagetitle"
+msgstr "Suprimeix el grup"
+
+#. %s is a number to identify the group
+#: controllers/groups_controller.php:117
+#, php-format
+msgid "admin_group_deleted"
+msgstr "El grup amb l'id %s s'ha suprimit"
+
+#: controllers/groups_controller.php:89
+msgid "admin_group_edit_pagetitle"
+msgstr "Edita el grup"
+
+#: controllers/groups_controller.php:92 controllers/groups_controller.php:113
+msgid "admin_group_error_invalid_id"
+msgstr "Id invàlid per al grup"
+
+#: controllers/groups_controller.php:65
+msgid "admin_group_pagetitle"
+msgstr "Administrador de grups"
+
+#: controllers/groups_controller.php:77 controllers/groups_controller.php:99
+msgid "admin_group_saved"
+msgstr "El grup s'ha desat"
+
+#: views/elements/amo2009/search.thtml:257 views/elements/search.thtml:239
+msgid "advanced_search_form"
+msgstr "Avançat"
+
+#: views/elements/amo2009/search.thtml:126 views/elements/search.thtml:125
+msgid "advanced_search_form_any_time"
+msgstr "Qualsevol hora"
+
+#: views/elements/amo2009/search.thtml:97
+#: views/elements/amo2009/search.thtml:110 views/elements/search.thtml:96
+#: views/elements/search.thtml:109
+msgid "advanced_search_form_any_type"
+msgstr "Qualsevol"
+
+#: views/elements/amo2009/search.thtml:275 views/elements/search.thtml:254
+msgid "advanced_search_form_any_version"
+msgstr "Qualsevol"
+
+#: views/elements/amo2009/search.thtml:217 views/elements/search.thtml:212
+msgid "advanced_search_form_application"
+msgstr "Aplicació"
+
+#: views/elements/amo2009/search.thtml:143 views/elements/search.thtml:142
+msgid "advanced_search_form_keyword_match"
+msgstr "Paraula clau"
+
+#: views/elements/amo2009/search.thtml:251 views/elements/search.thtml:225
+msgid "advanced_search_form_lastupdate"
+msgstr "Última actualització"
+
+#: views/elements/amo2009/search.thtml:145 views/elements/search.thtml:144
+msgid "advanced_search_form_name"
+msgstr "Nom"
+
+#: views/elements/amo2009/search.thtml:144 views/elements/search.thtml:143
+msgid "advanced_search_form_newest"
+msgstr "El més recent"
+
+#: views/elements/amo2009/search.thtml:130 views/elements/search.thtml:129
+msgid "advanced_search_form_past_3_months"
+msgstr "Els últims 3 mesos"
+
+#: views/elements/amo2009/search.thtml:131 views/elements/search.thtml:130
+msgid "advanced_search_form_past_6_months"
+msgstr "Els últims 6 mesos"
+
+#: views/elements/amo2009/search.thtml:127 views/elements/search.thtml:126
+msgid "advanced_search_form_past_day"
+msgstr "L'últim dia"
+
+#: views/elements/amo2009/search.thtml:129 views/elements/search.thtml:128
+msgid "advanced_search_form_past_month"
+msgstr "L'últim mes"
+
+#: views/elements/amo2009/search.thtml:128 views/elements/search.thtml:127
+msgid "advanced_search_form_past_week"
+msgstr "La última setmana"
+
+#: views/elements/amo2009/search.thtml:132 views/elements/search.thtml:131
+msgid "advanced_search_form_past_year"
+msgstr "L'últim any"
+
+#: views/elements/amo2009/search.thtml:239 views/elements/search.thtml:230
+msgid "advanced_search_form_perpage"
+msgstr "Per pàgina"
+
+#: views/elements/amo2009/search.thtml:243 views/elements/search.thtml:224
+msgid "advanced_search_form_platform"
+msgstr "Plataforma"
+
+#: views/elements/amo2009/search.thtml:147 views/elements/search.thtml:146
+msgid "advanced_search_form_popularity"
+msgstr "Popularitat"
+
+#: views/elements/amo2009/search.thtml:146 views/elements/search.thtml:145
+msgid "advanced_search_form_rating"
+msgstr "Valoració"
+
+#: views/elements/amo2009/search.thtml:247 views/elements/search.thtml:231
+msgid "advanced_search_form_sortby"
+msgstr "Ordena per"
+
+#: views/elements/amo2009/search.thtml:227 views/elements/search.thtml:216
+msgid "advanced_search_form_to"
+msgstr "a"
+
+#: views/elements/amo2009/search.thtml:257 views/elements/search.thtml:237
+msgid "advanced_search_form_toggle_tooltip"
+msgstr "Commuta el mode de cerca avançada"
+
+#: views/elements/amo2009/search.thtml:235 views/elements/search.thtml:223
+msgid "advanced_search_form_type"
+msgstr "Tipus"
+
+#: views/elements/amo2009/search.thtml:222 views/elements/search.thtml:214
+msgid "advanced_search_form_version"
+msgstr "Versió"
+
+#: views/elements/amo2009/pagination.thtml:42
+msgid "amo2009_pagination_next_page"
+msgstr "Següent"
+
+#: views/elements/amo2009/pagination.thtml:41
+msgid "amo2009_pagination_previous_page"
+msgstr "Anterior"
+
+#: views/pages/js_constants.js.thtml:96
+msgid "app_compat_ignore_check"
+msgstr "Ignora la comprovació de versions"
+
+#: views/pages/js_constants.js.thtml:72
+msgid "app_compat_older_firefox_only"
+msgstr "Aquest complement és només per a versions més antigues del Firefox"
+
+#. %1$s and %2$s are URLs
+#: views/pages/js_constants.js.thtml:74
+msgid "app_compat_older_version_or_ignore_check"
+msgstr ""
+"Podeu <a href=\"%1$s\">provar una versió més antiga</a> o <a href=\"#\" "
+"onclick=\"%2$s\">ignorar aquesta comprovació</a>"
+
+#. %1$s is a URL
+#: views/pages/js_constants.js.thtml:71
+msgid "app_compat_try_old_version"
+msgstr "Pot ser que funcioni en una <a href=\"%1$s\">versió més antiga</a>"
+
+#. %1$s is a URL
+#. %2$s is a version number. Example: 3.1
+#: views/pages/js_constants.js.thtml:73
+msgid "app_compat_unreleased_version"
+msgstr ""
+"Aquest complement requereix una versió del <a href=\"%1$s\">Firefox %2$s</a> "
+"que encara no ha sortit"
+
+#: views/pages/js_constants.js.thtml:70
+msgid "app_compat_update_firefox"
+msgstr ""
+"<a href=\"http://getfirefox.com\">Actualitzeu el Firefox</a> per a utilitzar "
+"aquest complement"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#. %3$s is a status, like Public.
+#: controllers/components/audit.php:79
+msgid "audit_addon_status"
+msgstr "En/na %1$s va canviar l'estat de %2$s a %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:221
+msgid "audit_admin_default"
+msgstr ""
+"En/na %1$s va validar l'acció d'administració desconeguda %2$s amb id %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:153
+msgid "audit_admin_feature_remove"
+msgstr "En/na %1$s va suprimir la característica %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is an application, like Firefox.
+#: controllers/components/audit.php:92
+msgid "audit_application_create"
+msgstr "En/na %1$s va crear l'aplicació %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is an application, like Firefox.
+#: controllers/components/audit.php:95
+msgid "audit_application_edit"
+msgstr "En/na %1$s va editar l'aplicació %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a version number, like 3.5.
+#. %3$s is an application, like Firefox.
+#: controllers/components/audit.php:105
+msgid "audit_appversion_create"
+msgstr "En/na %1$s va crear la versió %2$s del %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a version number, like 3.5.
+#. %3$s is an application, like Firefox.
+#: controllers/components/audit.php:108
+msgid "audit_appversion_delete"
+msgstr "En/na %1$s va suprimir la versió %2$s del %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a config field, like "awesomeness".
+#. %3$s is a config value, like "off".
+#. %4$s is a config value, like "on".
+#: controllers/components/audit.php:210
+msgid "audit_config"
+msgstr "En/na %1$s va canviar el valor de '%2$s' de '%3$s' a '%4$s'"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:258
+msgid "audit_editor_default"
+msgstr "En/na %1$s va validar l'acció d'editor desconeguda %2$s amb id %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#: controllers/components/audit.php:236
+msgid "audit_editor_feature_remove"
+msgstr "En/na %1$s va esborrar el complement %2$s de la llista"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#: controllers/components/audit.php:231
+msgid "audit_feature_add"
+msgstr "En/na %1$s va afegir el complement %2$s a la llista"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:149
+msgid "audit_feature_edit"
+msgstr "En/na %1$s va canviar una característica per a l'idioma %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#: controllers/components/audit.php:241
+msgid "audit_feature_locale_change"
+msgstr ""
+"En/na %1$s va canviar algun idioma de la llista de característiques del "
+"complement %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:83
+msgid "audit_file_recalchash"
+msgstr "En/na %1$s va recalcular el codi hash del fitxer %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>user name</a>
+#. %3$s is <a>group name</a>
+#: controllers/components/audit.php:182
+msgid "audit_group_addmember"
+msgstr "En/na %1$s va afegir %2$s al grup %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:313
+msgid "audit_group_associated"
+msgstr "En/na %1$s s'ha afegit ell/a mateix al grup %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:162
+msgid "audit_group_create"
+msgstr "En/na %1s va crear el grup %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:170
+msgid "audit_group_delete"
+msgstr "En/na %1$s va suprimir el grup %2$s (id %3$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:165
+msgid "audit_group_edit"
+msgstr "En/na %1$s va editar el grup %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>user name</a>
+#. %3$s is <a>group name</a>
+#: controllers/components/audit.php:188
+msgid "audit_group_removemember"
+msgstr "En/na %1$s va suprimir l'usuari %2$s del grup %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:280
+msgid "audit_l10n_default"
+msgstr "En/na %1$s va validar l'acció desconeguda %2$s amb id %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:295
+msgid "audit_modify_locked_group"
+msgstr "En/na %1$s va intentar modificar el grup bloquejat %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:299
+msgid "audit_modify_other_locale"
+msgstr ""
+"En/na %1$s va intentar modificar les traduccions en %2$s quan no tenia permís"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a platform, like <a>Windows</a>
+#: controllers/components/audit.php:135
+msgid "audit_platform_create"
+msgstr "En/na %1$s va crear la plataforma %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a platform, like <a>Windows</a>
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:143
+msgid "audit_platform_delete"
+msgstr "En/na %1$s va suprimir la plataforma %2$s (id %3$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a platform, like <a>Windows</a>
+#: controllers/components/audit.php:138
+msgid "audit_platform_edit"
+msgstr "En/na %1$s va editar la plataforma %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a part of the admin, like 'Site Config'
+#: controllers/components/audit.php:288
+msgid "audit_reauthentication_failure"
+msgstr ""
+"En/na %1$s va fallar més de dues vegades a l'identificar-se per accedir a %2"
+"$s."
+
+#. %1$s is <a>user name</a>
+#. %2$s is the name of a canned response, like 'Ready for the public'
+#: controllers/components/audit.php:198
+msgid "audit_response_create"
+msgstr "En/na %1$s va crear la resposta %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is the name of a canned response, like 'Ready for the public'
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:206
+msgid "audit_response_delete"
+msgstr "En/na %1$s va suprimir la resposta %2$s (id %3$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is the name of a canned response, like 'Ready for the public'
+#: controllers/components/audit.php:201
+msgid "audit_response_edit"
+msgstr "En/na %1$s va editar la resposta %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:245
+msgid "audit_review_approve"
+msgstr "En/na %1$s va aprovar la revisió %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:250 controllers/components/audit.php:253
+msgid "audit_review_delete"
+msgstr "En/na %1$s va suprimir la revsisió %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:303
+msgid "audit_security_default"
+msgstr ""
+"En/na %1$s va validar l'acció de seguretat desconeguda %2$s amb id %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a category name, like <a>Search Tools</a>
+#: controllers/components/audit.php:118
+msgid "audit_tag_create"
+msgstr "En/na %1$s va crear la categoria %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a category name, like <a>Search Tools</a>
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:126
+msgid "audit_tag_delete"
+msgstr "En/na %1$s va suprimir la categoria %2$s (id %3$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a category name, like <a>Search Tools</a>
+#: controllers/components/audit.php:121
+msgid "audit_tag_edit"
+msgstr "En/na %1$s va editar la categoria %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:266
+msgid "audit_update_applications"
+msgstr "En/na %1$s va actualitzar les traduccions en %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:277
+msgid "audit_update_blog"
+msgstr "En/na %1$s va actualitzar una entrada del bloc de traducció %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:274
+msgid "audit_update_platforms"
+msgstr "En/na %1$s va actualitzar les traduccions en %2$s de la plataforma"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:270
+msgid "audit_update_tags"
+msgstr "En/na %1$s va actualitzar les traduccions en %2$s de les categories"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>user name</a>
+#: controllers/components/audit.php:217
+msgid "audit_user_edit"
+msgstr "En/na %1$s va editar la informació de l'usuari %2$s"
+
+#: controllers/addons_controller.php:1012
+msgid "browse_addons_name"
+msgstr "Complements per nom"
+
+#: controllers/addons_controller.php:1010
+msgid "browse_addons_newest"
+msgstr "Els complements més nous"
+
+#: controllers/addons_controller.php:1008
+msgid "browse_addons_popular"
+msgstr "Els complements més famosos"
+
+#: controllers/addons_controller.php:1011
+msgid "browse_addons_rated"
+msgstr "Complements per valoració"
+
+#: controllers/addons_controller.php:1009
+msgid "browse_addons_updated"
+msgstr "Complements actualitzats recentment"
+
+#: views/elements/categories.thtml:73 views/elements/categories.thtml:82
+msgid "categories_current_title"
+msgstr "Categoria actual"
+
+#: views/elements/categories.thtml:50
+#: views/elements/amo2009/categories.thtml:43
+#: views/elements/amo2009/categories.thtml:45
+msgid "categories_header"
+msgstr "Categories"
+
+#: views/elements/categories.thtml:50
+#: views/elements/amo2009/categories.thtml:41
+msgid "categories_header_title"
+msgstr "Selecció de la categoria"
+
+#. %1$s is the category name
+#: views/addons/searchengines.thtml:129
+#, php-format
+msgid "category_extra_see_all"
+msgstr "Categoria %1$s"
+
+#. %1$s is a number.
+#: models/collection.php:130
+msgid "collection_description_limit"
+msgstr "La descripció hauria de tenir menys de %1$s caràcters."
+
+#. %1$s is the name of the collection
+#: controllers/collections_controller.php:392
+msgid "collection_detail_rss_title"
+msgstr "Col·lecció %s"
+
+#: controllers/collections_controller.php:1065
+msgid "collection_error_deleting_addon"
+msgstr "S'ha produït un error quan es suprimia el complement."
+
+#: controllers/collections_controller.php:1051
+msgid "collection_error_saving_addon"
+msgstr "S'ha produït un error quan es desava el complement."
+
+#: controllers/collections_controller.php:1080
+msgid "collection_error_saving_comment"
+msgstr "S'ha produït un error quan es desava el comentari."
+
+#. %1$s is a number.
+#: models/collection.php:122
+msgid "collection_name_limit"
+msgstr "El nom hauria de tenir menys de %1$s caràcters."
+
+#: controllers/collections_controller.php:352
+#: controllers/collections_controller.php:487
+msgid "collection_not_found"
+msgstr "No s'ha trobat l'agrupació."
+
+#. %1$s is the text on the "create collection" button
+#: views/collections/add.thtml:91
+msgid "collections_add_formfield_addons_description"
+msgstr ""
+"Si ja sabeu quins complements voleu afegir a la vostra col·lecció, comenceu "
+"a escriure els seu noms a continuació. Si preferiu fer-ho més tard, cliqueu %"
+"1$s ara."
+
+#: views/collections/add.thtml:90
+msgid "collections_add_formfield_firstaddons"
+msgstr "Escolliu els vostres primers complements"
+
+#: views/collections/add.thtml:48
+msgid "collections_add_header"
+msgstr "Crea una col·lecció"
+
+#: views/collections/add.thtml:97
+msgid "collections_add_header_selectedaddons"
+msgstr "Complements seleccionats"
+
+#: views/collections/add.thtml:50
+msgid "collections_add_intro"
+msgstr ""
+"Crear-vos la vostre pròpia col·lecció de complements és tan senzill com "
+"omplir els camps següents."
+
+#: views/collections/add.thtml:92 views/collections/add.thtml:103
+msgid "collections_add_submit"
+msgstr "Crea una col·lecció"
+
+#: views/pages/collector_faq.thtml:50 views/pages/collector_firstrun.thtml:43
+#: views/pages/collector.thtml:47 views/pages/collector_features.thtml:55
+#: controllers/search_controller.php:302
+#: controllers/collections_controller.php:206
+#: controllers/collections_controller.php:405
+#: controllers/collections_controller.php:467
+#: controllers/collections_controller.php:539
+msgid "collections_breadcrumb"
+msgstr "Col·leccions"
+
+#: views/collections/detail.thtml:185
+msgid "collections_detail_a_learn"
+msgstr "Més informació"
+
+#: views/elements/amo2009/collection_add_form.thtml:53
+#: views/elements/amo2009/collections_js_init.thtml:68
+#: views/pages/collector_firstrun.thtml:64
+msgid "collections_detail_button_add"
+msgstr "Afegeix-la a les preferides"
+
+#: views/elements/amo2009/collection_add_form.thtml:50
+#: views/elements/amo2009/collections_js_init.thtml:71
+msgid "collections_detail_button_remove"
+msgstr "Suprimeix-la de les preferides"
+
+#. %1$s is a URL.
+#. %2$s is a full <a href>.
+#: views/collections/detail.thtml:62
+msgid "collections_detail_created_desc"
+msgstr ""
+"<p>Podeu visualitzar la vostra nova co·lecció a continuació. Si voleu donar-"
+"li un àlies, afegir-li una icona o modificar més opcions, aneu a la pàgina "
+"<a href='%1$s'>Gestiona les col·leccions</a>.</p><p>Podreu accedir a la "
+"vostra col·lecció des d'aquí: %2$s</p>"
+
+#: views/collections/detail.thtml:61
+msgid "collections_detail_created_msg"
+msgstr "La vostra col·lecció ja està feta."
+
+#: views/collections/detail.thtml:109
+msgid "collections_detail_header_about"
+msgstr "En quant a aquesta col·lecció"
+
+#. %1$s is a number.
+#: views/collections/detail.thtml:126
+msgid "collections_detail_header_count"
+msgid_plural "collections_detail_header_count"
+msgstr[0] "%1$s complement en aquesta col·lecció"
+msgstr[1] "%1$s complements en aquesta col·lecció"
+
+#: views/collections/detail.thtml:113
+msgid "collections_detail_info_created"
+msgstr "<strong>Creada per:</strong> %1$s"
+
+#: views/collections/detail.thtml:117
+msgid "collections_detail_info_updated"
+msgstr "<strong>Actualitzada:</strong>"
+
+#: views/elements/amo2009/collections_js_init.thtml:62
+msgid "collections_detail_js_adding"
+msgstr "S'està afegint a les preferides&hellip;"
+
+#: views/elements/amo2009/collections_js_init.thtml:65
+msgid "collections_detail_js_removing"
+msgstr "S'està suprimint de les preferides&hellip;"
+
+#. %1$s is a URL
+#: views/collections/detail.thtml:90
+msgid "collections_detail_login"
+msgstr ""
+"<a href=\"%1$s\">Inicia una sessió</a> per a afegir aquesta col·lecció a les "
+"vostres preferides."
+
+#: views/collections/detail.thtml:104
+msgid "collections_detail_manage"
+msgstr "Gestiona la col·lecció"
+
+#: controllers/collections_controller.php:298
+msgid "collections_detail_sort_date"
+msgstr "Data"
+
+#: controllers/collections_controller.php:299
+msgid "collections_detail_sort_name"
+msgstr "Nom"
+
+#: controllers/collections_controller.php:300
+msgid "collections_detail_sort_popularity"
+msgstr "Popularitat"
+
+#. %1$s is a number.
+#: views/collections/detail.thtml:166
+msgid "collections_detail_weekly_downloads"
+msgid_plural "collections_detail_weekly_downloads"
+msgstr[0] "%1$s baixada aquesta setmana"
+msgstr[1] "%1$s baixades aquesta setmana"
+
+#: views/collections/edit.thtml:255
+msgid "collections_edit_addons_delete_noscript"
+msgstr "Els complements seleccionats se suprimiran després de desar"
+
+#: views/collections/edit.thtml:247
+msgid "collections_edit_addons_description"
+msgstr ""
+"Per a publicar complements nous a aquesta col·lecció, introduïu-ne els noms "
+"a continuació."
+
+#: views/collections/edit.thtml:248
+msgid "collections_edit_addons_description_noscript"
+msgstr ""
+"Per a publicar complements nous a aquesta col·lecció, introduïu a "
+"continuació una llista separada per comes dels ID dels complements."
+
+#: views/collections/edit.thtml:247 views/collections/edit.thtml:248
+msgid "collections_edit_addons_description_publish_detailspage"
+msgstr ""
+"També podeu publicar un complement des de la llista de complements normal."
+
+#. %1$s is the date the add-on was added to the collection
+#. %1$s is the name of the user who added the add-on to the collection
+#: views/collections/edit.thtml:260
+msgid "collections_edit_addons_listitem_added"
+msgstr "%2$s va afegir-lo el %1$s"
+
+#: views/collections/edit.thtml:263
+msgid "collections_edit_addons_listitem_comment_add"
+msgstr "Afegeix un comentari a la publicació"
+
+#: views/collections/edit.thtml:266
+msgid "collections_edit_addons_listitem_comment_delete"
+msgstr "Suprimeix el comentari de la publicació"
+
+#: views/collections/edit.thtml:265
+msgid "collections_edit_addons_listitem_comment_edit"
+msgstr "Edita el comentari de la publicació"
+
+#: views/collections/edit.thtml:271
+msgid "collections_edit_addons_listitem_comment_note"
+msgstr ""
+"Atenció: el comentari apareixerà tal com va ser publicat originalment en la "
+"data de publicació."
+
+#: views/collections/edit.thtml:270
+msgid "collections_edit_addons_listitem_comment_submit"
+msgstr "Desa el comentari"
+
+#: views/collections/edit.thtml:261
+msgid "collections_edit_addons_listitem_remove"
+msgstr "Suprimeix"
+
+#: views/collections/edit.thtml:250
+msgid "collections_edit_addons_submit"
+msgstr "Afegeix una col·lecció"
+
+#: views/collections/edit.thtml:153
+msgid "collections_edit_check_nickname"
+msgstr "Comprova la disponibilitat"
+
+#: views/collections/edit.thtml:299
+msgid "collections_edit_confirm_deletecollection"
+msgstr "Sí, vull suprimir aquesta col·lecció."
+
+#. %1$s is the label of the edit form's submit button
+#: views/collections/edit.thtml:300
+msgid "collections_edit_confirm_deletecollection_description"
+msgstr ""
+"Marqueu la casella, i després cliqueu \"%1$s\" per a suprimir la col·lecció."
+
+#. %1$s is the "delete" submit button text
+#. %2$s is the title of the "advanced" tab
+#: views/collections/edit.thtml:95
+msgid "collections_edit_delete_upon_submit"
+msgstr ""
+"Després de clicar el botó \"%1$s\", es suprimirà la vostra col·lecció. Si no "
+"voleu suprimir la vostra col·lecció, no marqueu la casella de confirmació de "
+"la pestanya \"%2$s\" i continueu editant la col·lecció. Si abandoneu aquesta "
+"pàgina sense desar-la, la vostra col·lecció tampoc s'esborrarà."
+
+#: views/collections/edit.thtml:94
+msgid "collections_edit_delete_warning"
+msgstr "La vostra col·lecció es suprimirà."
+
+#: views/collections/add.thtml:76 views/collections/edit.thtml:144
+msgid "collections_edit_form_error_description"
+msgstr "Cal que introduïu una descripció de la vostra col·lecció."
+
+#: views/collections/edit.thtml:181
+msgid "collections_edit_form_error_icon"
+msgstr "S'ha produït un error mentre es pujava la vostra icona."
+
+#: views/collections/add.thtml:69 views/collections/edit.thtml:130
+msgid "collections_edit_form_error_name"
+msgstr "Cal que doneu un nom a la col·lecció."
+
+#: views/collections/edit.thtml:158
+msgid "collections_edit_form_error_nickname"
+msgstr "Si escolliu un àlies, cal que sigui únic."
+
+#: views/collections/add.thtml:93 views/collections/edit.thtml:249
+msgid "collections_edit_formfield_addons"
+msgstr "Nom del complement:"
+
+#: views/collections/edit.thtml:281
+msgid "collections_edit_formfield_application"
+msgstr "Aplicació associada"
+
+#: views/collections/edit.thtml:282
+msgid "collections_edit_formfield_application_description"
+msgstr "Seleccioneu l'aplicació amb la qual funciona la vostra col·lecció."
+
+#: views/collections/edit.thtml:288
+msgid "collections_edit_formfield_collectiontype"
+msgstr "Tipus de col·lecció"
+
+#: views/collections/edit.thtml:295
+msgid "collections_edit_formfield_deletecollection"
+msgstr "Suprimeix la col·lecció"
+
+#: views/collections/edit.thtml:296
+msgid "collections_edit_formfield_deletecollection_description"
+msgstr "Si suprimiu la col·lecció, s'esborrarà per sempre."
+
+#: views/collections/add.thtml:73 views/collections/edit.thtml:140
+msgid "collections_edit_formfield_description"
+msgstr "Descripció de la col·lecció"
+
+#: views/collections/add.thtml:74 views/collections/edit.thtml:141
+msgid "collections_edit_formfield_description_description"
+msgstr ""
+"Descriviu breument la vostra col·lecció i el tipus de complements que conté"
+
+#: views/collections/edit.thtml:162
+msgid "collections_edit_formfield_icon"
+msgstr "Icona"
+
+#: views/collections/edit.thtml:163
+msgid "collections_edit_formfield_icon_description"
+msgstr ""
+"Podeu pujar icones tipus JPG, GIF o PNG, les icones s'escalaran a 32x32 "
+"píxels."
+
+#: views/collections/add.thtml:80 views/collections/edit.thtml:189
+msgid "collections_edit_formfield_listed"
+msgstr "Qui podrà veure la vostra col·lecció?"
+
+#: views/collections/add.thtml:81 views/collections/edit.thtml:190
+msgid "collections_edit_formfield_listed_description"
+msgstr ""
+"Per defecte, la col·lecció apareixerà en el Directori de col·leccions públic "
+"i la podrà veure tothom. Si voleu restringir la visibilitat de la vostra "
+"col·lecció a només a les persones a qui li heu donat un enllaç especial, "
+"marqueu la següent opció."
+
+#: views/collections/add.thtml:84 views/collections/edit.thtml:193
+msgid "collections_edit_formfield_listed_false"
+msgstr "Només les persones que jo inviti podran veure la meva col·lecció"
+
+#: views/collections/add.thtml:83 views/collections/edit.thtml:192
+msgid "collections_edit_formfield_listed_true"
+msgstr "Tothom pot veure la meva col·lecció en el directori"
+
+#: views/collections/edit.thtml:223
+msgid "collections_edit_formfield_managers"
+msgstr "Qui pot gestionar la meva col·lecció?"
+
+#: views/collections/edit.thtml:224
+msgid "collections_edit_formfield_managers_description"
+msgstr ""
+"Aquests usuaris poden publicar complements a la vostra col·lecció, gestinar-"
+"los, canviar-ne les opcions i modificar els permisos d'altres usuaris."
+
+#: views/collections/add.thtml:66 views/collections/edit.thtml:126
+msgid "collections_edit_formfield_name"
+msgstr "Nom de la col·lecció"
+
+#: views/collections/add.thtml:67 views/collections/edit.thtml:127
+msgid "collections_edit_formfield_name_description"
+msgstr ""
+"Cal que doneu un nom descriptiu a la vostra col·lecció, com per exemple "
+"\"Els millors complements per a viatges d'en David\""
+
+#: views/collections/edit.thtml:148
+msgid "collections_edit_formfield_nickname"
+msgstr "Àlias de la col·lecció"
+
+#: views/collections/edit.thtml:149
+msgid "collections_edit_formfield_nickname_description"
+msgstr ""
+"Opcionalment, podeu donar un àlias únic a la vostra col·lecció per a trobar-"
+"la més ràpidament:"
+
+#: views/collections/edit.thtml:201
+msgid "collections_edit_formfield_publishers"
+msgstr "Qui pot publicar complements a la vostra col·lecció?"
+
+#: views/collections/edit.thtml:202
+msgid "collections_edit_formfield_publishers_description"
+msgstr ""
+"Aquests usuaris poden publicar complements a la vostra col·lecció i suprimir "
+"només els que hagin publicat."
+
+#: views/collections/edit.thtml:210 views/collections/edit.thtml:232
+msgid "collections_edit_formfield_users_add"
+msgstr "Introduïu l'adreça electrònica d'un compte de Firefox Add-ons:"
+
+#: views/collections/edit.thtml:216 views/collections/edit.thtml:238
+msgid "collections_edit_formfield_users_delete_noscript"
+msgstr "Els comptes seleccionats es suprimiran quan es desi"
+
+#: views/collections/edit.thtml:215 views/collections/edit.thtml:237
+msgid "collections_edit_formfield_users_new_noscript"
+msgstr ""
+"Introduïu una llista d'adreces electròniques de comptes de Firefox Add-ons "
+"separades per comes"
+
+#: views/collections/edit.thtml:204 views/collections/edit.thtml:226
+msgid "collections_edit_formfield_users_onlyme"
+msgstr "Només jo"
+
+#: views/collections/edit.thtml:205 views/collections/edit.thtml:227
+msgid "collections_edit_formfield_users_otherusers"
+msgstr "Jo i aquests usuaris:"
+
+#: views/collections/edit.thtml:211 views/collections/edit.thtml:233
+msgid "collections_edit_formfield_users_submit"
+msgstr "Afegeix"
+
+#. %1$s is the name of the collection
+#: views/collections/edit.thtml:68
+msgid "collections_edit_header"
+msgstr "Gestiona %1$s"
+
+#: views/collections/edit.thtml:246
+msgid "collections_edit_header_addons"
+msgstr "Gestiona el contingut de la col·lecció"
+
+#: views/collections/edit.thtml:253 views/collections/edit.thtml:258
+msgid "collections_edit_header_addons_current"
+msgstr "Complements actuals:"
+
+#: views/collections/edit.thtml:279
+msgid "collections_edit_header_advanced"
+msgstr "Opcions avançades"
+
+#: views/collections/edit.thtml:186
+msgid "collections_edit_header_permissions"
+msgstr "Gestiona els permisos de la col·lecció"
+
+#: views/collections/edit.thtml:170
+msgid "collections_edit_icon_cancel"
+msgstr "Cancel·la"
+
+#: views/collections/edit.thtml:174 views/collections/edit.thtml:179
+msgid "collections_edit_icon_delete"
+msgstr "Suprimeix la icona"
+
+#: views/collections/edit.thtml:178
+msgid "collections_edit_icon_replace"
+msgstr "Canvia la icona"
+
+#. %1$s is the label of the edit form's submit button
+#: views/collections/edit.thtml:169
+msgid "collections_edit_icon_toberemoved"
+msgstr "La icona es suprimirà quan cliqueu el botó \"%1$s\""
+
+#: views/collections/edit.thtml:155
+msgid "collections_edit_nickname_available"
+msgstr "L'àlies està disponible"
+
+#: controllers/collections_controller.php:943
+msgid "collections_edit_nickname_error"
+msgstr ""
+"El vostre àlies té caràcters incorrectes i s'ha de corregir. Torneu-ho a "
+"intentar."
+
+#: views/collections/edit.thtml:156
+msgid "collections_edit_nickname_taken"
+msgstr "L'àlies ja està agafat"
+
+#. This string is followed by a URL pointing to the collection's view page
+#: views/collections/edit.thtml:75
+msgid "collections_edit_saved_nextstep"
+msgstr "La vostra col·lecció es pot accedir des d'aquesta ubicació:"
+
+#: views/collections/edit.thtml:74
+msgid "collections_edit_saved_success"
+msgstr "La vostra col·lecció s'ha desat satisfactòriament."
+
+#: views/collections/edit.thtml:169 views/collections/edit.thtml:300
+#: views/collections/edit.thtml:308 views/pages/js_constants.js.thtml:99
+msgid "collections_edit_submit"
+msgstr "Actualitza la col·lecció"
+
+#: views/collections/edit.thtml:96 views/collections/edit.thtml:297
+#: views/pages/js_constants.js.thtml:100
+msgid "collections_edit_submit_deletecollection"
+msgstr "Suprimeix la col·lecció"
+
+#: views/collections/edit.thtml:111
+msgid "collections_edit_tabheader_addons"
+msgstr "Complements"
+
+#: views/collections/edit.thtml:97 views/collections/edit.thtml:113
+msgid "collections_edit_tabheader_advanced"
+msgstr "Avançades"
+
+#: views/collections/edit.thtml:108
+msgid "collections_edit_tabheader_details"
+msgstr "Nom &amp; detalls"
+
+#: views/collections/edit.thtml:109
+msgid "collections_edit_tabheader_permissions"
+msgstr "Permisos"
+
+#: models/collection_promo.php:53
+msgid "collections_family_tagline"
+msgstr ""
+"Complements que poden vigilar els vostres fills i controlar el vostre "
+"calendari."
+
+#: models/collection_promo.php:53
+msgid "collections_family_title"
+msgstr "Organitzador familiar"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:70
+msgid "collections_index_a_check_out"
+msgstr "Mireu-vos l'Add-on Collector"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:52
+msgid "collections_index_a_create"
+msgstr "Crea una col·lecció"
+
+#: views/collections/detail.thtml:139 views/collections/listing.thtml:85
+#: views/search/collections.thtml:84
+msgid "collections_index_button_go"
+msgstr "Vés"
+
+#. %1$s is a URL.
+#: controllers/collections_controller.php:182
+msgid "collections_index_filler_favorites"
+msgstr ""
+"<p><strong>Encara no teniu col·leccions preferides.</strong></p> <p>Les "
+"col·leccions que marqueu com a preferides es poden accedir ràpidament des "
+"d'aquesta pàgina, i apareixeran en <a href='%1$s'>l'Add-on Collector</a> si "
+"encara no el teniu.</p>"
+
+#. %1$s is a URL.
+#: controllers/collections_controller.php:167
+msgid "collections_index_filler_mine"
+msgstr ""
+"<p>Encara no heu creat cap col·lecció. Les col·leccions són fàcils de crear "
+"i omplir amb els vostres complements preferits. <a href='%1$s'>Proveu-ho</"
+"a>!</p>"
+
+#: views/collections/listing.thtml:51
+msgid "collections_index_header_collections"
+msgstr "Col·leccions"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:60
+msgid "collections_index_header_collector"
+msgstr "Add-on Collector"
+
+#. %1$s is a comma-separated list of author names
+#: views/elements/amo2009/collection_listing_item.thtml:84
+#: views/collections/detail.thtml:151
+msgid "collections_index_header_created"
+msgstr "creada per %1$s"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:47
+msgid "collections_index_header_what"
+msgstr "Què són les col·leccions?"
+
+#: views/collections/detail.thtml:132 views/collections/listing.thtml:78
+#: views/search/collections.thtml:66
+msgid "collections_index_label_sortby"
+msgstr "Ordena per"
+
+#: controllers/collections_controller.php:130
+msgid "collections_index_li_editors"
+msgstr "Les destacades per un editor"
+
+#: views/collections/subscribe.thtml:64
+#: controllers/collections_controller.php:140
+msgid "collections_index_li_favorites"
+msgstr "Les meves preferides"
+
+#: controllers/collections_controller.php:138
+msgid "collections_index_li_mine"
+msgstr "Les meves col·leccions"
+
+#: controllers/collections_controller.php:132
+msgid "collections_index_li_popular"
+msgstr "Popular"
+
+#: views/search/collections.thtml:74 controllers/collections_controller.php:81
+msgid "collections_index_option_all"
+msgstr "Les més famoses de tots els temps"
+
+#: views/search/collections.thtml:72 controllers/collections_controller.php:78
+msgid "collections_index_option_month"
+msgstr "Les més populars d'aquest mes"
+
+#: views/search/collections.thtml:76 controllers/collections_controller.php:84
+msgid "collections_index_option_newest"
+msgstr "Les més noves"
+
+#: views/search/collections.thtml:70 controllers/collections_controller.php:75
+msgid "collections_index_option_week"
+msgstr "Les més populars d'aquesta setmana"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:67
+msgid "collections_index_p_collector"
+msgstr ""
+"Hi ha una nova manera per a gestiona i trobar els millors complements. "
+"Comenteu, compartiu i sincronitzeu les col·leccions, i tot des del vostre "
+"navegador"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:48
+msgid "collections_index_p_what_are"
+msgstr ""
+"Les col·leccions són agrupacions de complements que s'han aplegat per a "
+"compartir-los fàcilment."
+
+#. %s is a date in the _('date') format
+#: views/elements/collections_interactive_addon.thtml:85
+#, php-format
+msgid "collections_interactive_addon_added"
+msgstr "S'ha afegit %s"
+
+#: models/collection_promo.php:55
+msgid "collections_reference_tagline"
+msgstr "Complements que poden millorar la cerca en línia."
+
+#: models/collection_promo.php:55
+msgid "collections_reference_title"
+msgstr "Taula de referències"
+
+#: models/collection_promo.php:52
+msgid "collections_social_tagline"
+msgstr "Complements per a gestionar les vostres xarxes socials."
+
+#: models/collection_promo.php:52
+msgid "collections_social_title"
+msgstr "Circuït social"
+
+#: views/collections/subscribe.thtml:91
+msgid "collections_subscribe_button_close"
+msgstr "Tanca"
+
+#: views/collections/subscribe.thtml:70
+msgid "collections_subscribe_error"
+msgstr ""
+"S'ha produït un error mentre s'intentava afegir una col·lecció preferida. "
+"Potser aquesta col·lecció ja era una preferida?"
+
+#: views/collections/subscribe.thtml:96
+msgid "collections_subscribe_label_bothersome"
+msgstr "No em tornis a mostrar aquest missatge."
+
+#. %1$s is the collection name
+#: views/collections/subscribe.thtml:60
+msgid "collections_subscribe_success"
+msgstr "La col·lecció %1$s s'ha afegit a les preferides."
+
+#. %1$s is the link to the "My Favorites" tab on the main collections page
+#. %2$s is the localized title of the "My Favorites" tab
+#. %3$s is the link URL to the collector add-on
+#: views/collections/subscribe.thtml:62
+msgid "collections_subscribe_success_desc"
+msgstr ""
+"Ara podeu trobar ràpidament aquesta col·lecció des de la pestanya <a href=\"%"
+"1$s\">%2$s</a> del directori. Si encara voleu trobar les vostres "
+"col·leccions preferides més fàcilemnt, proveu l'extensió del Firefox <a href="
+"\"%3$s\">Add-on Collector</a>."
+
+#: views/collections/listing.thtml:55
+msgid "collections_success_delete"
+msgstr "S'ha suprimit la col·lecció."
+
+#: models/collection_promo.php:54
+msgid "collections_travel_tagline"
+msgstr "Complements que us poden convertir en una agència de viatges."
+
+#: models/collection_promo.php:54
+msgid "collections_travel_title"
+msgstr "Agència de viatges"
+
+#. A collection of add-ons that is automatically built for a user. They are "automatically published" to this collection.
+#: controllers/collections_controller.php:581
+msgid "collections_type_autopublisher"
+msgstr "Publicació automàtica"
+
+#. A collection that has been chosen by an Editor as notable or exceptional
+#: controllers/collections_controller.php:582
+msgid "collections_type_editorspick"
+msgstr "Destacada per un editor"
+
+#: controllers/collections_controller.php:580
+msgid "collections_type_normal"
+msgstr "Normal"
+
+#: views/collections/subscribe.thtml:84
+msgid "collections_unsubscribe_error"
+msgstr ""
+"S'ha produït un error mentre s'intentava suprimir una col·lecció preferida. "
+"Potser aquesta col·lecció no era preferida?"
+
+#. %1$s is the collection name
+#: views/collections/subscribe.thtml:78
+msgid "collections_unsubscribe_success"
+msgstr "La col·lecció %1$s s'ha suprimit de les vostres preferides."
+
+#: models/collection_promo.php:56
+msgid "collections_webdev_tagline"
+msgstr "Complements per a crear fàcilment el perfecte lloc web."
+
+#: models/collection_promo.php:56
+msgid "collections_webdev_title"
+msgstr "Barra d'eines del desenvolupador web"
+
+#: views/elements/amo2009/collections_sidebar_whatare.thtml:40
+msgid "collections_whatare_header"
+msgstr "Què són les col·leccions?"
+
+#: views/elements/amo2009/collections_sidebar_whatare.thtml:45
+msgid "collections_whatare_learnmore"
+msgstr "Llegiu les PMF"
+
+#: views/elements/amo2009/collections_sidebar_whatare.thtml:44
+msgid "collections_whatare_text"
+msgstr ""
+"Hi ha una nova manera de gestionar i trobar els vostres complements "
+"preferits. Comenteu, compartiu i sincronitzeu col·leccions de complements. "
+"Tot des del vostre navegador."
+
+#: views/pages/collector_faq.thtml:61 views/pages/collector_features.thtml:67
+msgid "collector_features_a_home"
+msgstr "Pàgina web de l'Add-on Collector"
+
+#: views/elements/amo2009/collector_sidebar_download.thtml:46
+msgid "collector_features_heading_download"
+msgstr "Baixeu-vos l'Add-on Collector:"
+
+#: views/elements/amo2009/collector_sidebar_download.thtml:43
+#: views/pages/collector_firstrun.thtml:116 views/pages/collector.thtml:69
+msgid "collector_features_img_logo"
+msgstr "Logotip de l'Add-on Collector"
+
+#: views/compatibility/dashboard.thtml:49
+#: controllers/compatibility_controller.php:72
+msgid "compatibility_dashboard_center_header"
+msgstr "Centre de compatibilitat dels complements"
+
+#. %1$s is the name of an application and a version. Example: Firefox 3.0
+#. %2$s is the name of an application. Example: Firefox
+#: views/compatibility/dashboard.thtml:50
+msgid "compatibility_dashboard_intro"
+msgstr ""
+"Prepareu-vos per a la versió final del %1$s amb les eines i la informació "
+"disponible per a la comunitat de complements del %2$s que trobareu a "
+"continuació."
+
+#: views/compatibility/dashboard.thtml:103
+msgid "compatibility_dashboard_loading"
+msgstr "S'estan carregant les dades..."
+
+#: views/compatibility/dashboard.thtml:45
+msgid "compatibility_dashboard_main_link"
+msgstr "Torna a l'inici"
+
+#: views/compatibility/dashboard.thtml:100 views/compatibility/report.thtml:43
+msgid "compatibility_dashboard_report"
+msgstr "Informe de compatibilitat del complement"
+
+#: views/compatibility/dashboard.thtml:53
+#: views/compatibility/dashboard.thtml:110
+#: views/compatibility/developers.thtml:43
+msgid "compatibility_developer_info"
+msgstr "Informació per als desenvolupadors de complements"
+
+#: views/compatibility/developers.thtml:66
+msgid "compatibility_developers_adjust_maxversion"
+msgstr "Ajusta el maxVersion sense pujar el fitxer"
+
+#: views/compatibility/dashboard.thtml:124
+msgid "compatibility_developers_check_status"
+msgstr "Comprova l'estat dels complements"
+
+#. %1$s is a URL
+#. %2$s is an application and version. Example: Firefox 3.0
+#: views/compatibility/dashboard.thtml:126
+msgid "compatibility_developers_login_first"
+msgstr ""
+"Si teniu complements hostatjats al Mozilla Add-ons, <a href=\"%1$s"
+"\">registreu-vos</a> per a veure l'estat dels vostres complements per al %2"
+"$s."
+
+#: views/compatibility/dashboard.thtml:114
+msgid "compatibility_developers_mdclogo_alt"
+msgstr "Logotip del Centre de desenvolupadors de Mozilla"
+
+#: views/compatibility/developers.thtml:73
+msgid "compatibility_developers_no_addons"
+msgstr "No teniu cap complement hostatjat al Mozilla Add-ons."
+
+#: views/compatibility/dashboard.thtml:133
+#: views/compatibility/developers.thtml:55
+msgid "compatibility_developers_results"
+msgstr "Resultats de la comprovació del complement"
+
+#: views/compatibility/dashboard.thtml:137
+msgid "compatibility_developers_retrieving"
+msgstr "S'està recuperant l'estat dels complements hostatjats..."
+
+#. %1$s is a number
+#. %2$s is an application name
+#. %3$s is a number.
+#. Full example: 50 Firefox users (10% of total)
+#: views/compatibility/developers.thtml:65
+msgid "compatibility_developers_user_count"
+msgstr "%1$s %2$s usuaris (%3$s&#37; del total)"
+
+#: views/compatibility/report.thtml:45
+msgid "compatibility_report_detail_intro"
+msgstr ""
+"Els següents complements, que es mostren ordenats segons la utilització, "
+"tenen una utilització superior al 95%, segons les dades que disposa Mozilla. "
+
+#: views/compatibility/dashboard.thtml:94
+msgid "compatibility_report_detailed_link"
+msgstr "Mostra l'informe detallat"
+
+#. %1$s and %2$s are numbers
+#. %3$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:65
+msgid "compatibility_report_intro"
+msgstr ""
+"Dels %1$s complements que tenen una utilització superior del 95&#37;, que "
+"tingui constància Mozilla, <b>%2$s&#37;</b> es consideren actualment "
+"compatibles amb l'última versió del %3$s."
+
+#: views/compatibility/dashboard.thtml:81
+msgid "compatibility_report_legend_alpha"
+msgstr "Versions Alfa"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:81
+msgid "compatibility_report_legend_alpha_description"
+msgstr "Complements compatibles amb una versió alfa del %1$s"
+
+#: views/compatibility/dashboard.thtml:85
+msgid "compatibility_report_legend_beta"
+msgstr "Versions Beta"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:85
+msgid "compatibility_report_legend_beta_description"
+msgstr ""
+"Complements compatibles amb una versió beta o amb una versió candidata a "
+"versió final del %1$s"
+
+#: views/compatibility/dashboard.thtml:89
+msgid "compatibility_report_legend_latest"
+msgstr "Última versió"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:89
+msgid "compatibility_report_legend_latest_description"
+msgstr "Complements actualitzats per a l'última versió del %1$s"
+
+#: views/compatibility/dashboard.thtml:77
+msgid "compatibility_report_legend_other"
+msgstr "Altres versions"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:77
+msgid "compatibility_report_legend_other_description"
+msgstr "Complements que no són compatibles amb cap de les versions del %1$s"
+
+#: views/compatibility/dashboard.thtml:62
+msgid "compatibility_report_title"
+msgstr "Informe de compatibilitat del complement"
+
+#: views/compatibility/dashboard.thtml:54
+#: views/compatibility/dashboard.thtml:144 views/compatibility/users.thtml:42
+msgid "compatibility_user_info"
+msgstr "Informació per als usuaris del complement"
+
+#: views/compatibility/dashboard.thtml:52
+msgid "compatibility_view_report"
+msgstr "Mostra l'informe de compatibilitat"
+
+#. %s is a URL
+#: views/pages/credits.thtml:142
+#, php-format
+msgid "credits_contributing"
+msgstr "Per a més informació de com contribuir, consulteu la nostra %s."
+
+#: views/pages/credits.thtml:142
+msgid "credits_contributing_wikipage"
+msgstr "pàgina wiki"
+
+#: views/pages/credits.thtml:99
+msgid "credits_intro"
+msgstr ""
+"Mozilla voldria agrair a les persones següents la contribució al projecte "
+"addons.mozilla.org al llarg dels anys:"
+
+#: views/pages/credits.thtml:103
+msgid "credits_section_developers"
+msgstr "Desenvolupadors"
+
+#: views/pages/credits.thtml:115
+msgid "credits_section_editors"
+msgstr "Editors"
+
+#: views/pages/credits.thtml:109
+msgid "credits_section_localizers"
+msgstr "Traductors"
+
+#: views/pages/credits.thtml:121
+msgid "credits_section_other_contributors"
+msgstr "Altres col·laboradors"
+
+#: views/pages/credits.thtml:127
+msgid "credits_section_past_developers"
+msgstr "Antics desenvolupadors"
+
+#: views/pages/credits.thtml:133
+msgid "credits_section_software"
+msgstr "Programes i imatges"
+
+#: views/pages/credits.thtml:136
+msgid "credits_software_famfamfam"
+msgstr ""
+"Algunes icones que s'han utilitzat són del <a href=\"http://www.famfamfam."
+"com/lab/icons/silk/\">Conjunt d'icones Seda de famfamfam</a>, amb llicència "
+"<a href=\"http://creativecommons.org/licenses/by/2.5/\">Creative Commons "
+"Attribution 2.5 License</a>."
+
+#: views/pages/credits.thtml:137
+msgid "credits_software_timeplot"
+msgstr ""
+"Algunes pàgines utilitzen elements de <a href=\"http://www.simile-widgets."
+"org/timeplot/\">Timeplot</a>, que té una <a href=\"http://simile.mit.edu/"
+"license.html\">llicència BSD</a>."
+
+#. date format string as used in PHP's strftime():
+#. http://php.net/strftime
+#: views/elements/collections_interactive_addon.thtml:85
+#: views/elements/amo2009/addon_version_detail.thtml:53
+#: views/elements/amo2009/homepage_addon.thtml:115
+#: views/elements/addon_version_detail.thtml:54
+#: views/elements/addon_listitem.thtml:124 views/elements/feature.thtml:106
+#: views/collections/detail.thtml:118 views/collections/edit.thtml:325
+#: views/users/info.thtml:76 views/editors/reviews_queue.thtml:57
+#: views/editors/reviews_queue.thtml:68 views/developers/dashboard.thtml:65
+#: views/developers/versions_edit.thtml:208 views/developers/versions.thtml:67
+#: views/search/rss/index.thtml:5 views/addons/rss/versions.thtml:42
+#: views/addons/display.thtml:104 views/addons/display.thtml:356
+#: views/addons/browse_thumbs.thtml:75 views/reviews/add.thtml:63
+#: views/reviews/display.thtml:74 views/reviews/display.thtml:160
+#: views/reviews/delete.thtml:54 controllers/statistics_controller.php:244
+#: controllers/collections_controller.php:1047
+msgid "date"
+msgstr "%e %B %Y"
+
+#. date and time format string (strftime)
+#. http://php.net/strftime
+#: views/elements/addon_version_detail.thtml:53
+#: views/developers/discuss.thtml:52 views/developers/discuss.thtml:62
+#: views/admin/addons_status.thtml:57
+msgid "datetime"
+msgstr "%e %B %Y, %H:%M"
+
+#: views/elements/developers/actionbar.thtml:47
+msgid "devcp_actionbar_link_details"
+msgstr "Informació detallada"
+
+#: views/elements/developers/actionbar.thtml:42
+#: views/elements/developers/actionbar.thtml:50
+#: views/developers/dashboard.thtml:64
+msgid "devcp_actionbar_link_edit"
+msgstr "Edita el complement"
+
+#: views/elements/developers/actionbar.thtml:51
+msgid "devcp_actionbar_link_newversion"
+msgstr "Puja una nova versió"
+
+#: views/elements/developers/actionbar.thtml:44
+#: views/elements/developers/actionbar.thtml:49
+#: views/developers/dashboard.thtml:73
+msgid "devcp_actionbar_link_stats"
+msgstr "Estadístiques"
+
+#. %1$s is a filename, e.g. "foo.txt"
+#. %2$s is the extension, e.g. ".txt"
+#. %3$s is a list of valid extensions, like ".png, .jpg, .gif"
+#: controllers/developers_controller.php:1361
+msgid "devcp_add_previews_extension_error"
+msgstr ""
+"El fitxer %1$s té una extensió que no és vàlida (%2$s). Les extensions "
+"permeses són: %3$s"
+
+#. %s is the filename.
+#: controllers/developers_controller.php:1394
+msgid "devcp_add_previews_save_error"
+msgstr ""
+"El fitxer %s no s'ha pogut desar a la base de dades. Torneu-ho a provar."
+
+#. %1$s is the preview ID number, %2$s is the filename.
+#: controllers/developers_controller.php:1389
+msgid "devcp_add_previews_success_replace"
+msgstr ""
+"S'ha reemplaçat satisfactòriament la previsualització %1$s amb el fitxer %2"
+"$s."
+
+#. %s is the filename.
+#: controllers/developers_controller.php:1391
+msgid "devcp_add_previews_success_upload"
+msgstr ""
+"S'ha pujat satisfactòriament el fitxer %s. A continuació podeu afegir-li un "
+"títol."
+
+#: controllers/components/developers.php:1163
+msgid "devcp_additem_addontype_autodetect"
+msgstr "(auto-detecta)"
+
+#: views/elements/developers/additem.thtml:76
+msgid "devcp_additem_linktitle_opensin_newwindow"
+msgstr "Obre en una nova finestra"
+
+#: views/elements/developers/additem.thtml:41
+msgid "devcp_additem_sidebar_title"
+msgstr "Envia el complement"
+
+#: views/elements/developers/additem.thtml:53
+msgid "devcp_additem_step0_newlink"
+msgstr "Acord del desenvolupador"
+
+#: views/elements/developers/additem.thtml:46
+msgid "devcp_additem_step1_link"
+msgstr "Pas 1: Enviament"
+
+#: views/elements/developers/additem.thtml:47
+msgid "devcp_additem_step2_link"
+msgstr "Pas 2: Detalls del complement"
+
+#: views/elements/developers/additem.thtml:48
+msgid "devcp_additem_step3_link"
+msgstr "Pas 3: Detalls de la versió"
+
+#: views/elements/developers/additem.thtml:49
+msgid "devcp_additem_step4_link"
+msgstr "Pas 4: Localització"
+
+#: views/elements/developers/additem.thtml:50
+msgid "devcp_additem_step5_link"
+msgstr "Pas 5: Fi"
+
+#: views/elements/developers/additem.thtml:76
+msgid "devcp_additem_submissionhelp_link"
+msgstr "Ajuda a la publicació"
+
+#: controllers/previews_controller.php:168
+#: controllers/previews_controller.php:277
+msgid "devcp_addon_field_preview_caption_displaytitle"
+msgstr "Text de la previsualització"
+
+#: views/developers/addon_status.thtml:177
+msgid "devcp_addon_status_action_activate"
+msgstr "Activa el complement"
+
+#: views/developers/addon_status.thtml:178
+msgid "devcp_addon_status_action_activate_description"
+msgstr ""
+"Activa el vostre complement, el mostra a les llistes públiques i habilita el "
+"servei de validació d'actualitzacions."
+
+#: views/developers/addon_status.thtml:135
+msgid "devcp_addon_status_action_complete"
+msgstr "Dóna per acabat el complement"
+
+#: views/developers/addon_status.thtml:136
+msgid "devcp_addon_status_action_complete_description"
+msgstr "Dóna per acabat el complement i el passa a l'entorn de proves"
+
+#: views/developers/addon_status.thtml:181
+msgid "devcp_addon_status_action_deactivate"
+msgstr "Desactiva el complement"
+
+#: views/developers/addon_status.thtml:182
+msgid "devcp_addon_status_action_deactivate_description"
+msgstr ""
+"Desactiva el vostre complement, l'oculta de les llistes públiques i "
+"deshabilita el servei de validació d'actualitzacions."
+
+#: views/developers/addon_status.thtml:143
+msgid "devcp_addon_status_action_move"
+msgstr "Mou-lo a l'entorn de proves"
+
+#: views/developers/addon_status.thtml:144
+msgid "devcp_addon_status_action_move_description"
+msgstr "Torna el vostre complement a l'entorn de proves. Això és reversible."
+
+#: views/developers/addon_status.thtml:139
+msgid "devcp_addon_status_action_nominate"
+msgstr "Nomina'l per a fer-lo públic"
+
+#: views/developers/addon_status.thtml:140
+msgid "devcp_addon_status_action_nominate_description"
+msgstr "Nomina el vostre complement per a fer-lo públic"
+
+#: views/developers/addon_status.thtml:147
+msgid "devcp_addon_status_action_public"
+msgstr "Publica el complement"
+
+#: views/developers/addon_status.thtml:148
+msgid "devcp_addon_status_action_public_description"
+msgstr "Torna a fer públic el vostre complement."
+
+#: views/developers/addon_status.thtml:169
+msgid "devcp_addon_status_active"
+msgstr ""
+"El vostre complement està <span class=\"inactive-0\">Actiu</span>. Això vol "
+"dir que s'està mostrant a totes les llistes corresponents al seu estat."
+
+#: views/developers/addon_status.thtml:111
+msgid "devcp_addon_status_completion_disabled"
+msgstr ""
+"Cal complir tots els criteris anteriors abans de completar el vostre "
+"complement i moure'l a <span class=\"status-1\">l'entorn de proves</span>."
+
+#: views/developers/addon_status.thtml:108
+msgid "devcp_addon_status_completion_enabled"
+msgstr ""
+"Ara podeu completar el vostre complement i moure'l a <span class=\"status-1"
+"\">l'entorn de proves</span> clicant el botó següent."
+
+#: views/developers/addon_status.thtml:102
+msgid "devcp_addon_status_criteria_category"
+msgstr "Com a mínim cal seleccionar una categoria"
+
+#: views/developers/addon_status.thtml:101
+msgid "devcp_addon_status_criteria_description"
+msgstr "Fa falta escriure una descripció del complement"
+
+#: views/developers/addon_status.thtml:99
+msgid "devcp_addon_status_criteria_name"
+msgstr "Cal donar un nom al complement"
+
+#: views/developers/addon_status.thtml:120
+msgid "devcp_addon_status_criteria_prerelease"
+msgstr "El complement no està marcat com a versió candidata a final."
+
+#: views/developers/addon_status.thtml:119
+msgid "devcp_addon_status_criteria_preview"
+msgstr ""
+"Com a mínim cal una imatge de previsualització per a les extensions i temes."
+
+#: views/developers/addon_status.thtml:100
+msgid "devcp_addon_status_criteria_summary"
+msgstr "Cal un resum del complement"
+
+#. %s is the status in a span, e.g. "<span>_('Public')</span>".
+#: views/developers/addon_status.thtml:58
+msgid "devcp_addon_status_header"
+msgstr "Estat del complement: %s"
+
+#: views/developers/addon_status.thtml:152
+#: views/developers/addon_status.thtml:173
+msgid "devcp_addon_status_header_actions"
+msgstr "Accions disponibles"
+
+#: views/developers/addon_status.thtml:168
+msgid "devcp_addon_status_header_active"
+msgstr "Estat actual: <span class=\"inactive-0\">Actiu</span>"
+
+#: views/developers/addon_status.thtml:97
+msgid "devcp_addon_status_header_criteria"
+msgstr "Criteris per a completar el complement"
+
+#: views/developers/addon_status.thtml:164
+msgid "devcp_addon_status_header_inactive"
+msgstr "Estat actual: <span class=\"inactive-1\">Inactiu</span>"
+
+#: views/developers/addon_status.thtml:117
+msgid "devcp_addon_status_header_nomination"
+msgstr "Criteris per a la nominació pública"
+
+#: views/developers/addon_status.thtml:190
+msgid "devcp_addon_status_header_trusted"
+msgstr "Nivell de confiança: <span class=\"status-4\">de confiança</span>"
+
+#: views/developers/addon_status.thtml:165
+msgid "devcp_addon_status_inactive"
+msgstr ""
+"El vostre complement està <span class=\"inactive-1\">inactiu</span>. Això "
+"vol dir que el vostre complement no es mostrarà a cap llista, tot i el "
+"nivell de confiança anterior. I no se'n publicarà <b>cap</b> actualització "
+"al servei de comprovació d'actualitzacions."
+
+#: views/developers/addon_status.thtml:128
+msgid "devcp_addon_status_nominate_disabled"
+msgstr ""
+"Cal que compliu tots els criteris anteriors abans de nominar el vostre "
+"complement i esdevingui <span class=\"status-4\">públic</span>."
+
+#: views/developers/addon_status.thtml:125
+msgid "devcp_addon_status_nominate_enabled"
+msgstr ""
+"Ara podeu nominar el vostre complement per a què es faci <span class="
+"\"status-4\">públic</span> clicant el botó següent."
+
+#: views/developers/addon_status.thtml:64
+msgid "devcp_addon_status_public"
+msgstr "Públic"
+
+#: views/developers/addon_status.thtml:63
+msgid "devcp_addon_status_sandbox"
+msgstr "A l'entorn de proves"
+
+#. %s is an email address.
+#: views/developers/addon_status.thtml:89
+msgid "devcp_addon_status_switch_disabled"
+msgstr ""
+"El vostre complement l'ha <span class=\"status-5\">deshabilitat</span> un "
+"administrador i no es pot utilitzar. Si voleu fer cap pregunta, escriviu un "
+"correu a %s."
+
+#: views/developers/addon_status.thtml:67
+msgid "devcp_addon_status_switch_incomplete"
+msgstr ""
+"El vostre complement actualment està <span class=\"status-0\">incomplet</"
+"span>. Això significa que no es mostra enlloc del web ni al servei "
+"d'actualitzacions. Podeu tornar a aquesta pàgina per a completar el vostre "
+"complement, i un cop compleixi els criteris següents ja es podrà moure a "
+"<span class=\"status-1\">l'entorn de proves</span>."
+
+#. %s is a number, perhaps 42.
+#: views/developers/addon_status.thtml:77
+msgid "devcp_addon_status_switch_nominated"
+msgstr ""
+"El vostre complement actualment està nominat per a esdevenir <span class="
+"\"status-4\">públic</span> i està a punt per a ser revisat per un editor. A "
+"la cua de nominacions hi ha %s complements més."
+
+#. %s is an email address.
+#: views/developers/addon_status.thtml:81
+msgid "devcp_addon_status_switch_pending"
+msgstr ""
+"El vostre complement està pendent. Això no hauria d'haver passat. Escriviu "
+"un correu a %s amb l'ID del vostre complement i expliqueu que teniu aquest "
+"error."
+
+#: views/developers/addon_status.thtml:85
+msgid "devcp_addon_status_switch_public"
+msgstr ""
+"El vostre complement és <span class=\"status-4\">públic</span>, això "
+"significa que s'està mostrant a totes les llistes i cerques i que es pot "
+"baixar sense cap restricció. També estan disponibles les actualitzacions del "
+"vostre complement a través del servei de comprovació d'actualitzacions."
+
+#: views/developers/addon_status.thtml:71
+#: views/developers/addon_status.thtml:75
+msgid "devcp_addon_status_switch_sandbox"
+msgstr ""
+"El vostre complement està a <span class=\"status-1\">l'entorn de proves</"
+"span>, això vol dir que es mostrarà a en les llistes i les cerques, però els "
+"usuaris s'hauran de registrar i baixar-se'l. I no es publicarà <b>cap</b> "
+"actualització a través del servei de comprovació d'actualitzacions."
+
+#. %s is the add-on name.
+#: views/developers/addon_status_nominate.thtml:43
+#: views/developers/addon_status_confirm.thtml:43
+#: views/developers/addon_status.thtml:43
+msgid "devcp_addon_status_title"
+msgstr "Estat del %s"
+
+#: views/developers/addon_status.thtml:191
+msgid "devcp_addon_status_trusted"
+msgstr ""
+"El vostre complement és <span class=\"status-4\">de confiança</span>. Això "
+"significa que podeu enviar actualitzacions del vostre complement sense la "
+"revisió d'un editor."
+
+#: views/developers/dashboard.thtml:68
+msgid "devcp_dashboard_active"
+msgstr "Actiu"
+
+#. %1$s is the add-on type string
+#. %2$s is Inactive or Active in a <span>
+#. %3$s is the addon's public status (Public, In Sandbox, ...) in a <span>
+#: views/developers/dashboard.thtml:69
+msgid "devcp_dashboard_addontype_status"
+msgstr "%1$s actualment %2$s i %3$s"
+
+#: views/developers/dashboard.thtml:67
+msgid "devcp_dashboard_change_status"
+msgstr "Canvia l'estat"
+
+#. %s is the addons email address.
+#: views/developers/dashboard.thtml:99
+msgid "devcp_dashboard_disabled_questions"
+msgstr ""
+"El vostre complement ha estat deshabilitat per un administrador i no es pot "
+"fer servir. Si teniu cap pregunta, escriviu a %s."
+
+#. %s is the (localized) add-on status string in a span, e.g. "Disabled"
+#: views/developers/dashboard.thtml:98
+msgid "devcp_dashboard_disabled_status"
+msgstr "Estat del complement: %s"
+
+#: views/developers/dashboard.thtml:43
+msgid "devcp_dashboard_header_main"
+msgstr "Consola del desenvolupador"
+
+#: views/developers/dashboard.thtml:110
+msgid "devcp_dashboard_header_welcome"
+msgstr "Benvingut a la consola del desenvolupador"
+
+#: views/developers/dashboard.thtml:68
+msgid "devcp_dashboard_inactive"
+msgstr "Inactiu"
+
+#. %s is a date in the _('date') format
+#: views/developers/dashboard.thtml:65
+msgid "devcp_dashboard_last_edited"
+msgstr "Editat per última vegada el %s"
+
+#: views/developers/dashboard.thtml:111
+msgid "devcp_dashboard_learn"
+msgstr ""
+"Actualment no teniu cap complement hostatjat al Mozilla add-ons. Per "
+"aprendre com funciona el procés i enviar el vostre primer complement, "
+"cliqueu Comença ara."
+
+#: views/developers/dashboard.thtml:112
+msgid "devcp_dashboard_start"
+msgstr "Comença ara"
+
+#: views/developers/dashboard.thtml:82
+msgid "devcp_dashboard_versions"
+msgstr "Versions i fitxers"
+
+#: views/developers/dashboard.thtml:91
+msgid "devcp_dashboard_versions_new"
+msgstr "Puja una nova versió"
+
+#. %s is the preview ID number.
+#: controllers/developers_controller.php:1415
+msgid "devcp_delete_previews_error"
+msgstr ""
+"La previsualització %s no s'ha pogut esborrar de la base de dades. Torneu a "
+"intentar-ho."
+
+#. %s is the preview ID number.
+#: controllers/developers_controller.php:1413
+msgid "devcp_delete_previews_success"
+msgstr "La previsualització %s s'ha esborrat satisfactòriament."
+
+#: controllers/developers_controller.php:1089
+msgid "devcp_delete_version_priv_error"
+msgstr "No teniu privilegis per a suprimir versions o fitxers."
+
+#. %1$s is the count of files, a number
+#. %2$s is a status string like _('Public') or _('Incomplete')
+#: controllers/components/amo.php:549
+msgid "devcp_describe_version_status"
+msgid_plural "devcp_describe_version_status"
+msgstr[0] "%1$s fitxer %2$s"
+msgstr[1] "%1$s fitxers %2$s"
+
+#. %s is a version number. Example: 3.0
+#: views/developers/versions.thtml:65
+#, php-format
+msgid "devcp_details_version"
+msgstr "Versió %s"
+
+#: views/developers/discuss.thtml:68
+msgid "devcp_discuss_addreply_header"
+msgstr "Afegeix una resposta"
+
+#: views/developers/discuss.thtml:57
+msgid "devcp_discuss_allreplies_header"
+msgstr "Respostes"
+
+#. notice when an error occurs saving a discussion reply
+#. %1 is the email address (linked) for the amo-editors list
+#: views/developers/discuss.thtml:70
+msgid "devcp_discuss_error_notice"
+msgstr ""
+"S'ha produït un error desant la vostra resposta. Per aquest motiu cal que "
+"contacteu amb %1$s."
+
+#. %1 is the add-on name, %2 is the add-on's version number currently being reviewed by an editor
+#: views/developers/discuss.thtml:46
+msgid "devcp_discuss_intro"
+msgstr ""
+"Un editor de Mozilla Add-ons us demana més informació sobre la versió %2$s "
+"del vostre complement %1$s."
+
+#. %1 is the add-on name
+#: views/developers/discuss.thtml:43
+msgid "devcp_discuss_pagetitle"
+msgstr "Amplia la informació sobre la revisió del complement %1$s"
+
+#. submit button text
+#: views/developers/discuss.thtml:79
+msgid "devcp_discuss_submit_reply"
+msgstr "Envia la resposta"
+
+#: views/developers/discuss.thtml:72
+msgid "devcp_discuss_success_message"
+msgstr ""
+"La vostra resposta s'ha desat satisfactòriament. Es notificarà per correu "
+"electrònic els demés participants de la discussió."
+
+#. in an author/editor discussion about an add-on to be reviewed:
+#. %1 is the commenter's user name (linked).
+#. %2 is the full date the comment was made.
+#: views/developers/discuss.thtml:52 views/developers/discuss.thtml:62
+msgid "devcp_discuss_writtenby"
+msgstr "escrit per %1$s el %2$s"
+
+#: views/developers/addon_edit_authors.thtml:72
+#: views/developers/addon_edit_authors.thtml:81
+msgid "devcp_edit_authors_add_author"
+msgstr "Afegeix un autor nou"
+
+#: views/developers/addon_edit_authors.thtml:96
+msgid "devcp_edit_authors_add_author_button"
+msgstr "Afegeix un autor"
+
+#: views/developers/addon_edit_authors.thtml:83
+msgid "devcp_edit_authors_add_email"
+msgstr "Adreça electrònica de l'autor:"
+
+#: views/developers/addon_edit_authors.thtml:98
+msgid "devcp_edit_authors_add_loading"
+msgstr "Comprovant l'adreça electrònica..."
+
+#: views/developers/addon_edit_authors.thtml:70
+msgid "devcp_edit_authors_click_save"
+msgstr "Cliqueu el botó Actualitza els autors per a desar-ho."
+
+#: views/developers/addon_edit_authors.thtml:58
+msgid "devcp_edit_authors_header_current"
+msgstr "Autors actuals"
+
+#: views/developers/addon_edit_authors.thtml:50
+msgid "devcp_edit_authors_header_manage"
+msgstr "Gestiona els autors del complement"
+
+#: views/developers/addon_edit_authors.thtml:93
+msgid "devcp_edit_authors_label_add_listed"
+msgstr "Llista dels autors que es mostren a les pàgines públiques"
+
+#: views/developers/addon_edit_authors.thtml:89
+msgid "devcp_edit_authors_label_developer"
+msgstr ""
+"<strong>Desenvolupador</strong> - Pot gestionar tot el que fa referència a "
+"les llistes del complement, excepte afegir i suprimir altres autors."
+
+#: views/developers/addon_edit_authors.thtml:88
+msgid "devcp_edit_authors_label_owner"
+msgstr ""
+"<strong>Propietari</strong>- Pot gestionar tot el que fa referència a les "
+"llistes del complement, incloent-hi afegir i suprimir altres autors."
+
+#: views/developers/addon_edit_authors.thtml:90
+msgid "devcp_edit_authors_label_viewer"
+msgstr ""
+"<strong>Observador</strong> - Pot veure les les estadístiques i les llistes "
+"del desenvolupador, però no pot fer cap canvi."
+
+#. Placeholder for the empty option in a <select>.
+#: views/developers/addon_edit_categories.thtml:69
+msgid "devcp_edit_authors_option_empty"
+msgstr "----------------"
+
+#: views/developers/addon_edit_authors.thtml:86
+msgid "devcp_edit_authors_select_role"
+msgstr "Seleccioneu un rol per a l'autor:"
+
+#. Column name in a table.
+#: views/developers/addon_edit_authors.thtml:62
+msgid "devcp_edit_authors_th_author"
+msgstr "Autor"
+
+#. Column name in a table.
+#: views/developers/addon_edit_authors.thtml:64
+msgid "devcp_edit_authors_th_listed"
+msgstr "Llistat"
+
+#. Column name in a table.
+#: views/developers/addon_edit_authors.thtml:63
+msgid "devcp_edit_authors_th_role"
+msgstr "Rol"
+
+#: views/developers/addon_edit_authors.thtml:77
+msgid "devcp_edit_authors_update_author"
+msgstr "Actualitza els autors"
+
+#: views/developers/addon_edit_categories.thtml:99
+msgid "devcp_edit_categories_button_update"
+msgstr "Actualitza les categories"
+
+#: views/developers/addon_edit_categories.thtml:88
+msgid "devcp_edit_categories_does_not_fit"
+msgstr "El meu complement no concorda amb cap de les categories disponibles."
+
+#. %s is the application name (Firefox, Thunderbird).
+#: views/developers/addon_edit_categories.thtml:61
+msgid "devcp_edit_categories_header_application"
+msgstr "Categories del %s"
+
+#: views/developers/addon_edit_categories.thtml:49
+msgid "devcp_edit_categories_header_manage"
+msgstr "Gestiona les categories del complement"
+
+#: views/developers/addon_edit_categories.thtml:91
+msgid "devcp_edit_categories_hover"
+msgstr "Passeu el ratolí per sobre una categoria per a veure'n la descripció."
+
+#. %s is the category number (1, 2, 3).
+#: views/developers/addon_edit_categories.thtml:67
+msgid "devcp_edit_categories_label_category_num"
+msgstr "Categoria %s"
+
+#: views/developers/addon_edit_categories.thtml:94
+#: views/developers/addon_edit_categories.thtml:103
+msgid "devcp_edit_categories_none_available"
+msgstr ""
+"No hi ha cap categoria disponible per a aquest tipus de complement i "
+"d'aplicació."
+
+#: views/developers/addon_edit_categories.thtml:86
+msgid "devcp_edit_categories_other"
+msgstr ""
+"Poseu el vostre complement en aquesta categoria només si no concorda amb cap "
+"altra categoria disponible."
+
+#. %s is the application name (Firefox, Thunderbird).
+#: views/developers/addon_edit_categories.thtml:63
+msgid "devcp_edit_categories_select_application_categories"
+msgstr ""
+"Podeu seleccionar fins a tres categories del %s per al vostre complement"
+
+#: views/developers/addon_edit.thtml:47
+msgid "devcp_edit_dd_manage_authors"
+msgstr "Afegiu o suprimiu usuaris que puguin gestionar aquest complement."
+
+#: views/developers/addon_edit.thtml:49
+msgid "devcp_edit_dd_manage_categories"
+msgstr ""
+"Seleccioneu les categories més importants de totes els aplicacions on "
+"tingueu disponible el vostre complement."
+
+#: views/developers/addon_edit.thtml:51
+msgid "devcp_edit_dd_manage_description"
+msgstr ""
+"Afegeix o modifica una traducció del resum del complement, de la descripció, "
+"de la llicència de l'usuari, i de la política de privadesa."
+
+#: views/developers/addon_edit.thtml:53
+msgid "devcp_edit_dd_manage_properties"
+msgstr ""
+"Canvia el nom del vostre complement, la pàgina principal, la icona i altres "
+"paràmetres."
+
+#: views/developers/addon_edit_descriptions.thtml:116
+msgid "devcp_edit_description_button_update"
+msgstr "Actualitza les descripcions"
+
+#: views/developers/addon_edit_descriptions.thtml:115
+msgid "devcp_edit_description_correct_error"
+msgstr "Corregiu els errors anteriors, que apareixen en vermell."
+
+#: views/developers/addon_edit_descriptions.thtml:51
+msgid "devcp_edit_descriptions_header"
+msgstr "Edita les descripcions del complement"
+
+#: views/developers/addon_edit_descriptions.thtml:94
+msgid "devcp_edit_descriptions_transbox_comments_description"
+msgstr ""
+"Qualsevol informació que l'usuari final pugui voler saber i que, per alguna "
+"raó, no es pugui posar ni al resum ni a la descripció. Per exemple per a "
+"explicar problemes coneguts, o donar informació de com enviar incidències i "
+"problemes o per anunciar amb antelació de la data d'una nova versió, etc."
+
+#: views/developers/addon_edit_descriptions.thtml:93
+msgid "devcp_edit_descriptions_transbox_comments_name"
+msgstr "Comentaris del desenvolupador"
+
+#: views/developers/addon_edit_descriptions.thtml:86
+msgid "devcp_edit_descriptions_transbox_description_description"
+msgstr ""
+"La descripció del vostre complement és una explicació més extensa i "
+"detallada de les propietats i les funcionalitats i de la informació més "
+"important. La descripció es mostra sota del resum a la pàgina del complement."
+
+#: views/developers/addon_edit_descriptions.thtml:85
+msgid "devcp_edit_descriptions_transbox_description_name"
+msgstr "Descripció del complement"
+
+#: views/developers/addon_edit_descriptions.thtml:103
+msgid "devcp_edit_descriptions_transbox_eula_description"
+msgstr ""
+"Si el vostre complement té un Acord de llicència d'usuari final (EULA), "
+"introduïu el text a continuació. Si s'inclou l'acord, els usuaris hauran "
+"d'acceptar-la abans d'instal·lar-es el complement. Cal tenir en compte que "
+"aquest acord no és el mateix que la llicència del codi, com per exemple GPL "
+"o MPL."
+
+#: views/developers/addon_edit_descriptions.thtml:102
+msgid "devcp_edit_descriptions_transbox_eula_name"
+msgstr "Acord de llicència de l'usuari final"
+
+#: views/developers/addon_edit_descriptions.thtml:112
+msgid "devcp_edit_descriptions_transbox_privacy_description"
+msgstr ""
+"Si el vostre complement té una política de privadesa, introduïu el text "
+"aquí. A la pàgina del vostre complement es mostrarà un enllaç per a ensenyar-"
+"la."
+
+#: views/developers/addon_edit_descriptions.thtml:111
+msgid "devcp_edit_descriptions_transbox_privacy_name"
+msgstr "Política de privadesa"
+
+#: views/developers/addon_edit_descriptions.thtml:78
+msgid "devcp_edit_descriptions_transbox_summary_description"
+msgstr ""
+"El resum és una explicació curta de les funcionalitats bàsiques del vostre "
+"complement. Es mostra en les cerques i en les llistes, així com a dalt de "
+"tot de la pàgina del vostre complement. <strong>No pot tenim és de 250 "
+"caràters.</strong>"
+
+#: views/developers/addon_edit_descriptions.thtml:77
+msgid "devcp_edit_descriptions_transbox_summary_name"
+msgstr "Resum del complement"
+
+#: views/developers/addon_edit.thtml:46
+msgid "devcp_edit_dt_manage_authors"
+msgstr "Gestiona els autors del complement"
+
+#: views/developers/addon_edit.thtml:48
+msgid "devcp_edit_dt_manage_categories"
+msgstr "Gestiona les categories del complement"
+
+#: views/developers/addon_edit.thtml:50
+msgid "devcp_edit_dt_manage_descriptions"
+msgstr "Gestiona les descripcions del complement"
+
+#: views/developers/addon_edit.thtml:52
+msgid "devcp_edit_dt_manage_properties"
+msgstr "Gestiona les propietats del complement"
+
+#: views/developers/addon_edit_properties.thtml:170
+msgid "devcp_edit_label_externalsoftware"
+msgstr "Aquest complement requereix programari extern"
+
+#: views/developers/addon_edit_properties.thtml:205
+msgid "devcp_edit_label_locale_disambiguation"
+msgstr "Més informació de la traducció"
+
+#: views/developers/addon_edit_properties.thtml:168
+msgid "devcp_edit_label_prerelease"
+msgstr "Açò és una versió candidata"
+
+#: views/developers/addon_edit_properties.thtml:169
+msgid "devcp_edit_label_sitespecific"
+msgstr "Aquest és el web específic del complement"
+
+#: views/developers/addon_edit_properties.thtml:202
+msgid "devcp_edit_label_target_locale"
+msgstr "Idioma"
+
+#: views/developers/addon_edit_properties.thtml:212
+msgid "devcp_edit_properties_button_update"
+msgstr "Actualitza les propietats"
+
+#: views/developers/addon_edit_properties.thtml:198
+msgid "devcp_edit_properties_change_guid"
+msgstr "Només canvieu-ho si sou conscients de totes les conseqüències."
+
+#: views/developers/addon_edit_properties.thtml:109
+msgid "devcp_edit_properties_current_icon"
+msgstr "Icona actual"
+
+#: views/developers/addon_edit_properties.thtml:85
+msgid "devcp_edit_properties_default_locale"
+msgstr ""
+"És important que estigui present l'idioma per defecte d'un complement. Si "
+"falta alguna de les traduccions de les descripcions del vostre complement en "
+"l'idioma que ha seleccionat l'usuari, aleshores es mostrarà la descripció en "
+"l'idioma per defecte."
+
+#: views/developers/addon_edit_properties.thtml:167
+msgid "devcp_edit_properties_flags"
+msgstr ""
+"Aquests indicadors s'utilitzen per a filtrar i classificar els complements."
+
+#: views/developers/addon_edit_properties.thtml:174
+msgid "devcp_edit_properties_guid"
+msgstr ""
+"L'identificador del vostre complement (GUID) s'especifica al install.rdf i "
+"només allà. No podreu canviar de GUID un cop estigui a la llista de Mozilla "
+"Add-ons."
+
+#: views/developers/addon_edit_properties.thtml:53
+msgid "devcp_edit_properties_header"
+msgstr "Edita les propietats del complement"
+
+#: views/developers/addon_edit_properties.thtml:186
+msgid "devcp_edit_properties_header_addon_type"
+msgstr "Tipus de complement"
+
+#: views/developers/addon_edit_properties.thtml:181
+msgid "devcp_edit_properties_header_admin_settings"
+msgstr "Opcions d'admin"
+
+#: views/developers/addon_edit_properties.thtml:84
+msgid "devcp_edit_properties_header_default_locale"
+msgstr "Idioma per defecte"
+
+#: views/developers/addon_edit_properties.thtml:166
+msgid "devcp_edit_properties_header_flags"
+msgstr "Indicadors del compelment"
+
+#: views/developers/addon_edit_properties.thtml:173
+#: views/developers/addon_edit_properties.thtml:197
+msgid "devcp_edit_properties_header_guid"
+msgstr "GUID del complement"
+
+#: views/developers/addon_edit_properties.thtml:104
+msgid "devcp_edit_properties_header_icon"
+msgstr "Icona del complement"
+
+#: views/developers/addon_edit_properties.thtml:159
+msgid "devcp_edit_properties_header_other_settings"
+msgstr "altres opcions"
+
+#. A header on the admin page to toggle trusted status.
+#: views/developers/addon_edit_properties.thtml:182
+msgid "devcp_edit_properties_header_trusted"
+msgstr "Complement de confiança?"
+
+#: views/developers/addon_edit_properties.thtml:160
+msgid "devcp_edit_properties_header_view_source"
+msgstr "Visualitza el codi font en línia"
+
+#. %s is a comma-separated list of image extensions ".png, .jpg"
+#: views/developers/addon_edit_properties.thtml:106
+msgid "devcp_edit_properties_icon"
+msgstr ""
+"La icona del complement és una petita imatge que es mostra al costat del nom "
+"del vostre complement. Apareixerà tant a la pàgina, com als resultats de la "
+"cerca, com al diàleg d'instal·lació de complements. La imatge es "
+"redimensionarà a 32 x 32 píxels. Utilitzeu un dels tipus d'imatge següents: %"
+"s"
+
+#: views/developers/addon_edit_properties.thtml:171
+msgid "devcp_edit_properties_label_binary"
+msgstr "Aquest complement conté components binaris"
+
+#: views/developers/addon_edit_properties.thtml:185
+msgid "devcp_edit_properties_label_not_trusted"
+msgstr "No de confiança"
+
+#: views/developers/addon_edit_properties.thtml:184
+msgid "devcp_edit_properties_label_trusted"
+msgstr "De confiança"
+
+#: views/developers/addon_edit_properties.thtml:110
+msgid "devcp_edit_properties_new_icon"
+msgstr "Icona nova"
+
+#: views/developers/addon_edit_properties.thtml:118
+msgid "devcp_edit_properties_remove_icon"
+msgstr "Suprimeix la icona"
+
+#: views/developers/addon_edit_properties.thtml:136
+msgid "devcp_edit_properties_transbox_homepage_description"
+msgstr ""
+"Si el vostre complement té una altra pàgina web, introduïu l'adreça aquí. No "
+"cal que afegiu altres traduccions a no ser que el lloc web estigui en altres "
+"idiomes."
+
+#: views/developers/addon_edit_properties.thtml:135
+msgid "devcp_edit_properties_transbox_homepage_name"
+msgstr "Pàgina web del complement"
+
+#: views/developers/addon_edit_properties.thtml:79
+msgid "devcp_edit_properties_transbox_name_description"
+msgstr ""
+"El nom del vostre complement es mostrarà a tot arreu on aparegui el vostre "
+"complement."
+
+#: views/developers/addon_edit_properties.thtml:78
+msgid "devcp_edit_properties_transbox_name_name"
+msgstr "Nom del complement"
+
+#: views/developers/addon_edit_properties.thtml:145
+msgid "devcp_edit_properties_transbox_supportemail_description"
+msgstr ""
+"Si teniu un adreça de correu per a atendre les preguntes i problemes, "
+"introduïu-la aquí. No cal que afegiu altres traduccions a no ser que tingueu "
+"diverses adreces de correu per a diverses llengües."
+
+#: views/developers/addon_edit_properties.thtml:144
+msgid "devcp_edit_properties_transbox_supportemail_name"
+msgstr "Adreça de correu per a consultes"
+
+#: views/developers/addon_edit_properties.thtml:154
+msgid "devcp_edit_properties_transbox_supporturl_description"
+msgstr ""
+"Si teniu un lloc web o un fòrum per a atendre les preguntes i problemes, "
+"introduïu l'adreça aquí. No cal que afegiu altres traduccions a no ser que "
+"web estigui en diversos idiomes."
+
+#: views/developers/addon_edit_properties.thtml:153
+msgid "devcp_edit_properties_transbox_supporturl_name"
+msgstr "Web o fòrum de consultes"
+
+#: views/developers/addon_edit_properties.thtml:183
+msgid "devcp_edit_properties_trusted"
+msgstr ""
+"Els complements de confiança poden esdevenir públics sense la revisió d'un "
+"editor."
+
+#. %s is href="..." and should stay in the <a> tag.
+#: views/developers/addon_edit_properties.thtml:119
+msgid "devcp_edit_properties_undelete"
+msgstr "Es suprimirà la icona quan deseu. <a %s>Voleu cancel·lar?</a>"
+
+#: views/developers/addon_edit_properties.thtml:161
+msgid "devcp_edit_properties_view_source"
+msgstr ""
+"Si voleu, el codi font del vostre complement el pot veure en línia qualsevol "
+"usuari registrat."
+
+#: views/developers/addon_edit_properties.thtml:162
+msgid "devcp_edit_properties_view_source_allow"
+msgstr "Permet la visualització del codi font en línia"
+
+#: views/developers/addon_edit_properties.thtml:163
+msgid "devcp_edit_properties_view_source_do_not_allow"
+msgstr "No permetis la visualització del codi font en línia"
+
+#: views/elements/developers/editbox.thtml:46
+msgid "devcp_editbox_authors"
+msgstr "Autors"
+
+#: views/elements/developers/editbox.thtml:47
+msgid "devcp_editbox_categories"
+msgstr "Categories"
+
+#: views/elements/developers/editbox.thtml:52
+msgid "devcp_editbox_change_status"
+msgstr "Canvia l'estat"
+
+#: views/elements/developers/editbox.thtml:48
+msgid "devcp_editbox_descriptions"
+msgstr "Descripcions"
+
+#: views/elements/developers/editbox.thtml:43
+msgid "devcp_editbox_edit_addon"
+msgstr "Edita el complement"
+
+#: views/elements/developers/editbox.thtml:57
+msgid "devcp_editbox_new_version"
+msgstr "Versió nova"
+
+#: views/elements/developers/editbox.thtml:49
+msgid "devcp_editbox_properties"
+msgstr "Propietats"
+
+#: views/elements/developers/editbox.thtml:60
+msgid "devcp_editbox_screenshots"
+msgstr "Mostra les captures de pantalla"
+
+#: views/elements/developers/editbox.thtml:53
+msgid "devcp_editbox_statistics_dashboard"
+msgstr "Estadístiques"
+
+#: views/elements/developers/editbox.thtml:54
+msgid "devcp_editbox_versions"
+msgstr "Versions i fitxers"
+
+#: views/elements/developers/editbox.thtml:42
+msgid "devcp_editbox_view_listing"
+msgstr "Mostra la llista"
+
+#: views/elements/developers/editorsmenu.thtml:59
+msgid "devcp_editorsqueue_featured"
+msgstr "Complements destacats"
+
+#. %1 is the review count
+#: views/elements/developers/editorsqueue.thtml:42
+#: views/elements/developers/editorsmenu.thtml:56
+#, php-format
+msgid "devcp_editorsqueue_moderatedreviews"
+msgid_plural "devcp_editorsqueue_moderatedreviews"
+msgstr[0] "Revisió moderada (%s)"
+msgstr[1] "Revisions moderades (%s)"
+
+#. %1 is the nominated addons count
+#: views/elements/developers/editorsqueue.thtml:44
+#: views/elements/developers/editorsmenu.thtml:58
+#, php-format
+msgid "devcp_editorsqueue_nominated"
+msgid_plural "devcp_editorsqueue_nominated"
+msgstr[0] "Complement nominat (%s)"
+msgstr[1] "Complements nominats (%s)"
+
+#. %1 is the update count
+#: views/elements/developers/editorsqueue.thtml:43
+#: views/elements/developers/editorsmenu.thtml:57
+#, php-format
+msgid "devcp_editorsqueue_pendingupdates"
+msgid_plural "devcp_editorsqueue_pendingupdates"
+msgstr[0] "Actualització pendent (%s)"
+msgstr[1] "Actualitzacions pendents (%s)"
+
+#: controllers/statistics_controller.php:147
+#: controllers/statistics_controller.php:361
+#: controllers/previews_controller.php:108
+#: controllers/previews_controller.php:211
+#: controllers/previews_controller.php:312
+msgid "devcp_error_addon_access_denied"
+msgstr "No teniu accés a aquest complement."
+
+#. %s is a complete URL with the text from devcp_error_appversion_reference_link_text
+#. in the <a> tag. This should be fixed.
+#: controllers/components/developers.php:591
+#, php-format
+msgid "devcp_error_appversion_reference_link"
+msgstr "Consulteu %s com a referència."
+
+#. This is the link text in the <a> for devcp_error_appversion_reference_link. This
+#. should be fixed.
+#: controllers/components/developers.php:591
+msgid "devcp_error_appversion_reference_link_text"
+msgstr "aquesta pàgina"
+
+#: views/developers/addon_edit_authors.thtml:76
+msgid "devcp_error_empty_authors"
+msgstr "El vostre complement cal que tingui com a mínim un propietari."
+
+#. %1$s is the name of the file
+#: controllers/components/developers.php:658
+msgid "devcp_error_file_exists"
+msgstr ""
+"Ja existeix una versió d'aquest complement. Per a substituir-lo, primer heu "
+"de suprimir el fitxer %1$s."
+
+#. %1$s is a file extension. Example: .exe
+#. %2$s is a comma separated list of extensions. Example: .xpi, .jar
+#: controllers/components/developers.php:355
+#, php-format
+msgid "devcp_error_file_extension"
+msgstr ""
+"No es permet aquesta extensió de fitxer (%s) per a aquest tipus de "
+"complement. N'heu de seleccionar una de les següents:%s"
+
+#: controllers/components/developers.php:64
+msgid "devcp_error_five_categories"
+msgstr "No podeu seleccionar més de cinc categories."
+
+#: controllers/components/developers.php:526
+msgid "devcp_error_guid_application"
+msgstr "L'ID d'aquest complement ja s'està utilitzant per una aplicació."
+
+#: controllers/components/developers.php:337
+#: controllers/components/developers.php:389
+msgid "devcp_error_http_incomplete"
+msgstr "Enviament incomplet"
+
+#: controllers/components/developers.php:335
+#: controllers/components/developers.php:336
+#: controllers/components/developers.php:387
+#: controllers/components/developers.php:388
+msgid "devcp_error_http_maxupload"
+msgstr "Supera la mida màxima d'enviament."
+
+#: controllers/components/developers.php:338
+#: controllers/components/developers.php:390
+msgid "devcp_error_http_nofile"
+msgstr "No s'ha enviat cap fitxer"
+
+#. %1$s is a file extension. Example: .exe
+#. %2$s is a comma separated list of extensions. Example: .xpi, .jar
+#: controllers/components/developers.php:401
+#, php-format
+msgid "devcp_error_icon_extension"
+msgstr ""
+"No es permet aquesta extensió de fitxer (%s) per a una icona. N'heu de "
+"seleccionar una de les següents: %s "
+
+#: controllers/developers_controller.php:504
+msgid "devcp_error_index_rdf_notfound"
+msgstr "No s'ha trobat install.rdf."
+
+#: controllers/components/developers.php:601
+msgid "devcp_error_install_manifest"
+msgstr "S'han trobat els següents errors a install.rdf:"
+
+#: controllers/developers_controller.php:1463
+msgid "devcp_error_invalid_addontype"
+msgstr "Heu de seleccionar un tipus de complement vàlid."
+
+#. %$1s is a version. Example: 3.1.1
+#. %$2s is an add-on name.
+#: controllers/components/developers.php:569
+#: controllers/components/developers.php:581
+#, php-format
+msgid "devcp_error_invalid_appversion"
+msgstr "%s no és una versió vàlida per a %s"
+
+#. %s is a string
+#: controllers/components/developers.php:521
+#, php-format
+msgid "devcp_error_invalid_guid"
+msgstr "L'ID d'aquest complement no és vàlid: %s"
+
+#. %$1s is a version. Example: 3.1.1
+#. %$2s is an add-on name.
+#: controllers/components/developers.php:572
+#, php-format
+msgid "devcp_error_invalid_minversion"
+msgstr ""
+"%s no és una versió vàlida per a %s: la versió mínima no pot tenir cap *"
+
+#: controllers/components/developers.php:536
+msgid "devcp_error_invalid_version"
+msgstr ""
+"La versió d'aquest complement no és vàlida: consulteu-ne les <a href="
+"\"http://developer.mozilla.org/ca/docs/Toolkit_version_format"
+"\">especificacions</a>"
+
+#: controllers/components/developers.php:531
+msgid "devcp_error_invalid_version_spaces"
+msgstr ""
+"La versió d'aquest complement no és vàlida: les versions no poden tenir "
+"espais."
+
+#. %s is an error message from the parser.
+#: controllers/components/developers.php:501
+#, php-format
+msgid "devcp_error_manifest_parse"
+msgstr ""
+"S'ha produït el següent error mentre es processava el fitxer install.rdf: %s"
+
+#: controllers/components/developers.php:373
+msgid "devcp_error_move_file"
+msgstr "No s'ha pogut moure el fitxer"
+
+#. %s is the name of a file
+#: controllers/components/developers.php:650
+#: controllers/components/developers.php:662
+#: controllers/components/developers.php:667
+#: controllers/components/developers.php:727
+#: controllers/components/developers.php:738
+#: controllers/components/developers.php:743
+#, php-format
+msgid "devcp_error_moving_file"
+msgstr "S'ha produït un error movent %s."
+
+#: controllers/components/developers.php:595
+msgid "devcp_error_mozilla_application"
+msgstr "Com a mínim ha de funcionar en una de les aplicacions del Mozilla."
+
+#: controllers/components/developers.php:516
+msgid "devcp_error_no_guid"
+msgstr "No s'ha trobat cap ID per a aquest complement en el install.rdf."
+
+#: controllers/components/developers.php:287
+msgid "devcp_error_no_platform"
+msgstr "No s'ha escollit cap plataforma"
+
+#: controllers/components/developers.php:59
+msgid "devcp_error_one_category"
+msgstr "Heu de seleccionar com a mínim una categoria."
+
+#: controllers/components/developers.php:92
+msgid "devcp_error_one_user"
+msgstr "Com a mínim cal un autor per aquest complement."
+
+#. %1$s is a file extension. Example: .exe
+#. %2$s is a comma separated list of extensions. Example: .xpi, .jar
+#: controllers/components/developers.php:1081
+#, php-format
+msgid "devcp_error_preview_extension"
+msgstr ""
+"No es permet aquesta extensió de fitxer (%s) per a una previsualització. Heu "
+"d'utilitzar una de les següents: %s"
+
+#: controllers/components/developers.php:511
+msgid "devcp_error_updatekey"
+msgstr ""
+"Els complements no poden utilitzar una clau d'actualització. Heu d'eliminar-"
+"la del fitxer install.rdf i tornar-ho a intentar."
+
+#: controllers/components/developers.php:506
+msgid "devcp_error_updateurl"
+msgstr ""
+"Els complements no poden utilitzar un updateURL extern. Heu d'eliminar-ho "
+"del fitxer install.rdf i tornar-ho a intentar."
+
+#: controllers/developers_controller.php:465
+#: controllers/components/developers.php:271
+msgid "devcp_error_upload_file"
+msgstr "Cal enviar un fitxer"
+
+#: views/developers/uploader.thtml:135
+msgid "devcp_input_upload_file"
+msgstr "Puja un fitxer"
+
+#: views/pages/js_constants.js.thtml:89
+msgid "devcp_js_a_cancel"
+msgstr "Cancel·la"
+
+#: views/pages/js_constants.js.thtml:90
+msgid "devcp_js_add_email"
+msgstr "Introduïu l'adreça de correu de l'autor que voleu afegir."
+
+#. alt text for a down-arrow image.
+#: views/pages/js_constants.js.thtml:81
+msgid "devcp_js_img_move_down"
+msgstr "Mou avall"
+
+#. alt text for an up-arrow image.
+#: views/pages/js_constants.js.thtml:82
+msgid "devcp_js_img_move_up"
+msgstr "Mou amunt"
+
+#: views/pages/js_constants.js.thtml:91
+msgid "devcp_js_img_remove_compat"
+msgstr "Suprimeix la compatibilitat de l'aplicació"
+
+#: views/pages/js_constants.js.thtml:86
+msgid "devcp_js_input_list_author"
+msgstr "Mostra l'autor en les llistes públiques"
+
+#: views/pages/js_constants.js.thtml:92
+msgid "devcp_js_license_select"
+msgstr "Seleccioneu una llicència."
+
+#: views/pages/js_constants.js.thtml:93
+msgid "devcp_js_license_text"
+msgstr "Introduïu un text per a la vostra llicència."
+
+#. <option> text in a <select> for Author role in an add-on.
+#: views/pages/js_constants.js.thtml:84
+msgid "devcp_js_option_developer"
+msgstr "Desenvolupador"
+
+#. <option> text in a <select> for Author role in an add-on.
+#: views/pages/js_constants.js.thtml:83
+msgid "devcp_js_option_owner"
+msgstr "Propietari"
+
+#. <option> text in a <select> for Author role in an add-on.
+#: views/pages/js_constants.js.thtml:85
+msgid "devcp_js_option_viewer"
+msgstr "Observador"
+
+#: views/pages/js_constants.js.thtml:88
+msgid "devcp_js_remove_author"
+msgstr "Suprimeix l'autor"
+
+#: views/pages/js_constants.js.thtml:87
+msgid "devcp_js_sure_remove"
+msgstr "Esteu <strong>segur</strong> que voleu suprimir aquest autor?"
+
+#: views/pages/js_constants.js.thtml:77
+msgid "devcp_js_upload_alert"
+msgstr "Heu de seleccionar un fitxer per a pujar."
+
+#. %1$s is an addon id, like 32.
+#. %2$s is a version number, like 3.5.
+#: controllers/components/developers.php:1212
+msgid "devcp_license_existing"
+msgstr "La llicència personalitzada del complement %1$s v%2$s"
+
+#: views/elements/developers/localebox.thtml:44
+msgid "devcp_localebox_header_localizedfields"
+msgstr "Camps localitzats"
+
+#. %1 is the default locale
+#: views/elements/developers/localebox.thtml:48
+#, php-format
+msgid "devcp_localebox_intro"
+msgstr ""
+"Alguns dels camps d'aquesta pàgina estan localitzats, per així aparèixer en "
+"la la llengua nativa de l'usuari final. Seleccioneu una de les "
+"localitzacions següents per a editar els vostres detalls del complement en "
+"aquella llengua. Si una traducció d'una determinada localització no està "
+"disponible, aleshores es farà servir la localització per defecte (%s)."
+
+#: views/elements/developers/sidebar.thtml:68
+#: views/elements/developers/myaddons.thtml:75
+msgid "devcp_myaddons_admincp_link"
+msgstr "Tauler de control de l'admin"
+
+#: views/elements/developers/sidebar.thtml:65
+#: views/elements/developers/myaddons.thtml:72
+msgid "devcp_myaddons_editorcp_link"
+msgstr "Tauler de control de l'editor"
+
+#: views/elements/developers/myaddons.thtml:52
+msgid "devcp_myaddons_link"
+msgstr "Els meus complements"
+
+#: views/elements/developers/sidebar.thtml:70
+#: views/elements/developers/myaddons.thtml:77
+msgid "devcp_myaddons_mainpage_link"
+msgstr "Torna a la principal"
+
+#: views/elements/developers/sidebar.thtml:63
+#: views/elements/developers/myaddons.thtml:70
+msgid "devcp_myaddons_statistics_link"
+msgstr "Estadístiques"
+
+#: views/elements/developers/sidebar.thtml:62
+#: views/elements/developers/myaddons.thtml:69
+msgid "devcp_myaddons_submitaddon_link"
+msgstr "Envia el complement"
+
+#: views/elements/developers/sidebar.thtml:48
+#: views/elements/developers/myaddons.thtml:67
+msgid "devcp_myaddons_title"
+msgstr "Eines de desenvolupament"
+
+#. %1$s is an add-on ID, perhaps 167.
+#. %2$s is a URL.
+#: controllers/developers_controller.php:256
+msgid "devcp_new_addon_error"
+msgstr ""
+"L'identificador d'aquest complement (%1$s) ja existeix a la base de dades. "
+"Si és el vostre complement, podeu <a href=\"%2$s\">actualitzar la versió</a>."
+
+#: views/developers/addon_status_nominate.thtml:62
+msgid "devcp_nominate_cancel"
+msgstr "Cancel·la i torna"
+
+#. %1 is the add-on name
+#: views/developers/addon_status_nominate.thtml:61
+#, php-format
+msgid "devcp_nominate_submit_nominate"
+msgstr "Nomina %s"
+
+#: views/developers/addon_edit_properties.thtml:50
+#: views/developers/addon_status.thtml:49
+#: views/developers/versions_edit.thtml:50
+msgid "devcp_notice_changes_error"
+msgstr ""
+"<span>No s'han pogut desar tots els canvis.</span><br />Comproveu els errors "
+"a continuació. La resta de canvis s'han pogut desar satisfactòriament."
+
+#: views/developers/addon_edit_authors.thtml:47
+#: views/developers/addon_edit_properties.thtml:47
+#: views/developers/addon_status.thtml:46
+#: views/developers/addon_edit_descriptions.thtml:47
+#: views/developers/versions_edit.thtml:47
+#: views/developers/addon_edit_categories.thtml:46
+msgid "devcp_notice_changes_saved"
+msgstr ""
+"<span>Tots els canvis s'han pogut desar.</span><br />Cal que tingueu en "
+"compte que alguns canvis poden tardar hores a aparèixer a tot arreu del web."
+
+#: controllers/previews_controller.php:252
+msgid "devcp_notice_cleardefault"
+msgstr ""
+"Esborrant això com a previsualització per defecte farà que una altra "
+"previsualització esdevingui la per defecte."
+
+#: controllers/previews_controller.php:184
+#: controllers/previews_controller.php:251
+msgid "devcp_notice_makedefault"
+msgstr ""
+"Si feu que aquesta previsualització sigui la per defecte, la "
+"previsualització per defecte actual ho deixarà de ser."
+
+#: views/developers/addon_edit_authors.thtml:70
+msgid "devcp_notice_unsaved_changes"
+msgstr "Hi ha canvis que no s'han desat encara"
+
+#: controllers/developers_controller.php:87
+#: controllers/developers_controller.php:97
+#: controllers/developers_controller.php:100
+#: controllers/previews_controller.php:67
+#: controllers/previews_controller.php:79
+#: controllers/previews_controller.php:82
+msgid "devcp_pagetitle"
+msgstr "Tauler de control del desenvolupador"
+
+#: controllers/previews_controller.php:103
+#: controllers/previews_controller.php:104
+msgid "devcp_preview_add_pagetitle"
+msgstr "Afegeix una previsualització"
+
+#: controllers/previews_controller.php:135
+msgid "devcp_preview_added_successfully"
+msgstr "S'ha afegit la previsualització satisfactòriament."
+
+#: controllers/previews_controller.php:323
+msgid "devcp_preview_deleted_successfully"
+msgstr "S'ha suprimit la previsualització satisfactòriament."
+
+#: controllers/previews_controller.php:194
+#: controllers/previews_controller.php:195
+msgid "devcp_preview_edit_pagetitle"
+msgstr "Edita la previsualització"
+
+#: controllers/previews_controller.php:237
+msgid "devcp_preview_updated_successfully"
+msgstr "S'ha modificat la previsualització satisfactòriament."
+
+#: views/developers/previews.thtml:120
+msgid "devcp_previews_a_another"
+msgstr "Afegeix una altra previsualització"
+
+#: views/developers/previews.thtml:96
+msgid "devcp_previews_a_delete"
+msgstr "Suprimeix la previsualització"
+
+#: views/developers/previews.thtml:95
+msgid "devcp_previews_a_replace"
+msgstr "Substitueix la previsualització"
+
+#: views/developers/previews.thtml:126
+msgid "devcp_previews_a_update"
+msgstr "Actualitza les previsualitzacions"
+
+#: views/developers/previews.thtml:115 views/developers/previews.thtml:124
+msgid "devcp_previews_add_new"
+msgstr "Afegeix una previsualització"
+
+#. %s is a list of file extensions, e.g. ".png, .gif"
+#: views/developers/previews.thtml:116
+msgid "devcp_previews_add_select"
+msgstr ""
+"Seleccioneu una imatge per a pujar-la. Les imatges que siguin més grans de "
+"700 píxels d'ample i 525 píxels d'alçada s'escalaran. Els tipus permesos "
+"són: %s"
+
+#: views/developers/previews.thtml:121
+msgid "devcp_previews_click_below"
+msgstr "Cliqueu Actualitza les previsualitzacions per a pujar.la."
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/previews.thtml:102
+msgid "devcp_previews_click_update"
+msgstr ""
+"Cliqueu Actualitza les previsualitzacions per a desar la imatge. (<a %"
+"s>Cancel·la?</a>)"
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/previews.thtml:107
+msgid "devcp_previews_error_message"
+msgstr ""
+"Aquesta previsualització se suprimirà quan cliqueu Actualitza les "
+"previsualitzacions. (<a %s>Cancel·la?</a>)"
+
+#: views/previews/add.thtml:45
+msgid "devcp_previews_filetype_info"
+msgstr ""
+"Utilitza el següent formulari per a pujar una captura de pantalla del vostre "
+"complement en format PNG, JPG o GIF. Les imatges que siguin més grans de 700 "
+"píxels d'ample i 525 píxels d'alçada s'escalaran."
+
+#: views/previews/add.thtml:43
+msgid "devcp_previews_header_add"
+msgstr "Afegeix una previsualització"
+
+#: views/developers/previews.thtml:80
+msgid "devcp_previews_header_caption"
+msgstr "Títol de la previsualització"
+
+#: views/previews/edit.thtml:43
+msgid "devcp_previews_header_edit"
+msgstr "Edita la previsualització"
+
+#: views/developers/previews.thtml:93
+msgid "devcp_previews_label_default"
+msgstr "Previsualització per defecte"
+
+#: views/previews/add.thtml:54
+msgid "devcp_previews_label_file"
+msgstr "Fitxer de la previsualització"
+
+#: views/previews/add.thtml:59 views/previews/edit.thtml:50
+msgid "devcp_previews_label_makedefault"
+msgstr "Fes-la previsualització per defecte"
+
+#: views/developers/previews.thtml:100
+msgid "devcp_previews_label_new"
+msgstr "Imatge nova:"
+
+#: views/developers/previews.thtml:118
+msgid "devcp_previews_label_upload"
+msgstr "Imatge per pujar: "
+
+#: views/developers/previews.thtml:50
+msgid "devcp_previews_notice_error"
+msgstr "No s'ha pogut desar una previsualització o més de les noves."
+
+#: views/developers/previews.thtml:47
+msgid "devcp_previews_notice_success"
+msgstr "Les vostres actualitzacions s'han pogut desar satisfactòriament."
+
+#: views/developers/previews.thtml:59
+msgid "devcp_previews_p_screenshots"
+msgstr ""
+"Les previsualitzacions de les captures de pantalla del vostre complement es "
+"mostren a continuació. Podeu fer canvis als títols o a les imatges. La "
+"previsualització per defecte és la previsualització que es mostra al costat "
+"del vostre complement en les cerques i en les llistes."
+
+#: views/previews/edit.thtml:55
+msgid "devcp_previews_submit_delete"
+msgstr "Suprimeix la previsualització"
+
+#: views/previews/edit.thtml:55
+msgid "devcp_previews_submit_delete_confirm"
+msgstr "Esteu segur que voleu suprimir aquesta previsualització?"
+
+#: views/previews/edit.thtml:54
+msgid "devcp_previews_submit_edit"
+msgstr "Edita la previsualització"
+
+#: views/previews/add.thtml:63
+msgid "devcp_previews_submit_upload"
+msgstr "Actualitza la previsualització"
+
+#: views/developers/previews.thtml:78
+msgid "devcp_previews_thumbnail"
+msgstr "Miniatures"
+
+#. %s is the add-on name.
+#: views/developers/previews.thtml:44
+msgid "devcp_previews_title"
+msgstr "Gestor de previsualitzacions del %s"
+
+#: views/developers/uploader.thtml:74
+msgid "devcp_review_agreement_please"
+msgstr ""
+"Reviseu i accepteu el següent Acord del desenvolupador abans de continuar."
+
+#: views/elements/developers/rolecheck.thtml:42
+msgid "devcp_rolecheck_no_privs"
+msgstr ""
+"<span>No teniu permís per a fer canvis a aquesta pàgina.</span><br /"
+">Contacteu al propietari del complement si necessiteu fer cap canvi."
+
+#: controllers/developers_controller.php:1315
+msgid "devcp_several_hours"
+msgstr ""
+"Cal que tingueu en compte que alguns canvis tardaran diverses hores abans "
+"que apareixin a tot arreu del web."
+
+#: views/elements/developers/sidebar.thtml:52
+msgid "devcp_sidebar_a_dashboard"
+msgstr "Consola"
+
+#. %s is a number
+#: views/elements/developers/statsbar.thtml:45
+#: views/developers/dashboard.thtml:79
+#, php-format
+msgid "devcp_statsbar_adu"
+msgstr "<em>%s</em> usuaris actius diàriament"
+
+#. %s is a number
+#: views/elements/developers/statsbar.thtml:41
+#: views/developers/dashboard.thtml:75
+#, php-format
+msgid "devcp_statsbar_total_downloads"
+msgstr "<em>%s</em> baixades en total"
+
+#. %s is a number
+#: views/elements/developers/statsbar.thtml:43
+#: views/developers/dashboard.thtml:77
+#, php-format
+msgid "devcp_statsbar_weekly_downloads"
+msgstr "<em>%s</em> baixades setmanals"
+
+#: views/developers/addon_status_confirm.thtml:59
+msgid "devcp_status_confirm_active"
+msgstr ""
+"Si es marca aquest complement com a actiu, aleshores es publicarà en els "
+"llocs corresponents al seu estat, incloent cerques i llistes públiques. Es "
+"podrà baixar des del lloc web i es podrà actualitzar a través del servei "
+"d'actualitzacions, depenent del seu estat. Podreu tornar a aquí i "
+"deshabilitar-lo de nou quan vulgueu."
+
+#: views/developers/addon_status_confirm.thtml:59
+msgid "devcp_status_confirm_active_sure"
+msgstr "Esteu segur que voleu marcar aquest complement com a actiu?"
+
+#: views/developers/addon_status_confirm.thtml:50
+msgid "devcp_status_confirm_header_sure"
+msgstr "Esteu segur?"
+
+#: views/developers/addon_status_confirm.thtml:55
+msgid "devcp_status_confirm_inactive"
+msgstr ""
+"Si es marca aquest complement com a inactiu, s'evitarà que es mostri enlloc, "
+"incloent les cerques i les llistes públiques. No es podrà baixar des del "
+"lloc web i no es podrà actualitzar via el servei d'actualitzacions. Podreu "
+"tornar aquí i tornar a habilitar-lo quan vulgueu."
+
+#: views/developers/addon_status_confirm.thtml:55
+msgid "devcp_status_confirm_inactive_sure"
+msgstr "Esteu segur que voleu marcar aquest complement com a inactiu?"
+
+#: views/developers/addon_status_confirm.thtml:74
+msgid "devcp_status_confirm_no"
+msgstr "No, cancel·la-ho"
+
+#: views/developers/addon_status_confirm.thtml:67
+msgid "devcp_status_confirm_public"
+msgstr ""
+"Si es marca aquest complement com a públic, aleshores es permetrà que tothom "
+"se'l pugui baixar i s'oferiran actualitzacions als usuaris."
+
+#: views/developers/addon_status_confirm.thtml:67
+msgid "devcp_status_confirm_public_sure"
+msgstr "Esteu segur que voleu fer-lo públic?"
+
+#: views/developers/addon_status_confirm.thtml:63
+msgid "devcp_status_confirm_sandbox"
+msgstr ""
+"Si es torna aquest complement a l'entorn de proves, aleshores els usuaris "
+"s'hauran de registrar abans de baixar-se'l i es deixarà d'oferir les "
+"actualitzacions. Com que el complement actualment és públic, podreu tornar "
+"aquí quan vulgueu i tornar-lo a fer públic."
+
+#: views/developers/addon_status_confirm.thtml:63
+msgid "devcp_status_confirm_sandbox_sure"
+msgstr "Esteu segur que voleu tornar aquest complement a l'entorn de proves?"
+
+#: views/developers/addon_status_confirm.thtml:73
+msgid "devcp_status_confirm_yes"
+msgstr "Sí, segur"
+
+#: views/developers/addon_status_nominate.thtml:46
+msgid "devcp_status_nominate_error_notice"
+msgstr ""
+"<span>És necessari un missatge de nominació.</span><br />Cal que ompliu el "
+"camp de text amb la informació que s'us demana i ho torneu a provar."
+
+#: views/developers/addon_status_nominate.thtml:55
+msgid "devcp_status_nominate_header"
+msgstr "Nominació del complement"
+
+#: views/developers/dashboard.thtml:85
+msgid "devcp_summary_lastversion"
+msgstr "Darrera versió:"
+
+#. %s is the add-on name.
+#: views/developers/addon_edit.thtml:43
+#: views/developers/addon_edit_authors.thtml:44
+#: views/developers/versions_delete.thtml:43
+#: views/developers/addon_edit_properties.thtml:44
+#: views/developers/addon_edit_descriptions.thtml:44
+#: views/developers/versions_edit.thtml:44
+#: views/developers/addon_edit_categories.thtml:43
+#: views/developers/versions.thtml:43
+msgid "devcp_title_edit_addon"
+msgstr "Edita %s"
+
+#. title attribute for a javascript link that pops up a help dialog.
+#: views/elements/translationbox.thtml:68
+msgid "devcp_transbox_a_title_help"
+msgstr "Ajuda (sense deixar la pàgina)"
+
+#: views/elements/translationbox.thtml:68
+msgid "devcp_transbox_alt_help"
+msgstr "Ajuda"
+
+#. %1$s is <span>17</span>, %2$s is 42.
+#: views/elements/translationbox.thtml:101
+msgid "devcp_transbox_chars_used"
+msgstr "Caràcters utilitzats: %1$s / %2$s"
+
+#: views/elements/translationbox.thtml:132
+msgid "devcp_transbox_delete_sure"
+msgstr "Esteu segur que voleu suprimir aquesta traducció?"
+
+#. %s is a locale, like en-US.
+#: views/elements/translationbox.thtml:143
+msgid "devcp_transbox_help_header_tabs"
+msgstr "Què són aquestes %s pestanyes?"
+
+#: views/elements/translationbox.thtml:145
+msgid "devcp_transbox_help_header_what"
+msgstr "Què passa si no tinc cap traducció?"
+
+#: views/elements/translationbox.thtml:147
+msgid "devcp_transbox_help_hide"
+msgstr "Oculta l'ajuda"
+
+#: views/elements/translationbox.thtml:146
+msgid "devcp_transbox_help_if"
+msgstr ""
+"Si un usuari consulta el lloc web i no hi ha la traducció al seu idioma, "
+"aleshores es mostrarà segons l'idioma per defecte del vostre complement, tal "
+"com s'ha especificat a Edita les propietats del complement. Si no teniu cap "
+"traducció, escriviu el que podeu en l'idioma que heu definit per defecte, "
+"que hauria de correspondre amb el vostre idioma ."
+
+#: views/elements/translationbox.thtml:144
+msgid "devcp_transbox_help_transbox"
+msgstr ""
+"Això és <i>el quadre de traducció</i>. Us permet traduir un determinat camp "
+"a altres llengües. Podeu afegir, editar i suprimir traduccions utilitzant "
+"les pestanyes."
+
+#: views/elements/translationbox.thtml:85
+msgid "devcp_transbox_img_add_trans"
+msgstr "Afegeix una traducció"
+
+#: views/elements/translationbox.thtml:86
+msgid "devcp_transbox_img_remove_trans"
+msgstr "Suprimeix una traducció"
+
+#: views/elements/translationbox.thtml:123
+msgid "devcp_transbox_input_add_all"
+msgstr "Afegeix un idioma a tot"
+
+#: views/elements/translationbox.thtml:122
+msgid "devcp_transbox_input_add_locale"
+msgstr "Afegeix un idioma"
+
+#: views/elements/translationbox.thtml:124
+#: views/elements/translationbox.thtml:135
+msgid "devcp_transbox_input_cancel"
+msgstr "Cancel·la"
+
+#: views/elements/translationbox.thtml:134
+msgid "devcp_transbox_input_delete"
+msgstr "Suprimeix-ho"
+
+#: views/elements/translationbox.thtml:113
+msgid "devcp_transbox_select_locale"
+msgstr "Seleccioneu l'idioma de la traducció que voleu afegir:"
+
+#. %1$s and %2$s are GUIDs.
+#: controllers/developers_controller.php:343
+msgid "devcp_update_addon_guid_error"
+msgstr ""
+"El GUID del complement utilitzat en aquest fitxers (%1$s) no concorda amb el "
+"GUID existent d'aquest complement (%2$s)."
+
+#: controllers/developers_controller.php:334
+msgid "devcp_update_addon_priv_error"
+msgstr "No teniu prou privilegis per actualitzar aquest complement."
+
+#. %1$s is a version number, %2$s is an add-on ID.
+#: controllers/developers_controller.php:399
+msgid "devcp_update_addon_version_belong_error"
+msgstr "La versió especificada (%1$s) no pertany a aquest complement (%2$s)."
+
+#. %1$s is a version number, maybe 1.1.
+#. %2$s is a URL.
+#: controllers/developers_controller.php:351
+msgid "devcp_update_addon_version_exists_error"
+msgstr ""
+"El número de versió que s'ha pujat (%1$s) ja existia per aquest complement. "
+"Si esteu intentant d'afegir un altre fitxer a aquesta versió, <a href=\"%2$s"
+"\">cliqueu aquí</a>."
+
+#. %1$s and %2$s are version numbers.
+#: controllers/developers_controller.php:405
+msgid "devcp_update_addon_version_match_error"
+msgstr "El número de versió (%1$s) no concorda amb la versió existent (%2$s)."
+
+#: views/developers/uploader.thtml:68
+msgid "devcp_uploader_a_start"
+msgstr "Comença ara"
+
+#: views/developers/uploader.thtml:137
+msgid "devcp_uploader_ajax_loading"
+msgstr "S'està pujant el fitxer..."
+
+#: views/developers/uploader.thtml:82
+msgid "devcp_uploader_button_agree"
+msgstr "D'acord"
+
+#: views/developers/uploader.thtml:157
+msgid "devcp_uploader_button_edit"
+msgstr "Edita el meu complement"
+
+#: views/developers/uploader.thtml:158
+msgid "devcp_uploader_button_later"
+msgstr "Acabaré el meu complement més tard."
+
+#: views/developers/uploader.thtml:168
+msgid "devcp_uploader_button_release"
+msgstr "Afegeix unes notes de la versió"
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/uploader.thtml:156
+msgid "devcp_uploader_created_results"
+msgstr ""
+"<p>La llista del vostre complement s'ha creat satisfactòriament. La "
+"informació bàsica que s'ha obtingut del fitxer que heu pujat s'ha desat "
+"correctament, però a banda de la vostra llista, encara hi ha molta més "
+"informació que podeu personalitzar.</p><p>El vostre complement actualment "
+"està marcat com a <strong>Incomplet</strong>. Per tal de completar el vostre "
+"complement, heu d'assegurar-vos que té un nom, un resum i una descripció "
+"correctes, i cal escollir una categoria. Podeu editar la informació del "
+"vostre complement utilitzant l'enllaç següent i comprovar-ne l'estat a "
+"qualsevol hora consultant la <a %s>pàgina de l'estat</a>."
+
+#: views/developers/uploader.thtml:143
+msgid "devcp_uploader_error_correct"
+msgstr "Corregiu el problema i torneu a pujar el fitxer una altra vegada."
+
+#. %1$s is a version number, %2$s is a status, e.g Public or Incomplete.
+#: views/developers/uploader.thtml:175
+msgid "devcp_uploader_file_created"
+msgstr ""
+"El nou fitxer s'ha afegit a la versió %1$s i actualment està marcat com a %2"
+"$s."
+
+#: views/developers/uploader.thtml:154
+msgid "devcp_uploader_header_created"
+msgstr "S'ha creat el complement."
+
+#: views/developers/uploader.thtml:141
+msgid "devcp_uploader_header_error"
+msgstr "Sembla que hi ha hagut un problema amb aquest fitxer..."
+
+#: views/developers/uploader.thtml:173
+msgid "devcp_uploader_header_file_added"
+msgstr "S'ha afegit el fitxer."
+
+#: views/developers/uploader.thtml:66
+msgid "devcp_uploader_header_how"
+msgstr "Com funciona tot?"
+
+#. %s is the version number, e.g. 3.2.
+#: views/developers/uploader.thtml:163
+msgid "devcp_uploader_header_update_created"
+msgstr "S'ha creat la versió %s"
+
+#: views/developers/uploader.thtml:117
+msgid "devcp_uploader_header_upload"
+msgstr "Puja un fitxer"
+
+#: views/developers/uploader.thtml:67
+msgid "devcp_uploader_how"
+msgstr ""
+"<p>Gràcies pel vostre interès en publicar el vostre complement al Mozilla "
+"Add-ons. Hostatjar el vostre complement al Mozilla Add-ons és la forma més "
+"senzilla per a gestionar la distribució del vostre complement. Disposareu de "
+"tot això:</p> <ul><li>Tots els complement tindran una pàgina pública amb la "
+"informació que hàgiu donat, com per exemple un resum breu de la funció del "
+"vostre complement, una descripció opcional, més llarga i un catàleg de "
+"previsualitzacions.<li><li>El vostre complement apareixerà a les cerques i a "
+"les llistes públiques del web, i també al Gestor de complements del Firefox "
+"3.</li><li>Ens cuidarem d'hostatjar totes les baixades i oferirem un sistema "
+"d'actualització automàtica als usuaris que permetrà distribuir les noves "
+"versions que pugeu.</li><li>Podreu consultar estadístiques amb informació "
+"detallada dels vostres usuaris.</li></ul><p>Els complement hostatjats al web "
+"hauran de ser revisats per un editor de Mozilla Add-ons abans que rebre tots "
+"els avantatges que s'han explicat. Si esteu a punt per a començar el procés "
+"i ja teniu preparat per pujar el paquet del vostre complement cliqueu el "
+"botó Comença ara.</p>"
+
+#: views/developers/uploader.thtml:125
+msgid "devcp_uploader_label_platformtype"
+msgstr "Plataformes disponibles:"
+
+#: views/developers/uploader.thtml:124
+msgid "devcp_uploader_label_upload_field"
+msgstr "Fitxer del complement: "
+
+#: controllers/components/developers.php:1221
+msgid "devcp_uploader_option_other"
+msgstr "Altre"
+
+#. %1$s is a number, %2$s is href="..." and should stay in the <a> tag.
+#: views/developers/uploader.thtml:176
+msgid "devcp_uploader_p_pending_file"
+msgstr ""
+"El nou fitxer es publicarà tant aviat com un editor pugui revisar-vos-el. "
+"Actualment hi ha %1$s complements més a la cua. Si voleu que es revisi més "
+"ràpidament penseu en <a %2$s>fer-vos editor</a>."
+
+#. %1$s is a number, %2$s is href="..." and should stay in the <a> tag.
+#: views/developers/uploader.thtml:166
+msgid "devcp_uploader_p_pending_version"
+msgstr ""
+"La nova versió es publicarà tant aviat com un editor pugui revisar-vos-la. "
+"Actualment hi ha %1$s complements més a la cua. Si voleu que es revisi més "
+"ràpidament penseu en <a %2$s>fer-vos editor</a>."
+
+#. %s is a status, e.g Public or Incomplete.
+#: views/developers/uploader.thtml:165
+msgid "devcp_uploader_p_update_created"
+msgstr ""
+"La vostra nova versió s'ha creat correctament i actualment està marcada com "
+"a %s."
+
+#. %1$s is href="..." and should stay in the 'Versions and Files' <a> tag.
+#. %2$s is href="..." and should stay in the 'current status' <a> tag.
+#: views/developers/uploader.thtml:177
+msgid "devcp_uploader_p_update_file"
+msgstr ""
+"Consulteu el vostre nou fitxer a la <a %1$s>Pàgina de versions i fitxers</"
+"a>, vigileu el vostre complement a <a %2$s>l'Estat actual</a>, o <b>afegiu "
+"unes notes de la versió</b> clicant el següent botó (recomanat)."
+
+#. %1$s is href="..." and should stay in the 'Versions and Files' <a> tag.
+#. %2$s is href="..." and should stay in the 'current status' <a> tag.
+#: views/developers/uploader.thtml:167
+msgid "devcp_uploader_p_update_version"
+msgstr ""
+"Consulteu la vostra nova versió a la <a %1$s>Pàgina de versions i fitxers</"
+"a>, vigileu el vostre complement a <a %2$s>l'Estat actual</a>, o <b>afegiu "
+"unes notes de la versió</b> clicant el següent botó (recomanat)."
+
+#: views/developers/uploader.thtml:118
+msgid "devcp_uploader_p_upload"
+msgstr ""
+"Pugeu el fitxer del vostre complement utilitzant el següent formulari. Si "
+"teniu més d'un fitxer, específic per a cada plataforma, seleccioneu només un "
+"fitxer i pugeu els demés fitxers utilitzant el Gestor de versions i fitxers."
+
+#: views/developers/uploader.thtml:125
+msgid "devcp_uploader_platformtype_all"
+msgstr "Totes"
+
+#: views/developers/uploader.thtml:126
+msgid "devcp_uploader_platformtype_specific"
+msgstr "Específica:"
+
+#. Used as first item in a <select>.
+#: controllers/components/developers.php:1185
+msgid "devcp_uploader_please_choose"
+msgstr "Seleccioneu-lo..."
+
+#. %1$s is the add-on name, %2$s is the version number.
+#: views/developers/uploader.thtml:57
+msgid "devcp_uploader_title_file"
+msgstr "Afegeix un fitxer al %1$s %2$s"
+
+#: views/developers/uploader.thtml:50
+msgid "devcp_uploader_title_submit"
+msgstr "Envia un nou complement"
+
+#. %s is the add-on name.
+#: views/developers/uploader.thtml:54
+msgid "devcp_uploader_title_update"
+msgstr "Actualitza el %s"
+
+#. %s is a full <a> tag
+#: controllers/developers_controller.php:503
+#, php-format
+msgid "devcp_valid_app_reference"
+msgstr "Llegiu %s com a referència."
+
+#. This is the text in the <a> tag for devcp_valid_app_reference. This should be
+#. fixed.
+#: controllers/developers_controller.php:503
+msgid "devcp_valid_app_reference_linktext"
+msgstr "aquesta pàgina"
+
+#: controllers/developers_controller.php:581
+msgid "devcp_verify_author_error"
+msgstr "No s'ha trobat cap compte per aquesta adreça electrònica."
+
+#: controllers/developers_controller.php:553
+msgid "devcp_verify_search_engine_error"
+msgstr ""
+"O bé l'XML conté errors o bé falta algun camp obligatori. Cal que <a href="
+"\"https://developer.mozilla.org/en/Creating_OpenSearch_plugins_for_Firefox"
+"\">llegiu la documentació</a>, verifiqueu el vostre complement, i ho torneu "
+"a intentar."
+
+#: views/developers/versions.thtml:75
+msgid "devcp_versions_a_cancel"
+msgstr "Cancel·la"
+
+#: views/developers/versions.thtml:79
+msgid "devcp_versions_a_delete"
+msgstr "Suprimeix la versió"
+
+#: views/developers/versions.thtml:74
+msgid "devcp_versions_a_empty"
+msgstr "Suprimeix la versió buida"
+
+#: views/developers/versions.thtml:71
+msgid "devcp_versions_a_remove"
+msgstr "Voleu suprimir-la?"
+
+#: views/developers/versions.thtml:91
+msgid "devcp_versions_add"
+msgstr "Afegeix una versió nova"
+
+#: views/developers/versions_delete.thtml:58
+msgid "devcp_versions_delete_a_cancel"
+msgstr "Cancel·la"
+
+#: views/developers/versions_delete.thtml:56
+msgid "devcp_versions_delete_a_delete"
+msgstr "Suprimeix la versió"
+
+#. Followed by a list of reviews and files that will be removed.
+#: views/developers/versions_delete.thtml:50
+msgid "devcp_versions_delete_also"
+msgstr "Això també suprimirà:"
+
+#: views/developers/versions_delete.thtml:53
+msgid "devcp_versions_delete_files"
+msgid_plural "devcp_versions_delete_files"
+msgstr[0] "%s fitxer"
+msgstr[1] "%s fitxers"
+
+#. %s is the version number.
+#: views/developers/versions_delete.thtml:48
+msgid "devcp_versions_delete_header"
+msgstr "Suprimeix la versió %s?"
+
+#: views/developers/versions_delete.thtml:52
+msgid "devcp_versions_delete_reviews"
+msgid_plural "devcp_versions_delete_reviews"
+msgstr[0] "%s revisió"
+msgstr[1] "%s revisions"
+
+#. %s is the version number.
+#: views/developers/versions_delete.thtml:49
+msgid "devcp_versions_delete_sure"
+msgstr "Esteu segur que voleu suprimir permanentment la versió %s?"
+
+#: views/developers/versions_edit.thtml:102
+#: views/developers/versions_edit.thtml:155
+msgid "devcp_versions_edit_a_cancel"
+msgstr "Cancel·la"
+
+#: views/developers/versions_edit.thtml:101
+msgid "devcp_versions_edit_a_delete"
+msgstr "Suprimeix el fitxer"
+
+#: views/developers/versions_edit.thtml:165
+msgid "devcp_versions_edit_a_new_app"
+msgstr "Afegeix una nova aplicació"
+
+#: views/developers/versions_edit.thtml:154
+msgid "devcp_versions_edit_a_remove_app"
+msgstr "Suprimeix l'aplicació"
+
+#: views/developers/versions_edit.thtml:114
+msgid "devcp_versions_edit_add"
+msgstr "Afegeix un nou fitxer"
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/versions_edit.thtml:121
+msgid "devcp_versions_edit_adjust"
+msgstr ""
+"Si canvieu la configuració de l'aplicació aquí podreu fer que els usuaris "
+"pugin instal·lar el vostre complement tot i que el install.rdf del paquet "
+"indiqui que el complement és incompatible. <a %s>Llista d'aplicacions "
+"permeses</a>"
+
+#: views/developers/versions_edit.thtml:153
+msgid "devcp_versions_edit_compat_sure"
+msgstr ""
+"Esteu <b>segur</b> que voleu suprimir la compatibilitat amb aquesta "
+"aplicació?"
+
+#: views/developers/versions_edit.thtml:100
+msgid "devcp_versions_edit_delete_sure"
+msgstr "Esteu <b>segur</b> que voleu suprimir permanentment aquest fitxer?"
+
+#: views/developers/versions_edit.thtml:203
+msgid "devcp_versions_edit_header_approval"
+msgstr "Informació d'aprovació"
+
+#: views/developers/versions_edit.thtml:120
+msgid "devcp_versions_edit_header_compat"
+msgstr "Aplicacions compatibles"
+
+#: views/developers/versions_edit.thtml:74
+msgid "devcp_versions_edit_header_file"
+msgstr "Informació del fitxer"
+
+#: views/developers/versions_edit.thtml:189
+msgid "devcp_versions_edit_header_license"
+msgstr "Llicència"
+
+#. %s is the version number.
+#: views/developers/versions_edit.thtml:53
+msgid "devcp_versions_edit_header_manage"
+msgstr "Gestiona la versió %s"
+
+#: views/developers/versions_edit.thtml:212
+msgid "devcp_versions_edit_header_notes"
+msgstr "Notes de l'aprovació"
+
+#: views/developers/versions_edit.thtml:98
+msgid "devcp_versions_edit_img_delete"
+msgstr "Suprimeix el fitxer"
+
+#. %1$s is the file id, e.g. 18723.
+#. %2$s is the platform name, e.g. ALL or Windows.
+#. %3$s is the _('date) created.
+#. %4$s is the status, e.g. "In Sandbox" or "Public".
+#. %5$s is the _('date') status was changed.
+#: views/developers/versions_edit.thtml:208
+msgid "devcp_versions_edit_li_file"
+msgstr "Fitxer %1$s (%2$s) es va crear el %3$s i es va passar a %4$s el %5$s"
+
+#: views/developers/versions_edit.thtml:190
+msgid "devcp_versions_edit_license_description"
+msgstr ""
+"Seleccioneu una llicència per al vostre complement. Aquesta llicència "
+"especificarà els drets que donareu al vostre codi font."
+
+#: views/developers/versions_edit.thtml:111
+msgid "devcp_versions_edit_no_files"
+msgstr "No s'ha trobat cap fitxer."
+
+#: views/developers/versions_edit.thtml:213
+msgid "devcp_versions_edit_optional"
+msgstr "Informació opcional de l'editor que revisa aquesta versió."
+
+#: views/developers/versions_edit.thtml:151
+msgid "devcp_versions_edit_remove_compat"
+msgstr "Suprimeix la compatibilitat de l'aplicació"
+
+#: views/developers/versions_edit.thtml:167
+msgid "devcp_versions_edit_select_app"
+msgstr "Seleccioneu una aplicació"
+
+#: views/developers/versions_edit.thtml:78
+msgid "devcp_versions_edit_th_file"
+msgstr "Fitxer"
+
+#: views/developers/versions_edit.thtml:79
+msgid "devcp_versions_edit_th_platform"
+msgstr "Plataforma"
+
+#: views/developers/versions_edit.thtml:80
+msgid "devcp_versions_edit_th_size"
+msgstr "Mida"
+
+#: views/developers/versions_edit.thtml:81
+msgid "devcp_versions_edit_th_status"
+msgstr "Estat"
+
+#: views/developers/versions_edit.thtml:183
+msgid "devcp_versions_edit_transbox_releasenotes_description"
+msgstr ""
+"Informació sobre els canvis d'aquesta versió, noves funcionalitats, "
+"problemes coneguts i altre informació d'utilitat referent a la versió. "
+"Aquesta informació també estarà disponible per als usuaris que s'instal·lin "
+"el complement amb el Gestor de complements del Firefox 3."
+
+#: views/developers/versions_edit.thtml:182
+msgid "devcp_versions_edit_transbox_releasenotes_name"
+msgstr "Notes de la versió"
+
+#: views/developers/versions_edit.thtml:164
+msgid "devcp_versions_edit_unsaved_compat"
+msgstr ""
+"<strong>Teniu canvis sense desar.</strong> La compatibilitat s'esborrarà "
+"fins que cliqueu Actualitza la versió."
+
+#: views/developers/versions_edit.thtml:113
+msgid "devcp_versions_edit_unsaved_files"
+msgstr ""
+"<strong>Teniu canvis sense desar.</strong> Els fitxers no se suprimiran fins "
+"que cliqueu Actualitza la versió."
+
+#: views/developers/versions_edit.thtml:218
+msgid "devcp_versions_edit_update"
+msgstr "Actualitza les versions"
+
+#: views/developers/versions.thtml:49
+msgid "devcp_versions_header_manage"
+msgstr "Gestiona les versions i els fitxers"
+
+#: views/developers/versions.thtml:87
+msgid "devcp_versions_no_versions"
+msgstr "Cap versió."
+
+#. %s is a version number, base 10.
+#: views/developers/versions.thtml:46
+msgid "devcp_versions_notice_success"
+msgstr "La versió %s s'ha suprimit satisfactòriament."
+
+#: views/developers/versions.thtml:73
+msgid "devcp_versions_p_remove"
+msgstr ""
+"Aquesta versió no té cap fitxer associat que es pugui suprimir. Voleu "
+"suprimir aquesta versió?"
+
+#: views/developers/versions.thtml:58
+msgid "devcp_versions_th_created"
+msgstr "Creat"
+
+#: views/developers/versions.thtml:57
+msgid "devcp_versions_th_status"
+msgstr "Estat"
+
+#: views/developers/versions.thtml:56
+msgid "devcp_versions_th_version"
+msgstr "Versió"
+
+#: controllers/downloads_controller.php:91
+msgid "downloads_disable_warning"
+msgstr "S'ha inhabilitat el complement"
+
+#: controllers/components/editors.php:57
+msgid "editor_review_error_addon_not_nominated"
+msgstr "Aquest complement no ha estat nominat."
+
+#: controllers/components/editors.php:213
+msgid "editor_review_error_file_not_pending"
+msgstr "Aquest fitxer no està pendent de revisió."
+
+#. Actions are, for example: approving or rejecting
+#: controllers/components/editors.php:79
+#: controllers/components/editors.php:182
+msgid "editor_review_error_no_action"
+msgstr "Cal que seleccioneu una acció de revisió."
+
+#: controllers/components/editors.php:192
+msgid "editor_review_error_no_applications"
+msgstr "Cal que indiqueu les aplicacions que heu provat."
+
+#. Comments are required when an editor approves or rejects an add-on.
+#: controllers/components/editors.php:84
+#: controllers/components/editors.php:187
+msgid "editor_review_error_no_comments"
+msgstr "Cal que escriviu algun comentari de la revisió."
+
+#: controllers/components/editors.php:161
+msgid "editor_review_error_no_files"
+msgstr "Cal que seleccioneu com a mínim un fitxer per a revisar."
+
+#: controllers/components/editors.php:197
+msgid "editor_review_error_no_operating_system"
+msgstr "Cal que indiqueu els sistemes operatius que heu provat."
+
+#: views/editors/logs.thtml:51
+msgid "editorcp_logs_button_filter"
+msgstr "Filtra"
+
+#: views/editors/logs.thtml:44
+msgid "editorcp_logs_filter_by"
+msgstr "Filtra per tipus/acció"
+
+#: views/editors/logs.thtml:42 controllers/editors_controller.php:964
+msgid "editorcp_logs_page_heading"
+msgstr "Registre d'esdeveniments"
+
+#: views/elements/developers/editorsmenu.thtml:60
+msgid "editorcp_menu_eventlog_link"
+msgstr "Registre d'esdeveniments"
+
+#: views/elements/developers/editorsmenu.thtml:62
+msgid "editorcp_menu_mainpage_link"
+msgstr "Torna al principal"
+
+#: views/elements/developers/editorsmenu.thtml:61
+msgid "editorcp_menu_reviewlog_link"
+msgstr "Registre de revisions"
+
+#: views/elements/developers/editorsmenu.thtml:55
+msgid "editorcp_menu_summary_link"
+msgstr "Resum de l'editor"
+
+#: views/elements/developers/editorsmenu.thtml:52
+msgid "editorcp_menu_title"
+msgstr "Eines de l'editor"
+
+#: views/editors/reviewlog.thtml:49
+msgid "editorcp_reviewlog_button_filter"
+msgstr "Filtra"
+
+#: views/editors/reviewlog.thtml:58
+msgid "editorcp_reviewlog_column_action"
+msgstr "Acció"
+
+#: views/editors/reviewlog.thtml:56
+msgid "editorcp_reviewlog_column_addon"
+msgstr "Complement"
+
+#: views/editors/reviewlog.thtml:55
+msgid "editorcp_reviewlog_column_date"
+msgstr "Data"
+
+#: views/editors/reviewlog.thtml:57
+msgid "editorcp_reviewlog_column_editor"
+msgstr "Editor"
+
+#: views/editors/reviewlog.thtml:94
+msgid "editorcp_reviewlog_comments_hide"
+msgstr "Oculta els comentaris"
+
+#: views/editors/reviewlog.thtml:93
+msgid "editorcp_reviewlog_comments_show"
+msgstr "Mostra els comentaris"
+
+#. %1$s and %2$s are full <input> tags for dates
+#: views/editors/reviewlog.thtml:45
+#, php-format
+msgid "editorcp_reviewlog_entries_between"
+msgstr "Mostra-ho entre %s i %s"
+
+#: views/editors/reviewlog.thtml:104
+msgid "editorcp_reviewlog_none_found"
+msgstr "No s'han trobat cap revisió en aquest període."
+
+#: views/editors/reviewlog.thtml:42
+msgid "editorcp_reviewlog_page_heading"
+msgstr "Registre de revisions"
+
+#: views/editors/summary.thtml:61
+msgid "editorcp_summary_monthreviews_heading"
+msgstr "Revisions del mes"
+
+#: views/editors/summary.thtml:77
+msgid "editorcp_summary_neweditors_heading"
+msgstr "Nous editors"
+
+#: views/editors/summary.thtml:42
+msgid "editorcp_summary_page_heading"
+msgstr "Resum de l'editor"
+
+#: views/editors/summary.thtml:94
+msgid "editorcp_summary_recentactivity_heading"
+msgstr "Activitat recent de l'editor"
+
+#: views/editors/summary.thtml:45
+msgid "editorcp_summary_totalreviews_heading"
+msgstr "Revisions totals"
+
+#: controllers/editors_controller.php:248
+#: controllers/editors_controller.php:249
+msgid "editors_addon_review_pagetitle"
+msgstr "Revisa el complement"
+
+#: controllers/editors_controller.php:349
+msgid "editors_error_js-formerror"
+msgstr "Completeu els següents camps:"
+
+#: controllers/editors_controller.php:350
+msgid "editors_error_review_one_file"
+msgstr "Seleccioneu com a mínim un fitxer per a revisar."
+
+#: controllers/editors_controller.php:274
+msgid "editors_error_self_reviews_forbidden"
+msgstr "No es permeten les revisions pròpies."
+
+#: controllers/editors_controller.php:699
+msgid "editors_external_software"
+msgstr "Programari extern"
+
+#: views/editors/featured.thtml:120 views/editors/featured.thtml:121
+msgid "editors_featured_add_feature"
+msgstr "Afegeix una característica"
+
+#: views/editors/featured.thtml:126
+msgid "editors_featured_add_feature_submit"
+msgstr "Afegeix"
+
+#: views/editors/featured.thtml:49 controllers/editors_controller.php:832
+#: controllers/editors_controller.php:848
+msgid "editors_featured_addon_add_failure"
+msgstr "No s'ha pogut afegir la característica."
+
+#: controllers/editors_controller.php:851
+msgid "editors_featured_addon_add_success"
+msgstr "S'ha afegit la característica correctament."
+
+#: views/editors/featured.thtml:50 controllers/editors_controller.php:839
+#: controllers/editors_controller.php:868
+#: controllers/editors_controller.php:886
+msgid "editors_featured_addon_edit_failure"
+msgstr "No s'ha pogut editar la característica."
+
+#: views/editors/featured.thtml:51 controllers/editors_controller.php:888
+msgid "editors_featured_addon_edit_success"
+msgstr "S'ha editat la característica correctament."
+
+#: views/editors/featured.thtml:53 controllers/editors_controller.php:861
+msgid "editors_featured_addon_invalid_locale"
+msgstr "Un o més codis d'idomes són invàlids."
+
+#: views/editors/featured.thtml:52 controllers/editors_controller.php:906
+msgid "editors_featured_addon_remove_failure"
+msgstr "No s'ha pogut suprimir la característica."
+
+#: controllers/editors_controller.php:901
+msgid "editors_featured_addon_remove_success"
+msgstr "S'ha suprimit la característica correctament."
+
+#: controllers/editors_controller.php:915
+#: controllers/editors_controller.php:917
+msgid "editors_featured_addons_pagetitle"
+msgstr "Característiques del complement"
+
+#: views/editors/featured.thtml:54 views/editors/featured.thtml:107
+msgid "editors_featured_edit_feature_submit"
+msgstr "D'acord"
+
+#: views/editors/featured.thtml:90 views/editors/featured.thtml:91
+msgid "editors_featured_remove_feature"
+msgstr "Suprimeix la característica"
+
+#: views/editors/queue.thtml:46
+msgid "editors_filter_queue"
+msgstr "Cua de filtratge"
+
+#: views/editors/queue.thtml:182
+msgid "editors_helpful_links"
+msgstr "Enllaços útils"
+
+#: views/editors/queue.thtml:182
+msgid "editors_link_guide"
+msgstr "Guia d'edició"
+
+#: views/editors/queue.thtml:182
+msgid "editors_link_policy"
+msgstr "Política dels complements"
+
+#: views/editors/queue.thtml:47
+msgid "editors_notice_filter_session"
+msgstr ""
+"Els filtres romandran al mateix lloc durant aquesta sessió o fins que es "
+"netegin."
+
+#. %1 is the queue mode
+#: views/editors/queue.thtml:177 views/admin/flagged_queue.thtml:89
+msgid "editors_notice_none_found"
+msgstr "No hi ha actualment cap complement de %s per revisar."
+
+#: controllers/editors_controller.php:1040
+msgid "editors_one_day"
+msgstr "1 dia"
+
+#: controllers/editors_controller.php:1048
+msgid "editors_one_hour"
+msgstr "1 hora"
+
+#: controllers/editors_controller.php:1056
+msgid "editors_one_minute"
+msgstr "1 minut"
+
+#: controllers/editors_controller.php:64 controllers/editors_controller.php:73
+#: controllers/editors_controller.php:77
+msgid "editors_pagetitle"
+msgstr "Tauler de control d'edició"
+
+#. %s is a comma separated list of platforms. Example: Windows, OS X
+#: controllers/editors_controller.php:680
+#: controllers/editors_controller.php:683
+#, php-format
+msgid "editors_platform_x_only"
+msgstr "només %s"
+
+#: controllers/editors_controller.php:695
+msgid "editors_pre-release"
+msgstr "Versió candidata"
+
+#. %1 is the app name
+#: views/editors/queue.thtml:131
+#, php-format
+msgid "editors_queue_app_compatibility"
+msgstr "Compatibilitat del %s"
+
+#: views/editors/queue.thtml:51
+msgid "editors_queue_filter_label_addon"
+msgstr "Adreça electrònica del complement o de l'autor"
+
+#: views/editors/queue.thtml:72
+msgid "editors_queue_filter_label_addontypes"
+msgstr "Tipus de complements"
+
+#: views/editors/queue.thtml:56
+msgid "editors_queue_filter_label_application"
+msgstr "Aplicació"
+
+#: views/editors/queue.thtml:61
+msgid "editors_queue_filter_label_maxversion"
+msgstr "Versiò màx."
+
+#: views/editors/queue.thtml:78
+msgid "editors_queue_filter_label_platforms"
+msgstr "Plataformes"
+
+#: views/editors/queue.thtml:66
+msgid "editors_queue_filter_label_submissionage"
+msgstr "Antiguitat (dies)"
+
+#. %1$s is a number
+#: views/editors/queue.thtml:90
+msgid "editors_queue_filter_result_count"
+msgid_plural "editors_queue_filter_result_count"
+msgstr[0] ""
+"Resultats de la vostra cerca filtrada: <strong>%1$s</strong> complement"
+msgstr[1] ""
+"Resultats de la vostra cerca filtrada: <strong>%1$s</strong> complements"
+
+#: views/editors/queue.thtml:84
+msgid "editors_queue_submit_clean"
+msgstr "Neteja"
+
+#: views/editors/queue.thtml:83
+msgid "editors_queue_submit_filter"
+msgstr "Filtra"
+
+#: controllers/editors_controller.php:133
+msgid "editors_queues_disabled"
+msgstr ""
+"Totes les cues de revisió estan actualment inhabilitades. Torneu-ho a "
+"comprovar més endavant."
+
+#: views/editors/review.thtml:149
+msgid "editors_review_a_edit_item"
+msgstr "Edita l'element"
+
+#: views/editors/review.thtml:146
+msgid "editors_review_a_item_history"
+msgstr "Història de l'element"
+
+#: views/editors/review.thtml:148
+msgid "editors_review_a_item_homepage"
+msgstr "Web de l'element"
+
+#: views/editors/review.thtml:145
+msgid "editors_review_a_item_overview"
+msgstr "Descripció general"
+
+#: views/editors/review.thtml:147
+msgid "editors_review_a_previews"
+msgstr "Previsualitzacions"
+
+#: controllers/editors_controller.php:345
+msgid "editors_review_action"
+msgstr "Acció de revisió"
+
+#: views/editors/review.thtml:159
+msgid "editors_review_action_info"
+msgstr "Sol·licita més informació"
+
+#: views/editors/review.thtml:157
+msgid "editors_review_action_public"
+msgstr "Porta a la part pública"
+
+#: views/editors/review.thtml:160
+msgid "editors_review_action_request_superreview"
+msgstr "Sol·licita una revisió suprema"
+
+#: views/editors/review.thtml:158
+msgid "editors_review_action_sandbox"
+msgstr "Retén en l'entorn de proves"
+
+#: controllers/editors_controller.php:346
+msgid "editors_review_comments"
+msgstr "Revisa els comentaris"
+
+#: views/editors/review.thtml:182
+msgid "editors_review_details_info_request"
+msgstr ""
+"Utilitzeu aquest formulari per a sol·licitar informació dels autors. Rebran "
+"un correu i podran respondre-us aquí. Quan us responguin us ho notificarem "
+"per correu electrònic."
+
+#: views/editors/review.thtml:174
+msgid "editors_review_details_nominated_public"
+msgstr ""
+"Açò marcarà el complement i la seua versió més recent i fitxers com a "
+"públic. Les versions futures aniran a l'entorn de proves fins que les revisi "
+"un editor."
+
+#: views/editors/review.thtml:177
+msgid "editors_review_details_nominated_sandbox"
+msgstr "Açò retindrà el complement en l'entorn de proves."
+
+#: views/editors/review.thtml:166
+msgid "editors_review_details_pending_public"
+msgstr ""
+"Açò aprovarà una versió d'un complement públic en l'entorn de proves per tal "
+"que aparegui en la part publica."
+
+#: views/editors/review.thtml:169
+msgid "editors_review_details_pending_sandbox"
+msgstr ""
+"Açò farà que una versió en l'entorn de proves d'un complement públic "
+"romangui allà."
+
+#: views/editors/review.thtml:185
+msgid "editors_review_details_superreview"
+msgstr ""
+"Si patiu pel que fa a la seguretat del complement, aspectes de drets "
+"d'autor, o altres punts on creieu que calgui un administrador que hi faci "
+"una ullada, introduïu els vostres comentaris al següent camp. Aquests "
+"s'enviaran als administradors, no a l'autor."
+
+#: views/editors/review.thtml:134
+msgid "editors_review_file_diff_link"
+msgstr "Compara amb la versió pública"
+
+#: views/editors/review.thtml:131
+msgid "editors_review_file_viewcontents_link"
+msgstr "Visualitza els continguts"
+
+#: views/editors/review.thtml:65
+msgid "editors_review_header_authors"
+msgstr "Autors:"
+
+#: views/editors/review.thtml:79
+msgid "editors_review_header_categories"
+msgstr "Categories:"
+
+#: views/editors/review.thtml:92
+msgid "editors_review_header_compatibility"
+msgstr "Compatibilitat:"
+
+#: views/editors/review.thtml:251
+msgid "editors_review_header_description"
+msgstr "Descripció"
+
+#: views/editors/review.thtml:275
+msgid "editors_review_header_devcomments"
+msgstr "Comentaris del desenvolupador"
+
+#: views/editors/review.thtml:263
+msgid "editors_review_header_eula"
+msgstr "ALUF (EULA)"
+
+#: views/editors/review.thtml:115
+msgid "editors_review_header_files"
+msgstr "Fitxers"
+
+#: views/editors/review.thtml:284
+msgid "editors_review_header_itemhistory"
+msgstr "Historial d'elements"
+
+#: views/editors/review.thtml:232
+msgid "editors_review_header_nominationmessage"
+msgstr "Missatge de nominació"
+
+#: views/editors/review.thtml:311
+msgid "editors_review_header_previews"
+msgstr "Previsualitzacions"
+
+#: views/editors/review.thtml:269
+msgid "editors_review_header_privacy"
+msgstr "Política de privadesa"
+
+#. %1 is the add-on name and version
+#: views/editors/review.thtml:56
+#, php-format
+msgid "editors_review_header_review"
+msgstr "Revisa %s"
+
+#: views/editors/review.thtml:239
+msgid "editors_review_header_reviewernotes"
+msgstr "Notes al revisor"
+
+#: views/editors/review.thtml:245
+msgid "editors_review_header_summary"
+msgstr "Resum"
+
+#: views/editors/review.thtml:257
+msgid "editors_review_header_versionnotes"
+msgstr "Notes de la versió"
+
+#. a noun: shown in an add-on's editor review history
+#: views/elements/developers/editors_review_history_item.thtml:80
+msgid "editors_review_history_info_reply"
+msgstr "Resposta"
+
+#: views/elements/developers/editors_review_history_item.thtml:78
+msgid "editors_review_history_info_request"
+msgstr "Sol·licitud d'informació"
+
+#: views/elements/developers/editors_review_history_item.thtml:62
+#: views/editors/reviewlog.thtml:77
+msgid "editors_review_history_nominated_adminreview"
+msgstr "Revisió de l'administrador"
+
+#: views/elements/developers/editors_review_history_item.thtml:56
+#: views/editors/reviewlog.thtml:71
+msgid "editors_review_history_nominated_approved"
+msgstr "Nominació aprovada/públic"
+
+#: views/elements/developers/editors_review_history_item.thtml:59
+#: views/editors/reviewlog.thtml:74
+msgid "editors_review_history_nominated_denied"
+msgstr "Nominació denegada/entorn de proves"
+
+#: views/editors/review.thtml:303
+msgid "editors_review_history_nonefound"
+msgstr "No s'han trobat revisions anteriors."
+
+#: views/elements/developers/editors_review_history_item.thtml:73
+#: views/editors/reviewlog.thtml:88
+msgid "editors_review_history_pending_adminreview"
+msgstr "Revisió de l'administrador"
+
+#: views/elements/developers/editors_review_history_item.thtml:67
+#: views/editors/reviewlog.thtml:82
+msgid "editors_review_history_pending_approved"
+msgstr "Aprovat/públic"
+
+#: views/elements/developers/editors_review_history_item.thtml:70
+#: views/editors/reviewlog.thtml:85
+msgid "editors_review_history_pending_denied"
+msgstr "Denegat / entorn de proves"
+
+#. link text in an add-on's editor review history, allowing to hide and show an information request's replies
+#. %1 is the number of replies
+#: views/elements/developers/editors_review_history_item.thtml:90
+msgid "editors_review_history_show_hide_replies"
+msgid_plural "editors_review_history_show_hide_replies"
+msgstr[0] "Mostra/oculta la resposta (%1$s)"
+msgstr[1] "Mostra/oculta les respostes (%1$s)"
+
+#: views/editors/review.thtml:208
+msgid "editors_review_label_applications"
+msgstr "Aplicacions:"
+
+#: views/editors/review.thtml:196
+msgid "editors_review_label_cannedresponse"
+msgstr "o selecciona una resposta predeterminada:"
+
+#: views/editors/review.thtml:190
+msgid "editors_review_label_comments"
+msgstr "Comentaris:"
+
+#: views/editors/review.thtml:204
+msgid "editors_review_label_operating_systems"
+msgstr "Sistema operatiu:"
+
+#: views/editors/review.thtml:285 views/editors/review.thtml:312
+msgid "editors_review_link_pagetop"
+msgstr "Inici"
+
+#: views/editors/review.thtml:141
+msgid "editors_review_mulitple_notice"
+msgstr ""
+"Atenció: només fes més d'una revisió si heu provat tots els fitxers que heu "
+"seleccionat."
+
+#: views/editors/review.thtml:51
+msgid "editors_review_next_link"
+msgstr "següent &raquo;"
+
+#: views/editors/review.thtml:322
+msgid "editors_review_previews_notfound"
+msgstr "No hi ha previsualitzacions."
+
+#: views/editors/review.thtml:50
+msgid "editors_review_previous_link"
+msgstr "&laquo; anterior"
+
+#: controllers/editors_controller.php:144
+#: controllers/editors_controller.php:146
+msgid "editors_review_queue_pagetitle"
+msgstr "Cua de revisions"
+
+#. %1 is the add-ons rank in the queue, %2 is the total queue length
+#: views/editors/review.thtml:47
+msgid "editors_review_rank_in_queue"
+msgstr "<strong># %1$s</strong> de %2$s a la cua"
+
+#. %1 is the add-ons rank in the queue, %2 is the total queue length. Both numbers
+#: views/editors/review.thtml:45
+msgid "editors_review_rank_in_queue_filtered"
+msgstr "<strong># %1$s</strong> de %2$s a la cua (filtrada)"
+
+#: views/editors/review.thtml:223
+msgid "editors_review_submit_process_action"
+msgstr "Processa l'acció"
+
+#: views/editors/review.thtml:293
+msgid "editors_review_th_action"
+msgstr "Acció"
+
+#: views/editors/review.thtml:294
+msgid "editors_review_th_comments"
+msgstr "Comentaris"
+
+#: views/editors/review.thtml:291
+msgid "editors_review_th_date"
+msgstr "Data"
+
+#: views/editors/review.thtml:292
+msgid "editors_review_th_reviewer"
+msgstr "Revisor"
+
+#: views/editors/review.thtml:290
+msgid "editors_review_th_version_file"
+msgstr "Versió/fitxer"
+
+#: views/editors/review.thtml:217
+msgid "editors_review_update_notify_once"
+msgstr ""
+"Notifica'm només la propera vegada que s'actualitzi aquest complement. (Les "
+"actualitzacions que la segueixin no generaran cap correu)"
+
+#: controllers/editors_controller.php:298
+msgid "editors_reviewed_successfully"
+msgstr "La revisió s'ha processat satisfactòriament."
+
+#: views/editors/reviews_queue.thtml:106
+msgid "editors_reviews_action_delete_review"
+msgstr "Esborra la revisió"
+
+#: views/editors/reviews_queue.thtml:104
+msgid "editors_reviews_action_keep"
+msgstr "Esborra les marques; conserva la revisió"
+
+#: views/editors/reviews_queue.thtml:102
+msgid "editors_reviews_action_skip"
+msgstr "Salta"
+
+#: views/editors/reviews_queue.thtml:100
+msgid "editors_reviews_header_action"
+msgstr "Acció"
+
+#: views/editors/reviews_queue.thtml:67
+msgid "editors_reviews_in_reply_to"
+msgstr "En resposta a:"
+
+#: controllers/editors_controller.php:748
+msgid "editors_reviews_processed"
+msgstr "La revisió s'ha processat satisfactòriament."
+
+#: views/editors/reviews_queue.thtml:117
+msgid "editors_reviews_queue_empty"
+msgstr "Actualment no hi ha cap revisió moderant-se."
+
+#: views/editors/reviews_queue.thtml:111
+msgid "editors_reviews_submit_process_reviews"
+msgstr "Processa les revisions"
+
+#: controllers/editors_controller.php:691
+msgid "editors_site_specific"
+msgstr "Web específic"
+
+#: controllers/editors_controller.php:348
+msgid "editors_tested_app"
+msgstr "Aplicació provada"
+
+#: controllers/editors_controller.php:347
+msgid "editors_tested_os"
+msgstr "Sistema operatiu provat"
+
+#: views/editors/queue.thtml:151
+msgid "editors_th_additional_info"
+msgstr "Informació addicional"
+
+#: views/editors/featured.thtml:63 views/editors/queue.thtml:109
+#: views/admin/flagged_queue.thtml:53
+msgid "editors_th_addon"
+msgstr "Complement"
+
+#: views/editors/queue.thtml:125
+msgid "editors_th_addontype"
+msgstr "Tipus"
+
+#: views/editors/featured.thtml:64
+msgid "editors_th_locales"
+msgstr "Limita'l als idiomes?"
+
+#: views/editors/queue.thtml:148
+msgid "editors_th_nomination_age"
+msgstr "Temps a la cua"
+
+#: views/editors/queue.thtml:101 views/editors/queue.thtml:117
+#: views/editors/queue.thtml:144
+msgid "editors_th_sort_ascending"
+msgstr "Ordenació ascendent"
+
+#: views/editors/queue.thtml:105 views/editors/queue.thtml:121
+#: views/editors/queue.thtml:140
+msgid "editors_th_sort_descending"
+msgstr "Ordenació descendent"
+
+#. %s is a number
+#: controllers/editors_controller.php:1036
+#, php-format
+msgid "editors_x_days"
+msgstr "%s dies"
+
+#. %s is a number
+#: controllers/editors_controller.php:1044
+#, php-format
+msgid "editors_x_hours"
+msgstr "%s hores"
+
+#. %s is a number
+#: controllers/editors_controller.php:1052
+#, php-format
+msgid "editors_x_minutes"
+msgstr "%s minuts"
+
+#: views/errors/error401.thtml:50 controllers/components/simple_acl.php:81
+#: controllers/components/simple_acl.php:82
+#: controllers/components/simple_acl.php:83 controllers/components/amo.php:607
+#: controllers/components/amo.php:608 controllers/components/amo.php:609
+#: controllers/reviews_controller.php:353
+#: controllers/reviews_controller.php:485
+#: controllers/collections_controller.php:438
+#: controllers/collections_controller.php:496
+#: controllers/collections_controller.php:504
+#: controllers/collections_controller.php:971
+#: controllers/collections_controller.php:1034
+#: controllers/collections_controller.php:1077
+msgid "error_access_denied"
+msgstr "Accés denegat"
+
+#: views/errors/error401.thtml:52
+msgid "error_access_denied_message"
+msgstr "No esteu autoritzats a veure aquesta pàgina."
+
+#: controllers/collections_controller.php:1039
+msgid "error_addon_exists"
+msgstr "El complement ja existeix"
+
+#: controllers/developers_controller.php:200
+#: controllers/developers_controller.php:593
+#: controllers/developers_controller.php:1016
+#: controllers/developers_controller.php:1429
+#: controllers/downloads_controller.php:95
+#: controllers/downloads_controller.php:102
+#: controllers/downloads_controller.php:164
+#: controllers/statistics_controller.php:135
+#: controllers/previews_controller.php:115
+#: controllers/previews_controller.php:206
+#: controllers/previews_controller.php:307
+#: controllers/reviews_controller.php:77
+#: controllers/reviews_controller.php:240
+#: controllers/reviews_controller.php:332
+#: controllers/reviews_controller.php:340 controllers/api_controller.php:123
+#: controllers/api_controller.php:759 controllers/addons_controller.php:131
+#: controllers/addons_controller.php:197
+#: controllers/addons_controller.php:1407
+#: controllers/addons_controller.php:1465
+#: controllers/addons_controller.php:1469
+#: controllers/addons_controller.php:1503
+#: controllers/editors_controller.php:265
+#: controllers/collections_controller.php:1041
+#: controllers/collections_controller.php:1074
+msgid "error_addon_notfound"
+msgstr "El complement no s'ha trobat."
+
+#: controllers/files_controller.php:83 controllers/files_controller.php:196
+msgid "error_addon_notviewable"
+msgstr "Aquest complement no es pot veure ací."
+
+#: controllers/reviews_controller.php:246
+msgid "error_addon_selfreview"
+msgstr "No us podeu revisar el vostre propi complement."
+
+#: controllers/addons_controller.php:970
+msgid "error_browse_no_addons"
+msgstr "No hi ha cap complement en aquesta categoria."
+
+#: controllers/api_controller.php:424
+msgid "error_collection_feed_notfound"
+msgstr "No s'ha trobat el canal del complement."
+
+#: views/users/register.thtml:65 views/users/edit.thtml:194
+msgid "error_email_invalid"
+msgstr "Aquesta adreça de correu no és vàlida."
+
+#: views/users/pwreset.thtml:74 views/users/register.thtml:70
+#: views/users/register.thtml:80 views/users/register.thtml:86
+#: views/users/edit.thtml:105 views/users/edit.thtml:111
+#: views/users/edit.thtml:192 views/admin/users_edit.thtml:78
+#: views/admin/users_edit.thtml:83 views/reviews/add.thtml:80
+#: views/reviews/add.thtml:104
+msgid "error_field_required"
+msgstr "Aquest camp no pot estar buit."
+
+#: controllers/files_controller.php:75 controllers/files_controller.php:93
+#: controllers/files_controller.php:96 controllers/files_controller.php:163
+#: controllers/files_controller.php:176 controllers/files_controller.php:185
+#: controllers/files_controller.php:204 controllers/editors_controller.php:412
+msgid "error_file_notfound"
+msgstr "No s'ha trobat el fitxer."
+
+#. %s is a filename
+#: controllers/editors_controller.php:430
+#, php-format
+msgid "error_file_x_notfound"
+msgstr "Error en el fitxer: no existeix %s."
+
+#: views/collections/add.thtml:55 views/collections/edit.thtml:89
+#: views/users/register.thtml:54 views/users/edit.thtml:81
+#: views/reviews/add.thtml:70 controllers/groups_controller.php:80
+#: controllers/groups_controller.php:102
+msgid "error_formerrors"
+msgstr "Hi ha errors en el formulari. Corregiu-los i torneu-lo a enviar."
+
+#: views/users/register.thtml:109
+msgid "error_invalid_captcha"
+msgstr "El captcha no és correcte, torneu a intentar-ho."
+
+#: views/users/register.thtml:100 views/users/edit.thtml:125
+#: views/admin/users_edit.thtml:101
+msgid "error_invalid_url"
+msgstr ""
+"Aquest URL no té un format vàlid. Els URL són de la forma http://exemple.com/"
+"pagina."
+
+#. %s is a string representing what's missing. Example: file_id
+#: controllers/downloads_controller.php:65
+#: controllers/users_controller.php:185 controllers/users_controller.php:264
+#: controllers/users_controller.php:559 controllers/users_controller.php:653
+#: controllers/reviews_controller.php:71
+#: controllers/reviews_controller.php:234
+#: controllers/reviews_controller.php:325
+#: controllers/reviews_controller.php:473
+#: controllers/reviews_controller.php:475
+#: controllers/addons_controller.php:182
+#: controllers/addons_controller.php:1381
+#: controllers/addons_controller.php:1455
+#: controllers/collections_controller.php:266
+#: controllers/collections_controller.php:285
+#: controllers/collections_controller.php:346
+#: controllers/collections_controller.php:443
+#: controllers/collections_controller.php:482
+#: controllers/collections_controller.php:936
+#: controllers/collections_controller.php:959
+#: controllers/collections_controller.php:960
+#: controllers/collections_controller.php:975
+#: controllers/collections_controller.php:977
+#: controllers/collections_controller.php:994
+#: controllers/collections_controller.php:1003
+#: controllers/collections_controller.php:1016
+#: controllers/collections_controller.php:1017
+#: controllers/collections_controller.php:1024
+#: controllers/collections_controller.php:1070
+#: controllers/collections_controller.php:1090
+#, php-format
+msgid "error_missing_argument"
+msgstr "Falta el paràmetre: %s"
+
+#: controllers/components/amo.php:507 controllers/components/amo.php:532
+msgid "error_no_files_in_addon"
+msgstr "Sense fitxers"
+
+#: controllers/previews_controller.php:200
+msgid "error_preview_notfound"
+msgstr "No s'ha trobat la previsualització."
+
+#: views/addons/display.thtml:400 views/reviews/add.thtml:98
+msgid "error_review_rating_required"
+msgstr "Heu de fer una valoració."
+
+#: controllers/users_controller.php:160
+msgid "error_user_already_confirmed"
+msgstr "El compte de l'usuari ja estava confirmat."
+
+#: controllers/users_controller.php:202 controllers/users_controller.php:276
+#: controllers/users_controller.php:569 controllers/users_controller.php:581
+#: controllers/users_controller.php:587 controllers/users_controller.php:610
+#: controllers/users_controller.php:627
+msgid "error_user_badconfirmationcode"
+msgstr "El codi de confirmació no és vàlid."
+
+#: views/users/pwreset.thtml:79 views/users/register.thtml:75
+#: views/users/edit.thtml:183
+msgid "error_user_confirmpw_nomatch"
+msgstr "La contrasenya no és correcta."
+
+#: views/users/register.thtml:65 views/users/edit.thtml:190
+#: controllers/users_controller.php:617
+msgid "error_user_email_notunique"
+msgstr "L'adreça de correu ja està assignada a un altre usuari"
+
+#: controllers/users_controller.php:596
+msgid "error_user_emailchange_expired"
+msgstr ""
+"El canvi d'adreça de correu ha caducat. Haureu de tornar a canviar la vostra "
+"adreça de correu des del perfil d'usuari i clicar l'enllaç del correu de "
+"confirmació tan aviat com el rebeu."
+
+#: controllers/collections_controller.php:985
+msgid "error_user_exists"
+msgstr ""
+"Els usuaris només poden tenir un únic rol. Cal que suprimiu tots els rols "
+"que tingui abans de continuar."
+
+#: views/users/register.thtml:91 views/users/edit.thtml:116
+#: views/admin/users_edit.thtml:88
+msgid "error_user_nickname_notunique"
+msgstr "L'àlies ja està assignat."
+
+#: views/users/pwreset.thtml:54 controllers/users_controller.php:191
+#: controllers/users_controller.php:270 controllers/users_controller.php:603
+#: controllers/users_controller.php:659
+#: controllers/collections_controller.php:988
+#: controllers/collections_controller.php:998
+msgid "error_user_notfound"
+msgstr "Usuari desconegut"
+
+#: views/users/activatefirst.thtml:47
+msgid "error_user_unconfirmed"
+msgstr ""
+"Primer de tot confirmeu el vostre compte d'usuari amb el codi que heu rebut "
+"per correu."
+
+#: views/users/login.thtml:67
+msgid "error_username_or_pw_wrong"
+msgstr "Usuari o contrasenya erronis"
+
+#: controllers/editors_controller.php:260
+msgid "error_version_notfound"
+msgstr "Versió desconeguda"
+
+#: views/users/delete.thtml:125 views/users/edit.thtml:173
+msgid "error_wrong_password"
+msgstr "Contrasenya incorrecta"
+
+#: views/elements/amo2009/homepage_addon.thtml:122
+#: views/elements/feature.thtml:122
+msgid "feature_learnmore"
+msgstr "Més informació"
+
+#. %1 is the add-on name
+#: views/elements/amo2009/homepage_addon.thtml:123
+#: views/elements/feature.thtml:123
+#, php-format
+msgid "feature_learnmore_about_addon"
+msgstr "Més informació sobre %1$s"
+
+#. %1$s is a number
+#: views/elements/amo2009/reviews.thtml:52
+#: views/elements/addon_listitem.thtml:112 views/elements/feature.thtml:99
+#: views/addons/browse_thumbs.thtml:86
+#, php-format
+msgid "feature_reviews"
+msgid_plural "feature_reviews"
+msgstr[0] "%1$s revisió"
+msgstr[1] "%1$s revisions"
+
+#: views/elements/amo2009/homepage_addon.thtml:127
+#: views/elements/feature.thtml:127
+msgid "feature_view_more_from_category"
+msgstr "Més informació sobre el"
+
+#. This appears on a page that views the source of an add-on. This link will return
+#. the user to the add-on's main page
+#: views/files/browse.thtml:65
+msgid "file_browser_link_addon"
+msgstr "Torna al complement"
+
+#. There is a list of directories and files on the page. Clicking this will show the
+#. contents of all the directories (normally you would click on each one to see the
+#. contents)
+#: views/files/browse.thtml:67
+msgid "file_browser_link_expand_all"
+msgstr "Expandeix-ho tot"
+
+#. This appears on a page that views the source of an add-on. This link will return
+#. the user to the add-on's review page (it only appears if the add-on is being
+#. reviewed)
+#: views/files/browse.thtml:64
+msgid "file_browser_link_review"
+msgstr "Torna a la revisió"
+
+#. The title of the page for viewing an add-on's source.
+#. %1$s is the name of the add-on
+#. %2$s is the name of the current application (e.g. Firefox or Thunderbird)
+#: views/files/browse.thtml:46
+msgid "file_browser_title"
+msgstr "%1$s :: Navegador :: Complements del %2$s"
+
+#. This appears on a page that views the source of an add-on. There is a list of
+#. directories and files on the page. Clicking this link will toggle between an
+#. expanded or a collapsed list. This string should be kept short.
+#: views/files/browse.thtml:68
+msgid "file_browser_toggle_expand_collapse"
+msgstr "+/-"
+
+#. Link text for the AMO About page.
+#: views/elements/footer.thtml:72 views/layouts/amo2009.thtml:341
+msgid "footer_a_about"
+msgstr "Quant a"
+
+#. Link text to the AMO blog.
+#: views/elements/footer.thtml:74 views/layouts/amo2009.thtml:343
+msgid "footer_a_blog"
+msgstr "Bloc"
+
+#. Link text to the Frequently Asked Questions page.
+#: views/elements/footer.thtml:73 views/layouts/amo2009.thtml:342
+msgid "footer_a_faq"
+msgstr "FAQ"
+
+#. Full text for the FAQ abbreviation.
+#: views/elements/footer.thtml:73 views/pages/collector_features.thtml:72
+#: views/layouts/amo2009.thtml:342
+msgid "footer_abbr_faq"
+msgstr "Frequently Asked Questions"
+
+#: views/elements/footer.thtml:67 views/layouts/amo2009.thtml:336
+msgid "footer_all_rights_reserved"
+msgstr "Tots els drets reservats."
+
+#: views/elements/footer.thtml:67 views/layouts/amo2009.thtml:336
+msgid "footer_copyright"
+msgstr "Drets de còpia"
+
+#: views/elements/footer.thtml:71 views/layouts/amo2009.thtml:340
+msgid "footer_credits"
+msgstr "Crèdits"
+
+#: views/elements/footer.thtml:76 views/layouts/amo2009.thtml:346
+msgid "footer_disclaimer"
+msgstr ""
+"Mozilla només enllaça a aquestes aplicacions com a gentilesa, però això no "
+"significa que faci de representant de les aplicacions ni que en disposi "
+"d'informació relacionada. Qualsevol consulta, queixa o reclamació de "
+"l'aplicació cal fer-la directament al proveïdor de programari corresponent."
+
+#: views/elements/footer.thtml:61 views/layouts/amo2009.thtml:332
+msgid "footer_lang_form_lang_submit_go"
+msgstr "Vés"
+
+#: views/elements/footer.thtml:70 views/layouts/amo2009.thtml:339
+msgid "footer_legal_notices"
+msgstr "Avís legal"
+
+#: views/elements/footer.thtml:50 views/layouts/amo2009.thtml:321
+msgid "footer_other_languages"
+msgstr "Altres llengües:"
+
+#: views/elements/footer.thtml:69 views/layouts/amo2009.thtml:338
+msgid "footer_privacy_policy"
+msgstr "Política de privadesa"
+
+#: models/addontype.php:79
+msgid "general_addontype_dict"
+msgstr "Diccionari"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:100
+msgid "general_addontype_dict_plural"
+msgstr "Diccionaris"
+
+#: models/addontype.php:75
+msgid "general_addontype_extension"
+msgstr "Extensió"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:98
+msgid "general_addontype_extension_plural"
+msgstr "Extensions"
+
+#: models/addontype.php:85
+msgid "general_addontype_lpaddon"
+msgstr "Paquet d'idioma (complement)"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:103
+msgid "general_addontype_lpaddon_plural"
+msgstr "Paquets d'idioma (complement)"
+
+#: models/addontype.php:83
+msgid "general_addontype_lpapp"
+msgstr "Paquet d'idioma (aplicació)"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:102
+msgid "general_addontype_lpapp_plural"
+msgstr "Paquets d'idioma (aplicació)"
+
+#: models/addontype.php:87
+msgid "general_addontype_plugin"
+msgstr "Connector"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:104
+msgid "general_addontype_plugin_plural"
+msgstr "Connector"
+
+#: models/addontype.php:81
+msgid "general_addontype_search"
+msgstr "Motor de cerca"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:101
+msgid "general_addontype_search_plural"
+msgstr "Motors de cerca"
+
+#: models/addontype.php:77
+msgid "general_addontype_theme"
+msgstr "Tema"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:99
+msgid "general_addontype_theme_plural"
+msgstr "Temes"
+
+#: config/language.php:367
+msgid "general_languages_all_locales"
+msgstr "Tots els idiomes"
+
+#: views/layouts/amo2009.thtml:249
+msgid "header_brand_name"
+msgstr "Mozilla"
+
+#. %1$s is the application name. Example: Firefox
+#: views/elements/header.thtml:111 views/elements/header.thtml:122
+#: views/layouts/amo2009.thtml:248
+#, php-format
+msgid "header_home_tooltip"
+msgstr "Torna a la pàgina principal dels complements %1$s"
+
+#: views/elements/header.thtml:87
+msgid "header_main_firefox_header"
+msgstr "Complements del Firefox"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:218
+msgid "header_main_firefox_header_with_logo"
+msgstr ""
+"Complements <em>per al</em> <img alt=\"Firefox\" src=\"%1$s\" /> "
+"<strong>Firefox</strong>"
+
+#: views/elements/header.thtml:99
+msgid "header_main_header"
+msgstr "Complements"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:242
+msgid "header_main_header_with_logo"
+msgstr "Complements <img alt=\"Complements\" src=\"%1$s\" />"
+
+#: views/elements/header.thtml:90
+msgid "header_main_seamonkey_header"
+msgstr "Complements del Seamonkey"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:224
+msgid "header_main_seamonkey_header_with_logo"
+msgstr ""
+"Complements <em>per al</em> <img alt=\"seamonkey\" src=\"%1$s\" /> "
+"<strong>SeaMonkey</strong>"
+
+#: views/elements/header.thtml:93
+msgid "header_main_sunbird_header"
+msgstr "Complements del Sunbird"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:230
+msgid "header_main_sunbird_header_with_logo"
+msgstr ""
+"Complements <em>per al</em> <img alt=\"sunbird\" src=\"%1$s\" /> "
+"<strong>Sunbird</strong>"
+
+#: views/elements/header.thtml:96
+msgid "header_main_thunderbird_header"
+msgstr "Complements del Thunderbird"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:236
+msgid "header_main_thunderbird_header_with_logo"
+msgstr ""
+"Complements <em>per al</em> <img alt=\"thunderbird\" src=\"%1$s\" /> "
+"<strong>Thunderbird</strong>"
+
+#: views/layouts/amo2009.thtml:205
+msgid "header_navaccess_applications_menu"
+msgstr "Salta a un altre menú d'aplicacions"
+
+#: views/layouts/amo2009.thtml:204
+msgid "header_navaccess_categories_menu"
+msgstr "Salta al menú de categories"
+
+#: views/layouts/amo2009.thtml:202
+msgid "header_navaccess_main_content"
+msgstr "Salta als continguts principals"
+
+#: views/layouts/amo2009.thtml:203
+msgid "header_navaccess_search_form"
+msgstr "Salta al formulari de cerca"
+
+#: views/elements/header.thtml:62
+msgid "header_navlink_addons"
+msgstr "Complements"
+
+#: views/elements/developers/sidebar.thtml:72
+#: views/elements/developers/myaddons.thtml:50 views/elements/header.thtml:159
+#: views/addons/display.thtml:378
+msgid "header_navlink_login"
+msgstr "Inicia una sessió"
+
+#: views/elements/header.thtml:156 views/layouts/amo2009.thtml:304
+msgid "header_navlink_logout"
+msgstr "Surt"
+
+#: views/elements/header.thtml:145 views/layouts/amo2009.thtml:303
+msgid "header_navlink_myaccount"
+msgstr "El meu compte"
+
+#: views/elements/header.thtml:158
+msgid "header_navlink_register"
+msgstr "Registre"
+
+#. %1 is the URL to the registration page
+#. %2 is the URL to the login page
+#: views/layouts/amo2009.thtml:278
+msgid "header_navlink_register_or_login"
+msgstr ""
+"<a href=\"%1$s\">Registra'm</a> o <a href=\"%2$s\">Inicia una sessió</a>"
+
+#: views/layouts/amo2009.thtml:285
+msgid "header_navlink_tools"
+msgstr "Eines"
+
+#. %s is the add-on name
+#: views/elements/collections_interactive_addon.thtml:62
+#: views/elements/amo2009/homepage_addon.thtml:77
+#: views/elements/addon_discussionheader.thtml:62
+#: views/elements/addon_listitem.thtml:67 views/elements/feature.thtml:84
+#: views/addons/category_landing.thtml:87 views/addons/browse_thumbs.thtml:60
+#, php-format
+msgid "img_preview_of"
+msgstr "Previsualitza la imatge de %s"
+
+#. %1 is the login URL for the link tag
+#. %2 is the link to an explanatory page.
+#: views/elements/amo2009/install.thtml:307 views/elements/install.thtml:255
+msgid "install_a_login_to_install"
+msgstr "<a href=\"%1$s\">Registreu-vos</a> per a instal·lar aquest complement"
+
+#. %1 is the URL for the Experimental Add-ons section of the FAQ page
+#: views/elements/amo2009/install.thtml:283 views/elements/install.thtml:232
+msgid "install_button_confirm_exp_install"
+msgstr ""
+"Permet-me instal·lar aquest complement experimental. <a href=\"%1$s\">Què és "
+"això?</a>"
+
+#. %1$s is the application name. Example: Firefox
+#. %2$s is an optional string used to specify a platform. Example: (Windows)
+#: views/elements/amo2009/install.thtml:128 views/elements/install.thtml:75
+#, php-format
+msgid "install_button_text"
+msgstr "Afegeix-lo al %s %s"
+
+#. %1 is the add-on name, %2 is the app name
+#: views/elements/amo2009/install.thtml:191
+#: views/elements/amo2009/install.thtml:206
+#: views/elements/amo2009/install.thtml:249
+#: views/elements/amo2009/install.thtml:298 views/elements/install.thtml:150
+#: views/elements/install.thtml:165 views/elements/install.thtml:202
+#: views/elements/install.thtml:246
+#, php-format
+msgid "install_button_title"
+msgstr "Afegeix %1$s al %2$s"
+
+#. %1$s is the add-on name
+#: views/elements/amo2009/install.thtml:200 views/elements/install.thtml:159
+#, php-format
+msgid "install_download"
+msgstr "Baixa %1$s"
+
+#: views/elements/amo2009/install.thtml:147 views/elements/install.thtml:94
+msgid "install_error_addon_not_found"
+msgstr "Aquest complement no està disponible."
+
+#: views/addons/dictionaries.thtml:65
+msgid "langtools_a11y_tablesummary"
+msgstr "Llista de paquets d'idioma i diccionaris"
+
+#: views/addons/dictionaries.thtml:47
+msgid "langtools_download_dictionary"
+msgstr "Baixa el diccionari"
+
+#: views/addons/dictionaries.thtml:48
+msgid "langtools_download_langpack"
+msgstr "Baixa el paquet d'idioma"
+
+#: views/addons/dictionaries.thtml:63 controllers/components/amo.php:685
+#: controllers/addons_controller.php:1239
+msgid "langtools_header_dicts_and_langpacks"
+msgstr "Diccionaris i paquets d'idioma"
+
+#: views/addons/dictionaries.thtml:44
+msgid "langtools_install_dictionary"
+msgstr "Instal·la el diccionari"
+
+#: views/addons/dictionaries.thtml:45
+msgid "langtools_install_langpack"
+msgstr "Instal·la el paquet d'idioma"
+
+#: views/addons/dictionaries.thtml:69
+msgid "langtools_tableheader_dictionary"
+msgstr "Diccionari"
+
+#: views/addons/dictionaries.thtml:70
+msgid "langtools_tableheader_langpack"
+msgstr "Paquet d'idioma"
+
+#: views/addons/dictionaries.thtml:68
+msgid "langtools_tableheader_language"
+msgstr "Idioma"
+
+#: models/license.php:65
+msgid "license_custom"
+msgstr "Custom License"
+
+#: config/bootstrap.php:303
+msgid "licenses_bsd"
+msgstr "BSD License"
+
+#: config/bootstrap.php:298
+msgid "licenses_gpl_2.0"
+msgstr "GNU General Public License, version 2.0"
+
+#: config/bootstrap.php:299
+msgid "licenses_gpl_3.0"
+msgstr "GNU General Public License, version 3.0"
+
+#: config/bootstrap.php:300
+msgid "licenses_lgpl_2.1"
+msgstr "GNU Lesser General Public License, version 2.1"
+
+#: config/bootstrap.php:301
+msgid "licenses_lgpl_3.0"
+msgstr "GNU Lesser General Public License, version 3.0"
+
+#: config/bootstrap.php:302
+msgid "licenses_mit"
+msgstr "MIT/X11 License"
+
+#: config/bootstrap.php:297
+msgid "licenses_mpl_1.1"
+msgstr "Mozilla Public License, version 1.1"
+
+#: views/users/emailchange.thtml:51 views/users/delete.thtml:55
+#: views/users/delete.thtml:137 views/users/edit.thtml:74
+#: views/reviews/flag.thtml:54
+msgid "link_return_to_front_page"
+msgstr "Cliqueu aquí per a tornar a la pàgina principal."
+
+#: views/elements/amo2009/addon_list_options.thtml:46
+#: views/elements/addon_list_options.thtml:46
+msgid "list_sortby_date"
+msgstr "Data"
+
+#: views/elements/amo2009/addon_list_options.thtml:47
+#: views/elements/addon_list_options.thtml:47
+msgid "list_sortby_downloads"
+msgstr "Baixades"
+
+#: views/elements/amo2009/addon_list_options.thtml:45
+#: views/elements/addon_list_options.thtml:45
+msgid "list_sortby_name"
+msgstr "Nom del complement"
+
+#: views/elements/amo2009/addon_list_options.thtml:48
+#: views/elements/addon_list_options.thtml:48
+msgid "list_sortby_rating"
+msgstr "Valoració"
+
+#: config/bootstrap.php:278
+msgid "main_prettyname_fennec"
+msgstr "Fennec"
+
+#: config/bootstrap.php:274
+msgid "main_prettyname_firefox"
+msgstr "Firefox"
+
+#: config/bootstrap.php:277
+msgid "main_prettyname_seamonkey"
+msgstr "SeaMonkey"
+
+#: config/bootstrap.php:276
+msgid "main_prettyname_sunbird"
+msgstr "Sunbird"
+
+#: config/bootstrap.php:275
+msgid "main_prettyname_thunderbird"
+msgstr "Thunderbird"
+
+#: views/elements/addon_categories.thtml:52
+msgid "nav_category_dicts_langpacks"
+msgstr "Diccionaris i paquets d'idioma"
+
+#: views/elements/addon_categories.thtml:55
+msgid "nav_category_themes"
+msgstr "Temes"
+
+#: views/elements/app_chooser.thtml:47 views/layouts/amo2009.thtml:255
+msgid "other_apps_tooltip"
+msgstr "Troba complements per a altres aplicacions"
+
+#. In a user list: user 1, user 2, "others"
+#: views/helpers/addons_html.php:222
+msgid "other_users"
+msgstr "altres"
+
+#: controllers/pages_controller.php:90
+msgid "page_title_appversions"
+msgstr "Versions de l'aplicació"
+
+#: controllers/pages_controller.php:115
+msgid "page_title_collector"
+msgstr "Add-on Collector"
+
+#: controllers/pages_controller.php:117
+msgid "page_title_collector_faq"
+msgstr "PMF de l'Add-on Collector"
+
+#: controllers/pages_controller.php:119
+msgid "page_title_collector_features"
+msgstr "Característiques de l'Add-on Collector"
+
+#: controllers/pages_controller.php:122
+msgid "page_title_collector_firstrun"
+msgstr "Benvingut a l'Add-on Collector"
+
+#: controllers/pages_controller.php:92
+msgid "page_title_credits"
+msgstr "Crèdits"
+
+#: controllers/pages_controller.php:113
+msgid "page_title_developer_faq"
+msgstr "PMF del desenvolupador"
+
+#: controllers/pages_controller.php:111
+msgid "page_title_faq"
+msgstr "Preguntes més freqüents"
+
+#: controllers/pages_controller.php:94
+msgid "page_title_fashionyourfirefox_faq"
+msgstr "PMF Modernitza el teu Firefox"
+
+#: controllers/pages_controller.php:101
+msgid "page_title_policy"
+msgstr "Normes dels complements"
+
+#: controllers/pages_controller.php:103
+msgid "page_title_privacy"
+msgstr "Política de privadesa de Mozilla"
+
+#: controllers/pages_controller.php:105
+msgid "page_title_review_guide"
+msgstr "Guia per a la revisió"
+
+#: controllers/pages_controller.php:107
+msgid "page_title_sandbox"
+msgstr "Sistema de revisió de l'entorn de proves"
+
+#: controllers/pages_controller.php:109
+msgid "page_title_submissionhelp"
+msgstr "Ajuda a la publicació"
+
+#: views/pages/appversions.thtml:87
+msgid "pages_appversions_guid"
+msgstr "GUID"
+
+#: views/pages/appversions.thtml:79 controllers/pages_controller.php:90
+msgid "pages_appversions_header"
+msgstr "Versions d'aplicació vàlides"
+
+#: views/pages/appversions.thtml:80
+msgid "pages_appversions_intro"
+msgstr ""
+"Els complements publicats a Mozilla Add-ons han de tenir un fitxer install."
+"rdf disponible per, com a mínim, una de les aplicacions següents. Només les "
+"versions que es mostren a continuació són permeses per a aquestes "
+"aplicacions."
+
+#. %s is a full <a> tag
+#: views/pages/appversions.thtml:93
+#, php-format
+msgid "pages_appversions_required_files"
+msgstr ""
+"Si la vostra aplicació no requereix un fitxer install.rdf, tot i així haureu "
+"d'incloure'n un amb les propietats necessàries tal com ho especifica %s."
+
+#. this is the text inside of an <a> tag for pages_appversions_required_files. This
+#. should be fixed.
+#: views/pages/appversions.thtml:93
+msgid "pages_appversions_required_files_link"
+msgstr "ací"
+
+#: views/pages/appversions.thtml:88
+msgid "pages_appversions_versions"
+msgstr "Versions"
+
+#: views/pages/policy.thtml:51
+msgid "pages_policy_sandbox_link"
+msgstr "Informació de l'entorn de proves"
+
+#: views/elements/pagination.thtml:53
+msgid "pagination_next_page"
+msgstr "següent"
+
+#: views/elements/pagination.thtml:52
+msgid "pagination_previous_page"
+msgstr "anterior"
+
+#: views/elements/recaptcha.thtml:65
+msgid "recaptcha_enter_both_words"
+msgstr ""
+"Escriviu les <strong>dues paraules</strong> de sota, <strong>separades amb "
+"un espai</strong>."
+
+#: views/elements/recaptcha.thtml:83
+msgid "recaptcha_enter_here"
+msgstr "Escriviu la vostra resposta aquí:"
+
+#: views/elements/recaptcha.thtml:74
+msgid "recaptcha_enter_whatyouhear"
+msgstr "Escriviu el que escolteu."
+
+#. %1 is the link switching refreshing the captcha
+#. %2 is the link switching to a text captcha
+#: views/elements/recaptcha.thtml:77
+msgid "recaptcha_hardtohear_text"
+msgstr ""
+"Si no ho heu pogut entendre, podeu <a href=\"%1$s\">escoltar una altra cosa</"
+"a> o bé <a href=\"%2$s\">tornar al text</a>."
+
+#. %1 is the link switching refreshing the captcha
+#. %2 is the link switching to an audio captcha
+#: views/elements/recaptcha.thtml:68
+msgid "recaptcha_hardtoread_text"
+msgstr ""
+"Si us costa de llegir, podeu <a href=\"%1$s\">intentar unes paraules "
+"diferents</a> o bé, en comptes d'això, <a href=\"%2$s\">escoltar una altra "
+"cosa</a>."
+
+#: views/users/register.thtml:105
+msgid "recaptcha_label"
+msgstr "Sou humà?"
+
+#: views/users/register.thtml:106
+msgid "recaptcha_whatsthis"
+msgstr "Què és això?"
+
+#: controllers/reviews_controller.php:559
+msgid "review_flag_error"
+msgstr "S'ha produït un error marcant aquesta revisió."
+
+#: models/reviews_moderation_flag.php:69
+msgid "review_flag_reason_bug_support"
+msgstr "Petició o un problema que no hauria de ser aquí"
+
+#: views/reviews/display.thtml:103 views/reviews/display.thtml:186
+msgid "review_flag_reason_instructions"
+msgstr "Denuncia aquesta revisió (selecciona el motiu)"
+
+#: models/reviews_moderation_flag.php:67
+msgid "review_flag_reason_language"
+msgstr "Utilitza un llenguatge inadequat."
+
+#: models/reviews_moderation_flag.php:71
+msgid "review_flag_reason_other"
+msgstr "Un altre motiu (especifica)"
+
+#: models/reviews_moderation_flag.php:65
+msgid "review_flag_reason_spam"
+msgstr "És spam o bé el contingut no és una revisió"
+
+#: views/reviews/display.thtml:91 views/reviews/display.thtml:175
+#: controllers/reviews_controller.php:555
+msgid "review_flag_success"
+msgstr "Gràcies, aquesta revisió està marcada per a què l'aprovi un editor."
+
+#: views/reviews/display.thtml:41
+msgid "review_flag_this"
+msgstr "Marca aquesta revisió"
+
+#: views/reviews/display.thtml:42
+msgid "review_flag_this_titletip"
+msgstr ""
+"Aquesta revisió és inadequada, poc acurada o és correu brossa? cliqueu aquí "
+"per a marcar-la per a ser revisada per un editor."
+
+#. %1 is the URL of the support section, %2 for the review guidelines
+#: views/reviews/add.thtml:53
+msgid "review_guidelines_short"
+msgstr ""
+"<p>Tingueu present aquests consells:</p><ul><li>Escriviu com si parléssiu a "
+"un amic sobre què us sembla el complement. Expliqueu-ne detalls útils i "
+"específics com per exemple què us ha agradat i que què no us ha agradat, si "
+"és fàcil de fer servir o no, o bé sobre qualsevol desavantatge que tingui. "
+"Eviteu expressions genèriques com \"Bo\" o \"Dolent\" a no ser que "
+"n'expliqueu ben bé les raons.</li><li>No informeu d'errades en les "
+"revisions. Ja que la vostra adreça de correu no es farà pública al "
+"desenvolupador del complement i potser la necessitaria per a poder-se posar-"
+"se en contacte amb vostè per a resoldre el problema. Vegeu <a href=\"%1$s"
+"\">la secció d'ajuda</a> per a saber on podeu trobar assistència per a "
+"aquest complement.</li><li>Sigueu polits amb les vostres revisions, eviteu "
+"el llenguatge impropi i les referències personals.</li></ul><p>Llegiu la <a "
+"href=\"%2$s\">Guia de les revisions</a> si voleu més informació sobre la "
+"revisió de complements.</p>"
+
+#. %1 is the add-on name
+#: views/reviews/flag.thtml:56 views/reviews/display.thtml:55
+#: views/reviews/review_added.thtml:50
+#, php-format
+msgid "reviews_header"
+msgstr "Revisions del %s"
+
+#: controllers/addons_controller.php:435
+msgid "rss_featuredaddons"
+msgstr "Complements destacats"
+
+#: controllers/addons_controller.php:432
+msgid "rss_newestaddons"
+msgstr "Complements nous"
+
+#: controllers/addons_controller.php:434
+msgid "rss_popularaddons"
+msgstr "Complements populars"
+
+#: controllers/addons_controller.php:433
+msgid "rss_updatedaddons"
+msgstr "Complements actualitzats"
+
+#: views/elements/search_mini.thtml:70
+msgid "search"
+msgstr "Search"
+
+#: views/search/collections.thtml:51
+msgid "search_collections_header"
+msgstr "Resultat de la cerca de col·leccions"
+
+#: controllers/search_controller.php:297
+msgid "search_collections_pagetitle"
+msgstr "Resultat de la cerca de col·leccions"
+
+#: controllers/search_controller.php:99
+msgid "search_disabled"
+msgstr "La cerca està inhabilitada. Torneu-ho a provar més tard."
+
+#: views/elements/amo2009/search.thtml:188 views/elements/search.thtml:187
+#: views/elements/search_mini.thtml:54
+msgid "search_form_all_addons"
+msgstr "tots els complements"
+
+#. This string is in the main category dropdown when searching
+#: views/elements/amo2009/search.thtml:204
+msgid "search_form_all_collections"
+msgstr "totes les col·leccions"
+
+#: views/elements/amo2009/search.thtml:184
+#: views/elements/amo2009/search.thtml:385
+#: views/elements/amo2009/search.thtml:408 views/elements/search.thtml:171
+#: views/elements/search.thtml:183 views/elements/search_mini.thtml:43
+#: views/elements/search_mini.thtml:49 views/layouts/mozilla.thtml:188
+msgid "search_form_default_text"
+msgstr "cerca complements"
+
+#: views/elements/amo2009/search.thtml:184
+#: views/elements/amo2009/search.thtml:404
+msgid "search_form_default_text_collections"
+msgstr "cerca col·leccions"
+
+#: views/elements/amo2009/search.thtml:206 views/elements/search.thtml:202
+msgid "search_form_submit_tooltip"
+msgstr "Cerca complements"
+
+#: views/elements/amo2009/search.thtml:184 views/elements/search.thtml:183
+#: views/elements/search_mini.thtml:49
+msgid "search_form_tooltip"
+msgstr "Cliqueu per a introduir el termes de la cerca"
+
+#: views/elements/amo2009/search.thtml:186 views/elements/search.thtml:185
+#: views/elements/search_mini.thtml:52
+msgid "search_form_within"
+msgstr "a"
+
+#: views/addons/searchengines.thtml:118
+msgid "search_landing_all_search_engines"
+msgstr "Tots els motors de cerca"
+
+#: views/addons/searchengines.thtml:114
+msgid "search_landing_browse_search_engines"
+msgstr "Els motors de cerca del navegador"
+
+#: views/search/collections.thtml:58 views/search/index.thtml:59
+msgid "search_nothing_found"
+msgstr "No s'han trobat resultats."
+
+#: controllers/search_controller.php:185
+msgid "search_pagetitle"
+msgstr "Cerca complements"
+
+#: controllers/search_controller.php:242
+msgid "search_rss_description"
+msgstr "Canal dels resultats de la cerca"
+
+#. %s is the terms the user is searching for (a string)
+#: controllers/search_controller.php:241
+#, php-format
+msgid "search_rss_results_for"
+msgstr "Resultats de la cerca: %s"
+
+#: views/elements/header.thtml:154 views/layouts/amo2009.thtml:296
+msgid "sidebar_navlink_admin_tools"
+msgstr "Eines de l'administrador"
+
+#: views/elements/header.thtml:146 views/layouts/amo2009.thtml:288
+msgid "sidebar_navlink_developer_tools"
+msgstr "Eines del desenvolupador"
+
+#: views/elements/header.thtml:148 views/layouts/amo2009.thtml:290
+msgid "sidebar_navlink_editor_tools"
+msgstr "Eines de l'editor"
+
+#: views/layouts/amo2009.thtml:302
+msgid "sidebar_navlink_welcome"
+msgstr "Benvingut/da"
+
+#. %s is the user's name
+#: views/layouts/amo2009.thtml:302
+#, php-format
+msgid "sidebar_navlink_welcome_name"
+msgstr "Benvingut/da, %s"
+
+#: views/elements/pitch.thtml:50 views/elements/pitch.thtml:55
+msgid "sidebar_pitch_dictionary"
+msgstr "Diccionari"
+
+#: views/elements/pitch.thtml:72
+msgid "sidebar_pitch_featured_addons"
+msgstr "Complements recomanats"
+
+#: views/elements/pitch.thtml:61
+msgid "sidebar_pitch_looking_for"
+msgstr "Estic cercant:"
+
+#: views/elements/pitch.thtml:70
+msgid "sidebar_pitch_newest_addons"
+msgstr "Els complements més nous"
+
+#: views/elements/pitch.thtml:49
+msgid "sidebar_pitch_search"
+msgstr "Connector de cerca"
+
+#: views/elements/pitch.thtml:69
+msgid "sidebar_pitch_subscribe_to"
+msgstr "Subscriu-me a"
+
+#: views/elements/pitch.thtml:48 views/elements/pitch.thtml:54
+msgid "sidebar_pitch_theme"
+msgstr "Tema"
+
+#: views/elements/pitch.thtml:71
+msgid "sidebar_pitch_updated_addons"
+msgstr "Complements actualitzats"
+
+#. %1$s is a number
+#: views/helpers/localization.php:65 views/developers/versions_edit.thtml:95
+#: views/addons/dictionaries.thtml:92
+#, php-format
+msgid "size_kb"
+msgstr "%1$s kB"
+
+#: views/elements/amo2009/stars.thtml:57 views/elements/stars.thtml:63
+msgid "stars_not_yet_rated"
+msgstr "Encara no s'ha valorat"
+
+#. %1 is the number of stars this add-on has
+#: views/elements/amo2009/stars.thtml:49 views/elements/stars.thtml:54
+#, php-format
+msgid "stars_rated_x_outof_5"
+msgstr "Valorat amb %s de 5 estrelles"
+
+#: views/statistics/addon.thtml:59
+msgid "statistics_addon_dashboard_link"
+msgstr "Estadístiques"
+
+#: views/statistics/addon.thtml:58
+msgid "statistics_addon_developertools_link"
+msgstr "Eines de desenvolupament"
+
+#: views/statistics/addon.thtml:53
+msgid "statistics_addon_switch"
+msgstr "Canvia de complement"
+
+#. This is a date format.
+#. http://php.net/strftime
+#: views/statistics/rss/summary.thtml:54 views/statistics/addon.thtml:181
+msgid "statistics_date_shortmonth"
+msgstr "%e %b."
+
+#. This is a date format.
+#. http://php.net/strftime
+#: views/statistics/rss/summary.thtml:40 views/statistics/addon.thtml:152
+msgid "statistics_date_shortmonthwithyear"
+msgstr "%e %b %Y"
+
+#. This is a date format.
+#. http://php.net/strftime
+#: views/statistics/rss/summary.thtml:41 views/statistics/rss/summary.thtml:48
+#: views/statistics/addon.thtml:161 views/statistics/addon.thtml:172
+msgid "statistics_date_weekdayshortmonth"
+msgstr "%A, %e %b."
+
+#. %1$s is an add-on name and version. Example: Add-on 3.5
+#: controllers/components/stats.php:519
+#, php-format
+msgid "statistics_events_addon_created"
+msgstr "%1$s creats"
+
+#. %1$s is an application name and version. Example: Firefox 3.5
+#: controllers/components/stats.php:500
+#, php-format
+msgid "statistics_events_app_released"
+msgstr "%1$s acabats"
+
+#: views/statistics/addon.thtml:71
+msgid "statistics_help_close_link"
+msgstr "Tanca"
+
+#: views/statistics/addon.thtml:60
+msgid "statistics_help_link"
+msgstr "Ajuda"
+
+#: views/statistics/index.thtml:83
+msgid "statistics_index_anotheraddon"
+msgstr "o bé selecciona un altre complement"
+
+#: views/statistics/index.thtml:85
+msgid "statistics_index_anotheraddon_public"
+msgstr "o bé selecciona un complement amb estadístiques publicades"
+
+#: views/statistics/index.thtml:71
+msgid "statistics_index_myaddons"
+msgstr ""
+"Seleccioneu un dels vostres complements per a veure'n les estadístiques"
+
+#: views/statistics/index.thtml:89
+msgid "statistics_index_selectaddon"
+msgstr "Seleccioneu un complement per a veure'n les estadístiques"
+
+#: views/statistics/index.thtml:91
+msgid "statistics_index_selectaddon_public"
+msgstr "Seleccioneu un complement amb estadístiques publicades"
+
+#: views/statistics/index.thtml:39
+msgid "statistics_index_title"
+msgstr "Consola d'estadístiques"
+
+#: views/statistics/index.thtml:97
+msgid "statistics_index_view_button"
+msgstr "Mostra les estadístiques"
+
+#: views/statistics/addon.thtml:222 controllers/statistics_controller.php:247
+msgid "statistics_js_download_csv"
+msgstr "Visualitza aquesta taula en format CSV"
+
+#: controllers/statistics_controller.php:246
+msgid "statistics_js_dropdowns_none"
+msgstr "cap"
+
+#: controllers/statistics_controller.php:245
+msgid "statistics_js_dropdowns_removeplot"
+msgstr "Esborra aquesta traça"
+
+#: controllers/statistics_controller.php:248
+msgid "statistics_js_groupby_selector_date"
+msgstr "Agrupa per: Dia"
+
+#: controllers/statistics_controller.php:251
+msgid "statistics_js_groupby_selector_month"
+msgstr "Agrupa per: Mes"
+
+#: controllers/statistics_controller.php:249
+msgid "statistics_js_groupby_selector_week"
+msgstr "Agrupa per: Setmana"
+
+#: controllers/statistics_controller.php:250
+msgid "statistics_js_groupby_selector_week_over_week"
+msgstr "Compara per: Setmana"
+
+#: controllers/statistics_controller.php:260
+msgid "statistics_js_plotselection_foundinrange"
+msgstr "%s trobat en la regió"
+
+#: controllers/statistics_controller.php:270
+msgid "statistics_js_plotselection_options_addplot_name"
+msgstr "Afegeix una traça"
+
+#: controllers/statistics_controller.php:271
+msgid "statistics_js_plotselection_options_addplot_tooltip"
+msgstr "Afegeix una altra traça al diagrama"
+
+#: controllers/statistics_controller.php:261
+msgid "statistics_js_plotselection_options_count_name_checked"
+msgstr "Amaga el total"
+
+#: controllers/statistics_controller.php:262
+msgid "statistics_js_plotselection_options_count_name_unchecked"
+msgstr "Mostra el total"
+
+#: controllers/statistics_controller.php:263
+msgid "statistics_js_plotselection_options_count_tooltip"
+msgstr "Mostra el total en aquest diagrama"
+
+#: controllers/statistics_controller.php:275
+msgid "statistics_js_plotselection_options_csv_name"
+msgstr "Visualitza les dades (CSV)"
+
+#: controllers/statistics_controller.php:276
+msgid "statistics_js_plotselection_options_csv_tooltip"
+msgstr "Obtén les dades en un fitxer amb els valors separats per comes"
+
+#: controllers/statistics_controller.php:267
+msgid "statistics_js_plotselection_options_events_addon_name_checked"
+msgstr "Amaga %s esdeveniments"
+
+#: controllers/statistics_controller.php:268
+msgid "statistics_js_plotselection_options_events_addon_name_unchecked"
+msgstr "Mostra %s esdeveniments"
+
+#: controllers/statistics_controller.php:269
+msgid "statistics_js_plotselection_options_events_addon_tooltip"
+msgstr "Sobreposa les dates de sortida del complement en el diagrama"
+
+#: controllers/statistics_controller.php:264
+msgid "statistics_js_plotselection_options_events_firefox_name_checked"
+msgstr "Amaga els esdeveniments del Firefox"
+
+#: controllers/statistics_controller.php:265
+msgid "statistics_js_plotselection_options_events_firefox_name_unchecked"
+msgstr "Mostra els esdeveniments del Firefox"
+
+#: controllers/statistics_controller.php:266
+msgid "statistics_js_plotselection_options_events_firefox_tooltip"
+msgstr "Sobreposa les dades de sortida del Firefox en els diagrames"
+
+#: controllers/statistics_controller.php:272
+msgid "statistics_js_plotselection_options_resize_name_checked"
+msgstr "Amaga el diagrama"
+
+#: controllers/statistics_controller.php:273
+msgid "statistics_js_plotselection_options_resize_name_unchecked"
+msgstr "Mostra el diagrama"
+
+#: controllers/statistics_controller.php:274
+msgid "statistics_js_plotselection_options_resize_tooltip"
+msgstr "Canvia la mida del diagrama"
+
+#: controllers/statistics_controller.php:254
+msgid "statistics_js_plotselection_selector_adu"
+msgstr "Usuaris actius diàriament"
+
+#: controllers/statistics_controller.php:256
+msgid "statistics_js_plotselection_selector_application"
+msgstr "Aplicació"
+
+#: controllers/statistics_controller.php:259
+msgid "statistics_js_plotselection_selector_custom"
+msgstr "Personalitzat"
+
+#: controllers/statistics_controller.php:253
+msgid "statistics_js_plotselection_selector_downloads"
+msgstr "Baixades"
+
+#: controllers/statistics_controller.php:258
+msgid "statistics_js_plotselection_selector_os"
+msgstr "Sistema operatiu"
+
+#: controllers/statistics_controller.php:257
+msgid "statistics_js_plotselection_selector_status"
+msgstr "Estat del complement"
+
+#: controllers/statistics_controller.php:252
+msgid "statistics_js_plotselection_selector_summary"
+msgstr "Resum"
+
+#: controllers/statistics_controller.php:255
+msgid "statistics_js_plotselection_selector_version"
+msgstr "Versió del complement"
+
+#: controllers/components/stats.php:398
+msgid "statistics_longnames_application"
+msgstr "Aplicació"
+
+#: controllers/components/stats.php:400
+msgid "statistics_longnames_os"
+msgstr "Sistema operatiu"
+
+#: controllers/components/stats.php:399
+msgid "statistics_longnames_status"
+msgstr "Estat del complement"
+
+#: controllers/components/stats.php:401
+msgid "statistics_longnames_unknown"
+msgstr "Desconegut"
+
+#: controllers/components/stats.php:397
+msgid "statistics_longnames_version"
+msgstr "Versió del complement"
+
+#: views/statistics/addon.thtml:118
+msgid "statistics_notice_data_insufficient"
+msgstr ""
+"Encara no hi ha prou informació per a mostrar aquest diagrama. Proveu-ho més "
+"tard."
+
+#: views/statistics/addon.thtml:130
+msgid "statistics_notice_data_none"
+msgstr ""
+"Encara no tenim informació del vostre complement. Proveu-ho d'aquí uns "
+"quants dies."
+
+#: views/statistics/addon.thtml:41
+msgid "statistics_notice_data_updating"
+msgstr ""
+"Les estadístiques dels complements estan en procés d'actualització. La "
+"informació més recent potser encara no estarà actualitzada fins que no "
+"s'acabi el procés d'actualització. Torneu d'aquí uns minuts."
+
+#: views/statistics/addon.thtml:136
+msgid "statistics_notice_disabled"
+msgstr ""
+"La consola d'estadístiques està deshabilitada. Toneu-ho a provar més tard."
+
+#: views/statistics/addon.thtml:123
+msgid "statistics_notice_nojavascript"
+msgstr ""
+"Cal Javascript per a visualitzar els diagrames de la consola d'estadístiques."
+
+#: views/statistics/addon.thtml:44
+msgid "statistics_notice_settings_updated"
+msgstr "S'han actualitzat les vostres preferències."
+
+#: controllers/statistics_controller.php:60
+#: controllers/statistics_controller.php:71
+#: controllers/statistics_controller.php:74
+#: controllers/statistics_controller.php:240
+msgid "statistics_pagetitle"
+msgstr "Consola d'estadístiques"
+
+#: views/statistics/addon.thtml:99
+msgid "statistics_plot_legend_adu"
+msgstr "Usuaris actius diàriament"
+
+#: views/statistics/addon.thtml:95
+msgid "statistics_plot_legend_downloads"
+msgstr "Baixades per dia"
+
+#: views/statistics/addon.thtml:107
+msgid "statistics_plot_options_zoomin_alt"
+msgstr "Amplia"
+
+#: views/statistics/addon.thtml:106
+msgid "statistics_plot_options_zoomin_title"
+msgstr "Amplia un mes"
+
+#: views/statistics/addon.thtml:110
+msgid "statistics_plot_options_zoomout_alt"
+msgstr "Redueix"
+
+#: views/statistics/addon.thtml:109
+msgid "statistics_plot_options_zoomout_title"
+msgstr "Redueix un mes"
+
+#: controllers/statistics_controller.php:283
+#, php-format
+msgid "statistics_rss_description"
+msgstr "Resum diari de les estadístiques de %1$s"
+
+#: views/statistics/rss/summary.thtml:68
+msgid "statistics_rss_title_fulldate"
+msgstr "%A, %e de %B de %Y"
+
+#: views/statistics/rss/summary.thtml:68
+#, php-format
+msgid "statistics_rss_title_statsfordate"
+msgstr "Estadístiques de %1$s"
+
+#: views/statistics/settings.thtml:49
+msgid "statistics_settings_access_description"
+msgstr ""
+"Per defecte, només vostè i Mozilla podreu accedir a la informació de la "
+"consola d'estadístiques. Però també podeu obrir-ho al públic per tal que "
+"tothom pugui veure les dades del vostre complement."
+
+#: views/statistics/settings.thtml:48
+msgid "statistics_settings_access_heading"
+msgstr "Accés a les dades"
+
+#: views/statistics/settings.thtml:51
+msgid "statistics_settings_access_private"
+msgstr "Privat"
+
+#: views/statistics/settings.thtml:51
+msgid "statistics_settings_access_private_description"
+msgstr "Només vostè i Mozilla podreu veure les estadístiques del complement"
+
+#: views/statistics/settings.thtml:52
+msgid "statistics_settings_access_public"
+msgstr "Públic"
+
+#: views/statistics/settings.thtml:52
+msgid "statistics_settings_access_public_description"
+msgstr "Tothom podrà veure les estadístiques d'aquest complement"
+
+#: views/statistics/addon.thtml:251
+msgid "statistics_settings_change_link"
+msgstr "Canvia les preferències"
+
+#: views/statistics/addon.thtml:253
+msgid "statistics_settings_confidential"
+msgstr "Tracteu aquesta informació com a confidencial."
+
+#: views/statistics/addon.thtml:245
+msgid "statistics_settings_currently_private"
+msgstr "Aquestes dades actualment són <b>privades</b>."
+
+#: views/statistics/addon.thtml:241
+msgid "statistics_settings_currently_public"
+msgstr "Aquestes dades actualment són <b>públiques</b>."
+
+#: views/statistics/addon.thtml:246
+msgid "statistics_settings_locked_alt"
+msgstr "Bloquejat"
+
+#: views/statistics/settings.thtml:57
+msgid "statistics_settings_return_link"
+msgstr "Torna a les estadístiques"
+
+#: views/statistics/settings.thtml:56
+msgid "statistics_settings_save_button"
+msgstr "Desa les preferències"
+
+#: views/statistics/settings.thtml:46
+#, php-format
+msgid "statistics_settings_title"
+msgstr "Preferències de la consola d'estadístiques de %1$s"
+
+#: views/statistics/addon.thtml:242
+msgid "statistics_settings_unlocked_alt"
+msgstr "Desbloquejat"
+
+#: controllers/components/stats.php:405
+msgid "statistics_shortnames_application"
+msgstr "Apl."
+
+#: controllers/components/stats.php:407
+msgid "statistics_shortnames_os"
+msgstr "S.O."
+
+#: controllers/components/stats.php:406
+msgid "statistics_shortnames_status"
+msgstr "Est"
+
+#: controllers/components/stats.php:408
+msgid "statistics_shortnames_unknown"
+msgstr "Des"
+
+#: controllers/components/stats.php:404
+msgid "statistics_shortnames_version"
+msgstr "Ver"
+
+#: views/statistics/rss/summary.thtml:42 views/statistics/addon.thtml:192
+msgid "statistics_summary_downloads_average"
+msgstr "Mitjana de baixades diàries"
+
+#: views/statistics/rss/summary.thtml:39
+msgid "statistics_summary_downloads_heading"
+msgstr "Baixades"
+
+#: views/statistics/rss/summary.thtml:41 views/statistics/addon.thtml:171
+msgid "statistics_summary_downloads_lastcount"
+msgstr "Recompte de l'últim dia"
+
+#: views/statistics/rss/summary.thtml:43 views/statistics/addon.thtml:199
+msgid "statistics_summary_downloads_lastweek"
+msgstr "Baixades dels últims 7 dies"
+
+#: views/statistics/rss/summary.thtml:40 views/statistics/addon.thtml:151
+msgid "statistics_summary_downloads_total"
+msgstr "Total de baixades"
+
+#: views/statistics/rss/summary.thtml:40 views/statistics/addon.thtml:152
+#, php-format
+msgid "statistics_summary_downloads_total_sincedate"
+msgstr "Des de %1$s"
+
+#: views/statistics/rss/summary.thtml:50 views/statistics/rss/summary.thtml:56
+#: views/statistics/addon.thtml:163 views/statistics/addon.thtml:183
+msgid "statistics_summary_nodata"
+msgstr "Sense dades encara"
+
+#: views/statistics/rss/summary.thtml:60 views/statistics/addon.thtml:195
+msgid "statistics_summary_updatepings_average"
+msgstr "Mitjana d'usuaris actius diàriament"
+
+#: views/statistics/rss/summary.thtml:52 views/statistics/addon.thtml:177
+msgid "statistics_summary_updatepings_changefromprevious"
+msgstr "Canvis respecte l'anterior"
+
+#: views/statistics/rss/summary.thtml:54 views/statistics/addon.thtml:181
+#, php-format
+msgid "statistics_summary_updatepings_changefromprevious_ondate"
+msgstr "%1$s de %2$s"
+
+#: views/statistics/rss/summary.thtml:45
+msgid "statistics_summary_updatepings_heading"
+msgstr "Usuaris actius diàriament"
+
+#: views/statistics/rss/summary.thtml:46 views/statistics/addon.thtml:157
+msgid "statistics_summary_updatepings_total"
+msgstr "Usuaris actius diàriament"
+
+#: views/statistics/rss/summary.thtml:48 views/statistics/addon.thtml:161
+#, php-format
+msgid "statistics_summary_updatepings_total_ondate"
+msgstr "A %1$s"
+
+#: views/statistics/rss/summary.thtml:61 views/statistics/addon.thtml:203
+msgid "statistics_summary_updatepings_weekly_average"
+msgstr "Mitjana d'usuaris diaris d'aquesta setmana"
+
+#. %s is a percentage, like '+22.33%'. It sits next to another number, so
+#. the implied meaning is 'percentage change' from the previous stat point.
+#: views/statistics/rss/summary.thtml:62 views/statistics/addon.thtml:205
+msgid "statistics_summary_updatepings_weekly_change"
+msgstr "%s comparat amb l'última setmana"
+
+#: views/statistics/addon.thtml:65 controllers/statistics_controller.php:184
+#: controllers/statistics_controller.php:282
+#, php-format
+msgid "statistics_title_addon_stats"
+msgstr "Estadístiques de %1$s"
+
+#: views/addons/themes_landing.thtml:113
+msgid "themes_landing_all_themes"
+msgstr "Tots els temes"
+
+#: views/addons/themes_landing.thtml:109
+msgid "themes_landing_browse_themes"
+msgstr "Explora els temes"
+
+#: views/users/edit.thtml:185
+msgid "user_change_email"
+msgstr "Canvia l'adreça de correu"
+
+#: views/users/edit.thtml:169
+msgid "user_change_password"
+msgstr "Canvia la contrasenya"
+
+#: views/users/edit.thtml:96
+msgid "user_change_password_or_email"
+msgstr "Canvia la contrasenya o l'adreça electrònica"
+
+#: controllers/users_controller.php:197
+msgid "user_confirmationcode_resent"
+msgstr "El codi de confirmació es va tornar a enviar!"
+
+#. %1 is the email address, %2 is the URL of the user registration page
+#: views/users/delete.thtml:51
+msgid "user_del_account_deleted"
+msgstr ""
+"El vostre compte d'usuari %1$s s'ha suprimit correctament. Si alguna vegada "
+"voleu tornar us podeu tornar a registrar a la <a href=\"%2$s\">pàgina de "
+"registre d'usuaris</a>."
+
+#: views/users/delete.thtml:102
+msgid "user_del_community_sad"
+msgstr ""
+"La comunitat de complements del Mozilla s'entristeix al veure't marxar."
+
+#: views/users/delete.thtml:123
+msgid "user_del_confirm_password"
+msgstr "Confirma la contrasenya"
+
+#: views/users/delete.thtml:134
+msgid "user_del_deletenow"
+msgstr "Suprimeix el meu compte d'usuari ara"
+
+#. %1 is the URL of the user's info page
+#: views/users/delete.thtml:64
+msgid "user_del_error_addons"
+msgstr ""
+"No podeu suprimir el vostre compte d'usuari si sou a la llista <a href=\"%1$s"
+"\">d'autors d'un complement</a>. Per a suprimir el vostre compte, demaneu a "
+"una altra persona del vostre grup de desenvolupament que us esborri de la "
+"llista d'autors dels vostres complements. A continuació ja podreu suprimir "
+"el vostre compte des d'aquí."
+
+#. %1 is a link to the amo-editors mailing list
+#: views/users/delete.thtml:71
+msgid "user_del_error_addons_more_questions"
+msgstr "Si teniu una pregunta més, contacteu amb %1$s per a ser atesos."
+
+#: views/users/delete.thtml:78
+msgid "user_del_error_checkbox"
+msgstr ""
+"Cal que marqueu la casella «Ho he entès...» abans de suprimir el vostre "
+"compte."
+
+#: views/users/delete.thtml:84
+msgid "user_del_error_password"
+msgstr ""
+"Cal que introduïu la vostra contrasenya correctament per tal de continuar."
+
+#. %1 is a link to the amo-admins mailing list
+#: views/users/delete.thtml:91
+msgid "user_del_error_unknown"
+msgstr ""
+"S'ha produït un error desconegut al suprimir el vostre compte. Contacteu amb "
+"%1$s i informeu del problema, nosaltres us suprimirem el vostre compte. "
+"Perdoneu l'inconvenient."
+
+#: views/users/delete.thtml:110
+msgid "user_del_header_confirm_deletion"
+msgstr "Confirmació de la supressió del compte"
+
+#. %1 is the user's email address
+#: views/users/delete.thtml:100
+msgid "user_del_header_delete_account"
+msgstr "Supressió del compte d'usuari %1$s"
+
+#: views/users/delete.thtml:50
+msgid "user_del_header_farewell"
+msgstr "Comiat"
+
+#: views/users/delete.thtml:115
+msgid "user_del_nologin"
+msgstr "Ja no podreu tornar a iniciar una sessió al Mozilla Add-ons."
+
+#: views/users/delete.thtml:112
+msgid "user_del_permanently_removed_means"
+msgstr ""
+"Si cliqueu «Suprimeix» el vostre compte <strong>s'esborrarà permanentment</"
+"strong>. Això significa que:"
+
+#: views/users/delete.thtml:116
+msgid "user_del_reviews_anonymized"
+msgstr ""
+"Les vostres revisions i valoracions no s'esborraran, però es deixaran "
+"d'estar associades amb vostè."
+
+#. %1 is a link to the amo-editors mailing list
+#: views/users/delete.thtml:104
+msgid "user_del_specific_problem_editors"
+msgstr ""
+"Si teniu cap problema específic us podem mirar d'ajudar, per favor no "
+"suprimiu el compte ara, i contacteu amb nosaltres via %1$s. Farem el millor "
+"que podem per a atendre-us i solucionar-ho. "
+
+#: views/users/delete.thtml:130
+msgid "user_del_understand_permanent"
+msgstr "He entès que aquest pas no es pot desfer."
+
+#: views/helpers/addons_html.php:192
+msgid "user_deleted_nickname"
+msgstr "Suprimeix l'usuari"
+
+#. %1 is the new email address
+#: views/users/edit.thtml:71
+msgid "user_edit_confirm_email_sent"
+msgstr ""
+"S'ha enviat un correu electrònic a %1$s per a confirmar la vostra nova "
+"adreça de correu. Per tal que el canvi tingui efecte, heu de clicar l'enllaç "
+"inclòs en el correu. Fins aleshores, podeu continuar entrant amb la vostra "
+"adreça de correu actual. "
+
+#: views/users/edit.thtml:201
+msgid "user_edit_delete_user"
+msgstr "Suprimeix el compte de l'usuari"
+
+#. This contains the email sent to users when they signed up for a new
+#. account:
+#. %1 is the confirmation URL, %2 is the current app
+#: views/users/email/confirm_plain.thtml:6
+#, php-format
+msgid "user_email_confirm_account_nopass"
+msgstr ""
+"Benvingut a %2$s Add-ons.\n"
+"\n"
+"Abans que podeu començar a utilitzar el vostre compte l'heu d'activar - així "
+"es verificarà que la vostra adreça de correu és correcta i que us pertany.\n"
+"Per activar-la, cliqueu l'enllaç següent o copieu i enganxeu-lo a la barra "
+"de navegació del vostre navegador:\n"
+"\n"
+"%1$s\n"
+"\n"
+"Un cop hàgiu activat satisfactòriament el vostre compte, ja no us caldrà "
+"l'adreça de correu.\n"
+"\n"
+"Gràcies per unir-vos al %2$s Add-ons\n"
+"-- Personal del %2$s Add-ons"
+
+#. %1 is the confirmation url, %2 is the application name
+#: views/users/email/emailchange_plain.thtml:5
+msgid "user_email_confirm_emailchange"
+msgstr ""
+"Heu sol·licitat un canvi d'adreça de correu des de %2$s Add-ons.\n"
+"\n"
+"Per tal de confirmar la vostra nova adreça de correu, cliqueu l'enllaç "
+"següent o bé copieu i enganxeu-lo sencer a la barra d'adreces del vostre "
+"navegador:\n"
+"\n"
+"%1$s\n"
+"\n"
+"Teniu 48 hores per a confirmar la nova adreça. Si no voleu realitzar el "
+"canvi, tan sols heu d'ignorar aquest correu.\n"
+"\n"
+"Gràcies.\n"
+"--Personal del %2$s Add-ons"
+
+#: controllers/users_controller.php:168
+#, php-format
+msgid "user_email_confirm_subject"
+msgstr "Gràcies per unir-vos al %s Add-ons"
+
+#. This is the password reset email
+#. %1 is the pw reset URL, %2 is the application
+#: views/users/email/pwreset_plain.thtml:5
+#, php-format
+msgid "user_email_pwreset"
+msgstr ""
+"Recuperació de la contrasenya del %2$s Add-ons\n"
+"\n"
+"S'ha rebut una petició de recuperació de contrasenya d'aquest compte des de "
+"addons.mozilla.org. Per a canviar la contrasenya cliqueu el següent enllaç, "
+"o bé copieu i enganxeu-lo a la barra de navegació del vostre navegador:\n"
+"\n"
+"%1$s\n"
+"\n"
+"Si no heu demanat aquest correu, no cal que feu res més.\n"
+"\n"
+"Gràcies,\n"
+"-- Personal de %2$s Add-ons"
+
+#: controllers/users_controller.php:245
+#, php-format
+msgid "user_email_pwreset_subject"
+msgstr "Recuperació de la vostra contrasenya del %s Add-ons"
+
+#: views/users/emailchange.thtml:50
+msgid "user_emailchange_error"
+msgstr "Error!"
+
+#. %1 is the application name
+#: controllers/users_controller.php:533
+msgid "user_emailchange_subject"
+msgstr "Confirmeu el canvi de la vostra adreça de correu al %1$s Add-ons"
+
+#: views/users/emailchange.thtml:48
+msgid "user_emailchange_success"
+msgstr "Èxit!"
+
+#. %1 is the new email address
+#: views/users/emailchange.thtml:49
+msgid "user_emailchange_successful_description"
+msgstr ""
+"La vostra adreça de correu s'ha canviat satisfactòriament. A partir d'ara "
+"feu servir %1$s per a entrar."
+
+#: views/users/edit.thtml:134 views/admin/users_edit.thtml:111
+msgid "user_form_bio"
+msgstr "Sobre mi"
+
+#: views/users/edit.thtml:135 views/admin/users_edit.thtml:112
+msgid "user_form_bio_description"
+msgstr ""
+"Presenteu-vos vosaltres mateixos a la comunitat, si ho voleu. Aquest text "
+"apareixerà públicament a la vostra pàgina d'informació personal. Es "
+"respectaran els salts de línia, però no es permetrà tot l'HTML."
+
+#: views/users/pwreset.thtml:77 views/users/register.thtml:73
+#: views/users/edit.thtml:181
+msgid "user_form_confirmpassword"
+msgstr "Confirma la contrasenya"
+
+#: views/users/edit.thtml:145
+msgid "user_form_display_collections"
+msgstr "Mostra les col·leccions que he creat al meu perfil d'usuari"
+
+#: views/users/edit.thtml:149
+msgid "user_form_display_collections_fav"
+msgstr "Mostra les meves col·leccions preferides al meu perfil d'usuari"
+
+#: views/users/edit.thtml:86
+#, php-format
+msgid "user_form_editprofile"
+msgstr "Edita el perfil d'usuari d'en/na %s"
+
+#: views/users/pwreset.thtml:52 views/users/login.thtml:81
+#: views/users/register.thtml:63 views/users/edit.thtml:187
+msgid "user_form_email"
+msgstr "Adreça de correu"
+
+#: views/users/register.thtml:78 views/users/edit.thtml:103
+#: views/admin/users_edit.thtml:76
+msgid "user_form_firstname"
+msgstr "Nom"
+
+#: views/users/register.thtml:94 views/users/edit.thtml:119
+#: views/admin/users_edit.thtml:91
+msgid "user_form_hideemail"
+msgstr "Oculta l'adreça de correu"
+
+#: views/users/register.thtml:98 views/users/edit.thtml:123
+#: views/admin/users_edit.thtml:99
+msgid "user_form_homepage"
+msgstr "URL de la pàgina web"
+
+#: views/users/register.thtml:84 views/users/edit.thtml:109
+#: views/admin/users_edit.thtml:81
+msgid "user_form_lastname"
+msgstr "Cognoms"
+
+#: controllers/users_controller.php:333
+msgid "user_form_login"
+msgstr "Usuari"
+
+#: views/users/pwreset.thtml:72 views/users/edit.thtml:176
+msgid "user_form_newpassword"
+msgstr "Nova contrasenya"
+
+#: views/users/register.thtml:89 views/users/edit.thtml:114
+#: views/admin/users_edit.thtml:86
+msgid "user_form_nickname"
+msgstr "Àlies"
+
+#: views/users/edit.thtml:171
+msgid "user_form_oldpassword"
+msgstr "Contrasenya antiga"
+
+#: views/users/edit.thtml:97 views/users/edit.thtml:200
+msgid "user_form_otheractions"
+msgstr "Altres accions"
+
+#: views/users/login.thtml:85 views/users/register.thtml:68
+msgid "user_form_password"
+msgstr "Contrasenya"
+
+#: controllers/users_controller.php:93
+msgid "user_form_registration"
+msgstr "Registre d'un nou usuari"
+
+#: views/users/login.thtml:90
+msgid "user_form_remember_me"
+msgstr "Recorda'm en aquest ordinador"
+
+#: views/admin/users_edit.thtml:95
+msgid "user_form_showsandbox"
+msgstr "Mostra l'entorn de proves?"
+
+#: views/users/edit.thtml:205
+msgid "user_form_submit_edit"
+msgstr "Desa"
+
+#: views/users/login.thtml:93
+msgid "user_form_submit_login"
+msgstr "Inicia una sessió"
+
+#: views/users/register.thtml:113
+msgid "user_form_submit_register"
+msgstr "Registre"
+
+#: views/users/info.thtml:75
+#, php-format
+msgid "user_info_usersince"
+msgstr "Usuari del %s complements des de"
+
+#: views/users/login.thtml:102
+msgid "user_login_register_link"
+msgstr "Crea un compte d'usuari"
+
+#: views/users/edit.thtml:160
+msgid "user_notifications_item_compat"
+msgstr "Compatibilitat del complement (molt recomanada)"
+
+#: views/users/edit.thtml:161
+msgid "user_notifications_item_events"
+msgstr "Esdeveniments futurs i respostes"
+
+#: views/users/edit.thtml:156
+msgid "user_notifications_none_available"
+msgstr "No teniu cap notificació disponible que calgui configurar."
+
+#: views/users/edit.thtml:158
+msgid "user_notifications_select_topics"
+msgstr ""
+"De tant en tant, Mozilla us anirà enviant correus sobre les properes "
+"versions i esdeveniments dels complements. Seleccioneu els temes que us "
+"interessen:"
+
+#: views/users/edit.thtml:164
+msgid "user_notifications_specific_contact"
+msgstr ""
+"Mozilla es reserva el dret de contactar-vos individualment per tractar de "
+"temes específics dels vostres complements hostatjats."
+
+#: controllers/users_controller.php:543
+msgid "user_profile_edit_error"
+msgstr ""
+"Hi ha errors en els canvis que heu fet. Corregiu-los i torneu a enviar el "
+"formulari"
+
+#: controllers/users_controller.php:540
+msgid "user_profile_saved"
+msgstr "El perfil s'ha actualitzat."
+
+#: views/users/pwreset.thtml:65
+#, php-format
+msgid "user_pwreset_for_email"
+msgstr "Recuperació de la contrasenya d'en/na %s"
+
+#: controllers/users_controller.php:226
+msgid "user_pwreset_header"
+msgstr "Recuperació de la contrasenya"
+
+#: views/users/login.thtml:103
+msgid "user_pwreset_link"
+msgstr "Heu oblidat la vostra contrasenya?"
+
+#: controllers/users_controller.php:248
+msgid "user_pwreset_link_sent"
+msgstr ""
+"S'ha enviat un correu a la vostra adreça amb l'enllaç cap a la recuperació "
+"de la contrasenya."
+
+#: controllers/users_controller.php:304
+msgid "user_pwreset_okay"
+msgstr "La contrasenya s'ha recuperat satisfactòriament."
+
+#: views/users/pwreset.thtml:82
+msgid "user_pwreset_submit_changepw"
+msgstr "Envia el canvi de contrasenya"
+
+#: views/users/pwreset.thtml:57
+msgid "user_pwreset_submit_sendlink"
+msgstr "Envia l'enllaç per a recuperar la contrasenya"
+
+#: views/users/register_complete.thtml:51
+#, php-format
+msgid "user_register_amo_link"
+msgstr "Complements del %s"
+
+#. %1 is the user's email address, %2 is the current app
+#: views/users/activatefirst.thtml:49
+#, php-format
+msgid "user_register_click_confirm_link"
+msgstr ""
+"S'ha enviat un correu a la vostra adreça %1$s amb l'enllaç per a activar el "
+"vostre compte d'usuari. Heu de clicar l'enllaç abans que pugueu connectar-"
+"vos al %2$s Add-ons."
+
+#. %1 is the user's email address
+#: views/users/register_complete.thtml:49
+#, php-format
+msgid "user_register_confirm_email_sent"
+msgstr ""
+"S'ha enviat un correu a la vostra adreça %1$s per a confirmar el vostre "
+"compte. Abans que pugueu connectar-vos, heu d'activar el compte clicant "
+"l'enllaç següent. "
+
+#: views/users/activatefirst.thtml:51
+msgid "user_register_confirmation_link_text"
+msgstr "Torna a enviar el missatge de confirmació"
+
+#: views/users/register_complete.thtml:47
+msgid "user_register_congratulations"
+msgstr "Felicitats! El vostre compte d'usuari s'ha creat satisfactòriament."
+
+#: views/users/register.thtml:50
+msgid "user_register_details"
+msgstr ""
+"<p><strong>No cal que us registreu</strong> a l'AMO si tan sols voleu baixar "
+"i instal·lar-vos complements públics.</p><p>Només cal que us registreu si:</"
+"p><ul><li>Voleu publicar comentaris dels complements</li><li>Sou un "
+"desenvolupador de complements i voleu fer-los públics utilitzant l'AMO</li></"
+"ul><p>Després que us hàgiu registrat correctament, se us enviarà una "
+"confirmació a l'adreça electrònica que hàgiu indicat. Seguiu les "
+"instruccions per a crear el vostre compte.</p><p>Si ho desitgeu podeu llegir "
+"les nostres <a href='%1$s' title='Notes legals'>Notes legals</a> i la <a "
+"href='%2$s' title='Política de privacitat'> Política de privacitat</a>.</p>"
+
+#. %1 is the link to the "resend confirmation code" page
+#: views/users/activatefirst.thtml:51
+#, php-format
+msgid "user_register_resend_confirmation_link"
+msgstr ""
+"Si nou heu rebut el correu de confirmació, assegureu-vos que el vostre "
+"gestor de correu no l'ha marcat com a «correu brossa» o «spam». Si ho "
+"necessiteu, podeu sol·licitar-nos-ho, %1$s, a la vostra adreça de correu "
+"descrita anteriorment. "
+
+#. %1 is the link to the Mozilla Add-ons front page
+#: views/users/register_complete.thtml:51
+#, php-format
+msgid "user_register_welcome"
+msgstr "Gràcies per registrar-vos i benvingut al %1$s!"
+
+#: views/users/register.thtml:49
+msgid "user_register_welcome_header"
+msgstr "Benvingut a addons.mozilla.org (AMO)!"
+
+#: views/users/register.thtml:81 views/users/edit.thtml:106
+msgid "user_required_firstlast_or_nickname"
+msgstr "Cal informar del nom, del cognom o bé de l'àlies"
+
+#: views/users/edit.thtml:94 views/users/edit.thtml:142
+msgid "user_tab_collections"
+msgstr "Col·leccions"
+
+#: views/users/edit.thtml:95 views/users/edit.thtml:154
+msgid "user_tab_notifications"
+msgstr "Notificacions"
+
+#: views/users/edit.thtml:93 views/users/edit.thtml:101
+msgid "user_tab_profile"
+msgstr "El perfil de l'usuari."
+
+#: controllers/users_controller.php:209
+msgid "user_verified_okay"
+msgstr "S'ha verificat satisfactòriament!"
+
+#: controllers/users_controller.php:723
+msgid "users_delete_pagetitle"
+msgstr "Supressió del compte d'usuari"
+
+#: controllers/users_controller.php:414
+msgid "users_edit_pagetitle"
+msgstr "Edició del compte d'usuari"
+
+#: views/users/info.thtml:71
+msgid "users_info_aboutme"
+msgstr "Sobre mi"
+
+#: views/users/info.thtml:96
+#, php-format
+msgid "users_info_addons_by_user"
+msgstr "Complements d'en/na %1$s"
+
+#: views/users/info.thtml:51
+msgid "users_info_author_name"
+msgstr "Nom"
+
+#: views/users/info.thtml:48
+msgid "users_info_author_profile"
+msgstr "Perfil d'usuari"
+
+#. %s is the user name
+#: views/users/info.thtml:137
+msgid "users_info_collections_by_user"
+msgstr "Col·leccions de l'usuari %s"
+
+#: views/users/info.thtml:66
+msgid "users_info_email"
+msgstr "Adreça de correu"
+
+#: views/users/info.thtml:155
+msgid "users_info_fav_collections_by_user"
+msgstr "Col·leccions preferides"
+
+#: views/users/info.thtml:61
+msgid "users_info_homepage"
+msgstr "Pàgina d'inici"
+
+#: views/users/info.thtml:56
+msgid "users_info_nickname"
+msgstr "Àlies"
+
+#: controllers/users_controller.php:707
+#, php-format
+msgid "users_info_pagetitle"
+msgstr "Informació de l'usauri %1$s"
+
+#. %1 is the user's name
+#: views/users/info.thtml:116
+msgid "users_info_reviews_by_user"
+msgstr "Revisats per %s"
+
+#: controllers/users_controller.php:330 controllers/users_controller.php:332
+msgid "users_login_pagetitle"
+msgstr "Inici de sessió"
+
+#. %1 is the link to the sandbox/policy explanation page
+#. This message is for a specific add-on not found
+#: views/users/login.thtml:53
+#, php-format
+msgid "users_login_sandbox_display_warning"
+msgstr ""
+"El complement que esteu cercant està actualment en l'entorn de proves. Si ja "
+"teniu un compte del Mozilla Add-ons, connecteu-vos, o bé <a href=\"%1$s"
+"\">coneixeu més coses de l'entorn de proves</a>"
+
+#. %1 is the link to the sandbox/policy explanation page
+#. This message is for any given sandbox-related page not found
+#: views/users/login.thtml:56
+#, php-format
+msgid "users_login_sandbox_page_warning"
+msgstr ""
+"El complement que esteu cercant està actualment en l'entorn de proves. Si ja "
+"teniu un compte del Mozilla Add-ons, connecteu-vos, o bé <a href=\"%1$s"
+"\">coneixeu més coses de l'entorn de proves</a>"
+
+#: controllers/users_controller.php:223 controllers/users_controller.php:225
+msgid "users_pwreset_pagetitle"
+msgstr "Recuperació de la contrasenya de l'usuari"
+
+#: controllers/users_controller.php:90 controllers/users_controller.php:92
+msgid "users_register_pagetitle"
+msgstr "Registre d'un nou usuari"
+
+#. %1$s is an addon name, like <a>Firebug</a>
+#. %2$s is a version number, like <a>1.2</a>
+#: views/versions/license.thtml:52
+msgid "versions_license_header_source"
+msgstr "Llicència del codi font del %1$s %2$s"
+
+#: views/addons/category_landing.thtml:147
+msgid "view_recently_added"
+msgstr "Mostra tots els que s'han afegit recentment"
+
+#: views/addons/category_landing.thtml:161
+msgid "view_top_downloads"
+msgstr "Mostra tots els més baixats"
+
+#: views/addons/category_landing.thtml:175
+msgid "view_top_rated"
+msgstr "Mostra tots els més ben valorats"
+
+#~ msgid "addon_slider_tooltip_next"
+#~ msgstr "Complement següent "
+
+#~ msgid "addon_slider_tooltip_previous"
+#~ msgstr "Complement anterior"
+
+#~ msgid "addon_versions_getlatesttext"
+#~ msgstr "La versió més nova compatible amb"
+
+#~ msgid "addons_display_version_history"
+#~ msgstr "Historial de versions complet"
+
+#~ msgid "addons_home_newest_header"
+#~ msgstr "El més nou:"
+
+#~ msgid "addons_home_popular_header"
+#~ msgstr "Els més famosos:"
+
+#~ msgid "addons_home_recommended_header"
+#~ msgstr "Recomanem:"
+
+#~ msgid "addons_home_updated_header"
+#~ msgstr "Actualitzat fa poc:"
+
+#~ msgid "addons_home_view_all"
+#~ msgstr "Mostra'ls tots"
+
+#~ msgid "category_extra_allrecommended"
+#~ msgstr "Mostra tots els complements recomanats"
+
+#~ msgid "category_extra_highestrated"
+#~ msgstr "Mostra el més ben valorat primer"
+
+#~ msgid "category_extra_lastupdated"
+#~ msgstr "Mostra el més nou primer"
+
+#~ msgid "category_extra_mostpopular"
+#~ msgstr "El més famós primer"
+
+#~ msgid "collections_detail_js_loading"
+#~ msgstr "Loading"
+
+#~ msgid "collections_detail_more_info"
+#~ msgstr "Show More Info"
+
+#~ msgid "devcp_additem_firefox_notice"
+#~ msgstr ""
+#~ "Aquesta versió del vostre complement diu que no és compatible amb el "
+#~ "Firefox %1$s. Mozilla preveu que la propera versió del Firefox sortirà "
+#~ "aviat, per tant proveu el vostre complement amb la nova versió i "
+#~ "actualitzeu la informació de compatibilitat. Sobre tot això també se'n "
+#~ "parla <a href=\"%2$s\">aquí</a>. Això només és un avís i podeu continuar "
+#~ "amb l'enviament d'aquesta versió a l'addons.mozilla.org."
+
+#~ msgid "devcp_addon_disabled_successfully"
+#~ msgstr "S'ha deshabilitat el complement correctament"
+
+#~ msgid "devcp_addon_edit_pagetitle"
+#~ msgstr "Edita el complement"
+
+#~ msgid "devcp_addon_enabled_successfully"
+#~ msgstr "S'ha habilitat el complement correctament"
+
+#~ msgid "devcp_addon_field_description_displaytitle"
+#~ msgstr "Descripció del complement"
+
+#~ msgid "devcp_addon_field_eula_displaytitle"
+#~ msgstr "ALUF (EULA)"
+
+#~ msgid "devcp_addon_field_homepage_displaytitle"
+#~ msgstr "Pàgina web del complement"
+
+#~ msgid "devcp_addon_field_name_displaytitle"
+#~ msgstr "Nom del complement"
+
+#~ msgid "devcp_addon_field_privacy_displaytitle"
+#~ msgstr "Política de privadesa"
+
+#~ msgid "devcp_addon_field_summary_displaytitle"
+#~ msgstr "Resum del complement"
+
+#~ msgid "devcp_addon_field_supportemail_displaytitle"
+#~ msgstr "Correu per a problemes"
+
+#~ msgid "devcp_addon_field_supporturl_displaytitle"
+#~ msgstr "URL per a problemes"
+
+#~ msgid "devcp_addon_field_versionnotes_displaytitle"
+#~ msgstr "Notes de la versió"
+
+#~ msgid "devcp_addon_nominate_pagetitle"
+#~ msgstr "Nomina el complement"
+
+#~ msgid "devcp_addon_nominated_successfully"
+#~ msgstr "S'ha nominat el complement correctament"
+
+#~ msgid "devcp_addon_status_criteria_review"
+#~ msgstr ""
+#~ "Fan falta revisions de diversos usuaris (poden ser revisions externes)."
+
+#~ msgid "devcp_addon_submission_makechanges"
+#~ msgstr ""
+#~ "Visiteu la pàgina del %1$s per a fer canvis a la vostra publicació, o bé "
+#~ "a %2$s per a tornar al tauler de control del desenvolupador."
+
+#~ msgid "devcp_addon_submission_makechanges_devcp_link"
+#~ msgstr "Cliqueu ací"
+
+#~ msgid "devcp_addon_submission_makechanges_link"
+#~ msgstr "Edita el complement"
+
+#~ msgid "devcp_addon_submission_pending"
+#~ msgstr ""
+#~ "La versió s'ha posat en l'entorn de proves mentre s'espera que la provi "
+#~ "algun provador i un editor de complements de Mozilla. Rebreu un correu "
+#~ "electrònic quan s'hagi decidit alguna cosa."
+
+#~ msgid "devcp_addon_submission_sandbox_readmore"
+#~ msgstr ""
+#~ "Trobareu més informació sobre el sistema de revisió i l'entorn de proves "
+#~ "a %s."
+
+#~ msgid "devcp_addon_submission_sandbox_readmore_link"
+#~ msgstr "ací"
+
+#~ msgid "devcp_addon_submission_sandboxed"
+#~ msgstr ""
+#~ "Aquesta versió s'ha posat en l'entorn de proves perquè la puguin "
+#~ "utilitzar els usuaris experimentats. Per tal de mostrar-la en el lloc web "
+#~ "públic, cal que la nomineu, %1, i que «segueixi un procés de revisió»."
+
+#~ msgid "devcp_addon_submission_sandboxed_nominate_link"
+#~ msgstr "nomina"
+
+#~ msgid "devcp_addon_submission_success"
+#~ msgstr ""
+#~ "La publicació del vostre complement s'ha completat satisfactòriament."
+
+#~ msgid "devcp_addon_submission_trusted_public"
+#~ msgstr ""
+#~ "Ja que el vostre complement és de confiança, aquesta versió s'ha aprovat "
+#~ "automàticament per anar a l'àrea pública."
+
+#~ msgid "devcp_addon_submit_pagetitle"
+#~ msgstr "Envia el complement"
+
+#~ msgid "devcp_addon_updated_successfully"
+#~ msgstr "El complement s'ha actualitzat satisfactòriament"
+
+#~ msgid "devcp_addon_upload_preview"
+#~ msgstr ""
+#~ "Segurament voleu que %s incrementi el seu interès amb el vostre "
+#~ "complement."
+
+#~ msgid "devcp_addon_upload_preview_link"
+#~ msgstr "Envia una previsualització"
+
+#~ msgid "devcp_author_lookup_none_found"
+#~ msgstr "No s'ha trobat cap autor [%s]"
+
+#~ msgid "devcp_author_lookup_remove"
+#~ msgstr "Esborra"
+
+#~ msgid "devcp_button_cancel"
+#~ msgstr "Cancel·a"
+
+#~ msgid "devcp_button_cancel_confirm"
+#~ msgstr "Esteu segur que voleu cancel·lar la vostra publicació?"
+
+#~ msgid "devcp_change_addontype"
+#~ msgstr "Canvia el tipus de complement:"
+
+#~ msgid "devcp_comments_updated"
+#~ msgstr "S'ha actualitzat els comentaris del desenvolupador."
+
+#~ msgid "devcp_details_addpreview_link"
+#~ msgstr "Afegeix una previsualització"
+
+#~ msgid "devcp_details_authors"
+#~ msgstr "Autors"
+
+#~ msgid "devcp_details_authors_none"
+#~ msgstr "Cap"
+
+#~ msgid "devcp_details_categories"
+#~ msgstr "Categories"
+
+#~ msgid "devcp_details_category"
+#~ msgstr "Categoria"
+
+#~ msgid "devcp_details_description"
+#~ msgstr "Descripció"
+
+#~ msgid "devcp_details_disabled"
+#~ msgstr "Deshabilitat"
+
+#~ msgid "devcp_details_guid"
+#~ msgstr "GUID"
+
+#~ msgid "devcp_details_header_details"
+#~ msgstr "Detalls"
+
+#~ msgid "devcp_details_header_devcomments"
+#~ msgstr "Comentaris del desenvolupador"
+
+#~ msgid "devcp_details_header_previews"
+#~ msgstr "Previsualitza"
+
+#~ msgid "devcp_details_header_versions"
+#~ msgstr "Versió"
+
+#~ msgid "devcp_details_homepage"
+#~ msgstr "Pàgina d'inici"
+
+#~ msgid "devcp_details_homepage_none"
+#~ msgstr "Cap"
+
+#~ msgid "devcp_details_preview_nocaption"
+#~ msgstr "Sense nom"
+
+#~ msgid "devcp_details_previews_nonefound"
+#~ msgstr "No s'han trobat cap previsualització."
+
+#~ msgid "devcp_details_submit_update"
+#~ msgstr "Actualitza"
+
+#~ msgid "devcp_details_supportemail"
+#~ msgstr "Correu per a problemes"
+
+#~ msgid "devcp_details_supportemail_none"
+#~ msgstr "El desenvolupador no ha donat cap adreça de correu per a problemes."
+
+#~ msgid "devcp_details_supporturl"
+#~ msgstr "URL per a problemes"
+
+#~ msgid "devcp_details_supporturl_none"
+#~ msgstr "El desenvolupador no ha donat cap URL per a problemes."
+
+#~ msgid "devcp_details_trusted"
+#~ msgstr "De confiança"
+
+#~ msgid "devcp_details_versions_none_found"
+#~ msgstr "No s'han trobat versions."
+
+#~ msgid "devcp_disable_disable_button"
+#~ msgstr "Sí, deshabilita'l"
+
+#~ msgid "devcp_disable_disable_confirm"
+#~ msgstr "Esteu segur que voleu deshabilitar aquest complement?"
+
+#~ msgid "devcp_disable_disable_description"
+#~ msgstr ""
+#~ "Si deshabiliteu aquest complement no es mostrarà en cap cerca ni cap "
+#~ "llistat. No es podrà baixar del web ni s'enviaran actualitzacions als "
+#~ "clients. El complement s'esborrarà, tot i que podreu tornar aquí i tornar-"
+#~ "lo a habilitar si voleu."
+
+#~ msgid "devcp_disable_disable_title"
+#~ msgstr "Deshabilita %s"
+
+#~ msgid "devcp_disable_enable_button"
+#~ msgstr "Sí, habilita'l"
+
+#~ msgid "devcp_disable_enable_confirm"
+#~ msgstr "Esteu segur que voleu habilitar aquest complement?"
+
+#~ msgid "devcp_disable_enable_description"
+#~ msgstr ""
+#~ "Si habiliteu aquest complement de nou tornarà a aparèixer en les cerques "
+#~ "i llistats. I es podrà baixar tant des de la pàgina web com des del "
+#~ "client d'actualitzacions."
+
+#~ msgid "devcp_disable_enable_title"
+#~ msgstr "Habilita %s"
+
+#~ msgid "devcp_edit_author_add"
+#~ msgstr "Afegeix un autor"
+
+#~ msgid "devcp_edit_author_email"
+#~ msgstr "Adreça de correu de l'autor"
+
+#~ msgid "devcp_edit_error_categories_unavailable"
+#~ msgstr "No hi ha cap categoria per a aquest tipus de complement."
+
+#~ msgid "devcp_edit_file_error_incomplete"
+#~ msgstr "Transferència incompleta"
+
+#~ msgid "devcp_edit_file_error_no"
+#~ msgstr "No s'ha pujat cap fitxer"
+
+#~ msgid "devcp_edit_file_error_size"
+#~ msgstr "Supera la mida màxima permesa per a pujar un fitxer"
+
+#~ msgid "devcp_edit_header_authors"
+#~ msgstr "Autors"
+
+#~ msgid "devcp_edit_icon_add_link"
+#~ msgstr "Afegeix una icona"
+
+#~ msgid "devcp_edit_icon_change_link"
+#~ msgstr "Canvia la icona"
+
+#~ msgid "devcp_edit_label_allow_viewsource"
+#~ msgstr "Permet als usuaris veure en línia els fitxers font"
+
+#~ msgid "devcp_edit_label_categories"
+#~ msgstr "Categories"
+
+#~ msgid "devcp_edit_label_defaultlocale"
+#~ msgstr "Localització per defecte"
+
+#~ msgid "devcp_edit_label_icon_delete"
+#~ msgstr "Només esborra la icona existent"
+
+#~ msgid "devcp_edit_label_icon_new"
+#~ msgstr "Nou fitxer d'icona"
+
+#~ msgid "devcp_edit_label_info"
+#~ msgstr "Icona"
+
+#~ msgid "devcp_edit_locale_disambiguation_explanation"
+#~ msgstr "més informació breu (com el dialecte)"
+
+#~ msgid "devcp_edit_submit_update"
+#~ msgstr "Actualitza"
+
+#~ msgid "devcp_edit_target_locale_explanation"
+#~ msgstr ""
+#~ "<a href=\"http://wiki.mozilla.org/L10n:Simple_locale_names"
+#~ "\">identificador de l'idioma </a>, com per exemple 'en-US'"
+
+#~ msgid "devcp_editversion_checkedfiles_delete"
+#~ msgstr "Els fitxers marcats se suprimiran."
+
+#~ msgid "devcp_editversion_filename_size"
+#~ msgstr "%1$s (%2$s)"
+
+#~ msgid "devcp_editversion_label_files"
+#~ msgstr "Fitxers"
+
+#~ msgid "devcp_editversion_label_targetapps"
+#~ msgstr "Aplicacions destinació"
+
+#~ msgid "devcp_editversion_nofiles"
+#~ msgstr "No hi ha fitxers."
+
+#~ msgid "devcp_editversion_submit_update"
+#~ msgstr "Actualitza"
+
+#~ msgid "devcp_error_addon_field_summary_toolong"
+#~ msgstr ""
+#~ "Els resums estan limitats a un màxim de 250 caràcters.\n"
+#~ "(N'heu escrit %s)"
+
+#~ msgid "devcp_error_addonname_not_unique"
+#~ msgstr ""
+#~ "El nom del vostre complement ja existeix a la base de dades. Assegureu-"
+#~ "vos de què: <br /><li>El vostre GUID sigui correcte. La causa més comuna "
+#~ "d'aquest error és un GUID incorrecte.</li><li>No tingueu un registre "
+#~ "duplicat a la base de dades. Si és així, haureu d'actualitzar el registre "
+#~ "o esborrar-lo i tornar-ho a intentar.</li>"
+
+#~ msgid "devcp_error_describe_changes"
+#~ msgstr ""
+#~ "Descriviu els canvis que heu fet en aquesta actualització del complement."
+
+#~ msgid "devcp_error_file_guids_dont_match"
+#~ msgstr "No tots els GUID dels fitxers són correctes"
+
+#~ msgid "devcp_error_identical_version_exists"
+#~ msgstr ""
+#~ "Ja existeix una versió idèntica (%s) per a aquest complement i plataforma."
+
+#~ msgid "devcp_error_nominate_message"
+#~ msgstr "Heu de proporcionar els detalls necessaris per a la nominació."
+
+#~ msgid "devcp_error_nominate_no_prerelease"
+#~ msgstr "No podeu nominar una versió candidata d'un complement."
+
+#~ msgid "devcp_error_nominate_sandbox_only"
+#~ msgstr ""
+#~ "Només podeu nominar complements que actualment estiguin en l'entorn de "
+#~ "proves."
+
+#~ msgid "devcp_error_saving"
+#~ msgstr "S'ha produït un error mentre s'intentava desar les vostres dades."
+
+#~ msgid "devcp_error_update_access_denied"
+#~ msgstr "No teniu permisos per actualitzar aquest complement."
+
+#~ msgid "devcp_file_addanother"
+#~ msgstr "Afegeix un altre fitxer de plataforma"
+
+#~ msgid "devcp_form_author_add"
+#~ msgstr "Afegeix un autor"
+
+#~ msgid "devcp_form_author_remove"
+#~ msgstr "Esborra"
+
+#~ msgid "devcp_form_categories_nextstep"
+#~ msgstr ""
+#~ "Les categories per al vostre nou tipus de complement les tindreu "
+#~ "disponibles en el pròxim pas."
+
+#~ msgid "devcp_form_error_categories_unavailable"
+#~ msgstr "No hi ha cap categoria disponible per a aquest tipus de complement."
+
+#~ msgid "devcp_form_error_description_notempty"
+#~ msgstr "Escriviu una descripció del vostre complement."
+
+#~ msgid "devcp_form_error_name_required"
+#~ msgstr "Escriviu el nom del vostre complement."
+
+#~ msgid "devcp_form_error_select_addontype"
+#~ msgstr "Escriviu el tipus del complement que esteu publicat."
+
+#~ msgid "devcp_form_error_summary_notempty"
+#~ msgstr "Escriviu un resum del vostre complement."
+
+#~ msgid "devcp_form_label_addonfile"
+#~ msgstr "Fitxer del complement"
+
+#~ msgid "devcp_form_label_addonfile2"
+#~ msgstr "Fitxer 2 del complement"
+
+#~ msgid "devcp_form_label_addonfile3"
+#~ msgstr "Fitxer 3 del complement"
+
+#~ msgid "devcp_form_label_addontype"
+#~ msgstr "Tipus de complement"
+
+#~ msgid "devcp_form_label_allow_viewsource"
+#~ msgstr "Permet als usuaris consultar en línia els fitxers font"
+
+#~ msgid "devcp_form_label_author_email"
+#~ msgstr "Adreça de correu de l'autor"
+
+#~ msgid "devcp_form_label_authors"
+#~ msgstr "Autors"
+
+#~ msgid "devcp_form_label_categories"
+#~ msgstr "Categories"
+
+#~ msgid "devcp_form_label_defaultlocale"
+#~ msgstr "Localització per defecte"
+
+#~ msgid "devcp_form_label_eula"
+#~ msgstr "Acord de la llicència d'usuari final (EULA)"
+
+#~ msgid "devcp_form_label_externalsoftware"
+#~ msgstr "Aquest complement necessita programari extern"
+
+#~ msgid "devcp_form_label_files"
+#~ msgstr "Fitxers"
+
+#~ msgid "devcp_form_label_homepage"
+#~ msgstr "Pàgina web"
+
+#~ msgid "devcp_form_label_iconfile"
+#~ msgstr "Fitxer d'icona"
+
+#~ msgid "devcp_form_label_name"
+#~ msgstr "Nom"
+
+#~ msgid "devcp_form_label_platforms"
+#~ msgstr "Plataformes disponibles"
+
+#~ msgid "devcp_form_label_prerelease"
+#~ msgstr "Aquesta és una versió candidata"
+
+#~ msgid "devcp_form_label_privacy"
+#~ msgstr "Política de privadesa"
+
+#~ msgid "devcp_form_label_sitespecific"
+#~ msgstr "Aquest és un complement específic d'un web"
+
+#~ msgid "devcp_form_label_summary"
+#~ msgstr "Resum"
+
+#~ msgid "devcp_form_label_supportemail"
+#~ msgstr "Correu per a problemes"
+
+#~ msgid "devcp_form_label_supporturl"
+#~ msgstr "URL per a problemes"
+
+#~ msgid "devcp_form_label_target_applications"
+#~ msgstr "Aplicacions destinació"
+
+#~ msgid "devcp_form_label_version"
+#~ msgstr "Versió"
+
+#~ msgid "devcp_form_label_versionnotes"
+#~ msgstr "Notes de la versió"
+
+#~ msgid "devcp_form_no_target_apps"
+#~ msgstr "Cap"
+
+#~ msgid "devcp_form_reviewernotes"
+#~ msgstr "Notes del revisor"
+
+#~ msgid "devcp_form_trustedaddon_destination"
+#~ msgstr ""
+#~ "Perquè el vostre complement és de confiança, trieu on voleu que vagi "
+#~ "aquesta versió:"
+
+#~ msgid "devcp_form_trustedaddon_destination_public"
+#~ msgstr "Públic"
+
+#~ msgid "devcp_form_trustedaddon_destination_sandbox"
+#~ msgstr "Entorn de proves"
+
+#~ msgid "devcp_header_developer_agreement"
+#~ msgstr "Acord del desenvolupador"
+
+#~ msgid "devcp_header_step1"
+#~ msgstr "1r pas"
+
+#~ msgid "devcp_header_step1_upload"
+#~ msgstr "Enviament del fitxer"
+
+#~ msgid "devcp_header_step2"
+#~ msgstr "2n pas"
+
+#~ msgid "devcp_header_step2_addondetails"
+#~ msgstr "Detalls del complement"
+
+#~ msgid "devcp_header_step3"
+#~ msgstr "3r pas"
+
+#~ msgid "devcp_header_step3_versiondetails"
+#~ msgstr "Detalls de la versió"
+
+#~ msgid "devcp_header_step4"
+#~ msgstr "4t pas"
+
+#~ msgid "devcp_header_step4_localization"
+#~ msgstr "Localització"
+
+#~ msgid "devcp_header_step5"
+#~ msgstr "5è pas"
+
+#~ msgid "devcp_header_step5_success"
+#~ msgstr "Fi"
+
+#~ msgid "devcp_index_header_myaddons"
+#~ msgstr "Els meus complements"
+
+#~ msgid "devcp_nominate_link_returnto_details"
+#~ msgstr "Torna als detalls del complement"
+
+#~ msgid "devcp_notice_autodetected_addontype"
+#~ msgstr "Detecta automàticament el tipus de complement: %s"
+
+#~ msgid "devcp_notice_different_defaultlocale"
+#~ msgstr ""
+#~ "La localització per defecte d'aquest complement (%1$s [%2$s]) és "
+#~ "diferent de la localització que actualment teniu seleccionada (%3$s [%4"
+#~ "$s]). Els camps següents s'haurien de completar en %1$s."
+
+#~ msgid "devcp_question_addontype_incorrect"
+#~ msgstr "És incorrecta?"
+
+#~ msgid "devcp_question_delete_file"
+#~ msgstr "Esteu segur que voleu suprimir aquest fitxer?"
+
+#~ msgid "devcp_skip_reviewing_addon_info"
+#~ msgstr "Omet l'actualització de la informació del meu complement actual"
+
+#~ msgid "devcp_submissions_disabled"
+#~ msgstr ""
+#~ "Els enviaments de complements estan inhabilitats actualment. Torneu-ho a "
+#~ "comprovar més endavant."
+
+#~ msgid "devcp_submit_accept_dev_agreement"
+#~ msgstr "Ho accepto"
+
+#~ msgid "devcp_submit_decline_dev_agreement"
+#~ msgstr "Ho refuso"
+
+#~ msgid "devcp_summary_admin_disabled"
+#~ msgstr "Un administrador ha inhabilitat el complement."
+
+#~ msgid "devcp_summary_header_disabled"
+#~ msgstr "Inhabilitat"
+
+#~ msgid "devcp_summary_header_trusted"
+#~ msgstr "De confiança"
+
+#~ msgid "devcp_summary_noaddons_submit_one"
+#~ msgstr "No teniu cap complement. Feu clic a %s per a enviar-ne un."
+
+#~ msgid "devcp_summary_noaddons_submit_one_link"
+#~ msgstr "ací"
+
+#~ msgid "devcp_theme_upload_preview"
+#~ msgstr "Assegureu-vos de %s el vostre tema."
+
+#~ msgid "devcp_theme_upload_preview_link"
+#~ msgstr "Envia una previsualització"
+
+#~ msgid "devcp_version_edit_pagetitle"
+#~ msgstr "Edita la versió"
+
+#~ msgid "devcp_version_updated_successfully"
+#~ msgstr "La versió s'ha actualitzat amb èxit."
+
+#~ msgid "editors_submissiontype_new"
+#~ msgstr "Nou"
+
+#~ msgid "editors_submissiontype_updated"
+#~ msgstr "Actualitzat"
+
+#~ msgid "editors_th_addon_age"
+#~ msgstr "Antiguitat del complement"
+
+#~ msgid "editors_th_addontypes"
+#~ msgstr "Tipus de complements"
+
+#~ msgid "editors_th_age"
+#~ msgstr "Edat"
+
+#~ msgid "editors_th_applications"
+#~ msgstr "Aplicacions"
+
+#~ msgid "editors_th_platforms"
+#~ msgstr "Plataformes"
+
+#~ msgid "editors_th_submissiontypes"
+#~ msgstr "Tipus de publicacions"
+
+#~ msgid "error_notice"
+#~ msgstr "Avís"
+
+#~ msgid "forum_save"
+#~ msgstr "Desa"
+
+#~ msgid "home"
+#~ msgstr "home"
+
+#~ msgid "nav_category_plugins"
+#~ msgstr "Connectors"
+
+#~ msgid "page_title_experimental_addons"
+#~ msgstr "Complements experimentals"
+
+#~ msgid "pages_experimental_addons_backbutton"
+#~ msgstr "Torna a la pàgina anterior"
+
+#~ msgid "pagination_page_number_title"
+#~ msgstr "Aquesta és la pàgina %1$s de %2$s"
+
+#~ msgid "search_matching_addons_number"
+#~ msgid_plural "search_matching_addons_number"
+#~ msgstr[0] "%s complement trobat"
+#~ msgstr[1] "%s complements trobats"
+
+#~ msgid "statistics_rss_icon_title"
+#~ msgstr "Canal RSS del resum"
diff --git a/site/app/locale/ca/images/sandbox-review.png b/site/app/locale/ca/images/sandbox-review.png
new file mode 100644
index 0000000..f3866ca
--- /dev/null
+++ b/site/app/locale/ca/images/sandbox-review.png
Binary files differ
diff --git a/site/app/locale/ca/pages/collector_features.thtml b/site/app/locale/ca/pages/collector_features.thtml
new file mode 100644
index 0000000..38b6303
--- /dev/null
+++ b/site/app/locale/ca/pages/collector_features.thtml
@@ -0,0 +1,25 @@
+<p>
+ El Add-on Collector us manté connectat amb els vostres complements i col·leccions preferits de diverses maneres:
+</p>
+
+<dl>
+ <dt>Accediu a les vostres col·leccions preferides des del Firefox</dt>
+ <dd>
+ Les col·leccions que marqueu com a preferides al
+ <a href="%1$s">directori de col·leccions</a> apareixen en una part especial del
+ gestor de complements. Podreu rebre les novetats i veure els continguts de cada col·lecció.
+ </dd>
+ <dt>Compartiu els complements amb el menú de publicacions</dt>
+ <dd>
+ Cada complement que instal·leu es pot compartir fàcilment amb els amics per correu electrònic o el podeu publicar en una de les vostres col·leccions mitjançant el menú de publicacions.
+ </dd>
+ <dt>Rebeu notificacions</dt>
+ <dd>
+ El Collector us alertarà quan una de les vostres col·leccions tingui un nou ítem i el marcarà perquè el pogueu veure més tard.
+ </dd>
+
+ <dt>Publiqueu automàticament en una col·lecció els vostres complements instal·lats</dt>
+ <dd>
+ La funció d'auto-publicació manté la vostra col·lecció sempre actualitzada amb els darrers complements, tot mantenint al dia els vostres amics subscrits.
+ </dd>
+</dl>
diff --git a/site/app/locale/ca/pages/error404.thtml b/site/app/locale/ca/pages/error404.thtml
new file mode 100644
index 0000000..7cd7ccf
--- /dev/null
+++ b/site/app/locale/ca/pages/error404.thtml
@@ -0,0 +1,16 @@
+<h1>Ho sentim, però no s'ha trobat allò que esteu cercant.</h1>
+
+<p>Heu demanat una pàgina o fitxer que no es troba al lloc web. Potser heu fet clic a un enllaç no actualitzat, o heu teclejat incorrectament l'adreça .</p>
+
+<ul>
+<li>Si heu teclejat l'adreça, comproveu que està ben escrita.</li>
+<li>Si heu seguit un enllaç des d'algun lloc, si us plau, feu-nos-ho saber a <a href="mailto:webmaster@mozilla.com" title="Pàgina no trobada a Mozilla.com">webmaster@mozilla.com</a>. Digueu-nos de quina pàgina veniu i que esteu cercant, farem tot el possible per solucionar-ho.</li>
+</ul>
+
+<p>O simplement podeu anar a alguna de les pàgines més populars del lloc web.</p>
+
+<ul>
+<li>Esteu interessat en una <a href="%1$s">llista de complements populars</a>?</li>
+<li>Desitgeu <a href="%2$s">cercar complements</a>? Podeu anar a la <a href="%2$s">pàgina de recerca</a> o simplement usar el camp de recerca de sota.</li>
+<li>Si preferiu anar a l'inici, simplement aneu a la <a href="%3$s">pàgina principal dels complements</a>.</li>
+</ul>
diff --git a/site/app/locale/ca/pages/nomination.thtml b/site/app/locale/ca/pages/nomination.thtml
new file mode 100644
index 0000000..752d184
--- /dev/null
+++ b/site/app/locale/ca/pages/nomination.thtml
@@ -0,0 +1,8 @@
+<p>Un complement que actualment es troba a l'entorn de proves pot ser nomenat per a ser part del lloc públic. Estarà disponible per a tots els usuaris després de passar la revisió d'un editor. Per a aconseguir uns millors resultats, tingueu en compte açò:</p>
+<ul>
+ <li>Calen imatges de mostra per als temes; són molt recomanables també per als altres tipus de complements</li>
+ <li>El complement cal que hagi passat suficient temps a l'entorn de proves perquè pugui haver acumulat prou revisions i opinions dels usuaris</li>
+ <li>Els complements públics han de ser de major qualitat que els de l'entorn de prova; cal que millorin el web</li>
+ <li>Els criteris de plena nominació es troben disponibles a la nostra <a href="%s">Política de complements</a></li>
+</ul>
+<p>Si el vostre complement compleix els criteris anteriors, podeu nomenar-lo clicant al botó de sota. Rebreu una notificació per correu electrònic pel que fa a l'estat de la vostra nominació.</p>
diff --git a/site/app/locale/ca/pages/policy.thtml b/site/app/locale/ca/pages/policy.thtml
new file mode 100644
index 0000000..da1412b
--- /dev/null
+++ b/site/app/locale/ca/pages/policy.thtml
@@ -0,0 +1,110 @@
+<h1>Política de complements</h1>
+
+<h2>Què és un entorn de proves?</h2>
+<p>Vegeu %s.</p>
+
+<h2>Quins complements hi ha l'entorn de proves?</h2>
+<p>L'entorn de proves és on s'hostatgen tots els complements que arriben a l'AMO, per començar. Conté noves versions de complements públics, i també totes les versions dels complements que encara no ho són. Quan s'envia a l'AMO un nou complement o una actualització d'un que ja hi és present, es col·loquen allà.</p>
+
+<p>Alguns complements, i llurs versions específiques, es fan públics després que el procés de revisió indica que estan preparats i són apropiats per a mostrar-los al públic. D'altres, romandran indefinidament en l'entorn de proves, on estaran disponibles a aquells usuaris que triïn navegar per la seua llista i experimentar amb el programari que hi hagi.</p>
+
+<h2>Com es fan públics els complements?</h2>
+
+<p>Els complements els revisen els usuaris de l'AMO que decideixen visualitzar l'entorn de proves i provar els paquets que hi hagi. Les revisions que escriuen els usuaris de l'AMO indicaran si un complement és suficientment útil, ben escrit i polit perquè pugui ser present per als usuaris del Firefox. Aquestes revisions, possiblement juntament amb altres revisions i inspeccions de l'equip de l'AMO, s'utilitzen per a determinar que un complement donat cal que es faci públic, si li cal més treball o si cal polir-lo per a una major visibilitat, o si bé no és adequat per a la promoció en el lloc web de l'AMO fora de l'entorn de proves.</p>
+
+<h2>Com puc aconseguir promocionar el meu complement al públic?</h2>
+
+<p>Si creieu que el vostre complement (i el vostre comportament!) reuneix els criteris per a ser un complement públic, podeu nomenar-lo des del tauler de control del desenvolupador.</p>
+
+<h2>Quins són els criteris per als complements públics?</h2>
+
+<p>Un complement que sigui públic a l'AMO cal que sigui de gran qualitat, i donar als usuaris una experiència millorada en el web. Demanem els punts següents a l'hora de decidir si un complement és apropiat per estar en la part pública de l'AMO:</p>
+
+<h3>Ateneu a les respostes?</h3>
+
+<p>Esperem que els autors que promocionin llurs complements als molts usuaris del Firefox puguin respondre als informes de problemes, mantinguin llur informació de contacte, i actualitzin llurs complements promptament perquè estigui al dia amb les versions del Firefox i els canvis de política de l'AMO . Açò no vol dir que hàgiu de respondre cada resposta que se us faci, o que calgui que arregleu tots els errors; però esperem que respondreu als problemes que sorgeixin d'acord amb llur severitat.</p>
+
+<h3>El complement s'ha descrit de forma clara i acurada?</h3>
+
+<p>És molt important que els usuaris tinguin allò que n'esperen quan provin un nou complement. La vostra descripció cal que proporcioni detalls d'allò que cal que faci el vostre complement, com un usuari hauria de treure'n profit, i que n'hauria d'esperar quan l'instal·li. Es pot enllaçar amb documentació externa si són instruccions detallades, però la descripció adjunta caldria que cobrís els punts bàsics de tal manera que els usuaris sàpiguen de forma segura què n'obtindran.</p>
+
+<p>També és important que mantingueu les notes de versió adequadament a mesura que canvieu i milloreu el vostre complement. Els usuaris haurien de poder veure les novetats del complement que puguin haver provat anteriorment, i estar a l'aguait dels canvis que podrien afectar l'ús actual del complement quan l'actualitzin. (A partir d'ara, els usuaris no veuen les notes de la versió quan se'ls avisa d'una actualització des del navegador, però estem treballant per a corregir-ho. Si manteniu unes bones notes de versió, els vostres usuaris se'n beneficiaran molt abans i després que aqueix treball hagi acabat)</p>
+
+<h3>Hi estan tots els assumptes de seguretat de privadesa especificats clarament?</h3>
+
+<p>Açò recau dins d'una descripció clara i acurada, però és de tal importància que creiem que mereix una menció especial. Molts complements útils i ben escrits manipulen algun tipus de dades de l'usuari, o poden ocasionar perills de seguretat si se'n fa un mal ús; són benvinguts en l'espai públic de l'AMO, però cal que sigui clar per als usuaris quins riscos podrien assumir, i què poden fer a protegir-se'n.</p>
+
+<h3>S'ha comprovat adequadament un complement, i està lliure de defectes obvis o seriosos?</h3>
+
+<p>Quelcom important que mirem en considerar un complement per a l'accés públic és si les revisions de l'entorn de proves indica que n'ha rebut una comprovació detallada, i que no té cap problema seriós o impacte negatiu en el navegador. Si els revisors informen de problemes com ara d'eficiència desmillorada, penjades, problemes freqüents emprant les funcions del complement, inundació de missatges a la consola d'errors; caldria que en prenguéssiu nota, i torna a nomenar el vostre complement després que els hàgiu adreçat tan bé com hàgiu pogut. No esperem que l'optimitzeu perfectament fins que tingui zero erros -- El mateix Firefox contínuament té millores en aquestes àrees -- però sí que volem que us esforceu a minimitzar-los, i respondre clarament als casos on els usuaris se sorprenguin dels errors pendents.</p>
+
+<p>Si el vostre complement s'ha comprovat fora del procés de l'entorn de proves de l'AMO, tant per un grup d'usuaris del servei com per un equip de qualitat propi, cal que ho indiqueu en el vostre missatge de nominació. Açò ens ajuda a determinar quin nivell de comprovació s'ha fet, i pot ajudar a promocionar el vostre complement.</p>
+
+<h3>Tant el complement com el seu autor tracten a l'usuari amb respecte?</h3>
+
+<p>El vostre programari no hauria d'interferir amb l'usuari innecessàriament, intentar enganyar-lo, o ocultar-li cap de les seues activats. Els usuaris (o fins i tot aquells que no ho són) a vegades són maleducats en llurs comentaris, i si bé mirarem de filtrar-los a mesura que ens n'informin, esperem que els autors també evitin de contestar-hi de forma poc educada.</p>
+
+<h3>És el complement útil per a una proporció prou àmplia d'usuaris del Firefox?</h3>
+
+<p>El vostre complement no cal que sigui el proper Greasemonkey o FireBug, però si només és útil per a gent de la vostra empresa o aquells que són part d'una comunitat web petita, podríem pensar que encara no és apropiat de posar-lo davant de tots els usuaris del Firefox.</p>
+
+<p>Continuem cercant formes de millorar l'organització del lloc web per a acomodar millors els complements que són exemplars d'alguna altra forma, però dirigits només a una comunitat petita d'usuaris potencials. Categoritzar correctament i mantenir les metadades del vostre complement us ajudarà a esbrinar com podem presentar aquest tipus de complements a la gent que més probablement se'n podrien beneficiar.</p>
+
+<p>Si el vostre complement simplement proporciona adreces d'interès o altres simples punts d'accés al vostre lloc web, probablement no és apropiat que es faci públic. Com la resta del projecte Mozilla, ens agrada les aplicacions web i els nous serveis web, però els complements del Firefox cal que proporcionin una experiència de navegació millorada per a l'usuari, i no simplement que siguin una forma de promocionar un nou lloc web o un nou servei a través del llistat de l'AMO. Si la descripció del vostre complement és més sobre el servei que no sobre les millores que ofereix a l'experiència de l'usuari, probablement no aneu pel bon camí.</p>
+
+<h3>És el complement lliure de marques o drets d'autor?</h3>
+
+<p>Encara que no vulgueu fer cap mal al titular d'una marca, o d'un treball amb drets d'autor, no podem hostatjar cap complement que pugui infringir-ne. Si no teniu permís per a utilitzar un nom de marca o una imatge, no envieu el vostre complement a l'AMO. Si el vostre complement inclou codi que té drets d'autor d'algú altre, i no teniu cap llicència per a utilitzar-lo, tampoc l'envieu a l'AMO. (Si el titular d'una marca o d'un dret d'autor presenta objeccions a l'ús, molt probablement haurem de considerar la sol·licitud de supressió després d'una revisió per consell, i haurem d'eliminar el complement si s'estima que és legalment necessari. Es tracta d'un procés costós en termes dels recursos del projecte, incloent-hi temps i diners, per això us demanem que sigueu respectuós i no ens causeu cap dificultat innecessària.)</p>
+
+<p>Si no esteu segur del nom del vostre complement, o de l'ús de quelcom a dins, evitarem que s'hi llisti; podeu demanar assistència a amo-editors@mozilla.org. IMPORTANT: Tingueu en compte que aquest grup no pot oferir consell legal, i fins i tot si pensem que el vostre ús és acceptable, podríem tornar a considerar aqueixa decisió si hi ha queixes dels titulars dels drets i en rebre consell legal.</p>
+
+<p>Pel que fa a l'ús de codi font d'altres complements, si l'autor no afirma clarament que es permet utilitzar el codi en el vostre propi treball -- com ara deixant-lo en una llicència de codi obert -- llavors hauríeu d'assumir que no teniu el dret de fer-ho. Podeu contactar-lo per a demanar-ho, però no podem proporcionar-vos cap dret especial simplement perquè hagi estat a l'AMO, o perquè l'autor no respongui a les vostres sol·licituds. (I novament, no podem oferir cap consell legal; només podem com els vostres complements han d'interactuar amb les polítiques d'aquest lloc web.)</p>
+
+<p>Tot açò s'aplica també a les marques de la Fundació Mozilla, incloent-hi «Mozilla», «Firefox», i «Thunderbird». La política de Mozilla pel que fa a l'ús de marques està dissenyada per a la protecció davant de la confusió, i evitar així que les marques es desvirtuïn per una manca de protecció; respecteu la necessitat d'aquesta protecció, i ajudeu-nos a preservar alguns dels béns més valuosos de la Fundació Mozilla.</p>
+
+<h2>Què passa després de nomenar quelcom?</h2>
+
+<p>Una vegada s'hagi nomenat el vostre complement, l'equip d'editors de l'AMO l'avalua d'acord amb els criteris descrits a sobre. Si s'estima que està preparat per a mostrar-lo al públic, s'hi portarà una vegada s'hagi avaluat, i rebreu una notificació per correu electrònic.</p>
+
+<p>Si creiem que el vostre complement no és adequat per a posar-lo a la part pública de l'AMO en aquests moments, rebreu una notificació de correu electrònic indicant-ho, i se suprimirà la vostra nominació de la cua. Quan creieu que hàgiu esmenat les inquietuds que s'expressen en la nominació, i vulgueu que es torni avaluar, podeu fer-ho a la vostra discreció. Les nominacions repetitives sense cap millora significant no es consideraran positivament; és més probable que així ens enfadeu que no ens esgoteu.</p>
+
+<h2>Puc nomenar el complement d'algú altre?</h2>
+
+<p>Actualment demanem que els autors dels complements nomenin llur propi treball per a la publicació. Volem assegurar-nos que l'autor se senti còmode amb una major exposició i que cregui que el complement en el seu estat actual reflecteix adequadament la qualitat del seu treball. Si creieu que un complement està cuidat, que l'autor compleix la lletra i l'esperit de les polítiques de l'AMO, i que això beneficiaria el Firefox, els nostres usuaris, i la web en general fent-lo disponible a gairebé un centenar de milions d'usuaris d'arreu del món, no dubteu a animar l'autor perquè nomeni la seua creació.</p>
+
+<h2>El meu complement ha estat en la cua de nominació durant molt de temps, que m'odieu?</h2>
+
+<p>No us odiem. De fet, estimem als desenvolupadors de complements, i treballem dur per a fer-los feliços i productius, per tal que els usuaris d'arreu del món puguin beneficiar-se de llur treball. Estar a la part pública de l'AMO té valor precisament perquè tenim cura d'allò que hi arriba, i per tant no podem precipitar-nos a fer-ho més ràpid. Sabem que pot ser frustrant esperar l'avaluació del vostre complement, i volem que aquesta espera sigui el més curta possible. Com més gent aporti revisions clares i acurades dels complements de l'entorn de proves, més senzill és fer aquestes avaluacions; per això, podríeu considerar ajudar-nos en la tasca si ho desitgeu.</p>
+
+<h2>He trobat un error seriós en el meu complement, i voldria tenir-ho reparat allà ràpidament. Què caldria que fes?</h2>
+
+<p>Si hi ha un error seriós (seguretat, estabilitat, problema de funcionalitat greu) en un complement del qual necessiteu una actualització ràpidament, hauríeu d'indicar-ho en les «notes de revisió» quan trameteu l'actualització -- i òbviament també en les notes de la versió! També podríeu voler demanar a alguns dels usuaris del vostre complement que provin l'actualització i informin de llurs resultats en detall a l'entorn de proves. Deixar-se caure a #addons on irc.mozilla.org pot ajudar a fer conèixer la situació a la gent, però sigueu pacient i educat en fer-ho.</p>
+
+<p>No crideu al llop. Mirem de tractar ràpidament les actualitzacions de major prioritat; però també ens implica temps avaluar altres complements nomenats o versions, i sovint a expenses de temps de son o dedicat a les nostres famílies o amics. Per això, no veurem bé aquella gent que intenti treure profit d'aquest mecanisme per a pujar-se a la cua. Si no esteu segur si heu de seguir aquest camí, si ho demaneu a #addons a irc.mozilla.org pot ajudar-vos a decidir.
+
+<h2>Crec que no se m'ha tractat justament en l'avaluació del complement. Què hauria de fer?</h2>
+
+<p>Si creieu que el vostre complement s'ha avaluat incorrectament i que si li ha negat l'estat públic per error, hauríeu d'enviar un missatge a amo-editors@mozilla.org amb les vostres raons detallades. Sigueu educat i clar en el missatge, i assegureu-vos d'oferir punts específics de com el complement s'ha jutjat incorrectament.</p>
+
+<p>(Si heu arreglat *totes* les coses llistades com a problemes en el vostre missatge de notificació, no hauríeu d'apel·lar a l'avaluació, sinó que l'hauríeu de tornar a nomenar perquè es considerés al tauler de control del desenvolupador.)</p>
+
+<h2>El meu complement era públic, i ara és a l'entorn de proves. Què ha passat? </h2>
+
+<p>Si un complement ja no compleix els requisits per a estar públic, el tornarem a l'entorn de proves. Aleshores us ho notificarem per correu electrònic indicant-hi les nostres raons, si no és que hi hagin motius legals per a no notificar-vos-ho.</p>
+
+<p>També podria ser que haguéssiu trobat un error en el lloc web, en aquest cas n'hauria d'informar a través del Bugzilla; marqueu com a producte «addons.mozilla.org» i el component «Public Pages» en el vostre informe, incloeu-hi tot els detalls que pugueu.</p>
+
+<h2>El meu complement és public, i a la gent sembla que li agrada. Com puc fer-lo aparèixer a la llista de complements recomanats?</h2>
+
+<p>Si creieu que el vostre complement és un bon exemple del potencial dels complements, que demostra i estén els valors de Mozilla per a un web extensible i controlat per l'usuari i que proporciona una gran experiència per a l'usuari, podeu demanar que es consideri la seua addició a la llista de complements recomanats. Per a fer-ho, cal que envieu un missatge de correu electrònic a amo-editors@mozilla.org explicant les bondats del vostre complement.</p>
+
+<p>El vostre missatge hauria d'incloure <strong>com a mínim</strong> informació dels punts següents:</p>
+<ul>
+<li>com es millora l'experiència dels usuaris</li>
+<li>fins a quin punt el vostre complement és apropiat per a un gran sector dels usuaris del Firefox</li>
+<li>fins a quin punt el vostre complement demostra i/o serveix als valors del projecte Mozilla, en particular pel que fa a posar a l'usuari en control, la protecció de la privadesa i la seguretat, l'accés universal al web, i les dades i estàndards oberts</li>
+<li>fins a quin punt el vostre complement difereix d'altres (en els punts forts i febles)</li>
+<li>quines reaccions heu rebut d'usuaris, revisors, blocaires, astronautes o de les vostres mascotes, tant positives com negatives</li>
+</ul>
+
+<p>Com més completa sigui la informació que proporcioneu en la vostra sol·licitud, de més bon grat l'acceptarem; encara que fins i tot un informe escrit de forma excel·lent i ben exhaustiu no és garantia que impliqui afegir-lo a la llista de recomanats. En darrer terme, la llista ha de ser -- i és -- mantinguda a la discreció de Mozilla, i es prioritza sobre tot l'experiència i la protecció de l'usuari.</p>
diff --git a/site/app/locale/ca/pages/sandbox.thtml b/site/app/locale/ca/pages/sandbox.thtml
new file mode 100644
index 0000000..5ddfc9f
--- /dev/null
+++ b/site/app/locale/ca/pages/sandbox.thtml
@@ -0,0 +1,13 @@
+<h1>Sistema de revisió de l'entorn de proves</h1>
+<h2>Què és l'entorn de proves?</h2>
+<p>L'entorn de proves és un àrea on els usuaris avançats poden provar els complements abans que es revisin per a l'ús general. Per a poder accedir-hi cal que ho habiliteu als paràmetres de configuració del vostre compte. Cal anar amb compte a l'hora d'instal·lar complements de l'entorn de proves, perquè no els ha provat cap editor i podrien fer malbé el vostre ordinador.</p>
+
+<h2>Com puc fer públic el meu complement?</h2>
+<!-- To localize the flowchart image, see http://wiki.mozilla.org/Update:Remora_Sandbox_Flowchart -->
+<div style="text-align: center;">%s</div>
+<ol>
+ <li><b>Envieu el vostre complement des del tauler de control del desenvolupador.</b> Aquest apareixerà immediatament a la zona de l'«entorn de proves» del web Mozilla Add-ons, on els usuaris més experimentats podran provar-lo i aportar-ne opinions. Per a visitar l'entorn de proves, cal que ho habiliteu als paràmetres de configuració del vostre compte.</li>
+ <li><b>Nomeneu el vostre complement perquè sigui públic.</b> Al tauler de control del desenvolupador hi ha un enllaç per a nomenar el vostre complement. En fer-ho, apareixerà a la cua de nominació de l'editor a l'espera de ser revisat.</li>
+ <li><b>Un editor revisa el vostre complement.</b> Un editor de Mozilla Add-ons instal·larà el vostre complement i comprovarà que funcioni. També consultarà les revisions rebudes a l'entorn de proves.</li>
+ <li><b>El vostre complement es fa públic o es reté a l'entorn de proves.</b> L'editor farà públic el vostre complement o bé el retindrà a l'entorn de proves. Si queda a l'entorn de proves, podeu tornar a nomenar-lo una vegada hi hàgiu fet els canvis que s'hi suggereixen. Si es fa públic, les versions futures apareixeran a l'entorn de proves fins que un editor les revisi i les faci públiques. Una vegada que el vostre complement sigui públic, no caldrà que el torneu a nomenar de nou - les versions futures aniran directament a la cua de pendents per revisar.</li>
+</ol>
diff --git a/site/app/locale/ca/pages/submission_help.thtml b/site/app/locale/ca/pages/submission_help.thtml
new file mode 100644
index 0000000..11b38d2
--- /dev/null
+++ b/site/app/locale/ca/pages/submission_help.thtml
@@ -0,0 +1,34 @@
+<h1>Ajuda en la tramesa</h1>
+Els camps necessaris estan <b>en negreta</b>. Els opcionals <i>en cursiva</i>.
+<h2 id="step1">1er pas: Pujada</h2>
+<ul class="submissionHelp">
+ <li><span class="required">Tipus de complement</span> - Per defecte, el tipus de complement es determinarà automàticament a partir del fitxer pujat. No hauríeu de canviar aquest camp.</li>
+ <li><span class="required">Fitxer del complement</span> - El fitxer empaquetat del vostre complement, complet i amb un fitxer install.rdf. Si només funciona en una plataforma específica, seleccionant-la es permetrà que diferents fitxers es pugin de cop.</li>
+ <li><span class="optional">Fitxer d'icona</span> - El fitxer d'icona es mostra al costat del nom del complement a la seua pàgina de visualització i també es mostrarà en el diàleg d'instal·lació del complement. Es redimensionarà automàticament a 32x32 píxels, conservant-ne les proporcions.</li>
+ <li><span class="required">Llengua per defecte</span> - La llengua per defecte d'un complement és la que s'utilitza principalment. Si la seleccionada per un usuari no es troba disponible en el complement, s'utilitzarà llavors la definida per defecte.</li>
+ <li><span class="optional">Omet la revisió de la informació del meu complement actual</span> - Si esteu actualitzant un complement ja existent, apareixerà aquest camp. En marcar-lo, s'anirà directament al pas 3, on podreu introduir-hi la informació específica de la versió.</li>
+</ul>
+<h2 id="step2">2on pas: Detalls del complement</h2>
+<ul class="submissionHelp">
+ <li><span class="required">Nom</span> - Nom del complement en la seua llengua per defecte.</li>
+ <li><span class="required">Autors</span> - Tots els usuaris que tinguin accés a la modificació de detalls del complement, i que es reconeixeran com a autors a la pàgina de visualització.</li>
+ <li><span class="required">Categories</span> - Categories aplicables al complement.</li>
+ <li><span class="optional">Pàgina d'inici</span> - Pàgina d'inici del lloc web en la llengua per defecte.</li>
+ <li><span class="required">Resum</span> - Un breu resum del complement en la seua llengua per defecte. Aquest camp permet un màxim de 250 caràcters, i apareixerà en la pàgina de visualització del complement, com també al resultats de cerca/navegació.</li>
+ <li><span class="required">Descripció</span> - Una descripció del complement en la llengua per defecte. Apareixerà a la pàgina de visualització del complement a sota del resum.</li>
+ <li><span class="optional">ALUF</span> - L'Acord de Llicència d'Usuari Final (EULA en anglès) són els termes que es demana als usuaris que acceptin abans de baixar l'extensió, en la llengua per defecte.</li>
+ <li><span class="optional">Política de privadesa</span> - La política de privadesa del complement, en la llengua per defecte. Les polítiques de privadesa expliquen què es fa amb la informació personal de l'usuari. Hi haurà un enllaç a les polítiques de privadesa al costat del botó d'instal·lació de la pàgina de visualització. Podeu trobar més informació de què cal que s'inclogui en una política de privadesa i si el vostre complement en necessita una a <a href="%s">Política del complement</a>.</li>
+ <li><span class="optional">Permet als usuaris visualitzar el codi font en línia</span> - En marcar aquesta casella, es permetrà als usuaris navegar pel codi font del vostre complement en línia.</li>
+ <li><span class="optional">És una versió provisional</span> - En marcar aquesta casella, s'indica que la versió del complement és provisional o «beta». Les versions provisionals cal que romanguin a l'entorn de proves, i no poden nomenar-se en públic fins que no se'ls hagi tret aquest senyal.</li>
+ <li><span class="optional">És un complement específic d'un lloc web</span> - En marcar aquesta casella, s'indica que el complement és especific d'un únic lloc web, com ara un que n'alteri l'aspecte o el contingut. És un camp útil per als editors i pot servir per a filtrar cerques en un futur.</li>
+ <li><span class="optional">Aquest complement necessita programari extern</span> - En marcar aquesta casella, s'indica que el complement necessita programari extern. És un camp útil per als editors i pot servir per a filtrar cerques en un futur.</li>
+</ul>
+
+<h2 id="step3">3er: Detalls de la versió</h2>
+<ul class="submissionHelp">
+ <li><span class="required optional">Notes de la versió</span> - Un resum de la llista de canvis de la versió. És opcional per a les noves trameses, però obligatori en les actualitzacions.</li>
+ <li><span class="optional">Notes per al revisor</span> - Aquest camp s'utilitza per a facilitar informació als editors que revisaran l'extensió. Els detalls del compte de prova i les notes especials caldria que anessin ací.</li>
+</ul>
+
+<h2 id="step4">4rt pas: Localització</h2>
+Ací és des d'on els camps del complement poden traduir-se a totes les llengües que s'hi accepten. Només cal que feu clic al codi de la llengua per a introduir-hi les traduccions.
diff --git a/site/app/locale/compile-mo.sh b/site/app/locale/compile-mo.sh
new file mode 100755
index 0000000..f9dca74
--- /dev/null
+++ b/site/app/locale/compile-mo.sh
@@ -0,0 +1,19 @@
+#!/bin/bash
+
+# syntax:
+# compile-mo.sh locale-dir/
+
+function usage() {
+ echo "syntax:"
+ echo "compile.sh locale-dir/"
+ exit 1
+}
+
+# check if file and dir are there
+if [[ ($# -ne 1) || (! -d "$1") ]]; then usage; fi
+
+for lang in `find $1 -type f -name "messages.po"`; do
+ dir=`dirname $lang`
+ stem=`basename $lang .po`
+ msgfmt -o ${dir}/${stem}.mo $lang
+done
diff --git a/site/app/locale/cs/LC_MESSAGES/messages.mo b/site/app/locale/cs/LC_MESSAGES/messages.mo
new file mode 100644
index 0000000..c87b5a6
--- /dev/null
+++ b/site/app/locale/cs/LC_MESSAGES/messages.mo
Binary files differ
diff --git a/site/app/locale/cs/LC_MESSAGES/messages.po b/site/app/locale/cs/LC_MESSAGES/messages.po
new file mode 100644
index 0000000..736d2ae
--- /dev/null
+++ b/site/app/locale/cs/LC_MESSAGES/messages.po
@@ -0,0 +1,7285 @@
+# Czech translations for addons.mozilla.org package.
+# This file is distributed under the same license as the addons.mozilla.org package.
+# Copyright (C) 2007-2009 addons.mozilla.org
+# Copyright (C) 2007-2009 Pavel Franc <franc@czilla.cz>
+# Copyright (C) 2008-2009 Pavel CvrÄek <jasnapaka@jasnapaka.com>
+# Copyright (C) 2007 Lukáš Petrovický <petrovicky@czilla.cz>
+msgid ""
+msgstr ""
+"Project-Id-Version: REMORA 0.1\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2009-01-16 11:45-0800\n"
+"PO-Revision-Date: 2009-03-09 23:50+0100\n"
+"Last-Translator: Pavel Franc <franc@czilla.cz>\n"
+"Language-Team: CZilla <info@czilla.cz>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%"
+"10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
+
+#: views/addons/policy.thtml:98
+msgid "a_cancel_installation"
+msgstr "Přerušit instalaci"
+
+#. This is the text that appears on buttons to download add-ons.
+#. %$1s is an optional string that only appears if the add-on is only available for
+#. a certain platform. Examples: (Windows) or (Linux)
+#. Note that the parentheses are included in the string. :(
+#: views/elements/amo2009/install.thtml:126
+#: views/elements/amo2009/install.thtml:227
+#: views/elements/amo2009/install.thtml:257
+#: views/elements/amo2009/install.thtml:300
+#: views/elements/amo2009/install.thtml:312 views/elements/install.thtml:73
+#: views/elements/install.thtml:181 views/elements/install.thtml:205
+#: views/elements/install.thtml:248 views/elements/install.thtml:260
+#: views/addons/plugins.thtml:66 views/addons/plugins.thtml:76
+#: views/addons/plugins.thtml:86 views/addons/plugins.thtml:96
+#: views/addons/plugins.thtml:119
+#, php-format
+msgid "a_download"
+msgstr "Stáhnout doplněk %s"
+
+#: views/addons/policy.thtml:72
+msgid "a_eula_download"
+msgstr "Souhlasím a stahovat"
+
+#: views/addons/policy.thtml:74
+msgid "a_eula_install"
+msgstr "Souhlasím a instalovat"
+
+#: views/elements/header.thtml:76 views/elements/header.thtml:82
+#: views/api/api_addon.thtml:55 views/api/collections_feed.thtml:75
+#: views/sharing_api/addon.thtml:64
+msgid "a_header_public"
+msgstr "Veřejné doplňky"
+
+#: views/elements/header.thtml:58 views/elements/header.thtml:75
+#: views/elements/header.thtml:80 views/api/api_addon.thtml:57
+#: views/api/collections_feed.thtml:77 views/sharing_api/addon.thtml:66
+msgid "a_header_sandbox"
+msgstr "Pískoviště"
+
+#. %s is a date in the _('date') format
+#: views/elements/amo2009/homepage_addon.thtml:115
+#: views/elements/addon_listitem.thtml:122 views/elements/feature.thtml:106
+#: views/addons/display.thtml:104 views/addons/browse_thumbs.thtml:73
+msgid "addon_detail_last_updated"
+msgstr "Aktualizováno dne %s"
+
+#. %s is the version of the add-on. Example: 3.2a1
+#: views/elements/amo2009/addon_version_detail.thtml:51
+#: views/elements/addon_version_detail.thtml:51
+#, php-format
+msgid "addon_display_header_version"
+msgstr "Verze %s"
+
+#: views/addons/browse_thumbs.thtml:80
+msgid "addon_downloads"
+msgstr "stažení"
+
+#: views/addons/display.thtml:147
+msgid "addon_downloads_total"
+msgstr "staženo celkem"
+
+#: views/elements/amo2009/homepage_addon.thtml:106
+#: views/elements/addon_listitem.thtml:115 views/elements/feature.thtml:101
+#: views/addons/category_landing.thtml:157 views/addons/display.thtml:146
+#: views/addons/browse_thumbs.thtml:80
+msgid "addon_downloads_weekly"
+msgstr "staženo týdně"
+
+#. %1 is the add-on count, %2 the category name
+#: views/addons/browse_thumbs.thtml:104 views/addons/browse.thtml:60
+#, php-format
+msgid "addon_list_category_totalcount"
+msgid_plural "addon_list_category_totalcount"
+msgstr[0] "%1$s doplněk v&nbsp;kategorii \"%2$s\""
+msgstr[1] "%1$s doplňky v&nbsp;kategorii \"%2$s\""
+msgstr[2] "%1$s doplňků v&nbsp;kategorii \"%2$s\""
+
+#: views/elements/amo2009/addon_list_options.thtml:103
+#: views/elements/pagination.thtml:67
+#: views/elements/addon_list_options.thtml:94
+msgid "addon_list_perpage"
+msgstr "na stránku"
+
+#: views/elements/amo2009/addon_list_options.thtml:84
+#: views/elements/addon_list_options.thtml:98
+msgid "addon_list_sortby"
+msgstr "Řazení:"
+
+#: views/helpers/addons_html.php:568 views/elements/amo2009/install.thtml:321
+#: views/elements/feature.thtml:89
+msgid "addon_listitem_flag_experimental"
+msgstr "experimentální"
+
+#: views/helpers/addons_html.php:570
+msgid "addon_listitem_flag_recommended"
+msgstr "doporuÄované"
+
+#. %1 is the add-on name, %2 is the platform
+#: views/pages/js_constants.js.thtml:66
+msgid "addon_not_available_for_platform"
+msgstr "Doplněk %1$s není pro %2$s dostupný."
+
+#. %1 is the add-on name
+#: views/addons/policy.thtml:101 views/addons/previews.thtml:60
+#: views/addons/versions.thtml:130 views/reviews/flag.thtml:61
+#: views/reviews/add.thtml:114 views/reviews/display.thtml:216
+#: views/reviews/review_added.thtml:57
+#, php-format
+msgid "addon_review_a_back_to_addon_x"
+msgstr "Zpět na doplněk %1$s…"
+
+#. %1 is the add-on name
+#: views/reviews/flag.thtml:60 views/reviews/add.thtml:113
+#: views/reviews/review_added.thtml:56
+#, php-format
+msgid "addon_review_a_back_to_reviews"
+msgstr "Zpět na recenze…"
+
+#: views/reviews/add.thtml:85
+msgid "addon_review_add_rating_field"
+msgstr "Hodnocení:"
+
+#: views/reviews/add.thtml:102
+msgid "addon_review_add_review_field"
+msgstr "Recenze:"
+
+#: views/reviews/add.thtml:107
+msgid "addon_review_add_submit"
+msgstr "Odeslat recenzi"
+
+#. %s is the name of the add-on
+#: views/reviews/add.thtml:51
+#, php-format
+msgid "addon_review_add_title"
+msgstr "Přidat recenzi doplňku %s"
+
+#: views/reviews/add.thtml:78
+msgid "addon_review_add_title_field"
+msgstr "Název/StruÄný popis:"
+
+#: views/reviews/display.thtml:77 views/reviews/display.thtml:161
+msgid "addon_review_admin_delete"
+msgstr "Smazat"
+
+#: views/reviews/display.thtml:76
+msgid "addon_review_author_reply_link"
+msgstr "Odpovědět"
+
+#: views/reviews/delete.thtml:62
+msgid "addon_review_confirm_delete"
+msgstr "Opravdu chcete smazat tuto recenzi?"
+
+#: views/reviews/delete.thtml:63
+msgid "addon_review_confirm_no"
+msgstr "Ne"
+
+#: views/reviews/delete.thtml:64
+msgid "addon_review_confirm_yes"
+msgstr "Ano"
+
+#: views/reviews/delete.thtml:48
+msgid "addon_review_delete_header"
+msgstr "Smazat recenzi"
+
+#: controllers/reviews_controller.php:449
+msgid "addon_review_deleted_successfully"
+msgstr "Recenze úspěšně smazána."
+
+#. %s is the name of the add-on
+#: views/reviews/add.thtml:51
+#, php-format
+msgid "addon_review_edit_title"
+msgstr "Úprava recenze doplňku %s"
+
+#. %1 is the count of characters entered as notes for the review flag reason.
+#: controllers/reviews_controller.php:539
+msgid "addon_review_flag_error_other_length"
+msgstr ""
+"Problém s&nbsp;nahlášením recenze: Poznámky pro nahlášení recenze jsou "
+"omezeny na 10 až 100 znaků. Délka poznámky byla %1$s."
+
+#. Removing an extra comma
+#: views/reviews/review_added.thtml:53
+msgid "addon_review_in_moderation"
+msgstr "Upozornění: Recenze musí být před zveřejněním schválena redaktorem."
+
+#: views/reviews/add.thtml:57
+msgid "addon_review_in_reply_to"
+msgstr "OdpovÄ›Ä vývojáře:"
+
+#. %1 is the review count, %2 is the nickname or full name of the user.
+#: views/reviews/display.thtml:131
+#, php-format
+msgid "addon_review_others_by_user"
+msgid_plural "addon_review_others_by_user"
+msgstr[0] ""
+"Zobrazit %1$s předchozí recenzi napsanou pro tento doplněk uživatelem %2$s."
+msgstr[1] ""
+"Zobrazit %1$s předchozí recenze napsané pro tento doplněk uživatelem %2$s."
+msgstr[2] ""
+"Zobrazit %1$s předchozích recenzí napsaných pro tento doplněk uživatelem %2"
+"$s."
+
+#. %1 is the add-on name
+#: controllers/reviews_controller.php:201
+#: controllers/reviews_controller.php:250
+#: controllers/reviews_controller.php:345
+#: controllers/reviews_controller.php:424
+#, php-format
+msgid "addon_review_pagetitle"
+msgstr "Recenze doplňku %s"
+
+#. %1 is the user, %2 is the (localized) date
+#: views/reviews/display.thtml:160
+#, php-format
+msgid "addon_review_reply_on_x_by_y"
+msgstr "OdpovÄ›Ä uživatele %1$s dne %2$s"
+
+#: views/reviews/display.thtml:157
+msgid "addon_review_reply_prefix"
+msgstr "OdpovÄ›Ä vývojáře:"
+
+#: views/reviews/review_added.thtml:51
+msgid "addon_review_saved_successfully"
+msgstr "Recenze byla uložena. Děkujeme!"
+
+#: views/addons/display.thtml:354 views/reviews/display.thtml:72
+msgid "addon_reviewed_by_u_on_d"
+msgstr "uživatelem %1$s dne %2$s"
+
+#. %1 is the user, %2 is the (localized) date, %3 is the rating
+#: views/editors/reviews_queue.thtml:57 views/editors/reviews_queue.thtml:68
+#: views/reviews/add.thtml:63 views/reviews/delete.thtml:54
+#, php-format
+msgid "addon_reviewed_on_x_rated_y"
+msgstr "Uživatel %1$s dne %2$s (hodnocení: %3$s)"
+
+#: views/elements/amo2009/addon_version_detail.thtml:52
+#: views/elements/addon_version_detail.thtml:52
+msgid "addon_version_permalink"
+msgstr "Stálý odkaz na tuto verzi"
+
+#. %1 is the current Application name (e.g. Firefox)
+#. %2 is the Application's version number
+#: views/addons/versions.thtml:140
+msgid "addon_versions_getlatestversion"
+msgstr "Nejnovější verze kompatibilní s&nbsp;aplikací %1$s %2$s"
+
+#: views/addons/display.thtml:447
+msgid "addons_author_addons_submit"
+msgstr "Odeslat"
+
+#: views/elements/amo2009/homepage_addon.thtml:100
+#: views/elements/feature.thtml:95
+msgid "addons_author_tooltip"
+msgstr "Zobrazí profil autora"
+
+#. %1 is the name of the Application (eg. Firefox)
+#: controllers/addons_controller.php:1296
+msgid "addons_browse_all_themes_title"
+msgstr "Motivy vzhledu :: Doplňky aplikace %1$s"
+
+#. %s is the name of the category
+#: controllers/addons_controller.php:1016
+#, php-format
+msgid "addons_browse_browse_category"
+msgstr "Procházet %s"
+
+#. %1 is the name of the theme category (eg. Modern)
+#. %2 is the name of the Application (eg. Firefox)
+#: controllers/addons_controller.php:664
+msgid "addons_browse_categories_header_theme"
+msgstr "Motivy vzhledu z&nbsp;kategorie %1$s :: Doplňky aplikace %2$s"
+
+#: views/addons/display.thtml:249
+msgid "addons_display_a_license_what"
+msgstr "Co to je?"
+
+#: views/reviews/display.thtml:222
+msgid "addons_display_add_review"
+msgstr "Přidat recenzi"
+
+#: views/addons/display.thtml:294
+msgid "addons_display_advanced_details"
+msgstr "Další podrobnosti"
+
+#: views/addons/display.thtml:98
+msgid "addons_display_categories"
+msgstr "Kategorie"
+
+#: views/addons/display.thtml:482
+msgid "addons_display_collection_add"
+msgstr "Přidat do sbírky:"
+
+#: views/addons/display.thtml:491
+msgid "addons_display_collection_add_new"
+msgstr "Nová sbírka..."
+
+#: views/addons/display.thtml:487
+msgid "addons_display_collection_add_select_one"
+msgstr "Zvolit sbírku..."
+
+#: views/addons/display.thtml:493
+msgid "addons_display_collection_add_submit"
+msgstr "Publikovat"
+
+#. %1$s is the add-on name
+#. %2$s is the collection name, linked to the collection's page
+#: views/pages/js_constants.js.thtml:103 views/addons/display.thtml:61
+msgid "addons_display_collection_publish_success"
+msgstr "%1$s byl přidán ke sbírce %2$s."
+
+#: views/addons/display.thtml:483
+msgid "addons_display_collection_whatsthis"
+msgstr "Co to je?"
+
+#. %1$s is a number
+#: views/addons/display.thtml:473
+msgid "addons_display_collections_more"
+msgid_plural "addons_display_collections_more"
+msgstr[0] "and %1$s more collection"
+msgstr[1] "a %1$s dalších sbírek"
+
+#: views/addons/display.thtml:403
+msgid "addons_display_detailed_review"
+msgstr "Podrobná recenze"
+
+#: views/reviews/add.thtml:89 views/reviews/add.thtml:90
+msgid "addons_display_dont_like_it"
+msgstr "Nelíbí se mi"
+
+#: views/reviews/display.thtml:220
+msgid "addons_display_edit_review"
+msgstr "Upravit recenzi"
+
+#: views/addons/display.thtml:132
+msgid "addons_display_has_privacy"
+msgstr "Tento doplněk obsahuje zásady ochrany soukromí"
+
+#: views/reviews/add.thtml:87 views/reviews/add.thtml:88
+msgid "addons_display_hate_it"
+msgstr "Nesnáším ho"
+
+#: views/addons/display.thtml:462
+msgid "addons_display_header_collections"
+msgstr "Obdobné sbírky"
+
+#: views/addons/display.thtml:297
+msgid "addons_display_header_developer_comments"
+msgstr "Komentáře vývojářů"
+
+#: views/addons/display.thtml:230
+msgid "addons_display_header_homepage"
+msgstr "Titulní stránka"
+
+#: views/addons/display.thtml:247 views/addons/versions.thtml:110
+msgid "addons_display_header_license"
+msgstr "Licence zdrojového kódu"
+
+#: views/addons/display.thtml:337
+msgid "addons_display_header_reviews"
+msgstr "Recenze"
+
+#: views/addons/display.thtml:261
+msgid "addons_display_header_support"
+msgstr "Podpora"
+
+#: views/reviews/add.thtml:91 views/reviews/add.thtml:92
+msgid "addons_display_like_it"
+msgstr "Líbí se mi"
+
+#: views/addons/display.thtml:210
+msgid "addons_display_long_description"
+msgstr "Popis"
+
+#: views/reviews/add.thtml:95 views/reviews/add.thtml:96
+msgid "addons_display_love_it"
+msgstr "Miluji ho"
+
+#: views/addons/display.thtml:178
+msgid "addons_display_more_images"
+msgstr "Další obrázky"
+
+#: views/addons/display.thtml:465
+msgid "addons_display_nocollections"
+msgstr "Tento doplněk dosud není v žádné sbírce."
+
+#. %1$s is either an author's name or a comma separated list of authors. Using
+#. the list doesn't make sense in the English plural form so we ignore the
+#. variable.
+#: views/addons/display.thtml:436
+msgid "addons_display_other_addons_by"
+msgid_plural "addons_display_other_addons_by"
+msgstr[0] "Další doplňky autora %1$s"
+msgstr[1] "Další doplňky těchto autorů"
+msgstr[2] "Další doplňky těchto autorů"
+
+#. %s is the name of the add-on and the add-on section. Example:
+#. Some Add-on :: Firefox Add-ons
+#. This should not be concatenated in the code and should be fixed.
+#: controllers/addons_controller.php:141 controllers/addons_controller.php:280
+#: controllers/addons_controller.php:1442
+#, php-format
+msgid "addons_display_pagetitle"
+msgstr "Doplněk %s"
+
+#. %s is an email address
+#: views/addons/display.thtml:286
+#, php-format
+msgid "addons_display_paragraph_supportinfoemail"
+msgstr "Podporu tohoto doplňku poskytuje vývojář na e-mailu %s"
+
+#. %$1s is a URL
+#. %$2s is an email address
+#: views/addons/display.thtml:269
+#, php-format
+msgid "addons_display_paragraph_supportinfoemailurl"
+msgstr ""
+"Podporu tohoto doplňku poskytuje vývojář na stránce %1$s nebo na e-mailu %2$s"
+
+#. %s is a URL
+#: views/addons/display.thtml:278
+#, php-format
+msgid "addons_display_paragraph_supportinfourl"
+msgstr "Podporu tohoto doplňku poskytuje vývojář na stránce %s"
+
+#: views/addons/display.thtml:383
+msgid "addons_display_rate_it"
+msgstr "Hodnocení"
+
+#: views/reviews/add.thtml:93 views/reviews/add.thtml:94
+msgid "addons_display_really_like_it"
+msgstr "Velmi se mi líbí"
+
+#: views/addons/display.thtml:410
+msgid "addons_display_review_etiquette"
+msgstr ""
+"Nepřidávejte prosím do recenze hlášení chyb. Jelikož vývojář rozšíření nemá "
+"možnost, jak ze stránek získat vaši e-mailovou adresu, nemá rovněž možnost, "
+"jak vás kontaktovat a vyřešit váš problém."
+
+#. %1 is the review guidelines link
+#: views/addons/display.thtml:417
+msgid "addons_display_review_guidelines_link"
+msgstr "<a href=\"%s\">Pravidla pro přidání recenze</a>"
+
+#. %1 is the support section link
+#: views/addons/display.thtml:414
+msgid "addons_display_review_see_support"
+msgstr ""
+"Informace o&nbsp;asistenci k&nbsp;tomuto doplňku naleznete v&nbsp;<a href=\"%"
+"1$s\">sekci podpora</a>."
+
+#: views/addons/display.thtml:404
+msgid "addons_display_review_submit"
+msgstr "Uložit"
+
+#: views/addons/display.thtml:430
+#, php-format
+msgid "addons_display_see_all_addons"
+msgstr "Zobrazit všechny doplňky z&nbsp;kategorie %1$s"
+
+#. %1 is the number of reviews
+#: views/addons/display.thtml:364
+#, php-format
+msgid "addons_display_see_all_reviews"
+msgstr "Zobrazit všechny recenze (%1$s)"
+
+#: views/addons/display.thtml:219
+msgid "addons_display_see_all_versions"
+msgstr "Zobrazit všechny verze"
+
+#: views/addons/display.thtml:321 views/addons/versions.thtml:117
+msgid "addons_display_view_source"
+msgstr "Zobrazit zdrojový kód"
+
+#: views/addons/display.thtml:324
+msgid "addons_display_view_stats"
+msgstr "Zobrazit statistiku"
+
+#: views/addons/display.thtml:376
+msgid "addons_display_what_do_you_think"
+msgstr "Jak se vám líbí?"
+
+#: views/elements/app_compatibility.thtml:49
+msgid "addons_display_workswith"
+msgstr "Vyžaduje:"
+
+#: views/addons/home.thtml:112
+msgid "addons_home_browse_new"
+msgstr "Právě přidané"
+
+#: views/addons/home.thtml:110
+msgid "addons_home_browse_popular"
+msgstr "Populární"
+
+#: views/addons/home.thtml:108
+msgid "addons_home_browse_recommended"
+msgstr "DoporuÄené"
+
+#: views/addons/home.thtml:127 views/addons/home.thtml:134
+#: views/addons/home.thtml:141 views/addons/home.thtml:148
+msgid "addons_home_browse_subscribe"
+msgstr "Odebírat"
+
+#: views/addons/home.thtml:101
+msgid "addons_home_browse_title"
+msgstr "Procházet doplňky"
+
+#: views/addons/home.thtml:114
+msgid "addons_home_browse_updated"
+msgstr "Aktualizované"
+
+#: views/elements/amo2009/homepage_addon.thtml:100
+#: views/elements/addon_discussionheader.thtml:83
+#: views/elements/addon_listitem.thtml:109 views/elements/feature.thtml:95
+#: views/addons/category_landing.thtml:66 views/addons/policy.thtml:57
+#: views/addons/display.thtml:70 views/addons/home.thtml:178
+msgid "addons_home_by"
+msgstr "od"
+
+#: views/addons/home.thtml:169
+msgid "addons_home_collection_popular_title"
+msgstr "Populární sbírky"
+
+#: views/elements/amo2009/categories.thtml:69 views/addons/home.thtml:160
+msgid "addons_home_collections"
+msgstr "Sbírky"
+
+#. %1$s is the count of addons in a collection
+#: views/elements/amo2009/collection_listing_item.thtml:51
+#: views/addons/home.thtml:185
+msgid "addons_home_collections_addon_count"
+msgid_plural "addons_home_collections_addon_count"
+msgstr[0] "<strong>%1$s</strong> doplněk"
+msgstr[1] "<strong>%1$s</strong> doplňky"
+msgstr[2] "<strong>%1$s</strong> doplňků"
+
+#: views/addons/home.thtml:196
+msgid "addons_home_collections_all"
+msgstr "Zobrazit všechny sbírky"
+
+#: views/addons/home.thtml:162
+msgid "addons_home_collections_intro"
+msgstr ""
+"Sbírky vám umožňují kategorizovat, porovnávat a míchat doplňky. Odebírejte "
+"sbírky vytvořené jinými uživateli nebo si vytvořte vlastní."
+
+#. %1$s is the count of subscribers for a collection
+#: views/elements/amo2009/collection_listing_item.thtml:58
+#: views/collections/detail.thtml:96 views/addons/home.thtml:189
+msgid "addons_home_collections_subscribers"
+msgid_plural "addons_home_collections_subscribers"
+msgstr[0] "<strong>%1$s</strong> odběratel"
+msgstr[1] "<strong>%1$s</strong> odběratelé"
+msgstr[2] "<strong>%1$s</strong> odběratelů"
+
+#: views/addons/searchengines.thtml:54 views/addons/themes_landing.thtml:49
+msgid "addons_home_feature_head"
+msgstr "DoporuÄujeme"
+
+#: controllers/search_controller.php:218 controllers/addons_controller.php:176
+#: controllers/addons_controller.php:428 controllers/addons_controller.php:671
+#: controllers/addons_controller.php:871
+#: controllers/addons_controller.php:1103
+#: controllers/addons_controller.php:1242
+#: controllers/addons_controller.php:1298
+#, php-format
+msgid "addons_home_header_details"
+msgstr ""
+"Doplňky rozšiřují %1$s a umožňují vám lépe personalizovat své prohlížení "
+"webu. Porozhlédněte se kolem a udělejte si %1$s přesně podle sebe."
+
+#. %1$s is the HTML collection name link.
+#: views/elements/amo2009/teaser_collections.thtml:107
+msgid "addons_home_introduction_collection_link"
+msgstr "Líbí se vám? Více doplňků naleznete v %1$s."
+
+#: views/elements/amo2009/teaser_collections.thtml:60
+msgid "addons_home_introduction_extras"
+msgstr ""
+"<strong>Více jak 5000 způsobů</strong>, jak si přizpůsobit a rozšířit "
+"Firefox dle svých potřeb."
+
+#: views/elements/amo2009/teaser_collections.thtml:55
+msgid "addons_home_introduction_header"
+msgstr "Co jsou doplňky?"
+
+#: views/elements/amo2009/teaser_collections.thtml:72
+msgid "addons_home_introduction_install"
+msgstr ""
+"<strong>Snadné na instalaci</strong>. Když budou dostupné aktualizace, "
+"budete upozornění."
+
+#: views/elements/amo2009/teaser_collections.thtml:45
+msgid "addons_home_introduction_name"
+msgstr "Úvod"
+
+#: views/elements/amo2009/teaser_collections.thtml:66
+msgid "addons_home_introduction_themes"
+msgstr ""
+"Lišty, motivy vzhledu a vyhledávací moduly, které vám <strong>pomohou "
+"urychlit provádÄ›ní běžných Äinností.</strong>"
+
+#: views/addons/home.thtml:161
+msgid "addons_home_new_indicator"
+msgstr "NOVÄš!"
+
+#: views/elements/app_chooser.thtml:48 views/layouts/amo2009.thtml:257
+msgid "addons_home_other_applications"
+msgstr "Ostatní aplikace"
+
+#. %1$s is the application the user is browsing. Examples: Thunderbird, Firefox,
+#. Sunbird
+#: views/pages/collector_faq.thtml:49 views/pages/collector_firstrun.thtml:42
+#: views/pages/collector.thtml:46 views/pages/collector_features.thtml:54
+#: controllers/developers_controller.php:87
+#: controllers/compatibility_controller.php:72
+#: controllers/components/simple_acl.php:81 controllers/components/amo.php:607
+#: controllers/statistics_controller.php:60
+#: controllers/statistics_controller.php:240
+#: controllers/previews_controller.php:67 controllers/users_controller.php:90
+#: controllers/users_controller.php:223 controllers/users_controller.php:330
+#: controllers/users_controller.php:414 controllers/users_controller.php:708
+#: controllers/users_controller.php:723 controllers/reviews_controller.php:204
+#: controllers/reviews_controller.php:251
+#: controllers/reviews_controller.php:346
+#: controllers/reviews_controller.php:425
+#: controllers/search_controller.php:185 controllers/search_controller.php:297
+#: controllers/search_controller.php:301 controllers/addons_controller.php:147
+#: controllers/addons_controller.php:280 controllers/addons_controller.php:370
+#: controllers/addons_controller.php:667 controllers/addons_controller.php:874
+#: controllers/addons_controller.php:1019
+#: controllers/addons_controller.php:1034
+#: controllers/addons_controller.php:1101
+#: controllers/addons_controller.php:1121
+#: controllers/addons_controller.php:1240
+#: controllers/addons_controller.php:1357
+#: controllers/addons_controller.php:1364
+#: controllers/addons_controller.php:1442
+#: controllers/addons_controller.php:1477
+#: controllers/addons_controller.php:1538
+#: controllers/addons_controller.php:1543
+#: controllers/editors_controller.php:64 controllers/pages_controller.php:132
+#: controllers/groups_controller.php:65 controllers/groups_controller.php:71
+#: controllers/groups_controller.php:89 controllers/groups_controller.php:111
+#: controllers/collections_controller.php:57
+#: controllers/collections_controller.php:121
+#: controllers/collections_controller.php:205
+#: controllers/collections_controller.php:365
+#: controllers/collections_controller.php:404
+#: controllers/collections_controller.php:466
+#: controllers/collections_controller.php:538
+#: controllers/collections_controller.php:828
+#: controllers/localizers_controller.php:72
+#, php-format
+msgid "addons_home_pagetitle"
+msgstr "Doplňky aplikace %1$s"
+
+#. %1$s is the number of addons downloaded
+#: views/addons/home.thtml:57
+#, php-format
+msgid "addons_home_stats_downloaded"
+msgid_plural "addons_home_stats_downloaded"
+msgstr[0] "<strong>%1$s</strong> <span>stažený doplněk</span>"
+msgstr[1] "<strong>%1$s</strong> <span>stažené doplňky</span>"
+msgstr[2] "<strong>%1$s</strong> <span>stažených doplňků</span>"
+
+#. %1$s is the number of addons in use
+#: views/addons/home.thtml:63
+#, php-format
+msgid "addons_home_stats_inuse"
+msgid_plural "addons_home_stats_inuse"
+msgstr[0] "<strong>%1$s</strong> <span>používaný doplněk</span>"
+msgstr[1] "<strong>%1$s</strong> <span>používané doplňky</span>"
+msgstr[2] "<strong>%1$s</strong> <span>používaných doplňků</span>"
+
+#: views/addons/home.thtml:136
+msgid "addons_home_view_all_newest_title"
+msgstr "Zobrazit všechny nové doplňky"
+
+#: views/addons/home.thtml:129
+msgid "addons_home_view_all_popular_title"
+msgstr "Zobrazit všechny populární doplňky"
+
+#: views/addons/home.thtml:150
+msgid "addons_home_view_all_recommended_title"
+msgstr "Zobrazit vÅ¡echny doporuÄované doplňky"
+
+#: views/addons/home.thtml:143
+msgid "addons_home_view_all_updated_title"
+msgstr "Zobrazit všechny aktualizované doplňky"
+
+#: views/elements/amo2009/install.thtml:334 views/elements/install.thtml:112
+msgid "addons_install_in_sunbird"
+msgstr ""
+"<ol><li>Uložte soubor klepnutím na odkaz níže.</li><li>V Mozilla Sunbirdu "
+"otevřete Spráce doplňků z&nbsp;nabídky Nástroje.</li><li>Klepněte na "
+"tlaÄítko Instalovat, zvolte soubor, který jste stáhli a klepnÄ›te na \"OK\".</"
+"li></ol>"
+
+#: views/elements/amo2009/install.thtml:333 views/elements/install.thtml:111
+msgid "addons_install_in_sunbird_title"
+msgstr "Jak nainstalovat v&nbsp;Sunbirdu"
+
+#: views/elements/amo2009/install.thtml:331 views/elements/install.thtml:106
+msgid "addons_install_in_thunderbird"
+msgstr ""
+"<ol><li>Na odkaz níže klepnÄ›te pravým tlaÄítkem a z&nbsp;místní nabídky "
+"zvolte \"Uložit odkaz jako…\" a uložte soubor dopňku na váš pevný disk.</"
+"li><li>V Mozilla Thunderbirdu otevřete z&nbsp;nabídky Správce doplňků.</"
+"li><li>KlepnÄ›te na tlaÄítko Instalovat, najdÄ›te a vyberte stažený soubor a "
+"klepněte na \"OK\".</li></ol>"
+
+#: views/elements/amo2009/install.thtml:330 views/elements/install.thtml:105
+msgid "addons_install_in_thunderbird_title"
+msgstr "Jak naistalovat doplněk do Thunderbirdu"
+
+#: views/elements/amo2009/addon_list_options.thtml:108
+#: views/elements/addon_list_options.thtml:105
+msgid "addons_options_show_experimental"
+msgstr "Experimentální doplňky"
+
+#: views/elements/amo2009/addon_list_options.thtml:113
+#: views/elements/addon_list_options.thtml:109
+msgid "addons_options_submit"
+msgstr "Odeslat"
+
+#: views/addons/plugins.thtml:63 views/addons/plugins.thtml:73
+#: views/addons/plugins.thtml:83 views/addons/plugins.thtml:93
+#: views/addons/plugins.thtml:103 views/addons/plugins.thtml:116
+#: views/addons/plugins.thtml:126
+msgid "addons_plugins_by"
+msgstr "Výrobce: "
+
+#: views/addons/plugins.thtml:107
+msgid "addons_plugins_for_linux"
+msgstr "Linux"
+
+#: views/addons/plugins.thtml:108 views/addons/plugins.thtml:131
+msgid "addons_plugins_for_macosx"
+msgstr "Mac OS X"
+
+#: views/addons/plugins.thtml:106 views/addons/plugins.thtml:129
+#: views/addons/plugins.thtml:130
+msgid "addons_plugins_for_windows"
+msgstr "Windows"
+
+#. %1$s is a URL
+#: views/addons/plugins.thtml:139
+#, php-format
+msgid "addons_plugins_looking_for_more"
+msgstr ""
+"Tato stránka obsahuje seznam nejÄastÄ›ji používaných zásuvných modulů. Pokud "
+"hledáte další zásuvné moduly pro prohlížeÄe založené na Mozille, najdete je "
+"na stránkách projektu %1$s"
+
+#: views/addons/plugins.thtml:137
+msgid "addons_plugins_looking_for_plugin"
+msgstr "Hledáte zásuvný modul, který tu není"
+
+#: views/addons/plugins.thtml:58
+msgid "addons_plugins_main_description"
+msgstr ""
+"Zásuvné moduly (angl. plugins) jsou malé doplňky, které přidávají do "
+"prohlížeÄe nové, a vÄ›tÅ¡inou specifické, funkce. Typickým příkladem je "
+"pÅ™idání podpory urÄitého grafického formátu a nebo podpora multimédií - "
+"např. Flash, PDF, WMV. Zásuvné moduly na rozdíl od rozšíření nemodifikují "
+"samotný kód aplikace."
+
+#. %1$s is the application name. Example: Firefox, Thunderbird, Sunbird
+#: controllers/addons_controller.php:1122
+#, php-format
+msgid "addons_plugins_main_header"
+msgstr "Zásuvné moduly pro %1$s"
+
+#: controllers/components/amo.php:698 controllers/addons_controller.php:1121
+msgid "addons_plugins_pagetitle"
+msgstr "Zásuvné moduly"
+
+#: views/addons/plugins.thtml:68 views/addons/plugins.thtml:78
+#: views/addons/plugins.thtml:88 views/addons/plugins.thtml:98
+#: views/addons/plugins.thtml:110 views/addons/plugins.thtml:121
+#: views/addons/plugins.thtml:133
+msgid "addons_plugins_support_documentation"
+msgstr "Uživatelská dokumentace: "
+
+#. %s is the name of the add-on
+#: views/addons/policy.thtml:61
+#, php-format
+msgid "addons_policy_eula_require"
+msgstr ""
+"PÅ™ed instalací doplňku %s je nutné odsouhlasit následující LicenÄní smlouvu "
+"s koncovým uživatelem (EULA): "
+
+#. %1 is the add-on name
+#: controllers/addons_controller.php:1476
+#, php-format
+msgid "addons_previews_pagetitle"
+msgstr "Náhledy doplňku %s"
+
+#: views/addons/category_landing.thtml:135
+msgid "addons_recently_added"
+msgstr "Nedávno přidané"
+
+#: views/addons/recommended.thtml:51 controllers/addons_controller.php:1365
+msgid "addons_recommended_introduction"
+msgstr ""
+"Ve více než tisíci doplňcích si jistÄ› každý najde ten svůj. Pro zaÄátek vám "
+"nabízíme pár našich oblíbených. Užijte si je!"
+
+#: controllers/addons_controller.php:1357
+#: controllers/addons_controller.php:1364
+msgid "addons_recommended_pagetitle"
+msgstr "DoporuÄované doplňky"
+
+#: controllers/addons_controller.php:1360
+msgid "addons_recommended_title"
+msgstr "DoporuÄované doplňky"
+
+#: views/addons/searchengines.thtml:136
+msgid "addons_searchengines_additional_resources"
+msgstr "Další zdroje"
+
+#. link text devmo
+#: views/addons/searchengines.thtml:141
+msgid "addons_searchengines_devmo_link"
+msgstr "Vývojářském centrum Mozilly"
+
+#: views/pages/js_constants.js.thtml:67
+msgid "addons_searchengines_error_mozilla_browser_required"
+msgstr ""
+"Je nám líto, ale váš prohlížeÄ nepodporuje instalaci vyhledávacích modulů."
+
+#: views/addons/searchengines.thtml:49
+msgid "addons_searchengines_error_nojavascript"
+msgstr ""
+"K instalaci vyhledávacích modulů je vyžadován JavaScript, který váš "
+"prohlížeÄ nepodporuje a nebo ho máte vypnutý. PÅ™ed instalací níže uvedených "
+"vyhledávacích modulů si prosím zapněte podporu JavaScriptu."
+
+#. %1 is "make your own" link
+#. %2 is MDC link
+#: views/addons/searchengines.thtml:139
+msgid "addons_searchengines_learn_howto"
+msgstr "NauÄte se %1$s podle návodu na %2$s."
+
+#. link path to search plugins instructions, relative to devmo
+#: views/addons/searchengines.thtml:140
+msgid "addons_searchengines_makeyourown_href"
+msgstr "/cs/docs/Vytvo%C5%99en%C3%AD_vyhled%C3%A1vac%C3%ADho_modulu_OpenSearch"
+
+#. link text for "make your own" (opensearch engine)
+#: views/addons/searchengines.thtml:140
+msgid "addons_searchengines_makeyourown_link"
+msgstr "vytvářet vlastní moduly"
+
+#. %1 is the link to mycroft.mozdev.org
+#: views/addons/searchengines.thtml:138
+msgid "addons_searchengines_more"
+msgstr "Vyhledejte další moduly na stránkách %1$s"
+
+#. link text to mycroft.mozdev.org
+#: views/addons/searchengines.thtml:138
+msgid "addons_searchengines_mycroft_link"
+msgstr "mycroft.mozdev.org"
+
+#: controllers/addons_controller.php:1100
+#: controllers/addons_controller.php:1110
+msgid "addons_searchengines_pagetitle"
+msgstr "Vyhledávací moduly"
+
+#: views/addons/searchengines.thtml:143
+msgid "addons_searchengines_thanks"
+msgstr ""
+"Specialní díky patří projektu Mycroft za jejich práci kolem vyhledávacích "
+"modulů Firefoxu."
+
+#: views/addons/display.thtml:154
+msgid "addons_share_button_text"
+msgstr "Sdílet"
+
+#: controllers/addons_controller.php:89
+msgid "addons_share_label_delicious"
+msgstr "Přidat do Delicious"
+
+#: controllers/addons_controller.php:77
+msgid "addons_share_label_digg"
+msgstr "Přidat na Digg"
+
+#: controllers/addons_controller.php:83
+msgid "addons_share_label_facebook"
+msgstr "Přidat na Facebook"
+
+#: controllers/addons_controller.php:101
+msgid "addons_share_label_friendfeed"
+msgstr "Přidat na FriendFeed"
+
+#: controllers/addons_controller.php:95
+msgid "addons_share_label_myspace"
+msgstr "Přidat na MySpace"
+
+#: controllers/components/amo.php:201 controllers/components/amo.php:229
+msgid "addons_status_disabled"
+msgstr "Zakázaný"
+
+#: controllers/components/amo.php:191 controllers/components/amo.php:224
+msgid "addons_status_incomplete"
+msgstr "Neúplná verze"
+
+#: controllers/components/amo.php:197 controllers/components/amo.php:227
+msgid "addons_status_nominated"
+msgstr "Na pískovišti: Nominováno ke zveřejnění"
+
+#: views/pages/js_constants.js.thtml:80 controllers/components/amo.php:195
+#: controllers/components/amo.php:226
+msgid "addons_status_pending"
+msgstr "Na pískovišti: Čeká na kontrolu"
+
+#: views/pages/js_constants.js.thtml:78 controllers/components/amo.php:199
+#: controllers/components/amo.php:228
+msgid "addons_status_public"
+msgstr "veřejné"
+
+#: views/pages/js_constants.js.thtml:79 controllers/components/amo.php:193
+#: controllers/components/amo.php:225
+msgid "addons_status_sandbox"
+msgstr "na pískovišti"
+
+#: controllers/components/amo.php:203
+msgid "addons_status_unknown"
+msgstr "neznámý"
+
+#: views/elements/amo2009/teaser_collections.thtml:91
+#: views/elements/amo2009/homepage_addon.thtml:99
+#: views/elements/feature.thtml:94
+msgid "addons_title_tooltip"
+msgstr "Zobrazí více o&nbsp;doplňku"
+
+#: views/addons/category_landing.thtml:151
+msgid "addons_top_downloads"
+msgstr "Nejvíce stahované"
+
+#: views/addons/category_landing.thtml:165
+msgid "addons_top_rated"
+msgstr "Nejlépe hodnocené"
+
+#: views/addons/versions.thtml:62
+msgid "addons_versions_careful"
+msgstr "PÅ™i používání starších verzí buÄte opatrní"
+
+#: views/addons/versions.thtml:63
+msgid "addons_versions_careful_introduction"
+msgstr ""
+"Tyto verze jsou nabízeny pÅ™edevším pro porovnání a pro testovací úÄely. Pro "
+"běžné používání doporuÄujeme mít nainstalovánu vždy nejnovÄ›jší verzi doplňku."
+
+#: controllers/addons_controller.php:1549
+msgid "addons_versions_history"
+msgstr "Historie verzí s&nbsp;popisem změn"
+
+#. %1$s is the add-on name
+#: controllers/addons_controller.php:1535
+#, php-format
+msgid "addons_versions_pagetitle"
+msgstr "Historie verzí doplňku %1$s"
+
+#: controllers/groups_controller.php:71
+msgid "admin_group_add_pagetitle"
+msgstr "Přidat skupinu"
+
+#: controllers/groups_controller.php:111
+msgid "admin_group_delete_pagetitle"
+msgstr "Smazat skupinu"
+
+#. %s is a number to identify the group
+#: controllers/groups_controller.php:117
+#, php-format
+msgid "admin_group_deleted"
+msgstr "Skupina s&nbsp;ID %s byla smazána"
+
+#: controllers/groups_controller.php:89
+msgid "admin_group_edit_pagetitle"
+msgstr "Úprava skupiny"
+
+#: controllers/groups_controller.php:92 controllers/groups_controller.php:113
+msgid "admin_group_error_invalid_id"
+msgstr "Neplatné ID skupiny"
+
+#: controllers/groups_controller.php:65
+msgid "admin_group_pagetitle"
+msgstr "Správce skupin"
+
+#: controllers/groups_controller.php:77 controllers/groups_controller.php:99
+msgid "admin_group_saved"
+msgstr "Skupina byla uložena"
+
+#: views/elements/amo2009/search.thtml:257 views/elements/search.thtml:239
+msgid "advanced_search_form"
+msgstr "Rozšířené"
+
+#: views/elements/amo2009/search.thtml:126 views/elements/search.thtml:125
+msgid "advanced_search_form_any_time"
+msgstr "Kdykoliv"
+
+#: views/elements/amo2009/search.thtml:97
+#: views/elements/amo2009/search.thtml:110 views/elements/search.thtml:96
+#: views/elements/search.thtml:109
+msgid "advanced_search_form_any_type"
+msgstr "Nezáleží"
+
+#: views/elements/amo2009/search.thtml:275 views/elements/search.thtml:254
+msgid "advanced_search_form_any_version"
+msgstr "Nezáleží"
+
+#: views/elements/amo2009/search.thtml:217 views/elements/search.thtml:212
+msgid "advanced_search_form_application"
+msgstr "Aplikace"
+
+#: views/elements/amo2009/search.thtml:143 views/elements/search.thtml:142
+msgid "advanced_search_form_keyword_match"
+msgstr "Shoda klíÄového slova"
+
+#: views/elements/amo2009/search.thtml:251 views/elements/search.thtml:225
+msgid "advanced_search_form_lastupdate"
+msgstr "Aktualizované"
+
+#: views/elements/amo2009/search.thtml:145 views/elements/search.thtml:144
+msgid "advanced_search_form_name"
+msgstr "Název"
+
+#: views/elements/amo2009/search.thtml:144 views/elements/search.thtml:143
+msgid "advanced_search_form_newest"
+msgstr "Nejnovější"
+
+#: views/elements/amo2009/search.thtml:130 views/elements/search.thtml:129
+msgid "advanced_search_form_past_3_months"
+msgstr "Poslední 3 měsíce"
+
+#: views/elements/amo2009/search.thtml:131 views/elements/search.thtml:130
+msgid "advanced_search_form_past_6_months"
+msgstr "Posledních 6 měsíců"
+
+#: views/elements/amo2009/search.thtml:127 views/elements/search.thtml:126
+msgid "advanced_search_form_past_day"
+msgstr "Poslední den"
+
+#: views/elements/amo2009/search.thtml:129 views/elements/search.thtml:128
+msgid "advanced_search_form_past_month"
+msgstr "Poslední měsíc"
+
+#: views/elements/amo2009/search.thtml:128 views/elements/search.thtml:127
+msgid "advanced_search_form_past_week"
+msgstr "Poslední týden"
+
+#: views/elements/amo2009/search.thtml:132 views/elements/search.thtml:131
+msgid "advanced_search_form_past_year"
+msgstr "Poslední rok"
+
+#: views/elements/amo2009/search.thtml:239 views/elements/search.thtml:230
+msgid "advanced_search_form_perpage"
+msgstr "Doplňků na stránku"
+
+#: views/elements/amo2009/search.thtml:243 views/elements/search.thtml:224
+msgid "advanced_search_form_platform"
+msgstr "Platforma"
+
+#: views/elements/amo2009/search.thtml:147 views/elements/search.thtml:146
+msgid "advanced_search_form_popularity"
+msgstr "Popularita"
+
+#: views/elements/amo2009/search.thtml:146 views/elements/search.thtml:145
+msgid "advanced_search_form_rating"
+msgstr "Hodnocení"
+
+#: views/elements/amo2009/search.thtml:247 views/elements/search.thtml:231
+msgid "advanced_search_form_sortby"
+msgstr "Seřadit dle"
+
+#: views/elements/amo2009/search.thtml:227 views/elements/search.thtml:216
+msgid "advanced_search_form_to"
+msgstr "až"
+
+#: views/elements/amo2009/search.thtml:257 views/elements/search.thtml:237
+msgid "advanced_search_form_toggle_tooltip"
+msgstr "Přepne do režimu rozšířeného vyhledávání"
+
+#: views/elements/amo2009/search.thtml:235 views/elements/search.thtml:223
+msgid "advanced_search_form_type"
+msgstr "Typ"
+
+#: views/elements/amo2009/search.thtml:222 views/elements/search.thtml:214
+msgid "advanced_search_form_version"
+msgstr "Verze"
+
+#: views/elements/amo2009/pagination.thtml:42
+msgid "amo2009_pagination_next_page"
+msgstr "Další"
+
+#: views/elements/amo2009/pagination.thtml:41
+msgid "amo2009_pagination_previous_page"
+msgstr "Předchozí"
+
+#: views/pages/js_constants.js.thtml:96
+msgid "app_compat_ignore_check"
+msgstr "Ignorovat kontrolu verzí"
+
+#: views/pages/js_constants.js.thtml:72
+msgid "app_compat_older_firefox_only"
+msgstr "Tento doplněk je pouze pro starší verzi Firefoxu"
+
+#. %1$s and %2$s are URLs
+#: views/pages/js_constants.js.thtml:74
+msgid "app_compat_older_version_or_ignore_check"
+msgstr ""
+"Můžete <a href=\"%1$s\">vyzkoušet starší verzi</a> nebo <a href=\"#\" "
+"onclick=\"%2$s\">tuto kontrolu ignorovat</a>"
+
+#. %1$s is a URL
+#: views/pages/js_constants.js.thtml:71
+msgid "app_compat_try_old_version"
+msgstr "Zkuste použít <a href=\"%1$s\">starší verzi</a>"
+
+#. %1$s is a URL
+#. %2$s is a version number. Example: 3.1
+#: views/pages/js_constants.js.thtml:73
+msgid "app_compat_unreleased_version"
+msgstr ""
+"Tento doplněk vyžaduje dosud nevydaný <a href=\"%1$s\">Firefox %2$s</a>"
+
+#: views/pages/js_constants.js.thtml:70
+msgid "app_compat_update_firefox"
+msgstr ""
+"Pro použití tohoto doplňku je nutné <a href=\"http://getfirefox.com"
+"\">aktualizovat Firefox</a>"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#. %3$s is a status, like Public.
+#: controllers/components/audit.php:79
+msgid "audit_addon_status"
+msgstr "Uživatel %1$s změnil stav %2$s na %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:221
+msgid "audit_admin_default"
+msgstr "Uživatel %1$s uÄinil neznámou administrátorskou akci %2$s u ID %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:153
+msgid "audit_admin_feature_remove"
+msgstr "Uživatel %1$s odstranil funkci %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is an application, like Firefox.
+#: controllers/components/audit.php:92
+msgid "audit_application_create"
+msgstr "Uživatel %1$s vytvořil aplikaci %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is an application, like Firefox.
+#: controllers/components/audit.php:95
+msgid "audit_application_edit"
+msgstr "Uživatel %1$s upravil aplikaci %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a version number, like 3.5.
+#. %3$s is an application, like Firefox.
+#: controllers/components/audit.php:105
+msgid "audit_appversion_create"
+msgstr "Uživatel %1$s vytvořil verzi %2$s pro %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a version number, like 3.5.
+#. %3$s is an application, like Firefox.
+#: controllers/components/audit.php:108
+msgid "audit_appversion_delete"
+msgstr "Uživatel %1$s odstranil verzi %2$s pro %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a config field, like "awesomeness".
+#. %3$s is a config value, like "off".
+#. %4$s is a config value, like "on".
+#: controllers/components/audit.php:210
+msgid "audit_config"
+msgstr "Uživatel %1$s změnil předvolbu '%2$s' z '%3$s' na '%4$s'"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:258
+msgid "audit_editor_default"
+msgstr "Uživatel %1$s uÄinil neznámou akci editora %2$s na ID %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#: controllers/components/audit.php:236
+msgid "audit_editor_feature_remove"
+msgstr "Uživatel %1$s odstranil doplnÄ›k %2$s ze seznamu doporuÄovaných"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#: controllers/components/audit.php:231
+msgid "audit_feature_add"
+msgstr "Uživatel %1$s pÅ™idal %2$s na seznam doporuÄovaných"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:149
+msgid "audit_feature_edit"
+msgstr "Uživatel %1$s zmÄ›nil doporuÄení pro jazyk %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#: controllers/components/audit.php:241
+msgid "audit_feature_locale_change"
+msgstr "Uživatel %1$s zmÄ›nil jazyky pro doplnÄ›k %2$s ze seznamu doporuÄovaných"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:83
+msgid "audit_file_recalchash"
+msgstr "Uživatel %1$s pÅ™epoÄítal kontrolní souÄet souboru %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>user name</a>
+#. %3$s is <a>group name</a>
+#: controllers/components/audit.php:182
+msgid "audit_group_addmember"
+msgstr "Uživatel %1$s byl přidán %2$s do skupiny %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:313
+msgid "audit_group_associated"
+msgstr "Uživatel %1$s se přiřadil k %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:162
+msgid "audit_group_create"
+msgstr "Uživatel %1s vytvořil skupinu %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:170
+msgid "audit_group_delete"
+msgstr "Uživatel %1$s odstranil skupinu %2$s (ID %3$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:165
+msgid "audit_group_edit"
+msgstr "Uživatel %1$s upravil skupinu %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>user name</a>
+#. %3$s is <a>group name</a>
+#: controllers/components/audit.php:188
+msgid "audit_group_removemember"
+msgstr "Uživatel %1$s odstranil %2$s ze skupiny %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:280
+msgid "audit_l10n_default"
+msgstr "Uživatel %1$s provedl neznámou akci %2$s u %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:295
+msgid "audit_modify_locked_group"
+msgstr "Uživatel %1$s se pokusil upravit uzamÄenou skupinu %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:299
+msgid "audit_modify_other_locale"
+msgstr "Uživatel %1$s se pokusil bez oprávnění upravit překlady u %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a platform, like <a>Windows</a>
+#: controllers/components/audit.php:135
+msgid "audit_platform_create"
+msgstr "Uživatel %1$s vytvořil platformu %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a platform, like <a>Windows</a>
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:143
+msgid "audit_platform_delete"
+msgstr "Uživatel %1$s odstranil platformu %2$s (ID %3$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a platform, like <a>Windows</a>
+#: controllers/components/audit.php:138
+msgid "audit_platform_edit"
+msgstr "Uživatel %1$s upravil platformu %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a part of the admin, like 'Site Config'
+#: controllers/components/audit.php:288
+msgid "audit_reauthentication_failure"
+msgstr "Uživatel %1$s selhal při opětovném ověření přístupu k %2$s."
+
+#. %1$s is <a>user name</a>
+#. %2$s is the name of a canned response, like 'Ready for the public'
+#: controllers/components/audit.php:198
+msgid "audit_response_create"
+msgstr "Uživatel %1$s vytvoÅ™il odpovÄ›Ä %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is the name of a canned response, like 'Ready for the public'
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:206
+msgid "audit_response_delete"
+msgstr "Uživatel %1$s odstranil odpovÄ›Ä %2$s (ID %3$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is the name of a canned response, like 'Ready for the public'
+#: controllers/components/audit.php:201
+msgid "audit_response_edit"
+msgstr "Uživatel %1$s upravil odpovÄ›Ä %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:245
+msgid "audit_review_approve"
+msgstr "Uživatel %1$s schválil recenzi %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:250 controllers/components/audit.php:253
+msgid "audit_review_delete"
+msgstr "Uživatel %1$s odstranil recenzi %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:303
+msgid "audit_security_default"
+msgstr "Uživatel %1$s provedl neznámou bezpeÄnostní akci %2$s na ID %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a category name, like <a>Search Tools</a>
+#: controllers/components/audit.php:118
+msgid "audit_tag_create"
+msgstr "Uživatel %1$s vytvořil štítek %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a category name, like <a>Search Tools</a>
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:126
+msgid "audit_tag_delete"
+msgstr "Uživatel %1$s odstranil kategorii %2$s (ID %3$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a category name, like <a>Search Tools</a>
+#: controllers/components/audit.php:121
+msgid "audit_tag_edit"
+msgstr "Uživatel %1$s upravil kategorii %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:266
+msgid "audit_update_applications"
+msgstr "Uživatel %1$s upravil překlady aplikace pro %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:277
+msgid "audit_update_blog"
+msgstr "Uživatel %1$s upravil překlad příspěvku do blogu pro %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:274
+msgid "audit_update_platforms"
+msgstr "Uživatel %1$s upravil překlady platformy pro %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:270
+msgid "audit_update_tags"
+msgstr "Uživatel %1$s upravil překlady kategorií pro %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>user name</a>
+#: controllers/components/audit.php:217
+msgid "audit_user_edit"
+msgstr "Uživatel %1$s upravil informace o uživateli %2$s"
+
+#: controllers/addons_controller.php:1012
+msgid "browse_addons_name"
+msgstr "Doplňky podle jména"
+
+#: controllers/addons_controller.php:1010
+msgid "browse_addons_newest"
+msgstr "Nové doplňky"
+
+#: controllers/addons_controller.php:1008
+msgid "browse_addons_popular"
+msgstr "Oblíbené doplňky"
+
+#: controllers/addons_controller.php:1011
+msgid "browse_addons_rated"
+msgstr "Doplňky podle hodnocení"
+
+#: controllers/addons_controller.php:1009
+msgid "browse_addons_updated"
+msgstr "Právě aktualizované doplňky"
+
+#: views/elements/categories.thtml:73 views/elements/categories.thtml:82
+msgid "categories_current_title"
+msgstr "SouÄasná kategorie"
+
+#: views/elements/categories.thtml:50
+#: views/elements/amo2009/categories.thtml:43
+#: views/elements/amo2009/categories.thtml:45
+msgid "categories_header"
+msgstr "Kategorie"
+
+#: views/elements/categories.thtml:50
+#: views/elements/amo2009/categories.thtml:41
+msgid "categories_header_title"
+msgstr "Vybere kategorii"
+
+#. %1$s is the category name
+#: views/addons/searchengines.thtml:129
+#, php-format
+msgid "category_extra_see_all"
+msgstr "Zobrazit vše v&nbsp;kategorii %1$s"
+
+#. %1$s is a number.
+#: models/collection.php:130
+msgid "collection_description_limit"
+msgstr "Popis by měl být kratší než %1$s znaků."
+
+#. %1$s is the name of the collection
+#: controllers/collections_controller.php:392
+msgid "collection_detail_rss_title"
+msgstr "Sbírka %s"
+
+#: controllers/collections_controller.php:1065
+msgid "collection_error_deleting_addon"
+msgstr "Chyba při mazání doplňku!"
+
+#: controllers/collections_controller.php:1051
+msgid "collection_error_saving_addon"
+msgstr "Chyba při ukládání doplňku!"
+
+#: controllers/collections_controller.php:1080
+msgid "collection_error_saving_comment"
+msgstr "Chyba při ukládání komentáře!"
+
+#. %1$s is a number.
+#: models/collection.php:122
+msgid "collection_name_limit"
+msgstr "Jméno by mělo být kratší než %1$s znaků."
+
+#: controllers/collections_controller.php:352
+#: controllers/collections_controller.php:487
+msgid "collection_not_found"
+msgstr "Sbírka nenalezena!"
+
+#. %1$s is the text on the "create collection" button
+#: views/collections/add.thtml:91
+msgid "collections_add_formfield_addons_description"
+msgstr ""
+"Pokud již víte, které doplňky chcete přidat do vaší sbírky, jednoduše "
+"zaÄnÄ›te psáte níže jejich jména. Pokud je chcete radÄ›ji pÅ™idat pozdÄ›ji, "
+"jednoduše klepněte na %1$s."
+
+#: views/collections/add.thtml:90
+msgid "collections_add_formfield_firstaddons"
+msgstr "Zvolte váš první doplněk"
+
+#: views/collections/add.thtml:48
+msgid "collections_add_header"
+msgstr "Vytvořit sbírku"
+
+#: views/collections/add.thtml:97
+msgid "collections_add_header_selectedaddons"
+msgstr "Zvolené doplňky"
+
+#: views/collections/add.thtml:50
+msgid "collections_add_intro"
+msgstr ""
+"Pomocí několika polí níže je snadné vytvořit si vlastní sbírky doplňků."
+
+#: views/collections/add.thtml:92 views/collections/add.thtml:103
+msgid "collections_add_submit"
+msgstr "Vytvořit sbírku"
+
+#: views/pages/collector_faq.thtml:50 views/pages/collector_firstrun.thtml:43
+#: views/pages/collector.thtml:47 views/pages/collector_features.thtml:55
+#: controllers/search_controller.php:302
+#: controllers/collections_controller.php:206
+#: controllers/collections_controller.php:405
+#: controllers/collections_controller.php:467
+#: controllers/collections_controller.php:539
+msgid "collections_breadcrumb"
+msgstr "Sbírky"
+
+#: views/collections/detail.thtml:185
+msgid "collections_detail_a_learn"
+msgstr "Dozvědět se více"
+
+#: views/elements/amo2009/collection_add_form.thtml:53
+#: views/elements/amo2009/collections_js_init.thtml:68
+#: views/pages/collector_firstrun.thtml:64
+msgid "collections_detail_button_add"
+msgstr "Přidat do oblíbených"
+
+#: views/elements/amo2009/collection_add_form.thtml:50
+#: views/elements/amo2009/collections_js_init.thtml:71
+msgid "collections_detail_button_remove"
+msgstr "Odebrat z oblíbených"
+
+#. %1$s is a URL.
+#. %2$s is a full <a href>.
+#: views/collections/detail.thtml:62
+msgid "collections_detail_created_desc"
+msgstr ""
+"<p>Vaši novou sbírku můžete vidět níže. Pokud byste rádi u sbírky nastavili "
+"oznaÄení, nahráli ikonu Äi zmÄ›nili další nastavení, navÅ¡tivte prosím stránku "
+"<a href='%1$s'>Správa sbírek</a>.</p><p>Vaše sbírka je dostupná na adrese: %2$s</p>"
+
+#: views/collections/detail.thtml:61
+msgid "collections_detail_created_msg"
+msgstr "Vaše sbírka je nyní připravena!"
+
+#: views/collections/detail.thtml:109
+msgid "collections_detail_header_about"
+msgstr "O této sbírce"
+
+#. %1$s is a number.
+#: views/collections/detail.thtml:126
+msgid "collections_detail_header_count"
+msgid_plural "collections_detail_header_count"
+msgstr[0] "%1$s doplněk ve sbírce"
+msgstr[1] "%1$s doplňky v této sbírce"
+msgstr[2] "%1$s doplňků v této sbírce"
+
+#: views/collections/detail.thtml:113
+msgid "collections_detail_info_created"
+msgstr "<strong>Vytvořil:</strong> %1$s"
+
+#: views/collections/detail.thtml:117
+msgid "collections_detail_info_updated"
+msgstr "<strong>Aktualizováno:</strong>"
+
+#: views/elements/amo2009/collections_js_init.thtml:62
+msgid "collections_detail_js_adding"
+msgstr "Přidání k oblíbeným&hellip;"
+
+#: views/elements/amo2009/collections_js_init.thtml:65
+msgid "collections_detail_js_removing"
+msgstr "Odebrání z oblíbených&hellip;"
+
+#. %1$s is a URL
+#: views/collections/detail.thtml:90
+msgid "collections_detail_login"
+msgstr "Pro přidání sbírky k oblíbeným se <a href=\"%1$s\">přihlašte</a>."
+
+#: views/collections/detail.thtml:104
+msgid "collections_detail_manage"
+msgstr "Správa sbírky"
+
+#: controllers/collections_controller.php:298
+msgid "collections_detail_sort_date"
+msgstr "Datum přidání"
+
+#: controllers/collections_controller.php:299
+msgid "collections_detail_sort_name"
+msgstr "Jméno"
+
+#: controllers/collections_controller.php:300
+msgid "collections_detail_sort_popularity"
+msgstr "Popularita"
+
+#. %1$s is a number.
+#: views/collections/detail.thtml:166
+msgid "collections_detail_weekly_downloads"
+msgid_plural "collections_detail_weekly_downloads"
+msgstr[0] "%1$s stažení tento týden"
+msgstr[1] "%1$s stažení tento týden"
+msgstr[2] "%1$s stažení tento týden"
+
+#: views/collections/edit.thtml:255
+msgid "collections_edit_addons_delete_noscript"
+msgstr "Zvolené doplňky budou po uložení odstraněny"
+
+#: views/collections/edit.thtml:247
+msgid "collections_edit_addons_description"
+msgstr "Pro pÅ™idání nových doplňků do sbírky zaÄnete psát níže jejich jména."
+
+#: views/collections/edit.thtml:248
+msgid "collections_edit_addons_description_noscript"
+msgstr ""
+"Pro přidání nových doplňků do této sbírky vložte níže seznam jejich ID "
+"oddÄ›lený Äárkami."
+
+#: views/collections/edit.thtml:247 views/collections/edit.thtml:248
+msgid "collections_edit_addons_description_publish_detailspage"
+msgstr "Doplněk též můžete přidat z jeho stránky."
+
+#. %1$s is the date the add-on was added to the collection
+#. %1$s is the name of the user who added the add-on to the collection
+#: views/collections/edit.thtml:260
+msgid "collections_edit_addons_listitem_added"
+msgstr "Přidán %1$s uživatelem(kou) %2$s"
+
+#: views/collections/edit.thtml:263
+msgid "collections_edit_addons_listitem_comment_add"
+msgstr "Přidat komentář vydavatele"
+
+#: views/collections/edit.thtml:266
+msgid "collections_edit_addons_listitem_comment_delete"
+msgstr "Smazat komentář vydavatele"
+
+#: views/collections/edit.thtml:265
+msgid "collections_edit_addons_listitem_comment_edit"
+msgstr "Upravit komentář vydavatele"
+
+#: views/collections/edit.thtml:271
+msgid "collections_edit_addons_listitem_comment_note"
+msgstr ""
+"Poznámka: Komentář se bude tvářit, jako by jej psal vydavatel v den původní "
+"publikace"
+
+#: views/collections/edit.thtml:270
+msgid "collections_edit_addons_listitem_comment_submit"
+msgstr "Uložit komentář"
+
+#: views/collections/edit.thtml:261
+msgid "collections_edit_addons_listitem_remove"
+msgstr "Odebrat"
+
+#: views/collections/edit.thtml:250
+msgid "collections_edit_addons_submit"
+msgstr "Přidat do sbírky"
+
+#: views/collections/edit.thtml:153
+msgid "collections_edit_check_nickname"
+msgstr "Ověřit dostupnost"
+
+#: views/collections/edit.thtml:299
+msgid "collections_edit_confirm_deletecollection"
+msgstr "Ano, chci smazat tuto sbírku."
+
+#. %1$s is the label of the edit form's submit button
+#: views/collections/edit.thtml:300
+msgid "collections_edit_confirm_deletecollection_description"
+msgstr "Pro smazání tété sbírky zaškrtněte pole a klepněte na \"%1$s\"."
+
+#. %1$s is the "delete" submit button text
+#. %2$s is the title of the "advanced" tab
+#: views/collections/edit.thtml:95
+msgid "collections_edit_delete_upon_submit"
+msgstr ""
+"Po klepnutí na \"%1$s\" níže bude vaše sbírka smazána. Pokud nechcete vaši "
+"sbírku smazat, odÅ¡krtnÄ›te potvrzující dialog na panelu \"%2$s\" a pokraÄujte "
+"úpravou vaší sbírky. Pokud tuto stránku opustíte bez uložení vaše sbírka též "
+"nebude smazána."
+
+#: views/collections/edit.thtml:94
+msgid "collections_edit_delete_warning"
+msgstr "Sbírka bude smazána!"
+
+#: views/collections/add.thtml:76 views/collections/edit.thtml:144
+msgid "collections_edit_form_error_description"
+msgstr "K své sbírce musíte napsat popis."
+
+#: views/collections/edit.thtml:181
+msgid "collections_edit_form_error_icon"
+msgstr "Při nahrávání ikony nastala chyba."
+
+#: views/collections/add.thtml:69 views/collections/edit.thtml:130
+msgid "collections_edit_form_error_name"
+msgstr "Vaši sbírku musíte pojmenovat."
+
+#: views/collections/edit.thtml:158
+msgid "collections_edit_form_error_nickname"
+msgstr "Pokud zvolíte oznaÄení, musí být unikátní."
+
+#: views/collections/add.thtml:93 views/collections/edit.thtml:249
+msgid "collections_edit_formfield_addons"
+msgstr "Jméno doplňku:"
+
+#: views/collections/edit.thtml:281
+msgid "collections_edit_formfield_application"
+msgstr "Přiřazená aplikace"
+
+#: views/collections/edit.thtml:282
+msgid "collections_edit_formfield_application_description"
+msgstr "Zvolte aplikaci, kterou vaše sbírka podporuje."
+
+#: views/collections/edit.thtml:288
+msgid "collections_edit_formfield_collectiontype"
+msgstr "Typ sbírky"
+
+#: views/collections/edit.thtml:295
+msgid "collections_edit_formfield_deletecollection"
+msgstr "Smazat sbírku"
+
+#: views/collections/edit.thtml:296
+msgid "collections_edit_formfield_deletecollection_description"
+msgstr "Smazáním vaší sbírky ji definitivně odstraníte."
+
+#: views/collections/add.thtml:73 views/collections/edit.thtml:140
+msgid "collections_edit_formfield_description"
+msgstr "Popis sbírky"
+
+#: views/collections/add.thtml:74 views/collections/edit.thtml:141
+msgid "collections_edit_formfield_description_description"
+msgstr "StruÄnÄ› popiÅ¡te vaÅ¡i sbírku a typ doplňků, které obsahuje"
+
+#: views/collections/edit.thtml:162
+msgid "collections_edit_formfield_icon"
+msgstr "Ikona"
+
+#: views/collections/edit.thtml:163
+msgid "collections_edit_formfield_icon_description"
+msgstr ""
+"Můžete nahrát ikonu ve formátech JPG, GIF Äi PNG, které budou upraveny na "
+"rozměry 32x32 pixelů."
+
+#: views/collections/add.thtml:80 views/collections/edit.thtml:189
+msgid "collections_edit_formfield_listed"
+msgstr "Kdo může vidět vaši sbírku?"
+
+#: views/collections/add.thtml:81 views/collections/edit.thtml:190
+msgid "collections_edit_formfield_listed_description"
+msgstr ""
+"Ve výchozím nastavení jsou sbírky viditelné ve veřejném adresáři sbírek a "
+"každý se na ně může podívat. Pokud chcete k vaší sbírce dát přístup pouze "
+"lidem, kterým dáte speciální odkaz, zvolte volbu níže."
+
+#: views/collections/add.thtml:84 views/collections/edit.thtml:193
+msgid "collections_edit_formfield_listed_false"
+msgstr "Sbírku mohou vidět pouze lidé, které pozvu"
+
+#: views/collections/add.thtml:83 views/collections/edit.thtml:192
+msgid "collections_edit_formfield_listed_true"
+msgstr "Kdokoliv může mou sbírku vidět v adresáři"
+
+#: views/collections/edit.thtml:223
+msgid "collections_edit_formfield_managers"
+msgstr "Kdo může spravovat mou sbírku?"
+
+#: views/collections/edit.thtml:224
+msgid "collections_edit_formfield_managers_description"
+msgstr ""
+"Tito uživatelé mohou přidávat doplňky do vaší sbírky, spravovat všechny "
+"doplňky a nastavení a udělovat práva jiným uživatelům."
+
+#: views/collections/add.thtml:66 views/collections/edit.thtml:126
+msgid "collections_edit_formfield_name"
+msgstr "Jméno sbírky"
+
+#: views/collections/add.thtml:67 views/collections/edit.thtml:127
+msgid "collections_edit_formfield_name_description"
+msgstr ""
+"Pojmenujte vaši sbírku rozumně. Například \"Mé oblíbené doplňky pro vývoj\"."
+
+#: views/collections/edit.thtml:148
+msgid "collections_edit_formfield_nickname"
+msgstr "OznaÄení sbírky"
+
+#: views/collections/edit.thtml:149
+msgid "collections_edit_formfield_nickname_description"
+msgstr "VolitelnÄ› můžete dát vaší sbírce unikátní oznaÄení pro rychlý přístup:"
+
+#: views/collections/edit.thtml:201
+msgid "collections_edit_formfield_publishers"
+msgstr "Kdo může přidávat doplňky do vaší sbírky?"
+
+#: views/collections/edit.thtml:202
+msgid "collections_edit_formfield_publishers_description"
+msgstr ""
+"Tito uživatelé smí přidávat doplňky do vaší sbírky a odstraňovat ty, které "
+"přidali."
+
+#: views/collections/edit.thtml:210 views/collections/edit.thtml:232
+msgid "collections_edit_formfield_users_add"
+msgstr "Vložte e-mailovou adresu svého úÄtu na webu Doplňky Firefoxu:"
+
+#: views/collections/edit.thtml:216 views/collections/edit.thtml:238
+msgid "collections_edit_formfield_users_delete_noscript"
+msgstr "Vybrané úÄty budou po uložení odstranÄ›ny"
+
+#: views/collections/edit.thtml:215 views/collections/edit.thtml:237
+msgid "collections_edit_formfield_users_new_noscript"
+msgstr ""
+"Vložte seznam e-mailových adres úÄtů webu Doplňky Firefoxu oddÄ›lených Äárkou"
+
+#: views/collections/edit.thtml:204 views/collections/edit.thtml:226
+msgid "collections_edit_formfield_users_onlyme"
+msgstr "Pouze já"
+
+#: views/collections/edit.thtml:205 views/collections/edit.thtml:227
+msgid "collections_edit_formfield_users_otherusers"
+msgstr "Já a tito uživatelé:"
+
+#: views/collections/edit.thtml:211 views/collections/edit.thtml:233
+msgid "collections_edit_formfield_users_submit"
+msgstr "Přidat"
+
+#. %1$s is the name of the collection
+#: views/collections/edit.thtml:68
+msgid "collections_edit_header"
+msgstr "Správa %1$s"
+
+#: views/collections/edit.thtml:246
+msgid "collections_edit_header_addons"
+msgstr "Správa obsahu sbírky"
+
+#: views/collections/edit.thtml:253 views/collections/edit.thtml:258
+msgid "collections_edit_header_addons_current"
+msgstr "Aktuální doplňky:"
+
+#: views/collections/edit.thtml:279
+msgid "collections_edit_header_advanced"
+msgstr "PokroÄilá nastavení"
+
+#: views/collections/edit.thtml:186
+msgid "collections_edit_header_permissions"
+msgstr "Správa práv ke sbírce"
+
+#: views/collections/edit.thtml:170
+msgid "collections_edit_icon_cancel"
+msgstr "Zrušit"
+
+#: views/collections/edit.thtml:174 views/collections/edit.thtml:179
+msgid "collections_edit_icon_delete"
+msgstr "Smazat ikonu"
+
+#: views/collections/edit.thtml:178
+msgid "collections_edit_icon_replace"
+msgstr "Nahradit ikonu"
+
+#. %1$s is the label of the edit form's submit button
+#: views/collections/edit.thtml:169
+msgid "collections_edit_icon_toberemoved"
+msgstr "Ikona bude po klepnutí na \"%1$s\" odstraněna"
+
+#: views/collections/edit.thtml:155
+msgid "collections_edit_nickname_available"
+msgstr "Dostupné oznaÄení"
+
+#: controllers/collections_controller.php:943
+msgid "collections_edit_nickname_error"
+msgstr ""
+"OznaÄení obsahuje neplatné znaky, které byly opraveny. Zkuste to prosím "
+"znovu."
+
+#: views/collections/edit.thtml:156
+msgid "collections_edit_nickname_taken"
+msgstr "OznaÄení je obsazeno"
+
+#. This string is followed by a URL pointing to the collection's view page
+#: views/collections/edit.thtml:75
+msgid "collections_edit_saved_nextstep"
+msgstr "Sbírka může být dostupná v tomto umístění:"
+
+#: views/collections/edit.thtml:74
+msgid "collections_edit_saved_success"
+msgstr "Sbírka byla úspěšně uložena!"
+
+#: views/collections/edit.thtml:169 views/collections/edit.thtml:300
+#: views/collections/edit.thtml:308 views/pages/js_constants.js.thtml:99
+msgid "collections_edit_submit"
+msgstr "Aktualizovat sbírku"
+
+#: views/collections/edit.thtml:96 views/collections/edit.thtml:297
+#: views/pages/js_constants.js.thtml:100
+msgid "collections_edit_submit_deletecollection"
+msgstr "Smazat sbírku"
+
+#: views/collections/edit.thtml:111
+msgid "collections_edit_tabheader_addons"
+msgstr "Doplňky"
+
+#: views/collections/edit.thtml:97 views/collections/edit.thtml:113
+msgid "collections_edit_tabheader_advanced"
+msgstr "PokroÄilé"
+
+#: views/collections/edit.thtml:108
+msgid "collections_edit_tabheader_details"
+msgstr "Jméno a podrobnosti"
+
+#: views/collections/edit.thtml:109
+msgid "collections_edit_tabheader_permissions"
+msgstr "Povolení"
+
+#: models/collection_promo.php:53
+msgid "collections_family_tagline"
+msgstr "Doplňky mohou dávat pozor na vaše děti i kalendář."
+
+#: models/collection_promo.php:53
+msgid "collections_family_title"
+msgstr "Rodina"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:70
+msgid "collections_index_a_check_out"
+msgstr "Vyzkoušejte Sbírku doplňků"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:52
+msgid "collections_index_a_create"
+msgstr "Vytvořit sbírku"
+
+#: views/collections/detail.thtml:139 views/collections/listing.thtml:85
+#: views/search/collections.thtml:84
+msgid "collections_index_button_go"
+msgstr "Přejít"
+
+#. %1$s is a URL.
+#: controllers/collections_controller.php:182
+msgid "collections_index_filler_favorites"
+msgstr ""
+"<p><strong>Prozatím nemáte žádné oblíbené sbírky.</strong></p> "
+"<p>Sbírky, které oznaÄíte jako oblíbené, jsou z této stránky rychle dostupné "
+"a zobrazí se též v rozšíření <a href='%1$s'>Sbírky doplňků</a>, pokud ho "
+"máte nainstalováno.</p>"
+
+#. %1$s is a URL.
+#: controllers/collections_controller.php:167
+msgid "collections_index_filler_mine"
+msgstr ""
+"<p>Prozatím jste nevytvořili žádné sbírky. Sbírky se snadno vytvářejí "
+"a naplňují vašimi oblíbenými doplňky. <a href='%1$s'>Vyzkoušejte je</a>!</p>"
+
+#: views/collections/listing.thtml:51
+msgid "collections_index_header_collections"
+msgstr "Sbírky"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:60
+msgid "collections_index_header_collector"
+msgstr "Sbírky doplňků"
+
+#. %1$s is a comma-separated list of author names
+#: views/elements/amo2009/collection_listing_item.thtml:84
+#: views/collections/detail.thtml:151
+msgid "collections_index_header_created"
+msgstr "vytvořili %1$s"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:47
+msgid "collections_index_header_what"
+msgstr "Co jsou sbírky?"
+
+#: views/collections/detail.thtml:132 views/collections/listing.thtml:78
+#: views/search/collections.thtml:66
+msgid "collections_index_label_sortby"
+msgstr "Řadit dle"
+
+#: controllers/collections_controller.php:130
+msgid "collections_index_li_editors"
+msgstr "DoporuÄené redaktory"
+
+#: views/collections/subscribe.thtml:64
+#: controllers/collections_controller.php:140
+msgid "collections_index_li_favorites"
+msgstr "Mé oblíbené"
+
+#: controllers/collections_controller.php:138
+msgid "collections_index_li_mine"
+msgstr "Mé sbírky"
+
+#: controllers/collections_controller.php:132
+msgid "collections_index_li_popular"
+msgstr "Populární"
+
+#: views/search/collections.thtml:74 controllers/collections_controller.php:81
+msgid "collections_index_option_all"
+msgstr "Nejpopulárnější"
+
+#: views/search/collections.thtml:72 controllers/collections_controller.php:78
+msgid "collections_index_option_month"
+msgstr "Nejpopulárnější tento měsíc"
+
+#: views/search/collections.thtml:76 controllers/collections_controller.php:84
+msgid "collections_index_option_newest"
+msgstr "Nejnovější"
+
+#: views/search/collections.thtml:70 controllers/collections_controller.php:75
+msgid "collections_index_option_week"
+msgstr "Nejpopulárnější tento týden"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:67
+msgid "collections_index_p_collector"
+msgstr ""
+"Existuje nový způsob, jak spravovat a vyhledávat oblíbené doplňky. "
+"Komentujte, sdílejte a synchronizujte sbírky. VÅ¡e z vaÅ¡eho prohlížeÄe."
+
+#: views/elements/amo2009/collector_info_secondary.thtml:48
+msgid "collections_index_p_what_are"
+msgstr "Sbírky jsou skupiny podobných doplňků seskupených pro snadné sdílení."
+
+#. %s is a date in the _('date') format
+#: views/elements/collections_interactive_addon.thtml:85
+#, php-format
+msgid "collections_interactive_addon_added"
+msgstr "Přidáno %s"
+
+#: models/collection_promo.php:55
+msgid "collections_reference_tagline"
+msgstr "Doplňky mohou usnadnit vaše vyhledávání."
+
+#: models/collection_promo.php:55
+msgid "collections_reference_title"
+msgstr "Reference"
+
+#: models/collection_promo.php:52
+msgid "collections_social_tagline"
+msgstr "Doplňky mohou spravovat vaši sociální síť."
+
+#: models/collection_promo.php:52
+msgid "collections_social_title"
+msgstr "Sociální sítě"
+
+#: views/collections/subscribe.thtml:91
+msgid "collections_subscribe_button_close"
+msgstr "Zavřít"
+
+#: views/collections/subscribe.thtml:70
+msgid "collections_subscribe_error"
+msgstr ""
+"Při pokusu o přidání k oblíbené sbírce nastala chyba. Je tato sbírka "
+"stále oblíbená?"
+
+#: views/collections/subscribe.thtml:96
+msgid "collections_subscribe_label_bothersome"
+msgstr "Příště tuto zprávu nezobrazovat."
+
+#. %1$s is the collection name
+#: views/collections/subscribe.thtml:60
+msgid "collections_subscribe_success"
+msgstr "%1$s byl přidán do vašich oblíbených sbírek."
+
+#. %1$s is the link to the "My Favorites" tab on the main collections page
+#. %2$s is the localized title of the "My Favorites" tab
+#. %3$s is the link URL to the collector add-on
+#: views/collections/subscribe.thtml:62
+msgid "collections_subscribe_success_desc"
+msgstr ""
+"Tuto sbírku můžete nyní snadno nalézt v tomto adresáři na panelu <a href=\"%1$s\">%2$s</a> "
+"Pro ještě snadnější správu vašich oblíbených sbírek vyzkoušejte "
+"rozšíření <a href=\"%3$s\">Sbírky doplňků</a> pro Firefox."
+
+#: views/collections/listing.thtml:55
+msgid "collections_success_delete"
+msgstr "Sbírka byla smazána."
+
+#: models/collection_promo.php:54
+msgid "collections_travel_tagline"
+msgstr "Doplňky se mohou stát vašim cestovním agentem."
+
+#: models/collection_promo.php:54
+msgid "collections_travel_title"
+msgstr "Cestování"
+
+#. A collection of add-ons that is automatically built for a user. They are "automatically published" to this collection.
+#: controllers/collections_controller.php:581
+msgid "collections_type_autopublisher"
+msgstr "Automaticky publikované"
+
+#. A collection that has been chosen by an Editor as notable or exceptional
+#: controllers/collections_controller.php:582
+msgid "collections_type_editorspick"
+msgstr "Volba redaktora"
+
+#: controllers/collections_controller.php:580
+msgid "collections_type_normal"
+msgstr "Běžné"
+
+#: views/collections/subscribe.thtml:84
+msgid "collections_unsubscribe_error"
+msgstr ""
+"Při pokusu o odebrání sbírky z oblíbených nastala chyba. Byla tato "
+"sbírka mezi oblíbenými?"
+
+#. %1$s is the collection name
+#: views/collections/subscribe.thtml:78
+msgid "collections_unsubscribe_success"
+msgstr "Sbírka %1$s byla odebrána z vašich oblíbených sbírek."
+
+#: models/collection_promo.php:56
+msgid "collections_webdev_tagline"
+msgstr "Doplňky usnadňují vytváření perfektní webové stránky."
+
+#: models/collection_promo.php:56
+msgid "collections_webdev_title"
+msgstr "Vývoj pro web"
+
+#: views/elements/amo2009/collections_sidebar_whatare.thtml:40
+msgid "collections_whatare_header"
+msgstr "Co jsou sbírky?"
+
+#: views/elements/amo2009/collections_sidebar_whatare.thtml:45
+msgid "collections_whatare_learnmore"
+msgstr "PÅ™eÄtÄ›te si FAQ"
+
+#: views/elements/amo2009/collections_sidebar_whatare.thtml:44
+msgid "collections_whatare_text"
+msgstr ""
+"Existuje nový způsob, jak spravovat a vyhledávat oblíbené doplňky. "
+"Komentujte, sdílejte a synchronizujte sbírky. VÅ¡e z vaÅ¡eho prohlížeÄe."
+
+#: views/pages/collector_faq.thtml:61 views/pages/collector_features.thtml:67
+msgid "collector_features_a_home"
+msgstr "Domovská stránka Sbírky doplňků"
+
+#: views/elements/amo2009/collector_sidebar_download.thtml:46
+msgid "collector_features_heading_download"
+msgstr "Stáhnout sbírku doplňků:"
+
+#: views/elements/amo2009/collector_sidebar_download.thtml:43
+#: views/pages/collector_firstrun.thtml:116 views/pages/collector.thtml:69
+msgid "collector_features_img_logo"
+msgstr "Logo Sbírky doplňků"
+
+#: views/compatibility/dashboard.thtml:49
+#: controllers/compatibility_controller.php:72
+msgid "compatibility_dashboard_center_header"
+msgstr "Centrum kompatibility doplňků"
+
+#. %1$s is the name of an application and a version. Example: Firefox 3.0
+#. %2$s is the name of an application. Example: Firefox
+#: views/compatibility/dashboard.thtml:50
+msgid "compatibility_dashboard_intro"
+msgstr ""
+"Připravte se na vydání aplikace %1$s pomocí nástrojů a informací dostupných "
+"níže."
+
+#: views/compatibility/dashboard.thtml:103
+msgid "compatibility_dashboard_loading"
+msgstr "Nahrávání dat…"
+
+#: views/compatibility/dashboard.thtml:45
+msgid "compatibility_dashboard_main_link"
+msgstr "Návrat na titulní stránku"
+
+#: views/compatibility/dashboard.thtml:100 views/compatibility/report.thtml:43
+msgid "compatibility_dashboard_report"
+msgstr "Hlášení o&nbsp;kompatibilitě doplňků"
+
+#: views/compatibility/dashboard.thtml:53
+#: views/compatibility/dashboard.thtml:110
+#: views/compatibility/developers.thtml:43
+msgid "compatibility_developer_info"
+msgstr "Informace pro vývojáře doplňků"
+
+#: views/compatibility/developers.thtml:66
+msgid "compatibility_developers_adjust_maxversion"
+msgstr "Nastavit maxVersion bez nahrávání"
+
+#: views/compatibility/dashboard.thtml:124
+msgid "compatibility_developers_check_status"
+msgstr "Zkontrolovat stav svých doplňků"
+
+#. %1$s is a URL
+#. %2$s is an application and version. Example: Firefox 3.0
+#: views/compatibility/dashboard.thtml:126
+msgid "compatibility_developers_login_first"
+msgstr ""
+"Pokud máte na serveru doplňky Mozilly hostovány své doplňky, <a href=\"%1$s"
+"\">přihlašte se prosím</a> a zkontrolujte si stav svých doplňků pro aplikaci "
+"%2$s."
+
+#: views/compatibility/dashboard.thtml:114
+msgid "compatibility_developers_mdclogo_alt"
+msgstr "Logo vývojářského centra Mozilly"
+
+#: views/compatibility/developers.thtml:73
+msgid "compatibility_developers_no_addons"
+msgstr "Na serveru doplňky Mozilly nemáte hostované žádné doplňky."
+
+#: views/compatibility/dashboard.thtml:133
+#: views/compatibility/developers.thtml:55
+msgid "compatibility_developers_results"
+msgstr "Hlášení o&nbsp;kontrole stavu doplňků"
+
+#: views/compatibility/dashboard.thtml:137
+msgid "compatibility_developers_retrieving"
+msgstr "Získávání stavu hostovaných doplňků…"
+
+#. %1$s is a number
+#. %2$s is an application name
+#. %3$s is a number.
+#. Full example: 50 Firefox users (10% of total)
+#: views/compatibility/developers.thtml:65
+msgid "compatibility_developers_user_count"
+msgstr "%1$s uživatelů aplikace %2$s (%3$s&#37; celkem)"
+
+#: views/compatibility/report.thtml:45
+msgid "compatibility_report_detail_intro"
+msgstr ""
+"Níže uvedené doplňky tvoří dle měření Mozilly 95% nejvíce používaných "
+"doplňků a jsou seřazeny dle používanosti."
+
+#: views/compatibility/dashboard.thtml:94
+msgid "compatibility_report_detailed_link"
+msgstr "Zobrazit podrobné hlášení"
+
+#. %1$s and %2$s are numbers
+#. %3$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:65
+msgid "compatibility_report_intro"
+msgstr ""
+"%1$s doplňků pokrývá 95&#37; používanosti doplňků dle měření Mozilly. <b>%2"
+"$s&#37;</b> doplňků je v&nbsp;souÄasnosti považováno za kompatibilní s&nbsp;"
+"poslední verzí aplikace %3$s."
+
+#: views/compatibility/dashboard.thtml:81
+msgid "compatibility_report_legend_alpha"
+msgstr "Alfa verze"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:81
+msgid "compatibility_report_legend_alpha_description"
+msgstr "Doplňky kompatibilní s&nbsp;alfa verzemi aplikace %1$s"
+
+#: views/compatibility/dashboard.thtml:85
+msgid "compatibility_report_legend_beta"
+msgstr "Beta verze"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:85
+msgid "compatibility_report_legend_beta_description"
+msgstr "Doplňky kompatibilní s&nbsp;beta verzemi aplikace %1$s"
+
+#: views/compatibility/dashboard.thtml:89
+msgid "compatibility_report_legend_latest"
+msgstr "Poslední verze"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:89
+msgid "compatibility_report_legend_latest_description"
+msgstr "Doplňky kompatibilní s&nbsp;posledními verzemi aplikace %1$s"
+
+#: views/compatibility/dashboard.thtml:77
+msgid "compatibility_report_legend_other"
+msgstr "Jiné verze"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:77
+msgid "compatibility_report_legend_other_description"
+msgstr "Doplňky nekompatibilní s&nbsp;žádnou verzí aplikace %1$s"
+
+#: views/compatibility/dashboard.thtml:62
+msgid "compatibility_report_title"
+msgstr "Hlášení o&nbsp;kompatibilitě doplňků"
+
+#: views/compatibility/dashboard.thtml:54
+#: views/compatibility/dashboard.thtml:144 views/compatibility/users.thtml:42
+msgid "compatibility_user_info"
+msgstr "Informace pro uživatele doplňku"
+
+#: views/compatibility/dashboard.thtml:52
+msgid "compatibility_view_report"
+msgstr "Zobrazit hlášení o&nbsp;kompatibilitě"
+
+#. %s is a URL
+#: views/pages/credits.thtml:142
+#, php-format
+msgid "credits_contributing"
+msgstr "Více informací o&nbsp;přispívání naleznete na naší %s."
+
+#: views/pages/credits.thtml:142
+msgid "credits_contributing_wikipage"
+msgstr "wiki stránce"
+
+#: views/pages/credits.thtml:99
+msgid "credits_intro"
+msgstr ""
+"Mozilla děkuje následujícím lidem za jejich práci na projektu addons.mozilla."
+"org:"
+
+#: views/pages/credits.thtml:103
+msgid "credits_section_developers"
+msgstr "Vývojáři"
+
+#: views/pages/credits.thtml:115
+msgid "credits_section_editors"
+msgstr "Redaktoři"
+
+#: views/pages/credits.thtml:109
+msgid "credits_section_localizers"
+msgstr "Lokalizátoři"
+
+#: views/pages/credits.thtml:121
+msgid "credits_section_other_contributors"
+msgstr "Ostatní přispěvatelé"
+
+#: views/pages/credits.thtml:127
+msgid "credits_section_past_developers"
+msgstr "Bývalí vývojáři"
+
+#: views/pages/credits.thtml:133
+msgid "credits_section_software"
+msgstr "Software a obrázky"
+
+#: views/pages/credits.thtml:136
+msgid "credits_software_famfamfam"
+msgstr ""
+"NÄ›které z&nbsp;ikon pochází z&nbsp;balíÄku <a href=\"http://www.famfamfam."
+"com/lab/icons/silk/\">famfamfam Silk Icon</a>, licencovaného pod licencí <a "
+"href=\"http://creativecommons.org/licenses/by/2.5/\">Creative Commons "
+"Attribution 2.5</a>."
+
+#: views/pages/credits.thtml:137
+msgid "credits_software_timeplot"
+msgstr ""
+"Některé stránky používají technologii <a href=\"http://www.simile-widgets."
+"org/timeplot/\">Timeplot</a>, která je dostupná pod <a href=\"http://simile."
+"mit.edu/license.html\">licencí BSD</a>."
+
+#. date format string as used in PHP's strftime():
+#. http://php.net/strftime
+#: views/elements/collections_interactive_addon.thtml:85
+#: views/elements/amo2009/addon_version_detail.thtml:53
+#: views/elements/amo2009/homepage_addon.thtml:115
+#: views/elements/addon_version_detail.thtml:54
+#: views/elements/addon_listitem.thtml:124 views/elements/feature.thtml:106
+#: views/collections/detail.thtml:118 views/collections/edit.thtml:325
+#: views/users/info.thtml:76 views/editors/reviews_queue.thtml:57
+#: views/editors/reviews_queue.thtml:68 views/developers/dashboard.thtml:65
+#: views/developers/versions_edit.thtml:208 views/developers/versions.thtml:67
+#: views/search/rss/index.thtml:5 views/addons/rss/versions.thtml:42
+#: views/addons/display.thtml:104 views/addons/display.thtml:356
+#: views/addons/browse_thumbs.thtml:75 views/reviews/add.thtml:63
+#: views/reviews/display.thtml:74 views/reviews/display.thtml:160
+#: views/reviews/delete.thtml:54 controllers/statistics_controller.php:244
+#: controllers/collections_controller.php:1047
+msgid "date"
+msgstr "%e. %B %Y"
+
+#. date and time format string (strftime)
+#. http://php.net/strftime
+#: views/elements/addon_version_detail.thtml:53
+#: views/developers/discuss.thtml:52 views/developers/discuss.thtml:62
+#: views/admin/addons_status.thtml:57
+msgid "datetime"
+msgstr "%e. %B %Y, %H.%M"
+
+#: views/elements/developers/actionbar.thtml:47
+msgid "devcp_actionbar_link_details"
+msgstr "Více informací"
+
+#: views/elements/developers/actionbar.thtml:42
+#: views/elements/developers/actionbar.thtml:50
+#: views/developers/dashboard.thtml:64
+msgid "devcp_actionbar_link_edit"
+msgstr "Úpravy doplňku"
+
+#: views/elements/developers/actionbar.thtml:51
+msgid "devcp_actionbar_link_newversion"
+msgstr "Nahrát novou verzi"
+
+#: views/elements/developers/actionbar.thtml:44
+#: views/elements/developers/actionbar.thtml:49
+#: views/developers/dashboard.thtml:73
+msgid "devcp_actionbar_link_stats"
+msgstr "Stránka statistik"
+
+#. %1$s is a filename, e.g. "foo.txt"
+#. %2$s is the extension, e.g. ".txt"
+#. %3$s is a list of valid extensions, like ".png, .jpg, .gif"
+#: controllers/developers_controller.php:1361
+msgid "devcp_add_previews_extension_error"
+msgstr "Soubor %1$s má neplatnou příponu (%2$s). Povolené přípony jsou: %3$s"
+
+#. %s is the filename.
+#: controllers/developers_controller.php:1394
+msgid "devcp_add_previews_save_error"
+msgstr "Soubor %s se nepodařilo uložit do databáze. Zkuste to prosím znova."
+
+#. %1$s is the preview ID number, %2$s is the filename.
+#: controllers/developers_controller.php:1389
+msgid "devcp_add_previews_success_replace"
+msgstr "Náhled %1$s byl úspěšně nahrazen souborem %2$s."
+
+#. %s is the filename.
+#: controllers/developers_controller.php:1391
+msgid "devcp_add_previews_success_upload"
+msgstr "Soubor %s byl úspěšně nahrán. Nyní můžete přidat popisek."
+
+#: controllers/components/developers.php:1163
+msgid "devcp_additem_addontype_autodetect"
+msgstr "(urÄit automaticky)"
+
+#: views/elements/developers/additem.thtml:76
+msgid "devcp_additem_linktitle_opensin_newwindow"
+msgstr "Otevřít v&nbsp;novém okně"
+
+#: views/elements/developers/additem.thtml:41
+msgid "devcp_additem_sidebar_title"
+msgstr "Přidání doplňku"
+
+#: views/elements/developers/additem.thtml:53
+msgid "devcp_additem_step0_newlink"
+msgstr "Souhlas vývojáře"
+
+#: views/elements/developers/additem.thtml:46
+msgid "devcp_additem_step1_link"
+msgstr "Krok 1: Nahrání souboru"
+
+#: views/elements/developers/additem.thtml:47
+msgid "devcp_additem_step2_link"
+msgstr "Krok 2: Informace o&nbsp;doplňku"
+
+#: views/elements/developers/additem.thtml:48
+msgid "devcp_additem_step3_link"
+msgstr "Krok 3: Informace o&nbsp;verzi"
+
+#: views/elements/developers/additem.thtml:49
+msgid "devcp_additem_step4_link"
+msgstr "Krok 4: Lokalizace"
+
+#: views/elements/developers/additem.thtml:50
+msgid "devcp_additem_step5_link"
+msgstr "Krok 5: Hotovo"
+
+#: views/elements/developers/additem.thtml:76
+msgid "devcp_additem_submissionhelp_link"
+msgstr "Nápověda přidání doplňku"
+
+#: controllers/previews_controller.php:168
+#: controllers/previews_controller.php:277
+msgid "devcp_addon_field_preview_caption_displaytitle"
+msgstr "Ukázka záhlaví"
+
+#: views/developers/addon_status.thtml:177
+msgid "devcp_addon_status_action_activate"
+msgstr "Aktivovat"
+
+#: views/developers/addon_status.thtml:178
+msgid "devcp_addon_status_action_activate_description"
+msgstr ""
+"Po aktivaci se bude doplněk zobrazovat ve veřejně dostupných výpisech a bude "
+"povolena jeho aktualizaÄní služba."
+
+#: views/developers/addon_status.thtml:135
+msgid "devcp_addon_status_action_complete"
+msgstr "DokonÄit doplnÄ›k"
+
+#: views/developers/addon_status.thtml:136
+msgid "devcp_addon_status_action_complete_description"
+msgstr "DokonÄený doplnÄ›k se pÅ™esune na pískoviÅ¡tÄ›."
+
+#: views/developers/addon_status.thtml:181
+msgid "devcp_addon_status_action_deactivate"
+msgstr "Deaktivovat"
+
+#: views/developers/addon_status.thtml:182
+msgid "devcp_addon_status_action_deactivate_description"
+msgstr ""
+"Po deaktivaci se přestane doplněk zobrazovat ve veřejně dostupných výpisech "
+"a bude zakázána jeho aktualizaÄní služba."
+
+#: views/developers/addon_status.thtml:143
+msgid "devcp_addon_status_action_move"
+msgstr "Přesunout na pískoviště"
+
+#: views/developers/addon_status.thtml:144
+msgid "devcp_addon_status_action_move_description"
+msgstr "Doplněk bude přesunut zpět na pískoviště. Tato operace je vratná."
+
+#: views/developers/addon_status.thtml:139
+msgid "devcp_addon_status_action_nominate"
+msgstr "Nominovat ke zveřejnění"
+
+#: views/developers/addon_status.thtml:140
+msgid "devcp_addon_status_action_nominate_description"
+msgstr "Nominujte svůj doplněk ke zveřejnění."
+
+#: views/developers/addon_status.thtml:147
+msgid "devcp_addon_status_action_public"
+msgstr "Zveřejnit"
+
+#: views/developers/addon_status.thtml:148
+msgid "devcp_addon_status_action_public_description"
+msgstr "Doplněk bude opět zveřejněn."
+
+#: views/developers/addon_status.thtml:169
+msgid "devcp_addon_status_active"
+msgstr ""
+"Doplněk je <span class=\"inactive-0\">aktivní</span>. Doplněk se zobrazuje "
+"ve všech seznamech odpovídajících jeho stavu výše."
+
+#: views/developers/addon_status.thtml:111
+msgid "devcp_addon_status_completion_disabled"
+msgstr ""
+"PÅ™ed dokonÄením doplňku a jeho pÅ™esunem na <span class=\"status-1"
+"\">pískoviště</span> splňte prosím výše uvedené požadavky."
+
+#: views/developers/addon_status.thtml:108
+msgid "devcp_addon_status_completion_enabled"
+msgstr ""
+"Klepnutím na tlaÄítko níže můžete svůj doplnÄ›k dokoÄit a pÅ™esunout jej na "
+"<span class=\"status-1\">pískoviště</span>."
+
+#: views/developers/addon_status.thtml:102
+msgid "devcp_addon_status_criteria_category"
+msgstr "Musí být zvolena nejméně jedna kategorie"
+
+#: views/developers/addon_status.thtml:101
+msgid "devcp_addon_status_criteria_description"
+msgstr "Je vyžadován popis doplňku"
+
+#: views/developers/addon_status.thtml:99
+msgid "devcp_addon_status_criteria_name"
+msgstr "Je vyžadován název doplňku"
+
+#: views/developers/addon_status.thtml:120
+msgid "devcp_addon_status_criteria_prerelease"
+msgstr "DoplnÄ›k není ozanÄen jako kandidát na vydání."
+
+#: views/developers/addon_status.thtml:119
+msgid "devcp_addon_status_criteria_preview"
+msgstr "Pro rozšíření a motivy vzhledu je vyžadován alespoň jeden náhled."
+
+#: views/developers/addon_status.thtml:100
+msgid "devcp_addon_status_criteria_summary"
+msgstr "Je vyžadován struÄný popis doplňku"
+
+#. %s is the status in a span, e.g. "<span>_('Public')</span>".
+#: views/developers/addon_status.thtml:58
+msgid "devcp_addon_status_header"
+msgstr "Stav doplňku: %s"
+
+#: views/developers/addon_status.thtml:152
+#: views/developers/addon_status.thtml:173
+msgid "devcp_addon_status_header_actions"
+msgstr "Dostupné akce"
+
+#: views/developers/addon_status.thtml:168
+msgid "devcp_addon_status_header_active"
+msgstr "Stav aktivity doplňku: <span class=\"inactive-0\">aktivní</span>"
+
+#: views/developers/addon_status.thtml:97
+msgid "devcp_addon_status_header_criteria"
+msgstr "Kritéria pro dokonÄení doplňku"
+
+#: views/developers/addon_status.thtml:164
+msgid "devcp_addon_status_header_inactive"
+msgstr "Stav aktivity doplňku: <span class=\"inactive-1\">není aktivní</span>"
+
+#: views/developers/addon_status.thtml:117
+msgid "devcp_addon_status_header_nomination"
+msgstr "Kritéria pro nominaci ke zveřejnění"
+
+#: views/developers/addon_status.thtml:190
+msgid "devcp_addon_status_header_trusted"
+msgstr "Důvěryhodnost doplňku: <span class=\"status-4\">důvěryhodný</span>"
+
+#: views/developers/addon_status.thtml:165
+msgid "devcp_addon_status_inactive"
+msgstr ""
+"Doplněk <span class=\"inactive-1\">není aktivní</span> a proto se "
+"nezobrazuje ve žádném seznamu bez ohledu na jeho stav výše. Aktualizace "
+"doplňku <b>nejsou</b>pomocí aktualizaÄní služby poskytovány."
+
+#: views/developers/addon_status.thtml:128
+msgid "devcp_addon_status_nominate_disabled"
+msgstr ""
+"Před nominací doplňku ke <span class=\"status-4\">zveřejnění</span> splňte "
+"prosím výše uvedené požadavky."
+
+#: views/developers/addon_status.thtml:125
+msgid "devcp_addon_status_nominate_enabled"
+msgstr ""
+"Klepnutím na tlaÄítko níže můžete svůj doplnÄ›k nominovat ke <span class="
+"\"status-4\">zveřejnění</span>."
+
+#: views/developers/addon_status.thtml:64
+msgid "devcp_addon_status_public"
+msgstr "veřejný"
+
+#: views/developers/addon_status.thtml:63
+msgid "devcp_addon_status_sandbox"
+msgstr "Pískoviště"
+
+#. %s is an email address.
+#: views/developers/addon_status.thtml:89
+msgid "devcp_addon_status_switch_disabled"
+msgstr ""
+"Doplněk je <span class=\"status-5\">zakázán</span> administrátorem a proto "
+"ho nelze používat. Pokud máte dotaz, zašlete ho prosím na e-mail %s."
+
+#: views/developers/addon_status.thtml:67
+msgid "devcp_addon_status_switch_incomplete"
+msgstr ""
+"Doplněk je <span class=\"status-0\">nekompletní</span> a proto se "
+"nezobrazuje v žádné Äásti stránek a je zakázána jeho aktualizaÄní služba. "
+"Pokud splníte kritéria pro jeho dokonÄení a pÅ™esun na <span class=\"status-1"
+"\">pískoviÅ¡tÄ›</span> můžete ho na této stránce dokonÄit."
+
+#. %s is a number, perhaps 42.
+#: views/developers/addon_status.thtml:77
+msgid "devcp_addon_status_switch_nominated"
+msgstr ""
+"DoplnÄ›k je nominován ke <span class=\"status-4\">zveÅ™ejnÄ›ní</span> a Äeká na "
+"kontrolu redaktora. V nominaÄní frontÄ› je v&nbsp;souÄasnosti %s dalších "
+"doplňků."
+
+#. %s is an email address.
+#: views/developers/addon_status.thtml:81
+msgid "devcp_addon_status_switch_pending"
+msgstr ""
+"DoplnÄ›k je Äekající. Tato situace by nemÄ›la nastat. PoÅ¡lete nám prosím na "
+"adresu %s e-mail s&nbsp;Id doplňku a informujte nás o&nbsp;této chybě."
+
+#: views/developers/addon_status.thtml:85
+msgid "devcp_addon_status_switch_public"
+msgstr ""
+"Doplněk je <span class=\"status-4\">veřejný</span> a proto se zobrazuje ve "
+"veřejně dostupných výpisech a lze ho bez omezení stáhnout. Jeho aktualizace "
+"jsou poskytovány pomocí aktualizaÄní služby."
+
+#: views/developers/addon_status.thtml:71
+#: views/developers/addon_status.thtml:75
+msgid "devcp_addon_status_switch_sandbox"
+msgstr ""
+"Doplněk je na <span class=\"status-1\">pískovišti</span> a proto se "
+"zobrazuje ve veřejně dostupných výpisech, ale pro jeho stažení se musí "
+"uživatelé přihlásit. Jeho aktualizace <b>nejsou</b> poskytovány pomocí "
+"aktualizaÄní služby."
+
+#. %s is the add-on name.
+#: views/developers/addon_status_nominate.thtml:43
+#: views/developers/addon_status_confirm.thtml:43
+#: views/developers/addon_status.thtml:43
+msgid "devcp_addon_status_title"
+msgstr "Stav doplňku %s "
+
+#: views/developers/addon_status.thtml:191
+msgid "devcp_addon_status_trusted"
+msgstr ""
+"Doplněk je <span class=\"status-4\">důvěryhodný</span> a proto můžete "
+"nahrávat jeho aktualizace bez kontroly redaktora."
+
+#: views/developers/dashboard.thtml:68
+msgid "devcp_dashboard_active"
+msgstr "aktivní"
+
+#. %1$s is the add-on type string
+#. %2$s is Inactive or Active in a <span>
+#. %3$s is the addon's public status (Public, In Sandbox, ...) in a <span>
+#: views/developers/dashboard.thtml:69
+msgid "devcp_dashboard_addontype_status"
+msgstr "Typ doplňku: %1$s&nbsp;·&nbsp;Stav doplňku: %2$s a %3$s"
+
+#: views/developers/dashboard.thtml:67
+msgid "devcp_dashboard_change_status"
+msgstr "Změna stavu"
+
+#. %s is the addons email address.
+#: views/developers/dashboard.thtml:99
+msgid "devcp_dashboard_disabled_questions"
+msgstr ""
+"Doplněk je zakázán administrátorem a proto ho nelze používat. Pokud máte "
+"dotaz, zašlete ho prosím na e-mail %s."
+
+#. %s is the (localized) add-on status string in a span, e.g. "Disabled"
+#: views/developers/dashboard.thtml:98
+msgid "devcp_dashboard_disabled_status"
+msgstr "Stav doplňku: %s"
+
+#: views/developers/dashboard.thtml:43
+msgid "devcp_dashboard_header_main"
+msgstr "Nástěnka vývojáře"
+
+#: views/developers/dashboard.thtml:110
+msgid "devcp_dashboard_header_welcome"
+msgstr "Vítejte na vývojářově nástěnce"
+
+#: views/developers/dashboard.thtml:68
+msgid "devcp_dashboard_inactive"
+msgstr "Deaktivován"
+
+#. %s is a date in the _('date') format
+#: views/developers/dashboard.thtml:65
+msgid "devcp_dashboard_last_edited"
+msgstr "Naposledy upraveno: %s"
+
+#: views/developers/dashboard.thtml:111
+msgid "devcp_dashboard_learn"
+msgstr ""
+"V souÄasnosti nemáte na serveru doplňky Mozilly žádné vlastní doplňky. Pokud "
+"chcete nahrát svůj první doplnÄ›k, klepnÄ›te na tlaÄítko ZaÄít níže."
+
+#: views/developers/dashboard.thtml:112
+msgid "devcp_dashboard_start"
+msgstr "ZaÄít"
+
+#: views/developers/dashboard.thtml:82
+msgid "devcp_dashboard_versions"
+msgstr "Verze a soubory"
+
+#: views/developers/dashboard.thtml:91
+msgid "devcp_dashboard_versions_new"
+msgstr "Nahrání nové verze"
+
+#. %s is the preview ID number.
+#: controllers/developers_controller.php:1415
+msgid "devcp_delete_previews_error"
+msgstr ""
+"Náhled %s se nepodařilo smazat z&nbsp;databáze. Zkuste to prosím znova."
+
+#. %s is the preview ID number.
+#: controllers/developers_controller.php:1413
+msgid "devcp_delete_previews_success"
+msgstr "Náhled %s byl úspěšně smazán."
+
+#: controllers/developers_controller.php:1089
+msgid "devcp_delete_version_priv_error"
+msgstr "Namáte dostateÄná oprávnÄ›ní mazat verze nebo soubory."
+
+#. %1$s is the count of files, a number
+#. %2$s is a status string like _('Public') or _('Incomplete')
+#: controllers/components/amo.php:549
+msgid "devcp_describe_version_status"
+msgid_plural "devcp_describe_version_status"
+msgstr[0] "%1$s soubor ve stavu %2$s"
+msgstr[1] "%1$s soubory ve stavu %2$s"
+msgstr[2] "%1$s souborů ve stavu %2$s"
+
+#. %s is a version number. Example: 3.0
+#: views/developers/versions.thtml:65
+#, php-format
+msgid "devcp_details_version"
+msgstr "Verze %s"
+
+#: views/developers/discuss.thtml:68
+msgid "devcp_discuss_addreply_header"
+msgstr "Odpovědět"
+
+#: views/developers/discuss.thtml:57
+msgid "devcp_discuss_allreplies_header"
+msgstr "Odpovědi"
+
+#. notice when an error occurs saving a discussion reply
+#. %1 is the email address (linked) for the amo-editors list
+#: views/developers/discuss.thtml:70
+msgid "devcp_discuss_error_notice"
+msgstr ""
+"Uložení odpovědi se nezdařilo. Kontaktujte prosím %1$s a nahlšte tento "
+"problém."
+
+#. %1 is the add-on name, %2 is the add-on's version number currently being reviewed by an editor
+#: views/developers/discuss.thtml:46
+msgid "devcp_discuss_intro"
+msgstr ""
+"Redaktor serveru doplňky Mozilly požaduje dodateÄné informace ohlednÄ› verze %"
+"2$s vašeho doplňku %1$s."
+
+#. %1 is the add-on name
+#: views/developers/discuss.thtml:43
+msgid "devcp_discuss_pagetitle"
+msgstr "Kvůli kontrole doplňku %1$s je požadováno více informací"
+
+#. submit button text
+#: views/developers/discuss.thtml:79
+msgid "devcp_discuss_submit_reply"
+msgstr "Odeslat odpovÄ›Ä"
+
+#: views/developers/discuss.thtml:72
+msgid "devcp_discuss_success_message"
+msgstr ""
+"VaÅ¡e odpovÄ›Ä byla úspěšnÄ› uložena. Ostatní úÄastníci diskuze budou "
+"informování e-mailem."
+
+#. in an author/editor discussion about an add-on to be reviewed:
+#. %1 is the commenter's user name (linked).
+#. %2 is the full date the comment was made.
+#: views/developers/discuss.thtml:52 views/developers/discuss.thtml:62
+msgid "devcp_discuss_writtenby"
+msgstr "napsáno %1$s dne %2$s"
+
+#: views/developers/addon_edit_authors.thtml:72
+#: views/developers/addon_edit_authors.thtml:81
+msgid "devcp_edit_authors_add_author"
+msgstr "Přidat nového autora"
+
+#: views/developers/addon_edit_authors.thtml:96
+msgid "devcp_edit_authors_add_author_button"
+msgstr "Přidat autora"
+
+#: views/developers/addon_edit_authors.thtml:83
+msgid "devcp_edit_authors_add_email"
+msgstr "E-mail úÄtu autora:"
+
+#: views/developers/addon_edit_authors.thtml:98
+msgid "devcp_edit_authors_add_loading"
+msgstr "Kontrola e-mailu úÄtu…"
+
+#: views/developers/addon_edit_authors.thtml:70
+msgid "devcp_edit_authors_click_save"
+msgstr "Pro uložení klepnÄ›te na tlaÄítko Aktualizovat autory."
+
+#: views/developers/addon_edit_authors.thtml:58
+msgid "devcp_edit_authors_header_current"
+msgstr "SouÄasní autoÅ™i"
+
+#: views/developers/addon_edit_authors.thtml:50
+msgid "devcp_edit_authors_header_manage"
+msgstr "Správa autorů doplňku"
+
+#: views/developers/addon_edit_authors.thtml:93
+msgid "devcp_edit_authors_label_add_listed"
+msgstr "Zobrazit autora na veřejných stránkách"
+
+#: views/developers/addon_edit_authors.thtml:89
+msgid "devcp_edit_authors_label_developer"
+msgstr ""
+"<strong>Vývojář</strong> - Může spravovat vše kolem seznamů doplňku mimo "
+"přidávání a odebírání dalších autorů."
+
+#: views/developers/addon_edit_authors.thtml:88
+msgid "devcp_edit_authors_label_owner"
+msgstr ""
+"<strong>Vlastník</strong> - Může spravovat vÅ¡e kolem seznamů doplňku vÄetnÄ› "
+"přidávání a odebírání dalších autorů."
+
+#: views/developers/addon_edit_authors.thtml:90
+msgid "devcp_edit_authors_label_viewer"
+msgstr ""
+"<strong>Pozorovatel</strong> - Může prohlížet vývojářské seznamy a "
+"statistiky doplňku, ale nemůže nic měnit."
+
+#. Placeholder for the empty option in a <select>.
+#: views/developers/addon_edit_categories.thtml:69
+msgid "devcp_edit_authors_option_empty"
+msgstr "----------------"
+
+#: views/developers/addon_edit_authors.thtml:86
+msgid "devcp_edit_authors_select_role"
+msgstr "Zvolte roli autora:"
+
+#. Column name in a table.
+#: views/developers/addon_edit_authors.thtml:62
+msgid "devcp_edit_authors_th_author"
+msgstr "Autor"
+
+#. Column name in a table.
+#: views/developers/addon_edit_authors.thtml:64
+msgid "devcp_edit_authors_th_listed"
+msgstr "Zobrazení"
+
+#. Column name in a table.
+#: views/developers/addon_edit_authors.thtml:63
+msgid "devcp_edit_authors_th_role"
+msgstr "Role"
+
+#: views/developers/addon_edit_authors.thtml:77
+msgid "devcp_edit_authors_update_author"
+msgstr "Aktualizovat autory"
+
+#: views/developers/addon_edit_categories.thtml:99
+msgid "devcp_edit_categories_button_update"
+msgstr "Aktualizovat kategorie"
+
+#: views/developers/addon_edit_categories.thtml:88
+msgid "devcp_edit_categories_does_not_fit"
+msgstr "Můj doplněk se nehodí do žádné z&nbsp;dostupných kategorií."
+
+#. %s is the application name (Firefox, Thunderbird).
+#: views/developers/addon_edit_categories.thtml:61
+msgid "devcp_edit_categories_header_application"
+msgstr "Kategorie aplikace %s"
+
+#: views/developers/addon_edit_categories.thtml:49
+msgid "devcp_edit_categories_header_manage"
+msgstr "Správa kategorií doplňku"
+
+#: views/developers/addon_edit_categories.thtml:91
+msgid "devcp_edit_categories_hover"
+msgstr "Pro zobrazení popisu kategorie najeÄte myší nad její název."
+
+#. %s is the category number (1, 2, 3).
+#: views/developers/addon_edit_categories.thtml:67
+msgid "devcp_edit_categories_label_category_num"
+msgstr "Kategorie %s"
+
+#: views/developers/addon_edit_categories.thtml:94
+#: views/developers/addon_edit_categories.thtml:103
+msgid "devcp_edit_categories_none_available"
+msgstr "Pro tento typ doplňku a aplikaci nejsou dostupné žádné kategorie."
+
+#: views/developers/addon_edit_categories.thtml:86
+msgid "devcp_edit_categories_other"
+msgstr ""
+"Tuto kategorii vyberte pouze tehdy pokud doplněk nelze umístit do jiné "
+"kategorie."
+
+#. %s is the application name (Firefox, Thunderbird).
+#: views/developers/addon_edit_categories.thtml:63
+msgid "devcp_edit_categories_select_application_categories"
+msgstr "Pro svůj doplněk vyberte až tři kategorie aplikace %s"
+
+#: views/developers/addon_edit.thtml:47
+msgid "devcp_edit_dd_manage_authors"
+msgstr "Přidání nebo odebrání uživatelů, kteří smí spravovat tento doplněk."
+
+#: views/developers/addon_edit.thtml:49
+msgid "devcp_edit_dd_manage_categories"
+msgstr "Volba odpovídajících kategorií pro doplňkem podporované aplikace."
+
+#: views/developers/addon_edit.thtml:51
+msgid "devcp_edit_dd_manage_description"
+msgstr ""
+"PÅ™idání nebo zmÄ›na pÅ™ekladu struÄného popisu, popisu, licence pro koncové "
+"uživatele a zásad ochrany soukromí."
+
+#: views/developers/addon_edit.thtml:53
+msgid "devcp_edit_dd_manage_properties"
+msgstr "Změna názvu, domovské stránky, ikony a dalších příznaků doplňku."
+
+#: views/developers/addon_edit_descriptions.thtml:116
+msgid "devcp_edit_description_button_update"
+msgstr "Aktualizovat popis"
+
+#: views/developers/addon_edit_descriptions.thtml:115
+msgid "devcp_edit_description_correct_error"
+msgstr "Opravte prosím výše uvedené ÄervenÄ› vyznaÄené chyby."
+
+#: views/developers/addon_edit_descriptions.thtml:51
+msgid "devcp_edit_descriptions_header"
+msgstr "Úprava popisu doplňku"
+
+#: views/developers/addon_edit_descriptions.thtml:94
+msgid "devcp_edit_descriptions_transbox_comments_description"
+msgstr ""
+"Jakékoliv informace pro koncové uživatele, které se nehodí do struÄného "
+"popisu nebo popisu doplňku. Lze zde například uvádět seznam známých hlavních "
+"chyb, informace o&nbsp;hlášení chyb, oÄekávané datum vydání nové verze, atd. "
+
+#: views/developers/addon_edit_descriptions.thtml:93
+msgid "devcp_edit_descriptions_transbox_comments_name"
+msgstr "Komentáře vývojáře"
+
+#: views/developers/addon_edit_descriptions.thtml:86
+msgid "devcp_edit_descriptions_transbox_description_description"
+msgstr ""
+"Popis doplňku je delší vysvětlení jeho vlastností, funkcí a dalších "
+"odpovídajících informací. Zobrazuje se pod struÄným popisem na stránce "
+"doplňku."
+
+#: views/developers/addon_edit_descriptions.thtml:85
+msgid "devcp_edit_descriptions_transbox_description_name"
+msgstr "Popis doplňku"
+
+#: views/developers/addon_edit_descriptions.thtml:103
+msgid "devcp_edit_descriptions_transbox_eula_description"
+msgstr ""
+"Pokud má doplnÄ›k obsahovat LicenÄní smlouvu s&nbsp;koncovým uživatelem "
+"(EULA), vložte její text níže. Pokud bude smlouva vložena, budou ji "
+"uživatelé muset odsouhlasit před instalací doplňku. Berte prosím na vědomí, "
+"že EULA není to samé jako licence zdrojového kódu jako např.GPL nebo MPL."
+
+#: views/developers/addon_edit_descriptions.thtml:102
+msgid "devcp_edit_descriptions_transbox_eula_name"
+msgstr "LicenÄní smlouva s&nbsp;koncovým uživatelem"
+
+#: views/developers/addon_edit_descriptions.thtml:112
+msgid "devcp_edit_descriptions_transbox_privacy_description"
+msgstr ""
+"Pokud má doplněk obsahovat zásady ochrany soukromí, vložte jejich text níže. "
+"Na stránce doplňku pak bude zobrazen odkaz na tyto zásady."
+
+#: views/developers/addon_edit_descriptions.thtml:111
+msgid "devcp_edit_descriptions_transbox_privacy_name"
+msgstr "Zásady ochrany soukromí"
+
+#: views/developers/addon_edit_descriptions.thtml:78
+msgid "devcp_edit_descriptions_transbox_summary_description"
+msgstr ""
+"StruÄný popis doplňku je krátké vysvÄ›tlení jeho základních funkcí, které se "
+"zobrazuje ve výpisech hledání a veřejných seznamech, stejně jako v&nbsp;"
+"horní Äásti stránky doplňku. <strong>Popis je omezen na 250 znaků.</strong>"
+
+#: views/developers/addon_edit_descriptions.thtml:77
+msgid "devcp_edit_descriptions_transbox_summary_name"
+msgstr "Přehled doplňku"
+
+#: views/developers/addon_edit.thtml:46
+msgid "devcp_edit_dt_manage_authors"
+msgstr "Správa autorů doplňku"
+
+#: views/developers/addon_edit.thtml:48
+msgid "devcp_edit_dt_manage_categories"
+msgstr "Správa kategorií doplňku"
+
+#: views/developers/addon_edit.thtml:50
+msgid "devcp_edit_dt_manage_descriptions"
+msgstr "Správa popisu doplňku"
+
+#: views/developers/addon_edit.thtml:52
+msgid "devcp_edit_dt_manage_properties"
+msgstr "Správa vlastností doplňku"
+
+#: views/developers/addon_edit_properties.thtml:170
+msgid "devcp_edit_label_externalsoftware"
+msgstr "Tento doplněk vyžaduje externí software"
+
+#: views/developers/addon_edit_properties.thtml:205
+msgid "devcp_edit_label_locale_disambiguation"
+msgstr "DodateÄné lokalizaÄní informace"
+
+#: views/developers/addon_edit_properties.thtml:168
+msgid "devcp_edit_label_prerelease"
+msgstr "Toto je kandidát na vydání doplňku"
+
+#: views/developers/addon_edit_properties.thtml:169
+msgid "devcp_edit_label_sitespecific"
+msgstr "Toto je doplněk pro specifický server"
+
+#: views/developers/addon_edit_properties.thtml:202
+msgid "devcp_edit_label_target_locale"
+msgstr "Cílová lokalizace"
+
+#: views/developers/addon_edit_properties.thtml:212
+msgid "devcp_edit_properties_button_update"
+msgstr "Aktualizovat vlastnosti"
+
+#: views/developers/addon_edit_properties.thtml:198
+msgid "devcp_edit_properties_change_guid"
+msgstr "Změny provádějte pouze pokud rozumíte všem důsledkům."
+
+#: views/developers/addon_edit_properties.thtml:109
+msgid "devcp_edit_properties_current_icon"
+msgstr "Aktuální ikona"
+
+#: views/developers/addon_edit_properties.thtml:85
+msgid "devcp_edit_properties_default_locale"
+msgstr ""
+"Výchozí lokalizací dopňku je ta lAn add-on's default locale is the main "
+"locale in which translations must be present. If translations for your add-"
+"on's descriptions are unavailable in a user's selected language, they will "
+"fall back to this default locale."
+
+#: views/developers/addon_edit_properties.thtml:167
+msgid "devcp_edit_properties_flags"
+msgstr "Tyto příznaky se používají v&nbsp;filtrování a klasifikaci doplňků."
+
+#: views/developers/addon_edit_properties.thtml:174
+msgid "devcp_edit_properties_guid"
+msgstr ""
+"GUID doplňku ho jednoznaÄnÄ› urÄuje a nachází se v&nbsp;souboru install.rdf."
+"Po nahrání doplňku na server doplňky Mozilly již nelze GUID měnit."
+
+#: views/developers/addon_edit_properties.thtml:53
+msgid "devcp_edit_properties_header"
+msgstr "Úprava vlastností doplňku"
+
+#: views/developers/addon_edit_properties.thtml:186
+msgid "devcp_edit_properties_header_addon_type"
+msgstr "Typ doplňku"
+
+#: views/developers/addon_edit_properties.thtml:181
+msgid "devcp_edit_properties_header_admin_settings"
+msgstr "Administrátorské nastavení"
+
+#: views/developers/addon_edit_properties.thtml:84
+msgid "devcp_edit_properties_header_default_locale"
+msgstr "Výchozí lokalizace"
+
+#: views/developers/addon_edit_properties.thtml:166
+msgid "devcp_edit_properties_header_flags"
+msgstr "Příznaky doplňku"
+
+#: views/developers/addon_edit_properties.thtml:173
+#: views/developers/addon_edit_properties.thtml:197
+msgid "devcp_edit_properties_header_guid"
+msgstr "GUID doplňku"
+
+#: views/developers/addon_edit_properties.thtml:104
+msgid "devcp_edit_properties_header_icon"
+msgstr "Icona doplňku"
+
+#: views/developers/addon_edit_properties.thtml:159
+msgid "devcp_edit_properties_header_other_settings"
+msgstr "Ostatní nastavení"
+
+#. A header on the admin page to toggle trusted status.
+#: views/developers/addon_edit_properties.thtml:182
+msgid "devcp_edit_properties_header_trusted"
+msgstr "Důvěryhodný doplněk?"
+
+#: views/developers/addon_edit_properties.thtml:160
+msgid "devcp_edit_properties_header_view_source"
+msgstr "Zobrazit zdrojový kód online"
+
+#. %s is a comma-separated list of image extensions ".png, .jpg"
+#: views/developers/addon_edit_properties.thtml:106
+msgid "devcp_edit_properties_icon"
+msgstr ""
+"Ikona doplňku je malý obrázek, který se zobrazuje vedle názvu doplňku ve "
+"výpisech hledání, veÅ™ejných seznamech, stránce doplňku a v&nbsp;instalÄním "
+"dialogu doplňku. Velikost obrázku bude po nahrátí automaticky upravena na 32 "
+"x 32 bodů. Používejte prosím pouze následující formáty obrázků: %s"
+
+#: views/developers/addon_edit_properties.thtml:171
+msgid "devcp_edit_properties_label_binary"
+msgstr "Tento doplněk obsahuje binární komponenty"
+
+#: views/developers/addon_edit_properties.thtml:185
+msgid "devcp_edit_properties_label_not_trusted"
+msgstr "Nedůvěryhodný"
+
+#: views/developers/addon_edit_properties.thtml:184
+msgid "devcp_edit_properties_label_trusted"
+msgstr "Důvěryhodný"
+
+#: views/developers/addon_edit_properties.thtml:110
+msgid "devcp_edit_properties_new_icon"
+msgstr "Nová ikona"
+
+#: views/developers/addon_edit_properties.thtml:118
+msgid "devcp_edit_properties_remove_icon"
+msgstr "Odstranit ikonu"
+
+#: views/developers/addon_edit_properties.thtml:136
+msgid "devcp_edit_properties_transbox_homepage_description"
+msgstr ""
+"Pokud má doplňek vlastní domovskou stránku, vložte zde její adresu. Překlady "
+"adresy přidávejte pouze tehdy, pokud je stránka lokalizovaná i do dalších "
+"jazyků."
+
+#: views/developers/addon_edit_properties.thtml:135
+msgid "devcp_edit_properties_transbox_homepage_name"
+msgstr "Domovská stránka doplňku"
+
+#: views/developers/addon_edit_properties.thtml:79
+msgid "devcp_edit_properties_transbox_name_description"
+msgstr "Název doplňku se zobrazuje všude, kde je doplněk vypsán."
+
+#: views/developers/addon_edit_properties.thtml:78
+msgid "devcp_edit_properties_transbox_name_name"
+msgstr "Název doplňku"
+
+#: views/developers/addon_edit_properties.thtml:145
+msgid "devcp_edit_properties_transbox_supportemail_description"
+msgstr ""
+"Pokud máte zřízen e-mail pro podporu doplňku, vložte zde jeho adresu. "
+"Překlady adresy přidávejte pouze tehdy, pokud máte různé adresy pro různé "
+"jazyky."
+
+#: views/developers/addon_edit_properties.thtml:144
+msgid "devcp_edit_properties_transbox_supportemail_name"
+msgstr "E-mailová adresa podpory"
+
+#: views/developers/addon_edit_properties.thtml:154
+msgid "devcp_edit_properties_transbox_supporturl_description"
+msgstr ""
+"Pokud máte zřízenu stránku nebo fórum pro podporu doplňku, vložte zde její "
+"adreesu. Překlady adresy přidávejte pouze tehdy, pokud je stránka "
+"lokalizovaná i do dalších jazyků."
+
+#: views/developers/addon_edit_properties.thtml:153
+msgid "devcp_edit_properties_transbox_supporturl_name"
+msgstr "Stránka podpory"
+
+#: views/developers/addon_edit_properties.thtml:183
+msgid "devcp_edit_properties_trusted"
+msgstr "Důvěryhodné doplňky lze zveřejňovat bez kontroly redaktora."
+
+#. %s is href="..." and should stay in the <a> tag.
+#: views/developers/addon_edit_properties.thtml:119
+msgid "devcp_edit_properties_undelete"
+msgstr "Ikona bude smazána při uložení. <a %s>Zrušit?</a>"
+
+#: views/developers/addon_edit_properties.thtml:161
+msgid "devcp_edit_properties_view_source"
+msgstr ""
+"Přihlášení uživatelé mají možnost procházet zdrojový kód souborů doplňku."
+
+#: views/developers/addon_edit_properties.thtml:162
+msgid "devcp_edit_properties_view_source_allow"
+msgstr "Povolit online prohlížení zdrojového kódu"
+
+#: views/developers/addon_edit_properties.thtml:163
+msgid "devcp_edit_properties_view_source_do_not_allow"
+msgstr "Zakázat online prohlížení zdrojového kódu"
+
+#: views/elements/developers/editbox.thtml:46
+msgid "devcp_editbox_authors"
+msgstr "Autoři"
+
+#: views/elements/developers/editbox.thtml:47
+msgid "devcp_editbox_categories"
+msgstr "Kategorie"
+
+#: views/elements/developers/editbox.thtml:52
+msgid "devcp_editbox_change_status"
+msgstr "Změna stavu"
+
+#: views/elements/developers/editbox.thtml:48
+msgid "devcp_editbox_descriptions"
+msgstr "Popis"
+
+#: views/elements/developers/editbox.thtml:43
+msgid "devcp_editbox_edit_addon"
+msgstr "Úpravy doplňku"
+
+#: views/elements/developers/editbox.thtml:57
+msgid "devcp_editbox_new_version"
+msgstr "Nová verze"
+
+#: views/elements/developers/editbox.thtml:49
+msgid "devcp_editbox_properties"
+msgstr "Vlastnosti"
+
+#: views/elements/developers/editbox.thtml:60
+msgid "devcp_editbox_screenshots"
+msgstr "Náhledy"
+
+#: views/elements/developers/editbox.thtml:53
+msgid "devcp_editbox_statistics_dashboard"
+msgstr "Nástěnka statistik"
+
+#: views/elements/developers/editbox.thtml:54
+msgid "devcp_editbox_versions"
+msgstr "Verze a soubory"
+
+#: views/elements/developers/editbox.thtml:42
+msgid "devcp_editbox_view_listing"
+msgstr "Stránka doplňku"
+
+#: views/elements/developers/editorsmenu.thtml:59
+msgid "devcp_editorsqueue_featured"
+msgstr "Uváděné doplňky"
+
+#. %1 is the review count
+#: views/elements/developers/editorsqueue.thtml:42
+#: views/elements/developers/editorsmenu.thtml:56
+#, php-format
+msgid "devcp_editorsqueue_moderatedreviews"
+msgid_plural "devcp_editorsqueue_moderatedreviews"
+msgstr[0] "%s moderovaná recenze"
+msgstr[1] "%s moderované recenze"
+msgstr[2] "%s moderovaných recenzí"
+
+#. %1 is the nominated addons count
+#: views/elements/developers/editorsqueue.thtml:44
+#: views/elements/developers/editorsmenu.thtml:58
+#, php-format
+msgid "devcp_editorsqueue_nominated"
+msgid_plural "devcp_editorsqueue_nominated"
+msgstr[0] "%s nominovaný doplněk"
+msgstr[1] "%s nominované doplňky"
+msgstr[2] "%s nominovaných doplňků"
+
+#. %1 is the update count
+#: views/elements/developers/editorsqueue.thtml:43
+#: views/elements/developers/editorsmenu.thtml:57
+#, php-format
+msgid "devcp_editorsqueue_pendingupdates"
+msgid_plural "devcp_editorsqueue_pendingupdates"
+msgstr[0] "%s Äekající aktualizace"
+msgstr[1] "%s Äekající aktualizace"
+msgstr[2] "%s Äekajících aktualizací"
+
+#: controllers/statistics_controller.php:147
+#: controllers/statistics_controller.php:361
+#: controllers/previews_controller.php:108
+#: controllers/previews_controller.php:211
+#: controllers/previews_controller.php:312
+msgid "devcp_error_addon_access_denied"
+msgstr "K tomuto doplňku nemáte přístup."
+
+#. %s is a complete URL with the text from devcp_error_appversion_reference_link_text
+#. in the <a> tag. This should be fixed.
+#: controllers/components/developers.php:591
+#, php-format
+msgid "devcp_error_appversion_reference_link"
+msgstr "Více informací viz stránka %s."
+
+#. This is the link text in the <a> for devcp_error_appversion_reference_link. This
+#. should be fixed.
+#: controllers/components/developers.php:591
+msgid "devcp_error_appversion_reference_link_text"
+msgstr "platných verzí aplikace"
+
+#: views/developers/addon_edit_authors.thtml:76
+msgid "devcp_error_empty_authors"
+msgstr "Doplněk musí mít alespoň jednoho vlastníka."
+
+#. %1$s is the name of the file
+#: controllers/components/developers.php:658
+msgid "devcp_error_file_exists"
+msgstr ""
+"Tato verze doplňku již existuje. Pokud ji chcete nahradit, musíte nejdříve "
+"odstranit soubor %1$s."
+
+#. %1$s is a file extension. Example: .exe
+#. %2$s is a comma separated list of extensions. Example: .xpi, .jar
+#: controllers/components/developers.php:355
+#, php-format
+msgid "devcp_error_file_extension"
+msgstr ""
+"Přípona souboru (%s) není povolena pro tento typ doplňku. Použijte prosím "
+"jednu z&nbsp;následujících: %s"
+
+#: controllers/components/developers.php:64
+msgid "devcp_error_five_categories"
+msgstr "Nevolte prosím více než 5 kategorií."
+
+#: controllers/components/developers.php:526
+msgid "devcp_error_guid_application"
+msgstr "Id tohoto doplňku je již používáno aplikací."
+
+#: controllers/components/developers.php:337
+#: controllers/components/developers.php:389
+msgid "devcp_error_http_incomplete"
+msgstr "Nekompletní nahrání"
+
+#: controllers/components/developers.php:335
+#: controllers/components/developers.php:336
+#: controllers/components/developers.php:387
+#: controllers/components/developers.php:388
+msgid "devcp_error_http_maxupload"
+msgstr "PÅ™ekroÄena maximální velikost nahrávaného souboru"
+
+#: controllers/components/developers.php:338
+#: controllers/components/developers.php:390
+msgid "devcp_error_http_nofile"
+msgstr "Nebyl nahrán soubor"
+
+#. %1$s is a file extension. Example: .exe
+#. %2$s is a comma separated list of extensions. Example: .xpi, .jar
+#: controllers/components/developers.php:401
+#, php-format
+msgid "devcp_error_icon_extension"
+msgstr ""
+"Přípona souboru (%s) není povolena pro ikonu. Použijte prosím jednu z&nbsp;"
+"následujících: %s"
+
+#: controllers/developers_controller.php:504
+msgid "devcp_error_index_rdf_notfound"
+msgstr "Nebyl nalezen soubor install.rdf."
+
+#: controllers/components/developers.php:601
+msgid "devcp_error_install_manifest"
+msgstr "V souboru install.rdf byly nalezeny následujícící chyby:"
+
+#: controllers/developers_controller.php:1463
+msgid "devcp_error_invalid_addontype"
+msgstr "Id doplňku je neplatné: %s"
+
+#. %$1s is a version. Example: 3.1.1
+#. %$2s is an add-on name.
+#: controllers/components/developers.php:569
+#: controllers/components/developers.php:581
+#, php-format
+msgid "devcp_error_invalid_appversion"
+msgstr "Verze %s není platná pro aplikaci %s"
+
+#. %s is a string
+#: controllers/components/developers.php:521
+#, php-format
+msgid "devcp_error_invalid_guid"
+msgstr "Id doplňku je neplatné: %s"
+
+#. %$1s is a version. Example: 3.1.1
+#. %$2s is an add-on name.
+#: controllers/components/developers.php:572
+#, php-format
+msgid "devcp_error_invalid_minversion"
+msgstr "%s není platná verze pro %s: minimální verze nesmí obsahovat *"
+
+#: controllers/components/developers.php:536
+msgid "devcp_error_invalid_version"
+msgstr ""
+"Verze doplňku je neplatná: platné verze viz <a href=\"http://developer."
+"mozilla.org/en/docs/Toolkit_version_format\">specifikace</a>"
+
+#: controllers/components/developers.php:531
+msgid "devcp_error_invalid_version_spaces"
+msgstr "Verze doplňku je neplatná: verze nesmí obsahovat mezery."
+
+#. %s is an error message from the parser.
+#: controllers/components/developers.php:501
+#, php-format
+msgid "devcp_error_manifest_parse"
+msgstr "Pří zpracovávání souboru install.rdf nastaly následující chyby: %s"
+
+#: controllers/components/developers.php:373
+msgid "devcp_error_move_file"
+msgstr "Nelze přesunout soubor"
+
+#. %s is the name of a file
+#: controllers/components/developers.php:650
+#: controllers/components/developers.php:662
+#: controllers/components/developers.php:667
+#: controllers/components/developers.php:727
+#: controllers/components/developers.php:738
+#: controllers/components/developers.php:743
+#, php-format
+msgid "devcp_error_moving_file"
+msgstr "Při přesunu %s nastala chyba."
+
+#: controllers/components/developers.php:595
+msgid "devcp_error_mozilla_application"
+msgstr "Je nutné urÄit alespoň jednu platnou cílovou aplikaci Mozilla."
+
+#: controllers/components/developers.php:516
+msgid "devcp_error_no_guid"
+msgstr "V souboru install.rdf nabylo nalezeno Id doplňku."
+
+#: controllers/components/developers.php:287
+msgid "devcp_error_no_platform"
+msgstr "Nebyla zvolena platforma"
+
+#: controllers/components/developers.php:59
+msgid "devcp_error_one_category"
+msgstr "Zvolte prosím alespoň jednu kategorii."
+
+#: controllers/components/developers.php:92
+msgid "devcp_error_one_user"
+msgstr "Doplněk musí mít alespoň jednoho autora."
+
+#. %1$s is a file extension. Example: .exe
+#. %2$s is a comma separated list of extensions. Example: .xpi, .jar
+#: controllers/components/developers.php:1081
+#, php-format
+msgid "devcp_error_preview_extension"
+msgstr ""
+"Přípona souboru (%s) není povolena pro náhledy. Použijte prosím jednu z&nbsp;"
+"následujících: %s"
+
+#: controllers/components/developers.php:511
+msgid "devcp_error_updatekey"
+msgstr ""
+"Doplňky nesmí používat vlastní klÃ­Ä updateKey. Odstraňte prosím tuto položku "
+"a nahrání opakujte"
+
+#: controllers/components/developers.php:506
+msgid "devcp_error_updateurl"
+msgstr ""
+"Doplňky nesmí používat externí updateURL. Odstraňte prosím tuto položku ze "
+"souboru install.rdf a nahrání opakujte."
+
+#: controllers/developers_controller.php:465
+#: controllers/components/developers.php:271
+msgid "devcp_error_upload_file"
+msgstr "Nahrajte prosím soubor."
+
+#: views/developers/uploader.thtml:135
+msgid "devcp_input_upload_file"
+msgstr "Nahrát soubor"
+
+#: views/pages/js_constants.js.thtml:89
+msgid "devcp_js_a_cancel"
+msgstr "Zrušit"
+
+#: views/pages/js_constants.js.thtml:90
+msgid "devcp_js_add_email"
+msgstr "Vložte prosím e-mail úÄtu autora, kterého chcete pÅ™idat."
+
+#. alt text for a down-arrow image.
+#: views/pages/js_constants.js.thtml:81
+msgid "devcp_js_img_move_down"
+msgstr "Posune dolů"
+
+#. alt text for an up-arrow image.
+#: views/pages/js_constants.js.thtml:82
+msgid "devcp_js_img_move_up"
+msgstr "Posune nahoru"
+
+#: views/pages/js_constants.js.thtml:91
+msgid "devcp_js_img_remove_compat"
+msgstr "Odstranit kompatibilitu aplikace"
+
+#: views/pages/js_constants.js.thtml:86
+msgid "devcp_js_input_list_author"
+msgstr "Zobrazí autora ve veřejných seznamech"
+
+#: views/pages/js_constants.js.thtml:92
+msgid "devcp_js_license_select"
+msgstr "Zvolte prosím licenci."
+
+#: views/pages/js_constants.js.thtml:93
+msgid "devcp_js_license_text"
+msgstr "Vložte prosím text vaší licence."
+
+#. <option> text in a <select> for Author role in an add-on.
+#: views/pages/js_constants.js.thtml:84
+msgid "devcp_js_option_developer"
+msgstr "Vývojář"
+
+#. <option> text in a <select> for Author role in an add-on.
+#: views/pages/js_constants.js.thtml:83
+msgid "devcp_js_option_owner"
+msgstr "Vlastník"
+
+#. <option> text in a <select> for Author role in an add-on.
+#: views/pages/js_constants.js.thtml:85
+msgid "devcp_js_option_viewer"
+msgstr "Pozorovatel"
+
+#: views/pages/js_constants.js.thtml:88
+msgid "devcp_js_remove_author"
+msgstr "Odebere autora"
+
+#: views/pages/js_constants.js.thtml:87
+msgid "devcp_js_sure_remove"
+msgstr "<strong>Opravdu</strong> chcete odebrat tohoto autora?"
+
+#: views/pages/js_constants.js.thtml:77
+msgid "devcp_js_upload_alert"
+msgstr "Musíte vybrat soubor k nahrání."
+
+#. %1$s is an addon id, like 32.
+#. %2$s is a version number, like 3.5.
+#: controllers/components/developers.php:1212
+msgid "devcp_license_existing"
+msgstr "Vlastní licence pro doplněk %1$s v. %2$s"
+
+#: views/elements/developers/localebox.thtml:44
+msgid "devcp_localebox_header_localizedfields"
+msgstr "Položky lokalizace"
+
+#. %1 is the default locale
+#: views/elements/developers/localebox.thtml:48
+#, php-format
+msgid "devcp_localebox_intro"
+msgstr ""
+"Některé z&nbsp;položek na této stránce mohou být lokalizovány a zobrazovat "
+"se tak uživatelům v&nbsp;jejich mateřském jazyce. K&nbsp;úpravě detailů "
+"svého doplňku ve zvolené lokalizaci zvolte v&nbsp;nabídce odpovídající "
+"lokalizaci. Pokud není překlad pro danou lokalizaci dostupný, budou položky "
+"zobrazeny ve zvolené výchozí lokalizaci (%s)."
+
+#: views/elements/developers/sidebar.thtml:68
+#: views/elements/developers/myaddons.thtml:75
+msgid "devcp_myaddons_admincp_link"
+msgstr "Ovládací panel správce"
+
+#: views/elements/developers/sidebar.thtml:65
+#: views/elements/developers/myaddons.thtml:72
+msgid "devcp_myaddons_editorcp_link"
+msgstr "Ovládací panel redaktora"
+
+#: views/elements/developers/myaddons.thtml:52
+msgid "devcp_myaddons_link"
+msgstr "Mé doplňky"
+
+#: views/elements/developers/sidebar.thtml:70
+#: views/elements/developers/myaddons.thtml:77
+msgid "devcp_myaddons_mainpage_link"
+msgstr "Titulní stránka"
+
+#: views/elements/developers/sidebar.thtml:63
+#: views/elements/developers/myaddons.thtml:70
+msgid "devcp_myaddons_statistics_link"
+msgstr "Stránka statistik"
+
+#: views/elements/developers/sidebar.thtml:62
+#: views/elements/developers/myaddons.thtml:69
+msgid "devcp_myaddons_submitaddon_link"
+msgstr "Přidání doplňku"
+
+#: views/elements/developers/sidebar.thtml:48
+#: views/elements/developers/myaddons.thtml:67
+msgid "devcp_myaddons_title"
+msgstr "Nástroje vývojáře"
+
+#. %1$s is an add-on ID, perhaps 167.
+#. %2$s is a URL.
+#: controllers/developers_controller.php:256
+msgid "devcp_new_addon_error"
+msgstr ""
+"Toto Id doplňku (%1$s) již v&nbsp;databázi existuje. Pokud se jedná o&nbsp;"
+"váš doplňek, můžete <a href=\"%2$s\">nahrát novou verzi</a>."
+
+#: views/developers/addon_status_nominate.thtml:62
+msgid "devcp_nominate_cancel"
+msgstr "Zrušit a vrátit se"
+
+#. %1 is the add-on name
+#: views/developers/addon_status_nominate.thtml:61
+#, php-format
+msgid "devcp_nominate_submit_nominate"
+msgstr "Nominovat doplněk %s"
+
+#: views/developers/addon_edit_properties.thtml:50
+#: views/developers/addon_status.thtml:49
+#: views/developers/versions_edit.thtml:50
+msgid "devcp_notice_changes_error"
+msgstr ""
+"<span>Jedna nebo více provedených změn se nepodařilo uložit.</span><br /> "
+"Prohlédněte si prosím chyby níže. Zbylé změny byly úspěšně uloženy."
+
+#: views/developers/addon_edit_authors.thtml:47
+#: views/developers/addon_edit_properties.thtml:47
+#: views/developers/addon_status.thtml:46
+#: views/developers/addon_edit_descriptions.thtml:47
+#: views/developers/versions_edit.thtml:47
+#: views/developers/addon_edit_categories.thtml:46
+msgid "devcp_notice_changes_saved"
+msgstr ""
+"<span>Provedené změny byly uloženy.</span><br /> Berte prosím na vědomí, že "
+"projevení zmÄ›n v&nbsp;nÄ›kterých Äástech stránek může trvat až nÄ›kolik hodin."
+
+#: controllers/previews_controller.php:252
+msgid "devcp_notice_cleardefault"
+msgstr ""
+"Odstranění výchozího náhledu způsobí, že se další náhled automaticky stane "
+"výchozím náhledem."
+
+#: controllers/previews_controller.php:184
+#: controllers/previews_controller.php:251
+msgid "devcp_notice_makedefault"
+msgstr ""
+"Nastavením tohoto náhledu jako výchozí odstraníte příznak výchozí ze "
+"souÄasného výchozího náhledu."
+
+#: views/developers/addon_edit_authors.thtml:70
+msgid "devcp_notice_unsaved_changes"
+msgstr "Máte neuložené změny."
+
+#: controllers/developers_controller.php:87
+#: controllers/developers_controller.php:97
+#: controllers/developers_controller.php:100
+#: controllers/previews_controller.php:67
+#: controllers/previews_controller.php:79
+#: controllers/previews_controller.php:82
+msgid "devcp_pagetitle"
+msgstr "Ovládací panel vývojáře"
+
+#: controllers/previews_controller.php:103
+#: controllers/previews_controller.php:104
+msgid "devcp_preview_add_pagetitle"
+msgstr "Přidat náhled"
+
+#: controllers/previews_controller.php:135
+msgid "devcp_preview_added_successfully"
+msgstr "Náhled úspěšně přidán."
+
+#: controllers/previews_controller.php:323
+msgid "devcp_preview_deleted_successfully"
+msgstr "Náhled úspěšně smazán."
+
+#: controllers/previews_controller.php:194
+#: controllers/previews_controller.php:195
+msgid "devcp_preview_edit_pagetitle"
+msgstr "Úprava náhledu"
+
+#: controllers/previews_controller.php:237
+msgid "devcp_preview_updated_successfully"
+msgstr "Náhled úspěšně upraven."
+
+#: views/developers/previews.thtml:120
+msgid "devcp_previews_a_another"
+msgstr "Přidat jiný náhled"
+
+#: views/developers/previews.thtml:96
+msgid "devcp_previews_a_delete"
+msgstr "Smazat náhled"
+
+#: views/developers/previews.thtml:95
+msgid "devcp_previews_a_replace"
+msgstr "Nahradit náhled"
+
+#: views/developers/previews.thtml:126
+msgid "devcp_previews_a_update"
+msgstr "Aktualizovat náhledy"
+
+#: views/developers/previews.thtml:115 views/developers/previews.thtml:124
+msgid "devcp_previews_add_new"
+msgstr "Přidat nový náhled"
+
+#. %s is a list of file extensions, e.g. ".png, .gif"
+#: views/developers/previews.thtml:116
+msgid "devcp_previews_add_select"
+msgstr ""
+"Zvolte obrázek v&nbsp;nahrátí. Obrázky o&nbsp;velikosti větší než 700 bodů "
+"na šířku a 525 bodů na výšku budou zmenšeny. Povolené formáty obrázků jsou: %"
+"s"
+
+#: views/developers/previews.thtml:121
+msgid "devcp_previews_click_below"
+msgstr "Pro nahrání náhledu klepnÄ›te na tlaÄítko Aktualizovat náhledy."
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/previews.thtml:102
+msgid "devcp_previews_click_update"
+msgstr ""
+"Pro uložení tohoto obrázku klepnÄ›te na tlaÄítko Aktualizovat náhledy.(<a %"
+"s>Zrušit?</a>)"
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/previews.thtml:107
+msgid "devcp_previews_error_message"
+msgstr ""
+"Tento náhled bude po klepnutí na tlaÄítko Aktualizovat náhledy smazán.(<a %"
+"s>Zrušit?</a>)"
+
+#: views/previews/add.thtml:45
+msgid "devcp_previews_filetype_info"
+msgstr ""
+"Formulář níže lze použít pro nahrání náhledů doplňku ve formátech PNG, JPG "
+"nebo GIF. Obrázky širší než 700 bodů a vyšší něž 525 bodů budou automaticky "
+"zmenšeny."
+
+#: views/previews/add.thtml:43
+msgid "devcp_previews_header_add"
+msgstr "Přidat náhled"
+
+#: views/developers/previews.thtml:80
+msgid "devcp_previews_header_caption"
+msgstr "Legenda v&nbsp;náhledu"
+
+#: views/previews/edit.thtml:43
+msgid "devcp_previews_header_edit"
+msgstr "Úprava náhledu"
+
+#: views/developers/previews.thtml:93
+msgid "devcp_previews_label_default"
+msgstr "Výchozí náhled"
+
+#: views/previews/add.thtml:54
+msgid "devcp_previews_label_file"
+msgstr "Soubor náhledu"
+
+#: views/previews/add.thtml:59 views/previews/edit.thtml:50
+msgid "devcp_previews_label_makedefault"
+msgstr "Nastavit jako výchozí náhled"
+
+#: views/developers/previews.thtml:100
+msgid "devcp_previews_label_new"
+msgstr "Nový obrázek:"
+
+#: views/developers/previews.thtml:118
+msgid "devcp_previews_label_upload"
+msgstr "Nahrát náhled: "
+
+#: views/developers/previews.thtml:50
+msgid "devcp_previews_notice_error"
+msgstr "Jeden nebo více náhledů se nepodařilo uloži."
+
+#: views/developers/previews.thtml:47
+msgid "devcp_previews_notice_success"
+msgstr "Náhledy byly úspěšně aktualizovány."
+
+#: views/developers/previews.thtml:59
+msgid "devcp_previews_p_screenshots"
+msgstr ""
+"Níže naleznete přehled náhledů doplňku. Můžete měnit jak legendy, tak "
+"samotné obrázky. Výchozí náhled se zobrazuje vedle doplňku ve výpisech "
+"hledání a veřejných seznamech."
+
+#: views/previews/edit.thtml:55
+msgid "devcp_previews_submit_delete"
+msgstr "Smazat náhled"
+
+#: views/previews/edit.thtml:55
+msgid "devcp_previews_submit_delete_confirm"
+msgstr "Opravdu chcete tento náhled smazat?"
+
+#: views/previews/edit.thtml:54
+msgid "devcp_previews_submit_edit"
+msgstr "Upravit náhled"
+
+#: views/previews/add.thtml:63
+msgid "devcp_previews_submit_upload"
+msgstr "Nahrát náhled"
+
+#: views/developers/previews.thtml:78
+msgid "devcp_previews_thumbnail"
+msgstr "Náhled obrázku"
+
+#. %s is the add-on name.
+#: views/developers/previews.thtml:44
+msgid "devcp_previews_title"
+msgstr "Spráce náhledů doplňku %s"
+
+#: views/developers/uploader.thtml:74
+msgid "devcp_review_agreement_please"
+msgstr "PÅ™ed pokraÄováním si prosím pÅ™eÄtÄ›te a odsouhlaste následující text."
+
+#: views/elements/developers/rolecheck.thtml:42
+msgid "devcp_rolecheck_no_privs"
+msgstr ""
+"<span>Nemáte potřebná oprávnění pro provádění změn na této stránce.</"
+"span><br />Pokud potřebujete něco změnit, kontaktujte prosím vlastníka "
+"doplňku."
+
+#: controllers/developers_controller.php:1315
+msgid "devcp_several_hours"
+msgstr ""
+"Berte prosím na vÄ›domí, že projevení zmÄ›n v&nbsp;nÄ›kterých Äástech stránek "
+"může trvat až několik hodin."
+
+#: views/elements/developers/sidebar.thtml:52
+msgid "devcp_sidebar_a_dashboard"
+msgstr "Nástěnka"
+
+#. %s is a number
+#: views/elements/developers/statsbar.thtml:45
+#: views/developers/dashboard.thtml:79
+#, php-format
+msgid "devcp_statsbar_adu"
+msgstr "Aktivních uživatelů za den: <em>%s</em> "
+
+#. %s is a number
+#: views/elements/developers/statsbar.thtml:41
+#: views/developers/dashboard.thtml:75
+#, php-format
+msgid "devcp_statsbar_total_downloads"
+msgstr "Celkově staženo: <em>%s</em>"
+
+#. %s is a number
+#: views/elements/developers/statsbar.thtml:43
+#: views/developers/dashboard.thtml:77
+#, php-format
+msgid "devcp_statsbar_weekly_downloads"
+msgstr "Staženo za týden: <em>%s</em>"
+
+#: views/developers/addon_status_confirm.thtml:59
+msgid "devcp_status_confirm_active"
+msgstr ""
+"Po oznaÄení doplňku jako aktivní se zaÄne doplnÄ›k zobrazovat na veÅ™ejnÄ› "
+"dostupných stránkách odpovídajících jeho stavu, vÄetnÄ› hledání a výpisů. "
+"Doplněk bude ze stránek stažitelný a v závislosti na jeho stavu bude nabízen "
+"v rámci své aktualizaÄní služby. V případÄ› potÅ™eby budete mít na této "
+"stránce možnost doplněk opět zakázat."
+
+#: views/developers/addon_status_confirm.thtml:59
+msgid "devcp_status_confirm_active_sure"
+msgstr "Opravdu chcete oznaÄit tento doplnÄ›k jako aktivní?"
+
+#: views/developers/addon_status_confirm.thtml:50
+msgid "devcp_status_confirm_header_sure"
+msgstr "Jste si jisti?"
+
+#: views/developers/addon_status_confirm.thtml:55
+msgid "devcp_status_confirm_inactive"
+msgstr ""
+"Po oznaÄení doplňku jako neaktivní se pÅ™estane doplnÄ›k zobrazovat na veÅ™ejnÄ› "
+"dostupných stránkách, vÄetnÄ› hledání a výpisů. DoplnÄ›k nebude ze stránek "
+"stažitelný a to ani v rámci své aktualizaÄní služby. V případÄ› potÅ™eby "
+"budete mít na této stránce možnost doplněk opět povolit."
+
+#: views/developers/addon_status_confirm.thtml:55
+msgid "devcp_status_confirm_inactive_sure"
+msgstr "Opravdu chcete oznaÄit tento doplnÄ›k jako neaktivní?'"
+
+#: views/developers/addon_status_confirm.thtml:74
+msgid "devcp_status_confirm_no"
+msgstr "Ne, zrušit"
+
+#: views/developers/addon_status_confirm.thtml:67
+msgid "devcp_status_confirm_public"
+msgstr ""
+"Po zveřejnění bude doplněk ze stránek stažitelný a bude nabízen existujícím "
+"uživatelům v rámci své aktualizaÄní služby."
+
+#: views/developers/addon_status_confirm.thtml:67
+msgid "devcp_status_confirm_public_sure"
+msgstr "Opravdu chcete tento doplněk zveřejnit?"
+
+#: views/developers/addon_status_confirm.thtml:63
+msgid "devcp_status_confirm_sandbox"
+msgstr ""
+"Po přesunutí doplňku na pískoviště bude k jeho stažení vyžadováno přihlášení "
+"a doplnÄ›k nebude existujícím uživatelům nabíze v rámci své aktualizaÄní "
+"služby. Jelikož je doplnÄ›k v souÄasnosti veÅ™ejný, budete mít na této stránce "
+"v případě potřeby možnost doplněk opět zveřejnit."
+
+#: views/developers/addon_status_confirm.thtml:63
+msgid "devcp_status_confirm_sandbox_sure"
+msgstr "Opravdu chcete přesunout tento doplněk na pískoviště?"
+
+#: views/developers/addon_status_confirm.thtml:73
+msgid "devcp_status_confirm_yes"
+msgstr "Ano, jsem si jistý"
+
+#: views/developers/addon_status_nominate.thtml:46
+msgid "devcp_status_nominate_error_notice"
+msgstr ""
+"<span>Je požadována nominaÄní zpráva.</span><br />VepiÅ¡te prosím do "
+"textového pole požadované informace a zkuste to znova."
+
+#: views/developers/addon_status_nominate.thtml:55
+msgid "devcp_status_nominate_header"
+msgstr "Nominace doplňku"
+
+#: views/developers/dashboard.thtml:85
+msgid "devcp_summary_lastversion"
+msgstr "Poslední verze:"
+
+#. %s is the add-on name.
+#: views/developers/addon_edit.thtml:43
+#: views/developers/addon_edit_authors.thtml:44
+#: views/developers/versions_delete.thtml:43
+#: views/developers/addon_edit_properties.thtml:44
+#: views/developers/addon_edit_descriptions.thtml:44
+#: views/developers/versions_edit.thtml:44
+#: views/developers/addon_edit_categories.thtml:43
+#: views/developers/versions.thtml:43
+msgid "devcp_title_edit_addon"
+msgstr "Úpravy doplňku %s"
+
+#. title attribute for a javascript link that pops up a help dialog.
+#: views/elements/translationbox.thtml:68
+msgid "devcp_transbox_a_title_help"
+msgstr "Zobrazí nápovědu (a neopustí stránku)"
+
+#: views/elements/translationbox.thtml:68
+msgid "devcp_transbox_alt_help"
+msgstr "Nápověda"
+
+#. %1$s is <span>17</span>, %2$s is 42.
+#: views/elements/translationbox.thtml:101
+msgid "devcp_transbox_chars_used"
+msgstr "Použité znaky: %1$s / %2$s"
+
+#: views/elements/translationbox.thtml:132
+msgid "devcp_transbox_delete_sure"
+msgstr "Opravdu chcete smazat tento překlad?"
+
+#. %s is a locale, like en-US.
+#: views/elements/translationbox.thtml:143
+msgid "devcp_transbox_help_header_tabs"
+msgstr "K Äemu jsou tyto %s panely?"
+
+#: views/elements/translationbox.thtml:145
+msgid "devcp_transbox_help_header_what"
+msgstr "Co když nemám žádný překlad?"
+
+#: views/elements/translationbox.thtml:147
+msgid "devcp_transbox_help_hide"
+msgstr "Skrýt nápovědu"
+
+#: views/elements/translationbox.thtml:146
+msgid "devcp_transbox_help_if"
+msgstr ""
+"Pokud při prohlížení stránky není dostupný překlad pro aktuálně používaný "
+"jazyk, bude použita lokalizace oznaÄená jako výchozí. Ta lze nastavit v "
+"Äásti úprav vlastností doplňku. Pokud nemáte k dispozici žádný pÅ™eklad, "
+"použijte jako výchozí lokalizaci váš mateřský jazyk."
+
+#: views/elements/translationbox.thtml:144
+msgid "devcp_transbox_help_transbox"
+msgstr ""
+"Toto je <i>lokalizaÄní koutek</i>, který vám umožní pÅ™eložit danou položku "
+"do libovolného podporovaného jazyka. Můžete zde pomocí lokalizaÄních karet "
+"přidávat, upravovat a odebírat překlady."
+
+#: views/elements/translationbox.thtml:85
+msgid "devcp_transbox_img_add_trans"
+msgstr "Přidá překlad"
+
+#: views/elements/translationbox.thtml:86
+msgid "devcp_transbox_img_remove_trans"
+msgstr "Odebere překlad"
+
+#: views/elements/translationbox.thtml:123
+msgid "devcp_transbox_input_add_all"
+msgstr "Přidat lokalizaci ke všem"
+
+#: views/elements/translationbox.thtml:122
+msgid "devcp_transbox_input_add_locale"
+msgstr "Přidat lokalizaci"
+
+#: views/elements/translationbox.thtml:124
+#: views/elements/translationbox.thtml:135
+msgid "devcp_transbox_input_cancel"
+msgstr "Zrušit"
+
+#: views/elements/translationbox.thtml:134
+msgid "devcp_transbox_input_delete"
+msgstr "Smazat"
+
+#: views/elements/translationbox.thtml:113
+msgid "devcp_transbox_select_locale"
+msgstr "Lokalizaci překladu, který se má přidat:"
+
+#. %1$s and %2$s are GUIDs.
+#: controllers/developers_controller.php:343
+msgid "devcp_update_addon_guid_error"
+msgstr ""
+"GUID doplňku v&nbsp;souboru (%1$s) neodpovídá GUID tohoto doplňku (%2$s)."
+
+#: controllers/developers_controller.php:334
+msgid "devcp_update_addon_priv_error"
+msgstr "K aktualizaci tohoto doplňku nemáte dostateÄná oprávnÄ›ní."
+
+#. %1$s is a version number, %2$s is an add-on ID.
+#: controllers/developers_controller.php:399
+msgid "devcp_update_addon_version_belong_error"
+msgstr "Uvedená verze (%1$s) nepatří v&nbsp;doplňku (%2$s)."
+
+#. %1$s is a version number, maybe 1.1.
+#. %2$s is a URL.
+#: controllers/developers_controller.php:351
+msgid "devcp_update_addon_version_exists_error"
+msgstr ""
+"Nahrané Äíslo verze (%1$s) již u tohoto doplňku existuje. Pokud se snažíte "
+"k&nbsp;této verzi přidat další soubor, <a href=\"%2$s\">klepněte zde</a>."
+
+#. %1$s and %2$s are version numbers.
+#: controllers/developers_controller.php:405
+msgid "devcp_update_addon_version_match_error"
+msgstr "Číslo nahrané verze (%1$s) neodpovídá Äíslu existující verze (%2$s)."
+
+#: views/developers/uploader.thtml:68
+msgid "devcp_uploader_a_start"
+msgstr "ZaÄít"
+
+#: views/developers/uploader.thtml:137
+msgid "devcp_uploader_ajax_loading"
+msgstr "Nahrávání souboru…"
+
+#: views/developers/uploader.thtml:82
+msgid "devcp_uploader_button_agree"
+msgstr "Souhlasím a pokraÄovat"
+
+#: views/developers/uploader.thtml:157
+msgid "devcp_uploader_button_edit"
+msgstr "Upravit doplněk"
+
+#: views/developers/uploader.thtml:158
+msgid "devcp_uploader_button_later"
+msgstr "DokonÄit doplnÄ›k pozdÄ›ji."
+
+#: views/developers/uploader.thtml:168
+msgid "devcp_uploader_button_release"
+msgstr "Přidat poznámky v&nbsp;vydání"
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/uploader.thtml:156
+#, fuzzy
+msgid "devcp_uploader_created_results"
+msgstr ""
+"<p>Your add-on listing has been successfully created. The basic information "
+"obtained from your uploaded file has been stored, but there's a lot more to "
+"your listing that can be customized.</p><p>Your add-on is currently marked "
+"as <strong>Incomplete</strong>. In order to complete your add-on, you'll "
+"need to make sure it has an accurate name, summary, and description, as well "
+"as at least one selected category. You can edit your add-on's information "
+"using the link below and check the status of your add-on at any time on the "
+"<a %s>status page</a>."
+
+#: views/developers/uploader.thtml:143
+msgid "devcp_uploader_error_correct"
+msgstr "Opravte prosím tento problém a nahrajte soubor znova."
+
+#. %1$s is a version number, %2$s is a status, e.g Public or Incomplete.
+#: views/developers/uploader.thtml:175
+msgid "devcp_uploader_file_created"
+msgstr "K verzi %1$s byl pÅ™idán nový soubor a je oznaÄen jako %2$s."
+
+#: views/developers/uploader.thtml:154
+msgid "devcp_uploader_header_created"
+msgstr "Doplněk vytvořen!"
+
+#: views/developers/uploader.thtml:141
+msgid "devcp_uploader_header_error"
+msgstr "Jejda! Vypadá to, že máme problém se souborem…"
+
+#: views/developers/uploader.thtml:173
+msgid "devcp_uploader_header_file_added"
+msgstr "Soubor přidán!"
+
+#: views/developers/uploader.thtml:66
+msgid "devcp_uploader_header_how"
+msgstr "Jak to funguje?"
+
+#. %s is the version number, e.g. 3.2.
+#: views/developers/uploader.thtml:163
+msgid "devcp_uploader_header_update_created"
+msgstr "Verze %s vytvořena"
+
+#: views/developers/uploader.thtml:117
+msgid "devcp_uploader_header_upload"
+msgstr "Nahrání souboru"
+
+#: views/developers/uploader.thtml:67
+#, fuzzy
+msgid "devcp_uploader_how"
+msgstr ""
+"<p>Thanks for your interest in submitting your add-on to Mozilla Add-ons. "
+"Hosting your add-on on Mozilla Add-ons is the easiest way to handle "
+"distribution of your add-on. Here's what you'll get:</p><ul><li>Each add-on "
+"will have a public display page with information you provide, such as a "
+"brief summary of the add-on's functionality, an optional longer description, "
+"and a showcase of preview screenshots of your add-on.</li><li>Your add-on "
+"will appear in search and browse listings across the site, and even in the "
+"Add-ons Manager of Firefox 3.</li><li>We'll take care of hosting all of your "
+"downloads and providing automatic updates to users when you upload a new "
+"version.</li><li>You'll have access to a statistics dashboard with detailed "
+"information about your user base.</li></ul><p>Add-ons hosted on the site "
+"must be reviewed by a Mozilla Add-ons Editor before they will have all of "
+"the features listed above. If you're ready to start the process and have "
+"your add-on package ready for upload, just click on Get Started below!</p>"
+
+#: views/developers/uploader.thtml:125
+msgid "devcp_uploader_label_platformtype"
+msgstr "Podporované platformy:"
+
+#: views/developers/uploader.thtml:124
+msgid "devcp_uploader_label_upload_field"
+msgstr "Soubor doplňku: "
+
+#: controllers/components/developers.php:1221
+msgid "devcp_uploader_option_other"
+msgstr "Jiné"
+
+#. %1$s is a number, %2$s is href="..." and should stay in the <a> tag.
+#: views/developers/uploader.thtml:176
+#, fuzzy
+msgid "devcp_uploader_p_pending_file"
+msgstr ""
+"The new file will be available to the public as soon as an editor is able to "
+"review it. There are currently %1$s other add-ons in the queue. Want to be "
+"reviewed faster? Consider <a %2$s>becoming an editor</a>."
+
+#. %1$s is a number, %2$s is href="..." and should stay in the <a> tag.
+#: views/developers/uploader.thtml:166
+#, fuzzy
+msgid "devcp_uploader_p_pending_version"
+msgstr ""
+"The new version will be available to the public as soon as an editor is able "
+"to review it. There are currently %1$s other add-ons in the queue. Want to "
+"be reviewed faster? Consider <a %2$s>becoming an editor</a>."
+
+#. %s is a status, e.g Public or Incomplete.
+#: views/developers/uploader.thtml:165
+msgid "devcp_uploader_p_update_created"
+msgstr "Nová verze byla vytvoÅ™ena a oznaÄena jako %s."
+
+#. %1$s is href="..." and should stay in the 'Versions and Files' <a> tag.
+#. %2$s is href="..." and should stay in the 'current status' <a> tag.
+#: views/developers/uploader.thtml:177
+#, fuzzy
+msgid "devcp_uploader_p_update_file"
+msgstr ""
+"View your new file in the <a %1$s>Versions and Files page</a>, check out "
+"your add-on's <a %2$s>current status</a>, or <b>add release notes</b> by "
+"clicking the button below (highly recommended)."
+
+#. %1$s is href="..." and should stay in the 'Versions and Files' <a> tag.
+#. %2$s is href="..." and should stay in the 'current status' <a> tag.
+#: views/developers/uploader.thtml:167
+#, fuzzy
+msgid "devcp_uploader_p_update_version"
+msgstr ""
+"View your new version in the <a %1$s>Versions and Files page</a>, check out "
+"your add-on's <a %2$s>current status</a>, or <b>add release notes</b> by "
+"clicking the button below (highly recommended)."
+
+#: views/developers/uploader.thtml:118
+#, fuzzy
+msgid "devcp_uploader_p_upload"
+msgstr ""
+"Upload your add-on file using the form below. If you have multiple, platform-"
+"specific files to upload, choose a single file and then upload the others "
+"using the Versions and Files Manager."
+
+#: views/developers/uploader.thtml:125
+msgid "devcp_uploader_platformtype_all"
+msgstr "VÅ¡echny"
+
+#: views/developers/uploader.thtml:126
+msgid "devcp_uploader_platformtype_specific"
+msgstr "Pouze:"
+
+#. Used as first item in a <select>.
+#: controllers/components/developers.php:1185
+msgid "devcp_uploader_please_choose"
+msgstr "Zvolte prosím..."
+
+#. %1$s is the add-on name, %2$s is the version number.
+#: views/developers/uploader.thtml:57
+msgid "devcp_uploader_title_file"
+msgstr "Přidat soubor v&nbsp;%1$s %2$s"
+
+#: views/developers/uploader.thtml:50
+msgid "devcp_uploader_title_submit"
+msgstr "Přidání nového doplňku"
+
+#. %s is the add-on name.
+#: views/developers/uploader.thtml:54
+msgid "devcp_uploader_title_update"
+msgstr "Aktualizace doplňku %s"
+
+#. %s is a full <a> tag
+#: controllers/developers_controller.php:503
+#, php-format
+msgid "devcp_valid_app_reference"
+msgstr "Více informací naleznete na %s."
+
+#. This is the text in the <a> tag for devcp_valid_app_reference. This should be
+#. fixed.
+#: controllers/developers_controller.php:503
+msgid "devcp_valid_app_reference_linktext"
+msgstr "této stránce"
+
+#: controllers/developers_controller.php:581
+msgid "devcp_verify_author_error"
+msgstr "K této e-mailové adrese nebyl nalezen žádný úÄet."
+
+#: controllers/developers_controller.php:553
+msgid "devcp_verify_search_engine_error"
+msgstr ""
+"Zdá se, že XML je nevalidní nebo chybí nÄ›která důležitá pole. PÅ™eÄtÄ›te si "
+"prosím <a href=\"https://developer.mozilla.org/en/"
+"Creating_OpenSearch_plugins_for_Firefox\">dokumentaci</a>, zkontrolujte svůj "
+"doplněk a zkuste to znovu."
+
+#: views/developers/versions.thtml:75
+msgid "devcp_versions_a_cancel"
+msgstr "Zrušit"
+
+#: views/developers/versions.thtml:79
+msgid "devcp_versions_a_delete"
+msgstr "Smaže verzi"
+
+#: views/developers/versions.thtml:74
+msgid "devcp_versions_a_empty"
+msgstr "Odstranit prázdnou verzi"
+
+#: views/developers/versions.thtml:71
+msgid "devcp_versions_a_remove"
+msgstr "Odstranit?"
+
+#: views/developers/versions.thtml:91
+msgid "devcp_versions_add"
+msgstr "Přidat novou verzi"
+
+#: views/developers/versions_delete.thtml:58
+msgid "devcp_versions_delete_a_cancel"
+msgstr "Zrušit"
+
+#: views/developers/versions_delete.thtml:56
+msgid "devcp_versions_delete_a_delete"
+msgstr "Smazat verzi"
+
+#. Followed by a list of reviews and files that will be removed.
+#: views/developers/versions_delete.thtml:50
+msgid "devcp_versions_delete_also"
+msgstr "Toto rovněž smaže:"
+
+#: views/developers/versions_delete.thtml:53
+msgid "devcp_versions_delete_files"
+msgid_plural "devcp_versions_delete_files"
+msgstr[0] "%s soubor"
+msgstr[1] "%s soubory"
+msgstr[2] "%s souborů"
+
+#. %s is the version number.
+#: views/developers/versions_delete.thtml:48
+msgid "devcp_versions_delete_header"
+msgstr "Smazat verzi %s?"
+
+#: views/developers/versions_delete.thtml:52
+msgid "devcp_versions_delete_reviews"
+msgid_plural "devcp_versions_delete_reviews"
+msgstr[0] "%s recenze"
+msgstr[1] "%s recenze"
+msgstr[2] "%s recenzí"
+
+#. %s is the version number.
+#: views/developers/versions_delete.thtml:49
+msgid "devcp_versions_delete_sure"
+msgstr "Opravdu chcete trvale smazat verzi %s?"
+
+#: views/developers/versions_edit.thtml:102
+#: views/developers/versions_edit.thtml:155
+msgid "devcp_versions_edit_a_cancel"
+msgstr "Zrušit"
+
+#: views/developers/versions_edit.thtml:101
+msgid "devcp_versions_edit_a_delete"
+msgstr "Smazat soubor"
+
+#: views/developers/versions_edit.thtml:165
+msgid "devcp_versions_edit_a_new_app"
+msgstr "Přidat novou aplikaci"
+
+#: views/developers/versions_edit.thtml:154
+msgid "devcp_versions_edit_a_remove_app"
+msgstr "Odebrat aplikaci"
+
+#: views/developers/versions_edit.thtml:114
+msgid "devcp_versions_edit_add"
+msgstr "Přidat nový soubor"
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/versions_edit.thtml:121
+#, fuzzy
+msgid "devcp_versions_edit_adjust"
+msgstr ""
+"Adjusting application information here will allow users to install your add-"
+"on even if the install.rdf in the package indicates that the add-on is "
+"incompatible. <a %s>List of supported applications</a>"
+
+#: views/developers/versions_edit.thtml:153
+msgid "devcp_versions_edit_compat_sure"
+msgstr "<b>Opravdu</b> chcete odebrat kompatibilitu s&nbsp;touto aplikací?"
+
+#: views/developers/versions_edit.thtml:100
+msgid "devcp_versions_edit_delete_sure"
+msgstr "<b>Opravdu</b> chcete trvale smazat tento soubor?"
+
+#: views/developers/versions_edit.thtml:203
+msgid "devcp_versions_edit_header_approval"
+msgstr "Informace o&nbsp;schválení"
+
+#: views/developers/versions_edit.thtml:120
+msgid "devcp_versions_edit_header_compat"
+msgstr "Kompatibilní aplikace"
+
+#: views/developers/versions_edit.thtml:74
+msgid "devcp_versions_edit_header_file"
+msgstr "Informace o&nbsp;souboru"
+
+#: views/developers/versions_edit.thtml:189
+msgid "devcp_versions_edit_header_license"
+msgstr "Licence"
+
+#. %s is the version number.
+#: views/developers/versions_edit.thtml:53
+msgid "devcp_versions_edit_header_manage"
+msgstr "Správe verze %s"
+
+#: views/developers/versions_edit.thtml:212
+msgid "devcp_versions_edit_header_notes"
+msgstr "Poznámky ke&nbsp;schválení"
+
+#: views/developers/versions_edit.thtml:98
+msgid "devcp_versions_edit_img_delete"
+msgstr "Smazat soubor"
+
+#. %1$s is the file id, e.g. 18723.
+#. %2$s is the platform name, e.g. ALL or Windows.
+#. %3$s is the _('date) created.
+#. %4$s is the status, e.g. "In Sandbox" or "Public".
+#. %5$s is the _('date') status was changed.
+#: views/developers/versions_edit.thtml:208
+msgid "devcp_versions_edit_li_file"
+msgstr "Soubor %1$s (%2$s) vytvořen dne %3$s byl změněn do stavu %4$s dne %5$s"
+
+#: views/developers/versions_edit.thtml:190
+msgid "devcp_versions_edit_license_description"
+msgstr ""
+"Zvolte prosím pro váš doplnÄ›k odpovídající licenci. Tato licence urÄuje "
+"práva, která dáváte ke svému zdrojovému kódu."
+
+#: views/developers/versions_edit.thtml:111
+msgid "devcp_versions_edit_no_files"
+msgstr "Nebyl nalezen žádný soubor."
+
+#: views/developers/versions_edit.thtml:213
+msgid "devcp_versions_edit_optional"
+msgstr "Nepovinné informace pro redaktora, který bude kontrolovat tuto verzi."
+
+#: views/developers/versions_edit.thtml:151
+msgid "devcp_versions_edit_remove_compat"
+msgstr "Odebrat kompatibilní aplikace"
+
+#: views/developers/versions_edit.thtml:167
+msgid "devcp_versions_edit_select_app"
+msgstr "Zvolte prosím aplikaci"
+
+#: views/developers/versions_edit.thtml:78
+msgid "devcp_versions_edit_th_file"
+msgstr "Soubor"
+
+#: views/developers/versions_edit.thtml:79
+msgid "devcp_versions_edit_th_platform"
+msgstr "Platforma"
+
+#: views/developers/versions_edit.thtml:80
+msgid "devcp_versions_edit_th_size"
+msgstr "Velikost"
+
+#: views/developers/versions_edit.thtml:81
+msgid "devcp_versions_edit_th_status"
+msgstr "Stav"
+
+#: views/developers/versions_edit.thtml:183
+#, fuzzy
+msgid "devcp_versions_edit_transbox_releasenotes_description"
+msgstr ""
+"Information about changes in this release, new features, known bugs, and "
+"other useful information specific to this release/version. This information "
+"will also be available to users updating the add-on in the Firefox 3 Add-ons "
+"Manager interface."
+
+#: views/developers/versions_edit.thtml:182
+msgid "devcp_versions_edit_transbox_releasenotes_name"
+msgstr "Poznámky v&nbsp;vydání"
+
+#: views/developers/versions_edit.thtml:164
+msgid "devcp_versions_edit_unsaved_compat"
+msgstr ""
+"<strong>Neuložené změny!</strong> Kompatibilita nebude smazána dokud "
+"neklepnete na tlaÄítko Aktualizovat verzi."
+
+#: views/developers/versions_edit.thtml:113
+msgid "devcp_versions_edit_unsaved_files"
+msgstr ""
+"<strong>Neuložené změny!</strong> Soubory nebudou smazány dokud neklepnete "
+"na tlaÄítko Aktualizovat verzi."
+
+#: views/developers/versions_edit.thtml:218
+msgid "devcp_versions_edit_update"
+msgstr "Aktualizovat verzi"
+
+#: views/developers/versions.thtml:49
+msgid "devcp_versions_header_manage"
+msgstr "Správa verzí a souborů"
+
+#: views/developers/versions.thtml:87
+msgid "devcp_versions_no_versions"
+msgstr "Bez verzí"
+
+#. %s is a version number, base 10.
+#: views/developers/versions.thtml:46
+msgid "devcp_versions_notice_success"
+msgstr "Verze %s byla úspěšně smazána."
+
+#: views/developers/versions.thtml:73
+msgid "devcp_versions_p_remove"
+msgstr ""
+"Tato verze nemá přiřazeny žádné soubory a lze ji proto smazat. Chcete ji "
+"smazat?"
+
+#: views/developers/versions.thtml:58
+msgid "devcp_versions_th_created"
+msgstr "Vytvořeno"
+
+#: views/developers/versions.thtml:57
+msgid "devcp_versions_th_status"
+msgstr "Stav"
+
+#: views/developers/versions.thtml:56
+msgid "devcp_versions_th_version"
+msgstr "Verze"
+
+#: controllers/downloads_controller.php:91
+msgid "downloads_disable_warning"
+msgstr "Tento doplněk je zakázán"
+
+#: controllers/components/editors.php:57
+msgid "editor_review_error_addon_not_nominated"
+msgstr "Tento doplněk nebyl nominován."
+
+#: controllers/components/editors.php:213
+msgid "editor_review_error_file_not_pending"
+msgstr "Tento soubor neÄeká na kontrolu."
+
+#. Actions are, for example: approving or rejecting
+#: controllers/components/editors.php:79
+#: controllers/components/editors.php:182
+msgid "editor_review_error_no_action"
+msgstr "Zvolte prosím akci kontroly."
+
+#: controllers/components/editors.php:192
+msgid "editor_review_error_no_applications"
+msgstr "Zadejte prosím testovanou aplikací."
+
+#. Comments are required when an editor approves or rejects an add-on.
+#: controllers/components/editors.php:84
+#: controllers/components/editors.php:187
+msgid "editor_review_error_no_comments"
+msgstr "Zadejte prosím komentář kontroly."
+
+#: controllers/components/editors.php:161
+msgid "editor_review_error_no_files"
+msgstr "Zvolte prosím alespoň jeden soubor ke kontrole."
+
+#: controllers/components/editors.php:197
+msgid "editor_review_error_no_operating_system"
+msgstr "Zadejte prosím testovaný operaÄní systém."
+
+#: views/editors/logs.thtml:51
+msgid "editorcp_logs_button_filter"
+msgstr "Filtrovat"
+
+#: views/editors/logs.thtml:44
+msgid "editorcp_logs_filter_by"
+msgstr "Filtrovat podle typu/akce"
+
+#: views/editors/logs.thtml:42 controllers/editors_controller.php:964
+msgid "editorcp_logs_page_heading"
+msgstr "Záznam událostí"
+
+#: views/elements/developers/editorsmenu.thtml:60
+msgid "editorcp_menu_eventlog_link"
+msgstr "Záznam událostí"
+
+#: views/elements/developers/editorsmenu.thtml:62
+msgid "editorcp_menu_mainpage_link"
+msgstr "Zpět na titulní stránku"
+
+#: views/elements/developers/editorsmenu.thtml:61
+msgid "editorcp_menu_reviewlog_link"
+msgstr "Záznam kontroly"
+
+#: views/elements/developers/editorsmenu.thtml:55
+msgid "editorcp_menu_summary_link"
+msgstr "Přehled redaktora"
+
+#: views/elements/developers/editorsmenu.thtml:52
+msgid "editorcp_menu_title"
+msgstr "Nástroje redaktora"
+
+#: views/editors/reviewlog.thtml:49
+msgid "editorcp_reviewlog_button_filter"
+msgstr "Filtrovat"
+
+#: views/editors/reviewlog.thtml:58
+msgid "editorcp_reviewlog_column_action"
+msgstr "Akce"
+
+#: views/editors/reviewlog.thtml:56
+msgid "editorcp_reviewlog_column_addon"
+msgstr "Doplněk"
+
+#: views/editors/reviewlog.thtml:55
+msgid "editorcp_reviewlog_column_date"
+msgstr "Datum"
+
+#: views/editors/reviewlog.thtml:57
+msgid "editorcp_reviewlog_column_editor"
+msgstr "Redaktor"
+
+#: views/editors/reviewlog.thtml:94
+msgid "editorcp_reviewlog_comments_hide"
+msgstr "Skrýt komentáře"
+
+#: views/editors/reviewlog.thtml:93
+msgid "editorcp_reviewlog_comments_show"
+msgstr "Zobrazit komentáře"
+
+#. %1$s and %2$s are full <input> tags for dates
+#: views/editors/reviewlog.thtml:45
+#, php-format
+msgid "editorcp_reviewlog_entries_between"
+msgstr "Zobrazit položky mezi %s a %s"
+
+#: views/editors/reviewlog.thtml:104
+msgid "editorcp_reviewlog_none_found"
+msgstr "Pro toto období nebyla nalezena žádná kontrola."
+
+#: views/editors/reviewlog.thtml:42
+msgid "editorcp_reviewlog_page_heading"
+msgstr "Záznam kontroly"
+
+#: views/editors/summary.thtml:61
+msgid "editorcp_summary_monthreviews_heading"
+msgstr "MÄ›síÄní kontrola"
+
+#: views/editors/summary.thtml:77
+msgid "editorcp_summary_neweditors_heading"
+msgstr "Noví redaktoři"
+
+#: views/editors/summary.thtml:42
+msgid "editorcp_summary_page_heading"
+msgstr "Přehled redaktora"
+
+#: views/editors/summary.thtml:94
+msgid "editorcp_summary_recentactivity_heading"
+msgstr "Nedávna aktivita redaktora"
+
+#: views/editors/summary.thtml:45
+msgid "editorcp_summary_totalreviews_heading"
+msgstr "Kontroly celkem"
+
+#: controllers/editors_controller.php:248
+#: controllers/editors_controller.php:249
+msgid "editors_addon_review_pagetitle"
+msgstr "Kontrola doplňku"
+
+#: controllers/editors_controller.php:349
+msgid "editors_error_js-formerror"
+msgstr "Vyplňte prosím následující položky:"
+
+#: controllers/editors_controller.php:350
+msgid "editors_error_review_one_file"
+msgstr "Zvolte prosím alespoň jeden soubor ke&nbsp;kontrole."
+
+#: controllers/editors_controller.php:274
+msgid "editors_error_self_reviews_forbidden"
+msgstr "Vlastní kontrola není povolena."
+
+#: controllers/editors_controller.php:699
+msgid "editors_external_software"
+msgstr "Externí software"
+
+#: views/editors/featured.thtml:120 views/editors/featured.thtml:121
+msgid "editors_featured_add_feature"
+msgstr "Přidat vlastnost"
+
+#: views/editors/featured.thtml:126
+msgid "editors_featured_add_feature_submit"
+msgstr "Přidat"
+
+#: views/editors/featured.thtml:49 controllers/editors_controller.php:832
+#: controllers/editors_controller.php:848
+msgid "editors_featured_addon_add_failure"
+msgstr "PÅ™idání vlastnosti skonÄilo chybou."
+
+#: controllers/editors_controller.php:851
+msgid "editors_featured_addon_add_success"
+msgstr "Vlastnost byla úspěšně přidána."
+
+#: views/editors/featured.thtml:50 controllers/editors_controller.php:839
+#: controllers/editors_controller.php:868
+#: controllers/editors_controller.php:886
+msgid "editors_featured_addon_edit_failure"
+msgstr "Úprava vlastnosti skonÄilo chybou."
+
+#: views/editors/featured.thtml:51 controllers/editors_controller.php:888
+msgid "editors_featured_addon_edit_success"
+msgstr "Vlastnost byla úspěšně upravena."
+
+#: views/editors/featured.thtml:53 controllers/editors_controller.php:861
+msgid "editors_featured_addon_invalid_locale"
+msgstr "Jedna nebo více lokalizací je naplatná."
+
+#: views/editors/featured.thtml:52 controllers/editors_controller.php:906
+msgid "editors_featured_addon_remove_failure"
+msgstr "Odebrání vlastnosti skonÄilo chybou."
+
+#: controllers/editors_controller.php:901
+msgid "editors_featured_addon_remove_success"
+msgstr "Vlastnost byla úspěšně odebrána."
+
+#: controllers/editors_controller.php:915
+#: controllers/editors_controller.php:917
+msgid "editors_featured_addons_pagetitle"
+msgstr "Uváděné doplňky"
+
+#: views/editors/featured.thtml:54 views/editors/featured.thtml:107
+msgid "editors_featured_edit_feature_submit"
+msgstr "Odeslat"
+
+#: views/editors/featured.thtml:90 views/editors/featured.thtml:91
+msgid "editors_featured_remove_feature"
+msgstr "Odebrat vlastnost"
+
+#: views/editors/queue.thtml:46
+msgid "editors_filter_queue"
+msgstr "Filtr fronty"
+
+#: views/editors/queue.thtml:182
+msgid "editors_helpful_links"
+msgstr "Pomocné odkazy"
+
+#: views/editors/queue.thtml:182
+msgid "editors_link_guide"
+msgstr "Průvodce redaktora"
+
+#: views/editors/queue.thtml:182
+msgid "editors_link_policy"
+msgstr "Zásady užití doplňku"
+
+#: views/editors/queue.thtml:47
+msgid "editors_notice_filter_session"
+msgstr ""
+"Tyto filtry zůstanou aktivní po celou dobu relace nebo dokud nebudou "
+"vymazány."
+
+#. %1 is the queue mode
+#: views/editors/queue.thtml:177 views/admin/flagged_queue.thtml:89
+msgid "editors_notice_none_found"
+msgstr "V souÄasnosti nejsou ke kontrole dostupné žádné doplňky."
+
+#: controllers/editors_controller.php:1040
+msgid "editors_one_day"
+msgstr "1 den"
+
+#: controllers/editors_controller.php:1048
+msgid "editors_one_hour"
+msgstr "1 hodina"
+
+#: controllers/editors_controller.php:1056
+msgid "editors_one_minute"
+msgstr "1 minuta"
+
+#: controllers/editors_controller.php:64 controllers/editors_controller.php:73
+#: controllers/editors_controller.php:77
+msgid "editors_pagetitle"
+msgstr "Ovládací panel redaktora"
+
+#. %s is a comma separated list of platforms. Example: Windows, OS X
+#: controllers/editors_controller.php:680
+#: controllers/editors_controller.php:683
+#, php-format
+msgid "editors_platform_x_only"
+msgstr "pouze %s"
+
+#: controllers/editors_controller.php:695
+msgid "editors_pre-release"
+msgstr "kandidát na vydání"
+
+#. %1 is the app name
+#: views/editors/queue.thtml:131
+#, php-format
+msgid "editors_queue_app_compatibility"
+msgstr "%s kompatibilita"
+
+#: views/editors/queue.thtml:51
+msgid "editors_queue_filter_label_addon"
+msgstr "Doplněk nebo e-mail autora"
+
+#: views/editors/queue.thtml:72
+msgid "editors_queue_filter_label_addontypes"
+msgstr "Typy doplňků"
+
+#: views/editors/queue.thtml:56
+msgid "editors_queue_filter_label_application"
+msgstr "Aplikace"
+
+#: views/editors/queue.thtml:61
+msgid "editors_queue_filter_label_maxversion"
+msgstr "Max. verze"
+
+#: views/editors/queue.thtml:78
+msgid "editors_queue_filter_label_platforms"
+msgstr "Platformy"
+
+#: views/editors/queue.thtml:66
+msgid "editors_queue_filter_label_submissionage"
+msgstr "Stáří odeslání (ve dnech)"
+
+#. %1$s is a number
+#: views/editors/queue.thtml:90
+msgid "editors_queue_filter_result_count"
+msgid_plural "editors_queue_filter_result_count"
+msgstr[0] "Results of your filtered search: <strong>%1$s</strong> Add-on"
+msgstr[1] "Výsledek vyhledávání: <strong>%1$s</strong> doplňků"
+
+#: views/editors/queue.thtml:84
+msgid "editors_queue_submit_clean"
+msgstr "Vymazat"
+
+#: views/editors/queue.thtml:83
+msgid "editors_queue_submit_filter"
+msgstr "Filtr"
+
+#: controllers/editors_controller.php:133
+msgid "editors_queues_disabled"
+msgstr ""
+"VÅ¡echny fronty kontroly doplňků jsou v&nbsp;souÄasnosti zakázány. Opakujte "
+"prosím akci později."
+
+#: views/editors/review.thtml:149
+msgid "editors_review_a_edit_item"
+msgstr "Upravit doplněk"
+
+#: views/editors/review.thtml:146
+msgid "editors_review_a_item_history"
+msgstr "Historie doplňku"
+
+#: views/editors/review.thtml:148
+msgid "editors_review_a_item_homepage"
+msgstr "Domovská stránka doplňku"
+
+#: views/editors/review.thtml:145
+msgid "editors_review_a_item_overview"
+msgstr "Souhrnné informace"
+
+#: views/editors/review.thtml:147
+msgid "editors_review_a_previews"
+msgstr "Náhledy"
+
+#: controllers/editors_controller.php:345
+msgid "editors_review_action"
+msgstr "Akce kontroly"
+
+#: views/editors/review.thtml:159
+msgid "editors_review_action_info"
+msgstr "Požadovat více informací"
+
+#: views/editors/review.thtml:157
+msgid "editors_review_action_public"
+msgstr "Zveřejnit"
+
+#: views/editors/review.thtml:160
+msgid "editors_review_action_request_superreview"
+msgstr "Požádat o&nbsp;super-kontrolu"
+
+#: views/editors/review.thtml:158
+msgid "editors_review_action_sandbox"
+msgstr "Ponechat na pískovišti"
+
+#: controllers/editors_controller.php:346
+msgid "editors_review_comments"
+msgstr "Komentář kontroly"
+
+#: views/editors/review.thtml:182
+msgid "editors_review_details_info_request"
+msgstr ""
+"Tento formulář lze použít k požádání autorů o dodateÄné informace. Ti obdrží "
+"e-mail a budou zde moci odpovědět. Až se tak stane, budete rovněž "
+"informováni e-mailem."
+
+#: views/editors/review.thtml:174
+msgid "editors_review_details_nominated_public"
+msgstr ""
+"PÅ™esune doplnÄ›k, jeho souÄasnou verzi a přísluÅ¡né soubory mezi veÅ™ejné "
+"doplňky. Budoucí verze doplňku budou opět umístěny na pískoviště, dokud "
+"nebudou zkontrolovány redaktorem."
+
+#: views/editors/review.thtml:177
+msgid "editors_review_details_nominated_sandbox"
+msgstr "Ponechá doplněk na pískovišti."
+
+#: views/editors/review.thtml:166
+msgid "editors_review_details_pending_public"
+msgstr ""
+"Schválí verzi doplňku z&nbsp;pískoviště již jednou veřejného doplňku k&nbsp;"
+"zobrazení na stránkách veřejných doplňků."
+
+#: views/editors/review.thtml:169
+msgid "editors_review_details_pending_sandbox"
+msgstr ""
+"Ponechá verzi doplňku z&nbsp;pískoviště již jednou veřejného doplňku na "
+"pískovišti."
+
+#: views/editors/review.thtml:185
+msgid "editors_review_details_superreview"
+msgstr ""
+"Pokud máte jakékoliv pochybnosti ohlednÄ› bezpeÄnosti doplňku, jeho "
+"autorských práv, Äi jakékoliv jiné záležitosti, na které by se správci mÄ›li "
+"podívat, vepište níže váš komentář. Tento komentář bude zaslán pouze "
+"správcům, ne autorům."
+
+#: views/editors/review.thtml:134
+msgid "editors_review_file_diff_link"
+msgstr "Porovnat s&nbsp;veřejnou verzí"
+
+#: views/editors/review.thtml:131
+msgid "editors_review_file_viewcontents_link"
+msgstr "Zobrazit obsah"
+
+#: views/editors/review.thtml:65
+msgid "editors_review_header_authors"
+msgstr "Autoři:"
+
+#: views/editors/review.thtml:79
+msgid "editors_review_header_categories"
+msgstr "Kategorie:"
+
+#: views/editors/review.thtml:92
+msgid "editors_review_header_compatibility"
+msgstr "Kompatibilita:"
+
+#: views/editors/review.thtml:251
+msgid "editors_review_header_description"
+msgstr "Popis"
+
+#: views/editors/review.thtml:275
+msgid "editors_review_header_devcomments"
+msgstr "Komentáře vývojářů"
+
+#: views/editors/review.thtml:263
+msgid "editors_review_header_eula"
+msgstr "EULA"
+
+#: views/editors/review.thtml:115
+msgid "editors_review_header_files"
+msgstr "Soubory:"
+
+#: views/editors/review.thtml:284
+msgid "editors_review_header_itemhistory"
+msgstr "Položka historie"
+
+#: views/editors/review.thtml:232
+msgid "editors_review_header_nominationmessage"
+msgstr "NominaÄní zpráva"
+
+#: views/editors/review.thtml:311
+msgid "editors_review_header_previews"
+msgstr "Náhledy"
+
+#: views/editors/review.thtml:269
+msgid "editors_review_header_privacy"
+msgstr "Zásady ochrany soukromí"
+
+#. %1 is the add-on name and version
+#: views/editors/review.thtml:56
+#, php-format
+msgid "editors_review_header_review"
+msgstr "Kontrola doplňku %s"
+
+#: views/editors/review.thtml:239
+msgid "editors_review_header_reviewernotes"
+msgstr "Poznámky pro kontrolora"
+
+#: views/editors/review.thtml:245
+msgid "editors_review_header_summary"
+msgstr "Přehled"
+
+#: views/editors/review.thtml:257
+msgid "editors_review_header_versionnotes"
+msgstr "Poznámky k&nbsp;verzi"
+
+#. a noun: shown in an add-on's editor review history
+#: views/elements/developers/editors_review_history_item.thtml:80
+msgid "editors_review_history_info_reply"
+msgstr "Odpovědět"
+
+#: views/elements/developers/editors_review_history_item.thtml:78
+msgid "editors_review_history_info_request"
+msgstr "Žádost o&nbsp;informace"
+
+#: views/elements/developers/editors_review_history_item.thtml:62
+#: views/editors/reviewlog.thtml:77
+msgid "editors_review_history_nominated_adminreview"
+msgstr "Správce kontroly"
+
+#: views/elements/developers/editors_review_history_item.thtml:56
+#: views/editors/reviewlog.thtml:71
+msgid "editors_review_history_nominated_approved"
+msgstr "Nominace schválena/veřejné doplňky"
+
+#: views/elements/developers/editors_review_history_item.thtml:59
+#: views/editors/reviewlog.thtml:74
+msgid "editors_review_history_nominated_denied"
+msgstr "Nominace zamítnuta/pískoviště"
+
+#: views/editors/review.thtml:303
+msgid "editors_review_history_nonefound"
+msgstr "Nebyly nalezeny žádné záznamy předchozího kontroly."
+
+#: views/elements/developers/editors_review_history_item.thtml:73
+#: views/editors/reviewlog.thtml:88
+msgid "editors_review_history_pending_adminreview"
+msgstr "Správce kontroly"
+
+#: views/elements/developers/editors_review_history_item.thtml:67
+#: views/editors/reviewlog.thtml:82
+msgid "editors_review_history_pending_approved"
+msgstr "Schváleno/veřejné doplňky"
+
+#: views/elements/developers/editors_review_history_item.thtml:70
+#: views/editors/reviewlog.thtml:85
+msgid "editors_review_history_pending_denied"
+msgstr "Zamítnuto/Pískoviště"
+
+#. link text in an add-on's editor review history, allowing to hide and show an information request's replies
+#. %1 is the number of replies
+#: views/elements/developers/editors_review_history_item.thtml:90
+msgid "editors_review_history_show_hide_replies"
+msgid_plural "editors_review_history_show_hide_replies"
+msgstr[0] "Zobrazit/Skrýt %1$s odpovÄ›Ä"
+msgstr[1] "Zobrazit/Skrýt %1$s odpovědi"
+msgstr[2] "Zobrazit/Skrýt %1$s odpovědí"
+
+#: views/editors/review.thtml:208
+msgid "editors_review_label_applications"
+msgstr "Aplikace:"
+
+#: views/editors/review.thtml:196
+msgid "editors_review_label_cannedresponse"
+msgstr "nebo zvolte některou z&nbsp;připravených odpovědí:"
+
+#: views/editors/review.thtml:190
+msgid "editors_review_label_comments"
+msgstr "Komentáře:"
+
+#: views/editors/review.thtml:204
+msgid "editors_review_label_operating_systems"
+msgstr "OperaÄní systém:"
+
+#: views/editors/review.thtml:285 views/editors/review.thtml:312
+msgid "editors_review_link_pagetop"
+msgstr "Nahoru"
+
+#: views/editors/review.thtml:141
+msgid "editors_review_mulitple_notice"
+msgstr ""
+"Poznámka: Kontrolujte pouze více než jeden soubor, pokud jste testovali "
+"všechny zvolené soubory."
+
+#: views/editors/review.thtml:51
+msgid "editors_review_next_link"
+msgstr "další &raquo;"
+
+#: views/editors/review.thtml:322
+msgid "editors_review_previews_notfound"
+msgstr "Náhledy nenalezeny."
+
+#: views/editors/review.thtml:50
+msgid "editors_review_previous_link"
+msgstr "&laquo; předchozí"
+
+#: controllers/editors_controller.php:144
+#: controllers/editors_controller.php:146
+msgid "editors_review_queue_pagetitle"
+msgstr "Fronta kontroly"
+
+#. %1 is the add-ons rank in the queue, %2 is the total queue length
+#: views/editors/review.thtml:47
+msgid "editors_review_rank_in_queue"
+msgstr "<strong># %1$s</strong> z&nbsp;%2$s ve frontÄ›"
+
+#. %1 is the add-ons rank in the queue, %2 is the total queue length. Both numbers
+#: views/editors/review.thtml:45
+msgid "editors_review_rank_in_queue_filtered"
+msgstr "<strong># %1$s</strong> z %2$s, které jsou ve frontě (filtrováno)"
+
+#: views/editors/review.thtml:223
+msgid "editors_review_submit_process_action"
+msgstr "Provést akci"
+
+#: views/editors/review.thtml:293
+msgid "editors_review_th_action"
+msgstr "Akce"
+
+#: views/editors/review.thtml:294
+msgid "editors_review_th_comments"
+msgstr "Komentáře"
+
+#: views/editors/review.thtml:291
+msgid "editors_review_th_date"
+msgstr "Datum"
+
+#: views/editors/review.thtml:292
+msgid "editors_review_th_reviewer"
+msgstr "Kontrolor"
+
+#: views/editors/review.thtml:290
+msgid "editors_review_th_version_file"
+msgstr "Verze/soubor"
+
+#: views/editors/review.thtml:217
+msgid "editors_review_update_notify_once"
+msgstr ""
+"Upozornit na následující aktualizace tohoto doplňku. (Postupné aktualizace "
+"nebudou generovat e-mail.)"
+
+#: controllers/editors_controller.php:298
+msgid "editors_reviewed_successfully"
+msgstr "Kontrola úspěšně provedena."
+
+#: views/editors/reviews_queue.thtml:106
+msgid "editors_reviews_action_delete_review"
+msgstr "Smazat kontrolu"
+
+#: views/editors/reviews_queue.thtml:104
+msgid "editors_reviews_action_keep"
+msgstr "Odstranit hlášení a ponechat recenzi"
+
+#: views/editors/reviews_queue.thtml:102
+msgid "editors_reviews_action_skip"
+msgstr "PÅ™eskoÄit"
+
+#: views/editors/reviews_queue.thtml:100
+msgid "editors_reviews_header_action"
+msgstr "Akce"
+
+#: views/editors/reviews_queue.thtml:67
+msgid "editors_reviews_in_reply_to"
+msgstr "V odpovědi uživatele:"
+
+#: controllers/editors_controller.php:748
+msgid "editors_reviews_processed"
+msgstr "Kontroly úspěšně provedeny!"
+
+#: views/editors/reviews_queue.thtml:117
+msgid "editors_reviews_queue_empty"
+msgstr "V souÄasnosti nejsou žádné požadavky na kontrolu."
+
+#: views/editors/reviews_queue.thtml:111
+msgid "editors_reviews_submit_process_reviews"
+msgstr "Provést kontrolu"
+
+#: controllers/editors_controller.php:691
+msgid "editors_site_specific"
+msgstr "Pro specifický server"
+
+#: controllers/editors_controller.php:348
+msgid "editors_tested_app"
+msgstr "Testovaná aplikace"
+
+#: controllers/editors_controller.php:347
+msgid "editors_tested_os"
+msgstr "Testovaný operaÄní systém"
+
+#: views/editors/queue.thtml:151
+msgid "editors_th_additional_info"
+msgstr "Doplňující informace"
+
+#: views/editors/featured.thtml:63 views/editors/queue.thtml:109
+#: views/admin/flagged_queue.thtml:53
+msgid "editors_th_addon"
+msgstr "Doplněk"
+
+#: views/editors/queue.thtml:125
+msgid "editors_th_addontype"
+msgstr "Typ"
+
+#: views/editors/featured.thtml:64
+msgid "editors_th_locales"
+msgstr "Omezit na lokalizace?"
+
+#: views/editors/queue.thtml:148
+msgid "editors_th_nomination_age"
+msgstr "ÄŒas ve frontÄ›"
+
+#: views/editors/queue.thtml:101 views/editors/queue.thtml:117
+#: views/editors/queue.thtml:144
+msgid "editors_th_sort_ascending"
+msgstr "Vzestupné řazení"
+
+#: views/editors/queue.thtml:105 views/editors/queue.thtml:121
+#: views/editors/queue.thtml:140
+msgid "editors_th_sort_descending"
+msgstr "Sestupné řazení"
+
+#. %s is a number
+#: controllers/editors_controller.php:1036
+#, php-format
+msgid "editors_x_days"
+msgstr "%s dní"
+
+#. %s is a number
+#: controllers/editors_controller.php:1044
+#, php-format
+msgid "editors_x_hours"
+msgstr "%s hodin"
+
+#. %s is a number
+#: controllers/editors_controller.php:1052
+#, php-format
+msgid "editors_x_minutes"
+msgstr "%s minut"
+
+#: views/errors/error401.thtml:50 controllers/components/simple_acl.php:81
+#: controllers/components/simple_acl.php:82
+#: controllers/components/simple_acl.php:83 controllers/components/amo.php:607
+#: controllers/components/amo.php:608 controllers/components/amo.php:609
+#: controllers/reviews_controller.php:353
+#: controllers/reviews_controller.php:485
+#: controllers/collections_controller.php:438
+#: controllers/collections_controller.php:496
+#: controllers/collections_controller.php:504
+#: controllers/collections_controller.php:971
+#: controllers/collections_controller.php:1034
+#: controllers/collections_controller.php:1077
+msgid "error_access_denied"
+msgstr "Přístup zamítnout"
+
+#: views/errors/error401.thtml:52
+msgid "error_access_denied_message"
+msgstr "K zobrazení požadované stránky nemáte dostateÄné oprávnÄ›ní."
+
+#: controllers/collections_controller.php:1039
+msgid "error_addon_exists"
+msgstr "Doplněk již existuje!"
+
+#: controllers/developers_controller.php:200
+#: controllers/developers_controller.php:593
+#: controllers/developers_controller.php:1016
+#: controllers/developers_controller.php:1429
+#: controllers/downloads_controller.php:95
+#: controllers/downloads_controller.php:102
+#: controllers/downloads_controller.php:164
+#: controllers/statistics_controller.php:135
+#: controllers/previews_controller.php:115
+#: controllers/previews_controller.php:206
+#: controllers/previews_controller.php:307
+#: controllers/reviews_controller.php:77
+#: controllers/reviews_controller.php:240
+#: controllers/reviews_controller.php:332
+#: controllers/reviews_controller.php:340 controllers/api_controller.php:123
+#: controllers/api_controller.php:759 controllers/addons_controller.php:131
+#: controllers/addons_controller.php:197
+#: controllers/addons_controller.php:1407
+#: controllers/addons_controller.php:1465
+#: controllers/addons_controller.php:1469
+#: controllers/addons_controller.php:1503
+#: controllers/editors_controller.php:265
+#: controllers/collections_controller.php:1041
+#: controllers/collections_controller.php:1074
+msgid "error_addon_notfound"
+msgstr "Doplněk nenalezen!"
+
+#: controllers/files_controller.php:83 controllers/files_controller.php:196
+msgid "error_addon_notviewable"
+msgstr "Tento doplněk zde nelze zobrazit."
+
+#: controllers/reviews_controller.php:246
+msgid "error_addon_selfreview"
+msgstr "Nelze recenzovat svůj vlastní doplněk."
+
+#: controllers/addons_controller.php:970
+msgid "error_browse_no_addons"
+msgstr "V této kategorii nejsou žádné doplňky."
+
+#: controllers/api_controller.php:424
+msgid "error_collection_feed_notfound"
+msgstr "Kanál doplňku nenalezen."
+
+#: views/users/register.thtml:65 views/users/edit.thtml:194
+msgid "error_email_invalid"
+msgstr "Tato e-mailová adresa není platná."
+
+#: views/users/pwreset.thtml:74 views/users/register.thtml:70
+#: views/users/register.thtml:80 views/users/register.thtml:86
+#: views/users/edit.thtml:105 views/users/edit.thtml:111
+#: views/users/edit.thtml:192 views/admin/users_edit.thtml:78
+#: views/admin/users_edit.thtml:83 views/reviews/add.thtml:80
+#: views/reviews/add.thtml:104
+msgid "error_field_required"
+msgstr "Tato položka nesmí být prázdná."
+
+#: controllers/files_controller.php:75 controllers/files_controller.php:93
+#: controllers/files_controller.php:96 controllers/files_controller.php:163
+#: controllers/files_controller.php:176 controllers/files_controller.php:185
+#: controllers/files_controller.php:204 controllers/editors_controller.php:412
+msgid "error_file_notfound"
+msgstr "Soubor nebyl nalezen!"
+
+#. %s is a filename
+#: controllers/editors_controller.php:430
+#, php-format
+msgid "error_file_x_notfound"
+msgstr "Chyba souboru: %s neexistuje."
+
+#: views/collections/add.thtml:55 views/collections/edit.thtml:89
+#: views/users/register.thtml:54 views/users/edit.thtml:81
+#: views/reviews/add.thtml:70 controllers/groups_controller.php:80
+#: controllers/groups_controller.php:102
+msgid "error_formerrors"
+msgstr ""
+"Tento formulář obsahuje chyby. Opravte je prosím a formulář znova odešlete."
+
+#: views/users/register.thtml:109
+msgid "error_invalid_captcha"
+msgstr "Neplatný ověřovací kód. Zkuste to prosím znova!"
+
+#: views/users/register.thtml:100 views/users/edit.thtml:125
+#: views/admin/users_edit.thtml:101
+msgid "error_invalid_url"
+msgstr ""
+"Tato adresa nemá platný formát. Platné adresy mají tvar http://moje.domena."
+"cz/moje-stranka/."
+
+#. %s is a string representing what's missing. Example: file_id
+#: controllers/downloads_controller.php:65
+#: controllers/users_controller.php:185 controllers/users_controller.php:264
+#: controllers/users_controller.php:559 controllers/users_controller.php:653
+#: controllers/reviews_controller.php:71
+#: controllers/reviews_controller.php:234
+#: controllers/reviews_controller.php:325
+#: controllers/reviews_controller.php:473
+#: controllers/reviews_controller.php:475
+#: controllers/addons_controller.php:182
+#: controllers/addons_controller.php:1381
+#: controllers/addons_controller.php:1455
+#: controllers/collections_controller.php:266
+#: controllers/collections_controller.php:285
+#: controllers/collections_controller.php:346
+#: controllers/collections_controller.php:443
+#: controllers/collections_controller.php:482
+#: controllers/collections_controller.php:936
+#: controllers/collections_controller.php:959
+#: controllers/collections_controller.php:960
+#: controllers/collections_controller.php:975
+#: controllers/collections_controller.php:977
+#: controllers/collections_controller.php:994
+#: controllers/collections_controller.php:1003
+#: controllers/collections_controller.php:1016
+#: controllers/collections_controller.php:1017
+#: controllers/collections_controller.php:1024
+#: controllers/collections_controller.php:1070
+#: controllers/collections_controller.php:1090
+#, php-format
+msgid "error_missing_argument"
+msgstr "Chybějící argument: %s"
+
+#: controllers/components/amo.php:507 controllers/components/amo.php:532
+msgid "error_no_files_in_addon"
+msgstr "Soubory nenalezeny"
+
+#: controllers/previews_controller.php:200
+msgid "error_preview_notfound"
+msgstr "Náhled nebyl nalezen!"
+
+#: views/addons/display.thtml:400 views/reviews/add.thtml:98
+msgid "error_review_rating_required"
+msgstr "Musíte zvolit hodnocení."
+
+#: controllers/users_controller.php:160
+msgid "error_user_already_confirmed"
+msgstr "Tento uživatelský dokument je již aktivován."
+
+#: controllers/users_controller.php:202 controllers/users_controller.php:276
+#: controllers/users_controller.php:569 controllers/users_controller.php:581
+#: controllers/users_controller.php:587 controllers/users_controller.php:610
+#: controllers/users_controller.php:627
+msgid "error_user_badconfirmationcode"
+msgstr "Å patný aktivaÄní kód!"
+
+#: views/users/pwreset.thtml:79 views/users/register.thtml:75
+#: views/users/edit.thtml:183
+msgid "error_user_confirmpw_nomatch"
+msgstr "Hesla nesouhlasí."
+
+#: views/users/register.thtml:65 views/users/edit.thtml:190
+#: controllers/users_controller.php:617
+msgid "error_user_email_notunique"
+msgstr "Tuto e-mailovou adresu již používá jiný uživatel."
+
+#: controllers/users_controller.php:596
+msgid "error_user_emailchange_expired"
+msgstr ""
+"Platnost tohoto potvrzení vypršela. Ve svém profilu si prosím opět změňte "
+"svůj e-mail. Ihned po obdržení potvrzovacího e-mailu, klepněte na zaslaný "
+"odkaz."
+
+#: controllers/collections_controller.php:985
+msgid "error_user_exists"
+msgstr ""
+"Uživatelé mohou mít ve stejný Äas pouze jednu roli. PÅ™ed pokraÄováním "
+"odstraňte uživatele z jakékoliv existující role."
+
+#: views/users/register.thtml:91 views/users/edit.thtml:116
+#: views/admin/users_edit.thtml:88
+msgid "error_user_nickname_notunique"
+msgstr "Tuto přezdívku používá již jiný uživatel."
+
+#: views/users/pwreset.thtml:54 controllers/users_controller.php:191
+#: controllers/users_controller.php:270 controllers/users_controller.php:603
+#: controllers/users_controller.php:659
+#: controllers/collections_controller.php:988
+#: controllers/collections_controller.php:998
+msgid "error_user_notfound"
+msgstr "Uživatel nenalezen!"
+
+#: views/users/activatefirst.thtml:47
+msgid "error_user_unconfirmed"
+msgstr ""
+"Nejprve prosím aktivujte svůj uživatelský úÄet pomocí kódu, který jste "
+"obdrželi v&nbsp;e-mailu."
+
+#: views/users/login.thtml:67
+msgid "error_username_or_pw_wrong"
+msgstr "Chybné uživatelské jméno a nebo heslo!"
+
+#: controllers/editors_controller.php:260
+msgid "error_version_notfound"
+msgstr "Verze nenalezena!"
+
+#: views/users/delete.thtml:125 views/users/edit.thtml:173
+msgid "error_wrong_password"
+msgstr "Vloženo chybné heslo!"
+
+#: views/elements/amo2009/homepage_addon.thtml:122
+#: views/elements/feature.thtml:122
+msgid "feature_learnmore"
+msgstr "Více informací"
+
+#. %1 is the add-on name
+#: views/elements/amo2009/homepage_addon.thtml:123
+#: views/elements/feature.thtml:123
+#, php-format
+msgid "feature_learnmore_about_addon"
+msgstr "Více informací o&nbsp;doplňku %1$s"
+
+#. %1$s is a number
+#: views/elements/amo2009/reviews.thtml:52
+#: views/elements/addon_listitem.thtml:112 views/elements/feature.thtml:99
+#: views/addons/browse_thumbs.thtml:86
+#, php-format
+msgid "feature_reviews"
+msgid_plural "feature_reviews"
+msgstr[0] "%1$s recenze"
+msgstr[1] "%1$s recenze"
+msgstr[2] "%1$s recenzí"
+
+#: views/elements/amo2009/homepage_addon.thtml:127
+#: views/elements/feature.thtml:127
+msgid "feature_view_more_from_category"
+msgstr "Zobrazit více z&nbsp;kategorie"
+
+#. This appears on a page that views the source of an add-on. This link will return
+#. the user to the add-on's main page
+#: views/files/browse.thtml:65
+msgid "file_browser_link_addon"
+msgstr "Zpět na stránku doplňku"
+
+#. There is a list of directories and files on the page. Clicking this will show the
+#. contents of all the directories (normally you would click on each one to see the
+#. contents)
+#: views/files/browse.thtml:67
+msgid "file_browser_link_expand_all"
+msgstr "Rozbalit vše"
+
+#. This appears on a page that views the source of an add-on. This link will return
+#. the user to the add-on's review page (it only appears if the add-on is being
+#. reviewed)
+#: views/files/browse.thtml:64
+msgid "file_browser_link_review"
+msgstr "Zpět na stránku recenzí"
+
+#. The title of the page for viewing an add-on's source.
+#. %1$s is the name of the add-on
+#. %2$s is the name of the current application (e.g. Firefox or Thunderbird)
+#: views/files/browse.thtml:46
+msgid "file_browser_title"
+msgstr "%1$s :: ProhlížeÄ souborů :: Doplňky aplikace %2$s"
+
+#. This appears on a page that views the source of an add-on. There is a list of
+#. directories and files on the page. Clicking this link will toggle between an
+#. expanded or a collapsed list. This string should be kept short.
+#: views/files/browse.thtml:68
+msgid "file_browser_toggle_expand_collapse"
+msgstr "+/-"
+
+#. Link text for the AMO About page.
+#: views/elements/footer.thtml:72 views/layouts/amo2009.thtml:341
+msgid "footer_a_about"
+msgstr "O nás"
+
+#. Link text to the AMO blog.
+#: views/elements/footer.thtml:74 views/layouts/amo2009.thtml:343
+msgid "footer_a_blog"
+msgstr "Blog"
+
+#. Link text to the Frequently Asked Questions page.
+#: views/elements/footer.thtml:73 views/layouts/amo2009.thtml:342
+msgid "footer_a_faq"
+msgstr "Otázky"
+
+#. Full text for the FAQ abbreviation.
+#: views/elements/footer.thtml:73 views/pages/collector_features.thtml:72
+#: views/layouts/amo2009.thtml:342
+msgid "footer_abbr_faq"
+msgstr "Často kladené otázky"
+
+#: views/elements/footer.thtml:67 views/layouts/amo2009.thtml:336
+msgid "footer_all_rights_reserved"
+msgstr "Všechna práva vyhrazena."
+
+#: views/elements/footer.thtml:67 views/layouts/amo2009.thtml:336
+msgid "footer_copyright"
+msgstr "Copyright"
+
+#: views/elements/footer.thtml:71 views/layouts/amo2009.thtml:340
+msgid "footer_credits"
+msgstr "Autoři"
+
+#: views/elements/footer.thtml:76 views/layouts/amo2009.thtml:346
+msgid "footer_disclaimer"
+msgstr ""
+"Mozilla poskytuje rozcestník na tyto aplikace v&nbsp;dobré vůli. Nezastupuje "
+"autory těchto aplikací ani neposkytuje žádné informace, které se jich "
+"týkají. Jakékoliv dotazy, stížnosti, Äi požadavky týkající se tÄ›chto "
+"aplikací musí být adresovány příslušným poskytovatelům daného software."
+
+#: views/elements/footer.thtml:61 views/layouts/amo2009.thtml:332
+msgid "footer_lang_form_lang_submit_go"
+msgstr "Přejít"
+
+#: views/elements/footer.thtml:70 views/layouts/amo2009.thtml:339
+msgid "footer_legal_notices"
+msgstr "Právní omezení"
+
+#: views/elements/footer.thtml:50 views/layouts/amo2009.thtml:321
+msgid "footer_other_languages"
+msgstr "Další jazyky:"
+
+#: views/elements/footer.thtml:69 views/layouts/amo2009.thtml:338
+msgid "footer_privacy_policy"
+msgstr "Zásady ochrany soukromí"
+
+#: models/addontype.php:79
+msgid "general_addontype_dict"
+msgstr "Slovník"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:100
+msgid "general_addontype_dict_plural"
+msgstr "Slovníky"
+
+#: models/addontype.php:75
+msgid "general_addontype_extension"
+msgstr "Rozšíření"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:98
+msgid "general_addontype_extension_plural"
+msgstr "Rozšíření"
+
+#: models/addontype.php:85
+msgid "general_addontype_lpaddon"
+msgstr "Jazykový balíÄek (doplnÄ›k)"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:103
+msgid "general_addontype_lpaddon_plural"
+msgstr "Jazykové balíÄky (doplnÄ›k)"
+
+#: models/addontype.php:83
+msgid "general_addontype_lpapp"
+msgstr "Jazykový balíÄek (aplikace)"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:102
+msgid "general_addontype_lpapp_plural"
+msgstr "Jazykové balíÄky (aplikace)"
+
+#: models/addontype.php:87
+msgid "general_addontype_plugin"
+msgstr "Zásuvný modul"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:104
+msgid "general_addontype_plugin_plural"
+msgstr "Zásuvné moduly"
+
+#: models/addontype.php:81
+msgid "general_addontype_search"
+msgstr "Vyhledávací modul"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:101
+msgid "general_addontype_search_plural"
+msgstr "Vyhledávací moduly"
+
+#: models/addontype.php:77
+msgid "general_addontype_theme"
+msgstr "Motivy vzhledu"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:99
+msgid "general_addontype_theme_plural"
+msgstr "Motivy vzhledu"
+
+#: config/language.php:367
+msgid "general_languages_all_locales"
+msgstr "VÅ¡echny jazyky"
+
+#: views/layouts/amo2009.thtml:249
+msgid "header_brand_name"
+msgstr "Mozilla"
+
+#. %1$s is the application name. Example: Firefox
+#: views/elements/header.thtml:111 views/elements/header.thtml:122
+#: views/layouts/amo2009.thtml:248
+#, php-format
+msgid "header_home_tooltip"
+msgstr "Návrat na titulní stránku doplňků aplikace %1$s"
+
+#: views/elements/header.thtml:87
+msgid "header_main_firefox_header"
+msgstr "Doplňky Firefoxu"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:218
+msgid "header_main_firefox_header_with_logo"
+msgstr ""
+"Doplňky <img alt=\"Firefox\" src=\"%1$s\" /> <strong>Firefoxu</strong>"
+
+#: views/elements/header.thtml:99
+msgid "header_main_header"
+msgstr "Doplňky"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:242
+msgid "header_main_header_with_logo"
+msgstr "Doplňky <img alt=\"Doplňky\" src=\"%1$s\" />"
+
+#: views/elements/header.thtml:90
+msgid "header_main_seamonkey_header"
+msgstr "Doplňky Seamonkey"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:224
+msgid "header_main_seamonkey_header_with_logo"
+msgstr ""
+"Doplňky <img alt=\"seamonkey\" src=\"%1$s\" /> <strong>SeaMonkey</strong>"
+
+#: views/elements/header.thtml:93
+msgid "header_main_sunbird_header"
+msgstr "Doplňky Sunbirdu"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:230
+msgid "header_main_sunbird_header_with_logo"
+msgstr ""
+"Doplňky <img alt=\"sunbird\" src=\"%1$s\" /> <strong>Sunbirdu</strong>"
+
+#: views/elements/header.thtml:96
+msgid "header_main_thunderbird_header"
+msgstr "Doplňky Thunderbirdu"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:236
+msgid "header_main_thunderbird_header_with_logo"
+msgstr ""
+"Doplňky <img alt=\"thunderbird\" src=\"%1$s\" /> <strong>Thunderbirdu</strong>"
+
+#: views/layouts/amo2009.thtml:205
+msgid "header_navaccess_applications_menu"
+msgstr "PÅ™eskoÄit na nabídku ostatních aplikací"
+
+#: views/layouts/amo2009.thtml:204
+msgid "header_navaccess_categories_menu"
+msgstr "PÅ™eskoÄit na nabídku kategorií"
+
+#: views/layouts/amo2009.thtml:202
+msgid "header_navaccess_main_content"
+msgstr "PÅ™eskoÄit na hlavní obsah"
+
+#: views/layouts/amo2009.thtml:203
+msgid "header_navaccess_search_form"
+msgstr "PÅ™eskoÄit na vyhledávací formulář"
+
+#: views/elements/header.thtml:62
+msgid "header_navlink_addons"
+msgstr "Doplňky"
+
+#: views/elements/developers/sidebar.thtml:72
+#: views/elements/developers/myaddons.thtml:50 views/elements/header.thtml:159
+#: views/addons/display.thtml:378
+msgid "header_navlink_login"
+msgstr "Přihlášení"
+
+#: views/elements/header.thtml:156 views/layouts/amo2009.thtml:304
+msgid "header_navlink_logout"
+msgstr "Odhlášení"
+
+#: views/elements/header.thtml:145 views/layouts/amo2009.thtml:303
+msgid "header_navlink_myaccount"
+msgstr "Můj úÄet"
+
+#: views/elements/header.thtml:158
+msgid "header_navlink_register"
+msgstr "Registrace"
+
+#. %1 is the URL to the registration page
+#. %2 is the URL to the login page
+#: views/layouts/amo2009.thtml:278
+msgid "header_navlink_register_or_login"
+msgstr "<a href=\"%1$s\">Registrace</a> nebo <a href=\"%2$s\">Přihlášení</a>"
+
+#: views/layouts/amo2009.thtml:285
+msgid "header_navlink_tools"
+msgstr "Nástroje"
+
+#. %s is the add-on name
+#: views/elements/collections_interactive_addon.thtml:62
+#: views/elements/amo2009/homepage_addon.thtml:77
+#: views/elements/addon_discussionheader.thtml:62
+#: views/elements/addon_listitem.thtml:67 views/elements/feature.thtml:84
+#: views/addons/category_landing.thtml:87 views/addons/browse_thumbs.thtml:60
+#, php-format
+msgid "img_preview_of"
+msgstr "Náhledy doplňku %s"
+
+#. %1 is the login URL for the link tag
+#. %2 is the link to an explanatory page.
+#: views/elements/amo2009/install.thtml:307 views/elements/install.thtml:255
+msgid "install_a_login_to_install"
+msgstr "Pro instalaci tohoto doplňku se musíte <a href=\"%1$s\">přihlásit</a>."
+
+#. %1 is the URL for the Experimental Add-ons section of the FAQ page
+#: views/elements/amo2009/install.thtml:283 views/elements/install.thtml:232
+msgid "install_button_confirm_exp_install"
+msgstr ""
+"Povolit instalaci tohoto experimentálního doplňku. <a href=\"%1$s\">Co to "
+"znamená?</a>"
+
+#. %1$s is the application name. Example: Firefox
+#. %2$s is an optional string used to specify a platform. Example: (Windows)
+#: views/elements/amo2009/install.thtml:128 views/elements/install.thtml:75
+#, php-format
+msgid "install_button_text"
+msgstr "Přidat do aplikace %s %s"
+
+#. %1 is the add-on name, %2 is the app name
+#: views/elements/amo2009/install.thtml:191
+#: views/elements/amo2009/install.thtml:206
+#: views/elements/amo2009/install.thtml:249
+#: views/elements/amo2009/install.thtml:298 views/elements/install.thtml:150
+#: views/elements/install.thtml:165 views/elements/install.thtml:202
+#: views/elements/install.thtml:246
+#, php-format
+msgid "install_button_title"
+msgstr "Přidá doplněk %1$s do aplikace %2$s"
+
+#. %1$s is the add-on name
+#: views/elements/amo2009/install.thtml:200 views/elements/install.thtml:159
+#, php-format
+msgid "install_download"
+msgstr "Stáhnout doplněk %1$s"
+
+#: views/elements/amo2009/install.thtml:147 views/elements/install.thtml:94
+msgid "install_error_addon_not_found"
+msgstr "Tento doplněk není dostupný."
+
+#: views/addons/dictionaries.thtml:65
+msgid "langtools_a11y_tablesummary"
+msgstr "PÅ™ehled slovníků a jazykových balíÄků."
+
+#: views/addons/dictionaries.thtml:47
+msgid "langtools_download_dictionary"
+msgstr "Stáhnout slovník"
+
+#: views/addons/dictionaries.thtml:48
+msgid "langtools_download_langpack"
+msgstr "Stáhnout jazykový balíÄek"
+
+#: views/addons/dictionaries.thtml:63 controllers/components/amo.php:685
+#: controllers/addons_controller.php:1239
+msgid "langtools_header_dicts_and_langpacks"
+msgstr "Slovníky a jazykové balíÄky"
+
+#: views/addons/dictionaries.thtml:44
+msgid "langtools_install_dictionary"
+msgstr "Instalovat slovník"
+
+#: views/addons/dictionaries.thtml:45
+msgid "langtools_install_langpack"
+msgstr "Instalovat jazykový balíÄek"
+
+#: views/addons/dictionaries.thtml:69
+msgid "langtools_tableheader_dictionary"
+msgstr "Slovníky"
+
+#: views/addons/dictionaries.thtml:70
+msgid "langtools_tableheader_langpack"
+msgstr "Jazykový balíÄek"
+
+#: views/addons/dictionaries.thtml:68
+msgid "langtools_tableheader_language"
+msgstr "Jazyk"
+
+#: models/license.php:65
+msgid "license_custom"
+msgstr "Vlastní licence"
+
+#: config/bootstrap.php:303
+msgid "licenses_bsd"
+msgstr "BSD licence"
+
+#: config/bootstrap.php:298
+msgid "licenses_gpl_2.0"
+msgstr "GNU General Public License, verze 2.0"
+
+#: config/bootstrap.php:299
+msgid "licenses_gpl_3.0"
+msgstr "GNU General Public License, verze 3.0"
+
+#: config/bootstrap.php:300
+msgid "licenses_lgpl_2.1"
+msgstr "GNU Lesser General Public License, verze 2.1"
+
+#: config/bootstrap.php:301
+msgid "licenses_lgpl_3.0"
+msgstr "GNU Lesser General Public License, verze 3.0"
+
+#: config/bootstrap.php:302
+msgid "licenses_mit"
+msgstr "MIT/X11 licence"
+
+#: config/bootstrap.php:297
+msgid "licenses_mpl_1.1"
+msgstr "Mozilla Public License, verze 1.1"
+
+#: views/users/emailchange.thtml:51 views/users/delete.thtml:55
+#: views/users/delete.thtml:137 views/users/edit.thtml:74
+#: views/reviews/flag.thtml:54
+msgid "link_return_to_front_page"
+msgstr "Klepnutím zde se vrátíte na titulní stránku."
+
+#: views/elements/amo2009/addon_list_options.thtml:46
+#: views/elements/addon_list_options.thtml:46
+msgid "list_sortby_date"
+msgstr "Datum"
+
+#: views/elements/amo2009/addon_list_options.thtml:47
+#: views/elements/addon_list_options.thtml:47
+msgid "list_sortby_downloads"
+msgstr "Stažení"
+
+#: views/elements/amo2009/addon_list_options.thtml:45
+#: views/elements/addon_list_options.thtml:45
+msgid "list_sortby_name"
+msgstr "Název"
+
+#: views/elements/amo2009/addon_list_options.thtml:48
+#: views/elements/addon_list_options.thtml:48
+msgid "list_sortby_rating"
+msgstr "Hodnocení"
+
+#: config/bootstrap.php:278
+msgid "main_prettyname_fennec"
+msgstr "Fennec"
+
+#: config/bootstrap.php:274
+msgid "main_prettyname_firefox"
+msgstr "Firefox"
+
+#: config/bootstrap.php:277
+msgid "main_prettyname_seamonkey"
+msgstr "SeaMonkey"
+
+#: config/bootstrap.php:276
+msgid "main_prettyname_sunbird"
+msgstr "Sunbird"
+
+#: config/bootstrap.php:275
+msgid "main_prettyname_thunderbird"
+msgstr "Thunderbird"
+
+#: views/elements/addon_categories.thtml:52
+msgid "nav_category_dicts_langpacks"
+msgstr "Slovníky a jazykové balíÄky"
+
+#: views/elements/addon_categories.thtml:55
+msgid "nav_category_themes"
+msgstr "Motivy vzhledu"
+
+#: views/elements/app_chooser.thtml:47 views/layouts/amo2009.thtml:255
+msgid "other_apps_tooltip"
+msgstr "Zobrazí doplňky pro ostatní aplikace"
+
+#. In a user list: user 1, user 2, "others"
+#: views/helpers/addons_html.php:222
+msgid "other_users"
+msgstr "další"
+
+#: controllers/pages_controller.php:90
+msgid "page_title_appversions"
+msgstr "Verze aplikace"
+
+#: controllers/pages_controller.php:115
+msgid "page_title_collector"
+msgstr "Sbírky doplňků"
+
+#: controllers/pages_controller.php:117
+msgid "page_title_collector_faq"
+msgstr "FAQ ke sbírce doplňků"
+
+#: controllers/pages_controller.php:119
+msgid "page_title_collector_features"
+msgstr "Vlastnosti rozšíření Sbírky doplňků"
+
+#: controllers/pages_controller.php:122
+msgid "page_title_collector_firstrun"
+msgstr "Vítá vás rozšíření Sbírky doplňků"
+
+#: controllers/pages_controller.php:92
+msgid "page_title_credits"
+msgstr "Autoři"
+
+#: controllers/pages_controller.php:113
+msgid "page_title_developer_faq"
+msgstr "Otázky pro vývojáře"
+
+#: controllers/pages_controller.php:111
+msgid "page_title_faq"
+msgstr "Často kladené otázky"
+
+#: controllers/pages_controller.php:94
+msgid "page_title_fashionyourfirefox_faq"
+msgstr "Vytvořte si své Firefox FAQ"
+
+#: controllers/pages_controller.php:101
+msgid "page_title_policy"
+msgstr "Zásady doplňků"
+
+#: controllers/pages_controller.php:103
+msgid "page_title_privacy"
+msgstr "Zásady ochrany soukromí Mozilly"
+
+#: controllers/pages_controller.php:105
+msgid "page_title_review_guide"
+msgstr "PříruÄka recenzenta"
+
+#: controllers/pages_controller.php:107
+msgid "page_title_sandbox"
+msgstr "Systém pískoviště"
+
+#: controllers/pages_controller.php:109
+msgid "page_title_submissionhelp"
+msgstr "Nápověda v&nbsp;odeslání"
+
+#: views/pages/appversions.thtml:87
+msgid "pages_appversions_guid"
+msgstr "GUID"
+
+#: views/pages/appversions.thtml:79 controllers/pages_controller.php:90
+msgid "pages_appversions_header"
+msgstr "Platné verze aplikace"
+
+#: views/pages/appversions.thtml:80
+msgid "pages_appversions_intro"
+msgstr ""
+"Všechny doplňky serveru doplňky Mozilly musí obsahovat soubor install.rdf "
+"obsahující alespoň jednu níže podporovanou aplikaci. Pro tyto aplikace jsou "
+"pak podporovány pouze verze uvedené níže."
+
+#. %s is a full <a> tag
+#: views/pages/appversions.thtml:93
+#, php-format
+msgid "pages_appversions_required_files"
+msgstr ""
+"Soubor install.rdf s&nbsp;požadovanými vlastnostmi, které jsou specifikovány "
+"%s, je do doplňku nutné zahrnout i v&nbsp;případě, že vámi podporovaná "
+"aplikace tento soubor nevyžaduje."
+
+#. this is the text inside of an <a> tag for pages_appversions_required_files. This
+#. should be fixed.
+#: views/pages/appversions.thtml:93
+msgid "pages_appversions_required_files_link"
+msgstr "zde"
+
+#: views/pages/appversions.thtml:88
+msgid "pages_appversions_versions"
+msgstr "Verze"
+
+#: views/pages/policy.thtml:51
+msgid "pages_policy_sandbox_link"
+msgstr "InformaÄní stránka pískoviÅ¡tÄ›"
+
+#: views/elements/pagination.thtml:53
+msgid "pagination_next_page"
+msgstr "následující"
+
+#: views/elements/pagination.thtml:52
+msgid "pagination_previous_page"
+msgstr "předchozí"
+
+#: views/elements/recaptcha.thtml:65
+msgid "recaptcha_enter_both_words"
+msgstr "Vložte prosím níže <strong>obě slova oddělená mezerou</strong>."
+
+#: views/elements/recaptcha.thtml:83
+msgid "recaptcha_enter_here"
+msgstr "Zde vložte odpovÄ›Ä"
+
+#: views/elements/recaptcha.thtml:74
+msgid "recaptcha_enter_whatyouhear"
+msgstr "Vložte prosím, co jste slyšeli."
+
+#. %1 is the link switching refreshing the captcha
+#. %2 is the link switching to a text captcha
+#: views/elements/recaptcha.thtml:77
+msgid "recaptcha_hardtohear_text"
+msgstr ""
+"Pokud tomu není rozumnět, můžete <a href=\"%1$s\">si poslechnout něco jiného "
+"</a> nebo <a href=\"%2$s\">se přepnou zpět na text</a>."
+
+#. %1 is the link switching refreshing the captcha
+#. %2 is the link switching to an audio captcha
+#: views/elements/recaptcha.thtml:68
+msgid "recaptcha_hardtoread_text"
+msgstr ""
+"Pokud je tento text těžko Äitelný, můžete <a href=\"%1$s\">zkusit jiná slova "
+"</a> nebo <a href=\"%2$s\">si ho poslechnout</a>."
+
+#: views/users/register.thtml:105
+msgid "recaptcha_label"
+msgstr "Jste ÄlovÄ›k?"
+
+#: views/users/register.thtml:106
+msgid "recaptcha_whatsthis"
+msgstr "Copak je to?"
+
+#: controllers/reviews_controller.php:559
+msgid "review_flag_error"
+msgstr "Chyba při nahlášení recenze!"
+
+#: models/reviews_moderation_flag.php:69
+msgid "review_flag_reason_bug_support"
+msgstr "Nevhodné oznámení chyby nebo žádost o&nbsp;podporu"
+
+#: views/reviews/display.thtml:103 views/reviews/display.thtml:186
+msgid "review_flag_reason_instructions"
+msgstr "Nahlásit toto hodnocení (zvolte důvod)"
+
+#: models/reviews_moderation_flag.php:67
+msgid "review_flag_reason_language"
+msgstr "Nevhodný jazyk/chování"
+
+#: models/reviews_moderation_flag.php:71
+msgid "review_flag_reason_other"
+msgstr "Jiné (prosím upřesněte)"
+
+#: models/reviews_moderation_flag.php:65
+msgid "review_flag_reason_spam"
+msgstr "Nevyžádaný příspÄ›vek Äi obsah nesouvisící s&nbsp;recenzí"
+
+#: views/reviews/display.thtml:91 views/reviews/display.thtml:175
+#: controllers/reviews_controller.php:555
+msgid "review_flag_success"
+msgstr "Děkujeme. Recenze bude zkontrolována redaktorem."
+
+#: views/reviews/display.thtml:41
+msgid "review_flag_this"
+msgstr "Nahlásit recenzi"
+
+#: views/reviews/display.thtml:42
+msgid "review_flag_this_titletip"
+msgstr ""
+"Je tato recenze nevhodná, chybná Äi se jedná o&nbsp;nevyžádanou zprávu? "
+"KlepnÄ›te zde a oznaÄte ji ke zkontrolování redaktorem."
+
+#. %1 is the URL of the support section, %2 for the review guidelines
+#: views/reviews/add.thtml:53
+msgid "review_guidelines_short"
+msgstr ""
+"<p>PÅ™eÄtÄ›te si prosím následující tipy:</p><ul><li>PiÅ¡te, jako byste se "
+"ptali přítele na jeho zkušenost s&nbsp;doplňkem. Poskytujte detailní a "
+"užiteÄné informace, jako jsou vlastnosti, které máte Äi nemáte rádi, jak "
+"snadno se vám doplněk používá a popis nedostatků, které má. Vyvarujte se "
+"obecných hlášek typu \"SkvÄ›lé\" Äi \"Å patné\" bez toho, abyste sdÄ›lili "
+"důvod, proÄ tomu tak je.</li><li>NepÅ™idávejte prosím do recenze příspÄ›vky "
+"s&nbsp;hlášením chyb. Vaše e-mailová adresa není viditelná ani vývojářům "
+"doplňků, kteří vás mohou chtít kontaktovat pro vyřešení vašeho problému. "
+"Podívejte se do <a href=\"%1$s\">sekce podpory</a>, kde naleznete, jak se "
+"vám může dostat podpory pro konkrétní doplněk.</li><li>Recenzi pište prosím "
+"ÄistÄ›, vyhýbejte se nesluÅ¡ným výrazům a nezadávejte do nich žádné osobní "
+"informace.</li></ul><p>PÅ™eÄtÄ›te si prosím <a href=\"%2$s\">pravidla pro "
+"přidávání recenze</a>, kde naleznete více informaci o&nbsp;tom, jak psát "
+"recenzi.</p>"
+
+#. %1 is the add-on name
+#: views/reviews/flag.thtml:56 views/reviews/display.thtml:55
+#: views/reviews/review_added.thtml:50
+#, php-format
+msgid "reviews_header"
+msgstr "Recenze doplňku %s"
+
+#: controllers/addons_controller.php:435
+msgid "rss_featuredaddons"
+msgstr "Zajímavé doplňky"
+
+#: controllers/addons_controller.php:432
+msgid "rss_newestaddons"
+msgstr "Nejnovější doplňky"
+
+#: controllers/addons_controller.php:434
+msgid "rss_popularaddons"
+msgstr "Populární doplňky"
+
+#: controllers/addons_controller.php:433
+msgid "rss_updatedaddons"
+msgstr "Aktualizované doplňky"
+
+#: views/elements/search_mini.thtml:70
+msgid "search"
+msgstr "Hledat"
+
+#: views/search/collections.thtml:51
+msgid "search_collections_header"
+msgstr "Výsledky vyhledávání sbírky"
+
+#: controllers/search_controller.php:297
+msgid "search_collections_pagetitle"
+msgstr "Výsledky vyhledávání sbírky"
+
+#: controllers/search_controller.php:99
+msgid "search_disabled"
+msgstr "Hledání je nyní zakázáno. Zkuste to zprosím později."
+
+#: views/elements/amo2009/search.thtml:188 views/elements/search.thtml:187
+#: views/elements/search_mini.thtml:54
+msgid "search_form_all_addons"
+msgstr "všechny doplňky"
+
+#. This string is in the main category dropdown when searching
+#: views/elements/amo2009/search.thtml:204
+msgid "search_form_all_collections"
+msgstr "všechny sbírky"
+
+#: views/elements/amo2009/search.thtml:184
+#: views/elements/amo2009/search.thtml:385
+#: views/elements/amo2009/search.thtml:408 views/elements/search.thtml:171
+#: views/elements/search.thtml:183 views/elements/search_mini.thtml:43
+#: views/elements/search_mini.thtml:49 views/layouts/mozilla.thtml:188
+msgid "search_form_default_text"
+msgstr "hledat doplňky"
+
+#: views/elements/amo2009/search.thtml:184
+#: views/elements/amo2009/search.thtml:404
+msgid "search_form_default_text_collections"
+msgstr "hledání sbírek"
+
+#: views/elements/amo2009/search.thtml:206 views/elements/search.thtml:202
+msgid "search_form_submit_tooltip"
+msgstr "Vyhledá doplňky"
+
+#: views/elements/amo2009/search.thtml:184 views/elements/search.thtml:183
+#: views/elements/search_mini.thtml:49
+msgid "search_form_tooltip"
+msgstr "Klepněte a zadejte název hledaného doplňku"
+
+#: views/elements/amo2009/search.thtml:186 views/elements/search.thtml:185
+#: views/elements/search_mini.thtml:52
+msgid "search_form_within"
+msgstr "v kategorii"
+
+#: views/addons/searchengines.thtml:118
+msgid "search_landing_all_search_engines"
+msgstr "Vyhledávací moduly"
+
+#: views/addons/searchengines.thtml:114
+msgid "search_landing_browse_search_engines"
+msgstr "Vyhledávací moduly dle typu"
+
+#: views/search/collections.thtml:58 views/search/index.thtml:59
+msgid "search_nothing_found"
+msgstr "Nic nebylo nalezeno."
+
+#: controllers/search_controller.php:185
+msgid "search_pagetitle"
+msgstr "Vyhledávání doplňků"
+
+#: controllers/search_controller.php:242
+msgid "search_rss_description"
+msgstr "Kanál s&nbsp;výsledky hledání"
+
+#. %s is the terms the user is searching for (a string)
+#: controllers/search_controller.php:241
+#, php-format
+msgid "search_rss_results_for"
+msgstr "Výsledky hledání pro: %s"
+
+#: views/elements/header.thtml:154 views/layouts/amo2009.thtml:296
+msgid "sidebar_navlink_admin_tools"
+msgstr "Nástroje správce"
+
+#: views/elements/header.thtml:146 views/layouts/amo2009.thtml:288
+msgid "sidebar_navlink_developer_tools"
+msgstr "Nástroje vývojáře"
+
+#: views/elements/header.thtml:148 views/layouts/amo2009.thtml:290
+msgid "sidebar_navlink_editor_tools"
+msgstr "Nástroje redaktora"
+
+#: views/layouts/amo2009.thtml:302
+msgid "sidebar_navlink_welcome"
+msgstr "Vítejte"
+
+#. %s is the user's name
+#: views/layouts/amo2009.thtml:302
+#, php-format
+msgid "sidebar_navlink_welcome_name"
+msgstr "Vítejte uživateli %s"
+
+#: views/elements/pitch.thtml:50 views/elements/pitch.thtml:55
+msgid "sidebar_pitch_dictionary"
+msgstr "Slovník"
+
+#: views/elements/pitch.thtml:72
+msgid "sidebar_pitch_featured_addons"
+msgstr "DoporuÄované doplňky"
+
+#: views/elements/pitch.thtml:61
+msgid "sidebar_pitch_looking_for"
+msgstr "Hledám:"
+
+#: views/elements/pitch.thtml:70
+msgid "sidebar_pitch_newest_addons"
+msgstr "Nejnovější doplňky"
+
+#: views/elements/pitch.thtml:49
+msgid "sidebar_pitch_search"
+msgstr "Vyhledávací modul"
+
+#: views/elements/pitch.thtml:69
+msgid "sidebar_pitch_subscribe_to"
+msgstr "Odebírat"
+
+#: views/elements/pitch.thtml:48 views/elements/pitch.thtml:54
+msgid "sidebar_pitch_theme"
+msgstr "Motiv vzhledu"
+
+#: views/elements/pitch.thtml:71
+msgid "sidebar_pitch_updated_addons"
+msgstr "Aktualizované doplňky"
+
+#. %1$s is a number
+#: views/helpers/localization.php:65 views/developers/versions_edit.thtml:95
+#: views/addons/dictionaries.thtml:92
+#, php-format
+msgid "size_kb"
+msgstr "%1$s KB"
+
+#: views/elements/amo2009/stars.thtml:57 views/elements/stars.thtml:63
+msgid "stars_not_yet_rated"
+msgstr "Nehodnoceno"
+
+#. %1 is the number of stars this add-on has
+#: views/elements/amo2009/stars.thtml:49 views/elements/stars.thtml:54
+#, php-format
+msgid "stars_rated_x_outof_5"
+msgstr "Hodnoceno %s z&nbsp;5 hvÄ›zdiÄek"
+
+#: views/statistics/addon.thtml:59
+msgid "statistics_addon_dashboard_link"
+msgstr "Stránka statistik"
+
+#: views/statistics/addon.thtml:58
+msgid "statistics_addon_developertools_link"
+msgstr "Nástroje vývojáře"
+
+#: views/statistics/addon.thtml:53
+msgid "statistics_addon_switch"
+msgstr "Přepnout doplněk"
+
+#. This is a date format.
+#. http://php.net/strftime
+#: views/statistics/rss/summary.thtml:54 views/statistics/addon.thtml:181
+msgid "statistics_date_shortmonth"
+msgstr "%e. %b."
+
+#. This is a date format.
+#. http://php.net/strftime
+#: views/statistics/rss/summary.thtml:40 views/statistics/addon.thtml:152
+msgid "statistics_date_shortmonthwithyear"
+msgstr "%e. %b. %Y"
+
+#. This is a date format.
+#. http://php.net/strftime
+#: views/statistics/rss/summary.thtml:41 views/statistics/rss/summary.thtml:48
+#: views/statistics/addon.thtml:161 views/statistics/addon.thtml:172
+msgid "statistics_date_weekdayshortmonth"
+msgstr "%A %e. %b."
+
+#. %1$s is an add-on name and version. Example: Add-on 3.5
+#: controllers/components/stats.php:519
+#, php-format
+msgid "statistics_events_addon_created"
+msgstr "Doplněk %1$s vytvořen"
+
+#. %1$s is an application name and version. Example: Firefox 3.5
+#: controllers/components/stats.php:500
+#, php-format
+msgid "statistics_events_app_released"
+msgstr "Aplikace %1$s vydána"
+
+#: views/statistics/addon.thtml:71
+msgid "statistics_help_close_link"
+msgstr "Zavřít"
+
+#: views/statistics/addon.thtml:60
+msgid "statistics_help_link"
+msgstr "Nápověda"
+
+#: views/statistics/index.thtml:83
+msgid "statistics_index_anotheraddon"
+msgstr " a nebo zvolte jiný doplněk"
+
+#: views/statistics/index.thtml:85
+msgid "statistics_index_anotheraddon_public"
+msgstr " a nebo zvolte jiný doplněk s&nbsp;veřejnými statistikami"
+
+#: views/statistics/index.thtml:71
+msgid "statistics_index_myaddons"
+msgstr "Pro zobrazení statistik zvolte některý ze&nbsp;svých doplňků"
+
+#: views/statistics/index.thtml:89
+msgid "statistics_index_selectaddon"
+msgstr "Pro zobrazení statistik zvolte některý z&nbsp;doplňků"
+
+#: views/statistics/index.thtml:91
+msgid "statistics_index_selectaddon_public"
+msgstr "Zvolte doplněk z&nbsp;veřejnými statistikami"
+
+#: views/statistics/index.thtml:39
+msgid "statistics_index_title"
+msgstr "Stránka statistik"
+
+#: views/statistics/index.thtml:97
+msgid "statistics_index_view_button"
+msgstr "Zobrazit statistiky"
+
+#: views/statistics/addon.thtml:222 controllers/statistics_controller.php:247
+msgid "statistics_js_download_csv"
+msgstr "Zobrazit tuto tabulku ve formátu CSV"
+
+#: controllers/statistics_controller.php:246
+msgid "statistics_js_dropdowns_none"
+msgstr "žádný"
+
+#: controllers/statistics_controller.php:245
+msgid "statistics_js_dropdowns_removeplot"
+msgstr "Odstranit diagram"
+
+#: controllers/statistics_controller.php:248
+msgid "statistics_js_groupby_selector_date"
+msgstr "Seskupit podle dne"
+
+#: controllers/statistics_controller.php:251
+msgid "statistics_js_groupby_selector_month"
+msgstr "Seskupit podle měsíce"
+
+#: controllers/statistics_controller.php:249
+msgid "statistics_js_groupby_selector_week"
+msgstr "Seskupit podle týdnek"
+
+#: controllers/statistics_controller.php:250
+msgid "statistics_js_groupby_selector_week_over_week"
+msgstr "Porovnat podle týdne"
+
+#: controllers/statistics_controller.php:260
+msgid "statistics_js_plotselection_foundinrange"
+msgstr "%s nalezen v&nbsp;rozsahu"
+
+#: controllers/statistics_controller.php:270
+msgid "statistics_js_plotselection_options_addplot_name"
+msgstr "Přidat diagram"
+
+#: controllers/statistics_controller.php:271
+msgid "statistics_js_plotselection_options_addplot_tooltip"
+msgstr "Přidá další diagram do tohoto grafu"
+
+#: controllers/statistics_controller.php:261
+msgid "statistics_js_plotselection_options_count_name_checked"
+msgstr "Skrýt celkový poÄet"
+
+#: controllers/statistics_controller.php:262
+msgid "statistics_js_plotselection_options_count_name_unchecked"
+msgstr "Zobrazit celkový poÄet"
+
+#: controllers/statistics_controller.php:263
+msgid "statistics_js_plotselection_options_count_tooltip"
+msgstr "Vykreslí na tento graf celkový poÄet"
+
+#: controllers/statistics_controller.php:275
+msgid "statistics_js_plotselection_options_csv_name"
+msgstr "Zobrazit data (CSV)"
+
+#: controllers/statistics_controller.php:276
+msgid "statistics_js_plotselection_options_csv_tooltip"
+msgstr "Zobrazí Äárkou oddÄ›lené hodnoty pro tyto data"
+
+#: controllers/statistics_controller.php:267
+msgid "statistics_js_plotselection_options_events_addon_name_checked"
+msgstr "Skrýt události doplňku %s"
+
+#: controllers/statistics_controller.php:268
+msgid "statistics_js_plotselection_options_events_addon_name_unchecked"
+msgstr "! události doplňku %s"
+
+#: controllers/statistics_controller.php:269
+msgid "statistics_js_plotselection_options_events_addon_tooltip"
+msgstr "VyznaÄí do diagramu datumy vydání doplňku"
+
+#: controllers/statistics_controller.php:264
+msgid "statistics_js_plotselection_options_events_firefox_name_checked"
+msgstr "Skrýt události Firefoxu"
+
+#: controllers/statistics_controller.php:265
+msgid "statistics_js_plotselection_options_events_firefox_name_unchecked"
+msgstr "Zobrazit události Firefoxu"
+
+#: controllers/statistics_controller.php:266
+msgid "statistics_js_plotselection_options_events_firefox_tooltip"
+msgstr "VyznaÄí do diagramu datumy vydání Firefoxu"
+
+#: controllers/statistics_controller.php:272
+msgid "statistics_js_plotselection_options_resize_name_checked"
+msgstr "Zmenšit graf"
+
+#: controllers/statistics_controller.php:273
+msgid "statistics_js_plotselection_options_resize_name_unchecked"
+msgstr "Zvětšit graf"
+
+#: controllers/statistics_controller.php:274
+msgid "statistics_js_plotselection_options_resize_tooltip"
+msgstr "Změní velikost grafu"
+
+#: controllers/statistics_controller.php:254
+msgid "statistics_js_plotselection_selector_adu"
+msgstr "Uživatelé za den"
+
+#: controllers/statistics_controller.php:256
+msgid "statistics_js_plotselection_selector_application"
+msgstr "Aplikace"
+
+#: controllers/statistics_controller.php:259
+msgid "statistics_js_plotselection_selector_custom"
+msgstr "Vlastní"
+
+#: controllers/statistics_controller.php:253
+msgid "statistics_js_plotselection_selector_downloads"
+msgstr "Stažení"
+
+#: controllers/statistics_controller.php:258
+msgid "statistics_js_plotselection_selector_os"
+msgstr "OperaÄní systém"
+
+#: controllers/statistics_controller.php:257
+msgid "statistics_js_plotselection_selector_status"
+msgstr "Stav doplňku"
+
+#: controllers/statistics_controller.php:252
+msgid "statistics_js_plotselection_selector_summary"
+msgstr "Celkový přehled"
+
+#: controllers/statistics_controller.php:255
+msgid "statistics_js_plotselection_selector_version"
+msgstr "Verze doplňku"
+
+#: controllers/components/stats.php:398
+msgid "statistics_longnames_application"
+msgstr "Aplikace"
+
+#: controllers/components/stats.php:400
+msgid "statistics_longnames_os"
+msgstr "OperaÄní systém"
+
+#: controllers/components/stats.php:399
+msgid "statistics_longnames_status"
+msgstr "Stav doplňku"
+
+#: controllers/components/stats.php:401
+msgid "statistics_longnames_unknown"
+msgstr "Neznámý"
+
+#: controllers/components/stats.php:397
+msgid "statistics_longnames_version"
+msgstr "Verze doplňku"
+
+#: views/statistics/addon.thtml:118
+msgid "statistics_notice_data_insufficient"
+msgstr ""
+"Pro zobrazení tohoto grafu stále není dostatek dat. Zkuste to prosím později."
+
+#: views/statistics/addon.thtml:130
+msgid "statistics_notice_data_none"
+msgstr ""
+"Pro zobrazení grafu toho doplňku nejsou žádná data. Zkuste to prosím za pár "
+"dní."
+
+#: views/statistics/addon.thtml:41
+msgid "statistics_notice_data_updating"
+msgstr ""
+"Statistiky doplňku jsou nyní aktualizovány. Zobrazovaná data můžou být proto "
+"nekompletní. Zkuste to prosím později."
+
+#: views/statistics/addon.thtml:136
+msgid "statistics_notice_disabled"
+msgstr "Stránka statistik je momentálně zakázánaná. Zkuste to prosím později."
+
+#: views/statistics/addon.thtml:123
+msgid "statistics_notice_nojavascript"
+msgstr "Pro zobrazení grafů na stránce statistik je vyžadován JavaScript."
+
+#: views/statistics/addon.thtml:44
+msgid "statistics_notice_settings_updated"
+msgstr "Nastavení bylo aktualizováno!"
+
+#: controllers/statistics_controller.php:60
+#: controllers/statistics_controller.php:71
+#: controllers/statistics_controller.php:74
+#: controllers/statistics_controller.php:240
+msgid "statistics_pagetitle"
+msgstr "Stránka statistik"
+
+#: views/statistics/addon.thtml:99
+msgid "statistics_plot_legend_adu"
+msgstr "PoÄet aktivních uživatelů za den"
+
+#: views/statistics/addon.thtml:95
+msgid "statistics_plot_legend_downloads"
+msgstr "PoÄet stažení za den"
+
+#: views/statistics/addon.thtml:107
+msgid "statistics_plot_options_zoomin_alt"
+msgstr "Zvětšit velikost"
+
+#: views/statistics/addon.thtml:106
+msgid "statistics_plot_options_zoomin_title"
+msgstr "Zvětšit velikost na jeden měsíc"
+
+#: views/statistics/addon.thtml:110
+msgid "statistics_plot_options_zoomout_alt"
+msgstr "Zmenšit velikost"
+
+#: views/statistics/addon.thtml:109
+msgid "statistics_plot_options_zoomout_title"
+msgstr "Zmenšit velikost na jeden měsíc"
+
+#: controllers/statistics_controller.php:283
+#, php-format
+msgid "statistics_rss_description"
+msgstr "Denní přehled statistik doplňku %1$s"
+
+#: views/statistics/rss/summary.thtml:68
+msgid "statistics_rss_title_fulldate"
+msgstr "%A, %e. %B %Y"
+
+#: views/statistics/rss/summary.thtml:68
+#, php-format
+msgid "statistics_rss_title_statsfordate"
+msgstr "Statistiky doplňku %1$s"
+
+#: views/statistics/settings.thtml:49
+msgid "statistics_settings_access_description"
+msgstr ""
+"Ve výchozím nastavení může tyto statistiky vidět pouze Mozilla a vy. Tyto "
+"statistiky lze ale zveřejnit a umožnit tak komukoliv vidět data vašeho "
+"doplňku."
+
+#: views/statistics/settings.thtml:48
+msgid "statistics_settings_access_heading"
+msgstr "Přístup ke statistikám"
+
+#: views/statistics/settings.thtml:51
+msgid "statistics_settings_access_private"
+msgstr "Soukromý"
+
+#: views/statistics/settings.thtml:51
+msgid "statistics_settings_access_private_description"
+msgstr "Pouze vy a Mozilla si může zobrazit statistiky tohoto doplňku"
+
+#: views/statistics/settings.thtml:52
+msgid "statistics_settings_access_public"
+msgstr "Veřejný"
+
+#: views/statistics/settings.thtml:52
+msgid "statistics_settings_access_public_description"
+msgstr "Kdokoliv si může zobrazit statistiky tohoto doplňku"
+
+#: views/statistics/addon.thtml:251
+msgid "statistics_settings_change_link"
+msgstr "Změnit nastavení"
+
+#: views/statistics/addon.thtml:253
+msgid "statistics_settings_confidential"
+msgstr "Považujte prosím tyto informace za důvěrné."
+
+#: views/statistics/addon.thtml:245
+msgid "statistics_settings_currently_private"
+msgstr "Tato stránka je v&nbsp;souÄasnosti <b>soukromá</b>."
+
+#: views/statistics/addon.thtml:241
+msgid "statistics_settings_currently_public"
+msgstr "Tato stránka je v&nbsp;souÄasnosti <b>veÅ™ejná</b>."
+
+#: views/statistics/addon.thtml:246
+msgid "statistics_settings_locked_alt"
+msgstr "Zamknuto"
+
+#: views/statistics/settings.thtml:57
+msgid "statistics_settings_return_link"
+msgstr "Návrat na stránku statistik"
+
+#: views/statistics/settings.thtml:56
+msgid "statistics_settings_save_button"
+msgstr "Uložit nastavení"
+
+#: views/statistics/settings.thtml:46
+#, php-format
+msgid "statistics_settings_title"
+msgstr "Nastavení stránky statistik pro doplněk %1$s"
+
+#: views/statistics/addon.thtml:242
+msgid "statistics_settings_unlocked_alt"
+msgstr "Odemknuto"
+
+#: controllers/components/stats.php:405
+msgid "statistics_shortnames_application"
+msgstr "Apl"
+
+#: controllers/components/stats.php:407
+msgid "statistics_shortnames_os"
+msgstr "OS"
+
+#: controllers/components/stats.php:406
+msgid "statistics_shortnames_status"
+msgstr "St"
+
+#: controllers/components/stats.php:408
+msgid "statistics_shortnames_unknown"
+msgstr "Nz"
+
+#: controllers/components/stats.php:404
+msgid "statistics_shortnames_version"
+msgstr "Verze"
+
+#: views/statistics/rss/summary.thtml:42 views/statistics/addon.thtml:192
+msgid "statistics_summary_downloads_average"
+msgstr "PrůmÄ›rný poÄet stažení za den"
+
+#: views/statistics/rss/summary.thtml:39
+msgid "statistics_summary_downloads_heading"
+msgstr "Stažení"
+
+#: views/statistics/rss/summary.thtml:41 views/statistics/addon.thtml:171
+msgid "statistics_summary_downloads_lastcount"
+msgstr "PoÄet za poslední den"
+
+#: views/statistics/rss/summary.thtml:43 views/statistics/addon.thtml:199
+msgid "statistics_summary_downloads_lastweek"
+msgstr "PoÄet stažení za poslední týden"
+
+#: views/statistics/rss/summary.thtml:40 views/statistics/addon.thtml:151
+msgid "statistics_summary_downloads_total"
+msgstr "Celkový poÄet stažení"
+
+#: views/statistics/rss/summary.thtml:40 views/statistics/addon.thtml:152
+#, php-format
+msgid "statistics_summary_downloads_total_sincedate"
+msgstr "Od %1$s"
+
+#: views/statistics/rss/summary.thtml:50 views/statistics/rss/summary.thtml:56
+#: views/statistics/addon.thtml:163 views/statistics/addon.thtml:183
+msgid "statistics_summary_nodata"
+msgstr "Chybí data"
+
+#: views/statistics/rss/summary.thtml:60 views/statistics/addon.thtml:195
+msgid "statistics_summary_updatepings_average"
+msgstr "PrůmÄ›rný poÄet aktivních uživatelů za den"
+
+#: views/statistics/rss/summary.thtml:52 views/statistics/addon.thtml:177
+msgid "statistics_summary_updatepings_changefromprevious"
+msgstr "ZmÄ›na z&nbsp;pÅ™edchozího poÄtu"
+
+#: views/statistics/rss/summary.thtml:54 views/statistics/addon.thtml:181
+#, php-format
+msgid "statistics_summary_updatepings_changefromprevious_ondate"
+msgstr "%1$s v&nbsp;%2$s"
+
+#: views/statistics/rss/summary.thtml:45
+msgid "statistics_summary_updatepings_heading"
+msgstr "Aktivní uživatelé za den"
+
+#: views/statistics/rss/summary.thtml:46 views/statistics/addon.thtml:157
+msgid "statistics_summary_updatepings_total"
+msgstr "PoÄet aktivních uživatelů za den"
+
+#: views/statistics/rss/summary.thtml:48 views/statistics/addon.thtml:161
+#, php-format
+msgid "statistics_summary_updatepings_total_ondate"
+msgstr "%1$s"
+
+#: views/statistics/rss/summary.thtml:61 views/statistics/addon.thtml:203
+msgid "statistics_summary_updatepings_weekly_average"
+msgstr "PrůmÄ›rný poÄet denních uživatelů v tomto týdnu"
+
+#. %s is a percentage, like '+22.33%'. It sits next to another number, so
+#. the implied meaning is 'percentage change' from the previous stat point.
+#: views/statistics/rss/summary.thtml:62 views/statistics/addon.thtml:205
+msgid "statistics_summary_updatepings_weekly_change"
+msgstr "%s oproti minulému týdnu"
+
+#: views/statistics/addon.thtml:65 controllers/statistics_controller.php:184
+#: controllers/statistics_controller.php:282
+#, php-format
+msgid "statistics_title_addon_stats"
+msgstr "Statistika doplňku %1$s"
+
+#: views/addons/themes_landing.thtml:113
+msgid "themes_landing_all_themes"
+msgstr "VÅ¡echny motivy vzhledu"
+
+#: views/addons/themes_landing.thtml:109
+msgid "themes_landing_browse_themes"
+msgstr "Procházet motivy vzhledu"
+
+#: views/users/edit.thtml:185
+msgid "user_change_email"
+msgstr "Změnit e-mailovou adresu"
+
+#: views/users/edit.thtml:169
+msgid "user_change_password"
+msgstr "Změnit heslo"
+
+#: views/users/edit.thtml:96
+msgid "user_change_password_or_email"
+msgstr "Změna hesla nebo e-mailu"
+
+#: controllers/users_controller.php:197
+msgid "user_confirmationcode_resent"
+msgstr "AktivaÄní kód byl znova poslán!"
+
+#. %1 is the email address, %2 is the URL of the user registration page
+#: views/users/delete.thtml:51
+msgid "user_del_account_deleted"
+msgstr ""
+"Váš uživatelský úÄet %1$s byl úspěšnÄ› smazán. Pakliže se budete chtít nÄ›kdy "
+"později vrátit, můžete se znova registrovat na <a href=\"%2$s\">stránce "
+"registrace nového uživatele</a>."
+
+#: views/users/delete.thtml:102
+msgid "user_del_community_sad"
+msgstr "Komunitu Mozilla Add-ons mrzí, že odcházíte."
+
+#: views/users/delete.thtml:123
+msgid "user_del_confirm_password"
+msgstr "Potvrzení hesla"
+
+#: views/users/delete.thtml:134
+msgid "user_del_deletenow"
+msgstr "Smazat můj uživatelský úÄet"
+
+#. %1 is the URL of the user's info page
+#: views/users/delete.thtml:64
+msgid "user_del_error_addons"
+msgstr ""
+"Pokud jste veden jako <a href=\"%1$s\">autor některého doplňku</a>, nemůže "
+"být váš uživatelský úÄet smazán. PÅ™ed smazáním svého úÄtu pověřte jinou "
+"osobou ve vašem vývojovém týmu odstraněním vaší osoby ze seznamu autorů "
+"doplňků. Poté již budete schopen svůj uživatelský úÄet odstranit."
+
+#. %1 is a link to the amo-editors mailing list
+#: views/users/delete.thtml:71
+msgid "user_del_error_addons_more_questions"
+msgstr "Pokud máte další otázky, kontaktujte prosím pro asistenci %1$s."
+
+#: views/users/delete.thtml:78
+msgid "user_del_error_checkbox"
+msgstr ""
+"PÅ™edtím, než budete moci smazat váš úÄet, musíte zaÅ¡krtnout pole \"Souhlasím…"
+"\""
+
+#: views/users/delete.thtml:84
+msgid "user_del_error_password"
+msgstr "Pro provedení tohoto kroku zadejte platné heslo."
+
+#. %1 is a link to the amo-admins mailing list
+#: views/users/delete.thtml:91
+msgid "user_del_error_unknown"
+msgstr ""
+"PÅ™i mazání úÄtu doÅ¡lo v&nbsp;neznámé chybÄ›. Kontaktujte prosím %1$s s&nbsp;"
+"informací o chybÄ› a my váš úÄet odstraníme. Omlouváme se za problémy."
+
+#: views/users/delete.thtml:110
+msgid "user_del_header_confirm_deletion"
+msgstr "Potvrzení smazání úÄtu"
+
+#. %1 is the user's email address
+#: views/users/delete.thtml:100
+msgid "user_del_header_delete_account"
+msgstr "Smazat uživatelský úÄet %1$s"
+
+#: views/users/delete.thtml:50
+msgid "user_del_header_farewell"
+msgstr "Sbohem!"
+
+#: views/users/delete.thtml:115
+msgid "user_del_nologin"
+msgstr "Nebudete již schopen se přihlásit na Mozilla Add-ons."
+
+#: views/users/delete.thtml:112
+msgid "user_del_permanently_removed_means"
+msgstr ""
+"Klepnutím na \"smazat\" bude váš úÄet <strong>natrvalo odstranÄ›n</strong>. "
+"To znamená:"
+
+#: views/users/delete.thtml:116
+msgid "user_del_reviews_anonymized"
+msgstr "Vaše recenze nebudou smazány, pouze s&nbsp;vámi nebudou již provázány."
+
+#. %1 is a link to the amo-editors mailing list
+#: views/users/delete.thtml:104
+msgid "user_del_specific_problem_editors"
+msgstr ""
+"Pokud máte konkrétní problém, s&nbsp;kterým vám můžeme pomoci, pak svůj úÄet "
+"nemažte a namísto toho nás kontaktujte na adrese %1$s. My se pokusíme váš "
+"problém vyřešit."
+
+#: views/users/delete.thtml:130
+msgid "user_del_understand_permanent"
+msgstr "Rozumím, že tento krok je nevratný."
+
+#: views/helpers/addons_html.php:192
+msgid "user_deleted_nickname"
+msgstr "Smazat uživatele"
+
+#. %1 is the new email address
+#: views/users/edit.thtml:71
+msgid "user_edit_confirm_email_sent"
+msgstr ""
+"Pro potvrzení nové e-mailové adresy byl odeslán e-mail na adresu %1$s. Pro "
+"potvrzení změny bude potřeba, abyste klepli na odkaz uvedený v&nbsp;tomto e-"
+"mailu. Do té doby zůstane přihlašování spojené s&nbsp;vaší aktuální e-"
+"mailovou adresou."
+
+#: views/users/edit.thtml:201
+msgid "user_edit_delete_user"
+msgstr "Smazat uživatelský úÄet"
+
+#. This contains the email sent to users when they signed up for a new
+#. account:
+#. %1 is the confirmation URL, %2 is the current app
+#: views/users/email/confirm_plain.thtml:6
+#, php-format
+msgid "user_email_confirm_account_nopass"
+msgstr ""
+"Vítejte na serveru doplňky Mozilly.\n"
+"\n"
+"PÅ™ed tím, než budete moci zaÄít využívat váš úÄet, je nutné ho aktivovat - "
+"to zaruÄí, že e-mailová adresa, kterou jste použily, je platná a je vaÅ¡e.\n"
+"K aktivaci úÄtu staÄí klepnout na následující odkaz, Äi tento odkaz "
+"zkopírovat do adresního řádku ve svém prohlížeÄi:\n"
+"\n"
+"%1$s\n"
+"\n"
+"Po úspěšné aktivaci svého úÄtu můžete tento e-mail smazat.\n"
+"\n"
+"Děkujeme za registraci na serveru doplňky Mozilly.\n"
+"-- Tým serveru doplňky Mozilly"
+
+#. %1 is the confirmation url, %2 is the application name
+#: views/users/email/emailchange_plain.thtml:5
+msgid "user_email_confirm_emailchange"
+msgstr ""
+"Požádali jste o&nbsp;zmÄ›nu e-mailové adresy u vaÅ¡eho úÄtu na %2$s Add-ons.\n"
+"\n"
+"Pokud chcete novou adresu potvrdit, klepnete na odkaz níže nebo jej "
+"zkopírujte a vložte do adresního řádku svého prohlížeÄe:\n"
+"\n"
+"%1$s\n"
+"\n"
+"Na potvrzení nové adresy máte 48 hodin. Pokud si již adresu nepřejete změnit "
+"postaÄí, když tento e-mail budete ignorovat.\n"
+"\n"
+"Díky!\n"
+"-- Tým %2$s Add-ons"
+
+#: controllers/users_controller.php:168
+#, php-format
+msgid "user_email_confirm_subject"
+msgstr "Doplňky Mozilly - aktivace úÄtu"
+
+#. This is the password reset email
+#. %1 is the pw reset URL, %2 is the application
+#: views/users/email/pwreset_plain.thtml:5
+#, php-format
+msgid "user_email_pwreset"
+msgstr ""
+"Žádost o&nbsp;obnovení hesla na serveru doplňky Mozilly\n"
+"\n"
+"Server doplňky Mozilly obdržel žádost na obnovení hesla úÄtu, který je "
+"provázán s&nbsp;tímto e-mailem. Pokud si přejete heslo změnit, klepněte "
+"prosím na následující odkaz nebo tento odkaz vložte do svého prohlížeÄe:\n"
+"\n"
+"%1$s\n"
+"\n"
+"Pokud jste změnu hesla nepožadovali, tento e-mail prosím ignorujte.\n"
+"\n"
+"S pozdravem,\n"
+"-- Tým serveru doplňky Mozilly"
+
+#: controllers/users_controller.php:245
+#, php-format
+msgid "user_email_pwreset_subject"
+msgstr "Doplňky Mozilly - obnovení hesla"
+
+#: views/users/emailchange.thtml:50
+msgid "user_emailchange_error"
+msgstr "Chyba!"
+
+#. %1 is the application name
+#: controllers/users_controller.php:533
+msgid "user_emailchange_subject"
+msgstr "PotvrÄte prosím zmÄ›nu své e-mailové adresy na stránkách %1$s doplňky"
+
+#: views/users/emailchange.thtml:48
+msgid "user_emailchange_success"
+msgstr "Úspěch!"
+
+#. %1 is the new email address
+#: views/users/emailchange.thtml:49
+msgid "user_emailchange_successful_description"
+msgstr ""
+"VaÅ¡e e-mailová adresa byla úspěšnÄ› zmÄ›nÄ›na. OdteÄ prosím používejte pro "
+"příhlášení %1$s."
+
+#: views/users/edit.thtml:134 views/admin/users_edit.thtml:111
+msgid "user_form_bio"
+msgstr "O mnÄ›"
+
+#: views/users/edit.thtml:135 views/admin/users_edit.thtml:112
+msgid "user_form_bio_description"
+msgstr ""
+"Pokud chcete, představte se komunitě. Tento text se zobrazí veřejně na "
+"stránce s informacemi o vás. Odřádkování bude zachováno, ale není povoleno "
+"HTML."
+
+#: views/users/pwreset.thtml:77 views/users/register.thtml:73
+#: views/users/edit.thtml:181
+msgid "user_form_confirmpassword"
+msgstr "Heslo znova"
+
+#: views/users/edit.thtml:145
+msgid "user_form_display_collections"
+msgstr "Zobrazit mé sebrané sbírky"
+
+#: views/users/edit.thtml:149
+msgid "user_form_display_collections_fav"
+msgstr "Zobrazit mé oblíbené sbírky"
+
+#: views/users/edit.thtml:86
+#, php-format
+msgid "user_form_editprofile"
+msgstr "Upravit profil uživatele %s"
+
+#: views/users/pwreset.thtml:52 views/users/login.thtml:81
+#: views/users/register.thtml:63 views/users/edit.thtml:187
+msgid "user_form_email"
+msgstr "E-mailová adresa"
+
+#: views/users/register.thtml:78 views/users/edit.thtml:103
+#: views/admin/users_edit.thtml:76
+msgid "user_form_firstname"
+msgstr "Křestní jméno"
+
+#: views/users/register.thtml:94 views/users/edit.thtml:119
+#: views/admin/users_edit.thtml:91
+msgid "user_form_hideemail"
+msgstr "Skrýt e-mailovou adresu"
+
+#: views/users/register.thtml:98 views/users/edit.thtml:123
+#: views/admin/users_edit.thtml:99
+msgid "user_form_homepage"
+msgstr "Adresa webové stránky"
+
+#: views/users/register.thtml:84 views/users/edit.thtml:109
+#: views/admin/users_edit.thtml:81
+msgid "user_form_lastname"
+msgstr "Příjmení"
+
+#: controllers/users_controller.php:333
+msgid "user_form_login"
+msgstr "Přihlášení"
+
+#: views/users/pwreset.thtml:72 views/users/edit.thtml:176
+msgid "user_form_newpassword"
+msgstr "Nové heslo"
+
+#: views/users/register.thtml:89 views/users/edit.thtml:114
+#: views/admin/users_edit.thtml:86
+msgid "user_form_nickname"
+msgstr "Přezdívka"
+
+#: views/users/edit.thtml:171
+msgid "user_form_oldpassword"
+msgstr "Původní heslo"
+
+#: views/users/edit.thtml:97 views/users/edit.thtml:200
+msgid "user_form_otheractions"
+msgstr "Další akce"
+
+#: views/users/login.thtml:85 views/users/register.thtml:68
+msgid "user_form_password"
+msgstr "Heslo"
+
+#: controllers/users_controller.php:93
+msgid "user_form_registration"
+msgstr "Registrace nového uživatele"
+
+#: views/users/login.thtml:90
+msgid "user_form_remember_me"
+msgstr "Zapamatovat si mÄ› na tomto poÄítaÄi"
+
+#: views/admin/users_edit.thtml:95
+msgid "user_form_showsandbox"
+msgstr "Zobrazit pískoviště"
+
+#: views/users/edit.thtml:205
+msgid "user_form_submit_edit"
+msgstr "Uložit"
+
+#: views/users/login.thtml:93
+msgid "user_form_submit_login"
+msgstr "Přihlášení"
+
+#: views/users/register.thtml:113
+msgid "user_form_submit_register"
+msgstr "Založit úÄet"
+
+#: views/users/info.thtml:75
+#, php-format
+msgid "user_info_usersince"
+msgstr "Uživatelem serveru doplňky Mozilly od"
+
+#: views/users/login.thtml:102
+msgid "user_login_register_link"
+msgstr "Založit nový úÄet"
+
+#: views/users/edit.thtml:160
+msgid "user_notifications_item_compat"
+msgstr "Kompatibilita doplňku (silnÄ› doporuÄováno)"
+
+#: views/users/edit.thtml:161
+msgid "user_notifications_item_events"
+msgstr "Nadcházející události a soutěže"
+
+#: views/users/edit.thtml:156
+msgid "user_notifications_none_available"
+msgstr "Nejsou dostupné žádné typy upozornění, které by šlo nastavit."
+
+#: views/users/edit.thtml:158
+msgid "user_notifications_select_topics"
+msgstr ""
+"ÄŒas od Äasu posílá Mozilla e-mail o&nbsp;nadcházejících vydání doplňků nebo "
+"událostech. Zvolte si prosím témata, která vás zajímají: "
+
+#: views/users/edit.thtml:164
+msgid "user_notifications_specific_contact"
+msgstr ""
+"Mozilla si vyhrazuje právo vás individuálně kontaktovat v otázkách ohledně "
+"vámi hostovaného doplňku."
+
+#: controllers/users_controller.php:543
+msgid "user_profile_edit_error"
+msgstr ""
+"Změněné údaje obsahují chyby. Opravte je prosím a formulář znova odešlete."
+
+#: controllers/users_controller.php:540
+msgid "user_profile_saved"
+msgstr "Profil aktualizován."
+
+#: views/users/pwreset.thtml:65
+#, php-format
+msgid "user_pwreset_for_email"
+msgstr "Heslo uživatele %s obnoveno"
+
+#: controllers/users_controller.php:226
+msgid "user_pwreset_header"
+msgstr "Obnovení hesla"
+
+#: views/users/login.thtml:103
+msgid "user_pwreset_link"
+msgstr "Zapomněli jste heslo?"
+
+#: controllers/users_controller.php:248
+msgid "user_pwreset_link_sent"
+msgstr "Odkaz pro obnovení hesla vám byl odeslán e-mailem."
+
+#: controllers/users_controller.php:304
+msgid "user_pwreset_okay"
+msgstr "Heslo úspěšně obnoveno."
+
+#: views/users/pwreset.thtml:82
+msgid "user_pwreset_submit_changepw"
+msgstr "Odeslat změněné heslo"
+
+#: views/users/pwreset.thtml:57
+msgid "user_pwreset_submit_sendlink"
+msgstr "Poslat odkaz na obnovení hesla"
+
+#: views/users/register_complete.thtml:51
+#, php-format
+msgid "user_register_amo_link"
+msgstr "doplňky Mozilly"
+
+#. %1 is the user's email address, %2 is the current app
+#: views/users/activatefirst.thtml:49
+#, php-format
+msgid "user_register_click_confirm_link"
+msgstr ""
+"Na vaši adresu %1$s byl odeslán e-mail obsahující odkaz k&nbsp;aktivaci "
+"úÄtu. PÅ™ed tím než se budete moci pÅ™ihlásit, si musíte svůj úÄet aktivovat "
+"klepnutím na tento odkaz."
+
+#. %1 is the user's email address
+#: views/users/register_complete.thtml:49
+#, php-format
+msgid "user_register_confirm_email_sent"
+msgstr ""
+"Na vaši adresu %1$s byl odeslán e-mail obsahující odkaz k&nbsp;aktivaci "
+"úÄtu. PÅ™ed tím než se budete moci pÅ™ihlásit, si musíte svůj úÄet aktivovat "
+"klepnutím na tento odkaz."
+
+#: views/users/activatefirst.thtml:51
+msgid "user_register_confirmation_link_text"
+msgstr "znova poslat aktivaÄní e-mail"
+
+#: views/users/register_complete.thtml:47
+msgid "user_register_congratulations"
+msgstr "Gratulujeme! Váš úÄet byl úspěšnÄ› vytvoÅ™en."
+
+#: views/users/register.thtml:50
+msgid "user_register_details"
+msgstr ""
+"<p>Registrace na AMO <strong>není vyžadována</strong>, pokud chcete pouze "
+"stahovat a instalovat veřejné doplňky.</p><p>Registrace je nutná pouze pokud:"
+"</p><ul><li>chcete recenzovat doplňky</li><li>jste vývojář a chcete na AMO "
+"hostovat svůj doplnÄ›k.</li></ul><p>Po vyplnÄ›ní registraÄního formuláře vám "
+"bude na zadanou adresu zaslán aktivaÄní e-mail s popisem jak postupovat pro "
+"dokonÄení registrace.</p><p>Také si můžete prostudovat naÅ¡e <a href='%1$s' "
+"title='Legal Notices'>právní omezení</a> a <a href='%2$s' title='Privacy "
+"Policy'>zásady ochrany soukromí</a>.</p>"
+
+#. %1 is the link to the "resend confirmation code" page
+#: views/users/activatefirst.thtml:51
+#, php-format
+msgid "user_register_resend_confirmation_link"
+msgstr ""
+"Pokud jste neobdrželi aktivaÄní e-mail, zkontrolujte prosím, zda ho váš "
+"poÅ¡tovní klient neoznaÄil jako \"nevyžádanou poÅ¡tu\". Pokud potÅ™ebujete, "
+"můžete si na svoji e-mailovou adresu uvedenou výše nechat %1$s."
+
+#. %1 is the link to the Mozilla Add-ons front page
+#: views/users/register_complete.thtml:51
+#, php-format
+msgid "user_register_welcome"
+msgstr "Děkujeme za zaregistrování a vítejte na serveru %1$s!"
+
+#: views/users/register.thtml:49
+msgid "user_register_welcome_header"
+msgstr "Vítejte na serveru addons.mozilla.org (AMO)!"
+
+#: views/users/register.thtml:81 views/users/edit.thtml:106
+msgid "user_required_firstlast_or_nickname"
+msgstr "Je vyžadováno jméno, příjmení Äi pÅ™ezdívka."
+
+#: views/users/edit.thtml:94 views/users/edit.thtml:142
+msgid "user_tab_collections"
+msgstr "Sbírky"
+
+#: views/users/edit.thtml:95 views/users/edit.thtml:154
+msgid "user_tab_notifications"
+msgstr "Upozornění"
+
+#: views/users/edit.thtml:93 views/users/edit.thtml:101
+msgid "user_tab_profile"
+msgstr "Uživatelský profil"
+
+#: controllers/users_controller.php:209
+msgid "user_verified_okay"
+msgstr "Úspěšně ověřeno!"
+
+#: controllers/users_controller.php:723
+msgid "users_delete_pagetitle"
+msgstr "Smazat uživatelský úÄet"
+
+#: controllers/users_controller.php:414
+msgid "users_edit_pagetitle"
+msgstr "Úprava uživatelského úÄtu"
+
+#: views/users/info.thtml:71
+msgid "users_info_aboutme"
+msgstr "O mnÄ›"
+
+#: views/users/info.thtml:96
+#, php-format
+msgid "users_info_addons_by_user"
+msgstr "Doplňky od uživatele %1$s"
+
+#: views/users/info.thtml:51
+msgid "users_info_author_name"
+msgstr "Jméno"
+
+#: views/users/info.thtml:48
+msgid "users_info_author_profile"
+msgstr "Profil autora"
+
+#. %s is the user name
+#: views/users/info.thtml:137
+msgid "users_info_collections_by_user"
+msgstr "Sbírky od %s"
+
+#: views/users/info.thtml:66
+msgid "users_info_email"
+msgstr "E-mailová adresa"
+
+#: views/users/info.thtml:155
+msgid "users_info_fav_collections_by_user"
+msgstr "Oblíbené sbírky"
+
+#: views/users/info.thtml:61
+msgid "users_info_homepage"
+msgstr "Domovská stránka"
+
+#: views/users/info.thtml:56
+msgid "users_info_nickname"
+msgstr "Přezdívka"
+
+#: controllers/users_controller.php:707
+#, php-format
+msgid "users_info_pagetitle"
+msgstr "Profil uživatele %1$s"
+
+#. %1 is the user's name
+#: views/users/info.thtml:116
+msgid "users_info_reviews_by_user"
+msgstr "Recenze od uživatele %s"
+
+#: controllers/users_controller.php:330 controllers/users_controller.php:332
+msgid "users_login_pagetitle"
+msgstr "Přihlášení uživatele"
+
+#. %1 is the link to the sandbox/policy explanation page
+#. This message is for a specific add-on not found
+#: views/users/login.thtml:53
+#, php-format
+msgid "users_login_sandbox_display_warning"
+msgstr ""
+"DoplnÄ›k, který hledáte, je v&nbsp;souÄasnosti na pískoviÅ¡ti. Pokud máte na "
+"serveru doplňky Mozilly úÄet, pak se prosím pÅ™ihlaste, a nebo si zjistÄ›te "
+"o&nbsp;pískovišti <a href=\"%1$s\">více informací.</a>"
+
+#. %1 is the link to the sandbox/policy explanation page
+#. This message is for any given sandbox-related page not found
+#: views/users/login.thtml:56
+#, php-format
+msgid "users_login_sandbox_page_warning"
+msgstr ""
+"Stránka, kterou hledáte, je souÄástí pískoviÅ¡tÄ›. Pokud máte na serveru "
+"doplňky Mozilly úÄet, pak se prosím pÅ™ihlaste, a nebo si zjistÄ›te o&nbsp;"
+"pískovišti <a href=\"%1$s\">více informací.</a>"
+
+#: controllers/users_controller.php:223 controllers/users_controller.php:225
+msgid "users_pwreset_pagetitle"
+msgstr "Obnovení uživatelského hesla"
+
+#: controllers/users_controller.php:90 controllers/users_controller.php:92
+msgid "users_register_pagetitle"
+msgstr "Registrace nového uživatele"
+
+#. %1$s is an addon name, like <a>Firebug</a>
+#. %2$s is a version number, like <a>1.2</a>
+#: views/versions/license.thtml:52
+msgid "versions_license_header_source"
+msgstr "Licence ke zdrojovém kódu %1$s %2$s"
+
+#: views/addons/category_landing.thtml:147
+msgid "view_recently_added"
+msgstr "Zobrazit všechny nedávno přidané"
+
+#: views/addons/category_landing.thtml:161
+msgid "view_top_downloads"
+msgstr "Zobrazit vÅ¡echny nejÄastÄ›ji stahované"
+
+#: views/addons/category_landing.thtml:175
+msgid "view_top_rated"
+msgstr "Zobrazit všechny nejlépe hodnocené"
+
+#~ msgid "collections_detail_js_loading"
+#~ msgstr "NaÄítání"
+
+#~ msgid "collections_detail_more_info"
+#~ msgstr "Zobrazit více informací"
+
+#~ msgid "home"
+#~ msgstr "Domů"
+
+#~ msgid "search_matching_addons_number"
+#~ msgid_plural "search_matching_addons_number"
+#~ msgstr[0] "%s odpovídající doplněk"
+#~ msgstr[1] "%s odpovídající doplňky"
+#~ msgstr[2] "%s odpovídajících doplňků"
diff --git a/site/app/locale/cs/pages/collector.thtml b/site/app/locale/cs/pages/collector.thtml
new file mode 100644
index 0000000..d6755fc
--- /dev/null
+++ b/site/app/locale/cs/pages/collector.thtml
@@ -0,0 +1,47 @@
+<h2>Sbírka doplňků pro Mozilla Firefox</h2>
+
+<p class="intro">UÄiňte vaÅ¡e pÅ™izpůsobení prohlížeÄe zajímavÄ›jší.</p>
+
+<div class="primary">
+ <p>Objevte nejlepší doplňky a organizujte vaÅ¡e oblíbené ve snadno spravovatelných sbírkách. Odebírejte je a obdivujte, jak roste poÄet jejich fanouÅ¡ků. Spravujte a aktualizujte vaÅ¡e vlastní sbírky.</p>
+</div>
+
+<div class="secondary">
+ <div class="highlight">
+ <h4>Stáhnout Správce sbírek:</h4>
+ %1$s
+ </div><!-- /.highlight -->
+</div>
+
+<div class="column-wrapper article-wrapper">
+
+ <div class="column first">
+ <div class="article">
+ <h3>DoporuÄené sbírky</h3>
+ <p>Odebírejte sbírky doplňků a zůstaňte informování o její aktualizacích. Pokud si vytvoříte vlastní sbírku, máže možnost říci, proÄ máte doplnÄ›k rád(a) a uvést bližší informace.</p>
+
+ </div>
+ </div>
+
+ <div class="column">
+ <div class="article">
+ <h3>Sdílení doplňků</h3>
+ <p>Řekněte známým o vašich objevech. Zvolte "Publikovat" a oni se dozví o zajímavých doplňcích přímo od vás.</p>
+ </div>
+
+ </div>
+
+
+ <div class="column">
+ <div class="article">
+ <h3>Synchronizace</h3>
+ <p>Oznamujte nové sbírky doplňků a posílejte odkazy, které zůstanou stálé. VÅ¡e díky automatické publikaci. Synchronizujte zařízení a mÄ›jte ve vÅ¡ech prohlížeÄích vaÅ¡i oblíbenou sbírku.</p>
+ </div>
+ </div>
+
+</div><!-- /.column-wrapper .article-wrapper -->
+
+<ul class="further-navigation">
+ <li><a href="%2$s">Vlastnosti rozšíření Sbírka doplňků</a></li>
+ <li><a href="%3$s">Často kladené otázky</a></li>
+</ul>
diff --git a/site/app/locale/cs/pages/collector_faq.thtml b/site/app/locale/cs/pages/collector_faq.thtml
new file mode 100644
index 0000000..3356282
--- /dev/null
+++ b/site/app/locale/cs/pages/collector_faq.thtml
@@ -0,0 +1,24 @@
+<h2>Často kladené otázky k rozšíření</h2>
+
+<dl class="faq">
+<dt>Co jsou sbírky?</dt>
+<dd>Sbírky jsou skupiny podobných doplňků seskupených pro snadné sdílení.</dd>
+
+<dt>Co je rozšíření Sbírky doplňků?</dt>
+<dd>Rozšíření Sbírky doplňků pro Firefox umožňuje snadnou synchronizaci s vašimi oblíbenými sbírkami. </dd>
+
+<dt>Co potřebuji, abych mohl rozšíření Sbírky doplňků používat?</dt>
+<dd>PotÅ™ebujete mít <a href="%s">úÄet na Mozilla Add-ons</a> a poslední verzi <a href="http://www.getfirefox.com">Firefoxu</a>.</dd>
+
+<dt>Jak mohu sbírku odebírat?</dt>
+<dd>Sbírku lze odebírat oznaÄením jako oblíbenou v <a href="%s">adresáři sbírek</a>. VaÅ¡e oblíbené sbírky se zobrazí jako odebírané ve Správci doplňků.</dd>
+
+<dt>Jak mohu pomocí rozšíření Sbírky doplňků synchronizovat mé doplňky mezi poÄítaÄi?</dt>
+<dd>PostaÄí si na jednom poÄítaÄi nastavit automatické publikování a rázem se vám zobrazí na vrcholu seznamu k odebírání na vÅ¡ech poÄítaÄích, kde máte rozšíření Sbírky doplňků nainstalováno. Poté budete moci vidÄ›t nainstalované doplňků na každém poÄítaÄi, který má nastaveno automatické publikování.</dd>
+
+<dt>Není Weave od Mozilla Labs způsob, jak mohu synchronizovat mé doplňky?</dt>
+<dd>Weave plánuje do budoucna podporu synchronizace doplňků mezi profily a zařízeními. Synchronizace rozšíření Sbírky doplňků ale funguje trochu odlišně. Automaticky publikovaná data nejsou šifrována a jsou uzpůsobena pro sdílení mezi přáteli ve formě sbírky. Doplňky mohou být sdíleny mezi profily pomocí více sbírek.</dd>
+
+<dt>Kde se mohu k rozšíření vyjádÅ™it Äi nahlásit chybu?</dt>
+<dd>Pokud naleznete chybu nebo chcete zaslat připomíku, vyplňte v Bugzille <a href="https://bugzilla.mozilla.org/enter_bug.cgi?component=Bandwagon&amp;product=addons.mozilla.org">tento formulář</a>. Pokud chcete poslat obecnou reakci, přidejte ji do <a href="http://groups.google.com/group/mozilla.dev.amo">naší diskusní skupiny</a>.</dd>
+</dl>
diff --git a/site/app/locale/cs/pages/collector_features.thtml b/site/app/locale/cs/pages/collector_features.thtml
new file mode 100644
index 0000000..f4b61da
--- /dev/null
+++ b/site/app/locale/cs/pages/collector_features.thtml
@@ -0,0 +1,32 @@
+<h2>Sbírky doplňků pro Mozilla Firefox</h2>
+<h4>UÄiňte vaÅ¡e pÅ™izpůsobení prohlížeÄe zajímavÄ›jší.</h4>
+<h3>Vlastnosti rozšíření</h3>
+<p>
+ Rozšíření Sbírky doplňků vám umožňuje snadný přístup k vašim oblíbeným doplňkům
+ a sbírkám a to hned několika způsoby:
+</p>
+
+<dl>
+ <dt>Přístup k oblíbeným sbírkám z Firefoxu</dt>
+ <dd>
+ Sbírky, které oznaÄíte v <a href="%1$s">adresáři sbírek</a> jako oblíbené, se zobrazí
+ ve speciální sekci Správce doplňků. Budete tak moci vidět aktualizovaný obsah každé sbírky.
+ </dd>
+ <dt>Sdílení doplňků pomocí publikování</dt>
+ <dd>
+ Každý doplněk, který si nainstalujete, lze snadno sdílet s přáteli pomocí e-mailu
+ Äi publikovat do jedné z vaÅ¡ich sbírek pomocí nabídky pro publikaci.
+ </dd>
+ <dt>Získávání upozornění</dt>
+ <dd>
+ Doplněk vás upozorní, když se v nějaké z vašich oblíbených sbírek objeví
+ nová položka a oznaÄí ji, abyste si ji mohli pozdÄ›ji prohlédnout.
+ </dd>
+
+ <dt>Automatické publikování vašich nainstalovaných doplňků do sbírky</dt>
+ <dd>
+ Funkce pro automatické publikování umožní pravidelnou synchronizaci vaší sbírky
+ s doplňky, které máte nainstalovány. Přátelé, kteří odebírají vaši sbírku,
+ tak uvidí aktuální stav.
+ </dd>
+</dl>
diff --git a/site/app/locale/cs/pages/collector_firstrun.thtml b/site/app/locale/cs/pages/collector_firstrun.thtml
new file mode 100644
index 0000000..8c88c34
--- /dev/null
+++ b/site/app/locale/cs/pages/collector_firstrun.thtml
@@ -0,0 +1,38 @@
+<div>
+ <h2>Welcome</h2>
+ <p class="intro">Rozšíření Sbírky doplňků bylo nainstalováno do vaÅ¡eho Firefoxu. Jste téměř pÅ™ipraveni zaÄít vytvářet, spravovat, sdílet a pÅ™ijímat sbírky doplňků.</p>
+</div>
+
+ <div class="primary">
+ <h3>Pro zaÄátek používání rozšíření Sbírky doplňků</h3>
+ <ol class="numbered">
+ <li>
+ <h4 class="step">1</h4>
+ Klepněte na nabídku Nástroje a zvolte Správce doplňků.
+ </li>
+ <li>
+ <h4 class="step">2</h4>
+ V sekci Sbírky se pÅ™ihlaÅ¡te ke svému úÄtu na Mozilla Add-ons.
+ </li>
+ <li>
+ <h4 class="step">3</h4>
+ Po levé stranÄ› se vám zobrazí seznam vÅ¡ech vaÅ¡ich sbírek. Pro zobrazení obsahu sbírky na ni klepnÄ›te. Pro správu sbírky Äi její poslání e-mailem klepnÄ›te na tlaÄítka "PÅ™idat do Firefoxu" Äi "Publikovat".
+ </li>
+ </ol>
+ <p>Je jedno, zda jste chtivý lovec doplňků Äi pouze nÄ›kdo, kdo používá doplňky pro lepší zážitky na webu, rozšíření Sbírky doplňků je tu, aby vám pomohlo. Pro více informací o možnostech rozšíření Sbírky doplňků a Äasto kladených otázkách pÅ™ejdÄ›te na <a href="%1$s">stránku vlastností</a> a <a href="%2$s">FAQ</a>.</p>
+ </div><!-- / .primary -->
+
+ <div class="secondary">
+ <div class="highlight">
+ <h4>ZaÄnÄ›te s tÄ›mito sbírkami</h4>
+
+ <ul>
+ %3$s
+ </ul>
+
+ <ul class="further-navigation">
+ <li><a href="%4$s" class="more-info">Zobrazit všechny sbírky</a></li>
+ </ul>
+ </div><!-- /. highlight -->
+ </div><!-- /. secondary-->
+
diff --git a/site/app/locale/cs/pages/error404.thtml b/site/app/locale/cs/pages/error404.thtml
new file mode 100644
index 0000000..298fcf1
--- /dev/null
+++ b/site/app/locale/cs/pages/error404.thtml
@@ -0,0 +1,16 @@
+<h1>Je nám líto, ale nemůžeme nalézt, co hledáte.</h1>
+
+<p>Stránka nebo soubor, který jste požadovali, nebyl na tomto serveru nalezen. Pravděpodobně jste klepli na neaktuální odkaz nebo napsali nesprávnou adresu.</p>
+
+<ul>
+<li>Pokud jste klepli na odkaz, dejte nám o tom vědět na e-mail <a href="mailto:webmaster@mozilla.com" title="Stránka nenalezena na Mozilla.com">webmaster@mozilla.com</a>. Sdělte nám, odkud jste přišli a co jste hledali, a my se vynasnažíme to opravit.</li>
+<li>Pokud jste napsali adresu, zkontrolujte její správnost.</li>
+</ul>
+
+<p>A nebo můžete rovnou skoÄit na nÄ›které populární stránky na naÅ¡em serveru.</p>
+
+<ul>
+<li>Zajímal by vás seznam <a href="%1$s">doporuÄovaných doplňků</a>?</li>
+<li>Hledáte <a href="%2$s">nÄ›jaký doplnÄ›k</a>? Pak skoÄte na stránku <a href="%2$s">hledání</a> a nebo použijte hledací pole níže.</li>
+<li>Pokud si pÅ™ejete zaÄít od zaÄátku, jdÄ›te na <a href="%3$s">titulní stránku</a> serveru.</li>
+</ul>
diff --git a/site/app/locale/cs/pages/faq.thtml b/site/app/locale/cs/pages/faq.thtml
new file mode 100644
index 0000000..8866353
--- /dev/null
+++ b/site/app/locale/cs/pages/faq.thtml
@@ -0,0 +1,78 @@
+<h1>Často kladené otázky</h1>
+
+<p>Tyto Äasto kladané otázky pro <a href="http://addons.mozilla.org">web Mozilla Add-ons</a> pokrývají oblasti, které nejsou aktuálnÄ› pokryty stránkami podpory Firefoxu. Na nich naleznete úvodní informace o <a href="http://support.mozilla.com/kb/Customizing+Firefox+with+add-ons">pÅ™izpůsobení Firfoxu doplňky</a> a Älánky jako:</p>
+
+<ul>
+ <li>Řešení problémů s <a href="http://support.mozilla.com/kb/Unable+to+install+add-ons">instalací doplňků</a>, <a href="http://support.mozilla.com/kb/Troubleshooting+plugins">zásuvnými moduly</a> &amp; <a href="http://support.mozilla.com/kb/Troubleshooting+extensions+and+themes">řešení obecných problémů</a>.</li>
+ <li> <a href="http://support.mozilla.com/kb/Uninstalling+add-ons">Jak odinstalovat doplňky</a> a <a href="http://support.mozilla.com/kb/Cannot+uninstall+an+add-on">jak řešit problémy při odinstalaci</a>.</li>
+ <li> <a href="http://support.mozilla.com/kb/Gray+bar+below+the+status+bar">Problematické doplňky / Problémy s divnou šedou lištou</a>.</li>
+</ul>
+
+<p></p>
+
+<div id="gsfn_list_widget">
+ <a href="https://getsatisfaction.com/mozilla" class="widget_title">Diskuse o webu Mozilla Addons (v angliÄtinÄ›)</a>
+ <div id="gsfn_content">NaÄítám...</div>
+ <div class="powered_by">
+ <a href="https://getsatisfaction.com/"><img alt="Favicon" src="https://www.getsatisfaction.com/favicon.gif" style="vertical-align: middle;" /></a>
+ <a href="https://getsatisfaction.com/">Přejít na stránky sítě podpory Get Satisfaction</a>
+ </div>
+</div>
+
+<h2>Otázky k doplňkům</h2>
+<dl class="faq">
+<dt>Co je doplněk?</dt>
+<dd>Doplňky vám umožňují pÅ™idávat funkce, které nejsou standardní souÄástí aplikace. Motivy vzhledu umožňují zmÄ›nit vzhled beze zmÄ›ny funkcionality. Vyhledávací moduly, slovníky a jazykové balíÄky pÅ™idávají podporu pro další vyhledávaÄe a jazyky. Rozšíření pÅ™idávají do aplikace nové funkce. Může se jednat o jednoduché liÅ¡ty Äi o celou Å™adu nových funkcí.</dd>
+
+<dt>Instalují se doplňky snadno?</dt>
+<dd>Ano! Doplňky se instalují velmi snadno. Jsou o moc menší než klasická aplikace a stáhnou se velmi rychle. Pokud se vám nelíbí, můžete je snadno odinstalovat Äi zakázat. Pokud je navíc pro nÄ›jaký doplnÄ›k dostupná aktualizace, Firefox vás o tom informuje a umožní vám provést aktualizaci jedním klepnutím.</dd>
+
+<dt>Jak mohu spravovat doplňky?</dt>
+<dd>Pro správu rozšíření a motivů vzhledu pÅ™ejdÄ›te ve Firefoxu do nabídky "Nástroje" a zde zvolte položku "Správce doplňků". Pokud mají vaÅ¡e rozšíření speciální nastavení, můžete je vidÄ›t v sekci Rozšíření okna Správce doplňků. Z tohoto místa též můžete doplňky odinstalovat Äi zakázat. Slovníky jsou nainstalovány jako rozšíření, vyhledávací moduly je možné spravovat z vyhledávacího pole.</dd>
+
+<dt>Mohou doplňky zpomalit Firefox?</dt>
+<dd>Ve většině případů doplňky neuzpůsobují zpomalení Firefoxu. Nicméně některé doplňky mohou v závislosti na vaší systémové konfiguraci výkon Firefoxu ovlivnit. Pokud se vám zdá, že doplněk ovlivňuje výkon Firefoxu, zakažte jej.</dd>
+
+<dt>ProÄ bych mÄ›l(a) zakázat doplnÄ›k?</dt>
+<dd>Zakázáním doplňku zajistíte, že se pÅ™i startu Firefoxu doplnÄ›k nenaÄte, ale zároveň neprovedete jeho odstranÄ›ní Äi odstranÄ›ní jeho nastavení. OpÄ›tovným povolením doplňku jej budete mít ve stejné podobÄ›, jakou jste mÄ›li pÅ™ed jeho zakázáním. Pokud chcete doplnÄ›k vypnout bez jeho odinstalace, je jeho zakázání správnou volbou.</dd>
+
+<dt>Jak mohu zazálohovat všechny doplňky a motivy vzhledu, které mám nainstalovány?</dt>
+<dd>Můžete zazálohovat adresář s profilem, Äímž také zazálohujete vaÅ¡e doplňky a motivy vzhledu. S tím vám mohou pomoci aplikace tÅ™etích stran jako napÅ™. MozBackup.</dd>
+</dl>
+
+<h2>Otázky týkající se webu</h2>
+<dl class="faq">
+<dt>NaÅ¡el jsem nÄ›kolik doplňků, které poskytují stejnou funkÄnost. Jak se mám rozhodnout, který je nejlepší?</dt>
+<dd>ObecnÄ› Å™eÄeno, můžete se podívat na hodnocení a poÄet stažení, což jsou informace, které vám mohou pomoci. Lepší doplňky jsou vÄ›tÅ¡inou stahovány ÄastÄ›ji než ty horší. Na druhou stranu je snadnÄ›jší nainstalovat oba doplňky a rozhodnout se, který chcete použít. Po vyzkouÅ¡ení se nakonec můžete rozhodnout, že budete používat oba.</dd>
+
+<dt>Koukám na svělý doplněk, ale říká mi to, že není kompatibilní s Firefoxem 2.x. Mohu ho přesto nainstalovat do Firefoxu 3.x?</dt>
+<dd>ObecnÄ› ne. Firefox 3.0 obsahuje nÄ›kolik novinek a velká Äást vývojářů doplňků aktualizovala své doplňky pro Firefox 3.x. Pokud doplnÄ›k podporuje pouze Firefox 2, vyzkouÅ¡ejte vyhledat název doplňku. V mnoha případech najdete jeho novÄ›jší verzi, která Firefox 3 podporujem, Äi obdobný doplnÄ›k.</dd>
+
+<dt>Nainstaloval jsem si nový motiv vzhledu, ale rád bych se vrátil k výchozímu vzhledu Firefoxu. Jak to mam udělat?</dt>
+<dd>V hlavní nabídce zvolte "Nástroje" a v ní položku "Správce doplňků". V zobrazeném oknÄ› klepnÄ›te na sekci "Motivy vzhledu" a zde zvolte výchozí motiv vzhledu Äi jiný, který máte nainstalován.</dd>
+
+<dt>Pokud mám problém s doplňkem, měl bych kontaktovat Mozillu?</dt>
+<dd>Doplňky jsou až na několik výjimek vytvářeny komunitou a nikoliv Mozillou. Nejlepší věc, kterou můžete udělat, je kontaktovat přímo jeho vývojáře. Pro nalezení kontaktních informací klepněte na jméno vývojáře na stránce s doplňkem.</dd>
+
+<dt>Jak jsou doplňky kontrolovány?</dt>
+<dd>Veřejné doplňky jsou kontrolovány týmem editorů. Ti kontrolují kód všech publikovaných doplňků, testují je a kontrolují, zda doplňky dělají to, co mají.</dd>
+
+<dt>Aktualizoval jsem na Firefox 3.5 a mé doplňky již nefungují. ProÄ?</dt>
+<dd>Řada z doplňků je již s Firefoxem 3.5 kompatibilní a každý den jsou dostupné další. Pokud váš doplněk fungoval ve verzi 3.0, ale ve verzi 3.5 již nefunguje, je pravděpodobné, že jeho vývojáři pracují na aktualizaci. Až bude dostupná, Firefox vás na ni upozorní.</dd>
+
+<dt id="experimental-addons">Co jsou experimentální doplňky?</dt>
+<dd>
+ <p>Experimentální doplňky jsou nové doplňky, které dosud neprošly našim veřejným procesem kontroly. Řada z těchto doplňků může být prototypem. Do té doby, dokud nejsou otestovány našim týmem editorů, mohou mít horší kvalitu kódu, výkon a vlastnosti.</p>
+ <p>PÅ™i instalaci jste na experimentální doplňky upozornÄ›ní. Jste tak informováni, že nebyly otestovány editorem a mohou poÅ¡kodit konfiguraci vaÅ¡eho poÄítaÄe.</p>
+</dd>
+
+<dt id="recognizing-experimental-addons">Jak mohu vědět, že konkrétní doplněk na webu je experimentální?</dt>
+<dd>Experimentální doplňky jsou oznaÄeny slovem "experimentální" a pÅ™i jejich instalaci se u nich zobrazuje varování.</dd>
+
+<dt id="recommended-addons">Co jsou doporuÄené a propagované doplňky?</dt>
+<dd>Tým Mozilla Add-ons doporuÄuje sadu doplňků, v které jsou nejlepší doplňky z hlediska užiteÄnosti. Tyto doporuÄené doplňky se zobrazují na stránkách konkrétních kategorií. NÄ›které z tÄ›chto doplňků se pravidelnÄ› zobrazují na titulní stránce Mozilla Add-ons jako propagované doplňky. Tento seznam není myÅ¡len jako vyÄerpávající a je mÄ›síÄnÄ› aktualizován, takže se uživatelům stále zobrazuje nová sada doplňků. PÅ™i výbÄ›ru doporuÄených doplňků bereme v potaz kvalitu, popularitu, unikátnost a to, zda již byl doplnÄ›k mezi doporuÄenými.</dd>
+
+</dl>
+
+<script src="https://getsatisfaction.com/mozilla/widgets/javascripts/500b6b4141/widgets.js" type="text/javascript"></script>
+<script src="https://getsatisfaction.com/mozilla/topics.widget?callback=gsfnTopicsCallback&amp;limit=5&amp;product=mozilla_mozilla_add_ons&amp;sort=last_active_at&amp;style=topics" type="text/javascript"></script>
diff --git a/site/app/locale/cs/pages/nomination.thtml b/site/app/locale/cs/pages/nomination.thtml
new file mode 100644
index 0000000..e54f4a5
--- /dev/null
+++ b/site/app/locale/cs/pages/nomination.thtml
@@ -0,0 +1,8 @@
+<p>Doplněk umístěný na pískovišti může být nominován mezi veřejné doplňky a tím dostupný všem uživatelům pokud projde při kontrole editora. Pokud chcete uspět, berte na vědomí následující:</p>
+<ul>
+ <li>U motivů vzhledu jsou vyžadovány náhledy a jsou důraznÄ› doporuÄovány i u ostatních typů doplňků</li>
+ <li>DoplnÄ›k by mÄ›l strávit dostateÄný Äas na pískoviÅ¡ti a získat Å™adu hodnocení a komentářů od uživatelů</li>
+ <li>Veřejné doplňky musí splňovat větší měřítka kvality než doplňky na pískovišti a měly by vylepšovat web</li>
+ <li>Kompletní kritéria pro nominaci doplňku jsou dostupná na stránce <a href="%s">Zásady užití serveru doplňky Mozilly</a></li>
+</ul>
+<p>Pokud váš doplnÄ›k splňuje výše uvedená kritéria, můžete ho nominovat klepnutím na tlaÄítko níže. O stavu vaší nominace budete informováni e-mailem.</p>
diff --git a/site/app/locale/cs/pages/sandbox.thtml b/site/app/locale/cs/pages/sandbox.thtml
new file mode 100644
index 0000000..285b3a2
--- /dev/null
+++ b/site/app/locale/cs/pages/sandbox.thtml
@@ -0,0 +1,13 @@
+<h1>Systém kontroly v&nbsp;Sandboxe</h1>
+<h2>Co je pískoviště?</h2>
+<p>PískoviÅ¡tÄ› je místo, kde si zkuÅ¡ení uživatelé mohou hrát se svými doplňky pÅ™ed&nbsp;tím, než jsou zkontrolované pro&nbsp;vÅ¡eobecné použití. Přístup na pískoviÅ¡tÄ› je nutné si povolit v&nbsp;nastavení svého úÄtu. PÅ™i&nbsp;instalaci doplňku z&nbsp;pískoviÅ¡tÄ› byste mÄ›li být opatrní, neboÅ¥ tyto doplňky nebyly jeÅ¡tÄ› zkotrolovány redaktorem a můžou vám poÅ¡kodit poÄítaÄ.</p>
+
+<h2>Jak dosta svůj doplněk mezi veřejné doplňky?</h2>
+<!-- To localize the flowchart image, see http://wiki.mozilla.org/Update:Remora_Sandbox_Flowchart -->
+<div style="text-align: center;">%s</div>
+<ol>
+ <li><b>V&nbsp;nástrojích vývojáře nahrajte svůj doplnÄ›k.</b> Ten bude po&nbsp;té ihned dostupný na&nbsp;pískoviÅ¡ti, kde ho můžou zkuÅ¡ení uživatelé otestovat a okomentovat. APřístup na pískoviÅ¡tÄ› je nutné si povolit v&nbsp;nastavení svého úÄtu.</li>
+ <li><b>Nominujte svůj doplnÄ›k na&nbsp;zveÅ™ejnÄ›ní.</b> V&nbsp;nástrojích vývojáře použijte odkaz pro&nbsp;nominaci doplňku. Po&nbsp;té je doplnÄ›k zaÅ™azen do &nbsp;nominaÄní fronty, dokud není nÄ›kterým redaktorem zkontrolován.</li>
+ <li><b>Redaktor zkontroluje váš doplněk.</b> Reedaktor webu doplňky Mozilly si nainstauje váš doplněk a&nbsp;otestuje jestli funguje. Podívá se i na hodnocení uživatelů z pískoviště.</li>
+ <li><b>DoplnÄ›k bude zveÅ™ejnÄ›ný nebo zůstane na&nbsp;pískoviÅ¡ti.</b> Pokud je váš doplnÄ›k v&nbsp;pořádku, redaktor ho pÅ™esune mezi veÅ™ejné doplňky. V opaÄném případÄ› zůstane doplnÄ›k na pískoviÅ¡ti a vy ho můžete po odstranÄ›ní nedostatků, zmínÄ›ných redaktorem v komentáři, znovu nominovat. PÅ™estože bude váš doplnÄ›k zveÅ™ejnÄ›n, objeví se vÅ¡echny jeho další verze opÄ›t na pískoviÅ¡ti, dokud je radaktoÅ™i opÄ›t nezkontrolují a nezveÅ™ejní. Pokud bude váš doplnÄ›k jednou zveÅ™ejnÄ›n, jsou vÅ¡echny jeho další verze automaticky zaÅ™azeny do nominaÄní fronty a doplnÄ›k tak není nutné znovu nominovat.</li>
+</ol> \ No newline at end of file
diff --git a/site/app/locale/cs/pages/statistics_help.thtml b/site/app/locale/cs/pages/statistics_help.thtml
new file mode 100644
index 0000000..a2eef69
--- /dev/null
+++ b/site/app/locale/cs/pages/statistics_help.thtml
@@ -0,0 +1,8 @@
+<h3>Nápověda</h3>
+<p>Stránka statistik zobrazuje stažení a aktualizace pro váš doplněk.</p>
+
+<h4>Stažení</h4>
+<p>PoÄty stažení jsou aktualizovány každý den a zahrnují pouze stažení doplňků bez zahrnutí aktualizací.</p>
+
+<h4>Aktualizace</h4>
+<p>Doplňky stažené z webu jednou dennÄ› provádí kontrolu dostupnosti aktualizací a celkový poÄet tÄ›chto kontrol je poÄet aktivních denních uživatelů. Aktivní denní uživatelé mohou poklesnout v závislosti na verzi doplňku, operaÄním systému, stavu doplňku a aplikace. Tato data jsou aktuálnÄ› zaznamenávány každý týden ve stÅ™edu.</p> \ No newline at end of file
diff --git a/site/app/locale/cs/pages/submission_help.thtml b/site/app/locale/cs/pages/submission_help.thtml
new file mode 100644
index 0000000..354b55e
--- /dev/null
+++ b/site/app/locale/cs/pages/submission_help.thtml
@@ -0,0 +1,35 @@
+<h1>Nápověda k nahrávání doplňku</h1>
+Povinná pole jsou vyznaÄena <b>tuÄnÄ›</b>. Volitelná jsou vyznaÄena <i>kurzívou</i>.
+<h2 id="step1">Krok 1: Nahrání</h2>
+<ul class="submissionHelp">
+ <li><span class="required">Typ doplňku</span> - Jestliže ponecháte výchozí hodnotu, typ doplňku se automaticky urÄí podle nahraného souboru. Toto pole byste nemÄ›li mÄ›nit.</li>
+ <li><span class="required">Soubor doplňku</span> - Zabalený soubor spoleÄnÄ› se&nbsp;souborem install.rdf. Pokud soubor funguje jen na&nbsp;urÄité platformÄ›, vyberte ji a tím umožníte nahrání více souborů najednou.</li>
+ <li><span class="optional">Soubor ikony</span> - Ikona je zobrazena na&nbsp;stránce doplňků, vedle jména doplňku a v&nbsp;instalaÄním oknÄ›. Automaticky bude zmenÅ¡ena na&nbsp;velikost 32x32 pixelů, pÅ™i&nbsp;zachování pomÄ›ru stran.</li>
+ <li><span class="required">Výchozí lokalizace</span> - Výchozí lokalizace je hlavním jazykem doplňku. Jestliže jazyk, který používá uživatel není v&nbsp;doplňku obsažen, bude zvolen právě výchozí jazyk.</li>
+ <li><span class="optional">PÅ™eskoÄit aktualizaci informací o mém doplňku</span> - Jestliže nahráváte již existující doplnÄ›k, objeví se vám tato volba. ZaÅ¡krtnutím pÅ™eskoÄíte na krok 3, kde zadáváte informace týkající se verzi vaÅ¡eho rozšíření.</li>
+</ul>
+
+<h2 id="step2">Krok 2: Detaily doplňku</h2>
+<ul class="submissionHelp">
+ <li><span class="required">Jméno</span> - Jméno doplňku ve&nbsp;výchozí lokalizaci.</li>
+ <li><span class="required">Autoři</span> - Všichni uživatelé, kteří mají přístup k úpravám doplňku a kteří budou na&nbsp;stránce doplňku uvedeni jako autoři.</li>
+ <li><span class="required">Kategorie</span> - Kategorie, do&nbsp;které váš doplněk patří.</li>
+ <li><span class="optional">Domovská stránka</span> - Stránka doplňku ve&nbsp;výchozím jazyce.</li>
+ <li><span class="required">StruÄný popis</span> - StruÄný popisu doplňku (max.&nbsp;250&nbsp;znaků) ve&nbsp;výchozí lokalizaci, který se&nbsp;objeví na&nbsp;stránce doplňku stejnÄ› jako ve&nbsp;výsledcích hledání.</li>
+ <li><span class="required">Popis</span> - Popis vaÅ¡eho doplňku ve&nbsp;výchozí lokalizaci. Tento popis se&nbsp;objeví na&nbsp;stránce doplňků pod&nbsp;struÄným popisem.</li>
+ <li><span class="optional">EULA</span> - LicenÄní smlouva s koncovým uživatelem ve&nbsp;výchozí lokalizaci, kterou uživatelé musí odsouhlasit pÅ™ed&nbsp;stáhnutím doplňku.</li>
+ <li><span class="optional">Zásady ochrany soukromí</span> - Zásady ochrany soukromí ve&nbsp;výchozí lokalizaci. VysvÄ›tlují, jak je zacházeno se&nbsp;soukromými daty uživatele. Jsou umístÄ›ny vedle instalaÄního tlaÄítka na&nbsp;stránce s&nbsp;doplňky. Další informace, co by mÄ›li Zásady ochrany soukromí obsahovat a zda je váš doplnÄ›k potÅ™ebuje, jsou dostupné na&nbsp; stránce <a href="%s">Zásady užití serveru doplňky Mozilly</a>.</li>
+ <li><span class="optional">Povolit uživatelům zobrazovat zdrojové soubory online</span> - Zaškrtnutím povolíte uživatelům zobrazení zdrojových souborů vašeho doplňku online.</li>
+ <li><span class="optional">Tento doplněk je kandidát na vydání</span> - Zaškrtnutím této volby dáte najevo, že doplněk je kandidát na vydání nebo beta verze. Doplňky typu kandidát na vydání zůstávají na&nbsp;pískovišti a nelze je nominovat mezi veřejné doplňky, dokud tato volba nebude odškrtnuta.</li>
+ <li><span class="optional">Tento doplnÄ›k je urÄen pro&nbsp;specifický server</span> - ZaÅ¡krtnutím této volby oznámíte, že doplnÄ›k je urÄen pro&nbsp;urÄitý webový server, například doplnÄ›k mÄ›ní vzhled stránek urÄitého serveru Äi zobrazuje obsah z&nbsp;urÄitého webového serveru. V budoucnosti toto pole může být užito k&nbsp;filtrování hledání.</li>
+ <li><span class="optional">Tento doplněk vyžaduje externí software</span> - Zaškrtnutím tohoto pole uvádíte, že doplněk potřebuje externí software. V budoucnosti toto pole může být užito k&nbsp;filtrování hledání.</li>
+</ul>
+
+<h2 id="step3">Krok 3: Detaily verze</h2>
+<ul class="submissionHelp">
+ <li><span class="required optional">Poznámky k&nbsp;verzi</span> - Souhrn nebo seznam změn v&nbsp;této verzi. Toto pole je volitelné při&nbsp;první verzi doplňku, avšak povinné při&nbsp;aktualizaci.</li>
+ <li><span class="optional">Poznámky pro&nbsp;hodnotitele</span> - Toto pole využijte pro&nbsp;komunikaci s&nbsp; hodnotiteli vašeho doplňku. Patří sem rovněž informace pro&nbsp;testery a zvláštní poznámky.</li>
+</ul>
+
+<h2 id="step4">Krok 4: Lokalizace</h2>
+V této Äásti je možno pÅ™eložit jednotlivé položky doplňku do&nbsp;vÅ¡ech podporovaných lokalizací. Pro&nbsp;vložení pÅ™ekladu staÄí klepnout na&nbsp;kód lokalizace.
diff --git a/site/app/locale/cy/LC_MESSAGES/messages.mo b/site/app/locale/cy/LC_MESSAGES/messages.mo
new file mode 100644
index 0000000..3976bb5
--- /dev/null
+++ b/site/app/locale/cy/LC_MESSAGES/messages.mo
Binary files differ
diff --git a/site/app/locale/cy/LC_MESSAGES/messages.po b/site/app/locale/cy/LC_MESSAGES/messages.po
new file mode 100644
index 0000000..5df8931
--- /dev/null
+++ b/site/app/locale/cy/LC_MESSAGES/messages.po
@@ -0,0 +1,8769 @@
+# Remora Preliminary Language File
+# Copyright (C) 2006 Mozilla Corporation
+# This file is distributed under the same license as the REMORA package.
+# Wil Clouser <clouserw@mozilla.com>, 2006.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: REMORA 0.1\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2009-01-16 11:45-0800\n"
+"PO-Revision-Date: 2008-06-01 16:39-0000\n"
+"Last-Translator: Rhoslyn Prys <post@meddal.com>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=n != 1;\n"
+"X-Poedit-Bookmarks: 363,-1,-1,-1,-1,-1,-1,-1,-1,-1\n"
+
+#: views/addons/policy.thtml:98
+msgid "a_cancel_installation"
+msgstr "Diddymu'r Gosod"
+
+#. This is the text that appears on buttons to download add-ons.
+#. %$1s is an optional string that only appears if the add-on is only available for
+#. a certain platform. Examples: (Windows) or (Linux)
+#. Note that the parentheses are included in the string. :(
+#: views/elements/amo2009/install.thtml:126
+#: views/elements/amo2009/install.thtml:227
+#: views/elements/amo2009/install.thtml:257
+#: views/elements/amo2009/install.thtml:300
+#: views/elements/amo2009/install.thtml:312 views/elements/install.thtml:73
+#: views/elements/install.thtml:181 views/elements/install.thtml:205
+#: views/elements/install.thtml:248 views/elements/install.thtml:260
+#: views/addons/plugins.thtml:66 views/addons/plugins.thtml:76
+#: views/addons/plugins.thtml:86 views/addons/plugins.thtml:96
+#: views/addons/plugins.thtml:119
+#, php-format
+msgid "a_download"
+msgstr "Llwytho %s Nawr"
+
+#: views/addons/policy.thtml:72
+msgid "a_eula_download"
+msgstr "Derbyn a Llwytho i Lawr"
+
+#: views/addons/policy.thtml:74
+msgid "a_eula_install"
+msgstr "Derbyn a Gosod"
+
+#: views/elements/header.thtml:76 views/elements/header.thtml:82
+#: views/api/api_addon.thtml:55 views/api/collections_feed.thtml:75
+#: views/sharing_api/addon.thtml:64
+msgid "a_header_public"
+msgstr "Cyhoeddus"
+
+#: views/elements/header.thtml:58 views/elements/header.thtml:75
+#: views/elements/header.thtml:80 views/api/api_addon.thtml:57
+#: views/api/collections_feed.thtml:77 views/sharing_api/addon.thtml:66
+msgid "a_header_sandbox"
+msgstr "Blwch Tywod"
+
+#. %s is a date in the _('date') format
+#: views/elements/amo2009/homepage_addon.thtml:115
+#: views/elements/addon_listitem.thtml:122 views/elements/feature.thtml:106
+#: views/addons/display.thtml:104 views/addons/browse_thumbs.thtml:73
+msgid "addon_detail_last_updated"
+msgstr "Diweddaru %s"
+
+#. %s is the version of the add-on. Example: 3.2a1
+#: views/elements/amo2009/addon_version_detail.thtml:51
+#: views/elements/addon_version_detail.thtml:51
+#, php-format
+msgid "addon_display_header_version"
+msgstr "Fersiwn %s"
+
+#: views/addons/browse_thumbs.thtml:80
+msgid "addon_downloads"
+msgstr "Llwythi"
+
+#: views/addons/display.thtml:147
+msgid "addon_downloads_total"
+msgstr "Y llwythi i gyd"
+
+#: views/elements/amo2009/homepage_addon.thtml:106
+#: views/elements/addon_listitem.thtml:115 views/elements/feature.thtml:101
+#: views/addons/category_landing.thtml:157 views/addons/display.thtml:146
+#: views/addons/browse_thumbs.thtml:80
+msgid "addon_downloads_weekly"
+msgstr "llwythi wythnosol"
+
+#. %1 is the add-on count, %2 the category name
+#: views/addons/browse_thumbs.thtml:104 views/addons/browse.thtml:60
+#, php-format
+msgid "addon_list_category_totalcount"
+msgid_plural "addon_list_category_totalcount"
+msgstr[0] "%1$s add-on"
+msgstr[1] "%1$s add-ons"
+
+#: views/elements/amo2009/addon_list_options.thtml:103
+#: views/elements/pagination.thtml:67
+#: views/elements/addon_list_options.thtml:94
+msgid "addon_list_perpage"
+msgstr "y dudalen"
+
+#: views/elements/amo2009/addon_list_options.thtml:84
+#: views/elements/addon_list_options.thtml:98
+msgid "addon_list_sortby"
+msgstr "Trefnu yn ôl"
+
+#: views/helpers/addons_html.php:568 views/elements/amo2009/install.thtml:321
+#: views/elements/feature.thtml:89
+msgid "addon_listitem_flag_experimental"
+msgstr "arbrofol"
+
+#: views/helpers/addons_html.php:570
+msgid "addon_listitem_flag_recommended"
+msgstr "argymell"
+
+#. %1 is the add-on name, %2 is the platform
+#: views/pages/js_constants.js.thtml:66
+msgid "addon_not_available_for_platform"
+msgstr "Nid yw %1$s ar gael ar gyfer %2$s."
+
+#. %1 is the add-on name
+#: views/addons/policy.thtml:101 views/addons/previews.thtml:60
+#: views/addons/versions.thtml:130 views/reviews/flag.thtml:61
+#: views/reviews/add.thtml:114 views/reviews/display.thtml:216
+#: views/reviews/review_added.thtml:57
+#, php-format
+msgid "addon_review_a_back_to_addon_x"
+msgstr "Nôl i %1$s..."
+
+#. %1 is the add-on name
+#: views/reviews/flag.thtml:60 views/reviews/add.thtml:113
+#: views/reviews/review_added.thtml:56
+#, php-format
+msgid "addon_review_a_back_to_reviews"
+msgstr "Nôl i'r adolygiadau..."
+
+#: views/reviews/add.thtml:85
+msgid "addon_review_add_rating_field"
+msgstr "Graddio:"
+
+#: views/reviews/add.thtml:102
+msgid "addon_review_add_review_field"
+msgstr "Adolygiad:"
+
+#: views/reviews/add.thtml:107
+msgid "addon_review_add_submit"
+msgstr "Cyflwyno dy adolygiad"
+
+#. %s is the name of the add-on
+#: views/reviews/add.thtml:51
+#, php-format
+msgid "addon_review_add_title"
+msgstr "Ychwanegu adolygiad ar %s"
+
+#: views/reviews/add.thtml:78
+msgid "addon_review_add_title_field"
+msgstr "Teitl/Crynodeb:"
+
+#: views/reviews/display.thtml:77 views/reviews/display.thtml:161
+msgid "addon_review_admin_delete"
+msgstr "Dileu"
+
+#: views/reviews/display.thtml:76
+msgid "addon_review_author_reply_link"
+msgstr "Ateb"
+
+#: views/reviews/delete.thtml:62
+msgid "addon_review_confirm_delete"
+msgstr "Wyt ti'n siŵr dy fod am ddileu'r adolygiad?"
+
+#: views/reviews/delete.thtml:63
+msgid "addon_review_confirm_no"
+msgstr "Na"
+
+#: views/reviews/delete.thtml:64
+msgid "addon_review_confirm_yes"
+msgstr "Iawn"
+
+#: views/reviews/delete.thtml:48
+msgid "addon_review_delete_header"
+msgstr "Dileu'r Adolygiad"
+
+#: controllers/reviews_controller.php:449
+msgid "addon_review_deleted_successfully"
+msgstr "Wedi dileu'r adolygiad yn llwyddiannus."
+
+#. %s is the name of the add-on
+#: views/reviews/add.thtml:51
+#, php-format
+msgid "addon_review_edit_title"
+msgstr "Golygu’r adolygiad ar %s"
+
+#. %1 is the count of characters entered as notes for the review flag reason.
+#: controllers/reviews_controller.php:539
+#, fuzzy
+msgid "addon_review_flag_error_other_length"
+msgstr ""
+"Problem flagging review: Notes for flagged reviews are limited to between 10 "
+"and 100 characters; your character length was %1$s."
+
+#. Removing an extra comma
+#: views/reviews/review_added.thtml:53
+msgid "addon_review_in_moderation"
+msgstr ""
+"Sylw: Cyn i dy adolygiad ymddangos ar y safle cyhoeddus bydd yn cael ei "
+"gymedroli gan olygydd."
+
+#: views/reviews/add.thtml:57
+msgid "addon_review_in_reply_to"
+msgstr "Datblygwr i ateb i:"
+
+#. %1 is the review count, %2 is the nickname or full name of the user.
+#: views/reviews/display.thtml:131
+#, fuzzy, php-format
+msgid "addon_review_others_by_user"
+msgid_plural "addon_review_others_by_user"
+msgstr[0] "See %1$s previous review submitted by %2$s for this add-on."
+msgstr[1] "See %1$s previous reviews submitted by %2$s for this add-on."
+
+#. %1 is the add-on name
+#: controllers/reviews_controller.php:201
+#: controllers/reviews_controller.php:250
+#: controllers/reviews_controller.php:345
+#: controllers/reviews_controller.php:424
+#, php-format
+msgid "addon_review_pagetitle"
+msgstr "Adolygiadau ar gyfer %s"
+
+#. %1 is the user, %2 is the (localized) date
+#: views/reviews/display.thtml:160
+#, php-format
+msgid "addon_review_reply_on_x_by_y"
+msgstr "Ateb gan %1$s ynghylch %2$s"
+
+#: views/reviews/display.thtml:157
+msgid "addon_review_reply_prefix"
+msgstr "Ateb Datblygwr:"
+
+#: views/reviews/review_added.thtml:51
+msgid "addon_review_saved_successfully"
+msgstr "Cafodd dy adolygiad ei gadw'n llwyddiannus. Diolch!"
+
+#: views/addons/display.thtml:354 views/reviews/display.thtml:72
+msgid "addon_reviewed_by_u_on_d"
+msgstr "gan %1$s ynghylch %2$s"
+
+#. %1 is the user, %2 is the (localized) date, %3 is the rating
+#: views/editors/reviews_queue.thtml:57 views/editors/reviews_queue.thtml:68
+#: views/reviews/add.thtml:63 views/reviews/delete.thtml:54
+#, php-format
+msgid "addon_reviewed_on_x_rated_y"
+msgstr "gan %1$s ynghylch %2$s (gradd %3$s)"
+
+#: views/elements/amo2009/addon_version_detail.thtml:52
+#: views/elements/addon_version_detail.thtml:52
+#, fuzzy
+msgid "addon_version_permalink"
+msgstr "Permanent link to this version"
+
+#. %1 is the current Application name (e.g. Firefox)
+#. %2 is the Application's version number
+#: views/addons/versions.thtml:140
+#, fuzzy
+msgid "addon_versions_getlatestversion"
+msgstr "The most recent version compatible with %1$s %2$s"
+
+#: views/addons/display.thtml:447
+msgid "addons_author_addons_submit"
+msgstr "Mynd"
+
+#: views/elements/amo2009/homepage_addon.thtml:100
+#: views/elements/feature.thtml:95
+#, fuzzy
+msgid "addons_author_tooltip"
+msgstr "View Author's Profile"
+
+#. %1 is the name of the Application (eg. Firefox)
+#: controllers/addons_controller.php:1296
+#, fuzzy
+msgid "addons_browse_all_themes_title"
+msgstr "Browse all Themes :: %1$s Add-ons"
+
+#. %s is the name of the category
+#: controllers/addons_controller.php:1016
+#, php-format
+msgid "addons_browse_browse_category"
+msgstr "Pori %s"
+
+#. %1 is the name of the theme category (eg. Modern)
+#. %2 is the name of the Application (eg. Firefox)
+#: controllers/addons_controller.php:664
+#, fuzzy
+msgid "addons_browse_categories_header_theme"
+msgstr "Browse %1$s Themes :: %2$s Add-ons"
+
+#: views/addons/display.thtml:249
+#, fuzzy
+msgid "addons_display_a_license_what"
+msgstr "What's this?"
+
+#: views/reviews/display.thtml:222
+msgid "addons_display_add_review"
+msgstr "Ychwanegu adolygiad"
+
+#: views/addons/display.thtml:294
+msgid "addons_display_advanced_details"
+msgstr "Manylion Uwch"
+
+#: views/addons/display.thtml:98
+msgid "addons_display_categories"
+msgstr "Categorïau"
+
+#: views/addons/display.thtml:482
+#, fuzzy
+msgid "addons_display_collection_add"
+msgstr "Add to a collection:"
+
+#: views/addons/display.thtml:491
+#, fuzzy
+msgid "addons_display_collection_add_new"
+msgstr "New Collection..."
+
+#: views/addons/display.thtml:487
+#, fuzzy
+msgid "addons_display_collection_add_select_one"
+msgstr "Select a collection..."
+
+#: views/addons/display.thtml:493
+#, fuzzy
+msgid "addons_display_collection_add_submit"
+msgstr "Publish"
+
+#. %1$s is the add-on name
+#. %2$s is the collection name, linked to the collection's page
+#: views/pages/js_constants.js.thtml:103 views/addons/display.thtml:61
+#, fuzzy
+msgid "addons_display_collection_publish_success"
+msgstr "%1$s has been added to the %2$s collection."
+
+#: views/addons/display.thtml:483
+#, fuzzy
+msgid "addons_display_collection_whatsthis"
+msgstr "What's this?"
+
+#. %1$s is a number
+#: views/addons/display.thtml:473
+#, fuzzy
+msgid "addons_display_collections_more"
+msgid_plural "addons_display_collections_more"
+msgstr[0] "and %1$s more collection"
+msgstr[1] "and %1$s more collections"
+
+#: views/addons/display.thtml:403
+msgid "addons_display_detailed_review"
+msgstr "adolygiad manwl"
+
+#: views/reviews/add.thtml:89 views/reviews/add.thtml:90
+msgid "addons_display_dont_like_it"
+msgstr "Dim yn ei hoffi"
+
+#: views/reviews/display.thtml:220
+msgid "addons_display_edit_review"
+msgstr "Golygu dy adolygiad"
+
+#: views/addons/display.thtml:132
+msgid "addons_display_has_privacy"
+msgstr "Mae gan yr ychwanegyn bolisi preifatrwydd"
+
+#: views/reviews/add.thtml:87 views/reviews/add.thtml:88
+msgid "addons_display_hate_it"
+msgstr "Casáu"
+
+#: views/addons/display.thtml:462
+#, fuzzy
+msgid "addons_display_header_collections"
+msgstr "Related Collections"
+
+#: views/addons/display.thtml:297
+msgid "addons_display_header_developer_comments"
+msgstr "Sylw Datblygwr"
+
+#: views/addons/display.thtml:230
+msgid "addons_display_header_homepage"
+msgstr "Tudalen cartref"
+
+#: views/addons/display.thtml:247 views/addons/versions.thtml:110
+#, fuzzy
+msgid "addons_display_header_license"
+msgstr "Source Code License"
+
+#: views/addons/display.thtml:337
+msgid "addons_display_header_reviews"
+msgstr "Adolygiadau"
+
+#: views/addons/display.thtml:261
+msgid "addons_display_header_support"
+msgstr "Cefnogaeth"
+
+#: views/reviews/add.thtml:91 views/reviews/add.thtml:92
+msgid "addons_display_like_it"
+msgstr "Hoffi"
+
+#: views/addons/display.thtml:210
+msgid "addons_display_long_description"
+msgstr "Disgrifiad Hir"
+
+#: views/reviews/add.thtml:95 views/reviews/add.thtml:96
+msgid "addons_display_love_it"
+msgstr "Gwych"
+
+#: views/addons/display.thtml:178
+msgid "addons_display_more_images"
+msgstr "Rhagor o Ddelweddau"
+
+#: views/addons/display.thtml:465
+#, fuzzy
+msgid "addons_display_nocollections"
+msgstr "This add-on is not yet in any collections."
+
+#. %1$s is either an author's name or a comma separated list of authors. Using
+#. the list doesn't make sense in the English plural form so we ignore the
+#. variable.
+#: views/addons/display.thtml:436
+#, fuzzy
+msgid "addons_display_other_addons_by"
+msgid_plural "addons_display_other_addons_by"
+msgstr[0] "Ychwanegion eraill gan %1$s"
+msgstr[1] "Other add-ons by these authors"
+
+#. %s is the name of the add-on and the add-on section. Example:
+#. Some Add-on :: Firefox Add-ons
+#. This should not be concatenated in the code and should be fixed.
+#: controllers/addons_controller.php:141 controllers/addons_controller.php:280
+#: controllers/addons_controller.php:1442
+#, fuzzy, php-format
+msgid "addons_display_pagetitle"
+msgstr "%s"
+
+#. %s is an email address
+#: views/addons/display.thtml:286
+#, php-format
+msgid "addons_display_paragraph_supportinfoemail"
+msgstr "Mae cefnogaeth ar gyfer yr ychwanegyn ar gael gan y datblygwr yn %s"
+
+#. %$1s is a URL
+#. %$2s is an email address
+#: views/addons/display.thtml:269
+#, php-format
+msgid "addons_display_paragraph_supportinfoemailurl"
+msgstr ""
+"Mae cefnogaeth ar gyfer yr ychwanegyn ar gael gan y datblygwr yn %s neu drwy "
+"anfon e-bost at %s"
+
+#. %s is a URL
+#: views/addons/display.thtml:278
+#, php-format
+msgid "addons_display_paragraph_supportinfourl"
+msgstr "Mae cefnogaeth ar gyfer yr ychwanegyn ar gael gan y datblygwr yn %s"
+
+#: views/addons/display.thtml:383
+msgid "addons_display_rate_it"
+msgstr "Grafddio Hwn"
+
+#: views/reviews/add.thtml:93 views/reviews/add.thtml:94
+msgid "addons_display_really_like_it"
+msgstr "Hoffi'n fawr"
+
+#: views/addons/display.thtml:410
+msgid "addons_display_review_etiquette"
+msgstr ""
+"Paid cofnodi gwallau mewn adolygiadau. Nid ydym yn rhoi dy gyfeiriad e-bost "
+"i ddatblygwyr ychwanegion a gall fod angen iddyn gysylltu a thi."
+
+#. %1 is the review guidelines link
+#: views/addons/display.thtml:417
+#, fuzzy
+msgid "addons_display_review_guidelines_link"
+msgstr "<a href=\"%s\">Review Guidelines</a>"
+
+#. %1 is the support section link
+#: views/addons/display.thtml:414
+#, fuzzy
+msgid "addons_display_review_see_support"
+msgstr ""
+"See the <a href=\"%1$s\">support section</a> to find out where to get "
+"assistance for this add-on."
+
+#: views/addons/display.thtml:404
+msgid "addons_display_review_submit"
+msgstr "Cadw"
+
+#: views/addons/display.thtml:430
+#, php-format
+msgid "addons_display_see_all_addons"
+msgstr "Gweld Holl Ychwanegion %1$s"
+
+#. %1 is the number of reviews
+#: views/addons/display.thtml:364
+#, php-format
+msgid "addons_display_see_all_reviews"
+msgstr "Gweld pob adolygiad (%1$s)"
+
+#: views/addons/display.thtml:219
+msgid "addons_display_see_all_versions"
+msgstr "Gweld Pob Fersiwn"
+
+#: views/addons/display.thtml:321 views/addons/versions.thtml:117
+msgid "addons_display_view_source"
+msgstr "Gweld y ffynhonnell"
+
+#: views/addons/display.thtml:324
+msgid "addons_display_view_stats"
+msgstr "Gweld yr ystadegau"
+
+#: views/addons/display.thtml:376
+msgid "addons_display_what_do_you_think"
+msgstr "Beth wyt ti'n feddwl?"
+
+#: views/elements/app_compatibility.thtml:49
+msgid "addons_display_workswith"
+msgstr "Mae'n gweithio gyda:"
+
+#: views/addons/home.thtml:112
+#, fuzzy
+msgid "addons_home_browse_new"
+msgstr "Just Added"
+
+#: views/addons/home.thtml:110
+#, fuzzy
+msgid "addons_home_browse_popular"
+msgstr "Popular"
+
+#: views/addons/home.thtml:108
+#, fuzzy
+msgid "addons_home_browse_recommended"
+msgstr "Recommended"
+
+#: views/addons/home.thtml:127 views/addons/home.thtml:134
+#: views/addons/home.thtml:141 views/addons/home.thtml:148
+#, fuzzy
+msgid "addons_home_browse_subscribe"
+msgstr "Subscribe"
+
+#: views/addons/home.thtml:101
+#, fuzzy
+msgid "addons_home_browse_title"
+msgstr "Browse Add-ons"
+
+#: views/addons/home.thtml:114
+#, fuzzy
+msgid "addons_home_browse_updated"
+msgstr "Updated"
+
+#: views/elements/amo2009/homepage_addon.thtml:100
+#: views/elements/addon_discussionheader.thtml:83
+#: views/elements/addon_listitem.thtml:109 views/elements/feature.thtml:95
+#: views/addons/category_landing.thtml:66 views/addons/policy.thtml:57
+#: views/addons/display.thtml:70 views/addons/home.thtml:178
+msgid "addons_home_by"
+msgstr "gan"
+
+#: views/addons/home.thtml:169
+#, fuzzy
+msgid "addons_home_collection_popular_title"
+msgstr "Popular Collections"
+
+#: views/elements/amo2009/categories.thtml:69 views/addons/home.thtml:160
+#, fuzzy
+msgid "addons_home_collections"
+msgstr "Collections"
+
+#. %1$s is the count of addons in a collection
+#: views/elements/amo2009/collection_listing_item.thtml:51
+#: views/addons/home.thtml:185
+#, fuzzy
+msgid "addons_home_collections_addon_count"
+msgid_plural "addons_home_collections_addon_count"
+msgstr[0] "<strong>%1$s</strong> add-on"
+msgstr[1] "<strong>%1$s</strong> add-ons"
+
+#: views/addons/home.thtml:196
+#, fuzzy
+msgid "addons_home_collections_all"
+msgstr "View All Collections"
+
+#: views/addons/home.thtml:162
+#, fuzzy
+msgid "addons_home_collections_intro"
+msgstr ""
+"Collections are a way for you to categorize, mix, match and mingle add-ons. "
+"Subscribe to collections created by other users or create your own."
+
+#. %1$s is the count of subscribers for a collection
+#: views/elements/amo2009/collection_listing_item.thtml:58
+#: views/collections/detail.thtml:96 views/addons/home.thtml:189
+#, fuzzy
+msgid "addons_home_collections_subscribers"
+msgid_plural "addons_home_collections_subscribers"
+msgstr[0] "<strong>%1$s</strong> subscriber"
+msgstr[1] "<strong>%1$s</strong> subscribers"
+
+#: views/addons/searchengines.thtml:54 views/addons/themes_landing.thtml:49
+msgid "addons_home_feature_head"
+msgstr "Argymellion"
+
+#: controllers/search_controller.php:218 controllers/addons_controller.php:176
+#: controllers/addons_controller.php:428 controllers/addons_controller.php:671
+#: controllers/addons_controller.php:871
+#: controllers/addons_controller.php:1103
+#: controllers/addons_controller.php:1242
+#: controllers/addons_controller.php:1298
+#, php-format
+msgid "addons_home_header_details"
+msgstr ""
+"Mae ychwanegion yn ymestyn %1$s, gan ganitau i tii gael y math o brofiad "
+"pori rwyt ti am ei gael. Cymer olwg o gwmpas a gwna dy hun yn gysurus gyda%1"
+"$s."
+
+#. %1$s is the HTML collection name link.
+#: views/elements/amo2009/teaser_collections.thtml:107
+#, fuzzy
+msgid "addons_home_introduction_collection_link"
+msgstr "Like these? Find more add-ons in %1$s."
+
+#: views/elements/amo2009/teaser_collections.thtml:60
+#, fuzzy
+msgid "addons_home_introduction_extras"
+msgstr ""
+"<strong>Over 5000 free extras</strong> that let you customize and extend "
+"Firefox to meet your needs."
+
+#: views/elements/amo2009/teaser_collections.thtml:55
+#, fuzzy
+msgid "addons_home_introduction_header"
+msgstr "What are Add-ons?"
+
+#: views/elements/amo2009/teaser_collections.thtml:72
+#, fuzzy
+msgid "addons_home_introduction_install"
+msgstr ""
+"<strong>Easy to install</strong>, get notified when updates are available."
+
+#: views/elements/amo2009/teaser_collections.thtml:45
+#, fuzzy
+msgid "addons_home_introduction_name"
+msgstr "Introduction"
+
+#: views/elements/amo2009/teaser_collections.thtml:66
+#, fuzzy
+msgid "addons_home_introduction_themes"
+msgstr ""
+"Toolbars, themes and search providers that <strong>help you perform common "
+"tasks.</strong>"
+
+#: views/addons/home.thtml:161
+#, fuzzy
+msgid "addons_home_new_indicator"
+msgstr "NEW!"
+
+#: views/elements/app_chooser.thtml:48 views/layouts/amo2009.thtml:257
+msgid "addons_home_other_applications"
+msgstr "Rhaglenni Eraill"
+
+#. %1$s is the application the user is browsing. Examples: Thunderbird, Firefox,
+#. Sunbird
+#: views/pages/collector_faq.thtml:49 views/pages/collector_firstrun.thtml:42
+#: views/pages/collector.thtml:46 views/pages/collector_features.thtml:54
+#: controllers/developers_controller.php:87
+#: controllers/compatibility_controller.php:72
+#: controllers/components/simple_acl.php:81 controllers/components/amo.php:607
+#: controllers/statistics_controller.php:60
+#: controllers/statistics_controller.php:240
+#: controllers/previews_controller.php:67 controllers/users_controller.php:90
+#: controllers/users_controller.php:223 controllers/users_controller.php:330
+#: controllers/users_controller.php:414 controllers/users_controller.php:708
+#: controllers/users_controller.php:723 controllers/reviews_controller.php:204
+#: controllers/reviews_controller.php:251
+#: controllers/reviews_controller.php:346
+#: controllers/reviews_controller.php:425
+#: controllers/search_controller.php:185 controllers/search_controller.php:297
+#: controllers/search_controller.php:301 controllers/addons_controller.php:147
+#: controllers/addons_controller.php:280 controllers/addons_controller.php:370
+#: controllers/addons_controller.php:667 controllers/addons_controller.php:874
+#: controllers/addons_controller.php:1019
+#: controllers/addons_controller.php:1034
+#: controllers/addons_controller.php:1101
+#: controllers/addons_controller.php:1121
+#: controllers/addons_controller.php:1240
+#: controllers/addons_controller.php:1357
+#: controllers/addons_controller.php:1364
+#: controllers/addons_controller.php:1442
+#: controllers/addons_controller.php:1477
+#: controllers/addons_controller.php:1538
+#: controllers/addons_controller.php:1543
+#: controllers/editors_controller.php:64 controllers/pages_controller.php:132
+#: controllers/groups_controller.php:65 controllers/groups_controller.php:71
+#: controllers/groups_controller.php:89 controllers/groups_controller.php:111
+#: controllers/collections_controller.php:57
+#: controllers/collections_controller.php:121
+#: controllers/collections_controller.php:205
+#: controllers/collections_controller.php:365
+#: controllers/collections_controller.php:404
+#: controllers/collections_controller.php:466
+#: controllers/collections_controller.php:538
+#: controllers/collections_controller.php:828
+#: controllers/localizers_controller.php:72
+#, php-format
+msgid "addons_home_pagetitle"
+msgstr "%1$s Ychwanegyn"
+
+#. %1$s is the number of addons downloaded
+#: views/addons/home.thtml:57
+#, fuzzy, php-format
+msgid "addons_home_stats_downloaded"
+msgid_plural "addons_home_stats_downloaded"
+msgstr[0] "<strong>%1$s</strong> <span>add-on downloaded</span>"
+msgstr[1] "<strong>%1$s</strong> <span>add-ons downloaded</span>"
+
+#. %1$s is the number of addons in use
+#: views/addons/home.thtml:63
+#, fuzzy, php-format
+msgid "addons_home_stats_inuse"
+msgid_plural "addons_home_stats_inuse"
+msgstr[0] "<strong>%1$s</strong> <span>add-on in use</span>"
+msgstr[1] "<strong>%1$s</strong> <span>add-ons in use</span>"
+
+#: views/addons/home.thtml:136
+#, fuzzy
+msgid "addons_home_view_all_newest_title"
+msgstr "View all newly created add-ons"
+
+#: views/addons/home.thtml:129
+msgid "addons_home_view_all_popular_title"
+msgstr "Gweld yr ychwanegion mwyaf poblogaidd"
+
+#: views/addons/home.thtml:150
+msgid "addons_home_view_all_recommended_title"
+msgstr "Gweld yr holl ychwanegion gorau"
+
+#: views/addons/home.thtml:143
+#, fuzzy
+msgid "addons_home_view_all_updated_title"
+msgstr "View all recently updated add-ons"
+
+#: views/elements/amo2009/install.thtml:334 views/elements/install.thtml:112
+#, fuzzy
+msgid "addons_install_in_sunbird"
+msgstr ""
+"<ol><li>Click the link below to save the file.</li><li>In Mozilla Sunbird, "
+"open Add-ons from the Tools menu.</li><li>Click the Install button, and "
+"locate/select the file you downloaded and click \"OK\".</li></ol>"
+
+#: views/elements/amo2009/install.thtml:333 views/elements/install.thtml:111
+#, fuzzy
+msgid "addons_install_in_sunbird_title"
+msgstr "How to Install in Sunbird"
+
+#: views/elements/amo2009/install.thtml:331 views/elements/install.thtml:106
+msgid "addons_install_in_thunderbird"
+msgstr ""
+"<ol><li>Rho glic de i'r cyswllt isod a dewis \"Cadw'r Cyswllt Fel...\" ti "
+"lwytho i lawr a chadw'r ffeil i dy ddisg caled.</li><li>Yn Mozilla "
+"Thunderbird, agora'r Ychwanegion o'r ddewislen Offer.</li><li>Clicia'r botwm "
+"Gosod, a chanfod/dewis y ffeil rwyt ti wedi ei lwytho i lawr a chlicio \"Iawn"
+"\".</li></ol>"
+
+#: views/elements/amo2009/install.thtml:330 views/elements/install.thtml:105
+msgid "addons_install_in_thunderbird_title"
+msgstr "Sut mae ei osod o fewn Thunderbird"
+
+#: views/elements/amo2009/addon_list_options.thtml:108
+#: views/elements/addon_list_options.thtml:105
+msgid "addons_options_show_experimental"
+msgstr "dangos ychwanegion arbrofol"
+
+#: views/elements/amo2009/addon_list_options.thtml:113
+#: views/elements/addon_list_options.thtml:109
+msgid "addons_options_submit"
+msgstr "Mynd"
+
+#: views/addons/plugins.thtml:63 views/addons/plugins.thtml:73
+#: views/addons/plugins.thtml:83 views/addons/plugins.thtml:93
+#: views/addons/plugins.thtml:103 views/addons/plugins.thtml:116
+#: views/addons/plugins.thtml:126
+msgid "addons_plugins_by"
+msgstr "Gan"
+
+#: views/addons/plugins.thtml:107
+msgid "addons_plugins_for_linux"
+msgstr "ar gyfer Linux"
+
+#: views/addons/plugins.thtml:108 views/addons/plugins.thtml:131
+msgid "addons_plugins_for_macosx"
+msgstr "ar gyfer y Mac OS X"
+
+#: views/addons/plugins.thtml:106 views/addons/plugins.thtml:129
+#: views/addons/plugins.thtml:130
+msgid "addons_plugins_for_windows"
+msgstr "ar gyfer Windows"
+
+#. %1$s is a URL
+#: views/addons/plugins.thtml:139
+#, php-format
+msgid "addons_plugins_looking_for_more"
+msgstr ""
+"Dim ond yr ategynnau mwyaf cyffredin a phoblogaidd sy'n cael eu rhestru ar y "
+"dudalen hon. Am fwy o wybodaeth ar ategynnau eraill ar gyfer porwyr sy'n "
+"seiliedig ar Mozilla, gwêl %1$s"
+
+#: views/addons/plugins.thtml:137
+msgid "addons_plugins_looking_for_plugin"
+msgstr "Chwilio am ategyn sydd heb ei restru yma?"
+
+#: views/addons/plugins.thtml:58
+msgid "addons_plugins_main_description"
+msgstr ""
+"Mae ategynnau yn cynorthwyo dy borwr i gyflawni tasgau penodol fel dangos "
+"fformatau graffigol arbennig neu chwarae ffeiliau amlgyfrwng. Mae ategynnau "
+"yn ychydig yn wahanol i estyniadau, sy'n newid neu yn ychwanegu at y "
+"swyddogaethau presennol."
+
+#. %1$s is the application name. Example: Firefox, Thunderbird, Sunbird
+#: controllers/addons_controller.php:1122
+#, php-format
+msgid "addons_plugins_main_header"
+msgstr "Ategynnau Cyffredin ar gyfer %1$s"
+
+#: controllers/components/amo.php:698 controllers/addons_controller.php:1121
+msgid "addons_plugins_pagetitle"
+msgstr "Ategynnau"
+
+#: views/addons/plugins.thtml:68 views/addons/plugins.thtml:78
+#: views/addons/plugins.thtml:88 views/addons/plugins.thtml:98
+#: views/addons/plugins.thtml:110 views/addons/plugins.thtml:121
+#: views/addons/plugins.thtml:133
+msgid "addons_plugins_support_documentation"
+msgstr "Dogfennau Cymorth:"
+
+#. %s is the name of the add-on
+#: views/addons/policy.thtml:61
+#, php-format
+msgid "addons_policy_eula_require"
+msgstr ""
+"Mae %s angen i chi dderbyn y Cytundeb Trwyddedu Defnyddiwr cyn bod modd "
+"cychwyn gosod:"
+
+#. %1 is the add-on name
+#: controllers/addons_controller.php:1476
+#, php-format
+msgid "addons_previews_pagetitle"
+msgstr "Rhagolwg %s"
+
+#: views/addons/category_landing.thtml:135
+#, fuzzy
+msgid "addons_recently_added"
+msgstr "Recently Added"
+
+#: views/addons/recommended.thtml:51 controllers/addons_controller.php:1365
+msgid "addons_recommended_introduction"
+msgstr ""
+"Gan fod yna gymaint o ychwanegion rhagorol ar gael, mae yna rhywbeth ar "
+"gyfer pawb. I gychwyn, dyma restr o'r rhai mwyaf poblogaidd. Mwynha!"
+
+#: controllers/addons_controller.php:1357
+#: controllers/addons_controller.php:1364
+msgid "addons_recommended_pagetitle"
+msgstr "Ychwanegion Gorau"
+
+#: controllers/addons_controller.php:1360
+msgid "addons_recommended_title"
+msgstr "Ychwanegion Gorau"
+
+#: views/addons/searchengines.thtml:136
+msgid "addons_searchengines_additional_resources"
+msgstr "Adnoddau Ychwanegol"
+
+#. link text devmo
+#: views/addons/searchengines.thtml:141
+msgid "addons_searchengines_devmo_link"
+msgstr "Canolfan Datblygwyr Mozilla"
+
+#: views/pages/js_constants.js.thtml:67
+msgid "addons_searchengines_error_mozilla_browser_required"
+msgstr ""
+"Ymddiheuriadau, mae angen porwr wedi ei sylfaeni ar Mozilla (e.e. Firefox) i "
+"osod yr ategyn chwilio."
+
+#: views/addons/searchengines.thtml:49
+msgid "addons_searchengines_error_nojavascript"
+msgstr ""
+"Mae angen Javascript ar gyfer gosod ategyn, ond mae'n ymddangos dy fod wedi "
+"ei anablu. Bydd angen cychwyn Javascript cyn gallu gosod yr ategynnau hyn."
+
+#. %1 is "make your own" link
+#. %2 is MDC link
+#: views/addons/searchengines.thtml:139
+msgid "addons_searchengines_learn_howto"
+msgstr "Dysgu sut i %1$s yn y %2$s."
+
+#. link path to search plugins instructions, relative to devmo
+#: views/addons/searchengines.thtml:140
+msgid "addons_searchengines_makeyourown_href"
+msgstr "/en/docs/Creating_OpenSearch_plugins_for_Firefox"
+
+#. link text for "make your own" (opensearch engine)
+#: views/addons/searchengines.thtml:140
+msgid "addons_searchengines_makeyourown_link"
+msgstr "creu dy rhai dy hun"
+
+#. %1 is the link to mycroft.mozdev.org
+#: views/addons/searchengines.thtml:138
+msgid "addons_searchengines_more"
+msgstr "Pori drwy ragor o beiriannau chwilio yn %1$s"
+
+#. link text to mycroft.mozdev.org
+#: views/addons/searchengines.thtml:138
+#, fuzzy
+msgid "addons_searchengines_mycroft_link"
+msgstr "mycroft.mozdev.org"
+
+#: controllers/addons_controller.php:1100
+#: controllers/addons_controller.php:1110
+msgid "addons_searchengines_pagetitle"
+msgstr "Peiriannau Chwilio"
+
+#: views/addons/searchengines.thtml:143
+msgid "addons_searchengines_thanks"
+msgstr ""
+"Diolch arbennig i Broject Mycroft am eu gwaith ar y Peiriant Chwilio Firefox."
+
+#: views/addons/display.thtml:154
+#, fuzzy
+msgid "addons_share_button_text"
+msgstr "Share this"
+
+#: controllers/addons_controller.php:89
+#, fuzzy
+msgid "addons_share_label_delicious"
+msgstr "Add to Delicious"
+
+#: controllers/addons_controller.php:77
+#, fuzzy
+msgid "addons_share_label_digg"
+msgstr "Digg this!"
+
+#: controllers/addons_controller.php:83
+#, fuzzy
+msgid "addons_share_label_facebook"
+msgstr "Post to Facebook"
+
+#: controllers/addons_controller.php:101
+#, fuzzy
+msgid "addons_share_label_friendfeed"
+msgstr "Share on FriendFeed"
+
+#: controllers/addons_controller.php:95
+#, fuzzy
+msgid "addons_share_label_myspace"
+msgstr "Post to MySpace"
+
+#: controllers/components/amo.php:201 controllers/components/amo.php:229
+#, fuzzy
+msgid "addons_status_disabled"
+msgstr "Disabled"
+
+#: controllers/components/amo.php:191 controllers/components/amo.php:224
+#, fuzzy
+msgid "addons_status_incomplete"
+msgstr "Incomplete Version"
+
+#: controllers/components/amo.php:197 controllers/components/amo.php:227
+#, fuzzy
+msgid "addons_status_nominated"
+msgstr "In Sandbox; Public Nomination"
+
+#: views/pages/js_constants.js.thtml:80 controllers/components/amo.php:195
+#: controllers/components/amo.php:226
+#, fuzzy
+msgid "addons_status_pending"
+msgstr "In Sandbox; Pending Review"
+
+#: views/pages/js_constants.js.thtml:78 controllers/components/amo.php:199
+#: controllers/components/amo.php:228
+#, fuzzy
+msgid "addons_status_public"
+msgstr "Public"
+
+#: views/pages/js_constants.js.thtml:79 controllers/components/amo.php:193
+#: controllers/components/amo.php:225
+#, fuzzy
+msgid "addons_status_sandbox"
+msgstr "In Sandbox"
+
+#: controllers/components/amo.php:203
+#, fuzzy
+msgid "addons_status_unknown"
+msgstr "Unknown"
+
+#: views/elements/amo2009/teaser_collections.thtml:91
+#: views/elements/amo2009/homepage_addon.thtml:99
+#: views/elements/feature.thtml:94
+#, fuzzy
+msgid "addons_title_tooltip"
+msgstr "Learn more about this add-on"
+
+#: views/addons/category_landing.thtml:151
+#, fuzzy
+msgid "addons_top_downloads"
+msgstr "Top Downloads"
+
+#: views/addons/category_landing.thtml:165
+#, fuzzy
+msgid "addons_top_rated"
+msgstr "Top Rated"
+
+#: views/addons/versions.thtml:62
+msgid "addons_versions_careful"
+msgstr "Bydd Ofalus gyda Hen Fersiynau"
+
+#: views/addons/versions.thtml:63
+msgid "addons_versions_careful_introduction"
+msgstr ""
+"Mae'r fersiynau hyn yn cael eu dangos er mwyn gwybodaeth a chynnal "
+"arbrofion. Dylet ddefnyddio'r fersiwn diweddaraf bob tro."
+
+#: controllers/addons_controller.php:1549
+msgid "addons_versions_history"
+msgstr "Hanes y Fersiwn a'r Cofnodion Newid"
+
+#. %1$s is the add-on name
+#: controllers/addons_controller.php:1535
+#, php-format
+msgid "addons_versions_pagetitle"
+msgstr "Hanes Fersiwn %1$s"
+
+#: controllers/groups_controller.php:71
+msgid "admin_group_add_pagetitle"
+msgstr "Ychwanegu Grŵp"
+
+#: controllers/groups_controller.php:111
+msgid "admin_group_delete_pagetitle"
+msgstr "Dileu Grŵp"
+
+#. %s is a number to identify the group
+#: controllers/groups_controller.php:117
+#, php-format
+msgid "admin_group_deleted"
+msgstr "Cafod y Grŵp gyda'r enw %s ei ddileu"
+
+#: controllers/groups_controller.php:89
+msgid "admin_group_edit_pagetitle"
+msgstr "Golygu Grŵp"
+
+#: controllers/groups_controller.php:92 controllers/groups_controller.php:113
+msgid "admin_group_error_invalid_id"
+msgstr "Enw annilys ar gyfer Grŵp"
+
+#: controllers/groups_controller.php:65
+msgid "admin_group_pagetitle"
+msgstr "Gweinyddiaeth Grŵp"
+
+#: controllers/groups_controller.php:77 controllers/groups_controller.php:99
+msgid "admin_group_saved"
+msgstr "Mae'r Grŵp wedi ei gadw"
+
+#: views/elements/amo2009/search.thtml:257 views/elements/search.thtml:239
+#, fuzzy
+msgid "advanced_search_form"
+msgstr "Advanced"
+
+#: views/elements/amo2009/search.thtml:126 views/elements/search.thtml:125
+#, fuzzy
+msgid "advanced_search_form_any_time"
+msgstr "Any time"
+
+#: views/elements/amo2009/search.thtml:97
+#: views/elements/amo2009/search.thtml:110 views/elements/search.thtml:96
+#: views/elements/search.thtml:109
+#, fuzzy
+msgid "advanced_search_form_any_type"
+msgstr "Any"
+
+#: views/elements/amo2009/search.thtml:275 views/elements/search.thtml:254
+#, fuzzy
+msgid "advanced_search_form_any_version"
+msgstr "Any"
+
+#: views/elements/amo2009/search.thtml:217 views/elements/search.thtml:212
+#, fuzzy
+msgid "advanced_search_form_application"
+msgstr "Application"
+
+#: views/elements/amo2009/search.thtml:143 views/elements/search.thtml:142
+#, fuzzy
+msgid "advanced_search_form_keyword_match"
+msgstr "Keyword Match"
+
+#: views/elements/amo2009/search.thtml:251 views/elements/search.thtml:225
+#, fuzzy
+msgid "advanced_search_form_lastupdate"
+msgstr "Last Updated"
+
+#: views/elements/amo2009/search.thtml:145 views/elements/search.thtml:144
+#, fuzzy
+msgid "advanced_search_form_name"
+msgstr "Name"
+
+#: views/elements/amo2009/search.thtml:144 views/elements/search.thtml:143
+#, fuzzy
+msgid "advanced_search_form_newest"
+msgstr "Newest"
+
+#: views/elements/amo2009/search.thtml:130 views/elements/search.thtml:129
+#, fuzzy
+msgid "advanced_search_form_past_3_months"
+msgstr "Past 3 months"
+
+#: views/elements/amo2009/search.thtml:131 views/elements/search.thtml:130
+#, fuzzy
+msgid "advanced_search_form_past_6_months"
+msgstr "Past 6 months"
+
+#: views/elements/amo2009/search.thtml:127 views/elements/search.thtml:126
+#, fuzzy
+msgid "advanced_search_form_past_day"
+msgstr "Past Day"
+
+#: views/elements/amo2009/search.thtml:129 views/elements/search.thtml:128
+#, fuzzy
+msgid "advanced_search_form_past_month"
+msgstr "Past month"
+
+#: views/elements/amo2009/search.thtml:128 views/elements/search.thtml:127
+#, fuzzy
+msgid "advanced_search_form_past_week"
+msgstr "Past week"
+
+#: views/elements/amo2009/search.thtml:132 views/elements/search.thtml:131
+#, fuzzy
+msgid "advanced_search_form_past_year"
+msgstr "Past year"
+
+#: views/elements/amo2009/search.thtml:239 views/elements/search.thtml:230
+#, fuzzy
+msgid "advanced_search_form_perpage"
+msgstr "Per Page"
+
+#: views/elements/amo2009/search.thtml:243 views/elements/search.thtml:224
+#, fuzzy
+msgid "advanced_search_form_platform"
+msgstr "Platform"
+
+#: views/elements/amo2009/search.thtml:147 views/elements/search.thtml:146
+#, fuzzy
+msgid "advanced_search_form_popularity"
+msgstr "Popularity"
+
+#: views/elements/amo2009/search.thtml:146 views/elements/search.thtml:145
+#, fuzzy
+msgid "advanced_search_form_rating"
+msgstr "Rating"
+
+#: views/elements/amo2009/search.thtml:247 views/elements/search.thtml:231
+#, fuzzy
+msgid "advanced_search_form_sortby"
+msgstr "Sort By"
+
+#: views/elements/amo2009/search.thtml:227 views/elements/search.thtml:216
+#, fuzzy
+msgid "advanced_search_form_to"
+msgstr "to"
+
+#: views/elements/amo2009/search.thtml:257 views/elements/search.thtml:237
+#, fuzzy
+msgid "advanced_search_form_toggle_tooltip"
+msgstr "Toggle advanced search mode"
+
+#: views/elements/amo2009/search.thtml:235 views/elements/search.thtml:223
+#, fuzzy
+msgid "advanced_search_form_type"
+msgstr "Type"
+
+#: views/elements/amo2009/search.thtml:222 views/elements/search.thtml:214
+#, fuzzy
+msgid "advanced_search_form_version"
+msgstr "version"
+
+#: views/elements/amo2009/pagination.thtml:42
+#, fuzzy
+msgid "amo2009_pagination_next_page"
+msgstr "Next"
+
+#: views/elements/amo2009/pagination.thtml:41
+#, fuzzy
+msgid "amo2009_pagination_previous_page"
+msgstr "Prev"
+
+#: views/pages/js_constants.js.thtml:96
+msgid "app_compat_ignore_check"
+msgstr "Anwybyddu gwirio'r fersiwn"
+
+#: views/pages/js_constants.js.thtml:72
+msgid "app_compat_older_firefox_only"
+msgstr "Mae'r ychwanegyn ar gyfer fersiynau hÅ·n o Firefox"
+
+#. %1$s and %2$s are URLs
+#: views/pages/js_constants.js.thtml:74
+#, fuzzy
+msgid "app_compat_older_version_or_ignore_check"
+msgstr ""
+"You can <a href=\"%1$s\">try an older version</a> or <a href=\"#\" onclick="
+"\"%2$s\">ignore this check</a>"
+
+#. %1$s is a URL
+#: views/pages/js_constants.js.thtml:71
+msgid "app_compat_try_old_version"
+msgstr "Efallai bydd <a href=\"%1$s\">fersiwn hÅ·n</a> yn gweithio"
+
+#. %1$s is a URL
+#. %2$s is a version number. Example: 3.1
+#: views/pages/js_constants.js.thtml:73
+#, fuzzy
+msgid "app_compat_unreleased_version"
+msgstr ""
+"This add-on requires the not-yet released <a href=\"%1$s\">Firefox %2$s</a>"
+
+#: views/pages/js_constants.js.thtml:70
+msgid "app_compat_update_firefox"
+msgstr ""
+"<a href=\"http://getfirefox.com\">Diweddaru Firefox</a> er mwyn defnyddio’r "
+"ychwanegyn hwn"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#. %3$s is a status, like Public.
+#: controllers/components/audit.php:79
+#, fuzzy
+msgid "audit_addon_status"
+msgstr "%1$s changed the status of %2$s to %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:221
+#, fuzzy
+msgid "audit_admin_default"
+msgstr "%1$s committed unknown admin action %2$s to ID %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:153
+#, fuzzy
+msgid "audit_admin_feature_remove"
+msgstr "%1$s removed feature %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is an application, like Firefox.
+#: controllers/components/audit.php:92
+#, fuzzy
+msgid "audit_application_create"
+msgstr "%1$s created application %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is an application, like Firefox.
+#: controllers/components/audit.php:95
+#, fuzzy
+msgid "audit_application_edit"
+msgstr "%1$s edited application %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a version number, like 3.5.
+#. %3$s is an application, like Firefox.
+#: controllers/components/audit.php:105
+#, fuzzy
+msgid "audit_appversion_create"
+msgstr "%1$s created version %2$s for %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a version number, like 3.5.
+#. %3$s is an application, like Firefox.
+#: controllers/components/audit.php:108
+#, fuzzy
+msgid "audit_appversion_delete"
+msgstr "%1$s deleted version %2$s for %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a config field, like "awesomeness".
+#. %3$s is a config value, like "off".
+#. %4$s is a config value, like "on".
+#: controllers/components/audit.php:210
+#, fuzzy
+msgid "audit_config"
+msgstr "%1$s changed config '%2$s' from '%3$s' to '%4$s'"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:258
+#, fuzzy
+msgid "audit_editor_default"
+msgstr "%1$s committed unknown editor action %2$s to ID %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#: controllers/components/audit.php:236
+#, fuzzy
+msgid "audit_editor_feature_remove"
+msgstr "%1$s removed addon %2$s from feature list"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#: controllers/components/audit.php:231
+#, fuzzy
+msgid "audit_feature_add"
+msgstr "%1$s added addon %2$s to feature list"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:149
+#, fuzzy
+msgid "audit_feature_edit"
+msgstr "%1$s changed a feature for %2$s locale"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#: controllers/components/audit.php:241
+#, fuzzy
+msgid "audit_feature_locale_change"
+msgstr "%1$s changed locales for addon %2$s on feature list"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:83
+#, fuzzy
+msgid "audit_file_recalchash"
+msgstr "%1$s recalculated the hash for file %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>user name</a>
+#. %3$s is <a>group name</a>
+#: controllers/components/audit.php:182
+#, fuzzy
+msgid "audit_group_addmember"
+msgstr "%1$s added %2$s to group %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:313
+#, fuzzy
+msgid "audit_group_associated"
+msgstr "%1$s associated themselves with %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:162
+#, fuzzy
+msgid "audit_group_create"
+msgstr "%1s created group %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:170
+#, fuzzy
+msgid "audit_group_delete"
+msgstr "%1$s deleted group %2$s (ID %3$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:165
+#, fuzzy
+msgid "audit_group_edit"
+msgstr "%1$s edited group %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>user name</a>
+#. %3$s is <a>group name</a>
+#: controllers/components/audit.php:188
+#, fuzzy
+msgid "audit_group_removemember"
+msgstr "%1$s removed %2$s from group %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:280
+#, fuzzy
+msgid "audit_l10n_default"
+msgstr "%1$s committed unknown action %2$s for %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:295
+#, fuzzy
+msgid "audit_modify_locked_group"
+msgstr "%1$s attempted to modify locked group %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:299
+#, fuzzy
+msgid "audit_modify_other_locale"
+msgstr "%1$s attempted to modify translations in %2$s without permission"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a platform, like <a>Windows</a>
+#: controllers/components/audit.php:135
+#, fuzzy
+msgid "audit_platform_create"
+msgstr "%1$s created platform %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a platform, like <a>Windows</a>
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:143
+#, fuzzy
+msgid "audit_platform_delete"
+msgstr "%1$s deleted platform %2$s (ID %3$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a platform, like <a>Windows</a>
+#: controllers/components/audit.php:138
+#, fuzzy
+msgid "audit_platform_edit"
+msgstr "%1$s edited platform %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a part of the admin, like 'Site Config'
+#: controllers/components/audit.php:288
+#, fuzzy
+msgid "audit_reauthentication_failure"
+msgstr "%1$s failed to re-authenticate to access %2$s."
+
+#. %1$s is <a>user name</a>
+#. %2$s is the name of a canned response, like 'Ready for the public'
+#: controllers/components/audit.php:198
+#, fuzzy
+msgid "audit_response_create"
+msgstr "%1$s created response %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is the name of a canned response, like 'Ready for the public'
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:206
+#, fuzzy
+msgid "audit_response_delete"
+msgstr "%1$s deleted response %2$s (ID %3$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is the name of a canned response, like 'Ready for the public'
+#: controllers/components/audit.php:201
+#, fuzzy
+msgid "audit_response_edit"
+msgstr "%1$s edited response %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:245
+#, fuzzy
+msgid "audit_review_approve"
+msgstr "%1$s approved review %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:250 controllers/components/audit.php:253
+#, fuzzy
+msgid "audit_review_delete"
+msgstr "%1$s deleted review %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:303
+#, fuzzy
+msgid "audit_security_default"
+msgstr "%1$s committed unknown security action %2$s to ID %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a category name, like <a>Search Tools</a>
+#: controllers/components/audit.php:118
+#, fuzzy
+msgid "audit_tag_create"
+msgstr "%1$s created tag %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a category name, like <a>Search Tools</a>
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:126
+#, fuzzy
+msgid "audit_tag_delete"
+msgstr "%1$s deleted category %2$s (ID %3$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a category name, like <a>Search Tools</a>
+#: controllers/components/audit.php:121
+#, fuzzy
+msgid "audit_tag_edit"
+msgstr "%1$s edited category %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:266
+#, fuzzy
+msgid "audit_update_applications"
+msgstr "%1$s updated application translations for %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:277
+#, fuzzy
+msgid "audit_update_blog"
+msgstr "%1$s updated blog post translations for %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:274
+#, fuzzy
+msgid "audit_update_platforms"
+msgstr "%1$s updated platform translations for %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:270
+#, fuzzy
+msgid "audit_update_tags"
+msgstr "%1$s updated category translations for %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>user name</a>
+#: controllers/components/audit.php:217
+#, fuzzy
+msgid "audit_user_edit"
+msgstr "%1$s edited %2$s's user information"
+
+#: controllers/addons_controller.php:1012
+#, fuzzy
+msgid "browse_addons_name"
+msgstr "Add-ons by Name"
+
+#: controllers/addons_controller.php:1010
+#, fuzzy
+msgid "browse_addons_newest"
+msgstr "Newest Add-ons"
+
+#: controllers/addons_controller.php:1008
+#, fuzzy
+msgid "browse_addons_popular"
+msgstr "Popular Add-ons"
+
+#: controllers/addons_controller.php:1011
+#, fuzzy
+msgid "browse_addons_rated"
+msgstr "Add-ons by Rating"
+
+#: controllers/addons_controller.php:1009
+#, fuzzy
+msgid "browse_addons_updated"
+msgstr "Recently Updated Add-ons"
+
+#: views/elements/categories.thtml:73 views/elements/categories.thtml:82
+msgid "categories_current_title"
+msgstr "Categori Presennol"
+
+#: views/elements/categories.thtml:50
+#: views/elements/amo2009/categories.thtml:43
+#: views/elements/amo2009/categories.thtml:45
+msgid "categories_header"
+msgstr "Categorïau"
+
+#: views/elements/categories.thtml:50
+#: views/elements/amo2009/categories.thtml:41
+msgid "categories_header_title"
+msgstr "Dewis categori"
+
+#. %1$s is the category name
+#: views/addons/searchengines.thtml:129
+#, php-format
+msgid "category_extra_see_all"
+msgstr "Gweld Popeth %1$s"
+
+#. %1$s is a number.
+#: models/collection.php:130
+#, fuzzy
+msgid "collection_description_limit"
+msgstr "The description should be less than %1$s characters."
+
+#. %1$s is the name of the collection
+#: controllers/collections_controller.php:392
+#, fuzzy
+msgid "collection_detail_rss_title"
+msgstr "%s Collection"
+
+#: controllers/collections_controller.php:1065
+#, fuzzy
+msgid "collection_error_deleting_addon"
+msgstr "Error deleting add-on!"
+
+#: controllers/collections_controller.php:1051
+#, fuzzy
+msgid "collection_error_saving_addon"
+msgstr "Error saving add-on!"
+
+#: controllers/collections_controller.php:1080
+#, fuzzy
+msgid "collection_error_saving_comment"
+msgstr "Error saving comment!"
+
+#. %1$s is a number.
+#: models/collection.php:122
+#, fuzzy
+msgid "collection_name_limit"
+msgstr "The name should be less than %1$s characters."
+
+#: controllers/collections_controller.php:352
+#: controllers/collections_controller.php:487
+#, fuzzy
+msgid "collection_not_found"
+msgstr "Collection not found!"
+
+#. %1$s is the text on the "create collection" button
+#: views/collections/add.thtml:91
+#, fuzzy
+msgid "collections_add_formfield_addons_description"
+msgstr ""
+"If you already know which add-ons you want to add to your collection, just "
+"start typing their names below. If you'd rather wait and do this later, just "
+"click %1$s now."
+
+#: views/collections/add.thtml:90
+#, fuzzy
+msgid "collections_add_formfield_firstaddons"
+msgstr "Choose your first add-ons"
+
+#: views/collections/add.thtml:48
+#, fuzzy
+msgid "collections_add_header"
+msgstr "Create a Collection"
+
+#: views/collections/add.thtml:97
+#, fuzzy
+msgid "collections_add_header_selectedaddons"
+msgstr "Selected Add-ons"
+
+#: views/collections/add.thtml:50
+#, fuzzy
+msgid "collections_add_intro"
+msgstr ""
+"It's easy to create your own collection of add-ons by filling in a few "
+"fields below."
+
+#: views/collections/add.thtml:92 views/collections/add.thtml:103
+#, fuzzy
+msgid "collections_add_submit"
+msgstr "Create Collection"
+
+#: views/pages/collector_faq.thtml:50 views/pages/collector_firstrun.thtml:43
+#: views/pages/collector.thtml:47 views/pages/collector_features.thtml:55
+#: controllers/search_controller.php:302
+#: controllers/collections_controller.php:206
+#: controllers/collections_controller.php:405
+#: controllers/collections_controller.php:467
+#: controllers/collections_controller.php:539
+#, fuzzy
+msgid "collections_breadcrumb"
+msgstr "Collections"
+
+#: views/collections/detail.thtml:185
+#, fuzzy
+msgid "collections_detail_a_learn"
+msgstr "Learn More"
+
+#: views/elements/amo2009/collection_add_form.thtml:53
+#: views/elements/amo2009/collections_js_init.thtml:68
+#: views/pages/collector_firstrun.thtml:64
+#, fuzzy
+msgid "collections_detail_button_add"
+msgstr "Add to Favorites"
+
+#: views/elements/amo2009/collection_add_form.thtml:50
+#: views/elements/amo2009/collections_js_init.thtml:71
+#, fuzzy
+msgid "collections_detail_button_remove"
+msgstr "Remove from Favorites"
+
+#. %1$s is a URL.
+#. %2$s is a full <a href>.
+#: views/collections/detail.thtml:62
+#, fuzzy
+msgid "collections_detail_created_desc"
+msgstr ""
+"<p>You can view your new collection below. If you'd like to set a collection "
+"nickname, upload an icon, or change additional settings, please visit the <a "
+"href='%1$s'>Manage Collections</a> page.</p><p>Your collection can be "
+"accessed at this location: %2$s</p>"
+
+#: views/collections/detail.thtml:61
+#, fuzzy
+msgid "collections_detail_created_msg"
+msgstr "Your collection is now ready!"
+
+#: views/collections/detail.thtml:109
+#, fuzzy
+msgid "collections_detail_header_about"
+msgstr "About This Collection"
+
+#. %1$s is a number.
+#: views/collections/detail.thtml:126
+#, fuzzy
+msgid "collections_detail_header_count"
+msgid_plural "collections_detail_header_count"
+msgstr[0] "%1$s Add-on in this Collection"
+msgstr[1] "%1$s Add-ons in this Collection"
+
+#: views/collections/detail.thtml:113
+#, fuzzy
+msgid "collections_detail_info_created"
+msgstr "<strong>Created by:</strong> %1$s"
+
+#: views/collections/detail.thtml:117
+#, fuzzy
+msgid "collections_detail_info_updated"
+msgstr "<strong>Updated:</strong>"
+
+#: views/elements/amo2009/collections_js_init.thtml:62
+#, fuzzy
+msgid "collections_detail_js_adding"
+msgstr "Adding to Favorites&hellip;"
+
+#: views/elements/amo2009/collections_js_init.thtml:65
+#, fuzzy
+msgid "collections_detail_js_removing"
+msgstr "Removing Favorite&hellip;"
+
+#. %1$s is a URL
+#: views/collections/detail.thtml:90
+#, fuzzy
+msgid "collections_detail_login"
+msgstr "<a href=\"%1$s\">Log in</a> to add this collection to your favorites."
+
+#: views/collections/detail.thtml:104
+#, fuzzy
+msgid "collections_detail_manage"
+msgstr "Manage Collection"
+
+#: controllers/collections_controller.php:298
+#, fuzzy
+msgid "collections_detail_sort_date"
+msgstr "Date Added"
+
+#: controllers/collections_controller.php:299
+#, fuzzy
+msgid "collections_detail_sort_name"
+msgstr "Name"
+
+#: controllers/collections_controller.php:300
+#, fuzzy
+msgid "collections_detail_sort_popularity"
+msgstr "Popularity"
+
+#. %1$s is a number.
+#: views/collections/detail.thtml:166
+#, fuzzy
+msgid "collections_detail_weekly_downloads"
+msgid_plural "collections_detail_weekly_downloads"
+msgstr[0] "%1$s download this week"
+msgstr[1] "%1$s downloads this week"
+
+#: views/collections/edit.thtml:255
+#, fuzzy
+msgid "collections_edit_addons_delete_noscript"
+msgstr "Selected add-ons will be removed upon Save"
+
+#: views/collections/edit.thtml:247
+#, fuzzy
+msgid "collections_edit_addons_description"
+msgstr ""
+"To publish new add-ons to this collection, start typing their names below."
+
+#: views/collections/edit.thtml:248
+#, fuzzy
+msgid "collections_edit_addons_description_noscript"
+msgstr ""
+"To publish new add-ons to this collection, enter a comma-separated list of "
+"Add-on IDs below."
+
+#: views/collections/edit.thtml:247 views/collections/edit.thtml:248
+#, fuzzy
+msgid "collections_edit_addons_description_publish_detailspage"
+msgstr "You can also publish an add-on from its normal listing page."
+
+#. %1$s is the date the add-on was added to the collection
+#. %1$s is the name of the user who added the add-on to the collection
+#: views/collections/edit.thtml:260
+#, fuzzy
+msgid "collections_edit_addons_listitem_added"
+msgstr "Added %1$s by %2$s"
+
+#: views/collections/edit.thtml:263
+#, fuzzy
+msgid "collections_edit_addons_listitem_comment_add"
+msgstr "Add publisher comment"
+
+#: views/collections/edit.thtml:266
+#, fuzzy
+msgid "collections_edit_addons_listitem_comment_delete"
+msgstr "Delete publisher comment"
+
+#: views/collections/edit.thtml:265
+#, fuzzy
+msgid "collections_edit_addons_listitem_comment_edit"
+msgstr "Edit publisher comment"
+
+#: views/collections/edit.thtml:271
+#, fuzzy
+msgid "collections_edit_addons_listitem_comment_note"
+msgstr ""
+"Note: Comment will appear as though written by original publisher on the "
+"original publication date"
+
+#: views/collections/edit.thtml:270
+#, fuzzy
+msgid "collections_edit_addons_listitem_comment_submit"
+msgstr "Save Comment"
+
+#: views/collections/edit.thtml:261
+#, fuzzy
+msgid "collections_edit_addons_listitem_remove"
+msgstr "Remove"
+
+#: views/collections/edit.thtml:250
+#, fuzzy
+msgid "collections_edit_addons_submit"
+msgstr "Add to Collection"
+
+#: views/collections/edit.thtml:153
+#, fuzzy
+msgid "collections_edit_check_nickname"
+msgstr "Check Availability"
+
+#: views/collections/edit.thtml:299
+#, fuzzy
+msgid "collections_edit_confirm_deletecollection"
+msgstr "Yes, I would like to delete this collection."
+
+#. %1$s is the label of the edit form's submit button
+#: views/collections/edit.thtml:300
+#, fuzzy
+msgid "collections_edit_confirm_deletecollection_description"
+msgstr "Check the box, then click on \"%1$s\" to delete this collection."
+
+#. %1$s is the "delete" submit button text
+#. %2$s is the title of the "advanced" tab
+#: views/collections/edit.thtml:95
+#, fuzzy
+msgid "collections_edit_delete_upon_submit"
+msgstr ""
+"Upon clicking \"%1$s\" below, your collection will be deleted. If you do not "
+"want to delete your collection, uncheck the confirmation box in the \"%2$s\" "
+"tab and continue editing your collection. If you leave this page without "
+"saving, your collection will also not be deleted."
+
+#: views/collections/edit.thtml:94
+#, fuzzy
+msgid "collections_edit_delete_warning"
+msgstr "Your collection is about to be deleted!"
+
+#: views/collections/add.thtml:76 views/collections/edit.thtml:144
+#, fuzzy
+msgid "collections_edit_form_error_description"
+msgstr "You must provide a description of your collection."
+
+#: views/collections/edit.thtml:181
+#, fuzzy
+msgid "collections_edit_form_error_icon"
+msgstr "There was an error uploading your icon."
+
+#: views/collections/add.thtml:69 views/collections/edit.thtml:130
+#, fuzzy
+msgid "collections_edit_form_error_name"
+msgstr "You must give your collection a name."
+
+#: views/collections/edit.thtml:158
+#, fuzzy
+msgid "collections_edit_form_error_nickname"
+msgstr "If you choose a nickname, it must be unique."
+
+#: views/collections/add.thtml:93 views/collections/edit.thtml:249
+#, fuzzy
+msgid "collections_edit_formfield_addons"
+msgstr "Add-on name:"
+
+#: views/collections/edit.thtml:281
+#, fuzzy
+msgid "collections_edit_formfield_application"
+msgstr "Associated Application"
+
+#: views/collections/edit.thtml:282
+#, fuzzy
+msgid "collections_edit_formfield_application_description"
+msgstr "Select the application that your collection supports."
+
+#: views/collections/edit.thtml:288
+#, fuzzy
+msgid "collections_edit_formfield_collectiontype"
+msgstr "Collection Type"
+
+#: views/collections/edit.thtml:295
+#, fuzzy
+msgid "collections_edit_formfield_deletecollection"
+msgstr "Delete Collection"
+
+#: views/collections/edit.thtml:296
+#, fuzzy
+msgid "collections_edit_formfield_deletecollection_description"
+msgstr "Deleting your collection will permanently erase it."
+
+#: views/collections/add.thtml:73 views/collections/edit.thtml:140
+#, fuzzy
+msgid "collections_edit_formfield_description"
+msgstr "Collection Description"
+
+#: views/collections/add.thtml:74 views/collections/edit.thtml:141
+#, fuzzy
+msgid "collections_edit_formfield_description_description"
+msgstr "Briefly describe your collection and the kind of add-ons in it"
+
+#: views/collections/edit.thtml:162
+#, fuzzy
+msgid "collections_edit_formfield_icon"
+msgstr "Icon"
+
+#: views/collections/edit.thtml:163
+#, fuzzy
+msgid "collections_edit_formfield_icon_description"
+msgstr ""
+"You can upload a JPG, GIF or PNG icon that will be resized to 32x32 pixels."
+
+#: views/collections/add.thtml:80 views/collections/edit.thtml:189
+#, fuzzy
+msgid "collections_edit_formfield_listed"
+msgstr "Who can view your collection?"
+
+#: views/collections/add.thtml:81 views/collections/edit.thtml:190
+#, fuzzy
+msgid "collections_edit_formfield_listed_description"
+msgstr ""
+"By default, collections appear in the public Collection Directory and are "
+"discoverable by anyone. If you want to restrict your collection to be "
+"viewable only by people who are given a special link, choose that option "
+"below."
+
+#: views/collections/add.thtml:84 views/collections/edit.thtml:193
+#, fuzzy
+msgid "collections_edit_formfield_listed_false"
+msgstr "Only people I invite can view my collection"
+
+#: views/collections/add.thtml:83 views/collections/edit.thtml:192
+#, fuzzy
+msgid "collections_edit_formfield_listed_true"
+msgstr "Everyone can view my collection in the directory"
+
+#: views/collections/edit.thtml:223
+#, fuzzy
+msgid "collections_edit_formfield_managers"
+msgstr "Who can manage my collection?"
+
+#: views/collections/edit.thtml:224
+#, fuzzy
+msgid "collections_edit_formfield_managers_description"
+msgstr ""
+"These users can publish add-ons to your collection, manage all add-ons and "
+"settings, and grant other users permission."
+
+#: views/collections/add.thtml:66 views/collections/edit.thtml:126
+#, fuzzy
+msgid "collections_edit_formfield_name"
+msgstr "Collection Name"
+
+#: views/collections/add.thtml:67 views/collections/edit.thtml:127
+#, fuzzy
+msgid "collections_edit_formfield_name_description"
+msgstr ""
+"Give your collection a descriptive name, such as \"Dave's Favorite Travel "
+"Add-ons\""
+
+#: views/collections/edit.thtml:148
+#, fuzzy
+msgid "collections_edit_formfield_nickname"
+msgstr "Collection Nickname"
+
+#: views/collections/edit.thtml:149
+#, fuzzy
+msgid "collections_edit_formfield_nickname_description"
+msgstr "Optionally, give your collection a unique nickname for quick access:"
+
+#: views/collections/edit.thtml:201
+#, fuzzy
+msgid "collections_edit_formfield_publishers"
+msgstr "Who can publish add-ons to your collection?"
+
+#: views/collections/edit.thtml:202
+#, fuzzy
+msgid "collections_edit_formfield_publishers_description"
+msgstr ""
+"These users can publish add-ons to your collection and remove add-ons that "
+"they publish."
+
+#: views/collections/edit.thtml:210 views/collections/edit.thtml:232
+#, fuzzy
+msgid "collections_edit_formfield_users_add"
+msgstr "Enter the e-mail address of a Firefox Add-ons account:"
+
+#: views/collections/edit.thtml:216 views/collections/edit.thtml:238
+#, fuzzy
+msgid "collections_edit_formfield_users_delete_noscript"
+msgstr "Selected accounts will be removed upon Save"
+
+#: views/collections/edit.thtml:215 views/collections/edit.thtml:237
+#, fuzzy
+msgid "collections_edit_formfield_users_new_noscript"
+msgstr ""
+"Enter a comma-separated list of e-mail addresses of Firefox Add-ons accounts"
+
+#: views/collections/edit.thtml:204 views/collections/edit.thtml:226
+#, fuzzy
+msgid "collections_edit_formfield_users_onlyme"
+msgstr "Only me"
+
+#: views/collections/edit.thtml:205 views/collections/edit.thtml:227
+#, fuzzy
+msgid "collections_edit_formfield_users_otherusers"
+msgstr "Myself and these users:"
+
+#: views/collections/edit.thtml:211 views/collections/edit.thtml:233
+#, fuzzy
+msgid "collections_edit_formfield_users_submit"
+msgstr "Add"
+
+#. %1$s is the name of the collection
+#: views/collections/edit.thtml:68
+#, fuzzy
+msgid "collections_edit_header"
+msgstr "Manage %1$s"
+
+#: views/collections/edit.thtml:246
+#, fuzzy
+msgid "collections_edit_header_addons"
+msgstr "Manage Collection Contents"
+
+#: views/collections/edit.thtml:253 views/collections/edit.thtml:258
+#, fuzzy
+msgid "collections_edit_header_addons_current"
+msgstr "Current Add-ons:"
+
+#: views/collections/edit.thtml:279
+#, fuzzy
+msgid "collections_edit_header_advanced"
+msgstr "Advanced Settings"
+
+#: views/collections/edit.thtml:186
+#, fuzzy
+msgid "collections_edit_header_permissions"
+msgstr "Manage Collection Permissions"
+
+#: views/collections/edit.thtml:170
+#, fuzzy
+msgid "collections_edit_icon_cancel"
+msgstr "Cancel"
+
+#: views/collections/edit.thtml:174 views/collections/edit.thtml:179
+#, fuzzy
+msgid "collections_edit_icon_delete"
+msgstr "Delete Icon"
+
+#: views/collections/edit.thtml:178
+#, fuzzy
+msgid "collections_edit_icon_replace"
+msgstr "Replace Icon"
+
+#. %1$s is the label of the edit form's submit button
+#: views/collections/edit.thtml:169
+#, fuzzy
+msgid "collections_edit_icon_toberemoved"
+msgstr "Icon will be removed when \"%1$s\" is clicked below"
+
+#: views/collections/edit.thtml:155
+#, fuzzy
+msgid "collections_edit_nickname_available"
+msgstr "Nickname Available"
+
+#: controllers/collections_controller.php:943
+#, fuzzy
+msgid "collections_edit_nickname_error"
+msgstr ""
+"Your nickname contained invalid characters and was corrected. Please try "
+"again."
+
+#: views/collections/edit.thtml:156
+#, fuzzy
+msgid "collections_edit_nickname_taken"
+msgstr "Nickname Taken"
+
+#. This string is followed by a URL pointing to the collection's view page
+#: views/collections/edit.thtml:75
+#, fuzzy
+msgid "collections_edit_saved_nextstep"
+msgstr "Your collection can be accessed at this location:"
+
+#: views/collections/edit.thtml:74
+#, fuzzy
+msgid "collections_edit_saved_success"
+msgstr "Your collection was successfully saved!"
+
+#: views/collections/edit.thtml:169 views/collections/edit.thtml:300
+#: views/collections/edit.thtml:308 views/pages/js_constants.js.thtml:99
+#, fuzzy
+msgid "collections_edit_submit"
+msgstr "Update Collection"
+
+#: views/collections/edit.thtml:96 views/collections/edit.thtml:297
+#: views/pages/js_constants.js.thtml:100
+#, fuzzy
+msgid "collections_edit_submit_deletecollection"
+msgstr "Delete Collection"
+
+#: views/collections/edit.thtml:111
+#, fuzzy
+msgid "collections_edit_tabheader_addons"
+msgstr "Add-ons"
+
+#: views/collections/edit.thtml:97 views/collections/edit.thtml:113
+#, fuzzy
+msgid "collections_edit_tabheader_advanced"
+msgstr "Advanced"
+
+#: views/collections/edit.thtml:108
+#, fuzzy
+msgid "collections_edit_tabheader_details"
+msgstr "Name &amp; Details"
+
+#: views/collections/edit.thtml:109
+#, fuzzy
+msgid "collections_edit_tabheader_permissions"
+msgstr "Permissions"
+
+#: models/collection_promo.php:53
+#, fuzzy
+msgid "collections_family_tagline"
+msgstr "Add-ons can keep an eye on your kids and your calendar."
+
+#: models/collection_promo.php:53
+#, fuzzy
+msgid "collections_family_title"
+msgstr "Family Organizer"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:70
+#, fuzzy
+msgid "collections_index_a_check_out"
+msgstr "Check out Add-on Collector"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:52
+#, fuzzy
+msgid "collections_index_a_create"
+msgstr "Create a Collection"
+
+#: views/collections/detail.thtml:139 views/collections/listing.thtml:85
+#: views/search/collections.thtml:84
+#, fuzzy
+msgid "collections_index_button_go"
+msgstr "Go"
+
+#. %1$s is a URL.
+#: controllers/collections_controller.php:182
+#, fuzzy
+msgid "collections_index_filler_favorites"
+msgstr ""
+"<p><strong>You don't have any favorite collections yet.</strong></p> "
+"<p>Collections you mark as favorites can be quickly accessed from this page, "
+"and will appear in the <a href='%1$s'>Add-on Collector</a> if you've "
+"installed it.</p>"
+
+#. %1$s is a URL.
+#: controllers/collections_controller.php:167
+#, fuzzy
+msgid "collections_index_filler_mine"
+msgstr ""
+"<p>You haven't created any collections yet. Collections are easy to create "
+"and fill with your favorite add-ons. <a href='%1$s'>Try it out</a>!</p>"
+
+#: views/collections/listing.thtml:51
+#, fuzzy
+msgid "collections_index_header_collections"
+msgstr "Collections"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:60
+#, fuzzy
+msgid "collections_index_header_collector"
+msgstr "Add-on Collector"
+
+#. %1$s is a comma-separated list of author names
+#: views/elements/amo2009/collection_listing_item.thtml:84
+#: views/collections/detail.thtml:151
+#, fuzzy
+msgid "collections_index_header_created"
+msgstr "created by %1$s"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:47
+#, fuzzy
+msgid "collections_index_header_what"
+msgstr "What are Collections?"
+
+#: views/collections/detail.thtml:132 views/collections/listing.thtml:78
+#: views/search/collections.thtml:66
+#, fuzzy
+msgid "collections_index_label_sortby"
+msgstr "Sort by"
+
+#: controllers/collections_controller.php:130
+#, fuzzy
+msgid "collections_index_li_editors"
+msgstr "Editor's Picks"
+
+#: views/collections/subscribe.thtml:64
+#: controllers/collections_controller.php:140
+#, fuzzy
+msgid "collections_index_li_favorites"
+msgstr "My Favorites"
+
+#: controllers/collections_controller.php:138
+#, fuzzy
+msgid "collections_index_li_mine"
+msgstr "My Collections"
+
+#: controllers/collections_controller.php:132
+#, fuzzy
+msgid "collections_index_li_popular"
+msgstr "Popular"
+
+#: views/search/collections.thtml:74 controllers/collections_controller.php:81
+#, fuzzy
+msgid "collections_index_option_all"
+msgstr "Most popular all time"
+
+#: views/search/collections.thtml:72 controllers/collections_controller.php:78
+#, fuzzy
+msgid "collections_index_option_month"
+msgstr "Most popular this month"
+
+#: views/search/collections.thtml:76 controllers/collections_controller.php:84
+#, fuzzy
+msgid "collections_index_option_newest"
+msgstr "Newest"
+
+#: views/search/collections.thtml:70 controllers/collections_controller.php:75
+#, fuzzy
+msgid "collections_index_option_week"
+msgstr "Most popular this week"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:67
+#, fuzzy
+msgid "collections_index_p_collector"
+msgstr ""
+"There's a new way to manage and find favorite add-ons. Comment, share and "
+"sync collections, all from your browser"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:48
+#, fuzzy
+msgid "collections_index_p_what_are"
+msgstr "Collections are groups of related add-ons assembled for easy sharing."
+
+#. %s is a date in the _('date') format
+#: views/elements/collections_interactive_addon.thtml:85
+#, fuzzy, php-format
+msgid "collections_interactive_addon_added"
+msgstr "Added %s"
+
+#: models/collection_promo.php:55
+#, fuzzy
+msgid "collections_reference_tagline"
+msgstr "Add-ons can do better research online."
+
+#: models/collection_promo.php:55
+#, fuzzy
+msgid "collections_reference_title"
+msgstr "Reference Desk"
+
+#: models/collection_promo.php:52
+#, fuzzy
+msgid "collections_social_tagline"
+msgstr "Add-ons can manage your social network."
+
+#: models/collection_promo.php:52
+#, fuzzy
+msgid "collections_social_title"
+msgstr "Social Circuit"
+
+#: views/collections/subscribe.thtml:91
+#, fuzzy
+msgid "collections_subscribe_button_close"
+msgstr "Close"
+
+#: views/collections/subscribe.thtml:70
+#, fuzzy
+msgid "collections_subscribe_error"
+msgstr ""
+"An error occurred trying to add a favorite collection. Is this collection "
+"already a favorite?"
+
+#: views/collections/subscribe.thtml:96
+#, fuzzy
+msgid "collections_subscribe_label_bothersome"
+msgstr "Don't show me this message again."
+
+#. %1$s is the collection name
+#: views/collections/subscribe.thtml:60
+#, fuzzy
+msgid "collections_subscribe_success"
+msgstr "%1$s has been added to your favorite collections."
+
+#. %1$s is the link to the "My Favorites" tab on the main collections page
+#. %2$s is the localized title of the "My Favorites" tab
+#. %3$s is the link URL to the collector add-on
+#: views/collections/subscribe.thtml:62
+#, fuzzy
+msgid "collections_subscribe_success_desc"
+msgstr ""
+"You can now quickly find this collection from the <a href=\"%1$s\">%2$s</a> "
+"tab in the directory. For an even easier way to keep track of your favorite "
+"collections, try out our <a href=\"%3$s\">Add-on Collector</a> extension for "
+"Firefox."
+
+#: views/collections/listing.thtml:55
+#, fuzzy
+msgid "collections_success_delete"
+msgstr "The collection has been deleted."
+
+#: models/collection_promo.php:54
+#, fuzzy
+msgid "collections_travel_tagline"
+msgstr "Add-ons can turn you into a travel agent."
+
+#: models/collection_promo.php:54
+#, fuzzy
+msgid "collections_travel_title"
+msgstr "The Traveler's Pack"
+
+#. A collection of add-ons that is automatically built for a user. They are "automatically published" to this collection.
+#: controllers/collections_controller.php:581
+#, fuzzy
+msgid "collections_type_autopublisher"
+msgstr "Auto-publisher"
+
+#. A collection that has been chosen by an Editor as notable or exceptional
+#: controllers/collections_controller.php:582
+#, fuzzy
+msgid "collections_type_editorspick"
+msgstr "Editor's Pick"
+
+#: controllers/collections_controller.php:580
+#, fuzzy
+msgid "collections_type_normal"
+msgstr "Normal"
+
+#: views/collections/subscribe.thtml:84
+#, fuzzy
+msgid "collections_unsubscribe_error"
+msgstr ""
+"An error occurred trying to remove a favorite collection. Was this "
+"collection not a favorite?"
+
+#. %1$s is the collection name
+#: views/collections/subscribe.thtml:78
+#, fuzzy
+msgid "collections_unsubscribe_success"
+msgstr "%1$s has been removed from your favorite collections."
+
+#: models/collection_promo.php:56
+#, fuzzy
+msgid "collections_webdev_tagline"
+msgstr "Add-ons make it easier to build the perfect website."
+
+#: models/collection_promo.php:56
+#, fuzzy
+msgid "collections_webdev_title"
+msgstr "Web Developer's Toolbox"
+
+#: views/elements/amo2009/collections_sidebar_whatare.thtml:40
+#, fuzzy
+msgid "collections_whatare_header"
+msgstr "What are Collections?"
+
+#: views/elements/amo2009/collections_sidebar_whatare.thtml:45
+#, fuzzy
+msgid "collections_whatare_learnmore"
+msgstr "Read the FAQ"
+
+#: views/elements/amo2009/collections_sidebar_whatare.thtml:44
+#, fuzzy
+msgid "collections_whatare_text"
+msgstr ""
+"There’s a new way to manage and find favorite add-ons. Comment, share and "
+"sync collections, all from your browser."
+
+#: views/pages/collector_faq.thtml:61 views/pages/collector_features.thtml:67
+#, fuzzy
+msgid "collector_features_a_home"
+msgstr "Add-on Collector Home"
+
+#: views/elements/amo2009/collector_sidebar_download.thtml:46
+#, fuzzy
+msgid "collector_features_heading_download"
+msgstr "Download the Add-on Collector:"
+
+#: views/elements/amo2009/collector_sidebar_download.thtml:43
+#: views/pages/collector_firstrun.thtml:116 views/pages/collector.thtml:69
+#, fuzzy
+msgid "collector_features_img_logo"
+msgstr "Add-on Collector Logo"
+
+#: views/compatibility/dashboard.thtml:49
+#: controllers/compatibility_controller.php:72
+#, fuzzy
+msgid "compatibility_dashboard_center_header"
+msgstr "Add-on Compatibility Center"
+
+#. %1$s is the name of an application and a version. Example: Firefox 3.0
+#. %2$s is the name of an application. Example: Firefox
+#: views/compatibility/dashboard.thtml:50
+#, fuzzy
+msgid "compatibility_dashboard_intro"
+msgstr ""
+"Be prepared for the release of %1$s with the tools and information available "
+"for the %2$s Add-ons community found below."
+
+#: views/compatibility/dashboard.thtml:103
+#, fuzzy
+msgid "compatibility_dashboard_loading"
+msgstr "Loading data..."
+
+#: views/compatibility/dashboard.thtml:45
+#, fuzzy
+msgid "compatibility_dashboard_main_link"
+msgstr "Back to Main"
+
+#: views/compatibility/dashboard.thtml:100 views/compatibility/report.thtml:43
+#, fuzzy
+msgid "compatibility_dashboard_report"
+msgstr "Add-on Compatibility Report"
+
+#: views/compatibility/dashboard.thtml:53
+#: views/compatibility/dashboard.thtml:110
+#: views/compatibility/developers.thtml:43
+#, fuzzy
+msgid "compatibility_developer_info"
+msgstr "Information for Add-on Developers"
+
+#: views/compatibility/developers.thtml:66
+#, fuzzy
+msgid "compatibility_developers_adjust_maxversion"
+msgstr "Adjust maxVersion without uploading"
+
+#: views/compatibility/dashboard.thtml:124
+#, fuzzy
+msgid "compatibility_developers_check_status"
+msgstr "Check Status of My Add-ons"
+
+#. %1$s is a URL
+#. %2$s is an application and version. Example: Firefox 3.0
+#: views/compatibility/dashboard.thtml:126
+#, fuzzy
+msgid "compatibility_developers_login_first"
+msgstr ""
+"If you have add-ons hosted on Mozilla Add-ons, <a href=\"%1$s\">please "
+"login</a> to analyze the status of your add-ons for %2$s."
+
+#: views/compatibility/dashboard.thtml:114
+#, fuzzy
+msgid "compatibility_developers_mdclogo_alt"
+msgstr "Mozilla Developer Center Logo"
+
+#: views/compatibility/developers.thtml:73
+#, fuzzy
+msgid "compatibility_developers_no_addons"
+msgstr "You do not have any add-ons hosted on Mozilla Add-ons."
+
+#: views/compatibility/dashboard.thtml:133
+#: views/compatibility/developers.thtml:55
+#, fuzzy
+msgid "compatibility_developers_results"
+msgstr "Add-on Status Check Results"
+
+#: views/compatibility/dashboard.thtml:137
+#, fuzzy
+msgid "compatibility_developers_retrieving"
+msgstr "Retrieving status of hosted add-ons..."
+
+#. %1$s is a number
+#. %2$s is an application name
+#. %3$s is a number.
+#. Full example: 50 Firefox users (10% of total)
+#: views/compatibility/developers.thtml:65
+#, fuzzy
+msgid "compatibility_developers_user_count"
+msgstr "%1$s %2$s users (%3$s&#37; of total)"
+
+#: views/compatibility/report.thtml:45
+#, fuzzy
+msgid "compatibility_report_detail_intro"
+msgstr ""
+"The add-ons below make up 95% of add-on usage known to Mozilla and are "
+"ordered by their usage size."
+
+#: views/compatibility/dashboard.thtml:94
+#, fuzzy
+msgid "compatibility_report_detailed_link"
+msgstr "View Detailed Report"
+
+#. %1$s and %2$s are numbers
+#. %3$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:65
+#, fuzzy
+msgid "compatibility_report_intro"
+msgstr ""
+"Of the %1$s add-ons that make up 95&#37; of add-on usage known to Mozilla, "
+"<b>%2$s&#37;</b> are currently considered compatible with the latest builds "
+"of %3$s."
+
+#: views/compatibility/dashboard.thtml:81
+#, fuzzy
+msgid "compatibility_report_legend_alpha"
+msgstr "Alpha Versions"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:81
+#, fuzzy
+msgid "compatibility_report_legend_alpha_description"
+msgstr "Add-ons compatible with an alpha version of %1$s"
+
+#: views/compatibility/dashboard.thtml:85
+#, fuzzy
+msgid "compatibility_report_legend_beta"
+msgstr "Beta Versions"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:85
+#, fuzzy
+msgid "compatibility_report_legend_beta_description"
+msgstr "Add-ons compatible with a beta version or release candidate of %1$s"
+
+#: views/compatibility/dashboard.thtml:89
+#, fuzzy
+msgid "compatibility_report_legend_latest"
+msgstr "Latest Version"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:89
+#, fuzzy
+msgid "compatibility_report_legend_latest_description"
+msgstr "Add-ons up-to-date with the latest builds of %1$s"
+
+#: views/compatibility/dashboard.thtml:77
+#, fuzzy
+msgid "compatibility_report_legend_other"
+msgstr "Other Versions"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:77
+#, fuzzy
+msgid "compatibility_report_legend_other_description"
+msgstr "Add-ons not compatible with any version of %1$s"
+
+#: views/compatibility/dashboard.thtml:62
+#, fuzzy
+msgid "compatibility_report_title"
+msgstr "Add-on Compatibility Report"
+
+#: views/compatibility/dashboard.thtml:54
+#: views/compatibility/dashboard.thtml:144 views/compatibility/users.thtml:42
+#, fuzzy
+msgid "compatibility_user_info"
+msgstr "Information for Add-on Users"
+
+#: views/compatibility/dashboard.thtml:52
+#, fuzzy
+msgid "compatibility_view_report"
+msgstr "View Compatibility Report"
+
+#. %s is a URL
+#: views/pages/credits.thtml:142
+#, php-format
+msgid "credits_contributing"
+msgstr "Am wybodaeth ar gyfrannu, gwel %s."
+
+#: views/pages/credits.thtml:142
+msgid "credits_contributing_wikipage"
+msgstr "tudalen wiki"
+
+#: views/pages/credits.thtml:99
+msgid "credits_intro"
+msgstr ""
+"Hoffai Mozilla ddiolch i'r canlynol am eu cyfraniad i broject addons.mozilla."
+"org project dros y blynyddoedd:"
+
+#: views/pages/credits.thtml:103
+msgid "credits_section_developers"
+msgstr "Datblygwyr"
+
+#: views/pages/credits.thtml:115
+msgid "credits_section_editors"
+msgstr "Golygyddion"
+
+#: views/pages/credits.thtml:109
+msgid "credits_section_localizers"
+msgstr "Lleoleiddwyr"
+
+#: views/pages/credits.thtml:121
+msgid "credits_section_other_contributors"
+msgstr "Cyfranwyr Eraill"
+
+#: views/pages/credits.thtml:127
+msgid "credits_section_past_developers"
+msgstr "Datblygwyr Blaenorol"
+
+#: views/pages/credits.thtml:133
+msgid "credits_section_software"
+msgstr "Meddalwedd a Delweddau"
+
+#: views/pages/credits.thtml:136
+msgid "credits_software_famfamfam"
+msgstr ""
+"Mae rhai eiconau yn dod o <a href=\"http://www.famfamfam.com/lab/icons/silk/"
+"\">famfamfam Silk Icon Set</a>,o dan drwydded <a href=\"http://"
+"creativecommons.org/licenses/by/2.5/\">Creative Commons Attribution 2.5 "
+"License</a>."
+
+#: views/pages/credits.thtml:137
+#, fuzzy
+msgid "credits_software_timeplot"
+msgstr ""
+"Some pages use elements of <a href=\"http://www.simile-widgets.org/timeplot/"
+"\">Timeplot</a>, licensed under a <a href=\"http://simile.mit.edu/license."
+"html\">BSD License</a>."
+
+#. date format string as used in PHP's strftime():
+#. http://php.net/strftime
+#: views/elements/collections_interactive_addon.thtml:85
+#: views/elements/amo2009/addon_version_detail.thtml:53
+#: views/elements/amo2009/homepage_addon.thtml:115
+#: views/elements/addon_version_detail.thtml:54
+#: views/elements/addon_listitem.thtml:124 views/elements/feature.thtml:106
+#: views/collections/detail.thtml:118 views/collections/edit.thtml:325
+#: views/users/info.thtml:76 views/editors/reviews_queue.thtml:57
+#: views/editors/reviews_queue.thtml:68 views/developers/dashboard.thtml:65
+#: views/developers/versions_edit.thtml:208 views/developers/versions.thtml:67
+#: views/search/rss/index.thtml:5 views/addons/rss/versions.thtml:42
+#: views/addons/display.thtml:104 views/addons/display.thtml:356
+#: views/addons/browse_thumbs.thtml:75 views/reviews/add.thtml:63
+#: views/reviews/display.thtml:74 views/reviews/display.thtml:160
+#: views/reviews/delete.thtml:54 controllers/statistics_controller.php:244
+#: controllers/collections_controller.php:1047
+msgid "date"
+msgstr "%B %e, %Y"
+
+#. date and time format string (strftime)
+#. http://php.net/strftime
+#: views/elements/addon_version_detail.thtml:53
+#: views/developers/discuss.thtml:52 views/developers/discuss.thtml:62
+#: views/admin/addons_status.thtml:57
+msgid "datetime"
+msgstr "%B %e, %Y, %I:%M %p"
+
+#: views/elements/developers/actionbar.thtml:47
+msgid "devcp_actionbar_link_details"
+msgstr "Gwybodaeth Fanwl"
+
+#: views/elements/developers/actionbar.thtml:42
+#: views/elements/developers/actionbar.thtml:50
+#: views/developers/dashboard.thtml:64
+msgid "devcp_actionbar_link_edit"
+msgstr "Golygu Ychwanegyn"
+
+#: views/elements/developers/actionbar.thtml:51
+msgid "devcp_actionbar_link_newversion"
+msgstr "Llwytho Fersiwn Newydd"
+
+#: views/elements/developers/actionbar.thtml:44
+#: views/elements/developers/actionbar.thtml:49
+#: views/developers/dashboard.thtml:73
+msgid "devcp_actionbar_link_stats"
+msgstr "Bwrdd Gwybodaeth Ystadegau"
+
+#. %1$s is a filename, e.g. "foo.txt"
+#. %2$s is the extension, e.g. ".txt"
+#. %3$s is a list of valid extensions, like ".png, .jpg, .gif"
+#: controllers/developers_controller.php:1361
+#, fuzzy
+msgid "devcp_add_previews_extension_error"
+msgstr "File %1$s has an invalid extension (%2$s). Allowed extensions: %3$s"
+
+#. %s is the filename.
+#: controllers/developers_controller.php:1394
+#, fuzzy
+msgid "devcp_add_previews_save_error"
+msgstr "File %s could not be saved to the database. Please try again."
+
+#. %1$s is the preview ID number, %2$s is the filename.
+#: controllers/developers_controller.php:1389
+#, fuzzy
+msgid "devcp_add_previews_success_replace"
+msgstr "Preview %1$s was replaced with file %2$s successfully."
+
+#. %s is the filename.
+#: controllers/developers_controller.php:1391
+#, fuzzy
+msgid "devcp_add_previews_success_upload"
+msgstr "File %s was uploaded successfully. You can add a caption below."
+
+#: controllers/components/developers.php:1163
+msgid "devcp_additem_addontype_autodetect"
+msgstr "(awto ganfod)"
+
+#: views/elements/developers/additem.thtml:76
+msgid "devcp_additem_linktitle_opensin_newwindow"
+msgstr "Agor mewn ffenestr newydd"
+
+#: views/elements/developers/additem.thtml:41
+msgid "devcp_additem_sidebar_title"
+msgstr "Cyflwyno Ychwanegyn"
+
+#: views/elements/developers/additem.thtml:53
+msgid "devcp_additem_step0_newlink"
+msgstr "Cytundeb Datblygwr"
+
+#: views/elements/developers/additem.thtml:46
+msgid "devcp_additem_step1_link"
+msgstr "Cam 1: Llwytho i Fyny"
+
+#: views/elements/developers/additem.thtml:47
+msgid "devcp_additem_step2_link"
+msgstr "Cam 2: Manylion yr Ychwanegyn"
+
+#: views/elements/developers/additem.thtml:48
+msgid "devcp_additem_step3_link"
+msgstr "Cam 3: Manylion y Fersiwn"
+
+#: views/elements/developers/additem.thtml:49
+msgid "devcp_additem_step4_link"
+msgstr "Cam 4: Lleoleiddio"
+
+#: views/elements/developers/additem.thtml:50
+msgid "devcp_additem_step5_link"
+msgstr "Cam 5: Llwyddiant"
+
+#: views/elements/developers/additem.thtml:76
+msgid "devcp_additem_submissionhelp_link"
+msgstr "Cymorth ar gyfer Cyflwyno"
+
+#: controllers/previews_controller.php:168
+#: controllers/previews_controller.php:277
+msgid "devcp_addon_field_preview_caption_displaytitle"
+msgstr "Rhagolwg o'r Pennawd"
+
+#: views/developers/addon_status.thtml:177
+#, fuzzy
+msgid "devcp_addon_status_action_activate"
+msgstr "Make Active"
+
+#: views/developers/addon_status.thtml:178
+#, fuzzy
+msgid "devcp_addon_status_action_activate_description"
+msgstr ""
+"Make your add-on active for it to show up in public listings and enable the "
+"update check service."
+
+#: views/developers/addon_status.thtml:135
+#, fuzzy
+msgid "devcp_addon_status_action_complete"
+msgstr "Complete Add-on"
+
+#: views/developers/addon_status.thtml:136
+#, fuzzy
+msgid "devcp_addon_status_action_complete_description"
+msgstr "Complete your add-on and move to the Sandbox"
+
+#: views/developers/addon_status.thtml:181
+#, fuzzy
+msgid "devcp_addon_status_action_deactivate"
+msgstr "Make Inactive"
+
+#: views/developers/addon_status.thtml:182
+#, fuzzy
+msgid "devcp_addon_status_action_deactivate_description"
+msgstr ""
+"Make your add-on inactive to hide it from all public listings and disable "
+"the update check service."
+
+#: views/developers/addon_status.thtml:143
+#, fuzzy
+msgid "devcp_addon_status_action_move"
+msgstr "Move to Sandbox"
+
+#: views/developers/addon_status.thtml:144
+#, fuzzy
+msgid "devcp_addon_status_action_move_description"
+msgstr "Move your add-on back to the Sandbox. This is reversible."
+
+#: views/developers/addon_status.thtml:139
+#, fuzzy
+msgid "devcp_addon_status_action_nominate"
+msgstr "Nominate for Public"
+
+#: views/developers/addon_status.thtml:140
+#, fuzzy
+msgid "devcp_addon_status_action_nominate_description"
+msgstr "Nominate your add-on to become Public"
+
+#: views/developers/addon_status.thtml:147
+#, fuzzy
+msgid "devcp_addon_status_action_public"
+msgstr "Make Public"
+
+#: views/developers/addon_status.thtml:148
+#, fuzzy
+msgid "devcp_addon_status_action_public_description"
+msgstr "Make your add-on Public again."
+
+#: views/developers/addon_status.thtml:169
+#, fuzzy
+msgid "devcp_addon_status_active"
+msgstr ""
+"Your add-on is <span class=\"inactive-0\">Active</span>. This means your add-"
+"on is showing up in all available listings appropriate for its status above."
+
+#: views/developers/addon_status.thtml:111
+#, fuzzy
+msgid "devcp_addon_status_completion_disabled"
+msgstr ""
+"Please fulfill the criteria above before you can complete your add-on and "
+"move it to the <span class=\"status-1\">Sandbox</span>."
+
+#: views/developers/addon_status.thtml:108
+#, fuzzy
+msgid "devcp_addon_status_completion_enabled"
+msgstr ""
+"You may now complete your add-on and move it to the <span class=\"status-1"
+"\">Sandbox</span> by clicking the button below."
+
+#: views/developers/addon_status.thtml:102
+#, fuzzy
+msgid "devcp_addon_status_criteria_category"
+msgstr "At least one category selected"
+
+#: views/developers/addon_status.thtml:101
+#, fuzzy
+msgid "devcp_addon_status_criteria_description"
+msgstr "Add-on Description required"
+
+#: views/developers/addon_status.thtml:99
+#, fuzzy
+msgid "devcp_addon_status_criteria_name"
+msgstr "Add-on Name required"
+
+#: views/developers/addon_status.thtml:120
+#, fuzzy
+msgid "devcp_addon_status_criteria_prerelease"
+msgstr "Add-on is not marked as pre-release."
+
+#: views/developers/addon_status.thtml:119
+#, fuzzy
+msgid "devcp_addon_status_criteria_preview"
+msgstr "At least one preview image required for extensions and themes."
+
+#: views/developers/addon_status.thtml:100
+#, fuzzy
+msgid "devcp_addon_status_criteria_summary"
+msgstr "Add-on Summary required"
+
+#. %s is the status in a span, e.g. "<span>_('Public')</span>".
+#: views/developers/addon_status.thtml:58
+#, fuzzy
+msgid "devcp_addon_status_header"
+msgstr "Add-on Status: %s"
+
+#: views/developers/addon_status.thtml:152
+#: views/developers/addon_status.thtml:173
+#, fuzzy
+msgid "devcp_addon_status_header_actions"
+msgstr "Available Actions"
+
+#: views/developers/addon_status.thtml:168
+#, fuzzy
+msgid "devcp_addon_status_header_active"
+msgstr "Active Status: <span class=\"inactive-0\">Active</span>"
+
+#: views/developers/addon_status.thtml:97
+#, fuzzy
+msgid "devcp_addon_status_header_criteria"
+msgstr "Add-on Completion Criteria"
+
+#: views/developers/addon_status.thtml:164
+#, fuzzy
+msgid "devcp_addon_status_header_inactive"
+msgstr "Active Status: <span class=\"inactive-1\">Inactive</span>"
+
+#: views/developers/addon_status.thtml:117
+#, fuzzy
+msgid "devcp_addon_status_header_nomination"
+msgstr "Public Nomination Criteria"
+
+#: views/developers/addon_status.thtml:190
+#, fuzzy
+msgid "devcp_addon_status_header_trusted"
+msgstr "Trusted Status: <span class=\"status-4\">Trusted</span>"
+
+#: views/developers/addon_status.thtml:165
+#, fuzzy
+msgid "devcp_addon_status_inactive"
+msgstr ""
+"Your add-on is <span class=\"inactive-1\">Inactive</span>. This means your "
+"add-on will not show up in any listing, regardless of its status above. "
+"Updates are <b>not</b> being provided to your add-on through the update "
+"check service."
+
+#: views/developers/addon_status.thtml:128
+#, fuzzy
+msgid "devcp_addon_status_nominate_disabled"
+msgstr ""
+"Please fulfill the criteria above before nominating your add-on to become "
+"<span class=\"status-4\">Public</span>."
+
+#: views/developers/addon_status.thtml:125
+#, fuzzy
+msgid "devcp_addon_status_nominate_enabled"
+msgstr ""
+"You may now nominate your add-on for <span class=\"status-4\">Public</span> "
+"by clicking the button below."
+
+#: views/developers/addon_status.thtml:64
+#, fuzzy
+msgid "devcp_addon_status_public"
+msgstr "Public"
+
+#: views/developers/addon_status.thtml:63
+#, fuzzy
+msgid "devcp_addon_status_sandbox"
+msgstr "Sandbox"
+
+#. %s is an email address.
+#: views/developers/addon_status.thtml:89
+#, fuzzy
+msgid "devcp_addon_status_switch_disabled"
+msgstr ""
+"Your add-on was <span class=\"status-5\">Disabled</span> by an administrator "
+"and cannot be used. If you have any questions, please e-mail %s."
+
+#: views/developers/addon_status.thtml:67
+#, fuzzy
+msgid "devcp_addon_status_switch_incomplete"
+msgstr ""
+"Your add-on is currently <span class=\"status-0\">Incomplete</span>. This "
+"means your add-on is not showing up on any portion of the site or update "
+"check service. You may come to this page to complete your add-on after it "
+"meets the criteria below for completion and transfer to the <span class="
+"\"status-1\">Sandbox</span>."
+
+#. %s is a number, perhaps 42.
+#: views/developers/addon_status.thtml:77
+#, fuzzy
+msgid "devcp_addon_status_switch_nominated"
+msgstr ""
+"Your add-on is currently nominated to become <span class=\"status-4"
+"\">Public</span> and is awaiting editor review. There are currently %s other "
+"add-ons in the nomination queue."
+
+#. %s is an email address.
+#: views/developers/addon_status.thtml:81
+#, fuzzy
+msgid "devcp_addon_status_switch_pending"
+msgstr ""
+"Your add-on is pending. This shouldn't have happened. Please e-mail %s with "
+"your add-on ID and state this error."
+
+#: views/developers/addon_status.thtml:85
+#, fuzzy
+msgid "devcp_addon_status_switch_public"
+msgstr ""
+"Your add-on is <span class=\"status-4\">Public</span>, which means it will "
+"show up in all listings and searches and can be downloaded without "
+"restriction. Updates are being provided to your add-on through the update "
+"check service."
+
+#: views/developers/addon_status.thtml:71
+#: views/developers/addon_status.thtml:75
+#, fuzzy
+msgid "devcp_addon_status_switch_sandbox"
+msgstr ""
+"Your add-on is in the <span class=\"status-1\">Sandbox</span>, which means "
+"it will show up in listings and searches, but users must log in to download "
+"it. Updates are <b>not</b> being provided to your add-on through the update "
+"check service."
+
+#. %s is the add-on name.
+#: views/developers/addon_status_nominate.thtml:43
+#: views/developers/addon_status_confirm.thtml:43
+#: views/developers/addon_status.thtml:43
+#, fuzzy
+msgid "devcp_addon_status_title"
+msgstr "%s Status"
+
+#: views/developers/addon_status.thtml:191
+#, fuzzy
+msgid "devcp_addon_status_trusted"
+msgstr ""
+"Your add-on is <span class=\"status-4\">Trusted</span>. This means you can "
+"submit updates to your add-on without editor review."
+
+#: views/developers/dashboard.thtml:68
+#, fuzzy
+msgid "devcp_dashboard_active"
+msgstr "Active"
+
+#. %1$s is the add-on type string
+#. %2$s is Inactive or Active in a <span>
+#. %3$s is the addon's public status (Public, In Sandbox, ...) in a <span>
+#: views/developers/dashboard.thtml:69
+#, fuzzy
+msgid "devcp_dashboard_addontype_status"
+msgstr "%1$s currenty %2$s and %3$s"
+
+#: views/developers/dashboard.thtml:67
+#, fuzzy
+msgid "devcp_dashboard_change_status"
+msgstr "Change Status"
+
+#. %s is the addons email address.
+#: views/developers/dashboard.thtml:99
+#, fuzzy
+msgid "devcp_dashboard_disabled_questions"
+msgstr ""
+"Your add-on was disabled by an administrator and cannot be used. If you "
+"have any questions, please email %s."
+
+#. %s is the (localized) add-on status string in a span, e.g. "Disabled"
+#: views/developers/dashboard.thtml:98
+#, fuzzy
+msgid "devcp_dashboard_disabled_status"
+msgstr "Add-on Status: %s"
+
+#: views/developers/dashboard.thtml:43
+#, fuzzy
+msgid "devcp_dashboard_header_main"
+msgstr "Developer Dashboard"
+
+#: views/developers/dashboard.thtml:110
+#, fuzzy
+msgid "devcp_dashboard_header_welcome"
+msgstr "Welcome to the Developer Dashboard"
+
+#: views/developers/dashboard.thtml:68
+#, fuzzy
+msgid "devcp_dashboard_inactive"
+msgstr "Inactive"
+
+#. %s is a date in the _('date') format
+#: views/developers/dashboard.thtml:65
+#, fuzzy
+msgid "devcp_dashboard_last_edited"
+msgstr "Last edited on %s"
+
+#: views/developers/dashboard.thtml:111
+#, fuzzy
+msgid "devcp_dashboard_learn"
+msgstr ""
+"You don't currently have any add-ons hosted on Mozilla Add-ons. To learn how "
+"the process works and submit your first add-on, click Get Started below."
+
+#: views/developers/dashboard.thtml:112
+#, fuzzy
+msgid "devcp_dashboard_start"
+msgstr "Get Started"
+
+#: views/developers/dashboard.thtml:82
+#, fuzzy
+msgid "devcp_dashboard_versions"
+msgstr "Versions and Files"
+
+#: views/developers/dashboard.thtml:91
+#, fuzzy
+msgid "devcp_dashboard_versions_new"
+msgstr "Upload a new version"
+
+#. %s is the preview ID number.
+#: controllers/developers_controller.php:1415
+#, fuzzy
+msgid "devcp_delete_previews_error"
+msgstr "Preview %s could not be deleted from the database. Please try again."
+
+#. %s is the preview ID number.
+#: controllers/developers_controller.php:1413
+#, fuzzy
+msgid "devcp_delete_previews_success"
+msgstr "Preview %s has been deleted successfully."
+
+#: controllers/developers_controller.php:1089
+#, fuzzy
+msgid "devcp_delete_version_priv_error"
+msgstr "You do not have privileges to delete versions or files."
+
+#. %1$s is the count of files, a number
+#. %2$s is a status string like _('Public') or _('Incomplete')
+#: controllers/components/amo.php:549
+#, fuzzy
+msgid "devcp_describe_version_status"
+msgid_plural "devcp_describe_version_status"
+msgstr[0] "%1$s %2$s file"
+msgstr[1] "%1$s %2$s files"
+
+#. %s is a version number. Example: 3.0
+#: views/developers/versions.thtml:65
+#, php-format
+msgid "devcp_details_version"
+msgstr "Fersiwn %s"
+
+#: views/developers/discuss.thtml:68
+#, fuzzy
+msgid "devcp_discuss_addreply_header"
+msgstr "Add Reply"
+
+#: views/developers/discuss.thtml:57
+#, fuzzy
+msgid "devcp_discuss_allreplies_header"
+msgstr "Replies"
+
+#. notice when an error occurs saving a discussion reply
+#. %1 is the email address (linked) for the amo-editors list
+#: views/developers/discuss.thtml:70
+#, fuzzy
+msgid "devcp_discuss_error_notice"
+msgstr ""
+"There was an error saving your reply. Please contact %1$s about the issue."
+
+#. %1 is the add-on name, %2 is the add-on's version number currently being reviewed by an editor
+#: views/developers/discuss.thtml:46
+#, fuzzy
+msgid "devcp_discuss_intro"
+msgstr ""
+"A Mozilla Add-ons Editor requested further information from you regarding "
+"version %2$s of your add-on %1$s."
+
+#. %1 is the add-on name
+#: views/developers/discuss.thtml:43
+#, fuzzy
+msgid "devcp_discuss_pagetitle"
+msgstr "Provide More Information For the Add-on Review of %1$s"
+
+#. submit button text
+#: views/developers/discuss.thtml:79
+#, fuzzy
+msgid "devcp_discuss_submit_reply"
+msgstr "Submit Reply"
+
+#: views/developers/discuss.thtml:72
+#, fuzzy
+msgid "devcp_discuss_success_message"
+msgstr ""
+"Your reply was successfully saved. The other participants of the discussion "
+"will be notified by email."
+
+#. in an author/editor discussion about an add-on to be reviewed:
+#. %1 is the commenter's user name (linked).
+#. %2 is the full date the comment was made.
+#: views/developers/discuss.thtml:52 views/developers/discuss.thtml:62
+#, fuzzy
+msgid "devcp_discuss_writtenby"
+msgstr "written by %1$s on %2$s"
+
+#: views/developers/addon_edit_authors.thtml:72
+#: views/developers/addon_edit_authors.thtml:81
+#, fuzzy
+msgid "devcp_edit_authors_add_author"
+msgstr "Add New Author"
+
+#: views/developers/addon_edit_authors.thtml:96
+#, fuzzy
+msgid "devcp_edit_authors_add_author_button"
+msgstr "Add Author"
+
+#: views/developers/addon_edit_authors.thtml:83
+#, fuzzy
+msgid "devcp_edit_authors_add_email"
+msgstr "Author Account Email:"
+
+#: views/developers/addon_edit_authors.thtml:98
+#, fuzzy
+msgid "devcp_edit_authors_add_loading"
+msgstr "Checking account email..."
+
+#: views/developers/addon_edit_authors.thtml:70
+#, fuzzy
+msgid "devcp_edit_authors_click_save"
+msgstr "Click the Update Authors button below to save."
+
+#: views/developers/addon_edit_authors.thtml:58
+#, fuzzy
+msgid "devcp_edit_authors_header_current"
+msgstr "Current Authors"
+
+#: views/developers/addon_edit_authors.thtml:50
+#, fuzzy
+msgid "devcp_edit_authors_header_manage"
+msgstr "Manage Add-on Authors"
+
+#: views/developers/addon_edit_authors.thtml:93
+#, fuzzy
+msgid "devcp_edit_authors_label_add_listed"
+msgstr "List as author in pubilc display pages"
+
+#: views/developers/addon_edit_authors.thtml:89
+#, fuzzy
+msgid "devcp_edit_authors_label_developer"
+msgstr ""
+"<strong>Developer</strong> - Can manage all aspects of the add-on listing, "
+"except for adding and removing other authors."
+
+#: views/developers/addon_edit_authors.thtml:88
+#, fuzzy
+msgid "devcp_edit_authors_label_owner"
+msgstr ""
+"<strong>Owner</strong> - Can manage all aspects of the add-on listing, "
+"including adding and removing other authors."
+
+#: views/developers/addon_edit_authors.thtml:90
+#, fuzzy
+msgid "devcp_edit_authors_label_viewer"
+msgstr ""
+"<strong>Viewer</strong> - Can view add-on developer listing and statistics, "
+"but can't make any changes."
+
+#. Placeholder for the empty option in a <select>.
+#: views/developers/addon_edit_categories.thtml:69
+#, fuzzy
+msgid "devcp_edit_authors_option_empty"
+msgstr "----------------"
+
+#: views/developers/addon_edit_authors.thtml:86
+#, fuzzy
+msgid "devcp_edit_authors_select_role"
+msgstr "Select a role for the author:"
+
+#. Column name in a table.
+#: views/developers/addon_edit_authors.thtml:62
+#, fuzzy
+msgid "devcp_edit_authors_th_author"
+msgstr "Author"
+
+#. Column name in a table.
+#: views/developers/addon_edit_authors.thtml:64
+#, fuzzy
+msgid "devcp_edit_authors_th_listed"
+msgstr "Listed"
+
+#. Column name in a table.
+#: views/developers/addon_edit_authors.thtml:63
+#, fuzzy
+msgid "devcp_edit_authors_th_role"
+msgstr "Role"
+
+#: views/developers/addon_edit_authors.thtml:77
+#, fuzzy
+msgid "devcp_edit_authors_update_author"
+msgstr "Update authors"
+
+#: views/developers/addon_edit_categories.thtml:99
+#, fuzzy
+msgid "devcp_edit_categories_button_update"
+msgstr "Update Categories"
+
+#: views/developers/addon_edit_categories.thtml:88
+#, fuzzy
+msgid "devcp_edit_categories_does_not_fit"
+msgstr "My add-on doesn't fit into any available categories."
+
+#. %s is the application name (Firefox, Thunderbird).
+#: views/developers/addon_edit_categories.thtml:61
+#, fuzzy
+msgid "devcp_edit_categories_header_application"
+msgstr "%s Categories"
+
+#: views/developers/addon_edit_categories.thtml:49
+#, fuzzy
+msgid "devcp_edit_categories_header_manage"
+msgstr "Manage Add-on Categories"
+
+#: views/developers/addon_edit_categories.thtml:91
+#, fuzzy
+msgid "devcp_edit_categories_hover"
+msgstr "Hover over a category to see its description."
+
+#. %s is the category number (1, 2, 3).
+#: views/developers/addon_edit_categories.thtml:67
+#, fuzzy
+msgid "devcp_edit_categories_label_category_num"
+msgstr "Category %s"
+
+#: views/developers/addon_edit_categories.thtml:94
+#: views/developers/addon_edit_categories.thtml:103
+#, fuzzy
+msgid "devcp_edit_categories_none_available"
+msgstr "No categories are available for this add-on type and application."
+
+#: views/developers/addon_edit_categories.thtml:86
+#, fuzzy
+msgid "devcp_edit_categories_other"
+msgstr ""
+"Place your add-on into this category only if it does not fit into any other "
+"available categories."
+
+#. %s is the application name (Firefox, Thunderbird).
+#: views/developers/addon_edit_categories.thtml:63
+#, fuzzy
+msgid "devcp_edit_categories_select_application_categories"
+msgstr "Select up to three %s categories for your add-on"
+
+#: views/developers/addon_edit.thtml:47
+#, fuzzy
+msgid "devcp_edit_dd_manage_authors"
+msgstr "Add or remove users that can manage this add-on."
+
+#: views/developers/addon_edit.thtml:49
+#, fuzzy
+msgid "devcp_edit_dd_manage_categories"
+msgstr ""
+"Select the relevant categories for each application your add-on supports."
+
+#: views/developers/addon_edit.thtml:51
+#, fuzzy
+msgid "devcp_edit_dd_manage_description"
+msgstr ""
+"Add and modify translations for your add-on's summary, description, end-user "
+"license, and privacy policy."
+
+#: views/developers/addon_edit.thtml:53
+#, fuzzy
+msgid "devcp_edit_dd_manage_properties"
+msgstr "Change your add-on's name, homepage, icon, and other flags."
+
+#: views/developers/addon_edit_descriptions.thtml:116
+#, fuzzy
+msgid "devcp_edit_description_button_update"
+msgstr "Update Descriptions"
+
+#: views/developers/addon_edit_descriptions.thtml:115
+#, fuzzy
+msgid "devcp_edit_description_correct_error"
+msgstr "Please correct the errors above indicated in red."
+
+#: views/developers/addon_edit_descriptions.thtml:51
+#, fuzzy
+msgid "devcp_edit_descriptions_header"
+msgstr "Edit Add-on Descriptions"
+
+#: views/developers/addon_edit_descriptions.thtml:94
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_comments_description"
+msgstr ""
+"Any information end users may want to know that isn't necessarily applicable "
+"to the add-on summary or description. Common uses include listing known "
+"major bugs, information on how to report bugs, anticipated release date of a "
+"new version, etc."
+
+#: views/developers/addon_edit_descriptions.thtml:93
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_comments_name"
+msgstr "Developer Comments"
+
+#: views/developers/addon_edit_descriptions.thtml:86
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_description_description"
+msgstr ""
+"The description of your add-on is a longer explanation of features, "
+"functionality, and other relevant information. It is displayed under the "
+"summary on the add-on's display page."
+
+#: views/developers/addon_edit_descriptions.thtml:85
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_description_name"
+msgstr "Add-on Description"
+
+#: views/developers/addon_edit_descriptions.thtml:103
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_eula_description"
+msgstr ""
+"If your add-on has an End-User License Agreement (EULA), please enter its "
+"text below. If set below, users will be required to agree to this before "
+"installing your add-on. Please note that a EULA is not the same as a code "
+"license such as GPL or MPL."
+
+#: views/developers/addon_edit_descriptions.thtml:102
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_eula_name"
+msgstr "End-User License Agreement"
+
+#: views/developers/addon_edit_descriptions.thtml:112
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_privacy_description"
+msgstr ""
+"If your add-on has a privacy policy, enter its text here. Your add-on's "
+"display page will display a link to the policy."
+
+#: views/developers/addon_edit_descriptions.thtml:111
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_privacy_name"
+msgstr "Privacy Policy"
+
+#: views/developers/addon_edit_descriptions.thtml:78
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_summary_description"
+msgstr ""
+"The summary is a short explanation of your add-on's basic functionality that "
+"is displayed in search and browse listings, as well as at the top of your "
+"add-on's display page. <strong>Limit of 250 characters.</strong>"
+
+#: views/developers/addon_edit_descriptions.thtml:77
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_summary_name"
+msgstr "Add-on Summary"
+
+#: views/developers/addon_edit.thtml:46
+#, fuzzy
+msgid "devcp_edit_dt_manage_authors"
+msgstr "Manage Add-on Authors"
+
+#: views/developers/addon_edit.thtml:48
+#, fuzzy
+msgid "devcp_edit_dt_manage_categories"
+msgstr "Manage Add-on Categories"
+
+#: views/developers/addon_edit.thtml:50
+#, fuzzy
+msgid "devcp_edit_dt_manage_descriptions"
+msgstr "Manage Add-on Descriptions"
+
+#: views/developers/addon_edit.thtml:52
+#, fuzzy
+msgid "devcp_edit_dt_manage_properties"
+msgstr "Manage Add-on Properties"
+
+#: views/developers/addon_edit_properties.thtml:170
+msgid "devcp_edit_label_externalsoftware"
+msgstr "Mae'r ychwanegyn angen meddalwedd allanol"
+
+#: views/developers/addon_edit_properties.thtml:205
+msgid "devcp_edit_label_locale_disambiguation"
+msgstr "Gwybodaeth Lleoliad ychwanegol"
+
+#: views/developers/addon_edit_properties.thtml:168
+msgid "devcp_edit_label_prerelease"
+msgstr "Mae hwn cyn y rhyddhad"
+
+#: views/developers/addon_edit_properties.thtml:169
+msgid "devcp_edit_label_sitespecific"
+msgstr "Mae hwn yn ychwanegyn gwefan benodol"
+
+#: views/developers/addon_edit_properties.thtml:202
+msgid "devcp_edit_label_target_locale"
+msgstr "Lleoliad Targed"
+
+#: views/developers/addon_edit_properties.thtml:212
+#, fuzzy
+msgid "devcp_edit_properties_button_update"
+msgstr "Update Properties"
+
+#: views/developers/addon_edit_properties.thtml:198
+#, fuzzy
+msgid "devcp_edit_properties_change_guid"
+msgstr "Only change if you understand all of the consequences."
+
+#: views/developers/addon_edit_properties.thtml:109
+#, fuzzy
+msgid "devcp_edit_properties_current_icon"
+msgstr "Current Icon"
+
+#: views/developers/addon_edit_properties.thtml:85
+#, fuzzy
+msgid "devcp_edit_properties_default_locale"
+msgstr ""
+"An add-on's default locale is the main locale in which translations must be "
+"present. If translations for your add-on's descriptions are unavailable in a "
+"user's selected language, they will fall back to this default locale."
+
+#: views/developers/addon_edit_properties.thtml:167
+#, fuzzy
+msgid "devcp_edit_properties_flags"
+msgstr "These flags are used to filter and classify add-ons."
+
+#: views/developers/addon_edit_properties.thtml:174
+#, fuzzy
+msgid "devcp_edit_properties_guid"
+msgstr ""
+"The GUID of your add-on is specified in its install.rdf and uniquely "
+"identifies it. You cannot change your GUID once it is listed on Mozilla Add-"
+"ons."
+
+#: views/developers/addon_edit_properties.thtml:53
+#, fuzzy
+msgid "devcp_edit_properties_header"
+msgstr "Edit Add-on Properties"
+
+#: views/developers/addon_edit_properties.thtml:186
+#, fuzzy
+msgid "devcp_edit_properties_header_addon_type"
+msgstr "Add-on Type"
+
+#: views/developers/addon_edit_properties.thtml:181
+#, fuzzy
+msgid "devcp_edit_properties_header_admin_settings"
+msgstr "Admin Settings"
+
+#: views/developers/addon_edit_properties.thtml:84
+#, fuzzy
+msgid "devcp_edit_properties_header_default_locale"
+msgstr "Default Locale"
+
+#: views/developers/addon_edit_properties.thtml:166
+#, fuzzy
+msgid "devcp_edit_properties_header_flags"
+msgstr "Add-on Flags"
+
+#: views/developers/addon_edit_properties.thtml:173
+#: views/developers/addon_edit_properties.thtml:197
+#, fuzzy
+msgid "devcp_edit_properties_header_guid"
+msgstr "Add-on GUID"
+
+#: views/developers/addon_edit_properties.thtml:104
+#, fuzzy
+msgid "devcp_edit_properties_header_icon"
+msgstr "Add-on Icon"
+
+#: views/developers/addon_edit_properties.thtml:159
+#, fuzzy
+msgid "devcp_edit_properties_header_other_settings"
+msgstr "Other Settings"
+
+#. A header on the admin page to toggle trusted status.
+#: views/developers/addon_edit_properties.thtml:182
+#, fuzzy
+msgid "devcp_edit_properties_header_trusted"
+msgstr "Trusted Add-on?"
+
+#: views/developers/addon_edit_properties.thtml:160
+#, fuzzy
+msgid "devcp_edit_properties_header_view_source"
+msgstr "View Source Online"
+
+#. %s is a comma-separated list of image extensions ".png, .jpg"
+#: views/developers/addon_edit_properties.thtml:106
+#, fuzzy
+msgid "devcp_edit_properties_icon"
+msgstr ""
+"The add-on icon is a small image that is displayed next to your add-on's "
+"name in browse and search results, display pages, and in the add-on "
+"installation dialog. The image will automatically be resized to 32 x 32 "
+"pixels. Please use one of the following image types: %s"
+
+#: views/developers/addon_edit_properties.thtml:171
+#, fuzzy
+msgid "devcp_edit_properties_label_binary"
+msgstr "This add-on contains binary components"
+
+#: views/developers/addon_edit_properties.thtml:185
+#, fuzzy
+msgid "devcp_edit_properties_label_not_trusted"
+msgstr "Not Trusted"
+
+#: views/developers/addon_edit_properties.thtml:184
+#, fuzzy
+msgid "devcp_edit_properties_label_trusted"
+msgstr "Trusted"
+
+#: views/developers/addon_edit_properties.thtml:110
+#, fuzzy
+msgid "devcp_edit_properties_new_icon"
+msgstr "New Icon"
+
+#: views/developers/addon_edit_properties.thtml:118
+#, fuzzy
+msgid "devcp_edit_properties_remove_icon"
+msgstr "Remove Icon"
+
+#: views/developers/addon_edit_properties.thtml:136
+#, fuzzy
+msgid "devcp_edit_properties_transbox_homepage_description"
+msgstr ""
+"If your add-on has another homepage, enter its address here. Adding other "
+"translations is not necessary unless your website is localized into other "
+"languages."
+
+#: views/developers/addon_edit_properties.thtml:135
+#, fuzzy
+msgid "devcp_edit_properties_transbox_homepage_name"
+msgstr "Add-on Homepage"
+
+#: views/developers/addon_edit_properties.thtml:79
+#, fuzzy
+msgid "devcp_edit_properties_transbox_name_description"
+msgstr "The name of your add-on is displayed everywhere your add-on is listed."
+
+#: views/developers/addon_edit_properties.thtml:78
+#, fuzzy
+msgid "devcp_edit_properties_transbox_name_name"
+msgstr "Add-on Name"
+
+#: views/developers/addon_edit_properties.thtml:145
+#, fuzzy
+msgid "devcp_edit_properties_transbox_supportemail_description"
+msgstr ""
+"If you have an email address for support inquiries, enter it here. Adding "
+"other translations is not necessary unless you have different email "
+"addresses for different languages."
+
+#: views/developers/addon_edit_properties.thtml:144
+#, fuzzy
+msgid "devcp_edit_properties_transbox_supportemail_name"
+msgstr "Support Email Address"
+
+#: views/developers/addon_edit_properties.thtml:154
+#, fuzzy
+msgid "devcp_edit_properties_transbox_supporturl_description"
+msgstr ""
+"If your add-on has a support website or forum, enter its address here. "
+"Adding other translations is not necessary unless your website is localized "
+"into other languages."
+
+#: views/developers/addon_edit_properties.thtml:153
+#, fuzzy
+msgid "devcp_edit_properties_transbox_supporturl_name"
+msgstr "Support Website"
+
+#: views/developers/addon_edit_properties.thtml:183
+#, fuzzy
+msgid "devcp_edit_properties_trusted"
+msgstr "Trusted add-ons can become public without Editor review."
+
+#. %s is href="..." and should stay in the <a> tag.
+#: views/developers/addon_edit_properties.thtml:119
+#, fuzzy
+msgid "devcp_edit_properties_undelete"
+msgstr "Icon will be deleted on save. <a %s>Cancel?</a>"
+
+#: views/developers/addon_edit_properties.thtml:161
+#, fuzzy
+msgid "devcp_edit_properties_view_source"
+msgstr ""
+"The source of your add-on files can be viewed online by any logged in user "
+"if you wish."
+
+#: views/developers/addon_edit_properties.thtml:162
+#, fuzzy
+msgid "devcp_edit_properties_view_source_allow"
+msgstr "Allow online source viewing"
+
+#: views/developers/addon_edit_properties.thtml:163
+#, fuzzy
+msgid "devcp_edit_properties_view_source_do_not_allow"
+msgstr "Do not allow online source viewing"
+
+#: views/elements/developers/editbox.thtml:46
+#, fuzzy
+msgid "devcp_editbox_authors"
+msgstr "Authors"
+
+#: views/elements/developers/editbox.thtml:47
+#, fuzzy
+msgid "devcp_editbox_categories"
+msgstr "Categories"
+
+#: views/elements/developers/editbox.thtml:52
+#, fuzzy
+msgid "devcp_editbox_change_status"
+msgstr "Change Status"
+
+#: views/elements/developers/editbox.thtml:48
+#, fuzzy
+msgid "devcp_editbox_descriptions"
+msgstr "Descriptions"
+
+#: views/elements/developers/editbox.thtml:43
+#, fuzzy
+msgid "devcp_editbox_edit_addon"
+msgstr "Edit Add-on"
+
+#: views/elements/developers/editbox.thtml:57
+#, fuzzy
+msgid "devcp_editbox_new_version"
+msgstr "New Version"
+
+#: views/elements/developers/editbox.thtml:49
+#, fuzzy
+msgid "devcp_editbox_properties"
+msgstr "Properties"
+
+#: views/elements/developers/editbox.thtml:60
+#, fuzzy
+msgid "devcp_editbox_screenshots"
+msgstr "Preview Screenshots"
+
+#: views/elements/developers/editbox.thtml:53
+#, fuzzy
+msgid "devcp_editbox_statistics_dashboard"
+msgstr "Statistics Dashboard"
+
+#: views/elements/developers/editbox.thtml:54
+#, fuzzy
+msgid "devcp_editbox_versions"
+msgstr "Versions and Files"
+
+#: views/elements/developers/editbox.thtml:42
+#, fuzzy
+msgid "devcp_editbox_view_listing"
+msgstr "View Listing"
+
+#: views/elements/developers/editorsmenu.thtml:59
+msgid "devcp_editorsqueue_featured"
+msgstr "Cyflwyno Ychwanegion "
+
+#. %1 is the review count
+#: views/elements/developers/editorsqueue.thtml:42
+#: views/elements/developers/editorsmenu.thtml:56
+#, php-format
+msgid "devcp_editorsqueue_moderatedreviews"
+msgid_plural "devcp_editorsqueue_moderatedreviews"
+msgstr[0] "Adolygiad wedi ei Gymedroli (%s)"
+msgstr[1] "Adolygiadau wedi eu Cymedroli (%s)"
+
+#. %1 is the nominated addons count
+#: views/elements/developers/editorsqueue.thtml:44
+#: views/elements/developers/editorsmenu.thtml:58
+#, php-format
+msgid "devcp_editorsqueue_nominated"
+msgid_plural "devcp_editorsqueue_nominated"
+msgstr[0] "Ychwanegyn Enwebedig (%s)"
+msgstr[1] "Ychwanegion Enwebedig (%s)"
+
+#. %1 is the update count
+#: views/elements/developers/editorsqueue.thtml:43
+#: views/elements/developers/editorsmenu.thtml:57
+#, php-format
+msgid "devcp_editorsqueue_pendingupdates"
+msgid_plural "devcp_editorsqueue_pendingupdates"
+msgstr[0] "Diweddariad yn Disgwyl (%s)"
+msgstr[1] "Diweddariadau'n Disgwyl (%s)"
+
+#: controllers/statistics_controller.php:147
+#: controllers/statistics_controller.php:361
+#: controllers/previews_controller.php:108
+#: controllers/previews_controller.php:211
+#: controllers/previews_controller.php:312
+msgid "devcp_error_addon_access_denied"
+msgstr "Nid oes gen ti fynediad at yr ychwanegyn hwn."
+
+#. %s is a complete URL with the text from devcp_error_appversion_reference_link_text
+#. in the <a> tag. This should be fixed.
+#: controllers/components/developers.php:591
+#, php-format
+msgid "devcp_error_appversion_reference_link"
+msgstr "Gwel %s am gyfeirnod"
+
+#. This is the link text in the <a> for devcp_error_appversion_reference_link. This
+#. should be fixed.
+#: controllers/components/developers.php:591
+msgid "devcp_error_appversion_reference_link_text"
+msgstr "yn y dudalen"
+
+#: views/developers/addon_edit_authors.thtml:76
+#, fuzzy
+msgid "devcp_error_empty_authors"
+msgstr "Your add-on must have at least one owner."
+
+#. %1$s is the name of the file
+#: controllers/components/developers.php:658
+#, fuzzy
+msgid "devcp_error_file_exists"
+msgstr ""
+"A version of that addon already exists. To replace it, you must delete the "
+"file %1$s first."
+
+#. %1$s is a file extension. Example: .exe
+#. %2$s is a comma separated list of extensions. Example: .xpi, .jar
+#: controllers/components/developers.php:355
+#, php-format
+msgid "devcp_error_file_extension"
+msgstr ""
+"Nid yw'r estyniad ffeil yma (%s) i'w ddefnyddio ar gyfer y math yma o "
+"ychwanegyn. Defnyddia'r canlynol: %s"
+
+#: controllers/components/developers.php:64
+msgid "devcp_error_five_categories"
+msgstr "Dewisa llai na phum categori"
+
+#: controllers/components/developers.php:526
+msgid "devcp_error_guid_application"
+msgstr ""
+"Mae dynodiad yr ychwanegiad eisoes yn cael ei ddefnyddio gan y rhaglen."
+
+#: controllers/components/developers.php:337
+#: controllers/components/developers.php:389
+msgid "devcp_error_http_incomplete"
+msgstr "Trosglwyddiad anghyflawn"
+
+#: controllers/components/developers.php:335
+#: controllers/components/developers.php:336
+#: controllers/components/developers.php:387
+#: controllers/components/developers.php:388
+msgid "devcp_error_http_maxupload"
+msgstr "Mae'n fwy na'r maint llwytho i fyny"
+
+#: controllers/components/developers.php:338
+#: controllers/components/developers.php:390
+msgid "devcp_error_http_nofile"
+msgstr "Heb llwytho ffeil i fyny"
+
+#. %1$s is a file extension. Example: .exe
+#. %2$s is a comma separated list of extensions. Example: .xpi, .jar
+#: controllers/components/developers.php:401
+#, php-format
+msgid "devcp_error_icon_extension"
+msgstr ""
+"Nid yw'r estyniad ffeil yma (%s) i'w ddefnyddio ar gyfer eicon. Defnyddia'r "
+"canlynol: %s"
+
+#: controllers/developers_controller.php:504
+msgid "devcp_error_index_rdf_notfound"
+msgstr "Dim install.rdf ar gael."
+
+#: controllers/components/developers.php:601
+msgid "devcp_error_install_manifest"
+msgstr "Roedd y gwallau canlynol yn yr install.rdf:"
+
+#: controllers/developers_controller.php:1463
+msgid "devcp_error_invalid_addontype"
+msgstr "Dewisa math o ychwanegyn dilys"
+
+#. %$1s is a version. Example: 3.1.1
+#. %$2s is an add-on name.
+#: controllers/components/developers.php:569
+#: controllers/components/developers.php:581
+#, php-format
+msgid "devcp_error_invalid_appversion"
+msgstr "Nid yw %s yn fersiwn dilys o %s"
+
+#. %s is a string
+#: controllers/components/developers.php:521
+#, php-format
+msgid "devcp_error_invalid_guid"
+msgstr "Nid yw dynodiad yr ychwanegyn yn ddilys: %s"
+
+#. %$1s is a version. Example: 3.1.1
+#. %$2s is an add-on name.
+#: controllers/components/developers.php:572
+#, php-format
+msgid "devcp_error_invalid_minversion"
+msgstr ""
+"Nid yw %s yn fersiwn dilys o %s: nid yw fersiynau llai yn gallu cynnwys *"
+
+#: controllers/components/developers.php:536
+msgid "devcp_error_invalid_version"
+msgstr ""
+"Mae'r fersiwn yma o'r ychwanegyn yn annilys, gw.<a href=\"http://developer."
+"mozilla.org/en/docs/Toolkit_version_format\">y fanyleb</a>"
+
+#: controllers/components/developers.php:531
+msgid "devcp_error_invalid_version_spaces"
+msgstr ""
+"Mae'r fersiwn yma o'r ychwanegyn yn annilys: nid oes modd i fersiynau "
+"gynnwys bylchau."
+
+#. %s is an error message from the parser.
+#: controllers/components/developers.php:501
+#, php-format
+msgid "devcp_error_manifest_parse"
+msgstr "Digwyddodd y gwall canlynol wrth ddidoli install.rdf: %s"
+
+#: controllers/components/developers.php:373
+msgid "devcp_error_move_file"
+msgstr "Methu symud y ffeil"
+
+#. %s is the name of a file
+#: controllers/components/developers.php:650
+#: controllers/components/developers.php:662
+#: controllers/components/developers.php:667
+#: controllers/components/developers.php:727
+#: controllers/components/developers.php:738
+#: controllers/components/developers.php:743
+#, php-format
+msgid "devcp_error_moving_file"
+msgstr "Digwyddodd gwall wrth symud %s."
+
+#: controllers/components/developers.php:595
+msgid "devcp_error_mozilla_application"
+msgstr "Rhaid cael o leiaf un rhaglen targed Mozilla dilys."
+
+#: controllers/components/developers.php:516
+msgid "devcp_error_no_guid"
+msgstr "Nid oed modd canfod dynodiad ar gyfer yr ychwanegyn ar install.rdf."
+
+#: controllers/components/developers.php:287
+msgid "devcp_error_no_platform"
+msgstr "Heb ddewis platfform"
+
+#: controllers/components/developers.php:59
+msgid "devcp_error_one_category"
+msgstr "Dewis o leiaf un categori"
+
+#: controllers/components/developers.php:92
+msgid "devcp_error_one_user"
+msgstr "Rhaid bod o leiaf un awdur ar gyfer yr ychwanegyn."
+
+#. %1$s is a file extension. Example: .exe
+#. %2$s is a comma separated list of extensions. Example: .xpi, .jar
+#: controllers/components/developers.php:1081
+#, php-format
+msgid "devcp_error_preview_extension"
+msgstr ""
+"Nid oes modd defnyddio'r estyniad ffeil (%s) ar gyfer yr estyniad ar gyfer "
+"rhagolwg. Defnyddio un o'r canlynol: %s"
+
+#: controllers/components/developers.php:511
+msgid "devcp_error_updatekey"
+msgstr ""
+"Nid oes modd i ychwanegyn ddefnyddio updateKey. Tynna hwn o'r ffeil install."
+"rdf a cheisio eto."
+
+#: controllers/components/developers.php:506
+msgid "devcp_error_updateurl"
+msgstr ""
+"Nid oes modd i ychwanegyn ddefnyddio updateURL allanol. Tynna hwn o'r ffeil "
+"install.rdf a cheisio eto."
+
+#: controllers/developers_controller.php:465
+#: controllers/components/developers.php:271
+msgid "devcp_error_upload_file"
+msgstr "Llwytha ffeil i fyny."
+
+#: views/developers/uploader.thtml:135
+#, fuzzy
+msgid "devcp_input_upload_file"
+msgstr "Upload File"
+
+#: views/pages/js_constants.js.thtml:89
+#, fuzzy
+msgid "devcp_js_a_cancel"
+msgstr "Cancel"
+
+#: views/pages/js_constants.js.thtml:90
+#, fuzzy
+msgid "devcp_js_add_email"
+msgstr "Please enter the account email of the author you wish to add."
+
+#. alt text for a down-arrow image.
+#: views/pages/js_constants.js.thtml:81
+#, fuzzy
+msgid "devcp_js_img_move_down"
+msgstr "Move Down"
+
+#. alt text for an up-arrow image.
+#: views/pages/js_constants.js.thtml:82
+#, fuzzy
+msgid "devcp_js_img_move_up"
+msgstr "Move Up"
+
+#: views/pages/js_constants.js.thtml:91
+#, fuzzy
+msgid "devcp_js_img_remove_compat"
+msgstr "Remove Application Compatibility"
+
+#: views/pages/js_constants.js.thtml:86
+#, fuzzy
+msgid "devcp_js_input_list_author"
+msgstr "List as author in public listings"
+
+#: views/pages/js_constants.js.thtml:92
+#, fuzzy
+msgid "devcp_js_license_select"
+msgstr "Please select a license."
+
+#: views/pages/js_constants.js.thtml:93
+#, fuzzy
+msgid "devcp_js_license_text"
+msgstr "Please enter text for your license."
+
+#. <option> text in a <select> for Author role in an add-on.
+#: views/pages/js_constants.js.thtml:84
+#, fuzzy
+msgid "devcp_js_option_developer"
+msgstr "Developer"
+
+#. <option> text in a <select> for Author role in an add-on.
+#: views/pages/js_constants.js.thtml:83
+#, fuzzy
+msgid "devcp_js_option_owner"
+msgstr "Owner"
+
+#. <option> text in a <select> for Author role in an add-on.
+#: views/pages/js_constants.js.thtml:85
+#, fuzzy
+msgid "devcp_js_option_viewer"
+msgstr "Viewer"
+
+#: views/pages/js_constants.js.thtml:88
+#, fuzzy
+msgid "devcp_js_remove_author"
+msgstr "Remove Author"
+
+#: views/pages/js_constants.js.thtml:87
+#, fuzzy
+msgid "devcp_js_sure_remove"
+msgstr "Are you <strong>sure</strong> you wish to remove this author?"
+
+#: views/pages/js_constants.js.thtml:77
+#, fuzzy
+msgid "devcp_js_upload_alert"
+msgstr "You must select a file to upload."
+
+#. %1$s is an addon id, like 32.
+#. %2$s is a version number, like 3.5.
+#: controllers/components/developers.php:1212
+#, fuzzy
+msgid "devcp_license_existing"
+msgstr "Custom license for add-on %1$s v%2$s"
+
+#: views/elements/developers/localebox.thtml:44
+msgid "devcp_localebox_header_localizedfields"
+msgstr "Meysydd Lleoleiddiwyd"
+
+#. %1 is the default locale
+#: views/elements/developers/localebox.thtml:48
+#, php-format
+msgid "devcp_localebox_intro"
+msgstr ""
+"Mae rhai meysydd ar y dudalen hon wedi eu lleoleiddio er mwyn ymddangos yn "
+"iaith frodorol y defnyddiwr. Dewiswch leoliad isod i olygu manylion dy "
+"ychwanegyn yn yr iaith honno. Os nad oes cyfieithiad ar gael ar gyfer y "
+"lleoliad, bydd yn ddibynnol ar y lleoliad cynhenid (%s)."
+
+#: views/elements/developers/sidebar.thtml:68
+#: views/elements/developers/myaddons.thtml:75
+msgid "devcp_myaddons_admincp_link"
+msgstr "Offer Gweinyddol"
+
+#: views/elements/developers/sidebar.thtml:65
+#: views/elements/developers/myaddons.thtml:72
+msgid "devcp_myaddons_editorcp_link"
+msgstr "Offer Golygu"
+
+#: views/elements/developers/myaddons.thtml:52
+msgid "devcp_myaddons_link"
+msgstr "Fy Ychwanegion"
+
+#: views/elements/developers/sidebar.thtml:70
+#: views/elements/developers/myaddons.thtml:77
+msgid "devcp_myaddons_mainpage_link"
+msgstr "Nôl i'r Brif Dudalen"
+
+#: views/elements/developers/sidebar.thtml:63
+#: views/elements/developers/myaddons.thtml:70
+msgid "devcp_myaddons_statistics_link"
+msgstr "Bwrdd Data Ystadegau"
+
+#: views/elements/developers/sidebar.thtml:62
+#: views/elements/developers/myaddons.thtml:69
+msgid "devcp_myaddons_submitaddon_link"
+msgstr "Cyflwyno'r Ychwanegyn"
+
+#: views/elements/developers/sidebar.thtml:48
+#: views/elements/developers/myaddons.thtml:67
+msgid "devcp_myaddons_title"
+msgstr "Offer Datblygwr"
+
+#. %1$s is an add-on ID, perhaps 167.
+#. %2$s is a URL.
+#: controllers/developers_controller.php:256
+#, fuzzy
+msgid "devcp_new_addon_error"
+msgstr ""
+"This add-on ID (%1$s) already exists in the database. If this is your add-"
+"on, you can <a href=\"%2$s\">upload a new version</a>."
+
+#: views/developers/addon_status_nominate.thtml:62
+#, fuzzy
+msgid "devcp_nominate_cancel"
+msgstr "Cancel and return"
+
+#. %1 is the add-on name
+#: views/developers/addon_status_nominate.thtml:61
+#, php-format
+msgid "devcp_nominate_submit_nominate"
+msgstr "Enwebu %s"
+
+#: views/developers/addon_edit_properties.thtml:50
+#: views/developers/addon_status.thtml:49
+#: views/developers/versions_edit.thtml:50
+#, fuzzy
+msgid "devcp_notice_changes_error"
+msgstr ""
+"<span>One or more of your changes couldn't be saved.</span><br />Please look "
+"for the errors below. The rest of your changes were successfully saved."
+
+#: views/developers/addon_edit_authors.thtml:47
+#: views/developers/addon_edit_properties.thtml:47
+#: views/developers/addon_status.thtml:46
+#: views/developers/addon_edit_descriptions.thtml:47
+#: views/developers/versions_edit.thtml:47
+#: views/developers/addon_edit_categories.thtml:46
+#, fuzzy
+msgid "devcp_notice_changes_saved"
+msgstr ""
+"<span>Your changes have been saved.</span><br />Please note that some "
+"changes may take several hours to appear in all areas of the website."
+
+#: controllers/previews_controller.php:252
+msgid "devcp_notice_cleardefault"
+msgstr ""
+"Bydd tynnu hwn fel rhagolwg rhagosodedig yn achosi i ragolwg arall i ddod yn "
+"rhagolwg rhagosodedig yn awtomatig."
+
+#: controllers/previews_controller.php:184
+#: controllers/previews_controller.php:251
+msgid "devcp_notice_makedefault"
+msgstr ""
+"Bydd gwneud hyn yn rhagolwg rhagosodedig yn tynnu statws rhagosodedig o'r "
+"rhagolwg rhagosodedig presennol."
+
+#: views/developers/addon_edit_authors.thtml:70
+#, fuzzy
+msgid "devcp_notice_unsaved_changes"
+msgstr "You have unsaved changes."
+
+#: controllers/developers_controller.php:87
+#: controllers/developers_controller.php:97
+#: controllers/developers_controller.php:100
+#: controllers/previews_controller.php:67
+#: controllers/previews_controller.php:79
+#: controllers/previews_controller.php:82
+msgid "devcp_pagetitle"
+msgstr "Offer Datblygwr"
+
+#: controllers/previews_controller.php:103
+#: controllers/previews_controller.php:104
+msgid "devcp_preview_add_pagetitle"
+msgstr "Ychwanegu Rhagolwg"
+
+#: controllers/previews_controller.php:135
+msgid "devcp_preview_added_successfully"
+msgstr "Rhagolwg wedi ei ychwanegu'n llwyddiannus."
+
+#: controllers/previews_controller.php:323
+msgid "devcp_preview_deleted_successfully"
+msgstr "Rhagolwg wedi ei ddikeu'n llwyddiannus."
+
+#: controllers/previews_controller.php:194
+#: controllers/previews_controller.php:195
+msgid "devcp_preview_edit_pagetitle"
+msgstr "Golygu'r Rhagolwg"
+
+#: controllers/previews_controller.php:237
+msgid "devcp_preview_updated_successfully"
+msgstr "Mae'r rhagolwg wedi ei ddiweddaru'n llwyddiannus."
+
+#: views/developers/previews.thtml:120
+#, fuzzy
+msgid "devcp_previews_a_another"
+msgstr "Add Another Preview"
+
+#: views/developers/previews.thtml:96
+#, fuzzy
+msgid "devcp_previews_a_delete"
+msgstr "Delete Preview"
+
+#: views/developers/previews.thtml:95
+#, fuzzy
+msgid "devcp_previews_a_replace"
+msgstr "Replace Preview"
+
+#: views/developers/previews.thtml:126
+#, fuzzy
+msgid "devcp_previews_a_update"
+msgstr "Update Previews"
+
+#: views/developers/previews.thtml:115 views/developers/previews.thtml:124
+#, fuzzy
+msgid "devcp_previews_add_new"
+msgstr "Add New Preview"
+
+#. %s is a list of file extensions, e.g. ".png, .gif"
+#: views/developers/previews.thtml:116
+#, fuzzy
+msgid "devcp_previews_add_select"
+msgstr ""
+"Select an image to upload below. Images larger than the maximum size of 700 "
+"pixels wide by 525 pixels tall will be resized. Allowed file types: %s"
+
+#: views/developers/previews.thtml:121
+#, fuzzy
+msgid "devcp_previews_click_below"
+msgstr "Click Update Previews below to upload."
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/previews.thtml:102
+#, fuzzy
+msgid "devcp_previews_click_update"
+msgstr ""
+"Click the Update Previews button below to save this image. (<a %s>Cancel?</"
+"a>)"
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/previews.thtml:107
+#, fuzzy
+msgid "devcp_previews_error_message"
+msgstr ""
+"This preview will be deleted when Update Previews is clicked below. (<a %"
+"s>Cancel?</a>)"
+
+#: views/previews/add.thtml:45
+msgid "devcp_previews_filetype_info"
+msgstr ""
+"Defnyddia'r ffurflen isod i lwytho llun sgrin PNG, JPG, neu GIF o dy "
+"ychwanegyn. Bydd delweddau mwy na 700 picsel o led a 525 picsel o uchder yn "
+"cael eu maint wedi ei addasu'n awtomatig."
+
+#: views/previews/add.thtml:43
+msgid "devcp_previews_header_add"
+msgstr "Ychwanegu Rhagolwg"
+
+#: views/developers/previews.thtml:80
+#, fuzzy
+msgid "devcp_previews_header_caption"
+msgstr "Preview Caption"
+
+#: views/previews/edit.thtml:43
+msgid "devcp_previews_header_edit"
+msgstr "Golygu Rhagolwg"
+
+#: views/developers/previews.thtml:93
+#, fuzzy
+msgid "devcp_previews_label_default"
+msgstr "Default Preview"
+
+#: views/previews/add.thtml:54
+msgid "devcp_previews_label_file"
+msgstr "Rhagolwg Ffeil"
+
+#: views/previews/add.thtml:59 views/previews/edit.thtml:50
+msgid "devcp_previews_label_makedefault"
+msgstr "Gwneud hyn yn ddelwedd rhagosodedig"
+
+#: views/developers/previews.thtml:100
+#, fuzzy
+msgid "devcp_previews_label_new"
+msgstr "New image:"
+
+#: views/developers/previews.thtml:118
+#, fuzzy
+msgid "devcp_previews_label_upload"
+msgstr "Upload Preview: "
+
+#: views/developers/previews.thtml:50
+#, fuzzy
+msgid "devcp_previews_notice_error"
+msgstr "One or more of your new previews could not be saved."
+
+#: views/developers/previews.thtml:47
+#, fuzzy
+msgid "devcp_previews_notice_success"
+msgstr "Your previews have been updated successfully."
+
+#: views/developers/previews.thtml:59
+#, fuzzy
+msgid "devcp_previews_p_screenshots"
+msgstr ""
+"The preview screenshots for your add-on are shown below. You can make "
+"changes to captions or images below. The Default Preview is the preview that "
+"is displayed next to your add-on in search and browse listings."
+
+#: views/previews/edit.thtml:55
+msgid "devcp_previews_submit_delete"
+msgstr "Dileu'r Rhagolwg"
+
+#: views/previews/edit.thtml:55
+msgid "devcp_previews_submit_delete_confirm"
+msgstr "Wyt ti'n siŵr dy fod am ddileu'r rhagolwg?"
+
+#: views/previews/edit.thtml:54
+msgid "devcp_previews_submit_edit"
+msgstr "Golygu'r Rhagolwg"
+
+#: views/previews/add.thtml:63
+msgid "devcp_previews_submit_upload"
+msgstr "Llwytho'r Rhagolwg"
+
+#: views/developers/previews.thtml:78
+#, fuzzy
+msgid "devcp_previews_thumbnail"
+msgstr "Thumbnail"
+
+#. %s is the add-on name.
+#: views/developers/previews.thtml:44
+#, fuzzy
+msgid "devcp_previews_title"
+msgstr "%s Preview Manager"
+
+#: views/developers/uploader.thtml:74
+msgid "devcp_review_agreement_please"
+msgstr "Darllena'r adolygiad a derbyn y Cytundeb Datblygu cyn mynd ymhellach"
+
+#: views/elements/developers/rolecheck.thtml:42
+#, fuzzy
+msgid "devcp_rolecheck_no_privs"
+msgstr ""
+"<span>You do not have sufficient privileges to make changes on this page.</"
+"span><br />Contact the Add-on Owner if you need to make changes."
+
+#: controllers/developers_controller.php:1315
+#, fuzzy
+msgid "devcp_several_hours"
+msgstr ""
+"Please note that some changes may take several hours to appear in all areas "
+"of the website."
+
+#: views/elements/developers/sidebar.thtml:52
+#, fuzzy
+msgid "devcp_sidebar_a_dashboard"
+msgstr "Dashboard"
+
+#. %s is a number
+#: views/elements/developers/statsbar.thtml:45
+#: views/developers/dashboard.thtml:79
+#, php-format
+msgid "devcp_statsbar_adu"
+msgstr "<em>%s</em> Defnyddiwr Dyddiol Gweithredol"
+
+#. %s is a number
+#: views/elements/developers/statsbar.thtml:41
+#: views/developers/dashboard.thtml:75
+#, php-format
+msgid "devcp_statsbar_total_downloads"
+msgstr "<em>%s</em> Cyfanswm Llwytho i Lawr"
+
+#. %s is a number
+#: views/elements/developers/statsbar.thtml:43
+#: views/developers/dashboard.thtml:77
+#, php-format
+msgid "devcp_statsbar_weekly_downloads"
+msgstr "<em>%s</em> Llwytho i Lawr Wythnosol"
+
+#: views/developers/addon_status_confirm.thtml:59
+#, fuzzy
+msgid "devcp_status_confirm_active"
+msgstr ""
+"Marking this add-on active will cause it to show up in public areas "
+"appropriate for its status, including search and browse listings. It will be "
+"downloadable from the website and could be returned in client update checks, "
+"depending on its status. You will be able to return here and disable it "
+"again at your convenience."
+
+#: views/developers/addon_status_confirm.thtml:59
+#, fuzzy
+msgid "devcp_status_confirm_active_sure"
+msgstr "Are you sure you wish to mark this add-on active?"
+
+#: views/developers/addon_status_confirm.thtml:50
+#, fuzzy
+msgid "devcp_status_confirm_header_sure"
+msgstr "Are you sure?"
+
+#: views/developers/addon_status_confirm.thtml:55
+#, fuzzy
+msgid "devcp_status_confirm_inactive"
+msgstr ""
+"Marking this add-on inactive will prevent it from showing up in any public "
+"areas, including search and browse listings. It will not be downloadable "
+"from the website and will not be returned in client update checks. You will "
+"be able to return here and re-enable it at your convenience."
+
+#: views/developers/addon_status_confirm.thtml:55
+#, fuzzy
+msgid "devcp_status_confirm_inactive_sure"
+msgstr "Are you sure you wish to mark this add-on inactive?'"
+
+#: views/developers/addon_status_confirm.thtml:74
+#, fuzzy
+msgid "devcp_status_confirm_no"
+msgstr "No, cancel"
+
+#: views/developers/addon_status_confirm.thtml:67
+#, fuzzy
+msgid "devcp_status_confirm_public"
+msgstr ""
+"Making this add-on public will make it available for anyone to download and "
+"will begin offering updates to existing users."
+
+#: views/developers/addon_status_confirm.thtml:67
+#, fuzzy
+msgid "devcp_status_confirm_public_sure"
+msgstr "Are you sure you wish to make this add-on public?"
+
+#: views/developers/addon_status_confirm.thtml:63
+#, fuzzy
+msgid "devcp_status_confirm_sandbox"
+msgstr ""
+"Moving this add-on back to the sandbox will require users to login before "
+"downloading and updates will no longer be offered to existing users. Because "
+"your add-on is currently public, you will be able to return here at any time "
+"to make it public again."
+
+#: views/developers/addon_status_confirm.thtml:63
+#, fuzzy
+msgid "devcp_status_confirm_sandbox_sure"
+msgstr "Are you sure you wish to move this add-on to the sandbox?"
+
+#: views/developers/addon_status_confirm.thtml:73
+#, fuzzy
+msgid "devcp_status_confirm_yes"
+msgstr "Yes, I'm Sure"
+
+#: views/developers/addon_status_nominate.thtml:46
+#, fuzzy
+msgid "devcp_status_nominate_error_notice"
+msgstr ""
+"<span>A nomination message is required.</span><br />Please fill in the text "
+"box with the requested information and try again."
+
+#: views/developers/addon_status_nominate.thtml:55
+#, fuzzy
+msgid "devcp_status_nominate_header"
+msgstr "Add-on Nomination"
+
+#: views/developers/dashboard.thtml:85
+msgid "devcp_summary_lastversion"
+msgstr "Fersiwn Diweddaraf:"
+
+#. %s is the add-on name.
+#: views/developers/addon_edit.thtml:43
+#: views/developers/addon_edit_authors.thtml:44
+#: views/developers/versions_delete.thtml:43
+#: views/developers/addon_edit_properties.thtml:44
+#: views/developers/addon_edit_descriptions.thtml:44
+#: views/developers/versions_edit.thtml:44
+#: views/developers/addon_edit_categories.thtml:43
+#: views/developers/versions.thtml:43
+#, fuzzy
+msgid "devcp_title_edit_addon"
+msgstr "Edit %s"
+
+#. title attribute for a javascript link that pops up a help dialog.
+#: views/elements/translationbox.thtml:68
+#, fuzzy
+msgid "devcp_transbox_a_title_help"
+msgstr "Help (does not leave page)"
+
+#: views/elements/translationbox.thtml:68
+#, fuzzy
+msgid "devcp_transbox_alt_help"
+msgstr "Help"
+
+#. %1$s is <span>17</span>, %2$s is 42.
+#: views/elements/translationbox.thtml:101
+#, fuzzy
+msgid "devcp_transbox_chars_used"
+msgstr "Characters used: %1$s / %2$s"
+
+#: views/elements/translationbox.thtml:132
+#, fuzzy
+msgid "devcp_transbox_delete_sure"
+msgstr "Are you sure you wish to delete this translation?"
+
+#. %s is a locale, like en-US.
+#: views/elements/translationbox.thtml:143
+#, fuzzy
+msgid "devcp_transbox_help_header_tabs"
+msgstr "What are these %s tabs?"
+
+#: views/elements/translationbox.thtml:145
+#, fuzzy
+msgid "devcp_transbox_help_header_what"
+msgstr "What if I don't have any translations?"
+
+#: views/elements/translationbox.thtml:147
+#, fuzzy
+msgid "devcp_transbox_help_hide"
+msgstr "Hide Help"
+
+#: views/elements/translationbox.thtml:146
+#, fuzzy
+msgid "devcp_transbox_help_if"
+msgstr ""
+"If a user browses the site and a translation isn't available in their own "
+"language, it will fall back to your add-on's Default Locale, specified in "
+"the Edit Add-on Properties area. If you don't have any translations, just "
+"enter what you can into your Default Locale, which should be a language you "
+"speak."
+
+#: views/elements/translationbox.thtml:144
+#, fuzzy
+msgid "devcp_transbox_help_transbox"
+msgstr ""
+"This is a <i>Translation Box</i>. It allows you to localize a specific field "
+"into any other languages for which you might have a translation. You can "
+"add, edit, and remove translations using the locale tabs."
+
+#: views/elements/translationbox.thtml:85
+#, fuzzy
+msgid "devcp_transbox_img_add_trans"
+msgstr "Add Translation"
+
+#: views/elements/translationbox.thtml:86
+#, fuzzy
+msgid "devcp_transbox_img_remove_trans"
+msgstr "Remove Translation"
+
+#: views/elements/translationbox.thtml:123
+#, fuzzy
+msgid "devcp_transbox_input_add_all"
+msgstr "Add Locale to All"
+
+#: views/elements/translationbox.thtml:122
+#, fuzzy
+msgid "devcp_transbox_input_add_locale"
+msgstr "Add Locale"
+
+#: views/elements/translationbox.thtml:124
+#: views/elements/translationbox.thtml:135
+#, fuzzy
+msgid "devcp_transbox_input_cancel"
+msgstr "Cancel"
+
+#: views/elements/translationbox.thtml:134
+#, fuzzy
+msgid "devcp_transbox_input_delete"
+msgstr "Delete It"
+
+#: views/elements/translationbox.thtml:113
+#, fuzzy
+msgid "devcp_transbox_select_locale"
+msgstr "Select the locale of the translation to add:"
+
+#. %1$s and %2$s are GUIDs.
+#: controllers/developers_controller.php:343
+#, fuzzy
+msgid "devcp_update_addon_guid_error"
+msgstr ""
+"The add-on GUID used in this file (%1$s) does not match the existing GUID "
+"for this add-on (%2$s)."
+
+#: controllers/developers_controller.php:334
+#, fuzzy
+msgid "devcp_update_addon_priv_error"
+msgstr "You do not have sufficient privileges to update this add-on."
+
+#. %1$s is a version number, %2$s is an add-on ID.
+#: controllers/developers_controller.php:399
+#, fuzzy
+msgid "devcp_update_addon_version_belong_error"
+msgstr "The specified version (%1$s) does not belong to this add-on (%2$s)."
+
+#. %1$s is a version number, maybe 1.1.
+#. %2$s is a URL.
+#: controllers/developers_controller.php:351
+#, fuzzy
+msgid "devcp_update_addon_version_exists_error"
+msgstr ""
+"The version number uploaded (%1$s) already exists for this add-on. If you "
+"are trying to add another file to this version, <a href=\"%2$s\">click here</"
+"a>."
+
+#. %1$s and %2$s are version numbers.
+#: controllers/developers_controller.php:405
+#, fuzzy
+msgid "devcp_update_addon_version_match_error"
+msgstr ""
+"The uploaded version number (%1$s) does not match the existing version "
+"number (%2$s)."
+
+#: views/developers/uploader.thtml:68
+#, fuzzy
+msgid "devcp_uploader_a_start"
+msgstr "Get Started"
+
+#: views/developers/uploader.thtml:137
+#, fuzzy
+msgid "devcp_uploader_ajax_loading"
+msgstr "Uploading file..."
+
+#: views/developers/uploader.thtml:82
+#, fuzzy
+msgid "devcp_uploader_button_agree"
+msgstr "Agree and continue"
+
+#: views/developers/uploader.thtml:157
+#, fuzzy
+msgid "devcp_uploader_button_edit"
+msgstr "Edit My Add-on"
+
+#: views/developers/uploader.thtml:158
+#, fuzzy
+msgid "devcp_uploader_button_later"
+msgstr "I'll complete my add-on later."
+
+#: views/developers/uploader.thtml:168
+#, fuzzy
+msgid "devcp_uploader_button_release"
+msgstr "Add Release Notes"
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/uploader.thtml:156
+#, fuzzy
+msgid "devcp_uploader_created_results"
+msgstr ""
+"<p>Your add-on listing has been successfully created. The basic information "
+"obtained from your uploaded file has been stored, but there's a lot more to "
+"your listing that can be customized.</p><p>Your add-on is currently marked "
+"as <strong>Incomplete</strong>. In order to complete your add-on, you'll "
+"need to make sure it has an accurate name, summary, and description, as well "
+"as at least one selected category. You can edit your add-on's information "
+"using the link below and check the status of your add-on at any time on the "
+"<a %s>status page</a>."
+
+#: views/developers/uploader.thtml:143
+#, fuzzy
+msgid "devcp_uploader_error_correct"
+msgstr "Please correct this problem and upload your file again."
+
+#. %1$s is a version number, %2$s is a status, e.g Public or Incomplete.
+#: views/developers/uploader.thtml:175
+#, fuzzy
+msgid "devcp_uploader_file_created"
+msgstr ""
+"Your new file has been added to version %1$s and is currently marked as %2$s."
+
+#: views/developers/uploader.thtml:154
+#, fuzzy
+msgid "devcp_uploader_header_created"
+msgstr "Add-on Created!"
+
+#: views/developers/uploader.thtml:141
+#, fuzzy
+msgid "devcp_uploader_header_error"
+msgstr "Oops! There seems to be a problem with this file..."
+
+#: views/developers/uploader.thtml:173
+#, fuzzy
+msgid "devcp_uploader_header_file_added"
+msgstr "File Added!"
+
+#: views/developers/uploader.thtml:66
+#, fuzzy
+msgid "devcp_uploader_header_how"
+msgstr "How does it all work?"
+
+#. %s is the version number, e.g. 3.2.
+#: views/developers/uploader.thtml:163
+#, fuzzy
+msgid "devcp_uploader_header_update_created"
+msgstr "Version %s Created"
+
+#: views/developers/uploader.thtml:117
+#, fuzzy
+msgid "devcp_uploader_header_upload"
+msgstr "Upload Your File"
+
+#: views/developers/uploader.thtml:67
+#, fuzzy
+msgid "devcp_uploader_how"
+msgstr ""
+"<p>Thanks for your interest in submitting your add-on to Mozilla Add-ons. "
+"Hosting your add-on on Mozilla Add-ons is the easiest way to handle "
+"distribution of your add-on. Here's what you'll get:</p><ul><li>Each add-on "
+"will have a public display page with information you provide, such as a "
+"brief summary of the add-on's functionality, an optional longer description, "
+"and a showcase of preview screenshots of your add-on.</li><li>Your add-on "
+"will appear in search and browse listings across the site, and even in the "
+"Add-ons Manager of Firefox 3.</li><li>We'll take care of hosting all of your "
+"downloads and providing automatic updates to users when you upload a new "
+"version.</li><li>You'll have access to a statistics dashboard with detailed "
+"information about your user base.</li></ul><p>Add-ons hosted on the site "
+"must be reviewed by a Mozilla Add-ons Editor before they will have all of "
+"the features listed above. If you're ready to start the process and have "
+"your add-on package ready for upload, just click on Get Started below!</p>"
+
+#: views/developers/uploader.thtml:125
+#, fuzzy
+msgid "devcp_uploader_label_platformtype"
+msgstr "Supported Platforms:"
+
+#: views/developers/uploader.thtml:124
+#, fuzzy
+msgid "devcp_uploader_label_upload_field"
+msgstr "Add-on File: "
+
+#: controllers/components/developers.php:1221
+#, fuzzy
+msgid "devcp_uploader_option_other"
+msgstr "Other"
+
+#. %1$s is a number, %2$s is href="..." and should stay in the <a> tag.
+#: views/developers/uploader.thtml:176
+#, fuzzy
+msgid "devcp_uploader_p_pending_file"
+msgstr ""
+"The new file will be available to the public as soon as an editor is able to "
+"review it. There are currently %1$s other add-ons in the queue. Want to be "
+"reviewed faster? Consider <a %2$s>becoming an editor</a>."
+
+#. %1$s is a number, %2$s is href="..." and should stay in the <a> tag.
+#: views/developers/uploader.thtml:166
+#, fuzzy
+msgid "devcp_uploader_p_pending_version"
+msgstr ""
+"The new version will be available to the public as soon as an editor is able "
+"to review it. There are currently %1$s other add-ons in the queue. Want to "
+"be reviewed faster? Consider <a %2$s>becoming an editor</a>."
+
+#. %s is a status, e.g Public or Incomplete.
+#: views/developers/uploader.thtml:165
+#, fuzzy
+msgid "devcp_uploader_p_update_created"
+msgstr "Your new version has been created and is currently marked as %s."
+
+#. %1$s is href="..." and should stay in the 'Versions and Files' <a> tag.
+#. %2$s is href="..." and should stay in the 'current status' <a> tag.
+#: views/developers/uploader.thtml:177
+#, fuzzy
+msgid "devcp_uploader_p_update_file"
+msgstr ""
+"View your new file in the <a %1$s>Versions and Files page</a>, check out "
+"your add-on's <a %2$s>current status</a>, or <b>add release notes</b> by "
+"clicking the button below (highly recommended)."
+
+#. %1$s is href="..." and should stay in the 'Versions and Files' <a> tag.
+#. %2$s is href="..." and should stay in the 'current status' <a> tag.
+#: views/developers/uploader.thtml:167
+#, fuzzy
+msgid "devcp_uploader_p_update_version"
+msgstr ""
+"View your new version in the <a %1$s>Versions and Files page</a>, check out "
+"your add-on's <a %2$s>current status</a>, or <b>add release notes</b> by "
+"clicking the button below (highly recommended)."
+
+#: views/developers/uploader.thtml:118
+#, fuzzy
+msgid "devcp_uploader_p_upload"
+msgstr ""
+"Upload your add-on file using the form below. If you have multiple, platform-"
+"specific files to upload, choose a single file and then upload the others "
+"using the Versions and Files Manager."
+
+#: views/developers/uploader.thtml:125
+#, fuzzy
+msgid "devcp_uploader_platformtype_all"
+msgstr "All"
+
+#: views/developers/uploader.thtml:126
+#, fuzzy
+msgid "devcp_uploader_platformtype_specific"
+msgstr "Specific:"
+
+#. Used as first item in a <select>.
+#: controllers/components/developers.php:1185
+#, fuzzy
+msgid "devcp_uploader_please_choose"
+msgstr "Please Choose..."
+
+#. %1$s is the add-on name, %2$s is the version number.
+#: views/developers/uploader.thtml:57
+#, fuzzy
+msgid "devcp_uploader_title_file"
+msgstr "Add File to %1$s %2$s"
+
+#: views/developers/uploader.thtml:50
+#, fuzzy
+msgid "devcp_uploader_title_submit"
+msgstr "Submit New Add-on"
+
+#. %s is the add-on name.
+#: views/developers/uploader.thtml:54
+#, fuzzy
+msgid "devcp_uploader_title_update"
+msgstr "Update %s"
+
+#. %s is a full <a> tag
+#: controllers/developers_controller.php:503
+#, php-format
+msgid "devcp_valid_app_reference"
+msgstr "Gw. %s ar gyfer cyfeiriad"
+
+#. This is the text in the <a> tag for devcp_valid_app_reference. This should be
+#. fixed.
+#: controllers/developers_controller.php:503
+msgid "devcp_valid_app_reference_linktext"
+msgstr "y dudalen hon"
+
+#: controllers/developers_controller.php:581
+#, fuzzy
+msgid "devcp_verify_author_error"
+msgstr "No account found for that email address."
+
+#: controllers/developers_controller.php:553
+#, fuzzy
+msgid "devcp_verify_search_engine_error"
+msgstr ""
+"Either the XML is invalid or required fields are missing. Please <a href="
+"\"https://developer.mozilla.org/en/Creating_OpenSearch_plugins_for_Firefox"
+"\">read the documentation</a>, verify your add-on, and try again."
+
+#: views/developers/versions.thtml:75
+#, fuzzy
+msgid "devcp_versions_a_cancel"
+msgstr "Cancel"
+
+#: views/developers/versions.thtml:79
+#, fuzzy
+msgid "devcp_versions_a_delete"
+msgstr "Delete Version"
+
+#: views/developers/versions.thtml:74
+#, fuzzy
+msgid "devcp_versions_a_empty"
+msgstr "Remove Empty Version"
+
+#: views/developers/versions.thtml:71
+#, fuzzy
+msgid "devcp_versions_a_remove"
+msgstr "Remove?"
+
+#: views/developers/versions.thtml:91
+#, fuzzy
+msgid "devcp_versions_add"
+msgstr "Add New Version"
+
+#: views/developers/versions_delete.thtml:58
+#, fuzzy
+msgid "devcp_versions_delete_a_cancel"
+msgstr "Cancel"
+
+#: views/developers/versions_delete.thtml:56
+#, fuzzy
+msgid "devcp_versions_delete_a_delete"
+msgstr "Delete Version"
+
+#. Followed by a list of reviews and files that will be removed.
+#: views/developers/versions_delete.thtml:50
+#, fuzzy
+msgid "devcp_versions_delete_also"
+msgstr "This will also delete:"
+
+#: views/developers/versions_delete.thtml:53
+#, fuzzy
+msgid "devcp_versions_delete_files"
+msgid_plural "devcp_versions_delete_files"
+msgstr[0] "%s file"
+msgstr[1] "%s files"
+
+#. %s is the version number.
+#: views/developers/versions_delete.thtml:48
+#, fuzzy
+msgid "devcp_versions_delete_header"
+msgstr "Delete Version %s?"
+
+#: views/developers/versions_delete.thtml:52
+#, fuzzy
+msgid "devcp_versions_delete_reviews"
+msgid_plural "devcp_versions_delete_reviews"
+msgstr[0] "%s review"
+msgstr[1] "%s reviews"
+
+#. %s is the version number.
+#: views/developers/versions_delete.thtml:49
+#, fuzzy
+msgid "devcp_versions_delete_sure"
+msgstr "Are you sure you want to permanently delete version %s?"
+
+#: views/developers/versions_edit.thtml:102
+#: views/developers/versions_edit.thtml:155
+#, fuzzy
+msgid "devcp_versions_edit_a_cancel"
+msgstr "Cancel"
+
+#: views/developers/versions_edit.thtml:101
+#, fuzzy
+msgid "devcp_versions_edit_a_delete"
+msgstr "Delete File"
+
+#: views/developers/versions_edit.thtml:165
+#, fuzzy
+msgid "devcp_versions_edit_a_new_app"
+msgstr "Add New Application"
+
+#: views/developers/versions_edit.thtml:154
+#, fuzzy
+msgid "devcp_versions_edit_a_remove_app"
+msgstr "Remove Application"
+
+#: views/developers/versions_edit.thtml:114
+#, fuzzy
+msgid "devcp_versions_edit_add"
+msgstr "Add New File"
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/versions_edit.thtml:121
+#, fuzzy
+msgid "devcp_versions_edit_adjust"
+msgstr ""
+"Adjusting application information here will allow users to install your add-"
+"on even if the install.rdf in the package indicates that the add-on is "
+"incompatible. <a %s>List of supported applications</a>"
+
+#: views/developers/versions_edit.thtml:153
+#, fuzzy
+msgid "devcp_versions_edit_compat_sure"
+msgstr ""
+"Are you <b>sure</b> you wish to remove compatibility with this application?"
+
+#: views/developers/versions_edit.thtml:100
+#, fuzzy
+msgid "devcp_versions_edit_delete_sure"
+msgstr "Are you <b>sure</b> you wish to permanently delete this file?"
+
+#: views/developers/versions_edit.thtml:203
+#, fuzzy
+msgid "devcp_versions_edit_header_approval"
+msgstr "Approval Information"
+
+#: views/developers/versions_edit.thtml:120
+#, fuzzy
+msgid "devcp_versions_edit_header_compat"
+msgstr "Compatible Applications"
+
+#: views/developers/versions_edit.thtml:74
+#, fuzzy
+msgid "devcp_versions_edit_header_file"
+msgstr "File Information"
+
+#: views/developers/versions_edit.thtml:189
+#, fuzzy
+msgid "devcp_versions_edit_header_license"
+msgstr "License"
+
+#. %s is the version number.
+#: views/developers/versions_edit.thtml:53
+#, fuzzy
+msgid "devcp_versions_edit_header_manage"
+msgstr "Manage Version %s"
+
+#: views/developers/versions_edit.thtml:212
+#, fuzzy
+msgid "devcp_versions_edit_header_notes"
+msgstr "Approval Notes"
+
+#: views/developers/versions_edit.thtml:98
+#, fuzzy
+msgid "devcp_versions_edit_img_delete"
+msgstr "Delete File"
+
+#. %1$s is the file id, e.g. 18723.
+#. %2$s is the platform name, e.g. ALL or Windows.
+#. %3$s is the _('date) created.
+#. %4$s is the status, e.g. "In Sandbox" or "Public".
+#. %5$s is the _('date') status was changed.
+#: views/developers/versions_edit.thtml:208
+#, fuzzy
+msgid "devcp_versions_edit_li_file"
+msgstr "File %1$s (%2$s) created on %3$s and changed to %4$s on %5$s"
+
+#: views/developers/versions_edit.thtml:190
+#, fuzzy
+msgid "devcp_versions_edit_license_description"
+msgstr ""
+"Please select the appropriate license for your add-on. This license "
+"specifies the rights you grant on your source code."
+
+#: views/developers/versions_edit.thtml:111
+#, fuzzy
+msgid "devcp_versions_edit_no_files"
+msgstr "No files found."
+
+#: views/developers/versions_edit.thtml:213
+#, fuzzy
+msgid "devcp_versions_edit_optional"
+msgstr "Optional information for the Editor that reviews this version."
+
+#: views/developers/versions_edit.thtml:151
+#, fuzzy
+msgid "devcp_versions_edit_remove_compat"
+msgstr "Remove Application Compatibility"
+
+#: views/developers/versions_edit.thtml:167
+#, fuzzy
+msgid "devcp_versions_edit_select_app"
+msgstr "Please Select an Application"
+
+#: views/developers/versions_edit.thtml:78
+#, fuzzy
+msgid "devcp_versions_edit_th_file"
+msgstr "File"
+
+#: views/developers/versions_edit.thtml:79
+#, fuzzy
+msgid "devcp_versions_edit_th_platform"
+msgstr "Platform"
+
+#: views/developers/versions_edit.thtml:80
+#, fuzzy
+msgid "devcp_versions_edit_th_size"
+msgstr "Size"
+
+#: views/developers/versions_edit.thtml:81
+#, fuzzy
+msgid "devcp_versions_edit_th_status"
+msgstr "Status"
+
+#: views/developers/versions_edit.thtml:183
+#, fuzzy
+msgid "devcp_versions_edit_transbox_releasenotes_description"
+msgstr ""
+"Information about changes in this release, new features, known bugs, and "
+"other useful information specific to this release/version. This information "
+"will also be available to users updating the add-on in the Firefox 3 Add-ons "
+"Manager interface."
+
+#: views/developers/versions_edit.thtml:182
+#, fuzzy
+msgid "devcp_versions_edit_transbox_releasenotes_name"
+msgstr "Release Notes"
+
+#: views/developers/versions_edit.thtml:164
+#, fuzzy
+msgid "devcp_versions_edit_unsaved_compat"
+msgstr ""
+"<strong>You have unsaved changes.</strong> Compatibility will not be deleted "
+"until you click Update Version below."
+
+#: views/developers/versions_edit.thtml:113
+#, fuzzy
+msgid "devcp_versions_edit_unsaved_files"
+msgstr ""
+"<strong>You have unsaved changes.</strong> Files will not be deleted until "
+"you click Update Version below."
+
+#: views/developers/versions_edit.thtml:218
+#, fuzzy
+msgid "devcp_versions_edit_update"
+msgstr "Update Versions"
+
+#: views/developers/versions.thtml:49
+#, fuzzy
+msgid "devcp_versions_header_manage"
+msgstr "Manage Versions and Files"
+
+#: views/developers/versions.thtml:87
+#, fuzzy
+msgid "devcp_versions_no_versions"
+msgstr "No versions."
+
+#. %s is a version number, base 10.
+#: views/developers/versions.thtml:46
+#, fuzzy
+msgid "devcp_versions_notice_success"
+msgstr "Version %s deleted successfully."
+
+#: views/developers/versions.thtml:73
+#, fuzzy
+msgid "devcp_versions_p_remove"
+msgstr ""
+"This version has no files associated with it and can be removed. Would you "
+"like to remove this version?"
+
+#: views/developers/versions.thtml:58
+#, fuzzy
+msgid "devcp_versions_th_created"
+msgstr "Created"
+
+#: views/developers/versions.thtml:57
+#, fuzzy
+msgid "devcp_versions_th_status"
+msgstr "Status"
+
+#: views/developers/versions.thtml:56
+#, fuzzy
+msgid "devcp_versions_th_version"
+msgstr "Version"
+
+#: controllers/downloads_controller.php:91
+msgid "downloads_disable_warning"
+msgstr "Mae'r ychwanegyn wedi ei anablu'n llwyddiannus"
+
+#: controllers/components/editors.php:57
+#, fuzzy
+msgid "editor_review_error_addon_not_nominated"
+msgstr "This add-on has not been nominated."
+
+#: controllers/components/editors.php:213
+#, fuzzy
+msgid "editor_review_error_file_not_pending"
+msgstr "This file is not pending review."
+
+#. Actions are, for example: approving or rejecting
+#: controllers/components/editors.php:79
+#: controllers/components/editors.php:182
+#, fuzzy
+msgid "editor_review_error_no_action"
+msgstr "Please select a review action."
+
+#: controllers/components/editors.php:192
+#, fuzzy
+msgid "editor_review_error_no_applications"
+msgstr "Please enter the applications you tested."
+
+#. Comments are required when an editor approves or rejects an add-on.
+#: controllers/components/editors.php:84
+#: controllers/components/editors.php:187
+#, fuzzy
+msgid "editor_review_error_no_comments"
+msgstr "Please enter review comments."
+
+#: controllers/components/editors.php:161
+#, fuzzy
+msgid "editor_review_error_no_files"
+msgstr "Please select at least one file to review."
+
+#: controllers/components/editors.php:197
+#, fuzzy
+msgid "editor_review_error_no_operating_system"
+msgstr "Please enter the operating systems you tested."
+
+#: views/editors/logs.thtml:51
+msgid "editorcp_logs_button_filter"
+msgstr "Hidl"
+
+#: views/editors/logs.thtml:44
+msgid "editorcp_logs_filter_by"
+msgstr "Hidlo yn ôl math/gweithred"
+
+#: views/editors/logs.thtml:42 controllers/editors_controller.php:964
+msgid "editorcp_logs_page_heading"
+msgstr "Cofnod Digwyddiad"
+
+#: views/elements/developers/editorsmenu.thtml:60
+msgid "editorcp_menu_eventlog_link"
+msgstr "Cofnod Digwyddiad"
+
+#: views/elements/developers/editorsmenu.thtml:62
+msgid "editorcp_menu_mainpage_link"
+msgstr "Nôl i'r Brif Dudalen"
+
+#: views/elements/developers/editorsmenu.thtml:61
+msgid "editorcp_menu_reviewlog_link"
+msgstr "Cofnod Adolygu"
+
+#: views/elements/developers/editorsmenu.thtml:55
+msgid "editorcp_menu_summary_link"
+msgstr "Crynodeb Golygydd"
+
+#: views/elements/developers/editorsmenu.thtml:52
+msgid "editorcp_menu_title"
+msgstr "Offer y Golygydd"
+
+#: views/editors/reviewlog.thtml:49
+msgid "editorcp_reviewlog_button_filter"
+msgstr "Hidl"
+
+#: views/editors/reviewlog.thtml:58
+msgid "editorcp_reviewlog_column_action"
+msgstr "Gweithred"
+
+#: views/editors/reviewlog.thtml:56
+msgid "editorcp_reviewlog_column_addon"
+msgstr "Ychwanegyn"
+
+#: views/editors/reviewlog.thtml:55
+msgid "editorcp_reviewlog_column_date"
+msgstr "Dyddiad"
+
+#: views/editors/reviewlog.thtml:57
+msgid "editorcp_reviewlog_column_editor"
+msgstr "Golygydd"
+
+#: views/editors/reviewlog.thtml:94
+msgid "editorcp_reviewlog_comments_hide"
+msgstr "Cuddio Sylwadau"
+
+#: views/editors/reviewlog.thtml:93
+msgid "editorcp_reviewlog_comments_show"
+msgstr "Dangos Sylwadau"
+
+#. %1$s and %2$s are full <input> tags for dates
+#: views/editors/reviewlog.thtml:45
+#, php-format
+msgid "editorcp_reviewlog_entries_between"
+msgstr "Gweld cofnodion rhwng %s a %s"
+
+#: views/editors/reviewlog.thtml:104
+msgid "editorcp_reviewlog_none_found"
+msgstr "Dim adolygiadau wedi eu canfod ar gyfer y cyfnod yma"
+
+#: views/editors/reviewlog.thtml:42
+msgid "editorcp_reviewlog_page_heading"
+msgstr "Cofnod Adolygu"
+
+#: views/editors/summary.thtml:61
+msgid "editorcp_summary_monthreviews_heading"
+msgstr "Adolygiadau’r Mis"
+
+#: views/editors/summary.thtml:77
+msgid "editorcp_summary_neweditors_heading"
+msgstr "Golygyddion Newydd"
+
+#: views/editors/summary.thtml:42
+msgid "editorcp_summary_page_heading"
+msgstr "Crynodeb Golygydd"
+
+#: views/editors/summary.thtml:94
+msgid "editorcp_summary_recentactivity_heading"
+msgstr "Gweithgaredd Golygyddol Diweddar"
+
+#: views/editors/summary.thtml:45
+msgid "editorcp_summary_totalreviews_heading"
+msgstr "Cyfanswm Adolygiadau"
+
+#: controllers/editors_controller.php:248
+#: controllers/editors_controller.php:249
+msgid "editors_addon_review_pagetitle"
+msgstr "Adolygiad Ychwanegyn"
+
+#: controllers/editors_controller.php:349
+msgid "editors_error_js-formerror"
+msgstr "Cwblha'r meysydd canlynol:"
+
+#: controllers/editors_controller.php:350
+msgid "editors_error_review_one_file"
+msgstr "Dewisa o leiaf un ffeil i'w adolygu."
+
+#: controllers/editors_controller.php:274
+msgid "editors_error_self_reviews_forbidden"
+msgstr "Dim caniatâd ar gyfer hunan adolygu"
+
+#: controllers/editors_controller.php:699
+msgid "editors_external_software"
+msgstr "Meddalwedd Allanol"
+
+#: views/editors/featured.thtml:120 views/editors/featured.thtml:121
+msgid "editors_featured_add_feature"
+msgstr "Ychwanegu nodwedd"
+
+#: views/editors/featured.thtml:126
+msgid "editors_featured_add_feature_submit"
+msgstr "Ychwanegu"
+
+#: views/editors/featured.thtml:49 controllers/editors_controller.php:832
+#: controllers/editors_controller.php:848
+msgid "editors_featured_addon_add_failure"
+msgstr "Methu ychwanegu nodwedd"
+
+#: controllers/editors_controller.php:851
+msgid "editors_featured_addon_add_success"
+msgstr "Wedi ychwanegu nodwedd yn llwyddiannus"
+
+#: views/editors/featured.thtml:50 controllers/editors_controller.php:839
+#: controllers/editors_controller.php:868
+#: controllers/editors_controller.php:886
+msgid "editors_featured_addon_edit_failure"
+msgstr "Methu golygu nodwedd."
+
+#: views/editors/featured.thtml:51 controllers/editors_controller.php:888
+msgid "editors_featured_addon_edit_success"
+msgstr "Wedi golygu nodwedd yn llwyddiannus."
+
+#: views/editors/featured.thtml:53 controllers/editors_controller.php:861
+msgid "editors_featured_addon_invalid_locale"
+msgstr "Mae un neu fwy o locales yn annilys."
+
+#: views/editors/featured.thtml:52 controllers/editors_controller.php:906
+msgid "editors_featured_addon_remove_failure"
+msgstr "Methu tynnu nodwedd."
+
+#: controllers/editors_controller.php:901
+msgid "editors_featured_addon_remove_success"
+msgstr "Wedi tynnu nodwedd yn llwyddiannus."
+
+#: controllers/editors_controller.php:915
+#: controllers/editors_controller.php:917
+msgid "editors_featured_addons_pagetitle"
+msgstr "Nodweddion Gorau"
+
+#: views/editors/featured.thtml:54 views/editors/featured.thtml:107
+msgid "editors_featured_edit_feature_submit"
+msgstr "Mynd"
+
+#: views/editors/featured.thtml:90 views/editors/featured.thtml:91
+msgid "editors_featured_remove_feature"
+msgstr "Tynnu nodwedd"
+
+#: views/editors/queue.thtml:46
+msgid "editors_filter_queue"
+msgstr "Hidlo Rhes"
+
+#: views/editors/queue.thtml:182
+msgid "editors_helpful_links"
+msgstr "Cyswll Defnyddiol"
+
+#: views/editors/queue.thtml:182
+msgid "editors_link_guide"
+msgstr "Canllaw Golygydd"
+
+#: views/editors/queue.thtml:182
+msgid "editors_link_policy"
+msgstr "Polisi Ychwanegion"
+
+#: views/editors/queue.thtml:47
+msgid "editors_notice_filter_session"
+msgstr ""
+"Bydd yr hidlau yn aros yn eu lle ar gyfer y sesiwn neu tan eu bod wedi eu "
+"clirio."
+
+#. %1 is the queue mode
+#: views/editors/queue.thtml:177 views/admin/flagged_queue.thtml:89
+msgid "editors_notice_none_found"
+msgstr "Nid oes ychwanegion o'r math yma i'w hadolygu."
+
+#: controllers/editors_controller.php:1040
+msgid "editors_one_day"
+msgstr "1 diwrnod"
+
+#: controllers/editors_controller.php:1048
+msgid "editors_one_hour"
+msgstr "1 awr"
+
+#: controllers/editors_controller.php:1056
+msgid "editors_one_minute"
+msgstr "1 munud"
+
+#: controllers/editors_controller.php:64 controllers/editors_controller.php:73
+#: controllers/editors_controller.php:77
+msgid "editors_pagetitle"
+msgstr "Offer Golygydd"
+
+#. %s is a comma separated list of platforms. Example: Windows, OS X
+#: controllers/editors_controller.php:680
+#: controllers/editors_controller.php:683
+#, php-format
+msgid "editors_platform_x_only"
+msgstr "%s yn unig"
+
+#: controllers/editors_controller.php:695
+msgid "editors_pre-release"
+msgstr "Cyn rhyddhau"
+
+#. %1 is the app name
+#: views/editors/queue.thtml:131
+#, php-format
+msgid "editors_queue_app_compatibility"
+msgstr "%s Cytunedd"
+
+#: views/editors/queue.thtml:51
+#, fuzzy
+msgid "editors_queue_filter_label_addon"
+msgstr "Add-on or Author Email"
+
+#: views/editors/queue.thtml:72
+#, fuzzy
+msgid "editors_queue_filter_label_addontypes"
+msgstr "Add-on Types"
+
+#: views/editors/queue.thtml:56
+#, fuzzy
+msgid "editors_queue_filter_label_application"
+msgstr "Application"
+
+#: views/editors/queue.thtml:61
+#, fuzzy
+msgid "editors_queue_filter_label_maxversion"
+msgstr "Max. Version"
+
+#: views/editors/queue.thtml:78
+#, fuzzy
+msgid "editors_queue_filter_label_platforms"
+msgstr "Platforms"
+
+#: views/editors/queue.thtml:66
+#, fuzzy
+msgid "editors_queue_filter_label_submissionage"
+msgstr "Age of Submission (days)"
+
+#. %1$s is a number
+#: views/editors/queue.thtml:90
+#, fuzzy
+msgid "editors_queue_filter_result_count"
+msgid_plural "editors_queue_filter_result_count"
+msgstr[0] "Results of your filtered search: <strong>%1$s</strong> Add-on"
+msgstr[1] "Results of your filtered search: <strong>%1$s</strong> Add-ons"
+
+#: views/editors/queue.thtml:84
+msgid "editors_queue_submit_clean"
+msgstr "Clirio"
+
+#: views/editors/queue.thtml:83
+msgid "editors_queue_submit_filter"
+msgstr "Hidl"
+
+#: controllers/editors_controller.php:133
+msgid "editors_queues_disabled"
+msgstr "Mae pob rhes adolygu wedi eu hanablu. Ceisia eto yn hwyrach."
+
+#: views/editors/review.thtml:149
+#, fuzzy
+msgid "editors_review_a_edit_item"
+msgstr "Edit Item"
+
+#: views/editors/review.thtml:146
+#, fuzzy
+msgid "editors_review_a_item_history"
+msgstr "Item History"
+
+#: views/editors/review.thtml:148
+#, fuzzy
+msgid "editors_review_a_item_homepage"
+msgstr "Item Homepage"
+
+#: views/editors/review.thtml:145
+#, fuzzy
+msgid "editors_review_a_item_overview"
+msgstr "Item Overview"
+
+#: views/editors/review.thtml:147
+#, fuzzy
+msgid "editors_review_a_previews"
+msgstr "Previews"
+
+#: controllers/editors_controller.php:345
+msgid "editors_review_action"
+msgstr "Gweithred Adolygu"
+
+#: views/editors/review.thtml:159
+#, fuzzy
+msgid "editors_review_action_info"
+msgstr "Request More Information"
+
+#: views/editors/review.thtml:157
+msgid "editors_review_action_public"
+msgstr "Gwthio i'r Cyhoeddus"
+
+#: views/editors/review.thtml:160
+msgid "editors_review_action_request_superreview"
+msgstr "Gofyn am Uwch Adolygiad"
+
+#: views/editors/review.thtml:158
+msgid "editors_review_action_sandbox"
+msgstr "Cadw yn y Blwch Tywod"
+
+#: controllers/editors_controller.php:346
+msgid "editors_review_comments"
+msgstr "Sylwadau Adolygu"
+
+#: views/editors/review.thtml:182
+#, fuzzy
+msgid "editors_review_details_info_request"
+msgstr ""
+"Use this form to request more information from the author. They will receive "
+"an email and be able to answer here. You will be notified by email when they "
+"reply."
+
+#: views/editors/review.thtml:174
+msgid "editors_review_details_nominated_public"
+msgstr ""
+"Bydd hyn yn nodi'r ychwanegyn a'r fersiwn mwyaf diweddar a'r ffeiliau fel "
+"rhai cyhoeddus. Bydd fersiynau’r dyfodol yn mynd i'r blwch tywod nes eu bod "
+"wedi eu hadolygu gan olygydd."
+
+#: views/editors/review.thtml:177
+msgid "editors_review_details_nominated_sandbox"
+msgstr "Bydd hyn yn cadw'r ychwanegyn yn y blwch tywod."
+
+#: views/editors/review.thtml:166
+msgid "editors_review_details_pending_public"
+msgstr ""
+"Bydd hyn yn cadarnhau'r fersiwn yn y blwch tywod o fersiwn o ychwanegyn "
+"cyhoeddus i ymddangos ar yr ochr gyhoeddus."
+
+#: views/editors/review.thtml:169
+msgid "editors_review_details_pending_sandbox"
+msgstr ""
+"Bydd hyn yn achosi i fersiwn yn y blwch tywod o ychwanegyn cyhoeddus i aros "
+"yn y blwch tywod."
+
+#: views/editors/review.thtml:185
+msgid "editors_review_details_superreview"
+msgstr ""
+"Os oes gennych bryderon am ddiogelwch, materion hawlfraint neu bryderon "
+"eraill y dylai'r gweinyddwr edrych arnynt, rhowch eich sylwadau yn y maes "
+"isod. Byddant yn cael eu hanfon at y gweinyddwyr nid yr awdur."
+
+#: views/editors/review.thtml:134
+#, fuzzy
+msgid "editors_review_file_diff_link"
+msgstr "Compare with public version"
+
+#: views/editors/review.thtml:131
+msgid "editors_review_file_viewcontents_link"
+msgstr "Darllen Sylwadau"
+
+#: views/editors/review.thtml:65
+msgid "editors_review_header_authors"
+msgstr "Awduron:"
+
+#: views/editors/review.thtml:79
+msgid "editors_review_header_categories"
+msgstr "Categoriau:"
+
+#: views/editors/review.thtml:92
+msgid "editors_review_header_compatibility"
+msgstr "Cytunedd:"
+
+#: views/editors/review.thtml:251
+msgid "editors_review_header_description"
+msgstr "Disgrifiad"
+
+#: views/editors/review.thtml:275
+msgid "editors_review_header_devcomments"
+msgstr "Sylwadau Datblygwyr"
+
+#: views/editors/review.thtml:263
+msgid "editors_review_header_eula"
+msgstr "EULA"
+
+#: views/editors/review.thtml:115
+msgid "editors_review_header_files"
+msgstr "Ffeiliau:"
+
+#: views/editors/review.thtml:284
+msgid "editors_review_header_itemhistory"
+msgstr "Hanes Eitemau"
+
+#: views/editors/review.thtml:232
+msgid "editors_review_header_nominationmessage"
+msgstr "Neges Enwebu"
+
+#: views/editors/review.thtml:311
+msgid "editors_review_header_previews"
+msgstr "Rhagolwg"
+
+#: views/editors/review.thtml:269
+msgid "editors_review_header_privacy"
+msgstr "Polisi Preifatrwydd"
+
+#. %1 is the add-on name and version
+#: views/editors/review.thtml:56
+#, php-format
+msgid "editors_review_header_review"
+msgstr "Adolygu %s"
+
+#: views/editors/review.thtml:239
+msgid "editors_review_header_reviewernotes"
+msgstr "Nodiadau Adolygu"
+
+#: views/editors/review.thtml:245
+msgid "editors_review_header_summary"
+msgstr "Crynodeb"
+
+#: views/editors/review.thtml:257
+msgid "editors_review_header_versionnotes"
+msgstr "Nodiadau'r Fersiwn"
+
+#. a noun: shown in an add-on's editor review history
+#: views/elements/developers/editors_review_history_item.thtml:80
+#, fuzzy
+msgid "editors_review_history_info_reply"
+msgstr "Reply"
+
+#: views/elements/developers/editors_review_history_item.thtml:78
+#, fuzzy
+msgid "editors_review_history_info_request"
+msgstr "Information Request"
+
+#: views/elements/developers/editors_review_history_item.thtml:62
+#: views/editors/reviewlog.thtml:77
+msgid "editors_review_history_nominated_adminreview"
+msgstr "Adolygiad Gweinyddol"
+
+#: views/elements/developers/editors_review_history_item.thtml:56
+#: views/editors/reviewlog.thtml:71
+msgid "editors_review_history_nominated_approved"
+msgstr "Enwebiad Cytunwyd/Cyhoeddus"
+
+#: views/elements/developers/editors_review_history_item.thtml:59
+#: views/editors/reviewlog.thtml:74
+msgid "editors_review_history_nominated_denied"
+msgstr "Enwebiad Gwrthod/Blwch Tywod"
+
+#: views/editors/review.thtml:303
+msgid "editors_review_history_nonefound"
+msgstr "Methu canfod cofnod adolygu blaenorol."
+
+#: views/elements/developers/editors_review_history_item.thtml:73
+#: views/editors/reviewlog.thtml:88
+msgid "editors_review_history_pending_adminreview"
+msgstr "Adolygiad Gweinyddol"
+
+#: views/elements/developers/editors_review_history_item.thtml:67
+#: views/editors/reviewlog.thtml:82
+msgid "editors_review_history_pending_approved"
+msgstr "Cytuno/Cyhoeddus"
+
+#: views/elements/developers/editors_review_history_item.thtml:70
+#: views/editors/reviewlog.thtml:85
+msgid "editors_review_history_pending_denied"
+msgstr "Gwrthod/Blwch Tywod"
+
+#. link text in an add-on's editor review history, allowing to hide and show an information request's replies
+#. %1 is the number of replies
+#: views/elements/developers/editors_review_history_item.thtml:90
+#, fuzzy
+msgid "editors_review_history_show_hide_replies"
+msgid_plural "editors_review_history_show_hide_replies"
+msgstr[0] "Show/Hide Replies (%1$s)"
+msgstr[1] "Show/Hide Replies (%1$s)"
+
+#: views/editors/review.thtml:208
+msgid "editors_review_label_applications"
+msgstr "Rhaglenni:"
+
+#: views/editors/review.thtml:196
+msgid "editors_review_label_cannedresponse"
+msgstr "neu ddewis ymateb parod:"
+
+#: views/editors/review.thtml:190
+msgid "editors_review_label_comments"
+msgstr "Sylwadau:"
+
+#: views/editors/review.thtml:204
+msgid "editors_review_label_operating_systems"
+msgstr "Systemau Gweithredu:"
+
+#: views/editors/review.thtml:285 views/editors/review.thtml:312
+msgid "editors_review_link_pagetop"
+msgstr "Brig"
+
+#: views/editors/review.thtml:141
+#, fuzzy
+msgid "editors_review_mulitple_notice"
+msgstr ""
+"Notice: Only review more than one file if you have tested EVERY file you "
+"select."
+
+#: views/editors/review.thtml:51
+#, fuzzy
+msgid "editors_review_next_link"
+msgstr "next &raquo;"
+
+#: views/editors/review.thtml:322
+msgid "editors_review_previews_notfound"
+msgstr "Heb ganfod rhagolwg."
+
+#: views/editors/review.thtml:50
+#, fuzzy
+msgid "editors_review_previous_link"
+msgstr "&laquo; prev"
+
+#: controllers/editors_controller.php:144
+#: controllers/editors_controller.php:146
+msgid "editors_review_queue_pagetitle"
+msgstr "Rhes Adolygu"
+
+#. %1 is the add-ons rank in the queue, %2 is the total queue length
+#: views/editors/review.thtml:47
+#, fuzzy
+msgid "editors_review_rank_in_queue"
+msgstr "<strong># %1$s</strong> of %2$s in queue"
+
+#. %1 is the add-ons rank in the queue, %2 is the total queue length. Both numbers
+#: views/editors/review.thtml:45
+#, fuzzy
+msgid "editors_review_rank_in_queue_filtered"
+msgstr "<strong># %1$s</strong> of %2$s in queue (filtered)"
+
+#: views/editors/review.thtml:223
+msgid "editors_review_submit_process_action"
+msgstr "Gweithred Prosesu"
+
+#: views/editors/review.thtml:293
+msgid "editors_review_th_action"
+msgstr "Gweithred"
+
+#: views/editors/review.thtml:294
+msgid "editors_review_th_comments"
+msgstr "Sylwadau"
+
+#: views/editors/review.thtml:291
+msgid "editors_review_th_date"
+msgstr "Dyddiad"
+
+#: views/editors/review.thtml:292
+msgid "editors_review_th_reviewer"
+msgstr "Adolygwr"
+
+#: views/editors/review.thtml:290
+msgid "editors_review_th_version_file"
+msgstr "Fersiwn/Ffeil"
+
+#: views/editors/review.thtml:217
+#, fuzzy
+msgid "editors_review_update_notify_once"
+msgstr ""
+"Notify me the next time this add-on is updated. (Subsequent updates will not "
+"generate an email)"
+
+#: controllers/editors_controller.php:298
+msgid "editors_reviewed_successfully"
+msgstr "Adolygiad wedi ei brosesu'n llwyddiannus"
+
+#: views/editors/reviews_queue.thtml:106
+#, fuzzy
+msgid "editors_reviews_action_delete_review"
+msgstr "Delete review"
+
+#: views/editors/reviews_queue.thtml:104
+#, fuzzy
+msgid "editors_reviews_action_keep"
+msgstr "Remove flags; keep review"
+
+#: views/editors/reviews_queue.thtml:102
+msgid "editors_reviews_action_skip"
+msgstr "Hepgor"
+
+#: views/editors/reviews_queue.thtml:100
+msgid "editors_reviews_header_action"
+msgstr "Gweithred"
+
+#: views/editors/reviews_queue.thtml:67
+msgid "editors_reviews_in_reply_to"
+msgstr "Mewn ymateb i:"
+
+#: controllers/editors_controller.php:748
+msgid "editors_reviews_processed"
+msgstr "Adolygiadau wedi eu prosesu'n llwyddiannus!"
+
+#: views/editors/reviews_queue.thtml:117
+msgid "editors_reviews_queue_empty"
+msgstr "Nid oes adolygiadau'n disgwyl cymedroli ar hyn o bryd."
+
+#: views/editors/reviews_queue.thtml:111
+msgid "editors_reviews_submit_process_reviews"
+msgstr "Adolygiadau'r Proses"
+
+#: controllers/editors_controller.php:691
+msgid "editors_site_specific"
+msgstr "Gwefan Benodol"
+
+#: controllers/editors_controller.php:348
+msgid "editors_tested_app"
+msgstr "Rhaglenni wedi eu Profi"
+
+#: controllers/editors_controller.php:347
+msgid "editors_tested_os"
+msgstr "Systemau Gweithredu wedi eu Profi"
+
+#: views/editors/queue.thtml:151
+msgid "editors_th_additional_info"
+msgstr "Gwybodaeth Ychwanegol"
+
+#: views/editors/featured.thtml:63 views/editors/queue.thtml:109
+#: views/admin/flagged_queue.thtml:53
+msgid "editors_th_addon"
+msgstr "Ychwanegyn"
+
+#: views/editors/queue.thtml:125
+msgid "editors_th_addontype"
+msgstr "Math"
+
+#: views/editors/featured.thtml:64
+msgid "editors_th_locales"
+msgstr "Cyfyngu i locales?"
+
+#: views/editors/queue.thtml:148
+#, fuzzy
+msgid "editors_th_nomination_age"
+msgstr "Time in Queue"
+
+#: views/editors/queue.thtml:101 views/editors/queue.thtml:117
+#: views/editors/queue.thtml:144
+#, fuzzy
+msgid "editors_th_sort_ascending"
+msgstr "Ascending sort"
+
+#: views/editors/queue.thtml:105 views/editors/queue.thtml:121
+#: views/editors/queue.thtml:140
+#, fuzzy
+msgid "editors_th_sort_descending"
+msgstr "Descending sort"
+
+#. %s is a number
+#: controllers/editors_controller.php:1036
+#, php-format
+msgid "editors_x_days"
+msgstr "%s dwrnod"
+
+#. %s is a number
+#: controllers/editors_controller.php:1044
+#, php-format
+msgid "editors_x_hours"
+msgstr "%s awr"
+
+#. %s is a number
+#: controllers/editors_controller.php:1052
+#, php-format
+msgid "editors_x_minutes"
+msgstr "%s minud"
+
+#: views/errors/error401.thtml:50 controllers/components/simple_acl.php:81
+#: controllers/components/simple_acl.php:82
+#: controllers/components/simple_acl.php:83 controllers/components/amo.php:607
+#: controllers/components/amo.php:608 controllers/components/amo.php:609
+#: controllers/reviews_controller.php:353
+#: controllers/reviews_controller.php:485
+#: controllers/collections_controller.php:438
+#: controllers/collections_controller.php:496
+#: controllers/collections_controller.php:504
+#: controllers/collections_controller.php:971
+#: controllers/collections_controller.php:1034
+#: controllers/collections_controller.php:1077
+msgid "error_access_denied"
+msgstr "Gwrthod Mynediad"
+
+#: views/errors/error401.thtml:52
+msgid "error_access_denied_message"
+msgstr "Nid oes gennyt ganiatâd i ddarllen y dudalen hon."
+
+#: controllers/collections_controller.php:1039
+#, fuzzy
+msgid "error_addon_exists"
+msgstr "Add-on already exists!"
+
+#: controllers/developers_controller.php:200
+#: controllers/developers_controller.php:593
+#: controllers/developers_controller.php:1016
+#: controllers/developers_controller.php:1429
+#: controllers/downloads_controller.php:95
+#: controllers/downloads_controller.php:102
+#: controllers/downloads_controller.php:164
+#: controllers/statistics_controller.php:135
+#: controllers/previews_controller.php:115
+#: controllers/previews_controller.php:206
+#: controllers/previews_controller.php:307
+#: controllers/reviews_controller.php:77
+#: controllers/reviews_controller.php:240
+#: controllers/reviews_controller.php:332
+#: controllers/reviews_controller.php:340 controllers/api_controller.php:123
+#: controllers/api_controller.php:759 controllers/addons_controller.php:131
+#: controllers/addons_controller.php:197
+#: controllers/addons_controller.php:1407
+#: controllers/addons_controller.php:1465
+#: controllers/addons_controller.php:1469
+#: controllers/addons_controller.php:1503
+#: controllers/editors_controller.php:265
+#: controllers/collections_controller.php:1041
+#: controllers/collections_controller.php:1074
+msgid "error_addon_notfound"
+msgstr "Heb ganfod ychwanegyn!"
+
+#: controllers/files_controller.php:83 controllers/files_controller.php:196
+msgid "error_addon_notviewable"
+msgstr "Nid yw'r ychwanegyn i'w weld yma."
+
+#: controllers/reviews_controller.php:246
+#, fuzzy
+msgid "error_addon_selfreview"
+msgstr "You cannot review your own add-on."
+
+#: controllers/addons_controller.php:970
+msgid "error_browse_no_addons"
+msgstr "Dim ychwanegion yn y categori hwn!"
+
+#: controllers/api_controller.php:424
+#, fuzzy
+msgid "error_collection_feed_notfound"
+msgstr "Add-on feed not found."
+
+#: views/users/register.thtml:65 views/users/edit.thtml:194
+msgid "error_email_invalid"
+msgstr "Nid yw hwn yn gyfeiriad e-bost dilys."
+
+#: views/users/pwreset.thtml:74 views/users/register.thtml:70
+#: views/users/register.thtml:80 views/users/register.thtml:86
+#: views/users/edit.thtml:105 views/users/edit.thtml:111
+#: views/users/edit.thtml:192 views/admin/users_edit.thtml:78
+#: views/admin/users_edit.thtml:83 views/reviews/add.thtml:80
+#: views/reviews/add.thtml:104
+msgid "error_field_required"
+msgstr "Rhaid i'r maes beidio â bod yn wag."
+
+#: controllers/files_controller.php:75 controllers/files_controller.php:93
+#: controllers/files_controller.php:96 controllers/files_controller.php:163
+#: controllers/files_controller.php:176 controllers/files_controller.php:185
+#: controllers/files_controller.php:204 controllers/editors_controller.php:412
+msgid "error_file_notfound"
+msgstr "Heb ganfod y ffeil!"
+
+#. %s is a filename
+#: controllers/editors_controller.php:430
+#, php-format
+msgid "error_file_x_notfound"
+msgstr "Gwall ffeil: Nid yw %s yn bodoli."
+
+#: views/collections/add.thtml:55 views/collections/edit.thtml:89
+#: views/users/register.thtml:54 views/users/edit.thtml:81
+#: views/reviews/add.thtml:70 controllers/groups_controller.php:80
+#: controllers/groups_controller.php:102
+msgid "error_formerrors"
+msgstr "Mae gwallau yn y ffurflen. Cywira nhw a'i ailgyflwyno."
+
+#: views/users/register.thtml:109
+#, fuzzy
+msgid "error_invalid_captcha"
+msgstr "Invalid captcha, please try again!"
+
+#: views/users/register.thtml:100 views/users/edit.thtml:125
+#: views/admin/users_edit.thtml:101
+msgid "error_invalid_url"
+msgstr ""
+"Mae i'r URL fformat annilys. Dyali URLau dilys edrych fel http://esiampl.com/"
+"fy_nhudalen."
+
+#. %s is a string representing what's missing. Example: file_id
+#: controllers/downloads_controller.php:65
+#: controllers/users_controller.php:185 controllers/users_controller.php:264
+#: controllers/users_controller.php:559 controllers/users_controller.php:653
+#: controllers/reviews_controller.php:71
+#: controllers/reviews_controller.php:234
+#: controllers/reviews_controller.php:325
+#: controllers/reviews_controller.php:473
+#: controllers/reviews_controller.php:475
+#: controllers/addons_controller.php:182
+#: controllers/addons_controller.php:1381
+#: controllers/addons_controller.php:1455
+#: controllers/collections_controller.php:266
+#: controllers/collections_controller.php:285
+#: controllers/collections_controller.php:346
+#: controllers/collections_controller.php:443
+#: controllers/collections_controller.php:482
+#: controllers/collections_controller.php:936
+#: controllers/collections_controller.php:959
+#: controllers/collections_controller.php:960
+#: controllers/collections_controller.php:975
+#: controllers/collections_controller.php:977
+#: controllers/collections_controller.php:994
+#: controllers/collections_controller.php:1003
+#: controllers/collections_controller.php:1016
+#: controllers/collections_controller.php:1017
+#: controllers/collections_controller.php:1024
+#: controllers/collections_controller.php:1070
+#: controllers/collections_controller.php:1090
+#, php-format
+msgid "error_missing_argument"
+msgstr "Ymresymiad coll: %s"
+
+#: controllers/components/amo.php:507 controllers/components/amo.php:532
+#, fuzzy
+msgid "error_no_files_in_addon"
+msgstr "No Files"
+
+#: controllers/previews_controller.php:200
+msgid "error_preview_notfound"
+msgstr "Heb ganfod rhagolwg!"
+
+#: views/addons/display.thtml:400 views/reviews/add.thtml:98
+msgid "error_review_rating_required"
+msgstr "Rhaid dewis gradd."
+
+#: controllers/users_controller.php:160
+msgid "error_user_already_confirmed"
+msgstr "Mae'r cyfrif defnyddiwr eisoes wedi ei gadarnhau."
+
+#: controllers/users_controller.php:202 controllers/users_controller.php:276
+#: controllers/users_controller.php:569 controllers/users_controller.php:581
+#: controllers/users_controller.php:587 controllers/users_controller.php:610
+#: controllers/users_controller.php:627
+msgid "error_user_badconfirmationcode"
+msgstr "Cod cadarnhau annilys!"
+
+#: views/users/pwreset.thtml:79 views/users/register.thtml:75
+#: views/users/edit.thtml:183
+msgid "error_user_confirmpw_nomatch"
+msgstr "Nid yw'r cyfrineiriau'n cyd-fynd."
+
+#: views/users/register.thtml:65 views/users/edit.thtml:190
+#: controllers/users_controller.php:617
+msgid "error_user_email_notunique"
+msgstr "Mae'r cyfeiriad e-bost yn cael ei ddefnyddio gan ddefnyddiwr arall."
+
+#: controllers/users_controller.php:596
+#, fuzzy
+msgid "error_user_emailchange_expired"
+msgstr ""
+"The email change has expired. Please change your email address again in your "
+"user profile and click the link in the confirmation email as soon as you "
+"receive it."
+
+#: controllers/collections_controller.php:985
+#, fuzzy
+msgid "error_user_exists"
+msgstr ""
+"Users can only have one role at a time. Please remove the user from any "
+"existing roles before continuing."
+
+#: views/users/register.thtml:91 views/users/edit.thtml:116
+#: views/admin/users_edit.thtml:88
+msgid "error_user_nickname_notunique"
+msgstr "Mae'r llys enw yn cael ei ddefnyddio gan rywun arall."
+
+#: views/users/pwreset.thtml:54 controllers/users_controller.php:191
+#: controllers/users_controller.php:270 controllers/users_controller.php:603
+#: controllers/users_controller.php:659
+#: controllers/collections_controller.php:988
+#: controllers/collections_controller.php:998
+msgid "error_user_notfound"
+msgstr "Heb ganfod defnyddiwr!"
+
+#: views/users/activatefirst.thtml:47
+msgid "error_user_unconfirmed"
+msgstr ""
+"Cadarnha dy gyfrif yn gyntaf gyda'r cod rwyt ti wedi ei dderbyn drwy'r e-"
+"bost."
+
+#: views/users/login.thtml:67
+msgid "error_username_or_pw_wrong"
+msgstr "Enw defnyddiwr neu gyfrinair anghywir!"
+
+#: controllers/editors_controller.php:260
+msgid "error_version_notfound"
+msgstr "Heb ganfod y fersiwn!"
+
+#: views/users/delete.thtml:125 views/users/edit.thtml:173
+msgid "error_wrong_password"
+msgstr "Cyfrinair anghywir wedi ei gynnig!"
+
+#: views/elements/amo2009/homepage_addon.thtml:122
+#: views/elements/feature.thtml:122
+msgid "feature_learnmore"
+msgstr "Dysgu mwy"
+
+#. %1 is the add-on name
+#: views/elements/amo2009/homepage_addon.thtml:123
+#: views/elements/feature.thtml:123
+#, php-format
+msgid "feature_learnmore_about_addon"
+msgstr "Dysgu mwy am %1$s"
+
+#. %1$s is a number
+#: views/elements/amo2009/reviews.thtml:52
+#: views/elements/addon_listitem.thtml:112 views/elements/feature.thtml:99
+#: views/addons/browse_thumbs.thtml:86
+#, php-format
+msgid "feature_reviews"
+msgid_plural "feature_reviews"
+msgstr[0] "%1$s adolygiad"
+msgstr[1] "%1$s adolygiad"
+
+#: views/elements/amo2009/homepage_addon.thtml:127
+#: views/elements/feature.thtml:127
+msgid "feature_view_more_from_category"
+msgstr "Gweld mwy o"
+
+#. This appears on a page that views the source of an add-on. This link will return
+#. the user to the add-on's main page
+#: views/files/browse.thtml:65
+#, fuzzy
+msgid "file_browser_link_addon"
+msgstr "Back to add-on"
+
+#. There is a list of directories and files on the page. Clicking this will show the
+#. contents of all the directories (normally you would click on each one to see the
+#. contents)
+#: views/files/browse.thtml:67
+#, fuzzy
+msgid "file_browser_link_expand_all"
+msgstr "Expand all"
+
+#. This appears on a page that views the source of an add-on. This link will return
+#. the user to the add-on's review page (it only appears if the add-on is being
+#. reviewed)
+#: views/files/browse.thtml:64
+#, fuzzy
+msgid "file_browser_link_review"
+msgstr "Back to review"
+
+#. The title of the page for viewing an add-on's source.
+#. %1$s is the name of the add-on
+#. %2$s is the name of the current application (e.g. Firefox or Thunderbird)
+#: views/files/browse.thtml:46
+#, fuzzy
+msgid "file_browser_title"
+msgstr "%1$s :: File Browser :: %2$s Add-ons"
+
+#. This appears on a page that views the source of an add-on. There is a list of
+#. directories and files on the page. Clicking this link will toggle between an
+#. expanded or a collapsed list. This string should be kept short.
+#: views/files/browse.thtml:68
+#, fuzzy
+msgid "file_browser_toggle_expand_collapse"
+msgstr "+/-"
+
+#. Link text for the AMO About page.
+#: views/elements/footer.thtml:72 views/layouts/amo2009.thtml:341
+#, fuzzy
+msgid "footer_a_about"
+msgstr "About"
+
+#. Link text to the AMO blog.
+#: views/elements/footer.thtml:74 views/layouts/amo2009.thtml:343
+#, fuzzy
+msgid "footer_a_blog"
+msgstr "Blog"
+
+#. Link text to the Frequently Asked Questions page.
+#: views/elements/footer.thtml:73 views/layouts/amo2009.thtml:342
+#, fuzzy
+msgid "footer_a_faq"
+msgstr "FAQ"
+
+#. Full text for the FAQ abbreviation.
+#: views/elements/footer.thtml:73 views/pages/collector_features.thtml:72
+#: views/layouts/amo2009.thtml:342
+#, fuzzy
+msgid "footer_abbr_faq"
+msgstr "Frequently Asked Questions"
+
+#: views/elements/footer.thtml:67 views/layouts/amo2009.thtml:336
+msgid "footer_all_rights_reserved"
+msgstr "Cedwir pob hawl."
+
+#: views/elements/footer.thtml:67 views/layouts/amo2009.thtml:336
+msgid "footer_copyright"
+msgstr "Hawlfraint"
+
+#: views/elements/footer.thtml:71 views/layouts/amo2009.thtml:340
+msgid "footer_credits"
+msgstr "Diolchiadau"
+
+#: views/elements/footer.thtml:76 views/layouts/amo2009.thtml:346
+msgid "footer_disclaimer"
+msgstr ""
+"Mae Mozilla yn darparu cyswllt i'r rhaglenni hyn fel cwrteisi ac nid yw'n "
+"rhannu unrhyw farn ar y rhaglenni na'r wybodaeth sy'n perthyn iddynt. Rhaid "
+"cyfeirio unrhyw gwestiwn, cwyn neu geisiadau at y darparwr meddalwedd "
+"penodol."
+
+#: views/elements/footer.thtml:61 views/layouts/amo2009.thtml:332
+msgid "footer_lang_form_lang_submit_go"
+msgstr "Mynd"
+
+#: views/elements/footer.thtml:70 views/layouts/amo2009.thtml:339
+msgid "footer_legal_notices"
+msgstr "Hysbysiad Cyfreithiol"
+
+#: views/elements/footer.thtml:50 views/layouts/amo2009.thtml:321
+msgid "footer_other_languages"
+msgstr "Ieithoedd Eraill"
+
+#: views/elements/footer.thtml:69 views/layouts/amo2009.thtml:338
+msgid "footer_privacy_policy"
+msgstr "Polisi Preifatrwydd"
+
+#: models/addontype.php:79
+#, fuzzy
+msgid "general_addontype_dict"
+msgstr "Dictionary"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:100
+#, fuzzy
+msgid "general_addontype_dict_plural"
+msgstr "Dictionaries"
+
+#: models/addontype.php:75
+#, fuzzy
+msgid "general_addontype_extension"
+msgstr "Extension"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:98
+#, fuzzy
+msgid "general_addontype_extension_plural"
+msgstr "Extensions"
+
+#: models/addontype.php:85
+#, fuzzy
+msgid "general_addontype_lpaddon"
+msgstr "Language Pack (Add-on)"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:103
+#, fuzzy
+msgid "general_addontype_lpaddon_plural"
+msgstr "Language Packs (Add-on)"
+
+#: models/addontype.php:83
+#, fuzzy
+msgid "general_addontype_lpapp"
+msgstr "Language Pack (Application)"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:102
+#, fuzzy
+msgid "general_addontype_lpapp_plural"
+msgstr "Language Packs (Application)"
+
+#: models/addontype.php:87
+#, fuzzy
+msgid "general_addontype_plugin"
+msgstr "Plugin"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:104
+#, fuzzy
+msgid "general_addontype_plugin_plural"
+msgstr "Plugins"
+
+#: models/addontype.php:81
+#, fuzzy
+msgid "general_addontype_search"
+msgstr "Search Engine"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:101
+#, fuzzy
+msgid "general_addontype_search_plural"
+msgstr "Search Engines"
+
+#: models/addontype.php:77
+#, fuzzy
+msgid "general_addontype_theme"
+msgstr "Theme"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:99
+#, fuzzy
+msgid "general_addontype_theme_plural"
+msgstr "Themes"
+
+#: config/language.php:367
+#, fuzzy
+msgid "general_languages_all_locales"
+msgstr "All Locales"
+
+#: views/layouts/amo2009.thtml:249
+#, fuzzy
+msgid "header_brand_name"
+msgstr "Mozilla"
+
+#. %1$s is the application name. Example: Firefox
+#: views/elements/header.thtml:111 views/elements/header.thtml:122
+#: views/layouts/amo2009.thtml:248
+#, php-format
+msgid "header_home_tooltip"
+msgstr "Dychwelyd i dudalen cartref Ychwanegion %1$s"
+
+#: views/elements/header.thtml:87
+msgid "header_main_firefox_header"
+msgstr "Ychwanegion Firefox"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:218
+#, fuzzy
+msgid "header_main_firefox_header_with_logo"
+msgstr ""
+"Add-ons <em>for</em> <img alt=\"Firefox\" src=\"%1$s\" /> <strong>Firefox</"
+"strong>"
+
+#: views/elements/header.thtml:99
+msgid "header_main_header"
+msgstr "Ychwanegion"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:242
+#, fuzzy
+msgid "header_main_header_with_logo"
+msgstr "Add-ons <img alt=\"Add-ons\" src=\"%1$s\" />"
+
+#: views/elements/header.thtml:90
+msgid "header_main_seamonkey_header"
+msgstr "Ychwanegion Seamonkey"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:224
+#, fuzzy
+msgid "header_main_seamonkey_header_with_logo"
+msgstr ""
+"Add-ons <em>for</em> <img alt=\"seamonkey\" src=\"%1$s\" /> "
+"<strong>SeaMonkey</strong>"
+
+#: views/elements/header.thtml:93
+msgid "header_main_sunbird_header"
+msgstr "Ychwanegion Sunbird"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:230
+#, fuzzy
+msgid "header_main_sunbird_header_with_logo"
+msgstr ""
+"Add-ons <em>for</em> <img alt=\"sunbird\" src=\"%1$s\" /> <strong>Sunbird</"
+"strong>"
+
+#: views/elements/header.thtml:96
+msgid "header_main_thunderbird_header"
+msgstr "Ychwanegion Thunderbird"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:236
+#, fuzzy
+msgid "header_main_thunderbird_header_with_logo"
+msgstr ""
+"Add-ons <em>for</em> <img alt=\"thunderbird\" src=\"%1$s\" /> "
+"<strong>Thunderbird</strong>"
+
+#: views/layouts/amo2009.thtml:205
+#, fuzzy
+msgid "header_navaccess_applications_menu"
+msgstr "Skip to other applications menu"
+
+#: views/layouts/amo2009.thtml:204
+#, fuzzy
+msgid "header_navaccess_categories_menu"
+msgstr "Skip to categories menu"
+
+#: views/layouts/amo2009.thtml:202
+#, fuzzy
+msgid "header_navaccess_main_content"
+msgstr "Skip to main content"
+
+#: views/layouts/amo2009.thtml:203
+#, fuzzy
+msgid "header_navaccess_search_form"
+msgstr "Skip to search form"
+
+#: views/elements/header.thtml:62
+msgid "header_navlink_addons"
+msgstr "Ychwanegion"
+
+#: views/elements/developers/sidebar.thtml:72
+#: views/elements/developers/myaddons.thtml:50 views/elements/header.thtml:159
+#: views/addons/display.thtml:378
+msgid "header_navlink_login"
+msgstr "Mewngofnodi"
+
+#: views/elements/header.thtml:156 views/layouts/amo2009.thtml:304
+msgid "header_navlink_logout"
+msgstr "Allgofnodi"
+
+#: views/elements/header.thtml:145 views/layouts/amo2009.thtml:303
+msgid "header_navlink_myaccount"
+msgstr "Cyfrif"
+
+#: views/elements/header.thtml:158
+msgid "header_navlink_register"
+msgstr "Cofrestru"
+
+#. %1 is the URL to the registration page
+#. %2 is the URL to the login page
+#: views/layouts/amo2009.thtml:278
+#, fuzzy
+msgid "header_navlink_register_or_login"
+msgstr "<a href=\"%1$s\">Register</a> or <a href=\"%2$s\">Log in</a>"
+
+#: views/layouts/amo2009.thtml:285
+#, fuzzy
+msgid "header_navlink_tools"
+msgstr "Tools"
+
+#. %s is the add-on name
+#: views/elements/collections_interactive_addon.thtml:62
+#: views/elements/amo2009/homepage_addon.thtml:77
+#: views/elements/addon_discussionheader.thtml:62
+#: views/elements/addon_listitem.thtml:67 views/elements/feature.thtml:84
+#: views/addons/category_landing.thtml:87 views/addons/browse_thumbs.thtml:60
+#, php-format
+msgid "img_preview_of"
+msgstr "Rhagolwg Delwedd %s"
+
+#. %1 is the login URL for the link tag
+#. %2 is the link to an explanatory page.
+#: views/elements/amo2009/install.thtml:307 views/elements/install.thtml:255
+msgid "install_a_login_to_install"
+msgstr "<a href=\"%1$s\">Mewngofnodi</a> i osod yr ychwanegyn"
+
+#. %1 is the URL for the Experimental Add-ons section of the FAQ page
+#: views/elements/amo2009/install.thtml:283 views/elements/install.thtml:232
+#, fuzzy
+msgid "install_button_confirm_exp_install"
+msgstr ""
+"Let me install this experimental add-on. <a href=\"%1$s\">What's this?</a>"
+
+#. %1$s is the application name. Example: Firefox
+#. %2$s is an optional string used to specify a platform. Example: (Windows)
+#: views/elements/amo2009/install.thtml:128 views/elements/install.thtml:75
+#, php-format
+msgid "install_button_text"
+msgstr "Ychwaneu at %s %s"
+
+#. %1 is the add-on name, %2 is the app name
+#: views/elements/amo2009/install.thtml:191
+#: views/elements/amo2009/install.thtml:206
+#: views/elements/amo2009/install.thtml:249
+#: views/elements/amo2009/install.thtml:298 views/elements/install.thtml:150
+#: views/elements/install.thtml:165 views/elements/install.thtml:202
+#: views/elements/install.thtml:246
+#, php-format
+msgid "install_button_title"
+msgstr "Ychwanegu %1$s at %2$s"
+
+#. %1$s is the add-on name
+#: views/elements/amo2009/install.thtml:200 views/elements/install.thtml:159
+#, php-format
+msgid "install_download"
+msgstr "Llwytho %1$s i Lawr"
+
+#: views/elements/amo2009/install.thtml:147 views/elements/install.thtml:94
+msgid "install_error_addon_not_found"
+msgstr "Nid yw'r ychwanegyn yma ar gael"
+
+#: views/addons/dictionaries.thtml:65
+msgid "langtools_a11y_tablesummary"
+msgstr "Rhestr o becynnau iaith a geiriaduron."
+
+#: views/addons/dictionaries.thtml:47
+msgid "langtools_download_dictionary"
+msgstr "Llwytho Geiriadur i Lawr"
+
+#: views/addons/dictionaries.thtml:48
+msgid "langtools_download_langpack"
+msgstr "Llwytho Pecyn Iaith i Lawr"
+
+#: views/addons/dictionaries.thtml:63 controllers/components/amo.php:685
+#: controllers/addons_controller.php:1239
+msgid "langtools_header_dicts_and_langpacks"
+msgstr "Geiriaduron a Phecynnau Iaith"
+
+#: views/addons/dictionaries.thtml:44
+msgid "langtools_install_dictionary"
+msgstr "Gosod Geiriadur"
+
+#: views/addons/dictionaries.thtml:45
+msgid "langtools_install_langpack"
+msgstr "Gosod Pecyn Iaith"
+
+#: views/addons/dictionaries.thtml:69
+msgid "langtools_tableheader_dictionary"
+msgstr "Geiriadur"
+
+#: views/addons/dictionaries.thtml:70
+msgid "langtools_tableheader_langpack"
+msgstr "Pecyn Iaith"
+
+#: views/addons/dictionaries.thtml:68
+msgid "langtools_tableheader_language"
+msgstr "Iaith"
+
+#: models/license.php:65
+#, fuzzy
+msgid "license_custom"
+msgstr "Custom License"
+
+#: config/bootstrap.php:303
+#, fuzzy
+msgid "licenses_bsd"
+msgstr "BSD License"
+
+#: config/bootstrap.php:298
+#, fuzzy
+msgid "licenses_gpl_2.0"
+msgstr "GNU General Public License, version 2.0"
+
+#: config/bootstrap.php:299
+#, fuzzy
+msgid "licenses_gpl_3.0"
+msgstr "GNU General Public License, version 3.0"
+
+#: config/bootstrap.php:300
+#, fuzzy
+msgid "licenses_lgpl_2.1"
+msgstr "GNU Lesser General Public License, version 2.1"
+
+#: config/bootstrap.php:301
+#, fuzzy
+msgid "licenses_lgpl_3.0"
+msgstr "GNU Lesser General Public License, version 3.0"
+
+#: config/bootstrap.php:302
+#, fuzzy
+msgid "licenses_mit"
+msgstr "MIT/X11 License"
+
+#: config/bootstrap.php:297
+#, fuzzy
+msgid "licenses_mpl_1.1"
+msgstr "Mozilla Public License, version 1.1"
+
+#: views/users/emailchange.thtml:51 views/users/delete.thtml:55
+#: views/users/delete.thtml:137 views/users/edit.thtml:74
+#: views/reviews/flag.thtml:54
+#, fuzzy
+msgid "link_return_to_front_page"
+msgstr "Click here to return to the front page."
+
+#: views/elements/amo2009/addon_list_options.thtml:46
+#: views/elements/addon_list_options.thtml:46
+msgid "list_sortby_date"
+msgstr "Dyddiad"
+
+#: views/elements/amo2009/addon_list_options.thtml:47
+#: views/elements/addon_list_options.thtml:47
+msgid "list_sortby_downloads"
+msgstr "Llwythi"
+
+#: views/elements/amo2009/addon_list_options.thtml:45
+#: views/elements/addon_list_options.thtml:45
+msgid "list_sortby_name"
+msgstr "Enw Ychwanegyn"
+
+#: views/elements/amo2009/addon_list_options.thtml:48
+#: views/elements/addon_list_options.thtml:48
+msgid "list_sortby_rating"
+msgstr "Gradd"
+
+#: config/bootstrap.php:278
+#, fuzzy
+msgid "main_prettyname_fennec"
+msgstr "Fennec"
+
+#: config/bootstrap.php:274
+msgid "main_prettyname_firefox"
+msgstr "Firefox"
+
+#: config/bootstrap.php:277
+msgid "main_prettyname_seamonkey"
+msgstr "SeaMonkey"
+
+#: config/bootstrap.php:276
+msgid "main_prettyname_sunbird"
+msgstr "Sunbird"
+
+#: config/bootstrap.php:275
+msgid "main_prettyname_thunderbird"
+msgstr "Thunderbird"
+
+#: views/elements/addon_categories.thtml:52
+#, fuzzy
+msgid "nav_category_dicts_langpacks"
+msgstr "Dictionaries & Language Packs"
+
+#: views/elements/addon_categories.thtml:55
+#, fuzzy
+msgid "nav_category_themes"
+msgstr "Themes"
+
+#: views/elements/app_chooser.thtml:47 views/layouts/amo2009.thtml:255
+#, fuzzy
+msgid "other_apps_tooltip"
+msgstr "Find add-ons for other applications"
+
+#. In a user list: user 1, user 2, "others"
+#: views/helpers/addons_html.php:222
+msgid "other_users"
+msgstr "eraill"
+
+#: controllers/pages_controller.php:90
+#, fuzzy
+msgid "page_title_appversions"
+msgstr "Application Versions"
+
+#: controllers/pages_controller.php:115
+#, fuzzy
+msgid "page_title_collector"
+msgstr "Add-on Collector"
+
+#: controllers/pages_controller.php:117
+#, fuzzy
+msgid "page_title_collector_faq"
+msgstr "Add-on Collector FAQ"
+
+#: controllers/pages_controller.php:119
+#, fuzzy
+msgid "page_title_collector_features"
+msgstr "Add-on Collector Features"
+
+#: controllers/pages_controller.php:122
+#, fuzzy
+msgid "page_title_collector_firstrun"
+msgstr "Welcome to the Add-on Collector"
+
+#: controllers/pages_controller.php:92
+#, fuzzy
+msgid "page_title_credits"
+msgstr "Credits"
+
+#: controllers/pages_controller.php:113
+#, fuzzy
+msgid "page_title_developer_faq"
+msgstr "Developer FAQ"
+
+#: controllers/pages_controller.php:111
+#, fuzzy
+msgid "page_title_faq"
+msgstr "Frequently Asked Questions"
+
+#: controllers/pages_controller.php:94
+#, fuzzy
+msgid "page_title_fashionyourfirefox_faq"
+msgstr "Fashion your Firefox FAQ"
+
+#: controllers/pages_controller.php:101
+#, fuzzy
+msgid "page_title_policy"
+msgstr "Add-ons Policy"
+
+#: controllers/pages_controller.php:103
+#, fuzzy
+msgid "page_title_privacy"
+msgstr "Mozilla Privacy Policy"
+
+#: controllers/pages_controller.php:105
+#, fuzzy
+msgid "page_title_review_guide"
+msgstr "Review Guidelines"
+
+#: controllers/pages_controller.php:107
+#, fuzzy
+msgid "page_title_sandbox"
+msgstr "Sandbox Review System"
+
+#: controllers/pages_controller.php:109
+#, fuzzy
+msgid "page_title_submissionhelp"
+msgstr "Submission Help"
+
+#: views/pages/appversions.thtml:87
+msgid "pages_appversions_guid"
+msgstr "GUID"
+
+#: views/pages/appversions.thtml:79 controllers/pages_controller.php:90
+msgid "pages_appversions_header"
+msgstr "Fersiynau Rhaglenni Dilys"
+
+#: views/pages/appversions.thtml:80
+msgid "pages_appversions_intro"
+msgstr ""
+"Rhaid i Ychwanegion sy'n cael eu cyflwyno i Ychwanegion Mozilla gael ffeil "
+"install.rdf file sy'n cynnal o leiaf un o'r rhaglenni isod. Dim ond y "
+"fersiynau isod sydd ar gael i'r rhaglenni."
+
+#. %s is a full <a> tag
+#: views/pages/appversions.thtml:93
+#, php-format
+msgid "pages_appversions_required_files"
+msgstr ""
+"Os nad yw dy raglen cynnal angen ffeil install.rdf file, rhaid i ti gynnwys "
+"un gyda'r priodweddau angenrheidiol fel su'n cael ei nodi %s."
+
+#. this is the text inside of an <a> tag for pages_appversions_required_files. This
+#. should be fixed.
+#: views/pages/appversions.thtml:93
+msgid "pages_appversions_required_files_link"
+msgstr "yma"
+
+#: views/pages/appversions.thtml:88
+msgid "pages_appversions_versions"
+msgstr "Fersiynnau"
+
+#: views/pages/policy.thtml:51
+msgid "pages_policy_sandbox_link"
+msgstr "Tudalen Gwybodaeth y Blwch Tywod"
+
+#: views/elements/pagination.thtml:53
+msgid "pagination_next_page"
+msgstr "nesaf"
+
+#: views/elements/pagination.thtml:52
+msgid "pagination_previous_page"
+msgstr "blaenorol"
+
+#: views/elements/recaptcha.thtml:65
+#, fuzzy
+msgid "recaptcha_enter_both_words"
+msgstr ""
+"Please enter <strong>both words</strong> below, <strong>separated by a "
+"space</strong>."
+
+#: views/elements/recaptcha.thtml:83
+#, fuzzy
+msgid "recaptcha_enter_here"
+msgstr "Enter your answer here:"
+
+#: views/elements/recaptcha.thtml:74
+#, fuzzy
+msgid "recaptcha_enter_whatyouhear"
+msgstr "Please type what you hear."
+
+#. %1 is the link switching refreshing the captcha
+#. %2 is the link switching to a text captcha
+#: views/elements/recaptcha.thtml:77
+#, fuzzy
+msgid "recaptcha_hardtohear_text"
+msgstr ""
+"If this is hard to understand, you can <a href=\"%1$s\">listen to something "
+"else</a> or <a href=\"%2$s\">switch back to text</a>."
+
+#. %1 is the link switching refreshing the captcha
+#. %2 is the link switching to an audio captcha
+#: views/elements/recaptcha.thtml:68
+#, fuzzy
+msgid "recaptcha_hardtoread_text"
+msgstr ""
+"If this is hard to read, you can <a href=\"%1$s\">try different words</a> or "
+"<a href=\"%2$s\">listen to something</a> instead."
+
+#: views/users/register.thtml:105
+#, fuzzy
+msgid "recaptcha_label"
+msgstr "Are you human?"
+
+#: views/users/register.thtml:106
+#, fuzzy
+msgid "recaptcha_whatsthis"
+msgstr "What's this?"
+
+#: controllers/reviews_controller.php:559
+#, fuzzy
+msgid "review_flag_error"
+msgstr "Error flagging this review!"
+
+#: models/reviews_moderation_flag.php:69
+#, fuzzy
+msgid "review_flag_reason_bug_support"
+msgstr "Misplaced bug report or support request"
+
+#: views/reviews/display.thtml:103 views/reviews/display.thtml:186
+#, fuzzy
+msgid "review_flag_reason_instructions"
+msgstr "Report this review (select a reason)"
+
+#: models/reviews_moderation_flag.php:67
+#, fuzzy
+msgid "review_flag_reason_language"
+msgstr "Inappropriate language/dialog"
+
+#: models/reviews_moderation_flag.php:71
+#, fuzzy
+msgid "review_flag_reason_other"
+msgstr "Other (please specify)"
+
+#: models/reviews_moderation_flag.php:65
+#, fuzzy
+msgid "review_flag_reason_spam"
+msgstr "Spam or otherwise non-review content"
+
+#: views/reviews/display.thtml:91 views/reviews/display.thtml:175
+#: controllers/reviews_controller.php:555
+#, fuzzy
+msgid "review_flag_success"
+msgstr "Thanks; this review has been flagged for editor approval."
+
+#: views/reviews/display.thtml:41
+#, fuzzy
+msgid "review_flag_this"
+msgstr "Report this review"
+
+#: views/reviews/display.thtml:42
+#, fuzzy
+msgid "review_flag_this_titletip"
+msgstr ""
+"Is this review inappropriate, inaccurate or spam? Click here to flag it for "
+"editor review."
+
+#. %1 is the URL of the support section, %2 for the review guidelines
+#: views/reviews/add.thtml:53
+#, fuzzy
+msgid "review_guidelines_short"
+msgstr ""
+"<p>Keep these tips in mind:</p><ul><li>Write like you're telling a friend "
+"about your experience with the add-on. Give specifics and helpful details, "
+"such as what features you liked and/or disliked, how easy to use it is, and "
+"any disadvantages it has. Avoid generic language such as calling it \"Great"
+"\" or \"Bad\" unless you can give reasons why you believe this is so.</"
+"li><li>Please do not post bug reports in reviews. We do not make your email "
+"address available to add-on developers and they may need to contact you to "
+"help resolve your issue. See the <a href=\"%1$s\">support section</a> to "
+"find out where to get assistance for this add-on.</li><li>Please keep "
+"reviews clean, avoid the use of improper language and do not post any "
+"personal information.</li></ul><p>Please read the <a href=\"%2$s\">Review "
+"Guidelines</a> for more detail about user add-on reviews.</p>"
+
+#. %1 is the add-on name
+#: views/reviews/flag.thtml:56 views/reviews/display.thtml:55
+#: views/reviews/review_added.thtml:50
+#, php-format
+msgid "reviews_header"
+msgstr "Adolygiadau o %s"
+
+#: controllers/addons_controller.php:435
+msgid "rss_featuredaddons"
+msgstr "Ychwanegion Gorau"
+
+#: controllers/addons_controller.php:432
+msgid "rss_newestaddons"
+msgstr "Ychwanegion Diweddaraf"
+
+#: controllers/addons_controller.php:434
+#, fuzzy
+msgid "rss_popularaddons"
+msgstr "Popular Add-ons"
+
+#: controllers/addons_controller.php:433
+#, fuzzy
+msgid "rss_updatedaddons"
+msgstr "Updated Add-ons"
+
+#: views/elements/search_mini.thtml:70
+#, fuzzy
+msgid "search"
+msgstr "Search"
+
+#: views/search/collections.thtml:51
+#, fuzzy
+msgid "search_collections_header"
+msgstr "Collection Search Results"
+
+#: controllers/search_controller.php:297
+#, fuzzy
+msgid "search_collections_pagetitle"
+msgstr "Collection Search Results"
+
+#: controllers/search_controller.php:99
+msgid "search_disabled"
+msgstr "Mae chwilio wedi ei anablu. Ceisiwch eto."
+
+#: views/elements/amo2009/search.thtml:188 views/elements/search.thtml:187
+#: views/elements/search_mini.thtml:54
+msgid "search_form_all_addons"
+msgstr "pob ychwanegyn"
+
+#. This string is in the main category dropdown when searching
+#: views/elements/amo2009/search.thtml:204
+#, fuzzy
+msgid "search_form_all_collections"
+msgstr "all collections"
+
+#: views/elements/amo2009/search.thtml:184
+#: views/elements/amo2009/search.thtml:385
+#: views/elements/amo2009/search.thtml:408 views/elements/search.thtml:171
+#: views/elements/search.thtml:183 views/elements/search_mini.thtml:43
+#: views/elements/search_mini.thtml:49 views/layouts/mozilla.thtml:188
+msgid "search_form_default_text"
+msgstr "chwilio am ychwanegion"
+
+#: views/elements/amo2009/search.thtml:184
+#: views/elements/amo2009/search.thtml:404
+#, fuzzy
+msgid "search_form_default_text_collections"
+msgstr "search for collections"
+
+#: views/elements/amo2009/search.thtml:206 views/elements/search.thtml:202
+#, fuzzy
+msgid "search_form_submit_tooltip"
+msgstr "Search for add-ons"
+
+#: views/elements/amo2009/search.thtml:184 views/elements/search.thtml:183
+#: views/elements/search_mini.thtml:49
+#, fuzzy
+msgid "search_form_tooltip"
+msgstr "Click to enter search terms"
+
+#: views/elements/amo2009/search.thtml:186 views/elements/search.thtml:185
+#: views/elements/search_mini.thtml:52
+msgid "search_form_within"
+msgstr "o fewn"
+
+#: views/addons/searchengines.thtml:118
+msgid "search_landing_all_search_engines"
+msgstr "Pob Peiriant Chwilio"
+
+#: views/addons/searchengines.thtml:114
+msgid "search_landing_browse_search_engines"
+msgstr "Pori'r Peiriannau Chwilio"
+
+#: views/search/collections.thtml:58 views/search/index.thtml:59
+msgid "search_nothing_found"
+msgstr "Heb ganfod canlyniad"
+
+#: controllers/search_controller.php:185
+msgid "search_pagetitle"
+msgstr "Chwilio Ychwanegion"
+
+#: controllers/search_controller.php:242
+msgid "search_rss_description"
+msgstr "Chwilio llif canlyniadau"
+
+#. %s is the terms the user is searching for (a string)
+#: controllers/search_controller.php:241
+#, php-format
+msgid "search_rss_results_for"
+msgstr "Canlyniadau chwilio am: %s"
+
+#: views/elements/header.thtml:154 views/layouts/amo2009.thtml:296
+msgid "sidebar_navlink_admin_tools"
+msgstr "Offer Gweinyddol"
+
+#: views/elements/header.thtml:146 views/layouts/amo2009.thtml:288
+msgid "sidebar_navlink_developer_tools"
+msgstr "Offer Datblygu"
+
+#: views/elements/header.thtml:148 views/layouts/amo2009.thtml:290
+msgid "sidebar_navlink_editor_tools"
+msgstr "Offer Golygu"
+
+#: views/layouts/amo2009.thtml:302
+msgid "sidebar_navlink_welcome"
+msgstr "Croeso"
+
+#. %s is the user's name
+#: views/layouts/amo2009.thtml:302
+#, php-format
+msgid "sidebar_navlink_welcome_name"
+msgstr "Croeso, %s"
+
+#: views/elements/pitch.thtml:50 views/elements/pitch.thtml:55
+msgid "sidebar_pitch_dictionary"
+msgstr "Geiriadur"
+
+#: views/elements/pitch.thtml:72
+msgid "sidebar_pitch_featured_addons"
+msgstr "Ychwanegion Gorau"
+
+#: views/elements/pitch.thtml:61
+msgid "sidebar_pitch_looking_for"
+msgstr "Rwy'n edrych am:"
+
+#: views/elements/pitch.thtml:70
+msgid "sidebar_pitch_newest_addons"
+msgstr "Ychwanegion Diweddaraf"
+
+#: views/elements/pitch.thtml:49
+msgid "sidebar_pitch_search"
+msgstr "Ategyn Chwilio"
+
+#: views/elements/pitch.thtml:69
+msgid "sidebar_pitch_subscribe_to"
+msgstr "Tanysgrifio i"
+
+#: views/elements/pitch.thtml:48 views/elements/pitch.thtml:54
+msgid "sidebar_pitch_theme"
+msgstr "Thema"
+
+#: views/elements/pitch.thtml:71
+#, fuzzy
+msgid "sidebar_pitch_updated_addons"
+msgstr "Updated Add-ons"
+
+#. %1$s is a number
+#: views/helpers/localization.php:65 views/developers/versions_edit.thtml:95
+#: views/addons/dictionaries.thtml:92
+#, php-format
+msgid "size_kb"
+msgstr "%1$s KB"
+
+#: views/elements/amo2009/stars.thtml:57 views/elements/stars.thtml:63
+msgid "stars_not_yet_rated"
+msgstr "Heb ei raddio eto"
+
+#. %1 is the number of stars this add-on has
+#: views/elements/amo2009/stars.thtml:49 views/elements/stars.thtml:54
+#, php-format
+msgid "stars_rated_x_outof_5"
+msgstr "Gradd o %s allan o 5 seren"
+
+#: views/statistics/addon.thtml:59
+msgid "statistics_addon_dashboard_link"
+msgstr "Cartref Bwrdd Data"
+
+#: views/statistics/addon.thtml:58
+msgid "statistics_addon_developertools_link"
+msgstr "Offer Datblygwr"
+
+#: views/statistics/addon.thtml:53
+msgid "statistics_addon_switch"
+msgstr "Newid Ychwanegyn"
+
+#. This is a date format.
+#. http://php.net/strftime
+#: views/statistics/rss/summary.thtml:54 views/statistics/addon.thtml:181
+msgid "statistics_date_shortmonth"
+msgstr "%b. %e"
+
+#. This is a date format.
+#. http://php.net/strftime
+#: views/statistics/rss/summary.thtml:40 views/statistics/addon.thtml:152
+msgid "statistics_date_shortmonthwithyear"
+msgstr "%b. %e, %Y"
+
+#. This is a date format.
+#. http://php.net/strftime
+#: views/statistics/rss/summary.thtml:41 views/statistics/rss/summary.thtml:48
+#: views/statistics/addon.thtml:161 views/statistics/addon.thtml:172
+msgid "statistics_date_weekdayshortmonth"
+msgstr "%A, %b. %e"
+
+#. %1$s is an add-on name and version. Example: Add-on 3.5
+#: controllers/components/stats.php:519
+#, php-format
+msgid "statistics_events_addon_created"
+msgstr "Crëwyd %1$s"
+
+#. %1$s is an application name and version. Example: Firefox 3.5
+#: controllers/components/stats.php:500
+#, php-format
+msgid "statistics_events_app_released"
+msgstr "Ryddhawyd %1$s"
+
+#: views/statistics/addon.thtml:71
+msgid "statistics_help_close_link"
+msgstr "Cau"
+
+#: views/statistics/addon.thtml:60
+msgid "statistics_help_link"
+msgstr "Cymorth"
+
+#: views/statistics/index.thtml:83
+msgid "statistics_index_anotheraddon"
+msgstr "neu, ddewis ychwanegyn arall"
+
+#: views/statistics/index.thtml:85
+msgid "statistics_index_anotheraddon_public"
+msgstr "neu, ddewis ychwanegyn gydag ystadegau cyhoeddus"
+
+#: views/statistics/index.thtml:71
+msgid "statistics_index_myaddons"
+msgstr "Dewis un o dy ychwanegion er mwyn gweld yr ystadegau"
+
+#: views/statistics/index.thtml:89
+msgid "statistics_index_selectaddon"
+msgstr "Dewis ystadegyn i weld ei ystadegau"
+
+#: views/statistics/index.thtml:91
+msgid "statistics_index_selectaddon_public"
+msgstr "Dewis ystadegyn gydag ystadegau cyhoeddus"
+
+#: views/statistics/index.thtml:39
+msgid "statistics_index_title"
+msgstr "Bwrdd Gwybodaeth Ystadegau"
+
+#: views/statistics/index.thtml:97
+msgid "statistics_index_view_button"
+msgstr "Gweld yr Ystadegau"
+
+#: views/statistics/addon.thtml:222 controllers/statistics_controller.php:247
+#, fuzzy
+msgid "statistics_js_download_csv"
+msgstr "View this table in CSV format"
+
+#: controllers/statistics_controller.php:246
+msgid "statistics_js_dropdowns_none"
+msgstr "dim"
+
+#: controllers/statistics_controller.php:245
+msgid "statistics_js_dropdowns_removeplot"
+msgstr "Tynnu'r plot"
+
+#: controllers/statistics_controller.php:248
+#, fuzzy
+msgid "statistics_js_groupby_selector_date"
+msgstr "Group by: Day"
+
+#: controllers/statistics_controller.php:251
+#, fuzzy
+msgid "statistics_js_groupby_selector_month"
+msgstr "Group by: Month"
+
+#: controllers/statistics_controller.php:249
+#, fuzzy
+msgid "statistics_js_groupby_selector_week"
+msgstr "Group by: Week"
+
+#: controllers/statistics_controller.php:250
+#, fuzzy
+msgid "statistics_js_groupby_selector_week_over_week"
+msgstr "Compare by: Week"
+
+#: controllers/statistics_controller.php:260
+msgid "statistics_js_plotselection_foundinrange"
+msgstr "Wedi canfod %s dewis"
+
+#: controllers/statistics_controller.php:270
+msgid "statistics_js_plotselection_options_addplot_name"
+msgstr "Ychwanebu Plot"
+
+#: controllers/statistics_controller.php:271
+msgid "statistics_js_plotselection_options_addplot_tooltip"
+msgstr "Ychwanegu plot arall i'r graff"
+
+#: controllers/statistics_controller.php:261
+msgid "statistics_js_plotselection_options_count_name_checked"
+msgstr "Cuddio Cyfanswm y Cyfrif"
+
+#: controllers/statistics_controller.php:262
+msgid "statistics_js_plotselection_options_count_name_unchecked"
+msgstr "Dangos Cyfanswm y Cyfrif"
+
+#: controllers/statistics_controller.php:263
+#, fuzzy
+msgid "statistics_js_plotselection_options_count_tooltip"
+msgstr "Plot the total count on this graph"
+
+#: controllers/statistics_controller.php:275
+msgid "statistics_js_plotselection_options_csv_name"
+msgstr "Gweld y Data (CVS)"
+
+#: controllers/statistics_controller.php:276
+msgid "statistics_js_plotselection_options_csv_tooltip"
+msgstr "Estyn ffeil CVS o'r data"
+
+#: controllers/statistics_controller.php:267
+msgid "statistics_js_plotselection_options_events_addon_name_checked"
+msgstr "Cuddio %s Digwyddiad"
+
+#: controllers/statistics_controller.php:268
+msgid "statistics_js_plotselection_options_events_addon_name_unchecked"
+msgstr "Dangos %s Digwyddiad"
+
+#: controllers/statistics_controller.php:269
+msgid "statistics_js_plotselection_options_events_addon_tooltip"
+msgstr "Gosod troshaen o ddyddiadau ryddhau ychwanegion ar y plotiau"
+
+#: controllers/statistics_controller.php:264
+msgid "statistics_js_plotselection_options_events_firefox_name_checked"
+msgstr "Cuddio Digwyddiadau Firefox"
+
+#: controllers/statistics_controller.php:265
+msgid "statistics_js_plotselection_options_events_firefox_name_unchecked"
+msgstr "Dangos Digwyddiadau Firefox"
+
+#: controllers/statistics_controller.php:266
+msgid "statistics_js_plotselection_options_events_firefox_tooltip"
+msgstr "Gosod troshaen o ddyddiadau ryddhau Firefox ar y plotiau"
+
+#: controllers/statistics_controller.php:272
+msgid "statistics_js_plotselection_options_resize_name_checked"
+msgstr "Cau'r Graff"
+
+#: controllers/statistics_controller.php:273
+msgid "statistics_js_plotselection_options_resize_name_unchecked"
+msgstr "Ehangu'r Graff"
+
+#: controllers/statistics_controller.php:274
+msgid "statistics_js_plotselection_options_resize_tooltip"
+msgstr "Newid y graff"
+
+#: controllers/statistics_controller.php:254
+msgid "statistics_js_plotselection_selector_adu"
+msgstr "Defnyddwyr Gweithredol Dyddiol"
+
+#: controllers/statistics_controller.php:256
+msgid "statistics_js_plotselection_selector_application"
+msgstr "Rhaglen"
+
+#: controllers/statistics_controller.php:259
+msgid "statistics_js_plotselection_selector_custom"
+msgstr "Addasu"
+
+#: controllers/statistics_controller.php:253
+msgid "statistics_js_plotselection_selector_downloads"
+msgstr "Llwythi"
+
+#: controllers/statistics_controller.php:258
+msgid "statistics_js_plotselection_selector_os"
+msgstr "Systemau Gweithredu"
+
+#: controllers/statistics_controller.php:257
+msgid "statistics_js_plotselection_selector_status"
+msgstr "Statws Ychwanegyn"
+
+#: controllers/statistics_controller.php:252
+msgid "statistics_js_plotselection_selector_summary"
+msgstr "Crynodeb"
+
+#: controllers/statistics_controller.php:255
+msgid "statistics_js_plotselection_selector_version"
+msgstr "Fersiwn yr Ychwanegyn"
+
+#: controllers/components/stats.php:398
+msgid "statistics_longnames_application"
+msgstr "Rhaglen"
+
+#: controllers/components/stats.php:400
+msgid "statistics_longnames_os"
+msgstr "System Weithredu"
+
+#: controllers/components/stats.php:399
+msgid "statistics_longnames_status"
+msgstr "Statws Ychwanegyn"
+
+#: controllers/components/stats.php:401
+msgid "statistics_longnames_unknown"
+msgstr "Anhysbys"
+
+#: controllers/components/stats.php:397
+msgid "statistics_longnames_version"
+msgstr "Fersiwn yr Ychwanegyn"
+
+#: views/statistics/addon.thtml:118
+msgid "statistics_notice_data_insufficient"
+msgstr "Nid oes digon o ddata i arddangos y graff. Galwa eto."
+
+#: views/statistics/addon.thtml:130
+msgid "statistics_notice_data_none"
+msgstr ""
+"Nid oes gennym ddata ar dy ychwanegyn eto. Galw eto ymhen ychwydig "
+"ddyddiadau."
+
+#: views/statistics/addon.thtml:41
+msgid "statistics_notice_data_updating"
+msgstr ""
+"Mae ystadegau Ychwanegion yn y broes o gael eu diweddaru. Gall fod data "
+"diweddar fod yn anghyflawn wrth i'n sgriptiau weithio i ddiweddaru'r "
+"wybodaeth. Galwa eto ymhen ychydig funudau"
+
+#: views/statistics/addon.thtml:136
+msgid "statistics_notice_disabled"
+msgstr ""
+"Mae'r bwrdd Gwybodaeth Ystadegau wedi ei anablu. Galwa heibio eto rhywbryd."
+
+#: views/statistics/addon.thtml:123
+msgid "statistics_notice_nojavascript"
+msgstr "Mae angen Javascript ar gyfer gweld graffiau'r Bwrdd Gwybodaeth."
+
+#: views/statistics/addon.thtml:44
+msgid "statistics_notice_settings_updated"
+msgstr "Mae dy osodiadau wedi eu diweddaru"
+
+#: controllers/statistics_controller.php:60
+#: controllers/statistics_controller.php:71
+#: controllers/statistics_controller.php:74
+#: controllers/statistics_controller.php:240
+msgid "statistics_pagetitle"
+msgstr "Bwrdd Gwybodaeth Ystadegau"
+
+#: views/statistics/addon.thtml:99
+msgid "statistics_plot_legend_adu"
+msgstr "Defnyddwyr Dyddiol Gweithredol"
+
+#: views/statistics/addon.thtml:95
+msgid "statistics_plot_legend_downloads"
+msgstr "Llwythi Dyddiol"
+
+#: views/statistics/addon.thtml:107
+msgid "statistics_plot_options_zoomin_alt"
+msgstr "Chwyddo i Mewn"
+
+#: views/statistics/addon.thtml:106
+msgid "statistics_plot_options_zoomin_title"
+msgstr "Chwyddo i un mis"
+
+#: views/statistics/addon.thtml:110
+msgid "statistics_plot_options_zoomout_alt"
+msgstr "Chwyddo Allan"
+
+#: views/statistics/addon.thtml:109
+msgid "statistics_plot_options_zoomout_title"
+msgstr "Chwyddo allan un mis"
+
+#: controllers/statistics_controller.php:283
+#, php-format
+msgid "statistics_rss_description"
+msgstr "Crynodeb dyddiol o ystadegau %1$s"
+
+#: views/statistics/rss/summary.thtml:68
+msgid "statistics_rss_title_fulldate"
+msgstr "%A, %B %e, %Y"
+
+#: views/statistics/rss/summary.thtml:68
+#, php-format
+msgid "statistics_rss_title_statsfordate"
+msgstr "Ystadegau %1$s"
+
+#: views/statistics/settings.thtml:49
+msgid "statistics_settings_access_description"
+msgstr ""
+"Drwy ragosodiad, dim ond ti a Mozilla sy'n cael mynediad at y wybodaeth ar "
+"dy fwrdd gwybodaeth. Gelli agor hwn i'r cyhoedd fel bod modd i bawb weld "
+"data dy ychwanegyn."
+
+#: views/statistics/settings.thtml:48
+msgid "statistics_settings_access_heading"
+msgstr "Mynediad i'r Bwrdd Gwybodaeth"
+
+#: views/statistics/settings.thtml:51
+msgid "statistics_settings_access_private"
+msgstr "Preifat"
+
+#: views/statistics/settings.thtml:51
+msgid "statistics_settings_access_private_description"
+msgstr "Dim ond ti a Mozilla sy'n gallu gweld ystadegau'r ychwanegyn"
+
+#: views/statistics/settings.thtml:52
+msgid "statistics_settings_access_public"
+msgstr "Cyhoeddus"
+
+#: views/statistics/settings.thtml:52
+msgid "statistics_settings_access_public_description"
+msgstr "Gall unrhyw un weld ystadegau'r ychwanegyn"
+
+#: views/statistics/addon.thtml:251
+msgid "statistics_settings_change_link"
+msgstr "Newid y Gosodiadau"
+
+#: views/statistics/addon.thtml:253
+msgid "statistics_settings_confidential"
+msgstr "Cofia drin y wybodaeth fel un cyfrinachol."
+
+#: views/statistics/addon.thtml:245
+msgid "statistics_settings_currently_private"
+msgstr "Mae'r bwrdd gwybodaeth yn un <b>preifat</b> ar hyn o bryd."
+
+#: views/statistics/addon.thtml:241
+msgid "statistics_settings_currently_public"
+msgstr "Mae'r bwrdd gwybodaeth yn <b>gyhoeddus</b> ar hyn o bryd."
+
+#: views/statistics/addon.thtml:246
+msgid "statistics_settings_locked_alt"
+msgstr "Wedi Cloi"
+
+#: views/statistics/settings.thtml:57
+msgid "statistics_settings_return_link"
+msgstr "Nôl i'r Bwrdd Gwybodaeth"
+
+#: views/statistics/settings.thtml:56
+msgid "statistics_settings_save_button"
+msgstr "Cadw'r Gosodiadau"
+
+#: views/statistics/settings.thtml:46
+#, php-format
+msgid "statistics_settings_title"
+msgstr "Gosodiadau Bwrdd Gwybodaeth Ystadegau %1$s"
+
+#: views/statistics/addon.thtml:242
+msgid "statistics_settings_unlocked_alt"
+msgstr "Ddim ar Glo"
+
+#: controllers/components/stats.php:405
+msgid "statistics_shortnames_application"
+msgstr "Rhaglen"
+
+#: controllers/components/stats.php:407
+msgid "statistics_shortnames_os"
+msgstr "SW"
+
+#: controllers/components/stats.php:406
+msgid "statistics_shortnames_status"
+msgstr "St"
+
+#: controllers/components/stats.php:408
+msgid "statistics_shortnames_unknown"
+msgstr "ah"
+
+#: controllers/components/stats.php:404
+msgid "statistics_shortnames_version"
+msgstr "Fer"
+
+#: views/statistics/rss/summary.thtml:42 views/statistics/addon.thtml:192
+msgid "statistics_summary_downloads_average"
+msgstr "Cyfartaledd Llwythi Dyddiol"
+
+#: views/statistics/rss/summary.thtml:39
+msgid "statistics_summary_downloads_heading"
+msgstr "Llwythi"
+
+#: views/statistics/rss/summary.thtml:41 views/statistics/addon.thtml:171
+msgid "statistics_summary_downloads_lastcount"
+msgstr "Cyfri'r Diwrnod Diwethaf"
+
+#: views/statistics/rss/summary.thtml:43 views/statistics/addon.thtml:199
+msgid "statistics_summary_downloads_lastweek"
+msgstr "Llwythi yn ystod y 7 diwrnod diwethaf"
+
+#: views/statistics/rss/summary.thtml:40 views/statistics/addon.thtml:151
+msgid "statistics_summary_downloads_total"
+msgstr "Cyfanswm Llwythi"
+
+#: views/statistics/rss/summary.thtml:40 views/statistics/addon.thtml:152
+#, php-format
+msgid "statistics_summary_downloads_total_sincedate"
+msgstr "Ers %1$s"
+
+#: views/statistics/rss/summary.thtml:50 views/statistics/rss/summary.thtml:56
+#: views/statistics/addon.thtml:163 views/statistics/addon.thtml:183
+msgid "statistics_summary_nodata"
+msgstr "Dim data eto"
+
+#: views/statistics/rss/summary.thtml:60 views/statistics/addon.thtml:195
+msgid "statistics_summary_updatepings_average"
+msgstr "Cyfartaledd Defnyddwyr Dyddiol Gweithredol"
+
+#: views/statistics/rss/summary.thtml:52 views/statistics/addon.thtml:177
+msgid "statistics_summary_updatepings_changefromprevious"
+msgstr "Newid o'r cyfrif blaenorol"
+
+#: views/statistics/rss/summary.thtml:54 views/statistics/addon.thtml:181
+#, php-format
+msgid "statistics_summary_updatepings_changefromprevious_ondate"
+msgstr "%1$s ar %2$s"
+
+#: views/statistics/rss/summary.thtml:45
+msgid "statistics_summary_updatepings_heading"
+msgstr "Defnyddwyr Dyddiol Gweithredol"
+
+#: views/statistics/rss/summary.thtml:46 views/statistics/addon.thtml:157
+msgid "statistics_summary_updatepings_total"
+msgstr "Defnyddwyr Dyddiol Gweithredol"
+
+#: views/statistics/rss/summary.thtml:48 views/statistics/addon.thtml:161
+#, php-format
+msgid "statistics_summary_updatepings_total_ondate"
+msgstr "Ar %1$s"
+
+#: views/statistics/rss/summary.thtml:61 views/statistics/addon.thtml:203
+#, fuzzy
+msgid "statistics_summary_updatepings_weekly_average"
+msgstr "Average Daily Users this Week"
+
+#. %s is a percentage, like '+22.33%'. It sits next to another number, so
+#. the implied meaning is 'percentage change' from the previous stat point.
+#: views/statistics/rss/summary.thtml:62 views/statistics/addon.thtml:205
+#, fuzzy
+msgid "statistics_summary_updatepings_weekly_change"
+msgstr "%s from last week"
+
+#: views/statistics/addon.thtml:65 controllers/statistics_controller.php:184
+#: controllers/statistics_controller.php:282
+#, php-format
+msgid "statistics_title_addon_stats"
+msgstr "Ystadegau %1$s"
+
+#: views/addons/themes_landing.thtml:113
+msgid "themes_landing_all_themes"
+msgstr "Pob Thema"
+
+#: views/addons/themes_landing.thtml:109
+msgid "themes_landing_browse_themes"
+msgstr "Pori'r Themâu"
+
+#: views/users/edit.thtml:185
+#, fuzzy
+msgid "user_change_email"
+msgstr "Change Email Address"
+
+#: views/users/edit.thtml:169
+msgid "user_change_password"
+msgstr "Newid cyfrinair"
+
+#: views/users/edit.thtml:96
+#, fuzzy
+msgid "user_change_password_or_email"
+msgstr "Change Password or Email"
+
+#: controllers/users_controller.php:197
+msgid "user_confirmationcode_resent"
+msgstr "Mae'r cod cadarnhau wedi ei ail anfon!"
+
+#. %1 is the email address, %2 is the URL of the user registration page
+#: views/users/delete.thtml:51
+#, fuzzy
+msgid "user_del_account_deleted"
+msgstr ""
+"Your user account %1$s has been successfully deleted. If you want to come "
+"back some time, you can re-register on the <a href=\"%2$s\">user "
+"registration page</a>."
+
+#: views/users/delete.thtml:102
+#, fuzzy
+msgid "user_del_community_sad"
+msgstr "The Mozilla Add-ons community is sad to see you go."
+
+#: views/users/delete.thtml:123
+#, fuzzy
+msgid "user_del_confirm_password"
+msgstr "Confirm Password"
+
+#: views/users/delete.thtml:134
+#, fuzzy
+msgid "user_del_deletenow"
+msgstr "Delete my user account now"
+
+#. %1 is the URL of the user's info page
+#: views/users/delete.thtml:64
+#, fuzzy
+msgid "user_del_error_addons"
+msgstr ""
+"You cannot delete your account if you are listed as an <a href=\"%1$s"
+"\">author of any add-ons</a>. To delete your account, please have another "
+"person in your development group delete you from the list of authors for "
+"your add-ons. Afterwards you will be able to delete your account here."
+
+#. %1 is a link to the amo-editors mailing list
+#: views/users/delete.thtml:71
+#, fuzzy
+msgid "user_del_error_addons_more_questions"
+msgstr "If you have additional questions, please contact %1$s for assistance."
+
+#: views/users/delete.thtml:78
+#, fuzzy
+msgid "user_del_error_checkbox"
+msgstr ""
+"You need to check the box \"I understand...\" before we can delete your "
+"account."
+
+#: views/users/delete.thtml:84
+#, fuzzy
+msgid "user_del_error_password"
+msgstr "Please enter your password correctly in order to perform this step."
+
+#. %1 is a link to the amo-admins mailing list
+#: views/users/delete.thtml:91
+#, fuzzy
+msgid "user_del_error_unknown"
+msgstr ""
+"An unknown error occured deleting your account. Please contact %1$s with the "
+"issue and we will delete it for you. We apologize for the inconvenience."
+
+#: views/users/delete.thtml:110
+#, fuzzy
+msgid "user_del_header_confirm_deletion"
+msgstr "Confirm account deletion"
+
+#. %1 is the user's email address
+#: views/users/delete.thtml:100
+#, fuzzy
+msgid "user_del_header_delete_account"
+msgstr "Delete User Account %1$s"
+
+#: views/users/delete.thtml:50
+#, fuzzy
+msgid "user_del_header_farewell"
+msgstr "Farewell!"
+
+#: views/users/delete.thtml:115
+#, fuzzy
+msgid "user_del_nologin"
+msgstr "You will not be able to log into Mozilla Add-ons anymore."
+
+#: views/users/delete.thtml:112
+#, fuzzy
+msgid "user_del_permanently_removed_means"
+msgstr ""
+"By clicking \"delete\" your account is going to be <strong>permanently "
+"removed</strong>. That means:"
+
+#: views/users/delete.thtml:116
+#, fuzzy
+msgid "user_del_reviews_anonymized"
+msgstr ""
+"Your reviews and ratings will not be deleted, but they will no longer be "
+"associated with you."
+
+#. %1 is a link to the amo-editors mailing list
+#: views/users/delete.thtml:104
+#, fuzzy
+msgid "user_del_specific_problem_editors"
+msgstr ""
+"If you have a specific problem we may help you with, please do not delete "
+"your account now, but contact us at %1$s and we will do our best to assist "
+"you in solving it."
+
+#: views/users/delete.thtml:130
+#, fuzzy
+msgid "user_del_understand_permanent"
+msgstr "I understand that this step cannot be undone."
+
+#: views/helpers/addons_html.php:192
+#, fuzzy
+msgid "user_deleted_nickname"
+msgstr "Deleted User"
+
+#. %1 is the new email address
+#: views/users/edit.thtml:71
+#, fuzzy
+msgid "user_edit_confirm_email_sent"
+msgstr ""
+"An email has been sent to %1$s to confirm your new email address. For the "
+"change to take effect, you need to click on the link provided in this email. "
+"Until then, you can keep logging in with your current email address."
+
+#: views/users/edit.thtml:201
+#, fuzzy
+msgid "user_edit_delete_user"
+msgstr "Delete user account"
+
+#. This contains the email sent to users when they signed up for a new
+#. account:
+#. %1 is the confirmation URL, %2 is the current app
+#: views/users/email/confirm_plain.thtml:6
+#, php-format
+msgid "user_email_confirm_account_nopass"
+msgstr ""
+"Croeso i Ychwanegion %2$s.\n"
+"\n"
+"Cyn bod modd i ti ddefnyddio dy gyfrif newydd raid ei weithredu - mae hyn yn "
+"sicrhau fod y cyfeiriad e-bost rwyt ti'n ei ddefnyddio yn ddilys ac yn "
+"perthyn i ti.\n"
+"I weithredu dy gyfrif, clicia'r cyswllt isod neu gopïo a gludo'r holl beth i "
+"far lleoliad dy borwr:\n"
+"\n"
+"%1$s\n"
+"\n"
+"Unwaith i ti weithredu dy gyfrif yn llwyddiannus, gelli ddileu'r e-bost "
+"yma.\n"
+"\n"
+"Diolch am ymuno gydag Ychwanegion %2$s\n"
+"-- Staff Ychwanegion %2$s"
+
+#. %1 is the confirmation url, %2 is the application name
+#: views/users/email/emailchange_plain.thtml:5
+#, fuzzy
+msgid "user_email_confirm_emailchange"
+msgstr ""
+"You requested a change to your email address at %2$s Add-ons.\n"
+"\n"
+"In order to confirm the new address, please click the link below or copy and "
+"paste the whole thing into your browser's location bar:\n"
+"\n"
+"%1$s\n"
+"\n"
+"You have 48 hours to confirm the new address. If you do not want to change "
+"the address anymore, you can just ignore this email.\n"
+"\n"
+"Thanks!\n"
+"-- %2$s Add-ons Staff"
+
+#: controllers/users_controller.php:168
+#, php-format
+msgid "user_email_confirm_subject"
+msgstr "Diolch am ymuno gydag Ychwanegion %s"
+
+#. This is the password reset email
+#. %1 is the pw reset URL, %2 is the application
+#: views/users/email/pwreset_plain.thtml:5
+#, php-format
+msgid "user_email_pwreset"
+msgstr ""
+"Ailosod Cyfrinair Ychwanegion %2$s\n"
+"\n"
+"Derbyniwyd cais i ailosod y cyfrinair ar gyfer y cyfrif hwn ar addons."
+"mozilla.org. I newid y cyfrinair clicia’r cyswllt canlynol, neu ei ludo i'r "
+"bar lleoliad yn dy borwr:\n"
+"\n"
+"%1$s\n"
+"\n"
+"Os nad wyt wedi gofyn am yr e-bost hwn nid oes angen i ti wneud dim.\n"
+"\n"
+"Diolch,\n"
+"-- Staff Ychwanegion %2$s"
+
+#: controllers/users_controller.php:245
+#, php-format
+msgid "user_email_pwreset_subject"
+msgstr "Ailosod dy gyfrinair Ychwanegion %s"
+
+#: views/users/emailchange.thtml:50
+#, fuzzy
+msgid "user_emailchange_error"
+msgstr "Error!"
+
+#. %1 is the application name
+#: controllers/users_controller.php:533
+#, fuzzy
+msgid "user_emailchange_subject"
+msgstr "Please confirm your email address change at %1$s Add-ons"
+
+#: views/users/emailchange.thtml:48
+#, fuzzy
+msgid "user_emailchange_success"
+msgstr "Success!"
+
+#. %1 is the new email address
+#: views/users/emailchange.thtml:49
+#, fuzzy
+msgid "user_emailchange_successful_description"
+msgstr ""
+"Your email address was changed successfully. From now on, please use %1$s to "
+"log in."
+
+#: views/users/edit.thtml:134 views/admin/users_edit.thtml:111
+#, fuzzy
+msgid "user_form_bio"
+msgstr "About me"
+
+#: views/users/edit.thtml:135 views/admin/users_edit.thtml:112
+#, fuzzy
+msgid "user_form_bio_description"
+msgstr ""
+"Introduce yourself to the community, if you like! This text will appear "
+"publicly on your user info page. Line breaks will be preserved, but no HTML "
+"is allowed."
+
+#: views/users/pwreset.thtml:77 views/users/register.thtml:73
+#: views/users/edit.thtml:181
+msgid "user_form_confirmpassword"
+msgstr "Cadarnhau'r cyfrinair"
+
+#: views/users/edit.thtml:145
+#, fuzzy
+msgid "user_form_display_collections"
+msgstr "Display the collections I have created in my user profile"
+
+#: views/users/edit.thtml:149
+#, fuzzy
+msgid "user_form_display_collections_fav"
+msgstr "Display my favorite collections in my user profile"
+
+#: views/users/edit.thtml:86
+#, php-format
+msgid "user_form_editprofile"
+msgstr "Golygu proffil defnyddiwr ar gyfer %s"
+
+#: views/users/pwreset.thtml:52 views/users/login.thtml:81
+#: views/users/register.thtml:63 views/users/edit.thtml:187
+msgid "user_form_email"
+msgstr "Cyfeiriad e-bost"
+
+#: views/users/register.thtml:78 views/users/edit.thtml:103
+#: views/admin/users_edit.thtml:76
+msgid "user_form_firstname"
+msgstr "Enw cyntaf"
+
+#: views/users/register.thtml:94 views/users/edit.thtml:119
+#: views/admin/users_edit.thtml:91
+msgid "user_form_hideemail"
+msgstr "Cuddio'r cyfeiriad e-bost"
+
+#: views/users/register.thtml:98 views/users/edit.thtml:123
+#: views/admin/users_edit.thtml:99
+msgid "user_form_homepage"
+msgstr "URL y wefan"
+
+#: views/users/register.thtml:84 views/users/edit.thtml:109
+#: views/admin/users_edit.thtml:81
+msgid "user_form_lastname"
+msgstr "Enw olaf"
+
+#: controllers/users_controller.php:333
+msgid "user_form_login"
+msgstr "Mewngofnod Defnyddiwr"
+
+#: views/users/pwreset.thtml:72 views/users/edit.thtml:176
+msgid "user_form_newpassword"
+msgstr "Cyfrinair newydd"
+
+#: views/users/register.thtml:89 views/users/edit.thtml:114
+#: views/admin/users_edit.thtml:86
+msgid "user_form_nickname"
+msgstr "Llys enw"
+
+#: views/users/edit.thtml:171
+msgid "user_form_oldpassword"
+msgstr "Hen gyfrinair"
+
+#: views/users/edit.thtml:97 views/users/edit.thtml:200
+#, fuzzy
+msgid "user_form_otheractions"
+msgstr "Other Actions"
+
+#: views/users/login.thtml:85 views/users/register.thtml:68
+msgid "user_form_password"
+msgstr "Cyfrinair"
+
+#: controllers/users_controller.php:93
+msgid "user_form_registration"
+msgstr "Cofrestriad defnyddiwr Newydd"
+
+#: views/users/login.thtml:90
+#, fuzzy
+msgid "user_form_remember_me"
+msgstr "Remember me on this computer"
+
+#: views/admin/users_edit.thtml:95
+msgid "user_form_showsandbox"
+msgstr "Dangos y blwch tywod?"
+
+#: views/users/edit.thtml:205
+msgid "user_form_submit_edit"
+msgstr "Cadw"
+
+#: views/users/login.thtml:93
+msgid "user_form_submit_login"
+msgstr "Mewngofnodi"
+
+#: views/users/register.thtml:113
+msgid "user_form_submit_register"
+msgstr "Cofrestru"
+
+#: views/users/info.thtml:75
+#, php-format
+msgid "user_info_usersince"
+msgstr "%s defnyddiwr Ychwanegion ers"
+
+#: views/users/login.thtml:102
+msgid "user_login_register_link"
+msgstr "Creu cyfrif defnyddiwr newydd"
+
+#: views/users/edit.thtml:160
+#, fuzzy
+msgid "user_notifications_item_compat"
+msgstr "Add-on Compatibility (strongly recommended)"
+
+#: views/users/edit.thtml:161
+#, fuzzy
+msgid "user_notifications_item_events"
+msgstr "Upcoming events and contests"
+
+#: views/users/edit.thtml:156
+#, fuzzy
+msgid "user_notifications_none_available"
+msgstr "There are currently no notifications available for you to configure."
+
+#: views/users/edit.thtml:158
+#, fuzzy
+msgid "user_notifications_select_topics"
+msgstr ""
+"From time to time, Mozilla may send you email about upcoming releases and "
+"add-on events. Please select the topics you are interested in below:"
+
+#: views/users/edit.thtml:164
+#, fuzzy
+msgid "user_notifications_specific_contact"
+msgstr ""
+"Mozilla reserves the right to contact you individually about specific "
+"concerns with your hosted add-ons."
+
+#: controllers/users_controller.php:543
+msgid "user_profile_edit_error"
+msgstr "Roedd gwallau yn y newidiadau wnes ti. Cywira nhw a'u hail gyflwyno."
+
+#: controllers/users_controller.php:540
+msgid "user_profile_saved"
+msgstr "Diweddarwyd y proffil"
+
+#: views/users/pwreset.thtml:65
+#, php-format
+msgid "user_pwreset_for_email"
+msgstr "Ailosod y cyfrinair ar gyfer %s"
+
+#: controllers/users_controller.php:226
+msgid "user_pwreset_header"
+msgstr "Ailosod y Cyfrinair"
+
+#: views/users/login.thtml:103
+msgid "user_pwreset_link"
+msgstr "Wedi anghofio dy gyfrinair?"
+
+#: controllers/users_controller.php:248
+msgid "user_pwreset_link_sent"
+msgstr "Mae cyswllt ailosod dy gyfrinair wedi ei anfon at dy gyfeiriad e-bost."
+
+#: controllers/users_controller.php:304
+msgid "user_pwreset_okay"
+msgstr "Mae'r cyfrinair wedi ei ailosod yn llwyddiannus."
+
+#: views/users/pwreset.thtml:82
+msgid "user_pwreset_submit_changepw"
+msgstr "Cyflwyno newid i'r cyfrinair"
+
+#: views/users/pwreset.thtml:57
+msgid "user_pwreset_submit_sendlink"
+msgstr "Anfon cyswllt ailosod y cyfrinair"
+
+#: views/users/register_complete.thtml:51
+#, php-format
+msgid "user_register_amo_link"
+msgstr "%s Ychanegyn"
+
+#. %1 is the user's email address, %2 is the current app
+#: views/users/activatefirst.thtml:49
+#, php-format
+msgid "user_register_click_confirm_link"
+msgstr ""
+"Mae cyswllt ailosod dy gyfrinair wedi ei anfon at dy gyfeiriad e-bost %1$s. "
+"Rhaid i ti glicio arno cyn bod modd mewngofnodi i Ychwanegion %2$s."
+
+#. %1 is the user's email address
+#: views/users/register_complete.thtml:49
+#, php-format
+msgid "user_register_confirm_email_sent"
+msgstr ""
+"Mae e-bost wedi ei anfon at dy gyfeiriad %1$s i gadarnhau dy gyfrif. Cyn bod "
+"modd mewngofnodi, rhaid i ti weithredu dy gyfrif drwy glicio ar y cyswllt "
+"sydd wedi ei ddarparu gan yr e-bost hwn."
+
+#: views/users/activatefirst.thtml:51
+msgid "user_register_confirmation_link_text"
+msgstr "ailanfon y neges cadarnhau"
+
+#: views/users/register_complete.thtml:47
+msgid "user_register_congratulations"
+msgstr ""
+"Llongyfarchiadau! Mae dy gyfrif defnyddiwr wedi ei greu yn llwyddiannus."
+
+#: views/users/register.thtml:50
+#, fuzzy
+msgid "user_register_details"
+msgstr ""
+"<p>Registration on AMO is <strong>not required</strong> if you simply want "
+"to download and install public add-ons.</p><p>You only need to register if:</"
+"p><ul><li>You want to submit reviews for add-ons</li><li>You are an add-on "
+"developer and want to upload your add-on for hosting on AMO</li></ul><p>Upon "
+"successful registration, you will be sent a confirmation email to the "
+"address you provided. Please follow the instructions there to confirm your "
+"account.</p><p>If you like, you can read our <a href='%1$s' title='Legal "
+"Notices'>Legal Notices</a> and <a href='%2$s' title='Privacy Policy'>Privacy "
+"Policy</a>.</p>"
+
+#. %1 is the link to the "resend confirmation code" page
+#: views/users/activatefirst.thtml:51
+#, php-format
+msgid "user_register_resend_confirmation_link"
+msgstr ""
+"Os na wnes ti dderbyn yr e-bost cadarnhau, gwna'n siŵr fod dy wasanaeth e-"
+"bost heb ei farcio fel \"sbwriel\" neu \"sbam\". Os oes angen, mae modd "
+"cysylltu â %1$s ar yr e-bost uchod."
+
+#. %1 is the link to the Mozilla Add-ons front page
+#: views/users/register_complete.thtml:51
+#, php-format
+msgid "user_register_welcome"
+msgstr "Diolch am gofrestru a chroeso i %1$s!"
+
+#: views/users/register.thtml:49
+#, fuzzy
+msgid "user_register_welcome_header"
+msgstr "Welcome to addons.mozilla.org (AMO)!"
+
+#: views/users/register.thtml:81 views/users/edit.thtml:106
+#, fuzzy
+msgid "user_required_firstlast_or_nickname"
+msgstr "A first name, last name or nickname is required."
+
+#: views/users/edit.thtml:94 views/users/edit.thtml:142
+#, fuzzy
+msgid "user_tab_collections"
+msgstr "Collections"
+
+#: views/users/edit.thtml:95 views/users/edit.thtml:154
+#, fuzzy
+msgid "user_tab_notifications"
+msgstr "Notifications"
+
+#: views/users/edit.thtml:93 views/users/edit.thtml:101
+#, fuzzy
+msgid "user_tab_profile"
+msgstr "User Profile"
+
+#: controllers/users_controller.php:209
+msgid "user_verified_okay"
+msgstr "Wedi ei ddilysu'n llwyddiannus!"
+
+#: controllers/users_controller.php:723
+#, fuzzy
+msgid "users_delete_pagetitle"
+msgstr "Delete User Account"
+
+#: controllers/users_controller.php:414
+msgid "users_edit_pagetitle"
+msgstr "Golygu Cyfrif Defnyddiwr"
+
+#: views/users/info.thtml:71
+#, fuzzy
+msgid "users_info_aboutme"
+msgstr "About Me"
+
+#: views/users/info.thtml:96
+#, php-format
+msgid "users_info_addons_by_user"
+msgstr "Ychwanegion gan %1$s"
+
+#: views/users/info.thtml:51
+msgid "users_info_author_name"
+msgstr "Enw"
+
+#: views/users/info.thtml:48
+msgid "users_info_author_profile"
+msgstr "Proffil Defnyddiwr"
+
+#. %s is the user name
+#: views/users/info.thtml:137
+#, fuzzy
+msgid "users_info_collections_by_user"
+msgstr "Collections by %s"
+
+#: views/users/info.thtml:66
+msgid "users_info_email"
+msgstr "Cyfeiriad E-bost"
+
+#: views/users/info.thtml:155
+#, fuzzy
+msgid "users_info_fav_collections_by_user"
+msgstr "Favorite Collections"
+
+#: views/users/info.thtml:61
+msgid "users_info_homepage"
+msgstr "Tudalen Cartref"
+
+#: views/users/info.thtml:56
+msgid "users_info_nickname"
+msgstr "Llys Enw"
+
+#: controllers/users_controller.php:707
+#, php-format
+msgid "users_info_pagetitle"
+msgstr "Gwybodaeth Defnyddiwr %1$s"
+
+#. %1 is the user's name
+#: views/users/info.thtml:116
+#, fuzzy
+msgid "users_info_reviews_by_user"
+msgstr "Reviews by %s"
+
+#: controllers/users_controller.php:330 controllers/users_controller.php:332
+msgid "users_login_pagetitle"
+msgstr "Mewngofnod Defnyddiwr"
+
+#. %1 is the link to the sandbox/policy explanation page
+#. This message is for a specific add-on not found
+#: views/users/login.thtml:53
+#, php-format
+msgid "users_login_sandbox_display_warning"
+msgstr ""
+"Mae'r ychwanegyn rwyt yn chwilio amdano yn y blwch tywod. Os oes gennyt "
+"gyfrif yn Ychwanegion Mozilla, mewngofnoda, neu <a href=\"%1$s\"> dysga fwy "
+"am y blwch tywod.</a>"
+
+#. %1 is the link to the sandbox/policy explanation page
+#. This message is for any given sandbox-related page not found
+#: views/users/login.thtml:56
+#, php-format
+msgid "users_login_sandbox_page_warning"
+msgstr ""
+"Mae'r dudalen rwyt ti'nchwilio amdano yn rhan o'r blwch tywod. Os oes gennyt "
+"gyfrif yn Ychwanegion Mozilla, mewngofnoda, neu <a href=\"%1$s\"> dysga fwy "
+"am y blwch tywod.</a>"
+
+#: controllers/users_controller.php:223 controllers/users_controller.php:225
+msgid "users_pwreset_pagetitle"
+msgstr "Ailosod Cyfrinair Defnyddiwr"
+
+#: controllers/users_controller.php:90 controllers/users_controller.php:92
+msgid "users_register_pagetitle"
+msgstr "Cofrestru defnyddiwr Newydd"
+
+#. %1$s is an addon name, like <a>Firebug</a>
+#. %2$s is a version number, like <a>1.2</a>
+#: views/versions/license.thtml:52
+#, fuzzy
+msgid "versions_license_header_source"
+msgstr "Source code license for %1$s %2$s"
+
+#: views/addons/category_landing.thtml:147
+#, fuzzy
+msgid "view_recently_added"
+msgstr "View all recently added"
+
+#: views/addons/category_landing.thtml:161
+#, fuzzy
+msgid "view_top_downloads"
+msgstr "View all top downloads"
+
+#: views/addons/category_landing.thtml:175
+#, fuzzy
+msgid "view_top_rated"
+msgstr "View all top rated"
+
+#, fuzzy
+#~ msgid "addon_slider_tooltip_next"
+#~ msgstr "Next Add-on"
+
+#, fuzzy
+#~ msgid "addon_slider_tooltip_previous"
+#~ msgstr "Previous Add-on"
+
+#~ msgid "addon_versions_getlatesttext"
+#~ msgstr "Y fersiwn cydnaws diweddar yw"
+
+#~ msgid "addons_display_version_history"
+#~ msgstr "Hanes Llawn Bob Fersiwn"
+
+#, fuzzy
+#~ msgid "addons_home_newest_header"
+#~ msgstr "Newest:"
+
+#~ msgid "addons_home_popular_header"
+#~ msgstr "Mwyaf Poblogaidd:"
+
+#~ msgid "addons_home_recommended_header"
+#~ msgstr "Y Goreuon:"
+
+#, fuzzy
+#~ msgid "addons_home_updated_header"
+#~ msgstr "Recently Updated:"
+
+#~ msgid "addons_home_view_all"
+#~ msgstr "Gweld popeth"
+
+#~ msgid "category_extra_allrecommended"
+#~ msgstr "Gweld yr Ychwanegion Gorau"
+
+#~ msgid "category_extra_highestrated"
+#~ msgstr "Gradd Uchaf yn Gyntaf"
+
+#~ msgid "category_extra_lastupdated"
+#~ msgstr "Diweddarwyd Diwethaf yn Gyntaf"
+
+#~ msgid "category_extra_mostpopular"
+#~ msgstr "Mwyaf Poblogaidd yn Gyntaf"
+
+#, fuzzy
+#~ msgid "collections_detail_js_loading"
+#~ msgstr "Loading"
+
+#, fuzzy
+#~ msgid "collections_detail_more_info"
+#~ msgstr "Show More Info"
+
+#~ msgid "devcp_additem_firefox_notice"
+#~ msgstr ""
+#~ "Nid yw'r fersiwn yma o dy ychwanegyn yn honni cytunedd gyda Firefox %1$s. "
+#~ "Mae Mozilla yn disgwyl fersiwn nesaf o Firefox i gael ei ryddhau yn fuan, "
+#~ "felly profa'r ychwanegyn gyda'r fersiwn newydd a diweddaru'r wybodaeth "
+#~ "cytunedd. Mae modd cael mwy o wybodaeth yn fan <a href=\"%2$s\">hyn</a>. "
+#~ "Dim ond er gwybodaeth yw hyn ac mae modd parhau i gyflwyno'r fersiwn i "
+#~ "addons.mozilla.org."
+
+#~ msgid "devcp_addon_disabled_successfully"
+#~ msgstr "Ychwanegyn wedi ei anablu'n llwyddiannus"
+
+#~ msgid "devcp_addon_edit_pagetitle"
+#~ msgstr "Golygu Ychwanegyn"
+
+#~ msgid "devcp_addon_enabled_successfully"
+#~ msgstr "Ychwanegyn wedi ei alluogi'n llwyddiannus"
+
+#~ msgid "devcp_addon_field_description_displaytitle"
+#~ msgstr "Disgrifiad o Ychwanegyn"
+
+#~ msgid "devcp_addon_field_eula_displaytitle"
+#~ msgstr "EULA"
+
+#~ msgid "devcp_addon_field_homepage_displaytitle"
+#~ msgstr "Ychwanegu Tiudalen Cartref"
+
+#~ msgid "devcp_addon_field_name_displaytitle"
+#~ msgstr "Enw'r Ychwanegyn"
+
+#~ msgid "devcp_addon_field_privacy_displaytitle"
+#~ msgstr "Polisi Preifatrwydd"
+
+#~ msgid "devcp_addon_field_summary_displaytitle"
+#~ msgstr "Crynodeb Ychwanegion"
+
+#~ msgid "devcp_addon_field_supportemail_displaytitle"
+#~ msgstr "Cynnal E-bost"
+
+#~ msgid "devcp_addon_field_supporturl_displaytitle"
+#~ msgstr "Cynnal URL"
+
+#~ msgid "devcp_addon_field_versionnotes_displaytitle"
+#~ msgstr "Nodiadau'r Fersiwn"
+
+#~ msgid "devcp_addon_nominate_pagetitle"
+#~ msgstr "Enwebu Ychwanegyn"
+
+#~ msgid "devcp_addon_nominated_successfully"
+#~ msgstr "Enwebwyd Ychwanegyn yn llwyddiannus!"
+
+#, fuzzy
+#~ msgid "devcp_addon_status_criteria_review"
+#~ msgstr "Several user reviews of the add-on (may be external reviews)."
+
+#~ msgid "devcp_addon_submission_makechanges"
+#~ msgstr ""
+#~ "Dos i dudalen %1$s i wneud newidiadau i dy gyflwyniad, neu i %2$s i "
+#~ "ddychwelyd i Offer Datblygwyr."
+
+#~ msgid "devcp_addon_submission_makechanges_devcp_link"
+#~ msgstr "clicia yma"
+
+#~ msgid "devcp_addon_submission_makechanges_link"
+#~ msgstr "Golygu Ychwanegyn"
+
+#~ msgid "devcp_addon_submission_pending"
+#~ msgstr ""
+#~ "Mae'r fersiwn yma wedi ei osod yn y blwch tywod tra ei fod yn disgwyl "
+#~ "adolygiad gan brofwyr y blwch tywod a golygydd Ychwanegion Mozilla. "
+#~ "Byddi'n cael dy hysbysu pan fydd gweithred wedi digwydd."
+
+#~ msgid "devcp_addon_submission_sandbox_readmore"
+#~ msgstr "Gelli ddarllen mwy am System Adolygu Blwch Tywod %s."
+
+#~ msgid "devcp_addon_submission_sandbox_readmore_link"
+#~ msgstr "yma"
+
+#~ msgid "devcp_addon_submission_sandboxed"
+#~ msgstr ""
+#~ "Mae'r fersiwn yma wedi ei osod yn y blwch tywod ar gyfer Datblygwyr Uwch. "
+#~ "Er mwyn iddo gael ei ddangos ar y safle cyhoeddus, rhaid %s dy ychwanegyn "
+#~ "a mynd drwy broses adolygu."
+
+#~ msgid "devcp_addon_submission_sandboxed_nominate_link"
+#~ msgstr "enwebu"
+
+#~ msgid "devcp_addon_submission_success"
+#~ msgstr "Mae dy gyflwyniad o ychwanegyn wedi bod yn llwyddiant."
+
+#~ msgid "devcp_addon_submission_trusted_public"
+#~ msgstr ""
+#~ "Gan ein bod yn ymddiried yn dy ychwanegyn, mae'r fersiwn wedi cael ei "
+#~ "dderbyn yn awtomatig ar gyfer y man cyhoeddus."
+
+#~ msgid "devcp_addon_submit_pagetitle"
+#~ msgstr "Cyflwyno Ychwanegyn"
+
+#~ msgid "devcp_addon_updated_successfully"
+#~ msgstr "Ychwanegyn wedi ei ddiweddaru'n llwyddiannus"
+
+#~ msgid "devcp_addon_upload_preview"
+#~ msgstr ""
+#~ "Efallai y byddwch yn awyddus i %s gynyddu diddordeb yn eich ychwanegyn."
+
+#~ msgid "devcp_addon_upload_preview_link"
+#~ msgstr "llwytho'r rhagolwg"
+
+#~ msgid "devcp_author_lookup_none_found"
+#~ msgstr "Heb ganfod awdur [%s]"
+
+#~ msgid "devcp_author_lookup_remove"
+#~ msgstr "Tynnu"
+
+#~ msgid "devcp_button_cancel"
+#~ msgstr "Diddymu"
+
+#~ msgid "devcp_button_cancel_confirm"
+#~ msgstr "Ydych chi'n siŵr eich bod am ddiddymu eich cyflwyniad?"
+
+#~ msgid "devcp_button_next"
+#~ msgstr "Nesaf"
+
+#~ msgid "devcp_change_addontype"
+#~ msgstr "Newid y math o ychwanegyn:"
+
+#~ msgid "devcp_comments_updated"
+#~ msgstr "Diweddarwyd Sylwadau Datblygwyr"
+
+#~ msgid "devcp_details_addpreview_link"
+#~ msgstr "Ychwanegu Rhagolwg"
+
+#~ msgid "devcp_details_author"
+#~ msgstr "Awdur"
+
+#~ msgid "devcp_details_authors"
+#~ msgstr "Awduron"
+
+#~ msgid "devcp_details_authors_none"
+#~ msgstr "Dim"
+
+#~ msgid "devcp_details_categories"
+#~ msgstr "Categorïau"
+
+#~ msgid "devcp_details_category"
+#~ msgstr "Categori"
+
+#~ msgid "devcp_details_description"
+#~ msgstr "Disgrifiad"
+
+#~ msgid "devcp_details_disabled"
+#~ msgstr "Anablu"
+
+#~ msgid "devcp_details_guid"
+#~ msgstr "GUID"
+
+#~ msgid "devcp_details_header_details"
+#~ msgstr "Manylion"
+
+#~ msgid "devcp_details_header_devcomments"
+#~ msgstr "Sylwadau Datblygwyr"
+
+#~ msgid "devcp_details_header_previews"
+#~ msgstr "Rhagolygon"
+
+#~ msgid "devcp_details_header_versions"
+#~ msgstr "Fersiynau"
+
+#~ msgid "devcp_details_homepage"
+#~ msgstr "Tudalen Cartref"
+
+#~ msgid "devcp_details_homepage_none"
+#~ msgstr "Dim"
+
+#~ msgid "devcp_details_preview_nocaption"
+#~ msgstr "Dim pennawd"
+
+#~ msgid "devcp_details_previews_nonefound"
+#~ msgstr "Heb ganfod rhagolygon"
+
+#~ msgid "devcp_details_submit_update"
+#~ msgstr "Diweddaru"
+
+#~ msgid "devcp_details_supportemail"
+#~ msgstr "Cynnal E-bost"
+
+#~ msgid "devcp_details_supportemail_none"
+#~ msgstr "Dim e-bost cefnogi wedi ei ddarparu gan y datblygwr."
+
+#~ msgid "devcp_details_supporturl"
+#~ msgstr "URL Cefnogi"
+
+#~ msgid "devcp_details_supporturl_none"
+#~ msgstr "Dim url cefnogi wedi ei ddarparu gan y datblygwr."
+
+#~ msgid "devcp_details_trusted"
+#~ msgstr "Ymddiriedir"
+
+#~ msgid "devcp_details_versions_none_found"
+#~ msgstr "Heb ganfod fersiwn."
+
+#~ msgid "devcp_disable_cancel"
+#~ msgstr "Diddymu a mynd nôl"
+
+#~ msgid "devcp_disable_disable_button"
+#~ msgstr "Iawn, ei anablu"
+
+#~ msgid "devcp_disable_disable_confirm"
+#~ msgstr "Wyt ti'n siŵr dy fod am anablu'r ychwanegyn?"
+
+#~ msgid "devcp_disable_disable_description"
+#~ msgstr ""
+#~ "Bydd anablu'r ychwanegyn yn ei guddio rhag y chwilio a'r rhestrau. Ni "
+#~ "fydd modd ei lwytho i lawr o'r wefan ac ni fydd yn cael ei ddychwelyd "
+#~ "mewn gwiriad gan raglen diweddaru. Bydd yr ychwanegyn wedi ei ddileu i "
+#~ "bob pwrpas, er y bydd modd dychwelyd yma a'i ail alluogi."
+
+#~ msgid "devcp_disable_disable_title"
+#~ msgstr "Anablu %s"
+
+#~ msgid "devcp_disable_enable_button"
+#~ msgstr "Iawn, ei alluogi"
+
+#~ msgid "devcp_disable_enable_confirm"
+#~ msgstr "Wyt ti'n siŵr dy fod am alluogi yr ychwanegyn?"
+
+#~ msgid "devcp_disable_enable_description"
+#~ msgstr ""
+#~ "Bydd galluogi'r ychwanegyn yn achosi ei fod yn ymddangos wrth chwilio ac "
+#~ "mewn rhestrau. Bydd ar gael i'w lwytho i lawr o'r wefan a drwy wiriad "
+#~ "diweddaru'r rhaglen."
+
+#~ msgid "devcp_disable_enable_title"
+#~ msgstr "Galluogi %s"
+
+#~ msgid "devcp_edit_author_add"
+#~ msgstr "Ychwanegu Awdur"
+
+#~ msgid "devcp_edit_author_email"
+#~ msgstr "Cyfeiriad E-bost yr Awdur"
+
+#~ msgid "devcp_edit_author_remove"
+#~ msgstr "Tynnu"
+
+#~ msgid "devcp_edit_error_categories_unavailable"
+#~ msgstr "Does dim categorïau ar gael ar gyfer y math yma o ychwanegyn."
+
+#, fuzzy
+#~ msgid "devcp_edit_file_error_incomplete"
+#~ msgstr "Incomplete transfer"
+
+#, fuzzy
+#~ msgid "devcp_edit_file_error_no"
+#~ msgstr "No file uploaded"
+
+#, fuzzy
+#~ msgid "devcp_edit_file_error_size"
+#~ msgstr "Exceeds maximum upload size"
+
+#~ msgid "devcp_edit_header_authors"
+#~ msgstr "Awduron"
+
+#~ msgid "devcp_edit_icon_add_link"
+#~ msgstr "Ychwanegu Eicon"
+
+#~ msgid "devcp_edit_icon_change_link"
+#~ msgstr "Newid Eicon"
+
+#~ msgid "devcp_edit_label_allow_viewsource"
+#~ msgstr "Caniatáu i ddefnyddwyr weld y ffeiliau ffynhonnell ar-lein"
+
+#~ msgid "devcp_edit_label_categories"
+#~ msgstr "Categoriau"
+
+#~ msgid "devcp_edit_label_defaultlocale"
+#~ msgstr "Lleoliad Rhagosodedig"
+
+#~ msgid "devcp_edit_label_icon_delete"
+#~ msgstr "Dim ond tynnu'r eicon cyfredol"
+
+#~ msgid "devcp_edit_label_icon_new"
+#~ msgstr "Ffeil Eicon Newydd"
+
+#~ msgid "devcp_edit_label_info"
+#~ msgstr "Eicon"
+
+#~ msgid "devcp_edit_locale_disambiguation_explanation"
+#~ msgstr "gwybodaeth ychwanegol gryno (megis enw 'r lleoliad targed)"
+
+#~ msgid "devcp_edit_submit_update"
+#~ msgstr "Diweddaru"
+
+#~ msgid "devcp_edit_target_locale_explanation"
+#~ msgstr ""
+#~ "<a href=\"http://wiki.mozilla.org/L10n:Simple_locale_names\">enw lleoliad "
+#~ "syml</a>, megis 'cy-GB'"
+
+#~ msgid "devcp_editversion_checkedfiles_delete"
+#~ msgstr "bydd ffeiliau wedi eu ticio'n cael eu dilwu"
+
+#~ msgid "devcp_editversion_filename_size"
+#~ msgstr "%1$s (%2$s)"
+
+#~ msgid "devcp_editversion_label_files"
+#~ msgstr "Ffeiliau"
+
+#~ msgid "devcp_editversion_label_targetapps"
+#~ msgstr "Rhaglenni Targed"
+
+#~ msgid "devcp_editversion_nofiles"
+#~ msgstr "Dim ffeiliau."
+
+#~ msgid "devcp_editversion_reviewernotes"
+#~ msgstr "Nodiadau ar gyfer Adolygwyr"
+
+#~ msgid "devcp_editversion_submit_update"
+#~ msgstr "Diweddaru"
+
+#~ msgid "devcp_error_addon_field_summary_toolong"
+#~ msgstr ""
+#~ "Mae crynodebau wedi eu cyfyngu i ddim mwy na 250 nod.\n"
+#~ "(Rwyt wedi rhoi %s)"
+
+#~ msgid "devcp_error_addonname_not_unique"
+#~ msgstr ""
+#~ "Mae enw dy ychwanegyn eisoes yn y gronfa ddata. Gwna'n siŵr: <br /"
+#~ "><li>Bod dy GUIDau'n cyd-fynd. Y rheswm mwyaf cyffredin am y gwall hwn yw "
+#~ "nad yw'r GUIDau'n cyd-fynd.</li><li>Nad oes gennyt ddau gofnod yn y "
+#~ "gronfa ddata. Os oes, dylet ddiweddaru'r cofnod neu ei ddileu a cheisio "
+#~ "eto.</li>"
+
+#~ msgid "devcp_error_describe_changes"
+#~ msgstr "Disgrifia'r newidiadau sydd yn bodoli yn y diweddariad."
+
+#~ msgid "devcp_error_file_guids_dont_match"
+#~ msgstr "Nid yw pob ffeil GUIDau'n cyd-fynd"
+
+#~ msgid "devcp_error_identical_version_exists"
+#~ msgstr ""
+#~ "Mae fersiwn yn union yr un peth (%s) yn bodoli eisoes ar gyfer yr "
+#~ "ychwanegyn a'r platfform hwn."
+
+#~ msgid "devcp_error_nominate_message"
+#~ msgstr "Rhaid darparu'r wybodaeth gofynnwyd amdano ar gyfer enwebiad."
+
+#~ msgid "devcp_error_nominate_no_prerelease"
+#~ msgstr "Nid oes modd enwebu ychwanegyn cyn ei ryddhau."
+
+#~ msgid "devcp_error_nominate_sandbox_only"
+#~ msgstr ""
+#~ "Dim ond ychwanegion sydd eisoes yn y blwch tywod y mae modd eu henwebu."
+
+#~ msgid "devcp_error_saving"
+#~ msgstr "Digwyddodd gwall wrth geisio cadw dy ddata."
+
+#~ msgid "devcp_error_update_access_denied"
+#~ msgstr "Nid oes gennyt ganiatâd i ddiweddaru'r ychwanegyn."
+
+#~ msgid "devcp_file_addanother"
+#~ msgstr "Ychwanega Ffeil Platfform Arall"
+
+#~ msgid "devcp_form_author_add"
+#~ msgstr "Ychwanegu Awdur"
+
+#~ msgid "devcp_form_author_remove"
+#~ msgstr "Tynnu"
+
+#~ msgid "devcp_form_categories_nextstep"
+#~ msgstr ""
+#~ "Bydd categorïau ar gyfer dy fath newydd o ychwanegyn ar gael yn y cam "
+#~ "nesaf."
+
+#~ msgid "devcp_form_error_categories_unavailable"
+#~ msgstr "Nid oes categori ar gael ar gyfer y math yma o ychwanegyn."
+
+#~ msgid "devcp_form_error_description_notempty"
+#~ msgstr "Rhowch ddisgrifiad o dy ategyn."
+
+#~ msgid "devcp_form_error_name_required"
+#~ msgstr "Rho enw ar gyfer dy ychwanegyn."
+
+#~ msgid "devcp_form_error_select_addontype"
+#~ msgstr "Dewis y math o ychwanegyn rwyt ti'n ei gyflwyno."
+
+#~ msgid "devcp_form_error_summary_notempty"
+#~ msgstr "Rho grynodeb o dy ychwanegyn."
+
+#~ msgid "devcp_form_label_addonfile"
+#~ msgstr "Ffeil Ychwanegyn"
+
+#~ msgid "devcp_form_label_addonfile2"
+#~ msgstr "Ffeil Ychwanegyn 2"
+
+#~ msgid "devcp_form_label_addonfile3"
+#~ msgstr "Ffeil Ychwanegyn 3"
+
+#~ msgid "devcp_form_label_addontype"
+#~ msgstr "Math o Ychwanegyn"
+
+#~ msgid "devcp_form_label_allow_viewsource"
+#~ msgstr "Caniatáu i ddefnyddwyr weld ffeiliau'r ffynhonnell ar-lein."
+
+#~ msgid "devcp_form_label_author_email"
+#~ msgstr "Cyfeiriad E-bost yr Awdur"
+
+#~ msgid "devcp_form_label_authors"
+#~ msgstr "Awduron"
+
+#~ msgid "devcp_form_label_categories"
+#~ msgstr "Categorïau"
+
+#~ msgid "devcp_form_label_defaultlocale"
+#~ msgstr "Lleoliad Rhagosodedig"
+
+#~ msgid "devcp_form_label_description"
+#~ msgstr "Disgrifiad"
+
+#~ msgid "devcp_form_label_eula"
+#~ msgstr "Cytundeb Trwydded Defnyddiwr (EULA)"
+
+#~ msgid "devcp_form_label_externalsoftware"
+#~ msgstr "Mae'r ychwanegyn hwn angen meddalwedd allanol"
+
+#~ msgid "devcp_form_label_files"
+#~ msgstr "Ffeiliau"
+
+#~ msgid "devcp_form_label_homepage"
+#~ msgstr "Tudalen Cartref"
+
+#~ msgid "devcp_form_label_iconfile"
+#~ msgstr "Ffeil Eicon"
+
+#~ msgid "devcp_form_label_name"
+#~ msgstr "Enw"
+
+#~ msgid "devcp_form_label_platforms"
+#~ msgstr "Platfform sy'n Cael eu Cynnal"
+
+#~ msgid "devcp_form_label_prerelease"
+#~ msgstr "Fersiwn cyn rhyddhad yw hwn"
+
+#~ msgid "devcp_form_label_privacy"
+#~ msgstr "Polisi Preifatrwydd"
+
+#~ msgid "devcp_form_label_sitespecific"
+#~ msgstr "Mae hwn yn ychwanegyn gwefan benodol"
+
+#~ msgid "devcp_form_label_summary"
+#~ msgstr "Crynodeb"
+
+#~ msgid "devcp_form_label_supportemail"
+#~ msgstr "E-bost Cefnogi"
+
+#~ msgid "devcp_form_label_supporturl"
+#~ msgstr "URL Cefnogi"
+
+#~ msgid "devcp_form_label_target_applications"
+#~ msgstr "Rhaglenni Targed"
+
+#~ msgid "devcp_form_label_version"
+#~ msgstr "Fersiwn"
+
+#~ msgid "devcp_form_label_versionnotes"
+#~ msgstr "Nodiadau Fersiwn"
+
+#~ msgid "devcp_form_no_target_apps"
+#~ msgstr "Dim"
+
+#~ msgid "devcp_form_reviewernotes"
+#~ msgstr "Nodiadau ar gyfer yr Adolygwr"
+
+#~ msgid "devcp_form_trustedaddon_destination"
+#~ msgstr ""
+#~ "Gan fod dy ychwanegyn yn un dibynadwy, dewisa lle ddylai'r fersiwn yma "
+#~ "fynd:"
+
+#~ msgid "devcp_form_trustedaddon_destination_public"
+#~ msgstr "Cyhoeddus"
+
+#~ msgid "devcp_form_trustedaddon_destination_sandbox"
+#~ msgstr "Blwch Tywod"
+
+#~ msgid "devcp_header_developer_agreement"
+#~ msgstr "Cytundeb Datblygwr"
+
+#~ msgid "devcp_header_step1"
+#~ msgstr "Cam 1"
+
+#~ msgid "devcp_header_step1_upload"
+#~ msgstr "Llwytho Ffeil i Fyny"
+
+#~ msgid "devcp_header_step2"
+#~ msgstr "Cam 2"
+
+#~ msgid "devcp_header_step2_addondetails"
+#~ msgstr "Manylion Ychwanegyn"
+
+#~ msgid "devcp_header_step3"
+#~ msgstr "Cam 3"
+
+#~ msgid "devcp_header_step3_versiondetails"
+#~ msgstr "Manylion y Fersiwn"
+
+#~ msgid "devcp_header_step4"
+#~ msgstr "Cam 4"
+
+#~ msgid "devcp_header_step4_localization"
+#~ msgstr "Lleoleiddio"
+
+#~ msgid "devcp_header_step5"
+#~ msgstr "Cam 5"
+
+#~ msgid "devcp_header_step5_success"
+#~ msgstr "Llwyddiant"
+
+#~ msgid "devcp_index_header_myaddons"
+#~ msgstr "Fy Ychwanegion"
+
+#~ msgid "devcp_nominate_link_returnto_details"
+#~ msgstr "Nôl i fanylion ychwanegyn"
+
+#~ msgid "devcp_notice_autodetected_addontype"
+#~ msgstr "Wedi canfod yna awtomatig y math o ychwanegyn: %s."
+
+#~ msgid "devcp_notice_different_defaultlocale"
+#~ msgstr ""
+#~ "Mae locale'r ychwanegyn (%1$s [%2$s]) yn wahanol i'r locale rwyt ti wedi "
+#~ "ei ddewis (%3$s [%4$s]). Rhaid llawn y meysydd %1$s."
+
+#~ msgid "devcp_question_addontype_incorrect"
+#~ msgstr "Anghywir?"
+
+#~ msgid "devcp_question_delete_file"
+#~ msgstr "Wyt ti'n siŵr dy fod am ddileu'r ffeil?"
+
+#~ msgid "devcp_skip_reviewing_addon_info"
+#~ msgstr "Hepgor diweddaru fy ngwybodaeth gyfredol ar yr ychwanegyn"
+
+#~ msgid "devcp_submissions_disabled"
+#~ msgstr ""
+#~ "Mae cyflwyno ychwanegion wedi eu hanablu ar hyn o bryd. Dewch nôl eto."
+
+#~ msgid "devcp_submit_accept_dev_agreement"
+#~ msgstr "Rwy'n Derbyn"
+
+#~ msgid "devcp_submit_decline_dev_agreement"
+#~ msgstr "Rwy'n Gwrthod"
+
+#~ msgid "devcp_summary_admin_disabled"
+#~ msgstr "Mae'r ychwanegyn wedi ei anablu gan y gweinyddwr."
+
+#~ msgid "devcp_summary_header_disabled"
+#~ msgstr "Anablwyd"
+
+#~ msgid "devcp_summary_header_trusted"
+#~ msgstr "Ymddiriedwyr"
+
+#~ msgid "devcp_summary_noaddons_submit_one"
+#~ msgstr "Nid oes gennyt ychwanegion. Clicia %s i gyflwyno un."
+
+#~ msgid "devcp_summary_noaddons_submit_one_link"
+#~ msgstr "yma"
+
+#~ msgid "devcp_theme_upload_preview"
+#~ msgstr "Gwnewch yn siŵr eich bod %s ar gyfer eich thema."
+
+#~ msgid "devcp_theme_upload_preview_link"
+#~ msgstr "llwytho rhagolwg i fyny"
+
+#~ msgid "devcp_version_edit_pagetitle"
+#~ msgstr "Golygu Fersiwn"
+
+#~ msgid "devcp_version_updated_successfully"
+#~ msgstr "Diweddarwyd y fersiwn yn llwyddiannus."
+
+#~ msgid "editors_submissiontype_new"
+#~ msgstr "Newydd"
+
+#~ msgid "editors_submissiontype_updated"
+#~ msgstr "Diewddarwyd"
+
+#, fuzzy
+#~ msgid "editors_th_addon_age"
+#~ msgstr "Addon Age"
+
+#~ msgid "editors_th_addontypes"
+#~ msgstr "Math o Ychwanegyn"
+
+#~ msgid "editors_th_age"
+#~ msgstr "Oed"
+
+#~ msgid "editors_th_applications"
+#~ msgstr "Rhaglenni"
+
+#~ msgid "editors_th_platforms"
+#~ msgstr "Platfform"
+
+#~ msgid "editors_th_submissiontypes"
+#~ msgstr "Math o Gyflwyno"
+
+#~ msgid "error_notice"
+#~ msgstr "Hysbysiad"
+
+#~ msgid "forum_save"
+#~ msgstr "Cadw"
+
+#, fuzzy
+#~ msgid "home"
+#~ msgstr "home"
+
+#, fuzzy
+#~ msgid "nav_category_plugins"
+#~ msgstr "Plugins"
+
+#, fuzzy
+#~ msgid "page_title_experimental_addons"
+#~ msgstr "Experimental Add-ons"
+
+#, fuzzy
+#~ msgid "pages_experimental_addons_backbutton"
+#~ msgstr "Back to the previous page"
+
+#~ msgid "pagination_page_number_title"
+#~ msgstr "Dyma dudalen %1$s o %2$s"
+
+#~ msgid "search_matching_addons_number"
+#~ msgid_plural "search_matching_addons_number"
+#~ msgstr[0] "%s ychwanegyn sy'n cydweddu"
+#~ msgstr[1] "%s ychwanegyn sy'n cydweddu"
+
+#~ msgid "statistics_rss_icon_title"
+#~ msgstr "Llif RSS o grynodeb y data"
diff --git a/site/app/locale/cy/images/sandbox-review.png b/site/app/locale/cy/images/sandbox-review.png
new file mode 100644
index 0000000..7dd4734
--- /dev/null
+++ b/site/app/locale/cy/images/sandbox-review.png
Binary files differ
diff --git a/site/app/locale/da/LC_MESSAGES/da.txt b/site/app/locale/da/LC_MESSAGES/da.txt
new file mode 100644
index 0000000..5690fe4
--- /dev/null
+++ b/site/app/locale/da/LC_MESSAGES/da.txt
@@ -0,0 +1,2044 @@
+# Language en-US translations for addons.mozilla.org package.
+# Copyright (C) 2009 THE addons.mozilla.org'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the addons.mozilla.org package.
+# Automatically generated, 2009.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: addons\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2009-01-16 11:45-0800\n"
+"PO-Revision-Date: 2009-02-26 15:08-0800\n"
+"Last-Translator: Jesper Kristensen <www.mozilladanmark.dk>\n"
+"Language-Team: Danish\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+msgid "a_cancel_installation"
+msgstr "Annuller installation"
+
+#. This is the text that appears on buttons to download add-ons.
+#. %$1s is an optional string that only appears if the add-on is only available for
+#. a certain platform. Examples: (Windows) or (Linux)
+#. Note that the parenthesis are included in the string. :(
+#, php-format
+msgid "a_download"
+msgstr "Download nu %s"
+
+msgid "a_eula_download"
+msgstr "Accepter og download"
+
+msgid "a_eula_install"
+msgstr "Accepter og installer"
+
+msgid "a_header_public"
+msgstr "Offentlig"
+
+msgid "a_header_sandbox"
+msgstr "Sandkasse"
+
+#. %s is a date in the _('date') format
+msgid "addon_detail_last_updated"
+msgstr "Opdateret %s"
+
+#. %s is the version of the add-on. Example: 3.2a1
+#, php-format
+msgid "addon_display_header_version"
+msgstr "Version %s"
+
+msgid "addon_downloads"
+msgstr "downloads"
+
+msgid "addon_downloads_total"
+msgstr "downloads i alt"
+
+msgid "addon_downloads_weekly"
+msgstr "downloads pr. uge"
+
+#. %1 is the add-on count, %2 the category name
+#, php-format
+msgid "addon_list_category_totalcount"
+msgid_plural "addon_list_category_totalcount"
+msgstr[0] "%1$s tilføjelse"
+msgstr[1] "%1$s tilføjelser"
+
+msgid "addon_list_perpage"
+msgstr "pr. side"
+
+msgid "addon_list_sortby"
+msgstr "Sorter efter:"
+
+msgid "addon_listitem_flag_experimental"
+msgstr "eksperimentel"
+
+msgid "addon_listitem_flag_recommended"
+msgstr "anbefalet"
+
+#. %1 is the add-on name, %2 is the platform
+msgid "addon_not_available_for_platform"
+msgstr "%1$s er ikke tilgængelig til %2$s."
+
+#. %1 is the add-on name
+#, php-format
+msgid "addon_review_a_back_to_addon_x"
+msgstr "Tilbage til %1$s..."
+
+#. %1 is the add-on name
+#, php-format
+msgid "addon_review_a_back_to_reviews"
+msgstr "Tilbage til anmeldelser..."
+
+msgid "addon_review_add_rating_field"
+msgstr "Bedømmelse:"
+
+msgid "addon_review_add_review_field"
+msgstr "Anmeldelse:"
+
+msgid "addon_review_add_submit"
+msgstr "Indsend din anmeldelse"
+
+#. %s is the name of the add-on
+#, php-format
+msgid "addon_review_add_title"
+msgstr "Tilføj en anmeldelse af %s"
+
+msgid "addon_review_add_title_field"
+msgstr "Titel/resumé:"
+
+msgid "addon_review_admin_delete"
+msgstr "Slet"
+
+msgid "addon_review_author_reply_link"
+msgstr "Svar"
+
+msgid "addon_review_confirm_delete"
+msgstr "Er du sikker på, at du vil slette denne anmeldelse?"
+
+msgid "addon_review_confirm_no"
+msgstr "Nej"
+
+msgid "addon_review_confirm_yes"
+msgstr "Ja"
+
+msgid "addon_review_delete_header"
+msgstr "Slet anmeldelse"
+
+msgid "addon_review_deleted_successfully"
+msgstr "Anmeldelsen blev slettet."
+
+#. %s is the name of the add-on
+#, php-format
+msgid "addon_review_edit_title"
+msgstr "Ret anmeldelse af %s"
+
+#. %1 is the count of characters entered as notes for the review flag reason.
+msgid "addon_review_flag_error_other_length"
+msgstr ""
+"Problem ved rapporteringen af anmeldelse: Bemærkninger til rapporterede anmeldelser skal være på "
+"mellem 10 og 100 tegn. Du har skrevet %1$s tegn."
+
+#. Removing an extra comma
+msgid "addon_review_in_moderation"
+msgstr ""
+"Bemærk: Din anmeldelse vil blive gennemgået af en redaktør, før den kan ses "
+"på den offentlige side."
+
+msgid "addon_review_in_reply_to"
+msgstr "Udviklersvar til:"
+
+#. %1 is the review count, %2 is the nickname or full name of the user.
+#, php-format
+msgid "addon_review_others_by_user"
+msgid_plural "addon_review_others_by_user"
+msgstr[0] "Vis %1$s tidligere anmeldelse af denne tilføjelse indsendt af %2$s."
+msgstr[1] "Vis %1$s tidligere anmeldelser af denne tilføjelse indsendt af %2$s."
+
+#. %1 is the add-on name
+#, php-format
+msgid "addon_review_pagetitle"
+msgstr "Anmeldelser af %s"
+
+#. %1 is the user, %2 is the (localized) date
+#, php-format
+msgid "addon_review_reply_on_x_by_y"
+msgstr "Svar fra %1$s den %2$s"
+
+msgid "addon_review_reply_prefix"
+msgstr "Svar fra udvikleren:"
+
+msgid "addon_review_saved_successfully"
+msgstr "Din anmeldelse er gemt. Tak!"
+
+msgid "addon_reviewed_by_u_on_d"
+msgstr "af %1$s den %2$s"
+
+#. %1 is the user, %2 is the (localized) date, %3 is the rating
+#, php-format
+msgid "addon_reviewed_on_x_rated_y"
+msgstr "af %1$s den %2$s (bedømmelse %3$s)"
+
+msgid "addon_slider_tooltip_next"
+msgstr "Næste tilføjelse"
+
+msgid "addon_slider_tooltip_previous"
+msgstr "Forrige tilføjelse"
+
+msgid "addon_version_permalink"
+msgstr "Permanent link til denne version"
+
+#. %1 is the current Application name (e.g. Firefox)
+#. %2 is the Application's version number
+msgid "addon_versions_getlatestversion"
+msgstr "Seneste version, som er kompatibel med %1$s %2$s"
+
+msgid "addons_author_addons_submit"
+msgstr "Vis"
+
+msgid "addons_author_tooltip"
+msgstr "Vis forfatterens profil"
+
+#. %1 is the name of the Application (eg. Firefox)
+msgid "addons_browse_all_themes_title"
+msgstr "Gennemse alle temaer :: %1$s Add-ons"
+
+#. %s is the name of the category
+#, php-format
+msgid "addons_browse_browse_category"
+msgstr "Gennemse %s"
+
+#. %1 is the name of the theme category (eg. Modern)
+#. %2 is the name of the Application (eg. Firefox)
+msgid "addons_browse_categories_header_theme"
+msgstr "Gennemse temaer i kategorien %1$s :: %2$s Add-ons"
+
+msgid "addons_display_a_license_what"
+msgstr "Hvad er dette?"
+
+msgid "addons_display_add_review"
+msgstr "Tilføj en anmeldelse"
+
+msgid "addons_display_advanced_details"
+msgstr "Avancerede detaljer"
+
+msgid "addons_display_categories"
+msgstr "Kategorier"
+
+msgid "addons_display_detailed_review"
+msgstr "detaljeret anmeldelse"
+
+msgid "addons_display_dont_like_it"
+msgstr "Synes ikke om den"
+
+msgid "addons_display_edit_review"
+msgstr "Rediger din anmeldelse"
+
+msgid "addons_display_has_privacy"
+msgstr "Denne tilføjelse har en privatlivspolitik."
+
+msgid "addons_display_hate_it"
+msgstr "Hader den"
+
+msgid "addons_display_header_developer_comments"
+msgstr "Kommentarer fra udvikleren"
+
+msgid "addons_display_header_homepage"
+msgstr "Hjemmeside"
+
+msgid "addons_display_header_license"
+msgstr "Licens for kildekode"
+
+msgid "addons_display_header_reviews"
+msgstr "Anmeldelser"
+
+msgid "addons_display_header_support"
+msgstr "Support"
+
+msgid "addons_display_like_it"
+msgstr "Synes om den"
+
+msgid "addons_display_long_description"
+msgstr "Lang beskrivelse"
+
+msgid "addons_display_love_it"
+msgstr "Er vild med den"
+
+msgid "addons_display_more_images"
+msgstr "Flere billeder"
+
+#. %1$s is either an author's name or a comma separated list of authors. Using
+#. the list doesn't make sense in the English plural form so we ignore the
+#. variable.
+msgid "addons_display_other_addons_by"
+msgid_plural "addons_display_other_addons_by"
+msgstr[0] "Andre tilføjelser fra %1$s"
+msgstr[1] "Andre tilføjelser fra samme forfattere"
+
+#. %s is the name of the add-on and the add-on section. Example:
+#. Some Add-on :: Firefox Add-ons
+#. This should not be concatenated in the code and should be fixed.
+#, php-format
+msgid "addons_display_pagetitle"
+msgstr "%s"
+
+#. %s is an email address
+#, php-format
+msgid "addons_display_paragraph_supportinfoemail"
+msgstr "Support af denne tilføjelse tilbydes af udvikleren ved at kontakte %s"
+
+#. %$1s is a URL
+#. %$2s is an email address
+#, php-format
+msgid "addons_display_paragraph_supportinfoemailurl"
+msgstr ""
+"Support af denne tilføjelse tilbydes af udvikleren på %1$s eller ved at "
+"kontakte %2$s"
+
+#. %s is a URL
+#, php-format
+msgid "addons_display_paragraph_supportinfourl"
+msgstr "Support af denne tilføjelse tilbydes af udvikleren på %s"
+
+msgid "addons_display_rate_it"
+msgstr "Bedømmelse"
+
+msgid "addons_display_really_like_it"
+msgstr "Synes vældigt godt om den"
+
+msgid "addons_display_review_etiquette"
+msgstr ""
+"Lad venligst være med at sende fejlrapporter som anmeldelser. Vi videregiver ikke din e-mail-adresse "
+"til tilføjelsens udviklere, og de kan have behov for at kontakte dig for at "
+"løse problemet."
+
+#. %1 is the review guidelines link
+msgid "addons_display_review_guidelines_link"
+msgstr "<a href=\"%s\">Retningslinjer for anmeldelser</a>"
+
+#. %1 is the support section link
+msgid "addons_display_review_see_support"
+msgstr ""
+"Se <a href=\"%1$s\">supportafsnittet</a> for at finde ud af hvor du kan få "
+"hjælp til denne udvidelse."
+
+msgid "addons_display_review_submit"
+msgstr "Gem"
+
+#, php-format
+msgid "addons_display_see_all_addons"
+msgstr "Alle tilføjelser i kategorien %1$s"
+
+#. %1 is the number of reviews
+#, php-format
+msgid "addons_display_see_all_reviews"
+msgstr "Vis alle anmeldelser (%1$s)"
+
+msgid "addons_display_see_all_versions"
+msgstr "Vis alle versioner"
+
+msgid "addons_display_view_source"
+msgstr "Vis kildekoden"
+
+msgid "addons_display_view_stats"
+msgstr "Vis statistik"
+
+msgid "addons_display_what_do_you_think"
+msgstr "Hvad synes du?"
+
+msgid "addons_display_workswith"
+msgstr "Virker med:"
+
+msgid "addons_home_by"
+msgstr "af"
+
+msgid "addons_home_feature_head"
+msgstr "Vi anbefaler"
+
+#, php-format
+msgid "addons_home_header_details"
+msgstr ""
+"Tilføjelser udvider %1$s og giver dig mulighed for at skræddersy den efter "
+"dine behov. Se dig omkring, og gør %1$s til din egen."
+
+msgid "addons_home_newest_header"
+msgstr "Nyeste:"
+
+msgid "addons_home_other_applications"
+msgstr "Andre programmer"
+
+#. %1$s is the application the user is browsing. Examples: Thunderbird, Firefox,
+#. Sunbird
+#, php-format
+msgid "addons_home_pagetitle"
+msgstr "%1$s Add-ons"
+
+msgid "addons_home_popular_header"
+msgstr "Mest populære:"
+
+msgid "addons_home_recommended_header"
+msgstr "Vi anbefaler:"
+
+msgid "addons_home_updated_header"
+msgstr "Opdateret for nylig:"
+
+msgid "addons_home_view_all"
+msgstr "Vis alle"
+
+msgid "addons_home_view_all_newest_title"
+msgstr "Vis alle nyoprettede tilføjelser"
+
+msgid "addons_home_view_all_popular_title"
+msgstr "Vis alle populære tilføjelser"
+
+msgid "addons_home_view_all_recommended_title"
+msgstr "Vis alle anbefalede tilføjelser"
+
+msgid "addons_home_view_all_updated_title"
+msgstr "Vis alle nyligt opdaterede tilføjelser"
+
+msgid "addons_install_in_sunbird"
+msgstr ""
+"<ol><li>Klik på linket herunder for at gemme filen.</li><li>Åbn Mozilla Sunbird, "
+"og åbn Tilføjelser fra menuen Funktioner.</li><li>Klik på knappen "
+"Installer, find/marker filen, som du downloadede, og klik \"OK\".</li></ol>"
+
+msgid "addons_install_in_sunbird_title"
+msgstr "Hvordan du installerer i Sunbird"
+
+msgid "addons_install_in_thunderbird"
+msgstr ""
+"<ol><li>Klik på linket herunder for at gemme filen."
+"</li><li>Ã…bn Mozilla "
+"Thunderbird, og åbn Tilføjelser fra menuen Funktioner.</li><li>Klik på knappen "
+"Installer, find/marker filen, som du downloadede, og klik \"OK\".</li></ol>"
+
+msgid "addons_install_in_thunderbird_title"
+msgstr "Hvordan du installerer i Thunderbird"
+
+msgid "addons_options_show_experimental"
+msgstr "Vis eksperimentelle tilføjelser"
+
+msgid "addons_options_submit"
+msgstr "Opdater"
+
+msgid "addons_plugins_by"
+msgstr "Af"
+
+msgid "addons_plugins_for_linux"
+msgstr "til Linux"
+
+msgid "addons_plugins_for_macosx"
+msgstr "til Mac OS X"
+
+msgid "addons_plugins_for_windows"
+msgstr "til Windows"
+
+#. %1$s is a URL
+#, php-format
+msgid "addons_plugins_looking_for_more"
+msgstr ""
+"Denne side indeholder kun nogle af de mest almindelige og populære plugins. "
+"Besøg %1$s for at få mere at vide om andre plugins til Mozillabaserede "
+"browsere."
+
+msgid "addons_plugins_looking_for_plugin"
+msgstr "Leder du efter et plugin, som ikke er på listen?"
+
+msgid "addons_plugins_main_description"
+msgstr ""
+"Plugins hjælper din browser med specifikke funktioner, som fx at vise "
+"specielle grafikformater eller afspille multimediefiler. Plugins er en "
+"anelse anderledes end udvidelser, som ændrer eller udvider eksisterende funktionalitet."
+
+#. %1$s is the application name. Example: Firefox, Thunderbird, Sunbird
+#, php-format
+msgid "addons_plugins_main_header"
+msgstr "Almindelige plugins til %1$s"
+
+msgid "addons_plugins_pagetitle"
+msgstr "Plugins"
+
+msgid "addons_plugins_support_documentation"
+msgstr "Hjælp og dokumentation: "
+
+#. %s is the name of the add-on
+#, php-format
+msgid "addons_policy_eula_require"
+msgstr ""
+"%s kræver, at du accepterer følgende slutbrugerlicensaftale, før "
+"installationen kan fortsætte:"
+
+#. %1 is the add-on name
+#, php-format
+msgid "addons_previews_pagetitle"
+msgstr "Skærmbilleder af %s"
+
+msgid "addons_recently_added"
+msgstr "Tilføjet fornyligt"
+
+msgid "addons_recommended_introduction"
+msgstr ""
+"Med så mange fantastiske tilføjelser er der noget for enhver smag. Her er en "
+"liste over nogle af de mest populære, så du kan komme godt i gang."
+
+msgid "addons_recommended_pagetitle"
+msgstr "Anbefalede tilføjelser"
+
+msgid "addons_recommended_title"
+msgstr "Anbefalede tilføjelser"
+
+msgid "addons_searchengines_additional_resources"
+msgstr "Yderligere kilder"
+
+#. link text devmo
+msgid "addons_searchengines_devmo_link"
+msgstr "Mozilla Developer Center"
+
+msgid "addons_searchengines_error_mozilla_browser_required"
+msgstr ""
+"Desværre, du skal bruge en Mozillabaseret browser (eksempelvis Firefox) for "
+"at installere et søgeplugin."
+
+msgid "addons_searchengines_error_nojavascript"
+msgstr ""
+"Der kræves JavaScript for at installere søgeplugins, men det ser ud til, at "
+"du har slået det fra. Slå JavaScript til før du forsøger at installere nogen "
+"af søgepluginsne herunder."
+
+#. %1 is "make your own" link
+#. %2 is MDC link
+msgid "addons_searchengines_learn_howto"
+msgstr "Lær hvordan du %1$s hos %2$s."
+
+#. link path to search plugins instructions, relative to devmo
+msgid "addons_searchengines_makeyourown_href"
+msgstr "/en/docs/Creating_OpenSearch_plugins_for_Firefox"
+
+#. link text for "make your own" (opensearch engine)
+msgid "addons_searchengines_makeyourown_link"
+msgstr "laver din egen"
+
+#. %1 is the link to mycroft.mozdev.org
+msgid "addons_searchengines_more"
+msgstr "Find flere søgetjenester hos %1$s"
+
+#. link text to mycroft.mozdev.org
+msgid "addons_searchengines_mycroft_link"
+msgstr "mycroft.mozdev.org"
+
+msgid "addons_searchengines_pagetitle"
+msgstr "Søgemasikner"
+
+msgid "addons_searchengines_thanks"
+msgstr ""
+"Særligt tak til Mycroftprojektet for deres arbejder med søgetjenester til "
+"Firefox."
+
+msgid "addons_share_button_text"
+msgstr "Del dette"
+
+msgid "addons_share_label_delicious"
+msgstr "Tilføj til Delicious"
+
+msgid "addons_share_label_digg"
+msgstr "Tilføj til Digg"
+
+msgid "addons_share_label_facebook"
+msgstr "Besked på Facebook"
+
+msgid "addons_share_label_friendfeed"
+msgstr "Del på FriendFeed"
+
+msgid "addons_share_label_myspace"
+msgstr "Besked på MySpace"
+
+msgid "addons_status_disabled"
+msgstr "Deaktiveret"
+
+msgid "addons_status_incomplete"
+msgstr "Inkompatibel version"
+
+msgid "addons_status_nominated"
+msgstr "I sandkassen; Nomineret til at blive offentliggjort"
+
+msgid "addons_status_pending"
+msgstr "I sandkassen; Venter på anmeldelser"
+
+msgid "addons_status_public"
+msgstr "Offentliggjort"
+
+msgid "addons_status_sandbox"
+msgstr "I sandkassen"
+
+msgid "addons_status_unknown"
+msgstr "Ukendt"
+
+msgid "addons_title_tooltip"
+msgstr "Lær mere om denne tilføjelse"
+
+msgid "addons_top_downloads"
+msgstr "Flest downloads"
+
+msgid "addons_top_rated"
+msgstr "Bedste bedømmelse"
+
+msgid "addons_versions_careful"
+msgstr "Pas på med gamle versioner"
+
+msgid "addons_versions_careful_introduction"
+msgstr ""
+"Disse versioner vises som reference og til brug for test. Du bør altid "
+"anvende den nyeste udgave af en tilføjelse."
+
+msgid "addons_versions_history"
+msgstr "Versionshistorik med beskrivelse af ændringer"
+
+#. %1$s is the add-on name
+#, php-format
+msgid "addons_versions_pagetitle"
+msgstr "Versionshistorik for %1$s"
+
+msgid "admin_group_add_pagetitle"
+msgstr "Tilføj gruppe"
+
+msgid "admin_group_delete_pagetitle"
+msgstr "Slet gruppe"
+
+#. %s is a number to identify the group
+#, php-format
+msgid "admin_group_deleted"
+msgstr "Gruppen med id %s er slettet"
+
+msgid "admin_group_edit_pagetitle"
+msgstr "Ret gruppe"
+
+msgid "admin_group_error_invalid_id"
+msgstr "Ugyldigt id til gruppe"
+
+msgid "admin_group_pagetitle"
+msgstr "Gruppeadministration"
+
+msgid "admin_group_saved"
+msgstr "Gruppen er gemt"
+
+msgid "advanced_search_form"
+msgstr "Avanceret"
+
+msgid "advanced_search_form_any_time"
+msgstr "NÃ¥r som helst"
+
+msgid "advanced_search_form_any_type"
+msgstr "Enhver"
+
+msgid "advanced_search_form_any_version"
+msgstr "Enhver"
+
+msgid "advanced_search_form_application"
+msgstr "Program"
+
+msgid "advanced_search_form_keyword_match"
+msgstr "Relevans for søgningen"
+
+msgid "advanced_search_form_lastupdate"
+msgstr "Sidst opdateret"
+
+msgid "advanced_search_form_name"
+msgstr "Navn"
+
+msgid "advanced_search_form_newest"
+msgstr "Nyeste"
+
+msgid "advanced_search_form_past_3_months"
+msgstr "under 3 måneder siden"
+
+msgid "advanced_search_form_past_6_months"
+msgstr "under 6 måneder siden"
+
+msgid "advanced_search_form_past_day"
+msgstr "under et døgn siden"
+
+msgid "advanced_search_form_past_month"
+msgstr "under en måned siden"
+
+msgid "advanced_search_form_past_week"
+msgstr "under en uge siden"
+
+msgid "advanced_search_form_past_year"
+msgstr "under et år siden"
+
+msgid "advanced_search_form_perpage"
+msgstr "Pr. side"
+
+msgid "advanced_search_form_platform"
+msgstr "Platform"
+
+msgid "advanced_search_form_popularity"
+msgstr "Popularitet"
+
+msgid "advanced_search_form_rating"
+msgstr "Bedømmelse"
+
+msgid "advanced_search_form_sortby"
+msgstr "Sorter efter"
+
+msgid "advanced_search_form_to"
+msgstr "til"
+
+msgid "advanced_search_form_toggle_tooltip"
+msgstr "Skift mellem avanceret og simpel søgning"
+
+msgid "advanced_search_form_type"
+msgstr "Type"
+
+msgid "advanced_search_form_version"
+msgstr "version"
+
+msgid "app_compat_ignore_check"
+msgstr "Ignorer versionskontrol"
+
+msgid "app_compat_older_firefox_only"
+msgstr "Denne tilføjelse er til ældre versioner af Firefox"
+
+#. %1$s and %2$s are URLs
+msgid "app_compat_older_version_or_ignore_check"
+msgstr ""
+"Du kan <a href=\"%1$s\">prøve en ældre version</a> eller <a href=\"#\" onclick="
+"\"%2$s\">ignorere denne test</a>"
+
+#. %1$s is a URL
+msgid "app_compat_try_old_version"
+msgstr "En <a href=\"%1$s\">ældre version</a> vil måske virke"
+
+#. %1$s is a URL
+#. %2$s is a version number. Example: 3.1
+msgid "app_compat_unreleased_version"
+msgstr ""
+"Denne tilføjelse kræver <a href=\"%1$s\">Firefox %2$s</a>, som endnu ikke er udgivet"
+
+msgid "app_compat_update_firefox"
+msgstr ""
+"<a href=\"http://getfirefox.com\">Opdater Firefox</a> for at bruge denne tilføjelse"
+
+msgid "browse_addons_name"
+msgstr "Tilføjelser efter navn"
+
+msgid "browse_addons_newest"
+msgstr "Nyeste tilføjelser"
+
+msgid "browse_addons_popular"
+msgstr "Populære tilføjelser"
+
+msgid "browse_addons_rated"
+msgstr "Tilføjelser efter bedømmelse"
+
+msgid "browse_addons_updated"
+msgstr "Nyligt opdaterede tilføjelser"
+
+msgid "categories_current_title"
+msgstr "Nuværende kategori"
+
+msgid "categories_header"
+msgstr "Kategorier"
+
+msgid "categories_header_title"
+msgstr "Vælg en kategori"
+
+#. %1$s is the category name
+#, php-format
+msgid "category_extra_see_all"
+msgstr "Se alle tilføjelser i kategorien %1$s"
+
+#. %1$s is a number.
+msgid "collection_description_limit"
+msgstr "Beskrivelsen bør være mindre end %1$s tegn."
+
+#. %1$s is a number.
+msgid "collection_name_limit"
+msgstr "Navnet bør være mindre end %1$s tegn."
+
+msgid "collection_not_found"
+msgstr "Samlingen findes ikke!"
+
+#. %s is a date in the _('date') format
+#, php-format
+msgid "collections_interactive_addon_added"
+msgstr "Tilføjet %s"
+
+msgid "compatibility_dashboard_center_header"
+msgstr "Kompatibilitetscenter for tilføjelser"
+
+#. %1$s is the name of an application and a version. Example: Firefox 3.0
+#. %2$s is the name of an application. Example: Firefox
+msgid "compatibility_dashboard_intro"
+msgstr ""
+"Vær klar til udgivelsen af %1$s med værktøjerne og informationerne herunder."
+""
+
+msgid "compatibility_dashboard_loading"
+msgstr "Indlæser data..."
+
+msgid "compatibility_dashboard_main_link"
+msgstr "Tilbage til hovedsiden"
+
+msgid "compatibility_dashboard_report"
+msgstr "Kompatibilitetsrapport for tilføjelser"
+
+msgid "compatibility_developer_info"
+msgstr "Information til udviklere af tilføjelser"
+
+msgid "compatibility_developers_adjust_maxversion"
+msgstr "Juster maxVersion uden at uploade"
+
+msgid "compatibility_developers_check_status"
+msgstr "Kontroller status for mine tilføjelser"
+
+#. %1$s is a URL
+#. %2$s is an application and version. Example: Firefox 3.0
+msgid "compatibility_developers_login_first"
+msgstr ""
+"Hvis du har tilføjelser hostet på Mozilla Add-ons, kan du <a href=\"%1$s\">logge "
+"ind</a> for at se status for dine tilføjelser relateret til %2$s."
+
+msgid "compatibility_developers_mdclogo_alt"
+msgstr "Logo for Mozilla Developer Center"
+
+msgid "compatibility_developers_no_addons"
+msgstr "Du har ingen tilføjelser, som hostes af Mozilla Add-ons."
+
+msgid "compatibility_developers_results"
+msgstr "Resultat af statustjek"
+
+msgid "compatibility_developers_retrieving"
+msgstr "Indlæser status for tilføjelser..."
+
+#. %1$s is a number
+#. %2$s is an application name
+#. %3$s is a number.
+#. Full example: 50 Firefox users (10% of total)
+msgid "compatibility_developers_user_count"
+msgstr "%1$s brugere af %2$s (%3$s&#37; af alle)"
+
+msgid "compatibility_report_detail_intro"
+msgstr ""
+"Tilføjelserne herunder udgør 95% af den del af tilføjelsesbrugen som Mozilla kender til og er "
+"ordnet efter antal brugere."
+
+msgid "compatibility_report_detailed_link"
+msgstr "Vis detaljeret rapport"
+
+#. %1$s and %2$s are numbers
+#. %3$s is an application name and version. Example: Firefox 3.1
+msgid "compatibility_report_intro"
+msgstr ""
+"Af de %1$s tilføjelser, som udgør 95&#37; af den del af tilføjelsesbrugen som Mozilla kender til, "
+"er <b>%2$s&#37;</b> i øjeblikket kompatible med de seneste udgaver "
+"af %3$s."
+
+msgid "compatibility_report_legend_alpha"
+msgstr "Alfaversioner"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+msgid "compatibility_report_legend_alpha_description"
+msgstr "Tilføjelser som er kompatible med en alfaversion af %1$s"
+
+msgid "compatibility_report_legend_beta"
+msgstr "Betaversioner"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+msgid "compatibility_report_legend_beta_description"
+msgstr "Tilføjelser som er kompatible med en betaversion eller release candidate af %1$s"
+
+msgid "compatibility_report_legend_latest"
+msgstr "Seneste version"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+msgid "compatibility_report_legend_latest_description"
+msgstr "Tilføjelser som er opdateret til de seneste udgaver af %1$s"
+
+msgid "compatibility_report_legend_other"
+msgstr "Andre versioner"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+msgid "compatibility_report_legend_other_description"
+msgstr "Tilføjelser som ikke er kompatible med nogen versioner af %1$s"
+
+msgid "compatibility_report_title"
+msgstr "Kompatibilitetsrapport for tilføjelser"
+
+msgid "compatibility_user_info"
+msgstr "Information til brugere af tilføjelser"
+
+msgid "compatibility_view_report"
+msgstr "Vis kompatibilitetsrapport"
+
+#. %s is a URL
+#, php-format
+msgid "credits_contributing"
+msgstr "Se hvodan du selv kan bidrage på %s."
+
+msgid "credits_contributing_wikipage"
+msgstr "vores wikiside"
+
+msgid "credits_intro"
+msgstr ""
+"Mozilla vil gerne takke følgende personer for deres bidrag til "
+"addons.mozilla.org gennem årene:"
+
+msgid "credits_section_developers"
+msgstr "Udviklere"
+
+msgid "credits_section_editors"
+msgstr "Redaktører"
+
+msgid "credits_section_localizers"
+msgstr "Oversættere"
+
+msgid "credits_section_other_contributors"
+msgstr "Andre bidragydere"
+
+msgid "credits_section_past_developers"
+msgstr "Forhenværende udviklere"
+
+msgid "credits_section_software"
+msgstr "Software og billeder"
+
+msgid "credits_software_famfamfam"
+msgstr ""
+"Visse ikoner på siden er fra <a href=\"http://www.famfamfam.com/lab/icons/"
+"silk/\">famfamfam Silk Icon Set</a>, givet i licens under <a href=\"http://"
+"creativecommons.org/licenses/by/2.5/\">Creative Commons Navngivelse 2.5 "
+"Licens</a>."
+
+msgid "credits_software_timeplot"
+msgstr ""
+"Nogle sider bruger elementer fra <a href=\"http://www.simile-widgets.org/timeplot/"
+"\">Timeplot</a>, givet i licens under en <a href=\"http://simile.mit.edu/license."
+"html\">BSD-licens</a>."
+
+#. date format string as used in PHP's strftime():
+#. http://php.net/strftime
+msgid "date"
+msgstr "%e. %B %Y"
+
+#. date and time format string (strftime)
+#. http://php.net/strftime
+msgid "datetime"
+msgstr "%e. %B %Y, %H:%M"
+
+msgid "downloads_disable_warning"
+msgstr "Denne tilføjelse er deaktiveret"
+
+msgid "error_access_denied"
+msgstr "Ingen adgang"
+
+msgid "error_access_denied_message"
+msgstr "Du har ikke adgang til at se denne side."
+
+msgid "error_addon_notfound"
+msgstr "Tilføjelse ikke fundet!"
+
+msgid "error_addon_notviewable"
+msgstr "Tilføjelsen kan ikke vises her."
+
+msgid "error_addon_selfreview"
+msgstr "Du kan ikke anmelde din egen tilføjelse."
+
+msgid "error_browse_no_addons"
+msgstr "Ingen tilføjelser i denne kategori!"
+
+msgid "error_collection_feed_notfound"
+msgstr "Tilføjelsesfeed ikke fundet."
+
+msgid "error_email_invalid"
+msgstr "Dette er ikke en gyldig e-mail-adresse."
+
+msgid "error_field_required"
+msgstr "Dette felt skal udfyldes."
+
+msgid "error_file_notfound"
+msgstr "Fil ikke fundet!"
+
+#. %s is a filename
+#, php-format
+msgid "error_file_x_notfound"
+msgstr "Fejl: Filen %s eksisterer ikke."
+
+msgid "error_formerrors"
+msgstr "Der er fejl i denne formular. Ret dem venligst og indsend igen."
+
+msgid "error_invalid_captcha"
+msgstr "Vi var ikke i stand til at finde ud af, om du er et menneske eller en robot. Prøv igen."
+
+msgid "error_invalid_url"
+msgstr ""
+"Denne URL har et ugyldigt format. Gyldige URLs ligner http://example.com/"
+"min_side."
+
+#. %s is a string representing what's missing. Example: file_id
+#, php-format
+msgid "error_missing_argument"
+msgstr "Manglende argument: %s"
+
+msgid "error_no_files_in_addon"
+msgstr "Ingen filer"
+
+msgid "error_preview_notfound"
+msgstr "Skærmbillede ikke fundet!"
+
+msgid "error_review_rating_required"
+msgstr "Du skal give en bedømmelse."
+
+msgid "error_user_already_confirmed"
+msgstr "Brugerkontoen er allerede bekræftet."
+
+msgid "error_user_badconfirmationcode"
+msgstr "Ugyldig bekræftelseskode!"
+
+msgid "error_user_confirmpw_nomatch"
+msgstr "Adgangskoderne matchede ikke."
+
+msgid "error_user_email_notunique"
+msgstr "Denne e-mail-adresse anvendes allerede af en anden bruger."
+
+msgid "error_user_emailchange_expired"
+msgstr ""
+"E-mail ændringen er udløbet. Du bedes rette din e-mail-adresse igen i din "
+"brugerprofil og klikke på linket i bekræftelsesmailen så snart du modtager "
+"den."
+
+msgid "error_user_nickname_notunique"
+msgstr "Kaldenavnet er allerede i brug."
+
+msgid "error_user_notfound"
+msgstr "Bruger ikke fundet!"
+
+msgid "error_user_unconfirmed"
+msgstr ""
+"Bekræft venligst først din brugerkonto med koden, du modtog via e-mail."
+
+msgid "error_username_or_pw_wrong"
+msgstr "Forkert brugernavn eller adgangskode!"
+
+msgid "error_version_notfound"
+msgstr "Version ikke fundet!"
+
+msgid "error_wrong_password"
+msgstr "Forkert adgangskode!"
+
+msgid "feature_learnmore"
+msgstr "Lær mere"
+
+#. %1 is the add-on name
+#, php-format
+msgid "feature_learnmore_about_addon"
+msgstr "Lær mere om %1$s"
+
+#. %1$s is a number
+#, php-format
+msgid "feature_reviews"
+msgid_plural "feature_reviews"
+msgstr[0] "%1$s anmeldelse"
+msgstr[1] "%1$s anmeldelser"
+
+msgid "feature_view_more_from_category"
+msgstr "Vis mere fra"
+
+#. This appears on a page that views the source of an add-on. This link will return
+#. the user to the add-on's main page
+msgid "file_browser_link_addon"
+msgstr "Tilbage til tilføjelsen"
+
+#. There is a list of directories and files on the page. Clicking this will show the
+#. contents of all the directories (normally you would click on each one to see the
+#. contents)
+msgid "file_browser_link_expand_all"
+msgstr "Vis alle"
+
+#. This appears on a page that views the source of an add-on. This link will return
+#. the user to the add-on's review page (it only appears if the add-on is being
+#. reviewed)
+msgid "file_browser_link_review"
+msgstr "Tilbage til anmeldelse"
+
+#. The title of the page for viewing an add-on's source.
+#. %1$s is the name of the add-on
+#. %2$s is the name of the current application (e.g. Firefox or Thunderbird)
+msgid "file_browser_title"
+msgstr "%1$s :: Filbrowser :: %2$s Add-ons"
+
+#. This appears on a page that views the source of an add-on. There is a list of
+#. directories and files on the page. Clicking this link will toggle between an
+#. expanded or a collapsed list. This string should be kept short.
+msgid "file_browser_toggle_expand_collapse"
+msgstr "+/-"
+
+#. Link text for the AMO About page.
+msgid "footer_a_about"
+msgstr "Om"
+
+#. Link text to the AMO blog.
+msgid "footer_a_blog"
+msgstr "Blog"
+
+#. Link text to the Frequently Asked Questions page.
+msgid "footer_a_faq"
+msgstr "FAQ"
+
+#. Full text for the FAQ abbreviation.
+msgid "footer_abbr_faq"
+msgstr "Frequently Asked Questions"
+
+msgid "footer_all_rights_reserved"
+msgstr "Alle rettigheder forbeholdes."
+
+msgid "footer_copyright"
+msgstr "Copyright"
+
+msgid "footer_credits"
+msgstr "Tak til"
+
+msgid "footer_disclaimer"
+msgstr ""
+"Mozilla linker til disse programmer som en ekstra service og repræsenterer "
+"på ingen måde programmet eller enhver information relateret til dette. Alle "
+"spørgsmål, klager eller krav vedrørende programmerne skal sendes til "
+"softwareudgiveren."
+
+msgid "footer_lang_form_lang_submit_go"
+msgstr "Skift"
+
+msgid "footer_legal_notices"
+msgstr "Juridiske betingelser"
+
+msgid "footer_other_languages"
+msgstr "Andre sprog:"
+
+msgid "footer_privacy_policy"
+msgstr "Privatlivspolitik"
+
+msgid "general_addontype_dict"
+msgstr "Ordbog"
+
+#. Plural in this context means many of the add-on type
+msgid "general_addontype_dict_plural"
+msgstr "Ordbøger"
+
+msgid "general_addontype_extension"
+msgstr "Udvidelse"
+
+#. Plural in this context means many of the add-on type
+msgid "general_addontype_extension_plural"
+msgstr "Udvidelser"
+
+msgid "general_addontype_lpaddon"
+msgstr "Sprogpakke (tilføjelse)"
+
+#. Plural in this context means many of the add-on type
+msgid "general_addontype_lpaddon_plural"
+msgstr "Sprogpakker (tilføjelse)"
+
+msgid "general_addontype_lpapp"
+msgstr "Sprogpakke (program)"
+
+#. Plural in this context means many of the add-on type
+msgid "general_addontype_lpapp_plural"
+msgstr "Sprogpakker (program)"
+
+msgid "general_addontype_plugin"
+msgstr "Plugin"
+
+#. Plural in this context means many of the add-on type
+msgid "general_addontype_plugin_plural"
+msgstr "Plugins"
+
+msgid "general_addontype_search"
+msgstr "Søgetjeneste"
+
+#. Plural in this context means many of the add-on type
+msgid "general_addontype_search_plural"
+msgstr "Søgetjenester"
+
+msgid "general_addontype_theme"
+msgstr "Tema"
+
+#. Plural in this context means many of the add-on type
+msgid "general_addontype_theme_plural"
+msgstr "Temaer"
+
+#. %1$s is the application name. Example: Firefox
+#, php-format
+msgid "header_home_tooltip"
+msgstr "Tilbage til startsiden for %1$s Add-ons"
+
+msgid "header_main_firefox_header"
+msgstr "Firefox Add-ons"
+
+msgid "header_main_header"
+msgstr "Tilføjelser"
+
+msgid "header_main_seamonkey_header"
+msgstr "SeaMonkey Add-ons"
+
+msgid "header_main_sunbird_header"
+msgstr "Sunbird Add-ons"
+
+msgid "header_main_thunderbird_header"
+msgstr "Thunderbird Add-ons"
+
+msgid "header_navlink_addons"
+msgstr "Tilføjelser"
+
+msgid "header_navlink_login"
+msgstr "Log ind"
+
+msgid "header_navlink_logout"
+msgstr "Log ud"
+
+msgid "header_navlink_myaccount"
+msgstr "Min konto"
+
+msgid "header_navlink_register"
+msgstr "Registrer"
+
+msgid "home"
+msgstr "hjem"
+
+#. %s is the add-on name
+#, php-format
+msgid "img_preview_of"
+msgstr "Skærmbillede af %s"
+
+#. %1 is the login URL for the link tag
+#. %2 is the link to an explanatory page.
+msgid "install_a_login_to_install"
+msgstr ""
+"<a href=\"%1$s\">Log ind</a> for at installere denne tilføjelse. <a href=\"%2"
+"$s\">Hvorfor</a>?"
+
+#. %1 is the URL for the Experimental Add-ons section of the FAQ page
+msgid "install_button_confirm_exp_install"
+msgstr ""
+"Lad mig installere denne eksperimentelle tilføjelse. <a href=\"%1$s\">Hvad er det?</a>"
+
+#. %1$s is the application name. Example: Firefox
+#. %2$s is an optional string used to specify a platform. Example: (Windows)
+#, php-format
+msgid "install_button_text"
+msgstr "Tilføj til %1$s %2$s"
+
+#. %1 is the add-on name, %2 is the app name
+#, php-format
+msgid "install_button_title"
+msgstr "Tilføj %1$s til %2$s"
+
+#. %1$s is the add-on name
+#, php-format
+msgid "install_download"
+msgstr "Download %1$s"
+
+msgid "install_error_addon_not_found"
+msgstr "Denne tilføjelse er ikke tilgængelig."
+
+msgid "langtools_a11y_tablesummary"
+msgstr "Liste over sprogpakker og ordbøger."
+
+msgid "langtools_download_dictionary"
+msgstr "Download ordbog"
+
+msgid "langtools_download_langpack"
+msgstr "Download sprogpakke"
+
+msgid "langtools_header_dicts_and_langpacks"
+msgstr "Ordbøger & sprogpakker"
+
+msgid "langtools_install_dictionary"
+msgstr "Installer ordbog"
+
+msgid "langtools_install_langpack"
+msgstr "Installer sprogpakke"
+
+msgid "langtools_tableheader_dictionary"
+msgstr "Ordbog"
+
+msgid "langtools_tableheader_langpack"
+msgstr "Sprogpakke"
+
+msgid "langtools_tableheader_language"
+msgstr "Sprog"
+
+msgid "license_custom"
+msgstr "Anden licens"
+
+msgid "licenses_bsd"
+msgstr "BSD-licens"
+
+msgid "licenses_gpl_2.0"
+msgstr "GNU General Public License, version 2.0"
+
+msgid "licenses_gpl_3.0"
+msgstr "GNU General Public License, version 3.0"
+
+msgid "licenses_lgpl_2.1"
+msgstr "GNU Lesser General Public License, version 2.1"
+
+msgid "licenses_lgpl_3.0"
+msgstr "GNU Lesser General Public License, version 3.0"
+
+msgid "licenses_mit"
+msgstr "MIT/X11-licens"
+
+msgid "licenses_mpl_1.1"
+msgstr "Mozilla Public License, version 1.1"
+
+msgid "link_return_to_front_page"
+msgstr "Klik her for at komme tilbage til forsiden."
+
+msgid "list_sortby_date"
+msgstr "Dato"
+
+msgid "list_sortby_downloads"
+msgstr "Downloads"
+
+msgid "list_sortby_name"
+msgstr "Navn"
+
+msgid "list_sortby_rating"
+msgstr "Bedømmelse"
+
+msgid "main_prettyname_fennec"
+msgstr "Fennec"
+
+msgid "main_prettyname_firefox"
+msgstr "Firefox"
+
+msgid "main_prettyname_seamonkey"
+msgstr "SeaMonkey"
+
+msgid "main_prettyname_sunbird"
+msgstr "Sunbird"
+
+msgid "main_prettyname_thunderbird"
+msgstr "Thunderbird"
+
+msgid "nav_category_dicts_langpacks"
+msgstr "Ordbøger & sprogpakker"
+
+msgid "nav_category_themes"
+msgstr "Temaer"
+
+msgid "other_apps_tooltip"
+msgstr "Find tilføjelser til andre programmer"
+
+#. In a user list: user 1, user 2, "others"
+msgid "other_users"
+msgstr "andre"
+
+msgid "page_title_appversions"
+msgstr "Application Versions"
+
+msgid "page_title_credits"
+msgstr "Tak til"
+
+msgid "page_title_developer_faq"
+msgstr "Developer FAQ"
+
+msgid "page_title_faq"
+msgstr "Ofte stillede spørgsmål"
+
+msgid "page_title_fashionyourfirefox_faq"
+msgstr "Fashion your Firefox FAQ"
+
+msgid "page_title_policy"
+msgstr "Add-ons Policy"
+
+msgid "page_title_privacy"
+msgstr "Mozilla Privacy Policy"
+
+msgid "page_title_review_guide"
+msgstr "Retningslinjer for anmeldelser"
+
+msgid "page_title_sandbox"
+msgstr "Sandkassegodkendelsessystemet"
+
+msgid "page_title_submissionhelp"
+msgstr "Submission Help"
+
+msgid "pages_appversions_guid"
+msgstr "GUID"
+
+msgid "pages_appversions_header"
+msgstr "Valid Application Versions"
+
+msgid "pages_appversions_intro"
+msgstr ""
+"Add-ons submitted to Mozilla Add-ons must have an install.rdf file with at "
+"least one of the below applications supported. Only the versions listed "
+"below are allowed for these applications."
+
+#. %s is a full <a> tag
+#, php-format
+msgid "pages_appversions_required_files"
+msgstr ""
+"If your supported application does not require an install.rdf file, you "
+"still must include one with the required properties as specified %s."
+
+#. this is the text inside of an <a> tag for pages_appversions_required_files. This
+#. should be fixed.
+msgid "pages_appversions_required_files_link"
+msgstr "here"
+
+msgid "pages_appversions_versions"
+msgstr "Versions"
+
+msgid "pages_policy_sandbox_link"
+msgstr "Sandbox Information Page"
+
+msgid "pagination_next_page"
+msgstr "næste"
+
+#. %1 is page number, %2 is total page count
+#, php-format
+msgid "pagination_page_number_title"
+msgstr "Dette er side %1$s af %2$s"
+
+msgid "pagination_previous_page"
+msgstr "forrige"
+
+msgid "recaptcha_enter_both_words"
+msgstr ""
+"Indtast <strong>begge ord</strong> herunder <strong>adskilt af et "
+"mellemrum</strong>."
+
+msgid "recaptcha_enter_here"
+msgstr "Skriv ordene her:"
+
+msgid "recaptcha_enter_whatyouhear"
+msgstr "Indtast hvad du hører."
+
+#. %1 is the link switching refreshing the captcha
+#. %2 is the link switching to a text captcha
+msgid "recaptcha_hardtohear_text"
+msgstr ""
+"Hvis det er svære at høre, kan du <a href=\"%1$s\">lytte til noget "
+"andet</a> eller <a href=\"%2$s\">bruge tekst i stedet</a>."
+
+#. %1 is the link switching refreshing the captcha
+#. %2 is the link switching to an audio captcha
+msgid "recaptcha_hardtoread_text"
+msgstr ""
+"Hvis ordene er svære at læse, kan du <a href=\"%1$s\">prøve med andre ord</a> eller "
+"<a href=\"%2$s\">lytte til noget</a> i stedet."
+
+msgid "recaptcha_label"
+msgstr "Er du et menneske eller en robot?"
+
+msgid "recaptcha_whatsthis"
+msgstr "Hvad er dette?"
+
+msgid "review_flag_error"
+msgstr "Der opstod en fejl under rapporteringen af denne anmeldelse!"
+
+msgid "review_flag_reason_bug_support"
+msgstr "Fejlplaceret fejlrapport eller support-spørgsmål"
+
+msgid "review_flag_reason_instructions"
+msgstr "Rapporter denne anmeldelse (vælg en begrundelse)"
+
+msgid "review_flag_reason_language"
+msgstr "Upassende sprogbrug"
+
+msgid "review_flag_reason_other"
+msgstr "Andet (angiv hvad)"
+
+msgid "review_flag_reason_spam"
+msgstr "Spam eller på anden måde ikke en anmeldelse"
+
+msgid "review_flag_success"
+msgstr "Tak; denne anmeldelse er rapporteret til redaktørerne."
+
+msgid "review_flag_this"
+msgstr "Rapporter denne anmeldelse"
+
+msgid "review_flag_this_titletip"
+msgstr ""
+"Er denne anmeldelse upassende, unøjagtig eller spam? Klik her for at "
+"rapportere den til redaktørerne."
+
+#. %1 is the URL of the support section, %2 for the review guidelines
+msgid "review_guidelines_short"
+msgstr ""
+"<p>Bemærk disse råd:</p><ul><li>Skriv som hvis du fortalte en ven "
+"om din oplevelse af tilføjelsen. Vær specifik og giv nyttige detaljer, "
+"så som ting du synes godt og dårligt om, hvor nemt det er at bruge tilføjelsen, og "
+"hvilke ulemper den har. Undgå generelle kommentarer som fx at kalde tilføjelsen \"god"
+"\" eller \"dårlig\" med mindre du kan give begrundelser.</"
+"li><li>Lad være med at rapportere fejl eller spørge om hjælp i din anmeldelse. Din e-mail-adresse er ikke "
+"synlig for udviklerne af tilføjelsen, og de kan have behov for at kontakte dig for "
+"at løse problemet. Se <a href=\"%1$s\">supportsektionen</a> for at "
+"finde ud af hvor du kan få hjælp til denne tilføjelse.</li><li>Hold "
+"anmeldelsen i et høfligt sprog og indtast ikke "
+"personlig information.</li></ul><p>Læs vores <a href=\"%2$s\">retningslinjer "
+"for anmeldelser</a>, hvis du vil vide mere om brugeranmeldelser af tilføjelser.</p>"
+
+#. %1 is the add-on name
+#, php-format
+msgid "reviews_header"
+msgstr "Anmeldelser af %s"
+
+msgid "rss_featuredaddons"
+msgstr "Udmærkede tilføjelser"
+
+msgid "rss_newestaddons"
+msgstr "Nyeste tilføjelser"
+
+msgid "rss_updatedaddons"
+msgstr "Opdaterede tilføjelser"
+
+msgid "search"
+msgstr "Søg"
+
+msgid "search_disabled"
+msgstr "Søgning er deaktiveret i øjeblikket. Prøv igen senere."
+
+msgid "search_form_all_addons"
+msgstr "Alle tilføjelser"
+
+msgid "search_form_default_text"
+msgstr "søg efter tilføjelser"
+
+msgid "search_form_submit_tooltip"
+msgstr "Søg efter tilføjelser"
+
+msgid "search_form_tooltip"
+msgstr "Klik for at indtaste søgeord"
+
+msgid "search_form_within"
+msgstr "i"
+
+msgid "search_landing_all_search_engines"
+msgstr "Alle søgemaskiner"
+
+msgid "search_landing_browse_search_engines"
+msgstr "Gennemse søgemaskiner"
+
+#. %s is a number
+#, php-format
+msgid "search_matching_addons_number"
+msgid_plural "search_matching_addons_number"
+msgstr[0] "%s matchende tilføjelse"
+msgstr[1] "%s matchende tilføjelser"
+
+msgid "search_nothing_found"
+msgstr "Ingen resultater fundet."
+
+msgid "search_pagetitle"
+msgstr "Søg i tilføjelser"
+
+msgid "search_rss_description"
+msgstr "Feed med søgeresultater"
+
+#. %s is the terms the user is searching for (a string)
+#, php-format
+msgid "search_rss_results_for"
+msgstr "Søgeresulteter for: %s"
+
+msgid "sidebar_navlink_admin_tools"
+msgstr "Administrationsværktøjer"
+
+msgid "sidebar_navlink_developer_tools"
+msgstr "Udviklingsværktøjer"
+
+msgid "sidebar_navlink_editor_tools"
+msgstr "Editor Tools"
+
+msgid "sidebar_navlink_welcome"
+msgstr "Velkommen"
+
+#. %s is the user's name
+#, php-format
+msgid "sidebar_navlink_welcome_name"
+msgstr "Velkommen %s"
+
+msgid "sidebar_pitch_dictionary"
+msgstr "en ordbog"
+
+msgid "sidebar_pitch_featured_addons"
+msgstr "Anbefalede tilføjelser"
+
+msgid "sidebar_pitch_looking_for"
+msgstr "Jeg leder efter:"
+
+msgid "sidebar_pitch_newest_addons"
+msgstr "Nyeste tilføjelser"
+
+msgid "sidebar_pitch_search"
+msgstr "en søgetjeneste"
+
+msgid "sidebar_pitch_subscribe_to"
+msgstr "Abonner på"
+
+msgid "sidebar_pitch_theme"
+msgstr "et tema"
+
+msgid "sidebar_pitch_updated_addons"
+msgstr "Opdaterede tilføjelser"
+
+#. %1$s is a number
+#, php-format
+msgid "size_kb"
+msgstr "%1$s KB"
+
+msgid "stars_not_yet_rated"
+msgstr "Ikke bedømt endnu"
+
+#. %1 is the number of stars this add-on has
+#, php-format
+msgid "stars_rated_x_outof_5"
+msgstr "Bedømmelse: %s ud af 5 stjerner"
+
+msgid "themes_landing_all_themes"
+msgstr "Alle temaer"
+
+msgid "themes_landing_browse_themes"
+msgstr "Gennemse temaer"
+
+msgid "user_change_email"
+msgstr "Skift e-mail-adresse"
+
+msgid "user_change_password"
+msgstr "Skift adgangskode"
+
+msgid "user_confirmationcode_resent"
+msgstr "Bekræftelseskoden er sendt igen!"
+
+#. %1 is the email address, %2 is the URL of the user registration page
+msgid "user_del_account_deleted"
+msgstr ""
+"Din konto, %1$s, er nu slettet. Hvis du ønsker at vende tilbage "
+"en anden gang, kan du registrere dig igen på <a href=\"%2$s\">"
+"brugerregistreringssiden</a>."
+
+msgid "user_del_community_sad"
+msgstr "Fællesskabet omkring Mozilla Add-ons er kede af at se dig gå."
+
+msgid "user_del_confirm_password"
+msgstr "Bekræft adgangskode"
+
+msgid "user_del_deletenow"
+msgstr "Slet min konto nu"
+
+#. %1 is the URL of the user's info page
+msgid "user_del_error_addons"
+msgstr ""
+"Du kan ikke slette din konto, hvis du står listet som en <a href=\"%1$s"
+"\">forfatter af en eller flere tilføjelser</a>. For at slette din konto er du nødt til at få en anden "
+" person i din udviklergruppe til at slette dig fra listen over forfattere til "
+" dine tilføjelser. Derefter kan du slette din konto her."
+
+#. %1 is a link to the amo-editors mailing list
+msgid "user_del_error_addons_more_questions"
+msgstr "Har du yderligere spørgsmål, kan du kontakte %1$s for mere information."
+
+msgid "user_del_error_checkbox"
+msgstr ""
+"Du skal sætte markering i boksen \"Jeg forstår...\" før vi kan slette din "
+"konto."
+
+msgid "user_del_error_password"
+msgstr "Kontoen blev ikke slettet, da den angivne adgangskode er forkert."
+
+#. %1 is a link to the amo-admins mailing list
+msgid "user_del_error_unknown"
+msgstr ""
+"En ukendt fejl opstod under sletningen af din konto. Kontakt venligst %1$s vedrørende dette "
+"problem, og vi vil slette kontoen for dig. Vi beklager ulejligheden."
+
+msgid "user_del_header_confirm_deletion"
+msgstr "Bekræft sletning af konto"
+
+#. %1 is the user's email address
+msgid "user_del_header_delete_account"
+msgstr "Slet kontoen %1$s"
+
+msgid "user_del_header_farewell"
+msgstr "Farvel!"
+
+msgid "user_del_nologin"
+msgstr "Du vil fremover ikke kunne logge ind på Mozilla Add-ons."
+
+msgid "user_del_permanently_removed_means"
+msgstr ""
+"Ved at klikke på \"slet\" vil du slette din konto <strong>permanent"
+"</strong>. Dette betyder:"
+
+msgid "user_del_reviews_anonymized"
+msgstr ""
+"Dine anmeldelser og bedømmelser vil ikke blive slettet, men de vil ikke længere være "
+"knyttet til dig."
+
+#. %1 is a link to the amo-editors mailing list
+msgid "user_del_specific_problem_editors"
+msgstr ""
+"Har du et specifikt problem, som vi kan hjælpe med, bør du ikke slette din konto nu, "
+"men i stedet kontakte os på %1$s, og vi vil gøre vores bedste for at hjælpe dig "
+"med at løse problemet."
+
+msgid "user_del_understand_permanent"
+msgstr "Jeg forstår at dette trin ikke kan annulleres."
+
+msgid "user_deleted_nickname"
+msgstr "Slettet bruger"
+
+#. %1 is the new email address
+msgid "user_edit_confirm_email_sent"
+msgstr ""
+"En e-mail er sendt til %1$s for at bekræfte din nye e-mail-adresse. Før "
+"ændringen kan gennemføres, skal du klikke på linket i "
+"denne mail. Indtil da skal du fortsat bruge din nuværende e-mail-adresse til at logge ind."
+
+msgid "user_edit_delete_user"
+msgstr "Slet konto"
+
+#. This contains the email sent to users when they signed up for a new
+#. account:
+#. %1 is the confirmation URL, %2 is the current app
+#, php-format
+msgid "user_email_confirm_account_nopass"
+msgstr ""
+"Velkommen til %2$s Add-ons.\n"
+"\n"
+"Før du kan bruge din nye konto, skal du aktivere den - det sikrer, at den "
+"anvendte e-mail-adresse er gyldig og tilhører dig.\n"
+"For at aktivere din konto skal du klikke på linket herunder eller kopiere "
+"hele linket ind i din browsers adresselinje:\n"
+"\n"
+"%1$s\n"
+"\n"
+"NÃ¥r du har aktiveret din konto, kan du smide denne e-mail "
+"væk.\n"
+"\n"
+"Tak fordi du tilmeldte dig %2$s Add-ons\n"
+"-- %2$s Add-ons"
+
+#. %1 is the confirmation url, %2 is the application name
+msgid "user_email_confirm_emailchange"
+msgstr ""
+"Du anmodede om at ændre din e-mail-adresse hos %2$s Add-ons.\n"
+"\n"
+"For at bekræfte din nye adresse, bedes du klikke på linket herunder eller kopiere det hele "
+"ind i din browsers adresselinje:\n"
+"\n"
+"%1$s\n"
+"\n"
+"Du har to døgn til at bekræfte din nye adresse. Hvis du alligevel ikke ønsker at "
+"ændre din adresse, kan du bare ignorere denne e-mail.\n"
+"\n"
+"Tak!\n"
+"-- %2$s Add-ons"
+
+#, php-format
+msgid "user_email_confirm_subject"
+msgstr "Tak fordi du tilmeldte dig %s Add-ons"
+
+#. This is the password reset email
+#. %1 is the pw reset URL, %2 is the application
+#, php-format
+msgid "user_email_pwreset"
+msgstr ""
+"Nulstilling af adgangskode til %2$s Add-ons\n"
+"\n"
+"Vi modtog en anmodning om at nulstille adgangskoden for denne konto på "
+"addons.mozilla.org. For at ændre din adgangskode bedes du klikke på følgende "
+"link eller kopiere det ind i din browsers adresselinje:\n"
+"\n"
+"%1$s\n"
+"\n"
+"Har du ikke anmodet om denne e-mail, skal du ikke foretage dig noget yderligere.\n"
+"\n"
+"Tak,\n"
+"-- %2$s Add-ons"
+
+#, php-format
+msgid "user_email_pwreset_subject"
+msgstr "Nulstil din adgangskode til %s Add-ons"
+
+msgid "user_emailchange_error"
+msgstr "Fejl!"
+
+#. %1 is the application name
+msgid "user_emailchange_subject"
+msgstr "Bekræft ændring af e-mail-adresse hos %1$s Add-ons"
+
+msgid "user_emailchange_success"
+msgstr "Succes!"
+
+#. %1 is the new email address
+msgid "user_emailchange_successful_description"
+msgstr ""
+"Din e-mail-adresse blev ændret. Fra nu af skal du bruge "
+"%1$s for at logge ind."
+
+msgid "user_form_bio"
+msgstr "Om mig"
+
+msgid "user_form_bio_description"
+msgstr ""
+"Introducer dig selv til fællesskabet, hvis du vil! Denne tekst vil blive vist "
+"offentligt op din brugerside. Linjeskift bevares, men HTML "
+"tillades ikke."
+
+msgid "user_form_confirmpassword"
+msgstr "Bekræft adgangskode"
+
+#, php-format
+msgid "user_form_editprofile"
+msgstr "Ret brugerprofil for %s"
+
+msgid "user_form_email"
+msgstr "E-mail-adresse"
+
+msgid "user_form_firstname"
+msgstr "Fornavn"
+
+msgid "user_form_hideemail"
+msgstr "Skjul e-mail-adresse"
+
+msgid "user_form_homepage"
+msgstr "Website URL"
+
+msgid "user_form_lastname"
+msgstr "Efternavn"
+
+msgid "user_form_login"
+msgstr "Brugerlogin"
+
+msgid "user_form_newpassword"
+msgstr "Ny adgangskode"
+
+msgid "user_form_nickname"
+msgstr "Kaldenavn"
+
+msgid "user_form_oldpassword"
+msgstr "Gammel adgangskode"
+
+msgid "user_form_otheractions"
+msgstr "Andre muligheder"
+
+msgid "user_form_password"
+msgstr "Adgangskode"
+
+msgid "user_form_registration"
+msgstr "Registrering af ny bruger"
+
+msgid "user_form_remember_me"
+msgstr "Husk mig på denne computer"
+
+msgid "user_form_showsandbox"
+msgstr "Vis sandkasse?"
+
+msgid "user_form_submit_edit"
+msgstr "Gem"
+
+msgid "user_form_submit_login"
+msgstr "Log ind"
+
+msgid "user_form_submit_register"
+msgstr "Registrer"
+
+#, php-format
+msgid "user_info_usersince"
+msgstr "Bruger af %s Add-ons siden"
+
+msgid "user_login_register_link"
+msgstr "Opret ny brugerkonto"
+
+msgid "user_notifications_item_compat"
+msgstr "Kompatibilitet vedrørende tilføjelser (anbefales kraftigt)"
+
+msgid "user_notifications_item_events"
+msgstr "Kommende begivenheder og konkurrencer"
+
+msgid "user_notifications_none_available"
+msgstr "Der er i øjeblikket ingen beskeder, som du kan kan konfigurere."
+
+msgid "user_notifications_select_topics"
+msgstr ""
+"Mozilla kan af og til sende e-mails vedrørende kommende udgivelser og "
+"begivenheder relateret til tilføjelser. Vælg hvad du er interesseret i herunder:"
+
+msgid "user_notifications_specific_contact"
+msgstr ""
+"Mozilla forbeholder sig retten til at kontakte dig individuelt vedrørende "
+"dine tilføjelser, som er hostet her."
+
+msgid "user_profile_edit_error"
+msgstr ""
+"Der var fejl i de indtastede ændringer. Ret dem venligst og indsend igen."
+
+msgid "user_profile_saved"
+msgstr "Profil opdateret."
+
+#, php-format
+msgid "user_pwreset_for_email"
+msgstr "Adgangskode nulstillet for %s"
+
+msgid "user_pwreset_header"
+msgstr "Adgangskode nulstillet"
+
+msgid "user_pwreset_link"
+msgstr "Har du glemt din adgangskode?"
+
+msgid "user_pwreset_link_sent"
+msgstr "Linket til nulstilling af adgangskode er sendt til din e-mail-adresse."
+
+msgid "user_pwreset_okay"
+msgstr "Adgangskoden blev nulstillet."
+
+msgid "user_pwreset_submit_changepw"
+msgstr "Indsend ændring af adgangskode"
+
+msgid "user_pwreset_submit_sendlink"
+msgstr "Send link til ændring af adgangskode"
+
+#, php-format
+msgid "user_register_amo_link"
+msgstr "%s Add-ons"
+
+#. %1 is the user's email address, %2 is the current app
+#, php-format
+msgid "user_register_click_confirm_link"
+msgstr ""
+"Et link til aktivering af din brugerkonto er sendt af sted via e-mail til "
+"din adresse, %1$s. Du skal klikke på linket i denne e-mail, før du kan logge ind på %2$s Add-ons."
+
+#. %1 is the user's email address
+#, php-format
+msgid "user_register_confirm_email_sent"
+msgstr ""
+"En e-mail er sendt af sted til din adresse, %1$s, for at bekræfte din konto. "
+"Før du kan logge ind, skal du aktivere kontoen ved at klikke på linket i e-"
+"mailen."
+
+msgid "user_register_confirmation_link_text"
+msgstr "sende bekræftelsesmeddelelsen igen"
+
+msgid "user_register_congratulations"
+msgstr "Tillykke! Din brugerkonto er nu oprettet."
+
+msgid "user_register_details"
+msgstr ""
+"<p>Registrering på AMO er <strong>ikke påkrævet</strong> hvis du bare vil "
+"hente og installere offentlige tilføjelser.</p><p>Du behøver kun at registrere, hvis:</"
+"p><ul><li>Du vil indsende anmeldelser af tilføjelser</li><li>Du er udvikler af en tilføjelse "
+"og ønsker at uploade den til hosting på AMO</li></ul><p>Ved "
+"succesfuld registrering vil du få tilsendt en bekræftelsesmail til den "
+"adresse du opgav. Følg instruktionerne i mailen for at bekræfte din "
+"konto.</p><p>Hvis du vil, kan du læse vores <a href='%1$s' title='Juridiske "
+"betingelser'>juridiske betingelser</a> og <a href='%2$s' title='Privatlivspolitik'>privatlivspolitik"
+"</a>.</p>"
+
+#. %1 is the link to the "resend confirmation code" page
+#, php-format
+msgid "user_register_resend_confirmation_link"
+msgstr ""
+"Hvis du ikke modtog bekræftelsesmailen, bør du kontrollere, at din "
+"maiservice ikke markerede den som \"spam\". Har du behov for det, kan vi %1"
+"$s til din e-mail-adresse, som står herover."
+
+#. %1 is the link to the Mozilla Add-ons front page
+#, php-format
+msgid "user_register_welcome"
+msgstr "Tak fordi du registrerede dig og velkommen til %1$s!"
+
+msgid "user_register_welcome_header"
+msgstr "Velkommen til addons.mozilla.org (AMO)!"
+
+msgid "user_required_firstlast_or_nickname"
+msgstr "Et fornavn, efternavn eller kaldenavn skal angives."
+
+msgid "user_tab_notifications"
+msgstr "Beskeder"
+
+msgid "user_tab_profile"
+msgstr "Brugerprofil"
+
+msgid "user_verified_okay"
+msgstr "Godkendt!"
+
+msgid "users_delete_pagetitle"
+msgstr "Slet konto"
+
+msgid "users_edit_pagetitle"
+msgstr "Redigering af brugerkonto"
+
+msgid "users_info_aboutme"
+msgstr "Om mig"
+
+#, php-format
+msgid "users_info_addons_by_user"
+msgstr "Tilføjelser fra %1$s"
+
+msgid "users_info_author_name"
+msgstr "Navn"
+
+msgid "users_info_author_profile"
+msgstr "Brugerprofil"
+
+msgid "users_info_email"
+msgstr "E-mail-adresser"
+
+msgid "users_info_homepage"
+msgstr "Hjemmeside"
+
+msgid "users_info_nickname"
+msgstr "Kaldenavn"
+
+#, php-format
+msgid "users_info_pagetitle"
+msgstr "Brugerinfo om %1$s"
+
+#. %1 is the user's name
+msgid "users_info_reviews_by_user"
+msgstr "Anmeldelser skrevet af %s"
+
+msgid "users_login_pagetitle"
+msgstr "Log ind"
+
+#. %1 is the link to the sandbox/policy explanation page
+#. This message is for a specific add-on not found
+#, php-format
+msgid "users_login_sandbox_display_warning"
+msgstr ""
+"Den ønskede tilføjelse befinder sig i øjeblikket i sandkassen. Har du "
+"allerede en konto hos Mozilla Add-ons, bedes du logge ind, eller du kan <a "
+"href=\"%1$s\">lære mere om sandkassen.</a>"
+
+#. %1 is the link to the sandbox/policy explanation page
+#. This message is for any given sandbox-related page not found
+#, php-format
+msgid "users_login_sandbox_page_warning"
+msgstr ""
+"Den ønskede side er en del af sandkassen. Har du allerede en konto hos "
+"Mozilla Add-ons, bedes du logge ind, eller du kan <a href=\"%1$s\">lære mere "
+"om sandkassen.</a>"
+
+msgid "users_pwreset_pagetitle"
+msgstr "Nulstilling af adgangskode"
+
+msgid "users_register_pagetitle"
+msgstr "Registrering af ny bruger"
+
+#. %1$s is an addon name, like <a>Firebug</a>
+#. %2$s is a version number, like <a>1.2</a>
+msgid "versions_license_header_source"
+msgstr "Licens for kildekoden til %1$s %2$s"
+
+msgid "view_recently_added"
+msgstr "Vis alle som blev tilføjet fornyligt"
+
+msgid "view_top_downloads"
+msgstr "Vis alle med flest downloads"
+
+msgid "view_top_rated"
+msgstr "Vis alle med de bedste bedømmelser"
diff --git a/site/app/locale/da/LC_MESSAGES/en-US.txt b/site/app/locale/da/LC_MESSAGES/en-US.txt
new file mode 100644
index 0000000..5b18f24
--- /dev/null
+++ b/site/app/locale/da/LC_MESSAGES/en-US.txt
@@ -0,0 +1,2044 @@
+# Language en-US translations for addons.mozilla.org package.
+# Copyright (C) 2009 THE addons.mozilla.org'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the addons.mozilla.org package.
+# Automatically generated, 2009.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: addons\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2009-01-16 11:45-0800\n"
+"PO-Revision-Date: 2009-02-26 15:08-0800\n"
+"Last-Translator: Automatically generated\n"
+"Language-Team: none\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+msgid "a_cancel_installation"
+msgstr "Cancel Installation"
+
+#. This is the text that appears on buttons to download add-ons.
+#. %$1s is an optional string that only appears if the add-on is only available for
+#. a certain platform. Examples: (Windows) or (Linux)
+#. Note that the parenthesis are included in the string. :(
+#, php-format
+msgid "a_download"
+msgstr "Download Now %s"
+
+msgid "a_eula_download"
+msgstr "Accept and Download"
+
+msgid "a_eula_install"
+msgstr "Accept and Install"
+
+msgid "a_header_public"
+msgstr "Public"
+
+msgid "a_header_sandbox"
+msgstr "Sandbox"
+
+#. %s is a date in the _('date') format
+msgid "addon_detail_last_updated"
+msgstr "Updated %s"
+
+#. %s is the version of the add-on. Example: 3.2a1
+#, php-format
+msgid "addon_display_header_version"
+msgstr "Version %s"
+
+msgid "addon_downloads"
+msgstr "downloads"
+
+msgid "addon_downloads_total"
+msgstr "total downloads"
+
+msgid "addon_downloads_weekly"
+msgstr "weekly downloads"
+
+#. %1 is the add-on count, %2 the category name
+#, php-format
+msgid "addon_list_category_totalcount"
+msgid_plural "addon_list_category_totalcount"
+msgstr[0] "%1$s add-on"
+msgstr[1] "%1$s add-ons"
+
+msgid "addon_list_perpage"
+msgstr "per page"
+
+msgid "addon_list_sortby"
+msgstr "Sort by:"
+
+msgid "addon_listitem_flag_experimental"
+msgstr "experimental"
+
+msgid "addon_listitem_flag_recommended"
+msgstr "recommended"
+
+#. %1 is the add-on name, %2 is the platform
+msgid "addon_not_available_for_platform"
+msgstr "%1$s is not available for %2$s."
+
+#. %1 is the add-on name
+#, php-format
+msgid "addon_review_a_back_to_addon_x"
+msgstr "Back to %1$s..."
+
+#. %1 is the add-on name
+#, php-format
+msgid "addon_review_a_back_to_reviews"
+msgstr "Back to the reviews..."
+
+msgid "addon_review_add_rating_field"
+msgstr "Rating:"
+
+msgid "addon_review_add_review_field"
+msgstr "Review:"
+
+msgid "addon_review_add_submit"
+msgstr "Submit your review"
+
+#. %s is the name of the add-on
+#, php-format
+msgid "addon_review_add_title"
+msgstr "Add a review for %s"
+
+msgid "addon_review_add_title_field"
+msgstr "Title/Summary:"
+
+msgid "addon_review_admin_delete"
+msgstr "Delete"
+
+msgid "addon_review_author_reply_link"
+msgstr "Reply"
+
+msgid "addon_review_confirm_delete"
+msgstr "Are you sure you wish to delete this review?"
+
+msgid "addon_review_confirm_no"
+msgstr "No"
+
+msgid "addon_review_confirm_yes"
+msgstr "Yes"
+
+msgid "addon_review_delete_header"
+msgstr "Delete Review"
+
+msgid "addon_review_deleted_successfully"
+msgstr "Review deleted successfully."
+
+#. %s is the name of the add-on
+#, php-format
+msgid "addon_review_edit_title"
+msgstr "Edit Review for %s"
+
+#. %1 is the count of characters entered as notes for the review flag reason.
+msgid "addon_review_flag_error_other_length"
+msgstr ""
+"Problem flagging review: Notes for flagged reviews are limited to between 10 "
+"and 100 characters; your character length was %1$s."
+
+#. Removing an extra comma
+msgid "addon_review_in_moderation"
+msgstr ""
+"Please note: Before your review shows up on the public site it will be "
+"moderated by an editor."
+
+msgid "addon_review_in_reply_to"
+msgstr "Developer reply to:"
+
+#. %1 is the review count, %2 is the nickname or full name of the user.
+#, php-format
+msgid "addon_review_others_by_user"
+msgid_plural "addon_review_others_by_user"
+msgstr[0] "See %1$s previous review submitted by %2$s for this add-on."
+msgstr[1] "See %1$s previous reviews submitted by %2$s for this add-on."
+
+#. %1 is the add-on name
+#, php-format
+msgid "addon_review_pagetitle"
+msgstr "Reviews for %s"
+
+#. %1 is the user, %2 is the (localized) date
+#, php-format
+msgid "addon_review_reply_on_x_by_y"
+msgstr "Reply by %1$s on %2$s"
+
+msgid "addon_review_reply_prefix"
+msgstr "Developer Reply:"
+
+msgid "addon_review_saved_successfully"
+msgstr "Your review was saved successfully. Thanks!"
+
+msgid "addon_reviewed_by_u_on_d"
+msgstr "by %1$s on %2$s"
+
+#. %1 is the user, %2 is the (localized) date, %3 is the rating
+#, php-format
+msgid "addon_reviewed_on_x_rated_y"
+msgstr "by %1$s on %2$s (rated %3$s)"
+
+msgid "addon_slider_tooltip_next"
+msgstr "Next Add-on"
+
+msgid "addon_slider_tooltip_previous"
+msgstr "Previous Add-on"
+
+msgid "addon_version_permalink"
+msgstr "Permanent link to this version"
+
+#. %1 is the current Application name (e.g. Firefox)
+#. %2 is the Application's version number
+msgid "addon_versions_getlatestversion"
+msgstr "The most recent version compatible with %1$s %2$s"
+
+msgid "addons_author_addons_submit"
+msgstr "Go"
+
+msgid "addons_author_tooltip"
+msgstr "View Author's Profile"
+
+#. %1 is the name of the Application (eg. Firefox)
+msgid "addons_browse_all_themes_title"
+msgstr "Browse all Themes :: %1$s Add-ons"
+
+#. %s is the name of the category
+#, php-format
+msgid "addons_browse_browse_category"
+msgstr "Browse %s"
+
+#. %1 is the name of the theme category (eg. Modern)
+#. %2 is the name of the Application (eg. Firefox)
+msgid "addons_browse_categories_header_theme"
+msgstr "Browse %1$s Themes :: %2$s Add-ons"
+
+msgid "addons_display_a_license_what"
+msgstr "What's this?"
+
+msgid "addons_display_add_review"
+msgstr "Add a review"
+
+msgid "addons_display_advanced_details"
+msgstr "Advanced Details"
+
+msgid "addons_display_categories"
+msgstr "Categories"
+
+msgid "addons_display_detailed_review"
+msgstr "detailed review"
+
+msgid "addons_display_dont_like_it"
+msgstr "Don't like it"
+
+msgid "addons_display_edit_review"
+msgstr "Edit your review"
+
+msgid "addons_display_has_privacy"
+msgstr "This add-on has a privacy policy."
+
+msgid "addons_display_hate_it"
+msgstr "Hate it"
+
+msgid "addons_display_header_developer_comments"
+msgstr "Developer Comments"
+
+msgid "addons_display_header_homepage"
+msgstr "Homepage"
+
+msgid "addons_display_header_license"
+msgstr "Source Code License"
+
+msgid "addons_display_header_reviews"
+msgstr "Reviews"
+
+msgid "addons_display_header_support"
+msgstr "Support"
+
+msgid "addons_display_like_it"
+msgstr "Like it"
+
+msgid "addons_display_long_description"
+msgstr "Long Description"
+
+msgid "addons_display_love_it"
+msgstr "Love it"
+
+msgid "addons_display_more_images"
+msgstr "More Images"
+
+#. %1$s is either an author's name or a comma separated list of authors. Using
+#. the list doesn't make sense in the English plural form so we ignore the
+#. variable.
+msgid "addons_display_other_addons_by"
+msgid_plural "addons_display_other_addons_by"
+msgstr[0] "Other add-ons by %1$s"
+msgstr[1] "Other add-ons by these authors"
+
+#. %s is the name of the add-on and the add-on section. Example:
+#. Some Add-on :: Firefox Add-ons
+#. This should not be concatenated in the code and should be fixed.
+#, php-format
+msgid "addons_display_pagetitle"
+msgstr "%s"
+
+#. %s is an email address
+#, php-format
+msgid "addons_display_paragraph_supportinfoemail"
+msgstr "Support for this add-on is provided by the developer at %s"
+
+#. %$1s is a URL
+#. %$2s is an email address
+#, php-format
+msgid "addons_display_paragraph_supportinfoemailurl"
+msgstr ""
+"Support for this add-on is provided by the developer at %1$s or by sending "
+"an e-mail to %2$s"
+
+#. %s is a URL
+#, php-format
+msgid "addons_display_paragraph_supportinfourl"
+msgstr "Support for this add-on is provided by the developer at %s"
+
+msgid "addons_display_rate_it"
+msgstr "Rate It"
+
+msgid "addons_display_really_like_it"
+msgstr "Really like it"
+
+msgid "addons_display_review_etiquette"
+msgstr ""
+"Please do not post bug reports in reviews. We do not make your email address "
+"available to add-on developers and they may need to contact you to help "
+"resolve your issue."
+
+#. %1 is the review guidelines link
+msgid "addons_display_review_guidelines_link"
+msgstr "<a href=\"%s\">Review Guidelines</a>"
+
+#. %1 is the support section link
+msgid "addons_display_review_see_support"
+msgstr ""
+"See the <a href=\"%1$s\">support section</a> to find out where to get "
+"assistance for this add-on."
+
+msgid "addons_display_review_submit"
+msgstr "Save"
+
+#, php-format
+msgid "addons_display_see_all_addons"
+msgstr "See All %1$s Add-ons"
+
+#. %1 is the number of reviews
+#, php-format
+msgid "addons_display_see_all_reviews"
+msgstr "See all reviews (%1$s)"
+
+msgid "addons_display_see_all_versions"
+msgstr "See All Versions"
+
+msgid "addons_display_view_source"
+msgstr "View the source"
+
+msgid "addons_display_view_stats"
+msgstr "View statistics"
+
+msgid "addons_display_what_do_you_think"
+msgstr "What do you think?"
+
+msgid "addons_display_workswith"
+msgstr "Works with:"
+
+msgid "addons_home_by"
+msgstr "by"
+
+msgid "addons_home_feature_head"
+msgstr "We Recommend"
+
+#, php-format
+msgid "addons_home_header_details"
+msgstr ""
+"Add-ons extend %1$s, letting you personalize your browsing experience. Take "
+"a look around and make %1$s your own."
+
+msgid "addons_home_newest_header"
+msgstr "Newest:"
+
+msgid "addons_home_other_applications"
+msgstr "Other Applications"
+
+#. %1$s is the application the user is browsing. Examples: Thunderbird, Firefox,
+#. Sunbird
+#, php-format
+msgid "addons_home_pagetitle"
+msgstr "%1$s Add-ons"
+
+msgid "addons_home_popular_header"
+msgstr "Most Popular:"
+
+msgid "addons_home_recommended_header"
+msgstr "We Recommend:"
+
+msgid "addons_home_updated_header"
+msgstr "Recently Updated:"
+
+msgid "addons_home_view_all"
+msgstr "View all"
+
+msgid "addons_home_view_all_newest_title"
+msgstr "View all newly created add-ons"
+
+msgid "addons_home_view_all_popular_title"
+msgstr "View all popular add-ons"
+
+msgid "addons_home_view_all_recommended_title"
+msgstr "View all recommended add-ons"
+
+msgid "addons_home_view_all_updated_title"
+msgstr "View all recently updated add-ons"
+
+msgid "addons_install_in_sunbird"
+msgstr ""
+"<ol><li>Click the link below to save the file.</li><li>In Mozilla Sunbird, "
+"open Add-ons from the Tools menu.</li><li>Click the Install button, and "
+"locate/select the file you downloaded and click \"OK\".</li></ol>"
+
+msgid "addons_install_in_sunbird_title"
+msgstr "How to Install in Sunbird"
+
+msgid "addons_install_in_thunderbird"
+msgstr ""
+"<ol><li>Right-click the link below and choose \"Save Link As...\" to "
+"download and save the file to your hard disk.</li><li>In Mozilla "
+"Thunderbird, open Add-ons from the Tools menu.</li><li>Click the Install "
+"button, and locate/select the file you downloaded and click \"OK\".</li></ol>"
+
+msgid "addons_install_in_thunderbird_title"
+msgstr "How to Install in Thunderbird"
+
+msgid "addons_options_show_experimental"
+msgstr "show experimental add-ons"
+
+msgid "addons_options_submit"
+msgstr "Go"
+
+msgid "addons_plugins_by"
+msgstr "By"
+
+msgid "addons_plugins_for_linux"
+msgstr "for Linux"
+
+msgid "addons_plugins_for_macosx"
+msgstr "for Mac OS X"
+
+msgid "addons_plugins_for_windows"
+msgstr "for Windows"
+
+#. %1$s is a URL
+#, php-format
+msgid "addons_plugins_looking_for_more"
+msgstr ""
+"This page only lists some of the most common and most popular plugins. For "
+"more information about other plugins available for Mozilla-based Browsers, "
+"visit %1$s"
+
+msgid "addons_plugins_looking_for_plugin"
+msgstr "Looking for a plugin not listed here?"
+
+msgid "addons_plugins_main_description"
+msgstr ""
+"Plugins help your browser perform specific functions like viewing special "
+"graphic formats or playing multimedia files. Plugins are slightly different "
+"from extensions, which modify or add to existing functionality."
+
+#. %1$s is the application name. Example: Firefox, Thunderbird, Sunbird
+#, php-format
+msgid "addons_plugins_main_header"
+msgstr "Common Plugins for %1$s"
+
+msgid "addons_plugins_pagetitle"
+msgstr "Plugins"
+
+msgid "addons_plugins_support_documentation"
+msgstr "Support Documentation: "
+
+#. %s is the name of the add-on
+#, php-format
+msgid "addons_policy_eula_require"
+msgstr ""
+"%s requires that you accept the following End-User License Agreement before "
+"installation can proceed:"
+
+#. %1 is the add-on name
+#, php-format
+msgid "addons_previews_pagetitle"
+msgstr "Previews for %s"
+
+msgid "addons_recently_added"
+msgstr "Recently Added"
+
+msgid "addons_recommended_introduction"
+msgstr ""
+"With so many great add-ons available, there's something for everyone. To get "
+"you started, here's a list of some of the most popular. Enjoy!"
+
+msgid "addons_recommended_pagetitle"
+msgstr "Recommended Add-ons"
+
+msgid "addons_recommended_title"
+msgstr "Recommended Add-ons"
+
+msgid "addons_searchengines_additional_resources"
+msgstr "Additional Resources"
+
+#. link text devmo
+msgid "addons_searchengines_devmo_link"
+msgstr "Mozilla Developer Center"
+
+msgid "addons_searchengines_error_mozilla_browser_required"
+msgstr ""
+"Sorry, you need a Mozilla-based browser (such as Firefox) to install a "
+"search plugin."
+
+msgid "addons_searchengines_error_nojavascript"
+msgstr ""
+"JavaScript is required to install plugins, but it looks like you have it "
+"disabled. Please enable JavaScript before trying to install any of the "
+"search plugins below."
+
+#. %1 is "make your own" link
+#. %2 is MDC link
+msgid "addons_searchengines_learn_howto"
+msgstr "Learn how to %1$s at the %2$s."
+
+#. link path to search plugins instructions, relative to devmo
+msgid "addons_searchengines_makeyourown_href"
+msgstr "/en/docs/Creating_OpenSearch_plugins_for_Firefox"
+
+#. link text for "make your own" (opensearch engine)
+msgid "addons_searchengines_makeyourown_link"
+msgstr "make your own"
+
+#. %1 is the link to mycroft.mozdev.org
+msgid "addons_searchengines_more"
+msgstr "Browse through more search engines at %1$s"
+
+#. link text to mycroft.mozdev.org
+msgid "addons_searchengines_mycroft_link"
+msgstr "mycroft.mozdev.org"
+
+msgid "addons_searchengines_pagetitle"
+msgstr "Search Engines"
+
+msgid "addons_searchengines_thanks"
+msgstr ""
+"Special thanks to the Mycroft Project for their work on Firefox Search "
+"Engines."
+
+msgid "addons_share_button_text"
+msgstr "Share this"
+
+msgid "addons_share_label_delicious"
+msgstr "Add to Delicious"
+
+msgid "addons_share_label_digg"
+msgstr "Digg this!"
+
+msgid "addons_share_label_facebook"
+msgstr "Post to Facebook"
+
+msgid "addons_share_label_friendfeed"
+msgstr "Share on FriendFeed"
+
+msgid "addons_share_label_myspace"
+msgstr "Post to MySpace"
+
+msgid "addons_status_disabled"
+msgstr "Disabled"
+
+msgid "addons_status_incomplete"
+msgstr "Incomplete Version"
+
+msgid "addons_status_nominated"
+msgstr "In Sandbox; Public Nomination"
+
+msgid "addons_status_pending"
+msgstr "In Sandbox; Pending Review"
+
+msgid "addons_status_public"
+msgstr "Public"
+
+msgid "addons_status_sandbox"
+msgstr "In Sandbox"
+
+msgid "addons_status_unknown"
+msgstr "Unknown"
+
+msgid "addons_title_tooltip"
+msgstr "Learn more about this add-on"
+
+msgid "addons_top_downloads"
+msgstr "Top Downloads"
+
+msgid "addons_top_rated"
+msgstr "Top Rated"
+
+msgid "addons_versions_careful"
+msgstr "Be Careful With Old Versions"
+
+msgid "addons_versions_careful_introduction"
+msgstr ""
+"These versions are displayed for reference and testing purposes. You should "
+"always use the latest version of an add-on."
+
+msgid "addons_versions_history"
+msgstr "Version History with Changelogs"
+
+#. %1$s is the add-on name
+#, php-format
+msgid "addons_versions_pagetitle"
+msgstr "%1$s Version History"
+
+msgid "admin_group_add_pagetitle"
+msgstr "Add Group"
+
+msgid "admin_group_delete_pagetitle"
+msgstr "Delete Group"
+
+#. %s is a number to identify the group
+#, php-format
+msgid "admin_group_deleted"
+msgstr "The Group with id %s was deleted"
+
+msgid "admin_group_edit_pagetitle"
+msgstr "Edit Group"
+
+msgid "admin_group_error_invalid_id"
+msgstr "Invalid id for Group"
+
+msgid "admin_group_pagetitle"
+msgstr "Group Admin"
+
+msgid "admin_group_saved"
+msgstr "The Group has been saved"
+
+msgid "advanced_search_form"
+msgstr "Advanced"
+
+msgid "advanced_search_form_any_time"
+msgstr "Any time"
+
+msgid "advanced_search_form_any_type"
+msgstr "Any"
+
+msgid "advanced_search_form_any_version"
+msgstr "Any"
+
+msgid "advanced_search_form_application"
+msgstr "Application"
+
+msgid "advanced_search_form_keyword_match"
+msgstr "Keyword Match"
+
+msgid "advanced_search_form_lastupdate"
+msgstr "Last Updated"
+
+msgid "advanced_search_form_name"
+msgstr "Name"
+
+msgid "advanced_search_form_newest"
+msgstr "Newest"
+
+msgid "advanced_search_form_past_3_months"
+msgstr "Past 3 months"
+
+msgid "advanced_search_form_past_6_months"
+msgstr "Past 6 months"
+
+msgid "advanced_search_form_past_day"
+msgstr "Past Day"
+
+msgid "advanced_search_form_past_month"
+msgstr "Past month"
+
+msgid "advanced_search_form_past_week"
+msgstr "Past week"
+
+msgid "advanced_search_form_past_year"
+msgstr "Past year"
+
+msgid "advanced_search_form_perpage"
+msgstr "Per Page"
+
+msgid "advanced_search_form_platform"
+msgstr "Platform"
+
+msgid "advanced_search_form_popularity"
+msgstr "Popularity"
+
+msgid "advanced_search_form_rating"
+msgstr "Rating"
+
+msgid "advanced_search_form_sortby"
+msgstr "Sort By"
+
+msgid "advanced_search_form_to"
+msgstr "to"
+
+msgid "advanced_search_form_toggle_tooltip"
+msgstr "Toggle advanced search mode"
+
+msgid "advanced_search_form_type"
+msgstr "Type"
+
+msgid "advanced_search_form_version"
+msgstr "version"
+
+msgid "app_compat_ignore_check"
+msgstr "Ignore version check"
+
+msgid "app_compat_older_firefox_only"
+msgstr "This add-on is for older versions of Firefox"
+
+#. %1$s and %2$s are URLs
+msgid "app_compat_older_version_or_ignore_check"
+msgstr ""
+"You can <a href=\"%1$s\">try an older version</a> or <a href=\"#\" onclick="
+"\"%2$s\">ignore this check</a>"
+
+#. %1$s is a URL
+msgid "app_compat_try_old_version"
+msgstr "An <a href=\"%1$s\">older version</a> may work"
+
+#. %1$s is a URL
+#. %2$s is a version number. Example: 3.1
+msgid "app_compat_unreleased_version"
+msgstr ""
+"This add-on requires the not-yet released <a href=\"%1$s\">Firefox %2$s</a>"
+
+msgid "app_compat_update_firefox"
+msgstr ""
+"<a href=\"http://getfirefox.com\">Upgrade Firefox</a> to use this add-on"
+
+msgid "browse_addons_name"
+msgstr "Add-ons by Name"
+
+msgid "browse_addons_newest"
+msgstr "Newest Add-ons"
+
+msgid "browse_addons_popular"
+msgstr "Popular Add-ons"
+
+msgid "browse_addons_rated"
+msgstr "Add-ons by Rating"
+
+msgid "browse_addons_updated"
+msgstr "Recently Updated Add-ons"
+
+msgid "categories_current_title"
+msgstr "Current Category"
+
+msgid "categories_header"
+msgstr "Categories"
+
+msgid "categories_header_title"
+msgstr "Choose a category"
+
+#. %1$s is the category name
+#, php-format
+msgid "category_extra_see_all"
+msgstr "See All %1$s"
+
+#. %1$s is a number.
+msgid "collection_description_limit"
+msgstr "The description should be less than %1$s characters."
+
+#. %1$s is a number.
+msgid "collection_name_limit"
+msgstr "The name should be less than %1$s characters."
+
+msgid "collection_not_found"
+msgstr "Collection not found!"
+
+#. %s is a date in the _('date') format
+#, php-format
+msgid "collections_interactive_addon_added"
+msgstr "Added %s"
+
+msgid "compatibility_dashboard_center_header"
+msgstr "Add-on Compatibility Center"
+
+#. %1$s is the name of an application and a version. Example: Firefox 3.0
+#. %2$s is the name of an application. Example: Firefox
+msgid "compatibility_dashboard_intro"
+msgstr ""
+"Be prepared for the release of %1$s with the tools and information available "
+"for the %2$s Add-ons community found below."
+
+msgid "compatibility_dashboard_loading"
+msgstr "Loading data..."
+
+msgid "compatibility_dashboard_main_link"
+msgstr "Back to Main"
+
+msgid "compatibility_dashboard_report"
+msgstr "Add-on Compatibility Report"
+
+msgid "compatibility_developer_info"
+msgstr "Information for Add-on Developers"
+
+msgid "compatibility_developers_adjust_maxversion"
+msgstr "Adjust maxVersion without uploading"
+
+msgid "compatibility_developers_check_status"
+msgstr "Check Status of My Add-ons"
+
+#. %1$s is a URL
+#. %2$s is an application and version. Example: Firefox 3.0
+msgid "compatibility_developers_login_first"
+msgstr ""
+"If you have add-ons hosted on Mozilla Add-ons, <a href=\"%1$s\">please log "
+"in</a> to analyze the status of your add-ons for %2$s."
+
+msgid "compatibility_developers_mdclogo_alt"
+msgstr "Mozilla Developer Center Logo"
+
+msgid "compatibility_developers_no_addons"
+msgstr "You do not have any add-ons hosted on Mozilla Add-ons."
+
+msgid "compatibility_developers_results"
+msgstr "Add-on Status Check Results"
+
+msgid "compatibility_developers_retrieving"
+msgstr "Retrieving status of hosted add-ons..."
+
+#. %1$s is a number
+#. %2$s is an application name
+#. %3$s is a number.
+#. Full example: 50 Firefox users (10% of total)
+msgid "compatibility_developers_user_count"
+msgstr "%1$s %2$s users (%3$s&#37; of total)"
+
+msgid "compatibility_report_detail_intro"
+msgstr ""
+"The add-ons below make up 95% of add-on usage known to Mozilla and are "
+"ordered by their usage size."
+
+msgid "compatibility_report_detailed_link"
+msgstr "View Detailed Report"
+
+#. %1$s and %2$s are numbers
+#. %3$s is an application name and version. Example: Firefox 3.1
+msgid "compatibility_report_intro"
+msgstr ""
+"Of the %1$s add-ons that make up 95&#37; of add-on usage known to Mozilla, "
+"<b>%2$s&#37;</b> are currently considered compatible with the latest builds "
+"of %3$s."
+
+msgid "compatibility_report_legend_alpha"
+msgstr "Alpha Versions"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+msgid "compatibility_report_legend_alpha_description"
+msgstr "Add-ons compatible with an alpha version of %1$s"
+
+msgid "compatibility_report_legend_beta"
+msgstr "Beta Versions"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+msgid "compatibility_report_legend_beta_description"
+msgstr "Add-ons compatible with a beta version or release candidate of %1$s"
+
+msgid "compatibility_report_legend_latest"
+msgstr "Latest Version"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+msgid "compatibility_report_legend_latest_description"
+msgstr "Add-ons up-to-date with the latest builds of %1$s"
+
+msgid "compatibility_report_legend_other"
+msgstr "Other Versions"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+msgid "compatibility_report_legend_other_description"
+msgstr "Add-ons not compatible with any version of %1$s"
+
+msgid "compatibility_report_title"
+msgstr "Add-on Compatibility Report"
+
+msgid "compatibility_user_info"
+msgstr "Information for Add-on Users"
+
+msgid "compatibility_view_report"
+msgstr "View Compatibility Report"
+
+#. %s is a URL
+#, php-format
+msgid "credits_contributing"
+msgstr "For information on contributing, please see our %s."
+
+msgid "credits_contributing_wikipage"
+msgstr "wiki page"
+
+msgid "credits_intro"
+msgstr ""
+"Mozilla would like to thank the following people for their contributions to "
+"the addons.mozilla.org project over the years:"
+
+msgid "credits_section_developers"
+msgstr "Developers"
+
+msgid "credits_section_editors"
+msgstr "Editors"
+
+msgid "credits_section_localizers"
+msgstr "Localizers"
+
+msgid "credits_section_other_contributors"
+msgstr "Other Contributors"
+
+msgid "credits_section_past_developers"
+msgstr "Past Developers"
+
+msgid "credits_section_software"
+msgstr "Software and Images"
+
+msgid "credits_software_famfamfam"
+msgstr ""
+"Some icons used are from the <a href=\"http://www.famfamfam.com/lab/icons/"
+"silk/\">famfamfam Silk Icon Set</a>, licensed under a <a href=\"http://"
+"creativecommons.org/licenses/by/2.5/\">Creative Commons Attribution 2.5 "
+"License</a>."
+
+msgid "credits_software_timeplot"
+msgstr ""
+"Some pages use elements of <a href=\"http://www.simile-widgets.org/timeplot/"
+"\">Timeplot</a>, licensed under a <a href=\"http://simile.mit.edu/license."
+"html\">BSD License</a>."
+
+#. date format string as used in PHP's strftime():
+#. http://php.net/strftime
+msgid "date"
+msgstr "%B %e, %Y"
+
+#. date and time format string (strftime)
+#. http://php.net/strftime
+msgid "datetime"
+msgstr "%B %e, %Y, %I:%M %p"
+
+msgid "downloads_disable_warning"
+msgstr "This add-on is disabled"
+
+msgid "error_access_denied"
+msgstr "Access Denied"
+
+msgid "error_access_denied_message"
+msgstr "You are not authorized to view this page."
+
+msgid "error_addon_notfound"
+msgstr "Add-on not found!"
+
+msgid "error_addon_notviewable"
+msgstr "This add-on is not viewable here."
+
+msgid "error_addon_selfreview"
+msgstr "You cannot review your own add-on."
+
+msgid "error_browse_no_addons"
+msgstr "No add-ons in this category!"
+
+msgid "error_collection_feed_notfound"
+msgstr "Add-on feed not found."
+
+msgid "error_email_invalid"
+msgstr "This is not a valid email address."
+
+msgid "error_field_required"
+msgstr "This field must not be empty."
+
+msgid "error_file_notfound"
+msgstr "File not found!"
+
+#. %s is a filename
+#, php-format
+msgid "error_file_x_notfound"
+msgstr "File error: %s does not exist."
+
+msgid "error_formerrors"
+msgstr "There are errors in this form. Please correct them and resubmit."
+
+msgid "error_invalid_captcha"
+msgstr "Invalid captcha, please try again!"
+
+msgid "error_invalid_url"
+msgstr ""
+"This URL has an invalid format. Valid URLs look like http://example.com/"
+"my_page."
+
+#. %s is a string representing what's missing. Example: file_id
+#, php-format
+msgid "error_missing_argument"
+msgstr "Missing argument: %s"
+
+msgid "error_no_files_in_addon"
+msgstr "No Files"
+
+msgid "error_preview_notfound"
+msgstr "Preview not found!"
+
+msgid "error_review_rating_required"
+msgstr "You must select a rating."
+
+msgid "error_user_already_confirmed"
+msgstr "This user account is already confirmed."
+
+msgid "error_user_badconfirmationcode"
+msgstr "Invalid confirmation code!"
+
+msgid "error_user_confirmpw_nomatch"
+msgstr "The passwords did not match."
+
+msgid "error_user_email_notunique"
+msgstr "This email address is already taken by another user."
+
+msgid "error_user_emailchange_expired"
+msgstr ""
+"The email change has expired. Please change your email address again in your "
+"user profile and click the link in the confirmation email as soon as you "
+"receive it."
+
+msgid "error_user_nickname_notunique"
+msgstr "This nickname is already taken."
+
+msgid "error_user_notfound"
+msgstr "User not found!"
+
+msgid "error_user_unconfirmed"
+msgstr ""
+"Please confirm your user account first with the code you received by email."
+
+msgid "error_username_or_pw_wrong"
+msgstr "Wrong username or password!"
+
+msgid "error_version_notfound"
+msgstr "Version not found!"
+
+msgid "error_wrong_password"
+msgstr "Wrong password entered!"
+
+msgid "feature_learnmore"
+msgstr "Learn more"
+
+#. %1 is the add-on name
+#, php-format
+msgid "feature_learnmore_about_addon"
+msgstr "Learn more about %1$s"
+
+#. %1$s is a number
+#, php-format
+msgid "feature_reviews"
+msgid_plural "feature_reviews"
+msgstr[0] "%1$s review"
+msgstr[1] "%1$s reviews"
+
+msgid "feature_view_more_from_category"
+msgstr "View more from"
+
+#. This appears on a page that views the source of an add-on. This link will return
+#. the user to the add-on's main page
+msgid "file_browser_link_addon"
+msgstr "Back to add-on"
+
+#. There is a list of directories and files on the page. Clicking this will show the
+#. contents of all the directories (normally you would click on each one to see the
+#. contents)
+msgid "file_browser_link_expand_all"
+msgstr "Expand all"
+
+#. This appears on a page that views the source of an add-on. This link will return
+#. the user to the add-on's review page (it only appears if the add-on is being
+#. reviewed)
+msgid "file_browser_link_review"
+msgstr "Back to review"
+
+#. The title of the page for viewing an add-on's source.
+#. %1$s is the name of the add-on
+#. %2$s is the name of the current application (e.g. Firefox or Thunderbird)
+msgid "file_browser_title"
+msgstr "%1$s :: File Browser :: %2$s Add-ons"
+
+#. This appears on a page that views the source of an add-on. There is a list of
+#. directories and files on the page. Clicking this link will toggle between an
+#. expanded or a collapsed list. This string should be kept short.
+msgid "file_browser_toggle_expand_collapse"
+msgstr "+/-"
+
+#. Link text for the AMO About page.
+msgid "footer_a_about"
+msgstr "About"
+
+#. Link text to the AMO blog.
+msgid "footer_a_blog"
+msgstr "Blog"
+
+#. Link text to the Frequently Asked Questions page.
+msgid "footer_a_faq"
+msgstr "FAQ"
+
+#. Full text for the FAQ abbreviation.
+msgid "footer_abbr_faq"
+msgstr "Frequently Asked Questions"
+
+msgid "footer_all_rights_reserved"
+msgstr "All rights reserved."
+
+msgid "footer_copyright"
+msgstr "Copyright"
+
+msgid "footer_credits"
+msgstr "Credits"
+
+msgid "footer_disclaimer"
+msgstr ""
+"Mozilla is providing links to these applications as a courtesy, and makes no "
+"representations regarding the applications or any information related there "
+"to. Any questions, complaints or claims regarding the applications must be "
+"directed to the appropriate software vendor."
+
+msgid "footer_lang_form_lang_submit_go"
+msgstr "Go"
+
+msgid "footer_legal_notices"
+msgstr "Legal Notices"
+
+msgid "footer_other_languages"
+msgstr "Other languages:"
+
+msgid "footer_privacy_policy"
+msgstr "Privacy Policy"
+
+msgid "general_addontype_dict"
+msgstr "Dictionary"
+
+#. Plural in this context means many of the add-on type
+msgid "general_addontype_dict_plural"
+msgstr "Dictionaries"
+
+msgid "general_addontype_extension"
+msgstr "Extension"
+
+#. Plural in this context means many of the add-on type
+msgid "general_addontype_extension_plural"
+msgstr "Extensions"
+
+msgid "general_addontype_lpaddon"
+msgstr "Language Pack (Add-on)"
+
+#. Plural in this context means many of the add-on type
+msgid "general_addontype_lpaddon_plural"
+msgstr "Language Packs (Add-on)"
+
+msgid "general_addontype_lpapp"
+msgstr "Language Pack (Application)"
+
+#. Plural in this context means many of the add-on type
+msgid "general_addontype_lpapp_plural"
+msgstr "Language Packs (Application)"
+
+msgid "general_addontype_plugin"
+msgstr "Plugin"
+
+#. Plural in this context means many of the add-on type
+msgid "general_addontype_plugin_plural"
+msgstr "Plugins"
+
+msgid "general_addontype_search"
+msgstr "Search Engine"
+
+#. Plural in this context means many of the add-on type
+msgid "general_addontype_search_plural"
+msgstr "Search Engines"
+
+msgid "general_addontype_theme"
+msgstr "Theme"
+
+#. Plural in this context means many of the add-on type
+msgid "general_addontype_theme_plural"
+msgstr "Themes"
+
+#. %1$s is the application name. Example: Firefox
+#, php-format
+msgid "header_home_tooltip"
+msgstr "Return to the %1$s Add-ons homepage"
+
+msgid "header_main_firefox_header"
+msgstr "Firefox Add-ons"
+
+msgid "header_main_header"
+msgstr "Add-ons"
+
+msgid "header_main_seamonkey_header"
+msgstr "SeaMonkey Add-ons"
+
+msgid "header_main_sunbird_header"
+msgstr "Sunbird Add-ons"
+
+msgid "header_main_thunderbird_header"
+msgstr "Thunderbird Add-ons"
+
+msgid "header_navlink_addons"
+msgstr "Add-ons"
+
+msgid "header_navlink_login"
+msgstr "Log in"
+
+msgid "header_navlink_logout"
+msgstr "Log out"
+
+msgid "header_navlink_myaccount"
+msgstr "My Account"
+
+msgid "header_navlink_register"
+msgstr "Register"
+
+msgid "home"
+msgstr "home"
+
+#. %s is the add-on name
+#, php-format
+msgid "img_preview_of"
+msgstr "Preview Image of %s"
+
+#. %1 is the login URL for the link tag
+#. %2 is the link to an explanatory page.
+msgid "install_a_login_to_install"
+msgstr ""
+"<a href=\"%1$s\">Log in</a> to install this experimental add-on. <a href=\"%2"
+"$s\">Why</a>?"
+
+#. %1 is the URL for the Experimental Add-ons section of the FAQ page
+msgid "install_button_confirm_exp_install"
+msgstr ""
+"Let me install this experimental add-on. <a href=\"%1$s\">What's this?</a>"
+
+#. %1$s is the application name. Example: Firefox
+#. %2$s is an optional string used to specify a platform. Example: (Windows)
+#, php-format
+msgid "install_button_text"
+msgstr "Add to %1$s %2$s"
+
+#. %1 is the add-on name, %2 is the app name
+#, php-format
+msgid "install_button_title"
+msgstr "Add %1$s to %2$s"
+
+#. %1$s is the add-on name
+#, php-format
+msgid "install_download"
+msgstr "Download %1$s"
+
+msgid "install_error_addon_not_found"
+msgstr "This add-on is not available."
+
+msgid "langtools_a11y_tablesummary"
+msgstr "List of language packs and dictionaries."
+
+msgid "langtools_download_dictionary"
+msgstr "Download Dictionary"
+
+msgid "langtools_download_langpack"
+msgstr "Download Language Pack"
+
+msgid "langtools_header_dicts_and_langpacks"
+msgstr "Dictionaries & Language Packs"
+
+msgid "langtools_install_dictionary"
+msgstr "Install Dictionary"
+
+msgid "langtools_install_langpack"
+msgstr "Install Language Pack"
+
+msgid "langtools_tableheader_dictionary"
+msgstr "Dictionary"
+
+msgid "langtools_tableheader_langpack"
+msgstr "Language Pack"
+
+msgid "langtools_tableheader_language"
+msgstr "Language"
+
+msgid "license_custom"
+msgstr "Custom License"
+
+msgid "licenses_bsd"
+msgstr "BSD License"
+
+msgid "licenses_gpl_2.0"
+msgstr "GNU General Public License, version 2.0"
+
+msgid "licenses_gpl_3.0"
+msgstr "GNU General Public License, version 3.0"
+
+msgid "licenses_lgpl_2.1"
+msgstr "GNU Lesser General Public License, version 2.1"
+
+msgid "licenses_lgpl_3.0"
+msgstr "GNU Lesser General Public License, version 3.0"
+
+msgid "licenses_mit"
+msgstr "MIT/X11 License"
+
+msgid "licenses_mpl_1.1"
+msgstr "Mozilla Public License, version 1.1"
+
+msgid "link_return_to_front_page"
+msgstr "Click here to return to the front page."
+
+msgid "list_sortby_date"
+msgstr "Date"
+
+msgid "list_sortby_downloads"
+msgstr "Downloads"
+
+msgid "list_sortby_name"
+msgstr "Add-on Name"
+
+msgid "list_sortby_rating"
+msgstr "Rating"
+
+msgid "main_prettyname_fennec"
+msgstr "Fennec"
+
+msgid "main_prettyname_firefox"
+msgstr "Firefox"
+
+msgid "main_prettyname_seamonkey"
+msgstr "SeaMonkey"
+
+msgid "main_prettyname_sunbird"
+msgstr "Sunbird"
+
+msgid "main_prettyname_thunderbird"
+msgstr "Thunderbird"
+
+msgid "nav_category_dicts_langpacks"
+msgstr "Dictionaries & Language Packs"
+
+msgid "nav_category_themes"
+msgstr "Themes"
+
+msgid "other_apps_tooltip"
+msgstr "Find add-ons for other applications"
+
+#. In a user list: user 1, user 2, "others"
+msgid "other_users"
+msgstr "others"
+
+msgid "page_title_appversions"
+msgstr "Application Versions"
+
+msgid "page_title_credits"
+msgstr "Credits"
+
+msgid "page_title_developer_faq"
+msgstr "Developer FAQ"
+
+msgid "page_title_faq"
+msgstr "Frequently Asked Questions"
+
+msgid "page_title_fashionyourfirefox_faq"
+msgstr "Fashion your Firefox FAQ"
+
+msgid "page_title_policy"
+msgstr "Add-ons Policy"
+
+msgid "page_title_privacy"
+msgstr "Mozilla Privacy Policy"
+
+msgid "page_title_review_guide"
+msgstr "Review Guidelines"
+
+msgid "page_title_sandbox"
+msgstr "Sandbox Review System"
+
+msgid "page_title_submissionhelp"
+msgstr "Submission Help"
+
+msgid "pages_appversions_guid"
+msgstr "GUID"
+
+msgid "pages_appversions_header"
+msgstr "Valid Application Versions"
+
+msgid "pages_appversions_intro"
+msgstr ""
+"Add-ons submitted to Mozilla Add-ons must have an install.rdf file with at "
+"least one of the below applications supported. Only the versions listed "
+"below are allowed for these applications."
+
+#. %s is a full <a> tag
+#, php-format
+msgid "pages_appversions_required_files"
+msgstr ""
+"If your supported application does not require an install.rdf file, you "
+"still must include one with the required properties as specified %s."
+
+#. this is the text inside of an <a> tag for pages_appversions_required_files. This
+#. should be fixed.
+msgid "pages_appversions_required_files_link"
+msgstr "here"
+
+msgid "pages_appversions_versions"
+msgstr "Versions"
+
+msgid "pages_policy_sandbox_link"
+msgstr "Sandbox Information Page"
+
+msgid "pagination_next_page"
+msgstr "next"
+
+#. %1 is page number, %2 is total page count
+#, php-format
+msgid "pagination_page_number_title"
+msgstr "This is page %1$s of %2$s"
+
+msgid "pagination_previous_page"
+msgstr "previous"
+
+msgid "recaptcha_enter_both_words"
+msgstr ""
+"Please enter <strong>both words</strong> below, <strong>separated by a "
+"space</strong>."
+
+msgid "recaptcha_enter_here"
+msgstr "Enter your answer here:"
+
+msgid "recaptcha_enter_whatyouhear"
+msgstr "Please type what you hear."
+
+#. %1 is the link switching refreshing the captcha
+#. %2 is the link switching to a text captcha
+msgid "recaptcha_hardtohear_text"
+msgstr ""
+"If this is hard to understand, you can <a href=\"%1$s\">listen to something "
+"else</a> or <a href=\"%2$s\">switch back to text</a>."
+
+#. %1 is the link switching refreshing the captcha
+#. %2 is the link switching to an audio captcha
+msgid "recaptcha_hardtoread_text"
+msgstr ""
+"If this is hard to read, you can <a href=\"%1$s\">try different words</a> or "
+"<a href=\"%2$s\">listen to something</a> instead."
+
+msgid "recaptcha_label"
+msgstr "Are you human?"
+
+msgid "recaptcha_whatsthis"
+msgstr "What's this?"
+
+msgid "review_flag_error"
+msgstr "Error flagging this review!"
+
+msgid "review_flag_reason_bug_support"
+msgstr "Misplaced bug report or support request"
+
+msgid "review_flag_reason_instructions"
+msgstr "Report this review (select a reason)"
+
+msgid "review_flag_reason_language"
+msgstr "Inappropriate language/dialog"
+
+msgid "review_flag_reason_other"
+msgstr "Other (please specify)"
+
+msgid "review_flag_reason_spam"
+msgstr "Spam or otherwise non-review content"
+
+msgid "review_flag_success"
+msgstr "Thanks; this review has been flagged for editor approval."
+
+msgid "review_flag_this"
+msgstr "Report this review"
+
+msgid "review_flag_this_titletip"
+msgstr ""
+"Is this review inappropriate, inaccurate or spam? Click here to flag it for "
+"editor review."
+
+#. %1 is the URL of the support section, %2 for the review guidelines
+msgid "review_guidelines_short"
+msgstr ""
+"<p>Keep these tips in mind:</p><ul><li>Write like you're telling a friend "
+"about your experience with the add-on. Give specifics and helpful details, "
+"such as what features you liked and/or disliked, how easy to use it is, and "
+"any disadvantages it has. Avoid generic language such as calling it \"Great"
+"\" or \"Bad\" unless you can give reasons why you believe this is so.</"
+"li><li>Please do not post bug reports in reviews. We do not make your email "
+"address available to add-on developers and they may need to contact you to "
+"help resolve your issue. See the <a href=\"%1$s\">support section</a> to "
+"find out where to get assistance for this add-on.</li><li>Please keep "
+"reviews clean, avoid the use of improper language and do not post any "
+"personal information.</li></ul><p>Please read the <a href=\"%2$s\">Review "
+"Guidelines</a> for more detail about user add-on reviews.</p>"
+
+#. %1 is the add-on name
+#, php-format
+msgid "reviews_header"
+msgstr "Reviews for %s"
+
+msgid "rss_featuredaddons"
+msgstr "Featured Add-ons"
+
+msgid "rss_newestaddons"
+msgstr "Newest Add-ons"
+
+msgid "rss_updatedaddons"
+msgstr "Updated Add-ons"
+
+msgid "search"
+msgstr "Search"
+
+msgid "search_disabled"
+msgstr "Search is currently disabled. Please try again later."
+
+msgid "search_form_all_addons"
+msgstr "all add-ons"
+
+msgid "search_form_default_text"
+msgstr "search for add-ons"
+
+msgid "search_form_submit_tooltip"
+msgstr "Search for add-ons"
+
+msgid "search_form_tooltip"
+msgstr "Click to enter search terms"
+
+msgid "search_form_within"
+msgstr "within"
+
+msgid "search_landing_all_search_engines"
+msgstr "All Search Engines"
+
+msgid "search_landing_browse_search_engines"
+msgstr "Browse Search Engines"
+
+#. %s is a number
+#, php-format
+msgid "search_matching_addons_number"
+msgid_plural "search_matching_addons_number"
+msgstr[0] "%s matching add-on"
+msgstr[1] "%s matching add-ons"
+
+msgid "search_nothing_found"
+msgstr "No results found."
+
+msgid "search_pagetitle"
+msgstr "Search Add-ons"
+
+msgid "search_rss_description"
+msgstr "Search results feed"
+
+#. %s is the terms the user is searching for (a string)
+#, php-format
+msgid "search_rss_results_for"
+msgstr "Search results for: %s"
+
+msgid "sidebar_navlink_admin_tools"
+msgstr "Admin Tools"
+
+msgid "sidebar_navlink_developer_tools"
+msgstr "Developer Tools"
+
+msgid "sidebar_navlink_editor_tools"
+msgstr "Editor Tools"
+
+msgid "sidebar_navlink_welcome"
+msgstr "Welcome"
+
+#. %s is the user's name
+#, php-format
+msgid "sidebar_navlink_welcome_name"
+msgstr "Welcome, %s"
+
+msgid "sidebar_pitch_dictionary"
+msgstr "Dictionary"
+
+msgid "sidebar_pitch_featured_addons"
+msgstr "Featured Add-ons"
+
+msgid "sidebar_pitch_looking_for"
+msgstr "I am looking for a:"
+
+msgid "sidebar_pitch_newest_addons"
+msgstr "Newest Add-ons"
+
+msgid "sidebar_pitch_search"
+msgstr "Search Plugin"
+
+msgid "sidebar_pitch_subscribe_to"
+msgstr "Subscribe to"
+
+msgid "sidebar_pitch_theme"
+msgstr "Theme"
+
+msgid "sidebar_pitch_updated_addons"
+msgstr "Updated Add-ons"
+
+#. %1$s is a number
+#, php-format
+msgid "size_kb"
+msgstr "%1$s KB"
+
+msgid "stars_not_yet_rated"
+msgstr "Not yet rated"
+
+#. %1 is the number of stars this add-on has
+#, php-format
+msgid "stars_rated_x_outof_5"
+msgstr "Rated %s out of 5 stars"
+
+msgid "themes_landing_all_themes"
+msgstr "All Themes"
+
+msgid "themes_landing_browse_themes"
+msgstr "Browse Themes"
+
+msgid "user_change_email"
+msgstr "Change Email Address"
+
+msgid "user_change_password"
+msgstr "Change password"
+
+msgid "user_confirmationcode_resent"
+msgstr "The confirmation code was resent!"
+
+#. %1 is the email address, %2 is the URL of the user registration page
+msgid "user_del_account_deleted"
+msgstr ""
+"Your user account %1$s has been successfully deleted. If you want to come "
+"back some time, you can re-register on the <a href=\"%2$s\">user "
+"registration page</a>."
+
+msgid "user_del_community_sad"
+msgstr "The Mozilla Add-ons community is sad to see you go."
+
+msgid "user_del_confirm_password"
+msgstr "Confirm Password"
+
+msgid "user_del_deletenow"
+msgstr "Delete my user account now"
+
+#. %1 is the URL of the user's info page
+msgid "user_del_error_addons"
+msgstr ""
+"You cannot delete your account if you are listed as an <a href=\"%1$s"
+"\">author of any add-ons</a>. To delete your account, please have another "
+"person in your development group delete you from the list of authors for "
+"your add-ons. Afterwards you will be able to delete your account here."
+
+#. %1 is a link to the amo-editors mailing list
+msgid "user_del_error_addons_more_questions"
+msgstr "If you have additional questions, please contact %1$s for assistance."
+
+msgid "user_del_error_checkbox"
+msgstr ""
+"You need to check the box \"I understand...\" before we can delete your "
+"account."
+
+msgid "user_del_error_password"
+msgstr "Please enter your password correctly in order to perform this step."
+
+#. %1 is a link to the amo-admins mailing list
+msgid "user_del_error_unknown"
+msgstr ""
+"An unknown error occured deleting your account. Please contact %1$s with the "
+"issue and we will delete it for you. We apologize for the inconvenience."
+
+msgid "user_del_header_confirm_deletion"
+msgstr "Confirm account deletion"
+
+#. %1 is the user's email address
+msgid "user_del_header_delete_account"
+msgstr "Delete User Account %1$s"
+
+msgid "user_del_header_farewell"
+msgstr "Farewell!"
+
+msgid "user_del_nologin"
+msgstr "You will not be able to log into Mozilla Add-ons anymore."
+
+msgid "user_del_permanently_removed_means"
+msgstr ""
+"By clicking \"delete\" your account is going to be <strong>permanently "
+"removed</strong>. That means:"
+
+msgid "user_del_reviews_anonymized"
+msgstr ""
+"Your reviews and ratings will not be deleted, but they will no longer be "
+"associated with you."
+
+#. %1 is a link to the amo-editors mailing list
+msgid "user_del_specific_problem_editors"
+msgstr ""
+"If you have a specific problem we may help you with, please do not delete "
+"your account now, but contact us at %1$s and we will do our best to assist "
+"you in solving it."
+
+msgid "user_del_understand_permanent"
+msgstr "I understand that this step cannot be undone."
+
+msgid "user_deleted_nickname"
+msgstr "Deleted User"
+
+#. %1 is the new email address
+msgid "user_edit_confirm_email_sent"
+msgstr ""
+"An email has been sent to %1$s to confirm your new email address. For the "
+"change to take effect, you need to click on the link provided in this email. "
+"Until then, you can keep logging in with your current email address."
+
+msgid "user_edit_delete_user"
+msgstr "Delete user account"
+
+#. This contains the email sent to users when they signed up for a new
+#. account:
+#. %1 is the confirmation URL, %2 is the current app
+#, php-format
+msgid "user_email_confirm_account_nopass"
+msgstr ""
+"Welcome to %2$s Add-ons.\n"
+"\n"
+"Before you can use your new account you must activate it - this ensures the "
+"e-mail address you used is valid and belongs to you.\n"
+"To activate your account, click the link below or copy and paste the whole "
+"thing into your browser's location bar:\n"
+"\n"
+"%1$s\n"
+"\n"
+"Once you successfully activated your account, you can throw away this e-"
+"mail.\n"
+"\n"
+"Thanks for joining %2$s Add-ons\n"
+"-- %2$s Add-ons Staff"
+
+#. %1 is the confirmation url, %2 is the application name
+msgid "user_email_confirm_emailchange"
+msgstr ""
+"You requested a change to your email address at %2$s Add-ons.\n"
+"\n"
+"In order to confirm the new address, please click the link below or copy and "
+"paste the whole thing into your browser's location bar:\n"
+"\n"
+"%1$s\n"
+"\n"
+"You have 48 hours to confirm the new address. If you do not want to change "
+"the address anymore, you can just ignore this email.\n"
+"\n"
+"Thanks!\n"
+"-- %2$s Add-ons Staff"
+
+#, php-format
+msgid "user_email_confirm_subject"
+msgstr "Thanks for joining %s Add-ons"
+
+#. This is the password reset email
+#. %1 is the pw reset URL, %2 is the application
+#, php-format
+msgid "user_email_pwreset"
+msgstr ""
+"%2$s Add-ons Password Reset\n"
+"\n"
+"A request was received to reset the password for this account on addons."
+"mozilla.org. To change this password please click on the following link, or "
+"paste it into your browser's location bar:\n"
+"\n"
+"%1$s\n"
+"\n"
+"If you did not request this email there is no need for further action.\n"
+"\n"
+"Thanks,\n"
+"-- %2$s Add-ons Staff"
+
+#, php-format
+msgid "user_email_pwreset_subject"
+msgstr "Reset your %s Add-ons password"
+
+msgid "user_emailchange_error"
+msgstr "Error!"
+
+#. %1 is the application name
+msgid "user_emailchange_subject"
+msgstr "Please confirm your email address change at %1$s Add-ons"
+
+msgid "user_emailchange_success"
+msgstr "Success!"
+
+#. %1 is the new email address
+msgid "user_emailchange_successful_description"
+msgstr ""
+"Your email address was changed successfully. From now on, please use %1$s to "
+"log in."
+
+msgid "user_form_bio"
+msgstr "About me"
+
+msgid "user_form_bio_description"
+msgstr ""
+"Introduce yourself to the community, if you like! This text will appear "
+"publicly on your user info page. Line breaks will be preserved, but no HTML "
+"is allowed."
+
+msgid "user_form_confirmpassword"
+msgstr "Confirm password"
+
+#, php-format
+msgid "user_form_editprofile"
+msgstr "Edit user profile for %s"
+
+msgid "user_form_email"
+msgstr "Email address"
+
+msgid "user_form_firstname"
+msgstr "First name"
+
+msgid "user_form_hideemail"
+msgstr "Hide email address"
+
+msgid "user_form_homepage"
+msgstr "Website URL"
+
+msgid "user_form_lastname"
+msgstr "Last name"
+
+msgid "user_form_login"
+msgstr "User Login"
+
+msgid "user_form_newpassword"
+msgstr "New password"
+
+msgid "user_form_nickname"
+msgstr "Nickname"
+
+msgid "user_form_oldpassword"
+msgstr "Old password"
+
+msgid "user_form_otheractions"
+msgstr "Other Actions"
+
+msgid "user_form_password"
+msgstr "Password"
+
+msgid "user_form_registration"
+msgstr "New User Registration"
+
+msgid "user_form_remember_me"
+msgstr "Remember me on this computer"
+
+msgid "user_form_showsandbox"
+msgstr "Show sandbox?"
+
+msgid "user_form_submit_edit"
+msgstr "Save"
+
+msgid "user_form_submit_login"
+msgstr "Log in"
+
+msgid "user_form_submit_register"
+msgstr "Register"
+
+#, php-format
+msgid "user_info_usersince"
+msgstr "%s Add-ons user since"
+
+msgid "user_login_register_link"
+msgstr "Create a new user account"
+
+msgid "user_notifications_item_compat"
+msgstr "Add-on Compatibility (strongly recommended)"
+
+msgid "user_notifications_item_events"
+msgstr "Upcoming events and contests"
+
+msgid "user_notifications_none_available"
+msgstr "There are currently no notifications available for you to configure."
+
+msgid "user_notifications_select_topics"
+msgstr ""
+"From time to time, Mozilla may send you email about upcoming releases and "
+"add-on events. Please select the topics you are interested in below:"
+
+msgid "user_notifications_specific_contact"
+msgstr ""
+"Mozilla reserves the right to contact you individually about specific "
+"concerns with your hosted add-ons."
+
+msgid "user_profile_edit_error"
+msgstr ""
+"There were errors in the changes you made. Please correct them and resubmit."
+
+msgid "user_profile_saved"
+msgstr "Profile updated."
+
+#, php-format
+msgid "user_pwreset_for_email"
+msgstr "Password reset for %s"
+
+msgid "user_pwreset_header"
+msgstr "Password Reset"
+
+msgid "user_pwreset_link"
+msgstr "Forgot your password?"
+
+msgid "user_pwreset_link_sent"
+msgstr "The password reset link was sent to your email address."
+
+msgid "user_pwreset_okay"
+msgstr "Password successfully reset."
+
+msgid "user_pwreset_submit_changepw"
+msgstr "Submit password change"
+
+msgid "user_pwreset_submit_sendlink"
+msgstr "Send password reset link"
+
+#, php-format
+msgid "user_register_amo_link"
+msgstr "%s Add-ons"
+
+#. %1 is the user's email address, %2 is the current app
+#, php-format
+msgid "user_register_click_confirm_link"
+msgstr ""
+"A link to activate your user account was sent by email to your address %1$s. "
+"You have to click it before you can log into %2$s Add-ons."
+
+#. %1 is the user's email address
+#, php-format
+msgid "user_register_confirm_email_sent"
+msgstr ""
+"An email has been sent to your address %1$s to confirm your account. Before "
+"you can log in, you have to activate your account by clicking on the link "
+"provided in this email."
+
+msgid "user_register_confirmation_link_text"
+msgstr "resend the confirmation message"
+
+msgid "user_register_congratulations"
+msgstr "Congratulations! Your user account was successfully created."
+
+msgid "user_register_details"
+msgstr ""
+"<p>Registration on AMO is <strong>not required</strong> if you simply want "
+"to download and install public add-ons.</p><p>You only need to register if:</"
+"p><ul><li>You want to submit reviews for add-ons</li><li>You are an add-on "
+"developer and want to upload your add-on for hosting on AMO</li></ul><p>Upon "
+"successful registration, you will be sent a confirmation email to the "
+"address you provided. Please follow the instructions there to confirm your "
+"account.</p><p>If you like, you can read our <a href='%1$s' title='Legal "
+"Notices'>Legal Notices</a> and <a href='%2$s' title='Privacy Policy'>Privacy "
+"Policy</a>.</p>"
+
+#. %1 is the link to the "resend confirmation code" page
+#, php-format
+msgid "user_register_resend_confirmation_link"
+msgstr ""
+"If you did not receive the confirmation email, make sure your email service "
+"did not mark it as \"junk mail\" or \"spam\". If you need to, you can have "
+"us %1$s to your email address mentioned above."
+
+#. %1 is the link to the Mozilla Add-ons front page
+#, php-format
+msgid "user_register_welcome"
+msgstr "Thanks for registering and welcome to %1$s!"
+
+msgid "user_register_welcome_header"
+msgstr "Welcome to addons.mozilla.org (AMO)!"
+
+msgid "user_required_firstlast_or_nickname"
+msgstr "A first name, last name or nickname is required."
+
+msgid "user_tab_notifications"
+msgstr "Notifications"
+
+msgid "user_tab_profile"
+msgstr "User Profile"
+
+msgid "user_verified_okay"
+msgstr "Successfully verified!"
+
+msgid "users_delete_pagetitle"
+msgstr "Delete User Account"
+
+msgid "users_edit_pagetitle"
+msgstr "User Account Editing"
+
+msgid "users_info_aboutme"
+msgstr "About Me"
+
+#, php-format
+msgid "users_info_addons_by_user"
+msgstr "Add-ons by %1$s"
+
+msgid "users_info_author_name"
+msgstr "Name"
+
+msgid "users_info_author_profile"
+msgstr "User Profile"
+
+msgid "users_info_email"
+msgstr "Email address"
+
+msgid "users_info_homepage"
+msgstr "Homepage"
+
+msgid "users_info_nickname"
+msgstr "Nickname"
+
+#, php-format
+msgid "users_info_pagetitle"
+msgstr "User Info for %1$s"
+
+#. %1 is the user's name
+msgid "users_info_reviews_by_user"
+msgstr "Reviews by %s"
+
+msgid "users_login_pagetitle"
+msgstr "User Login"
+
+#. %1 is the link to the sandbox/policy explanation page
+#. This message is for a specific add-on not found
+#, php-format
+msgid "users_login_sandbox_display_warning"
+msgstr ""
+"The add-on you're looking for is currently in the sandbox. If you already "
+"have an account on Mozilla Add-ons, please log in, or <a href=\"%1$s\">learn "
+"more about the sandbox.</a>"
+
+#. %1 is the link to the sandbox/policy explanation page
+#. This message is for any given sandbox-related page not found
+#, php-format
+msgid "users_login_sandbox_page_warning"
+msgstr ""
+"The page you're looking for is part of the sandbox. If you already have an "
+"account on Mozilla Add-ons, please log in, or <a href=\"%1$s\">learn more "
+"about the sandbox.</a>"
+
+msgid "users_pwreset_pagetitle"
+msgstr "User Password Reset"
+
+msgid "users_register_pagetitle"
+msgstr "New User Registration"
+
+#. %1$s is an addon name, like <a>Firebug</a>
+#. %2$s is a version number, like <a>1.2</a>
+msgid "versions_license_header_source"
+msgstr "Source code license for %1$s %2$s"
+
+msgid "view_recently_added"
+msgstr "View all recently added"
+
+msgid "view_top_downloads"
+msgstr "View all top downloads"
+
+msgid "view_top_rated"
+msgstr "View all top rated"
diff --git a/site/app/locale/da/LC_MESSAGES/messages.mo b/site/app/locale/da/LC_MESSAGES/messages.mo
new file mode 100644
index 0000000..294e8fe
--- /dev/null
+++ b/site/app/locale/da/LC_MESSAGES/messages.mo
Binary files differ
diff --git a/site/app/locale/da/LC_MESSAGES/messages.po b/site/app/locale/da/LC_MESSAGES/messages.po
new file mode 100644
index 0000000..c0ee94d
--- /dev/null
+++ b/site/app/locale/da/LC_MESSAGES/messages.po
@@ -0,0 +1,7539 @@
+# Language en-US translations for addons.mozilla.org package.
+# Copyright (C) 2009 THE addons.mozilla.org'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the addons.mozilla.org package.
+# Automatically generated, 2009.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: addons\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2009-01-16 11:45-0800\n"
+"PO-Revision-Date: 2009-02-26 15:08-0800\n"
+"Last-Translator: Jesper Kristensen <www.mozilladanmark.dk>\n"
+"Language-Team: Danish\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#: views/addons/policy.thtml:98
+msgid "a_cancel_installation"
+msgstr "Annuller installation"
+
+#. This is the text that appears on buttons to download add-ons.
+#. %$1s is an optional string that only appears if the add-on is only available for
+#. a certain platform. Examples: (Windows) or (Linux)
+#. Note that the parentheses are included in the string. :(
+#: views/elements/amo2009/install.thtml:126
+#: views/elements/amo2009/install.thtml:227
+#: views/elements/amo2009/install.thtml:257
+#: views/elements/amo2009/install.thtml:300
+#: views/elements/amo2009/install.thtml:312 views/elements/install.thtml:73
+#: views/elements/install.thtml:181 views/elements/install.thtml:205
+#: views/elements/install.thtml:248 views/elements/install.thtml:260
+#: views/addons/plugins.thtml:66 views/addons/plugins.thtml:76
+#: views/addons/plugins.thtml:86 views/addons/plugins.thtml:96
+#: views/addons/plugins.thtml:119
+#, php-format
+msgid "a_download"
+msgstr "Download nu %s"
+
+#: views/addons/policy.thtml:72
+msgid "a_eula_download"
+msgstr "Accepter og download"
+
+#: views/addons/policy.thtml:74
+msgid "a_eula_install"
+msgstr "Accepter og installer"
+
+#: views/elements/header.thtml:76 views/elements/header.thtml:82
+#: views/api/api_addon.thtml:55 views/api/collections_feed.thtml:75
+#: views/sharing_api/addon.thtml:64
+msgid "a_header_public"
+msgstr "Offentlig"
+
+#: views/elements/header.thtml:58 views/elements/header.thtml:75
+#: views/elements/header.thtml:80 views/api/api_addon.thtml:57
+#: views/api/collections_feed.thtml:77 views/sharing_api/addon.thtml:66
+msgid "a_header_sandbox"
+msgstr "Sandkasse"
+
+#. %s is a date in the _('date') format
+#: views/elements/amo2009/homepage_addon.thtml:115
+#: views/elements/addon_listitem.thtml:122 views/elements/feature.thtml:106
+#: views/addons/display.thtml:104 views/addons/browse_thumbs.thtml:73
+msgid "addon_detail_last_updated"
+msgstr "Opdateret %s"
+
+#. %s is the version of the add-on. Example: 3.2a1
+#: views/elements/amo2009/addon_version_detail.thtml:51
+#: views/elements/addon_version_detail.thtml:51
+#, php-format
+msgid "addon_display_header_version"
+msgstr "Version %s"
+
+#: views/addons/browse_thumbs.thtml:80
+msgid "addon_downloads"
+msgstr "downloads"
+
+#: views/addons/display.thtml:147
+msgid "addon_downloads_total"
+msgstr "downloads i alt"
+
+#: views/elements/amo2009/homepage_addon.thtml:106
+#: views/elements/addon_listitem.thtml:115 views/elements/feature.thtml:101
+#: views/addons/category_landing.thtml:157 views/addons/display.thtml:146
+#: views/addons/browse_thumbs.thtml:80
+msgid "addon_downloads_weekly"
+msgstr "downloads pr. uge"
+
+#. %1 is the add-on count, %2 the category name
+#: views/addons/browse_thumbs.thtml:104 views/addons/browse.thtml:60
+#, php-format
+msgid "addon_list_category_totalcount"
+msgid_plural "addon_list_category_totalcount"
+msgstr[0] "%1$s tilføjelse"
+msgstr[1] "%1$s tilføjelser"
+
+#: views/elements/amo2009/addon_list_options.thtml:103
+#: views/elements/pagination.thtml:67
+#: views/elements/addon_list_options.thtml:94
+msgid "addon_list_perpage"
+msgstr "pr. side"
+
+#: views/elements/amo2009/addon_list_options.thtml:84
+#: views/elements/addon_list_options.thtml:98
+msgid "addon_list_sortby"
+msgstr "Sorter efter:"
+
+#: views/helpers/addons_html.php:568 views/elements/amo2009/install.thtml:321
+#: views/elements/feature.thtml:89
+msgid "addon_listitem_flag_experimental"
+msgstr "eksperimentel"
+
+#: views/helpers/addons_html.php:570
+msgid "addon_listitem_flag_recommended"
+msgstr "anbefalet"
+
+#. %1 is the add-on name, %2 is the platform
+#: views/pages/js_constants.js.thtml:66
+msgid "addon_not_available_for_platform"
+msgstr "%1$s er ikke tilgængelig til %2$s."
+
+#. %1 is the add-on name
+#: views/addons/policy.thtml:101 views/addons/previews.thtml:60
+#: views/addons/versions.thtml:130 views/reviews/flag.thtml:61
+#: views/reviews/add.thtml:114 views/reviews/display.thtml:216
+#: views/reviews/review_added.thtml:57
+#, php-format
+msgid "addon_review_a_back_to_addon_x"
+msgstr "Tilbage til %1$s..."
+
+#. %1 is the add-on name
+#: views/reviews/flag.thtml:60 views/reviews/add.thtml:113
+#: views/reviews/review_added.thtml:56
+#, php-format
+msgid "addon_review_a_back_to_reviews"
+msgstr "Tilbage til anmeldelser..."
+
+#: views/reviews/add.thtml:85
+msgid "addon_review_add_rating_field"
+msgstr "Bedømmelse:"
+
+#: views/reviews/add.thtml:102
+msgid "addon_review_add_review_field"
+msgstr "Anmeldelse:"
+
+#: views/reviews/add.thtml:107
+msgid "addon_review_add_submit"
+msgstr "Indsend din anmeldelse"
+
+#. %s is the name of the add-on
+#: views/reviews/add.thtml:51
+#, php-format
+msgid "addon_review_add_title"
+msgstr "Tilføj en anmeldelse af %s"
+
+#: views/reviews/add.thtml:78
+msgid "addon_review_add_title_field"
+msgstr "Titel/resumé:"
+
+#: views/reviews/display.thtml:77 views/reviews/display.thtml:161
+msgid "addon_review_admin_delete"
+msgstr "Slet"
+
+#: views/reviews/display.thtml:76
+msgid "addon_review_author_reply_link"
+msgstr "Svar"
+
+#: views/reviews/delete.thtml:62
+msgid "addon_review_confirm_delete"
+msgstr "Er du sikker på, at du vil slette denne anmeldelse?"
+
+#: views/reviews/delete.thtml:63
+msgid "addon_review_confirm_no"
+msgstr "Nej"
+
+#: views/reviews/delete.thtml:64
+msgid "addon_review_confirm_yes"
+msgstr "Ja"
+
+#: views/reviews/delete.thtml:48
+msgid "addon_review_delete_header"
+msgstr "Slet anmeldelse"
+
+#: controllers/reviews_controller.php:449
+msgid "addon_review_deleted_successfully"
+msgstr "Anmeldelsen blev slettet."
+
+#. %s is the name of the add-on
+#: views/reviews/add.thtml:51
+#, php-format
+msgid "addon_review_edit_title"
+msgstr "Ret anmeldelse af %s"
+
+#. %1 is the count of characters entered as notes for the review flag reason.
+#: controllers/reviews_controller.php:539
+msgid "addon_review_flag_error_other_length"
+msgstr ""
+"Problem ved rapporteringen af anmeldelse: Bemærkninger til rapporterede "
+"anmeldelser skal være på mellem 10 og 100 tegn. Du har skrevet %1$s tegn."
+
+#. Removing an extra comma
+#: views/reviews/review_added.thtml:53
+msgid "addon_review_in_moderation"
+msgstr ""
+"Bemærk: Din anmeldelse vil blive gennemgået af en redaktør, før den kan ses "
+"på den offentlige side."
+
+#: views/reviews/add.thtml:57
+msgid "addon_review_in_reply_to"
+msgstr "Udviklersvar til:"
+
+#. %1 is the review count, %2 is the nickname or full name of the user.
+#: views/reviews/display.thtml:131
+#, php-format
+msgid "addon_review_others_by_user"
+msgid_plural "addon_review_others_by_user"
+msgstr[0] "Vis %1$s tidligere anmeldelse af denne tilføjelse indsendt af %2$s."
+msgstr[1] ""
+"Vis %1$s tidligere anmeldelser af denne tilføjelse indsendt af %2$s."
+
+#. %1 is the add-on name
+#: controllers/reviews_controller.php:201
+#: controllers/reviews_controller.php:250
+#: controllers/reviews_controller.php:345
+#: controllers/reviews_controller.php:424
+#, php-format
+msgid "addon_review_pagetitle"
+msgstr "Anmeldelser af %s"
+
+#. %1 is the user, %2 is the (localized) date
+#: views/reviews/display.thtml:160
+#, php-format
+msgid "addon_review_reply_on_x_by_y"
+msgstr "Svar fra %1$s den %2$s"
+
+#: views/reviews/display.thtml:157
+msgid "addon_review_reply_prefix"
+msgstr "Svar fra udvikleren:"
+
+#: views/reviews/review_added.thtml:51
+msgid "addon_review_saved_successfully"
+msgstr "Din anmeldelse er gemt. Tak!"
+
+#: views/addons/display.thtml:354 views/reviews/display.thtml:72
+msgid "addon_reviewed_by_u_on_d"
+msgstr "af %1$s den %2$s"
+
+#. %1 is the user, %2 is the (localized) date, %3 is the rating
+#: views/editors/reviews_queue.thtml:57 views/editors/reviews_queue.thtml:68
+#: views/reviews/add.thtml:63 views/reviews/delete.thtml:54
+#, php-format
+msgid "addon_reviewed_on_x_rated_y"
+msgstr "af %1$s den %2$s (bedømmelse %3$s)"
+
+#: views/elements/amo2009/addon_version_detail.thtml:52
+#: views/elements/addon_version_detail.thtml:52
+msgid "addon_version_permalink"
+msgstr "Permanent link til denne version"
+
+#. %1 is the current Application name (e.g. Firefox)
+#. %2 is the Application's version number
+#: views/addons/versions.thtml:140
+msgid "addon_versions_getlatestversion"
+msgstr "Seneste version, som er kompatibel med %1$s %2$s"
+
+#: views/addons/display.thtml:447
+msgid "addons_author_addons_submit"
+msgstr "Vis"
+
+#: views/elements/amo2009/homepage_addon.thtml:100
+#: views/elements/feature.thtml:95
+msgid "addons_author_tooltip"
+msgstr "Vis forfatterens profil"
+
+#. %1 is the name of the Application (eg. Firefox)
+#: controllers/addons_controller.php:1296
+msgid "addons_browse_all_themes_title"
+msgstr "Gennemse alle temaer :: %1$s Add-ons"
+
+#. %s is the name of the category
+#: controllers/addons_controller.php:1016
+#, php-format
+msgid "addons_browse_browse_category"
+msgstr "Gennemse %s"
+
+#. %1 is the name of the theme category (eg. Modern)
+#. %2 is the name of the Application (eg. Firefox)
+#: controllers/addons_controller.php:664
+msgid "addons_browse_categories_header_theme"
+msgstr "Gennemse temaer i kategorien %1$s :: %2$s Add-ons"
+
+#: views/addons/display.thtml:249
+msgid "addons_display_a_license_what"
+msgstr "Hvad er dette?"
+
+#: views/reviews/display.thtml:222
+msgid "addons_display_add_review"
+msgstr "Tilføj en anmeldelse"
+
+#: views/addons/display.thtml:294
+msgid "addons_display_advanced_details"
+msgstr "Avancerede detaljer"
+
+#: views/addons/display.thtml:98
+msgid "addons_display_categories"
+msgstr "Kategorier"
+
+#: views/addons/display.thtml:482
+#, fuzzy
+msgid "addons_display_collection_add"
+msgstr "Add to a collection:"
+
+#: views/addons/display.thtml:491
+#, fuzzy
+msgid "addons_display_collection_add_new"
+msgstr "New Collection..."
+
+#: views/addons/display.thtml:487
+#, fuzzy
+msgid "addons_display_collection_add_select_one"
+msgstr "Select a collection..."
+
+#: views/addons/display.thtml:493
+#, fuzzy
+msgid "addons_display_collection_add_submit"
+msgstr "Publish"
+
+#. %1$s is the add-on name
+#. %2$s is the collection name, linked to the collection's page
+#: views/pages/js_constants.js.thtml:103 views/addons/display.thtml:61
+#, fuzzy
+msgid "addons_display_collection_publish_success"
+msgstr "%1$s has been added to the %2$s collection."
+
+#: views/addons/display.thtml:483
+#, fuzzy
+msgid "addons_display_collection_whatsthis"
+msgstr "What's this?"
+
+#. %1$s is a number
+#: views/addons/display.thtml:473
+#, fuzzy
+msgid "addons_display_collections_more"
+msgid_plural "addons_display_collections_more"
+msgstr[0] "and %1$s more collection"
+msgstr[1] "and %1$s more collections"
+
+#: views/addons/display.thtml:403
+msgid "addons_display_detailed_review"
+msgstr "detaljeret anmeldelse"
+
+#: views/reviews/add.thtml:89 views/reviews/add.thtml:90
+msgid "addons_display_dont_like_it"
+msgstr "Synes ikke om den"
+
+#: views/reviews/display.thtml:220
+msgid "addons_display_edit_review"
+msgstr "Rediger din anmeldelse"
+
+#: views/addons/display.thtml:132
+msgid "addons_display_has_privacy"
+msgstr "Denne tilføjelse har en privatlivspolitik."
+
+#: views/reviews/add.thtml:87 views/reviews/add.thtml:88
+msgid "addons_display_hate_it"
+msgstr "Hader den"
+
+#: views/addons/display.thtml:462
+#, fuzzy
+msgid "addons_display_header_collections"
+msgstr "Related Collections"
+
+#: views/addons/display.thtml:297
+msgid "addons_display_header_developer_comments"
+msgstr "Kommentarer fra udvikleren"
+
+#: views/addons/display.thtml:230
+msgid "addons_display_header_homepage"
+msgstr "Hjemmeside"
+
+#: views/addons/display.thtml:247 views/addons/versions.thtml:110
+msgid "addons_display_header_license"
+msgstr "Licens for kildekode"
+
+#: views/addons/display.thtml:337
+msgid "addons_display_header_reviews"
+msgstr "Anmeldelser"
+
+#: views/addons/display.thtml:261
+msgid "addons_display_header_support"
+msgstr "Support"
+
+#: views/reviews/add.thtml:91 views/reviews/add.thtml:92
+msgid "addons_display_like_it"
+msgstr "Synes om den"
+
+#: views/addons/display.thtml:210
+msgid "addons_display_long_description"
+msgstr "Lang beskrivelse"
+
+#: views/reviews/add.thtml:95 views/reviews/add.thtml:96
+msgid "addons_display_love_it"
+msgstr "Er vild med den"
+
+#: views/addons/display.thtml:178
+msgid "addons_display_more_images"
+msgstr "Flere billeder"
+
+#: views/addons/display.thtml:465
+#, fuzzy
+msgid "addons_display_nocollections"
+msgstr "This add-on is not yet in any collections."
+
+#. %1$s is either an author's name or a comma separated list of authors. Using
+#. the list doesn't make sense in the English plural form so we ignore the
+#. variable.
+#: views/addons/display.thtml:436
+msgid "addons_display_other_addons_by"
+msgid_plural "addons_display_other_addons_by"
+msgstr[0] "Andre tilføjelser fra %1$s"
+msgstr[1] "Andre tilføjelser fra samme forfattere"
+
+#. %s is the name of the add-on and the add-on section. Example:
+#. Some Add-on :: Firefox Add-ons
+#. This should not be concatenated in the code and should be fixed.
+#: controllers/addons_controller.php:141 controllers/addons_controller.php:280
+#: controllers/addons_controller.php:1442
+#, php-format
+msgid "addons_display_pagetitle"
+msgstr "%s"
+
+#. %s is an email address
+#: views/addons/display.thtml:286
+#, php-format
+msgid "addons_display_paragraph_supportinfoemail"
+msgstr "Support af denne tilføjelse tilbydes af udvikleren ved at kontakte %s"
+
+#. %$1s is a URL
+#. %$2s is an email address
+#: views/addons/display.thtml:269
+#, php-format
+msgid "addons_display_paragraph_supportinfoemailurl"
+msgstr ""
+"Support af denne tilføjelse tilbydes af udvikleren på %1$s eller ved at "
+"kontakte %2$s"
+
+#. %s is a URL
+#: views/addons/display.thtml:278
+#, php-format
+msgid "addons_display_paragraph_supportinfourl"
+msgstr "Support af denne tilføjelse tilbydes af udvikleren på %s"
+
+#: views/addons/display.thtml:383
+msgid "addons_display_rate_it"
+msgstr "Bedømmelse"
+
+#: views/reviews/add.thtml:93 views/reviews/add.thtml:94
+msgid "addons_display_really_like_it"
+msgstr "Synes vældigt godt om den"
+
+#: views/addons/display.thtml:410
+msgid "addons_display_review_etiquette"
+msgstr ""
+"Lad venligst være med at sende fejlrapporter som anmeldelser. Vi videregiver "
+"ikke din e-mail-adresse til tilføjelsens udviklere, og de kan have behov for "
+"at kontakte dig for at løse problemet."
+
+#. %1 is the review guidelines link
+#: views/addons/display.thtml:417
+msgid "addons_display_review_guidelines_link"
+msgstr "<a href=\"%s\">Retningslinjer for anmeldelser</a>"
+
+#. %1 is the support section link
+#: views/addons/display.thtml:414
+msgid "addons_display_review_see_support"
+msgstr ""
+"Se <a href=\"%1$s\">supportafsnittet</a> for at finde ud af hvor du kan få "
+"hjælp til denne udvidelse."
+
+#: views/addons/display.thtml:404
+msgid "addons_display_review_submit"
+msgstr "Gem"
+
+#: views/addons/display.thtml:430
+#, php-format
+msgid "addons_display_see_all_addons"
+msgstr "Alle tilføjelser i kategorien %1$s"
+
+#. %1 is the number of reviews
+#: views/addons/display.thtml:364
+#, php-format
+msgid "addons_display_see_all_reviews"
+msgstr "Vis alle anmeldelser (%1$s)"
+
+#: views/addons/display.thtml:219
+msgid "addons_display_see_all_versions"
+msgstr "Vis alle versioner"
+
+#: views/addons/display.thtml:321 views/addons/versions.thtml:117
+msgid "addons_display_view_source"
+msgstr "Vis kildekoden"
+
+#: views/addons/display.thtml:324
+msgid "addons_display_view_stats"
+msgstr "Vis statistik"
+
+#: views/addons/display.thtml:376
+msgid "addons_display_what_do_you_think"
+msgstr "Hvad synes du?"
+
+#: views/elements/app_compatibility.thtml:49
+msgid "addons_display_workswith"
+msgstr "Virker med:"
+
+#: views/addons/home.thtml:112
+#, fuzzy
+msgid "addons_home_browse_new"
+msgstr "Just Added"
+
+#: views/addons/home.thtml:110
+#, fuzzy
+msgid "addons_home_browse_popular"
+msgstr "Popular"
+
+#: views/addons/home.thtml:108
+#, fuzzy
+msgid "addons_home_browse_recommended"
+msgstr "Recommended"
+
+#: views/addons/home.thtml:127 views/addons/home.thtml:134
+#: views/addons/home.thtml:141 views/addons/home.thtml:148
+#, fuzzy
+msgid "addons_home_browse_subscribe"
+msgstr "Subscribe"
+
+#: views/addons/home.thtml:101
+#, fuzzy
+msgid "addons_home_browse_title"
+msgstr "Browse Add-ons"
+
+#: views/addons/home.thtml:114
+#, fuzzy
+msgid "addons_home_browse_updated"
+msgstr "Updated"
+
+#: views/elements/amo2009/homepage_addon.thtml:100
+#: views/elements/addon_discussionheader.thtml:83
+#: views/elements/addon_listitem.thtml:109 views/elements/feature.thtml:95
+#: views/addons/category_landing.thtml:66 views/addons/policy.thtml:57
+#: views/addons/display.thtml:70 views/addons/home.thtml:178
+msgid "addons_home_by"
+msgstr "af"
+
+#: views/addons/home.thtml:169
+#, fuzzy
+msgid "addons_home_collection_popular_title"
+msgstr "Popular Collections"
+
+#: views/elements/amo2009/categories.thtml:69 views/addons/home.thtml:160
+#, fuzzy
+msgid "addons_home_collections"
+msgstr "Collections"
+
+#. %1$s is the count of addons in a collection
+#: views/elements/amo2009/collection_listing_item.thtml:51
+#: views/addons/home.thtml:185
+#, fuzzy
+msgid "addons_home_collections_addon_count"
+msgid_plural "addons_home_collections_addon_count"
+msgstr[0] "<strong>%1$s</strong> add-on"
+msgstr[1] "<strong>%1$s</strong> add-ons"
+
+#: views/addons/home.thtml:196
+#, fuzzy
+msgid "addons_home_collections_all"
+msgstr "View All Collections"
+
+#: views/addons/home.thtml:162
+#, fuzzy
+msgid "addons_home_collections_intro"
+msgstr ""
+"Collections are a way for you to categorize, mix, match and mingle add-ons. "
+"Subscribe to collections created by other users or create your own."
+
+#. %1$s is the count of subscribers for a collection
+#: views/elements/amo2009/collection_listing_item.thtml:58
+#: views/collections/detail.thtml:96 views/addons/home.thtml:189
+#, fuzzy
+msgid "addons_home_collections_subscribers"
+msgid_plural "addons_home_collections_subscribers"
+msgstr[0] "<strong>%1$s</strong> subscriber"
+msgstr[1] "<strong>%1$s</strong> subscribers"
+
+#: views/addons/searchengines.thtml:54 views/addons/themes_landing.thtml:49
+msgid "addons_home_feature_head"
+msgstr "Vi anbefaler"
+
+#: controllers/search_controller.php:218 controllers/addons_controller.php:176
+#: controllers/addons_controller.php:428 controllers/addons_controller.php:671
+#: controllers/addons_controller.php:871
+#: controllers/addons_controller.php:1103
+#: controllers/addons_controller.php:1242
+#: controllers/addons_controller.php:1298
+#, php-format
+msgid "addons_home_header_details"
+msgstr ""
+"Tilføjelser udvider %1$s og giver dig mulighed for at skræddersy den efter "
+"dine behov. Se dig omkring, og gør %1$s til din egen."
+
+#. %1$s is the HTML collection name link.
+#: views/elements/amo2009/teaser_collections.thtml:107
+#, fuzzy
+msgid "addons_home_introduction_collection_link"
+msgstr "Like these? Find more add-ons in %1$s."
+
+#: views/elements/amo2009/teaser_collections.thtml:60
+#, fuzzy
+msgid "addons_home_introduction_extras"
+msgstr ""
+"<strong>Over 5000 free extras</strong> that let you customize and extend "
+"Firefox to meet your needs."
+
+#: views/elements/amo2009/teaser_collections.thtml:55
+#, fuzzy
+msgid "addons_home_introduction_header"
+msgstr "What are Add-ons?"
+
+#: views/elements/amo2009/teaser_collections.thtml:72
+#, fuzzy
+msgid "addons_home_introduction_install"
+msgstr ""
+"<strong>Easy to install</strong>, get notified when updates are available."
+
+#: views/elements/amo2009/teaser_collections.thtml:45
+#, fuzzy
+msgid "addons_home_introduction_name"
+msgstr "Introduction"
+
+#: views/elements/amo2009/teaser_collections.thtml:66
+#, fuzzy
+msgid "addons_home_introduction_themes"
+msgstr ""
+"Toolbars, themes and search providers that <strong>help you perform common "
+"tasks.</strong>"
+
+#: views/addons/home.thtml:161
+#, fuzzy
+msgid "addons_home_new_indicator"
+msgstr "NEW!"
+
+#: views/elements/app_chooser.thtml:48 views/layouts/amo2009.thtml:257
+msgid "addons_home_other_applications"
+msgstr "Andre programmer"
+
+#. %1$s is the application the user is browsing. Examples: Thunderbird, Firefox,
+#. Sunbird
+#: views/pages/collector_faq.thtml:49 views/pages/collector_firstrun.thtml:42
+#: views/pages/collector.thtml:46 views/pages/collector_features.thtml:54
+#: controllers/developers_controller.php:87
+#: controllers/compatibility_controller.php:72
+#: controllers/components/simple_acl.php:81 controllers/components/amo.php:607
+#: controllers/statistics_controller.php:60
+#: controllers/statistics_controller.php:240
+#: controllers/previews_controller.php:67 controllers/users_controller.php:90
+#: controllers/users_controller.php:223 controllers/users_controller.php:330
+#: controllers/users_controller.php:414 controllers/users_controller.php:708
+#: controllers/users_controller.php:723 controllers/reviews_controller.php:204
+#: controllers/reviews_controller.php:251
+#: controllers/reviews_controller.php:346
+#: controllers/reviews_controller.php:425
+#: controllers/search_controller.php:185 controllers/search_controller.php:297
+#: controllers/search_controller.php:301 controllers/addons_controller.php:147
+#: controllers/addons_controller.php:280 controllers/addons_controller.php:370
+#: controllers/addons_controller.php:667 controllers/addons_controller.php:874
+#: controllers/addons_controller.php:1019
+#: controllers/addons_controller.php:1034
+#: controllers/addons_controller.php:1101
+#: controllers/addons_controller.php:1121
+#: controllers/addons_controller.php:1240
+#: controllers/addons_controller.php:1357
+#: controllers/addons_controller.php:1364
+#: controllers/addons_controller.php:1442
+#: controllers/addons_controller.php:1477
+#: controllers/addons_controller.php:1538
+#: controllers/addons_controller.php:1543
+#: controllers/editors_controller.php:64 controllers/pages_controller.php:132
+#: controllers/groups_controller.php:65 controllers/groups_controller.php:71
+#: controllers/groups_controller.php:89 controllers/groups_controller.php:111
+#: controllers/collections_controller.php:57
+#: controllers/collections_controller.php:121
+#: controllers/collections_controller.php:205
+#: controllers/collections_controller.php:365
+#: controllers/collections_controller.php:404
+#: controllers/collections_controller.php:466
+#: controllers/collections_controller.php:538
+#: controllers/collections_controller.php:828
+#: controllers/localizers_controller.php:72
+#, php-format
+msgid "addons_home_pagetitle"
+msgstr "%1$s Add-ons"
+
+#. %1$s is the number of addons downloaded
+#: views/addons/home.thtml:57
+#, fuzzy, php-format
+msgid "addons_home_stats_downloaded"
+msgid_plural "addons_home_stats_downloaded"
+msgstr[0] "<strong>%1$s</strong> <span>add-on downloaded</span>"
+msgstr[1] "<strong>%1$s</strong> <span>add-ons downloaded</span>"
+
+#. %1$s is the number of addons in use
+#: views/addons/home.thtml:63
+#, fuzzy, php-format
+msgid "addons_home_stats_inuse"
+msgid_plural "addons_home_stats_inuse"
+msgstr[0] "<strong>%1$s</strong> <span>add-on in use</span>"
+msgstr[1] "<strong>%1$s</strong> <span>add-ons in use</span>"
+
+#: views/addons/home.thtml:136
+msgid "addons_home_view_all_newest_title"
+msgstr "Vis alle nyoprettede tilføjelser"
+
+#: views/addons/home.thtml:129
+msgid "addons_home_view_all_popular_title"
+msgstr "Vis alle populære tilføjelser"
+
+#: views/addons/home.thtml:150
+msgid "addons_home_view_all_recommended_title"
+msgstr "Vis alle anbefalede tilføjelser"
+
+#: views/addons/home.thtml:143
+msgid "addons_home_view_all_updated_title"
+msgstr "Vis alle nyligt opdaterede tilføjelser"
+
+#: views/elements/amo2009/install.thtml:334 views/elements/install.thtml:112
+msgid "addons_install_in_sunbird"
+msgstr ""
+"<ol><li>Klik på linket herunder for at gemme filen.</li><li>Åbn Mozilla "
+"Sunbird, og åbn Tilføjelser fra menuen Funktioner.</li><li>Klik på knappen "
+"Installer, find/marker filen, som du downloadede, og klik \"OK\".</li></ol>"
+
+#: views/elements/amo2009/install.thtml:333 views/elements/install.thtml:111
+msgid "addons_install_in_sunbird_title"
+msgstr "Hvordan du installerer i Sunbird"
+
+#: views/elements/amo2009/install.thtml:331 views/elements/install.thtml:106
+msgid "addons_install_in_thunderbird"
+msgstr ""
+"<ol><li>Klik på linket herunder for at gemme filen.</li><li>Åbn Mozilla "
+"Thunderbird, og åbn Tilføjelser fra menuen Funktioner.</li><li>Klik på "
+"knappen Installer, find/marker filen, som du downloadede, og klik \"OK\".</"
+"li></ol>"
+
+#: views/elements/amo2009/install.thtml:330 views/elements/install.thtml:105
+msgid "addons_install_in_thunderbird_title"
+msgstr "Hvordan du installerer i Thunderbird"
+
+#: views/elements/amo2009/addon_list_options.thtml:108
+#: views/elements/addon_list_options.thtml:105
+msgid "addons_options_show_experimental"
+msgstr "Vis eksperimentelle tilføjelser"
+
+#: views/elements/amo2009/addon_list_options.thtml:113
+#: views/elements/addon_list_options.thtml:109
+msgid "addons_options_submit"
+msgstr "Opdater"
+
+#: views/addons/plugins.thtml:63 views/addons/plugins.thtml:73
+#: views/addons/plugins.thtml:83 views/addons/plugins.thtml:93
+#: views/addons/plugins.thtml:103 views/addons/plugins.thtml:116
+#: views/addons/plugins.thtml:126
+msgid "addons_plugins_by"
+msgstr "Af"
+
+#: views/addons/plugins.thtml:107
+msgid "addons_plugins_for_linux"
+msgstr "til Linux"
+
+#: views/addons/plugins.thtml:108 views/addons/plugins.thtml:131
+msgid "addons_plugins_for_macosx"
+msgstr "til Mac OS X"
+
+#: views/addons/plugins.thtml:106 views/addons/plugins.thtml:129
+#: views/addons/plugins.thtml:130
+msgid "addons_plugins_for_windows"
+msgstr "til Windows"
+
+#. %1$s is a URL
+#: views/addons/plugins.thtml:139
+#, php-format
+msgid "addons_plugins_looking_for_more"
+msgstr ""
+"Denne side indeholder kun nogle af de mest almindelige og populære plugins. "
+"Besøg %1$s for at få mere at vide om andre plugins til Mozillabaserede "
+"browsere."
+
+#: views/addons/plugins.thtml:137
+msgid "addons_plugins_looking_for_plugin"
+msgstr "Leder du efter et plugin, som ikke er på listen?"
+
+#: views/addons/plugins.thtml:58
+msgid "addons_plugins_main_description"
+msgstr ""
+"Plugins hjælper din browser med specifikke funktioner, som fx at vise "
+"specielle grafikformater eller afspille multimediefiler. Plugins er en "
+"anelse anderledes end udvidelser, som ændrer eller udvider eksisterende "
+"funktionalitet."
+
+#. %1$s is the application name. Example: Firefox, Thunderbird, Sunbird
+#: controllers/addons_controller.php:1122
+#, php-format
+msgid "addons_plugins_main_header"
+msgstr "Almindelige plugins til %1$s"
+
+#: controllers/components/amo.php:698 controllers/addons_controller.php:1121
+msgid "addons_plugins_pagetitle"
+msgstr "Plugins"
+
+#: views/addons/plugins.thtml:68 views/addons/plugins.thtml:78
+#: views/addons/plugins.thtml:88 views/addons/plugins.thtml:98
+#: views/addons/plugins.thtml:110 views/addons/plugins.thtml:121
+#: views/addons/plugins.thtml:133
+msgid "addons_plugins_support_documentation"
+msgstr "Hjælp og dokumentation: "
+
+#. %s is the name of the add-on
+#: views/addons/policy.thtml:61
+#, php-format
+msgid "addons_policy_eula_require"
+msgstr ""
+"%s kræver, at du accepterer følgende slutbrugerlicensaftale, før "
+"installationen kan fortsætte:"
+
+#. %1 is the add-on name
+#: controllers/addons_controller.php:1476
+#, php-format
+msgid "addons_previews_pagetitle"
+msgstr "Skærmbilleder af %s"
+
+#: views/addons/category_landing.thtml:135
+msgid "addons_recently_added"
+msgstr "Tilføjet fornyligt"
+
+#: views/addons/recommended.thtml:51 controllers/addons_controller.php:1365
+msgid "addons_recommended_introduction"
+msgstr ""
+"Med så mange fantastiske tilføjelser er der noget for enhver smag. Her er en "
+"liste over nogle af de mest populære, så du kan komme godt i gang."
+
+#: controllers/addons_controller.php:1357
+#: controllers/addons_controller.php:1364
+msgid "addons_recommended_pagetitle"
+msgstr "Anbefalede tilføjelser"
+
+#: controllers/addons_controller.php:1360
+msgid "addons_recommended_title"
+msgstr "Anbefalede tilføjelser"
+
+#: views/addons/searchengines.thtml:136
+msgid "addons_searchengines_additional_resources"
+msgstr "Yderligere kilder"
+
+#. link text devmo
+#: views/addons/searchengines.thtml:141
+msgid "addons_searchengines_devmo_link"
+msgstr "Mozilla Developer Center"
+
+#: views/pages/js_constants.js.thtml:67
+msgid "addons_searchengines_error_mozilla_browser_required"
+msgstr ""
+"Desværre, du skal bruge en Mozillabaseret browser (eksempelvis Firefox) for "
+"at installere et søgeplugin."
+
+#: views/addons/searchengines.thtml:49
+msgid "addons_searchengines_error_nojavascript"
+msgstr ""
+"Der kræves JavaScript for at installere søgeplugins, men det ser ud til, at "
+"du har slået det fra. Slå JavaScript til før du forsøger at installere nogen "
+"af søgepluginsne herunder."
+
+#. %1 is "make your own" link
+#. %2 is MDC link
+#: views/addons/searchengines.thtml:139
+msgid "addons_searchengines_learn_howto"
+msgstr "Lær hvordan du %1$s hos %2$s."
+
+#. link path to search plugins instructions, relative to devmo
+#: views/addons/searchengines.thtml:140
+msgid "addons_searchengines_makeyourown_href"
+msgstr "/en/docs/Creating_OpenSearch_plugins_for_Firefox"
+
+#. link text for "make your own" (opensearch engine)
+#: views/addons/searchengines.thtml:140
+msgid "addons_searchengines_makeyourown_link"
+msgstr "laver din egen"
+
+#. %1 is the link to mycroft.mozdev.org
+#: views/addons/searchengines.thtml:138
+msgid "addons_searchengines_more"
+msgstr "Find flere søgetjenester hos %1$s"
+
+#. link text to mycroft.mozdev.org
+#: views/addons/searchengines.thtml:138
+msgid "addons_searchengines_mycroft_link"
+msgstr "mycroft.mozdev.org"
+
+#: controllers/addons_controller.php:1100
+#: controllers/addons_controller.php:1110
+msgid "addons_searchengines_pagetitle"
+msgstr "Søgemasikner"
+
+#: views/addons/searchengines.thtml:143
+msgid "addons_searchengines_thanks"
+msgstr ""
+"Særligt tak til Mycroftprojektet for deres arbejder med søgetjenester til "
+"Firefox."
+
+#: views/addons/display.thtml:154
+msgid "addons_share_button_text"
+msgstr "Del dette"
+
+#: controllers/addons_controller.php:89
+msgid "addons_share_label_delicious"
+msgstr "Tilføj til Delicious"
+
+#: controllers/addons_controller.php:77
+msgid "addons_share_label_digg"
+msgstr "Tilføj til Digg"
+
+#: controllers/addons_controller.php:83
+msgid "addons_share_label_facebook"
+msgstr "Besked på Facebook"
+
+#: controllers/addons_controller.php:101
+msgid "addons_share_label_friendfeed"
+msgstr "Del på FriendFeed"
+
+#: controllers/addons_controller.php:95
+msgid "addons_share_label_myspace"
+msgstr "Besked på MySpace"
+
+#: controllers/components/amo.php:201 controllers/components/amo.php:229
+msgid "addons_status_disabled"
+msgstr "Deaktiveret"
+
+#: controllers/components/amo.php:191 controllers/components/amo.php:224
+msgid "addons_status_incomplete"
+msgstr "Inkompatibel version"
+
+#: controllers/components/amo.php:197 controllers/components/amo.php:227
+msgid "addons_status_nominated"
+msgstr "I sandkassen; Nomineret til at blive offentliggjort"
+
+#: views/pages/js_constants.js.thtml:80 controllers/components/amo.php:195
+#: controllers/components/amo.php:226
+msgid "addons_status_pending"
+msgstr "I sandkassen; Venter på anmeldelser"
+
+#: views/pages/js_constants.js.thtml:78 controllers/components/amo.php:199
+#: controllers/components/amo.php:228
+msgid "addons_status_public"
+msgstr "Offentliggjort"
+
+#: views/pages/js_constants.js.thtml:79 controllers/components/amo.php:193
+#: controllers/components/amo.php:225
+msgid "addons_status_sandbox"
+msgstr "I sandkassen"
+
+#: controllers/components/amo.php:203
+msgid "addons_status_unknown"
+msgstr "Ukendt"
+
+#: views/elements/amo2009/teaser_collections.thtml:91
+#: views/elements/amo2009/homepage_addon.thtml:99
+#: views/elements/feature.thtml:94
+msgid "addons_title_tooltip"
+msgstr "Lær mere om denne tilføjelse"
+
+#: views/addons/category_landing.thtml:151
+msgid "addons_top_downloads"
+msgstr "Flest downloads"
+
+#: views/addons/category_landing.thtml:165
+msgid "addons_top_rated"
+msgstr "Bedste bedømmelse"
+
+#: views/addons/versions.thtml:62
+msgid "addons_versions_careful"
+msgstr "Pas på med gamle versioner"
+
+#: views/addons/versions.thtml:63
+msgid "addons_versions_careful_introduction"
+msgstr ""
+"Disse versioner vises som reference og til brug for test. Du bør altid "
+"anvende den nyeste udgave af en tilføjelse."
+
+#: controllers/addons_controller.php:1549
+msgid "addons_versions_history"
+msgstr "Versionshistorik med beskrivelse af ændringer"
+
+#. %1$s is the add-on name
+#: controllers/addons_controller.php:1535
+#, php-format
+msgid "addons_versions_pagetitle"
+msgstr "Versionshistorik for %1$s"
+
+#: controllers/groups_controller.php:71
+msgid "admin_group_add_pagetitle"
+msgstr "Tilføj gruppe"
+
+#: controllers/groups_controller.php:111
+msgid "admin_group_delete_pagetitle"
+msgstr "Slet gruppe"
+
+#. %s is a number to identify the group
+#: controllers/groups_controller.php:117
+#, php-format
+msgid "admin_group_deleted"
+msgstr "Gruppen med id %s er slettet"
+
+#: controllers/groups_controller.php:89
+msgid "admin_group_edit_pagetitle"
+msgstr "Ret gruppe"
+
+#: controllers/groups_controller.php:92 controllers/groups_controller.php:113
+msgid "admin_group_error_invalid_id"
+msgstr "Ugyldigt id til gruppe"
+
+#: controllers/groups_controller.php:65
+msgid "admin_group_pagetitle"
+msgstr "Gruppeadministration"
+
+#: controllers/groups_controller.php:77 controllers/groups_controller.php:99
+msgid "admin_group_saved"
+msgstr "Gruppen er gemt"
+
+#: views/elements/amo2009/search.thtml:257 views/elements/search.thtml:239
+msgid "advanced_search_form"
+msgstr "Avanceret"
+
+#: views/elements/amo2009/search.thtml:126 views/elements/search.thtml:125
+msgid "advanced_search_form_any_time"
+msgstr "NÃ¥r som helst"
+
+#: views/elements/amo2009/search.thtml:97
+#: views/elements/amo2009/search.thtml:110 views/elements/search.thtml:96
+#: views/elements/search.thtml:109
+msgid "advanced_search_form_any_type"
+msgstr "Enhver"
+
+#: views/elements/amo2009/search.thtml:275 views/elements/search.thtml:254
+msgid "advanced_search_form_any_version"
+msgstr "Enhver"
+
+#: views/elements/amo2009/search.thtml:217 views/elements/search.thtml:212
+msgid "advanced_search_form_application"
+msgstr "Program"
+
+#: views/elements/amo2009/search.thtml:143 views/elements/search.thtml:142
+msgid "advanced_search_form_keyword_match"
+msgstr "Relevans for søgningen"
+
+#: views/elements/amo2009/search.thtml:251 views/elements/search.thtml:225
+msgid "advanced_search_form_lastupdate"
+msgstr "Sidst opdateret"
+
+#: views/elements/amo2009/search.thtml:145 views/elements/search.thtml:144
+msgid "advanced_search_form_name"
+msgstr "Navn"
+
+#: views/elements/amo2009/search.thtml:144 views/elements/search.thtml:143
+msgid "advanced_search_form_newest"
+msgstr "Nyeste"
+
+#: views/elements/amo2009/search.thtml:130 views/elements/search.thtml:129
+msgid "advanced_search_form_past_3_months"
+msgstr "under 3 måneder siden"
+
+#: views/elements/amo2009/search.thtml:131 views/elements/search.thtml:130
+msgid "advanced_search_form_past_6_months"
+msgstr "under 6 måneder siden"
+
+#: views/elements/amo2009/search.thtml:127 views/elements/search.thtml:126
+msgid "advanced_search_form_past_day"
+msgstr "under et døgn siden"
+
+#: views/elements/amo2009/search.thtml:129 views/elements/search.thtml:128
+msgid "advanced_search_form_past_month"
+msgstr "under en måned siden"
+
+#: views/elements/amo2009/search.thtml:128 views/elements/search.thtml:127
+msgid "advanced_search_form_past_week"
+msgstr "under en uge siden"
+
+#: views/elements/amo2009/search.thtml:132 views/elements/search.thtml:131
+msgid "advanced_search_form_past_year"
+msgstr "under et år siden"
+
+#: views/elements/amo2009/search.thtml:239 views/elements/search.thtml:230
+msgid "advanced_search_form_perpage"
+msgstr "Pr. side"
+
+#: views/elements/amo2009/search.thtml:243 views/elements/search.thtml:224
+msgid "advanced_search_form_platform"
+msgstr "Platform"
+
+#: views/elements/amo2009/search.thtml:147 views/elements/search.thtml:146
+msgid "advanced_search_form_popularity"
+msgstr "Popularitet"
+
+#: views/elements/amo2009/search.thtml:146 views/elements/search.thtml:145
+msgid "advanced_search_form_rating"
+msgstr "Bedømmelse"
+
+#: views/elements/amo2009/search.thtml:247 views/elements/search.thtml:231
+msgid "advanced_search_form_sortby"
+msgstr "Sorter efter"
+
+#: views/elements/amo2009/search.thtml:227 views/elements/search.thtml:216
+msgid "advanced_search_form_to"
+msgstr "til"
+
+#: views/elements/amo2009/search.thtml:257 views/elements/search.thtml:237
+msgid "advanced_search_form_toggle_tooltip"
+msgstr "Skift mellem avanceret og simpel søgning"
+
+#: views/elements/amo2009/search.thtml:235 views/elements/search.thtml:223
+msgid "advanced_search_form_type"
+msgstr "Type"
+
+#: views/elements/amo2009/search.thtml:222 views/elements/search.thtml:214
+msgid "advanced_search_form_version"
+msgstr "version"
+
+#: views/elements/amo2009/pagination.thtml:42
+#, fuzzy
+msgid "amo2009_pagination_next_page"
+msgstr "Next"
+
+#: views/elements/amo2009/pagination.thtml:41
+#, fuzzy
+msgid "amo2009_pagination_previous_page"
+msgstr "Prev"
+
+#: views/pages/js_constants.js.thtml:96
+msgid "app_compat_ignore_check"
+msgstr "Ignorer versionskontrol"
+
+#: views/pages/js_constants.js.thtml:72
+msgid "app_compat_older_firefox_only"
+msgstr "Denne tilføjelse er til ældre versioner af Firefox"
+
+#. %1$s and %2$s are URLs
+#: views/pages/js_constants.js.thtml:74
+msgid "app_compat_older_version_or_ignore_check"
+msgstr ""
+"Du kan <a href=\"%1$s\">prøve en ældre version</a> eller <a href=\"#\" "
+"onclick=\"%2$s\">ignorere denne test</a>"
+
+#. %1$s is a URL
+#: views/pages/js_constants.js.thtml:71
+msgid "app_compat_try_old_version"
+msgstr "En <a href=\"%1$s\">ældre version</a> vil måske virke"
+
+#. %1$s is a URL
+#. %2$s is a version number. Example: 3.1
+#: views/pages/js_constants.js.thtml:73
+msgid "app_compat_unreleased_version"
+msgstr ""
+"Denne tilføjelse kræver <a href=\"%1$s\">Firefox %2$s</a>, som endnu ikke er "
+"udgivet"
+
+#: views/pages/js_constants.js.thtml:70
+msgid "app_compat_update_firefox"
+msgstr ""
+"<a href=\"http://getfirefox.com\">Opdater Firefox</a> for at bruge denne "
+"tilføjelse"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#. %3$s is a status, like Public.
+#: controllers/components/audit.php:79
+msgid "audit_addon_status"
+msgstr "%1$s changed the status of %2$s to %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:221
+msgid "audit_admin_default"
+msgstr "%1$s committed unknown admin action %2$s to ID %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:153
+msgid "audit_admin_feature_remove"
+msgstr "%1$s removed feature %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is an application, like Firefox.
+#: controllers/components/audit.php:92
+msgid "audit_application_create"
+msgstr "%1$s created application %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is an application, like Firefox.
+#: controllers/components/audit.php:95
+msgid "audit_application_edit"
+msgstr "%1$s edited application %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a version number, like 3.5.
+#. %3$s is an application, like Firefox.
+#: controllers/components/audit.php:105
+msgid "audit_appversion_create"
+msgstr "%1$s created version %2$s for %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a version number, like 3.5.
+#. %3$s is an application, like Firefox.
+#: controllers/components/audit.php:108
+msgid "audit_appversion_delete"
+msgstr "%1$s deleted version %2$s for %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a config field, like "awesomeness".
+#. %3$s is a config value, like "off".
+#. %4$s is a config value, like "on".
+#: controllers/components/audit.php:210
+msgid "audit_config"
+msgstr "%1$s changed config '%2$s' from '%3$s' to '%4$s'"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:258
+msgid "audit_editor_default"
+msgstr "%1$s committed unknown editor action %2$s to ID %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#: controllers/components/audit.php:236
+msgid "audit_editor_feature_remove"
+msgstr "%1$s removed addon %2$s from feature list"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#: controllers/components/audit.php:231
+msgid "audit_feature_add"
+msgstr "%1$s added addon %2$s to feature list"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:149
+msgid "audit_feature_edit"
+msgstr "%1$s changed a feature for %2$s locale"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#: controllers/components/audit.php:241
+msgid "audit_feature_locale_change"
+msgstr "%1$s changed locales for addon %2$s on feature list"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:83
+msgid "audit_file_recalchash"
+msgstr "%1$s recalculated the hash for file %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>user name</a>
+#. %3$s is <a>group name</a>
+#: controllers/components/audit.php:182
+msgid "audit_group_addmember"
+msgstr "%1$s added %2$s to group %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:313
+msgid "audit_group_associated"
+msgstr "%1$s associated themselves with %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:162
+msgid "audit_group_create"
+msgstr "%1s created group %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:170
+msgid "audit_group_delete"
+msgstr "%1$s deleted group %2$s (ID %3$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:165
+msgid "audit_group_edit"
+msgstr "%1$s edited group %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>user name</a>
+#. %3$s is <a>group name</a>
+#: controllers/components/audit.php:188
+msgid "audit_group_removemember"
+msgstr "%1$s removed %2$s from group %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:280
+msgid "audit_l10n_default"
+msgstr "%1$s committed unknown action %2$s for %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:295
+msgid "audit_modify_locked_group"
+msgstr "%1$s attempted to modify locked group %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:299
+msgid "audit_modify_other_locale"
+msgstr "%1$s attempted to modify translations in %2$s without permission"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a platform, like <a>Windows</a>
+#: controllers/components/audit.php:135
+msgid "audit_platform_create"
+msgstr "%1$s created platform %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a platform, like <a>Windows</a>
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:143
+msgid "audit_platform_delete"
+msgstr "%1$s deleted platform %2$s (ID %3$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a platform, like <a>Windows</a>
+#: controllers/components/audit.php:138
+msgid "audit_platform_edit"
+msgstr "%1$s edited platform %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a part of the admin, like 'Site Config'
+#: controllers/components/audit.php:288
+msgid "audit_reauthentication_failure"
+msgstr "%1$s failed to re-authenticate to access %2$s."
+
+#. %1$s is <a>user name</a>
+#. %2$s is the name of a canned response, like 'Ready for the public'
+#: controllers/components/audit.php:198
+msgid "audit_response_create"
+msgstr "%1$s created response %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is the name of a canned response, like 'Ready for the public'
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:206
+msgid "audit_response_delete"
+msgstr "%1$s deleted response %2$s (ID %3$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is the name of a canned response, like 'Ready for the public'
+#: controllers/components/audit.php:201
+msgid "audit_response_edit"
+msgstr "%1$s edited response %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:245
+msgid "audit_review_approve"
+msgstr "%1$s approved review %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:250 controllers/components/audit.php:253
+msgid "audit_review_delete"
+msgstr "%1$s deleted review %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:303
+msgid "audit_security_default"
+msgstr "%1$s committed unknown security action %2$s to ID %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a category name, like <a>Search Tools</a>
+#: controllers/components/audit.php:118
+msgid "audit_tag_create"
+msgstr "%1$s created tag %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a category name, like <a>Search Tools</a>
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:126
+msgid "audit_tag_delete"
+msgstr "%1$s deleted category %2$s (ID %3$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a category name, like <a>Search Tools</a>
+#: controllers/components/audit.php:121
+msgid "audit_tag_edit"
+msgstr "%1$s edited category %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:266
+msgid "audit_update_applications"
+msgstr "%1$s updated application translations for %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:277
+msgid "audit_update_blog"
+msgstr "%1$s updated blog post translations for %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:274
+msgid "audit_update_platforms"
+msgstr "%1$s updated platform translations for %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:270
+msgid "audit_update_tags"
+msgstr "%1$s updated category translations for %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>user name</a>
+#: controllers/components/audit.php:217
+msgid "audit_user_edit"
+msgstr "%1$s edited %2$s's user information"
+
+#: controllers/addons_controller.php:1012
+msgid "browse_addons_name"
+msgstr "Tilføjelser efter navn"
+
+#: controllers/addons_controller.php:1010
+msgid "browse_addons_newest"
+msgstr "Nyeste tilføjelser"
+
+#: controllers/addons_controller.php:1008
+msgid "browse_addons_popular"
+msgstr "Populære tilføjelser"
+
+#: controllers/addons_controller.php:1011
+msgid "browse_addons_rated"
+msgstr "Tilføjelser efter bedømmelse"
+
+#: controllers/addons_controller.php:1009
+msgid "browse_addons_updated"
+msgstr "Nyligt opdaterede tilføjelser"
+
+#: views/elements/categories.thtml:73 views/elements/categories.thtml:82
+msgid "categories_current_title"
+msgstr "Nuværende kategori"
+
+#: views/elements/categories.thtml:50
+#: views/elements/amo2009/categories.thtml:43
+#: views/elements/amo2009/categories.thtml:45
+msgid "categories_header"
+msgstr "Kategorier"
+
+#: views/elements/categories.thtml:50
+#: views/elements/amo2009/categories.thtml:41
+msgid "categories_header_title"
+msgstr "Vælg en kategori"
+
+#. %1$s is the category name
+#: views/addons/searchengines.thtml:129
+#, php-format
+msgid "category_extra_see_all"
+msgstr "Se alle tilføjelser i kategorien %1$s"
+
+#. %1$s is a number.
+#: models/collection.php:130
+msgid "collection_description_limit"
+msgstr "Beskrivelsen bør være mindre end %1$s tegn."
+
+#. %1$s is the name of the collection
+#: controllers/collections_controller.php:392
+#, fuzzy
+msgid "collection_detail_rss_title"
+msgstr "%s Collection"
+
+#: controllers/collections_controller.php:1065
+#, fuzzy
+msgid "collection_error_deleting_addon"
+msgstr "Error deleting add-on!"
+
+#: controllers/collections_controller.php:1051
+#, fuzzy
+msgid "collection_error_saving_addon"
+msgstr "Error saving add-on!"
+
+#: controllers/collections_controller.php:1080
+#, fuzzy
+msgid "collection_error_saving_comment"
+msgstr "Error saving comment!"
+
+#. %1$s is a number.
+#: models/collection.php:122
+msgid "collection_name_limit"
+msgstr "Navnet bør være mindre end %1$s tegn."
+
+#: controllers/collections_controller.php:352
+#: controllers/collections_controller.php:487
+msgid "collection_not_found"
+msgstr "Samlingen findes ikke!"
+
+#. %1$s is the text on the "create collection" button
+#: views/collections/add.thtml:91
+#, fuzzy
+msgid "collections_add_formfield_addons_description"
+msgstr ""
+"If you already know which add-ons you want to add to your collection, just "
+"start typing their names below. If you'd rather wait and do this later, just "
+"click %1$s now."
+
+#: views/collections/add.thtml:90
+#, fuzzy
+msgid "collections_add_formfield_firstaddons"
+msgstr "Choose your first add-ons"
+
+#: views/collections/add.thtml:48
+#, fuzzy
+msgid "collections_add_header"
+msgstr "Create a Collection"
+
+#: views/collections/add.thtml:97
+#, fuzzy
+msgid "collections_add_header_selectedaddons"
+msgstr "Selected Add-ons"
+
+#: views/collections/add.thtml:50
+#, fuzzy
+msgid "collections_add_intro"
+msgstr ""
+"It's easy to create your own collection of add-ons by filling in a few "
+"fields below."
+
+#: views/collections/add.thtml:92 views/collections/add.thtml:103
+#, fuzzy
+msgid "collections_add_submit"
+msgstr "Create Collection"
+
+#: views/pages/collector_faq.thtml:50 views/pages/collector_firstrun.thtml:43
+#: views/pages/collector.thtml:47 views/pages/collector_features.thtml:55
+#: controllers/search_controller.php:302
+#: controllers/collections_controller.php:206
+#: controllers/collections_controller.php:405
+#: controllers/collections_controller.php:467
+#: controllers/collections_controller.php:539
+#, fuzzy
+msgid "collections_breadcrumb"
+msgstr "Collections"
+
+#: views/collections/detail.thtml:185
+#, fuzzy
+msgid "collections_detail_a_learn"
+msgstr "Learn More"
+
+#: views/elements/amo2009/collection_add_form.thtml:53
+#: views/elements/amo2009/collections_js_init.thtml:68
+#: views/pages/collector_firstrun.thtml:64
+#, fuzzy
+msgid "collections_detail_button_add"
+msgstr "Add to Favorites"
+
+#: views/elements/amo2009/collection_add_form.thtml:50
+#: views/elements/amo2009/collections_js_init.thtml:71
+#, fuzzy
+msgid "collections_detail_button_remove"
+msgstr "Remove from Favorites"
+
+#. %1$s is a URL.
+#. %2$s is a full <a href>.
+#: views/collections/detail.thtml:62
+#, fuzzy
+msgid "collections_detail_created_desc"
+msgstr ""
+"<p>You can view your new collection below. If you'd like to set a collection "
+"nickname, upload an icon, or change additional settings, please visit the <a "
+"href='%1$s'>Manage Collections</a> page.</p><p>Your collection can be "
+"accessed at this location: %2$s</p>"
+
+#: views/collections/detail.thtml:61
+#, fuzzy
+msgid "collections_detail_created_msg"
+msgstr "Your collection is now ready!"
+
+#: views/collections/detail.thtml:109
+#, fuzzy
+msgid "collections_detail_header_about"
+msgstr "About This Collection"
+
+#. %1$s is a number.
+#: views/collections/detail.thtml:126
+#, fuzzy
+msgid "collections_detail_header_count"
+msgid_plural "collections_detail_header_count"
+msgstr[0] "%1$s Add-on in this Collection"
+msgstr[1] "%1$s Add-ons in this Collection"
+
+#: views/collections/detail.thtml:113
+#, fuzzy
+msgid "collections_detail_info_created"
+msgstr "<strong>Created by:</strong> %1$s"
+
+#: views/collections/detail.thtml:117
+#, fuzzy
+msgid "collections_detail_info_updated"
+msgstr "<strong>Updated:</strong>"
+
+#: views/elements/amo2009/collections_js_init.thtml:62
+#, fuzzy
+msgid "collections_detail_js_adding"
+msgstr "Adding to Favorites&hellip;"
+
+#: views/elements/amo2009/collections_js_init.thtml:65
+#, fuzzy
+msgid "collections_detail_js_removing"
+msgstr "Removing Favorite&hellip;"
+
+#. %1$s is a URL
+#: views/collections/detail.thtml:90
+#, fuzzy
+msgid "collections_detail_login"
+msgstr "<a href=\"%1$s\">Log in</a> to add this collection to your favorites."
+
+#: views/collections/detail.thtml:104
+#, fuzzy
+msgid "collections_detail_manage"
+msgstr "Manage Collection"
+
+#: controllers/collections_controller.php:298
+#, fuzzy
+msgid "collections_detail_sort_date"
+msgstr "Date Added"
+
+#: controllers/collections_controller.php:299
+#, fuzzy
+msgid "collections_detail_sort_name"
+msgstr "Name"
+
+#: controllers/collections_controller.php:300
+#, fuzzy
+msgid "collections_detail_sort_popularity"
+msgstr "Popularity"
+
+#. %1$s is a number.
+#: views/collections/detail.thtml:166
+#, fuzzy
+msgid "collections_detail_weekly_downloads"
+msgid_plural "collections_detail_weekly_downloads"
+msgstr[0] "%1$s download this week"
+msgstr[1] "%1$s downloads this week"
+
+#: views/collections/edit.thtml:255
+#, fuzzy
+msgid "collections_edit_addons_delete_noscript"
+msgstr "Selected add-ons will be removed upon Save"
+
+#: views/collections/edit.thtml:247
+#, fuzzy
+msgid "collections_edit_addons_description"
+msgstr ""
+"To publish new add-ons to this collection, start typing their names below."
+
+#: views/collections/edit.thtml:248
+#, fuzzy
+msgid "collections_edit_addons_description_noscript"
+msgstr ""
+"To publish new add-ons to this collection, enter a comma-separated list of "
+"Add-on IDs below."
+
+#: views/collections/edit.thtml:247 views/collections/edit.thtml:248
+#, fuzzy
+msgid "collections_edit_addons_description_publish_detailspage"
+msgstr "You can also publish an add-on from its normal listing page."
+
+#. %1$s is the date the add-on was added to the collection
+#. %1$s is the name of the user who added the add-on to the collection
+#: views/collections/edit.thtml:260
+#, fuzzy
+msgid "collections_edit_addons_listitem_added"
+msgstr "Added %1$s by %2$s"
+
+#: views/collections/edit.thtml:263
+#, fuzzy
+msgid "collections_edit_addons_listitem_comment_add"
+msgstr "Add publisher comment"
+
+#: views/collections/edit.thtml:266
+#, fuzzy
+msgid "collections_edit_addons_listitem_comment_delete"
+msgstr "Delete publisher comment"
+
+#: views/collections/edit.thtml:265
+#, fuzzy
+msgid "collections_edit_addons_listitem_comment_edit"
+msgstr "Edit publisher comment"
+
+#: views/collections/edit.thtml:271
+#, fuzzy
+msgid "collections_edit_addons_listitem_comment_note"
+msgstr ""
+"Note: Comment will appear as though written by original publisher on the "
+"original publication date"
+
+#: views/collections/edit.thtml:270
+#, fuzzy
+msgid "collections_edit_addons_listitem_comment_submit"
+msgstr "Save Comment"
+
+#: views/collections/edit.thtml:261
+#, fuzzy
+msgid "collections_edit_addons_listitem_remove"
+msgstr "Remove"
+
+#: views/collections/edit.thtml:250
+#, fuzzy
+msgid "collections_edit_addons_submit"
+msgstr "Add to Collection"
+
+#: views/collections/edit.thtml:153
+#, fuzzy
+msgid "collections_edit_check_nickname"
+msgstr "Check Availability"
+
+#: views/collections/edit.thtml:299
+#, fuzzy
+msgid "collections_edit_confirm_deletecollection"
+msgstr "Yes, I would like to delete this collection."
+
+#. %1$s is the label of the edit form's submit button
+#: views/collections/edit.thtml:300
+#, fuzzy
+msgid "collections_edit_confirm_deletecollection_description"
+msgstr "Check the box, then click on \"%1$s\" to delete this collection."
+
+#. %1$s is the "delete" submit button text
+#. %2$s is the title of the "advanced" tab
+#: views/collections/edit.thtml:95
+#, fuzzy
+msgid "collections_edit_delete_upon_submit"
+msgstr ""
+"Upon clicking \"%1$s\" below, your collection will be deleted. If you do not "
+"want to delete your collection, uncheck the confirmation box in the \"%2$s\" "
+"tab and continue editing your collection. If you leave this page without "
+"saving, your collection will also not be deleted."
+
+#: views/collections/edit.thtml:94
+#, fuzzy
+msgid "collections_edit_delete_warning"
+msgstr "Your collection is about to be deleted!"
+
+#: views/collections/add.thtml:76 views/collections/edit.thtml:144
+#, fuzzy
+msgid "collections_edit_form_error_description"
+msgstr "You must provide a description of your collection."
+
+#: views/collections/edit.thtml:181
+#, fuzzy
+msgid "collections_edit_form_error_icon"
+msgstr "There was an error uploading your icon."
+
+#: views/collections/add.thtml:69 views/collections/edit.thtml:130
+#, fuzzy
+msgid "collections_edit_form_error_name"
+msgstr "You must give your collection a name."
+
+#: views/collections/edit.thtml:158
+#, fuzzy
+msgid "collections_edit_form_error_nickname"
+msgstr "If you choose a nickname, it must be unique."
+
+#: views/collections/add.thtml:93 views/collections/edit.thtml:249
+#, fuzzy
+msgid "collections_edit_formfield_addons"
+msgstr "Add-on name:"
+
+#: views/collections/edit.thtml:281
+#, fuzzy
+msgid "collections_edit_formfield_application"
+msgstr "Associated Application"
+
+#: views/collections/edit.thtml:282
+#, fuzzy
+msgid "collections_edit_formfield_application_description"
+msgstr "Select the application that your collection supports."
+
+#: views/collections/edit.thtml:288
+#, fuzzy
+msgid "collections_edit_formfield_collectiontype"
+msgstr "Collection Type"
+
+#: views/collections/edit.thtml:295
+#, fuzzy
+msgid "collections_edit_formfield_deletecollection"
+msgstr "Delete Collection"
+
+#: views/collections/edit.thtml:296
+#, fuzzy
+msgid "collections_edit_formfield_deletecollection_description"
+msgstr "Deleting your collection will permanently erase it."
+
+#: views/collections/add.thtml:73 views/collections/edit.thtml:140
+#, fuzzy
+msgid "collections_edit_formfield_description"
+msgstr "Collection Description"
+
+#: views/collections/add.thtml:74 views/collections/edit.thtml:141
+#, fuzzy
+msgid "collections_edit_formfield_description_description"
+msgstr "Briefly describe your collection and the kind of add-ons in it"
+
+#: views/collections/edit.thtml:162
+#, fuzzy
+msgid "collections_edit_formfield_icon"
+msgstr "Icon"
+
+#: views/collections/edit.thtml:163
+#, fuzzy
+msgid "collections_edit_formfield_icon_description"
+msgstr ""
+"You can upload a JPG, GIF or PNG icon that will be resized to 32x32 pixels."
+
+#: views/collections/add.thtml:80 views/collections/edit.thtml:189
+#, fuzzy
+msgid "collections_edit_formfield_listed"
+msgstr "Who can view your collection?"
+
+#: views/collections/add.thtml:81 views/collections/edit.thtml:190
+#, fuzzy
+msgid "collections_edit_formfield_listed_description"
+msgstr ""
+"By default, collections appear in the public Collection Directory and are "
+"discoverable by anyone. If you want to restrict your collection to be "
+"viewable only by people who are given a special link, choose that option "
+"below."
+
+#: views/collections/add.thtml:84 views/collections/edit.thtml:193
+#, fuzzy
+msgid "collections_edit_formfield_listed_false"
+msgstr "Only people I invite can view my collection"
+
+#: views/collections/add.thtml:83 views/collections/edit.thtml:192
+#, fuzzy
+msgid "collections_edit_formfield_listed_true"
+msgstr "Everyone can view my collection in the directory"
+
+#: views/collections/edit.thtml:223
+#, fuzzy
+msgid "collections_edit_formfield_managers"
+msgstr "Who can manage my collection?"
+
+#: views/collections/edit.thtml:224
+#, fuzzy
+msgid "collections_edit_formfield_managers_description"
+msgstr ""
+"These users can publish add-ons to your collection, manage all add-ons and "
+"settings, and grant other users permission."
+
+#: views/collections/add.thtml:66 views/collections/edit.thtml:126
+#, fuzzy
+msgid "collections_edit_formfield_name"
+msgstr "Collection Name"
+
+#: views/collections/add.thtml:67 views/collections/edit.thtml:127
+#, fuzzy
+msgid "collections_edit_formfield_name_description"
+msgstr ""
+"Give your collection a descriptive name, such as \"Dave's Favorite Travel "
+"Add-ons\""
+
+#: views/collections/edit.thtml:148
+#, fuzzy
+msgid "collections_edit_formfield_nickname"
+msgstr "Collection Nickname"
+
+#: views/collections/edit.thtml:149
+#, fuzzy
+msgid "collections_edit_formfield_nickname_description"
+msgstr "Optionally, give your collection a unique nickname for quick access:"
+
+#: views/collections/edit.thtml:201
+#, fuzzy
+msgid "collections_edit_formfield_publishers"
+msgstr "Who can publish add-ons to your collection?"
+
+#: views/collections/edit.thtml:202
+#, fuzzy
+msgid "collections_edit_formfield_publishers_description"
+msgstr ""
+"These users can publish add-ons to your collection and remove add-ons that "
+"they publish."
+
+#: views/collections/edit.thtml:210 views/collections/edit.thtml:232
+#, fuzzy
+msgid "collections_edit_formfield_users_add"
+msgstr "Enter the e-mail address of a Firefox Add-ons account:"
+
+#: views/collections/edit.thtml:216 views/collections/edit.thtml:238
+#, fuzzy
+msgid "collections_edit_formfield_users_delete_noscript"
+msgstr "Selected accounts will be removed upon Save"
+
+#: views/collections/edit.thtml:215 views/collections/edit.thtml:237
+#, fuzzy
+msgid "collections_edit_formfield_users_new_noscript"
+msgstr ""
+"Enter a comma-separated list of e-mail addresses of Firefox Add-ons accounts"
+
+#: views/collections/edit.thtml:204 views/collections/edit.thtml:226
+#, fuzzy
+msgid "collections_edit_formfield_users_onlyme"
+msgstr "Only me"
+
+#: views/collections/edit.thtml:205 views/collections/edit.thtml:227
+#, fuzzy
+msgid "collections_edit_formfield_users_otherusers"
+msgstr "Myself and these users:"
+
+#: views/collections/edit.thtml:211 views/collections/edit.thtml:233
+#, fuzzy
+msgid "collections_edit_formfield_users_submit"
+msgstr "Add"
+
+#. %1$s is the name of the collection
+#: views/collections/edit.thtml:68
+#, fuzzy
+msgid "collections_edit_header"
+msgstr "Manage %1$s"
+
+#: views/collections/edit.thtml:246
+#, fuzzy
+msgid "collections_edit_header_addons"
+msgstr "Manage Collection Contents"
+
+#: views/collections/edit.thtml:253 views/collections/edit.thtml:258
+#, fuzzy
+msgid "collections_edit_header_addons_current"
+msgstr "Current Add-ons:"
+
+#: views/collections/edit.thtml:279
+#, fuzzy
+msgid "collections_edit_header_advanced"
+msgstr "Advanced Settings"
+
+#: views/collections/edit.thtml:186
+#, fuzzy
+msgid "collections_edit_header_permissions"
+msgstr "Manage Collection Permissions"
+
+#: views/collections/edit.thtml:170
+#, fuzzy
+msgid "collections_edit_icon_cancel"
+msgstr "Cancel"
+
+#: views/collections/edit.thtml:174 views/collections/edit.thtml:179
+#, fuzzy
+msgid "collections_edit_icon_delete"
+msgstr "Delete Icon"
+
+#: views/collections/edit.thtml:178
+#, fuzzy
+msgid "collections_edit_icon_replace"
+msgstr "Replace Icon"
+
+#. %1$s is the label of the edit form's submit button
+#: views/collections/edit.thtml:169
+#, fuzzy
+msgid "collections_edit_icon_toberemoved"
+msgstr "Icon will be removed when \"%1$s\" is clicked below"
+
+#: views/collections/edit.thtml:155
+#, fuzzy
+msgid "collections_edit_nickname_available"
+msgstr "Nickname Available"
+
+#: controllers/collections_controller.php:943
+#, fuzzy
+msgid "collections_edit_nickname_error"
+msgstr ""
+"Your nickname contained invalid characters and was corrected. Please try "
+"again."
+
+#: views/collections/edit.thtml:156
+#, fuzzy
+msgid "collections_edit_nickname_taken"
+msgstr "Nickname Taken"
+
+#. This string is followed by a URL pointing to the collection's view page
+#: views/collections/edit.thtml:75
+#, fuzzy
+msgid "collections_edit_saved_nextstep"
+msgstr "Your collection can be accessed at this location:"
+
+#: views/collections/edit.thtml:74
+#, fuzzy
+msgid "collections_edit_saved_success"
+msgstr "Your collection was successfully saved!"
+
+#: views/collections/edit.thtml:169 views/collections/edit.thtml:300
+#: views/collections/edit.thtml:308 views/pages/js_constants.js.thtml:99
+#, fuzzy
+msgid "collections_edit_submit"
+msgstr "Update Collection"
+
+#: views/collections/edit.thtml:96 views/collections/edit.thtml:297
+#: views/pages/js_constants.js.thtml:100
+#, fuzzy
+msgid "collections_edit_submit_deletecollection"
+msgstr "Delete Collection"
+
+#: views/collections/edit.thtml:111
+#, fuzzy
+msgid "collections_edit_tabheader_addons"
+msgstr "Add-ons"
+
+#: views/collections/edit.thtml:97 views/collections/edit.thtml:113
+#, fuzzy
+msgid "collections_edit_tabheader_advanced"
+msgstr "Advanced"
+
+#: views/collections/edit.thtml:108
+#, fuzzy
+msgid "collections_edit_tabheader_details"
+msgstr "Name &amp; Details"
+
+#: views/collections/edit.thtml:109
+#, fuzzy
+msgid "collections_edit_tabheader_permissions"
+msgstr "Permissions"
+
+#: models/collection_promo.php:53
+#, fuzzy
+msgid "collections_family_tagline"
+msgstr "Add-ons can keep an eye on your kids and your calendar."
+
+#: models/collection_promo.php:53
+#, fuzzy
+msgid "collections_family_title"
+msgstr "Family Organizer"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:70
+#, fuzzy
+msgid "collections_index_a_check_out"
+msgstr "Check out Add-on Collector"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:52
+#, fuzzy
+msgid "collections_index_a_create"
+msgstr "Create a Collection"
+
+#: views/collections/detail.thtml:139 views/collections/listing.thtml:85
+#: views/search/collections.thtml:84
+#, fuzzy
+msgid "collections_index_button_go"
+msgstr "Go"
+
+#. %1$s is a URL.
+#: controllers/collections_controller.php:182
+#, fuzzy
+msgid "collections_index_filler_favorites"
+msgstr ""
+"<p><strong>You don't have any favorite collections yet.</strong></p> "
+"<p>Collections you mark as favorites can be quickly accessed from this page, "
+"and will appear in the <a href='%1$s'>Add-on Collector</a> if you've "
+"installed it.</p>"
+
+#. %1$s is a URL.
+#: controllers/collections_controller.php:167
+#, fuzzy
+msgid "collections_index_filler_mine"
+msgstr ""
+"<p>You haven't created any collections yet. Collections are easy to create "
+"and fill with your favorite add-ons. <a href='%1$s'>Try it out</a>!</p>"
+
+#: views/collections/listing.thtml:51
+#, fuzzy
+msgid "collections_index_header_collections"
+msgstr "Collections"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:60
+#, fuzzy
+msgid "collections_index_header_collector"
+msgstr "Add-on Collector"
+
+#. %1$s is a comma-separated list of author names
+#: views/elements/amo2009/collection_listing_item.thtml:84
+#: views/collections/detail.thtml:151
+#, fuzzy
+msgid "collections_index_header_created"
+msgstr "created by %1$s"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:47
+#, fuzzy
+msgid "collections_index_header_what"
+msgstr "What are Collections?"
+
+#: views/collections/detail.thtml:132 views/collections/listing.thtml:78
+#: views/search/collections.thtml:66
+#, fuzzy
+msgid "collections_index_label_sortby"
+msgstr "Sort by"
+
+#: controllers/collections_controller.php:130
+#, fuzzy
+msgid "collections_index_li_editors"
+msgstr "Editor's Picks"
+
+#: views/collections/subscribe.thtml:64
+#: controllers/collections_controller.php:140
+#, fuzzy
+msgid "collections_index_li_favorites"
+msgstr "My Favorites"
+
+#: controllers/collections_controller.php:138
+#, fuzzy
+msgid "collections_index_li_mine"
+msgstr "My Collections"
+
+#: controllers/collections_controller.php:132
+#, fuzzy
+msgid "collections_index_li_popular"
+msgstr "Popular"
+
+#: views/search/collections.thtml:74 controllers/collections_controller.php:81
+#, fuzzy
+msgid "collections_index_option_all"
+msgstr "Most popular all time"
+
+#: views/search/collections.thtml:72 controllers/collections_controller.php:78
+#, fuzzy
+msgid "collections_index_option_month"
+msgstr "Most popular this month"
+
+#: views/search/collections.thtml:76 controllers/collections_controller.php:84
+#, fuzzy
+msgid "collections_index_option_newest"
+msgstr "Newest"
+
+#: views/search/collections.thtml:70 controllers/collections_controller.php:75
+#, fuzzy
+msgid "collections_index_option_week"
+msgstr "Most popular this week"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:67
+#, fuzzy
+msgid "collections_index_p_collector"
+msgstr ""
+"There's a new way to manage and find favorite add-ons. Comment, share and "
+"sync collections, all from your browser"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:48
+#, fuzzy
+msgid "collections_index_p_what_are"
+msgstr "Collections are groups of related add-ons assembled for easy sharing."
+
+#. %s is a date in the _('date') format
+#: views/elements/collections_interactive_addon.thtml:85
+#, php-format
+msgid "collections_interactive_addon_added"
+msgstr "Tilføjet %s"
+
+#: models/collection_promo.php:55
+#, fuzzy
+msgid "collections_reference_tagline"
+msgstr "Add-ons can do better research online."
+
+#: models/collection_promo.php:55
+#, fuzzy
+msgid "collections_reference_title"
+msgstr "Reference Desk"
+
+#: models/collection_promo.php:52
+#, fuzzy
+msgid "collections_social_tagline"
+msgstr "Add-ons can manage your social network."
+
+#: models/collection_promo.php:52
+#, fuzzy
+msgid "collections_social_title"
+msgstr "Social Circuit"
+
+#: views/collections/subscribe.thtml:91
+#, fuzzy
+msgid "collections_subscribe_button_close"
+msgstr "Close"
+
+#: views/collections/subscribe.thtml:70
+#, fuzzy
+msgid "collections_subscribe_error"
+msgstr ""
+"An error occurred trying to add a favorite collection. Is this collection "
+"already a favorite?"
+
+#: views/collections/subscribe.thtml:96
+#, fuzzy
+msgid "collections_subscribe_label_bothersome"
+msgstr "Don't show me this message again."
+
+#. %1$s is the collection name
+#: views/collections/subscribe.thtml:60
+#, fuzzy
+msgid "collections_subscribe_success"
+msgstr "%1$s has been added to your favorite collections."
+
+#. %1$s is the link to the "My Favorites" tab on the main collections page
+#. %2$s is the localized title of the "My Favorites" tab
+#. %3$s is the link URL to the collector add-on
+#: views/collections/subscribe.thtml:62
+#, fuzzy
+msgid "collections_subscribe_success_desc"
+msgstr ""
+"You can now quickly find this collection from the <a href=\"%1$s\">%2$s</a> "
+"tab in the directory. For an even easier way to keep track of your favorite "
+"collections, try out our <a href=\"%3$s\">Add-on Collector</a> extension for "
+"Firefox."
+
+#: views/collections/listing.thtml:55
+#, fuzzy
+msgid "collections_success_delete"
+msgstr "The collection has been deleted."
+
+#: models/collection_promo.php:54
+#, fuzzy
+msgid "collections_travel_tagline"
+msgstr "Add-ons can turn you into a travel agent."
+
+#: models/collection_promo.php:54
+#, fuzzy
+msgid "collections_travel_title"
+msgstr "The Traveler's Pack"
+
+#. A collection of add-ons that is automatically built for a user. They are "automatically published" to this collection.
+#: controllers/collections_controller.php:581
+#, fuzzy
+msgid "collections_type_autopublisher"
+msgstr "Auto-publisher"
+
+#. A collection that has been chosen by an Editor as notable or exceptional
+#: controllers/collections_controller.php:582
+#, fuzzy
+msgid "collections_type_editorspick"
+msgstr "Editor's Pick"
+
+#: controllers/collections_controller.php:580
+#, fuzzy
+msgid "collections_type_normal"
+msgstr "Normal"
+
+#: views/collections/subscribe.thtml:84
+#, fuzzy
+msgid "collections_unsubscribe_error"
+msgstr ""
+"An error occurred trying to remove a favorite collection. Was this "
+"collection not a favorite?"
+
+#. %1$s is the collection name
+#: views/collections/subscribe.thtml:78
+#, fuzzy
+msgid "collections_unsubscribe_success"
+msgstr "%1$s has been removed from your favorite collections."
+
+#: models/collection_promo.php:56
+#, fuzzy
+msgid "collections_webdev_tagline"
+msgstr "Add-ons make it easier to build the perfect website."
+
+#: models/collection_promo.php:56
+#, fuzzy
+msgid "collections_webdev_title"
+msgstr "Web Developer's Toolbox"
+
+#: views/elements/amo2009/collections_sidebar_whatare.thtml:40
+#, fuzzy
+msgid "collections_whatare_header"
+msgstr "What are Collections?"
+
+#: views/elements/amo2009/collections_sidebar_whatare.thtml:45
+#, fuzzy
+msgid "collections_whatare_learnmore"
+msgstr "Read the FAQ"
+
+#: views/elements/amo2009/collections_sidebar_whatare.thtml:44
+#, fuzzy
+msgid "collections_whatare_text"
+msgstr ""
+"There’s a new way to manage and find favorite add-ons. Comment, share and "
+"sync collections, all from your browser."
+
+#: views/pages/collector_faq.thtml:61 views/pages/collector_features.thtml:67
+#, fuzzy
+msgid "collector_features_a_home"
+msgstr "Add-on Collector Home"
+
+#: views/elements/amo2009/collector_sidebar_download.thtml:46
+#, fuzzy
+msgid "collector_features_heading_download"
+msgstr "Download the Add-on Collector:"
+
+#: views/elements/amo2009/collector_sidebar_download.thtml:43
+#: views/pages/collector_firstrun.thtml:116 views/pages/collector.thtml:69
+#, fuzzy
+msgid "collector_features_img_logo"
+msgstr "Add-on Collector Logo"
+
+#: views/compatibility/dashboard.thtml:49
+#: controllers/compatibility_controller.php:72
+msgid "compatibility_dashboard_center_header"
+msgstr "Kompatibilitetscenter for tilføjelser"
+
+#. %1$s is the name of an application and a version. Example: Firefox 3.0
+#. %2$s is the name of an application. Example: Firefox
+#: views/compatibility/dashboard.thtml:50
+msgid "compatibility_dashboard_intro"
+msgstr ""
+"Vær klar til udgivelsen af %1$s med værktøjerne og informationerne herunder."
+
+#: views/compatibility/dashboard.thtml:103
+msgid "compatibility_dashboard_loading"
+msgstr "Indlæser data..."
+
+#: views/compatibility/dashboard.thtml:45
+msgid "compatibility_dashboard_main_link"
+msgstr "Tilbage til hovedsiden"
+
+#: views/compatibility/dashboard.thtml:100 views/compatibility/report.thtml:43
+msgid "compatibility_dashboard_report"
+msgstr "Kompatibilitetsrapport for tilføjelser"
+
+#: views/compatibility/dashboard.thtml:53
+#: views/compatibility/dashboard.thtml:110
+#: views/compatibility/developers.thtml:43
+msgid "compatibility_developer_info"
+msgstr "Information til udviklere af tilføjelser"
+
+#: views/compatibility/developers.thtml:66
+msgid "compatibility_developers_adjust_maxversion"
+msgstr "Juster maxVersion uden at uploade"
+
+#: views/compatibility/dashboard.thtml:124
+msgid "compatibility_developers_check_status"
+msgstr "Kontroller status for mine tilføjelser"
+
+#. %1$s is a URL
+#. %2$s is an application and version. Example: Firefox 3.0
+#: views/compatibility/dashboard.thtml:126
+msgid "compatibility_developers_login_first"
+msgstr ""
+"Hvis du har tilføjelser hostet på Mozilla Add-ons, kan du <a href=\"%1$s"
+"\">logge ind</a> for at se status for dine tilføjelser relateret til %2$s."
+
+#: views/compatibility/dashboard.thtml:114
+msgid "compatibility_developers_mdclogo_alt"
+msgstr "Logo for Mozilla Developer Center"
+
+#: views/compatibility/developers.thtml:73
+msgid "compatibility_developers_no_addons"
+msgstr "Du har ingen tilføjelser, som hostes af Mozilla Add-ons."
+
+#: views/compatibility/dashboard.thtml:133
+#: views/compatibility/developers.thtml:55
+msgid "compatibility_developers_results"
+msgstr "Resultat af statustjek"
+
+#: views/compatibility/dashboard.thtml:137
+msgid "compatibility_developers_retrieving"
+msgstr "Indlæser status for tilføjelser..."
+
+#. %1$s is a number
+#. %2$s is an application name
+#. %3$s is a number.
+#. Full example: 50 Firefox users (10% of total)
+#: views/compatibility/developers.thtml:65
+msgid "compatibility_developers_user_count"
+msgstr "%1$s brugere af %2$s (%3$s&#37; af alle)"
+
+#: views/compatibility/report.thtml:45
+msgid "compatibility_report_detail_intro"
+msgstr ""
+"Tilføjelserne herunder udgør 95% af den del af tilføjelsesbrugen som Mozilla "
+"kender til og er ordnet efter antal brugere."
+
+#: views/compatibility/dashboard.thtml:94
+msgid "compatibility_report_detailed_link"
+msgstr "Vis detaljeret rapport"
+
+#. %1$s and %2$s are numbers
+#. %3$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:65
+msgid "compatibility_report_intro"
+msgstr ""
+"Af de %1$s tilføjelser, som udgør 95&#37; af den del af tilføjelsesbrugen "
+"som Mozilla kender til, er <b>%2$s&#37;</b> i øjeblikket kompatible med de "
+"seneste udgaver af %3$s."
+
+#: views/compatibility/dashboard.thtml:81
+msgid "compatibility_report_legend_alpha"
+msgstr "Alfaversioner"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:81
+msgid "compatibility_report_legend_alpha_description"
+msgstr "Tilføjelser som er kompatible med en alfaversion af %1$s"
+
+#: views/compatibility/dashboard.thtml:85
+msgid "compatibility_report_legend_beta"
+msgstr "Betaversioner"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:85
+msgid "compatibility_report_legend_beta_description"
+msgstr ""
+"Tilføjelser som er kompatible med en betaversion eller release candidate af %"
+"1$s"
+
+#: views/compatibility/dashboard.thtml:89
+msgid "compatibility_report_legend_latest"
+msgstr "Seneste version"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:89
+msgid "compatibility_report_legend_latest_description"
+msgstr "Tilføjelser som er opdateret til de seneste udgaver af %1$s"
+
+#: views/compatibility/dashboard.thtml:77
+msgid "compatibility_report_legend_other"
+msgstr "Andre versioner"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:77
+msgid "compatibility_report_legend_other_description"
+msgstr "Tilføjelser som ikke er kompatible med nogen versioner af %1$s"
+
+#: views/compatibility/dashboard.thtml:62
+msgid "compatibility_report_title"
+msgstr "Kompatibilitetsrapport for tilføjelser"
+
+#: views/compatibility/dashboard.thtml:54
+#: views/compatibility/dashboard.thtml:144 views/compatibility/users.thtml:42
+msgid "compatibility_user_info"
+msgstr "Information til brugere af tilføjelser"
+
+#: views/compatibility/dashboard.thtml:52
+msgid "compatibility_view_report"
+msgstr "Vis kompatibilitetsrapport"
+
+#. %s is a URL
+#: views/pages/credits.thtml:142
+#, php-format
+msgid "credits_contributing"
+msgstr "Se hvodan du selv kan bidrage på %s."
+
+#: views/pages/credits.thtml:142
+msgid "credits_contributing_wikipage"
+msgstr "vores wikiside"
+
+#: views/pages/credits.thtml:99
+msgid "credits_intro"
+msgstr ""
+"Mozilla vil gerne takke følgende personer for deres bidrag til addons."
+"mozilla.org gennem årene:"
+
+#: views/pages/credits.thtml:103
+msgid "credits_section_developers"
+msgstr "Udviklere"
+
+#: views/pages/credits.thtml:115
+msgid "credits_section_editors"
+msgstr "Redaktører"
+
+#: views/pages/credits.thtml:109
+msgid "credits_section_localizers"
+msgstr "Oversættere"
+
+#: views/pages/credits.thtml:121
+msgid "credits_section_other_contributors"
+msgstr "Andre bidragydere"
+
+#: views/pages/credits.thtml:127
+msgid "credits_section_past_developers"
+msgstr "Forhenværende udviklere"
+
+#: views/pages/credits.thtml:133
+msgid "credits_section_software"
+msgstr "Software og billeder"
+
+#: views/pages/credits.thtml:136
+msgid "credits_software_famfamfam"
+msgstr ""
+"Visse ikoner på siden er fra <a href=\"http://www.famfamfam.com/lab/icons/"
+"silk/\">famfamfam Silk Icon Set</a>, givet i licens under <a href=\"http://"
+"creativecommons.org/licenses/by/2.5/\">Creative Commons Navngivelse 2.5 "
+"Licens</a>."
+
+#: views/pages/credits.thtml:137
+msgid "credits_software_timeplot"
+msgstr ""
+"Nogle sider bruger elementer fra <a href=\"http://www.simile-widgets.org/"
+"timeplot/\">Timeplot</a>, givet i licens under en <a href=\"http://simile."
+"mit.edu/license.html\">BSD-licens</a>."
+
+#. date format string as used in PHP's strftime():
+#. http://php.net/strftime
+#: views/elements/collections_interactive_addon.thtml:85
+#: views/elements/amo2009/addon_version_detail.thtml:53
+#: views/elements/amo2009/homepage_addon.thtml:115
+#: views/elements/addon_version_detail.thtml:54
+#: views/elements/addon_listitem.thtml:124 views/elements/feature.thtml:106
+#: views/collections/detail.thtml:118 views/collections/edit.thtml:325
+#: views/users/info.thtml:76 views/editors/reviews_queue.thtml:57
+#: views/editors/reviews_queue.thtml:68 views/developers/dashboard.thtml:65
+#: views/developers/versions_edit.thtml:208 views/developers/versions.thtml:67
+#: views/search/rss/index.thtml:5 views/addons/rss/versions.thtml:42
+#: views/addons/display.thtml:104 views/addons/display.thtml:356
+#: views/addons/browse_thumbs.thtml:75 views/reviews/add.thtml:63
+#: views/reviews/display.thtml:74 views/reviews/display.thtml:160
+#: views/reviews/delete.thtml:54 controllers/statistics_controller.php:244
+#: controllers/collections_controller.php:1047
+msgid "date"
+msgstr "%e. %B %Y"
+
+#. date and time format string (strftime)
+#. http://php.net/strftime
+#: views/elements/addon_version_detail.thtml:53
+#: views/developers/discuss.thtml:52 views/developers/discuss.thtml:62
+#: views/admin/addons_status.thtml:57
+msgid "datetime"
+msgstr "%e. %B %Y, %H:%M"
+
+#: views/elements/developers/actionbar.thtml:47
+msgid "devcp_actionbar_link_details"
+msgstr "Detailed Info"
+
+#: views/elements/developers/actionbar.thtml:42
+#: views/elements/developers/actionbar.thtml:50
+#: views/developers/dashboard.thtml:64
+msgid "devcp_actionbar_link_edit"
+msgstr "Edit Add-on"
+
+#: views/elements/developers/actionbar.thtml:51
+msgid "devcp_actionbar_link_newversion"
+msgstr "Upload New Version"
+
+#: views/elements/developers/actionbar.thtml:44
+#: views/elements/developers/actionbar.thtml:49
+#: views/developers/dashboard.thtml:73
+msgid "devcp_actionbar_link_stats"
+msgstr "Statistics Dashboard"
+
+#. %1$s is a filename, e.g. "foo.txt"
+#. %2$s is the extension, e.g. ".txt"
+#. %3$s is a list of valid extensions, like ".png, .jpg, .gif"
+#: controllers/developers_controller.php:1361
+msgid "devcp_add_previews_extension_error"
+msgstr "File %1$s has an invalid extension (%2$s). Allowed extensions: %3$s"
+
+#. %s is the filename.
+#: controllers/developers_controller.php:1394
+msgid "devcp_add_previews_save_error"
+msgstr "File %s could not be saved to the database. Please try again."
+
+#. %1$s is the preview ID number, %2$s is the filename.
+#: controllers/developers_controller.php:1389
+msgid "devcp_add_previews_success_replace"
+msgstr "Preview %1$s was replaced with file %2$s successfully."
+
+#. %s is the filename.
+#: controllers/developers_controller.php:1391
+msgid "devcp_add_previews_success_upload"
+msgstr "File %s was uploaded successfully. You can add a caption below."
+
+#: controllers/components/developers.php:1163
+msgid "devcp_additem_addontype_autodetect"
+msgstr "(auto-detect)"
+
+#: views/elements/developers/additem.thtml:76
+msgid "devcp_additem_linktitle_opensin_newwindow"
+msgstr "Opens in a new window"
+
+#: views/elements/developers/additem.thtml:41
+msgid "devcp_additem_sidebar_title"
+msgstr "Submit Add-on"
+
+#: views/elements/developers/additem.thtml:53
+msgid "devcp_additem_step0_newlink"
+msgstr "Developer Agreement"
+
+#: views/elements/developers/additem.thtml:46
+msgid "devcp_additem_step1_link"
+msgstr "Step 1: Upload"
+
+#: views/elements/developers/additem.thtml:47
+msgid "devcp_additem_step2_link"
+msgstr "Step 2: Add-on Details"
+
+#: views/elements/developers/additem.thtml:48
+msgid "devcp_additem_step3_link"
+msgstr "Step 3: Version Details"
+
+#: views/elements/developers/additem.thtml:49
+msgid "devcp_additem_step4_link"
+msgstr "Step 4: Localization"
+
+#: views/elements/developers/additem.thtml:50
+msgid "devcp_additem_step5_link"
+msgstr "Step 5: Success"
+
+#: views/elements/developers/additem.thtml:76
+msgid "devcp_additem_submissionhelp_link"
+msgstr "Submission Help"
+
+#: controllers/previews_controller.php:168
+#: controllers/previews_controller.php:277
+msgid "devcp_addon_field_preview_caption_displaytitle"
+msgstr "Preview Caption"
+
+#: views/developers/addon_status.thtml:177
+msgid "devcp_addon_status_action_activate"
+msgstr "Make Active"
+
+#: views/developers/addon_status.thtml:178
+msgid "devcp_addon_status_action_activate_description"
+msgstr ""
+"Make your add-on active for it to show up in public listings and enable the "
+"update check service."
+
+#: views/developers/addon_status.thtml:135
+msgid "devcp_addon_status_action_complete"
+msgstr "Complete Add-on"
+
+#: views/developers/addon_status.thtml:136
+msgid "devcp_addon_status_action_complete_description"
+msgstr "Complete your add-on and move to the Sandbox"
+
+#: views/developers/addon_status.thtml:181
+msgid "devcp_addon_status_action_deactivate"
+msgstr "Make Inactive"
+
+#: views/developers/addon_status.thtml:182
+msgid "devcp_addon_status_action_deactivate_description"
+msgstr ""
+"Make your add-on inactive to hide it from all public listings and disable "
+"the update check service."
+
+#: views/developers/addon_status.thtml:143
+msgid "devcp_addon_status_action_move"
+msgstr "Move to Sandbox"
+
+#: views/developers/addon_status.thtml:144
+msgid "devcp_addon_status_action_move_description"
+msgstr "Move your add-on back to the Sandbox. This is reversible."
+
+#: views/developers/addon_status.thtml:139
+msgid "devcp_addon_status_action_nominate"
+msgstr "Nominate for Public"
+
+#: views/developers/addon_status.thtml:140
+msgid "devcp_addon_status_action_nominate_description"
+msgstr "Nominate your add-on to become Public"
+
+#: views/developers/addon_status.thtml:147
+msgid "devcp_addon_status_action_public"
+msgstr "Make Public"
+
+#: views/developers/addon_status.thtml:148
+msgid "devcp_addon_status_action_public_description"
+msgstr "Make your add-on Public again."
+
+#: views/developers/addon_status.thtml:169
+msgid "devcp_addon_status_active"
+msgstr ""
+"Your add-on is <span class=\"inactive-0\">Active</span>. This means your add-"
+"on is showing up in all available listings appropriate for its status above."
+
+#: views/developers/addon_status.thtml:111
+msgid "devcp_addon_status_completion_disabled"
+msgstr ""
+"Please fulfill the criteria above before you can complete your add-on and "
+"move it to the <span class=\"status-1\">Sandbox</span>."
+
+#: views/developers/addon_status.thtml:108
+msgid "devcp_addon_status_completion_enabled"
+msgstr ""
+"You may now complete your add-on and move it to the <span class=\"status-1"
+"\">Sandbox</span> by clicking the button below."
+
+#: views/developers/addon_status.thtml:102
+msgid "devcp_addon_status_criteria_category"
+msgstr "At least one category selected"
+
+#: views/developers/addon_status.thtml:101
+msgid "devcp_addon_status_criteria_description"
+msgstr "Add-on Description required"
+
+#: views/developers/addon_status.thtml:99
+msgid "devcp_addon_status_criteria_name"
+msgstr "Add-on Name required"
+
+#: views/developers/addon_status.thtml:120
+msgid "devcp_addon_status_criteria_prerelease"
+msgstr "Add-on is not marked as pre-release."
+
+#: views/developers/addon_status.thtml:119
+msgid "devcp_addon_status_criteria_preview"
+msgstr "At least one preview image required for extensions and themes."
+
+#: views/developers/addon_status.thtml:100
+msgid "devcp_addon_status_criteria_summary"
+msgstr "Add-on Summary required"
+
+#. %s is the status in a span, e.g. "<span>_('Public')</span>".
+#: views/developers/addon_status.thtml:58
+msgid "devcp_addon_status_header"
+msgstr "Add-on Status: %s"
+
+#: views/developers/addon_status.thtml:152
+#: views/developers/addon_status.thtml:173
+msgid "devcp_addon_status_header_actions"
+msgstr "Available Actions"
+
+#: views/developers/addon_status.thtml:168
+msgid "devcp_addon_status_header_active"
+msgstr "Active Status: <span class=\"inactive-0\">Active</span>"
+
+#: views/developers/addon_status.thtml:97
+msgid "devcp_addon_status_header_criteria"
+msgstr "Add-on Completion Criteria"
+
+#: views/developers/addon_status.thtml:164
+msgid "devcp_addon_status_header_inactive"
+msgstr "Active Status: <span class=\"inactive-1\">Inactive</span>"
+
+#: views/developers/addon_status.thtml:117
+msgid "devcp_addon_status_header_nomination"
+msgstr "Public Nomination Criteria"
+
+#: views/developers/addon_status.thtml:190
+msgid "devcp_addon_status_header_trusted"
+msgstr "Trusted Status: <span class=\"status-4\">Trusted</span>"
+
+#: views/developers/addon_status.thtml:165
+msgid "devcp_addon_status_inactive"
+msgstr ""
+"Your add-on is <span class=\"inactive-1\">Inactive</span>. This means your "
+"add-on will not show up in any listing, regardless of its status above. "
+"Updates are <b>not</b> being provided to your add-on through the update "
+"check service."
+
+#: views/developers/addon_status.thtml:128
+msgid "devcp_addon_status_nominate_disabled"
+msgstr ""
+"Please fulfill the criteria above before nominating your add-on to become "
+"<span class=\"status-4\">Public</span>."
+
+#: views/developers/addon_status.thtml:125
+msgid "devcp_addon_status_nominate_enabled"
+msgstr ""
+"You may now nominate your add-on for <span class=\"status-4\">Public</span> "
+"by clicking the button below."
+
+#: views/developers/addon_status.thtml:64
+msgid "devcp_addon_status_public"
+msgstr "Public"
+
+#: views/developers/addon_status.thtml:63
+msgid "devcp_addon_status_sandbox"
+msgstr "Sandbox"
+
+#. %s is an email address.
+#: views/developers/addon_status.thtml:89
+msgid "devcp_addon_status_switch_disabled"
+msgstr ""
+"Your add-on was <span class=\"status-5\">Disabled</span> by an administrator "
+"and cannot be used. If you have any questions, please e-mail %s."
+
+#: views/developers/addon_status.thtml:67
+msgid "devcp_addon_status_switch_incomplete"
+msgstr ""
+"Your add-on is currently <span class=\"status-0\">Incomplete</span>. This "
+"means your add-on is not showing up on any portion of the site or update "
+"check service. You may come to this page to complete your add-on after it "
+"meets the criteria below for completion and transfer to the <span class="
+"\"status-1\">Sandbox</span>."
+
+#. %s is a number, perhaps 42.
+#: views/developers/addon_status.thtml:77
+msgid "devcp_addon_status_switch_nominated"
+msgstr ""
+"Your add-on is currently nominated to become <span class=\"status-4"
+"\">Public</span> and is awaiting editor review. There are currently %s other "
+"add-ons in the nomination queue."
+
+#. %s is an email address.
+#: views/developers/addon_status.thtml:81
+msgid "devcp_addon_status_switch_pending"
+msgstr ""
+"Your add-on is pending. This shouldn't have happened. Please e-mail %s with "
+"your add-on ID and state this error."
+
+#: views/developers/addon_status.thtml:85
+msgid "devcp_addon_status_switch_public"
+msgstr ""
+"Your add-on is <span class=\"status-4\">Public</span>, which means it will "
+"show up in all listings and searches and can be downloaded without "
+"restriction. Updates are being provided to your add-on through the update "
+"check service."
+
+#: views/developers/addon_status.thtml:71
+#: views/developers/addon_status.thtml:75
+msgid "devcp_addon_status_switch_sandbox"
+msgstr ""
+"Your add-on is in the <span class=\"status-1\">Sandbox</span>, which means "
+"it will show up in listings and searches, but users must log in to download "
+"it. Updates are <b>not</b> being provided to your add-on through the update "
+"check service."
+
+#. %s is the add-on name.
+#: views/developers/addon_status_nominate.thtml:43
+#: views/developers/addon_status_confirm.thtml:43
+#: views/developers/addon_status.thtml:43
+msgid "devcp_addon_status_title"
+msgstr "%s Status"
+
+#: views/developers/addon_status.thtml:191
+msgid "devcp_addon_status_trusted"
+msgstr ""
+"Your add-on is <span class=\"status-4\">Trusted</span>. This means you can "
+"submit updates to your add-on without editor review."
+
+#: views/developers/dashboard.thtml:68
+msgid "devcp_dashboard_active"
+msgstr "Active"
+
+#. %1$s is the add-on type string
+#. %2$s is Inactive or Active in a <span>
+#. %3$s is the addon's public status (Public, In Sandbox, ...) in a <span>
+#: views/developers/dashboard.thtml:69
+msgid "devcp_dashboard_addontype_status"
+msgstr "%1$s currently %2$s and %3$s"
+
+#: views/developers/dashboard.thtml:67
+msgid "devcp_dashboard_change_status"
+msgstr "Change Status"
+
+#. %s is the addons email address.
+#: views/developers/dashboard.thtml:99
+msgid "devcp_dashboard_disabled_questions"
+msgstr ""
+"Your add-on was disabled by an administrator and cannot be used. If you "
+"have any questions, please email %s."
+
+#. %s is the (localized) add-on status string in a span, e.g. "Disabled"
+#: views/developers/dashboard.thtml:98
+msgid "devcp_dashboard_disabled_status"
+msgstr "Add-on Status: %s"
+
+#: views/developers/dashboard.thtml:43
+msgid "devcp_dashboard_header_main"
+msgstr "Developer Dashboard"
+
+#: views/developers/dashboard.thtml:110
+msgid "devcp_dashboard_header_welcome"
+msgstr "Welcome to the Developer Dashboard"
+
+#: views/developers/dashboard.thtml:68
+msgid "devcp_dashboard_inactive"
+msgstr "Inactive"
+
+#. %s is a date in the _('date') format
+#: views/developers/dashboard.thtml:65
+msgid "devcp_dashboard_last_edited"
+msgstr "Last edited on %s"
+
+#: views/developers/dashboard.thtml:111
+msgid "devcp_dashboard_learn"
+msgstr ""
+"You don't currently have any add-ons hosted on Mozilla Add-ons. To learn how "
+"the process works and submit your first add-on, click Get Started below."
+
+#: views/developers/dashboard.thtml:112
+msgid "devcp_dashboard_start"
+msgstr "Get Started"
+
+#: views/developers/dashboard.thtml:82
+msgid "devcp_dashboard_versions"
+msgstr "Versions and Files"
+
+#: views/developers/dashboard.thtml:91
+msgid "devcp_dashboard_versions_new"
+msgstr "Upload a new version"
+
+#. %s is the preview ID number.
+#: controllers/developers_controller.php:1415
+msgid "devcp_delete_previews_error"
+msgstr "Preview %s could not be deleted from the database. Please try again."
+
+#. %s is the preview ID number.
+#: controllers/developers_controller.php:1413
+msgid "devcp_delete_previews_success"
+msgstr "Preview %s has been deleted successfully."
+
+#: controllers/developers_controller.php:1089
+msgid "devcp_delete_version_priv_error"
+msgstr "You do not have privileges to delete versions or files."
+
+#. %1$s is the count of files, a number
+#. %2$s is a status string like _('Public') or _('Incomplete')
+#: controllers/components/amo.php:549
+msgid "devcp_describe_version_status"
+msgid_plural "devcp_describe_version_status"
+msgstr[0] "%1$s %2$s file"
+msgstr[1] "%1$s %2$s files"
+
+#. %s is a version number. Example: 3.0
+#: views/developers/versions.thtml:65
+#, php-format
+msgid "devcp_details_version"
+msgstr "Version %s"
+
+#: views/developers/discuss.thtml:68
+msgid "devcp_discuss_addreply_header"
+msgstr "Add Reply"
+
+#: views/developers/discuss.thtml:57
+msgid "devcp_discuss_allreplies_header"
+msgstr "Replies"
+
+#. notice when an error occurs saving a discussion reply
+#. %1 is the email address (linked) for the amo-editors list
+#: views/developers/discuss.thtml:70
+msgid "devcp_discuss_error_notice"
+msgstr ""
+"There was an error saving your reply. Please contact %1$s about the issue."
+
+#. %1 is the add-on name, %2 is the add-on's version number currently being reviewed by an editor
+#: views/developers/discuss.thtml:46
+msgid "devcp_discuss_intro"
+msgstr ""
+"A Mozilla Add-ons Editor requested further information from you regarding "
+"version %2$s of your add-on %1$s."
+
+#. %1 is the add-on name
+#: views/developers/discuss.thtml:43
+msgid "devcp_discuss_pagetitle"
+msgstr "Provide More Information For the Add-on Review of %1$s"
+
+#. submit button text
+#: views/developers/discuss.thtml:79
+msgid "devcp_discuss_submit_reply"
+msgstr "Submit Reply"
+
+#: views/developers/discuss.thtml:72
+msgid "devcp_discuss_success_message"
+msgstr ""
+"Your reply was successfully saved. The other participants of the discussion "
+"will be notified by email."
+
+#. in an author/editor discussion about an add-on to be reviewed:
+#. %1 is the commenter's user name (linked).
+#. %2 is the full date the comment was made.
+#: views/developers/discuss.thtml:52 views/developers/discuss.thtml:62
+msgid "devcp_discuss_writtenby"
+msgstr "written by %1$s on %2$s"
+
+#: views/developers/addon_edit_authors.thtml:72
+#: views/developers/addon_edit_authors.thtml:81
+msgid "devcp_edit_authors_add_author"
+msgstr "Add New Author"
+
+#: views/developers/addon_edit_authors.thtml:96
+msgid "devcp_edit_authors_add_author_button"
+msgstr "Add Author"
+
+#: views/developers/addon_edit_authors.thtml:83
+msgid "devcp_edit_authors_add_email"
+msgstr "Author Account Email:"
+
+#: views/developers/addon_edit_authors.thtml:98
+msgid "devcp_edit_authors_add_loading"
+msgstr "Checking account email..."
+
+#: views/developers/addon_edit_authors.thtml:70
+msgid "devcp_edit_authors_click_save"
+msgstr "Click the Update Authors button below to save."
+
+#: views/developers/addon_edit_authors.thtml:58
+msgid "devcp_edit_authors_header_current"
+msgstr "Current Authors"
+
+#: views/developers/addon_edit_authors.thtml:50
+msgid "devcp_edit_authors_header_manage"
+msgstr "Manage Add-on Authors"
+
+#: views/developers/addon_edit_authors.thtml:93
+msgid "devcp_edit_authors_label_add_listed"
+msgstr "List as author in public display pages"
+
+#: views/developers/addon_edit_authors.thtml:89
+msgid "devcp_edit_authors_label_developer"
+msgstr ""
+"<strong>Developer</strong> - Can manage all aspects of the add-on listing, "
+"except for adding and removing other authors."
+
+#: views/developers/addon_edit_authors.thtml:88
+msgid "devcp_edit_authors_label_owner"
+msgstr ""
+"<strong>Owner</strong> - Can manage all aspects of the add-on listing, "
+"including adding and removing other authors."
+
+#: views/developers/addon_edit_authors.thtml:90
+msgid "devcp_edit_authors_label_viewer"
+msgstr ""
+"<strong>Viewer</strong> - Can view add-on developer listing and statistics, "
+"but can't make any changes."
+
+#. Placeholder for the empty option in a <select>.
+#: views/developers/addon_edit_categories.thtml:69
+msgid "devcp_edit_authors_option_empty"
+msgstr "----------------"
+
+#: views/developers/addon_edit_authors.thtml:86
+msgid "devcp_edit_authors_select_role"
+msgstr "Select a role for the author:"
+
+#. Column name in a table.
+#: views/developers/addon_edit_authors.thtml:62
+msgid "devcp_edit_authors_th_author"
+msgstr "Author"
+
+#. Column name in a table.
+#: views/developers/addon_edit_authors.thtml:64
+msgid "devcp_edit_authors_th_listed"
+msgstr "Listed"
+
+#. Column name in a table.
+#: views/developers/addon_edit_authors.thtml:63
+msgid "devcp_edit_authors_th_role"
+msgstr "Role"
+
+#: views/developers/addon_edit_authors.thtml:77
+msgid "devcp_edit_authors_update_author"
+msgstr "Update authors"
+
+#: views/developers/addon_edit_categories.thtml:99
+msgid "devcp_edit_categories_button_update"
+msgstr "Update Categories"
+
+#: views/developers/addon_edit_categories.thtml:88
+msgid "devcp_edit_categories_does_not_fit"
+msgstr "My add-on doesn't fit into any available categories."
+
+#. %s is the application name (Firefox, Thunderbird).
+#: views/developers/addon_edit_categories.thtml:61
+msgid "devcp_edit_categories_header_application"
+msgstr "%s Categories"
+
+#: views/developers/addon_edit_categories.thtml:49
+msgid "devcp_edit_categories_header_manage"
+msgstr "Manage Add-on Categories"
+
+#: views/developers/addon_edit_categories.thtml:91
+msgid "devcp_edit_categories_hover"
+msgstr "Hover over a category to see its description."
+
+#. %s is the category number (1, 2, 3).
+#: views/developers/addon_edit_categories.thtml:67
+msgid "devcp_edit_categories_label_category_num"
+msgstr "Category %s"
+
+#: views/developers/addon_edit_categories.thtml:94
+#: views/developers/addon_edit_categories.thtml:103
+msgid "devcp_edit_categories_none_available"
+msgstr "No categories are available for this add-on type and application."
+
+#: views/developers/addon_edit_categories.thtml:86
+msgid "devcp_edit_categories_other"
+msgstr ""
+"Place your add-on into this category only if it does not fit into any other "
+"available categories."
+
+#. %s is the application name (Firefox, Thunderbird).
+#: views/developers/addon_edit_categories.thtml:63
+msgid "devcp_edit_categories_select_application_categories"
+msgstr "Select up to three %s categories for your add-on"
+
+#: views/developers/addon_edit.thtml:47
+msgid "devcp_edit_dd_manage_authors"
+msgstr "Add or remove users that can manage this add-on."
+
+#: views/developers/addon_edit.thtml:49
+msgid "devcp_edit_dd_manage_categories"
+msgstr ""
+"Select the relevant categories for each application your add-on supports."
+
+#: views/developers/addon_edit.thtml:51
+msgid "devcp_edit_dd_manage_description"
+msgstr ""
+"Add and modify translations for your add-on's summary, description, end-user "
+"license, and privacy policy."
+
+#: views/developers/addon_edit.thtml:53
+msgid "devcp_edit_dd_manage_properties"
+msgstr "Change your add-on's name, homepage, icon, and other flags."
+
+#: views/developers/addon_edit_descriptions.thtml:116
+msgid "devcp_edit_description_button_update"
+msgstr "Update Descriptions"
+
+#: views/developers/addon_edit_descriptions.thtml:115
+msgid "devcp_edit_description_correct_error"
+msgstr "Please correct the errors above indicated in red."
+
+#: views/developers/addon_edit_descriptions.thtml:51
+msgid "devcp_edit_descriptions_header"
+msgstr "Edit Add-on Descriptions"
+
+#: views/developers/addon_edit_descriptions.thtml:94
+msgid "devcp_edit_descriptions_transbox_comments_description"
+msgstr ""
+"Any information end users may want to know that isn't necessarily applicable "
+"to the add-on summary or description. Common uses include listing known "
+"major bugs, information on how to report bugs, anticipated release date of a "
+"new version, etc."
+
+#: views/developers/addon_edit_descriptions.thtml:93
+msgid "devcp_edit_descriptions_transbox_comments_name"
+msgstr "Developer Comments"
+
+#: views/developers/addon_edit_descriptions.thtml:86
+msgid "devcp_edit_descriptions_transbox_description_description"
+msgstr ""
+"The description of your add-on is a longer explanation of features, "
+"functionality, and other relevant information. It is displayed under the "
+"summary on the add-on's display page."
+
+#: views/developers/addon_edit_descriptions.thtml:85
+msgid "devcp_edit_descriptions_transbox_description_name"
+msgstr "Add-on Description"
+
+#: views/developers/addon_edit_descriptions.thtml:103
+msgid "devcp_edit_descriptions_transbox_eula_description"
+msgstr ""
+"If your add-on has an End-User License Agreement (EULA), please enter its "
+"text below. If set below, users will be required to agree to this before "
+"installing your add-on. Please note that a EULA is not the same as a code "
+"license such as GPL or MPL."
+
+#: views/developers/addon_edit_descriptions.thtml:102
+msgid "devcp_edit_descriptions_transbox_eula_name"
+msgstr "End-User License Agreement"
+
+#: views/developers/addon_edit_descriptions.thtml:112
+msgid "devcp_edit_descriptions_transbox_privacy_description"
+msgstr ""
+"If your add-on has a privacy policy, enter its text here. Your add-on's "
+"display page will display a link to the policy."
+
+#: views/developers/addon_edit_descriptions.thtml:111
+msgid "devcp_edit_descriptions_transbox_privacy_name"
+msgstr "Privacy Policy"
+
+#: views/developers/addon_edit_descriptions.thtml:78
+msgid "devcp_edit_descriptions_transbox_summary_description"
+msgstr ""
+"The summary is a short explanation of your add-on's basic functionality that "
+"is displayed in search and browse listings, as well as at the top of your "
+"add-on's display page. <strong>Limit of 250 characters.</strong>"
+
+#: views/developers/addon_edit_descriptions.thtml:77
+msgid "devcp_edit_descriptions_transbox_summary_name"
+msgstr "Add-on Summary"
+
+#: views/developers/addon_edit.thtml:46
+msgid "devcp_edit_dt_manage_authors"
+msgstr "Manage Add-on Authors"
+
+#: views/developers/addon_edit.thtml:48
+msgid "devcp_edit_dt_manage_categories"
+msgstr "Manage Add-on Categories"
+
+#: views/developers/addon_edit.thtml:50
+msgid "devcp_edit_dt_manage_descriptions"
+msgstr "Manage Add-on Descriptions"
+
+#: views/developers/addon_edit.thtml:52
+msgid "devcp_edit_dt_manage_properties"
+msgstr "Manage Add-on Properties"
+
+#: views/developers/addon_edit_properties.thtml:170
+msgid "devcp_edit_label_externalsoftware"
+msgstr "This add-on requires external software"
+
+#: views/developers/addon_edit_properties.thtml:205
+msgid "devcp_edit_label_locale_disambiguation"
+msgstr "Additional Locale Info"
+
+#: views/developers/addon_edit_properties.thtml:168
+msgid "devcp_edit_label_prerelease"
+msgstr "This is a pre-release"
+
+#: views/developers/addon_edit_properties.thtml:169
+msgid "devcp_edit_label_sitespecific"
+msgstr "This is a site-specific add-on"
+
+#: views/developers/addon_edit_properties.thtml:202
+msgid "devcp_edit_label_target_locale"
+msgstr "Target Locale"
+
+#: views/developers/addon_edit_properties.thtml:212
+msgid "devcp_edit_properties_button_update"
+msgstr "Update Properties"
+
+#: views/developers/addon_edit_properties.thtml:198
+msgid "devcp_edit_properties_change_guid"
+msgstr "Only change if you understand all of the consequences."
+
+#: views/developers/addon_edit_properties.thtml:109
+msgid "devcp_edit_properties_current_icon"
+msgstr "Current Icon"
+
+#: views/developers/addon_edit_properties.thtml:85
+msgid "devcp_edit_properties_default_locale"
+msgstr ""
+"An add-on's default locale is the main locale in which translations must be "
+"present. If translations for your add-on's descriptions are unavailable in a "
+"user's selected language, they will fall back to this default locale."
+
+#: views/developers/addon_edit_properties.thtml:167
+msgid "devcp_edit_properties_flags"
+msgstr "These flags are used to filter and classify add-ons."
+
+#: views/developers/addon_edit_properties.thtml:174
+msgid "devcp_edit_properties_guid"
+msgstr ""
+"The GUID of your add-on is specified in its install.rdf and uniquely "
+"identifies it. You cannot change your GUID once it is listed on Mozilla Add-"
+"ons."
+
+#: views/developers/addon_edit_properties.thtml:53
+msgid "devcp_edit_properties_header"
+msgstr "Edit Add-on Properties"
+
+#: views/developers/addon_edit_properties.thtml:186
+msgid "devcp_edit_properties_header_addon_type"
+msgstr "Add-on Type"
+
+#: views/developers/addon_edit_properties.thtml:181
+msgid "devcp_edit_properties_header_admin_settings"
+msgstr "Admin Settings"
+
+#: views/developers/addon_edit_properties.thtml:84
+msgid "devcp_edit_properties_header_default_locale"
+msgstr "Default Locale"
+
+#: views/developers/addon_edit_properties.thtml:166
+msgid "devcp_edit_properties_header_flags"
+msgstr "Add-on Flags"
+
+#: views/developers/addon_edit_properties.thtml:173
+#: views/developers/addon_edit_properties.thtml:197
+msgid "devcp_edit_properties_header_guid"
+msgstr "Add-on GUID"
+
+#: views/developers/addon_edit_properties.thtml:104
+msgid "devcp_edit_properties_header_icon"
+msgstr "Add-on Icon"
+
+#: views/developers/addon_edit_properties.thtml:159
+msgid "devcp_edit_properties_header_other_settings"
+msgstr "Other Settings"
+
+#. A header on the admin page to toggle trusted status.
+#: views/developers/addon_edit_properties.thtml:182
+msgid "devcp_edit_properties_header_trusted"
+msgstr "Trusted Add-on?"
+
+#: views/developers/addon_edit_properties.thtml:160
+msgid "devcp_edit_properties_header_view_source"
+msgstr "View Source Online"
+
+#. %s is a comma-separated list of image extensions ".png, .jpg"
+#: views/developers/addon_edit_properties.thtml:106
+msgid "devcp_edit_properties_icon"
+msgstr ""
+"The add-on icon is a small image that is displayed next to your add-on's "
+"name in browse and search results, display pages, and in the add-on "
+"installation dialog. The image will automatically be resized to 32 x 32 "
+"pixels. Please use one of the following image types: %s"
+
+#: views/developers/addon_edit_properties.thtml:171
+msgid "devcp_edit_properties_label_binary"
+msgstr "This add-on contains binary components"
+
+#: views/developers/addon_edit_properties.thtml:185
+msgid "devcp_edit_properties_label_not_trusted"
+msgstr "Not Trusted"
+
+#: views/developers/addon_edit_properties.thtml:184
+msgid "devcp_edit_properties_label_trusted"
+msgstr "Trusted"
+
+#: views/developers/addon_edit_properties.thtml:110
+msgid "devcp_edit_properties_new_icon"
+msgstr "New Icon"
+
+#: views/developers/addon_edit_properties.thtml:118
+msgid "devcp_edit_properties_remove_icon"
+msgstr "Remove Icon"
+
+#: views/developers/addon_edit_properties.thtml:136
+msgid "devcp_edit_properties_transbox_homepage_description"
+msgstr ""
+"If your add-on has another homepage, enter its address here. Adding other "
+"translations is not necessary unless your website is localized into other "
+"languages."
+
+#: views/developers/addon_edit_properties.thtml:135
+msgid "devcp_edit_properties_transbox_homepage_name"
+msgstr "Add-on Homepage"
+
+#: views/developers/addon_edit_properties.thtml:79
+msgid "devcp_edit_properties_transbox_name_description"
+msgstr "The name of your add-on is displayed everywhere your add-on is listed."
+
+#: views/developers/addon_edit_properties.thtml:78
+msgid "devcp_edit_properties_transbox_name_name"
+msgstr "Add-on Name"
+
+#: views/developers/addon_edit_properties.thtml:145
+msgid "devcp_edit_properties_transbox_supportemail_description"
+msgstr ""
+"If you have an email address for support inquiries, enter it here. Adding "
+"other translations is not necessary unless you have different email "
+"addresses for different languages."
+
+#: views/developers/addon_edit_properties.thtml:144
+msgid "devcp_edit_properties_transbox_supportemail_name"
+msgstr "Support Email Address"
+
+#: views/developers/addon_edit_properties.thtml:154
+msgid "devcp_edit_properties_transbox_supporturl_description"
+msgstr ""
+"If your add-on has a support website or forum, enter its address here. "
+"Adding other translations is not necessary unless your website is localized "
+"into other languages."
+
+#: views/developers/addon_edit_properties.thtml:153
+msgid "devcp_edit_properties_transbox_supporturl_name"
+msgstr "Support Website"
+
+#: views/developers/addon_edit_properties.thtml:183
+msgid "devcp_edit_properties_trusted"
+msgstr "Trusted add-ons can become public without Editor review."
+
+#. %s is href="..." and should stay in the <a> tag.
+#: views/developers/addon_edit_properties.thtml:119
+msgid "devcp_edit_properties_undelete"
+msgstr "Icon will be deleted on save. <a %s>Cancel?</a>"
+
+#: views/developers/addon_edit_properties.thtml:161
+msgid "devcp_edit_properties_view_source"
+msgstr ""
+"The source of your add-on files can be viewed online by any logged in user "
+"if you wish."
+
+#: views/developers/addon_edit_properties.thtml:162
+msgid "devcp_edit_properties_view_source_allow"
+msgstr "Allow online source viewing"
+
+#: views/developers/addon_edit_properties.thtml:163
+msgid "devcp_edit_properties_view_source_do_not_allow"
+msgstr "Do not allow online source viewing"
+
+#: views/elements/developers/editbox.thtml:46
+msgid "devcp_editbox_authors"
+msgstr "Authors"
+
+#: views/elements/developers/editbox.thtml:47
+msgid "devcp_editbox_categories"
+msgstr "Categories"
+
+#: views/elements/developers/editbox.thtml:52
+msgid "devcp_editbox_change_status"
+msgstr "Change Status"
+
+#: views/elements/developers/editbox.thtml:48
+msgid "devcp_editbox_descriptions"
+msgstr "Descriptions"
+
+#: views/elements/developers/editbox.thtml:43
+msgid "devcp_editbox_edit_addon"
+msgstr "Edit Add-on"
+
+#: views/elements/developers/editbox.thtml:57
+msgid "devcp_editbox_new_version"
+msgstr "New Version"
+
+#: views/elements/developers/editbox.thtml:49
+msgid "devcp_editbox_properties"
+msgstr "Properties"
+
+#: views/elements/developers/editbox.thtml:60
+msgid "devcp_editbox_screenshots"
+msgstr "Preview Screenshots"
+
+#: views/elements/developers/editbox.thtml:53
+msgid "devcp_editbox_statistics_dashboard"
+msgstr "Statistics Dashboard"
+
+#: views/elements/developers/editbox.thtml:54
+msgid "devcp_editbox_versions"
+msgstr "Versions and Files"
+
+#: views/elements/developers/editbox.thtml:42
+msgid "devcp_editbox_view_listing"
+msgstr "View Listing"
+
+#: views/elements/developers/editorsmenu.thtml:59
+msgid "devcp_editorsqueue_featured"
+msgstr "Featured Add-ons"
+
+#. %1 is the review count
+#: views/elements/developers/editorsqueue.thtml:42
+#: views/elements/developers/editorsmenu.thtml:56
+#, php-format
+msgid "devcp_editorsqueue_moderatedreviews"
+msgid_plural "devcp_editorsqueue_moderatedreviews"
+msgstr[0] "Moderated Reviews (%s)"
+msgstr[1] "Moderated Reviews (%s)"
+
+#. %1 is the nominated addons count
+#: views/elements/developers/editorsqueue.thtml:44
+#: views/elements/developers/editorsmenu.thtml:58
+#, php-format
+msgid "devcp_editorsqueue_nominated"
+msgid_plural "devcp_editorsqueue_nominated"
+msgstr[0] "Nominated Add-ons (%s)"
+msgstr[1] "Nominated Add-ons (%s)"
+
+#. %1 is the update count
+#: views/elements/developers/editorsqueue.thtml:43
+#: views/elements/developers/editorsmenu.thtml:57
+#, php-format
+msgid "devcp_editorsqueue_pendingupdates"
+msgid_plural "devcp_editorsqueue_pendingupdates"
+msgstr[0] "Pending Updates (%s)"
+msgstr[1] "Pending Updates (%s)"
+
+#: controllers/statistics_controller.php:147
+#: controllers/statistics_controller.php:361
+#: controllers/previews_controller.php:108
+#: controllers/previews_controller.php:211
+#: controllers/previews_controller.php:312
+msgid "devcp_error_addon_access_denied"
+msgstr "You do not have access to that add-on."
+
+#. %s is a complete URL with the text from devcp_error_appversion_reference_link_text
+#. in the <a> tag. This should be fixed.
+#: controllers/components/developers.php:591
+#, php-format
+msgid "devcp_error_appversion_reference_link"
+msgstr "Please see %s for reference."
+
+#. This is the link text in the <a> for devcp_error_appversion_reference_link. This
+#. should be fixed.
+#: controllers/components/developers.php:591
+msgid "devcp_error_appversion_reference_link_text"
+msgstr "this page"
+
+#: views/developers/addon_edit_authors.thtml:76
+msgid "devcp_error_empty_authors"
+msgstr "Your add-on must have at least one owner."
+
+#. %1$s is the name of the file
+#: controllers/components/developers.php:658
+msgid "devcp_error_file_exists"
+msgstr ""
+"A version of that add-on already exists. To replace it, you must delete the "
+"file %1$s first."
+
+#. %1$s is a file extension. Example: .exe
+#. %2$s is a comma separated list of extensions. Example: .xpi, .jar
+#: controllers/components/developers.php:355
+#, php-format
+msgid "devcp_error_file_extension"
+msgstr ""
+"That file extension (%1$s) is not allowed for the selected add-on type. "
+"Please use one of the following: %2$s"
+
+#: controllers/components/developers.php:64
+msgid "devcp_error_five_categories"
+msgstr "Please select no more than five categories."
+
+#: controllers/components/developers.php:526
+msgid "devcp_error_guid_application"
+msgstr "The ID of this add-on is already used by an application."
+
+#: controllers/components/developers.php:337
+#: controllers/components/developers.php:389
+msgid "devcp_error_http_incomplete"
+msgstr "Incomplete transfer"
+
+#: controllers/components/developers.php:335
+#: controllers/components/developers.php:336
+#: controllers/components/developers.php:387
+#: controllers/components/developers.php:388
+msgid "devcp_error_http_maxupload"
+msgstr "Exceeds maximum upload size"
+
+#: controllers/components/developers.php:338
+#: controllers/components/developers.php:390
+msgid "devcp_error_http_nofile"
+msgstr "No file uploaded"
+
+#. %1$s is a file extension. Example: .exe
+#. %2$s is a comma separated list of extensions. Example: .xpi, .jar
+#: controllers/components/developers.php:401
+#, php-format
+msgid "devcp_error_icon_extension"
+msgstr ""
+"That file extension (%1$s) is not allowed for an icon. Please use one of the "
+"following: %2$s"
+
+#: controllers/developers_controller.php:504
+msgid "devcp_error_index_rdf_notfound"
+msgstr "No install.rdf present."
+
+#: controllers/components/developers.php:601
+msgid "devcp_error_install_manifest"
+msgstr "The following errors were found in install.rdf:"
+
+#: controllers/developers_controller.php:1463
+msgid "devcp_error_invalid_addontype"
+msgstr ""
+
+#. %$1s is a version. Example: 3.1.1
+#. %$2s is an add-on name.
+#: controllers/components/developers.php:569
+#: controllers/components/developers.php:581
+#, php-format
+msgid "devcp_error_invalid_appversion"
+msgstr "%1$s is not a valid version for %2$s"
+
+#. %s is a string
+#: controllers/components/developers.php:521
+#, php-format
+msgid "devcp_error_invalid_guid"
+msgstr "The ID of this add-on is invalid: %s"
+
+#. %$1s is a version. Example: 3.1.1
+#. %$2s is an add-on name.
+#: controllers/components/developers.php:572
+#, php-format
+msgid "devcp_error_invalid_minversion"
+msgstr ""
+"%1$s is not a valid version for %2$s: minimum versions cannot contain *"
+
+#: controllers/components/developers.php:536
+msgid "devcp_error_invalid_version"
+msgstr ""
+"The version of this add-on is invalid: please see the <a href=\"http://"
+"developer.mozilla.org/en/docs/Toolkit_version_format\">specification</a>"
+
+#: controllers/components/developers.php:531
+msgid "devcp_error_invalid_version_spaces"
+msgstr "The version of this add-on is invalid: versions cannot contain spaces."
+
+#. %s is an error message from the parser.
+#: controllers/components/developers.php:501
+#, php-format
+msgid "devcp_error_manifest_parse"
+msgstr "The following error occurred while parsing install.rdf: %s"
+
+#: controllers/components/developers.php:373
+msgid "devcp_error_move_file"
+msgstr "Could not move file"
+
+#. %s is the name of a file
+#: controllers/components/developers.php:650
+#: controllers/components/developers.php:662
+#: controllers/components/developers.php:667
+#: controllers/components/developers.php:727
+#: controllers/components/developers.php:738
+#: controllers/components/developers.php:743
+#, php-format
+msgid "devcp_error_moving_file"
+msgstr "An error occurred moving %s."
+
+#: controllers/components/developers.php:595
+msgid "devcp_error_mozilla_application"
+msgstr "You must have at least one valid Mozilla target application."
+
+#: controllers/components/developers.php:516
+msgid "devcp_error_no_guid"
+msgstr "No ID could be found for this add-on in install.rdf."
+
+#: controllers/components/developers.php:287
+msgid "devcp_error_no_platform"
+msgstr "No platform selected"
+
+#: controllers/components/developers.php:59
+msgid "devcp_error_one_category"
+msgstr "Please select at least one category."
+
+#: controllers/components/developers.php:92
+msgid "devcp_error_one_user"
+msgstr "There must be at least one author for this add-on."
+
+#. %1$s is a file extension. Example: .exe
+#. %2$s is a comma separated list of extensions. Example: .xpi, .jar
+#: controllers/components/developers.php:1081
+#, php-format
+msgid "devcp_error_preview_extension"
+msgstr ""
+"That file extension (%1$s) is not allowed for a preview. Please use one of "
+"the following: %2$s"
+
+#: controllers/components/developers.php:511
+msgid "devcp_error_updatekey"
+msgstr ""
+"Add-ons cannot use an updateKey. Please remove this from install.rdf and try "
+"again."
+
+#: controllers/components/developers.php:506
+msgid "devcp_error_updateurl"
+msgstr ""
+"Add-ons cannot use an external updateURL. Please remove this from install."
+"rdf and try again."
+
+#: controllers/developers_controller.php:465
+#: controllers/components/developers.php:271
+msgid "devcp_error_upload_file"
+msgstr "Please upload a file."
+
+#: views/developers/uploader.thtml:135
+msgid "devcp_input_upload_file"
+msgstr "Upload File"
+
+#: views/pages/js_constants.js.thtml:89
+msgid "devcp_js_a_cancel"
+msgstr "Cancel"
+
+#: views/pages/js_constants.js.thtml:90
+msgid "devcp_js_add_email"
+msgstr "Please enter the account email of the author you wish to add."
+
+#. alt text for a down-arrow image.
+#: views/pages/js_constants.js.thtml:81
+msgid "devcp_js_img_move_down"
+msgstr "Move Down"
+
+#. alt text for an up-arrow image.
+#: views/pages/js_constants.js.thtml:82
+msgid "devcp_js_img_move_up"
+msgstr "Move Up"
+
+#: views/pages/js_constants.js.thtml:91
+msgid "devcp_js_img_remove_compat"
+msgstr "Remove Application Compatibility"
+
+#: views/pages/js_constants.js.thtml:86
+msgid "devcp_js_input_list_author"
+msgstr "List as author in public listings"
+
+#: views/pages/js_constants.js.thtml:92
+msgid "devcp_js_license_select"
+msgstr "Please select a license."
+
+#: views/pages/js_constants.js.thtml:93
+msgid "devcp_js_license_text"
+msgstr "Please enter text for your license."
+
+#. <option> text in a <select> for Author role in an add-on.
+#: views/pages/js_constants.js.thtml:84
+msgid "devcp_js_option_developer"
+msgstr "Developer"
+
+#. <option> text in a <select> for Author role in an add-on.
+#: views/pages/js_constants.js.thtml:83
+msgid "devcp_js_option_owner"
+msgstr "Owner"
+
+#. <option> text in a <select> for Author role in an add-on.
+#: views/pages/js_constants.js.thtml:85
+msgid "devcp_js_option_viewer"
+msgstr "Viewer"
+
+#: views/pages/js_constants.js.thtml:88
+msgid "devcp_js_remove_author"
+msgstr "Remove Author"
+
+#: views/pages/js_constants.js.thtml:87
+msgid "devcp_js_sure_remove"
+msgstr "Are you <strong>sure</strong> you wish to remove this author?"
+
+#: views/pages/js_constants.js.thtml:77
+msgid "devcp_js_upload_alert"
+msgstr "You must select a file to upload."
+
+#. %1$s is an addon id, like 32.
+#. %2$s is a version number, like 3.5.
+#: controllers/components/developers.php:1212
+msgid "devcp_license_existing"
+msgstr "Custom license for add-on %1$s v%2$s"
+
+#: views/elements/developers/localebox.thtml:44
+msgid "devcp_localebox_header_localizedfields"
+msgstr "Localized Fields"
+
+#. %1 is the default locale
+#: views/elements/developers/localebox.thtml:48
+#, php-format
+msgid "devcp_localebox_intro"
+msgstr ""
+"Some of the fields on this page are localized to appear in the end-user's "
+"native language. Select a locale below to edit your add-on's details in that "
+"language. If a translation for a locale is not available, it will fall back "
+"to the selected default locale (%s)."
+
+#: views/elements/developers/sidebar.thtml:68
+#: views/elements/developers/myaddons.thtml:75
+msgid "devcp_myaddons_admincp_link"
+msgstr "Admin Tools"
+
+#: views/elements/developers/sidebar.thtml:65
+#: views/elements/developers/myaddons.thtml:72
+msgid "devcp_myaddons_editorcp_link"
+msgstr "Editor Tools"
+
+#: views/elements/developers/myaddons.thtml:52
+msgid "devcp_myaddons_link"
+msgstr "My Add-ons"
+
+#: views/elements/developers/sidebar.thtml:70
+#: views/elements/developers/myaddons.thtml:77
+msgid "devcp_myaddons_mainpage_link"
+msgstr "Back to Main"
+
+#: views/elements/developers/sidebar.thtml:63
+#: views/elements/developers/myaddons.thtml:70
+msgid "devcp_myaddons_statistics_link"
+msgstr "Statistics Dashboard"
+
+#: views/elements/developers/sidebar.thtml:62
+#: views/elements/developers/myaddons.thtml:69
+msgid "devcp_myaddons_submitaddon_link"
+msgstr "Submit Add-on"
+
+#: views/elements/developers/sidebar.thtml:48
+#: views/elements/developers/myaddons.thtml:67
+msgid "devcp_myaddons_title"
+msgstr "Developer Tools"
+
+#. %1$s is an add-on ID, perhaps 167.
+#. %2$s is a URL.
+#: controllers/developers_controller.php:256
+msgid "devcp_new_addon_error"
+msgstr ""
+"This add-on ID (%1$s) already exists in the database. If this is your add-"
+"on, you can <a href=\"%2$s\">upload a new version</a>."
+
+#: views/developers/addon_status_nominate.thtml:62
+msgid "devcp_nominate_cancel"
+msgstr "Cancel and return"
+
+#. %1 is the add-on name
+#: views/developers/addon_status_nominate.thtml:61
+#, php-format
+msgid "devcp_nominate_submit_nominate"
+msgstr "Nominate %s"
+
+#: views/developers/addon_edit_properties.thtml:50
+#: views/developers/addon_status.thtml:49
+#: views/developers/versions_edit.thtml:50
+msgid "devcp_notice_changes_error"
+msgstr ""
+"<span>One or more of your changes couldn't be saved.</span><br />Please look "
+"for the errors below. The rest of your changes were successfully saved."
+
+#: views/developers/addon_edit_authors.thtml:47
+#: views/developers/addon_edit_properties.thtml:47
+#: views/developers/addon_status.thtml:46
+#: views/developers/addon_edit_descriptions.thtml:47
+#: views/developers/versions_edit.thtml:47
+#: views/developers/addon_edit_categories.thtml:46
+msgid "devcp_notice_changes_saved"
+msgstr ""
+"<span>Your changes have been saved.</span><br />Please note that some "
+"changes may take several hours to appear in all areas of the website."
+
+#: controllers/previews_controller.php:252
+msgid "devcp_notice_cleardefault"
+msgstr ""
+"Removing this as the default preview will cause another preview to "
+"automatically become the default preview."
+
+#: controllers/previews_controller.php:184
+#: controllers/previews_controller.php:251
+msgid "devcp_notice_makedefault"
+msgstr ""
+"Making this the default preview will remove default status from the current "
+"default preview."
+
+#: views/developers/addon_edit_authors.thtml:70
+msgid "devcp_notice_unsaved_changes"
+msgstr "You have unsaved changes."
+
+#: controllers/developers_controller.php:87
+#: controllers/developers_controller.php:97
+#: controllers/developers_controller.php:100
+#: controllers/previews_controller.php:67
+#: controllers/previews_controller.php:79
+#: controllers/previews_controller.php:82
+msgid "devcp_pagetitle"
+msgstr "Developer Tools"
+
+#: controllers/previews_controller.php:103
+#: controllers/previews_controller.php:104
+msgid "devcp_preview_add_pagetitle"
+msgstr "Add Preview"
+
+#: controllers/previews_controller.php:135
+msgid "devcp_preview_added_successfully"
+msgstr "Preview added successfully."
+
+#: controllers/previews_controller.php:323
+msgid "devcp_preview_deleted_successfully"
+msgstr "Preview deleted successfully."
+
+#: controllers/previews_controller.php:194
+#: controllers/previews_controller.php:195
+msgid "devcp_preview_edit_pagetitle"
+msgstr "Edit Preview"
+
+#: controllers/previews_controller.php:237
+msgid "devcp_preview_updated_successfully"
+msgstr "Preview updated successfully."
+
+#: views/developers/previews.thtml:120
+msgid "devcp_previews_a_another"
+msgstr "Add Another Preview"
+
+#: views/developers/previews.thtml:96
+msgid "devcp_previews_a_delete"
+msgstr "Delete Preview"
+
+#: views/developers/previews.thtml:95
+msgid "devcp_previews_a_replace"
+msgstr "Replace Preview"
+
+#: views/developers/previews.thtml:126
+msgid "devcp_previews_a_update"
+msgstr "Update Previews"
+
+#: views/developers/previews.thtml:115 views/developers/previews.thtml:124
+msgid "devcp_previews_add_new"
+msgstr "Add New Preview"
+
+#. %s is a list of file extensions, e.g. ".png, .gif"
+#: views/developers/previews.thtml:116
+msgid "devcp_previews_add_select"
+msgstr ""
+"Select an image to upload below. Images larger than the maximum size of 700 "
+"pixels wide by 525 pixels tall will be resized. Allowed file types: %s"
+
+#: views/developers/previews.thtml:121
+msgid "devcp_previews_click_below"
+msgstr "Click Update Previews below to upload."
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/previews.thtml:102
+msgid "devcp_previews_click_update"
+msgstr ""
+"Click the Update Previews button below to save this image. (<a %s>Cancel?</"
+"a>)"
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/previews.thtml:107
+msgid "devcp_previews_error_message"
+msgstr ""
+"This preview will be deleted when Update Previews is clicked below. (<a %"
+"s>Cancel?</a>)"
+
+#: views/previews/add.thtml:45
+msgid "devcp_previews_filetype_info"
+msgstr ""
+"Use the form below to upload a PNG, JPG, or GIF screenshot of your add-on. "
+"Images larger than 700 pixels wide and 525 pixels high will automatically be "
+"resized."
+
+#: views/previews/add.thtml:43
+msgid "devcp_previews_header_add"
+msgstr "Add Preview"
+
+#: views/developers/previews.thtml:80
+msgid "devcp_previews_header_caption"
+msgstr "Preview Caption"
+
+#: views/previews/edit.thtml:43
+msgid "devcp_previews_header_edit"
+msgstr "Edit Preview"
+
+#: views/developers/previews.thtml:93
+msgid "devcp_previews_label_default"
+msgstr "Default Preview"
+
+#: views/previews/add.thtml:54
+msgid "devcp_previews_label_file"
+msgstr "Preview File"
+
+#: views/previews/add.thtml:59 views/previews/edit.thtml:50
+msgid "devcp_previews_label_makedefault"
+msgstr "Make this the default preview image"
+
+#: views/developers/previews.thtml:100
+msgid "devcp_previews_label_new"
+msgstr "New image:"
+
+#: views/developers/previews.thtml:118
+msgid "devcp_previews_label_upload"
+msgstr "Upload Preview: "
+
+#: views/developers/previews.thtml:50
+msgid "devcp_previews_notice_error"
+msgstr "One or more of your new previews could not be saved."
+
+#: views/developers/previews.thtml:47
+msgid "devcp_previews_notice_success"
+msgstr "Your previews have been updated successfully."
+
+#: views/developers/previews.thtml:59
+msgid "devcp_previews_p_screenshots"
+msgstr ""
+"The preview screenshots for your add-on are shown below. You can make "
+"changes to captions or images below. The Default Preview is the preview that "
+"is displayed next to your add-on in search and browse listings."
+
+#: views/previews/edit.thtml:55
+msgid "devcp_previews_submit_delete"
+msgstr "Delete Preview"
+
+#: views/previews/edit.thtml:55
+msgid "devcp_previews_submit_delete_confirm"
+msgstr "Are you sure you wish to delete this preview?"
+
+#: views/previews/edit.thtml:54
+msgid "devcp_previews_submit_edit"
+msgstr "Edit Preview"
+
+#: views/previews/add.thtml:63
+msgid "devcp_previews_submit_upload"
+msgstr "Upload Preview"
+
+#: views/developers/previews.thtml:78
+msgid "devcp_previews_thumbnail"
+msgstr "Thumbnail"
+
+#. %s is the add-on name.
+#: views/developers/previews.thtml:44
+msgid "devcp_previews_title"
+msgstr "%s Preview Manager"
+
+#: views/developers/uploader.thtml:74
+msgid "devcp_review_agreement_please"
+msgstr ""
+"Please review and accept the following Developer Agreement before proceeding."
+
+#: views/elements/developers/rolecheck.thtml:42
+msgid "devcp_rolecheck_no_privs"
+msgstr ""
+"<span>You do not have sufficient privileges to make changes on this page.</"
+"span><br />Contact the Add-on Owner if you need to make changes."
+
+#: controllers/developers_controller.php:1315
+msgid "devcp_several_hours"
+msgstr ""
+"Please note that some changes may take several hours to appear in all areas "
+"of the website."
+
+#: views/elements/developers/sidebar.thtml:52
+msgid "devcp_sidebar_a_dashboard"
+msgstr "Dashboard"
+
+#. %s is a number
+#: views/elements/developers/statsbar.thtml:45
+#: views/developers/dashboard.thtml:79
+#, php-format
+msgid "devcp_statsbar_adu"
+msgstr "<em>%s</em> Active Daily Users"
+
+#. %s is a number
+#: views/elements/developers/statsbar.thtml:41
+#: views/developers/dashboard.thtml:75
+#, php-format
+msgid "devcp_statsbar_total_downloads"
+msgstr "<em>%s</em> Total Downloads"
+
+#. %s is a number
+#: views/elements/developers/statsbar.thtml:43
+#: views/developers/dashboard.thtml:77
+#, php-format
+msgid "devcp_statsbar_weekly_downloads"
+msgstr "<em>%s</em> Weekly Downloads"
+
+#: views/developers/addon_status_confirm.thtml:59
+msgid "devcp_status_confirm_active"
+msgstr ""
+"Marking this add-on active will cause it to show up in public areas "
+"appropriate for its status, including search and browse listings. It will be "
+"downloadable from the website and could be returned in client update checks, "
+"depending on its status. You will be able to return here and disable it "
+"again at your convenience."
+
+#: views/developers/addon_status_confirm.thtml:59
+msgid "devcp_status_confirm_active_sure"
+msgstr "Are you sure you wish to mark this add-on active?"
+
+#: views/developers/addon_status_confirm.thtml:50
+msgid "devcp_status_confirm_header_sure"
+msgstr "Are you sure?"
+
+#: views/developers/addon_status_confirm.thtml:55
+msgid "devcp_status_confirm_inactive"
+msgstr ""
+"Marking this add-on inactive will prevent it from showing up in any public "
+"areas, including search and browse listings. It will not be downloadable "
+"from the website and will not be returned in client update checks. You will "
+"be able to return here and re-enable it at your convenience."
+
+#: views/developers/addon_status_confirm.thtml:55
+msgid "devcp_status_confirm_inactive_sure"
+msgstr "Are you sure you wish to mark this add-on inactive?"
+
+#: views/developers/addon_status_confirm.thtml:74
+msgid "devcp_status_confirm_no"
+msgstr "No, cancel"
+
+#: views/developers/addon_status_confirm.thtml:67
+msgid "devcp_status_confirm_public"
+msgstr ""
+"Making this add-on public will make it available for anyone to download and "
+"will begin offering updates to existing users."
+
+#: views/developers/addon_status_confirm.thtml:67
+msgid "devcp_status_confirm_public_sure"
+msgstr "Are you sure you wish to make this add-on public?"
+
+#: views/developers/addon_status_confirm.thtml:63
+msgid "devcp_status_confirm_sandbox"
+msgstr ""
+"Moving this add-on back to the sandbox will require users to log in before "
+"downloading and updates will no longer be offered to existing users. Because "
+"your add-on is currently public, you will be able to return here at any time "
+"to make it public again."
+
+#: views/developers/addon_status_confirm.thtml:63
+msgid "devcp_status_confirm_sandbox_sure"
+msgstr "Are you sure you wish to move this add-on to the sandbox?"
+
+#: views/developers/addon_status_confirm.thtml:73
+msgid "devcp_status_confirm_yes"
+msgstr "Yes, I'm Sure"
+
+#: views/developers/addon_status_nominate.thtml:46
+msgid "devcp_status_nominate_error_notice"
+msgstr ""
+"<span>A nomination message is required.</span><br />Please fill in the text "
+"box with the requested information and try again."
+
+#: views/developers/addon_status_nominate.thtml:55
+msgid "devcp_status_nominate_header"
+msgstr "Add-on Nomination"
+
+#: views/developers/dashboard.thtml:85
+msgid "devcp_summary_lastversion"
+msgstr "Latest Version:"
+
+#. %s is the add-on name.
+#: views/developers/addon_edit.thtml:43
+#: views/developers/addon_edit_authors.thtml:44
+#: views/developers/versions_delete.thtml:43
+#: views/developers/addon_edit_properties.thtml:44
+#: views/developers/addon_edit_descriptions.thtml:44
+#: views/developers/versions_edit.thtml:44
+#: views/developers/addon_edit_categories.thtml:43
+#: views/developers/versions.thtml:43
+msgid "devcp_title_edit_addon"
+msgstr "Edit %s"
+
+#. title attribute for a javascript link that pops up a help dialog.
+#: views/elements/translationbox.thtml:68
+msgid "devcp_transbox_a_title_help"
+msgstr "Help (does not leave page)"
+
+#: views/elements/translationbox.thtml:68
+msgid "devcp_transbox_alt_help"
+msgstr "Help"
+
+#. %1$s is <span>17</span>, %2$s is 42.
+#: views/elements/translationbox.thtml:101
+msgid "devcp_transbox_chars_used"
+msgstr "Characters used: %1$s / %2$s"
+
+#: views/elements/translationbox.thtml:132
+msgid "devcp_transbox_delete_sure"
+msgstr "Are you sure you wish to delete this translation?"
+
+#. %s is a locale, like en-US.
+#: views/elements/translationbox.thtml:143
+msgid "devcp_transbox_help_header_tabs"
+msgstr "What are these %s tabs?"
+
+#: views/elements/translationbox.thtml:145
+msgid "devcp_transbox_help_header_what"
+msgstr "What if I don't have any translations?"
+
+#: views/elements/translationbox.thtml:147
+msgid "devcp_transbox_help_hide"
+msgstr "Hide Help"
+
+#: views/elements/translationbox.thtml:146
+msgid "devcp_transbox_help_if"
+msgstr ""
+"If a user browses the site and a translation isn't available in their own "
+"language, it will fall back to your add-on's Default Locale, specified in "
+"the Edit Add-on Properties area. If you don't have any translations, just "
+"enter what you can into your Default Locale, which should be a language you "
+"speak."
+
+#: views/elements/translationbox.thtml:144
+msgid "devcp_transbox_help_transbox"
+msgstr ""
+"This is a <i>Translation Box</i>. It allows you to localize a specific field "
+"into any other languages for which you might have a translation. You can "
+"add, edit, and remove translations using the locale tabs."
+
+#: views/elements/translationbox.thtml:85
+msgid "devcp_transbox_img_add_trans"
+msgstr "Add Translation"
+
+#: views/elements/translationbox.thtml:86
+msgid "devcp_transbox_img_remove_trans"
+msgstr "Remove Translation"
+
+#: views/elements/translationbox.thtml:123
+msgid "devcp_transbox_input_add_all"
+msgstr "Add Locale to All"
+
+#: views/elements/translationbox.thtml:122
+msgid "devcp_transbox_input_add_locale"
+msgstr "Add Locale"
+
+#: views/elements/translationbox.thtml:124
+#: views/elements/translationbox.thtml:135
+msgid "devcp_transbox_input_cancel"
+msgstr "Cancel"
+
+#: views/elements/translationbox.thtml:134
+msgid "devcp_transbox_input_delete"
+msgstr "Delete It"
+
+#: views/elements/translationbox.thtml:113
+msgid "devcp_transbox_select_locale"
+msgstr "Select the locale of the translation to add:"
+
+#. %1$s and %2$s are GUIDs.
+#: controllers/developers_controller.php:343
+msgid "devcp_update_addon_guid_error"
+msgstr ""
+"The add-on GUID used in this file (%1$s) does not match the existing GUID "
+"for this add-on (%2$s)."
+
+#: controllers/developers_controller.php:334
+msgid "devcp_update_addon_priv_error"
+msgstr "You do not have sufficient privileges to update this add-on."
+
+#. %1$s is a version number, %2$s is an add-on ID.
+#: controllers/developers_controller.php:399
+msgid "devcp_update_addon_version_belong_error"
+msgstr "The specified version (%1$s) does not belong to this add-on (%2$s)."
+
+#. %1$s is a version number, maybe 1.1.
+#. %2$s is a URL.
+#: controllers/developers_controller.php:351
+msgid "devcp_update_addon_version_exists_error"
+msgstr ""
+"The version number uploaded (%1$s) already exists for this add-on. If you "
+"are trying to add another file to this version, <a href=\"%2$s\">click here</"
+"a>."
+
+#. %1$s and %2$s are version numbers.
+#: controllers/developers_controller.php:405
+msgid "devcp_update_addon_version_match_error"
+msgstr ""
+"The uploaded version number (%1$s) does not match the existing version "
+"number (%2$s)."
+
+#: views/developers/uploader.thtml:68
+msgid "devcp_uploader_a_start"
+msgstr "Get Started"
+
+#: views/developers/uploader.thtml:137
+msgid "devcp_uploader_ajax_loading"
+msgstr "Uploading file..."
+
+#: views/developers/uploader.thtml:82
+msgid "devcp_uploader_button_agree"
+msgstr "Agree and continue"
+
+#: views/developers/uploader.thtml:157
+msgid "devcp_uploader_button_edit"
+msgstr "Edit My Add-on"
+
+#: views/developers/uploader.thtml:158
+msgid "devcp_uploader_button_later"
+msgstr "I'll complete my add-on later."
+
+#: views/developers/uploader.thtml:168
+msgid "devcp_uploader_button_release"
+msgstr "Add Release Notes"
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/uploader.thtml:156
+msgid "devcp_uploader_created_results"
+msgstr ""
+"<p>Your add-on listing has been successfully created. The basic information "
+"obtained from your uploaded file has been stored, but there's a lot more to "
+"your listing that can be customized.</p><p>Your add-on is currently marked "
+"as <strong>Incomplete</strong>. In order to complete your add-on, you'll "
+"need to make sure it has an accurate name, summary, and description, as well "
+"as at least one selected category. You can edit your add-on's information "
+"using the link below and check the status of your add-on at any time on the "
+"<a %s>status page</a>."
+
+#: views/developers/uploader.thtml:143
+msgid "devcp_uploader_error_correct"
+msgstr "Please correct this problem and upload your file again."
+
+#. %1$s is a version number, %2$s is a status, e.g Public or Incomplete.
+#: views/developers/uploader.thtml:175
+msgid "devcp_uploader_file_created"
+msgstr ""
+"Your new file has been added to version %1$s and is currently marked as %2$s."
+
+#: views/developers/uploader.thtml:154
+msgid "devcp_uploader_header_created"
+msgstr "Add-on Created!"
+
+#: views/developers/uploader.thtml:141
+msgid "devcp_uploader_header_error"
+msgstr "Oops! There seems to be a problem with this file..."
+
+#: views/developers/uploader.thtml:173
+msgid "devcp_uploader_header_file_added"
+msgstr "File Added!"
+
+#: views/developers/uploader.thtml:66
+msgid "devcp_uploader_header_how"
+msgstr "How does it all work?"
+
+#. %s is the version number, e.g. 3.2.
+#: views/developers/uploader.thtml:163
+msgid "devcp_uploader_header_update_created"
+msgstr "Version %s Created"
+
+#: views/developers/uploader.thtml:117
+msgid "devcp_uploader_header_upload"
+msgstr "Upload Your File"
+
+#: views/developers/uploader.thtml:67
+msgid "devcp_uploader_how"
+msgstr ""
+"<p>Thanks for your interest in submitting your add-on to Mozilla Add-ons. "
+"Hosting your add-on on Mozilla Add-ons is the easiest way to handle "
+"distribution of your add-on. Here's what you'll get:</p><ul><li>Each add-on "
+"will have a public display page with information you provide, such as a "
+"brief summary of the add-on's functionality, an optional longer description, "
+"and a showcase of preview screenshots of your add-on.</li><li>Your add-on "
+"will appear in search and browse listings across the site, and even in the "
+"Add-ons Manager of Firefox 3.</li><li>We'll take care of hosting all of your "
+"downloads and providing automatic updates to users when you upload a new "
+"version.</li><li>You'll have access to a statistics dashboard with detailed "
+"information about your user base.</li></ul><p>Add-ons hosted on the site "
+"must be reviewed by a Mozilla Add-ons Editor before they will have all of "
+"the features listed above. If you're ready to start the process and have "
+"your add-on package ready for upload, just click on Get Started below!</p>"
+
+#: views/developers/uploader.thtml:125
+msgid "devcp_uploader_label_platformtype"
+msgstr "Supported Platforms:"
+
+#: views/developers/uploader.thtml:124
+msgid "devcp_uploader_label_upload_field"
+msgstr "Add-on File: "
+
+#: controllers/components/developers.php:1221
+msgid "devcp_uploader_option_other"
+msgstr "Other"
+
+#. %1$s is a number, %2$s is href="..." and should stay in the <a> tag.
+#: views/developers/uploader.thtml:176
+msgid "devcp_uploader_p_pending_file"
+msgstr ""
+"The new file will be available to the public as soon as an editor is able to "
+"review it. There are currently %1$s other add-ons in the queue. Want to be "
+"reviewed faster? Consider <a %2$s>becoming an editor</a>."
+
+#. %1$s is a number, %2$s is href="..." and should stay in the <a> tag.
+#: views/developers/uploader.thtml:166
+msgid "devcp_uploader_p_pending_version"
+msgstr ""
+"The new version will be available to the public as soon as an editor is able "
+"to review it. There are currently %1$s other add-ons in the queue. Want to "
+"be reviewed faster? Consider <a %2$s>becoming an editor</a>."
+
+#. %s is a status, e.g Public or Incomplete.
+#: views/developers/uploader.thtml:165
+msgid "devcp_uploader_p_update_created"
+msgstr "Your new version has been created and is currently marked as %s."
+
+#. %1$s is href="..." and should stay in the 'Versions and Files' <a> tag.
+#. %2$s is href="..." and should stay in the 'current status' <a> tag.
+#: views/developers/uploader.thtml:177
+msgid "devcp_uploader_p_update_file"
+msgstr ""
+"View your new file in the <a %1$s>Versions and Files page</a>, check out "
+"your add-on's <a %2$s>current status</a>, or <b>add release notes</b> by "
+"clicking the button below (highly recommended)."
+
+#. %1$s is href="..." and should stay in the 'Versions and Files' <a> tag.
+#. %2$s is href="..." and should stay in the 'current status' <a> tag.
+#: views/developers/uploader.thtml:167
+msgid "devcp_uploader_p_update_version"
+msgstr ""
+"View your new version in the <a %1$s>Versions and Files page</a>, check out "
+"your add-on's <a %2$s>current status</a>, or <b>add release notes</b> by "
+"clicking the button below (highly recommended)."
+
+#: views/developers/uploader.thtml:118
+msgid "devcp_uploader_p_upload"
+msgstr ""
+"Upload your add-on file using the form below. If you have multiple, platform-"
+"specific files to upload, choose a single file and then upload the others "
+"using the Versions and Files Manager."
+
+#: views/developers/uploader.thtml:125
+msgid "devcp_uploader_platformtype_all"
+msgstr "All"
+
+#: views/developers/uploader.thtml:126
+msgid "devcp_uploader_platformtype_specific"
+msgstr "Specific:"
+
+#. Used as first item in a <select>.
+#: controllers/components/developers.php:1185
+msgid "devcp_uploader_please_choose"
+msgstr "Please Choose..."
+
+#. %1$s is the add-on name, %2$s is the version number.
+#: views/developers/uploader.thtml:57
+msgid "devcp_uploader_title_file"
+msgstr "Add File to %1$s %2$s"
+
+#: views/developers/uploader.thtml:50
+msgid "devcp_uploader_title_submit"
+msgstr "Submit New Add-on"
+
+#. %s is the add-on name.
+#: views/developers/uploader.thtml:54
+msgid "devcp_uploader_title_update"
+msgstr "Update %s"
+
+#. %s is a full <a> tag
+#: controllers/developers_controller.php:503
+#, php-format
+msgid "devcp_valid_app_reference"
+msgstr "Please see %s for reference."
+
+#. This is the text in the <a> tag for devcp_valid_app_reference. This should be
+#. fixed.
+#: controllers/developers_controller.php:503
+msgid "devcp_valid_app_reference_linktext"
+msgstr "this page"
+
+#: controllers/developers_controller.php:581
+msgid "devcp_verify_author_error"
+msgstr "No account found for that email address."
+
+#: controllers/developers_controller.php:553
+msgid "devcp_verify_search_engine_error"
+msgstr ""
+"Either the XML is invalid or required fields are missing. Please <a href="
+"\"https://developer.mozilla.org/en/Creating_OpenSearch_plugins_for_Firefox"
+"\">read the documentation</a>, verify your add-on, and try again."
+
+#: views/developers/versions.thtml:75
+msgid "devcp_versions_a_cancel"
+msgstr "Cancel"
+
+#: views/developers/versions.thtml:79
+msgid "devcp_versions_a_delete"
+msgstr "Delete Version"
+
+#: views/developers/versions.thtml:74
+msgid "devcp_versions_a_empty"
+msgstr "Remove Empty Version"
+
+#: views/developers/versions.thtml:71
+msgid "devcp_versions_a_remove"
+msgstr "Remove?"
+
+#: views/developers/versions.thtml:91
+msgid "devcp_versions_add"
+msgstr "Add New Version"
+
+#: views/developers/versions_delete.thtml:58
+msgid "devcp_versions_delete_a_cancel"
+msgstr "Cancel"
+
+#: views/developers/versions_delete.thtml:56
+msgid "devcp_versions_delete_a_delete"
+msgstr "Delete Version"
+
+#. Followed by a list of reviews and files that will be removed.
+#: views/developers/versions_delete.thtml:50
+msgid "devcp_versions_delete_also"
+msgstr "This will also delete:"
+
+#: views/developers/versions_delete.thtml:53
+msgid "devcp_versions_delete_files"
+msgid_plural "devcp_versions_delete_files"
+msgstr[0] "%s file"
+msgstr[1] "%s files"
+
+#. %s is the version number.
+#: views/developers/versions_delete.thtml:48
+msgid "devcp_versions_delete_header"
+msgstr "Delete Version %s?"
+
+#: views/developers/versions_delete.thtml:52
+msgid "devcp_versions_delete_reviews"
+msgid_plural "devcp_versions_delete_reviews"
+msgstr[0] "%s review"
+msgstr[1] "%s reviews"
+
+#. %s is the version number.
+#: views/developers/versions_delete.thtml:49
+msgid "devcp_versions_delete_sure"
+msgstr "Are you sure you want to permanently delete version %s?"
+
+#: views/developers/versions_edit.thtml:102
+#: views/developers/versions_edit.thtml:155
+msgid "devcp_versions_edit_a_cancel"
+msgstr "Cancel"
+
+#: views/developers/versions_edit.thtml:101
+msgid "devcp_versions_edit_a_delete"
+msgstr "Delete File"
+
+#: views/developers/versions_edit.thtml:165
+msgid "devcp_versions_edit_a_new_app"
+msgstr "Add New Application"
+
+#: views/developers/versions_edit.thtml:154
+msgid "devcp_versions_edit_a_remove_app"
+msgstr "Remove Application"
+
+#: views/developers/versions_edit.thtml:114
+msgid "devcp_versions_edit_add"
+msgstr "Add New File"
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/versions_edit.thtml:121
+msgid "devcp_versions_edit_adjust"
+msgstr ""
+"Adjusting application information here will allow users to install your add-"
+"on even if the install.rdf in the package indicates that the add-on is "
+"incompatible. <a %s>List of supported applications</a>"
+
+#: views/developers/versions_edit.thtml:153
+msgid "devcp_versions_edit_compat_sure"
+msgstr ""
+"Are you <b>sure</b> you wish to remove compatibility with this application?"
+
+#: views/developers/versions_edit.thtml:100
+msgid "devcp_versions_edit_delete_sure"
+msgstr "Are you <b>sure</b> you wish to permanently delete this file?"
+
+#: views/developers/versions_edit.thtml:203
+msgid "devcp_versions_edit_header_approval"
+msgstr "Approval Information"
+
+#: views/developers/versions_edit.thtml:120
+msgid "devcp_versions_edit_header_compat"
+msgstr "Compatible Applications"
+
+#: views/developers/versions_edit.thtml:74
+msgid "devcp_versions_edit_header_file"
+msgstr "File Information"
+
+#: views/developers/versions_edit.thtml:189
+msgid "devcp_versions_edit_header_license"
+msgstr "License"
+
+#. %s is the version number.
+#: views/developers/versions_edit.thtml:53
+msgid "devcp_versions_edit_header_manage"
+msgstr "Manage Version %s"
+
+#: views/developers/versions_edit.thtml:212
+msgid "devcp_versions_edit_header_notes"
+msgstr "Approval Notes"
+
+#: views/developers/versions_edit.thtml:98
+msgid "devcp_versions_edit_img_delete"
+msgstr "Delete File"
+
+#. %1$s is the file id, e.g. 18723.
+#. %2$s is the platform name, e.g. ALL or Windows.
+#. %3$s is the _('date) created.
+#. %4$s is the status, e.g. "In Sandbox" or "Public".
+#. %5$s is the _('date') status was changed.
+#: views/developers/versions_edit.thtml:208
+msgid "devcp_versions_edit_li_file"
+msgstr "File %1$s (%2$s) created on %3$s and changed to %4$s on %5$s"
+
+#: views/developers/versions_edit.thtml:190
+msgid "devcp_versions_edit_license_description"
+msgstr ""
+"Please select the appropriate license for your add-on. This license "
+"specifies the rights you grant on your source code."
+
+#: views/developers/versions_edit.thtml:111
+msgid "devcp_versions_edit_no_files"
+msgstr "No files found."
+
+#: views/developers/versions_edit.thtml:213
+msgid "devcp_versions_edit_optional"
+msgstr "Optional information for the Editor that reviews this version."
+
+#: views/developers/versions_edit.thtml:151
+msgid "devcp_versions_edit_remove_compat"
+msgstr "Remove Application Compatibility"
+
+#: views/developers/versions_edit.thtml:167
+msgid "devcp_versions_edit_select_app"
+msgstr "Please Select an Application"
+
+#: views/developers/versions_edit.thtml:78
+msgid "devcp_versions_edit_th_file"
+msgstr "File"
+
+#: views/developers/versions_edit.thtml:79
+msgid "devcp_versions_edit_th_platform"
+msgstr "Platform"
+
+#: views/developers/versions_edit.thtml:80
+msgid "devcp_versions_edit_th_size"
+msgstr "Size"
+
+#: views/developers/versions_edit.thtml:81
+msgid "devcp_versions_edit_th_status"
+msgstr "Status"
+
+#: views/developers/versions_edit.thtml:183
+msgid "devcp_versions_edit_transbox_releasenotes_description"
+msgstr ""
+"Information about changes in this release, new features, known bugs, and "
+"other useful information specific to this release/version. This information "
+"will also be available to users updating the add-on in the Firefox 3 Add-ons "
+"Manager interface."
+
+#: views/developers/versions_edit.thtml:182
+msgid "devcp_versions_edit_transbox_releasenotes_name"
+msgstr "Release Notes"
+
+#: views/developers/versions_edit.thtml:164
+msgid "devcp_versions_edit_unsaved_compat"
+msgstr ""
+"<strong>You have unsaved changes.</strong> Compatibility will not be deleted "
+"until you click Update Version below."
+
+#: views/developers/versions_edit.thtml:113
+msgid "devcp_versions_edit_unsaved_files"
+msgstr ""
+"<strong>You have unsaved changes.</strong> Files will not be deleted until "
+"you click Update Version below."
+
+#: views/developers/versions_edit.thtml:218
+msgid "devcp_versions_edit_update"
+msgstr "Update Versions"
+
+#: views/developers/versions.thtml:49
+msgid "devcp_versions_header_manage"
+msgstr "Manage Versions and Files"
+
+#: views/developers/versions.thtml:87
+msgid "devcp_versions_no_versions"
+msgstr "No versions."
+
+#. %s is a version number, base 10.
+#: views/developers/versions.thtml:46
+msgid "devcp_versions_notice_success"
+msgstr "Version %s deleted successfully."
+
+#: views/developers/versions.thtml:73
+msgid "devcp_versions_p_remove"
+msgstr ""
+"This version has no files associated with it and can be removed. Would you "
+"like to remove this version?"
+
+#: views/developers/versions.thtml:58
+msgid "devcp_versions_th_created"
+msgstr "Created"
+
+#: views/developers/versions.thtml:57
+msgid "devcp_versions_th_status"
+msgstr "Status"
+
+#: views/developers/versions.thtml:56
+msgid "devcp_versions_th_version"
+msgstr "Version"
+
+#: controllers/downloads_controller.php:91
+msgid "downloads_disable_warning"
+msgstr "Denne tilføjelse er deaktiveret"
+
+#: controllers/components/editors.php:57
+msgid "editor_review_error_addon_not_nominated"
+msgstr "This add-on has not been nominated."
+
+#: controllers/components/editors.php:213
+msgid "editor_review_error_file_not_pending"
+msgstr "This file is not pending review."
+
+#. Actions are, for example: approving or rejecting
+#: controllers/components/editors.php:79
+#: controllers/components/editors.php:182
+msgid "editor_review_error_no_action"
+msgstr "Please select a review action."
+
+#: controllers/components/editors.php:192
+msgid "editor_review_error_no_applications"
+msgstr "Please enter the applications you tested."
+
+#. Comments are required when an editor approves or rejects an add-on.
+#: controllers/components/editors.php:84
+#: controllers/components/editors.php:187
+msgid "editor_review_error_no_comments"
+msgstr "Please enter review comments."
+
+#: controllers/components/editors.php:161
+msgid "editor_review_error_no_files"
+msgstr "Please select at least one file to review."
+
+#: controllers/components/editors.php:197
+msgid "editor_review_error_no_operating_system"
+msgstr "Please enter the operating systems you tested."
+
+#: views/editors/logs.thtml:51
+msgid "editorcp_logs_button_filter"
+msgstr "Filter"
+
+#: views/editors/logs.thtml:44
+msgid "editorcp_logs_filter_by"
+msgstr "Filter by type/action"
+
+#: views/editors/logs.thtml:42 controllers/editors_controller.php:964
+msgid "editorcp_logs_page_heading"
+msgstr "Event Log"
+
+#: views/elements/developers/editorsmenu.thtml:60
+msgid "editorcp_menu_eventlog_link"
+msgstr "Event Log"
+
+#: views/elements/developers/editorsmenu.thtml:62
+msgid "editorcp_menu_mainpage_link"
+msgstr "Back to Main"
+
+#: views/elements/developers/editorsmenu.thtml:61
+msgid "editorcp_menu_reviewlog_link"
+msgstr "Review Log"
+
+#: views/elements/developers/editorsmenu.thtml:55
+msgid "editorcp_menu_summary_link"
+msgstr "Editor Summary"
+
+#: views/elements/developers/editorsmenu.thtml:52
+msgid "editorcp_menu_title"
+msgstr "Editor Tools"
+
+#: views/editors/reviewlog.thtml:49
+msgid "editorcp_reviewlog_button_filter"
+msgstr "Filter"
+
+#: views/editors/reviewlog.thtml:58
+msgid "editorcp_reviewlog_column_action"
+msgstr "Action"
+
+#: views/editors/reviewlog.thtml:56
+msgid "editorcp_reviewlog_column_addon"
+msgstr "Add-on"
+
+#: views/editors/reviewlog.thtml:55
+msgid "editorcp_reviewlog_column_date"
+msgstr "Date"
+
+#: views/editors/reviewlog.thtml:57
+msgid "editorcp_reviewlog_column_editor"
+msgstr "Editor"
+
+#: views/editors/reviewlog.thtml:94
+msgid "editorcp_reviewlog_comments_hide"
+msgstr "Hide Comments"
+
+#: views/editors/reviewlog.thtml:93
+msgid "editorcp_reviewlog_comments_show"
+msgstr "Show Comments"
+
+#. %1$s and %2$s are full <input> tags for dates
+#: views/editors/reviewlog.thtml:45
+#, php-format
+msgid "editorcp_reviewlog_entries_between"
+msgstr "View entries between %1$s and %2$s"
+
+#: views/editors/reviewlog.thtml:104
+msgid "editorcp_reviewlog_none_found"
+msgstr "No reviews found for this period."
+
+#: views/editors/reviewlog.thtml:42
+msgid "editorcp_reviewlog_page_heading"
+msgstr "Review Log"
+
+#: views/editors/summary.thtml:61
+msgid "editorcp_summary_monthreviews_heading"
+msgstr "Month Reviews"
+
+#: views/editors/summary.thtml:77
+msgid "editorcp_summary_neweditors_heading"
+msgstr "New Editors"
+
+#: views/editors/summary.thtml:42
+msgid "editorcp_summary_page_heading"
+msgstr "Editor Summary"
+
+#: views/editors/summary.thtml:94
+msgid "editorcp_summary_recentactivity_heading"
+msgstr "Recent Editor Activity"
+
+#: views/editors/summary.thtml:45
+msgid "editorcp_summary_totalreviews_heading"
+msgstr "Total Reviews"
+
+#: controllers/editors_controller.php:248
+#: controllers/editors_controller.php:249
+msgid "editors_addon_review_pagetitle"
+msgstr "Review Add-on"
+
+#: controllers/editors_controller.php:349
+msgid "editors_error_js-formerror"
+msgstr "Please complete the following fields:"
+
+#: controllers/editors_controller.php:350
+msgid "editors_error_review_one_file"
+msgstr "Please select at least one file to review."
+
+#: controllers/editors_controller.php:274
+msgid "editors_error_self_reviews_forbidden"
+msgstr "Self-reviews are not allowed."
+
+#: controllers/editors_controller.php:699
+msgid "editors_external_software"
+msgstr "External Software"
+
+#: views/editors/featured.thtml:120 views/editors/featured.thtml:121
+msgid "editors_featured_add_feature"
+msgstr "Add feature"
+
+#: views/editors/featured.thtml:126
+msgid "editors_featured_add_feature_submit"
+msgstr "Add"
+
+#: views/editors/featured.thtml:49 controllers/editors_controller.php:832
+#: controllers/editors_controller.php:848
+msgid "editors_featured_addon_add_failure"
+msgstr "Failed to add feature."
+
+#: controllers/editors_controller.php:851
+msgid "editors_featured_addon_add_success"
+msgstr "Successfully added feature."
+
+#: views/editors/featured.thtml:50 controllers/editors_controller.php:839
+#: controllers/editors_controller.php:868
+#: controllers/editors_controller.php:886
+msgid "editors_featured_addon_edit_failure"
+msgstr "Failed to edit feature."
+
+#: views/editors/featured.thtml:51 controllers/editors_controller.php:888
+msgid "editors_featured_addon_edit_success"
+msgstr "Successfully edited feature."
+
+#: views/editors/featured.thtml:53 controllers/editors_controller.php:861
+msgid "editors_featured_addon_invalid_locale"
+msgstr "One or more locales are invalid."
+
+#: views/editors/featured.thtml:52 controllers/editors_controller.php:906
+msgid "editors_featured_addon_remove_failure"
+msgstr "Failed to remove feature."
+
+#: controllers/editors_controller.php:901
+msgid "editors_featured_addon_remove_success"
+msgstr "Successfully removed feature."
+
+#: controllers/editors_controller.php:915
+#: controllers/editors_controller.php:917
+msgid "editors_featured_addons_pagetitle"
+msgstr "Featured Add-ons"
+
+#: views/editors/featured.thtml:54 views/editors/featured.thtml:107
+msgid "editors_featured_edit_feature_submit"
+msgstr "Go"
+
+#: views/editors/featured.thtml:90 views/editors/featured.thtml:91
+msgid "editors_featured_remove_feature"
+msgstr "Remove feature"
+
+#: views/editors/queue.thtml:46
+msgid "editors_filter_queue"
+msgstr "Filter Queue"
+
+#: views/editors/queue.thtml:182
+msgid "editors_helpful_links"
+msgstr "Helpful Links"
+
+#: views/editors/queue.thtml:182
+msgid "editors_link_guide"
+msgstr "Editors' Guide"
+
+#: views/editors/queue.thtml:182
+msgid "editors_link_policy"
+msgstr "Add-on Policy"
+
+#: views/editors/queue.thtml:47
+msgid "editors_notice_filter_session"
+msgstr "These filters will remain in place for this session or until cleared."
+
+#. %1 is the queue mode
+#: views/editors/queue.thtml:177 views/admin/flagged_queue.thtml:89
+msgid "editors_notice_none_found"
+msgstr "There are currently no add-ons of this type to review."
+
+#: controllers/editors_controller.php:1040
+msgid "editors_one_day"
+msgstr "1 day"
+
+#: controllers/editors_controller.php:1048
+msgid "editors_one_hour"
+msgstr "1 hour"
+
+#: controllers/editors_controller.php:1056
+msgid "editors_one_minute"
+msgstr "1 minute"
+
+#: controllers/editors_controller.php:64 controllers/editors_controller.php:73
+#: controllers/editors_controller.php:77
+msgid "editors_pagetitle"
+msgstr "Editor Tools"
+
+#. %s is a comma separated list of platforms. Example: Windows, OS X
+#: controllers/editors_controller.php:680
+#: controllers/editors_controller.php:683
+#, php-format
+msgid "editors_platform_x_only"
+msgstr "%s only"
+
+#: controllers/editors_controller.php:695
+msgid "editors_pre-release"
+msgstr "Pre-release"
+
+#. %1 is the app name
+#: views/editors/queue.thtml:131
+#, php-format
+msgid "editors_queue_app_compatibility"
+msgstr "%s Compatibility"
+
+#: views/editors/queue.thtml:51
+#, fuzzy
+msgid "editors_queue_filter_label_addon"
+msgstr "Add-on or Author Email"
+
+#: views/editors/queue.thtml:72
+#, fuzzy
+msgid "editors_queue_filter_label_addontypes"
+msgstr "Add-on Types"
+
+#: views/editors/queue.thtml:56
+#, fuzzy
+msgid "editors_queue_filter_label_application"
+msgstr "Application"
+
+#: views/editors/queue.thtml:61
+#, fuzzy
+msgid "editors_queue_filter_label_maxversion"
+msgstr "Max. Version"
+
+#: views/editors/queue.thtml:78
+#, fuzzy
+msgid "editors_queue_filter_label_platforms"
+msgstr "Platforms"
+
+#: views/editors/queue.thtml:66
+#, fuzzy
+msgid "editors_queue_filter_label_submissionage"
+msgstr "Age of Submission (days)"
+
+#. %1$s is a number
+#: views/editors/queue.thtml:90
+#, fuzzy
+msgid "editors_queue_filter_result_count"
+msgid_plural "editors_queue_filter_result_count"
+msgstr[0] "Results of your filtered search: <strong>%1$s</strong> Add-on"
+msgstr[1] "Results of your filtered search: <strong>%1$s</strong> Add-ons"
+
+#: views/editors/queue.thtml:84
+msgid "editors_queue_submit_clean"
+msgstr "Clear"
+
+#: views/editors/queue.thtml:83
+msgid "editors_queue_submit_filter"
+msgstr "Filter"
+
+#: controllers/editors_controller.php:133
+msgid "editors_queues_disabled"
+msgstr ""
+"All review queues are currently disabled. Please check back at a later time."
+
+#: views/editors/review.thtml:149
+msgid "editors_review_a_edit_item"
+msgstr "Edit Item"
+
+#: views/editors/review.thtml:146
+msgid "editors_review_a_item_history"
+msgstr "Item History"
+
+#: views/editors/review.thtml:148
+msgid "editors_review_a_item_homepage"
+msgstr "Item Homepage"
+
+#: views/editors/review.thtml:145
+msgid "editors_review_a_item_overview"
+msgstr "Item Overview"
+
+#: views/editors/review.thtml:147
+msgid "editors_review_a_previews"
+msgstr "Previews"
+
+#: controllers/editors_controller.php:345
+msgid "editors_review_action"
+msgstr "Review Action"
+
+#: views/editors/review.thtml:159
+msgid "editors_review_action_info"
+msgstr "Request More Information"
+
+#: views/editors/review.thtml:157
+msgid "editors_review_action_public"
+msgstr "Push to Public"
+
+#: views/editors/review.thtml:160
+msgid "editors_review_action_request_superreview"
+msgstr "Request Super-Review"
+
+#: views/editors/review.thtml:158
+msgid "editors_review_action_sandbox"
+msgstr "Retain in Sandbox"
+
+#: controllers/editors_controller.php:346
+msgid "editors_review_comments"
+msgstr "Review Comments"
+
+#: views/editors/review.thtml:182
+msgid "editors_review_details_info_request"
+msgstr ""
+"Use this form to request more information from the author. They will receive "
+"an email and be able to answer here. You will be notified by email when they "
+"reply."
+
+#: views/editors/review.thtml:174
+msgid "editors_review_details_nominated_public"
+msgstr ""
+"This will mark the add-on and its most recent version and files as public. "
+"Future versions will go into the sandbox until they are reviewed by an "
+"editor."
+
+#: views/editors/review.thtml:177
+msgid "editors_review_details_nominated_sandbox"
+msgstr "This will retain the add-on in the sandbox."
+
+#: views/editors/review.thtml:166
+msgid "editors_review_details_pending_public"
+msgstr ""
+"This will approve a sandboxed version of a public add-on to appear on the "
+"public side."
+
+#: views/editors/review.thtml:169
+msgid "editors_review_details_pending_sandbox"
+msgstr ""
+"This will cause a sandboxed version of a public add-on to remain in the "
+"sandbox."
+
+#: views/editors/review.thtml:185
+msgid "editors_review_details_superreview"
+msgstr ""
+"If you have concerns about this add-on's security, copyright issues, or "
+"other concerns that an administrator should look into, enter your comments "
+"in the area below. They will be sent to administrators, not the author."
+
+#: views/editors/review.thtml:134
+msgid "editors_review_file_diff_link"
+msgstr "Compare with public version"
+
+#: views/editors/review.thtml:131
+msgid "editors_review_file_viewcontents_link"
+msgstr "View Contents"
+
+#: views/editors/review.thtml:65
+msgid "editors_review_header_authors"
+msgstr "Authors:"
+
+#: views/editors/review.thtml:79
+msgid "editors_review_header_categories"
+msgstr "Categories:"
+
+#: views/editors/review.thtml:92
+msgid "editors_review_header_compatibility"
+msgstr "Compatibility:"
+
+#: views/editors/review.thtml:251
+msgid "editors_review_header_description"
+msgstr "Description"
+
+#: views/editors/review.thtml:275
+msgid "editors_review_header_devcomments"
+msgstr "Developer Comments"
+
+#: views/editors/review.thtml:263
+msgid "editors_review_header_eula"
+msgstr "EULA"
+
+#: views/editors/review.thtml:115
+msgid "editors_review_header_files"
+msgstr "Files:"
+
+#: views/editors/review.thtml:284
+msgid "editors_review_header_itemhistory"
+msgstr "Item History"
+
+#: views/editors/review.thtml:232
+msgid "editors_review_header_nominationmessage"
+msgstr "Nomination Message"
+
+#: views/editors/review.thtml:311
+msgid "editors_review_header_previews"
+msgstr "Previews"
+
+#: views/editors/review.thtml:269
+msgid "editors_review_header_privacy"
+msgstr "Privacy Policy"
+
+#. %1 is the add-on name and version
+#: views/editors/review.thtml:56
+#, php-format
+msgid "editors_review_header_review"
+msgstr "Review %s"
+
+#: views/editors/review.thtml:239
+msgid "editors_review_header_reviewernotes"
+msgstr "Notes to Reviewer"
+
+#: views/editors/review.thtml:245
+msgid "editors_review_header_summary"
+msgstr "Summary"
+
+#: views/editors/review.thtml:257
+msgid "editors_review_header_versionnotes"
+msgstr "Version Notes"
+
+#. a noun: shown in an add-on's editor review history
+#: views/elements/developers/editors_review_history_item.thtml:80
+msgid "editors_review_history_info_reply"
+msgstr "Reply"
+
+#: views/elements/developers/editors_review_history_item.thtml:78
+msgid "editors_review_history_info_request"
+msgstr "Information Request"
+
+#: views/elements/developers/editors_review_history_item.thtml:62
+#: views/editors/reviewlog.thtml:77
+msgid "editors_review_history_nominated_adminreview"
+msgstr "Admin Review"
+
+#: views/elements/developers/editors_review_history_item.thtml:56
+#: views/editors/reviewlog.thtml:71
+msgid "editors_review_history_nominated_approved"
+msgstr "Nomination Approved/Public"
+
+#: views/elements/developers/editors_review_history_item.thtml:59
+#: views/editors/reviewlog.thtml:74
+msgid "editors_review_history_nominated_denied"
+msgstr "Nomination Denied/Sandbox"
+
+#: views/editors/review.thtml:303
+msgid "editors_review_history_nonefound"
+msgstr "No previous review entries could be found."
+
+#: views/elements/developers/editors_review_history_item.thtml:73
+#: views/editors/reviewlog.thtml:88
+msgid "editors_review_history_pending_adminreview"
+msgstr "Admin Review"
+
+#: views/elements/developers/editors_review_history_item.thtml:67
+#: views/editors/reviewlog.thtml:82
+msgid "editors_review_history_pending_approved"
+msgstr "Approved/Public"
+
+#: views/elements/developers/editors_review_history_item.thtml:70
+#: views/editors/reviewlog.thtml:85
+msgid "editors_review_history_pending_denied"
+msgstr "Denied/Sandbox"
+
+#. link text in an add-on's editor review history, allowing to hide and show an information request's replies
+#. %1 is the number of replies
+#: views/elements/developers/editors_review_history_item.thtml:90
+msgid "editors_review_history_show_hide_replies"
+msgid_plural "editors_review_history_show_hide_replies"
+msgstr[0] "Show/Hide Replies (%1$s)"
+msgstr[1] "Show/Hide Replies (%1$s)"
+
+#: views/editors/review.thtml:208
+msgid "editors_review_label_applications"
+msgstr "Applications:"
+
+#: views/editors/review.thtml:196
+msgid "editors_review_label_cannedresponse"
+msgstr "or select a canned response:"
+
+#: views/editors/review.thtml:190
+msgid "editors_review_label_comments"
+msgstr "Comments:"
+
+#: views/editors/review.thtml:204
+msgid "editors_review_label_operating_systems"
+msgstr "Operating Systems:"
+
+#: views/editors/review.thtml:285 views/editors/review.thtml:312
+msgid "editors_review_link_pagetop"
+msgstr "Top"
+
+#: views/editors/review.thtml:141
+msgid "editors_review_mulitple_notice"
+msgstr ""
+"Notice: Only review more than one file if you have tested EVERY file you "
+"select."
+
+#: views/editors/review.thtml:51
+msgid "editors_review_next_link"
+msgstr "next &raquo;"
+
+#: views/editors/review.thtml:322
+msgid "editors_review_previews_notfound"
+msgstr "No previews found."
+
+#: views/editors/review.thtml:50
+msgid "editors_review_previous_link"
+msgstr "&laquo; prev"
+
+#: controllers/editors_controller.php:144
+#: controllers/editors_controller.php:146
+msgid "editors_review_queue_pagetitle"
+msgstr "Review Queue"
+
+#. %1 is the add-ons rank in the queue, %2 is the total queue length
+#: views/editors/review.thtml:47
+msgid "editors_review_rank_in_queue"
+msgstr "<strong># %1$s</strong> of %2$s in queue"
+
+#. %1 is the add-ons rank in the queue, %2 is the total queue length. Both numbers
+#: views/editors/review.thtml:45
+#, fuzzy
+msgid "editors_review_rank_in_queue_filtered"
+msgstr "<strong># %1$s</strong> of %2$s in queue (filtered)"
+
+#: views/editors/review.thtml:223
+msgid "editors_review_submit_process_action"
+msgstr "Process Action"
+
+#: views/editors/review.thtml:293
+msgid "editors_review_th_action"
+msgstr "Action"
+
+#: views/editors/review.thtml:294
+msgid "editors_review_th_comments"
+msgstr "Comments"
+
+#: views/editors/review.thtml:291
+msgid "editors_review_th_date"
+msgstr "Date"
+
+#: views/editors/review.thtml:292
+msgid "editors_review_th_reviewer"
+msgstr "Reviewer"
+
+#: views/editors/review.thtml:290
+msgid "editors_review_th_version_file"
+msgstr "Version/File"
+
+#: views/editors/review.thtml:217
+msgid "editors_review_update_notify_once"
+msgstr ""
+"Notify me the next time this add-on is updated. (Subsequent updates will not "
+"generate an email)"
+
+#: controllers/editors_controller.php:298
+msgid "editors_reviewed_successfully"
+msgstr "Review successfully processed."
+
+#: views/editors/reviews_queue.thtml:106
+msgid "editors_reviews_action_delete_review"
+msgstr "Delete review"
+
+#: views/editors/reviews_queue.thtml:104
+msgid "editors_reviews_action_keep"
+msgstr "Remove flags; keep review"
+
+#: views/editors/reviews_queue.thtml:102
+msgid "editors_reviews_action_skip"
+msgstr "Skip"
+
+#: views/editors/reviews_queue.thtml:100
+msgid "editors_reviews_header_action"
+msgstr "Action"
+
+#: views/editors/reviews_queue.thtml:67
+msgid "editors_reviews_in_reply_to"
+msgstr "In reply to:"
+
+#: controllers/editors_controller.php:748
+msgid "editors_reviews_processed"
+msgstr "Reviews processed successfully!"
+
+#: views/editors/reviews_queue.thtml:117
+msgid "editors_reviews_queue_empty"
+msgstr "There are currently no reviews in moderation."
+
+#: views/editors/reviews_queue.thtml:111
+msgid "editors_reviews_submit_process_reviews"
+msgstr "Process Reviews"
+
+#: controllers/editors_controller.php:691
+msgid "editors_site_specific"
+msgstr "Site Specific"
+
+#: controllers/editors_controller.php:348
+msgid "editors_tested_app"
+msgstr "Tested Application"
+
+#: controllers/editors_controller.php:347
+msgid "editors_tested_os"
+msgstr "Tested Operating Systems"
+
+#: views/editors/queue.thtml:151
+msgid "editors_th_additional_info"
+msgstr "Additional Information"
+
+#: views/editors/featured.thtml:63 views/editors/queue.thtml:109
+#: views/admin/flagged_queue.thtml:53
+msgid "editors_th_addon"
+msgstr "Add-on"
+
+#: views/editors/queue.thtml:125
+msgid "editors_th_addontype"
+msgstr "Type"
+
+#: views/editors/featured.thtml:64
+msgid "editors_th_locales"
+msgstr "Restrict to locales?"
+
+#: views/editors/queue.thtml:148
+msgid "editors_th_nomination_age"
+msgstr "Time in Queue"
+
+#: views/editors/queue.thtml:101 views/editors/queue.thtml:117
+#: views/editors/queue.thtml:144
+#, fuzzy
+msgid "editors_th_sort_ascending"
+msgstr "Ascending sort"
+
+#: views/editors/queue.thtml:105 views/editors/queue.thtml:121
+#: views/editors/queue.thtml:140
+#, fuzzy
+msgid "editors_th_sort_descending"
+msgstr "Descending sort"
+
+#. %s is a number
+#: controllers/editors_controller.php:1036
+#, php-format
+msgid "editors_x_days"
+msgstr "%s days"
+
+#. %s is a number
+#: controllers/editors_controller.php:1044
+#, php-format
+msgid "editors_x_hours"
+msgstr "%s hours"
+
+#. %s is a number
+#: controllers/editors_controller.php:1052
+#, php-format
+msgid "editors_x_minutes"
+msgstr "%s minutes"
+
+#: views/errors/error401.thtml:50 controllers/components/simple_acl.php:81
+#: controllers/components/simple_acl.php:82
+#: controllers/components/simple_acl.php:83 controllers/components/amo.php:607
+#: controllers/components/amo.php:608 controllers/components/amo.php:609
+#: controllers/reviews_controller.php:353
+#: controllers/reviews_controller.php:485
+#: controllers/collections_controller.php:438
+#: controllers/collections_controller.php:496
+#: controllers/collections_controller.php:504
+#: controllers/collections_controller.php:971
+#: controllers/collections_controller.php:1034
+#: controllers/collections_controller.php:1077
+msgid "error_access_denied"
+msgstr "Ingen adgang"
+
+#: views/errors/error401.thtml:52
+msgid "error_access_denied_message"
+msgstr "Du har ikke adgang til at se denne side."
+
+#: controllers/collections_controller.php:1039
+#, fuzzy
+msgid "error_addon_exists"
+msgstr "Add-on already exists!"
+
+#: controllers/developers_controller.php:200
+#: controllers/developers_controller.php:593
+#: controllers/developers_controller.php:1016
+#: controllers/developers_controller.php:1429
+#: controllers/downloads_controller.php:95
+#: controllers/downloads_controller.php:102
+#: controllers/downloads_controller.php:164
+#: controllers/statistics_controller.php:135
+#: controllers/previews_controller.php:115
+#: controllers/previews_controller.php:206
+#: controllers/previews_controller.php:307
+#: controllers/reviews_controller.php:77
+#: controllers/reviews_controller.php:240
+#: controllers/reviews_controller.php:332
+#: controllers/reviews_controller.php:340 controllers/api_controller.php:123
+#: controllers/api_controller.php:759 controllers/addons_controller.php:131
+#: controllers/addons_controller.php:197
+#: controllers/addons_controller.php:1407
+#: controllers/addons_controller.php:1465
+#: controllers/addons_controller.php:1469
+#: controllers/addons_controller.php:1503
+#: controllers/editors_controller.php:265
+#: controllers/collections_controller.php:1041
+#: controllers/collections_controller.php:1074
+msgid "error_addon_notfound"
+msgstr "Tilføjelse ikke fundet!"
+
+#: controllers/files_controller.php:83 controllers/files_controller.php:196
+msgid "error_addon_notviewable"
+msgstr "Tilføjelsen kan ikke vises her."
+
+#: controllers/reviews_controller.php:246
+msgid "error_addon_selfreview"
+msgstr "Du kan ikke anmelde din egen tilføjelse."
+
+#: controllers/addons_controller.php:970
+msgid "error_browse_no_addons"
+msgstr "Ingen tilføjelser i denne kategori!"
+
+#: controllers/api_controller.php:424
+msgid "error_collection_feed_notfound"
+msgstr "Tilføjelsesfeed ikke fundet."
+
+#: views/users/register.thtml:65 views/users/edit.thtml:194
+msgid "error_email_invalid"
+msgstr "Dette er ikke en gyldig e-mail-adresse."
+
+#: views/users/pwreset.thtml:74 views/users/register.thtml:70
+#: views/users/register.thtml:80 views/users/register.thtml:86
+#: views/users/edit.thtml:105 views/users/edit.thtml:111
+#: views/users/edit.thtml:192 views/admin/users_edit.thtml:78
+#: views/admin/users_edit.thtml:83 views/reviews/add.thtml:80
+#: views/reviews/add.thtml:104
+msgid "error_field_required"
+msgstr "Dette felt skal udfyldes."
+
+#: controllers/files_controller.php:75 controllers/files_controller.php:93
+#: controllers/files_controller.php:96 controllers/files_controller.php:163
+#: controllers/files_controller.php:176 controllers/files_controller.php:185
+#: controllers/files_controller.php:204 controllers/editors_controller.php:412
+msgid "error_file_notfound"
+msgstr "Fil ikke fundet!"
+
+#. %s is a filename
+#: controllers/editors_controller.php:430
+#, php-format
+msgid "error_file_x_notfound"
+msgstr "Fejl: Filen %s eksisterer ikke."
+
+#: views/collections/add.thtml:55 views/collections/edit.thtml:89
+#: views/users/register.thtml:54 views/users/edit.thtml:81
+#: views/reviews/add.thtml:70 controllers/groups_controller.php:80
+#: controllers/groups_controller.php:102
+msgid "error_formerrors"
+msgstr "Der er fejl i denne formular. Ret dem venligst og indsend igen."
+
+#: views/users/register.thtml:109
+msgid "error_invalid_captcha"
+msgstr ""
+"Vi var ikke i stand til at finde ud af, om du er et menneske eller en robot. "
+"Prøv igen."
+
+#: views/users/register.thtml:100 views/users/edit.thtml:125
+#: views/admin/users_edit.thtml:101
+msgid "error_invalid_url"
+msgstr ""
+"Denne URL har et ugyldigt format. Gyldige URLs ligner http://example.com/"
+"min_side."
+
+#. %s is a string representing what's missing. Example: file_id
+#: controllers/downloads_controller.php:65
+#: controllers/users_controller.php:185 controllers/users_controller.php:264
+#: controllers/users_controller.php:559 controllers/users_controller.php:653
+#: controllers/reviews_controller.php:71
+#: controllers/reviews_controller.php:234
+#: controllers/reviews_controller.php:325
+#: controllers/reviews_controller.php:473
+#: controllers/reviews_controller.php:475
+#: controllers/addons_controller.php:182
+#: controllers/addons_controller.php:1381
+#: controllers/addons_controller.php:1455
+#: controllers/collections_controller.php:266
+#: controllers/collections_controller.php:285
+#: controllers/collections_controller.php:346
+#: controllers/collections_controller.php:443
+#: controllers/collections_controller.php:482
+#: controllers/collections_controller.php:936
+#: controllers/collections_controller.php:959
+#: controllers/collections_controller.php:960
+#: controllers/collections_controller.php:975
+#: controllers/collections_controller.php:977
+#: controllers/collections_controller.php:994
+#: controllers/collections_controller.php:1003
+#: controllers/collections_controller.php:1016
+#: controllers/collections_controller.php:1017
+#: controllers/collections_controller.php:1024
+#: controllers/collections_controller.php:1070
+#: controllers/collections_controller.php:1090
+#, php-format
+msgid "error_missing_argument"
+msgstr "Manglende argument: %s"
+
+#: controllers/components/amo.php:507 controllers/components/amo.php:532
+msgid "error_no_files_in_addon"
+msgstr "Ingen filer"
+
+#: controllers/previews_controller.php:200
+msgid "error_preview_notfound"
+msgstr "Skærmbillede ikke fundet!"
+
+#: views/addons/display.thtml:400 views/reviews/add.thtml:98
+msgid "error_review_rating_required"
+msgstr "Du skal give en bedømmelse."
+
+#: controllers/users_controller.php:160
+msgid "error_user_already_confirmed"
+msgstr "Brugerkontoen er allerede bekræftet."
+
+#: controllers/users_controller.php:202 controllers/users_controller.php:276
+#: controllers/users_controller.php:569 controllers/users_controller.php:581
+#: controllers/users_controller.php:587 controllers/users_controller.php:610
+#: controllers/users_controller.php:627
+msgid "error_user_badconfirmationcode"
+msgstr "Ugyldig bekræftelseskode!"
+
+#: views/users/pwreset.thtml:79 views/users/register.thtml:75
+#: views/users/edit.thtml:183
+msgid "error_user_confirmpw_nomatch"
+msgstr "Adgangskoderne matchede ikke."
+
+#: views/users/register.thtml:65 views/users/edit.thtml:190
+#: controllers/users_controller.php:617
+msgid "error_user_email_notunique"
+msgstr "Denne e-mail-adresse anvendes allerede af en anden bruger."
+
+#: controllers/users_controller.php:596
+msgid "error_user_emailchange_expired"
+msgstr ""
+"E-mail ændringen er udløbet. Du bedes rette din e-mail-adresse igen i din "
+"brugerprofil og klikke på linket i bekræftelsesmailen så snart du modtager "
+"den."
+
+#: controllers/collections_controller.php:985
+#, fuzzy
+msgid "error_user_exists"
+msgstr ""
+"Users can only have one role at a time. Please remove the user from any "
+"existing roles before continuing."
+
+#: views/users/register.thtml:91 views/users/edit.thtml:116
+#: views/admin/users_edit.thtml:88
+msgid "error_user_nickname_notunique"
+msgstr "Kaldenavnet er allerede i brug."
+
+#: views/users/pwreset.thtml:54 controllers/users_controller.php:191
+#: controllers/users_controller.php:270 controllers/users_controller.php:603
+#: controllers/users_controller.php:659
+#: controllers/collections_controller.php:988
+#: controllers/collections_controller.php:998
+msgid "error_user_notfound"
+msgstr "Bruger ikke fundet!"
+
+#: views/users/activatefirst.thtml:47
+msgid "error_user_unconfirmed"
+msgstr ""
+"Bekræft venligst først din brugerkonto med koden, du modtog via e-mail."
+
+#: views/users/login.thtml:67
+msgid "error_username_or_pw_wrong"
+msgstr "Forkert brugernavn eller adgangskode!"
+
+#: controllers/editors_controller.php:260
+msgid "error_version_notfound"
+msgstr "Version ikke fundet!"
+
+#: views/users/delete.thtml:125 views/users/edit.thtml:173
+msgid "error_wrong_password"
+msgstr "Forkert adgangskode!"
+
+#: views/elements/amo2009/homepage_addon.thtml:122
+#: views/elements/feature.thtml:122
+msgid "feature_learnmore"
+msgstr "Lær mere"
+
+#. %1 is the add-on name
+#: views/elements/amo2009/homepage_addon.thtml:123
+#: views/elements/feature.thtml:123
+#, php-format
+msgid "feature_learnmore_about_addon"
+msgstr "Lær mere om %1$s"
+
+#. %1$s is a number
+#: views/elements/amo2009/reviews.thtml:52
+#: views/elements/addon_listitem.thtml:112 views/elements/feature.thtml:99
+#: views/addons/browse_thumbs.thtml:86
+#, php-format
+msgid "feature_reviews"
+msgid_plural "feature_reviews"
+msgstr[0] "%1$s anmeldelse"
+msgstr[1] "%1$s anmeldelser"
+
+#: views/elements/amo2009/homepage_addon.thtml:127
+#: views/elements/feature.thtml:127
+msgid "feature_view_more_from_category"
+msgstr "Vis mere fra"
+
+#. This appears on a page that views the source of an add-on. This link will return
+#. the user to the add-on's main page
+#: views/files/browse.thtml:65
+msgid "file_browser_link_addon"
+msgstr "Tilbage til tilføjelsen"
+
+#. There is a list of directories and files on the page. Clicking this will show the
+#. contents of all the directories (normally you would click on each one to see the
+#. contents)
+#: views/files/browse.thtml:67
+msgid "file_browser_link_expand_all"
+msgstr "Vis alle"
+
+#. This appears on a page that views the source of an add-on. This link will return
+#. the user to the add-on's review page (it only appears if the add-on is being
+#. reviewed)
+#: views/files/browse.thtml:64
+msgid "file_browser_link_review"
+msgstr "Tilbage til anmeldelse"
+
+#. The title of the page for viewing an add-on's source.
+#. %1$s is the name of the add-on
+#. %2$s is the name of the current application (e.g. Firefox or Thunderbird)
+#: views/files/browse.thtml:46
+msgid "file_browser_title"
+msgstr "%1$s :: Filbrowser :: %2$s Add-ons"
+
+#. This appears on a page that views the source of an add-on. There is a list of
+#. directories and files on the page. Clicking this link will toggle between an
+#. expanded or a collapsed list. This string should be kept short.
+#: views/files/browse.thtml:68
+msgid "file_browser_toggle_expand_collapse"
+msgstr "+/-"
+
+#. Link text for the AMO About page.
+#: views/elements/footer.thtml:72 views/layouts/amo2009.thtml:341
+msgid "footer_a_about"
+msgstr "Om"
+
+#. Link text to the AMO blog.
+#: views/elements/footer.thtml:74 views/layouts/amo2009.thtml:343
+msgid "footer_a_blog"
+msgstr "Blog"
+
+#. Link text to the Frequently Asked Questions page.
+#: views/elements/footer.thtml:73 views/layouts/amo2009.thtml:342
+msgid "footer_a_faq"
+msgstr "FAQ"
+
+#. Full text for the FAQ abbreviation.
+#: views/elements/footer.thtml:73 views/pages/collector_features.thtml:72
+#: views/layouts/amo2009.thtml:342
+msgid "footer_abbr_faq"
+msgstr "Frequently Asked Questions"
+
+#: views/elements/footer.thtml:67 views/layouts/amo2009.thtml:336
+msgid "footer_all_rights_reserved"
+msgstr "Alle rettigheder forbeholdes."
+
+#: views/elements/footer.thtml:67 views/layouts/amo2009.thtml:336
+msgid "footer_copyright"
+msgstr "Copyright"
+
+#: views/elements/footer.thtml:71 views/layouts/amo2009.thtml:340
+msgid "footer_credits"
+msgstr "Tak til"
+
+#: views/elements/footer.thtml:76 views/layouts/amo2009.thtml:346
+msgid "footer_disclaimer"
+msgstr ""
+"Mozilla linker til disse programmer som en ekstra service og repræsenterer "
+"på ingen måde programmet eller enhver information relateret til dette. Alle "
+"spørgsmål, klager eller krav vedrørende programmerne skal sendes til "
+"softwareudgiveren."
+
+#: views/elements/footer.thtml:61 views/layouts/amo2009.thtml:332
+msgid "footer_lang_form_lang_submit_go"
+msgstr "Skift"
+
+#: views/elements/footer.thtml:70 views/layouts/amo2009.thtml:339
+msgid "footer_legal_notices"
+msgstr "Juridiske betingelser"
+
+#: views/elements/footer.thtml:50 views/layouts/amo2009.thtml:321
+msgid "footer_other_languages"
+msgstr "Andre sprog:"
+
+#: views/elements/footer.thtml:69 views/layouts/amo2009.thtml:338
+msgid "footer_privacy_policy"
+msgstr "Privatlivspolitik"
+
+#: models/addontype.php:79
+msgid "general_addontype_dict"
+msgstr "Ordbog"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:100
+msgid "general_addontype_dict_plural"
+msgstr "Ordbøger"
+
+#: models/addontype.php:75
+msgid "general_addontype_extension"
+msgstr "Udvidelse"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:98
+msgid "general_addontype_extension_plural"
+msgstr "Udvidelser"
+
+#: models/addontype.php:85
+msgid "general_addontype_lpaddon"
+msgstr "Sprogpakke (tilføjelse)"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:103
+msgid "general_addontype_lpaddon_plural"
+msgstr "Sprogpakker (tilføjelse)"
+
+#: models/addontype.php:83
+msgid "general_addontype_lpapp"
+msgstr "Sprogpakke (program)"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:102
+msgid "general_addontype_lpapp_plural"
+msgstr "Sprogpakker (program)"
+
+#: models/addontype.php:87
+msgid "general_addontype_plugin"
+msgstr "Plugin"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:104
+msgid "general_addontype_plugin_plural"
+msgstr "Plugins"
+
+#: models/addontype.php:81
+msgid "general_addontype_search"
+msgstr "Søgetjeneste"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:101
+msgid "general_addontype_search_plural"
+msgstr "Søgetjenester"
+
+#: models/addontype.php:77
+msgid "general_addontype_theme"
+msgstr "Tema"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:99
+msgid "general_addontype_theme_plural"
+msgstr "Temaer"
+
+#: config/language.php:367
+#, fuzzy
+msgid "general_languages_all_locales"
+msgstr "All Locales"
+
+#: views/layouts/amo2009.thtml:249
+#, fuzzy
+msgid "header_brand_name"
+msgstr "Mozilla"
+
+#. %1$s is the application name. Example: Firefox
+#: views/elements/header.thtml:111 views/elements/header.thtml:122
+#: views/layouts/amo2009.thtml:248
+#, php-format
+msgid "header_home_tooltip"
+msgstr "Tilbage til startsiden for %1$s Add-ons"
+
+#: views/elements/header.thtml:87
+msgid "header_main_firefox_header"
+msgstr "Firefox Add-ons"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:218
+#, fuzzy
+msgid "header_main_firefox_header_with_logo"
+msgstr ""
+"Add-ons <em>for</em> <img alt=\"Firefox\" src=\"%1$s\" /> <strong>Firefox</"
+"strong>"
+
+#: views/elements/header.thtml:99
+msgid "header_main_header"
+msgstr "Tilføjelser"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:242
+#, fuzzy
+msgid "header_main_header_with_logo"
+msgstr "Add-ons <img alt=\"Add-ons\" src=\"%1$s\" />"
+
+#: views/elements/header.thtml:90
+msgid "header_main_seamonkey_header"
+msgstr "SeaMonkey Add-ons"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:224
+#, fuzzy
+msgid "header_main_seamonkey_header_with_logo"
+msgstr ""
+"Add-ons <em>for</em> <img alt=\"seamonkey\" src=\"%1$s\" /> "
+"<strong>SeaMonkey</strong>"
+
+#: views/elements/header.thtml:93
+msgid "header_main_sunbird_header"
+msgstr "Sunbird Add-ons"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:230
+#, fuzzy
+msgid "header_main_sunbird_header_with_logo"
+msgstr ""
+"Add-ons <em>for</em> <img alt=\"sunbird\" src=\"%1$s\" /> <strong>Sunbird</"
+"strong>"
+
+#: views/elements/header.thtml:96
+msgid "header_main_thunderbird_header"
+msgstr "Thunderbird Add-ons"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:236
+#, fuzzy
+msgid "header_main_thunderbird_header_with_logo"
+msgstr ""
+"Add-ons <em>for</em> <img alt=\"thunderbird\" src=\"%1$s\" /> "
+"<strong>Thunderbird</strong>"
+
+#: views/layouts/amo2009.thtml:205
+#, fuzzy
+msgid "header_navaccess_applications_menu"
+msgstr "Skip to other applications menu"
+
+#: views/layouts/amo2009.thtml:204
+#, fuzzy
+msgid "header_navaccess_categories_menu"
+msgstr "Skip to categories menu"
+
+#: views/layouts/amo2009.thtml:202
+#, fuzzy
+msgid "header_navaccess_main_content"
+msgstr "Skip to main content"
+
+#: views/layouts/amo2009.thtml:203
+#, fuzzy
+msgid "header_navaccess_search_form"
+msgstr "Skip to search form"
+
+#: views/elements/header.thtml:62
+msgid "header_navlink_addons"
+msgstr "Tilføjelser"
+
+#: views/elements/developers/sidebar.thtml:72
+#: views/elements/developers/myaddons.thtml:50 views/elements/header.thtml:159
+#: views/addons/display.thtml:378
+msgid "header_navlink_login"
+msgstr "Log ind"
+
+#: views/elements/header.thtml:156 views/layouts/amo2009.thtml:304
+msgid "header_navlink_logout"
+msgstr "Log ud"
+
+#: views/elements/header.thtml:145 views/layouts/amo2009.thtml:303
+msgid "header_navlink_myaccount"
+msgstr "Min konto"
+
+#: views/elements/header.thtml:158
+msgid "header_navlink_register"
+msgstr "Registrer"
+
+#. %1 is the URL to the registration page
+#. %2 is the URL to the login page
+#: views/layouts/amo2009.thtml:278
+#, fuzzy
+msgid "header_navlink_register_or_login"
+msgstr "<a href=\"%1$s\">Register</a> or <a href=\"%2$s\">Log in</a>"
+
+#: views/layouts/amo2009.thtml:285
+#, fuzzy
+msgid "header_navlink_tools"
+msgstr "Tools"
+
+#. %s is the add-on name
+#: views/elements/collections_interactive_addon.thtml:62
+#: views/elements/amo2009/homepage_addon.thtml:77
+#: views/elements/addon_discussionheader.thtml:62
+#: views/elements/addon_listitem.thtml:67 views/elements/feature.thtml:84
+#: views/addons/category_landing.thtml:87 views/addons/browse_thumbs.thtml:60
+#, php-format
+msgid "img_preview_of"
+msgstr "Skærmbillede af %s"
+
+#. %1 is the login URL for the link tag
+#. %2 is the link to an explanatory page.
+#: views/elements/amo2009/install.thtml:307 views/elements/install.thtml:255
+msgid "install_a_login_to_install"
+msgstr ""
+"<a href=\"%1$s\">Log ind</a> for at installere denne tilføjelse. <a href=\"%2"
+"$s\">Hvorfor</a>?"
+
+#. %1 is the URL for the Experimental Add-ons section of the FAQ page
+#: views/elements/amo2009/install.thtml:283 views/elements/install.thtml:232
+msgid "install_button_confirm_exp_install"
+msgstr ""
+"Lad mig installere denne eksperimentelle tilføjelse. <a href=\"%1$s\">Hvad "
+"er det?</a>"
+
+#. %1$s is the application name. Example: Firefox
+#. %2$s is an optional string used to specify a platform. Example: (Windows)
+#: views/elements/amo2009/install.thtml:128 views/elements/install.thtml:75
+#, php-format
+msgid "install_button_text"
+msgstr "Tilføj til %1$s %2$s"
+
+#. %1 is the add-on name, %2 is the app name
+#: views/elements/amo2009/install.thtml:191
+#: views/elements/amo2009/install.thtml:206
+#: views/elements/amo2009/install.thtml:249
+#: views/elements/amo2009/install.thtml:298 views/elements/install.thtml:150
+#: views/elements/install.thtml:165 views/elements/install.thtml:202
+#: views/elements/install.thtml:246
+#, php-format
+msgid "install_button_title"
+msgstr "Tilføj %1$s til %2$s"
+
+#. %1$s is the add-on name
+#: views/elements/amo2009/install.thtml:200 views/elements/install.thtml:159
+#, php-format
+msgid "install_download"
+msgstr "Download %1$s"
+
+#: views/elements/amo2009/install.thtml:147 views/elements/install.thtml:94
+msgid "install_error_addon_not_found"
+msgstr "Denne tilføjelse er ikke tilgængelig."
+
+#: views/addons/dictionaries.thtml:65
+msgid "langtools_a11y_tablesummary"
+msgstr "Liste over sprogpakker og ordbøger."
+
+#: views/addons/dictionaries.thtml:47
+msgid "langtools_download_dictionary"
+msgstr "Download ordbog"
+
+#: views/addons/dictionaries.thtml:48
+msgid "langtools_download_langpack"
+msgstr "Download sprogpakke"
+
+#: views/addons/dictionaries.thtml:63 controllers/components/amo.php:685
+#: controllers/addons_controller.php:1239
+msgid "langtools_header_dicts_and_langpacks"
+msgstr "Ordbøger & sprogpakker"
+
+#: views/addons/dictionaries.thtml:44
+msgid "langtools_install_dictionary"
+msgstr "Installer ordbog"
+
+#: views/addons/dictionaries.thtml:45
+msgid "langtools_install_langpack"
+msgstr "Installer sprogpakke"
+
+#: views/addons/dictionaries.thtml:69
+msgid "langtools_tableheader_dictionary"
+msgstr "Ordbog"
+
+#: views/addons/dictionaries.thtml:70
+msgid "langtools_tableheader_langpack"
+msgstr "Sprogpakke"
+
+#: views/addons/dictionaries.thtml:68
+msgid "langtools_tableheader_language"
+msgstr "Sprog"
+
+#: models/license.php:65
+msgid "license_custom"
+msgstr "Anden licens"
+
+#: config/bootstrap.php:303
+msgid "licenses_bsd"
+msgstr "BSD-licens"
+
+#: config/bootstrap.php:298
+msgid "licenses_gpl_2.0"
+msgstr "GNU General Public License, version 2.0"
+
+#: config/bootstrap.php:299
+msgid "licenses_gpl_3.0"
+msgstr "GNU General Public License, version 3.0"
+
+#: config/bootstrap.php:300
+msgid "licenses_lgpl_2.1"
+msgstr "GNU Lesser General Public License, version 2.1"
+
+#: config/bootstrap.php:301
+msgid "licenses_lgpl_3.0"
+msgstr "GNU Lesser General Public License, version 3.0"
+
+#: config/bootstrap.php:302
+msgid "licenses_mit"
+msgstr "MIT/X11-licens"
+
+#: config/bootstrap.php:297
+msgid "licenses_mpl_1.1"
+msgstr "Mozilla Public License, version 1.1"
+
+#: views/users/emailchange.thtml:51 views/users/delete.thtml:55
+#: views/users/delete.thtml:137 views/users/edit.thtml:74
+#: views/reviews/flag.thtml:54
+msgid "link_return_to_front_page"
+msgstr "Klik her for at komme tilbage til forsiden."
+
+#: views/elements/amo2009/addon_list_options.thtml:46
+#: views/elements/addon_list_options.thtml:46
+msgid "list_sortby_date"
+msgstr "Dato"
+
+#: views/elements/amo2009/addon_list_options.thtml:47
+#: views/elements/addon_list_options.thtml:47
+msgid "list_sortby_downloads"
+msgstr "Downloads"
+
+#: views/elements/amo2009/addon_list_options.thtml:45
+#: views/elements/addon_list_options.thtml:45
+msgid "list_sortby_name"
+msgstr "Navn"
+
+#: views/elements/amo2009/addon_list_options.thtml:48
+#: views/elements/addon_list_options.thtml:48
+msgid "list_sortby_rating"
+msgstr "Bedømmelse"
+
+#: config/bootstrap.php:278
+msgid "main_prettyname_fennec"
+msgstr "Fennec"
+
+#: config/bootstrap.php:274
+msgid "main_prettyname_firefox"
+msgstr "Firefox"
+
+#: config/bootstrap.php:277
+msgid "main_prettyname_seamonkey"
+msgstr "SeaMonkey"
+
+#: config/bootstrap.php:276
+msgid "main_prettyname_sunbird"
+msgstr "Sunbird"
+
+#: config/bootstrap.php:275
+msgid "main_prettyname_thunderbird"
+msgstr "Thunderbird"
+
+#: views/elements/addon_categories.thtml:52
+msgid "nav_category_dicts_langpacks"
+msgstr "Ordbøger & sprogpakker"
+
+#: views/elements/addon_categories.thtml:55
+msgid "nav_category_themes"
+msgstr "Temaer"
+
+#: views/elements/app_chooser.thtml:47 views/layouts/amo2009.thtml:255
+msgid "other_apps_tooltip"
+msgstr "Find tilføjelser til andre programmer"
+
+#. In a user list: user 1, user 2, "others"
+#: views/helpers/addons_html.php:222
+msgid "other_users"
+msgstr "andre"
+
+#: controllers/pages_controller.php:90
+msgid "page_title_appversions"
+msgstr "Application Versions"
+
+#: controllers/pages_controller.php:115
+#, fuzzy
+msgid "page_title_collector"
+msgstr "Add-on Collector"
+
+#: controllers/pages_controller.php:117
+#, fuzzy
+msgid "page_title_collector_faq"
+msgstr "Add-on Collector FAQ"
+
+#: controllers/pages_controller.php:119
+#, fuzzy
+msgid "page_title_collector_features"
+msgstr "Add-on Collector Features"
+
+#: controllers/pages_controller.php:122
+#, fuzzy
+msgid "page_title_collector_firstrun"
+msgstr "Welcome to the Add-on Collector"
+
+#: controllers/pages_controller.php:92
+msgid "page_title_credits"
+msgstr "Tak til"
+
+#: controllers/pages_controller.php:113
+msgid "page_title_developer_faq"
+msgstr "Developer FAQ"
+
+#: controllers/pages_controller.php:111
+msgid "page_title_faq"
+msgstr "Ofte stillede spørgsmål"
+
+#: controllers/pages_controller.php:94
+msgid "page_title_fashionyourfirefox_faq"
+msgstr "Fashion your Firefox FAQ"
+
+#: controllers/pages_controller.php:101
+msgid "page_title_policy"
+msgstr "Add-ons Policy"
+
+#: controllers/pages_controller.php:103
+msgid "page_title_privacy"
+msgstr "Mozilla Privacy Policy"
+
+#: controllers/pages_controller.php:105
+msgid "page_title_review_guide"
+msgstr "Retningslinjer for anmeldelser"
+
+#: controllers/pages_controller.php:107
+msgid "page_title_sandbox"
+msgstr "Sandkassegodkendelsessystemet"
+
+#: controllers/pages_controller.php:109
+msgid "page_title_submissionhelp"
+msgstr "Submission Help"
+
+#: views/pages/appversions.thtml:87
+msgid "pages_appversions_guid"
+msgstr "GUID"
+
+#: views/pages/appversions.thtml:79 controllers/pages_controller.php:90
+msgid "pages_appversions_header"
+msgstr "Valid Application Versions"
+
+#: views/pages/appversions.thtml:80
+msgid "pages_appversions_intro"
+msgstr ""
+"Add-ons submitted to Mozilla Add-ons must have an install.rdf file with at "
+"least one of the below applications supported. Only the versions listed "
+"below are allowed for these applications."
+
+#. %s is a full <a> tag
+#: views/pages/appversions.thtml:93
+#, php-format
+msgid "pages_appversions_required_files"
+msgstr ""
+"If your supported application does not require an install.rdf file, you "
+"still must include one with the required properties as specified %s."
+
+#. this is the text inside of an <a> tag for pages_appversions_required_files. This
+#. should be fixed.
+#: views/pages/appversions.thtml:93
+msgid "pages_appversions_required_files_link"
+msgstr "here"
+
+#: views/pages/appversions.thtml:88
+msgid "pages_appversions_versions"
+msgstr "Versions"
+
+#: views/pages/policy.thtml:51
+msgid "pages_policy_sandbox_link"
+msgstr "Sandbox Information Page"
+
+#: views/elements/pagination.thtml:53
+msgid "pagination_next_page"
+msgstr "næste"
+
+#: views/elements/pagination.thtml:52
+msgid "pagination_previous_page"
+msgstr "forrige"
+
+#: views/elements/recaptcha.thtml:65
+msgid "recaptcha_enter_both_words"
+msgstr ""
+"Indtast <strong>begge ord</strong> herunder <strong>adskilt af et mellemrum</"
+"strong>."
+
+#: views/elements/recaptcha.thtml:83
+msgid "recaptcha_enter_here"
+msgstr "Skriv ordene her:"
+
+#: views/elements/recaptcha.thtml:74
+msgid "recaptcha_enter_whatyouhear"
+msgstr "Indtast hvad du hører."
+
+#. %1 is the link switching refreshing the captcha
+#. %2 is the link switching to a text captcha
+#: views/elements/recaptcha.thtml:77
+msgid "recaptcha_hardtohear_text"
+msgstr ""
+"Hvis det er svære at høre, kan du <a href=\"%1$s\">lytte til noget andet</a> "
+"eller <a href=\"%2$s\">bruge tekst i stedet</a>."
+
+#. %1 is the link switching refreshing the captcha
+#. %2 is the link switching to an audio captcha
+#: views/elements/recaptcha.thtml:68
+msgid "recaptcha_hardtoread_text"
+msgstr ""
+"Hvis ordene er svære at læse, kan du <a href=\"%1$s\">prøve med andre ord</"
+"a> eller <a href=\"%2$s\">lytte til noget</a> i stedet."
+
+#: views/users/register.thtml:105
+msgid "recaptcha_label"
+msgstr "Er du et menneske eller en robot?"
+
+#: views/users/register.thtml:106
+msgid "recaptcha_whatsthis"
+msgstr "Hvad er dette?"
+
+#: controllers/reviews_controller.php:559
+msgid "review_flag_error"
+msgstr "Der opstod en fejl under rapporteringen af denne anmeldelse!"
+
+#: models/reviews_moderation_flag.php:69
+msgid "review_flag_reason_bug_support"
+msgstr "Fejlplaceret fejlrapport eller support-spørgsmål"
+
+#: views/reviews/display.thtml:103 views/reviews/display.thtml:186
+msgid "review_flag_reason_instructions"
+msgstr "Rapporter denne anmeldelse (vælg en begrundelse)"
+
+#: models/reviews_moderation_flag.php:67
+msgid "review_flag_reason_language"
+msgstr "Upassende sprogbrug"
+
+#: models/reviews_moderation_flag.php:71
+msgid "review_flag_reason_other"
+msgstr "Andet (angiv hvad)"
+
+#: models/reviews_moderation_flag.php:65
+msgid "review_flag_reason_spam"
+msgstr "Spam eller på anden måde ikke en anmeldelse"
+
+#: views/reviews/display.thtml:91 views/reviews/display.thtml:175
+#: controllers/reviews_controller.php:555
+msgid "review_flag_success"
+msgstr "Tak; denne anmeldelse er rapporteret til redaktørerne."
+
+#: views/reviews/display.thtml:41
+msgid "review_flag_this"
+msgstr "Rapporter denne anmeldelse"
+
+#: views/reviews/display.thtml:42
+msgid "review_flag_this_titletip"
+msgstr ""
+"Er denne anmeldelse upassende, unøjagtig eller spam? Klik her for at "
+"rapportere den til redaktørerne."
+
+#. %1 is the URL of the support section, %2 for the review guidelines
+#: views/reviews/add.thtml:53
+msgid "review_guidelines_short"
+msgstr ""
+"<p>Bemærk disse råd:</p><ul><li>Skriv som hvis du fortalte en ven om din "
+"oplevelse af tilføjelsen. Vær specifik og giv nyttige detaljer, så som ting "
+"du synes godt og dårligt om, hvor nemt det er at bruge tilføjelsen, og "
+"hvilke ulemper den har. Undgå generelle kommentarer som fx at kalde "
+"tilføjelsen \"god\" eller \"dårlig\" med mindre du kan give begrundelser.</"
+"li><li>Lad være med at rapportere fejl eller spørge om hjælp i din "
+"anmeldelse. Din e-mail-adresse er ikke synlig for udviklerne af tilføjelsen, "
+"og de kan have behov for at kontakte dig for at løse problemet. Se <a href="
+"\"%1$s\">supportsektionen</a> for at finde ud af hvor du kan få hjælp til "
+"denne tilføjelse.</li><li>Hold anmeldelsen i et høfligt sprog og indtast "
+"ikke personlig information.</li></ul><p>Læs vores <a href=\"%2$s"
+"\">retningslinjer for anmeldelser</a>, hvis du vil vide mere om "
+"brugeranmeldelser af tilføjelser.</p>"
+
+#. %1 is the add-on name
+#: views/reviews/flag.thtml:56 views/reviews/display.thtml:55
+#: views/reviews/review_added.thtml:50
+#, php-format
+msgid "reviews_header"
+msgstr "Anmeldelser af %s"
+
+#: controllers/addons_controller.php:435
+msgid "rss_featuredaddons"
+msgstr "Udmærkede tilføjelser"
+
+#: controllers/addons_controller.php:432
+msgid "rss_newestaddons"
+msgstr "Nyeste tilføjelser"
+
+#: controllers/addons_controller.php:434
+#, fuzzy
+msgid "rss_popularaddons"
+msgstr "Popular Add-ons"
+
+#: controllers/addons_controller.php:433
+msgid "rss_updatedaddons"
+msgstr "Opdaterede tilføjelser"
+
+#: views/elements/search_mini.thtml:70
+msgid "search"
+msgstr "Søg"
+
+#: views/search/collections.thtml:51
+#, fuzzy
+msgid "search_collections_header"
+msgstr "Collection Search Results"
+
+#: controllers/search_controller.php:297
+#, fuzzy
+msgid "search_collections_pagetitle"
+msgstr "Collection Search Results"
+
+#: controllers/search_controller.php:99
+msgid "search_disabled"
+msgstr "Søgning er deaktiveret i øjeblikket. Prøv igen senere."
+
+#: views/elements/amo2009/search.thtml:188 views/elements/search.thtml:187
+#: views/elements/search_mini.thtml:54
+msgid "search_form_all_addons"
+msgstr "Alle tilføjelser"
+
+#. This string is in the main category dropdown when searching
+#: views/elements/amo2009/search.thtml:204
+#, fuzzy
+msgid "search_form_all_collections"
+msgstr "all collections"
+
+#: views/elements/amo2009/search.thtml:184
+#: views/elements/amo2009/search.thtml:385
+#: views/elements/amo2009/search.thtml:408 views/elements/search.thtml:171
+#: views/elements/search.thtml:183 views/elements/search_mini.thtml:43
+#: views/elements/search_mini.thtml:49 views/layouts/mozilla.thtml:188
+msgid "search_form_default_text"
+msgstr "søg efter tilføjelser"
+
+#: views/elements/amo2009/search.thtml:184
+#: views/elements/amo2009/search.thtml:404
+#, fuzzy
+msgid "search_form_default_text_collections"
+msgstr "search for collections"
+
+#: views/elements/amo2009/search.thtml:206 views/elements/search.thtml:202
+msgid "search_form_submit_tooltip"
+msgstr "Søg efter tilføjelser"
+
+#: views/elements/amo2009/search.thtml:184 views/elements/search.thtml:183
+#: views/elements/search_mini.thtml:49
+msgid "search_form_tooltip"
+msgstr "Klik for at indtaste søgeord"
+
+#: views/elements/amo2009/search.thtml:186 views/elements/search.thtml:185
+#: views/elements/search_mini.thtml:52
+msgid "search_form_within"
+msgstr "i"
+
+#: views/addons/searchengines.thtml:118
+msgid "search_landing_all_search_engines"
+msgstr "Alle søgemaskiner"
+
+#: views/addons/searchengines.thtml:114
+msgid "search_landing_browse_search_engines"
+msgstr "Gennemse søgemaskiner"
+
+#: views/search/collections.thtml:58 views/search/index.thtml:59
+msgid "search_nothing_found"
+msgstr "Ingen resultater fundet."
+
+#: controllers/search_controller.php:185
+msgid "search_pagetitle"
+msgstr "Søg i tilføjelser"
+
+#: controllers/search_controller.php:242
+msgid "search_rss_description"
+msgstr "Feed med søgeresultater"
+
+#. %s is the terms the user is searching for (a string)
+#: controllers/search_controller.php:241
+#, php-format
+msgid "search_rss_results_for"
+msgstr "Søgeresulteter for: %s"
+
+#: views/elements/header.thtml:154 views/layouts/amo2009.thtml:296
+msgid "sidebar_navlink_admin_tools"
+msgstr "Administrationsværktøjer"
+
+#: views/elements/header.thtml:146 views/layouts/amo2009.thtml:288
+msgid "sidebar_navlink_developer_tools"
+msgstr "Udviklingsværktøjer"
+
+#: views/elements/header.thtml:148 views/layouts/amo2009.thtml:290
+msgid "sidebar_navlink_editor_tools"
+msgstr "Editor Tools"
+
+#: views/layouts/amo2009.thtml:302
+msgid "sidebar_navlink_welcome"
+msgstr "Velkommen"
+
+#. %s is the user's name
+#: views/layouts/amo2009.thtml:302
+#, php-format
+msgid "sidebar_navlink_welcome_name"
+msgstr "Velkommen %s"
+
+#: views/elements/pitch.thtml:50 views/elements/pitch.thtml:55
+msgid "sidebar_pitch_dictionary"
+msgstr "en ordbog"
+
+#: views/elements/pitch.thtml:72
+msgid "sidebar_pitch_featured_addons"
+msgstr "Anbefalede tilføjelser"
+
+#: views/elements/pitch.thtml:61
+msgid "sidebar_pitch_looking_for"
+msgstr "Jeg leder efter:"
+
+#: views/elements/pitch.thtml:70
+msgid "sidebar_pitch_newest_addons"
+msgstr "Nyeste tilføjelser"
+
+#: views/elements/pitch.thtml:49
+msgid "sidebar_pitch_search"
+msgstr "en søgetjeneste"
+
+#: views/elements/pitch.thtml:69
+msgid "sidebar_pitch_subscribe_to"
+msgstr "Abonner på"
+
+#: views/elements/pitch.thtml:48 views/elements/pitch.thtml:54
+msgid "sidebar_pitch_theme"
+msgstr "et tema"
+
+#: views/elements/pitch.thtml:71
+msgid "sidebar_pitch_updated_addons"
+msgstr "Opdaterede tilføjelser"
+
+#. %1$s is a number
+#: views/helpers/localization.php:65 views/developers/versions_edit.thtml:95
+#: views/addons/dictionaries.thtml:92
+#, php-format
+msgid "size_kb"
+msgstr "%1$s KB"
+
+#: views/elements/amo2009/stars.thtml:57 views/elements/stars.thtml:63
+msgid "stars_not_yet_rated"
+msgstr "Ikke bedømt endnu"
+
+#. %1 is the number of stars this add-on has
+#: views/elements/amo2009/stars.thtml:49 views/elements/stars.thtml:54
+#, php-format
+msgid "stars_rated_x_outof_5"
+msgstr "Bedømmelse: %s ud af 5 stjerner"
+
+#: views/statistics/addon.thtml:59
+msgid "statistics_addon_dashboard_link"
+msgstr "Dashboard Home"
+
+#: views/statistics/addon.thtml:58
+msgid "statistics_addon_developertools_link"
+msgstr "Developer Tools"
+
+#: views/statistics/addon.thtml:53
+msgid "statistics_addon_switch"
+msgstr "Switch Add-on"
+
+#. This is a date format.
+#. http://php.net/strftime
+#: views/statistics/rss/summary.thtml:54 views/statistics/addon.thtml:181
+msgid "statistics_date_shortmonth"
+msgstr "%b. %e"
+
+#. This is a date format.
+#. http://php.net/strftime
+#: views/statistics/rss/summary.thtml:40 views/statistics/addon.thtml:152
+msgid "statistics_date_shortmonthwithyear"
+msgstr "%b. %e, %Y"
+
+#. This is a date format.
+#. http://php.net/strftime
+#: views/statistics/rss/summary.thtml:41 views/statistics/rss/summary.thtml:48
+#: views/statistics/addon.thtml:161 views/statistics/addon.thtml:172
+msgid "statistics_date_weekdayshortmonth"
+msgstr "%A, %b. %e"
+
+#. %1$s is an add-on name and version. Example: Add-on 3.5
+#: controllers/components/stats.php:519
+#, php-format
+msgid "statistics_events_addon_created"
+msgstr "%1$s created"
+
+#. %1$s is an application name and version. Example: Firefox 3.5
+#: controllers/components/stats.php:500
+#, php-format
+msgid "statistics_events_app_released"
+msgstr "%1$s released"
+
+#: views/statistics/addon.thtml:71
+msgid "statistics_help_close_link"
+msgstr "Close"
+
+#: views/statistics/addon.thtml:60
+msgid "statistics_help_link"
+msgstr "Help"
+
+#: views/statistics/index.thtml:83
+msgid "statistics_index_anotheraddon"
+msgstr "or, select another add-on"
+
+#: views/statistics/index.thtml:85
+msgid "statistics_index_anotheraddon_public"
+msgstr "or, select an add-on with public statistics"
+
+#: views/statistics/index.thtml:71
+msgid "statistics_index_myaddons"
+msgstr "Select one of your add-ons to view its statistics"
+
+#: views/statistics/index.thtml:89
+msgid "statistics_index_selectaddon"
+msgstr "Select an add-on to view its statistics"
+
+#: views/statistics/index.thtml:91
+msgid "statistics_index_selectaddon_public"
+msgstr "Select an add-on with public statistics"
+
+#: views/statistics/index.thtml:39
+msgid "statistics_index_title"
+msgstr "Statistics Dashboard"
+
+#: views/statistics/index.thtml:97
+msgid "statistics_index_view_button"
+msgstr "View Statistics"
+
+#: views/statistics/addon.thtml:222 controllers/statistics_controller.php:247
+msgid "statistics_js_download_csv"
+msgstr "View this table in CSV format"
+
+#: controllers/statistics_controller.php:246
+msgid "statistics_js_dropdowns_none"
+msgstr "none"
+
+#: controllers/statistics_controller.php:245
+msgid "statistics_js_dropdowns_removeplot"
+msgstr "Remove this plot"
+
+#: controllers/statistics_controller.php:248
+msgid "statistics_js_groupby_selector_date"
+msgstr "Group by: Day"
+
+#: controllers/statistics_controller.php:251
+msgid "statistics_js_groupby_selector_month"
+msgstr "Group by: Month"
+
+#: controllers/statistics_controller.php:249
+msgid "statistics_js_groupby_selector_week"
+msgstr "Group by: Week"
+
+#: controllers/statistics_controller.php:250
+msgid "statistics_js_groupby_selector_week_over_week"
+msgstr "Compare by: Week"
+
+#: controllers/statistics_controller.php:260
+msgid "statistics_js_plotselection_foundinrange"
+msgstr "%s found in range"
+
+#: controllers/statistics_controller.php:270
+msgid "statistics_js_plotselection_options_addplot_name"
+msgstr "Add Plot"
+
+#: controllers/statistics_controller.php:271
+msgid "statistics_js_plotselection_options_addplot_tooltip"
+msgstr "Add another plot to this graph"
+
+#: controllers/statistics_controller.php:261
+msgid "statistics_js_plotselection_options_count_name_checked"
+msgstr "Hide Total Count"
+
+#: controllers/statistics_controller.php:262
+msgid "statistics_js_plotselection_options_count_name_unchecked"
+msgstr "Show Total Count"
+
+#: controllers/statistics_controller.php:263
+msgid "statistics_js_plotselection_options_count_tooltip"
+msgstr "Plot the total count on this graph"
+
+#: controllers/statistics_controller.php:275
+msgid "statistics_js_plotselection_options_csv_name"
+msgstr "View Data (CSV)"
+
+#: controllers/statistics_controller.php:276
+msgid "statistics_js_plotselection_options_csv_tooltip"
+msgstr "Get a Comma Separated Values file of this data"
+
+#: controllers/statistics_controller.php:267
+msgid "statistics_js_plotselection_options_events_addon_name_checked"
+msgstr "Hide %s Events"
+
+#: controllers/statistics_controller.php:268
+msgid "statistics_js_plotselection_options_events_addon_name_unchecked"
+msgstr "Show %s Events"
+
+#: controllers/statistics_controller.php:269
+msgid "statistics_js_plotselection_options_events_addon_tooltip"
+msgstr "Overlay add-on release dates on the plots"
+
+#: controllers/statistics_controller.php:264
+msgid "statistics_js_plotselection_options_events_firefox_name_checked"
+msgstr "Hide Firefox Events"
+
+#: controllers/statistics_controller.php:265
+msgid "statistics_js_plotselection_options_events_firefox_name_unchecked"
+msgstr "Show Firefox Events"
+
+#: controllers/statistics_controller.php:266
+msgid "statistics_js_plotselection_options_events_firefox_tooltip"
+msgstr "Overlay Firefox release dates on the plots"
+
+#: controllers/statistics_controller.php:272
+msgid "statistics_js_plotselection_options_resize_name_checked"
+msgstr "Collapse Graph"
+
+#: controllers/statistics_controller.php:273
+msgid "statistics_js_plotselection_options_resize_name_unchecked"
+msgstr "Expand Graph"
+
+#: controllers/statistics_controller.php:274
+msgid "statistics_js_plotselection_options_resize_tooltip"
+msgstr "Resize the graph"
+
+#: controllers/statistics_controller.php:254
+msgid "statistics_js_plotselection_selector_adu"
+msgstr "Active Daily Users"
+
+#: controllers/statistics_controller.php:256
+msgid "statistics_js_plotselection_selector_application"
+msgstr "Application"
+
+#: controllers/statistics_controller.php:259
+msgid "statistics_js_plotselection_selector_custom"
+msgstr "Custom"
+
+#: controllers/statistics_controller.php:253
+msgid "statistics_js_plotselection_selector_downloads"
+msgstr "Downloads"
+
+#: controllers/statistics_controller.php:258
+msgid "statistics_js_plotselection_selector_os"
+msgstr "Operating System"
+
+#: controllers/statistics_controller.php:257
+msgid "statistics_js_plotselection_selector_status"
+msgstr "Add-on Status"
+
+#: controllers/statistics_controller.php:252
+msgid "statistics_js_plotselection_selector_summary"
+msgstr "Summary"
+
+#: controllers/statistics_controller.php:255
+msgid "statistics_js_plotselection_selector_version"
+msgstr "Add-on Version"
+
+#: controllers/components/stats.php:398
+msgid "statistics_longnames_application"
+msgstr "Application"
+
+#: controllers/components/stats.php:400
+msgid "statistics_longnames_os"
+msgstr "Operating System"
+
+#: controllers/components/stats.php:399
+msgid "statistics_longnames_status"
+msgstr "Add-on Status"
+
+#: controllers/components/stats.php:401
+msgid "statistics_longnames_unknown"
+msgstr "Unknown"
+
+#: controllers/components/stats.php:397
+msgid "statistics_longnames_version"
+msgstr "Add-on Version"
+
+#: views/statistics/addon.thtml:118
+msgid "statistics_notice_data_insufficient"
+msgstr ""
+"There is not yet enough data to display this graph. Please check back later."
+
+#: views/statistics/addon.thtml:130
+msgid "statistics_notice_data_none"
+msgstr ""
+"We don't have any data for your add-on yet. Please check back in a few days."
+
+#: views/statistics/addon.thtml:41
+msgid "statistics_notice_data_updating"
+msgstr ""
+"Add-on statistics are currently in the process of being updated. Recent data "
+"may be incomplete as our scripts work to update this information. Please "
+"check back in a few minutes."
+
+#: views/statistics/addon.thtml:136
+msgid "statistics_notice_disabled"
+msgstr ""
+"The Statistics Dashboard is currently disabled. Please check back later."
+
+#: views/statistics/addon.thtml:123
+msgid "statistics_notice_nojavascript"
+msgstr "JavaScript is required to view the Statistics Dashboard graphs."
+
+#: views/statistics/addon.thtml:44
+msgid "statistics_notice_settings_updated"
+msgstr "Your settings have been updated!"
+
+#: controllers/statistics_controller.php:60
+#: controllers/statistics_controller.php:71
+#: controllers/statistics_controller.php:74
+#: controllers/statistics_controller.php:240
+msgid "statistics_pagetitle"
+msgstr "Statistics Dashboard"
+
+#: views/statistics/addon.thtml:99
+msgid "statistics_plot_legend_adu"
+msgstr "Active Daily Users"
+
+#: views/statistics/addon.thtml:95
+msgid "statistics_plot_legend_downloads"
+msgstr "Daily Downloads"
+
+#: views/statistics/addon.thtml:107
+msgid "statistics_plot_options_zoomin_alt"
+msgstr "Zoom In"
+
+#: views/statistics/addon.thtml:106
+msgid "statistics_plot_options_zoomin_title"
+msgstr "Zoom in one month"
+
+#: views/statistics/addon.thtml:110
+msgid "statistics_plot_options_zoomout_alt"
+msgstr "Zoom Out"
+
+#: views/statistics/addon.thtml:109
+msgid "statistics_plot_options_zoomout_title"
+msgstr "Zoom out one month"
+
+#: controllers/statistics_controller.php:283
+#, php-format
+msgid "statistics_rss_description"
+msgstr "Daily summary of statistics for %1$s"
+
+#: views/statistics/rss/summary.thtml:68
+msgid "statistics_rss_title_fulldate"
+msgstr "%A, %B %e, %Y"
+
+#: views/statistics/rss/summary.thtml:68
+#, php-format
+msgid "statistics_rss_title_statsfordate"
+msgstr "Statistics for %1$s"
+
+#: views/statistics/settings.thtml:49
+msgid "statistics_settings_access_description"
+msgstr ""
+"By default, only you and Mozilla can access the information in your "
+"dashboard. You can open this up to the public so that anyone can view your "
+"add-on's data."
+
+#: views/statistics/settings.thtml:48
+msgid "statistics_settings_access_heading"
+msgstr "Dashboard Access"
+
+#: views/statistics/settings.thtml:51
+msgid "statistics_settings_access_private"
+msgstr "Private"
+
+#: views/statistics/settings.thtml:51
+msgid "statistics_settings_access_private_description"
+msgstr "Only you and Mozilla can view this add-on's statistics"
+
+#: views/statistics/settings.thtml:52
+msgid "statistics_settings_access_public"
+msgstr "Public"
+
+#: views/statistics/settings.thtml:52
+msgid "statistics_settings_access_public_description"
+msgstr "Anyone can view this add-on's statistics"
+
+#: views/statistics/addon.thtml:251
+msgid "statistics_settings_change_link"
+msgstr "Change Settings"
+
+#: views/statistics/addon.thtml:253
+msgid "statistics_settings_confidential"
+msgstr "Please treat this information as confidential."
+
+#: views/statistics/addon.thtml:245
+msgid "statistics_settings_currently_private"
+msgstr "This dashboard is currently <b>private</b>."
+
+#: views/statistics/addon.thtml:241
+msgid "statistics_settings_currently_public"
+msgstr "This dashboard is currently <b>public</b>."
+
+#: views/statistics/addon.thtml:246
+msgid "statistics_settings_locked_alt"
+msgstr "Locked"
+
+#: views/statistics/settings.thtml:57
+msgid "statistics_settings_return_link"
+msgstr "Return to Dashboard"
+
+#: views/statistics/settings.thtml:56
+msgid "statistics_settings_save_button"
+msgstr "Save Settings"
+
+#: views/statistics/settings.thtml:46
+#, php-format
+msgid "statistics_settings_title"
+msgstr "Statistics Dashboard Settings for %1$s"
+
+#: views/statistics/addon.thtml:242
+msgid "statistics_settings_unlocked_alt"
+msgstr "Unlocked"
+
+#: controllers/components/stats.php:405
+msgid "statistics_shortnames_application"
+msgstr "App"
+
+#: controllers/components/stats.php:407
+msgid "statistics_shortnames_os"
+msgstr "OS"
+
+#: controllers/components/stats.php:406
+msgid "statistics_shortnames_status"
+msgstr "St"
+
+#: controllers/components/stats.php:408
+msgid "statistics_shortnames_unknown"
+msgstr "Uk"
+
+#: controllers/components/stats.php:404
+msgid "statistics_shortnames_version"
+msgstr "Ver"
+
+#: views/statistics/rss/summary.thtml:42 views/statistics/addon.thtml:192
+msgid "statistics_summary_downloads_average"
+msgstr "Average Daily Downloads"
+
+#: views/statistics/rss/summary.thtml:39
+msgid "statistics_summary_downloads_heading"
+msgstr "Downloads"
+
+#: views/statistics/rss/summary.thtml:41 views/statistics/addon.thtml:171
+msgid "statistics_summary_downloads_lastcount"
+msgstr "Last Day Count"
+
+#: views/statistics/rss/summary.thtml:43 views/statistics/addon.thtml:199
+msgid "statistics_summary_downloads_lastweek"
+msgstr "Downloads in the last 7 days"
+
+#: views/statistics/rss/summary.thtml:40 views/statistics/addon.thtml:151
+msgid "statistics_summary_downloads_total"
+msgstr "Total Downloads"
+
+#: views/statistics/rss/summary.thtml:40 views/statistics/addon.thtml:152
+#, php-format
+msgid "statistics_summary_downloads_total_sincedate"
+msgstr "Since %1$s"
+
+#: views/statistics/rss/summary.thtml:50 views/statistics/rss/summary.thtml:56
+#: views/statistics/addon.thtml:163 views/statistics/addon.thtml:183
+msgid "statistics_summary_nodata"
+msgstr "No data yet"
+
+#: views/statistics/rss/summary.thtml:60 views/statistics/addon.thtml:195
+msgid "statistics_summary_updatepings_average"
+msgstr "Average Daily Active Users"
+
+#: views/statistics/rss/summary.thtml:52 views/statistics/addon.thtml:177
+msgid "statistics_summary_updatepings_changefromprevious"
+msgstr "Change from previous count"
+
+#: views/statistics/rss/summary.thtml:54 views/statistics/addon.thtml:181
+#, php-format
+msgid "statistics_summary_updatepings_changefromprevious_ondate"
+msgstr "%1$s on %2$s"
+
+#: views/statistics/rss/summary.thtml:45
+msgid "statistics_summary_updatepings_heading"
+msgstr "Active Daily Users"
+
+#: views/statistics/rss/summary.thtml:46 views/statistics/addon.thtml:157
+msgid "statistics_summary_updatepings_total"
+msgstr "Active Daily Users"
+
+#: views/statistics/rss/summary.thtml:48 views/statistics/addon.thtml:161
+#, php-format
+msgid "statistics_summary_updatepings_total_ondate"
+msgstr "On %1$s"
+
+#: views/statistics/rss/summary.thtml:61 views/statistics/addon.thtml:203
+msgid "statistics_summary_updatepings_weekly_average"
+msgstr "Average Daily Users this Week"
+
+#. %s is a percentage, like '+22.33%'. It sits next to another number, so
+#. the implied meaning is 'percentage change' from the previous stat point.
+#: views/statistics/rss/summary.thtml:62 views/statistics/addon.thtml:205
+msgid "statistics_summary_updatepings_weekly_change"
+msgstr "%s from last week"
+
+#: views/statistics/addon.thtml:65 controllers/statistics_controller.php:184
+#: controllers/statistics_controller.php:282
+#, php-format
+msgid "statistics_title_addon_stats"
+msgstr "%1$s Statistics"
+
+#: views/addons/themes_landing.thtml:113
+msgid "themes_landing_all_themes"
+msgstr "Alle temaer"
+
+#: views/addons/themes_landing.thtml:109
+msgid "themes_landing_browse_themes"
+msgstr "Gennemse temaer"
+
+#: views/users/edit.thtml:185
+msgid "user_change_email"
+msgstr "Skift e-mail-adresse"
+
+#: views/users/edit.thtml:169
+msgid "user_change_password"
+msgstr "Skift adgangskode"
+
+#: views/users/edit.thtml:96
+#, fuzzy
+msgid "user_change_password_or_email"
+msgstr "Change Password or Email"
+
+#: controllers/users_controller.php:197
+msgid "user_confirmationcode_resent"
+msgstr "Bekræftelseskoden er sendt igen!"
+
+#. %1 is the email address, %2 is the URL of the user registration page
+#: views/users/delete.thtml:51
+msgid "user_del_account_deleted"
+msgstr ""
+"Din konto, %1$s, er nu slettet. Hvis du ønsker at vende tilbage en anden "
+"gang, kan du registrere dig igen på <a href=\"%2$s"
+"\">brugerregistreringssiden</a>."
+
+#: views/users/delete.thtml:102
+msgid "user_del_community_sad"
+msgstr "Fællesskabet omkring Mozilla Add-ons er kede af at se dig gå."
+
+#: views/users/delete.thtml:123
+msgid "user_del_confirm_password"
+msgstr "Bekræft adgangskode"
+
+#: views/users/delete.thtml:134
+msgid "user_del_deletenow"
+msgstr "Slet min konto nu"
+
+#. %1 is the URL of the user's info page
+#: views/users/delete.thtml:64
+msgid "user_del_error_addons"
+msgstr ""
+"Du kan ikke slette din konto, hvis du står listet som en <a href=\"%1$s"
+"\">forfatter af en eller flere tilføjelser</a>. For at slette din konto er "
+"du nødt til at få en anden person i din udviklergruppe til at slette dig "
+"fra listen over forfattere til dine tilføjelser. Derefter kan du slette din "
+"konto her."
+
+#. %1 is a link to the amo-editors mailing list
+#: views/users/delete.thtml:71
+msgid "user_del_error_addons_more_questions"
+msgstr ""
+"Har du yderligere spørgsmål, kan du kontakte %1$s for mere information."
+
+#: views/users/delete.thtml:78
+msgid "user_del_error_checkbox"
+msgstr ""
+"Du skal sætte markering i boksen \"Jeg forstår...\" før vi kan slette din "
+"konto."
+
+#: views/users/delete.thtml:84
+msgid "user_del_error_password"
+msgstr "Kontoen blev ikke slettet, da den angivne adgangskode er forkert."
+
+#. %1 is a link to the amo-admins mailing list
+#: views/users/delete.thtml:91
+msgid "user_del_error_unknown"
+msgstr ""
+"En ukendt fejl opstod under sletningen af din konto. Kontakt venligst %1$s "
+"vedrørende dette problem, og vi vil slette kontoen for dig. Vi beklager "
+"ulejligheden."
+
+#: views/users/delete.thtml:110
+msgid "user_del_header_confirm_deletion"
+msgstr "Bekræft sletning af konto"
+
+#. %1 is the user's email address
+#: views/users/delete.thtml:100
+msgid "user_del_header_delete_account"
+msgstr "Slet kontoen %1$s"
+
+#: views/users/delete.thtml:50
+msgid "user_del_header_farewell"
+msgstr "Farvel!"
+
+#: views/users/delete.thtml:115
+msgid "user_del_nologin"
+msgstr "Du vil fremover ikke kunne logge ind på Mozilla Add-ons."
+
+#: views/users/delete.thtml:112
+msgid "user_del_permanently_removed_means"
+msgstr ""
+"Ved at klikke på \"slet\" vil du slette din konto <strong>permanent</"
+"strong>. Dette betyder:"
+
+#: views/users/delete.thtml:116
+msgid "user_del_reviews_anonymized"
+msgstr ""
+"Dine anmeldelser og bedømmelser vil ikke blive slettet, men de vil ikke "
+"længere være knyttet til dig."
+
+#. %1 is a link to the amo-editors mailing list
+#: views/users/delete.thtml:104
+msgid "user_del_specific_problem_editors"
+msgstr ""
+"Har du et specifikt problem, som vi kan hjælpe med, bør du ikke slette din "
+"konto nu, men i stedet kontakte os på %1$s, og vi vil gøre vores bedste for "
+"at hjælpe dig med at løse problemet."
+
+#: views/users/delete.thtml:130
+msgid "user_del_understand_permanent"
+msgstr "Jeg forstår at dette trin ikke kan annulleres."
+
+#: views/helpers/addons_html.php:192
+msgid "user_deleted_nickname"
+msgstr "Slettet bruger"
+
+#. %1 is the new email address
+#: views/users/edit.thtml:71
+msgid "user_edit_confirm_email_sent"
+msgstr ""
+"En e-mail er sendt til %1$s for at bekræfte din nye e-mail-adresse. Før "
+"ændringen kan gennemføres, skal du klikke på linket i denne mail. Indtil da "
+"skal du fortsat bruge din nuværende e-mail-adresse til at logge ind."
+
+#: views/users/edit.thtml:201
+msgid "user_edit_delete_user"
+msgstr "Slet konto"
+
+#. This contains the email sent to users when they signed up for a new
+#. account:
+#. %1 is the confirmation URL, %2 is the current app
+#: views/users/email/confirm_plain.thtml:6
+#, php-format
+msgid "user_email_confirm_account_nopass"
+msgstr ""
+"Velkommen til %2$s Add-ons.\n"
+"\n"
+"Før du kan bruge din nye konto, skal du aktivere den - det sikrer, at den "
+"anvendte e-mail-adresse er gyldig og tilhører dig.\n"
+"For at aktivere din konto skal du klikke på linket herunder eller kopiere "
+"hele linket ind i din browsers adresselinje:\n"
+"\n"
+"%1$s\n"
+"\n"
+"Når du har aktiveret din konto, kan du smide denne e-mail væk.\n"
+"\n"
+"Tak fordi du tilmeldte dig %2$s Add-ons\n"
+"-- %2$s Add-ons"
+
+#. %1 is the confirmation url, %2 is the application name
+#: views/users/email/emailchange_plain.thtml:5
+msgid "user_email_confirm_emailchange"
+msgstr ""
+"Du anmodede om at ændre din e-mail-adresse hos %2$s Add-ons.\n"
+"\n"
+"For at bekræfte din nye adresse, bedes du klikke på linket herunder eller "
+"kopiere det hele ind i din browsers adresselinje:\n"
+"\n"
+"%1$s\n"
+"\n"
+"Du har to døgn til at bekræfte din nye adresse. Hvis du alligevel ikke "
+"ønsker at ændre din adresse, kan du bare ignorere denne e-mail.\n"
+"\n"
+"Tak!\n"
+"-- %2$s Add-ons"
+
+#: controllers/users_controller.php:168
+#, php-format
+msgid "user_email_confirm_subject"
+msgstr "Tak fordi du tilmeldte dig %s Add-ons"
+
+#. This is the password reset email
+#. %1 is the pw reset URL, %2 is the application
+#: views/users/email/pwreset_plain.thtml:5
+#, php-format
+msgid "user_email_pwreset"
+msgstr ""
+"Nulstilling af adgangskode til %2$s Add-ons\n"
+"\n"
+"Vi modtog en anmodning om at nulstille adgangskoden for denne konto på "
+"addons.mozilla.org. For at ændre din adgangskode bedes du klikke på følgende "
+"link eller kopiere det ind i din browsers adresselinje:\n"
+"\n"
+"%1$s\n"
+"\n"
+"Har du ikke anmodet om denne e-mail, skal du ikke foretage dig noget "
+"yderligere.\n"
+"\n"
+"Tak,\n"
+"-- %2$s Add-ons"
+
+#: controllers/users_controller.php:245
+#, php-format
+msgid "user_email_pwreset_subject"
+msgstr "Nulstil din adgangskode til %s Add-ons"
+
+#: views/users/emailchange.thtml:50
+msgid "user_emailchange_error"
+msgstr "Fejl!"
+
+#. %1 is the application name
+#: controllers/users_controller.php:533
+msgid "user_emailchange_subject"
+msgstr "Bekræft ændring af e-mail-adresse hos %1$s Add-ons"
+
+#: views/users/emailchange.thtml:48
+msgid "user_emailchange_success"
+msgstr "Succes!"
+
+#. %1 is the new email address
+#: views/users/emailchange.thtml:49
+msgid "user_emailchange_successful_description"
+msgstr ""
+"Din e-mail-adresse blev ændret. Fra nu af skal du bruge %1$s for at logge "
+"ind."
+
+#: views/users/edit.thtml:134 views/admin/users_edit.thtml:111
+msgid "user_form_bio"
+msgstr "Om mig"
+
+#: views/users/edit.thtml:135 views/admin/users_edit.thtml:112
+msgid "user_form_bio_description"
+msgstr ""
+"Introducer dig selv til fællesskabet, hvis du vil! Denne tekst vil blive "
+"vist offentligt op din brugerside. Linjeskift bevares, men HTML tillades "
+"ikke."
+
+#: views/users/pwreset.thtml:77 views/users/register.thtml:73
+#: views/users/edit.thtml:181
+msgid "user_form_confirmpassword"
+msgstr "Bekræft adgangskode"
+
+#: views/users/edit.thtml:145
+#, fuzzy
+msgid "user_form_display_collections"
+msgstr "Display the collections I have created in my user profile"
+
+#: views/users/edit.thtml:149
+#, fuzzy
+msgid "user_form_display_collections_fav"
+msgstr "Display my favorite collections in my user profile"
+
+#: views/users/edit.thtml:86
+#, php-format
+msgid "user_form_editprofile"
+msgstr "Ret brugerprofil for %s"
+
+#: views/users/pwreset.thtml:52 views/users/login.thtml:81
+#: views/users/register.thtml:63 views/users/edit.thtml:187
+msgid "user_form_email"
+msgstr "E-mail-adresse"
+
+#: views/users/register.thtml:78 views/users/edit.thtml:103
+#: views/admin/users_edit.thtml:76
+msgid "user_form_firstname"
+msgstr "Fornavn"
+
+#: views/users/register.thtml:94 views/users/edit.thtml:119
+#: views/admin/users_edit.thtml:91
+msgid "user_form_hideemail"
+msgstr "Skjul e-mail-adresse"
+
+#: views/users/register.thtml:98 views/users/edit.thtml:123
+#: views/admin/users_edit.thtml:99
+msgid "user_form_homepage"
+msgstr "Website URL"
+
+#: views/users/register.thtml:84 views/users/edit.thtml:109
+#: views/admin/users_edit.thtml:81
+msgid "user_form_lastname"
+msgstr "Efternavn"
+
+#: controllers/users_controller.php:333
+msgid "user_form_login"
+msgstr "Brugerlogin"
+
+#: views/users/pwreset.thtml:72 views/users/edit.thtml:176
+msgid "user_form_newpassword"
+msgstr "Ny adgangskode"
+
+#: views/users/register.thtml:89 views/users/edit.thtml:114
+#: views/admin/users_edit.thtml:86
+msgid "user_form_nickname"
+msgstr "Kaldenavn"
+
+#: views/users/edit.thtml:171
+msgid "user_form_oldpassword"
+msgstr "Gammel adgangskode"
+
+#: views/users/edit.thtml:97 views/users/edit.thtml:200
+msgid "user_form_otheractions"
+msgstr "Andre muligheder"
+
+#: views/users/login.thtml:85 views/users/register.thtml:68
+msgid "user_form_password"
+msgstr "Adgangskode"
+
+#: controllers/users_controller.php:93
+msgid "user_form_registration"
+msgstr "Registrering af ny bruger"
+
+#: views/users/login.thtml:90
+msgid "user_form_remember_me"
+msgstr "Husk mig på denne computer"
+
+#: views/admin/users_edit.thtml:95
+msgid "user_form_showsandbox"
+msgstr "Vis sandkasse?"
+
+#: views/users/edit.thtml:205
+msgid "user_form_submit_edit"
+msgstr "Gem"
+
+#: views/users/login.thtml:93
+msgid "user_form_submit_login"
+msgstr "Log ind"
+
+#: views/users/register.thtml:113
+msgid "user_form_submit_register"
+msgstr "Registrer"
+
+#: views/users/info.thtml:75
+#, php-format
+msgid "user_info_usersince"
+msgstr "Bruger af %s Add-ons siden"
+
+#: views/users/login.thtml:102
+msgid "user_login_register_link"
+msgstr "Opret ny brugerkonto"
+
+#: views/users/edit.thtml:160
+msgid "user_notifications_item_compat"
+msgstr "Kompatibilitet vedrørende tilføjelser (anbefales kraftigt)"
+
+#: views/users/edit.thtml:161
+msgid "user_notifications_item_events"
+msgstr "Kommende begivenheder og konkurrencer"
+
+#: views/users/edit.thtml:156
+msgid "user_notifications_none_available"
+msgstr "Der er i øjeblikket ingen beskeder, som du kan kan konfigurere."
+
+#: views/users/edit.thtml:158
+msgid "user_notifications_select_topics"
+msgstr ""
+"Mozilla kan af og til sende e-mails vedrørende kommende udgivelser og "
+"begivenheder relateret til tilføjelser. Vælg hvad du er interesseret i "
+"herunder:"
+
+#: views/users/edit.thtml:164
+msgid "user_notifications_specific_contact"
+msgstr ""
+"Mozilla forbeholder sig retten til at kontakte dig individuelt vedrørende "
+"dine tilføjelser, som er hostet her."
+
+#: controllers/users_controller.php:543
+msgid "user_profile_edit_error"
+msgstr ""
+"Der var fejl i de indtastede ændringer. Ret dem venligst og indsend igen."
+
+#: controllers/users_controller.php:540
+msgid "user_profile_saved"
+msgstr "Profil opdateret."
+
+#: views/users/pwreset.thtml:65
+#, php-format
+msgid "user_pwreset_for_email"
+msgstr "Adgangskode nulstillet for %s"
+
+#: controllers/users_controller.php:226
+msgid "user_pwreset_header"
+msgstr "Adgangskode nulstillet"
+
+#: views/users/login.thtml:103
+msgid "user_pwreset_link"
+msgstr "Har du glemt din adgangskode?"
+
+#: controllers/users_controller.php:248
+msgid "user_pwreset_link_sent"
+msgstr "Linket til nulstilling af adgangskode er sendt til din e-mail-adresse."
+
+#: controllers/users_controller.php:304
+msgid "user_pwreset_okay"
+msgstr "Adgangskoden blev nulstillet."
+
+#: views/users/pwreset.thtml:82
+msgid "user_pwreset_submit_changepw"
+msgstr "Indsend ændring af adgangskode"
+
+#: views/users/pwreset.thtml:57
+msgid "user_pwreset_submit_sendlink"
+msgstr "Send link til ændring af adgangskode"
+
+#: views/users/register_complete.thtml:51
+#, php-format
+msgid "user_register_amo_link"
+msgstr "%s Add-ons"
+
+#. %1 is the user's email address, %2 is the current app
+#: views/users/activatefirst.thtml:49
+#, php-format
+msgid "user_register_click_confirm_link"
+msgstr ""
+"Et link til aktivering af din brugerkonto er sendt af sted via e-mail til "
+"din adresse, %1$s. Du skal klikke på linket i denne e-mail, før du kan logge "
+"ind på %2$s Add-ons."
+
+#. %1 is the user's email address
+#: views/users/register_complete.thtml:49
+#, php-format
+msgid "user_register_confirm_email_sent"
+msgstr ""
+"En e-mail er sendt af sted til din adresse, %1$s, for at bekræfte din konto. "
+"Før du kan logge ind, skal du aktivere kontoen ved at klikke på linket i e-"
+"mailen."
+
+#: views/users/activatefirst.thtml:51
+msgid "user_register_confirmation_link_text"
+msgstr "sende bekræftelsesmeddelelsen igen"
+
+#: views/users/register_complete.thtml:47
+msgid "user_register_congratulations"
+msgstr "Tillykke! Din brugerkonto er nu oprettet."
+
+#: views/users/register.thtml:50
+msgid "user_register_details"
+msgstr ""
+"<p>Registrering på AMO er <strong>ikke påkrævet</strong> hvis du bare vil "
+"hente og installere offentlige tilføjelser.</p><p>Du behøver kun at "
+"registrere, hvis:</p><ul><li>Du vil indsende anmeldelser af tilføjelser</"
+"li><li>Du er udvikler af en tilføjelse og ønsker at uploade den til hosting "
+"på AMO</li></ul><p>Ved succesfuld registrering vil du få tilsendt en "
+"bekræftelsesmail til den adresse du opgav. Følg instruktionerne i mailen for "
+"at bekræfte din konto.</p><p>Hvis du vil, kan du læse vores <a href='%1$s' "
+"title='Juridiske betingelser'>juridiske betingelser</a> og <a href='%2$s' "
+"title='Privatlivspolitik'>privatlivspolitik</a>.</p>"
+
+#. %1 is the link to the "resend confirmation code" page
+#: views/users/activatefirst.thtml:51
+#, php-format
+msgid "user_register_resend_confirmation_link"
+msgstr ""
+"Hvis du ikke modtog bekræftelsesmailen, bør du kontrollere, at din "
+"maiservice ikke markerede den som \"spam\". Har du behov for det, kan vi %1"
+"$s til din e-mail-adresse, som står herover."
+
+#. %1 is the link to the Mozilla Add-ons front page
+#: views/users/register_complete.thtml:51
+#, php-format
+msgid "user_register_welcome"
+msgstr "Tak fordi du registrerede dig og velkommen til %1$s!"
+
+#: views/users/register.thtml:49
+msgid "user_register_welcome_header"
+msgstr "Velkommen til addons.mozilla.org (AMO)!"
+
+#: views/users/register.thtml:81 views/users/edit.thtml:106
+msgid "user_required_firstlast_or_nickname"
+msgstr "Et fornavn, efternavn eller kaldenavn skal angives."
+
+#: views/users/edit.thtml:94 views/users/edit.thtml:142
+#, fuzzy
+msgid "user_tab_collections"
+msgstr "Collections"
+
+#: views/users/edit.thtml:95 views/users/edit.thtml:154
+msgid "user_tab_notifications"
+msgstr "Beskeder"
+
+#: views/users/edit.thtml:93 views/users/edit.thtml:101
+msgid "user_tab_profile"
+msgstr "Brugerprofil"
+
+#: controllers/users_controller.php:209
+msgid "user_verified_okay"
+msgstr "Godkendt!"
+
+#: controllers/users_controller.php:723
+msgid "users_delete_pagetitle"
+msgstr "Slet konto"
+
+#: controllers/users_controller.php:414
+msgid "users_edit_pagetitle"
+msgstr "Redigering af brugerkonto"
+
+#: views/users/info.thtml:71
+msgid "users_info_aboutme"
+msgstr "Om mig"
+
+#: views/users/info.thtml:96
+#, php-format
+msgid "users_info_addons_by_user"
+msgstr "Tilføjelser fra %1$s"
+
+#: views/users/info.thtml:51
+msgid "users_info_author_name"
+msgstr "Navn"
+
+#: views/users/info.thtml:48
+msgid "users_info_author_profile"
+msgstr "Brugerprofil"
+
+#. %s is the user name
+#: views/users/info.thtml:137
+#, fuzzy
+msgid "users_info_collections_by_user"
+msgstr "Collections by %s"
+
+#: views/users/info.thtml:66
+msgid "users_info_email"
+msgstr "E-mail-adresser"
+
+#: views/users/info.thtml:155
+#, fuzzy
+msgid "users_info_fav_collections_by_user"
+msgstr "Favorite Collections"
+
+#: views/users/info.thtml:61
+msgid "users_info_homepage"
+msgstr "Hjemmeside"
+
+#: views/users/info.thtml:56
+msgid "users_info_nickname"
+msgstr "Kaldenavn"
+
+#: controllers/users_controller.php:707
+#, php-format
+msgid "users_info_pagetitle"
+msgstr "Brugerinfo om %1$s"
+
+#. %1 is the user's name
+#: views/users/info.thtml:116
+msgid "users_info_reviews_by_user"
+msgstr "Anmeldelser skrevet af %s"
+
+#: controllers/users_controller.php:330 controllers/users_controller.php:332
+msgid "users_login_pagetitle"
+msgstr "Log ind"
+
+#. %1 is the link to the sandbox/policy explanation page
+#. This message is for a specific add-on not found
+#: views/users/login.thtml:53
+#, php-format
+msgid "users_login_sandbox_display_warning"
+msgstr ""
+"Den ønskede tilføjelse befinder sig i øjeblikket i sandkassen. Har du "
+"allerede en konto hos Mozilla Add-ons, bedes du logge ind, eller du kan <a "
+"href=\"%1$s\">lære mere om sandkassen.</a>"
+
+#. %1 is the link to the sandbox/policy explanation page
+#. This message is for any given sandbox-related page not found
+#: views/users/login.thtml:56
+#, php-format
+msgid "users_login_sandbox_page_warning"
+msgstr ""
+"Den ønskede side er en del af sandkassen. Har du allerede en konto hos "
+"Mozilla Add-ons, bedes du logge ind, eller du kan <a href=\"%1$s\">lære mere "
+"om sandkassen.</a>"
+
+#: controllers/users_controller.php:223 controllers/users_controller.php:225
+msgid "users_pwreset_pagetitle"
+msgstr "Nulstilling af adgangskode"
+
+#: controllers/users_controller.php:90 controllers/users_controller.php:92
+msgid "users_register_pagetitle"
+msgstr "Registrering af ny bruger"
+
+#. %1$s is an addon name, like <a>Firebug</a>
+#. %2$s is a version number, like <a>1.2</a>
+#: views/versions/license.thtml:52
+msgid "versions_license_header_source"
+msgstr "Licens for kildekoden til %1$s %2$s"
+
+#: views/addons/category_landing.thtml:147
+msgid "view_recently_added"
+msgstr "Vis alle som blev tilføjet fornyligt"
+
+#: views/addons/category_landing.thtml:161
+msgid "view_top_downloads"
+msgstr "Vis alle med flest downloads"
+
+#: views/addons/category_landing.thtml:175
+msgid "view_top_rated"
+msgstr "Vis alle med de bedste bedømmelser"
+
+#~ msgid "addon_slider_tooltip_next"
+#~ msgstr "Næste tilføjelse"
+
+#~ msgid "addon_slider_tooltip_previous"
+#~ msgstr "Forrige tilføjelse"
+
+#~ msgid "addons_home_newest_header"
+#~ msgstr "Nyeste:"
+
+#~ msgid "addons_home_popular_header"
+#~ msgstr "Mest populære:"
+
+#~ msgid "addons_home_recommended_header"
+#~ msgstr "Vi anbefaler:"
+
+#~ msgid "addons_home_updated_header"
+#~ msgstr "Opdateret for nylig:"
+
+#~ msgid "addons_home_view_all"
+#~ msgstr "Vis alle"
+
+#, fuzzy
+#~ msgid "collections_detail_js_loading"
+#~ msgstr "Loading"
+
+#, fuzzy
+#~ msgid "collections_detail_more_info"
+#~ msgstr "Show More Info"
+
+#~ msgid "devcp_addon_status_criteria_review"
+#~ msgstr "Several user reviews of the add-on (may be external reviews)."
+
+#~ msgid "editors_submissiontype_new"
+#~ msgstr "New"
+
+#~ msgid "editors_submissiontype_updated"
+#~ msgstr "Updated"
+
+#~ msgid "editors_th_addontypes"
+#~ msgstr "Add-on Types"
+
+#~ msgid "editors_th_applications"
+#~ msgstr "Applications"
+
+#~ msgid "editors_th_platforms"
+#~ msgstr "Platforms"
+
+#~ msgid "editors_th_submissiontypes"
+#~ msgstr "Submission Types"
+
+#~ msgid "home"
+#~ msgstr "hjem"
+
+#~ msgid "pagination_page_number_title"
+#~ msgstr "Dette er side %1$s af %2$s"
+
+#~ msgid "search_matching_addons_number"
+#~ msgid_plural "search_matching_addons_number"
+#~ msgstr[0] "%s matchende tilføjelse"
+#~ msgstr[1] "%s matchende tilføjelser"
diff --git a/site/app/locale/da/glossary.txt b/site/app/locale/da/glossary.txt
new file mode 100644
index 0000000..22ddf50
--- /dev/null
+++ b/site/app/locale/da/glossary.txt
@@ -0,0 +1,25 @@
+review anmeldelse
+rating bedømmelse
+highest rating bedste bedømmelse
+summary resumé
+featured udmærket
+editor redaktør
+preview skærmbillede
+note bemærk(ning)
+nominate nominer
+preview caption billedtekst
+version notes versionsbemærkninger
+trusted betroet
+disabled deaktiveret
+edit rediger
+author forfatter
+(user) account konto
+flag review rapporter anmeldelse
+notifications beskeder
+community fællesskab
+
+BANDWAGON
+collection samling
+directory oversigt
+enter indtast
+review godkend \ No newline at end of file
diff --git a/site/app/locale/da/pages/collector_features.thtml b/site/app/locale/da/pages/collector_features.thtml
new file mode 100644
index 0000000..d564a24
--- /dev/null
+++ b/site/app/locale/da/pages/collector_features.thtml
@@ -0,0 +1,30 @@
+<p>
+ Tilføjelsessamleren giver dig nem adgang til dine favorittilføjelser og
+ -samlinger på følgende måder:
+</p>
+
+<dl>
+ <dt>Tilgå dine favoritsamlinger fra Firefox</dt>
+ <dd>
+ Markerer du en samling som favorit i
+ <a href="%1$s">samlingsoversigten</a>, vil den vises i en speciel del af
+ tilføjelsesvinduet. Du kan her holde dig opdateret og se indholdet
+ af hver samling.
+ </dd>
+ <dt>Del tilføjelser med menuen offentliggør</dt>
+ <dd>
+ Hver tilføjelse du installerer kan nemt deles med en ven via e-mail eller
+ offentliggøres via en af dine samlinger gennem menuen offentliggør.
+ </dd>
+ <dt>Modtag beskeder</dt>
+ <dd>
+ Samleren vil give dig besked når en af dine favoritsamlinger har en ny
+ tilføjelse, så du nemt kan godkende den senere.
+ </dd>
+
+ <dt>Offentliggør automatisk dine installerede tilføjelser til en samling</dt>
+ <dd>
+ Med automatisk offentliggørelse har du altid en opdateret samling af
+ dine seneste tilføjelser, så dine venner kan abonnere og holde sig up-to-date.
+ </dd>
+</dl>
diff --git a/site/app/locale/da/pages/compatibility_developer_tips.thtml b/site/app/locale/da/pages/compatibility_developer_tips.thtml
new file mode 100644
index 0000000..97b67f9
--- /dev/null
+++ b/site/app/locale/da/pages/compatibility_developer_tips.thtml
@@ -0,0 +1,6 @@
+<ul class="tips">
+ <li>Information om hvordan du opdaterer dine tilføjelser til %s findes i <a href="https://developer.mozilla.org/En/Updating_extensions_for_%s">denne artikel hos Mozilla Developer Center</a>.</li>
+ <li>Generel information om ændringer i %s findes i <a href="https://developer.mozilla.org/en/%s_for_developers">denne artikel</a>.</li>
+ <li>Du kan abonnere på <a href="https://addons.mozilla.org/newsletter">nyhedsbrevet about:addons</a> og <a href="http://blog.mozilla.com/addons/">bloggen Mozilla Add-ons</a> for at få yderligere opdateringer.</li>
+ <li>Hvis din tilføjelse ikke kræver nogen kodeændringer for at være kompatibel og hostes hos Mozilla Add-ons, kan du opdatere dens kompatible maxVersion online uden at uploade en ny fil ved at bruge <a href="%s">Developer Tools-området</a> eller ved at se status herunder.</li>
+</ul> \ No newline at end of file
diff --git a/site/app/locale/da/pages/compatibility_user_tips.thtml b/site/app/locale/da/pages/compatibility_user_tips.thtml
new file mode 100644
index 0000000..fa73dbc
--- /dev/null
+++ b/site/app/locale/da/pages/compatibility_user_tips.thtml
@@ -0,0 +1,6 @@
+<ul class="tips">
+ <li>Selvom mange tilføjelser kan understøtte ændringerne i %s uden kodeændringer, kan andre kræve yderligere arbejde fra udviklernes side for at sikre en problemfri opdatering. Vær tålmodig i denne periode, da mange udviklere af tilføjelser vedligeholder deres tilføjelser frivilligt som en hobby.</li>
+ <li>Mozilla fraråder at slå kompatibilitetstjek fra, da det kan give alvorlige problemer med at starte %s og kan endda resultere i tab af data, hvis en tilføjelse, som ikke er kompatibel med en ny version af %s, tvinges til at blive brugt.</li>
+ <li>Hvis tilføjelsen, som du forsøger at bruge, ikke er kompatibel efter %s er frigivet, kan du tjekke tilføjelsens eller udviklerens hjemmeside vedrørende nyheder omkring opdateringen.</li>
+ <li>Du kan måske finde en tilføjelse med lignende funktionalitet, som virker i %s, på <a href="%s">%s Add-ons</a>-hjemmesiden.</li>
+</ul> \ No newline at end of file
diff --git a/site/app/locale/da/pages/error404.thtml b/site/app/locale/da/pages/error404.thtml
new file mode 100644
index 0000000..6c012a4
--- /dev/null
+++ b/site/app/locale/da/pages/error404.thtml
@@ -0,0 +1,16 @@
+<h1>Vi beklager, men vi kan ikke finde den side du søger.</h1>
+
+<p>Siden eller filen du spurgte efter findes ikke på vores webside. Det er muligt at du klikkede på et forældet link eller indtastede adressen forkert.</p>
+
+<ul>
+<li>Hvis du indtastede adressen, bør du kontrollere stavemåden igen.</li>
+<li>Hvis du fulgte et link fra et eller andet sted, så kontakt os venligst på <a href="mailto:webmaster@mozilla.com" title="Side ikke fundet på Mozilla.com">webmaster@mozilla.com</a>. Fortæl os, hvor du kom fra, og hvad du ledte efter, og vi vil forsøge at rette problemet.</li>
+</ul>
+
+<p>Eller hop direkte til nogle af de populære sider på vores website.</p>
+
+<ul>
+<li>Er du interesseret i en <a href="%1$s">liste over populære tilføjelser</a>?</li>
+<li>Vil du <a href="%2$s">søge efter tilføjelser</a>? Du kan gå til <a href="%2$s">søgesiden</a> eller bruge søgefeltet herover.</li>
+<li>Vil du starte forfra, kan du gå til <a href="%3$s">forsiden for tilføjelser</a>.</li>
+</ul>
diff --git a/site/app/locale/da/pages/reviewguide.thtml b/site/app/locale/da/pages/reviewguide.thtml
new file mode 100644
index 0000000..539f734
--- /dev/null
+++ b/site/app/locale/da/pages/reviewguide.thtml
@@ -0,0 +1,66 @@
+<h1>Retningslinjer for anmeldelser</h1>
+<p>Med en anmeldelse af en tilføjelse kan du dele din meninger om tilføjelser, som du har installeret og brugt, med andre brugere. Redaktørerne forbeholder sig retten til at fjerne enhver anmeldelse, som ikke er i overensstemmelse med disse retningslinjer.</p>
+
+<div class="corner-box">
+ <h2>RÃ¥d til hvordan du skriver en god anmeldelse</h2>
+
+<h3><b>Husk at:</b></h3>
+<ul>
+<li>Skrive som hvis du fortalte en ven om din oplevelse af tilføjelsen.</li>
+<li>Holde din anmeldelse kortfattet og nem at forstå.</li>
+<li>Give specifikke og brugbare detaljer, eksempelvis:
+<ul>
+ <li>Virkede tilføjelsen som du forventede?</li>
+ <li>Hvad kunne du lide, og hvad kunne du ikke lide ved tilføjelsen?</li>
+ <li>Er tilføjelsen brugbar?</li>
+ <li>Er tilføjelsen nem at bruge?</li>
+ <li>Vil du fortsætte med at bruge denne tilføjelse?</li>
+</ul></li>
+
+<li>Bruge lidt tid på at gennemlæse din anmeldelse for at undgå pinlige stavefejl eller grammatiske fejl.</li>
+
+<li>Undgå aktuelle eller midlertidige referencer, da anmeldelser kan blive på siden i lang tid.</li>
+</ul>
+
+<h3><b>Lad være med at:</b></h3>
+<ul>
+<li>Indsende simple anmeldelser som fx "godt", "smukt" eller "dårligt" uden videre forklaring.</li>
+<li>Indsende fejlrapporter som anmeldelser. Brug de tilgængelige supportmuligheder for hver enkel tilføjelse.</li>
+<li>Skrive anmeldelser af tilføjelser, som du ikke selv har brugt.</li>
+<li>Bruge sjofelt eller fjendtligt sprog.</li>
+<li>Benytte HTML, links til malware, kildekode eller kodestumper. Anmeldelser bør kun bestå af tekst.</li>
+<li>Give falske udtalelser, nedgøre tilføjelsens udviklere eller komme med personlige fornærmelser.</li>
+<li>Bruge anmeldelser til at bede om understøttelse af specifikke programmer eller versioner af programmer.</li>
+<li>Oplyse din e-mail, dit telefonnummer eller andre personlige informationer.</li>
+<li>Anmelde en tilføjelse, som du selv eller din organisation har skrevet eller repræsenterer.</li>
+</ul>
+</div>
+
+<div class="corner-box">
+ <h2>Retningslinjer for bedømmelser af tilføjelser</h2>
+
+<p>Bedømmelser af tilføjelser bør være fair og give en god indikation af den overordnede kvalitet og brugbarhed. Lad være med bare at give en tilføjelse 5 stjerner, hvis du kan lide den, eller 1 stjerne, hvis du ikke kan lide den. Konsekvent bedømmelse er en vigtig del af enhver anmeldelse.</p>
+
+<ul>
+<li><b>5 stjerner: Fantastisk.</b> Tilføjelsen gør ikke alene alt, hvad den reklamerer med, den er også langt mere brugbar end mange andre tilføjelser. Denne tilføjelse er sandsynligvis én, du bruger ofte og anbefaler kraftigt.</li>
+<li><b>4 stjerner: God.</b> Brugbar og nem at bruge, men ikke nødvendigvis speciel. Denne tilføjelse anbefales, men kan passe bedre til nogle end andre.</li>
+<li><b>3 stjerner: Acceptabel.</b> Kan have nogle problemer eller manglende funktionalitet, men der er ingen problemer, der er så alvorlige, at tilføjelsen frarådes, og nogle kan måske finde tilføjelsen nyttig. Anbefalet til dem der har brug for tilføjelsen og er villige til at give den et forsøg.</li>
+<li><b>2 stjerner: Ringe.</b> Tilføjelser af lav kvalitet, ringe brugervenlighed eller tilføjelser, som ikke leverer, hvad de påstår. Du fraråder denne tilføjelse, men bemærker samtidigt, at den kan være nyttig for nogle få.</li>
+<li><b>1 stjerne: Dårlig.</b> Enten virker tilføjelsen ikke, eller den er ubrugelig. Du kan ikke komme i tanker om nogen væsentlig årsag til, at nogen skulle afprøve den, og du fraråder al brug af den.</li>
+</ul>
+
+<p>Der er ikke noget galt i at give en tilføjelse en fantastisk eller en forfærdelig anmeldelse, hvis du bare beskriver hvorfor. Stjernerne har ingen betydning, hvis du ikke giver en begrundelse.</p>
+</div>
+
+<div class="corner-box">
+ <h2>Ofte stille spørgsmål vedrørende anmeldelser</h2>
+
+<h3>Hvordan kan jeg rapportere en problematisk anmeldelse?</h3>
+<p>Rapportér eller markér tvivlsomme anmeldelser ved at klikke på "Rapporter denne anmeldelse", og den vil blive indsendt til behandling. Redaktørerne vil bruge retningslinjerne for anmeldelser til at vurdere, om anmeldelsen skal slettes eller sættes tilbage på siden.</p>
+
+<h3>Jeg er forfatter til en tilføjelse. Kan jeg svare på anmeldelser?</h3>
+<p>Ja, forfattere til en tilføjelse kan give et enkelt svar til en anmeldelse. Yderligere diskussioner eller opfølgninger bør flyttes til et supportforum eller en diskussionsgruppe.</p>
+
+<h3>Jeg er forfatter til en tilføjelse. Kan jeg slette negative anmeldelser og bedømmelser?</h3>
+<p>Generelt nej, men hvis anmeldelsen ikke opfylder retningslinjerne for anmeldelser, som kan ses herover, kan du klikke på "Rapporter denne anmeldelse", og den vil blive gennemgået af en redaktør. Hvis en anmeldelse indeholder en klage, som ikke længere er relevant på grund af en ny udgivelse af tilføjelsen, vil vi overveje at slette anmeldelsen. Indsend en detaljeret forespørgsel til amo-editors@mozilla.org. E-mailen skal være på engelsk.</p>
+</div>
diff --git a/site/app/locale/da/pages/sandbox.thtml b/site/app/locale/da/pages/sandbox.thtml
new file mode 100644
index 0000000..4696a18
--- /dev/null
+++ b/site/app/locale/da/pages/sandbox.thtml
@@ -0,0 +1,13 @@
+<h1>Sandkassegodkendelsessystemet</h1>
+<h2>Hvad er sandkassen?</h2>
+<p>Sandkassen er et område hvor avancerede brugere kan teste tilføjelser før de godkendes til generel brug. For at få adgang til sandkassen, skal du slå den til i indstillingerne for din brugerkonto. Der bør udvises forsigtighed ved installation af tilføjelser i sandkassen, fordi de ikke er testet af redaktør og muligvis kan skade din computer.</p>
+
+<h2>How do I get my add-on to be on the public side?</h2>
+<!-- To localize the flowchart image, see http://wiki.mozilla.org/Update:Remora_Sandbox_Flowchart -->
+<div style="text-align: center;">%s</div>
+<ol>
+ <li><b>Submit your add-on in the Developer Tools.</b> Your item will immediately appear in the "Sandbox" side of Mozilla Add-ons, where experienced users will test it and provide feedback. In order to see the sandbox, you will have to enable it in your account settings.</li>
+ <li><b>Nominate your add-on to be public.</b> From the Developer Tools, there is a link to nominate your add-on. After nominated, your add-on will appear in the Editor Nomination Queue for review.</li>
+ <li><b>An editor reviews your add-on.</b> A Mozilla Add-ons editor will install your add-on and test that it works. The editor will also look at reviews given by sandbox testers.</li>
+ <li><b>Your add-on is pushed public or retained in the sandbox.</b> The editor will either push your add-on public or retain it in the sandbox. If retained in the sandbox, you can nominate it again after making changes the editor suggests in comments. If pushed public, future versions of your add-on will appear in the sandbox until they have been reviewed by an editor and pushed public. Once your add-on is public, there is no need to nominate it again - future versions will automatically go into the pending queue for review.</li>
+</ol> \ No newline at end of file
diff --git a/site/app/locale/de/LC_MESSAGES/messages.mo b/site/app/locale/de/LC_MESSAGES/messages.mo
new file mode 100644
index 0000000..0bb2a35
--- /dev/null
+++ b/site/app/locale/de/LC_MESSAGES/messages.mo
Binary files differ
diff --git a/site/app/locale/de/LC_MESSAGES/messages.po b/site/app/locale/de/LC_MESSAGES/messages.po
new file mode 100644
index 0000000..49bded7
--- /dev/null
+++ b/site/app/locale/de/LC_MESSAGES/messages.po
@@ -0,0 +1,7500 @@
+# Remora Preliminary Language File
+# Copyright (C) 2006 Mozilla Corporation
+# This file is distributed under the same license as the REMORA package.
+# Wil Clouser <clouserw@mozilla.com>, 2006.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: REMORA 0.1\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2009-01-16 11:45-0800\n"
+"PO-Revision-Date: 2008-03-05 21:30+0100\n"
+"Last-Translator: Frederic Wenzel <fwenzel@mozilla.com>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=n != 1;\n"
+
+#: views/addons/policy.thtml:98
+msgid "a_cancel_installation"
+msgstr "Installation abbrechen"
+
+#. This is the text that appears on buttons to download add-ons.
+#. %$1s is an optional string that only appears if the add-on is only available for
+#. a certain platform. Examples: (Windows) or (Linux)
+#. Note that the parentheses are included in the string. :(
+#: views/elements/amo2009/install.thtml:126
+#: views/elements/amo2009/install.thtml:227
+#: views/elements/amo2009/install.thtml:257
+#: views/elements/amo2009/install.thtml:300
+#: views/elements/amo2009/install.thtml:312 views/elements/install.thtml:73
+#: views/elements/install.thtml:181 views/elements/install.thtml:205
+#: views/elements/install.thtml:248 views/elements/install.thtml:260
+#: views/addons/plugins.thtml:66 views/addons/plugins.thtml:76
+#: views/addons/plugins.thtml:86 views/addons/plugins.thtml:96
+#: views/addons/plugins.thtml:119
+#, php-format
+msgid "a_download"
+msgstr "Herunterladen %s"
+
+#: views/addons/policy.thtml:72
+msgid "a_eula_download"
+msgstr "Zustimmen und Herunterladen"
+
+#: views/addons/policy.thtml:74
+msgid "a_eula_install"
+msgstr "Zustimmen und installieren"
+
+#: views/elements/header.thtml:76 views/elements/header.thtml:82
+#: views/api/api_addon.thtml:55 views/api/collections_feed.thtml:75
+#: views/sharing_api/addon.thtml:64
+msgid "a_header_public"
+msgstr "Öffentliche Seite"
+
+#: views/elements/header.thtml:58 views/elements/header.thtml:75
+#: views/elements/header.thtml:80 views/api/api_addon.thtml:57
+#: views/api/collections_feed.thtml:77 views/sharing_api/addon.thtml:66
+msgid "a_header_sandbox"
+msgstr "Sandkasten"
+
+#. %s is a date in the _('date') format
+#: views/elements/amo2009/homepage_addon.thtml:115
+#: views/elements/addon_listitem.thtml:122 views/elements/feature.thtml:106
+#: views/addons/display.thtml:104 views/addons/browse_thumbs.thtml:73
+msgid "addon_detail_last_updated"
+msgstr "Aktualisiert am %s"
+
+#. %s is the version of the add-on. Example: 3.2a1
+#: views/elements/amo2009/addon_version_detail.thtml:51
+#: views/elements/addon_version_detail.thtml:51
+#, php-format
+msgid "addon_display_header_version"
+msgstr "Version %s"
+
+#: views/addons/browse_thumbs.thtml:80
+msgid "addon_downloads"
+msgstr "mal heruntergeladen"
+
+#: views/addons/display.thtml:147
+msgid "addon_downloads_total"
+msgstr "Downloads insgesamt"
+
+#: views/elements/amo2009/homepage_addon.thtml:106
+#: views/elements/addon_listitem.thtml:115 views/elements/feature.thtml:101
+#: views/addons/category_landing.thtml:157 views/addons/display.thtml:146
+#: views/addons/browse_thumbs.thtml:80
+msgid "addon_downloads_weekly"
+msgstr "Downloads wöchentlich"
+
+#. %1 is the add-on count, %2 the category name
+#: views/addons/browse_thumbs.thtml:104 views/addons/browse.thtml:60
+#, php-format
+msgid "addon_list_category_totalcount"
+msgid_plural "addon_list_category_totalcount"
+msgstr[0] "%1$s Add-on in \"%2$s\""
+msgstr[1] "%1$s Add-ons in \"%2$s\""
+
+#: views/elements/amo2009/addon_list_options.thtml:103
+#: views/elements/pagination.thtml:67
+#: views/elements/addon_list_options.thtml:94
+msgid "addon_list_perpage"
+msgstr "pro Seite"
+
+#: views/elements/amo2009/addon_list_options.thtml:84
+#: views/elements/addon_list_options.thtml:98
+msgid "addon_list_sortby"
+msgstr "Sortieren nach:"
+
+#: views/helpers/addons_html.php:568 views/elements/amo2009/install.thtml:321
+#: views/elements/feature.thtml:89
+msgid "addon_listitem_flag_experimental"
+msgstr "experimentell"
+
+#: views/helpers/addons_html.php:570
+msgid "addon_listitem_flag_recommended"
+msgstr "empfohlen"
+
+#. %1 is the add-on name, %2 is the platform
+#: views/pages/js_constants.js.thtml:66
+msgid "addon_not_available_for_platform"
+msgstr "%1$s ist für %2$s nicht verfügbar."
+
+#. %1 is the add-on name
+#: views/addons/policy.thtml:101 views/addons/previews.thtml:60
+#: views/addons/versions.thtml:130 views/reviews/flag.thtml:61
+#: views/reviews/add.thtml:114 views/reviews/display.thtml:216
+#: views/reviews/review_added.thtml:57
+#, php-format
+msgid "addon_review_a_back_to_addon_x"
+msgstr "Zurück zu %1$s..."
+
+#. %1 is the add-on name
+#: views/reviews/flag.thtml:60 views/reviews/add.thtml:113
+#: views/reviews/review_added.thtml:56
+#, php-format
+msgid "addon_review_a_back_to_reviews"
+msgstr "Zurück zu den Bewertungen..."
+
+#: views/reviews/add.thtml:85
+msgid "addon_review_add_rating_field"
+msgstr "Bewertung"
+
+#: views/reviews/add.thtml:102
+msgid "addon_review_add_review_field"
+msgstr "Bewertungstext"
+
+#: views/reviews/add.thtml:107
+msgid "addon_review_add_submit"
+msgstr "Abschicken"
+
+#. %s is the name of the add-on
+#: views/reviews/add.thtml:51
+#, php-format
+msgid "addon_review_add_title"
+msgstr "Bewertung für %s schreiben"
+
+#: views/reviews/add.thtml:78
+msgid "addon_review_add_title_field"
+msgstr "Titel/Zusammenfassung"
+
+#: views/reviews/display.thtml:77 views/reviews/display.thtml:161
+msgid "addon_review_admin_delete"
+msgstr "Löschen"
+
+#: views/reviews/display.thtml:76
+msgid "addon_review_author_reply_link"
+msgstr "Antworten"
+
+#: views/reviews/delete.thtml:62
+msgid "addon_review_confirm_delete"
+msgstr "Wollen Sie diese Bewertung wirklich löschen?"
+
+#: views/reviews/delete.thtml:63
+msgid "addon_review_confirm_no"
+msgstr "Nein"
+
+#: views/reviews/delete.thtml:64
+msgid "addon_review_confirm_yes"
+msgstr "Ja"
+
+#: views/reviews/delete.thtml:48
+msgid "addon_review_delete_header"
+msgstr "Bewertung löschen"
+
+#: controllers/reviews_controller.php:449
+msgid "addon_review_deleted_successfully"
+msgstr "Die Bewertung wurde gelöscht."
+
+#. %s is the name of the add-on
+#: views/reviews/add.thtml:51
+#, php-format
+msgid "addon_review_edit_title"
+msgstr "Bewertung für %s editieren"
+
+#. %1 is the count of characters entered as notes for the review flag reason.
+#: controllers/reviews_controller.php:539
+msgid "addon_review_flag_error_other_length"
+msgstr ""
+"Fehler beim Melden dieser Bewertung: Der Beschreibungstext darf nur zwischen "
+"10 und 100 Zeichen lang sein. Ihre Beschreibung umfasste %1$s Zeichen."
+
+#. Removing an extra comma
+#: views/reviews/review_added.thtml:53
+msgid "addon_review_in_moderation"
+msgstr ""
+"Bitte beachten Sie: Bevor Ihre Bewertung auf der Seite veröffentlicht wird, "
+"muss sie von einem Moderator freigeschaltet werden."
+
+#: views/reviews/add.thtml:57
+msgid "addon_review_in_reply_to"
+msgstr "Antwort des Entwicklers auf:"
+
+#. %1 is the review count, %2 is the nickname or full name of the user.
+#: views/reviews/display.thtml:131
+#, php-format
+msgid "addon_review_others_by_user"
+msgid_plural "addon_review_others_by_user"
+msgstr[0] "%1$s vorherige Bewertung von %2$s für dieses Add-on anzeigen."
+msgstr[1] "%1$s vorherige Bewertungen von %2$s für dieses Add-on anzeigen."
+
+#. %1 is the add-on name
+#: controllers/reviews_controller.php:201
+#: controllers/reviews_controller.php:250
+#: controllers/reviews_controller.php:345
+#: controllers/reviews_controller.php:424
+#, php-format
+msgid "addon_review_pagetitle"
+msgstr "Bewertungen für %s"
+
+#. %1 is the user, %2 is the (localized) date
+#: views/reviews/display.thtml:160
+#, php-format
+msgid "addon_review_reply_on_x_by_y"
+msgstr "Antwort von %1$s am %2$s"
+
+#: views/reviews/display.thtml:157
+msgid "addon_review_reply_prefix"
+msgstr "Entwickler-Antwort:"
+
+#: views/reviews/review_added.thtml:51
+msgid "addon_review_saved_successfully"
+msgstr "Die Bewertung wurde erfolgreich gespeichert!"
+
+#: views/addons/display.thtml:354 views/reviews/display.thtml:72
+msgid "addon_reviewed_by_u_on_d"
+msgstr "von %1$s am %2$s"
+
+#. %1 is the user, %2 is the (localized) date, %3 is the rating
+#: views/editors/reviews_queue.thtml:57 views/editors/reviews_queue.thtml:68
+#: views/reviews/add.thtml:63 views/reviews/delete.thtml:54
+#, php-format
+msgid "addon_reviewed_on_x_rated_y"
+msgstr "von %1$s am %2$s (Note %3$d)"
+
+#: views/elements/amo2009/addon_version_detail.thtml:52
+#: views/elements/addon_version_detail.thtml:52
+msgid "addon_version_permalink"
+msgstr "Direkter Link zu dieser Version"
+
+#. %1 is the current Application name (e.g. Firefox)
+#. %2 is the Application's version number
+#: views/addons/versions.thtml:140
+msgid "addon_versions_getlatestversion"
+msgstr "Die neueste Version, die mit %1$s %2$s kompatibel ist"
+
+#: views/addons/display.thtml:447
+msgid "addons_author_addons_submit"
+msgstr "Anzeigen"
+
+#: views/elements/amo2009/homepage_addon.thtml:100
+#: views/elements/feature.thtml:95
+msgid "addons_author_tooltip"
+msgstr "Das Profil des Autors anzeigen"
+
+#. %1 is the name of the Application (eg. Firefox)
+#: controllers/addons_controller.php:1296
+msgid "addons_browse_all_themes_title"
+msgstr "Alle Themes anzeigen :: %1$s Add-ons"
+
+#. %s is the name of the category
+#: controllers/addons_controller.php:1016
+#, php-format
+msgid "addons_browse_browse_category"
+msgstr "Kategorie %s"
+
+#. %1 is the name of the theme category (eg. Modern)
+#. %2 is the name of the Application (eg. Firefox)
+#: controllers/addons_controller.php:664
+msgid "addons_browse_categories_header_theme"
+msgstr "Alle %1$s Themes anzeigen :: %2$s Add-ons"
+
+#: views/addons/display.thtml:249
+msgid "addons_display_a_license_what"
+msgstr "Was ist das?"
+
+#: views/reviews/display.thtml:222
+msgid "addons_display_add_review"
+msgstr "Eine Bewertung schreiben"
+
+#: views/addons/display.thtml:294
+msgid "addons_display_advanced_details"
+msgstr "Weitere Details"
+
+#: views/addons/display.thtml:98
+msgid "addons_display_categories"
+msgstr "Kategorien"
+
+#: views/addons/display.thtml:482
+msgid "addons_display_collection_add"
+msgstr "Zu einer Sammlung hinzufügen:"
+
+#: views/addons/display.thtml:491
+msgid "addons_display_collection_add_new"
+msgstr "Neue Sammlung..."
+
+#: views/addons/display.thtml:487
+msgid "addons_display_collection_add_select_one"
+msgstr "Eine Sammlung auswählen..."
+
+#: views/addons/display.thtml:493
+msgid "addons_display_collection_add_submit"
+msgstr "Los!"
+
+#. %1$s is the add-on name
+#. %2$s is the collection name, linked to the collection's page
+#: views/pages/js_constants.js.thtml:103 views/addons/display.thtml:61
+msgid "addons_display_collection_publish_success"
+msgstr "%1$s wurde zur Sammlung %2$s hinzugefügt."
+
+#: views/addons/display.thtml:483
+msgid "addons_display_collection_whatsthis"
+msgstr "Was ist das?"
+
+#. %1$s is a number
+#: views/addons/display.thtml:473
+msgid "addons_display_collections_more"
+msgid_plural "addons_display_collections_more"
+msgstr[0] "und %1$s weitere Sammlung"
+msgstr[1] "und %1$s weitere Sammlungen"
+
+#: views/addons/display.thtml:403
+msgid "addons_display_detailed_review"
+msgstr "Detaillierte Bewertung"
+
+#: views/reviews/add.thtml:89 views/reviews/add.thtml:90
+msgid "addons_display_dont_like_it"
+msgstr "Nicht so gut"
+
+#: views/reviews/display.thtml:220
+msgid "addons_display_edit_review"
+msgstr "Ihre Bewertung editieren"
+
+#: views/addons/display.thtml:132
+msgid "addons_display_has_privacy"
+msgstr "Dieses Add-on hat eine Datenschutzerklärung."
+
+#: views/reviews/add.thtml:87 views/reviews/add.thtml:88
+msgid "addons_display_hate_it"
+msgstr "Schlecht"
+
+#: views/addons/display.thtml:462
+msgid "addons_display_header_collections"
+msgstr "Sammlungen mit diesem Add-on"
+
+#: views/addons/display.thtml:297
+msgid "addons_display_header_developer_comments"
+msgstr "Entwickler-Kommentare"
+
+#: views/addons/display.thtml:230
+msgid "addons_display_header_homepage"
+msgstr "Homepage"
+
+#: views/addons/display.thtml:247 views/addons/versions.thtml:110
+msgid "addons_display_header_license"
+msgstr "Quellcode-Lizenz"
+
+#: views/addons/display.thtml:337
+msgid "addons_display_header_reviews"
+msgstr "Bewertungen"
+
+#: views/addons/display.thtml:261
+msgid "addons_display_header_support"
+msgstr "Hilfe"
+
+#: views/reviews/add.thtml:91 views/reviews/add.thtml:92
+msgid "addons_display_like_it"
+msgstr "Okay"
+
+#: views/addons/display.thtml:210
+msgid "addons_display_long_description"
+msgstr "Ausführliche Beschreibung"
+
+#: views/reviews/add.thtml:95 views/reviews/add.thtml:96
+msgid "addons_display_love_it"
+msgstr "Ausgezeichnet"
+
+#: views/addons/display.thtml:178
+msgid "addons_display_more_images"
+msgstr "Weitere Bilder"
+
+#: views/addons/display.thtml:465
+msgid "addons_display_nocollections"
+msgstr "Dieses Add-on ist noch in keiner Sammlung."
+
+#. %1$s is either an author's name or a comma separated list of authors. Using
+#. the list doesn't make sense in the English plural form so we ignore the
+#. variable.
+#: views/addons/display.thtml:436
+msgid "addons_display_other_addons_by"
+msgid_plural "addons_display_other_addons_by"
+msgstr[0] "Weitere Add-ons von %1$s"
+msgstr[1] "Weitere add-ons von diesen Autoren"
+
+#. %s is the name of the add-on and the add-on section. Example:
+#. Some Add-on :: Firefox Add-ons
+#. This should not be concatenated in the code and should be fixed.
+#: controllers/addons_controller.php:141 controllers/addons_controller.php:280
+#: controllers/addons_controller.php:1442
+#, php-format
+msgid "addons_display_pagetitle"
+msgstr "%s"
+
+#. %s is an email address
+#: views/addons/display.thtml:286
+#, php-format
+msgid "addons_display_paragraph_supportinfoemail"
+msgstr ""
+"Unterstützung für diese Erweiterung gibt der Entwickler unter der E-Mail-"
+"Adresse %s."
+
+#. %$1s is a URL
+#. %$2s is an email address
+#: views/addons/display.thtml:269
+#, php-format
+msgid "addons_display_paragraph_supportinfoemailurl"
+msgstr ""
+"Unterstützung für diese Erweiterung gibt der Entwickler unter %s oder unter "
+"der E-Mail-Adresse %s."
+
+#. %s is a URL
+#: views/addons/display.thtml:278
+#, php-format
+msgid "addons_display_paragraph_supportinfourl"
+msgstr "Unterstützung für diese Erweiterung gibt der Entwickler unter %s."
+
+#: views/addons/display.thtml:383
+msgid "addons_display_rate_it"
+msgstr "Bewertung"
+
+#: views/reviews/add.thtml:93 views/reviews/add.thtml:94
+msgid "addons_display_really_like_it"
+msgstr "Sehr gut"
+
+#: views/addons/display.thtml:410
+msgid "addons_display_review_etiquette"
+msgstr ""
+"Bitte schreiben Sie keine Fehlerberichte oder Support-Anfragen als "
+"Bewertungen. Wir veröffentlichen Ihre E-Mail-Adresse gegenüber dem Autor "
+"nicht, und deshalb kann dieser Sie nicht erreichen, wenn das zur Lösung des "
+"Problems notwendig ist."
+
+#. %1 is the review guidelines link
+#: views/addons/display.thtml:417
+msgid "addons_display_review_guidelines_link"
+msgstr "<a href=\"%s\">Richtlinien für Bewertungen</a>"
+
+#. %1 is the support section link
+#: views/addons/display.thtml:414
+msgid "addons_display_review_see_support"
+msgstr ""
+"Im Abschnitt <a href=\"%1$s\">\"Hilfe\"</a> erfahren Sie, wo Sie "
+"Unterstützung für dieses Add-on bekommen können."
+
+#: views/addons/display.thtml:404
+msgid "addons_display_review_submit"
+msgstr "Speichern"
+
+#: views/addons/display.thtml:430
+#, php-format
+msgid "addons_display_see_all_addons"
+msgstr "Alle %1$s-Add-ons anzeigen"
+
+#. %1 is the number of reviews
+#: views/addons/display.thtml:364
+#, php-format
+msgid "addons_display_see_all_reviews"
+msgstr "Alle Bewertungen anzeigen (%1$s)"
+
+#: views/addons/display.thtml:219
+msgid "addons_display_see_all_versions"
+msgstr "Alle Versionen anzeigen"
+
+#: views/addons/display.thtml:321 views/addons/versions.thtml:117
+msgid "addons_display_view_source"
+msgstr "Quelltext anzeigen"
+
+#: views/addons/display.thtml:324
+msgid "addons_display_view_stats"
+msgstr "Statistiken"
+
+#: views/addons/display.thtml:376
+msgid "addons_display_what_do_you_think"
+msgstr "Was halten Sie davon?"
+
+#: views/elements/app_compatibility.thtml:49
+msgid "addons_display_workswith"
+msgstr "Kompatibel mit:"
+
+#: views/addons/home.thtml:112
+msgid "addons_home_browse_new"
+msgstr "Gerade hinzugefügt"
+
+#: views/addons/home.thtml:110
+msgid "addons_home_browse_popular"
+msgstr "Beliebt"
+
+#: views/addons/home.thtml:108
+msgid "addons_home_browse_recommended"
+msgstr "Empfohlen"
+
+#: views/addons/home.thtml:127 views/addons/home.thtml:134
+#: views/addons/home.thtml:141 views/addons/home.thtml:148
+msgid "addons_home_browse_subscribe"
+msgstr "Abonnieren"
+
+#: views/addons/home.thtml:101
+msgid "addons_home_browse_title"
+msgstr "Add-ons durchstöbern"
+
+#: views/addons/home.thtml:114
+msgid "addons_home_browse_updated"
+msgstr "Aktualisiert"
+
+#: views/elements/amo2009/homepage_addon.thtml:100
+#: views/elements/addon_discussionheader.thtml:83
+#: views/elements/addon_listitem.thtml:109 views/elements/feature.thtml:95
+#: views/addons/category_landing.thtml:66 views/addons/policy.thtml:57
+#: views/addons/display.thtml:70 views/addons/home.thtml:178
+msgid "addons_home_by"
+msgstr "von"
+
+#: views/addons/home.thtml:169
+msgid "addons_home_collection_popular_title"
+msgstr "Beliebte Sammlungen"
+
+#: views/elements/amo2009/categories.thtml:69 views/addons/home.thtml:160
+msgid "addons_home_collections"
+msgstr "Sammlungen"
+
+#. %1$s is the count of addons in a collection
+#: views/elements/amo2009/collection_listing_item.thtml:51
+#: views/addons/home.thtml:185
+msgid "addons_home_collections_addon_count"
+msgid_plural "addons_home_collections_addon_count"
+msgstr[0] "<strong>%1$s</strong> Add-on"
+msgstr[1] "<strong>%1$s</strong> Add-ons"
+
+#: views/addons/home.thtml:196
+msgid "addons_home_collections_all"
+msgstr "Alle Sammlungen anzeigen"
+
+#: views/addons/home.thtml:162
+msgid "addons_home_collections_intro"
+msgstr ""
+"Sammlungen geben Ihnen die Möglichkeit, Add-ons zu gruppieren, kombinieren "
+"und nach Belieben zu vermischen. Abonnieren Sie Sammlungen anderer Benutzer "
+"oder erstellen Sie Ihre eigenen Sammlungen!"
+
+#. %1$s is the count of subscribers for a collection
+#: views/elements/amo2009/collection_listing_item.thtml:58
+#: views/collections/detail.thtml:96 views/addons/home.thtml:189
+msgid "addons_home_collections_subscribers"
+msgid_plural "addons_home_collections_subscribers"
+msgstr[0] "<strong>%1$s</strong> Abonnent"
+msgstr[1] "<strong>%1$s</strong> Abonnenten"
+
+#: views/addons/searchengines.thtml:54 views/addons/themes_landing.thtml:49
+msgid "addons_home_feature_head"
+msgstr "Empfohlenes Add-on:"
+
+#: controllers/search_controller.php:218 controllers/addons_controller.php:176
+#: controllers/addons_controller.php:428 controllers/addons_controller.php:671
+#: controllers/addons_controller.php:871
+#: controllers/addons_controller.php:1103
+#: controllers/addons_controller.php:1242
+#: controllers/addons_controller.php:1298
+#, php-format
+msgid "addons_home_header_details"
+msgstr ""
+"Add-ons erweitern %1$s und erlauben Ihnen, Ihrer alltäglichen Arbeit Ihre "
+"persönliche Note zu geben. Sehen Sie sich ruhig um und erweitern Sie %1$s "
+"nach Belieben."
+
+#. %1$s is the HTML collection name link.
+#: views/elements/amo2009/teaser_collections.thtml:107
+msgid "addons_home_introduction_collection_link"
+msgstr "Mögen Sie diese? Finden Sie weitere Add-ons in %1$s."
+
+#: views/elements/amo2009/teaser_collections.thtml:60
+msgid "addons_home_introduction_extras"
+msgstr ""
+"<strong>Ãœber 5000 kostenlose Erweiterungen</strong>, mit denen Sie Firefox "
+"nach Belieben anpassen und erweitern können, damit er genau das tut, was Sie "
+"brauchen."
+
+#: views/elements/amo2009/teaser_collections.thtml:55
+msgid "addons_home_introduction_header"
+msgstr "Was sind Add-ons?"
+
+#: views/elements/amo2009/teaser_collections.thtml:72
+msgid "addons_home_introduction_install"
+msgstr ""
+"<strong>Leicht zu installieren</strong>, und wenn es eine Aktualisierung "
+"gibt, werden Sie automatisch benachrichtigt."
+
+#: views/elements/amo2009/teaser_collections.thtml:45
+msgid "addons_home_introduction_name"
+msgstr "Einführung"
+
+#: views/elements/amo2009/teaser_collections.thtml:66
+msgid "addons_home_introduction_themes"
+msgstr ""
+"Toolbars, Themes und Suchmaschinen, die Ihnen dabei helfen, "
+"<strong>alltägliche Aufgaben zu erfüllen.</strong>"
+
+#: views/addons/home.thtml:161
+msgid "addons_home_new_indicator"
+msgstr "NEU!"
+
+#: views/elements/app_chooser.thtml:48 views/layouts/amo2009.thtml:257
+msgid "addons_home_other_applications"
+msgstr "Andere Anwendungen"
+
+#. %1$s is the application the user is browsing. Examples: Thunderbird, Firefox,
+#. Sunbird
+#: views/pages/collector_faq.thtml:49 views/pages/collector_firstrun.thtml:42
+#: views/pages/collector.thtml:46 views/pages/collector_features.thtml:54
+#: controllers/developers_controller.php:87
+#: controllers/compatibility_controller.php:72
+#: controllers/components/simple_acl.php:81 controllers/components/amo.php:607
+#: controllers/statistics_controller.php:60
+#: controllers/statistics_controller.php:240
+#: controllers/previews_controller.php:67 controllers/users_controller.php:90
+#: controllers/users_controller.php:223 controllers/users_controller.php:330
+#: controllers/users_controller.php:414 controllers/users_controller.php:708
+#: controllers/users_controller.php:723 controllers/reviews_controller.php:204
+#: controllers/reviews_controller.php:251
+#: controllers/reviews_controller.php:346
+#: controllers/reviews_controller.php:425
+#: controllers/search_controller.php:185 controllers/search_controller.php:297
+#: controllers/search_controller.php:301 controllers/addons_controller.php:147
+#: controllers/addons_controller.php:280 controllers/addons_controller.php:370
+#: controllers/addons_controller.php:667 controllers/addons_controller.php:874
+#: controllers/addons_controller.php:1019
+#: controllers/addons_controller.php:1034
+#: controllers/addons_controller.php:1101
+#: controllers/addons_controller.php:1121
+#: controllers/addons_controller.php:1240
+#: controllers/addons_controller.php:1357
+#: controllers/addons_controller.php:1364
+#: controllers/addons_controller.php:1442
+#: controllers/addons_controller.php:1477
+#: controllers/addons_controller.php:1538
+#: controllers/addons_controller.php:1543
+#: controllers/editors_controller.php:64 controllers/pages_controller.php:132
+#: controllers/groups_controller.php:65 controllers/groups_controller.php:71
+#: controllers/groups_controller.php:89 controllers/groups_controller.php:111
+#: controllers/collections_controller.php:57
+#: controllers/collections_controller.php:121
+#: controllers/collections_controller.php:205
+#: controllers/collections_controller.php:365
+#: controllers/collections_controller.php:404
+#: controllers/collections_controller.php:466
+#: controllers/collections_controller.php:538
+#: controllers/collections_controller.php:828
+#: controllers/localizers_controller.php:72
+#, php-format
+msgid "addons_home_pagetitle"
+msgstr "%1$s Add-ons"
+
+#. %1$s is the number of addons downloaded
+#: views/addons/home.thtml:57
+#, php-format
+msgid "addons_home_stats_downloaded"
+msgid_plural "addons_home_stats_downloaded"
+msgstr[0] "<strong>%1$s</strong> <span>add-on heruntergeladen</span>"
+msgstr[1] "<strong>%1$s</strong> <span>add-ons heruntergeladen</span>"
+
+#. %1$s is the number of addons in use
+#: views/addons/home.thtml:63
+#, php-format
+msgid "addons_home_stats_inuse"
+msgid_plural "addons_home_stats_inuse"
+msgstr[0] "<strong>%1$s</strong> <span>aktives Add-on</span>"
+msgstr[1] "<strong>%1$s</strong> <span>aktive Add-ons</span>"
+
+#: views/addons/home.thtml:136
+msgid "addons_home_view_all_newest_title"
+msgstr "Alle neuen Add-ons anzeigen"
+
+#: views/addons/home.thtml:129
+msgid "addons_home_view_all_popular_title"
+msgstr "Alle beliebten Add-ons"
+
+#: views/addons/home.thtml:150
+msgid "addons_home_view_all_recommended_title"
+msgstr "Alle empfohlenen Add-ons"
+
+#: views/addons/home.thtml:143
+msgid "addons_home_view_all_updated_title"
+msgstr "Alle jüngst aktualisierten Add-ons anzeigen"
+
+#: views/elements/amo2009/install.thtml:334 views/elements/install.thtml:112
+msgid "addons_install_in_sunbird"
+msgstr ""
+"<ol><li>Klicken Sie den unten stehenden Link, um die Datei herunterzuladen.</"
+"li><li>In Mozilla Sunbird, öffnen Sie im Menü \"Extras\" den Punkt \"Add-ons"
+"\".</li><li>Klicken Sie auf die Schaltfläche \"Installieren\", wählen Sie "
+"die heruntergeladene Datei aus, und klicken Sie \"OK\".</li></ol>"
+
+#: views/elements/amo2009/install.thtml:333 views/elements/install.thtml:111
+msgid "addons_install_in_sunbird_title"
+msgstr "Wie installiere ich ein Add-on in Thunderbird?"
+
+#: views/elements/amo2009/install.thtml:331 views/elements/install.thtml:106
+msgid "addons_install_in_thunderbird"
+msgstr ""
+"<ol><li>Klicken Sie mit der rechten Maustaste auf den unten stehenden Link "
+"und wählen Sie \"Speichern unter...\", um die Datei herunterzuladen und auf "
+"der Festplatte zu speichern.</li><li>In Mozilla Thunderbird, öffnen Sie im "
+"Menü \"Extras\" den Punkt \"Add-ons\".</li><li>Klicken Sie auf die "
+"Schaltfläche \"Installieren\", wählen Sie die heruntergeladene Datei aus und "
+"klicken Sie \"OK\".</li></ol>"
+
+#: views/elements/amo2009/install.thtml:330 views/elements/install.thtml:105
+msgid "addons_install_in_thunderbird_title"
+msgstr "Wie installiere ich ein Add-on in Thunderbird?"
+
+#: views/elements/amo2009/addon_list_options.thtml:108
+#: views/elements/addon_list_options.thtml:105
+msgid "addons_options_show_experimental"
+msgstr "Experimentelle Add-ons"
+
+#: views/elements/amo2009/addon_list_options.thtml:113
+#: views/elements/addon_list_options.thtml:109
+msgid "addons_options_submit"
+msgstr "Okay"
+
+#: views/addons/plugins.thtml:63 views/addons/plugins.thtml:73
+#: views/addons/plugins.thtml:83 views/addons/plugins.thtml:93
+#: views/addons/plugins.thtml:103 views/addons/plugins.thtml:116
+#: views/addons/plugins.thtml:126
+msgid "addons_plugins_by"
+msgstr "Von"
+
+#: views/addons/plugins.thtml:107
+msgid "addons_plugins_for_linux"
+msgstr "für Linux"
+
+#: views/addons/plugins.thtml:108 views/addons/plugins.thtml:131
+msgid "addons_plugins_for_macosx"
+msgstr "für Mac OS X"
+
+#: views/addons/plugins.thtml:106 views/addons/plugins.thtml:129
+#: views/addons/plugins.thtml:130
+msgid "addons_plugins_for_windows"
+msgstr "für Windows"
+
+#. %1$s is a URL
+#: views/addons/plugins.thtml:139
+#, php-format
+msgid "addons_plugins_looking_for_more"
+msgstr ""
+"Diese Seite listet nur die am häufigsten eingesetzten Plugins auf. Für "
+"weiteren Informationen über zusätzliche Plugins, die mit Browsern aus dem "
+"Hause Mozilla kompatibel sind, besuchen Sie %1$s."
+
+#: views/addons/plugins.thtml:137
+msgid "addons_plugins_looking_for_plugin"
+msgstr "Suchen Sie nach weiteren Plugins?"
+
+#: views/addons/plugins.thtml:58
+msgid "addons_plugins_main_description"
+msgstr ""
+"Plugins helfen Ihrem Browser dabei, bestimmte Funktionen auszuführen, wie "
+"beispielsweise die Anzeige spezieller Grafikformate oder das Abspielen von "
+"Multimedia-Dateien. Plugins unterscheiden sich ein wenig von Erweiterungen, "
+"die existierende Funktionen des Browsers verändern oder neue hinzufügen."
+
+#. %1$s is the application name. Example: Firefox, Thunderbird, Sunbird
+#: controllers/addons_controller.php:1122
+#, php-format
+msgid "addons_plugins_main_header"
+msgstr "Übliche Plugins für %1$s"
+
+#: controllers/components/amo.php:698 controllers/addons_controller.php:1121
+msgid "addons_plugins_pagetitle"
+msgstr "Plugins"
+
+#: views/addons/plugins.thtml:68 views/addons/plugins.thtml:78
+#: views/addons/plugins.thtml:88 views/addons/plugins.thtml:98
+#: views/addons/plugins.thtml:110 views/addons/plugins.thtml:121
+#: views/addons/plugins.thtml:133
+msgid "addons_plugins_support_documentation"
+msgstr "Benutzer-Dokumentation: "
+
+#. %s is the name of the add-on
+#: views/addons/policy.thtml:61
+#, php-format
+msgid "addons_policy_eula_require"
+msgstr ""
+"%1$s hat einen Endbenutzer-Lizenzvertrag. Bevor Sie es installieren können, "
+"müssen Sie diesem zustimmen:"
+
+#. %1 is the add-on name
+#: controllers/addons_controller.php:1476
+#, php-format
+msgid "addons_previews_pagetitle"
+msgstr "Vorschaubilder für %s"
+
+#: views/addons/category_landing.thtml:135
+msgid "addons_recently_added"
+msgstr "Neu hinzugefügt"
+
+#: views/addons/recommended.thtml:51 controllers/addons_controller.php:1365
+msgid "addons_recommended_introduction"
+msgstr ""
+"Bei der riesigen Auswahl an Add-ons ist sicher für jeden etwas dabei. Um den "
+"Einstieg zu erleichtern, haben wir eine Liste mit ein paar der beliebtesten "
+"Add-ons zusammengestellt. Viel Spaß!"
+
+#: controllers/addons_controller.php:1357
+#: controllers/addons_controller.php:1364
+msgid "addons_recommended_pagetitle"
+msgstr "Empfohlene Add-ons"
+
+#: controllers/addons_controller.php:1360
+msgid "addons_recommended_title"
+msgstr "Empfohlene Add-ons"
+
+#: views/addons/searchengines.thtml:136
+msgid "addons_searchengines_additional_resources"
+msgstr "Weiterführende Links"
+
+#. link text devmo
+#: views/addons/searchengines.thtml:141
+msgid "addons_searchengines_devmo_link"
+msgstr "Mozilla Developer Center"
+
+#: views/pages/js_constants.js.thtml:67
+msgid "addons_searchengines_error_mozilla_browser_required"
+msgstr ""
+"Um weitere Suchmaschinen zu installieren, benötigen Sie einen Mozilla-"
+"kompatiblen Browser (zum Beispiel Firefox)."
+
+#: views/addons/searchengines.thtml:49
+msgid "addons_searchengines_error_nojavascript"
+msgstr ""
+"JavaScript wird zur Installierung von Plugins benötigt, allerdings haben Sie "
+"es deaktiviert. Bitte aktivieren Sie JavaScript, bevor Sie versuchen, eine "
+"der untenstehenden Suchmaschinen zu installieren."
+
+#. %1 is "make your own" link
+#. %2 is MDC link
+#: views/addons/searchengines.thtml:139
+msgid "addons_searchengines_learn_howto"
+msgstr "Im %2$s erfahren Sie, wie Sie Ihr eigenes %1$s können."
+
+#. link path to search plugins instructions, relative to devmo
+#: views/addons/searchengines.thtml:140
+msgid "addons_searchengines_makeyourown_href"
+msgstr "/en/docs/Creating_OpenSearch_plugins_for_Firefox"
+
+#. link text for "make your own" (opensearch engine)
+#: views/addons/searchengines.thtml:140
+msgid "addons_searchengines_makeyourown_link"
+msgstr "Suchmaschinen-Plugin erstellen"
+
+#. %1 is the link to mycroft.mozdev.org
+#: views/addons/searchengines.thtml:138
+msgid "addons_searchengines_more"
+msgstr "Viele weitere Suchmaschinen können Sie auf %1$s finden."
+
+#. link text to mycroft.mozdev.org
+#: views/addons/searchengines.thtml:138
+msgid "addons_searchengines_mycroft_link"
+msgstr "mycroft.mozdev.org"
+
+#: controllers/addons_controller.php:1100
+#: controllers/addons_controller.php:1110
+msgid "addons_searchengines_pagetitle"
+msgstr "Suchmaschinen-Plugins"
+
+#: views/addons/searchengines.thtml:143
+msgid "addons_searchengines_thanks"
+msgstr ""
+"Ein besonderes Dankeschön an das Mycroft-Projekt für seinen Beitrag zu den "
+"Firefox Suchmaschinen-Plugins."
+
+#: views/addons/display.thtml:154
+msgid "addons_share_button_text"
+msgstr "Weiterempfehlen"
+
+#: controllers/addons_controller.php:89
+msgid "addons_share_label_delicious"
+msgstr "Zu Delicious hinzufügen"
+
+#: controllers/addons_controller.php:77
+msgid "addons_share_label_digg"
+msgstr "Zu Digg hinzufügen"
+
+#: controllers/addons_controller.php:83
+msgid "addons_share_label_facebook"
+msgstr "Bei Facebook posten"
+
+#: controllers/addons_controller.php:101
+msgid "addons_share_label_friendfeed"
+msgstr "Auf FriendFeed empfehlen"
+
+#: controllers/addons_controller.php:95
+msgid "addons_share_label_myspace"
+msgstr "Auf MySpace setzen"
+
+#: controllers/components/amo.php:201 controllers/components/amo.php:229
+msgid "addons_status_disabled"
+msgstr "Deaktiviert"
+
+#: controllers/components/amo.php:191 controllers/components/amo.php:224
+msgid "addons_status_incomplete"
+msgstr "Unvollständige Version"
+
+#: controllers/components/amo.php:197 controllers/components/amo.php:227
+msgid "addons_status_nominated"
+msgstr "Im Sandkasten; Zur Veröffentlichung nominiert"
+
+#: views/pages/js_constants.js.thtml:80 controllers/components/amo.php:195
+#: controllers/components/amo.php:226
+msgid "addons_status_pending"
+msgstr "Im Sandkasten; Wartet auf Moderation"
+
+#: views/pages/js_constants.js.thtml:78 controllers/components/amo.php:199
+#: controllers/components/amo.php:228
+msgid "addons_status_public"
+msgstr "Öffentlich"
+
+#: views/pages/js_constants.js.thtml:79 controllers/components/amo.php:193
+#: controllers/components/amo.php:225
+msgid "addons_status_sandbox"
+msgstr "Im Sandkasten"
+
+#: controllers/components/amo.php:203
+msgid "addons_status_unknown"
+msgstr "Unbekannt"
+
+#: views/elements/amo2009/teaser_collections.thtml:91
+#: views/elements/amo2009/homepage_addon.thtml:99
+#: views/elements/feature.thtml:94
+msgid "addons_title_tooltip"
+msgstr "Erfahren Sie mehr über dieses Add-on"
+
+#: views/addons/category_landing.thtml:151
+msgid "addons_top_downloads"
+msgstr "Am häufigsten heruntergeladen"
+
+#: views/addons/category_landing.thtml:165
+msgid "addons_top_rated"
+msgstr "Am höchsten bewertet"
+
+#: views/addons/versions.thtml:62
+msgid "addons_versions_careful"
+msgstr "Seien Sie vorsichtig mit alten Versionen"
+
+#: views/addons/versions.thtml:63
+msgid "addons_versions_careful_introduction"
+msgstr ""
+"Diese Versionen werden als Referenz und zu Testzwecken auf dieser Seite "
+"angezeigt. Sie sollten jedoch stets die neueste Version eines Add-ons "
+"installieren."
+
+#: controllers/addons_controller.php:1549
+msgid "addons_versions_history"
+msgstr "Versionsgeschichte mit Entwickler-Kommentaren"
+
+#. %1$s is the add-on name
+#: controllers/addons_controller.php:1535
+#, php-format
+msgid "addons_versions_pagetitle"
+msgstr "Versionsgeschichte von %1$s"
+
+#: controllers/groups_controller.php:71
+msgid "admin_group_add_pagetitle"
+msgstr "Gruppe hinzufügen"
+
+#: controllers/groups_controller.php:111
+msgid "admin_group_delete_pagetitle"
+msgstr "Gruppen löschen"
+
+#. %s is a number to identify the group
+#: controllers/groups_controller.php:117
+#, php-format
+msgid "admin_group_deleted"
+msgstr "Die Gruppe mit der ID %s wurde gelöscht"
+
+#: controllers/groups_controller.php:89
+msgid "admin_group_edit_pagetitle"
+msgstr "Gruppe bearbeiten"
+
+#: controllers/groups_controller.php:92 controllers/groups_controller.php:113
+msgid "admin_group_error_invalid_id"
+msgstr "Ungültige ID für Gruppe"
+
+#: controllers/groups_controller.php:65
+msgid "admin_group_pagetitle"
+msgstr "Gruppenadministrator"
+
+#: controllers/groups_controller.php:77 controllers/groups_controller.php:99
+msgid "admin_group_saved"
+msgstr "Die Gruppe wurde gespeichert"
+
+#: views/elements/amo2009/search.thtml:257 views/elements/search.thtml:239
+msgid "advanced_search_form"
+msgstr "Erweiterte Suche"
+
+#: views/elements/amo2009/search.thtml:126 views/elements/search.thtml:125
+msgid "advanced_search_form_any_time"
+msgstr "Egal"
+
+#: views/elements/amo2009/search.thtml:97
+#: views/elements/amo2009/search.thtml:110 views/elements/search.thtml:96
+#: views/elements/search.thtml:109
+msgid "advanced_search_form_any_type"
+msgstr "Egal"
+
+#: views/elements/amo2009/search.thtml:275 views/elements/search.thtml:254
+msgid "advanced_search_form_any_version"
+msgstr "Egal"
+
+#: views/elements/amo2009/search.thtml:217 views/elements/search.thtml:212
+msgid "advanced_search_form_application"
+msgstr "Anwendung"
+
+#: views/elements/amo2009/search.thtml:143 views/elements/search.thtml:142
+msgid "advanced_search_form_keyword_match"
+msgstr "Suchbegriff"
+
+#: views/elements/amo2009/search.thtml:251 views/elements/search.thtml:225
+msgid "advanced_search_form_lastupdate"
+msgstr "Letzte Aktualisierung"
+
+#: views/elements/amo2009/search.thtml:145 views/elements/search.thtml:144
+msgid "advanced_search_form_name"
+msgstr "Name"
+
+#: views/elements/amo2009/search.thtml:144 views/elements/search.thtml:143
+msgid "advanced_search_form_newest"
+msgstr "Am neuesten"
+
+#: views/elements/amo2009/search.thtml:130 views/elements/search.thtml:129
+msgid "advanced_search_form_past_3_months"
+msgstr "letzte 3 Wochen"
+
+#: views/elements/amo2009/search.thtml:131 views/elements/search.thtml:130
+msgid "advanced_search_form_past_6_months"
+msgstr "letzte 6 Monate"
+
+#: views/elements/amo2009/search.thtml:127 views/elements/search.thtml:126
+msgid "advanced_search_form_past_day"
+msgstr "innerhalb eines Tages"
+
+#: views/elements/amo2009/search.thtml:129 views/elements/search.thtml:128
+msgid "advanced_search_form_past_month"
+msgstr "letzten Monat"
+
+#: views/elements/amo2009/search.thtml:128 views/elements/search.thtml:127
+msgid "advanced_search_form_past_week"
+msgstr "letzte Woche"
+
+#: views/elements/amo2009/search.thtml:132 views/elements/search.thtml:131
+msgid "advanced_search_form_past_year"
+msgstr "letztes Jahr"
+
+#: views/elements/amo2009/search.thtml:239 views/elements/search.thtml:230
+msgid "advanced_search_form_perpage"
+msgstr "pro Seite"
+
+#: views/elements/amo2009/search.thtml:243 views/elements/search.thtml:224
+msgid "advanced_search_form_platform"
+msgstr "Betriebssystem"
+
+#: views/elements/amo2009/search.thtml:147 views/elements/search.thtml:146
+msgid "advanced_search_form_popularity"
+msgstr "Downloads"
+
+#: views/elements/amo2009/search.thtml:146 views/elements/search.thtml:145
+msgid "advanced_search_form_rating"
+msgstr "Bewertung"
+
+#: views/elements/amo2009/search.thtml:247 views/elements/search.thtml:231
+msgid "advanced_search_form_sortby"
+msgstr "Sortieren nach"
+
+#: views/elements/amo2009/search.thtml:227 views/elements/search.thtml:216
+msgid "advanced_search_form_to"
+msgstr "bis"
+
+#: views/elements/amo2009/search.thtml:257 views/elements/search.thtml:237
+msgid "advanced_search_form_toggle_tooltip"
+msgstr "Die erweiterte Suche an-/ausschalten"
+
+#: views/elements/amo2009/search.thtml:235 views/elements/search.thtml:223
+msgid "advanced_search_form_type"
+msgstr "Typ"
+
+#: views/elements/amo2009/search.thtml:222 views/elements/search.thtml:214
+msgid "advanced_search_form_version"
+msgstr "Version"
+
+#: views/elements/amo2009/pagination.thtml:42
+msgid "amo2009_pagination_next_page"
+msgstr "Nächste Seite"
+
+#: views/elements/amo2009/pagination.thtml:41
+msgid "amo2009_pagination_previous_page"
+msgstr "Vorherige Seite"
+
+#: views/pages/js_constants.js.thtml:96
+msgid "app_compat_ignore_check"
+msgstr "Versionsüberprüfung nicht beachten"
+
+#: views/pages/js_constants.js.thtml:72
+msgid "app_compat_older_firefox_only"
+msgstr "Dieses Add-on ist für ältere Versionen von Firefox"
+
+#. %1$s and %2$s are URLs
+#: views/pages/js_constants.js.thtml:74
+msgid "app_compat_older_version_or_ignore_check"
+msgstr ""
+"Sie können <a href=\"%1$s\">eine ältere Version versuchen</a> oder <a href="
+"\"#\" onclick=\"%2$s\">diese Überprüfung ignorieren</a>"
+
+#. %1$s is a URL
+#: views/pages/js_constants.js.thtml:71
+msgid "app_compat_try_old_version"
+msgstr "Eine <a href=\"%1$s\">ältere Version</a> könnte funktionieren"
+
+#. %1$s is a URL
+#. %2$s is a version number. Example: 3.1
+#: views/pages/js_constants.js.thtml:73
+msgid "app_compat_unreleased_version"
+msgstr ""
+"Dieses Add-on benötigt den noch nicht veröffentlichten <a href=\"%1$s"
+"\">Firefox %2$s</a>"
+
+#: views/pages/js_constants.js.thtml:70
+msgid "app_compat_update_firefox"
+msgstr ""
+"<a href=\"http://getfirefox.com\">Aktualisieren Sie Firefox</a>, um dieses "
+"Add-on zu verwenden"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#. %3$s is a status, like Public.
+#: controllers/components/audit.php:79
+msgid "audit_addon_status"
+msgstr "%1$s änderte den Status von %2$s zu %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:221
+msgid "audit_admin_default"
+msgstr "%1$s führte die unbekannte Admin-Aktion %2$s auf ID %3$s aus"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:153
+msgid "audit_admin_feature_remove"
+msgstr "%1$s entfernte Empfehlung %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is an application, like Firefox.
+#: controllers/components/audit.php:92
+msgid "audit_application_create"
+msgstr "%1$s erstellte Anwendung %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is an application, like Firefox.
+#: controllers/components/audit.php:95
+msgid "audit_application_edit"
+msgstr "%1$s bearbeitete Anwendung %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a version number, like 3.5.
+#. %3$s is an application, like Firefox.
+#: controllers/components/audit.php:105
+msgid "audit_appversion_create"
+msgstr "%1$s legte Version %2$s für %3$s an"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a version number, like 3.5.
+#. %3$s is an application, like Firefox.
+#: controllers/components/audit.php:108
+msgid "audit_appversion_delete"
+msgstr "%1$s löschte Version %2$s für %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a config field, like "awesomeness".
+#. %3$s is a config value, like "off".
+#. %4$s is a config value, like "on".
+#: controllers/components/audit.php:210
+msgid "audit_config"
+msgstr "%1$s änderte Konfigurationseinstellung '%2$s' von '%3$s' nach '%4$s'"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:258
+msgid "audit_editor_default"
+msgstr "%1$s führte unbekannte Editor-Aktion %2$s auf ID %3$s aus"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#: controllers/components/audit.php:236
+msgid "audit_editor_feature_remove"
+msgstr "%1$s entfernte Add-on %2$s von der Liste der Empfehlungen"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#: controllers/components/audit.php:231
+msgid "audit_feature_add"
+msgstr "%1$s fügte Add-on %2$s zur Liste der Empfehlungen hinzu"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:149
+msgid "audit_feature_edit"
+msgstr "%1$s änderte eine Empfehlung für die Sprache %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#: controllers/components/audit.php:241
+msgid "audit_feature_locale_change"
+msgstr "%1$s änderte die Sprachen für das Add-on %2$s auf der Empfehlungsliste"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:83
+msgid "audit_file_recalchash"
+msgstr "%1$s berechnete den Hash neu für das Add-on %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>user name</a>
+#. %3$s is <a>group name</a>
+#: controllers/components/audit.php:182
+msgid "audit_group_addmember"
+msgstr "%1$s fügte %2$s zur Gruppe %3$s hinzu"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:313
+msgid "audit_group_associated"
+msgstr "%1$s fügte sich selbst zur Gruppe %2$s hinzu"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:162
+msgid "audit_group_create"
+msgstr "%1s legte die Gruppe %2$s an"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:170
+msgid "audit_group_delete"
+msgstr "%1$s löschte die Gruppe %2$s (ID %3$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:165
+msgid "audit_group_edit"
+msgstr "%1$s editierte die Gruppe %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>user name</a>
+#. %3$s is <a>group name</a>
+#: controllers/components/audit.php:188
+msgid "audit_group_removemember"
+msgstr "%1$s entfernte %2$s von der Gruppe %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:280
+msgid "audit_l10n_default"
+msgstr "%1$s führte die unbekannte Aktion %2$s auf %3$s aus"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:295
+msgid "audit_modify_locked_group"
+msgstr "%1$s versuchte, die geschützte Gruppe %2$s zu verändern"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:299
+msgid "audit_modify_other_locale"
+msgstr ""
+"%1$s versuchte, Ãœbersetzungen in der Sprache %2$s ohne Berechtigung zu "
+"verändern"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a platform, like <a>Windows</a>
+#: controllers/components/audit.php:135
+msgid "audit_platform_create"
+msgstr "%1$s fügte Betriebssystem %2$s hinzu"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a platform, like <a>Windows</a>
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:143
+msgid "audit_platform_delete"
+msgstr "%1$s löschte Betriebssystem %2$s (ID %3$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a platform, like <a>Windows</a>
+#: controllers/components/audit.php:138
+msgid "audit_platform_edit"
+msgstr "%1$s editierte Betriebssystem %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a part of the admin, like 'Site Config'
+#: controllers/components/audit.php:288
+msgid "audit_reauthentication_failure"
+msgstr "%1$s loggte sich nicht korrekt erneut ein, um auf %2$s zuzugreifen."
+
+#. %1$s is <a>user name</a>
+#. %2$s is the name of a canned response, like 'Ready for the public'
+#: controllers/components/audit.php:198
+msgid "audit_response_create"
+msgstr "%1$s fügte Antwort %2$s hinzu"
+
+#. %1$s is <a>user name</a>
+#. %2$s is the name of a canned response, like 'Ready for the public'
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:206
+msgid "audit_response_delete"
+msgstr "%1$s löschte Antwort %2$s (ID %3$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is the name of a canned response, like 'Ready for the public'
+#: controllers/components/audit.php:201
+msgid "audit_response_edit"
+msgstr "%1$s editierte Antwort %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:245
+msgid "audit_review_approve"
+msgstr "%1$s gab Bewertung %2$s frei"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:250 controllers/components/audit.php:253
+msgid "audit_review_delete"
+msgstr "%1$s löschte Bewertung %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:303
+msgid "audit_security_default"
+msgstr "%1$s führte unbekannte Sicherheits-Aktion %2$s auf ID %3$s aus"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a category name, like <a>Search Tools</a>
+#: controllers/components/audit.php:118
+msgid "audit_tag_create"
+msgstr "%1$s fügte Kategorie %2$s hinzu"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a category name, like <a>Search Tools</a>
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:126
+msgid "audit_tag_delete"
+msgstr "%1$s löschte Kategorie %2$s (ID %3$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a category name, like <a>Search Tools</a>
+#: controllers/components/audit.php:121
+msgid "audit_tag_edit"
+msgstr "%1$s editierte Kategorie %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:266
+msgid "audit_update_applications"
+msgstr "%1$s veränderte die Anwendungs-Übersetzungen für %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:277
+msgid "audit_update_blog"
+msgstr "%1$s veränderte die Blog-Übersetzungen für %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:274
+msgid "audit_update_platforms"
+msgstr "%1$s veränderte die Betriebssystem-Übersetzungen für %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:270
+msgid "audit_update_tags"
+msgstr "%1$s veränderte die Kategorie-Übersetzungen für %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>user name</a>
+#: controllers/components/audit.php:217
+msgid "audit_user_edit"
+msgstr "%1$s editierte die Benutzerdaten von Benutzer %2$s"
+
+#: controllers/addons_controller.php:1012
+msgid "browse_addons_name"
+msgstr "Add-ons nach Name"
+
+#: controllers/addons_controller.php:1010
+msgid "browse_addons_newest"
+msgstr "Neueste Add-ons"
+
+#: controllers/addons_controller.php:1008
+msgid "browse_addons_popular"
+msgstr "Beliebte Add-ons"
+
+#: controllers/addons_controller.php:1011
+msgid "browse_addons_rated"
+msgstr "Add-ons nach Bewertung"
+
+#: controllers/addons_controller.php:1009
+msgid "browse_addons_updated"
+msgstr "Aktualisierte Add-ons"
+
+#: views/elements/categories.thtml:73 views/elements/categories.thtml:82
+msgid "categories_current_title"
+msgstr "Aktuelle Kategorie"
+
+#: views/elements/categories.thtml:50
+#: views/elements/amo2009/categories.thtml:43
+#: views/elements/amo2009/categories.thtml:45
+msgid "categories_header"
+msgstr "Kategorien"
+
+#: views/elements/categories.thtml:50
+#: views/elements/amo2009/categories.thtml:41
+msgid "categories_header_title"
+msgstr "Wählen Sie eine Kategorie"
+
+#. %1$s is the category name
+#: views/addons/searchengines.thtml:129
+#, php-format
+msgid "category_extra_see_all"
+msgstr "Alle %1$s anzeigen"
+
+#. %1$s is a number.
+#: models/collection.php:130
+msgid "collection_description_limit"
+msgstr "Die Beschreibung sollte nicht mehr als %1$s Zeichen lang sein."
+
+#. %1$s is the name of the collection
+#: controllers/collections_controller.php:392
+msgid "collection_detail_rss_title"
+msgstr "Sammlung: %s"
+
+#: controllers/collections_controller.php:1065
+msgid "collection_error_deleting_addon"
+msgstr "Fehler beim Löschen des Add-ons!"
+
+#: controllers/collections_controller.php:1051
+msgid "collection_error_saving_addon"
+msgstr "Fehler beim Speichern des Add-ons!"
+
+#: controllers/collections_controller.php:1080
+msgid "collection_error_saving_comment"
+msgstr "Fehler beim Speichern des Kommentars!"
+
+#. %1$s is a number.
+#: models/collection.php:122
+msgid "collection_name_limit"
+msgstr "Der Name sollte nicht mehr als %1$s Zeichen lang sein."
+
+#: controllers/collections_controller.php:352
+#: controllers/collections_controller.php:487
+msgid "collection_not_found"
+msgstr "Liste nicht gefunden!"
+
+#. %1$s is the text on the "create collection" button
+#: views/collections/add.thtml:91
+msgid "collections_add_formfield_addons_description"
+msgstr ""
+"Wenn Sie bereits wissen, welche Add-ons Ihre Sammlung enthalten soll, geben "
+"Sie einfach deren Namen hier ein. Wenn Sie noch ein wenig warten möchten und "
+"Ihre Add-ons erst später hinzufügen wollen, klicken Sie einfach unten auf %1"
+"$s."
+
+#: views/collections/add.thtml:90
+msgid "collections_add_formfield_firstaddons"
+msgstr "Wählen Sie Ihre ersten Add-ons"
+
+#: views/collections/add.thtml:48
+msgid "collections_add_header"
+msgstr "Eine Sammlung anlegen"
+
+#: views/collections/add.thtml:97
+msgid "collections_add_header_selectedaddons"
+msgstr "Gewählte Add-ons"
+
+#: views/collections/add.thtml:50
+msgid "collections_add_intro"
+msgstr ""
+"Ihre eigene Sammlung anzulegen ist ganz einfach. Füllen Sie einfach die "
+"folgenden, wenigen Felder aus."
+
+#: views/collections/add.thtml:92 views/collections/add.thtml:103
+msgid "collections_add_submit"
+msgstr "Sammlung anlegen"
+
+#: views/pages/collector_faq.thtml:50 views/pages/collector_firstrun.thtml:43
+#: views/pages/collector.thtml:47 views/pages/collector_features.thtml:55
+#: controllers/search_controller.php:302
+#: controllers/collections_controller.php:206
+#: controllers/collections_controller.php:405
+#: controllers/collections_controller.php:467
+#: controllers/collections_controller.php:539
+msgid "collections_breadcrumb"
+msgstr "Sammlungen"
+
+#: views/collections/detail.thtml:185
+msgid "collections_detail_a_learn"
+msgstr "mehr erfahren..."
+
+#: views/elements/amo2009/collection_add_form.thtml:53
+#: views/elements/amo2009/collections_js_init.thtml:68
+#: views/pages/collector_firstrun.thtml:64
+msgid "collections_detail_button_add"
+msgstr "Zu Favoriten hinzufügen"
+
+#: views/elements/amo2009/collection_add_form.thtml:50
+#: views/elements/amo2009/collections_js_init.thtml:71
+msgid "collections_detail_button_remove"
+msgstr "Als Favorit entfernen"
+
+#. %1$s is a URL.
+#. %2$s is a full <a href>.
+#: views/collections/detail.thtml:62
+msgid "collections_detail_created_desc"
+msgstr ""
+"<p>Unten sehen Sie Ihre neue Sammlung. Wenn Sie der Sammlung einen Kurznamen "
+"geben möchten, ein Icon hochladen oder weitere Einstellungen ändern wollen, "
+"verwenden Sie bitte die Seite \"<a href=\"%1$s\">Sammlung Bearbeiten</a>\"</"
+"p><p>Die neue Adresse Ihrer Sammlung ist: %2$s</p>"
+
+#: views/collections/detail.thtml:61
+msgid "collections_detail_created_msg"
+msgstr "Ihre Sammlung ist nun fertig!"
+
+#: views/collections/detail.thtml:109
+msgid "collections_detail_header_about"
+msgstr "Ãœber diese Sammlung"
+
+#. %1$s is a number.
+#: views/collections/detail.thtml:126
+msgid "collections_detail_header_count"
+msgid_plural "collections_detail_header_count"
+msgstr[0] "%1$s Add-on in dieser Sammlung"
+msgstr[1] "%1$s Add-ons in dieser Sammlung"
+
+#: views/collections/detail.thtml:113
+msgid "collections_detail_info_created"
+msgstr "<strong>Angelegt von:</strong> %1$s"
+
+#: views/collections/detail.thtml:117
+msgid "collections_detail_info_updated"
+msgstr "<strong>Aktualisiert:</strong>"
+
+#: views/elements/amo2009/collections_js_init.thtml:62
+msgid "collections_detail_js_adding"
+msgstr "Zu Favoriten hinzufügen&hellip;"
+
+#: views/elements/amo2009/collections_js_init.thtml:65
+msgid "collections_detail_js_removing"
+msgstr "Aus Favoriten entfernen&hellip;"
+
+#. %1$s is a URL
+#: views/collections/detail.thtml:90
+msgid "collections_detail_login"
+msgstr ""
+"<a href=\"%1$s\">Loggen Sie sich ein</a>, um diese Sammlung zu Ihren "
+"Favoriten hinzuzufügen."
+
+#: views/collections/detail.thtml:104
+msgid "collections_detail_manage"
+msgstr "Sammlung bearbeiten"
+
+#: controllers/collections_controller.php:298
+msgid "collections_detail_sort_date"
+msgstr "Hinzugefügt am"
+
+#: controllers/collections_controller.php:299
+msgid "collections_detail_sort_name"
+msgstr "Name"
+
+#: controllers/collections_controller.php:300
+msgid "collections_detail_sort_popularity"
+msgstr "Beliebtheit"
+
+#. %1$s is a number.
+#: views/collections/detail.thtml:166
+msgid "collections_detail_weekly_downloads"
+msgid_plural "collections_detail_weekly_downloads"
+msgstr[0] "%1$s Download diese Woche"
+msgstr[1] "%1$s Downloads diese Woche"
+
+#: views/collections/edit.thtml:255
+msgid "collections_edit_addons_delete_noscript"
+msgstr "Die gewählten Add-ons werden beim Speichern gelöscht"
+
+#: views/collections/edit.thtml:247
+msgid "collections_edit_addons_description"
+msgstr ""
+"Um dieser Sammlung neue Add-ons hinzuzufügen, geben Sie deren Namen unten ein"
+
+#: views/collections/edit.thtml:248
+msgid "collections_edit_addons_description_noscript"
+msgstr ""
+"Um dieser Sammlung neue Add-ons hinzuzufügen, geben Sie eine komma-getrennte "
+"Liste von Add-on ID-Nummern ein."
+
+#: views/collections/edit.thtml:247 views/collections/edit.thtml:248
+msgid "collections_edit_addons_description_publish_detailspage"
+msgstr "Sie können Add-ons auch von deren Add-on-Infoseite aus hinzufügen."
+
+#. %1$s is the date the add-on was added to the collection
+#. %1$s is the name of the user who added the add-on to the collection
+#: views/collections/edit.thtml:260
+msgid "collections_edit_addons_listitem_added"
+msgstr "Hinzugefügt am %1$s von %2$s"
+
+#: views/collections/edit.thtml:263
+msgid "collections_edit_addons_listitem_comment_add"
+msgstr "Kommentar hinzufügen"
+
+#: views/collections/edit.thtml:266
+msgid "collections_edit_addons_listitem_comment_delete"
+msgstr "Kommentar entfernen"
+
+#: views/collections/edit.thtml:265
+msgid "collections_edit_addons_listitem_comment_edit"
+msgstr "Kommentar editieren"
+
+#: views/collections/edit.thtml:271
+msgid "collections_edit_addons_listitem_comment_note"
+msgstr ""
+"Hinweis: Der Kommentar wird so aussehen, als sei er von dem veröffentlicht "
+"worden, der das Add-on dieser Sammlung hinzugefügt hat."
+
+#: views/collections/edit.thtml:270
+msgid "collections_edit_addons_listitem_comment_submit"
+msgstr "Kommentar speichern"
+
+#: views/collections/edit.thtml:261
+msgid "collections_edit_addons_listitem_remove"
+msgstr "Entfernen"
+
+#: views/collections/edit.thtml:250
+msgid "collections_edit_addons_submit"
+msgstr "Zur Sammlung hinzufügen"
+
+#: views/collections/edit.thtml:153
+msgid "collections_edit_check_nickname"
+msgstr "Verfügbarkeit prüfen"
+
+#: views/collections/edit.thtml:299
+msgid "collections_edit_confirm_deletecollection"
+msgstr "Ja, ich möchte diese Sammlung löschen."
+
+#. %1$s is the label of the edit form's submit button
+#: views/collections/edit.thtml:300
+msgid "collections_edit_confirm_deletecollection_description"
+msgstr ""
+"Setzen Sie den Haken, dann klicken Sie auf \"%1$s\" um diese Sammlung zu "
+"löschen."
+
+#. %1$s is the "delete" submit button text
+#. %2$s is the title of the "advanced" tab
+#: views/collections/edit.thtml:95
+msgid "collections_edit_delete_upon_submit"
+msgstr ""
+"Wenn Sie auf \"%1$s\" klicken, wird Ihre Sammlung gelöscht werden. Wenn Sie "
+"Ihre Sammlung nicht löschen möchten, entfernen Sie den Haken im Abschnitt \"%"
+"2$s\" und fahren Sie mit dem Bearbeiten Ihrer Sammlung fort. Wenn Sie diese "
+"Seite verlassen, ohne zu speichern, so wird Ihre Sammlung ebenfalls nicht "
+"gelöscht."
+
+#: views/collections/edit.thtml:94
+msgid "collections_edit_delete_warning"
+msgstr "Ihre Sammlung ist zum Löschen markiert!"
+
+#: views/collections/add.thtml:76 views/collections/edit.thtml:144
+msgid "collections_edit_form_error_description"
+msgstr "Sie müssen eine Beschreibung für Ihre Sammlung eingeben."
+
+#: views/collections/edit.thtml:181
+msgid "collections_edit_form_error_icon"
+msgstr "Beim Hochladen Ihres Icons ist ein Fehler aufgetreten."
+
+#: views/collections/add.thtml:69 views/collections/edit.thtml:130
+msgid "collections_edit_form_error_name"
+msgstr "Sie müssen Ihrer Sammlung einen Namen geben."
+
+#: views/collections/edit.thtml:158
+msgid "collections_edit_form_error_nickname"
+msgstr ""
+"Wenn Sie Ihrer Sammlung einen Spitznamen geben, so darf er noch nicht "
+"vergebensein."
+
+#: views/collections/add.thtml:93 views/collections/edit.thtml:249
+msgid "collections_edit_formfield_addons"
+msgstr "Add-on-Name:"
+
+#: views/collections/edit.thtml:281
+msgid "collections_edit_formfield_application"
+msgstr "Zugeordnete Anwendung"
+
+#: views/collections/edit.thtml:282
+msgid "collections_edit_formfield_application_description"
+msgstr "Wählen Sie die Anwendung, die Ihre Sammlung unterstützt."
+
+#: views/collections/edit.thtml:288
+msgid "collections_edit_formfield_collectiontype"
+msgstr "Sammlungs-Typ"
+
+#: views/collections/edit.thtml:295
+msgid "collections_edit_formfield_deletecollection"
+msgstr "Sammlung löschen"
+
+#: views/collections/edit.thtml:296
+msgid "collections_edit_formfield_deletecollection_description"
+msgstr "Das Löschen Ihrer Sammlung kann nicht rückgängig gemacht werden."
+
+#: views/collections/add.thtml:73 views/collections/edit.thtml:140
+msgid "collections_edit_formfield_description"
+msgstr "Beschreibung der Sammlung"
+
+#: views/collections/add.thtml:74 views/collections/edit.thtml:141
+msgid "collections_edit_formfield_description_description"
+msgstr ""
+"Beschreiben Sie Ihre Sammlung kurz nennen Sie, welche Art Add-ons sich darin "
+"befindet."
+
+#: views/collections/edit.thtml:162
+msgid "collections_edit_formfield_icon"
+msgstr "Icon"
+
+#: views/collections/edit.thtml:163
+msgid "collections_edit_formfield_icon_description"
+msgstr ""
+"Sie können ein Icon im JPG-, GIF- oder PNG-Format hochladen. Es wird auf die "
+"Größe 32x32 Pixel skaliert werden."
+
+#: views/collections/add.thtml:80 views/collections/edit.thtml:189
+msgid "collections_edit_formfield_listed"
+msgstr "Wer kann Ihre Sammlung ansehen?"
+
+#: views/collections/add.thtml:81 views/collections/edit.thtml:190
+msgid "collections_edit_formfield_listed_description"
+msgstr ""
+"Standardmäßig erscheinen Sammlungen im öffentlichen Verzeichnis von "
+"Sammlungen und können von jedermann gesehen werden. Wenn Sie den Zugriff auf "
+"Ihre Sammlung nur auf die Leute beschränken möchten, denen Sie einen "
+"speziellen Link geben, so treffen Sie unten die entsprechende Auswahl."
+
+#: views/collections/add.thtml:84 views/collections/edit.thtml:193
+msgid "collections_edit_formfield_listed_false"
+msgstr "Nur Leute, die ich einlade, können meine Sammlung sehen"
+
+#: views/collections/add.thtml:83 views/collections/edit.thtml:192
+msgid "collections_edit_formfield_listed_true"
+msgstr "Jedermann kann meine Sammlung im Verzeichnis sehen"
+
+#: views/collections/edit.thtml:223
+msgid "collections_edit_formfield_managers"
+msgstr "Wer kann Ihre Sammlung bearbeiten?"
+
+#: views/collections/edit.thtml:224
+msgid "collections_edit_formfield_managers_description"
+msgstr ""
+"Diese Benutzer können Add-ons zu Ihrer Sammlung hinzufügen, alle dort "
+"enthaltenen Add-on-Einträge bearbeiten, alle Einstellungen der Sammlung "
+"verändern, sowie weiteren Benutzern Zugriff darauf verschaffen."
+
+#: views/collections/add.thtml:66 views/collections/edit.thtml:126
+msgid "collections_edit_formfield_name"
+msgstr "Name der Sammlung"
+
+#: views/collections/add.thtml:67 views/collections/edit.thtml:127
+msgid "collections_edit_formfield_name_description"
+msgstr ""
+"Geben Sie Ihrer Sammlung einen erläuternden Namen, wie zum Beispiel "
+"\"Daniels Liste von Reise-Add-ons\""
+
+#: views/collections/edit.thtml:148
+msgid "collections_edit_formfield_nickname"
+msgstr "Spitzname der Sammlung"
+
+#: views/collections/edit.thtml:149
+msgid "collections_edit_formfield_nickname_description"
+msgstr ""
+"Optional können Sie Ihrer Sammlung einen Spitznamen geben, um auf diese "
+"bequemer zugreifen zu können:"
+
+#: views/collections/edit.thtml:201
+msgid "collections_edit_formfield_publishers"
+msgstr "Wer kann Ihrer Sammlung Add-ons hinzufügen?"
+
+#: views/collections/edit.thtml:202
+msgid "collections_edit_formfield_publishers_description"
+msgstr ""
+"Diese Benutzer können Ihrer Sammlung Add-ons hinzufügen und nur diejenigen "
+"Add-ons wieder entfernen, die sie selbst hinzugefügt haben."
+
+#: views/collections/edit.thtml:210 views/collections/edit.thtml:232
+msgid "collections_edit_formfield_users_add"
+msgstr ""
+"Geben Sie eine E-Mail-Adresse an, die einem Benutzerkonto bei Firefox Add-"
+"ons entspricht:"
+
+#: views/collections/edit.thtml:216 views/collections/edit.thtml:238
+msgid "collections_edit_formfield_users_delete_noscript"
+msgstr "Ausgewählte Benutzer werden beim Speichern aus der Liste gelöscht."
+
+#: views/collections/edit.thtml:215 views/collections/edit.thtml:237
+msgid "collections_edit_formfield_users_new_noscript"
+msgstr ""
+"Geben Sie eine durch Kommata getrennte Liste von E-Mail-Adressen ein, die "
+"einem Benutzerkonto bei Firefox Add-ons entsprechen."
+
+#: views/collections/edit.thtml:204 views/collections/edit.thtml:226
+msgid "collections_edit_formfield_users_onlyme"
+msgstr "Nur ich selbst"
+
+#: views/collections/edit.thtml:205 views/collections/edit.thtml:227
+msgid "collections_edit_formfield_users_otherusers"
+msgstr "Ich und folgende Benutzer:"
+
+#: views/collections/edit.thtml:211 views/collections/edit.thtml:233
+msgid "collections_edit_formfield_users_submit"
+msgstr "Hinzufügen"
+
+#. %1$s is the name of the collection
+#: views/collections/edit.thtml:68
+msgid "collections_edit_header"
+msgstr "%1$s bearbeiten"
+
+#: views/collections/edit.thtml:246
+msgid "collections_edit_header_addons"
+msgstr "Inhalt der Sammlung bearbeiten"
+
+#: views/collections/edit.thtml:253 views/collections/edit.thtml:258
+msgid "collections_edit_header_addons_current"
+msgstr "Gegenwärtig enthaltene Add-ons:"
+
+#: views/collections/edit.thtml:279
+msgid "collections_edit_header_advanced"
+msgstr "Besondere Einstellungen"
+
+#: views/collections/edit.thtml:186
+msgid "collections_edit_header_permissions"
+msgstr "Zugriffsrechte bearbeiten"
+
+#: views/collections/edit.thtml:170
+msgid "collections_edit_icon_cancel"
+msgstr "Abbrechen"
+
+#: views/collections/edit.thtml:174 views/collections/edit.thtml:179
+msgid "collections_edit_icon_delete"
+msgstr "Icon löschen"
+
+#: views/collections/edit.thtml:178
+msgid "collections_edit_icon_replace"
+msgstr "Icon ersetzen"
+
+#. %1$s is the label of the edit form's submit button
+#: views/collections/edit.thtml:169
+msgid "collections_edit_icon_toberemoved"
+msgstr "Das Icon wird entfernt werden, wenn Sie auf \"%1$s\" klicken"
+
+#: views/collections/edit.thtml:155
+msgid "collections_edit_nickname_available"
+msgstr "Spitzname verfügbar"
+
+#: controllers/collections_controller.php:943
+msgid "collections_edit_nickname_error"
+msgstr ""
+"Ihr Spitzname enthielt ungültige Zeichen und wurde angepasst. Bitte "
+"versuchen Sie es erneut."
+
+#: views/collections/edit.thtml:156
+msgid "collections_edit_nickname_taken"
+msgstr "Spitzname bereits vergeben"
+
+#. This string is followed by a URL pointing to the collection's view page
+#: views/collections/edit.thtml:75
+msgid "collections_edit_saved_nextstep"
+msgstr "Ihre Sammlung kann unter der folgenden Adresse abgerufen werden:"
+
+#: views/collections/edit.thtml:74
+msgid "collections_edit_saved_success"
+msgstr "Ihre Sammlung wurde erfolgreich gespeichert!"
+
+#: views/collections/edit.thtml:169 views/collections/edit.thtml:300
+#: views/collections/edit.thtml:308 views/pages/js_constants.js.thtml:99
+msgid "collections_edit_submit"
+msgstr "Sammlung speichern"
+
+#: views/collections/edit.thtml:96 views/collections/edit.thtml:297
+#: views/pages/js_constants.js.thtml:100
+msgid "collections_edit_submit_deletecollection"
+msgstr "Sammlung löschen"
+
+#: views/collections/edit.thtml:111
+msgid "collections_edit_tabheader_addons"
+msgstr "Add-ons"
+
+#: views/collections/edit.thtml:97 views/collections/edit.thtml:113
+msgid "collections_edit_tabheader_advanced"
+msgstr "Sonstiges"
+
+#: views/collections/edit.thtml:108
+msgid "collections_edit_tabheader_details"
+msgstr "Name &amp; Details"
+
+#: views/collections/edit.thtml:109
+msgid "collections_edit_tabheader_permissions"
+msgstr "Zugriffsrechte"
+
+#: models/collection_promo.php:53
+msgid "collections_family_tagline"
+msgstr "Achten Sie auf Ihre Kinder und auf Ihren Kalender"
+
+#: models/collection_promo.php:53
+msgid "collections_family_title"
+msgstr "Familie"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:70
+msgid "collections_index_a_check_out"
+msgstr "Probieren Sie den Add-on-Sammler aus"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:52
+msgid "collections_index_a_create"
+msgstr "Eine Sammlung anlegen"
+
+#: views/collections/detail.thtml:139 views/collections/listing.thtml:85
+#: views/search/collections.thtml:84
+msgid "collections_index_button_go"
+msgstr "Los"
+
+#. %1$s is a URL.
+#: controllers/collections_controller.php:182
+msgid "collections_index_filler_favorites"
+msgstr ""
+"<p><strong>Sie haben noch keine Sammlungen zu Favoriten erklärt.</strong></"
+"p> <p>Auf Sammlungen, die Sie als Favoriten markieren, können bequem von "
+"dieser Seite aus zugreifen, und sie werden im <a href='%1$s'>Add-on-Sammler</"
+"a> angezeigt, falls Sie ihn installiert haben.</p>"
+
+#. %1$s is a URL.
+#: controllers/collections_controller.php:167
+msgid "collections_index_filler_mine"
+msgstr ""
+"<p>Sie haben noch keine Sammlungen angelegt. Es ist ganz einfach, Sammlungen "
+"zu erstellen und sie mit Ihren Lieblings-Add-ons zu füllen. <a href=\"%1$s"
+"\">Versuchen Sie's!</a></p>"
+
+#: views/collections/listing.thtml:51
+msgid "collections_index_header_collections"
+msgstr "Sammlungen"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:60
+msgid "collections_index_header_collector"
+msgstr "Add-on-Sammler"
+
+#. %1$s is a comma-separated list of author names
+#: views/elements/amo2009/collection_listing_item.thtml:84
+#: views/collections/detail.thtml:151
+msgid "collections_index_header_created"
+msgstr "erstellt von %1$s"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:47
+msgid "collections_index_header_what"
+msgstr "Was sind Sammlungen?"
+
+#: views/collections/detail.thtml:132 views/collections/listing.thtml:78
+#: views/search/collections.thtml:66
+msgid "collections_index_label_sortby"
+msgstr "Sortieren nach"
+
+#: controllers/collections_controller.php:130
+msgid "collections_index_li_editors"
+msgstr "Empfohlene Sammlungen"
+
+#: views/collections/subscribe.thtml:64
+#: controllers/collections_controller.php:140
+msgid "collections_index_li_favorites"
+msgstr "Meine Favoriten"
+
+#: controllers/collections_controller.php:138
+msgid "collections_index_li_mine"
+msgstr "Eigene Sammlungen"
+
+#: controllers/collections_controller.php:132
+msgid "collections_index_li_popular"
+msgstr "Beliebte Sammlungen"
+
+#: views/search/collections.thtml:74 controllers/collections_controller.php:81
+msgid "collections_index_option_all"
+msgstr "Am beliebtesten aller Zeiten"
+
+#: views/search/collections.thtml:72 controllers/collections_controller.php:78
+msgid "collections_index_option_month"
+msgstr "Am beliebtesten diesen Monat"
+
+#: views/search/collections.thtml:76 controllers/collections_controller.php:84
+msgid "collections_index_option_newest"
+msgstr "Neueste"
+
+#: views/search/collections.thtml:70 controllers/collections_controller.php:75
+msgid "collections_index_option_week"
+msgstr "Am beliebtesten diese Woche"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:67
+msgid "collections_index_p_collector"
+msgstr ""
+"Sammlungen sind ein neuer Weg für Sie, Ihre Lieblings-Add-ons zu verwalten "
+"und neue Add-ons zu entdecken. Kommentieren Sie Sammlungen, empfehlen Sie "
+"sie weiter und bleiben Sie stets auf dem Laufenden, alles direkt von Ihrem "
+"Browser aus."
+
+#: views/elements/amo2009/collector_info_secondary.thtml:48
+msgid "collections_index_p_what_are"
+msgstr ""
+"Sammlungen sind Gruppen von Add-ons, die zum einfachen Verteilen gebündelt "
+"werden."
+
+#. %s is a date in the _('date') format
+#: views/elements/collections_interactive_addon.thtml:85
+#, php-format
+msgid "collections_interactive_addon_added"
+msgstr "Hinzugefügt am %s"
+
+#: models/collection_promo.php:55
+msgid "collections_reference_tagline"
+msgstr "Recherchieren Sie online, was auch immer Sie möchten"
+
+#: models/collection_promo.php:55
+msgid "collections_reference_title"
+msgstr "Recherchieren"
+
+#: models/collection_promo.php:52
+msgid "collections_social_tagline"
+msgstr "Verwalten Sie Ihr Sozialnetzwerk"
+
+#: models/collection_promo.php:52
+msgid "collections_social_title"
+msgstr "Sozial"
+
+#: views/collections/subscribe.thtml:91
+msgid "collections_subscribe_button_close"
+msgstr "Schließen"
+
+#: views/collections/subscribe.thtml:70
+msgid "collections_subscribe_error"
+msgstr ""
+"Beim Speichern der Sammlung als Favoriten ist ein Fehler aufgetreten. Ist "
+"diese Sammlung bereits ein Favorit?"
+
+#: views/collections/subscribe.thtml:96
+msgid "collections_subscribe_label_bothersome"
+msgstr "Diese Nachricht nicht erneut anzeigen."
+
+#. %1$s is the collection name
+#: views/collections/subscribe.thtml:60
+msgid "collections_subscribe_success"
+msgstr "%1$s wurde zu Ihren Favoriten hinzugefügt."
+
+#. %1$s is the link to the "My Favorites" tab on the main collections page
+#. %2$s is the localized title of the "My Favorites" tab
+#. %3$s is the link URL to the collector add-on
+#: views/collections/subscribe.thtml:62
+msgid "collections_subscribe_success_desc"
+msgstr ""
+"Sie können diese Sammlung nun ganz schnell im Abschnitt <a href=\"%1$s\">%2"
+"$s</a> des Verzeichnisses finden. Um Ihre Sammlungen noch leichter zu "
+"verwalten, versuchen Sie doch einmal die Erweiterung <a href=\"%3$s\">Add-on-"
+"Sammler</a> für Firefox."
+
+#: views/collections/listing.thtml:55
+msgid "collections_success_delete"
+msgstr "Diese Sammlung wurde gelöscht."
+
+#: models/collection_promo.php:54
+msgid "collections_travel_tagline"
+msgstr "Planen Sie Geschäftsreisen und unvergessliche Urlaube"
+
+#: models/collection_promo.php:54
+msgid "collections_travel_title"
+msgstr "Reisen"
+
+#. A collection of add-ons that is automatically built for a user. They are "automatically published" to this collection.
+#: controllers/collections_controller.php:581
+msgid "collections_type_autopublisher"
+msgstr "Auto-Veröffentlichung"
+
+#. A collection that has been chosen by an Editor as notable or exceptional
+#: controllers/collections_controller.php:582
+msgid "collections_type_editorspick"
+msgstr "Empfohlen"
+
+#: controllers/collections_controller.php:580
+msgid "collections_type_normal"
+msgstr "Normal"
+
+#: views/collections/subscribe.thtml:84
+msgid "collections_unsubscribe_error"
+msgstr ""
+"Beim Entfernen dieser Sammlung aus den Favoriten ist ein Fehler aufgetreten. "
+"Ist diese Sammlung bereits kein Favorit mehr?"
+
+#. %1$s is the collection name
+#: views/collections/subscribe.thtml:78
+msgid "collections_unsubscribe_success"
+msgstr "%1$s wurde aus Ihren Favoriten entfernt."
+
+#: models/collection_promo.php:56
+msgid "collections_webdev_tagline"
+msgstr "Bauen Sie eine perfekte Webseite"
+
+#: models/collection_promo.php:56
+msgid "collections_webdev_title"
+msgstr "Web-Entwicklung"
+
+#: views/elements/amo2009/collections_sidebar_whatare.thtml:40
+msgid "collections_whatare_header"
+msgstr "Was sind Sammlungen?"
+
+#: views/elements/amo2009/collections_sidebar_whatare.thtml:45
+msgid "collections_whatare_learnmore"
+msgstr "Häufige Fragen lesen"
+
+#: views/elements/amo2009/collections_sidebar_whatare.thtml:44
+msgid "collections_whatare_text"
+msgstr ""
+"Sammlungen sind ein neuer Weg für Sie, Ihre Lieblings-Add-ons zu verwalten "
+"und neue Add-ons zu entdecken. Kommentieren Sie Sammlungen, empfehlen Sie "
+"sie weiter und bleiben Sie stets auf dem Laufenden, alles direkt von Ihrem "
+"Browser aus."
+
+#: views/pages/collector_faq.thtml:61 views/pages/collector_features.thtml:67
+msgid "collector_features_a_home"
+msgstr "Add-on-Sammler Homepage"
+
+#: views/elements/amo2009/collector_sidebar_download.thtml:46
+msgid "collector_features_heading_download"
+msgstr "Laden Sie den Add-on-Sammler herunter:"
+
+#: views/elements/amo2009/collector_sidebar_download.thtml:43
+#: views/pages/collector_firstrun.thtml:116 views/pages/collector.thtml:69
+msgid "collector_features_img_logo"
+msgstr "Logo des Add-on-Sammlers"
+
+#: views/compatibility/dashboard.thtml:49
+#: controllers/compatibility_controller.php:72
+msgid "compatibility_dashboard_center_header"
+msgstr "Add-on Kompatibilitäts-Zentrum"
+
+#. %1$s is the name of an application and a version. Example: Firefox 3.0
+#. %2$s is the name of an application. Example: Firefox
+#: views/compatibility/dashboard.thtml:50
+msgid "compatibility_dashboard_intro"
+msgstr ""
+"Freuen Sie sich auf das Release von %1$s, mit den folgenden Werkzeugen und "
+"Informationen exklusiv für die %2$s Add-ons Community."
+
+#: views/compatibility/dashboard.thtml:103
+msgid "compatibility_dashboard_loading"
+msgstr "Daten werden geladen..."
+
+#: views/compatibility/dashboard.thtml:45
+msgid "compatibility_dashboard_main_link"
+msgstr "Zurück zur Hauptseite"
+
+#: views/compatibility/dashboard.thtml:100 views/compatibility/report.thtml:43
+msgid "compatibility_dashboard_report"
+msgstr "Add-on-Kompatibilitäts-Report"
+
+#: views/compatibility/dashboard.thtml:53
+#: views/compatibility/dashboard.thtml:110
+#: views/compatibility/developers.thtml:43
+msgid "compatibility_developer_info"
+msgstr "Informationen für Add-on-Entwickler"
+
+#: views/compatibility/developers.thtml:66
+msgid "compatibility_developers_adjust_maxversion"
+msgstr "maxVersion anpassen ohne Hochladen"
+
+#: views/compatibility/dashboard.thtml:124
+msgid "compatibility_developers_check_status"
+msgstr "Status meiner Add-ons prüfen"
+
+#. %1$s is a URL
+#. %2$s is an application and version. Example: Firefox 3.0
+#: views/compatibility/dashboard.thtml:126
+msgid "compatibility_developers_login_first"
+msgstr ""
+"Wenn Sie Add-ons auf Mozilla Add-ons besitzen, <a href=\"%1$s\">loggen Sie "
+"sich bitte ein</a>, um den Status Ihrer Add-ons für %2$s zu sehen."
+
+#: views/compatibility/dashboard.thtml:114
+msgid "compatibility_developers_mdclogo_alt"
+msgstr "Mozilla Developer Center Logo"
+
+#: views/compatibility/developers.thtml:73
+msgid "compatibility_developers_no_addons"
+msgstr "Sie haben keine Add-ons auf Mozilla Add-ons hochgeladen."
+
+#: views/compatibility/dashboard.thtml:133
+#: views/compatibility/developers.thtml:55
+msgid "compatibility_developers_results"
+msgstr "Ergebnisse der Add-on-Statusprüfung"
+
+#: views/compatibility/dashboard.thtml:137
+msgid "compatibility_developers_retrieving"
+msgstr "Status Ihrer Add-ons wird geladen..."
+
+#. %1$s is a number
+#. %2$s is an application name
+#. %3$s is a number.
+#. Full example: 50 Firefox users (10% of total)
+#: views/compatibility/developers.thtml:65
+msgid "compatibility_developers_user_count"
+msgstr "%1$s %2$s Benutzer (%3$s&#37; von allen)"
+
+#: views/compatibility/report.thtml:45
+msgid "compatibility_report_detail_intro"
+msgstr ""
+"Die folgenden Add-ons machen 95% der Add-on-Benutzung aus, die Mozilla "
+"bekannt ist. Sie sind nach ihrer Benutzungsmenge sortiert."
+
+#: views/compatibility/dashboard.thtml:94
+msgid "compatibility_report_detailed_link"
+msgstr "Detailierten Report anzeigen"
+
+#. %1$s and %2$s are numbers
+#. %3$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:65
+msgid "compatibility_report_intro"
+msgstr ""
+"Von den %1%s Add-ons, die 95&#37; der Add-on-Benutzung ausmachen, die "
+"Mozilla bekannt ist, sind <b>%2$s&#37;</b> gegenwärtig mit den jüngsten "
+"Versionen von %3$2 kompatibel."
+
+#: views/compatibility/dashboard.thtml:81
+msgid "compatibility_report_legend_alpha"
+msgstr "Alpha-Versionen"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:81
+msgid "compatibility_report_legend_alpha_description"
+msgstr "Add-ons, die mit einer Alpha-Version von %1$s kompatibel sind"
+
+#: views/compatibility/dashboard.thtml:85
+msgid "compatibility_report_legend_beta"
+msgstr "Beta-Versionen"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:85
+msgid "compatibility_report_legend_beta_description"
+msgstr "Add-ons, die mit einer Beta-Version von %1$s kompatibel sind"
+
+#: views/compatibility/dashboard.thtml:89
+msgid "compatibility_report_legend_latest"
+msgstr "Neueste Version"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:89
+msgid "compatibility_report_legend_latest_description"
+msgstr "Add-ons, die mit den neuesten Versionen von %1$s kompatibel sind"
+
+#: views/compatibility/dashboard.thtml:77
+msgid "compatibility_report_legend_other"
+msgstr "Andere Versionen"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:77
+msgid "compatibility_report_legend_other_description"
+msgstr "Add-ons, die mit keiner Version von %1$s kompatibel sind"
+
+#: views/compatibility/dashboard.thtml:62
+msgid "compatibility_report_title"
+msgstr "Add-on-Kompatibilitäts-Report"
+
+#: views/compatibility/dashboard.thtml:54
+#: views/compatibility/dashboard.thtml:144 views/compatibility/users.thtml:42
+msgid "compatibility_user_info"
+msgstr "Informationen für Add-on-Benutzer"
+
+#: views/compatibility/dashboard.thtml:52
+msgid "compatibility_view_report"
+msgstr "Kompatibilitäts-Report anzeigen"
+
+#. %s is a URL
+#: views/pages/credits.thtml:142
+#, php-format
+msgid "credits_contributing"
+msgstr ""
+"Wenn Sie auch einen Beitrag leisten möchten, sehen Sie sich diese %s an."
+
+#: views/pages/credits.thtml:142
+msgid "credits_contributing_wikipage"
+msgstr "Wiki-Seite"
+
+#: views/pages/credits.thtml:99
+msgid "credits_intro"
+msgstr ""
+"Mozilla dankt den folgenden Personen für Ihre Beiträge zum addons.mozilla."
+"org-Projekt im Laufe der Jahre:"
+
+#: views/pages/credits.thtml:103
+msgid "credits_section_developers"
+msgstr "Entwickler"
+
+#: views/pages/credits.thtml:115
+msgid "credits_section_editors"
+msgstr "Moderatoren"
+
+#: views/pages/credits.thtml:109
+msgid "credits_section_localizers"
+msgstr "Ãœbersetzer"
+
+#: views/pages/credits.thtml:121
+msgid "credits_section_other_contributors"
+msgstr "Andere Helfer"
+
+#: views/pages/credits.thtml:127
+msgid "credits_section_past_developers"
+msgstr "Ehemalige Entwickler"
+
+#: views/pages/credits.thtml:133
+msgid "credits_section_software"
+msgstr "Software and Bilder"
+
+#: views/pages/credits.thtml:136
+msgid "credits_software_famfamfam"
+msgstr ""
+"Einige Icons stammen aus der <a href=\"http://www.famfamfam.com/lab/icons/"
+"silk/\">famfamfam Silk Icon-Kollektion</a>, lizensiert unter einer <a href="
+"\"http://creativecommons.org/licenses/by/2.5/deed.de\">Creative Commons "
+"Attribution 2.5 Lizenz</a>."
+
+#: views/pages/credits.thtml:137
+msgid "credits_software_timeplot"
+msgstr ""
+"Manche Seiten verwenden Elemente von <a href=\"http://www.simile-widgets.org/"
+"timeplot/\">Timeplot</a>, lizensiert unter einer <a href=\"http://simile.mit."
+"edu/license.html\">BSD Lizenz</a>."
+
+#. date format string as used in PHP's strftime():
+#. http://php.net/strftime
+#: views/elements/collections_interactive_addon.thtml:85
+#: views/elements/amo2009/addon_version_detail.thtml:53
+#: views/elements/amo2009/homepage_addon.thtml:115
+#: views/elements/addon_version_detail.thtml:54
+#: views/elements/addon_listitem.thtml:124 views/elements/feature.thtml:106
+#: views/collections/detail.thtml:118 views/collections/edit.thtml:325
+#: views/users/info.thtml:76 views/editors/reviews_queue.thtml:57
+#: views/editors/reviews_queue.thtml:68 views/developers/dashboard.thtml:65
+#: views/developers/versions_edit.thtml:208 views/developers/versions.thtml:67
+#: views/search/rss/index.thtml:5 views/addons/rss/versions.thtml:42
+#: views/addons/display.thtml:104 views/addons/display.thtml:356
+#: views/addons/browse_thumbs.thtml:75 views/reviews/add.thtml:63
+#: views/reviews/display.thtml:74 views/reviews/display.thtml:160
+#: views/reviews/delete.thtml:54 controllers/statistics_controller.php:244
+#: controllers/collections_controller.php:1047
+msgid "date"
+msgstr "%e.%m.%Y"
+
+#. date and time format string (strftime)
+#. http://php.net/strftime
+#: views/elements/addon_version_detail.thtml:53
+#: views/developers/discuss.thtml:52 views/developers/discuss.thtml:62
+#: views/admin/addons_status.thtml:57
+msgid "datetime"
+msgstr "%e.%m.%Y %H:%M"
+
+#: views/elements/developers/actionbar.thtml:47
+msgid "devcp_actionbar_link_details"
+msgstr "Ausführliche Informationen"
+
+#: views/elements/developers/actionbar.thtml:42
+#: views/elements/developers/actionbar.thtml:50
+#: views/developers/dashboard.thtml:64
+msgid "devcp_actionbar_link_edit"
+msgstr "Add-on bearbeiten"
+
+#: views/elements/developers/actionbar.thtml:51
+msgid "devcp_actionbar_link_newversion"
+msgstr "Neue Version hochladen"
+
+#: views/elements/developers/actionbar.thtml:44
+#: views/elements/developers/actionbar.thtml:49
+#: views/developers/dashboard.thtml:73
+msgid "devcp_actionbar_link_stats"
+msgstr "Statistiken"
+
+#. %1$s is a filename, e.g. "foo.txt"
+#. %2$s is the extension, e.g. ".txt"
+#. %3$s is a list of valid extensions, like ".png, .jpg, .gif"
+#: controllers/developers_controller.php:1361
+msgid "devcp_add_previews_extension_error"
+msgstr ""
+"Die Datei %1$s hat eine ungültige Erweiterung (%2$s). Erlaubte "
+"Erweiterungen: %3$s"
+
+#. %s is the filename.
+#: controllers/developers_controller.php:1394
+msgid "devcp_add_previews_save_error"
+msgstr ""
+"Die Datei %s konnte nicht gespeichert werden. Bitte versuchen Sie es erneut."
+
+#. %1$s is the preview ID number, %2$s is the filename.
+#: controllers/developers_controller.php:1389
+msgid "devcp_add_previews_success_replace"
+msgstr "Vorschau %1$s wurde erfolgreich durch die Datei %2$s ersetzt."
+
+#. %s is the filename.
+#: controllers/developers_controller.php:1391
+msgid "devcp_add_previews_success_upload"
+msgstr ""
+"Die Datei %s wurde erfolgreich hochgeladen. Sie können nun eine Beschreibung "
+"hinzufügen."
+
+#: controllers/components/developers.php:1163
+msgid "devcp_additem_addontype_autodetect"
+msgstr "(automatisch)"
+
+#: views/elements/developers/additem.thtml:76
+msgid "devcp_additem_linktitle_opensin_newwindow"
+msgstr "Öffnet in einem neuen Fenster"
+
+#: views/elements/developers/additem.thtml:41
+msgid "devcp_additem_sidebar_title"
+msgstr "Neues Add-on anlegen"
+
+#: views/elements/developers/additem.thtml:53
+msgid "devcp_additem_step0_newlink"
+msgstr "Einverständniserklärung der Entwickler"
+
+#: views/elements/developers/additem.thtml:46
+msgid "devcp_additem_step1_link"
+msgstr "Schritt 1: Hochladen"
+
+#: views/elements/developers/additem.thtml:47
+msgid "devcp_additem_step2_link"
+msgstr "Schritt 2: Add-on-Details"
+
+#: views/elements/developers/additem.thtml:48
+msgid "devcp_additem_step3_link"
+msgstr "Schritt 3: Versionsdetails"
+
+#: views/elements/developers/additem.thtml:49
+msgid "devcp_additem_step4_link"
+msgstr "Schritt 4: Ãœbersetzung"
+
+#: views/elements/developers/additem.thtml:50
+msgid "devcp_additem_step5_link"
+msgstr "Schritt 5: Erfolreicher Abschluss"
+
+#: views/elements/developers/additem.thtml:76
+msgid "devcp_additem_submissionhelp_link"
+msgstr "Ãœbermittlungshilfe"
+
+#: controllers/previews_controller.php:168
+#: controllers/previews_controller.php:277
+msgid "devcp_addon_field_preview_caption_displaytitle"
+msgstr "Vorschauuntertitel"
+
+#: views/developers/addon_status.thtml:177
+msgid "devcp_addon_status_action_activate"
+msgstr "Aktivieren"
+
+#: views/developers/addon_status.thtml:178
+msgid "devcp_addon_status_action_activate_description"
+msgstr ""
+"Aktivieren Sie Ihr Add-on, damit es auf öffentlichen Bereichen der Seite "
+"angezeigt wird, und damit Benutzer automatisch Updates erhalten können."
+
+#: views/developers/addon_status.thtml:135
+msgid "devcp_addon_status_action_complete"
+msgstr "Add-on vervollständigen"
+
+#: views/developers/addon_status.thtml:136
+msgid "devcp_addon_status_action_complete_description"
+msgstr "Vervollständigen Sie Ihr Add-on und bringen Sie es in den Sandkasten"
+
+#: views/developers/addon_status.thtml:181
+msgid "devcp_addon_status_action_deactivate"
+msgstr "Deaktivieren"
+
+#: views/developers/addon_status.thtml:182
+msgid "devcp_addon_status_action_deactivate_description"
+msgstr ""
+"Deaktivieren Sie Ihr Add-on, um es von öffentlichen Bereichen der Seite "
+"verschwindet, und damit Benutzer keine Updates mehr erhalten."
+
+#: views/developers/addon_status.thtml:143
+msgid "devcp_addon_status_action_move"
+msgstr "In den Sandkasten"
+
+#: views/developers/addon_status.thtml:144
+msgid "devcp_addon_status_action_move_description"
+msgstr ""
+"Schicken Sie Ihr Add-on zurück in den Sandkasten. Dies kann rückgängig "
+"gemacht werden."
+
+#: views/developers/addon_status.thtml:139
+msgid "devcp_addon_status_action_nominate"
+msgstr "Zur Veröffentlichung nominieren"
+
+#: views/developers/addon_status.thtml:140
+msgid "devcp_addon_status_action_nominate_description"
+msgstr "Nominieren Sie Ihr Add-on für die Veröffentlichung"
+
+#: views/developers/addon_status.thtml:147
+msgid "devcp_addon_status_action_public"
+msgstr "Veröffentlichen"
+
+#: views/developers/addon_status.thtml:148
+msgid "devcp_addon_status_action_public_description"
+msgstr "Veröffentlichen Sie Ihr Add-on erneut."
+
+#: views/developers/addon_status.thtml:169
+msgid "devcp_addon_status_active"
+msgstr ""
+"Ihr Add-on ist <span class=\"inactive-0\">aktiv</span>. Das bedeutet, dass "
+"Ihr Add-on an allen Stellen gezeigt wird, die seinem oben genannten Status "
+"entsprechen."
+
+#: views/developers/addon_status.thtml:111
+msgid "devcp_addon_status_completion_disabled"
+msgstr ""
+"Bitte erfüllen Sie die oben genannten Kriterien, bevor Sie Ihr Add-on "
+"vervollständigen und in den <span class=\"status-1\">Sandkasten</span> "
+"bewegen können."
+
+#: views/developers/addon_status.thtml:108
+msgid "devcp_addon_status_completion_enabled"
+msgstr ""
+"Sie können Ihr Add-on nun vervollständigen und es in den <span class="
+"\"status-1\">Sandkasten</span> bewegen, indem Sie auf die unten stehende "
+"Schaltfläche klicken."
+
+#: views/developers/addon_status.thtml:102
+msgid "devcp_addon_status_criteria_category"
+msgstr "Mindestens eine Kategorie gewählt"
+
+#: views/developers/addon_status.thtml:101
+msgid "devcp_addon_status_criteria_description"
+msgstr "Add-on-Beschreibung benötigt"
+
+#: views/developers/addon_status.thtml:99
+msgid "devcp_addon_status_criteria_name"
+msgstr "Add-on-Name benötigt"
+
+#: views/developers/addon_status.thtml:120
+msgid "devcp_addon_status_criteria_prerelease"
+msgstr "Add-on ist nicht als Testversion markiert."
+
+#: views/developers/addon_status.thtml:119
+msgid "devcp_addon_status_criteria_preview"
+msgstr "Erweiterungen und Themes müssen mindestens ein Vorschaubild haben."
+
+#: views/developers/addon_status.thtml:100
+msgid "devcp_addon_status_criteria_summary"
+msgstr "Add-on-Zusammenfassung benötigt"
+
+#. %s is the status in a span, e.g. "<span>_('Public')</span>".
+#: views/developers/addon_status.thtml:58
+msgid "devcp_addon_status_header"
+msgstr "Add-on-Status: %s"
+
+#: views/developers/addon_status.thtml:152
+#: views/developers/addon_status.thtml:173
+msgid "devcp_addon_status_header_actions"
+msgstr "Verfügbare Aktionen"
+
+#: views/developers/addon_status.thtml:168
+msgid "devcp_addon_status_header_active"
+msgstr "Aktivitäts-Status: <span class=\"inactive-0\">Aktiv</span>"
+
+#: views/developers/addon_status.thtml:97
+msgid "devcp_addon_status_header_criteria"
+msgstr "Kriterien zur Vervollständigung"
+
+#: views/developers/addon_status.thtml:164
+msgid "devcp_addon_status_header_inactive"
+msgstr "Aktivitäts-Status: <span class=\"inactive-1\">Deaktiviert</span>"
+
+#: views/developers/addon_status.thtml:117
+msgid "devcp_addon_status_header_nomination"
+msgstr "Kriterien zur Veröffentlichung"
+
+#: views/developers/addon_status.thtml:190
+msgid "devcp_addon_status_header_trusted"
+msgstr "Vertrauens-Status: <span class=\"status-4\">Vertraut</span>"
+
+#: views/developers/addon_status.thtml:165
+msgid "devcp_addon_status_inactive"
+msgstr ""
+"Ihr Add-on ist <span class=\"inactive-1\">deaktiviert</span>. Das bedeutet, "
+"dass Ihr Add-on in keinen Listen gezeigt wird, unabhängig von seinem oben "
+"genannten Status. Benutzer des Add-ons erhalten <strong>keine</strong> "
+"automatischen Updates."
+
+#: views/developers/addon_status.thtml:128
+msgid "devcp_addon_status_nominate_disabled"
+msgstr ""
+"Bitte erfüllen Sie die oben genannten Kriterien, bevor Sie Ihr Add-on für "
+"die <span class=\"status-4\">Veröffentlichung</span> nominieren."
+
+#: views/developers/addon_status.thtml:125
+msgid "devcp_addon_status_nominate_enabled"
+msgstr ""
+"Sie können Ihr Add-on nun für die <span class=\"status-4\">Veröffentlichung</"
+"span> nominieren, indem Sie auf die unten stehende Schaltfläche klicken."
+
+#: views/developers/addon_status.thtml:64
+msgid "devcp_addon_status_public"
+msgstr "Öffentlich"
+
+#: views/developers/addon_status.thtml:63
+msgid "devcp_addon_status_sandbox"
+msgstr "Sandkasten"
+
+#. %s is an email address.
+#: views/developers/addon_status.thtml:89
+msgid "devcp_addon_status_switch_disabled"
+msgstr ""
+"Ihr Add-on wurde von einem Administrator <span class=\"status-5"
+"\">deaktiviert</span> und kann nicht mehr verwendet werden. Falls Sie Fragen "
+"haben, schreiben Sie bitte eine E-Mail an %s."
+
+#: views/developers/addon_status.thtml:67
+msgid "devcp_addon_status_switch_incomplete"
+msgstr ""
+"Ihr Add-on ist gegenwärtig <span class=\"status-0\">unvollständig</span>. "
+"Das bedeutet, dass Ihr Add-on nirgendwo auf der Seite gezeigt wird. Benutzer "
+"des Add-ons erhalten keine automatischen Updates. Sie können zu dieser Seite "
+"zurückkehren, um Ihr Add-on zu vervollständigen, nachdem es die unten "
+"stehenden Kriterien erfüllt. Dann können Sie es in den <span class=\"status-1"
+"\">Sandkasten</span> bewegen."
+
+#. %s is a number, perhaps 42.
+#: views/developers/addon_status.thtml:77
+msgid "devcp_addon_status_switch_nominated"
+msgstr ""
+"Ihr Add-on ist gegenwärtig zur <span class=\"status-4\">Veröffentlichung</"
+"span> nominiert und wartet auf die Bewertung durch einen Moderator. Zurzeit "
+"warten noch %s weitere Add-ons auf eine Bewertung."
+
+#. %s is an email address.
+#: views/developers/addon_status.thtml:81
+msgid "devcp_addon_status_switch_pending"
+msgstr ""
+"Der Status Ihres Add-ons ist fehlerhaft. Das hätte nicht passieren dürfen. "
+"Bitte senden Sie eine E-Mail an %s, nennen Sie die ID-Nummer Ihres Add-ons "
+"und diesen Fehler."
+
+#: views/developers/addon_status.thtml:85
+msgid "devcp_addon_status_switch_public"
+msgstr ""
+"Ihr Add-on ist gegenwärtig <span class=\"status-4\">öffentlich</span>. Das "
+"bedeutet, dass Ihr Add-on auf allen Listen und in Suchergebnissen angezeigt "
+"wird. Außerdem kann es ohne Einschränkung heruntergeladen werden. Benutzer "
+"des Add-ons erhalten automatische Updates."
+
+#: views/developers/addon_status.thtml:71
+#: views/developers/addon_status.thtml:75
+msgid "devcp_addon_status_switch_sandbox"
+msgstr ""
+"Ihr Add-on ist gegenwärtig im <span class=\"status-1\">Sandkasten</span>. "
+"Das bedeutet, dass Ihr Add-on auf Listen und in Suchergebnissen angezeigt "
+"wird, aber Benutzer müssen sich einloggen, bevor sie es herunterladen "
+"können. Benutzer des Add-ons erhalten <strong>keine</strong> automatischen "
+"Updates."
+
+#. %s is the add-on name.
+#: views/developers/addon_status_nominate.thtml:43
+#: views/developers/addon_status_confirm.thtml:43
+#: views/developers/addon_status.thtml:43
+msgid "devcp_addon_status_title"
+msgstr "Status von %s"
+
+#: views/developers/addon_status.thtml:191
+msgid "devcp_addon_status_trusted"
+msgstr ""
+"Ihrem Add-on wird <span class=\"status-4\">vertraut</span>. Das bedeutet, "
+"Sie können Updates für Ihr Add-on übermitteln ohne die Bewertung eines "
+"Moderators."
+
+#: views/developers/dashboard.thtml:68
+msgid "devcp_dashboard_active"
+msgstr "Aktiv"
+
+#. %1$s is the add-on type string
+#. %2$s is Inactive or Active in a <span>
+#. %3$s is the addon's public status (Public, In Sandbox, ...) in a <span>
+#: views/developers/dashboard.thtml:69
+msgid "devcp_dashboard_addontype_status"
+msgstr "%1$s ist gegenwärtig %2$s und %3$s"
+
+#: views/developers/dashboard.thtml:67
+msgid "devcp_dashboard_change_status"
+msgstr "Status ändern"
+
+#. %s is the addons email address.
+#: views/developers/dashboard.thtml:99
+msgid "devcp_dashboard_disabled_questions"
+msgstr ""
+"Ihr Add-on wurde von einem Administrator deaktiviert und kann nicht mehr "
+"verwendet werden. Falls Sie Fragen haben, schreiben Sie bitte eine E-Mail an "
+"%s."
+
+#. %s is the (localized) add-on status string in a span, e.g. "Disabled"
+#: views/developers/dashboard.thtml:98
+msgid "devcp_dashboard_disabled_status"
+msgstr "Add-on-Status: %s"
+
+#: views/developers/dashboard.thtml:43
+msgid "devcp_dashboard_header_main"
+msgstr "Entwickler-Seite"
+
+#: views/developers/dashboard.thtml:110
+msgid "devcp_dashboard_header_welcome"
+msgstr "Willkommen auf der Entwickler-Seite"
+
+#: views/developers/dashboard.thtml:68
+msgid "devcp_dashboard_inactive"
+msgstr "Deaktiviert"
+
+#. %s is a date in the _('date') format
+#: views/developers/dashboard.thtml:65
+msgid "devcp_dashboard_last_edited"
+msgstr "Zuletzt editiert am %s"
+
+#: views/developers/dashboard.thtml:111
+msgid "devcp_dashboard_learn"
+msgstr ""
+"Sie besitzen gegenwärtig keine Add-ons auf Mozilla Add-ons. Wenn Sie lernen "
+"möchten, wie der Prozess funktioniert, und um Ihr erstes Add-on zu "
+"übermitteln, klicken Sie auf \"Los geht's!\""
+
+#: views/developers/dashboard.thtml:112
+msgid "devcp_dashboard_start"
+msgstr "Los geht's!"
+
+#: views/developers/dashboard.thtml:82
+msgid "devcp_dashboard_versions"
+msgstr "Versionen und Dateien"
+
+#: views/developers/dashboard.thtml:91
+msgid "devcp_dashboard_versions_new"
+msgstr "Neue Version hochladen"
+
+#. %s is the preview ID number.
+#: controllers/developers_controller.php:1415
+msgid "devcp_delete_previews_error"
+msgstr ""
+"Die Vorschau Nummer %s konnte nicht aus der Datenbank gelöscht werden. Bitte "
+"versuchen Sie es erneut."
+
+#. %s is the preview ID number.
+#: controllers/developers_controller.php:1413
+msgid "devcp_delete_previews_success"
+msgstr "Die Vorschau Nummer %s wurde erfolgreich gelöscht."
+
+#: controllers/developers_controller.php:1089
+msgid "devcp_delete_version_priv_error"
+msgstr ""
+"Sie haben nicht das die Berechtigung dazu, Versionen oder Dateien zu löschen."
+
+#. %1$s is the count of files, a number
+#. %2$s is a status string like _('Public') or _('Incomplete')
+#: controllers/components/amo.php:549
+msgid "devcp_describe_version_status"
+msgid_plural "devcp_describe_version_status"
+msgstr[0] "%1$s Datei ist %2$s"
+msgstr[1] "%1$s Dateien sind %2$s"
+
+#. %s is a version number. Example: 3.0
+#: views/developers/versions.thtml:65
+#, php-format
+msgid "devcp_details_version"
+msgstr "Version %s"
+
+#: views/developers/discuss.thtml:68
+msgid "devcp_discuss_addreply_header"
+msgstr "Einen Kommentar schreiben"
+
+#: views/developers/discuss.thtml:57
+msgid "devcp_discuss_allreplies_header"
+msgstr "Alle Antworten"
+
+#. notice when an error occurs saving a discussion reply
+#. %1 is the email address (linked) for the amo-editors list
+#: views/developers/discuss.thtml:70
+msgid "devcp_discuss_error_notice"
+msgstr ""
+"Beim Speichern Ihrer Antwort ist ein Fehler aufgetreten. Bitte kontaktieren "
+"Sie %1$s wegen dieses Problems."
+
+#. %1 is the add-on name, %2 is the add-on's version number currently being reviewed by an editor
+#: views/developers/discuss.thtml:46
+msgid "devcp_discuss_intro"
+msgstr ""
+"Ein Mozilla Add-ons Editor hat um weitere Informationen hinsichtlich der "
+"Version %2$s Ihres Add-ons %1$s gebeten."
+
+#. %1 is the add-on name
+#: views/developers/discuss.thtml:43
+msgid "devcp_discuss_pagetitle"
+msgstr "Mehr Informationen zur Bewertung von %1$s abgeben"
+
+#. submit button text
+#: views/developers/discuss.thtml:79
+msgid "devcp_discuss_submit_reply"
+msgstr "Antwort abschicken"
+
+#: views/developers/discuss.thtml:72
+msgid "devcp_discuss_success_message"
+msgstr ""
+"Ihre Antwort wurde erfolgreich gespeichert. Die anderen Teilnehmer an dieser "
+"Diskussion werden davon per E-Mail in Kenntnis gesetzt."
+
+#. in an author/editor discussion about an add-on to be reviewed:
+#. %1 is the commenter's user name (linked).
+#. %2 is the full date the comment was made.
+#: views/developers/discuss.thtml:52 views/developers/discuss.thtml:62
+msgid "devcp_discuss_writtenby"
+msgstr "geschrieben von %1$s am %2$s"
+
+#: views/developers/addon_edit_authors.thtml:72
+#: views/developers/addon_edit_authors.thtml:81
+msgid "devcp_edit_authors_add_author"
+msgstr "Einen neuen Autor hinzufügen"
+
+#: views/developers/addon_edit_authors.thtml:96
+msgid "devcp_edit_authors_add_author_button"
+msgstr "Autor hinzufügen"
+
+#: views/developers/addon_edit_authors.thtml:83
+msgid "devcp_edit_authors_add_email"
+msgstr "E-Mail-Adresse des Autors:"
+
+#: views/developers/addon_edit_authors.thtml:98
+msgid "devcp_edit_authors_add_loading"
+msgstr "E-Mail-Adresse wird geprüft..."
+
+#: views/developers/addon_edit_authors.thtml:70
+msgid "devcp_edit_authors_click_save"
+msgstr ""
+"Klicken Sie unten auf \"aktualisieren\", um die Liste der Autoren zu "
+"speichern."
+
+#: views/developers/addon_edit_authors.thtml:58
+msgid "devcp_edit_authors_header_current"
+msgstr "Aktuelle Autoren"
+
+#: views/developers/addon_edit_authors.thtml:50
+msgid "devcp_edit_authors_header_manage"
+msgstr "Add-on-Autoren bearbeiten"
+
+#: views/developers/addon_edit_authors.thtml:93
+msgid "devcp_edit_authors_label_add_listed"
+msgstr "Als Autor auf den öffentlichen Seiten anzeigen"
+
+#: views/developers/addon_edit_authors.thtml:89
+msgid "devcp_edit_authors_label_developer"
+msgstr ""
+"<strong>Entwickler</strong> - Kann alle Aspekte eines Add-ons verändern, "
+"außer dem Hinzufügen oder Löschen anderer Autoren."
+
+#: views/developers/addon_edit_authors.thtml:88
+msgid "devcp_edit_authors_label_owner"
+msgstr ""
+"<strong>Eigentümer</strong> - Kann alle Aspekte eines Add-ons verändern, "
+"inklusive dem Hinzufügen und Löschen anderer Autoren."
+
+#: views/developers/addon_edit_authors.thtml:90
+msgid "devcp_edit_authors_label_viewer"
+msgstr ""
+"<strong>Beobachter</strong> - Kann Entwickler-Informationen und Statistiken "
+"über das Add-on abrufen, aber keine Veränderungen vornehmen."
+
+#. Placeholder for the empty option in a <select>.
+#: views/developers/addon_edit_categories.thtml:69
+msgid "devcp_edit_authors_option_empty"
+msgstr "----------------"
+
+#: views/developers/addon_edit_authors.thtml:86
+msgid "devcp_edit_authors_select_role"
+msgstr "Wählen Sie eine Rolle für diesen Autor aus:"
+
+#. Column name in a table.
+#: views/developers/addon_edit_authors.thtml:62
+msgid "devcp_edit_authors_th_author"
+msgstr "Autor"
+
+#. Column name in a table.
+#: views/developers/addon_edit_authors.thtml:64
+msgid "devcp_edit_authors_th_listed"
+msgstr "Angezeigt"
+
+#. Column name in a table.
+#: views/developers/addon_edit_authors.thtml:63
+msgid "devcp_edit_authors_th_role"
+msgstr "Rolle"
+
+#: views/developers/addon_edit_authors.thtml:77
+msgid "devcp_edit_authors_update_author"
+msgstr "Aktualisieren"
+
+#: views/developers/addon_edit_categories.thtml:99
+msgid "devcp_edit_categories_button_update"
+msgstr "Kategorien bearbeiten"
+
+#: views/developers/addon_edit_categories.thtml:88
+msgid "devcp_edit_categories_does_not_fit"
+msgstr "Mein Add-on passt in keine der vorhandenen Kategorien."
+
+#. %s is the application name (Firefox, Thunderbird).
+#: views/developers/addon_edit_categories.thtml:61
+msgid "devcp_edit_categories_header_application"
+msgstr "%s-Kategorien"
+
+#: views/developers/addon_edit_categories.thtml:49
+msgid "devcp_edit_categories_header_manage"
+msgstr "Kategorien des Add-ons bearbeiten"
+
+#: views/developers/addon_edit_categories.thtml:91
+msgid "devcp_edit_categories_hover"
+msgstr ""
+"Fahren Sie mit der Maus über eine Kategorie, um ihre Beschreibung zu sehen."
+
+#. %s is the category number (1, 2, 3).
+#: views/developers/addon_edit_categories.thtml:67
+msgid "devcp_edit_categories_label_category_num"
+msgstr "Kategorie Nr. %s"
+
+#: views/developers/addon_edit_categories.thtml:94
+#: views/developers/addon_edit_categories.thtml:103
+msgid "devcp_edit_categories_none_available"
+msgstr ""
+"Für diese Kombination von Add-on-Typ und Anwendung sind keine Kategorien "
+"verfügbar."
+
+#: views/developers/addon_edit_categories.thtml:86
+msgid "devcp_edit_categories_other"
+msgstr ""
+"Fügen Sie Ihr Add-on nur dann in diese Kategorie ein, wenn es in keine "
+"andere vorhandene Kategorie passt."
+
+#. %s is the application name (Firefox, Thunderbird).
+#: views/developers/addon_edit_categories.thtml:63
+msgid "devcp_edit_categories_select_application_categories"
+msgstr "Wählen Sie bis zu drei %s-Kategorien für Ihr Add-on."
+
+#: views/developers/addon_edit.thtml:47
+msgid "devcp_edit_dd_manage_authors"
+msgstr ""
+"Hinzufügen oder Löschen von Benutzern, die dieses Add-on verändern können."
+
+#: views/developers/addon_edit.thtml:49
+msgid "devcp_edit_dd_manage_categories"
+msgstr ""
+"Wählen Sie für jede Anwendung, die Ihr Add-on unterstützt, die relevanten "
+"Kategorien aus."
+
+#: views/developers/addon_edit.thtml:51
+msgid "devcp_edit_dd_manage_description"
+msgstr ""
+"Hinzufügen und Verändern von Übersetzungen der Zusammenfassung, "
+"Beschreibung, Lizenz und Datenschutzerklärung Ihres Add-ons."
+
+#: views/developers/addon_edit.thtml:53
+msgid "devcp_edit_dd_manage_properties"
+msgstr ""
+"Ändern des Namens, der Homepage, des Icons und anderer Einstellungen Ihres "
+"Add-ons."
+
+#: views/developers/addon_edit_descriptions.thtml:116
+msgid "devcp_edit_description_button_update"
+msgstr "Beschreibungen ändern"
+
+#: views/developers/addon_edit_descriptions.thtml:115
+msgid "devcp_edit_description_correct_error"
+msgstr "Bitte korrigieren Sie die Fehler, die oben in rot angezeigt werden."
+
+#: views/developers/addon_edit_descriptions.thtml:51
+msgid "devcp_edit_descriptions_header"
+msgstr "Beschreibungen des Add-ons ändern"
+
+#: views/developers/addon_edit_descriptions.thtml:94
+msgid "devcp_edit_descriptions_transbox_comments_description"
+msgstr ""
+"Jede Information, die Endbenutzer möglicherweise wissen möchten, die aber "
+"nicht notwendigerweise in die Zusammenfassung oder Beschreibung gehören. Die "
+"übliche Verwendung für dieses Feld umfasst beispielsweise bekannte Probleme, "
+"Informationen zum Melden von gefundenen Fehlern, der beabsichtigte "
+"Erscheinungstermin der nächsten Add-on-Version, und ähnliches."
+
+#: views/developers/addon_edit_descriptions.thtml:93
+msgid "devcp_edit_descriptions_transbox_comments_name"
+msgstr "Entwickler-Kommentare"
+
+#: views/developers/addon_edit_descriptions.thtml:86
+msgid "devcp_edit_descriptions_transbox_description_description"
+msgstr ""
+"Die Beschreibung Ihres Add-ons ist eine längere Erklärung seiner "
+"Fähigkeiten, Funktionalität, und anderer relevanter Information. Sie wird "
+"unterhalb der Zusammenfassung auf der öffentlichen Seite Ihres Add-ons "
+"angezeigt."
+
+#: views/developers/addon_edit_descriptions.thtml:85
+msgid "devcp_edit_descriptions_transbox_description_name"
+msgstr "Add-on-Beschreibung"
+
+#: views/developers/addon_edit_descriptions.thtml:103
+msgid "devcp_edit_descriptions_transbox_eula_description"
+msgstr ""
+"Wenn Ihr Add-on einen Endbenutzer-Lizenzvertrag (EULA) besitzt, dann geben "
+"Sie dessen Text bitte hier ein. Wenn Sie dieses Feld füllen, müssen Benutzer "
+"der Vereinbarung zustimmen, bevor sie Ihr Add-on installieren können. "
+"Achtung: Ein Endbenutzer-Lizenzvertrag ist nicht dasselbe wie eine Code-"
+"Lizenz, also etwa GPL oder MPL."
+
+#: views/developers/addon_edit_descriptions.thtml:102
+msgid "devcp_edit_descriptions_transbox_eula_name"
+msgstr "Endbenutzer-Lizenzvertrag"
+
+#: views/developers/addon_edit_descriptions.thtml:112
+msgid "devcp_edit_descriptions_transbox_privacy_description"
+msgstr ""
+"Wenn Ihr Add-on eine Datenschutzerklärung hat, geben Sie sie bitte hier ein. "
+"Auf der Webseite Ihres Add-ons wird ein Link darauf erscheinen."
+
+#: views/developers/addon_edit_descriptions.thtml:111
+msgid "devcp_edit_descriptions_transbox_privacy_name"
+msgstr "Datenschutzerklärung"
+
+#: views/developers/addon_edit_descriptions.thtml:78
+msgid "devcp_edit_descriptions_transbox_summary_description"
+msgstr ""
+"Die Zusammenfassung ist eine kurze Erklärung zur grundsätzlichen "
+"Funktionalität Ihres Add-ons.Sie wird beispielsweise in Suchergebnissen und "
+"Add-on-Listen angezeigt, außerdem oben auf der Webseite Ihres Add-ons. "
+"<strong>Höchstens 250 Zeichen.</strong>"
+
+#: views/developers/addon_edit_descriptions.thtml:77
+msgid "devcp_edit_descriptions_transbox_summary_name"
+msgstr "Add-on-Zusammenfassung"
+
+#: views/developers/addon_edit.thtml:46
+msgid "devcp_edit_dt_manage_authors"
+msgstr "Add-on-Autoren bearbeiten"
+
+#: views/developers/addon_edit.thtml:48
+msgid "devcp_edit_dt_manage_categories"
+msgstr "Add-on-Kategorien bearbeiten"
+
+#: views/developers/addon_edit.thtml:50
+msgid "devcp_edit_dt_manage_descriptions"
+msgstr "Add-on-Beschreibungen bearbeiten"
+
+#: views/developers/addon_edit.thtml:52
+msgid "devcp_edit_dt_manage_properties"
+msgstr "Add-on-Eigenschaften bearbeiten"
+
+#: views/developers/addon_edit_properties.thtml:170
+msgid "devcp_edit_label_externalsoftware"
+msgstr "Dieses Add-on benötigt externe Software."
+
+#: views/developers/addon_edit_properties.thtml:205
+msgid "devcp_edit_label_locale_disambiguation"
+msgstr "Weiterer Hinweis"
+
+#: views/developers/addon_edit_properties.thtml:168
+msgid "devcp_edit_label_prerelease"
+msgstr "Dies ist keine Endversion"
+
+#: views/developers/addon_edit_properties.thtml:169
+msgid "devcp_edit_label_sitespecific"
+msgstr "Dies ist ein seitenabhängiges Add-on"
+
+#: views/developers/addon_edit_properties.thtml:202
+msgid "devcp_edit_label_target_locale"
+msgstr "Zielsprache"
+
+#: views/developers/addon_edit_properties.thtml:212
+msgid "devcp_edit_properties_button_update"
+msgstr "Eigenschaften bearbeiten"
+
+#: views/developers/addon_edit_properties.thtml:198
+msgid "devcp_edit_properties_change_guid"
+msgstr "Ändern Sie dies nur, falls Sie sich aller Konsequenzen bewusst sind."
+
+#: views/developers/addon_edit_properties.thtml:109
+msgid "devcp_edit_properties_current_icon"
+msgstr "Aktuelles Icon"
+
+#: views/developers/addon_edit_properties.thtml:85
+msgid "devcp_edit_properties_default_locale"
+msgstr ""
+"Die Standard-Sprache eines Add-ons ist seine Haupt-Ãœbersetzung. Falls eine "
+"Übersetzung für die Beschreibungstexte des Add-ons in der Sprache eines "
+"Benutzers nicht verfügbar ist, so wird ihm stattdessen die Übersetzung in "
+"der hier gewählen Sprache angezeigt."
+
+#: views/developers/addon_edit_properties.thtml:167
+msgid "devcp_edit_properties_flags"
+msgstr ""
+"Diese Eigenschaften werden verwendet, um Add-ons zu filtern und zu "
+"klassifizieren."
+
+#: views/developers/addon_edit_properties.thtml:174
+msgid "devcp_edit_properties_guid"
+msgstr ""
+"Die GUID Ihres Add-ons wird in der Datei install.rdf festgelegt und "
+"identifiziert das Add-on eindeutig. Sie können die GUID eines Add-ons nicht "
+"mehr ändern, wenn es einmal zu Mozilla Add-ons übermittelt wurde."
+
+#: views/developers/addon_edit_properties.thtml:53
+msgid "devcp_edit_properties_header"
+msgstr "Add-on-Eigenschaften bearbeiten"
+
+#: views/developers/addon_edit_properties.thtml:186
+msgid "devcp_edit_properties_header_addon_type"
+msgstr "Add-on-Typ"
+
+#: views/developers/addon_edit_properties.thtml:181
+msgid "devcp_edit_properties_header_admin_settings"
+msgstr "Admin-Einstellungen"
+
+#: views/developers/addon_edit_properties.thtml:84
+msgid "devcp_edit_properties_header_default_locale"
+msgstr "Standard-Sprache"
+
+#: views/developers/addon_edit_properties.thtml:166
+msgid "devcp_edit_properties_header_flags"
+msgstr "Add-on-Markierungen"
+
+#: views/developers/addon_edit_properties.thtml:173
+#: views/developers/addon_edit_properties.thtml:197
+msgid "devcp_edit_properties_header_guid"
+msgstr "Add-on-GUID"
+
+#: views/developers/addon_edit_properties.thtml:104
+msgid "devcp_edit_properties_header_icon"
+msgstr "Add-on-Icon"
+
+#: views/developers/addon_edit_properties.thtml:159
+msgid "devcp_edit_properties_header_other_settings"
+msgstr "Andere Einstellungen"
+
+#. A header on the admin page to toggle trusted status.
+#: views/developers/addon_edit_properties.thtml:182
+msgid "devcp_edit_properties_header_trusted"
+msgstr "Vertrautes Add-on?"
+
+#: views/developers/addon_edit_properties.thtml:160
+msgid "devcp_edit_properties_header_view_source"
+msgstr "Quellcode online anzeigen"
+
+#. %s is a comma-separated list of image extensions ".png, .jpg"
+#: views/developers/addon_edit_properties.thtml:106
+msgid "devcp_edit_properties_icon"
+msgstr ""
+"Das Add-on-Icon ist ein kleines Bild, das neben dem Namen Ihres Add-ons in "
+"Listen und Suchergebnissen angezeigt wird, sowie auf dessen Webseite und im "
+"Browserfenster beim Installieren des Add-ons. Das Bild wird automatisch auf "
+"die Größe 32x32 Pixel skaliert. Bitte verwenden Sie einen der folgenden "
+"Dateitypen: %s"
+
+#: views/developers/addon_edit_properties.thtml:171
+msgid "devcp_edit_properties_label_binary"
+msgstr "Dieses Add-on enthält binäre Komponenten"
+
+#: views/developers/addon_edit_properties.thtml:185
+msgid "devcp_edit_properties_label_not_trusted"
+msgstr "Nicht vertraut"
+
+#: views/developers/addon_edit_properties.thtml:184
+msgid "devcp_edit_properties_label_trusted"
+msgstr "Vertraut"
+
+#: views/developers/addon_edit_properties.thtml:110
+msgid "devcp_edit_properties_new_icon"
+msgstr "Neues Icon"
+
+#: views/developers/addon_edit_properties.thtml:118
+msgid "devcp_edit_properties_remove_icon"
+msgstr "Icon entfernen"
+
+#: views/developers/addon_edit_properties.thtml:136
+msgid "devcp_edit_properties_transbox_homepage_description"
+msgstr ""
+"Wenn Ihr Add-on noch über eine weitere Homepage verfügt, geben Sie diese "
+"Adresse bitte hier ein. Das Hinzufügen weiterer Übersetzungen ist nicht "
+"notwendig, es sei denn Ihre Webseite ist in verschiedene Sprachen übersetzt."
+
+#: views/developers/addon_edit_properties.thtml:135
+msgid "devcp_edit_properties_transbox_homepage_name"
+msgstr "Add-on-Homepage"
+
+#: views/developers/addon_edit_properties.thtml:79
+msgid "devcp_edit_properties_transbox_name_description"
+msgstr ""
+"Der Name Ihres Add-ons wird überall angezeigt, wo Ihr Add-on dargestellt "
+"wird."
+
+#: views/developers/addon_edit_properties.thtml:78
+msgid "devcp_edit_properties_transbox_name_name"
+msgstr "Add-on-Name"
+
+#: views/developers/addon_edit_properties.thtml:145
+msgid "devcp_edit_properties_transbox_supportemail_description"
+msgstr ""
+"Wenn Sie E-Mail-Adressen haben, an die Support-Anfragen gerichtet werden "
+"können, geben Sie sie bitte hier ein. Das Hinzufügen weiterer Übersetzungen "
+"ist nicht notwendig, es sei denn Sie haben unterschiedliche E-Mail-Adressen "
+"für unterschiedliche Sprachen."
+
+#: views/developers/addon_edit_properties.thtml:144
+msgid "devcp_edit_properties_transbox_supportemail_name"
+msgstr "Support-E-Mail-Adresse"
+
+#: views/developers/addon_edit_properties.thtml:154
+msgid "devcp_edit_properties_transbox_supporturl_description"
+msgstr ""
+"Wenn Ihr Add-on eine Support-Webseite oder ein Benutzerforum hat, geben Sie "
+"diese Adresse hier ein. Das Hinzufügen weiterer Übersetzungen ist nicht "
+"notwendig, es sei denn Ihre Webseite ist in verschiedene Sprachen übersetzt."
+
+#: views/developers/addon_edit_properties.thtml:153
+msgid "devcp_edit_properties_transbox_supporturl_name"
+msgstr "Support-Webseite"
+
+#: views/developers/addon_edit_properties.thtml:183
+msgid "devcp_edit_properties_trusted"
+msgstr ""
+"Vertraute Add-ons können ohne Moderator-Bewertung öffentlich gemacht werden."
+
+#. %s is href="..." and should stay in the <a> tag.
+#: views/developers/addon_edit_properties.thtml:119
+msgid "devcp_edit_properties_undelete"
+msgstr "Das Icon wird gelöscht, wenn Sie nun speichern. <a %s>Abbrechen?</a>"
+
+#: views/developers/addon_edit_properties.thtml:161
+msgid "devcp_edit_properties_view_source"
+msgstr ""
+"Wenn Sie die Anzeige des Quellcodes Ihrer Add-on-Dateien zulassen, so kann "
+"jeder eingeloggte Benutzer sie online ansehen."
+
+#: views/developers/addon_edit_properties.thtml:162
+msgid "devcp_edit_properties_view_source_allow"
+msgstr "Online-Anzeige des Quellcodes zulassen"
+
+#: views/developers/addon_edit_properties.thtml:163
+msgid "devcp_edit_properties_view_source_do_not_allow"
+msgstr "Online-Anzeige des Quellcodes nicht zulassen"
+
+#: views/elements/developers/editbox.thtml:46
+msgid "devcp_editbox_authors"
+msgstr "Autoren"
+
+#: views/elements/developers/editbox.thtml:47
+msgid "devcp_editbox_categories"
+msgstr "Kategorien"
+
+#: views/elements/developers/editbox.thtml:52
+msgid "devcp_editbox_change_status"
+msgstr "Status verändern"
+
+#: views/elements/developers/editbox.thtml:48
+msgid "devcp_editbox_descriptions"
+msgstr "Beschreibungen"
+
+#: views/elements/developers/editbox.thtml:43
+msgid "devcp_editbox_edit_addon"
+msgstr "Add-on bearbeiten"
+
+#: views/elements/developers/editbox.thtml:57
+msgid "devcp_editbox_new_version"
+msgstr "Neue Version"
+
+#: views/elements/developers/editbox.thtml:49
+msgid "devcp_editbox_properties"
+msgstr "Eigenschaften"
+
+#: views/elements/developers/editbox.thtml:60
+msgid "devcp_editbox_screenshots"
+msgstr "Vorschaubilder"
+
+#: views/elements/developers/editbox.thtml:53
+msgid "devcp_editbox_statistics_dashboard"
+msgstr "Statistiken"
+
+#: views/elements/developers/editbox.thtml:54
+msgid "devcp_editbox_versions"
+msgstr "Versionen und Dateien"
+
+#: views/elements/developers/editbox.thtml:42
+msgid "devcp_editbox_view_listing"
+msgstr "Add-on-Webseite anzeigen"
+
+#: views/elements/developers/editorsmenu.thtml:59
+msgid "devcp_editorsqueue_featured"
+msgstr "Empfohlene Add-ons"
+
+#. %1 is the review count
+#: views/elements/developers/editorsqueue.thtml:42
+#: views/elements/developers/editorsmenu.thtml:56
+#, php-format
+msgid "devcp_editorsqueue_moderatedreviews"
+msgid_plural "devcp_editorsqueue_moderatedreviews"
+msgstr[0] "Eine wartende Bewertung"
+msgstr[1] "Wartende Bewertungen (%s)"
+
+#. %1 is the nominated addons count
+#: views/elements/developers/editorsqueue.thtml:44
+#: views/elements/developers/editorsmenu.thtml:58
+#, php-format
+msgid "devcp_editorsqueue_nominated"
+msgid_plural "devcp_editorsqueue_nominated"
+msgstr[0] "Ein nominiertes Add-on"
+msgstr[1] "Nominierte Add-ons (%s)"
+
+#. %1 is the update count
+#: views/elements/developers/editorsqueue.thtml:43
+#: views/elements/developers/editorsmenu.thtml:57
+#, php-format
+msgid "devcp_editorsqueue_pendingupdates"
+msgid_plural "devcp_editorsqueue_pendingupdates"
+msgstr[0] "Ein wartendes Update"
+msgstr[1] "Wartende Updates (%s)"
+
+#: controllers/statistics_controller.php:147
+#: controllers/statistics_controller.php:361
+#: controllers/previews_controller.php:108
+#: controllers/previews_controller.php:211
+#: controllers/previews_controller.php:312
+msgid "devcp_error_addon_access_denied"
+msgstr "Sie haben keine Zugriff auf dieses Add-on."
+
+#. %s is a complete URL with the text from devcp_error_appversion_reference_link_text
+#. in the <a> tag. This should be fixed.
+#: controllers/components/developers.php:591
+#, php-format
+msgid "devcp_error_appversion_reference_link"
+msgstr "Bitte beachten Sie auch %s."
+
+#. This is the link text in the <a> for devcp_error_appversion_reference_link. This
+#. should be fixed.
+#: controllers/components/developers.php:591
+msgid "devcp_error_appversion_reference_link_text"
+msgstr "diese Seite"
+
+#: views/developers/addon_edit_authors.thtml:76
+msgid "devcp_error_empty_authors"
+msgstr "Ihr Add-on muss mindestens einen Eigentümer haben."
+
+#. %1$s is the name of the file
+#: controllers/components/developers.php:658
+msgid "devcp_error_file_exists"
+msgstr ""
+"Eine Version dieses Add-ons existiert bereits. Um sie zu ersetzen, löschen "
+"Sie bitte zunächst die Datei %1$s."
+
+#. %1$s is a file extension. Example: .exe
+#. %2$s is a comma separated list of extensions. Example: .xpi, .jar
+#: controllers/components/developers.php:355
+#, php-format
+msgid "devcp_error_file_extension"
+msgstr ""
+"Diese Dateinamen-Erweiterung (%s) ist für diesen Add-on-Typ nicht zulässig. "
+"Bitte benutzen Sie eine der folgenden Erweiterungen: %s"
+
+#: controllers/components/developers.php:64
+msgid "devcp_error_five_categories"
+msgstr "Bitte wählen Sie nicht mehr als fünf Kategorien aus."
+
+#: controllers/components/developers.php:526
+msgid "devcp_error_guid_application"
+msgstr "Die ID dieses Add-ons wird bereits von einer Anwendung verwendet."
+
+#: controllers/components/developers.php:337
+#: controllers/components/developers.php:389
+msgid "devcp_error_http_incomplete"
+msgstr "Unvollständig übertragen"
+
+#: controllers/components/developers.php:335
+#: controllers/components/developers.php:336
+#: controllers/components/developers.php:387
+#: controllers/components/developers.php:388
+msgid "devcp_error_http_maxupload"
+msgstr "Überschreitet die maximale Upload-Größe"
+
+#: controllers/components/developers.php:338
+#: controllers/components/developers.php:390
+msgid "devcp_error_http_nofile"
+msgstr "Noch keine Datei hochgeladen"
+
+#. %1$s is a file extension. Example: .exe
+#. %2$s is a comma separated list of extensions. Example: .xpi, .jar
+#: controllers/components/developers.php:401
+#, php-format
+msgid "devcp_error_icon_extension"
+msgstr ""
+"Diese Dateinamen-Erweiterung (%s) ist für ein Icon nicht erlaubt. Bitte "
+"verwenden Sie eine der folgenden: %s"
+
+#: controllers/developers_controller.php:504
+msgid "devcp_error_index_rdf_notfound"
+msgstr "Keine install.rdf gefunden."
+
+#: controllers/components/developers.php:601
+msgid "devcp_error_install_manifest"
+msgstr "Die folgenden Fehler wurden in der Datei install.rdf gefunden:"
+
+#: controllers/developers_controller.php:1463
+msgid "devcp_error_invalid_addontype"
+msgstr "Die ID dieses Add-ons ist ungültig: %s"
+
+#. %$1s is a version. Example: 3.1.1
+#. %$2s is an add-on name.
+#: controllers/components/developers.php:569
+#: controllers/components/developers.php:581
+#, php-format
+msgid "devcp_error_invalid_appversion"
+msgstr "%s ist keine gültige Version für %s"
+
+#. %s is a string
+#: controllers/components/developers.php:521
+#, php-format
+msgid "devcp_error_invalid_guid"
+msgstr "Die ID dieses Add-ons ist ungültig: %s"
+
+#. %$1s is a version. Example: 3.1.1
+#. %$2s is an add-on name.
+#: controllers/components/developers.php:572
+#, php-format
+msgid "devcp_error_invalid_minversion"
+msgstr ""
+"%s ist keine gültige Version für %s: minimale Versionen können kein * "
+"enthalten"
+
+#: controllers/components/developers.php:536
+msgid "devcp_error_invalid_version"
+msgstr ""
+"Die Version dieses Add-ons ist ungültig: Bitte beachten Sie die <a href="
+"\"http://developer.mozilla.org/en/docs/Toolkit_version_format"
+"\">Spezifikation</a>"
+
+#: controllers/components/developers.php:531
+msgid "devcp_error_invalid_version_spaces"
+msgstr ""
+"Die Version dieses Add-ons ist ungültig: Versionsnummern dürfen keine "
+"Leerstellen beinhalten."
+
+#. %s is an error message from the parser.
+#: controllers/components/developers.php:501
+#, php-format
+msgid "devcp_error_manifest_parse"
+msgstr "Der folgende Fehler trat beim Parsen der Datei install.rdf auf: %s"
+
+#: controllers/components/developers.php:373
+msgid "devcp_error_move_file"
+msgstr "Datei konnte nicht verschoben werden"
+
+#. %s is the name of a file
+#: controllers/components/developers.php:650
+#: controllers/components/developers.php:662
+#: controllers/components/developers.php:667
+#: controllers/components/developers.php:727
+#: controllers/components/developers.php:738
+#: controllers/components/developers.php:743
+#, php-format
+msgid "devcp_error_moving_file"
+msgstr "Ein Fehler trat beim Verschieben von %s auf."
+
+#: controllers/components/developers.php:595
+msgid "devcp_error_mozilla_application"
+msgstr "Sie müssen wenigstens eine gültige Mozilla-Zielanwendung auswählen."
+
+#: controllers/components/developers.php:516
+msgid "devcp_error_no_guid"
+msgstr "Die Datei install.rdf enthielt keine ID für dieses Add-on."
+
+#: controllers/components/developers.php:287
+msgid "devcp_error_no_platform"
+msgstr "Kein Betriebssystem gewählt"
+
+#: controllers/components/developers.php:59
+msgid "devcp_error_one_category"
+msgstr "Bitte wählen Sie mindestens eine Kategorie aus."
+
+#: controllers/components/developers.php:92
+msgid "devcp_error_one_user"
+msgstr "Dieses Add-on muss mindestens einen Entwickler haben."
+
+#. %1$s is a file extension. Example: .exe
+#. %2$s is a comma separated list of extensions. Example: .xpi, .jar
+#: controllers/components/developers.php:1081
+#, php-format
+msgid "devcp_error_preview_extension"
+msgstr ""
+"Diese Dateinamen-Erweiterung (%s) ist für eine Vorschau nicht erlaubt. Bitte "
+"verwenden Sie eine der folgenden: %s"
+
+#: controllers/components/developers.php:511
+msgid "devcp_error_updatekey"
+msgstr ""
+"Add-ons dürfen keinen updateKey verwenden. Bitte entfernen Sie diesen von "
+"Ihrer install.rdf-Datei und versuchen Sie es erneut."
+
+#: controllers/components/developers.php:506
+msgid "devcp_error_updateurl"
+msgstr ""
+"Add-ons dürfen keine externe updateURL verwenden. Bitte entfernen Sie diese "
+"aus der Datei install.rdf und versuchen Sie es erneut."
+
+#: controllers/developers_controller.php:465
+#: controllers/components/developers.php:271
+msgid "devcp_error_upload_file"
+msgstr "Bitte laden Sie eine Datei hoch."
+
+#: views/developers/uploader.thtml:135
+msgid "devcp_input_upload_file"
+msgstr "Datei hochladen"
+
+#: views/pages/js_constants.js.thtml:89
+msgid "devcp_js_a_cancel"
+msgstr "Abbrechen"
+
+#: views/pages/js_constants.js.thtml:90
+msgid "devcp_js_add_email"
+msgstr ""
+"Bitte geben Sie die E-Mail des Benutzers ein, den Sie hinzufügen möchten."
+
+#. alt text for a down-arrow image.
+#: views/pages/js_constants.js.thtml:81
+msgid "devcp_js_img_move_down"
+msgstr "Nach unten"
+
+#. alt text for an up-arrow image.
+#: views/pages/js_constants.js.thtml:82
+msgid "devcp_js_img_move_up"
+msgstr "Nach oben"
+
+#: views/pages/js_constants.js.thtml:91
+msgid "devcp_js_img_remove_compat"
+msgstr "Anwendungs-Kompatibilität entfernen"
+
+#: views/pages/js_constants.js.thtml:86
+msgid "devcp_js_input_list_author"
+msgstr "Autor auf öffentlichen Seiten anzeigen"
+
+#: views/pages/js_constants.js.thtml:92
+msgid "devcp_js_license_select"
+msgstr "Bitte wählen Sie eine Lizenz aus."
+
+#: views/pages/js_constants.js.thtml:93
+msgid "devcp_js_license_text"
+msgstr "Bitte geben Sie einen Text für Ihre Lizenz ein."
+
+#. <option> text in a <select> for Author role in an add-on.
+#: views/pages/js_constants.js.thtml:84
+msgid "devcp_js_option_developer"
+msgstr "Entwickler"
+
+#. <option> text in a <select> for Author role in an add-on.
+#: views/pages/js_constants.js.thtml:83
+msgid "devcp_js_option_owner"
+msgstr "Eigentümer"
+
+#. <option> text in a <select> for Author role in an add-on.
+#: views/pages/js_constants.js.thtml:85
+msgid "devcp_js_option_viewer"
+msgstr "Beobachter"
+
+#: views/pages/js_constants.js.thtml:88
+msgid "devcp_js_remove_author"
+msgstr "Autor entfernen"
+
+#: views/pages/js_constants.js.thtml:87
+msgid "devcp_js_sure_remove"
+msgstr ""
+"Sind Sie <strong>sicher</strong>, dass Sie diesen Autor entfernen möchten?"
+
+#: views/pages/js_constants.js.thtml:77
+msgid "devcp_js_upload_alert"
+msgstr "Sie müssen eine Datei auswählen, um sie hochzuladen."
+
+#. %1$s is an addon id, like 32.
+#. %2$s is a version number, like 3.5.
+#: controllers/components/developers.php:1212
+msgid "devcp_license_existing"
+msgstr "Benutzerdefinierte Lizenz für Add-on %1$s Version %2$s"
+
+#: views/elements/developers/localebox.thtml:44
+msgid "devcp_localebox_header_localizedfields"
+msgstr "Ãœbersetzte Felder"
+
+#. %1 is the default locale
+#: views/elements/developers/localebox.thtml:48
+#, php-format
+msgid "devcp_localebox_intro"
+msgstr ""
+"Einige dieser Felder sind übersetzt, um in der Muttersprache des "
+"Endbenutzers erscheinen zu können. Wählen Sie unten eine Sprache, um Ihre "
+"Add-on-Details in dieser Sprache zu bearbeiten. Falls für eine Sprache keine "
+"Ãœbersetzung vorhanden ist, so wird die Standard-Sprache (%s) angezeigt."
+
+#: views/elements/developers/sidebar.thtml:68
+#: views/elements/developers/myaddons.thtml:75
+msgid "devcp_myaddons_admincp_link"
+msgstr "Adminwerkzeuge"
+
+#: views/elements/developers/sidebar.thtml:65
+#: views/elements/developers/myaddons.thtml:72
+msgid "devcp_myaddons_editorcp_link"
+msgstr "Moderatorenwerkzeuge"
+
+#: views/elements/developers/myaddons.thtml:52
+msgid "devcp_myaddons_link"
+msgstr "Meine Add-ons"
+
+#: views/elements/developers/sidebar.thtml:70
+#: views/elements/developers/myaddons.thtml:77
+msgid "devcp_myaddons_mainpage_link"
+msgstr "Zurück zur Hauptseite"
+
+#: views/elements/developers/sidebar.thtml:63
+#: views/elements/developers/myaddons.thtml:70
+msgid "devcp_myaddons_statistics_link"
+msgstr "Statistische Auswertung"
+
+#: views/elements/developers/sidebar.thtml:62
+#: views/elements/developers/myaddons.thtml:69
+msgid "devcp_myaddons_submitaddon_link"
+msgstr "Add-on hochladen"
+
+#: views/elements/developers/sidebar.thtml:48
+#: views/elements/developers/myaddons.thtml:67
+msgid "devcp_myaddons_title"
+msgstr "Entwickler"
+
+#. %1$s is an add-on ID, perhaps 167.
+#. %2$s is a URL.
+#: controllers/developers_controller.php:256
+msgid "devcp_new_addon_error"
+msgstr ""
+"Diese Add-on-ID (%1$s) existiert bereits in der Datenbank. Falls dies Ihr "
+"Add-on ist, möchten Sie wahrscheinlich eine <a href=\"%2$s\">neue Version "
+"hochladen</a>."
+
+#: views/developers/addon_status_nominate.thtml:62
+msgid "devcp_nominate_cancel"
+msgstr "Abbrechen und zurückkehren"
+
+#. %1 is the add-on name
+#: views/developers/addon_status_nominate.thtml:61
+#, php-format
+msgid "devcp_nominate_submit_nominate"
+msgstr "%s nominieren"
+
+#: views/developers/addon_edit_properties.thtml:50
+#: views/developers/addon_status.thtml:49
+#: views/developers/versions_edit.thtml:50
+msgid "devcp_notice_changes_error"
+msgstr ""
+"<span>Eine oder mehrere Ihrer Änderungen konnten nicht gespeichert werden.</"
+"span><br />Bitte sehen Sie sich die unten stehenden Fehler an. Der Rest "
+"Ihrer Änderungen wurde erfolgreich gespeichert."
+
+#: views/developers/addon_edit_authors.thtml:47
+#: views/developers/addon_edit_properties.thtml:47
+#: views/developers/addon_status.thtml:46
+#: views/developers/addon_edit_descriptions.thtml:47
+#: views/developers/versions_edit.thtml:47
+#: views/developers/addon_edit_categories.thtml:46
+msgid "devcp_notice_changes_saved"
+msgstr ""
+"<span>Ihre Änderungen wurden gespeichert.</span><br />Achtung: Bei manchen "
+"Veränderungen kann es bis zu wenigen Stunden dauern, bis sie in allen "
+"Bereichen der Webseite angezeigt werden."
+
+#: controllers/previews_controller.php:252
+msgid "devcp_notice_cleardefault"
+msgstr ""
+"Das Löschen dieser Grafik als Standardvorschau führt automatisch zur "
+"Ernennung einer anderen Vorschau als Standardvorschau."
+
+#: controllers/previews_controller.php:184
+#: controllers/previews_controller.php:251
+msgid "devcp_notice_makedefault"
+msgstr ""
+"Die Ernennung dieser Grafik zur Standardvorschau entfernt den Status der "
+"Standardvorschau von der derzeitigen Standardvorschau."
+
+#: views/developers/addon_edit_authors.thtml:70
+msgid "devcp_notice_unsaved_changes"
+msgstr "Es sind noch nicht alle Änderungen gespeichert."
+
+#: controllers/developers_controller.php:87
+#: controllers/developers_controller.php:97
+#: controllers/developers_controller.php:100
+#: controllers/previews_controller.php:67
+#: controllers/previews_controller.php:79
+#: controllers/previews_controller.php:82
+msgid "devcp_pagetitle"
+msgstr "Entwicklerwerkzeuge"
+
+#: controllers/previews_controller.php:103
+#: controllers/previews_controller.php:104
+msgid "devcp_preview_add_pagetitle"
+msgstr "Vorschau hinzufügen"
+
+#: controllers/previews_controller.php:135
+msgid "devcp_preview_added_successfully"
+msgstr "Vorschau erfolgreich hinzugefügt"
+
+#: controllers/previews_controller.php:323
+msgid "devcp_preview_deleted_successfully"
+msgstr "Vorschau erfolgreich gelöscht"
+
+#: controllers/previews_controller.php:194
+#: controllers/previews_controller.php:195
+msgid "devcp_preview_edit_pagetitle"
+msgstr "Vorschau bearbeiten"
+
+#: controllers/previews_controller.php:237
+msgid "devcp_preview_updated_successfully"
+msgstr "Vorschau erfolgreich aktualisiert."
+
+#: views/developers/previews.thtml:120
+msgid "devcp_previews_a_another"
+msgstr "Vorschaubild hinzufügen"
+
+#: views/developers/previews.thtml:96
+msgid "devcp_previews_a_delete"
+msgstr "Vorschaubild löschen"
+
+#: views/developers/previews.thtml:95
+msgid "devcp_previews_a_replace"
+msgstr "Vorschaubild ersetzen"
+
+#: views/developers/previews.thtml:126
+msgid "devcp_previews_a_update"
+msgstr "Vorschaubilder aktualisieren"
+
+#: views/developers/previews.thtml:115 views/developers/previews.thtml:124
+msgid "devcp_previews_add_new"
+msgstr "Ein neues Vorschaubild hinzufügen"
+
+#. %s is a list of file extensions, e.g. ".png, .gif"
+#: views/developers/previews.thtml:116
+msgid "devcp_previews_add_select"
+msgstr ""
+"Wählen Sie bitte ein Bild aus, um es hochzuladen. Bilder, die breiter als "
+"700 oder höher als 525 Pixel sind, werden automatisch verkleinert. Erlaubte "
+"Dateitypen: %s"
+
+#: views/developers/previews.thtml:121
+msgid "devcp_previews_click_below"
+msgstr ""
+"Klicken Sie auf \"Vorschaubilder aktualisieren\", um das Hochladen zu "
+"starten."
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/previews.thtml:102
+msgid "devcp_previews_click_update"
+msgstr ""
+"Klicken Sie auf den Knopf \"Vorschaubilder aktualisieren\", um das Bild zu "
+"speichern. (<a %s>Abbrechen?</a>)"
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/previews.thtml:107
+msgid "devcp_previews_error_message"
+msgstr ""
+"Dieses Vorschaubild wird gelöscht, wenn Sie auf \"Vorschaubilder "
+"aktualisieren\"klicken. (<a %s>Abbrechen?</a>)"
+
+#: views/previews/add.thtml:45
+msgid "devcp_previews_filetype_info"
+msgstr ""
+"Benutzen Sie das folgende Formular um eine Vorschau Ihrer Erweiterung im "
+"Format PNG, JPG oder GIF hochzuladen. Grafiken breiter als 700 Pixel oder "
+"höher als 525 Pixel werden automatisch verkleinert."
+
+#: views/previews/add.thtml:43
+msgid "devcp_previews_header_add"
+msgstr "Vorschau hinzufügen"
+
+#: views/developers/previews.thtml:80
+msgid "devcp_previews_header_caption"
+msgstr "Beschreibungstext"
+
+#: views/previews/edit.thtml:43
+msgid "devcp_previews_header_edit"
+msgstr "Vorschau bearbeiten"
+
+#: views/developers/previews.thtml:93
+msgid "devcp_previews_label_default"
+msgstr "Standard-Vorschaubild"
+
+#: views/previews/add.thtml:54
+msgid "devcp_previews_label_file"
+msgstr "Vorschaudatei"
+
+#: views/previews/add.thtml:59 views/previews/edit.thtml:50
+msgid "devcp_previews_label_makedefault"
+msgstr "Diese Grafik zur Standardvorschau machen."
+
+#: views/developers/previews.thtml:100
+msgid "devcp_previews_label_new"
+msgstr "Neues Bild:"
+
+#: views/developers/previews.thtml:118
+msgid "devcp_previews_label_upload"
+msgstr "Bild hochladen: "
+
+#: views/developers/previews.thtml:50
+msgid "devcp_previews_notice_error"
+msgstr ""
+"Mindestens eines Ihrer neuen Vorschaubilder konnte nicht gespeichert werden."
+
+#: views/developers/previews.thtml:47
+msgid "devcp_previews_notice_success"
+msgstr "Ihre Vorschaubilder wurden erfolgreich aktualisiert."
+
+#: views/developers/previews.thtml:59
+msgid "devcp_previews_p_screenshots"
+msgstr ""
+"Die Vorschaubilder für Ihr Add-on werden unten angezeigt. Dort können Sie "
+"auch die Beschreibungstexte ändern. Das Standard-Vorschaubild ist das Bild, "
+"das neben Ihrem Add-on in Suchergebnissen und Add-on-Listen angezeigt wird."
+
+#: views/previews/edit.thtml:55
+msgid "devcp_previews_submit_delete"
+msgstr "Vorschau löschen"
+
+#: views/previews/edit.thtml:55
+msgid "devcp_previews_submit_delete_confirm"
+msgstr "Sind Sie sicher, dass Sie diese Vorschau löschen möchten?"
+
+#: views/previews/edit.thtml:54
+msgid "devcp_previews_submit_edit"
+msgstr "Vorschau bearbeiten"
+
+#: views/previews/add.thtml:63
+msgid "devcp_previews_submit_upload"
+msgstr "Vorschau hochladen"
+
+#: views/developers/previews.thtml:78
+msgid "devcp_previews_thumbnail"
+msgstr "Miniaturbild"
+
+#. %s is the add-on name.
+#: views/developers/previews.thtml:44
+msgid "devcp_previews_title"
+msgstr "Vorschaubilder für %s"
+
+#: views/developers/uploader.thtml:74
+msgid "devcp_review_agreement_please"
+msgstr ""
+"Bitte lesen und akzeptieren Sie die folgende Einverständniserklärung für "
+"Entwickler vor dem weitern Vorgehen."
+
+#: views/elements/developers/rolecheck.thtml:42
+msgid "devcp_rolecheck_no_privs"
+msgstr ""
+"<span>Sie haben nicht die erforderliche Berechtigung, um auf dieser Seite "
+"Veränderungen vorzunehmen.</span><br />Kontaktieren Sie bitte den Eigentümer "
+"des Add-ons, wenn Sie hier etwas verändern müssen."
+
+#: controllers/developers_controller.php:1315
+msgid "devcp_several_hours"
+msgstr ""
+"Achtung: Bei manchen Veränderungen kann es bis zu wenigen Stunden dauern, "
+"bis sie in allen Bereichen der Webseite angezeigt werden."
+
+#: views/elements/developers/sidebar.thtml:52
+msgid "devcp_sidebar_a_dashboard"
+msgstr "Ãœbersicht"
+
+#. %s is a number
+#: views/elements/developers/statsbar.thtml:45
+#: views/developers/dashboard.thtml:79
+#, php-format
+msgid "devcp_statsbar_adu"
+msgstr "<em>%s</em> aktive tägliche Nutzer"
+
+#. %s is a number
+#: views/elements/developers/statsbar.thtml:41
+#: views/developers/dashboard.thtml:75
+#, php-format
+msgid "devcp_statsbar_total_downloads"
+msgstr "<em>%s</em> Downloads insgesamt"
+
+#. %s is a number
+#: views/elements/developers/statsbar.thtml:43
+#: views/developers/dashboard.thtml:77
+#, php-format
+msgid "devcp_statsbar_weekly_downloads"
+msgstr "<em>%s</em> Downloads pro Woche"
+
+#: views/developers/addon_status_confirm.thtml:59
+msgid "devcp_status_confirm_active"
+msgstr ""
+"Wenn Sie dieses Add-on als aktiv markieren, wird es in öffentlichen "
+"Seitenbereichen angezeigt werden (abhängig von seinem Status), inklusive "
+"Suchergebnissen und Add-on-Listen. Man wird es von der Webseite "
+"herunterladen können, und es kann als automatisches Update an Benutzer "
+"geschickt werden. Sie können jederzeit zu dieser Seite zurückkehren und das "
+"Add-on erneut deaktivieren."
+
+#: views/developers/addon_status_confirm.thtml:59
+msgid "devcp_status_confirm_active_sure"
+msgstr "Sind Sie sicher, dass Sie dieses Add-on als aktiv markieren möchten?"
+
+#: views/developers/addon_status_confirm.thtml:50
+msgid "devcp_status_confirm_header_sure"
+msgstr "Sind Sie sicher?"
+
+#: views/developers/addon_status_confirm.thtml:55
+msgid "devcp_status_confirm_inactive"
+msgstr ""
+"Wenn Sie dieses Add-on deaktivieren, wird es nicht in öffentlichen "
+"Seitenbereichen angezeigt werden, auch nicht in Suchergebnissen und Add-on-"
+"Listen. Man wird es nicht von der Webseite herunterladen können, und "
+"Benutzer erhalten keine automatischen Updates. Sie können jederzeit zu "
+"dieser Seite zurückkehren und das Add-on erneut aktivieren."
+
+#: views/developers/addon_status_confirm.thtml:55
+msgid "devcp_status_confirm_inactive_sure"
+msgstr "Sind Sie sicher, dass Sie dieses Add-on deaktivieren möchten?"
+
+#: views/developers/addon_status_confirm.thtml:74
+msgid "devcp_status_confirm_no"
+msgstr "Nein, abbrechen"
+
+#: views/developers/addon_status_confirm.thtml:67
+msgid "devcp_status_confirm_public"
+msgstr ""
+"Wenn Sie dieses Add-on als öffentlich markieren, wird es von jedermann "
+"herunterladbar sein und Benutzer werden automatische Updates erhalten können."
+
+#: views/developers/addon_status_confirm.thtml:67
+msgid "devcp_status_confirm_public_sure"
+msgstr "Wollen Sie dieses Add-on wirklich als öffentlich markieren?"
+
+#: views/developers/addon_status_confirm.thtml:63
+msgid "devcp_status_confirm_sandbox"
+msgstr ""
+"Wenn Sie dieses Add-on zurück in den Sandkasten bewegen, werden sich "
+"Benutzer, die es herunterladen möchten, einloggen müssen. Benutzer des Add-"
+"ons werden keine automatischen Updates mehr erhalten. Weil Ihr Add-on "
+"gegenwärtig öffentlich ist, werden Sie jederzeit dazu in der Lage sein, zu "
+"dieser Seite zurückzukehren und es wieder als öffentlich zu markieren."
+
+#: views/developers/addon_status_confirm.thtml:63
+msgid "devcp_status_confirm_sandbox_sure"
+msgstr ""
+"Sind Sie sicher, dass Sie dieses Add-on in den Sandkasten bewegen möchten?"
+
+#: views/developers/addon_status_confirm.thtml:73
+msgid "devcp_status_confirm_yes"
+msgstr "Ja, ich bin sicher"
+
+#: views/developers/addon_status_nominate.thtml:46
+msgid "devcp_status_nominate_error_notice"
+msgstr ""
+"<span>Eine Nominierungs-Nachricht ist notwendig.</span><br />Bitte füllen "
+"Sie das Textfeld aus und versuchen Sie es erneut."
+
+#: views/developers/addon_status_nominate.thtml:55
+msgid "devcp_status_nominate_header"
+msgstr "Add-on-Nominierung"
+
+#: views/developers/dashboard.thtml:85
+msgid "devcp_summary_lastversion"
+msgstr "Neueste Version:"
+
+#. %s is the add-on name.
+#: views/developers/addon_edit.thtml:43
+#: views/developers/addon_edit_authors.thtml:44
+#: views/developers/versions_delete.thtml:43
+#: views/developers/addon_edit_properties.thtml:44
+#: views/developers/addon_edit_descriptions.thtml:44
+#: views/developers/versions_edit.thtml:44
+#: views/developers/addon_edit_categories.thtml:43
+#: views/developers/versions.thtml:43
+msgid "devcp_title_edit_addon"
+msgstr "%s bearbeiten"
+
+#. title attribute for a javascript link that pops up a help dialog.
+#: views/elements/translationbox.thtml:68
+msgid "devcp_transbox_a_title_help"
+msgstr "Hilfe (verlässt die Seite nicht)"
+
+#: views/elements/translationbox.thtml:68
+msgid "devcp_transbox_alt_help"
+msgstr "Hilfe"
+
+#. %1$s is <span>17</span>, %2$s is 42.
+#: views/elements/translationbox.thtml:101
+msgid "devcp_transbox_chars_used"
+msgstr "Buchstaben: %1$s von %2$s"
+
+#: views/elements/translationbox.thtml:132
+msgid "devcp_transbox_delete_sure"
+msgstr "Sind Sie sicher, dass Sie diese Übersetzung löschen möchten?"
+
+#. %s is a locale, like en-US.
+#: views/elements/translationbox.thtml:143
+msgid "devcp_transbox_help_header_tabs"
+msgstr "Was bedeuten die \"%s\" Tabs?"
+
+#: views/elements/translationbox.thtml:145
+msgid "devcp_transbox_help_header_what"
+msgstr "Was ist, wenn ich keine Ãœbersetzungen habe?"
+
+#: views/elements/translationbox.thtml:147
+msgid "devcp_transbox_help_hide"
+msgstr "Hilfe verstecken"
+
+#: views/elements/translationbox.thtml:146
+msgid "devcp_transbox_help_if"
+msgstr ""
+"Wenn ein Benutzer auf der Webseite unterwegs ist, und eine Ãœbersetzung in "
+"seiner Sprache ist nicht verfügbar, dann wird stattdessen der Text aus der "
+"Standard-Sprache Ihres Add-ons angezeigt. Die Standard-Sprache können Sie im "
+"Bereich \"Add-on-Eigenschaften bearbeiten\" wählen. Wenn Sie keine "
+"Übersetzungen für Ihr Add-on haben, geben Sie nur Text in Ihrer Standard-"
+"Sprache ein, wobei es sich um eine Sprache handeln sollte, die Sie verstehen."
+
+#: views/elements/translationbox.thtml:144
+msgid "devcp_transbox_help_transbox"
+msgstr ""
+"Dies ist ein <em>Ãœbersetzungsfeld</em>. Es erlaubt Ihnen, ein bestimmtes "
+"Feld in verschiedene Sprachen zu übersetzen. Mit Hilfe der Sprach-Tabs "
+"können Sie Übersetzungen hinzufügen, bearbeiten oder löschen."
+
+#: views/elements/translationbox.thtml:85
+msgid "devcp_transbox_img_add_trans"
+msgstr "Übersetzung hinzufügen"
+
+#: views/elements/translationbox.thtml:86
+msgid "devcp_transbox_img_remove_trans"
+msgstr "Ãœbersetzung entfernen"
+
+#: views/elements/translationbox.thtml:123
+msgid "devcp_transbox_input_add_all"
+msgstr "Sprache überall hinzufügen"
+
+#: views/elements/translationbox.thtml:122
+msgid "devcp_transbox_input_add_locale"
+msgstr "Sprache hinzufügen"
+
+#: views/elements/translationbox.thtml:124
+#: views/elements/translationbox.thtml:135
+msgid "devcp_transbox_input_cancel"
+msgstr "Abbrechen"
+
+#: views/elements/translationbox.thtml:134
+msgid "devcp_transbox_input_delete"
+msgstr "Löschen"
+
+#: views/elements/translationbox.thtml:113
+msgid "devcp_transbox_select_locale"
+msgstr "Bitte wählen Sie die Sprache, die Sie hinzufügen möchten:"
+
+#. %1$s and %2$s are GUIDs.
+#: controllers/developers_controller.php:343
+msgid "devcp_update_addon_guid_error"
+msgstr ""
+"Die GUID, in der hochgeladenen Datei (%1$s) entspricht nicht der bereits in "
+"der Datenbank gespeicherten GUID dieses Add-ons (%2$s)."
+
+#: controllers/developers_controller.php:334
+msgid "devcp_update_addon_priv_error"
+msgstr ""
+"Sie haben nicht die erforderlichen Berechtigungen, um dieses Add-on zu "
+"bearbeiten."
+
+#. %1$s is a version number, %2$s is an add-on ID.
+#: controllers/developers_controller.php:399
+msgid "devcp_update_addon_version_belong_error"
+msgstr "Die gewählte Version (%1$s) gehört nicht zu diesem Add-on (%2$s)."
+
+#. %1$s is a version number, maybe 1.1.
+#. %2$s is a URL.
+#: controllers/developers_controller.php:351
+msgid "devcp_update_addon_version_exists_error"
+msgstr ""
+"Die hochgeladene Version (%1$s) existiert bereits für dieses Add-on. Wenn "
+"Sie eine weitere Datei zu dieser Version hinzufügen möchten, <a href=\"%2$s"
+"\">klicken Sie hier</a>."
+
+#. %1$s and %2$s are version numbers.
+#: controllers/developers_controller.php:405
+msgid "devcp_update_addon_version_match_error"
+msgstr ""
+"Die hochgeladene Versionsnummer (%1$s) stimmt nicht mit der existierenden "
+"Versionsnummer (%2$s) überein."
+
+#: views/developers/uploader.thtml:68
+msgid "devcp_uploader_a_start"
+msgstr "Los geht's!"
+
+#: views/developers/uploader.thtml:137
+msgid "devcp_uploader_ajax_loading"
+msgstr "Datei wird hochgeladen..."
+
+#: views/developers/uploader.thtml:82
+msgid "devcp_uploader_button_agree"
+msgstr "Zustimmen und fortfahren"
+
+#: views/developers/uploader.thtml:157
+msgid "devcp_uploader_button_edit"
+msgstr "Mein Add-on bearbeiten"
+
+#: views/developers/uploader.thtml:158
+msgid "devcp_uploader_button_later"
+msgstr "Ich werde mein Add-on später vervollständigen."
+
+#: views/developers/uploader.thtml:168
+msgid "devcp_uploader_button_release"
+msgstr "Versionshinweise hinzufügen"
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/uploader.thtml:156
+msgid "devcp_uploader_created_results"
+msgstr ""
+"<p>Ihr Add-on-Eintrag wurde erfolgreich angelegt. Einige allgemeine "
+"Informationen wurden bereits aus Ihrer hochgeladenen Datei herausgelesen und "
+"gespeichert, aber es gibt noch viel mehr, das Sie an Ihrem Eintrag nach "
+"Belieben verändern können.</p><p>Ihr Add-on ist gegenwärtig als "
+"<strong>unvollständig</strong> markiert. Um Ihr Add-on zu vervollständigen, "
+"sollten Sie sicherstellen, dass es einen korrekten Namen hat, sowie eine "
+"Zusammenfassung und einen Beschreibungstext. Außerdem muss es mindestens "
+"einer Kategorie zugeordnet werden. Sie können Ihr Add-on bearbeiten, wenn "
+"Sie dem unten stehenden Link folgen. Den Status Ihres Add-ons können Sie "
+"jederzeit auf der <a %s>Status-Seite</a> prüfen."
+
+#: views/developers/uploader.thtml:143
+msgid "devcp_uploader_error_correct"
+msgstr "Bitte beheben Sie dieses Problem und laden Sie Ihre Datei erneut hoch."
+
+#. %1$s is a version number, %2$s is a status, e.g Public or Incomplete.
+#: views/developers/uploader.thtml:175
+msgid "devcp_uploader_file_created"
+msgstr ""
+"Ihre neue Datei wurde zur Version %1$s hinzugefügt und ist gegenwärtig als %2"
+"$s markiert."
+
+#: views/developers/uploader.thtml:154
+msgid "devcp_uploader_header_created"
+msgstr "Add-on angelegt!"
+
+#: views/developers/uploader.thtml:141
+msgid "devcp_uploader_header_error"
+msgstr "Hoppla! Mit dieser Datei scheint es ein Problem zu geben..."
+
+#: views/developers/uploader.thtml:173
+msgid "devcp_uploader_header_file_added"
+msgstr "Datei hinzugefügt!"
+
+#: views/developers/uploader.thtml:66
+msgid "devcp_uploader_header_how"
+msgstr "Wie funktioniert das alles?"
+
+#. %s is the version number, e.g. 3.2.
+#: views/developers/uploader.thtml:163
+msgid "devcp_uploader_header_update_created"
+msgstr "Version %s angelegt"
+
+#: views/developers/uploader.thtml:117
+msgid "devcp_uploader_header_upload"
+msgstr "Datei hochladen"
+
+#: views/developers/uploader.thtml:67
+msgid "devcp_uploader_how"
+msgstr ""
+"<p>Vielen Dank, dass Sie sich dafür interessieren, Ihr Add-on zu Mozilla Add-"
+"ons übermitteln. Ihr Add-on auf Mozilla Add-ons zu stellen ist der "
+"einfachste Weg, Ihr Add-on zu veröffentlichen. Dies sind Ihre Vorteile:</"
+"p><ul><li>Jedes Add-on verfügt über eine eigene, öffenliche Webseite mit den "
+"Informationen, die Sie zuvor eingeben, zum Beispiel einer kurzen "
+"Zusammenfassung zu den Fähigkeiten Ihres Add-ons, einem optionalen, längeren "
+"Beschreibungstext, sowie einer Anzahl von Vorschaubildern für Ihr Add-on.</"
+"li><li>Ihr Add-on wird in Suchergebnissen sowie verschiedenen Add-on-Listen "
+"angezeigt, und sogar im Add-on-Manager von Firefox&nbsp;3.</li><li>Wir "
+"stellen die Bandbreite für all Ihre Add-on-Downloads zur Verfügung und geben "
+"den Benutzern automatische Updates, wenn Sie eine neue Version hochladen.</"
+"li><li>Sie haben Zugriff auf eine Seite mit Statistiken, die Ihnen "
+"detaillierte Auskünfte darüber gibt, wie viele Leute Ihr Add-on verwenden.</"
+"li></ul><p>Add-ons, die auf dieser Seite erscheinen sollen, müssen von einem "
+"Mozilla Add-ons Moderator begutachtet werden, bevor Sie alle oben genannten "
+"Vorteile erhalten. Wenn Sie bereit sind, den Prozess zu beginnen, und wenn "
+"Sie Ihr Add-on-Paket für das Hochladen vorbereitet haben, klicken Sie auf "
+"\"Los geht's\"!"
+
+#: views/developers/uploader.thtml:125
+msgid "devcp_uploader_label_platformtype"
+msgstr "Unterstützte Betriebssysteme:"
+
+#: views/developers/uploader.thtml:124
+msgid "devcp_uploader_label_upload_field"
+msgstr "Add-on-Datei: "
+
+#: controllers/components/developers.php:1221
+msgid "devcp_uploader_option_other"
+msgstr "andere"
+
+#. %1$s is a number, %2$s is href="..." and should stay in the <a> tag.
+#: views/developers/uploader.thtml:176
+msgid "devcp_uploader_p_pending_file"
+msgstr ""
+"Die neue Datei wird öffentlich verfügbar sein, sobald ein Moderator sie "
+"begutachtet hat. Im Moment sind noch weitere %1$s Add-ons in dieser Liste. "
+"Möchten Sie, dass die Liste schneller schrumpft? Vielleicht möchten Sie <a %2"
+"$s>ein Moderator werden</a>?"
+
+#. %1$s is a number, %2$s is href="..." and should stay in the <a> tag.
+#: views/developers/uploader.thtml:166
+msgid "devcp_uploader_p_pending_version"
+msgstr ""
+"Die neue Version wird öffentlich verfügbar sein, sobald ein Moderator sie "
+"begutachtet hat. Im Moment sind noch weitere %1$s Add-ons in dieser Liste. "
+"Möchten Sie, dass die Liste schneller schrumpft? Vielleicht möchten Sie <a %2"
+"$s>ein Moderator werden</a>?"
+
+#. %s is a status, e.g Public or Incomplete.
+#: views/developers/uploader.thtml:165
+msgid "devcp_uploader_p_update_created"
+msgstr "Ihre neue Version wurde angelegt und ist gegenwärtig als %s markiert."
+
+#. %1$s is href="..." and should stay in the 'Versions and Files' <a> tag.
+#. %2$s is href="..." and should stay in the 'current status' <a> tag.
+#: views/developers/uploader.thtml:177
+msgid "devcp_uploader_p_update_file"
+msgstr ""
+"Sehen Sie sich Ihre neue Datei auf der <a %1$s>Seite für Versionen und "
+"Dateien</a> an, überprüfen Sie den <a %2$s>gegenwärtigen Status Ihres Add-"
+"ons</a> or <b>fügen Sie Versionsinformationen hinzu</b>, indem Sie auf den "
+"unten stehenden Knopf drücken (sehr empfohlen)."
+
+#. %1$s is href="..." and should stay in the 'Versions and Files' <a> tag.
+#. %2$s is href="..." and should stay in the 'current status' <a> tag.
+#: views/developers/uploader.thtml:167
+msgid "devcp_uploader_p_update_version"
+msgstr ""
+"Sehen Sie sich Ihre neue Version auf der <a %1$s>Seite für Versionen und "
+"Dateien</a> an, überprüfen Sie den <a %2$s>gegenwärtigen Status Ihres Add-"
+"ons</a> or <b>fügen Sie Versionsinformationen hinzu</b>, indem Sie auf den "
+"unten stehenden Knopf drücken (sehr empfohlen)."
+
+#: views/developers/uploader.thtml:118
+msgid "devcp_uploader_p_upload"
+msgstr ""
+"Laden Sie die Datei für Ihr Add-on mit dem unten stehenden Formular hoch. "
+"Falls Sie mehrere, plattform-spezifische Dateien haben, wählen Sie zunächst "
+"eine der Dateien und laden Sie die übrigen auf der \"Versionen und Dateien\"-"
+"Seite hoch."
+
+#: views/developers/uploader.thtml:125
+msgid "devcp_uploader_platformtype_all"
+msgstr "Alle"
+
+#: views/developers/uploader.thtml:126
+msgid "devcp_uploader_platformtype_specific"
+msgstr "Spezifisch:"
+
+#. Used as first item in a <select>.
+#: controllers/components/developers.php:1185
+msgid "devcp_uploader_please_choose"
+msgstr "Bitte wählen..."
+
+#. %1$s is the add-on name, %2$s is the version number.
+#: views/developers/uploader.thtml:57
+msgid "devcp_uploader_title_file"
+msgstr "Datei zu %1$s %2$s hinzufügen"
+
+#: views/developers/uploader.thtml:50
+msgid "devcp_uploader_title_submit"
+msgstr "Neues Add-on übermitteln"
+
+#. %s is the add-on name.
+#: views/developers/uploader.thtml:54
+msgid "devcp_uploader_title_update"
+msgstr "%s aktualisieren"
+
+#. %s is a full <a> tag
+#: controllers/developers_controller.php:503
+#, php-format
+msgid "devcp_valid_app_reference"
+msgstr "Bitte lesen Sie %s für weitere Informationen."
+
+#. This is the text in the <a> tag for devcp_valid_app_reference. This should be
+#. fixed.
+#: controllers/developers_controller.php:503
+msgid "devcp_valid_app_reference_linktext"
+msgstr "diese Seite"
+
+#: controllers/developers_controller.php:581
+msgid "devcp_verify_author_error"
+msgstr "Mit dieser E-Mail-Adresse wurde kein Benutzerkonto gefunden."
+
+#: controllers/developers_controller.php:553
+msgid "devcp_verify_search_engine_error"
+msgstr ""
+"Entweder das XML hat einen Fehler, oder benötigte Felder fehlen. Bitte <a "
+"href=\"https://developer.mozilla.org/en/"
+"Creating_OpenSearch_plugins_for_Firefox\">lesen Sie die Dokumentation</a>, "
+"überprüfen Sie Ihr Add-on und versuchen Sie esanschließend erneut."
+
+#: views/developers/versions.thtml:75
+msgid "devcp_versions_a_cancel"
+msgstr "Abbrechen"
+
+#: views/developers/versions.thtml:79
+msgid "devcp_versions_a_delete"
+msgstr "Version löschen"
+
+#: views/developers/versions.thtml:74
+msgid "devcp_versions_a_empty"
+msgstr "Leere Version löschen"
+
+#: views/developers/versions.thtml:71
+msgid "devcp_versions_a_remove"
+msgstr "Entfernen?"
+
+#: views/developers/versions.thtml:91
+msgid "devcp_versions_add"
+msgstr "Neue Version hinzufügen"
+
+#: views/developers/versions_delete.thtml:58
+msgid "devcp_versions_delete_a_cancel"
+msgstr "Abbrechen"
+
+#: views/developers/versions_delete.thtml:56
+msgid "devcp_versions_delete_a_delete"
+msgstr "Version löschen"
+
+#. Followed by a list of reviews and files that will be removed.
+#: views/developers/versions_delete.thtml:50
+msgid "devcp_versions_delete_also"
+msgstr "Dies wird auch folgendes löschen:"
+
+#: views/developers/versions_delete.thtml:53
+msgid "devcp_versions_delete_files"
+msgid_plural "devcp_versions_delete_files"
+msgstr[0] "%s Datei"
+msgstr[1] "%s Dateien"
+
+#. %s is the version number.
+#: views/developers/versions_delete.thtml:48
+msgid "devcp_versions_delete_header"
+msgstr "Version %s löschen?"
+
+#: views/developers/versions_delete.thtml:52
+msgid "devcp_versions_delete_reviews"
+msgid_plural "devcp_versions_delete_reviews"
+msgstr[0] "%s Bewertung"
+msgstr[1] "%s Bewertungen"
+
+#. %s is the version number.
+#: views/developers/versions_delete.thtml:49
+msgid "devcp_versions_delete_sure"
+msgstr "Sind Sie sicher, dass Sie Version %s permanent löschen möchten?"
+
+#: views/developers/versions_edit.thtml:102
+#: views/developers/versions_edit.thtml:155
+msgid "devcp_versions_edit_a_cancel"
+msgstr "Abbrechen"
+
+#: views/developers/versions_edit.thtml:101
+msgid "devcp_versions_edit_a_delete"
+msgstr "Datei löschen"
+
+#: views/developers/versions_edit.thtml:165
+msgid "devcp_versions_edit_a_new_app"
+msgstr "Neue Anwendung hinzufügen"
+
+#: views/developers/versions_edit.thtml:154
+msgid "devcp_versions_edit_a_remove_app"
+msgstr "Anwendung entfernen"
+
+#: views/developers/versions_edit.thtml:114
+msgid "devcp_versions_edit_add"
+msgstr "Neue Datei hinzufügen"
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/versions_edit.thtml:121
+msgid "devcp_versions_edit_adjust"
+msgstr ""
+"Wenn Sie die Anwendungs-Informationen hier ändern, können Benuzer Ihr Add-on "
+"auch installieren, wenn die Datei install.rdf in der hochgeladenen Add-on-"
+"Datei gegenteilige Informationen enthält. <a %s>Liste unterstützter "
+"Anwendungen</a>"
+
+#: views/developers/versions_edit.thtml:153
+msgid "devcp_versions_edit_compat_sure"
+msgstr ""
+"Sind Sie <b>sicher</b>, dass Sie die Kompatibilität mit dieser Anwendung "
+"entfernen möchten?"
+
+#: views/developers/versions_edit.thtml:100
+msgid "devcp_versions_edit_delete_sure"
+msgstr ""
+"Sind Sie <b>sicher</b>, dass Sie diese Datei dauerhaft löschen möchten?"
+
+#: views/developers/versions_edit.thtml:203
+msgid "devcp_versions_edit_header_approval"
+msgstr "Freischaltungs-Informationen"
+
+#: views/developers/versions_edit.thtml:120
+msgid "devcp_versions_edit_header_compat"
+msgstr "Kompatible Anwendungen"
+
+#: views/developers/versions_edit.thtml:74
+msgid "devcp_versions_edit_header_file"
+msgstr "Datei-Informationen"
+
+#: views/developers/versions_edit.thtml:189
+msgid "devcp_versions_edit_header_license"
+msgstr "Lizenz"
+
+#. %s is the version number.
+#: views/developers/versions_edit.thtml:53
+msgid "devcp_versions_edit_header_manage"
+msgstr "Version %s bearbeiten"
+
+#: views/developers/versions_edit.thtml:212
+msgid "devcp_versions_edit_header_notes"
+msgstr "Hinweise zur Begutachtung"
+
+#: views/developers/versions_edit.thtml:98
+msgid "devcp_versions_edit_img_delete"
+msgstr "Datei löschen"
+
+#. %1$s is the file id, e.g. 18723.
+#. %2$s is the platform name, e.g. ALL or Windows.
+#. %3$s is the _('date) created.
+#. %4$s is the status, e.g. "In Sandbox" or "Public".
+#. %5$s is the _('date') status was changed.
+#: views/developers/versions_edit.thtml:208
+msgid "devcp_versions_edit_li_file"
+msgstr "Datei %1$s (%2$s), angelegt am %3$s und verändert zu \"%4$s\" am %5$s"
+
+#: views/developers/versions_edit.thtml:190
+msgid "devcp_versions_edit_license_description"
+msgstr ""
+"Bitte wählen Sie die anwendbare Lizenz für Ihr Add-on. Diese Lizenz legt "
+"fest, welche Rechte Sie an Ihrem Quellcode gewähren möchten."
+
+#: views/developers/versions_edit.thtml:111
+msgid "devcp_versions_edit_no_files"
+msgstr "Keine Dateien gefunden."
+
+#: views/developers/versions_edit.thtml:213
+msgid "devcp_versions_edit_optional"
+msgstr ""
+"Optionale Informationen für den Moderator, der diese Version begutachten "
+"wird."
+
+#: views/developers/versions_edit.thtml:151
+msgid "devcp_versions_edit_remove_compat"
+msgstr "Anwendungs-Kompatibilität entfernen"
+
+#: views/developers/versions_edit.thtml:167
+msgid "devcp_versions_edit_select_app"
+msgstr "Bitte wählen Sie eine Anwendung"
+
+#: views/developers/versions_edit.thtml:78
+msgid "devcp_versions_edit_th_file"
+msgstr "Datei"
+
+#: views/developers/versions_edit.thtml:79
+msgid "devcp_versions_edit_th_platform"
+msgstr "Betriebssystem"
+
+#: views/developers/versions_edit.thtml:80
+msgid "devcp_versions_edit_th_size"
+msgstr "Größe"
+
+#: views/developers/versions_edit.thtml:81
+msgid "devcp_versions_edit_th_status"
+msgstr "Status"
+
+#: views/developers/versions_edit.thtml:183
+msgid "devcp_versions_edit_transbox_releasenotes_description"
+msgstr ""
+"Informationen über Veränderungen in dieser Version, neue Funktionen, "
+"bekannte Fehler und weitere nützliche Informationen, die sich nur auf diese "
+"Version beziehen. Diese Information wird für alle Benutzern sichtbar sein, "
+"wenn sie das Add-on über den Firefox&nbsp;3 Add-on Manager aktualisieren."
+
+#: views/developers/versions_edit.thtml:182
+msgid "devcp_versions_edit_transbox_releasenotes_name"
+msgstr "Versionshinweise"
+
+#: views/developers/versions_edit.thtml:164
+msgid "devcp_versions_edit_unsaved_compat"
+msgstr ""
+"<strong>Sie haben noch ungespeicherte Änderungen.</strong> Die "
+"Kompatibilität wird nicht gelöscht werden, bevor Sie unten auf \"Version "
+"aktualisieren\" klicken."
+
+#: views/developers/versions_edit.thtml:113
+msgid "devcp_versions_edit_unsaved_files"
+msgstr ""
+"<strong>Sie haben noch ungespeicherte Änderungen.</strong> Es werden keine "
+"Dateien gelöscht werden, bevor Sie unten auf \"Version aktualisieren\" "
+"klicken."
+
+#: views/developers/versions_edit.thtml:218
+msgid "devcp_versions_edit_update"
+msgstr "Versionen aktualisieren"
+
+#: views/developers/versions.thtml:49
+msgid "devcp_versions_header_manage"
+msgstr "Versionen und Dateien bearbeiten"
+
+#: views/developers/versions.thtml:87
+msgid "devcp_versions_no_versions"
+msgstr "Keine Versionen."
+
+#. %s is a version number, base 10.
+#: views/developers/versions.thtml:46
+msgid "devcp_versions_notice_success"
+msgstr "Version %s wurde erfolgreich gelöscht."
+
+#: views/developers/versions.thtml:73
+msgid "devcp_versions_p_remove"
+msgstr ""
+"Diese Versionen hat keine Dateien und kann entfernt werden. Möchten Sie das "
+"tun?"
+
+#: views/developers/versions.thtml:58
+msgid "devcp_versions_th_created"
+msgstr "Angelegt"
+
+#: views/developers/versions.thtml:57
+msgid "devcp_versions_th_status"
+msgstr "Status"
+
+#: views/developers/versions.thtml:56
+msgid "devcp_versions_th_version"
+msgstr "Version"
+
+#: controllers/downloads_controller.php:91
+msgid "downloads_disable_warning"
+msgstr "Dieses Add-on ist deaktiviert."
+
+#: controllers/components/editors.php:57
+msgid "editor_review_error_addon_not_nominated"
+msgstr "Dieses Add-on ist momentan nicht zur Veröffentlichung nominiert."
+
+#: controllers/components/editors.php:213
+msgid "editor_review_error_file_not_pending"
+msgstr "Diese Datei wartet gegenwärtig nicht auf Freischaltung."
+
+#. Actions are, for example: approving or rejecting
+#: controllers/components/editors.php:79
+#: controllers/components/editors.php:182
+msgid "editor_review_error_no_action"
+msgstr "Bitte wählen Sie eine Aktion aus."
+
+#: controllers/components/editors.php:192
+msgid "editor_review_error_no_applications"
+msgstr ""
+"Bitte geben Sie die Anwendungen ein, mit denen Sie das Add-on getestet haben."
+
+#. Comments are required when an editor approves or rejects an add-on.
+#: controllers/components/editors.php:84
+#: controllers/components/editors.php:187
+msgid "editor_review_error_no_comments"
+msgstr "Bitte geben Sie einen Kommentar ein."
+
+#: controllers/components/editors.php:161
+msgid "editor_review_error_no_files"
+msgstr "Bitte wählen Sie mindestens eine Datei aus."
+
+#: controllers/components/editors.php:197
+msgid "editor_review_error_no_operating_system"
+msgstr ""
+"Bitte wählen Sie die Betriebssysteme aus, mit denen Sie getestet haben."
+
+#: views/editors/logs.thtml:51
+msgid "editorcp_logs_button_filter"
+msgstr "Filtern"
+
+#: views/editors/logs.thtml:44
+msgid "editorcp_logs_filter_by"
+msgstr "Nach Typ/Aktion filtern"
+
+#: views/editors/logs.thtml:42 controllers/editors_controller.php:964
+msgid "editorcp_logs_page_heading"
+msgstr "Bewertungslogbuch"
+
+#: views/elements/developers/editorsmenu.thtml:60
+msgid "editorcp_menu_eventlog_link"
+msgstr "Bewertungslogbuch"
+
+#: views/elements/developers/editorsmenu.thtml:62
+msgid "editorcp_menu_mainpage_link"
+msgstr "Zurück zur Hauptseite"
+
+#: views/elements/developers/editorsmenu.thtml:61
+msgid "editorcp_menu_reviewlog_link"
+msgstr "Moderationslogbuch"
+
+#: views/elements/developers/editorsmenu.thtml:55
+msgid "editorcp_menu_summary_link"
+msgstr "Überblick für Moderatoren"
+
+#: views/elements/developers/editorsmenu.thtml:52
+msgid "editorcp_menu_title"
+msgstr "Moderatoren"
+
+#: views/editors/reviewlog.thtml:49
+msgid "editorcp_reviewlog_button_filter"
+msgstr "Filtern"
+
+#: views/editors/reviewlog.thtml:58
+msgid "editorcp_reviewlog_column_action"
+msgstr "Aktion"
+
+#: views/editors/reviewlog.thtml:56
+msgid "editorcp_reviewlog_column_addon"
+msgstr "Add-on"
+
+#: views/editors/reviewlog.thtml:55
+msgid "editorcp_reviewlog_column_date"
+msgstr "Datum"
+
+#: views/editors/reviewlog.thtml:57
+msgid "editorcp_reviewlog_column_editor"
+msgstr "Moderator"
+
+#: views/editors/reviewlog.thtml:94
+msgid "editorcp_reviewlog_comments_hide"
+msgstr "Kommentare verstecken"
+
+#: views/editors/reviewlog.thtml:93
+msgid "editorcp_reviewlog_comments_show"
+msgstr "Kommentare zeigen"
+
+#. %1$s and %2$s are full <input> tags for dates
+#: views/editors/reviewlog.thtml:45
+#, php-format
+msgid "editorcp_reviewlog_entries_between"
+msgstr "Einträge zwischen %s und %s anzeigen"
+
+#: views/editors/reviewlog.thtml:104
+msgid "editorcp_reviewlog_none_found"
+msgstr "Keine Bewertungen in diesem Zeitraum gefunden."
+
+#: views/editors/reviewlog.thtml:42
+msgid "editorcp_reviewlog_page_heading"
+msgstr "Moderationslogbuch"
+
+#: views/editors/summary.thtml:61
+msgid "editorcp_summary_monthreviews_heading"
+msgstr "Bewertungen diesen Monat"
+
+#: views/editors/summary.thtml:77
+msgid "editorcp_summary_neweditors_heading"
+msgstr "Neue Moderatoren"
+
+#: views/editors/summary.thtml:42
+msgid "editorcp_summary_page_heading"
+msgstr "Überblick für Moderatoren"
+
+#: views/editors/summary.thtml:94
+msgid "editorcp_summary_recentactivity_heading"
+msgstr "Aktuellste Moderationen"
+
+#: views/editors/summary.thtml:45
+msgid "editorcp_summary_totalreviews_heading"
+msgstr "Bewertungen gesamt"
+
+#: controllers/editors_controller.php:248
+#: controllers/editors_controller.php:249
+msgid "editors_addon_review_pagetitle"
+msgstr "Add-on moderieren"
+
+#: controllers/editors_controller.php:349
+msgid "editors_error_js-formerror"
+msgstr "Bitte vervollständigen Sie die folgenden Felder:"
+
+#: controllers/editors_controller.php:350
+msgid "editors_error_review_one_file"
+msgstr "Bitte wählen Sie mindestens eine Datei zur Moderation aus."
+
+#: controllers/editors_controller.php:274
+msgid "editors_error_self_reviews_forbidden"
+msgstr "Selbstmoderation ist nicht erlaubt."
+
+#: controllers/editors_controller.php:699
+msgid "editors_external_software"
+msgstr "Externe Software"
+
+#: views/editors/featured.thtml:120 views/editors/featured.thtml:121
+msgid "editors_featured_add_feature"
+msgstr "Empfehlung hinzufügen"
+
+#: views/editors/featured.thtml:126
+msgid "editors_featured_add_feature_submit"
+msgstr "Hinzufügen"
+
+#: views/editors/featured.thtml:49 controllers/editors_controller.php:832
+#: controllers/editors_controller.php:848
+msgid "editors_featured_addon_add_failure"
+msgstr "Hinzufügen fehlgeschlagen."
+
+#: controllers/editors_controller.php:851
+msgid "editors_featured_addon_add_success"
+msgstr "Erfolgreich hinzugefügt."
+
+#: views/editors/featured.thtml:50 controllers/editors_controller.php:839
+#: controllers/editors_controller.php:868
+#: controllers/editors_controller.php:886
+msgid "editors_featured_addon_edit_failure"
+msgstr "Editieren fehlgeschlagen."
+
+#: views/editors/featured.thtml:51 controllers/editors_controller.php:888
+msgid "editors_featured_addon_edit_success"
+msgstr "Erfolgreich gespeichert."
+
+#: views/editors/featured.thtml:53 controllers/editors_controller.php:861
+msgid "editors_featured_addon_invalid_locale"
+msgstr "Ein oder mehrere Sprachen sind ungültig."
+
+#: views/editors/featured.thtml:52 controllers/editors_controller.php:906
+msgid "editors_featured_addon_remove_failure"
+msgstr "Entfernen fehlgeschlagen."
+
+#: controllers/editors_controller.php:901
+msgid "editors_featured_addon_remove_success"
+msgstr "Erfolgreich entfernt."
+
+#: controllers/editors_controller.php:915
+#: controllers/editors_controller.php:917
+msgid "editors_featured_addons_pagetitle"
+msgstr "Empfohlene Add-ons"
+
+#: views/editors/featured.thtml:54 views/editors/featured.thtml:107
+msgid "editors_featured_edit_feature_submit"
+msgstr "Absenden"
+
+#: views/editors/featured.thtml:90 views/editors/featured.thtml:91
+msgid "editors_featured_remove_feature"
+msgstr "Entfernen"
+
+#: views/editors/queue.thtml:46
+msgid "editors_filter_queue"
+msgstr "Warteliste filtern"
+
+#: views/editors/queue.thtml:182
+msgid "editors_helpful_links"
+msgstr "Nützliche Links"
+
+#: views/editors/queue.thtml:182
+msgid "editors_link_guide"
+msgstr "Moderatorenhandbuch"
+
+#: views/editors/queue.thtml:182
+msgid "editors_link_policy"
+msgstr "Rechtliche Hinweise zum Add-on"
+
+#: views/editors/queue.thtml:47
+msgid "editors_notice_filter_session"
+msgstr ""
+"Diese Filter bleiben für diese Sitzung aktiv oder bis sie gelöscht werden."
+
+#. %1 is the queue mode
+#: views/editors/queue.thtml:177 views/admin/flagged_queue.thtml:89
+msgid "editors_notice_none_found"
+msgstr "Momentan sind keine %s Add-ons zu moderieren."
+
+#: controllers/editors_controller.php:1040
+msgid "editors_one_day"
+msgstr "1 Tag"
+
+#: controllers/editors_controller.php:1048
+msgid "editors_one_hour"
+msgstr "1 Stunde"
+
+#: controllers/editors_controller.php:1056
+msgid "editors_one_minute"
+msgstr "1 Minute"
+
+#: controllers/editors_controller.php:64 controllers/editors_controller.php:73
+#: controllers/editors_controller.php:77
+msgid "editors_pagetitle"
+msgstr "Moderatorenwerkzeuge"
+
+#. %s is a comma separated list of platforms. Example: Windows, OS X
+#: controllers/editors_controller.php:680
+#: controllers/editors_controller.php:683
+#, php-format
+msgid "editors_platform_x_only"
+msgstr "nur %s"
+
+#: controllers/editors_controller.php:695
+msgid "editors_pre-release"
+msgstr "Testversion"
+
+#. %1 is the app name
+#: views/editors/queue.thtml:131
+#, php-format
+msgid "editors_queue_app_compatibility"
+msgstr "%s Kompatibilität"
+
+#: views/editors/queue.thtml:51
+msgid "editors_queue_filter_label_addon"
+msgstr "Add-on oder Autor-E-Mail"
+
+#: views/editors/queue.thtml:72
+msgid "editors_queue_filter_label_addontypes"
+msgstr "Add-on-Typen"
+
+#: views/editors/queue.thtml:56
+msgid "editors_queue_filter_label_application"
+msgstr "Anwendung"
+
+#: views/editors/queue.thtml:61
+msgid "editors_queue_filter_label_maxversion"
+msgstr "Max. Version"
+
+#: views/editors/queue.thtml:78
+msgid "editors_queue_filter_label_platforms"
+msgstr "Betriebssystem"
+
+#: views/editors/queue.thtml:66
+msgid "editors_queue_filter_label_submissionage"
+msgstr "Zeit in Liste (Tage)"
+
+#. %1$s is a number
+#: views/editors/queue.thtml:90
+msgid "editors_queue_filter_result_count"
+msgid_plural "editors_queue_filter_result_count"
+msgstr[0] "Ergebnis Ihrer Filter-Suche: <strong>%1$s</strong> Add-on"
+msgstr[1] "Ergebnis Ihrer Filter-Suche: <strong>%1$s</strong> Add-ons"
+
+#: views/editors/queue.thtml:84
+msgid "editors_queue_submit_clean"
+msgstr "Löschen"
+
+#: views/editors/queue.thtml:83
+msgid "editors_queue_submit_filter"
+msgstr "Filter"
+
+#: controllers/editors_controller.php:133
+msgid "editors_queues_disabled"
+msgstr ""
+"Alle Moderationslisten sind momentan deaktiviert. Bitte versuchen Sie es "
+"später noch einmal."
+
+#: views/editors/review.thtml:149
+msgid "editors_review_a_edit_item"
+msgstr "Editieren"
+
+#: views/editors/review.thtml:146
+msgid "editors_review_a_item_history"
+msgstr "Versionsgeschichte"
+
+#: views/editors/review.thtml:148
+msgid "editors_review_a_item_homepage"
+msgstr "Homepage"
+
+#: views/editors/review.thtml:145
+msgid "editors_review_a_item_overview"
+msgstr "Ãœbersicht"
+
+#: views/editors/review.thtml:147
+msgid "editors_review_a_previews"
+msgstr "Vorschaubilder"
+
+#: controllers/editors_controller.php:345
+msgid "editors_review_action"
+msgstr "Moderationsauftrag"
+
+#: views/editors/review.thtml:159
+msgid "editors_review_action_info"
+msgstr "Mehr Infos anfordern"
+
+#: views/editors/review.thtml:157
+msgid "editors_review_action_public"
+msgstr "Veröffentlichen"
+
+#: views/editors/review.thtml:160
+msgid "editors_review_action_request_superreview"
+msgstr "Intensive Untersuchung anfordern"
+
+#: views/editors/review.thtml:158
+msgid "editors_review_action_sandbox"
+msgstr "Im Sandkasten belassen"
+
+#: controllers/editors_controller.php:346
+msgid "editors_review_comments"
+msgstr "Bewertungen bearbeiten"
+
+#: views/editors/review.thtml:182
+msgid "editors_review_details_info_request"
+msgstr ""
+"Verwenden Sie dieses Formular, um vom Autor mehr Informationen anzufordern. "
+"Der Autor bekommt dann eine E-Mail und kann an dieser Stelle auf die Frage "
+"antworten. Wenn der Autor das getan hat, erhalten Sie einen Hinweis per E-"
+"Mail."
+
+#: views/editors/review.thtml:174
+msgid "editors_review_details_nominated_public"
+msgstr ""
+"Damit werden das Add-on und seine neuesten Dateien veröffentlicht. Spätere "
+"Versionen werden in den Sandkasten übermittelt bis sie von einem Moderator "
+"getestet worden."
+
+#: views/editors/review.thtml:177
+msgid "editors_review_details_nominated_sandbox"
+msgstr "Das Add-on wird im Sandkasten belassen"
+
+#: views/editors/review.thtml:166
+msgid "editors_review_details_pending_public"
+msgstr ""
+"Damit wird ein Add-on aus dem Sandkasten in den öffentlichen Seiten "
+"veröffentlicht."
+
+#: views/editors/review.thtml:169
+msgid "editors_review_details_pending_sandbox"
+msgstr ""
+"Damit wird die Version im Sandkasten eines öffentlichen Add-on dort belassen."
+
+#: views/editors/review.thtml:185
+msgid "editors_review_details_superreview"
+msgstr ""
+"Im Falle von Unsicherheit über die Sicherheit des Add-ons, "
+"Urheberrechtsverletzungen oder anderer Bedenken, denen ein Administrator "
+"nachgehen soll, so geben Sie Ihre Kommentare bitte im folgenden Feld an. Sie "
+"werden an die Administratoren, nicht die Entwickler, übermitterlt."
+
+#: views/editors/review.thtml:134
+msgid "editors_review_file_diff_link"
+msgstr "Code mit letzter öffentlicher Version vergleichen"
+
+#: views/editors/review.thtml:131
+msgid "editors_review_file_viewcontents_link"
+msgstr "Inhalte anzeigen"
+
+#: views/editors/review.thtml:65
+msgid "editors_review_header_authors"
+msgstr "Entwickler:"
+
+#: views/editors/review.thtml:79
+msgid "editors_review_header_categories"
+msgstr "Kategorien:"
+
+#: views/editors/review.thtml:92
+msgid "editors_review_header_compatibility"
+msgstr "Kompatibilität:"
+
+#: views/editors/review.thtml:251
+msgid "editors_review_header_description"
+msgstr "Beschreibung"
+
+#: views/editors/review.thtml:275
+msgid "editors_review_header_devcomments"
+msgstr "Entwicklerkommentare"
+
+#: views/editors/review.thtml:263
+msgid "editors_review_header_eula"
+msgstr "Endbenutzer-Lizenzvereinbarung (EULA)"
+
+#: views/editors/review.thtml:115
+msgid "editors_review_header_files"
+msgstr "Dateien:"
+
+#: views/editors/review.thtml:284
+msgid "editors_review_header_itemhistory"
+msgstr "Add-on-Historie"
+
+#: views/editors/review.thtml:232
+msgid "editors_review_header_nominationmessage"
+msgstr "Nominierungs-Nachricht"
+
+#: views/editors/review.thtml:311
+msgid "editors_review_header_previews"
+msgstr "Vorschaubilder"
+
+#: views/editors/review.thtml:269
+msgid "editors_review_header_privacy"
+msgstr "Datenschutzerklärung"
+
+#. %1 is the add-on name and version
+#: views/editors/review.thtml:56
+#, php-format
+msgid "editors_review_header_review"
+msgstr "Moderiere %s"
+
+#: views/editors/review.thtml:239
+msgid "editors_review_header_reviewernotes"
+msgstr "Hinweise an den Moderator"
+
+#: views/editors/review.thtml:245
+msgid "editors_review_header_summary"
+msgstr "Zusammenfassung"
+
+#: views/editors/review.thtml:257
+msgid "editors_review_header_versionnotes"
+msgstr "Versionshinweise"
+
+#. a noun: shown in an add-on's editor review history
+#: views/elements/developers/editors_review_history_item.thtml:80
+msgid "editors_review_history_info_reply"
+msgstr "Antwort"
+
+#: views/elements/developers/editors_review_history_item.thtml:78
+msgid "editors_review_history_info_request"
+msgstr "Info-Anforderung"
+
+#: views/elements/developers/editors_review_history_item.thtml:62
+#: views/editors/reviewlog.thtml:77
+msgid "editors_review_history_nominated_adminreview"
+msgstr "Untersuchung durch Admin"
+
+#: views/elements/developers/editors_review_history_item.thtml:56
+#: views/editors/reviewlog.thtml:71
+msgid "editors_review_history_nominated_approved"
+msgstr "Nominierung genehmigt/Öffentlich"
+
+#: views/elements/developers/editors_review_history_item.thtml:59
+#: views/editors/reviewlog.thtml:74
+msgid "editors_review_history_nominated_denied"
+msgstr "Nominierung abgelehnt/Sandkasten"
+
+#: views/editors/review.thtml:303
+msgid "editors_review_history_nonefound"
+msgstr "Es wurden bisher keine Moderationen für dieses Add-on durchgeführt."
+
+#: views/elements/developers/editors_review_history_item.thtml:73
+#: views/editors/reviewlog.thtml:88
+msgid "editors_review_history_pending_adminreview"
+msgstr "Untersuchung durch Admin"
+
+#: views/elements/developers/editors_review_history_item.thtml:67
+#: views/editors/reviewlog.thtml:82
+msgid "editors_review_history_pending_approved"
+msgstr "Update genehmigt/Öffentlich"
+
+#: views/elements/developers/editors_review_history_item.thtml:70
+#: views/editors/reviewlog.thtml:85
+msgid "editors_review_history_pending_denied"
+msgstr "Update abgelehnt/Sandkasten"
+
+#. link text in an add-on's editor review history, allowing to hide and show an information request's replies
+#. %1 is the number of replies
+#: views/elements/developers/editors_review_history_item.thtml:90
+msgid "editors_review_history_show_hide_replies"
+msgid_plural "editors_review_history_show_hide_replies"
+msgstr[0] "Antwort zeigen/verstecken (%1$s)"
+msgstr[1] "Antworten zeigen/verstecken (%1$s)"
+
+#: views/editors/review.thtml:208
+msgid "editors_review_label_applications"
+msgstr "Anwendungen:"
+
+#: views/editors/review.thtml:196
+msgid "editors_review_label_cannedresponse"
+msgstr "oder wählen Sie eine Antwortvorlage:"
+
+#: views/editors/review.thtml:190
+msgid "editors_review_label_comments"
+msgstr "Kommentare:"
+
+#: views/editors/review.thtml:204
+msgid "editors_review_label_operating_systems"
+msgstr "Betriebssysteme:"
+
+#: views/editors/review.thtml:285 views/editors/review.thtml:312
+msgid "editors_review_link_pagetop"
+msgstr "Nach oben"
+
+#: views/editors/review.thtml:141
+msgid "editors_review_mulitple_notice"
+msgstr ""
+"Hinweis: Bitte bewerten Sie nur dann mehr als eine Datei, wenn Sie JEDE "
+"dieser Dateien überprüft haben."
+
+#: views/editors/review.thtml:51
+msgid "editors_review_next_link"
+msgstr "weiter &raquo;"
+
+#: views/editors/review.thtml:322
+msgid "editors_review_previews_notfound"
+msgstr "Keine Vorschau gefunden."
+
+#: views/editors/review.thtml:50
+msgid "editors_review_previous_link"
+msgstr "&laquo; zurück"
+
+#: controllers/editors_controller.php:144
+#: controllers/editors_controller.php:146
+msgid "editors_review_queue_pagetitle"
+msgstr "Moderationswarteliste"
+
+#. %1 is the add-ons rank in the queue, %2 is the total queue length
+#: views/editors/review.thtml:47
+msgid "editors_review_rank_in_queue"
+msgstr "<strong>Nr. %1$s</strong> von %2$s Add-ons in der Liste"
+
+#. %1 is the add-ons rank in the queue, %2 is the total queue length. Both numbers
+#: views/editors/review.thtml:45
+msgid "editors_review_rank_in_queue_filtered"
+msgstr "<strong>Nr. %1$s</strong> von %2$s in der Liste (gefiltert)"
+
+#: views/editors/review.thtml:223
+msgid "editors_review_submit_process_action"
+msgstr "Aktion ausführen"
+
+#: views/editors/review.thtml:293
+msgid "editors_review_th_action"
+msgstr "Aktion"
+
+#: views/editors/review.thtml:294
+msgid "editors_review_th_comments"
+msgstr "Kommentare"
+
+#: views/editors/review.thtml:291
+msgid "editors_review_th_date"
+msgstr "Datum"
+
+#: views/editors/review.thtml:292
+msgid "editors_review_th_reviewer"
+msgstr "Moderator"
+
+#: views/editors/review.thtml:290
+msgid "editors_review_th_version_file"
+msgstr "Version/Datei"
+
+#: views/editors/review.thtml:217
+msgid "editors_review_update_notify_once"
+msgstr ""
+"Benachrichtigen Sie mich das nächste mal, wenn dieses Add-on aktualisiert "
+"wird (Einmalig: Nachfolgende Updates erzeugen keine weiteren E-Mails.)"
+
+#: controllers/editors_controller.php:298
+msgid "editors_reviewed_successfully"
+msgstr "Moderation erfolgreich übermittelt"
+
+#: views/editors/reviews_queue.thtml:106
+msgid "editors_reviews_action_delete_review"
+msgstr "Bewertung löschen"
+
+#: views/editors/reviews_queue.thtml:104
+msgid "editors_reviews_action_keep"
+msgstr "Flags löschen; Bewertung behalten"
+
+#: views/editors/reviews_queue.thtml:102
+msgid "editors_reviews_action_skip"
+msgstr "Ãœberspringen"
+
+#: views/editors/reviews_queue.thtml:100
+msgid "editors_reviews_header_action"
+msgstr "Aktion"
+
+#: views/editors/reviews_queue.thtml:67
+msgid "editors_reviews_in_reply_to"
+msgstr "Antwort auf:"
+
+#: controllers/editors_controller.php:748
+msgid "editors_reviews_processed"
+msgstr "Moderationen erfolgreich übermittelt!"
+
+#: views/editors/reviews_queue.thtml:117
+msgid "editors_reviews_queue_empty"
+msgstr "Im Moment sind keine Bewertungen zu moderieren."
+
+#: views/editors/reviews_queue.thtml:111
+msgid "editors_reviews_submit_process_reviews"
+msgstr "Moderation übermitteln"
+
+#: controllers/editors_controller.php:691
+msgid "editors_site_specific"
+msgstr "Seitenabhängig"
+
+#: controllers/editors_controller.php:348
+msgid "editors_tested_app"
+msgstr "Getestete Anwendungen"
+
+#: controllers/editors_controller.php:347
+msgid "editors_tested_os"
+msgstr "Getestete Betriebssysteme"
+
+#: views/editors/queue.thtml:151
+msgid "editors_th_additional_info"
+msgstr "Zusätzliche Informationen"
+
+#: views/editors/featured.thtml:63 views/editors/queue.thtml:109
+#: views/admin/flagged_queue.thtml:53
+msgid "editors_th_addon"
+msgstr "Add-on"
+
+#: views/editors/queue.thtml:125
+msgid "editors_th_addontype"
+msgstr "Typ"
+
+#: views/editors/featured.thtml:64
+msgid "editors_th_locales"
+msgstr "Nur für einige Sprachen?"
+
+#: views/editors/queue.thtml:148
+msgid "editors_th_nomination_age"
+msgstr "Zeit in Liste"
+
+#: views/editors/queue.thtml:101 views/editors/queue.thtml:117
+#: views/editors/queue.thtml:144
+msgid "editors_th_sort_ascending"
+msgstr "Aufsteigend"
+
+#: views/editors/queue.thtml:105 views/editors/queue.thtml:121
+#: views/editors/queue.thtml:140
+msgid "editors_th_sort_descending"
+msgstr "Absteigend"
+
+#. %s is a number
+#: controllers/editors_controller.php:1036
+#, php-format
+msgid "editors_x_days"
+msgstr "%s Tage"
+
+#. %s is a number
+#: controllers/editors_controller.php:1044
+#, php-format
+msgid "editors_x_hours"
+msgstr "%s Stunden"
+
+#. %s is a number
+#: controllers/editors_controller.php:1052
+#, php-format
+msgid "editors_x_minutes"
+msgstr "%s Minuten"
+
+#: views/errors/error401.thtml:50 controllers/components/simple_acl.php:81
+#: controllers/components/simple_acl.php:82
+#: controllers/components/simple_acl.php:83 controllers/components/amo.php:607
+#: controllers/components/amo.php:608 controllers/components/amo.php:609
+#: controllers/reviews_controller.php:353
+#: controllers/reviews_controller.php:485
+#: controllers/collections_controller.php:438
+#: controllers/collections_controller.php:496
+#: controllers/collections_controller.php:504
+#: controllers/collections_controller.php:971
+#: controllers/collections_controller.php:1034
+#: controllers/collections_controller.php:1077
+msgid "error_access_denied"
+msgstr "Zugriff verweigert"
+
+#: views/errors/error401.thtml:52
+msgid "error_access_denied_message"
+msgstr ""
+"Sie haben nicht die erforderlichen Berechtigungen, um diese Seite angezeigt "
+"zu bekommen."
+
+#: controllers/collections_controller.php:1039
+msgid "error_addon_exists"
+msgstr "Add-on existiert bereits!"
+
+#: controllers/developers_controller.php:200
+#: controllers/developers_controller.php:593
+#: controllers/developers_controller.php:1016
+#: controllers/developers_controller.php:1429
+#: controllers/downloads_controller.php:95
+#: controllers/downloads_controller.php:102
+#: controllers/downloads_controller.php:164
+#: controllers/statistics_controller.php:135
+#: controllers/previews_controller.php:115
+#: controllers/previews_controller.php:206
+#: controllers/previews_controller.php:307
+#: controllers/reviews_controller.php:77
+#: controllers/reviews_controller.php:240
+#: controllers/reviews_controller.php:332
+#: controllers/reviews_controller.php:340 controllers/api_controller.php:123
+#: controllers/api_controller.php:759 controllers/addons_controller.php:131
+#: controllers/addons_controller.php:197
+#: controllers/addons_controller.php:1407
+#: controllers/addons_controller.php:1465
+#: controllers/addons_controller.php:1469
+#: controllers/addons_controller.php:1503
+#: controllers/editors_controller.php:265
+#: controllers/collections_controller.php:1041
+#: controllers/collections_controller.php:1074
+msgid "error_addon_notfound"
+msgstr "Add-on nicht gefunden!"
+
+#: controllers/files_controller.php:83 controllers/files_controller.php:196
+msgid "error_addon_notviewable"
+msgstr "Dieses Add-on kann hier nicht angezeigt werden."
+
+#: controllers/reviews_controller.php:246
+msgid "error_addon_selfreview"
+msgstr "Sie dürfen keine Bewertungen für Ihre eigenen Add-ons abgeben."
+
+#: controllers/addons_controller.php:970
+msgid "error_browse_no_addons"
+msgstr "Keine Add-ons in dieser Kategorie gefunden!"
+
+#: controllers/api_controller.php:424
+msgid "error_collection_feed_notfound"
+msgstr "Add-on-Feed nicht gefunden."
+
+#: views/users/register.thtml:65 views/users/edit.thtml:194
+msgid "error_email_invalid"
+msgstr "Dies ist keine korrekte E-Mail-Adresse!"
+
+#: views/users/pwreset.thtml:74 views/users/register.thtml:70
+#: views/users/register.thtml:80 views/users/register.thtml:86
+#: views/users/edit.thtml:105 views/users/edit.thtml:111
+#: views/users/edit.thtml:192 views/admin/users_edit.thtml:78
+#: views/admin/users_edit.thtml:83 views/reviews/add.thtml:80
+#: views/reviews/add.thtml:104
+msgid "error_field_required"
+msgstr "Dieses Feld darf nicht leer sein."
+
+#: controllers/files_controller.php:75 controllers/files_controller.php:93
+#: controllers/files_controller.php:96 controllers/files_controller.php:163
+#: controllers/files_controller.php:176 controllers/files_controller.php:185
+#: controllers/files_controller.php:204 controllers/editors_controller.php:412
+msgid "error_file_notfound"
+msgstr "Datei nicht gefunden!"
+
+#. %s is a filename
+#: controllers/editors_controller.php:430
+#, php-format
+msgid "error_file_x_notfound"
+msgstr "Dateifehler: %s existiert nicht."
+
+#: views/collections/add.thtml:55 views/collections/edit.thtml:89
+#: views/users/register.thtml:54 views/users/edit.thtml:81
+#: views/reviews/add.thtml:70 controllers/groups_controller.php:80
+#: controllers/groups_controller.php:102
+msgid "error_formerrors"
+msgstr ""
+"Dieses Formular enthält Fehler. Bitte korrigieren Sie diese und schicken Sie "
+"es erneut ab."
+
+#: views/users/register.thtml:109
+msgid "error_invalid_captcha"
+msgstr "Ungültige Zeichenfolge: Bitte erneut versuchen!"
+
+#: views/users/register.thtml:100 views/users/edit.thtml:125
+#: views/admin/users_edit.thtml:101
+msgid "error_invalid_url"
+msgstr ""
+"Dies ist keine gültige URL. Erlaubte URLs sehen etwa wie folgt aus: http://"
+"example.com/meine_seite."
+
+#. %s is a string representing what's missing. Example: file_id
+#: controllers/downloads_controller.php:65
+#: controllers/users_controller.php:185 controllers/users_controller.php:264
+#: controllers/users_controller.php:559 controllers/users_controller.php:653
+#: controllers/reviews_controller.php:71
+#: controllers/reviews_controller.php:234
+#: controllers/reviews_controller.php:325
+#: controllers/reviews_controller.php:473
+#: controllers/reviews_controller.php:475
+#: controllers/addons_controller.php:182
+#: controllers/addons_controller.php:1381
+#: controllers/addons_controller.php:1455
+#: controllers/collections_controller.php:266
+#: controllers/collections_controller.php:285
+#: controllers/collections_controller.php:346
+#: controllers/collections_controller.php:443
+#: controllers/collections_controller.php:482
+#: controllers/collections_controller.php:936
+#: controllers/collections_controller.php:959
+#: controllers/collections_controller.php:960
+#: controllers/collections_controller.php:975
+#: controllers/collections_controller.php:977
+#: controllers/collections_controller.php:994
+#: controllers/collections_controller.php:1003
+#: controllers/collections_controller.php:1016
+#: controllers/collections_controller.php:1017
+#: controllers/collections_controller.php:1024
+#: controllers/collections_controller.php:1070
+#: controllers/collections_controller.php:1090
+#, php-format
+msgid "error_missing_argument"
+msgstr "Fehlender Parameter: %s"
+
+#: controllers/components/amo.php:507 controllers/components/amo.php:532
+msgid "error_no_files_in_addon"
+msgstr "Keine Dateien"
+
+#: controllers/previews_controller.php:200
+msgid "error_preview_notfound"
+msgstr "Vorschau nicht gefunden!"
+
+#: views/addons/display.thtml:400 views/reviews/add.thtml:98
+msgid "error_review_rating_required"
+msgstr "Sie müssen eine Bewertung abgeben."
+
+#: controllers/users_controller.php:160
+msgid "error_user_already_confirmed"
+msgstr "Der Benutzeraccount ist bereits bestätigt worden."
+
+#: controllers/users_controller.php:202 controllers/users_controller.php:276
+#: controllers/users_controller.php:569 controllers/users_controller.php:581
+#: controllers/users_controller.php:587 controllers/users_controller.php:610
+#: controllers/users_controller.php:627
+msgid "error_user_badconfirmationcode"
+msgstr "Falscher Bestätigungscode!"
+
+#: views/users/pwreset.thtml:79 views/users/register.thtml:75
+#: views/users/edit.thtml:183
+msgid "error_user_confirmpw_nomatch"
+msgstr "Die Passwörter stimmten nicht überein."
+
+#: views/users/register.thtml:65 views/users/edit.thtml:190
+#: controllers/users_controller.php:617
+msgid "error_user_email_notunique"
+msgstr "Diese E-Mail-Adresse ist bereits vergeben!"
+
+#: controllers/users_controller.php:596
+msgid "error_user_emailchange_expired"
+msgstr ""
+"Der Bestätigungscode für die Adressänderung ist verfallen. Bitte ändern Sie "
+"Ihre E-Mail-Adresse erneut auf Ihrer Profilseite und klicken Sie den Link in "
+"der Bestätigungsmail an, sobald Sie diese erhalten."
+
+#: controllers/collections_controller.php:985
+msgid "error_user_exists"
+msgstr ""
+"Benutzer können je nur eine Rolle innehaben. Bitte entfernen Sie den "
+"Benutzer von allen anderen Rollen bevor Sie fortfahren."
+
+#: views/users/register.thtml:91 views/users/edit.thtml:116
+#: views/admin/users_edit.thtml:88
+msgid "error_user_nickname_notunique"
+msgstr "Dieser Spitzname ist bereits vergeben."
+
+#: views/users/pwreset.thtml:54 controllers/users_controller.php:191
+#: controllers/users_controller.php:270 controllers/users_controller.php:603
+#: controllers/users_controller.php:659
+#: controllers/collections_controller.php:988
+#: controllers/collections_controller.php:998
+msgid "error_user_notfound"
+msgstr "Benutzer wurde nicht gefunden!"
+
+#: views/users/activatefirst.thtml:47
+msgid "error_user_unconfirmed"
+msgstr ""
+"Bitte bestätigen Sie Ihr Konto zuerst mit den Daten, die Sie per Mail "
+"erhalten haben."
+
+#: views/users/login.thtml:67
+msgid "error_username_or_pw_wrong"
+msgstr "Benutzername oder Passwort falsch!"
+
+#: controllers/editors_controller.php:260
+msgid "error_version_notfound"
+msgstr "Version nicht gefunden!"
+
+#: views/users/delete.thtml:125 views/users/edit.thtml:173
+msgid "error_wrong_password"
+msgstr "Falsches Passwort!"
+
+#: views/elements/amo2009/homepage_addon.thtml:122
+#: views/elements/feature.thtml:122
+msgid "feature_learnmore"
+msgstr "Mehr erfahren"
+
+#. %1 is the add-on name
+#: views/elements/amo2009/homepage_addon.thtml:123
+#: views/elements/feature.thtml:123
+#, php-format
+msgid "feature_learnmore_about_addon"
+msgstr "Erfahren Sie mehr über %1$s"
+
+#. %1$s is a number
+#: views/elements/amo2009/reviews.thtml:52
+#: views/elements/addon_listitem.thtml:112 views/elements/feature.thtml:99
+#: views/addons/browse_thumbs.thtml:86
+#, php-format
+msgid "feature_reviews"
+msgid_plural "feature_reviews"
+msgstr[0] "Eine Bewertung"
+msgstr[1] "%s Bewertungen"
+
+#: views/elements/amo2009/homepage_addon.thtml:127
+#: views/elements/feature.thtml:127
+msgid "feature_view_more_from_category"
+msgstr "Mehr aus"
+
+#. This appears on a page that views the source of an add-on. This link will return
+#. the user to the add-on's main page
+#: views/files/browse.thtml:65
+msgid "file_browser_link_addon"
+msgstr "Zurück zum Add-on"
+
+#. There is a list of directories and files on the page. Clicking this will show the
+#. contents of all the directories (normally you would click on each one to see the
+#. contents)
+#: views/files/browse.thtml:67
+msgid "file_browser_link_expand_all"
+msgstr "Alle Verzeichnisse ausklappen"
+
+#. This appears on a page that views the source of an add-on. This link will return
+#. the user to the add-on's review page (it only appears if the add-on is being
+#. reviewed)
+#: views/files/browse.thtml:64
+msgid "file_browser_link_review"
+msgstr "Zurück zur Bewertungsseite"
+
+#. The title of the page for viewing an add-on's source.
+#. %1$s is the name of the add-on
+#. %2$s is the name of the current application (e.g. Firefox or Thunderbird)
+#: views/files/browse.thtml:46
+msgid "file_browser_title"
+msgstr "%1$s :: Datei-Browser :: %2$s Add-ons"
+
+#. This appears on a page that views the source of an add-on. There is a list of
+#. directories and files on the page. Clicking this link will toggle between an
+#. expanded or a collapsed list. This string should be kept short.
+#: views/files/browse.thtml:68
+msgid "file_browser_toggle_expand_collapse"
+msgstr "+/-"
+
+#. Link text for the AMO About page.
+#: views/elements/footer.thtml:72 views/layouts/amo2009.thtml:341
+msgid "footer_a_about"
+msgstr "Ãœber Mozilla Add-ons"
+
+#. Link text to the AMO blog.
+#: views/elements/footer.thtml:74 views/layouts/amo2009.thtml:343
+msgid "footer_a_blog"
+msgstr "Blog"
+
+#. Link text to the Frequently Asked Questions page.
+#: views/elements/footer.thtml:73 views/layouts/amo2009.thtml:342
+msgid "footer_a_faq"
+msgstr "Häufige Fragen"
+
+#. Full text for the FAQ abbreviation.
+#: views/elements/footer.thtml:73 views/pages/collector_features.thtml:72
+#: views/layouts/amo2009.thtml:342
+msgid "footer_abbr_faq"
+msgstr "Häufig gestellte Fragen"
+
+#: views/elements/footer.thtml:67 views/layouts/amo2009.thtml:336
+msgid "footer_all_rights_reserved"
+msgstr "Alle Rechte vorbehalten."
+
+#: views/elements/footer.thtml:67 views/layouts/amo2009.thtml:336
+msgid "footer_copyright"
+msgstr "Copyright"
+
+#: views/elements/footer.thtml:71 views/layouts/amo2009.thtml:340
+msgid "footer_credits"
+msgstr "Danksagungen"
+
+#: views/elements/footer.thtml:76 views/layouts/amo2009.thtml:346
+msgid "footer_disclaimer"
+msgstr ""
+"Mozilla veröffentlicht Links zu diesen Anwendungen als unverbindlichen "
+"Service und macht sich weder diese noch Informationen im Bezug auf sie "
+"zueigen. Alle Fragen, Beschwerden und Ansprüche hinsichtlich dieser "
+"Anwendungen müssen direkt an den jeweiligen Hersteller gerichtet werden."
+
+#: views/elements/footer.thtml:61 views/layouts/amo2009.thtml:332
+msgid "footer_lang_form_lang_submit_go"
+msgstr "Aufrufen"
+
+#: views/elements/footer.thtml:70 views/layouts/amo2009.thtml:339
+msgid "footer_legal_notices"
+msgstr "Rechtliche Hinweise"
+
+#: views/elements/footer.thtml:50 views/layouts/amo2009.thtml:321
+msgid "footer_other_languages"
+msgstr "Andere Sprachen:"
+
+#: views/elements/footer.thtml:69 views/layouts/amo2009.thtml:338
+msgid "footer_privacy_policy"
+msgstr "Datenschutzhinweise"
+
+#: models/addontype.php:79
+msgid "general_addontype_dict"
+msgstr "Wörterbuch"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:100
+msgid "general_addontype_dict_plural"
+msgstr "Wörterbücher"
+
+#: models/addontype.php:75
+msgid "general_addontype_extension"
+msgstr "Erweiterung"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:98
+msgid "general_addontype_extension_plural"
+msgstr "Erweiterungen"
+
+#: models/addontype.php:85
+msgid "general_addontype_lpaddon"
+msgstr "Sprachpaket (Add-on)"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:103
+msgid "general_addontype_lpaddon_plural"
+msgstr "Sprachpakete (Add-on)"
+
+#: models/addontype.php:83
+msgid "general_addontype_lpapp"
+msgstr "Sprachpaket (Anwendung)"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:102
+msgid "general_addontype_lpapp_plural"
+msgstr "Sprachpakete (Anwendung)"
+
+#: models/addontype.php:87
+msgid "general_addontype_plugin"
+msgstr "Plugin"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:104
+msgid "general_addontype_plugin_plural"
+msgstr "Plugins"
+
+#: models/addontype.php:81
+msgid "general_addontype_search"
+msgstr "Suchmaschine"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:101
+msgid "general_addontype_search_plural"
+msgstr "Suchmaschinen"
+
+#: models/addontype.php:77
+msgid "general_addontype_theme"
+msgstr "Theme"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:99
+msgid "general_addontype_theme_plural"
+msgstr "Themes"
+
+#: config/language.php:367
+msgid "general_languages_all_locales"
+msgstr "Alle Sprachen"
+
+#: views/layouts/amo2009.thtml:249
+msgid "header_brand_name"
+msgstr "Mozilla"
+
+#. %1$s is the application name. Example: Firefox
+#: views/elements/header.thtml:111 views/elements/header.thtml:122
+#: views/layouts/amo2009.thtml:248
+#, php-format
+msgid "header_home_tooltip"
+msgstr "Zurück zur %1$s-Add-ons-Startseite"
+
+#: views/elements/header.thtml:87
+msgid "header_main_firefox_header"
+msgstr "Firefox-Add-ons"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:218
+msgid "header_main_firefox_header_with_logo"
+msgstr ""
+"Add-ons <em>für</em> <img alt=\"Firefox\" src=\"%1$s\" /> <strong>Firefox</"
+"strong>"
+
+#: views/elements/header.thtml:99
+msgid "header_main_header"
+msgstr "Add-ons"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:242
+msgid "header_main_header_with_logo"
+msgstr "Add-ons <img alt=\"Add-ons\" src=\"%1$s\" />"
+
+#: views/elements/header.thtml:90
+msgid "header_main_seamonkey_header"
+msgstr "SeaMonkey Add-ons"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:224
+msgid "header_main_seamonkey_header_with_logo"
+msgstr ""
+"Add-ons <em>für</em> <img alt=\"seamonkey\" src=\"%1$s\" /> "
+"<strong>SeaMonkey</strong>"
+
+#: views/elements/header.thtml:93
+msgid "header_main_sunbird_header"
+msgstr "Sunbird-Add-ons"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:230
+msgid "header_main_sunbird_header_with_logo"
+msgstr ""
+"Add-ons <em>für</em> <img alt=\"sunbird\" src=\"%1$s\" /> <strong>Sunbird</"
+"strong>"
+
+#: views/elements/header.thtml:96
+msgid "header_main_thunderbird_header"
+msgstr "Thunderbird-Add-ons"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:236
+msgid "header_main_thunderbird_header_with_logo"
+msgstr ""
+"Add-ons <em>für</em> <img alt=\"thunderbird\" src=\"%1$s\" /> "
+"<strong>Thunderbird</strong>"
+
+#: views/layouts/amo2009.thtml:205
+msgid "header_navaccess_applications_menu"
+msgstr "Zum \"Andere Anwendungen\"-Menü springen"
+
+#: views/layouts/amo2009.thtml:204
+msgid "header_navaccess_categories_menu"
+msgstr "Zum \"Kategorien\"-Menü springen"
+
+#: views/layouts/amo2009.thtml:202
+msgid "header_navaccess_main_content"
+msgstr "Zum Inhalt springen"
+
+#: views/layouts/amo2009.thtml:203
+msgid "header_navaccess_search_form"
+msgstr "Zum Suchfeld springen"
+
+#: views/elements/header.thtml:62
+msgid "header_navlink_addons"
+msgstr "Add-ons"
+
+#: views/elements/developers/sidebar.thtml:72
+#: views/elements/developers/myaddons.thtml:50 views/elements/header.thtml:159
+#: views/addons/display.thtml:378
+msgid "header_navlink_login"
+msgstr "Einloggen"
+
+#: views/elements/header.thtml:156 views/layouts/amo2009.thtml:304
+msgid "header_navlink_logout"
+msgstr "Ausloggen"
+
+#: views/elements/header.thtml:145 views/layouts/amo2009.thtml:303
+msgid "header_navlink_myaccount"
+msgstr "Mein Konto"
+
+#: views/elements/header.thtml:158
+msgid "header_navlink_register"
+msgstr "Neu anmelden"
+
+#. %1 is the URL to the registration page
+#. %2 is the URL to the login page
+#: views/layouts/amo2009.thtml:278
+msgid "header_navlink_register_or_login"
+msgstr ""
+"<a href=\"%1$s\">Registrieren Sie ich</a> oder <a href=\"%2$s\">loggen Sie "
+"sich ein</a>"
+
+#: views/layouts/amo2009.thtml:285
+msgid "header_navlink_tools"
+msgstr "Werkzeuge"
+
+#. %s is the add-on name
+#: views/elements/collections_interactive_addon.thtml:62
+#: views/elements/amo2009/homepage_addon.thtml:77
+#: views/elements/addon_discussionheader.thtml:62
+#: views/elements/addon_listitem.thtml:67 views/elements/feature.thtml:84
+#: views/addons/category_landing.thtml:87 views/addons/browse_thumbs.thtml:60
+#, php-format
+msgid "img_preview_of"
+msgstr "Vorschaubild von %s"
+
+#. %1 is the login URL for the link tag
+#. %2 is the link to an explanatory page.
+#: views/elements/amo2009/install.thtml:307 views/elements/install.thtml:255
+msgid "install_a_login_to_install"
+msgstr ""
+"<a href=\"%1$s\">Einloggen</a> zum Installieren. <a href=\"%2$s\">Warum?</a>"
+
+#. %1 is the URL for the Experimental Add-ons section of the FAQ page
+#: views/elements/amo2009/install.thtml:283 views/elements/install.thtml:232
+msgid "install_button_confirm_exp_install"
+msgstr ""
+"Lassen Sie mich dieses experimentelle Add-on installieren <a href=\"%1$s"
+"\">Was bedeutet das?</a>"
+
+#. %1$s is the application name. Example: Firefox
+#. %2$s is an optional string used to specify a platform. Example: (Windows)
+#: views/elements/amo2009/install.thtml:128 views/elements/install.thtml:75
+#, php-format
+msgid "install_button_text"
+msgstr "Zu %s %s hinzufügen"
+
+#. %1 is the add-on name, %2 is the app name
+#: views/elements/amo2009/install.thtml:191
+#: views/elements/amo2009/install.thtml:206
+#: views/elements/amo2009/install.thtml:249
+#: views/elements/amo2009/install.thtml:298 views/elements/install.thtml:150
+#: views/elements/install.thtml:165 views/elements/install.thtml:202
+#: views/elements/install.thtml:246
+#, php-format
+msgid "install_button_title"
+msgstr "%1$s zu %2$s hinzufügen"
+
+#. %1$s is the add-on name
+#: views/elements/amo2009/install.thtml:200 views/elements/install.thtml:159
+#, php-format
+msgid "install_download"
+msgstr "%1$s herunterladen"
+
+#: views/elements/amo2009/install.thtml:147 views/elements/install.thtml:94
+msgid "install_error_addon_not_found"
+msgstr "Add-on nicht gefunden!"
+
+#: views/addons/dictionaries.thtml:65
+msgid "langtools_a11y_tablesummary"
+msgstr "Liste von Wörterbüchern und Sprachpaketen."
+
+#: views/addons/dictionaries.thtml:47
+msgid "langtools_download_dictionary"
+msgstr "Wörterbuch herunterladen"
+
+#: views/addons/dictionaries.thtml:48
+msgid "langtools_download_langpack"
+msgstr "Sprachpaket herunterladen"
+
+#: views/addons/dictionaries.thtml:63 controllers/components/amo.php:685
+#: controllers/addons_controller.php:1239
+msgid "langtools_header_dicts_and_langpacks"
+msgstr "Wörterbücher und Sprachpakete"
+
+#: views/addons/dictionaries.thtml:44
+msgid "langtools_install_dictionary"
+msgstr "Wörterbuch installieren"
+
+#: views/addons/dictionaries.thtml:45
+msgid "langtools_install_langpack"
+msgstr "Sprachpaket installieren"
+
+#: views/addons/dictionaries.thtml:69
+msgid "langtools_tableheader_dictionary"
+msgstr "Wörterbuch"
+
+#: views/addons/dictionaries.thtml:70
+msgid "langtools_tableheader_langpack"
+msgstr "Sprachpaket"
+
+#: views/addons/dictionaries.thtml:68
+msgid "langtools_tableheader_language"
+msgstr "Sprache"
+
+#: models/license.php:65
+msgid "license_custom"
+msgstr "Benutzerdefinierte Lizenz"
+
+#: config/bootstrap.php:303
+msgid "licenses_bsd"
+msgstr "BSD-Lizenz"
+
+#: config/bootstrap.php:298
+msgid "licenses_gpl_2.0"
+msgstr "GNU General Public License, Version 2.0"
+
+#: config/bootstrap.php:299
+msgid "licenses_gpl_3.0"
+msgstr "GNU General Public License, Version 3.0"
+
+#: config/bootstrap.php:300
+msgid "licenses_lgpl_2.1"
+msgstr "GNU Lesser General Public License, Version 2.1"
+
+#: config/bootstrap.php:301
+msgid "licenses_lgpl_3.0"
+msgstr "GNU Lesser General Public License, Version 3.0"
+
+#: config/bootstrap.php:302
+msgid "licenses_mit"
+msgstr "MIT/X11-Lizenz"
+
+#: config/bootstrap.php:297
+msgid "licenses_mpl_1.1"
+msgstr "Mozilla Public License, Version 1.1"
+
+#: views/users/emailchange.thtml:51 views/users/delete.thtml:55
+#: views/users/delete.thtml:137 views/users/edit.thtml:74
+#: views/reviews/flag.thtml:54
+msgid "link_return_to_front_page"
+msgstr "Klicken Sie hier, um zur Hauptseite zurückzukehren."
+
+#: views/elements/amo2009/addon_list_options.thtml:46
+#: views/elements/addon_list_options.thtml:46
+msgid "list_sortby_date"
+msgstr "Datum"
+
+#: views/elements/amo2009/addon_list_options.thtml:47
+#: views/elements/addon_list_options.thtml:47
+msgid "list_sortby_downloads"
+msgstr "Downloads"
+
+#: views/elements/amo2009/addon_list_options.thtml:45
+#: views/elements/addon_list_options.thtml:45
+msgid "list_sortby_name"
+msgstr "Add-on-Name"
+
+#: views/elements/amo2009/addon_list_options.thtml:48
+#: views/elements/addon_list_options.thtml:48
+msgid "list_sortby_rating"
+msgstr "Bewertung"
+
+#: config/bootstrap.php:278
+msgid "main_prettyname_fennec"
+msgstr "Fennec"
+
+#: config/bootstrap.php:274
+msgid "main_prettyname_firefox"
+msgstr "Firefox"
+
+#: config/bootstrap.php:277
+msgid "main_prettyname_seamonkey"
+msgstr "SeaMonkey"
+
+#: config/bootstrap.php:276
+msgid "main_prettyname_sunbird"
+msgstr "Sunbird"
+
+#: config/bootstrap.php:275
+msgid "main_prettyname_thunderbird"
+msgstr "Thunderbird"
+
+#: views/elements/addon_categories.thtml:52
+msgid "nav_category_dicts_langpacks"
+msgstr "Wörterbücher & Sprachpakete"
+
+#: views/elements/addon_categories.thtml:55
+msgid "nav_category_themes"
+msgstr "Themes"
+
+#: views/elements/app_chooser.thtml:47 views/layouts/amo2009.thtml:255
+msgid "other_apps_tooltip"
+msgstr "Add-ons für andere Anwendungen finden"
+
+#. In a user list: user 1, user 2, "others"
+#: views/helpers/addons_html.php:222
+msgid "other_users"
+msgstr "andere"
+
+#: controllers/pages_controller.php:90
+msgid "page_title_appversions"
+msgstr "Anwendungs-Versionen"
+
+#: controllers/pages_controller.php:115
+msgid "page_title_collector"
+msgstr "Add-on-Sammler"
+
+#: controllers/pages_controller.php:117
+msgid "page_title_collector_faq"
+msgstr "Häufige Fragen zum Add-on-Sammler"
+
+#: controllers/pages_controller.php:119
+msgid "page_title_collector_features"
+msgstr "Fähigkeiten des Add-on-Sammlers"
+
+#: controllers/pages_controller.php:122
+msgid "page_title_collector_firstrun"
+msgstr "Willkommen beim Add-on-Sammler"
+
+#: controllers/pages_controller.php:92
+msgid "page_title_credits"
+msgstr "Danksagungen"
+
+#: controllers/pages_controller.php:113
+msgid "page_title_developer_faq"
+msgstr "Entwickler-FAQ"
+
+#: controllers/pages_controller.php:111
+msgid "page_title_faq"
+msgstr "Häufig gestellte Fragen"
+
+#: controllers/pages_controller.php:94
+msgid "page_title_fashionyourfirefox_faq"
+msgstr "Fashion your Firefox: Häufige Fragen"
+
+#: controllers/pages_controller.php:101
+msgid "page_title_policy"
+msgstr "Add-ons-Richtlinien"
+
+#: controllers/pages_controller.php:103
+msgid "page_title_privacy"
+msgstr "Datenschutzhinweise"
+
+#: controllers/pages_controller.php:105
+msgid "page_title_review_guide"
+msgstr "Bewertungs-Richtlinien"
+
+#: controllers/pages_controller.php:107
+msgid "page_title_sandbox"
+msgstr "Das \"Sandkasten\"-System"
+
+#: controllers/pages_controller.php:109
+msgid "page_title_submissionhelp"
+msgstr "Hilfe beim Hochladen"
+
+#: views/pages/appversions.thtml:87
+msgid "pages_appversions_guid"
+msgstr "GUID"
+
+#: views/pages/appversions.thtml:79 controllers/pages_controller.php:90
+msgid "pages_appversions_header"
+msgstr "Gültige Anwendungsversionen"
+
+#: views/pages/appversions.thtml:80
+msgid "pages_appversions_intro"
+msgstr ""
+"An Mozilla Add-ons übermittelte Add-ons müssen die Datei install.rdf "
+"besitzen, welche mindestens eine der folgenden Anwendungen zu unterstützen "
+"hat. Nur die aufgelisteten Versionen der Anwendungen sind erlaubt."
+
+#. %s is a full <a> tag
+#: views/pages/appversions.thtml:93
+#, php-format
+msgid "pages_appversions_required_files"
+msgstr ""
+"Falls die von Ihnen unterstützte Anwendung keine install.rdf verlangt, so "
+"müssen Sie trotzdem diese mit den %s erklärten Eigenschaften hinzufügen."
+
+#. this is the text inside of an <a> tag for pages_appversions_required_files. This
+#. should be fixed.
+#: views/pages/appversions.thtml:93
+msgid "pages_appversions_required_files_link"
+msgstr "hier"
+
+#: views/pages/appversions.thtml:88
+msgid "pages_appversions_versions"
+msgstr "Versionen"
+
+#: views/pages/policy.thtml:51
+msgid "pages_policy_sandbox_link"
+msgstr "Der Sandkasten - Wissenswertes"
+
+#: views/elements/pagination.thtml:53
+msgid "pagination_next_page"
+msgstr "nächste Seite"
+
+#: views/elements/pagination.thtml:52
+msgid "pagination_previous_page"
+msgstr "vorige Seite"
+
+#: views/elements/recaptcha.thtml:65
+msgid "recaptcha_enter_both_words"
+msgstr ""
+"Bitte geben Sie <strong>beide Worte</strong> ein, <strong>getrennt durch ein "
+"Leerzeichen</strong>."
+
+#: views/elements/recaptcha.thtml:83
+msgid "recaptcha_enter_here"
+msgstr "Geben Sie Ihre Antwort hier ein:"
+
+#: views/elements/recaptcha.thtml:74
+msgid "recaptcha_enter_whatyouhear"
+msgstr "Bitte geben Sie ein, was Sie hören."
+
+#. %1 is the link switching refreshing the captcha
+#. %2 is the link switching to a text captcha
+#: views/elements/recaptcha.thtml:77
+msgid "recaptcha_hardtohear_text"
+msgstr ""
+"Falls dies schwer zu verstehen ist, können Sie <a href=\"%1$s\">etwas "
+"anderes anhören</a> oder <a href=\"%2$s\">zurück zu einer Text-Abfrage "
+"wechseln</a>."
+
+#. %1 is the link switching refreshing the captcha
+#. %2 is the link switching to an audio captcha
+#: views/elements/recaptcha.thtml:68
+msgid "recaptcha_hardtoread_text"
+msgstr ""
+"Falls dies schwer zu lesen ist, können Sie sich <a href=\"%1$s\">andere "
+"Wörter anzeigen lassen</a> oder sich stattdessen <a href=\"%2$s\">etwas "
+"ansagen lassen</a>."
+
+#: views/users/register.thtml:105
+msgid "recaptcha_label"
+msgstr "Sind Sie ein Mensch?"
+
+#: views/users/register.thtml:106
+msgid "recaptcha_whatsthis"
+msgstr "Was ist das?"
+
+#: controllers/reviews_controller.php:559
+msgid "review_flag_error"
+msgstr "Fehler beim Markieren dieser Bewertung!"
+
+#: models/reviews_moderation_flag.php:69
+msgid "review_flag_reason_bug_support"
+msgstr "Unpassender Fehlerbericht, oder Unterstützungs-Anfrage"
+
+#: views/reviews/display.thtml:103 views/reviews/display.thtml:186
+msgid "review_flag_reason_instructions"
+msgstr "Diese Bewertung als unpassend melden (wählen Sie eine Begründung aus)"
+
+#: models/reviews_moderation_flag.php:67
+msgid "review_flag_reason_language"
+msgstr "Unpassende Wortwahl"
+
+#: models/reviews_moderation_flag.php:71
+msgid "review_flag_reason_other"
+msgstr "Anderes (bitte eine Begründung angeben)"
+
+#: models/reviews_moderation_flag.php:65
+msgid "review_flag_reason_spam"
+msgstr "Spam oder anderweitiger Inhalt, der keine Bewertung ist"
+
+#: views/reviews/display.thtml:91 views/reviews/display.thtml:175
+#: controllers/reviews_controller.php:555
+msgid "review_flag_success"
+msgstr "Danke; diese Bewertung wurde zur Moderation markiert."
+
+#: views/reviews/display.thtml:41
+msgid "review_flag_this"
+msgstr "Diese Bewertung als unpassend markieren"
+
+#: views/reviews/display.thtml:42
+msgid "review_flag_this_titletip"
+msgstr ""
+"Ist diese Bewertung unpassend, ungenau oder Spam? Klicken Sie hier, um sie "
+"zur Überprüfung durch einen Moderator zu markieren."
+
+#. %1 is the URL of the support section, %2 for the review guidelines
+#: views/reviews/add.thtml:53
+msgid "review_guidelines_short"
+msgstr ""
+"<p>Bitte achten Sie auf folgendes:</p><ul><li>Schreiben Sie so, als würden "
+"Sie einem Freund von Ihrer Erfahrung mit dem Add-on erzählen. Machen Sie "
+"genaue Angaben und erläutern Sie hilfreiche Details, zum Beispiel welche "
+"Eigenschaften ihnen gefallen oder nicht gefallen haben, wie einfach es zu "
+"verwenden war und welche Nachteile es hat. Vermeiden Sie allgemeine Floskeln "
+"wie zum Beispiel ein simples \"großartig\" oder \"schlecht\", es sei denn "
+"Sie nennen Gründe, warum Sie dieser Meinung sind.</li><li>Bitte schreiben "
+"Sie keine Fehlerberichte als Bewertung. Wir geben Ihre E-Mail-Adresse nicht "
+"an die Add-on-Entwickler weiter, aber diese könnten Kontakt mit Ihnen "
+"aufnehmen müssen, um Ihnen bei der Behebung des Problems zu helfen. Bitte "
+"sehen Sie sich den Abschnitt <a href=\"%1$s\">\"Hilfe\"</a> an, um "
+"herauszufinden, wo Sie Unterstützung für dieses Add-on erhalten können.</"
+"li><li>Bitte halten Sie Ihre Bewertungen \"sauber\": Verwenden Sie keine "
+"unangemessene Sprache, und veröffentlichen Sie keine persönlichen Daten.</"
+"li></ul><p>Bitte lesen Sie die <a href=\"%2$s\">Richtlinien für Bewertungen</"
+"a> für genauere Informationen über Add-on-Bewertungen von Benutzern.</p>"
+
+#. %1 is the add-on name
+#: views/reviews/flag.thtml:56 views/reviews/display.thtml:55
+#: views/reviews/review_added.thtml:50
+#, php-format
+msgid "reviews_header"
+msgstr "Bewertungen für %s"
+
+#: controllers/addons_controller.php:435
+msgid "rss_featuredaddons"
+msgstr "Empfohlene Add-ons"
+
+#: controllers/addons_controller.php:432
+msgid "rss_newestaddons"
+msgstr "Die neuesten Add-ons"
+
+#: controllers/addons_controller.php:434
+msgid "rss_popularaddons"
+msgstr "Beliebte Add-ons"
+
+#: controllers/addons_controller.php:433
+msgid "rss_updatedaddons"
+msgstr "Aktualisierte Add-ons"
+
+#: views/elements/search_mini.thtml:70
+msgid "search"
+msgstr "Suchen"
+
+#: views/search/collections.thtml:51
+msgid "search_collections_header"
+msgstr "Sammlungen: Suchergebnisse"
+
+#: controllers/search_controller.php:297
+msgid "search_collections_pagetitle"
+msgstr "Sammlungen: Suchergebnisse"
+
+#: controllers/search_controller.php:99
+msgid "search_disabled"
+msgstr ""
+"Die Suche ist momentan deaktiviert. Bitte versuchen Sie es später noch "
+"einmal."
+
+#: views/elements/amo2009/search.thtml:188 views/elements/search.thtml:187
+#: views/elements/search_mini.thtml:54
+msgid "search_form_all_addons"
+msgstr "Alle Add-ons"
+
+#. This string is in the main category dropdown when searching
+#: views/elements/amo2009/search.thtml:204
+msgid "search_form_all_collections"
+msgstr "Alle Sammlungen"
+
+#: views/elements/amo2009/search.thtml:184
+#: views/elements/amo2009/search.thtml:385
+#: views/elements/amo2009/search.thtml:408 views/elements/search.thtml:171
+#: views/elements/search.thtml:183 views/elements/search_mini.thtml:43
+#: views/elements/search_mini.thtml:49 views/layouts/mozilla.thtml:188
+msgid "search_form_default_text"
+msgstr "Suche nach Add-ons"
+
+#: views/elements/amo2009/search.thtml:184
+#: views/elements/amo2009/search.thtml:404
+msgid "search_form_default_text_collections"
+msgstr "nach Sammlungen suchen"
+
+#: views/elements/amo2009/search.thtml:206 views/elements/search.thtml:202
+msgid "search_form_submit_tooltip"
+msgstr "Nach Add-ons suchen"
+
+#: views/elements/amo2009/search.thtml:184 views/elements/search.thtml:183
+#: views/elements/search_mini.thtml:49
+msgid "search_form_tooltip"
+msgstr "Klicken Sie hier, um Suchbegriffe einzugeben"
+
+#: views/elements/amo2009/search.thtml:186 views/elements/search.thtml:185
+#: views/elements/search_mini.thtml:52
+msgid "search_form_within"
+msgstr "in"
+
+#: views/addons/searchengines.thtml:118
+msgid "search_landing_all_search_engines"
+msgstr "Alle Suchmaschinen"
+
+#: views/addons/searchengines.thtml:114
+msgid "search_landing_browse_search_engines"
+msgstr "Alle Suchmaschinen durchsuchen"
+
+#: views/search/collections.thtml:58 views/search/index.thtml:59
+msgid "search_nothing_found"
+msgstr "Es wurde nichts gefunden."
+
+#: controllers/search_controller.php:185
+msgid "search_pagetitle"
+msgstr "Add-on-Suche"
+
+#: controllers/search_controller.php:242
+msgid "search_rss_description"
+msgstr "Die aktuellen Suchergebnisse für Ihre Anfrage als RSS-Feed"
+
+#. %s is the terms the user is searching for (a string)
+#: controllers/search_controller.php:241
+#, php-format
+msgid "search_rss_results_for"
+msgstr "Suchergebnisse für: %s"
+
+#: views/elements/header.thtml:154 views/layouts/amo2009.thtml:296
+msgid "sidebar_navlink_admin_tools"
+msgstr "Administration"
+
+#: views/elements/header.thtml:146 views/layouts/amo2009.thtml:288
+msgid "sidebar_navlink_developer_tools"
+msgstr "Entwickler"
+
+#: views/elements/header.thtml:148 views/layouts/amo2009.thtml:290
+msgid "sidebar_navlink_editor_tools"
+msgstr "Moderatoren"
+
+#: views/layouts/amo2009.thtml:302
+msgid "sidebar_navlink_welcome"
+msgstr "Herzlich Willkommen"
+
+#. %s is the user's name
+#: views/layouts/amo2009.thtml:302
+#, php-format
+msgid "sidebar_navlink_welcome_name"
+msgstr "Herzlich Willkommen, %s"
+
+#: views/elements/pitch.thtml:50 views/elements/pitch.thtml:55
+msgid "sidebar_pitch_dictionary"
+msgstr "Wörterbüchern"
+
+#: views/elements/pitch.thtml:72
+msgid "sidebar_pitch_featured_addons"
+msgstr "Empfohlene Add-ons"
+
+#: views/elements/pitch.thtml:61
+msgid "sidebar_pitch_looking_for"
+msgstr "Ich bin auf der Suche nach:"
+
+#: views/elements/pitch.thtml:70
+msgid "sidebar_pitch_newest_addons"
+msgstr "Neueste Add-ons"
+
+#: views/elements/pitch.thtml:49
+msgid "sidebar_pitch_search"
+msgstr "Suchmaschinen"
+
+#: views/elements/pitch.thtml:69
+msgid "sidebar_pitch_subscribe_to"
+msgstr "RSS-Feeds abonnieren:"
+
+#: views/elements/pitch.thtml:48 views/elements/pitch.thtml:54
+msgid "sidebar_pitch_theme"
+msgstr "Themes"
+
+#: views/elements/pitch.thtml:71
+msgid "sidebar_pitch_updated_addons"
+msgstr "Aktualisierte Add-ons"
+
+#. %1$s is a number
+#: views/helpers/localization.php:65 views/developers/versions_edit.thtml:95
+#: views/addons/dictionaries.thtml:92
+#, php-format
+msgid "size_kb"
+msgstr "%1$s KB"
+
+#: views/elements/amo2009/stars.thtml:57 views/elements/stars.thtml:63
+msgid "stars_not_yet_rated"
+msgstr "Noch nicht bewertet"
+
+#. %1 is the number of stars this add-on has
+#: views/elements/amo2009/stars.thtml:49 views/elements/stars.thtml:54
+#, php-format
+msgid "stars_rated_x_outof_5"
+msgstr "Mit %s von 5 Sternen bewertet"
+
+#: views/statistics/addon.thtml:59
+msgid "statistics_addon_dashboard_link"
+msgstr "Statistische Auswertung"
+
+#: views/statistics/addon.thtml:58
+msgid "statistics_addon_developertools_link"
+msgstr "Entwickler"
+
+#: views/statistics/addon.thtml:53
+msgid "statistics_addon_switch"
+msgstr "Add-on wechseln"
+
+#. This is a date format.
+#. http://php.net/strftime
+#: views/statistics/rss/summary.thtml:54 views/statistics/addon.thtml:181
+msgid "statistics_date_shortmonth"
+msgstr "%e. %b."
+
+#. This is a date format.
+#. http://php.net/strftime
+#: views/statistics/rss/summary.thtml:40 views/statistics/addon.thtml:152
+msgid "statistics_date_shortmonthwithyear"
+msgstr "%e. %b. %Y"
+
+#. This is a date format.
+#. http://php.net/strftime
+#: views/statistics/rss/summary.thtml:41 views/statistics/rss/summary.thtml:48
+#: views/statistics/addon.thtml:161 views/statistics/addon.thtml:172
+msgid "statistics_date_weekdayshortmonth"
+msgstr "%A, %e. %b."
+
+#. %1$s is an add-on name and version. Example: Add-on 3.5
+#: controllers/components/stats.php:519
+#, php-format
+msgid "statistics_events_addon_created"
+msgstr "%1$s erstellt"
+
+#. %1$s is an application name and version. Example: Firefox 3.5
+#: controllers/components/stats.php:500
+#, php-format
+msgid "statistics_events_app_released"
+msgstr "%1$s veröffentlicht"
+
+#: views/statistics/addon.thtml:71
+msgid "statistics_help_close_link"
+msgstr "Schließen"
+
+#: views/statistics/addon.thtml:60
+msgid "statistics_help_link"
+msgstr "Hilfe"
+
+#: views/statistics/index.thtml:83
+msgid "statistics_index_anotheraddon"
+msgstr "oder wählen Sie ein anderes Add-on"
+
+#: views/statistics/index.thtml:85
+msgid "statistics_index_anotheraddon_public"
+msgstr "oder wählen Sie ein Add-on mit öffentlicher statistischer Auswertung"
+
+#: views/statistics/index.thtml:71
+msgid "statistics_index_myaddons"
+msgstr ""
+"Wählen Sie eines Ihrer Add-ons, um die zugehörigen Statistiken zu sehen"
+
+#: views/statistics/index.thtml:89
+msgid "statistics_index_selectaddon"
+msgstr "Wählen Sie ein Add-on, um seine Statistiken zu sehen"
+
+#: views/statistics/index.thtml:91
+msgid "statistics_index_selectaddon_public"
+msgstr "Wählen Sie ein Add-on mit öffentlichen Statistiken"
+
+#: views/statistics/index.thtml:39
+msgid "statistics_index_title"
+msgstr "Statistische Auswertung"
+
+#: views/statistics/index.thtml:97
+msgid "statistics_index_view_button"
+msgstr "Statistiken anzeigen"
+
+#: views/statistics/addon.thtml:222 controllers/statistics_controller.php:247
+msgid "statistics_js_download_csv"
+msgstr "Diese Tabelle im CSV-Format anzeigen"
+
+#: controllers/statistics_controller.php:246
+msgid "statistics_js_dropdowns_none"
+msgstr "keine"
+
+#: controllers/statistics_controller.php:245
+msgid "statistics_js_dropdowns_removeplot"
+msgstr "Diesen Graph entfernen"
+
+#: controllers/statistics_controller.php:248
+msgid "statistics_js_groupby_selector_date"
+msgstr "Gruppieren nach: Tag"
+
+#: controllers/statistics_controller.php:251
+msgid "statistics_js_groupby_selector_month"
+msgstr "Gruppieren nach: Monat"
+
+#: controllers/statistics_controller.php:249
+msgid "statistics_js_groupby_selector_week"
+msgstr "Gruppieren nach: Woche"
+
+#: controllers/statistics_controller.php:250
+msgid "statistics_js_groupby_selector_week_over_week"
+msgstr "Vergleichen nach: Woche"
+
+#: controllers/statistics_controller.php:260
+msgid "statistics_js_plotselection_foundinrange"
+msgstr "%s im Bereich gefunden"
+
+#: controllers/statistics_controller.php:270
+msgid "statistics_js_plotselection_options_addplot_name"
+msgstr "Graph hinzufügen"
+
+#: controllers/statistics_controller.php:271
+msgid "statistics_js_plotselection_options_addplot_tooltip"
+msgstr "Weiteren Graph zur Grafik hinzufügen"
+
+#: controllers/statistics_controller.php:261
+msgid "statistics_js_plotselection_options_count_name_checked"
+msgstr "Gesamtzahl ausblenden"
+
+#: controllers/statistics_controller.php:262
+msgid "statistics_js_plotselection_options_count_name_unchecked"
+msgstr "Gesamtzahl anzeigen"
+
+#: controllers/statistics_controller.php:263
+msgid "statistics_js_plotselection_options_count_tooltip"
+msgstr "Gesamtzahl hier aufzeichnen"
+
+#: controllers/statistics_controller.php:275
+msgid "statistics_js_plotselection_options_csv_name"
+msgstr "Daten anzeigen (CSV)"
+
+#: controllers/statistics_controller.php:276
+msgid "statistics_js_plotselection_options_csv_tooltip"
+msgstr "Zeigt eine kommaseparierte Liste dieser Daten"
+
+#: controllers/statistics_controller.php:267
+msgid "statistics_js_plotselection_options_events_addon_name_checked"
+msgstr "%s-Ereignisse ausblenden"
+
+#: controllers/statistics_controller.php:268
+msgid "statistics_js_plotselection_options_events_addon_name_unchecked"
+msgstr "%s-Ereignisse anzeigen"
+
+#: controllers/statistics_controller.php:269
+msgid "statistics_js_plotselection_options_events_addon_tooltip"
+msgstr "Veröffentlichungsdaten des Add-ons in den Grafiken anzeigen"
+
+#: controllers/statistics_controller.php:264
+msgid "statistics_js_plotselection_options_events_firefox_name_checked"
+msgstr "Firefox-Ereignisse ausblenden"
+
+#: controllers/statistics_controller.php:265
+msgid "statistics_js_plotselection_options_events_firefox_name_unchecked"
+msgstr "Firefox-Ereignisse anzeigen"
+
+#: controllers/statistics_controller.php:266
+msgid "statistics_js_plotselection_options_events_firefox_tooltip"
+msgstr "Veröffentlichungsdaten von Firefox in den Grafiken anzeigen"
+
+#: controllers/statistics_controller.php:272
+msgid "statistics_js_plotselection_options_resize_name_checked"
+msgstr "Grafik verkleinern"
+
+#: controllers/statistics_controller.php:273
+msgid "statistics_js_plotselection_options_resize_name_unchecked"
+msgstr "Grafik erweitern"
+
+#: controllers/statistics_controller.php:274
+msgid "statistics_js_plotselection_options_resize_tooltip"
+msgstr "Größe der Grafik ändern"
+
+#: controllers/statistics_controller.php:254
+msgid "statistics_js_plotselection_selector_adu"
+msgstr "Tägliche Nutzer"
+
+#: controllers/statistics_controller.php:256
+msgid "statistics_js_plotselection_selector_application"
+msgstr "Anwendung"
+
+#: controllers/statistics_controller.php:259
+msgid "statistics_js_plotselection_selector_custom"
+msgstr "Benutzerdefiniert"
+
+#: controllers/statistics_controller.php:253
+msgid "statistics_js_plotselection_selector_downloads"
+msgstr "Downloads"
+
+#: controllers/statistics_controller.php:258
+msgid "statistics_js_plotselection_selector_os"
+msgstr "Betriebssystem"
+
+#: controllers/statistics_controller.php:257
+msgid "statistics_js_plotselection_selector_status"
+msgstr "Status des Add-on"
+
+#: controllers/statistics_controller.php:252
+msgid "statistics_js_plotselection_selector_summary"
+msgstr "Zusammenfassung"
+
+#: controllers/statistics_controller.php:255
+msgid "statistics_js_plotselection_selector_version"
+msgstr "Version des Add-ons"
+
+#: controllers/components/stats.php:398
+msgid "statistics_longnames_application"
+msgstr "Anwendung"
+
+#: controllers/components/stats.php:400
+msgid "statistics_longnames_os"
+msgstr "Betriebssystem"
+
+#: controllers/components/stats.php:399
+msgid "statistics_longnames_status"
+msgstr "Status des Add-ons"
+
+#: controllers/components/stats.php:401
+msgid "statistics_longnames_unknown"
+msgstr "Unbekannt"
+
+#: controllers/components/stats.php:397
+msgid "statistics_longnames_version"
+msgstr "Version des Add-ons"
+
+#: views/statistics/addon.thtml:118
+msgid "statistics_notice_data_insufficient"
+msgstr ""
+"Momemtan liegen nicht genügend Daten für die Generierung dieser Grafik vor. "
+"Bitte versuchen Sie es später noch einmal."
+
+#: views/statistics/addon.thtml:130
+msgid "statistics_notice_data_none"
+msgstr ""
+"Wir verfügen noch nicht über Daten für Ihr Add-on. Bitte versuchen Sie es in "
+"einigen Tagen noch einmal."
+
+#: views/statistics/addon.thtml:41
+msgid "statistics_notice_data_updating"
+msgstr ""
+"Die Statistiken für Add-ons werden momentan aktualisiert, sodass die "
+"derzeitigen Daten unvollständig sein können. Bitte versuchen Sie es in ein "
+"paar Minuten noch einmal."
+
+#: views/statistics/addon.thtml:136
+msgid "statistics_notice_disabled"
+msgstr ""
+"Die statistische Auswertung ist momentan deaktiviert. Bitte versuchen Sie es "
+"später noch einmal."
+
+#: views/statistics/addon.thtml:123
+msgid "statistics_notice_nojavascript"
+msgstr "Für die statistische Auswertung wird JavaScript benötigt."
+
+#: views/statistics/addon.thtml:44
+msgid "statistics_notice_settings_updated"
+msgstr "Ihre Einstellungen wurden aktualisiert."
+
+#: controllers/statistics_controller.php:60
+#: controllers/statistics_controller.php:71
+#: controllers/statistics_controller.php:74
+#: controllers/statistics_controller.php:240
+msgid "statistics_pagetitle"
+msgstr "Statistische Auswertung"
+
+#: views/statistics/addon.thtml:99
+msgid "statistics_plot_legend_adu"
+msgstr "Tägliche Nutzer"
+
+#: views/statistics/addon.thtml:95
+msgid "statistics_plot_legend_downloads"
+msgstr "Tägliche Downloads"
+
+#: views/statistics/addon.thtml:107
+msgid "statistics_plot_options_zoomin_alt"
+msgstr "Hineinzoomen"
+
+#: views/statistics/addon.thtml:106
+msgid "statistics_plot_options_zoomin_title"
+msgstr "Um einen Monat hereinzommen"
+
+#: views/statistics/addon.thtml:110
+msgid "statistics_plot_options_zoomout_alt"
+msgstr "Herauszoomen"
+
+#: views/statistics/addon.thtml:109
+msgid "statistics_plot_options_zoomout_title"
+msgstr "Um einen Monat herauszoomen"
+
+#: controllers/statistics_controller.php:283
+#, php-format
+msgid "statistics_rss_description"
+msgstr "Tägliche Zusammenfassung der Statistiken für %1$s"
+
+#: views/statistics/rss/summary.thtml:68
+msgid "statistics_rss_title_fulldate"
+msgstr "%A, %e. %b. %Y"
+
+#: views/statistics/rss/summary.thtml:68
+#, php-format
+msgid "statistics_rss_title_statsfordate"
+msgstr "Statistiken für %1$s"
+
+#: views/statistics/settings.thtml:49
+msgid "statistics_settings_access_description"
+msgstr ""
+"Standardmäßig sind nur Sie und Mozilla dazu in berechtigt, Ihre Add-on-"
+"Statistiken zu betrachten. Sie können die Daten aber auch für die "
+"Öffentlichkeit freigeben, sodass jedermann die statistischen Daten Ihres Add-"
+"ons betrachten kann."
+
+#: views/statistics/settings.thtml:48
+msgid "statistics_settings_access_heading"
+msgstr "Zugangsberechtigung für die statische Auswertung"
+
+#: views/statistics/settings.thtml:51
+msgid "statistics_settings_access_private"
+msgstr "Privat"
+
+#: views/statistics/settings.thtml:51
+msgid "statistics_settings_access_private_description"
+msgstr "Nur Sie und Mozilla können auf die Add-on-Statistiken zugreifen"
+
+#: views/statistics/settings.thtml:52
+msgid "statistics_settings_access_public"
+msgstr "Öffentlich"
+
+#: views/statistics/settings.thtml:52
+msgid "statistics_settings_access_public_description"
+msgstr "Jeder kann auf die Add-on-Statistiken zugreifen"
+
+#: views/statistics/addon.thtml:251
+msgid "statistics_settings_change_link"
+msgstr "Einstellungen ändern"
+
+#: views/statistics/addon.thtml:253
+msgid "statistics_settings_confidential"
+msgstr "Bitte beachten Sie diese Einstellung als vertraulich"
+
+#: views/statistics/addon.thtml:245
+msgid "statistics_settings_currently_private"
+msgstr "Die Statistiken sind derzeit <b>privat</b>."
+
+#: views/statistics/addon.thtml:241
+msgid "statistics_settings_currently_public"
+msgstr "Die Statistiken sind derzeit <b>öffentlich</b>."
+
+#: views/statistics/addon.thtml:246
+msgid "statistics_settings_locked_alt"
+msgstr "privat"
+
+#: views/statistics/settings.thtml:57
+msgid "statistics_settings_return_link"
+msgstr "Zurück zur Statistikübersicht"
+
+#: views/statistics/settings.thtml:56
+msgid "statistics_settings_save_button"
+msgstr "Einstellungen speichern"
+
+#: views/statistics/settings.thtml:46
+#, php-format
+msgid "statistics_settings_title"
+msgstr "Einstellungen der statistischen Auswertung für %1$s"
+
+#: views/statistics/addon.thtml:242
+msgid "statistics_settings_unlocked_alt"
+msgstr "öffentlich"
+
+#: controllers/components/stats.php:405
+msgid "statistics_shortnames_application"
+msgstr "Anw"
+
+#: controllers/components/stats.php:407
+msgid "statistics_shortnames_os"
+msgstr "BS"
+
+#: controllers/components/stats.php:406
+msgid "statistics_shortnames_status"
+msgstr "St"
+
+#: controllers/components/stats.php:408
+msgid "statistics_shortnames_unknown"
+msgstr "Uk"
+
+#: controllers/components/stats.php:404
+msgid "statistics_shortnames_version"
+msgstr "Ver"
+
+#: views/statistics/rss/summary.thtml:42 views/statistics/addon.thtml:192
+msgid "statistics_summary_downloads_average"
+msgstr "Durchschnitt Downloads pro Tag"
+
+#: views/statistics/rss/summary.thtml:39
+msgid "statistics_summary_downloads_heading"
+msgstr "Downloads"
+
+#: views/statistics/rss/summary.thtml:41 views/statistics/addon.thtml:171
+msgid "statistics_summary_downloads_lastcount"
+msgstr "Am letzten gezählten Tag"
+
+#: views/statistics/rss/summary.thtml:43 views/statistics/addon.thtml:199
+msgid "statistics_summary_downloads_lastweek"
+msgstr "Downloads in den letzten sieben Tagen"
+
+#: views/statistics/rss/summary.thtml:40 views/statistics/addon.thtml:151
+msgid "statistics_summary_downloads_total"
+msgstr "Downloads insgesamt"
+
+#: views/statistics/rss/summary.thtml:40 views/statistics/addon.thtml:152
+#, php-format
+msgid "statistics_summary_downloads_total_sincedate"
+msgstr "Seit %1$s"
+
+#: views/statistics/rss/summary.thtml:50 views/statistics/rss/summary.thtml:56
+#: views/statistics/addon.thtml:163 views/statistics/addon.thtml:183
+msgid "statistics_summary_nodata"
+msgstr "Noch keine Daten"
+
+#: views/statistics/rss/summary.thtml:60 views/statistics/addon.thtml:195
+msgid "statistics_summary_updatepings_average"
+msgstr "Durchschnitt tägliche Nutzer"
+
+#: views/statistics/rss/summary.thtml:52 views/statistics/addon.thtml:177
+msgid "statistics_summary_updatepings_changefromprevious"
+msgstr "Veränderung"
+
+#: views/statistics/rss/summary.thtml:54 views/statistics/addon.thtml:181
+#, php-format
+msgid "statistics_summary_updatepings_changefromprevious_ondate"
+msgstr "%1$s am %2$s"
+
+#: views/statistics/rss/summary.thtml:45
+msgid "statistics_summary_updatepings_heading"
+msgstr "Aktive tägliche Nutzer"
+
+#: views/statistics/rss/summary.thtml:46 views/statistics/addon.thtml:157
+msgid "statistics_summary_updatepings_total"
+msgstr "Aktive tägliche Nutzer"
+
+#: views/statistics/rss/summary.thtml:48 views/statistics/addon.thtml:161
+#, php-format
+msgid "statistics_summary_updatepings_total_ondate"
+msgstr "Für %1$s"
+
+#: views/statistics/rss/summary.thtml:61 views/statistics/addon.thtml:203
+msgid "statistics_summary_updatepings_weekly_average"
+msgstr "Durchschnittliche Benutzerzahl pro Tag in dieser Woche"
+
+#. %s is a percentage, like '+22.33%'. It sits next to another number, so
+#. the implied meaning is 'percentage change' from the previous stat point.
+#: views/statistics/rss/summary.thtml:62 views/statistics/addon.thtml:205
+msgid "statistics_summary_updatepings_weekly_change"
+msgstr "%s gegenüber letzter Woche"
+
+#: views/statistics/addon.thtml:65 controllers/statistics_controller.php:184
+#: controllers/statistics_controller.php:282
+#, php-format
+msgid "statistics_title_addon_stats"
+msgstr "Statistiken für %1$s"
+
+#: views/addons/themes_landing.thtml:113
+msgid "themes_landing_all_themes"
+msgstr "Alle Themes"
+
+#: views/addons/themes_landing.thtml:109
+msgid "themes_landing_browse_themes"
+msgstr "Themes durchsuchen"
+
+#: views/users/edit.thtml:185
+msgid "user_change_email"
+msgstr "E-Mail-Adresse ändern"
+
+#: views/users/edit.thtml:169
+msgid "user_change_password"
+msgstr "Passwort ändern"
+
+#: views/users/edit.thtml:96
+msgid "user_change_password_or_email"
+msgstr "Passwort oder E-Mail ändern"
+
+#: controllers/users_controller.php:197
+msgid "user_confirmationcode_resent"
+msgstr "Bestätigungscode erneut versandt!"
+
+#. %1 is the email address, %2 is the URL of the user registration page
+#: views/users/delete.thtml:51
+msgid "user_del_account_deleted"
+msgstr ""
+"Ihr Benutzerkonto wurde erfolgreich gelöscht. Wenn Sie eines Tages "
+"zurückkommen möchten, können Sie sich auf der <a href=\"%2$s"
+"\">Registrierungsseite</a> erneut anmelden."
+
+#: views/users/delete.thtml:102
+msgid "user_del_community_sad"
+msgstr "Schade, dass Sie die Mozilla Add-ons Gemeinschaft verlassen möchten."
+
+#: views/users/delete.thtml:123
+msgid "user_del_confirm_password"
+msgstr "Passwort bestätigen"
+
+#: views/users/delete.thtml:134
+msgid "user_del_deletenow"
+msgstr "Löschen Sie mein Benutzerkonto jetzt"
+
+#. %1 is the URL of the user's info page
+#: views/users/delete.thtml:64
+msgid "user_del_error_addons"
+msgstr ""
+"Sie können Ihr Benutzerkonto nicht löschen, falls Sie bei irgendwelchen Add-"
+"ons <a href=\"%1$s\">als Autor genannt</a> werden. Um Ihr Konto zu löschen, "
+"lassen Sie bitte ein anderes Mitglied Ihres Entwicklungsteams Ihren Namen "
+"von der Autorenliste entfernen. Danach werden Sie dazu in der Lage sein, "
+"hier Ihr Konto zu löschen."
+
+#. %1 is a link to the amo-editors mailing list
+#: views/users/delete.thtml:71
+msgid "user_del_error_addons_more_questions"
+msgstr "Wenn Sie noch Fragen haben, kontaktieren Sie bitte %1$s."
+
+#: views/users/delete.thtml:78
+msgid "user_del_error_checkbox"
+msgstr ""
+"Sie müssen den Haken bei \"Ich verstehe...\" setzen, bevor wir Ihr "
+"Benutzerkonto löschen können."
+
+#: views/users/delete.thtml:84
+msgid "user_del_error_password"
+msgstr ""
+"Bitte geben Sie Ihr Passwort korrekt ein, um diesen Schritt durchzuführen."
+
+#. %1 is a link to the amo-admins mailing list
+#: views/users/delete.thtml:91
+msgid "user_del_error_unknown"
+msgstr ""
+"Beim Löschen Ihres Benutzerkontos ist ein unbekannter Fehler aufgetreten. "
+"Bitte Bitte setzen Sie sich mit %1$s in Verbindung, und wir werden Ihr Konto "
+"für Sie löschen. Entschuldingen Sie die Unannehmlichkeiten."
+
+#: views/users/delete.thtml:110
+msgid "user_del_header_confirm_deletion"
+msgstr "Löschung bestätigen"
+
+#. %1 is the user's email address
+#: views/users/delete.thtml:100
+msgid "user_del_header_delete_account"
+msgstr "Benutzerkonto \"%1$s\" löschen"
+
+#: views/users/delete.thtml:50
+msgid "user_del_header_farewell"
+msgstr "Auf Wiedersehen!"
+
+#: views/users/delete.thtml:115
+msgid "user_del_nologin"
+msgstr "Sie werden sich nicht mehr bei Mozilla Add-ons anmelden können."
+
+#: views/users/delete.thtml:112
+msgid "user_del_permanently_removed_means"
+msgstr ""
+"Wenn Sie \"jetzt löschen\" klicken, wird Ihr Benutzerkonto "
+"<strong>unwiederbringlich entfernt</strong>. Das bedeutet:"
+
+#: views/users/delete.thtml:116
+msgid "user_del_reviews_anonymized"
+msgstr ""
+"Ihre Bewertungen für Add-ons werden nicht gelöscht werden, aber sie sind "
+"nicht mehr mit Ihrem Namen verbunden."
+
+#. %1 is a link to the amo-editors mailing list
+#: views/users/delete.thtml:104
+msgid "user_del_specific_problem_editors"
+msgstr ""
+"Falls Sie ein bestimmtes Problem haben, bei dem wir Ihnen helfen können, "
+"dann löschen Sie Ihr Benutzerkonto bitte jetzt nicht, sondern setzen Sie "
+"sich mit uns unter %1$s in Verbindung, und wir werden unser bestes tun, "
+"Ihnen bei der Lösung des Problems behilflich zu sein."
+
+#: views/users/delete.thtml:130
+msgid "user_del_understand_permanent"
+msgstr ""
+"Ich verstehe, dass dieser Schritt nicht rückgängig gemacht werden kann."
+
+#: views/helpers/addons_html.php:192
+msgid "user_deleted_nickname"
+msgstr "Gelöschter Benutzer"
+
+#. %1 is the new email address
+#: views/users/edit.thtml:71
+msgid "user_edit_confirm_email_sent"
+msgstr ""
+"Wir haben eine E-Mail an %1$s gesendet, um Ihre neue E-Mail-Adresse zu "
+"bestätigen. Um die Adressänderung wirksam werden zu lassen, klicken Sie "
+"bitte auf den Link, der sich in dieser E-Mail befindet. Bis das geschehen "
+"ist, können Sie sich weiterhin mit Ihrer gegenwärtigen Adresse anmelden."
+
+#: views/users/edit.thtml:201
+msgid "user_edit_delete_user"
+msgstr "Benutzerkonto löschen"
+
+#. This contains the email sent to users when they signed up for a new
+#. account:
+#. %1 is the confirmation URL, %2 is the current app
+#: views/users/email/confirm_plain.thtml:6
+#, php-format
+msgid "user_email_confirm_account_nopass"
+msgstr ""
+"Willkommen zu %2$s Add-ons.\n"
+"\n"
+"Bevor Sie Ihr Benutzerkonto verwenden können, müssen Sie es erst aktivieren. "
+"Das stellt sicher, dass Sie Ihre E-Mail-Adresse korrekt eingegeben haben.\n"
+"Um Ihr Konto zu aktivieren, klicken Sie bitte auf den folgenden Link oder "
+"kopieren Sie ihn in die Adressleiste Ihres Webbrowsers:\n"
+"\n"
+"%1$s\n"
+"\n"
+"Nachdem Sie Ihren Account erfolgreich aktiviert haben, können Sie diese E-"
+"Mail löschen.\n"
+"Danke, dass Sie sich bei %2$s Add-ons angemeldet haben!\n"
+"-- das %2$s Add-ons Team"
+
+#. %1 is the confirmation url, %2 is the application name
+#: views/users/email/emailchange_plain.thtml:5
+msgid "user_email_confirm_emailchange"
+msgstr ""
+"Sie haben eine E-Mail-Adressänderung bei %2$s Add-ons angefordert.\n"
+"Um Ihre neue E-Mail-Adresse zu bestätigen, klicken Sie bitte auf den "
+"folgenden Link, oder kopieren Sie ihn an einem Stück in die Adressleite "
+"Ihres Webbrowsers:\n"
+"\n"
+"%1$s\n"
+"\n"
+"Sie haben 48 Stunden Zeit, um Ihre neue E-Mail-Adresse zu bestätigen. Wenn "
+"Sie die Änderung doch nicht durchführen möchten, können Sie diese Mail "
+"hingegen ignorieren.\n"
+"\n"
+"Vielen Dank!\n"
+"-- das %2$s Add-ons Team"
+
+#: controllers/users_controller.php:168
+#, php-format
+msgid "user_email_confirm_subject"
+msgstr "Danke, dass Sie sich bei %1$s Add-ons angemeldet haben"
+
+#. This is the password reset email
+#. %1 is the pw reset URL, %2 is the application
+#: views/users/email/pwreset_plain.thtml:5
+#, php-format
+msgid "user_email_pwreset"
+msgstr ""
+"%2$s Add-ons Password zurücksetzen\n"
+"\n"
+"Sie erhalten diese E-Mail, weil jemand bei %2$s Add-ons angefordert hat, Ihr "
+"Passwort zurückzusetzen. Um Ihr Passwort zu ändern, klicken Sie bitte auf "
+"den folgenden Link, oder kopieren Sie ihn in die Adressleiste Ihres "
+"Webbrowsers:\n"
+"\n"
+"%1$s\n"
+"\n"
+"Wenn Sie diese Mail nicht angefordert haben, ignorieren Sie sie bitte "
+"einfach. Ihr Passwort wird dann nicht verändert.\n"
+"\n"
+"Danke,\n"
+"-- das %2$s Add-ons Team"
+
+#: controllers/users_controller.php:245
+#, php-format
+msgid "user_email_pwreset_subject"
+msgstr "Zurücksetzen Ihres %s Add-ons-Passworts"
+
+#: views/users/emailchange.thtml:50
+msgid "user_emailchange_error"
+msgstr "Fehler!"
+
+#. %1 is the application name
+#: controllers/users_controller.php:533
+msgid "user_emailchange_subject"
+msgstr "Bitte bestätigen Sie Ihre E-Mail-Adressänderung bei %1$s Add-ons"
+
+#: views/users/emailchange.thtml:48
+msgid "user_emailchange_success"
+msgstr "Erfolgreich durchgeführt!"
+
+#. %1 is the new email address
+#: views/users/emailchange.thtml:49
+msgid "user_emailchange_successful_description"
+msgstr ""
+"Ihre E-Mail-Adresse wurde erfolgreich geändert. Verwenden Sie bitte von nun "
+"an %1$s, um sich auf der Seite anzumelden."
+
+#: views/users/edit.thtml:134 views/admin/users_edit.thtml:111
+msgid "user_form_bio"
+msgstr "Ãœber mich"
+
+#: views/users/edit.thtml:135 views/admin/users_edit.thtml:112
+msgid "user_form_bio_description"
+msgstr ""
+"Stellen Sie sich den Benutzern gegenüber vor, wenn Sie möchten! Dieser Text "
+"wird öffentlich angezeigt auf Ihrer Benutzer-Infoseite. Zeilenumbrüche "
+"bleiben erhalten, aber HTML ist nicht erlaubt."
+
+#: views/users/pwreset.thtml:77 views/users/register.thtml:73
+#: views/users/edit.thtml:181
+msgid "user_form_confirmpassword"
+msgstr "Passwort bestätigen"
+
+#: views/users/edit.thtml:145
+msgid "user_form_display_collections"
+msgstr "Meine eigenen Sammlungen in meinem Benutzerprofil anzeigen"
+
+#: views/users/edit.thtml:149
+msgid "user_form_display_collections_fav"
+msgstr "Meine Favoriten unter den Sammlungen in meinem Benutzerprofil anzeigen"
+
+#: views/users/edit.thtml:86
+#, php-format
+msgid "user_form_editprofile"
+msgstr "Benutzerprofil von %s bearbeiten"
+
+#: views/users/pwreset.thtml:52 views/users/login.thtml:81
+#: views/users/register.thtml:63 views/users/edit.thtml:187
+msgid "user_form_email"
+msgstr "E-Mail"
+
+#: views/users/register.thtml:78 views/users/edit.thtml:103
+#: views/admin/users_edit.thtml:76
+msgid "user_form_firstname"
+msgstr "Vorname"
+
+#: views/users/register.thtml:94 views/users/edit.thtml:119
+#: views/admin/users_edit.thtml:91
+msgid "user_form_hideemail"
+msgstr "E-Mail nicht anzeigen"
+
+#: views/users/register.thtml:98 views/users/edit.thtml:123
+#: views/admin/users_edit.thtml:99
+msgid "user_form_homepage"
+msgstr "Homepage"
+
+#: views/users/register.thtml:84 views/users/edit.thtml:109
+#: views/admin/users_edit.thtml:81
+msgid "user_form_lastname"
+msgstr "Nachname"
+
+#: controllers/users_controller.php:333
+msgid "user_form_login"
+msgstr "Benutzer-Login"
+
+#: views/users/pwreset.thtml:72 views/users/edit.thtml:176
+msgid "user_form_newpassword"
+msgstr "Neues Passwort"
+
+#: views/users/register.thtml:89 views/users/edit.thtml:114
+#: views/admin/users_edit.thtml:86
+msgid "user_form_nickname"
+msgstr "Spitzname"
+
+#: views/users/edit.thtml:171
+msgid "user_form_oldpassword"
+msgstr "altes Passwort"
+
+#: views/users/edit.thtml:97 views/users/edit.thtml:200
+msgid "user_form_otheractions"
+msgstr "Weitere Aktionen"
+
+#: views/users/login.thtml:85 views/users/register.thtml:68
+msgid "user_form_password"
+msgstr "Passwort"
+
+#: controllers/users_controller.php:93
+msgid "user_form_registration"
+msgstr "Benutzerkonto anlegen"
+
+#: views/users/login.thtml:90
+msgid "user_form_remember_me"
+msgstr "Auf diesem Computer angemeldet bleiben"
+
+#: views/admin/users_edit.thtml:95
+msgid "user_form_showsandbox"
+msgstr "Sandkasten anzeigen?"
+
+#: views/users/edit.thtml:205
+msgid "user_form_submit_edit"
+msgstr "Speichern"
+
+#: views/users/login.thtml:93
+msgid "user_form_submit_login"
+msgstr "Einloggen"
+
+#: views/users/register.thtml:113
+msgid "user_form_submit_register"
+msgstr "Abschicken"
+
+#: views/users/info.thtml:75
+#, php-format
+msgid "user_info_usersince"
+msgstr "Angemeldet bei %1$s Add-ons seit"
+
+#: views/users/login.thtml:102
+msgid "user_login_register_link"
+msgstr "Neues Benutzerkonto anlegen"
+
+#: views/users/edit.thtml:160
+msgid "user_notifications_item_compat"
+msgstr "Add-on-Kompatibilität (strengstens empfohlen)"
+
+#: views/users/edit.thtml:161
+msgid "user_notifications_item_events"
+msgstr "Baldige Ereignisse und Wettbewerbe"
+
+#: views/users/edit.thtml:156
+msgid "user_notifications_none_available"
+msgstr "Gegenwärtig können Sie keine Benachrichtigungen an oder ausschalten."
+
+#: views/users/edit.thtml:158
+msgid "user_notifications_select_topics"
+msgstr ""
+"Von Zeit zu Zeit kann Mozilla Ihnen E-Mails bezüglich bald erscheinender "
+"Softwareversionen und Add-on-bezogener Ereignisse senden. Bitte wählen Sie "
+"diejenigen Themes aus, die Sie interessieren:"
+
+#: views/users/edit.thtml:164
+msgid "user_notifications_specific_contact"
+msgstr ""
+"Mozilla behält sich vor, Ihnen persönliche E-Mails zu schreiben, wenn es um "
+"bestimmte Angelegenheiten im Bezug auf Ihre hier beherbergten Add-ons geht."
+
+#: controllers/users_controller.php:543
+msgid "user_profile_edit_error"
+msgstr "Fehler beim Bearbeiten des Benutzerprofils!"
+
+#: controllers/users_controller.php:540
+msgid "user_profile_saved"
+msgstr "Benutzerprofil geändert."
+
+#: views/users/pwreset.thtml:65
+#, php-format
+msgid "user_pwreset_for_email"
+msgstr "Passwort für %s zurücksetzen"
+
+#: controllers/users_controller.php:226
+msgid "user_pwreset_header"
+msgstr "Passwort zurücksetzen"
+
+#: views/users/login.thtml:103
+msgid "user_pwreset_link"
+msgstr "Passwort vergessen?"
+
+#: controllers/users_controller.php:248
+msgid "user_pwreset_link_sent"
+msgstr ""
+"Ein Link zum Zurücksetzen Ihres Passworts wurde an Ihre E-Mail-Adresse "
+"gesendet."
+
+#: controllers/users_controller.php:304
+msgid "user_pwreset_okay"
+msgstr "Passwort erfolgreich geändert."
+
+#: views/users/pwreset.thtml:82
+msgid "user_pwreset_submit_changepw"
+msgstr "Neues Passwort speichern"
+
+#: views/users/pwreset.thtml:57
+msgid "user_pwreset_submit_sendlink"
+msgstr "Link per E-Mail senden"
+
+#: views/users/register_complete.thtml:51
+#, php-format
+msgid "user_register_amo_link"
+msgstr "%s Add-ons"
+
+#. %1 is the user's email address, %2 is the current app
+#: views/users/activatefirst.thtml:49
+#, php-format
+msgid "user_register_click_confirm_link"
+msgstr ""
+"Eine E-Mail wurde an Ihre Adresse %1$s gesendet, um Ihre E-Mail-Adresse zu "
+"bestätigen. Bevor Sie sich einloggen können, müssen Sie den in der Mail "
+"enthaltenen Link aufrufen, um Ihr Konto zu aktivieren."
+
+#. %1 is the user's email address
+#: views/users/register_complete.thtml:49
+#, php-format
+msgid "user_register_confirm_email_sent"
+msgstr ""
+"Eine E-Mail wurde an Ihre Adresse %1$s gesendet, um Ihre E-Mail-Adresse zu "
+"bestätigen. Bevor Sie sich einloggen können, müssen Sie den in der Mail "
+"enthaltenen Link aufrufen, um Ihr Konto zu aktivieren."
+
+#: views/users/activatefirst.thtml:51
+msgid "user_register_confirmation_link_text"
+msgstr "erneut zuschicken lassen"
+
+#: views/users/register_complete.thtml:47
+msgid "user_register_congratulations"
+msgstr "Glückwunsch, Ihr Benutzerkonto wurde erfolgreich angelegt!"
+
+#: views/users/register.thtml:50
+msgid "user_register_details"
+msgstr ""
+"<p>Es ist <strong>nicht zwingend notwendig</strong>, sich auf Mozilla Add-"
+"ons zu registrieren, wenn Sie nur öffentliche Add-ons herunterladen und "
+"installieren möchten.</p><p>Sie müssen sich nur registrieren, um folgendes "
+"zu tun:</p><ul><li>Sie möchten Bewertungen für Add-ons schreiben</li><li>Sie "
+"sind ein Entwickler und möchten Ihr Add-on auf Mozilla Add-ons anbieten</"
+"li></ul><p>Wenn Sie sich erfolgreich registriert haben, erhalten Sie eine "
+"Bestätigungs-E-Mail an die Adresse, die Sie eingegeben haben. Bitte folgen "
+"Sie den darin enthaltenen Informationen, um Ihr Benutzerkonto zu aktivieren."
+"</p><p>Wenn Sie möchten, lesen Sie ruhig unsere <a href=\"%1$s\">rechtlichen "
+"Hinweise</a> und <a href=\"%2$s\">Datenschutzerklärung</a>.</p>"
+
+#. %1 is the link to the "resend confirmation code" page
+#: views/users/activatefirst.thtml:51
+#, php-format
+msgid "user_register_resend_confirmation_link"
+msgstr ""
+"Falls Sie die Bestätigungsmail nicht erhalten haben, prüfen Sie bitte "
+"zunächst, ob Ihr E-Mail-Service diese als \"Spam\" markiert hat und diese "
+"ggf. im dafür vorgesehenen Ordner gelandet ist. Wenn es nötig ist, können "
+"Sie sich die E-Mail an ihre o.g. Adresse %1$s."
+
+#. %1 is the link to the Mozilla Add-ons front page
+#: views/users/register_complete.thtml:51
+#, php-format
+msgid "user_register_welcome"
+msgstr "Danke für Ihre Anmeldung und willkommen zu %1$s!"
+
+#: views/users/register.thtml:49
+msgid "user_register_welcome_header"
+msgstr "Wilkommen bei Mozilla Add-ons (AMO)!"
+
+#: views/users/register.thtml:81 views/users/edit.thtml:106
+msgid "user_required_firstlast_or_nickname"
+msgstr "Ein Vorname, Nachname oder Spitzname wird benötigt."
+
+#: views/users/edit.thtml:94 views/users/edit.thtml:142
+msgid "user_tab_collections"
+msgstr "Sammlungen"
+
+#: views/users/edit.thtml:95 views/users/edit.thtml:154
+msgid "user_tab_notifications"
+msgstr "Benachrichtigungen"
+
+#: views/users/edit.thtml:93 views/users/edit.thtml:101
+msgid "user_tab_profile"
+msgstr "Benutzerprofil"
+
+#: controllers/users_controller.php:209
+msgid "user_verified_okay"
+msgstr "Benutzerkonto erfolgreich bestätigt."
+
+#: controllers/users_controller.php:723
+msgid "users_delete_pagetitle"
+msgstr "Benutzerkonto löschen"
+
+#: controllers/users_controller.php:414
+msgid "users_edit_pagetitle"
+msgstr "Benutzerkonto bearbeiten"
+
+#: views/users/info.thtml:71
+msgid "users_info_aboutme"
+msgstr "Ãœber mich"
+
+#: views/users/info.thtml:96
+#, php-format
+msgid "users_info_addons_by_user"
+msgstr "Add-ons von Benutzer %1$s"
+
+#: views/users/info.thtml:51
+msgid "users_info_author_name"
+msgstr "Name"
+
+#: views/users/info.thtml:48
+msgid "users_info_author_profile"
+msgstr "Benutzerprofil"
+
+#. %s is the user name
+#: views/users/info.thtml:137
+msgid "users_info_collections_by_user"
+msgstr "Sammlungen von %s"
+
+#: views/users/info.thtml:66
+msgid "users_info_email"
+msgstr "E-Mail"
+
+#: views/users/info.thtml:155
+msgid "users_info_fav_collections_by_user"
+msgstr "Lieblings-Sammlungen"
+
+#: views/users/info.thtml:61
+msgid "users_info_homepage"
+msgstr "Homepage"
+
+#: views/users/info.thtml:56
+msgid "users_info_nickname"
+msgstr "Spitzname"
+
+#: controllers/users_controller.php:707
+#, php-format
+msgid "users_info_pagetitle"
+msgstr "Benutzer-Info über %1$s"
+
+#. %1 is the user's name
+#: views/users/info.thtml:116
+msgid "users_info_reviews_by_user"
+msgstr "Bewertungen von %s"
+
+#: controllers/users_controller.php:330 controllers/users_controller.php:332
+msgid "users_login_pagetitle"
+msgstr "Benutzer-Login"
+
+#. %1 is the link to the sandbox/policy explanation page
+#. This message is for a specific add-on not found
+#: views/users/login.thtml:53
+#, php-format
+msgid "users_login_sandbox_display_warning"
+msgstr ""
+"Das von Ihnen angeforderte Add-on befindet sich derzeit im Sandkasten. Falls "
+"Sie bereits ein Konto bei Mozilla Add-ons haben, so melden Sie sich bitte "
+"an, oder <a href=\"%1$s\">erfahren Sie mehr über den Sandkasten.</a>"
+
+#. %1 is the link to the sandbox/policy explanation page
+#. This message is for any given sandbox-related page not found
+#: views/users/login.thtml:56
+#, php-format
+msgid "users_login_sandbox_page_warning"
+msgstr ""
+"Die von Ihnen angeforderte Seite gehört zum Sandkasten. The page you're "
+"looking for is part of the sandbox. Falls Sie bereits ein Konto bei Mozilla "
+"Add-ons haben, so melden Sie sich bitte an, oder <a href=\"%1$s\">erfahren "
+"Sie mehr über den Sandkasten.</a>"
+
+#: controllers/users_controller.php:223 controllers/users_controller.php:225
+msgid "users_pwreset_pagetitle"
+msgstr "Passwort zurücksetzen"
+
+#: controllers/users_controller.php:90 controllers/users_controller.php:92
+msgid "users_register_pagetitle"
+msgstr "Benutzerkonto anlegen"
+
+#. %1$s is an addon name, like <a>Firebug</a>
+#. %2$s is a version number, like <a>1.2</a>
+#: views/versions/license.thtml:52
+msgid "versions_license_header_source"
+msgstr "Quellcode-Lizenz für %1$s Version %2$s"
+
+#: views/addons/category_landing.thtml:147
+msgid "view_recently_added"
+msgstr "Alle neu hinzugefügten Add-ons"
+
+#: views/addons/category_landing.thtml:161
+msgid "view_top_downloads"
+msgstr "Alle häufig heruntergeladenen Add-ons"
+
+#: views/addons/category_landing.thtml:175
+msgid "view_top_rated"
+msgstr "Alle am höchsten bewerteten Add-ons"
+
+#~ msgid "addon_slider_tooltip_next"
+#~ msgstr "Nächstes Add-on"
+
+#~ msgid "addon_slider_tooltip_previous"
+#~ msgstr "Vorheriges Add-on"
+
+#~ msgid "addons_display_version_history"
+#~ msgstr "Gesamte Versionsgeschichte"
+
+#~ msgid "addons_home_newest_header"
+#~ msgstr "Neueste:"
+
+#~ msgid "addons_home_popular_header"
+#~ msgstr "Am beliebtesten:"
+
+#~ msgid "addons_home_recommended_header"
+#~ msgstr "Von uns empfohlen:"
+
+#~ msgid "addons_home_updated_header"
+#~ msgstr "Aktualisiert:"
+
+#~ msgid "addons_home_view_all"
+#~ msgstr "Alle anzeigen"
+
+#~ msgid "category_extra_allrecommended"
+#~ msgstr "Alle empfohlenen Add-ons"
+
+#~ msgid "category_extra_highestrated"
+#~ msgstr "Nach Bewertung"
+
+#~ msgid "category_extra_lastupdated"
+#~ msgstr "Nach Aktualität"
+
+#~ msgid "category_extra_mostpopular"
+#~ msgstr "Nach Beliebtheit"
+
+#~ msgid "collections_detail_js_loading"
+#~ msgstr "Lädt..."
+
+#~ msgid "collections_detail_more_info"
+#~ msgstr "Mehr Infos anzeigen"
+
+#~ msgid "devcp_addon_status_criteria_review"
+#~ msgstr ""
+#~ "Ihr Add-on benötigt mehrere Benutzer-Bewertungen (diese dürfen auch "
+#~ "externe Webadressen sein)."
+
+#~ msgid "editors_submissiontype_new"
+#~ msgstr "Neu"
+
+#~ msgid "editors_submissiontype_updated"
+#~ msgstr "Aktualisiert"
+
+#~ msgid "editors_th_addon_age"
+#~ msgstr "Add-on-Alter"
+
+#~ msgid "editors_th_addontypes"
+#~ msgstr "Add-on-Typen"
+
+#~ msgid "editors_th_applications"
+#~ msgstr "Anwendungen"
+
+#~ msgid "editors_th_platforms"
+#~ msgstr "Betriebssystemart"
+
+#~ msgid "editors_th_submissiontypes"
+#~ msgstr "Ãœbermittelungstypen"
+
+#~ msgid "forum_save"
+#~ msgstr "Speichern"
+
+#~ msgid "home"
+#~ msgstr "Hauptseite"
+
+#~ msgid "nav_category_plugins"
+#~ msgstr "Plugins"
+
+#~ msgid "pagination_page_number_title"
+#~ msgstr "Dies ist Seite %1$s von %2$s"
+
+#~ msgid "search_matching_addons_number"
+#~ msgid_plural "search_matching_addons_number"
+#~ msgstr[0] "%s passendes Add-on"
+#~ msgstr[1] "%s passende Add-ons"
diff --git a/site/app/locale/de/images/sandbox-review.png b/site/app/locale/de/images/sandbox-review.png
new file mode 100644
index 0000000..ef8a4c0
--- /dev/null
+++ b/site/app/locale/de/images/sandbox-review.png
Binary files differ
diff --git a/site/app/locale/de/pages/error404.thtml b/site/app/locale/de/pages/error404.thtml
new file mode 100644
index 0000000..c122b15
--- /dev/null
+++ b/site/app/locale/de/pages/error404.thtml
@@ -0,0 +1,16 @@
+<h1>Diese Seite wurde leider nicht gefunden.</h1>
+
+<p>Die Webseite oder Datei, die Sie angefordert haben, wurde auf unserem Server nicht gefunden. Es ist möglich, dass Sie auf einen Link geklickt haben, der nicht mehr aktuell ist, oder vielleicht haben Sie sich bei der Eingabe der Adresse vertippt.</p>
+
+<ul>
+<li>Falls Sie die Adresse von Hand eingegeben haben, überprüfen Sie bitte noch einmal, ob Sie sie richtig geschrieben haben.</li>
+<li>Wenn Sie einem "toten" Link gefolgt sind, lassen Sie uns das bitte wissen, indem Sie uns eine E-Mail an <a href="mailto:webmaster@mozilla.com" title="Page Not Found on Mozilla.com">webmaster@mozilla.com</a> schreiben. Teilen Sie uns mit, woher Sie gekommen sind und wohin Sie gelangen wollten, und wir werden uns bemühen, das Problem zu beheben.</li>
+</ul>
+
+<p>Stattdessen möchten Sie aber vielleicht auch einfach zu einer der beliebten Seiten auf unserem Angebot surfen:</p>
+
+<ul>
+<li>Möchten Sie eine Liste von <a href="%1$s">beliebten Add-ons</a> sehen?</li>
+<li>Möchten Sie nach <a href="%2$s">Add-ons suchen</a>? Dazu können sie die <a href="%2$s">Suche aufrufen</a> oder einfach etwas in das unten stehende Suchfeld eingeben.</li>
+<li>Wenn Sie lieben von vorne beginnen wollen, gehen Sie einfach zur <a href="%3$s">Add-ons-Hauptseite</a>.</li>
+</ul>
diff --git a/site/app/locale/de/pages/faq.thtml b/site/app/locale/de/pages/faq.thtml
new file mode 100755
index 0000000..bd42bb5
--- /dev/null
+++ b/site/app/locale/de/pages/faq.thtml
@@ -0,0 +1,65 @@
+<h1>Häufig gestellte Fragen</h1>
+
+<p>Diese Fragen über die <a href="http://addons.mozilla.org">Mozilla Add-ons-Seite</a> beantwortet manche Fragen, die gegenwärtig nicht von der Mozilla Support-Webseite behandelt werden. Die Support-Webseite verfügt über Informationen, um <a href="http://support.mozilla.com/kb/Customizing+Firefox+with+add-ons">Firefox mit Add-ons anzupassen</a> und Artikel über:</p>
+
+<ul>
+ <li>Probleme bei der <a href="http://support.mozilla.com/kb/Unable+to+install+add-ons">Installation von Add-ons</a>, <a href="http://support.mozilla.com/kb/Troubleshooting+plugins">Plugins</a> &amp; <a href="http://support.mozilla.com/kb/Troubleshooting+extensions+and+themes">allgemeine Probleme</a>.</li>
+ <li><a href="http://support.mozilla.com/kb/Uninstalling+add-ons">Add-ons deinstallieren</a> und <a href="http://support.mozilla.com/kb/Cannot+uninstall+an+add-on">Probleme mit der Deinstallation</a>.</li>
+ <li><a href="http://support.mozilla.com/kb/Gray+bar+below+the+status+bar">Umgang mit problematischen Add-ons / "Graue Leiste"-Problem</a></li>
+</ul>
+
+<p></p>
+
+<h2>Fragen über Add-ons</h2>
+<dl class="faq">
+<dt>Was ist ein Add-on?</dt>
+<dd>Add-ons erlauben Ihnen Funktionen hinzuzufügen, die nicht Teil einer Standardinstallation sind. Themes ändern das Aussehen, ohne Funktionalität zu beeinflussen. Suchmaschinen-Plugins und Wörterbücher/Sprachpakete fügen weitere Suchmaschinen und Sprachunterstützung hinzu. Erweiterungen für ausführlichere Funktionen zum Browser hinzu; manche fügen einfache Werkzeugleisten hinzu, während andere eine große Vielfalt von neuen Funktionen hinzufügen.</dd>
+
+<dt>Ist es leicht, Add-ons zu installieren?</dt>
+<dd>Ja! Add-ons sind sehr leicht zu installieren. Sie sind in der Regel viel kleiner als eine normale Anwendung und lassen sich sehr schnell herunterladen. Wenn Sie eines von ihnen nicht mögen, können sie es ebenfalls sehr leicht wieder entfernen oder deaktivieren. Außerdem informiert Firefox Sie, wenn es Aktualisierungen für eines Ihrer Add-ons gibt und lässt Sie diese mit nur einem Klick installieren.</dd>
+
+<dt>Wie kann ich meine Add-ons verwalten?</dt>
+<dd>Gehen Sie in Firefox auf "Add-ons" im Menü "Extras", um ihre Themes und Erweiterungen zu verwalten. Wenn eine Ihrer Erweiterungen spezielle Einstellungen erlaubt, dann können Sie diese im "Erweiterungen" Teil des "Add-ons"-Fensters sehen. Von hier aus können Sie auch Add-ons deaktivieren oder installieren. Wörterbücher werden wie Erweiterungen installiert. Suchmaschinen können über die Suchleiste verwaltet werden.</dd>
+
+<dt>Können Add-ons Firefox langsamer machen?</dt>
+<dd>In den meisten Fällen führen Add-ons nicht zu einer merklichen Verlangsamung von Firefox. Da es sich allerdings bei Add-ons um kleine Anwendungen handelt, können sie die Geschwindigkeit von Firefox, abhängig von Ihrer Systemausstattung, manchmal beeinflussen. Wenn Sie vermuten, dass ein Add-on beeinflusst, wie Firefox auf Ihrem Computer läuft, versuchen Sie es einmal zu deaktivieren.</dd>
+
+<dt>Warum sollte ich ein Add-on deaktivieren wollen?</dt>
+<dd>Ein Add-on zu deaktivieren hält es davon ab, beim Start von Firefox geladen zu werden, aber es entfernt nicht das Add-on selbst oder seine gespeicherten Einstellungen. Wenn Sie das Add-on wieder aktivieren, ist der Zustand wiederhergestellt, der vor dem Deaktivieren herrschte. Wenn Sie also ein Add-on ausschalten möchten, ohne es komplett zu entfernen, dann sollten Sie es deaktivieren.</dd>
+
+<dt>Wie sichere ich alle Add-ons und Themes, die ich installiert habe?</dt>
+<dd>Wenn Sie Ihr Profil-Verzeichnis sichern, dann enthält dies auch Ihre Erweiterungen und Themes. Eine Software einer Drittfirma, wie beispielsweise MozBackup, kann Ihnen dabei helfen.</dd>
+</dl>
+
+<h2>Fragen zur Webseite</h2>
+<dl class="faq">
+<dt>Ich finde mehrere Add-ons, die die gleichen Funktionen erfüllen. Wie kann ich entscheiden, welches das beste ist?</dt>
+<dd>Im allgemeinen können die Bewertungen und Download-Zahlen Ihnen einen Hinweis geben. Gute Add-ons werden oft häufiger heruntergeladen als schlechte. Es ist allerdings auch einfach, beide Add-ons zu installieren und schließlich zu entscheiden, welches das richtige für Sie ist. Wenn Sie sie ausprobiert haben, kann es sogar sein, dass Sie sie beide benutzen wollen!</dd>
+
+<dt>Ich habe ein tolles Add-on gefnden, aber es scheint nur mit Firefox 2.x kompatibel zu sein. Kann ich es dennoch in Firefox 3.x installieren?</dt>
+<dd>Im allgemeinen nein. Firefox 3.x hat eine große Anzahl neuer Funktionen und der Großteil der Add-on-Entwickler hat seine Add-ons für diese Version aktualisiert. Wenn ein Add-on nur Firefox 2 unterstützt, suchen Sie einmal nach dem Add-on-Namen. In vielen Fällen gibt es eine neue Version, die Firefox 3 unterstützt, unter demselben oder einem ähnlichen Titel.</dd>
+
+<dt>Ich habe ein neues Theme installiert, möchte aber das Aussehen zum Firefox-Standard zurücksetzen. Wie geht das?</dt>
+<dd>Wählen Sie "Add-ons" aus dem Menü "Extras". Klicken Sie auf "Themes" und wählen Sie dort das Standard-Theme aus, oder auch irgendein anderes, das Sie installiert haben.</dd>
+
+<dt>Wenn ich ein Problem mit einem Add-on habe, sollte ich Mozilla kontaktieren?</dt>
+<dd>Mit nur wenigen Ausnahmen stammen alle Add-ons aus der Community und nicht von Mozilla. Das beste, was Sie tun können, ist den Entwickler des Add-ons mit Ihrer Frage direkt zu kontaktieren. Um Kontaktinfos zu einem Entwickler zu bekommen, klicken Sie in der "von"-Zeile eines Add-ons auf seinen Namen.</dd>
+
+<dt>Wie werden Add-ons moderiert?</dt>
+<dd>Öffentliche Add-ons werden von unserem engagierten und talentierten Moderatorenteam bewertet. Sie beurteilen den Code von allen öffentlichen Add-on uns testen außerdem, ob die Funktion von Add-ons ihrer Beschreibung entspricht.</dd>
+
+<dt>Ich habe gerade Firefox auf Version 3.5 aktualisiert, und nun funktioniert mein Add-on nicht mehr. Warum?</dt>
+<dd>Die meisten unserer Add-ons sind nun mit Firefox 3.5 kompatibel, und jeden Tag werden es mehr. Wenn ein Add-on mit Version 3.0 funktionierte, aber nicht mehr mit Version 3.5, stehen die Chancen gut dass die Entwickler bereits an einer Aktualisierung arbeiten. Wenn das Add-on aktualisiert wird, wird Firefox Sie auf das Update hinweisen.</dd>
+
+<dt id="experimental-addons">Was sind experimentelle Add-ons?</dt>
+<dd>
+ <p>Experimentelle Add-on sind neuere Add-ons, die noch nicht den Veröffentlichungsprozess durchlaufen haben. Viele dieser Add-ons sind "Prototypen". Da sie noch nicht von unserem Moderatorenteam bewertet wurden, können sie ohne weiteres Alpha-, Beta- oder Vorveröffentlichungs-Charakter haben, sowohl hinsichtlich ihrer Qualität und Geschwindigkeit, als auch ihrer Funktionspalette.</p>
+ <p>Seien Sie vorsichtig mit experimentellen Add-ons, denn sie wurden noch nicht von einem Moderator überprüft und können möglicherweise Schaden auf Ihrem Computer anrichten.</p>
+</dd>
+
+<dt id="recognizing-experimental-addons">Wie erkenne ich ein experimentelles Add-on auf der Seite?</dt>
+<dd>Experimentelle Add-ons tragen den Hinweis "experimentell" und verfügen außerdem über eine Warnung, bevor Sie sie installieren können.</dd>
+
+<dt id="recommended-addons">Was sind empfohlene Add-ons?</dt>
+<dd>Das AMO Team empfiehlt eine Anzahl von Add-ons, die hinsichtlich ihrer Nützlichkeit und Qualität zu den besten zählen. Diese empfohlenen Add-ons werden auf den Seiten ihrer jeweiligen Kategorien angezeigt. Manche von ihnen werden ebenfalls auf der Vorderseite von AMO besonders hervorgehoben. Natürlich ist diese Liste auf keinen Fall vollständig und wir aktualisieren die Liste monatlich, damit unsere Benutzer wieder neue Add-ons kennenlernen können. Einige der Erwägungen, die wir in Betracht ziehen für die Entscheidung, ob ein Add-on empfohlen werden soll oder nicht: Qualität, Beliebtheit, Einzigartigkeit, und ob oder ob nicht ein Add-on zuvor bereits einmal empfohlen worden war.</dd>
+</dl>
diff --git a/site/app/locale/de/pages/nomination.thtml b/site/app/locale/de/pages/nomination.thtml
new file mode 100644
index 0000000..1c9c06b
--- /dev/null
+++ b/site/app/locale/de/pages/nomination.thtml
@@ -0,0 +1,8 @@
+<p>Ein Add-on, das sich momentan im Sandkasten befindet, kann für das Erscheinen in den öffentlichen Seiten nominiert werden, wodurch es nach positiv beschiedenen ausführlichen Test eines Moderators allen Benutzern zur Verfügung steht. Um beste Ergebnisse zu erzielen, beachten Sie bitte Folgendes:</p>
+<ul>
+ <li>Vorschaubilder sind für Themes verpflichtend und sehr empfohlen für alle anderen Add-on-Typen</li>
+ <li>Das Add-on sollte genug Zeit im Sandkasten verbracht haben, um ausreichend Rückmeldungen und Bewertungen durch die Benutzer erhalten zu haben.</li>
+ <li>Öffentliche Add-ons haben höhere Mindestanforderungen als Erweiterungen im Sandkasten und sollten den Umgang mit dem Internet erleichtern</li>
+ <li>Die vollständigen Nominierungskriterien befinden sich in unseren <a href="%s">Add-on Richtlinien</a></li>
+</ul>
+<p>Falls Ihr Add-on diese Kriterien erfüllt, so können Sie es mit der untenstehenden Schaltfläche nominieren. Sie werden per E-Mail über den Status Ihrer Nominierung informiert.</p>
diff --git a/site/app/locale/de/pages/policy.thtml b/site/app/locale/de/pages/policy.thtml
new file mode 100644
index 0000000..555d267
--- /dev/null
+++ b/site/app/locale/de/pages/policy.thtml
@@ -0,0 +1,110 @@
+<h1>Add-ons-Richtlinien</h1>
+
+<h2>Was ist der Sandkasten?</h2>
+<p>Schauen Sie hier: %s.</p>
+
+<h2>Welche Add-ons befinden sich im Sandkasten?</h2>
+<p>Der Sandkasten ist der Ort, an dem sich anfangs alle Add-ons befinden, die zu AMO übermittelt werden. Er enthält neue Versionen von öffentlichen Add-ons, sowie alle Versionen von Add-ons die noch nicht für die Veröffentlichung nominiert und freigegeben wurden. Wenn ein neues Add-on, oder ein Update für ein bestehendes Add-on, zu AMO übermittelt wird, landet es im Sandkasten.</p>
+
+<p>Manche Add-ons (und ihre jeweiligen Versionen) werden veröffentlicht, nachdem eine Prüfung zu dem Ergebnis kam, dass sie für die "breite Öffentlichkeit" bereit und geeignet sind. Andere Add-ons bleiben für immer im Sandkasten, wo sie für Benutzer erhältlich bleiben, die entschieden haben, dass sie den Inhalt des Sandkastens sehen wollen und mit der dort enthaltenen Software experimentieren wollen.</p>
+
+<h2>Wie gelangen Add-ons in den öffentlichen Bereich?</h2>
+
+<p>Add-ons werden von AMO-Benutzern geprüft, die sich dafür entschieden haben, den Inhalt des Sandkastens anzuzeigen und die dortigen Add-ons auszuprobieren. Die Bewertungen, die diese AMO-Benutzer schreiben, zeigen an ob ein Add-on ausreichend nützlich, gut geschrieben und "glatt" genug ist, um allen Benutzern von Firefox etc. zur Verfügung gestellt zu werden. Diese Bewertungen, möglicherweise in Verbindung mit weiteren Prüfungen durch das AMO-Team, werden verwendet um zu entscheiden, ob ein bestimmtes Add-on veröffentlicht wird, ob es noch ein bisschen mehr Arbeit benötigt, bevor es öffentlich angezeigt werden kann, oder ob es dafür nicht geeignet ist, um außerhalb des Sandkastens auf AMO dargestellt zu werden.</p>
+
+<h2>Wie kann ich mein Add-on zur Veröffentlichung nominieren?</h2>
+
+<p>Wenn Sie denken, dass Ihr Add-on (und Ihr Verhalten!) die Kriterien für ein öffentliches Add-on erfüllen, dann können Sie es in den Entwickler-Werkzeugen für eine Veröffentlichung nominieren.</p>
+
+<h2>Welche Kriterien gibt es für öffentliche Add-ons?</h2>
+
+<p>Ein Add-on, das im öffentlichen Teil von AMO angezeigt werden soll, sollte eine hohe Qualität aufweisen und dem Benutzer das Verwenden des Webs erleichtern. Wenn wir entscheiden, ob ein Add-on für die öffentliche Seite von AMO geeignet ist, beachten wir Folgendes:</p>
+
+<h3>Reagieren Sie auf Anfragen?</h3>
+
+<p>Wir erwarten, dass ein Add-on-Autor, der sein Add-on den vielen Benutzern von Firefox etc. zur Verfügung stellen möchte, auf Problemberichte reagiert, seine Kontaktinformationen aktuell hält, und regelmäßige Updates veröffentlicht, um das Add-on aktuell zu halten, was sich verändernde Versionen von Firefox etc. oder auch der AMO Richtlinien betrifft. Das bedeutet nicht, dass Sie auf jede Frage antworten müssen die jemand im Forum stellt, und es bedeutet nicht einmal, dass Sie jeden kleinen Fehler beheben müssen. Aber wir erwarten, dass Sie offene Fragen in einer Weise behandeln, die der Wichtigkeit des Problems angemessen ist.</p>
+
+<h3>Ist die Beschreibung des Add-ons klar und deutlich?</h3>
+
+<p>Es ist für uns unerlässlich, dass Benutzer das bekommen, was sie erwarten, wenn sie ein neues Add-on ausprobieren. Ihre Beschreibung soll Details darüber enthalten, was das Add-on tut, wie ein Benutzer es bestmöglich nutzen kann, und was ihn erwartet, wenn er es installiert. Links zu Handbüchern und Beschreibungsseiten sind in Ordnung, aber die Beschreibung selbst sollte die grundlegenden Punkte beinhalten und dem Benutzer den Eindruck vermitteln, dass er weiß was ihn erwartet.</p>
+
+<p>Außerdem ist es wichtig, dass Sie Versionshinweise aktuell halten, während Sie Ihr Add-on verbessern und verändern. Benutzer sollten in der Lage sein, zu sehen, was sich bei einem Add-on gegenüber der Vorversion verändert hat, und sie sollten über Veränderungen informiert werden, die bei einem Update die Art und Weise beeinträchtigen könnten, in der sie es momentan verwenden. (Im Moment sehen Benutzer leider die Versionshinweise nicht, wenn der Browser ihr Add-on automatisch updatet, aber wir arbeiten daran, das zu korrigieren. Wenn Sie Ihre Versionshinweise gut pflegen, werden die Benutzer schon jetzt, und auch nach der entsprechenden Änderung, davon sehr profitieren.)</p>
+
+<h3>Werden alle Datenschutz- und Sicherheitsbedenken ausdrücklich behandelt?</h3>
+
+<p>Dies ist ein Teilaspekt der oben genannten "klaren Beschreibung", aber er ist so wichtig für uns, dass wir ihn besonders erwähnen. Viele sehr nützliche und gut geschriebene Add-ons bearbeiten Benutzerdaten (in welcher Form auch immer), oder sie können -- wenn sie missbraucht werden -- gefährlich sein; solche Add-ons sind auf der öffentlichten Seite von AMO willkommen, aber sie müssen es dem Benutzer gegenüber sehr klar machen, welche Risiken sie bergen könnten, und was die Benutzer tun können, um sich zu schützen.</p>
+
+<h3>Ist das Add-on gut getestet, und ist es frei von offensichtlichen oder ernsten Defekten?</h3>
+
+<p>Ein wichtiger Punkt, den wir beachten bei der Entscheidung, ob ein Add-on öffentlich werden soll, ist, ob die Bewertungen, die das Add-on im Sandkasten erhalten hat, zeigen, dass es intensiv geprüft wurde, und dass keine ernsthaften Probleme oder negative Einflüsse auf den Browser vorliegen. Wenn die Schreiber der Bewertungen von so großen Problemen berichten wie signifikante Geschwindigkeitsprobleme, sich aufhängende Software, häufige Fehler bei der Benutzung der Funktionen des Add-ons oder auch haufenweise Nachrichten in der Fehler-Konsole, dann sollten Sie sich diese Berichte zu Herzen nehmen und das Add-on erneut nominieren nachdem Sie auf diese Probleme bestmöglich eingegangen sind. Wir erwarten nicht, dass Add-ons perfekt optimiert oder völlig frei von Bugs sind -- Firefox selbst wird in diesem Bereich ständig verbessert -- aber wie möchten, dass Sie sinnvolle Anstrengungen unternehmen, um die negativen Aspekte Ihres Produktes zu minimieren, und dass Sie klar darauf hinweisen, wo Benutzer von solchen Stellen überrascht werden könnten.</p>
+
+<p>Falls Ihr Add-on außerhalb des AMO Sandkastens getestet wurde, zum Beispiel von einer Benutzergruppe Ihres Angebots oder von einem QA-Team in Ihrem Hause, dann sollten Sie das in der Nominierungsnachricht erwähnen. Das hilft uns, herauszufinden, wie intensiv ein Add-on getestet wurde und kann dabei helfen, das Add-on auf die öffentliche Seite zu bringen.</p>
+
+<h3>Behandeln das Add-on und sein Autor die Benutzer mit Respekt?</h3>
+
+<p>Ihre Software sollte dem Benutzer nicht unnötig zu Nahe treten, versuchen, ihn zu täuschen, oder irgendwelche seiner Aktivitäten vor ihm verbergen. Benutzer (oder gar Nicht-Benutzer) hinterlassen manchmal unhöfliche Kommentare, und obwohl wir unser Bestes tun, um sie herauszufiltern, wenn sie uns gemeldet werden, erwarten wir, dass Autoren davon absehen, einen ähnlich unpassenden Ton in ihren Antworten zu wählen.</p>
+
+<h3>Ist das Add-on nützlich für eine ausreichend große Gruppe von Firefox-Benutzern?</h3>
+
+<p>Ihr Add-on muss nicht das nächste "Greasemonkey" oder "Firebug" sein, aber wenn es nur für Leute in Ihrer Firma oder einen Teil einer kleinen Web-Community von Nutzen ist, halten wir es möglicherweise noch nicht für geeignet, vor allen Firefox-Benutzern veröffentlicht zu werden.</p>
+
+<p>Wir suchen dauernd nach neuen Wegen, um die Organisation unserer Webseite zu verbessern, zum Wohl von Add-ons, die trotzdem etwas Besonderes sind, obwohl sie nur auf eine kleine Benutzergruppe abzielen. Wenn Sie Ihr Add-on sorgfältig in Kategorien einsortieren und dessen Metadaten aktuell halten, hilft uns das dabei herauszufinden, wie wir mehr dieser Add-ons Benutzern nahe bringen, die am wahrscheinlichsten sind von ihnen zu profitieren.</p>
+
+<p>Wenn Ihr Add-on nur Bookmarks oder einfache Zugangspunkte zu Ihrer Webseite zur Verfügung stellt, dann ist es wahrscheinlich nicht dafür geeignet, auf der öffentlichen Seite zu erscheinen. Wie der Rest des Mozilla-Projektes lieben wir Web-Anwendungen und neue Web-Services, aber Firefox Add-ons sollten der Erfahrung des Benutzers beim Websurfen zuträglich sein, und durch seinen Eintrag auf der AMO-Webseite nicht nur als Werbung für ein neues Angebot dienen. Wenn die Beschreibung Ihres Add-ons hauptsächlich von Ihrem Angebot handelt statt auf die Verbesserungen einzugehen, die das Add-on dem Benutzer bringt, dann sind Sie wahrscheinlich nicht auf dem richtigen Weg.</p>
+
+<h3>Ist das Add-on frei von unlizensierten Marken und Urheberrechten?</h3>
+
+<p>Auch wenn Sie dem Eigentümer einer Marke oder eines urheberrechtlich geschützten Werks nicht schaden möchten, können wir keine Add-ons veröffentlichen, die Marken- oder Urheberrechte verletzen. Wenn Sie keine Erlaubnis haben, einen geschützten Namen oder ein Bild zu verwenden, dann übermitteln Sie bitte Ihr Add-on nicht an AMO. Wenn Ihr Add-on Quellcode beinhaltet, dessen Urheberrecht jemand anderes innehat, und wenn Sie keine Lizenz dafür haben, es in Ihrem Add-on zu verwenden, dann übermitteln Sie es bitte ebenfalls nicht an AMO. (Wenn der Inhaber einer Marke oder eines Urheberrechts einen Einwand dagegen erhebt, dass sein geistiges Eigentum verwendet wird, dann werden wir sehr wahrscheinlich den Antrag auf Entfernung des Add-ons von einem Rechtsbeistand betrachten lassen müssen und wenn es rechtlich geboten scheint, werden wir das Add-on entfernen. Dabei handelt es sich um einen teuren Prozess, der auf den Ressourcen des Projekts lastet (was sowohl Zeit als auch Geld betrifft) und daher bitten wir Sie, sich respektvoll zu verhalten und uns keine unnötigen Schwierigkeiten zu verschaffen.)</p>
+
+<p>Wenn Sie unsicher sind, ob der Name Ihres Add-ons oder die Verwendung von irgendetwas, was darin enthalten ist, ihr Add-on davon abhält auf der Seite gelistet zu werden, können Sie amo-editors@mozilla.org um Hilfestellung bitten. WICHTIG: Wir weisen darauf hin, dass diese Gruppe Ihnen keinen rechtlichen Rat erteilen kann, und dass wir selbst dann, wenn wir eine bestimmte Verwendung für akzeptabel halten, unsere Entscheidung revidieren können, angesichts Beschwerden von Rechteinhabern oder rechtlicher Beratung.</p>
+
+<p>Wenn Sie Quelltext von anderen Add-ons wiederverwenden wollen, aber der andere Add-on-Autor nicht ausdrücklich erlaubt hat, dass Sie seinen Code in Ihren Add-ons wiederverwenden dürfen -- zum Beispiel, indem er es unter eine Open-Source-Lizenz gestellt hat -- dann sollten Sie davon ausgehen, dass Sie es nicht dürfen. Sie können Kontakt mit dem Autor aufnehmen, um ihn nach Erlaubnis zu fragen, aber wir können Ihnen keine Sonderrechte erteilen, nur weil das Add-on auf AMO gelistet war, oder weil ein Autor nicht auf Ihre Anfrage antwortet. (Und, noch einmal, wir können Ihnen keine Rechtsberatung geben, sondern nur Hinweise darauf, wie Ihr Add-on sich wahrscheinlich gegenüber den Richtlinien dieser Webseite verhält.)</p>
+
+<p>Das alles bezieht sich genau so auch auf die Marken der Mozilla Foundation, unter anderem "Mozilla", "Firefox" und "Thunderbird". Die Richtlinie von Mozilla im Bezug auf die Verwendung seiner Marken ist dafür ausgelegt, vor Verwirrung zu schützen und die Marken aus Mangel an Schutz bedeutungslos werden zu lassen; bitte respektieren Sie die Notwendigkeit für so einen Schutz und helfen Sie uns dabei, einige der wertvollsten Gegenstände im Kapital der Mozilla Foundation zu bewahren.</p>
+
+<h2>Was passiert, wenn ich ein Add-on nominiere?</h2>
+
+<p>Wenn ein Add-on nominiert wurde, wird es von einem Team von AMO-Bearbeitern nach den oben genannten Kriterien bewertet. Wenn sich dabei ergibt, dass es für die Öffentlichkeit geeignet ist, dann wird es daraufhin auf die öffentliche Seite geschoben werden. Anschließend bekommen Sie einen Hinweis per E-Mail.</p>
+
+<p>Wenn wir denken, dass Ihr Add-on (noch) nicht für die öffentliche Seite geeignet ist, bekommen Sie eine entsprechende Mitteilung per E-Mail, die den Grund dafür enthält, und Ihre Nominierung wird aus der List entfernt. Falls und zu dem Zeitpunkt wenn Sie die in der Hinweismail geäußerten Bedenken behandelt haben, und wenn Sie erneut beurteilt werden wollen, dann steht es Ihnen frei, den Prozess erneut zu starten. Wiederholte Nominierungen ohne signifikante Verbesserungen werden aber nicht gerne gesehen, also üben Sie bitte Zurückhaltung; es ist sonst wahrscheinlicher, dass Sie uns verärgern, als dass Sie uns erweichen können.</p>
+
+<h2>Kann ich ein Add-on nominieren, das jemand anderem gehört?</h2>
+
+<p>Im Moment möchten wir, dass Add-on-Autoren ihre eigene Arbeit für die Veröffentlichung nominieren. Wir wollen sicherstellen, dass der Autor mit dem erhöhten Öffentlichkeitsdruck einverstanden ist und dass der gegenwärtige Zustand des Add-ons die Qualität ihrer Arbeit angemessen widerspiegelt. Wenn Sie glauben, dass ein Add-on in gutem Zustand ist, und dass der Autor sich an den Text und den Geist der Richtlinien von AMO hält und dass Firefox, unsere Benutzer und das Web im Allgemeinen davon profitieren würden, wenn das Add-on fast 100 Millionen Benutzern weltweit zur Verfügung stünde, dann ermutigen Sie den Add-on-Autor ruhig, sein Werk für die Veröffentlichung zu nominieren.</p>
+
+<h2>Mein Add-on ist schon lange in der Nominierungsliste, hassen Sie mich?</h2>
+
+<p>Wir hassen Sie nicht. Wir lieben Add-on-Entwickler, und wir arbeiten hart um sie glücklich und produktiv zu machen, sodass ihre Arbeit Benutzern überall auf der Welt zugute kommt. Aber auf der öffentlichen Seite von AMO zu sein hat nur daher einen Vorteil, weil wir gewissenhaft entscheiden was dorthin gelangt, und darum können wir nicht übereilt entscheiden, nur damit es schneller geht. Wir wissen, dass es frustrierend sein kann, wenn Sie lange auf die Überprüfung Ihres Add-ons warten müssen, und wir wollen die Zeit bis zur Rückmeldung so kurz wie möglich halten. Je mehr Leute gewissenhafte und und klare Bewertungen von Add-ons im Sandkasten beitragen, desto einfacher ist es, diese Überprüfungen zu machen, also möglicherweise möchten Sie uns auch an dieser Stelle aushelfen.</p>
+
+<h2>Ich habe einen nennenswerten Fehler in meinem Add-on gefunden und ich möchte die korrigierte Version so schnell wie möglich verfügbar machen. Was soll ich tun?</h2>
+
+<p>Wenn es um einen ernsten Bug geht (Sicherheits-, Stabilitäts- oder große Funktionalitätsprobleme) in einem Add-on, für den Sie so schnell wie möglich ein Update veröffentlichen müssen, dann sollten Sie das in der Nachricht an den Bearbeiter vermerken, wenn Sie das Update hochladen -- und natürlich auch in den Versionshinweisen! Gegebenenfalls sollten Sie auch ein paar Ihrer gegenwärtigen Benutzer bitten, das Update zu installieren und zu testen, und ihre Ergebnisse im Sandkasten zu veröffentlichen. Wenn Sie in #addons auf irc.mozilla.org vorbeischauen, können Sie auf Ihre Situation aufmerksam machen; aber seien Sie bitte geduldig und höflich, wenn Sie das tun.</p>
+
+<p>Bitte schlagen Sie keinen falschen Alarm. Wir bemühen uns, Updates mit hoher Priorität schnell durchzuführen, aber es kostet uns Zeit, andere nominierte Add-ons oder Versionen zu prüfen, und oft kostet es uns sogar Schlaf oder Zeit, die wir mit unseren Familien und Freunden verbringen würden, und daher ist es nicht gerne gesehen, wenn Leute diesen Mechanismus missbrauchen, um sich "vorzudrängeln". Wenn Sie unsicher sind, ob Sie diesen Weg einschlagen sollten, dann kann es bei Ihrer Entscheidung helfen, in #addons auf irc.mozilla.org nachzufragen.</p>
+
+<h2>Ich denke, dass ich bei der Bewertung meines Add-ons unfair behandelt wurde. Was soll ich tun?</h2>
+
+<p>Wenn Sie denken, dass Ihr Add-on nicht korrekt bewertet wurde, und dass es zu Unrecht nicht den öffentlichen Status erhalten hat, dann sollten Sie eine E-Mail an amo-editors@mozilla.org mit Ihrer Argumentation senden. Bitte seien Sie höflich und formulieren Sie Ihre E-Mail klar, und stellen Sie sicher, dass Sie deutlich machen, in welchen Punkten Ihr Add-on falsch bewertet wurde.</p>
+
+<p>(Wenn Sie *alle* Dinge behandelt haben, die in Ihrer Hinweis-Mail als Probleme aufgelistet waren, dann sollten Sie sich nicht über die Bewertung beschweren, sondern stattdessen das Add-on erneut in den Entwickler-Werkzeugen für eine Veröffentlichung nominieren.)</p>
+
+<h2>Mein Add-on war einmal öffentlich, jetzt ist es aber im Sandkasten. Was ist passiert?</h2>
+
+<p>Wenn ein Add-on nicht mehr länger die Kriterien für ein öffentliches Add-on erfüllt, dann wird es zurück in den Sandkasten geschoben. Außer wenn wir per Gesetz daran gehindert sind, Sie davon zu informieren, werden wir Ihnen eine E-Mail senden wenn das passiert, und Ihnen die Gründe dafür mitteilen.</p>
+
+<p>Es ist auch möglich, dass Sie einen Bug in der Webseite entdeckt haben; in diesem Fall sollten Sie uns davon mittels Bugzilla berichten (bugzilla.mozilla.org): Wählen Sie das Produkt "addons.mozilla.org" und die Komponente "Public Pages" und seien sie so spezifisch wie möglich.</p>
+
+<h2>Mein Add-on ist öffentlich, und die Leute scheinen es zu mögen. Wie kann ich in die Liste der empfohlenen Add-ons kommen?</h2>
+
+<p>Wenn Sie denken, dass Ihr Add-on ein glänzendes Beispiel für die Möglichkeiten von Add-ons ist, und dass es Mozillas Werte für ein erweiterbares und benutzer-kontrolliertes Web widerspiegelt und erweitert, und wenn es für den Benutzer außerdem eine großartige Erfahrung darstellt, dann können Sie darum bitten, es auf der Liste empfohlener Add-ons unterzubringen. Dafür sollten Sie eine E-Mail an amo-editors@mozilla.org senden, in der Sie erklären, warum Ihr Add-on ganz großartig ist.</p>
+
+<p>Ihre E-Mail sollte <b>mindestens</b> die folgenden Informationen enthalten:</p>
+<ul>
+<li>wie das Add-on die Verwendung des Webs für die Benutzer verbessert</li>
+<li>inwiefern das Add-on dazu geeignet ist, von einem Großteil der Firefox-Bentzer verwendet zu werden</li>
+<li>wie das Add-on für die Werte des Mozilla-Projektes steht und/oder wie es diesen dient, besonders was es betrifft, den Benutzer wichtige Dinge entscheiden zu lassen, seine Daten zu schützen und das Web sicherer zu machen, den Zugang zum Web zu vereinfachen, sowie die Förderung offener Standards und Informationen</li>
+<li>wie sich Ihr Add-on von anderen, ähnlichen Add-ons unterscheidet (und zwar zum Positiven wie auch Negativen)</li>
+<li>welche Reaktionen Ihnen entgegengebracht wurden, sei es von Benutzern, Bearbeitern, Bloggern, Astronauten oder Ihrem heimischen Haustier (wiederum: positive wie negative)</li>
+</ul>
+
+<p>Je vollständiger die Information ist, die Sie uns in Ihrer Anfrage geben, um so zugänglicher werden wir sein, um der Bitte nachzugeben, obwohl auch eine ganz wundervoll geschriebene und vollständige Anwendung keine Garantie ist, auf die Liste empfohlener Add-ons zu gelangen. Unter dem Strich muss die Zusammenstellung eben von Mozilla gebildet und aktualisiert werden (und das wird sie auch), und die Benutzererfahrung und der -schutz müssen alles andere in den Schatten stellen.</p>
diff --git a/site/app/locale/de/pages/reviewguide.thtml b/site/app/locale/de/pages/reviewguide.thtml
new file mode 100644
index 0000000..cb08408
--- /dev/null
+++ b/site/app/locale/de/pages/reviewguide.thtml
@@ -0,0 +1,109 @@
+<h1>Richtlinien für Bewertungen</h1>
+<p>Add-on-Bewertungen sind eine Möglichkeit für Benutzer der Add-ons-Seite,
+ihre Meinungen über Add-ons auszutauschen, die sie installiert und benutzt
+haben. Moderatoren haben das Recht, jede Bewertung abzuweisen oder zu entfernen,
+die nicht diesen Richtlinien entspricht.</p>
+
+<div class="corner-box">
+ <h2>Ein paar Tips, um großartige Bewertungen zu schreiben</h2>
+
+<h3><b>Was Sie tun sollten:</b></h3>
+<ul>
+<li>Schreiben Sie, als ob Sie einem Freund von Ihrer Erfahrung mit dem Add-on erzählen.</li>
+<li>Fassen Sie sich kurz und schreiben Sie leicht verständliche Sätze.<li>
+<li>Führen Sie genaue und hilfreiche Details an. Zum Beispiel:
+<ul>
+ <li>Hat das Add-on funktioniert, wie Sie es erwartet haben?</li>
+ <li>Welche Funktionen haben Ihnen gefallen, welche nicht?</li>
+ <li>War es nützlich?</li>
+ <li>War es leicht zu verwenden?</li>
+ <li>Werden Sie das Add-on weiterhin verwenden?</li>
+</ul></li>
+
+<li>Nehmen Sie sich einen Moment Zeit, Ihre Bewertung noch einmal zu lesen, bevor
+Sie sie abschicken, um peinliche Tippfehler oder Grammatikfehler zu vermeiden.</li>
+
+<li>Vermeiden Sie, sich auf aktuelle oder kurzzeitige Dinge/Ereignisse zu beziehen,
+weil Bewertungen sehr lange auf der Seite bleiben werden.</li>
+</ul>
+
+<h3><b>Was Sie <strong>nicht</strong> tun sollten:</b></h3>
+<ul>
+<li>Einfache Bewertungen vergeben, wie "großartig!", "wundervoll", oder "schlecht",
+ohne diese genauer zu erklären.</li>
+<li>Problembeschreibungen in Bewertungen schreiben. Verwenden Sie stattdessen die
+für das jeweilige Add-on verfügbaren Hilfe-Optionen.</li>
+<li>Bewertungen für Add-ons abgeben, die Sie nicht selbst verwendet haben.</li>
+<li>Schimpfworte verwenden, sexuell geprägte Sprache, oder Worte, die als hasserfüllt
+interpretiert werden können.</li>
+<li>HTML verwenden, Links zu schädlicher Software, Quellcode oder Ähnlichem setzen.
+Bewertungen sollen nur aus Text bestehen.</li>
+<li>Falsche Behauptungen aufstellen, Add-on-Autoren verleumden oder sie persönlich
+angreifen.</li>
+<li>Bewertungen verwenden, um Hilfe für eine bestimmte Firefox-Version (oder andere
+Software) zu erhalten.</li>
+<li>Ihre E-Mail, Telefonnummer, oder andere persönliche Daten veröffentlichen.</li>
+<li>Bewertungen für ein Add-on hinterlassen, das von Ihnen oder Ihrer Organisation
+geschrieben oder unterstützt wird.</li>
+</ul>
+</div>
+
+<div class="corner-box">
+ <h2>Richtlinien zur Notengebung</h2>
+
+<p>Die Noten für Add-ons sollen Fair sein und einen guten Überblick darüber geben,
+was die Qualität und Nützlichkeit eines jeden Add-ons angeht. Geben Sie einem Add-on
+nicht einfach 5 Sterne wenn Sie es mögen, oder 1 Stern, wenn es nicht leiden
+können. Eine gut durchdachte Note zu geben ist ein wichtiger Teil der Bewertung.</p>
+
+<ul>
+<li><b>5 Sterne: Ausgezeichnet.</b> Das Add-on macht nicht nur all das, was es
+tun soll, sondern es ist auch deutlich hilfreicher als andere Add-ons. Dieses
+Add-on werden Sie sehr wahrscheinlich recht häufig benutzen, und Sie würden es
+absolut weiterempfehlen.</li>
+<li><b>4 Sterne: Gut.</b> Nützlich und leicht zu verwenden, aber nicht notwendig
+außergewöhnlich. Dieses Add-on empfehlen Sie weiter, aber es könnte für manche
+Leute hilfreicher sein als für andere.</li>
+<li><b>3 Sterne: Passabel.</b> Könnte ein paar Design-Probleme aufweisen, oder
+ein paar Funktionen vermissen lassen. Diese Probleme sind aber nicht schwerwiegend
+genug, um von der Verwendung abzuraten, und manche Leute könnten es trotzdem
+benutzen wollen. Empfohlen für diejenigen, die es benötigen und es daher einmal
+ausprobieren möchten.</li>
+<li><b>2 Sterne: Schwach.</b> Das Add-on hat eine geringe Qualität, ist nur
+eingeschränkt verwendbar, oder es tut schlicht nicht das, was es zu tun verspricht.
+Sie raten davon ab, dieses Add-on zu verwenden, aber für manche Leute könnte es
+doch noch einen gewissen Wert haben.</li>
+<li><b>1 Stern: Schlecht.</b> Das Add-on funktioniert entweder nicht richtig,
+oder es ist völlig nutzlos. Sie können sich nicht vorstellen, warum irgendjemand
+es jemals verwenden sollte, und Sie schlagen vor, dass man sich komplett von ihm
+fernhält.</li>
+</ul>
+
+<p>Es ist vollkommen in Ordnung, einem Add-on eine perfekte oder schreckliche
+Bewertung zu geben, solange Sie nur sagen, warum Sie es tun. Die Sterne bedeuten
+nichts, wenn Sie uns nicht sagen, warum Sie dieser Meinung sind.</p>
+</div>
+
+<div class="corner-box">
+ <h2>Häufige Fragen über Bewertungen</h2>
+
+<h3>Wie kann ich auf eine problematische Bewertung aufmerksam machen?</h3>
+<p>Bitte markieren Sie fragwürdige Bewertungen, indem Sie auf "diese Bewertung
+als unpassend markieren" klicken; dann wird diese Bewertung einem Moderator
+zur Überprüfung vorgelegt. Die Moderatoren werden die Richtlinien für Bwertungen
+verwenden, um zu entscheiden, ob diese Bewertung dann gelöscht oder zurück auf
+die Seite geschickt wird.</p>
+
+<h3>Ich bin ein Add-on-Autor, kann ich auf Bewertungen antworten?</h3>
+<p>Ja, Add-on-Autoren können auf Bewertungen ein einziges mal antworten. Weitere
+Diskussionen sollten dann in einem Support-Forum oder einer Diskussionsgruppe
+stattfinden.</p>
+
+<h3>Ich bn ein Add-on-Autor, kann ich unerwünschte Bewertungen löschen?</h3>
+<p>Im allgemeinen, nein. Falls, aber die Bewertung gegen die Richtlinien verstößt,
+können Sie auf den "als unpassend markieren" Link klicken, damit ein Moderator
+sich die Bewertung ansieht. Falls die Bewertung eine Beschwerde enthält, die in
+der aktuellen Version des Add-ons nicht mehr stimmt, könnten wir sie unter
+Umständen ebenfalls entfernen. Senden Sie in diesem Fall eine detaillierte Anfrage
+(vorzugsweise auf englisch) an amo-editors@mozilla.org.</p>
+</div>
diff --git a/site/app/locale/de/pages/sandbox.thtml b/site/app/locale/de/pages/sandbox.thtml
new file mode 100644
index 0000000..116f3d7
--- /dev/null
+++ b/site/app/locale/de/pages/sandbox.thtml
@@ -0,0 +1,13 @@
+<h1>Das "Sandkasten"-System zur Überprüfung von Add-ons</h1>
+<h2>Was ist der Sandkasten?</h2>
+<p>Der so genannte "Sandkasten" ist ein Bereich auf der Add-ons-Webseite, der fortgeschrittenen Benutzern ermöglicht, Add-ons zu testen, bevor sie für die Verwendung durch die Öffentlichkeit freigegeben wurden. Um auf den Sandkasten zugreifen zu können, müssen Sie diese Funktion in Ihren Benutzereinstellungen aktivieren. Bei der Installation von Add-ons aus dem Sandkasten sollten Sie vorsichtig sein: Sie wurden noch nicht von einem Bearbeiter überprüft und könnten daher möglicherweise schädlichen Code enthalten.</p>
+
+<h2>Was kann ich tun, damit mein Add-on auf der öffentlichen Seite angezeigt wird?</h2>
+<!-- To localize the flowchart image, see http://wiki.mozilla.org/Update:Remora_Sandbox_Flowchart -->
+<div style="text-align: center;">%s</div>
+<ol>
+ <li><b>Laden Sie Ihr Add-on über die Entwickler-Tools hoch.</b> Es wird sofort auf der Add-ons-"Sandkasten"-Seite erscheinen, wo erfahrene Benutzer es ausprobieren und Kommentare dazu abgeben können. InUm den Sandkasten zu sehen, müssen Sie diese Funktion in Ihren Benutzereinstellungen aktivieren.</li>
+ <li><b>Merken Sie Ihr Add-on für die Veröffentlichung vor.</b> In den Entwickler-Tools finden Sie einen Link, um Ihr Add-on für die Veröffentlichung vorzumerken. Wenn Sie es vorgemerkt haben, wird es in der Bearbeiter-Liste zur Überprüfung erscheinen.</li>
+ <li><b>Ein Bearbeiter überprüft Ihr Add-on.</b> Ein Bearbeiter von Mozilla-Add-ons wird Ihre Add-on installieren und prüfen, ob es funktioniert. Der Bearbeiter wird sich auch die Kommentare ansehen, die Benutzer des "Sandkastens" über Ihre Add-on hinterlassen haben.</li>
+ <li><b>Ihr Add-on wird veröffentlicht oder verbleibt im "Sandkasten".</b> Der Bearbeiter wird entscheiden, Ihr Add-on entweder auf die öffentliche Seite zu schieben, oder es im Sandkasten zu lassen. Wenn es im Sandkasten bleibt, dann können Sie es erneut für eine Veröffentlichung vormerken, nachdem Sie die Veränderungen gemacht haben, die der Bearbeiter in seinen Kommentaren vorgeschlagen hat. Wenn das Add-on veröffentlicht wird, werden zukünftige Versionen des Add-ons im Sandkasten verweilen, bis sie von einem Bearbeiter überprüft und veröffentlicht werden. Sobald Ihr Add-on öffentlich ist, müssen Sie es nicht mehr zur Freischaltung vormerken -- zukünftige Versionen werden den Bearbeitern automatisch in der Überprüfungsliste angezeigt.</li>
+</ol>
diff --git a/site/app/locale/de/pages/submission_help.thtml b/site/app/locale/de/pages/submission_help.thtml
new file mode 100644
index 0000000..fbb73e3
--- /dev/null
+++ b/site/app/locale/de/pages/submission_help.thtml
@@ -0,0 +1,35 @@
+<h1>Hilfe beim Hochladen von Add-ons</h1>
+Benötigte Felder sind <b>fett</b> dargestellt. Optionale Felder sind <i>kursiv</i>.
+<h2 id="step1">Step 1: Hochladen</h2>
+<ul class="submissionHelp">
+ <li><span class="required">Add-on-Typ</span> - In der Standardeinstellung wird der Add-on-Typ automatisch aus der hochgeladenen Datei bestimmt. Eine Änderung diese Feldes sollte nicht nötig sein.</li>
+ <li><span class="required">Add-on-Datei</span> - Die Datei, welche das Add-on enthält, einschließlich der Datei install.rdf. Falls die Datei nur unter einem Betriebssystemtyp läuft (z. B. Linux), so ermöglicht die Auswahl eines bestimmten Betriebssystemtyps das Hochladen mehrerer Datei auf einmal.</li>
+ <li><span class="optional">Symboldatei</span> - Die Symboldatei wird neben dem Add-on-Namen auf der Detailseite sowie im Installationsdialog angezeigt. Sie wird automatisch auf 32x32 Pixel unter Beibehaltung des Seitenverhältnisses angepasst.</li>
+ <li><span class="required">Standardlokalisierung</span> - Die Standardlokalisierung eines Add-ons it die Hauptlokalisierung, das heißt, dass wenn ein Benutzer mit einer Lokalisierung, die für das Add-on nicht verfügbar ist, die Add-on-Seite besucht, so wird die Standardlokalisierung verwendet.</li>
+ <li><span class="optional">Die Überarbeitung meiner derzeitigen Add-on-Informationen überspringen</span> - Beim Aktualisieren eines existierenden Add-ons wird dieses Feld erscheinen. Durch das aktivieren dieser Option können Sie zu Schritt 3 übergehen, wo Sie die versionsbezogenen Informationen eingeben.</li>
+</ul>
+
+<h2 id="step2">Step 2: Add-on-Details</h2>
+<ul class="submissionHelp">
+ <li><span class="required">Name</span> - Name des Add-ons in der Standardlokalisierung.</li>
+ <li><span class="required">Entwickler</span> - Alle Entwickler, die die Auflistung dieser Version verändern können und als Entwickler auf der Detailseite aufgeführt werden.</li>
+ <li><span class="required">Kategorien</span> - Auf das Add-on zutreffende Kategorien.</li>
+ <li><span class="optional">Homepage</span> - Die Homepage des Add-ons für die Standardlokalisierung.</li>
+ <li><span class="required">Zusammenfassung</span> - Eine kurze Zusammenfassung des Add-ons in der Standardlokalisierung. Dieses Feld hat eine Maximallänge von 250 Zeichen und erscheint sowohl auf der Detailseite als auch in den Suchergebnissen.</li>
+ <li><span class="required">Beschreibung</span> - Eine Beschreibung des Add-ons in der Standardlokalisierung. Dies erscheint unter der Zusammenfassung des Add-ons auf der Detailseite.</li>
+ <li><span class="optional">EULA</span> - Der Endbenutzer-Lizenzvertrag, den Nutzern vor dem Herunterladen akzeptieren müssen, in der Standardlokalisierung.</li>
+ <li><span class="optional">Datenschutzerklärung</span> - Die Datenschutzerklärung des Add-ons in der Standardlokalisierung. Die Datenschutzerklärung informiert den Benutzer über den Umgang mit seinen Daten und befindet sich neben der Installationsschaltfläche auf der Detailseite des Add-ons. Zusätzliche Informationen, was die Datenschutzerklärung enthalten muss und ob Ihr Add-on eine benötigt, finden Sie in unserer <a href="%s">Add-on Richtlinie</a>.</li>
+ <li><span class="optional">Den Benutzern das Betrachten des Quelltextes online erlauben</span> - Die Aktivierung dieses Feldes erlaubt den Benutzern den Quelltext Ihres Add-ons online zu betrachten.</li>
+ <li><span class="optional">Dies ist keine Endversion</span> - Mit der Aktivierung dieser Option kennzeichnen Sie diese Datei als Vorab- oder Beta-Version. Vorabversionen sollten im Sandkasten verbleiben und können nicht für die öffentlichen Seiten nominiert werden, bis diese Eigenschaft entfernt wurde.</li>
+ <li><span class="optional">Dies ist ein seitenabhängiges Add-on</span> - Durch Aktivierung dieser Einstellung informieren Sie den Nutzer darüber, dass Ihr Add-on für eine bestimmte Seite bestimmt ist, z. B. das Aussehen einer bestimmten Seite ändert oder von dieser Inhalt wiedergibt. Diese Option hilft Moderatoren und könnte in Zukunft nützlich sein, um Suchen einzuschränken.</li>
+ <li><span class="optional">Dieses Add-on benötigt externe Software.</span> - Mittels dieser Option wird angezeigt, dass die Erweiterung zusätzlich externe Software benötigt. Diese Option hilft Moderatoren und könnte in Zukunft nützlich sein, um Suchen einzuschränken.</li>
+</ul>
+
+<h2 id="step3">Schritt 3: Versionsdetails</h2>
+<ul class="submissionHelp">
+ <li><span class="required optional">Versionshinweise</span> - Eine Zusammenfassung oder Liste der Änderungen in dieser Version. Für erstmalig übermittelte Add-ons ist dies freiwillig, für Aktualisierungen dagegen verpflichtend.</li>
+ <li><span class="optional">Hinweise an die Moderatoren</span> - Dieses Feld dient zur Übermittelung von Nachrichten an die Moderatoren, welche das Add-on testen werden. Informationen zu Testkonten und spezielle Hinweise gehören hier hinein.</li>
+</ul>
+
+<h2 id="step4">Schritt 4: Lokalisierung</h2>
+An dieser Stelle können die Felder über das Add-on in allen unterstützten Sprachen lokalisieren. Klicken Sie einfach auf die entsprechende Lokalisierung, um die Übersetzung einzufügen.
diff --git a/site/app/locale/el/LC_MESSAGES/messages.mo b/site/app/locale/el/LC_MESSAGES/messages.mo
new file mode 100644
index 0000000..ec2413e
--- /dev/null
+++ b/site/app/locale/el/LC_MESSAGES/messages.mo
Binary files differ
diff --git a/site/app/locale/el/LC_MESSAGES/messages.po b/site/app/locale/el/LC_MESSAGES/messages.po
new file mode 100644
index 0000000..43a0fe2
--- /dev/null
+++ b/site/app/locale/el/LC_MESSAGES/messages.po
@@ -0,0 +1,7239 @@
+msgid ""
+msgstr ""
+"Project-Id-Version: REMORA 0.1\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2009-01-16 11:45-0800\n"
+"PO-Revision-Date: 2009-06-08 17:52+0200\n"
+"Last-Translator: ΓιώÏγος Φιωτάκης <fiotakis@otenet.gr>\n"
+"Language-Team: el-GR <LL@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=n != 1;\n"
+"X-Poedit-Country: GREECE\n"
+"X-Poedit-Language: Greek\n"
+
+#: views/addons/policy.thtml:98
+msgid "a_cancel_installation"
+msgstr "ΑκÏÏωση εγκατάστασης"
+
+#. This is the text that appears on buttons to download add-ons.
+#. %$1s is an optional string that only appears if the add-on is only available for
+#. a certain platform. Examples: (Windows) or (Linux)
+#. Note that the parentheses are included in the string. :(
+#: views/elements/amo2009/install.thtml:126
+#: views/elements/amo2009/install.thtml:227
+#: views/elements/amo2009/install.thtml:257
+#: views/elements/amo2009/install.thtml:300
+#: views/elements/amo2009/install.thtml:312
+#: views/elements/install.thtml:73
+#: views/elements/install.thtml:181
+#: views/elements/install.thtml:205
+#: views/elements/install.thtml:248
+#: views/elements/install.thtml:260
+#: views/addons/plugins.thtml:66
+#: views/addons/plugins.thtml:76
+#: views/addons/plugins.thtml:86
+#: views/addons/plugins.thtml:96
+#: views/addons/plugins.thtml:119
+#, php-format
+msgid "a_download"
+msgstr "Λήψη Ï„ÏŽÏα %s"
+
+#: views/addons/policy.thtml:72
+msgid "a_eula_download"
+msgstr "Αποδοχή και λήψη"
+
+#: views/addons/policy.thtml:74
+msgid "a_eula_install"
+msgstr "Αποδοχή κι εγκατάσταση"
+
+#: views/elements/header.thtml:76
+#: views/elements/header.thtml:82
+#: views/api/api_addon.thtml:55
+#: views/api/collections_feed.thtml:75
+#: views/sharing_api/addon.thtml:64
+msgid "a_header_public"
+msgstr "Δημόσιος χώÏος"
+
+#: views/elements/header.thtml:58
+#: views/elements/header.thtml:75
+#: views/elements/header.thtml:80
+#: views/api/api_addon.thtml:57
+#: views/api/collections_feed.thtml:77
+#: views/sharing_api/addon.thtml:66
+msgid "a_header_sandbox"
+msgstr "Sandbox"
+
+#. %s is a date in the _('date') format
+#: views/elements/amo2009/homepage_addon.thtml:115
+#: views/elements/addon_listitem.thtml:122
+#: views/elements/feature.thtml:106
+#: views/addons/display.thtml:104
+#: views/addons/browse_thumbs.thtml:73
+msgid "addon_detail_last_updated"
+msgstr "ΕνημεÏώθηκε %s"
+
+#. %s is the version of the add-on. Example: 3.2a1
+#: views/elements/amo2009/addon_version_detail.thtml:51
+#: views/elements/addon_version_detail.thtml:51
+#, php-format
+msgid "addon_display_header_version"
+msgstr "Έκδοση %s"
+
+#: views/addons/browse_thumbs.thtml:80
+msgid "addon_downloads"
+msgstr "λήψεις"
+
+#: views/addons/display.thtml:147
+msgid "addon_downloads_total"
+msgstr "συνολικές λήψεις"
+
+#: views/elements/amo2009/homepage_addon.thtml:106
+#: views/elements/addon_listitem.thtml:115
+#: views/elements/feature.thtml:101
+#: views/addons/category_landing.thtml:157
+#: views/addons/display.thtml:146
+#: views/addons/browse_thumbs.thtml:80
+msgid "addon_downloads_weekly"
+msgstr "εβδομαδιαίες λήψεις"
+
+# %1 is the add-on count, %2 the category name
+#. %1 is the add-on count, %2 the category name
+#: views/addons/browse_thumbs.thtml:104
+#: views/addons/browse.thtml:60
+#, php-format
+msgid "addon_list_category_totalcount"
+msgid_plural "addon_list_category_totalcount"
+msgstr[0] "%1$s Ï€Ïόσθετο"
+msgstr[1] "%1$s Ï€Ïόσθετα"
+
+#: views/elements/amo2009/addon_list_options.thtml:103
+#: views/elements/pagination.thtml:67
+#: views/elements/addon_list_options.thtml:94
+msgid "addon_list_perpage"
+msgstr "ανά σελίδα"
+
+#: views/elements/amo2009/addon_list_options.thtml:84
+#: views/elements/addon_list_options.thtml:98
+msgid "addon_list_sortby"
+msgstr "Ταξινόμηση κατά :"
+
+#: views/helpers/addons_html.php:568
+#: views/elements/amo2009/install.thtml:321
+#: views/elements/feature.thtml:89
+msgid "addon_listitem_flag_experimental"
+msgstr "πειÏαματικό"
+
+#: views/helpers/addons_html.php:570
+msgid "addon_listitem_flag_recommended"
+msgstr "συνιστάται"
+
+# %1 is the addon name, %2 is the platform
+#. %1 is the add-on name, %2 is the platform
+#: views/pages/js_constants.js.thtml:66
+msgid "addon_not_available_for_platform"
+msgstr "Δεν είναι διαθέσιμο το %1$s για %2$s."
+
+# %1 is the addon name
+#. %1 is the add-on name
+#: views/addons/policy.thtml:101
+#: views/addons/previews.thtml:60
+#: views/addons/versions.thtml:130
+#: views/reviews/flag.thtml:61
+#: views/reviews/add.thtml:114
+#: views/reviews/display.thtml:216
+#: views/reviews/review_added.thtml:57
+#, php-format
+msgid "addon_review_a_back_to_addon_x"
+msgstr "Πίσω στο %1$s..."
+
+# %1 is the addon name
+#. %1 is the add-on name
+#: views/reviews/flag.thtml:60
+#: views/reviews/add.thtml:113
+#: views/reviews/review_added.thtml:56
+#, php-format
+msgid "addon_review_a_back_to_reviews"
+msgstr "Πίσω στις αξιολογήσεις..."
+
+#: views/reviews/add.thtml:85
+msgid "addon_review_add_rating_field"
+msgstr "Βαθμολογία:"
+
+#: views/reviews/add.thtml:102
+msgid "addon_review_add_review_field"
+msgstr "Αξιολόγηση:"
+
+#: views/reviews/add.thtml:107
+msgid "addon_review_add_submit"
+msgstr "Υποβολή αξιολόγησης"
+
+#. %s is the name of the add-on
+#: views/reviews/add.thtml:51
+#, php-format
+msgid "addon_review_add_title"
+msgstr "ΠÏοσθήκη αξιολόγησης για το %s"
+
+#: views/reviews/add.thtml:78
+msgid "addon_review_add_title_field"
+msgstr "Τίτλος/πεÏίληψη:"
+
+#: views/reviews/display.thtml:77
+#: views/reviews/display.thtml:161
+msgid "addon_review_admin_delete"
+msgstr "ΔιαγÏαφή"
+
+#: views/reviews/display.thtml:76
+msgid "addon_review_author_reply_link"
+msgstr "Απάντηση"
+
+#: views/reviews/delete.thtml:62
+msgid "addon_review_confirm_delete"
+msgstr "Θέλετε να διαγÏάψετε την αξιολόγηση;"
+
+#: views/reviews/delete.thtml:63
+msgid "addon_review_confirm_no"
+msgstr "Όχι"
+
+#: views/reviews/delete.thtml:64
+msgid "addon_review_confirm_yes"
+msgstr "Îαι"
+
+#: views/reviews/delete.thtml:48
+msgid "addon_review_delete_header"
+msgstr "ΔιαγÏαφή αξιολόγησης"
+
+#: controllers/reviews_controller.php:449
+msgid "addon_review_deleted_successfully"
+msgstr "ΔιαγÏάφτηκε με επιτυχία η αξιολόγηση."
+
+#. %s is the name of the add-on
+#: views/reviews/add.thtml:51
+#, php-format
+msgid "addon_review_edit_title"
+msgstr "ΕπεξεÏγασία αξιολόγησης για το %s"
+
+# %1 is the count of characters entered as notes for the review flag reason.
+#. %1 is the count of characters entered as notes for the review flag reason.
+#: controllers/reviews_controller.php:539
+msgid "addon_review_flag_error_other_length"
+msgstr "Σφάλμα αναφοÏάς αξιολόγησης: Οι σημειώσεις αναφοÏάς αξιολόγησης θα Ï€Ïέπει να έχουν μήκος από 10 εως 100 χαÏακτήÏες. Το μήκος της σημείωσης σας ήταν %1$s χαÏακτήÏες."
+
+#. Removing an extra comma
+#: views/reviews/review_added.thtml:53
+msgid "addon_review_in_moderation"
+msgstr "Σημείωση: ΠÏιν εμφανιστεί στο κοινό, η αξιολόγησή σας θα επεξεÏγαστεί από κάποιον συντάκτη μας."
+
+#: views/reviews/add.thtml:57
+msgid "addon_review_in_reply_to"
+msgstr "Απάντηση δημιουÏÎ³Î¿Ï Ï€Ïος:"
+
+# %1 is the review count, %2 is the nickname or full name of the user.
+#. %1 is the review count, %2 is the nickname or full name of the user.
+#: views/reviews/display.thtml:131
+#, php-format
+msgid "addon_review_others_by_user"
+msgid_plural "addon_review_others_by_user"
+msgstr[0] "Δείτε τη %1$s παλιότεÏη αξιολόγηση του χÏήστη %2$s για το Ï€Ïόσθετο."
+msgstr[1] "Δείτε τις %1$s παλιότεÏες αξιολογήσεις του χÏήστη %2$s για το Ï€Ïόσθετο."
+
+# %1 is the addon name
+#. %1 is the add-on name
+#: controllers/reviews_controller.php:201
+#: controllers/reviews_controller.php:250
+#: controllers/reviews_controller.php:345
+#: controllers/reviews_controller.php:424
+#, php-format
+msgid "addon_review_pagetitle"
+msgstr "Αξιολογήσεις για το %s"
+
+# %1 is the user, %2 is the (localized) date
+#. %1 is the user, %2 is the (localized) date
+#: views/reviews/display.thtml:160
+#, php-format
+msgid "addon_review_reply_on_x_by_y"
+msgstr "Απάντηση από %1$s την %2$s"
+
+#: views/reviews/display.thtml:157
+msgid "addon_review_reply_prefix"
+msgstr "Απάντηση δημιουÏγοÏ:"
+
+#: views/reviews/review_added.thtml:51
+msgid "addon_review_saved_successfully"
+msgstr "ΕυχαÏιστοÏμε! η αξιολόγησή σας αποθηκεÏθηκε με επιτυχία"
+
+#: views/addons/display.thtml:354
+#: views/reviews/display.thtml:72
+msgid "addon_reviewed_by_u_on_d"
+msgstr "από %1$s την %2$s"
+
+# %1 is the user, %2 is the (localized) date, %3 is the rating
+#. %1 is the user, %2 is the (localized) date, %3 is the rating
+#: views/editors/reviews_queue.thtml:57
+#: views/editors/reviews_queue.thtml:68
+#: views/reviews/add.thtml:63
+#: views/reviews/delete.thtml:54
+#, php-format
+msgid "addon_reviewed_on_x_rated_y"
+msgstr "από το χÏήστη %1$s στις %2$s (βαθμολόγηση %3$s)"
+
+#: views/elements/amo2009/addon_version_detail.thtml:52
+#: views/elements/addon_version_detail.thtml:52
+msgid "addon_version_permalink"
+msgstr "Μόνιμος δεσμός αυτής της έκδοσης."
+
+# %1 is the current Application name (e.g. Firefox)
+# %2 is the Application's version number
+#. %1 is the current Application name (e.g. Firefox)
+#. %2 is the Application's version number
+#: views/addons/versions.thtml:140
+msgid "addon_versions_getlatestversion"
+msgstr "Η πιο Ï€Ïόσφατη συμβατή έκδοση με τον %1$s %2$s"
+
+#: views/addons/display.thtml:447
+msgid "addons_author_addons_submit"
+msgstr "Μετάβαση"
+
+#: views/elements/amo2009/homepage_addon.thtml:100
+#: views/elements/feature.thtml:95
+msgid "addons_author_tooltip"
+msgstr "Εμφάνιση Ï€Ïοφίλ δημιουÏγοÏ"
+
+# %1 is the name of the Application (eg. Firefox)
+#. %1 is the name of the Application (eg. Firefox)
+#: controllers/addons_controller.php:1296
+msgid "addons_browse_all_themes_title"
+msgstr "ΠεÏιήγηση σε όλα τα θέματα :: ΠÏόσθετα %1$s"
+
+#. %s is the name of the category
+#: controllers/addons_controller.php:1016
+#, php-format
+msgid "addons_browse_browse_category"
+msgstr "ΠεÏιήγηση σε %s"
+
+# %1 is the name of the theme category (eg. Modern)
+# %2 is the name of the Application (eg. Firefox)
+#. %1 is the name of the theme category (eg. Modern)
+#. %2 is the name of the Application (eg. Firefox)
+#: controllers/addons_controller.php:664
+msgid "addons_browse_categories_header_theme"
+msgstr "ΠεÏιήγηση σε θέματα: %1$s :: ΠÏόσθετα %2$s"
+
+#: views/addons/display.thtml:249
+msgid "addons_display_a_license_what"
+msgstr "Τι είναι αυτό;"
+
+#: views/reviews/display.thtml:222
+msgid "addons_display_add_review"
+msgstr "ΠÏοσθήκη αξιολόγησης"
+
+#: views/addons/display.thtml:294
+msgid "addons_display_advanced_details"
+msgstr "Αναλυτικές λεπτομέÏειες"
+
+#: views/addons/display.thtml:98
+msgid "addons_display_categories"
+msgstr "ΚατηγοÏίες"
+
+#: views/addons/display.thtml:482
+msgid "addons_display_collection_add"
+msgstr "ΠÏοσθήκη σε συλλογή:"
+
+#: views/addons/display.thtml:491
+msgid "addons_display_collection_add_new"
+msgstr "Îέα συλλογή..."
+
+#: views/addons/display.thtml:487
+msgid "addons_display_collection_add_select_one"
+msgstr "Επιλογή συλλογής..."
+
+#: views/addons/display.thtml:493
+msgid "addons_display_collection_add_submit"
+msgstr "Δημοσίευση"
+
+#. %1$s is the add-on name
+#. %2$s is the collection name, linked to the collection's page
+#: views/pages/js_constants.js.thtml:103
+#: views/addons/display.thtml:61
+msgid "addons_display_collection_publish_success"
+msgstr "Το %1$s Ï€Ïοστέθηκε στη συλλογή %2$s."
+
+#: views/addons/display.thtml:483
+msgid "addons_display_collection_whatsthis"
+msgstr "Τι είναι αυτό;"
+
+#. %1$s is a number
+#: views/addons/display.thtml:473
+msgid "addons_display_collections_more"
+msgid_plural "addons_display_collections_more"
+msgstr[0] "συν %1$s ακόμα συλλογή"
+msgstr[1] "συν %1$s ακόμα συλλογές"
+
+#: views/addons/display.thtml:403
+msgid "addons_display_detailed_review"
+msgstr "λεπτομεÏής αξιολόγηση"
+
+#: views/reviews/add.thtml:89
+#: views/reviews/add.thtml:90
+msgid "addons_display_dont_like_it"
+msgstr "Δε μου αÏέσει"
+
+#: views/reviews/display.thtml:220
+msgid "addons_display_edit_review"
+msgstr "ΕπεξεÏγασία αξιολόγησης"
+
+#: views/addons/display.thtml:132
+msgid "addons_display_has_privacy"
+msgstr "Αυτό το Ï€Ïόσθετο συνοδεÏεται από ξεχωÏιστή πολιτική αποÏÏήτου."
+
+#: views/reviews/add.thtml:87
+#: views/reviews/add.thtml:88
+msgid "addons_display_hate_it"
+msgstr "Το σιχαίνομαι"
+
+#: views/addons/display.thtml:462
+msgid "addons_display_header_collections"
+msgstr "Σχετικές συλλογές"
+
+#: views/addons/display.thtml:297
+msgid "addons_display_header_developer_comments"
+msgstr "Σχόλια δημιουÏγοÏ"
+
+#: views/addons/display.thtml:230
+msgid "addons_display_header_homepage"
+msgstr "ΑÏχική σελίδα"
+
+#: views/addons/display.thtml:247
+#: views/addons/versions.thtml:110
+msgid "addons_display_header_license"
+msgstr "Άδεια πηγαίου κώδικα"
+
+#: views/addons/display.thtml:337
+msgid "addons_display_header_reviews"
+msgstr "Αξιολογήσεις"
+
+#: views/addons/display.thtml:261
+msgid "addons_display_header_support"
+msgstr "ΥποστήÏιξη"
+
+#: views/reviews/add.thtml:91
+#: views/reviews/add.thtml:92
+msgid "addons_display_like_it"
+msgstr "Μου αÏέσει"
+
+#: views/addons/display.thtml:210
+msgid "addons_display_long_description"
+msgstr "Αναλυτική πεÏιγÏαφή"
+
+#: views/reviews/add.thtml:95
+#: views/reviews/add.thtml:96
+msgid "addons_display_love_it"
+msgstr "Το λατÏεÏω"
+
+#: views/addons/display.thtml:178
+msgid "addons_display_more_images"
+msgstr "ΠεÏισσότεÏες εικόνες"
+
+#: views/addons/display.thtml:465
+msgid "addons_display_nocollections"
+msgstr "Αυτό το Ï€Ïόσθετο δεν συμπεÏιλαμβάνεται ακόμα σε καμία συλλογή."
+
+# %1$s is either an author's name or a comma separated list of authors. Using
+# the list doesn't make sense in the English plural form so we ignore the
+# variable.
+#. %1$s is either an author's name or a comma separated list of authors. Using
+#. the list doesn't make sense in the English plural form so we ignore the
+#. variable.
+#: views/addons/display.thtml:436
+msgid "addons_display_other_addons_by"
+msgid_plural "addons_display_other_addons_by"
+msgstr[0] "Άλλα Ï€Ïόσθετα από: %1$s"
+msgstr[1] "Άλλα Ï€Ïόσθετα απ' αυτοÏÏ‚ τους δημιουÏγοÏÏ‚"
+
+#. %s is the name of the add-on and the add-on section. Example:
+#. Some Add-on :: Firefox Add-ons
+#. This should not be concatenated in the code and should be fixed.
+#: controllers/addons_controller.php:141
+#: controllers/addons_controller.php:280
+#: controllers/addons_controller.php:1442
+#, php-format
+msgid "addons_display_pagetitle"
+msgstr "%s"
+
+#. %s is an email address
+#: views/addons/display.thtml:286
+#, php-format
+msgid "addons_display_paragraph_supportinfoemail"
+msgstr "ΥποστήÏιξη γι' αυτή την επέκταση θα βÏείτε στη διεÏθυνση ηλεκτÏÎ¿Î½Î¹ÎºÎ¿Ï Ï„Î±Ï‡Ï…Î´Ïομείου %s."
+
+#. %$1s is a URL
+#. %$2s is an email address
+#: views/addons/display.thtml:269
+#, php-format
+msgid "addons_display_paragraph_supportinfoemailurl"
+msgstr "ΥποστήÏιξη γι' αυτή την επέκταση θα βÏείτε στο %s ή στη διεÏθυνση ηλεκτÏÎ¿Î½Î¹ÎºÎ¿Ï Ï„Î±Ï‡Ï…Î´Ïομείου %s."
+
+#. %s is a URL
+#: views/addons/display.thtml:278
+#, php-format
+msgid "addons_display_paragraph_supportinfourl"
+msgstr "ΥποστήÏιξη γι' αυτή την επέκταση θα βÏείτε στο %s."
+
+#: views/addons/display.thtml:383
+msgid "addons_display_rate_it"
+msgstr "Βαθμολόγηση"
+
+#: views/reviews/add.thtml:93
+#: views/reviews/add.thtml:94
+msgid "addons_display_really_like_it"
+msgstr "Μου αÏέσει Ï€Ïαγματικά"
+
+#: views/addons/display.thtml:410
+msgid "addons_display_review_etiquette"
+msgstr "ΠαÏακαλοÏμε μη χÏησιμοποιείτε τις αξιολογήσεις για αναφοÏά σφαλμάτων. Οι δημιουÏγοί είναι πιθανό να χÏειαστεί να επικοινωνήσουν μαζί σας για να επιλυθεί το Ï€Ïόβλημα κι εμείς δεν τους γνωστοποιοÏμε τη διεÏθυνση του ηλεκτÏÎ¿Î½Î¹ÎºÎ¿Ï ÏƒÎ±Ï‚ ταχυδÏομείου."
+
+# %1 is the review guidelines link
+#. %1 is the review guidelines link
+#: views/addons/display.thtml:417
+msgid "addons_display_review_guidelines_link"
+msgstr "<a href=\"%s\">Οδηγίες σÏνταξης αξιολόγησης</a>"
+
+# %1 is the support section link
+#. %1 is the support section link
+#: views/addons/display.thtml:414
+msgid "addons_display_review_see_support"
+msgstr "Δείτε το <a href=\"%1$s\">τμήμα υποστήÏιξης</a> για πληÏοφοÏίες σχετικά με το που θα βÏείτε βοήθεια γι' αυτό το Ï€Ïόσθετο."
+
+#: views/addons/display.thtml:404
+msgid "addons_display_review_submit"
+msgstr "Υποβολή"
+
+#: views/addons/display.thtml:430
+#, php-format
+msgid "addons_display_see_all_addons"
+msgstr "Δείτε όλα τα Ï€Ïόσθετα: %1$s"
+
+# %1 is the number of reviews
+#. %1 is the number of reviews
+#: views/addons/display.thtml:364
+#, php-format
+msgid "addons_display_see_all_reviews"
+msgstr "Δείτε όλες τις αξιολογήσεις (%1$s)"
+
+#: views/addons/display.thtml:219
+msgid "addons_display_see_all_versions"
+msgstr "Δείτε όλες τις εκδόσεις"
+
+#: views/addons/display.thtml:321
+#: views/addons/versions.thtml:117
+msgid "addons_display_view_source"
+msgstr "Δείτε τον πηγαίο κώδικα"
+
+#: views/addons/display.thtml:324
+msgid "addons_display_view_stats"
+msgstr "Εμφάνιση στατιστικών"
+
+#: views/addons/display.thtml:376
+msgid "addons_display_what_do_you_think"
+msgstr "Πώς σας φαίνεται;"
+
+#: views/elements/app_compatibility.thtml:49
+msgid "addons_display_workswith"
+msgstr "Συμβατό με:"
+
+#: views/addons/home.thtml:112
+msgid "addons_home_browse_new"
+msgstr "Μόλις Ï€Ïοστέθηκαν"
+
+#: views/addons/home.thtml:110
+msgid "addons_home_browse_popular"
+msgstr "Δημοφιλή"
+
+#: views/addons/home.thtml:108
+msgid "addons_home_browse_recommended"
+msgstr "Συνιστώμενα"
+
+#: views/addons/home.thtml:127
+#: views/addons/home.thtml:134
+#: views/addons/home.thtml:141
+#: views/addons/home.thtml:148
+msgid "addons_home_browse_subscribe"
+msgstr "ΣυνδÏομή"
+
+#: views/addons/home.thtml:101
+msgid "addons_home_browse_title"
+msgstr "ΠεÏιήγηση στα Ï€Ïόσθετα"
+
+#: views/addons/home.thtml:114
+msgid "addons_home_browse_updated"
+msgstr "ΕνημεÏωμένα"
+
+#: views/elements/amo2009/homepage_addon.thtml:100
+#: views/elements/addon_discussionheader.thtml:83
+#: views/elements/addon_listitem.thtml:109
+#: views/elements/feature.thtml:95
+#: views/addons/category_landing.thtml:66
+#: views/addons/policy.thtml:57
+#: views/addons/display.thtml:70
+#: views/addons/home.thtml:178
+msgid "addons_home_by"
+msgstr "από"
+
+#: views/addons/home.thtml:169
+msgid "addons_home_collection_popular_title"
+msgstr "δημοφιλείς συλλογές"
+
+#: views/elements/amo2009/categories.thtml:69
+#: views/addons/home.thtml:160
+msgid "addons_home_collections"
+msgstr "Συλλογές"
+
+#. %1$s is the count of addons in a collection
+#: views/elements/amo2009/collection_listing_item.thtml:51
+#: views/addons/home.thtml:185
+msgid "addons_home_collections_addon_count"
+msgid_plural "addons_home_collections_addon_count"
+msgstr[0] "<strong>%1$s</strong> Ï€Ïόσθετο"
+msgstr[1] "<strong>%1$s</strong> Ï€Ïόσθετα"
+
+#: views/addons/home.thtml:196
+msgid "addons_home_collections_all"
+msgstr "Εμφάνιση όλων των συλλογών"
+
+#: views/addons/home.thtml:162
+msgid "addons_home_collections_intro"
+msgstr "Οι συλλογές είναι ένας Ï„Ïόπος για να κατηγοÏιοποιήσετε, να συνδυάσετε και να ταιÏιάξετε Ï€Ïόσθετα. ΓÏαφτείτε συνδÏομητές σε συλλογές που έχουν δημιουÏγήσει άλλοι ή δημιουÏγήστε τη δική σας!"
+
+#. %1$s is the count of subscribers for a collection
+#: views/elements/amo2009/collection_listing_item.thtml:58
+#: views/collections/detail.thtml:96
+#: views/addons/home.thtml:189
+msgid "addons_home_collections_subscribers"
+msgid_plural "addons_home_collections_subscribers"
+msgstr[0] "<strong>%1$s</strong> συνδÏομητής"
+msgstr[1] "<strong>%1$s</strong> συνδÏομητές"
+
+#: views/addons/searchengines.thtml:54
+#: views/addons/themes_landing.thtml:49
+msgid "addons_home_feature_head"
+msgstr "ΣυνιστοÏμε"
+
+#: controllers/search_controller.php:218
+#: controllers/addons_controller.php:176
+#: controllers/addons_controller.php:428
+#: controllers/addons_controller.php:671
+#: controllers/addons_controller.php:871
+#: controllers/addons_controller.php:1103
+#: controllers/addons_controller.php:1242
+#: controllers/addons_controller.php:1298
+#, php-format
+msgid "addons_home_header_details"
+msgstr "Τα Ï€Ïόσθετα επεκτείνουν τον %1$s και σας επιτÏέπουν να Ï€ÏοσαÏμόσετε την πεÏιήγηση στα μέτÏα σας. Ρίξτε μια ματιά και κάντε τον %1$s κτήμα σας."
+
+#. %1$s is the HTML collection name link.
+#: views/elements/amo2009/teaser_collections.thtml:107
+msgid "addons_home_introduction_collection_link"
+msgstr "Σας αÏέσουν; Î’Ïείτε κι άλλα Ï€Ïόσθετα στη σελίδα %1$s."
+
+#: views/elements/amo2009/teaser_collections.thtml:60
+msgid "addons_home_introduction_extras"
+msgstr "<strong>Πάνω από 5000 δωÏεάν Ï€Ïόσθετα</strong> για να Ï€ÏοσαÏμόσετε και να φέÏετε τον Firefox στα μέτÏα σας."
+
+#: views/elements/amo2009/teaser_collections.thtml:55
+msgid "addons_home_introduction_header"
+msgstr "Τι είναι τα Ï€Ïόσθετα;"
+
+#: views/elements/amo2009/teaser_collections.thtml:72
+msgid "addons_home_introduction_install"
+msgstr "<strong>ΕÏκολη εγκατάσταση</strong> και ενημέÏωση."
+
+#: views/elements/amo2009/teaser_collections.thtml:45
+msgid "addons_home_introduction_name"
+msgstr "Εισαγωγή"
+
+#: views/elements/amo2009/teaser_collections.thtml:66
+msgid "addons_home_introduction_themes"
+msgstr "ΕÏγαλειοθήκες, θέματα και μηχανές αναζήτησης που σας <strong>βοηθοÏν σε καθημεÏινές εÏγασίες.</strong>"
+
+#: views/addons/home.thtml:161
+msgid "addons_home_new_indicator"
+msgstr "ÎΕΟ!"
+
+#: views/elements/app_chooser.thtml:48
+#: views/layouts/amo2009.thtml:257
+msgid "addons_home_other_applications"
+msgstr "Άλλα Ï€ÏογÏάμματα"
+
+#. %1$s is the application the user is browsing. Examples: Thunderbird, Firefox,
+#. Sunbird
+#: views/pages/collector_faq.thtml:49
+#: views/pages/collector_firstrun.thtml:42
+#: views/pages/collector.thtml:46
+#: views/pages/collector_features.thtml:54
+#: controllers/developers_controller.php:87
+#: controllers/compatibility_controller.php:72
+#: controllers/components/simple_acl.php:81
+#: controllers/components/amo.php:607
+#: controllers/statistics_controller.php:60
+#: controllers/statistics_controller.php:240
+#: controllers/previews_controller.php:67
+#: controllers/users_controller.php:90
+#: controllers/users_controller.php:223
+#: controllers/users_controller.php:330
+#: controllers/users_controller.php:414
+#: controllers/users_controller.php:708
+#: controllers/users_controller.php:723
+#: controllers/reviews_controller.php:204
+#: controllers/reviews_controller.php:251
+#: controllers/reviews_controller.php:346
+#: controllers/reviews_controller.php:425
+#: controllers/search_controller.php:185
+#: controllers/search_controller.php:297
+#: controllers/search_controller.php:301
+#: controllers/addons_controller.php:147
+#: controllers/addons_controller.php:280
+#: controllers/addons_controller.php:370
+#: controllers/addons_controller.php:667
+#: controllers/addons_controller.php:874
+#: controllers/addons_controller.php:1019
+#: controllers/addons_controller.php:1034
+#: controllers/addons_controller.php:1101
+#: controllers/addons_controller.php:1121
+#: controllers/addons_controller.php:1240
+#: controllers/addons_controller.php:1357
+#: controllers/addons_controller.php:1364
+#: controllers/addons_controller.php:1442
+#: controllers/addons_controller.php:1477
+#: controllers/addons_controller.php:1538
+#: controllers/addons_controller.php:1543
+#: controllers/editors_controller.php:64
+#: controllers/pages_controller.php:132
+#: controllers/groups_controller.php:65
+#: controllers/groups_controller.php:71
+#: controllers/groups_controller.php:89
+#: controllers/groups_controller.php:111
+#: controllers/collections_controller.php:57
+#: controllers/collections_controller.php:121
+#: controllers/collections_controller.php:205
+#: controllers/collections_controller.php:365
+#: controllers/collections_controller.php:404
+#: controllers/collections_controller.php:466
+#: controllers/collections_controller.php:538
+#: controllers/collections_controller.php:828
+#: controllers/localizers_controller.php:72
+#, php-format
+msgid "addons_home_pagetitle"
+msgstr "ΠÏόσθετα %1$s"
+
+#. %1$s is the number of addons downloaded
+#: views/addons/home.thtml:57
+#, php-format
+msgid "addons_home_stats_downloaded"
+msgid_plural "addons_home_stats_downloaded"
+msgstr[0] "<strong>%1$s</strong> <span>λήψη Ï€Ïόσθετου</span>"
+msgstr[1] "<strong>%1$s</strong> <span>λήψεις Ï€Ïόσθετων</span>"
+
+#. %1$s is the number of addons in use
+#: views/addons/home.thtml:63
+#, php-format
+msgid "addons_home_stats_inuse"
+msgid_plural "addons_home_stats_inuse"
+msgstr[0] "<strong>%1$s</strong> <span>Ï€Ïόσθετο σε χÏήση</span>"
+msgstr[1] "<strong>%1$s</strong> <span>Ï€Ïόσθετα σε χÏήση</span>"
+
+#: views/addons/home.thtml:136
+msgid "addons_home_view_all_newest_title"
+msgstr "Δείτε όλα τα Ï€Ïόσθετα που δημιουÏγήθηκαν Ï€Ïόσφατα"
+
+#: views/addons/home.thtml:129
+msgid "addons_home_view_all_popular_title"
+msgstr "Εμφάνιση όλων των δημοφιλών Ï€Ïόσθετων"
+
+#: views/addons/home.thtml:150
+msgid "addons_home_view_all_recommended_title"
+msgstr "Εμφάνιση όλων των συνιστώμενων Ï€Ïόσθετων"
+
+#: views/addons/home.thtml:143
+msgid "addons_home_view_all_updated_title"
+msgstr "Δείτε όλα τα Ï€Ïόσθετα που ενημεÏώθηκαν Ï€Ïόσφατα"
+
+#: views/elements/amo2009/install.thtml:334
+#: views/elements/install.thtml:112
+msgid "addons_install_in_sunbird"
+msgstr "<ol><li>Κάντε κλικ στον παÏακάτω δεσμό για να αποθηκεÏσετε το αÏχείο.</li><li>Στο Mozilla Sunbird, ανοίξτε τα «ΠÏόσθετα» από το Î¼ÎµÎ½Î¿Ï Â«Î•Ïγαλεία».</li><li>Κάντε κλικ στο κουμπί «Εγκατάσταση» και Î±Ï†Î¿Ï ÎµÎ½Ï„Î¿Ï€Î¯ÏƒÎµÏ„Îµ/επιλέξετε το αÏχείο που αποθηκεÏσατε κάντε κλικ στο «OK».</li></ol>"
+
+#: views/elements/amo2009/install.thtml:333
+#: views/elements/install.thtml:111
+msgid "addons_install_in_sunbird_title"
+msgstr "Πως να κάνετε εγκατάσταση στο Sunbird"
+
+#: views/elements/amo2009/install.thtml:331
+#: views/elements/install.thtml:106
+msgid "addons_install_in_thunderbird"
+msgstr "<ol><li>κάντε δεξί κλικ παÏακάτω και επιλέξτε «Αποθήκευση Î´ÎµÏƒÎ¼Î¿Ï Ï‰Ï‚...» για να αποθηκεÏσετε το αÏχείο στο δίσκο σας.</li><li>Στον Mozilla Thunderbird, ανοίξτε τα «ΠÏόσθετα» μέσα από το Î¼ÎµÎ½Î¿Ï Â«Î•Ïγαλεία».</li><li>Κάντε κλικ στο κουμπί «Εγκατάσταση» και Î±Ï†Î¿Ï ÎµÎ½Ï„Î¿Ï€Î¯ÏƒÎµÏ„Îµ/επιλέξετε το αÏχείο που αποθηκεÏσατε κάντε κλικ στο «OK».</li></ol>"
+
+#: views/elements/amo2009/install.thtml:330
+#: views/elements/install.thtml:105
+msgid "addons_install_in_thunderbird_title"
+msgstr "Εγκατάσταση στον Thunderbird"
+
+#: views/elements/amo2009/addon_list_options.thtml:108
+#: views/elements/addon_list_options.thtml:105
+msgid "addons_options_show_experimental"
+msgstr "Ï€Ïοβολή πειÏαματικών Ï€Ïόσθετων"
+
+#: views/elements/amo2009/addon_list_options.thtml:113
+#: views/elements/addon_list_options.thtml:109
+msgid "addons_options_submit"
+msgstr "Μετάβαση"
+
+#: views/addons/plugins.thtml:63
+#: views/addons/plugins.thtml:73
+#: views/addons/plugins.thtml:83
+#: views/addons/plugins.thtml:93
+#: views/addons/plugins.thtml:103
+#: views/addons/plugins.thtml:116
+#: views/addons/plugins.thtml:126
+msgid "addons_plugins_by"
+msgstr "Από"
+
+#: views/addons/plugins.thtml:107
+msgid "addons_plugins_for_linux"
+msgstr "για Linux"
+
+#: views/addons/plugins.thtml:108
+#: views/addons/plugins.thtml:131
+msgid "addons_plugins_for_macosx"
+msgstr "για Mac OS X"
+
+#: views/addons/plugins.thtml:106
+#: views/addons/plugins.thtml:129
+#: views/addons/plugins.thtml:130
+msgid "addons_plugins_for_windows"
+msgstr "για Windows"
+
+#. %1$s is a URL
+#: views/addons/plugins.thtml:139
+#, php-format
+msgid "addons_plugins_looking_for_more"
+msgstr "Αυτή η σελίδα αναφέÏει μεÏικές μόνο από τις πιο συνηθισμένες και δημοφιλείς Ï€Ïόσθετες λειτουÏγίες. Για πεÏισσότεÏες πληÏοφοÏίες σχετικά με άλλες Ï€Ïόσθετες λειτουÏγίες, διαθέσιμες για πεÏιηγητές της οικογένειας Mozilla, επισκεφθείτε το %1$s"
+
+#: views/addons/plugins.thtml:137
+msgid "addons_plugins_looking_for_plugin"
+msgstr "Ψάχνετε για μια Ï€Ïόσθετη λειτουÏγία που δεν αναφέÏεται εδώ;"
+
+#: views/addons/plugins.thtml:58
+msgid "addons_plugins_main_description"
+msgstr "Οι Ï€Ïόσθετες λειτουÏγίες βοηθοÏν τον πεÏιηγητή να εκτελέσει συγκεκÏιμένες λειτουÏγίες, όπως την εμφάνιση ειδικών Ï„Ïπων γÏαφικών ή την αναπαÏαγωγή αÏχείων πολυμέσων. Οι Ï€Ïόσθετες λειτουÏγίες είναι ελαφÏÏŽÏ‚ διαφοÏετικές από τις επεκτάσεις, οι οποίες Ï„ÏοποποιοÏν ή Ï€Ïοσθέτουν χαÏακτηÏιστικά."
+
+#. %1$s is the application name. Example: Firefox, Thunderbird, Sunbird
+#: controllers/addons_controller.php:1122
+#, php-format
+msgid "addons_plugins_main_header"
+msgstr "Δημοφιλείς Ï€Ïόσθετες λειτουÏγίες για τον %1$s"
+
+#: controllers/components/amo.php:698
+#: controllers/addons_controller.php:1121
+msgid "addons_plugins_pagetitle"
+msgstr "ΠÏόσθετες λειτουÏγίες"
+
+#: views/addons/plugins.thtml:68
+#: views/addons/plugins.thtml:78
+#: views/addons/plugins.thtml:88
+#: views/addons/plugins.thtml:98
+#: views/addons/plugins.thtml:110
+#: views/addons/plugins.thtml:121
+#: views/addons/plugins.thtml:133
+msgid "addons_plugins_support_documentation"
+msgstr "ΈγγÏαφα υποστήÏιξης: "
+
+#. %s is the name of the add-on
+#: views/addons/policy.thtml:61
+#, php-format
+msgid "addons_policy_eula_require"
+msgstr "Το %s απαιτεί να αποδεχτείτε το παÏακάτω Συμφωνητικό Αδειδότησης Î¤ÎµÎ»Î¹ÎºÎ¿Ï Î§Ïήστη για να ξεκκινήσει η εγκατάσταση:"
+
+# %1 is the addon name
+#. %1 is the add-on name
+#: controllers/addons_controller.php:1476
+#, php-format
+msgid "addons_previews_pagetitle"
+msgstr "Εικόνες Ï€Ïοεπισκόπησης για το %s"
+
+#: views/addons/category_landing.thtml:135
+msgid "addons_recently_added"
+msgstr "ΠÏοστεθηκαν Ï€Ïοσφατα"
+
+#: views/addons/recommended.thtml:51
+#: controllers/addons_controller.php:1365
+msgid "addons_recommended_introduction"
+msgstr "Με τόσα πολλά διαθέσιμα Ï€Ïόσθετα, σίγουÏα θα υπάÏχει κάτι που να σας ταιÏιάζει. Για να ξεκινήσετε, Î¹Î´Î¿Ï Î¼Î¹Î± λίστα με τα πιο δημοφιλή! "
+
+#: controllers/addons_controller.php:1357
+#: controllers/addons_controller.php:1364
+msgid "addons_recommended_pagetitle"
+msgstr "Συνιστώμενα Ï€Ïόσθετα"
+
+#: controllers/addons_controller.php:1360
+msgid "addons_recommended_title"
+msgstr "Συνιστώμενα Ï€Ïόσθετα"
+
+#: views/addons/searchengines.thtml:136
+msgid "addons_searchengines_additional_resources"
+msgstr "ΠÏόσθετοι πόÏοι"
+
+# link text devmo
+#. link text devmo
+#: views/addons/searchengines.thtml:141
+msgid "addons_searchengines_devmo_link"
+msgstr "ΚέντÏο δημιουÏγών Mozilla"
+
+#: views/pages/js_constants.js.thtml:67
+msgid "addons_searchengines_error_mozilla_browser_required"
+msgstr "Απαιτείται πεÏιηγητής της οικογένειας Mozilla (όπως ο Firefox) για να εγκαταστήσετε μια Ï€Ïόσθετη λειτουÏγία αναζήτησης."
+
+#: views/addons/searchengines.thtml:49
+msgid "addons_searchengines_error_nojavascript"
+msgstr "Απαιτείται η ενεÏγοποίηση της JavaScript για να εγκαταστήσετε Ï€Ïόσθετες λειτουÏγίες, αλλά φαίνεται πως την έχετε απενεÏγοποιήσει. ΠαÏακαλοÏμε ενεÏγοποιήστε την JavaScript Ï€Ïιν Ï€Ïοσπαθήσετε να εγκαταστήσετε κάποια από τις παÏακάτω Ï€Ïόσθετες λειτουÏγίες."
+
+# %1 is "make your own" link
+# %2 is MDC link
+#. %1 is "make your own" link
+#. %2 is MDC link
+#: views/addons/searchengines.thtml:139
+msgid "addons_searchengines_learn_howto"
+msgstr "Μάθετε πώς να %1$s στο %2$s."
+
+# link path to search plugins instructions, relative to devmo
+#. link path to search plugins instructions, relative to devmo
+#: views/addons/searchengines.thtml:140
+msgid "addons_searchengines_makeyourown_href"
+msgstr "/en/docs/Creating_OpenSearch_plugins_for_Firefox"
+
+# link text for "make your own" (opensearch engine)
+#. link text for "make your own" (opensearch engine)
+#: views/addons/searchengines.thtml:140
+msgid "addons_searchengines_makeyourown_link"
+msgstr "δημιουÏγήστε το δικό σας"
+
+# %1 is the link to mycroft.mozdev.org
+#. %1 is the link to mycroft.mozdev.org
+#: views/addons/searchengines.thtml:138
+msgid "addons_searchengines_more"
+msgstr "ΠεÏιηγηθείτε σε πεÏισσότεÏες μηχανές αναζήτησης στο %1$s"
+
+# link text to mycroft.mozdev.org
+#. link text to mycroft.mozdev.org
+#: views/addons/searchengines.thtml:138
+msgid "addons_searchengines_mycroft_link"
+msgstr "mycroft.mozdev.org"
+
+#: controllers/addons_controller.php:1100
+#: controllers/addons_controller.php:1110
+msgid "addons_searchengines_pagetitle"
+msgstr "Μηχανές αναζήτησης"
+
+#: views/addons/searchengines.thtml:143
+msgid "addons_searchengines_thanks"
+msgstr "ΕυχαÏιστοÏμε ειδικά τους συντελεστές του εγχειÏήματος Mycroft για τη δουλειά τους σχετικά με τις μηχανές αναζήτησης του Firefox."
+
+#: views/addons/display.thtml:154
+msgid "addons_share_button_text"
+msgstr "ΜοιÏαστείτε το"
+
+#: controllers/addons_controller.php:89
+msgid "addons_share_label_delicious"
+msgstr "ΠÏοσθήκη στο Delicious"
+
+#: controllers/addons_controller.php:77
+msgid "addons_share_label_digg"
+msgstr "ΠÏοσθήκη στο Digg"
+
+#: controllers/addons_controller.php:83
+msgid "addons_share_label_facebook"
+msgstr "Δημοσίευση στο Facebook"
+
+#: controllers/addons_controller.php:101
+msgid "addons_share_label_friendfeed"
+msgstr "ΔιαμοιÏασμός στο FriendFeed"
+
+#: controllers/addons_controller.php:95
+msgid "addons_share_label_myspace"
+msgstr "Δημοσίευση στο MySpace"
+
+#: controllers/components/amo.php:201
+#: controllers/components/amo.php:229
+msgid "addons_status_disabled"
+msgstr "ΑπενεÏγοποιημένο"
+
+#: controllers/components/amo.php:191
+#: controllers/components/amo.php:224
+msgid "addons_status_incomplete"
+msgstr "Ατελής έκδοση"
+
+#: controllers/components/amo.php:197
+#: controllers/components/amo.php:227
+msgid "addons_status_nominated"
+msgstr "Στο Sandbox; Υποψηφιότητα για το δημόσιο χώÏο"
+
+#: views/pages/js_constants.js.thtml:80
+#: controllers/components/amo.php:195
+#: controllers/components/amo.php:226
+msgid "addons_status_pending"
+msgstr "Στο Sandbox; αναμονή αξιολόγησης"
+
+#: views/pages/js_constants.js.thtml:78
+#: controllers/components/amo.php:199
+#: controllers/components/amo.php:228
+msgid "addons_status_public"
+msgstr "Δημόσιος χώÏος"
+
+#: views/pages/js_constants.js.thtml:79
+#: controllers/components/amo.php:193
+#: controllers/components/amo.php:225
+msgid "addons_status_sandbox"
+msgstr "Στο Sandbox"
+
+#: controllers/components/amo.php:203
+msgid "addons_status_unknown"
+msgstr "Άγνωστο"
+
+#: views/elements/amo2009/teaser_collections.thtml:91
+#: views/elements/amo2009/homepage_addon.thtml:99
+#: views/elements/feature.thtml:94
+msgid "addons_title_tooltip"
+msgstr "Μάθετε πεÏισσότεÏα για το Ï€Ïόσθετο"
+
+#: views/addons/category_landing.thtml:151
+msgid "addons_top_downloads"
+msgstr "ΚοÏυφαια σε ληψεις"
+
+#: views/addons/category_landing.thtml:165
+msgid "addons_top_rated"
+msgstr "ΚοÏυφαια σε βαθμολογια"
+
+#: views/addons/versions.thtml:62
+msgid "addons_versions_careful"
+msgstr "Συνιστάται Ï€Ïοσοχή για τις παλαιότεÏες εκδόσεις"
+
+#: views/addons/versions.thtml:63
+msgid "addons_versions_careful_introduction"
+msgstr "Αυτές οι εκδόσεις υπάÏχουν για αναφοÏά και πειÏαματικοÏÏ‚ σκοποÏÏ‚. Σας συμβουλεÏουμε να χÏησιμοποιείτε πάντα την πιο Ï€Ïόσφατα ενημεÏωμένη έκδοση ενός Ï€Ïόσθετου."
+
+#: controllers/addons_controller.php:1549
+msgid "addons_versions_history"
+msgstr "ΙστοÏικό αλλαγών εκδόσεων "
+
+#. %1$s is the add-on name
+#: controllers/addons_controller.php:1535
+#, php-format
+msgid "addons_versions_pagetitle"
+msgstr "ΙστοÏικό εκδόσεων %1$s "
+
+#: controllers/groups_controller.php:71
+msgid "admin_group_add_pagetitle"
+msgstr "ΠÏοσθήκη ομάδας"
+
+#: controllers/groups_controller.php:111
+msgid "admin_group_delete_pagetitle"
+msgstr "ΔιαγÏαφή ομάδας"
+
+#. %s is a number to identify the group
+#: controllers/groups_controller.php:117
+#, php-format
+msgid "admin_group_deleted"
+msgstr "ΔιαγÏάφηκε η ομάδα με αναγνωÏιστικό %s"
+
+#: controllers/groups_controller.php:89
+msgid "admin_group_edit_pagetitle"
+msgstr "ΕπεξεÏγασία ομάδας"
+
+#: controllers/groups_controller.php:92
+#: controllers/groups_controller.php:113
+msgid "admin_group_error_invalid_id"
+msgstr "Μη έγκυÏο αναγνωÏιστικό ομάδας"
+
+#: controllers/groups_controller.php:65
+msgid "admin_group_pagetitle"
+msgstr "ΔιαχειÏιστής ομάδας"
+
+#: controllers/groups_controller.php:77
+#: controllers/groups_controller.php:99
+msgid "admin_group_saved"
+msgstr "Η ομάδα αποθηκεÏθηκε"
+
+#: views/elements/amo2009/search.thtml:257
+#: views/elements/search.thtml:239
+msgid "advanced_search_form"
+msgstr "ΠεÏισσότεÏα"
+
+#: views/elements/amo2009/search.thtml:126
+#: views/elements/search.thtml:125
+msgid "advanced_search_form_any_time"
+msgstr "ΧωÏίς ÏŒÏιο"
+
+#: views/elements/amo2009/search.thtml:97
+#: views/elements/amo2009/search.thtml:110
+#: views/elements/search.thtml:96
+#: views/elements/search.thtml:109
+msgid "advanced_search_form_any_type"
+msgstr "ΧωÏίς ÏŒÏιο"
+
+#: views/elements/amo2009/search.thtml:275
+#: views/elements/search.thtml:254
+msgid "advanced_search_form_any_version"
+msgstr "ΧωÏίς ÏŒÏιο"
+
+#: views/elements/amo2009/search.thtml:217
+#: views/elements/search.thtml:212
+msgid "advanced_search_form_application"
+msgstr "ΠÏόγÏαμμα"
+
+#: views/elements/amo2009/search.thtml:143
+#: views/elements/search.thtml:142
+msgid "advanced_search_form_keyword_match"
+msgstr "ταίÏιασμα λέξης-κλειδιοÏ"
+
+#: views/elements/amo2009/search.thtml:251
+#: views/elements/search.thtml:225
+msgid "advanced_search_form_lastupdate"
+msgstr "Τελευταία ενημέÏωση"
+
+#: views/elements/amo2009/search.thtml:145
+#: views/elements/search.thtml:144
+msgid "advanced_search_form_name"
+msgstr "Όνομα"
+
+#: views/elements/amo2009/search.thtml:144
+#: views/elements/search.thtml:143
+msgid "advanced_search_form_newest"
+msgstr "πιο Ï€Ïόσφατα"
+
+#: views/elements/amo2009/search.thtml:130
+#: views/elements/search.thtml:129
+msgid "advanced_search_form_past_3_months"
+msgstr "Ï€Ïιν 3 μήνες "
+
+#: views/elements/amo2009/search.thtml:131
+#: views/elements/search.thtml:130
+msgid "advanced_search_form_past_6_months"
+msgstr "Ï€Ïιν 6 μήνες"
+
+#: views/elements/amo2009/search.thtml:127
+#: views/elements/search.thtml:126
+msgid "advanced_search_form_past_day"
+msgstr "Ï€Ïιν 1 ήμεÏα"
+
+#: views/elements/amo2009/search.thtml:129
+#: views/elements/search.thtml:128
+msgid "advanced_search_form_past_month"
+msgstr "Ï€Ïιν 1 μήνα"
+
+#: views/elements/amo2009/search.thtml:128
+#: views/elements/search.thtml:127
+msgid "advanced_search_form_past_week"
+msgstr "Ï€Ïιν 1 εβδομάδα"
+
+#: views/elements/amo2009/search.thtml:132
+#: views/elements/search.thtml:131
+msgid "advanced_search_form_past_year"
+msgstr "Ï€Ïιν 1 χÏόνο"
+
+#: views/elements/amo2009/search.thtml:239
+#: views/elements/search.thtml:230
+msgid "advanced_search_form_perpage"
+msgstr "Αποτελέσματα ανά σελίδα"
+
+#: views/elements/amo2009/search.thtml:243
+#: views/elements/search.thtml:224
+msgid "advanced_search_form_platform"
+msgstr "ΠλατφόÏμα"
+
+#: views/elements/amo2009/search.thtml:147
+#: views/elements/search.thtml:146
+msgid "advanced_search_form_popularity"
+msgstr "πιο δημοφιλή"
+
+#: views/elements/amo2009/search.thtml:146
+#: views/elements/search.thtml:145
+msgid "advanced_search_form_rating"
+msgstr "αξιολογήσεις"
+
+#: views/elements/amo2009/search.thtml:247
+#: views/elements/search.thtml:231
+msgid "advanced_search_form_sortby"
+msgstr "Ταξινόμηση"
+
+#: views/elements/amo2009/search.thtml:227
+#: views/elements/search.thtml:216
+msgid "advanced_search_form_to"
+msgstr "έως"
+
+#: views/elements/amo2009/search.thtml:257
+#: views/elements/search.thtml:237
+msgid "advanced_search_form_toggle_tooltip"
+msgstr "Εναλλαγή σε/από σÏνθετη αναζήτηση"
+
+#: views/elements/amo2009/search.thtml:235
+#: views/elements/search.thtml:223
+msgid "advanced_search_form_type"
+msgstr "ΤÏπος"
+
+#: views/elements/amo2009/search.thtml:222
+#: views/elements/search.thtml:214
+msgid "advanced_search_form_version"
+msgstr "έκδοση"
+
+#: views/elements/amo2009/pagination.thtml:42
+msgid "amo2009_pagination_next_page"
+msgstr "Επόμενο"
+
+#: views/elements/amo2009/pagination.thtml:41
+msgid "amo2009_pagination_previous_page"
+msgstr "ΠÏοηγοÏμενο"
+
+#: views/pages/js_constants.js.thtml:96
+msgid "app_compat_ignore_check"
+msgstr "αγνόηση ελέγχου έκδοσης"
+
+#: views/pages/js_constants.js.thtml:72
+msgid "app_compat_older_firefox_only"
+msgstr "Αυτό το Ï€Ïόσθετο λειτουÏγεί με παλιότεÏες εκδόσεις του Firefox."
+
+#. %1$s and %2$s are URLs
+#: views/pages/js_constants.js.thtml:74
+msgid "app_compat_older_version_or_ignore_check"
+msgstr "ΜποÏείτε να <a href=\"%1$s\">δοκιμάσετε μια παλιότεÏη έκδοση</a> ή να <a href=\"#\" onclick=\"%2$s\">αγνοήσετε αυτό τον έλεγχο</a>."
+
+#. %1$s is a URL
+#: views/pages/js_constants.js.thtml:71
+msgid "app_compat_try_old_version"
+msgstr "Πιθανότατα μια <a href=\"%1$s\">παλιότεÏη έκδοση</a> να δουλέψει."
+
+#. %1$s is a URL
+#. %2$s is a version number. Example: 3.1
+#: views/pages/js_constants.js.thtml:73
+msgid "app_compat_unreleased_version"
+msgstr "Το Ï€Ïόσθετο αυτό απαιτεί την έκδοση <a href=\"%1$s\"> %2$s</a> του Firefox η οποία δεν είναι ακόμα επίσημα διαθέσιμη."
+
+#: views/pages/js_constants.js.thtml:70
+msgid "app_compat_update_firefox"
+msgstr "<a href=\"http://getfirefox.com\">ΕνημεÏώστε τον Firefox</a> για να χÏησιμοποιήσετε αυτό το Ï€Ïόσθετο."
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#. %3$s is a status, like Public.
+#: controllers/components/audit.php:79
+msgid "audit_addon_status"
+msgstr "Ο/Η %1$s άλλαξε την κατάσταση του %2$s σε %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:221
+msgid "audit_admin_default"
+msgstr "Ο/Η %1$s υπέβαλε άγνωστη δÏαστηÏιότητα διαχειÏιστή %2$s στο ID %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:153
+msgid "audit_admin_feature_remove"
+msgstr "Ο/Η %1$s αφαίÏεσε το χαÏακτηÏιστικό %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is an application, like Firefox.
+#: controllers/components/audit.php:92
+msgid "audit_application_create"
+msgstr "Ο/Η %1$s δημιοÏÏγησε την εφαÏμογή %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is an application, like Firefox.
+#: controllers/components/audit.php:95
+msgid "audit_application_edit"
+msgstr "Ο/Η %1$s επεξεÏγάστηκε την εφαÏμογή %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a version number, like 3.5.
+#. %3$s is an application, like Firefox.
+#: controllers/components/audit.php:105
+msgid "audit_appversion_create"
+msgstr "Ο/Η %1$s δημιοÏÏγησε την έκδοση %2$s για τον %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a version number, like 3.5.
+#. %3$s is an application, like Firefox.
+#: controllers/components/audit.php:108
+msgid "audit_appversion_delete"
+msgstr "Ο/Η %1$s διέγÏαψε την έκδοση %2$s για τον %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a config field, like "awesomeness".
+#. %3$s is a config value, like "off".
+#. %4$s is a config value, like "on".
+#: controllers/components/audit.php:210
+msgid "audit_config"
+msgstr "Ο/Η %1$s άλλαξε τη ÏÏθμιση «%2$s» από «%3$s» σε «%4$s»"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:258
+msgid "audit_editor_default"
+msgstr "Ο/Η %1$s υπέβαλε την άγνωστη ενέÏγεια συντάκτη %2$s στο ID %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#: controllers/components/audit.php:236
+msgid "audit_editor_feature_remove"
+msgstr "Ο/Η %1$s αφαίÏεσε το Ï€Ïόσθετο %2$s από τη λίστα συνιστώμενων"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#: controllers/components/audit.php:231
+msgid "audit_feature_add"
+msgstr "Ο/Η %1$s Ï€Ïόσθεσε το Ï€Ïόσθετο %2$s στη λίστα συνιστώμενων"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:149
+msgid "audit_feature_edit"
+msgstr "Ο/Η %1$s άλλαξε ένα χαÏακτηÏιστικό για τη γλώσσαr %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#: controllers/components/audit.php:241
+msgid "audit_feature_locale_change"
+msgstr "Ο/Η %1$s άλλαξε τις τοπικοποιήσεις για το Ï€Ïόσθετο %2$s στη λίστα συνιστώμενων"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:83
+msgid "audit_file_recalchash"
+msgstr "Ο/Η %1$s επαναπÏοσδιόÏισε το hash για το αÏχείο %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>user name</a>
+#. %3$s is <a>group name</a>
+#: controllers/components/audit.php:182
+msgid "audit_group_addmember"
+msgstr "Ο/Η %1$s Ï€Ïόσθεσε τον/την %2$s στην ομάδα %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:313
+msgid "audit_group_associated"
+msgstr "Ο/Η %1$s έγινε μέλος της ομάδας %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:162
+msgid "audit_group_create"
+msgstr "Ο/Η %1s δημιοÏÏγησε την ομάδα %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:170
+msgid "audit_group_delete"
+msgstr "Ο/Η %1$s διέγÏαψε την ομάδα %2$s (ID %3$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:165
+msgid "audit_group_edit"
+msgstr "Ο/Η %1$s επεξεÏγάστηκε την ομάδα %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>user name</a>
+#. %3$s is <a>group name</a>
+#: controllers/components/audit.php:188
+msgid "audit_group_removemember"
+msgstr "Ο/Η %1$s διέγÏαψε τον/την %2$s από την ομάδα %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:280
+msgid "audit_l10n_default"
+msgstr "Ο/Η %1$s υπέβαλε την άγνωστη ενέÏγεια %2$s για το %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:295
+msgid "audit_modify_locked_group"
+msgstr "Ο/Η %1$s Ï€Ïοσπάθησε να Ï„Ïοποποιήσει την κλειδωμένη ομάδα %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:299
+msgid "audit_modify_other_locale"
+msgstr "Ο/Η %1$s Ï€Ïοσπάθησε να Ï„Ïοποποιήσει τη μετάφÏαση για τη γλώσσα %2$s χωÏίς να έχει εξουσιοδότηση"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a platform, like <a>Windows</a>
+#: controllers/components/audit.php:135
+msgid "audit_platform_create"
+msgstr "Ο/Η %1$s δημιοÏÏγησε την πλατφόÏμα %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a platform, like <a>Windows</a>
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:143
+msgid "audit_platform_delete"
+msgstr "Ο/Η %1$s διέγÏαψε την πλατφόÏμα %2$s (ID %3$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a platform, like <a>Windows</a>
+#: controllers/components/audit.php:138
+msgid "audit_platform_edit"
+msgstr "Ο/η %1$s επεξεÏγάστηκε την πλατφόÏμα %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a part of the admin, like 'Site Config'
+#: controllers/components/audit.php:288
+msgid "audit_reauthentication_failure"
+msgstr "Ο/Η %1$s απέτυχε να πιστοποιηθεί ξανά για να αποκτήσει Ï€Ïόσβαση στο τμήμα %2$s."
+
+#. %1$s is <a>user name</a>
+#. %2$s is the name of a canned response, like 'Ready for the public'
+#: controllers/components/audit.php:198
+msgid "audit_response_create"
+msgstr "Ο/Η %1$s δημιοÏÏγησε την απόκÏιση %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is the name of a canned response, like 'Ready for the public'
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:206
+msgid "audit_response_delete"
+msgstr "Ο/Η %1$s διέγÏαψε την απόκÏιση %2$s (ID %3$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is the name of a canned response, like 'Ready for the public'
+#: controllers/components/audit.php:201
+msgid "audit_response_edit"
+msgstr "Ο/Η %1$s επεξεÏγάστηκε την απόκÏιση %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:245
+msgid "audit_review_approve"
+msgstr "Ο/Η %1$s ενέκÏινε την αξιολόγηση %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:250
+#: controllers/components/audit.php:253
+msgid "audit_review_delete"
+msgstr "Ο/Η %1$s διέγÏαψε την αξιολόγηση %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:303
+msgid "audit_security_default"
+msgstr "Ο/Η %1$s υπέβαλε την άγνωστη ενέÏγεια ασφαλείας %2$s στο ID %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a category name, like <a>Search Tools</a>
+#: controllers/components/audit.php:118
+msgid "audit_tag_create"
+msgstr "Ο/Η %1$s δημιοÏÏγησε την ετικέτα %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a category name, like <a>Search Tools</a>
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:126
+msgid "audit_tag_delete"
+msgstr "Ο/Η %1$s διέγÏαψε την κατηγοÏίαy %2$s (ID %3$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a category name, like <a>Search Tools</a>
+#: controllers/components/audit.php:121
+msgid "audit_tag_edit"
+msgstr "Ο/Η %1$s επεξεÏγάστηκε την κατηγοÏία %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:266
+msgid "audit_update_applications"
+msgstr "Ο/Η %1$s ενημέÏωσε τις μεταφÏάσεις εφαÏμογών για τη γλώσσα %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:277
+msgid "audit_update_blog"
+msgstr "Ο/Η %1$s ενημέÏωσε τις μεταφÏάσεις δημοσιεÏσεων ιστολόγιου για τη γλώσσα %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:274
+msgid "audit_update_platforms"
+msgstr "Ο/Η %1$s ενημέÏωσε τις μεταφÏάσεις πλατφόÏμας για τη γλώσσα %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:270
+msgid "audit_update_tags"
+msgstr "Ο/Η %1$s ενημέÏωσε τις μεταφÏάσεις κατηγοÏιών για τη γλώσσα %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>user name</a>
+#: controllers/components/audit.php:217
+msgid "audit_user_edit"
+msgstr "Ο/Η %1$s επεξεÏγάστηκε τις πληÏοφοÏίες χÏήστη του/της %2$s"
+
+#: controllers/addons_controller.php:1012
+msgid "browse_addons_name"
+msgstr "ΠÏόσθετα κατά όνομα"
+
+#: controllers/addons_controller.php:1010
+msgid "browse_addons_newest"
+msgstr "ÎεότεÏα Ï€Ïόσθετα"
+
+#: controllers/addons_controller.php:1008
+msgid "browse_addons_popular"
+msgstr "Δημοφιλή Ï€Ïόσθετα"
+
+#: controllers/addons_controller.php:1011
+msgid "browse_addons_rated"
+msgstr "ΠÏόσθετα κατά βαθμολογία"
+
+#: controllers/addons_controller.php:1009
+msgid "browse_addons_updated"
+msgstr "ΠÏόσφατα ενημεÏωμένα Ï€Ïόσθετα"
+
+#: views/elements/categories.thtml:73
+#: views/elements/categories.thtml:82
+msgid "categories_current_title"
+msgstr "ΤÏέχουσα κατηγοÏία"
+
+#: views/elements/categories.thtml:50
+#: views/elements/amo2009/categories.thtml:43
+#: views/elements/amo2009/categories.thtml:45
+msgid "categories_header"
+msgstr "ΚατηγοÏίες"
+
+#: views/elements/categories.thtml:50
+#: views/elements/amo2009/categories.thtml:41
+msgid "categories_header_title"
+msgstr "Επιλογή κατηγοÏίας"
+
+# %1 is the category name
+#. %1$s is the category name
+#: views/addons/searchengines.thtml:129
+#, php-format
+msgid "category_extra_see_all"
+msgstr "Εμφάνιση όλων σε %1$s"
+
+#. %1$s is a number.
+#: models/collection.php:130
+msgid "collection_description_limit"
+msgstr "Η πεÏιγÏαφή θα Ï€Ïέπει να έχει λιγότεÏους από %1$s χαÏακτήÏες."
+
+#. %1$s is the name of the collection
+#: controllers/collections_controller.php:392
+msgid "collection_detail_rss_title"
+msgstr "Συλλογή %s "
+
+#: controllers/collections_controller.php:1065
+msgid "collection_error_deleting_addon"
+msgstr "Συνέβη σφάλμα κατά τη διαγÏαφή του Ï€Ïόσθετου!"
+
+#: controllers/collections_controller.php:1051
+msgid "collection_error_saving_addon"
+msgstr "ΠαÏουσιάστηκε σφάλμα κατά την αποθήκευση του Ï€Ïόσθετου!"
+
+#: controllers/collections_controller.php:1080
+msgid "collection_error_saving_comment"
+msgstr "ΠαÏουσιάστηκε σφάλμα κατά την αποθήκευση του σχόλιου!"
+
+#. %1$s is a number.
+#: models/collection.php:122
+msgid "collection_name_limit"
+msgstr "Το όνομα θα Ï€Ïέπει να έχει λιγότεÏους από %1$s χαÏακτήÏες."
+
+#: controllers/collections_controller.php:352
+#: controllers/collections_controller.php:487
+msgid "collection_not_found"
+msgstr "Δε βÏέθηκε η συλλογή!"
+
+#. %1$s is the text on the "create collection" button
+#: views/collections/add.thtml:91
+msgid "collections_add_formfield_addons_description"
+msgstr "Αν ξέÏετε ήδη ποια Ï€Ïόσθετα θέλετε να Ï€Ïοσθέσετε στη συλλογή σας, απλά πληκτÏολογήστε τα ονόματα τους παÏακάτω. Αν θέλετε να πεÏιμένετε και να το κάνετε αÏγότεÏα, κάντε κλικ στο %1$s για την ÏŽÏα."
+
+#: views/collections/add.thtml:90
+msgid "collections_add_formfield_firstaddons"
+msgstr "Επιλέξτε τα Ï€Ïώτα σας Ï€Ïόσθετα"
+
+#: views/collections/add.thtml:48
+msgid "collections_add_header"
+msgstr "ΔημιουÏγήστε μια συλλογή"
+
+#: views/collections/add.thtml:97
+msgid "collections_add_header_selectedaddons"
+msgstr "Επιλεγμένα Ï€Ïόσθετα"
+
+#: views/collections/add.thtml:50
+msgid "collections_add_intro"
+msgstr "ΜποÏείτε να δημιουÏγήσετε τη δική σας συλλογή Ï€Ïόσθετων, συμπληÏώνοντας μεÏικά απ' τα παÏακάτω πεδία."
+
+#: views/collections/add.thtml:92
+#: views/collections/add.thtml:103
+msgid "collections_add_submit"
+msgstr "ΔημιουÏγία συλλογής"
+
+#: views/pages/collector_faq.thtml:50
+#: views/pages/collector_firstrun.thtml:43
+#: views/pages/collector.thtml:47
+#: views/pages/collector_features.thtml:55
+#: controllers/search_controller.php:302
+#: controllers/collections_controller.php:206
+#: controllers/collections_controller.php:405
+#: controllers/collections_controller.php:467
+#: controllers/collections_controller.php:539
+msgid "collections_breadcrumb"
+msgstr "Συλλογές"
+
+#: views/collections/detail.thtml:185
+msgid "collections_detail_a_learn"
+msgstr "Μάθετε πεÏισσότεÏα"
+
+#: views/elements/amo2009/collection_add_form.thtml:53
+#: views/elements/amo2009/collections_js_init.thtml:68
+#: views/pages/collector_firstrun.thtml:64
+msgid "collections_detail_button_add"
+msgstr "ΠÏοσθήκη στις αγαπημένες"
+
+#: views/elements/amo2009/collection_add_form.thtml:50
+#: views/elements/amo2009/collections_js_init.thtml:71
+msgid "collections_detail_button_remove"
+msgstr "ΑφαίÏεση από τις αγαπημένες"
+
+#. %1$s is a URL.
+#. %2$s is a full <a href>.
+#: views/collections/detail.thtml:62
+msgid "collections_detail_created_desc"
+msgstr "<p>ΜποÏείτε να δείτε τη νέα σας συλλογή παÏακάτω. Αν θέλετε να της δώσετε ένα ψευδώνυμο, να αποστείλετε ένα εικονίδιο, ή να αλλάξετε άλλες Ïυθμίσεις, παÏακαλοÏμε επισκεφθείτε τη σελίδα <a href='%1$s'>διαχείÏισης συλλογών</a>.</p><p>ΜποÏείτε να έχετε Ï€Ïόσβαση στη σελίδα της συλλογής σας σ' αυτή την τοποθεσία: %2$s</p>"
+
+#: views/collections/detail.thtml:61
+msgid "collections_detail_created_msg"
+msgstr "Η συλλογή σας είναι έτοιμη!"
+
+#: views/collections/detail.thtml:109
+msgid "collections_detail_header_about"
+msgstr "ΠεÏί της συλλογής"
+
+#. %1$s is a number.
+#: views/collections/detail.thtml:126
+msgid "collections_detail_header_count"
+msgid_plural "collections_detail_header_count"
+msgstr[0] "%1$s Ï€Ïόσθετο σ' αυτή τη συλλογή"
+msgstr[1] "%1$s Ï€Ïόσθετα σ' αυτή τη συλλογή"
+
+#: views/collections/detail.thtml:113
+msgid "collections_detail_info_created"
+msgstr "<strong>ΔημιουÏγήθηκε από:</strong> %1$s"
+
+#: views/collections/detail.thtml:117
+msgid "collections_detail_info_updated"
+msgstr "<strong>ΕνημεÏώθηκε:</strong>"
+
+#: views/elements/amo2009/collections_js_init.thtml:62
+msgid "collections_detail_js_adding"
+msgstr "Γίνεται Ï€Ïοσθήκη στις αγαπημένες&hellip;"
+
+#: views/elements/amo2009/collections_js_init.thtml:65
+msgid "collections_detail_js_removing"
+msgstr "ΑφαιÏείται από τις αγαπημένες&hellip;"
+
+#. %1$s is a URL
+#: views/collections/detail.thtml:90
+msgid "collections_detail_login"
+msgstr "<a href=\"%1$s\">Συνδεθείτε</a> για να Ï€Ïοσθέσετε αυτή τη συλλογή στις αγαπημένες σας."
+
+#: views/collections/detail.thtml:104
+msgid "collections_detail_manage"
+msgstr "ΔιαχείÏιση συλλογής"
+
+#: controllers/collections_controller.php:298
+msgid "collections_detail_sort_date"
+msgstr "ΗμεÏομηνία Ï€Ïοσθήκης"
+
+#: controllers/collections_controller.php:299
+msgid "collections_detail_sort_name"
+msgstr "Όνομα"
+
+#: controllers/collections_controller.php:300
+msgid "collections_detail_sort_popularity"
+msgstr "Δημοτικότητα"
+
+#. %1$s is a number.
+#: views/collections/detail.thtml:166
+msgid "collections_detail_weekly_downloads"
+msgid_plural "collections_detail_weekly_downloads"
+msgstr[0] "%1$s λήψη αυτή την εβδομάδα"
+msgstr[1] "%1$s λήψεις αυτή την εβδομάδα"
+
+#: views/collections/edit.thtml:255
+msgid "collections_edit_addons_delete_noscript"
+msgstr "Τα επιλεγμένα Ï€Ïόσθετα θα αφαιÏεθοÏν κατά την αποθήκευση"
+
+#: views/collections/edit.thtml:247
+msgid "collections_edit_addons_description"
+msgstr "Για να δημοσιεÏσετε νέα Ï€Ïόσθετα σ' αυτή τη συλλογή, πληκτÏολογήστε τα ονόματα τους παÏακάτω."
+
+#: views/collections/edit.thtml:248
+msgid "collections_edit_addons_description_noscript"
+msgstr "Για να δημοσιεÏσετε νέα Ï€Ïόσθετα σ' αυτή τη συλλογή, εισάγετε παÏακάτω μια λίστα αναγνωÏιστικών (ID) Ï€Ïόσθετων διαχωÏισμένων με κόμματα."
+
+#: views/collections/edit.thtml:247
+#: views/collections/edit.thtml:248
+msgid "collections_edit_addons_description_publish_detailspage"
+msgstr "ΜποÏείτε επίσης να δημοσιεÏσετε ένα Ï€Ïόσθετο από την κανονική σελίδα παÏουσίασης του."
+
+#. %1$s is the date the add-on was added to the collection
+#. %1$s is the name of the user who added the add-on to the collection
+#: views/collections/edit.thtml:260
+msgid "collections_edit_addons_listitem_added"
+msgstr "ΠÏοστέθηκε στι %1$s από %2$s"
+
+#: views/collections/edit.thtml:263
+msgid "collections_edit_addons_listitem_comment_add"
+msgstr "ΠÏοσθήκη σχολίου εκδότη"
+
+#: views/collections/edit.thtml:266
+msgid "collections_edit_addons_listitem_comment_delete"
+msgstr "ΔιαγÏαφή σχολίου εκδότη"
+
+#: views/collections/edit.thtml:265
+msgid "collections_edit_addons_listitem_comment_edit"
+msgstr "ΕπεξεÏγασία σχολίου εκδότη"
+
+#: views/collections/edit.thtml:271
+msgid "collections_edit_addons_listitem_comment_note"
+msgstr "Σημείωση: Το σχόλιο θα εμφανιστεί ως σχόλιο του αÏÏ‡Î¹ÎºÎ¿Ï ÎµÎºÎ´ÏŒÏ„Î· με την Ï€Ïαγματική ημεÏομηνία έκδοσης"
+
+#: views/collections/edit.thtml:270
+msgid "collections_edit_addons_listitem_comment_submit"
+msgstr "Αποθήκευση σχολίου"
+
+#: views/collections/edit.thtml:261
+msgid "collections_edit_addons_listitem_remove"
+msgstr "ΑφαίÏεση"
+
+#: views/collections/edit.thtml:250
+msgid "collections_edit_addons_submit"
+msgstr "ΠÏοσθήκη σε συλλογή"
+
+#: views/collections/edit.thtml:153
+msgid "collections_edit_check_nickname"
+msgstr "Έλεγχος διαθεσιμότητας"
+
+#: views/collections/edit.thtml:299
+msgid "collections_edit_confirm_deletecollection"
+msgstr "Îαι, θέλω να διαγÏάψω αυτή τη συλλογή."
+
+#. %1$s is the label of the edit form's submit button
+#: views/collections/edit.thtml:300
+msgid "collections_edit_confirm_deletecollection_description"
+msgstr "Επιλέξτε το πλαίσιο και μετά κάντε κλικ στο «%1$s» για να διαγÏάψετε τη συλλογή."
+
+#. %1$s is the "delete" submit button text
+#. %2$s is the title of the "advanced" tab
+#: views/collections/edit.thtml:95
+msgid "collections_edit_delete_upon_submit"
+msgstr "Κάνοντας κλικ στο κουμπί «%1$s» παÏακάτω, η συλλογή σας θα διαγÏαφεί. Αν δεν θέλετε να διαγÏαφεί η συλλογή σας, απεπιλέξτε το πλαίσιο επιβεβαίωσης στην καÏτέλα «%2$s» και συνεχίστε την επεξεÏγασία της συλλογής σας. Αν αποχωÏήσετε από τη σελίδα χωÏίς να αποθηκεÏσετε τις αλλαγές, η συλλογή σας δεν θα διαγÏαφεί."
+
+#: views/collections/edit.thtml:94
+msgid "collections_edit_delete_warning"
+msgstr "Η συλλογή σας Ï€Ïόκειται να διαγÏαφεί!"
+
+#: views/collections/add.thtml:76
+#: views/collections/edit.thtml:144
+msgid "collections_edit_form_error_description"
+msgstr "ΠÏέπει να δώσετε μια πεÏιγÏαφή της συλλογής σας."
+
+#: views/collections/edit.thtml:181
+msgid "collections_edit_form_error_icon"
+msgstr "ΠαÏουσιάστηκε σφάλμα κατά τη μεταφοÏά του εικονιδίου σας."
+
+#: views/collections/add.thtml:69
+#: views/collections/edit.thtml:130
+msgid "collections_edit_form_error_name"
+msgstr "ΠÏέπει να δώσετε ένα όνομα στη συλλογή σας."
+
+#: views/collections/edit.thtml:158
+msgid "collections_edit_form_error_nickname"
+msgstr "Αν επιλέξετε ψευδώνυμο, θα Ï€Ïέπει να είναι μοναδικό."
+
+#: views/collections/add.thtml:93
+#: views/collections/edit.thtml:249
+msgid "collections_edit_formfield_addons"
+msgstr "Όνομα Ï€Ïόσθετου:"
+
+#: views/collections/edit.thtml:281
+msgid "collections_edit_formfield_application"
+msgstr "Σχετιζόμενο Ï€ÏόγÏαμμα"
+
+#: views/collections/edit.thtml:282
+msgid "collections_edit_formfield_application_description"
+msgstr "Επιλέξτε το Ï€ÏόγÏαμμα που υποστηÏίζει η συλλογή σας."
+
+#: views/collections/edit.thtml:288
+msgid "collections_edit_formfield_collectiontype"
+msgstr "ΤÏπος συλλογής"
+
+#: views/collections/edit.thtml:295
+msgid "collections_edit_formfield_deletecollection"
+msgstr "ΔιαγÏαφή συλλογής"
+
+#: views/collections/edit.thtml:296
+msgid "collections_edit_formfield_deletecollection_description"
+msgstr "Η διαγÏαφή της συλλογής σας θα είναι οÏιστική."
+
+#: views/collections/add.thtml:73
+#: views/collections/edit.thtml:140
+msgid "collections_edit_formfield_description"
+msgstr "ΠεÏιγÏαφή συλλογής"
+
+#: views/collections/add.thtml:74
+#: views/collections/edit.thtml:141
+msgid "collections_edit_formfield_description_description"
+msgstr "ΠεÏιγÏάψτε συνοπτικά τη συλλογή σας και τους Ï„Ïπους Ï€Ïόσθετων που πεÏιέχει"
+
+#: views/collections/edit.thtml:162
+msgid "collections_edit_formfield_icon"
+msgstr "Εικονίδιο"
+
+#: views/collections/edit.thtml:163
+msgid "collections_edit_formfield_icon_description"
+msgstr "ΜποÏείτε να αποστείλετε ένα εικονίδιο σε μοÏφή JPG, GIF ή PNG του οποίου το μέγεθος θα μετατÏαπεί σε 32x32 πίξελ."
+
+#: views/collections/add.thtml:80
+#: views/collections/edit.thtml:189
+msgid "collections_edit_formfield_listed"
+msgstr "Σε ποιους θα είναι οÏατή η συλλογή σας;"
+
+#: views/collections/add.thtml:81
+#: views/collections/edit.thtml:190
+msgid "collections_edit_formfield_listed_description"
+msgstr "Σαν αÏχική επιλογή, οι συλλογές εμφανίζονται στον δημόσιο κατάλογο συλλογών και μποÏεί να τις δει οποιοσδήποτε. Αν θέλετε να πεÏιοÏίσετε την έκθεση της συλλογής σας σε ανθÏώπους που θα έχουν λάβε ένα δεσμό Ï€Ïος αυτή, επιλέξτε την παÏακάτω επιλογή."
+
+#: views/collections/add.thtml:84
+#: views/collections/edit.thtml:193
+msgid "collections_edit_formfield_listed_false"
+msgstr "Μόνο όσοι Ï€Ïοσκαλώ θα μποÏοÏν να δουν τη συλλογή μου"
+
+#: views/collections/add.thtml:83
+#: views/collections/edit.thtml:192
+msgid "collections_edit_formfield_listed_true"
+msgstr "Οποιοσδήποτε μποÏεί να δει τη συλλογή μου στον κατάλογο"
+
+#: views/collections/edit.thtml:223
+msgid "collections_edit_formfield_managers"
+msgstr "Ποιος μποÏεί να διαχειÏιστεί τη συλλογή μου;"
+
+#: views/collections/edit.thtml:224
+msgid "collections_edit_formfield_managers_description"
+msgstr "Αυτοί οι χÏήστες θα μποÏοÏν να δημοσιεÏσουν Ï€Ïόσθετα στη συλλογή σας, να διαχειÏιστοÏν όλα τα Ï€Ïόσθετα που πεÏιέχει και να παÏέχουν δικαιώματα σε άλλους χÏήστες."
+
+#: views/collections/add.thtml:66
+#: views/collections/edit.thtml:126
+msgid "collections_edit_formfield_name"
+msgstr "Όνομα συλλογής"
+
+#: views/collections/add.thtml:67
+#: views/collections/edit.thtml:127
+msgid "collections_edit_formfield_name_description"
+msgstr "Δώστε στη συλλογή σας ένα πεÏιγÏαφικό όνομα, όπως πχ «Η συλλογή για Ï€ÏογÏαμματισμό του Γιάννη»"
+
+#: views/collections/edit.thtml:148
+msgid "collections_edit_formfield_nickname"
+msgstr "Ψευδώνυμο συλλογής"
+
+#: views/collections/edit.thtml:149
+msgid "collections_edit_formfield_nickname_description"
+msgstr "ΠÏοαιÏετικά, μποÏείτε να δώσετε ένα ψευδώνυμο στη συλλογή σας για πιο εÏκολη Ï€Ïόσβαση σ' αυτή:"
+
+#: views/collections/edit.thtml:201
+msgid "collections_edit_formfield_publishers"
+msgstr "Ποιος μποÏεί να δημοσιεÏσει Ï€Ïόσθετα στη συλλογή σας;"
+
+#: views/collections/edit.thtml:202
+msgid "collections_edit_formfield_publishers_description"
+msgstr "Αυτοί οι χÏήστες θα μποÏοÏν να δημοσιεÏσουν Ï€Ïόσθετα στη συλλογή σας και να αφαιÏέσουν όσα Ï€Ïοσθέτουν."
+
+#: views/collections/edit.thtml:210
+#: views/collections/edit.thtml:232
+msgid "collections_edit_formfield_users_add"
+msgstr "Εισάγετε τη διεÏθυνση ηλεκτÏÎ¿Î½Î¹ÎºÎ¿Ï Ï„Î±Ï‡Ï…Î´Ïομείου λογαÏÎ¹ÏƒÎ±Î¼Î¿Ï ÏƒÏ„Î± Ï€Ïόσθετα Firefox:"
+
+#: views/collections/edit.thtml:216
+#: views/collections/edit.thtml:238
+msgid "collections_edit_formfield_users_delete_noscript"
+msgstr "Οι επιλεγμένοι λογαÏιασμοί θα αφαιÏεθοÏνκατά την «Αποθήκευση»"
+
+#: views/collections/edit.thtml:215
+#: views/collections/edit.thtml:237
+msgid "collections_edit_formfield_users_new_noscript"
+msgstr "Εισάγετε μια λίστα διευθÏνσεων ηλ. ταχυδÏομείου χÏηστών των Ï€Ïόσθετων Firefox διαχωÏισμένη με κόμματα"
+
+#: views/collections/edit.thtml:204
+#: views/collections/edit.thtml:226
+msgid "collections_edit_formfield_users_onlyme"
+msgstr "Μόνο εγώ"
+
+#: views/collections/edit.thtml:205
+#: views/collections/edit.thtml:227
+msgid "collections_edit_formfield_users_otherusers"
+msgstr "Εγώ και αυτοί οι χÏήστες:"
+
+#: views/collections/edit.thtml:211
+#: views/collections/edit.thtml:233
+msgid "collections_edit_formfield_users_submit"
+msgstr "ΠÏοσθήκη"
+
+#. %1$s is the name of the collection
+#: views/collections/edit.thtml:68
+msgid "collections_edit_header"
+msgstr "ΔιαχείÏιση συλλογής %1$s"
+
+#: views/collections/edit.thtml:246
+msgid "collections_edit_header_addons"
+msgstr "ΔιαχείÏιση πεÏιεχομένων συλλογής"
+
+#: views/collections/edit.thtml:253
+#: views/collections/edit.thtml:258
+msgid "collections_edit_header_addons_current"
+msgstr "ΤÏέχοντα Ï€Ïόσθετα:"
+
+#: views/collections/edit.thtml:279
+msgid "collections_edit_header_advanced"
+msgstr "Επιλογές για Ï€ÏοχωÏημένους"
+
+#: views/collections/edit.thtml:186
+msgid "collections_edit_header_permissions"
+msgstr "ΔιαχείÏιση δικαιωμάτων συλλογής"
+
+#: views/collections/edit.thtml:170
+msgid "collections_edit_icon_cancel"
+msgstr "ΑκÏÏωση"
+
+#: views/collections/edit.thtml:174
+#: views/collections/edit.thtml:179
+msgid "collections_edit_icon_delete"
+msgstr "ΔιαγÏαφή εικονιδίου"
+
+#: views/collections/edit.thtml:178
+msgid "collections_edit_icon_replace"
+msgstr "Αντικατάσταση εικονιδίου"
+
+#. %1$s is the label of the edit form's submit button
+#: views/collections/edit.thtml:169
+msgid "collections_edit_icon_toberemoved"
+msgstr "Το εικονίδιο θα αφαιÏεθεί όταν κάνετε κλικ στο κουμπί «%1$s» παÏακάτω"
+
+#: views/collections/edit.thtml:155
+msgid "collections_edit_nickname_available"
+msgstr "Το ψευδώνυμο είναι διαθέσιμο"
+
+#: controllers/collections_controller.php:943
+msgid "collections_edit_nickname_error"
+msgstr "Το ψευδώνυμο σας πεÏιείχε μη αποδεκτοÏÏ‚ χαÏακτήÏες και διοÏθώθηκε. ΠαÏακαλοÏμε Ï€Ïοσπαθήστε ξανά."
+
+#: views/collections/edit.thtml:156
+msgid "collections_edit_nickname_taken"
+msgstr "Το ψευδώνυμο χÏησιμοποιείται ήδη"
+
+#. This string is followed by a URL pointing to the collection's view page
+#: views/collections/edit.thtml:75
+msgid "collections_edit_saved_nextstep"
+msgstr "ΜποÏείτε να δείτε τη συλλογή σας σ' αυτή τη διεÏθυνση:"
+
+#: views/collections/edit.thtml:74
+msgid "collections_edit_saved_success"
+msgstr "Η συλλογή σας αποθηκεÏτηκε με επιτυχία!"
+
+#: views/collections/edit.thtml:169
+#: views/collections/edit.thtml:300
+#: views/collections/edit.thtml:308
+#: views/pages/js_constants.js.thtml:99
+msgid "collections_edit_submit"
+msgstr "ΕνημέÏωση συλλογής"
+
+#: views/collections/edit.thtml:96
+#: views/collections/edit.thtml:297
+#: views/pages/js_constants.js.thtml:100
+msgid "collections_edit_submit_deletecollection"
+msgstr "ΔιαγÏαφή συλλογής"
+
+#: views/collections/edit.thtml:111
+msgid "collections_edit_tabheader_addons"
+msgstr "ΠÏόσθετα"
+
+#: views/collections/edit.thtml:97
+#: views/collections/edit.thtml:113
+msgid "collections_edit_tabheader_advanced"
+msgstr "Για Ï€ÏοχωÏημένους"
+
+#: views/collections/edit.thtml:108
+msgid "collections_edit_tabheader_details"
+msgstr "Όνομα &amp; ΛεπτομέÏειες"
+
+#: views/collections/edit.thtml:109
+msgid "collections_edit_tabheader_permissions"
+msgstr "Δικαιώματα"
+
+#: models/collection_promo.php:53
+msgid "collections_family_tagline"
+msgstr "ΠÏόσθετα που μποÏοÏν να Ï€Ïοσέχουν τις δÏαστηÏιότητες των παιδιών σας και το ημεÏολόγιο σας."
+
+#: models/collection_promo.php:53
+msgid "collections_family_title"
+msgstr "Οικογενειακά"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:70
+msgid "collections_index_a_check_out"
+msgstr "Δείτε το Add-on Collector"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:52
+msgid "collections_index_a_create"
+msgstr "ΔημιουÏγία συλλογής"
+
+#: views/collections/detail.thtml:139
+#: views/collections/listing.thtml:85
+#: views/search/collections.thtml:84
+msgid "collections_index_button_go"
+msgstr "ΕμπÏός"
+
+#. %1$s is a URL.
+#: controllers/collections_controller.php:182
+msgid "collections_index_filler_favorites"
+msgstr "<p><strong>Δεν έχετε καμία συλλογή στις αγαπημένες σας ακόμη.</strong></p> <p>ΜποÏείτε να έχετε εÏκολη Ï€Ïόσβαση στις συλλογές που επισημαίνετε σαν αγαπημένες απ' αυτή τη σελίδα και επίσης θα εμφανίζονται στο Ï€Ïόσθετο <a href='%1$s'>Add-on Collector</a> αν το έχετε εγκαταστήσει.</p>"
+
+#. %1$s is a URL.
+#: controllers/collections_controller.php:167
+msgid "collections_index_filler_mine"
+msgstr "<p>Δεν έχετε δημιουÏγήσει ακόμη καμία συλλογή. Είναι εÏκολο να δημιουÏγήσετε συλλογές και να Ï€Ïοσθέσετε τα αγαπημένα σας Ï€Ïόσθετα σ' αυτές. <a href='%1$s'>Δοκιμάστε το</a>!</p>"
+
+#: views/collections/listing.thtml:51
+msgid "collections_index_header_collections"
+msgstr "Συλλογές"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:60
+msgid "collections_index_header_collector"
+msgstr "Add-on Collector"
+
+#. %1$s is a comma-separated list of author names
+#: views/elements/amo2009/collection_listing_item.thtml:84
+#: views/collections/detail.thtml:151
+msgid "collections_index_header_created"
+msgstr "δημιουÏγήθηκε από %1$s"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:47
+msgid "collections_index_header_what"
+msgstr "Τι είναι οι συλλογές;"
+
+#: views/collections/detail.thtml:132
+#: views/collections/listing.thtml:78
+#: views/search/collections.thtml:66
+msgid "collections_index_label_sortby"
+msgstr "Ταξινόμηση με βάση"
+
+#: controllers/collections_controller.php:130
+msgid "collections_index_li_editors"
+msgstr "Επιλογές συντακτών"
+
+#: views/collections/subscribe.thtml:64
+#: controllers/collections_controller.php:140
+msgid "collections_index_li_favorites"
+msgstr "Οι αγαπημένες μου"
+
+#: controllers/collections_controller.php:138
+msgid "collections_index_li_mine"
+msgstr "Οι συλλογές μου"
+
+#: controllers/collections_controller.php:132
+msgid "collections_index_li_popular"
+msgstr "Δημοφιλείς"
+
+#: views/search/collections.thtml:74
+#: controllers/collections_controller.php:81
+msgid "collections_index_option_all"
+msgstr "Πιο δημοφιλείς όλων των καιÏών"
+
+#: views/search/collections.thtml:72
+#: controllers/collections_controller.php:78
+msgid "collections_index_option_month"
+msgstr "Πιο δημοφιλείς αυτό τον μήνα"
+
+#: views/search/collections.thtml:76
+#: controllers/collections_controller.php:84
+msgid "collections_index_option_newest"
+msgstr "Πιο Ï€Ïόσφατες"
+
+#: views/search/collections.thtml:70
+#: controllers/collections_controller.php:75
+msgid "collections_index_option_week"
+msgstr "Πιο δημοφιλείς αυτή την εβδομάδα"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:67
+msgid "collections_index_p_collector"
+msgstr "ΥπάÏχει ένας νέος Ï„Ïόπος να διαχειÏιστείτε και να βÏείτε ενδιαφέÏοντα Ï€Ïόσθετα. Σχολιάστε, μοιÏαστείτε και συγχÏονίστε συλλογές και όλα αυτά μέσα απ' τον πεÏιηγητή σας."
+
+#: views/elements/amo2009/collector_info_secondary.thtml:48
+msgid "collections_index_p_what_are"
+msgstr "Οι συλλογές είναι σÏνολα σχετικών Ï€Ïόσθετων που ομαδοποιοÏνται για να μποÏοÏν να μοιÏαστοÏν εÏκολα."
+
+#. %s is a date in the _('date') format
+#: views/elements/collections_interactive_addon.thtml:85
+#, php-format
+msgid "collections_interactive_addon_added"
+msgstr "ΠÏοστέθηκε"
+
+#: models/collection_promo.php:55
+msgid "collections_reference_tagline"
+msgstr "ΠÏόσθετα που μποÏοÏν να βελτιστοποιήσουν τις αναζητήσεις στο διαδίκτυο."
+
+#: models/collection_promo.php:55
+msgid "collections_reference_title"
+msgstr "ΠληÏοφοÏίες"
+
+#: models/collection_promo.php:52
+msgid "collections_social_tagline"
+msgstr "ΠÏόσθετα που μποÏοÏν να διαχειÏιστοÏν τα κοινωνικά σας δίκτυα."
+
+#: models/collection_promo.php:52
+msgid "collections_social_title"
+msgstr "Κοινωνικά"
+
+#: views/collections/subscribe.thtml:91
+msgid "collections_subscribe_button_close"
+msgstr "Κλείσιμο"
+
+#: views/collections/subscribe.thtml:70
+msgid "collections_subscribe_error"
+msgstr "ΠαÏουσιάστηκε σφάλμα κατά την Ï€Ïοσθήκη συλλογής στις αγαπημένες. Μήπως ήταν ήδη στις αγαπημένες η συλλογή;"
+
+#: views/collections/subscribe.thtml:96
+msgid "collections_subscribe_label_bothersome"
+msgstr "Îα μην εμφανιστεί ξανά."
+
+#. %1$s is the collection name
+#: views/collections/subscribe.thtml:60
+msgid "collections_subscribe_success"
+msgstr "Η συλλογή «%1$s» Ï€Ïοστέθηκε στις αγαπημένες σας."
+
+#. %1$s is the link to the "My Favorites" tab on the main collections page
+#. %2$s is the localized title of the "My Favorites" tab
+#. %3$s is the link URL to the collector add-on
+#: views/collections/subscribe.thtml:62
+msgid "collections_subscribe_success_desc"
+msgstr "ΜποÏείτε Ï„ÏŽÏα να εντοπίσετε γÏήγοÏα αυτή τη συλλογή από την καÏτέλα <a href=\"%1$s\">%2$s</a> του καταλόγου. Για ένα ακόμα πιο εÏκολο Ï„Ïόπο παÏακολοÏθησης των αγαπημένων σας συλλογών, δοκιμάστε την επέκταση <a href=\"%3$s\">Add-on Collector</a> για τον Firefox."
+
+#: views/collections/listing.thtml:55
+msgid "collections_success_delete"
+msgstr "Η συλλογή διαγÏάφηκε."
+
+#: models/collection_promo.php:54
+msgid "collections_travel_tagline"
+msgstr "ΠÏόσθετα που μποÏοÏν να σας μετατÏέψουν σε ταξιδιωτικό Ï€ÏάκτοÏα."
+
+#: models/collection_promo.php:54
+msgid "collections_travel_title"
+msgstr "Ταξιδιωτικά"
+
+#. A collection of add-ons that is automatically built for a user. They are "automatically published" to this collection.
+#: controllers/collections_controller.php:581
+msgid "collections_type_autopublisher"
+msgstr "Αυτόματη δημοσίευση"
+
+#. A collection that has been chosen by an Editor as notable or exceptional
+#: controllers/collections_controller.php:582
+msgid "collections_type_editorspick"
+msgstr "Επιλογές συντακτών"
+
+#: controllers/collections_controller.php:580
+msgid "collections_type_normal"
+msgstr "Κανονική"
+
+#: views/collections/subscribe.thtml:84
+msgid "collections_unsubscribe_error"
+msgstr "ΠαÏουσιάστηκε σφάλμα κατά την αφαίÏεση συλλογής από τις αγαπημένες. Μήπως δεν άνηκε στις αγαπημένες η συλλογή;"
+
+#. %1$s is the collection name
+#: views/collections/subscribe.thtml:78
+msgid "collections_unsubscribe_success"
+msgstr "Η συλλογή «%1$s» αφαιÏέθηκε από τις αγαπημένες σας."
+
+#: models/collection_promo.php:56
+msgid "collections_webdev_tagline"
+msgstr "ΠÏόσθετα που θα σας διευκολÏνουν να φτιάξετε την τέλεια ιστοσελίδα."
+
+#: models/collection_promo.php:56
+msgid "collections_webdev_title"
+msgstr "ΔημιουÏγικά"
+
+#: views/elements/amo2009/collections_sidebar_whatare.thtml:40
+msgid "collections_whatare_header"
+msgstr "Τι είναι οι συλλογές;"
+
+#: views/elements/amo2009/collections_sidebar_whatare.thtml:45
+msgid "collections_whatare_learnmore"
+msgstr "Διαβάστε τις συχνές εÏωτήσεις"
+
+#: views/elements/amo2009/collections_sidebar_whatare.thtml:44
+msgid "collections_whatare_text"
+msgstr "ΥπάÏχει ένας νέος Ï„Ïόπος να διαχειÏιστείτε και να βÏείτε ενδιαφέÏοντα Ï€Ïόσθετα. Σχολιάστε, μοιÏαστείτε και συγχÏονίστε συλλογές και όλα αυτά μέσα απ' τον πεÏιηγητή σας."
+
+#: views/pages/collector_faq.thtml:61
+#: views/pages/collector_features.thtml:67
+msgid "collector_features_a_home"
+msgstr "ΑÏχική σελίδα του Add-on Collector"
+
+#: views/elements/amo2009/collector_sidebar_download.thtml:46
+msgid "collector_features_heading_download"
+msgstr "Λήψη του Add-on Collector:"
+
+#: views/elements/amo2009/collector_sidebar_download.thtml:43
+#: views/pages/collector_firstrun.thtml:116
+#: views/pages/collector.thtml:69
+msgid "collector_features_img_logo"
+msgstr "Λογότυπο Add-on Collector"
+
+#: views/compatibility/dashboard.thtml:49
+#: controllers/compatibility_controller.php:72
+msgid "compatibility_dashboard_center_header"
+msgstr "ΚέντÏο συμβατότητας Ï€Ïόσθετων"
+
+#. %1$s is the name of an application and a version. Example: Firefox 3.0
+#. %2$s is the name of an application. Example: Firefox
+#: views/compatibility/dashboard.thtml:50
+msgid "compatibility_dashboard_intro"
+msgstr "ΠÏοετοιμαστείτε για την έκδοση του %1$s με τα εÏγαλεία και τις πληÏοφοÏίες που διαθέτουμε για την κοινότητα Ï€Ïόσθετων του %2$s και θα βÏείτε παÏακάτω."
+
+#: views/compatibility/dashboard.thtml:103
+msgid "compatibility_dashboard_loading"
+msgstr "ΦόÏτωση δεδομένων..."
+
+#: views/compatibility/dashboard.thtml:45
+msgid "compatibility_dashboard_main_link"
+msgstr "Πίσω στην κεντÏική"
+
+#: views/compatibility/dashboard.thtml:100
+#: views/compatibility/report.thtml:43
+msgid "compatibility_dashboard_report"
+msgstr "ΑναφοÏά συμβατότητας Ï€Ïόσθετου"
+
+#: views/compatibility/dashboard.thtml:53
+#: views/compatibility/dashboard.thtml:110
+#: views/compatibility/developers.thtml:43
+msgid "compatibility_developer_info"
+msgstr "ΠληÏοφοÏίες για δημιουÏγοÏÏ‚ Ï€Ïόσθετων"
+
+#: views/compatibility/developers.thtml:66
+msgid "compatibility_developers_adjust_maxversion"
+msgstr "ΠÏοσαÏμογή του maxVersion χωÏίς αποστολή"
+
+#: views/compatibility/dashboard.thtml:124
+msgid "compatibility_developers_check_status"
+msgstr "Έλεγχος κατάστασης των Ï€Ïόσθετων μου"
+
+#. %1$s is a URL
+#. %2$s is an application and version. Example: Firefox 3.0
+#: views/compatibility/dashboard.thtml:126
+msgid "compatibility_developers_login_first"
+msgstr "Αν φιλοξενοÏνται Ï€Ïόσθετα σας στον ιστότοπο Ï€Ïόσθετων Mozilla, <a href=\"%1$s\">παÏακαλοÏμε συνδεθείτε</a> για να δείτε την ανάλυση της κατάστασης του Ï€Ïοσθέτου σας σε σχέση με τον %2$s."
+
+#: views/compatibility/dashboard.thtml:114
+msgid "compatibility_developers_mdclogo_alt"
+msgstr "Λογότυπο κέντÏου δημιουÏγών Mozilla"
+
+#: views/compatibility/developers.thtml:73
+msgid "compatibility_developers_no_addons"
+msgstr "Δεν φιλοξενείται κανένα Ï€Ïόσθετο σας στον ιστότοπο Ï€Ïόσθετων Mozilla."
+
+#: views/compatibility/dashboard.thtml:133
+#: views/compatibility/developers.thtml:55
+msgid "compatibility_developers_results"
+msgstr "Αποτελέσματα ελέγχου κατάστασης Ï€Ïόσθετου"
+
+#: views/compatibility/dashboard.thtml:137
+msgid "compatibility_developers_retrieving"
+msgstr "Ανάκτηση κατάστασης φιλοξενοÏμενων Ï€Ïόσθετων..."
+
+#. %1$s is a number
+#. %2$s is an application name
+#. %3$s is a number.
+#. Full example: 50 Firefox users (10% of total)
+#: views/compatibility/developers.thtml:65
+msgid "compatibility_developers_user_count"
+msgstr "%1$s χÏήστες του %2$s (%3$s&#37; του συνόλου)"
+
+#: views/compatibility/report.thtml:45
+msgid "compatibility_report_detail_intro"
+msgstr "Τα παÏακάτω Ï€Ïόσθετα αποτελοÏν το 95% των Ï€Ïόσθετων σε χÏήση που γνωÏίζει ο οÏγανισμός Mozilla και είναι ταξινομημένα κατά ποσοστό χÏηστών."
+
+#: views/compatibility/dashboard.thtml:94
+msgid "compatibility_report_detailed_link"
+msgstr "ΠÏοβολή αναλυτικής αναφοÏάς"
+
+#. %1$s and %2$s are numbers
+#. %3$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:65
+msgid "compatibility_report_intro"
+msgstr "Από τα %1$s Ï€Ïόσθετα που συνθέτουν το 95&#37; της χÏήσης Ï€Ïόσθετων που γνωÏίζει ο οÏγανισμός Mozilla, το <b>%2$s&#37;</b> θεωÏείται Ï€Ïος το παÏόν συμβατό με τις πιο Ï€Ïόσφατες εκδόσεις του %3$s."
+
+#: views/compatibility/dashboard.thtml:81
+msgid "compatibility_report_legend_alpha"
+msgstr "Δοκιμαστικές εκδόσεις άλφα"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:81
+msgid "compatibility_report_legend_alpha_description"
+msgstr "ΠÏόσθετα συμβατά με δοκιμαστική έκδοση άλφα του %1$s"
+
+#: views/compatibility/dashboard.thtml:85
+msgid "compatibility_report_legend_beta"
+msgstr "Δοκιμαστικές εκδόσεις βήτα"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:85
+msgid "compatibility_report_legend_beta_description"
+msgstr "ΠÏόσθετα συμβατά με δοκιμαστικές βήτα ή υποψήφιες για κυκλοφοÏία εκδόσεις του %1$s"
+
+#: views/compatibility/dashboard.thtml:89
+msgid "compatibility_report_legend_latest"
+msgstr "Πιο Ï€Ïόσφατη έκδοση"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:89
+msgid "compatibility_report_legend_latest_description"
+msgstr "ΠÏόσθετα που συμβαδίζουν με τις πιο Ï€Ïόσφατες εκδόσεις του %1$s"
+
+#: views/compatibility/dashboard.thtml:77
+msgid "compatibility_report_legend_other"
+msgstr "Άλλες εκδόσεις"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:77
+msgid "compatibility_report_legend_other_description"
+msgstr "ΠÏόσθετα που δεν είναι συμβατά με καμία έκδοση του %1$s"
+
+#: views/compatibility/dashboard.thtml:62
+msgid "compatibility_report_title"
+msgstr "ΑναφοÏά συμβατότητας Ï€Ïόσθετου"
+
+#: views/compatibility/dashboard.thtml:54
+#: views/compatibility/dashboard.thtml:144
+#: views/compatibility/users.thtml:42
+msgid "compatibility_user_info"
+msgstr "ΠληÏοφοÏίες για τους χÏήστες του Ï€Ïόσθετου"
+
+#: views/compatibility/dashboard.thtml:52
+msgid "compatibility_view_report"
+msgstr "ΠÏοβολή αναφοÏάς συμβατότητας"
+
+#. %s is a URL
+#: views/pages/credits.thtml:142
+#, php-format
+msgid "credits_contributing"
+msgstr "Για πληÏοφοÏίες σχετικές με συνεισφοÏές, παÏακαλοÏμε δείτε τη %s."
+
+#: views/pages/credits.thtml:142
+msgid "credits_contributing_wikipage"
+msgstr "σελίδα wiki"
+
+#: views/pages/credits.thtml:99
+msgid "credits_intro"
+msgstr "Ο οÏγανισμός Mozilla ευχαÏιστεί τους ακόλουθους ανθÏώπους για τη συνεισφοÏά τους στο έÏγο addons.mozilla.org:"
+
+#: views/pages/credits.thtml:103
+msgid "credits_section_developers"
+msgstr "ΔημιουÏγοί"
+
+#: views/pages/credits.thtml:115
+msgid "credits_section_editors"
+msgstr "Συντάκτες"
+
+#: views/pages/credits.thtml:109
+msgid "credits_section_localizers"
+msgstr "ΜεταφÏαστές"
+
+#: views/pages/credits.thtml:121
+msgid "credits_section_other_contributors"
+msgstr "Άλλες συνεισφοÏές"
+
+#: views/pages/credits.thtml:127
+msgid "credits_section_past_developers"
+msgstr "ΠαÏελθόντες δημιουÏγοί"
+
+#: views/pages/credits.thtml:133
+msgid "credits_section_software"
+msgstr "Λογισμικό και γÏαφικά"
+
+#: views/pages/credits.thtml:136
+msgid "credits_software_famfamfam"
+msgstr "ΜεÏικά από τα εικονίδια που χÏησιμοποιοÏνται είναι τμήμα του <a href=\"http://www.famfamfam.com/lab/icons/silk/\">famfamfam Silk Icon Set</a>, και φέÏουν την άδεια χÏήσης <a href=\"http://creativecommons.org/licenses/by/2.5/deed.el\">Creative Commons Attribution 2.5</a>."
+
+#: views/pages/credits.thtml:137
+msgid "credits_software_timeplot"
+msgstr "ΜεÏικές σελίδες χÏησιμοποιοÏν στοιχεία του <a href=\"http://www.simile-widgets.org/timeplot/\">Timeplot</a>, που εκδίδεται σÏμφωνα με την <a href=\"http://simile.mit.edu/license.html\">άδεια BSD</a>."
+
+# date format string as used in PHP's strftime():
+# http://php.net/strftime
+#. date format string as used in PHP's strftime():
+#. http://php.net/strftime
+#: views/elements/collections_interactive_addon.thtml:85
+#: views/elements/amo2009/addon_version_detail.thtml:53
+#: views/elements/amo2009/homepage_addon.thtml:115
+#: views/elements/addon_version_detail.thtml:54
+#: views/elements/addon_listitem.thtml:124
+#: views/elements/feature.thtml:106
+#: views/collections/detail.thtml:118
+#: views/collections/edit.thtml:325
+#: views/users/info.thtml:76
+#: views/editors/reviews_queue.thtml:57
+#: views/editors/reviews_queue.thtml:68
+#: views/developers/dashboard.thtml:65
+#: views/developers/versions_edit.thtml:208
+#: views/developers/versions.thtml:67
+#: views/search/rss/index.thtml:5
+#: views/addons/rss/versions.thtml:42
+#: views/addons/display.thtml:104
+#: views/addons/display.thtml:356
+#: views/addons/browse_thumbs.thtml:75
+#: views/reviews/add.thtml:63
+#: views/reviews/display.thtml:74
+#: views/reviews/display.thtml:160
+#: views/reviews/delete.thtml:54
+#: controllers/statistics_controller.php:244
+#: controllers/collections_controller.php:1047
+msgid "date"
+msgstr "%e %B %Y"
+
+# date and time format string (strftime)
+#. date and time format string (strftime)
+#. http://php.net/strftime
+#: views/elements/addon_version_detail.thtml:53
+#: views/developers/discuss.thtml:52
+#: views/developers/discuss.thtml:62
+#: views/admin/addons_status.thtml:57
+msgid "datetime"
+msgstr "%e %B %Y, %I:%M %p"
+
+#: views/elements/developers/actionbar.thtml:47
+msgid "devcp_actionbar_link_details"
+msgstr "ΛεπτομεÏείς πληÏοφοÏίες"
+
+#: views/elements/developers/actionbar.thtml:42
+#: views/elements/developers/actionbar.thtml:50
+#: views/developers/dashboard.thtml:64
+msgid "devcp_actionbar_link_edit"
+msgstr "ΕπεξεÏγασία Ï€Ïόσθετου"
+
+#: views/elements/developers/actionbar.thtml:51
+msgid "devcp_actionbar_link_newversion"
+msgstr "Αποστολή νέας έκδοσης"
+
+#: views/elements/developers/actionbar.thtml:44
+#: views/elements/developers/actionbar.thtml:49
+#: views/developers/dashboard.thtml:73
+msgid "devcp_actionbar_link_stats"
+msgstr "Ταμπλό στατιστικών"
+
+#. %1$s is a filename, e.g. "foo.txt"
+#. %2$s is the extension, e.g. ".txt"
+#. %3$s is a list of valid extensions, like ".png, .jpg, .gif"
+#: controllers/developers_controller.php:1361
+msgid "devcp_add_previews_extension_error"
+msgstr "Το αÏχείο %1$s έχει μη έγκυÏη κατάληξη (%2$s). ΕπιτÏεπόμενες καταλήξεις: %3$s"
+
+#. %s is the filename.
+#: controllers/developers_controller.php:1394
+msgid "devcp_add_previews_save_error"
+msgstr "Το αÏχείο %s δεν ήταν δυνατό να αποθηκευθεί στη βάση δεδομένων. ΠαÏακαλοÏμε Ï€Ïοσπαθήστε ξανά."
+
+#. %1$s is the preview ID number, %2$s is the filename.
+#: controllers/developers_controller.php:1389
+msgid "devcp_add_previews_success_replace"
+msgstr "Η εικόνα Ï€Ïοεπισκόπησης %1$s αντικαταστάθηκε με επιτυχία από το αÏχείο %2$s successfully."
+
+#. %s is the filename.
+#: controllers/developers_controller.php:1391
+msgid "devcp_add_previews_success_upload"
+msgstr "Το αÏχείο %s μεταφέÏθηκε με επιτυχία. ΠαÏακάτω, μποÏείτε να Ï€Ïοσθέσετε μια λεζάντα."
+
+#: controllers/components/developers.php:1163
+msgid "devcp_additem_addontype_autodetect"
+msgstr "(αυτόματος εντοπισμός)"
+
+#: views/elements/developers/additem.thtml:76
+msgid "devcp_additem_linktitle_opensin_newwindow"
+msgstr "Άνοιγμα σε νέο παÏάθυÏο"
+
+#: views/elements/developers/additem.thtml:41
+msgid "devcp_additem_sidebar_title"
+msgstr "Υποβολή Ï€Ïόσθετου"
+
+#: views/elements/developers/additem.thtml:53
+msgid "devcp_additem_step0_newlink"
+msgstr "Συμφωνητικό δημιουÏγοÏ"
+
+#: views/elements/developers/additem.thtml:46
+msgid "devcp_additem_step1_link"
+msgstr "Βήμα 1ο: Αποστολή"
+
+#: views/elements/developers/additem.thtml:47
+msgid "devcp_additem_step2_link"
+msgstr "Βήμα 2ο: ΛεπτομέÏειες Ï€Ïόσθετου"
+
+#: views/elements/developers/additem.thtml:48
+msgid "devcp_additem_step3_link"
+msgstr "Βήμα 3ο: ΛεπτομέÏειες έκδοσης"
+
+#: views/elements/developers/additem.thtml:49
+msgid "devcp_additem_step4_link"
+msgstr "Βήμα 4ο: Τοπικοποίηση"
+
+#: views/elements/developers/additem.thtml:50
+msgid "devcp_additem_step5_link"
+msgstr "Βήμα 5ο: Επιτυχία"
+
+#: views/elements/developers/additem.thtml:76
+msgid "devcp_additem_submissionhelp_link"
+msgstr "Βοήθεια υποβολής"
+
+#: controllers/previews_controller.php:168
+#: controllers/previews_controller.php:277
+msgid "devcp_addon_field_preview_caption_displaytitle"
+msgstr "Λεζάντα Ï€Ïοεπισκόπησης"
+
+#: views/developers/addon_status.thtml:177
+msgid "devcp_addon_status_action_activate"
+msgstr "ΕνεÏγοποίηση"
+
+#: views/developers/addon_status.thtml:178
+msgid "devcp_addon_status_action_activate_description"
+msgstr "Κάντε το Ï€Ïόσθετο σας ενεÏγό για να παÏουσιάζεται στις δημόσιες λίστες και να ανταποκÏίνεται στον έλεγχο αυτόματων ενημεÏώσεων."
+
+#: views/developers/addon_status.thtml:135
+msgid "devcp_addon_status_action_complete"
+msgstr "ΟλοκλήÏωση Ï€Ïόσθετου"
+
+#: views/developers/addon_status.thtml:136
+msgid "devcp_addon_status_action_complete_description"
+msgstr "ΟλοκληÏώστε το Ï€Ïόσθετο σας και μεταφέÏετε το στο Sandbox"
+
+#: views/developers/addon_status.thtml:181
+msgid "devcp_addon_status_action_deactivate"
+msgstr "ΑπενεÏγοποίηση"
+
+#: views/developers/addon_status.thtml:182
+msgid "devcp_addon_status_action_deactivate_description"
+msgstr "ΑπενεÏγοποιήστε το Ï€Ïόσθετο σας, αποκÏÏψετε το έτσι από όλες τις δημόσιες λίστες και απενεÏγοποιήστε την ανταπόκÏιση στην υπηÏεσία ελέγχου για ενημεÏώσεις."
+
+#: views/developers/addon_status.thtml:143
+msgid "devcp_addon_status_action_move"
+msgstr "ΜεταφοÏά στο Sandbox"
+
+#: views/developers/addon_status.thtml:144
+msgid "devcp_addon_status_action_move_description"
+msgstr "ΜεταφέÏετε το Ï€Ïόσθετο σας πίσω στο Sandbox. Η ενέÏγεια είναι αναστÏέψιμη."
+
+#: views/developers/addon_status.thtml:139
+msgid "devcp_addon_status_action_nominate"
+msgstr "Θέστε υποψηφιότητα για το δημόσιο χώÏο"
+
+#: views/developers/addon_status.thtml:140
+msgid "devcp_addon_status_action_nominate_description"
+msgstr "Θέστε το Ï€Ïόσθετο σας σε υποψηφιότητα για να Ï€Ïοστεθεί στο δημόσιο χώÏο."
+
+#: views/developers/addon_status.thtml:147
+msgid "devcp_addon_status_action_public"
+msgstr "ΜεταφοÏά στο δημόσιο χώÏο"
+
+#: views/developers/addon_status.thtml:148
+msgid "devcp_addon_status_action_public_description"
+msgstr "ΜεταφέÏετε το Ï€Ïόσθετο σας και πάλι στο δημόσιο χώÏο."
+
+#: views/developers/addon_status.thtml:169
+msgid "devcp_addon_status_active"
+msgstr "Το Ï€Ïόσθετο σας είναι <span class=\"inactive-0\">ενεÏγό</span>. Αυτό σημαίνει ωπς θα εμφανίζεται σε όλους τους διαθέσιμους χώÏους που αναλογοÏν στην κατάσταση του."
+
+#: views/developers/addon_status.thtml:111
+msgid "devcp_addon_status_completion_disabled"
+msgstr "ΠαÏακαλοÏμε φÏοντίστε το Ï€Ïόσθετο σας να πληÏεί τα παÏαπάνω κÏιτήÏια για να μποÏέσετε να το ολοκληÏώσετε και να το μεταφέÏετε στο <span class=\"status-1\">Sandbox</span>."
+
+#: views/developers/addon_status.thtml:108
+msgid "devcp_addon_status_completion_enabled"
+msgstr "ΜποÏείτε Ï„ÏŽÏα να ολοκληÏώσετε το Ï€Ïόσθετο σας και να το μετακινήσετε στο <span class=\"status-1\">Sandbox</span> κάνωντας κλικ στο παÏακάτω κουμπί."
+
+#: views/developers/addon_status.thtml:102
+msgid "devcp_addon_status_criteria_category"
+msgstr "Έχει επιλεγεί τουλάχιστον μια κατηγοÏία"
+
+#: views/developers/addon_status.thtml:101
+msgid "devcp_addon_status_criteria_description"
+msgstr "Απαιτείται πεÏιγÏαφή του Ï€Ïόσθετου"
+
+#: views/developers/addon_status.thtml:99
+msgid "devcp_addon_status_criteria_name"
+msgstr "Απαιτείται όνομα για το Ï€Ïόσθετο"
+
+#: views/developers/addon_status.thtml:120
+msgid "devcp_addon_status_criteria_prerelease"
+msgstr "Το Ï€Ïόσθετο δεν έχει οÏιστεί σαν Ï€Ïο-έκδοση."
+
+#: views/developers/addon_status.thtml:119
+msgid "devcp_addon_status_criteria_preview"
+msgstr "Απαιτείται τουλάχιστον μια εικόνα Ï€Ïοεπισκόπησης για επεκτάσεις και θέματα."
+
+#: views/developers/addon_status.thtml:100
+msgid "devcp_addon_status_criteria_summary"
+msgstr "Απαιτείται σÏνοψη για το Ï€Ïόσθετο"
+
+#. %s is the status in a span, e.g. "<span>_('Public')</span>".
+#: views/developers/addon_status.thtml:58
+msgid "devcp_addon_status_header"
+msgstr "Κατάσταση Ï€Ïόσθετου: %s"
+
+#: views/developers/addon_status.thtml:152
+#: views/developers/addon_status.thtml:173
+msgid "devcp_addon_status_header_actions"
+msgstr "Διαθέσιμες ενέÏγειες"
+
+#: views/developers/addon_status.thtml:168
+msgid "devcp_addon_status_header_active"
+msgstr "Κατάσταση ενεÏγοποίησης: <span class=\"inactive-0\">ΕνεÏγό</span>"
+
+#: views/developers/addon_status.thtml:97
+msgid "devcp_addon_status_header_criteria"
+msgstr "ΚÏιτήÏια ολοκλήÏωσης Ï€Ïόσθετου"
+
+#: views/developers/addon_status.thtml:164
+msgid "devcp_addon_status_header_inactive"
+msgstr "Κατάσταση ενεÏγοποίησης: <span class=\"inactive-1\">ΑνενεÏγό</span>"
+
+#: views/developers/addon_status.thtml:117
+msgid "devcp_addon_status_header_nomination"
+msgstr "ΚÏιτήÏια υποψηφιότητας για το δημόσιο χώÏο"
+
+#: views/developers/addon_status.thtml:190
+msgid "devcp_addon_status_header_trusted"
+msgstr "Κατάσταση εμπιστοσÏνης: <span class=\"status-4\">Έμπιστο</span>"
+
+#: views/developers/addon_status.thtml:165
+msgid "devcp_addon_status_inactive"
+msgstr "Το Ï€Ïόσθετο σας είναι <span class=\"inactive-1\">ανενεÏγό</span>. Αυτό σημαίνει ότι το Ï€Ïόσθετο σας δεν θα εμφανίζεται πουθενά, άσχετα με την παÏαπάνω κατάσταση του. <b>Δεν</b> θα παÏέχονται ενημεÏώσεις για το Ï€Ïόσθετο σας από το σÏστημα αυτόματου ελέγχου ενημεÏώσεων."
+
+#: views/developers/addon_status.thtml:128
+msgid "devcp_addon_status_nominate_disabled"
+msgstr "ΠαÏακαλοÏμε φÏοντίστε το Ï€Ïόσθετο σας να πληÏεί τα παÏαπάνω κÏιτήÏια Ï€Ïιν το θέσετε σε υποψηφιότητα για τον <span class=\"status-4\">δημόσιο χώÏο</span>."
+
+#: views/developers/addon_status.thtml:125
+msgid "devcp_addon_status_nominate_enabled"
+msgstr "ΜποÏείτε Ï„ÏŽÏα να θέσετε το Ï€Ïόσθετο σας σε υποψηφιότητα για τον <span class=\"status-4\">δημόσιο χώÏο</span> κάνοντας κλικ στο παÏακάτω κουμπί."
+
+#: views/developers/addon_status.thtml:64
+msgid "devcp_addon_status_public"
+msgstr "Δημόσιος χώÏος"
+
+#: views/developers/addon_status.thtml:63
+msgid "devcp_addon_status_sandbox"
+msgstr "Sandbox"
+
+#. %s is an email address.
+#: views/developers/addon_status.thtml:89
+msgid "devcp_addon_status_switch_disabled"
+msgstr "Το Ï€Ïόσθετο σας <span class=\"status-5\">απενεÏγοποιήθηκε</span> από κάποιον διαχειÏιστή και δεν μποÏεί να χÏησιμοποιηθεί. Αν θέλετε να μαθέτε το λόγο, παÏακαλοÏμε επικοινωνήστε με τη διεÏθυνση %s."
+
+#: views/developers/addon_status.thtml:67
+msgid "devcp_addon_status_switch_incomplete"
+msgstr "Το Ï€Ïόσθετο σας είναι Ï€Ïος το παÏόν <span class=\"status-0\">ημιτελές</span>. Αυτό σημαίνει ότι το Ï€Ïόσθετο σας δεν εμφανίζεται σε κανένα χώÏο του ιστότοπου η στην υπηÏεσία ελέγχου για ενημεÏώσεις. ΜποÏείτε να επιστÏέψετε σ' αυτή τη σελίδα για να ολοκληÏώσετε το Ï€Ïόσθετο σας όταν θα πληÏεί τα παÏακάτω κÏιτήÏια για να θεωÏηθεί ολοκληÏωμένο και να το μεταφέÏετε στο <span class=\"status-1\">Sandbox</span>."
+
+#. %s is a number, perhaps 42.
+#: views/developers/addon_status.thtml:77
+msgid "devcp_addon_status_switch_nominated"
+msgstr "Το Ï€Ïόσθετο σας βÏίσκεται σε κατάσταση υποψηφιότητας για να μεταφεÏθεί στο <span class=\"status-4\">δημόσιο χώÏο</span> και πεÏιμένει την αξιολόγηση του από κάποιον συντάκτη. ΥπάÏχουν Ï€Ïος το παÏόν %s άλλα υποψήφια Ï€Ïόσθετα στην ουÏά αναμονής."
+
+#. %s is an email address.
+#: views/developers/addon_status.thtml:81
+msgid "devcp_addon_status_switch_pending"
+msgstr "Το Ï€Ïόσθετο σας είναι σε αναμονή. Αυτό είναι κάτι που δεν θα έπÏεπε να συμβεί κανονικά. ΠαÏακαλοÏμε επικοινωνήστε με τη διεÏθυνση %s, δώστε το αναγνωÏιστικό (ID) του Ï€Ïόσθετου σας και αναφέÏετε αυτό το σφάλμα."
+
+#: views/developers/addon_status.thtml:85
+msgid "devcp_addon_status_switch_public"
+msgstr "Το Ï€Ïόσθετο σας είναι στο <span class=\"status-4\">δημόσιο χώÏο</span>, που σημαίνει ότι θα εμφανίζεται σε όλες τις λίστες και στα αποτελέσματα αναζήτησης και θα μποÏεί να γίνει λήψη του χωÏίς πεÏιοÏισμοÏÏ‚. Επίσης, θα παÏέχονται ενημεÏώσεις για το Ï€Ïόσθετο σας μέσω της ενσωματωμένης υπηÏεσίας αυτόματου ελέγχου για ενημεÏώσεις."
+
+#: views/developers/addon_status.thtml:71
+#: views/developers/addon_status.thtml:75
+msgid "devcp_addon_status_switch_sandbox"
+msgstr "Το Ï€Ïόσθετο σας βÏίσκεται στο <span class=\"status-1\">Sandbox</span>, Ï€Ïάγμα που σημαίνει ότι θα εμφανίζεται στην πεÏιήγηση και στα αποτελέσματα, αλλά οι χÏήστες θα Ï€Ïέπει να συνδεθοÏν για να το εγκαταστήσουν. <b>Δεν</b> παÏέχονται ενημεÏώσεις στους χÏήστες μέσω του συστήματος αυτόματου ελέγχου ενημεÏώσεων."
+
+#. %s is the add-on name.
+#: views/developers/addon_status_nominate.thtml:43
+#: views/developers/addon_status_confirm.thtml:43
+#: views/developers/addon_status.thtml:43
+msgid "devcp_addon_status_title"
+msgstr "Κατάσταση %s"
+
+#: views/developers/addon_status.thtml:191
+msgid "devcp_addon_status_trusted"
+msgstr "Το Ï€Ïόσθετο σας είναι <span class=\"status-4\">έμπιστο</span>. Αυτό σημαίνει ότι μποÏείτε να υποβάλετε νέες εκδόσεις για το Ï€Ïόσθετο σας χωÏίς να πεÏάσουν από αξιολόγηση συντάκτη."
+
+#: views/developers/dashboard.thtml:68
+msgid "devcp_dashboard_active"
+msgstr "ΕνεÏγό"
+
+#. %1$s is the add-on type string
+#. %2$s is Inactive or Active in a <span>
+#. %3$s is the addon's public status (Public, In Sandbox, ...) in a <span>
+#: views/developers/dashboard.thtml:69
+msgid "devcp_dashboard_addontype_status"
+msgstr "%1$s είναι Ï€Ïος το παÏόν %2$s και βÏίσκεται στο %3$s"
+
+#: views/developers/dashboard.thtml:67
+msgid "devcp_dashboard_change_status"
+msgstr "Αλλαγή κατάστασης"
+
+#. %s is the addons email address.
+#: views/developers/dashboard.thtml:99
+msgid "devcp_dashboard_disabled_questions"
+msgstr "Το Ï€Ïόσθετο σας απενεÏγοποιήθηκε από κάποιον διαχειÏιστή μας και δεν μποÏεί να χÏησιμοποιηθεί. Για οποιαδήποτε αποÏία παÏακαλοÏμε στείλτε ένα μήνυμα στη διεÏθυνση ηλ. ταχυδÏομείου %s."
+
+#. %s is the (localized) add-on status string in a span, e.g. "Disabled"
+#: views/developers/dashboard.thtml:98
+msgid "devcp_dashboard_disabled_status"
+msgstr "Κατάσταση Ï€Ïόσθετου: %s"
+
+#: views/developers/dashboard.thtml:43
+msgid "devcp_dashboard_header_main"
+msgstr "Ταμπλό δημιουÏγοÏ"
+
+#: views/developers/dashboard.thtml:110
+msgid "devcp_dashboard_header_welcome"
+msgstr "Καλώς ήÏθατε στο ταμπλό δημιουÏγών"
+
+#: views/developers/dashboard.thtml:68
+msgid "devcp_dashboard_inactive"
+msgstr "ΑνενεÏγό"
+
+#. %s is a date in the _('date') format
+#: views/developers/dashboard.thtml:65
+msgid "devcp_dashboard_last_edited"
+msgstr "Τελευταία επεξεÏγασία στις %s"
+
+#: views/developers/dashboard.thtml:111
+msgid "devcp_dashboard_learn"
+msgstr "Δεν φιλοξενείται Ï€Ïος το παÏόν κανένα Ï€Ïόσθετο σας στον ιστότοπο Ï€Ïόσθετων του Mozilla. Για να μάθετε τη διαδικασία και να υποβάλετε το Ï€Ïώτο σας Ï€Ïόσθετο, κάντε κλικ στο παÏακάτω κουμπί «Ξεκινήστε»."
+
+#: views/developers/dashboard.thtml:112
+msgid "devcp_dashboard_start"
+msgstr "Ξεκινήστε"
+
+#: views/developers/dashboard.thtml:82
+msgid "devcp_dashboard_versions"
+msgstr "Εκδόσεις και αÏχεία"
+
+#: views/developers/dashboard.thtml:91
+msgid "devcp_dashboard_versions_new"
+msgstr "Αποστολή νέας έκδοσης"
+
+#. %s is the preview ID number.
+#: controllers/developers_controller.php:1415
+msgid "devcp_delete_previews_error"
+msgstr "Η εικόνα Ï€Ïοεπισκόπησης %s δεν ήταν δυνατό να διαγÏαφεί από τη βάση δεδομένων. ΠαÏακαλοÏμε Ï€Ïοσπαθήστε ξανά."
+
+#. %s is the preview ID number.
+#: controllers/developers_controller.php:1413
+msgid "devcp_delete_previews_success"
+msgstr "Η εικόνα Ï€Ïοεπισκόπησης %s διαγÏάφηκε με επιτυχία."
+
+#: controllers/developers_controller.php:1089
+msgid "devcp_delete_version_priv_error"
+msgstr "Δεν έχετε τα δικαιώματα για να διαγÏάψετε εκδόσεις ή αÏχεία."
+
+#. %1$s is the count of files, a number
+#. %2$s is a status string like _('Public') or _('Incomplete')
+#: controllers/components/amo.php:549
+msgid "devcp_describe_version_status"
+msgid_plural "devcp_describe_version_status"
+msgstr[0] "%1$s %2$s αÏχείο"
+msgstr[1] "%1$s %2$s αÏχεία"
+
+#. %s is a version number. Example: 3.0
+#: views/developers/versions.thtml:65
+#, php-format
+msgid "devcp_details_version"
+msgstr "Έκδοση %s"
+
+#: views/developers/discuss.thtml:68
+msgid "devcp_discuss_addreply_header"
+msgstr "ΠÏοσθήκη απάντησης"
+
+#: views/developers/discuss.thtml:57
+msgid "devcp_discuss_allreplies_header"
+msgstr "Απαντήσεις"
+
+#. notice when an error occurs saving a discussion reply
+#. %1 is the email address (linked) for the amo-editors list
+#: views/developers/discuss.thtml:70
+msgid "devcp_discuss_error_notice"
+msgstr "ΠαÏουσιάστηκε σφάλμα κατά την αποθήκευση της απάντησης σας. ΠαÏακαλοÏμε επικοινωνήστε με τη διεÏθυνση ηλεκτÏÎ¿Î½Î¹ÎºÎ¿Ï Ï„Î±Ï‡Ï…Î´Ïομείου %1$s για να επιλυθεί το Ï€Ïόβλημα."
+
+#. %1 is the add-on name, %2 is the add-on's version number currently being reviewed by an editor
+#: views/developers/discuss.thtml:46
+msgid "devcp_discuss_intro"
+msgstr "Ένας από τους συντάκτες αξιολογήσεων του ιστότοπου Ï€Ïόσθετων Mozilla ζήτησε πεÏαιτέÏω πληÏοφοÏίες σχετικά με την έκδοση %2$s του Ï€Ïόσθετου %1$s."
+
+#. %1 is the add-on name
+#: views/developers/discuss.thtml:43
+msgid "devcp_discuss_pagetitle"
+msgstr "ΠαÏαθέστε πεÏισσότεÏες πληÏοφοÏίες για την αξιολόγηση του Ï€Ïόσθετου %1$s"
+
+#. submit button text
+#: views/developers/discuss.thtml:79
+msgid "devcp_discuss_submit_reply"
+msgstr "Υποβολή απάντησης"
+
+#: views/developers/discuss.thtml:72
+msgid "devcp_discuss_success_message"
+msgstr "Η απάντηση σας αποθηκεÏθηκε με επιτυχία. Όσοι συμμετέχουν στη συζήτηση θα ειδοποιηθοÏν με μήνυμα ηλεκτÏÎ¿Î½Î¹ÎºÎ¿Ï Ï„Î±Ï‡Ï…Î´Ïομείου."
+
+#. in an author/editor discussion about an add-on to be reviewed:
+#. %1 is the commenter's user name (linked).
+#. %2 is the full date the comment was made.
+#: views/developers/discuss.thtml:52
+#: views/developers/discuss.thtml:62
+msgid "devcp_discuss_writtenby"
+msgstr "Συντάχθηκε από %1$s στις %2$s"
+
+#: views/developers/addon_edit_authors.thtml:72
+#: views/developers/addon_edit_authors.thtml:81
+msgid "devcp_edit_authors_add_author"
+msgstr "ΠÏοσθήκη νέου δημιουÏγοÏ"
+
+#: views/developers/addon_edit_authors.thtml:96
+msgid "devcp_edit_authors_add_author_button"
+msgstr "ΠÏοσθήκη δημιουÏγοÏ"
+
+#: views/developers/addon_edit_authors.thtml:83
+msgid "devcp_edit_authors_add_email"
+msgstr "ΔιεÏθυνση ηλ. ταχυδÏομείου δημιουÏγοÏ:"
+
+#: views/developers/addon_edit_authors.thtml:98
+msgid "devcp_edit_authors_add_loading"
+msgstr "Γίνεται έλεγχος διεÏθυνσης ηλ. ταχυδÏομείου λογαÏιασμοÏ..."
+
+#: views/developers/addon_edit_authors.thtml:70
+msgid "devcp_edit_authors_click_save"
+msgstr "Κάντε κλικ στο «ΕνημέÏωση δημιουÏγών» παÏακάτω για αποθήκευση."
+
+#: views/developers/addon_edit_authors.thtml:58
+msgid "devcp_edit_authors_header_current"
+msgstr "ΤÏέχοντες δημιουÏγοί"
+
+#: views/developers/addon_edit_authors.thtml:50
+msgid "devcp_edit_authors_header_manage"
+msgstr "ΔιαχείÏιση δημιουÏγών Ï€Ïόσθετου"
+
+#: views/developers/addon_edit_authors.thtml:93
+msgid "devcp_edit_authors_label_add_listed"
+msgstr "Îα εμφανίζεται ως δημιουÏγός στις δημόσιες σελίδες"
+
+#: views/developers/addon_edit_authors.thtml:89
+msgid "devcp_edit_authors_label_developer"
+msgstr "<strong>ΔημιουÏγός</strong> - ΜποÏεί να διαχειÏιστεί όλες τις ιδιότητες του Ï€Ïόσθετου, εκτός από το να Ï€ÏοσθαφαιÏέσει άλλους δημιουÏγοÏÏ‚."
+
+#: views/developers/addon_edit_authors.thtml:88
+msgid "devcp_edit_authors_label_owner"
+msgstr "<strong>Ιδιοκτήτης</strong> - ΜποÏεί να διαχειÏιστεί όλες τις ιδιότητες του Ï€Ïόσθετου, συμπεÏιλαμβανομένης και της Ï€ÏοσθαφαίÏεσης δημιουÏγών."
+
+#: views/developers/addon_edit_authors.thtml:90
+msgid "devcp_edit_authors_label_viewer"
+msgstr "<strong>Θεατής</strong> - ΜποÏεί να δει τις καταχωÏήσεις και τα στατιστικά όπως και οι δημιουÏγοί αλλά δεν μποÏεί να κάνει αλλαγές."
+
+#. Placeholder for the empty option in a <select>.
+#: views/developers/addon_edit_categories.thtml:69
+msgid "devcp_edit_authors_option_empty"
+msgstr "----------------"
+
+#: views/developers/addon_edit_authors.thtml:86
+msgid "devcp_edit_authors_select_role"
+msgstr "Επιλέξτε Ïόλο για τον δημιουÏγό:"
+
+#. Column name in a table.
+#: views/developers/addon_edit_authors.thtml:62
+msgid "devcp_edit_authors_th_author"
+msgstr "ΔημιουÏγός"
+
+#. Column name in a table.
+#: views/developers/addon_edit_authors.thtml:64
+msgid "devcp_edit_authors_th_listed"
+msgstr "Δηλωμένοι"
+
+#. Column name in a table.
+#: views/developers/addon_edit_authors.thtml:63
+msgid "devcp_edit_authors_th_role"
+msgstr "Ρόλος"
+
+#: views/developers/addon_edit_authors.thtml:77
+msgid "devcp_edit_authors_update_author"
+msgstr "ΕνημέÏωση δημιουÏγών"
+
+#: views/developers/addon_edit_categories.thtml:99
+msgid "devcp_edit_categories_button_update"
+msgstr "ΕνημέÏωση κατηγοÏιών"
+
+#: views/developers/addon_edit_categories.thtml:88
+msgid "devcp_edit_categories_does_not_fit"
+msgstr "Το Ï€Ïόσθετο μου δεν ταιÏιάζει με καμία από τις διαθέσιμες κατηγοÏίες."
+
+#. %s is the application name (Firefox, Thunderbird).
+#: views/developers/addon_edit_categories.thtml:61
+msgid "devcp_edit_categories_header_application"
+msgstr "ΚατηγοÏίες %s"
+
+#: views/developers/addon_edit_categories.thtml:49
+msgid "devcp_edit_categories_header_manage"
+msgstr "ΔιαχείÏιση κατηγοÏιών Ï€Ïόσθετου"
+
+#: views/developers/addon_edit_categories.thtml:91
+msgid "devcp_edit_categories_hover"
+msgstr "Μετακινήστε το ποντίκι πάνω από μια κατηγοÏία για να δείτε την πεÏιγÏαφή της."
+
+#. %s is the category number (1, 2, 3).
+#: views/developers/addon_edit_categories.thtml:67
+msgid "devcp_edit_categories_label_category_num"
+msgstr "%s κατηγοÏία"
+
+#: views/developers/addon_edit_categories.thtml:94
+#: views/developers/addon_edit_categories.thtml:103
+msgid "devcp_edit_categories_none_available"
+msgstr "Δεν υπάÏχουν διαθέσιμες κατηγοÏίες γι' αυτό τον Ï„Ïπο Ï€Ïόσθετου και εφαÏμογής."
+
+#: views/developers/addon_edit_categories.thtml:86
+msgid "devcp_edit_categories_other"
+msgstr "Βάλτε το Ï€Ïόσθετο σας σ' αυτή την κατηγοÏία μόνο αν δεν ταιÏιάζει σε καμία από τις διαθέσιμες."
+
+#. %s is the application name (Firefox, Thunderbird).
+#: views/developers/addon_edit_categories.thtml:63
+msgid "devcp_edit_categories_select_application_categories"
+msgstr "Επιλέξτε μέχÏι 3 κατηγοÏίες του %s για το Ï€Ïόσθετο σας"
+
+#: views/developers/addon_edit.thtml:47
+msgid "devcp_edit_dd_manage_authors"
+msgstr "ΠÏοσθέστε ή αφαιÏέστε χÏήστες που θα μποÏοÏν να διαχειÏιστοÏν αυτό το Ï€Ïόσθετο."
+
+#: views/developers/addon_edit.thtml:49
+msgid "devcp_edit_dd_manage_categories"
+msgstr "Επιλέξτε τις σχετικές κατηγοÏίες για κάθε εφαÏμογή που υποστηÏίζεται από το Ï€Ïόσθετο σας."
+
+#: views/developers/addon_edit.thtml:51
+msgid "devcp_edit_dd_manage_description"
+msgstr "ΠÏοσθέστε και επεξεÏγαστείτε μεταφÏάσεις για τη σÏνοψη, την πεÏιγÏαφή, την αδειοδότηση Ï„ÎµÎ»Î¹ÎºÎ¿Ï Ï‡Ïήστη και την πολιτική αποÏÏήτου του Ï€Ïόσθετου σας."
+
+#: views/developers/addon_edit.thtml:53
+msgid "devcp_edit_dd_manage_properties"
+msgstr "Αλλάξτε το όνομα του Ï€Ïόσθετου σας, την αÏχική του σελίδα, το εικονίδιο του και άλλoÏ…Ï‚ διακόπτες."
+
+#: views/developers/addon_edit_descriptions.thtml:116
+msgid "devcp_edit_description_button_update"
+msgstr "ΕνημέÏωση πεÏιγÏαφών"
+
+#: views/developers/addon_edit_descriptions.thtml:115
+msgid "devcp_edit_description_correct_error"
+msgstr "ΠαÏακαλοÏμε διοÏθώστε τα παÏαπάνω σημειωμένα με κόκκινο σφάλματα."
+
+#: views/developers/addon_edit_descriptions.thtml:51
+msgid "devcp_edit_descriptions_header"
+msgstr "ΕπεξεÏγασία πεÏιγÏαφών Ï€Ïόσθετου"
+
+#: views/developers/addon_edit_descriptions.thtml:94
+msgid "devcp_edit_descriptions_transbox_comments_description"
+msgstr "Οποιαδήποτε πληÏοφοÏία μποÏεί να ενδιαφέÏει τους τελικοÏÏ‚ χÏήστες και δεν είναι απαÏαίτητη στη σÏνοψη ή την πεÏιγÏαφή του Ï€Ïόσθετου. ΧÏησιμοποιείται συχνά για την αναφοÏά σημαντικών Ï€Ïοβλημάτων, πληÏοφοÏίες για το πως μποÏεί να γίνει αναφοÏά Ï€Ïοβλημάτων, αναμενόμενες ημεÏομηνίες νέων εκδόσεων κλπ."
+
+#: views/developers/addon_edit_descriptions.thtml:93
+msgid "devcp_edit_descriptions_transbox_comments_name"
+msgstr "Σχόλια δημιουÏγοÏ"
+
+#: views/developers/addon_edit_descriptions.thtml:86
+msgid "devcp_edit_descriptions_transbox_description_description"
+msgstr "Η πεÏιγÏαφή του Ï€Ïόσθετου σας είναι μια εκτενέστεÏη επεξήγηση των χαÏακτηÏιστικών του, της λειτουÏγίας του και άλλων πληÏοφοÏιών. Εμφανίζεται κάτω από τη σÏνοψη στη σελίδα του Ï€Ïόσθετου."
+
+#: views/developers/addon_edit_descriptions.thtml:85
+msgid "devcp_edit_descriptions_transbox_description_name"
+msgstr "ΠεÏιγÏαφή Ï€Ïόσθετου"
+
+#: views/developers/addon_edit_descriptions.thtml:103
+msgid "devcp_edit_descriptions_transbox_eula_description"
+msgstr "Αν το Ï€Ïόσθετο σας συνοδεÏεται από συμφωνητικό αδειοδότησης Ï„ÎµÎ»Î¹ÎºÎ¿Ï Ï‡Ïήστη (EULA), παÏακαλοÏμε εισάγετε το κείμενο του παÏακάτω. Αν οÏιστεί, οι χÏήστες θα Ï€Ïέπει να δώσουν τη συγκατάθεση τους για να εγκαταστήσουν το Ï€Ïόσθετο σας. ΠαÏακαλοÏμε σημειώστε πως ένα EULA iδεν είναι το ίδιο με μια άδεια Î»Î¿Î³Î¹ÏƒÎ¼Î¹ÎºÎ¿Ï ÏŒÏ€Ï‰Ï‚ οι GPL ή MPL."
+
+#: views/developers/addon_edit_descriptions.thtml:102
+msgid "devcp_edit_descriptions_transbox_eula_name"
+msgstr "Αδειοδότηση Ï„ÎµÎ»Î¹ÎºÎ¿Ï Ï‡Ïήστη (EULA)"
+
+#: views/developers/addon_edit_descriptions.thtml:112
+msgid "devcp_edit_descriptions_transbox_privacy_description"
+msgstr "Αν το Ï€Ïόσθετο σας έχει ξεχωÏιστή πολιτική αποÏÏήτου εισάγετε το κείμενο της εδώ. Στη σελίδα του Ï€Ïόσθετου, θα εμφανίζεται δεσμός γι' αυτή την πολιτική αποÏÏήτου."
+
+#: views/developers/addon_edit_descriptions.thtml:111
+msgid "devcp_edit_descriptions_transbox_privacy_name"
+msgstr "Πολιτική αποÏÏήτου"
+
+#: views/developers/addon_edit_descriptions.thtml:78
+msgid "devcp_edit_descriptions_transbox_summary_description"
+msgstr "Η σÏνοψη είναι μια σÏντομη επεξήγηση των βασικών λειτουÏγιών του Ï€Ïόσθετου σας που εμφανίζεται στις λίστες αναζήτησης και πεÏιήγησης, καθώς και στην κοÏυφή της σελίδας του Ï€Ïόσθετου σας. <strong>ΠεÏιοÏίζεται σε 250 χαÏακτήÏες.</strong>"
+
+#: views/developers/addon_edit_descriptions.thtml:77
+msgid "devcp_edit_descriptions_transbox_summary_name"
+msgstr "ΣÏνοψη Ï€Ïόσθετου"
+
+#: views/developers/addon_edit.thtml:46
+msgid "devcp_edit_dt_manage_authors"
+msgstr "ΔιαχείÏιση δημιουÏγών Ï€Ïόσθετου"
+
+#: views/developers/addon_edit.thtml:48
+msgid "devcp_edit_dt_manage_categories"
+msgstr "ΔιαχείÏιση κατηγοÏιών Ï€Ïόσθετου"
+
+#: views/developers/addon_edit.thtml:50
+msgid "devcp_edit_dt_manage_descriptions"
+msgstr "ΔιαχείÏιση πεÏιγÏαφών Ï€Ïόσθετου"
+
+#: views/developers/addon_edit.thtml:52
+msgid "devcp_edit_dt_manage_properties"
+msgstr "ΔιαχείÏιση ιδιοτήτων Ï€Ïόσθετου"
+
+#: views/developers/addon_edit_properties.thtml:170
+msgid "devcp_edit_label_externalsoftware"
+msgstr "Αυτό το Ï€Ïόσθετο απαιτεί επιπÏόσθετο λογισμικό "
+
+#: views/developers/addon_edit_properties.thtml:205
+msgid "devcp_edit_label_locale_disambiguation"
+msgstr "ΣυμπληÏωματικές πληÏοφοÏίες Ï€Ïόσθετου"
+
+#: views/developers/addon_edit_properties.thtml:168
+msgid "devcp_edit_label_prerelease"
+msgstr "ΠÏόκειται για Ï€Ïοέκδοση"
+
+#: views/developers/addon_edit_properties.thtml:169
+msgid "devcp_edit_label_sitespecific"
+msgstr "Αυτό το Ï€Ïόσθετο δουλεÏει με συγκεκÏιμένους ιστότοπους"
+
+#: views/developers/addon_edit_properties.thtml:202
+msgid "devcp_edit_label_target_locale"
+msgstr "Επιθυμητή τοπική ÏÏθμιση γλώσσας"
+
+#: views/developers/addon_edit_properties.thtml:212
+msgid "devcp_edit_properties_button_update"
+msgstr "ΕνημέÏωση ιδιοτήτων"
+
+#: views/developers/addon_edit_properties.thtml:198
+msgid "devcp_edit_properties_change_guid"
+msgstr "Κάντε αλλαγές μόνο αν καταλαβαίνετε όλες τις συνέπειες των αλλαγών σας."
+
+#: views/developers/addon_edit_properties.thtml:109
+msgid "devcp_edit_properties_current_icon"
+msgstr "ΤÏέχον εικονίδιο"
+
+#: views/developers/addon_edit_properties.thtml:85
+msgid "devcp_edit_properties_default_locale"
+msgstr "Η αÏχική γλώσσα ενός Ï€Ïόσθετου είναι η βασική γλώσσα στην οποία θα Ï€Ïέπει να έχει μεταφÏαστεί. Αν δεν υπάÏχει διαθέσιμη μετάφÏαση για τις πεÏιγÏαφές του Ï€Ïόσθετου στη γλώσσα κάποιου χÏήστη, θα χÏησιμοποιηθεί αυτή."
+
+#: views/developers/addon_edit_properties.thtml:167
+msgid "devcp_edit_properties_flags"
+msgstr "Αυτοί οι διακόπτες χÏησιμοποιοÏνται για το φιλτÏάÏισμα και την κατηγοÏιοποίηση των Ï€Ïόσθετων."
+
+#: views/developers/addon_edit_properties.thtml:174
+msgid "devcp_edit_properties_guid"
+msgstr "Το GUID του Ï€Ïόσθετου σας έχει οÏιστεί στο install.rdf του και αποτελεί μοναδιαίο αναγνωÏιστικό του. Δεν μποÏείτε να αλλάξετε το GUID μετά που αυτό θα συμπεÏιληφθεί στον ιστότοπο Ï€Ïόσθετων του Mozilla."
+
+#: views/developers/addon_edit_properties.thtml:53
+msgid "devcp_edit_properties_header"
+msgstr "ΕπεξεÏγασία ιδιοτήτων Ï€Ïόσθετου"
+
+#: views/developers/addon_edit_properties.thtml:186
+msgid "devcp_edit_properties_header_addon_type"
+msgstr "ΤÏπος Ï€Ïόσθετου"
+
+#: views/developers/addon_edit_properties.thtml:181
+msgid "devcp_edit_properties_header_admin_settings"
+msgstr "Ρυθμίσεις διαχειÏιστή"
+
+#: views/developers/addon_edit_properties.thtml:84
+msgid "devcp_edit_properties_header_default_locale"
+msgstr "ΑÏχικές Ïυθμίσεις γλώσσας"
+
+#: views/developers/addon_edit_properties.thtml:166
+msgid "devcp_edit_properties_header_flags"
+msgstr "Σημαίες Ï€Ïόσθετου"
+
+#: views/developers/addon_edit_properties.thtml:173
+#: views/developers/addon_edit_properties.thtml:197
+msgid "devcp_edit_properties_header_guid"
+msgstr "GUID Ï€Ïόσθετου"
+
+#: views/developers/addon_edit_properties.thtml:104
+msgid "devcp_edit_properties_header_icon"
+msgstr "Εικονίδιο Ï€Ïόσθετου"
+
+#: views/developers/addon_edit_properties.thtml:159
+msgid "devcp_edit_properties_header_other_settings"
+msgstr "Άλλες Ïυθμίσεις"
+
+#. A header on the admin page to toggle trusted status.
+#: views/developers/addon_edit_properties.thtml:182
+msgid "devcp_edit_properties_header_trusted"
+msgstr "Έμπιστο Ï€Ïόσθετο;"
+
+#: views/developers/addon_edit_properties.thtml:160
+msgid "devcp_edit_properties_header_view_source"
+msgstr "Εμφάνιση πηγαίου κώδικα στο δίκτυο"
+
+#. %s is a comma-separated list of image extensions ".png, .jpg"
+#: views/developers/addon_edit_properties.thtml:106
+msgid "devcp_edit_properties_icon"
+msgstr "Το εικονίδιο του Ï€Ïόσθετου είναι μια μικÏή εικόνα που εμφανίζεται δίπλα στο όνομα του Ï€Ïόσθετου σας στην πεÏιήγηση και στα αποτελέσματα αναζήτησης, στη σελίδα του και στο διάλογο εγκατάστασης. Η εικόνα θα σμικÏυνθεί αυτόματα σε μέγεθος 32 x 32 πίξελ. ΠαÏακαλοÏμε χÏησιμοποιείστε μια από τις ακόλουθες μοÏφές αÏχείου: %s"
+
+#: views/developers/addon_edit_properties.thtml:171
+msgid "devcp_edit_properties_label_binary"
+msgstr "Αυτό το Ï€Ïόσθετο πεÏιέχει δυαδικά εκτελέσιμα στοιχεία"
+
+#: views/developers/addon_edit_properties.thtml:185
+msgid "devcp_edit_properties_label_not_trusted"
+msgstr "Μη έμπιστο"
+
+#: views/developers/addon_edit_properties.thtml:184
+msgid "devcp_edit_properties_label_trusted"
+msgstr "Έμπιστο"
+
+#: views/developers/addon_edit_properties.thtml:110
+msgid "devcp_edit_properties_new_icon"
+msgstr "Îέο εικονίδιο"
+
+#: views/developers/addon_edit_properties.thtml:118
+msgid "devcp_edit_properties_remove_icon"
+msgstr "ΑφαίÏεση εικονιδίου"
+
+#: views/developers/addon_edit_properties.thtml:136
+msgid "devcp_edit_properties_transbox_homepage_description"
+msgstr "Αν έχετε κι άλλο ιστότοπο για το Ï€Ïόσθετο σας, εισάγετε τη διεÏθυνση του εδώ. Δεν χÏειάζεται να Ï€Ïοσθέσετε μεταφÏάσεις, εκτός κι αν ο ιστότοπος σας είναι μεταφÏασμένος και σε άλλες γλώσσες."
+
+#: views/developers/addon_edit_properties.thtml:135
+msgid "devcp_edit_properties_transbox_homepage_name"
+msgstr "Ιστότοπος Ï€Ïόσθετου"
+
+#: views/developers/addon_edit_properties.thtml:79
+msgid "devcp_edit_properties_transbox_name_description"
+msgstr "Το όνομα του Ï€Ïόσθετου σας θα εμφανίζεται Ï€Î±Î½Ï„Î¿Ï ÏŒÏ€Î¿Ï… θα εμφανίζεται και το Ï€Ïόσθετο σας."
+
+#: views/developers/addon_edit_properties.thtml:78
+msgid "devcp_edit_properties_transbox_name_name"
+msgstr "Όνομα Ï€Ïόσθετου"
+
+#: views/developers/addon_edit_properties.thtml:145
+msgid "devcp_edit_properties_transbox_supportemail_description"
+msgstr "Αν έχετε μια διεÏθυνση ηλεκτÏÎ¿Î½Î¹ÎºÎ¿Ï Ï„Î±Ï‡Ï…Î´Ïομείου για θέματα, εισάγετε την έδω. Δεν χÏειάζεται να Ï€Ïοσθέσετε μεταφÏάσεις, εκτός κι αν χÏησιμοποιείτε διάφοÏες διευθÏνσεις για διάφοÏες γλώσσες."
+
+#: views/developers/addon_edit_properties.thtml:144
+msgid "devcp_edit_properties_transbox_supportemail_name"
+msgstr "ΔιεÏθυνση ηλεκτÏÎ¿Î½Î¹ÎºÎ¿Ï Ï„Î±Ï‡Ï…Î´Ïομείου για υποστήÏιξη"
+
+#: views/developers/addon_edit_properties.thtml:154
+msgid "devcp_edit_properties_transbox_supporturl_description"
+msgstr "Αν έχετε ιστότοπο ή φόÏουμ υποστήÏιξης για το Ï€Ïόσθετο σας, εισάγετε εδώ τη διεÏθυνση του. Δεν χÏειάζεται να Ï€Ïοσθέσετε μεταφÏάσεις, εκτός κι αν ο ιστότοπος σας έχει μεταφÏαστεί σε άλλες γλώσσες."
+
+#: views/developers/addon_edit_properties.thtml:153
+msgid "devcp_edit_properties_transbox_supporturl_name"
+msgstr "Ιστότοπος υποστήÏιξης"
+
+#: views/developers/addon_edit_properties.thtml:183
+msgid "devcp_edit_properties_trusted"
+msgstr "Τα έμπιστα Ï€Ïόσθετα μποÏοÏν να μεταφεÏθοÏν στο δημόσιο χώÏο χωÏίς να αξιολογηθοÏν από συντάκτες."
+
+#. %s is href="..." and should stay in the <a> tag.
+#: views/developers/addon_edit_properties.thtml:119
+msgid "devcp_edit_properties_undelete"
+msgstr "Το εικονίδιο θα διαγÏαφεί κατά την αποθήκευση. <a %s>ΑκÏÏωση;</a>"
+
+#: views/developers/addon_edit_properties.thtml:161
+msgid "devcp_edit_properties_view_source"
+msgstr "Οποιοσδήποτε συνδεδεμένος χÏήστης θα μποÏεί να δει τον πηγαίο κώδικα των αÏχείων του Ï€Ïόσθετου σας αν το θέλετε."
+
+#: views/developers/addon_edit_properties.thtml:162
+msgid "devcp_edit_properties_view_source_allow"
+msgstr "Îα επιτÏέπεται η εμφάνιση του πηγαίου κώδικα στο δίκτυο"
+
+#: views/developers/addon_edit_properties.thtml:163
+msgid "devcp_edit_properties_view_source_do_not_allow"
+msgstr "Îα μην επιτÏέπεται η εμφάνιση του πηγαίου κώδικα στο δίκτυο"
+
+#: views/elements/developers/editbox.thtml:46
+msgid "devcp_editbox_authors"
+msgstr "ΔημιουÏγοί"
+
+#: views/elements/developers/editbox.thtml:47
+msgid "devcp_editbox_categories"
+msgstr "ΚατηγοÏίες"
+
+#: views/elements/developers/editbox.thtml:52
+msgid "devcp_editbox_change_status"
+msgstr "Αλλαγή κατάστασης"
+
+#: views/elements/developers/editbox.thtml:48
+msgid "devcp_editbox_descriptions"
+msgstr "ΠεÏιγÏαφές"
+
+#: views/elements/developers/editbox.thtml:43
+msgid "devcp_editbox_edit_addon"
+msgstr "ΕπεξεÏγασία Ï€Ïόσθετου"
+
+#: views/elements/developers/editbox.thtml:57
+msgid "devcp_editbox_new_version"
+msgstr "Îέα έκδοση"
+
+#: views/elements/developers/editbox.thtml:49
+msgid "devcp_editbox_properties"
+msgstr "Ιδιότητες"
+
+#: views/elements/developers/editbox.thtml:60
+msgid "devcp_editbox_screenshots"
+msgstr "Εικόνες Ï€Ïοεπισκόπησης"
+
+#: views/elements/developers/editbox.thtml:53
+msgid "devcp_editbox_statistics_dashboard"
+msgstr "Ταμπλό στατιστικώνStatistics Dashboard"
+
+#: views/elements/developers/editbox.thtml:54
+msgid "devcp_editbox_versions"
+msgstr "Εκδόσεις και αÏχεία"
+
+#: views/elements/developers/editbox.thtml:42
+msgid "devcp_editbox_view_listing"
+msgstr "Σελίδα Ï€Ïόσθετου"
+
+#: views/elements/developers/editorsmenu.thtml:59
+msgid "devcp_editorsqueue_featured"
+msgstr "Συνιστώμενα Ï€Ïόσθετα"
+
+# %1 is the review count
+#. %1 is the review count
+#: views/elements/developers/editorsqueue.thtml:42
+#: views/elements/developers/editorsmenu.thtml:56
+#, php-format
+msgid "devcp_editorsqueue_moderatedreviews"
+msgid_plural "devcp_editorsqueue_moderatedreviews"
+msgstr[0] "%s επιμελημένη αξιολόγηση"
+msgstr[1] "%s επιμελημένες αξιολογήσεις"
+
+# %1 is the nominated addons count
+#. %1 is the nominated addons count
+#: views/elements/developers/editorsqueue.thtml:44
+#: views/elements/developers/editorsmenu.thtml:58
+#, php-format
+msgid "devcp_editorsqueue_nominated"
+msgid_plural "devcp_editorsqueue_nominated"
+msgstr[0] "%s υποψήφιο Ï€Ïόσθετο"
+msgstr[1] "%s υποψήφια Ï€Ïόσθετα"
+
+# %1 is the update count
+#. %1 is the update count
+#: views/elements/developers/editorsqueue.thtml:43
+#: views/elements/developers/editorsmenu.thtml:57
+#, php-format
+msgid "devcp_editorsqueue_pendingupdates"
+msgid_plural "devcp_editorsqueue_pendingupdates"
+msgstr[0] "ΕκκÏεμεί %s ενημέÏωση"
+msgstr[1] "ΕκκÏεμοÏν %s ενημεÏώσεις"
+
+#: controllers/statistics_controller.php:147
+#: controllers/statistics_controller.php:361
+#: controllers/previews_controller.php:108
+#: controllers/previews_controller.php:211
+#: controllers/previews_controller.php:312
+msgid "devcp_error_addon_access_denied"
+msgstr "Δεν έχετε Ï€Ïόσβαση σε αυτό το Ï€Ïόσθετο."
+
+#. %s is a complete URL with the text from devcp_error_appversion_reference_link_text
+#. in the <a> tag. This should be fixed.
+#: controllers/components/developers.php:591
+#, php-format
+msgid "devcp_error_appversion_reference_link"
+msgstr "ΠαÏακαλοÏμε δείτε για αναφοÏά %s."
+
+#. This is the link text in the <a> for devcp_error_appversion_reference_link. This
+#. should be fixed.
+#: controllers/components/developers.php:591
+msgid "devcp_error_appversion_reference_link_text"
+msgstr "αυτή τη σελίδα"
+
+#: views/developers/addon_edit_authors.thtml:76
+msgid "devcp_error_empty_authors"
+msgstr "Το Ï€Ïόσθετο σας θα Ï€Ïέπει να έχει τουλάχιστον ένα ιδιοκτήτη."
+
+#. %1$s is the name of the file
+#: controllers/components/developers.php:658
+msgid "devcp_error_file_exists"
+msgstr "ΥπάÏχει ήδη μια έκδοση Î±Ï…Ï„Î¿Ï Ï„Î¿Ï… Ï€Ïόσθετου. Για να το αντικαταστήσετε, θα Ï€Ïέπει Ï€Ïώτα να διαγÏάψετε το αÏχείο %1$s."
+
+#. %1$s is a file extension. Example: .exe
+#. %2$s is a comma separated list of extensions. Example: .xpi, .jar
+#: controllers/components/developers.php:355
+#, php-format
+msgid "devcp_error_file_extension"
+msgstr "Η Ï€Ïοέκταση αÏχείου (%s) δεν επιτÏέπεται για αυτό τον Ï„Ïπο Ï€Ïόσθετου. ΠαÏακαλοÏμε επιλέξτε μια από τις ακόλουθες: %s"
+
+#: controllers/components/developers.php:64
+msgid "devcp_error_five_categories"
+msgstr "ΠαÏακαλοÏμε επιλέξτε το Ï€Î¿Î»Ï Ï€Î­Î½Ï„Îµ κατηγοÏίες."
+
+#: controllers/components/developers.php:526
+msgid "devcp_error_guid_application"
+msgstr "Το αναγνωÏιστικό (ID) του Ï€Ïόσθετου χÏησιμοποιείται ήδη από εφαÏμογή."
+
+#: controllers/components/developers.php:337
+#: controllers/components/developers.php:389
+msgid "devcp_error_http_incomplete"
+msgstr "Μη ολοκληÏωμένη μεταφοÏά"
+
+#: controllers/components/developers.php:335
+#: controllers/components/developers.php:336
+#: controllers/components/developers.php:387
+#: controllers/components/developers.php:388
+msgid "devcp_error_http_maxupload"
+msgstr "ΥπεÏβαίνει το μέγιστο μέγεθος αποστολής"
+
+#: controllers/components/developers.php:338
+#: controllers/components/developers.php:390
+msgid "devcp_error_http_nofile"
+msgstr "Δεν έγινε αποστολή αÏχείου"
+
+#. %1$s is a file extension. Example: .exe
+#. %2$s is a comma separated list of extensions. Example: .xpi, .jar
+#: controllers/components/developers.php:401
+#, php-format
+msgid "devcp_error_icon_extension"
+msgstr "Η Ï€Ïοέκταση αÏχείου (%s) δεν επιτÏέπεται για αÏχείο εικονιδίου. ΠαÏακαλοÏμε επιλέξτε μία από τις ακόλουθες: %s"
+
+#: controllers/developers_controller.php:504
+msgid "devcp_error_index_rdf_notfound"
+msgstr "Δεν υπάÏχει αÏχείο install.rdf."
+
+#: controllers/components/developers.php:601
+msgid "devcp_error_install_manifest"
+msgstr "Τα ακόλουθα σφάλματα εντοπίστηκαν στο αÏχείο install.rdf:"
+
+#: controllers/developers_controller.php:1463
+msgid "devcp_error_invalid_addontype"
+msgstr "Δεν είναι έγκυÏο το αναγνωÏιστικό (ID) του Ï€Ïόσθετου: %s"
+
+#. %$1s is a version. Example: 3.1.1
+#. %$2s is an add-on name.
+#: controllers/components/developers.php:569
+#: controllers/components/developers.php:581
+#, php-format
+msgid "devcp_error_invalid_appversion"
+msgstr "Δεν είναι έγκυÏος αÏιθμός έκδοσης το %s για τον %s"
+
+#. %s is a string
+#: controllers/components/developers.php:521
+#, php-format
+msgid "devcp_error_invalid_guid"
+msgstr "Δεν είναι έγκυÏο το ανανγωÏιστικό (ID) του Ï€Ïόσθετου: %s"
+
+#. %$1s is a version. Example: 3.1.1
+#. %$2s is an add-on name.
+#: controllers/components/developers.php:572
+#, php-format
+msgid "devcp_error_invalid_minversion"
+msgstr "Δεν είναι έγκυÏο το %s s σαν αÏιθμός έκδοσης για το %s: η ελάχιστη απαιτοÏμενη έκδοση δεν επιτÏέπεται να πεÏιέχει *"
+
+#: controllers/components/developers.php:536
+msgid "devcp_error_invalid_version"
+msgstr "Δεν είναι έγκυÏος ο αÏιθμός έκδοσης του Ï€Ïόσθετου: παÏακαλοÏμε δείτε τις <a href=\"http://developer.mozilla.org/en/docs/Toolkit_version_format\">Ï€ÏοδιαγÏαφές</a>"
+
+#: controllers/components/developers.php:531
+msgid "devcp_error_invalid_version_spaces"
+msgstr "Δεν είναι έγκυÏος ο αÏιθμός έκδοσης του Ï€Ïόσθετου: οι αÏιθμοί εκδόσεων δεν επιτÏέπεται να πεÏιέχουν κενά διαστήματα."
+
+#. %s is an error message from the parser.
+#: controllers/components/developers.php:501
+#, php-format
+msgid "devcp_error_manifest_parse"
+msgstr "Συνέβει το ακόλουθο σφάλμα κατά την ανάλυση του αÏχείου install.rdf: %s"
+
+#: controllers/components/developers.php:373
+msgid "devcp_error_move_file"
+msgstr "Δεν ήταν δυνατή η μετακκίνηση του αÏχείου"
+
+#. %s is the name of a file
+#: controllers/components/developers.php:650
+#: controllers/components/developers.php:662
+#: controllers/components/developers.php:667
+#: controllers/components/developers.php:727
+#: controllers/components/developers.php:738
+#: controllers/components/developers.php:743
+#, php-format
+msgid "devcp_error_moving_file"
+msgstr "Συνέβη σφάλμα κατά τη μεταφοÏά του %s."
+
+#: controllers/components/developers.php:595
+msgid "devcp_error_mozilla_application"
+msgstr "ΠÏέπει να υπάÏχει τουλάχιστον μια έγκυÏη δήλωση εφαÏμογής Ï€ÏοοÏÎ¹ÏƒÎ¼Î¿Ï Ï„Î·Ï‚ οικογένειας Mozilla."
+
+#: controllers/components/developers.php:516
+msgid "devcp_error_no_guid"
+msgstr "Δε βÏέθηκε αναγνωÏιστικό (ID) για το Ï€Ïόσθετο στο αÏχείο install.rdf."
+
+#: controllers/components/developers.php:287
+msgid "devcp_error_no_platform"
+msgstr "Δεν έχει επιλεγεί πλατφόÏμα"
+
+#: controllers/components/developers.php:59
+msgid "devcp_error_one_category"
+msgstr "ΠαÏακαλοÏμε επιλέξτε τουλάχιστον μια κατηγοÏία."
+
+#: controllers/components/developers.php:92
+msgid "devcp_error_one_user"
+msgstr "Θα Ï€Ïέπει να δηλωθεί τουλάχιστον ένας δημιουÏγός για το Ï€Ïόσθετο."
+
+#. %1$s is a file extension. Example: .exe
+#. %2$s is a comma separated list of extensions. Example: .xpi, .jar
+#: controllers/components/developers.php:1081
+#, php-format
+msgid "devcp_error_preview_extension"
+msgstr "Δεν επιτÏέπεται αυτή η Ï€Ïοέκταση αÏχείου (%s) για εικόνα Ï€Ïοεπισκόπησης. ΠαÏακαλοÏμε επιλέξτε μία από τις ακόλουθες: %s"
+
+#: controllers/components/developers.php:511
+msgid "devcp_error_updatekey"
+msgstr "Το updateKey δεν μποÏεί να χÏησιμοποιηθεί στον ιστότοπο Add-ons. ΑφαιÏέστε το από το αÏχείο install.rdf και Ï€Ïοσπαθήστε ξανά."
+
+#: controllers/components/developers.php:506
+msgid "devcp_error_updateurl"
+msgstr "Τα Ï€Ïόσθετα δεν επιτÏέπεται να χÏησιμοποιοÏν εξωτεÏικά updateURL. ΠαÏακαλοÏμε αφαιÏέστε την οδηγία από το αÏχείο install.rdf και Ï€Ïοσπαθήστε ξανά."
+
+#: controllers/developers_controller.php:465
+#: controllers/components/developers.php:271
+msgid "devcp_error_upload_file"
+msgstr "ΠαÏακαλοÏμε αποστείλατε αÏχείο."
+
+#: views/developers/uploader.thtml:135
+msgid "devcp_input_upload_file"
+msgstr "Αποστολή αÏχείου"
+
+#: views/pages/js_constants.js.thtml:89
+msgid "devcp_js_a_cancel"
+msgstr "ΑκÏÏωση"
+
+#: views/pages/js_constants.js.thtml:90
+msgid "devcp_js_add_email"
+msgstr "ΠαÏακαλοÏμε εισάγετε το email του λογαÏÎ¹Î±ÏƒÎ¼Î¿Ï Ï„Î¿Ï… δημιουÏÎ³Î¿Ï Ï€Î¿Ï… θέλετε να Ï€Ïοσθέσετε."
+
+#. alt text for a down-arrow image.
+#: views/pages/js_constants.js.thtml:81
+msgid "devcp_js_img_move_down"
+msgstr "Μετακίνηση κάτω"
+
+#. alt text for an up-arrow image.
+#: views/pages/js_constants.js.thtml:82
+msgid "devcp_js_img_move_up"
+msgstr "Μετακίνηση πάνω"
+
+#: views/pages/js_constants.js.thtml:91
+msgid "devcp_js_img_remove_compat"
+msgstr "ΑφαίÏεση συμβατότητας με εφαÏμογή"
+
+#: views/pages/js_constants.js.thtml:86
+msgid "devcp_js_input_list_author"
+msgstr "Εμφάνιση ως δημιουÏÎ³Î¿Ï ÏƒÏ„Î¹Ï‚ δημόσιες σελίδες"
+
+#: views/pages/js_constants.js.thtml:92
+msgid "devcp_js_license_select"
+msgstr "ΠαÏακαλοÏμε επιλέξτε μια άδεια."
+
+#: views/pages/js_constants.js.thtml:93
+msgid "devcp_js_license_text"
+msgstr "ΠαÏακαλοÏμε εισάγετε κείμενο για την άδεια σας."
+
+#. <option> text in a <select> for Author role in an add-on.
+#: views/pages/js_constants.js.thtml:84
+msgid "devcp_js_option_developer"
+msgstr "ΔημιουÏγός"
+
+#. <option> text in a <select> for Author role in an add-on.
+#: views/pages/js_constants.js.thtml:83
+msgid "devcp_js_option_owner"
+msgstr "Ιδιοκτήτης"
+
+#. <option> text in a <select> for Author role in an add-on.
+#: views/pages/js_constants.js.thtml:85
+msgid "devcp_js_option_viewer"
+msgstr "Θεατής"
+
+#: views/pages/js_constants.js.thtml:88
+msgid "devcp_js_remove_author"
+msgstr "ΑφαίÏεση συντάκτη"
+
+#: views/pages/js_constants.js.thtml:87
+msgid "devcp_js_sure_remove"
+msgstr "Θέλετε <strong>σίγουÏα</strong> να αφαιÏέσετε αυτόν τον συντάκτη;"
+
+#: views/pages/js_constants.js.thtml:77
+msgid "devcp_js_upload_alert"
+msgstr "ΠÏέπει να επιλέξετε αÏχείο για αποστολή."
+
+#. %1$s is an addon id, like 32.
+#. %2$s is a version number, like 3.5.
+#: controllers/components/developers.php:1212
+msgid "devcp_license_existing"
+msgstr "ΠÏοσαÏμοσμένη άδεια για το Ï€Ïόσθετο %1$s εκδ. %2$s"
+
+#: views/elements/developers/localebox.thtml:44
+msgid "devcp_localebox_header_localizedfields"
+msgstr "Τοπικοποιημένα πεδία"
+
+# %1 is the default locale
+#. %1 is the default locale
+#: views/elements/developers/localebox.thtml:48
+#, php-format
+msgid "devcp_localebox_intro"
+msgstr "ΜεÏικά από τα πεδία της σελίδας έχουν τοπικοποιηθεί και εμφανίζονται στη μητÏική γλώσσα του Ï„ÎµÎ»Î¹ÎºÎ¿Ï Ï‡Ïήστη. Επιλέξτε μια από τις παÏακάτω τοπικές Ïυθμίσεις για να επεξεÏγαστείτε τις λεπτομέÏειες του Ï€Ïοσθέτου σας σ' αυτή τη γλώσσα. Αν δεν υπάÏχει διαθέσιμη μετάφÏαση για κάποια από τις τοπικές Ïυθμίσεις, θα χÏησιμοποιηθεί η αÏχική ÏÏθμιση γλώσσας (%s)."
+
+#: views/elements/developers/sidebar.thtml:68
+#: views/elements/developers/myaddons.thtml:75
+msgid "devcp_myaddons_admincp_link"
+msgstr "ΕÏγαλεία διαχειÏιστή"
+
+#: views/elements/developers/sidebar.thtml:65
+#: views/elements/developers/myaddons.thtml:72
+msgid "devcp_myaddons_editorcp_link"
+msgstr "ΕÏγαλεία συντακτών"
+
+#: views/elements/developers/myaddons.thtml:52
+msgid "devcp_myaddons_link"
+msgstr "Τα Ï€Ïόσθετά μου"
+
+#: views/elements/developers/sidebar.thtml:70
+#: views/elements/developers/myaddons.thtml:77
+msgid "devcp_myaddons_mainpage_link"
+msgstr "Πίσω στο κεντÏικό"
+
+#: views/elements/developers/sidebar.thtml:63
+#: views/elements/developers/myaddons.thtml:70
+msgid "devcp_myaddons_statistics_link"
+msgstr "Ταμπλό στατιστικών"
+
+#: views/elements/developers/sidebar.thtml:62
+#: views/elements/developers/myaddons.thtml:69
+msgid "devcp_myaddons_submitaddon_link"
+msgstr "Υποβολή Ï€Ïόσθετου"
+
+#: views/elements/developers/sidebar.thtml:48
+#: views/elements/developers/myaddons.thtml:67
+msgid "devcp_myaddons_title"
+msgstr "ΕÏγαλεία δημιουÏγών"
+
+#. %1$s is an add-on ID, perhaps 167.
+#. %2$s is a URL.
+#: controllers/developers_controller.php:256
+msgid "devcp_new_addon_error"
+msgstr "Το ID του Ï€Ïόσθετου (%1$s) υπάÏχει ήδη στη βάση δεδομένων. Αν το Ï€Ïόσθετο αυτό είναι δικό σας, μποÏείτε να <a href=\"%2$s\">αποστείλετε νέα έκδοση</a>."
+
+#: views/developers/addon_status_nominate.thtml:62
+msgid "devcp_nominate_cancel"
+msgstr "ΑκÏÏωση και επιστÏοφή"
+
+# %1 is the addon name
+#. %1 is the add-on name
+#: views/developers/addon_status_nominate.thtml:61
+#, php-format
+msgid "devcp_nominate_submit_nominate"
+msgstr "Υποψηφιότητα του %s"
+
+#: views/developers/addon_edit_properties.thtml:50
+#: views/developers/addon_status.thtml:49
+#: views/developers/versions_edit.thtml:50
+msgid "devcp_notice_changes_error"
+msgstr "<span>Μια ή πεÏισσότεÏες από τις αλλαγές σας δεν ήταν δυνατό να αποθηκευτεί.</span><br />ΠαÏακαλοÏμε δείτε τις αναφοÏές σφαλμάτων παÏακάτω. Οι υπόλοιπες αλλαγές σας αποθηκεÏτηκαν με επιτυχία."
+
+#: views/developers/addon_edit_authors.thtml:47
+#: views/developers/addon_edit_properties.thtml:47
+#: views/developers/addon_status.thtml:46
+#: views/developers/addon_edit_descriptions.thtml:47
+#: views/developers/versions_edit.thtml:47
+#: views/developers/addon_edit_categories.thtml:46
+msgid "devcp_notice_changes_saved"
+msgstr "<span>Οι αλλαγές σας αποθηκεÏτηκαν .</span><br />ΠαÏακαλοÏμε σημειώστε ότι μεÏικές αλλαγές ίσως χÏειαστοÏν αÏκετές ÏŽÏες για να παÏουσιαστοÏν σε όλους τους χώÏους του ιστότοπου."
+
+#: controllers/previews_controller.php:252
+msgid "devcp_notice_cleardefault"
+msgstr "Ο αποχαÏακτηÏισμός αυτής της εικόνας ως αÏχικής εικόνας Ï€Ïοεπισκόπησης θα έχει ως αποτέλεσμα τον αυτόματο οÏισμό μιας άλλης ως αÏχικής."
+
+#: controllers/previews_controller.php:184
+#: controllers/previews_controller.php:251
+msgid "devcp_notice_makedefault"
+msgstr "Ο οÏισμός αυτής της εικόνας Ï€Ïοεπισκόπησης ως αÏχικής θα αφαιÏέσει αυτή την ιδιότητα από την Ï„Ïέχουσα οÏισμένη ως αÏχική."
+
+#: views/developers/addon_edit_authors.thtml:70
+msgid "devcp_notice_unsaved_changes"
+msgstr "ΥπάÏχουν μη αποθηκευμένες αλλαγές."
+
+#: controllers/developers_controller.php:87
+#: controllers/developers_controller.php:97
+#: controllers/developers_controller.php:100
+#: controllers/previews_controller.php:67
+#: controllers/previews_controller.php:79
+#: controllers/previews_controller.php:82
+msgid "devcp_pagetitle"
+msgstr "Πίνακας ελέγχου δημιουÏγοÏ"
+
+#: controllers/previews_controller.php:103
+#: controllers/previews_controller.php:104
+msgid "devcp_preview_add_pagetitle"
+msgstr "ΠÏοσθήκη εικόνας Ï€Ïοεπισκόπησης"
+
+#: controllers/previews_controller.php:135
+msgid "devcp_preview_added_successfully"
+msgstr "Η εικόνα Ï€Ïοεπισκόπησης Ï€Ïοστέθηκε με επιτυχία."
+
+#: controllers/previews_controller.php:323
+msgid "devcp_preview_deleted_successfully"
+msgstr "Η εικόνα Ï€Ïοεπισκόπησης διαγÏάφηκε με επιτυχία."
+
+#: controllers/previews_controller.php:194
+#: controllers/previews_controller.php:195
+msgid "devcp_preview_edit_pagetitle"
+msgstr "ΕπεξεÏγασία εικόνας Ï€Ïοεπισκόπησης"
+
+#: controllers/previews_controller.php:237
+msgid "devcp_preview_updated_successfully"
+msgstr "Η εικόνα Ï€Ïοεπισκόπησης ενημεÏώθηκε με επιτυχία."
+
+#: views/developers/previews.thtml:120
+msgid "devcp_previews_a_another"
+msgstr "ΠÏοσθήκη κι άλλης εικόνας Ï€Ïοεπισκόπησης"
+
+#: views/developers/previews.thtml:96
+msgid "devcp_previews_a_delete"
+msgstr "ΔιαγÏαφή εικόνας Ï€Ïοεπισκόπησης"
+
+#: views/developers/previews.thtml:95
+msgid "devcp_previews_a_replace"
+msgstr "Αντικατάσταση εικόνας Ï€Ïοεπισκόπησης"
+
+#: views/developers/previews.thtml:126
+msgid "devcp_previews_a_update"
+msgstr "ΕνημέÏωση εικόνων Ï€Ïοεπισκόπησης"
+
+#: views/developers/previews.thtml:115
+#: views/developers/previews.thtml:124
+msgid "devcp_previews_add_new"
+msgstr "ΠÏοσθήκη εικόνας Ï€Ïοεπισκόπησης"
+
+#. %s is a list of file extensions, e.g. ".png, .gif"
+#: views/developers/previews.thtml:116
+msgid "devcp_previews_add_select"
+msgstr "Επιλέξτε παÏακάτω μια εικόνα για αποστολή. Εικόνες μεγαλÏτεÏες από τη μέγιστη επιτÏεπόμενη διάσταση των 700 πίξελ σε πλάτος επί 525 πίξελ σε Ïψος θα σμικÏυνθοÏν. ΕπιτÏεπόμενες μοÏφές αÏχείων: %s"
+
+#: views/developers/previews.thtml:121
+msgid "devcp_previews_click_below"
+msgstr "Κάντε κλικ στο κουμπί «ΕνημέÏωση εικόνων Ï€Ïοεπισκόπησης» για αποστολή."
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/previews.thtml:102
+msgid "devcp_previews_click_update"
+msgstr "Κάντε κλικ στο κουμπί «ΕνημέÏωση εικόνων Ï€Ïοεπισκόπησης» παÏακάτω για να αποθηκευθεί η εικόνα. (<a %s>ΑκÏÏωση;</a>)"
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/previews.thtml:107
+msgid "devcp_previews_error_message"
+msgstr "Αυτή η εικόνα Ï€Ïοεπισκόπησης θα διαγÏαφεί όταν κάνετε κλικ στο κουμπί «ΕνημέÏωση εικόνων Ï€Ïοεπισκόπησης παÏακάτω. (<a %s>ΑκÏÏωση;</a>)"
+
+#: views/previews/add.thtml:45
+msgid "devcp_previews_filetype_info"
+msgstr "ΧÏησιμοποιήστε την παÏακάτω φόÏμα για να αποστείλετε εικόνες Ï€Ïοεπισκόπησης του Ï€Ïοσθέτου σας σε Ï„Ïπο αÏχείου PNG, JPG, ή GIF. Εικόνες μεγαλÏτεÏες από 700 πίξελ σε πλάτος και 525 πίξελ σε Ïψος, θα αλλάξουν μέγεθος αυτόματα."
+
+#: views/previews/add.thtml:43
+msgid "devcp_previews_header_add"
+msgstr "ΠÏοσθήκη εικόνας Ï€Ïοεπισκόπησης"
+
+#: views/developers/previews.thtml:80
+msgid "devcp_previews_header_caption"
+msgstr "Λεζάντα εικόνας Ï€Ïοεπισκόπησης"
+
+#: views/previews/edit.thtml:43
+msgid "devcp_previews_header_edit"
+msgstr "ΕπεξεÏγασία εικόνας Ï€Ïοεπισκόπησης"
+
+#: views/developers/previews.thtml:93
+msgid "devcp_previews_label_default"
+msgstr "ΑÏχική εικόνα Ï€Ïοεπισκόπησης"
+
+#: views/previews/add.thtml:54
+msgid "devcp_previews_label_file"
+msgstr "ΑÏχείο εικόνας Ï€Ïοεπισκόπησης"
+
+#: views/previews/add.thtml:59
+#: views/previews/edit.thtml:50
+msgid "devcp_previews_label_makedefault"
+msgstr "ΟÏισμός εικόνας ως αÏχικής εικόνας Ï€Ïοεπισκόπησης"
+
+#: views/developers/previews.thtml:100
+msgid "devcp_previews_label_new"
+msgstr "Îέα εικόνα:"
+
+#: views/developers/previews.thtml:118
+msgid "devcp_previews_label_upload"
+msgstr "Αποστολή εικόνας Ï€Ïοεπισκόπησης: "
+
+#: views/developers/previews.thtml:50
+msgid "devcp_previews_notice_error"
+msgstr "Μια ή πεÏισσότεÏες από τις νέες εικόνες Ï€Ïοεπισκόπησης δεν ήταν δυνατό να αποθηκευθοÏν."
+
+#: views/developers/previews.thtml:47
+msgid "devcp_previews_notice_success"
+msgstr "Οι εικόνες Ï€Ïοεπισκόπησης ενημεÏώθηκαν με επιτυχία."
+
+#: views/developers/previews.thtml:59
+msgid "devcp_previews_p_screenshots"
+msgstr "ΠαÏακάτω εμφανίζονται οι εικόνες Ï€Ïοεπισκόπησης του Ï€Ïόσθετου σας. ΜποÏείτε να κάνετε αλλαγές στις παÏακάτω εικόνες ή λεζάντες. Η αÏχική εικόνα Ï€Ïοεπισκόπησης είναι αυτή που θα Ï€Ïοβάλλεται δίπλα από το όνομα του Ï€Ïόσθετου σας στις λίστες πεÏιήγησης και αναζήτησης."
+
+#: views/previews/edit.thtml:55
+msgid "devcp_previews_submit_delete"
+msgstr "ΔιαγÏαφή εικόνας Ï€Ïοεπισκόπησης"
+
+#: views/previews/edit.thtml:55
+msgid "devcp_previews_submit_delete_confirm"
+msgstr "Θέλετε να διαγÏαφεί η εικόνα Ï€Ïοεπισκόπησης;"
+
+#: views/previews/edit.thtml:54
+msgid "devcp_previews_submit_edit"
+msgstr "ΕπεξεÏγασία εικόνας Ï€Ïοεπισκόπησης"
+
+#: views/previews/add.thtml:63
+msgid "devcp_previews_submit_upload"
+msgstr "Αποστολή εικόνας Ï€Ïοεπισκόπησης"
+
+#: views/developers/previews.thtml:78
+msgid "devcp_previews_thumbnail"
+msgstr "ΜικÏογÏαφία"
+
+#. %s is the add-on name.
+#: views/developers/previews.thtml:44
+msgid "devcp_previews_title"
+msgstr "ΔιαχειÏιστής Ï€Ïοεπισκόπησης %s"
+
+#: views/developers/uploader.thtml:74
+msgid "devcp_review_agreement_please"
+msgstr "ΠαÏακαλοÏμε διαβάστε και αποδεχτείτε το ακόλουθο συμφωνητικό δημιουÏÎ³Î¿Ï Ï€Ïιν Ï€ÏοχωÏήσετε."
+
+#: views/elements/developers/rolecheck.thtml:42
+msgid "devcp_rolecheck_no_privs"
+msgstr "<span>Δεν έχετε επαÏκή δικαιώματα για να κάνετε αλλαγές σ' αυτή τη σελίδα.</span><br />Επικοινωνήστε με τον ιδιοκτήτη του Ï€Ïόσθετου αν θέλετε να κάνετε αλλαγές."
+
+#: controllers/developers_controller.php:1315
+msgid "devcp_several_hours"
+msgstr "ΠαÏακαλοÏμε σημειώστε ότι μεÏικές αλλαγές μποÏεί να χÏειαστοÏν αÏκετές ÏŽÏες μέχÏι να εμφανιστοÏν σε όλους τους χώÏους του ιστότοπου."
+
+#: views/elements/developers/sidebar.thtml:52
+msgid "devcp_sidebar_a_dashboard"
+msgstr "Ταμπλό"
+
+#. %s is a number
+#: views/elements/developers/statsbar.thtml:45
+#: views/developers/dashboard.thtml:79
+#, php-format
+msgid "devcp_statsbar_adu"
+msgstr "<em>%s</em> ενεÏγοί καθημεÏινοί χÏήστες"
+
+#. %s is a number
+#: views/elements/developers/statsbar.thtml:41
+#: views/developers/dashboard.thtml:75
+#, php-format
+msgid "devcp_statsbar_total_downloads"
+msgstr "<em>%s</em> συνολικές λήψεις"
+
+#. %s is a number
+#: views/elements/developers/statsbar.thtml:43
+#: views/developers/dashboard.thtml:77
+#, php-format
+msgid "devcp_statsbar_weekly_downloads"
+msgstr "<em>%s</em> εβδομαδιαίες λήψεις"
+
+#: views/developers/addon_status_confirm.thtml:59
+msgid "devcp_status_confirm_active"
+msgstr "Η σημείωση Î±Ï…Ï„Î¿Ï Ï„Î¿Ï… Ï€Ïόσθετου ως «ενεÏγό» σημαίνει ότι θα εμφανίζεται δημόσια σε κατάλληλους χώÏους ανάλογα με την κατάσταση του, συμπεÏιλαμβανομένων της αναζήτησης και της λίστας πεÏιήγησης. Θα είναι δυνατή η λήψη του από τον ιστότοπο και θα επιστÏέφεται σαν αποτέλεσμα σε ελέγχους διαθέσιμων ενημεÏώσεων της εφαÏμογής ανάλογα με την κατάσταση του. Θα μποÏείτε να επιστÏέψετε εδώ και να το απενεÏγοποιήσετε ξανά αν το θελήσετε."
+
+#: views/developers/addon_status_confirm.thtml:59
+msgid "devcp_status_confirm_active_sure"
+msgstr "Θέλετε σίγουÏα να οÏίσετε αυτό το Ï€Ïόσθετο σαν ενεÏγό;"
+
+#: views/developers/addon_status_confirm.thtml:50
+msgid "devcp_status_confirm_header_sure"
+msgstr "Είστε σίγουÏοι;"
+
+#: views/developers/addon_status_confirm.thtml:55
+msgid "devcp_status_confirm_inactive"
+msgstr "Η σημείωση Î±Ï…Ï„Î¿Ï Ï„Î¿Ï… Ï€Ïόσθετου ως «ανενεÏγό» θα εμποδίσει την εμφάνιση του σε οποιοδήποτε χώÏο, συμπεÏιλαμβανομένων της αναζήτησης και της λίστας πεÏιήγησης. Δεν θα είναι δυνατή η λήψη του από τον ιστότοπο και δεν θα επιστÏέφονται αποτελέσματα σε έλεγχους διαθέσιμων ενημεÏώσεων της εφαÏμογής. Θα μποÏείτε όμως να επιστÏέψετε εδώ και να το ενεÏγοποιήσετε ξανά όταν θελήσετε."
+
+#: views/developers/addon_status_confirm.thtml:55
+msgid "devcp_status_confirm_inactive_sure"
+msgstr "Θέλετε σίγουÏα να οÏίσετε αυτό το Ï€Ïόσθετο σαν ανενεÏγό;"
+
+#: views/developers/addon_status_confirm.thtml:74
+msgid "devcp_status_confirm_no"
+msgstr "Όχι, ακÏÏωση"
+
+#: views/developers/addon_status_confirm.thtml:67
+msgid "devcp_status_confirm_public"
+msgstr "Η μεταφοÏά Î±Ï…Ï„Î¿Ï Ï„Î¿Ï… Ï€Ïόσθετου στο δημόσιο χώÏο σημαίνει ότι θα είναι διαθέσιμο για λήψη από τον καθένα και θα παÏέχονται ενημεÏώσεις σε όσους το χÏησιμοποιοÏν ήδη."
+
+#: views/developers/addon_status_confirm.thtml:67
+msgid "devcp_status_confirm_public_sure"
+msgstr "Θέλετε να μεταφεÏθεί αυτό το Ï€Ïόσθετο στο δημόσιο χώÏο;"
+
+#: views/developers/addon_status_confirm.thtml:63
+msgid "devcp_status_confirm_sandbox"
+msgstr "Η μετακίνηση Î±Ï…Ï„Î¿Ï Ï„Î¿Ï… Ï€Ïόσθετου πίσω στο sandbox σημαίνει πως οι χÏήστες θα Ï€Ïέπει να συνδεθοÏν για να κάνουν λήψη και δεν θα Ï€ÏοσφέÏουμε ενημεÏώσεις σε όσους το χÏησιμοποιοÏν ήδη. Επειδή το Ï€Ïόσθετο σας βÏίσκεται αυτή τη στιγμή στο δημόσιο χώÏο, θα μποÏείτε να επιστÏέψετε εδώ οποιαδήποτε στιγμή και να το μεταφέÏετε στο δημόσιο χώÏο ξανά."
+
+#: views/developers/addon_status_confirm.thtml:63
+msgid "devcp_status_confirm_sandbox_sure"
+msgstr "Θέλετε σίγουÏα να μετακινήσετε αυτό το Ï€Ïόσθετο στο;"
+
+#: views/developers/addon_status_confirm.thtml:73
+msgid "devcp_status_confirm_yes"
+msgstr "Îαι, είμαι σίγουÏος"
+
+#: views/developers/addon_status_nominate.thtml:46
+msgid "devcp_status_nominate_error_notice"
+msgstr "<span>Απαιτείται μήνυμα υποψηφιότητας.</span><br />ΠαÏακαλοÏμε συμπληÏώστε το παÏακάτω πεδίο κειμένου με τις απαÏαίτητες πληÏοφοÏίες και Ï€Ïοσπαθήστε ξανά."
+
+#: views/developers/addon_status_nominate.thtml:55
+msgid "devcp_status_nominate_header"
+msgstr "Υποψηφιότητα Ï€Ïόσθετου"
+
+#: views/developers/dashboard.thtml:85
+msgid "devcp_summary_lastversion"
+msgstr "Πιο Ï€Ïόσφατη έκδοση:"
+
+#. %s is the add-on name.
+#: views/developers/addon_edit.thtml:43
+#: views/developers/addon_edit_authors.thtml:44
+#: views/developers/versions_delete.thtml:43
+#: views/developers/addon_edit_properties.thtml:44
+#: views/developers/addon_edit_descriptions.thtml:44
+#: views/developers/versions_edit.thtml:44
+#: views/developers/addon_edit_categories.thtml:43
+#: views/developers/versions.thtml:43
+msgid "devcp_title_edit_addon"
+msgstr "ΕπεξεÏγασία %s"
+
+#. title attribute for a javascript link that pops up a help dialog.
+#: views/elements/translationbox.thtml:68
+msgid "devcp_transbox_a_title_help"
+msgstr "Βοήθεια (δεν αλλάζει σελίδα)"
+
+#: views/elements/translationbox.thtml:68
+msgid "devcp_transbox_alt_help"
+msgstr "Βοήθεια"
+
+#. %1$s is <span>17</span>, %2$s is 42.
+#: views/elements/translationbox.thtml:101
+msgid "devcp_transbox_chars_used"
+msgstr "ΧαÏακτήÏες που χÏησιμοποιοÏνται: %1$s / %2$s"
+
+#: views/elements/translationbox.thtml:132
+msgid "devcp_transbox_delete_sure"
+msgstr "Θέλετε σίγουÏα να διαγÏάψετε αυτή τη μετάφÏαση;"
+
+#. %s is a locale, like en-US.
+#: views/elements/translationbox.thtml:143
+msgid "devcp_transbox_help_header_tabs"
+msgstr "Τι είναι αυτές οι %s καÏτέλες;"
+
+#: views/elements/translationbox.thtml:145
+msgid "devcp_transbox_help_header_what"
+msgstr "Τι γίνεται αν δεν έχω μεταφÏάσεις;"
+
+#: views/elements/translationbox.thtml:147
+msgid "devcp_transbox_help_hide"
+msgstr "ΑπόκÏυψη βοήθειας"
+
+#: views/elements/translationbox.thtml:146
+msgid "devcp_transbox_help_if"
+msgstr "Αν κάποιος χÏήστης πεÏιηγήται στον ιστότοπο και δεν υπάÏχει μετάφÏαση για τη γλώσσα του, θα χÏησιμοποιηθεί η αÏχική γλωσσική ÏÏθμιση του Ï€Ïόσθετου σας που έχετε οÏίσει στην πεÏιοχή επεξεÏγασίας ιδιοτήτων Ï€Ïόσθετου. Αν δεν έχετε καμία μετάφÏαση, απλά εισάγετε τις πληÏοφοÏίες που θέλετε στην «ΑÏχική γλώσσα» χÏησιμοποιώντας τη γλώσσα που μιλάτε."
+
+#: views/elements/translationbox.thtml:144
+msgid "devcp_transbox_help_transbox"
+msgstr "Είναι <i>πλαίσιο μετάφÏασης</i>. Σας επιτÏέπει να μεταφÏάσετε συγκεκÏιμένα πεδία σε οποιαδήποτε γλώσσα μποÏείτε. ΜποÏείτε να Ï€Ïοσθέσετε, να επεξεÏγαστείτε και να αφαιÏέσετε μεταφÏάσεις μέσα από τις καÏτέλες μετάφÏασης."
+
+#: views/elements/translationbox.thtml:85
+msgid "devcp_transbox_img_add_trans"
+msgstr "ΠÏοσθήκη μετάφÏασης"
+
+#: views/elements/translationbox.thtml:86
+msgid "devcp_transbox_img_remove_trans"
+msgstr "ΑφαίÏεση μετάφÏασης"
+
+#: views/elements/translationbox.thtml:123
+msgid "devcp_transbox_input_add_all"
+msgstr "ΠÏοσθήκη γλώσσας σε όλες"
+
+#: views/elements/translationbox.thtml:122
+msgid "devcp_transbox_input_add_locale"
+msgstr "ΠÏοσθήκη γλώσσας"
+
+#: views/elements/translationbox.thtml:124
+#: views/elements/translationbox.thtml:135
+msgid "devcp_transbox_input_cancel"
+msgstr "ΑκÏÏωση"
+
+#: views/elements/translationbox.thtml:134
+msgid "devcp_transbox_input_delete"
+msgstr "ΔιαγÏαφή"
+
+#: views/elements/translationbox.thtml:113
+msgid "devcp_transbox_select_locale"
+msgstr "Επιλέξτε τη γλώσσα της μετάφÏασης που θα Ï€Ïοστεθεί:"
+
+#. %1$s and %2$s are GUIDs.
+#: controllers/developers_controller.php:343
+msgid "devcp_update_addon_guid_error"
+msgstr "Το GUID του Ï€Ïόσθετου που υπάÏχει σ' αυτό το αÏχείο (%1$s) dδεν ταιÏιάζει με το υπάÏχον GUID Î±Ï…Ï„Î¿Ï Ï„Î¿Ï… Ï€Ïόσθετου (%2$s)."
+
+#: controllers/developers_controller.php:334
+msgid "devcp_update_addon_priv_error"
+msgstr "Δεν έχετε επαÏκή δικαιώματα για να ενημεÏώσετε αυτό το Ï€Ïόσθετο."
+
+#. %1$s is a version number, %2$s is an add-on ID.
+#: controllers/developers_controller.php:399
+msgid "devcp_update_addon_version_belong_error"
+msgstr "Η συγκεκÏιμένη έκδοση (%1$s) δεν ανήκει σ' αυτό το Ï€Ïόσθετο (%2$s)."
+
+#. %1$s is a version number, maybe 1.1.
+#. %2$s is a URL.
+#: controllers/developers_controller.php:351
+msgid "devcp_update_addon_version_exists_error"
+msgstr "Ο αÏιθμός έκδοσης που αποστείλατε (%1$s) υπάÏχει ήδη σ' αυτό το Ï€Ïόσθετο. Αν θέλετε να Ï€Ïοσθέσετε κάποιο αÏχείο γι' αυτή την έκδοση, κάντε κλικ <a href=\"%2$s\">εδώ</a>."
+
+#. %1$s and %2$s are version numbers.
+#: controllers/developers_controller.php:405
+msgid "devcp_update_addon_version_match_error"
+msgstr "Ο αÏιθμός έκδοσης που αποστείλατε (%1$s) δεν ταιÏιάζει με τον Ï„Ïέχοντα αÏιθμό έκδοσης (%2$s)."
+
+#: views/developers/uploader.thtml:68
+msgid "devcp_uploader_a_start"
+msgstr "Ξεκινήστε"
+
+#: views/developers/uploader.thtml:137
+msgid "devcp_uploader_ajax_loading"
+msgstr "Γίνεται μεταφοÏά αÏχείου..."
+
+#: views/developers/uploader.thtml:82
+msgid "devcp_uploader_button_agree"
+msgstr "Αποδοχή και συνέχεια"
+
+#: views/developers/uploader.thtml:157
+msgid "devcp_uploader_button_edit"
+msgstr "ΕπεξεÏγασία του Ï€Ïόσθετου μου"
+
+#: views/developers/uploader.thtml:158
+msgid "devcp_uploader_button_later"
+msgstr "Θα ολοκληÏώσω το Ï€Ïόσθετο μου αÏγότεÏα."
+
+#: views/developers/uploader.thtml:168
+msgid "devcp_uploader_button_release"
+msgstr "ΠÏοσθήκη σημειώσεων έκδοσης"
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/uploader.thtml:156
+msgid "devcp_uploader_created_results"
+msgstr "<p>Η εγγÏαφή του Ï€Ïόσθετου σας δημιουÏγήθηκε με επιτυχία. Οι βασικές πληÏοφοÏίες που αποκτήθηκαν από το αÏχείο που μεταφέÏατε έχουν αποθηκευθεί, αλλά υπάÏχουν πολλά ακόμα που μποÏείτε να δηλώσετε.</p><p>Το Ï€Ïόσθετο σας έχει σημειωθεί Ï€Ïος το παÏόν ως <strong>ημιτελές</strong>. Για να ολοκληÏώσετε το Ï€Ïόσθετο σας, θα Ï€Ïέπει να φÏοντίσετε να έχει ένα ακÏιβές όνομα, μια σÏνοψη και μια πεÏιγÏαφή, καθώς και να έχετε επιλέξει τουλάχιστον μια κατηγοÏία. ΜποÏείτε να επεξεÏγαστείτε τις πληÏοφοÏίες του Ï€Ïόσθετου σας χÏησιμοποιώντας τον παÏακάτω δεσμό και να ελέγξετε την κατάσταση του οποιαδήποτε στιγμή στη <a %s>σελίδα κατάστασης</a>."
+
+#: views/developers/uploader.thtml:143
+msgid "devcp_uploader_error_correct"
+msgstr "ΠαÏακαλοÏμε διοÏθώστε αυτό το Ï€Ïόβλημα και αποστείλετε το αÏχείο ξανά."
+
+#. %1$s is a version number, %2$s is a status, e.g Public or Incomplete.
+#: views/developers/uploader.thtml:175
+msgid "devcp_uploader_file_created"
+msgstr "Το νέο σας αÏχείο Ï€Ïοστέθηκε στην έκδοση %1$s και η κατάσταση του έχει Ï€Ïος το παÏόν χαÏακτηÏιστεί ως «%2$s»."
+
+#: views/developers/uploader.thtml:154
+msgid "devcp_uploader_header_created"
+msgstr "Το Ï€Ïόσθετο δημιουÏγήθηκε!"
+
+#: views/developers/uploader.thtml:141
+msgid "devcp_uploader_header_error"
+msgstr "Το αÏχείο αυτό μάλλον έχει κάποιο Ï€Ïόβλημα..."
+
+#: views/developers/uploader.thtml:173
+msgid "devcp_uploader_header_file_added"
+msgstr "Το αÏχείο Ï€Ïοστέθηκε!"
+
+#: views/developers/uploader.thtml:66
+msgid "devcp_uploader_header_how"
+msgstr "Πως δουλεÏει το σÏστημα;"
+
+#. %s is the version number, e.g. 3.2.
+#: views/developers/uploader.thtml:163
+msgid "devcp_uploader_header_update_created"
+msgstr "ΔημιουÏγήθηκε η έκδοση %s"
+
+#: views/developers/uploader.thtml:117
+msgid "devcp_uploader_header_upload"
+msgstr "Αποστολή του αÏχείου σας"
+
+#: views/developers/uploader.thtml:67
+msgid "devcp_uploader_how"
+msgstr "<p>ΕυχαÏιστοÏμε για το ενδιαφέÏον σας να υποβάλετε το Ï€Ïόσθετο σας στον ιστότοπο Ï€Ïόσθετων του Mozilla. Η φιλοξενία του Ï€Ïόσθετου σας στον ιστότοπο Ï€Ïόσθετων του είναι ο ευκολότεÏος Ï„Ïόπος να διαχειÏιστείτε τη διανομή του. Τι Ï€ÏοσφέÏουμε:</p><ul><li>Κάθε Ï€Ïόσθετο εμφανίζεται δημόσια σε μια σελίδα με πληÏοφοÏίες που μας δίνετε, όπως μια συνοπτική πεÏιγÏαφή των λειτουÏγιών του, μια Ï€ÏοαιÏετικά πιο λεπτομεÏή πεÏιγÏαφή και μια σειÏά εικόνων Ï€Ïοεπισκόπησης του Ï€Ïόσθετου σας.</li><li>Το Ï€Ïόσθετο σας θα εμφανίζεται στη μηχανή αναζήτησης και τις λίστες πεÏιήγησης του ιστότοπου και μέσα στον ενσωματωμένο διαχειÏιστή Ï€Ïόσθετων του Firefox 3.</li><li>ΦÏοντίζουμε για τη λήψη του Ï€Ïόσθετου σας και παÏέχουμε αυτόματες ενημεÏώσεις στους χÏήστες του όταν μας αποστείλετε νέα έκδοση.</li><li>Σας παÏέχουμε Ï€Ïόσβαση σε ένα ταμπλό στατιστικών με αναλυτικές λεπτομέÏειες για τη βάση χÏηστών σας.</li></ul><p> Τα Ï€Ïόσθετα που φιλοξενοÏμε στον ιστότοπο αυτό, θα Ï€Ïέπει να αξιολογήθουν από κάποιο συντάκτη του ιστότοπου για να αποκτήσουν όλα όσα αναφέÏαμε παÏαπάνω. Αν είστε έτοιμοι να ξεκινήσετε τη διαδικασία και έχετε ετοιμάσει το πακέτο του Ï€Ïόσθετου σας για αποστολή, απλά κάντε κλικ στο παÏακάτω κουμπί «Ξεκινήστε Ï„ÏŽÏα»!</p>"
+
+#: views/developers/uploader.thtml:125
+msgid "devcp_uploader_label_platformtype"
+msgstr "ΥποστηÏιζόμενες πλατφόÏμες:"
+
+#: views/developers/uploader.thtml:124
+msgid "devcp_uploader_label_upload_field"
+msgstr "ΑÏχείο Ï€Ïόσθετου: "
+
+#: controllers/components/developers.php:1221
+msgid "devcp_uploader_option_other"
+msgstr "Άλλο"
+
+#. %1$s is a number, %2$s is href="..." and should stay in the <a> tag.
+#: views/developers/uploader.thtml:176
+msgid "devcp_uploader_p_pending_file"
+msgstr "Το νέο σας αÏχείο θα είναι διαθέσιμο στο δημόσιο χώÏο όταν θα μποÏέσει να το αξιολογήσει κάποιος συντάκτης. ΥπάÏχουν Ï€Ïος το παÏόν %1$s άλλα Ï€Ïόσθετα σε ουÏά αναμονής. Θέλετε να επιταχÏνετε τη διαδικασία αξιολόγησης; Σκεφτείτε την πιθανότητα να <a %2$s>γίνετε συντάκτης</a> κι εσείς."
+
+#. %1$s is a number, %2$s is href="..." and should stay in the <a> tag.
+#: views/developers/uploader.thtml:166
+msgid "devcp_uploader_p_pending_version"
+msgstr "Η νέα έκδοση θα είναι διαθέσιμη στο δημόσιο χώÏο όταν θα μποÏέσει να την αξιολογήσει κάποιος συντάκτης. ΥπάÏχουν Ï€Ïος το παÏόν %1$s άλλα Ï€Ïόσθετα σε ουÏά αναμονής. Θέλετε να επιταχÏνετε τη διαδικασία αξιολόγησης; Σκεφτείτε την πιθανότητα να <a %2$s>γίνετε συντάκτης</a> κι εσείς."
+
+#. %s is a status, e.g Public or Incomplete.
+#: views/developers/uploader.thtml:165
+msgid "devcp_uploader_p_update_created"
+msgstr "ΔημιουÏγήθηκε η νέα σας έκδοση και έχει σημειωθεί Ï€Ïος το παÏόν σε κατάσταση «%s»."
+
+#. %1$s is href="..." and should stay in the 'Versions and Files' <a> tag.
+#. %2$s is href="..." and should stay in the 'current status' <a> tag.
+#: views/developers/uploader.thtml:177
+msgid "devcp_uploader_p_update_file"
+msgstr "Δείτε το νέο σας αÏχείο στη <a %1$s>σελίδα εκδόσεων και αÏχείων</a>, ελέγξτε την <a %2$s>Ï„Ïέχουσα κατάσταση</a> του Ï€Ïόσθετου σας, ή <b>Ï€Ïοσθέστε σημειώσεις έκδοσης</b> κάνοντας κλικ στο παÏακάτω κουμπί (συνιστάται)."
+
+#. %1$s is href="..." and should stay in the 'Versions and Files' <a> tag.
+#. %2$s is href="..." and should stay in the 'current status' <a> tag.
+#: views/developers/uploader.thtml:167
+msgid "devcp_uploader_p_update_version"
+msgstr "Δείτε τη νέα έκδοση σας στη <a %1$s>σελίδα εκδόσεων και αÏχείων</a>, ελέγξτε την <a %2$s>Ï„Ïέχουσα κατάσταση</a> του Ï€Ïόσθετου σας, ή <b>Ï€Ïοσθέστε σημειώσεις έκδοσης</b> κάνοντας κλικ στο παÏακάτω κουμπί (συνιστάται)."
+
+#: views/developers/uploader.thtml:118
+msgid "devcp_uploader_p_upload"
+msgstr "Αποστείλετε το αÏχείο του Ï€Ïόσθετου σας από την παÏακάτω φόÏμα. Αν χÏειάζεται να αποστείλετε διάφοÏα αÏχεία, ξεχωÏιστά για κάθε πλατφόÏμα, επιλέξτε ένα μοναδικό αÏχείο και μετά αποστείλετε τα υπόλοιπα χÏησιμοποιώντας τον διαχειÏιστή εκδόσεων και αÏχείων."
+
+#: views/developers/uploader.thtml:125
+msgid "devcp_uploader_platformtype_all"
+msgstr "Όλες"
+
+#: views/developers/uploader.thtml:126
+msgid "devcp_uploader_platformtype_specific"
+msgstr "ΣυγκεκÏιμένα:"
+
+#. Used as first item in a <select>.
+#: controllers/components/developers.php:1185
+msgid "devcp_uploader_please_choose"
+msgstr "ΠαÏακαλοÏμε επιλέξτε..."
+
+#. %1$s is the add-on name, %2$s is the version number.
+#: views/developers/uploader.thtml:57
+msgid "devcp_uploader_title_file"
+msgstr "ΠÏοσθήκη αÏχείου στο %1$s %2$s"
+
+#: views/developers/uploader.thtml:50
+msgid "devcp_uploader_title_submit"
+msgstr "Υποβολή νέου Ï€Ïόσθετου"
+
+#. %s is the add-on name.
+#: views/developers/uploader.thtml:54
+msgid "devcp_uploader_title_update"
+msgstr "ΕνημέÏωση του %s"
+
+#. %s is a full <a> tag
+#: controllers/developers_controller.php:503
+#, php-format
+msgid "devcp_valid_app_reference"
+msgstr "ΠαÏακαλοÏμε δείτε %s για οδηγίες."
+
+#. This is the text in the <a> tag for devcp_valid_app_reference. This should be
+#. fixed.
+#: controllers/developers_controller.php:503
+msgid "devcp_valid_app_reference_linktext"
+msgstr "αυτή τη σελίδα"
+
+#: controllers/developers_controller.php:581
+msgid "devcp_verify_author_error"
+msgstr "Δεν βÏέθηκε λογαÏιασμός με αυτή τη διεÏθυνση ηλ. αλληλογÏαφίας."
+
+#: controllers/developers_controller.php:553
+msgid "devcp_verify_search_engine_error"
+msgstr "Είτε δεν είναι έγκυÏος ο κώδικας XML, είτε απουσιάζουν απαιτοÏμενα πεδία. ΠαÏακαλοÏμε δείτε την <a href=\"https://developer.mozilla.org/en/Creating_OpenSearch_plugins_for_Firefox\">τεκμηÏίωση</a>, επαληθεÏστε το Ï€Ïόσθετο σας και Ï€Ïοσπαθήστε ξανά."
+
+#: views/developers/versions.thtml:75
+msgid "devcp_versions_a_cancel"
+msgstr "ΑκÏÏωση"
+
+#: views/developers/versions.thtml:79
+msgid "devcp_versions_a_delete"
+msgstr "ΔιαγÏαφή έκδοσης"
+
+#: views/developers/versions.thtml:74
+msgid "devcp_versions_a_empty"
+msgstr "ΑφαίÏεση κενής έκδοσης"
+
+#: views/developers/versions.thtml:71
+msgid "devcp_versions_a_remove"
+msgstr "ΑφαίÏεση;"
+
+#: views/developers/versions.thtml:91
+msgid "devcp_versions_add"
+msgstr "ΠÏοσθήκη νέας έκδοσης"
+
+#: views/developers/versions_delete.thtml:58
+msgid "devcp_versions_delete_a_cancel"
+msgstr "ΑκÏÏωση"
+
+#: views/developers/versions_delete.thtml:56
+msgid "devcp_versions_delete_a_delete"
+msgstr "ΔιαγÏαφή έκδοσης"
+
+#. Followed by a list of reviews and files that will be removed.
+#: views/developers/versions_delete.thtml:50
+msgid "devcp_versions_delete_also"
+msgstr "Αυτή η ενέÏγεια θα διαγÏάψει επίσης:"
+
+#: views/developers/versions_delete.thtml:53
+msgid "devcp_versions_delete_files"
+msgid_plural "devcp_versions_delete_files"
+msgstr[0] "%s αÏχείο"
+msgstr[1] "%s αÏχεία"
+
+#. %s is the version number.
+#: views/developers/versions_delete.thtml:48
+msgid "devcp_versions_delete_header"
+msgstr "ΔιαγÏαφή έκδοσης %s;"
+
+#: views/developers/versions_delete.thtml:52
+msgid "devcp_versions_delete_reviews"
+msgid_plural "devcp_versions_delete_reviews"
+msgstr[0] "%s αξιολόγηση"
+msgstr[1] "%s αξιολογήσεις"
+
+#. %s is the version number.
+#: views/developers/versions_delete.thtml:49
+msgid "devcp_versions_delete_sure"
+msgstr "Θέλετε σίγουÏα να διαγÏαφεί οÏιστικά η έκδοση %s;"
+
+#: views/developers/versions_edit.thtml:102
+#: views/developers/versions_edit.thtml:155
+msgid "devcp_versions_edit_a_cancel"
+msgstr "ΑκÏÏωση"
+
+#: views/developers/versions_edit.thtml:101
+msgid "devcp_versions_edit_a_delete"
+msgstr "ΔιαγÏαφή αÏχείου"
+
+#: views/developers/versions_edit.thtml:165
+msgid "devcp_versions_edit_a_new_app"
+msgstr "ΠÏοσθήκη νέας εφαÏμογής"
+
+#: views/developers/versions_edit.thtml:154
+msgid "devcp_versions_edit_a_remove_app"
+msgstr "ΑφαίÏεση εφαÏμογής"
+
+#: views/developers/versions_edit.thtml:114
+msgid "devcp_versions_edit_add"
+msgstr "ΠÏοσθήκη νέου αÏχείου"
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/versions_edit.thtml:121
+msgid "devcp_versions_edit_adjust"
+msgstr "Η ÏÏθμιση πληÏοφοÏιών για την εφαÏμογή εδώ θα επιτÏέψει στους χÏήστες να εγκαταστήσουν το Ï€Ïόσθετο σας ακόμα και αν το αÏχείο install.rdf του πακέτου υποδεικνÏει ότι δεν είναι συμβατό με την εφαÏμογή. <a %s>Λίστα υποστηÏιζόμενων εφαÏμογών</a>"
+
+#: views/developers/versions_edit.thtml:153
+msgid "devcp_versions_edit_compat_sure"
+msgstr "Θέλετε <b>σίγουÏα</b> να αφαιÏεθεί η συμβατότητα με αυτή την εφαÏμογή;"
+
+#: views/developers/versions_edit.thtml:100
+msgid "devcp_versions_edit_delete_sure"
+msgstr "Θέλετε <b>σίγουÏα</b> να διαγÏαφεί οÏιστικά αυτό το αÏχείο;"
+
+#: views/developers/versions_edit.thtml:203
+msgid "devcp_versions_edit_header_approval"
+msgstr "ΠληÏοφοÏίες έγκÏισης"
+
+#: views/developers/versions_edit.thtml:120
+msgid "devcp_versions_edit_header_compat"
+msgstr "Συμβατές εφαÏμογές"
+
+#: views/developers/versions_edit.thtml:74
+msgid "devcp_versions_edit_header_file"
+msgstr "ΠληÏοφοÏίες αÏχείου"
+
+#: views/developers/versions_edit.thtml:189
+msgid "devcp_versions_edit_header_license"
+msgstr "Άδεια"
+
+#. %s is the version number.
+#: views/developers/versions_edit.thtml:53
+msgid "devcp_versions_edit_header_manage"
+msgstr "ΔιαχείÏιση έκδοσης %s"
+
+#: views/developers/versions_edit.thtml:212
+msgid "devcp_versions_edit_header_notes"
+msgstr "Σημειώσεις έγκÏισης"
+
+#: views/developers/versions_edit.thtml:98
+msgid "devcp_versions_edit_img_delete"
+msgstr "ΔιαγÏαφή αÏχείου"
+
+#. %1$s is the file id, e.g. 18723.
+#. %2$s is the platform name, e.g. ALL or Windows.
+#. %3$s is the _('date) created.
+#. %4$s is the status, e.g. "In Sandbox" or "Public".
+#. %5$s is the _('date') status was changed.
+#: views/developers/versions_edit.thtml:208
+msgid "devcp_versions_edit_li_file"
+msgstr "Το αÏχείο %1$s (πλατφόÏμα: %2$s) δημιουÏγήθηκε στις %3$s και η κατάσταση του άλλαξε σε « %4$s» στις %5$s"
+
+#: views/developers/versions_edit.thtml:190
+msgid "devcp_versions_edit_license_description"
+msgstr "ΠαÏακαλοÏμε επιλέξτε την κατάλληλη άδεια για το Ï€Ïόσθετο σας. Η άδεια αυτή καθοÏίζει τα δικαιώματα που παÏέχετε πάνω στον πηγαίο κώδικα."
+
+#: views/developers/versions_edit.thtml:111
+msgid "devcp_versions_edit_no_files"
+msgstr "Δεν βÏέθηκαν αÏχεία."
+
+#: views/developers/versions_edit.thtml:213
+msgid "devcp_versions_edit_optional"
+msgstr "ΠÏοαιÏετικές πληÏοφοÏίες για τον συντάκτη που θα αξιολογήσει αυτή την έκδοση."
+
+#: views/developers/versions_edit.thtml:151
+msgid "devcp_versions_edit_remove_compat"
+msgstr "ΑφαίÏεση συμβατότητας με εφαÏμογή"
+
+#: views/developers/versions_edit.thtml:167
+msgid "devcp_versions_edit_select_app"
+msgstr "ΠαÏακαλοÏμε επιλέξτε μια εφαÏμογή"
+
+#: views/developers/versions_edit.thtml:78
+msgid "devcp_versions_edit_th_file"
+msgstr "ΑÏχείο"
+
+#: views/developers/versions_edit.thtml:79
+msgid "devcp_versions_edit_th_platform"
+msgstr "ΠλατφόÏμα"
+
+#: views/developers/versions_edit.thtml:80
+msgid "devcp_versions_edit_th_size"
+msgstr "Μέγεθος"
+
+#: views/developers/versions_edit.thtml:81
+msgid "devcp_versions_edit_th_status"
+msgstr "Κατάσταση"
+
+#: views/developers/versions_edit.thtml:183
+msgid "devcp_versions_edit_transbox_releasenotes_description"
+msgstr "ΠληÏοφοÏίες για τις αλλαγές σ' αυτή την έκδοση, νέα χαÏακτηÏιστικά, γνωστά Ï€Ïοβλήματα και άλλες χÏήσιμες πληÏοφοÏίες γι' αυτή τη συγκεκÏιμένη έκδοση. Αυτές οι πληÏοφοÏίες θα είναι διαθέσιμες στους χÏήστες και μέσα από το διάλογο διαχειÏιστή Ï€Ïόσθετων του Firefox 3."
+
+#: views/developers/versions_edit.thtml:182
+msgid "devcp_versions_edit_transbox_releasenotes_name"
+msgstr "Σημειώσεις έκδοσης"
+
+#: views/developers/versions_edit.thtml:164
+msgid "devcp_versions_edit_unsaved_compat"
+msgstr "<strong>ΥπάÏχουν μη αποθηκευμένες αλλαγές.</strong> Η συμβατότητα δεν θα διαγÏαφεί μέχÏι να κάνετε κλικ στο «ΕνημέÏωση εκδόσεων» παÏακάτω."
+
+#: views/developers/versions_edit.thtml:113
+msgid "devcp_versions_edit_unsaved_files"
+msgstr "<strong>ΥπάÏχουν μη αποθηκευμένες αλλαγές.</strong> Τα αÏχεία δεν θα διαγÏαφοÏν αν δεν κάνετε κλικ στο «ΕνημέÏωση εκδόσεων» παÏακάτω."
+
+#: views/developers/versions_edit.thtml:218
+msgid "devcp_versions_edit_update"
+msgstr "ΕνημέÏωση εκδόσεων"
+
+#: views/developers/versions.thtml:49
+msgid "devcp_versions_header_manage"
+msgstr "ΔιαχείÏιση εκδόσεων και αÏχείων"
+
+#: views/developers/versions.thtml:87
+msgid "devcp_versions_no_versions"
+msgstr "Δεν υπάÏχουν εκδόσεις."
+
+#. %s is a version number, base 10.
+#: views/developers/versions.thtml:46
+msgid "devcp_versions_notice_success"
+msgstr "Η έκδοση %s διαγÏάφηκε με επιτυχία."
+
+#: views/developers/versions.thtml:73
+msgid "devcp_versions_p_remove"
+msgstr "Αυτή η έκδοση δεν είναι συσχετισμένη με κανένα αÏχείο και μποÏεί να αφαιÏεθεί. Θέλετε να την αφαιÏέσουμε;"
+
+#: views/developers/versions.thtml:58
+msgid "devcp_versions_th_created"
+msgstr "ΔημιουÏγήθηκε"
+
+#: views/developers/versions.thtml:57
+msgid "devcp_versions_th_status"
+msgstr "Κατάσταση"
+
+#: views/developers/versions.thtml:56
+msgid "devcp_versions_th_version"
+msgstr "Έκδοση"
+
+#: controllers/downloads_controller.php:91
+msgid "downloads_disable_warning"
+msgstr "Αυτό το Ï€Ïόσθετο έχει απενεÏγοποιηθεί"
+
+#: controllers/components/editors.php:57
+msgid "editor_review_error_addon_not_nominated"
+msgstr "Αυτό το Ï€Ïόσθετο δεν είναι υποψήφιο για το δημόσιο χώÏο."
+
+#: controllers/components/editors.php:213
+msgid "editor_review_error_file_not_pending"
+msgstr "Δεν υπάÏχει αναμονή αξιολόγησης για το αÏχείο."
+
+#. Actions are, for example: approving or rejecting
+#: controllers/components/editors.php:79
+#: controllers/components/editors.php:182
+msgid "editor_review_error_no_action"
+msgstr "ΠαÏακαλοÏμε επιλέξτε μια ενέÏγεια αξιολόγησης."
+
+#: controllers/components/editors.php:192
+msgid "editor_review_error_no_applications"
+msgstr "ΠαÏακαλοÏμε εισάγετε τις εφαÏμογές που ελέγξατε."
+
+#. Comments are required when an editor approves or rejects an add-on.
+#: controllers/components/editors.php:84
+#: controllers/components/editors.php:187
+msgid "editor_review_error_no_comments"
+msgstr "ΠαÏακαλοÏμε εισάγετε τα σχόλια αξιολόγησης."
+
+#: controllers/components/editors.php:161
+msgid "editor_review_error_no_files"
+msgstr "ΠαÏακαλοÏμε επιλέξτε τουλάχιστον ένα αÏχείο για αξιολόγηση."
+
+#: controllers/components/editors.php:197
+msgid "editor_review_error_no_operating_system"
+msgstr "ΠαÏακαλοÏμε εισάγετε τα λειτουÏγικά συστήματα που κάνατε ελέγχους."
+
+#: views/editors/logs.thtml:51
+msgid "editorcp_logs_button_filter"
+msgstr "ΦίλτÏο"
+
+#: views/editors/logs.thtml:44
+msgid "editorcp_logs_filter_by"
+msgstr "ΦιλτÏάÏισμα κατά Ï„Ïπο/ενέÏγεια"
+
+#: views/editors/logs.thtml:42
+#: controllers/editors_controller.php:964
+msgid "editorcp_logs_page_heading"
+msgstr "ΚαταγÏαφή συμβάντων"
+
+#: views/elements/developers/editorsmenu.thtml:60
+msgid "editorcp_menu_eventlog_link"
+msgstr "ΚαταγÏαφή συμβάντων"
+
+#: views/elements/developers/editorsmenu.thtml:62
+msgid "editorcp_menu_mainpage_link"
+msgstr "Πίσω στο κεντÏικό"
+
+#: views/elements/developers/editorsmenu.thtml:61
+msgid "editorcp_menu_reviewlog_link"
+msgstr "ΚαταγÏαφή αξιολόγησης"
+
+#: views/elements/developers/editorsmenu.thtml:55
+msgid "editorcp_menu_summary_link"
+msgstr "ΠεÏίληψη συντάκτη"
+
+#: views/elements/developers/editorsmenu.thtml:52
+msgid "editorcp_menu_title"
+msgstr "ΕÏγαλεία συντακτών"
+
+#: views/editors/reviewlog.thtml:49
+msgid "editorcp_reviewlog_button_filter"
+msgstr "ΦίλτÏο"
+
+#: views/editors/reviewlog.thtml:58
+msgid "editorcp_reviewlog_column_action"
+msgstr "ΕνέÏγεια"
+
+#: views/editors/reviewlog.thtml:56
+msgid "editorcp_reviewlog_column_addon"
+msgstr "ΠÏόσθετο"
+
+#: views/editors/reviewlog.thtml:55
+msgid "editorcp_reviewlog_column_date"
+msgstr "ΗμεÏομηνία"
+
+#: views/editors/reviewlog.thtml:57
+msgid "editorcp_reviewlog_column_editor"
+msgstr "Συντάκτης"
+
+#: views/editors/reviewlog.thtml:94
+msgid "editorcp_reviewlog_comments_hide"
+msgstr "ΑπόκÏυψη σχόλιων"
+
+#: views/editors/reviewlog.thtml:93
+msgid "editorcp_reviewlog_comments_show"
+msgstr "ΠÏοβολή σχόλιων"
+
+#. %1$s and %2$s are full <input> tags for dates
+#: views/editors/reviewlog.thtml:45
+#, php-format
+msgid "editorcp_reviewlog_entries_between"
+msgstr "Εμφάνιση εγγÏαφών Î¼ÎµÏ„Î±Î¾Ï %s και %s"
+
+#: views/editors/reviewlog.thtml:104
+msgid "editorcp_reviewlog_none_found"
+msgstr "Δεν βÏέθηκαν αξιολογήσεις γι' αυτή την πεÏίοδο."
+
+#: views/editors/reviewlog.thtml:42
+msgid "editorcp_reviewlog_page_heading"
+msgstr "ΚαταγÏαφή αξιολόγησης"
+
+#: views/editors/summary.thtml:61
+msgid "editorcp_summary_monthreviews_heading"
+msgstr "Μηνιαίες αξιολογήσεις"
+
+#: views/editors/summary.thtml:77
+msgid "editorcp_summary_neweditors_heading"
+msgstr "Îέοι συντάκτες"
+
+#: views/editors/summary.thtml:42
+msgid "editorcp_summary_page_heading"
+msgstr "ΠεÏίληψη συντάκτη"
+
+#: views/editors/summary.thtml:94
+msgid "editorcp_summary_recentactivity_heading"
+msgstr "ΠÏόσφατη δÏαστηÏιότητα συντάκτη"
+
+#: views/editors/summary.thtml:45
+msgid "editorcp_summary_totalreviews_heading"
+msgstr "ΣÏνολο αξιολογήσεων"
+
+#: controllers/editors_controller.php:248
+#: controllers/editors_controller.php:249
+msgid "editors_addon_review_pagetitle"
+msgstr "Αξιολόγηση Ï€Ïόσθετου"
+
+#: controllers/editors_controller.php:349
+msgid "editors_error_js-formerror"
+msgstr "ΠαÏακαλοÏμε συμπληÏώστε τα ακόλουθα πεδία:"
+
+#: controllers/editors_controller.php:350
+msgid "editors_error_review_one_file"
+msgstr "ΠαÏακαλοÏμε επιλέξτε τουλάχιστον ένα αÏχείο για αξιολόγηση."
+
+#: controllers/editors_controller.php:274
+msgid "editors_error_self_reviews_forbidden"
+msgstr "Δεν επιτÏέπεται η αξιολόγηση Î´Î¹ÎºÎ¿Ï ÏƒÎ±Ï‚ Ï€Ïόσθετου."
+
+#: controllers/editors_controller.php:699
+msgid "editors_external_software"
+msgstr "Λογισμικό Ï„Ïίτων"
+
+#: views/editors/featured.thtml:120
+#: views/editors/featured.thtml:121
+msgid "editors_featured_add_feature"
+msgstr "ΠÏοσθήκη χαÏακτηÏιστικοÏ"
+
+#: views/editors/featured.thtml:126
+msgid "editors_featured_add_feature_submit"
+msgstr "ΠÏοσθήκη"
+
+#: views/editors/featured.thtml:49
+#: controllers/editors_controller.php:832
+#: controllers/editors_controller.php:848
+msgid "editors_featured_addon_add_failure"
+msgstr "Αποτυχία Ï€Ïοσθήκης χαÏακτηÏιστικοÏ."
+
+#: controllers/editors_controller.php:851
+msgid "editors_featured_addon_add_success"
+msgstr "Το χαÏακτηÏιστικό Ï€Ïοστέθηκε επιτυχώς."
+
+#: views/editors/featured.thtml:50
+#: controllers/editors_controller.php:839
+#: controllers/editors_controller.php:868
+#: controllers/editors_controller.php:886
+msgid "editors_featured_addon_edit_failure"
+msgstr "Αποτυχία επεξεÏγασίας χαÏακτηÏιστικοÏ."
+
+#: views/editors/featured.thtml:51
+#: controllers/editors_controller.php:888
+msgid "editors_featured_addon_edit_success"
+msgstr "Το χαÏακτηÏιστικό επεξεÏγάστηκε επιτυχώς."
+
+#: views/editors/featured.thtml:53
+#: controllers/editors_controller.php:861
+msgid "editors_featured_addon_invalid_locale"
+msgstr "Μια ή πεÏισσότεÏες γλώσσες δεν είναι έγκυÏη."
+
+#: views/editors/featured.thtml:52
+#: controllers/editors_controller.php:906
+msgid "editors_featured_addon_remove_failure"
+msgstr "Αποτυχία αφαίÏεσης χαÏακτηÏιστικοÏ."
+
+#: controllers/editors_controller.php:901
+msgid "editors_featured_addon_remove_success"
+msgstr "Το χαÏακτηÏιστικό αφαιÏέθηκε επιτυχώς."
+
+#: controllers/editors_controller.php:915
+#: controllers/editors_controller.php:917
+msgid "editors_featured_addons_pagetitle"
+msgstr "Συνιστώμενα Ï€Ïόσθετα"
+
+#: views/editors/featured.thtml:54
+#: views/editors/featured.thtml:107
+msgid "editors_featured_edit_feature_submit"
+msgstr "Μετάβαση"
+
+#: views/editors/featured.thtml:90
+#: views/editors/featured.thtml:91
+msgid "editors_featured_remove_feature"
+msgstr "ΑφαίÏεση χαÏακτηÏιστικοÏ"
+
+#: views/editors/queue.thtml:46
+msgid "editors_filter_queue"
+msgstr "ΟυÏά αναμονής φίλτÏων"
+
+#: views/editors/queue.thtml:182
+msgid "editors_helpful_links"
+msgstr "Δεσμοί για βοήθεια"
+
+#: views/editors/queue.thtml:182
+msgid "editors_link_guide"
+msgstr "Οδηγός συντάκτη"
+
+#: views/editors/queue.thtml:182
+msgid "editors_link_policy"
+msgstr "Πολιτική Ï€Ïόσθετου"
+
+#: views/editors/queue.thtml:47
+msgid "editors_notice_filter_session"
+msgstr "Τα φίλτÏα θα παÏαμείνουν ενεÏγά για τη συνεδÏία ή μέχÏι να εκκαθαÏιστοÏν."
+
+# %1 is the queue mode
+#. %1 is the queue mode
+#: views/editors/queue.thtml:177
+#: views/admin/flagged_queue.thtml:89
+msgid "editors_notice_none_found"
+msgstr "Δεν υπάÏχουν Ï€Ïος το παÏόν Ï€Ïόσθετα για αξιολόγηση"
+
+#: controllers/editors_controller.php:1040
+msgid "editors_one_day"
+msgstr "1 ημέÏα"
+
+#: controllers/editors_controller.php:1048
+msgid "editors_one_hour"
+msgstr "1 ÏŽÏα"
+
+#: controllers/editors_controller.php:1056
+msgid "editors_one_minute"
+msgstr "1 λεπτό"
+
+#: controllers/editors_controller.php:64
+#: controllers/editors_controller.php:73
+#: controllers/editors_controller.php:77
+msgid "editors_pagetitle"
+msgstr "Πίνακας ελέγχου συντάκτη"
+
+#. %s is a comma separated list of platforms. Example: Windows, OS X
+#: controllers/editors_controller.php:680
+#: controllers/editors_controller.php:683
+#, php-format
+msgid "editors_platform_x_only"
+msgstr "μόνο για %s"
+
+#: controllers/editors_controller.php:695
+msgid "editors_pre-release"
+msgstr "ΠÏοέκδοση"
+
+# %1 is the app name
+#. %1 is the app name
+#: views/editors/queue.thtml:131
+#, php-format
+msgid "editors_queue_app_compatibility"
+msgstr "Συμβατότητα με %s"
+
+#: views/editors/queue.thtml:51
+msgid "editors_queue_filter_label_addon"
+msgstr "ΔιεÏθυνση ηλ. ταχυδÏομείου δημιουÏÎ³Î¿Ï Î® Ï€Ïόσθετου"
+
+#: views/editors/queue.thtml:72
+msgid "editors_queue_filter_label_addontypes"
+msgstr "ΤÏποι Ï€Ïόσθετων"
+
+#: views/editors/queue.thtml:56
+msgid "editors_queue_filter_label_application"
+msgstr "ΠÏόγÏαμμα"
+
+#: views/editors/queue.thtml:61
+msgid "editors_queue_filter_label_maxversion"
+msgstr "Μέγιστη έκδοση"
+
+#: views/editors/queue.thtml:78
+msgid "editors_queue_filter_label_platforms"
+msgstr "ΠλατφόÏμες"
+
+#: views/editors/queue.thtml:66
+msgid "editors_queue_filter_label_submissionage"
+msgstr "ΧÏόνος υποβολής (ημέÏες)"
+
+#. %1$s is a number
+#: views/editors/queue.thtml:90
+msgid "editors_queue_filter_result_count"
+msgid_plural "editors_queue_filter_result_count"
+msgstr[0] "Αποτελέσματα της φιλτÏαÏισμένης αναζήτησης: <strong>%1$s</strong> Ï€Ïόσθετο"
+msgstr[1] "Αποτελέσματα της φιλτÏαÏισμένης αναζήτησης: <strong>%1$s</strong> Ï€Ïόσθετα"
+
+#: views/editors/queue.thtml:84
+msgid "editors_queue_submit_clean"
+msgstr "ΕκκαθάÏιση"
+
+#: views/editors/queue.thtml:83
+msgid "editors_queue_submit_filter"
+msgstr "ΦίλτÏο"
+
+#: controllers/editors_controller.php:133
+msgid "editors_queues_disabled"
+msgstr "Όλες οι λίστες αναμονής αξιολογήσεων έχουν Ï€Ïος το παÏόν απενεÏγοποιηθεί. ΠαÏακαλοÏμε Ï€Ïοσπαθήστε ξανά αÏγότεÏα."
+
+#: views/editors/review.thtml:149
+msgid "editors_review_a_edit_item"
+msgstr "ΕπεξεÏγασία αντικειμένου"
+
+#: views/editors/review.thtml:146
+msgid "editors_review_a_item_history"
+msgstr "ΙστοÏικό αντικειμένου"
+
+#: views/editors/review.thtml:148
+msgid "editors_review_a_item_homepage"
+msgstr "ΑÏχική σελίδα αντικειμένου"
+
+#: views/editors/review.thtml:145
+msgid "editors_review_a_item_overview"
+msgstr "Επισκόπηση στοιχείου"
+
+#: views/editors/review.thtml:147
+msgid "editors_review_a_previews"
+msgstr "ΠÏοεπισκοπήσεις"
+
+#: controllers/editors_controller.php:345
+msgid "editors_review_action"
+msgstr "ΕνέÏγεια αξιολόγησης"
+
+#: views/editors/review.thtml:159
+msgid "editors_review_action_info"
+msgstr "Αίτηση για πεÏισσότεÏες πληÏοφοÏίες"
+
+#: views/editors/review.thtml:157
+msgid "editors_review_action_public"
+msgstr "ΠÏοώθηση στο δημόσιο χώÏο"
+
+#: views/editors/review.thtml:160
+msgid "editors_review_action_request_superreview"
+msgstr "Αίτηση ανώτεÏης αξιολόγησης"
+
+#: views/editors/review.thtml:158
+msgid "editors_review_action_sandbox"
+msgstr "ΠαÏαμονή στο Sandbox"
+
+#: controllers/editors_controller.php:346
+msgid "editors_review_comments"
+msgstr "Αξιολόγηση σχόλιων"
+
+#: views/editors/review.thtml:182
+msgid "editors_review_details_info_request"
+msgstr "ΧÏησιμοποιείστε αυτή τη φόÏμα για να ζητήσετε πεÏισσότεÏες πληÏοφοÏίες από τους δημιουÏγοÏÏ‚. Θα ειδοποιηθοÏν μέσω ηλεκτÏÎ¿Î½Î¹ÎºÎ¿Ï Ï„Î±Ï‡Ï…Î´Ïομείου και θα μποÏοÏν να απαντήσουν εδώ. Όταν απαντήσουν, θα ειδοποιηθείτε κι εσείς μέσω ηλεκτÏÎ¿Î½Î¹ÎºÎ¿Ï Ï„Î±Ï‡Ï…Î´Ïομείου."
+
+#: views/editors/review.thtml:174
+msgid "editors_review_details_nominated_public"
+msgstr "Αυτή η ενέÏγεια θα σημειώσει το Ï€Ïόσθετο και την πιο Ï€Ïόσφατη έκδοσή του ως κατάλληλες για τοποθέτηση στο δημόσιο χώÏο. Οι μελλοντικές εκδόσεις θα παÏαμένουν στο sandbox ώσπου να αξιολογηθοÏν από κάποιον συντάκτη."
+
+#: views/editors/review.thtml:177
+msgid "editors_review_details_nominated_sandbox"
+msgstr "Αυτή η ενέÏγεια θα διατηÏήσει το Ï€Ïόσθετο στο sandbox."
+
+#: views/editors/review.thtml:166
+msgid "editors_review_details_pending_public"
+msgstr "Αυτή η ενέÏγεια θα επιτÏέψει σε μια έκδοση που βÏίσκεται Ï€Ïος το παÏόν στο sandbox, να εμφανιστεί στο δημόσιο χώÏο."
+
+#: views/editors/review.thtml:169
+msgid "editors_review_details_pending_sandbox"
+msgstr "Αυτή η ενέÏγεια θα διατηÏήσει στο sandbox μια έκδοση Ï€Ïόσθετου που βÏίσκεται ήδη εκεί."
+
+#: views/editors/review.thtml:185
+msgid "editors_review_details_superreview"
+msgstr "Αν έχετε αμφιβολίες για την ασφάλεια του συγκεκÏιμένου Ï€Ïόσθετου, για θέματα πνευματικής ιδιοκτησίας ή για ο,τιδήποτε άλλο θα έπÏεπε να ελέγξει ένας διαχειÏιστής, εισάγετε τα σχόλιά σας στην παÏακάτω πεÏιοχή. Τα σχόλια θα αποσταλοÏν στους διαχειÏιστές μόνο και όχι στο δημιουÏγό."
+
+#: views/editors/review.thtml:134
+msgid "editors_review_file_diff_link"
+msgstr "ΣÏγκÏιση με την έκδοση στο δημόσιο χώÏο"
+
+#: views/editors/review.thtml:131
+msgid "editors_review_file_viewcontents_link"
+msgstr "Εμφάνιση πεÏιεχομένων"
+
+#: views/editors/review.thtml:65
+msgid "editors_review_header_authors"
+msgstr "ΔημιουÏγοί:"
+
+#: views/editors/review.thtml:79
+msgid "editors_review_header_categories"
+msgstr "ΚατηγοÏίες:"
+
+#: views/editors/review.thtml:92
+msgid "editors_review_header_compatibility"
+msgstr "Συμβατότητα:"
+
+#: views/editors/review.thtml:251
+msgid "editors_review_header_description"
+msgstr "ΠεÏιγÏαφή"
+
+#: views/editors/review.thtml:275
+msgid "editors_review_header_devcomments"
+msgstr "Σχόλια δημιουÏγοÏ"
+
+#: views/editors/review.thtml:263
+msgid "editors_review_header_eula"
+msgstr "ΣΑΤΧ (EULA)"
+
+#: views/editors/review.thtml:115
+msgid "editors_review_header_files"
+msgstr "ΑÏχεία:"
+
+#: views/editors/review.thtml:284
+msgid "editors_review_header_itemhistory"
+msgstr "ΙστοÏικό στοιχείου"
+
+#: views/editors/review.thtml:232
+msgid "editors_review_header_nominationmessage"
+msgstr "Μήνυμα υποβολής υποψηφιότητας"
+
+#: views/editors/review.thtml:311
+msgid "editors_review_header_previews"
+msgstr "Στιγμιότυπα"
+
+#: views/editors/review.thtml:269
+msgid "editors_review_header_privacy"
+msgstr "Πολιτική αποÏÏήτου"
+
+# %1 is the addon name and version
+#. %1 is the add-on name and version
+#: views/editors/review.thtml:56
+#, php-format
+msgid "editors_review_header_review"
+msgstr "Αξιολόγηση του %s"
+
+#: views/editors/review.thtml:239
+msgid "editors_review_header_reviewernotes"
+msgstr "Σημειώσεις για το συντάκτη αξιολόγησης"
+
+#: views/editors/review.thtml:245
+msgid "editors_review_header_summary"
+msgstr "ΠεÏίληψη"
+
+#: views/editors/review.thtml:257
+msgid "editors_review_header_versionnotes"
+msgstr "Σημειώσεις έκδοσης"
+
+#. a noun: shown in an add-on's editor review history
+#: views/elements/developers/editors_review_history_item.thtml:80
+msgid "editors_review_history_info_reply"
+msgstr "Απάντηση"
+
+#: views/elements/developers/editors_review_history_item.thtml:78
+msgid "editors_review_history_info_request"
+msgstr "Αίτηση πληÏοφοÏιών"
+
+#: views/elements/developers/editors_review_history_item.thtml:62
+#: views/editors/reviewlog.thtml:77
+msgid "editors_review_history_nominated_adminreview"
+msgstr "Αξιολόγηση διαχειÏιστή"
+
+#: views/elements/developers/editors_review_history_item.thtml:56
+#: views/editors/reviewlog.thtml:71
+msgid "editors_review_history_nominated_approved"
+msgstr "Η υποψηφιότητα εγκÏίθηκε/δημόσιος χώÏος"
+
+#: views/elements/developers/editors_review_history_item.thtml:59
+#: views/editors/reviewlog.thtml:74
+msgid "editors_review_history_nominated_denied"
+msgstr "Η υποψηφιότητα αποÏÏίφθηκε/Sandbox"
+
+#: views/editors/review.thtml:303
+msgid "editors_review_history_nonefound"
+msgstr "Δε βÏέθηκαν παλαιότεÏες αξιολογήσεις."
+
+#: views/elements/developers/editors_review_history_item.thtml:73
+#: views/editors/reviewlog.thtml:88
+msgid "editors_review_history_pending_adminreview"
+msgstr "Αξιολόγηση διαχειÏιστή"
+
+#: views/elements/developers/editors_review_history_item.thtml:67
+#: views/editors/reviewlog.thtml:82
+msgid "editors_review_history_pending_approved"
+msgstr "ΕγκÏίθηκε/δημόσιος χώÏος"
+
+#: views/elements/developers/editors_review_history_item.thtml:70
+#: views/editors/reviewlog.thtml:85
+msgid "editors_review_history_pending_denied"
+msgstr "ΑποÏÏίφθηκε/Sandbox"
+
+#. link text in an add-on's editor review history, allowing to hide and show an information request's replies
+#. %1 is the number of replies
+#: views/elements/developers/editors_review_history_item.thtml:90
+msgid "editors_review_history_show_hide_replies"
+msgid_plural "editors_review_history_show_hide_replies"
+msgstr[0] "ΠÏοβολή/απόκÏυψη απάντησης (%1$s)"
+msgstr[1] "ΠÏοβολή/απόκÏυψη απαντήσεων (%1$s)"
+
+#: views/editors/review.thtml:208
+msgid "editors_review_label_applications"
+msgstr "ΕφαÏμογές:"
+
+#: views/editors/review.thtml:196
+msgid "editors_review_label_cannedresponse"
+msgstr "ή επιλέξτε μια τυποποιημένη απόκÏιση:"
+
+#: views/editors/review.thtml:190
+msgid "editors_review_label_comments"
+msgstr "Σχόλια:"
+
+#: views/editors/review.thtml:204
+msgid "editors_review_label_operating_systems"
+msgstr "ΛειτουÏγικά συστήματα:"
+
+#: views/editors/review.thtml:285
+#: views/editors/review.thtml:312
+msgid "editors_review_link_pagetop"
+msgstr "ΚοÏυφή"
+
+#: views/editors/review.thtml:141
+msgid "editors_review_mulitple_notice"
+msgstr "Σημείωση: Αξιολογήστε πάνω από ένα αÏχείο μόνο αν ελέγξατε όλα τα αÏχεία που επιλέξατε."
+
+#: views/editors/review.thtml:51
+msgid "editors_review_next_link"
+msgstr "επόμ. &raquo;"
+
+#: views/editors/review.thtml:322
+msgid "editors_review_previews_notfound"
+msgstr "Δε βÏέθηκε αξιολόγηση."
+
+#: views/editors/review.thtml:50
+msgid "editors_review_previous_link"
+msgstr "&laquo; Ï€Ïοηγ."
+
+#: controllers/editors_controller.php:144
+#: controllers/editors_controller.php:146
+msgid "editors_review_queue_pagetitle"
+msgstr "ΟυÏά αναμονής αξιολόγησης"
+
+# %1 is the add-ons rank in the queue, %2 is the total queue length
+#. %1 is the add-ons rank in the queue, %2 is the total queue length
+#: views/editors/review.thtml:47
+msgid "editors_review_rank_in_queue"
+msgstr "<strong># %1$s</strong> από %2$s σε αναμονή"
+
+#. %1 is the add-ons rank in the queue, %2 is the total queue length. Both numbers
+#: views/editors/review.thtml:45
+msgid "editors_review_rank_in_queue_filtered"
+msgstr "<strong># %1$s</strong>ο από %2$s Ï€Ïόσθετα στην ουÏά αναμονής(φιλτÏαÏισμένα))"
+
+#: views/editors/review.thtml:223
+msgid "editors_review_submit_process_action"
+msgstr "ΕνέÏγεια επεξεÏγασίας"
+
+#: views/editors/review.thtml:293
+msgid "editors_review_th_action"
+msgstr "ΕνέÏγεια"
+
+#: views/editors/review.thtml:294
+msgid "editors_review_th_comments"
+msgstr "Σχόλια"
+
+#: views/editors/review.thtml:291
+msgid "editors_review_th_date"
+msgstr "ΗμεÏομηνία"
+
+#: views/editors/review.thtml:292
+msgid "editors_review_th_reviewer"
+msgstr "Συντάκτης αξιολόγησης"
+
+#: views/editors/review.thtml:290
+msgid "editors_review_th_version_file"
+msgstr "Έκδοση/ΑÏχείο"
+
+#: views/editors/review.thtml:217
+msgid "editors_review_update_notify_once"
+msgstr "Îα ειδοποιηθώ την επόμενη φοÏά που θα ενημεÏωθεί το Ï€Ïόσθετο. (ΙσχÏει για μια μόνο φοÏά, δεν θα σταλεί μήνυμα ειδοποίησης για άλλες μελλοντικές ενημεÏώσεις)"
+
+#: controllers/editors_controller.php:298
+msgid "editors_reviewed_successfully"
+msgstr "Η αξιολόγηση επεξεÏγάστηκε με επιτυχία."
+
+#: views/editors/reviews_queue.thtml:106
+msgid "editors_reviews_action_delete_review"
+msgstr "ΔιαγÏαφή αξιολόγησης"
+
+#: views/editors/reviews_queue.thtml:104
+msgid "editors_reviews_action_keep"
+msgstr "ΑφαίÏεση σημείωσης - ΔιατήÏηση αξιολόγησης"
+
+#: views/editors/reviews_queue.thtml:102
+msgid "editors_reviews_action_skip"
+msgstr "ΠαÏάβλεψη"
+
+#: views/editors/reviews_queue.thtml:100
+msgid "editors_reviews_header_action"
+msgstr "ΕνέÏγεια"
+
+#: views/editors/reviews_queue.thtml:67
+msgid "editors_reviews_in_reply_to"
+msgstr "Σε απάντηση του:"
+
+#: controllers/editors_controller.php:748
+msgid "editors_reviews_processed"
+msgstr "Οι αξιολογήσεις επεξεÏγάστηκαν με επιτυχία!"
+
+#: views/editors/reviews_queue.thtml:117
+msgid "editors_reviews_queue_empty"
+msgstr "Δεν υπάÏχουν αξιολογήσεις για έλεγχο Ï€Ïος το παÏόν."
+
+#: views/editors/reviews_queue.thtml:111
+msgid "editors_reviews_submit_process_reviews"
+msgstr "ΕπεξεÏγασία αξιολογήσεων"
+
+#: controllers/editors_controller.php:691
+msgid "editors_site_specific"
+msgstr "Συσχετιζόμενο με ιστοχώÏο"
+
+#: controllers/editors_controller.php:348
+msgid "editors_tested_app"
+msgstr "Ελεγμένη εφαÏμογή"
+
+#: controllers/editors_controller.php:347
+msgid "editors_tested_os"
+msgstr "Ελεγμένο λειτουÏγικό σÏστημα"
+
+#: views/editors/queue.thtml:151
+msgid "editors_th_additional_info"
+msgstr "ΠÏόσθετες πληÏοφοÏίες"
+
+#: views/editors/featured.thtml:63
+#: views/editors/queue.thtml:109
+#: views/admin/flagged_queue.thtml:53
+msgid "editors_th_addon"
+msgstr "ΠÏόσθετο"
+
+#: views/editors/queue.thtml:125
+msgid "editors_th_addontype"
+msgstr "ΤÏπος"
+
+#: views/editors/featured.thtml:64
+msgid "editors_th_locales"
+msgstr "ΠεÏιοÏισμός γλωσσών;"
+
+#: views/editors/queue.thtml:148
+msgid "editors_th_nomination_age"
+msgstr "ΧÏόνος αναμονής"
+
+#: views/editors/queue.thtml:101
+#: views/editors/queue.thtml:117
+#: views/editors/queue.thtml:144
+msgid "editors_th_sort_ascending"
+msgstr "ΑÏξουσα ταξινόμηση"
+
+#: views/editors/queue.thtml:105
+#: views/editors/queue.thtml:121
+#: views/editors/queue.thtml:140
+msgid "editors_th_sort_descending"
+msgstr "Φθίνουσα ταξινόμηση"
+
+#. %s is a number
+#: controllers/editors_controller.php:1036
+#, php-format
+msgid "editors_x_days"
+msgstr "%s ημέÏες"
+
+#. %s is a number
+#: controllers/editors_controller.php:1044
+#, php-format
+msgid "editors_x_hours"
+msgstr "%s ÏŽÏες"
+
+#. %s is a number
+#: controllers/editors_controller.php:1052
+#, php-format
+msgid "editors_x_minutes"
+msgstr "%s λεπτά"
+
+#: views/errors/error401.thtml:50
+#: controllers/components/simple_acl.php:81
+#: controllers/components/simple_acl.php:82
+#: controllers/components/simple_acl.php:83
+#: controllers/components/amo.php:607
+#: controllers/components/amo.php:608
+#: controllers/components/amo.php:609
+#: controllers/reviews_controller.php:353
+#: controllers/reviews_controller.php:485
+#: controllers/collections_controller.php:438
+#: controllers/collections_controller.php:496
+#: controllers/collections_controller.php:504
+#: controllers/collections_controller.php:971
+#: controllers/collections_controller.php:1034
+#: controllers/collections_controller.php:1077
+msgid "error_access_denied"
+msgstr "ΑπαγοÏεÏεται η Ï€Ïόσβαση"
+
+#: views/errors/error401.thtml:52
+msgid "error_access_denied_message"
+msgstr "Δεν είστε εξουσιοδοτημένος να δείτε αυτή τη σελίδα."
+
+#: controllers/collections_controller.php:1039
+msgid "error_addon_exists"
+msgstr "Το Ï€Ïόσθετο υπάÏχει ήδη!"
+
+#: controllers/developers_controller.php:200
+#: controllers/developers_controller.php:593
+#: controllers/developers_controller.php:1016
+#: controllers/developers_controller.php:1429
+#: controllers/downloads_controller.php:95
+#: controllers/downloads_controller.php:102
+#: controllers/downloads_controller.php:164
+#: controllers/statistics_controller.php:135
+#: controllers/previews_controller.php:115
+#: controllers/previews_controller.php:206
+#: controllers/previews_controller.php:307
+#: controllers/reviews_controller.php:77
+#: controllers/reviews_controller.php:240
+#: controllers/reviews_controller.php:332
+#: controllers/reviews_controller.php:340
+#: controllers/api_controller.php:123
+#: controllers/api_controller.php:759
+#: controllers/addons_controller.php:131
+#: controllers/addons_controller.php:197
+#: controllers/addons_controller.php:1407
+#: controllers/addons_controller.php:1465
+#: controllers/addons_controller.php:1469
+#: controllers/addons_controller.php:1503
+#: controllers/editors_controller.php:265
+#: controllers/collections_controller.php:1041
+#: controllers/collections_controller.php:1074
+msgid "error_addon_notfound"
+msgstr "Δε βÏέθηκε το Ï€Ïόσθετο!"
+
+#: controllers/files_controller.php:83
+#: controllers/files_controller.php:196
+msgid "error_addon_notviewable"
+msgstr "Δεν μποÏεί να εμφανιστεί εδώ αυτό το Ï€Ïόσθετο."
+
+#: controllers/reviews_controller.php:246
+msgid "error_addon_selfreview"
+msgstr "Δεν επιτÏέπεται να αξιολογήσετε το Ï€Ïόσθετο σας."
+
+#: controllers/addons_controller.php:970
+msgid "error_browse_no_addons"
+msgstr "Δεν υπάÏχουν Ï€Ïόσθετα σε αυτή την κατηγοÏία!"
+
+#: controllers/api_controller.php:424
+msgid "error_collection_feed_notfound"
+msgstr "Δεν βÏέθηκε το αÏχείο Ïοής του Ï€Ïόσθετου"
+
+#: views/users/register.thtml:65
+#: views/users/edit.thtml:194
+msgid "error_email_invalid"
+msgstr "Δεν είναι έγκυÏη η διεÏθυνση ηλεκτÏÎ¿Î½Î¹ÎºÎ¿Ï Ï„Î±Ï‡Ï…Î´Ïομείου."
+
+#: views/users/pwreset.thtml:74
+#: views/users/register.thtml:70
+#: views/users/register.thtml:80
+#: views/users/register.thtml:86
+#: views/users/edit.thtml:105
+#: views/users/edit.thtml:111
+#: views/users/edit.thtml:192
+#: views/admin/users_edit.thtml:78
+#: views/admin/users_edit.thtml:83
+#: views/reviews/add.thtml:80
+#: views/reviews/add.thtml:104
+msgid "error_field_required"
+msgstr "Δεν επιτÏέπεται να είναι κενό το πεδίο."
+
+#: controllers/files_controller.php:75
+#: controllers/files_controller.php:93
+#: controllers/files_controller.php:96
+#: controllers/files_controller.php:163
+#: controllers/files_controller.php:176
+#: controllers/files_controller.php:185
+#: controllers/files_controller.php:204
+#: controllers/editors_controller.php:412
+msgid "error_file_notfound"
+msgstr "Δε βÏέθηκε το αÏχείο!"
+
+#. %s is a filename
+#: controllers/editors_controller.php:430
+#, php-format
+msgid "error_file_x_notfound"
+msgstr "Σφάλμα αÏχείου: δεν υπάÏχει το %s."
+
+#: views/collections/add.thtml:55
+#: views/collections/edit.thtml:89
+#: views/users/register.thtml:54
+#: views/users/edit.thtml:81
+#: views/reviews/add.thtml:70
+#: controllers/groups_controller.php:80
+#: controllers/groups_controller.php:102
+msgid "error_formerrors"
+msgstr "Εντοπίστηκαν σφάλματα στη φόÏμα. ΠαÏακαλοÏμε διοÏθώστε τα και υποβάλετέ την ξανά."
+
+#: views/users/register.thtml:109
+msgid "error_invalid_captcha"
+msgstr "Λάθος λέξη, παÏακαλοÏμε Ï€Ïοσπαθήστε ξανά!"
+
+#: views/users/register.thtml:100
+#: views/users/edit.thtml:125
+#: views/admin/users_edit.thtml:101
+msgid "error_invalid_url"
+msgstr "Αυτό το URL έχει μη έγκυÏη μοÏφή. Τα έγκυÏα URL έχουν τη μοÏφή http://example.com/my_page."
+
+#. %s is a string representing what's missing. Example: file_id
+#: controllers/downloads_controller.php:65
+#: controllers/users_controller.php:185
+#: controllers/users_controller.php:264
+#: controllers/users_controller.php:559
+#: controllers/users_controller.php:653
+#: controllers/reviews_controller.php:71
+#: controllers/reviews_controller.php:234
+#: controllers/reviews_controller.php:325
+#: controllers/reviews_controller.php:473
+#: controllers/reviews_controller.php:475
+#: controllers/addons_controller.php:182
+#: controllers/addons_controller.php:1381
+#: controllers/addons_controller.php:1455
+#: controllers/collections_controller.php:266
+#: controllers/collections_controller.php:285
+#: controllers/collections_controller.php:346
+#: controllers/collections_controller.php:443
+#: controllers/collections_controller.php:482
+#: controllers/collections_controller.php:936
+#: controllers/collections_controller.php:959
+#: controllers/collections_controller.php:960
+#: controllers/collections_controller.php:975
+#: controllers/collections_controller.php:977
+#: controllers/collections_controller.php:994
+#: controllers/collections_controller.php:1003
+#: controllers/collections_controller.php:1016
+#: controllers/collections_controller.php:1017
+#: controllers/collections_controller.php:1024
+#: controllers/collections_controller.php:1070
+#: controllers/collections_controller.php:1090
+#, php-format
+msgid "error_missing_argument"
+msgstr "Λείπει το ÏŒÏισμα: %s"
+
+#: controllers/components/amo.php:507
+#: controllers/components/amo.php:532
+msgid "error_no_files_in_addon"
+msgstr "Δεν πεÏιέχει αÏχεία"
+
+#: controllers/previews_controller.php:200
+msgid "error_preview_notfound"
+msgstr "Δε βÏέθηκε στιγμιότυπο!"
+
+#: views/addons/display.thtml:400
+#: views/reviews/add.thtml:98
+msgid "error_review_rating_required"
+msgstr "ΠÏέπει να επιλέξετε βαθμολογία."
+
+#: controllers/users_controller.php:160
+msgid "error_user_already_confirmed"
+msgstr "Ο λογαÏιασμός χÏήστη έχει ήδη επιβεβαιωθεί."
+
+#: controllers/users_controller.php:202
+#: controllers/users_controller.php:276
+#: controllers/users_controller.php:569
+#: controllers/users_controller.php:581
+#: controllers/users_controller.php:587
+#: controllers/users_controller.php:610
+#: controllers/users_controller.php:627
+msgid "error_user_badconfirmationcode"
+msgstr "Μη έγκυÏος κωδικός επιβεβαίωσης!"
+
+#: views/users/pwreset.thtml:79
+#: views/users/register.thtml:75
+#: views/users/edit.thtml:183
+msgid "error_user_confirmpw_nomatch"
+msgstr "Δεν ταιÏιάζουν οι κωδικοί."
+
+#: views/users/register.thtml:65
+#: views/users/edit.thtml:190
+#: controllers/users_controller.php:617
+msgid "error_user_email_notunique"
+msgstr "Αυτή η διεÏθυνση ηλεκτÏÎ¿Î½Î¹ÎºÎ¿Ï Ï„Î±Ï‡Ï…Î´Ïομείου χÏησιμοποιείται ήδη από άλλο χÏήστη."
+
+#: controllers/users_controller.php:596
+msgid "error_user_emailchange_expired"
+msgstr "Ο χÏόνος για αλλαγή διεÏθυνσης ηλεκτÏÎ¿Î½Î¹ÎºÎ¿Ï Ï„Î±Ï‡Ï…Î´Ïομείου έχει λήξει. ΠαÏακαλοÏμε αλλάξτε ξανά τη διεÏθυνση στο Ï€Ïοφίλ χÏήστη και κάντε κλικ στο δεσμό που θα βÏείτε στο μήνυμα επιβεβαίωσης μόλις το παÏαλάβετε."
+
+#: controllers/collections_controller.php:985
+msgid "error_user_exists"
+msgstr "Οι χÏήστες μποÏοÏν να έχουν μόνο ένα Ïόλο κάθε φοÏά. ΠαÏακαλοÏμε αφαιÏέστε οποιοδήποτε άλλο Ïόλο από το χÏήστη Ï€Ïιν συνεχίσετε."
+
+#: views/users/register.thtml:91
+#: views/users/edit.thtml:116
+#: views/admin/users_edit.thtml:88
+msgid "error_user_nickname_notunique"
+msgstr "Το ψευδώνυμο υπάÏχει ήδη."
+
+#: views/users/pwreset.thtml:54
+#: controllers/users_controller.php:191
+#: controllers/users_controller.php:270
+#: controllers/users_controller.php:603
+#: controllers/users_controller.php:659
+#: controllers/collections_controller.php:988
+#: controllers/collections_controller.php:998
+msgid "error_user_notfound"
+msgstr "Δε βÏέθηκε ο χÏήστης!"
+
+#: views/users/activatefirst.thtml:47
+msgid "error_user_unconfirmed"
+msgstr "ΠαÏακαλοÏμε επιβεβαιώστε Ï€Ïώτα το λογαÏιασμό χÏήστη με τον κωδικό που παÏαλάβατε μέσω ηλεκτÏÎ¿Î½Î¹ÎºÎ¿Ï Ï„Î±Ï‡Ï…Î´Ïομείου."
+
+#: views/users/login.thtml:67
+msgid "error_username_or_pw_wrong"
+msgstr "Λάθος όνομα χÏήστη ή κωδικός!"
+
+#: controllers/editors_controller.php:260
+msgid "error_version_notfound"
+msgstr "Δε βÏέθηκε η έκδοση!"
+
+#: views/users/delete.thtml:125
+#: views/users/edit.thtml:173
+msgid "error_wrong_password"
+msgstr "Έχετε εισάγει λάθος κωδικό!"
+
+#: views/elements/amo2009/homepage_addon.thtml:122
+#: views/elements/feature.thtml:122
+msgid "feature_learnmore"
+msgstr "Μάθετε πεÏισσότεÏα"
+
+# %1 is the add-on name
+#. %1 is the add-on name
+#: views/elements/amo2009/homepage_addon.thtml:123
+#: views/elements/feature.thtml:123
+#, php-format
+msgid "feature_learnmore_about_addon"
+msgstr "Μάθετε πεÏισσότεÏα για το %1$s"
+
+#. %1$s is a number
+#: views/elements/amo2009/reviews.thtml:52
+#: views/elements/addon_listitem.thtml:112
+#: views/elements/feature.thtml:99
+#: views/addons/browse_thumbs.thtml:86
+#, php-format
+msgid "feature_reviews"
+msgid_plural "feature_reviews"
+msgstr[0] "%1$s αξιολόγηση"
+msgstr[1] "%1$s αξιολογήσεις"
+
+#: views/elements/amo2009/homepage_addon.thtml:127
+#: views/elements/feature.thtml:127
+msgid "feature_view_more_from_category"
+msgstr "Δείτε πεÏισσότεÏα από"
+
+#. This appears on a page that views the source of an add-on. This link will return
+#. the user to the add-on's main page
+#: views/files/browse.thtml:65
+msgid "file_browser_link_addon"
+msgstr "Πίσω στο Ï€Ïόσθετο"
+
+#. There is a list of directories and files on the page. Clicking this will show the
+#. contents of all the directories (normally you would click on each one to see the
+#. contents)
+#: views/files/browse.thtml:67
+msgid "file_browser_link_expand_all"
+msgstr "Ανάπτυξη όλων"
+
+#. This appears on a page that views the source of an add-on. This link will return
+#. the user to the add-on's review page (it only appears if the add-on is being
+#. reviewed)
+#: views/files/browse.thtml:64
+msgid "file_browser_link_review"
+msgstr "Πίσω στην αξιολόγηση"
+
+#. The title of the page for viewing an add-on's source.
+#. %1$s is the name of the add-on
+#. %2$s is the name of the current application (e.g. Firefox or Thunderbird)
+#: views/files/browse.thtml:46
+msgid "file_browser_title"
+msgstr "%1$s :: ΠεÏιήγηση αÏχείων :: ΠÏόσθετα %2$s"
+
+#. This appears on a page that views the source of an add-on. There is a list of
+#. directories and files on the page. Clicking this link will toggle between an
+#. expanded or a collapsed list. This string should be kept short.
+#: views/files/browse.thtml:68
+msgid "file_browser_toggle_expand_collapse"
+msgstr "+/-"
+
+#. Link text for the AMO About page.
+#: views/elements/footer.thtml:72
+#: views/layouts/amo2009.thtml:341
+msgid "footer_a_about"
+msgstr "ΠεÏί"
+
+#. Link text to the AMO blog.
+#: views/elements/footer.thtml:74
+#: views/layouts/amo2009.thtml:343
+msgid "footer_a_blog"
+msgstr "Ιστολόγιο"
+
+#. Link text to the Frequently Asked Questions page.
+#: views/elements/footer.thtml:73
+#: views/layouts/amo2009.thtml:342
+msgid "footer_a_faq"
+msgstr "Σ. Ε."
+
+#. Full text for the FAQ abbreviation.
+#: views/elements/footer.thtml:73
+#: views/pages/collector_features.thtml:72
+#: views/layouts/amo2009.thtml:342
+msgid "footer_abbr_faq"
+msgstr "Συχνές εÏωτήσεις"
+
+#: views/elements/footer.thtml:67
+#: views/layouts/amo2009.thtml:336
+msgid "footer_all_rights_reserved"
+msgstr "Με την επιφÏλαξη παντός δικαιώματος."
+
+#: views/elements/footer.thtml:67
+#: views/layouts/amo2009.thtml:336
+msgid "footer_copyright"
+msgstr "Copyright"
+
+#: views/elements/footer.thtml:71
+#: views/layouts/amo2009.thtml:340
+msgid "footer_credits"
+msgstr "Μνεία"
+
+#: views/elements/footer.thtml:76
+#: views/layouts/amo2009.thtml:346
+msgid "footer_disclaimer"
+msgstr "Ο οÏγανισμός Mozilla παÏέχει τους δεσμοÏÏ‚ αυτοÏÏ‚ σαν μια Ï€Ïόσθετη υπηÏεσία και δεν αντιπÏοσωπεÏει τις εφαÏμογές ή οποιαδήποτε πληÏοφοÏία σχετικά με αυτές. Οποιαδήποτε εÏώτηση, παÏάπονο ή ισχυÏισμός σχετικά με τις εφαÏμογές θα Ï€Ïέπει να απευθÏνεται στον αντίστοιχο κατασκευαστή λογισμικοÏ."
+
+#: views/elements/footer.thtml:61
+#: views/layouts/amo2009.thtml:332
+msgid "footer_lang_form_lang_submit_go"
+msgstr "Αλλαγή"
+
+#: views/elements/footer.thtml:70
+#: views/layouts/amo2009.thtml:339
+msgid "footer_legal_notices"
+msgstr "Îομικές σημειώσεις"
+
+#: views/elements/footer.thtml:50
+#: views/layouts/amo2009.thtml:321
+msgid "footer_other_languages"
+msgstr "Άλλες γλώσσες:"
+
+#: views/elements/footer.thtml:69
+#: views/layouts/amo2009.thtml:338
+msgid "footer_privacy_policy"
+msgstr "Πολιτική αποÏÏήτου"
+
+#: models/addontype.php:79
+msgid "general_addontype_dict"
+msgstr "Λεξικό"
+
+# Plural in this context means many of the add-on type
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:100
+msgid "general_addontype_dict_plural"
+msgstr "Λεξικά"
+
+#: models/addontype.php:75
+msgid "general_addontype_extension"
+msgstr "Επέκταση"
+
+# Plural in this context means many of the add-on type
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:98
+msgid "general_addontype_extension_plural"
+msgstr "Επεκτάσεις"
+
+#: models/addontype.php:85
+msgid "general_addontype_lpaddon"
+msgstr "Πακέτο γλώσσας (Ï€Ïόσθετου)"
+
+# Plural in this context means many of the add-on type
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:103
+msgid "general_addontype_lpaddon_plural"
+msgstr "Πακέτα γλώσσας (Ï€Ïόσθετου)"
+
+#: models/addontype.php:83
+msgid "general_addontype_lpapp"
+msgstr "Πακέτο γλώσσας (εφαÏμογής)"
+
+# Plural in this context means many of the add-on type
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:102
+msgid "general_addontype_lpapp_plural"
+msgstr "Πακέτα γλώσσας (εφαÏμογής)"
+
+#: models/addontype.php:87
+msgid "general_addontype_plugin"
+msgstr "ΠÏόσθετη λειτουÏγία"
+
+# Plural in this context means many of the add-on type
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:104
+msgid "general_addontype_plugin_plural"
+msgstr "ΠÏόσθετες λειτουÏγίες"
+
+#: models/addontype.php:81
+msgid "general_addontype_search"
+msgstr "Μηχανή αναζήτησης"
+
+# Plural in this context means many of the add-on type
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:101
+msgid "general_addontype_search_plural"
+msgstr "Μηχανές αναζήτησης"
+
+#: models/addontype.php:77
+msgid "general_addontype_theme"
+msgstr "Θέμα"
+
+# Plural in this context means many of the add-on type
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:99
+msgid "general_addontype_theme_plural"
+msgstr "Θέματα"
+
+#: config/language.php:367
+msgid "general_languages_all_locales"
+msgstr "Όλες οι γλώσσες"
+
+#: views/layouts/amo2009.thtml:249
+msgid "header_brand_name"
+msgstr "Mozilla"
+
+#. %1$s is the application name. Example: Firefox
+#: views/elements/header.thtml:111
+#: views/elements/header.thtml:122
+#: views/layouts/amo2009.thtml:248
+#, php-format
+msgid "header_home_tooltip"
+msgstr "ΕπιστÏοφή στην αÏχική σελίδα των Ï€Ïόσθετων του %1$s"
+
+#: views/elements/header.thtml:87
+msgid "header_main_firefox_header"
+msgstr "ΠÏόσθετα Firefox"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:218
+msgid "header_main_firefox_header_with_logo"
+msgstr "ΠÏόσθετα <em>για τον</em> <img alt=\"Firefox\" src=\"%1$s\" /> <strong>Firefox</strong>"
+
+#: views/elements/header.thtml:99
+msgid "header_main_header"
+msgstr "ΠÏόσθετα"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:242
+msgid "header_main_header_with_logo"
+msgstr "ΠÏόσθετα <img alt=\"Add-ons\" src=\"%1$s\" />"
+
+#: views/elements/header.thtml:90
+msgid "header_main_seamonkey_header"
+msgstr "ΠÏόσθετα Seamonkey"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:224
+msgid "header_main_seamonkey_header_with_logo"
+msgstr "ΠÏόσθετα <em>για τον</em> <img alt=\"seamonkey\" src=\"%1$s\" /> <strong>SeaMonkey</strong>"
+
+#: views/elements/header.thtml:93
+msgid "header_main_sunbird_header"
+msgstr "ΠÏόσθετα Sunbird"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:230
+msgid "header_main_sunbird_header_with_logo"
+msgstr "ΠÏόσθετα <em>για τον</em> <img alt=\"sunbird\" src=\"%1$s\" /> <strong>Sunbird</strong>"
+
+#: views/elements/header.thtml:96
+msgid "header_main_thunderbird_header"
+msgstr "ΠÏόσθετα Thunderbird"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:236
+msgid "header_main_thunderbird_header_with_logo"
+msgstr "ΠÏόσθετα <em>για τον</em> <img alt=\"thunderbird\" src=\"%1$s\" /> <strong>Thunderbird</strong>"
+
+#: views/layouts/amo2009.thtml:205
+msgid "header_navaccess_applications_menu"
+msgstr "Μετάβαση στο Î¼ÎµÎ½Î¿Ï Ï€ÏογÏαμμάτων"
+
+#: views/layouts/amo2009.thtml:204
+msgid "header_navaccess_categories_menu"
+msgstr "Μετάβαση στο Î¼ÎµÎ½Î¿Ï ÎºÎ±Ï„Î·Î³Î¿Ïιών"
+
+#: views/layouts/amo2009.thtml:202
+msgid "header_navaccess_main_content"
+msgstr "Μετάβαση στο κεντÏικό πεÏιεχόμενο"
+
+#: views/layouts/amo2009.thtml:203
+msgid "header_navaccess_search_form"
+msgstr "Μετάβαση στη φόÏμα αναζήτησης"
+
+#: views/elements/header.thtml:62
+msgid "header_navlink_addons"
+msgstr "ΠÏόσθετα"
+
+#: views/elements/developers/sidebar.thtml:72
+#: views/elements/developers/myaddons.thtml:50
+#: views/elements/header.thtml:159
+#: views/addons/display.thtml:378
+msgid "header_navlink_login"
+msgstr "ΣÏνδεση"
+
+#: views/elements/header.thtml:156
+#: views/layouts/amo2009.thtml:304
+msgid "header_navlink_logout"
+msgstr "ΑποσÏνδεση"
+
+#: views/elements/header.thtml:145
+#: views/layouts/amo2009.thtml:303
+msgid "header_navlink_myaccount"
+msgstr "Ο λογαÏιασμός μου"
+
+#: views/elements/header.thtml:158
+msgid "header_navlink_register"
+msgstr "ΕγγÏαφή"
+
+#. %1 is the URL to the registration page
+#. %2 is the URL to the login page
+#: views/layouts/amo2009.thtml:278
+msgid "header_navlink_register_or_login"
+msgstr "<a href=\"%1$s\">ΕγγÏαφείτε</a> ή <a href=\"%2$s\">συνδεθείτε</a>"
+
+#: views/layouts/amo2009.thtml:285
+msgid "header_navlink_tools"
+msgstr "ΕÏγαλεία"
+
+#. %s is the add-on name
+#: views/elements/collections_interactive_addon.thtml:62
+#: views/elements/amo2009/homepage_addon.thtml:77
+#: views/elements/addon_discussionheader.thtml:62
+#: views/elements/addon_listitem.thtml:67
+#: views/elements/feature.thtml:84
+#: views/addons/category_landing.thtml:87
+#: views/addons/browse_thumbs.thtml:60
+#, php-format
+msgid "img_preview_of"
+msgstr "Εικόνα Ï€Ïοεπισκόπησης του %s"
+
+# %1 is the login URL for the link tag
+#. %1 is the login URL for the link tag
+#. %2 is the link to an explanatory page.
+#: views/elements/amo2009/install.thtml:307
+#: views/elements/install.thtml:255
+msgid "install_a_login_to_install"
+msgstr "<a href=\"%1$s\">Συνδεθείτε</a> για να εγκαταστήσετε αυτό το Ï€Ïόσθετο. <a href=\"%2$s\">Ποιος ο λόγος</a>;"
+
+#. %1 is the URL for the Experimental Add-ons section of the FAQ page
+#: views/elements/amo2009/install.thtml:283
+#: views/elements/install.thtml:232
+msgid "install_button_confirm_exp_install"
+msgstr "Îα επιτÏαπεί η εγκατάσταση Î±Ï…Ï„Î¿Ï Ï„Î¿Ï… πειÏÎ±Î¼Î±Ï„Î¹ÎºÎ¿Ï Ï€Ïόσθετου. <a href=\"%1$s\">Τι είναι αυτό;</a>"
+
+#. %1$s is the application name. Example: Firefox
+#. %2$s is an optional string used to specify a platform. Example: (Windows)
+#: views/elements/amo2009/install.thtml:128
+#: views/elements/install.thtml:75
+#, php-format
+msgid "install_button_text"
+msgstr "ΠÏοσθήκη στον %s %s"
+
+# %1 is the add-on name, %2 is the app name
+#. %1 is the add-on name, %2 is the app name
+#: views/elements/amo2009/install.thtml:191
+#: views/elements/amo2009/install.thtml:206
+#: views/elements/amo2009/install.thtml:249
+#: views/elements/amo2009/install.thtml:298
+#: views/elements/install.thtml:150
+#: views/elements/install.thtml:165
+#: views/elements/install.thtml:202
+#: views/elements/install.thtml:246
+#, php-format
+msgid "install_button_title"
+msgstr "ΠÏοσθήκη του %1$s στο %2$s"
+
+#. %1$s is the add-on name
+#: views/elements/amo2009/install.thtml:200
+#: views/elements/install.thtml:159
+#, php-format
+msgid "install_download"
+msgstr "Λήψη %1$s"
+
+#: views/elements/amo2009/install.thtml:147
+#: views/elements/install.thtml:94
+msgid "install_error_addon_not_found"
+msgstr "Δεν είναι διαθέσιμο αυτό το Ï€Ïόσθετο."
+
+#: views/addons/dictionaries.thtml:65
+msgid "langtools_a11y_tablesummary"
+msgstr "Λίστα πακέτων γλωσσών και λεξικών.."
+
+#: views/addons/dictionaries.thtml:47
+msgid "langtools_download_dictionary"
+msgstr "Λήψη λεξικοÏ"
+
+#: views/addons/dictionaries.thtml:48
+msgid "langtools_download_langpack"
+msgstr "Λήψη πακέτου γλώσσας"
+
+#: views/addons/dictionaries.thtml:63
+#: controllers/components/amo.php:685
+#: controllers/addons_controller.php:1239
+msgid "langtools_header_dicts_and_langpacks"
+msgstr "Λεξικά & πακέτα γλώσσας"
+
+#: views/addons/dictionaries.thtml:44
+msgid "langtools_install_dictionary"
+msgstr "Εγκατάσταση λεξικοÏ"
+
+#: views/addons/dictionaries.thtml:45
+msgid "langtools_install_langpack"
+msgstr "Εγκατάσταση πακέτου γλώσσας"
+
+#: views/addons/dictionaries.thtml:69
+msgid "langtools_tableheader_dictionary"
+msgstr "Λεξικό"
+
+#: views/addons/dictionaries.thtml:70
+msgid "langtools_tableheader_langpack"
+msgstr "Πακέτο γλώσσας"
+
+#: views/addons/dictionaries.thtml:68
+msgid "langtools_tableheader_language"
+msgstr "Γλώσσα"
+
+#: models/license.php:65
+msgid "license_custom"
+msgstr "ΠÏοσαÏμοσμένη άδεια"
+
+#: config/bootstrap.php:303
+msgid "licenses_bsd"
+msgstr "Άδεια BSD"
+
+#: config/bootstrap.php:298
+msgid "licenses_gpl_2.0"
+msgstr "GNU General Public License, έκδοση 2.0"
+
+#: config/bootstrap.php:299
+msgid "licenses_gpl_3.0"
+msgstr "GNU General Public License, έκδοση 3.0"
+
+#: config/bootstrap.php:300
+msgid "licenses_lgpl_2.1"
+msgstr "GNU Lesser General Public License, έκδοση 2.1"
+
+#: config/bootstrap.php:301
+msgid "licenses_lgpl_3.0"
+msgstr "GNU Lesser General Public License, έκδοση 3.0"
+
+#: config/bootstrap.php:302
+msgid "licenses_mit"
+msgstr "Άδεια MIT/X11"
+
+#: config/bootstrap.php:297
+msgid "licenses_mpl_1.1"
+msgstr "Mozilla Public License, έκδοση 1.1"
+
+#: views/users/emailchange.thtml:51
+#: views/users/delete.thtml:55
+#: views/users/delete.thtml:137
+#: views/users/edit.thtml:74
+#: views/reviews/flag.thtml:54
+msgid "link_return_to_front_page"
+msgstr "Κάντε κλικ εδώ για επιστÏοφή στην αÏχική σελίδα."
+
+#: views/elements/amo2009/addon_list_options.thtml:46
+#: views/elements/addon_list_options.thtml:46
+msgid "list_sortby_date"
+msgstr "ΗμεÏομηνία"
+
+#: views/elements/amo2009/addon_list_options.thtml:47
+#: views/elements/addon_list_options.thtml:47
+msgid "list_sortby_downloads"
+msgstr "Λήψεις"
+
+#: views/elements/amo2009/addon_list_options.thtml:45
+#: views/elements/addon_list_options.thtml:45
+msgid "list_sortby_name"
+msgstr "Όνομα Ï€Ïόσθετου"
+
+#: views/elements/amo2009/addon_list_options.thtml:48
+#: views/elements/addon_list_options.thtml:48
+msgid "list_sortby_rating"
+msgstr "Βαθμολογία"
+
+#: config/bootstrap.php:278
+msgid "main_prettyname_fennec"
+msgstr "Fennec"
+
+#: config/bootstrap.php:274
+msgid "main_prettyname_firefox"
+msgstr "Firefox"
+
+#: config/bootstrap.php:277
+msgid "main_prettyname_seamonkey"
+msgstr "SeaMonkey"
+
+#: config/bootstrap.php:276
+msgid "main_prettyname_sunbird"
+msgstr "Sunbird"
+
+#: config/bootstrap.php:275
+msgid "main_prettyname_thunderbird"
+msgstr "Thunderbird"
+
+#: views/elements/addon_categories.thtml:52
+msgid "nav_category_dicts_langpacks"
+msgstr "Λεξικά & πακέτα γλωσσών"
+
+#: views/elements/addon_categories.thtml:55
+msgid "nav_category_themes"
+msgstr "Θέματα"
+
+#: views/elements/app_chooser.thtml:47
+#: views/layouts/amo2009.thtml:255
+msgid "other_apps_tooltip"
+msgstr "Αναζήτηση Ï€Ïόσθετων για άλλα Ï€ÏογÏάμματα"
+
+# In a user list: user 1, user 2, "others"
+#. In a user list: user 1, user 2, "others"
+#: views/helpers/addons_html.php:222
+msgid "other_users"
+msgstr "άλλα"
+
+#: controllers/pages_controller.php:90
+msgid "page_title_appversions"
+msgstr "Εκδόσεις εφαÏμογών"
+
+#: controllers/pages_controller.php:115
+msgid "page_title_collector"
+msgstr "Add-on Collector"
+
+#: controllers/pages_controller.php:117
+msgid "page_title_collector_faq"
+msgstr "Συχνές εÏωτήσεις Add-on Collector"
+
+#: controllers/pages_controller.php:119
+msgid "page_title_collector_features"
+msgstr "ΧαÏακτηÏιστικά Add-on Collector"
+
+#: controllers/pages_controller.php:122
+msgid "page_title_collector_firstrun"
+msgstr "ΚαλωσοÏίσατε στο Add-on Collector"
+
+#: controllers/pages_controller.php:92
+msgid "page_title_credits"
+msgstr "Μνεία"
+
+#: controllers/pages_controller.php:113
+msgid "page_title_developer_faq"
+msgstr "Συχνές εÏωτήσεις δημιουÏγών"
+
+#: controllers/pages_controller.php:111
+msgid "page_title_faq"
+msgstr "Συχνές εÏωτήσεις"
+
+#: controllers/pages_controller.php:94
+msgid "page_title_fashionyourfirefox_faq"
+msgstr "Συχνές εÏωτήσεις για το «ÎÏ„Ïστε τον Firefox»"
+
+#: controllers/pages_controller.php:101
+msgid "page_title_policy"
+msgstr "Πολιτική Ï€Ïόσθετων"
+
+#: controllers/pages_controller.php:103
+msgid "page_title_privacy"
+msgstr "Πολιτική αποÏÏήτου Mozilla"
+
+#: controllers/pages_controller.php:105
+msgid "page_title_review_guide"
+msgstr "Οδηγίες σÏνταξης αξιολόγησης"
+
+#: controllers/pages_controller.php:107
+msgid "page_title_sandbox"
+msgstr "ΣÏστημα αξιολογήσεων Sandbox"
+
+#: controllers/pages_controller.php:109
+msgid "page_title_submissionhelp"
+msgstr "Βοήθεια υποβολής"
+
+#: views/pages/appversions.thtml:87
+msgid "pages_appversions_guid"
+msgstr "GUID"
+
+#: views/pages/appversions.thtml:79
+#: controllers/pages_controller.php:90
+msgid "pages_appversions_header"
+msgstr "ΈγκυÏες εκδόσεις εφαÏμογής"
+
+#: views/pages/appversions.thtml:80
+msgid "pages_appversions_intro"
+msgstr "Τα Ï€Ïόσθετα που υποβάλλετε στο Mozilla Add-ons θα Ï€Ïέπει να έχουν ένα αÏχείο install.rdf που θα υποστηÏίζει τουλάχιστον μια από τις παÏακάτω εφαÏμογές. Μόνο οι εκδόσεις που παÏαθέτουμε παÏακάτω επιτÏέπονται γι' αυτές τις εφαÏμογές."
+
+#. %s is a full <a> tag
+#: views/pages/appversions.thtml:93
+#, php-format
+msgid "pages_appversions_required_files"
+msgstr "Ακόμα και αν η εφαÏμογή που υποστηÏίζεται από το Ï€Ïότυπό σας δεν απαιτεί αÏχείο install.rdf, θα Ï€Ïέπει να συμπεÏιλάβετε ένα με τις απαιτοÏμενες Ïυθμίσεις όπως αυτές πεÏιγÏάφονται %s."
+
+#. this is the text inside of an <a> tag for pages_appversions_required_files. This
+#. should be fixed.
+#: views/pages/appversions.thtml:93
+msgid "pages_appversions_required_files_link"
+msgstr "εδώ"
+
+#: views/pages/appversions.thtml:88
+msgid "pages_appversions_versions"
+msgstr "Εκδόσεις"
+
+#: views/pages/policy.thtml:51
+msgid "pages_policy_sandbox_link"
+msgstr "Σελίδα πληÏοφοÏιών για το Sandbox"
+
+#: views/elements/pagination.thtml:53
+msgid "pagination_next_page"
+msgstr "επόμενη"
+
+#: views/elements/pagination.thtml:52
+msgid "pagination_previous_page"
+msgstr "Ï€ÏοηγοÏμενη"
+
+#: views/elements/recaptcha.thtml:65
+msgid "recaptcha_enter_both_words"
+msgstr "ΠαÏακαλοÏμε εισάγετε <strong>και τις δÏο λέξεις</strong> παÏακάτω, <strong>διαχωÏίζοντας τις με ένα κενό διάστημα</strong>."
+
+#: views/elements/recaptcha.thtml:83
+msgid "recaptcha_enter_here"
+msgstr "Εισάγετε την απάντηση σας εδώ:"
+
+#: views/elements/recaptcha.thtml:74
+msgid "recaptcha_enter_whatyouhear"
+msgstr "ΠαÏακαλοÏμε πληκτÏολογήστε αυτό που ακοÏτε."
+
+# %1 is the link switching refreshing the captcha
+# %2 is the link switching to a text captcha
+#. %1 is the link switching refreshing the captcha
+#. %2 is the link switching to a text captcha
+#: views/elements/recaptcha.thtml:77
+msgid "recaptcha_hardtohear_text"
+msgstr "αν δεν μποÏείτε να καταλάβατε τι ακοÏτε, μποÏείτε να <a href=\"%1$s\">ακοÏσετε κάτι άλλο</a> ή<a href=\"%2$s\">να επιστÏέψετε στη μέθοδο με κείμενο</a>."
+
+# %1 is the link switching refreshing the captcha
+# %2 is the link switching to an audio captcha
+#. %1 is the link switching refreshing the captcha
+#. %2 is the link switching to an audio captcha
+#: views/elements/recaptcha.thtml:68
+msgid "recaptcha_hardtoread_text"
+msgstr "Αν δεν μποÏείτε να καταλάβετε τι γÏάφει, μποÏείτε να <a href=\"%1$s\">δοκιμάσετε διαφοÏετικές λέξεις</a> ή <a href=\"%2$s\">να ακοÏσετε κάτι</a>."
+
+#: views/users/register.thtml:105
+msgid "recaptcha_label"
+msgstr "Είστε άνθÏωπος;"
+
+#: views/users/register.thtml:106
+msgid "recaptcha_whatsthis"
+msgstr "Τι είναι αυτό;"
+
+#: controllers/reviews_controller.php:559
+msgid "review_flag_error"
+msgstr "ΠαÏουσιάστηκε σφάλμα κατά τη σημείωση της αξιολόγησης!"
+
+#: models/reviews_moderation_flag.php:69
+msgid "review_flag_reason_bug_support"
+msgstr "ΑναφοÏά σφάλματος ή αίτημα υποστήÏιξης αντί για αξιολόγηση."
+
+#: views/reviews/display.thtml:103
+#: views/reviews/display.thtml:186
+msgid "review_flag_reason_instructions"
+msgstr "ΑναφοÏά αξιολόγησης (επιλέξτε ένα λόγο)"
+
+#: models/reviews_moderation_flag.php:67
+msgid "review_flag_reason_language"
+msgstr "ΑνάÏμοστη διατÏπωση"
+
+#: models/reviews_moderation_flag.php:71
+msgid "review_flag_reason_other"
+msgstr "Άλλος (παÏακαλοÏμε εξηγήστε)"
+
+#: models/reviews_moderation_flag.php:65
+msgid "review_flag_reason_spam"
+msgstr "ΑνεπιθÏμητο ή άσχετο με την αξιολόγηση πεÏιεχόμενο."
+
+#: views/reviews/display.thtml:91
+#: views/reviews/display.thtml:175
+#: controllers/reviews_controller.php:555
+msgid "review_flag_success"
+msgstr "ΕυχαÏιστοÏμε, η αξιολόγηση έχει σημειωθεί για να εγκÏιθεί από τους συντάκτες μας."
+
+#: views/reviews/display.thtml:41
+msgid "review_flag_this"
+msgstr "ΑναφοÏά αξιολόγησης"
+
+#: views/reviews/display.thtml:42
+msgid "review_flag_this_titletip"
+msgstr "ΘεωÏείτε αυτή την αξιολόγηση ανάÏμοστη, μη ακÏιβή ή απλά άσχετη; Κάντε κλικ εδώ για να τη σημειώσετε ώστε να αξιολογηθεί από τους συντάκτες μας."
+
+# %1 is the URL of the support section, %2 for the review guidelines
+#. %1 is the URL of the support section, %2 for the review guidelines
+#: views/reviews/add.thtml:53
+msgid "review_guidelines_short"
+msgstr "<p>Έχετε υπόψη σας τα εξής:</p><ul><li>Συντάξτε την αξιολόγηση σας σα να διηγήστε την εμπειÏία σας με το Ï€Ïόσθετο σε ένα φίλο σας. Δώστε συγκεκÏιμένες και χÏήσιμες λεπτομέÏειες, όπως τα χαÏακτηÏιστικά που σας άÏεσαν και/ή δεν σας άÏεσαν, πόσο εÏκολη είναι η χÏήση του και αν έχει κάποια πιθανά μειονεκτήματα. ΑποφÏγετε γενικεÏσεις του Ï„Ïπου «ΦοβεÏό» ή «ΆχÏηστο», εκτός κι αν μποÏείτε να δικαιολογήσετε αυτή σας την άποψη.</li><li>ΠαÏακαλοÏμε μη δημοσιεÏετε αναφοÏές σφαλμάτων στις αξιολογήσεις. Οι δημιουÏγοί είναι πιθανό να χÏειαστεί να επικοινωνήσουν μαζί σας για να επιλυθεί το Ï€Ïόβλημα κι εμείς δεν τους γνωστοποιοÏμε τη διεÏθυνση του ηλεκτÏÎ¿Î½Î¹ÎºÎ¿Ï ÏƒÎ±Ï‚ ταχυδÏομείου.. Δείτε το <a href=\"%1$s\">τμήμα υποστήÏιξης</a> για να μάθετε που μποÏείτε να βÏείτε υποστήÏιξη για το Ï€Ïόσθετο.</li><li>Σας παÏακαλοÏμε να διατηÏείτε το επίπεδο των αξιολογήσεων και να αποφεÏγετε ακατάλληλες εκφÏάσεις και τη δημοσιοποίηση Ï€Ïοσωπικών σας πληÏοφοÏιών.</li></ul><p>Διαβάστε τις <a href=\"%2$s\">οδηγίες σÏνταξης αξιολόγησης</a> για πεÏισσότεÏες λεπτομέÏειες σχετικά με την υποβολή αξιολογήσεων από τους χÏήστες.</p>"
+
+#. %1 is the add-on name
+#: views/reviews/flag.thtml:56
+#: views/reviews/display.thtml:55
+#: views/reviews/review_added.thtml:50
+#, php-format
+msgid "reviews_header"
+msgstr "Αξιολογήσεις για %s"
+
+#: controllers/addons_controller.php:435
+msgid "rss_featuredaddons"
+msgstr "Συνιστώμενα Ï€Ïόσθετα"
+
+#: controllers/addons_controller.php:432
+msgid "rss_newestaddons"
+msgstr "ΠÏόσφατα Ï€Ïόσθετα"
+
+#: controllers/addons_controller.php:434
+msgid "rss_popularaddons"
+msgstr "Δημοφιλή Ï€Ïόσθετα"
+
+#: controllers/addons_controller.php:433
+msgid "rss_updatedaddons"
+msgstr "ΕνημεÏωμένα Ï€Ïόσθετα"
+
+#: views/elements/search_mini.thtml:70
+msgid "search"
+msgstr "Αναζήτηση"
+
+#: views/search/collections.thtml:51
+msgid "search_collections_header"
+msgstr "Αποτελέσματα αναζήτησης συλλογών"
+
+#: controllers/search_controller.php:297
+msgid "search_collections_pagetitle"
+msgstr "Αποτελέσματα αναζήτησης για συλλογές"
+
+#: controllers/search_controller.php:99
+msgid "search_disabled"
+msgstr "Η αναζήτηση είναι απενεÏγοποιημένη Ï€Ïος το παÏόν. ΠαÏακαλοÏμε Ï€Ïοσπαθήστε ξανά αÏγότεÏα."
+
+#: views/elements/amo2009/search.thtml:188
+#: views/elements/search.thtml:187
+#: views/elements/search_mini.thtml:54
+msgid "search_form_all_addons"
+msgstr "όλα τα Ï€Ïόσθετα"
+
+#. This string is in the main category dropdown when searching
+#: views/elements/amo2009/search.thtml:204
+msgid "search_form_all_collections"
+msgstr "όλες τις συλλογές"
+
+#: views/elements/amo2009/search.thtml:184
+#: views/elements/amo2009/search.thtml:385
+#: views/elements/amo2009/search.thtml:408
+#: views/elements/search.thtml:171
+#: views/elements/search.thtml:183
+#: views/elements/search_mini.thtml:43
+#: views/elements/search_mini.thtml:49
+#: views/layouts/mozilla.thtml:188
+msgid "search_form_default_text"
+msgstr "αναζήτηση για Ï€Ïόσθετα"
+
+#: views/elements/amo2009/search.thtml:184
+#: views/elements/amo2009/search.thtml:404
+msgid "search_form_default_text_collections"
+msgstr "αναζήτηση για συλλογές"
+
+#: views/elements/amo2009/search.thtml:206
+#: views/elements/search.thtml:202
+msgid "search_form_submit_tooltip"
+msgstr "Αναζήτηση για Ï€Ïόσθετα"
+
+#: views/elements/amo2009/search.thtml:184
+#: views/elements/search.thtml:183
+#: views/elements/search_mini.thtml:49
+msgid "search_form_tooltip"
+msgstr "Κάντε κλικ για να εισάγετε ÏŒÏους αναζήτησης"
+
+#: views/elements/amo2009/search.thtml:186
+#: views/elements/search.thtml:185
+#: views/elements/search_mini.thtml:52
+msgid "search_form_within"
+msgstr "σε"
+
+#: views/addons/searchengines.thtml:118
+msgid "search_landing_all_search_engines"
+msgstr "Όλες τις μηχανές αναζήτησης"
+
+#: views/addons/searchengines.thtml:114
+msgid "search_landing_browse_search_engines"
+msgstr "ΠεÏιήγηση στις μηχανές αναζήτησης"
+
+#: views/search/collections.thtml:58
+#: views/search/index.thtml:59
+msgid "search_nothing_found"
+msgstr "Δε βÏέθηκαν αποτελέσματα."
+
+#: controllers/search_controller.php:185
+msgid "search_pagetitle"
+msgstr "Αναζήτηση στα Ï€Ïόσθετα"
+
+#: controllers/search_controller.php:242
+msgid "search_rss_description"
+msgstr "ΑÏχείο Ïοής αποτελεσμάτων αναζήτησης"
+
+#. %s is the terms the user is searching for (a string)
+#: controllers/search_controller.php:241
+#, php-format
+msgid "search_rss_results_for"
+msgstr "Αποτελέσματα αναζήτησης για: %s"
+
+#: views/elements/header.thtml:154
+#: views/layouts/amo2009.thtml:296
+msgid "sidebar_navlink_admin_tools"
+msgstr "ΕÏγαλεία διαχειÏιστή"
+
+#: views/elements/header.thtml:146
+#: views/layouts/amo2009.thtml:288
+msgid "sidebar_navlink_developer_tools"
+msgstr "ΕÏγαλεία δημιουÏγών"
+
+#: views/elements/header.thtml:148
+#: views/layouts/amo2009.thtml:290
+msgid "sidebar_navlink_editor_tools"
+msgstr "ΕÏγαλεία συντακτών"
+
+#: views/layouts/amo2009.thtml:302
+msgid "sidebar_navlink_welcome"
+msgstr "ΚαλωσήÏθατε"
+
+#. %s is the user's name
+#: views/layouts/amo2009.thtml:302
+#, php-format
+msgid "sidebar_navlink_welcome_name"
+msgstr "ΚαλωσόÏισες, %s"
+
+#: views/elements/pitch.thtml:50
+#: views/elements/pitch.thtml:55
+msgid "sidebar_pitch_dictionary"
+msgstr "Λεξικό"
+
+#: views/elements/pitch.thtml:72
+msgid "sidebar_pitch_featured_addons"
+msgstr "Συνιστώμενα Ï€Ïόσθετα"
+
+#: views/elements/pitch.thtml:61
+msgid "sidebar_pitch_looking_for"
+msgstr "Αναζητώ:"
+
+#: views/elements/pitch.thtml:70
+msgid "sidebar_pitch_newest_addons"
+msgstr "Îέα Ï€Ïόσθετα"
+
+#: views/elements/pitch.thtml:49
+msgid "sidebar_pitch_search"
+msgstr "ΠÏόσθετη λειτουÏγία αναζήτησης"
+
+#: views/elements/pitch.thtml:69
+msgid "sidebar_pitch_subscribe_to"
+msgstr "ΕγγÏαφή σε"
+
+#: views/elements/pitch.thtml:48
+#: views/elements/pitch.thtml:54
+msgid "sidebar_pitch_theme"
+msgstr "Θέματα"
+
+#: views/elements/pitch.thtml:71
+msgid "sidebar_pitch_updated_addons"
+msgstr "ΕνημεÏωμένα Ï€Ïόσθετα"
+
+#. %1$s is a number
+#: views/helpers/localization.php:65
+#: views/developers/versions_edit.thtml:95
+#: views/addons/dictionaries.thtml:92
+#, php-format
+msgid "size_kb"
+msgstr "%1$s KB"
+
+#: views/elements/amo2009/stars.thtml:57
+#: views/elements/stars.thtml:63
+msgid "stars_not_yet_rated"
+msgstr "Δεν έχει βαθμολογηθεί ακόμα"
+
+# %1 is the number of stars this add-on has
+#. %1 is the number of stars this add-on has
+#: views/elements/amo2009/stars.thtml:49
+#: views/elements/stars.thtml:54
+#, php-format
+msgid "stars_rated_x_outof_5"
+msgstr "Βαθμολογήθηκε με %s από 5 αστέÏια"
+
+#: views/statistics/addon.thtml:59
+msgid "statistics_addon_dashboard_link"
+msgstr "ΑÏχική σελίδα ταμπλό"
+
+#: views/statistics/addon.thtml:58
+msgid "statistics_addon_developertools_link"
+msgstr "ΕÏγαλεία δημιουÏγών"
+
+#: views/statistics/addon.thtml:53
+msgid "statistics_addon_switch"
+msgstr "Εναλλαγή Ï€Ïόσθετου"
+
+#. This is a date format.
+#. http://php.net/strftime
+#: views/statistics/rss/summary.thtml:54
+#: views/statistics/addon.thtml:181
+msgid "statistics_date_shortmonth"
+msgstr "%e %b."
+
+#. This is a date format.
+#. http://php.net/strftime
+#: views/statistics/rss/summary.thtml:40
+#: views/statistics/addon.thtml:152
+msgid "statistics_date_shortmonthwithyear"
+msgstr "%e, %b. %Y"
+
+#. This is a date format.
+#. http://php.net/strftime
+#: views/statistics/rss/summary.thtml:41
+#: views/statistics/rss/summary.thtml:48
+#: views/statistics/addon.thtml:161
+#: views/statistics/addon.thtml:172
+msgid "statistics_date_weekdayshortmonth"
+msgstr "%A, %e %b."
+
+#. %1$s is an add-on name and version. Example: Add-on 3.5
+#: controllers/components/stats.php:519
+#, php-format
+msgid "statistics_events_addon_created"
+msgstr "ΔημιουÏγήθηκε το %1$s "
+
+#. %1$s is an application name and version. Example: Firefox 3.5
+#: controllers/components/stats.php:500
+#, php-format
+msgid "statistics_events_app_released"
+msgstr "Εκδόθηκε ο %1$s"
+
+#: views/statistics/addon.thtml:71
+msgid "statistics_help_close_link"
+msgstr "Κλείσιμο"
+
+#: views/statistics/addon.thtml:60
+msgid "statistics_help_link"
+msgstr "Βοήθεια"
+
+#: views/statistics/index.thtml:83
+msgid "statistics_index_anotheraddon"
+msgstr "ή επιλέξτε κάποιο άλλο Ï€Ïόσθετο"
+
+#: views/statistics/index.thtml:85
+msgid "statistics_index_anotheraddon_public"
+msgstr "ή επιλέξτε ένα Ï€Ïόσθετο με δημόσια στατιστικά."
+
+#: views/statistics/index.thtml:71
+msgid "statistics_index_myaddons"
+msgstr "Επιλέξτε ένα από τα Ï€Ïόσθετά σας για να δείτε τα στατιστικά του"
+
+#: views/statistics/index.thtml:89
+msgid "statistics_index_selectaddon"
+msgstr "Επιλέξτε Ï€Ïόσθετο για να δείτε τα στατιστικά του"
+
+#: views/statistics/index.thtml:91
+msgid "statistics_index_selectaddon_public"
+msgstr "Επιλέξτε Ï€Ïόσθετο με δημόσια στατιστικά"
+
+#: views/statistics/index.thtml:39
+msgid "statistics_index_title"
+msgstr "Ταμπλό στατιστικών"
+
+#: views/statistics/index.thtml:97
+msgid "statistics_index_view_button"
+msgstr "Εμφάνιση στατιστικών"
+
+#: views/statistics/addon.thtml:222
+#: controllers/statistics_controller.php:247
+msgid "statistics_js_download_csv"
+msgstr "Εμφάνιση πίνακα σε μοÏφή CSV"
+
+#: controllers/statistics_controller.php:246
+msgid "statistics_js_dropdowns_none"
+msgstr "κανένα"
+
+#: controllers/statistics_controller.php:245
+msgid "statistics_js_dropdowns_removeplot"
+msgstr "ΑφαίÏεση γÏαφήματος"
+
+#: controllers/statistics_controller.php:248
+msgid "statistics_js_groupby_selector_date"
+msgstr "Ομαδοποίηση κατά: ΗμέÏα"
+
+#: controllers/statistics_controller.php:251
+msgid "statistics_js_groupby_selector_month"
+msgstr "Ομαδοποίηση κατά: Μήνα"
+
+#: controllers/statistics_controller.php:249
+msgid "statistics_js_groupby_selector_week"
+msgstr "Ομαδοποίηση κατά : Εβδομάδα"
+
+#: controllers/statistics_controller.php:250
+msgid "statistics_js_groupby_selector_week_over_week"
+msgstr "ΣÏγκÏιση ανά: εβδομάδα"
+
+#: controllers/statistics_controller.php:260
+msgid "statistics_js_plotselection_foundinrange"
+msgstr "βÏέθηκαν %s στο διάστημα"
+
+#: controllers/statistics_controller.php:270
+msgid "statistics_js_plotselection_options_addplot_name"
+msgstr "ΠÏοσθήκη γÏαφήματος"
+
+#: controllers/statistics_controller.php:271
+msgid "statistics_js_plotselection_options_addplot_tooltip"
+msgstr "ΠÏοσθήκη κι άλλου σχεδίου στο γÏάφημα"
+
+#: controllers/statistics_controller.php:261
+msgid "statistics_js_plotselection_options_count_name_checked"
+msgstr "ΑπόκÏυψη ÏƒÏ…Î½Î¿Î»Î¹ÎºÎ¿Ï Î¼ÎµÏ„Ïητή"
+
+#: controllers/statistics_controller.php:262
+msgid "statistics_js_plotselection_options_count_name_unchecked"
+msgstr "ΠÏοβολή ÏƒÏ…Î½Î¿Î»Î¹ÎºÎ¿Ï Î¼ÎµÏ„Ïητή"
+
+#: controllers/statistics_controller.php:263
+msgid "statistics_js_plotselection_options_count_tooltip"
+msgstr "Σχεδίαση του συνόλου στο γÏάφημα"
+
+#: controllers/statistics_controller.php:275
+msgid "statistics_js_plotselection_options_csv_name"
+msgstr "Εμφάνιση δεδομένων (CSV)"
+
+#: controllers/statistics_controller.php:276
+msgid "statistics_js_plotselection_options_csv_tooltip"
+msgstr "ΠάÏτε τα δεδομένα σε αÏχείο όπου οι τιμές διαχωÏίζονται με κόμματα (CSV)"
+
+#: controllers/statistics_controller.php:267
+msgid "statistics_js_plotselection_options_events_addon_name_checked"
+msgstr "ΑπόκÏυψη οÏόσημων του %s"
+
+#: controllers/statistics_controller.php:268
+msgid "statistics_js_plotselection_options_events_addon_name_unchecked"
+msgstr "ΠÏοβολή οÏόσημων του %s"
+
+#: controllers/statistics_controller.php:269
+msgid "statistics_js_plotselection_options_events_addon_tooltip"
+msgstr "ΗμεÏομηνίες έκδοσης Ï€Ïόσθετου σε επικάλυψη πάνω στο γÏάφημα"
+
+#: controllers/statistics_controller.php:264
+msgid "statistics_js_plotselection_options_events_firefox_name_checked"
+msgstr "ΑπόκÏυψη οÏόσημων του Firefox"
+
+#: controllers/statistics_controller.php:265
+msgid "statistics_js_plotselection_options_events_firefox_name_unchecked"
+msgstr "ΠÏοβολή οÏόσημων του Firefox"
+
+#: controllers/statistics_controller.php:266
+msgid "statistics_js_plotselection_options_events_firefox_tooltip"
+msgstr "ΗμεÏομηνίες έκδοσης του Firefox σε επικάλυψη πάνω στο γÏάφημα"
+
+#: controllers/statistics_controller.php:272
+msgid "statistics_js_plotselection_options_resize_name_checked"
+msgstr "ΣÏμπτυξη γÏαφήματος"
+
+#: controllers/statistics_controller.php:273
+msgid "statistics_js_plotselection_options_resize_name_unchecked"
+msgstr "Ανάπτυξη γÏαφήματος"
+
+#: controllers/statistics_controller.php:274
+msgid "statistics_js_plotselection_options_resize_tooltip"
+msgstr "Αλλαγή μεγέθους γÏαφήματος"
+
+#: controllers/statistics_controller.php:254
+msgid "statistics_js_plotselection_selector_adu"
+msgstr "ΕνεÏγοί καθημεÏινοί χÏήστες"
+
+#: controllers/statistics_controller.php:256
+msgid "statistics_js_plotselection_selector_application"
+msgstr "ΕφαÏμογή"
+
+#: controllers/statistics_controller.php:259
+msgid "statistics_js_plotselection_selector_custom"
+msgstr "ΠÏοσαÏμοσμένο"
+
+#: controllers/statistics_controller.php:253
+msgid "statistics_js_plotselection_selector_downloads"
+msgstr "Λήψεις"
+
+#: controllers/statistics_controller.php:258
+msgid "statistics_js_plotselection_selector_os"
+msgstr "ΛειτουÏγικό σÏστημα"
+
+#: controllers/statistics_controller.php:257
+msgid "statistics_js_plotselection_selector_status"
+msgstr "Κατάσταση Ï€Ïόσθετου"
+
+#: controllers/statistics_controller.php:252
+msgid "statistics_js_plotselection_selector_summary"
+msgstr "ΣÏνοψη"
+
+#: controllers/statistics_controller.php:255
+msgid "statistics_js_plotselection_selector_version"
+msgstr "Έκδοση Ï€Ïόσθετου"
+
+#: controllers/components/stats.php:398
+msgid "statistics_longnames_application"
+msgstr "ΕφαÏμογή"
+
+#: controllers/components/stats.php:400
+msgid "statistics_longnames_os"
+msgstr "ΛειτουÏγικό σÏστημα"
+
+#: controllers/components/stats.php:399
+msgid "statistics_longnames_status"
+msgstr "Κατάσταση Ï€Ïόσθετου"
+
+#: controllers/components/stats.php:401
+msgid "statistics_longnames_unknown"
+msgstr "Άγνωστη"
+
+#: controllers/components/stats.php:397
+msgid "statistics_longnames_version"
+msgstr "Έκδοση Ï€Ïόσθετου"
+
+#: views/statistics/addon.thtml:118
+msgid "statistics_notice_data_insufficient"
+msgstr "Δεν υπάÏχουν ακόμα αÏκετά δεδομένα για να σχεδιαστεί το γÏάφημα. ΠαÏακαλοÏμε δοκιμάστε ξανά αÏγότεÏα."
+
+#: views/statistics/addon.thtml:130
+msgid "statistics_notice_data_none"
+msgstr "Δεν υπάÏχουν ακόμα δεδομένα για το Ï€Ïόσθετό σας. ΠαÏακαλοÏμε δοκιμάστε ξανά σε μεÏικές μέÏες."
+
+#: views/statistics/addon.thtml:41
+msgid "statistics_notice_data_updating"
+msgstr "Τα στατιστικά Ï€Ïόσθετων βÏίσκονται Ï€Ïος το παÏόν σε διαδικασία ενημέÏωσης. Τα Ï€Ïόσφατα δεδομένα μποÏεί να είναι ημιτελή καθώς τα σενάÏια εντολών ενημεÏώνουν τις πληÏοφοÏίες. ΠαÏακαλοÏμε δοκιμάστε ξανά μετά από μεÏικά λεπτά."
+
+#: views/statistics/addon.thtml:136
+msgid "statistics_notice_disabled"
+msgstr "Το ταμπλό στατιστικών είναι απενεÏγοποιημένο Ï€Ïος το παÏόν. ΠαÏακαλοÏμε Ï€Ïοσπαθήστε αÏγότεÏα."
+
+#: views/statistics/addon.thtml:123
+msgid "statistics_notice_nojavascript"
+msgstr "Για να δείτε τα γÏαφήματα του ταμπλό στατιστικών, απαιτείται η ενεÏγοποίηση της JavaScript."
+
+#: views/statistics/addon.thtml:44
+msgid "statistics_notice_settings_updated"
+msgstr "Οι Ïυθμίσεις σας ενημεÏώθηκαν!"
+
+#: controllers/statistics_controller.php:60
+#: controllers/statistics_controller.php:71
+#: controllers/statistics_controller.php:74
+#: controllers/statistics_controller.php:240
+msgid "statistics_pagetitle"
+msgstr "Ταμπλό στατιστικών"
+
+#: views/statistics/addon.thtml:99
+msgid "statistics_plot_legend_adu"
+msgstr "ΕνεÏγοί καθημεÏινοί χÏήστες"
+
+#: views/statistics/addon.thtml:95
+msgid "statistics_plot_legend_downloads"
+msgstr "ΚαθημεÏινές λήψεις"
+
+#: views/statistics/addon.thtml:107
+msgid "statistics_plot_options_zoomin_alt"
+msgstr "Εστίαση σε"
+
+#: views/statistics/addon.thtml:106
+msgid "statistics_plot_options_zoomin_title"
+msgstr "Εστίαση κατά ένα μήνα"
+
+#: views/statistics/addon.thtml:110
+msgid "statistics_plot_options_zoomout_alt"
+msgstr "ΑπομάκÏυνση"
+
+#: views/statistics/addon.thtml:109
+msgid "statistics_plot_options_zoomout_title"
+msgstr "ΑπομάκÏυνση κατά ένα μήνα"
+
+#: controllers/statistics_controller.php:283
+#, php-format
+msgid "statistics_rss_description"
+msgstr "ΚαθημεÏινή σÏνοψη στατιστικών για %1$s"
+
+#: views/statistics/rss/summary.thtml:68
+msgid "statistics_rss_title_fulldate"
+msgstr "%A %e, %B %Y"
+
+#: views/statistics/rss/summary.thtml:68
+#, php-format
+msgid "statistics_rss_title_statsfordate"
+msgstr "Στατιστικά για %1$s"
+
+#: views/statistics/settings.thtml:49
+msgid "statistics_settings_access_description"
+msgstr "Εξ οÏισμοÏ, μόνο εσείς και ο οÏγανισμός Mozilla μποÏείτε να έχετε Ï€Ïόσβαση στις πληÏοφοÏίες του ταμπλό σας. ΜποÏείτε να το ανοίξετε στο κοινό ώστε να μποÏεί να δει ο καθένας τα δεδομένα του Ï€Ïοσθέτου σας."
+
+#: views/statistics/settings.thtml:48
+msgid "statistics_settings_access_heading"
+msgstr "ΠÏόσβαση στο ταμπλό"
+
+#: views/statistics/settings.thtml:51
+msgid "statistics_settings_access_private"
+msgstr "Ιδιωτικό"
+
+#: views/statistics/settings.thtml:51
+msgid "statistics_settings_access_private_description"
+msgstr "Μόνο εσείς και ο οÏγανισμός Mozilla μποÏείτε να δείτε τα στατιστικά Î±Ï…Ï„Î¿Ï Ï„Î¿Ï… Ï€Ïόσθετου"
+
+#: views/statistics/settings.thtml:52
+msgid "statistics_settings_access_public"
+msgstr "Δημόσια"
+
+#: views/statistics/settings.thtml:52
+msgid "statistics_settings_access_public_description"
+msgstr "Τα στατιστικά Î±Ï…Ï„Î¿Ï Ï„Î¿Ï… Ï€Ïόσθετου είναι σε κοινή θέα"
+
+#: views/statistics/addon.thtml:251
+msgid "statistics_settings_change_link"
+msgstr "Αλλαγή Ïυθμίσεων"
+
+#: views/statistics/addon.thtml:253
+msgid "statistics_settings_confidential"
+msgstr "ΠαÏακαλοÏμε διαχειÏιστείτε αυτή την πληÏοφοÏία σαν εμπιστευτική."
+
+#: views/statistics/addon.thtml:245
+msgid "statistics_settings_currently_private"
+msgstr "Αυτό το ταμπλό είναι <b>ιδιωτικό</b> Ï€Ïος το παÏόν."
+
+#: views/statistics/addon.thtml:241
+msgid "statistics_settings_currently_public"
+msgstr "Αυτό το ταμπλό είναι <b>δημόσιο</b> Ï€Ïος το παÏόν."
+
+#: views/statistics/addon.thtml:246
+msgid "statistics_settings_locked_alt"
+msgstr "Κλειδωμένο"
+
+#: views/statistics/settings.thtml:57
+msgid "statistics_settings_return_link"
+msgstr "ΕπιστÏοφή στο ταμπλό"
+
+#: views/statistics/settings.thtml:56
+msgid "statistics_settings_save_button"
+msgstr "Αποθήκευση Ïυθμίσεων"
+
+#: views/statistics/settings.thtml:46
+#, php-format
+msgid "statistics_settings_title"
+msgstr "Ρυθμίσεις ταμπλό στατιστικών για %1$s"
+
+#: views/statistics/addon.thtml:242
+msgid "statistics_settings_unlocked_alt"
+msgstr "Ξεκλειδωμένο"
+
+#: controllers/components/stats.php:405
+msgid "statistics_shortnames_application"
+msgstr "ΠÏογÏ."
+
+#: controllers/components/stats.php:407
+msgid "statistics_shortnames_os"
+msgstr "Συστ."
+
+#: controllers/components/stats.php:406
+msgid "statistics_shortnames_status"
+msgstr "Κατ."
+
+#: controllers/components/stats.php:408
+msgid "statistics_shortnames_unknown"
+msgstr "Αγν."
+
+#: controllers/components/stats.php:404
+msgid "statistics_shortnames_version"
+msgstr "Εκδ."
+
+#: views/statistics/rss/summary.thtml:42
+#: views/statistics/addon.thtml:192
+msgid "statistics_summary_downloads_average"
+msgstr "Μέσος ÏŒÏος ημεÏήσεων λήψεων"
+
+#: views/statistics/rss/summary.thtml:39
+msgid "statistics_summary_downloads_heading"
+msgstr "Λήψεις"
+
+#: views/statistics/rss/summary.thtml:41
+#: views/statistics/addon.thtml:171
+msgid "statistics_summary_downloads_lastcount"
+msgstr "ΜέτÏηση τελευταίας ημέÏας"
+
+#: views/statistics/rss/summary.thtml:43
+#: views/statistics/addon.thtml:199
+msgid "statistics_summary_downloads_lastweek"
+msgstr "Λήψεις κατά τις Ï€ÏοηγοÏμενες 7 ημέÏες"
+
+#: views/statistics/rss/summary.thtml:40
+#: views/statistics/addon.thtml:151
+msgid "statistics_summary_downloads_total"
+msgstr "Συνολικές λήψεις"
+
+#: views/statistics/rss/summary.thtml:40
+#: views/statistics/addon.thtml:152
+#, php-format
+msgid "statistics_summary_downloads_total_sincedate"
+msgstr "Από %1$s"
+
+#: views/statistics/rss/summary.thtml:50
+#: views/statistics/rss/summary.thtml:56
+#: views/statistics/addon.thtml:163
+#: views/statistics/addon.thtml:183
+msgid "statistics_summary_nodata"
+msgstr "Δεν υπάÏχουν ακόμα δεδομένα"
+
+#: views/statistics/rss/summary.thtml:60
+#: views/statistics/addon.thtml:195
+msgid "statistics_summary_updatepings_average"
+msgstr "Μέσος ÏŒÏος καθημεÏινών ενεÏγών χÏηστών"
+
+#: views/statistics/rss/summary.thtml:52
+#: views/statistics/addon.thtml:177
+msgid "statistics_summary_updatepings_changefromprevious"
+msgstr "Αλλαγή από την Ï€ÏοηγοÏμενη μέτÏηση"
+
+#: views/statistics/rss/summary.thtml:54
+#: views/statistics/addon.thtml:181
+#, php-format
+msgid "statistics_summary_updatepings_changefromprevious_ondate"
+msgstr "%1$s την %2$s"
+
+#: views/statistics/rss/summary.thtml:45
+msgid "statistics_summary_updatepings_heading"
+msgstr "ΕνεÏγοί καθημεÏινοί χÏήστες"
+
+#: views/statistics/rss/summary.thtml:46
+#: views/statistics/addon.thtml:157
+msgid "statistics_summary_updatepings_total"
+msgstr "ΕνεÏγοί καθημεÏινοί χÏήστες"
+
+#: views/statistics/rss/summary.thtml:48
+#: views/statistics/addon.thtml:161
+#, php-format
+msgid "statistics_summary_updatepings_total_ondate"
+msgstr "Την %1$s"
+
+#: views/statistics/rss/summary.thtml:61
+#: views/statistics/addon.thtml:203
+msgid "statistics_summary_updatepings_weekly_average"
+msgstr "Μέσος ÏŒÏος καθημεÏινών χÏηστών αυτή την εβδομάδα"
+
+#. %s is a percentage, like '+22.33%'. It sits next to another number, so
+#. the implied meaning is 'percentage change' from the previous stat point.
+#: views/statistics/rss/summary.thtml:62
+#: views/statistics/addon.thtml:205
+msgid "statistics_summary_updatepings_weekly_change"
+msgstr "%s διαφοÏά από την Ï€ÏοηγοÏμενη εβδομάδα"
+
+#: views/statistics/addon.thtml:65
+#: controllers/statistics_controller.php:184
+#: controllers/statistics_controller.php:282
+#, php-format
+msgid "statistics_title_addon_stats"
+msgstr "Στατιστικά %1$s "
+
+#: views/addons/themes_landing.thtml:113
+msgid "themes_landing_all_themes"
+msgstr "Όλα τα θέματα"
+
+#: views/addons/themes_landing.thtml:109
+msgid "themes_landing_browse_themes"
+msgstr "ΠεÏιήγηση στα θέματα"
+
+#: views/users/edit.thtml:185
+msgid "user_change_email"
+msgstr "Αλλαγή διεÏθυνσης ηλεκτÏÎ¿Î½Î¹ÎºÎ¿Ï Ï„Î±Ï‡Ï…Î´Ïομείου"
+
+#: views/users/edit.thtml:169
+msgid "user_change_password"
+msgstr "Αλλαγή κωδικοÏ"
+
+#: views/users/edit.thtml:96
+msgid "user_change_password_or_email"
+msgstr "Αλλαγή ÎºÏ‰Î´Î¹ÎºÎ¿Ï Î® διεÏθυνσης ηλ. ταχυδÏομείου"
+
+#: controllers/users_controller.php:197
+msgid "user_confirmationcode_resent"
+msgstr "Ο κωδικός επιβεβαίωσης στάλθηκε ξανά!"
+
+# %1 is the email address, %2 is the URL of the user registration page
+#. %1 is the email address, %2 is the URL of the user registration page
+#: views/users/delete.thtml:51
+msgid "user_del_account_deleted"
+msgstr "Ο λογαÏιασμός σας για τη διεÏθυνση %1$s διαγÏάφηκε με επιτυχία. Αν θελήσετε κάποτε να επιστÏέψετε, μποÏείτε να εγγÏαφείτε ξανά από τη σελίδα <a href=\"%2$s\">εγγÏαφής νέου χÏήστη</a>."
+
+#: views/users/delete.thtml:102
+msgid "user_del_community_sad"
+msgstr "Η κοινότητα των Ï€Ïόσθετων Mozilla λυπάται που φεÏγετε."
+
+#: views/users/delete.thtml:123
+msgid "user_del_confirm_password"
+msgstr "Επιβεβαίωση κωδικοÏ"
+
+#: views/users/delete.thtml:134
+msgid "user_del_deletenow"
+msgstr "ΔιαγÏαφή Ï„ÏŽÏα του λογαÏÎ¹Î±ÏƒÎ¼Î¿Ï Î¼Î¿Ï…"
+
+# %1 is the URL of the user's info page
+#. %1 is the URL of the user's info page
+#: views/users/delete.thtml:64
+msgid "user_del_error_addons"
+msgstr "Δεν μποÏείτε να διαγÏάψετε τον λογαÏιασμό σας αν αναφέÏεστε ως <a href=\"%1$s\">δημιουÏγός Ï€Ïόσθετου</a>. Για να διαγÏαφεί ο λογαÏιασμός σας, παÏακαλοÏμε ζητήστε από κάποιο μέλος της ομάδας ανάπτυξης του Ï€Ïόσθετου σας να σας διαγÏάψει από τη λίστα των δημιουÏγών. Μετά απ' αυτό, θα μποÏέσετε να διαγÏάψετε τον λογαÏιασμό σας από 'δω."
+
+# %1 is a link to the amo-editors mailing list
+#. %1 is a link to the amo-editors mailing list
+#: views/users/delete.thtml:71
+msgid "user_del_error_addons_more_questions"
+msgstr "Αν έχετε Ï€Ïόσθετες εÏωτήσεις, παÏακαλοÏμε επικοινωνήστε με τη διεÏθυνση %1$s για βοήθεια."
+
+#: views/users/delete.thtml:78
+msgid "user_del_error_checkbox"
+msgstr "ΠÏέπει να τσεκάÏετε το πλαίσιο στο «Κατανοώ...» για να να διαγÏάψουμε τον λογαÏιασμό σας."
+
+#: views/users/delete.thtml:84
+msgid "user_del_error_password"
+msgstr "ΠαÏακαλοÏμε εισάγετε τον κωδικό σας σωστά για να ολοκληÏώσετε αυτή τη διαδικασία."
+
+# %1 is a link to the amo-admins mailing list
+#. %1 is a link to the amo-admins mailing list
+#: views/users/delete.thtml:91
+msgid "user_del_error_unknown"
+msgstr "ΠαÏουσιάστηκε ένα άγνωστο σφάλμα κατά τη διαγÏαφή του λογαÏÎ¹Î±ÏƒÎ¼Î¿Ï ÏƒÎ±Ï‚. ΠαÏακαλοÏμε επικοινωνήστε με τη διεÏθυνση %1$s γνωστοποιώντας το Ï€Ïόβλημα και θα τον διαγÏάψουμε εμείς. Ζητάμε συγνώμη για την ταλαιπωÏία."
+
+#: views/users/delete.thtml:110
+msgid "user_del_header_confirm_deletion"
+msgstr "Επιβεβαίωση διαγÏαφής λογαÏιασμοÏ"
+
+# %1 is the user's email address
+#. %1 is the user's email address
+#: views/users/delete.thtml:100
+msgid "user_del_header_delete_account"
+msgstr "ΔιαγÏαφή του λογαÏÎ¹Î±ÏƒÎ¼Î¿Ï Ï‡Ïήστη %1$s"
+
+#: views/users/delete.thtml:50
+msgid "user_del_header_farewell"
+msgstr "Σας αποχαιÏετοÏμε!"
+
+#: views/users/delete.thtml:115
+msgid "user_del_nologin"
+msgstr "Δεν θα μποÏείτε πια να συνδεθείτε στον ιστότοπο των Ï€Ïόσθετων Mozilla."
+
+#: views/users/delete.thtml:112
+msgid "user_del_permanently_removed_means"
+msgstr "Κάνωντας κλικ στο «ΔιαγÏαφή...» ο λογαÏιασμός σας θα <strong>διαγÏαφεί οÏιστικά</strong>. Αυτό σημαίνει πως:"
+
+#: views/users/delete.thtml:116
+msgid "user_del_reviews_anonymized"
+msgstr "Οι βαθμολογίες και οι αξιολογήσεις σας δεν θα διαγÏαφοÏν αλλά δεν θα έχετε καμία σχέση πλέον με αυτές."
+
+# %1 is a link to the amo-editors mailing list
+#. %1 is a link to the amo-editors mailing list
+#: views/users/delete.thtml:104
+msgid "user_del_specific_problem_editors"
+msgstr "Αν αντιμετωπίζετε κάποιο Ï€Ïόβλημα που ίσως μποÏοÏμε να σας βοηθήσουμε να λÏσετε, μην διαγÏάψετε τον λογαÏιασμό σας άμεσα, επικοινωνήστε μαζί μας στη διεÏθυνση %1$s και θα κάνουμε ÏŒ,τι μποÏοÏμε για να σας βοηθήσουμε."
+
+#: views/users/delete.thtml:130
+msgid "user_del_understand_permanent"
+msgstr "Κατανοώ ότι η ενέÏγεια αυτή είναι μη αναστÏέψιμη."
+
+#: views/helpers/addons_html.php:192
+msgid "user_deleted_nickname"
+msgstr "ΔιαγÏαμμένος χÏήστης"
+
+# %1 is the new email address
+#. %1 is the new email address
+#: views/users/edit.thtml:71
+msgid "user_edit_confirm_email_sent"
+msgstr "Έχει αποσταλεί ένα μήνυμα ηλεκτÏÎ¿Î½Î¹ÎºÎ¿Ï Ï„Î±Ï‡Ï…Î´Ïομείου στη διεÏθυνση %1$s για να γίνει επιβεβαίωση. Για να ολοκληÏωθεί η αλλαγή θα Ï€Ïέπει να κάνετε κλικ στο δεσμό που θα βÏείτε στο μήνυμα. ΜέχÏι να γίνει αυτό, μποÏείτε να συνδέεστε χÏησιμοποιώντας την Ï„Ïέχουσα διεÏθυνση ηλεκτÏÎ¿Î½Î¹ÎºÎ¿Ï Ï„Î±Ï‡Ï…Î´Ïομείου σας."
+
+#: views/users/edit.thtml:201
+msgid "user_edit_delete_user"
+msgstr "ΔιαγÏαφή λογαÏÎ¹Î±ÏƒÎ¼Î¿Ï Ï‡Ïήστη"
+
+# This contains the email sent to users when they signed up for a new
+# account:
+# %1 is the confirmation URL, %2 is the current app
+#. This contains the email sent to users when they signed up for a new
+#. account:
+#. %1 is the confirmation URL, %2 is the current app
+#: views/users/email/confirm_plain.thtml:6
+#, php-format
+msgid "user_email_confirm_account_nopass"
+msgstr ""
+"ΚαλωσήÏθατε στα Ï€Ïόσθετα του %2$s.\n"
+"\n"
+"ΠÏιν μποÏέσετε να χÏησιμοποιήσετε το λογαÏιασμό σας, θα Ï€Ïέπει να τον ενεÏγοποιήσετε - αυτό διασφαλίζει πως η διεÏθυνση ηλεκτÏÎ¿Î½Î¹ÎºÎ¿Ï Ï„Î±Ï‡Ï…Î´Ïομείου που χÏησιμοποιήσατε είναι έγκυÏη και σας ανήκει.\n"
+"Για να ενεÏγοποιήσετε το λογαÏιασμό σας, κάντε κλικ στον παÏακάτω δεσμό ή κάντε αντιγÏαφή και επικόλληση ολόκληÏης της γÏαμμής στη γÏαμμή διευθÏνσεων του πεÏιηγητή σας:\n"
+"\n"
+"%1$s\n"
+"\n"
+"Î‘Ï†Î¿Ï ÎµÎ½ÎµÏγοποιήσετε το λογαÏιασμό σας με επιτυχία, μποÏείτε να διαγÏάψετε αυτό το μήνυμα με ασφάλεια.\n"
+"\n"
+"ΕυχαÏιστοÏμε για τη συμμετοχή σας στα Ï€Ïόσθετα του %2$s\n"
+"-- Το Ï€Ïοσωπικό των Ï€Ïόσθετων του %2$s"
+
+# %1 is the confirmation url, %2 is the application name
+#. %1 is the confirmation url, %2 is the application name
+#: views/users/email/emailchange_plain.thtml:5
+msgid "user_email_confirm_emailchange"
+msgstr ""
+"Ζητήσατε να γίνει αλλαγή της διεÏθυνσης ηλεκτÏÎ¿Î½Î¹ÎºÎ¿Ï Ï„Î±Ï‡Ï…Î´Ïομείου σας για τα ΠÏόσθετα του %2$s.\n"
+"\n"
+"Για να επιβεβαιωθεί η νέα διεÏθυνση, κάντε κλικ στον παÏακάτω δεσμό ή αντιγÏάψτε και επικολλήστε τον ολόκληÏο στην εÏγαλειοθήκη διευθÏνσεων του πεÏιηγητή σας:\n"
+"\n"
+"%1$s\n"
+"\n"
+"Η επιβεβαίωση της νέας διεÏθυνσης θα Ï€Ïέπει να γίνει εντός 48 ωÏών. Αν αλλάξατε γνώμη και δεν θέλετε πια να γίνει η αλλαγή, απλά αγνοήστε αυτό το μήνυμα.\n"
+"\n"
+"ΕυχαÏιστοÏμε!\n"
+"-- Το Ï€Ïοσωπικό των ΠÏόσθετων του %2$s"
+
+#: controllers/users_controller.php:168
+#, php-format
+msgid "user_email_confirm_subject"
+msgstr "ΕυχαÏιστοÏμε για τη συμμετοχή σας στα Ï€Ïόσθετα του %s"
+
+# This is the password reset email
+# %1 is the pw reset URL, %2 is the application
+#. This is the password reset email
+#. %1 is the pw reset URL, %2 is the application
+#: views/users/email/pwreset_plain.thtml:5
+#, php-format
+msgid "user_email_pwreset"
+msgstr ""
+"ΕπαναφοÏά ÎºÏ‰Î´Î¹ÎºÎ¿Ï Î³Î¹Î± τα Ï€Ïόσθετα του %2$s\n"
+"\n"
+"Δεχθήκαμε ένα αίτημα για την επαναφοÏά ÎºÏ‰Î´Î¹ÎºÎ¿Ï Î±Ï…Ï„Î¿Ï Ï„Î¿Ï… λογαÏÎ¹Î±ÏƒÎ¼Î¿Ï ÏƒÏ„Î¿ addons.mozilla.org. Για να αλλάξετε τον κωδικό , παÏακαλοÏμε κάντε κλικ στον ακόλουθο δεσμό ή επικολλήστε τον στη γÏαμμή διευθÏνσεων του πεÏιηγητή σας:\n"
+"\n"
+"%1$s\n"
+"\n"
+"Αν θεωÏείτε πως το αίτημα στάλθηκε εσφαλμένα, δεν υπάÏχει λόγος να κάνετε οποιαδήποτε ενέÏγεια.\n"
+"\n"
+"ΕυχαÏιστοÏμε,\n"
+"-- Το Ï€Ïοσωπικό των Ï€Ïόσθετων του %2$s"
+
+#: controllers/users_controller.php:245
+#, php-format
+msgid "user_email_pwreset_subject"
+msgstr "ΕπαναφοÏά του ÎºÏ‰Î´Î¹ÎºÎ¿Ï ÏƒÎ±Ï‚ για τα Ï€Ïόσθετα του %s"
+
+#: views/users/emailchange.thtml:50
+msgid "user_emailchange_error"
+msgstr "Σφάλμα!"
+
+# %1 is the application name
+#. %1 is the application name
+#: controllers/users_controller.php:533
+msgid "user_emailchange_subject"
+msgstr "ΠαÏακαλοÏμε επιβεβαιώστε την αλλαγή της διεÏθυνσης ηλεκτÏÎ¿Î½Î¹ÎºÎ¿Ï Ï„Î±Ï‡Ï…Î´Ïομείου σας στα ΠÏόσθετα %1$s "
+
+#: views/users/emailchange.thtml:48
+msgid "user_emailchange_success"
+msgstr "Επιτυχία!"
+
+# %1 is the new email address
+#. %1 is the new email address
+#: views/users/emailchange.thtml:49
+msgid "user_emailchange_successful_description"
+msgstr "Η διεÏθυνση ηλεκτÏÎ¿Î½Î¹ÎºÎ¿Ï Ï„Î±Ï‡Ï…Î´Ïομείου σας αλλάχθηκε με επιτυχία. Στο εξής χÏησιμοποιήστε τη διεÏθυνση %1$s για να συνδεθείτε."
+
+#: views/users/edit.thtml:134
+#: views/admin/users_edit.thtml:111
+msgid "user_form_bio"
+msgstr "Λίγα λόγια για μένα"
+
+#: views/users/edit.thtml:135
+#: views/admin/users_edit.thtml:112
+msgid "user_form_bio_description"
+msgstr "Συστηθείτε στην κοινότητα αν θέλετε! Αυτό το κείμενο θα εμφανίζεται δημόσια στη σελίδα πληÏοφοÏιών χÏήστη. Οι αλλαγές γαμμής διατηÏοÏνται αλλά δεν επιτÏέπεται κώδικας HTML."
+
+#: views/users/pwreset.thtml:77
+#: views/users/register.thtml:73
+#: views/users/edit.thtml:181
+msgid "user_form_confirmpassword"
+msgstr "Επιβεβαίωση κωδικοÏ"
+
+#: views/users/edit.thtml:145
+msgid "user_form_display_collections"
+msgstr "Εμφάνιση των συλλογών που έχω δημιουÏγήσει στο Ï€Ïοφίλ χÏήστη"
+
+#: views/users/edit.thtml:149
+msgid "user_form_display_collections_fav"
+msgstr "Εμφάνιση των αγαπημένων μου συλλογών στο Ï€Ïοφίλ χÏήστη"
+
+#: views/users/edit.thtml:86
+#, php-format
+msgid "user_form_editprofile"
+msgstr "ΕπεξεÏγασία Ï€Ïοφίλ χÏήστη του %s"
+
+#: views/users/pwreset.thtml:52
+#: views/users/login.thtml:81
+#: views/users/register.thtml:63
+#: views/users/edit.thtml:187
+msgid "user_form_email"
+msgstr "ΔιεÏθυνση ηλεκτÏÎ¿Î½Î¹ÎºÎ¿Ï Ï„Î±Ï‡Ï…Î´Ïομείου"
+
+#: views/users/register.thtml:78
+#: views/users/edit.thtml:103
+#: views/admin/users_edit.thtml:76
+msgid "user_form_firstname"
+msgstr "Όνομα"
+
+#: views/users/register.thtml:94
+#: views/users/edit.thtml:119
+#: views/admin/users_edit.thtml:91
+msgid "user_form_hideemail"
+msgstr "ΑπόκÏυψη διεÏθυνσης ηλ. ταχυδÏομείου"
+
+#: views/users/register.thtml:98
+#: views/users/edit.thtml:123
+#: views/admin/users_edit.thtml:99
+msgid "user_form_homepage"
+msgstr "URL ιστότοπου"
+
+#: views/users/register.thtml:84
+#: views/users/edit.thtml:109
+#: views/admin/users_edit.thtml:81
+msgid "user_form_lastname"
+msgstr "Επώνυμο"
+
+#: controllers/users_controller.php:333
+msgid "user_form_login"
+msgstr "ΣÏνδεση χÏήστη"
+
+#: views/users/pwreset.thtml:72
+#: views/users/edit.thtml:176
+msgid "user_form_newpassword"
+msgstr "Îέος κωδικός"
+
+#: views/users/register.thtml:89
+#: views/users/edit.thtml:114
+#: views/admin/users_edit.thtml:86
+msgid "user_form_nickname"
+msgstr "Ψευδώνυμο"
+
+#: views/users/edit.thtml:171
+msgid "user_form_oldpassword"
+msgstr "Παλιός κωδικός"
+
+#: views/users/edit.thtml:97
+#: views/users/edit.thtml:200
+msgid "user_form_otheractions"
+msgstr "Άλλες ενέÏγειες"
+
+#: views/users/login.thtml:85
+#: views/users/register.thtml:68
+msgid "user_form_password"
+msgstr "Κωδικός"
+
+#: controllers/users_controller.php:93
+msgid "user_form_registration"
+msgstr "ΕγγÏαφή νέου χÏήστη"
+
+#: views/users/login.thtml:90
+msgid "user_form_remember_me"
+msgstr "Îα με θυμάσαι σ' αυτό τον υπολογιστή"
+
+#: views/admin/users_edit.thtml:95
+msgid "user_form_showsandbox"
+msgstr "ΠÏοβολή του sandbox;"
+
+#: views/users/edit.thtml:205
+msgid "user_form_submit_edit"
+msgstr "Αποθήκευση"
+
+#: views/users/login.thtml:93
+msgid "user_form_submit_login"
+msgstr "ΣÏνδεση"
+
+#: views/users/register.thtml:113
+msgid "user_form_submit_register"
+msgstr "ΕγγÏαφή"
+
+#: views/users/info.thtml:75
+#, php-format
+msgid "user_info_usersince"
+msgstr "ΧÏήστης του %s Add-ons από:"
+
+#: views/users/login.thtml:102
+msgid "user_login_register_link"
+msgstr "ΔημιουÏγία νέου λογαÏÎ¹Î±ÏƒÎ¼Î¿Ï Ï‡Ïήστη"
+
+#: views/users/edit.thtml:160
+msgid "user_notifications_item_compat"
+msgstr "Συμβατότητα Ï€Ïοσθέτου (Συστήνεται σφόδÏα)"
+
+#: views/users/edit.thtml:161
+msgid "user_notifications_item_events"
+msgstr "ΕπεÏχόμενες εκδηλώσεις και διαγωνισμοί"
+
+#: views/users/edit.thtml:156
+msgid "user_notifications_none_available"
+msgstr "Δεν υπάÏχουν Ï€Ïος το παÏόν ειδοποιήσεις για να τακτοποιήσετε."
+
+#: views/users/edit.thtml:158
+msgid "user_notifications_select_topics"
+msgstr "Κατά καιÏοÏÏ‚ , ο οÏγανισμός Mozilla μποÏεί να σας στείλει μηνÏματα ηλεκτÏÎ¿Î½Î¹ÎºÎ¿Ï Ï„Î±Ï‡Ï…Î´Ïομείου για επεÏχόμενες εκδόσεις και εκδηλώσεις σχετικά με τα Ï€Ïόσθετα. ΠαÏακαλοÏμε επιλέξτε ποια θέματα σας ενδιαφέÏουν από τα παÏακάτω:"
+
+#: views/users/edit.thtml:164
+msgid "user_notifications_specific_contact"
+msgstr "Ο οÏγανισμός Mozilla διατηÏεί το δικαίωμα να επικοινωνήσει Ï€Ïοσωπικά μαζί σας για συγκεκÏιμένα θέματα σχετικά με το Ï€Ïόσθετο σας."
+
+#: controllers/users_controller.php:543
+msgid "user_profile_edit_error"
+msgstr "ΥπάÏχουν σφάλματα στις αλλαγές που κάνατε. ΠαÏακαλοÏμε ελέγξτε τις και υποβάλετέ τες ξανά..."
+
+#: controllers/users_controller.php:540
+msgid "user_profile_saved"
+msgstr "ΕνημεÏώθηκε το Ï€Ïοφίλ."
+
+#: views/users/pwreset.thtml:65
+#, php-format
+msgid "user_pwreset_for_email"
+msgstr "ΕπαναφοÏά ÎºÏ‰Î´Î¹ÎºÎ¿Ï Ï„Î¿Ï… %s"
+
+#: controllers/users_controller.php:226
+msgid "user_pwreset_header"
+msgstr "ΕπαναφοÏά κωδικοÏ"
+
+#: views/users/login.thtml:103
+msgid "user_pwreset_link"
+msgstr "Ξεχάσατε τον κωδικό σας;"
+
+#: controllers/users_controller.php:248
+msgid "user_pwreset_link_sent"
+msgstr "Ο δεσμός επαναφοÏάς ÎºÏ‰Î´Î¹ÎºÎ¿Ï Î­Ï‡ÎµÎ¹ αποσταλεί στη διεÏθυνσή σας."
+
+#: controllers/users_controller.php:304
+msgid "user_pwreset_okay"
+msgstr "Έγινε επαναφοÏά του ÎºÏ‰Î´Î¹ÎºÎ¿Ï Î¼Îµ επιτυχία."
+
+#: views/users/pwreset.thtml:82
+msgid "user_pwreset_submit_changepw"
+msgstr "Υποβολή αιτήματος αλλαγής κωδικοÏ"
+
+#: views/users/pwreset.thtml:57
+msgid "user_pwreset_submit_sendlink"
+msgstr "Αποστολή Î´ÎµÏƒÎ¼Î¿Ï ÎµÏ€Î±Î½Î±Ï†Î¿Ïάς κωδικοÏ"
+
+#: views/users/register_complete.thtml:51
+#, php-format
+msgid "user_register_amo_link"
+msgstr "ΠÏόσθετα %s"
+
+# %1 is the user's email address, %2 is the current app
+#. %1 is the user's email address, %2 is the current app
+#: views/users/activatefirst.thtml:49
+#, php-format
+msgid "user_register_click_confirm_link"
+msgstr "Στάλθηκε ένας δεσμός για να ενεÏγοποιήσετε το λογαÏιασμό σας μέσω ηλ. ταχυδÏομείου στη διεÏθυνση %1$s. Θα Ï€Ïέπει να κάνετε κλικ στο δεσμό αυτό για να μποÏέσετε να συνδεθείτε στα Ï€Ïόσθετά του %2$s."
+
+# %1 is the user's email address
+#. %1 is the user's email address
+#: views/users/register_complete.thtml:49
+#, php-format
+msgid "user_register_confirm_email_sent"
+msgstr "Έχει αποσταλεί μήνυμα επιβεβαίωσης στη διεÏθυνση %1$s. Για να μποÏέσετε να συνδεθείτε θα Ï€Ïέπει Ï€Ïώτα να ενεÏγοποιήσετε το λογαÏιασμό σας κάνοντας κλικ στο δεσμό που θα βÏείτε στο μήνυμα αυτό."
+
+#: views/users/activatefirst.thtml:51
+msgid "user_register_confirmation_link_text"
+msgstr "Επανάληψη αποστολής μηνÏματος επιβεβαίωσης"
+
+#: views/users/register_complete.thtml:47
+msgid "user_register_congratulations"
+msgstr "ΣυγχαÏητήÏια! Ο λογαÏιασμός χÏήστη δημιουÏγήθηκε με επιτυχία."
+
+#: views/users/register.thtml:50
+msgid "user_register_details"
+msgstr "<p>Η εγγÏαφή στο AMO <strong>δεν</strong> απαιτείται αν θέλετε απλά να κάνετε λήψη και εγκατάσταση Ï€Ïόσθετων που βÏίσκονται στο δημόσιο χώÏο.</p><p>Θα Ï€Ïέπει να εγγÏαφείτε μόνο αν:</p><ul><li>Θέλετε να υποβάλετε αξιολογήσεις για Ï€Ïόσθετα.</li><li>Είστε δημιουÏγός κάποιου Ï€Ïόσθετου και θέλετε να φιλοξενηθεί στο AMO</li></ul><p>Αφου εγγÏαφείτε επιτυχώς, θα παÏαλάβετε ένα μήνυμα επιβεβαίωσης στη διεÏθυνση που δώσατε. ΠαÏακαλοÏμε ακολουθήστε τις οδηγίες που θα βÏείτε εκεί για να επιβεβαιώσετε το λογαÏιασμό σας.</p><p>Αν θέλετε, μποÏείτε να διαβάσετε τις <a href='%1$s' title='νομικές σημειώσεις'>Îομικές σημειώσεις</a> και την <a href='%2$s' title='πολιτική αποÏÏήτου'>πολιτική αποÏÏήτου</a> (Αγγλικά).</p>"
+
+# %1 is the link to the "resend confirmation code" page
+#. %1 is the link to the "resend confirmation code" page
+#: views/users/activatefirst.thtml:51
+#, php-format
+msgid "user_register_resend_confirmation_link"
+msgstr "Αν δε λάβατε το μήνυμα επιβεβαίωσης, σιγουÏευτείτε πως η υπηÏεσία ηλ. ταχυδÏομείου που χÏησιμοποιείτε δεν το σημείωσε ως «ανεπιθÏμητο» ή «spam». Αν χÏειάζεται, μποÏοÏμε να κάνουμε %1$s στη διεÏθυνση ηλ. ταχυδÏομείου που αναφέÏθηκε παÏαπάνω."
+
+# %1 is the link to the Mozilla Add-ons front page
+#. %1 is the link to the Mozilla Add-ons front page
+#: views/users/register_complete.thtml:51
+#, php-format
+msgid "user_register_welcome"
+msgstr "ΚαλωσήÏθατε στα %1$s! και ευχαÏιστοÏμε για την εγγÏαφή σας"
+
+#: views/users/register.thtml:49
+msgid "user_register_welcome_header"
+msgstr "Καλώς ήλθατε στον ιστότοπο addons.mozilla.org (AMO)!"
+
+#: views/users/register.thtml:81
+#: views/users/edit.thtml:106
+msgid "user_required_firstlast_or_nickname"
+msgstr "Απαιτείται όνομα, επώνυμο ή ψευδώνυμο."
+
+#: views/users/edit.thtml:94
+#: views/users/edit.thtml:142
+msgid "user_tab_collections"
+msgstr "Συλλογές"
+
+#: views/users/edit.thtml:95
+#: views/users/edit.thtml:154
+msgid "user_tab_notifications"
+msgstr "Ειδοποιήσεις"
+
+#: views/users/edit.thtml:93
+#: views/users/edit.thtml:101
+msgid "user_tab_profile"
+msgstr "ΠÏοφίλ χÏήστη"
+
+#: controllers/users_controller.php:209
+msgid "user_verified_okay"
+msgstr "Επιβεβαιώθηκε με επιτυχία!"
+
+#: controllers/users_controller.php:723
+msgid "users_delete_pagetitle"
+msgstr "ΔιαγÏαφή λογαÏÎ¹Î±ÏƒÎ¼Î¿Ï Ï‡Ïήστη"
+
+#: controllers/users_controller.php:414
+msgid "users_edit_pagetitle"
+msgstr "ΕπεξεÏγασία λογαÏÎ¹Î±ÏƒÎ¼Î¿Ï Ï‡Ïήστη"
+
+#: views/users/info.thtml:71
+msgid "users_info_aboutme"
+msgstr "Λίγα λόγια για μένα"
+
+#: views/users/info.thtml:96
+#, php-format
+msgid "users_info_addons_by_user"
+msgstr "ΠÏόσθετα από τον %1$s"
+
+#: views/users/info.thtml:51
+msgid "users_info_author_name"
+msgstr "Όνομα"
+
+#: views/users/info.thtml:48
+msgid "users_info_author_profile"
+msgstr "ΠÏοφίλ χÏήστη"
+
+#. %s is the user name
+#: views/users/info.thtml:137
+msgid "users_info_collections_by_user"
+msgstr "Συλλογές από %s"
+
+#: views/users/info.thtml:66
+msgid "users_info_email"
+msgstr "ΔιεÏθυνση ηλεκτÏÎ¿Î½Î¹ÎºÎ¿Ï Ï„Î±Ï‡Ï…Î´Ïομείου"
+
+#: views/users/info.thtml:155
+msgid "users_info_fav_collections_by_user"
+msgstr "Αγαπημένες συλλογές"
+
+#: views/users/info.thtml:61
+msgid "users_info_homepage"
+msgstr "ΑÏχική σελίδα"
+
+#: views/users/info.thtml:56
+msgid "users_info_nickname"
+msgstr "Ψευδώνυμο"
+
+#: controllers/users_controller.php:707
+#, php-format
+msgid "users_info_pagetitle"
+msgstr "ΠληÏοφοÏίες για το χÏήστη: %1$s"
+
+# %1 is the user's name
+#. %1 is the user's name
+#: views/users/info.thtml:116
+msgid "users_info_reviews_by_user"
+msgstr "Αξιολογήσεις από %s"
+
+#: controllers/users_controller.php:330
+#: controllers/users_controller.php:332
+msgid "users_login_pagetitle"
+msgstr "ΣÏνδεση χÏήστη"
+
+# %1 is the link to the sandbox/policy explanation page
+# This message is for a specific add-on not found
+#. %1 is the link to the sandbox/policy explanation page
+#. This message is for a specific add-on not found
+#: views/users/login.thtml:53
+#, php-format
+msgid "users_login_sandbox_display_warning"
+msgstr "Το Ï€Ïόσθετο που αναζητήσατε βÏίσκεται Ï€ÏοσωÏινά στο sandbox. Αν έχετε ήδη ένα λογαÏιασμό στο Mozilla Add-ons, παÏακαλοÏμε συνδεθείτε, ή <a href=\"%1$s\">μάθετε πεÏισσότεÏα για το sandbox.</a>"
+
+# %1 is the link to the sandbox/policy explanation page
+# This message is for any given sandbox-related page not found
+#. %1 is the link to the sandbox/policy explanation page
+#. This message is for any given sandbox-related page not found
+#: views/users/login.thtml:56
+#, php-format
+msgid "users_login_sandbox_page_warning"
+msgstr "Η σελίδα που αναζητήσατε είναι τμήμα του sandbox. Αν έχετε ήδη ένα λογαÏιασμό στο Mozilla Add-ons, παÏακαλοÏμε συνδεθείτε, ή <a href=\"%1$s\">μάθετε Ï€ÏισσότεÏα για το sandbox.</a>"
+
+#: controllers/users_controller.php:223
+#: controllers/users_controller.php:225
+msgid "users_pwreset_pagetitle"
+msgstr "ΕπαναφοÏά ÎºÏ‰Î´Î¹ÎºÎ¿Ï Ï‡Ïήστη"
+
+#: controllers/users_controller.php:90
+#: controllers/users_controller.php:92
+msgid "users_register_pagetitle"
+msgstr "ΕγγÏαφή νέου χÏήστη"
+
+#. %1$s is an addon name, like <a>Firebug</a>
+#. %2$s is a version number, like <a>1.2</a>
+#: views/versions/license.thtml:52
+msgid "versions_license_header_source"
+msgstr "Άδεια πηγαίου κώδικα του %1$s %2$s"
+
+#: views/addons/category_landing.thtml:147
+msgid "view_recently_added"
+msgstr "Εμφάνιση όλων όσων Ï€Ïοστέθηκαν Ï€Ïόσφατα"
+
+#: views/addons/category_landing.thtml:161
+msgid "view_top_downloads"
+msgstr "Εμφάνιση όλων των κοÏυφαίων σε λήψεις"
+
+#: views/addons/category_landing.thtml:175
+msgid "view_top_rated"
+msgstr "Εμφάνιση όλων με κοÏυφαία βαθμολογία"
+
+#~ msgid "addon_slider_tooltip_next"
+#~ msgstr "Επόμενο Ï€Ïόσθετο"
+#~ msgid "addon_slider_tooltip_previous"
+#~ msgstr "ΠÏοηγοÏμενο Ï€Ïόσθετο"
+#~ msgid "addon_versions_getlatesttext"
+#~ msgstr "Η πιο Ï€Ïόσφατη έκδοση, συμβατή με"
+#~ msgid "addons_display_version_history"
+#~ msgstr "ΟλοκληÏωμένο ιστοÏικό εκδόσεων"
+#~ msgid "addons_home_newest_header"
+#~ msgstr "ÎεότεÏα:"
+#~ msgid "addons_home_popular_header"
+#~ msgstr "ΔημοφιλέστεÏα:"
+#~ msgid "addons_home_recommended_header"
+#~ msgstr "ΣυνιστοÏμε:"
+#~ msgid "addons_home_updated_header"
+#~ msgstr "Πιο Ï€Ïόσφατα ενημεÏωμένα:"
+#~ msgid "addons_home_view_all"
+#~ msgstr "Εμφάνιση όλων"
+#~ msgid "category_extra_allrecommended"
+#~ msgstr "Δείτε όλα τα συνιστώμενα Ï€Ïόσθετα"
+#~ msgid "category_extra_highestrated"
+#~ msgstr "ΠÏώτα τα βαθμολογημένα υψηλότεÏα"
+#~ msgid "category_extra_lastupdated"
+#~ msgstr "ΠÏώτα τα Ï€Ïόσφατα ενημεÏωμένα"
+#~ msgid "category_extra_mostpopular"
+#~ msgstr "ΠÏώτα τα πιο δημοφιλή"
+#~ msgid "collections_detail_js_loading"
+#~ msgstr "ΦόÏτωση"
+#~ msgid "collections_detail_more_info"
+#~ msgstr "ΠÏοβολή πεÏισσότεÏων πληÏοφοÏιών"
+#~ msgid "devcp_additem_firefox_notice"
+#~ msgstr ""
+#~ "Αυτή η έκδοση του Ï€Ïοσθέτου σας δεν φαίνεται να είναι συμβατή με τον "
+#~ "Firefox %1$s. Η επόμενη έκδοση του Firefox θα εκδοθεί σÏντομα από τον "
+#~ "οÏγανισμό Mozilla, οπότε σας παÏακαλοÏμε να δοκιμάσετε το Ï€Ïόσθετό σας "
+#~ "με τη νέα έκδοση και να ελέγξετε τη συμβατότητά του. ΜποÏείτε να βÏείτε "
+#~ "πεÏισσότεÏες πληÏοφοÏίες <a href=\"%2$s\">εδώ</a>. Αυτή είναι μια απλή "
+#~ "ειδοποίηση, μποÏείτε να υποβάλετε κανονικά αυτή την έκδοση στο addons."
+#~ "mozilla.org."
+#~ msgid "devcp_addon_disabled_successfully"
+#~ msgstr "Το Ï€Ïόσθετο απενεÏγοποιήθηκε επιτυχώς"
+#~ msgid "devcp_addon_edit_pagetitle"
+#~ msgstr "ΕπεξεÏγασία Ï€Ïόσθετου"
+#~ msgid "devcp_addon_enabled_successfully"
+#~ msgstr "Το Ï€Ïόσθετο ενεÏγοποιήθηκε επιτυχώς"
+#~ msgid "devcp_addon_field_description_displaytitle"
+#~ msgstr "ΠεÏιγÏαφή Ï€Ïόσθετου"
+#~ msgid "devcp_addon_field_eula_displaytitle"
+#~ msgstr "Συμφωνητικό αδειοδότησης Ï„ÎµÎ»Î¹ÎºÎ¿Ï Ï‡Ïήστη"
+#~ msgid "devcp_addon_field_homepage_displaytitle"
+#~ msgstr "ΑÏχική σελίδα Ï€Ïόσθετου"
+#~ msgid "devcp_addon_field_name_displaytitle"
+#~ msgstr "Όνομα Ï€Ïόσθετου"
+#~ msgid "devcp_addon_field_privacy_displaytitle"
+#~ msgstr "Πολιτική αποÏÏήτου"
+#~ msgid "devcp_addon_field_summary_displaytitle"
+#~ msgstr "ΣÏνοψη Ï€Ïόσθετου"
+#~ msgid "devcp_addon_field_supportemail_displaytitle"
+#~ msgstr "ΔιεÏθυνση email υποστήÏιξης"
+#~ msgid "devcp_addon_field_supporturl_displaytitle"
+#~ msgstr "URL υποστήÏιξης"
+#~ msgid "devcp_addon_field_versionnotes_displaytitle"
+#~ msgstr "Σημειώσεις έκδοσης"
+#~ msgid "devcp_addon_nominate_pagetitle"
+#~ msgstr "Υποψηφιότητα Ï€Ïόσθετου"
+#~ msgid "devcp_addon_nominated_successfully"
+#~ msgstr "Το Ï€Ïόσθετο τέθηκε σε υποψηφιότητα επιτυχώς"
+#~ msgid "devcp_addon_status_criteria_review"
+#~ msgstr ""
+#~ "ΑÏκετές αξιολογήσεις από χÏήστες για το Ï€Ïόσθετο (Πιθανόν εκτός "
+#~ "ιστοτόπου)."
+#~ msgid "devcp_submit_accept_dev_agreement"
+#~ msgstr "Αποδεκτό"
+#~ msgid "devcp_submit_decline_dev_agreement"
+#~ msgstr "Μη αποδεκτό"
+#~ msgid "editors_submissiontype_new"
+#~ msgstr "Îέο"
+#~ msgid "editors_submissiontype_updated"
+#~ msgstr "ΕνημεÏωμένο"
+#~ msgid "editors_th_addon_age"
+#~ msgstr "Ηλικία Ï€Ïόσθετου"
+#~ msgid "editors_th_addontypes"
+#~ msgstr "ΤÏποι Ï€Ïόσθετων"
+#~ msgid "editors_th_applications"
+#~ msgstr "ΕφαÏμογές"
+#~ msgid "editors_th_platforms"
+#~ msgstr "ΠλατφόÏμες"
+#~ msgid "editors_th_submissiontypes"
+#~ msgstr "ΤÏποι υποβληθέντων"
+#~ msgid "forum_save"
+#~ msgstr "Αποθήκευση"
+#~ msgid "home"
+#~ msgstr "αÏχική"
+#~ msgid "nav_category_plugins"
+#~ msgstr "ΠÏόσθετες λειτουÏγίες"
+#~ msgid "search_matching_addons_number"
+#~ msgid_plural "search_matching_addons_number"
+#~ msgstr[0] "ταιÏιάζει %s Ï€Ïόσθετο"
+#~ msgstr[1] "ταιÏιάζουν %s Ï€Ïόσθετα"
+
diff --git a/site/app/locale/el/images/sandbox-review.png b/site/app/locale/el/images/sandbox-review.png
new file mode 100644
index 0000000..e770f1c
--- /dev/null
+++ b/site/app/locale/el/images/sandbox-review.png
Binary files differ
diff --git a/site/app/locale/el/pages/about.thtml b/site/app/locale/el/pages/about.thtml
new file mode 100644
index 0000000..a9a6ae6
--- /dev/null
+++ b/site/app/locale/el/pages/about.thtml
@@ -0,0 +1,45 @@
+<h2>Τι είναι το addons.mozilla.org;</h2>
+<p>
+ Το addons.mozilla.org (AMO) είναι ο επίσημος ιστότοπος του Mozilla για Ï€Ïόσθετα εφαÏμογών Mozilla. Τα Ï€Ïόσθετα σας επιτÏέπουν να Ï€Ïοσθέσετε νέα χαÏακτηÏιστικά στον Firefox, τον Thunderbird, το SeaMonkey, και το Sunbird. Από το AMO, μποÏείτε να δείτε και να κάνετε λήψη χιλιάδων Ï€Ïόσθετων για να αλλάξετε τον Ï„Ïόπο που χÏησιμοποιείτε το διαδίκτυο.
+</p>
+
+<h2>Ποιος φτιάχνει αυτά τα Ï€Ïόσθετα;</h2>
+<p>
+ Οι χιλιάδες των δημιουÏγών Ï€Ïόσθετων αποτελοÏνται από ανθÏώπους που απασχολοÏνται εÏασιτεχνικά, μέχÏι και μεγάλες εταιÏείες. Όλα τα Ï€Ïόσθετα που βÏίσκονται στο δημόσιο χώÏο έχουν αξιολογηθεί από μια ομάδα αφοσιωμένων εθελοντών Ï€Ïιν δημοσιευθοÏν. Τα πειÏαματικά Ï€Ïόσθετα φέÏουν ειδική σήμανση και δεν έχουν πεÏάσει από αξιολόγηση.
+</p>
+
+<h2>Πως μποÏÏŽ να παÏακολουθήσω τις εξελίξεις γÏÏω από το AMO;</h2>
+<p>
+ Το <a href="http://blog.mozilla.com/addons/">ιστολόγιο</a> μας ανανεώνεται σε σταθεÏή βάση και συχνά φιλοξενοÏμε δημοσιεÏσεις από την κοινότητα. Επίσης υπάÏχει και το <a href="https://addons.mozilla.org/newsletter">ενημεÏωτικό δελτίο</a> που αποστέλλεται σε μηνιαία βάση.
+</p>
+
+<h2>Καλό ακοÏγεται! πως μποÏÏŽ να συμμετέχω;</h2>
+<p>
+ ΥπάÏχουν πολλοί Ï„Ïόποι για να συμμετέχετε:
+</p>
+<ul>
+ <li>
+ <a href="https://wiki.mozilla.org/AMO:Editors/Applying">Γίνετε συντάκτης</a>. Οι συντάκτες μας είναι φίλοι του AMO οι οποίοι διαθέτουν τεχνολογικές γνώσεις και αξιολογοÏν την ποιότητα του κώδικα και τη σταθεÏότητα των Ï€Ïόσθετων.
+ </li>
+ <li>
+ <a href="http://developer.mozilla.org/">ΔημιουÏγήστε το δικό σας Ï€Ïόσθετο</a>. Το AMO παÏέχει δωÏεάν φιλοξενία και υπηÏεσίες ενημέÏωσης και σας επιτÏέπει να απευθυνθείτε σε ένα μεγάλο κοινό χÏηστών.
+ </li>
+ <li>
+ Πείτε το στους φίλους σας! Διαδώστε τον Firefox (<a href="http://spreadfirefox.com/">Spread Firefox</a>) και πείτε στον κόσμο ποια Ï€Ïόσθετα χÏησιμοποιείτε.
+ </li>
+ <li>
+ Υποβάλετε αναφοÏές σφαλμάτων και διοÏθώσεις. Ο <a href="https://bugzilla.mozilla.org/buglist.cgi?quicksearch=addons">Bugzilla</a> πεÏιέχει όλα τα σφάλματα που έχει Ï€Ïος το παÏών το AMO. ΜποÏείτε να αναφέÏετε κάποιο που δεν έχει ανακαλυφθεί ακόμα ή να συνεισφέÏετε με κώδικα που να διοÏθώνει κάποιο.
+ </li>
+</ul>
+
+<h2>Θέλω να κάνω μια εÏώτηση.</h2>
+<p>
+ Ένα καλό σημείο εκκίνησης είναι η σελίδα <a href="https://addons.mozilla.org/pages/faq"><abbr title="Συχνές ΕÏωτήσεις">Σ.Ε.</abbr></a>. Αν δεν βÏείτε την απάντηση που θέλετε εκεί, χÏησιμοποιήστε τις πληÏοφοÏίες επικοινωνίας που θα βÏείτε στο τέλος αυτής της σελίδας. Για εÏωτήσεις σχετικά με κάποιο συγκεκÏιμένο Ï€Ïόσθετο, χÏησιμοποιήστε τις πληÏοφοÏίες επικοινωνίας που θα βÏείτε στη σελίδα που το δημοσιεÏουμε.
+</p>
+
+<h2>Επικοινωνήστε μαζί μας</h2>
+<dl>
+ <dt>Στο <abbr title="Internet Relay Chat">IRC</abbr>:</dt>
+ <dd><a href="irc://irc.mozilla.org/#addons">#addons</a> στο irc.mozilla.org για γενικές εÏωτήσεις και εÏωτήσεις σχετικές με αξιολογήσεις</dd>
+ <dd><a href="irc://irc.mozilla.org/#amo">#amo</a> στο irc.mozilla.org για θέματα διαχείÏισης και ανάπτυξης</dd>
+</dl>
diff --git a/site/app/locale/el/pages/collector.thtml b/site/app/locale/el/pages/collector.thtml
new file mode 100644
index 0000000..f5935e8
--- /dev/null
+++ b/site/app/locale/el/pages/collector.thtml
@@ -0,0 +1,47 @@
+<h2>Mozilla Firefox Add-on Collector</h2>
+
+<p class="intro">ΚοÏυφαία Ï€ÏοσαÏμογή του πεÏιηγητή σας.</p>
+
+<div class="primary">
+ <p>ΑνακαλÏψτε πεÏισσότεÏα Ï€Ïόσθετα απ' τα καλÏτεÏα που υπάÏχουν και οÏγανώστε τα αγαπημένα σας σε εÏκολες στη διαχείÏιση τους συλλογές. ΓÏαφτείτε συνδÏομητές στις συλλογές που σας αÏέσουν και δείτε τις να μεγαλώνουν, ή δημιουÏγήστε τη δική σας συλλογή και δείτε πόσοι χÏήστες θα την εκτιμήσουν καθώς την εξελίσσετε.</p>
+</div>
+
+<div class="secondary">
+ <div class="highlight">
+ <h4>Κάντε λήψη του Add-on Collector:</h4>
+ %1$s
+ </div><!-- /.highlight -->
+</div>
+
+<div class="column-wrapper article-wrapper">
+
+ <div class="column first">
+ <div class="article">
+ <h3>Συνιστώμενες συλλογές</h3>
+ <p>ΓÏαφτείτε συνδÏομητής σε μια συλλογή Ï€Ïόσθετων για να λαμβάνετε ειδοποιήσεις όταν εξελίσσεται. Αν δημιουÏγήσετε τη δική σας συλλογή, θα έχετε χώÏο για να πείτε τους λόγους που σας αÏέσει κάποιο Ï€Ïόσθετο και να δώσετε οδηγίες για την Ï€ÏοσαÏμογή τους.</p>
+
+ </div>
+ </div>
+
+ <div class="column">
+ <div class="article">
+ <h3>ΔιαμοιÏάστε Ï€Ïόσθετα</h3>
+ <p>Ειδοποιήστε φίλους για Ï€Ïόσθετα που είναι αξιόλογα. Επιλέξτε το «Δημοσίευση Ï€Ïος» και θα ειδοποιηθοÏν σε μοÏφή έτοιμη για εγκατάσταση απευθείας απ' την πηγή (δηλαδή εσάς!).</p>
+ </div>
+
+ </div>
+
+
+ <div class="column">
+ <div class="article">
+ <h3>ΣυγχÏονιστείτε με όλες τις πηγές</h3>
+ <p>ΔημοσιεÏστε νέες συλλογές και δώστε δεσμοÏÏ‚ που θα είναι πάντα επίκαιÏοι χάÏις στην «Αυτόματη δημοσίευση». ΣυγχÏονίστε τις συσκευές σας και βάλτε στους πεÏιηγητές που έχετε σε όλα σας τα μηχανήματα τις πιο Ï€Ïόσφατες συλλογές σας.</p>
+ </div>
+ </div>
+
+</div><!-- /.column-wrapper .article-wrapper -->
+
+<ul class="further-navigation">
+ <li><a href="%2$s">ΧαÏακτηÏιστικά Add-on Collector</a></li>
+ <li><a href="%3$s">Συχνές εÏωτήσεις</a></li>
+</ul>
diff --git a/site/app/locale/el/pages/collector_faq.thtml b/site/app/locale/el/pages/collector_faq.thtml
new file mode 100644
index 0000000..5a9d57e
--- /dev/null
+++ b/site/app/locale/el/pages/collector_faq.thtml
@@ -0,0 +1,24 @@
+<h2>Συχνές εÏωτήσεις για το Add-on Collector</h2>
+
+<dl class="faq">
+<dt>Τι είναι οι συλλογές;</dt>
+<dd>Οι συλλογές είναι ομάδες σχετικών Ï€Ïόσθετων που έχουν συγκεντÏωθεί για να μποÏοÏν να μοιÏαστοÏν εÏκολα.</dd>
+
+<dt>Τι είναι το Add-on Collector;</dt>
+<dd>Το Add-on Collector είναι μια επέκταση για τον Firefox που σας διευκολÏνει στο να συμβαδίζετε με τις αγαπημένες σας συλλογές.</dd>
+
+<dt>Τι χÏειάζεται για να χÏησιμοποιήσω το Add-on Collector;</dt>
+<dd>Θα χÏειαστείτε ένα <a href="%s">λογαÏιασμό στα Ï€Ïόσθετα Mozilla</a> και την πιο Ï€Ïόσφατη έκδοση του <a href="http://www.getfirefox.com">Firefox</a>.</dd>
+
+<dt>Πως μποÏÏŽ να γίνω συνδÏομητής μιας συλλογής;</dt>
+<dd>ΜποÏείτε να γÏαφτείτε συνδÏομητές σε μια συλλογή επισημαίνοντας την σαν αγαπημένη μέσα από τον <a href="%s">κατάλογο συλλογών</a>. Οι αγαπημένες σας συλλογές θα εμφανίζονται ως συνδÏομές στον διαχειÏιστή Ï€Ïόσθετων.</dd>
+
+<dt>Πως μποÏÏŽ να συγχÏονίσω τα Ï€Ïόσθετα που έχω στους υπολογιστές μου με το Add-on Collector;</dt>
+<dd>Απλά Ïυθμίστε την αυτόματη δημοσίευση σε ένα υπολογιστή και θα εμφανίζεται στην κοÏυφή της λίστας συνδÏομών σας σε όλους του υπολογιστές που έχετε εγκαταστήσει το Add-on Collector. Έτσι θα μποÏείτε να δείτε ποια Ï€Ïόσθετα έχετε εγκαταστήσει σε καθένα από τους υπολογιστές που έχετε Ïυθμίσει για αυτόματη δημοσίευση.</dd>
+
+<dt>Ο συγχÏονισμός των Ï€Ïόσθετων δεν γίνεται και με το Weave των Mozilla Labs;</dt>
+<dd>Το Weave όντως θα Ï€ÏοσφέÏει συγχÏονισμό Î¼ÎµÏ„Î±Î¾Ï Î´Î¹Î±Ï†Î¿Ïετικών Ï€Ïοφίλ και συσκευών στο μέλλον. Ο συγχÏονισμός που κάνει το Add-on Collector λειτουÏγεί κάπως διαφοÏετικά, από την άποψη ότι τα δεδομένα αυτόματης δημοσίευσης δεν είναι κÏυπτογÏαφημένα και έχουν σχεδιαστεί έτσι για να μποÏείτε να τα μοιÏάσετε σε φίλους με τη μοÏφή μιας συλλογής. Επίσης, μποÏείτε να μοιÏάσετε Ï€Ïόσθετα διαφοÏετικών Ï€Ïοφίλ χÏησιμοποιώντας διαφοÏετικές συλλογές.</dd>
+
+<dt>Πως μποÏÏŽ να αφήσω σχόλια ή να αναφέÏω ένα σφάλμα;</dt>
+<dd>Αν ανακαλÏψατε κάποιο σφάλμα ή θέλετε να κάνετε μια Ï€Ïόταση για κάποιο χαÏακτηÏιστικό, παÏακαλοÏμε αναφέÏετε το στο Bugzilla μέσα απ' αυτή τη <a href="https://bugzilla.mozilla.org/enter_bug.cgi?component=Bandwagon&amp;product=addons.mozilla.org">φόÏμα</a>. Αν θέλετε να κάνετε γενικότεÏο σχολιασμό, παÏακαλοÏμε στείλτε τα σχόλια σας γÏαμμένα στα αγγλικά στην <a href="http://groups.google.com/group/mozilla.dev.amo">ομάδα συζητήσεων</a> μας.</dd>
+</dl>
diff --git a/site/app/locale/el/pages/collector_features.thtml b/site/app/locale/el/pages/collector_features.thtml
new file mode 100644
index 0000000..0897938
--- /dev/null
+++ b/site/app/locale/el/pages/collector_features.thtml
@@ -0,0 +1,27 @@
+<h2>Add-on Collector για τον Mozilla Firefox</h2>
+<h4>ΚοÏυφαία Ï€ÏοσαÏμογή του πεÏιηγητή σας.</h4>
+<h3>ΧαÏακτηÏιστικά της επέκτασης</h3>
+<p>
+ Το Ï€Ïόσθετο Add-on Collector σας συνδέει με τα αγαπημένα σας Ï€Ïόσθετα και τις συλλογές με πολλοÏÏ‚ Ï„Ïόπους:
+</p>
+
+<dl>
+ <dt>ΠÏόσβαση στις αγαπημένες σας συλλογές από τον Firefox</dt>
+ <dd>
+ Οι συλλογές που σημειώνετε σαν αγαπημένες στον
+ <a href="%1$s">κατάλογο συλλογών</a> εμφανίζονται σε ένα ειδικό τμήμα του διαχειÏιστή Ï€Ïόσθετων. Έτσι θα μποÏείτε να έχετε πάντα ενημεÏωμένες τις συλλογές σας και να βλέπετε τα πεÏιεχόμενα της κάθε μιας.
+ </dd>
+ <dt>ΔιαμοιÏασμός Ï€Ïόσθετων με το Î¼ÎµÎ½Î¿Ï Î´Î·Î¼Î¿ÏƒÎ¯ÎµÏ…ÏƒÎ·Ï‚</dt>
+ <dd>
+ Κάθε Ï€Ïόσθετο που εγκαθιστάτε μποÏεί να διαμοιÏαστεί εÏκολα σε φίλους σας μέσω ηλεκτÏÎ¿Î½Î¹ÎºÎ¿Ï Ï„Î±Ï‡Ï…Î´Ïομείου ή να δημοσιευθεί σε μια από τις συλλογές μας μέσω ενός Î¼ÎµÎ½Î¿Ï Î³Î¹Î± δημοσιεÏσεις.
+ </dd>
+ <dt>Αποστολή ειδοποιήσεων</dt>
+ <dd>
+ Το Add-on Collector θα σας ειδοποιεί όταν κάποια από τις συλλογές σας αποκτήσει ένα νέο στοιχείο και θα το σημειώσει για να το αξιολογήσετε αÏγότεÏα.
+ </dd>
+
+ <dt>Αυτόματη δημοσίευση ήδη εγκαταστημένων Ï€Ïόσθετων σε συλλογή</dt>
+ <dd>
+ Η λειτουÏγία αυτόματης δημοσίευσης διατηÏεί συνεχώς ενημεÏωμένη τη συλλογή σας με τα πιο Ï€Ïόσφατα Ï€Ïόσθετα που εγκαθιστάτε, διατηÏώντας παÏάλληλα ενημεÏωμένους και τους φίλους σας που έχουν συνδÏομή στη συλλογή αυτή.
+ </dd>
+</dl>
diff --git a/site/app/locale/el/pages/collector_firstrun.thtml b/site/app/locale/el/pages/collector_firstrun.thtml
new file mode 100644
index 0000000..9185257
--- /dev/null
+++ b/site/app/locale/el/pages/collector_firstrun.thtml
@@ -0,0 +1,38 @@
+<div>
+ <h2>ΚαλωσοÏίσατε</h2>
+ <p class="intro">Το Add-on Collector για τον Firefox έχει Ï€Ïοστεθεί στον πεÏιηγητή Firefox. Είστε σχεδόν έτοιμοι για να δημιουÏγήσετε, να διαχειÏιστείτε, να διαμοιÏάσετε και να λάβετε συλλογές Ï€Ïόσθετων.</p>
+</div>
+
+ <div class="primary">
+ <h3>Για να χÏησιμοποιήσετε το Add-on Collector</h3>
+ <ol class="numbered">
+ <li>
+ <h4 class="step">1</h4>
+ Κάντε κλικ στο Î¼ÎµÎ½Î¿Ï Â«Î•Ïγαλεία» της εÏγαλειοθήκης του Firefox toolbar και επιλέξτε «ΠÏόσθετα».
+ </li>
+ <li>
+ <h4 class="step">2</h4>
+ Από το τμήμα συνδÏομών, συνδεθείτε με τις πληÏοφοÏίες του λογαÏÎ¹Î±ÏƒÎ¼Î¿Ï ÏƒÎ±Ï‚ στα «ΠÏόσθετα Mozilla».
+ </li>
+ <li>
+ <h4 class="step">3</h4>
+ Θα δείτε μια λίστα με όλες σας τις συλλογές στα αÏιστεÏά. Κάντε κλικ σε οποιαδήποτε συλλογή για μια λεπτομεÏή λίστα των πεÏιεχόμενων της. Κάντε κλικ στο «ΠÏοσθήκη στον Firefox» ή στο «Δημοσίευση Ï€Ïος» για να διαχειÏιστείτε τη συλλογή ή να τη στείλετε σε κάποιο φίλο μέσω ηλεκτÏÎ¿Î½Î¹ÎºÎ¿Ï Ï„Î±Ï‡Ï…Î´Ïομείου.
+ </li>
+ </ol>
+ <p>Είτε είστε φανατικός «κυνηγός» Ï€Ïόσθετων, είτε απλά κάποιος/α που χÏησιμοποιεί τα Ï€Ïόσθετα για να βελτιώσει την πεÏιήγηση στο διαδίκτυο, το Add-on Collector θα σας βοηθήσει. Για πεÏισσότεÏες πληÏοφοÏίες σχετικά με τα χαÏακτηÏιστικά του Add-on Collector για τον Firefox και συχνές εÏωτήσεις, δείτε τις σελίδες <a href="%1$s">χαÏακτηÏιστικών</a> και <a href="%2$s">συχνών εÏωτήσεων</a>.</p>
+ </div><!-- / .primary -->
+
+ <div class="secondary">
+ <div class="highlight">
+ <h4>Ξεκινήστε μ' αυτές τις συλλογές</h4>
+
+ <ul>
+ %3$s
+ </ul>
+
+ <ul class="further-navigation">
+ <li><a href="%4$s" class="more-info">Δείτε όλες τις συλλογές</a></li>
+ </ul>
+ </div><!-- /. highlight -->
+ </div><!-- /. secondary-->
+
diff --git a/site/app/locale/el/pages/compatibility_user_tips.thtml b/site/app/locale/el/pages/compatibility_user_tips.thtml
new file mode 100644
index 0000000..aba1e97
--- /dev/null
+++ b/site/app/locale/el/pages/compatibility_user_tips.thtml
@@ -0,0 +1,6 @@
+<ul class="tips">
+ <li>Αν και πολλά από τα Ï€Ïόσθετα μποÏοÏν να λειτουÏγήσουν με τις νέες εκδόσεις του %s χωÏίς να χÏειάζονται αλλαγές στον κώδικα τους, μεÏικά ίσως απαιτοÏν επιπλέον δουλειά από τους δημιουÏγοÏÏ‚ τους για να λειτουÏγήσουν μετά από μια αναβάθμιση. ΠαÏακαλοÏμε κάντε υπομονή για όσο χÏόνο χÏειαστεί, πολλοί δημιουÏγοί υποστηÏίζουν τα Ï€Ïόσθετα τους σαν εÏασιτεχνική απασχόληση στον ελεÏθεÏο χÏόνο τους.</li>
+ <li>Το ίδÏυμα Mozilla δεν συνιστά την απενεÏγοποίηση του ελέγχου συμβατότητας γιατί κάτι τέτοιο μποÏεί να Ï€Ïοκαλέσει σοβαÏά Ï€Ïοβλήματα στην εκκίνηση του %s ή ακόμα και απώλεια δεδομένων αν χÏησιμοποιηθεί μια επέκταση που δεν είναι συμβατή με μια νέα έκδοση του %s.</li>
+ <li>Αν η επέκταση που θέλετε να χÏησιμοποιήσετε αναφεÏθεί από τον %s ως μη συμβατή κατά την εκκίνηση του, μποÏείτε να δείτε την Ï€Ïοσωπική σελίδα του δημιουÏÎ³Î¿Ï Ï„Î¿Ï… ή τον ιστότοπο του για νέα σχετικά με την ενημέÏωση του.</li>
+ <li>ΜποÏείτε επίσης να ψάξετε για κάποιο Ï€Ïόσθετο με παÏόμοια χαÏακτηÏιστικά που να υποστηÏίζει την έκδοση %s στον ιστότοπο των <a href="%s">Ï€Ïόσθετων %s </a>.</li>
+</ul>
diff --git a/site/app/locale/el/pages/error404.thtml b/site/app/locale/el/pages/error404.thtml
new file mode 100644
index 0000000..89ad83c
--- /dev/null
+++ b/site/app/locale/el/pages/error404.thtml
@@ -0,0 +1,16 @@
+<h1>Συγνώμη αλλά δεν ήταν δυνατόν να βÏεθεί αυτό το οποίο ψάχνετε.</h1>
+
+<p>Η σελίδα ή το αÏχείο που ζητήσατε δε βÏέθηκε στον ιστότοπό μας. Είναι πιθανό να κάνατε κλικ σε ένα παÏωχημένο δεσμό, ή να πληκτÏολογήσατε λάθος τη διεÏθυνση.</p>
+
+<ul>
+<li>Αν πληκτÏολογήσατε λάθος τη διεÏθυνση, ελέγξτε την οÏθογÏαφία.</li>
+<li>Αν ακολουθήσατε ένα δεσμό από κάποια σελίδα, παÏακαλοÏμε ενημεÏώστε μας στη διεÏθυνση <a href="mailto:webmaster@mozilla.com" title="Page Not Found on Mozilla.com">webmaster@mozilla.com</a>. Πείτε μας Ï€Î¿Ï Ï…Ï€Î®Ïχε ο δεσμός και τι ακÏιβώς αναζητοÏσατε και θα Ï€Ïοσπαθήσουμε να το διοÏθώσουμε.</li>
+</ul>
+
+<p>ΜποÏείτε επίσης να μεταβείτε απλά σε μια από τις δημοφιλείς σελίδες του ιστοτόπου μας.</p>
+
+<ul>
+<li>Σας ενδιαφέÏει μια <a href="%1$s">λίστα δημοφιλών Ï€Ïόσθετων</a>;</li>
+<li>Θέλετε να κάνετε <a href="%2$s">αναζήτηση για Ï€Ïόσθετα</a>; ΜποÏείτε να πάτε στη <a href="%2$s">σελίδα αναζήτησης</a> ή απλά να χÏησιμοποιήσετε το παÏαπάνω πεδίο αναζήτησης.</li>
+<li>Αν Ï€Ïοτιμάτε να Ï€Ïοσπαθήσετε ξανά και από την αÏχή, πηγαίνετε απλά στην <a href="%3$s">αÏχική σελίδα Ï€Ïόσθετων</a>.</li>
+</ul>
diff --git a/site/app/locale/el/pages/faq.thtml b/site/app/locale/el/pages/faq.thtml
new file mode 100644
index 0000000..1b803b6
--- /dev/null
+++ b/site/app/locale/el/pages/faq.thtml
@@ -0,0 +1,78 @@
+<h1>Συχνές εÏωτήσεις</h1>
+
+<p>Αυτές οι «Συχνές ΕÏωτήσεις» για τις σελίδες του <a href="http://addons.mozilla.org">AMO</a> καλÏπτουν οÏισμένα θέματα που δεν καλÏπτονται Ï€Ïος το παÏόν στον ιστότοπο υποστήÏιξης του Firefox. Ο ιστότοπος υποστήÏιξης πεÏιλαμβάνει εισαγωγικές πληÏοφοÏίες για την <a href="http://support.mozilla.com/kb/Customizing+Firefox+with+add-ons">Ï€ÏοσαÏμογή του Firefox με Ï€Ïόσθετα</a> καθώς και άÏθÏα για:</p>
+
+<ul>
+ <li> Ανίχνευση Ï€Ïοβλημάτων <a href="http://support.mozilla.com/kb/Unable+to+install+add-ons">εγκατάστασης Ï€Ïόσθετων</a>, <a href="http://support.mozilla.com/kb/Troubleshooting+plugins">Ï€Ïόσθετων λειτουÏγιών</a> &amp; <a href="http://support.mozilla.com/kb/Troubleshooting+extensions+and+themes">γενικά θέματα</a>.</li>
+ <li> <a href="http://support.mozilla.com/kb/Uninstalling+add-ons">Πως να απεγκαταστήσετε Ï€Ïόσθετα</a> και <a href="http://support.mozilla.com/kb/Cannot+uninstall+an+add-on">ανίχνευση Ï€Ïοβλημάτων απεγκατάστασης</a>.</li>
+ <li> <a href="http://support.mozilla.com/kb/Gray+bar+below+the+status+bar">ΔιαχείÏιση Ï€Ïοβληματικών Ï€Ïόσθετων / ΠÏόβλημα Gray Bar</a></li>
+</ul>
+
+<p></p>
+
+<div id="gsfn_list_widget">
+ <a href="https://getsatisfaction.com/mozilla" class="widget_title">ΕνεÏγές συζητήσεις υποστήÏιξης για Ï€Ïόσθετα Mozilla</a>
+ <div id="gsfn_content">φόÏτωση...</div>
+ <div class="powered_by">
+ <a href="https://getsatisfaction.com/"><img alt="Favicon" src="https://www.getsatisfaction.com/favicon.gif" style="vertical-align: middle;" /></a>
+ <a href="https://getsatisfaction.com/">Δίκτυο υποστήÏιξης Get Satisfaction</a>
+ </div>
+</div>
+
+<h2>ΕÏωτήσεις για Ï€Ïόσθετα</h2>
+<dl class="faq">
+<dt>Τι είναι τα Ï€Ïόσθετα;?</dt>
+<dd>Τα Ï€Ïόσθετα σας επιτÏέπουν να Ï€Ïοσθέσετε χαÏακτηÏιστικά που δεν αποτελοÏν τμήμα της τυπικής εγκατάστασης. Τα θέματα αλλάζουν την εμφάνιση χωÏίς να επηÏεάζουν τη λειτουÏγικότητα. Τα Ï€Ïόσθετα αναζήτησης και τα λεξικά/πακέτα γλωσσών Ï€Ïοσθέτουν επιπÏόσθετες μηχανές αναζήτησης και υποστήÏιξη γλωσσών. Οι επεκτάσεις Ï€Ïοσθέτουν ακόμα πιο εξελιγμένα χαÏακτηÏιστικά στον πεÏιηγητή, μεÏικές απλά Ï€Ïοσθέτουν μια Ï€Ïόσθετη εÏγαλειοθήκη ενώ άλλες Ï€Ïοσθέτουν ένα ευÏÏ Ï†Î¬ÏƒÎ¼Î± νέων χαÏακτηÏιστικών.</dd>
+
+<dt>Είναι εÏκολη η εγκατάσταση των Ï€Ïόσθετων;</dt>
+<dd>Îαι! Η εγκατάσταση των Ï€Ïόσθετων είναι Ï€Î¿Î»Ï ÎµÏκολη. Είναι γενικά Ï€Î¿Î»Ï Î¼Î¹ÎºÏότεÏα σε μέγεθος από ένα κανονικό Ï€ÏόγÏαμμα και η λήψη τους είναι ταχÏτατη. Αν κάποιο δεν σας αÏέσει, είναι επίσης Ï€Î¿Î»Ï ÎµÏκολο να το αφαιÏέσετε ή να το απενεÏγοποιήσετε. Επίσης, αν υπάÏχει διαθέσιμη ενημέÏωση για κάποιο, ο Firefox θα σας ειδοποιήσει και θα μποÏείτε να την εγκαταστήσετε απλά με ένα κλικ.</dd>
+
+<dt>Πως μποÏÏŽ να διαχειÏιστώ ένα Ï€Ïόσθετο;</dt>
+<dd>Στον Firefox, πηγαίνετε στο Î¼ÎµÎ½Î¿Ï Â«Î•Ïγαλεία» και μετά στο «ΠÏόσθετα» για να διαχειÏιστείτε επεκτάσεις και θέματα. Αν η επέκταση σας έχει δικές της επιλογές, μποÏείτε να τις δείτε στο τμήμα επεκτάσεων του διαχειÏιστή Ï€Ïόσθετων. Από τον διαχειÏιστή, μποÏείτε επίσης να απενεÏγοποιήσετε ή να αφαιÏέσετε Ï€Ïόσθετα. Τα λεξικά εγκαθίστανται σαν επεκτάσεις. Τα Ï€Ïόσθετα αναζήτησης μποÏείτε να τα διαχειÏιστείτε από την εÏγαλειοθήκη αναζήτησης.</dd>
+
+<dt>Κάνουν πιο αÏγό τον Firefox;</dt>
+<dd>Στις πεÏισσότεÏες πεÏιπτώσεις, τα Ï€Ïόσθετα εν Ï€ÏοκαλοÏν αισθητή επιβÏάδυνση στον Firefox. Επειδή όμως είναι κι αυτά Ï€ÏογÏάμματα, μποÏεί να επηÏεάσουν τις επιδόσεις του Firefox ανάλογα με τις Ïυθμίσεις του συστήματος σας. Αν υποψιάζεστε ότι κάποιο Ï€Ïόσθετο επηÏεάζει την εκτέλεση του Firefox στο μηχάνημα σας, δοκιμάστε να το απενεÏγοποιήσετε.</dd>
+
+<dt>Γιατί να θέλω να απενεÏγοποιήσω ένα Ï€Ïόσθετο;</dt>
+<dd>Η απενεÏγοποίηση ενός Ï€Ïόσθετου το εμποδίζει να φοÏτωθεί όταν ξεκινάει ο Firefox, αλλά δεν αφαιÏεί το ίδιο το Ï€Ïόσθετο ή τις Ïυθμίσεις του. Όταν το ενεÏγοποιήσετε ξανά, θα επανέλθει όπως ακÏιβώς ήταν όταν το απενεÏγοποιήσατε. Η απενεÏγοποίηση είναι η καλÏτεÏη λÏση όταν δεν θέλετε να χÏησιμοποιήσετε κάποιο Ï€Ïόσθετο αλλά οÏτε και να το αφαιÏέσετε εντελώς.</dd>
+
+<dt>Πως μποÏÏŽ να πάÏω αντίγÏαφα ασφαλείας των Ï€Ïόσθετων που έχω εγκαταστήσει;</dt>
+<dd>ΜποÏείτε να πάÏετε αντίγÏαφο ασφαλείας του καταλόγου Ï€Ïοφίλ χÏήστη, το οποίο θα πεÏιλαμβάνει τα Ï€Ïόσθετα σας. Δείτε το Ï€Ïόσθετο FEBE </dd>
+</dl>
+
+<h2>ΕÏωτήσεις σχετικές με τις σελίδες</h2>
+<dl class="faq">
+<dt>Βλέπω πολλά Ï€Ïόσθετα με παÏόμοιες δυνατότητες. Πως θα αποφασίσω ποίο είναι καλÏτεÏο;</dt>
+<dd>Σε γενικές γÏαμμές,μποÏείτε να δείτε τις βαθμολογίες και τον αÏιθμό λήψεων για να πάÏετε μια ιδέα. Τα καλά Ï€Ïόσθετα έχουν συνήθως πεÏισσότεÏες λήψεις από τα αδιάφοÏα. Επίσης, μποÏείτε Ï€Î¿Î»Ï ÎµÏκολα να εγκαταστήσετε δÏο η πεÏισσότεÏα παÏόμοια Ï€Ïόσθετα για να τα δοκιμάσετε και να διαλέξετε το ένα ή να τα χÏησιμοποιήσετε και όλα!</dd>
+
+<dt>Î’Ïήκα ένα Ï€Î¿Î»Ï Ï‡Ïήσιμο Ï€Ïόσθετο κάπου αλλά αναφέÏει ότι είναι συμβατό μόνο με τις εκδόσεις του Firefox 2.x. ΜποÏÏŽ να το χÏησιμοποιήσω με τον Firefox 3.x;</dt>
+<dd>Γενικά όχι. Οι εκδόσεις του Firefox 3.x έχουν μεγάλο αÏιθμό νέων χαÏακτηÏιστικών και η συντÏιπτική πλειοψηφία των δημιουÏγών Ï€ÏοσφέÏουν υποστήÏιξη για τις εκδόσεις 3.x. Αν το Ï€Ïόσθετο σας υποστηÏίζει μόνο τον Firefox 2, δοκιμάστε μια αναζήτηση για τον τίτλο του. Σε πολλές πεÏιπτώσεις θα βÏείτε μια νέα έκδοση που υποστηÏίζει τον Firefox 3 με τον ίδιο ή παÏαπλήσιο τίτλο.</dd>
+
+<dt>Εγκατέστησα ένα νέο θέμα αλλά θα ήθελα να επιστÏέψω στο αÏχικό του Firefox. Πως μποÏÏŽ να το κάνω;</dt>
+<dd>Από το Î¼ÎµÎ½Î¿Ï Â«Î•Ïγαλεία» του Firefox, πηγαίνετε στα «ΠÏόσθετα». Κάντε κλικ στο τμήμα «Θέματα» και από 'κει μποÏείτε να επιλέξετε το αÏχικό ή οποιοδήποτε άλλο θέμα έχετε εγκαταστήσει.</dd>
+
+<dt>Αν υπάÏχει κάποιο Ï€Ïόβλημα με ένα από τα Ï€Ïόσθετα μου, θα Ï€Ïέπει να επικοινωνήσω με το ίδÏυμα Mozilla;</dt>
+<dd>Τα Ï€Ïόσθετα, εκτός ελαχίστων εξαιÏέσεων, δημιουÏγοÏνται από την κοινότητα και όχι από το ίδÏυμα Mozilla. Το καλÏτεÏο που έχετε να κάνετε είναι να επικοινωνήσετε με τον δημιουÏγό τους για τα εÏωτήματα σας. Για να βÏείτε πληÏοφοÏίες επικοινωνίας με τους δημιουÏγοÏÏ‚, κάντε κλικ στο όνομα τους δίπλα από τη γÏαμμή που εμφανίζεται το «Από:» στη σελίδα του Ï€Ïόσθετου.</dd>
+
+<dt>Πως γίνεται η αξιολόγηση των Ï€Ïόσθετων;</dt>
+<dd>Τα δημοσιευμένα Ï€Ïόσθετα αξιολογοÏνται από την αφοσιωμένη και ταλαντοÏχα ομάδα συντακτών μας. ΑξιολογοÏν τον κώδικα όλων των Ï€Ïόσθετων που βÏίσκονται στο δημόσιο χώÏο και επίσης δοκιμάζουν τα Ï€Ïόσθετα για να εξασφαλίσουν την ακÏίβεια στις πεÏιγÏαφές τους.</dd>
+
+<dt>Αναβάθμισα το σÏστημα μου με τον Firefox 3.5 και κάποιο Ï€Ïόσθετο δεν λειτουÏγεί, γιατί;</dt>
+<dd>Τα πεÏισσότεÏα από τα Ï€Ïόσθετα είναι ήδη συμβατά με τον Firefox 3.5 και καθημεÏινά γίνονται συμβατά ακόμη πιο πολλά. Αν το Ï€Ïόσθετο σας δοÏλευε με τον Firefox 3.0 αλλά δεν δουλεÏει με τον 3.5, πιθανότατα οι δημιουÏγοί του ήδη ετοιμάζουν μια ενημέÏωση. Όταν θα είναι έτοιμη, θα σας ειδοποιήσει ο Firefox για την ενημέÏωση.</dd>
+
+<dt id="experimental-addons">Τι είναι τα πειÏαματικά Ï€Ïόσθετα;</dt>
+<dd>
+ <p>Τα πειÏαματικά Ï€Ïόσθετα είναι νέα Ï€Ïόσθετα που δεν έχουν υποστεί ακόμα αξιολόγηση από το κοινό μας. Πολλά από αυτά τα Ï€Ïόσθετα μποÏεί να είναι ακόμα στο στάδιο του Ï€Ïότυπου. Εφόσον δεν έχουν ακόμα δοκιμαστεί από την ομάδα συντακτών μας, τα χαÏακτηÏιστικά, οι επιδόσεις και η ποιότητα τους μποÏεί να είναι τέτοια που να αντιστοιχοÏν σε δοκιμαστικές εκδόσεις alpha, beta ή και Ï€Ïο-εκδόσεις.</p>
+ <p>ΠÏέπει να εγκαθιστώνται με Ï€Ïοσοχή εφόσον δεν έχουν δοκιμαστεί από κάποιον συντάκτη και μποÏεί να Ï€Ïοκαλέσουν Ï€Ïοβλήματα στο σÏστημα σας.</p>
+</dd>
+
+<dt id="recognizing-experimental-addons">Πως μποÏÏŽ να αναγνωÏίσω τα πειÏαματικά Ï€Ïόσθετα;</dt>
+<dd>Τα πειÏαματικά Ï€Ïόσθετα σημειώνονται με την ετικέτα «ΠειÏαματικό» και Ï€Ïοβάλουν μια ειδοποίηση κατά την εγκατάσταση τους.</dd>
+
+<dt id="recommended-addons">Τι είναι τα συνιστώμενα και τα Ï€Ïοβεβλημένα Ï€Ïόσθετα;</dt>
+<dd>Η ομάδα του AMO συστήνει ένα σÏνολο Ï€Ïόσθετων που το απαÏτίζουν μεÏικά από τα καλÏτεÏα Ï€Ïόσθετα όσο αφοÏά τη χÏησιμότητα και τη γενική εικόνα τους. Αυτά τα συνιστώμενα Ï€Ïόσθετα εμφανίζονται στις ξεχωÏιστές σελίδες των κατηγοÏιών. ΜεÏικά από αυτά τα Ï€Ïόσθετα εμφανίζονται επίσης εναλλάξ στην αÏχική σελίδα του AMO. Δεν Ï€Ïόκειται σε καμία πεÏίπτωση για μια αναλυτική λίστα που πεÏιλαμβάνει τα πάντα αλλά την ανανεώνουμε σε μηνιαία βάση για να Ï€Ïοβάλουμε στους χÏήστες μας νέα σÏνολα Ï€Ïόσθετων. ΜεÏικά από τα στοιχεία που λαμβάνουμε υπόψιν μας όταν συνιστοÏμε Ï€Ïόσθετα:, ποιότητα, δημοτικότητα, μοναδικότητα και το αν έχουν ήδη Ï€Ïοβληθεί σαν συνιστώμενα στο παÏελθόν.</dd>
+
+</dl>
+
+<script src="https://getsatisfaction.com/mozilla/widgets/javascripts/500b6b4141/widgets.js" type="text/javascript"></script>
+<script src="https://getsatisfaction.com/mozilla/topics.widget?callback=gsfnTopicsCallback&amp;limit=5&amp;product=mozilla_mozilla_add_ons&amp;sort=last_active_at&amp;style=topics" type="text/javascript"></script>
diff --git a/site/app/locale/el/pages/nomination.thtml b/site/app/locale/el/pages/nomination.thtml
new file mode 100644
index 0000000..bb8db72
--- /dev/null
+++ b/site/app/locale/el/pages/nomination.thtml
@@ -0,0 +1,10 @@
+<p>Ένα Ï€Ïόσθετο που βÏίσκεται Ï€ÏοσωÏινά στο sandbox μποÏεί να θέσει υποψηφιότητα για να μπει στο δημόσιο χώÏο και να είναι διαθέσιμο σε όλους τους χÏήστες Î±Ï†Î¿Ï Î±Î¾Î¹Î¿Î»Î¿Î³Î·Î¸ÎµÎ¯ από κάποιο συντάκτη. Για καλÏτεÏα αποτελέσματα, να σημειωθοÏν τα παÏακάτω:</p>
+<ul>
+ <li>Εικόνες Ï€Ïοεπισκόπησης απαιτοÏνται για υποβολή θεμάτων και συνιστοÏμε την υποβολή τους και για όλους τους άλλους Ï„Ïπους Ï€Ïόσθετων.</li>
+ <li>Το Ï€Ïόσθετο θα Ï€Ïέπει να έχει παÏαμείνει για αÏκετό διάστημα στο sandbox ώστε να αποκτήσει σχόλια και αξιολόγηση από έμπειÏους χÏήστες. <b>Η αξιολόγηση είναι απαÏαίτητη για να μπει στο δημόσιο χώÏο.</b></li>
+ <li>Τα Ï€Ïόσθετα του δημόσιου χώÏου έχουν υψηλότεÏα κÏιτήÏια ποιότητας από αυτά του sandbox και θα Ï€Ïέπει να συντελοÏν στη βελτίωση του παγκόσμιου ιστοÏ.</li>
+ <li>Όλα τα κÏιτήÏια για την υποψηφιότητα είναι διαθέσιμα στην <a href="%s">πολιτική Ï€Ïόσθετων</a>.</li>
+</ul>
+<p>Αν το Ï€Ïόσθετό σας είναι συμβατό με τα παÏαπάνω κÏιτήÏια, μποÏείτε να το θέσετε σε υποψηφιότητα συμπληÏώνοντας το παÏακάτω πεδίο. Θα ενημεÏωθείτε με μήνυμα ηλ. ταχυδÏομείου για την κατάσταση της υποψηφιότητας.</p>
+
+<p>Για να θέσετε το Ï€Ïόσθετό σας σε υποψηφιότητα, παÏακαλοÏμε πεÏιγÏάψτε πως έχει ελεγχθεί (συμπεÏιλαμβάνοντας το ότι δεν παÏουσιάζει σφάλματα και Ï€Ïοειδοποιήσεις) και για ποιο λόγο είναι χÏήσιμο στο ευÏÏτεÏο κοινό του δικτÏου. ΜποÏείτε επίσης να συμπεÏιλάβετε δεσμοÏÏ‚ από αξιολογήσεις Ï„Ïίτων για το Ï€Ïόσθετό σας.</p>
diff --git a/site/app/locale/el/pages/reviewguide.thtml b/site/app/locale/el/pages/reviewguide.thtml
new file mode 100644
index 0000000..7d495a0
--- /dev/null
+++ b/site/app/locale/el/pages/reviewguide.thtml
@@ -0,0 +1,85 @@
+<h1>Οδηγίες σÏνταξης αξιολόγησης</h1>
+<p>Οι αξιολογήσεις Ï€Ïόσθετων Ï€ÏοσφέÏουν στους χÏήστες του ιστότοπου Ï€Ïόσθετων τη δυνατότητα να μοιÏαστοÏν τις απόψεις τους
+για τα Ï€Ïόσθετα που έχουν εγκαταστήσει και χÏησιμοποιοÏν. Οι συντάκτες μας διατηÏοÏν το δικαίωμα
+να απαγοÏεÏσουν και να αφαιÏέσουν αξιολογήσεις που δε συμμοÏφώνονται με τις παÏακάτω οδηγίες.</p>
+
+<div class="corner-box">
+ <h2>ΜεÏικές συμβουλές για τη σÏνταξη μιας καλής αξιολόγησης</h2>
+
+<h3><b>Τι να κάνετε:</b></h3>
+<ul>
+<li>Αν έχετε τη δυνατότητα, υποβάλετε την αξιολόγησή σας στα αγγλικά ώστε να ωφεληθοÏν απ' αυτή όσο το δυνατό πεÏισσότεÏοι χÏήστες.</li>
+<li>ΓÏάψτε σα να διηγήστε σε ένα φίλο σας την εμπειÏία σας με το Ï€Ïόσθετο.</li>
+<li>ΦÏοντίστε ώστε το πεÏιεχόμενο να είναι πεÏιεκτικό και ευκολονόητο.</li>
+<li>Δώστε συγκεκÏιμένες και χÏήσιμες λεπτομέÏειες. Για παÏάδειγμα:
+<ul>
+ <li>ΛειτουÏγεί το Ï€Ïόσθετο όπως νομίζετε ότι θα έπÏεπε;</li>
+ <li>Ποια χαÏακτηÏιστικά του σας άÏεσαν ή όχι;</li>
+ <li>Είναι χÏήσιμο;</li>
+ <li>Είναι εÏχÏηστο;</li>
+ <li>Θα συνεχίσετε να το χÏησιμοποιείτε;</li>
+</ul></li>
+
+<li>Ξαναδιαβάστε την αξιολόγησή σας Ï€Ïιν την υποβάλετε για να αποφÏγετε ενοχλητικά τυπογÏαφικά και οÏθογÏαφικά λάθη.</li>
+
+<li>ΑποφÏγετε τις αναφοÏές σε τοπικοÏÏ‚ ή Ï€ÏοσωÏινοÏÏ‚ πόÏους, γιατί οι αξιολογήσεις παÏαμένουν στον ιστότοπο για πάÏα Ï€Î¿Î»Ï ÎºÎ±Î¹ÏÏŒ.</li>
+</ul>
+
+<h3><b>Τι να μην κάνετε:</b></h3>
+<ul>
+<li>Μην υποβάλετε απλουστευμένες αξιολογήσεις όπως «Θαυμάσιο!», «ΦοβεÏÏŒ!» ή «ΆχÏηστο» χωÏίς πεÏαιτέÏω αιτιολόγηση.</li>
+<li>Μην υποβάλετε αναφοÏές σφαλμάτων ή Ï€Ïοβλημάτων μέσα σε αξιολογήσεις. ΧÏησιμοποιήστε τις διαθέσιμες επιλογές υποστήÏιξης κάθε Ï€Ïόσθετου για τέτοια θέματα.</li>
+<li>Μην υποβάλετε αξιολογήσεις για Ï€Ïόσθετα που δεν έχετε χÏησιμοποιήσει Ï€Ïοσωπικά.</li>
+<li>Μη χÏησιμοποιείτε Ï€Ïοσβλητικές, σεξιστικές ή εÏιστικές εκφÏάσεις.</li>
+<li>Μην εισάγετε κώδικα HTML, δεσμοÏÏ‚ σε κακόβουλο λογισμικό, πηγαίο κώδικα ή τμήματα κώδικα σε παÏάθεση. Οι αξιολογήσεις θα Ï€Ïέπει να είναι γÏαμμένες σε απλό κείμενο.</li>
+<li>Μη δηλώνετε ψευδή στοιχεία για τα Ï€Ïόσθετα και μη μειώνετε ή Ï€Ïοσβάλετε Ï€Ïοσωπικά τους δημιουÏγοÏÏ‚ τους.</li>
+<li>Μη χÏησιμοποιείτε τις αξιολογήσεις για να ζητήσετε υποστήÏιξη από το Ï€Ïόσθετο για συγκεκÏιμένες εκδόσεις του Firefox (ή άλλης εφαÏμογής).</li>
+<li>Μη συμπεÏιλαμβάνετε στην αξιολόγηση τη διεÏθυνση ηλεκτÏÎ¿Î½Î¹ÎºÎ¿Ï Ï„Î±Ï‡Ï…Î´Ïομείου σας, τον αÏιθμό του τηλεφώνου σας ή άλλες Ï€Ïοσωπικές σας πληÏοφοÏίες.</li>
+<li>Μην υποβάλετε αξιολογήσεις για ένα Ï€Ïόσθετο που έχει δημιουÏγηθεί ή αντιπÏοσωπεÏεται από εσάς τους ίδιους ή τους εÏγοδότες σας.</li>
+</ul>
+</div>
+
+<div class="corner-box">
+ <h2>Οδηγίες για τη βαθμολόγηση Ï€Ïόσθετων</h2>
+
+<p>Οι βαθμολογήσεις των Ï€Ïόσθετων θα Ï€Ïέπει να είναι δίκαιες και να Ï€ÏοσφέÏουν μια συνολική ένδειξη ποιότητας
+και χÏησιμότητας. Μη δώσετε απλά 5 αστέÏια αν σας αÏέσει ή 1 αστέÏι αν δεν σας αÏέσει.
+Η συνεπής βαθμολόγηση είναι ένα σημαντικό τμήμα κάθε αξιολόγησης.</p>
+
+<ul>
+<li><b>5 αστέÏια: ΕξαιÏετικό.</b> Δεν κάνει απλά όσα υπόσχεται αλλά είναι
+και Ï€Î¿Î»Ï Ï€Î¹Î¿ χÏήσιμο από πολλά άλλα Ï€Ïόσθετα. Αυτό το Ï€Ïόσθετο έχει τις Ï€Ïοϋποθέσεις να σας
+κάνει να το χÏησιμοποιείτε συχνά και να το συστήνετε και σε άλλους.</li>
+<li><b>4 αστέÏια: Καλό.</b> ΧÏήσιμο και εÏχÏηστο αν και όχι απαÏαίτητα μοναδικό. Αυτό το
+Ï€Ïόσθετο θα το συστήνατε αλλά όχι σε όλους.</li>
+<li><b>3 αστέÏια: ΜέτÏιο.</b> Ίσως έχει κάποια σχεδιαστικά Ï€Ïοβλήματα και/ή να απουσιάζουν κάποια χαÏακτηÏιστικά.
+Τα όποια Ï€Ïοβλήματα όμως δεν είναι τόσο σημαντικά ώστε να αποτÏέψετε άλλους από το να το δοκιμάσουν, ενώ
+μεÏικοί χÏήστες ίσως το βÏουν Ï€Î¿Î»Ï Ï‡Ïήσιμο. Συστήνεται μόνο για όσους το χÏειάζονται και θέλουν να το δοκιμάσουν.</li>
+<li><b>2 αστέÏια: Φτωχό.</b> Το Ï€Ïόσθετο είναι χαμηλής ποιότητας, δÏσχÏηστο, ή απλά δεν κάνει
+όσα υπόσχεται. Συστήνετε την αποφυγή του αλλά με την υποσημείωση πως μποÏεί να είναι στοιχειωδώς χÏήσιμο για μεÏικοÏÏ‚ χÏήστες.</li>
+<li><b>1 αστέÏι: Κακό.</b> Το Ï€Ïόσθετο είτε δεν λειτουÏγεί σωστά, είτε δεν έχει κάποια συγκεκÏιμένη χÏήση.
+Δεν υπάÏχει λόγος να το δοκιμάσει κάποιος χÏήστης και συστήνετε την αποφυγή του.</li>
+</ul>
+
+<p>Δεν είναι λάθος να δώσετε σε ένα Ï€Ïόσθετο μια τέλεια ή απαξιωτική βαθμολογία, απλά
+σας παÏακαλοÏμε να αιτιολογήσετε γιατί το κάνετε αυτό. Τα αστέÏια δεν σημαίνουν τίποτα, αν δεν μας πείτε γιατί τα δίνετε.</p>
+</div>
+
+<div class="corner-box">
+ <h2>Συχνές εÏωτήσεις για τις αξιολογήσεις</h2>
+
+<h3>Πώς μποÏÏŽ να αναφέÏω μια Ï€Ïοβληματική αξιολόγηση;</h3>
+<p>ΠαÏακαλοÏμε να σημειώνετε αμφισβητοÏμενες αξιολογήσεις κάνοντας κλικ στο αναδυόμενο Î¼ÎµÎ½Î¿Ï Â«Î‘Î½Î±Ï†Î¿Ïά αξιολόγησης...»
+ώστε να υποβληθεί σε έλεγχο. Οι συντάκτες μας θα τη συγκÏίνουν με τις οδηγίες υποβολής και θα αποφασίσουν αν θα διαγÏαφεί ή θα παÏαμείνει στον ιστότοπο.</p>
+
+<h3>Είμαι ο δημιουÏγός ενός Ï€Ïόσθετου, μποÏÏŽ να απαντήσω σε μια αξιολόγηση;</h3>
+<p>Îαι, οι δημιουÏγοί μποÏοÏν να δώσουν μία και μοναδική απάντηση σε κάθε αξιολόγηση.
+ΠεÏισσότεÏες απαντήσεις ή πεÏαιτέÏω διάλογος θα Ï€Ïέπει να μεταφεÏθοÏν σε κάποιο φόÏουμ υποστήÏιξης ή σε ομάδα συζητήσεων.</p>
+
+<h3>Είμαι δημιουÏγός ενός Ï€Ïόσθετου, μποÏÏŽ να διαγÏάψω μια αÏνητική αξιολόγηση ή βαθμολογία;</h3>
+<p>Γενικά όχι. Αν όμως η αξιολόγηση δεν συμμοÏφώνεται με τις παÏαπάνω οδηγίες,
+μποÏείτε να κάνετε κλικ στο αναδυόμενο Î¼ÎµÎ½Î¿Ï Â«Î‘Î½Î±Ï†Î¿Ïά αξιολόγησης...» και να την ελέγξει ένας συντάκτης μας.
+Αν μια αξιολόγηση πεÏιελάμβανε παÏάπονα που δεν ισχÏουν μετά από μια νέα έκδοση
+του Ï€Ïόσθετου, είναι πιθανόν να διαγÏάψουμε την αξιολόγηση. Υποβάλετε το αίτημά σας με λεπτομέÏειες
+στη διεÏθυνση amo-editors@mozilla.org <mailto:amo-editors@mozilla.org>.</p>
+</div>
diff --git a/site/app/locale/el/pages/sandbox.thtml b/site/app/locale/el/pages/sandbox.thtml
new file mode 100644
index 0000000..c4c0dd5
--- /dev/null
+++ b/site/app/locale/el/pages/sandbox.thtml
@@ -0,0 +1,13 @@
+<h1>ΣÏστημα επισκοπήσεων Sandbox</h1>
+<h2>Τι είναι το sandbox;</h2>
+<p>Το sandbox είναι ένα τμήμα όπου έμπειÏοι χÏήστες δοκιμάζουν Ï€Ïόσθετα Ï€Ïιν αυτά αξιολογηθοÏν για γενική χÏήση. Για να έχετε Ï€Ïόσβαση στο sandbox, θα Ï€Ïέπει να το ενεÏγοποιήσετε από τις Ïυθμίσεις του λογαÏÎ¹Î±ÏƒÎ¼Î¿Ï ÏƒÎ±Ï‚. Η εγκατάσταση Ï€Ïοσθέτων από το sandbox θα Ï€Ïέπει να γίνεται με Ï€Ïοσοχή καθώς δεν έχουν αξιολογηθεί από κάποιο συντάκτη και μποÏεί να Ï€Ïοκαλέσουν Ï€Ïοβλήματα στον υπολογιστή σας.</p>
+
+<h2>Πως μποÏÏŽ να Ï€Ïοωθήσω το Ï€Ïόσθετό μου στο τμήμα του δημόσιου χώÏου;</h2>
+<!-- To localize the flowchart image, see http://wiki.mozilla.org/Update:Remora_Sandbox_Flowchart -->
+<div style="text-align: center;">%s</div>
+<ol>
+ <li><b>Υποβάλετε το Ï€Ïόσθετό σας μέσα από τον πίνακα ελέγχου δημιουÏγών.</b> Το Ï€Ïόσθετό σας θα εμφανιστεί άμεσα στο τμήμα «Sandbox» του Mozilla Add-ons, όπου έμπειÏοι χÏήστες θα το δοκιμάσουν και θα παÏέχουν σχόλια. Για να έχετε Ï€Ïόσβαση στο sandbox, θα Ï€Ïέπει να το ενεÏγοποιήσετε από τις Ïυθμίσεις του λογαÏÎ¹Î±ÏƒÎ¼Î¿Ï ÏƒÎ±Ï‚.</li>
+ <li><b>Υποβάλετε υποψηφιότητα για το δημόσιο χώÏο.</b> Στον πίνακα ελέγχου δημιουÏγοÏ, υπάÏχει ένας δεσμός για να θέσετε σε υποψηφιότητα το Ï€Ïόσθετό σας. Î‘Ï†Î¿Ï Ï„ÎµÎ¸ÎµÎ¯ σε υποψηφιότητα, το Ï€Ïόσθετό σας θα Ï€Ïοστεθεί στην ουÏά αναμονής υποψήφιων Ï€Ïόσθετων για αξιολόγηση από συντάκτη.</li>
+ <li><b>Κάποιος συντάκτης αξιολογεί το Ï€Ïόσθετό σας.</b> Ένας από τους συντάκτες του Mozilla Add-ons θα εγκαταστήσει το Ï€Ïόσθετό σας και θα εξετάσει τη λειτουÏγία του. Ο συντάκτης αυτός θα αξιολογήσει επίσης τα αποτελέσματα από τις δοκιμές στο sandbox.</li>
+ <li><b>Το Ï€Ïόσθετό σας Ï€Ïοωθείται στο δημόσιο χώÏο ή παÏαμένει στο sandbox.</b> Ο συντάκτης είτε θα Ï€Ïοωθήσει το Ï€Ïόσθετό σας στο δημόσιο χώÏο είτε θα το αφήσει στο sandbox. Αν παÏαμείνει στο sandbox, μποÏείτε να υποβάλετε ξανά αίτημα για υποψηφιότητα Î±Ï†Î¿Ï ÎºÎ¬Î½ÎµÏ„Îµ τις αλλαγές που θα Ï€Ïοτείνει ο συντάκτης στα σχόλιά του. Αν Ï€Ïοωθηθεί στο δημόσιο χώÏο, οι μελλοντικές εκδόσεις του Ï€Ïοσθέτου σας θα εμφανίζονται στο sandbox ώσπου να αξιολογηθοÏν από συντάκτη και να Ï€ÏοωθηθοÏν στο δημόσιο χώÏο. Î‘Ï†Î¿Ï Ï„Î¿ Ï€Ïόσθετό σας μπει για Ï€Ïώτη φοÏά στο δημόσιο χώÏο, δεν χÏειάζεται να υποβάλετε υποψηφιότητα ξανά γι' αυτό, οι μελλοντικές εκδόσεις θα μπαίνουν αυτόματα στην ουÏά αναμονής για αξιολόγηση.</li>
+</ol> \ No newline at end of file
diff --git a/site/app/locale/el/pages/statistics_help.thtml b/site/app/locale/el/pages/statistics_help.thtml
new file mode 100644
index 0000000..fdab65f
--- /dev/null
+++ b/site/app/locale/el/pages/statistics_help.thtml
@@ -0,0 +1,7 @@
+<h3>Βοήθεια</h3>
+<p>Το ταμπλό στατιστικών εμφανίζει δεδομένα ping λήψεων και ενημεÏώσεων που έχουν πεÏισυλλεγεί για το Ï€Ïόσθετο σας.</p>
+<h4>Λήψεις</h4>
+<p>Οι μετÏητές λήψεων ενημεÏώνωνται καθημεÏινά και πεÏιλαμβάνουν μόνο λήψεις και όχι ενημεÏώσεις.</p>
+
+<h4>Ping ενημεÏώσεων</h4>
+<p>Τα Ï€Ïόσθετα που η λήψη τους έχει γίνει από αυτό τον ιστότοπο ελέγχουν για ενημεÏώσεις μια φοÏά καθημεÏινά και ο συνολικός αÏιθμός των ping από αυτοÏÏ‚ τους ελέγχους αντιπÏοσωπεÏει τους ενεÏγοÏÏ‚ καθημεÏινοÏÏ‚ χÏήστες. Οι ενεÏγοί καθημεÏινοί χÏήστες (ΕΚΧ) μποÏοÏν να αναλυθοÏν ανάλογα με την έκδοση του Ï€Ïόσθετου, το λειτουÏγικό σÏστημα, την κατάσταση του Ï€Ïόσθετου και την εφαÏμογή. Τα δεδομένα αυτά καταγÏάφονται Ï€Ïος το παÏόν για μια ημέÏα κάθε εβδομάδας, κάθε ΤετάÏτη.</p>
diff --git a/site/app/locale/el/pages/submission_help.thtml b/site/app/locale/el/pages/submission_help.thtml
new file mode 100644
index 0000000..731f05d
--- /dev/null
+++ b/site/app/locale/el/pages/submission_help.thtml
@@ -0,0 +1,35 @@
+<h1>Βοήθεια για την υποβολή</h1>
+Τα απαιτοÏμενα πεδία είναι <b>έντονα</b>. Τα Ï€ÏοαιÏετικά πεδία είναι <i>πλάγια</i>.
+<h2 id="step1">Βήμα Ï€Ïώτο: Αποστολή αÏχείου</h2>
+<ul class="submissionHelp">
+ <li><span class="required">ΤÏπος Ï€Ïόσθετου</span> - Ο Ï„Ïπος του Ï€Ïόσθετου καταχωÏείται αυτόματα με βάση το αÏχείο που αποστέλλεται. Κανονικά δε χÏειάζεται να αλλάξετε αυτό το πεδίο.</li>
+ <li><span class="required">ΑÏχείο Ï€Ïόσθετου</span> - ΟλόκληÏο το πακέτο αÏχείων του Ï€Ïοσθέτου σας μαζί με το αÏχείο install.rdf. Αν το Ï€Ïόσθετο δουλεÏει μόνο σε μια πλατφόÏμα, η επιλογή της θα σας επιτÏέψει να αποστείλετε πολλαπλά αÏχεία ταυτόχÏονα.</li>
+ <li><span class="optional">ΑÏχείο εικονίδιου</span> - Το αÏχείο εικονιδίου εμφανίζεται δίπλα από το όνομα του Ï€Ïόσθετου στη σελίδα Ï€Ïοβολής του και εμφανίζεται επίσης και στο διάλογο εγκατάστασης. Οι διαστάσεις του αλλάζουν αυτόματα σε 32x32 πίξελ διατηÏώντας όμως το λόγο θέασης.</li>
+ <li><span class="required">ΑÏχική ÏÏθμιση γλώσσας</span> - Η αÏχική ÏÏθμιση γλώσσας ενός Ï€Ïόσθετου είναι η βασική ÏÏθμιση γλώσσας. Αν η επιλεγμένη ÏÏθμιση γλώσσας του χÏήστη δεν είναι διαθέσιμη για το Ï€Ïόσθετο, τότε θα χÏησιμοποιείται η αÏχική ÏÏθμιση γλώσσας.</li>
+ <li><span class="optional">ΠαÏάβλεψη αξιολόγησης πληÏοφοÏιών Ï„Ïέχουσας έκδοσης</span> - Αυτό το πεδίο θα εμφανιστεί, αν ενημεÏώνετε ένα ήδη υπάÏχον Ï€Ïόσθετο. Επιλέγοντας αυτό το πλαίσο, πάτε άμεσα στο Ï„Ïίτο βήμα όπου μποÏείτε να εισάγετε τις πληÏοφοÏίες για τη συγκεκÏιμένη έκδοση.</li>
+</ul>
+
+<h2 id="step2">Βήμα δεÏτεÏο: ΛεπτομέÏειες Ï€Ïοσθέτου</h2>
+<ul class="submissionHelp">
+ <li><span class="required">Όνομα</span> - Το όνομα του Ï€Ïόσθετου στην αÏχική ÏÏθμιση γλώσσας.</li>
+ <li><span class="required">ΔημιουÏγοί</span> - Όλοι οι χÏήστες που έχουν το δικαίωμα να επέμβουν στην κατάσταση του Ï€Ïόσθετου και που θα αναφέÏονται σαν δημιουÏγοί του στη σελίδα Ï€Ïοβολής του.</li>
+ <li><span class="required">ΚατηγοÏίες</span> - ΚατηγοÏίες που μποÏεί να καταταχθεί το Ï€Ïόσθετο.</li>
+ <li><span class="optional">ΑÏχική σελίδα</span> - Η αÏχική σελίδα του Ï€Ïοσθέτου στην αÏχική ÏÏθμιση γλώσσας.</li>
+ <li><span class="required">ΣÏνοψη</span> - Μια σÏντομη σÏνοψη του Ï€Ïόσθετου στην αÏχική ÏÏθμιση γλώσσας. Αυτό το πεδίο δέχεται μέχÏι 250 χαÏακτήÏες και θα εμφανίζεται στη σελίδα Ï€Ïοβολής του Ï€Ïόσθετου καθώς και στα αποτελέσματα αναζήτησης και στην πεÏιήγηση.</li>
+ <li><span class="required">ΠεÏιγÏαφή</span> - Μια πεÏιγÏαφή του Ï€Ïόσθετου στην αÏχική ÏÏθμιση γλώσσας. Η πεÏιγÏαφή θα εμφανίζεται στη σελίδα Ï€Ïοβολής του Ï€Ïοσθέτου κάτω από τη σÏνοψη.</li>
+ <li><span class="optional">Συμφωνητικό Αδειοδότησης Î¤ÎµÎ»Î¹ÎºÎ¿Ï Î§Ïήστη EULA</span> - Το συμφωνητικό αδειοδότησης Ï„ÎµÎ»Î¹ÎºÎ¿Ï Ï‡Ïήστη (End User License Agreement) το οποίο οι χÏήστες θα Ï€Ïέπει να αποδεχθοÏν Ï€Ïιν κάνουν λήψη του Ï€Ïοσθέτου - στην αÏχική ÏÏθμιση γλώσσας.</li>
+ <li><span class="optional">Πολιτική αποÏÏήτου</span> - Η πολιτική αποÏÏήτου του Ï€Ïοσθέτου στην αÏχική ÏÏθμιση γλώσσας. Η πολιτική αποÏÏήτου εξηγεί τι ακÏιβώς γίνεται με τυχόν Ï€Ïοσωπικά δεδομένα του Ï„ÎµÎ»Î¹ÎºÎ¿Ï Ï‡Ïήστη και εμφανίζεται δίπλα από το κουμπί εγκατάστασης στη σελίδα Ï€Ïοβολής του Ï€Ïοσθέτου. Επιπλέον πληÏοφοÏίες για το τι θα Ï€Ïέπει να πεÏιλαμβάνει η πολιτική αποÏÏήτου και αν το Ï€Ïόσθετό σας Ï€Ïέπει να έχει μια τέτοια, θα βÏείτε στο <a href="%s">Πολιτική αποÏÏήτου</a>.</li>
+ <li><span class="optional">Îα επιτÏέπεται στους χÏήστες να δουν τον πηγαίο κώδικα στο διαδίκτυο</span> - Η επιλογή Î±Ï…Ï„Î¿Ï Ï„Î¿Ï… πλαισίου θα επιτÏέψει στους χÏήστες να πεÏιηγηθοÏν στον πηγαίο κώδικα του Ï€Ïοσθέτου σας.</li>
+ <li><span class="optional">ΠÏοέκδοση</span> - Η επιλογή Î±Ï…Ï„ÏŒÏ Ï„Î¿Ï… πλαισίου σηματοδοτεί το γεγονός ότι Ï€Ïόκειται για Ï€Ïοέκδοση (ή έκδοση «beta»). Οι Ï€Ïοεκδόσεις Ï€Ïοσθέτων παÏαμένουν στο sandbox και δεν μποÏοÏν να είναι υποψήφιες για το δημόσιο χώÏο ώσπου να αφαιÏεθεί αυτή η σήμανση.</li>
+ <li><span class="optional">Συσχετιζόμενο με ιστοχώÏο</span> - Η επιλογή Î±Ï…Ï„Î¿Ï Ï„Î¿Ï… πλαισίου σημαίνει πως το Ï€Ïόσθετό σας είναι σχετικό με κάποιο ιστοχώÏο, Ï€.χ., αλλάζει την εμφάνιση ή Ï€Ïοβάλλει πεÏιεχόμενο από κάποιο ιστοχώÏο. Αυτό το πεδίο διευκολÏνει τους συντάκτες και μποÏεί να χÏησιμοποιηθεί σα φίλτÏο αναζήτησης στο μέλλον.</li>
+ <li><span class="optional">Αυτό το Ï€Ïόσθετο απαιτεί επιπÏόσθετο λογισμικό</span> - Η επιλογή Î±Ï…Ï„Î¿Ï Ï„Î¿Ï… πλαισίου σημαίνει πως το Ï€Ïόσθετό σας απαιτεί επιπÏόσθετο λογισμικό. Αυτό το πεδίο διευκολÏνει τους συντάκτες και μποÏεί να χÏησιμοποιηθεί σα φίλτÏο αναζήτησης στο μέλλον.</li>
+</ul>
+
+<h2 id="step3">Βήμα Ï„Ïίτο: ΛεπτομέÏειες έκδοσης</h2>
+<ul class="submissionHelp">
+ <li><span class="required optional">Σημειώσεις έκδοσης</span> - Μια σÏνοψη ή λίστα με τις αλλαγές σ' αυτή την έκδοση. Είναι Ï€ÏοαιÏετικό για νέα Ï€Ïόσθετα αλλά απαιτείται για ενημεÏωμένες εκδόσεις ήδη υπαÏχόντων Ï€Ïόσθετων.</li>
+ <li><span class="optional">Σημειώσεις για συντάκτες αξιολόγησης</span> - Το πεδίο αυτό χÏησιμεÏει στην ανταλαγή πληÏοφοÏιών με τους συντάκτες που θα αξιολογήσουν το Ï€Ïόσθετό σας. ΠληÏοφοÏίες δοκιμών και ειδικές σημειώσεις θα Ï€Ïέπει να εισάγονται εδώ.</li>
+</ul>
+
+<h2 id="step4">Βήμα τέταÏτο: Τοπικοποίηση</h2>
+Εδώ μποÏείτε να πεÏάσετε τις μεταφÏάσεις των πεδίων σε όλες τις υποστηÏιζόμενες γλώσσες. Απλά κάντε κλικ σε μια γλώσσα και εισάγετε τη μετάφÏαση. \ No newline at end of file
diff --git a/site/app/locale/en_US/LC_MESSAGES/messages.mo b/site/app/locale/en_US/LC_MESSAGES/messages.mo
new file mode 100644
index 0000000..fbe5672
--- /dev/null
+++ b/site/app/locale/en_US/LC_MESSAGES/messages.mo
Binary files differ
diff --git a/site/app/locale/en_US/LC_MESSAGES/messages.po b/site/app/locale/en_US/LC_MESSAGES/messages.po
new file mode 100644
index 0000000..945c083
--- /dev/null
+++ b/site/app/locale/en_US/LC_MESSAGES/messages.po
@@ -0,0 +1,7248 @@
+# Language en-US translations for addons.mozilla.org package.
+# Copyright (C) 2009 THE addons.mozilla.org'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the addons.mozilla.org package.
+# Automatically generated, 2009.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: addons\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2009-01-16 11:45-0800\n"
+"PO-Revision-Date: 2009-02-26 15:08-0800\n"
+"Last-Translator: Automatically generated\n"
+"Language-Team: none\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#: views/addons/policy.thtml:98
+msgid "a_cancel_installation"
+msgstr "Cancel Installation"
+
+#. This is the text that appears on buttons to download add-ons.
+#. %$1s is an optional string that only appears if the add-on is only available for
+#. a certain platform. Examples: (Windows) or (Linux)
+#. Note that the parentheses are included in the string. :(
+#: views/elements/amo2009/install.thtml:126
+#: views/elements/amo2009/install.thtml:227
+#: views/elements/amo2009/install.thtml:257
+#: views/elements/amo2009/install.thtml:300
+#: views/elements/amo2009/install.thtml:312 views/elements/install.thtml:73
+#: views/elements/install.thtml:181 views/elements/install.thtml:205
+#: views/elements/install.thtml:248 views/elements/install.thtml:260
+#: views/addons/plugins.thtml:66 views/addons/plugins.thtml:76
+#: views/addons/plugins.thtml:86 views/addons/plugins.thtml:96
+#: views/addons/plugins.thtml:119
+#, php-format
+msgid "a_download"
+msgstr "Download Now %s"
+
+#: views/addons/policy.thtml:72
+msgid "a_eula_download"
+msgstr "Accept and Download"
+
+#: views/addons/policy.thtml:74
+msgid "a_eula_install"
+msgstr "Accept and Install"
+
+#: views/elements/header.thtml:76 views/elements/header.thtml:82
+#: views/api/api_addon.thtml:55 views/api/collections_feed.thtml:75
+#: views/sharing_api/addon.thtml:64
+msgid "a_header_public"
+msgstr "Public"
+
+#: views/elements/header.thtml:58 views/elements/header.thtml:75
+#: views/elements/header.thtml:80 views/api/api_addon.thtml:57
+#: views/api/collections_feed.thtml:77 views/sharing_api/addon.thtml:66
+msgid "a_header_sandbox"
+msgstr "Sandbox"
+
+#. %s is a date in the _('date') format
+#: views/elements/amo2009/homepage_addon.thtml:115
+#: views/elements/addon_listitem.thtml:122 views/elements/feature.thtml:106
+#: views/addons/display.thtml:104 views/addons/browse_thumbs.thtml:73
+msgid "addon_detail_last_updated"
+msgstr "Updated %s"
+
+#. %s is the version of the add-on. Example: 3.2a1
+#: views/elements/amo2009/addon_version_detail.thtml:51
+#: views/elements/addon_version_detail.thtml:51
+#, php-format
+msgid "addon_display_header_version"
+msgstr "Version %s"
+
+#: views/addons/browse_thumbs.thtml:80
+msgid "addon_downloads"
+msgstr "downloads"
+
+#: views/addons/display.thtml:147
+msgid "addon_downloads_total"
+msgstr "total downloads"
+
+#: views/elements/amo2009/homepage_addon.thtml:106
+#: views/elements/addon_listitem.thtml:115 views/elements/feature.thtml:101
+#: views/addons/category_landing.thtml:157 views/addons/display.thtml:146
+#: views/addons/browse_thumbs.thtml:80
+msgid "addon_downloads_weekly"
+msgstr "weekly downloads"
+
+#. %1 is the add-on count, %2 the category name
+#: views/addons/browse_thumbs.thtml:104 views/addons/browse.thtml:60
+#, php-format
+msgid "addon_list_category_totalcount"
+msgid_plural "addon_list_category_totalcount"
+msgstr[0] "%1$s add-on"
+msgstr[1] "%1$s add-ons"
+
+#: views/elements/amo2009/addon_list_options.thtml:103
+#: views/elements/pagination.thtml:67
+#: views/elements/addon_list_options.thtml:94
+msgid "addon_list_perpage"
+msgstr "per page"
+
+#: views/elements/amo2009/addon_list_options.thtml:84
+#: views/elements/addon_list_options.thtml:98
+msgid "addon_list_sortby"
+msgstr "Sort by:"
+
+#: views/helpers/addons_html.php:568 views/elements/amo2009/install.thtml:321
+#: views/elements/feature.thtml:89
+msgid "addon_listitem_flag_experimental"
+msgstr "experimental"
+
+#: views/helpers/addons_html.php:570
+msgid "addon_listitem_flag_recommended"
+msgstr "recommended"
+
+#. %1 is the add-on name, %2 is the platform
+#: views/pages/js_constants.js.thtml:66
+msgid "addon_not_available_for_platform"
+msgstr "%1$s is not available for %2$s."
+
+#. %1 is the add-on name
+#: views/addons/policy.thtml:101 views/addons/previews.thtml:60
+#: views/addons/versions.thtml:130 views/reviews/flag.thtml:61
+#: views/reviews/add.thtml:114 views/reviews/display.thtml:216
+#: views/reviews/review_added.thtml:57
+#, php-format
+msgid "addon_review_a_back_to_addon_x"
+msgstr "Back to %1$s..."
+
+#. %1 is the add-on name
+#: views/reviews/flag.thtml:60 views/reviews/add.thtml:113
+#: views/reviews/review_added.thtml:56
+#, php-format
+msgid "addon_review_a_back_to_reviews"
+msgstr "Back to the reviews..."
+
+#: views/reviews/add.thtml:85
+msgid "addon_review_add_rating_field"
+msgstr "Rating:"
+
+#: views/reviews/add.thtml:102
+msgid "addon_review_add_review_field"
+msgstr "Review:"
+
+#: views/reviews/add.thtml:107
+msgid "addon_review_add_submit"
+msgstr "Submit your review"
+
+#. %s is the name of the add-on
+#: views/reviews/add.thtml:51
+#, php-format
+msgid "addon_review_add_title"
+msgstr "Add a review for %s"
+
+#: views/reviews/add.thtml:78
+msgid "addon_review_add_title_field"
+msgstr "Title/Summary:"
+
+#: views/reviews/display.thtml:77 views/reviews/display.thtml:161
+msgid "addon_review_admin_delete"
+msgstr "Delete"
+
+#: views/reviews/display.thtml:76
+msgid "addon_review_author_reply_link"
+msgstr "Reply"
+
+#: views/reviews/delete.thtml:62
+msgid "addon_review_confirm_delete"
+msgstr "Are you sure you wish to delete this review?"
+
+#: views/reviews/delete.thtml:63
+msgid "addon_review_confirm_no"
+msgstr "No"
+
+#: views/reviews/delete.thtml:64
+msgid "addon_review_confirm_yes"
+msgstr "Yes"
+
+#: views/reviews/delete.thtml:48
+msgid "addon_review_delete_header"
+msgstr "Delete Review"
+
+#: controllers/reviews_controller.php:449
+msgid "addon_review_deleted_successfully"
+msgstr "Review deleted successfully."
+
+#. %s is the name of the add-on
+#: views/reviews/add.thtml:51
+#, php-format
+msgid "addon_review_edit_title"
+msgstr "Edit Review for %s"
+
+#. %1 is the count of characters entered as notes for the review flag reason.
+#: controllers/reviews_controller.php:539
+msgid "addon_review_flag_error_other_length"
+msgstr ""
+"Problem flagging review: Notes for flagged reviews are limited to between 10 "
+"and 100 characters; your character length was %1$s."
+
+#. Removing an extra comma
+#: views/reviews/review_added.thtml:53
+msgid "addon_review_in_moderation"
+msgstr ""
+"Please note: Before your review shows up on the public site it will be "
+"moderated by an editor."
+
+#: views/reviews/add.thtml:57
+msgid "addon_review_in_reply_to"
+msgstr "Developer reply to:"
+
+#. %1 is the review count, %2 is the nickname or full name of the user.
+#: views/reviews/display.thtml:131
+#, php-format
+msgid "addon_review_others_by_user"
+msgid_plural "addon_review_others_by_user"
+msgstr[0] "See %1$s previous review submitted by %2$s for this add-on."
+msgstr[1] "See %1$s previous reviews submitted by %2$s for this add-on."
+
+#. %1 is the add-on name
+#: controllers/reviews_controller.php:201
+#: controllers/reviews_controller.php:250
+#: controllers/reviews_controller.php:345
+#: controllers/reviews_controller.php:424
+#, php-format
+msgid "addon_review_pagetitle"
+msgstr "Reviews for %s"
+
+#. %1 is the user, %2 is the (localized) date
+#: views/reviews/display.thtml:160
+#, php-format
+msgid "addon_review_reply_on_x_by_y"
+msgstr "Reply by %1$s on %2$s"
+
+#: views/reviews/display.thtml:157
+msgid "addon_review_reply_prefix"
+msgstr "Developer Reply:"
+
+#: views/reviews/review_added.thtml:51
+msgid "addon_review_saved_successfully"
+msgstr "Your review was saved successfully. Thanks!"
+
+#: views/addons/display.thtml:354 views/reviews/display.thtml:72
+msgid "addon_reviewed_by_u_on_d"
+msgstr "by %1$s on %2$s"
+
+#. %1 is the user, %2 is the (localized) date, %3 is the rating
+#: views/editors/reviews_queue.thtml:57 views/editors/reviews_queue.thtml:68
+#: views/reviews/add.thtml:63 views/reviews/delete.thtml:54
+#, php-format
+msgid "addon_reviewed_on_x_rated_y"
+msgstr "by %1$s on %2$s (rated %3$s)"
+
+#: views/elements/amo2009/addon_version_detail.thtml:52
+#: views/elements/addon_version_detail.thtml:52
+msgid "addon_version_permalink"
+msgstr "Permanent link to this version"
+
+#. %1 is the current Application name (e.g. Firefox)
+#. %2 is the Application's version number
+#: views/addons/versions.thtml:140
+msgid "addon_versions_getlatestversion"
+msgstr "The most recent version compatible with %1$s %2$s"
+
+#: views/addons/display.thtml:447
+msgid "addons_author_addons_submit"
+msgstr "Go"
+
+#: views/elements/amo2009/homepage_addon.thtml:100
+#: views/elements/feature.thtml:95
+msgid "addons_author_tooltip"
+msgstr "View Author's Profile"
+
+#. %1 is the name of the Application (eg. Firefox)
+#: controllers/addons_controller.php:1296
+msgid "addons_browse_all_themes_title"
+msgstr "Browse all Themes :: %1$s Add-ons"
+
+#. %s is the name of the category
+#: controllers/addons_controller.php:1016
+#, php-format
+msgid "addons_browse_browse_category"
+msgstr "Browse %s"
+
+#. %1 is the name of the theme category (eg. Modern)
+#. %2 is the name of the Application (eg. Firefox)
+#: controllers/addons_controller.php:664
+msgid "addons_browse_categories_header_theme"
+msgstr "Browse %1$s Themes :: %2$s Add-ons"
+
+#: views/addons/display.thtml:249
+msgid "addons_display_a_license_what"
+msgstr "What's this?"
+
+#: views/reviews/display.thtml:222
+msgid "addons_display_add_review"
+msgstr "Add a review"
+
+#: views/addons/display.thtml:294
+msgid "addons_display_advanced_details"
+msgstr "Advanced Details"
+
+#: views/addons/display.thtml:98
+msgid "addons_display_categories"
+msgstr "Categories"
+
+#: views/addons/display.thtml:482
+msgid "addons_display_collection_add"
+msgstr "Add to a collection:"
+
+#: views/addons/display.thtml:491
+msgid "addons_display_collection_add_new"
+msgstr "New Collection..."
+
+#: views/addons/display.thtml:487
+msgid "addons_display_collection_add_select_one"
+msgstr "Select a collection..."
+
+#: views/addons/display.thtml:493
+msgid "addons_display_collection_add_submit"
+msgstr "Publish"
+
+#. %1$s is the add-on name
+#. %2$s is the collection name, linked to the collection's page
+#: views/pages/js_constants.js.thtml:103 views/addons/display.thtml:61
+msgid "addons_display_collection_publish_success"
+msgstr "%1$s has been added to the %2$s collection."
+
+#: views/addons/display.thtml:483
+msgid "addons_display_collection_whatsthis"
+msgstr "What's this?"
+
+#. %1$s is a number
+#: views/addons/display.thtml:473
+msgid "addons_display_collections_more"
+msgid_plural "addons_display_collections_more"
+msgstr[0] "and %1$s more collection"
+msgstr[1] "and %1$s more collections"
+
+#: views/addons/display.thtml:403
+msgid "addons_display_detailed_review"
+msgstr "detailed review"
+
+#: views/reviews/add.thtml:89 views/reviews/add.thtml:90
+msgid "addons_display_dont_like_it"
+msgstr "Don't like it"
+
+#: views/reviews/display.thtml:220
+msgid "addons_display_edit_review"
+msgstr "Edit your review"
+
+#: views/addons/display.thtml:132
+msgid "addons_display_has_privacy"
+msgstr "This add-on has a privacy policy."
+
+#: views/reviews/add.thtml:87 views/reviews/add.thtml:88
+msgid "addons_display_hate_it"
+msgstr "Hate it"
+
+#: views/addons/display.thtml:462
+msgid "addons_display_header_collections"
+msgstr "Related Collections"
+
+#: views/addons/display.thtml:297
+msgid "addons_display_header_developer_comments"
+msgstr "Developer Comments"
+
+#: views/addons/display.thtml:230
+msgid "addons_display_header_homepage"
+msgstr "Homepage"
+
+#: views/addons/display.thtml:247 views/addons/versions.thtml:110
+msgid "addons_display_header_license"
+msgstr "Source Code License"
+
+#: views/addons/display.thtml:337
+msgid "addons_display_header_reviews"
+msgstr "Reviews"
+
+#: views/addons/display.thtml:261
+msgid "addons_display_header_support"
+msgstr "Support"
+
+#: views/reviews/add.thtml:91 views/reviews/add.thtml:92
+msgid "addons_display_like_it"
+msgstr "Like it"
+
+#: views/addons/display.thtml:210
+msgid "addons_display_long_description"
+msgstr "Long Description"
+
+#: views/reviews/add.thtml:95 views/reviews/add.thtml:96
+msgid "addons_display_love_it"
+msgstr "Love it"
+
+#: views/addons/display.thtml:178
+msgid "addons_display_more_images"
+msgstr "More Images"
+
+#: views/addons/display.thtml:465
+msgid "addons_display_nocollections"
+msgstr "This add-on is not yet in any collections."
+
+#. %1$s is either an author's name or a comma separated list of authors. Using
+#. the list doesn't make sense in the English plural form so we ignore the
+#. variable.
+#: views/addons/display.thtml:436
+msgid "addons_display_other_addons_by"
+msgid_plural "addons_display_other_addons_by"
+msgstr[0] "Other add-ons by %1$s"
+msgstr[1] "Other add-ons by these authors"
+
+#. %s is the name of the add-on and the add-on section. Example:
+#. Some Add-on :: Firefox Add-ons
+#. This should not be concatenated in the code and should be fixed.
+#: controllers/addons_controller.php:141 controllers/addons_controller.php:280
+#: controllers/addons_controller.php:1442
+#, php-format
+msgid "addons_display_pagetitle"
+msgstr "%s"
+
+#. %s is an email address
+#: views/addons/display.thtml:286
+#, php-format
+msgid "addons_display_paragraph_supportinfoemail"
+msgstr "Support for this add-on is provided by the developer at %s"
+
+#. %$1s is a URL
+#. %$2s is an email address
+#: views/addons/display.thtml:269
+#, php-format
+msgid "addons_display_paragraph_supportinfoemailurl"
+msgstr ""
+"Support for this add-on is provided by the developer at %1$s or by sending "
+"an e-mail to %2$s"
+
+#. %s is a URL
+#: views/addons/display.thtml:278
+#, php-format
+msgid "addons_display_paragraph_supportinfourl"
+msgstr "Support for this add-on is provided by the developer at %s"
+
+#: views/addons/display.thtml:383
+msgid "addons_display_rate_it"
+msgstr "Rate It"
+
+#: views/reviews/add.thtml:93 views/reviews/add.thtml:94
+msgid "addons_display_really_like_it"
+msgstr "Really like it"
+
+#: views/addons/display.thtml:410
+msgid "addons_display_review_etiquette"
+msgstr ""
+"Please do not post bug reports in reviews. We do not make your email address "
+"available to add-on developers and they may need to contact you to help "
+"resolve your issue."
+
+#. %1 is the review guidelines link
+#: views/addons/display.thtml:417
+msgid "addons_display_review_guidelines_link"
+msgstr "<a href=\"%s\">Review Guidelines</a>"
+
+#. %1 is the support section link
+#: views/addons/display.thtml:414
+msgid "addons_display_review_see_support"
+msgstr ""
+"See the <a href=\"%1$s\">support section</a> to find out where to get "
+"assistance for this add-on."
+
+#: views/addons/display.thtml:404
+msgid "addons_display_review_submit"
+msgstr "Save"
+
+#: views/addons/display.thtml:430
+#, php-format
+msgid "addons_display_see_all_addons"
+msgstr "See All %1$s Add-ons"
+
+#. %1 is the number of reviews
+#: views/addons/display.thtml:364
+#, php-format
+msgid "addons_display_see_all_reviews"
+msgstr "See all reviews (%1$s)"
+
+#: views/addons/display.thtml:219
+msgid "addons_display_see_all_versions"
+msgstr "See All Versions"
+
+#: views/addons/display.thtml:321 views/addons/versions.thtml:117
+msgid "addons_display_view_source"
+msgstr "View the source"
+
+#: views/addons/display.thtml:324
+msgid "addons_display_view_stats"
+msgstr "View statistics"
+
+#: views/addons/display.thtml:376
+msgid "addons_display_what_do_you_think"
+msgstr "What do you think?"
+
+#: views/elements/app_compatibility.thtml:49
+msgid "addons_display_workswith"
+msgstr "Works with:"
+
+#: views/addons/home.thtml:112
+msgid "addons_home_browse_new"
+msgstr "Just Added"
+
+#: views/addons/home.thtml:110
+msgid "addons_home_browse_popular"
+msgstr "Popular"
+
+#: views/addons/home.thtml:108
+msgid "addons_home_browse_recommended"
+msgstr "Recommended"
+
+#: views/addons/home.thtml:127 views/addons/home.thtml:134
+#: views/addons/home.thtml:141 views/addons/home.thtml:148
+msgid "addons_home_browse_subscribe"
+msgstr "Subscribe"
+
+#: views/addons/home.thtml:101
+msgid "addons_home_browse_title"
+msgstr "Browse Add-ons"
+
+#: views/addons/home.thtml:114
+msgid "addons_home_browse_updated"
+msgstr "Updated"
+
+#: views/elements/amo2009/homepage_addon.thtml:100
+#: views/elements/addon_discussionheader.thtml:83
+#: views/elements/addon_listitem.thtml:109 views/elements/feature.thtml:95
+#: views/addons/category_landing.thtml:66 views/addons/policy.thtml:57
+#: views/addons/display.thtml:70 views/addons/home.thtml:178
+msgid "addons_home_by"
+msgstr "by"
+
+#: views/addons/home.thtml:169
+msgid "addons_home_collection_popular_title"
+msgstr "Popular Collections"
+
+#: views/elements/amo2009/categories.thtml:69 views/addons/home.thtml:160
+msgid "addons_home_collections"
+msgstr "Collections"
+
+#. %1$s is the count of addons in a collection
+#: views/elements/amo2009/collection_listing_item.thtml:51
+#: views/addons/home.thtml:185
+msgid "addons_home_collections_addon_count"
+msgid_plural "addons_home_collections_addon_count"
+msgstr[0] "<strong>%1$s</strong> add-on"
+msgstr[1] "<strong>%1$s</strong> add-ons"
+
+#: views/addons/home.thtml:196
+msgid "addons_home_collections_all"
+msgstr "View All Collections"
+
+#: views/addons/home.thtml:162
+msgid "addons_home_collections_intro"
+msgstr ""
+"Collections are a way for you to categorize, mix, match and mingle add-ons. "
+"Subscribe to collections created by other users or create your own."
+
+#. %1$s is the count of subscribers for a collection
+#: views/elements/amo2009/collection_listing_item.thtml:58
+#: views/collections/detail.thtml:96 views/addons/home.thtml:189
+msgid "addons_home_collections_subscribers"
+msgid_plural "addons_home_collections_subscribers"
+msgstr[0] "<strong>%1$s</strong> subscriber"
+msgstr[1] "<strong>%1$s</strong> subscribers"
+
+#: views/addons/searchengines.thtml:54 views/addons/themes_landing.thtml:49
+msgid "addons_home_feature_head"
+msgstr "We Recommend"
+
+#: controllers/search_controller.php:218 controllers/addons_controller.php:176
+#: controllers/addons_controller.php:428 controllers/addons_controller.php:671
+#: controllers/addons_controller.php:871
+#: controllers/addons_controller.php:1103
+#: controllers/addons_controller.php:1242
+#: controllers/addons_controller.php:1298
+#, php-format
+msgid "addons_home_header_details"
+msgstr ""
+"Add-ons extend %1$s, letting you personalize your browsing experience. Take "
+"a look around and make %1$s your own."
+
+#. %1$s is the HTML collection name link.
+#: views/elements/amo2009/teaser_collections.thtml:107
+msgid "addons_home_introduction_collection_link"
+msgstr "Like these? Find related add-ons in the %1$s collection."
+
+#: views/elements/amo2009/teaser_collections.thtml:60
+msgid "addons_home_introduction_extras"
+msgstr ""
+"<strong>Over 5000 free extras</strong> that let you customize and extend "
+"Firefox to meet your needs."
+
+#: views/elements/amo2009/teaser_collections.thtml:55
+msgid "addons_home_introduction_header"
+msgstr "What are Add-ons?"
+
+#: views/elements/amo2009/teaser_collections.thtml:72
+msgid "addons_home_introduction_install"
+msgstr "<strong>Easy to install</strong> and keep up-to-date."
+
+#: views/elements/amo2009/teaser_collections.thtml:45
+msgid "addons_home_introduction_name"
+msgstr "Introduction"
+
+#: views/elements/amo2009/teaser_collections.thtml:66
+msgid "addons_home_introduction_themes"
+msgstr ""
+"Toolbars, themes and search providers that <strong>help you perform common "
+"tasks.</strong>"
+
+#: views/addons/home.thtml:161
+msgid "addons_home_new_indicator"
+msgstr "NEW!"
+
+#: views/elements/app_chooser.thtml:48 views/layouts/amo2009.thtml:257
+msgid "addons_home_other_applications"
+msgstr "Other Applications"
+
+#. %1$s is the application the user is browsing. Examples: Thunderbird, Firefox,
+#. Sunbird
+#: views/pages/collector_faq.thtml:49 views/pages/collector_firstrun.thtml:42
+#: views/pages/collector.thtml:46 views/pages/collector_features.thtml:54
+#: controllers/developers_controller.php:87
+#: controllers/compatibility_controller.php:72
+#: controllers/components/simple_acl.php:81 controllers/components/amo.php:607
+#: controllers/statistics_controller.php:60
+#: controllers/statistics_controller.php:240
+#: controllers/previews_controller.php:67 controllers/users_controller.php:90
+#: controllers/users_controller.php:223 controllers/users_controller.php:330
+#: controllers/users_controller.php:414 controllers/users_controller.php:708
+#: controllers/users_controller.php:723 controllers/reviews_controller.php:204
+#: controllers/reviews_controller.php:251
+#: controllers/reviews_controller.php:346
+#: controllers/reviews_controller.php:425
+#: controllers/search_controller.php:185 controllers/search_controller.php:297
+#: controllers/search_controller.php:301 controllers/addons_controller.php:147
+#: controllers/addons_controller.php:280 controllers/addons_controller.php:370
+#: controllers/addons_controller.php:667 controllers/addons_controller.php:874
+#: controllers/addons_controller.php:1019
+#: controllers/addons_controller.php:1034
+#: controllers/addons_controller.php:1101
+#: controllers/addons_controller.php:1121
+#: controllers/addons_controller.php:1240
+#: controllers/addons_controller.php:1357
+#: controllers/addons_controller.php:1364
+#: controllers/addons_controller.php:1442
+#: controllers/addons_controller.php:1477
+#: controllers/addons_controller.php:1538
+#: controllers/addons_controller.php:1543
+#: controllers/editors_controller.php:64 controllers/pages_controller.php:132
+#: controllers/groups_controller.php:65 controllers/groups_controller.php:71
+#: controllers/groups_controller.php:89 controllers/groups_controller.php:111
+#: controllers/collections_controller.php:57
+#: controllers/collections_controller.php:121
+#: controllers/collections_controller.php:205
+#: controllers/collections_controller.php:365
+#: controllers/collections_controller.php:404
+#: controllers/collections_controller.php:466
+#: controllers/collections_controller.php:538
+#: controllers/collections_controller.php:828
+#: controllers/localizers_controller.php:72
+#, php-format
+msgid "addons_home_pagetitle"
+msgstr "Add-ons for %1$s"
+
+#. %1$s is the number of addons downloaded
+#: views/addons/home.thtml:57
+#, php-format
+msgid "addons_home_stats_downloaded"
+msgid_plural "addons_home_stats_downloaded"
+msgstr[0] "<strong>%1$s</strong> <span>add-on downloaded</span>"
+msgstr[1] "<strong>%1$s</strong> <span>add-ons downloaded</span>"
+
+#. %1$s is the number of addons in use
+#: views/addons/home.thtml:63
+#, php-format
+msgid "addons_home_stats_inuse"
+msgid_plural "addons_home_stats_inuse"
+msgstr[0] "<strong>%1$s</strong> <span>add-on in use</span>"
+msgstr[1] "<strong>%1$s</strong> <span>add-ons in use</span>"
+
+#: views/addons/home.thtml:136
+msgid "addons_home_view_all_newest_title"
+msgstr "View all newly created add-ons"
+
+#: views/addons/home.thtml:129
+msgid "addons_home_view_all_popular_title"
+msgstr "View all popular add-ons"
+
+#: views/addons/home.thtml:150
+msgid "addons_home_view_all_recommended_title"
+msgstr "View all recommended add-ons"
+
+#: views/addons/home.thtml:143
+msgid "addons_home_view_all_updated_title"
+msgstr "View all recently updated add-ons"
+
+#: views/elements/amo2009/install.thtml:334 views/elements/install.thtml:112
+msgid "addons_install_in_sunbird"
+msgstr ""
+"<ol><li>Download and save the file to your hard disk.</li><li>In Mozilla "
+"Sunbird, open Add-ons from the Tools menu.</li><li>Click the Install button, "
+"and locate/select the file you downloaded and click \"OK\".</li></ol>"
+
+#: views/elements/amo2009/install.thtml:333 views/elements/install.thtml:111
+msgid "addons_install_in_sunbird_title"
+msgstr "How to Install in Sunbird"
+
+#: views/elements/amo2009/install.thtml:331 views/elements/install.thtml:106
+msgid "addons_install_in_thunderbird"
+msgstr ""
+"<ol><li>Download and save the file to your hard disk.</li><li>In Mozilla "
+"Thunderbird, open Add-ons from the Tools menu.</li><li>Click the Install "
+"button, and locate/select the file you downloaded and click \"OK\".</li></ol>"
+
+#: views/elements/amo2009/install.thtml:330 views/elements/install.thtml:105
+msgid "addons_install_in_thunderbird_title"
+msgstr "How to Install in Thunderbird"
+
+#: views/elements/amo2009/addon_list_options.thtml:108
+#: views/elements/addon_list_options.thtml:105
+msgid "addons_options_show_experimental"
+msgstr "show experimental add-ons"
+
+#: views/elements/amo2009/addon_list_options.thtml:113
+#: views/elements/addon_list_options.thtml:109
+msgid "addons_options_submit"
+msgstr "Go"
+
+#: views/addons/plugins.thtml:63 views/addons/plugins.thtml:73
+#: views/addons/plugins.thtml:83 views/addons/plugins.thtml:93
+#: views/addons/plugins.thtml:103 views/addons/plugins.thtml:116
+#: views/addons/plugins.thtml:126
+msgid "addons_plugins_by"
+msgstr "By"
+
+#: views/addons/plugins.thtml:107
+msgid "addons_plugins_for_linux"
+msgstr "for Linux"
+
+#: views/addons/plugins.thtml:108 views/addons/plugins.thtml:131
+msgid "addons_plugins_for_macosx"
+msgstr "for Mac OS X"
+
+#: views/addons/plugins.thtml:106 views/addons/plugins.thtml:129
+#: views/addons/plugins.thtml:130
+msgid "addons_plugins_for_windows"
+msgstr "for Windows"
+
+#. %1$s is a URL
+#: views/addons/plugins.thtml:139
+#, php-format
+msgid "addons_plugins_looking_for_more"
+msgstr ""
+"This page only lists some of the most common and most popular plugins. For "
+"more information about other plugins available for Mozilla-based Browsers, "
+"visit %1$s"
+
+#: views/addons/plugins.thtml:137
+msgid "addons_plugins_looking_for_plugin"
+msgstr "Looking for a plugin not listed here?"
+
+#: views/addons/plugins.thtml:58
+msgid "addons_plugins_main_description"
+msgstr ""
+"Plugins help your browser perform specific functions like viewing special "
+"graphic formats or playing multimedia files. Plugins are slightly different "
+"from extensions, which modify or add to existing functionality."
+
+#. %1$s is the application name. Example: Firefox, Thunderbird, Sunbird
+#: controllers/addons_controller.php:1122
+#, php-format
+msgid "addons_plugins_main_header"
+msgstr "Common Plugins for %1$s"
+
+#: controllers/components/amo.php:698 controllers/addons_controller.php:1121
+msgid "addons_plugins_pagetitle"
+msgstr "Plugins"
+
+#: views/addons/plugins.thtml:68 views/addons/plugins.thtml:78
+#: views/addons/plugins.thtml:88 views/addons/plugins.thtml:98
+#: views/addons/plugins.thtml:110 views/addons/plugins.thtml:121
+#: views/addons/plugins.thtml:133
+msgid "addons_plugins_support_documentation"
+msgstr "Support Documentation: "
+
+#. %s is the name of the add-on
+#: views/addons/policy.thtml:61
+#, php-format
+msgid "addons_policy_eula_require"
+msgstr ""
+"%s requires that you accept the following End-User License Agreement before "
+"installation can proceed:"
+
+#. %1 is the add-on name
+#: controllers/addons_controller.php:1476
+#, php-format
+msgid "addons_previews_pagetitle"
+msgstr "Previews for %s"
+
+#: views/addons/category_landing.thtml:135
+msgid "addons_recently_added"
+msgstr "Recently Added"
+
+#: views/addons/recommended.thtml:51 controllers/addons_controller.php:1365
+msgid "addons_recommended_introduction"
+msgstr ""
+"With so many great add-ons available, there's something for everyone. To get "
+"you started, here's a list of some of the most popular. Enjoy!"
+
+#: controllers/addons_controller.php:1357
+#: controllers/addons_controller.php:1364
+msgid "addons_recommended_pagetitle"
+msgstr "Recommended Add-ons"
+
+#: controllers/addons_controller.php:1360
+msgid "addons_recommended_title"
+msgstr "Recommended Add-ons"
+
+#: views/addons/searchengines.thtml:136
+msgid "addons_searchengines_additional_resources"
+msgstr "Additional Resources"
+
+#. link text devmo
+#: views/addons/searchengines.thtml:141
+msgid "addons_searchengines_devmo_link"
+msgstr "Mozilla Developer Center"
+
+#: views/pages/js_constants.js.thtml:67
+msgid "addons_searchengines_error_mozilla_browser_required"
+msgstr ""
+"Sorry, you need a Mozilla-based browser (such as Firefox) to install a "
+"search plugin."
+
+#: views/addons/searchengines.thtml:49
+msgid "addons_searchengines_error_nojavascript"
+msgstr ""
+"JavaScript is required to install plugins, but it looks like you have it "
+"disabled. Please enable JavaScript before trying to install any of the "
+"search plugins below."
+
+#. %1 is "make your own" link
+#. %2 is MDC link
+#: views/addons/searchengines.thtml:139
+msgid "addons_searchengines_learn_howto"
+msgstr "Learn how to %1$s at the %2$s."
+
+#. link path to search plugins instructions, relative to devmo
+#: views/addons/searchengines.thtml:140
+msgid "addons_searchengines_makeyourown_href"
+msgstr "/en/docs/Creating_OpenSearch_plugins_for_Firefox"
+
+#. link text for "make your own" (opensearch engine)
+#: views/addons/searchengines.thtml:140
+msgid "addons_searchengines_makeyourown_link"
+msgstr "make your own"
+
+#. %1 is the link to mycroft.mozdev.org
+#: views/addons/searchengines.thtml:138
+msgid "addons_searchengines_more"
+msgstr "Browse through more search engines at %1$s"
+
+#. link text to mycroft.mozdev.org
+#: views/addons/searchengines.thtml:138
+msgid "addons_searchengines_mycroft_link"
+msgstr "mycroft.mozdev.org"
+
+#: controllers/addons_controller.php:1100
+#: controllers/addons_controller.php:1110
+msgid "addons_searchengines_pagetitle"
+msgstr "Search Engines"
+
+#: views/addons/searchengines.thtml:143
+msgid "addons_searchengines_thanks"
+msgstr ""
+"Special thanks to the Mycroft Project for their work on Firefox search "
+"engines."
+
+#: views/addons/display.thtml:154
+msgid "addons_share_button_text"
+msgstr "Share this"
+
+#: controllers/addons_controller.php:89
+msgid "addons_share_label_delicious"
+msgstr "Add to Delicious"
+
+#: controllers/addons_controller.php:77
+msgid "addons_share_label_digg"
+msgstr "Digg this!"
+
+#: controllers/addons_controller.php:83
+msgid "addons_share_label_facebook"
+msgstr "Post to Facebook"
+
+#: controllers/addons_controller.php:101
+msgid "addons_share_label_friendfeed"
+msgstr "Share on FriendFeed"
+
+#: controllers/addons_controller.php:95
+msgid "addons_share_label_myspace"
+msgstr "Post to MySpace"
+
+#: controllers/components/amo.php:201 controllers/components/amo.php:229
+msgid "addons_status_disabled"
+msgstr "Disabled"
+
+#: controllers/components/amo.php:191 controllers/components/amo.php:224
+msgid "addons_status_incomplete"
+msgstr "Incomplete Version"
+
+#: controllers/components/amo.php:197 controllers/components/amo.php:227
+msgid "addons_status_nominated"
+msgstr "In Sandbox; Public Nomination"
+
+#: views/pages/js_constants.js.thtml:80 controllers/components/amo.php:195
+#: controllers/components/amo.php:226
+msgid "addons_status_pending"
+msgstr "In Sandbox; Pending Review"
+
+#: views/pages/js_constants.js.thtml:78 controllers/components/amo.php:199
+#: controllers/components/amo.php:228
+msgid "addons_status_public"
+msgstr "Public"
+
+#: views/pages/js_constants.js.thtml:79 controllers/components/amo.php:193
+#: controllers/components/amo.php:225
+msgid "addons_status_sandbox"
+msgstr "In Sandbox"
+
+#: controllers/components/amo.php:203
+msgid "addons_status_unknown"
+msgstr "Unknown"
+
+#: views/elements/amo2009/teaser_collections.thtml:91
+#: views/elements/amo2009/homepage_addon.thtml:99
+#: views/elements/feature.thtml:94
+msgid "addons_title_tooltip"
+msgstr "Learn more about this add-on"
+
+#: views/addons/category_landing.thtml:151
+msgid "addons_top_downloads"
+msgstr "Top Downloads"
+
+#: views/addons/category_landing.thtml:165
+msgid "addons_top_rated"
+msgstr "Top Rated"
+
+#: views/addons/versions.thtml:62
+msgid "addons_versions_careful"
+msgstr "Be Careful With Old Versions"
+
+#: views/addons/versions.thtml:63
+msgid "addons_versions_careful_introduction"
+msgstr ""
+"These versions are displayed for reference and testing purposes. You should "
+"always use the latest version of an add-on."
+
+#: controllers/addons_controller.php:1549
+msgid "addons_versions_history"
+msgstr "Version History with Changelogs"
+
+#. %1$s is the add-on name
+#: controllers/addons_controller.php:1535
+#, php-format
+msgid "addons_versions_pagetitle"
+msgstr "%1$s Version History"
+
+#: controllers/groups_controller.php:71
+msgid "admin_group_add_pagetitle"
+msgstr "Add Group"
+
+#: controllers/groups_controller.php:111
+msgid "admin_group_delete_pagetitle"
+msgstr "Delete Group"
+
+#. %s is a number to identify the group
+#: controllers/groups_controller.php:117
+#, php-format
+msgid "admin_group_deleted"
+msgstr "The Group with id %s was deleted"
+
+#: controllers/groups_controller.php:89
+msgid "admin_group_edit_pagetitle"
+msgstr "Edit Group"
+
+#: controllers/groups_controller.php:92 controllers/groups_controller.php:113
+msgid "admin_group_error_invalid_id"
+msgstr "Invalid id for Group"
+
+#: controllers/groups_controller.php:65
+msgid "admin_group_pagetitle"
+msgstr "Group Admin"
+
+#: controllers/groups_controller.php:77 controllers/groups_controller.php:99
+msgid "admin_group_saved"
+msgstr "The Group has been saved"
+
+#: views/elements/amo2009/search.thtml:257 views/elements/search.thtml:239
+msgid "advanced_search_form"
+msgstr "Advanced"
+
+#: views/elements/amo2009/search.thtml:126 views/elements/search.thtml:125
+msgid "advanced_search_form_any_time"
+msgstr "Any time"
+
+#: views/elements/amo2009/search.thtml:97
+#: views/elements/amo2009/search.thtml:110 views/elements/search.thtml:96
+#: views/elements/search.thtml:109
+msgid "advanced_search_form_any_type"
+msgstr "Any"
+
+#: views/elements/amo2009/search.thtml:275 views/elements/search.thtml:254
+msgid "advanced_search_form_any_version"
+msgstr "Any"
+
+#: views/elements/amo2009/search.thtml:217 views/elements/search.thtml:212
+msgid "advanced_search_form_application"
+msgstr "Application"
+
+#: views/elements/amo2009/search.thtml:143 views/elements/search.thtml:142
+msgid "advanced_search_form_keyword_match"
+msgstr "Keyword Match"
+
+#: views/elements/amo2009/search.thtml:251 views/elements/search.thtml:225
+msgid "advanced_search_form_lastupdate"
+msgstr "Last Updated"
+
+#: views/elements/amo2009/search.thtml:145 views/elements/search.thtml:144
+msgid "advanced_search_form_name"
+msgstr "Name"
+
+#: views/elements/amo2009/search.thtml:144 views/elements/search.thtml:143
+msgid "advanced_search_form_newest"
+msgstr "Newest"
+
+#: views/elements/amo2009/search.thtml:130 views/elements/search.thtml:129
+msgid "advanced_search_form_past_3_months"
+msgstr "Past 3 months"
+
+#: views/elements/amo2009/search.thtml:131 views/elements/search.thtml:130
+msgid "advanced_search_form_past_6_months"
+msgstr "Past 6 months"
+
+#: views/elements/amo2009/search.thtml:127 views/elements/search.thtml:126
+msgid "advanced_search_form_past_day"
+msgstr "Past Day"
+
+#: views/elements/amo2009/search.thtml:129 views/elements/search.thtml:128
+msgid "advanced_search_form_past_month"
+msgstr "Past month"
+
+#: views/elements/amo2009/search.thtml:128 views/elements/search.thtml:127
+msgid "advanced_search_form_past_week"
+msgstr "Past week"
+
+#: views/elements/amo2009/search.thtml:132 views/elements/search.thtml:131
+msgid "advanced_search_form_past_year"
+msgstr "Past year"
+
+#: views/elements/amo2009/search.thtml:239 views/elements/search.thtml:230
+msgid "advanced_search_form_perpage"
+msgstr "Per Page"
+
+#: views/elements/amo2009/search.thtml:243 views/elements/search.thtml:224
+msgid "advanced_search_form_platform"
+msgstr "Platform"
+
+#: views/elements/amo2009/search.thtml:147 views/elements/search.thtml:146
+msgid "advanced_search_form_popularity"
+msgstr "Popularity"
+
+#: views/elements/amo2009/search.thtml:146 views/elements/search.thtml:145
+msgid "advanced_search_form_rating"
+msgstr "Rating"
+
+#: views/elements/amo2009/search.thtml:247 views/elements/search.thtml:231
+msgid "advanced_search_form_sortby"
+msgstr "Sort By"
+
+#: views/elements/amo2009/search.thtml:227 views/elements/search.thtml:216
+msgid "advanced_search_form_to"
+msgstr "to"
+
+#: views/elements/amo2009/search.thtml:257 views/elements/search.thtml:237
+msgid "advanced_search_form_toggle_tooltip"
+msgstr "Toggle advanced search mode"
+
+#: views/elements/amo2009/search.thtml:235 views/elements/search.thtml:223
+msgid "advanced_search_form_type"
+msgstr "Type"
+
+#: views/elements/amo2009/search.thtml:222 views/elements/search.thtml:214
+msgid "advanced_search_form_version"
+msgstr "version"
+
+#: views/elements/amo2009/pagination.thtml:42
+msgid "amo2009_pagination_next_page"
+msgstr "Next"
+
+#: views/elements/amo2009/pagination.thtml:41
+msgid "amo2009_pagination_previous_page"
+msgstr "Prev"
+
+#: views/pages/js_constants.js.thtml:96
+msgid "app_compat_ignore_check"
+msgstr "Ignore version check"
+
+#: views/pages/js_constants.js.thtml:72
+msgid "app_compat_older_firefox_only"
+msgstr "This add-on is for older versions of Firefox"
+
+#. %1$s and %2$s are URLs
+#: views/pages/js_constants.js.thtml:74
+msgid "app_compat_older_version_or_ignore_check"
+msgstr ""
+"You can <a href=\"%1$s\">try an older version</a> or <a href=\"#\" onclick="
+"\"%2$s\">ignore this check</a>"
+
+#. %1$s is a URL
+#: views/pages/js_constants.js.thtml:71
+msgid "app_compat_try_old_version"
+msgstr "An <a href=\"%1$s\">older version</a> may work"
+
+#. %1$s is a URL
+#. %2$s is a version number. Example: 3.1
+#: views/pages/js_constants.js.thtml:73
+msgid "app_compat_unreleased_version"
+msgstr ""
+"This add-on requires the not-yet released <a href=\"%1$s\">Firefox %2$s</a>"
+
+#: views/pages/js_constants.js.thtml:70
+msgid "app_compat_update_firefox"
+msgstr ""
+"<a href=\"http://getfirefox.com\">Upgrade Firefox</a> to use this add-on"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#. %3$s is a status, like Public.
+#: controllers/components/audit.php:79
+msgid "audit_addon_status"
+msgstr "%1$s changed the status of %2$s to %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:221
+msgid "audit_admin_default"
+msgstr "%1$s committed unknown admin action %2$s to ID %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:153
+msgid "audit_admin_feature_remove"
+msgstr "%1$s removed feature %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is an application, like Firefox.
+#: controllers/components/audit.php:92
+msgid "audit_application_create"
+msgstr "%1$s created application %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is an application, like Firefox.
+#: controllers/components/audit.php:95
+msgid "audit_application_edit"
+msgstr "%1$s edited application %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a version number, like 3.5.
+#. %3$s is an application, like Firefox.
+#: controllers/components/audit.php:105
+msgid "audit_appversion_create"
+msgstr "%1$s created version %2$s for %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a version number, like 3.5.
+#. %3$s is an application, like Firefox.
+#: controllers/components/audit.php:108
+msgid "audit_appversion_delete"
+msgstr "%1$s deleted version %2$s for %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a config field, like "awesomeness".
+#. %3$s is a config value, like "off".
+#. %4$s is a config value, like "on".
+#: controllers/components/audit.php:210
+msgid "audit_config"
+msgstr "%1$s changed config '%2$s' from '%3$s' to '%4$s'"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:258
+msgid "audit_editor_default"
+msgstr "%1$s committed unknown editor action %2$s to ID %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#: controllers/components/audit.php:236
+msgid "audit_editor_feature_remove"
+msgstr "%1$s removed addon %2$s from feature list"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#: controllers/components/audit.php:231
+msgid "audit_feature_add"
+msgstr "%1$s added addon %2$s to feature list"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:149
+msgid "audit_feature_edit"
+msgstr "%1$s changed a feature for %2$s locale"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#: controllers/components/audit.php:241
+msgid "audit_feature_locale_change"
+msgstr "%1$s changed locales for addon %2$s on feature list"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:83
+msgid "audit_file_recalchash"
+msgstr "%1$s recalculated the hash for file %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>user name</a>
+#. %3$s is <a>group name</a>
+#: controllers/components/audit.php:182
+msgid "audit_group_addmember"
+msgstr "%1$s added %2$s to group %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:313
+msgid "audit_group_associated"
+msgstr "%1$s associated themselves with %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:162
+msgid "audit_group_create"
+msgstr "%1s created group %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:170
+msgid "audit_group_delete"
+msgstr "%1$s deleted group %2$s (ID %3$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:165
+msgid "audit_group_edit"
+msgstr "%1$s edited group %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>user name</a>
+#. %3$s is <a>group name</a>
+#: controllers/components/audit.php:188
+msgid "audit_group_removemember"
+msgstr "%1$s removed %2$s from group %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:280
+msgid "audit_l10n_default"
+msgstr "%1$s committed unknown action %2$s for %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:295
+msgid "audit_modify_locked_group"
+msgstr "%1$s attempted to modify locked group %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:299
+msgid "audit_modify_other_locale"
+msgstr "%1$s attempted to modify translations in %2$s without permission"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a platform, like <a>Windows</a>
+#: controllers/components/audit.php:135
+msgid "audit_platform_create"
+msgstr "%1$s created platform %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a platform, like <a>Windows</a>
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:143
+msgid "audit_platform_delete"
+msgstr "%1$s deleted platform %2$s (ID %3$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a platform, like <a>Windows</a>
+#: controllers/components/audit.php:138
+msgid "audit_platform_edit"
+msgstr "%1$s edited platform %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a part of the admin, like 'Site Config'
+#: controllers/components/audit.php:288
+msgid "audit_reauthentication_failure"
+msgstr "%1$s failed to re-authenticate to access %2$s."
+
+#. %1$s is <a>user name</a>
+#. %2$s is the name of a canned response, like 'Ready for the public'
+#: controllers/components/audit.php:198
+msgid "audit_response_create"
+msgstr "%1$s created response %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is the name of a canned response, like 'Ready for the public'
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:206
+msgid "audit_response_delete"
+msgstr "%1$s deleted response %2$s (ID %3$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is the name of a canned response, like 'Ready for the public'
+#: controllers/components/audit.php:201
+msgid "audit_response_edit"
+msgstr "%1$s edited response %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:245
+msgid "audit_review_approve"
+msgstr "%1$s approved review %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:250 controllers/components/audit.php:253
+msgid "audit_review_delete"
+msgstr "%1$s deleted review %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:303
+msgid "audit_security_default"
+msgstr "%1$s committed unknown security action %2$s to ID %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a category name, like <a>Search Tools</a>
+#: controllers/components/audit.php:118
+msgid "audit_tag_create"
+msgstr "%1$s created tag %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a category name, like <a>Search Tools</a>
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:126
+msgid "audit_tag_delete"
+msgstr "%1$s deleted category %2$s (ID %3$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a category name, like <a>Search Tools</a>
+#: controllers/components/audit.php:121
+msgid "audit_tag_edit"
+msgstr "%1$s edited category %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:266
+msgid "audit_update_applications"
+msgstr "%1$s updated application translations for %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:277
+msgid "audit_update_blog"
+msgstr "%1$s updated blog post translations for %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:274
+msgid "audit_update_platforms"
+msgstr "%1$s updated platform translations for %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:270
+msgid "audit_update_tags"
+msgstr "%1$s updated category translations for %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>user name</a>
+#: controllers/components/audit.php:217
+msgid "audit_user_edit"
+msgstr "%1$s edited %2$s's user information"
+
+#: controllers/addons_controller.php:1012
+msgid "browse_addons_name"
+msgstr "Add-ons by Name"
+
+#: controllers/addons_controller.php:1010
+msgid "browse_addons_newest"
+msgstr "Newest Add-ons"
+
+#: controllers/addons_controller.php:1008
+msgid "browse_addons_popular"
+msgstr "Popular Add-ons"
+
+#: controllers/addons_controller.php:1011
+msgid "browse_addons_rated"
+msgstr "Add-ons by Rating"
+
+#: controllers/addons_controller.php:1009
+msgid "browse_addons_updated"
+msgstr "Recently Updated Add-ons"
+
+#: views/elements/categories.thtml:73 views/elements/categories.thtml:82
+msgid "categories_current_title"
+msgstr "Current Category"
+
+#: views/elements/categories.thtml:50
+#: views/elements/amo2009/categories.thtml:43
+#: views/elements/amo2009/categories.thtml:45
+msgid "categories_header"
+msgstr "Categories"
+
+#: views/elements/categories.thtml:50
+#: views/elements/amo2009/categories.thtml:41
+msgid "categories_header_title"
+msgstr "Choose a category"
+
+#. %1$s is the category name
+#: views/addons/searchengines.thtml:129
+#, php-format
+msgid "category_extra_see_all"
+msgstr "See All %1$s"
+
+#. %1$s is a number.
+#: models/collection.php:130
+msgid "collection_description_limit"
+msgstr "The description should be less than %1$s characters."
+
+#. %1$s is the name of the collection
+#: controllers/collections_controller.php:392
+msgid "collection_detail_rss_title"
+msgstr "%s Collection"
+
+#: controllers/collections_controller.php:1065
+msgid "collection_error_deleting_addon"
+msgstr "Error deleting add-on!"
+
+#: controllers/collections_controller.php:1051
+msgid "collection_error_saving_addon"
+msgstr "Error saving add-on!"
+
+#: controllers/collections_controller.php:1080
+msgid "collection_error_saving_comment"
+msgstr "Error saving comment!"
+
+#. %1$s is a number.
+#: models/collection.php:122
+msgid "collection_name_limit"
+msgstr "The name should be less than %1$s characters."
+
+#: controllers/collections_controller.php:352
+#: controllers/collections_controller.php:487
+msgid "collection_not_found"
+msgstr "Collection not found!"
+
+#. %1$s is the text on the "create collection" button
+#: views/collections/add.thtml:91
+msgid "collections_add_formfield_addons_description"
+msgstr ""
+"If you already know which add-ons you want to add to your collection, just "
+"start typing their names below. If you'd rather wait and do this later, just "
+"click %1$s now."
+
+#: views/collections/add.thtml:90
+msgid "collections_add_formfield_firstaddons"
+msgstr "Choose your first add-ons"
+
+#: views/collections/add.thtml:48
+msgid "collections_add_header"
+msgstr "Create a Collection"
+
+#: views/collections/add.thtml:97
+msgid "collections_add_header_selectedaddons"
+msgstr "Selected Add-ons"
+
+#: views/collections/add.thtml:50
+msgid "collections_add_intro"
+msgstr ""
+"It's easy to create your own collection of add-ons by filling in a few "
+"fields below."
+
+#: views/collections/add.thtml:92 views/collections/add.thtml:103
+msgid "collections_add_submit"
+msgstr "Create Collection"
+
+#: views/pages/collector_faq.thtml:50 views/pages/collector_firstrun.thtml:43
+#: views/pages/collector.thtml:47 views/pages/collector_features.thtml:55
+#: controllers/search_controller.php:302
+#: controllers/collections_controller.php:206
+#: controllers/collections_controller.php:405
+#: controllers/collections_controller.php:467
+#: controllers/collections_controller.php:539
+msgid "collections_breadcrumb"
+msgstr "Collections"
+
+#: views/collections/detail.thtml:185
+msgid "collections_detail_a_learn"
+msgstr "Learn More"
+
+#: views/elements/amo2009/collection_add_form.thtml:53
+#: views/elements/amo2009/collections_js_init.thtml:68
+#: views/pages/collector_firstrun.thtml:64
+msgid "collections_detail_button_add"
+msgstr "Add to Favorites"
+
+#: views/elements/amo2009/collection_add_form.thtml:50
+#: views/elements/amo2009/collections_js_init.thtml:71
+msgid "collections_detail_button_remove"
+msgstr "Remove from Favorites"
+
+#. %1$s is a URL.
+#. %2$s is a full <a href>.
+#: views/collections/detail.thtml:62
+msgid "collections_detail_created_desc"
+msgstr ""
+"<p>You can view your new collection below. If you'd like to set a collection "
+"nickname, upload an icon, or change additional settings, please visit the <a "
+"href='%1$s'>Manage Collections</a> page.</p><p>Your collection can be "
+"accessed at this location: %2$s</p>"
+
+#: views/collections/detail.thtml:61
+msgid "collections_detail_created_msg"
+msgstr "Your collection is now ready!"
+
+#: views/collections/detail.thtml:109
+msgid "collections_detail_header_about"
+msgstr "About This Collection"
+
+#. %1$s is a number.
+#: views/collections/detail.thtml:126
+msgid "collections_detail_header_count"
+msgid_plural "collections_detail_header_count"
+msgstr[0] "%1$s Add-on in this Collection"
+msgstr[1] "%1$s Add-ons in this Collection"
+
+#: views/collections/detail.thtml:113
+msgid "collections_detail_info_created"
+msgstr "<strong>Created by:</strong> %1$s"
+
+#: views/collections/detail.thtml:117
+msgid "collections_detail_info_updated"
+msgstr "<strong>Updated:</strong>"
+
+#: views/elements/amo2009/collections_js_init.thtml:62
+msgid "collections_detail_js_adding"
+msgstr "Adding to Favorites&hellip;"
+
+#: views/elements/amo2009/collections_js_init.thtml:65
+msgid "collections_detail_js_removing"
+msgstr "Removing Favorite&hellip;"
+
+#. %1$s is a URL
+#: views/collections/detail.thtml:90
+msgid "collections_detail_login"
+msgstr "<a href=\"%1$s\">Log in</a> to add this collection to your favorites."
+
+#: views/collections/detail.thtml:104
+msgid "collections_detail_manage"
+msgstr "Manage Collection"
+
+#: controllers/collections_controller.php:298
+msgid "collections_detail_sort_date"
+msgstr "Date Added"
+
+#: controllers/collections_controller.php:299
+msgid "collections_detail_sort_name"
+msgstr "Name"
+
+#: controllers/collections_controller.php:300
+msgid "collections_detail_sort_popularity"
+msgstr "Popularity"
+
+#. %1$s is a number.
+#: views/collections/detail.thtml:166
+msgid "collections_detail_weekly_downloads"
+msgid_plural "collections_detail_weekly_downloads"
+msgstr[0] "%1$s download this week"
+msgstr[1] "%1$s downloads this week"
+
+#: views/collections/edit.thtml:255
+msgid "collections_edit_addons_delete_noscript"
+msgstr "Selected add-ons will be removed upon Save"
+
+#: views/collections/edit.thtml:247
+msgid "collections_edit_addons_description"
+msgstr ""
+"To publish new add-ons to this collection, start typing their names below."
+
+#: views/collections/edit.thtml:248
+msgid "collections_edit_addons_description_noscript"
+msgstr ""
+"To publish new add-ons to this collection, enter a comma-separated list of "
+"Add-on IDs below."
+
+#: views/collections/edit.thtml:247 views/collections/edit.thtml:248
+msgid "collections_edit_addons_description_publish_detailspage"
+msgstr "You can also publish an add-on from its normal listing page."
+
+#. %1$s is the date the add-on was added to the collection
+#. %1$s is the name of the user who added the add-on to the collection
+#: views/collections/edit.thtml:260
+msgid "collections_edit_addons_listitem_added"
+msgstr "Added %1$s by %2$s"
+
+#: views/collections/edit.thtml:263
+msgid "collections_edit_addons_listitem_comment_add"
+msgstr "Add publisher comment"
+
+#: views/collections/edit.thtml:266
+msgid "collections_edit_addons_listitem_comment_delete"
+msgstr "Delete publisher comment"
+
+#: views/collections/edit.thtml:265
+msgid "collections_edit_addons_listitem_comment_edit"
+msgstr "Edit publisher comment"
+
+#: views/collections/edit.thtml:271
+msgid "collections_edit_addons_listitem_comment_note"
+msgstr ""
+"Note: Comment will appear as though written by original publisher on the "
+"original publication date"
+
+#: views/collections/edit.thtml:270
+msgid "collections_edit_addons_listitem_comment_submit"
+msgstr "Save Comment"
+
+#: views/collections/edit.thtml:261
+msgid "collections_edit_addons_listitem_remove"
+msgstr "Remove"
+
+#: views/collections/edit.thtml:250
+msgid "collections_edit_addons_submit"
+msgstr "Add to Collection"
+
+#: views/collections/edit.thtml:153
+msgid "collections_edit_check_nickname"
+msgstr "Check Availability"
+
+#: views/collections/edit.thtml:299
+msgid "collections_edit_confirm_deletecollection"
+msgstr "Yes, I would like to delete this collection."
+
+#. %1$s is the label of the edit form's submit button
+#: views/collections/edit.thtml:300
+msgid "collections_edit_confirm_deletecollection_description"
+msgstr "Check the box, then click on \"%1$s\" to delete this collection."
+
+#. %1$s is the "delete" submit button text
+#. %2$s is the title of the "advanced" tab
+#: views/collections/edit.thtml:95
+msgid "collections_edit_delete_upon_submit"
+msgstr ""
+"Upon clicking \"%1$s\" below, your collection will be deleted. If you do not "
+"want to delete your collection, uncheck the confirmation box in the \"%2$s\" "
+"tab and continue editing your collection. If you leave this page without "
+"saving, your collection will also not be deleted."
+
+#: views/collections/edit.thtml:94
+msgid "collections_edit_delete_warning"
+msgstr "Your collection is about to be deleted!"
+
+#: views/collections/add.thtml:76 views/collections/edit.thtml:144
+msgid "collections_edit_form_error_description"
+msgstr "You must provide a description of your collection."
+
+#: views/collections/edit.thtml:181
+msgid "collections_edit_form_error_icon"
+msgstr "There was an error uploading your icon."
+
+#: views/collections/add.thtml:69 views/collections/edit.thtml:130
+msgid "collections_edit_form_error_name"
+msgstr "You must give your collection a name."
+
+#: views/collections/edit.thtml:158
+msgid "collections_edit_form_error_nickname"
+msgstr "If you choose a nickname, it must be unique."
+
+#: views/collections/add.thtml:93 views/collections/edit.thtml:249
+msgid "collections_edit_formfield_addons"
+msgstr "Add-on name:"
+
+#: views/collections/edit.thtml:281
+msgid "collections_edit_formfield_application"
+msgstr "Associated Application"
+
+#: views/collections/edit.thtml:282
+msgid "collections_edit_formfield_application_description"
+msgstr "Select the application that your collection supports."
+
+#: views/collections/edit.thtml:288
+msgid "collections_edit_formfield_collectiontype"
+msgstr "Collection Type"
+
+#: views/collections/edit.thtml:295
+msgid "collections_edit_formfield_deletecollection"
+msgstr "Delete Collection"
+
+#: views/collections/edit.thtml:296
+msgid "collections_edit_formfield_deletecollection_description"
+msgstr "Deleting your collection will permanently erase it."
+
+#: views/collections/add.thtml:73 views/collections/edit.thtml:140
+msgid "collections_edit_formfield_description"
+msgstr "Collection Description"
+
+#: views/collections/add.thtml:74 views/collections/edit.thtml:141
+msgid "collections_edit_formfield_description_description"
+msgstr "Briefly describe your collection and the kind of add-ons in it"
+
+#: views/collections/edit.thtml:162
+msgid "collections_edit_formfield_icon"
+msgstr "Icon"
+
+#: views/collections/edit.thtml:163
+msgid "collections_edit_formfield_icon_description"
+msgstr ""
+"You can upload a JPG, GIF or PNG icon that will be resized to 32x32 pixels."
+
+#: views/collections/add.thtml:80 views/collections/edit.thtml:189
+msgid "collections_edit_formfield_listed"
+msgstr "Who can view your collection?"
+
+#: views/collections/add.thtml:81 views/collections/edit.thtml:190
+msgid "collections_edit_formfield_listed_description"
+msgstr ""
+"By default, collections appear in the public Collection Directory and are "
+"discoverable by anyone. If you want to restrict your collection to be "
+"viewable only by people who are given a special link, choose that option "
+"below."
+
+#: views/collections/add.thtml:84 views/collections/edit.thtml:193
+msgid "collections_edit_formfield_listed_false"
+msgstr "Only people I invite can view my collection"
+
+#: views/collections/add.thtml:83 views/collections/edit.thtml:192
+msgid "collections_edit_formfield_listed_true"
+msgstr "Everyone can view my collection in the directory"
+
+#: views/collections/edit.thtml:223
+msgid "collections_edit_formfield_managers"
+msgstr "Who can manage my collection?"
+
+#: views/collections/edit.thtml:224
+msgid "collections_edit_formfield_managers_description"
+msgstr ""
+"These users can publish add-ons to your collection, manage all add-ons and "
+"settings, and grant other users permission."
+
+#: views/collections/add.thtml:66 views/collections/edit.thtml:126
+msgid "collections_edit_formfield_name"
+msgstr "Collection Name"
+
+#: views/collections/add.thtml:67 views/collections/edit.thtml:127
+msgid "collections_edit_formfield_name_description"
+msgstr ""
+"Give your collection a descriptive name, such as \"Dave's Favorite Travel "
+"Add-ons\""
+
+#: views/collections/edit.thtml:148
+msgid "collections_edit_formfield_nickname"
+msgstr "Collection Nickname"
+
+#: views/collections/edit.thtml:149
+msgid "collections_edit_formfield_nickname_description"
+msgstr "Optionally, give your collection a unique nickname for quick access:"
+
+#: views/collections/edit.thtml:201
+msgid "collections_edit_formfield_publishers"
+msgstr "Who can publish add-ons to your collection?"
+
+#: views/collections/edit.thtml:202
+msgid "collections_edit_formfield_publishers_description"
+msgstr ""
+"These users can publish add-ons to your collection and remove add-ons that "
+"they publish."
+
+#: views/collections/edit.thtml:210 views/collections/edit.thtml:232
+msgid "collections_edit_formfield_users_add"
+msgstr "Enter the e-mail address of a Firefox Add-ons account:"
+
+#: views/collections/edit.thtml:216 views/collections/edit.thtml:238
+msgid "collections_edit_formfield_users_delete_noscript"
+msgstr "Selected accounts will be removed upon Save"
+
+#: views/collections/edit.thtml:215 views/collections/edit.thtml:237
+msgid "collections_edit_formfield_users_new_noscript"
+msgstr ""
+"Enter a comma-separated list of e-mail addresses of Firefox Add-ons accounts"
+
+#: views/collections/edit.thtml:204 views/collections/edit.thtml:226
+msgid "collections_edit_formfield_users_onlyme"
+msgstr "Only me"
+
+#: views/collections/edit.thtml:205 views/collections/edit.thtml:227
+msgid "collections_edit_formfield_users_otherusers"
+msgstr "Myself and these users:"
+
+#: views/collections/edit.thtml:211 views/collections/edit.thtml:233
+msgid "collections_edit_formfield_users_submit"
+msgstr "Add"
+
+#. %1$s is the name of the collection
+#: views/collections/edit.thtml:68
+msgid "collections_edit_header"
+msgstr "Manage %1$s"
+
+#: views/collections/edit.thtml:246
+msgid "collections_edit_header_addons"
+msgstr "Manage Collection Contents"
+
+#: views/collections/edit.thtml:253 views/collections/edit.thtml:258
+msgid "collections_edit_header_addons_current"
+msgstr "Current Add-ons:"
+
+#: views/collections/edit.thtml:279
+msgid "collections_edit_header_advanced"
+msgstr "Advanced Settings"
+
+#: views/collections/edit.thtml:186
+msgid "collections_edit_header_permissions"
+msgstr "Manage Collection Permissions"
+
+#: views/collections/edit.thtml:170
+msgid "collections_edit_icon_cancel"
+msgstr "Cancel"
+
+#: views/collections/edit.thtml:174 views/collections/edit.thtml:179
+msgid "collections_edit_icon_delete"
+msgstr "Delete Icon"
+
+#: views/collections/edit.thtml:178
+msgid "collections_edit_icon_replace"
+msgstr "Replace Icon"
+
+#. %1$s is the label of the edit form's submit button
+#: views/collections/edit.thtml:169
+msgid "collections_edit_icon_toberemoved"
+msgstr "Icon will be removed when \"%1$s\" is clicked below"
+
+#: views/collections/edit.thtml:155
+msgid "collections_edit_nickname_available"
+msgstr "Nickname Available"
+
+#: controllers/collections_controller.php:943
+msgid "collections_edit_nickname_error"
+msgstr ""
+"Your nickname contained invalid characters and was corrected. Please try "
+"again."
+
+#: views/collections/edit.thtml:156
+msgid "collections_edit_nickname_taken"
+msgstr "Nickname Taken"
+
+#. This string is followed by a URL pointing to the collection's view page
+#: views/collections/edit.thtml:75
+msgid "collections_edit_saved_nextstep"
+msgstr "Your collection can be accessed at this location:"
+
+#: views/collections/edit.thtml:74
+msgid "collections_edit_saved_success"
+msgstr "Your collection was successfully saved!"
+
+#: views/collections/edit.thtml:169 views/collections/edit.thtml:300
+#: views/collections/edit.thtml:308 views/pages/js_constants.js.thtml:99
+msgid "collections_edit_submit"
+msgstr "Update Collection"
+
+#: views/collections/edit.thtml:96 views/collections/edit.thtml:297
+#: views/pages/js_constants.js.thtml:100
+msgid "collections_edit_submit_deletecollection"
+msgstr "Delete Collection"
+
+#: views/collections/edit.thtml:111
+msgid "collections_edit_tabheader_addons"
+msgstr "Add-ons"
+
+#: views/collections/edit.thtml:97 views/collections/edit.thtml:113
+msgid "collections_edit_tabheader_advanced"
+msgstr "Advanced"
+
+#: views/collections/edit.thtml:108
+msgid "collections_edit_tabheader_details"
+msgstr "Name &amp; Details"
+
+#: views/collections/edit.thtml:109
+msgid "collections_edit_tabheader_permissions"
+msgstr "Permissions"
+
+#: models/collection_promo.php:53
+msgid "collections_family_tagline"
+msgstr "Keep an eye on your kids and your calendar"
+
+#: models/collection_promo.php:53
+msgid "collections_family_title"
+msgstr "Family"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:70
+msgid "collections_index_a_check_out"
+msgstr "Check out Add-on Collector"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:52
+msgid "collections_index_a_create"
+msgstr "Create a Collection"
+
+#: views/collections/detail.thtml:139 views/collections/listing.thtml:85
+#: views/search/collections.thtml:84
+msgid "collections_index_button_go"
+msgstr "Go"
+
+#. %1$s is a URL.
+#: controllers/collections_controller.php:182
+msgid "collections_index_filler_favorites"
+msgstr ""
+"<p><strong>You don't have any favorite collections yet.</strong></p> "
+"<p>Collections you mark as favorites can be quickly accessed from this page, "
+"and will appear in the <a href='%1$s'>Add-on Collector</a> if you've "
+"installed it.</p>"
+
+#. %1$s is a URL.
+#: controllers/collections_controller.php:167
+msgid "collections_index_filler_mine"
+msgstr ""
+"<p>You haven't created any collections yet. Collections are easy to create "
+"and fill with your favorite add-ons. <a href='%1$s'>Try it out</a>!</p>"
+
+#: views/collections/listing.thtml:51
+msgid "collections_index_header_collections"
+msgstr "Collections"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:60
+msgid "collections_index_header_collector"
+msgstr "Add-on Collector"
+
+#. %1$s is a comma-separated list of author names
+#: views/elements/amo2009/collection_listing_item.thtml:84
+#: views/collections/detail.thtml:151
+msgid "collections_index_header_created"
+msgstr "created by %1$s"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:47
+msgid "collections_index_header_what"
+msgstr "What are Collections?"
+
+#: views/collections/detail.thtml:132 views/collections/listing.thtml:78
+#: views/search/collections.thtml:66
+msgid "collections_index_label_sortby"
+msgstr "Sort by"
+
+#: controllers/collections_controller.php:130
+msgid "collections_index_li_editors"
+msgstr "Editor's Picks"
+
+#: views/collections/subscribe.thtml:64
+#: controllers/collections_controller.php:140
+msgid "collections_index_li_favorites"
+msgstr "My Favorites"
+
+#: controllers/collections_controller.php:138
+msgid "collections_index_li_mine"
+msgstr "My Collections"
+
+#: controllers/collections_controller.php:132
+msgid "collections_index_li_popular"
+msgstr "Popular"
+
+#: views/search/collections.thtml:74 controllers/collections_controller.php:81
+msgid "collections_index_option_all"
+msgstr "Most popular all time"
+
+#: views/search/collections.thtml:72 controllers/collections_controller.php:78
+msgid "collections_index_option_month"
+msgstr "Most popular this month"
+
+#: views/search/collections.thtml:76 controllers/collections_controller.php:84
+msgid "collections_index_option_newest"
+msgstr "Newest"
+
+#: views/search/collections.thtml:70 controllers/collections_controller.php:75
+msgid "collections_index_option_week"
+msgstr "Most popular this week"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:67
+msgid "collections_index_p_collector"
+msgstr ""
+"There's a new way to manage and find favorite add-ons. Comment, share and "
+"sync collections, all from your browser"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:48
+msgid "collections_index_p_what_are"
+msgstr "Collections are groups of related add-ons assembled for easy sharing."
+
+#. %s is a date in the _('date') format
+#: views/elements/collections_interactive_addon.thtml:85
+#, php-format
+msgid "collections_interactive_addon_added"
+msgstr "Added %s"
+
+#: models/collection_promo.php:55
+msgid "collections_reference_tagline"
+msgstr "Research anything online"
+
+#: models/collection_promo.php:55
+msgid "collections_reference_title"
+msgstr "Reference"
+
+#: models/collection_promo.php:52
+msgid "collections_social_tagline"
+msgstr "Manage your social network"
+
+#: models/collection_promo.php:52
+msgid "collections_social_title"
+msgstr "Social"
+
+#: views/collections/subscribe.thtml:91
+msgid "collections_subscribe_button_close"
+msgstr "Close"
+
+#: views/collections/subscribe.thtml:70
+msgid "collections_subscribe_error"
+msgstr ""
+"An error occurred trying to add a favorite collection. Is this collection "
+"already a favorite?"
+
+#: views/collections/subscribe.thtml:96
+msgid "collections_subscribe_label_bothersome"
+msgstr "Don't show me this message again."
+
+#. %1$s is the collection name
+#: views/collections/subscribe.thtml:60
+msgid "collections_subscribe_success"
+msgstr "%1$s has been added to your favorite collections."
+
+#. %1$s is the link to the "My Favorites" tab on the main collections page
+#. %2$s is the localized title of the "My Favorites" tab
+#. %3$s is the link URL to the collector add-on
+#: views/collections/subscribe.thtml:62
+msgid "collections_subscribe_success_desc"
+msgstr ""
+"You can now quickly find this collection from the <a href=\"%1$s\">%2$s</a> "
+"tab in the directory. For an even easier way to keep track of your favorite "
+"collections, try out our <a href=\"%3$s\">Add-on Collector</a> extension for "
+"Firefox."
+
+#: views/collections/listing.thtml:55
+msgid "collections_success_delete"
+msgstr "The collection has been deleted."
+
+#: models/collection_promo.php:54
+msgid "collections_travel_tagline"
+msgstr "Plan business trips and unforgettable vacations"
+
+#: models/collection_promo.php:54
+msgid "collections_travel_title"
+msgstr "Travel"
+
+#. A collection of add-ons that is automatically built for a user. They are "automatically published" to this collection.
+#: controllers/collections_controller.php:581
+msgid "collections_type_autopublisher"
+msgstr "Auto-publisher"
+
+#. A collection that has been chosen by an Editor as notable or exceptional
+#: controllers/collections_controller.php:582
+msgid "collections_type_editorspick"
+msgstr "Editor's Pick"
+
+#: controllers/collections_controller.php:580
+msgid "collections_type_normal"
+msgstr "Normal"
+
+#: views/collections/subscribe.thtml:84
+msgid "collections_unsubscribe_error"
+msgstr ""
+"An error occurred trying to remove a favorite collection. Was this "
+"collection not a favorite?"
+
+#. %1$s is the collection name
+#: views/collections/subscribe.thtml:78
+msgid "collections_unsubscribe_success"
+msgstr "%1$s has been removed from your favorite collections."
+
+#: models/collection_promo.php:56
+msgid "collections_webdev_tagline"
+msgstr "Build the perfect website"
+
+#: models/collection_promo.php:56
+msgid "collections_webdev_title"
+msgstr "Web Development"
+
+#: views/elements/amo2009/collections_sidebar_whatare.thtml:40
+msgid "collections_whatare_header"
+msgstr "What are Collections?"
+
+#: views/elements/amo2009/collections_sidebar_whatare.thtml:45
+msgid "collections_whatare_learnmore"
+msgstr "Read the FAQ"
+
+#: views/elements/amo2009/collections_sidebar_whatare.thtml:44
+msgid "collections_whatare_text"
+msgstr ""
+"There’s a new way to manage and find favorite add-ons. Comment, share and "
+"sync collections, all from your browser."
+
+#: views/pages/collector_faq.thtml:61 views/pages/collector_features.thtml:67
+msgid "collector_features_a_home"
+msgstr "Add-on Collector Home"
+
+#: views/elements/amo2009/collector_sidebar_download.thtml:46
+msgid "collector_features_heading_download"
+msgstr "Download the Add-on Collector:"
+
+#: views/elements/amo2009/collector_sidebar_download.thtml:43
+#: views/pages/collector_firstrun.thtml:116 views/pages/collector.thtml:69
+msgid "collector_features_img_logo"
+msgstr "Add-on Collector Logo"
+
+#: views/compatibility/dashboard.thtml:49
+#: controllers/compatibility_controller.php:72
+msgid "compatibility_dashboard_center_header"
+msgstr "Add-on Compatibility Center"
+
+#. %1$s is the name of an application and a version. Example: Firefox 3.0
+#. %2$s is the name of an application. Example: Firefox
+#: views/compatibility/dashboard.thtml:50
+msgid "compatibility_dashboard_intro"
+msgstr ""
+"Be prepared for the release of %1$s with the tools and information available "
+"for the %2$s Add-ons community found below."
+
+#: views/compatibility/dashboard.thtml:103
+msgid "compatibility_dashboard_loading"
+msgstr "Loading data..."
+
+#: views/compatibility/dashboard.thtml:45
+msgid "compatibility_dashboard_main_link"
+msgstr "Back to Main"
+
+#: views/compatibility/dashboard.thtml:100 views/compatibility/report.thtml:43
+msgid "compatibility_dashboard_report"
+msgstr "Add-on Compatibility Report"
+
+#: views/compatibility/dashboard.thtml:53
+#: views/compatibility/dashboard.thtml:110
+#: views/compatibility/developers.thtml:43
+msgid "compatibility_developer_info"
+msgstr "Information for Add-on Developers"
+
+#: views/compatibility/developers.thtml:66
+msgid "compatibility_developers_adjust_maxversion"
+msgstr "Adjust maxVersion without uploading"
+
+#: views/compatibility/dashboard.thtml:124
+msgid "compatibility_developers_check_status"
+msgstr "Check Status of My Add-ons"
+
+#. %1$s is a URL
+#. %2$s is an application and version. Example: Firefox 3.0
+#: views/compatibility/dashboard.thtml:126
+msgid "compatibility_developers_login_first"
+msgstr ""
+"If you have add-ons hosted on Mozilla Add-ons, <a href=\"%1$s\">please log "
+"in</a> to analyze the status of your add-ons for %2$s."
+
+#: views/compatibility/dashboard.thtml:114
+msgid "compatibility_developers_mdclogo_alt"
+msgstr "Mozilla Developer Center Logo"
+
+#: views/compatibility/developers.thtml:73
+msgid "compatibility_developers_no_addons"
+msgstr "You do not have any add-ons hosted on Mozilla Add-ons."
+
+#: views/compatibility/dashboard.thtml:133
+#: views/compatibility/developers.thtml:55
+msgid "compatibility_developers_results"
+msgstr "Add-on Status Check Results"
+
+#: views/compatibility/dashboard.thtml:137
+msgid "compatibility_developers_retrieving"
+msgstr "Retrieving status of hosted add-ons..."
+
+#. %1$s is a number
+#. %2$s is an application name
+#. %3$s is a number.
+#. Full example: 50 Firefox users (10% of total)
+#: views/compatibility/developers.thtml:65
+msgid "compatibility_developers_user_count"
+msgstr "%1$s %2$s users (%3$s&#37; of total)"
+
+#: views/compatibility/report.thtml:45
+msgid "compatibility_report_detail_intro"
+msgstr ""
+"The add-ons below make up 95% of add-on usage known to Mozilla and are "
+"ordered by their usage size."
+
+#: views/compatibility/dashboard.thtml:94
+msgid "compatibility_report_detailed_link"
+msgstr "View Detailed Report"
+
+#. %1$s and %2$s are numbers
+#. %3$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:65
+msgid "compatibility_report_intro"
+msgstr ""
+"Of the %1$s add-ons that make up 95&#37; of add-on usage known to Mozilla, "
+"<b>%2$s&#37;</b> are currently considered compatible with the latest builds "
+"of %3$s."
+
+#: views/compatibility/dashboard.thtml:81
+msgid "compatibility_report_legend_alpha"
+msgstr "Alpha Versions"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:81
+msgid "compatibility_report_legend_alpha_description"
+msgstr "Add-ons compatible with an alpha version of %1$s"
+
+#: views/compatibility/dashboard.thtml:85
+msgid "compatibility_report_legend_beta"
+msgstr "Beta Versions"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:85
+msgid "compatibility_report_legend_beta_description"
+msgstr "Add-ons compatible with a beta version or release candidate of %1$s"
+
+#: views/compatibility/dashboard.thtml:89
+msgid "compatibility_report_legend_latest"
+msgstr "Latest Version"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:89
+msgid "compatibility_report_legend_latest_description"
+msgstr "Add-ons up-to-date with the latest builds of %1$s"
+
+#: views/compatibility/dashboard.thtml:77
+msgid "compatibility_report_legend_other"
+msgstr "Other Versions"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:77
+msgid "compatibility_report_legend_other_description"
+msgstr "Add-ons not compatible with any version of %1$s"
+
+#: views/compatibility/dashboard.thtml:62
+msgid "compatibility_report_title"
+msgstr "Add-on Compatibility Report"
+
+#: views/compatibility/dashboard.thtml:54
+#: views/compatibility/dashboard.thtml:144 views/compatibility/users.thtml:42
+msgid "compatibility_user_info"
+msgstr "Information for Add-on Users"
+
+#: views/compatibility/dashboard.thtml:52
+msgid "compatibility_view_report"
+msgstr "View Compatibility Report"
+
+#. %s is a URL
+#: views/pages/credits.thtml:142
+#, php-format
+msgid "credits_contributing"
+msgstr "For information on contributing, please see our %s."
+
+#: views/pages/credits.thtml:142
+msgid "credits_contributing_wikipage"
+msgstr "wiki page"
+
+#: views/pages/credits.thtml:99
+msgid "credits_intro"
+msgstr ""
+"Mozilla would like to thank the following people for their contributions to "
+"the addons.mozilla.org project over the years:"
+
+#: views/pages/credits.thtml:103
+msgid "credits_section_developers"
+msgstr "Developers"
+
+#: views/pages/credits.thtml:115
+msgid "credits_section_editors"
+msgstr "Editors"
+
+#: views/pages/credits.thtml:109
+msgid "credits_section_localizers"
+msgstr "Localizers"
+
+#: views/pages/credits.thtml:121
+msgid "credits_section_other_contributors"
+msgstr "Other Contributors"
+
+#: views/pages/credits.thtml:127
+msgid "credits_section_past_developers"
+msgstr "Past Developers"
+
+#: views/pages/credits.thtml:133
+msgid "credits_section_software"
+msgstr "Software and Images"
+
+#: views/pages/credits.thtml:136
+msgid "credits_software_famfamfam"
+msgstr ""
+"Some icons used are from the <a href=\"http://www.famfamfam.com/lab/icons/"
+"silk/\">famfamfam Silk Icon Set</a>, licensed under a <a href=\"http://"
+"creativecommons.org/licenses/by/2.5/\">Creative Commons Attribution 2.5 "
+"License</a>."
+
+#: views/pages/credits.thtml:137
+msgid "credits_software_timeplot"
+msgstr ""
+"Some pages use elements of <a href=\"http://www.simile-widgets.org/timeplot/"
+"\">Timeplot</a>, licensed under a <a href=\"http://simile.mit.edu/license."
+"html\">BSD License</a>."
+
+#. date format string as used in PHP's strftime():
+#. http://php.net/strftime
+#: views/elements/collections_interactive_addon.thtml:85
+#: views/elements/amo2009/addon_version_detail.thtml:53
+#: views/elements/amo2009/homepage_addon.thtml:115
+#: views/elements/addon_version_detail.thtml:54
+#: views/elements/addon_listitem.thtml:124 views/elements/feature.thtml:106
+#: views/collections/detail.thtml:118 views/collections/edit.thtml:325
+#: views/users/info.thtml:76 views/editors/reviews_queue.thtml:57
+#: views/editors/reviews_queue.thtml:68 views/developers/dashboard.thtml:65
+#: views/developers/versions_edit.thtml:208 views/developers/versions.thtml:67
+#: views/search/rss/index.thtml:5 views/addons/rss/versions.thtml:42
+#: views/addons/display.thtml:104 views/addons/display.thtml:356
+#: views/addons/browse_thumbs.thtml:75 views/reviews/add.thtml:63
+#: views/reviews/display.thtml:74 views/reviews/display.thtml:160
+#: views/reviews/delete.thtml:54 controllers/statistics_controller.php:244
+#: controllers/collections_controller.php:1047
+msgid "date"
+msgstr "%B %e, %Y"
+
+#. date and time format string (strftime)
+#. http://php.net/strftime
+#: views/elements/addon_version_detail.thtml:53
+#: views/developers/discuss.thtml:52 views/developers/discuss.thtml:62
+#: views/admin/addons_status.thtml:57
+msgid "datetime"
+msgstr "%B %e, %Y, %I:%M %p"
+
+#: views/elements/developers/actionbar.thtml:47
+msgid "devcp_actionbar_link_details"
+msgstr "Detailed Info"
+
+#: views/elements/developers/actionbar.thtml:42
+#: views/elements/developers/actionbar.thtml:50
+#: views/developers/dashboard.thtml:64
+msgid "devcp_actionbar_link_edit"
+msgstr "Edit Add-on"
+
+#: views/elements/developers/actionbar.thtml:51
+msgid "devcp_actionbar_link_newversion"
+msgstr "Upload New Version"
+
+#: views/elements/developers/actionbar.thtml:44
+#: views/elements/developers/actionbar.thtml:49
+#: views/developers/dashboard.thtml:73
+msgid "devcp_actionbar_link_stats"
+msgstr "Statistics Dashboard"
+
+#. %1$s is a filename, e.g. "foo.txt"
+#. %2$s is the extension, e.g. ".txt"
+#. %3$s is a list of valid extensions, like ".png, .jpg, .gif"
+#: controllers/developers_controller.php:1361
+msgid "devcp_add_previews_extension_error"
+msgstr "File %1$s has an invalid extension (%2$s). Allowed extensions: %3$s"
+
+#. %s is the filename.
+#: controllers/developers_controller.php:1394
+msgid "devcp_add_previews_save_error"
+msgstr "File %s could not be saved to the database. Please try again."
+
+#. %1$s is the preview ID number, %2$s is the filename.
+#: controllers/developers_controller.php:1389
+msgid "devcp_add_previews_success_replace"
+msgstr "Preview %1$s was replaced with file %2$s successfully."
+
+#. %s is the filename.
+#: controllers/developers_controller.php:1391
+msgid "devcp_add_previews_success_upload"
+msgstr "File %s was uploaded successfully. You can add a caption below."
+
+#: controllers/components/developers.php:1163
+msgid "devcp_additem_addontype_autodetect"
+msgstr "(auto-detect)"
+
+#: views/elements/developers/additem.thtml:76
+msgid "devcp_additem_linktitle_opensin_newwindow"
+msgstr "Opens in a new window"
+
+#: views/elements/developers/additem.thtml:41
+msgid "devcp_additem_sidebar_title"
+msgstr "Submit Add-on"
+
+#: views/elements/developers/additem.thtml:53
+msgid "devcp_additem_step0_newlink"
+msgstr "Developer Agreement"
+
+#: views/elements/developers/additem.thtml:46
+msgid "devcp_additem_step1_link"
+msgstr "Step 1: Upload"
+
+#: views/elements/developers/additem.thtml:47
+msgid "devcp_additem_step2_link"
+msgstr "Step 2: Add-on Details"
+
+#: views/elements/developers/additem.thtml:48
+msgid "devcp_additem_step3_link"
+msgstr "Step 3: Version Details"
+
+#: views/elements/developers/additem.thtml:49
+msgid "devcp_additem_step4_link"
+msgstr "Step 4: Localization"
+
+#: views/elements/developers/additem.thtml:50
+msgid "devcp_additem_step5_link"
+msgstr "Step 5: Success"
+
+#: views/elements/developers/additem.thtml:76
+msgid "devcp_additem_submissionhelp_link"
+msgstr "Submission Help"
+
+#: controllers/previews_controller.php:168
+#: controllers/previews_controller.php:277
+msgid "devcp_addon_field_preview_caption_displaytitle"
+msgstr "Preview Caption"
+
+#: views/developers/addon_status.thtml:177
+msgid "devcp_addon_status_action_activate"
+msgstr "Make Active"
+
+#: views/developers/addon_status.thtml:178
+msgid "devcp_addon_status_action_activate_description"
+msgstr ""
+"Make your add-on active for it to show up in public listings and enable the "
+"update check service."
+
+#: views/developers/addon_status.thtml:135
+msgid "devcp_addon_status_action_complete"
+msgstr "Complete Add-on"
+
+#: views/developers/addon_status.thtml:136
+msgid "devcp_addon_status_action_complete_description"
+msgstr "Complete your add-on and move to the Sandbox"
+
+#: views/developers/addon_status.thtml:181
+msgid "devcp_addon_status_action_deactivate"
+msgstr "Make Inactive"
+
+#: views/developers/addon_status.thtml:182
+msgid "devcp_addon_status_action_deactivate_description"
+msgstr ""
+"Make your add-on inactive to hide it from all public listings and disable "
+"the update check service."
+
+#: views/developers/addon_status.thtml:143
+msgid "devcp_addon_status_action_move"
+msgstr "Move to Sandbox"
+
+#: views/developers/addon_status.thtml:144
+msgid "devcp_addon_status_action_move_description"
+msgstr "Move your add-on back to the Sandbox. This is reversible."
+
+#: views/developers/addon_status.thtml:139
+msgid "devcp_addon_status_action_nominate"
+msgstr "Nominate for Public"
+
+#: views/developers/addon_status.thtml:140
+msgid "devcp_addon_status_action_nominate_description"
+msgstr "Nominate your add-on to become Public"
+
+#: views/developers/addon_status.thtml:147
+msgid "devcp_addon_status_action_public"
+msgstr "Make Public"
+
+#: views/developers/addon_status.thtml:148
+msgid "devcp_addon_status_action_public_description"
+msgstr "Make your add-on Public again."
+
+#: views/developers/addon_status.thtml:169
+msgid "devcp_addon_status_active"
+msgstr ""
+"Your add-on is <span class=\"inactive-0\">Active</span>. This means your add-"
+"on is showing up in all available listings appropriate for its status above."
+
+#: views/developers/addon_status.thtml:111
+msgid "devcp_addon_status_completion_disabled"
+msgstr ""
+"Please fulfill the criteria above before you can complete your add-on and "
+"move it to the <span class=\"status-1\">Sandbox</span>."
+
+#: views/developers/addon_status.thtml:108
+msgid "devcp_addon_status_completion_enabled"
+msgstr ""
+"You may now complete your add-on and move it to the <span class=\"status-1"
+"\">Sandbox</span> by clicking the button below."
+
+#: views/developers/addon_status.thtml:102
+msgid "devcp_addon_status_criteria_category"
+msgstr "At least one category selected"
+
+#: views/developers/addon_status.thtml:101
+msgid "devcp_addon_status_criteria_description"
+msgstr "Add-on Description required"
+
+#: views/developers/addon_status.thtml:99
+msgid "devcp_addon_status_criteria_name"
+msgstr "Add-on Name required"
+
+#: views/developers/addon_status.thtml:120
+msgid "devcp_addon_status_criteria_prerelease"
+msgstr "Add-on is not marked as pre-release."
+
+#: views/developers/addon_status.thtml:119
+msgid "devcp_addon_status_criteria_preview"
+msgstr "At least one preview image required for extensions and themes."
+
+#: views/developers/addon_status.thtml:100
+msgid "devcp_addon_status_criteria_summary"
+msgstr "Add-on Summary required"
+
+#. %s is the status in a span, e.g. "<span>_('Public')</span>".
+#: views/developers/addon_status.thtml:58
+msgid "devcp_addon_status_header"
+msgstr "Add-on Status: %s"
+
+#: views/developers/addon_status.thtml:152
+#: views/developers/addon_status.thtml:173
+msgid "devcp_addon_status_header_actions"
+msgstr "Available Actions"
+
+#: views/developers/addon_status.thtml:168
+msgid "devcp_addon_status_header_active"
+msgstr "Active Status: <span class=\"inactive-0\">Active</span>"
+
+#: views/developers/addon_status.thtml:97
+msgid "devcp_addon_status_header_criteria"
+msgstr "Add-on Completion Criteria"
+
+#: views/developers/addon_status.thtml:164
+msgid "devcp_addon_status_header_inactive"
+msgstr "Active Status: <span class=\"inactive-1\">Inactive</span>"
+
+#: views/developers/addon_status.thtml:117
+msgid "devcp_addon_status_header_nomination"
+msgstr "Public Nomination Criteria"
+
+#: views/developers/addon_status.thtml:190
+msgid "devcp_addon_status_header_trusted"
+msgstr "Trusted Status: <span class=\"status-4\">Trusted</span>"
+
+#: views/developers/addon_status.thtml:165
+msgid "devcp_addon_status_inactive"
+msgstr ""
+"Your add-on is <span class=\"inactive-1\">Inactive</span>. This means your "
+"add-on will not show up in any listing, regardless of its status above. "
+"Updates are <b>not</b> being provided to your add-on through the update "
+"check service."
+
+#: views/developers/addon_status.thtml:128
+msgid "devcp_addon_status_nominate_disabled"
+msgstr ""
+"Please fulfill the criteria above before nominating your add-on to become "
+"<span class=\"status-4\">Public</span>."
+
+#: views/developers/addon_status.thtml:125
+msgid "devcp_addon_status_nominate_enabled"
+msgstr ""
+"You may now nominate your add-on for <span class=\"status-4\">Public</span> "
+"by clicking the button below."
+
+#: views/developers/addon_status.thtml:64
+msgid "devcp_addon_status_public"
+msgstr "Public"
+
+#: views/developers/addon_status.thtml:63
+msgid "devcp_addon_status_sandbox"
+msgstr "Sandbox"
+
+#. %s is an email address.
+#: views/developers/addon_status.thtml:89
+msgid "devcp_addon_status_switch_disabled"
+msgstr ""
+"Your add-on was <span class=\"status-5\">Disabled</span> by an administrator "
+"and cannot be used. If you have any questions, please e-mail %s."
+
+#: views/developers/addon_status.thtml:67
+msgid "devcp_addon_status_switch_incomplete"
+msgstr ""
+"Your add-on is currently <span class=\"status-0\">Incomplete</span>. This "
+"means your add-on is not showing up on any portion of the site or update "
+"check service. You may come to this page to complete your add-on after it "
+"meets the criteria below for completion and transfer to the <span class="
+"\"status-1\">Sandbox</span>."
+
+#. %s is a number, perhaps 42.
+#: views/developers/addon_status.thtml:77
+msgid "devcp_addon_status_switch_nominated"
+msgstr ""
+"Your add-on is currently nominated to become <span class=\"status-4"
+"\">Public</span> and is awaiting editor review. There are currently %s other "
+"add-ons in the nomination queue."
+
+#. %s is an email address.
+#: views/developers/addon_status.thtml:81
+msgid "devcp_addon_status_switch_pending"
+msgstr ""
+"Your add-on is pending. This shouldn't have happened. Please e-mail %s with "
+"your add-on ID and state this error."
+
+#: views/developers/addon_status.thtml:85
+msgid "devcp_addon_status_switch_public"
+msgstr ""
+"Your add-on is <span class=\"status-4\">Public</span>, which means it will "
+"show up in all listings and searches and can be downloaded without "
+"restriction. Updates are being provided to your add-on through the update "
+"check service."
+
+#: views/developers/addon_status.thtml:71
+#: views/developers/addon_status.thtml:75
+msgid "devcp_addon_status_switch_sandbox"
+msgstr ""
+"Your add-on is in the <span class=\"status-1\">Sandbox</span>, which means "
+"it will show up in listings and searches, but users must log in to download "
+"it. Updates are <b>not</b> being provided to your add-on through the update "
+"check service."
+
+#. %s is the add-on name.
+#: views/developers/addon_status_nominate.thtml:43
+#: views/developers/addon_status_confirm.thtml:43
+#: views/developers/addon_status.thtml:43
+msgid "devcp_addon_status_title"
+msgstr "%s Status"
+
+#: views/developers/addon_status.thtml:191
+msgid "devcp_addon_status_trusted"
+msgstr ""
+"Your add-on is <span class=\"status-4\">Trusted</span>. This means you can "
+"submit updates to your add-on without editor review."
+
+#: views/developers/dashboard.thtml:68
+msgid "devcp_dashboard_active"
+msgstr "Active"
+
+#. %1$s is the add-on type string
+#. %2$s is Inactive or Active in a <span>
+#. %3$s is the addon's public status (Public, In Sandbox, ...) in a <span>
+#: views/developers/dashboard.thtml:69
+msgid "devcp_dashboard_addontype_status"
+msgstr "%1$s currently %2$s and %3$s"
+
+#: views/developers/dashboard.thtml:67
+msgid "devcp_dashboard_change_status"
+msgstr "Change Status"
+
+#. %s is the addons email address.
+#: views/developers/dashboard.thtml:99
+msgid "devcp_dashboard_disabled_questions"
+msgstr ""
+"Your add-on was disabled by an administrator and cannot be used. If you "
+"have any questions, please email %s."
+
+#. %s is the (localized) add-on status string in a span, e.g. "Disabled"
+#: views/developers/dashboard.thtml:98
+msgid "devcp_dashboard_disabled_status"
+msgstr "Add-on Status: %s"
+
+#: views/developers/dashboard.thtml:43
+msgid "devcp_dashboard_header_main"
+msgstr "Developer Dashboard"
+
+#: views/developers/dashboard.thtml:110
+msgid "devcp_dashboard_header_welcome"
+msgstr "Welcome to the Developer Dashboard"
+
+#: views/developers/dashboard.thtml:68
+msgid "devcp_dashboard_inactive"
+msgstr "Inactive"
+
+#. %s is a date in the _('date') format
+#: views/developers/dashboard.thtml:65
+msgid "devcp_dashboard_last_edited"
+msgstr "Last edited on %s"
+
+#: views/developers/dashboard.thtml:111
+msgid "devcp_dashboard_learn"
+msgstr ""
+"You don't currently have any add-ons hosted on Mozilla Add-ons. To learn how "
+"the process works and submit your first add-on, click Get Started below."
+
+#: views/developers/dashboard.thtml:112
+msgid "devcp_dashboard_start"
+msgstr "Get Started"
+
+#: views/developers/dashboard.thtml:82
+msgid "devcp_dashboard_versions"
+msgstr "Versions and Files"
+
+#: views/developers/dashboard.thtml:91
+msgid "devcp_dashboard_versions_new"
+msgstr "Upload a new version"
+
+#. %s is the preview ID number.
+#: controllers/developers_controller.php:1415
+msgid "devcp_delete_previews_error"
+msgstr "Preview %s could not be deleted from the database. Please try again."
+
+#. %s is the preview ID number.
+#: controllers/developers_controller.php:1413
+msgid "devcp_delete_previews_success"
+msgstr "Preview %s has been deleted successfully."
+
+#: controllers/developers_controller.php:1089
+msgid "devcp_delete_version_priv_error"
+msgstr "You do not have privileges to delete versions or files."
+
+#. %1$s is the count of files, a number
+#. %2$s is a status string like _('Public') or _('Incomplete')
+#: controllers/components/amo.php:549
+msgid "devcp_describe_version_status"
+msgid_plural "devcp_describe_version_status"
+msgstr[0] "%1$s %2$s file"
+msgstr[1] "%1$s %2$s files"
+
+#. %s is a version number. Example: 3.0
+#: views/developers/versions.thtml:65
+#, php-format
+msgid "devcp_details_version"
+msgstr "Version %s"
+
+#: views/developers/discuss.thtml:68
+msgid "devcp_discuss_addreply_header"
+msgstr "Add Reply"
+
+#: views/developers/discuss.thtml:57
+msgid "devcp_discuss_allreplies_header"
+msgstr "Replies"
+
+#. notice when an error occurs saving a discussion reply
+#. %1 is the email address (linked) for the amo-editors list
+#: views/developers/discuss.thtml:70
+msgid "devcp_discuss_error_notice"
+msgstr ""
+"There was an error saving your reply. Please contact %1$s about the issue."
+
+#. %1 is the add-on name, %2 is the add-on's version number currently being reviewed by an editor
+#: views/developers/discuss.thtml:46
+msgid "devcp_discuss_intro"
+msgstr ""
+"A Mozilla Add-ons Editor requested further information from you regarding "
+"version %2$s of your add-on %1$s."
+
+#. %1 is the add-on name
+#: views/developers/discuss.thtml:43
+msgid "devcp_discuss_pagetitle"
+msgstr "Provide More Information For the Add-on Review of %1$s"
+
+#. submit button text
+#: views/developers/discuss.thtml:79
+msgid "devcp_discuss_submit_reply"
+msgstr "Submit Reply"
+
+#: views/developers/discuss.thtml:72
+msgid "devcp_discuss_success_message"
+msgstr ""
+"Your reply was successfully saved. The other participants of the discussion "
+"will be notified by email."
+
+#. in an author/editor discussion about an add-on to be reviewed:
+#. %1 is the commenter's user name (linked).
+#. %2 is the full date the comment was made.
+#: views/developers/discuss.thtml:52 views/developers/discuss.thtml:62
+msgid "devcp_discuss_writtenby"
+msgstr "written by %1$s on %2$s"
+
+#: views/developers/addon_edit_authors.thtml:72
+#: views/developers/addon_edit_authors.thtml:81
+msgid "devcp_edit_authors_add_author"
+msgstr "Add New Author"
+
+#: views/developers/addon_edit_authors.thtml:96
+msgid "devcp_edit_authors_add_author_button"
+msgstr "Add Author"
+
+#: views/developers/addon_edit_authors.thtml:83
+msgid "devcp_edit_authors_add_email"
+msgstr "Author Account Email:"
+
+#: views/developers/addon_edit_authors.thtml:98
+msgid "devcp_edit_authors_add_loading"
+msgstr "Checking account email..."
+
+#: views/developers/addon_edit_authors.thtml:70
+msgid "devcp_edit_authors_click_save"
+msgstr "Click the Update Authors button below to save."
+
+#: views/developers/addon_edit_authors.thtml:58
+msgid "devcp_edit_authors_header_current"
+msgstr "Current Authors"
+
+#: views/developers/addon_edit_authors.thtml:50
+msgid "devcp_edit_authors_header_manage"
+msgstr "Manage Add-on Authors"
+
+#: views/developers/addon_edit_authors.thtml:93
+msgid "devcp_edit_authors_label_add_listed"
+msgstr "List as author in public display pages"
+
+#: views/developers/addon_edit_authors.thtml:89
+msgid "devcp_edit_authors_label_developer"
+msgstr ""
+"<strong>Developer</strong> - Can manage all aspects of the add-on listing, "
+"except for adding and removing other authors."
+
+#: views/developers/addon_edit_authors.thtml:88
+msgid "devcp_edit_authors_label_owner"
+msgstr ""
+"<strong>Owner</strong> - Can manage all aspects of the add-on listing, "
+"including adding and removing other authors."
+
+#: views/developers/addon_edit_authors.thtml:90
+msgid "devcp_edit_authors_label_viewer"
+msgstr ""
+"<strong>Viewer</strong> - Can view add-on developer listing and statistics, "
+"but can't make any changes."
+
+#. Placeholder for the empty option in a <select>.
+#: views/developers/addon_edit_categories.thtml:69
+msgid "devcp_edit_authors_option_empty"
+msgstr "----------------"
+
+#: views/developers/addon_edit_authors.thtml:86
+msgid "devcp_edit_authors_select_role"
+msgstr "Select a role for the author:"
+
+#. Column name in a table.
+#: views/developers/addon_edit_authors.thtml:62
+msgid "devcp_edit_authors_th_author"
+msgstr "Author"
+
+#. Column name in a table.
+#: views/developers/addon_edit_authors.thtml:64
+msgid "devcp_edit_authors_th_listed"
+msgstr "Listed"
+
+#. Column name in a table.
+#: views/developers/addon_edit_authors.thtml:63
+msgid "devcp_edit_authors_th_role"
+msgstr "Role"
+
+#: views/developers/addon_edit_authors.thtml:77
+msgid "devcp_edit_authors_update_author"
+msgstr "Update authors"
+
+#: views/developers/addon_edit_categories.thtml:99
+msgid "devcp_edit_categories_button_update"
+msgstr "Update Categories"
+
+#: views/developers/addon_edit_categories.thtml:88
+msgid "devcp_edit_categories_does_not_fit"
+msgstr "My add-on doesn't fit into any available categories."
+
+#. %s is the application name (Firefox, Thunderbird).
+#: views/developers/addon_edit_categories.thtml:61
+msgid "devcp_edit_categories_header_application"
+msgstr "%s Categories"
+
+#: views/developers/addon_edit_categories.thtml:49
+msgid "devcp_edit_categories_header_manage"
+msgstr "Manage Add-on Categories"
+
+#: views/developers/addon_edit_categories.thtml:91
+msgid "devcp_edit_categories_hover"
+msgstr "Hover over a category to see its description."
+
+#. %s is the category number (1, 2, 3).
+#: views/developers/addon_edit_categories.thtml:67
+msgid "devcp_edit_categories_label_category_num"
+msgstr "Category %s"
+
+#: views/developers/addon_edit_categories.thtml:94
+#: views/developers/addon_edit_categories.thtml:103
+msgid "devcp_edit_categories_none_available"
+msgstr "No categories are available for this add-on type and application."
+
+#: views/developers/addon_edit_categories.thtml:86
+msgid "devcp_edit_categories_other"
+msgstr ""
+"Place your add-on into this category only if it does not fit into any other "
+"available categories."
+
+#. %s is the application name (Firefox, Thunderbird).
+#: views/developers/addon_edit_categories.thtml:63
+msgid "devcp_edit_categories_select_application_categories"
+msgstr "Select up to three %s categories for your add-on"
+
+#: views/developers/addon_edit.thtml:47
+msgid "devcp_edit_dd_manage_authors"
+msgstr "Add or remove users that can manage this add-on."
+
+#: views/developers/addon_edit.thtml:49
+msgid "devcp_edit_dd_manage_categories"
+msgstr ""
+"Select the relevant categories for each application your add-on supports."
+
+#: views/developers/addon_edit.thtml:51
+msgid "devcp_edit_dd_manage_description"
+msgstr ""
+"Add and modify translations for your add-on's summary, description, end-user "
+"license, and privacy policy."
+
+#: views/developers/addon_edit.thtml:53
+msgid "devcp_edit_dd_manage_properties"
+msgstr "Change your add-on's name, homepage, icon, and other flags."
+
+#: views/developers/addon_edit_descriptions.thtml:116
+msgid "devcp_edit_description_button_update"
+msgstr "Update Descriptions"
+
+#: views/developers/addon_edit_descriptions.thtml:115
+msgid "devcp_edit_description_correct_error"
+msgstr "Please correct the errors above indicated in red."
+
+#: views/developers/addon_edit_descriptions.thtml:51
+msgid "devcp_edit_descriptions_header"
+msgstr "Edit Add-on Descriptions"
+
+#: views/developers/addon_edit_descriptions.thtml:94
+msgid "devcp_edit_descriptions_transbox_comments_description"
+msgstr ""
+"Any information end users may want to know that isn't necessarily applicable "
+"to the add-on summary or description. Common uses include listing known "
+"major bugs, information on how to report bugs, anticipated release date of a "
+"new version, etc."
+
+#: views/developers/addon_edit_descriptions.thtml:93
+msgid "devcp_edit_descriptions_transbox_comments_name"
+msgstr "Developer Comments"
+
+#: views/developers/addon_edit_descriptions.thtml:86
+msgid "devcp_edit_descriptions_transbox_description_description"
+msgstr ""
+"The description of your add-on is a longer explanation of features, "
+"functionality, and other relevant information. It is displayed under the "
+"summary on the add-on's display page."
+
+#: views/developers/addon_edit_descriptions.thtml:85
+msgid "devcp_edit_descriptions_transbox_description_name"
+msgstr "Add-on Description"
+
+#: views/developers/addon_edit_descriptions.thtml:103
+msgid "devcp_edit_descriptions_transbox_eula_description"
+msgstr ""
+"If your add-on has an End-User License Agreement (EULA), please enter its "
+"text below. If set below, users will be required to agree to this before "
+"installing your add-on. Please note that a EULA is not the same as a code "
+"license such as GPL or MPL."
+
+#: views/developers/addon_edit_descriptions.thtml:102
+msgid "devcp_edit_descriptions_transbox_eula_name"
+msgstr "End-User License Agreement"
+
+#: views/developers/addon_edit_descriptions.thtml:112
+msgid "devcp_edit_descriptions_transbox_privacy_description"
+msgstr ""
+"If your add-on has a privacy policy, enter its text here. Your add-on's "
+"display page will display a link to the policy."
+
+#: views/developers/addon_edit_descriptions.thtml:111
+msgid "devcp_edit_descriptions_transbox_privacy_name"
+msgstr "Privacy Policy"
+
+#: views/developers/addon_edit_descriptions.thtml:78
+msgid "devcp_edit_descriptions_transbox_summary_description"
+msgstr ""
+"The summary is a short explanation of your add-on's basic functionality that "
+"is displayed in search and browse listings, as well as at the top of your "
+"add-on's display page. <strong>Limit of 250 characters.</strong>"
+
+#: views/developers/addon_edit_descriptions.thtml:77
+msgid "devcp_edit_descriptions_transbox_summary_name"
+msgstr "Add-on Summary"
+
+#: views/developers/addon_edit.thtml:46
+msgid "devcp_edit_dt_manage_authors"
+msgstr "Manage Add-on Authors"
+
+#: views/developers/addon_edit.thtml:48
+msgid "devcp_edit_dt_manage_categories"
+msgstr "Manage Add-on Categories"
+
+#: views/developers/addon_edit.thtml:50
+msgid "devcp_edit_dt_manage_descriptions"
+msgstr "Manage Add-on Descriptions"
+
+#: views/developers/addon_edit.thtml:52
+msgid "devcp_edit_dt_manage_properties"
+msgstr "Manage Add-on Properties"
+
+#: views/developers/addon_edit_properties.thtml:170
+msgid "devcp_edit_label_externalsoftware"
+msgstr "This add-on requires external software"
+
+#: views/developers/addon_edit_properties.thtml:205
+msgid "devcp_edit_label_locale_disambiguation"
+msgstr "Additional Locale Info"
+
+#: views/developers/addon_edit_properties.thtml:168
+msgid "devcp_edit_label_prerelease"
+msgstr "This is a pre-release"
+
+#: views/developers/addon_edit_properties.thtml:169
+msgid "devcp_edit_label_sitespecific"
+msgstr "This is a site-specific add-on"
+
+#: views/developers/addon_edit_properties.thtml:202
+msgid "devcp_edit_label_target_locale"
+msgstr "Target Locale"
+
+#: views/developers/addon_edit_properties.thtml:212
+msgid "devcp_edit_properties_button_update"
+msgstr "Update Properties"
+
+#: views/developers/addon_edit_properties.thtml:198
+msgid "devcp_edit_properties_change_guid"
+msgstr "Only change if you understand all of the consequences."
+
+#: views/developers/addon_edit_properties.thtml:109
+msgid "devcp_edit_properties_current_icon"
+msgstr "Current Icon"
+
+#: views/developers/addon_edit_properties.thtml:85
+msgid "devcp_edit_properties_default_locale"
+msgstr ""
+"An add-on's default locale is the main locale in which translations must be "
+"present. If translations for your add-on's descriptions are unavailable in a "
+"user's selected language, they will fall back to this default locale."
+
+#: views/developers/addon_edit_properties.thtml:167
+msgid "devcp_edit_properties_flags"
+msgstr "These flags are used to filter and classify add-ons."
+
+#: views/developers/addon_edit_properties.thtml:174
+msgid "devcp_edit_properties_guid"
+msgstr ""
+"The GUID of your add-on is specified in its install.rdf and uniquely "
+"identifies it. You cannot change your GUID once it is listed on Mozilla Add-"
+"ons."
+
+#: views/developers/addon_edit_properties.thtml:53
+msgid "devcp_edit_properties_header"
+msgstr "Edit Add-on Properties"
+
+#: views/developers/addon_edit_properties.thtml:186
+msgid "devcp_edit_properties_header_addon_type"
+msgstr "Add-on Type"
+
+#: views/developers/addon_edit_properties.thtml:181
+msgid "devcp_edit_properties_header_admin_settings"
+msgstr "Admin Settings"
+
+#: views/developers/addon_edit_properties.thtml:84
+msgid "devcp_edit_properties_header_default_locale"
+msgstr "Default Locale"
+
+#: views/developers/addon_edit_properties.thtml:166
+msgid "devcp_edit_properties_header_flags"
+msgstr "Add-on Flags"
+
+#: views/developers/addon_edit_properties.thtml:173
+#: views/developers/addon_edit_properties.thtml:197
+msgid "devcp_edit_properties_header_guid"
+msgstr "Add-on GUID"
+
+#: views/developers/addon_edit_properties.thtml:104
+msgid "devcp_edit_properties_header_icon"
+msgstr "Add-on Icon"
+
+#: views/developers/addon_edit_properties.thtml:159
+msgid "devcp_edit_properties_header_other_settings"
+msgstr "Other Settings"
+
+#. A header on the admin page to toggle trusted status.
+#: views/developers/addon_edit_properties.thtml:182
+msgid "devcp_edit_properties_header_trusted"
+msgstr "Trusted Add-on?"
+
+#: views/developers/addon_edit_properties.thtml:160
+msgid "devcp_edit_properties_header_view_source"
+msgstr "View Source Online"
+
+#. %s is a comma-separated list of image extensions ".png, .jpg"
+#: views/developers/addon_edit_properties.thtml:106
+msgid "devcp_edit_properties_icon"
+msgstr ""
+"The add-on icon is a small image that is displayed next to your add-on's "
+"name in browse and search results, display pages, and in the add-on "
+"installation dialog. The image will automatically be resized to 32 x 32 "
+"pixels. Please use one of the following image types: %s"
+
+#: views/developers/addon_edit_properties.thtml:171
+msgid "devcp_edit_properties_label_binary"
+msgstr "This add-on contains binary components"
+
+#: views/developers/addon_edit_properties.thtml:185
+msgid "devcp_edit_properties_label_not_trusted"
+msgstr "Not Trusted"
+
+#: views/developers/addon_edit_properties.thtml:184
+msgid "devcp_edit_properties_label_trusted"
+msgstr "Trusted"
+
+#: views/developers/addon_edit_properties.thtml:110
+msgid "devcp_edit_properties_new_icon"
+msgstr "New Icon"
+
+#: views/developers/addon_edit_properties.thtml:118
+msgid "devcp_edit_properties_remove_icon"
+msgstr "Remove Icon"
+
+#: views/developers/addon_edit_properties.thtml:136
+msgid "devcp_edit_properties_transbox_homepage_description"
+msgstr ""
+"If your add-on has another homepage, enter its address here. Adding other "
+"translations is not necessary unless your website is localized into other "
+"languages."
+
+#: views/developers/addon_edit_properties.thtml:135
+msgid "devcp_edit_properties_transbox_homepage_name"
+msgstr "Add-on Homepage"
+
+#: views/developers/addon_edit_properties.thtml:79
+msgid "devcp_edit_properties_transbox_name_description"
+msgstr "The name of your add-on is displayed everywhere your add-on is listed."
+
+#: views/developers/addon_edit_properties.thtml:78
+msgid "devcp_edit_properties_transbox_name_name"
+msgstr "Add-on Name"
+
+#: views/developers/addon_edit_properties.thtml:145
+msgid "devcp_edit_properties_transbox_supportemail_description"
+msgstr ""
+"If you have an email address for support inquiries, enter it here. Adding "
+"other translations is not necessary unless you have different email "
+"addresses for different languages."
+
+#: views/developers/addon_edit_properties.thtml:144
+msgid "devcp_edit_properties_transbox_supportemail_name"
+msgstr "Support Email Address"
+
+#: views/developers/addon_edit_properties.thtml:154
+msgid "devcp_edit_properties_transbox_supporturl_description"
+msgstr ""
+"If your add-on has a support website or forum, enter its address here. "
+"Adding other translations is not necessary unless your website is localized "
+"into other languages."
+
+#: views/developers/addon_edit_properties.thtml:153
+msgid "devcp_edit_properties_transbox_supporturl_name"
+msgstr "Support Website"
+
+#: views/developers/addon_edit_properties.thtml:183
+msgid "devcp_edit_properties_trusted"
+msgstr "Trusted add-ons can become public without Editor review."
+
+#. %s is href="..." and should stay in the <a> tag.
+#: views/developers/addon_edit_properties.thtml:119
+msgid "devcp_edit_properties_undelete"
+msgstr "Icon will be deleted on save. <a %s>Cancel?</a>"
+
+#: views/developers/addon_edit_properties.thtml:161
+msgid "devcp_edit_properties_view_source"
+msgstr ""
+"The source of your add-on files can be viewed online by any logged in user "
+"if you wish."
+
+#: views/developers/addon_edit_properties.thtml:162
+msgid "devcp_edit_properties_view_source_allow"
+msgstr "Allow online source viewing"
+
+#: views/developers/addon_edit_properties.thtml:163
+msgid "devcp_edit_properties_view_source_do_not_allow"
+msgstr "Do not allow online source viewing"
+
+#: views/elements/developers/editbox.thtml:46
+msgid "devcp_editbox_authors"
+msgstr "Authors"
+
+#: views/elements/developers/editbox.thtml:47
+msgid "devcp_editbox_categories"
+msgstr "Categories"
+
+#: views/elements/developers/editbox.thtml:52
+msgid "devcp_editbox_change_status"
+msgstr "Change Status"
+
+#: views/elements/developers/editbox.thtml:48
+msgid "devcp_editbox_descriptions"
+msgstr "Descriptions"
+
+#: views/elements/developers/editbox.thtml:43
+msgid "devcp_editbox_edit_addon"
+msgstr "Edit Add-on"
+
+#: views/elements/developers/editbox.thtml:57
+msgid "devcp_editbox_new_version"
+msgstr "New Version"
+
+#: views/elements/developers/editbox.thtml:49
+msgid "devcp_editbox_properties"
+msgstr "Properties"
+
+#: views/elements/developers/editbox.thtml:60
+msgid "devcp_editbox_screenshots"
+msgstr "Preview Screenshots"
+
+#: views/elements/developers/editbox.thtml:53
+msgid "devcp_editbox_statistics_dashboard"
+msgstr "Statistics Dashboard"
+
+#: views/elements/developers/editbox.thtml:54
+msgid "devcp_editbox_versions"
+msgstr "Versions and Files"
+
+#: views/elements/developers/editbox.thtml:42
+msgid "devcp_editbox_view_listing"
+msgstr "View Listing"
+
+#: views/elements/developers/editorsmenu.thtml:59
+msgid "devcp_editorsqueue_featured"
+msgstr "Featured Add-ons"
+
+#. %1 is the review count
+#: views/elements/developers/editorsqueue.thtml:42
+#: views/elements/developers/editorsmenu.thtml:56
+#, php-format
+msgid "devcp_editorsqueue_moderatedreviews"
+msgid_plural "devcp_editorsqueue_moderatedreviews"
+msgstr[0] "Moderated Reviews (%s)"
+msgstr[1] "Moderated Reviews (%s)"
+
+#. %1 is the nominated addons count
+#: views/elements/developers/editorsqueue.thtml:44
+#: views/elements/developers/editorsmenu.thtml:58
+#, php-format
+msgid "devcp_editorsqueue_nominated"
+msgid_plural "devcp_editorsqueue_nominated"
+msgstr[0] "Nominated Add-ons (%s)"
+msgstr[1] "Nominated Add-ons (%s)"
+
+#. %1 is the update count
+#: views/elements/developers/editorsqueue.thtml:43
+#: views/elements/developers/editorsmenu.thtml:57
+#, php-format
+msgid "devcp_editorsqueue_pendingupdates"
+msgid_plural "devcp_editorsqueue_pendingupdates"
+msgstr[0] "Pending Updates (%s)"
+msgstr[1] "Pending Updates (%s)"
+
+#: controllers/statistics_controller.php:147
+#: controllers/statistics_controller.php:361
+#: controllers/previews_controller.php:108
+#: controllers/previews_controller.php:211
+#: controllers/previews_controller.php:312
+msgid "devcp_error_addon_access_denied"
+msgstr "You do not have access to that add-on."
+
+#. %s is a complete URL with the text from devcp_error_appversion_reference_link_text
+#. in the <a> tag. This should be fixed.
+#: controllers/components/developers.php:591
+#, php-format
+msgid "devcp_error_appversion_reference_link"
+msgstr "Please see %s for reference."
+
+#. This is the link text in the <a> for devcp_error_appversion_reference_link. This
+#. should be fixed.
+#: controllers/components/developers.php:591
+msgid "devcp_error_appversion_reference_link_text"
+msgstr "this page"
+
+#: views/developers/addon_edit_authors.thtml:76
+msgid "devcp_error_empty_authors"
+msgstr "Your add-on must have at least one owner."
+
+#. %1$s is the name of the file
+#: controllers/components/developers.php:658
+msgid "devcp_error_file_exists"
+msgstr ""
+"A version of that add-on already exists. To replace it, you must delete the "
+"file %1$s first."
+
+#. %1$s is a file extension. Example: .exe
+#. %2$s is a comma separated list of extensions. Example: .xpi, .jar
+#: controllers/components/developers.php:355
+#, php-format
+msgid "devcp_error_file_extension"
+msgstr ""
+"That file extension (%1$s) is not allowed for the selected add-on type. "
+"Please use one of the following: %2$s"
+
+#: controllers/components/developers.php:64
+msgid "devcp_error_five_categories"
+msgstr "Please select no more than five categories."
+
+#: controllers/components/developers.php:526
+msgid "devcp_error_guid_application"
+msgstr "The ID of this add-on is already used by an application."
+
+#: controllers/components/developers.php:337
+#: controllers/components/developers.php:389
+msgid "devcp_error_http_incomplete"
+msgstr "Incomplete transfer"
+
+#: controllers/components/developers.php:335
+#: controllers/components/developers.php:336
+#: controllers/components/developers.php:387
+#: controllers/components/developers.php:388
+msgid "devcp_error_http_maxupload"
+msgstr "Exceeds maximum upload size"
+
+#: controllers/components/developers.php:338
+#: controllers/components/developers.php:390
+msgid "devcp_error_http_nofile"
+msgstr "No file uploaded"
+
+#. %1$s is a file extension. Example: .exe
+#. %2$s is a comma separated list of extensions. Example: .xpi, .jar
+#: controllers/components/developers.php:401
+#, php-format
+msgid "devcp_error_icon_extension"
+msgstr ""
+"That file extension (%1$s) is not allowed for an icon. Please use one of the "
+"following: %2$s"
+
+#: controllers/developers_controller.php:504
+msgid "devcp_error_index_rdf_notfound"
+msgstr "No install.rdf present."
+
+#: controllers/components/developers.php:601
+msgid "devcp_error_install_manifest"
+msgstr "The following errors were found in install.rdf:"
+
+#: controllers/developers_controller.php:1463
+msgid "devcp_error_invalid_addontype"
+msgstr ""
+
+#. %$1s is a version. Example: 3.1.1
+#. %$2s is an add-on name.
+#: controllers/components/developers.php:569
+#: controllers/components/developers.php:581
+#, php-format
+msgid "devcp_error_invalid_appversion"
+msgstr "%1$s is not a valid version for %2$s"
+
+#. %s is a string
+#: controllers/components/developers.php:521
+#, php-format
+msgid "devcp_error_invalid_guid"
+msgstr "The ID of this add-on is invalid: %s"
+
+#. %$1s is a version. Example: 3.1.1
+#. %$2s is an add-on name.
+#: controllers/components/developers.php:572
+#, php-format
+msgid "devcp_error_invalid_minversion"
+msgstr ""
+"%1$s is not a valid version for %2$s: minimum versions cannot contain *"
+
+#: controllers/components/developers.php:536
+msgid "devcp_error_invalid_version"
+msgstr ""
+"The version of this add-on is invalid: please see the <a href=\"http://"
+"developer.mozilla.org/en/docs/Toolkit_version_format\">specification</a>"
+
+#: controllers/components/developers.php:531
+msgid "devcp_error_invalid_version_spaces"
+msgstr "The version of this add-on is invalid: versions cannot contain spaces."
+
+#. %s is an error message from the parser.
+#: controllers/components/developers.php:501
+#, php-format
+msgid "devcp_error_manifest_parse"
+msgstr "The following error occurred while parsing install.rdf: %s"
+
+#: controllers/components/developers.php:373
+msgid "devcp_error_move_file"
+msgstr "Could not move file"
+
+#. %s is the name of a file
+#: controllers/components/developers.php:650
+#: controllers/components/developers.php:662
+#: controllers/components/developers.php:667
+#: controllers/components/developers.php:727
+#: controllers/components/developers.php:738
+#: controllers/components/developers.php:743
+#, php-format
+msgid "devcp_error_moving_file"
+msgstr "An error occurred moving %s."
+
+#: controllers/components/developers.php:595
+msgid "devcp_error_mozilla_application"
+msgstr "You must have at least one valid Mozilla target application."
+
+#: controllers/components/developers.php:516
+msgid "devcp_error_no_guid"
+msgstr "No ID could be found for this add-on in install.rdf."
+
+#: controllers/components/developers.php:287
+msgid "devcp_error_no_platform"
+msgstr "No platform selected"
+
+#: controllers/components/developers.php:59
+msgid "devcp_error_one_category"
+msgstr "Please select at least one category."
+
+#: controllers/components/developers.php:92
+msgid "devcp_error_one_user"
+msgstr "There must be at least one author for this add-on."
+
+#. %1$s is a file extension. Example: .exe
+#. %2$s is a comma separated list of extensions. Example: .xpi, .jar
+#: controllers/components/developers.php:1081
+#, php-format
+msgid "devcp_error_preview_extension"
+msgstr ""
+"That file extension (%1$s) is not allowed for a preview. Please use one of "
+"the following: %2$s"
+
+#: controllers/components/developers.php:511
+msgid "devcp_error_updatekey"
+msgstr ""
+"Add-ons cannot use an updateKey. Please remove this from install.rdf and try "
+"again."
+
+#: controllers/components/developers.php:506
+msgid "devcp_error_updateurl"
+msgstr ""
+"Add-ons cannot use an external updateURL. Please remove this from install."
+"rdf and try again."
+
+#: controllers/developers_controller.php:465
+#: controllers/components/developers.php:271
+msgid "devcp_error_upload_file"
+msgstr "Please upload a file."
+
+#: views/developers/uploader.thtml:135
+msgid "devcp_input_upload_file"
+msgstr "Upload File"
+
+#: views/pages/js_constants.js.thtml:89
+msgid "devcp_js_a_cancel"
+msgstr "Cancel"
+
+#: views/pages/js_constants.js.thtml:90
+msgid "devcp_js_add_email"
+msgstr "Please enter the account email of the author you wish to add."
+
+#. alt text for a down-arrow image.
+#: views/pages/js_constants.js.thtml:81
+msgid "devcp_js_img_move_down"
+msgstr "Move Down"
+
+#. alt text for an up-arrow image.
+#: views/pages/js_constants.js.thtml:82
+msgid "devcp_js_img_move_up"
+msgstr "Move Up"
+
+#: views/pages/js_constants.js.thtml:91
+msgid "devcp_js_img_remove_compat"
+msgstr "Remove Application Compatibility"
+
+#: views/pages/js_constants.js.thtml:86
+msgid "devcp_js_input_list_author"
+msgstr "List as author in public listings"
+
+#: views/pages/js_constants.js.thtml:92
+msgid "devcp_js_license_select"
+msgstr "Please select a license."
+
+#: views/pages/js_constants.js.thtml:93
+msgid "devcp_js_license_text"
+msgstr "Please enter text for your license."
+
+#. <option> text in a <select> for Author role in an add-on.
+#: views/pages/js_constants.js.thtml:84
+msgid "devcp_js_option_developer"
+msgstr "Developer"
+
+#. <option> text in a <select> for Author role in an add-on.
+#: views/pages/js_constants.js.thtml:83
+msgid "devcp_js_option_owner"
+msgstr "Owner"
+
+#. <option> text in a <select> for Author role in an add-on.
+#: views/pages/js_constants.js.thtml:85
+msgid "devcp_js_option_viewer"
+msgstr "Viewer"
+
+#: views/pages/js_constants.js.thtml:88
+msgid "devcp_js_remove_author"
+msgstr "Remove Author"
+
+#: views/pages/js_constants.js.thtml:87
+msgid "devcp_js_sure_remove"
+msgstr "Are you <strong>sure</strong> you wish to remove this author?"
+
+#: views/pages/js_constants.js.thtml:77
+msgid "devcp_js_upload_alert"
+msgstr "You must select a file to upload."
+
+#. %1$s is an addon id, like 32.
+#. %2$s is a version number, like 3.5.
+#: controllers/components/developers.php:1212
+msgid "devcp_license_existing"
+msgstr "Custom license for add-on %1$s v%2$s"
+
+#: views/elements/developers/localebox.thtml:44
+msgid "devcp_localebox_header_localizedfields"
+msgstr "Localized Fields"
+
+#. %1 is the default locale
+#: views/elements/developers/localebox.thtml:48
+#, php-format
+msgid "devcp_localebox_intro"
+msgstr ""
+"Some of the fields on this page are localized to appear in the end-user's "
+"native language. Select a locale below to edit your add-on's details in that "
+"language. If a translation for a locale is not available, it will fall back "
+"to the selected default locale (%s)."
+
+#: views/elements/developers/sidebar.thtml:68
+#: views/elements/developers/myaddons.thtml:75
+msgid "devcp_myaddons_admincp_link"
+msgstr "Admin Tools"
+
+#: views/elements/developers/sidebar.thtml:65
+#: views/elements/developers/myaddons.thtml:72
+msgid "devcp_myaddons_editorcp_link"
+msgstr "Editor Tools"
+
+#: views/elements/developers/myaddons.thtml:52
+msgid "devcp_myaddons_link"
+msgstr "My Add-ons"
+
+#: views/elements/developers/sidebar.thtml:70
+#: views/elements/developers/myaddons.thtml:77
+msgid "devcp_myaddons_mainpage_link"
+msgstr "Back to Main"
+
+#: views/elements/developers/sidebar.thtml:63
+#: views/elements/developers/myaddons.thtml:70
+msgid "devcp_myaddons_statistics_link"
+msgstr "Statistics Dashboard"
+
+#: views/elements/developers/sidebar.thtml:62
+#: views/elements/developers/myaddons.thtml:69
+msgid "devcp_myaddons_submitaddon_link"
+msgstr "Submit Add-on"
+
+#: views/elements/developers/sidebar.thtml:48
+#: views/elements/developers/myaddons.thtml:67
+msgid "devcp_myaddons_title"
+msgstr "Developer Tools"
+
+#. %1$s is an add-on ID, perhaps 167.
+#. %2$s is a URL.
+#: controllers/developers_controller.php:256
+msgid "devcp_new_addon_error"
+msgstr ""
+"This add-on ID (%1$s) already exists in the database. If this is your add-"
+"on, you can <a href=\"%2$s\">upload a new version</a>."
+
+#: views/developers/addon_status_nominate.thtml:62
+msgid "devcp_nominate_cancel"
+msgstr "Cancel and return"
+
+#. %1 is the add-on name
+#: views/developers/addon_status_nominate.thtml:61
+#, php-format
+msgid "devcp_nominate_submit_nominate"
+msgstr "Nominate %s"
+
+#: views/developers/addon_edit_properties.thtml:50
+#: views/developers/addon_status.thtml:49
+#: views/developers/versions_edit.thtml:50
+msgid "devcp_notice_changes_error"
+msgstr ""
+"<span>One or more of your changes couldn't be saved.</span><br />Please look "
+"for the errors below. The rest of your changes were successfully saved."
+
+#: views/developers/addon_edit_authors.thtml:47
+#: views/developers/addon_edit_properties.thtml:47
+#: views/developers/addon_status.thtml:46
+#: views/developers/addon_edit_descriptions.thtml:47
+#: views/developers/versions_edit.thtml:47
+#: views/developers/addon_edit_categories.thtml:46
+msgid "devcp_notice_changes_saved"
+msgstr ""
+"<span>Your changes have been saved.</span><br />Please note that some "
+"changes may take several hours to appear in all areas of the website."
+
+#: controllers/previews_controller.php:252
+msgid "devcp_notice_cleardefault"
+msgstr ""
+"Removing this as the default preview will cause another preview to "
+"automatically become the default preview."
+
+#: controllers/previews_controller.php:184
+#: controllers/previews_controller.php:251
+msgid "devcp_notice_makedefault"
+msgstr ""
+"Making this the default preview will remove default status from the current "
+"default preview."
+
+#: views/developers/addon_edit_authors.thtml:70
+msgid "devcp_notice_unsaved_changes"
+msgstr "You have unsaved changes."
+
+#: controllers/developers_controller.php:87
+#: controllers/developers_controller.php:97
+#: controllers/developers_controller.php:100
+#: controllers/previews_controller.php:67
+#: controllers/previews_controller.php:79
+#: controllers/previews_controller.php:82
+msgid "devcp_pagetitle"
+msgstr "Developer Tools"
+
+#: controllers/previews_controller.php:103
+#: controllers/previews_controller.php:104
+msgid "devcp_preview_add_pagetitle"
+msgstr "Add Preview"
+
+#: controllers/previews_controller.php:135
+msgid "devcp_preview_added_successfully"
+msgstr "Preview added successfully."
+
+#: controllers/previews_controller.php:323
+msgid "devcp_preview_deleted_successfully"
+msgstr "Preview deleted successfully."
+
+#: controllers/previews_controller.php:194
+#: controllers/previews_controller.php:195
+msgid "devcp_preview_edit_pagetitle"
+msgstr "Edit Preview"
+
+#: controllers/previews_controller.php:237
+msgid "devcp_preview_updated_successfully"
+msgstr "Preview updated successfully."
+
+#: views/developers/previews.thtml:120
+msgid "devcp_previews_a_another"
+msgstr "Add Another Preview"
+
+#: views/developers/previews.thtml:96
+msgid "devcp_previews_a_delete"
+msgstr "Delete Preview"
+
+#: views/developers/previews.thtml:95
+msgid "devcp_previews_a_replace"
+msgstr "Replace Preview"
+
+#: views/developers/previews.thtml:126
+msgid "devcp_previews_a_update"
+msgstr "Update Previews"
+
+#: views/developers/previews.thtml:115 views/developers/previews.thtml:124
+msgid "devcp_previews_add_new"
+msgstr "Add New Preview"
+
+#. %s is a list of file extensions, e.g. ".png, .gif"
+#: views/developers/previews.thtml:116
+msgid "devcp_previews_add_select"
+msgstr ""
+"Select an image to upload below. Images larger than the maximum size of 700 "
+"pixels wide by 525 pixels tall will be resized. Allowed file types: %s"
+
+#: views/developers/previews.thtml:121
+msgid "devcp_previews_click_below"
+msgstr "Click Update Previews below to upload."
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/previews.thtml:102
+msgid "devcp_previews_click_update"
+msgstr ""
+"Click the Update Previews button below to save this image. (<a %s>Cancel?</"
+"a>)"
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/previews.thtml:107
+msgid "devcp_previews_error_message"
+msgstr ""
+"This preview will be deleted when Update Previews is clicked below. (<a %"
+"s>Cancel?</a>)"
+
+#: views/previews/add.thtml:45
+msgid "devcp_previews_filetype_info"
+msgstr ""
+"Use the form below to upload a PNG, JPG, or GIF screenshot of your add-on. "
+"Images larger than 700 pixels wide and 525 pixels high will automatically be "
+"resized."
+
+#: views/previews/add.thtml:43
+msgid "devcp_previews_header_add"
+msgstr "Add Preview"
+
+#: views/developers/previews.thtml:80
+msgid "devcp_previews_header_caption"
+msgstr "Preview Caption"
+
+#: views/previews/edit.thtml:43
+msgid "devcp_previews_header_edit"
+msgstr "Edit Preview"
+
+#: views/developers/previews.thtml:93
+msgid "devcp_previews_label_default"
+msgstr "Default Preview"
+
+#: views/previews/add.thtml:54
+msgid "devcp_previews_label_file"
+msgstr "Preview File"
+
+#: views/previews/add.thtml:59 views/previews/edit.thtml:50
+msgid "devcp_previews_label_makedefault"
+msgstr "Make this the default preview image"
+
+#: views/developers/previews.thtml:100
+msgid "devcp_previews_label_new"
+msgstr "New image:"
+
+#: views/developers/previews.thtml:118
+msgid "devcp_previews_label_upload"
+msgstr "Upload Preview: "
+
+#: views/developers/previews.thtml:50
+msgid "devcp_previews_notice_error"
+msgstr "One or more of your new previews could not be saved."
+
+#: views/developers/previews.thtml:47
+msgid "devcp_previews_notice_success"
+msgstr "Your previews have been updated successfully."
+
+#: views/developers/previews.thtml:59
+msgid "devcp_previews_p_screenshots"
+msgstr ""
+"The preview screenshots for your add-on are shown below. You can make "
+"changes to captions or images below. The Default Preview is the preview that "
+"is displayed next to your add-on in search and browse listings."
+
+#: views/previews/edit.thtml:55
+msgid "devcp_previews_submit_delete"
+msgstr "Delete Preview"
+
+#: views/previews/edit.thtml:55
+msgid "devcp_previews_submit_delete_confirm"
+msgstr "Are you sure you wish to delete this preview?"
+
+#: views/previews/edit.thtml:54
+msgid "devcp_previews_submit_edit"
+msgstr "Edit Preview"
+
+#: views/previews/add.thtml:63
+msgid "devcp_previews_submit_upload"
+msgstr "Upload Preview"
+
+#: views/developers/previews.thtml:78
+msgid "devcp_previews_thumbnail"
+msgstr "Thumbnail"
+
+#. %s is the add-on name.
+#: views/developers/previews.thtml:44
+msgid "devcp_previews_title"
+msgstr "%s Preview Manager"
+
+#: views/developers/uploader.thtml:74
+msgid "devcp_review_agreement_please"
+msgstr ""
+"Please review and accept the following Developer Agreement before proceeding."
+
+#: views/elements/developers/rolecheck.thtml:42
+msgid "devcp_rolecheck_no_privs"
+msgstr ""
+"<span>You do not have sufficient privileges to make changes on this page.</"
+"span><br />Contact the Add-on Owner if you need to make changes."
+
+#: controllers/developers_controller.php:1315
+msgid "devcp_several_hours"
+msgstr ""
+"Please note that some changes may take several hours to appear in all areas "
+"of the website."
+
+#: views/elements/developers/sidebar.thtml:52
+msgid "devcp_sidebar_a_dashboard"
+msgstr "Dashboard"
+
+#. %s is a number
+#: views/elements/developers/statsbar.thtml:45
+#: views/developers/dashboard.thtml:79
+#, php-format
+msgid "devcp_statsbar_adu"
+msgstr "<em>%s</em> Active Daily Users"
+
+#. %s is a number
+#: views/elements/developers/statsbar.thtml:41
+#: views/developers/dashboard.thtml:75
+#, php-format
+msgid "devcp_statsbar_total_downloads"
+msgstr "<em>%s</em> Total Downloads"
+
+#. %s is a number
+#: views/elements/developers/statsbar.thtml:43
+#: views/developers/dashboard.thtml:77
+#, php-format
+msgid "devcp_statsbar_weekly_downloads"
+msgstr "<em>%s</em> Weekly Downloads"
+
+#: views/developers/addon_status_confirm.thtml:59
+msgid "devcp_status_confirm_active"
+msgstr ""
+"Marking this add-on active will cause it to show up in public areas "
+"appropriate for its status, including search and browse listings. It will be "
+"downloadable from the website and could be returned in client update checks, "
+"depending on its status. You will be able to return here and disable it "
+"again at your convenience."
+
+#: views/developers/addon_status_confirm.thtml:59
+msgid "devcp_status_confirm_active_sure"
+msgstr "Are you sure you wish to mark this add-on active?"
+
+#: views/developers/addon_status_confirm.thtml:50
+msgid "devcp_status_confirm_header_sure"
+msgstr "Are you sure?"
+
+#: views/developers/addon_status_confirm.thtml:55
+msgid "devcp_status_confirm_inactive"
+msgstr ""
+"Marking this add-on inactive will prevent it from showing up in any public "
+"areas, including search and browse listings. It will not be downloadable "
+"from the website and will not be returned in client update checks. You will "
+"be able to return here and re-enable it at your convenience."
+
+#: views/developers/addon_status_confirm.thtml:55
+msgid "devcp_status_confirm_inactive_sure"
+msgstr "Are you sure you wish to mark this add-on inactive?"
+
+#: views/developers/addon_status_confirm.thtml:74
+msgid "devcp_status_confirm_no"
+msgstr "No, cancel"
+
+#: views/developers/addon_status_confirm.thtml:67
+msgid "devcp_status_confirm_public"
+msgstr ""
+"Making this add-on public will make it available for anyone to download and "
+"will begin offering updates to existing users."
+
+#: views/developers/addon_status_confirm.thtml:67
+msgid "devcp_status_confirm_public_sure"
+msgstr "Are you sure you wish to make this add-on public?"
+
+#: views/developers/addon_status_confirm.thtml:63
+msgid "devcp_status_confirm_sandbox"
+msgstr ""
+"Moving this add-on back to the sandbox will require users to log in before "
+"downloading and updates will no longer be offered to existing users. Because "
+"your add-on is currently public, you will be able to return here at any time "
+"to make it public again."
+
+#: views/developers/addon_status_confirm.thtml:63
+msgid "devcp_status_confirm_sandbox_sure"
+msgstr "Are you sure you wish to move this add-on to the sandbox?"
+
+#: views/developers/addon_status_confirm.thtml:73
+msgid "devcp_status_confirm_yes"
+msgstr "Yes, I'm Sure"
+
+#: views/developers/addon_status_nominate.thtml:46
+msgid "devcp_status_nominate_error_notice"
+msgstr ""
+"<span>A nomination message is required.</span><br />Please fill in the text "
+"box with the requested information and try again."
+
+#: views/developers/addon_status_nominate.thtml:55
+msgid "devcp_status_nominate_header"
+msgstr "Add-on Nomination"
+
+#: views/developers/dashboard.thtml:85
+msgid "devcp_summary_lastversion"
+msgstr "Latest Version:"
+
+#. %s is the add-on name.
+#: views/developers/addon_edit.thtml:43
+#: views/developers/addon_edit_authors.thtml:44
+#: views/developers/versions_delete.thtml:43
+#: views/developers/addon_edit_properties.thtml:44
+#: views/developers/addon_edit_descriptions.thtml:44
+#: views/developers/versions_edit.thtml:44
+#: views/developers/addon_edit_categories.thtml:43
+#: views/developers/versions.thtml:43
+msgid "devcp_title_edit_addon"
+msgstr "Edit %s"
+
+#. title attribute for a javascript link that pops up a help dialog.
+#: views/elements/translationbox.thtml:68
+msgid "devcp_transbox_a_title_help"
+msgstr "Help (does not leave page)"
+
+#: views/elements/translationbox.thtml:68
+msgid "devcp_transbox_alt_help"
+msgstr "Help"
+
+#. %1$s is <span>17</span>, %2$s is 42.
+#: views/elements/translationbox.thtml:101
+msgid "devcp_transbox_chars_used"
+msgstr "Characters used: %1$s / %2$s"
+
+#: views/elements/translationbox.thtml:132
+msgid "devcp_transbox_delete_sure"
+msgstr "Are you sure you wish to delete this translation?"
+
+#. %s is a locale, like en-US.
+#: views/elements/translationbox.thtml:143
+msgid "devcp_transbox_help_header_tabs"
+msgstr "What are these %s tabs?"
+
+#: views/elements/translationbox.thtml:145
+msgid "devcp_transbox_help_header_what"
+msgstr "What if I don't have any translations?"
+
+#: views/elements/translationbox.thtml:147
+msgid "devcp_transbox_help_hide"
+msgstr "Hide Help"
+
+#: views/elements/translationbox.thtml:146
+msgid "devcp_transbox_help_if"
+msgstr ""
+"If a user browses the site and a translation isn't available in their own "
+"language, it will fall back to your add-on's Default Locale, specified in "
+"the Edit Add-on Properties area. If you don't have any translations, just "
+"enter what you can into your Default Locale, which should be a language you "
+"speak."
+
+#: views/elements/translationbox.thtml:144
+msgid "devcp_transbox_help_transbox"
+msgstr ""
+"This is a <i>Translation Box</i>. It allows you to localize a specific field "
+"into any other languages for which you might have a translation. You can "
+"add, edit, and remove translations using the locale tabs."
+
+#: views/elements/translationbox.thtml:85
+msgid "devcp_transbox_img_add_trans"
+msgstr "Add Translation"
+
+#: views/elements/translationbox.thtml:86
+msgid "devcp_transbox_img_remove_trans"
+msgstr "Remove Translation"
+
+#: views/elements/translationbox.thtml:123
+msgid "devcp_transbox_input_add_all"
+msgstr "Add Locale to All"
+
+#: views/elements/translationbox.thtml:122
+msgid "devcp_transbox_input_add_locale"
+msgstr "Add Locale"
+
+#: views/elements/translationbox.thtml:124
+#: views/elements/translationbox.thtml:135
+msgid "devcp_transbox_input_cancel"
+msgstr "Cancel"
+
+#: views/elements/translationbox.thtml:134
+msgid "devcp_transbox_input_delete"
+msgstr "Delete It"
+
+#: views/elements/translationbox.thtml:113
+msgid "devcp_transbox_select_locale"
+msgstr "Select the locale of the translation to add:"
+
+#. %1$s and %2$s are GUIDs.
+#: controllers/developers_controller.php:343
+msgid "devcp_update_addon_guid_error"
+msgstr ""
+"The add-on GUID used in this file (%1$s) does not match the existing GUID "
+"for this add-on (%2$s)."
+
+#: controllers/developers_controller.php:334
+msgid "devcp_update_addon_priv_error"
+msgstr "You do not have sufficient privileges to update this add-on."
+
+#. %1$s is a version number, %2$s is an add-on ID.
+#: controllers/developers_controller.php:399
+msgid "devcp_update_addon_version_belong_error"
+msgstr "The specified version (%1$s) does not belong to this add-on (%2$s)."
+
+#. %1$s is a version number, maybe 1.1.
+#. %2$s is a URL.
+#: controllers/developers_controller.php:351
+msgid "devcp_update_addon_version_exists_error"
+msgstr ""
+"The version number uploaded (%1$s) already exists for this add-on. If you "
+"are trying to add another file to this version, <a href=\"%2$s\">click here</"
+"a>."
+
+#. %1$s and %2$s are version numbers.
+#: controllers/developers_controller.php:405
+msgid "devcp_update_addon_version_match_error"
+msgstr ""
+"The uploaded version number (%1$s) does not match the existing version "
+"number (%2$s)."
+
+#: views/developers/uploader.thtml:68
+msgid "devcp_uploader_a_start"
+msgstr "Get Started"
+
+#: views/developers/uploader.thtml:137
+msgid "devcp_uploader_ajax_loading"
+msgstr "Uploading file..."
+
+#: views/developers/uploader.thtml:82
+msgid "devcp_uploader_button_agree"
+msgstr "Agree and continue"
+
+#: views/developers/uploader.thtml:157
+msgid "devcp_uploader_button_edit"
+msgstr "Edit My Add-on"
+
+#: views/developers/uploader.thtml:158
+msgid "devcp_uploader_button_later"
+msgstr "I'll complete my add-on later."
+
+#: views/developers/uploader.thtml:168
+msgid "devcp_uploader_button_release"
+msgstr "Add Release Notes"
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/uploader.thtml:156
+msgid "devcp_uploader_created_results"
+msgstr ""
+"<p>Your add-on listing has been successfully created. The basic information "
+"obtained from your uploaded file has been stored, but there's a lot more to "
+"your listing that can be customized.</p><p>Your add-on is currently marked "
+"as <strong>Incomplete</strong>. In order to complete your add-on, you'll "
+"need to make sure it has an accurate name, summary, and description, as well "
+"as at least one selected category. You can edit your add-on's information "
+"using the link below and check the status of your add-on at any time on the "
+"<a %s>status page</a>."
+
+#: views/developers/uploader.thtml:143
+msgid "devcp_uploader_error_correct"
+msgstr "Please correct this problem and upload your file again."
+
+#. %1$s is a version number, %2$s is a status, e.g Public or Incomplete.
+#: views/developers/uploader.thtml:175
+msgid "devcp_uploader_file_created"
+msgstr ""
+"Your new file has been added to version %1$s and is currently marked as %2$s."
+
+#: views/developers/uploader.thtml:154
+msgid "devcp_uploader_header_created"
+msgstr "Add-on Created!"
+
+#: views/developers/uploader.thtml:141
+msgid "devcp_uploader_header_error"
+msgstr "Oops! There seems to be a problem with this file..."
+
+#: views/developers/uploader.thtml:173
+msgid "devcp_uploader_header_file_added"
+msgstr "File Added!"
+
+#: views/developers/uploader.thtml:66
+msgid "devcp_uploader_header_how"
+msgstr "How does it all work?"
+
+#. %s is the version number, e.g. 3.2.
+#: views/developers/uploader.thtml:163
+msgid "devcp_uploader_header_update_created"
+msgstr "Version %s Created"
+
+#: views/developers/uploader.thtml:117
+msgid "devcp_uploader_header_upload"
+msgstr "Upload Your File"
+
+#: views/developers/uploader.thtml:67
+msgid "devcp_uploader_how"
+msgstr ""
+"<p>Thanks for your interest in submitting your add-on to Mozilla Add-ons. "
+"Hosting your add-on on Mozilla Add-ons is the easiest way to handle "
+"distribution of your add-on. Here's what you'll get:</p><ul><li>Each add-on "
+"will have a public display page with information you provide, such as a "
+"brief summary of the add-on's functionality, an optional longer description, "
+"and a showcase of preview screenshots of your add-on.</li><li>Your add-on "
+"will appear in search and browse listings across the site, and even in the "
+"Add-ons Manager of Firefox 3.</li><li>We'll take care of hosting all of your "
+"downloads and providing automatic updates to users when you upload a new "
+"version.</li><li>You'll have access to a statistics dashboard with detailed "
+"information about your user base.</li></ul><p>Add-ons hosted on the site "
+"must be reviewed by a Mozilla Add-ons Editor before they will have all of "
+"the features listed above. If you're ready to start the process and have "
+"your add-on package ready for upload, just click on Get Started below!</p>"
+
+#: views/developers/uploader.thtml:125
+msgid "devcp_uploader_label_platformtype"
+msgstr "Supported Platforms:"
+
+#: views/developers/uploader.thtml:124
+msgid "devcp_uploader_label_upload_field"
+msgstr "Add-on File: "
+
+#: controllers/components/developers.php:1221
+msgid "devcp_uploader_option_other"
+msgstr "Other"
+
+#. %1$s is a number, %2$s is href="..." and should stay in the <a> tag.
+#: views/developers/uploader.thtml:176
+msgid "devcp_uploader_p_pending_file"
+msgstr ""
+"The new file will be available to the public as soon as an editor is able to "
+"review it. There are currently %1$s other add-ons in the queue. Want to be "
+"reviewed faster? Consider <a %2$s>becoming an editor</a>."
+
+#. %1$s is a number, %2$s is href="..." and should stay in the <a> tag.
+#: views/developers/uploader.thtml:166
+msgid "devcp_uploader_p_pending_version"
+msgstr ""
+"The new version will be available to the public as soon as an editor is able "
+"to review it. There are currently %1$s other add-ons in the queue. Want to "
+"be reviewed faster? Consider <a %2$s>becoming an editor</a>."
+
+#. %s is a status, e.g Public or Incomplete.
+#: views/developers/uploader.thtml:165
+msgid "devcp_uploader_p_update_created"
+msgstr "Your new version has been created and is currently marked as %s."
+
+#. %1$s is href="..." and should stay in the 'Versions and Files' <a> tag.
+#. %2$s is href="..." and should stay in the 'current status' <a> tag.
+#: views/developers/uploader.thtml:177
+msgid "devcp_uploader_p_update_file"
+msgstr ""
+"View your new file in the <a %1$s>Versions and Files page</a>, check out "
+"your add-on's <a %2$s>current status</a>, or <b>add release notes</b> by "
+"clicking the button below (highly recommended)."
+
+#. %1$s is href="..." and should stay in the 'Versions and Files' <a> tag.
+#. %2$s is href="..." and should stay in the 'current status' <a> tag.
+#: views/developers/uploader.thtml:167
+msgid "devcp_uploader_p_update_version"
+msgstr ""
+"View your new version in the <a %1$s>Versions and Files page</a>, check out "
+"your add-on's <a %2$s>current status</a>, or <b>add release notes</b> by "
+"clicking the button below (highly recommended)."
+
+#: views/developers/uploader.thtml:118
+msgid "devcp_uploader_p_upload"
+msgstr ""
+"Upload your add-on file using the form below. If you have multiple, platform-"
+"specific files to upload, choose a single file and then upload the others "
+"using the Versions and Files Manager."
+
+#: views/developers/uploader.thtml:125
+msgid "devcp_uploader_platformtype_all"
+msgstr "All"
+
+#: views/developers/uploader.thtml:126
+msgid "devcp_uploader_platformtype_specific"
+msgstr "Specific:"
+
+#. Used as first item in a <select>.
+#: controllers/components/developers.php:1185
+msgid "devcp_uploader_please_choose"
+msgstr "Please Choose..."
+
+#. %1$s is the add-on name, %2$s is the version number.
+#: views/developers/uploader.thtml:57
+msgid "devcp_uploader_title_file"
+msgstr "Add File to %1$s %2$s"
+
+#: views/developers/uploader.thtml:50
+msgid "devcp_uploader_title_submit"
+msgstr "Submit New Add-on"
+
+#. %s is the add-on name.
+#: views/developers/uploader.thtml:54
+msgid "devcp_uploader_title_update"
+msgstr "Update %s"
+
+#. %s is a full <a> tag
+#: controllers/developers_controller.php:503
+#, php-format
+msgid "devcp_valid_app_reference"
+msgstr "Please see %s for reference."
+
+#. This is the text in the <a> tag for devcp_valid_app_reference. This should be
+#. fixed.
+#: controllers/developers_controller.php:503
+msgid "devcp_valid_app_reference_linktext"
+msgstr "this page"
+
+#: controllers/developers_controller.php:581
+msgid "devcp_verify_author_error"
+msgstr "No account found for that email address."
+
+#: controllers/developers_controller.php:553
+msgid "devcp_verify_search_engine_error"
+msgstr ""
+"Either the XML is invalid or required fields are missing. Please <a href="
+"\"https://developer.mozilla.org/en/Creating_OpenSearch_plugins_for_Firefox"
+"\">read the documentation</a>, verify your add-on, and try again."
+
+#: views/developers/versions.thtml:75
+msgid "devcp_versions_a_cancel"
+msgstr "Cancel"
+
+#: views/developers/versions.thtml:79
+msgid "devcp_versions_a_delete"
+msgstr "Delete Version"
+
+#: views/developers/versions.thtml:74
+msgid "devcp_versions_a_empty"
+msgstr "Remove Empty Version"
+
+#: views/developers/versions.thtml:71
+msgid "devcp_versions_a_remove"
+msgstr "Remove?"
+
+#: views/developers/versions.thtml:91
+msgid "devcp_versions_add"
+msgstr "Add New Version"
+
+#: views/developers/versions_delete.thtml:58
+msgid "devcp_versions_delete_a_cancel"
+msgstr "Cancel"
+
+#: views/developers/versions_delete.thtml:56
+msgid "devcp_versions_delete_a_delete"
+msgstr "Delete Version"
+
+#. Followed by a list of reviews and files that will be removed.
+#: views/developers/versions_delete.thtml:50
+msgid "devcp_versions_delete_also"
+msgstr "This will also delete:"
+
+#: views/developers/versions_delete.thtml:53
+msgid "devcp_versions_delete_files"
+msgid_plural "devcp_versions_delete_files"
+msgstr[0] "%s file"
+msgstr[1] "%s files"
+
+#. %s is the version number.
+#: views/developers/versions_delete.thtml:48
+msgid "devcp_versions_delete_header"
+msgstr "Delete Version %s?"
+
+#: views/developers/versions_delete.thtml:52
+msgid "devcp_versions_delete_reviews"
+msgid_plural "devcp_versions_delete_reviews"
+msgstr[0] "%s review"
+msgstr[1] "%s reviews"
+
+#. %s is the version number.
+#: views/developers/versions_delete.thtml:49
+msgid "devcp_versions_delete_sure"
+msgstr "Are you sure you want to permanently delete version %s?"
+
+#: views/developers/versions_edit.thtml:102
+#: views/developers/versions_edit.thtml:155
+msgid "devcp_versions_edit_a_cancel"
+msgstr "Cancel"
+
+#: views/developers/versions_edit.thtml:101
+msgid "devcp_versions_edit_a_delete"
+msgstr "Delete File"
+
+#: views/developers/versions_edit.thtml:165
+msgid "devcp_versions_edit_a_new_app"
+msgstr "Add New Application"
+
+#: views/developers/versions_edit.thtml:154
+msgid "devcp_versions_edit_a_remove_app"
+msgstr "Remove Application"
+
+#: views/developers/versions_edit.thtml:114
+msgid "devcp_versions_edit_add"
+msgstr "Add New File"
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/versions_edit.thtml:121
+msgid "devcp_versions_edit_adjust"
+msgstr ""
+"Adjusting application information here will allow users to install your add-"
+"on even if the install.rdf in the package indicates that the add-on is "
+"incompatible. <a %s>List of supported applications</a>"
+
+#: views/developers/versions_edit.thtml:153
+msgid "devcp_versions_edit_compat_sure"
+msgstr ""
+"Are you <b>sure</b> you wish to remove compatibility with this application?"
+
+#: views/developers/versions_edit.thtml:100
+msgid "devcp_versions_edit_delete_sure"
+msgstr "Are you <b>sure</b> you wish to permanently delete this file?"
+
+#: views/developers/versions_edit.thtml:203
+msgid "devcp_versions_edit_header_approval"
+msgstr "Approval Information"
+
+#: views/developers/versions_edit.thtml:120
+msgid "devcp_versions_edit_header_compat"
+msgstr "Compatible Applications"
+
+#: views/developers/versions_edit.thtml:74
+msgid "devcp_versions_edit_header_file"
+msgstr "File Information"
+
+#: views/developers/versions_edit.thtml:189
+msgid "devcp_versions_edit_header_license"
+msgstr "License"
+
+#. %s is the version number.
+#: views/developers/versions_edit.thtml:53
+msgid "devcp_versions_edit_header_manage"
+msgstr "Manage Version %s"
+
+#: views/developers/versions_edit.thtml:212
+msgid "devcp_versions_edit_header_notes"
+msgstr "Approval Notes"
+
+#: views/developers/versions_edit.thtml:98
+msgid "devcp_versions_edit_img_delete"
+msgstr "Delete File"
+
+#. %1$s is the file id, e.g. 18723.
+#. %2$s is the platform name, e.g. ALL or Windows.
+#. %3$s is the _('date) created.
+#. %4$s is the status, e.g. "In Sandbox" or "Public".
+#. %5$s is the _('date') status was changed.
+#: views/developers/versions_edit.thtml:208
+msgid "devcp_versions_edit_li_file"
+msgstr "File %1$s (%2$s) created on %3$s and changed to %4$s on %5$s"
+
+#: views/developers/versions_edit.thtml:190
+msgid "devcp_versions_edit_license_description"
+msgstr ""
+"Please select the appropriate license for your add-on. This license "
+"specifies the rights you grant on your source code."
+
+#: views/developers/versions_edit.thtml:111
+msgid "devcp_versions_edit_no_files"
+msgstr "No files found."
+
+#: views/developers/versions_edit.thtml:213
+msgid "devcp_versions_edit_optional"
+msgstr "Optional information for the Editor that reviews this version."
+
+#: views/developers/versions_edit.thtml:151
+msgid "devcp_versions_edit_remove_compat"
+msgstr "Remove Application Compatibility"
+
+#: views/developers/versions_edit.thtml:167
+msgid "devcp_versions_edit_select_app"
+msgstr "Please Select an Application"
+
+#: views/developers/versions_edit.thtml:78
+msgid "devcp_versions_edit_th_file"
+msgstr "File"
+
+#: views/developers/versions_edit.thtml:79
+msgid "devcp_versions_edit_th_platform"
+msgstr "Platform"
+
+#: views/developers/versions_edit.thtml:80
+msgid "devcp_versions_edit_th_size"
+msgstr "Size"
+
+#: views/developers/versions_edit.thtml:81
+msgid "devcp_versions_edit_th_status"
+msgstr "Status"
+
+#: views/developers/versions_edit.thtml:183
+msgid "devcp_versions_edit_transbox_releasenotes_description"
+msgstr ""
+"Information about changes in this release, new features, known bugs, and "
+"other useful information specific to this release/version. This information "
+"will also be available to users updating the add-on in the Firefox 3 Add-ons "
+"Manager interface."
+
+#: views/developers/versions_edit.thtml:182
+msgid "devcp_versions_edit_transbox_releasenotes_name"
+msgstr "Release Notes"
+
+#: views/developers/versions_edit.thtml:164
+msgid "devcp_versions_edit_unsaved_compat"
+msgstr ""
+"<strong>You have unsaved changes.</strong> Compatibility will not be deleted "
+"until you click Update Version below."
+
+#: views/developers/versions_edit.thtml:113
+msgid "devcp_versions_edit_unsaved_files"
+msgstr ""
+"<strong>You have unsaved changes.</strong> Files will not be deleted until "
+"you click Update Version below."
+
+#: views/developers/versions_edit.thtml:218
+msgid "devcp_versions_edit_update"
+msgstr "Update Versions"
+
+#: views/developers/versions.thtml:49
+msgid "devcp_versions_header_manage"
+msgstr "Manage Versions and Files"
+
+#: views/developers/versions.thtml:87
+msgid "devcp_versions_no_versions"
+msgstr "No versions."
+
+#. %s is a version number, base 10.
+#: views/developers/versions.thtml:46
+msgid "devcp_versions_notice_success"
+msgstr "Version %s deleted successfully."
+
+#: views/developers/versions.thtml:73
+msgid "devcp_versions_p_remove"
+msgstr ""
+"This version has no files associated with it and can be removed. Would you "
+"like to remove this version?"
+
+#: views/developers/versions.thtml:58
+msgid "devcp_versions_th_created"
+msgstr "Created"
+
+#: views/developers/versions.thtml:57
+msgid "devcp_versions_th_status"
+msgstr "Status"
+
+#: views/developers/versions.thtml:56
+msgid "devcp_versions_th_version"
+msgstr "Version"
+
+#: controllers/downloads_controller.php:91
+msgid "downloads_disable_warning"
+msgstr "This add-on is disabled"
+
+#: controllers/components/editors.php:57
+msgid "editor_review_error_addon_not_nominated"
+msgstr "This add-on has not been nominated."
+
+#: controllers/components/editors.php:213
+msgid "editor_review_error_file_not_pending"
+msgstr "This file is not pending review."
+
+#. Actions are, for example: approving or rejecting
+#: controllers/components/editors.php:79
+#: controllers/components/editors.php:182
+msgid "editor_review_error_no_action"
+msgstr "Please select a review action."
+
+#: controllers/components/editors.php:192
+msgid "editor_review_error_no_applications"
+msgstr "Please enter the applications you tested."
+
+#. Comments are required when an editor approves or rejects an add-on.
+#: controllers/components/editors.php:84
+#: controllers/components/editors.php:187
+msgid "editor_review_error_no_comments"
+msgstr "Please enter review comments."
+
+#: controllers/components/editors.php:161
+msgid "editor_review_error_no_files"
+msgstr "Please select at least one file to review."
+
+#: controllers/components/editors.php:197
+msgid "editor_review_error_no_operating_system"
+msgstr "Please enter the operating systems you tested."
+
+#: views/editors/logs.thtml:51
+msgid "editorcp_logs_button_filter"
+msgstr "Filter"
+
+#: views/editors/logs.thtml:44
+msgid "editorcp_logs_filter_by"
+msgstr "Filter by type/action"
+
+#: views/editors/logs.thtml:42 controllers/editors_controller.php:964
+msgid "editorcp_logs_page_heading"
+msgstr "Event Log"
+
+#: views/elements/developers/editorsmenu.thtml:60
+msgid "editorcp_menu_eventlog_link"
+msgstr "Event Log"
+
+#: views/elements/developers/editorsmenu.thtml:62
+msgid "editorcp_menu_mainpage_link"
+msgstr "Back to Main"
+
+#: views/elements/developers/editorsmenu.thtml:61
+msgid "editorcp_menu_reviewlog_link"
+msgstr "Review Log"
+
+#: views/elements/developers/editorsmenu.thtml:55
+msgid "editorcp_menu_summary_link"
+msgstr "Editor Summary"
+
+#: views/elements/developers/editorsmenu.thtml:52
+msgid "editorcp_menu_title"
+msgstr "Editor Tools"
+
+#: views/editors/reviewlog.thtml:49
+msgid "editorcp_reviewlog_button_filter"
+msgstr "Filter"
+
+#: views/editors/reviewlog.thtml:58
+msgid "editorcp_reviewlog_column_action"
+msgstr "Action"
+
+#: views/editors/reviewlog.thtml:56
+msgid "editorcp_reviewlog_column_addon"
+msgstr "Add-on"
+
+#: views/editors/reviewlog.thtml:55
+msgid "editorcp_reviewlog_column_date"
+msgstr "Date"
+
+#: views/editors/reviewlog.thtml:57
+msgid "editorcp_reviewlog_column_editor"
+msgstr "Editor"
+
+#: views/editors/reviewlog.thtml:94
+msgid "editorcp_reviewlog_comments_hide"
+msgstr "Hide Comments"
+
+#: views/editors/reviewlog.thtml:93
+msgid "editorcp_reviewlog_comments_show"
+msgstr "Show Comments"
+
+#. %1$s and %2$s are full <input> tags for dates
+#: views/editors/reviewlog.thtml:45
+#, php-format
+msgid "editorcp_reviewlog_entries_between"
+msgstr "View entries between %1$s and %2$s"
+
+#: views/editors/reviewlog.thtml:104
+msgid "editorcp_reviewlog_none_found"
+msgstr "No reviews found for this period."
+
+#: views/editors/reviewlog.thtml:42
+msgid "editorcp_reviewlog_page_heading"
+msgstr "Review Log"
+
+#: views/editors/summary.thtml:61
+msgid "editorcp_summary_monthreviews_heading"
+msgstr "Month Reviews"
+
+#: views/editors/summary.thtml:77
+msgid "editorcp_summary_neweditors_heading"
+msgstr "New Editors"
+
+#: views/editors/summary.thtml:42
+msgid "editorcp_summary_page_heading"
+msgstr "Editor Summary"
+
+#: views/editors/summary.thtml:94
+msgid "editorcp_summary_recentactivity_heading"
+msgstr "Recent Editor Activity"
+
+#: views/editors/summary.thtml:45
+msgid "editorcp_summary_totalreviews_heading"
+msgstr "Total Reviews"
+
+#: controllers/editors_controller.php:248
+#: controllers/editors_controller.php:249
+msgid "editors_addon_review_pagetitle"
+msgstr "Review Add-on"
+
+#: controllers/editors_controller.php:349
+msgid "editors_error_js-formerror"
+msgstr "Please complete the following fields:"
+
+#: controllers/editors_controller.php:350
+msgid "editors_error_review_one_file"
+msgstr "Please select at least one file to review."
+
+#: controllers/editors_controller.php:274
+msgid "editors_error_self_reviews_forbidden"
+msgstr "Self-reviews are not allowed."
+
+#: controllers/editors_controller.php:699
+msgid "editors_external_software"
+msgstr "External Software"
+
+#: views/editors/featured.thtml:120 views/editors/featured.thtml:121
+msgid "editors_featured_add_feature"
+msgstr "Add feature"
+
+#: views/editors/featured.thtml:126
+msgid "editors_featured_add_feature_submit"
+msgstr "Add"
+
+#: views/editors/featured.thtml:49 controllers/editors_controller.php:832
+#: controllers/editors_controller.php:848
+msgid "editors_featured_addon_add_failure"
+msgstr "Failed to add feature."
+
+#: controllers/editors_controller.php:851
+msgid "editors_featured_addon_add_success"
+msgstr "Successfully added feature."
+
+#: views/editors/featured.thtml:50 controllers/editors_controller.php:839
+#: controllers/editors_controller.php:868
+#: controllers/editors_controller.php:886
+msgid "editors_featured_addon_edit_failure"
+msgstr "Failed to edit feature."
+
+#: views/editors/featured.thtml:51 controllers/editors_controller.php:888
+msgid "editors_featured_addon_edit_success"
+msgstr "Successfully edited feature."
+
+#: views/editors/featured.thtml:53 controllers/editors_controller.php:861
+msgid "editors_featured_addon_invalid_locale"
+msgstr "One or more locales are invalid."
+
+#: views/editors/featured.thtml:52 controllers/editors_controller.php:906
+msgid "editors_featured_addon_remove_failure"
+msgstr "Failed to remove feature."
+
+#: controllers/editors_controller.php:901
+msgid "editors_featured_addon_remove_success"
+msgstr "Successfully removed feature."
+
+#: controllers/editors_controller.php:915
+#: controllers/editors_controller.php:917
+msgid "editors_featured_addons_pagetitle"
+msgstr "Featured Add-ons"
+
+#: views/editors/featured.thtml:54 views/editors/featured.thtml:107
+msgid "editors_featured_edit_feature_submit"
+msgstr "Go"
+
+#: views/editors/featured.thtml:90 views/editors/featured.thtml:91
+msgid "editors_featured_remove_feature"
+msgstr "Remove feature"
+
+#: views/editors/queue.thtml:46
+msgid "editors_filter_queue"
+msgstr "Filter Queue"
+
+#: views/editors/queue.thtml:182
+msgid "editors_helpful_links"
+msgstr "Helpful Links"
+
+#: views/editors/queue.thtml:182
+msgid "editors_link_guide"
+msgstr "Editors' Guide"
+
+#: views/editors/queue.thtml:182
+msgid "editors_link_policy"
+msgstr "Add-on Policy"
+
+#: views/editors/queue.thtml:47
+msgid "editors_notice_filter_session"
+msgstr "These filters will remain in place for this session or until cleared."
+
+#. %1 is the queue mode
+#: views/editors/queue.thtml:177 views/admin/flagged_queue.thtml:89
+msgid "editors_notice_none_found"
+msgstr "There are currently no add-ons of this type to review."
+
+#: controllers/editors_controller.php:1040
+msgid "editors_one_day"
+msgstr "1 day"
+
+#: controllers/editors_controller.php:1048
+msgid "editors_one_hour"
+msgstr "1 hour"
+
+#: controllers/editors_controller.php:1056
+msgid "editors_one_minute"
+msgstr "1 minute"
+
+#: controllers/editors_controller.php:64 controllers/editors_controller.php:73
+#: controllers/editors_controller.php:77
+msgid "editors_pagetitle"
+msgstr "Editor Tools"
+
+#. %s is a comma separated list of platforms. Example: Windows, OS X
+#: controllers/editors_controller.php:680
+#: controllers/editors_controller.php:683
+#, php-format
+msgid "editors_platform_x_only"
+msgstr "%s only"
+
+#: controllers/editors_controller.php:695
+msgid "editors_pre-release"
+msgstr "Pre-release"
+
+#. %1 is the app name
+#: views/editors/queue.thtml:131
+#, php-format
+msgid "editors_queue_app_compatibility"
+msgstr "%s Compatibility"
+
+#: views/editors/queue.thtml:51
+msgid "editors_queue_filter_label_addon"
+msgstr "Add-on or Author Email"
+
+#: views/editors/queue.thtml:72
+msgid "editors_queue_filter_label_addontypes"
+msgstr "Add-on Types"
+
+#: views/editors/queue.thtml:56
+msgid "editors_queue_filter_label_application"
+msgstr "Application"
+
+#: views/editors/queue.thtml:61
+msgid "editors_queue_filter_label_maxversion"
+msgstr "Max. Version"
+
+#: views/editors/queue.thtml:78
+msgid "editors_queue_filter_label_platforms"
+msgstr "Platforms"
+
+#: views/editors/queue.thtml:66
+msgid "editors_queue_filter_label_submissionage"
+msgstr "Age of Submission (days)"
+
+#. %1$s is a number
+#: views/editors/queue.thtml:90
+msgid "editors_queue_filter_result_count"
+msgid_plural "editors_queue_filter_result_count"
+msgstr[0] "Results of your filtered search: <strong>%1$s</strong> Add-on"
+msgstr[1] "Results of your filtered search: <strong>%1$s</strong> Add-ons"
+
+#: views/editors/queue.thtml:84
+msgid "editors_queue_submit_clean"
+msgstr "Clear"
+
+#: views/editors/queue.thtml:83
+msgid "editors_queue_submit_filter"
+msgstr "Filter"
+
+#: controllers/editors_controller.php:133
+msgid "editors_queues_disabled"
+msgstr ""
+"All review queues are currently disabled. Please check back at a later time."
+
+#: views/editors/review.thtml:149
+msgid "editors_review_a_edit_item"
+msgstr "Edit Item"
+
+#: views/editors/review.thtml:146
+msgid "editors_review_a_item_history"
+msgstr "Item History"
+
+#: views/editors/review.thtml:148
+msgid "editors_review_a_item_homepage"
+msgstr "Item Homepage"
+
+#: views/editors/review.thtml:145
+msgid "editors_review_a_item_overview"
+msgstr "Item Overview"
+
+#: views/editors/review.thtml:147
+msgid "editors_review_a_previews"
+msgstr "Previews"
+
+#: controllers/editors_controller.php:345
+msgid "editors_review_action"
+msgstr "Review Action"
+
+#: views/editors/review.thtml:159
+msgid "editors_review_action_info"
+msgstr "Request More Information"
+
+#: views/editors/review.thtml:157
+msgid "editors_review_action_public"
+msgstr "Push to Public"
+
+#: views/editors/review.thtml:160
+msgid "editors_review_action_request_superreview"
+msgstr "Request Super-Review"
+
+#: views/editors/review.thtml:158
+msgid "editors_review_action_sandbox"
+msgstr "Retain in Sandbox"
+
+#: controllers/editors_controller.php:346
+msgid "editors_review_comments"
+msgstr "Review Comments"
+
+#: views/editors/review.thtml:182
+msgid "editors_review_details_info_request"
+msgstr ""
+"Use this form to request more information from the author. They will receive "
+"an email and be able to answer here. You will be notified by email when they "
+"reply."
+
+#: views/editors/review.thtml:174
+msgid "editors_review_details_nominated_public"
+msgstr ""
+"This will mark the add-on and its most recent version and files as public. "
+"Future versions will go into the sandbox until they are reviewed by an "
+"editor."
+
+#: views/editors/review.thtml:177
+msgid "editors_review_details_nominated_sandbox"
+msgstr "This will retain the add-on in the sandbox."
+
+#: views/editors/review.thtml:166
+msgid "editors_review_details_pending_public"
+msgstr ""
+"This will approve a sandboxed version of a public add-on to appear on the "
+"public side."
+
+#: views/editors/review.thtml:169
+msgid "editors_review_details_pending_sandbox"
+msgstr ""
+"This will cause a sandboxed version of a public add-on to remain in the "
+"sandbox."
+
+#: views/editors/review.thtml:185
+msgid "editors_review_details_superreview"
+msgstr ""
+"If you have concerns about this add-on's security, copyright issues, or "
+"other concerns that an administrator should look into, enter your comments "
+"in the area below. They will be sent to administrators, not the author."
+
+#: views/editors/review.thtml:134
+msgid "editors_review_file_diff_link"
+msgstr "Compare with public version"
+
+#: views/editors/review.thtml:131
+msgid "editors_review_file_viewcontents_link"
+msgstr "View Contents"
+
+#: views/editors/review.thtml:65
+msgid "editors_review_header_authors"
+msgstr "Authors:"
+
+#: views/editors/review.thtml:79
+msgid "editors_review_header_categories"
+msgstr "Categories:"
+
+#: views/editors/review.thtml:92
+msgid "editors_review_header_compatibility"
+msgstr "Compatibility:"
+
+#: views/editors/review.thtml:251
+msgid "editors_review_header_description"
+msgstr "Description"
+
+#: views/editors/review.thtml:275
+msgid "editors_review_header_devcomments"
+msgstr "Developer Comments"
+
+#: views/editors/review.thtml:263
+msgid "editors_review_header_eula"
+msgstr "EULA"
+
+#: views/editors/review.thtml:115
+msgid "editors_review_header_files"
+msgstr "Files:"
+
+#: views/editors/review.thtml:284
+msgid "editors_review_header_itemhistory"
+msgstr "Item History"
+
+#: views/editors/review.thtml:232
+msgid "editors_review_header_nominationmessage"
+msgstr "Nomination Message"
+
+#: views/editors/review.thtml:311
+msgid "editors_review_header_previews"
+msgstr "Previews"
+
+#: views/editors/review.thtml:269
+msgid "editors_review_header_privacy"
+msgstr "Privacy Policy"
+
+#. %1 is the add-on name and version
+#: views/editors/review.thtml:56
+#, php-format
+msgid "editors_review_header_review"
+msgstr "Review %s"
+
+#: views/editors/review.thtml:239
+msgid "editors_review_header_reviewernotes"
+msgstr "Notes to Reviewer"
+
+#: views/editors/review.thtml:245
+msgid "editors_review_header_summary"
+msgstr "Summary"
+
+#: views/editors/review.thtml:257
+msgid "editors_review_header_versionnotes"
+msgstr "Version Notes"
+
+#. a noun: shown in an add-on's editor review history
+#: views/elements/developers/editors_review_history_item.thtml:80
+msgid "editors_review_history_info_reply"
+msgstr "Reply"
+
+#: views/elements/developers/editors_review_history_item.thtml:78
+msgid "editors_review_history_info_request"
+msgstr "Information Request"
+
+#: views/elements/developers/editors_review_history_item.thtml:62
+#: views/editors/reviewlog.thtml:77
+msgid "editors_review_history_nominated_adminreview"
+msgstr "Admin Review"
+
+#: views/elements/developers/editors_review_history_item.thtml:56
+#: views/editors/reviewlog.thtml:71
+msgid "editors_review_history_nominated_approved"
+msgstr "Nomination Approved/Public"
+
+#: views/elements/developers/editors_review_history_item.thtml:59
+#: views/editors/reviewlog.thtml:74
+msgid "editors_review_history_nominated_denied"
+msgstr "Nomination Denied/Sandbox"
+
+#: views/editors/review.thtml:303
+msgid "editors_review_history_nonefound"
+msgstr "No previous review entries could be found."
+
+#: views/elements/developers/editors_review_history_item.thtml:73
+#: views/editors/reviewlog.thtml:88
+msgid "editors_review_history_pending_adminreview"
+msgstr "Admin Review"
+
+#: views/elements/developers/editors_review_history_item.thtml:67
+#: views/editors/reviewlog.thtml:82
+msgid "editors_review_history_pending_approved"
+msgstr "Approved/Public"
+
+#: views/elements/developers/editors_review_history_item.thtml:70
+#: views/editors/reviewlog.thtml:85
+msgid "editors_review_history_pending_denied"
+msgstr "Denied/Sandbox"
+
+#. link text in an add-on's editor review history, allowing to hide and show an information request's replies
+#. %1 is the number of replies
+#: views/elements/developers/editors_review_history_item.thtml:90
+msgid "editors_review_history_show_hide_replies"
+msgid_plural "editors_review_history_show_hide_replies"
+msgstr[0] "Show/Hide Replies (%1$s)"
+msgstr[1] "Show/Hide Replies (%1$s)"
+
+#: views/editors/review.thtml:208
+msgid "editors_review_label_applications"
+msgstr "Applications:"
+
+#: views/editors/review.thtml:196
+msgid "editors_review_label_cannedresponse"
+msgstr "or select a canned response:"
+
+#: views/editors/review.thtml:190
+msgid "editors_review_label_comments"
+msgstr "Comments:"
+
+#: views/editors/review.thtml:204
+msgid "editors_review_label_operating_systems"
+msgstr "Operating Systems:"
+
+#: views/editors/review.thtml:285 views/editors/review.thtml:312
+msgid "editors_review_link_pagetop"
+msgstr "Top"
+
+#: views/editors/review.thtml:141
+msgid "editors_review_mulitple_notice"
+msgstr ""
+"Notice: Only review more than one file if you have tested EVERY file you "
+"select."
+
+#: views/editors/review.thtml:51
+msgid "editors_review_next_link"
+msgstr "next &raquo;"
+
+#: views/editors/review.thtml:322
+msgid "editors_review_previews_notfound"
+msgstr "No previews found."
+
+#: views/editors/review.thtml:50
+msgid "editors_review_previous_link"
+msgstr "&laquo; prev"
+
+#: controllers/editors_controller.php:144
+#: controllers/editors_controller.php:146
+msgid "editors_review_queue_pagetitle"
+msgstr "Review Queue"
+
+#. %1 is the add-ons rank in the queue, %2 is the total queue length
+#: views/editors/review.thtml:47
+msgid "editors_review_rank_in_queue"
+msgstr "<strong># %1$s</strong> of %2$s in queue"
+
+#. %1 is the add-ons rank in the queue, %2 is the total queue length. Both numbers
+#: views/editors/review.thtml:45
+msgid "editors_review_rank_in_queue_filtered"
+msgstr "<strong># %1$s</strong> of %2$s in queue (filtered)"
+
+#: views/editors/review.thtml:223
+msgid "editors_review_submit_process_action"
+msgstr "Process Action"
+
+#: views/editors/review.thtml:293
+msgid "editors_review_th_action"
+msgstr "Action"
+
+#: views/editors/review.thtml:294
+msgid "editors_review_th_comments"
+msgstr "Comments"
+
+#: views/editors/review.thtml:291
+msgid "editors_review_th_date"
+msgstr "Date"
+
+#: views/editors/review.thtml:292
+msgid "editors_review_th_reviewer"
+msgstr "Reviewer"
+
+#: views/editors/review.thtml:290
+msgid "editors_review_th_version_file"
+msgstr "Version/File"
+
+#: views/editors/review.thtml:217
+msgid "editors_review_update_notify_once"
+msgstr ""
+"Notify me the next time this add-on is updated. (Subsequent updates will not "
+"generate an email)"
+
+#: controllers/editors_controller.php:298
+msgid "editors_reviewed_successfully"
+msgstr "Review successfully processed."
+
+#: views/editors/reviews_queue.thtml:106
+msgid "editors_reviews_action_delete_review"
+msgstr "Delete review"
+
+#: views/editors/reviews_queue.thtml:104
+msgid "editors_reviews_action_keep"
+msgstr "Remove flags; keep review"
+
+#: views/editors/reviews_queue.thtml:102
+msgid "editors_reviews_action_skip"
+msgstr "Skip"
+
+#: views/editors/reviews_queue.thtml:100
+msgid "editors_reviews_header_action"
+msgstr "Action"
+
+#: views/editors/reviews_queue.thtml:67
+msgid "editors_reviews_in_reply_to"
+msgstr "In reply to:"
+
+#: controllers/editors_controller.php:748
+msgid "editors_reviews_processed"
+msgstr "Reviews processed successfully!"
+
+#: views/editors/reviews_queue.thtml:117
+msgid "editors_reviews_queue_empty"
+msgstr "There are currently no reviews in moderation."
+
+#: views/editors/reviews_queue.thtml:111
+msgid "editors_reviews_submit_process_reviews"
+msgstr "Process Reviews"
+
+#: controllers/editors_controller.php:691
+msgid "editors_site_specific"
+msgstr "Site Specific"
+
+#: controllers/editors_controller.php:348
+msgid "editors_tested_app"
+msgstr "Tested Application"
+
+#: controllers/editors_controller.php:347
+msgid "editors_tested_os"
+msgstr "Tested Operating Systems"
+
+#: views/editors/queue.thtml:151
+msgid "editors_th_additional_info"
+msgstr "Additional Information"
+
+#: views/editors/featured.thtml:63 views/editors/queue.thtml:109
+#: views/admin/flagged_queue.thtml:53
+msgid "editors_th_addon"
+msgstr "Add-on"
+
+#: views/editors/queue.thtml:125
+msgid "editors_th_addontype"
+msgstr "Type"
+
+#: views/editors/featured.thtml:64
+msgid "editors_th_locales"
+msgstr "Restrict to locales?"
+
+#: views/editors/queue.thtml:148
+msgid "editors_th_nomination_age"
+msgstr "Time in Queue"
+
+#: views/editors/queue.thtml:101 views/editors/queue.thtml:117
+#: views/editors/queue.thtml:144
+msgid "editors_th_sort_ascending"
+msgstr "Ascending sort"
+
+#: views/editors/queue.thtml:105 views/editors/queue.thtml:121
+#: views/editors/queue.thtml:140
+msgid "editors_th_sort_descending"
+msgstr "Descending sort"
+
+#. %s is a number
+#: controllers/editors_controller.php:1036
+#, php-format
+msgid "editors_x_days"
+msgstr "%s days"
+
+#. %s is a number
+#: controllers/editors_controller.php:1044
+#, php-format
+msgid "editors_x_hours"
+msgstr "%s hours"
+
+#. %s is a number
+#: controllers/editors_controller.php:1052
+#, php-format
+msgid "editors_x_minutes"
+msgstr "%s minutes"
+
+#: views/errors/error401.thtml:50 controllers/components/simple_acl.php:81
+#: controllers/components/simple_acl.php:82
+#: controllers/components/simple_acl.php:83 controllers/components/amo.php:607
+#: controllers/components/amo.php:608 controllers/components/amo.php:609
+#: controllers/reviews_controller.php:353
+#: controllers/reviews_controller.php:485
+#: controllers/collections_controller.php:438
+#: controllers/collections_controller.php:496
+#: controllers/collections_controller.php:504
+#: controllers/collections_controller.php:971
+#: controllers/collections_controller.php:1034
+#: controllers/collections_controller.php:1077
+msgid "error_access_denied"
+msgstr "Access Denied"
+
+#: views/errors/error401.thtml:52
+msgid "error_access_denied_message"
+msgstr "You are not authorized to view this page."
+
+#: controllers/collections_controller.php:1039
+msgid "error_addon_exists"
+msgstr "Add-on already exists!"
+
+#: controllers/developers_controller.php:200
+#: controllers/developers_controller.php:593
+#: controllers/developers_controller.php:1016
+#: controllers/developers_controller.php:1429
+#: controllers/downloads_controller.php:95
+#: controllers/downloads_controller.php:102
+#: controllers/downloads_controller.php:164
+#: controllers/statistics_controller.php:135
+#: controllers/previews_controller.php:115
+#: controllers/previews_controller.php:206
+#: controllers/previews_controller.php:307
+#: controllers/reviews_controller.php:77
+#: controllers/reviews_controller.php:240
+#: controllers/reviews_controller.php:332
+#: controllers/reviews_controller.php:340 controllers/api_controller.php:123
+#: controllers/api_controller.php:759 controllers/addons_controller.php:131
+#: controllers/addons_controller.php:197
+#: controllers/addons_controller.php:1407
+#: controllers/addons_controller.php:1465
+#: controllers/addons_controller.php:1469
+#: controllers/addons_controller.php:1503
+#: controllers/editors_controller.php:265
+#: controllers/collections_controller.php:1041
+#: controllers/collections_controller.php:1074
+msgid "error_addon_notfound"
+msgstr "Add-on not found!"
+
+#: controllers/files_controller.php:83 controllers/files_controller.php:196
+msgid "error_addon_notviewable"
+msgstr "This add-on is not viewable here."
+
+#: controllers/reviews_controller.php:246
+msgid "error_addon_selfreview"
+msgstr "You cannot review your own add-on."
+
+#: controllers/addons_controller.php:970
+msgid "error_browse_no_addons"
+msgstr "No add-ons in this category!"
+
+#: controllers/api_controller.php:424
+msgid "error_collection_feed_notfound"
+msgstr "Add-on feed not found."
+
+#: views/users/register.thtml:65 views/users/edit.thtml:194
+msgid "error_email_invalid"
+msgstr "This is not a valid email address."
+
+#: views/users/pwreset.thtml:74 views/users/register.thtml:70
+#: views/users/register.thtml:80 views/users/register.thtml:86
+#: views/users/edit.thtml:105 views/users/edit.thtml:111
+#: views/users/edit.thtml:192 views/admin/users_edit.thtml:78
+#: views/admin/users_edit.thtml:83 views/reviews/add.thtml:80
+#: views/reviews/add.thtml:104
+msgid "error_field_required"
+msgstr "This field must not be empty."
+
+#: controllers/files_controller.php:75 controllers/files_controller.php:93
+#: controllers/files_controller.php:96 controllers/files_controller.php:163
+#: controllers/files_controller.php:176 controllers/files_controller.php:185
+#: controllers/files_controller.php:204 controllers/editors_controller.php:412
+msgid "error_file_notfound"
+msgstr "File not found!"
+
+#. %s is a filename
+#: controllers/editors_controller.php:430
+#, php-format
+msgid "error_file_x_notfound"
+msgstr "File error: %s does not exist."
+
+#: views/collections/add.thtml:55 views/collections/edit.thtml:89
+#: views/users/register.thtml:54 views/users/edit.thtml:81
+#: views/reviews/add.thtml:70 controllers/groups_controller.php:80
+#: controllers/groups_controller.php:102
+msgid "error_formerrors"
+msgstr "There are errors in this form. Please correct them and resubmit."
+
+#: views/users/register.thtml:109
+msgid "error_invalid_captcha"
+msgstr "Invalid captcha, please try again!"
+
+#: views/users/register.thtml:100 views/users/edit.thtml:125
+#: views/admin/users_edit.thtml:101
+msgid "error_invalid_url"
+msgstr ""
+"This URL has an invalid format. Valid URLs look like http://example.com/"
+"my_page."
+
+#. %s is a string representing what's missing. Example: file_id
+#: controllers/downloads_controller.php:65
+#: controllers/users_controller.php:185 controllers/users_controller.php:264
+#: controllers/users_controller.php:559 controllers/users_controller.php:653
+#: controllers/reviews_controller.php:71
+#: controllers/reviews_controller.php:234
+#: controllers/reviews_controller.php:325
+#: controllers/reviews_controller.php:473
+#: controllers/reviews_controller.php:475
+#: controllers/addons_controller.php:182
+#: controllers/addons_controller.php:1381
+#: controllers/addons_controller.php:1455
+#: controllers/collections_controller.php:266
+#: controllers/collections_controller.php:285
+#: controllers/collections_controller.php:346
+#: controllers/collections_controller.php:443
+#: controllers/collections_controller.php:482
+#: controllers/collections_controller.php:936
+#: controllers/collections_controller.php:959
+#: controllers/collections_controller.php:960
+#: controllers/collections_controller.php:975
+#: controllers/collections_controller.php:977
+#: controllers/collections_controller.php:994
+#: controllers/collections_controller.php:1003
+#: controllers/collections_controller.php:1016
+#: controllers/collections_controller.php:1017
+#: controllers/collections_controller.php:1024
+#: controllers/collections_controller.php:1070
+#: controllers/collections_controller.php:1090
+#, php-format
+msgid "error_missing_argument"
+msgstr "Missing argument: %s"
+
+#: controllers/components/amo.php:507 controllers/components/amo.php:532
+msgid "error_no_files_in_addon"
+msgstr "No Files"
+
+#: controllers/previews_controller.php:200
+msgid "error_preview_notfound"
+msgstr "Preview not found!"
+
+#: views/addons/display.thtml:400 views/reviews/add.thtml:98
+msgid "error_review_rating_required"
+msgstr "You must select a rating."
+
+#: controllers/users_controller.php:160
+msgid "error_user_already_confirmed"
+msgstr "This user account is already confirmed."
+
+#: controllers/users_controller.php:202 controllers/users_controller.php:276
+#: controllers/users_controller.php:569 controllers/users_controller.php:581
+#: controllers/users_controller.php:587 controllers/users_controller.php:610
+#: controllers/users_controller.php:627
+msgid "error_user_badconfirmationcode"
+msgstr "Invalid confirmation code!"
+
+#: views/users/pwreset.thtml:79 views/users/register.thtml:75
+#: views/users/edit.thtml:183
+msgid "error_user_confirmpw_nomatch"
+msgstr "The passwords did not match."
+
+#: views/users/register.thtml:65 views/users/edit.thtml:190
+#: controllers/users_controller.php:617
+msgid "error_user_email_notunique"
+msgstr "This email address is already taken by another user."
+
+#: controllers/users_controller.php:596
+msgid "error_user_emailchange_expired"
+msgstr ""
+"The email change has expired. Please change your email address again in your "
+"user profile and click the link in the confirmation email as soon as you "
+"receive it."
+
+#: controllers/collections_controller.php:985
+msgid "error_user_exists"
+msgstr ""
+"Users can only have one role at a time. Please remove the user from any "
+"existing roles before continuing."
+
+#: views/users/register.thtml:91 views/users/edit.thtml:116
+#: views/admin/users_edit.thtml:88
+msgid "error_user_nickname_notunique"
+msgstr "This nickname is already taken."
+
+#: views/users/pwreset.thtml:54 controllers/users_controller.php:191
+#: controllers/users_controller.php:270 controllers/users_controller.php:603
+#: controllers/users_controller.php:659
+#: controllers/collections_controller.php:988
+#: controllers/collections_controller.php:998
+msgid "error_user_notfound"
+msgstr "User not found!"
+
+#: views/users/activatefirst.thtml:47
+msgid "error_user_unconfirmed"
+msgstr ""
+"Please confirm your user account first with the code you received by email."
+
+#: views/users/login.thtml:67
+msgid "error_username_or_pw_wrong"
+msgstr "Wrong username or password!"
+
+#: controllers/editors_controller.php:260
+msgid "error_version_notfound"
+msgstr "Version not found!"
+
+#: views/users/delete.thtml:125 views/users/edit.thtml:173
+msgid "error_wrong_password"
+msgstr "Wrong password entered!"
+
+#: views/elements/amo2009/homepage_addon.thtml:122
+#: views/elements/feature.thtml:122
+msgid "feature_learnmore"
+msgstr "Learn more"
+
+#. %1 is the add-on name
+#: views/elements/amo2009/homepage_addon.thtml:123
+#: views/elements/feature.thtml:123
+#, php-format
+msgid "feature_learnmore_about_addon"
+msgstr "Learn more about %1$s"
+
+#. %1$s is a number
+#: views/elements/amo2009/reviews.thtml:52
+#: views/elements/addon_listitem.thtml:112 views/elements/feature.thtml:99
+#: views/addons/browse_thumbs.thtml:86
+#, php-format
+msgid "feature_reviews"
+msgid_plural "feature_reviews"
+msgstr[0] "%1$s review"
+msgstr[1] "%1$s reviews"
+
+#: views/elements/amo2009/homepage_addon.thtml:127
+#: views/elements/feature.thtml:127
+msgid "feature_view_more_from_category"
+msgstr "View more from"
+
+#. This appears on a page that views the source of an add-on. This link will return
+#. the user to the add-on's main page
+#: views/files/browse.thtml:65
+msgid "file_browser_link_addon"
+msgstr "Back to add-on"
+
+#. There is a list of directories and files on the page. Clicking this will show the
+#. contents of all the directories (normally you would click on each one to see the
+#. contents)
+#: views/files/browse.thtml:67
+msgid "file_browser_link_expand_all"
+msgstr "Expand all"
+
+#. This appears on a page that views the source of an add-on. This link will return
+#. the user to the add-on's review page (it only appears if the add-on is being
+#. reviewed)
+#: views/files/browse.thtml:64
+msgid "file_browser_link_review"
+msgstr "Back to review"
+
+#. The title of the page for viewing an add-on's source.
+#. %1$s is the name of the add-on
+#. %2$s is the name of the current application (e.g. Firefox or Thunderbird)
+#: views/files/browse.thtml:46
+msgid "file_browser_title"
+msgstr "%1$s :: File Browser :: %2$s Add-ons"
+
+#. This appears on a page that views the source of an add-on. There is a list of
+#. directories and files on the page. Clicking this link will toggle between an
+#. expanded or a collapsed list. This string should be kept short.
+#: views/files/browse.thtml:68
+msgid "file_browser_toggle_expand_collapse"
+msgstr "+/-"
+
+#. Link text for the AMO About page.
+#: views/elements/footer.thtml:72 views/layouts/amo2009.thtml:341
+msgid "footer_a_about"
+msgstr "About"
+
+#. Link text to the AMO blog.
+#: views/elements/footer.thtml:74 views/layouts/amo2009.thtml:343
+msgid "footer_a_blog"
+msgstr "Blog"
+
+#. Link text to the Frequently Asked Questions page.
+#: views/elements/footer.thtml:73 views/layouts/amo2009.thtml:342
+msgid "footer_a_faq"
+msgstr "FAQ"
+
+#. Full text for the FAQ abbreviation.
+#: views/elements/footer.thtml:73 views/pages/collector_features.thtml:72
+#: views/layouts/amo2009.thtml:342
+msgid "footer_abbr_faq"
+msgstr "Frequently Asked Questions"
+
+#: views/elements/footer.thtml:67 views/layouts/amo2009.thtml:336
+msgid "footer_all_rights_reserved"
+msgstr "All rights reserved."
+
+#: views/elements/footer.thtml:67 views/layouts/amo2009.thtml:336
+msgid "footer_copyright"
+msgstr "Copyright"
+
+#: views/elements/footer.thtml:71 views/layouts/amo2009.thtml:340
+msgid "footer_credits"
+msgstr "Credits"
+
+#: views/elements/footer.thtml:76 views/layouts/amo2009.thtml:346
+msgid "footer_disclaimer"
+msgstr ""
+"Mozilla is providing links to these applications as a courtesy, and makes no "
+"representations regarding the applications or any information related there "
+"to. Any questions, complaints or claims regarding the applications must be "
+"directed to the appropriate software vendor."
+
+#: views/elements/footer.thtml:61 views/layouts/amo2009.thtml:332
+msgid "footer_lang_form_lang_submit_go"
+msgstr "Go"
+
+#: views/elements/footer.thtml:70 views/layouts/amo2009.thtml:339
+msgid "footer_legal_notices"
+msgstr "Legal Notices"
+
+#: views/elements/footer.thtml:50 views/layouts/amo2009.thtml:321
+msgid "footer_other_languages"
+msgstr "Other languages:"
+
+#: views/elements/footer.thtml:69 views/layouts/amo2009.thtml:338
+msgid "footer_privacy_policy"
+msgstr "Privacy Policy"
+
+#: models/addontype.php:79
+msgid "general_addontype_dict"
+msgstr "Dictionary"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:100
+msgid "general_addontype_dict_plural"
+msgstr "Dictionaries"
+
+#: models/addontype.php:75
+msgid "general_addontype_extension"
+msgstr "Extension"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:98
+msgid "general_addontype_extension_plural"
+msgstr "Extensions"
+
+#: models/addontype.php:85
+msgid "general_addontype_lpaddon"
+msgstr "Language Pack (Add-on)"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:103
+msgid "general_addontype_lpaddon_plural"
+msgstr "Language Packs (Add-on)"
+
+#: models/addontype.php:83
+msgid "general_addontype_lpapp"
+msgstr "Language Pack (Application)"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:102
+msgid "general_addontype_lpapp_plural"
+msgstr "Language Packs (Application)"
+
+#: models/addontype.php:87
+msgid "general_addontype_plugin"
+msgstr "Plugin"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:104
+msgid "general_addontype_plugin_plural"
+msgstr "Plugins"
+
+#: models/addontype.php:81
+msgid "general_addontype_search"
+msgstr "Search Engine"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:101
+msgid "general_addontype_search_plural"
+msgstr "Search Engines"
+
+#: models/addontype.php:77
+msgid "general_addontype_theme"
+msgstr "Theme"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:99
+msgid "general_addontype_theme_plural"
+msgstr "Themes"
+
+#: config/language.php:367
+msgid "general_languages_all_locales"
+msgstr "All Locales"
+
+#: views/layouts/amo2009.thtml:249
+msgid "header_brand_name"
+msgstr "Mozilla"
+
+#. %1$s is the application name. Example: Firefox
+#: views/elements/header.thtml:111 views/elements/header.thtml:122
+#: views/layouts/amo2009.thtml:248
+#, php-format
+msgid "header_home_tooltip"
+msgstr "Return to the %1$s Add-ons homepage"
+
+#: views/elements/header.thtml:87
+msgid "header_main_firefox_header"
+msgstr "Add-ons for Firefox"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:218
+msgid "header_main_firefox_header_with_logo"
+msgstr ""
+"Add-ons <em>for</em> <img alt=\"Firefox\" src=\"%1$s\" /> <strong>Firefox</"
+"strong>"
+
+#: views/elements/header.thtml:99
+msgid "header_main_header"
+msgstr "Add-ons"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:242
+msgid "header_main_header_with_logo"
+msgstr "Add-ons <img alt=\"Add-ons\" src=\"%1$s\" />"
+
+#: views/elements/header.thtml:90
+msgid "header_main_seamonkey_header"
+msgstr "SeaMonkey Add-ons"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:224
+msgid "header_main_seamonkey_header_with_logo"
+msgstr ""
+"Add-ons <em>for</em> <img alt=\"seamonkey\" src=\"%1$s\" /> "
+"<strong>SeaMonkey</strong>"
+
+#: views/elements/header.thtml:93
+msgid "header_main_sunbird_header"
+msgstr "Sunbird Add-ons"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:230
+msgid "header_main_sunbird_header_with_logo"
+msgstr ""
+"Add-ons <em>for</em> <img alt=\"sunbird\" src=\"%1$s\" /> <strong>Sunbird</"
+"strong>"
+
+#: views/elements/header.thtml:96
+msgid "header_main_thunderbird_header"
+msgstr "Thunderbird Add-ons"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:236
+msgid "header_main_thunderbird_header_with_logo"
+msgstr ""
+"Add-ons <em>for</em> <img alt=\"thunderbird\" src=\"%1$s\" /> "
+"<strong>Thunderbird</strong>"
+
+#: views/layouts/amo2009.thtml:205
+msgid "header_navaccess_applications_menu"
+msgstr "Skip to other applications menu"
+
+#: views/layouts/amo2009.thtml:204
+msgid "header_navaccess_categories_menu"
+msgstr "Skip to categories menu"
+
+#: views/layouts/amo2009.thtml:202
+msgid "header_navaccess_main_content"
+msgstr "Skip to main content"
+
+#: views/layouts/amo2009.thtml:203
+msgid "header_navaccess_search_form"
+msgstr "Skip to search form"
+
+#: views/elements/header.thtml:62
+msgid "header_navlink_addons"
+msgstr "Add-ons"
+
+#: views/elements/developers/sidebar.thtml:72
+#: views/elements/developers/myaddons.thtml:50 views/elements/header.thtml:159
+#: views/addons/display.thtml:378
+msgid "header_navlink_login"
+msgstr "Log in"
+
+#: views/elements/header.thtml:156 views/layouts/amo2009.thtml:304
+msgid "header_navlink_logout"
+msgstr "Log out"
+
+#: views/elements/header.thtml:145 views/layouts/amo2009.thtml:303
+msgid "header_navlink_myaccount"
+msgstr "My Account"
+
+#: views/elements/header.thtml:158
+msgid "header_navlink_register"
+msgstr "Register"
+
+#. %1 is the URL to the registration page
+#. %2 is the URL to the login page
+#: views/layouts/amo2009.thtml:278
+msgid "header_navlink_register_or_login"
+msgstr "<a href=\"%1$s\">Register</a> or <a href=\"%2$s\">Log in</a>"
+
+#: views/layouts/amo2009.thtml:285
+msgid "header_navlink_tools"
+msgstr "Tools"
+
+#. %s is the add-on name
+#: views/elements/collections_interactive_addon.thtml:62
+#: views/elements/amo2009/homepage_addon.thtml:77
+#: views/elements/addon_discussionheader.thtml:62
+#: views/elements/addon_listitem.thtml:67 views/elements/feature.thtml:84
+#: views/addons/category_landing.thtml:87 views/addons/browse_thumbs.thtml:60
+#, php-format
+msgid "img_preview_of"
+msgstr "Preview Image of %s"
+
+#. %1 is the login URL for the link tag
+#. %2 is the link to an explanatory page.
+#: views/elements/amo2009/install.thtml:307 views/elements/install.thtml:255
+msgid "install_a_login_to_install"
+msgstr ""
+"<a href=\"%1$s\">Log in</a> to install this experimental add-on. <a href=\"%2"
+"$s\">Why</a>?"
+
+#. %1 is the URL for the Experimental Add-ons section of the FAQ page
+#: views/elements/amo2009/install.thtml:283 views/elements/install.thtml:232
+msgid "install_button_confirm_exp_install"
+msgstr ""
+"Let me install this experimental add-on. <a href=\"%1$s\">What's this?</a>"
+
+#. %1$s is the application name. Example: Firefox
+#. %2$s is an optional string used to specify a platform. Example: (Windows)
+#: views/elements/amo2009/install.thtml:128 views/elements/install.thtml:75
+#, php-format
+msgid "install_button_text"
+msgstr "Add to %1$s %2$s"
+
+#. %1 is the add-on name, %2 is the app name
+#: views/elements/amo2009/install.thtml:191
+#: views/elements/amo2009/install.thtml:206
+#: views/elements/amo2009/install.thtml:249
+#: views/elements/amo2009/install.thtml:298 views/elements/install.thtml:150
+#: views/elements/install.thtml:165 views/elements/install.thtml:202
+#: views/elements/install.thtml:246
+#, php-format
+msgid "install_button_title"
+msgstr "Add %1$s to %2$s"
+
+#. %1$s is the add-on name
+#: views/elements/amo2009/install.thtml:200 views/elements/install.thtml:159
+#, php-format
+msgid "install_download"
+msgstr "Download %1$s"
+
+#: views/elements/amo2009/install.thtml:147 views/elements/install.thtml:94
+msgid "install_error_addon_not_found"
+msgstr "This add-on is not available."
+
+#: views/addons/dictionaries.thtml:65
+msgid "langtools_a11y_tablesummary"
+msgstr "List of language packs and dictionaries."
+
+#: views/addons/dictionaries.thtml:47
+msgid "langtools_download_dictionary"
+msgstr "Download Dictionary"
+
+#: views/addons/dictionaries.thtml:48
+msgid "langtools_download_langpack"
+msgstr "Download Language Pack"
+
+#: views/addons/dictionaries.thtml:63 controllers/components/amo.php:685
+#: controllers/addons_controller.php:1239
+msgid "langtools_header_dicts_and_langpacks"
+msgstr "Dictionaries & Language Packs"
+
+#: views/addons/dictionaries.thtml:44
+msgid "langtools_install_dictionary"
+msgstr "Install Dictionary"
+
+#: views/addons/dictionaries.thtml:45
+msgid "langtools_install_langpack"
+msgstr "Install Language Pack"
+
+#: views/addons/dictionaries.thtml:69
+msgid "langtools_tableheader_dictionary"
+msgstr "Dictionary"
+
+#: views/addons/dictionaries.thtml:70
+msgid "langtools_tableheader_langpack"
+msgstr "Language Pack"
+
+#: views/addons/dictionaries.thtml:68
+msgid "langtools_tableheader_language"
+msgstr "Language"
+
+#: models/license.php:65
+msgid "license_custom"
+msgstr "Custom License"
+
+#: config/bootstrap.php:303
+msgid "licenses_bsd"
+msgstr "BSD License"
+
+#: config/bootstrap.php:298
+msgid "licenses_gpl_2.0"
+msgstr "GNU General Public License, version 2.0"
+
+#: config/bootstrap.php:299
+msgid "licenses_gpl_3.0"
+msgstr "GNU General Public License, version 3.0"
+
+#: config/bootstrap.php:300
+msgid "licenses_lgpl_2.1"
+msgstr "GNU Lesser General Public License, version 2.1"
+
+#: config/bootstrap.php:301
+msgid "licenses_lgpl_3.0"
+msgstr "GNU Lesser General Public License, version 3.0"
+
+#: config/bootstrap.php:302
+msgid "licenses_mit"
+msgstr "MIT/X11 License"
+
+#: config/bootstrap.php:297
+msgid "licenses_mpl_1.1"
+msgstr "Mozilla Public License, version 1.1"
+
+#: views/users/emailchange.thtml:51 views/users/delete.thtml:55
+#: views/users/delete.thtml:137 views/users/edit.thtml:74
+#: views/reviews/flag.thtml:54
+msgid "link_return_to_front_page"
+msgstr "Click here to return to the front page."
+
+#: views/elements/amo2009/addon_list_options.thtml:46
+#: views/elements/addon_list_options.thtml:46
+msgid "list_sortby_date"
+msgstr "Date"
+
+#: views/elements/amo2009/addon_list_options.thtml:47
+#: views/elements/addon_list_options.thtml:47
+msgid "list_sortby_downloads"
+msgstr "Downloads"
+
+#: views/elements/amo2009/addon_list_options.thtml:45
+#: views/elements/addon_list_options.thtml:45
+msgid "list_sortby_name"
+msgstr "Add-on Name"
+
+#: views/elements/amo2009/addon_list_options.thtml:48
+#: views/elements/addon_list_options.thtml:48
+msgid "list_sortby_rating"
+msgstr "Rating"
+
+#: config/bootstrap.php:278
+msgid "main_prettyname_fennec"
+msgstr "Fennec"
+
+#: config/bootstrap.php:274
+msgid "main_prettyname_firefox"
+msgstr "Firefox"
+
+#: config/bootstrap.php:277
+msgid "main_prettyname_seamonkey"
+msgstr "SeaMonkey"
+
+#: config/bootstrap.php:276
+msgid "main_prettyname_sunbird"
+msgstr "Sunbird"
+
+#: config/bootstrap.php:275
+msgid "main_prettyname_thunderbird"
+msgstr "Thunderbird"
+
+#: views/elements/addon_categories.thtml:52
+msgid "nav_category_dicts_langpacks"
+msgstr "Dictionaries & Language Packs"
+
+#: views/elements/addon_categories.thtml:55
+msgid "nav_category_themes"
+msgstr "Themes"
+
+#: views/elements/app_chooser.thtml:47 views/layouts/amo2009.thtml:255
+msgid "other_apps_tooltip"
+msgstr "Find add-ons for other applications"
+
+#. In a user list: user 1, user 2, "others"
+#: views/helpers/addons_html.php:222
+msgid "other_users"
+msgstr "others"
+
+#: controllers/pages_controller.php:90
+msgid "page_title_appversions"
+msgstr "Application Versions"
+
+#: controllers/pages_controller.php:115
+msgid "page_title_collector"
+msgstr "Add-on Collector"
+
+#: controllers/pages_controller.php:117
+msgid "page_title_collector_faq"
+msgstr "Add-on Collector FAQ"
+
+#: controllers/pages_controller.php:119
+msgid "page_title_collector_features"
+msgstr "Add-on Collector Features"
+
+#: controllers/pages_controller.php:122
+msgid "page_title_collector_firstrun"
+msgstr "Welcome to the Add-on Collector"
+
+#: controllers/pages_controller.php:92
+msgid "page_title_credits"
+msgstr "Credits"
+
+#: controllers/pages_controller.php:113
+msgid "page_title_developer_faq"
+msgstr "Developer FAQ"
+
+#: controllers/pages_controller.php:111
+msgid "page_title_faq"
+msgstr "Frequently Asked Questions"
+
+#: controllers/pages_controller.php:94
+msgid "page_title_fashionyourfirefox_faq"
+msgstr "Fashion your Firefox FAQ"
+
+#: controllers/pages_controller.php:101
+msgid "page_title_policy"
+msgstr "Add-ons Policy"
+
+#: controllers/pages_controller.php:103
+msgid "page_title_privacy"
+msgstr "Mozilla Privacy Policy"
+
+#: controllers/pages_controller.php:105
+msgid "page_title_review_guide"
+msgstr "Review Guidelines"
+
+#: controllers/pages_controller.php:107
+msgid "page_title_sandbox"
+msgstr "Sandbox Review System"
+
+#: controllers/pages_controller.php:109
+msgid "page_title_submissionhelp"
+msgstr "Submission Help"
+
+#: views/pages/appversions.thtml:87
+msgid "pages_appversions_guid"
+msgstr "GUID"
+
+#: views/pages/appversions.thtml:79 controllers/pages_controller.php:90
+msgid "pages_appversions_header"
+msgstr "Valid Application Versions"
+
+#: views/pages/appversions.thtml:80
+msgid "pages_appversions_intro"
+msgstr ""
+"Add-ons submitted to Mozilla Add-ons must have an install.rdf file with at "
+"least one of the below applications supported. Only the versions listed "
+"below are allowed for these applications."
+
+#. %s is a full <a> tag
+#: views/pages/appversions.thtml:93
+#, php-format
+msgid "pages_appversions_required_files"
+msgstr ""
+"If your supported application does not require an install.rdf file, you "
+"still must include one with the required properties as specified %s."
+
+#. this is the text inside of an <a> tag for pages_appversions_required_files. This
+#. should be fixed.
+#: views/pages/appversions.thtml:93
+msgid "pages_appversions_required_files_link"
+msgstr "here"
+
+#: views/pages/appversions.thtml:88
+msgid "pages_appversions_versions"
+msgstr "Versions"
+
+#: views/pages/policy.thtml:51
+msgid "pages_policy_sandbox_link"
+msgstr "Sandbox Information Page"
+
+#: views/elements/pagination.thtml:53
+msgid "pagination_next_page"
+msgstr "next"
+
+#: views/elements/pagination.thtml:52
+msgid "pagination_previous_page"
+msgstr "previous"
+
+#: views/elements/recaptcha.thtml:65
+msgid "recaptcha_enter_both_words"
+msgstr ""
+"Please enter <strong>both words</strong> below, <strong>separated by a "
+"space</strong>."
+
+#: views/elements/recaptcha.thtml:83
+msgid "recaptcha_enter_here"
+msgstr "Enter your answer here:"
+
+#: views/elements/recaptcha.thtml:74
+msgid "recaptcha_enter_whatyouhear"
+msgstr "Please type what you hear."
+
+#. %1 is the link switching refreshing the captcha
+#. %2 is the link switching to a text captcha
+#: views/elements/recaptcha.thtml:77
+msgid "recaptcha_hardtohear_text"
+msgstr ""
+"If this is hard to understand, you can <a href=\"%1$s\">listen to something "
+"else</a> or <a href=\"%2$s\">switch back to text</a>."
+
+#. %1 is the link switching refreshing the captcha
+#. %2 is the link switching to an audio captcha
+#: views/elements/recaptcha.thtml:68
+msgid "recaptcha_hardtoread_text"
+msgstr ""
+"If this is hard to read, you can <a href=\"%1$s\">try different words</a> or "
+"<a href=\"%2$s\">listen to something</a> instead."
+
+#: views/users/register.thtml:105
+msgid "recaptcha_label"
+msgstr "Are you human?"
+
+#: views/users/register.thtml:106
+msgid "recaptcha_whatsthis"
+msgstr "What's this?"
+
+#: controllers/reviews_controller.php:559
+msgid "review_flag_error"
+msgstr "Error flagging this review!"
+
+#: models/reviews_moderation_flag.php:69
+msgid "review_flag_reason_bug_support"
+msgstr "Misplaced bug report or support request"
+
+#: views/reviews/display.thtml:103 views/reviews/display.thtml:186
+msgid "review_flag_reason_instructions"
+msgstr "Report this review (select a reason)"
+
+#: models/reviews_moderation_flag.php:67
+msgid "review_flag_reason_language"
+msgstr "Inappropriate language/dialog"
+
+#: models/reviews_moderation_flag.php:71
+msgid "review_flag_reason_other"
+msgstr "Other (please specify)"
+
+#: models/reviews_moderation_flag.php:65
+msgid "review_flag_reason_spam"
+msgstr "Spam or otherwise non-review content"
+
+#: views/reviews/display.thtml:91 views/reviews/display.thtml:175
+#: controllers/reviews_controller.php:555
+msgid "review_flag_success"
+msgstr "Thanks; this review has been flagged for editor approval."
+
+#: views/reviews/display.thtml:41
+msgid "review_flag_this"
+msgstr "Report this review"
+
+#: views/reviews/display.thtml:42
+msgid "review_flag_this_titletip"
+msgstr ""
+"Is this review inappropriate, inaccurate or spam? Click here to flag it for "
+"editor review."
+
+#. %1 is the URL of the support section, %2 for the review guidelines
+#: views/reviews/add.thtml:53
+msgid "review_guidelines_short"
+msgstr ""
+"<p>Keep these tips in mind:</p><ul><li>Write like you're telling a friend "
+"about your experience with the add-on. Give specifics and helpful details, "
+"such as what features you liked and/or disliked, how easy to use it is, and "
+"any disadvantages it has. Avoid generic language such as calling it \"Great"
+"\" or \"Bad\" unless you can give reasons why you believe this is so.</"
+"li><li>Please do not post bug reports in reviews. We do not make your email "
+"address available to add-on developers and they may need to contact you to "
+"help resolve your issue. See the <a href=\"%1$s\">support section</a> to "
+"find out where to get assistance for this add-on.</li><li>Please keep "
+"reviews clean, avoid the use of improper language and do not post any "
+"personal information.</li></ul><p>Please read the <a href=\"%2$s\">Review "
+"Guidelines</a> for more detail about user add-on reviews.</p>"
+
+#. %1 is the add-on name
+#: views/reviews/flag.thtml:56 views/reviews/display.thtml:55
+#: views/reviews/review_added.thtml:50
+#, php-format
+msgid "reviews_header"
+msgstr "Reviews for %s"
+
+#: controllers/addons_controller.php:435
+msgid "rss_featuredaddons"
+msgstr "Featured Add-ons"
+
+#: controllers/addons_controller.php:432
+msgid "rss_newestaddons"
+msgstr "Newest Add-ons"
+
+#: controllers/addons_controller.php:434
+msgid "rss_popularaddons"
+msgstr "Popular Add-ons"
+
+#: controllers/addons_controller.php:433
+msgid "rss_updatedaddons"
+msgstr "Updated Add-ons"
+
+#: views/elements/search_mini.thtml:70
+msgid "search"
+msgstr "Search"
+
+#: views/search/collections.thtml:51
+msgid "search_collections_header"
+msgstr "Collection Search Results"
+
+#: controllers/search_controller.php:297
+msgid "search_collections_pagetitle"
+msgstr "Collection Search Results"
+
+#: controllers/search_controller.php:99
+msgid "search_disabled"
+msgstr "Search is currently disabled. Please try again later."
+
+#: views/elements/amo2009/search.thtml:188 views/elements/search.thtml:187
+#: views/elements/search_mini.thtml:54
+msgid "search_form_all_addons"
+msgstr "all add-ons"
+
+#. This string is in the main category dropdown when searching
+#: views/elements/amo2009/search.thtml:204
+msgid "search_form_all_collections"
+msgstr "all collections"
+
+#: views/elements/amo2009/search.thtml:184
+#: views/elements/amo2009/search.thtml:385
+#: views/elements/amo2009/search.thtml:408 views/elements/search.thtml:171
+#: views/elements/search.thtml:183 views/elements/search_mini.thtml:43
+#: views/elements/search_mini.thtml:49 views/layouts/mozilla.thtml:188
+msgid "search_form_default_text"
+msgstr "search for add-ons"
+
+#: views/elements/amo2009/search.thtml:184
+#: views/elements/amo2009/search.thtml:404
+msgid "search_form_default_text_collections"
+msgstr "search for collections"
+
+#: views/elements/amo2009/search.thtml:206 views/elements/search.thtml:202
+msgid "search_form_submit_tooltip"
+msgstr "Search for add-ons"
+
+#: views/elements/amo2009/search.thtml:184 views/elements/search.thtml:183
+#: views/elements/search_mini.thtml:49
+msgid "search_form_tooltip"
+msgstr "Click to enter search terms"
+
+#: views/elements/amo2009/search.thtml:186 views/elements/search.thtml:185
+#: views/elements/search_mini.thtml:52
+msgid "search_form_within"
+msgstr "within"
+
+#: views/addons/searchengines.thtml:118
+msgid "search_landing_all_search_engines"
+msgstr "All Search Engines"
+
+#: views/addons/searchengines.thtml:114
+msgid "search_landing_browse_search_engines"
+msgstr "Browse Search Engines"
+
+#: views/search/collections.thtml:58 views/search/index.thtml:59
+msgid "search_nothing_found"
+msgstr "No results found."
+
+#: controllers/search_controller.php:185
+msgid "search_pagetitle"
+msgstr "Search Add-ons"
+
+#: controllers/search_controller.php:242
+msgid "search_rss_description"
+msgstr "Search results feed"
+
+#. %s is the terms the user is searching for (a string)
+#: controllers/search_controller.php:241
+#, php-format
+msgid "search_rss_results_for"
+msgstr "Search results for: %s"
+
+#: views/elements/header.thtml:154 views/layouts/amo2009.thtml:296
+msgid "sidebar_navlink_admin_tools"
+msgstr "Admin Tools"
+
+#: views/elements/header.thtml:146 views/layouts/amo2009.thtml:288
+msgid "sidebar_navlink_developer_tools"
+msgstr "Developer Tools"
+
+#: views/elements/header.thtml:148 views/layouts/amo2009.thtml:290
+msgid "sidebar_navlink_editor_tools"
+msgstr "Editor Tools"
+
+#: views/layouts/amo2009.thtml:302
+msgid "sidebar_navlink_welcome"
+msgstr "Welcome"
+
+#. %s is the user's name
+#: views/layouts/amo2009.thtml:302
+#, php-format
+msgid "sidebar_navlink_welcome_name"
+msgstr "Welcome, %s"
+
+#: views/elements/pitch.thtml:50 views/elements/pitch.thtml:55
+msgid "sidebar_pitch_dictionary"
+msgstr "Dictionary"
+
+#: views/elements/pitch.thtml:72
+msgid "sidebar_pitch_featured_addons"
+msgstr "Featured Add-ons"
+
+#: views/elements/pitch.thtml:61
+msgid "sidebar_pitch_looking_for"
+msgstr "I am looking for a:"
+
+#: views/elements/pitch.thtml:70
+msgid "sidebar_pitch_newest_addons"
+msgstr "Newest Add-ons"
+
+#: views/elements/pitch.thtml:49
+msgid "sidebar_pitch_search"
+msgstr "Search Plugin"
+
+#: views/elements/pitch.thtml:69
+msgid "sidebar_pitch_subscribe_to"
+msgstr "Subscribe to"
+
+#: views/elements/pitch.thtml:48 views/elements/pitch.thtml:54
+msgid "sidebar_pitch_theme"
+msgstr "Theme"
+
+#: views/elements/pitch.thtml:71
+msgid "sidebar_pitch_updated_addons"
+msgstr "Updated Add-ons"
+
+#. %1$s is a number
+#: views/helpers/localization.php:65 views/developers/versions_edit.thtml:95
+#: views/addons/dictionaries.thtml:92
+#, php-format
+msgid "size_kb"
+msgstr "%1$s KB"
+
+#: views/elements/amo2009/stars.thtml:57 views/elements/stars.thtml:63
+msgid "stars_not_yet_rated"
+msgstr "Not yet rated"
+
+#. %1 is the number of stars this add-on has
+#: views/elements/amo2009/stars.thtml:49 views/elements/stars.thtml:54
+#, php-format
+msgid "stars_rated_x_outof_5"
+msgstr "Rated %s out of 5 stars"
+
+#: views/statistics/addon.thtml:59
+msgid "statistics_addon_dashboard_link"
+msgstr "Dashboard Home"
+
+#: views/statistics/addon.thtml:58
+msgid "statistics_addon_developertools_link"
+msgstr "Developer Tools"
+
+#: views/statistics/addon.thtml:53
+msgid "statistics_addon_switch"
+msgstr "Switch Add-on"
+
+#. This is a date format.
+#. http://php.net/strftime
+#: views/statistics/rss/summary.thtml:54 views/statistics/addon.thtml:181
+msgid "statistics_date_shortmonth"
+msgstr "%b. %e"
+
+#. This is a date format.
+#. http://php.net/strftime
+#: views/statistics/rss/summary.thtml:40 views/statistics/addon.thtml:152
+msgid "statistics_date_shortmonthwithyear"
+msgstr "%b. %e, %Y"
+
+#. This is a date format.
+#. http://php.net/strftime
+#: views/statistics/rss/summary.thtml:41 views/statistics/rss/summary.thtml:48
+#: views/statistics/addon.thtml:161 views/statistics/addon.thtml:172
+msgid "statistics_date_weekdayshortmonth"
+msgstr "%A, %b. %e"
+
+#. %1$s is an add-on name and version. Example: Add-on 3.5
+#: controllers/components/stats.php:519
+#, php-format
+msgid "statistics_events_addon_created"
+msgstr "%1$s created"
+
+#. %1$s is an application name and version. Example: Firefox 3.5
+#: controllers/components/stats.php:500
+#, php-format
+msgid "statistics_events_app_released"
+msgstr "%1$s released"
+
+#: views/statistics/addon.thtml:71
+msgid "statistics_help_close_link"
+msgstr "Close"
+
+#: views/statistics/addon.thtml:60
+msgid "statistics_help_link"
+msgstr "Help"
+
+#: views/statistics/index.thtml:83
+msgid "statistics_index_anotheraddon"
+msgstr "or, select another add-on"
+
+#: views/statistics/index.thtml:85
+msgid "statistics_index_anotheraddon_public"
+msgstr "or, select an add-on with public statistics"
+
+#: views/statistics/index.thtml:71
+msgid "statistics_index_myaddons"
+msgstr "Select one of your add-ons to view its statistics"
+
+#: views/statistics/index.thtml:89
+msgid "statistics_index_selectaddon"
+msgstr "Select an add-on to view its statistics"
+
+#: views/statistics/index.thtml:91
+msgid "statistics_index_selectaddon_public"
+msgstr "Select an add-on with public statistics"
+
+#: views/statistics/index.thtml:39
+msgid "statistics_index_title"
+msgstr "Statistics Dashboard"
+
+#: views/statistics/index.thtml:97
+msgid "statistics_index_view_button"
+msgstr "View Statistics"
+
+#: views/statistics/addon.thtml:222 controllers/statistics_controller.php:247
+msgid "statistics_js_download_csv"
+msgstr "View this table in CSV format"
+
+#: controllers/statistics_controller.php:246
+msgid "statistics_js_dropdowns_none"
+msgstr "none"
+
+#: controllers/statistics_controller.php:245
+msgid "statistics_js_dropdowns_removeplot"
+msgstr "Remove this plot"
+
+#: controllers/statistics_controller.php:248
+msgid "statistics_js_groupby_selector_date"
+msgstr "Group by: Day"
+
+#: controllers/statistics_controller.php:251
+msgid "statistics_js_groupby_selector_month"
+msgstr "Group by: Month"
+
+#: controllers/statistics_controller.php:249
+msgid "statistics_js_groupby_selector_week"
+msgstr "Group by: Week"
+
+#: controllers/statistics_controller.php:250
+msgid "statistics_js_groupby_selector_week_over_week"
+msgstr "Compare by: Week"
+
+#: controllers/statistics_controller.php:260
+msgid "statistics_js_plotselection_foundinrange"
+msgstr "%s found in range"
+
+#: controllers/statistics_controller.php:270
+msgid "statistics_js_plotselection_options_addplot_name"
+msgstr "Add Plot"
+
+#: controllers/statistics_controller.php:271
+msgid "statistics_js_plotselection_options_addplot_tooltip"
+msgstr "Add another plot to this graph"
+
+#: controllers/statistics_controller.php:261
+msgid "statistics_js_plotselection_options_count_name_checked"
+msgstr "Hide Total Count"
+
+#: controllers/statistics_controller.php:262
+msgid "statistics_js_plotselection_options_count_name_unchecked"
+msgstr "Show Total Count"
+
+#: controllers/statistics_controller.php:263
+msgid "statistics_js_plotselection_options_count_tooltip"
+msgstr "Plot the total count on this graph"
+
+#: controllers/statistics_controller.php:275
+msgid "statistics_js_plotselection_options_csv_name"
+msgstr "View Data (CSV)"
+
+#: controllers/statistics_controller.php:276
+msgid "statistics_js_plotselection_options_csv_tooltip"
+msgstr "Get a Comma Separated Values file of this data"
+
+#: controllers/statistics_controller.php:267
+msgid "statistics_js_plotselection_options_events_addon_name_checked"
+msgstr "Hide %s Events"
+
+#: controllers/statistics_controller.php:268
+msgid "statistics_js_plotselection_options_events_addon_name_unchecked"
+msgstr "Show %s Events"
+
+#: controllers/statistics_controller.php:269
+msgid "statistics_js_plotselection_options_events_addon_tooltip"
+msgstr "Overlay add-on release dates on the plots"
+
+#: controllers/statistics_controller.php:264
+msgid "statistics_js_plotselection_options_events_firefox_name_checked"
+msgstr "Hide Firefox Events"
+
+#: controllers/statistics_controller.php:265
+msgid "statistics_js_plotselection_options_events_firefox_name_unchecked"
+msgstr "Show Firefox Events"
+
+#: controllers/statistics_controller.php:266
+msgid "statistics_js_plotselection_options_events_firefox_tooltip"
+msgstr "Overlay Firefox release dates on the plots"
+
+#: controllers/statistics_controller.php:272
+msgid "statistics_js_plotselection_options_resize_name_checked"
+msgstr "Collapse Graph"
+
+#: controllers/statistics_controller.php:273
+msgid "statistics_js_plotselection_options_resize_name_unchecked"
+msgstr "Expand Graph"
+
+#: controllers/statistics_controller.php:274
+msgid "statistics_js_plotselection_options_resize_tooltip"
+msgstr "Resize the graph"
+
+#: controllers/statistics_controller.php:254
+msgid "statistics_js_plotselection_selector_adu"
+msgstr "Active Daily Users"
+
+#: controllers/statistics_controller.php:256
+msgid "statistics_js_plotselection_selector_application"
+msgstr "Application"
+
+#: controllers/statistics_controller.php:259
+msgid "statistics_js_plotselection_selector_custom"
+msgstr "Custom"
+
+#: controllers/statistics_controller.php:253
+msgid "statistics_js_plotselection_selector_downloads"
+msgstr "Downloads"
+
+#: controllers/statistics_controller.php:258
+msgid "statistics_js_plotselection_selector_os"
+msgstr "Operating System"
+
+#: controllers/statistics_controller.php:257
+msgid "statistics_js_plotselection_selector_status"
+msgstr "Add-on Status"
+
+#: controllers/statistics_controller.php:252
+msgid "statistics_js_plotselection_selector_summary"
+msgstr "Summary"
+
+#: controllers/statistics_controller.php:255
+msgid "statistics_js_plotselection_selector_version"
+msgstr "Add-on Version"
+
+#: controllers/components/stats.php:398
+msgid "statistics_longnames_application"
+msgstr "Application"
+
+#: controllers/components/stats.php:400
+msgid "statistics_longnames_os"
+msgstr "Operating System"
+
+#: controllers/components/stats.php:399
+msgid "statistics_longnames_status"
+msgstr "Add-on Status"
+
+#: controllers/components/stats.php:401
+msgid "statistics_longnames_unknown"
+msgstr "Unknown"
+
+#: controllers/components/stats.php:397
+msgid "statistics_longnames_version"
+msgstr "Add-on Version"
+
+#: views/statistics/addon.thtml:118
+msgid "statistics_notice_data_insufficient"
+msgstr ""
+"There is not yet enough data to display this graph. Please check back later."
+
+#: views/statistics/addon.thtml:130
+msgid "statistics_notice_data_none"
+msgstr ""
+"We don't have any data for your add-on yet. Please check back in a few days."
+
+#: views/statistics/addon.thtml:41
+msgid "statistics_notice_data_updating"
+msgstr ""
+"Add-on statistics are currently in the process of being updated. Recent data "
+"may be incomplete as our scripts work to update this information. Please "
+"check back in a few minutes."
+
+#: views/statistics/addon.thtml:136
+msgid "statistics_notice_disabled"
+msgstr ""
+"The Statistics Dashboard is currently disabled. Please check back later."
+
+#: views/statistics/addon.thtml:123
+msgid "statistics_notice_nojavascript"
+msgstr "JavaScript is required to view the Statistics Dashboard graphs."
+
+#: views/statistics/addon.thtml:44
+msgid "statistics_notice_settings_updated"
+msgstr "Your settings have been updated!"
+
+#: controllers/statistics_controller.php:60
+#: controllers/statistics_controller.php:71
+#: controllers/statistics_controller.php:74
+#: controllers/statistics_controller.php:240
+msgid "statistics_pagetitle"
+msgstr "Statistics Dashboard"
+
+#: views/statistics/addon.thtml:99
+msgid "statistics_plot_legend_adu"
+msgstr "Active Daily Users"
+
+#: views/statistics/addon.thtml:95
+msgid "statistics_plot_legend_downloads"
+msgstr "Daily Downloads"
+
+#: views/statistics/addon.thtml:107
+msgid "statistics_plot_options_zoomin_alt"
+msgstr "Zoom In"
+
+#: views/statistics/addon.thtml:106
+msgid "statistics_plot_options_zoomin_title"
+msgstr "Zoom in one month"
+
+#: views/statistics/addon.thtml:110
+msgid "statistics_plot_options_zoomout_alt"
+msgstr "Zoom Out"
+
+#: views/statistics/addon.thtml:109
+msgid "statistics_plot_options_zoomout_title"
+msgstr "Zoom out one month"
+
+#: controllers/statistics_controller.php:283
+#, php-format
+msgid "statistics_rss_description"
+msgstr "Daily summary of statistics for %1$s"
+
+#: views/statistics/rss/summary.thtml:68
+msgid "statistics_rss_title_fulldate"
+msgstr "%A, %B %e, %Y"
+
+#: views/statistics/rss/summary.thtml:68
+#, php-format
+msgid "statistics_rss_title_statsfordate"
+msgstr "Statistics for %1$s"
+
+#: views/statistics/settings.thtml:49
+msgid "statistics_settings_access_description"
+msgstr ""
+"By default, only you and Mozilla can access the information in your "
+"dashboard. You can open this up to the public so that anyone can view your "
+"add-on's data."
+
+#: views/statistics/settings.thtml:48
+msgid "statistics_settings_access_heading"
+msgstr "Dashboard Access"
+
+#: views/statistics/settings.thtml:51
+msgid "statistics_settings_access_private"
+msgstr "Private"
+
+#: views/statistics/settings.thtml:51
+msgid "statistics_settings_access_private_description"
+msgstr "Only you and Mozilla can view this add-on's statistics"
+
+#: views/statistics/settings.thtml:52
+msgid "statistics_settings_access_public"
+msgstr "Public"
+
+#: views/statistics/settings.thtml:52
+msgid "statistics_settings_access_public_description"
+msgstr "Anyone can view this add-on's statistics"
+
+#: views/statistics/addon.thtml:251
+msgid "statistics_settings_change_link"
+msgstr "Change Settings"
+
+#: views/statistics/addon.thtml:253
+msgid "statistics_settings_confidential"
+msgstr "Please treat this information as confidential."
+
+#: views/statistics/addon.thtml:245
+msgid "statistics_settings_currently_private"
+msgstr "This dashboard is currently <b>private</b>."
+
+#: views/statistics/addon.thtml:241
+msgid "statistics_settings_currently_public"
+msgstr "This dashboard is currently <b>public</b>."
+
+#: views/statistics/addon.thtml:246
+msgid "statistics_settings_locked_alt"
+msgstr "Locked"
+
+#: views/statistics/settings.thtml:57
+msgid "statistics_settings_return_link"
+msgstr "Return to Dashboard"
+
+#: views/statistics/settings.thtml:56
+msgid "statistics_settings_save_button"
+msgstr "Save Settings"
+
+#: views/statistics/settings.thtml:46
+#, php-format
+msgid "statistics_settings_title"
+msgstr "Statistics Dashboard Settings for %1$s"
+
+#: views/statistics/addon.thtml:242
+msgid "statistics_settings_unlocked_alt"
+msgstr "Unlocked"
+
+#: controllers/components/stats.php:405
+msgid "statistics_shortnames_application"
+msgstr "App"
+
+#: controllers/components/stats.php:407
+msgid "statistics_shortnames_os"
+msgstr "OS"
+
+#: controllers/components/stats.php:406
+msgid "statistics_shortnames_status"
+msgstr "St"
+
+#: controllers/components/stats.php:408
+msgid "statistics_shortnames_unknown"
+msgstr "Uk"
+
+#: controllers/components/stats.php:404
+msgid "statistics_shortnames_version"
+msgstr "Ver"
+
+#: views/statistics/rss/summary.thtml:42 views/statistics/addon.thtml:192
+msgid "statistics_summary_downloads_average"
+msgstr "Average Daily Downloads"
+
+#: views/statistics/rss/summary.thtml:39
+msgid "statistics_summary_downloads_heading"
+msgstr "Downloads"
+
+#: views/statistics/rss/summary.thtml:41 views/statistics/addon.thtml:171
+msgid "statistics_summary_downloads_lastcount"
+msgstr "Last Day Count"
+
+#: views/statistics/rss/summary.thtml:43 views/statistics/addon.thtml:199
+msgid "statistics_summary_downloads_lastweek"
+msgstr "Downloads in the last 7 days"
+
+#: views/statistics/rss/summary.thtml:40 views/statistics/addon.thtml:151
+msgid "statistics_summary_downloads_total"
+msgstr "Total Downloads"
+
+#: views/statistics/rss/summary.thtml:40 views/statistics/addon.thtml:152
+#, php-format
+msgid "statistics_summary_downloads_total_sincedate"
+msgstr "Since %1$s"
+
+#: views/statistics/rss/summary.thtml:50 views/statistics/rss/summary.thtml:56
+#: views/statistics/addon.thtml:163 views/statistics/addon.thtml:183
+msgid "statistics_summary_nodata"
+msgstr "No data yet"
+
+#: views/statistics/rss/summary.thtml:60 views/statistics/addon.thtml:195
+msgid "statistics_summary_updatepings_average"
+msgstr "Average Daily Active Users"
+
+#: views/statistics/rss/summary.thtml:52 views/statistics/addon.thtml:177
+msgid "statistics_summary_updatepings_changefromprevious"
+msgstr "Change from previous count"
+
+#: views/statistics/rss/summary.thtml:54 views/statistics/addon.thtml:181
+#, php-format
+msgid "statistics_summary_updatepings_changefromprevious_ondate"
+msgstr "%1$s on %2$s"
+
+#: views/statistics/rss/summary.thtml:45
+msgid "statistics_summary_updatepings_heading"
+msgstr "Active Daily Users"
+
+#: views/statistics/rss/summary.thtml:46 views/statistics/addon.thtml:157
+msgid "statistics_summary_updatepings_total"
+msgstr "Active Daily Users"
+
+#: views/statistics/rss/summary.thtml:48 views/statistics/addon.thtml:161
+#, php-format
+msgid "statistics_summary_updatepings_total_ondate"
+msgstr "On %1$s"
+
+#: views/statistics/rss/summary.thtml:61 views/statistics/addon.thtml:203
+msgid "statistics_summary_updatepings_weekly_average"
+msgstr "Average Daily Users this Week"
+
+#. %s is a percentage, like '+22.33%'. It sits next to another number, so
+#. the implied meaning is 'percentage change' from the previous stat point.
+#: views/statistics/rss/summary.thtml:62 views/statistics/addon.thtml:205
+msgid "statistics_summary_updatepings_weekly_change"
+msgstr "%s from last week"
+
+#: views/statistics/addon.thtml:65 controllers/statistics_controller.php:184
+#: controllers/statistics_controller.php:282
+#, php-format
+msgid "statistics_title_addon_stats"
+msgstr "%1$s Statistics"
+
+#: views/addons/themes_landing.thtml:113
+msgid "themes_landing_all_themes"
+msgstr "All Themes"
+
+#: views/addons/themes_landing.thtml:109
+msgid "themes_landing_browse_themes"
+msgstr "Browse Themes"
+
+#: views/users/edit.thtml:185
+msgid "user_change_email"
+msgstr "Change Email Address"
+
+#: views/users/edit.thtml:169
+msgid "user_change_password"
+msgstr "Change password"
+
+#: views/users/edit.thtml:96
+msgid "user_change_password_or_email"
+msgstr "Change Password or Email"
+
+#: controllers/users_controller.php:197
+msgid "user_confirmationcode_resent"
+msgstr "The confirmation code was resent!"
+
+#. %1 is the email address, %2 is the URL of the user registration page
+#: views/users/delete.thtml:51
+msgid "user_del_account_deleted"
+msgstr ""
+"Your user account %1$s has been successfully deleted. If you want to come "
+"back some time, you can re-register on the <a href=\"%2$s\">user "
+"registration page</a>."
+
+#: views/users/delete.thtml:102
+msgid "user_del_community_sad"
+msgstr "The Mozilla Add-ons community is sad to see you go."
+
+#: views/users/delete.thtml:123
+msgid "user_del_confirm_password"
+msgstr "Confirm Password"
+
+#: views/users/delete.thtml:134
+msgid "user_del_deletenow"
+msgstr "Delete my user account now"
+
+#. %1 is the URL of the user's info page
+#: views/users/delete.thtml:64
+msgid "user_del_error_addons"
+msgstr ""
+"You cannot delete your account if you are listed as an <a href=\"%1$s"
+"\">author of any add-ons</a>. To delete your account, please have another "
+"person in your development group delete you from the list of authors for "
+"your add-ons. Afterwards you will be able to delete your account here."
+
+#. %1 is a link to the amo-editors mailing list
+#: views/users/delete.thtml:71
+msgid "user_del_error_addons_more_questions"
+msgstr "If you have additional questions, please contact %1$s for assistance."
+
+#: views/users/delete.thtml:78
+msgid "user_del_error_checkbox"
+msgstr ""
+"You need to check the box \"I understand...\" before we can delete your "
+"account."
+
+#: views/users/delete.thtml:84
+msgid "user_del_error_password"
+msgstr "Please enter your password correctly in order to perform this step."
+
+#. %1 is a link to the amo-admins mailing list
+#: views/users/delete.thtml:91
+msgid "user_del_error_unknown"
+msgstr ""
+"An unknown error occured deleting your account. Please contact %1$s with the "
+"issue and we will delete it for you. We apologize for the inconvenience."
+
+#: views/users/delete.thtml:110
+msgid "user_del_header_confirm_deletion"
+msgstr "Confirm account deletion"
+
+#. %1 is the user's email address
+#: views/users/delete.thtml:100
+msgid "user_del_header_delete_account"
+msgstr "Delete User Account %1$s"
+
+#: views/users/delete.thtml:50
+msgid "user_del_header_farewell"
+msgstr "Farewell!"
+
+#: views/users/delete.thtml:115
+msgid "user_del_nologin"
+msgstr "You will not be able to log into Mozilla Add-ons anymore."
+
+#: views/users/delete.thtml:112
+msgid "user_del_permanently_removed_means"
+msgstr ""
+"By clicking \"delete\" your account is going to be <strong>permanently "
+"removed</strong>. That means:"
+
+#: views/users/delete.thtml:116
+msgid "user_del_reviews_anonymized"
+msgstr ""
+"Your reviews and ratings will not be deleted, but they will no longer be "
+"associated with you."
+
+#. %1 is a link to the amo-editors mailing list
+#: views/users/delete.thtml:104
+msgid "user_del_specific_problem_editors"
+msgstr ""
+"If you have a specific problem we may help you with, please do not delete "
+"your account now, but contact us at %1$s and we will do our best to assist "
+"you in solving it."
+
+#: views/users/delete.thtml:130
+msgid "user_del_understand_permanent"
+msgstr "I understand that this step cannot be undone."
+
+#: views/helpers/addons_html.php:192
+msgid "user_deleted_nickname"
+msgstr "Deleted User"
+
+#. %1 is the new email address
+#: views/users/edit.thtml:71
+msgid "user_edit_confirm_email_sent"
+msgstr ""
+"An email has been sent to %1$s to confirm your new email address. For the "
+"change to take effect, you need to click on the link provided in this email. "
+"Until then, you can keep logging in with your current email address."
+
+#: views/users/edit.thtml:201
+msgid "user_edit_delete_user"
+msgstr "Delete user account"
+
+#. This contains the email sent to users when they signed up for a new
+#. account:
+#. %1 is the confirmation URL, %2 is the current app
+#: views/users/email/confirm_plain.thtml:6
+#, php-format
+msgid "user_email_confirm_account_nopass"
+msgstr ""
+"Welcome to %2$s Add-ons.\n"
+"\n"
+"Before you can use your new account you must activate it - this ensures the "
+"e-mail address you used is valid and belongs to you.\n"
+"To activate your account, click the link below or copy and paste the whole "
+"thing into your browser's location bar:\n"
+"\n"
+"%1$s\n"
+"\n"
+"Once you've successfully activated your account, you can throw away this e-"
+"mail.\n"
+"\n"
+"Thanks for joining %2$s Add-ons\n"
+"-- %2$s Add-ons Staff"
+
+#. %1 is the confirmation url, %2 is the application name
+#: views/users/email/emailchange_plain.thtml:5
+msgid "user_email_confirm_emailchange"
+msgstr ""
+"You requested a change to your email address at %2$s Add-ons.\n"
+"\n"
+"In order to confirm the new address, please click the link below or copy and "
+"paste the whole thing into your browser's location bar:\n"
+"\n"
+"%1$s\n"
+"\n"
+"You have 48 hours to confirm the new address. If you do not want to change "
+"the address anymore, you can just ignore this email.\n"
+"\n"
+"Thanks!\n"
+"-- %2$s Add-ons Staff"
+
+#: controllers/users_controller.php:168
+#, php-format
+msgid "user_email_confirm_subject"
+msgstr "Thanks for joining %s Add-ons"
+
+#. This is the password reset email
+#. %1 is the pw reset URL, %2 is the application
+#: views/users/email/pwreset_plain.thtml:5
+#, php-format
+msgid "user_email_pwreset"
+msgstr ""
+"%2$s Add-ons Password Reset\n"
+"\n"
+"A request was received to reset the password for this account on addons."
+"mozilla.org. To change this password please click on the following link, or "
+"paste it into your browser's location bar:\n"
+"\n"
+"%1$s\n"
+"\n"
+"If you did not request this email there is no need for further action.\n"
+"\n"
+"Thanks,\n"
+"-- %2$s Add-ons Staff"
+
+#: controllers/users_controller.php:245
+#, php-format
+msgid "user_email_pwreset_subject"
+msgstr "Reset your %s Add-ons password"
+
+#: views/users/emailchange.thtml:50
+msgid "user_emailchange_error"
+msgstr "Error!"
+
+#. %1 is the application name
+#: controllers/users_controller.php:533
+msgid "user_emailchange_subject"
+msgstr "Please confirm your email address change at %1$s Add-ons"
+
+#: views/users/emailchange.thtml:48
+msgid "user_emailchange_success"
+msgstr "Success!"
+
+#. %1 is the new email address
+#: views/users/emailchange.thtml:49
+msgid "user_emailchange_successful_description"
+msgstr ""
+"Your email address was changed successfully. From now on, please use %1$s to "
+"log in."
+
+#: views/users/edit.thtml:134 views/admin/users_edit.thtml:111
+msgid "user_form_bio"
+msgstr "About me"
+
+#: views/users/edit.thtml:135 views/admin/users_edit.thtml:112
+msgid "user_form_bio_description"
+msgstr ""
+"Introduce yourself to the community, if you like! This text will appear "
+"publicly on your user info page. Line breaks will be preserved, but no HTML "
+"is allowed."
+
+#: views/users/pwreset.thtml:77 views/users/register.thtml:73
+#: views/users/edit.thtml:181
+msgid "user_form_confirmpassword"
+msgstr "Confirm password"
+
+#: views/users/edit.thtml:145
+msgid "user_form_display_collections"
+msgstr "Display the collections I have created in my user profile"
+
+#: views/users/edit.thtml:149
+msgid "user_form_display_collections_fav"
+msgstr "Display my favorite collections in my user profile"
+
+#: views/users/edit.thtml:86
+#, php-format
+msgid "user_form_editprofile"
+msgstr "Edit user profile for %s"
+
+#: views/users/pwreset.thtml:52 views/users/login.thtml:81
+#: views/users/register.thtml:63 views/users/edit.thtml:187
+msgid "user_form_email"
+msgstr "Email address"
+
+#: views/users/register.thtml:78 views/users/edit.thtml:103
+#: views/admin/users_edit.thtml:76
+msgid "user_form_firstname"
+msgstr "First name"
+
+#: views/users/register.thtml:94 views/users/edit.thtml:119
+#: views/admin/users_edit.thtml:91
+msgid "user_form_hideemail"
+msgstr "Hide email address"
+
+#: views/users/register.thtml:98 views/users/edit.thtml:123
+#: views/admin/users_edit.thtml:99
+msgid "user_form_homepage"
+msgstr "Website URL"
+
+#: views/users/register.thtml:84 views/users/edit.thtml:109
+#: views/admin/users_edit.thtml:81
+msgid "user_form_lastname"
+msgstr "Last name"
+
+#: controllers/users_controller.php:333
+msgid "user_form_login"
+msgstr "User Login"
+
+#: views/users/pwreset.thtml:72 views/users/edit.thtml:176
+msgid "user_form_newpassword"
+msgstr "New password"
+
+#: views/users/register.thtml:89 views/users/edit.thtml:114
+#: views/admin/users_edit.thtml:86
+msgid "user_form_nickname"
+msgstr "Nickname"
+
+#: views/users/edit.thtml:171
+msgid "user_form_oldpassword"
+msgstr "Old password"
+
+#: views/users/edit.thtml:97 views/users/edit.thtml:200
+msgid "user_form_otheractions"
+msgstr "Other Actions"
+
+#: views/users/login.thtml:85 views/users/register.thtml:68
+msgid "user_form_password"
+msgstr "Password"
+
+#: controllers/users_controller.php:93
+msgid "user_form_registration"
+msgstr "New User Registration"
+
+#: views/users/login.thtml:90
+msgid "user_form_remember_me"
+msgstr "Remember me on this computer"
+
+#: views/admin/users_edit.thtml:95
+msgid "user_form_showsandbox"
+msgstr "Show sandbox?"
+
+#: views/users/edit.thtml:205
+msgid "user_form_submit_edit"
+msgstr "Save"
+
+#: views/users/login.thtml:93
+msgid "user_form_submit_login"
+msgstr "Log in"
+
+#: views/users/register.thtml:113
+msgid "user_form_submit_register"
+msgstr "Register"
+
+#: views/users/info.thtml:75
+#, php-format
+msgid "user_info_usersince"
+msgstr "%s Add-ons user since"
+
+#: views/users/login.thtml:102
+msgid "user_login_register_link"
+msgstr "Create a new user account"
+
+#: views/users/edit.thtml:160
+msgid "user_notifications_item_compat"
+msgstr "Add-on Compatibility (strongly recommended)"
+
+#: views/users/edit.thtml:161
+msgid "user_notifications_item_events"
+msgstr "Upcoming events and contests"
+
+#: views/users/edit.thtml:156
+msgid "user_notifications_none_available"
+msgstr "There are currently no notifications available for you to configure."
+
+#: views/users/edit.thtml:158
+msgid "user_notifications_select_topics"
+msgstr ""
+"From time to time, Mozilla may send you email about upcoming releases and "
+"add-on events. Please select the topics you are interested in below:"
+
+#: views/users/edit.thtml:164
+msgid "user_notifications_specific_contact"
+msgstr ""
+"Mozilla reserves the right to contact you individually about specific "
+"concerns with your hosted add-ons."
+
+#: controllers/users_controller.php:543
+msgid "user_profile_edit_error"
+msgstr ""
+"There were errors in the changes you made. Please correct them and resubmit."
+
+#: controllers/users_controller.php:540
+msgid "user_profile_saved"
+msgstr "Profile updated."
+
+#: views/users/pwreset.thtml:65
+#, php-format
+msgid "user_pwreset_for_email"
+msgstr "Password reset for %s"
+
+#: controllers/users_controller.php:226
+msgid "user_pwreset_header"
+msgstr "Password Reset"
+
+#: views/users/login.thtml:103
+msgid "user_pwreset_link"
+msgstr "Forgot your password?"
+
+#: controllers/users_controller.php:248
+msgid "user_pwreset_link_sent"
+msgstr "The password reset link was sent to your email address."
+
+#: controllers/users_controller.php:304
+msgid "user_pwreset_okay"
+msgstr "Password successfully reset."
+
+#: views/users/pwreset.thtml:82
+msgid "user_pwreset_submit_changepw"
+msgstr "Submit password change"
+
+#: views/users/pwreset.thtml:57
+msgid "user_pwreset_submit_sendlink"
+msgstr "Send password reset link"
+
+#: views/users/register_complete.thtml:51
+#, php-format
+msgid "user_register_amo_link"
+msgstr "%s Add-ons"
+
+#. %1 is the user's email address, %2 is the current app
+#: views/users/activatefirst.thtml:49
+#, php-format
+msgid "user_register_click_confirm_link"
+msgstr ""
+"A link to activate your user account was sent by email to your address %1$s. "
+"You have to click it before you can log into %2$s Add-ons."
+
+#. %1 is the user's email address
+#: views/users/register_complete.thtml:49
+#, php-format
+msgid "user_register_confirm_email_sent"
+msgstr ""
+"An email has been sent to your address %1$s to confirm your account. Before "
+"you can log in, you have to activate your account by clicking on the link "
+"provided in this email."
+
+#: views/users/activatefirst.thtml:51
+msgid "user_register_confirmation_link_text"
+msgstr "resend the confirmation message"
+
+#: views/users/register_complete.thtml:47
+msgid "user_register_congratulations"
+msgstr "Congratulations! Your user account was successfully created."
+
+#: views/users/register.thtml:50
+msgid "user_register_details"
+msgstr ""
+"<p>Registration on AMO is <strong>not required</strong> if you simply want "
+"to download and install public add-ons.</p><p>You only need to register if:</"
+"p><ul><li>You want to submit reviews for add-ons</li><li>You are an add-on "
+"developer and want to upload your add-on for hosting on AMO</li></ul><p>Upon "
+"successful registration, you will be sent a confirmation email to the "
+"address you provided. Please follow the instructions there to confirm your "
+"account.</p><p>If you like, you can read our <a href='%1$s' title='Legal "
+"Notices'>Legal Notices</a> and <a href='%2$s' title='Privacy Policy'>Privacy "
+"Policy</a>.</p>"
+
+#. %1 is the link to the "resend confirmation code" page
+#: views/users/activatefirst.thtml:51
+#, php-format
+msgid "user_register_resend_confirmation_link"
+msgstr ""
+"If you did not receive the confirmation email, make sure your email service "
+"did not mark it as \"junk mail\" or \"spam\". If you need to, you can have "
+"us %1$s to your email address mentioned above."
+
+#. %1 is the link to the Mozilla Add-ons front page
+#: views/users/register_complete.thtml:51
+#, php-format
+msgid "user_register_welcome"
+msgstr "Thanks for registering and welcome to %1$s!"
+
+#: views/users/register.thtml:49
+msgid "user_register_welcome_header"
+msgstr "Welcome to addons.mozilla.org (AMO)!"
+
+#: views/users/register.thtml:81 views/users/edit.thtml:106
+msgid "user_required_firstlast_or_nickname"
+msgstr "A first name, last name or nickname is required."
+
+#: views/users/edit.thtml:94 views/users/edit.thtml:142
+msgid "user_tab_collections"
+msgstr "Collections"
+
+#: views/users/edit.thtml:95 views/users/edit.thtml:154
+msgid "user_tab_notifications"
+msgstr "Notifications"
+
+#: views/users/edit.thtml:93 views/users/edit.thtml:101
+msgid "user_tab_profile"
+msgstr "User Profile"
+
+#: controllers/users_controller.php:209
+msgid "user_verified_okay"
+msgstr "Successfully verified!"
+
+#: controllers/users_controller.php:723
+msgid "users_delete_pagetitle"
+msgstr "Delete User Account"
+
+#: controllers/users_controller.php:414
+msgid "users_edit_pagetitle"
+msgstr "User Account Editing"
+
+#: views/users/info.thtml:71
+msgid "users_info_aboutme"
+msgstr "About Me"
+
+#: views/users/info.thtml:96
+#, php-format
+msgid "users_info_addons_by_user"
+msgstr "Add-ons by %1$s"
+
+#: views/users/info.thtml:51
+msgid "users_info_author_name"
+msgstr "Name"
+
+#: views/users/info.thtml:48
+msgid "users_info_author_profile"
+msgstr "User Profile"
+
+#. %s is the user name
+#: views/users/info.thtml:137
+msgid "users_info_collections_by_user"
+msgstr "Collections by %s"
+
+#: views/users/info.thtml:66
+msgid "users_info_email"
+msgstr "Email address"
+
+#: views/users/info.thtml:155
+msgid "users_info_fav_collections_by_user"
+msgstr "Favorite Collections"
+
+#: views/users/info.thtml:61
+msgid "users_info_homepage"
+msgstr "Homepage"
+
+#: views/users/info.thtml:56
+msgid "users_info_nickname"
+msgstr "Nickname"
+
+#: controllers/users_controller.php:707
+#, php-format
+msgid "users_info_pagetitle"
+msgstr "User Info for %1$s"
+
+#. %1 is the user's name
+#: views/users/info.thtml:116
+msgid "users_info_reviews_by_user"
+msgstr "Reviews by %s"
+
+#: controllers/users_controller.php:330 controllers/users_controller.php:332
+msgid "users_login_pagetitle"
+msgstr "User Login"
+
+#. %1 is the link to the sandbox/policy explanation page
+#. This message is for a specific add-on not found
+#: views/users/login.thtml:53
+#, php-format
+msgid "users_login_sandbox_display_warning"
+msgstr ""
+"The add-on you're looking for is currently in the sandbox. If you already "
+"have an account on Mozilla Add-ons, please log in, or <a href=\"%1$s\">learn "
+"more about the sandbox.</a>"
+
+#. %1 is the link to the sandbox/policy explanation page
+#. This message is for any given sandbox-related page not found
+#: views/users/login.thtml:56
+#, php-format
+msgid "users_login_sandbox_page_warning"
+msgstr ""
+"The page you're looking for is part of the sandbox. If you already have an "
+"account on Mozilla Add-ons, please log in, or <a href=\"%1$s\">learn more "
+"about the sandbox.</a>"
+
+#: controllers/users_controller.php:223 controllers/users_controller.php:225
+msgid "users_pwreset_pagetitle"
+msgstr "User Password Reset"
+
+#: controllers/users_controller.php:90 controllers/users_controller.php:92
+msgid "users_register_pagetitle"
+msgstr "New User Registration"
+
+#. %1$s is an addon name, like <a>Firebug</a>
+#. %2$s is a version number, like <a>1.2</a>
+#: views/versions/license.thtml:52
+msgid "versions_license_header_source"
+msgstr "Source code license for %1$s %2$s"
+
+#: views/addons/category_landing.thtml:147
+msgid "view_recently_added"
+msgstr "View all recently added"
+
+#: views/addons/category_landing.thtml:161
+msgid "view_top_downloads"
+msgstr "View all top downloads"
+
+#: views/addons/category_landing.thtml:175
+msgid "view_top_rated"
+msgstr "View all top rated"
diff --git a/site/app/locale/en_US/images/sandbox-review.png b/site/app/locale/en_US/images/sandbox-review.png
new file mode 100644
index 0000000..56b3f55
--- /dev/null
+++ b/site/app/locale/en_US/images/sandbox-review.png
Binary files differ
diff --git a/site/app/locale/en_US/pages/about.thtml b/site/app/locale/en_US/pages/about.thtml
new file mode 100644
index 0000000..3b4946a
--- /dev/null
+++ b/site/app/locale/en_US/pages/about.thtml
@@ -0,0 +1,65 @@
+<h2>What is addons.mozilla.org?</h2>
+<p>
+ addons.mozilla.org (AMO) is Mozilla's official site for add-ons for Mozilla
+ applications. Add-ons let you add new features to Firefox, Thunderbird,
+ SeaMonkey, and Sunbird. From AMO, you can browse and download thousands of
+ add-ons to change the way you use the internet.
+</p>
+
+<h2>Who creates these add-ons?</h2>
+<p>
+ The thousands of add-on developers range from individual hobbyists to large
+ corporations. All public add-ons are reviewed by a staff of dedicated
+ volunteers before being released. Experimental add-ons are marked as such and
+ have not been reviewed.
+</p>
+
+<h2>How do I keep up on what's going on with AMO?</h2>
+<p>
+ Our <a href="http://blog.mozilla.com/addons/">blog</a> is regularly updated,
+ and we often feature posts from the general community. We also have a
+ <a href="https://addons.mozilla.org/newsletter">newsletter</a> which gets sent
+ out on a monthly basis.
+</p>
+
+<h2>This sounds great! How can I get involved?</h2>
+<p>
+ There are plenty of ways to get involved:
+</p>
+<ul>
+ <li>
+ <a href="https://wiki.mozilla.org/AMO:Editors/Applying">Become an
+ editor</a>. Our editors are AMO fans with a technical background who
+ review add-ons for code quality and stability.
+ </li>
+ <li>
+ <a href="http://developer.mozilla.org/">Make your own add-on</a>. AMO
+ provides free hosting and update services and can help you reach a large
+ audience of users.
+ </li>
+ <li>
+ Tell your friends! <a href="http://spreadfirefox.com/">Spread Firefox</a>
+ and let people know which add-ons you use.
+ </li>
+ <li>
+ Submit bugs and fixes.
+ <a href="https://bugzilla.mozilla.org/buglist.cgi?quicksearch=addons">Bugzilla</a>
+ contains all of our current AMO bugs. You can submit ones that haven't
+ been found yet or contribute patches.
+ </li>
+</ul>
+
+<h2>I have a question.</h2>
+<p>
+ A good place to start is our
+ <a href="https://addons.mozilla.org/pages/faq"><abbr title="Frequently Asked Questions">FAQ</abbr></a>. If you don't find
+ an answer there use the contact information at the bottom of this page. For
+ questions about a specific add-on use the contact information found on each add-on's listing page.
+</p>
+
+<h2>Contact Us</h2>
+<dl>
+ <dt>Using <abbr title="Internet Relay Chat">IRC</abbr>:</dt>
+ <dd><a href="irc://irc.mozilla.org/#addons">#addons</a> on irc.mozilla.org for general questions and review questions</dd>
+ <dd><a href="irc://irc.mozilla.org/#amo">#amo</a> on irc.mozilla.org for administrative or development concerns</dd>
+</dl>
diff --git a/site/app/locale/en_US/pages/collector.thtml b/site/app/locale/en_US/pages/collector.thtml
new file mode 100644
index 0000000..8c36fed
--- /dev/null
+++ b/site/app/locale/en_US/pages/collector.thtml
@@ -0,0 +1,47 @@
+<h2>Mozilla Firefox Add-on Collector</h2>
+
+<p class="intro">Keep your browser customization cutting-edge.</p>
+
+<div class="primary">
+ <p>Discover more of the best add-ons and organize your favorites in easy-to-manage collections. Subscribe to see how the collections you admire grow, and fans follow when you manage and update your own collections.</p>
+</div>
+
+<div class="secondary">
+ <div class="highlight">
+ <h4>Download the Add-on Collector:</h4>
+ %1$s
+ </div><!-- /.highlight -->
+</div>
+
+<div class="column-wrapper article-wrapper">
+
+ <div class="column first">
+ <div class="article">
+ <h3>Recommend Collections</h3>
+ <p>Subscribe to an Add-on Collection and get notification when it grows. If you're creating the collection, there's space to tell why you like an add-on and give some context for customization.</p>
+
+ </div>
+ </div>
+
+ <div class="column">
+ <div class="article">
+ <h3>Share Add-ons</h3>
+ <p>Ping friends about good finds. Choose “Publish to†and they get news about add-ons in a ready-to-go format endorsed by the source (that's you!).</p>
+ </div>
+
+ </div>
+
+
+ <div class="column">
+ <div class="article">
+ <h3>Sync with All Sources</h3>
+ <p>Announce new Add-on Collections and give links that stay current, thanks to Auto Publisher. Sync devices and keep all your browsers stocked with your latest collection.</p>
+ </div>
+ </div>
+
+</div><!-- /.column-wrapper .article-wrapper -->
+
+<ul class="further-navigation">
+ <li><a href="%2$s">Add-on Collector Features</a></li>
+ <li><a href="%3$s">Frequently Asked Questions</a></li>
+</ul>
diff --git a/site/app/locale/en_US/pages/collector_faq.thtml b/site/app/locale/en_US/pages/collector_faq.thtml
new file mode 100644
index 0000000..f58f83f
--- /dev/null
+++ b/site/app/locale/en_US/pages/collector_faq.thtml
@@ -0,0 +1,24 @@
+<h2>Add-on Collector Frequently Asked Questions</h2>
+
+<dl class="faq">
+<dt>What are collections?</dt>
+<dd>Collections are groups of related add-ons assembled for easy sharing.</dd>
+
+<dt>What is the Add-on Collector?</dt>
+<dd>Add-on Collector is an extension for Firefox that makes it easy to stay up-to-date with your favorite collections.</dd>
+
+<dt>What do I need in order to use the Add-on Collector?</dt>
+<dd>You'll need a <a href="%s">Mozilla Add-ons account</a> and the latest copy of <a href="http://www.getfirefox.com">Firefox</a>.</dd>
+
+<dt>How do I subscribe to a collection?</dt>
+<dd>You can subscribe to a collection by marking it as a favorite in the <a href="%s">Collection Directory</a>. Your favorite collections will then appear as subscriptions in the Add-ons Manager.</dd>
+
+<dt>How can I synchronize my add-ons between computers using the Add-on Collector?</dt>
+<dd>Just set up an auto-publisher with one computer, and it will appear at the top of your subscriptions list on all of the computers that have the Collector installed. You'll then be able to see add-ons installed on each computer that has an auto-publisher set up.</dd>
+
+<dt>Isn't Weave from Mozilla Labs already working on synchronizing my add-ons?</dt>
+<dd>Weave does plan to support synchronization of add-ons between profiles and devices in the future. The Add-on Collector's synchronization works a bit differently, in that your auto-published data is not encrypted and is designed to be shared with friends in the form of a collection. Add-ons can be shared between profiles using multiple collections.</dd>
+
+<dt>Where can I provide feedback or report a bug?</dt>
+<dd>If you've found a bug or would like to make a feature suggestion, please file it in Bugzilla using <a href="https://bugzilla.mozilla.org/enter_bug.cgi?component=Bandwagon&amp;product=addons.mozilla.org">this form</a>. If you'd like to provide general feedback, please post to <a href="http://groups.google.com/group/mozilla.dev.amo">our newsgroup</a>.</dd>
+</dl>
diff --git a/site/app/locale/en_US/pages/collector_features.thtml b/site/app/locale/en_US/pages/collector_features.thtml
new file mode 100644
index 0000000..7326356
--- /dev/null
+++ b/site/app/locale/en_US/pages/collector_features.thtml
@@ -0,0 +1,33 @@
+<h2>Mozilla Firefox Add-on Collector</h2>
+<h4>Keep your browser customization cutting-edge.</h4>
+<h3>Extension Features</h3>
+<p>
+ The Add-on Collector keeps you connected with your favorite add-ons and
+ collections in several ways:
+</p>
+
+<dl>
+ <dt>Access your favorite collections from Firefox</dt>
+ <dd>
+ Collections that you mark as favorites in the
+ <a href="%1$s">Collection Directory</a> appear in a special part of
+ the Add-ons Manager. You'll be able to stay up-to-date and view the contents
+ of each collection.
+ </dd>
+ <dt>Share add-ons with the Publishing Menu</dt>
+ <dd>
+ Each add-on you install is easily shared with a friend via e-mail or
+ published to one of your collections through a publishing menu.
+ </dd>
+ <dt>Receive notifications</dt>
+ <dd>
+ Collector will alert you when one of your favorite collections has a new
+ item, and mark it for you to review later.
+ </dd>
+
+ <dt>Automatically publish your installed add-ons to a collection</dt>
+ <dd>
+ Auto-publisher functionality keeps your collection continuously updated with
+ your latest add-ons, keeping your friends who subscribe up-to-date.
+ </dd>
+</dl>
diff --git a/site/app/locale/en_US/pages/collector_firstrun.thtml b/site/app/locale/en_US/pages/collector_firstrun.thtml
new file mode 100644
index 0000000..520e89a
--- /dev/null
+++ b/site/app/locale/en_US/pages/collector_firstrun.thtml
@@ -0,0 +1,38 @@
+<div>
+ <h2>Welcome</h2>
+ <p class="intro">The Firefox Add-on Collector has been added to your copy of the Firefox browser. You're almost ready to start building, managing, sharing and receiving Add-on Collections.</p>
+</div>
+
+ <div class="primary">
+ <h3>To start using your Firefox Add-on Collector</h3>
+ <ol class="numbered">
+ <li>
+ <h4 class="step">1</h4>
+ Click on the Tools menu on your Firefox toolbar and select “Add-ons.â€
+ </li>
+ <li>
+ <h4 class="step">2</h4>
+ From the Subscriptions pane, log in with your Mozilla add-ons account information.
+ </li>
+ <li>
+ <h4 class="step">3</h4>
+ You'll see a list of all your collections to the left. Click on any collection for a detailed list of contents. Click “Add to Firefox†or “Publish to†to manage that collection or send to a friend via email.
+ </li>
+ </ol>
+ <p>Whether you’re an avid add-on hound or just someone who uses add-ons to make your web experience better, Add-on Collector is here to help. For more information about Firefox Add-on Collector features and commonly asked questions, check out the <a href="%1$s">features page</a> and <a href="%2$s">FAQ</a>.</p>
+ </div><!-- / .primary -->
+
+ <div class="secondary">
+ <div class="highlight">
+ <h4>Get Started with These Collections</h4>
+
+ <ul>
+ %3$s
+ </ul>
+
+ <ul class="further-navigation">
+ <li><a href="%4$s" class="more-info">View All Collections</a></li>
+ </ul>
+ </div><!-- /. highlight -->
+ </div><!-- /. secondary-->
+
diff --git a/site/app/locale/en_US/pages/compatibility_developer_tips.thtml b/site/app/locale/en_US/pages/compatibility_developer_tips.thtml
new file mode 100644
index 0000000..bf844b3
--- /dev/null
+++ b/site/app/locale/en_US/pages/compatibility_developer_tips.thtml
@@ -0,0 +1,6 @@
+<ul class="tips">
+ <li>Information on updating your add-ons to %s can be found in this <a href="https://developer.mozilla.org/En/Updating_extensions_for_%s">Mozilla Developer Center article</a>.</li>
+ <li>Information on overall changes in %s can be found in <a href="https://developer.mozilla.org/en/%s_for_developers">this article</a>.</li>
+ <li>You can subscribe to the <a href="https://addons.mozilla.org/newsletter">about:addons newsletter</a> and the <a href="http://blog.mozilla.com/addons/">Mozilla Add-ons blog</a> for additional updates.</li>
+ <li>If your add-on requires no code changes to claim compatibility and is hosted on Mozilla Add-ons, you can bump its compatible maxVersion online without uploading a new file by heading to the <a href="%s">Developer Tools area</a> or by viewing its status below.</li>
+</ul> \ No newline at end of file
diff --git a/site/app/locale/en_US/pages/compatibility_user_tips.thtml b/site/app/locale/en_US/pages/compatibility_user_tips.thtml
new file mode 100644
index 0000000..03837fa
--- /dev/null
+++ b/site/app/locale/en_US/pages/compatibility_user_tips.thtml
@@ -0,0 +1,6 @@
+<ul class="tips">
+ <li>While many add-ons can support the changes in %s without any code modifications, others may require additional work by the authors to ensure a smooth upgrade. Please be patient during this time, as many add-on developers maintain their add-ons voluntarily as a hobby.</li>
+ <li>Mozilla discourages disabling the compatibility check setting, as this can lead to serious problems starting up %s and even data loss if an extension not compatible with a new version of %s is forced to be used.</li>
+ <li>If the extension you're trying to use is not compatible after %s is launched, you may want to check its website or author's homepage for any news concerning the update.</li>
+ <li>You may also want to look for an add-on with similar functionality that does support %s on the <a href="%s">%s Add-ons</a> website.</li>
+</ul> \ No newline at end of file
diff --git a/site/app/locale/en_US/pages/developer_agreement.thtml b/site/app/locale/en_US/pages/developer_agreement.thtml
new file mode 100644
index 0000000..4f85ca0
--- /dev/null
+++ b/site/app/locale/en_US/pages/developer_agreement.thtml
@@ -0,0 +1,215 @@
+<!-- Localizer note: please don't localize this page; we don't want to get into
+ any legal ambiguities between the english version and a translation. -->
+<div id="dev-agreement" class="rounded">
+<p>
+ If you upload add-on software or otherwise make information or material
+ available (each an &#8220;<strong><abbr title="addons.mozilla.org">AMO</abbr>
+ Contribution</strong>&#8221;) by means of the services provided by Mozilla
+ Corporation (&#8220;<strong>Mozilla</strong>&#8221;) via the
+ addons.mozilla.org website or any of its subdomains (&#8220;<strong>AMO
+ Services</strong>&#8221;), you (&#8220;<strong>Contributor</strong>&#8221;)
+ and the AMO Contribution are subject to the following terms, as well as
+ Mozilla’s Privacy Policy,
+ <a href="http://www.mozilla.com/en-US/about/legal.html">web site notices</a>
+ and other policies, guidelines or requirements that may be posted on an AMO
+ Services web site (the &#8220;<strong>Terms</strong>&#8221;). By acting as a
+ Contributor, you agree to these Terms. If you are an individual acting as a
+ representative of a corporation or other legal entity that wishes to use any
+ AMO Services, you represent and agree that you accept the Terms on behalf of
+ such entity. If you have any questions about these terms or the AMO Service,
+ please email:
+ <a href="mailto:amo-editors@mozilla.org">amo-editors@mozilla.org</a>
+</p>
+<ol>
+ <li>
+ <p>
+ <strong>Responsibility Re AMO Contributions.</strong>
+ You represent and warrant that:
+ </p>
+ <ul>
+ <li>
+ if any information about the user or usage of the AMO Contribution is
+ collected or transmitted outside of the user's computer, the details of this
+ collection will be provided in the description of the AMO Contribution and
+ you will provide a link to a privacy policy detailing how the information is
+ managed and protected;
+ </li>
+ <li>
+ the descriptions and other data you provide about the AMO Contribution are
+ true to the best of your knowledge; and
+ </li>
+ <li>
+ if the AMO Contribution is an add-on, such add-on is accompanied by an
+ accessible license that describes the rights of users;
+ </li>
+ <li>
+ the AMO Contribution does not violate any applicable law, regulation or
+ ordinance, nor infringe or misappropriate the rights of any third party.
+ </li>
+ </ul>
+ </li>
+ <li>
+ <p>
+ <strong>Licenses.</strong>
+ In order to provide the AMO Service, you grant to Mozilla and its
+ Affiliates a non-exclusive, worldwide, royalty-free, sublicensable license
+ to distribute, transmit, reproduce, publish, publicly and privately
+ perform and display and otherwise use the AMO Contribution, including any
+ updates, solely in connection with Mozilla’s provision of the AMO
+ Services. Mozilla may also (i) bundle and/or package your AMO Contribution
+ with third party add-ons for delivery and promotion of the AMO
+ Contributions to users and (ii) maintain and/or update your AMO
+ Contribution for the purpose of providing compatibility with current and
+ new versions of Firefox or other Mozilla software that the AMO
+ Contribution interoperates with.
+ </p>
+ </li>
+ <li>
+ <p>
+ <strong>Management of AMO Services.</strong>
+ Mozilla may manage the AMO Services in a manner designed to facilitate the
+ integrity and proper functioning of the AMO Services without limitation or
+ liability. The following is a list of exemplary activities that Mozilla in
+ its sole discretion may undertake as part of its management of the AMO
+ Services: (i) monitor, test and review AMO Contributions; (ii) remove or
+ disable AMO Contributions or change their listing or description; (iii)
+ move an AMO Service and related AMO Contributions to a new domain or
+ website; (iv) rate limit, throttle and/or block requests or access to any
+ AMO Service; (v) use, modify or remove authentication requirements for
+ access to AMO Services; and (vi) collect statistics and other data
+ regarding your AMO Contribution, which may be made publicly available
+ through the AMO API (as described below).
+ </p>
+ </li>
+ <li>
+ <p>
+ <strong>AMO <abbr title="Application Programming Interface">API</abbr>.</strong>
+ As part of the AMO Services, Mozilla provides the addons.mozilla.org API
+ (&#8220;<strong>AMO API</strong>&#8221;), which allows you to get
+ information about certain AMO Contributions distributed by Mozilla via the
+ AMO Service and is currently served via calls to
+ https://services.addons.mozilla.org/api/.
+ You may use the AMO API solely to retrieve data made publicly available by
+ Mozilla via the AMO API, which data may be used solely for your own
+ reasonable business purposes or personal use. In addition to the
+ restrictions otherwise set forth in the Terms regarding AMO Services
+ generally, you agree that you are responsible for your use of and
+ contribution to the AMO API and you will not:
+ </p>
+ <ul>
+ <li>
+ hide or mask from Mozilla the identity of your service as it uses the
+ AMO API, including by failing to follow required identification
+ conventions; or
+ </li>
+ <li>
+ use the AMO API for any application that replicates or attempts to
+ replicate the Mozilla AMO Service or experience
+ unless your use of the AMO API is non-confusing. By non-confusing,
+ Mozilla means that people should always know with whom they are dealing
+ and where the information or software they are downloading came from.
+ Websites and software that are not produced by Mozilla shouldn’t imply,
+ either directly or by omission, that they are.
+ </li>
+ </ul>
+ </li>
+ <li>
+ <p>
+ <strong>Ownership, Reservation of Rights.</strong>
+ You are welcome to use the AMO Services subject to these Terms, and
+ Mozilla grants you the right to do so. Mozilla and its licensors reserve
+ all other rights in the AMO Services. Further, nothing in the Terms shall
+ be deemed to grant you any right to use the trademarks, trade names,
+ service marks, or trade dress of Mozilla or its licensors and Mozilla
+ hereby reserves all right, title and interest therein. For information on
+ our trademarks, please see our
+ <a href="http://www.mozilla.org/foundation/trademarks/">Trademark and Logo Usage Policies</a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ <strong>
+ The AMO Services are provided &#8220;as-is&#8221;. Mozilla, its
+ contributors, licensors, and distributors, disclaim all warranties,
+ whether express or implied, including without limitation, implied
+ warranties of merchantability, fitness for a particular purpose and
+ non-infringement. Some jurisdictions do not allow the exclusion or
+ limitation of implied warranties, so this disclaimer may not apply to
+ you.
+ </strong>
+ </p>
+ </li>
+ <li>
+ <p>
+ <strong>
+ Except as required by law, Mozilla, its contributors, licensors, and
+ distributors will not be liable for any indirect, special, incidental,
+ consequential, punitive, or exemplary damages arising out of or in any way
+ relating to the use of AMO Services and their collective liability
+ under these Terms will not exceed $500 (five hundred dollars). Some
+ jurisdictions do not allow the exclusion or limitation of certain damages,
+ so this exclusion and limitation may not apply to you.
+ </strong>
+ </p>
+ </li>
+ <li>
+ <p>
+ <strong>Changes to the Terms.</strong>
+ Mozilla may update these Terms as necessary from time to time. These Terms
+ may not be modified or cancelled without Mozilla’s written agreement.
+ </p>
+ </li>
+ <li>
+ <p>
+ <strong>Eligibility.</strong>
+ You represent that you are of legal age to form a binding contract and
+ that you not are a person barred from receiving or using the AMO Services
+ under the laws of any country, including the country in which you are
+ resident or from which you use the AMO Services.
+ </p>
+ </li>
+ <li>
+ <p>
+ <strong>Export Control.</strong>
+ The AMO Services are subject to all applicable export restrictions
+ including the export and import laws, restrictions and regulations of any
+ United States or foreign agency.
+ </p>
+ </li>
+ <li>
+ <p>
+ <strong>Miscellaneous.</strong>
+ These Terms are governed by the laws of the state of California, U.S.A.,
+ excluding its conflict of law provisions. If any portion of these Terms is
+ held to be invalid or unenforceable, the remaining portions will remain in
+ full force and effect. In the event of a conflict between a translated
+ version of these Terms and the English language version, the English
+ language version shall control. Mozilla’s subsidiaries and affiliates
+ shall be third party beneficiaries of these Terms, entitled to enforce and
+ rely upon the provisions hereof.
+ </p>
+ </li>
+ <li>
+ <p>
+ <strong>Termination.</strong>
+ You may terminate your use of the AMO Services at any time. Mozilla may
+ modify or discontinue the AMO Services at its sole discretion.
+ </p>
+ </li>
+</ol>
+</div>
+<p id="license-disclosure">
+ <strong>
+ DEVELOPER LICENSE DISCLOSURE STATEMENT FOR ADD-ON UPLOAD/REGISTRATION PAGE:
+ </strong>
+ <br/>
+ For both your benefit and the benefit of users that download your add-on,
+ Mozilla requests that you identify the license terms applicable to use of your
+ add-on by users. Unless you specify otherwise, any updates to your add-on will
+ be assumed to be under the same license as that specified for your add-on.
+ Please select the applicable license terms from the list below or, if your
+ license terms are not listed, select &#8220;Other&#8221; and identify the
+ license terms in the dialog box provided. Please note that you must include an
+ accessible copy of your license terms with your add-on (such as in a parent
+ directory). <br /> <a href="%1$s">Learn more about open source licenses</a>
+</p>
diff --git a/site/app/locale/en_US/pages/developer_faq.thtml b/site/app/locale/en_US/pages/developer_faq.thtml
new file mode 100644
index 0000000..1d443e0
--- /dev/null
+++ b/site/app/locale/en_US/pages/developer_faq.thtml
@@ -0,0 +1,275 @@
+<h1>Add-on Developer FAQ</h1>
+
+<h2>Developing an Add-on</h2>
+<dl>
+<dt>How do I build an Add-on?</dt>
+<dd>
+<p>Mozilla provides documentation on how to build an add-on via the Mozilla Developer Center. The tutorial, <a href="https://developer.mozilla.org/En/Building_an_Extension">Building an Extension</a>, will help explain how to setup your work environment and move forward with creating an add-on.</p>
+<p>Other resources include:</p>
+<ul>
+<li><a href="https://developer.mozilla.org/En/Firefox_addons_dev_guide">Firefox Add-ons Developer Guide</a></li>
+<li><a href="http://blog.mozilla.com/addons/2009/01/28/how-to-develop-a-firefox-extension/">Robert Nyman's article "How to develop a Firefox extension"</a></li>
+<li><a href="http://blog.mozilla.com/addons/2009/03/18/video-tutorial-extensions-bootcamp-zero-to-hello-world-in-45-minutes/">Myk Melez's video tutorial "Video Tutorial - Extensions Bootcamp: Zero to “Hello World†in 45 Minutes"</a></li>
+</ul>
+</dd>
+
+<dt>What tools do I need to be able to build an Add-on?</dt>
+<dd>
+<p>You will need to have a version the Mozilla software that you're building the add-on for and a code editor of your choice. Add-ons can be built for almost all Mozilla software but are primarily targeted for:</p>
+<ul>
+<li><a href="http://www.mozilla.com/en-US/firefox/">Firefox</a></li>
+<li><a href="http://www.mozillamessaging.com/en-US/thunderbird/">Thunderbird</a></li>
+<li><a href="http://www.seamonkey-project.org/">SeaMonkey</a></li>
+<li><a href="http://www.mozilla.org/projects/calendar/sunbird/">SunBird</a></li>
+</ul>
+<p>Popular code editors include:</p>
+<ul>
+<li><a href="http://www.activestate.com/komodo_edit/">Komodo Edit</a></li>
+<li><a href="http://macromates.com/">TextMate</a></li>
+<li><a href="http://notepad-plus.sourceforge.net/uk/site.htm">Notepad++</a></li>
+<li><a href="http://www.eclipse.org/">Eclipse IDE</a></li>
+</ul>
+<p>You can also learn more about setting up your development environment via the MDC article <a href="https://developer.mozilla.org/en/Setting_up_extension_development_environment">Setting up extension development environment</a></p>
+</dd>
+
+<dt>Where can I find documentation on building add-ons?</dt>
+<dd>All Mozilla documentation on add-on development including tutorials and APIs can be found via the <a href="https://developer.mozilla.org/En">Mozilla Developer Center</a>.</dd>
+
+<dt>What is a ".xpi" file?</dt>
+<dd>Extensions are packaged and distributed in ZIP files or Bundles, with the XPI (pronounced “zippyâ€) file extension.</dd>
+
+<dt>What is XUL?</dt>
+<dd>XUL (XML User Interface Language) is Mozilla's XML-based language that lets you build feature-rich cross platform applications. It provides user interface widgets like buttons, menus, toolbars, trees, etc that can be used to enhance add-ons by modifying parts of the browser UI.</dd>
+
+<dt>What is the "install.rdf" file used for?</dt>
+<dd>This file, called an <a href="https://developer.mozilla.org/en/Install_Manifests">Install Manifest</a>, is used by Add-on Manager-enabled XUL applications to determine information about an add-on as it is being installed. It contains metadata identifying the add-on, providing information about who created it, where more information can be found about it, which versions of what applications it is compatible with, how it should be updated, and so on. The format of the Install Manifest is RDF/XML.</dd>
+
+<dt>What does "maxVersion" mean?</dt>
+<dd>This determines the maximum version of Firefox you're saying this extension will work with. Set this to be no newer than the newest currently available version!</dd>
+
+<dt>Can my add-on contain binary components?</dt>
+<dd>Yes. You can use Mozilla's <a href="https://developer.mozilla.org/en/XPCOM">XPCOM component object model</a> to enhance your add-ons. XPCOM components be used and implemented in JavaScript, Java, and Python in addition to C++.</dd>
+
+<dt>Can I use a JavaScript library like jQuery, MooTools or Prototype to build my add-on?</dt>
+<dd>Yes. It's possible, but some of the functionality provided by these libraries are available through XPCOM, XUL, and JS 1.8. In addition, authors should take care if libraries modify primitive object prototypes (String.prototype, Date.prototype, etc.) and/or define global functions (eg. the $ function). These are prone to cause conflict with other add-ons, in particular if different add-ons use different versions of libraries and so on. Developers need to be very, very careful with using them. Mozilla does not offer documentation on using them to build add-ons.</dd>
+
+<dt>How do I test my add-on?</dt>
+<dd>Details on testing your add-on are provided in the <a href="https://developer.mozilla.org/en/Building_an_Extension#Test">Testing</a> &amp; <a href="https://developer.mozilla.org/en/Building_an_Extension#Debugging_Extensions">Debugging Extensions</a> sections of the <a href="https://developer.mozilla.org/en/Building_an_Extension">Building an Extension tutorial</a>.</dd>
+
+<dt>How do I test for compatibility with the latest version of Mozilla software?</dt>
+<dd>To ensure compatibility with the latest Mozilla software, it's important to download updates as they become available and test your add-on to ensure that it is still functioning as expected. It's best to follow the steps outlined in the <a href="https://developer.mozilla.org/en/Building_an_Extension">Building an Extension</a> tutorial for <a href="https://developer.mozilla.org/en/Building_an_Extension#Test">testing your add-on</a>. In many cases, the latest version of Mozilla software may be a beta release. Since these releases at times introduce architectural changes that may impact the functionality of your add-on, it's important to be actively involved in the beta process to ensure that you're add-on users are not negatively impacted upon final release of Mozilla software.</dd>
+
+<dt>What is leak testing?</dt>
+<dd>Memory leaks are typically bugs in the source code used to build applications which consume system memory without properly releasing it once the application has finished. Leak testing allows you to pinpoint which bit of code is causing the memory leak. The following is a good <a href="https://wiki.mozilla.org/Performance:Leak_Tools">guide to finding tools and strategies</a> that help manage leak testing. Mozilla's Carsten Book has also written an excellent HOW-TO article on the subject of <a href="https://wiki.mozilla.org/QA:Home_Page:Firefox_3.0_TestPlan:Leaks:LeakTesting-How-To">leak testing in Firefox</a>.</dd>
+
+<dt>Can my add-on support multiple locales?</dt>
+<dd>Yes. Details on localizing your add-on can be found in the <a href="https://developer.mozilla.org/en/Building_an_Extension#Localization">Building an Extension</a> tutorial as well as the <a href="https://developer.mozilla.org/en/Localization">Mozilla Developer Center Localization page</a>. <a href="http://www.babelzilla.org/">The BabelZilla project</a> is also a great resource for learning about localization and volunteering to help translate add-ons.</dd>
+</dl>
+
+<h2>Support Resources</h2>
+<dl>
+<dt>I need some advice building my add-on. Where can I find help?</dt>
+<dd><p>Mozilla offers the following support options for add-on developers:</p>
+<ul>
+<li>irc://irc.mozilla.org/
+ <ul>
+ <li>#extdev (for add-on development discussions)</li>
+ <li>#amo (for support relating to hosting your add-on on AMO)</li>
+ </ul>
+</li>
+<li><a href="https://lists.mozilla.org/listinfo/dev-extensions">Mailing List</a></li>
+<li><a href="news://news.mozilla.org/mozilla.dev.extensions">Newsgroup</a></li>
+<li><a href="http://groups.google.com/group/mozilla.dev.extensions">Google Group</a></li>
+</ul>
+</dd>
+
+<dt>Does Mozilla offer development services?</dt>
+<dd>No.</dd>
+
+<dt>Are there 3rd party developers that I can hire to build my add-on?</dt>
+<dd>Yes. You may find 3rd party developers via the <a href="http://www.mozilla.org/community/developer-forums.html#projectwide-forums">mozilla.jobs list</a>, <a href="http://forums.mozillazine.org/">mozillaZine forums</a> or <a href="http://consultants.mozdev.org/">MozDev</a>. Please note that Mozilla does not offer developer recommendations.</dd>
+</dl>
+
+<h2>Contributing your Addon</h2>
+<dl>
+<dt>Can I host my own add-on?</dt>
+<dd>Yes. Many developers choose to host their own add-ons. Choosing to host your add-on on Mozilla's AMO (<a href="https://addons.mozilla.org">https://addons.mozilla.org</a>), though, allows for much greater exposure to your add-on due to the large volume of visitors to the site. The <a href="http://mozdev.org/">mozdev.org</a> site offers free project hosting for Mozilla applications and extensions providing developers with tools to help manage source code, version control, bug tracking and documentation.</dd>
+
+<dt>Can Mozilla host my add-on?</dt>
+<dd>Yes. You can host your add-on on Mozilla's AMO (<a href="https://addons.mozilla.org">https://addons.mozilla.org</a>) website.</dd>
+
+<dt>What is AMO?</dt>
+<dd>Mozilla's AMO (<a href="https://addons.mozilla.org">https://addons.mozilla.org</a>) is the incubator that helps developers build, distribute, and support fantastic consumer products powered by Mozilla. It provides you the tools and infrastructure necessary to manage, host and expose your add-on to a massive base of Mozilla users.</dd>
+
+<dt>Does Mozilla keep my account information private?</dt>
+<dd>Yes. Our <a href="https://addons.mozilla.org/en-US/firefox/pages/privacy">Privacy Policy</a> describes how your information is managed by Mozilla.</dd>
+
+<dt>What are the "developer tools" listed on AMO?</dt>
+<dd>The "Developer Tools" dashboard is the area that provides you the tools to successfully manage your add-ons. It provides the functionality necessary to submit your add-ons to AMO, manage add-on information, and review statistics.</dd>
+
+<dt>Does Mozilla have a policy in place as to what is an acceptable submission?</dt>
+<dd>Yes. Mozilla's <a href="https://addons.mozilla.org/en-US/firefox/pages/policy">Add-on Policy</a> describes what is an acceptable submission. This policy is subject to change without notice. In addition, the AMO editorial team uses the <a href="https://wiki.mozilla.org/AMO:Editors/ReviewingGuide">Editors Reviewing Guide</a> to ensure that your add-on meets specific guidelines for functionality and security.</dd>
+
+<dt>How do I submit my add-on for review?</dt>
+<dd>The Developer Tools dashboard will allow you to upload and submit add-ons to AMO. You must be a registered AMO users before you can submit an add-on. Before submitting your add-on be sure to you have read the AMO <a href="https://wiki.mozilla.org/AMO:Editors/ReviewingGuide">Editors Reviewing Guide</a> to ensure that your add-on has met the guidelines used by editors to review add-ons.</dd>
+
+<dt>What operating system do I choose for my add-on?</dt>
+<dd>You must choose the operating systems on which your add-on will successfully function.</dd>
+
+<dt>What category do I choose for my add-on?</dt>
+<dd>The choice of category is dependent on what type of audience you are targeting and the functionality of your add-on. If you're unsure of which category your add-on falls into, please choose "Other". The AMO team may re-categorize your add-on if it's determined that it's better suited in a different category.</dd>
+
+<dt>What does "nominating" my add-on mean?</dt>
+<dd>Nominated add-ons are new add-ons that the author has nominated to become public via the Developer Tools.</dd>
+
+<dt>Can I specify a license agreement for using my add-on?</dt>
+<dd>Yes. You can specify a license agreement when submitting your add-on. You can also add or update a license agreement via the Developer Tools dashboard after your add-on has been submitted.</dd>
+
+<dt>Can I include a privacy policy for my add-on?</dt>
+<dd>Yes. You can specify a privacy policy when submitting your add-on. You can also add or update a privacy policy via the Developer Tools dashboard after your add-on has been submitted.</dd>
+</dl>
+
+<h2>Add-on Review Process</h2>
+<dl>
+<dt>Why must my add-on be reviewed?</dt>
+<dd>All add-ons submitted, whether new or updated, are reviewed to ensure that Mozilla users have a stable and safe experience. All add-ons submissions are reviewed using the guidelines outlined in the <a href="https://wiki.mozilla.org/AMO:Editors/ReviewingGuide">Editors Reviewing Guide</a>.</dd>
+
+<dt>Who reviews my add-on?</dt>
+<dd>Add-ons are reviewed by the AMO Editors, a group of talented developers that volunteer to help the Mozilla project by reviewing add-ons to ensure a stable and safe experience for Mozilla users. When communicating with editors, please be courteous, patient and respectful as they are working hard to ensure that you're add-on is setup correctly and follows the guidelines outlined in the <a href="https://wiki.mozilla.org/AMO:Editors/ReviewingGuide">Editors Reviewing Guide</a>.</dd>
+
+<dt>What is the sandbox?</dt>
+<dd>A complete explanation of the <a href="https://addons.mozilla.org/en-US/firefox/pages/sandbox">AMO Sandbox</a> can be found <a href="https://addons.mozilla.org/en-US/firefox/pages/sandbox">here</a>.</dd>
+
+<dt>Why is my add-on marked as "experimental"?</dt>
+<dd>Newly submitted and nominated add-ons are listed as "experimental" until they have been properly reviewed by a member of the editorial team. This ensures that users are aware of the add-on's status before choosing to install an add-on that has not been fully reviewed.</dd>
+
+<dt>What are the guidelines used to review my add-on?</dt>
+<dd>The Mozilla editorial team follows the <a href="https://wiki.mozilla.org/AMO:Editors/ReviewingGuide">Editors Reviewing Guide</a> when testing an add-on for acceptance onto AMO. It is important that add-on developers review this guide to ensure that common problem areas are addressed prior to submitting their add-on for review. This will greatly assist in expediting the review process.</dd>
+
+<dt>How long will it take for my add-on to be reviewed?</dt>
+<dd><p>We cannot give a time estimate as to how long it will take before an add-on is reviewed. Many factors affect the time including the:</p>
+<ul>
+<li>number of add-on submissions</li>
+<li>complexity of an add-on's code</li>
+<li>number of problem areas discovered</li>
+</ul>
+<p>This is why it's very important to read the <a href="https://wiki.mozilla.org/AMO:Editors/ReviewingGuide">Editors Reviewing Guide</a> to ensure that your add-on is setup as expected. It's also a good idea to read the blog post, <a href="http://blog.mozilla.com/addons/2009/01/14/successfully-getting-your-addon-reviewed/">Successfully Getting your Addon Reviewed</a> which provides excellent insight into ensuring a smooth review of your add-on.</p></dd>
+</dl>
+
+<h2>Managing Your Add-on</h2>
+<dl>
+<dt>How can I see how many times my add-on has been downloaded?</dt>
+<dd>The Statistics Dashboard found in the Developer Tools dashboard provides information that can help you determine your add-on downloads since you've submitted it to AMO.</dd>
+
+<dt>How can I see how many active users are using my add-on?</dt>
+<dd>The Statistics Dashboard found in the Developer Tools dashboard provides information that can help you determine how many users have been actively using your add-on since you've submitted it to AMO.</dd>
+
+<dt>How do I submit an update for my add-on?</dt>
+<dd>You can submit an update for your add-on via the Developer Tools dashboard by choosing the option "Upload a new version" and uploading a new .xpi file for your add-on.</dd>
+
+<dt>Does my update need to be reviewed by editors?</dt>
+<dd>That depends. If you are simply changing a description of your add-on or updating a "maxVersion" to ensure compatibility with a new Mozilla software update, then your add-on does not need to be reviewed again. If, however, you submit a new updated file, then your add-on update will need to be reviewed by an editor.</dd>
+</dl>
+
+<h2>Recommended Status</h2>
+<dl>
+<dt>What are the Recommended Lists?</dt>
+<dd>The Recommended lists are an important part of exposing AMO visitors to useful and compelling add-ons within a small &amp; focused list. It allows us to feature add-ons that have done a good job of creating a unique and/or exciting enhancement to Mozilla software and increasing awareness of the thousands of add-ons hosted on AMO. The lists are broken down into two categories; Recommended and Category Recommended. The former is shown on the home page of AMO and is typically limited to 40 featured add-ons. The latter are lists of add-ons that are recommended at the category level. The only distinction between the two lists is that Category Recommended add-ons are not featured on the home page. Apart from that, both lists are meant to recognize the achievements of individual add-on authors and the work they’ve produced.</dd>
+
+<dt>What is a Featured add-on?</dt>
+<dd>The main page of AMO as well as the main page for each category contain three slots which are used to display a set of Featured Add-Ons. These add-ons are pulled from the Recommended and Category Recommended lists respectively and periodically rotated as described in the <a href="https://wiki.mozilla.org/AMO:Editors/Featured_and_Recommended#Featured_Add-Ons">Featured Add-ons FAQ</a> to allow recommended add-ons a chance for increased visibility to users. Featured add-ons are rotated regularly to prevent staleness.</dd>
+
+<dt>How can my add-on be listed as Recommended?</dt>
+<dd>The <a href="http://blog.mozilla.com/addons/2009/03/10/the-hows-whys-of-the-amo-recommended-rotation/">following blog post</a> describes the process by which the Recommended lists are managed.</dd>
+
+<dt>Can I pay to have my add-on listed as Recommended?</dt>
+<dd>No.</dd>
+
+<dt>Why is my add-on no longer listed as Recommended?</dt>
+<dd>The <a href="http://blog.mozilla.com/addons/2009/03/10/the-hows-whys-of-the-amo-recommended-rotation/">following blog post</a> describes the process by which the Recommended lists are managed.</dd>
+</dl>
+
+<h2>User Reviews</h2>
+<dl>
+<dt>How do I reply to a user who has posted a negative review of my add-on?</dt>
+<dd><p>A developer may reply to any review posted to their add-on as long as they are logged into AMO. In addition, any user can flag a review as:</p>
+<ul>
+<li>Spam or otherwise non-review content</li>
+<li>Inappropriate language/dialog</li>
+<li>Misplaced bug report or support request</li>
+<li>Other (provides a pop-up prompt for information)</li>
+</ul>
+
+<p>Currently, AMO does not provide a mechanism to directly communicate with a reviewer but this feature is being investigated and considered for a future update.</p>
+</dd>
+
+<dt>Can I request that a review be removed if the review is negative?</dt>
+<dd>No. We do not remove negative reviews from add-ons unless they are found to be false.</dd>
+
+<dt>Can I request that a review be removed if the review is inaccurate?</dt>
+<dd>If an author contacts us and asks for a review containing false or inaccurate information to be removed, we will review the post and consider removing it.</dd>
+</dl>
+
+<h2>References for Open Source Licenses</h2>
+<p>
+ Do you need more information about the various open source licenses? Are you
+ confused as to which license you should select? What rights does a specific
+ license grant? While nothing replaces reading the full terms of a license,
+ below are some sites that contain information about some of the key open
+ source licenses that may help you sort out the differences between them. These
+ sites are being provided solely for your convenience and as a reference for
+ your personal use. These resources do not constitute legal advice nor should
+ they be used in lieu of such advice. Mozilla neither guarantees nor is
+ responsible for the content of these sites or your reliance on such content.
+</p>
+<dl>
+ <dt>
+ <a href="http://www.mozilla.org/MPL/">http://www.mozilla.org/MPL/</a>
+ </dt>
+ <dd>
+ In addition to the full text of the Mozilla Public License
+ (&#8220;MPL&#8221;), this also provides an annotated version of the MPL and an
+ <abbr title="Frequently Asked Questions">FAQ</abbr> to help you if you want
+ to use or distribute code licensed under it.
+ </dd>
+ <dt>
+ <a href="http://developer.kde.org/documentation/licensing/licenses_summary.html">
+ http://developer.kde.org/documentation/licensing/licenses_summary.html
+ </a>
+ </dt>
+ <dd>
+ A table summarizing and comparing how some of the key open source licenses
+ treat distributions, proprietary software linking, and redistribution of
+ code with changes.
+ </dd>
+ <dt>
+ <a href="http://www.fsf.org/licensing/licenses/">
+ http://www.fsf.org/licensing/licenses/
+ </a>
+ </dt>
+ <dd>
+ Free Software Foundation provides short summaries of the key open source
+ licenses, including whether the license qualifies as a free software license
+ or a copyleft license. Also includes a discussion of what constitutes a
+ free software license or a copyleft license (e.g., a Copyleft license is a
+ general method for making a program or other work free, and requiring all
+ modified and extended versions of the program to be free as well.)
+ </dd>
+ <dt>
+ <a href="http://www.opensource.org/licenses/category">
+ http://www.opensource.org/licenses/category
+ </a>
+ </dt>
+ <dd>
+ Open Source Initiative provides the terms of some of the key open source
+ licenses.
+ </dd>
+ <dt>
+ <a href="http://en.wikipedia.org/wiki/Open_source_license">
+ http://en.wikipedia.org/wiki/Open_source_license
+ </a>
+ </dt>
+ <dd>
+ Wikipedia discussion of BSD style licenses.
+ </dd>
+</dl>
diff --git a/site/app/locale/en_US/pages/error404.thtml b/site/app/locale/en_US/pages/error404.thtml
new file mode 100644
index 0000000..cd3c287
--- /dev/null
+++ b/site/app/locale/en_US/pages/error404.thtml
@@ -0,0 +1,16 @@
+<h1>We’re sorry, but we can’t find what you’re looking for.</h1>
+
+<p>The page or file you requested wasn't found on our site. It's possible that you clicked a link that's out of date, or typed in the address incorrectly.</p>
+
+<ul>
+<li>If you typed in the address, please double check the spelling.</li>
+<li>If you followed a link from somewhere, please let us know at <a href="mailto:webmaster@mozilla.com" title="Page Not Found on Mozilla.com">webmaster@mozilla.com</a>. Tell us where you came from and what you were looking for, and we'll do our best to fix it.</li>
+</ul>
+
+<p>Or you can just jump over to some of the popular pages on our website.</p>
+
+<ul>
+<li>Are you interested in a <a href="%1$s">list of recommended add-ons</a>?</li>
+<li>Do you want to <a href="%2$s">search for add-ons</a>? You may go to the <a href="%2$s">search page</a> or just use the search field above.</li>
+<li>If you prefer to start over, just go to the <a href="%3$s">add-ons front page</a>.</li>
+</ul>
diff --git a/site/app/locale/en_US/pages/faq.thtml b/site/app/locale/en_US/pages/faq.thtml
new file mode 100755
index 0000000..7dd294d
--- /dev/null
+++ b/site/app/locale/en_US/pages/faq.thtml
@@ -0,0 +1,78 @@
+<h1>Frequently Asked Questions</h1>
+
+<p>This FAQ for the <a href="http://addons.mozilla.org">AMO site</a> addresses some topics not currently covered by the Firefox Support website. The Support website includes introductory information about <a href="http://support.mozilla.com/kb/Customizing+Firefox+with+add-ons">customizing Firefox with add-ons</a> as well as articles on:</p>
+
+<ul>
+ <li> Troubleshooting <a href="http://support.mozilla.com/kb/Unable+to+install+add-ons">add-on installation</a>, <a href="http://support.mozilla.com/kb/Troubleshooting+plugins">plugins</a> &amp; <a href="http://support.mozilla.com/kb/Troubleshooting+extensions+and+themes">general issues</a>.</li>
+ <li> <a href="http://support.mozilla.com/kb/Uninstalling+add-ons">How to uninstall add-ons</a> and <a href="http://support.mozilla.com/kb/Cannot+uninstall+an+add-on">troubleshooting uninstallation</a>.</li>
+ <li> <a href="http://support.mozilla.com/kb/Gray+bar+below+the+status+bar">Dealing with problematic add-ons / Gray Bar issue</a></li>
+</ul>
+
+<p></p>
+
+<div id="gsfn_list_widget">
+ <a href="https://getsatisfaction.com/mozilla" class="widget_title">Active customer service discussions about Mozilla Add-ons</a>
+ <div id="gsfn_content">Loading...</div>
+ <div class="powered_by">
+ <a href="https://getsatisfaction.com/"><img alt="Favicon" src="https://www.getsatisfaction.com/favicon.gif" style="vertical-align: middle;" /></a>
+ <a href="https://getsatisfaction.com/">Get Satisfaction support network</a>
+ </div>
+</div>
+
+<h2>Add-on Questions</h2>
+<dl class="faq">
+<dt>What is an Add-on?</dt>
+<dd>Add-ons let you add features which aren't part of the standard application. Themes change appearance without changing functionality. Search Plugins and Dictionaries/Language Packs add additional search engines and language support. Extensions add more extensive features to the browser; some add simple toolbars while others can add a wide range of new features.</dd>
+
+<dt>Are add-ons easy to install?</dt>
+<dd>Yes! Add-ons are very easy to install. They're generally much smaller than a normal application and download very quickly. If you don't like one, they are just as easy to remove or disable. Also, if an update is available for one of your add-ons, Firefox will inform you and let you upgrade with one click.</dd>
+
+<dt>How do I manage an add-on?</dt>
+<dd>In Firefox, go to "Add-ons" in the Tools menu to manage Themes and Extensions. If your Extension has special options, you can see them in the Extensions section of the Add-ons window. From here, you can also disable and uninstall add-ons. Dictionaries are installed as Extensions. Search Plugins can be managed in the Search Bar.</dd>
+
+<dt>Can add-ons make Firefox slower?</dt>
+<dd>In most cases, add-ons do not cause a perceivable slowdown in Firefox. However, since they are applications some may affect the performance of Firefox depending on your system configuration. If you suspect that an add-on is affecting the way Firefox runs on your machine try disabling it.</dd>
+
+<dt>Why would I disable an add-on?</dt>
+<dd>Disabling an add-on prevents it from loading when you start Firefox, but it doesn't remove the add-on or any of its settings. Enabling the add-on again will bring it back to where it was when you disabled it. For add-ons that you want to turn off without removing, disabling is the way to go.</dd>
+
+<dt>How do I backup all of the add-ons and themes that I've installed?</dt>
+<dd>You can backup your profile directory which will also backup your add-ons and themes. A third party application like MozBackup can help you with this.</dd>
+</dl>
+
+<h2>Website questions</h2>
+<dl class="faq">
+<dt>I see several add-ons which provide the same capabilities. How do I decide which one is best?</dt>
+<dd>In general, you can look at ratings and downloads which will give you an idea. Good add-ons tend to be downloaded more than bad ones. However, it's also easy to install both add-ons and decide which one you want to use. You may decide after trying them that you want to use both!</dd>
+
+<dt>I see a great add-on but it says that it's only compatible with Firefox 2.x. Can I still install it in Firefox 3.x?</dt>
+<dd>In general, no. Firefox 3.x has a number of new features and a large majority of add-on developers have updated their add-ons to support 3.x. If the add-on only supports Firefox 2, try searching for that add-on's title. In many cases there will be a new version that supports Firefox 3 with the same or similar title.</dd>
+
+<dt>I installed a new theme but would like to revert back to the Firefox default theme. How do I do that?</dt>
+<dd>Go to "Add-ons" in the "Tools" menu. Click the "Themes" section and from here you can select the default theme, or any others you have installed.</dd>
+
+<dt>If I have an issue with an add-on, should I contact Mozilla?</dt>
+<dd>Add-ons, with a few exceptions, are created by the community and not Mozilla. The best thing to do is to contact the developer directly with your question. To find contact info for a developer, click their name in the by line on the Add-on listing page.</dd>
+
+<dt>How are add-ons reviewed?</dt>
+<dd>Public add-ons are reviewed by our dedicated and talented editorial team. They review the code of all public add-ons and also test the add-ons to make sure that they are accurately described.</dd>
+
+<dt>I've upgraded to Firefox 3.5 but my add-on no longer works? Why is that?</dt>
+<dd>Most of our add-ons are now Firefox 3.5 compatible, and every day more are added. If your add-on worked on 3.0 but not 3.5, chances are they're already working on it. When they do upgrade their add-on, Firefox will notify you about the upgrade.</dd>
+
+<dt id="experimental-addons">What are experimental add-ons?</dt>
+<dd>
+ <p>Experimental add-ons are newer add-ons which have not yet undergone our public review process. Many of these add-ons may be in prototype form. Since they are untested by our editorial team, they may be alpha, beta or pre-production in quality, performance and features.</p>
+ <p>Caution should be used when installing experimental add-ons, as they have not been tested by an editor and may harm your computer configuration.</p>
+</dd>
+
+<dt id="recognizing-experimental-addons">How do I know an experimental add-on when I see one on the site?</dt>
+<dd>Experimental add-ons are marked with an "experimental" label and show a warning when you install them.</dd>
+
+<dt id="recommended-addons">What are Recommended and Featured add-ons?</dt>
+<dd>The AMO team recommends a set of add-ons which represent some of the best add-ons in terms of utility and overall experience. These Recommended add-ons appear on the individual category pages. Some of these add-ons are also rotated onto the front page of AMO as Featured add-ons. This is by no means a comprehensive list, and we update the list monthly to continue to show our users a fresh set of add-ons. Some things we consider when we recommend add-ons: quality, popularity, uniqueness, and whether or not the add-on has already been recommended.</dd>
+
+</dl>
+
+<script src="https://getsatisfaction.com/mozilla/widgets/javascripts/500b6b4141/widgets.js" type="text/javascript"></script>
+<script src="https://getsatisfaction.com/mozilla/topics.widget?callback=gsfnTopicsCallback&amp;limit=5&amp;product=mozilla_mozilla_add_ons&amp;sort=last_active_at&amp;style=topics" type="text/javascript"></script>
diff --git a/site/app/locale/en_US/pages/fashion_faq.thtml b/site/app/locale/en_US/pages/fashion_faq.thtml
new file mode 100644
index 0000000..b4e5a4e
--- /dev/null
+++ b/site/app/locale/en_US/pages/fashion_faq.thtml
@@ -0,0 +1,56 @@
+<h3>Frequently Asked Questions</h3>
+</div><!-- END branding -->
+
+<div id="content-main" class="faq">
+
+<dl>
+<dt>What is Fashion Your Firefox?</dt>
+<dd>Firefox offers you the most ways to customize your online experience, allowing you tailor your browser specifically for the way you use the Web. Fashion Your Firefox is a simple Web application that customizes your Firefox browser based on your interests and online activities. Fashion Your Firefox helps you select add-ons that fit your needs, and enables you to install them with just one click.</dd>
+
+<dt>What's an add-on?</dt>
+<dd>Firefox add-ons are little pieces of software that add new features or functionality to your browser. Add-ons extend Firefox, letting you tailor your browser to meet your needs and tastes. There are more than 5,000 add-ons just waiting out there to help you do more, have more fun and be more creative online. </dd>
+
+<dt>What does it mean to "Fashion Your Firefox"?</dt>
+<dd>Fashion Your Firefox refers to the application’s ability to customize, tailor, and "fashion†your Firefox to best suit your daily activities online.</dd>
+
+<dt>Does Fashion Your Firefox work with all versions of Firefox?</dt>
+<dd>At this time, Fashion Your Firefox is only compatible with Firefox 3. </dd>
+
+<dt>How do I add multiple add-ons to my Fashion Your Firefox collection?</dt>
+<dd>Fashion Your Firefox will guide you through this easy process – there is no having to look for add-ons that suit your needs. Simply select add-ons in categories that are interesting, click the "I want this add-on!†button, and select the adjacent "Click here to install them†link. You’ll then be prompted to confirm your choices and your browser will restart with the selections added to your Firefox without having to add them individually. Voila – welcome to your personalized browser.</dd>
+
+<dt>Will the add-ons offered in Fashion Your Firefox ever change?</dt>
+<dd>Fashion Your Firefox is the first collection of add-ons in a set of many collections that will be available during the year.</dd>
+
+<dt>How did you choose the add-ons for Fashion Your Firefox?</dt>
+
+<dd>The included add-ons were required to meet the following criteria:
+<ul>
+<li>Offer a well-rounded set of functionality</li>
+<li>Easy to use</li>
+<li>Popular within their category</li>
+<li>Firefox 3 and Mac/PC compatible</li>
+</ul>
+</dd>
+
+<dt>I can't seem to find my add-on after I downloaded "Fashion Your Firefox.†Where is it?</dt>
+<dd>Each add-on may appear in different places in your Firefox browser. Some appear as toolbars or buttons at the top of your browser, some appear as icons in the lower part of the browser and some are accessible from the "Tools†menu in Firefox. If you still are having trouble finding a Fashion Your Firefox add-on you selected, try doing a quick search on addons.mozilla.org for additional information on where to find it in the browser.</dd>
+
+<dt>Is it possible to install more than one theme from the "Decorator†category?</dt>
+<dd>It’s possible to install more than one, but only one theme will show up at a time. To easily switch themes, go to the "Tools†menu in Firefox and select "Add-ons†to display the Add-ons manager. Click on the "Themes†menu at the top, click on the theme you’d like to display, and click on the "Use Theme†button.</dd>
+
+<dt>How do I uninstall an add-on from my collection?</dt>
+<dd>To uninstall an add-on or theme, go to the "Tools†menu in Firefox and select "Add-ons†to display the Add-ons manager. Click the the add-on or theme you’d like to uninstall and select "Uninstall.†Once you restart your browser, the unwanted theme or add-on will be uninstalled.</dd>
+
+<dt>What languages does Fashion Your Firefox support?</dt>
+<dd>Currently, Fashion Your Firefox is only in English, though other languages are in the works. </dd>
+
+<dt>Is there an easy way to share the collection of Fashion Your Firefox add-ons with friends?</dt>
+
+<dd>Right now there is no way to share your Fashion Your Firefox add-ons with friends, but this may be available at a later time.</dd>
+
+<dt>How can I get support for any other Fashion Your Firefox issues I’m having?</dt>
+<dd>You can refer to Mozilla’s support site, <a href="http://support.mozilla.com/">support.mozilla.com</a>, for general support. For add-on specific support, please visit <a href="http://addons.mozilla.org/">addons.mozilla.org</a>.</dd>
+
+</dl>
+</div>
diff --git a/site/app/locale/en_US/pages/nomination.thtml b/site/app/locale/en_US/pages/nomination.thtml
new file mode 100644
index 0000000..9511c6f
--- /dev/null
+++ b/site/app/locale/en_US/pages/nomination.thtml
@@ -0,0 +1,10 @@
+<p>An add-on currently in the sandbox may be nominated to be a part of the public site and available to all users after undergoing review by an editor. For best results, please note the following:</p>
+<ul>
+ <li>Preview images are required for themes and highly recommended for all other add-on types.</li>
+ <li>The add-on should have spent enough time in the sandbox to accumulate reviews and feedback from users. <b>Reviews are required to become public.</b></li>
+ <li>Public add-ons have a higher quality bar than sandbox add-ons and should enhance the web.</li>
+ <li>Full nomination criteria is available in the <a href="%s">Add-on Policy</a>.</li>
+</ul>
+<p>If your add-on meets the above criteria, you can nominate it by completing the field below. You will be notified via e-mail about the status of your nomination.</p>
+
+<p>To nominate your add-on, please describe how it has been tested (including that it is free of errors and warnings) and how it is useful to the wider web. You may also include links to external reviews of your add-on.</p>
diff --git a/site/app/locale/en_US/pages/policy.thtml b/site/app/locale/en_US/pages/policy.thtml
new file mode 100644
index 0000000..aeceb48
--- /dev/null
+++ b/site/app/locale/en_US/pages/policy.thtml
@@ -0,0 +1,112 @@
+<h1>Add-ons Policy</h1>
+
+<h2>What is the sandbox?</h2>
+<p>See the %s.</p>
+
+<h2>What add-ons are in the sandbox?</h2>
+<p>The sandbox is where all add-ons that are hosted on AMO go, to start. It contains new versions of public add-ons, as well as all versions for add-ons that are not made public. When a new add-on, or an update to an existing add-on, is submitted to AMO, it is placed in the sandbox.</p>
+
+<p>Some add-ons, and their specific versions, are made public after the review process indicates that they are ready and appropriate for public display. Other add-ons will remain in the sandbox indefinitely, where they are available to users who choose to browse the sandbox list and experiment with the software there.</p>
+
+<h2>How do add-ons become public?</h2>
+
+<p>Add-ons are reviewed by AMO users who opt into viewing the sandbox and testing the packages found there. The reviews that AMO users write will indicate whether an add-on is sufficiently useful, well-written and polished to be put in front of all of Firefox's users. These reviews, possibly in addition to other reviews and inspections by the AMO team, are used to determine whether a given add-on should be made public, whether it needs more work to be polished for wider visibility, or whether it's not suitable for promotion on the AMO site outside of the sandbox.</p>
+
+<h2>How do I get my add-on promoted to public status?</h2>
+
+<p>If you believe that your add-on (and your behaviour!) meets the criteria for a public add-on, you can nominate it from the developer tools.</p>
+
+<h2>What are the criteria for public add-ons?</h2>
+
+<p>An add-on that's made public on AMO should be of high quality, and give users an improved web experience. We look for the following things when deciding whether an add-on is appropriate for the public side of AMO:</p>
+
+<h3>Are you responsive?</h3>
+
+<p>We expect that an author who is promoting their add-on to Firefox's many users is responsive to problem reports, maintains their contact information, and updates their add-on promptly to keep current with Firefox releases and changes in AMO policies. This doesn't mean that you have to reply to every question that someone posts in the discussions, or that you even need to fix every bug, but we do expect that you will respond to issues in a manner that's appropriate to the severity of the issue in question.</p>
+
+<h3>Is the add-on clearly and accurately described?</h3>
+
+<p>It's of the utmost importance to us that users get what they expect when they try a new add-on. Your description should provide details about what the add-on does, how a user should take advantage of it, and what the user should expect when they install it. Links to external docs for detailed instructions are fine, but the description itself should cover the basics and leave users confident that they know what they'll get.</p>
+
+<p>Also, it is important that you maintain version notes appropriately as you improve and change your add-on. Users should be able to see what's new in an add-on they may have tried previously, and should be made aware of changes that might affect their current use of the add-on when they update. (Right now, users don't see the version notes when they're prompted for an update within the browser, but we'll work to fix that. If you maintain the version notes well, your users will benefit greatly before and after that work is complete.)</p>
+
+<h3>Are all privacy and security concerns clearly spelled out?</h3>
+
+<p>This is an aspect of a clear and accurate description, but such an important one that we feel it deserves specific mention. Many very useful and well-written add-ons manipulate some form of user data, or can present security hazards if misused; they are welcome on the public portion of AMO, but they must make it very clear to users what risks they might encounter, and what they can do to protect themselves.</p>
+
+<h3>Has the add-on been well-tested, and is it free of obvious or serious defects?</h3>
+
+<p>One important thing that we look for when considering an add-on for public access is whether its sandbox reviews indicate that it has received thorough testing, and that it doesn't have serious problems or negative impacts on the browser. If reviewers report problems such as major performance issues, crashes, frequent problems using the functions of the add-on, or spamming of messages to the error console, you should take those reports to heart, and re-nominate your add-on after you've addressed them as best you can. We don't expect you to perfectly optimize or have zero bugs -- Firefox itself undergoes constant improvement in these areas -- but we do want you to take reasonable efforts to minimize downsides, and to clearly call out cases where users may be surprised by those that remain.</p>
+
+<p>If your add-on has been tested outside of the AMO Sandbox process, such as by a group of users of your service or an in-house QA team, you should indicate that in your nomination message. It certainly helps us establish what the level of testing has been, and can help get your add-on up on the site.</p>
+
+<h3>Do the add-on and add-on author both treat the user respectfully?</h3>
+
+<p>Your software should not intrude on the user unnecessarily, try to trick the user, or conceal any of its activities from the user. Users (or even non-users) are sometimes rude in their comments, and while we will do our best to filter those out as they're reported to us, we do expect that authors will avoid retaliating with rudeness of their own.</p>
+
+<h3>Is the add-on useful to an appropriately wide portion of Firefox's users?</h3>
+
+<p>Your add-on doesn't need to be the next Greasemonkey or FireBug, but if it is only useful to people at your company or who are part of a small web community, we may feel that it's not yet appropriate to put it in front of all of Firefox's users.</p>
+
+<p>We are constantly looking at ways to improve the organization of the site to better accommodate add-ons that are exemplary in other ways, but are aimed at only a small community of potential users. Correctly categorizing and maintaining the metadata of your add-on will help us figure out how we can surface more of those sorts of add-ons to people who are most likely to benefit from them.</p>
+
+<p>If your add-on just provides bookmarks or other simple access points to your site, it's probably not
+appropriate for the public part of the site. Like the rest of the Mozilla project, we love web applications and
+new web services, but Firefox add-ons should provide an improved browsing experience for the user and not just be a way to promote a new site or service through an AMO listing. If the description for your add-on is mostly about the service rather than the improvements it makes to the user's browser experience, you're probably not on the right track.</p>
+
+<h3>Is the add-on free of unlicensed trademarks or copyrights?</h3>
+
+<p>Though you may mean no harm to the holder of a trademark, or the owner of a copyrighted work, we can't host add-ons that infringe on trademarks or copyrights. If you don't have permission to use a trademarked name or image, please do not submit your add-on to AMO. If your add-on includes code that is copyrighted by someone else, and is not licensed to you to use in your add-on, please do not submit your add-on to AMO. (If the holder of a trademark or copyright objects to the use of their trademark, we will very likely have to have the request for removal reviewed by counsel, and we will remove the add-on if it's deemed legally necessary. This is an expensive process in terms of the project's resources, including time and money, so we ask you to be respectful and not cause us undue difficulty.)</p>
+
+<p>If you're not sure if the name of your add-on, or use of something within it, will prevent it from being listed on the site, you can ask amo-editors@mozilla.org for guidance. IMPORTANT: Please note that this group is not able to provide legal advice, and that even if we feel that your usage is acceptable, we may revisit that decision in light of complaints from rights-holders and advice from legal counsel.</p>
+
+<p>In terms of reuse of source code from other add-ons, if the author has not clearly stated that you are permitted to use her code in your own work -- such as by placing it under an open source license -- then you should assume that you do not have the right to do so. You can contact the author to seek such permission, but we can't provide you with any special rights to it just because it's been on AMO, or because the author isn't responding to your request. (And, again, we can't provide legal advice, just advice about how your add-on is likely to interact with the policies of the site.)</p>
+
+<p>This applies to the Mozilla Foundation's trademarks as well, including "Mozilla", "Firefox", and "Thunderbird". The Mozilla policy on trademark use is designed to protect against confusion, and prevent the trademarks from being overturned due to lack of protection; please respect the need for such protection, and help us preserve some of the most valuable assets of the Mozilla Foundation.</p>
+
+<h2>What happens after I nominate something?</h2>
+
+<p>Once your add-on has been nominated, it is evaluated by a team of AMO Editors according to the criteria described above. If it is deemed ready for public display, it will be pushed to the public side once it has been evaluated, and you will receive an email notification.</p>
+
+<p>If we feel that the add-on isn't appropriate for the public side of AMO at this time, you'll receive an email notification indicating why, and your nomination will be removed from the queue. If and when you feel that you've addressed the concerns expressed in that notification, and you want to be evaluated again, you can do so at your discretion. Repeated nominations without meaningful improvements in the add-on are not looked upon with favour, so please do exercise discretion; you are more likely to anger us than to wear us down.</p>
+
+<h2>Can I nominate someone else's add-on?</h2>
+
+<p>Currently, we ask that an add-on's author nominate their own work for publication. We want to make sure that the author is comfortable with the increased exposure and that feel the add-on in its current state appropriately reflects the quality of their work. If you believe that an add-on is polished, that the author is abiding by the letter and spirit of the AMO policies, and that it would benefit Firefox, our users, and the web in general to have it made available to nearly a hundred million users around the world, you should feel free to encourage the author of the add-on to nominate their creation.</p>
+
+<h2>My add-on has been in the nomination queue for a long time, do you hate me?</h2>
+
+<p>We don't hate you. We love add-on developers, and we work hard to make them happy and productive, so that users all over the world can benefit from their work. But being on the public side of AMO has value precisely because we take care in what ends up there, so we can't rush just to make it go faster. We appreciate that it can be frustrating to wait for your add-on to be evaluated, and we want to keep the turnaround time as short as possible. The more people provide careful and clear reviews of add-ons in the sandbox, the easier it is to perform these evaluations, so you might also consider helping out on that side if you're so inclined.</p>
+
+<h2>I found a serious bug in my add-on, and I really want to get the fix up there quickly. What should I do?</h2>
+
+<p>If there is a serious bug (security, stability, major functionality problem) in an add-on for which you need to get an update out promptly, you should indicate that in the "reviewer notes" when submitting the update -- as well as in the version notes, obviously! You may also want to enlist some existing users of your add-on to test the update and report their results in detail in the sandbox. Popping into #addons on irc.mozilla.org can help make people aware of the situation, but please be patient and polite if you do so.</p>
+
+<p>Please don't cry wolf. We try to jump quickly on high-priority updates, but it costs us time evaluating other nominated add-ons or versions, and often it costs us sleep or time with our families and friends, so we take a dim view of people who try to take advantage of this mechanism to "jump the queue". If you're not sure whether you should go this route, asking on #addons on irc.mozilla.org may well help you decide.
+
+<h2>I think I was treated unfairly in the evaluation of my add-on. What should I do?</h2>
+
+<p>If you believe that your add-on was incorrectly evaluated, and that it was denied public status in error, you should send an email to amo-editors@mozilla.org with the details of your reasoning. Please be polite and clear in your email, and make sure that you have specifics about how the add-on was misjudged.</p>
+
+<p>(If you have fixed *all* the things that were listed as problems in your notification mail, you shouldn't appeal the evaluation, but should instead re-nominate for consideration through the Developer Tools.)</p>
+
+<h2>My add-on used to be public, and now it's only in the sandbox. What happened? </h2>
+
+<p>If an add-on no longer meets the criteria for being on the public side of the site, we may move it back to the sandbox. Unless we are legally prevented from doing so, we will notify you by email when that happens, and indicate the reasons for doing so.</p>
+
+<p>It's also possible that you've found a bug in the site, in which case you should report it via Bugzilla; use the "addons.mozilla.org" product and the "Public Pages" component for your report, and include as much detail as you can.</p>
+
+<h2>My add-on is public, and people seem to love it. How can I get in the list of recommended add-ons?</h2>
+
+<p>If you believe that your add-on is a shining example of the power of add-ons, that it demonstrates and furthers Mozilla's values for the extensible and user-controlled web, and that it provides a great user experience, you can ask to have it considered for addition to the list of recommended add-ons. To do this, you should send an email to amo-editors@mozilla.org explaining why your add-on is great.</p>
+
+<p>Your mail should include at <b>least</b> information about these things:</p>
+<ul>
+<li>how the web experience is improved for users</li>
+<li>how your add-on is appropriate for a large portion of Firefox's users</li>
+<li>how your add-on demonstrates and/or serves the values of the Mozilla project, especially with respect to putting the user in charge, protection of privacy and security, universal access to the web, and open standards and data</li>
+<li>how your add-on differs from other similar add-ons (in ways that are both better and worse)</li>
+<li>what reaction you've seen from users, reviewers, bloggers, astronauts, or your household pets, both positive and negative</li>
+</ul>
+
+<p>The more complete the information you provide in your request the more amenable we are likely to be to granting it, though even a wonderfully-written and exhaustive application is no guarantee of placement in the recommended list. Ultimately, that list must be -- and is -- maintained at the discretion of Mozilla, and user experience and protection must trump all else.</p>
diff --git a/site/app/locale/en_US/pages/privacy.thtml b/site/app/locale/en_US/pages/privacy.thtml
new file mode 100644
index 0000000..a9acf55
--- /dev/null
+++ b/site/app/locale/en_US/pages/privacy.thtml
@@ -0,0 +1,162 @@
+<h2>Mozilla Privacy Policy</h2>
+
+<p>June 2008</p>
+
+<p><i>Note: This privacy policy applies to the Mozilla.org Web sites and services. We have a separate privacy policy for our
+products and for some Mozilla.com web properties. Please see for example: <a
+href="http://www.mozilla.com/en-US/legal/privacy/firefox-en.html">Mozilla Firefox Privacy Policy</a>.</i></p>
+
+<div class="corner-box"> <h3>Website Visitors</h3>
+
+<p>Except as described below, the Mozilla Foundation ("Mozilla") does not collect or require visitors to
+its Web sites to furnish personally-identifying information such as names, email addresses and phone numbers.
+Like most Web site operators, Mozilla collects non-personally-identifying information of the sort that web
+browsers and servers typically make available, such as the browser type, language preferences, referring
+site, and date and time of each visitor request. Mozilla also collects potentially personally-identifying
+information like Internet Protocol (IP) addresses, which are non-personally identifying in and of themselves
+but could be used in conjunction with other information to personally identify users.</p>
+
+<p>Mozilla's purpose in collecting this information is to better understand how Mozilla's visitors use
+its Web sites. To that end, Mozilla may share potentially personally-identifying information with its
+employees, contractors, and its subsidiaries and related organizations. Mozilla may also release
+non-personally-identifying information about visitors (e.g., by publishing a report on Web site usage
+trends). Otherwise, Mozilla will not publicly release potentially personally-identifying information
+except under the same circumstances as Mozilla releases personally-identifying information. Those
+circumstances are explained below.</p>
+
+</div>
+
+<div class="corner-box"> <h3>Community Members</h3>
+
+<p>Certain members of the Mozilla community (contributors, customers, etc.) choose to interact with
+Mozilla in ways that require Mozilla and others to know more about them. The amount and type of
+information that Mozilla gathers from those members depends on the nature of the interaction. For
+example, members who wish to post content to certain portions of Mozilla's Web sites or participate
+in live chat session(s) are asked to provide usernames that identify that content as having been
+posted by a particular member. Developers, by comparison, are asked to provide contact information,
+up to and sometimes including telephone or fax numbers, so that they can be contacted as necessary.
+Customers of the Mozilla store are asked to provide even more information, including billing and
+shipping addresses and credit card or similar information. In each case, Mozilla collects
+personally-identifying information only insofar as is necessary to fulfill the purpose of the
+community member's interaction with Mozilla.</p>
+
+<p>Mozilla is an open organization that believes in sharing as much information as possible about
+its products, its operations and its associations. Accordingly, community members should assume&mdash;as
+should most folks who interact with Mozilla&mdash;that any personally-identifying information
+provided to Mozilla will be made available to the public. There are three broad exceptions to that rule:</p>
+
+<ol>
+<li>Mozilla does not publicly release information gathered in connection with commercial transactions
+(i.e., transactions involving money), including transactions conducted through the Mozilla Store or
+donations to the Mozilla Foundation.</li>
+
+<li>Mozilla does not make publicly available information that is used to authenticate users the publication
+of which would compromise the security of Mozilla's Web sites (e.g., passwords).</li>
+
+<li>Mozilla does not make publicly available information that it specifically promises at the time of
+collection to maintain in confidence.</li>
+
+</ol>
+
+<p>Outside those three contexts, visitors should assume that personally-identifying information provided
+through Mozilla's Web sites will be made available to the public.</p>
+
+</div>
+
+<div class="corner-box"> <h3>Interactive Product Features</h3>
+
+<p>Certain Mozilla products contain features that report, or that permit users to report, the user's
+usage patterns and problems&mdash;whether caused by Mozilla's software, third party software, or
+third-party Web sites&mdash;to Mozilla. The reports generated by these features typically include
+non-personally-identifying information such as the configuration of the user's computer and the code
+running at the time the problem occurred. Some of the features give users the option of providing
+personally-identifying information, though none of these features require it. Some Mozilla software
+features that do permit users to provide personally-identifying information advise, in advance, that
+such information will not be made publicly available. Mozilla analyzes the information provided by
+these interactive product features to develop a better understanding of how its products are performing
+and being used. It does not use the information to track the usage of its products by identifiable
+individuals.</p>
+
+</div>
+
+<div class="corner-box"> <h3>Protection of Certain Personally-Identifying Information</h3>
+
+<p>Where Mozilla has collected personally-identifying information subject to one of the three
+exceptions described in the Contributors and Customers section, above, it discloses that information
+only to those of its employees, contractors and its subsidiaries and related organizations that need
+to know that information in order to process it on Mozilla's behalf and that have agreed not to disclose
+it to others. Some of those employees, contractors and subsidiaries and related organizations may be
+located outside of a visitor's home country; by using Mozilla's Web sites, the visitor consents to
+the transfer of his/her information to them. Mozilla does not rent or sell such information to anyone.
+Other than to its employees, contractors or its subsidiaries and related organizations, as described
+above, Mozilla discloses such information only when required to do so by law, or when Mozilla believes
+in good faith that disclosure is reasonably necessary to protect the property or rights of Mozilla,
+members of the Mozilla community, or the public at large. Mozilla takes all measures reasonably
+necessary to protect against the unauthorized access, use, alteration or destruction of such
+information.</p>
+
+</div>
+
+<div class="corner-box"> <h3>Updating of Personally-Identifying Information</h3>
+
+<p>Mozilla permits users to freely update and correct their personally-identifying information as
+maintained by Mozilla. To do so, users should look for links or contact information available on
+whichever Mozilla Web sites store the relevant information (e.g., Bugzilla users should go to
+<a href="https://bugzilla.mozilla.org/userprefs.cgi?tab=account">https://bugzilla.mozilla.org/userprefs.cgi?tab=account</a>),
+or contact Mozilla by email.</p>
+
+</div>
+
+<div class="corner-box"> <h3>Cookies and Clear GIFs</h3>
+
+<p><b>What Are Cookies?</b> A cookie is a string of information that a Web site stores on a visitor's
+computer, and that the visitor's browser provides to the Web site each time the visitor returns.
+Most major web sites use cookies. Because the browser provides this cookie information to the website
+at each visit, cookies serve as a sort of label that allows a website to "recognize" a browser when it
+returns to the site. The domain name in Mozilla cookies will clearly identify their affiliation with
+Mozilla and, where applicable, its third party service provider.</p>
+
+<p><b>What Are Clear GIFs?</b> Clear gifs (also known as web beacons) are used in combination with
+cookies to help web site operators understand how visitors interact with their websites. A clear gif is
+typically a transparent graphic image (usually 1 pixel x 1 pixel) that is placed on a site. The use of
+a clear gif allows the site to measure the actions of the visitor opening the page that contains the
+clear gif. It makes it easer to follow and record the activities of a recognized browser, such as the
+path of pages visited at a website.</p>
+
+<p><b>How We Use Cookies and Clear GIFs.</b> Mozilla's Web sites use cookies and may use clear gifs in
+the future. These tools help Mozilla identify and track visitors, their usage of Mozilla Web sites, and
+their Web site access preferences across multiple requests and visits to Mozilla's Web sites. The basic
+idea is to gather aggregate data about how people use the Mozilla Web sites. The term usually used to
+describe this is "web analytics" and the cookies and clear gifs are the tools by which a website owner
+collects this web analytics data. Mozilla will use the web analytics data only to determine aggregate
+usage patterns for our Web sites as described above. The Mozilla Web sites (.org domains) do this
+using Mozilla's own internal analytics software, and currently do not utilize third party service
+providers. Mozilla uses the information provided by cookies and clear gifs to develop a better
+understanding of how Mozilla's visitors use Mozilla's Web sites, and to facilitate those visitors'
+interactions with Mozilla's Web sites. Mozilla may make the aggregate data it obtains publicly
+available. If the data is made available, none of the information will be personally-identifying
+information or potentially-personally-identifying information.</p>
+
+<p><b>How to Control the Use of Cookies.</b> Mozilla visitors have the ability to accept or decline
+cookies. Mozilla visitors who do not wish to have cookies placed on their computers by Mozilla, its
+contractors, or third-party service providers should set their browsers to refuse cookies before linking
+to Mozilla's Web sites. Certain features of Mozilla's Web sites may not function properly without the
+aid of cookies.</p>
+
+</div>
+
+<div class="corner-box"> <h3>Privacy Policy Changes</h3>
+
+<p>Mozilla may change its Privacy Policy from time to time. Any and all changes will be reflected on
+this page. Substantive changes will also be announced through the standard mechanisms through which
+Mozilla communicates with the Mozilla community, including Mozilla's
+<a href="http://lists.mozilla.org/listinfo/announce">"Mozilla-announce" mailing list</a> and
+<a href="http://groups.google.com/group/mozilla.announce">newsgroup</a>.</p>
+
+</div>
+
+<div class="corner-box"> <h3>For More Information</h3>
+
+<p>If you have questions about this privacy policy, please contact Mozilla at: privacy@mozilla.org.</p>
+
+</div>
diff --git a/site/app/locale/en_US/pages/reviewguide.thtml b/site/app/locale/en_US/pages/reviewguide.thtml
new file mode 100644
index 0000000..588771e
--- /dev/null
+++ b/site/app/locale/en_US/pages/reviewguide.thtml
@@ -0,0 +1,90 @@
+<h1>Review Guidelines</h1>
+<p>Add-on Reviews are a way for add-on site users to share their opinions about
+the add-ons that they have installed and used. Editors reserve the right to
+refuse or remove any review that does not comply with these guidelines.</p>
+
+<div class="corner-box">
+ <h2>Some tips for writing a great review</h2>
+
+<h3><b>Do:</b></h3>
+<ul>
+<li>Write like you are telling a friend about your experience with the add-on.</li>
+<li>Keep reviews concise and easy to understand.</li>
+<li>Give specific and helpful details. For example:
+<ul>
+ <li>Did the add-on work as you expected it to?</li>
+ <li>What features did you like or dislike?</li>
+ <li>Was it useful?</li>
+ <li>Was it easy to use?</li>
+ <li>Will you continue to use this add-on?</li>
+</ul></li>
+
+<li>Take a moment to read your review before submitting it to avoid embarrassing typos or grammatical errors.</li>
+
+<li>Avoid referring to topical or temporal references since reviews can remain on the site for a long time.</li>
+</ul>
+
+<h3><b>Don't:</b></h3>
+<ul>
+<li>Submit simple reviews such as "Great!", "wonderful", or "bad" with no further explanation.</li>
+<li>Post bug or problem reports in reviews. Use the available support options for each add-on.</li>
+<li>Write reviews for add-ons which you have not personally used.</li>
+<li>Use profanity, sexual language or language that can be construed as hateful.</li>
+<li>Include HTML, links to malware, source code or code snippets. Reviews are meant to be text only.</li>
+<li>Make false statements, disparage add-on authors or personally insult them.</li>
+<li>Use reviews as a way to request support for a specific Firefox (or other application) version.</li>
+<li>Include your own email, phone number, or other personal details.</li>
+<li>Post reviews for an add-on you or your organization wrote or represent.</li>
+</ul>
+</div>
+
+<div class="corner-box">
+ <h2>Guidelines for rating add-ons</h2>
+
+<p>Add-ons ratings should be fair and give a good indication of overall quality
+and usefulness. Don't just give it 5 stars if you like it or 1 star if you
+hate it. Consistent grading is an important part of any review.</p>
+
+<ul>
+<li><b>5 stars: Excellent.</b> Not only does everything it claims, but it is
+significantly more useful than many other add-ons. This add-on is likely to be
+one you use often and you highly recommend it.</li>
+<li><b>4 stars: Good.</b> Useful and easy to use, though not necessarily special. This
+add-on is recommended but may be more suited for some people over others.</li>
+<li><b>3 stars: Passable.</b> May have some design issues and/or some missing features.
+Any problems it has are not drastic enough to recommend against, and some
+people may still find it useful. Recommended for those who need it and are
+willing to give it a try.</li>
+<li><b>2 stars: Poor.</b> Add-on is of low quality, usability, or just doesn't do what
+it says it should. You are recommending against this add-on, while noting that
+it might have some redeeming value for a few people.</li>
+<li><b>1 star: Bad.</b> Add-on either doesn't work correctly or is utterly useless. You
+can't think of any significant reason why someone should give it a try and are
+recommending that it be avoided completely.</li>
+</ul>
+
+<p>There's nothing wrong with giving an add-on a perfect or horrible review, just
+please indicate why you are doing so. The stars mean nothing if you don't tell
+us why.</p>
+</div>
+
+<div class="corner-box">
+ <h2>Frequently Asked Questions about Reviews</h2>
+
+<h3>How can I report a problematic review?</h3>
+<p>Please report or flag any questionable reviews by clicking the "Report this
+review" and it will be submitted to the site for moderation. Editors will use
+the Review Guidelines to evaluate whether or not to delete the review or
+restore it back to the site.</p>
+
+<h3>I'm an add-on author, can I respond to reviews?</h3>
+<p>Yes, add-on authors can provide a single response to a review. Additional
+discussions or followup should be moved to a support forum or discussion group.</p>
+
+<h3>I'm an add-on author, can I delete unfavorable reviews or ratings?</h3>
+<p>In general, no. But the review did not meet the review guidelines outlined
+above, you can click "Report this review" and have it moderated by an editor.
+If a review included a complaint that is no longer valid due to a new release
+of your add-on, we may consider deleting the review. Submit your detailed
+request to amo-editors@mozilla.org.</p>
+</div>
diff --git a/site/app/locale/en_US/pages/sandbox.thtml b/site/app/locale/en_US/pages/sandbox.thtml
new file mode 100644
index 0000000..8cfdb09
--- /dev/null
+++ b/site/app/locale/en_US/pages/sandbox.thtml
@@ -0,0 +1,13 @@
+<h1>Sandbox Review System</h1>
+<h2>What is the sandbox?</h2>
+<p>The sandbox is an area for advanced users to test add-ons before they are reviewed for general use. In order to access the sandbox, you must enable it in your account settings. Caution should be used when installing sandboxed add-ons, as they have not been tested by an editor and may harm your computer.</p>
+
+<h2>How do I get my add-on to be on the public side?</h2>
+<!-- To localize the flowchart image, see http://wiki.mozilla.org/Update:Remora_Sandbox_Flowchart -->
+<div style="text-align: center;">%s</div>
+<ol>
+ <li><b>Submit your add-on in the Developer Tools.</b> Your item will immediately appear in the "Sandbox" side of Mozilla Add-ons, where experienced users will test it and provide feedback. In order to see the sandbox, you will have to enable it in your account settings.</li>
+ <li><b>Nominate your add-on to be public.</b> From the Developer Tools, there is a link to nominate your add-on. After nominated, your add-on will appear in the Editor Nomination Queue for review.</li>
+ <li><b>An editor reviews your add-on.</b> A Mozilla Add-ons editor will install your add-on and test that it works. The editor will also look at reviews given by sandbox testers.</li>
+ <li><b>Your add-on is pushed public or retained in the sandbox.</b> The editor will either push your add-on public or retain it in the sandbox. If retained in the sandbox, you can nominate it again after making changes the editor suggests in comments. If pushed public, future versions of your add-on will appear in the sandbox until they have been reviewed by an editor and pushed public. Once your add-on is public, there is no need to nominate it again - future versions will automatically go into the pending queue for review.</li>
+</ol>
diff --git a/site/app/locale/en_US/pages/statistics_help.thtml b/site/app/locale/en_US/pages/statistics_help.thtml
new file mode 100644
index 0000000..2a529cd
--- /dev/null
+++ b/site/app/locale/en_US/pages/statistics_help.thtml
@@ -0,0 +1,7 @@
+<h3>Help</h3>
+<p>The Statistics Dashboard displays download and update ping data collected for your add-on.</p>
+<h4>Downloads</h4>
+<p>Download counts are updated every day and only include original add-on downloads, not updates.</p>
+
+<h4>Update Pings</h4>
+<p>Add-ons downloaded from this site check for updates once per day, and the total number of these update pings is known as Active Daily Users. Active Daily Users (ADU) can be broken down by add-on version, operating system, add-on status, and application.</p>
diff --git a/site/app/locale/en_US/pages/submission_help.thtml b/site/app/locale/en_US/pages/submission_help.thtml
new file mode 100644
index 0000000..4792286
--- /dev/null
+++ b/site/app/locale/en_US/pages/submission_help.thtml
@@ -0,0 +1,35 @@
+<h1>Submission Help</h1>
+Required fields are <b>bold</b>. Optional fields are <i>italicized</i>.
+<h2 id="step1">Step 1: Upload</h2>
+<ul class="submissionHelp">
+ <li><span class="required">Add-on Type</span> - By default, the add-on type will be automatically determined based on the uploaded file. You should not have to change this field.</li>
+ <li><span class="required">Add-on File</span> - The package file for your add-on, complete with an install.rdf file. If the file only works with a specific platform, selecting that platform will allow multiple files to be uploaded at once.</li>
+ <li><span class="optional">Icon File</span> - The icon file is displayed next to the add-on name on its display page and is shown in the add-on installation dialog. It will automatically be resized to 32x32 pixels, keeping the aspect ratio.</li>
+ <li><span class="required">Default Locale</span> - An add-on's default locale is its main locale. If a user's selected locale is not available for the add-on, translations will fall back to the default locale.</li>
+ <li><span class="optional">Skip reviewing my current add-on information</span> - If you are updating an existing add-on, this field will appear. Checking the box will skip to step 3 where you can enter your version-specific information.</li>
+</ul>
+
+<h2 id="step2">Step 2: Add-on Details</h2>
+<ul class="submissionHelp">
+ <li><span class="required">Name</span> - Name of the add-on in the default locale.</li>
+ <li><span class="required">Authors</span> - All users who have access to modify the add-on's listing and will be listed as authors on the display page.</li>
+ <li><span class="required">Categories</span> - Categories applicable to the add-on.</li>
+ <li><span class="optional">Homepage</span> - The add-on's website in the default locale.</li>
+ <li><span class="required">Summary</span> - A brief summary of the add-on in the default locale. This field has a maximum of 250 characters, and will appear in the add-on's display page, as well as search/browse results.</li>
+ <li><span class="required">Description</span> - A description of the add-on in the default locale. This will appear on the add-on's display page underneath the summary.</li>
+ <li><span class="optional">EULA</span> - The End User License Agreement that users will be required to accept before downloading, in the default locale.</li>
+ <li><span class="optional">Privacy Policy</span> - The add-on's Privacy Policy, in the default locale. Privacy Policies explain what is done with an end user's personal information, and will be linked next to the install button on an add-on's display page. Additional information on what should be included in a Privacy Policy and whether your add-on requires one is available in the <a href="%s">Add-on Policy</a>.</li>
+ <li><span class="optional">Allow users to view the source files online</span> - Checking this box will allow users to browse the source files of your add-on online.</li>
+ <li><span class="optional">This is a pre-release</span> - Checking this box will indicate that the add-on is a pre-release or "beta" version. Pre-release add-ons should remain in the sandbox and cannot be nominated for public until this flag has been removed.</li>
+ <li><span class="optional">This is a site-specific add-on</span> - Checking this box will indicate that the add-on is specific to a single website, such as an add-on that alters a certain website's look or displays content from a specific website. This field is helpful to editors and may be used to filter searches in the future.</li>
+ <li><span class="optional">This add-on requires external software</span> - Checking this box will indicate that the add-on requires external software. This field is helpful to editors and may be used to filter searches in the future.</li>
+</ul>
+
+<h2 id="step3">Step 3: Version Details</h2>
+<ul class="submissionHelp">
+ <li><span class="required optional">Version Notes</span> - A summary or list of the changes in this version. This is optional for new submissions, but required for updates.</li>
+ <li><span class="optional">Notes to Reviewer</span> - This field is used for communicating information to editors who will review your add-on. Test account information and special notes should go here.</li>
+</ul>
+
+<h2 id="step4">Step 4: Localization</h2>
+This is where add-on fields can be localized into all supported locales. Simply click on a locale to enter translations. \ No newline at end of file
diff --git a/site/app/locale/es_ES/LC_MESSAGES/messages.mo b/site/app/locale/es_ES/LC_MESSAGES/messages.mo
new file mode 100644
index 0000000..8afe426
--- /dev/null
+++ b/site/app/locale/es_ES/LC_MESSAGES/messages.mo
Binary files differ
diff --git a/site/app/locale/es_ES/LC_MESSAGES/messages.po b/site/app/locale/es_ES/LC_MESSAGES/messages.po
new file mode 100644
index 0000000..b91de83
--- /dev/null
+++ b/site/app/locale/es_ES/LC_MESSAGES/messages.po
@@ -0,0 +1,8241 @@
+# translation of messages.po to Español (España)
+# Remora Preliminary Language File
+# Copyright (C) 2006 Mozilla Corporation
+# This file is distributed under the same license as the REMORA package.
+# Wil Clouser <clouserw@mozilla.com>, 2006, 2007.
+# Rubén Martín (Nukeador) <nukeador@gmail.com>, 2007.
+# AMO <rpmdisguise-otros@yahoo.es>, 2007.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: messages\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2009-01-16 11:45-0800\n"
+"PO-Revision-Date: 2009-05-23 14:55+0100\n"
+"Last-Translator: \n"
+"Language-Team: Español (España) <nave@elistas.net>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: es\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+"X-Generator: Pootle 1.2.1\n"
+"X-Poedit-Language: Spanish\n"
+
+#: views/addons/policy.thtml:98
+msgid "a_cancel_installation"
+msgstr "Cancelar instalación"
+
+#. This is the text that appears on buttons to download add-ons.
+#. %$1s is an optional string that only appears if the add-on is only available for
+#. a certain platform. Examples: (Windows) or (Linux)
+#. Note that the parentheses are included in the string. :(
+#: views/elements/amo2009/install.thtml:126
+#: views/elements/amo2009/install.thtml:227
+#: views/elements/amo2009/install.thtml:257
+#: views/elements/amo2009/install.thtml:300
+#: views/elements/amo2009/install.thtml:312 views/elements/install.thtml:73
+#: views/elements/install.thtml:181 views/elements/install.thtml:205
+#: views/elements/install.thtml:248 views/elements/install.thtml:260
+#: views/addons/plugins.thtml:66 views/addons/plugins.thtml:76
+#: views/addons/plugins.thtml:86 views/addons/plugins.thtml:96
+#: views/addons/plugins.thtml:119
+#, php-format
+msgid "a_download"
+msgstr "Descargar ahora %s"
+
+#: views/addons/policy.thtml:72
+msgid "a_eula_download"
+msgstr "Aceptar y descargar"
+
+#: views/addons/policy.thtml:74
+msgid "a_eula_install"
+msgstr "Aceptar e instalar"
+
+#: views/elements/header.thtml:76 views/elements/header.thtml:82
+#: views/api/api_addon.thtml:55 views/api/collections_feed.thtml:75
+#: views/sharing_api/addon.thtml:64
+msgid "a_header_public"
+msgstr "Ãrea pública"
+
+#: views/elements/header.thtml:58 views/elements/header.thtml:75
+#: views/elements/header.thtml:80 views/api/api_addon.thtml:57
+#: views/api/collections_feed.thtml:77 views/sharing_api/addon.thtml:66
+msgid "a_header_sandbox"
+msgstr "Ãrea de pruebas"
+
+#. %s is a date in the _('date') format
+#: views/elements/amo2009/homepage_addon.thtml:115
+#: views/elements/addon_listitem.thtml:122 views/elements/feature.thtml:106
+#: views/addons/display.thtml:104 views/addons/browse_thumbs.thtml:73
+msgid "addon_detail_last_updated"
+msgstr "%s actualizado"
+
+#. %s is the version of the add-on. Example: 3.2a1
+#: views/elements/amo2009/addon_version_detail.thtml:51
+#: views/elements/addon_version_detail.thtml:51
+#, php-format
+msgid "addon_display_header_version"
+msgstr "Versión %s"
+
+#: views/addons/browse_thumbs.thtml:80
+msgid "addon_downloads"
+msgstr "descargas"
+
+#: views/addons/display.thtml:147
+msgid "addon_downloads_total"
+msgstr "descargas totales"
+
+#: views/elements/amo2009/homepage_addon.thtml:106
+#: views/elements/addon_listitem.thtml:115 views/elements/feature.thtml:101
+#: views/addons/category_landing.thtml:157 views/addons/display.thtml:146
+#: views/addons/browse_thumbs.thtml:80
+msgid "addon_downloads_weekly"
+msgstr "descargas semanales"
+
+#. %1 is the add-on count, %2 the category name
+#: views/addons/browse_thumbs.thtml:104 views/addons/browse.thtml:60
+#, php-format
+msgid "addon_list_category_totalcount"
+msgid_plural "addon_list_category_totalcount"
+msgstr[0] "%1$s complemento"
+msgstr[1] "%1$s complementos"
+
+#: views/elements/amo2009/addon_list_options.thtml:103
+#: views/elements/pagination.thtml:67
+#: views/elements/addon_list_options.thtml:94
+msgid "addon_list_perpage"
+msgstr "por página"
+
+#: views/elements/amo2009/addon_list_options.thtml:84
+#: views/elements/addon_list_options.thtml:98
+msgid "addon_list_sortby"
+msgstr "Ordenar por:"
+
+#: views/helpers/addons_html.php:568 views/elements/amo2009/install.thtml:321
+#: views/elements/feature.thtml:89
+msgid "addon_listitem_flag_experimental"
+msgstr "experimental"
+
+#: views/helpers/addons_html.php:570
+msgid "addon_listitem_flag_recommended"
+msgstr "recomendado"
+
+#. %1 is the add-on name, %2 is the platform
+#: views/pages/js_constants.js.thtml:66
+msgid "addon_not_available_for_platform"
+msgstr "%1$s no está disponible para %2$s"
+
+#. %1 is the add-on name
+#: views/addons/policy.thtml:101 views/addons/previews.thtml:60
+#: views/addons/versions.thtml:130 views/reviews/flag.thtml:61
+#: views/reviews/add.thtml:114 views/reviews/display.thtml:216
+#: views/reviews/review_added.thtml:57
+#, php-format
+msgid "addon_review_a_back_to_addon_x"
+msgstr "Volver a %1$s..."
+
+#. %1 is the add-on name
+#: views/reviews/flag.thtml:60 views/reviews/add.thtml:113
+#: views/reviews/review_added.thtml:56
+#, php-format
+msgid "addon_review_a_back_to_reviews"
+msgstr "Volver a las valoraciones..."
+
+#: views/reviews/add.thtml:85
+msgid "addon_review_add_rating_field"
+msgstr "Puntuación:"
+
+#: views/reviews/add.thtml:102
+msgid "addon_review_add_review_field"
+msgstr "Valoración:"
+
+#: views/reviews/add.thtml:107
+msgid "addon_review_add_submit"
+msgstr "Envía tu valoración"
+
+#. %s is the name of the add-on
+#: views/reviews/add.thtml:51
+#, php-format
+msgid "addon_review_add_title"
+msgstr "Añadir una valoración de %s"
+
+#: views/reviews/add.thtml:78
+msgid "addon_review_add_title_field"
+msgstr "Título/Resumen:"
+
+#: views/reviews/display.thtml:77 views/reviews/display.thtml:161
+msgid "addon_review_admin_delete"
+msgstr "Borrar"
+
+#: views/reviews/display.thtml:76
+msgid "addon_review_author_reply_link"
+msgstr "Responder"
+
+#: views/reviews/delete.thtml:62
+msgid "addon_review_confirm_delete"
+msgstr "¿Estás seguro que quieres borrar esta valoración?"
+
+#: views/reviews/delete.thtml:63
+msgid "addon_review_confirm_no"
+msgstr "No"
+
+#: views/reviews/delete.thtml:64
+msgid "addon_review_confirm_yes"
+msgstr "Si"
+
+#: views/reviews/delete.thtml:48
+msgid "addon_review_delete_header"
+msgstr "Borrar valoración"
+
+#: controllers/reviews_controller.php:449
+msgid "addon_review_deleted_successfully"
+msgstr "La valoración se borró con éxito."
+
+#. %s is the name of the add-on
+#: views/reviews/add.thtml:51
+#, php-format
+msgid "addon_review_edit_title"
+msgstr "Editar valoración de %s"
+
+#. %1 is the count of characters entered as notes for the review flag reason.
+#: controllers/reviews_controller.php:539
+msgid "addon_review_flag_error_other_length"
+msgstr ""
+"Problema al marcar para valoración: Las notas de las valoraciones están "
+"limitadas entre 10 y 100 caracteres; la longitud de tu texto fue de %1$s."
+
+#. Removing an extra comma
+#: views/reviews/review_added.thtml:53
+msgid "addon_review_in_moderation"
+msgstr ""
+"Atención: Antes de que tu valoración aparezca en el sitio público, será "
+"revisada por un editor."
+
+#: views/reviews/add.thtml:57
+msgid "addon_review_in_reply_to"
+msgstr "Respuesta del desarrollador a:"
+
+#. %1 is the review count, %2 is the nickname or full name of the user.
+#: views/reviews/display.thtml:131
+#, php-format
+msgid "addon_review_others_by_user"
+msgid_plural "addon_review_others_by_user"
+msgstr[0] "Ver %1$s valoración previa enviada por %2$s para este complemento."
+msgstr[1] ""
+"Ver %1$s valoraciones previas enviadas por %2$s para este complemento."
+
+#. %1 is the add-on name
+#: controllers/reviews_controller.php:201
+#: controllers/reviews_controller.php:250
+#: controllers/reviews_controller.php:345
+#: controllers/reviews_controller.php:424
+#, php-format
+msgid "addon_review_pagetitle"
+msgstr "Valoraciones de %s"
+
+#. %1 is the user, %2 is the (localized) date
+#: views/reviews/display.thtml:160
+#, php-format
+msgid "addon_review_reply_on_x_by_y"
+msgstr "Respuesta por %1$s el %2$s"
+
+#: views/reviews/display.thtml:157
+msgid "addon_review_reply_prefix"
+msgstr "Respuesta del desarrollador:"
+
+#: views/reviews/review_added.thtml:51
+msgid "addon_review_saved_successfully"
+msgstr "Tu valoración se ha guardado con éxito. ¡Gracias!"
+
+#: views/addons/display.thtml:354 views/reviews/display.thtml:72
+msgid "addon_reviewed_by_u_on_d"
+msgstr "por %1$s el %2$s"
+
+#. %1 is the user, %2 is the (localized) date, %3 is the rating
+#: views/editors/reviews_queue.thtml:57 views/editors/reviews_queue.thtml:68
+#: views/reviews/add.thtml:63 views/reviews/delete.thtml:54
+#, php-format
+msgid "addon_reviewed_on_x_rated_y"
+msgstr "Valorado por %1$s, puntuado con %2$d"
+
+#: views/elements/amo2009/addon_version_detail.thtml:52
+#: views/elements/addon_version_detail.thtml:52
+msgid "addon_version_permalink"
+msgstr "Enlace permanente a esta versión"
+
+#. %1 is the current Application name (e.g. Firefox)
+#. %2 is the Application's version number
+#: views/addons/versions.thtml:140
+msgid "addon_versions_getlatestversion"
+msgstr "La versión más reciente compatible con %1$s %2$s"
+
+#: views/addons/display.thtml:447
+msgid "addons_author_addons_submit"
+msgstr "Enviar"
+
+#: views/elements/amo2009/homepage_addon.thtml:100
+#: views/elements/feature.thtml:95
+msgid "addons_author_tooltip"
+msgstr "Ver el perfil del autor"
+
+#. %1 is the name of the Application (eg. Firefox)
+#: controllers/addons_controller.php:1296
+msgid "addons_browse_all_themes_title"
+msgstr "Ver todos los temas :: %1$s Addons"
+
+#. %s is the name of the category
+#: controllers/addons_controller.php:1016
+#, php-format
+msgid "addons_browse_browse_category"
+msgstr "Examinar %s"
+
+#. %1 is the name of the theme category (eg. Modern)
+#. %2 is the name of the Application (eg. Firefox)
+#: controllers/addons_controller.php:664
+msgid "addons_browse_categories_header_theme"
+msgstr "Ver todos los temas %1$s :: %2$s Addons"
+
+#: views/addons/display.thtml:249
+msgid "addons_display_a_license_what"
+msgstr "¿Qué es esto?"
+
+#: views/reviews/display.thtml:222
+msgid "addons_display_add_review"
+msgstr "Añadir una valoración"
+
+#: views/addons/display.thtml:294
+msgid "addons_display_advanced_details"
+msgstr "Detalles avanzados"
+
+#: views/addons/display.thtml:98
+msgid "addons_display_categories"
+msgstr "Categorías"
+
+#: views/addons/display.thtml:482
+#, fuzzy
+msgid "addons_display_collection_add"
+msgstr "Add to a collection:"
+
+#: views/addons/display.thtml:491
+#, fuzzy
+msgid "addons_display_collection_add_new"
+msgstr "New Collection..."
+
+#: views/addons/display.thtml:487
+#, fuzzy
+msgid "addons_display_collection_add_select_one"
+msgstr "Select a collection..."
+
+#: views/addons/display.thtml:493
+#, fuzzy
+msgid "addons_display_collection_add_submit"
+msgstr "Publish"
+
+#. %1$s is the add-on name
+#. %2$s is the collection name, linked to the collection's page
+#: views/pages/js_constants.js.thtml:103 views/addons/display.thtml:61
+#, fuzzy
+msgid "addons_display_collection_publish_success"
+msgstr "%1$s has been added to the %2$s collection."
+
+#: views/addons/display.thtml:483
+#, fuzzy
+msgid "addons_display_collection_whatsthis"
+msgstr "What's this?"
+
+#. %1$s is a number
+#: views/addons/display.thtml:473
+#, fuzzy
+msgid "addons_display_collections_more"
+msgid_plural "addons_display_collections_more"
+msgstr[0] "and %1$s more collection"
+msgstr[1] "and %1$s more collections"
+
+#: views/addons/display.thtml:403
+msgid "addons_display_detailed_review"
+msgstr "valoración en detalle"
+
+#: views/reviews/add.thtml:89 views/reviews/add.thtml:90
+msgid "addons_display_dont_like_it"
+msgstr "No me gusta"
+
+#: views/reviews/display.thtml:220
+msgid "addons_display_edit_review"
+msgstr "Editar tu valoración"
+
+#: views/addons/display.thtml:132
+msgid "addons_display_has_privacy"
+msgstr "Este complemento tiene una política de privacidad."
+
+#: views/reviews/add.thtml:87 views/reviews/add.thtml:88
+msgid "addons_display_hate_it"
+msgstr "Lo odio"
+
+#: views/addons/display.thtml:462
+#, fuzzy
+msgid "addons_display_header_collections"
+msgstr "Related Collections"
+
+#: views/addons/display.thtml:297
+msgid "addons_display_header_developer_comments"
+msgstr "Comentarios del desarrollador"
+
+#: views/addons/display.thtml:230
+msgid "addons_display_header_homepage"
+msgstr "Portada"
+
+#: views/addons/display.thtml:247 views/addons/versions.thtml:110
+msgid "addons_display_header_license"
+msgstr "Licencia del código fuente"
+
+#: views/addons/display.thtml:337
+msgid "addons_display_header_reviews"
+msgstr "Valoraciones"
+
+#: views/addons/display.thtml:261
+msgid "addons_display_header_support"
+msgstr "Asistencia"
+
+#: views/reviews/add.thtml:91 views/reviews/add.thtml:92
+msgid "addons_display_like_it"
+msgstr "Me gusta"
+
+#: views/addons/display.thtml:210
+msgid "addons_display_long_description"
+msgstr "Descripción larga"
+
+#: views/reviews/add.thtml:95 views/reviews/add.thtml:96
+msgid "addons_display_love_it"
+msgstr "Me encanta"
+
+#: views/addons/display.thtml:178
+msgid "addons_display_more_images"
+msgstr "Más imágenes"
+
+#: views/addons/display.thtml:465
+#, fuzzy
+msgid "addons_display_nocollections"
+msgstr "This add-on is not yet in any collections."
+
+#. %1$s is either an author's name or a comma separated list of authors. Using
+#. the list doesn't make sense in the English plural form so we ignore the
+#. variable.
+#: views/addons/display.thtml:436
+msgid "addons_display_other_addons_by"
+msgid_plural "addons_display_other_addons_by"
+msgstr[0] "Otros complementos de %1$s"
+msgstr[1] "Otros complementos de estos autores"
+
+#. %s is the name of the add-on and the add-on section. Example:
+#. Some Add-on :: Firefox Add-ons
+#. This should not be concatenated in the code and should be fixed.
+#: controllers/addons_controller.php:141 controllers/addons_controller.php:280
+#: controllers/addons_controller.php:1442
+#, php-format
+msgid "addons_display_pagetitle"
+msgstr "%s"
+
+#. %s is an email address
+#: views/addons/display.thtml:286
+#, php-format
+msgid "addons_display_paragraph_supportinfoemail"
+msgstr "El desarrollador proporciona ayuda técnica para esta extensión en %s."
+
+#. %$1s is a URL
+#. %$2s is an email address
+#: views/addons/display.thtml:269
+#, php-format
+msgid "addons_display_paragraph_supportinfoemailurl"
+msgstr ""
+"El desarrollador proporciona ayuda técnica para esta extensión en %s o "
+"enviando un correo electrónico a %s."
+
+#. %s is a URL
+#: views/addons/display.thtml:278
+#, php-format
+msgid "addons_display_paragraph_supportinfourl"
+msgstr "El desarrollador proporciona ayuda técnica para esta extensión en %s."
+
+#: views/addons/display.thtml:383
+msgid "addons_display_rate_it"
+msgstr "Puntúa"
+
+#: views/reviews/add.thtml:93 views/reviews/add.thtml:94
+msgid "addons_display_really_like_it"
+msgstr "Me gusta mucho"
+
+#: views/addons/display.thtml:410
+msgid "addons_display_review_etiquette"
+msgstr ""
+"Por favor, no informes de errores en las valoraciones. Tu correo electrónico "
+"no es visible para el desarrollador del complemento y es posible que "
+"necesite contactar contigo para resolver la incidencia."
+
+#. %1 is the review guidelines link
+#: views/addons/display.thtml:417
+msgid "addons_display_review_guidelines_link"
+msgstr "<a href=\"%s\">Guía para revisores</a>"
+
+#. %1 is the support section link
+#: views/addons/display.thtml:414
+msgid "addons_display_review_see_support"
+msgstr ""
+"Visita la <a href=\"%1$s\">sección de asistencia</a> para obtener ayuda con "
+"este complemento."
+
+#: views/addons/display.thtml:404
+msgid "addons_display_review_submit"
+msgstr "Guardar"
+
+#: views/addons/display.thtml:430
+#, php-format
+msgid "addons_display_see_all_addons"
+msgstr "Ver todos los complementos en %1$s"
+
+#. %1 is the number of reviews
+#: views/addons/display.thtml:364
+#, php-format
+msgid "addons_display_see_all_reviews"
+msgstr "Ver todas las valoraciones (%1$s)"
+
+#: views/addons/display.thtml:219
+msgid "addons_display_see_all_versions"
+msgstr "Ver todas las versiones"
+
+#: views/addons/display.thtml:321 views/addons/versions.thtml:117
+msgid "addons_display_view_source"
+msgstr "Ver el código fuente"
+
+#: views/addons/display.thtml:324
+msgid "addons_display_view_stats"
+msgstr "Ver estadísticas"
+
+#: views/addons/display.thtml:376
+msgid "addons_display_what_do_you_think"
+msgstr "¿Qué opinas?"
+
+#: views/elements/app_compatibility.thtml:49
+msgid "addons_display_workswith"
+msgstr "Válida para:"
+
+#: views/addons/home.thtml:112
+#, fuzzy
+msgid "addons_home_browse_new"
+msgstr "Just Added"
+
+#: views/addons/home.thtml:110
+#, fuzzy
+msgid "addons_home_browse_popular"
+msgstr "Popular"
+
+#: views/addons/home.thtml:108
+#, fuzzy
+msgid "addons_home_browse_recommended"
+msgstr "Recommended"
+
+#: views/addons/home.thtml:127 views/addons/home.thtml:134
+#: views/addons/home.thtml:141 views/addons/home.thtml:148
+#, fuzzy
+msgid "addons_home_browse_subscribe"
+msgstr "Subscribe"
+
+#: views/addons/home.thtml:101
+#, fuzzy
+msgid "addons_home_browse_title"
+msgstr "Browse Add-ons"
+
+#: views/addons/home.thtml:114
+#, fuzzy
+msgid "addons_home_browse_updated"
+msgstr "Updated"
+
+#: views/elements/amo2009/homepage_addon.thtml:100
+#: views/elements/addon_discussionheader.thtml:83
+#: views/elements/addon_listitem.thtml:109 views/elements/feature.thtml:95
+#: views/addons/category_landing.thtml:66 views/addons/policy.thtml:57
+#: views/addons/display.thtml:70 views/addons/home.thtml:178
+msgid "addons_home_by"
+msgstr "por"
+
+#: views/addons/home.thtml:169
+#, fuzzy
+msgid "addons_home_collection_popular_title"
+msgstr "Popular Collections"
+
+#: views/elements/amo2009/categories.thtml:69 views/addons/home.thtml:160
+#, fuzzy
+msgid "addons_home_collections"
+msgstr "Collections"
+
+#. %1$s is the count of addons in a collection
+#: views/elements/amo2009/collection_listing_item.thtml:51
+#: views/addons/home.thtml:185
+#, fuzzy
+msgid "addons_home_collections_addon_count"
+msgid_plural "addons_home_collections_addon_count"
+msgstr[0] "<strong>%1$s</strong> add-on"
+msgstr[1] "<strong>%1$s</strong> add-ons"
+
+#: views/addons/home.thtml:196
+#, fuzzy
+msgid "addons_home_collections_all"
+msgstr "View All Collections"
+
+#: views/addons/home.thtml:162
+#, fuzzy
+msgid "addons_home_collections_intro"
+msgstr ""
+"Collections are a way for you to categorize, mix, match and mingle add-ons. "
+"Subscribe to collections created by other users or create your own."
+
+#. %1$s is the count of subscribers for a collection
+#: views/elements/amo2009/collection_listing_item.thtml:58
+#: views/collections/detail.thtml:96 views/addons/home.thtml:189
+#, fuzzy
+msgid "addons_home_collections_subscribers"
+msgid_plural "addons_home_collections_subscribers"
+msgstr[0] "<strong>%1$s</strong> subscriber"
+msgstr[1] "<strong>%1$s</strong> subscribers"
+
+#: views/addons/searchengines.thtml:54 views/addons/themes_landing.thtml:49
+msgid "addons_home_feature_head"
+msgstr "Recomendamos"
+
+#: controllers/search_controller.php:218 controllers/addons_controller.php:176
+#: controllers/addons_controller.php:428 controllers/addons_controller.php:671
+#: controllers/addons_controller.php:871
+#: controllers/addons_controller.php:1103
+#: controllers/addons_controller.php:1242
+#: controllers/addons_controller.php:1298
+#, php-format
+msgid "addons_home_header_details"
+msgstr ""
+"Los complementos amplían %1$s, permitiéndote personalizar su "
+"funcionamiento. Echa un vistazo y crea tu propio %1$s."
+
+#. %1$s is the HTML collection name link.
+#: views/elements/amo2009/teaser_collections.thtml:107
+#, fuzzy
+msgid "addons_home_introduction_collection_link"
+msgstr "Like these? Find more add-ons in %1$s."
+
+#: views/elements/amo2009/teaser_collections.thtml:60
+#, fuzzy
+msgid "addons_home_introduction_extras"
+msgstr ""
+"<strong>Over 5000 free extras</strong> that let you customize and extend "
+"Firefox to meet your needs."
+
+#: views/elements/amo2009/teaser_collections.thtml:55
+#, fuzzy
+msgid "addons_home_introduction_header"
+msgstr "What are Add-ons?"
+
+#: views/elements/amo2009/teaser_collections.thtml:72
+#, fuzzy
+msgid "addons_home_introduction_install"
+msgstr ""
+"<strong>Easy to install</strong>, get notified when updates are available."
+
+#: views/elements/amo2009/teaser_collections.thtml:45
+#, fuzzy
+msgid "addons_home_introduction_name"
+msgstr "Introduction"
+
+#: views/elements/amo2009/teaser_collections.thtml:66
+#, fuzzy
+msgid "addons_home_introduction_themes"
+msgstr ""
+"Toolbars, themes and search providers that <strong>help you perform common "
+"tasks.</strong>"
+
+#: views/addons/home.thtml:161
+#, fuzzy
+msgid "addons_home_new_indicator"
+msgstr "NEW!"
+
+#: views/elements/app_chooser.thtml:48 views/layouts/amo2009.thtml:257
+msgid "addons_home_other_applications"
+msgstr "Otras aplicaciones"
+
+#. %1$s is the application the user is browsing. Examples: Thunderbird, Firefox,
+#. Sunbird
+#: views/pages/collector_faq.thtml:49 views/pages/collector_firstrun.thtml:42
+#: views/pages/collector.thtml:46 views/pages/collector_features.thtml:54
+#: controllers/developers_controller.php:87
+#: controllers/compatibility_controller.php:72
+#: controllers/components/simple_acl.php:81 controllers/components/amo.php:607
+#: controllers/statistics_controller.php:60
+#: controllers/statistics_controller.php:240
+#: controllers/previews_controller.php:67 controllers/users_controller.php:90
+#: controllers/users_controller.php:223 controllers/users_controller.php:330
+#: controllers/users_controller.php:414 controllers/users_controller.php:708
+#: controllers/users_controller.php:723 controllers/reviews_controller.php:204
+#: controllers/reviews_controller.php:251
+#: controllers/reviews_controller.php:346
+#: controllers/reviews_controller.php:425
+#: controllers/search_controller.php:185 controllers/search_controller.php:297
+#: controllers/search_controller.php:301 controllers/addons_controller.php:147
+#: controllers/addons_controller.php:280 controllers/addons_controller.php:370
+#: controllers/addons_controller.php:667 controllers/addons_controller.php:874
+#: controllers/addons_controller.php:1019
+#: controllers/addons_controller.php:1034
+#: controllers/addons_controller.php:1101
+#: controllers/addons_controller.php:1121
+#: controllers/addons_controller.php:1240
+#: controllers/addons_controller.php:1357
+#: controllers/addons_controller.php:1364
+#: controllers/addons_controller.php:1442
+#: controllers/addons_controller.php:1477
+#: controllers/addons_controller.php:1538
+#: controllers/addons_controller.php:1543
+#: controllers/editors_controller.php:64 controllers/pages_controller.php:132
+#: controllers/groups_controller.php:65 controllers/groups_controller.php:71
+#: controllers/groups_controller.php:89 controllers/groups_controller.php:111
+#: controllers/collections_controller.php:57
+#: controllers/collections_controller.php:121
+#: controllers/collections_controller.php:205
+#: controllers/collections_controller.php:365
+#: controllers/collections_controller.php:404
+#: controllers/collections_controller.php:466
+#: controllers/collections_controller.php:538
+#: controllers/collections_controller.php:828
+#: controllers/localizers_controller.php:72
+#, php-format
+msgid "addons_home_pagetitle"
+msgstr "Complementos para %1$s"
+
+#. %1$s is the number of addons downloaded
+#: views/addons/home.thtml:57
+#, fuzzy, php-format
+msgid "addons_home_stats_downloaded"
+msgid_plural "addons_home_stats_downloaded"
+msgstr[0] "<strong>%1$s</strong> <span>add-on downloaded</span>"
+msgstr[1] "<strong>%1$s</strong> <span>add-ons downloaded</span>"
+
+#. %1$s is the number of addons in use
+#: views/addons/home.thtml:63
+#, fuzzy, php-format
+msgid "addons_home_stats_inuse"
+msgid_plural "addons_home_stats_inuse"
+msgstr[0] "<strong>%1$s</strong> <span>add-on in use</span>"
+msgstr[1] "<strong>%1$s</strong> <span>add-ons in use</span>"
+
+#: views/addons/home.thtml:136
+msgid "addons_home_view_all_newest_title"
+msgstr "Ver todos los complementos nuevos"
+
+#: views/addons/home.thtml:129
+msgid "addons_home_view_all_popular_title"
+msgstr "Ver todos los complementos populares"
+
+#: views/addons/home.thtml:150
+msgid "addons_home_view_all_recommended_title"
+msgstr "Ver todos los complementos recomendados"
+
+#: views/addons/home.thtml:143
+msgid "addons_home_view_all_updated_title"
+msgstr "Ver todos los complementos actualizados recientemente"
+
+#: views/elements/amo2009/install.thtml:334 views/elements/install.thtml:112
+msgid "addons_install_in_sunbird"
+msgstr ""
+"<ol><li>Haz clic en el enlace a continuación para guardar el archivo.</"
+"li><li>En Mozilla Sunbird, abre Complementos desde el menú Herramientas.</"
+"li><li>Haz clic en el botón Instalar, localiza/selecciona el archivo que "
+"descargaste y pulsa sobre \"OK\".</li></ol>"
+
+#: views/elements/amo2009/install.thtml:333 views/elements/install.thtml:111
+msgid "addons_install_in_sunbird_title"
+msgstr "Cómo instalar en Sunbird"
+
+#: views/elements/amo2009/install.thtml:331 views/elements/install.thtml:106
+msgid "addons_install_in_thunderbird"
+msgstr ""
+"<ol><li>Haz clic con el botón secundario sobre el enlace a continuación y "
+"elige \"Guardar enlace como...\" para descargar y guardar el archivo a tu "
+"disco duro.</li><li>En Mozilla Thunderbird, abre Complementos desde el menú "
+"Herramientas.</li><li>Haz clic en el botón Instalar, selecciona el archivo "
+"que descargaste y haz clic en \"Aceptar\".</li></ol>"
+
+#: views/elements/amo2009/install.thtml:330 views/elements/install.thtml:105
+msgid "addons_install_in_thunderbird_title"
+msgstr "Cómo instalar en Thunderbird"
+
+#: views/elements/amo2009/addon_list_options.thtml:108
+#: views/elements/addon_list_options.thtml:105
+msgid "addons_options_show_experimental"
+msgstr "Ver los complementos experimentales"
+
+#: views/elements/amo2009/addon_list_options.thtml:113
+#: views/elements/addon_list_options.thtml:109
+msgid "addons_options_submit"
+msgstr "Ir"
+
+#: views/addons/plugins.thtml:63 views/addons/plugins.thtml:73
+#: views/addons/plugins.thtml:83 views/addons/plugins.thtml:93
+#: views/addons/plugins.thtml:103 views/addons/plugins.thtml:116
+#: views/addons/plugins.thtml:126
+msgid "addons_plugins_by"
+msgstr "Por"
+
+#: views/addons/plugins.thtml:107
+msgid "addons_plugins_for_linux"
+msgstr "para Linux"
+
+#: views/addons/plugins.thtml:108 views/addons/plugins.thtml:131
+msgid "addons_plugins_for_macosx"
+msgstr "para Mac OS X"
+
+#: views/addons/plugins.thtml:106 views/addons/plugins.thtml:129
+#: views/addons/plugins.thtml:130
+msgid "addons_plugins_for_windows"
+msgstr "para Windows"
+
+#. %1$s is a URL
+#: views/addons/plugins.thtml:139
+#, php-format
+msgid "addons_plugins_looking_for_more"
+msgstr ""
+"Esta página solo contiene una lista de los plugins más comunes y populares. "
+"Para más información sobre otros plugins disponibles para los navegadores "
+"basados en Mozilla, visite %1$s"
+
+#: views/addons/plugins.thtml:137
+msgid "addons_plugins_looking_for_plugin"
+msgstr "¿Busca un plugin que no se encuentra en esta lista?"
+
+#: views/addons/plugins.thtml:58
+msgid "addons_plugins_main_description"
+msgstr ""
+"Los plugins permiten a tu navegador realizar funciones específicas como ver "
+"gráficos en formatos especiales o reproducir archivos multimedia. Los "
+"plugins algo diferentes a las extensiones, las cuales modifican o añaden "
+"funcionalidades existentes."
+
+#. %1$s is the application name. Example: Firefox, Thunderbird, Sunbird
+#: controllers/addons_controller.php:1122
+#, php-format
+msgid "addons_plugins_main_header"
+msgstr "Plugins comunes para %1$s"
+
+#: controllers/components/amo.php:698 controllers/addons_controller.php:1121
+msgid "addons_plugins_pagetitle"
+msgstr "Plugins"
+
+#: views/addons/plugins.thtml:68 views/addons/plugins.thtml:78
+#: views/addons/plugins.thtml:88 views/addons/plugins.thtml:98
+#: views/addons/plugins.thtml:110 views/addons/plugins.thtml:121
+#: views/addons/plugins.thtml:133
+msgid "addons_plugins_support_documentation"
+msgstr "Documentación de ayuda: "
+
+#. %s is the name of the add-on
+#: views/addons/policy.thtml:61
+#, php-format
+msgid "addons_policy_eula_require"
+msgstr ""
+"%s requiere que aceptes el siguiente contrato de licencia para usuarios "
+"antes de que se proceda a su instalación:"
+
+#. %1 is the add-on name
+#: controllers/addons_controller.php:1476
+#, php-format
+msgid "addons_previews_pagetitle"
+msgstr "Capturas de %s"
+
+#: views/addons/category_landing.thtml:135
+msgid "addons_recently_added"
+msgstr "Añadido recientemente"
+
+#: views/addons/recommended.thtml:51 controllers/addons_controller.php:1365
+msgid "addons_recommended_introduction"
+msgstr ""
+"Con más de mil complementos disponibles, hay uno para cada persona. Para "
+"comenzar, aquí hay una lista de algunos de nuestros favoritos. ¡Disfrute!"
+
+#: controllers/addons_controller.php:1357
+#: controllers/addons_controller.php:1364
+msgid "addons_recommended_pagetitle"
+msgstr "Complementos recomendados"
+
+#: controllers/addons_controller.php:1360
+msgid "addons_recommended_title"
+msgstr "Complementos recomendados"
+
+#: views/addons/searchengines.thtml:136
+msgid "addons_searchengines_additional_resources"
+msgstr "Recursos adicionales"
+
+#. link text devmo
+#: views/addons/searchengines.thtml:141
+msgid "addons_searchengines_devmo_link"
+msgstr "Mozilla Developer Center"
+
+#: views/pages/js_constants.js.thtml:67
+msgid "addons_searchengines_error_mozilla_browser_required"
+msgstr ""
+"Lo lamento, necesitas tener un navegador basado en Mozilla (como Firefox) "
+"para instalar un plugin de búsqueda."
+
+#: views/addons/searchengines.thtml:49
+msgid "addons_searchengines_error_nojavascript"
+msgstr ""
+"JavaScript is required to install plugins, but it looks like you have it "
+"disabled. Please enable JavaScript before trying to install any of the "
+"search plugins below."
+
+#. %1 is "make your own" link
+#. %2 is MDC link
+#: views/addons/searchengines.thtml:139
+msgid "addons_searchengines_learn_howto"
+msgstr "Aprende como %1$s en el %2$s."
+
+#. link path to search plugins instructions, relative to devmo
+#: views/addons/searchengines.thtml:140
+msgid "addons_searchengines_makeyourown_href"
+msgstr "/es/docs/Creación_de_plugins_OpenSearch_para_Firefox"
+
+#. link text for "make your own" (opensearch engine)
+#: views/addons/searchengines.thtml:140
+msgid "addons_searchengines_makeyourown_link"
+msgstr "hacer el tuyo propio"
+
+#. %1 is the link to mycroft.mozdev.org
+#: views/addons/searchengines.thtml:138
+msgid "addons_searchengines_more"
+msgstr "Descubre más motores de búsqueda en %1$s"
+
+#. link text to mycroft.mozdev.org
+#: views/addons/searchengines.thtml:138
+msgid "addons_searchengines_mycroft_link"
+msgstr "mycroft.mozdev.org"
+
+#: controllers/addons_controller.php:1100
+#: controllers/addons_controller.php:1110
+msgid "addons_searchengines_pagetitle"
+msgstr "Motores de búsqueda"
+
+#: views/addons/searchengines.thtml:143
+msgid "addons_searchengines_thanks"
+msgstr ""
+"Gracias en especial al proyecto Mycroft por su trabajo en los motores de "
+"búsqueda de Firefox."
+
+#: views/addons/display.thtml:154
+msgid "addons_share_button_text"
+msgstr "Compartir"
+
+#: controllers/addons_controller.php:89
+msgid "addons_share_label_delicious"
+msgstr "Añador a Delicious"
+
+#: controllers/addons_controller.php:77
+msgid "addons_share_label_digg"
+msgstr "¡Enviar a Digg!"
+
+#: controllers/addons_controller.php:83
+msgid "addons_share_label_facebook"
+msgstr "Publicar en Facebook"
+
+#: controllers/addons_controller.php:101
+msgid "addons_share_label_friendfeed"
+msgstr "Compartir en FriendFeed"
+
+#: controllers/addons_controller.php:95
+msgid "addons_share_label_myspace"
+msgstr "Publicar en MySpace"
+
+#: controllers/components/amo.php:201 controllers/components/amo.php:229
+msgid "addons_status_disabled"
+msgstr "Desactivado"
+
+#: controllers/components/amo.php:191 controllers/components/amo.php:224
+msgid "addons_status_incomplete"
+msgstr "Versión incompleta"
+
+#: controllers/components/amo.php:197 controllers/components/amo.php:227
+msgid "addons_status_nominated"
+msgstr "En el área de pruebas; En propuestas públicas"
+
+#: views/pages/js_constants.js.thtml:80 controllers/components/amo.php:195
+#: controllers/components/amo.php:226
+msgid "addons_status_pending"
+msgstr "En el área de pruebas; Pendiente de valoración"
+
+#: views/pages/js_constants.js.thtml:78 controllers/components/amo.php:199
+#: controllers/components/amo.php:228
+msgid "addons_status_public"
+msgstr "Público"
+
+#: views/pages/js_constants.js.thtml:79 controllers/components/amo.php:193
+#: controllers/components/amo.php:225
+msgid "addons_status_sandbox"
+msgstr "En el área de pruebas"
+
+#: controllers/components/amo.php:203
+msgid "addons_status_unknown"
+msgstr "Desconocido"
+
+#: views/elements/amo2009/teaser_collections.thtml:91
+#: views/elements/amo2009/homepage_addon.thtml:99
+#: views/elements/feature.thtml:94
+msgid "addons_title_tooltip"
+msgstr "Descubre más sobre este complemento"
+
+#: views/addons/category_landing.thtml:151
+msgid "addons_top_downloads"
+msgstr "Más descargados"
+
+#: views/addons/category_landing.thtml:165
+msgid "addons_top_rated"
+msgstr "Mejor valorados"
+
+#: views/addons/versions.thtml:62
+msgid "addons_versions_careful"
+msgstr "Ten cuidado con las versiones antiguas"
+
+#: views/addons/versions.thtml:63
+msgid "addons_versions_careful_introduction"
+msgstr ""
+"Estas versiones se muestran como referencia y para pruebas. Debes usar "
+"siempre la última versión del complemento."
+
+#: controllers/addons_controller.php:1549
+msgid "addons_versions_history"
+msgstr "Historial de la versión con las listas de cambios"
+
+#. %1$s is the add-on name
+#: controllers/addons_controller.php:1535
+#, php-format
+msgid "addons_versions_pagetitle"
+msgstr "Historial de las versiones de %1$s"
+
+#: controllers/groups_controller.php:71
+msgid "admin_group_add_pagetitle"
+msgstr "Añadir grupo"
+
+#: controllers/groups_controller.php:111
+msgid "admin_group_delete_pagetitle"
+msgstr "Borrar grupo"
+
+#. %s is a number to identify the group
+#: controllers/groups_controller.php:117
+#, php-format
+msgid "admin_group_deleted"
+msgstr "El grupo con identificador %s fue borrado"
+
+#: controllers/groups_controller.php:89
+msgid "admin_group_edit_pagetitle"
+msgstr "Editar grupo"
+
+#: controllers/groups_controller.php:92 controllers/groups_controller.php:113
+msgid "admin_group_error_invalid_id"
+msgstr "Identificador no valido para el grupo"
+
+#: controllers/groups_controller.php:65
+msgid "admin_group_pagetitle"
+msgstr "Grupo administradores"
+
+#: controllers/groups_controller.php:77 controllers/groups_controller.php:99
+msgid "admin_group_saved"
+msgstr "El grupo ha sido guardado"
+
+#: views/elements/amo2009/search.thtml:257 views/elements/search.thtml:239
+msgid "advanced_search_form"
+msgstr "Avanzado"
+
+#: views/elements/amo2009/search.thtml:126 views/elements/search.thtml:125
+msgid "advanced_search_form_any_time"
+msgstr "Cualquier fecha"
+
+#: views/elements/amo2009/search.thtml:97
+#: views/elements/amo2009/search.thtml:110 views/elements/search.thtml:96
+#: views/elements/search.thtml:109
+msgid "advanced_search_form_any_type"
+msgstr "Cualquiera"
+
+#: views/elements/amo2009/search.thtml:275 views/elements/search.thtml:254
+msgid "advanced_search_form_any_version"
+msgstr "Cualquiera"
+
+#: views/elements/amo2009/search.thtml:217 views/elements/search.thtml:212
+msgid "advanced_search_form_application"
+msgstr "Aplicación"
+
+#: views/elements/amo2009/search.thtml:143 views/elements/search.thtml:142
+msgid "advanced_search_form_keyword_match"
+msgstr "Coincidencia por palabra"
+
+#: views/elements/amo2009/search.thtml:251 views/elements/search.thtml:225
+msgid "advanced_search_form_lastupdate"
+msgstr "Últimos actualizados"
+
+#: views/elements/amo2009/search.thtml:145 views/elements/search.thtml:144
+msgid "advanced_search_form_name"
+msgstr "Nombre"
+
+#: views/elements/amo2009/search.thtml:144 views/elements/search.thtml:143
+msgid "advanced_search_form_newest"
+msgstr "Más recientes"
+
+#: views/elements/amo2009/search.thtml:130 views/elements/search.thtml:129
+msgid "advanced_search_form_past_3_months"
+msgstr "Últimos 3 meses"
+
+#: views/elements/amo2009/search.thtml:131 views/elements/search.thtml:130
+msgid "advanced_search_form_past_6_months"
+msgstr "Últimos 6 meses"
+
+#: views/elements/amo2009/search.thtml:127 views/elements/search.thtml:126
+msgid "advanced_search_form_past_day"
+msgstr "Último día"
+
+#: views/elements/amo2009/search.thtml:129 views/elements/search.thtml:128
+msgid "advanced_search_form_past_month"
+msgstr "Último mes"
+
+#: views/elements/amo2009/search.thtml:128 views/elements/search.thtml:127
+msgid "advanced_search_form_past_week"
+msgstr "Última semana"
+
+#: views/elements/amo2009/search.thtml:132 views/elements/search.thtml:131
+msgid "advanced_search_form_past_year"
+msgstr "Último año"
+
+#: views/elements/amo2009/search.thtml:239 views/elements/search.thtml:230
+msgid "advanced_search_form_perpage"
+msgstr "Por página"
+
+#: views/elements/amo2009/search.thtml:243 views/elements/search.thtml:224
+msgid "advanced_search_form_platform"
+msgstr "Plataforma"
+
+#: views/elements/amo2009/search.thtml:147 views/elements/search.thtml:146
+msgid "advanced_search_form_popularity"
+msgstr "Popularidad"
+
+#: views/elements/amo2009/search.thtml:146 views/elements/search.thtml:145
+msgid "advanced_search_form_rating"
+msgstr "Puntuación"
+
+#: views/elements/amo2009/search.thtml:247 views/elements/search.thtml:231
+msgid "advanced_search_form_sortby"
+msgstr "Ordenar por"
+
+#: views/elements/amo2009/search.thtml:227 views/elements/search.thtml:216
+msgid "advanced_search_form_to"
+msgstr "a"
+
+#: views/elements/amo2009/search.thtml:257 views/elements/search.thtml:237
+msgid "advanced_search_form_toggle_tooltip"
+msgstr "Cambiar al modo de búsqueda avanzado"
+
+#: views/elements/amo2009/search.thtml:235 views/elements/search.thtml:223
+msgid "advanced_search_form_type"
+msgstr "Tipo"
+
+#: views/elements/amo2009/search.thtml:222 views/elements/search.thtml:214
+msgid "advanced_search_form_version"
+msgstr "versión"
+
+#: views/elements/amo2009/pagination.thtml:42
+#, fuzzy
+msgid "amo2009_pagination_next_page"
+msgstr "Next"
+
+#: views/elements/amo2009/pagination.thtml:41
+#, fuzzy
+msgid "amo2009_pagination_previous_page"
+msgstr "Prev"
+
+#: views/pages/js_constants.js.thtml:96
+msgid "app_compat_ignore_check"
+msgstr "Ignorar la comprobación"
+
+#: views/pages/js_constants.js.thtml:72
+msgid "app_compat_older_firefox_only"
+msgstr "Este complemento es para versiones antiguas de Firefox"
+
+#. %1$s and %2$s are URLs
+#: views/pages/js_constants.js.thtml:74
+msgid "app_compat_older_version_or_ignore_check"
+msgstr ""
+"Puedes <a href=\"%1$s\">probar una versión más antigua</a> o <a href=\"#\" "
+"onclick=\"%2$s\">ignorar esta comprobación</a>"
+
+#. %1$s is a URL
+#: views/pages/js_constants.js.thtml:71
+msgid "app_compat_try_old_version"
+msgstr "Puede que funcione una <a href=\"%1$s\">versión más antigua</a>"
+
+#. %1$s is a URL
+#. %2$s is a version number. Example: 3.1
+#: views/pages/js_constants.js.thtml:73
+msgid "app_compat_unreleased_version"
+msgstr ""
+"Este complemento requiere la versión aún no publicada de <a href=\"%1$s"
+"\">Firefox %2$s</a>"
+
+#: views/pages/js_constants.js.thtml:70
+msgid "app_compat_update_firefox"
+msgstr ""
+"<a href=\"http://getfirefox.com\">Actualiza Firefox</a> para usar este "
+"complemento"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#. %3$s is a status, like Public.
+#: controllers/components/audit.php:79
+msgid "audit_addon_status"
+msgstr "%1$s ha cambiado el estado de %2$s a %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:221
+msgid "audit_admin_default"
+msgstr ""
+"%1$s ha realizado una acción administrativa desconocida %2$s en el ID %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:153
+msgid "audit_admin_feature_remove"
+msgstr "%1$s ha borrado la característica %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is an application, like Firefox.
+#: controllers/components/audit.php:92
+msgid "audit_application_create"
+msgstr "%1$s ha creado la aplicación %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is an application, like Firefox.
+#: controllers/components/audit.php:95
+msgid "audit_application_edit"
+msgstr "%1$s ha editado la aplicación %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a version number, like 3.5.
+#. %3$s is an application, like Firefox.
+#: controllers/components/audit.php:105
+msgid "audit_appversion_create"
+msgstr "%1$s ha creado la versión %2$s de %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a version number, like 3.5.
+#. %3$s is an application, like Firefox.
+#: controllers/components/audit.php:108
+msgid "audit_appversion_delete"
+msgstr "%1$s ha borrado la versión %2$s de %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a config field, like "awesomeness".
+#. %3$s is a config value, like "off".
+#. %4$s is a config value, like "on".
+#: controllers/components/audit.php:210
+msgid "audit_config"
+msgstr "%1$s ha cambiado al configuración '%2$s' de '%3$s' a '%4$s'"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:258
+msgid "audit_editor_default"
+msgstr "%1$s ha realizado una acción de edición desconocida %2$s al ID %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#: controllers/components/audit.php:236
+msgid "audit_editor_feature_remove"
+msgstr "%1$s ha borrado el complemento %2$s de la lista de características"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#: controllers/components/audit.php:231
+msgid "audit_feature_add"
+msgstr "%1$s ha añadido el complemento %2$s a la lista de características"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:149
+msgid "audit_feature_edit"
+msgstr "%1$s ha cambiado una característica para el idioma %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#: controllers/components/audit.php:241
+msgid "audit_feature_locale_change"
+msgstr ""
+"%1$s ha cambiado los idiomas del complemento %2$s en la lista de "
+"características"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:83
+msgid "audit_file_recalchash"
+msgstr "%1$s ha recalculado el hash del archivo %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>user name</a>
+#. %3$s is <a>group name</a>
+#: controllers/components/audit.php:182
+msgid "audit_group_addmember"
+msgstr "%1$s ha añadido %2$s al grupo %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:313
+msgid "audit_group_associated"
+msgstr "%1$s los ha asociado con %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:162
+msgid "audit_group_create"
+msgstr "%1s ha creado el grupo %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:170
+msgid "audit_group_delete"
+msgstr "%1$s ha borrado el grupo %2$s (ID %3$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:165
+msgid "audit_group_edit"
+msgstr "%1$s ha editado el grupo %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>user name</a>
+#. %3$s is <a>group name</a>
+#: controllers/components/audit.php:188
+msgid "audit_group_removemember"
+msgstr "%1$s ha borrado %2$s del grupo %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:280
+msgid "audit_l10n_default"
+msgstr "%1$s ha realizado una acción desconocida %2$s en %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:295
+msgid "audit_modify_locked_group"
+msgstr "%1$s ha intentado modificar el grupo bloqueado %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:299
+msgid "audit_modify_other_locale"
+msgstr "%1$s ha intentado modificar las traducciones en %2$s sin permiso"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a platform, like <a>Windows</a>
+#: controllers/components/audit.php:135
+msgid "audit_platform_create"
+msgstr "%1$s ha creado la plataforma %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a platform, like <a>Windows</a>
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:143
+msgid "audit_platform_delete"
+msgstr "%1$s ha borrado la plataforma %2$s (ID %3$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a platform, like <a>Windows</a>
+#: controllers/components/audit.php:138
+msgid "audit_platform_edit"
+msgstr "%1$s ha editado la plataforma %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a part of the admin, like 'Site Config'
+#: controllers/components/audit.php:288
+msgid "audit_reauthentication_failure"
+msgstr "%1$s ha fallado al volver a autenticar para acceder a %2$s."
+
+#. %1$s is <a>user name</a>
+#. %2$s is the name of a canned response, like 'Ready for the public'
+#: controllers/components/audit.php:198
+msgid "audit_response_create"
+msgstr "%1$s ha creado la respuesta %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is the name of a canned response, like 'Ready for the public'
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:206
+msgid "audit_response_delete"
+msgstr "%1$s ha borrado la respuesta %2$s (ID %3$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is the name of a canned response, like 'Ready for the public'
+#: controllers/components/audit.php:201
+msgid "audit_response_edit"
+msgstr "%1$s ha editado la respuesta %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:245
+msgid "audit_review_approve"
+msgstr "%1$s ha aprobado la revisión %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:250 controllers/components/audit.php:253
+msgid "audit_review_delete"
+msgstr "%1$s ha borrado la previsión %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:303
+msgid "audit_security_default"
+msgstr "%1$s ha realizado una acción de seguridad desconocida %2$s al ID %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a category name, like <a>Search Tools</a>
+#: controllers/components/audit.php:118
+msgid "audit_tag_create"
+msgstr "%1$s ha creado la etiqueta %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a category name, like <a>Search Tools</a>
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:126
+msgid "audit_tag_delete"
+msgstr "%1$s ha borrado la categoría %2$s (ID %3$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a category name, like <a>Search Tools</a>
+#: controllers/components/audit.php:121
+msgid "audit_tag_edit"
+msgstr "%1$s ha editado la categoría %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:266
+msgid "audit_update_applications"
+msgstr "%1$s ha actualizado las traducciones de la aplicación para %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:277
+msgid "audit_update_blog"
+msgstr "%1$s ha actualizado las traducciones del blog para %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:274
+msgid "audit_update_platforms"
+msgstr "%1$s ha actualizado las traducciones de la plataforma para %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:270
+msgid "audit_update_tags"
+msgstr "%1$s ha actualizado las traducciones de la categoría para %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>user name</a>
+#: controllers/components/audit.php:217
+msgid "audit_user_edit"
+msgstr "%1$s ha editado la información del usuario %2$s"
+
+#: controllers/addons_controller.php:1012
+msgid "browse_addons_name"
+msgstr "Complementos por nombre"
+
+#: controllers/addons_controller.php:1010
+msgid "browse_addons_newest"
+msgstr "Complementos nuevos"
+
+#: controllers/addons_controller.php:1008
+msgid "browse_addons_popular"
+msgstr "Complementos populares"
+
+#: controllers/addons_controller.php:1011
+msgid "browse_addons_rated"
+msgstr "Complementos por puntuación"
+
+#: controllers/addons_controller.php:1009
+msgid "browse_addons_updated"
+msgstr "Complementos actualizados recientemente"
+
+#: views/elements/categories.thtml:73 views/elements/categories.thtml:82
+msgid "categories_current_title"
+msgstr "Categoría actual"
+
+#: views/elements/categories.thtml:50
+#: views/elements/amo2009/categories.thtml:43
+#: views/elements/amo2009/categories.thtml:45
+msgid "categories_header"
+msgstr "Categorías"
+
+#: views/elements/categories.thtml:50
+#: views/elements/amo2009/categories.thtml:41
+msgid "categories_header_title"
+msgstr "Elige una categoría"
+
+#. %1$s is the category name
+#: views/addons/searchengines.thtml:129
+#, php-format
+msgid "category_extra_see_all"
+msgstr "Ver todos en %1$s"
+
+#. %1$s is a number.
+#: models/collection.php:130
+msgid "collection_description_limit"
+msgstr "La descripción debe tener menos de %1$s caracteres."
+
+#. %1$s is the name of the collection
+#: controllers/collections_controller.php:392
+#, fuzzy
+msgid "collection_detail_rss_title"
+msgstr "%s Collection"
+
+#: controllers/collections_controller.php:1065
+#, fuzzy
+msgid "collection_error_deleting_addon"
+msgstr "Error deleting add-on!"
+
+#: controllers/collections_controller.php:1051
+#, fuzzy
+msgid "collection_error_saving_addon"
+msgstr "Error saving add-on!"
+
+#: controllers/collections_controller.php:1080
+#, fuzzy
+msgid "collection_error_saving_comment"
+msgstr "Error saving comment!"
+
+#. %1$s is a number.
+#: models/collection.php:122
+#, fuzzy
+msgid "collection_name_limit"
+msgstr "The name should be less than %1$s characters."
+
+#: controllers/collections_controller.php:352
+#: controllers/collections_controller.php:487
+msgid "collection_not_found"
+msgstr "¡Colección no encontrada!"
+
+#. %1$s is the text on the "create collection" button
+#: views/collections/add.thtml:91
+#, fuzzy
+msgid "collections_add_formfield_addons_description"
+msgstr ""
+"If you already know which add-ons you want to add to your collection, just "
+"start typing their names below. If you'd rather wait and do this later, just "
+"click %1$s now."
+
+#: views/collections/add.thtml:90
+#, fuzzy
+msgid "collections_add_formfield_firstaddons"
+msgstr "Choose your first add-ons"
+
+#: views/collections/add.thtml:48
+#, fuzzy
+msgid "collections_add_header"
+msgstr "Create a Collection"
+
+#: views/collections/add.thtml:97
+#, fuzzy
+msgid "collections_add_header_selectedaddons"
+msgstr "Selected Add-ons"
+
+#: views/collections/add.thtml:50
+#, fuzzy
+msgid "collections_add_intro"
+msgstr ""
+"It's easy to create your own collection of add-ons by filling in a few "
+"fields below."
+
+#: views/collections/add.thtml:92 views/collections/add.thtml:103
+#, fuzzy
+msgid "collections_add_submit"
+msgstr "Create Collection"
+
+#: views/pages/collector_faq.thtml:50 views/pages/collector_firstrun.thtml:43
+#: views/pages/collector.thtml:47 views/pages/collector_features.thtml:55
+#: controllers/search_controller.php:302
+#: controllers/collections_controller.php:206
+#: controllers/collections_controller.php:405
+#: controllers/collections_controller.php:467
+#: controllers/collections_controller.php:539
+#, fuzzy
+msgid "collections_breadcrumb"
+msgstr "Collections"
+
+#: views/collections/detail.thtml:185
+#, fuzzy
+msgid "collections_detail_a_learn"
+msgstr "Learn More"
+
+#: views/elements/amo2009/collection_add_form.thtml:53
+#: views/elements/amo2009/collections_js_init.thtml:68
+#: views/pages/collector_firstrun.thtml:64
+#, fuzzy
+msgid "collections_detail_button_add"
+msgstr "Add to Favorites"
+
+#: views/elements/amo2009/collection_add_form.thtml:50
+#: views/elements/amo2009/collections_js_init.thtml:71
+#, fuzzy
+msgid "collections_detail_button_remove"
+msgstr "Remove from Favorites"
+
+#. %1$s is a URL.
+#. %2$s is a full <a href>.
+#: views/collections/detail.thtml:62
+#, fuzzy
+msgid "collections_detail_created_desc"
+msgstr ""
+"<p>You can view your new collection below. If you'd like to set a collection "
+"nickname, upload an icon, or change additional settings, please visit the <a "
+"href='%1$s'>Manage Collections</a> page.</p><p>Your collection can be "
+"accessed at this location: %2$s</p>"
+
+#: views/collections/detail.thtml:61
+#, fuzzy
+msgid "collections_detail_created_msg"
+msgstr "Your collection is now ready!"
+
+#: views/collections/detail.thtml:109
+#, fuzzy
+msgid "collections_detail_header_about"
+msgstr "About This Collection"
+
+#. %1$s is a number.
+#: views/collections/detail.thtml:126
+#, fuzzy
+msgid "collections_detail_header_count"
+msgid_plural "collections_detail_header_count"
+msgstr[0] "%1$s Add-on in this Collection"
+msgstr[1] "%1$s Add-ons in this Collection"
+
+#: views/collections/detail.thtml:113
+#, fuzzy
+msgid "collections_detail_info_created"
+msgstr "<strong>Created by:</strong> %1$s"
+
+#: views/collections/detail.thtml:117
+#, fuzzy
+msgid "collections_detail_info_updated"
+msgstr "<strong>Updated:</strong>"
+
+#: views/elements/amo2009/collections_js_init.thtml:62
+#, fuzzy
+msgid "collections_detail_js_adding"
+msgstr "Adding to Favorites&hellip;"
+
+#: views/elements/amo2009/collections_js_init.thtml:65
+#, fuzzy
+msgid "collections_detail_js_removing"
+msgstr "Removing Favorite&hellip;"
+
+#. %1$s is a URL
+#: views/collections/detail.thtml:90
+#, fuzzy
+msgid "collections_detail_login"
+msgstr "<a href=\"%1$s\">Log in</a> to add this collection to your favorites."
+
+#: views/collections/detail.thtml:104
+#, fuzzy
+msgid "collections_detail_manage"
+msgstr "Manage Collection"
+
+#: controllers/collections_controller.php:298
+#, fuzzy
+msgid "collections_detail_sort_date"
+msgstr "Date Added"
+
+#: controllers/collections_controller.php:299
+#, fuzzy
+msgid "collections_detail_sort_name"
+msgstr "Name"
+
+#: controllers/collections_controller.php:300
+#, fuzzy
+msgid "collections_detail_sort_popularity"
+msgstr "Popularity"
+
+#. %1$s is a number.
+#: views/collections/detail.thtml:166
+#, fuzzy
+msgid "collections_detail_weekly_downloads"
+msgid_plural "collections_detail_weekly_downloads"
+msgstr[0] "%1$s download this week"
+msgstr[1] "%1$s downloads this week"
+
+#: views/collections/edit.thtml:255
+#, fuzzy
+msgid "collections_edit_addons_delete_noscript"
+msgstr "Selected add-ons will be removed upon Save"
+
+#: views/collections/edit.thtml:247
+#, fuzzy
+msgid "collections_edit_addons_description"
+msgstr ""
+"To publish new add-ons to this collection, start typing their names below."
+
+#: views/collections/edit.thtml:248
+#, fuzzy
+msgid "collections_edit_addons_description_noscript"
+msgstr ""
+"To publish new add-ons to this collection, enter a comma-separated list of "
+"Add-on IDs below."
+
+#: views/collections/edit.thtml:247 views/collections/edit.thtml:248
+#, fuzzy
+msgid "collections_edit_addons_description_publish_detailspage"
+msgstr "You can also publish an add-on from its normal listing page."
+
+#. %1$s is the date the add-on was added to the collection
+#. %1$s is the name of the user who added the add-on to the collection
+#: views/collections/edit.thtml:260
+#, fuzzy
+msgid "collections_edit_addons_listitem_added"
+msgstr "Added %1$s by %2$s"
+
+#: views/collections/edit.thtml:263
+#, fuzzy
+msgid "collections_edit_addons_listitem_comment_add"
+msgstr "Add publisher comment"
+
+#: views/collections/edit.thtml:266
+#, fuzzy
+msgid "collections_edit_addons_listitem_comment_delete"
+msgstr "Delete publisher comment"
+
+#: views/collections/edit.thtml:265
+#, fuzzy
+msgid "collections_edit_addons_listitem_comment_edit"
+msgstr "Edit publisher comment"
+
+#: views/collections/edit.thtml:271
+#, fuzzy
+msgid "collections_edit_addons_listitem_comment_note"
+msgstr ""
+"Note: Comment will appear as though written by original publisher on the "
+"original publication date"
+
+#: views/collections/edit.thtml:270
+#, fuzzy
+msgid "collections_edit_addons_listitem_comment_submit"
+msgstr "Save Comment"
+
+#: views/collections/edit.thtml:261
+#, fuzzy
+msgid "collections_edit_addons_listitem_remove"
+msgstr "Remove"
+
+#: views/collections/edit.thtml:250
+#, fuzzy
+msgid "collections_edit_addons_submit"
+msgstr "Add to Collection"
+
+#: views/collections/edit.thtml:153
+#, fuzzy
+msgid "collections_edit_check_nickname"
+msgstr "Check Availability"
+
+#: views/collections/edit.thtml:299
+#, fuzzy
+msgid "collections_edit_confirm_deletecollection"
+msgstr "Yes, I would like to delete this collection."
+
+#. %1$s is the label of the edit form's submit button
+#: views/collections/edit.thtml:300
+#, fuzzy
+msgid "collections_edit_confirm_deletecollection_description"
+msgstr "Check the box, then click on \"%1$s\" to delete this collection."
+
+#. %1$s is the "delete" submit button text
+#. %2$s is the title of the "advanced" tab
+#: views/collections/edit.thtml:95
+#, fuzzy
+msgid "collections_edit_delete_upon_submit"
+msgstr ""
+"Upon clicking \"%1$s\" below, your collection will be deleted. If you do not "
+"want to delete your collection, uncheck the confirmation box in the \"%2$s\" "
+"tab and continue editing your collection. If you leave this page without "
+"saving, your collection will also not be deleted."
+
+#: views/collections/edit.thtml:94
+#, fuzzy
+msgid "collections_edit_delete_warning"
+msgstr "Your collection is about to be deleted!"
+
+#: views/collections/add.thtml:76 views/collections/edit.thtml:144
+#, fuzzy
+msgid "collections_edit_form_error_description"
+msgstr "You must provide a description of your collection."
+
+#: views/collections/edit.thtml:181
+#, fuzzy
+msgid "collections_edit_form_error_icon"
+msgstr "There was an error uploading your icon."
+
+#: views/collections/add.thtml:69 views/collections/edit.thtml:130
+#, fuzzy
+msgid "collections_edit_form_error_name"
+msgstr "You must give your collection a name."
+
+#: views/collections/edit.thtml:158
+#, fuzzy
+msgid "collections_edit_form_error_nickname"
+msgstr "If you choose a nickname, it must be unique."
+
+#: views/collections/add.thtml:93 views/collections/edit.thtml:249
+#, fuzzy
+msgid "collections_edit_formfield_addons"
+msgstr "Add-on name:"
+
+#: views/collections/edit.thtml:281
+#, fuzzy
+msgid "collections_edit_formfield_application"
+msgstr "Associated Application"
+
+#: views/collections/edit.thtml:282
+#, fuzzy
+msgid "collections_edit_formfield_application_description"
+msgstr "Select the application that your collection supports."
+
+#: views/collections/edit.thtml:288
+#, fuzzy
+msgid "collections_edit_formfield_collectiontype"
+msgstr "Collection Type"
+
+#: views/collections/edit.thtml:295
+#, fuzzy
+msgid "collections_edit_formfield_deletecollection"
+msgstr "Delete Collection"
+
+#: views/collections/edit.thtml:296
+#, fuzzy
+msgid "collections_edit_formfield_deletecollection_description"
+msgstr "Deleting your collection will permanently erase it."
+
+#: views/collections/add.thtml:73 views/collections/edit.thtml:140
+#, fuzzy
+msgid "collections_edit_formfield_description"
+msgstr "Collection Description"
+
+#: views/collections/add.thtml:74 views/collections/edit.thtml:141
+#, fuzzy
+msgid "collections_edit_formfield_description_description"
+msgstr "Briefly describe your collection and the kind of add-ons in it"
+
+#: views/collections/edit.thtml:162
+#, fuzzy
+msgid "collections_edit_formfield_icon"
+msgstr "Icon"
+
+#: views/collections/edit.thtml:163
+#, fuzzy
+msgid "collections_edit_formfield_icon_description"
+msgstr ""
+"You can upload a JPG, GIF or PNG icon that will be resized to 32x32 pixels."
+
+#: views/collections/add.thtml:80 views/collections/edit.thtml:189
+#, fuzzy
+msgid "collections_edit_formfield_listed"
+msgstr "Who can view your collection?"
+
+#: views/collections/add.thtml:81 views/collections/edit.thtml:190
+#, fuzzy
+msgid "collections_edit_formfield_listed_description"
+msgstr ""
+"By default, collections appear in the public Collection Directory and are "
+"discoverable by anyone. If you want to restrict your collection to be "
+"viewable only by people who are given a special link, choose that option "
+"below."
+
+#: views/collections/add.thtml:84 views/collections/edit.thtml:193
+#, fuzzy
+msgid "collections_edit_formfield_listed_false"
+msgstr "Only people I invite can view my collection"
+
+#: views/collections/add.thtml:83 views/collections/edit.thtml:192
+#, fuzzy
+msgid "collections_edit_formfield_listed_true"
+msgstr "Everyone can view my collection in the directory"
+
+#: views/collections/edit.thtml:223
+#, fuzzy
+msgid "collections_edit_formfield_managers"
+msgstr "Who can manage my collection?"
+
+#: views/collections/edit.thtml:224
+#, fuzzy
+msgid "collections_edit_formfield_managers_description"
+msgstr ""
+"These users can publish add-ons to your collection, manage all add-ons and "
+"settings, and grant other users permission."
+
+#: views/collections/add.thtml:66 views/collections/edit.thtml:126
+#, fuzzy
+msgid "collections_edit_formfield_name"
+msgstr "Collection Name"
+
+#: views/collections/add.thtml:67 views/collections/edit.thtml:127
+#, fuzzy
+msgid "collections_edit_formfield_name_description"
+msgstr ""
+"Give your collection a descriptive name, such as \"Dave's Favorite Travel "
+"Add-ons\""
+
+#: views/collections/edit.thtml:148
+#, fuzzy
+msgid "collections_edit_formfield_nickname"
+msgstr "Collection Nickname"
+
+#: views/collections/edit.thtml:149
+#, fuzzy
+msgid "collections_edit_formfield_nickname_description"
+msgstr "Optionally, give your collection a unique nickname for quick access:"
+
+#: views/collections/edit.thtml:201
+#, fuzzy
+msgid "collections_edit_formfield_publishers"
+msgstr "Who can publish add-ons to your collection?"
+
+#: views/collections/edit.thtml:202
+#, fuzzy
+msgid "collections_edit_formfield_publishers_description"
+msgstr ""
+"These users can publish add-ons to your collection and remove add-ons that "
+"they publish."
+
+#: views/collections/edit.thtml:210 views/collections/edit.thtml:232
+#, fuzzy
+msgid "collections_edit_formfield_users_add"
+msgstr "Enter the e-mail address of a Firefox Add-ons account:"
+
+#: views/collections/edit.thtml:216 views/collections/edit.thtml:238
+#, fuzzy
+msgid "collections_edit_formfield_users_delete_noscript"
+msgstr "Selected accounts will be removed upon Save"
+
+#: views/collections/edit.thtml:215 views/collections/edit.thtml:237
+#, fuzzy
+msgid "collections_edit_formfield_users_new_noscript"
+msgstr ""
+"Enter a comma-separated list of e-mail addresses of Firefox Add-ons accounts"
+
+#: views/collections/edit.thtml:204 views/collections/edit.thtml:226
+#, fuzzy
+msgid "collections_edit_formfield_users_onlyme"
+msgstr "Only me"
+
+#: views/collections/edit.thtml:205 views/collections/edit.thtml:227
+#, fuzzy
+msgid "collections_edit_formfield_users_otherusers"
+msgstr "Myself and these users:"
+
+#: views/collections/edit.thtml:211 views/collections/edit.thtml:233
+#, fuzzy
+msgid "collections_edit_formfield_users_submit"
+msgstr "Add"
+
+#. %1$s is the name of the collection
+#: views/collections/edit.thtml:68
+#, fuzzy
+msgid "collections_edit_header"
+msgstr "Manage %1$s"
+
+#: views/collections/edit.thtml:246
+#, fuzzy
+msgid "collections_edit_header_addons"
+msgstr "Manage Collection Contents"
+
+#: views/collections/edit.thtml:253 views/collections/edit.thtml:258
+#, fuzzy
+msgid "collections_edit_header_addons_current"
+msgstr "Current Add-ons:"
+
+#: views/collections/edit.thtml:279
+#, fuzzy
+msgid "collections_edit_header_advanced"
+msgstr "Advanced Settings"
+
+#: views/collections/edit.thtml:186
+#, fuzzy
+msgid "collections_edit_header_permissions"
+msgstr "Manage Collection Permissions"
+
+#: views/collections/edit.thtml:170
+#, fuzzy
+msgid "collections_edit_icon_cancel"
+msgstr "Cancel"
+
+#: views/collections/edit.thtml:174 views/collections/edit.thtml:179
+#, fuzzy
+msgid "collections_edit_icon_delete"
+msgstr "Delete Icon"
+
+#: views/collections/edit.thtml:178
+#, fuzzy
+msgid "collections_edit_icon_replace"
+msgstr "Replace Icon"
+
+#. %1$s is the label of the edit form's submit button
+#: views/collections/edit.thtml:169
+#, fuzzy
+msgid "collections_edit_icon_toberemoved"
+msgstr "Icon will be removed when \"%1$s\" is clicked below"
+
+#: views/collections/edit.thtml:155
+#, fuzzy
+msgid "collections_edit_nickname_available"
+msgstr "Nickname Available"
+
+#: controllers/collections_controller.php:943
+#, fuzzy
+msgid "collections_edit_nickname_error"
+msgstr ""
+"Your nickname contained invalid characters and was corrected. Please try "
+"again."
+
+#: views/collections/edit.thtml:156
+#, fuzzy
+msgid "collections_edit_nickname_taken"
+msgstr "Nickname Taken"
+
+#. This string is followed by a URL pointing to the collection's view page
+#: views/collections/edit.thtml:75
+#, fuzzy
+msgid "collections_edit_saved_nextstep"
+msgstr "Your collection can be accessed at this location:"
+
+#: views/collections/edit.thtml:74
+#, fuzzy
+msgid "collections_edit_saved_success"
+msgstr "Your collection was successfully saved!"
+
+#: views/collections/edit.thtml:169 views/collections/edit.thtml:300
+#: views/collections/edit.thtml:308 views/pages/js_constants.js.thtml:99
+#, fuzzy
+msgid "collections_edit_submit"
+msgstr "Update Collection"
+
+#: views/collections/edit.thtml:96 views/collections/edit.thtml:297
+#: views/pages/js_constants.js.thtml:100
+#, fuzzy
+msgid "collections_edit_submit_deletecollection"
+msgstr "Delete Collection"
+
+#: views/collections/edit.thtml:111
+#, fuzzy
+msgid "collections_edit_tabheader_addons"
+msgstr "Add-ons"
+
+#: views/collections/edit.thtml:97 views/collections/edit.thtml:113
+#, fuzzy
+msgid "collections_edit_tabheader_advanced"
+msgstr "Advanced"
+
+#: views/collections/edit.thtml:108
+#, fuzzy
+msgid "collections_edit_tabheader_details"
+msgstr "Name &amp; Details"
+
+#: views/collections/edit.thtml:109
+#, fuzzy
+msgid "collections_edit_tabheader_permissions"
+msgstr "Permissions"
+
+#: models/collection_promo.php:53
+#, fuzzy
+msgid "collections_family_tagline"
+msgstr "Add-ons can keep an eye on your kids and your calendar."
+
+#: models/collection_promo.php:53
+#, fuzzy
+msgid "collections_family_title"
+msgstr "Family Organizer"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:70
+#, fuzzy
+msgid "collections_index_a_check_out"
+msgstr "Check out Add-on Collector"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:52
+#, fuzzy
+msgid "collections_index_a_create"
+msgstr "Create a Collection"
+
+#: views/collections/detail.thtml:139 views/collections/listing.thtml:85
+#: views/search/collections.thtml:84
+#, fuzzy
+msgid "collections_index_button_go"
+msgstr "Go"
+
+#. %1$s is a URL.
+#: controllers/collections_controller.php:182
+#, fuzzy
+msgid "collections_index_filler_favorites"
+msgstr ""
+"<p><strong>You don't have any favorite collections yet.</strong></p> "
+"<p>Collections you mark as favorites can be quickly accessed from this page, "
+"and will appear in the <a href='%1$s'>Add-on Collector</a> if you've "
+"installed it.</p>"
+
+#. %1$s is a URL.
+#: controllers/collections_controller.php:167
+#, fuzzy
+msgid "collections_index_filler_mine"
+msgstr ""
+"<p>You haven't created any collections yet. Collections are easy to create "
+"and fill with your favorite add-ons. <a href='%1$s'>Try it out</a>!</p>"
+
+#: views/collections/listing.thtml:51
+#, fuzzy
+msgid "collections_index_header_collections"
+msgstr "Collections"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:60
+#, fuzzy
+msgid "collections_index_header_collector"
+msgstr "Add-on Collector"
+
+#. %1$s is a comma-separated list of author names
+#: views/elements/amo2009/collection_listing_item.thtml:84
+#: views/collections/detail.thtml:151
+#, fuzzy
+msgid "collections_index_header_created"
+msgstr "created by %1$s"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:47
+#, fuzzy
+msgid "collections_index_header_what"
+msgstr "What are Collections?"
+
+#: views/collections/detail.thtml:132 views/collections/listing.thtml:78
+#: views/search/collections.thtml:66
+#, fuzzy
+msgid "collections_index_label_sortby"
+msgstr "Sort by"
+
+#: controllers/collections_controller.php:130
+#, fuzzy
+msgid "collections_index_li_editors"
+msgstr "Editor's Picks"
+
+#: views/collections/subscribe.thtml:64
+#: controllers/collections_controller.php:140
+#, fuzzy
+msgid "collections_index_li_favorites"
+msgstr "My Favorites"
+
+#: controllers/collections_controller.php:138
+#, fuzzy
+msgid "collections_index_li_mine"
+msgstr "My Collections"
+
+#: controllers/collections_controller.php:132
+#, fuzzy
+msgid "collections_index_li_popular"
+msgstr "Popular"
+
+#: views/search/collections.thtml:74 controllers/collections_controller.php:81
+#, fuzzy
+msgid "collections_index_option_all"
+msgstr "Most popular all time"
+
+#: views/search/collections.thtml:72 controllers/collections_controller.php:78
+#, fuzzy
+msgid "collections_index_option_month"
+msgstr "Most popular this month"
+
+#: views/search/collections.thtml:76 controllers/collections_controller.php:84
+#, fuzzy
+msgid "collections_index_option_newest"
+msgstr "Newest"
+
+#: views/search/collections.thtml:70 controllers/collections_controller.php:75
+#, fuzzy
+msgid "collections_index_option_week"
+msgstr "Most popular this week"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:67
+#, fuzzy
+msgid "collections_index_p_collector"
+msgstr ""
+"There's a new way to manage and find favorite add-ons. Comment, share and "
+"sync collections, all from your browser"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:48
+#, fuzzy
+msgid "collections_index_p_what_are"
+msgstr "Collections are groups of related add-ons assembled for easy sharing."
+
+#. %s is a date in the _('date') format
+#: views/elements/collections_interactive_addon.thtml:85
+#, php-format
+msgid "collections_interactive_addon_added"
+msgstr "Añadido %s"
+
+#: models/collection_promo.php:55
+#, fuzzy
+msgid "collections_reference_tagline"
+msgstr "Add-ons can do better research online."
+
+#: models/collection_promo.php:55
+#, fuzzy
+msgid "collections_reference_title"
+msgstr "Reference Desk"
+
+#: models/collection_promo.php:52
+#, fuzzy
+msgid "collections_social_tagline"
+msgstr "Add-ons can manage your social network."
+
+#: models/collection_promo.php:52
+#, fuzzy
+msgid "collections_social_title"
+msgstr "Social Circuit"
+
+#: views/collections/subscribe.thtml:91
+#, fuzzy
+msgid "collections_subscribe_button_close"
+msgstr "Close"
+
+#: views/collections/subscribe.thtml:70
+#, fuzzy
+msgid "collections_subscribe_error"
+msgstr ""
+"An error occurred trying to add a favorite collection. Is this collection "
+"already a favorite?"
+
+#: views/collections/subscribe.thtml:96
+#, fuzzy
+msgid "collections_subscribe_label_bothersome"
+msgstr "Don't show me this message again."
+
+#. %1$s is the collection name
+#: views/collections/subscribe.thtml:60
+#, fuzzy
+msgid "collections_subscribe_success"
+msgstr "%1$s has been added to your favorite collections."
+
+#. %1$s is the link to the "My Favorites" tab on the main collections page
+#. %2$s is the localized title of the "My Favorites" tab
+#. %3$s is the link URL to the collector add-on
+#: views/collections/subscribe.thtml:62
+#, fuzzy
+msgid "collections_subscribe_success_desc"
+msgstr ""
+"You can now quickly find this collection from the <a href=\"%1$s\">%2$s</a> "
+"tab in the directory. For an even easier way to keep track of your favorite "
+"collections, try out our <a href=\"%3$s\">Add-on Collector</a> extension for "
+"Firefox."
+
+#: views/collections/listing.thtml:55
+#, fuzzy
+msgid "collections_success_delete"
+msgstr "The collection has been deleted."
+
+#: models/collection_promo.php:54
+#, fuzzy
+msgid "collections_travel_tagline"
+msgstr "Add-ons can turn you into a travel agent."
+
+#: models/collection_promo.php:54
+#, fuzzy
+msgid "collections_travel_title"
+msgstr "The Traveler's Pack"
+
+#. A collection of add-ons that is automatically built for a user. They are "automatically published" to this collection.
+#: controllers/collections_controller.php:581
+#, fuzzy
+msgid "collections_type_autopublisher"
+msgstr "Auto-publisher"
+
+#. A collection that has been chosen by an Editor as notable or exceptional
+#: controllers/collections_controller.php:582
+#, fuzzy
+msgid "collections_type_editorspick"
+msgstr "Editor's Pick"
+
+#: controllers/collections_controller.php:580
+#, fuzzy
+msgid "collections_type_normal"
+msgstr "Normal"
+
+#: views/collections/subscribe.thtml:84
+#, fuzzy
+msgid "collections_unsubscribe_error"
+msgstr ""
+"An error occurred trying to remove a favorite collection. Was this "
+"collection not a favorite?"
+
+#. %1$s is the collection name
+#: views/collections/subscribe.thtml:78
+#, fuzzy
+msgid "collections_unsubscribe_success"
+msgstr "%1$s has been removed from your favorite collections."
+
+#: models/collection_promo.php:56
+#, fuzzy
+msgid "collections_webdev_tagline"
+msgstr "Add-ons make it easier to build the perfect website."
+
+#: models/collection_promo.php:56
+#, fuzzy
+msgid "collections_webdev_title"
+msgstr "Web Developer's Toolbox"
+
+#: views/elements/amo2009/collections_sidebar_whatare.thtml:40
+#, fuzzy
+msgid "collections_whatare_header"
+msgstr "What are Collections?"
+
+#: views/elements/amo2009/collections_sidebar_whatare.thtml:45
+#, fuzzy
+msgid "collections_whatare_learnmore"
+msgstr "Read the FAQ"
+
+#: views/elements/amo2009/collections_sidebar_whatare.thtml:44
+#, fuzzy
+msgid "collections_whatare_text"
+msgstr ""
+"There’s a new way to manage and find favorite add-ons. Comment, share and "
+"sync collections, all from your browser."
+
+#: views/pages/collector_faq.thtml:61 views/pages/collector_features.thtml:67
+#, fuzzy
+msgid "collector_features_a_home"
+msgstr "Add-on Collector Home"
+
+#: views/elements/amo2009/collector_sidebar_download.thtml:46
+#, fuzzy
+msgid "collector_features_heading_download"
+msgstr "Download the Add-on Collector:"
+
+#: views/elements/amo2009/collector_sidebar_download.thtml:43
+#: views/pages/collector_firstrun.thtml:116 views/pages/collector.thtml:69
+#, fuzzy
+msgid "collector_features_img_logo"
+msgstr "Add-on Collector Logo"
+
+#: views/compatibility/dashboard.thtml:49
+#: controllers/compatibility_controller.php:72
+msgid "compatibility_dashboard_center_header"
+msgstr "Centro de compatibilidad de complementos"
+
+#. %1$s is the name of an application and a version. Example: Firefox 3.0
+#. %2$s is the name of an application. Example: Firefox
+#: views/compatibility/dashboard.thtml:50
+msgid "compatibility_dashboard_intro"
+msgstr ""
+"Estate preparado para la publicación de %1$s con las herramientas y la "
+"información disponible para la comunidad de complementos de %2$s que "
+"encontrarás más abajo."
+
+#: views/compatibility/dashboard.thtml:103
+msgid "compatibility_dashboard_loading"
+msgstr "Cargando datos..."
+
+#: views/compatibility/dashboard.thtml:45
+msgid "compatibility_dashboard_main_link"
+msgstr "Volver al inicio"
+
+#: views/compatibility/dashboard.thtml:100 views/compatibility/report.thtml:43
+msgid "compatibility_dashboard_report"
+msgstr "Informe de compatibilidad del complemento"
+
+#: views/compatibility/dashboard.thtml:53
+#: views/compatibility/dashboard.thtml:110
+#: views/compatibility/developers.thtml:43
+msgid "compatibility_developer_info"
+msgstr "Información para desarrolladores de complementos"
+
+#: views/compatibility/developers.thtml:66
+msgid "compatibility_developers_adjust_maxversion"
+msgstr "Ajustar la maxVersion sin subirlo de nuevo"
+
+#: views/compatibility/dashboard.thtml:124
+msgid "compatibility_developers_check_status"
+msgstr "Comprobar el estado de mis complementos"
+
+#. %1$s is a URL
+#. %2$s is an application and version. Example: Firefox 3.0
+#: views/compatibility/dashboard.thtml:126
+msgid "compatibility_developers_login_first"
+msgstr ""
+"Si tienes complementos alojados en Mozilla Addons, <a href=\"%1$s\">por "
+"favor, inicia sesión</a>para analizar el estado de tus complementos para %2"
+"$s."
+
+#: views/compatibility/dashboard.thtml:114
+msgid "compatibility_developers_mdclogo_alt"
+msgstr "Logo del Mozilla Developer Center"
+
+#: views/compatibility/developers.thtml:73
+msgid "compatibility_developers_no_addons"
+msgstr "No tienes ningún complemento alojado en Mozilla Addons."
+
+#: views/compatibility/dashboard.thtml:133
+#: views/compatibility/developers.thtml:55
+msgid "compatibility_developers_results"
+msgstr "Resultados de la comprobación del estado del complemento"
+
+#: views/compatibility/dashboard.thtml:137
+msgid "compatibility_developers_retrieving"
+msgstr "Obteniendo el estado de los complementos alojados..."
+
+#. %1$s is a number
+#. %2$s is an application name
+#. %3$s is a number.
+#. Full example: 50 Firefox users (10% of total)
+#: views/compatibility/developers.thtml:65
+msgid "compatibility_developers_user_count"
+msgstr "%1$s usuarios de %2$s (%3$s&#37; del total)"
+
+#: views/compatibility/report.thtml:45
+msgid "compatibility_report_detail_intro"
+msgstr ""
+"Los siguientes complementos representan el 95% del volumen de uso que "
+"Mozilla tiene constancia y están ordenados por su volumen de uso."
+
+#: views/compatibility/dashboard.thtml:94
+msgid "compatibility_report_detailed_link"
+msgstr "Ver informe detallado"
+
+#. %1$s and %2$s are numbers
+#. %3$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:65
+msgid "compatibility_report_intro"
+msgstr ""
+"De los %1$s complementos que representan el 95&#37; del volumen de uso que "
+"Mozilla tiene constancia, <b>%2$s&#37;</b>son actualmente considerados "
+"compatibles con las últimas versiones de %3$s."
+
+#: views/compatibility/dashboard.thtml:81
+msgid "compatibility_report_legend_alpha"
+msgstr "Versiones Alpha"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:81
+msgid "compatibility_report_legend_alpha_description"
+msgstr "Complementos compatibles con un versión Alpha de %1$s"
+
+#: views/compatibility/dashboard.thtml:85
+msgid "compatibility_report_legend_beta"
+msgstr "Versiones Beta"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:85
+msgid "compatibility_report_legend_beta_description"
+msgstr "Complementos compatibles con una versión beta o candidata de %1$s"
+
+#: views/compatibility/dashboard.thtml:89
+msgid "compatibility_report_legend_latest"
+msgstr "Última versión"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:89
+msgid "compatibility_report_legend_latest_description"
+msgstr "Complementos actualizados para las últimas versiones de %1$s"
+
+#: views/compatibility/dashboard.thtml:77
+msgid "compatibility_report_legend_other"
+msgstr "Otras versiones"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:77
+msgid "compatibility_report_legend_other_description"
+msgstr "Complementos no compatibles con ninguna versión de %1$s"
+
+#: views/compatibility/dashboard.thtml:62
+msgid "compatibility_report_title"
+msgstr "Informe de compatibilidad del complemento"
+
+#: views/compatibility/dashboard.thtml:54
+#: views/compatibility/dashboard.thtml:144 views/compatibility/users.thtml:42
+msgid "compatibility_user_info"
+msgstr "Información para los usuarios del complemento"
+
+#: views/compatibility/dashboard.thtml:52
+msgid "compatibility_view_report"
+msgstr "Ver informe de compatibilidad"
+
+#. %s is a URL
+#: views/pages/credits.thtml:142
+#, php-format
+msgid "credits_contributing"
+msgstr ""
+"Si deseas información sobre cómo colaborar, por favor visita nuestra %s."
+
+#: views/pages/credits.thtml:142
+msgid "credits_contributing_wikipage"
+msgstr "página wiki"
+
+#: views/pages/credits.thtml:99
+msgid "credits_intro"
+msgstr ""
+"A Mozilla le gustaría dar las gracias a las siguientes personas por su "
+"colaboración con el proyecto addons.mozilla.org durante estos años:"
+
+#: views/pages/credits.thtml:103
+msgid "credits_section_developers"
+msgstr "Desarrolladores"
+
+#: views/pages/credits.thtml:115
+msgid "credits_section_editors"
+msgstr "Editores"
+
+#: views/pages/credits.thtml:109
+msgid "credits_section_localizers"
+msgstr "Traductores"
+
+#: views/pages/credits.thtml:121
+msgid "credits_section_other_contributors"
+msgstr "Otros colaboradores"
+
+#: views/pages/credits.thtml:127
+msgid "credits_section_past_developers"
+msgstr "Antiguos desarrolladores"
+
+#: views/pages/credits.thtml:133
+msgid "credits_section_software"
+msgstr "Aplicaciones e imágenes"
+
+#: views/pages/credits.thtml:136
+msgid "credits_software_famfamfam"
+msgstr ""
+"Alguno de los iconos usado son del <a href=\"http://www.famfamfam.com/lab/"
+"icons/silk/\">famfamfam Silk Icon Set</a>, licenciado bajo <a href=\"http://"
+"creativecommons.org/licenses/by/2.5/\">Licencia Creative Commons Attribution "
+"2.5</a>."
+
+#: views/pages/credits.thtml:137
+msgid "credits_software_timeplot"
+msgstr ""
+"Algunas páginas usan elementos de <a href=\"http://www.simile-widgets.org/"
+"timeplot/\">Timeplot</a>, bajo <a href=\"http://simile.mit.edu/license.html"
+"\">licencia BSD</a>."
+
+#. date format string as used in PHP's strftime():
+#. http://php.net/strftime
+#: views/elements/collections_interactive_addon.thtml:85
+#: views/elements/amo2009/addon_version_detail.thtml:53
+#: views/elements/amo2009/homepage_addon.thtml:115
+#: views/elements/addon_version_detail.thtml:54
+#: views/elements/addon_listitem.thtml:124 views/elements/feature.thtml:106
+#: views/collections/detail.thtml:118 views/collections/edit.thtml:325
+#: views/users/info.thtml:76 views/editors/reviews_queue.thtml:57
+#: views/editors/reviews_queue.thtml:68 views/developers/dashboard.thtml:65
+#: views/developers/versions_edit.thtml:208 views/developers/versions.thtml:67
+#: views/search/rss/index.thtml:5 views/addons/rss/versions.thtml:42
+#: views/addons/display.thtml:104 views/addons/display.thtml:356
+#: views/addons/browse_thumbs.thtml:75 views/reviews/add.thtml:63
+#: views/reviews/display.thtml:74 views/reviews/display.thtml:160
+#: views/reviews/delete.thtml:54 controllers/statistics_controller.php:244
+#: controllers/collections_controller.php:1047
+msgid "date"
+msgstr "%x"
+
+#. date and time format string (strftime)
+#. http://php.net/strftime
+#: views/elements/addon_version_detail.thtml:53
+#: views/developers/discuss.thtml:52 views/developers/discuss.thtml:62
+#: views/admin/addons_status.thtml:57
+msgid "datetime"
+msgstr "%x %X"
+
+#: views/elements/developers/actionbar.thtml:47
+msgid "devcp_actionbar_link_details"
+msgstr "Información detallada"
+
+#: views/elements/developers/actionbar.thtml:42
+#: views/elements/developers/actionbar.thtml:50
+#: views/developers/dashboard.thtml:64
+msgid "devcp_actionbar_link_edit"
+msgstr "Editar el complemento"
+
+#: views/elements/developers/actionbar.thtml:51
+msgid "devcp_actionbar_link_newversion"
+msgstr "Subir una nueva versión"
+
+#: views/elements/developers/actionbar.thtml:44
+#: views/elements/developers/actionbar.thtml:49
+#: views/developers/dashboard.thtml:73
+msgid "devcp_actionbar_link_stats"
+msgstr "Panel de estadísticas"
+
+#. %1$s is a filename, e.g. "foo.txt"
+#. %2$s is the extension, e.g. ".txt"
+#. %3$s is a list of valid extensions, like ".png, .jpg, .gif"
+#: controllers/developers_controller.php:1361
+msgid "devcp_add_previews_extension_error"
+msgstr ""
+"El archivo %1$s tiene una extensión incorrecta (%2$s). Extensiones "
+"permitidas: %3$s"
+
+#. %s is the filename.
+#: controllers/developers_controller.php:1394
+msgid "devcp_add_previews_save_error"
+msgstr ""
+"No se pudo guardar el archivo %s en la base de datos. Por favor, inténtalo "
+"de nuevo."
+
+#. %1$s is the preview ID number, %2$s is the filename.
+#: controllers/developers_controller.php:1389
+msgid "devcp_add_previews_success_replace"
+msgstr "La vista previa %1$s fue remplazada con éxito por el archivo %2$s."
+
+#. %s is the filename.
+#: controllers/developers_controller.php:1391
+msgid "devcp_add_previews_success_upload"
+msgstr "Se subió con éxito el archivo %s. Puedes añadir una captura abajo."
+
+#: controllers/components/developers.php:1163
+msgid "devcp_additem_addontype_autodetect"
+msgstr "(auto-detectar)"
+
+#: views/elements/developers/additem.thtml:76
+msgid "devcp_additem_linktitle_opensin_newwindow"
+msgstr "Abrir en una nueva ventana"
+
+#: views/elements/developers/additem.thtml:41
+msgid "devcp_additem_sidebar_title"
+msgstr "Enviar complemento"
+
+#: views/elements/developers/additem.thtml:53
+msgid "devcp_additem_step0_newlink"
+msgstr "Acuerdo del desarollador"
+
+#: views/elements/developers/additem.thtml:46
+msgid "devcp_additem_step1_link"
+msgstr "Paso 1: Subir"
+
+#: views/elements/developers/additem.thtml:47
+msgid "devcp_additem_step2_link"
+msgstr "Paso 2: Detalles del complemento"
+
+#: views/elements/developers/additem.thtml:48
+msgid "devcp_additem_step3_link"
+msgstr "Paso 3: Detalles de la versión"
+
+#: views/elements/developers/additem.thtml:49
+msgid "devcp_additem_step4_link"
+msgstr "Paso 4: Localización"
+
+#: views/elements/developers/additem.thtml:50
+msgid "devcp_additem_step5_link"
+msgstr "Paso 5: Éxito"
+
+#: views/elements/developers/additem.thtml:76
+msgid "devcp_additem_submissionhelp_link"
+msgstr "Ayuda con el envío"
+
+#: controllers/previews_controller.php:168
+#: controllers/previews_controller.php:277
+msgid "devcp_addon_field_preview_caption_displaytitle"
+msgstr "Captura de vista previa"
+
+#: views/developers/addon_status.thtml:177
+msgid "devcp_addon_status_action_activate"
+msgstr "Marcar como activo"
+
+#: views/developers/addon_status.thtml:178
+msgid "devcp_addon_status_action_activate_description"
+msgstr ""
+"Marcar tu complemento como activo para que pueda ser visualizado en los "
+"listados públicos y activar el sistema de comprobación de actualizaciones."
+
+#: views/developers/addon_status.thtml:135
+msgid "devcp_addon_status_action_complete"
+msgstr "Completar complemento"
+
+#: views/developers/addon_status.thtml:136
+msgid "devcp_addon_status_action_complete_description"
+msgstr "Completar tu complemento y moverlo al área de pruebas"
+
+#: views/developers/addon_status.thtml:181
+msgid "devcp_addon_status_action_deactivate"
+msgstr "Marcar como inactivo"
+
+#: views/developers/addon_status.thtml:182
+msgid "devcp_addon_status_action_deactivate_description"
+msgstr ""
+"Marcar tu complemento como inactivo para ocultarlo de los listados públicos "
+"y desactivar el sistema de comprobación de actualizaciones."
+
+#: views/developers/addon_status.thtml:143
+msgid "devcp_addon_status_action_move"
+msgstr "Mover al área de pruebas"
+
+#: views/developers/addon_status.thtml:144
+msgid "devcp_addon_status_action_move_description"
+msgstr "Mover tu complemento al área de pruebas. Puede ser revertido."
+
+#: views/developers/addon_status.thtml:139
+msgid "devcp_addon_status_action_nominate"
+msgstr "Proponer públicamente"
+
+#: views/developers/addon_status.thtml:140
+msgid "devcp_addon_status_action_nominate_description"
+msgstr "Proponer tu complemento para que sea público"
+
+#: views/developers/addon_status.thtml:147
+msgid "devcp_addon_status_action_public"
+msgstr "Hacer público"
+
+#: views/developers/addon_status.thtml:148
+msgid "devcp_addon_status_action_public_description"
+msgstr "Hacer tu complemento público de nuevo."
+
+#: views/developers/addon_status.thtml:169
+msgid "devcp_addon_status_active"
+msgstr ""
+"Tu complemento está <span class=\"inactive-0\">Activo</span>. Esto significa "
+"que debido a ello, se está mostrando en todos los listados actuales que le "
+"correspondan."
+
+#: views/developers/addon_status.thtml:111
+msgid "devcp_addon_status_completion_disabled"
+msgstr ""
+"Por favor, antes de que puedas completar el proceso, rellena completamente "
+"los campos superiores y muévelo al <span class=\"status-1\">Ãrea de pruebas</"
+"span>."
+
+#: views/developers/addon_status.thtml:108
+msgid "devcp_addon_status_completion_enabled"
+msgstr ""
+"Ahora debes completar el proceso y mover tu complemento al <span class="
+"\"status-1\">Ãrea de pruebas</span> haciendo clic sobre el siguiente botón."
+
+#: views/developers/addon_status.thtml:102
+msgid "devcp_addon_status_criteria_category"
+msgstr "Al menos una categoría debe ser seleccionada"
+
+#: views/developers/addon_status.thtml:101
+msgid "devcp_addon_status_criteria_description"
+msgstr "Se requiere una descripción del complemento"
+
+#: views/developers/addon_status.thtml:99
+msgid "devcp_addon_status_criteria_name"
+msgstr "Se requiere el nombre del complemento"
+
+#: views/developers/addon_status.thtml:120
+msgid "devcp_addon_status_criteria_prerelease"
+msgstr "El complemente no está marcado como una versión previa."
+
+#: views/developers/addon_status.thtml:119
+msgid "devcp_addon_status_criteria_preview"
+msgstr ""
+"Para las extensiones y temas, se requiere al menos una captura con la vista "
+"previa."
+
+#: views/developers/addon_status.thtml:100
+msgid "devcp_addon_status_criteria_summary"
+msgstr "Se requiere un resumen del complemento"
+
+#. %s is the status in a span, e.g. "<span>_('Public')</span>".
+#: views/developers/addon_status.thtml:58
+msgid "devcp_addon_status_header"
+msgstr "Estado del complemento: %s"
+
+#: views/developers/addon_status.thtml:152
+#: views/developers/addon_status.thtml:173
+msgid "devcp_addon_status_header_actions"
+msgstr "Acciones disponibles"
+
+#: views/developers/addon_status.thtml:168
+msgid "devcp_addon_status_header_active"
+msgstr "Estado: <span class=\"inactive-0\">Activo</span>"
+
+#: views/developers/addon_status.thtml:97
+msgid "devcp_addon_status_header_criteria"
+msgstr "Criterio para complementos"
+
+#: views/developers/addon_status.thtml:164
+msgid "devcp_addon_status_header_inactive"
+msgstr "Estado: <span class=\"inactive-1\">Inactivo</span>"
+
+#: views/developers/addon_status.thtml:117
+msgid "devcp_addon_status_header_nomination"
+msgstr "Criterios de propuesta pública"
+
+#: views/developers/addon_status.thtml:190
+msgid "devcp_addon_status_header_trusted"
+msgstr "Estado de confianza: <span class=\"status-4\">Confiable</span>"
+
+#: views/developers/addon_status.thtml:165
+msgid "devcp_addon_status_inactive"
+msgstr ""
+"Tu complemente está <span class=\"inactive-1\">Inactivo</span>. Esto "
+"significa que no se mostrará en ningún listado debido a su estado. "
+"<strong>No</strong> se están proporcionando actualizaciones para tu "
+"complemento a través del servicio de actualizaciones."
+
+#: views/developers/addon_status.thtml:128
+msgid "devcp_addon_status_nominate_disabled"
+msgstr ""
+"Por favor, rellena completamente los campos superiores antes de proponer tu "
+"complemento para convertirse en <span class=\"status-4\">Público</span>."
+
+#: views/developers/addon_status.thtml:125
+msgid "devcp_addon_status_nominate_enabled"
+msgstr ""
+"Ahora puedes proponer tu complemento para convertirse en <span class="
+"\"status-4\">Público</span> haciendo clic sobre el siguiente botón."
+
+#: views/developers/addon_status.thtml:64
+msgid "devcp_addon_status_public"
+msgstr "Público"
+
+#: views/developers/addon_status.thtml:63
+msgid "devcp_addon_status_sandbox"
+msgstr "Ãrea de pruebas"
+
+#. %s is an email address.
+#: views/developers/addon_status.thtml:89
+msgid "devcp_addon_status_switch_disabled"
+msgstr ""
+"Tu complemento fue <span class=\"status-5\">Desactivado</span> por un "
+"administrador y no puede usarse. Si tienes alguna pregunta, envía un correo "
+"a %s."
+
+#: views/developers/addon_status.thtml:67
+msgid "devcp_addon_status_switch_incomplete"
+msgstr ""
+"Tu complemento está actualmente <span class=\"status-0\">Incompleto</span>. "
+"Esto significa que no se mostrará en ninguna parte de la web o en el "
+"servicio de actualizaciones. Deberías regresar a esta página para completar "
+"los datos de tu complemento para que cumplan los requisitos, completando así "
+"el proceso y enviarlo al <span class=\"status-1\">Ãrea de pruebas</span>."
+
+#. %s is a number, perhaps 42.
+#: views/developers/addon_status.thtml:77
+msgid "devcp_addon_status_switch_nominated"
+msgstr ""
+"Tu complemento está actualmente propuesto para convertirse en <span class="
+"\"status-4\">Público</span> y está esperando una valoración del editor. "
+"Actualmente hay %s otros complementos en la cola de propuestas."
+
+#. %s is an email address.
+#: views/developers/addon_status.thtml:81
+msgid "devcp_addon_status_switch_pending"
+msgstr ""
+"Tu complemento está pendiente. Ésto no debería haber pasado. Por favor, "
+"envía un correo electrónico a %s con tu ID de complemento y menciona este "
+"error."
+
+#: views/developers/addon_status.thtml:85
+msgid "devcp_addon_status_switch_public"
+msgstr ""
+"Tu complemento es <span class=\"status-4\">Público</span>, lo que significa "
+"que se mostrará en todos los listados y búsquedas y puede ser descargado sin "
+"restricciones. Las actualizaciones son proporcionadas a través del servicio "
+"de verificación de actualizaciones."
+
+#: views/developers/addon_status.thtml:71
+#: views/developers/addon_status.thtml:75
+msgid "devcp_addon_status_switch_sandbox"
+msgstr ""
+"Tu complemento está en el <span class=\"status-1\">Ãrea de pruebas</span>, "
+"lo que significa que se mostrará en los listados y búsquedas, pero los "
+"usuarios deberán iniciar sesión descargarlo. <strong>No</strong> se "
+"proporcionarán actualizaciones de tu complemento a través del servicio de "
+"verificación de actualizaciones."
+
+#. %s is the add-on name.
+#: views/developers/addon_status_nominate.thtml:43
+#: views/developers/addon_status_confirm.thtml:43
+#: views/developers/addon_status.thtml:43
+msgid "devcp_addon_status_title"
+msgstr "Estado de %s"
+
+#: views/developers/addon_status.thtml:191
+msgid "devcp_addon_status_trusted"
+msgstr ""
+"Tu complemento es <span class=\"status-4\">Confiable</span>. Ésto significa "
+"que puedes enviar actualizaciones de tu complemento sin necesidad de una "
+"valoración del editor."
+
+#: views/developers/dashboard.thtml:68
+msgid "devcp_dashboard_active"
+msgstr "Activo"
+
+#. %1$s is the add-on type string
+#. %2$s is Inactive or Active in a <span>
+#. %3$s is the addon's public status (Public, In Sandbox, ...) in a <span>
+#: views/developers/dashboard.thtml:69
+msgid "devcp_dashboard_addontype_status"
+msgstr "%1$s actualmente %2$s y %3$s"
+
+#: views/developers/dashboard.thtml:67
+msgid "devcp_dashboard_change_status"
+msgstr "Cambiar estado"
+
+#. %s is the addons email address.
+#: views/developers/dashboard.thtml:99
+msgid "devcp_dashboard_disabled_questions"
+msgstr ""
+"Tu complemento fue deshabilitado por un administrador y no puede ser usado. "
+"Si tienes alguna pregunta, por favor envía un correo electrónico a %s."
+
+#. %s is the (localized) add-on status string in a span, e.g. "Disabled"
+#: views/developers/dashboard.thtml:98
+msgid "devcp_dashboard_disabled_status"
+msgstr "Estado del complemento: %s"
+
+#: views/developers/dashboard.thtml:43
+msgid "devcp_dashboard_header_main"
+msgstr "Panel del desarrollador"
+
+#: views/developers/dashboard.thtml:110
+msgid "devcp_dashboard_header_welcome"
+msgstr "Bienvenido al panel del desarrollador"
+
+#: views/developers/dashboard.thtml:68
+msgid "devcp_dashboard_inactive"
+msgstr "Inactivo"
+
+#. %s is a date in the _('date') format
+#: views/developers/dashboard.thtml:65
+msgid "devcp_dashboard_last_edited"
+msgstr "Última edición el %s"
+
+#: views/developers/dashboard.thtml:111
+msgid "devcp_dashboard_learn"
+msgstr ""
+"Actualmente no tienes ningún complemento alojado en Mozilla Addons. Para "
+"conocer cómo funciona el proceso y enviar tu primer complemento, haz clic en "
+"\"Comenzar\" debajo."
+
+#: views/developers/dashboard.thtml:112
+msgid "devcp_dashboard_start"
+msgstr "Comenzar"
+
+#: views/developers/dashboard.thtml:82
+msgid "devcp_dashboard_versions"
+msgstr "Versiones y archivos"
+
+#: views/developers/dashboard.thtml:91
+msgid "devcp_dashboard_versions_new"
+msgstr "Subir una nueva versión"
+
+#. %s is the preview ID number.
+#: controllers/developers_controller.php:1415
+msgid "devcp_delete_previews_error"
+msgstr ""
+"La vista previa de %s no puede borrarse de la base de datos. Por favor, "
+"intentalo de nuevo."
+
+#. %s is the preview ID number.
+#: controllers/developers_controller.php:1413
+msgid "devcp_delete_previews_success"
+msgstr "La vista previa de %s ha sido borrada con éxito."
+
+#: controllers/developers_controller.php:1089
+msgid "devcp_delete_version_priv_error"
+msgstr "No tienes privilegios para borrar versiones o archivos."
+
+#. %1$s is the count of files, a number
+#. %2$s is a status string like _('Public') or _('Incomplete')
+#: controllers/components/amo.php:549
+msgid "devcp_describe_version_status"
+msgid_plural "devcp_describe_version_status"
+msgstr[0] "%1$s archivo %2$s "
+msgstr[1] "%1$s archivos %2$s"
+
+#. %s is a version number. Example: 3.0
+#: views/developers/versions.thtml:65
+#, php-format
+msgid "devcp_details_version"
+msgstr "Versión %s"
+
+#: views/developers/discuss.thtml:68
+msgid "devcp_discuss_addreply_header"
+msgstr "Añadir respuesta"
+
+#: views/developers/discuss.thtml:57
+msgid "devcp_discuss_allreplies_header"
+msgstr "Respuestas"
+
+#. notice when an error occurs saving a discussion reply
+#. %1 is the email address (linked) for the amo-editors list
+#: views/developers/discuss.thtml:70
+msgid "devcp_discuss_error_notice"
+msgstr ""
+"Hubo un error al guardar tu respuesta. Por favor, contacta en %1$s sobre "
+"este problema."
+
+#. %1 is the add-on name, %2 is the add-on's version number currently being reviewed by an editor
+#: views/developers/discuss.thtml:46
+msgid "devcp_discuss_intro"
+msgstr ""
+"Un editor de Mozilla Addons ha solicitado más información sobre tu versión %2"
+"$s de tu complemento %1$s."
+
+#. %1 is the add-on name
+#: views/developers/discuss.thtml:43
+msgid "devcp_discuss_pagetitle"
+msgstr "Proporcionar más información sobre la valoración del complemento %1$s"
+
+#. submit button text
+#: views/developers/discuss.thtml:79
+msgid "devcp_discuss_submit_reply"
+msgstr "Enviar respuesta"
+
+#: views/developers/discuss.thtml:72
+msgid "devcp_discuss_success_message"
+msgstr ""
+"Tu respuesta se ha guardado con éxito. Se informará por correo electrónico a "
+"los otros participantes en la discusión."
+
+#. in an author/editor discussion about an add-on to be reviewed:
+#. %1 is the commenter's user name (linked).
+#. %2 is the full date the comment was made.
+#: views/developers/discuss.thtml:52 views/developers/discuss.thtml:62
+msgid "devcp_discuss_writtenby"
+msgstr "escrito por %1$s el %2$s"
+
+#: views/developers/addon_edit_authors.thtml:72
+#: views/developers/addon_edit_authors.thtml:81
+msgid "devcp_edit_authors_add_author"
+msgstr "Añadir nuevo autor"
+
+#: views/developers/addon_edit_authors.thtml:96
+msgid "devcp_edit_authors_add_author_button"
+msgstr "Añadir autor"
+
+#: views/developers/addon_edit_authors.thtml:83
+msgid "devcp_edit_authors_add_email"
+msgstr "Cuenta de correo del autor:"
+
+#: views/developers/addon_edit_authors.thtml:98
+msgid "devcp_edit_authors_add_loading"
+msgstr "Comprobando cuenta de correo..."
+
+#: views/developers/addon_edit_authors.thtml:70
+msgid "devcp_edit_authors_click_save"
+msgstr "Pulse el botón actualizar autores para guardar."
+
+#: views/developers/addon_edit_authors.thtml:58
+msgid "devcp_edit_authors_header_current"
+msgstr "Autores actuales"
+
+#: views/developers/addon_edit_authors.thtml:50
+msgid "devcp_edit_authors_header_manage"
+msgstr "Administrar autores del complemento"
+
+#: views/developers/addon_edit_authors.thtml:93
+msgid "devcp_edit_authors_label_add_listed"
+msgstr "Listar como autor en las páginas públicas"
+
+#: views/developers/addon_edit_authors.thtml:89
+msgid "devcp_edit_authors_label_developer"
+msgstr ""
+"<strong>Desarrollador</strong> - Puede administrar todos los aspectos del "
+"listado de complementos, excepto añadir y borrar otros autores."
+
+#: views/developers/addon_edit_authors.thtml:88
+msgid "devcp_edit_authors_label_owner"
+msgstr ""
+"<strong>Propietario</strong> - Puede administrar todos los aspectos del "
+"listado de complementos, incluyendo añadir y borrar otros autores."
+
+#: views/developers/addon_edit_authors.thtml:90
+msgid "devcp_edit_authors_label_viewer"
+msgstr ""
+"<strong>Visualizador</strong> - Puede visualizar el listado de "
+"desarrolladores y estadísticas, pero no puede hacer ningún cambio."
+
+#. Placeholder for the empty option in a <select>.
+#: views/developers/addon_edit_categories.thtml:69
+msgid "devcp_edit_authors_option_empty"
+msgstr "----------------"
+
+#: views/developers/addon_edit_authors.thtml:86
+msgid "devcp_edit_authors_select_role"
+msgstr "Selecciona un rol para el autor:"
+
+#. Column name in a table.
+#: views/developers/addon_edit_authors.thtml:62
+msgid "devcp_edit_authors_th_author"
+msgstr "Autor"
+
+#. Column name in a table.
+#: views/developers/addon_edit_authors.thtml:64
+msgid "devcp_edit_authors_th_listed"
+msgstr "Listado"
+
+#. Column name in a table.
+#: views/developers/addon_edit_authors.thtml:63
+msgid "devcp_edit_authors_th_role"
+msgstr "Rol"
+
+#: views/developers/addon_edit_authors.thtml:77
+msgid "devcp_edit_authors_update_author"
+msgstr "Actualizar autores"
+
+#: views/developers/addon_edit_categories.thtml:99
+msgid "devcp_edit_categories_button_update"
+msgstr "Actualiza categorías"
+
+#: views/developers/addon_edit_categories.thtml:88
+msgid "devcp_edit_categories_does_not_fit"
+msgstr "Mi complemento no coincide con ninguna de las categorías disponibles."
+
+#. %s is the application name (Firefox, Thunderbird).
+#: views/developers/addon_edit_categories.thtml:61
+msgid "devcp_edit_categories_header_application"
+msgstr "Categorías de %s"
+
+#: views/developers/addon_edit_categories.thtml:49
+msgid "devcp_edit_categories_header_manage"
+msgstr "Administrar las categorías del complemento"
+
+#: views/developers/addon_edit_categories.thtml:91
+msgid "devcp_edit_categories_hover"
+msgstr "Pase el cursor sobre una categoría para ver su descripción."
+
+#. %s is the category number (1, 2, 3).
+#: views/developers/addon_edit_categories.thtml:67
+msgid "devcp_edit_categories_label_category_num"
+msgstr "Categoría %s"
+
+#: views/developers/addon_edit_categories.thtml:94
+#: views/developers/addon_edit_categories.thtml:103
+msgid "devcp_edit_categories_none_available"
+msgstr ""
+"No hay categorías disponibles para el tipo y aplicación del complemento."
+
+#: views/developers/addon_edit_categories.thtml:86
+msgid "devcp_edit_categories_other"
+msgstr ""
+"Incluya su complemento en esta categoría sólo si no encaja en el resto de "
+"categorías disponibles."
+
+#. %s is the application name (Firefox, Thunderbird).
+#: views/developers/addon_edit_categories.thtml:63
+msgid "devcp_edit_categories_select_application_categories"
+msgstr "Selecciona hasta tres categorías de %s para tu complemento"
+
+#: views/developers/addon_edit.thtml:47
+msgid "devcp_edit_dd_manage_authors"
+msgstr "Añade o elimina usuarios que puedan administrar este complemento."
+
+#: views/developers/addon_edit.thtml:49
+msgid "devcp_edit_dd_manage_categories"
+msgstr ""
+"Selecciona las categorías relevantes para cada aplicación que admita tu "
+"complemento."
+
+#: views/developers/addon_edit.thtml:51
+msgid "devcp_edit_dd_manage_description"
+msgstr ""
+"Añade y modifica las traducciones para el resumen del complemento, "
+"descripción, licencia de usuario final y política de privacidad."
+
+#: views/developers/addon_edit.thtml:53
+msgid "devcp_edit_dd_manage_properties"
+msgstr ""
+"Cambie el nombre de tu complemento, la página web, el icono y otras marcas."
+
+#: views/developers/addon_edit_descriptions.thtml:116
+msgid "devcp_edit_description_button_update"
+msgstr "Actualizar descripciones"
+
+#: views/developers/addon_edit_descriptions.thtml:115
+msgid "devcp_edit_description_correct_error"
+msgstr "Por favor, corrige los errores indicados en rojo más arriba."
+
+#: views/developers/addon_edit_descriptions.thtml:51
+msgid "devcp_edit_descriptions_header"
+msgstr "Editar descripciones de complementos"
+
+#: views/developers/addon_edit_descriptions.thtml:94
+msgid "devcp_edit_descriptions_transbox_comments_description"
+msgstr ""
+"Cualquier información que los usuarios finales pueden necesitar saber, y que "
+"no necesariamente se aplican al resumen del complemento o la descripción. "
+"Los usos comunes incluyen informar de problemas conocidos, cómo informar de "
+"errores, fecha prevista de nuevas versiones, etc."
+
+#: views/developers/addon_edit_descriptions.thtml:93
+msgid "devcp_edit_descriptions_transbox_comments_name"
+msgstr "Comentarios del desarrollador"
+
+#: views/developers/addon_edit_descriptions.thtml:86
+msgid "devcp_edit_descriptions_transbox_description_description"
+msgstr ""
+"La descripción de tu complemento es una explicación más larga de "
+"características, funcionalidades y otra información relevante. Se muestra "
+"bajo el resumen en la página del complemento."
+
+#: views/developers/addon_edit_descriptions.thtml:85
+msgid "devcp_edit_descriptions_transbox_description_name"
+msgstr "Descripción del complemento"
+
+#: views/developers/addon_edit_descriptions.thtml:103
+msgid "devcp_edit_descriptions_transbox_eula_description"
+msgstr ""
+"Si tu complemento tiene un acuerdo de licencia final de usuario (EULA), "
+"introduce el texto a continuación. De este modo, los usuarios necesitarán "
+"aceptarla antes de poder instalar tu complemento. Ten en cuenta que una EULA "
+"no es lo mismo que una licencia de código como GPL o MPL."
+
+#: views/developers/addon_edit_descriptions.thtml:102
+msgid "devcp_edit_descriptions_transbox_eula_name"
+msgstr "Acuerdo de licencia final de usuario"
+
+#: views/developers/addon_edit_descriptions.thtml:112
+msgid "devcp_edit_descriptions_transbox_privacy_description"
+msgstr ""
+"Si tienes una política de privacidad, introduce el texto a continuación. La "
+"página del complemento mostrará un enlace a la política."
+
+#: views/developers/addon_edit_descriptions.thtml:111
+msgid "devcp_edit_descriptions_transbox_privacy_name"
+msgstr "Política de privacidad"
+
+#: views/developers/addon_edit_descriptions.thtml:78
+msgid "devcp_edit_descriptions_transbox_summary_description"
+msgstr ""
+"El resumen es una explicación corta de la funcionalidad básica de tu "
+"complemento que se muestra en la búsqueda y en los listados, además de en la "
+"parte superior de la página del complemento. <strong>Límite de 250 "
+"caracteres.</strong>"
+
+#: views/developers/addon_edit_descriptions.thtml:77
+msgid "devcp_edit_descriptions_transbox_summary_name"
+msgstr "Resumen del complemento"
+
+#: views/developers/addon_edit.thtml:46
+msgid "devcp_edit_dt_manage_authors"
+msgstr "Administrar autores del complemento"
+
+#: views/developers/addon_edit.thtml:48
+msgid "devcp_edit_dt_manage_categories"
+msgstr "Administrar categorías del complemento"
+
+#: views/developers/addon_edit.thtml:50
+msgid "devcp_edit_dt_manage_descriptions"
+msgstr "Administrar descripciones del complemento"
+
+#: views/developers/addon_edit.thtml:52
+msgid "devcp_edit_dt_manage_properties"
+msgstr "Administrar propiedades del complemento"
+
+#: views/developers/addon_edit_properties.thtml:170
+msgid "devcp_edit_label_externalsoftware"
+msgstr "Este complemento requiere programas externos"
+
+#: views/developers/addon_edit_properties.thtml:205
+msgid "devcp_edit_label_locale_disambiguation"
+msgstr "Información adicional sobre el idioma"
+
+#: views/developers/addon_edit_properties.thtml:168
+msgid "devcp_edit_label_prerelease"
+msgstr "Esta es una versión previa"
+
+#: views/developers/addon_edit_properties.thtml:169
+msgid "devcp_edit_label_sitespecific"
+msgstr "Este es un complemento específico para una web"
+
+#: views/developers/addon_edit_properties.thtml:202
+msgid "devcp_edit_label_target_locale"
+msgstr "Idioma objetivo"
+
+#: views/developers/addon_edit_properties.thtml:212
+msgid "devcp_edit_properties_button_update"
+msgstr "Actualizar propiedades"
+
+#: views/developers/addon_edit_properties.thtml:198
+msgid "devcp_edit_properties_change_guid"
+msgstr "Cámbialo sólo si entiendes todas las consecuencias."
+
+#: views/developers/addon_edit_properties.thtml:109
+msgid "devcp_edit_properties_current_icon"
+msgstr "Icono actual"
+
+#: views/developers/addon_edit_properties.thtml:85
+msgid "devcp_edit_properties_default_locale"
+msgstr ""
+"Un idioma por defecto para los complementos es el idioma principal en el que "
+"las traducciones deben estar. Si las traducciones de las descripciones de tu "
+"complemento no existen en un idioma seleccionado por el usuario, se usará el "
+"idioma por defecto."
+
+#: views/developers/addon_edit_properties.thtml:167
+msgid "devcp_edit_properties_flags"
+msgstr "Estas marcas se usan para filtrar y clasificar los complementos."
+
+#: views/developers/addon_edit_properties.thtml:174
+msgid "devcp_edit_properties_guid"
+msgstr ""
+"El GUID de tu complemento se especifica en el archivo install.rdf y lo "
+"identifica unívocamente. No puedes cambiar el GUID una vez se haya "
+"registrado en Mozilla Addons."
+
+#: views/developers/addon_edit_properties.thtml:53
+msgid "devcp_edit_properties_header"
+msgstr "Editar propiedades del complemento"
+
+#: views/developers/addon_edit_properties.thtml:186
+msgid "devcp_edit_properties_header_addon_type"
+msgstr "Tipo de complemento"
+
+#: views/developers/addon_edit_properties.thtml:181
+msgid "devcp_edit_properties_header_admin_settings"
+msgstr "Opciones de administrador"
+
+#: views/developers/addon_edit_properties.thtml:84
+msgid "devcp_edit_properties_header_default_locale"
+msgstr "Idioma por defecto"
+
+#: views/developers/addon_edit_properties.thtml:166
+msgid "devcp_edit_properties_header_flags"
+msgstr "Marcas del complemento"
+
+#: views/developers/addon_edit_properties.thtml:173
+#: views/developers/addon_edit_properties.thtml:197
+msgid "devcp_edit_properties_header_guid"
+msgstr "GUID del complemento"
+
+#: views/developers/addon_edit_properties.thtml:104
+msgid "devcp_edit_properties_header_icon"
+msgstr "Icono del complemento"
+
+#: views/developers/addon_edit_properties.thtml:159
+msgid "devcp_edit_properties_header_other_settings"
+msgstr "Otras opciones"
+
+#. A header on the admin page to toggle trusted status.
+#: views/developers/addon_edit_properties.thtml:182
+msgid "devcp_edit_properties_header_trusted"
+msgstr "¿Complemento de confianza?"
+
+#: views/developers/addon_edit_properties.thtml:160
+msgid "devcp_edit_properties_header_view_source"
+msgstr "Ver código fuente en línea"
+
+#. %s is a comma-separated list of image extensions ".png, .jpg"
+#: views/developers/addon_edit_properties.thtml:106
+msgid "devcp_edit_properties_icon"
+msgstr ""
+"El icono del complemento es una pequeña imagen que se muestra junto al "
+"nombre de tu complemento en los listados y los resultados de las búsquedas, "
+"y en el cuadro de instalación del complemento. La imagen se redimensionará "
+"automáticamente a 32 x 32 pixels. Por favor, usa uno de los siguientes "
+"tipos de imagen: %s"
+
+#: views/developers/addon_edit_properties.thtml:171
+msgid "devcp_edit_properties_label_binary"
+msgstr "Este complemento contiene componentes binarios"
+
+#: views/developers/addon_edit_properties.thtml:185
+msgid "devcp_edit_properties_label_not_trusted"
+msgstr "No es de confianza"
+
+#: views/developers/addon_edit_properties.thtml:184
+msgid "devcp_edit_properties_label_trusted"
+msgstr "De confianza"
+
+#: views/developers/addon_edit_properties.thtml:110
+msgid "devcp_edit_properties_new_icon"
+msgstr "Nuevo icono"
+
+#: views/developers/addon_edit_properties.thtml:118
+msgid "devcp_edit_properties_remove_icon"
+msgstr "Borrar icono"
+
+#: views/developers/addon_edit_properties.thtml:136
+msgid "devcp_edit_properties_transbox_homepage_description"
+msgstr ""
+"Si tu complemento tiene otra página web, introduce su dirección aquí. No es "
+"necesario añadir otras traducciones a menos que tu página web esté traducida "
+"en varios idiomas."
+
+#: views/developers/addon_edit_properties.thtml:135
+msgid "devcp_edit_properties_transbox_homepage_name"
+msgstr "Página del complemento"
+
+#: views/developers/addon_edit_properties.thtml:79
+msgid "devcp_edit_properties_transbox_name_description"
+msgstr ""
+"El nombre de su complemento aparecerá en todos los sitios donde sea listado."
+
+#: views/developers/addon_edit_properties.thtml:78
+msgid "devcp_edit_properties_transbox_name_name"
+msgstr "Nombre del complemento"
+
+#: views/developers/addon_edit_properties.thtml:145
+msgid "devcp_edit_properties_transbox_supportemail_description"
+msgstr ""
+"Si tienes una dirección de correo para peticiones de asistencia, introdúcela "
+"aquí. No es necesario añadir otras traducciones a menos que tengas "
+"diferentes direcciones para otros idiomas."
+
+#: views/developers/addon_edit_properties.thtml:144
+msgid "devcp_edit_properties_transbox_supportemail_name"
+msgstr "Dirección de correo de asistencia"
+
+#: views/developers/addon_edit_properties.thtml:154
+msgid "devcp_edit_properties_transbox_supporturl_description"
+msgstr ""
+"Si tu complemento tiene una página web o un foro de asistencia, introduce su "
+"dirección aquí. No es necesario añadir otras traducciones a menos que la "
+"página web esté traducida en varios idiomas."
+
+#: views/developers/addon_edit_properties.thtml:153
+msgid "devcp_edit_properties_transbox_supporturl_name"
+msgstr "Página web de asistencia"
+
+#: views/developers/addon_edit_properties.thtml:183
+msgid "devcp_edit_properties_trusted"
+msgstr ""
+"Los complementos de confianza pueden pasar a ser públicos sin necesidad de "
+"revisiones de los editores."
+
+#. %s is href="..." and should stay in the <a> tag.
+#: views/developers/addon_edit_properties.thtml:119
+msgid "devcp_edit_properties_undelete"
+msgstr "Los iconos se borrarán al guardar. <a %s>¿Cancelar?</a>"
+
+#: views/developers/addon_edit_properties.thtml:161
+msgid "devcp_edit_properties_view_source"
+msgstr ""
+"El código fuente de los archivos de tu complemento podrán ser vistos en "
+"línea por cualquier usuario conectado si lo deseas."
+
+#: views/developers/addon_edit_properties.thtml:162
+msgid "devcp_edit_properties_view_source_allow"
+msgstr "Permitir ver el código fuente en línea"
+
+#: views/developers/addon_edit_properties.thtml:163
+msgid "devcp_edit_properties_view_source_do_not_allow"
+msgstr "No permitir la visualización del código fuente en línea"
+
+#: views/elements/developers/editbox.thtml:46
+msgid "devcp_editbox_authors"
+msgstr "Autores"
+
+#: views/elements/developers/editbox.thtml:47
+msgid "devcp_editbox_categories"
+msgstr "Categorías"
+
+#: views/elements/developers/editbox.thtml:52
+msgid "devcp_editbox_change_status"
+msgstr "Cambiar estado"
+
+#: views/elements/developers/editbox.thtml:48
+msgid "devcp_editbox_descriptions"
+msgstr "Descripciones"
+
+#: views/elements/developers/editbox.thtml:43
+msgid "devcp_editbox_edit_addon"
+msgstr "Editar complemento"
+
+#: views/elements/developers/editbox.thtml:57
+msgid "devcp_editbox_new_version"
+msgstr "Nueva versión"
+
+#: views/elements/developers/editbox.thtml:49
+msgid "devcp_editbox_properties"
+msgstr "Propiedades"
+
+#: views/elements/developers/editbox.thtml:60
+msgid "devcp_editbox_screenshots"
+msgstr "Capturas de pantalla"
+
+#: views/elements/developers/editbox.thtml:53
+msgid "devcp_editbox_statistics_dashboard"
+msgstr "Panel de estadísticas"
+
+#: views/elements/developers/editbox.thtml:54
+msgid "devcp_editbox_versions"
+msgstr "Versiones y archivos"
+
+#: views/elements/developers/editbox.thtml:42
+msgid "devcp_editbox_view_listing"
+msgstr "Ver en la web"
+
+#: views/elements/developers/editorsmenu.thtml:59
+msgid "devcp_editorsqueue_featured"
+msgstr "Complementos destacados"
+
+#. %1 is the review count
+#: views/elements/developers/editorsqueue.thtml:42
+#: views/elements/developers/editorsmenu.thtml:56
+#, php-format
+msgid "devcp_editorsqueue_moderatedreviews"
+msgid_plural "devcp_editorsqueue_moderatedreviews"
+msgstr[0] "Una valoración por moderar"
+msgstr[1] "Valoraciones por moderar (%s)"
+
+#. %1 is the nominated addons count
+#: views/elements/developers/editorsqueue.thtml:44
+#: views/elements/developers/editorsmenu.thtml:58
+#, php-format
+msgid "devcp_editorsqueue_nominated"
+msgid_plural "devcp_editorsqueue_nominated"
+msgstr[0] "Un complemento propuesto"
+msgstr[1] "Complementos propuestos (%s)"
+
+#. %1 is the update count
+#: views/elements/developers/editorsqueue.thtml:43
+#: views/elements/developers/editorsmenu.thtml:57
+#, php-format
+msgid "devcp_editorsqueue_pendingupdates"
+msgid_plural "devcp_editorsqueue_pendingupdates"
+msgstr[0] "Una actualización pendiente"
+msgstr[1] "Actualizaciones pendientes (%s)"
+
+#: controllers/statistics_controller.php:147
+#: controllers/statistics_controller.php:361
+#: controllers/previews_controller.php:108
+#: controllers/previews_controller.php:211
+#: controllers/previews_controller.php:312
+msgid "devcp_error_addon_access_denied"
+msgstr "No tienes acceso a ese complemento."
+
+#. %s is a complete URL with the text from devcp_error_appversion_reference_link_text
+#. in the <a> tag. This should be fixed.
+#: controllers/components/developers.php:591
+#, php-format
+msgid "devcp_error_appversion_reference_link"
+msgstr "Por favor, lee %s para más información."
+
+#. This is the link text in the <a> for devcp_error_appversion_reference_link. This
+#. should be fixed.
+#: controllers/components/developers.php:591
+msgid "devcp_error_appversion_reference_link_text"
+msgstr "esta página"
+
+#: views/developers/addon_edit_authors.thtml:76
+msgid "devcp_error_empty_authors"
+msgstr "Tu complemente debe tener al menos un propietario."
+
+#. %1$s is the name of the file
+#: controllers/components/developers.php:658
+msgid "devcp_error_file_exists"
+msgstr ""
+"Ya existe una versión de ese complemento. Para reemplazarla, debes borrar "
+"primero el archivo %1$s."
+
+#. %1$s is a file extension. Example: .exe
+#. %2$s is a comma separated list of extensions. Example: .xpi, .jar
+#: controllers/components/developers.php:355
+#, php-format
+msgid "devcp_error_file_extension"
+msgstr ""
+"No está permitido esa extensión de archivo (%s) para el tipo de complemento "
+"seleccionado. Por favor, usa una de los siguientes: %s"
+
+#: controllers/components/developers.php:64
+msgid "devcp_error_five_categories"
+msgstr "Por favor, no elija más de cinco categorías."
+
+#: controllers/components/developers.php:526
+msgid "devcp_error_guid_application"
+msgstr "El ID de este complemento ya está en uso por una aplicación."
+
+#: controllers/components/developers.php:337
+#: controllers/components/developers.php:389
+msgid "devcp_error_http_incomplete"
+msgstr "Transferencia incompleta"
+
+#: controllers/components/developers.php:335
+#: controllers/components/developers.php:336
+#: controllers/components/developers.php:387
+#: controllers/components/developers.php:388
+msgid "devcp_error_http_maxupload"
+msgstr "Sobrepasa el tamaño máximo de subida"
+
+#: controllers/components/developers.php:338
+#: controllers/components/developers.php:390
+msgid "devcp_error_http_nofile"
+msgstr "No se subió ningún archivo"
+
+#. %1$s is a file extension. Example: .exe
+#. %2$s is a comma separated list of extensions. Example: .xpi, .jar
+#: controllers/components/developers.php:401
+#, php-format
+msgid "devcp_error_icon_extension"
+msgstr ""
+"No está permitida esa extensión de archivo (%s) para un icono. Por favor, "
+"elige una de las siguientes: %s"
+
+#: controllers/developers_controller.php:504
+msgid "devcp_error_index_rdf_notfound"
+msgstr "No está presente el archivo install.rdf."
+
+#: controllers/components/developers.php:601
+msgid "devcp_error_install_manifest"
+msgstr "Se encontraron los siguientes errores en el install.rdf:"
+
+#: controllers/developers_controller.php:1463
+msgid "devcp_error_invalid_addontype"
+msgstr "Por favor, seleccione un tipo válido de complemento."
+
+#. %$1s is a version. Example: 3.1.1
+#. %$2s is an add-on name.
+#: controllers/components/developers.php:569
+#: controllers/components/developers.php:581
+#, php-format
+msgid "devcp_error_invalid_appversion"
+msgstr "%s no es una versión válida para %s"
+
+#. %s is a string
+#: controllers/components/developers.php:521
+#, php-format
+msgid "devcp_error_invalid_guid"
+msgstr "El ID de este complemento no es válido: %s"
+
+#. %$1s is a version. Example: 3.1.1
+#. %$2s is an add-on name.
+#: controllers/components/developers.php:572
+#, php-format
+msgid "devcp_error_invalid_minversion"
+msgstr ""
+"%s no es una versión válida para %s: las versiones mínimas no pueden "
+"contener *"
+
+#: controllers/components/developers.php:536
+msgid "devcp_error_invalid_version"
+msgstr ""
+"La version de este complemento no es válida: por favor, lee las <a href="
+"\"http://developer.mozilla.org/es/docs/Formato_para_la_versi%C3%"
+"B3n_del_Toolkit\">especificaciones</a>"
+
+#: controllers/components/developers.php:531
+msgid "devcp_error_invalid_version_spaces"
+msgstr ""
+"La versión de este complemento no es válida: las versiones no pueden "
+"contener espacios."
+
+#. %s is an error message from the parser.
+#: controllers/components/developers.php:501
+#, php-format
+msgid "devcp_error_manifest_parse"
+msgstr ""
+"Ocurrieron los siguientes errores mientras se analizaba el install.rdf: %s"
+
+#: controllers/components/developers.php:373
+msgid "devcp_error_move_file"
+msgstr "No se puede mover el archivo"
+
+#. %s is the name of a file
+#: controllers/components/developers.php:650
+#: controllers/components/developers.php:662
+#: controllers/components/developers.php:667
+#: controllers/components/developers.php:727
+#: controllers/components/developers.php:738
+#: controllers/components/developers.php:743
+#, php-format
+msgid "devcp_error_moving_file"
+msgstr "Ocurrió un error al mover %s."
+
+#: controllers/components/developers.php:595
+msgid "devcp_error_mozilla_application"
+msgstr ""
+"Debes incluir en las aplicaciones destino al menos una aplicación válida de "
+"Mozilla."
+
+#: controllers/components/developers.php:516
+msgid "devcp_error_no_guid"
+msgstr ""
+"No se encontró ningún un ID en el archivo install.rdf de este complemento."
+
+#: controllers/components/developers.php:287
+msgid "devcp_error_no_platform"
+msgstr "No se seleccionó ninguna plataforma"
+
+#: controllers/components/developers.php:59
+msgid "devcp_error_one_category"
+msgstr "Por favor, elige al menos una categoría."
+
+#: controllers/components/developers.php:92
+msgid "devcp_error_one_user"
+msgstr "Este complemento debe tener al menos un autor."
+
+#. %1$s is a file extension. Example: .exe
+#. %2$s is a comma separated list of extensions. Example: .xpi, .jar
+#: controllers/components/developers.php:1081
+#, php-format
+msgid "devcp_error_preview_extension"
+msgstr ""
+"No está permitida esa extensión de archivo (%s) para las vistas previas. Por "
+"favor, usa una de las siguientes: %s"
+
+#: controllers/components/developers.php:511
+msgid "devcp_error_updatekey"
+msgstr ""
+"Los complementos no pueden usar un updateKey. Por favor, elimina esto del "
+"install.rdf e intentalo de nuevo."
+
+#: controllers/components/developers.php:506
+msgid "devcp_error_updateurl"
+msgstr ""
+"Los complementos no pueden usar una updateURL externa. Por favor, elimina "
+"esto del install.rdf e intentalo de nuevo."
+
+#: controllers/developers_controller.php:465
+#: controllers/components/developers.php:271
+msgid "devcp_error_upload_file"
+msgstr "Por favor, suba un archivo."
+
+#: views/developers/uploader.thtml:135
+msgid "devcp_input_upload_file"
+msgstr "Subir un archivo"
+
+#: views/pages/js_constants.js.thtml:89
+msgid "devcp_js_a_cancel"
+msgstr "Cancelar"
+
+#: views/pages/js_constants.js.thtml:90
+msgid "devcp_js_add_email"
+msgstr "Por favor, introduce la cuenta de correo del autor que quieres añadir."
+
+#. alt text for a down-arrow image.
+#: views/pages/js_constants.js.thtml:81
+msgid "devcp_js_img_move_down"
+msgstr "Bajar"
+
+#. alt text for an up-arrow image.
+#: views/pages/js_constants.js.thtml:82
+msgid "devcp_js_img_move_up"
+msgstr "Subir"
+
+#: views/pages/js_constants.js.thtml:91
+msgid "devcp_js_img_remove_compat"
+msgstr "Borrar la compatibilidad con la aplicación"
+
+#: views/pages/js_constants.js.thtml:86
+msgid "devcp_js_input_list_author"
+msgstr "Mostrar como autor en los listados públicos"
+
+#: views/pages/js_constants.js.thtml:92
+msgid "devcp_js_license_select"
+msgstr "Por favor, selecciona una licencia."
+
+#: views/pages/js_constants.js.thtml:93
+msgid "devcp_js_license_text"
+msgstr "Introduce el texto para tu licencia."
+
+#. <option> text in a <select> for Author role in an add-on.
+#: views/pages/js_constants.js.thtml:84
+msgid "devcp_js_option_developer"
+msgstr "Desarrollador"
+
+#. <option> text in a <select> for Author role in an add-on.
+#: views/pages/js_constants.js.thtml:83
+msgid "devcp_js_option_owner"
+msgstr "Propietario"
+
+#. <option> text in a <select> for Author role in an add-on.
+#: views/pages/js_constants.js.thtml:85
+msgid "devcp_js_option_viewer"
+msgstr "Visualizador"
+
+#: views/pages/js_constants.js.thtml:88
+msgid "devcp_js_remove_author"
+msgstr "Eliminar autor"
+
+#: views/pages/js_constants.js.thtml:87
+msgid "devcp_js_sure_remove"
+msgstr "¿<strong>Seguro</strong> que quieres eliminar este autor?"
+
+#: views/pages/js_constants.js.thtml:77
+msgid "devcp_js_upload_alert"
+msgstr "Debes seleccionar un archivo para subir."
+
+#. %1$s is an addon id, like 32.
+#. %2$s is a version number, like 3.5.
+#: controllers/components/developers.php:1212
+msgid "devcp_license_existing"
+msgstr "Licencia personalizada del complemento %1$s v%2$s"
+
+#: views/elements/developers/localebox.thtml:44
+msgid "devcp_localebox_header_localizedfields"
+msgstr "Campos localizables"
+
+#. %1 is the default locale
+#: views/elements/developers/localebox.thtml:48
+#, php-format
+msgid "devcp_localebox_intro"
+msgstr ""
+"Algunos de los campos de esta página son localizables para que aparezcan en "
+"las páginas finales de usuario en su idioma nativo. Elige un idioma abajo "
+"para editar los detalles de tu complemento en ese idioma. Si no está "
+"disponible la traducción para un idioma, se mostrará la elegida en el idioma "
+"por defecto (%s)."
+
+#: views/elements/developers/sidebar.thtml:68
+#: views/elements/developers/myaddons.thtml:75
+msgid "devcp_myaddons_admincp_link"
+msgstr "Herramientas del administrador"
+
+#: views/elements/developers/sidebar.thtml:65
+#: views/elements/developers/myaddons.thtml:72
+msgid "devcp_myaddons_editorcp_link"
+msgstr "Herramientas del editor"
+
+#: views/elements/developers/myaddons.thtml:52
+msgid "devcp_myaddons_link"
+msgstr "Mis complementos"
+
+#: views/elements/developers/sidebar.thtml:70
+#: views/elements/developers/myaddons.thtml:77
+msgid "devcp_myaddons_mainpage_link"
+msgstr "Volver a la página inicial"
+
+#: views/elements/developers/sidebar.thtml:63
+#: views/elements/developers/myaddons.thtml:70
+msgid "devcp_myaddons_statistics_link"
+msgstr "Panel de estadísticas"
+
+#: views/elements/developers/sidebar.thtml:62
+#: views/elements/developers/myaddons.thtml:69
+msgid "devcp_myaddons_submitaddon_link"
+msgstr "Enviar un complemento"
+
+#: views/elements/developers/sidebar.thtml:48
+#: views/elements/developers/myaddons.thtml:67
+msgid "devcp_myaddons_title"
+msgstr "Herramientas del desarrollador"
+
+#. %1$s is an add-on ID, perhaps 167.
+#. %2$s is a URL.
+#: controllers/developers_controller.php:256
+msgid "devcp_new_addon_error"
+msgstr ""
+"El ID de este complemento (%1$s) ya existe en la base de datos. Si es tu "
+"complemento, puedes <a href=\"%2$s\">enviar una nueva versión</a>."
+
+#: views/developers/addon_status_nominate.thtml:62
+msgid "devcp_nominate_cancel"
+msgstr "Cancelar y volver"
+
+#. %1 is the add-on name
+#: views/developers/addon_status_nominate.thtml:61
+#, php-format
+msgid "devcp_nominate_submit_nominate"
+msgstr "Proponer %s"
+
+#: views/developers/addon_edit_properties.thtml:50
+#: views/developers/addon_status.thtml:49
+#: views/developers/versions_edit.thtml:50
+msgid "devcp_notice_changes_error"
+msgstr ""
+"<span>Uno o más de tus cambios no han podido guardarse.</span><br />Por "
+"favor, revisa los errores a continuación. El resto de tus cambios se han "
+"guardado correctamente."
+
+#: views/developers/addon_edit_authors.thtml:47
+#: views/developers/addon_edit_properties.thtml:47
+#: views/developers/addon_status.thtml:46
+#: views/developers/addon_edit_descriptions.thtml:47
+#: views/developers/versions_edit.thtml:47
+#: views/developers/addon_edit_categories.thtml:46
+msgid "devcp_notice_changes_saved"
+msgstr ""
+"<span>Tus cambios se han guardado.</span><br />Por favor, ten en cuenta que "
+"algunos cambios pueden tardar varias horas en aparecer en todas las zonas de "
+"la página web."
+
+#: controllers/previews_controller.php:252
+msgid "devcp_notice_cleardefault"
+msgstr ""
+"Eliminar esta como la vista previa por defecto hará que otra vista previa se "
+"convierta automáticamente en la vista previa por defecto."
+
+#: controllers/previews_controller.php:184
+#: controllers/previews_controller.php:251
+msgid "devcp_notice_makedefault"
+msgstr ""
+"Hacer esta su vista previa por defecto eliminará el estado por defecto de su "
+"actual vista previa por defecto."
+
+#: views/developers/addon_edit_authors.thtml:70
+msgid "devcp_notice_unsaved_changes"
+msgstr "Tienes cambios sin guardar."
+
+#: controllers/developers_controller.php:87
+#: controllers/developers_controller.php:97
+#: controllers/developers_controller.php:100
+#: controllers/previews_controller.php:67
+#: controllers/previews_controller.php:79
+#: controllers/previews_controller.php:82
+msgid "devcp_pagetitle"
+msgstr "Herramientas del desarrollador"
+
+#: controllers/previews_controller.php:103
+#: controllers/previews_controller.php:104
+msgid "devcp_preview_add_pagetitle"
+msgstr "Añadir vista previa"
+
+#: controllers/previews_controller.php:135
+msgid "devcp_preview_added_successfully"
+msgstr "Vista previa añadida con éxito."
+
+#: controllers/previews_controller.php:323
+msgid "devcp_preview_deleted_successfully"
+msgstr "Vista previa eliminada con éxito."
+
+#: controllers/previews_controller.php:194
+#: controllers/previews_controller.php:195
+msgid "devcp_preview_edit_pagetitle"
+msgstr "Editar vista previa"
+
+#: controllers/previews_controller.php:237
+msgid "devcp_preview_updated_successfully"
+msgstr "Vista previa actualizada con éxito."
+
+#: views/developers/previews.thtml:120
+msgid "devcp_previews_a_another"
+msgstr "Añadir otra captura"
+
+#: views/developers/previews.thtml:96
+msgid "devcp_previews_a_delete"
+msgstr "Borrar captura"
+
+#: views/developers/previews.thtml:95
+msgid "devcp_previews_a_replace"
+msgstr "Reemplazar captura"
+
+#: views/developers/previews.thtml:126
+msgid "devcp_previews_a_update"
+msgstr "Actualizar capturas"
+
+#: views/developers/previews.thtml:115 views/developers/previews.thtml:124
+msgid "devcp_previews_add_new"
+msgstr "Añadir nueva captura"
+
+#. %s is a list of file extensions, e.g. ".png, .gif"
+#: views/developers/previews.thtml:116
+msgid "devcp_previews_add_select"
+msgstr ""
+"Selecciona una imagen para enviar a continuación. Las imágenes mayores de un "
+"tamaño máximo de 700 pixels de ancho por 525 serán redimensionadas. Tipos de "
+"archivos permitidos: %s"
+
+#: views/developers/previews.thtml:121
+msgid "devcp_previews_click_below"
+msgstr "Haz clic en actualizar captura a continuación para enviar."
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/previews.thtml:102
+msgid "devcp_previews_click_update"
+msgstr ""
+"Haz clic el botón actualizar capturas para guardar la imagen . (<a %"
+"s>¿Cancelar?</a>)"
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/previews.thtml:107
+msgid "devcp_previews_error_message"
+msgstr ""
+"Esta captura se borrará cuando pulses actualizar capturas. (<a %s>¿Cancelar?"
+"</a>)"
+
+#: views/previews/add.thtml:45
+msgid "devcp_previews_filetype_info"
+msgstr ""
+"Usa el formulario de abajo para subir una captura de pantalla en PNG, JPG, o "
+"GIF de tu complemento. Las imágenes mayores de 700 pixels de ancho y 525 "
+"pixels alto será redimensionadas automáticamente."
+
+#: views/previews/add.thtml:43
+msgid "devcp_previews_header_add"
+msgstr "Añadir vista previa"
+
+#: views/developers/previews.thtml:80
+msgid "devcp_previews_header_caption"
+msgstr "Título de la captura"
+
+#: views/previews/edit.thtml:43
+msgid "devcp_previews_header_edit"
+msgstr "Editar vista previa"
+
+#: views/developers/previews.thtml:93
+msgid "devcp_previews_label_default"
+msgstr "Captura por defecto"
+
+#: views/previews/add.thtml:54
+msgid "devcp_previews_label_file"
+msgstr "Vista previa del archivo"
+
+#: views/previews/add.thtml:59 views/previews/edit.thtml:50
+msgid "devcp_previews_label_makedefault"
+msgstr "Hacer esta la vista previa por defecto"
+
+#: views/developers/previews.thtml:100
+msgid "devcp_previews_label_new"
+msgstr "Nueva imagen:"
+
+#: views/developers/previews.thtml:118
+msgid "devcp_previews_label_upload"
+msgstr "Enviar captura:"
+
+#: views/developers/previews.thtml:50
+msgid "devcp_previews_notice_error"
+msgstr "Una o varias de tus capturas no se han podido guardar."
+
+#: views/developers/previews.thtml:47
+msgid "devcp_previews_notice_success"
+msgstr "Tus capturas se han actualizado correctamente."
+
+#: views/developers/previews.thtml:59
+msgid "devcp_previews_p_screenshots"
+msgstr ""
+"Las capturas de pantalla de tu complemento se muestran abajo y puedes hacer "
+"cambios a sus descripciones e imágenes. La captura por defecto en la que se "
+"muestra al lado en el listado de complementos tras una búsqueda."
+
+#: views/previews/edit.thtml:55
+msgid "devcp_previews_submit_delete"
+msgstr "Borrar vista previa"
+
+#: views/previews/edit.thtml:55
+msgid "devcp_previews_submit_delete_confirm"
+msgstr "¿Estás seguro de borrar esta vista previa?"
+
+#: views/previews/edit.thtml:54
+msgid "devcp_previews_submit_edit"
+msgstr "Editar la vista previa"
+
+#: views/previews/add.thtml:63
+msgid "devcp_previews_submit_upload"
+msgstr "Subir vista previa"
+
+#: views/developers/previews.thtml:78
+msgid "devcp_previews_thumbnail"
+msgstr "Miniatura"
+
+#. %s is the add-on name.
+#: views/developers/previews.thtml:44
+msgid "devcp_previews_title"
+msgstr "Administrador de capturas de %s"
+
+#: views/developers/uploader.thtml:74
+msgid "devcp_review_agreement_please"
+msgstr ""
+"Por favor, revisa y acepta el siguiente acuerdo de desarrollador antes de "
+"proceder."
+
+#: views/elements/developers/rolecheck.thtml:42
+msgid "devcp_rolecheck_no_privs"
+msgstr ""
+"<span>No tienes permisos suficientes para hacer cambios en esta página.</"
+"span><br />Contacta con el propietario del complemento si necesitas hacer "
+"cambios."
+
+#: controllers/developers_controller.php:1315
+msgid "devcp_several_hours"
+msgstr ""
+"Por favor, ten en cuenta que algunos cambios tardarán varias horas en "
+"aparecer en todas las áreas de la web."
+
+#: views/elements/developers/sidebar.thtml:52
+msgid "devcp_sidebar_a_dashboard"
+msgstr "Panel"
+
+#. %s is a number
+#: views/elements/developers/statsbar.thtml:45
+#: views/developers/dashboard.thtml:79
+#, php-format
+msgid "devcp_statsbar_adu"
+msgstr "<em>%s</em> usuarios activos al día"
+
+#. %s is a number
+#: views/elements/developers/statsbar.thtml:41
+#: views/developers/dashboard.thtml:75
+#, php-format
+msgid "devcp_statsbar_total_downloads"
+msgstr "<em>%s</em> descargas totales"
+
+#. %s is a number
+#: views/elements/developers/statsbar.thtml:43
+#: views/developers/dashboard.thtml:77
+#, php-format
+msgid "devcp_statsbar_weekly_downloads"
+msgstr "<em>%s</em> descargas semanales"
+
+#: views/developers/addon_status_confirm.thtml:59
+msgid "devcp_status_confirm_active"
+msgstr ""
+"Al marcar este complemento como activo, harás que se muestre en todas las "
+"áreas públicas donde corresponda por su estado, incluyendo las búsquedas y "
+"listados. Podrá ser descargado desde la web y podrán pedirse actualizaciones "
+"desde los clientes, dependiendo de su estado. Podrás volver aquí y "
+"desactivarlo de nuevo cuando lo desees."
+
+#: views/developers/addon_status_confirm.thtml:59
+msgid "devcp_status_confirm_active_sure"
+msgstr "¿Seguro que quieres marcar este complemente como activo?"
+
+#: views/developers/addon_status_confirm.thtml:50
+msgid "devcp_status_confirm_header_sure"
+msgstr "¿Estás seguro?"
+
+#: views/developers/addon_status_confirm.thtml:55
+msgid "devcp_status_confirm_inactive"
+msgstr ""
+"Al marcar este complemento como inactivo, harás que no se muestre en ningún "
+"área pública donde corresponda por su estado, incluyendo las búsquedas y "
+"listados. No podrá ser descargado desde la web y no se podrán pedir "
+"actualizaciones desde los clientes. Podrás volver aquí y activarlo de nuevo "
+"cuando lo desees."
+
+#: views/developers/addon_status_confirm.thtml:55
+msgid "devcp_status_confirm_inactive_sure"
+msgstr "¿Seguro que quieres marcar este complemente como inactivo?"
+
+#: views/developers/addon_status_confirm.thtml:74
+msgid "devcp_status_confirm_no"
+msgstr "No, cancelar"
+
+#: views/developers/addon_status_confirm.thtml:67
+msgid "devcp_status_confirm_public"
+msgstr ""
+"Al marcar este complemento como público harás que esté disponible para su "
+"descargar por cualquiera y se empezarán a servir actualizaciones los "
+"usuarios actuales."
+
+#: views/developers/addon_status_confirm.thtml:67
+msgid "devcp_status_confirm_public_sure"
+msgstr "¿Estás seguro de querer hacer este complemento público?"
+
+#: views/developers/addon_status_confirm.thtml:63
+msgid "devcp_status_confirm_sandbox"
+msgstr ""
+"Al mover este complemento al área de pruebas, los usuarios tendrán que "
+"conectarse antes de poder descargarlo, y las actualizaciones no se ofrecerán "
+"a los usuarios existentes. Ya que tu complemento es actualmente público, "
+"podrás volver aquí en cualquier momento y volver a hacerlo público."
+
+#: views/developers/addon_status_confirm.thtml:63
+msgid "devcp_status_confirm_sandbox_sure"
+msgstr "¿Estás seguro de mover este complemento al área de pruebas?"
+
+#: views/developers/addon_status_confirm.thtml:73
+msgid "devcp_status_confirm_yes"
+msgstr "Sí, estoy seguro"
+
+#: views/developers/addon_status_nominate.thtml:46
+msgid "devcp_status_nominate_error_notice"
+msgstr ""
+"<span>Es necesario un mensaje para la propuesta.</span><br />Por favor, "
+"rellena el cuadro de texto con la información solicitada e inténtalo de "
+"nuevo."
+
+#: views/developers/addon_status_nominate.thtml:55
+msgid "devcp_status_nominate_header"
+msgstr "Propuesta de complemento"
+
+#: views/developers/dashboard.thtml:85
+msgid "devcp_summary_lastversion"
+msgstr "Última versión:"
+
+#. %s is the add-on name.
+#: views/developers/addon_edit.thtml:43
+#: views/developers/addon_edit_authors.thtml:44
+#: views/developers/versions_delete.thtml:43
+#: views/developers/addon_edit_properties.thtml:44
+#: views/developers/addon_edit_descriptions.thtml:44
+#: views/developers/versions_edit.thtml:44
+#: views/developers/addon_edit_categories.thtml:43
+#: views/developers/versions.thtml:43
+msgid "devcp_title_edit_addon"
+msgstr "Editar %s"
+
+#. title attribute for a javascript link that pops up a help dialog.
+#: views/elements/translationbox.thtml:68
+msgid "devcp_transbox_a_title_help"
+msgstr "Ayuda (no abandonar la página)"
+
+#: views/elements/translationbox.thtml:68
+msgid "devcp_transbox_alt_help"
+msgstr "Ayuda"
+
+#. %1$s is <span>17</span>, %2$s is 42.
+#: views/elements/translationbox.thtml:101
+msgid "devcp_transbox_chars_used"
+msgstr "Caracteres usados: %1$s / %2$s"
+
+#: views/elements/translationbox.thtml:132
+msgid "devcp_transbox_delete_sure"
+msgstr "¿Estás seguro de que quieres borrar esta traducción?"
+
+#. %s is a locale, like en-US.
+#: views/elements/translationbox.thtml:143
+msgid "devcp_transbox_help_header_tabs"
+msgstr "¿Qué son estas %s pestañas?"
+
+#: views/elements/translationbox.thtml:145
+msgid "devcp_transbox_help_header_what"
+msgstr "¿Qué pasa si no tengo ninguna traducción?"
+
+#: views/elements/translationbox.thtml:147
+msgid "devcp_transbox_help_hide"
+msgstr "Ocultar ayuda"
+
+#: views/elements/translationbox.thtml:146
+msgid "devcp_transbox_help_if"
+msgstr ""
+"Si un usuario visita el sitio y la traducción de su propio idioma no está "
+"disponible, se usará el idioma por defecto de tu complemento, especificado "
+"en el área de edición de las propiedades del complemento. Si no tienes "
+"ninguna traducción, introduce lo que puedas en tu idioma por defecto, que "
+"debe ser un idioma que hables."
+
+#: views/elements/translationbox.thtml:144
+msgid "devcp_transbox_help_transbox"
+msgstr ""
+"Este es un <i>cuadro de traducción</i>. Te permite traducir un campo "
+"concreto en otro idioma, para el que debes tener una traducción. Puedes "
+"añadir, editar y borrar las traducciones usando las pestañas de idioma."
+
+#: views/elements/translationbox.thtml:85
+msgid "devcp_transbox_img_add_trans"
+msgstr "Añadir traducción"
+
+#: views/elements/translationbox.thtml:86
+msgid "devcp_transbox_img_remove_trans"
+msgstr "Borrar traducción"
+
+#: views/elements/translationbox.thtml:123
+msgid "devcp_transbox_input_add_all"
+msgstr "Añadir idioma a todos"
+
+#: views/elements/translationbox.thtml:122
+msgid "devcp_transbox_input_add_locale"
+msgstr "Añadir traducción"
+
+#: views/elements/translationbox.thtml:124
+#: views/elements/translationbox.thtml:135
+msgid "devcp_transbox_input_cancel"
+msgstr "Cancelar"
+
+#: views/elements/translationbox.thtml:134
+msgid "devcp_transbox_input_delete"
+msgstr "Borrar elemento"
+
+#: views/elements/translationbox.thtml:113
+msgid "devcp_transbox_select_locale"
+msgstr "Selecciona el idioma de la traducción a añadir:"
+
+#. %1$s and %2$s are GUIDs.
+#: controllers/developers_controller.php:343
+msgid "devcp_update_addon_guid_error"
+msgstr ""
+"El GUID del complemento usado en este archivo (%1$s) no se corresponde con "
+"el GUID existente para este complemento (%2$s)."
+
+#: controllers/developers_controller.php:334
+msgid "devcp_update_addon_priv_error"
+msgstr ""
+"No tienes los privilegios suficientes para actualizar este complemento."
+
+#. %1$s is a version number, %2$s is an add-on ID.
+#: controllers/developers_controller.php:399
+msgid "devcp_update_addon_version_belong_error"
+msgstr "La versión espeficada (%1$s) no pertenece a este complemento (%2$s)."
+
+#. %1$s is a version number, maybe 1.1.
+#. %2$s is a URL.
+#: controllers/developers_controller.php:351
+msgid "devcp_update_addon_version_exists_error"
+msgstr ""
+"El número de la versión enviada (%1$s) ya existe para este complemento. Si "
+"estás intentando añadir otro archivo para esta versión, <a href=\"%2$s"
+"\">pulsa aquí</a>."
+
+#. %1$s and %2$s are version numbers.
+#: controllers/developers_controller.php:405
+msgid "devcp_update_addon_version_match_error"
+msgstr ""
+"El número de la versión enviada (%1$s) no corresponde con el número de la "
+"versión existente (%2$s)."
+
+#: views/developers/uploader.thtml:68
+msgid "devcp_uploader_a_start"
+msgstr "Comenzar"
+
+#: views/developers/uploader.thtml:137
+msgid "devcp_uploader_ajax_loading"
+msgstr "Enviando archivo..."
+
+#: views/developers/uploader.thtml:82
+msgid "devcp_uploader_button_agree"
+msgstr "Aceptar y continuar"
+
+#: views/developers/uploader.thtml:157
+msgid "devcp_uploader_button_edit"
+msgstr "Editar mi complemento"
+
+#: views/developers/uploader.thtml:158
+msgid "devcp_uploader_button_later"
+msgstr "Completaré mi complemento después"
+
+#: views/developers/uploader.thtml:168
+msgid "devcp_uploader_button_release"
+msgstr "Añadir notas de la versión"
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/uploader.thtml:156
+msgid "devcp_uploader_created_results"
+msgstr ""
+"<p>El listado de tu complemento se ha creado correctamente. La información "
+"básica obtenida de tu archivo enviado se ha guardado, pero hay más datos en "
+"tu listado que puedes personalizar.</p><p>Tu complemento está actualmente "
+"marcado como <strong>incompleto</strong>. Para completar tu complemento, "
+"debes asegurarte que tiene un nombre preciso, resumen y descripción, así "
+"como al menos una categoría seleccionada. Puedes editar la información del "
+"complemento usando el siguiente enlace y comprobando el estado cada vez en "
+"la <a %s>página de estado</a>."
+
+#: views/developers/uploader.thtml:143
+msgid "devcp_uploader_error_correct"
+msgstr "Por favor, corrige este problema y vuelve a enviar el archivo."
+
+#. %1$s is a version number, %2$s is a status, e.g Public or Incomplete.
+#: views/developers/uploader.thtml:175
+msgid "devcp_uploader_file_created"
+msgstr ""
+"Tu nuevo archivo se ha añadido a la versión %1$s y está actualmente marcado "
+"como %2$s."
+
+#: views/developers/uploader.thtml:154
+msgid "devcp_uploader_header_created"
+msgstr "¡Complemento creado!"
+
+#: views/developers/uploader.thtml:141
+msgid "devcp_uploader_header_error"
+msgstr "¡Vaya! Parece que hay un problema con este archivo..."
+
+#: views/developers/uploader.thtml:173
+msgid "devcp_uploader_header_file_added"
+msgstr "¡Archivo añadido!"
+
+#: views/developers/uploader.thtml:66
+msgid "devcp_uploader_header_how"
+msgstr "¿Cómo funciona todo?"
+
+#. %s is the version number, e.g. 3.2.
+#: views/developers/uploader.thtml:163
+msgid "devcp_uploader_header_update_created"
+msgstr "Versión %s creada"
+
+#: views/developers/uploader.thtml:117
+msgid "devcp_uploader_header_upload"
+msgstr "Envía tu archivo"
+
+#: views/developers/uploader.thtml:67
+msgid "devcp_uploader_how"
+msgstr ""
+"<p>Gracias por tu interés en enviar tu complemento a Mozilla Add-ons. Alojar "
+"tu complemento en Mozilla Add-ons es la manera más sencilla de distribuir tu "
+"complento. Esto es lo que tendrás:</p><ul><li>Cada complemento tiene su "
+"página pública que muestra la información que proporcionas, como un breve "
+"resumen de la funcionalidad del complemento, una descripción más larga de "
+"modo opcional, y una presentación de vistas previas de tu complemento.</"
+"li><li>tu complemento aparecerá en las búsquedas del sitio, e incluso en el "
+"administrador de complementos de Firefox 3.</li><li>Nosotros nos encargamos "
+"el alojamiento de todas tus descargas y proporcionamos las actualizaciones "
+"automáticas a los usuarios cuando envías una nueva versión.</li><li>Tendrás "
+"acceso a un panel de estadísticas con información detallada sobre tus "
+"usuarios.</li></ul><p>Los complementos alojados en el sitio tienen que ser "
+"revisados por un editor de Mozilla Add-ons antes de tener todos los puntos "
+"listados anteriormente. Si estás preparado para iniciar el proceso y tienes "
+"tu complemento listo para enviar, tan sólo pulsa en la opción de iniciar</p>"
+
+#: views/developers/uploader.thtml:125
+msgid "devcp_uploader_label_platformtype"
+msgstr "Plataformas soportadas:"
+
+#: views/developers/uploader.thtml:124
+msgid "devcp_uploader_label_upload_field"
+msgstr "Archivo de complemento:"
+
+#: controllers/components/developers.php:1221
+msgid "devcp_uploader_option_other"
+msgstr "Otro"
+
+#. %1$s is a number, %2$s is href="..." and should stay in the <a> tag.
+#: views/developers/uploader.thtml:176
+msgid "devcp_uploader_p_pending_file"
+msgstr ""
+"El nuevo archivo estará disponible de forma pública tan pronto como un "
+"editor lo revise. Actualmente hay otros %1$s complementos en la cola. "
+"¿Quieres ser revisado más rápido? Piensa en la opción de <a %2$s>hacerte "
+"editor</a>."
+
+#. %1$s is a number, %2$s is href="..." and should stay in the <a> tag.
+#: views/developers/uploader.thtml:166
+msgid "devcp_uploader_p_pending_version"
+msgstr ""
+"La nueva versión estará disponible de forma pública tan pronto como un "
+"editor lo revise. Actualmente hay otros %1$s complementos en la cola. "
+"¿Quieres ser revisado más rápido? Piensa en la opción de <a %2$s>hacerte "
+"editor</a>."
+
+#. %s is a status, e.g Public or Incomplete.
+#: views/developers/uploader.thtml:165
+msgid "devcp_uploader_p_update_created"
+msgstr "Tu nueva versión se ha creado y está actualmente marcada como %s."
+
+#. %1$s is href="..." and should stay in the 'Versions and Files' <a> tag.
+#. %2$s is href="..." and should stay in the 'current status' <a> tag.
+#: views/developers/uploader.thtml:177
+msgid "devcp_uploader_p_update_file"
+msgstr ""
+"Comprueba tus nuevos archivos en la <a %1$s>página de versiones y archivos</"
+"a>, comprueba el <a %2$s>estado actual</a> de tu complemento, o <b>añade las "
+"notas de la versión</b> pulsando en el siguiente botón (muy recomendable)."
+
+#. %1$s is href="..." and should stay in the 'Versions and Files' <a> tag.
+#. %2$s is href="..." and should stay in the 'current status' <a> tag.
+#: views/developers/uploader.thtml:167
+msgid "devcp_uploader_p_update_version"
+msgstr ""
+"Comprueba tu nueva versión en la <a %1$s>página de versiones y archivos</"
+"a>, comprueba el <a %2$s>estado actual</a> de tu complemento, o <b>añade las "
+"notas de la versión</b> pulsando en el siguiente botón (muy recomendable)."
+
+#: views/developers/uploader.thtml:118
+msgid "devcp_uploader_p_upload"
+msgstr ""
+"Envía el archivo de tu complemento usando el siguiente formulario. Si tiene "
+"varios archivos dependientes de la plataforma, selecciona un único archivo y "
+"después envía el resto usando el administrador de versiones y archivos."
+
+#: views/developers/uploader.thtml:125
+msgid "devcp_uploader_platformtype_all"
+msgstr "Todas"
+
+#: views/developers/uploader.thtml:126
+msgid "devcp_uploader_platformtype_specific"
+msgstr "Específica:"
+
+#. Used as first item in a <select>.
+#: controllers/components/developers.php:1185
+msgid "devcp_uploader_please_choose"
+msgstr "Por favor, selecciona..."
+
+#. %1$s is the add-on name, %2$s is the version number.
+#: views/developers/uploader.thtml:57
+msgid "devcp_uploader_title_file"
+msgstr "Añadir archivo a %1$s %2$s"
+
+#: views/developers/uploader.thtml:50
+msgid "devcp_uploader_title_submit"
+msgstr "Enviar nuevo complemento"
+
+#. %s is the add-on name.
+#: views/developers/uploader.thtml:54
+msgid "devcp_uploader_title_update"
+msgstr "Actualizar %s"
+
+#. %s is a full <a> tag
+#: controllers/developers_controller.php:503
+#, php-format
+msgid "devcp_valid_app_reference"
+msgstr "Por favor, ve %s para una referencia."
+
+#. This is the text in the <a> tag for devcp_valid_app_reference. This should be
+#. fixed.
+#: controllers/developers_controller.php:503
+msgid "devcp_valid_app_reference_linktext"
+msgstr "esta página"
+
+#: controllers/developers_controller.php:581
+msgid "devcp_verify_author_error"
+msgstr "No se ha encontrado ninguna cuenta para esta dirección de correo."
+
+#: controllers/developers_controller.php:553
+msgid "devcp_verify_search_engine_error"
+msgstr ""
+"El archivo XML no es correcto o faltan campos obligatorios. Por favor <a "
+"href=\"https://developer.mozilla.org/en/"
+"Creating_OpenSearch_plugins_for_Firefox\">consulta la documentación</a>, "
+"verifica tu complemento, y vuelve a intentarlo."
+
+#: views/developers/versions.thtml:75
+msgid "devcp_versions_a_cancel"
+msgstr "Cancelar"
+
+#: views/developers/versions.thtml:79
+msgid "devcp_versions_a_delete"
+msgstr "Borrar versión"
+
+#: views/developers/versions.thtml:74
+msgid "devcp_versions_a_empty"
+msgstr "Borrar versión vacía"
+
+#: views/developers/versions.thtml:71
+msgid "devcp_versions_a_remove"
+msgstr "¿Borrar?"
+
+#: views/developers/versions.thtml:91
+msgid "devcp_versions_add"
+msgstr "Añadir nueva versión"
+
+#: views/developers/versions_delete.thtml:58
+msgid "devcp_versions_delete_a_cancel"
+msgstr "Cancelar"
+
+#: views/developers/versions_delete.thtml:56
+msgid "devcp_versions_delete_a_delete"
+msgstr "Borrar versión"
+
+#. Followed by a list of reviews and files that will be removed.
+#: views/developers/versions_delete.thtml:50
+msgid "devcp_versions_delete_also"
+msgstr "Esto también borrará:"
+
+#: views/developers/versions_delete.thtml:53
+msgid "devcp_versions_delete_files"
+msgid_plural "devcp_versions_delete_files"
+msgstr[0] "%s archivo"
+msgstr[1] "%s archivos"
+
+#. %s is the version number.
+#: views/developers/versions_delete.thtml:48
+msgid "devcp_versions_delete_header"
+msgstr "¿Borrar la versión %s?"
+
+#: views/developers/versions_delete.thtml:52
+msgid "devcp_versions_delete_reviews"
+msgid_plural "devcp_versions_delete_reviews"
+msgstr[0] "%s valoración"
+msgstr[1] "%s valoraciones"
+
+#. %s is the version number.
+#: views/developers/versions_delete.thtml:49
+msgid "devcp_versions_delete_sure"
+msgstr "¿Está seguro de que quiere eliminar permanentemente la versión %s?"
+
+#: views/developers/versions_edit.thtml:102
+#: views/developers/versions_edit.thtml:155
+msgid "devcp_versions_edit_a_cancel"
+msgstr "Cancelar"
+
+#: views/developers/versions_edit.thtml:101
+msgid "devcp_versions_edit_a_delete"
+msgstr "Borrar archivo"
+
+#: views/developers/versions_edit.thtml:165
+msgid "devcp_versions_edit_a_new_app"
+msgstr "Añadir nueva aplicación"
+
+#: views/developers/versions_edit.thtml:154
+msgid "devcp_versions_edit_a_remove_app"
+msgstr "Borrar aplicación"
+
+#: views/developers/versions_edit.thtml:114
+msgid "devcp_versions_edit_add"
+msgstr "Añadir nuevo archivo"
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/versions_edit.thtml:121
+msgid "devcp_versions_edit_adjust"
+msgstr ""
+"Al ajustar la información de las aplicaciones aquí, permitirá a los usuarios "
+"instalar tu complemento incluso si el install.rdf del paquete indica que el "
+"complemento es incompatible. <a %s>Lista de las aplicaciones soportadas</a>"
+
+#: views/developers/versions_edit.thtml:153
+msgid "devcp_versions_edit_compat_sure"
+msgstr ""
+"¿Está <b>seguro</b> de que quiere eliminar la compatibilidad con esta "
+"aplicación?"
+
+#: views/developers/versions_edit.thtml:100
+msgid "devcp_versions_edit_delete_sure"
+msgstr ""
+"¿Está <b>seguro</b> de que quiere eliminar permanentemente este archivo?"
+
+#: views/developers/versions_edit.thtml:203
+msgid "devcp_versions_edit_header_approval"
+msgstr "Información de aprobación"
+
+#: views/developers/versions_edit.thtml:120
+msgid "devcp_versions_edit_header_compat"
+msgstr "Aplicaciones compatibles"
+
+#: views/developers/versions_edit.thtml:74
+msgid "devcp_versions_edit_header_file"
+msgstr "Información del archivo"
+
+#: views/developers/versions_edit.thtml:189
+msgid "devcp_versions_edit_header_license"
+msgstr "Licencia"
+
+#. %s is the version number.
+#: views/developers/versions_edit.thtml:53
+msgid "devcp_versions_edit_header_manage"
+msgstr "Administrar versión %s"
+
+#: views/developers/versions_edit.thtml:212
+msgid "devcp_versions_edit_header_notes"
+msgstr "Notas de aprobación"
+
+#: views/developers/versions_edit.thtml:98
+msgid "devcp_versions_edit_img_delete"
+msgstr "Borrar archivo"
+
+#. %1$s is the file id, e.g. 18723.
+#. %2$s is the platform name, e.g. ALL or Windows.
+#. %3$s is the _('date) created.
+#. %4$s is the status, e.g. "In Sandbox" or "Public".
+#. %5$s is the _('date') status was changed.
+#: views/developers/versions_edit.thtml:208
+msgid "devcp_versions_edit_li_file"
+msgstr "Archivo %1$s (%2$s) creado el %3$s y cambiado a %4$s en %5$s"
+
+#: views/developers/versions_edit.thtml:190
+msgid "devcp_versions_edit_license_description"
+msgstr ""
+"Por favor, selecciona la licencia adecuada para tu complemento. Esta "
+"licencia espeficia los derechos que cedes del código fuente."
+
+#: views/developers/versions_edit.thtml:111
+msgid "devcp_versions_edit_no_files"
+msgstr "No se han encontrado archivos."
+
+#: views/developers/versions_edit.thtml:213
+msgid "devcp_versions_edit_optional"
+msgstr "Información opcional para el editor que va a revisar esta versión."
+
+#: views/developers/versions_edit.thtml:151
+msgid "devcp_versions_edit_remove_compat"
+msgstr "Borrar compatibilidad de aplicación"
+
+#: views/developers/versions_edit.thtml:167
+msgid "devcp_versions_edit_select_app"
+msgstr "Por favor, seleccione una aplicación"
+
+#: views/developers/versions_edit.thtml:78
+msgid "devcp_versions_edit_th_file"
+msgstr "Archivo"
+
+#: views/developers/versions_edit.thtml:79
+msgid "devcp_versions_edit_th_platform"
+msgstr "Plataforma"
+
+#: views/developers/versions_edit.thtml:80
+msgid "devcp_versions_edit_th_size"
+msgstr "Tamaño"
+
+#: views/developers/versions_edit.thtml:81
+msgid "devcp_versions_edit_th_status"
+msgstr "Estado"
+
+#: views/developers/versions_edit.thtml:183
+msgid "devcp_versions_edit_transbox_releasenotes_description"
+msgstr ""
+"Información sobre cambios en esta versión, nuevas características, bugs "
+"conocidos, y otra información útil específica de esta versión. Esta "
+"información estará también disponible para los usuarios al actualizar el "
+"complemento en el administrador de complementos de Firefox 3."
+
+#: views/developers/versions_edit.thtml:182
+msgid "devcp_versions_edit_transbox_releasenotes_name"
+msgstr "Notas de la versión"
+
+#: views/developers/versions_edit.thtml:164
+msgid "devcp_versions_edit_unsaved_compat"
+msgstr ""
+"<strong>Tienes cambios sin guardar.</strong> La compatibilidad no se "
+"guardará hasta que no use la opción inferior actualizar versión."
+
+#: views/developers/versions_edit.thtml:113
+msgid "devcp_versions_edit_unsaved_files"
+msgstr ""
+"<strong>Tienes cambios sin guardar.</strong> Los archivos no se borrarán "
+"hasta que no use la opción inferior actualizar versión."
+
+#: views/developers/versions_edit.thtml:218
+msgid "devcp_versions_edit_update"
+msgstr "Actualizar versión"
+
+#: views/developers/versions.thtml:49
+msgid "devcp_versions_header_manage"
+msgstr "Administrar versiones y archivos"
+
+#: views/developers/versions.thtml:87
+msgid "devcp_versions_no_versions"
+msgstr "No hay versiones"
+
+#. %s is a version number, base 10.
+#: views/developers/versions.thtml:46
+msgid "devcp_versions_notice_success"
+msgstr "Versión %s borrada correctamente."
+
+#: views/developers/versions.thtml:73
+msgid "devcp_versions_p_remove"
+msgstr ""
+"Esta versión no tiene archivos asociados y puede borrarse. ¿Quieres borrar "
+"esta versión?"
+
+#: views/developers/versions.thtml:58
+msgid "devcp_versions_th_created"
+msgstr "Creada"
+
+#: views/developers/versions.thtml:57
+msgid "devcp_versions_th_status"
+msgstr "Estado"
+
+#: views/developers/versions.thtml:56
+msgid "devcp_versions_th_version"
+msgstr "Versión"
+
+#: controllers/downloads_controller.php:91
+msgid "downloads_disable_warning"
+msgstr "Este complemento está deshabilitado"
+
+#: controllers/components/editors.php:57
+msgid "editor_review_error_addon_not_nominated"
+msgstr "Este complemento no ha sido propuesto."
+
+#: controllers/components/editors.php:213
+msgid "editor_review_error_file_not_pending"
+msgstr "Este archivo no tiene revisiones pendientes."
+
+#. Actions are, for example: approving or rejecting
+#: controllers/components/editors.php:79
+#: controllers/components/editors.php:182
+msgid "editor_review_error_no_action"
+msgstr "Por favor, selecciona una acción para la valoración."
+
+#: controllers/components/editors.php:192
+msgid "editor_review_error_no_applications"
+msgstr "Por favor, introduce las aplicaciones que has probado."
+
+#. Comments are required when an editor approves or rejects an add-on.
+#: controllers/components/editors.php:84
+#: controllers/components/editors.php:187
+msgid "editor_review_error_no_comments"
+msgstr "Por favor, introduce comentarios de valoración."
+
+#: controllers/components/editors.php:161
+msgid "editor_review_error_no_files"
+msgstr "Por favor, selecciona al menos un archivo para revisar."
+
+#: controllers/components/editors.php:197
+msgid "editor_review_error_no_operating_system"
+msgstr "Por favor, introduce los sistemas operativos que has probado."
+
+#: views/editors/logs.thtml:51
+msgid "editorcp_logs_button_filter"
+msgstr "Filtrar"
+
+#: views/editors/logs.thtml:44
+msgid "editorcp_logs_filter_by"
+msgstr "Filtrar por tipo/acción"
+
+#: views/editors/logs.thtml:42 controllers/editors_controller.php:964
+msgid "editorcp_logs_page_heading"
+msgstr "Registro de eventos"
+
+#: views/elements/developers/editorsmenu.thtml:60
+msgid "editorcp_menu_eventlog_link"
+msgstr "Registro de eventos"
+
+#: views/elements/developers/editorsmenu.thtml:62
+msgid "editorcp_menu_mainpage_link"
+msgstr "Volver a la página principal"
+
+#: views/elements/developers/editorsmenu.thtml:61
+msgid "editorcp_menu_reviewlog_link"
+msgstr "Registro de valoraciones"
+
+#: views/elements/developers/editorsmenu.thtml:55
+msgid "editorcp_menu_summary_link"
+msgstr "Resumen del editor"
+
+#: views/elements/developers/editorsmenu.thtml:52
+msgid "editorcp_menu_title"
+msgstr "Herramientas de editor"
+
+#: views/editors/reviewlog.thtml:49
+msgid "editorcp_reviewlog_button_filter"
+msgstr "Filtrar"
+
+#: views/editors/reviewlog.thtml:58
+msgid "editorcp_reviewlog_column_action"
+msgstr "Acción"
+
+#: views/editors/reviewlog.thtml:56
+msgid "editorcp_reviewlog_column_addon"
+msgstr "Complemento"
+
+#: views/editors/reviewlog.thtml:55
+msgid "editorcp_reviewlog_column_date"
+msgstr "Fecha"
+
+#: views/editors/reviewlog.thtml:57
+msgid "editorcp_reviewlog_column_editor"
+msgstr "Editor"
+
+#: views/editors/reviewlog.thtml:94
+msgid "editorcp_reviewlog_comments_hide"
+msgstr "Ocultar comentarios"
+
+#: views/editors/reviewlog.thtml:93
+msgid "editorcp_reviewlog_comments_show"
+msgstr "Mostrar comentarios"
+
+#. %1$s and %2$s are full <input> tags for dates
+#: views/editors/reviewlog.thtml:45
+#, php-format
+msgid "editorcp_reviewlog_entries_between"
+msgstr "Ver registros entre %s y %s"
+
+#: views/editors/reviewlog.thtml:104
+msgid "editorcp_reviewlog_none_found"
+msgstr "No se encontraron valoraciones para ese periodo."
+
+#: views/editors/reviewlog.thtml:42
+msgid "editorcp_reviewlog_page_heading"
+msgstr "Registro de valoraciones"
+
+#: views/editors/summary.thtml:61
+msgid "editorcp_summary_monthreviews_heading"
+msgstr "Valoraciones mensuales"
+
+#: views/editors/summary.thtml:77
+msgid "editorcp_summary_neweditors_heading"
+msgstr "Nuevos editores"
+
+#: views/editors/summary.thtml:42
+msgid "editorcp_summary_page_heading"
+msgstr "Resumen del editor"
+
+#: views/editors/summary.thtml:94
+msgid "editorcp_summary_recentactivity_heading"
+msgstr "Actividad reciente del editor"
+
+#: views/editors/summary.thtml:45
+msgid "editorcp_summary_totalreviews_heading"
+msgstr "Valoraciones totales"
+
+#: controllers/editors_controller.php:248
+#: controllers/editors_controller.php:249
+msgid "editors_addon_review_pagetitle"
+msgstr "Valorar complemento"
+
+#: controllers/editors_controller.php:349
+msgid "editors_error_js-formerror"
+msgstr "Por favor, completa los siguientes campos:"
+
+#: controllers/editors_controller.php:350
+msgid "editors_error_review_one_file"
+msgstr "Por favor, seleccione al menos un archivo para revisar."
+
+#: controllers/editors_controller.php:274
+msgid "editors_error_self_reviews_forbidden"
+msgstr "Las valoraciones a ti mismo no están permitidas."
+
+#: controllers/editors_controller.php:699
+msgid "editors_external_software"
+msgstr "Programas externos"
+
+#: views/editors/featured.thtml:120 views/editors/featured.thtml:121
+msgid "editors_featured_add_feature"
+msgstr "Añadir una característica"
+
+#: views/editors/featured.thtml:126
+msgid "editors_featured_add_feature_submit"
+msgstr "Añadir"
+
+#: views/editors/featured.thtml:49 controllers/editors_controller.php:832
+#: controllers/editors_controller.php:848
+msgid "editors_featured_addon_add_failure"
+msgstr "No se ha podido añadir una característica"
+
+#: controllers/editors_controller.php:851
+msgid "editors_featured_addon_add_success"
+msgstr "Se añadió una característica con éxito."
+
+#: views/editors/featured.thtml:50 controllers/editors_controller.php:839
+#: controllers/editors_controller.php:868
+#: controllers/editors_controller.php:886
+msgid "editors_featured_addon_edit_failure"
+msgstr "Fallo al editar una característica."
+
+#: views/editors/featured.thtml:51 controllers/editors_controller.php:888
+msgid "editors_featured_addon_edit_success"
+msgstr "Se editó una característica con éxito."
+
+#: views/editors/featured.thtml:53 controllers/editors_controller.php:861
+msgid "editors_featured_addon_invalid_locale"
+msgstr "No son válidos uno o más idiomas."
+
+#: views/editors/featured.thtml:52 controllers/editors_controller.php:906
+msgid "editors_featured_addon_remove_failure"
+msgstr "Fallo al eliminar una característica."
+
+#: controllers/editors_controller.php:901
+msgid "editors_featured_addon_remove_success"
+msgstr "Se eliminó una característica con éxito."
+
+#: controllers/editors_controller.php:915
+#: controllers/editors_controller.php:917
+msgid "editors_featured_addons_pagetitle"
+msgstr "Complementos destacados"
+
+#: views/editors/featured.thtml:54 views/editors/featured.thtml:107
+msgid "editors_featured_edit_feature_submit"
+msgstr "Ir"
+
+#: views/editors/featured.thtml:90 views/editors/featured.thtml:91
+msgid "editors_featured_remove_feature"
+msgstr "Borrar característica"
+
+#: views/editors/queue.thtml:46
+msgid "editors_filter_queue"
+msgstr "Filtrar cola"
+
+#: views/editors/queue.thtml:182
+msgid "editors_helpful_links"
+msgstr "Enlaces útiles"
+
+#: views/editors/queue.thtml:182
+msgid "editors_link_guide"
+msgstr "Guía de editores"
+
+#: views/editors/queue.thtml:182
+msgid "editors_link_policy"
+msgstr "Política del complemento"
+
+#: views/editors/queue.thtml:47
+msgid "editors_notice_filter_session"
+msgstr "Estos filtros permanecerán para esta sesión o hasta que se cancelen."
+
+#. %1 is the queue mode
+#: views/editors/queue.thtml:177 views/admin/flagged_queue.thtml:89
+msgid "editors_notice_none_found"
+msgstr "Actualmente no hay complementos para valorar."
+
+#: controllers/editors_controller.php:1040
+msgid "editors_one_day"
+msgstr "1 día"
+
+#: controllers/editors_controller.php:1048
+msgid "editors_one_hour"
+msgstr "1 hora"
+
+#: controllers/editors_controller.php:1056
+msgid "editors_one_minute"
+msgstr "1 minuto"
+
+#: controllers/editors_controller.php:64 controllers/editors_controller.php:73
+#: controllers/editors_controller.php:77
+msgid "editors_pagetitle"
+msgstr "Herramientas del editor"
+
+#. %s is a comma separated list of platforms. Example: Windows, OS X
+#: controllers/editors_controller.php:680
+#: controllers/editors_controller.php:683
+#, php-format
+msgid "editors_platform_x_only"
+msgstr "Solo %s"
+
+#: controllers/editors_controller.php:695
+msgid "editors_pre-release"
+msgstr "Versión previa"
+
+#. %1 is the app name
+#: views/editors/queue.thtml:131
+#, php-format
+msgid "editors_queue_app_compatibility"
+msgstr "Compatibilidad de %s"
+
+#: views/editors/queue.thtml:51
+#, fuzzy
+msgid "editors_queue_filter_label_addon"
+msgstr "Add-on or Author Email"
+
+#: views/editors/queue.thtml:72
+#, fuzzy
+msgid "editors_queue_filter_label_addontypes"
+msgstr "Add-on Types"
+
+#: views/editors/queue.thtml:56
+#, fuzzy
+msgid "editors_queue_filter_label_application"
+msgstr "Application"
+
+#: views/editors/queue.thtml:61
+#, fuzzy
+msgid "editors_queue_filter_label_maxversion"
+msgstr "Max. Version"
+
+#: views/editors/queue.thtml:78
+#, fuzzy
+msgid "editors_queue_filter_label_platforms"
+msgstr "Platforms"
+
+#: views/editors/queue.thtml:66
+#, fuzzy
+msgid "editors_queue_filter_label_submissionage"
+msgstr "Age of Submission (days)"
+
+#. %1$s is a number
+#: views/editors/queue.thtml:90
+#, fuzzy
+msgid "editors_queue_filter_result_count"
+msgid_plural "editors_queue_filter_result_count"
+msgstr[0] "Results of your filtered search: <strong>%1$s</strong> Add-on"
+msgstr[1] "Results of your filtered search: <strong>%1$s</strong> Add-ons"
+
+#: views/editors/queue.thtml:84
+msgid "editors_queue_submit_clean"
+msgstr "Limpiar"
+
+#: views/editors/queue.thtml:83
+msgid "editors_queue_submit_filter"
+msgstr "Filtro"
+
+#: controllers/editors_controller.php:133
+msgid "editors_queues_disabled"
+msgstr ""
+"Todas las colas de valoración están desactivadas actualmente. Por favor, "
+"vuelve a intentarlo en otro momento."
+
+#: views/editors/review.thtml:149
+msgid "editors_review_a_edit_item"
+msgstr "Editar elemento"
+
+#: views/editors/review.thtml:146
+msgid "editors_review_a_item_history"
+msgstr "Historial del elemento"
+
+#: views/editors/review.thtml:148
+msgid "editors_review_a_item_homepage"
+msgstr "Página web del elemento"
+
+#: views/editors/review.thtml:145
+msgid "editors_review_a_item_overview"
+msgstr "Acerca del elemento"
+
+#: views/editors/review.thtml:147
+msgid "editors_review_a_previews"
+msgstr "Vistas previas"
+
+#: controllers/editors_controller.php:345
+msgid "editors_review_action"
+msgstr "Valoración a realizar"
+
+#: views/editors/review.thtml:159
+msgid "editors_review_action_info"
+msgstr "Solicitar más información"
+
+#: views/editors/review.thtml:157
+msgid "editors_review_action_public"
+msgstr "Mover a la zona pública"
+
+#: views/editors/review.thtml:160
+msgid "editors_review_action_request_superreview"
+msgstr "Solicitar una valoración mayor (Super-Review)"
+
+#: views/editors/review.thtml:158
+msgid "editors_review_action_sandbox"
+msgstr "Mantener en el área de pruebas"
+
+#: controllers/editors_controller.php:346
+msgid "editors_review_comments"
+msgstr "Revisar los comentarios"
+
+#: views/editors/review.thtml:182
+msgid "editors_review_details_info_request"
+msgstr ""
+"Usa este formulario para solicitar más información del autor. Recibirán un "
+"correo electrónico y podrán responder aquí. Serás informado cuando se envíe "
+"una respuesta."
+
+#: views/editors/review.thtml:174
+msgid "editors_review_details_nominated_public"
+msgstr ""
+"Esto marcará el complemento y sus versiones más recientes como públicas. Las "
+"versiones posteriores irán al área de pruebas hasta que hayan sido valoradas "
+"por un editor."
+
+#: views/editors/review.thtml:177
+msgid "editors_review_details_nominated_sandbox"
+msgstr "Esto retendrá el complemento en el área de pruebas."
+
+#: views/editors/review.thtml:166
+msgid "editors_review_details_pending_public"
+msgstr ""
+"Esto aprobará la versión en el área de pruebas de un complemento público "
+"para que aparezca en el sitio público."
+
+#: views/editors/review.thtml:169
+msgid "editors_review_details_pending_sandbox"
+msgstr ""
+"Esto hará que la versión del área de pruebas de un complemento público "
+"permanezca en el área de pruebas."
+
+#: views/editors/review.thtml:185
+msgid "editors_review_details_superreview"
+msgstr ""
+"Si te preocupa la seguridad de este complemento, su licencia, u otras "
+"preocupaciones que un administrador deba valorar, introduce tus comentarios "
+"en el campo abajo. Serán enviados a los administradores, no al autor."
+
+#: views/editors/review.thtml:134
+msgid "editors_review_file_diff_link"
+msgstr "Comparar con la versión pública"
+
+#: views/editors/review.thtml:131
+msgid "editors_review_file_viewcontents_link"
+msgstr "Ver los contenidos"
+
+#: views/editors/review.thtml:65
+msgid "editors_review_header_authors"
+msgstr "Autores:"
+
+#: views/editors/review.thtml:79
+msgid "editors_review_header_categories"
+msgstr "Categorías:"
+
+#: views/editors/review.thtml:92
+msgid "editors_review_header_compatibility"
+msgstr "Compatibilidad:"
+
+#: views/editors/review.thtml:251
+msgid "editors_review_header_description"
+msgstr "Descripción"
+
+#: views/editors/review.thtml:275
+msgid "editors_review_header_devcomments"
+msgstr "Comentarios del desarrollador"
+
+#: views/editors/review.thtml:263
+msgid "editors_review_header_eula"
+msgstr "CLUF"
+
+#: views/editors/review.thtml:115
+msgid "editors_review_header_files"
+msgstr "Archivos:"
+
+#: views/editors/review.thtml:284
+msgid "editors_review_header_itemhistory"
+msgstr "Historial del elemento"
+
+#: views/editors/review.thtml:232
+msgid "editors_review_header_nominationmessage"
+msgstr "Mensaje de nominación"
+
+#: views/editors/review.thtml:311
+msgid "editors_review_header_previews"
+msgstr "Vistas previas"
+
+#: views/editors/review.thtml:269
+msgid "editors_review_header_privacy"
+msgstr "Política de privacidad"
+
+#. %1 is the add-on name and version
+#: views/editors/review.thtml:56
+#, php-format
+msgid "editors_review_header_review"
+msgstr "Valoraciones de %s"
+
+#: views/editors/review.thtml:239
+msgid "editors_review_header_reviewernotes"
+msgstr "Notas para el revisor"
+
+#: views/editors/review.thtml:245
+msgid "editors_review_header_summary"
+msgstr "Descripción"
+
+#: views/editors/review.thtml:257
+msgid "editors_review_header_versionnotes"
+msgstr "Notas de la versión"
+
+#. a noun: shown in an add-on's editor review history
+#: views/elements/developers/editors_review_history_item.thtml:80
+msgid "editors_review_history_info_reply"
+msgstr "Respuesta"
+
+#: views/elements/developers/editors_review_history_item.thtml:78
+msgid "editors_review_history_info_request"
+msgstr "Solicitud de información"
+
+#: views/elements/developers/editors_review_history_item.thtml:62
+#: views/editors/reviewlog.thtml:77
+msgid "editors_review_history_nominated_adminreview"
+msgstr "Valoraciones del administrador"
+
+#: views/elements/developers/editors_review_history_item.thtml:56
+#: views/editors/reviewlog.thtml:71
+msgid "editors_review_history_nominated_approved"
+msgstr "Propuesta Aprobada/Páblica"
+
+#: views/elements/developers/editors_review_history_item.thtml:59
+#: views/editors/reviewlog.thtml:74
+msgid "editors_review_history_nominated_denied"
+msgstr "Propuesta denegada/Ãrea de pruebas"
+
+#: views/editors/review.thtml:303
+msgid "editors_review_history_nonefound"
+msgstr "No se han podido encontrar valoraciones anteriores."
+
+#: views/elements/developers/editors_review_history_item.thtml:73
+#: views/editors/reviewlog.thtml:88
+msgid "editors_review_history_pending_adminreview"
+msgstr "Valoración del administrador"
+
+#: views/elements/developers/editors_review_history_item.thtml:67
+#: views/editors/reviewlog.thtml:82
+msgid "editors_review_history_pending_approved"
+msgstr "Aprobada/Pública"
+
+#: views/elements/developers/editors_review_history_item.thtml:70
+#: views/editors/reviewlog.thtml:85
+msgid "editors_review_history_pending_denied"
+msgstr "Denegada/Ãrea de pruebas"
+
+#. link text in an add-on's editor review history, allowing to hide and show an information request's replies
+#. %1 is the number of replies
+#: views/elements/developers/editors_review_history_item.thtml:90
+msgid "editors_review_history_show_hide_replies"
+msgid_plural "editors_review_history_show_hide_replies"
+msgstr[0] "Mostrar/Ocultar respuesta (%1$s)"
+msgstr[1] "Mostrar/Ocultar respuestas (%1$s)"
+
+#: views/editors/review.thtml:208
+msgid "editors_review_label_applications"
+msgstr "Aplicaciones:"
+
+#: views/editors/review.thtml:196
+msgid "editors_review_label_cannedresponse"
+msgstr "o selecciona una respuesta predeterminada:"
+
+#: views/editors/review.thtml:190
+msgid "editors_review_label_comments"
+msgstr "Comentarios:"
+
+#: views/editors/review.thtml:204
+msgid "editors_review_label_operating_systems"
+msgstr "Sistemas operativos:"
+
+#: views/editors/review.thtml:285 views/editors/review.thtml:312
+msgid "editors_review_link_pagetop"
+msgstr "Ir al inicio"
+
+#: views/editors/review.thtml:141
+msgid "editors_review_mulitple_notice"
+msgstr ""
+"Atención: Revisa más de un archivo sólo si has comprobado cada uno de los "
+"archivos que ha seleccionado."
+
+#: views/editors/review.thtml:51
+msgid "editors_review_next_link"
+msgstr "siguiente &raquo;"
+
+#: views/editors/review.thtml:322
+msgid "editors_review_previews_notfound"
+msgstr "No se encontraron vistas previas."
+
+#: views/editors/review.thtml:50
+msgid "editors_review_previous_link"
+msgstr "&laquo; anterior"
+
+#: controllers/editors_controller.php:144
+#: controllers/editors_controller.php:146
+msgid "editors_review_queue_pagetitle"
+msgstr "Cola de valoración"
+
+#. %1 is the add-ons rank in the queue, %2 is the total queue length
+#: views/editors/review.thtml:47
+msgid "editors_review_rank_in_queue"
+msgstr "<strong># %1$s</strong> de %2$s en cola"
+
+#. %1 is the add-ons rank in the queue, %2 is the total queue length. Both numbers
+#: views/editors/review.thtml:45
+#, fuzzy
+msgid "editors_review_rank_in_queue_filtered"
+msgstr "<strong># %1$s</strong> of %2$s in queue (filtered)"
+
+#: views/editors/review.thtml:223
+msgid "editors_review_submit_process_action"
+msgstr "Procesar acción"
+
+#: views/editors/review.thtml:293
+msgid "editors_review_th_action"
+msgstr "Acción"
+
+#: views/editors/review.thtml:294
+msgid "editors_review_th_comments"
+msgstr "Comentarios"
+
+#: views/editors/review.thtml:291
+msgid "editors_review_th_date"
+msgstr "Fecha"
+
+#: views/editors/review.thtml:292
+msgid "editors_review_th_reviewer"
+msgstr "Revisor"
+
+#: views/editors/review.thtml:290
+msgid "editors_review_th_version_file"
+msgstr "Versión/Archivo"
+
+#: views/editors/review.thtml:217
+msgid "editors_review_update_notify_once"
+msgstr ""
+"Informarme la próxima vez que este complemento se actualice. (Las "
+"actualizaciones sucesivas no generarán aviso por correo)"
+
+#: controllers/editors_controller.php:298
+msgid "editors_reviewed_successfully"
+msgstr "Valoración procesada con éxito."
+
+#: views/editors/reviews_queue.thtml:106
+msgid "editors_reviews_action_delete_review"
+msgstr "Borrar valoración"
+
+#: views/editors/reviews_queue.thtml:104
+msgid "editors_reviews_action_keep"
+msgstr "Borrar marcas; mantener valoración"
+
+#: views/editors/reviews_queue.thtml:102
+msgid "editors_reviews_action_skip"
+msgstr "Saltar"
+
+#: views/editors/reviews_queue.thtml:100
+msgid "editors_reviews_header_action"
+msgstr "Acción"
+
+#: views/editors/reviews_queue.thtml:67
+msgid "editors_reviews_in_reply_to"
+msgstr "En respuesta a:"
+
+#: controllers/editors_controller.php:748
+msgid "editors_reviews_processed"
+msgstr "¡Valoraciones procesadas con éxito!"
+
+#: views/editors/reviews_queue.thtml:117
+msgid "editors_reviews_queue_empty"
+msgstr "Actualmente no hay valoraciones que moderar."
+
+#: views/editors/reviews_queue.thtml:111
+msgid "editors_reviews_submit_process_reviews"
+msgstr "Procesar valoraciones"
+
+#: controllers/editors_controller.php:691
+msgid "editors_site_specific"
+msgstr "Específico del sitio"
+
+#: controllers/editors_controller.php:348
+msgid "editors_tested_app"
+msgstr "Aplicación probada"
+
+#: controllers/editors_controller.php:347
+msgid "editors_tested_os"
+msgstr "Sistemas operativos probados"
+
+#: views/editors/queue.thtml:151
+msgid "editors_th_additional_info"
+msgstr "Información adicional"
+
+#: views/editors/featured.thtml:63 views/editors/queue.thtml:109
+#: views/admin/flagged_queue.thtml:53
+msgid "editors_th_addon"
+msgstr "Complemento"
+
+#: views/editors/queue.thtml:125
+msgid "editors_th_addontype"
+msgstr "Tipo"
+
+#: views/editors/featured.thtml:64
+msgid "editors_th_locales"
+msgstr "¿Restringir idiomas?"
+
+#: views/editors/queue.thtml:148
+msgid "editors_th_nomination_age"
+msgstr "Tiempo en la cola"
+
+#: views/editors/queue.thtml:101 views/editors/queue.thtml:117
+#: views/editors/queue.thtml:144
+#, fuzzy
+msgid "editors_th_sort_ascending"
+msgstr "Ascending sort"
+
+#: views/editors/queue.thtml:105 views/editors/queue.thtml:121
+#: views/editors/queue.thtml:140
+#, fuzzy
+msgid "editors_th_sort_descending"
+msgstr "Descending sort"
+
+#. %s is a number
+#: controllers/editors_controller.php:1036
+#, php-format
+msgid "editors_x_days"
+msgstr "%s días"
+
+#. %s is a number
+#: controllers/editors_controller.php:1044
+#, php-format
+msgid "editors_x_hours"
+msgstr "%s horas"
+
+#. %s is a number
+#: controllers/editors_controller.php:1052
+#, php-format
+msgid "editors_x_minutes"
+msgstr "%s minutos"
+
+#: views/errors/error401.thtml:50 controllers/components/simple_acl.php:81
+#: controllers/components/simple_acl.php:82
+#: controllers/components/simple_acl.php:83 controllers/components/amo.php:607
+#: controllers/components/amo.php:608 controllers/components/amo.php:609
+#: controllers/reviews_controller.php:353
+#: controllers/reviews_controller.php:485
+#: controllers/collections_controller.php:438
+#: controllers/collections_controller.php:496
+#: controllers/collections_controller.php:504
+#: controllers/collections_controller.php:971
+#: controllers/collections_controller.php:1034
+#: controllers/collections_controller.php:1077
+msgid "error_access_denied"
+msgstr "Acceso denegado"
+
+#: views/errors/error401.thtml:52
+msgid "error_access_denied_message"
+msgstr "No estás autorizado para ver esta página."
+
+#: controllers/collections_controller.php:1039
+#, fuzzy
+msgid "error_addon_exists"
+msgstr "Add-on already exists!"
+
+#: controllers/developers_controller.php:200
+#: controllers/developers_controller.php:593
+#: controllers/developers_controller.php:1016
+#: controllers/developers_controller.php:1429
+#: controllers/downloads_controller.php:95
+#: controllers/downloads_controller.php:102
+#: controllers/downloads_controller.php:164
+#: controllers/statistics_controller.php:135
+#: controllers/previews_controller.php:115
+#: controllers/previews_controller.php:206
+#: controllers/previews_controller.php:307
+#: controllers/reviews_controller.php:77
+#: controllers/reviews_controller.php:240
+#: controllers/reviews_controller.php:332
+#: controllers/reviews_controller.php:340 controllers/api_controller.php:123
+#: controllers/api_controller.php:759 controllers/addons_controller.php:131
+#: controllers/addons_controller.php:197
+#: controllers/addons_controller.php:1407
+#: controllers/addons_controller.php:1465
+#: controllers/addons_controller.php:1469
+#: controllers/addons_controller.php:1503
+#: controllers/editors_controller.php:265
+#: controllers/collections_controller.php:1041
+#: controllers/collections_controller.php:1074
+msgid "error_addon_notfound"
+msgstr "¡Complemento no encontrado!"
+
+#: controllers/files_controller.php:83 controllers/files_controller.php:196
+msgid "error_addon_notviewable"
+msgstr "Este complemento no está visible aquí."
+
+#: controllers/reviews_controller.php:246
+msgid "error_addon_selfreview"
+msgstr "No puedes valorar tu propio complemento."
+
+#: controllers/addons_controller.php:970
+msgid "error_browse_no_addons"
+msgstr "¡No hay complementos en la categoría!"
+
+#: controllers/api_controller.php:424
+msgid "error_collection_feed_notfound"
+msgstr "Hilo del complemento no encontrado."
+
+#: views/users/register.thtml:65 views/users/edit.thtml:194
+msgid "error_email_invalid"
+msgstr "Esta dirección de correo electrónico no es válida."
+
+#: views/users/pwreset.thtml:74 views/users/register.thtml:70
+#: views/users/register.thtml:80 views/users/register.thtml:86
+#: views/users/edit.thtml:105 views/users/edit.thtml:111
+#: views/users/edit.thtml:192 views/admin/users_edit.thtml:78
+#: views/admin/users_edit.thtml:83 views/reviews/add.thtml:80
+#: views/reviews/add.thtml:104
+msgid "error_field_required"
+msgstr "Este campo no debe estar vacío."
+
+#: controllers/files_controller.php:75 controllers/files_controller.php:93
+#: controllers/files_controller.php:96 controllers/files_controller.php:163
+#: controllers/files_controller.php:176 controllers/files_controller.php:185
+#: controllers/files_controller.php:204 controllers/editors_controller.php:412
+msgid "error_file_notfound"
+msgstr "¡Archivo no encontrado!"
+
+#. %s is a filename
+#: controllers/editors_controller.php:430
+#, php-format
+msgid "error_file_x_notfound"
+msgstr "Error en el archivo: %s no existe."
+
+#: views/collections/add.thtml:55 views/collections/edit.thtml:89
+#: views/users/register.thtml:54 views/users/edit.thtml:81
+#: views/reviews/add.thtml:70 controllers/groups_controller.php:80
+#: controllers/groups_controller.php:102
+msgid "error_formerrors"
+msgstr ""
+"Hay errores en este formulario. Por favor, corríjalos y vuelva a enviarlo."
+
+#: views/users/register.thtml:109
+msgid "error_invalid_captcha"
+msgstr "Código no válido, por favor, inténtalo de nuevo"
+
+#: views/users/register.thtml:100 views/users/edit.thtml:125
+#: views/admin/users_edit.thtml:101
+msgid "error_invalid_url"
+msgstr ""
+"Esta URL tiene un formato no válido. Las URLs válidas tienen un aspecto como "
+"este http://example.com/my_page."
+
+#. %s is a string representing what's missing. Example: file_id
+#: controllers/downloads_controller.php:65
+#: controllers/users_controller.php:185 controllers/users_controller.php:264
+#: controllers/users_controller.php:559 controllers/users_controller.php:653
+#: controllers/reviews_controller.php:71
+#: controllers/reviews_controller.php:234
+#: controllers/reviews_controller.php:325
+#: controllers/reviews_controller.php:473
+#: controllers/reviews_controller.php:475
+#: controllers/addons_controller.php:182
+#: controllers/addons_controller.php:1381
+#: controllers/addons_controller.php:1455
+#: controllers/collections_controller.php:266
+#: controllers/collections_controller.php:285
+#: controllers/collections_controller.php:346
+#: controllers/collections_controller.php:443
+#: controllers/collections_controller.php:482
+#: controllers/collections_controller.php:936
+#: controllers/collections_controller.php:959
+#: controllers/collections_controller.php:960
+#: controllers/collections_controller.php:975
+#: controllers/collections_controller.php:977
+#: controllers/collections_controller.php:994
+#: controllers/collections_controller.php:1003
+#: controllers/collections_controller.php:1016
+#: controllers/collections_controller.php:1017
+#: controllers/collections_controller.php:1024
+#: controllers/collections_controller.php:1070
+#: controllers/collections_controller.php:1090
+#, php-format
+msgid "error_missing_argument"
+msgstr "Falta un argumento: %s"
+
+#: controllers/components/amo.php:507 controllers/components/amo.php:532
+msgid "error_no_files_in_addon"
+msgstr "Sin archivos"
+
+#: controllers/previews_controller.php:200
+msgid "error_preview_notfound"
+msgstr "¡Previsualización no encontrada!"
+
+#: views/addons/display.thtml:400 views/reviews/add.thtml:98
+msgid "error_review_rating_required"
+msgstr "Debes elegir una puntuación."
+
+#: controllers/users_controller.php:160
+msgid "error_user_already_confirmed"
+msgstr "Esta cuenta de usuario ya ha sido confirmada."
+
+#: controllers/users_controller.php:202 controllers/users_controller.php:276
+#: controllers/users_controller.php:569 controllers/users_controller.php:581
+#: controllers/users_controller.php:587 controllers/users_controller.php:610
+#: controllers/users_controller.php:627
+msgid "error_user_badconfirmationcode"
+msgstr "¡Código de confirmación no válido!"
+
+#: views/users/pwreset.thtml:79 views/users/register.thtml:75
+#: views/users/edit.thtml:183
+msgid "error_user_confirmpw_nomatch"
+msgstr "Las contraseñas no coinciden."
+
+#: views/users/register.thtml:65 views/users/edit.thtml:190
+#: controllers/users_controller.php:617
+msgid "error_user_email_notunique"
+msgstr "Esta dirección de correo electrónico ya está en uso."
+
+#: controllers/users_controller.php:596
+msgid "error_user_emailchange_expired"
+msgstr ""
+"El cambio de correo electrónico ha expirado. Por favor, cambiar tu dirección "
+"de correo electrónico de nuevo en tu perfil de usuario y haz clic en el "
+"enlace del correo de confirmación tan pronto como lo recibas."
+
+#: controllers/collections_controller.php:985
+#, fuzzy
+msgid "error_user_exists"
+msgstr ""
+"Users can only have one role at a time. Please remove the user from any "
+"existing roles before continuing."
+
+#: views/users/register.thtml:91 views/users/edit.thtml:116
+#: views/admin/users_edit.thtml:88
+msgid "error_user_nickname_notunique"
+msgstr "Este apodo ya está en uso."
+
+#: views/users/pwreset.thtml:54 controllers/users_controller.php:191
+#: controllers/users_controller.php:270 controllers/users_controller.php:603
+#: controllers/users_controller.php:659
+#: controllers/collections_controller.php:988
+#: controllers/collections_controller.php:998
+msgid "error_user_notfound"
+msgstr "¡Usuario no encontrado!"
+
+#: views/users/activatefirst.thtml:47
+msgid "error_user_unconfirmed"
+msgstr "Por favor, confirme su cuenta de usuario primero."
+
+#: views/users/login.thtml:67
+msgid "error_username_or_pw_wrong"
+msgstr "¡Nombre de usuario o contraseña incorrectos!"
+
+#: controllers/editors_controller.php:260
+msgid "error_version_notfound"
+msgstr "¡Versión no encontrada!"
+
+#: views/users/delete.thtml:125 views/users/edit.thtml:173
+msgid "error_wrong_password"
+msgstr "¡Se ha introducido una contraseña errónea!"
+
+#: views/elements/amo2009/homepage_addon.thtml:122
+#: views/elements/feature.thtml:122
+msgid "feature_learnmore"
+msgstr "Conoce más"
+
+#. %1 is the add-on name
+#: views/elements/amo2009/homepage_addon.thtml:123
+#: views/elements/feature.thtml:123
+#, php-format
+msgid "feature_learnmore_about_addon"
+msgstr "Conoce más acerca de %1$s"
+
+#. %1$s is a number
+#: views/elements/amo2009/reviews.thtml:52
+#: views/elements/addon_listitem.thtml:112 views/elements/feature.thtml:99
+#: views/addons/browse_thumbs.thtml:86
+#, php-format
+msgid "feature_reviews"
+msgid_plural "feature_reviews"
+msgstr[0] "%1$s valoración"
+msgstr[1] "%1$s valoraciones"
+
+#: views/elements/amo2009/homepage_addon.thtml:127
+#: views/elements/feature.thtml:127
+msgid "feature_view_more_from_category"
+msgstr "Ver más de"
+
+#. This appears on a page that views the source of an add-on. This link will return
+#. the user to the add-on's main page
+#: views/files/browse.thtml:65
+msgid "file_browser_link_addon"
+msgstr "Volver al complemento"
+
+#. There is a list of directories and files on the page. Clicking this will show the
+#. contents of all the directories (normally you would click on each one to see the
+#. contents)
+#: views/files/browse.thtml:67
+msgid "file_browser_link_expand_all"
+msgstr "Expandir todas"
+
+#. This appears on a page that views the source of an add-on. This link will return
+#. the user to the add-on's review page (it only appears if the add-on is being
+#. reviewed)
+#: views/files/browse.thtml:64
+msgid "file_browser_link_review"
+msgstr "Volver a la valoración"
+
+#. The title of the page for viewing an add-on's source.
+#. %1$s is the name of the add-on
+#. %2$s is the name of the current application (e.g. Firefox or Thunderbird)
+#: views/files/browse.thtml:46
+msgid "file_browser_title"
+msgstr "%1$s :: Navegador de archivos :: Complementos de %2$s"
+
+#. This appears on a page that views the source of an add-on. There is a list of
+#. directories and files on the page. Clicking this link will toggle between an
+#. expanded or a collapsed list. This string should be kept short.
+#: views/files/browse.thtml:68
+msgid "file_browser_toggle_expand_collapse"
+msgstr "+/-"
+
+#. Link text for the AMO About page.
+#: views/elements/footer.thtml:72 views/layouts/amo2009.thtml:341
+msgid "footer_a_about"
+msgstr "Acerca"
+
+#. Link text to the AMO blog.
+#: views/elements/footer.thtml:74 views/layouts/amo2009.thtml:343
+msgid "footer_a_blog"
+msgstr "Blog"
+
+#. Link text to the Frequently Asked Questions page.
+#: views/elements/footer.thtml:73 views/layouts/amo2009.thtml:342
+msgid "footer_a_faq"
+msgstr "PUF"
+
+#. Full text for the FAQ abbreviation.
+#: views/elements/footer.thtml:73 views/pages/collector_features.thtml:72
+#: views/layouts/amo2009.thtml:342
+msgid "footer_abbr_faq"
+msgstr "Preguntas de usuario frecuentes"
+
+#: views/elements/footer.thtml:67 views/layouts/amo2009.thtml:336
+msgid "footer_all_rights_reserved"
+msgstr "Todos los derechos reservados."
+
+#: views/elements/footer.thtml:67 views/layouts/amo2009.thtml:336
+msgid "footer_copyright"
+msgstr "Copyright"
+
+#: views/elements/footer.thtml:71 views/layouts/amo2009.thtml:340
+msgid "footer_credits"
+msgstr "Créditos"
+
+#: views/elements/footer.thtml:76 views/layouts/amo2009.thtml:346
+msgid "footer_disclaimer"
+msgstr ""
+"Mozilla proporciona enlaces a estas aplicaciones como muestra de cortesía, y "
+"no representa a éstas ni a ninguna información relacionada con ellas. "
+"Cualquier pregunta, queja o reclamación relativa a las aplicaciones debe "
+"dirigirse a los respectivos propietarios del software."
+
+#: views/elements/footer.thtml:61 views/layouts/amo2009.thtml:332
+msgid "footer_lang_form_lang_submit_go"
+msgstr "Ir"
+
+#: views/elements/footer.thtml:70 views/layouts/amo2009.thtml:339
+msgid "footer_legal_notices"
+msgstr "Avisos legales"
+
+#: views/elements/footer.thtml:50 views/layouts/amo2009.thtml:321
+msgid "footer_other_languages"
+msgstr "Otros idiomas:"
+
+#: views/elements/footer.thtml:69 views/layouts/amo2009.thtml:338
+msgid "footer_privacy_policy"
+msgstr "Política de privacidad"
+
+#: models/addontype.php:79
+msgid "general_addontype_dict"
+msgstr "Diccionario"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:100
+msgid "general_addontype_dict_plural"
+msgstr "Diccionarios"
+
+#: models/addontype.php:75
+msgid "general_addontype_extension"
+msgstr "Extensión"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:98
+msgid "general_addontype_extension_plural"
+msgstr "extensiones"
+
+#: models/addontype.php:85
+msgid "general_addontype_lpaddon"
+msgstr "Paquete de idioma (Complemento)"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:103
+msgid "general_addontype_lpaddon_plural"
+msgstr "Paquetes de idioma (Complemento)"
+
+#: models/addontype.php:83
+msgid "general_addontype_lpapp"
+msgstr "Paquete de idioma (Aplicación)"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:102
+msgid "general_addontype_lpapp_plural"
+msgstr "Paquetes de idioma (Aplicación)"
+
+#: models/addontype.php:87
+msgid "general_addontype_plugin"
+msgstr "Plugin"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:104
+msgid "general_addontype_plugin_plural"
+msgstr "Plugins"
+
+#: models/addontype.php:81
+msgid "general_addontype_search"
+msgstr "Motor de búsqueda"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:101
+msgid "general_addontype_search_plural"
+msgstr "Motores de búsqueda"
+
+#: models/addontype.php:77
+msgid "general_addontype_theme"
+msgstr "Tema"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:99
+msgid "general_addontype_theme_plural"
+msgstr "temas"
+
+#: config/language.php:367
+#, fuzzy
+msgid "general_languages_all_locales"
+msgstr "All Locales"
+
+#: views/layouts/amo2009.thtml:249
+#, fuzzy
+msgid "header_brand_name"
+msgstr "Mozilla"
+
+#. %1$s is the application name. Example: Firefox
+#: views/elements/header.thtml:111 views/elements/header.thtml:122
+#: views/layouts/amo2009.thtml:248
+#, php-format
+msgid "header_home_tooltip"
+msgstr "Volver a la página de inicio de Complementos para %1$s"
+
+#: views/elements/header.thtml:87
+msgid "header_main_firefox_header"
+msgstr "Complementos para Firefox"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:218
+#, fuzzy
+msgid "header_main_firefox_header_with_logo"
+msgstr ""
+"Add-ons <em>for</em> <img alt=\"Firefox\" src=\"%1$s\" /> <strong>Firefox</"
+"strong>"
+
+#: views/elements/header.thtml:99
+msgid "header_main_header"
+msgstr "Complementos"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:242
+#, fuzzy
+msgid "header_main_header_with_logo"
+msgstr "Add-ons <img alt=\"Add-ons\" src=\"%1$s\" />"
+
+#: views/elements/header.thtml:90
+msgid "header_main_seamonkey_header"
+msgstr "Complementos para Seamonkey"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:224
+#, fuzzy
+msgid "header_main_seamonkey_header_with_logo"
+msgstr ""
+"Add-ons <em>for</em> <img alt=\"seamonkey\" src=\"%1$s\" /> "
+"<strong>SeaMonkey</strong>"
+
+#: views/elements/header.thtml:93
+msgid "header_main_sunbird_header"
+msgstr "Complementos para Sunbird"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:230
+#, fuzzy
+msgid "header_main_sunbird_header_with_logo"
+msgstr ""
+"Add-ons <em>for</em> <img alt=\"sunbird\" src=\"%1$s\" /> <strong>Sunbird</"
+"strong>"
+
+#: views/elements/header.thtml:96
+msgid "header_main_thunderbird_header"
+msgstr "Complementos para Thunderbird"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:236
+#, fuzzy
+msgid "header_main_thunderbird_header_with_logo"
+msgstr ""
+"Add-ons <em>for</em> <img alt=\"thunderbird\" src=\"%1$s\" /> "
+"<strong>Thunderbird</strong>"
+
+#: views/layouts/amo2009.thtml:205
+#, fuzzy
+msgid "header_navaccess_applications_menu"
+msgstr "Skip to other applications menu"
+
+#: views/layouts/amo2009.thtml:204
+#, fuzzy
+msgid "header_navaccess_categories_menu"
+msgstr "Skip to categories menu"
+
+#: views/layouts/amo2009.thtml:202
+#, fuzzy
+msgid "header_navaccess_main_content"
+msgstr "Skip to main content"
+
+#: views/layouts/amo2009.thtml:203
+#, fuzzy
+msgid "header_navaccess_search_form"
+msgstr "Skip to search form"
+
+#: views/elements/header.thtml:62
+msgid "header_navlink_addons"
+msgstr "Complementos"
+
+#: views/elements/developers/sidebar.thtml:72
+#: views/elements/developers/myaddons.thtml:50 views/elements/header.thtml:159
+#: views/addons/display.thtml:378
+msgid "header_navlink_login"
+msgstr "Iniciar sesión"
+
+#: views/elements/header.thtml:156 views/layouts/amo2009.thtml:304
+msgid "header_navlink_logout"
+msgstr "Salir"
+
+#: views/elements/header.thtml:145 views/layouts/amo2009.thtml:303
+msgid "header_navlink_myaccount"
+msgstr "Mi cuenta"
+
+#: views/elements/header.thtml:158
+msgid "header_navlink_register"
+msgstr "Registrarse"
+
+#. %1 is the URL to the registration page
+#. %2 is the URL to the login page
+#: views/layouts/amo2009.thtml:278
+#, fuzzy
+msgid "header_navlink_register_or_login"
+msgstr "<a href=\"%1$s\">Register</a> or <a href=\"%2$s\">Log in</a>"
+
+#: views/layouts/amo2009.thtml:285
+#, fuzzy
+msgid "header_navlink_tools"
+msgstr "Tools"
+
+#. %s is the add-on name
+#: views/elements/collections_interactive_addon.thtml:62
+#: views/elements/amo2009/homepage_addon.thtml:77
+#: views/elements/addon_discussionheader.thtml:62
+#: views/elements/addon_listitem.thtml:67 views/elements/feature.thtml:84
+#: views/addons/category_landing.thtml:87 views/addons/browse_thumbs.thtml:60
+#, php-format
+msgid "img_preview_of"
+msgstr "Imagen previa de %s"
+
+#. %1 is the login URL for the link tag
+#. %2 is the link to an explanatory page.
+#: views/elements/amo2009/install.thtml:307 views/elements/install.thtml:255
+msgid "install_a_login_to_install"
+msgstr ""
+"<a href=\"%1$s\">Inicia sesión</a> para instalar este complemento "
+"experimental. ¿<a href=\"%2\" \"$s\">Por qué</a>?\""
+
+#. %1 is the URL for the Experimental Add-ons section of the FAQ page
+#: views/elements/amo2009/install.thtml:283 views/elements/install.thtml:232
+msgid "install_button_confirm_exp_install"
+msgstr ""
+"Déjame instalar este complemento experimental. <a href=\"%1$s\">¿Qué es esto?"
+"</a>"
+
+#. %1$s is the application name. Example: Firefox
+#. %2$s is an optional string used to specify a platform. Example: (Windows)
+#: views/elements/amo2009/install.thtml:128 views/elements/install.thtml:75
+#, php-format
+msgid "install_button_text"
+msgstr "Añadir a %s %s"
+
+#. %1 is the add-on name, %2 is the app name
+#: views/elements/amo2009/install.thtml:191
+#: views/elements/amo2009/install.thtml:206
+#: views/elements/amo2009/install.thtml:249
+#: views/elements/amo2009/install.thtml:298 views/elements/install.thtml:150
+#: views/elements/install.thtml:165 views/elements/install.thtml:202
+#: views/elements/install.thtml:246
+#, php-format
+msgid "install_button_title"
+msgstr "Añadir %1$s a %2$s"
+
+#. %1$s is the add-on name
+#: views/elements/amo2009/install.thtml:200 views/elements/install.thtml:159
+#, php-format
+msgid "install_download"
+msgstr "Descargar %1$s"
+
+#: views/elements/amo2009/install.thtml:147 views/elements/install.thtml:94
+msgid "install_error_addon_not_found"
+msgstr "¡Complemento no encontrado!"
+
+#: views/addons/dictionaries.thtml:65
+msgid "langtools_a11y_tablesummary"
+msgstr "Lista de paquetes de idioma y diccionarios."
+
+#: views/addons/dictionaries.thtml:47
+msgid "langtools_download_dictionary"
+msgstr "Descargar diccionario"
+
+#: views/addons/dictionaries.thtml:48
+msgid "langtools_download_langpack"
+msgstr "Descargar paquete de idioma"
+
+#: views/addons/dictionaries.thtml:63 controllers/components/amo.php:685
+#: controllers/addons_controller.php:1239
+msgid "langtools_header_dicts_and_langpacks"
+msgstr "Diccionarios y paquetes de idioma"
+
+#: views/addons/dictionaries.thtml:44
+msgid "langtools_install_dictionary"
+msgstr "Instalar diccionario"
+
+#: views/addons/dictionaries.thtml:45
+msgid "langtools_install_langpack"
+msgstr "Instalar paquete de idioma"
+
+#: views/addons/dictionaries.thtml:69
+msgid "langtools_tableheader_dictionary"
+msgstr "Diccionario"
+
+#: views/addons/dictionaries.thtml:70
+msgid "langtools_tableheader_langpack"
+msgstr "Paquete de idioma"
+
+#: views/addons/dictionaries.thtml:68
+msgid "langtools_tableheader_language"
+msgstr "Idioma"
+
+#: models/license.php:65
+msgid "license_custom"
+msgstr "Licencia personalizada"
+
+#: config/bootstrap.php:303
+msgid "licenses_bsd"
+msgstr "Licencia BSD"
+
+#: config/bootstrap.php:298
+msgid "licenses_gpl_2.0"
+msgstr "Licencia pública GNU, versión 2.0"
+
+#: config/bootstrap.php:299
+msgid "licenses_gpl_3.0"
+msgstr "Licencia pública GNU, versión 3.0"
+
+#: config/bootstrap.php:300
+msgid "licenses_lgpl_2.1"
+msgstr "Licencia pública menor GNU Lesser, versión 2.1"
+
+#: config/bootstrap.php:301
+msgid "licenses_lgpl_3.0"
+msgstr "Licencia pública menor GNU Lesser, versión 3.0"
+
+#: config/bootstrap.php:302
+msgid "licenses_mit"
+msgstr "Licencia MIT/X11"
+
+#: config/bootstrap.php:297
+msgid "licenses_mpl_1.1"
+msgstr "Licencia pública Mozilla, versión 1.1"
+
+#: views/users/emailchange.thtml:51 views/users/delete.thtml:55
+#: views/users/delete.thtml:137 views/users/edit.thtml:74
+#: views/reviews/flag.thtml:54
+msgid "link_return_to_front_page"
+msgstr "Haz clic aquí para volver a la página principal."
+
+#: views/elements/amo2009/addon_list_options.thtml:46
+#: views/elements/addon_list_options.thtml:46
+msgid "list_sortby_date"
+msgstr "Fecha"
+
+#: views/elements/amo2009/addon_list_options.thtml:47
+#: views/elements/addon_list_options.thtml:47
+msgid "list_sortby_downloads"
+msgstr "Descargas"
+
+#: views/elements/amo2009/addon_list_options.thtml:45
+#: views/elements/addon_list_options.thtml:45
+msgid "list_sortby_name"
+msgstr "Nombre"
+
+#: views/elements/amo2009/addon_list_options.thtml:48
+#: views/elements/addon_list_options.thtml:48
+msgid "list_sortby_rating"
+msgstr "Puntuación"
+
+#: config/bootstrap.php:278
+msgid "main_prettyname_fennec"
+msgstr "Fennec"
+
+#: config/bootstrap.php:274
+msgid "main_prettyname_firefox"
+msgstr "Firefox"
+
+#: config/bootstrap.php:277
+msgid "main_prettyname_seamonkey"
+msgstr "SeaMonkey"
+
+#: config/bootstrap.php:276
+msgid "main_prettyname_sunbird"
+msgstr "Sunbird"
+
+#: config/bootstrap.php:275
+msgid "main_prettyname_thunderbird"
+msgstr "Thunderbird"
+
+#: views/elements/addon_categories.thtml:52
+msgid "nav_category_dicts_langpacks"
+msgstr "Diccionarios y paquetes de idioma"
+
+#: views/elements/addon_categories.thtml:55
+msgid "nav_category_themes"
+msgstr "Temas"
+
+#: views/elements/app_chooser.thtml:47 views/layouts/amo2009.thtml:255
+msgid "other_apps_tooltip"
+msgstr "Encontrar complementos para otras aplicaciones"
+
+#. In a user list: user 1, user 2, "others"
+#: views/helpers/addons_html.php:222
+msgid "other_users"
+msgstr "otros"
+
+#: controllers/pages_controller.php:90
+msgid "page_title_appversions"
+msgstr "Versiones de la aplicación"
+
+#: controllers/pages_controller.php:115
+#, fuzzy
+msgid "page_title_collector"
+msgstr "Add-on Collector"
+
+#: controllers/pages_controller.php:117
+#, fuzzy
+msgid "page_title_collector_faq"
+msgstr "Add-on Collector FAQ"
+
+#: controllers/pages_controller.php:119
+#, fuzzy
+msgid "page_title_collector_features"
+msgstr "Add-on Collector Features"
+
+#: controllers/pages_controller.php:122
+#, fuzzy
+msgid "page_title_collector_firstrun"
+msgstr "Welcome to the Add-on Collector"
+
+#: controllers/pages_controller.php:92
+msgid "page_title_credits"
+msgstr "Créditos"
+
+#: controllers/pages_controller.php:113
+msgid "page_title_developer_faq"
+msgstr "Preguntas frecuentes del desarrollador"
+
+#: controllers/pages_controller.php:111
+msgid "page_title_faq"
+msgstr "Preguntas frecuentes"
+
+#: controllers/pages_controller.php:94
+msgid "page_title_fashionyourfirefox_faq"
+msgstr "PUF de \"Pon a punto Firefox\""
+
+#: controllers/pages_controller.php:101
+msgid "page_title_policy"
+msgstr "Política de los complementos"
+
+#: controllers/pages_controller.php:103
+msgid "page_title_privacy"
+msgstr "Política de privacidad de Mozilla"
+
+#: controllers/pages_controller.php:105
+msgid "page_title_review_guide"
+msgstr "Guía de valoración"
+
+#: controllers/pages_controller.php:107
+msgid "page_title_sandbox"
+msgstr "Sistema de valoración del área de prueba"
+
+#: controllers/pages_controller.php:109
+msgid "page_title_submissionhelp"
+msgstr "Ayuda sobre el envío"
+
+#: views/pages/appversions.thtml:87
+msgid "pages_appversions_guid"
+msgstr "GUID"
+
+#: views/pages/appversions.thtml:79 controllers/pages_controller.php:90
+msgid "pages_appversions_header"
+msgstr "Versiones válidas para las aplicaciones "
+
+#: views/pages/appversions.thtml:80
+msgid "pages_appversions_intro"
+msgstr ""
+"Los complementos enviados a Mozilla Addons deben especificar al menos una "
+"aplicación válida, como las listadas abajo, en el archivo install.rdf. Solo "
+"son permitidas para estas aplicaciones las versiones que se detallan abajo."
+
+#. %s is a full <a> tag
+#: views/pages/appversions.thtml:93
+#, php-format
+msgid "pages_appversions_required_files"
+msgstr ""
+"Si tu aplicación no requiere un archivo install.rdf, debes aun así incluir "
+"uno con las propiedades requeridas tal como se especifican %s."
+
+#. this is the text inside of an <a> tag for pages_appversions_required_files. This
+#. should be fixed.
+#: views/pages/appversions.thtml:93
+msgid "pages_appversions_required_files_link"
+msgstr "aquí"
+
+#: views/pages/appversions.thtml:88
+msgid "pages_appversions_versions"
+msgstr "Versiones"
+
+#: views/pages/policy.thtml:51
+msgid "pages_policy_sandbox_link"
+msgstr "Página de información del área de pruebas"
+
+#: views/elements/pagination.thtml:53
+msgid "pagination_next_page"
+msgstr "siguiente"
+
+#: views/elements/pagination.thtml:52
+msgid "pagination_previous_page"
+msgstr "anterior"
+
+#: views/elements/recaptcha.thtml:65
+msgid "recaptcha_enter_both_words"
+msgstr ""
+"Por favor, introduce <strong>todas las palabras</strong> que aparece, "
+"<strong>separadas por un espacio</strong>."
+
+#: views/elements/recaptcha.thtml:83
+msgid "recaptcha_enter_here"
+msgstr "Introduce tu respuesta aquí:"
+
+#: views/elements/recaptcha.thtml:74
+msgid "recaptcha_enter_whatyouhear"
+msgstr "Por favor, escribe lo que oigas."
+
+#. %1 is the link switching refreshing the captcha
+#. %2 is the link switching to a text captcha
+#: views/elements/recaptcha.thtml:77
+msgid "recaptcha_hardtohear_text"
+msgstr ""
+"Si es difícil de comprender, puedes <a href=\"%1$s\">escuchar otra cosa</a> "
+"o <a href=\"%2$s\">cambiar a texto</a>."
+
+#. %1 is the link switching refreshing the captcha
+#. %2 is the link switching to an audio captcha
+#: views/elements/recaptcha.thtml:68
+msgid "recaptcha_hardtoread_text"
+msgstr ""
+"Si es difícil de leer, puedes <a href=\"%1$s\">probar otras palabras</a> o "
+"<a href=\"%2$s\">escuchar el audio</a> en su lugar."
+
+#: views/users/register.thtml:105
+msgid "recaptcha_label"
+msgstr "¿Eres humano?"
+
+#: views/users/register.thtml:106
+msgid "recaptcha_whatsthis"
+msgstr "¿Qué es esto?"
+
+#: controllers/reviews_controller.php:559
+msgid "review_flag_error"
+msgstr "¡Error al marcar esta valoración!"
+
+#: models/reviews_moderation_flag.php:69
+msgid "review_flag_reason_bug_support"
+msgstr "Informe de problema en un lugar incorrecto o petición de asistencia"
+
+#: views/reviews/display.thtml:103 views/reviews/display.thtml:186
+msgid "review_flag_reason_instructions"
+msgstr "Informa de esta valoración (elige una razón)"
+
+#: models/reviews_moderation_flag.php:67
+msgid "review_flag_reason_language"
+msgstr "Lenguaje inapropiado"
+
+#: models/reviews_moderation_flag.php:71
+msgid "review_flag_reason_other"
+msgstr "Otro (por favor, especifícalo)"
+
+#: models/reviews_moderation_flag.php:65
+msgid "review_flag_reason_spam"
+msgstr "Publicidad u otro contenido no relacionado"
+
+#: views/reviews/display.thtml:91 views/reviews/display.thtml:175
+#: controllers/reviews_controller.php:555
+msgid "review_flag_success"
+msgstr ""
+"Gracias; esta valoración ha sido marcada para su aprobación por parte de un "
+"editor."
+
+#: views/reviews/display.thtml:41
+msgid "review_flag_this"
+msgstr "Informar de esta valoración"
+
+#: views/reviews/display.thtml:42
+msgid "review_flag_this_titletip"
+msgstr ""
+"Si esta valoración es inapropiada, incorrecta o ¿publicidad? Haz clic aquí "
+"para marcarla y que un editor la revise."
+
+#. %1 is the URL of the support section, %2 for the review guidelines
+#: views/reviews/add.thtml:53
+msgid "review_guidelines_short"
+msgstr ""
+"<p>Ten en mente estos consejos:</p><ul><li>Escribe como si estuvieras "
+"contando a un amigo tu experiencia con el complementos. Da detalles "
+"específicos y útiles, tales como qué características te gustaron más o "
+"menos, cómo de fácil es de usar, y las desventajas que tiene. Evita palabras "
+"genéricas como \"Genial\" o \"Malo\" a menos que des razones por las cuales "
+"crees esto.</li><li>Por favor, no informes de errores en las valoraciones. "
+"Tu dirección de correo no está disponible a los desarrolladores de "
+"complementos y puede que quieran contactar contigo para resolver la "
+"incidencia. Ve a la <a href=\"%1$s\">sección de asistencia</a> para "
+"descubrir dónde conseguir ayuda técnica para este complemento.</li><li>Por "
+"favor, escribe valoraciones claras, evita el lenguaje inadecuado y no "
+"publiques ninguna información personal.</li></ul><p>Lee la <a href=\"%2$s"
+"\">Guía para revisores</a> para más detalles sobre las valoraciones de "
+"usuarios.</p>"
+
+#. %1 is the add-on name
+#: views/reviews/flag.thtml:56 views/reviews/display.thtml:55
+#: views/reviews/review_added.thtml:50
+#, php-format
+msgid "reviews_header"
+msgstr "Valoraciones de %s"
+
+#: controllers/addons_controller.php:435
+msgid "rss_featuredaddons"
+msgstr "Complementos destacados"
+
+#: controllers/addons_controller.php:432
+msgid "rss_newestaddons"
+msgstr "Últimos complementos"
+
+#: controllers/addons_controller.php:434
+#, fuzzy
+msgid "rss_popularaddons"
+msgstr "Popular Add-ons"
+
+#: controllers/addons_controller.php:433
+msgid "rss_updatedaddons"
+msgstr "Complementos actualizados"
+
+#: views/elements/search_mini.thtml:70
+msgid "search"
+msgstr "Buscar"
+
+#: views/search/collections.thtml:51
+#, fuzzy
+msgid "search_collections_header"
+msgstr "Collection Search Results"
+
+#: controllers/search_controller.php:297
+#, fuzzy
+msgid "search_collections_pagetitle"
+msgstr "Collection Search Results"
+
+#: controllers/search_controller.php:99
+msgid "search_disabled"
+msgstr ""
+"La función de búsqueda no está activa en estos momentos. Por favor, "
+"inténtalo de nuevo más tarde."
+
+#: views/elements/amo2009/search.thtml:188 views/elements/search.thtml:187
+#: views/elements/search_mini.thtml:54
+msgid "search_form_all_addons"
+msgstr "todos los complementos"
+
+#. This string is in the main category dropdown when searching
+#: views/elements/amo2009/search.thtml:204
+#, fuzzy
+msgid "search_form_all_collections"
+msgstr "all collections"
+
+#: views/elements/amo2009/search.thtml:184
+#: views/elements/amo2009/search.thtml:385
+#: views/elements/amo2009/search.thtml:408 views/elements/search.thtml:171
+#: views/elements/search.thtml:183 views/elements/search_mini.thtml:43
+#: views/elements/search_mini.thtml:49 views/layouts/mozilla.thtml:188
+msgid "search_form_default_text"
+msgstr "buscar complementos"
+
+#: views/elements/amo2009/search.thtml:184
+#: views/elements/amo2009/search.thtml:404
+#, fuzzy
+msgid "search_form_default_text_collections"
+msgstr "search for collections"
+
+#: views/elements/amo2009/search.thtml:206 views/elements/search.thtml:202
+msgid "search_form_submit_tooltip"
+msgstr "Buscar complementos"
+
+#: views/elements/amo2009/search.thtml:184 views/elements/search.thtml:183
+#: views/elements/search_mini.thtml:49
+msgid "search_form_tooltip"
+msgstr "Haz clic para escribir tu busqueda"
+
+#: views/elements/amo2009/search.thtml:186 views/elements/search.thtml:185
+#: views/elements/search_mini.thtml:52
+msgid "search_form_within"
+msgstr "dentro de"
+
+#: views/addons/searchengines.thtml:118
+msgid "search_landing_all_search_engines"
+msgstr "Todos los motores de búsqueda"
+
+#: views/addons/searchengines.thtml:114
+msgid "search_landing_browse_search_engines"
+msgstr "Ver motores de búsqueda"
+
+#: views/search/collections.thtml:58 views/search/index.thtml:59
+msgid "search_nothing_found"
+msgstr "No se han encontrado resultados."
+
+#: controllers/search_controller.php:185
+msgid "search_pagetitle"
+msgstr "Buscar complementos"
+
+#: controllers/search_controller.php:242
+msgid "search_rss_description"
+msgstr "Canal de resultados de búsqueda"
+
+#. %s is the terms the user is searching for (a string)
+#: controllers/search_controller.php:241
+#, php-format
+msgid "search_rss_results_for"
+msgstr "Resultados de la búsqueda por: %s"
+
+#: views/elements/header.thtml:154 views/layouts/amo2009.thtml:296
+msgid "sidebar_navlink_admin_tools"
+msgstr "Herramientas de administrador"
+
+#: views/elements/header.thtml:146 views/layouts/amo2009.thtml:288
+msgid "sidebar_navlink_developer_tools"
+msgstr "Herramientas para desarrolladores"
+
+#: views/elements/header.thtml:148 views/layouts/amo2009.thtml:290
+msgid "sidebar_navlink_editor_tools"
+msgstr "Herramientas de edición"
+
+#: views/layouts/amo2009.thtml:302
+msgid "sidebar_navlink_welcome"
+msgstr "Bienvenido"
+
+#. %s is the user's name
+#: views/layouts/amo2009.thtml:302
+#, php-format
+msgid "sidebar_navlink_welcome_name"
+msgstr "Bienvenido, %s"
+
+#: views/elements/pitch.thtml:50 views/elements/pitch.thtml:55
+msgid "sidebar_pitch_dictionary"
+msgstr "Diccionario"
+
+#: views/elements/pitch.thtml:72
+msgid "sidebar_pitch_featured_addons"
+msgstr "Complementos destacados"
+
+#: views/elements/pitch.thtml:61
+msgid "sidebar_pitch_looking_for"
+msgstr "Estoy buscando:"
+
+#: views/elements/pitch.thtml:70
+msgid "sidebar_pitch_newest_addons"
+msgstr "Complementos más nuevos"
+
+#: views/elements/pitch.thtml:49
+msgid "sidebar_pitch_search"
+msgstr "Plugin de búsqueda"
+
+#: views/elements/pitch.thtml:69
+msgid "sidebar_pitch_subscribe_to"
+msgstr "Suscribirse a"
+
+#: views/elements/pitch.thtml:48 views/elements/pitch.thtml:54
+msgid "sidebar_pitch_theme"
+msgstr "Tema"
+
+#: views/elements/pitch.thtml:71
+msgid "sidebar_pitch_updated_addons"
+msgstr "Complementos actualizados"
+
+#. %1$s is a number
+#: views/helpers/localization.php:65 views/developers/versions_edit.thtml:95
+#: views/addons/dictionaries.thtml:92
+#, php-format
+msgid "size_kb"
+msgstr "%1$s Kb"
+
+#: views/elements/amo2009/stars.thtml:57 views/elements/stars.thtml:63
+msgid "stars_not_yet_rated"
+msgstr "Sin puntuar aún"
+
+#. %1 is the number of stars this add-on has
+#: views/elements/amo2009/stars.thtml:49 views/elements/stars.thtml:54
+#, php-format
+msgid "stars_rated_x_outof_5"
+msgstr "Puntuado con %s estrellas de 5"
+
+#: views/statistics/addon.thtml:59
+msgid "statistics_addon_dashboard_link"
+msgstr "Página de inicio del panel de control"
+
+#: views/statistics/addon.thtml:58
+msgid "statistics_addon_developertools_link"
+msgstr "Herramientas del desarrollador"
+
+#: views/statistics/addon.thtml:53
+msgid "statistics_addon_switch"
+msgstr "Cambiar complemento"
+
+#. This is a date format.
+#. http://php.net/strftime
+#: views/statistics/rss/summary.thtml:54 views/statistics/addon.thtml:181
+msgid "statistics_date_shortmonth"
+msgstr "%e de %b"
+
+#. This is a date format.
+#. http://php.net/strftime
+#: views/statistics/rss/summary.thtml:40 views/statistics/addon.thtml:152
+msgid "statistics_date_shortmonthwithyear"
+msgstr "%e de %b, %Y"
+
+#. This is a date format.
+#. http://php.net/strftime
+#: views/statistics/rss/summary.thtml:41 views/statistics/rss/summary.thtml:48
+#: views/statistics/addon.thtml:161 views/statistics/addon.thtml:172
+msgid "statistics_date_weekdayshortmonth"
+msgstr "%A, %e de %b"
+
+#. %1$s is an add-on name and version. Example: Add-on 3.5
+#: controllers/components/stats.php:519
+#, php-format
+msgid "statistics_events_addon_created"
+msgstr "%1$s creado"
+
+#. %1$s is an application name and version. Example: Firefox 3.5
+#: controllers/components/stats.php:500
+#, php-format
+msgid "statistics_events_app_released"
+msgstr "%1$s publicado"
+
+#: views/statistics/addon.thtml:71
+msgid "statistics_help_close_link"
+msgstr "Cerrar"
+
+#: views/statistics/addon.thtml:60
+msgid "statistics_help_link"
+msgstr "Ayuda"
+
+#: views/statistics/index.thtml:83
+msgid "statistics_index_anotheraddon"
+msgstr "o, elige otro complemento"
+
+#: views/statistics/index.thtml:85
+msgid "statistics_index_anotheraddon_public"
+msgstr "o, elige un complemento con estadísticas públicas"
+
+#: views/statistics/index.thtml:71
+msgid "statistics_index_myaddons"
+msgstr "Elige un de tus complementos favoritos para ver sus estadísticas"
+
+#: views/statistics/index.thtml:89
+msgid "statistics_index_selectaddon"
+msgstr "Elige un complemento para ver sus estadísticas"
+
+#: views/statistics/index.thtml:91
+msgid "statistics_index_selectaddon_public"
+msgstr "Elige un complemento con estadísticas públicas"
+
+#: views/statistics/index.thtml:39
+msgid "statistics_index_title"
+msgstr "Panel de estadísticas"
+
+#: views/statistics/index.thtml:97
+msgid "statistics_index_view_button"
+msgstr "Ver estadísticas"
+
+#: views/statistics/addon.thtml:222 controllers/statistics_controller.php:247
+msgid "statistics_js_download_csv"
+msgstr "Ver esta tabla en formato CSV"
+
+#: controllers/statistics_controller.php:246
+msgid "statistics_js_dropdowns_none"
+msgstr "ninguno"
+
+#: controllers/statistics_controller.php:245
+msgid "statistics_js_dropdowns_removeplot"
+msgstr "Eliminar este argumento"
+
+#: controllers/statistics_controller.php:248
+msgid "statistics_js_groupby_selector_date"
+msgstr "Agrupar por: Día"
+
+#: controllers/statistics_controller.php:251
+msgid "statistics_js_groupby_selector_month"
+msgstr "Agrupar por: Mes"
+
+#: controllers/statistics_controller.php:249
+msgid "statistics_js_groupby_selector_week"
+msgstr "Agrupar por: Semana"
+
+#: controllers/statistics_controller.php:250
+msgid "statistics_js_groupby_selector_week_over_week"
+msgstr "Comparar por: Semanas"
+
+#: controllers/statistics_controller.php:260
+msgid "statistics_js_plotselection_foundinrange"
+msgstr "Encontrados %s al alcance"
+
+#: controllers/statistics_controller.php:270
+msgid "statistics_js_plotselection_options_addplot_name"
+msgstr "Añadir argumento"
+
+#: controllers/statistics_controller.php:271
+msgid "statistics_js_plotselection_options_addplot_tooltip"
+msgstr "Añadir otro argumento a este gráfico"
+
+#: controllers/statistics_controller.php:261
+msgid "statistics_js_plotselection_options_count_name_checked"
+msgstr "Ocultar el recuento total"
+
+#: controllers/statistics_controller.php:262
+msgid "statistics_js_plotselection_options_count_name_unchecked"
+msgstr "Ver el recuento total"
+
+#: controllers/statistics_controller.php:263
+msgid "statistics_js_plotselection_options_count_tooltip"
+msgstr "Determinar el recuento total en este gráfico"
+
+#: controllers/statistics_controller.php:275
+msgid "statistics_js_plotselection_options_csv_name"
+msgstr "Ver datos (CSV)"
+
+#: controllers/statistics_controller.php:276
+msgid "statistics_js_plotselection_options_csv_tooltip"
+msgstr "Obtener valores separados por comas para este dato"
+
+#: controllers/statistics_controller.php:267
+msgid "statistics_js_plotselection_options_events_addon_name_checked"
+msgstr "Ocultar %s eventos"
+
+#: controllers/statistics_controller.php:268
+msgid "statistics_js_plotselection_options_events_addon_name_unchecked"
+msgstr "Ver %s eventos"
+
+#: controllers/statistics_controller.php:269
+msgid "statistics_js_plotselection_options_events_addon_tooltip"
+msgstr ""
+"Superponer las fechas de publicación de los complementos con los argumentos"
+
+#: controllers/statistics_controller.php:264
+msgid "statistics_js_plotselection_options_events_firefox_name_checked"
+msgstr "Ocultar los eventos de Firefox"
+
+#: controllers/statistics_controller.php:265
+msgid "statistics_js_plotselection_options_events_firefox_name_unchecked"
+msgstr "Ver los eventos de Firefox"
+
+#: controllers/statistics_controller.php:266
+msgid "statistics_js_plotselection_options_events_firefox_tooltip"
+msgstr "Superponer las fechas de publicación de Firefox sobre los argumentos"
+
+#: controllers/statistics_controller.php:272
+msgid "statistics_js_plotselection_options_resize_name_checked"
+msgstr "Contraer gráfico"
+
+#: controllers/statistics_controller.php:273
+msgid "statistics_js_plotselection_options_resize_name_unchecked"
+msgstr "Expandir gráfico"
+
+#: controllers/statistics_controller.php:274
+msgid "statistics_js_plotselection_options_resize_tooltip"
+msgstr "Redimensionar gráfico"
+
+#: controllers/statistics_controller.php:254
+msgid "statistics_js_plotselection_selector_adu"
+msgstr "Usuarios activos al día"
+
+#: controllers/statistics_controller.php:256
+msgid "statistics_js_plotselection_selector_application"
+msgstr "Aplicación"
+
+#: controllers/statistics_controller.php:259
+msgid "statistics_js_plotselection_selector_custom"
+msgstr "Personalizado"
+
+#: controllers/statistics_controller.php:253
+msgid "statistics_js_plotselection_selector_downloads"
+msgstr "Descargas"
+
+#: controllers/statistics_controller.php:258
+msgid "statistics_js_plotselection_selector_os"
+msgstr "Sistema operativo"
+
+#: controllers/statistics_controller.php:257
+msgid "statistics_js_plotselection_selector_status"
+msgstr "Estado del complemento"
+
+#: controllers/statistics_controller.php:252
+msgid "statistics_js_plotselection_selector_summary"
+msgstr "Resumen"
+
+#: controllers/statistics_controller.php:255
+msgid "statistics_js_plotselection_selector_version"
+msgstr "Versión del complemento"
+
+#: controllers/components/stats.php:398
+msgid "statistics_longnames_application"
+msgstr "Aplicación"
+
+#: controllers/components/stats.php:400
+msgid "statistics_longnames_os"
+msgstr "Sistema operativo"
+
+#: controllers/components/stats.php:399
+msgid "statistics_longnames_status"
+msgstr "Estado del complemento"
+
+#: controllers/components/stats.php:401
+msgid "statistics_longnames_unknown"
+msgstr "Desconocido"
+
+#: controllers/components/stats.php:397
+msgid "statistics_longnames_version"
+msgstr "Versión del complemento"
+
+#: views/statistics/addon.thtml:118
+msgid "statistics_notice_data_insufficient"
+msgstr ""
+"Aún no hay datos suficientes para mostrar este gráfico. Por favor, inténtalo "
+"de nuevo más tarde."
+
+#: views/statistics/addon.thtml:130
+msgid "statistics_notice_data_none"
+msgstr ""
+"No disponemos de datos sobre tu complemento aún. Por favor, inténtalo de "
+"nuevo en unos días."
+
+#: views/statistics/addon.thtml:41
+msgid "statistics_notice_data_updating"
+msgstr ""
+"Las estadísticas de los complementos están actualmente en proceso de ser "
+"actualizados. Los datos actuales pueden ser incompletos mientras nuestros "
+"scripts trabajan para actualizar esta información. Por favor, inténtalo de "
+"nuevo en unos minutos."
+
+#: views/statistics/addon.thtml:136
+msgid "statistics_notice_disabled"
+msgstr ""
+"En panel de estadísticas está desactivado en estos momentos. Por favor, "
+"inténtalo más tarde."
+
+#: views/statistics/addon.thtml:123
+msgid "statistics_notice_nojavascript"
+msgstr ""
+"Se requiere el uso de JavaScript para ver los gráficos del panel de "
+"estadísticas."
+
+#: views/statistics/addon.thtml:44
+msgid "statistics_notice_settings_updated"
+msgstr "¡Se han actualizado tus preferencias!"
+
+#: controllers/statistics_controller.php:60
+#: controllers/statistics_controller.php:71
+#: controllers/statistics_controller.php:74
+#: controllers/statistics_controller.php:240
+msgid "statistics_pagetitle"
+msgstr "Panel de estadísticas"
+
+#: views/statistics/addon.thtml:99
+msgid "statistics_plot_legend_adu"
+msgstr "Usuarios activos por día"
+
+#: views/statistics/addon.thtml:95
+msgid "statistics_plot_legend_downloads"
+msgstr "Descargas al día"
+
+#: views/statistics/addon.thtml:107
+msgid "statistics_plot_options_zoomin_alt"
+msgstr "Ampliar"
+
+#: views/statistics/addon.thtml:106
+msgid "statistics_plot_options_zoomin_title"
+msgstr "Ampliar un mes"
+
+#: views/statistics/addon.thtml:110
+msgid "statistics_plot_options_zoomout_alt"
+msgstr "Reducir"
+
+#: views/statistics/addon.thtml:109
+msgid "statistics_plot_options_zoomout_title"
+msgstr "Reducir un mes"
+
+#: controllers/statistics_controller.php:283
+#, php-format
+msgid "statistics_rss_description"
+msgstr "Resumen diario con estadísticas para %1$s"
+
+#: views/statistics/rss/summary.thtml:68
+msgid "statistics_rss_title_fulldate"
+msgstr "%A, %e de %B de %Y"
+
+#: views/statistics/rss/summary.thtml:68
+#, php-format
+msgid "statistics_rss_title_statsfordate"
+msgstr "Estadísticas para %1$s"
+
+#: views/statistics/settings.thtml:49
+msgid "statistics_settings_access_description"
+msgstr ""
+"Por defecto, solo tú y Mozilla pueden acceder a la información en tu panel "
+"de control. Puedes mostrarlo de forma pública para que todo el mundo pueda "
+"ver los datos e tu complemento."
+
+#: views/statistics/settings.thtml:48
+msgid "statistics_settings_access_heading"
+msgstr "Acceso al panel"
+
+#: views/statistics/settings.thtml:51
+msgid "statistics_settings_access_private"
+msgstr "Privado"
+
+#: views/statistics/settings.thtml:51
+msgid "statistics_settings_access_private_description"
+msgstr "Solo Mozilla y tú pueden ver las estadísticas de este complemento"
+
+#: views/statistics/settings.thtml:52
+msgid "statistics_settings_access_public"
+msgstr "Público"
+
+#: views/statistics/settings.thtml:52
+msgid "statistics_settings_access_public_description"
+msgstr "Cualquiera puede ver las estadísticas de este complemento"
+
+#: views/statistics/addon.thtml:251
+msgid "statistics_settings_change_link"
+msgstr "Cambiar preferencias"
+
+#: views/statistics/addon.thtml:253
+msgid "statistics_settings_confidential"
+msgstr "Por favor, tratar esta información como confidencial."
+
+#: views/statistics/addon.thtml:245
+msgid "statistics_settings_currently_private"
+msgstr "Este panel actualmente es <strong>privado</strong>."
+
+#: views/statistics/addon.thtml:241
+msgid "statistics_settings_currently_public"
+msgstr "Este panel actualmente es <strong>public</strong>."
+
+#: views/statistics/addon.thtml:246
+msgid "statistics_settings_locked_alt"
+msgstr "Bloqueado"
+
+#: views/statistics/settings.thtml:57
+msgid "statistics_settings_return_link"
+msgstr "Volver al panel de control"
+
+#: views/statistics/settings.thtml:56
+msgid "statistics_settings_save_button"
+msgstr "Guardar preferencias"
+
+#: views/statistics/settings.thtml:46
+#, php-format
+msgid "statistics_settings_title"
+msgstr "Preferencias del panel de estadísticas de %1$s"
+
+#: views/statistics/addon.thtml:242
+msgid "statistics_settings_unlocked_alt"
+msgstr "Desbloqueado"
+
+#: controllers/components/stats.php:405
+msgid "statistics_shortnames_application"
+msgstr "App."
+
+#: controllers/components/stats.php:407
+msgid "statistics_shortnames_os"
+msgstr "SO"
+
+#: controllers/components/stats.php:406
+msgid "statistics_shortnames_status"
+msgstr "Est."
+
+#: controllers/components/stats.php:408
+msgid "statistics_shortnames_unknown"
+msgstr "Desc."
+
+#: controllers/components/stats.php:404
+msgid "statistics_shortnames_version"
+msgstr "Ver."
+
+#: views/statistics/rss/summary.thtml:42 views/statistics/addon.thtml:192
+msgid "statistics_summary_downloads_average"
+msgstr "Media de descargas diarias"
+
+#: views/statistics/rss/summary.thtml:39
+msgid "statistics_summary_downloads_heading"
+msgstr "Descargas"
+
+#: views/statistics/rss/summary.thtml:41 views/statistics/addon.thtml:171
+msgid "statistics_summary_downloads_lastcount"
+msgstr "Conteo del último día"
+
+#: views/statistics/rss/summary.thtml:43 views/statistics/addon.thtml:199
+msgid "statistics_summary_downloads_lastweek"
+msgstr "Descargas en los últimos 7 días"
+
+#: views/statistics/rss/summary.thtml:40 views/statistics/addon.thtml:151
+msgid "statistics_summary_downloads_total"
+msgstr "Descargas totales"
+
+#: views/statistics/rss/summary.thtml:40 views/statistics/addon.thtml:152
+#, php-format
+msgid "statistics_summary_downloads_total_sincedate"
+msgstr "Desde %1$s"
+
+#: views/statistics/rss/summary.thtml:50 views/statistics/rss/summary.thtml:56
+#: views/statistics/addon.thtml:163 views/statistics/addon.thtml:183
+msgid "statistics_summary_nodata"
+msgstr "Sin datos aún"
+
+#: views/statistics/rss/summary.thtml:60 views/statistics/addon.thtml:195
+msgid "statistics_summary_updatepings_average"
+msgstr "Media de usuarios activos al día"
+
+#: views/statistics/rss/summary.thtml:52 views/statistics/addon.thtml:177
+msgid "statistics_summary_updatepings_changefromprevious"
+msgstr "Cambio desde el conteo previo"
+
+#: views/statistics/rss/summary.thtml:54 views/statistics/addon.thtml:181
+#, php-format
+msgid "statistics_summary_updatepings_changefromprevious_ondate"
+msgstr "%1$s el %2$s"
+
+#: views/statistics/rss/summary.thtml:45
+msgid "statistics_summary_updatepings_heading"
+msgstr "Usuarios activos al día"
+
+#: views/statistics/rss/summary.thtml:46 views/statistics/addon.thtml:157
+msgid "statistics_summary_updatepings_total"
+msgstr "Usuarios activos al día"
+
+#: views/statistics/rss/summary.thtml:48 views/statistics/addon.thtml:161
+#, php-format
+msgid "statistics_summary_updatepings_total_ondate"
+msgstr "El %1$s"
+
+#: views/statistics/rss/summary.thtml:61 views/statistics/addon.thtml:203
+msgid "statistics_summary_updatepings_weekly_average"
+msgstr "Media de usuarios diaria en esta semana"
+
+#. %s is a percentage, like '+22.33%'. It sits next to another number, so
+#. the implied meaning is 'percentage change' from the previous stat point.
+#: views/statistics/rss/summary.thtml:62 views/statistics/addon.thtml:205
+msgid "statistics_summary_updatepings_weekly_change"
+msgstr "%s desde la última semana"
+
+#: views/statistics/addon.thtml:65 controllers/statistics_controller.php:184
+#: controllers/statistics_controller.php:282
+#, php-format
+msgid "statistics_title_addon_stats"
+msgstr "Estadísticas para %1$s"
+
+#: views/addons/themes_landing.thtml:113
+msgid "themes_landing_all_themes"
+msgstr "Todos los temas"
+
+#: views/addons/themes_landing.thtml:109
+msgid "themes_landing_browse_themes"
+msgstr "Ver temas"
+
+#: views/users/edit.thtml:185
+msgid "user_change_email"
+msgstr "Cambiar correo electrónico"
+
+#: views/users/edit.thtml:169
+msgid "user_change_password"
+msgstr "Cambiar contraseña"
+
+#: views/users/edit.thtml:96
+#, fuzzy
+msgid "user_change_password_or_email"
+msgstr "Change Password or Email"
+
+#: controllers/users_controller.php:197
+msgid "user_confirmationcode_resent"
+msgstr "¡El código de confirmación se volvió a enviar!"
+
+#. %1 is the email address, %2 is the URL of the user registration page
+#: views/users/delete.thtml:51
+msgid "user_del_account_deleted"
+msgstr ""
+"Tu cuenta de usuario %1$s se ha borrado con éxito. Si algún día quieres "
+"regresar, puedes volverte a registrar en la <a href=\"%2$s\">página de "
+"registro de usuario</a>."
+
+#: views/users/delete.thtml:102
+msgid "user_del_community_sad"
+msgstr "La comunidad de Mozilla se entristece de tenerte que decir adiós."
+
+#: views/users/delete.thtml:123
+msgid "user_del_confirm_password"
+msgstr "Confirmar contraseña"
+
+#: views/users/delete.thtml:134
+msgid "user_del_deletenow"
+msgstr "Borrar mi cuenta de usuario ahora"
+
+#. %1 is the URL of the user's info page
+#: views/users/delete.thtml:64
+msgid "user_del_error_addons"
+msgstr ""
+"No puedes borrar tu cuenta si eres el <a href=\"%1$s\">autor de algún "
+"complemento</a>. Para borrar tu cuenta, por favor, pide a otra persona de tu "
+"grupo de desarrolladores que te elimine de la lista de autores de tus "
+"complementos. Una vez hecho eso, serás capaz de borrar tu cuenta desde aquí."
+
+#. %1 is a link to the amo-editors mailing list
+#: views/users/delete.thtml:71
+msgid "user_del_error_addons_more_questions"
+msgstr ""
+"Si tienes alguna otra pregunta, por favor, contacta en %1$s para recibir "
+"asistencia."
+
+#: views/users/delete.thtml:78
+msgid "user_del_error_checkbox"
+msgstr ""
+"Es necesario que marques la casilla \"Comprendo...\" antes de que podamos "
+"borrar tu cuenta."
+
+#: views/users/delete.thtml:84
+msgid "user_del_error_password"
+msgstr ""
+"Por favor, introduce tu contraseña correctamente para poder completar este "
+"paso."
+
+#. %1 is a link to the amo-admins mailing list
+#: views/users/delete.thtml:91
+msgid "user_del_error_unknown"
+msgstr ""
+"Ha ocurrido un error no esperado al borrar tu cuenta de usuario. Por favor, "
+"escribe a %1$s comentando el problema y borraremos la cuenta por ti. Te "
+"pedimos disculpas por los inconvenientes."
+
+#: views/users/delete.thtml:110
+msgid "user_del_header_confirm_deletion"
+msgstr "Confirmar el borrado de cuenta"
+
+#. %1 is the user's email address
+#: views/users/delete.thtml:100
+msgid "user_del_header_delete_account"
+msgstr "Borrar la cuenta de usuario %1$s"
+
+#: views/users/delete.thtml:50
+msgid "user_del_header_farewell"
+msgstr "¡Hasta luego!"
+
+#: views/users/delete.thtml:115
+msgid "user_del_nologin"
+msgstr "No podrás ingresar como usuario en Mozilla Addons nunca más."
+
+#: views/users/delete.thtml:112
+msgid "user_del_permanently_removed_means"
+msgstr ""
+"Al hacer clic en \"borrar\", tu cuenta se <strong>borrara de forma "
+"permanente</strong>. Lo que significa que:"
+
+#: views/users/delete.thtml:116
+msgid "user_del_reviews_anonymized"
+msgstr ""
+"Tus valoraciones y puntuaciones no se borrarán, pero no estarán nunca más "
+"asociadas a ti."
+
+#. %1 is a link to the amo-editors mailing list
+#: views/users/delete.thtml:104
+msgid "user_del_specific_problem_editors"
+msgstr ""
+"Si tienes algún problema específico en el que te podamos ayudar, por favor, "
+"no borres aún la cuenta y contacta con nosotros en %1$s , trataremos de "
+"ayudarte lo mejor posible para solucionarlo."
+
+#: views/users/delete.thtml:130
+msgid "user_del_understand_permanent"
+msgstr "Comprendo que este paso no se puede deshacer."
+
+#: views/helpers/addons_html.php:192
+msgid "user_deleted_nickname"
+msgstr "Usuario borrado"
+
+#. %1 is the new email address
+#: views/users/edit.thtml:71
+msgid "user_edit_confirm_email_sent"
+msgstr ""
+"Se ha enviado un correo electrónico a %1$s para confirmar tu nueva "
+"dirección. Para que este cambio surta efecto, necesitas hacer clic en el "
+"enlace que se proporciona en este correo. Hasta entonces, puedes seguir "
+"ingresando con tu dirección de correo electrónico actual."
+
+#: views/users/edit.thtml:201
+msgid "user_edit_delete_user"
+msgstr "Borrar la cuenta de usuario"
+
+#. This contains the email sent to users when they signed up for a new
+#. account:
+#. %1 is the confirmation URL, %2 is the current app
+#: views/users/email/confirm_plain.thtml:6
+#, php-format
+msgid "user_email_confirm_account_nopass"
+msgstr ""
+"Bienvenido a %2$s Addons.\n"
+"\n"
+"Antes de que puedas usar su nueva cuenta, debes activarla - esto permite "
+"asegurarnos que la dirección de correo que usaste es válida y te pertenece.\n"
+"Para activar tu cuenta, haz clic en el enlace de abajo o copia y pega la "
+"dirección en la barra de direcciones de tu navegador:\n"
+"\n"
+"%1$s\n"
+"\n"
+"Una vez que hayas activado satisfactoriamente tu cuenta, puedes borrar este "
+"correo.\n"
+"\n"
+"Gracias por unirte a %2$s Addons\n"
+"-- El Equipo de %2$s Addons"
+
+#. %1 is the confirmation url, %2 is the application name
+#: views/users/email/emailchange_plain.thtml:5
+msgid "user_email_confirm_emailchange"
+msgstr ""
+"Has solicitado cambiar tu dirección de correo electrónico en %2$s Addons.\n"
+"\n"
+"Para poder confirmar tu nueva dirección, por favor, haz clic en el enlace a "
+"continuación o copia y pega la dirección completa en la barra de direcciones "
+"de tu navegador:\n"
+"\n"
+"%1$s\n"
+"\n"
+"Dispones de 48 horas para confirmar la nueva dirección. Si ya no deseas "
+"cambiar de dirección, simplemente ignora este correo.\n"
+"\n"
+"¡Gracias!\n"
+"-- El equipo de %2$s Addons"
+
+#: controllers/users_controller.php:168
+#, php-format
+msgid "user_email_confirm_subject"
+msgstr "Gracias por unirte a Mozilla Addons"
+
+#. This is the password reset email
+#. %1 is the pw reset URL, %2 is the application
+#: views/users/email/pwreset_plain.thtml:5
+#, php-format
+msgid "user_email_pwreset"
+msgstr ""
+"Reinicio de contraseña de Mozilla Addons\n"
+"\n"
+"Se ha recibido una solicitud para reiniciar la contraseña de esta cuenta en "
+"addons.mozilla.org. Para cambiar esta cuenta, por favor pulse en el "
+"siguiente enlace, o copialo en la barra de direcciones de su navegador:\n"
+"\n"
+"%1$s\n"
+"\n"
+"Si no ha solicitado este mensaje no tiene que hacer nada.\n"
+"\n"
+"Gracias,\n"
+"-- El personal de Mozilla Addons"
+
+#: controllers/users_controller.php:245
+#, php-format
+msgid "user_email_pwreset_subject"
+msgstr "Reiniciar su contraseña de Mozilla Addons"
+
+#: views/users/emailchange.thtml:50
+msgid "user_emailchange_error"
+msgstr "¡Error!"
+
+#. %1 is the application name
+#: controllers/users_controller.php:533
+msgid "user_emailchange_subject"
+msgstr ""
+"Por favor, confirma el cambio de tu dirección de correo electrónico en %1$s "
+"Addons"
+
+#: views/users/emailchange.thtml:48
+msgid "user_emailchange_success"
+msgstr "¡Correcto!"
+
+#. %1 is the new email address
+#: views/users/emailchange.thtml:49
+msgid "user_emailchange_successful_description"
+msgstr ""
+"Tu dirección de correo electrónico se ha cambiado con éxito. A partir de "
+"ahora, por favor, usa %1$s para ingresar."
+
+#: views/users/edit.thtml:134 views/admin/users_edit.thtml:111
+msgid "user_form_bio"
+msgstr "Acerca de mí"
+
+#: views/users/edit.thtml:135 views/admin/users_edit.thtml:112
+msgid "user_form_bio_description"
+msgstr ""
+"¡Preséntate a ti mismo a la comunidad, si quieres! Este texto aparecerá de "
+"forma pública en tu página de información de usuario. Los saltos de línea se "
+"mantendrán, pero el código HTML no está permitido."
+
+#: views/users/pwreset.thtml:77 views/users/register.thtml:73
+#: views/users/edit.thtml:181
+msgid "user_form_confirmpassword"
+msgstr "Confirmar contraseña"
+
+#: views/users/edit.thtml:145
+#, fuzzy
+msgid "user_form_display_collections"
+msgstr "Display the collections I have created in my user profile"
+
+#: views/users/edit.thtml:149
+#, fuzzy
+msgid "user_form_display_collections_fav"
+msgstr "Display my favorite collections in my user profile"
+
+#: views/users/edit.thtml:86
+#, php-format
+msgid "user_form_editprofile"
+msgstr "Editar perfil del usuario %s"
+
+#: views/users/pwreset.thtml:52 views/users/login.thtml:81
+#: views/users/register.thtml:63 views/users/edit.thtml:187
+msgid "user_form_email"
+msgstr "Dirección de correo electrónico"
+
+#: views/users/register.thtml:78 views/users/edit.thtml:103
+#: views/admin/users_edit.thtml:76
+msgid "user_form_firstname"
+msgstr "Nombre"
+
+#: views/users/register.thtml:94 views/users/edit.thtml:119
+#: views/admin/users_edit.thtml:91
+msgid "user_form_hideemail"
+msgstr "Ocultar dirección de correo electrónico"
+
+#: views/users/register.thtml:98 views/users/edit.thtml:123
+#: views/admin/users_edit.thtml:99
+msgid "user_form_homepage"
+msgstr "Dirección del sitio web"
+
+#: views/users/register.thtml:84 views/users/edit.thtml:109
+#: views/admin/users_edit.thtml:81
+msgid "user_form_lastname"
+msgstr "Apellidos"
+
+#: controllers/users_controller.php:333
+msgid "user_form_login"
+msgstr "Código de usuario"
+
+#: views/users/pwreset.thtml:72 views/users/edit.thtml:176
+msgid "user_form_newpassword"
+msgstr "Nueva contraseña"
+
+#: views/users/register.thtml:89 views/users/edit.thtml:114
+#: views/admin/users_edit.thtml:86
+msgid "user_form_nickname"
+msgstr "Apodo"
+
+#: views/users/edit.thtml:171
+msgid "user_form_oldpassword"
+msgstr "Contraseña antigua"
+
+#: views/users/edit.thtml:97 views/users/edit.thtml:200
+msgid "user_form_otheractions"
+msgstr "Otras acciones"
+
+#: views/users/login.thtml:85 views/users/register.thtml:68
+msgid "user_form_password"
+msgstr "Contraseña"
+
+#: controllers/users_controller.php:93
+msgid "user_form_registration"
+msgstr "Registro de nuevo usuario"
+
+#: views/users/login.thtml:90
+msgid "user_form_remember_me"
+msgstr "Recuérdame en este equipo"
+
+#: views/admin/users_edit.thtml:95
+msgid "user_form_showsandbox"
+msgstr "¿Ver el área de pruebas?"
+
+#: views/users/edit.thtml:205
+msgid "user_form_submit_edit"
+msgstr "Guardar"
+
+#: views/users/login.thtml:93
+msgid "user_form_submit_login"
+msgstr "Entrar"
+
+#: views/users/register.thtml:113
+msgid "user_form_submit_register"
+msgstr "Registrarse"
+
+#: views/users/info.thtml:75
+#, php-format
+msgid "user_info_usersince"
+msgstr "%s complementos del usuario"
+
+#: views/users/login.thtml:102
+msgid "user_login_register_link"
+msgstr "Crear una nueva cuenta de usuario"
+
+#: views/users/edit.thtml:160
+msgid "user_notifications_item_compat"
+msgstr "Compatibilidad del complemento (altamente recomendado)"
+
+#: views/users/edit.thtml:161
+msgid "user_notifications_item_events"
+msgstr "Próximos eventos y concursos"
+
+#: views/users/edit.thtml:156
+msgid "user_notifications_none_available"
+msgstr "Actualmente no tienes avisos disponibles para configurar."
+
+#: views/users/edit.thtml:158
+msgid "user_notifications_select_topics"
+msgstr ""
+"De vez en cuando, Mozilla puede enviarte un correo electrónico sobre "
+"próximas publicaciones y eventos sobre complementos. Por favor, selecciona "
+"debajo los temas en los que estás interesados:"
+
+#: views/users/edit.thtml:164
+msgid "user_notifications_specific_contact"
+msgstr ""
+"Mozilla se reserva el derecho de contactar contigo individualmente sobre "
+"temas específicos de los complementos que hayas alojado."
+
+#: controllers/users_controller.php:543
+msgid "user_profile_edit_error"
+msgstr ""
+"Hay errores en los cambios que ha hecho. Por favor, corrígelos y vuelva a "
+"enviarlos..."
+
+#: controllers/users_controller.php:540
+msgid "user_profile_saved"
+msgstr "Perfil actualizado."
+
+#: views/users/pwreset.thtml:65
+#, php-format
+msgid "user_pwreset_for_email"
+msgstr "Reiniciar contraseña de %s"
+
+#: controllers/users_controller.php:226
+msgid "user_pwreset_header"
+msgstr "Reiniciar contraseña"
+
+#: views/users/login.thtml:103
+msgid "user_pwreset_link"
+msgstr "¿Ha olvidado su contraseña?"
+
+#: controllers/users_controller.php:248
+msgid "user_pwreset_link_sent"
+msgstr ""
+"El enlace de reinicio de contraseña se ha enviado a su dirección de correo "
+"electrónico."
+
+#: controllers/users_controller.php:304
+msgid "user_pwreset_okay"
+msgstr "Contraseña reiniciada con éxito."
+
+#: views/users/pwreset.thtml:82
+msgid "user_pwreset_submit_changepw"
+msgstr "Confirmar cambio de contraseña"
+
+#: views/users/pwreset.thtml:57
+msgid "user_pwreset_submit_sendlink"
+msgstr "Enviar enlace para reiniciar contraseña"
+
+#: views/users/register_complete.thtml:51
+#, php-format
+msgid "user_register_amo_link"
+msgstr "%s Addons"
+
+#. %1 is the user's email address, %2 is the current app
+#: views/users/activatefirst.thtml:49
+#, php-format
+msgid "user_register_click_confirm_link"
+msgstr ""
+"Un enlace para activar tu cuenta de usuario ha sido enviado a tu cuenta de "
+"correo %1$s. Debes hacer clic en él antes de que puedas entrar en %2$s "
+"Addons."
+
+#. %1 is the user's email address
+#: views/users/register_complete.thtml:49
+#, php-format
+msgid "user_register_confirm_email_sent"
+msgstr ""
+"Se ha enviado un correo a tu dirección %1$s para confirmar tu cuenta. Antes "
+"de que puedas entrar, debes activar tu cuenta haciendo clic en el enlace que "
+"hay en dicho correo."
+
+#: views/users/activatefirst.thtml:51
+msgid "user_register_confirmation_link_text"
+msgstr "reenviar el mensaje de confirmación"
+
+#: views/users/register_complete.thtml:47
+msgid "user_register_congratulations"
+msgstr "¡Enhorabuena! Tu cuenta de usuario se ha creado con éxito."
+
+#: views/users/register.thtml:50
+msgid "user_register_details"
+msgstr ""
+"<p>El registro en AMO <strong>no es obligatorio</strong> si solo quieres "
+"descargar e instalar complementos públicos.</p><p>Solo necesitas registrarte "
+"si:</p><ul><li>Quieres enviar valoraciones de los complementos</li><li>Eres "
+"desarrollador de complementos y quieres subir y alojarlos en AMO</li></"
+"ul><p>Una vez completes con éxito el registro, se te enviará un correo de "
+"confirmación a la dirección que hayas proporcionado. Por favor, sigue las "
+"instrucciones que se detallan para validar tu cuenta.</p><p>Si lo deseas, "
+"puedes leer nuestros <a href='%1$s' title='Avisos legales'>Avisos legales</"
+"a> y la <a href='%2$s' title='Política de privacidad'>Política de "
+"privacidad</a>.</p>"
+
+#. %1 is the link to the "resend confirmation code" page
+#: views/users/activatefirst.thtml:51
+#, php-format
+msgid "user_register_resend_confirmation_link"
+msgstr ""
+"Si no recibes el correo de confirmación, asegúrate que tu proveedor de "
+"correo no lo marque como \"correo basura\" o \"spam\". Si lo necesitas, "
+"podemos enviarte el %1$s a la dirección de correo electrónico mencionada."
+
+#. %1 is the link to the Mozilla Add-ons front page
+#: views/users/register_complete.thtml:51
+#, php-format
+msgid "user_register_welcome"
+msgstr "¡Gracias por registrarte y bienvenido a %1$s!"
+
+#: views/users/register.thtml:49
+msgid "user_register_welcome_header"
+msgstr "¡Bienvenido a addons.mozilla.org (AMO)!"
+
+#: views/users/register.thtml:81 views/users/edit.thtml:106
+msgid "user_required_firstlast_or_nickname"
+msgstr "Se requiere un nombre, apellido o nick."
+
+#: views/users/edit.thtml:94 views/users/edit.thtml:142
+#, fuzzy
+msgid "user_tab_collections"
+msgstr "Collections"
+
+#: views/users/edit.thtml:95 views/users/edit.thtml:154
+msgid "user_tab_notifications"
+msgstr "Avisos"
+
+#: views/users/edit.thtml:93 views/users/edit.thtml:101
+msgid "user_tab_profile"
+msgstr "Perfil de usuario"
+
+#: controllers/users_controller.php:209
+msgid "user_verified_okay"
+msgstr "¡Verificado con éxito!"
+
+#: controllers/users_controller.php:723
+msgid "users_delete_pagetitle"
+msgstr "Borrar la cuenta de usuario"
+
+#: controllers/users_controller.php:414
+msgid "users_edit_pagetitle"
+msgstr "Edición de cuenta de usuario"
+
+#: views/users/info.thtml:71
+msgid "users_info_aboutme"
+msgstr "Acerca de mí"
+
+#: views/users/info.thtml:96
+#, php-format
+msgid "users_info_addons_by_user"
+msgstr "Complementos de %1$s"
+
+#: views/users/info.thtml:51
+msgid "users_info_author_name"
+msgstr "Nombre"
+
+#: views/users/info.thtml:48
+msgid "users_info_author_profile"
+msgstr "Perfil del autor"
+
+#. %s is the user name
+#: views/users/info.thtml:137
+#, fuzzy
+msgid "users_info_collections_by_user"
+msgstr "Collections by %s"
+
+#: views/users/info.thtml:66
+msgid "users_info_email"
+msgstr "Dirección de correo"
+
+#: views/users/info.thtml:155
+#, fuzzy
+msgid "users_info_fav_collections_by_user"
+msgstr "Favorite Collections"
+
+#: views/users/info.thtml:61
+msgid "users_info_homepage"
+msgstr "Página web"
+
+#: views/users/info.thtml:56
+msgid "users_info_nickname"
+msgstr "Apodo"
+
+#: controllers/users_controller.php:707
+#, php-format
+msgid "users_info_pagetitle"
+msgstr "Información del usuario %1$s"
+
+#. %1 is the user's name
+#: views/users/info.thtml:116
+msgid "users_info_reviews_by_user"
+msgstr "Valoraciones de %s"
+
+#: controllers/users_controller.php:330 controllers/users_controller.php:332
+msgid "users_login_pagetitle"
+msgstr "Inicio de sesión de usuario"
+
+#. %1 is the link to the sandbox/policy explanation page
+#. This message is for a specific add-on not found
+#: views/users/login.thtml:53
+#, php-format
+msgid "users_login_sandbox_display_warning"
+msgstr ""
+"El complemento que estás buscando se encuentra actualmente en el área de "
+"pruebas. Si tienes una cuenta de usuario en Mozilla Addons, por favor inicia "
+"sesión, o <a href=\"%1$s\">descubre más sobre el área de pruebas.</a>"
+
+#. %1 is the link to the sandbox/policy explanation page
+#. This message is for any given sandbox-related page not found
+#: views/users/login.thtml:56
+#, php-format
+msgid "users_login_sandbox_page_warning"
+msgstr ""
+"La página que estas buscando es parte del área de pruebas. Si tienes una "
+"cuenta de usuario en Mozilla Addons, por favor inicia sesión, o <a href=\"%1"
+"$s\">descubre más sobre el área de pruebas.</a>"
+
+#: controllers/users_controller.php:223 controllers/users_controller.php:225
+msgid "users_pwreset_pagetitle"
+msgstr "Reinicio de contraseña de usuario"
+
+#: controllers/users_controller.php:90 controllers/users_controller.php:92
+msgid "users_register_pagetitle"
+msgstr "Registro de nuevo usuario"
+
+#. %1$s is an addon name, like <a>Firebug</a>
+#. %2$s is a version number, like <a>1.2</a>
+#: views/versions/license.thtml:52
+msgid "versions_license_header_source"
+msgstr "Licencia del código fuente para %1$s %2$s"
+
+#: views/addons/category_landing.thtml:147
+msgid "view_recently_added"
+msgstr "Ver todos los añadidos recientemente"
+
+#: views/addons/category_landing.thtml:161
+msgid "view_top_downloads"
+msgstr "Ver todos los más descargados"
+
+#: views/addons/category_landing.thtml:175
+msgid "view_top_rated"
+msgstr "Ver todos los mejor valorados"
+
+#~ msgid "addon_slider_tooltip_next"
+#~ msgstr "Siguiente complemento"
+
+#~ msgid "addon_slider_tooltip_previous"
+#~ msgstr "Complemento previo"
+
+#~ msgid "addon_versions_getlatesttext"
+#~ msgstr "La versión más reciente compatible con"
+
+#~ msgid "addons_display_version_history"
+#~ msgstr "Historial completo de la versión"
+
+#~ msgid "addons_home_newest_header"
+#~ msgstr "Nuevos:"
+
+#~ msgid "addons_home_popular_header"
+#~ msgstr "Más populares:"
+
+#~ msgid "addons_home_recommended_header"
+#~ msgstr "Recomendamos:"
+
+#~ msgid "addons_home_updated_header"
+#~ msgstr "Actualizados recientemente:"
+
+#~ msgid "addons_home_view_all"
+#~ msgstr "Ver todos"
+
+#~ msgid "category_extra_allrecommended"
+#~ msgstr "Ver todos los complementos recomendados"
+
+#~ msgid "category_extra_highestrated"
+#~ msgstr "Los mejor puntuados primero"
+
+#~ msgid "category_extra_lastupdated"
+#~ msgstr "Los actualizados recientemente primero"
+
+#~ msgid "category_extra_mostpopular"
+#~ msgstr "Los más populares primero"
+
+#, fuzzy
+#~ msgid "collections_detail_js_loading"
+#~ msgstr "Loading"
+
+#, fuzzy
+#~ msgid "collections_detail_more_info"
+#~ msgstr "Show More Info"
+
+#~ msgid "devcp_additem_firefox_notice"
+#~ msgstr ""
+#~ "Esta versión de tu complemento no es compatible con Firefox %1$s. Mozilla "
+#~ "tiene planeado publicar la próxima versión de Firefox pronto, así que, "
+#~ "por favor, prueba tu complemento en la nueva versión y actualiza la "
+#~ "información de compatibilidad. Puedes informarte más sobre ello <a href="
+#~ "\"%2$s\">aquí</a>. Esto es simplemente un aviso, puedes continuar y "
+#~ "enviar esta versión a addons.mozilla.org."
+
+#~ msgid "devcp_addon_disabled_successfully"
+#~ msgstr "Complemento desactivado con éxito"
+
+#~ msgid "devcp_addon_edit_pagetitle"
+#~ msgstr "Editar complemento"
+
+#~ msgid "devcp_addon_enabled_successfully"
+#~ msgstr "Complemento activado con éxito"
+
+#~ msgid "devcp_addon_field_description_displaytitle"
+#~ msgstr "Descripción del complemento"
+
+#~ msgid "devcp_addon_field_eula_displaytitle"
+#~ msgstr "CLUF"
+
+#~ msgid "devcp_addon_field_homepage_displaytitle"
+#~ msgstr "Página web del complemento"
+
+#~ msgid "devcp_addon_field_name_displaytitle"
+#~ msgstr "Nombre del complemento"
+
+#~ msgid "devcp_addon_field_privacy_displaytitle"
+#~ msgstr "Política de privacidad"
+
+#~ msgid "devcp_addon_field_summary_displaytitle"
+#~ msgstr "Resumen del complemento"
+
+#~ msgid "devcp_addon_field_supportemail_displaytitle"
+#~ msgstr "Correo de asistencia"
+
+#~ msgid "devcp_addon_field_supporturl_displaytitle"
+#~ msgstr "Web de asistencia"
+
+#~ msgid "devcp_addon_field_versionnotes_displaytitle"
+#~ msgstr "Notas de la versión"
+
+#~ msgid "devcp_addon_nominate_pagetitle"
+#~ msgstr "Proponer el complemento"
+
+#~ msgid "devcp_addon_nominated_successfully"
+#~ msgstr "¡Complemento propuesto con éxito!"
+
+#~ msgid "devcp_addon_status_criteria_review"
+#~ msgstr ""
+#~ "Varías valoraciones del complemente por usuarios (deberían ser "
+#~ "valoraciones externas)."
+
+#~ msgid "devcp_addon_submission_makechanges"
+#~ msgstr ""
+#~ "Visita la página de %1$s para hacer cambios a tu envío, o %2$s para "
+#~ "volver a las Herramientas del desarrollador."
+
+#~ msgid "devcp_addon_submission_makechanges_devcp_link"
+#~ msgstr "haz clic aquí"
+
+#~ msgid "devcp_addon_submission_makechanges_link"
+#~ msgstr "Editar complemento"
+
+#~ msgid "devcp_addon_submission_pending"
+#~ msgstr ""
+#~ "Esta versión ha sido colocada en el área de pruebas esperando "
+#~ "valoraciones por parte de los voluntarios y de un editor de Mozilla "
+#~ "Addons. Se te notificará por correo electrónico cualquier acción que se "
+#~ "tome."
+
+#~ msgid "devcp_addon_submission_sandbox_readmore"
+#~ msgstr ""
+#~ "Puedes leer más sobre el sistema de valoración del área de pruebas %s."
+
+#~ msgid "devcp_addon_submission_sandbox_readmore_link"
+#~ msgstr "aquí"
+
+#~ msgid "devcp_addon_submission_sandboxed"
+#~ msgstr ""
+#~ "Esta versión ha sido colocada en el área de pruebas para su uso por "
+#~ "usuarios expertos. Para que sea mostrado en el área pública, debes %s tu "
+#~ "complemento y someterte a un proceso de valoración."
+
+#~ msgid "devcp_addon_submission_sandboxed_nominate_link"
+#~ msgstr "proponer"
+
+#~ msgid "devcp_addon_submission_success"
+#~ msgstr "El envío de tu complemento se ha completado con éxito."
+
+#~ msgid "devcp_addon_submission_trusted_public"
+#~ msgstr ""
+#~ "Como tu complemento es de confianza, esta versión ha sido aprobada "
+#~ "automáticamente para aparecer en el área pública."
+
+#~ msgid "devcp_addon_submit_pagetitle"
+#~ msgstr "Enviar un complemento"
+
+#~ msgid "devcp_addon_updated_successfully"
+#~ msgstr "Complemento actualizado con éxito"
+
+#~ msgid "devcp_addon_upload_preview"
+#~ msgstr "Quizá desees %s para aumentar el interés en tu complemento."
+
+#~ msgid "devcp_addon_upload_preview_link"
+#~ msgstr "subir una vista previa"
+
+#~ msgid "devcp_author_lookup_none_found"
+#~ msgstr "Autor no encontrado [%s]"
+
+#~ msgid "devcp_author_lookup_remove"
+#~ msgstr "Eliminar"
+
+#~ msgid "devcp_button_cancel"
+#~ msgstr "Cancelar"
+
+#~ msgid "devcp_button_cancel_confirm"
+#~ msgstr "¿Estás seguro que quieres cancelar tu envío?"
+
+#~ msgid "devcp_button_next"
+#~ msgstr "Siguiente"
+
+#~ msgid "devcp_change_addontype"
+#~ msgstr "Cambiar el tipo de complemento:"
+
+#~ msgid "devcp_comments_updated"
+#~ msgstr "Actualizados los comentarios del desarrollador."
+
+#~ msgid "devcp_details_addpreview_link"
+#~ msgstr "Añadir captura"
+
+#~ msgid "devcp_details_author"
+#~ msgstr "Autor"
+
+#~ msgid "devcp_details_authors"
+#~ msgstr "Autores"
+
+#~ msgid "devcp_details_authors_none"
+#~ msgstr "Ninguno"
+
+#~ msgid "devcp_details_categories"
+#~ msgstr "Categorías"
+
+#~ msgid "devcp_details_category"
+#~ msgstr "Categoría"
+
+#~ msgid "devcp_details_description"
+#~ msgstr "Descripción"
+
+#~ msgid "devcp_details_disabled"
+#~ msgstr "Desactivado"
+
+#~ msgid "devcp_details_guid"
+#~ msgstr "GUID"
+
+#~ msgid "devcp_details_header_details"
+#~ msgstr "Detalles"
+
+#~ msgid "devcp_details_header_devcomments"
+#~ msgstr "Comentarios del desarrollador"
+
+#~ msgid "devcp_details_header_previews"
+#~ msgstr "Vistas previas"
+
+#~ msgid "devcp_details_header_versions"
+#~ msgstr "Versiones"
+
+#~ msgid "devcp_details_homepage"
+#~ msgstr "Página web"
+
+#~ msgid "devcp_details_homepage_none"
+#~ msgstr "Ninguna"
+
+#~ msgid "devcp_details_preview_nocaption"
+#~ msgstr "Sin capturas"
+
+#~ msgid "devcp_details_previews_nonefound"
+#~ msgstr "No se encontraron capturas."
+
+#~ msgid "devcp_details_submit_update"
+#~ msgstr "Actualizar"
+
+#~ msgid "devcp_details_supportemail"
+#~ msgstr "Correo de asistencia"
+
+#~ msgid "devcp_details_supportemail_none"
+#~ msgstr "El desarrollador no proporcionó ningún correo de asistencia."
+
+#~ msgid "devcp_details_supporturl"
+#~ msgstr "Web de asistencia"
+
+#~ msgid "devcp_details_supporturl_none"
+#~ msgstr "El desarrollador no proporcionó ninguna web de asistencia."
+
+#~ msgid "devcp_details_trusted"
+#~ msgstr "De confianza"
+
+#~ msgid "devcp_details_versions_none_found"
+#~ msgstr "No se encontraron versiones."
+
+#~ msgid "devcp_disable_cancel"
+#~ msgstr "Cancelar y volver atrás"
+
+#~ msgid "devcp_disable_disable_button"
+#~ msgstr "Sí, desactivarlo"
+
+#~ msgid "devcp_disable_disable_confirm"
+#~ msgstr "¿Estás seguro de querer desactivar este complemento?"
+
+#~ msgid "devcp_disable_disable_description"
+#~ msgstr ""
+#~ "Al desactivar este complemento lo ocultarás de las búsquedas y los "
+#~ "listados. No se podrá descargar desde la web y no enviará avisos de "
+#~ "actualización a los clientes. El complemento será borrado, aunque podrás "
+#~ "volver aquí para reactivarlo si lo deseas."
+
+#~ msgid "devcp_disable_disable_title"
+#~ msgstr "Desactivar %s"
+
+#~ msgid "devcp_disable_enable_button"
+#~ msgstr "Sí, activarlo"
+
+#~ msgid "devcp_disable_enable_confirm"
+#~ msgstr "¿Estás seguro de querer activar este complemento?"
+
+#~ msgid "devcp_disable_enable_description"
+#~ msgstr ""
+#~ "Al activar este complemento, este aparecerá de nuevo en las búsquedas y "
+#~ "en los listados. Se podrá descargar tanto desde la web como mediante los "
+#~ "avisos de actualización de los clientes."
+
+#~ msgid "devcp_disable_enable_title"
+#~ msgstr "Activar %s"
+
+#~ msgid "devcp_edit_author_add"
+#~ msgstr "Añadir autor"
+
+#~ msgid "devcp_edit_author_email"
+#~ msgstr "Correo electrónico del autor"
+
+#~ msgid "devcp_edit_author_remove"
+#~ msgstr "Eliminar"
+
+#~ msgid "devcp_edit_error_categories_unavailable"
+#~ msgstr "No hay categorías disponibles para este tipo de complemento."
+
+#~ msgid "devcp_edit_file_error_incomplete"
+#~ msgstr "Transferencia incompleta"
+
+#~ msgid "devcp_edit_file_error_no"
+#~ msgstr "No se han enviado archivos"
+
+#~ msgid "devcp_edit_file_error_size"
+#~ msgstr "Excede el tamaño máximo de subida"
+
+#~ msgid "devcp_edit_header_authors"
+#~ msgstr "Autores"
+
+#~ msgid "devcp_edit_icon_add_link"
+#~ msgstr "Añadir icono"
+
+#~ msgid "devcp_edit_icon_change_link"
+#~ msgstr "Cambiar icono"
+
+#~ msgid "devcp_edit_label_allow_viewsource"
+#~ msgstr "Permitir a los usuarios ver los archivos fuente en línea"
+
+#~ msgid "devcp_edit_label_categories"
+#~ msgstr "Categorías"
+
+#~ msgid "devcp_edit_label_defaultlocale"
+#~ msgstr "Idioma por defecto"
+
+#~ msgid "devcp_edit_label_icon_delete"
+#~ msgstr "Solo eliminar el icono actual"
+
+#~ msgid "devcp_edit_label_icon_new"
+#~ msgstr "Nuevo archivo de icono"
+
+#~ msgid "devcp_edit_label_info"
+#~ msgstr "Icono"
+
+#~ msgid "devcp_edit_locale_disambiguation_explanation"
+#~ msgstr "breve información adicional (como el nombre del dialecto local)"
+
+#~ msgid "devcp_edit_submit_update"
+#~ msgstr "Actualizar"
+
+#~ msgid "devcp_edit_target_locale_explanation"
+#~ msgstr ""
+#~ "<a href=\"http://wiki.mozilla.org/L10n:Simple_locale_names\">nombre "
+#~ "sencillo del idioma</a>, tal como 'en-US'"
+
+#~ msgid "devcp_editversion_checkedfiles_delete"
+#~ msgstr "Los archivos marcados serán eliminados"
+
+#~ msgid "devcp_editversion_filename_size"
+#~ msgstr "%1$s (%2$s)"
+
+#~ msgid "devcp_editversion_label_files"
+#~ msgstr "Archivos"
+
+#~ msgid "devcp_editversion_label_targetapps"
+#~ msgstr "Aplicaciones destino"
+
+#~ msgid "devcp_editversion_nofiles"
+#~ msgstr "Sin archivos."
+
+#~ msgid "devcp_editversion_reviewernotes"
+#~ msgstr "Notas para el revisor"
+
+#~ msgid "devcp_editversion_submit_update"
+#~ msgstr "Actualizar"
+
+#~ msgid "devcp_error_addon_field_summary_toolong"
+#~ msgstr ""
+#~ "Las descripciones están limitadas a un máximo de 250 caracteres.\n"
+#~ "(Introdujiste %s)"
+
+#~ msgid "devcp_error_addonname_not_unique"
+#~ msgstr ""
+#~ "El nombre de tu complemento ya existe en la base de datos. Por favor, "
+#~ "asegúrese que: <br /><li>Sus GUIDs coinciden. La causa más común de esto "
+#~ "son unas GUIDs erróneas.</li><li>No tienes una entrada duplicada en la "
+#~ "base de datos. Si es así, debes actualizar dicha entrada o eliminarla y "
+#~ "probar de nuevo.</li>"
+
+#~ msgid "devcp_error_describe_changes"
+#~ msgstr ""
+#~ "Por favor, describa los cambios realizados en esta actualización del "
+#~ "complemento."
+
+#~ msgid "devcp_error_file_guids_dont_match"
+#~ msgstr "No concuerdan todas las GUIDs de los archivos"
+
+#~ msgid "devcp_error_identical_version_exists"
+#~ msgstr ""
+#~ "Una versión idéntica (%s) ya existe para este complemento y plataforma."
+
+#~ msgid "devcp_error_nominate_message"
+#~ msgstr "Debes proporcionar los datos requeridos para la propuesta"
+
+#~ msgid "devcp_error_nominate_no_prerelease"
+#~ msgstr "No puedes proponer complementos en fase beta."
+
+#~ msgid "devcp_error_nominate_sandbox_only"
+#~ msgstr ""
+#~ "Solo puedes proponer complementos que estén actualmente en el área de "
+#~ "pruebas."
+
+#~ msgid "devcp_error_saving"
+#~ msgstr "Ocurrió un error mientras se intentaban salvar tus datos."
+
+#~ msgid "devcp_error_update_access_denied"
+#~ msgstr "No tienes permisos para actualizar este complemento."
+
+#~ msgid "devcp_file_addanother"
+#~ msgstr "Añadir otro archivo de plataforma"
+
+#~ msgid "devcp_form_author_add"
+#~ msgstr "Añadir autor"
+
+#~ msgid "devcp_form_author_remove"
+#~ msgstr "Eliminar"
+
+#~ msgid "devcp_form_categories_nextstep"
+#~ msgstr ""
+#~ "Las categorías para tu nuevo complemento estarán disponibles en el "
+#~ "próximo paso."
+
+#~ msgid "devcp_form_error_categories_unavailable"
+#~ msgstr "No hay categoría disponibles para este tipo de complemento."
+
+#~ msgid "devcp_form_error_description_notempty"
+#~ msgstr "Por favor, introduzca una descripción para su complemento."
+
+#~ msgid "devcp_form_error_name_required"
+#~ msgstr "Por favor, introduzca el nombre de su complemento."
+
+#~ msgid "devcp_form_error_select_addontype"
+#~ msgstr "Por favor, seleccione el tipo de complemento que está enviando."
+
+#~ msgid "devcp_form_error_summary_notempty"
+#~ msgstr "Por favor, introduzca una descripción para su complemento."
+
+#~ msgid "devcp_form_label_addonfile"
+#~ msgstr "Archivo del complemento"
+
+#~ msgid "devcp_form_label_addonfile2"
+#~ msgstr "Archivo del complemento 2"
+
+#~ msgid "devcp_form_label_addonfile3"
+#~ msgstr "Archivo del complemento 3"
+
+#~ msgid "devcp_form_label_addontype"
+#~ msgstr "Tipo de complemento"
+
+#~ msgid "devcp_form_label_allow_viewsource"
+#~ msgstr "Permitir a los usuarios ver los archivos fuente en línea"
+
+#~ msgid "devcp_form_label_author_email"
+#~ msgstr "Correo electrónico del autor"
+
+#~ msgid "devcp_form_label_authors"
+#~ msgstr "Autores"
+
+#~ msgid "devcp_form_label_categories"
+#~ msgstr "Categorías"
+
+#~ msgid "devcp_form_label_defaultlocale"
+#~ msgstr "Idioma por defecto"
+
+#~ msgid "devcp_form_label_description"
+#~ msgstr "Descripción"
+
+#~ msgid "devcp_form_label_eula"
+#~ msgstr "Contrato de Licencia para el Usuario Final (CLUF)"
+
+#~ msgid "devcp_form_label_externalsoftware"
+#~ msgstr "Este complemento requiere programas externos"
+
+#~ msgid "devcp_form_label_files"
+#~ msgstr "Archivos"
+
+#~ msgid "devcp_form_label_homepage"
+#~ msgstr "Página web"
+
+#~ msgid "devcp_form_label_iconfile"
+#~ msgstr "Archivo de icono"
+
+#~ msgid "devcp_form_label_name"
+#~ msgstr "Nombre"
+
+#~ msgid "devcp_form_label_platforms"
+#~ msgstr "Plataformas admitidas"
+
+#~ msgid "devcp_form_label_prerelease"
+#~ msgstr "Esta es una versión previa"
+
+#~ msgid "devcp_form_label_privacy"
+#~ msgstr "Política de privacidad"
+
+#~ msgid "devcp_form_label_sitespecific"
+#~ msgstr "Este complemento es específico para una página web"
+
+#~ msgid "devcp_form_label_summary"
+#~ msgstr "Descripción"
+
+#~ msgid "devcp_form_label_supportemail"
+#~ msgstr "Correo de ayuda"
+
+#~ msgid "devcp_form_label_supporturl"
+#~ msgstr "Web de asistencia"
+
+#~ msgid "devcp_form_label_target_applications"
+#~ msgstr "Aplicaciones destino"
+
+#~ msgid "devcp_form_label_version"
+#~ msgstr "Versión"
+
+#~ msgid "devcp_form_label_versionnotes"
+#~ msgstr "Notas de las versión"
+
+#~ msgid "devcp_form_no_target_apps"
+#~ msgstr "Ninguna"
+
+#~ msgid "devcp_form_reviewernotes"
+#~ msgstr "Notas para el revisor"
+
+#~ msgid "devcp_form_trustedaddon_destination"
+#~ msgstr ""
+#~ "Como tu complemento es confiable, por favor, elija donde debe ir esta "
+#~ "versión:"
+
+#~ msgid "devcp_form_trustedaddon_destination_public"
+#~ msgstr "Ãrea pública"
+
+#~ msgid "devcp_form_trustedaddon_destination_sandbox"
+#~ msgstr "Ãrea de pruebas"
+
+#~ msgid "devcp_header_developer_agreement"
+#~ msgstr "Acuerdo del desarrollador"
+
+#~ msgid "devcp_header_step1"
+#~ msgstr "Paso 1"
+
+#~ msgid "devcp_header_step1_upload"
+#~ msgstr "Subir archivo"
+
+#~ msgid "devcp_header_step2"
+#~ msgstr "Paso 2"
+
+#~ msgid "devcp_header_step2_addondetails"
+#~ msgstr "Detalles del complemento"
+
+#~ msgid "devcp_header_step3"
+#~ msgstr "Paso 3"
+
+#~ msgid "devcp_header_step3_versiondetails"
+#~ msgstr "Detalles de la versión"
+
+#~ msgid "devcp_header_step4"
+#~ msgstr "Paso 4"
+
+#~ msgid "devcp_header_step4_localization"
+#~ msgstr "Localización"
+
+#~ msgid "devcp_header_step5"
+#~ msgstr "Paso 5"
+
+#~ msgid "devcp_header_step5_success"
+#~ msgstr "Éxito"
+
+#~ msgid "devcp_index_header_myaddons"
+#~ msgstr "Mis complementos"
+
+#~ msgid "devcp_nominate_link_returnto_details"
+#~ msgstr "Volver a los detalles del complemento"
+
+#~ msgid "devcp_notice_autodetected_addontype"
+#~ msgstr "Detectar automáticamente el tipo de complemento: %s."
+
+#~ msgid "devcp_notice_different_defaultlocale"
+#~ msgstr ""
+#~ "El idioma por defecto de este complemento (%1$s [%2$s]) es distinto de su "
+#~ "idioma por defecto (%3$s [%4$s]). Los campos abajo deberían ser "
+#~ "completados en %1$s."
+
+#~ msgid "devcp_question_addontype_incorrect"
+#~ msgstr "¿Incorrecto?"
+
+#~ msgid "devcp_question_delete_file"
+#~ msgstr "¿Estás seguro de borrar este archivo?"
+
+#~ msgid "devcp_skip_reviewing_addon_info"
+#~ msgstr "Saltar la valoración de la información actual de mi complemento"
+
+#~ msgid "devcp_submissions_disabled"
+#~ msgstr ""
+#~ "Los envíos de complementos están actualmente deshabilitados. Por favor, "
+#~ "vuelva a intentarlo más tarde."
+
+#~ msgid "devcp_submit_accept_dev_agreement"
+#~ msgstr "Aceptar"
+
+#~ msgid "devcp_submit_decline_dev_agreement"
+#~ msgstr "Rechazar"
+
+#~ msgid "devcp_summary_admin_disabled"
+#~ msgstr "Este complemento ha sido desactivado por un administrador."
+
+#~ msgid "devcp_summary_header_disabled"
+#~ msgstr "Desactivado"
+
+#~ msgid "devcp_summary_header_trusted"
+#~ msgstr "De confianza"
+
+#~ msgid "devcp_summary_noaddons_submit_one"
+#~ msgstr "No tienes ningún complemento. Haz clic %s para enviar uno."
+
+#~ msgid "devcp_summary_noaddons_submit_one_link"
+#~ msgstr "aquí"
+
+#~ msgid "devcp_theme_upload_preview"
+#~ msgstr "Por favor, asegúrese de %s para su tema."
+
+#~ msgid "devcp_theme_upload_preview_link"
+#~ msgstr "subir una vista previa"
+
+#~ msgid "devcp_version_edit_pagetitle"
+#~ msgstr "Editar versión"
+
+#~ msgid "devcp_version_updated_successfully"
+#~ msgstr "Versión actualizada con éxito."
+
+#~ msgid "editors_submissiontype_new"
+#~ msgstr "Nuevo"
+
+#~ msgid "editors_submissiontype_updated"
+#~ msgstr "Actualizado"
+
+#~ msgid "editors_th_addon_age"
+#~ msgstr "Edad del complemento"
+
+#~ msgid "editors_th_addontypes"
+#~ msgstr "Tipos de complementos"
+
+#~ msgid "editors_th_age"
+#~ msgstr "Antigüedad"
+
+#~ msgid "editors_th_applications"
+#~ msgstr "Aplicaciones"
+
+#~ msgid "editors_th_platforms"
+#~ msgstr "Plataformas"
+
+#~ msgid "editors_th_submissiontypes"
+#~ msgstr "Tipos de envíos"
+
+#~ msgid "error_notice"
+#~ msgstr "Advertencia"
+
+#~ msgid "forum_save"
+#~ msgstr "Guardar"
+
+#~ msgid "home"
+#~ msgstr "Inicio"
+
+#~ msgid "nav_category_plugins"
+#~ msgstr "Plugins"
+
+#~ msgid "page_title_experimental_addons"
+#~ msgstr "Complementos experimentales"
+
+#~ msgid "pages_experimental_addons_backbutton"
+#~ msgstr "Volver a la página anterior"
+
+#~ msgid "pagination_page_number_title"
+#~ msgstr "Está es la página %1$s de %2$s"
+
+#~ msgid "search_matching_addons_number"
+#~ msgid_plural "search_matching_addons_number"
+#~ msgstr[0] "%s complemento encontrado"
+#~ msgstr[1] "%s complementos encontrados"
+
+#~ msgid "statistics_rss_icon_title"
+#~ msgstr "Canal RSS con datos de resumen"
diff --git a/site/app/locale/es_ES/images/sandbox-review.png b/site/app/locale/es_ES/images/sandbox-review.png
new file mode 100644
index 0000000..f3d72dc
--- /dev/null
+++ b/site/app/locale/es_ES/images/sandbox-review.png
Binary files differ
diff --git a/site/app/locale/es_ES/pages/error404.thtml b/site/app/locale/es_ES/pages/error404.thtml
new file mode 100644
index 0000000..df081d6
--- /dev/null
+++ b/site/app/locale/es_ES/pages/error404.thtml
@@ -0,0 +1,16 @@
+<h1>Lo sentimos, pero no hemos podido encontrar lo que estabas buscando.</h1>
+
+<p>La página o el archivo que solicitaste no fue encontrado en nuestro sitio. Es posible que hicieras clic en un enlace desfasado, o que escribieras la dirección incorrectamente.</p>
+
+<ul>
+<li>Si escribiste la dirección a mano, por favor revisa de nuevo la ortografía.</li>
+<li>Si llegaste a través de un enlace, por favor comunícanoslo en <a href="mailto:webmaster@mozilla.com" title="Página no encontrada en Mozilla.com">webmaster@mozilla.com</a>. Explícanos desde donde llegaste y que estabas buscando, haremos todo lo posible por arreglarlo.</li>
+</ul>
+
+<p>O simplemente puedes echar un vistazo a algunas de las páginas más populares de nuestra web.</p>
+
+<ul>
+<li>¿Estás interesado en una <a href="%1$s">lista de complementos populares</a>?</li>
+<li>¿Quieres <a href="%2$s">buscar algún complemento</a>? Entonces quizás quieras ir a la <a href="%2$s">página de búsqueda</a> o usar el cuadro de búsqueda de la web.</li>
+<li>Si prefieres una vista general del sitio, ve a la <a href="%3$s">página inicial de complementos</a>.</li>
+</ul>
diff --git a/site/app/locale/es_ES/pages/nomination.thtml b/site/app/locale/es_ES/pages/nomination.thtml
new file mode 100644
index 0000000..6cc7e66
--- /dev/null
+++ b/site/app/locale/es_ES/pages/nomination.thtml
@@ -0,0 +1,9 @@
+<p>Un complemento que se encuentre en el área de pruebas puede ser nominado para ser parte del sitio público y estar así disponible para todos los usuarios tras pasar revisión por un editor. Para obtener los mejores resultados, por favor, ten en cuenta lo siguiente:</p>
+<ul>
+ <li>Las imágenes con vista previas son obligatorias para los temas y muy recomendables para los otros tipos de complementos</li>
+ <li>El complemento debería haber pasado suficiente tiempo en el área de pruebas para acumular revisiones y comentarios de los usuarios. <strong>Se necesitan revisiones para que el complemento sea público</strong></li>
+ <li>Los complementos públicos tienen un estándar de calidad mayor que los complementos en el área de pruebas y deberían mejorar la web</li>
+ <li>El criterio completo para la nominación está detallado en nuestra <a href="%s">Política de complementos</a></li>
+</ul>
+<p>Si tu complemento cumple los criterios anteriores, puedes nominarlo pulsando el botón siguiente. Se te notificará por correo electrónico sobre la situación de tu nominación.</p>
+<p>>Para nominar tu complemento, por favor, haz un informe de como ha sido probado (incluyendo que está libre de errores y advertencias) y cómo es útil para la web. Puedes incluir también enlaces a revisiones externas de tu complemento.</p>
diff --git a/site/app/locale/es_ES/pages/policy.thtml b/site/app/locale/es_ES/pages/policy.thtml
new file mode 100644
index 0000000..f40b8f6
--- /dev/null
+++ b/site/app/locale/es_ES/pages/policy.thtml
@@ -0,0 +1,111 @@
+<h1>Política de complementos</h1>
+
+<h2>¿Qué es el área de pruebas?</h2>
+<p>Echa un vistazo a %s.</p>
+
+<h2>¿Qué complementos están en el área de pruebas?</h2>
+<p>El área de pruebas es donde van inicialmente todos los complementos alojados en AMO. Contiene nuevas versiones de los complementos públicos, así como todas las versiones de los complementos que no están en el sitio público. Cuando un nuevo complemento, o una actualización a uno existente, se envían a AMO, son depositados en el área de pruebas.</p>
+
+<p>Algunos complementos, y sus versiones específicas, pasan al sitio público una vez que el proceso de revisión indica que están listos y son apropiados para ser mostrados al público. Otros complementos permanecerán en el área de pruebas indefinidamente, donde están disponibles para los usuarios que escojan acceder al área de pruebas y experimentar con el software disponible en ella.</p>
+
+<h2>¿Cómo se convierten los complementos en públicos?</h2>
+
+<p>Los complementos se revisan por usuarios de AMO que escogen ver el área de pruebas y probar los paquetes encontrados aquí. Las revisiones que escriben los usuarios de AMO indicarán si un complemento es suficientemente útil y está bien escrito y pulido para ser puesto a disposición de todos los usuarios de Firefox. Estas revisiones, posiblemente sumadas a otras revisiones e inspecciones del equipo de AMO, se usan para determinar si un complemento dado debe ser hecho público , si necesita más trabajo para pulirlo y otorgarle mayor visibilidad, o si no es aceptable para su promoción en el sitio AMO fuera del área de pruebas.</p>
+
+<h2>¿Cómo hago que mi complemento sea promocionado a estado público?</h2>
+
+<p>Si crees que tu complemento (¡y tu comportamiento!) cumple los criterios para un complemento público, puedes proponerlo desde el panel de control del desarrollador.</p>
+
+<h2>¿Cuáles son los criterios para los complementos públicos?</h2>
+
+<p>Un complemento que se convierta en público en AMO debería ser de alta calidad, y proporcionar a los usuarios una experiencia web mejorada. Buscamos las siguientes cosas a la hora de decidir si un complemnto es apropiado para el área pública de AMO:</p>
+
+<h3>¿Eres rápido respondiendo?</h3>
+
+<p>Nosotros creemos que un autor que está promocionando su complemento a muchos usuarios de Firefox debe reaccionar rápidamente a los informes de problemas, mantener actualizada su información de contacto, y actualizar su complemento rápidamente para mantenerlo al día de las versiones de Firefox y los cambios en la política de AMO. Esto no significa que tengas que responder a cada pregunta que alguien publique en las discusiones, o incluso que debas resolver cada bug, pero esperamos que respondas a los problemas de una manera apropiada a la gravedad de cada uno.</p>
+
+<h3>¿El complemento está descrito de forma clara y precisa?</h3>
+
+<p>Es de la máxima importancia para nosotros que los usuarios obtengan lo que esperan cuando prueban un nuevo complemento. Tu descripción debería proporcionar detalles sobre qué hace el complemento, cómo le sacaría partido un usuario, y qué debe esperar éste cuando lo instale. Los enlaces a documentos externos para instrucciones detalladas están bien, pero la descripción en sí misma debería cubrir los puntos básicos y dejar a los usuarios con la tranquilidad de saber qué van a obtener.</p>
+
+<p>También es importante que mantengas las notas de versión adecuadamente a medida que mejores y cambies tu complemento. Los usuarios deberían poder ver qué hay de nuevo en un complemento que hayan probado previamente, y deberían ser avisados de los cambios que puedan afectar su uso actual del complemento cuando lo actualicen (ahora mismo, los usuarios no ven las notas de versión cuando se les solicita una actualización dentro del navegador, pero trabajaremos para corregir esto. Si mantienes las notas de versión bien, tus usuarios se beneficiarán enormemente antes y después de que el trabajo se complete).</p>
+
+<h3>¿Están claramente indicadas todas las cuestiones sobre privacidad y seguridad?</h3>
+
+<p>Esto es un problema de ofrecer una descripción clara y exacta, pero es un problema tan importante que creemos que merece una mención específica. Muchos complementos muy útiles y bien escritos manipulan algún tipo de datos de usuario, o pueden presentar problemas de seguridad si se usan incorrectamente; son bienvenidos en el sitio público de AMO, pero deben dejar muy claro a los usuarios qué riesgos pueden encontrarse, y qué pueden hacer para protegerse a sí mismos.</p>
+
+<h3>¿Se ha probado bien el complemento y está libre de defectos serios u obvios?</h3>
+
+<p>Una cosa importante que miramos cuando consideramos si un complemento está disponible para el público es si las revisiones en el área de pruebas indican que ha sido probado concienzudamente, y que no tiene problemas serios o impactos negativos en el navegador. Si los revisores informan de problemas tales como alteraciones importantes del rendimiento, cierres inesperados, problemas frecuentes al usar las funciones del complemento, o aluviones de mensajes a la consola de error, deberías tomarte esos informes en serio, y volver a proponer tu complemento después de haberlos resuelto lo mejor que puedas. No esperamos que optimices a la perfección ni que consigas cero bugs -- Firefox en sí mismo experiementa mejoras constantes en estas áreas -- pero queremos que hagas un esfuerzo razonable para minimizar los inconvenientes y publicites los casos en los que los usuarios podrían verse sorprendidos por los errores que persistan.</p>
+
+<p>Si tu complemento ha sido probado fuera del proceso de área de pruebas de AMO, como por ejemplo por un grupo de usuarios de tus servicios o de un equipo de control de calidad interno, debes indicarlo en tu mensaje de propuesta. Desde luego, nos ayuda a establecer qué nivel de pruebas ha tenido lugar, y puede ayudar a que tu complemento aparezca en el sitio público.</p>
+
+<h3>¿Tanto el complemento como el autor del complemento tratan al usuario con respeto?</h3>
+
+<p>Tu programa no debe molestar al usuario innecesariamente, intentar engañarle ni ocultarle ninguna de sus acciones. Los usuarios (y también los que no lo son) se muestran groseros a veces con sus comentarios, y aunque nosotros nos esforzamos al máximo en filtrarlos a medida que nos informan de ellos, esperamos que los autores eviten tomar represalias mostrándose ellos también groseros.</p>
+
+<h3>¿Es el complemento útil para una parte significativa de los usuarios de Firefox?</h3>
+
+<p>Tu complemento no necesita ser el nuevo Greasemonkey o FireBug, pero si sólo es útil para la gente de tu empresa o para quienes son parte de una pequeña comunidad web, quizá pensemos que no es apropiado para ponerlo a la vista de todos los usuarios de Firefox.</p>
+
+<p>Estamos buscando continuamente maneras de mejorar la organización del sitio para acomodar mejor los complementos que sirven de ejemplo en otros casos, pero están dirigidos sólo a una pequeña comunidad de usuarios potenciales. Otorgar categorías y mantener los metadatos de tu complemento correctamente nos ayudará a averiguar cómo presentar más complementos de este tipo a la gente que parece que les sacará más provecho.</p>
+
+<p>Si tu complemento sólo proporciona marcadores u otros puntos de acceso simple a tu sitio, probablemente no sea apropiado para la parte pública del sitio. Como al resto del proyecto Mozilla, nos encantan las aplicaciones web y los nuevos servicios web, pero los complementos de Firefox deben proporcionar una mejora en la experiencia de navegación del usuario y no ser sólo una vía para promover un nuevo sitio o servicio a través de una lista de AMO. Si la descripción de tu complemento es en su mayoría sobre el servicio más que sobre la mejora que proporciona a la experiencia de navegación del usuario, probablemente no estés en el buen camino.</p>
+
+<h3>¿Está libre el complemento de marcas registradas sin licencia y de copyrights?</h3>
+
+<p>Aunque no pretendas causar daño al propietario de una marca registrada, o de un trabajo protegido por copyright, no podemos almacenar complementos que infrinjan marcas registradas o copyrights. Si no tienes permiso para usar el nombre o el icono de una marca registrada, por favor, no envíes tu plugin a AMO. Si tu complemento incluye código que está bajo el copyright de otra persona, y no tienes permiso para incluirlo en tu complemento, por favor, no lo envíes a AMO (si el propietario de una marca registrada o un copyright se opone al uso de su marca, probablemente aconsejemos su eliminación, y eliminaremos el complemento si se estima necesario legalmente. Éste es un proceso muy caro en términos de los recursos del proyecto, incluyendo tiempo y dinero, así que, por favor, te pedimos que seas respetuoso y no nos causes dificultades sin razón).</p>
+
+<p>Si no estás seguro de si el nombre de tu complemento o algo usado en su interior impedirá que se muestre en la lista del sitio, puedes pedir consejo en amo-editors@mozilla.org. IMPORTANTE: por favor, date cuenta de que este grupo no puede dar consejos legales, y que incluso si creemos que tu uso es aceptable, es posible que cambiemos de decisión a la luz de quejas de los propietarios de los derechos y de consejos legales de abogados.</p>
+
+<p>Para reutilizar el código fuente de otros complementos, si el autor no ha especificado claramente si permite utilizar su código en tu propio trabajo -- por ejemplo, publicándolo bajo una licencia de código abierto -- entonces deberás suponer que no tienes derecho a hacerlo. Puedes contactar con el autor para pedirle permiso, pero no podemos darte ningún derecho especial por el hecho de que su complemento haya estado en AMO o a que el autor no esté contestando a tu petición (y, de nuevo, no podemos proporcionar consejo legal, sólo consejo sobre cómo parece adecuarse tu complemento a la política del sitio).</p>
+
+<p>Esto se aplica también a las marcas registradas de Mozilla Foundation, incluyendo "Mozilla", "Firefox" y "Thunderbird". La política de Mozilla para el uso de marcas registradas es proteger contra la confusión, y prevenir que las marcas sean revocadas debido a la falta de protección; por favor, respeta la necesidad de esta protección, y ayúdanos a conservar uno de los recursos más valiosos de la Fundación Mozilla.</p>
+
+<h2>¿Qué ocurre cuando propongo un complemento?</h2>
+
+<p>Una vez que tu complemento haya sido propuesto, un equipo de editores de AMO lo evalúa de acuerdo a los criterios descritos más arriba. Si se estima que está listo para su presentación al público, se colocará en la parte pública una vez que haya sido evaluado, y recibirás una notificación por correo electrónico.</p>
+
+<p>Si creemos que el complemento no es apropiado para la parte pública del sitio de AMO ahora mismo, recibirás un correo electrónico indicándote por qué, y tu propuesta será eliminada de la cola. Cuando creas que hayas resuelto los problemas que se indicaban en el correo y quieras ser evaluado de nuevo, puedes hacerlo a tu propio criterio. La repetición de propuestas sin mejoras significativas en el complemento no están bien vistas así que, por favor, hazlo con discreción; es más probable que nos enfades en lugar de convencernos.</p>
+
+<h2>¿Puedo proponer el complemento de otra persona?</h2>
+
+<p>Actualmente, pedimos al autor de un complemento que proponga su propio trabajo para publicarlo. Queremos asegurarmos de que el autor se encuentra cómodo con el aumento de exposición y que cree que el complemento refleja la calidad de su trabajo en su estado actual. Si crees que un complemento está pulido y que el autor está conforme con el texto y el espíritu de la política de AMO, y que hacer que esté disponible para cerca de cien millones de usuarios en todo el mundo beneficiaría a Firefox, a sus usuarios y a la red en general, siéntete libre de animar al autor del complemento a proponer su creación.</p>
+
+<h2>Mi complemento ha estado en la cola de propuestos durante mucho tiempo, ¿es que me odiáis?</h2>
+
+<p>No te odiamos. Nos encantan los desarrolladores de complementos, y trabajamos duramente para hacerlos felices y productivos y que los usuarios de todo el mundo se puedan beneficiar de su trabajo. Pero estar en el lado público de AMO tiene valor precisamente porque tenemos cuidado con lo que acaba aquí, por lo que no podemos precipitarnos sólo para hacerlo más rápido. Nos damos cuenta de que puede ser frustrante esperar a que tu complemento sea evaluado, y por eso queremos mantener el tiempo de respuesta tan corto como es posible. Cuanta más gente lleva a cabo estudios claros y minuciosos de los complementos en la zona de pruebas, más facil es llevar a cabo estas evaluaciones, por lo que quizá quieras ayudar en esta parte, si estás tan dispuesto.</p>
+
+<h2>He encontrado un fallo serio en mi complemento, y tengo mucho interés en publicar la versión corregida rápidamente. ¿Qué tengo que hacer?</h2>
+
+<p>Si hay un fallo serio (un problema de seguridad, estabilidad, o funcionalidad considerable) en tu complemento para el cual necesitas publicar una versión corregida enseguida, debes indicarlo en las "notas de revisión" al enviar la actualización -- al igual que en las notas de la versión, ¡obviamente! Quizá te interese también reclutar a algunos usuarios de tu complemento para que comprueben la actualización e informen detalladamente de sus resultados en la zona de pruebas. Avisar en el canal #addons en irc.mozilla.org puede ayudar a que la gente se entere de la situación, pero, por favor, sé paciente y educado si lo haces.</p>
+
+<p>Por favor, no des falsas alarmas. Intentamos tratar rápidamente las actualizaciones de alta prioridad, pero esto nos quita tiempo para evaluar otros complementos o versiones, y a menudo para dormir o estar con nuestras familias y amigos, por lo que pasamos de la gente que trata de aprovecharse de este mecanismo para "colarse". Si no estás seguro de si debes tomar estas medidas, preguntar en el canal #addons en irc.mozilla.org te puede ayudar a decidirte.</p>
+
+<h2>Creo que se me ha tratado injustamente en la evaluación de mi complemento. ¿Qué debería hacer?</h2>
+
+<p>Si crees que tu complemento no se ha evaluado bien, y se le denegó el estado público por error, envía un correo a amo-editors@mozilla.org con tus razones detalladas. Por favor, sé educado y claro en tu correo, y asegúrate de explicar por qué el complemento ha sido mal evaluado.</p>
+
+<p>(Si has arreglado *todas* las cosas que figuraban como problemas en tu correo de notificación, no deberías recurrir la evaluación, sino volverlo a proponer para su consideración a través del panel de control del desarrollador).</p>
+
+<h2>Mi complemento era público, pero ahora sólo está en la zona de pruebas. ¿Qué ha pasado?</h2>
+
+<p>Si un complemento ya no cumple los criterios para estar en el sitio público, es posible que lo devolvamos a la zona de pruebas. A no ser que no podamos legalmente, te avisaremos por correo electrónico cuando esto ocurra y te indicaremos las razones de haberlo hecho.</p>
+
+<p>También es posible que hayas encontrado un fallo en la página, en cuyo caso debes comunicarlo a través de Bugzilla; utiliza el producto "addons.mozilla.org" y el componente "páginas públicas" en tu informe, y da tantos detalles como puedas.</p>
+
+<h2>Mi complemento es público y parece que a la gente le encanta. ¿Cómo puedo hacer que aparezca en la lista de complementos recomendados?</h2>
+
+<p>Si crees que tu complemento es un ejemplo claro del poder de los complementos, que demuestra y promueve los valores de Mozilla para una red extensible y controlada por los usuarios, y que posibilita una buena experiencia de usuario, puedes pedir que se considere añadirlo a la lista de complementos recomendados. Para hacerlo, envía un correo electrónico a amo-editors@mozilla.org explicando por qué tu complemento es genial.</p>
+
+<p>Tu correo electrónico debería incluir <b>al menos</b> esta información:</p>
+<ul>
+<li>Cómo se mejora la experiencia web para los usuarios</li>
+<li>Por qué tu complemento es apropiado para un amplio rango de usuarios de Firefox</li>
+<li>La manera en que tu complemento demuestra y/o sirve a los valores del proyecto Mozilla, especialmente con respecto a hacerse cargo de la protección de la intimidad y de la seguridad del usuario, al acceso universal a la red, y a los datos y estándares abiertos</li>
+<li>En qué se diferencia tu complemento de otros parecidos al tuyo (comentar los pros y los contras)</li>
+<li>La reacción que han tenido los usuarios, los revisores, los bloggers, los astronautas o tu mascota al usar tu herramienta (también los pros y los contras)</li>
+</ul>
+
+<p>Cuanto más completa sea la información proporcionada más te lo agradeceremos, aunque un complemento perfectamente escrito no tiene por qué aparecer en la lista de recomendados. En última instancia, esta lista debe ser -- y es -- mantenida a criterio de Mozilla, y el disfrute y la protección del usuario final deben prevalecer sobre todo lo demás.</p>
+
diff --git a/site/app/locale/es_ES/pages/reviewguide.thtml b/site/app/locale/es_ES/pages/reviewguide.thtml
new file mode 100644
index 0000000..2c412dc
--- /dev/null
+++ b/site/app/locale/es_ES/pages/reviewguide.thtml
@@ -0,0 +1,66 @@
+<h1>Directrices de valoración</h1>
+<p>La valoración de complementos es una manera de que los usuarios del sitio de complementos compartan sus opiniones sobre los complementos que han instalado y usado. Los editores se reservan el derecho a rechazar o eliminar cualquier valoración que no cumpla con estas directrices.</p>
+
+<div class="corner-box">
+ <h2>Algunos consejos sobre cómo escribir una buena valoración</h2>
+
+<h3><b>Qué debes hacer:</b></h3>
+<ul>
+<li>Escribe como si estuvieras contándole a un amigo tu experiencia con el complemento.</li>
+<li>Procura que las valoraciones sean concisas y fáciles de entender.</li>
+<li>Proporciona detalles concretos y útiles. Por ejemplo:
+<ul>
+ <li>¿Funciona el complemento como tú esperabas?</li>
+ <li>¿Qué características te han gustado y cuáles no?</li>
+ <li>¿Te ha resultado útil?</li>
+ <li>¿Es fácil de usar?</li>
+ <li>¿Vas a seguir usando este complemento?</li>
+</ul></li>
+
+<li>Tómate un momento para leer tu propia valoración antes de enviarla, para evitar errores gramaticales o tipográficos embarazosos.</li>
+
+<li>Evita hacer referencias que sólo tengan sentido en un momento o contexto determinados, ya que las valoraciones pueden permanecer accesibles en el sitio durante mucho tiempo.</li>
+</ul>
+
+<h3><b>Qué NO debes hacer:</b></h3>
+<ul>
+<li>Enviar valoraciones simples como "¡Genial", "Maravilloso" o "Malo" sin aportar explicaciones adicionales.</li>
+<li>Publicar informes de fallos o problemas en las valoraciones. Usa las opciones de asistencia disponibles para cada complemento.</li>
+<li>Escribir valoraciones para complementos que no has usado tú personalmente.</li>
+<li>Usar lenguaje con connotaciones sexuales o religiosas, o que pueda interpretarse como odioso.</li>
+<li>Incluir HTML, enlaces a malware, código fuente o trozos de código. Las valoraciones deben contener únicamente texto.</li>
+<li>Hacer afirmaciones falsas, menospreciar a los autores de complementos o insultarlos.</li>
+<li>Usar las valoraciones como una manera de solicitar asistencia para una versión concreta de Firefox (u otra aplicación).</li>
+<li>Incluir tu propio número de teléfono, dirección de correo u otros detalles personales.</li>
+<li>Publicar valoraciones para un complemento que tú o tu organización habéis escrito o representáis.</li>
+</ul>
+</div>
+
+<div class="corner-box">
+ <h2>Directrices para puntuar complementos</h2>
+
+<p>La puntuación de los complementos debe ser justa y aportar una buena indicación de la calidad y utilidad en conjunto. No te limites a dar 5 estrellas si te gusta o 1 si lo odias. Una graduación consistente es una parte importante de cualquier valoración.</p>
+
+<ul>
+<li><b>5 estrellas: excelente</b>. No sólo hace todo lo que promete, sino que es significativamente más útil que muchos otros complementos. Este complemento es probablemente uno que usarás a menudo y lo recomiendas de verdad.</li>
+<li><b>4 estrellas: bueno</b>. Útil y fácil de usar, aunque no necesariamente especial. Este complemento está recomendado pero puede adaptarse más a algunas personas que otras.</li>
+<li><b>3 estrellas: pasable</b>. Puede haber algunos problemas de diseño o quizá faltan características. En cualquier caso, los problemas que pueda tener no son tan drásticos como para recomendar no usarlo, y algunas personas pueden encontrarlo útil. Recomendado para aquellos que lo necesitan y están dispuestos a darle una oportunidad.</li>
+<li><b>2 estrellas: mediocre</b>. El complemento es de baja calidad, ergonomía o simplemente no hace lo que promete. Estás desaconsejando su uso, a la vez que reconoces que podría tener cierto valor para algunas personas.</li>
+<li><b>1 estrella: malo</b>. El complemento o bien no funciona correctamente o es básicamente inútil. No puedes encontrar una razón significativa por la que alguien debería probarlo y recomiendas que se evite por completo.</li>
+</ul>
+
+<p>No hay nada malo en otorgar a un complemento una valoración perfecta u horrible, siempre que indiques por qué lo haces. Las estrellas no significan nada si no nos dices el motivo.</p>
+</div>
+
+<div class="corner-box">
+ <h2>Preguntas frecuentes sobre las valoraciones</h2>
+
+<h3>¿Cómo puedo informar de una valoración problemática?</h3>
+<p>Por favor, señala o informa de cualquier valoración cuestionable pulsando en "Informar de esta valoración" y se enviará al sitio para su moderación. Los editores usarán las directrices de valoración para evaluar si eliminarla o restaurarla de vuelta al sitio.</p>
+
+<h3>Soy el autor de un complemento, ¿puedo responder a las valoraciones?</h3>
+<p>Sí, los autores de complementos pueden proporcionar una única respuesta a una valoración. Las discusiones adicionales deben redireccionarse a un foro de asistencia o grupo de discusión.</p>
+
+<h3>Soy el autor de un complemento, ¿puedo eliminar valoraciones o puntuaciones desfavorables?</h3>
+<p>En general, no. Pero si la valoración no cumple las directrices de valoración descritas arriba, puedes pulsar en "Informar de esta valoración" y hacer que se modere por un editor. Si una revisión incluía una queja que ya no es válida debido a una nueva versión de tu complemento, podemos considerar eliminar la valoración. Envía tu petición detallada a amo-editors@mozilla.org.</p>
+</div>
diff --git a/site/app/locale/es_ES/pages/sandbox.thtml b/site/app/locale/es_ES/pages/sandbox.thtml
new file mode 100644
index 0000000..9fdad03
--- /dev/null
+++ b/site/app/locale/es_ES/pages/sandbox.thtml
@@ -0,0 +1,13 @@
+<h1>Sistema de revisión del área de pruebas</h1>
+<h2>¿Qué es el área de pruebas?</h2>
+<p>El área de pruebas es una zona para que los usuarios avanzados prueben los complementos antes de que sean revisados para su uso público. Para acceder al área de pruebas, debes activarla en las opciones de tu cuenta de usuario. Hay que tener precaución cuando se instalen complementos del área de pruebas, ya que no han sido probadas por ningún editor y pueden dañar tu ordenador.</p>
+
+<h2>¿Cómo puedo conseguir que mi complemento esté en el área pública?</h2>
+<!-- To localize the flowchart image, see http://wiki.mozilla.org/Update:Remora_Sandbox_Flowchart -->
+<div style="text-align: center;">%s</div>
+<ol>
+ <li><b>Envía tu complemento desde el panel de control de desarrollador.</b> Tu envío aparecerá inmediatamente en el "Ãrea de pruebas" de Mozilla Add-ons, donde usuarios experimentados lo probarán y lo comentarán. Para ver el área de pruebas, debes activarla en las opciones de tu cuenta de usuario.</li>
+ <li><b>Proponer tu complemento para ser público.</b> Desde el panel de control de desarrollador, hay un enlace para proponer tu complemento. Después de ser propuesto, tu complemento aparecerá en la cola de propuestas del editor para su revisión.</li>
+ <li><b>Revisión de tu complemento por un editor.</b> Un editor de Mozilla Add-ons instalará tu complemento para probar su funciona. El editor también revisará los comentarios dados por los voluntarios del área de pruebas.</li>
+ <li><b>Tu complemento es publicado o mantenido en el área de pruebas.</b> El editor publicará tu complemento o lo mantendrá en el área de pruebas. Si es retenido en el área de pruebas, puedes proponerlo de nuevo después de hacer los cambios que el editor te haya sugerido en los comentarios. Si es publicado, las versiones futuras de tu complemento aparecerán en el área de pruebas hasta que hayan sido revisadas por un editor y publicadas. Un vez que tu complemento haya sido publicado, no hay necesidad de proponerlo de nuevo - las versiones futuras irán automáticamente a la cola de pendiente de revisión.</li>
+</ol>
diff --git a/site/app/locale/es_ES/pages/submission_help.thtml b/site/app/locale/es_ES/pages/submission_help.thtml
new file mode 100644
index 0000000..7d81925
--- /dev/null
+++ b/site/app/locale/es_ES/pages/submission_help.thtml
@@ -0,0 +1,35 @@
+<h1>Ayuda sobre envíos</h1>
+Los datos obligatorios están en <b>negrita</b>. Los datos opcionales están en <i>cursiva</i>.
+<h2 id="step1">Paso 1: Cargar</h2>
+<ul class="submissionHelp">
+ <li><span class="required">Tipo de complemento</span> - Por defecto, el tipo de complemento se determinará automáticamente basándose en el archivo cargado. No deberías tener que cambiar este dato.</li>
+ <li><span class="required">Archivo del complemento</span> - El archivo paquete de tu complemento, incluido un archivo install.rdf. Si el archivo sólo funciona con una plataforma específica, seleccionar esta plataforma permitirá que se carguen múltiples archivos a la vez.</li>
+ <li><span class="optional">Archivo icono</span> - El archivo icono se muestra junto al nombre del complemento en su página y se muestra en el diálogo de instalación del complemento. Se redimensionará automáticamente a 32x32 píxeles, manteniendo la relación de aspecto.</li>
+ <li><span class="required">Idioma predeterminado</span> - El idioma predeterminado de un complemento es su idioma principal. Si el idioma seleccionado por un usuario no está disponible en el complemento, la traducciones usarán el idioma predeterminado.</li>
+ <li><span class="optional">Saltar la revisión de la información actual de mi complemento</span> - Este dato aparecerá si estás actualizando un complemento existente. Si marcas la casilla pasará directamente al paso 3 donde puede introducir información específica de versión.</li>
+</ul>
+
+<h2 id="step2">Paso 2: Detalles del complemento</h2>
+<ul class="submissionHelp">
+ <li><span class="required">Nombre</span> - Nombre del complemento en el idioma predeterminado.</li>
+ <li><span class="required">Autores</span> - Todos los usuarios que tienen acceso a modificar los datos del complemento y que figurarán como autores en la página del complemento.</li>
+ <li><span class="required">Categorías</span> - Categorías aplicables al complemento.</li>
+ <li><span class="optional">Página web</span> - El sitio web del complemento en el idioma predeterminado.</li>
+ <li><span class="required">Resumen</span> - Un breve resumen del complemento en el idioma predeterminado. Máximo de 250 caracteres, aparecerá en la página del complemento, así como en los resultados de búsqueda.</li>
+ <li><span class="required">Descripción</span> - Una descripción del complemento en el idioma predeterminado.</li>
+ <li><span class="optional">CLUF</span> - El contrato de licencia de usuario final (CLUF) que deberán aceptar los usuarios antes de descargar, en el idioma predeterminado. Éste se mostrará en la página del complemento debajo de la descripción.</li>
+ <li><span class="optional">Política de privacidad</span> - La política de privacidad del complemento, en el idioma predeterminado. La política de privacidad explica qué se hace con la información personal del usuario final, y será enlazada al lado del botón de instalación en la página del complemento. Hay más información disponible en la <a href="%s">Política de complementos</a> sobre qué debe ser incluido en una política de privacidad y si tu complemento lo requiere.</li>
+ <li><span class="optional">Permitir a los usuarios ver los archivos fuente en línea</span> - Si marcas esta casilla permitirás a los usuarios examinar los archivos fuente de tu complemento en línea.</li>
+ <li><span class="optional">Ésta es una versión preliminar<span> - Si marcas esta casilla indicarás que el complemento es una versión preliminar o "beta". Los complementos en estado beta deben permanecer en el área de pruebas y no pueden ser propuestos para mostrarse públicamente hasta que este estado haya sido superado.</li>
+ <li><span class="optional">Éste es un complemento específico de un sitio</span> - Si marcas esta casilla indicarás que el complemento es específico para un único sitio web, tal como un complemento que altera la presentación de una web determinada o muestra el contenido de una página en concreto. Este campo es útil para los editores y podrá ser usado para filtrar las búsquedas en un futuro.</li>
+ <li><span class="optional">Este complemento requiere programas externos</span> - Si marcas esta casilla indicarás que el complemento requiere software adicional. Este campo es útil para los editores y podrá ser usado para filtrar las búsquedas en un futuro.</li>
+</ul>
+
+<h2 id="step3">Paso 3: Detalles de la versión</h2>
+<ul class="submissionHelp">
+ <li><span class="required optional">Notas de la versión</span> - Un resumen o lista de los cambios en esta versión. Esto es opcional para los nuevos envíos, pero obligatorio para las actualizaciones.</li>
+ <li><span class="optional">Notas al revisor</span> - Este campo se usa para comunicar información a los editores que revisarán tu complemento. Aquí debería figurar información sobre cuentas de usuario necesarias para hacer pruebas y otras notas especiales.</li>
+</ul>
+
+<h2 id="step4">Paso 4: Traducción</h2>
+Aquí es donde se pueden traducir los datos del complemento a todos los idiomas admitidos. Simplemente haz clic en un idioma para introducir traducciones.
diff --git a/site/app/locale/eu/LC_MESSAGES/messages.mo b/site/app/locale/eu/LC_MESSAGES/messages.mo
new file mode 100644
index 0000000..45e40a8
--- /dev/null
+++ b/site/app/locale/eu/LC_MESSAGES/messages.mo
Binary files differ
diff --git a/site/app/locale/eu/LC_MESSAGES/messages.po b/site/app/locale/eu/LC_MESSAGES/messages.po
new file mode 100644
index 0000000..c8760f7
--- /dev/null
+++ b/site/app/locale/eu/LC_MESSAGES/messages.po
@@ -0,0 +1,8854 @@
+# translation of messages.pootle.po to Basque
+# Remora Preliminary Language File
+# Copyright (C) 2006 Mozilla Corporation
+# This file is distributed under the same license as the REMORA package.
+#
+# Wil Clouser <clouserw@mozilla.com>, 2006.
+# Julen Ruiz Aizpuru <julenx@gmail.com>, 2007, 2008.
+msgid ""
+msgstr ""
+"Project-Id-Version: messages.pootle\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2009-01-16 11:45-0800\n"
+"PO-Revision-Date: 2008-03-10 22:15+0100\n"
+"Last-Translator: Ibai Oihanguren <3arrano@3arrano.com>\n"
+"Language-Team: Basque <librezale@librezale.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+"X-Generator: Pootle 1.0.1\n"
+
+#: views/addons/policy.thtml:98
+msgid "a_cancel_installation"
+msgstr "Utzi instalazioa"
+
+#. This is the text that appears on buttons to download add-ons.
+#. %$1s is an optional string that only appears if the add-on is only available for
+#. a certain platform. Examples: (Windows) or (Linux)
+#. Note that the parentheses are included in the string. :(
+#: views/elements/amo2009/install.thtml:126
+#: views/elements/amo2009/install.thtml:227
+#: views/elements/amo2009/install.thtml:257
+#: views/elements/amo2009/install.thtml:300
+#: views/elements/amo2009/install.thtml:312 views/elements/install.thtml:73
+#: views/elements/install.thtml:181 views/elements/install.thtml:205
+#: views/elements/install.thtml:248 views/elements/install.thtml:260
+#: views/addons/plugins.thtml:66 views/addons/plugins.thtml:76
+#: views/addons/plugins.thtml:86 views/addons/plugins.thtml:96
+#: views/addons/plugins.thtml:119
+#, php-format
+msgid "a_download"
+msgstr "Deskargatu orain %s"
+
+#: views/addons/policy.thtml:72
+msgid "a_eula_download"
+msgstr "Onartu eta deskargatu"
+
+#: views/addons/policy.thtml:74
+msgid "a_eula_install"
+msgstr "Onartu eta instalatu"
+
+#: views/elements/header.thtml:76 views/elements/header.thtml:82
+#: views/api/api_addon.thtml:55 views/api/collections_feed.thtml:75
+#: views/sharing_api/addon.thtml:64
+msgid "a_header_public"
+msgstr "Publikoa"
+
+#: views/elements/header.thtml:58 views/elements/header.thtml:75
+#: views/elements/header.thtml:80 views/api/api_addon.thtml:57
+#: views/api/collections_feed.thtml:77 views/sharing_api/addon.thtml:66
+msgid "a_header_sandbox"
+msgstr "Probagunea"
+
+#. %s is a date in the _('date') format
+#: views/elements/amo2009/homepage_addon.thtml:115
+#: views/elements/addon_listitem.thtml:122 views/elements/feature.thtml:106
+#: views/addons/display.thtml:104 views/addons/browse_thumbs.thtml:73
+msgid "addon_detail_last_updated"
+msgstr "%s(e)an eguneratua"
+
+#. %s is the version of the add-on. Example: 3.2a1
+#: views/elements/amo2009/addon_version_detail.thtml:51
+#: views/elements/addon_version_detail.thtml:51
+#, php-format
+msgid "addon_display_header_version"
+msgstr "Azken bertsioa"
+
+#: views/addons/browse_thumbs.thtml:80
+msgid "addon_downloads"
+msgstr "deskarga"
+
+#: views/addons/display.thtml:147
+msgid "addon_downloads_total"
+msgstr "deskarga guztira"
+
+#: views/elements/amo2009/homepage_addon.thtml:106
+#: views/elements/addon_listitem.thtml:115 views/elements/feature.thtml:101
+#: views/addons/category_landing.thtml:157 views/addons/display.thtml:146
+#: views/addons/browse_thumbs.thtml:80
+msgid "addon_downloads_weekly"
+msgstr "deskarga astero"
+
+# %1 is the add-on count, %2 the category name
+#. %1 is the add-on count, %2 the category name
+#: views/addons/browse_thumbs.thtml:104 views/addons/browse.thtml:60
+#, php-format
+msgid "addon_list_category_totalcount"
+msgid_plural "addon_list_category_totalcount"
+msgstr[0] "Gehigarri %1$s"
+msgstr[1] "%1$s gehigarri"
+
+#: views/elements/amo2009/addon_list_options.thtml:103
+#: views/elements/pagination.thtml:67
+#: views/elements/addon_list_options.thtml:94
+msgid "addon_list_perpage"
+msgstr "orriko"
+
+#: views/elements/amo2009/addon_list_options.thtml:84
+#: views/elements/addon_list_options.thtml:98
+msgid "addon_list_sortby"
+msgstr "Ordenatu:"
+
+#: views/helpers/addons_html.php:568 views/elements/amo2009/install.thtml:321
+#: views/elements/feature.thtml:89
+msgid "addon_listitem_flag_experimental"
+msgstr "esperimentala"
+
+#: views/helpers/addons_html.php:570
+msgid "addon_listitem_flag_recommended"
+msgstr "aholkatua"
+
+# %1 is the addon name, %2 is the platform
+#. %1 is the add-on name, %2 is the platform
+#: views/pages/js_constants.js.thtml:66
+msgid "addon_not_available_for_platform"
+msgstr "%1$s ez dago eskuragarri %2$serako."
+
+# %1 is the addon name
+#. %1 is the add-on name
+#: views/addons/policy.thtml:101 views/addons/previews.thtml:60
+#: views/addons/versions.thtml:130 views/reviews/flag.thtml:61
+#: views/reviews/add.thtml:114 views/reviews/display.thtml:216
+#: views/reviews/review_added.thtml:57
+#, php-format
+msgid "addon_review_a_back_to_addon_x"
+msgstr "Itzuli %1$s(e)ra..."
+
+# %1 is the addon name
+#. %1 is the add-on name
+#: views/reviews/flag.thtml:60 views/reviews/add.thtml:113
+#: views/reviews/review_added.thtml:56
+#, php-format
+msgid "addon_review_a_back_to_reviews"
+msgstr "Itzuli berrikuspenetara..."
+
+#: views/reviews/add.thtml:85
+msgid "addon_review_add_rating_field"
+msgstr "Balorazioa:"
+
+#: views/reviews/add.thtml:102
+msgid "addon_review_add_review_field"
+msgstr "Berrikuspena:"
+
+#: views/reviews/add.thtml:107
+msgid "addon_review_add_submit"
+msgstr "Bidali berrikuspena"
+
+#. %s is the name of the add-on
+#: views/reviews/add.thtml:51
+#, php-format
+msgid "addon_review_add_title"
+msgstr "Gehitu berrikuspena %s(r)i"
+
+#: views/reviews/add.thtml:78
+msgid "addon_review_add_title_field"
+msgstr "Izenburua/laburpena:"
+
+#: views/reviews/display.thtml:77 views/reviews/display.thtml:161
+msgid "addon_review_admin_delete"
+msgstr "Ezabatu"
+
+#: views/reviews/display.thtml:76
+msgid "addon_review_author_reply_link"
+msgstr "Erantzun"
+
+#: views/reviews/delete.thtml:62
+msgid "addon_review_confirm_delete"
+msgstr "Ziur berrikuspen hau ezabatu nahi duzula?"
+
+#: views/reviews/delete.thtml:63
+msgid "addon_review_confirm_no"
+msgstr "Ez"
+
+#: views/reviews/delete.thtml:64
+msgid "addon_review_confirm_yes"
+msgstr "Bai"
+
+#: views/reviews/delete.thtml:48
+msgid "addon_review_delete_header"
+msgstr "Ezabatu berrikuspena"
+
+#: controllers/reviews_controller.php:449
+msgid "addon_review_deleted_successfully"
+msgstr "Berrikuspena guztiz ezabatu da."
+
+#. %s is the name of the add-on
+#: views/reviews/add.thtml:51
+#, php-format
+msgid "addon_review_edit_title"
+msgstr "Editatu %s(r)en berrikuspena"
+
+# %1 is the count of characters entered as notes for the review flag reason.
+#. %1 is the count of characters entered as notes for the review flag reason.
+#: controllers/reviews_controller.php:539
+#, fuzzy
+msgid "addon_review_flag_error_other_length"
+msgstr ""
+"Problem flagging review: Notes for flagged reviews are limited to between 10 "
+"and 100 characters; your character length was %1$s."
+
+#. Removing an extra comma
+#: views/reviews/review_added.thtml:53
+msgid "addon_review_in_moderation"
+msgstr ""
+"Oharra: zure berrikuspena gune publikoan erakutsi aurretik editore batek "
+"moderatuko du."
+
+#: views/reviews/add.thtml:57
+msgid "addon_review_in_reply_to"
+msgstr "Hona erantzun garatzaileari:"
+
+# %1 is the review count, %2 is the nickname or full name of the user.
+#. %1 is the review count, %2 is the nickname or full name of the user.
+#: views/reviews/display.thtml:131
+#, fuzzy, php-format
+msgid "addon_review_others_by_user"
+msgid_plural "addon_review_others_by_user"
+msgstr[0] "See %1$s previous review submitted by %2$s for this add-on."
+msgstr[1] "See %1$s previous reviews submitted by %2$s for this add-on."
+
+# %1 is the addon name
+#. %1 is the add-on name
+#: controllers/reviews_controller.php:201
+#: controllers/reviews_controller.php:250
+#: controllers/reviews_controller.php:345
+#: controllers/reviews_controller.php:424
+#, php-format
+msgid "addon_review_pagetitle"
+msgstr "%s(r)en berrikuspenak"
+
+# %1 is the user, %2 is the (localized) date
+#. %1 is the user, %2 is the (localized) date
+#: views/reviews/display.thtml:160
+#, php-format
+msgid "addon_review_reply_on_x_by_y"
+msgstr "%1$s(r)en erantzuna %2$sn"
+
+#: views/reviews/display.thtml:157
+msgid "addon_review_reply_prefix"
+msgstr "Garatzailearen erantzuna:"
+
+#: views/reviews/review_added.thtml:51
+msgid "addon_review_saved_successfully"
+msgstr "Berrikuspena behar bezala gorde da. Milesker!"
+
+#: views/addons/display.thtml:354 views/reviews/display.thtml:72
+msgid "addon_reviewed_by_u_on_d"
+msgstr "%1$s(e)k %2$s(e)an"
+
+# %1 is the (localized) date, y is the rating
+#. %1 is the user, %2 is the (localized) date, %3 is the rating
+#: views/editors/reviews_queue.thtml:57 views/editors/reviews_queue.thtml:68
+#: views/reviews/add.thtml:63 views/reviews/delete.thtml:54
+#, php-format
+msgid "addon_reviewed_on_x_rated_y"
+msgstr "%1$s(e)k %2$sn (balorazioa: %3$s)"
+
+#: views/elements/amo2009/addon_version_detail.thtml:52
+#: views/elements/addon_version_detail.thtml:52
+msgid "addon_version_permalink"
+msgstr "Bertsio honetara lotura iraunkorra"
+
+# %1 is the current Application name (e.g. Firefox)
+# %2 is the Application's version number
+#. %1 is the current Application name (e.g. Firefox)
+#. %2 is the Application's version number
+#: views/addons/versions.thtml:140
+#, fuzzy
+msgid "addon_versions_getlatestversion"
+msgstr "The most recent version compatible with %1$s %2$s"
+
+#: views/addons/display.thtml:447
+msgid "addons_author_addons_submit"
+msgstr "Joan"
+
+#: views/elements/amo2009/homepage_addon.thtml:100
+#: views/elements/feature.thtml:95
+msgid "addons_author_tooltip"
+msgstr "Ikusi egilearen profila"
+
+# %1 is the name of the Application (eg. Firefox)
+#. %1 is the name of the Application (eg. Firefox)
+#: controllers/addons_controller.php:1296
+#, fuzzy
+msgid "addons_browse_all_themes_title"
+msgstr "Browse all Themes :: %1$s Add-ons"
+
+#. %s is the name of the category
+#: controllers/addons_controller.php:1016
+#, php-format
+msgid "addons_browse_browse_category"
+msgstr "Arakatu %s"
+
+# %1 is the name of the theme category (eg. Modern)
+# %2 is the name of the Application (eg. Firefox)
+#. %1 is the name of the theme category (eg. Modern)
+#. %2 is the name of the Application (eg. Firefox)
+#: controllers/addons_controller.php:664
+#, fuzzy
+msgid "addons_browse_categories_header_theme"
+msgstr "Browse %1$s Themes :: %2$s Add-ons"
+
+#: views/addons/display.thtml:249
+#, fuzzy
+msgid "addons_display_a_license_what"
+msgstr "What's this?"
+
+#: views/reviews/display.thtml:222
+msgid "addons_display_add_review"
+msgstr "Gehitu berrikuspena"
+
+#: views/addons/display.thtml:294
+msgid "addons_display_advanced_details"
+msgstr "Xehetasun aurreratuak"
+
+#: views/addons/display.thtml:98
+msgid "addons_display_categories"
+msgstr "Kategoriak"
+
+#: views/addons/display.thtml:482
+#, fuzzy
+msgid "addons_display_collection_add"
+msgstr "Add to a collection:"
+
+#: views/addons/display.thtml:491
+#, fuzzy
+msgid "addons_display_collection_add_new"
+msgstr "New Collection..."
+
+#: views/addons/display.thtml:487
+#, fuzzy
+msgid "addons_display_collection_add_select_one"
+msgstr "Select a collection..."
+
+#: views/addons/display.thtml:493
+#, fuzzy
+msgid "addons_display_collection_add_submit"
+msgstr "Publish"
+
+#. %1$s is the add-on name
+#. %2$s is the collection name, linked to the collection's page
+#: views/pages/js_constants.js.thtml:103 views/addons/display.thtml:61
+#, fuzzy
+msgid "addons_display_collection_publish_success"
+msgstr "%1$s has been added to the %2$s collection."
+
+#: views/addons/display.thtml:483
+#, fuzzy
+msgid "addons_display_collection_whatsthis"
+msgstr "What's this?"
+
+#. %1$s is a number
+#: views/addons/display.thtml:473
+#, fuzzy
+msgid "addons_display_collections_more"
+msgid_plural "addons_display_collections_more"
+msgstr[0] "and %1$s more collection"
+msgstr[1] "and %1$s more collections"
+
+#: views/addons/display.thtml:403
+msgid "addons_display_detailed_review"
+msgstr "berrikuspen xehea"
+
+#: views/reviews/add.thtml:89 views/reviews/add.thtml:90
+msgid "addons_display_dont_like_it"
+msgstr "Ez dut gogoko"
+
+#: views/reviews/display.thtml:220
+msgid "addons_display_edit_review"
+msgstr "Editatu berrikuspena"
+
+#: views/addons/display.thtml:132
+msgid "addons_display_has_privacy"
+msgstr "Gehigarri honek pribatutasun politika du."
+
+#: views/reviews/add.thtml:87 views/reviews/add.thtml:88
+msgid "addons_display_hate_it"
+msgstr "Gorroto dut"
+
+#: views/addons/display.thtml:462
+#, fuzzy
+msgid "addons_display_header_collections"
+msgstr "Related Collections"
+
+#: views/addons/display.thtml:297
+msgid "addons_display_header_developer_comments"
+msgstr "Garatzailearen Iruzkinak"
+
+#: views/addons/display.thtml:230
+msgid "addons_display_header_homepage"
+msgstr "Webgunea"
+
+#: views/addons/display.thtml:247 views/addons/versions.thtml:110
+#, fuzzy
+msgid "addons_display_header_license"
+msgstr "Source Code License"
+
+#: views/addons/display.thtml:337
+msgid "addons_display_header_reviews"
+msgstr "Berrikuspenak"
+
+#: views/addons/display.thtml:261
+msgid "addons_display_header_support"
+msgstr "Laguntza"
+
+#: views/reviews/add.thtml:91 views/reviews/add.thtml:92
+msgid "addons_display_like_it"
+msgstr "Gogoko dut"
+
+#: views/addons/display.thtml:210
+msgid "addons_display_long_description"
+msgstr "Azalpen luzea"
+
+#: views/reviews/add.thtml:95 views/reviews/add.thtml:96
+msgid "addons_display_love_it"
+msgstr "Maite dut"
+
+#: views/addons/display.thtml:178
+msgid "addons_display_more_images"
+msgstr "Irudi gehiago"
+
+#: views/addons/display.thtml:465
+#, fuzzy
+msgid "addons_display_nocollections"
+msgstr "This add-on is not yet in any collections."
+
+# %1$s is either an author's name or a comma separated list of authors. Using
+# the list doesn't make sense in the English plural form so we ignore the
+# variable.
+#. %1$s is either an author's name or a comma separated list of authors. Using
+#. the list doesn't make sense in the English plural form so we ignore the
+#. variable.
+#: views/addons/display.thtml:436
+#, fuzzy
+msgid "addons_display_other_addons_by"
+msgid_plural "addons_display_other_addons_by"
+msgstr[0] "%1$s(r)en beste gehigarri batzuk"
+msgstr[1] "Other add-ons by these authors"
+
+#. %s is the name of the add-on and the add-on section. Example:
+#. Some Add-on :: Firefox Add-ons
+#. This should not be concatenated in the code and should be fixed.
+#: controllers/addons_controller.php:141 controllers/addons_controller.php:280
+#: controllers/addons_controller.php:1442
+#, php-format
+msgid "addons_display_pagetitle"
+msgstr "%s"
+
+#. %s is an email address
+#: views/addons/display.thtml:286
+#, fuzzy, php-format
+msgid "addons_display_paragraph_supportinfoemail"
+msgstr ""
+"Support for this Extension is available at %s.If you have a bug report it "
+"might be best to file it with the developer so that that they can follow up "
+"with you. Reviews are not really the place for detailed bug reports, and the "
+"developer may require several details in order to re-create the bug. Since "
+"we do not make your email address available to extension developers when you "
+"post a review, they will not be able to contact you to ask for more details "
+"or let you know if the bug has been fixed in an upcoming version."
+
+#. %$1s is a URL
+#. %$2s is an email address
+#: views/addons/display.thtml:269
+#, fuzzy, php-format
+msgid "addons_display_paragraph_supportinfoemailurl"
+msgstr ""
+"Support for this Extension is available at %s or %s. If you have a bug "
+"report it might be best to file it with the developer so that that they can "
+"follow up with you. Reviews are not really the place for detailed bug "
+"reports, and the developer may require several details in order to re-create "
+"the bug. Since we do not make your email address available to extension "
+"developers when you post a review, they will not be able to contact you to "
+"ask for more details or let you know if the bug has been fixed in an "
+"upcoming version."
+
+#. %s is a URL
+#: views/addons/display.thtml:278
+#, fuzzy, php-format
+msgid "addons_display_paragraph_supportinfourl"
+msgstr ""
+"Support for this Extension is available at %s. If you have a bug report it "
+"might be best to file it with the developer so that that they can follow up "
+"with you. Reviews are not really the place for detailed bug reports, and the "
+"developer may require several details in order to re-create the bug. Since "
+"we do not make your email address available to extension developers when you "
+"post a review, they will not be able to contact you to ask for more details "
+"or let you know if the bug has been fixed in an upcoming version."
+
+#: views/addons/display.thtml:383
+msgid "addons_display_rate_it"
+msgstr "Puntuatu"
+
+#: views/reviews/add.thtml:93 views/reviews/add.thtml:94
+msgid "addons_display_really_like_it"
+msgstr "Oso gogoko dut"
+
+#: views/addons/display.thtml:410
+#, fuzzy
+msgid "addons_display_review_etiquette"
+msgstr ""
+"Please do not post bug reports in reviews. We do not make your email address "
+"available to add-on developers and they may need to contact you to help "
+"resolve your issue."
+
+# %1 is the review guidelines link
+#. %1 is the review guidelines link
+#: views/addons/display.thtml:417
+#, fuzzy
+msgid "addons_display_review_guidelines_link"
+msgstr "<a href=\"%s\">Review Guidelines</a>"
+
+# %1 is the support section link
+#. %1 is the support section link
+#: views/addons/display.thtml:414
+#, fuzzy
+msgid "addons_display_review_see_support"
+msgstr ""
+"See the <a href=\"%1$s\">support section</a> to find out where to get "
+"assistance for this add-on."
+
+#: views/addons/display.thtml:404
+msgid "addons_display_review_submit"
+msgstr "Gorde"
+
+#: views/addons/display.thtml:430
+#, php-format
+msgid "addons_display_see_all_addons"
+msgstr "Ikusi %1$s(e)rako gehigarri guztiak"
+
+# %1 is the number of reviews
+#. %1 is the number of reviews
+#: views/addons/display.thtml:364
+#, php-format
+msgid "addons_display_see_all_reviews"
+msgstr "Ikusi berrikuspen guztiak (%1$s)"
+
+#: views/addons/display.thtml:219
+msgid "addons_display_see_all_versions"
+msgstr "Ikusi bertsio guztiak"
+
+#: views/addons/display.thtml:321 views/addons/versions.thtml:117
+msgid "addons_display_view_source"
+msgstr "Ikusi iturburua"
+
+#: views/addons/display.thtml:324
+msgid "addons_display_view_stats"
+msgstr "Ikusi estatistikak"
+
+#: views/addons/display.thtml:376
+msgid "addons_display_what_do_you_think"
+msgstr "Zer deritzozu?"
+
+#: views/elements/app_compatibility.thtml:49
+msgid "addons_display_workswith"
+msgstr "Honekin dabil:"
+
+#: views/addons/home.thtml:112
+#, fuzzy
+msgid "addons_home_browse_new"
+msgstr "Just Added"
+
+#: views/addons/home.thtml:110
+#, fuzzy
+msgid "addons_home_browse_popular"
+msgstr "Popular"
+
+#: views/addons/home.thtml:108
+#, fuzzy
+msgid "addons_home_browse_recommended"
+msgstr "Recommended"
+
+#: views/addons/home.thtml:127 views/addons/home.thtml:134
+#: views/addons/home.thtml:141 views/addons/home.thtml:148
+#, fuzzy
+msgid "addons_home_browse_subscribe"
+msgstr "Subscribe"
+
+#: views/addons/home.thtml:101
+#, fuzzy
+msgid "addons_home_browse_title"
+msgstr "Browse Add-ons"
+
+#: views/addons/home.thtml:114
+#, fuzzy
+msgid "addons_home_browse_updated"
+msgstr "Updated"
+
+#: views/elements/amo2009/homepage_addon.thtml:100
+#: views/elements/addon_discussionheader.thtml:83
+#: views/elements/addon_listitem.thtml:109 views/elements/feature.thtml:95
+#: views/addons/category_landing.thtml:66 views/addons/policy.thtml:57
+#: views/addons/display.thtml:70 views/addons/home.thtml:178
+msgid "addons_home_by"
+msgstr "Egilea:"
+
+#: views/addons/home.thtml:169
+#, fuzzy
+msgid "addons_home_collection_popular_title"
+msgstr "Popular Collections"
+
+#: views/elements/amo2009/categories.thtml:69 views/addons/home.thtml:160
+#, fuzzy
+msgid "addons_home_collections"
+msgstr "Collections"
+
+#. %1$s is the count of addons in a collection
+#: views/elements/amo2009/collection_listing_item.thtml:51
+#: views/addons/home.thtml:185
+#, fuzzy
+msgid "addons_home_collections_addon_count"
+msgid_plural "addons_home_collections_addon_count"
+msgstr[0] "<strong>%1$s</strong> add-on"
+msgstr[1] "<strong>%1$s</strong> add-ons"
+
+#: views/addons/home.thtml:196
+#, fuzzy
+msgid "addons_home_collections_all"
+msgstr "View All Collections"
+
+#: views/addons/home.thtml:162
+#, fuzzy
+msgid "addons_home_collections_intro"
+msgstr ""
+"Collections are a way for you to categorize, mix, match and mingle add-ons. "
+"Subscribe to collections created by other users or create your own."
+
+#. %1$s is the count of subscribers for a collection
+#: views/elements/amo2009/collection_listing_item.thtml:58
+#: views/collections/detail.thtml:96 views/addons/home.thtml:189
+#, fuzzy
+msgid "addons_home_collections_subscribers"
+msgid_plural "addons_home_collections_subscribers"
+msgstr[0] "<strong>%1$s</strong> subscriber"
+msgstr[1] "<strong>%1$s</strong> subscribers"
+
+#: views/addons/searchengines.thtml:54 views/addons/themes_landing.thtml:49
+msgid "addons_home_feature_head"
+msgstr "Gure gomendioak"
+
+#: controllers/search_controller.php:218 controllers/addons_controller.php:176
+#: controllers/addons_controller.php:428 controllers/addons_controller.php:671
+#: controllers/addons_controller.php:871
+#: controllers/addons_controller.php:1103
+#: controllers/addons_controller.php:1242
+#: controllers/addons_controller.php:1298
+#, php-format
+msgid "addons_home_header_details"
+msgstr ""
+"Gehigarriek %1$s hedatzen dute, zure nabigazio esperientzia pertsonaliza "
+"dezazun. Begirada bat eman eta %1$s zure egin."
+
+#. %1$s is the HTML collection name link.
+#: views/elements/amo2009/teaser_collections.thtml:107
+#, fuzzy
+msgid "addons_home_introduction_collection_link"
+msgstr "Like these? Find more add-ons in %1$s."
+
+#: views/elements/amo2009/teaser_collections.thtml:60
+#, fuzzy
+msgid "addons_home_introduction_extras"
+msgstr ""
+"<strong>Over 5000 free extras</strong> that let you customize and extend "
+"Firefox to meet your needs."
+
+#: views/elements/amo2009/teaser_collections.thtml:55
+#, fuzzy
+msgid "addons_home_introduction_header"
+msgstr "What are Add-ons?"
+
+#: views/elements/amo2009/teaser_collections.thtml:72
+#, fuzzy
+msgid "addons_home_introduction_install"
+msgstr ""
+"<strong>Easy to install</strong>, get notified when updates are available."
+
+#: views/elements/amo2009/teaser_collections.thtml:45
+#, fuzzy
+msgid "addons_home_introduction_name"
+msgstr "Introduction"
+
+#: views/elements/amo2009/teaser_collections.thtml:66
+#, fuzzy
+msgid "addons_home_introduction_themes"
+msgstr ""
+"Toolbars, themes and search providers that <strong>help you perform common "
+"tasks.</strong>"
+
+#: views/addons/home.thtml:161
+#, fuzzy
+msgid "addons_home_new_indicator"
+msgstr "NEW!"
+
+#: views/elements/app_chooser.thtml:48 views/layouts/amo2009.thtml:257
+msgid "addons_home_other_applications"
+msgstr "Beste aplikazioak"
+
+#. %1$s is the application the user is browsing. Examples: Thunderbird, Firefox,
+#. Sunbird
+#: views/pages/collector_faq.thtml:49 views/pages/collector_firstrun.thtml:42
+#: views/pages/collector.thtml:46 views/pages/collector_features.thtml:54
+#: controllers/developers_controller.php:87
+#: controllers/compatibility_controller.php:72
+#: controllers/components/simple_acl.php:81 controllers/components/amo.php:607
+#: controllers/statistics_controller.php:60
+#: controllers/statistics_controller.php:240
+#: controllers/previews_controller.php:67 controllers/users_controller.php:90
+#: controllers/users_controller.php:223 controllers/users_controller.php:330
+#: controllers/users_controller.php:414 controllers/users_controller.php:708
+#: controllers/users_controller.php:723 controllers/reviews_controller.php:204
+#: controllers/reviews_controller.php:251
+#: controllers/reviews_controller.php:346
+#: controllers/reviews_controller.php:425
+#: controllers/search_controller.php:185 controllers/search_controller.php:297
+#: controllers/search_controller.php:301 controllers/addons_controller.php:147
+#: controllers/addons_controller.php:280 controllers/addons_controller.php:370
+#: controllers/addons_controller.php:667 controllers/addons_controller.php:874
+#: controllers/addons_controller.php:1019
+#: controllers/addons_controller.php:1034
+#: controllers/addons_controller.php:1101
+#: controllers/addons_controller.php:1121
+#: controllers/addons_controller.php:1240
+#: controllers/addons_controller.php:1357
+#: controllers/addons_controller.php:1364
+#: controllers/addons_controller.php:1442
+#: controllers/addons_controller.php:1477
+#: controllers/addons_controller.php:1538
+#: controllers/addons_controller.php:1543
+#: controllers/editors_controller.php:64 controllers/pages_controller.php:132
+#: controllers/groups_controller.php:65 controllers/groups_controller.php:71
+#: controllers/groups_controller.php:89 controllers/groups_controller.php:111
+#: controllers/collections_controller.php:57
+#: controllers/collections_controller.php:121
+#: controllers/collections_controller.php:205
+#: controllers/collections_controller.php:365
+#: controllers/collections_controller.php:404
+#: controllers/collections_controller.php:466
+#: controllers/collections_controller.php:538
+#: controllers/collections_controller.php:828
+#: controllers/localizers_controller.php:72
+#, php-format
+msgid "addons_home_pagetitle"
+msgstr "%1$s(e)rako gehigarriak"
+
+#. %1$s is the number of addons downloaded
+#: views/addons/home.thtml:57
+#, fuzzy, php-format
+msgid "addons_home_stats_downloaded"
+msgid_plural "addons_home_stats_downloaded"
+msgstr[0] "<strong>%1$s</strong> <span>add-on downloaded</span>"
+msgstr[1] "<strong>%1$s</strong> <span>add-ons downloaded</span>"
+
+#. %1$s is the number of addons in use
+#: views/addons/home.thtml:63
+#, fuzzy, php-format
+msgid "addons_home_stats_inuse"
+msgid_plural "addons_home_stats_inuse"
+msgstr[0] "<strong>%1$s</strong> <span>add-on in use</span>"
+msgstr[1] "<strong>%1$s</strong> <span>add-ons in use</span>"
+
+#: views/addons/home.thtml:136
+msgid "addons_home_view_all_newest_title"
+msgstr "Ikusi sortu berri diren gehigarriak"
+
+#: views/addons/home.thtml:129
+msgid "addons_home_view_all_popular_title"
+msgstr "Ikusi gehigarri arrakastatsu guztiak"
+
+#: views/addons/home.thtml:150
+msgid "addons_home_view_all_recommended_title"
+msgstr "Ikusi gomendatutako gehigarri guztiak"
+
+#: views/addons/home.thtml:143
+msgid "addons_home_view_all_updated_title"
+msgstr "Ikusi eguneratu berri diren gehigarriak"
+
+#: views/elements/amo2009/install.thtml:334 views/elements/install.thtml:112
+#, fuzzy
+msgid "addons_install_in_sunbird"
+msgstr ""
+"<ol><li>Click the link below to save the file.</li><li>In Mozilla Sunbird, "
+"open Add-ons from the Tools menu.</li><li>Click the Install button, and "
+"locate/select the file you downloaded and click \"OK\".</li></ol>"
+
+#: views/elements/amo2009/install.thtml:333 views/elements/install.thtml:111
+#, fuzzy
+msgid "addons_install_in_sunbird_title"
+msgstr "How to Install in Sunbird"
+
+#: views/elements/amo2009/install.thtml:331 views/elements/install.thtml:106
+msgid "addons_install_in_thunderbird"
+msgstr ""
+"<ol><li>Egin eskuin-klika azpiko loturan eta aukeratu \"Gorde Lotura "
+"Honela...\" fitxategia deskargatu eta zure diskoan gordetzeko.</"
+"li><li>Mozilla Thunderbirden, zabaldu Gehigarriak, Tresnak menutik.</"
+"li><li>Egin klik instalatu botoian eta bilatu/aukeratu deskargatutako "
+"fitxategia eta egin klik \"Ados\" botoian.</li></ol>"
+
+#: views/elements/amo2009/install.thtml:330 views/elements/install.thtml:105
+msgid "addons_install_in_thunderbird_title"
+msgstr "Thunderbirden nola instalatu"
+
+#: views/elements/amo2009/addon_list_options.thtml:108
+#: views/elements/addon_list_options.thtml:105
+msgid "addons_options_show_experimental"
+msgstr "erakutsi probarako gehigarriak"
+
+#: views/elements/amo2009/addon_list_options.thtml:113
+#: views/elements/addon_list_options.thtml:109
+msgid "addons_options_submit"
+msgstr "Joan"
+
+#: views/addons/plugins.thtml:63 views/addons/plugins.thtml:73
+#: views/addons/plugins.thtml:83 views/addons/plugins.thtml:93
+#: views/addons/plugins.thtml:103 views/addons/plugins.thtml:116
+#: views/addons/plugins.thtml:126
+msgid "addons_plugins_by"
+msgstr "Garatzailea"
+
+#: views/addons/plugins.thtml:107
+msgid "addons_plugins_for_linux"
+msgstr "Linuxerako"
+
+#: views/addons/plugins.thtml:108 views/addons/plugins.thtml:131
+msgid "addons_plugins_for_macosx"
+msgstr "Mac OS Xrako"
+
+#: views/addons/plugins.thtml:106 views/addons/plugins.thtml:129
+#: views/addons/plugins.thtml:130
+msgid "addons_plugins_for_windows"
+msgstr "Windowserako"
+
+#. %1$s is a URL
+#: views/addons/plugins.thtml:139
+#, php-format
+msgid "addons_plugins_looking_for_more"
+msgstr ""
+"Orrialde honek plugin arrunten eta deskargatuenetako batzuk zerrendatzen "
+"ditu. Mozillan oinarritutako nabigatzaileentzat eskuragarri dauden plugin "
+"gehiagori buruzko argibideak jasotzeko jo %1$s(e)ra."
+
+#: views/addons/plugins.thtml:137
+msgid "addons_plugins_looking_for_plugin"
+msgstr "Hemen ez dagoen plugin baten bila?"
+
+#: views/addons/plugins.thtml:58
+msgid "addons_plugins_main_description"
+msgstr ""
+"Pluginek nabigatzaileari funtzio konkretuak burutzen laguntzen diote, hala "
+"nola formatu grafiko bereziak ikusten edo multimedia fitxategiak "
+"erreproduzitzen. Pluginak pittin bat ezberdinak dira hedapenekin alderatuta, "
+"azken hauek existitzen den funtzionalitatea aldatu edo honi zerbait gehitzen "
+"baitiote."
+
+#. %1$s is the application name. Example: Firefox, Thunderbird, Sunbird
+#: controllers/addons_controller.php:1122
+#, php-format
+msgid "addons_plugins_main_header"
+msgstr "%1$s(r)en plugin ohikoenak"
+
+#: controllers/components/amo.php:698 controllers/addons_controller.php:1121
+msgid "addons_plugins_pagetitle"
+msgstr "Pluginak"
+
+#: views/addons/plugins.thtml:68 views/addons/plugins.thtml:78
+#: views/addons/plugins.thtml:88 views/addons/plugins.thtml:98
+#: views/addons/plugins.thtml:110 views/addons/plugins.thtml:121
+#: views/addons/plugins.thtml:133
+msgid "addons_plugins_support_documentation"
+msgstr "Laguntza-dokumentazioa: "
+
+#. %s is the name of the add-on
+#: views/addons/policy.thtml:61
+#, php-format
+msgid "addons_policy_eula_require"
+msgstr ""
+"%s-n eskariz, instalazioa hasi aurretik beharrezkoa da jarraian dagoen azken "
+"erabiltzaile lizentziako baldintzak onartzea."
+
+# %1 is the addon name
+#. %1 is the add-on name
+#: controllers/addons_controller.php:1476
+#, php-format
+msgid "addons_previews_pagetitle"
+msgstr "%s(r)en aurrebista"
+
+#: views/addons/category_landing.thtml:135
+#, fuzzy
+msgid "addons_recently_added"
+msgstr "Recently Added"
+
+#: views/addons/recommended.thtml:51 controllers/addons_controller.php:1365
+msgid "addons_recommended_introduction"
+msgstr ""
+"Ehundaka gehigarri erabilgarrirekin guztiontzat dago zerbait. Hasteko hemen "
+"duzu gehien erabiltzen direnen zerrenda bat. Gozatu!"
+
+#: controllers/addons_controller.php:1357
+#: controllers/addons_controller.php:1364
+msgid "addons_recommended_pagetitle"
+msgstr "Gomendatutako gehigarriak"
+
+#: controllers/addons_controller.php:1360
+msgid "addons_recommended_title"
+msgstr "Gomendatutako gehigarriak"
+
+#: views/addons/searchengines.thtml:136
+msgid "addons_searchengines_additional_resources"
+msgstr "Baliabide gehigarriak"
+
+# link text devmo
+#. link text devmo
+#: views/addons/searchengines.thtml:141
+msgid "addons_searchengines_devmo_link"
+msgstr "Mozillaren garapengunea"
+
+#: views/pages/js_constants.js.thtml:67
+msgid "addons_searchengines_error_mozilla_browser_required"
+msgstr ""
+"Barkatu, Mozillan oinarritutako nabigatzaile bat behar duzu bilaketa "
+"instalatzeko."
+
+#: views/addons/searchengines.thtml:49
+msgid "addons_searchengines_error_nojavascript"
+msgstr ""
+"JavaScript beharrezkoa da pluginak instalatu ahal izateko, baina dirudienez "
+"ezgaituta daukazu. Mesedez gaitu JavaScript azpiko edozein bilaketa-motore "
+"instalatzen saiatu aurretik."
+
+# %1 is "make your own" link
+# %2 is mozdev link
+#. %1 is "make your own" link
+#. %2 is MDC link
+#: views/addons/searchengines.thtml:139
+#, fuzzy
+msgid "addons_searchengines_learn_howto"
+msgstr "Ikasi nola %1$s %2$s-(e)n."
+
+# link path to search plugins instructions, relative to devmo
+#. link path to search plugins instructions, relative to devmo
+#: views/addons/searchengines.thtml:140
+msgid "addons_searchengines_makeyourown_href"
+msgstr "/en/docs/Creating_OpenSearch_plugins_for_Firefox"
+
+# link text for "make your own" (opensearch engine)
+#. link text for "make your own" (opensearch engine)
+#: views/addons/searchengines.thtml:140
+msgid "addons_searchengines_makeyourown_link"
+msgstr "egin zuk zeuk"
+
+# %1 is the link to mycroft.mozdev.org
+#. %1 is the link to mycroft.mozdev.org
+#: views/addons/searchengines.thtml:138
+#, fuzzy
+msgid "addons_searchengines_more"
+msgstr "Arakatu bilaketa-motor gehiago %1$s(e)n"
+
+# link text to mycroft.mozdev.org
+#. link text to mycroft.mozdev.org
+#: views/addons/searchengines.thtml:138
+msgid "addons_searchengines_mycroft_link"
+msgstr "mycroft.mozdev.org"
+
+#: controllers/addons_controller.php:1100
+#: controllers/addons_controller.php:1110
+msgid "addons_searchengines_pagetitle"
+msgstr "Bilaketa-motorrak"
+
+#: views/addons/searchengines.thtml:143
+msgid "addons_searchengines_thanks"
+msgstr ""
+"Esker bereziak Mycroft Proiektuari Firefoxen Bilaketa-motorretan egindako "
+"lanagatik."
+
+#: views/addons/display.thtml:154
+#, fuzzy
+msgid "addons_share_button_text"
+msgstr "Share this"
+
+#: controllers/addons_controller.php:89
+#, fuzzy
+msgid "addons_share_label_delicious"
+msgstr "Add to Delicious"
+
+#: controllers/addons_controller.php:77
+#, fuzzy
+msgid "addons_share_label_digg"
+msgstr "Digg this!"
+
+#: controllers/addons_controller.php:83
+#, fuzzy
+msgid "addons_share_label_facebook"
+msgstr "Post to Facebook"
+
+#: controllers/addons_controller.php:101
+#, fuzzy
+msgid "addons_share_label_friendfeed"
+msgstr "Share on FriendFeed"
+
+#: controllers/addons_controller.php:95
+#, fuzzy
+msgid "addons_share_label_myspace"
+msgstr "Post to MySpace"
+
+#: controllers/components/amo.php:201 controllers/components/amo.php:229
+#, fuzzy
+msgid "addons_status_disabled"
+msgstr "Disabled"
+
+#: controllers/components/amo.php:191 controllers/components/amo.php:224
+#, fuzzy
+msgid "addons_status_incomplete"
+msgstr "Incomplete Version"
+
+#: controllers/components/amo.php:197 controllers/components/amo.php:227
+#, fuzzy
+msgid "addons_status_nominated"
+msgstr "In Sandbox; Public Nomination"
+
+#: views/pages/js_constants.js.thtml:80 controllers/components/amo.php:195
+#: controllers/components/amo.php:226
+#, fuzzy
+msgid "addons_status_pending"
+msgstr "In Sandbox; Pending Review"
+
+#: views/pages/js_constants.js.thtml:78 controllers/components/amo.php:199
+#: controllers/components/amo.php:228
+#, fuzzy
+msgid "addons_status_public"
+msgstr "Public"
+
+#: views/pages/js_constants.js.thtml:79 controllers/components/amo.php:193
+#: controllers/components/amo.php:225
+#, fuzzy
+msgid "addons_status_sandbox"
+msgstr "In Sandbox"
+
+#: controllers/components/amo.php:203
+#, fuzzy
+msgid "addons_status_unknown"
+msgstr "Unknown"
+
+#: views/elements/amo2009/teaser_collections.thtml:91
+#: views/elements/amo2009/homepage_addon.thtml:99
+#: views/elements/feature.thtml:94
+msgid "addons_title_tooltip"
+msgstr "Gehiago gehigarri honi buruz"
+
+#: views/addons/category_landing.thtml:151
+#, fuzzy
+msgid "addons_top_downloads"
+msgstr "Top Downloads"
+
+#: views/addons/category_landing.thtml:165
+#, fuzzy
+msgid "addons_top_rated"
+msgstr "Top Rated"
+
+#: views/addons/versions.thtml:62
+msgid "addons_versions_careful"
+msgstr "Kontuz ibili bertsio zaharrekin"
+
+#: views/addons/versions.thtml:63
+msgid "addons_versions_careful_introduction"
+msgstr ""
+"Bertsio hauek erreferentzia eta egiaztatze helburuetarako bistaratzen dira. "
+"Gehigarri baten azken bertsioa erabili beharko zenuke beti."
+
+#: controllers/addons_controller.php:1549
+msgid "addons_versions_history"
+msgstr "Bertsioaren historia aldaketen egunkariarekin"
+
+#. %1$s is the add-on name
+#: controllers/addons_controller.php:1535
+#, php-format
+msgid "addons_versions_pagetitle"
+msgstr "%1$s Bertsioaren historia"
+
+#: controllers/groups_controller.php:71
+msgid "admin_group_add_pagetitle"
+msgstr "Gehitu taldea"
+
+#: controllers/groups_controller.php:111
+msgid "admin_group_delete_pagetitle"
+msgstr "Ezabatu taldea"
+
+#. %s is a number to identify the group
+#: controllers/groups_controller.php:117
+#, php-format
+msgid "admin_group_deleted"
+msgstr "%s IDdun taldea ezabatu da"
+
+#: controllers/groups_controller.php:89
+msgid "admin_group_edit_pagetitle"
+msgstr "Editatu taldea"
+
+#: controllers/groups_controller.php:92 controllers/groups_controller.php:113
+msgid "admin_group_error_invalid_id"
+msgstr "Taldearentzat ID baliogabea"
+
+#: controllers/groups_controller.php:65
+msgid "admin_group_pagetitle"
+msgstr "Taldeko kudeatzailea"
+
+#: controllers/groups_controller.php:77 controllers/groups_controller.php:99
+msgid "admin_group_saved"
+msgstr "Taldea gorde da"
+
+#: views/elements/amo2009/search.thtml:257 views/elements/search.thtml:239
+msgid "advanced_search_form"
+msgstr "Aurreratua"
+
+#: views/elements/amo2009/search.thtml:126 views/elements/search.thtml:125
+msgid "advanced_search_form_any_time"
+msgstr "Edonoiz"
+
+#: views/elements/amo2009/search.thtml:97
+#: views/elements/amo2009/search.thtml:110 views/elements/search.thtml:96
+#: views/elements/search.thtml:109
+msgid "advanced_search_form_any_type"
+msgstr "Edozein"
+
+#: views/elements/amo2009/search.thtml:275 views/elements/search.thtml:254
+msgid "advanced_search_form_any_version"
+msgstr "Edozein"
+
+#: views/elements/amo2009/search.thtml:217 views/elements/search.thtml:212
+msgid "advanced_search_form_application"
+msgstr "Aplikazioa"
+
+#: views/elements/amo2009/search.thtml:143 views/elements/search.thtml:142
+msgid "advanced_search_form_keyword_match"
+msgstr "Bilatutako hitzak"
+
+#: views/elements/amo2009/search.thtml:251 views/elements/search.thtml:225
+msgid "advanced_search_form_lastupdate"
+msgstr "Azken eguneraketa"
+
+#: views/elements/amo2009/search.thtml:145 views/elements/search.thtml:144
+msgid "advanced_search_form_name"
+msgstr "Izena"
+
+#: views/elements/amo2009/search.thtml:144 views/elements/search.thtml:143
+msgid "advanced_search_form_newest"
+msgstr "Berriena"
+
+#: views/elements/amo2009/search.thtml:130 views/elements/search.thtml:129
+msgid "advanced_search_form_past_3_months"
+msgstr "Orain 3 hilabete"
+
+#: views/elements/amo2009/search.thtml:131 views/elements/search.thtml:130
+msgid "advanced_search_form_past_6_months"
+msgstr "Orain 6 hilabete"
+
+#: views/elements/amo2009/search.thtml:127 views/elements/search.thtml:126
+msgid "advanced_search_form_past_day"
+msgstr "Azken egunean"
+
+#: views/elements/amo2009/search.thtml:129 views/elements/search.thtml:128
+msgid "advanced_search_form_past_month"
+msgstr "Azken hilean"
+
+#: views/elements/amo2009/search.thtml:128 views/elements/search.thtml:127
+msgid "advanced_search_form_past_week"
+msgstr "Azken astean"
+
+#: views/elements/amo2009/search.thtml:132 views/elements/search.thtml:131
+msgid "advanced_search_form_past_year"
+msgstr "Azken urtean"
+
+#: views/elements/amo2009/search.thtml:239 views/elements/search.thtml:230
+msgid "advanced_search_form_perpage"
+msgstr "Orriko"
+
+#: views/elements/amo2009/search.thtml:243 views/elements/search.thtml:224
+msgid "advanced_search_form_platform"
+msgstr "Plataforma"
+
+#: views/elements/amo2009/search.thtml:147 views/elements/search.thtml:146
+msgid "advanced_search_form_popularity"
+msgstr "Arrakasta"
+
+#: views/elements/amo2009/search.thtml:146 views/elements/search.thtml:145
+msgid "advanced_search_form_rating"
+msgstr "Puntuaketa"
+
+#: views/elements/amo2009/search.thtml:247 views/elements/search.thtml:231
+msgid "advanced_search_form_sortby"
+msgstr "Ordena"
+
+#: views/elements/amo2009/search.thtml:227 views/elements/search.thtml:216
+msgid "advanced_search_form_to"
+msgstr "(e)tik honaino:"
+
+#: views/elements/amo2009/search.thtml:257 views/elements/search.thtml:237
+msgid "advanced_search_form_toggle_tooltip"
+msgstr "Bistaratu/ezkutatu bilaketa aurreratua"
+
+#: views/elements/amo2009/search.thtml:235 views/elements/search.thtml:223
+msgid "advanced_search_form_type"
+msgstr "Mota"
+
+#: views/elements/amo2009/search.thtml:222 views/elements/search.thtml:214
+msgid "advanced_search_form_version"
+msgstr "Bertsioa:"
+
+#: views/elements/amo2009/pagination.thtml:42
+#, fuzzy
+msgid "amo2009_pagination_next_page"
+msgstr "Next"
+
+#: views/elements/amo2009/pagination.thtml:41
+#, fuzzy
+msgid "amo2009_pagination_previous_page"
+msgstr "Prev"
+
+#: views/pages/js_constants.js.thtml:96
+msgid "app_compat_ignore_check"
+msgstr "Baztertu bertsio kontrola"
+
+#: views/pages/js_constants.js.thtml:72
+msgid "app_compat_older_firefox_only"
+msgstr "Gehigarri hau Firefoxen bertsio zaharragoetarako da"
+
+#. %1$s and %2$s are URLs
+#: views/pages/js_constants.js.thtml:74
+#, fuzzy
+msgid "app_compat_older_version_or_ignore_check"
+msgstr ""
+"You can <a href=\"%1$s\">try an older version</a> or <a href=\"#\" onclick="
+"\"%2$s\">ignore this check</a>"
+
+#. %1$s is a URL
+#: views/pages/js_constants.js.thtml:71
+msgid "app_compat_try_old_version"
+msgstr "Baliteke <a href=\"%1$s\">bertsio zaharrago bat</a>ek funtzionatzea"
+
+#. %1$s is a URL
+#. %2$s is a version number. Example: 3.1
+#: views/pages/js_constants.js.thtml:73
+#, fuzzy
+msgid "app_compat_unreleased_version"
+msgstr ""
+"This add-on requires the not-yet released <a href=\"%1$s\">Firefox %2$s</a>"
+
+#: views/pages/js_constants.js.thtml:70
+msgid "app_compat_update_firefox"
+msgstr ""
+"<a href=\"http://getfirefox.com\">Eguneratu Firefox</a> gehigarri hau "
+"erabiltzeko"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#. %3$s is a status, like Public.
+#: controllers/components/audit.php:79
+#, fuzzy
+msgid "audit_addon_status"
+msgstr "%1$s changed the status of %2$s to %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:221
+#, fuzzy
+msgid "audit_admin_default"
+msgstr "%1$s committed unknown admin action %2$s to ID %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:153
+#, fuzzy
+msgid "audit_admin_feature_remove"
+msgstr "%1$s removed feature %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is an application, like Firefox.
+#: controllers/components/audit.php:92
+#, fuzzy
+msgid "audit_application_create"
+msgstr "%1$s created application %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is an application, like Firefox.
+#: controllers/components/audit.php:95
+#, fuzzy
+msgid "audit_application_edit"
+msgstr "%1$s edited application %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a version number, like 3.5.
+#. %3$s is an application, like Firefox.
+#: controllers/components/audit.php:105
+#, fuzzy
+msgid "audit_appversion_create"
+msgstr "%1$s created version %2$s for %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a version number, like 3.5.
+#. %3$s is an application, like Firefox.
+#: controllers/components/audit.php:108
+#, fuzzy
+msgid "audit_appversion_delete"
+msgstr "%1$s deleted version %2$s for %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a config field, like "awesomeness".
+#. %3$s is a config value, like "off".
+#. %4$s is a config value, like "on".
+#: controllers/components/audit.php:210
+#, fuzzy
+msgid "audit_config"
+msgstr "%1$s changed config '%2$s' from '%3$s' to '%4$s'"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:258
+#, fuzzy
+msgid "audit_editor_default"
+msgstr "%1$s committed unknown editor action %2$s to ID %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#: controllers/components/audit.php:236
+#, fuzzy
+msgid "audit_editor_feature_remove"
+msgstr "%1$s removed addon %2$s from feature list"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#: controllers/components/audit.php:231
+#, fuzzy
+msgid "audit_feature_add"
+msgstr "%1$s added addon %2$s to feature list"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:149
+#, fuzzy
+msgid "audit_feature_edit"
+msgstr "%1$s changed a feature for %2$s locale"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#: controllers/components/audit.php:241
+#, fuzzy
+msgid "audit_feature_locale_change"
+msgstr "%1$s changed locales for addon %2$s on feature list"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:83
+#, fuzzy
+msgid "audit_file_recalchash"
+msgstr "%1$s recalculated the hash for file %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>user name</a>
+#. %3$s is <a>group name</a>
+#: controllers/components/audit.php:182
+#, fuzzy
+msgid "audit_group_addmember"
+msgstr "%1$s added %2$s to group %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:313
+#, fuzzy
+msgid "audit_group_associated"
+msgstr "%1$s associated themselves with %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:162
+#, fuzzy
+msgid "audit_group_create"
+msgstr "%1s created group %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:170
+#, fuzzy
+msgid "audit_group_delete"
+msgstr "%1$s deleted group %2$s (ID %3$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:165
+#, fuzzy
+msgid "audit_group_edit"
+msgstr "%1$s edited group %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>user name</a>
+#. %3$s is <a>group name</a>
+#: controllers/components/audit.php:188
+#, fuzzy
+msgid "audit_group_removemember"
+msgstr "%1$s removed %2$s from group %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:280
+#, fuzzy
+msgid "audit_l10n_default"
+msgstr "%1$s committed unknown action %2$s for %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:295
+#, fuzzy
+msgid "audit_modify_locked_group"
+msgstr "%1$s attempted to modify locked group %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:299
+#, fuzzy
+msgid "audit_modify_other_locale"
+msgstr "%1$s attempted to modify translations in %2$s without permission"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a platform, like <a>Windows</a>
+#: controllers/components/audit.php:135
+#, fuzzy
+msgid "audit_platform_create"
+msgstr "%1$s created platform %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a platform, like <a>Windows</a>
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:143
+#, fuzzy
+msgid "audit_platform_delete"
+msgstr "%1$s deleted platform %2$s (ID %3$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a platform, like <a>Windows</a>
+#: controllers/components/audit.php:138
+#, fuzzy
+msgid "audit_platform_edit"
+msgstr "%1$s edited platform %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a part of the admin, like 'Site Config'
+#: controllers/components/audit.php:288
+#, fuzzy
+msgid "audit_reauthentication_failure"
+msgstr "%1$s failed to re-authenticate to access %2$s."
+
+#. %1$s is <a>user name</a>
+#. %2$s is the name of a canned response, like 'Ready for the public'
+#: controllers/components/audit.php:198
+#, fuzzy
+msgid "audit_response_create"
+msgstr "%1$s created response %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is the name of a canned response, like 'Ready for the public'
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:206
+#, fuzzy
+msgid "audit_response_delete"
+msgstr "%1$s deleted response %2$s (ID %3$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is the name of a canned response, like 'Ready for the public'
+#: controllers/components/audit.php:201
+#, fuzzy
+msgid "audit_response_edit"
+msgstr "%1$s edited response %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:245
+#, fuzzy
+msgid "audit_review_approve"
+msgstr "%1$s approved review %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:250 controllers/components/audit.php:253
+#, fuzzy
+msgid "audit_review_delete"
+msgstr "%1$s deleted review %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:303
+#, fuzzy
+msgid "audit_security_default"
+msgstr "%1$s committed unknown security action %2$s to ID %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a category name, like <a>Search Tools</a>
+#: controllers/components/audit.php:118
+#, fuzzy
+msgid "audit_tag_create"
+msgstr "%1$s created tag %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a category name, like <a>Search Tools</a>
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:126
+#, fuzzy
+msgid "audit_tag_delete"
+msgstr "%1$s deleted category %2$s (ID %3$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a category name, like <a>Search Tools</a>
+#: controllers/components/audit.php:121
+#, fuzzy
+msgid "audit_tag_edit"
+msgstr "%1$s edited category %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:266
+#, fuzzy
+msgid "audit_update_applications"
+msgstr "%1$s updated application translations for %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:277
+#, fuzzy
+msgid "audit_update_blog"
+msgstr "%1$s updated blog post translations for %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:274
+#, fuzzy
+msgid "audit_update_platforms"
+msgstr "%1$s updated platform translations for %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:270
+#, fuzzy
+msgid "audit_update_tags"
+msgstr "%1$s updated category translations for %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>user name</a>
+#: controllers/components/audit.php:217
+#, fuzzy
+msgid "audit_user_edit"
+msgstr "%1$s edited %2$s's user information"
+
+#: controllers/addons_controller.php:1012
+#, fuzzy
+msgid "browse_addons_name"
+msgstr "Add-ons by Name"
+
+#: controllers/addons_controller.php:1010
+#, fuzzy
+msgid "browse_addons_newest"
+msgstr "Newest Add-ons"
+
+#: controllers/addons_controller.php:1008
+#, fuzzy
+msgid "browse_addons_popular"
+msgstr "Popular Add-ons"
+
+#: controllers/addons_controller.php:1011
+#, fuzzy
+msgid "browse_addons_rated"
+msgstr "Add-ons by Rating"
+
+#: controllers/addons_controller.php:1009
+#, fuzzy
+msgid "browse_addons_updated"
+msgstr "Recently Updated Add-ons"
+
+#: views/elements/categories.thtml:73 views/elements/categories.thtml:82
+msgid "categories_current_title"
+msgstr "Uneko kategoria"
+
+#: views/elements/categories.thtml:50
+#: views/elements/amo2009/categories.thtml:43
+#: views/elements/amo2009/categories.thtml:45
+msgid "categories_header"
+msgstr "Kategoriak"
+
+#: views/elements/categories.thtml:50
+#: views/elements/amo2009/categories.thtml:41
+msgid "categories_header_title"
+msgstr "Hautatu kategoria bat"
+
+# %1 is the category name
+#. %1$s is the category name
+#: views/addons/searchengines.thtml:129
+#, php-format
+msgid "category_extra_see_all"
+msgstr "Ikusi %1$s guztiak"
+
+#. %1$s is a number.
+#: models/collection.php:130
+#, fuzzy
+msgid "collection_description_limit"
+msgstr "The description should be less than %1$s characters."
+
+#. %1$s is the name of the collection
+#: controllers/collections_controller.php:392
+#, fuzzy
+msgid "collection_detail_rss_title"
+msgstr "%s Collection"
+
+#: controllers/collections_controller.php:1065
+#, fuzzy
+msgid "collection_error_deleting_addon"
+msgstr "Error deleting add-on!"
+
+#: controllers/collections_controller.php:1051
+#, fuzzy
+msgid "collection_error_saving_addon"
+msgstr "Error saving add-on!"
+
+#: controllers/collections_controller.php:1080
+#, fuzzy
+msgid "collection_error_saving_comment"
+msgstr "Error saving comment!"
+
+#. %1$s is a number.
+#: models/collection.php:122
+#, fuzzy
+msgid "collection_name_limit"
+msgstr "The name should be less than %1$s characters."
+
+#: controllers/collections_controller.php:352
+#: controllers/collections_controller.php:487
+#, fuzzy
+msgid "collection_not_found"
+msgstr "Collection not found!"
+
+#. %1$s is the text on the "create collection" button
+#: views/collections/add.thtml:91
+#, fuzzy
+msgid "collections_add_formfield_addons_description"
+msgstr ""
+"If you already know which add-ons you want to add to your collection, just "
+"start typing their names below. If you'd rather wait and do this later, just "
+"click %1$s now."
+
+#: views/collections/add.thtml:90
+#, fuzzy
+msgid "collections_add_formfield_firstaddons"
+msgstr "Choose your first add-ons"
+
+#: views/collections/add.thtml:48
+#, fuzzy
+msgid "collections_add_header"
+msgstr "Create a Collection"
+
+#: views/collections/add.thtml:97
+#, fuzzy
+msgid "collections_add_header_selectedaddons"
+msgstr "Selected Add-ons"
+
+#: views/collections/add.thtml:50
+#, fuzzy
+msgid "collections_add_intro"
+msgstr ""
+"It's easy to create your own collection of add-ons by filling in a few "
+"fields below."
+
+#: views/collections/add.thtml:92 views/collections/add.thtml:103
+#, fuzzy
+msgid "collections_add_submit"
+msgstr "Create Collection"
+
+#: views/pages/collector_faq.thtml:50 views/pages/collector_firstrun.thtml:43
+#: views/pages/collector.thtml:47 views/pages/collector_features.thtml:55
+#: controllers/search_controller.php:302
+#: controllers/collections_controller.php:206
+#: controllers/collections_controller.php:405
+#: controllers/collections_controller.php:467
+#: controllers/collections_controller.php:539
+#, fuzzy
+msgid "collections_breadcrumb"
+msgstr "Collections"
+
+#: views/collections/detail.thtml:185
+#, fuzzy
+msgid "collections_detail_a_learn"
+msgstr "Learn More"
+
+#: views/elements/amo2009/collection_add_form.thtml:53
+#: views/elements/amo2009/collections_js_init.thtml:68
+#: views/pages/collector_firstrun.thtml:64
+#, fuzzy
+msgid "collections_detail_button_add"
+msgstr "Add to Favorites"
+
+#: views/elements/amo2009/collection_add_form.thtml:50
+#: views/elements/amo2009/collections_js_init.thtml:71
+#, fuzzy
+msgid "collections_detail_button_remove"
+msgstr "Remove from Favorites"
+
+#. %1$s is a URL.
+#. %2$s is a full <a href>.
+#: views/collections/detail.thtml:62
+#, fuzzy
+msgid "collections_detail_created_desc"
+msgstr ""
+"<p>You can view your new collection below. If you'd like to set a collection "
+"nickname, upload an icon, or change additional settings, please visit the <a "
+"href='%1$s'>Manage Collections</a> page.</p><p>Your collection can be "
+"accessed at this location: %2$s</p>"
+
+#: views/collections/detail.thtml:61
+#, fuzzy
+msgid "collections_detail_created_msg"
+msgstr "Your collection is now ready!"
+
+#: views/collections/detail.thtml:109
+#, fuzzy
+msgid "collections_detail_header_about"
+msgstr "About This Collection"
+
+#. %1$s is a number.
+#: views/collections/detail.thtml:126
+#, fuzzy
+msgid "collections_detail_header_count"
+msgid_plural "collections_detail_header_count"
+msgstr[0] "%1$s Add-on in this Collection"
+msgstr[1] "%1$s Add-ons in this Collection"
+
+#: views/collections/detail.thtml:113
+#, fuzzy
+msgid "collections_detail_info_created"
+msgstr "<strong>Created by:</strong> %1$s"
+
+#: views/collections/detail.thtml:117
+#, fuzzy
+msgid "collections_detail_info_updated"
+msgstr "<strong>Updated:</strong>"
+
+#: views/elements/amo2009/collections_js_init.thtml:62
+#, fuzzy
+msgid "collections_detail_js_adding"
+msgstr "Adding to Favorites&hellip;"
+
+#: views/elements/amo2009/collections_js_init.thtml:65
+#, fuzzy
+msgid "collections_detail_js_removing"
+msgstr "Removing Favorite&hellip;"
+
+#. %1$s is a URL
+#: views/collections/detail.thtml:90
+#, fuzzy
+msgid "collections_detail_login"
+msgstr "<a href=\"%1$s\">Log in</a> to add this collection to your favorites."
+
+#: views/collections/detail.thtml:104
+#, fuzzy
+msgid "collections_detail_manage"
+msgstr "Manage Collection"
+
+#: controllers/collections_controller.php:298
+#, fuzzy
+msgid "collections_detail_sort_date"
+msgstr "Date Added"
+
+#: controllers/collections_controller.php:299
+#, fuzzy
+msgid "collections_detail_sort_name"
+msgstr "Name"
+
+#: controllers/collections_controller.php:300
+#, fuzzy
+msgid "collections_detail_sort_popularity"
+msgstr "Popularity"
+
+#. %1$s is a number.
+#: views/collections/detail.thtml:166
+#, fuzzy
+msgid "collections_detail_weekly_downloads"
+msgid_plural "collections_detail_weekly_downloads"
+msgstr[0] "%1$s download this week"
+msgstr[1] "%1$s downloads this week"
+
+#: views/collections/edit.thtml:255
+#, fuzzy
+msgid "collections_edit_addons_delete_noscript"
+msgstr "Selected add-ons will be removed upon Save"
+
+#: views/collections/edit.thtml:247
+#, fuzzy
+msgid "collections_edit_addons_description"
+msgstr ""
+"To publish new add-ons to this collection, start typing their names below."
+
+#: views/collections/edit.thtml:248
+#, fuzzy
+msgid "collections_edit_addons_description_noscript"
+msgstr ""
+"To publish new add-ons to this collection, enter a comma-separated list of "
+"Add-on IDs below."
+
+#: views/collections/edit.thtml:247 views/collections/edit.thtml:248
+#, fuzzy
+msgid "collections_edit_addons_description_publish_detailspage"
+msgstr "You can also publish an add-on from its normal listing page."
+
+#. %1$s is the date the add-on was added to the collection
+#. %1$s is the name of the user who added the add-on to the collection
+#: views/collections/edit.thtml:260
+#, fuzzy
+msgid "collections_edit_addons_listitem_added"
+msgstr "Added %1$s by %2$s"
+
+#: views/collections/edit.thtml:263
+#, fuzzy
+msgid "collections_edit_addons_listitem_comment_add"
+msgstr "Add publisher comment"
+
+#: views/collections/edit.thtml:266
+#, fuzzy
+msgid "collections_edit_addons_listitem_comment_delete"
+msgstr "Delete publisher comment"
+
+#: views/collections/edit.thtml:265
+#, fuzzy
+msgid "collections_edit_addons_listitem_comment_edit"
+msgstr "Edit publisher comment"
+
+#: views/collections/edit.thtml:271
+#, fuzzy
+msgid "collections_edit_addons_listitem_comment_note"
+msgstr ""
+"Note: Comment will appear as though written by original publisher on the "
+"original publication date"
+
+#: views/collections/edit.thtml:270
+#, fuzzy
+msgid "collections_edit_addons_listitem_comment_submit"
+msgstr "Save Comment"
+
+#: views/collections/edit.thtml:261
+#, fuzzy
+msgid "collections_edit_addons_listitem_remove"
+msgstr "Remove"
+
+#: views/collections/edit.thtml:250
+#, fuzzy
+msgid "collections_edit_addons_submit"
+msgstr "Add to Collection"
+
+#: views/collections/edit.thtml:153
+#, fuzzy
+msgid "collections_edit_check_nickname"
+msgstr "Check Availability"
+
+#: views/collections/edit.thtml:299
+#, fuzzy
+msgid "collections_edit_confirm_deletecollection"
+msgstr "Yes, I would like to delete this collection."
+
+#. %1$s is the label of the edit form's submit button
+#: views/collections/edit.thtml:300
+#, fuzzy
+msgid "collections_edit_confirm_deletecollection_description"
+msgstr "Check the box, then click on \"%1$s\" to delete this collection."
+
+#. %1$s is the "delete" submit button text
+#. %2$s is the title of the "advanced" tab
+#: views/collections/edit.thtml:95
+#, fuzzy
+msgid "collections_edit_delete_upon_submit"
+msgstr ""
+"Upon clicking \"%1$s\" below, your collection will be deleted. If you do not "
+"want to delete your collection, uncheck the confirmation box in the \"%2$s\" "
+"tab and continue editing your collection. If you leave this page without "
+"saving, your collection will also not be deleted."
+
+#: views/collections/edit.thtml:94
+#, fuzzy
+msgid "collections_edit_delete_warning"
+msgstr "Your collection is about to be deleted!"
+
+#: views/collections/add.thtml:76 views/collections/edit.thtml:144
+#, fuzzy
+msgid "collections_edit_form_error_description"
+msgstr "You must provide a description of your collection."
+
+#: views/collections/edit.thtml:181
+#, fuzzy
+msgid "collections_edit_form_error_icon"
+msgstr "There was an error uploading your icon."
+
+#: views/collections/add.thtml:69 views/collections/edit.thtml:130
+#, fuzzy
+msgid "collections_edit_form_error_name"
+msgstr "You must give your collection a name."
+
+#: views/collections/edit.thtml:158
+#, fuzzy
+msgid "collections_edit_form_error_nickname"
+msgstr "If you choose a nickname, it must be unique."
+
+#: views/collections/add.thtml:93 views/collections/edit.thtml:249
+#, fuzzy
+msgid "collections_edit_formfield_addons"
+msgstr "Add-on name:"
+
+#: views/collections/edit.thtml:281
+#, fuzzy
+msgid "collections_edit_formfield_application"
+msgstr "Associated Application"
+
+#: views/collections/edit.thtml:282
+#, fuzzy
+msgid "collections_edit_formfield_application_description"
+msgstr "Select the application that your collection supports."
+
+#: views/collections/edit.thtml:288
+#, fuzzy
+msgid "collections_edit_formfield_collectiontype"
+msgstr "Collection Type"
+
+#: views/collections/edit.thtml:295
+#, fuzzy
+msgid "collections_edit_formfield_deletecollection"
+msgstr "Delete Collection"
+
+#: views/collections/edit.thtml:296
+#, fuzzy
+msgid "collections_edit_formfield_deletecollection_description"
+msgstr "Deleting your collection will permanently erase it."
+
+#: views/collections/add.thtml:73 views/collections/edit.thtml:140
+#, fuzzy
+msgid "collections_edit_formfield_description"
+msgstr "Collection Description"
+
+#: views/collections/add.thtml:74 views/collections/edit.thtml:141
+#, fuzzy
+msgid "collections_edit_formfield_description_description"
+msgstr "Briefly describe your collection and the kind of add-ons in it"
+
+#: views/collections/edit.thtml:162
+#, fuzzy
+msgid "collections_edit_formfield_icon"
+msgstr "Icon"
+
+#: views/collections/edit.thtml:163
+#, fuzzy
+msgid "collections_edit_formfield_icon_description"
+msgstr ""
+"You can upload a JPG, GIF or PNG icon that will be resized to 32x32 pixels."
+
+#: views/collections/add.thtml:80 views/collections/edit.thtml:189
+#, fuzzy
+msgid "collections_edit_formfield_listed"
+msgstr "Who can view your collection?"
+
+#: views/collections/add.thtml:81 views/collections/edit.thtml:190
+#, fuzzy
+msgid "collections_edit_formfield_listed_description"
+msgstr ""
+"By default, collections appear in the public Collection Directory and are "
+"discoverable by anyone. If you want to restrict your collection to be "
+"viewable only by people who are given a special link, choose that option "
+"below."
+
+#: views/collections/add.thtml:84 views/collections/edit.thtml:193
+#, fuzzy
+msgid "collections_edit_formfield_listed_false"
+msgstr "Only people I invite can view my collection"
+
+#: views/collections/add.thtml:83 views/collections/edit.thtml:192
+#, fuzzy
+msgid "collections_edit_formfield_listed_true"
+msgstr "Everyone can view my collection in the directory"
+
+#: views/collections/edit.thtml:223
+#, fuzzy
+msgid "collections_edit_formfield_managers"
+msgstr "Who can manage my collection?"
+
+#: views/collections/edit.thtml:224
+#, fuzzy
+msgid "collections_edit_formfield_managers_description"
+msgstr ""
+"These users can publish add-ons to your collection, manage all add-ons and "
+"settings, and grant other users permission."
+
+#: views/collections/add.thtml:66 views/collections/edit.thtml:126
+#, fuzzy
+msgid "collections_edit_formfield_name"
+msgstr "Collection Name"
+
+#: views/collections/add.thtml:67 views/collections/edit.thtml:127
+#, fuzzy
+msgid "collections_edit_formfield_name_description"
+msgstr ""
+"Give your collection a descriptive name, such as \"Dave's Favorite Travel "
+"Add-ons\""
+
+#: views/collections/edit.thtml:148
+#, fuzzy
+msgid "collections_edit_formfield_nickname"
+msgstr "Collection Nickname"
+
+#: views/collections/edit.thtml:149
+#, fuzzy
+msgid "collections_edit_formfield_nickname_description"
+msgstr "Optionally, give your collection a unique nickname for quick access:"
+
+#: views/collections/edit.thtml:201
+#, fuzzy
+msgid "collections_edit_formfield_publishers"
+msgstr "Who can publish add-ons to your collection?"
+
+#: views/collections/edit.thtml:202
+#, fuzzy
+msgid "collections_edit_formfield_publishers_description"
+msgstr ""
+"These users can publish add-ons to your collection and remove add-ons that "
+"they publish."
+
+#: views/collections/edit.thtml:210 views/collections/edit.thtml:232
+#, fuzzy
+msgid "collections_edit_formfield_users_add"
+msgstr "Enter the e-mail address of a Firefox Add-ons account:"
+
+#: views/collections/edit.thtml:216 views/collections/edit.thtml:238
+#, fuzzy
+msgid "collections_edit_formfield_users_delete_noscript"
+msgstr "Selected accounts will be removed upon Save"
+
+#: views/collections/edit.thtml:215 views/collections/edit.thtml:237
+#, fuzzy
+msgid "collections_edit_formfield_users_new_noscript"
+msgstr ""
+"Enter a comma-separated list of e-mail addresses of Firefox Add-ons accounts"
+
+#: views/collections/edit.thtml:204 views/collections/edit.thtml:226
+#, fuzzy
+msgid "collections_edit_formfield_users_onlyme"
+msgstr "Only me"
+
+#: views/collections/edit.thtml:205 views/collections/edit.thtml:227
+#, fuzzy
+msgid "collections_edit_formfield_users_otherusers"
+msgstr "Myself and these users:"
+
+#: views/collections/edit.thtml:211 views/collections/edit.thtml:233
+#, fuzzy
+msgid "collections_edit_formfield_users_submit"
+msgstr "Add"
+
+#. %1$s is the name of the collection
+#: views/collections/edit.thtml:68
+#, fuzzy
+msgid "collections_edit_header"
+msgstr "Manage %1$s"
+
+#: views/collections/edit.thtml:246
+#, fuzzy
+msgid "collections_edit_header_addons"
+msgstr "Manage Collection Contents"
+
+#: views/collections/edit.thtml:253 views/collections/edit.thtml:258
+#, fuzzy
+msgid "collections_edit_header_addons_current"
+msgstr "Current Add-ons:"
+
+#: views/collections/edit.thtml:279
+#, fuzzy
+msgid "collections_edit_header_advanced"
+msgstr "Advanced Settings"
+
+#: views/collections/edit.thtml:186
+#, fuzzy
+msgid "collections_edit_header_permissions"
+msgstr "Manage Collection Permissions"
+
+#: views/collections/edit.thtml:170
+#, fuzzy
+msgid "collections_edit_icon_cancel"
+msgstr "Cancel"
+
+#: views/collections/edit.thtml:174 views/collections/edit.thtml:179
+#, fuzzy
+msgid "collections_edit_icon_delete"
+msgstr "Delete Icon"
+
+#: views/collections/edit.thtml:178
+#, fuzzy
+msgid "collections_edit_icon_replace"
+msgstr "Replace Icon"
+
+#. %1$s is the label of the edit form's submit button
+#: views/collections/edit.thtml:169
+#, fuzzy
+msgid "collections_edit_icon_toberemoved"
+msgstr "Icon will be removed when \"%1$s\" is clicked below"
+
+#: views/collections/edit.thtml:155
+#, fuzzy
+msgid "collections_edit_nickname_available"
+msgstr "Nickname Available"
+
+#: controllers/collections_controller.php:943
+#, fuzzy
+msgid "collections_edit_nickname_error"
+msgstr ""
+"Your nickname contained invalid characters and was corrected. Please try "
+"again."
+
+#: views/collections/edit.thtml:156
+#, fuzzy
+msgid "collections_edit_nickname_taken"
+msgstr "Nickname Taken"
+
+#. This string is followed by a URL pointing to the collection's view page
+#: views/collections/edit.thtml:75
+#, fuzzy
+msgid "collections_edit_saved_nextstep"
+msgstr "Your collection can be accessed at this location:"
+
+#: views/collections/edit.thtml:74
+#, fuzzy
+msgid "collections_edit_saved_success"
+msgstr "Your collection was successfully saved!"
+
+#: views/collections/edit.thtml:169 views/collections/edit.thtml:300
+#: views/collections/edit.thtml:308 views/pages/js_constants.js.thtml:99
+#, fuzzy
+msgid "collections_edit_submit"
+msgstr "Update Collection"
+
+#: views/collections/edit.thtml:96 views/collections/edit.thtml:297
+#: views/pages/js_constants.js.thtml:100
+#, fuzzy
+msgid "collections_edit_submit_deletecollection"
+msgstr "Delete Collection"
+
+#: views/collections/edit.thtml:111
+#, fuzzy
+msgid "collections_edit_tabheader_addons"
+msgstr "Add-ons"
+
+#: views/collections/edit.thtml:97 views/collections/edit.thtml:113
+#, fuzzy
+msgid "collections_edit_tabheader_advanced"
+msgstr "Advanced"
+
+#: views/collections/edit.thtml:108
+#, fuzzy
+msgid "collections_edit_tabheader_details"
+msgstr "Name &amp; Details"
+
+#: views/collections/edit.thtml:109
+#, fuzzy
+msgid "collections_edit_tabheader_permissions"
+msgstr "Permissions"
+
+#: models/collection_promo.php:53
+#, fuzzy
+msgid "collections_family_tagline"
+msgstr "Add-ons can keep an eye on your kids and your calendar."
+
+#: models/collection_promo.php:53
+#, fuzzy
+msgid "collections_family_title"
+msgstr "Family Organizer"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:70
+#, fuzzy
+msgid "collections_index_a_check_out"
+msgstr "Check out Add-on Collector"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:52
+#, fuzzy
+msgid "collections_index_a_create"
+msgstr "Create a Collection"
+
+#: views/collections/detail.thtml:139 views/collections/listing.thtml:85
+#: views/search/collections.thtml:84
+#, fuzzy
+msgid "collections_index_button_go"
+msgstr "Go"
+
+#. %1$s is a URL.
+#: controllers/collections_controller.php:182
+#, fuzzy
+msgid "collections_index_filler_favorites"
+msgstr ""
+"<p><strong>You don't have any favorite collections yet.</strong></p> "
+"<p>Collections you mark as favorites can be quickly accessed from this page, "
+"and will appear in the <a href='%1$s'>Add-on Collector</a> if you've "
+"installed it.</p>"
+
+#. %1$s is a URL.
+#: controllers/collections_controller.php:167
+#, fuzzy
+msgid "collections_index_filler_mine"
+msgstr ""
+"<p>You haven't created any collections yet. Collections are easy to create "
+"and fill with your favorite add-ons. <a href='%1$s'>Try it out</a>!</p>"
+
+#: views/collections/listing.thtml:51
+#, fuzzy
+msgid "collections_index_header_collections"
+msgstr "Collections"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:60
+#, fuzzy
+msgid "collections_index_header_collector"
+msgstr "Add-on Collector"
+
+#. %1$s is a comma-separated list of author names
+#: views/elements/amo2009/collection_listing_item.thtml:84
+#: views/collections/detail.thtml:151
+#, fuzzy
+msgid "collections_index_header_created"
+msgstr "created by %1$s"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:47
+#, fuzzy
+msgid "collections_index_header_what"
+msgstr "What are Collections?"
+
+#: views/collections/detail.thtml:132 views/collections/listing.thtml:78
+#: views/search/collections.thtml:66
+#, fuzzy
+msgid "collections_index_label_sortby"
+msgstr "Sort by"
+
+#: controllers/collections_controller.php:130
+#, fuzzy
+msgid "collections_index_li_editors"
+msgstr "Editor's Picks"
+
+#: views/collections/subscribe.thtml:64
+#: controllers/collections_controller.php:140
+#, fuzzy
+msgid "collections_index_li_favorites"
+msgstr "My Favorites"
+
+#: controllers/collections_controller.php:138
+#, fuzzy
+msgid "collections_index_li_mine"
+msgstr "My Collections"
+
+#: controllers/collections_controller.php:132
+#, fuzzy
+msgid "collections_index_li_popular"
+msgstr "Popular"
+
+#: views/search/collections.thtml:74 controllers/collections_controller.php:81
+#, fuzzy
+msgid "collections_index_option_all"
+msgstr "Most popular all time"
+
+#: views/search/collections.thtml:72 controllers/collections_controller.php:78
+#, fuzzy
+msgid "collections_index_option_month"
+msgstr "Most popular this month"
+
+#: views/search/collections.thtml:76 controllers/collections_controller.php:84
+#, fuzzy
+msgid "collections_index_option_newest"
+msgstr "Newest"
+
+#: views/search/collections.thtml:70 controllers/collections_controller.php:75
+#, fuzzy
+msgid "collections_index_option_week"
+msgstr "Most popular this week"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:67
+#, fuzzy
+msgid "collections_index_p_collector"
+msgstr ""
+"There's a new way to manage and find favorite add-ons. Comment, share and "
+"sync collections, all from your browser"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:48
+#, fuzzy
+msgid "collections_index_p_what_are"
+msgstr "Collections are groups of related add-ons assembled for easy sharing."
+
+#. %s is a date in the _('date') format
+#: views/elements/collections_interactive_addon.thtml:85
+#, fuzzy, php-format
+msgid "collections_interactive_addon_added"
+msgstr "Added %s"
+
+#: models/collection_promo.php:55
+#, fuzzy
+msgid "collections_reference_tagline"
+msgstr "Add-ons can do better research online."
+
+#: models/collection_promo.php:55
+#, fuzzy
+msgid "collections_reference_title"
+msgstr "Reference Desk"
+
+#: models/collection_promo.php:52
+#, fuzzy
+msgid "collections_social_tagline"
+msgstr "Add-ons can manage your social network."
+
+#: models/collection_promo.php:52
+#, fuzzy
+msgid "collections_social_title"
+msgstr "Social Circuit"
+
+#: views/collections/subscribe.thtml:91
+#, fuzzy
+msgid "collections_subscribe_button_close"
+msgstr "Close"
+
+#: views/collections/subscribe.thtml:70
+#, fuzzy
+msgid "collections_subscribe_error"
+msgstr ""
+"An error occurred trying to add a favorite collection. Is this collection "
+"already a favorite?"
+
+#: views/collections/subscribe.thtml:96
+#, fuzzy
+msgid "collections_subscribe_label_bothersome"
+msgstr "Don't show me this message again."
+
+#. %1$s is the collection name
+#: views/collections/subscribe.thtml:60
+#, fuzzy
+msgid "collections_subscribe_success"
+msgstr "%1$s has been added to your favorite collections."
+
+#. %1$s is the link to the "My Favorites" tab on the main collections page
+#. %2$s is the localized title of the "My Favorites" tab
+#. %3$s is the link URL to the collector add-on
+#: views/collections/subscribe.thtml:62
+#, fuzzy
+msgid "collections_subscribe_success_desc"
+msgstr ""
+"You can now quickly find this collection from the <a href=\"%1$s\">%2$s</a> "
+"tab in the directory. For an even easier way to keep track of your favorite "
+"collections, try out our <a href=\"%3$s\">Add-on Collector</a> extension for "
+"Firefox."
+
+#: views/collections/listing.thtml:55
+#, fuzzy
+msgid "collections_success_delete"
+msgstr "The collection has been deleted."
+
+#: models/collection_promo.php:54
+#, fuzzy
+msgid "collections_travel_tagline"
+msgstr "Add-ons can turn you into a travel agent."
+
+#: models/collection_promo.php:54
+#, fuzzy
+msgid "collections_travel_title"
+msgstr "The Traveler's Pack"
+
+#. A collection of add-ons that is automatically built for a user. They are "automatically published" to this collection.
+#: controllers/collections_controller.php:581
+#, fuzzy
+msgid "collections_type_autopublisher"
+msgstr "Auto-publisher"
+
+#. A collection that has been chosen by an Editor as notable or exceptional
+#: controllers/collections_controller.php:582
+#, fuzzy
+msgid "collections_type_editorspick"
+msgstr "Editor's Pick"
+
+#: controllers/collections_controller.php:580
+#, fuzzy
+msgid "collections_type_normal"
+msgstr "Normal"
+
+#: views/collections/subscribe.thtml:84
+#, fuzzy
+msgid "collections_unsubscribe_error"
+msgstr ""
+"An error occurred trying to remove a favorite collection. Was this "
+"collection not a favorite?"
+
+#. %1$s is the collection name
+#: views/collections/subscribe.thtml:78
+#, fuzzy
+msgid "collections_unsubscribe_success"
+msgstr "%1$s has been removed from your favorite collections."
+
+#: models/collection_promo.php:56
+#, fuzzy
+msgid "collections_webdev_tagline"
+msgstr "Add-ons make it easier to build the perfect website."
+
+#: models/collection_promo.php:56
+#, fuzzy
+msgid "collections_webdev_title"
+msgstr "Web Developer's Toolbox"
+
+#: views/elements/amo2009/collections_sidebar_whatare.thtml:40
+#, fuzzy
+msgid "collections_whatare_header"
+msgstr "What are Collections?"
+
+#: views/elements/amo2009/collections_sidebar_whatare.thtml:45
+#, fuzzy
+msgid "collections_whatare_learnmore"
+msgstr "Read the FAQ"
+
+#: views/elements/amo2009/collections_sidebar_whatare.thtml:44
+#, fuzzy
+msgid "collections_whatare_text"
+msgstr ""
+"There’s a new way to manage and find favorite add-ons. Comment, share and "
+"sync collections, all from your browser."
+
+#: views/pages/collector_faq.thtml:61 views/pages/collector_features.thtml:67
+#, fuzzy
+msgid "collector_features_a_home"
+msgstr "Add-on Collector Home"
+
+#: views/elements/amo2009/collector_sidebar_download.thtml:46
+#, fuzzy
+msgid "collector_features_heading_download"
+msgstr "Download the Add-on Collector:"
+
+#: views/elements/amo2009/collector_sidebar_download.thtml:43
+#: views/pages/collector_firstrun.thtml:116 views/pages/collector.thtml:69
+#, fuzzy
+msgid "collector_features_img_logo"
+msgstr "Add-on Collector Logo"
+
+#: views/compatibility/dashboard.thtml:49
+#: controllers/compatibility_controller.php:72
+#, fuzzy
+msgid "compatibility_dashboard_center_header"
+msgstr "Add-on Compatibility Center"
+
+#. %1$s is the name of an application and a version. Example: Firefox 3.0
+#. %2$s is the name of an application. Example: Firefox
+#: views/compatibility/dashboard.thtml:50
+#, fuzzy
+msgid "compatibility_dashboard_intro"
+msgstr ""
+"Be prepared for the release of %1$s with the tools and information available "
+"for the %2$s Add-ons community found below."
+
+#: views/compatibility/dashboard.thtml:103
+#, fuzzy
+msgid "compatibility_dashboard_loading"
+msgstr "Loading data..."
+
+#: views/compatibility/dashboard.thtml:45
+#, fuzzy
+msgid "compatibility_dashboard_main_link"
+msgstr "Back to Main"
+
+#: views/compatibility/dashboard.thtml:100 views/compatibility/report.thtml:43
+#, fuzzy
+msgid "compatibility_dashboard_report"
+msgstr "Add-on Compatibility Report"
+
+#: views/compatibility/dashboard.thtml:53
+#: views/compatibility/dashboard.thtml:110
+#: views/compatibility/developers.thtml:43
+#, fuzzy
+msgid "compatibility_developer_info"
+msgstr "Information for Add-on Developers"
+
+#: views/compatibility/developers.thtml:66
+#, fuzzy
+msgid "compatibility_developers_adjust_maxversion"
+msgstr "Adjust maxVersion without uploading"
+
+#: views/compatibility/dashboard.thtml:124
+#, fuzzy
+msgid "compatibility_developers_check_status"
+msgstr "Check Status of My Add-ons"
+
+#. %1$s is a URL
+#. %2$s is an application and version. Example: Firefox 3.0
+#: views/compatibility/dashboard.thtml:126
+#, fuzzy
+msgid "compatibility_developers_login_first"
+msgstr ""
+"If you have add-ons hosted on Mozilla Add-ons, <a href=\"%1$s\">please "
+"login</a> to analyze the status of your add-ons for %2$s."
+
+#: views/compatibility/dashboard.thtml:114
+#, fuzzy
+msgid "compatibility_developers_mdclogo_alt"
+msgstr "Mozilla Developer Center Logo"
+
+#: views/compatibility/developers.thtml:73
+#, fuzzy
+msgid "compatibility_developers_no_addons"
+msgstr "You do not have any add-ons hosted on Mozilla Add-ons."
+
+#: views/compatibility/dashboard.thtml:133
+#: views/compatibility/developers.thtml:55
+#, fuzzy
+msgid "compatibility_developers_results"
+msgstr "Add-on Status Check Results"
+
+#: views/compatibility/dashboard.thtml:137
+#, fuzzy
+msgid "compatibility_developers_retrieving"
+msgstr "Retrieving status of hosted add-ons..."
+
+#. %1$s is a number
+#. %2$s is an application name
+#. %3$s is a number.
+#. Full example: 50 Firefox users (10% of total)
+#: views/compatibility/developers.thtml:65
+#, fuzzy
+msgid "compatibility_developers_user_count"
+msgstr "%1$s %2$s users (%3$s&#37; of total)"
+
+#: views/compatibility/report.thtml:45
+#, fuzzy
+msgid "compatibility_report_detail_intro"
+msgstr ""
+"The add-ons below make up 95% of add-on usage known to Mozilla and are "
+"ordered by their usage size."
+
+#: views/compatibility/dashboard.thtml:94
+#, fuzzy
+msgid "compatibility_report_detailed_link"
+msgstr "View Detailed Report"
+
+#. %1$s and %2$s are numbers
+#. %3$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:65
+#, fuzzy
+msgid "compatibility_report_intro"
+msgstr ""
+"Of the %1$s add-ons that make up 95&#37; of add-on usage known to Mozilla, "
+"<b>%2$s&#37;</b> are currently considered compatible with the latest builds "
+"of %3$s."
+
+#: views/compatibility/dashboard.thtml:81
+#, fuzzy
+msgid "compatibility_report_legend_alpha"
+msgstr "Alpha Versions"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:81
+#, fuzzy
+msgid "compatibility_report_legend_alpha_description"
+msgstr "Add-ons compatible with an alpha version of %1$s"
+
+#: views/compatibility/dashboard.thtml:85
+#, fuzzy
+msgid "compatibility_report_legend_beta"
+msgstr "Beta Versions"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:85
+#, fuzzy
+msgid "compatibility_report_legend_beta_description"
+msgstr "Add-ons compatible with a beta version or release candidate of %1$s"
+
+#: views/compatibility/dashboard.thtml:89
+#, fuzzy
+msgid "compatibility_report_legend_latest"
+msgstr "Latest Version"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:89
+#, fuzzy
+msgid "compatibility_report_legend_latest_description"
+msgstr "Add-ons up-to-date with the latest builds of %1$s"
+
+#: views/compatibility/dashboard.thtml:77
+#, fuzzy
+msgid "compatibility_report_legend_other"
+msgstr "Other Versions"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:77
+#, fuzzy
+msgid "compatibility_report_legend_other_description"
+msgstr "Add-ons not compatible with any version of %1$s"
+
+#: views/compatibility/dashboard.thtml:62
+#, fuzzy
+msgid "compatibility_report_title"
+msgstr "Add-on Compatibility Report"
+
+#: views/compatibility/dashboard.thtml:54
+#: views/compatibility/dashboard.thtml:144 views/compatibility/users.thtml:42
+#, fuzzy
+msgid "compatibility_user_info"
+msgstr "Information for Add-on Users"
+
+#: views/compatibility/dashboard.thtml:52
+#, fuzzy
+msgid "compatibility_view_report"
+msgstr "View Compatibility Report"
+
+#. %s is a URL
+#: views/pages/credits.thtml:142
+#, php-format
+msgid "credits_contributing"
+msgstr "Laguntza-informazioa jasotzeko ikusi gure %s."
+
+#: views/pages/credits.thtml:142
+msgid "credits_contributing_wikipage"
+msgstr "wiki orria"
+
+#: views/pages/credits.thtml:99
+msgid "credits_intro"
+msgstr ""
+"Mozillak eskerrak eman nahi dizkie ondorengoei addons.mozilla.org "
+"proiektuari urteotan emandako laguntzagatik:"
+
+#: views/pages/credits.thtml:103
+msgid "credits_section_developers"
+msgstr "Garatzaileak"
+
+#: views/pages/credits.thtml:115
+msgid "credits_section_editors"
+msgstr "Editoreak"
+
+#: views/pages/credits.thtml:109
+msgid "credits_section_localizers"
+msgstr "Itzultzaileak"
+
+#: views/pages/credits.thtml:121
+msgid "credits_section_other_contributors"
+msgstr "Beste laguntzaileak"
+
+#: views/pages/credits.thtml:127
+msgid "credits_section_past_developers"
+msgstr "Lehengo garatzaileak"
+
+#: views/pages/credits.thtml:133
+#, fuzzy
+msgid "credits_section_software"
+msgstr "Software and Images"
+
+#: views/pages/credits.thtml:136
+#, fuzzy
+msgid "credits_software_famfamfam"
+msgstr ""
+"Some icons used are from the <a href=\"http://www.famfamfam.com/lab/icons/"
+"silk/\">famfamfam Silk Icon Set</a>, licensed under a <a href=\"http://"
+"creativecommons.org/licenses/by/2.5/\">Creative Commons Attribution 2.5 "
+"License</a>."
+
+#: views/pages/credits.thtml:137
+#, fuzzy
+msgid "credits_software_timeplot"
+msgstr ""
+"Some pages use elements of <a href=\"http://www.simile-widgets.org/timeplot/"
+"\">Timeplot</a>, licensed under a <a href=\"http://simile.mit.edu/license."
+"html\">BSD License</a>."
+
+# date format string as used in PHP's strftime():
+# http://php.net/strftime
+#. date format string as used in PHP's strftime():
+#. http://php.net/strftime
+#: views/elements/collections_interactive_addon.thtml:85
+#: views/elements/amo2009/addon_version_detail.thtml:53
+#: views/elements/amo2009/homepage_addon.thtml:115
+#: views/elements/addon_version_detail.thtml:54
+#: views/elements/addon_listitem.thtml:124 views/elements/feature.thtml:106
+#: views/collections/detail.thtml:118 views/collections/edit.thtml:325
+#: views/users/info.thtml:76 views/editors/reviews_queue.thtml:57
+#: views/editors/reviews_queue.thtml:68 views/developers/dashboard.thtml:65
+#: views/developers/versions_edit.thtml:208 views/developers/versions.thtml:67
+#: views/search/rss/index.thtml:5 views/addons/rss/versions.thtml:42
+#: views/addons/display.thtml:104 views/addons/display.thtml:356
+#: views/addons/browse_thumbs.thtml:75 views/reviews/add.thtml:63
+#: views/reviews/display.thtml:74 views/reviews/display.thtml:160
+#: views/reviews/delete.thtml:54 controllers/statistics_controller.php:244
+#: controllers/collections_controller.php:1047
+msgid "date"
+msgstr "%Y(e)ko %Bren %ea"
+
+# date and time format string (strftime)
+#. date and time format string (strftime)
+#. http://php.net/strftime
+#: views/elements/addon_version_detail.thtml:53
+#: views/developers/discuss.thtml:52 views/developers/discuss.thtml:62
+#: views/admin/addons_status.thtml:57
+msgid "datetime"
+msgstr "%Y(e)ko %Bren %ea, %I:%M %p"
+
+#: views/elements/developers/actionbar.thtml:47
+msgid "devcp_actionbar_link_details"
+msgstr "Informazio zehatza"
+
+#: views/elements/developers/actionbar.thtml:42
+#: views/elements/developers/actionbar.thtml:50
+#: views/developers/dashboard.thtml:64
+msgid "devcp_actionbar_link_edit"
+msgstr "Editatu gehigarria"
+
+#: views/elements/developers/actionbar.thtml:51
+msgid "devcp_actionbar_link_newversion"
+msgstr "Igo bertsio berria"
+
+#: views/elements/developers/actionbar.thtml:44
+#: views/elements/developers/actionbar.thtml:49
+#: views/developers/dashboard.thtml:73
+msgid "devcp_actionbar_link_stats"
+msgstr "Estatistiken arbela"
+
+#. %1$s is a filename, e.g. "foo.txt"
+#. %2$s is the extension, e.g. ".txt"
+#. %3$s is a list of valid extensions, like ".png, .jpg, .gif"
+#: controllers/developers_controller.php:1361
+#, fuzzy
+msgid "devcp_add_previews_extension_error"
+msgstr "File %1$s has an invalid extension (%2$s). Allowed extensions: %3$s"
+
+#. %s is the filename.
+#: controllers/developers_controller.php:1394
+#, fuzzy
+msgid "devcp_add_previews_save_error"
+msgstr "File %s could not be saved to the database. Please try again."
+
+#. %1$s is the preview ID number, %2$s is the filename.
+#: controllers/developers_controller.php:1389
+#, fuzzy
+msgid "devcp_add_previews_success_replace"
+msgstr "Preview %1$s was replaced with file %2$s successfully."
+
+#. %s is the filename.
+#: controllers/developers_controller.php:1391
+#, fuzzy
+msgid "devcp_add_previews_success_upload"
+msgstr "File %s was uploaded successfully. You can add a caption below."
+
+#: controllers/components/developers.php:1163
+msgid "devcp_additem_addontype_autodetect"
+msgstr "(automatikoki atzeman)"
+
+#: views/elements/developers/additem.thtml:76
+msgid "devcp_additem_linktitle_opensin_newwindow"
+msgstr "Leiho berrian irekiko da"
+
+#: views/elements/developers/additem.thtml:41
+msgid "devcp_additem_sidebar_title"
+msgstr "Bidali gehigarria"
+
+#: views/elements/developers/additem.thtml:53
+msgid "devcp_additem_step0_newlink"
+msgstr "Garatzaile-kontratua"
+
+#: views/elements/developers/additem.thtml:46
+msgid "devcp_additem_step1_link"
+msgstr "1. urratsa: igotzea"
+
+#: views/elements/developers/additem.thtml:47
+msgid "devcp_additem_step2_link"
+msgstr "2. urratsa: gehigarriaren xehetasunak"
+
+#: views/elements/developers/additem.thtml:48
+msgid "devcp_additem_step3_link"
+msgstr "3. urratsa: bertsioaren xehetasunak"
+
+#: views/elements/developers/additem.thtml:49
+msgid "devcp_additem_step4_link"
+msgstr "4. urratsa: lokalizazioa"
+
+#: views/elements/developers/additem.thtml:50
+msgid "devcp_additem_step5_link"
+msgstr "5. urratsa: eginda"
+
+#: views/elements/developers/additem.thtml:76
+msgid "devcp_additem_submissionhelp_link"
+msgstr "Bidaltzeko laguntza"
+
+#: controllers/previews_controller.php:168
+#: controllers/previews_controller.php:277
+msgid "devcp_addon_field_preview_caption_displaytitle"
+msgstr "Aurrebistaren izenburua"
+
+#: views/developers/addon_status.thtml:177
+#, fuzzy
+msgid "devcp_addon_status_action_activate"
+msgstr "Make Active"
+
+#: views/developers/addon_status.thtml:178
+#, fuzzy
+msgid "devcp_addon_status_action_activate_description"
+msgstr ""
+"Make your add-on active for it to show up in public listings and enable the "
+"update check service."
+
+#: views/developers/addon_status.thtml:135
+#, fuzzy
+msgid "devcp_addon_status_action_complete"
+msgstr "Complete Add-on"
+
+#: views/developers/addon_status.thtml:136
+#, fuzzy
+msgid "devcp_addon_status_action_complete_description"
+msgstr "Complete your add-on and move to the Sandbox"
+
+#: views/developers/addon_status.thtml:181
+#, fuzzy
+msgid "devcp_addon_status_action_deactivate"
+msgstr "Make Inactive"
+
+#: views/developers/addon_status.thtml:182
+#, fuzzy
+msgid "devcp_addon_status_action_deactivate_description"
+msgstr ""
+"Make your add-on inactive to hide it from all public listings and disable "
+"the update check service."
+
+#: views/developers/addon_status.thtml:143
+#, fuzzy
+msgid "devcp_addon_status_action_move"
+msgstr "Move to Sandbox"
+
+#: views/developers/addon_status.thtml:144
+#, fuzzy
+msgid "devcp_addon_status_action_move_description"
+msgstr "Move your add-on back to the Sandbox. This is reversible."
+
+#: views/developers/addon_status.thtml:139
+#, fuzzy
+msgid "devcp_addon_status_action_nominate"
+msgstr "Nominate for Public"
+
+#: views/developers/addon_status.thtml:140
+#, fuzzy
+msgid "devcp_addon_status_action_nominate_description"
+msgstr "Nominate your add-on to become Public"
+
+#: views/developers/addon_status.thtml:147
+#, fuzzy
+msgid "devcp_addon_status_action_public"
+msgstr "Make Public"
+
+#: views/developers/addon_status.thtml:148
+#, fuzzy
+msgid "devcp_addon_status_action_public_description"
+msgstr "Make your add-on Public again."
+
+#: views/developers/addon_status.thtml:169
+#, fuzzy
+msgid "devcp_addon_status_active"
+msgstr ""
+"Your add-on is <span class=\"inactive-0\">Active</span>. This means your add-"
+"on is showing up in all available listings appropriate for its status above."
+
+#: views/developers/addon_status.thtml:111
+#, fuzzy
+msgid "devcp_addon_status_completion_disabled"
+msgstr ""
+"Please fulfill the criteria above before you can complete your add-on and "
+"move it to the <span class=\"status-1\">Sandbox</span>."
+
+#: views/developers/addon_status.thtml:108
+#, fuzzy
+msgid "devcp_addon_status_completion_enabled"
+msgstr ""
+"You may now complete your add-on and move it to the <span class=\"status-1"
+"\">Sandbox</span> by clicking the button below."
+
+#: views/developers/addon_status.thtml:102
+#, fuzzy
+msgid "devcp_addon_status_criteria_category"
+msgstr "At least one category selected"
+
+#: views/developers/addon_status.thtml:101
+#, fuzzy
+msgid "devcp_addon_status_criteria_description"
+msgstr "Add-on Description required"
+
+#: views/developers/addon_status.thtml:99
+#, fuzzy
+msgid "devcp_addon_status_criteria_name"
+msgstr "Add-on Name required"
+
+#: views/developers/addon_status.thtml:120
+#, fuzzy
+msgid "devcp_addon_status_criteria_prerelease"
+msgstr "Add-on is not marked as pre-release."
+
+#: views/developers/addon_status.thtml:119
+#, fuzzy
+msgid "devcp_addon_status_criteria_preview"
+msgstr "At least one preview image required for extensions and themes."
+
+#: views/developers/addon_status.thtml:100
+#, fuzzy
+msgid "devcp_addon_status_criteria_summary"
+msgstr "Add-on Summary required"
+
+#. %s is the status in a span, e.g. "<span>_('Public')</span>".
+#: views/developers/addon_status.thtml:58
+#, fuzzy
+msgid "devcp_addon_status_header"
+msgstr "Add-on Status: %s"
+
+#: views/developers/addon_status.thtml:152
+#: views/developers/addon_status.thtml:173
+#, fuzzy
+msgid "devcp_addon_status_header_actions"
+msgstr "Available Actions"
+
+#: views/developers/addon_status.thtml:168
+#, fuzzy
+msgid "devcp_addon_status_header_active"
+msgstr "Active Status: <span class=\"inactive-0\">Active</span>"
+
+#: views/developers/addon_status.thtml:97
+#, fuzzy
+msgid "devcp_addon_status_header_criteria"
+msgstr "Add-on Completion Criteria"
+
+#: views/developers/addon_status.thtml:164
+#, fuzzy
+msgid "devcp_addon_status_header_inactive"
+msgstr "Active Status: <span class=\"inactive-1\">Inactive</span>"
+
+#: views/developers/addon_status.thtml:117
+#, fuzzy
+msgid "devcp_addon_status_header_nomination"
+msgstr "Public Nomination Criteria"
+
+#: views/developers/addon_status.thtml:190
+#, fuzzy
+msgid "devcp_addon_status_header_trusted"
+msgstr "Trusted Status: <span class=\"status-4\">Trusted</span>"
+
+#: views/developers/addon_status.thtml:165
+#, fuzzy
+msgid "devcp_addon_status_inactive"
+msgstr ""
+"Your add-on is <span class=\"inactive-1\">Inactive</span>. This means your "
+"add-on will not show up in any listing, regardless of its status above. "
+"Updates are <b>not</b> being provided to your add-on through the update "
+"check service."
+
+#: views/developers/addon_status.thtml:128
+#, fuzzy
+msgid "devcp_addon_status_nominate_disabled"
+msgstr ""
+"Please fulfill the criteria above before nominating your add-on to become "
+"<span class=\"status-4\">Public</span>."
+
+#: views/developers/addon_status.thtml:125
+#, fuzzy
+msgid "devcp_addon_status_nominate_enabled"
+msgstr ""
+"You may now nominate your add-on for <span class=\"status-4\">Public</span> "
+"by clicking the button below."
+
+#: views/developers/addon_status.thtml:64
+#, fuzzy
+msgid "devcp_addon_status_public"
+msgstr "Public"
+
+#: views/developers/addon_status.thtml:63
+#, fuzzy
+msgid "devcp_addon_status_sandbox"
+msgstr "Sandbox"
+
+#. %s is an email address.
+#: views/developers/addon_status.thtml:89
+#, fuzzy
+msgid "devcp_addon_status_switch_disabled"
+msgstr ""
+"Your add-on was <span class=\"status-5\">Disabled</span> by an administrator "
+"and cannot be used. If you have any questions, please e-mail %s."
+
+#: views/developers/addon_status.thtml:67
+#, fuzzy
+msgid "devcp_addon_status_switch_incomplete"
+msgstr ""
+"Your add-on is currently <span class=\"status-0\">Incomplete</span>. This "
+"means your add-on is not showing up on any portion of the site or update "
+"check service. You may come to this page to complete your add-on after it "
+"meets the criteria below for completion and transfer to the <span class="
+"\"status-1\">Sandbox</span>."
+
+#. %s is a number, perhaps 42.
+#: views/developers/addon_status.thtml:77
+#, fuzzy
+msgid "devcp_addon_status_switch_nominated"
+msgstr ""
+"Your add-on is currently nominated to become <span class=\"status-4"
+"\">Public</span> and is awaiting editor review. There are currently %s other "
+"add-ons in the nomination queue."
+
+#. %s is an email address.
+#: views/developers/addon_status.thtml:81
+#, fuzzy
+msgid "devcp_addon_status_switch_pending"
+msgstr ""
+"Your add-on is pending. This shouldn't have happened. Please e-mail %s with "
+"your add-on ID and state this error."
+
+#: views/developers/addon_status.thtml:85
+#, fuzzy
+msgid "devcp_addon_status_switch_public"
+msgstr ""
+"Your add-on is <span class=\"status-4\">Public</span>, which means it will "
+"show up in all listings and searches and can be downloaded without "
+"restriction. Updates are being provided to your add-on through the update "
+"check service."
+
+#: views/developers/addon_status.thtml:71
+#: views/developers/addon_status.thtml:75
+#, fuzzy
+msgid "devcp_addon_status_switch_sandbox"
+msgstr ""
+"Your add-on is in the <span class=\"status-1\">Sandbox</span>, which means "
+"it will show up in listings and searches, but users must log in to download "
+"it. Updates are <b>not</b> being provided to your add-on through the update "
+"check service."
+
+#. %s is the add-on name.
+#: views/developers/addon_status_nominate.thtml:43
+#: views/developers/addon_status_confirm.thtml:43
+#: views/developers/addon_status.thtml:43
+#, fuzzy
+msgid "devcp_addon_status_title"
+msgstr "%s Status"
+
+#: views/developers/addon_status.thtml:191
+#, fuzzy
+msgid "devcp_addon_status_trusted"
+msgstr ""
+"Your add-on is <span class=\"status-4\">Trusted</span>. This means you can "
+"submit updates to your add-on without editor review."
+
+#: views/developers/dashboard.thtml:68
+#, fuzzy
+msgid "devcp_dashboard_active"
+msgstr "Active"
+
+#. %1$s is the add-on type string
+#. %2$s is Inactive or Active in a <span>
+#. %3$s is the addon's public status (Public, In Sandbox, ...) in a <span>
+#: views/developers/dashboard.thtml:69
+#, fuzzy
+msgid "devcp_dashboard_addontype_status"
+msgstr "%1$s currenty %2$s and %3$s"
+
+#: views/developers/dashboard.thtml:67
+#, fuzzy
+msgid "devcp_dashboard_change_status"
+msgstr "Change Status"
+
+#. %s is the addons email address.
+#: views/developers/dashboard.thtml:99
+#, fuzzy
+msgid "devcp_dashboard_disabled_questions"
+msgstr ""
+"Your add-on was disabled by an administrator and cannot be used. If you "
+"have any questions, please email %s."
+
+#. %s is the (localized) add-on status string in a span, e.g. "Disabled"
+#: views/developers/dashboard.thtml:98
+#, fuzzy
+msgid "devcp_dashboard_disabled_status"
+msgstr "Add-on Status: %s"
+
+#: views/developers/dashboard.thtml:43
+#, fuzzy
+msgid "devcp_dashboard_header_main"
+msgstr "Developer Dashboard"
+
+#: views/developers/dashboard.thtml:110
+#, fuzzy
+msgid "devcp_dashboard_header_welcome"
+msgstr "Welcome to the Developer Dashboard"
+
+#: views/developers/dashboard.thtml:68
+#, fuzzy
+msgid "devcp_dashboard_inactive"
+msgstr "Inactive"
+
+#. %s is a date in the _('date') format
+#: views/developers/dashboard.thtml:65
+#, fuzzy
+msgid "devcp_dashboard_last_edited"
+msgstr "Last edited on %s"
+
+#: views/developers/dashboard.thtml:111
+#, fuzzy
+msgid "devcp_dashboard_learn"
+msgstr ""
+"You don't currently have any add-ons hosted on Mozilla Add-ons. To learn how "
+"the process works and submit your first add-on, click Get Started below."
+
+#: views/developers/dashboard.thtml:112
+#, fuzzy
+msgid "devcp_dashboard_start"
+msgstr "Get Started"
+
+#: views/developers/dashboard.thtml:82
+#, fuzzy
+msgid "devcp_dashboard_versions"
+msgstr "Versions and Files"
+
+#: views/developers/dashboard.thtml:91
+#, fuzzy
+msgid "devcp_dashboard_versions_new"
+msgstr "Upload a new version"
+
+#. %s is the preview ID number.
+#: controllers/developers_controller.php:1415
+#, fuzzy
+msgid "devcp_delete_previews_error"
+msgstr "Preview %s could not be deleted from the database. Please try again."
+
+#. %s is the preview ID number.
+#: controllers/developers_controller.php:1413
+#, fuzzy
+msgid "devcp_delete_previews_success"
+msgstr "Preview %s has been deleted successfully."
+
+#: controllers/developers_controller.php:1089
+#, fuzzy
+msgid "devcp_delete_version_priv_error"
+msgstr "You do not have privileges to delete versions or files."
+
+#. %1$s is the count of files, a number
+#. %2$s is a status string like _('Public') or _('Incomplete')
+#: controllers/components/amo.php:549
+#, fuzzy
+msgid "devcp_describe_version_status"
+msgid_plural "devcp_describe_version_status"
+msgstr[0] "%1$s %2$s file"
+msgstr[1] "%1$s %2$s files"
+
+#. %s is a version number. Example: 3.0
+#: views/developers/versions.thtml:65
+#, php-format
+msgid "devcp_details_version"
+msgstr "%s bertsioa"
+
+#: views/developers/discuss.thtml:68
+#, fuzzy
+msgid "devcp_discuss_addreply_header"
+msgstr "Add Reply"
+
+#: views/developers/discuss.thtml:57
+#, fuzzy
+msgid "devcp_discuss_allreplies_header"
+msgstr "Replies"
+
+#. notice when an error occurs saving a discussion reply
+#. %1 is the email address (linked) for the amo-editors list
+#: views/developers/discuss.thtml:70
+#, fuzzy
+msgid "devcp_discuss_error_notice"
+msgstr ""
+"There was an error saving your reply. Please contact %1$s about the issue."
+
+#. %1 is the add-on name, %2 is the add-on's version number currently being reviewed by an editor
+#: views/developers/discuss.thtml:46
+#, fuzzy
+msgid "devcp_discuss_intro"
+msgstr ""
+"A Mozilla Add-ons Editor requested further information from you regarding "
+"version %2$s of your add-on %1$s."
+
+#. %1 is the add-on name
+#: views/developers/discuss.thtml:43
+#, fuzzy
+msgid "devcp_discuss_pagetitle"
+msgstr "Provide More Information For the Add-on Review of %1$s"
+
+#. submit button text
+#: views/developers/discuss.thtml:79
+#, fuzzy
+msgid "devcp_discuss_submit_reply"
+msgstr "Submit Reply"
+
+#: views/developers/discuss.thtml:72
+#, fuzzy
+msgid "devcp_discuss_success_message"
+msgstr ""
+"Your reply was successfully saved. The other participants of the discussion "
+"will be notified by email."
+
+#. in an author/editor discussion about an add-on to be reviewed:
+#. %1 is the commenter's user name (linked).
+#. %2 is the full date the comment was made.
+#: views/developers/discuss.thtml:52 views/developers/discuss.thtml:62
+#, fuzzy
+msgid "devcp_discuss_writtenby"
+msgstr "written by %1$s on %2$s"
+
+#: views/developers/addon_edit_authors.thtml:72
+#: views/developers/addon_edit_authors.thtml:81
+#, fuzzy
+msgid "devcp_edit_authors_add_author"
+msgstr "Add New Author"
+
+#: views/developers/addon_edit_authors.thtml:96
+#, fuzzy
+msgid "devcp_edit_authors_add_author_button"
+msgstr "Add Author"
+
+#: views/developers/addon_edit_authors.thtml:83
+#, fuzzy
+msgid "devcp_edit_authors_add_email"
+msgstr "Author Account Email:"
+
+#: views/developers/addon_edit_authors.thtml:98
+#, fuzzy
+msgid "devcp_edit_authors_add_loading"
+msgstr "Checking account email..."
+
+#: views/developers/addon_edit_authors.thtml:70
+#, fuzzy
+msgid "devcp_edit_authors_click_save"
+msgstr "Click the Update Authors button below to save."
+
+#: views/developers/addon_edit_authors.thtml:58
+#, fuzzy
+msgid "devcp_edit_authors_header_current"
+msgstr "Current Authors"
+
+#: views/developers/addon_edit_authors.thtml:50
+#, fuzzy
+msgid "devcp_edit_authors_header_manage"
+msgstr "Manage Add-on Authors"
+
+#: views/developers/addon_edit_authors.thtml:93
+#, fuzzy
+msgid "devcp_edit_authors_label_add_listed"
+msgstr "List as author in pubilc display pages"
+
+#: views/developers/addon_edit_authors.thtml:89
+#, fuzzy
+msgid "devcp_edit_authors_label_developer"
+msgstr ""
+"<strong>Developer</strong> - Can manage all aspects of the add-on listing, "
+"except for adding and removing other authors."
+
+#: views/developers/addon_edit_authors.thtml:88
+#, fuzzy
+msgid "devcp_edit_authors_label_owner"
+msgstr ""
+"<strong>Owner</strong> - Can manage all aspects of the add-on listing, "
+"including adding and removing other authors."
+
+#: views/developers/addon_edit_authors.thtml:90
+#, fuzzy
+msgid "devcp_edit_authors_label_viewer"
+msgstr ""
+"<strong>Viewer</strong> - Can view add-on developer listing and statistics, "
+"but can't make any changes."
+
+#. Placeholder for the empty option in a <select>.
+#: views/developers/addon_edit_categories.thtml:69
+#, fuzzy
+msgid "devcp_edit_authors_option_empty"
+msgstr "----------------"
+
+#: views/developers/addon_edit_authors.thtml:86
+#, fuzzy
+msgid "devcp_edit_authors_select_role"
+msgstr "Select a role for the author:"
+
+#. Column name in a table.
+#: views/developers/addon_edit_authors.thtml:62
+#, fuzzy
+msgid "devcp_edit_authors_th_author"
+msgstr "Author"
+
+#. Column name in a table.
+#: views/developers/addon_edit_authors.thtml:64
+#, fuzzy
+msgid "devcp_edit_authors_th_listed"
+msgstr "Listed"
+
+#. Column name in a table.
+#: views/developers/addon_edit_authors.thtml:63
+#, fuzzy
+msgid "devcp_edit_authors_th_role"
+msgstr "Role"
+
+#: views/developers/addon_edit_authors.thtml:77
+#, fuzzy
+msgid "devcp_edit_authors_update_author"
+msgstr "Update authors"
+
+#: views/developers/addon_edit_categories.thtml:99
+#, fuzzy
+msgid "devcp_edit_categories_button_update"
+msgstr "Update Categories"
+
+#: views/developers/addon_edit_categories.thtml:88
+#, fuzzy
+msgid "devcp_edit_categories_does_not_fit"
+msgstr "My add-on doesn't fit into any available categories."
+
+#. %s is the application name (Firefox, Thunderbird).
+#: views/developers/addon_edit_categories.thtml:61
+#, fuzzy
+msgid "devcp_edit_categories_header_application"
+msgstr "%s Categories"
+
+#: views/developers/addon_edit_categories.thtml:49
+#, fuzzy
+msgid "devcp_edit_categories_header_manage"
+msgstr "Manage Add-on Categories"
+
+#: views/developers/addon_edit_categories.thtml:91
+#, fuzzy
+msgid "devcp_edit_categories_hover"
+msgstr "Hover over a category to see its description."
+
+#. %s is the category number (1, 2, 3).
+#: views/developers/addon_edit_categories.thtml:67
+#, fuzzy
+msgid "devcp_edit_categories_label_category_num"
+msgstr "Category %s"
+
+#: views/developers/addon_edit_categories.thtml:94
+#: views/developers/addon_edit_categories.thtml:103
+#, fuzzy
+msgid "devcp_edit_categories_none_available"
+msgstr "No categories are available for this add-on type and application."
+
+#: views/developers/addon_edit_categories.thtml:86
+#, fuzzy
+msgid "devcp_edit_categories_other"
+msgstr ""
+"Place your add-on into this category only if it does not fit into any other "
+"available categories."
+
+#. %s is the application name (Firefox, Thunderbird).
+#: views/developers/addon_edit_categories.thtml:63
+#, fuzzy
+msgid "devcp_edit_categories_select_application_categories"
+msgstr "Select up to three %s categories for your add-on"
+
+#: views/developers/addon_edit.thtml:47
+#, fuzzy
+msgid "devcp_edit_dd_manage_authors"
+msgstr "Add or remove users that can manage this add-on."
+
+#: views/developers/addon_edit.thtml:49
+#, fuzzy
+msgid "devcp_edit_dd_manage_categories"
+msgstr ""
+"Select the relevant categories for each application your add-on supports."
+
+#: views/developers/addon_edit.thtml:51
+#, fuzzy
+msgid "devcp_edit_dd_manage_description"
+msgstr ""
+"Add and modify translations for your add-on's summary, description, end-user "
+"license, and privacy policy."
+
+#: views/developers/addon_edit.thtml:53
+#, fuzzy
+msgid "devcp_edit_dd_manage_properties"
+msgstr "Change your add-on's name, homepage, icon, and other flags."
+
+#: views/developers/addon_edit_descriptions.thtml:116
+#, fuzzy
+msgid "devcp_edit_description_button_update"
+msgstr "Update Descriptions"
+
+#: views/developers/addon_edit_descriptions.thtml:115
+#, fuzzy
+msgid "devcp_edit_description_correct_error"
+msgstr "Please correct the errors above indicated in red."
+
+#: views/developers/addon_edit_descriptions.thtml:51
+#, fuzzy
+msgid "devcp_edit_descriptions_header"
+msgstr "Edit Add-on Descriptions"
+
+#: views/developers/addon_edit_descriptions.thtml:94
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_comments_description"
+msgstr ""
+"Any information end users may want to know that isn't necessarily applicable "
+"to the add-on summary or description. Common uses include listing known "
+"major bugs, information on how to report bugs, anticipated release date of a "
+"new version, etc."
+
+#: views/developers/addon_edit_descriptions.thtml:93
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_comments_name"
+msgstr "Developer Comments"
+
+#: views/developers/addon_edit_descriptions.thtml:86
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_description_description"
+msgstr ""
+"The description of your add-on is a longer explanation of features, "
+"functionality, and other relevant information. It is displayed under the "
+"summary on the add-on's display page."
+
+#: views/developers/addon_edit_descriptions.thtml:85
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_description_name"
+msgstr "Add-on Description"
+
+#: views/developers/addon_edit_descriptions.thtml:103
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_eula_description"
+msgstr ""
+"If your add-on has an End-User License Agreement (EULA), please enter its "
+"text below. If set below, users will be required to agree to this before "
+"installing your add-on. Please note that a EULA is not the same as a code "
+"license such as GPL or MPL."
+
+#: views/developers/addon_edit_descriptions.thtml:102
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_eula_name"
+msgstr "End-User License Agreement"
+
+#: views/developers/addon_edit_descriptions.thtml:112
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_privacy_description"
+msgstr ""
+"If your add-on has a privacy policy, enter its text here. Your add-on's "
+"display page will display a link to the policy."
+
+#: views/developers/addon_edit_descriptions.thtml:111
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_privacy_name"
+msgstr "Privacy Policy"
+
+#: views/developers/addon_edit_descriptions.thtml:78
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_summary_description"
+msgstr ""
+"The summary is a short explanation of your add-on's basic functionality that "
+"is displayed in search and browse listings, as well as at the top of your "
+"add-on's display page. <strong>Limit of 250 characters.</strong>"
+
+#: views/developers/addon_edit_descriptions.thtml:77
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_summary_name"
+msgstr "Add-on Summary"
+
+#: views/developers/addon_edit.thtml:46
+#, fuzzy
+msgid "devcp_edit_dt_manage_authors"
+msgstr "Manage Add-on Authors"
+
+#: views/developers/addon_edit.thtml:48
+#, fuzzy
+msgid "devcp_edit_dt_manage_categories"
+msgstr "Manage Add-on Categories"
+
+#: views/developers/addon_edit.thtml:50
+#, fuzzy
+msgid "devcp_edit_dt_manage_descriptions"
+msgstr "Manage Add-on Descriptions"
+
+#: views/developers/addon_edit.thtml:52
+#, fuzzy
+msgid "devcp_edit_dt_manage_properties"
+msgstr "Manage Add-on Properties"
+
+#: views/developers/addon_edit_properties.thtml:170
+msgid "devcp_edit_label_externalsoftware"
+msgstr "Gehigarri honek kanpoko softwarea behar du"
+
+#: views/developers/addon_edit_properties.thtml:205
+msgid "devcp_edit_label_locale_disambiguation"
+msgstr "Locale-aren info gehigarria"
+
+#: views/developers/addon_edit_properties.thtml:168
+msgid "devcp_edit_label_prerelease"
+msgstr "Hau aurreargitalpen bat da"
+
+#: views/developers/addon_edit_properties.thtml:169
+msgid "devcp_edit_label_sitespecific"
+msgstr "Hau gune konkretu baterako gehigarria da"
+
+#: views/developers/addon_edit_properties.thtml:202
+msgid "devcp_edit_label_target_locale"
+msgstr "Helburu locale-a"
+
+#: views/developers/addon_edit_properties.thtml:212
+#, fuzzy
+msgid "devcp_edit_properties_button_update"
+msgstr "Update Properties"
+
+#: views/developers/addon_edit_properties.thtml:198
+#, fuzzy
+msgid "devcp_edit_properties_change_guid"
+msgstr "Only change if you understand all of the consequences."
+
+#: views/developers/addon_edit_properties.thtml:109
+#, fuzzy
+msgid "devcp_edit_properties_current_icon"
+msgstr "Current Icon"
+
+#: views/developers/addon_edit_properties.thtml:85
+#, fuzzy
+msgid "devcp_edit_properties_default_locale"
+msgstr ""
+"An add-on's default locale is the main locale in which translations must be "
+"present. If translations for your add-on's descriptions are unavailable in a "
+"user's selected language, they will fall back to this default locale."
+
+#: views/developers/addon_edit_properties.thtml:167
+#, fuzzy
+msgid "devcp_edit_properties_flags"
+msgstr "These flags are used to filter and classify add-ons."
+
+#: views/developers/addon_edit_properties.thtml:174
+#, fuzzy
+msgid "devcp_edit_properties_guid"
+msgstr ""
+"The GUID of your add-on is specified in its install.rdf and uniquely "
+"identifies it. You cannot change your GUID once it is listed on Mozilla Add-"
+"ons."
+
+#: views/developers/addon_edit_properties.thtml:53
+#, fuzzy
+msgid "devcp_edit_properties_header"
+msgstr "Edit Add-on Properties"
+
+#: views/developers/addon_edit_properties.thtml:186
+#, fuzzy
+msgid "devcp_edit_properties_header_addon_type"
+msgstr "Add-on Type"
+
+#: views/developers/addon_edit_properties.thtml:181
+#, fuzzy
+msgid "devcp_edit_properties_header_admin_settings"
+msgstr "Admin Settings"
+
+#: views/developers/addon_edit_properties.thtml:84
+#, fuzzy
+msgid "devcp_edit_properties_header_default_locale"
+msgstr "Default Locale"
+
+#: views/developers/addon_edit_properties.thtml:166
+#, fuzzy
+msgid "devcp_edit_properties_header_flags"
+msgstr "Add-on Flags"
+
+#: views/developers/addon_edit_properties.thtml:173
+#: views/developers/addon_edit_properties.thtml:197
+#, fuzzy
+msgid "devcp_edit_properties_header_guid"
+msgstr "Add-on GUID"
+
+#: views/developers/addon_edit_properties.thtml:104
+#, fuzzy
+msgid "devcp_edit_properties_header_icon"
+msgstr "Add-on Icon"
+
+#: views/developers/addon_edit_properties.thtml:159
+#, fuzzy
+msgid "devcp_edit_properties_header_other_settings"
+msgstr "Other Settings"
+
+#. A header on the admin page to toggle trusted status.
+#: views/developers/addon_edit_properties.thtml:182
+#, fuzzy
+msgid "devcp_edit_properties_header_trusted"
+msgstr "Trusted Add-on?"
+
+#: views/developers/addon_edit_properties.thtml:160
+#, fuzzy
+msgid "devcp_edit_properties_header_view_source"
+msgstr "View Source Online"
+
+#. %s is a comma-separated list of image extensions ".png, .jpg"
+#: views/developers/addon_edit_properties.thtml:106
+#, fuzzy
+msgid "devcp_edit_properties_icon"
+msgstr ""
+"The add-on icon is a small image that is displayed next to your add-on's "
+"name in browse and search results, display pages, and in the add-on "
+"installation dialog. The image will automatically be resized to 32 x 32 "
+"pixels. Please use one of the following image types: %s"
+
+#: views/developers/addon_edit_properties.thtml:171
+#, fuzzy
+msgid "devcp_edit_properties_label_binary"
+msgstr "This add-on contains binary components"
+
+#: views/developers/addon_edit_properties.thtml:185
+#, fuzzy
+msgid "devcp_edit_properties_label_not_trusted"
+msgstr "Not Trusted"
+
+#: views/developers/addon_edit_properties.thtml:184
+#, fuzzy
+msgid "devcp_edit_properties_label_trusted"
+msgstr "Trusted"
+
+#: views/developers/addon_edit_properties.thtml:110
+#, fuzzy
+msgid "devcp_edit_properties_new_icon"
+msgstr "New Icon"
+
+#: views/developers/addon_edit_properties.thtml:118
+#, fuzzy
+msgid "devcp_edit_properties_remove_icon"
+msgstr "Remove Icon"
+
+#: views/developers/addon_edit_properties.thtml:136
+#, fuzzy
+msgid "devcp_edit_properties_transbox_homepage_description"
+msgstr ""
+"If your add-on has another homepage, enter its address here. Adding other "
+"translations is not necessary unless your website is localized into other "
+"languages."
+
+#: views/developers/addon_edit_properties.thtml:135
+#, fuzzy
+msgid "devcp_edit_properties_transbox_homepage_name"
+msgstr "Add-on Homepage"
+
+#: views/developers/addon_edit_properties.thtml:79
+#, fuzzy
+msgid "devcp_edit_properties_transbox_name_description"
+msgstr "The name of your add-on is displayed everywhere your add-on is listed."
+
+#: views/developers/addon_edit_properties.thtml:78
+#, fuzzy
+msgid "devcp_edit_properties_transbox_name_name"
+msgstr "Add-on Name"
+
+#: views/developers/addon_edit_properties.thtml:145
+#, fuzzy
+msgid "devcp_edit_properties_transbox_supportemail_description"
+msgstr ""
+"If you have an email address for support inquiries, enter it here. Adding "
+"other translations is not necessary unless you have different email "
+"addresses for different languages."
+
+#: views/developers/addon_edit_properties.thtml:144
+#, fuzzy
+msgid "devcp_edit_properties_transbox_supportemail_name"
+msgstr "Support Email Address"
+
+#: views/developers/addon_edit_properties.thtml:154
+#, fuzzy
+msgid "devcp_edit_properties_transbox_supporturl_description"
+msgstr ""
+"If your add-on has a support website or forum, enter its address here. "
+"Adding other translations is not necessary unless your website is localized "
+"into other languages."
+
+#: views/developers/addon_edit_properties.thtml:153
+#, fuzzy
+msgid "devcp_edit_properties_transbox_supporturl_name"
+msgstr "Support Website"
+
+#: views/developers/addon_edit_properties.thtml:183
+#, fuzzy
+msgid "devcp_edit_properties_trusted"
+msgstr "Trusted add-ons can become public without Editor review."
+
+#. %s is href="..." and should stay in the <a> tag.
+#: views/developers/addon_edit_properties.thtml:119
+#, fuzzy
+msgid "devcp_edit_properties_undelete"
+msgstr "Icon will be deleted on save. <a %s>Cancel?</a>"
+
+#: views/developers/addon_edit_properties.thtml:161
+#, fuzzy
+msgid "devcp_edit_properties_view_source"
+msgstr ""
+"The source of your add-on files can be viewed online by any logged in user "
+"if you wish."
+
+#: views/developers/addon_edit_properties.thtml:162
+#, fuzzy
+msgid "devcp_edit_properties_view_source_allow"
+msgstr "Allow online source viewing"
+
+#: views/developers/addon_edit_properties.thtml:163
+#, fuzzy
+msgid "devcp_edit_properties_view_source_do_not_allow"
+msgstr "Do not allow online source viewing"
+
+#: views/elements/developers/editbox.thtml:46
+#, fuzzy
+msgid "devcp_editbox_authors"
+msgstr "Authors"
+
+#: views/elements/developers/editbox.thtml:47
+#, fuzzy
+msgid "devcp_editbox_categories"
+msgstr "Categories"
+
+#: views/elements/developers/editbox.thtml:52
+#, fuzzy
+msgid "devcp_editbox_change_status"
+msgstr "Change Status"
+
+#: views/elements/developers/editbox.thtml:48
+#, fuzzy
+msgid "devcp_editbox_descriptions"
+msgstr "Descriptions"
+
+#: views/elements/developers/editbox.thtml:43
+#, fuzzy
+msgid "devcp_editbox_edit_addon"
+msgstr "Edit Add-on"
+
+#: views/elements/developers/editbox.thtml:57
+#, fuzzy
+msgid "devcp_editbox_new_version"
+msgstr "New Version"
+
+#: views/elements/developers/editbox.thtml:49
+#, fuzzy
+msgid "devcp_editbox_properties"
+msgstr "Properties"
+
+#: views/elements/developers/editbox.thtml:60
+#, fuzzy
+msgid "devcp_editbox_screenshots"
+msgstr "Preview Screenshots"
+
+#: views/elements/developers/editbox.thtml:53
+#, fuzzy
+msgid "devcp_editbox_statistics_dashboard"
+msgstr "Statistics Dashboard"
+
+#: views/elements/developers/editbox.thtml:54
+#, fuzzy
+msgid "devcp_editbox_versions"
+msgstr "Versions and Files"
+
+#: views/elements/developers/editbox.thtml:42
+#, fuzzy
+msgid "devcp_editbox_view_listing"
+msgstr "View Listing"
+
+#: views/elements/developers/editorsmenu.thtml:59
+msgid "devcp_editorsqueue_featured"
+msgstr "Nabarmendutako gehigarriak"
+
+# %1 is the review count
+#. %1 is the review count
+#: views/elements/developers/editorsqueue.thtml:42
+#: views/elements/developers/editorsmenu.thtml:56
+#, php-format
+msgid "devcp_editorsqueue_moderatedreviews"
+msgid_plural "devcp_editorsqueue_moderatedreviews"
+msgstr[0] "Moderatutako berrikuspenak (%s)"
+msgstr[1] "Moderatutako berrikuspenak (%s)"
+
+# %1 is the nominated addons count
+#. %1 is the nominated addons count
+#: views/elements/developers/editorsqueue.thtml:44
+#: views/elements/developers/editorsmenu.thtml:58
+#, php-format
+msgid "devcp_editorsqueue_nominated"
+msgid_plural "devcp_editorsqueue_nominated"
+msgstr[0] "Proposatutako gehigarriak (%s)"
+msgstr[1] "Proposatutako gehigarriak (%s)"
+
+# %1 is the update count
+#. %1 is the update count
+#: views/elements/developers/editorsqueue.thtml:43
+#: views/elements/developers/editorsmenu.thtml:57
+#, php-format
+msgid "devcp_editorsqueue_pendingupdates"
+msgid_plural "devcp_editorsqueue_pendingupdates"
+msgstr[0] "Burutugabeko eguneraketak (%s)"
+msgstr[1] "Burutugabeko eguneraketak (%s)"
+
+#: controllers/statistics_controller.php:147
+#: controllers/statistics_controller.php:361
+#: controllers/previews_controller.php:108
+#: controllers/previews_controller.php:211
+#: controllers/previews_controller.php:312
+msgid "devcp_error_addon_access_denied"
+msgstr "Ez duzu atzipenik gehigarri horretara."
+
+#. %s is a complete URL with the text from devcp_error_appversion_reference_link_text
+#. in the <a> tag. This should be fixed.
+#: controllers/components/developers.php:591
+#, php-format
+msgid "devcp_error_appversion_reference_link"
+msgstr "Erreferentziarako ikusi %s."
+
+#. This is the link text in the <a> for devcp_error_appversion_reference_link. This
+#. should be fixed.
+#: controllers/components/developers.php:591
+msgid "devcp_error_appversion_reference_link_text"
+msgstr "orri hau"
+
+#: views/developers/addon_edit_authors.thtml:76
+#, fuzzy
+msgid "devcp_error_empty_authors"
+msgstr "Your add-on must have at least one owner."
+
+#. %1$s is the name of the file
+#: controllers/components/developers.php:658
+#, fuzzy
+msgid "devcp_error_file_exists"
+msgstr ""
+"A version of that addon already exists. To replace it, you must delete the "
+"file %1$s first."
+
+#. %1$s is a file extension. Example: .exe
+#. %2$s is a comma separated list of extensions. Example: .xpi, .jar
+#: controllers/components/developers.php:355
+#, php-format
+msgid "devcp_error_file_extension"
+msgstr ""
+"Fitxategiaren luzapen hori (%s) ez da onartzen aukeratutako gehigarri "
+"motarentzat. Mesedez erabili ondorengoetako bat: %s"
+
+#: controllers/components/developers.php:64
+msgid "devcp_error_five_categories"
+msgstr "Mesedez aukeratu gehienez ere bost kategoria."
+
+#: controllers/components/developers.php:526
+msgid "devcp_error_guid_application"
+msgstr "Gehigarri onen IDa dagoeneko aplikazio batek darabil."
+
+#: controllers/components/developers.php:337
+#: controllers/components/developers.php:389
+msgid "devcp_error_http_incomplete"
+msgstr "Transferentzia osatugabea"
+
+#: controllers/components/developers.php:335
+#: controllers/components/developers.php:336
+#: controllers/components/developers.php:387
+#: controllers/components/developers.php:388
+msgid "devcp_error_http_maxupload"
+msgstr "Igoera-tamaina maximoa gainditzen du"
+
+#: controllers/components/developers.php:338
+#: controllers/components/developers.php:390
+msgid "devcp_error_http_nofile"
+msgstr "Fitxategirik ez da igo"
+
+#. %1$s is a file extension. Example: .exe
+#. %2$s is a comma separated list of extensions. Example: .xpi, .jar
+#: controllers/components/developers.php:401
+#, php-format
+msgid "devcp_error_icon_extension"
+msgstr ""
+"Fitxategiaren luzapen hori (%s) ez da onartzen ikono batentzat. Mesedez "
+"erabili ondorengoetako bat: %s"
+
+#: controllers/developers_controller.php:504
+msgid "devcp_error_index_rdf_notfound"
+msgstr "Ez dago install.rdf fitxategia."
+
+#: controllers/components/developers.php:601
+msgid "devcp_error_install_manifest"
+msgstr "Ondorengo erroreak aurkitu dira install.rdf fitxategian:"
+
+#: controllers/developers_controller.php:1463
+msgid "devcp_error_invalid_addontype"
+msgstr "Mesedez aukeratu baliozko gehigarri-mota bat."
+
+#. %$1s is a version. Example: 3.1.1
+#. %$2s is an add-on name.
+#: controllers/components/developers.php:569
+#: controllers/components/developers.php:581
+#, php-format
+msgid "devcp_error_invalid_appversion"
+msgstr "%s ez da %s-(r)en baliozko bertsio bat"
+
+#. %s is a string
+#: controllers/components/developers.php:521
+#, php-format
+msgid "devcp_error_invalid_guid"
+msgstr "Gehigarri honen IDa baliogabea da: %s"
+
+#. %$1s is a version. Example: 3.1.1
+#. %$2s is an add-on name.
+#: controllers/components/developers.php:572
+#, php-format
+msgid "devcp_error_invalid_minversion"
+msgstr ""
+"%s ez da %s-(r)en baliozko bertsio bat: bertsio minimoek ezin dute * eduki"
+
+#: controllers/components/developers.php:536
+msgid "devcp_error_invalid_version"
+msgstr ""
+"Gehigarri honen bertsioa baliogabea da: mesedez, ikusi <a href=\"http://"
+"developer.mozilla.org/en/docs/Toolkit_version_format\">zehaztapena</a>"
+
+#: controllers/components/developers.php:531
+msgid "devcp_error_invalid_version_spaces"
+msgstr ""
+"Gehigarri honen bertsioa baliogabea da: bertsioek ezin dituzte zuriuneak "
+"eduki."
+
+#. %s is an error message from the parser.
+#: controllers/components/developers.php:501
+#, php-format
+msgid "devcp_error_manifest_parse"
+msgstr "Ondorengo errorea gertatu da install.rdf fitxategia analizatzean: %s"
+
+#: controllers/components/developers.php:373
+msgid "devcp_error_move_file"
+msgstr "Ezin izan da fitxategia lekuz aldatu"
+
+#. %s is the name of a file
+#: controllers/components/developers.php:650
+#: controllers/components/developers.php:662
+#: controllers/components/developers.php:667
+#: controllers/components/developers.php:727
+#: controllers/components/developers.php:738
+#: controllers/components/developers.php:743
+#, php-format
+msgid "devcp_error_moving_file"
+msgstr "Errore bat gertatu da %s lekuz aldatzean."
+
+#: controllers/components/developers.php:595
+msgid "devcp_error_mozilla_application"
+msgstr "Gutxienez Mozilla helburu-aplikazio bat izan behar duzu."
+
+#: controllers/components/developers.php:516
+msgid "devcp_error_no_guid"
+msgstr "Ezin da IDrik aurkitu gehigarri honentzat install.rdf fitxategian."
+
+#: controllers/components/developers.php:287
+msgid "devcp_error_no_platform"
+msgstr "Ez da plataformarik aukeratu"
+
+#: controllers/components/developers.php:59
+msgid "devcp_error_one_category"
+msgstr "Mesedez aukeratu gutxienez kategoria bat."
+
+#: controllers/components/developers.php:92
+msgid "devcp_error_one_user"
+msgstr "Gutxienez egile bat egon behar da gehigarri honentzat."
+
+#. %1$s is a file extension. Example: .exe
+#. %2$s is a comma separated list of extensions. Example: .xpi, .jar
+#: controllers/components/developers.php:1081
+#, php-format
+msgid "devcp_error_preview_extension"
+msgstr ""
+"Fitxategiaren luzapen hori (%s) ez da onartzen aurrebista batentzat. Mesedez "
+"erabili ondorengoetako bat: %s"
+
+#: controllers/components/developers.php:511
+msgid "devcp_error_updatekey"
+msgstr ""
+"Gehigarriek ezin dute updateKey-rik erabili. Ezaba ezazu install.rdf "
+"fitxategitik eta saia zaitez berriro."
+
+#: controllers/components/developers.php:506
+msgid "devcp_error_updateurl"
+msgstr ""
+"Gehigarriek ezin dute kanpoko updateURL bat erabili. Mesedez ezaba ezazu hau "
+"install.rdf fitxategitik eta saiatu berriro."
+
+#: controllers/developers_controller.php:465
+#: controllers/components/developers.php:271
+msgid "devcp_error_upload_file"
+msgstr "Mesedez igo fitxategi bat."
+
+#: views/developers/uploader.thtml:135
+#, fuzzy
+msgid "devcp_input_upload_file"
+msgstr "Upload File"
+
+#: views/pages/js_constants.js.thtml:89
+#, fuzzy
+msgid "devcp_js_a_cancel"
+msgstr "Cancel"
+
+#: views/pages/js_constants.js.thtml:90
+#, fuzzy
+msgid "devcp_js_add_email"
+msgstr "Please enter the account email of the author you wish to add."
+
+#. alt text for a down-arrow image.
+#: views/pages/js_constants.js.thtml:81
+#, fuzzy
+msgid "devcp_js_img_move_down"
+msgstr "Move Down"
+
+#. alt text for an up-arrow image.
+#: views/pages/js_constants.js.thtml:82
+#, fuzzy
+msgid "devcp_js_img_move_up"
+msgstr "Move Up"
+
+#: views/pages/js_constants.js.thtml:91
+#, fuzzy
+msgid "devcp_js_img_remove_compat"
+msgstr "Remove Application Compatibility"
+
+#: views/pages/js_constants.js.thtml:86
+#, fuzzy
+msgid "devcp_js_input_list_author"
+msgstr "List as author in public listings"
+
+#: views/pages/js_constants.js.thtml:92
+#, fuzzy
+msgid "devcp_js_license_select"
+msgstr "Please select a license."
+
+#: views/pages/js_constants.js.thtml:93
+#, fuzzy
+msgid "devcp_js_license_text"
+msgstr "Please enter text for your license."
+
+#. <option> text in a <select> for Author role in an add-on.
+#: views/pages/js_constants.js.thtml:84
+#, fuzzy
+msgid "devcp_js_option_developer"
+msgstr "Developer"
+
+#. <option> text in a <select> for Author role in an add-on.
+#: views/pages/js_constants.js.thtml:83
+#, fuzzy
+msgid "devcp_js_option_owner"
+msgstr "Owner"
+
+#. <option> text in a <select> for Author role in an add-on.
+#: views/pages/js_constants.js.thtml:85
+#, fuzzy
+msgid "devcp_js_option_viewer"
+msgstr "Viewer"
+
+#: views/pages/js_constants.js.thtml:88
+#, fuzzy
+msgid "devcp_js_remove_author"
+msgstr "Remove Author"
+
+#: views/pages/js_constants.js.thtml:87
+#, fuzzy
+msgid "devcp_js_sure_remove"
+msgstr "Are you <strong>sure</strong> you wish to remove this author?"
+
+#: views/pages/js_constants.js.thtml:77
+#, fuzzy
+msgid "devcp_js_upload_alert"
+msgstr "You must select a file to upload."
+
+#. %1$s is an addon id, like 32.
+#. %2$s is a version number, like 3.5.
+#: controllers/components/developers.php:1212
+#, fuzzy
+msgid "devcp_license_existing"
+msgstr "Custom license for add-on %1$s v%2$s"
+
+#: views/elements/developers/localebox.thtml:44
+msgid "devcp_localebox_header_localizedfields"
+msgstr "Lokalizatutako eremuak"
+
+# %1 is the default locale
+#. %1 is the default locale
+#: views/elements/developers/localebox.thtml:48
+#, php-format
+msgid "devcp_localebox_intro"
+msgstr ""
+"Orri honetako zenbait eremu lokalizatuta daude azken erabiltzailearen ama-"
+"hizkuntzan ager daitezen. Aukeratu behean locale bat hizkuntza horretan zure "
+"gehigarriaren xehetasunak editatzeko. Locale batentzat ezin bada itzulpenik "
+"eskuratu, lehenetsitako locale-a aukeratuko da (%s)."
+
+#: views/elements/developers/sidebar.thtml:68
+#: views/elements/developers/myaddons.thtml:75
+msgid "devcp_myaddons_admincp_link"
+msgstr "Kudeatzailearen tresnak"
+
+#: views/elements/developers/sidebar.thtml:65
+#: views/elements/developers/myaddons.thtml:72
+msgid "devcp_myaddons_editorcp_link"
+msgstr "Editorearen tresnak"
+
+#: views/elements/developers/myaddons.thtml:52
+msgid "devcp_myaddons_link"
+msgstr "Nire gehigarriak"
+
+#: views/elements/developers/sidebar.thtml:70
+#: views/elements/developers/myaddons.thtml:77
+msgid "devcp_myaddons_mainpage_link"
+msgstr "Atzera orri nagusira"
+
+#: views/elements/developers/sidebar.thtml:63
+#: views/elements/developers/myaddons.thtml:70
+msgid "devcp_myaddons_statistics_link"
+msgstr "Estatistiken arbela"
+
+#: views/elements/developers/sidebar.thtml:62
+#: views/elements/developers/myaddons.thtml:69
+msgid "devcp_myaddons_submitaddon_link"
+msgstr "Bidali gehigarria"
+
+#: views/elements/developers/sidebar.thtml:48
+#: views/elements/developers/myaddons.thtml:67
+msgid "devcp_myaddons_title"
+msgstr "Garatzailearen tresnak"
+
+#. %1$s is an add-on ID, perhaps 167.
+#. %2$s is a URL.
+#: controllers/developers_controller.php:256
+#, fuzzy
+msgid "devcp_new_addon_error"
+msgstr ""
+"This add-on ID (%1$s) already exists in the database. If this is your add-"
+"on, you can <a href=\"%2$s\">upload a new version</a>."
+
+#: views/developers/addon_status_nominate.thtml:62
+#, fuzzy
+msgid "devcp_nominate_cancel"
+msgstr "Cancel and return"
+
+# %1 is the addon name
+#. %1 is the add-on name
+#: views/developers/addon_status_nominate.thtml:61
+#, php-format
+msgid "devcp_nominate_submit_nominate"
+msgstr "Proposatu %s"
+
+#: views/developers/addon_edit_properties.thtml:50
+#: views/developers/addon_status.thtml:49
+#: views/developers/versions_edit.thtml:50
+#, fuzzy
+msgid "devcp_notice_changes_error"
+msgstr ""
+"<span>One or more of your changes couldn't be saved.</span><br />Please look "
+"for the errors below. The rest of your changes were successfully saved."
+
+#: views/developers/addon_edit_authors.thtml:47
+#: views/developers/addon_edit_properties.thtml:47
+#: views/developers/addon_status.thtml:46
+#: views/developers/addon_edit_descriptions.thtml:47
+#: views/developers/versions_edit.thtml:47
+#: views/developers/addon_edit_categories.thtml:46
+#, fuzzy
+msgid "devcp_notice_changes_saved"
+msgstr ""
+"<span>Your changes have been saved.</span><br />Please note that some "
+"changes may take several hours to appear in all areas of the website."
+
+#: controllers/previews_controller.php:252
+msgid "devcp_notice_cleardefault"
+msgstr ""
+"Aurrebista lehenetsi bezala kentzeak beste aurrebista bat automatikoki "
+"lehenetsi bezala ezartzea dakar."
+
+#: controllers/previews_controller.php:184
+#: controllers/previews_controller.php:251
+msgid "devcp_notice_makedefault"
+msgstr ""
+"Aurrebista lehenetsi bezala ezartzeak uneko aurrebista lehenetsiari egoera "
+"hori kentzea dakar."
+
+#: views/developers/addon_edit_authors.thtml:70
+#, fuzzy
+msgid "devcp_notice_unsaved_changes"
+msgstr "You have unsaved changes."
+
+#: controllers/developers_controller.php:87
+#: controllers/developers_controller.php:97
+#: controllers/developers_controller.php:100
+#: controllers/previews_controller.php:67
+#: controllers/previews_controller.php:79
+#: controllers/previews_controller.php:82
+msgid "devcp_pagetitle"
+msgstr "Garatzailearen tresnak"
+
+#: controllers/previews_controller.php:103
+#: controllers/previews_controller.php:104
+msgid "devcp_preview_add_pagetitle"
+msgstr "Gehitu aurrebista"
+
+#: controllers/previews_controller.php:135
+msgid "devcp_preview_added_successfully"
+msgstr "Aurrebista arrakastaz gehitu da."
+
+#: controllers/previews_controller.php:323
+msgid "devcp_preview_deleted_successfully"
+msgstr "Aurrebista arrakastaz ezabatu da."
+
+#: controllers/previews_controller.php:194
+#: controllers/previews_controller.php:195
+msgid "devcp_preview_edit_pagetitle"
+msgstr "Editatu aurrebista"
+
+#: controllers/previews_controller.php:237
+msgid "devcp_preview_updated_successfully"
+msgstr "Aurrebista arrakastaz eguneratu da."
+
+#: views/developers/previews.thtml:120
+#, fuzzy
+msgid "devcp_previews_a_another"
+msgstr "Add Another Preview"
+
+#: views/developers/previews.thtml:96
+#, fuzzy
+msgid "devcp_previews_a_delete"
+msgstr "Delete Preview"
+
+#: views/developers/previews.thtml:95
+#, fuzzy
+msgid "devcp_previews_a_replace"
+msgstr "Replace Preview"
+
+#: views/developers/previews.thtml:126
+#, fuzzy
+msgid "devcp_previews_a_update"
+msgstr "Update Previews"
+
+#: views/developers/previews.thtml:115 views/developers/previews.thtml:124
+#, fuzzy
+msgid "devcp_previews_add_new"
+msgstr "Add New Preview"
+
+#. %s is a list of file extensions, e.g. ".png, .gif"
+#: views/developers/previews.thtml:116
+#, fuzzy
+msgid "devcp_previews_add_select"
+msgstr ""
+"Select an image to upload below. Images larger than the maximum size of 700 "
+"pixels wide by 525 pixels tall will be resized. Allowed file types: %s"
+
+#: views/developers/previews.thtml:121
+#, fuzzy
+msgid "devcp_previews_click_below"
+msgstr "Click Update Previews below to upload."
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/previews.thtml:102
+#, fuzzy
+msgid "devcp_previews_click_update"
+msgstr ""
+"Click the Update Previews button below to save this image. (<a %s>Cancel?</"
+"a>)"
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/previews.thtml:107
+#, fuzzy
+msgid "devcp_previews_error_message"
+msgstr ""
+"This preview will be deleted when Update Previews is clicked below. (<a %"
+"s>Cancel?</a>)"
+
+#: views/previews/add.thtml:45
+msgid "devcp_previews_filetype_info"
+msgstr ""
+"Erabili azpiko inprimakia zure gehigarriaren pantaila-argazki bat igotzeko "
+"(PNG, JPG edo GIF). Zabaleran 700 pixel eta alturan 525 pixel baino "
+"gehiagoko irudiak automatikoki aldatuko dira tamainaz."
+
+#: views/previews/add.thtml:43
+msgid "devcp_previews_header_add"
+msgstr "Gehitu aurrebista"
+
+#: views/developers/previews.thtml:80
+#, fuzzy
+msgid "devcp_previews_header_caption"
+msgstr "Preview Caption"
+
+#: views/previews/edit.thtml:43
+msgid "devcp_previews_header_edit"
+msgstr "Editatu aurrebista"
+
+#: views/developers/previews.thtml:93
+#, fuzzy
+msgid "devcp_previews_label_default"
+msgstr "Default Preview"
+
+#: views/previews/add.thtml:54
+msgid "devcp_previews_label_file"
+msgstr "Aurrebistaren fitxategia"
+
+#: views/previews/add.thtml:59 views/previews/edit.thtml:50
+msgid "devcp_previews_label_makedefault"
+msgstr "Ezarri lehenetsitako aurrebista-irudi gisa"
+
+#: views/developers/previews.thtml:100
+#, fuzzy
+msgid "devcp_previews_label_new"
+msgstr "New image:"
+
+#: views/developers/previews.thtml:118
+#, fuzzy
+msgid "devcp_previews_label_upload"
+msgstr "Upload Preview: "
+
+#: views/developers/previews.thtml:50
+#, fuzzy
+msgid "devcp_previews_notice_error"
+msgstr "One or more of your new previews could not be saved."
+
+#: views/developers/previews.thtml:47
+#, fuzzy
+msgid "devcp_previews_notice_success"
+msgstr "Your previews have been updated successfully."
+
+#: views/developers/previews.thtml:59
+#, fuzzy
+msgid "devcp_previews_p_screenshots"
+msgstr ""
+"The preview screenshots for your add-on are shown below. You can make "
+"changes to captions or images below. The Default Preview is the preview that "
+"is displayed next to your add-on in search and browse listings."
+
+#: views/previews/edit.thtml:55
+msgid "devcp_previews_submit_delete"
+msgstr "Ezabatu aurrebista"
+
+#: views/previews/edit.thtml:55
+msgid "devcp_previews_submit_delete_confirm"
+msgstr "Ziur zaude aurrebista hau ezabatu nahi duzula?"
+
+#: views/previews/edit.thtml:54
+msgid "devcp_previews_submit_edit"
+msgstr "Editatu aurrebista"
+
+#: views/previews/add.thtml:63
+msgid "devcp_previews_submit_upload"
+msgstr "Igo aurrebista"
+
+#: views/developers/previews.thtml:78
+#, fuzzy
+msgid "devcp_previews_thumbnail"
+msgstr "Thumbnail"
+
+#. %s is the add-on name.
+#: views/developers/previews.thtml:44
+#, fuzzy
+msgid "devcp_previews_title"
+msgstr "%s Preview Manager"
+
+#: views/developers/uploader.thtml:74
+msgid "devcp_review_agreement_please"
+msgstr ""
+"Mesedez aurreikusi eta onartu ondorengo garatzaile-kontratua aurrera "
+"jarraitu aurretik."
+
+#: views/elements/developers/rolecheck.thtml:42
+#, fuzzy
+msgid "devcp_rolecheck_no_privs"
+msgstr ""
+"<span>You do not have sufficient privileges to make changes on this page.</"
+"span><br />Contact the Add-on Owner if you need to make changes."
+
+#: controllers/developers_controller.php:1315
+#, fuzzy
+msgid "devcp_several_hours"
+msgstr ""
+"Please note that some changes may take several hours to appear in all areas "
+"of the website."
+
+#: views/elements/developers/sidebar.thtml:52
+#, fuzzy
+msgid "devcp_sidebar_a_dashboard"
+msgstr "Dashboard"
+
+#. %s is a number
+#: views/elements/developers/statsbar.thtml:45
+#: views/developers/dashboard.thtml:79
+#, php-format
+msgid "devcp_statsbar_adu"
+msgstr "<em>%s</em> erabiltzaile aktibo egunero"
+
+#. %s is a number
+#: views/elements/developers/statsbar.thtml:41
+#: views/developers/dashboard.thtml:75
+#, php-format
+msgid "devcp_statsbar_total_downloads"
+msgstr "<em>%s</em> deskarga guztira"
+
+#. %s is a number
+#: views/elements/developers/statsbar.thtml:43
+#: views/developers/dashboard.thtml:77
+#, php-format
+msgid "devcp_statsbar_weekly_downloads"
+msgstr "<em>%s</em> deskarga astero"
+
+#: views/developers/addon_status_confirm.thtml:59
+#, fuzzy
+msgid "devcp_status_confirm_active"
+msgstr ""
+"Marking this add-on active will cause it to show up in public areas "
+"appropriate for its status, including search and browse listings. It will be "
+"downloadable from the website and could be returned in client update checks, "
+"depending on its status. You will be able to return here and disable it "
+"again at your convenience."
+
+#: views/developers/addon_status_confirm.thtml:59
+#, fuzzy
+msgid "devcp_status_confirm_active_sure"
+msgstr "Are you sure you wish to mark this add-on active?"
+
+#: views/developers/addon_status_confirm.thtml:50
+#, fuzzy
+msgid "devcp_status_confirm_header_sure"
+msgstr "Are you sure?"
+
+#: views/developers/addon_status_confirm.thtml:55
+#, fuzzy
+msgid "devcp_status_confirm_inactive"
+msgstr ""
+"Marking this add-on inactive will prevent it from showing up in any public "
+"areas, including search and browse listings. It will not be downloadable "
+"from the website and will not be returned in client update checks. You will "
+"be able to return here and re-enable it at your convenience."
+
+#: views/developers/addon_status_confirm.thtml:55
+#, fuzzy
+msgid "devcp_status_confirm_inactive_sure"
+msgstr "Are you sure you wish to mark this add-on inactive?'"
+
+#: views/developers/addon_status_confirm.thtml:74
+#, fuzzy
+msgid "devcp_status_confirm_no"
+msgstr "No, cancel"
+
+#: views/developers/addon_status_confirm.thtml:67
+#, fuzzy
+msgid "devcp_status_confirm_public"
+msgstr ""
+"Making this add-on public will make it available for anyone to download and "
+"will begin offering updates to existing users."
+
+#: views/developers/addon_status_confirm.thtml:67
+#, fuzzy
+msgid "devcp_status_confirm_public_sure"
+msgstr "Are you sure you wish to make this add-on public?"
+
+#: views/developers/addon_status_confirm.thtml:63
+#, fuzzy
+msgid "devcp_status_confirm_sandbox"
+msgstr ""
+"Moving this add-on back to the sandbox will require users to login before "
+"downloading and updates will no longer be offered to existing users. Because "
+"your add-on is currently public, you will be able to return here at any time "
+"to make it public again."
+
+#: views/developers/addon_status_confirm.thtml:63
+#, fuzzy
+msgid "devcp_status_confirm_sandbox_sure"
+msgstr "Are you sure you wish to move this add-on to the sandbox?"
+
+#: views/developers/addon_status_confirm.thtml:73
+#, fuzzy
+msgid "devcp_status_confirm_yes"
+msgstr "Yes, I'm Sure"
+
+#: views/developers/addon_status_nominate.thtml:46
+#, fuzzy
+msgid "devcp_status_nominate_error_notice"
+msgstr ""
+"<span>A nomination message is required.</span><br />Please fill in the text "
+"box with the requested information and try again."
+
+#: views/developers/addon_status_nominate.thtml:55
+#, fuzzy
+msgid "devcp_status_nominate_header"
+msgstr "Add-on Nomination"
+
+#: views/developers/dashboard.thtml:85
+msgid "devcp_summary_lastversion"
+msgstr "Azken bertsioa:"
+
+#. %s is the add-on name.
+#: views/developers/addon_edit.thtml:43
+#: views/developers/addon_edit_authors.thtml:44
+#: views/developers/versions_delete.thtml:43
+#: views/developers/addon_edit_properties.thtml:44
+#: views/developers/addon_edit_descriptions.thtml:44
+#: views/developers/versions_edit.thtml:44
+#: views/developers/addon_edit_categories.thtml:43
+#: views/developers/versions.thtml:43
+#, fuzzy
+msgid "devcp_title_edit_addon"
+msgstr "Edit %s"
+
+#. title attribute for a javascript link that pops up a help dialog.
+#: views/elements/translationbox.thtml:68
+#, fuzzy
+msgid "devcp_transbox_a_title_help"
+msgstr "Help (does not leave page)"
+
+#: views/elements/translationbox.thtml:68
+#, fuzzy
+msgid "devcp_transbox_alt_help"
+msgstr "Help"
+
+#. %1$s is <span>17</span>, %2$s is 42.
+#: views/elements/translationbox.thtml:101
+#, fuzzy
+msgid "devcp_transbox_chars_used"
+msgstr "Characters used: %1$s / %2$s"
+
+#: views/elements/translationbox.thtml:132
+#, fuzzy
+msgid "devcp_transbox_delete_sure"
+msgstr "Are you sure you wish to delete this translation?"
+
+#. %s is a locale, like en-US.
+#: views/elements/translationbox.thtml:143
+#, fuzzy
+msgid "devcp_transbox_help_header_tabs"
+msgstr "What are these %s tabs?"
+
+#: views/elements/translationbox.thtml:145
+#, fuzzy
+msgid "devcp_transbox_help_header_what"
+msgstr "What if I don't have any translations?"
+
+#: views/elements/translationbox.thtml:147
+#, fuzzy
+msgid "devcp_transbox_help_hide"
+msgstr "Hide Help"
+
+#: views/elements/translationbox.thtml:146
+#, fuzzy
+msgid "devcp_transbox_help_if"
+msgstr ""
+"If a user browses the site and a translation isn't available in their own "
+"language, it will fall back to your add-on's Default Locale, specified in "
+"the Edit Add-on Properties area. If you don't have any translations, just "
+"enter what you can into your Default Locale, which should be a language you "
+"speak."
+
+#: views/elements/translationbox.thtml:144
+#, fuzzy
+msgid "devcp_transbox_help_transbox"
+msgstr ""
+"This is a <i>Translation Box</i>. It allows you to localize a specific field "
+"into any other languages for which you might have a translation. You can "
+"add, edit, and remove translations using the locale tabs."
+
+#: views/elements/translationbox.thtml:85
+#, fuzzy
+msgid "devcp_transbox_img_add_trans"
+msgstr "Add Translation"
+
+#: views/elements/translationbox.thtml:86
+#, fuzzy
+msgid "devcp_transbox_img_remove_trans"
+msgstr "Remove Translation"
+
+#: views/elements/translationbox.thtml:123
+#, fuzzy
+msgid "devcp_transbox_input_add_all"
+msgstr "Add Locale to All"
+
+#: views/elements/translationbox.thtml:122
+#, fuzzy
+msgid "devcp_transbox_input_add_locale"
+msgstr "Add Locale"
+
+#: views/elements/translationbox.thtml:124
+#: views/elements/translationbox.thtml:135
+#, fuzzy
+msgid "devcp_transbox_input_cancel"
+msgstr "Cancel"
+
+#: views/elements/translationbox.thtml:134
+#, fuzzy
+msgid "devcp_transbox_input_delete"
+msgstr "Delete It"
+
+#: views/elements/translationbox.thtml:113
+#, fuzzy
+msgid "devcp_transbox_select_locale"
+msgstr "Select the locale of the translation to add:"
+
+#. %1$s and %2$s are GUIDs.
+#: controllers/developers_controller.php:343
+#, fuzzy
+msgid "devcp_update_addon_guid_error"
+msgstr ""
+"The add-on GUID used in this file (%1$s) does not match the existing GUID "
+"for this add-on (%2$s)."
+
+#: controllers/developers_controller.php:334
+#, fuzzy
+msgid "devcp_update_addon_priv_error"
+msgstr "You do not have sufficient privileges to update this add-on."
+
+#. %1$s is a version number, %2$s is an add-on ID.
+#: controllers/developers_controller.php:399
+#, fuzzy
+msgid "devcp_update_addon_version_belong_error"
+msgstr "The specified version (%1$s) does not belong to this add-on (%2$s)."
+
+#. %1$s is a version number, maybe 1.1.
+#. %2$s is a URL.
+#: controllers/developers_controller.php:351
+#, fuzzy
+msgid "devcp_update_addon_version_exists_error"
+msgstr ""
+"The version number uploaded (%1$s) already exists for this add-on. If you "
+"are trying to add another file to this version, <a href=\"%2$s\">click here</"
+"a>."
+
+#. %1$s and %2$s are version numbers.
+#: controllers/developers_controller.php:405
+#, fuzzy
+msgid "devcp_update_addon_version_match_error"
+msgstr ""
+"The uploaded version number (%1$s) does not match the existing version "
+"number (%2$s)."
+
+#: views/developers/uploader.thtml:68
+#, fuzzy
+msgid "devcp_uploader_a_start"
+msgstr "Get Started"
+
+#: views/developers/uploader.thtml:137
+#, fuzzy
+msgid "devcp_uploader_ajax_loading"
+msgstr "Uploading file..."
+
+#: views/developers/uploader.thtml:82
+#, fuzzy
+msgid "devcp_uploader_button_agree"
+msgstr "Agree and continue"
+
+#: views/developers/uploader.thtml:157
+#, fuzzy
+msgid "devcp_uploader_button_edit"
+msgstr "Edit My Add-on"
+
+#: views/developers/uploader.thtml:158
+#, fuzzy
+msgid "devcp_uploader_button_later"
+msgstr "I'll complete my add-on later."
+
+#: views/developers/uploader.thtml:168
+#, fuzzy
+msgid "devcp_uploader_button_release"
+msgstr "Add Release Notes"
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/uploader.thtml:156
+#, fuzzy
+msgid "devcp_uploader_created_results"
+msgstr ""
+"<p>Your add-on listing has been successfully created. The basic information "
+"obtained from your uploaded file has been stored, but there's a lot more to "
+"your listing that can be customized.</p><p>Your add-on is currently marked "
+"as <strong>Incomplete</strong>. In order to complete your add-on, you'll "
+"need to make sure it has an accurate name, summary, and description, as well "
+"as at least one selected category. You can edit your add-on's information "
+"using the link below and check the status of your add-on at any time on the "
+"<a %s>status page</a>."
+
+#: views/developers/uploader.thtml:143
+#, fuzzy
+msgid "devcp_uploader_error_correct"
+msgstr "Please correct this problem and upload your file again."
+
+#. %1$s is a version number, %2$s is a status, e.g Public or Incomplete.
+#: views/developers/uploader.thtml:175
+#, fuzzy
+msgid "devcp_uploader_file_created"
+msgstr ""
+"Your new file has been added to version %1$s and is currently marked as %2$s."
+
+#: views/developers/uploader.thtml:154
+#, fuzzy
+msgid "devcp_uploader_header_created"
+msgstr "Add-on Created!"
+
+#: views/developers/uploader.thtml:141
+#, fuzzy
+msgid "devcp_uploader_header_error"
+msgstr "Oops! There seems to be a problem with this file..."
+
+#: views/developers/uploader.thtml:173
+#, fuzzy
+msgid "devcp_uploader_header_file_added"
+msgstr "File Added!"
+
+#: views/developers/uploader.thtml:66
+#, fuzzy
+msgid "devcp_uploader_header_how"
+msgstr "How does it all work?"
+
+#. %s is the version number, e.g. 3.2.
+#: views/developers/uploader.thtml:163
+#, fuzzy
+msgid "devcp_uploader_header_update_created"
+msgstr "Version %s Created"
+
+#: views/developers/uploader.thtml:117
+#, fuzzy
+msgid "devcp_uploader_header_upload"
+msgstr "Upload Your File"
+
+#: views/developers/uploader.thtml:67
+#, fuzzy
+msgid "devcp_uploader_how"
+msgstr ""
+"<p>Thanks for your interest in submitting your add-on to Mozilla Add-ons. "
+"Hosting your add-on on Mozilla Add-ons is the easiest way to handle "
+"distribution of your add-on. Here's what you'll get:</p><ul><li>Each add-on "
+"will have a public display page with information you provide, such as a "
+"brief summary of the add-on's functionality, an optional longer description, "
+"and a showcase of preview screenshots of your add-on.</li><li>Your add-on "
+"will appear in search and browse listings across the site, and even in the "
+"Add-ons Manager of Firefox 3.</li><li>We'll take care of hosting all of your "
+"downloads and providing automatic updates to users when you upload a new "
+"version.</li><li>You'll have access to a statistics dashboard with detailed "
+"information about your user base.</li></ul><p>Add-ons hosted on the site "
+"must be reviewed by a Mozilla Add-ons Editor before they will have all of "
+"the features listed above. If you're ready to start the process and have "
+"your add-on package ready for upload, just click on Get Started below!</p>"
+
+#: views/developers/uploader.thtml:125
+#, fuzzy
+msgid "devcp_uploader_label_platformtype"
+msgstr "Supported Platforms:"
+
+#: views/developers/uploader.thtml:124
+#, fuzzy
+msgid "devcp_uploader_label_upload_field"
+msgstr "Add-on File: "
+
+#: controllers/components/developers.php:1221
+#, fuzzy
+msgid "devcp_uploader_option_other"
+msgstr "Other"
+
+#. %1$s is a number, %2$s is href="..." and should stay in the <a> tag.
+#: views/developers/uploader.thtml:176
+#, fuzzy
+msgid "devcp_uploader_p_pending_file"
+msgstr ""
+"The new file will be available to the public as soon as an editor is able to "
+"review it. There are currently %1$s other add-ons in the queue. Want to be "
+"reviewed faster? Consider <a %2$s>becoming an editor</a>."
+
+#. %1$s is a number, %2$s is href="..." and should stay in the <a> tag.
+#: views/developers/uploader.thtml:166
+#, fuzzy
+msgid "devcp_uploader_p_pending_version"
+msgstr ""
+"The new version will be available to the public as soon as an editor is able "
+"to review it. There are currently %1$s other add-ons in the queue. Want to "
+"be reviewed faster? Consider <a %2$s>becoming an editor</a>."
+
+#. %s is a status, e.g Public or Incomplete.
+#: views/developers/uploader.thtml:165
+#, fuzzy
+msgid "devcp_uploader_p_update_created"
+msgstr "Your new version has been created and is currently marked as %s."
+
+#. %1$s is href="..." and should stay in the 'Versions and Files' <a> tag.
+#. %2$s is href="..." and should stay in the 'current status' <a> tag.
+#: views/developers/uploader.thtml:177
+#, fuzzy
+msgid "devcp_uploader_p_update_file"
+msgstr ""
+"View your new file in the <a %1$s>Versions and Files page</a>, check out "
+"your add-on's <a %2$s>current status</a>, or <b>add release notes</b> by "
+"clicking the button below (highly recommended)."
+
+#. %1$s is href="..." and should stay in the 'Versions and Files' <a> tag.
+#. %2$s is href="..." and should stay in the 'current status' <a> tag.
+#: views/developers/uploader.thtml:167
+#, fuzzy
+msgid "devcp_uploader_p_update_version"
+msgstr ""
+"View your new version in the <a %1$s>Versions and Files page</a>, check out "
+"your add-on's <a %2$s>current status</a>, or <b>add release notes</b> by "
+"clicking the button below (highly recommended)."
+
+#: views/developers/uploader.thtml:118
+#, fuzzy
+msgid "devcp_uploader_p_upload"
+msgstr ""
+"Upload your add-on file using the form below. If you have multiple, platform-"
+"specific files to upload, choose a single file and then upload the others "
+"using the Versions and Files Manager."
+
+#: views/developers/uploader.thtml:125
+#, fuzzy
+msgid "devcp_uploader_platformtype_all"
+msgstr "All"
+
+#: views/developers/uploader.thtml:126
+#, fuzzy
+msgid "devcp_uploader_platformtype_specific"
+msgstr "Specific:"
+
+#. Used as first item in a <select>.
+#: controllers/components/developers.php:1185
+#, fuzzy
+msgid "devcp_uploader_please_choose"
+msgstr "Please Choose..."
+
+#. %1$s is the add-on name, %2$s is the version number.
+#: views/developers/uploader.thtml:57
+#, fuzzy
+msgid "devcp_uploader_title_file"
+msgstr "Add File to %1$s %2$s"
+
+#: views/developers/uploader.thtml:50
+#, fuzzy
+msgid "devcp_uploader_title_submit"
+msgstr "Submit New Add-on"
+
+#. %s is the add-on name.
+#: views/developers/uploader.thtml:54
+#, fuzzy
+msgid "devcp_uploader_title_update"
+msgstr "Update %s"
+
+#. %s is a full <a> tag
+#: controllers/developers_controller.php:503
+#, php-format
+msgid "devcp_valid_app_reference"
+msgstr "Mesedez ikusi %s erreferentziarako."
+
+#. This is the text in the <a> tag for devcp_valid_app_reference. This should be
+#. fixed.
+#: controllers/developers_controller.php:503
+msgid "devcp_valid_app_reference_linktext"
+msgstr "orri hau"
+
+#: controllers/developers_controller.php:581
+#, fuzzy
+msgid "devcp_verify_author_error"
+msgstr "No account found for that email address."
+
+#: controllers/developers_controller.php:553
+#, fuzzy
+msgid "devcp_verify_search_engine_error"
+msgstr ""
+"Either the XML is invalid or required fields are missing. Please <a href="
+"\"https://developer.mozilla.org/en/Creating_OpenSearch_plugins_for_Firefox"
+"\">read the documentation</a>, verify your add-on, and try again."
+
+#: views/developers/versions.thtml:75
+#, fuzzy
+msgid "devcp_versions_a_cancel"
+msgstr "Cancel"
+
+#: views/developers/versions.thtml:79
+#, fuzzy
+msgid "devcp_versions_a_delete"
+msgstr "Delete Version"
+
+#: views/developers/versions.thtml:74
+#, fuzzy
+msgid "devcp_versions_a_empty"
+msgstr "Remove Empty Version"
+
+#: views/developers/versions.thtml:71
+#, fuzzy
+msgid "devcp_versions_a_remove"
+msgstr "Remove?"
+
+#: views/developers/versions.thtml:91
+#, fuzzy
+msgid "devcp_versions_add"
+msgstr "Add New Version"
+
+#: views/developers/versions_delete.thtml:58
+#, fuzzy
+msgid "devcp_versions_delete_a_cancel"
+msgstr "Cancel"
+
+#: views/developers/versions_delete.thtml:56
+#, fuzzy
+msgid "devcp_versions_delete_a_delete"
+msgstr "Delete Version"
+
+#. Followed by a list of reviews and files that will be removed.
+#: views/developers/versions_delete.thtml:50
+#, fuzzy
+msgid "devcp_versions_delete_also"
+msgstr "This will also delete:"
+
+#: views/developers/versions_delete.thtml:53
+#, fuzzy
+msgid "devcp_versions_delete_files"
+msgid_plural "devcp_versions_delete_files"
+msgstr[0] "%s file"
+msgstr[1] "%s files"
+
+#. %s is the version number.
+#: views/developers/versions_delete.thtml:48
+#, fuzzy
+msgid "devcp_versions_delete_header"
+msgstr "Delete Version %s?"
+
+#: views/developers/versions_delete.thtml:52
+#, fuzzy
+msgid "devcp_versions_delete_reviews"
+msgid_plural "devcp_versions_delete_reviews"
+msgstr[0] "%s review"
+msgstr[1] "%s reviews"
+
+#. %s is the version number.
+#: views/developers/versions_delete.thtml:49
+#, fuzzy
+msgid "devcp_versions_delete_sure"
+msgstr "Are you sure you want to permanently delete version %s?"
+
+#: views/developers/versions_edit.thtml:102
+#: views/developers/versions_edit.thtml:155
+#, fuzzy
+msgid "devcp_versions_edit_a_cancel"
+msgstr "Cancel"
+
+#: views/developers/versions_edit.thtml:101
+#, fuzzy
+msgid "devcp_versions_edit_a_delete"
+msgstr "Delete File"
+
+#: views/developers/versions_edit.thtml:165
+#, fuzzy
+msgid "devcp_versions_edit_a_new_app"
+msgstr "Add New Application"
+
+#: views/developers/versions_edit.thtml:154
+#, fuzzy
+msgid "devcp_versions_edit_a_remove_app"
+msgstr "Remove Application"
+
+#: views/developers/versions_edit.thtml:114
+#, fuzzy
+msgid "devcp_versions_edit_add"
+msgstr "Add New File"
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/versions_edit.thtml:121
+#, fuzzy
+msgid "devcp_versions_edit_adjust"
+msgstr ""
+"Adjusting application information here will allow users to install your add-"
+"on even if the install.rdf in the package indicates that the add-on is "
+"incompatible. <a %s>List of supported applications</a>"
+
+#: views/developers/versions_edit.thtml:153
+#, fuzzy
+msgid "devcp_versions_edit_compat_sure"
+msgstr ""
+"Are you <b>sure</b> you wish to remove compatibility with this application?"
+
+#: views/developers/versions_edit.thtml:100
+#, fuzzy
+msgid "devcp_versions_edit_delete_sure"
+msgstr "Are you <b>sure</b> you wish to permanently delete this file?"
+
+#: views/developers/versions_edit.thtml:203
+#, fuzzy
+msgid "devcp_versions_edit_header_approval"
+msgstr "Approval Information"
+
+#: views/developers/versions_edit.thtml:120
+#, fuzzy
+msgid "devcp_versions_edit_header_compat"
+msgstr "Compatible Applications"
+
+#: views/developers/versions_edit.thtml:74
+#, fuzzy
+msgid "devcp_versions_edit_header_file"
+msgstr "File Information"
+
+#: views/developers/versions_edit.thtml:189
+#, fuzzy
+msgid "devcp_versions_edit_header_license"
+msgstr "License"
+
+#. %s is the version number.
+#: views/developers/versions_edit.thtml:53
+#, fuzzy
+msgid "devcp_versions_edit_header_manage"
+msgstr "Manage Version %s"
+
+#: views/developers/versions_edit.thtml:212
+#, fuzzy
+msgid "devcp_versions_edit_header_notes"
+msgstr "Approval Notes"
+
+#: views/developers/versions_edit.thtml:98
+#, fuzzy
+msgid "devcp_versions_edit_img_delete"
+msgstr "Delete File"
+
+#. %1$s is the file id, e.g. 18723.
+#. %2$s is the platform name, e.g. ALL or Windows.
+#. %3$s is the _('date) created.
+#. %4$s is the status, e.g. "In Sandbox" or "Public".
+#. %5$s is the _('date') status was changed.
+#: views/developers/versions_edit.thtml:208
+#, fuzzy
+msgid "devcp_versions_edit_li_file"
+msgstr "File %1$s (%2$s) created on %3$s and changed to %4$s on %5$s"
+
+#: views/developers/versions_edit.thtml:190
+#, fuzzy
+msgid "devcp_versions_edit_license_description"
+msgstr ""
+"Please select the appropriate license for your add-on. This license "
+"specifies the rights you grant on your source code."
+
+#: views/developers/versions_edit.thtml:111
+#, fuzzy
+msgid "devcp_versions_edit_no_files"
+msgstr "No files found."
+
+#: views/developers/versions_edit.thtml:213
+#, fuzzy
+msgid "devcp_versions_edit_optional"
+msgstr "Optional information for the Editor that reviews this version."
+
+#: views/developers/versions_edit.thtml:151
+#, fuzzy
+msgid "devcp_versions_edit_remove_compat"
+msgstr "Remove Application Compatibility"
+
+#: views/developers/versions_edit.thtml:167
+#, fuzzy
+msgid "devcp_versions_edit_select_app"
+msgstr "Please Select an Application"
+
+#: views/developers/versions_edit.thtml:78
+#, fuzzy
+msgid "devcp_versions_edit_th_file"
+msgstr "File"
+
+#: views/developers/versions_edit.thtml:79
+#, fuzzy
+msgid "devcp_versions_edit_th_platform"
+msgstr "Platform"
+
+#: views/developers/versions_edit.thtml:80
+#, fuzzy
+msgid "devcp_versions_edit_th_size"
+msgstr "Size"
+
+#: views/developers/versions_edit.thtml:81
+#, fuzzy
+msgid "devcp_versions_edit_th_status"
+msgstr "Status"
+
+#: views/developers/versions_edit.thtml:183
+#, fuzzy
+msgid "devcp_versions_edit_transbox_releasenotes_description"
+msgstr ""
+"Information about changes in this release, new features, known bugs, and "
+"other useful information specific to this release/version. This information "
+"will also be available to users updating the add-on in the Firefox 3 Add-ons "
+"Manager interface."
+
+#: views/developers/versions_edit.thtml:182
+#, fuzzy
+msgid "devcp_versions_edit_transbox_releasenotes_name"
+msgstr "Release Notes"
+
+#: views/developers/versions_edit.thtml:164
+#, fuzzy
+msgid "devcp_versions_edit_unsaved_compat"
+msgstr ""
+"<strong>You have unsaved changes.</strong> Compatibility will not be deleted "
+"until you click Update Version below."
+
+#: views/developers/versions_edit.thtml:113
+#, fuzzy
+msgid "devcp_versions_edit_unsaved_files"
+msgstr ""
+"<strong>You have unsaved changes.</strong> Files will not be deleted until "
+"you click Update Version below."
+
+#: views/developers/versions_edit.thtml:218
+#, fuzzy
+msgid "devcp_versions_edit_update"
+msgstr "Update Versions"
+
+#: views/developers/versions.thtml:49
+#, fuzzy
+msgid "devcp_versions_header_manage"
+msgstr "Manage Versions and Files"
+
+#: views/developers/versions.thtml:87
+#, fuzzy
+msgid "devcp_versions_no_versions"
+msgstr "No versions."
+
+#. %s is a version number, base 10.
+#: views/developers/versions.thtml:46
+#, fuzzy
+msgid "devcp_versions_notice_success"
+msgstr "Version %s deleted successfully."
+
+#: views/developers/versions.thtml:73
+#, fuzzy
+msgid "devcp_versions_p_remove"
+msgstr ""
+"This version has no files associated with it and can be removed. Would you "
+"like to remove this version?"
+
+#: views/developers/versions.thtml:58
+#, fuzzy
+msgid "devcp_versions_th_created"
+msgstr "Created"
+
+#: views/developers/versions.thtml:57
+#, fuzzy
+msgid "devcp_versions_th_status"
+msgstr "Status"
+
+#: views/developers/versions.thtml:56
+#, fuzzy
+msgid "devcp_versions_th_version"
+msgstr "Version"
+
+#: controllers/downloads_controller.php:91
+msgid "downloads_disable_warning"
+msgstr "Gehigarri hau ezgaituta dago"
+
+#: controllers/components/editors.php:57
+#, fuzzy
+msgid "editor_review_error_addon_not_nominated"
+msgstr "This add-on has not been nominated."
+
+#: controllers/components/editors.php:213
+#, fuzzy
+msgid "editor_review_error_file_not_pending"
+msgstr "This file is not pending review."
+
+#. Actions are, for example: approving or rejecting
+#: controllers/components/editors.php:79
+#: controllers/components/editors.php:182
+#, fuzzy
+msgid "editor_review_error_no_action"
+msgstr "Please select a review action."
+
+#: controllers/components/editors.php:192
+#, fuzzy
+msgid "editor_review_error_no_applications"
+msgstr "Please enter the applications you tested."
+
+#. Comments are required when an editor approves or rejects an add-on.
+#: controllers/components/editors.php:84
+#: controllers/components/editors.php:187
+#, fuzzy
+msgid "editor_review_error_no_comments"
+msgstr "Please enter review comments."
+
+#: controllers/components/editors.php:161
+#, fuzzy
+msgid "editor_review_error_no_files"
+msgstr "Please select at least one file to review."
+
+#: controllers/components/editors.php:197
+#, fuzzy
+msgid "editor_review_error_no_operating_system"
+msgstr "Please enter the operating systems you tested."
+
+#: views/editors/logs.thtml:51
+msgid "editorcp_logs_button_filter"
+msgstr "Iragazkia"
+
+#: views/editors/logs.thtml:44
+msgid "editorcp_logs_filter_by"
+msgstr "Iragazkia motaren/ekintzaren arabera"
+
+#: views/editors/logs.thtml:42 controllers/editors_controller.php:964
+msgid "editorcp_logs_page_heading"
+msgstr "Gertaeren log-a"
+
+#: views/elements/developers/editorsmenu.thtml:60
+msgid "editorcp_menu_eventlog_link"
+msgstr "Gertaeren log-a"
+
+#: views/elements/developers/editorsmenu.thtml:62
+msgid "editorcp_menu_mainpage_link"
+msgstr "Atzera orri nagusira"
+
+#: views/elements/developers/editorsmenu.thtml:61
+msgid "editorcp_menu_reviewlog_link"
+msgstr "Berrikusi log-a"
+
+#: views/elements/developers/editorsmenu.thtml:55
+msgid "editorcp_menu_summary_link"
+msgstr "Editorearen laburpena"
+
+#: views/elements/developers/editorsmenu.thtml:52
+msgid "editorcp_menu_title"
+msgstr "Editorearen tresnak"
+
+#: views/editors/reviewlog.thtml:49
+msgid "editorcp_reviewlog_button_filter"
+msgstr "Iragazkia"
+
+#: views/editors/reviewlog.thtml:58
+msgid "editorcp_reviewlog_column_action"
+msgstr "Ekintza"
+
+#: views/editors/reviewlog.thtml:56
+msgid "editorcp_reviewlog_column_addon"
+msgstr "Gehigarria"
+
+#: views/editors/reviewlog.thtml:55
+msgid "editorcp_reviewlog_column_date"
+msgstr "Data"
+
+#: views/editors/reviewlog.thtml:57
+msgid "editorcp_reviewlog_column_editor"
+msgstr "Editorea"
+
+#: views/editors/reviewlog.thtml:94
+msgid "editorcp_reviewlog_comments_hide"
+msgstr "Ezkutatu iruzkinak"
+
+#: views/editors/reviewlog.thtml:93
+msgid "editorcp_reviewlog_comments_show"
+msgstr "Erakutsi iruzkinak"
+
+#. %1$s and %2$s are full <input> tags for dates
+#: views/editors/reviewlog.thtml:45
+#, php-format
+msgid "editorcp_reviewlog_entries_between"
+msgstr "Ikusi %s eta %s arteko sarrerak"
+
+#: views/editors/reviewlog.thtml:104
+msgid "editorcp_reviewlog_none_found"
+msgstr "Ez da berrikuspenik aurkitu periodo honetarako."
+
+#: views/editors/reviewlog.thtml:42
+msgid "editorcp_reviewlog_page_heading"
+msgstr "Berrikuspenen log-a"
+
+#: views/editors/summary.thtml:61
+msgid "editorcp_summary_monthreviews_heading"
+msgstr "Hilabeteko berrikuspenak"
+
+#: views/editors/summary.thtml:77
+msgid "editorcp_summary_neweditors_heading"
+msgstr "Editore berriak"
+
+#: views/editors/summary.thtml:42
+msgid "editorcp_summary_page_heading"
+msgstr "Editorearen laburpena"
+
+#: views/editors/summary.thtml:94
+msgid "editorcp_summary_recentactivity_heading"
+msgstr "Editorearen azken ekintzak"
+
+#: views/editors/summary.thtml:45
+msgid "editorcp_summary_totalreviews_heading"
+msgstr "Berrikuspenak guztira"
+
+#: controllers/editors_controller.php:248
+#: controllers/editors_controller.php:249
+msgid "editors_addon_review_pagetitle"
+msgstr "Ikuskatu Gehigarria"
+
+#: controllers/editors_controller.php:349
+msgid "editors_error_js-formerror"
+msgstr "Mesedez osatu ondorengo eremuak:"
+
+#: controllers/editors_controller.php:350
+msgid "editors_error_review_one_file"
+msgstr "Mesedez aukeratu gutxienez ikuskatzeko fitxategi bat."
+
+#: controllers/editors_controller.php:274
+msgid "editors_error_self_reviews_forbidden"
+msgstr "Norbere ikuskapenak ez dira onartzen."
+
+#: controllers/editors_controller.php:699
+msgid "editors_external_software"
+msgstr "Kanpoko softwarea"
+
+#: views/editors/featured.thtml:120 views/editors/featured.thtml:121
+msgid "editors_featured_add_feature"
+msgstr "Gehitu ezaugarria"
+
+#: views/editors/featured.thtml:126
+msgid "editors_featured_add_feature_submit"
+msgstr "Gehitu"
+
+#: views/editors/featured.thtml:49 controllers/editors_controller.php:832
+#: controllers/editors_controller.php:848
+msgid "editors_featured_addon_add_failure"
+msgstr "Ezaugarria gehitzeak huts egin du."
+
+#: controllers/editors_controller.php:851
+msgid "editors_featured_addon_add_success"
+msgstr "Ezaugarria ongi gehitu da."
+
+#: views/editors/featured.thtml:50 controllers/editors_controller.php:839
+#: controllers/editors_controller.php:868
+#: controllers/editors_controller.php:886
+msgid "editors_featured_addon_edit_failure"
+msgstr "Ezaugarria editatzeak huts egin du."
+
+#: views/editors/featured.thtml:51 controllers/editors_controller.php:888
+msgid "editors_featured_addon_edit_success"
+msgstr "Ezaugarria ongi editatu da."
+
+#: views/editors/featured.thtml:53 controllers/editors_controller.php:861
+msgid "editors_featured_addon_invalid_locale"
+msgstr "Locale bat edo gehiago baliogabeak dira."
+
+#: views/editors/featured.thtml:52 controllers/editors_controller.php:906
+msgid "editors_featured_addon_remove_failure"
+msgstr "Ezaugarria ezabatzeak huts egin du."
+
+#: controllers/editors_controller.php:901
+msgid "editors_featured_addon_remove_success"
+msgstr "Ezaugarria ongi ezabatu da."
+
+#: controllers/editors_controller.php:915
+#: controllers/editors_controller.php:917
+msgid "editors_featured_addons_pagetitle"
+msgstr "Nabarmendutako gehigarriak"
+
+#: views/editors/featured.thtml:54 views/editors/featured.thtml:107
+msgid "editors_featured_edit_feature_submit"
+msgstr "Joan"
+
+#: views/editors/featured.thtml:90 views/editors/featured.thtml:91
+msgid "editors_featured_remove_feature"
+msgstr "Ezabatu ezaugarria"
+
+#: views/editors/queue.thtml:46
+msgid "editors_filter_queue"
+msgstr "Iragazi ilara"
+
+#: views/editors/queue.thtml:182
+msgid "editors_helpful_links"
+msgstr "Lotura lagungarriak"
+
+#: views/editors/queue.thtml:182
+msgid "editors_link_guide"
+msgstr "Editorearen gida"
+
+#: views/editors/queue.thtml:182
+msgid "editors_link_policy"
+msgstr "Gehigarrien politika"
+
+#: views/editors/queue.thtml:47
+msgid "editors_notice_filter_session"
+msgstr "Iragazki hauek saio hau bukatu arte edo garbitu arte mantenduko dira."
+
+# %1 is the queue mode
+#. %1 is the queue mode
+#: views/editors/queue.thtml:177 views/admin/flagged_queue.thtml:89
+msgid "editors_notice_none_found"
+msgstr "Ez dago mota horretako gehigarririk berrikusteko."
+
+#: controllers/editors_controller.php:1040
+msgid "editors_one_day"
+msgstr "egun bat"
+
+#: controllers/editors_controller.php:1048
+msgid "editors_one_hour"
+msgstr "ordu bat"
+
+#: controllers/editors_controller.php:1056
+msgid "editors_one_minute"
+msgstr "minutu bat"
+
+#: controllers/editors_controller.php:64 controllers/editors_controller.php:73
+#: controllers/editors_controller.php:77
+msgid "editors_pagetitle"
+msgstr "Editorearen tresnak"
+
+#. %s is a comma separated list of platforms. Example: Windows, OS X
+#: controllers/editors_controller.php:680
+#: controllers/editors_controller.php:683
+#, php-format
+msgid "editors_platform_x_only"
+msgstr "%s bakarrik"
+
+#: controllers/editors_controller.php:695
+msgid "editors_pre-release"
+msgstr "Aurreargitalpena"
+
+# %1 is the app name
+#. %1 is the app name
+#: views/editors/queue.thtml:131
+#, php-format
+msgid "editors_queue_app_compatibility"
+msgstr "%s bateragarritasuna"
+
+#: views/editors/queue.thtml:51
+#, fuzzy
+msgid "editors_queue_filter_label_addon"
+msgstr "Add-on or Author Email"
+
+#: views/editors/queue.thtml:72
+#, fuzzy
+msgid "editors_queue_filter_label_addontypes"
+msgstr "Add-on Types"
+
+#: views/editors/queue.thtml:56
+#, fuzzy
+msgid "editors_queue_filter_label_application"
+msgstr "Application"
+
+#: views/editors/queue.thtml:61
+#, fuzzy
+msgid "editors_queue_filter_label_maxversion"
+msgstr "Max. Version"
+
+#: views/editors/queue.thtml:78
+#, fuzzy
+msgid "editors_queue_filter_label_platforms"
+msgstr "Platforms"
+
+#: views/editors/queue.thtml:66
+#, fuzzy
+msgid "editors_queue_filter_label_submissionage"
+msgstr "Age of Submission (days)"
+
+#. %1$s is a number
+#: views/editors/queue.thtml:90
+#, fuzzy
+msgid "editors_queue_filter_result_count"
+msgid_plural "editors_queue_filter_result_count"
+msgstr[0] "Results of your filtered search: <strong>%1$s</strong> Add-on"
+msgstr[1] "Results of your filtered search: <strong>%1$s</strong> Add-ons"
+
+#: views/editors/queue.thtml:84
+msgid "editors_queue_submit_clean"
+msgstr "Garbitu"
+
+#: views/editors/queue.thtml:83
+msgid "editors_queue_submit_filter"
+msgstr "Iragazkia"
+
+#: controllers/editors_controller.php:133
+msgid "editors_queues_disabled"
+msgstr ""
+"Ikuskapen-ilara guztiak ezgaituta daude momentuz. Mesedez beranduago "
+"egiaztatu."
+
+#: views/editors/review.thtml:149
+#, fuzzy
+msgid "editors_review_a_edit_item"
+msgstr "Edit Item"
+
+#: views/editors/review.thtml:146
+#, fuzzy
+msgid "editors_review_a_item_history"
+msgstr "Item History"
+
+#: views/editors/review.thtml:148
+#, fuzzy
+msgid "editors_review_a_item_homepage"
+msgstr "Item Homepage"
+
+#: views/editors/review.thtml:145
+#, fuzzy
+msgid "editors_review_a_item_overview"
+msgstr "Item Overview"
+
+#: views/editors/review.thtml:147
+#, fuzzy
+msgid "editors_review_a_previews"
+msgstr "Previews"
+
+#: controllers/editors_controller.php:345
+msgid "editors_review_action"
+msgstr "Ikuskapen ekintza"
+
+#: views/editors/review.thtml:159
+#, fuzzy
+msgid "editors_review_action_info"
+msgstr "Request More Information"
+
+#: views/editors/review.thtml:157
+msgid "editors_review_action_public"
+msgstr "Publiko izatea Eskatu"
+
+#: views/editors/review.thtml:160
+msgid "editors_review_action_request_superreview"
+msgstr "Eskatu super-ikuskapena"
+
+#: views/editors/review.thtml:158
+msgid "editors_review_action_sandbox"
+msgstr "Mantendu probagunean"
+
+#: controllers/editors_controller.php:346
+msgid "editors_review_comments"
+msgstr "Ikuskapen-iruzkinak"
+
+#: views/editors/review.thtml:182
+#, fuzzy
+msgid "editors_review_details_info_request"
+msgstr ""
+"Use this form to request more information from the author. They will receive "
+"an email and be able to answer here. You will be notified by email when they "
+"reply."
+
+#: views/editors/review.thtml:174
+msgid "editors_review_details_nominated_public"
+msgstr ""
+"Honek gehigarria gehigarria eta honen bertsiorik berrienaren fitxategiak "
+"publiko gisa ezarriko ditu. Etorkizuneko bertsioak hondar-kutxara joango "
+"dira editore batek ikuskatu arte."
+
+#: views/editors/review.thtml:177
+msgid "editors_review_details_nominated_sandbox"
+msgstr "Honek gehigarria probagunean mantenduko du."
+
+#: views/editors/review.thtml:166
+msgid "editors_review_details_pending_public"
+msgstr ""
+"Honek gehigarri publiko baten probagunera bidalitako bertsioa onartuko du "
+"alde publikoak ager dadin."
+
+#: views/editors/review.thtml:169
+msgid "editors_review_details_pending_sandbox"
+msgstr ""
+"Honek gehigarri publiko baten probagunera bidalitako bertsioa probagunean "
+"mantenduko du."
+
+#: views/editors/review.thtml:185
+msgid "editors_review_details_superreview"
+msgstr ""
+"Inolako kezkarik izanez gero gehigarri honen segurtasunarekin, "
+"copyrightarekin edo kudeatzaile batek arakatu beharko lukeen beste edozein "
+"gauza ikusiz gero, idatzi zure iruzkinak azpiko eremuan. Iruzkinak "
+"kudeatzaileei bidaliko zaizkie, ez egileei."
+
+#: views/editors/review.thtml:134
+#, fuzzy
+msgid "editors_review_file_diff_link"
+msgstr "Compare with public version"
+
+#: views/editors/review.thtml:131
+msgid "editors_review_file_viewcontents_link"
+msgstr "Ikusi edukiak"
+
+#: views/editors/review.thtml:65
+msgid "editors_review_header_authors"
+msgstr "Egileak:"
+
+#: views/editors/review.thtml:79
+msgid "editors_review_header_categories"
+msgstr "Kategoriak:"
+
+#: views/editors/review.thtml:92
+msgid "editors_review_header_compatibility"
+msgstr "Bateragarritasuna:"
+
+#: views/editors/review.thtml:251
+msgid "editors_review_header_description"
+msgstr "Azalpena"
+
+#: views/editors/review.thtml:275
+msgid "editors_review_header_devcomments"
+msgstr "Garatzailearen iruzkinak"
+
+#: views/editors/review.thtml:263
+msgid "editors_review_header_eula"
+msgstr "AELK"
+
+#: views/editors/review.thtml:115
+msgid "editors_review_header_files"
+msgstr "Fitxategiak:"
+
+#: views/editors/review.thtml:284
+msgid "editors_review_header_itemhistory"
+msgstr "Elementuaren historia"
+
+#: views/editors/review.thtml:232
+msgid "editors_review_header_nominationmessage"
+msgstr "Proposamen-mezua"
+
+#: views/editors/review.thtml:311
+msgid "editors_review_header_previews"
+msgstr "Aurrebistak"
+
+#: views/editors/review.thtml:269
+msgid "editors_review_header_privacy"
+msgstr "Pribatutasun-politika"
+
+# %1 is the addon name and version
+#. %1 is the add-on name and version
+#: views/editors/review.thtml:56
+#, php-format
+msgid "editors_review_header_review"
+msgstr "Ikuskatu %s"
+
+#: views/editors/review.thtml:239
+msgid "editors_review_header_reviewernotes"
+msgstr "Ikuskatzailearentzat oharrak"
+
+#: views/editors/review.thtml:245
+msgid "editors_review_header_summary"
+msgstr "Laburpena"
+
+#: views/editors/review.thtml:257
+msgid "editors_review_header_versionnotes"
+msgstr "Bertsio-oharrak"
+
+#. a noun: shown in an add-on's editor review history
+#: views/elements/developers/editors_review_history_item.thtml:80
+#, fuzzy
+msgid "editors_review_history_info_reply"
+msgstr "Reply"
+
+#: views/elements/developers/editors_review_history_item.thtml:78
+#, fuzzy
+msgid "editors_review_history_info_request"
+msgstr "Information Request"
+
+#: views/elements/developers/editors_review_history_item.thtml:62
+#: views/editors/reviewlog.thtml:77
+msgid "editors_review_history_nominated_adminreview"
+msgstr "Kudeatzailearen berrikuspena"
+
+#: views/elements/developers/editors_review_history_item.thtml:56
+#: views/editors/reviewlog.thtml:71
+msgid "editors_review_history_nominated_approved"
+msgstr "Proposamena Onartuta/Publikoa"
+
+#: views/elements/developers/editors_review_history_item.thtml:59
+#: views/editors/reviewlog.thtml:74
+msgid "editors_review_history_nominated_denied"
+msgstr "Proposamen ukatua/probagunea"
+
+#: views/editors/review.thtml:303
+msgid "editors_review_history_nonefound"
+msgstr "Ezin da aurreko berrikuspen sarrerarik aurkitu."
+
+#: views/elements/developers/editors_review_history_item.thtml:73
+#: views/editors/reviewlog.thtml:88
+msgid "editors_review_history_pending_adminreview"
+msgstr "Kudeatzailearen berrikuspena"
+
+#: views/elements/developers/editors_review_history_item.thtml:67
+#: views/editors/reviewlog.thtml:82
+msgid "editors_review_history_pending_approved"
+msgstr "Onartua/Publikoa"
+
+#: views/elements/developers/editors_review_history_item.thtml:70
+#: views/editors/reviewlog.thtml:85
+msgid "editors_review_history_pending_denied"
+msgstr "Ukatua/Probagunea"
+
+#. link text in an add-on's editor review history, allowing to hide and show an information request's replies
+#. %1 is the number of replies
+#: views/elements/developers/editors_review_history_item.thtml:90
+#, fuzzy
+msgid "editors_review_history_show_hide_replies"
+msgid_plural "editors_review_history_show_hide_replies"
+msgstr[0] "Show/Hide Replies (%1$s)"
+msgstr[1] "Show/Hide Replies (%1$s)"
+
+#: views/editors/review.thtml:208
+msgid "editors_review_label_applications"
+msgstr "Aplikazioak:"
+
+#: views/editors/review.thtml:196
+msgid "editors_review_label_cannedresponse"
+msgstr "edo aukeratu erantzun finkoa:"
+
+#: views/editors/review.thtml:190
+msgid "editors_review_label_comments"
+msgstr "Iruzkinak:"
+
+#: views/editors/review.thtml:204
+msgid "editors_review_label_operating_systems"
+msgstr "Sistema eragileak:"
+
+#: views/editors/review.thtml:285 views/editors/review.thtml:312
+msgid "editors_review_link_pagetop"
+msgstr "Goialdean"
+
+#: views/editors/review.thtml:141
+#, fuzzy
+msgid "editors_review_mulitple_notice"
+msgstr ""
+"Notice: Only review more than one file if you have tested EVERY file you "
+"select."
+
+#: views/editors/review.thtml:51
+#, fuzzy
+msgid "editors_review_next_link"
+msgstr "next &raquo;"
+
+#: views/editors/review.thtml:322
+msgid "editors_review_previews_notfound"
+msgstr "Ez da aurrebistarik aurkitu."
+
+#: views/editors/review.thtml:50
+#, fuzzy
+msgid "editors_review_previous_link"
+msgstr "&laquo; prev"
+
+#: controllers/editors_controller.php:144
+#: controllers/editors_controller.php:146
+msgid "editors_review_queue_pagetitle"
+msgstr "Berrikuspenen ilara"
+
+# %1 is the add-ons rank in the queue, %2 is the total queue length
+#. %1 is the add-ons rank in the queue, %2 is the total queue length
+#: views/editors/review.thtml:47
+#, fuzzy
+msgid "editors_review_rank_in_queue"
+msgstr "<strong># %1$s</strong> of %2$s in queue"
+
+#. %1 is the add-ons rank in the queue, %2 is the total queue length. Both numbers
+#: views/editors/review.thtml:45
+#, fuzzy
+msgid "editors_review_rank_in_queue_filtered"
+msgstr "<strong># %1$s</strong> of %2$s in queue (filtered)"
+
+#: views/editors/review.thtml:223
+msgid "editors_review_submit_process_action"
+msgstr "Prozesatu ekintza"
+
+#: views/editors/review.thtml:293
+msgid "editors_review_th_action"
+msgstr "Ekintza"
+
+#: views/editors/review.thtml:294
+msgid "editors_review_th_comments"
+msgstr "Iruzkinak"
+
+#: views/editors/review.thtml:291
+msgid "editors_review_th_date"
+msgstr "Data"
+
+#: views/editors/review.thtml:292
+msgid "editors_review_th_reviewer"
+msgstr "Ikuskatzailea"
+
+#: views/editors/review.thtml:290
+msgid "editors_review_th_version_file"
+msgstr "Bertsioa/Fitxategia"
+
+#: views/editors/review.thtml:217
+#, fuzzy
+msgid "editors_review_update_notify_once"
+msgstr ""
+"Notify me the next time this add-on is updated. (Subsequent updates will not "
+"generate an email)"
+
+#: controllers/editors_controller.php:298
+msgid "editors_reviewed_successfully"
+msgstr "Berrikuspena arrakastaz prozesatu da."
+
+#: views/editors/reviews_queue.thtml:106
+#, fuzzy
+msgid "editors_reviews_action_delete_review"
+msgstr "Delete review"
+
+#: views/editors/reviews_queue.thtml:104
+#, fuzzy
+msgid "editors_reviews_action_keep"
+msgstr "Remove flags; keep review"
+
+#: views/editors/reviews_queue.thtml:102
+msgid "editors_reviews_action_skip"
+msgstr "Saltatu"
+
+#: views/editors/reviews_queue.thtml:100
+msgid "editors_reviews_header_action"
+msgstr "Ekintza"
+
+#: views/editors/reviews_queue.thtml:67
+msgid "editors_reviews_in_reply_to"
+msgstr "honi erantzunez:"
+
+#: controllers/editors_controller.php:748
+msgid "editors_reviews_processed"
+msgstr "Berrikuspenak arrakastaz prozesatu dira!"
+
+#: views/editors/reviews_queue.thtml:117
+msgid "editors_reviews_queue_empty"
+msgstr "Ez dago berrikuspenik moderatzeke."
+
+#: views/editors/reviews_queue.thtml:111
+msgid "editors_reviews_submit_process_reviews"
+msgstr "Prozesatu berrikuspenak"
+
+#: controllers/editors_controller.php:691
+msgid "editors_site_specific"
+msgstr "Gune konkreturako"
+
+#: controllers/editors_controller.php:348
+msgid "editors_tested_app"
+msgstr "Egiaztatutako aplikazioa"
+
+#: controllers/editors_controller.php:347
+msgid "editors_tested_os"
+msgstr "Egiaztatutako sistema eragileak"
+
+#: views/editors/queue.thtml:151
+msgid "editors_th_additional_info"
+msgstr "Informazio gehigarria"
+
+#: views/editors/featured.thtml:63 views/editors/queue.thtml:109
+#: views/admin/flagged_queue.thtml:53
+msgid "editors_th_addon"
+msgstr "Gehigarria"
+
+#: views/editors/queue.thtml:125
+msgid "editors_th_addontype"
+msgstr "Mota"
+
+#: views/editors/featured.thtml:64
+msgid "editors_th_locales"
+msgstr "Murriztu locale-etara?"
+
+#: views/editors/queue.thtml:148
+#, fuzzy
+msgid "editors_th_nomination_age"
+msgstr "Time in Queue"
+
+#: views/editors/queue.thtml:101 views/editors/queue.thtml:117
+#: views/editors/queue.thtml:144
+#, fuzzy
+msgid "editors_th_sort_ascending"
+msgstr "Ascending sort"
+
+#: views/editors/queue.thtml:105 views/editors/queue.thtml:121
+#: views/editors/queue.thtml:140
+#, fuzzy
+msgid "editors_th_sort_descending"
+msgstr "Descending sort"
+
+#. %s is a number
+#: controllers/editors_controller.php:1036
+#, php-format
+msgid "editors_x_days"
+msgstr "%s egun"
+
+#. %s is a number
+#: controllers/editors_controller.php:1044
+#, php-format
+msgid "editors_x_hours"
+msgstr "%s ordu"
+
+#. %s is a number
+#: controllers/editors_controller.php:1052
+#, php-format
+msgid "editors_x_minutes"
+msgstr "%s minutu"
+
+#: views/errors/error401.thtml:50 controllers/components/simple_acl.php:81
+#: controllers/components/simple_acl.php:82
+#: controllers/components/simple_acl.php:83 controllers/components/amo.php:607
+#: controllers/components/amo.php:608 controllers/components/amo.php:609
+#: controllers/reviews_controller.php:353
+#: controllers/reviews_controller.php:485
+#: controllers/collections_controller.php:438
+#: controllers/collections_controller.php:496
+#: controllers/collections_controller.php:504
+#: controllers/collections_controller.php:971
+#: controllers/collections_controller.php:1034
+#: controllers/collections_controller.php:1077
+msgid "error_access_denied"
+msgstr "Sarrera ukatua"
+
+#: views/errors/error401.thtml:52
+msgid "error_access_denied_message"
+msgstr "Ez duzu orri hau ikusteko baimenik."
+
+#: controllers/collections_controller.php:1039
+#, fuzzy
+msgid "error_addon_exists"
+msgstr "Add-on already exists!"
+
+#: controllers/developers_controller.php:200
+#: controllers/developers_controller.php:593
+#: controllers/developers_controller.php:1016
+#: controllers/developers_controller.php:1429
+#: controllers/downloads_controller.php:95
+#: controllers/downloads_controller.php:102
+#: controllers/downloads_controller.php:164
+#: controllers/statistics_controller.php:135
+#: controllers/previews_controller.php:115
+#: controllers/previews_controller.php:206
+#: controllers/previews_controller.php:307
+#: controllers/reviews_controller.php:77
+#: controllers/reviews_controller.php:240
+#: controllers/reviews_controller.php:332
+#: controllers/reviews_controller.php:340 controllers/api_controller.php:123
+#: controllers/api_controller.php:759 controllers/addons_controller.php:131
+#: controllers/addons_controller.php:197
+#: controllers/addons_controller.php:1407
+#: controllers/addons_controller.php:1465
+#: controllers/addons_controller.php:1469
+#: controllers/addons_controller.php:1503
+#: controllers/editors_controller.php:265
+#: controllers/collections_controller.php:1041
+#: controllers/collections_controller.php:1074
+msgid "error_addon_notfound"
+msgstr "Ez da gehigarria aurkitu!"
+
+#: controllers/files_controller.php:83 controllers/files_controller.php:196
+msgid "error_addon_notviewable"
+msgstr "Gehigarri hau ezin da hemen ikusi."
+
+#: controllers/reviews_controller.php:246
+#, fuzzy
+msgid "error_addon_selfreview"
+msgstr "You cannot review your own add-on."
+
+#: controllers/addons_controller.php:970
+msgid "error_browse_no_addons"
+msgstr "Ez dago gehigarririk kategoria honetan!"
+
+#: controllers/api_controller.php:424
+#, fuzzy
+msgid "error_collection_feed_notfound"
+msgstr "Add-on feed not found."
+
+#: views/users/register.thtml:65 views/users/edit.thtml:194
+msgid "error_email_invalid"
+msgstr "Hau ez da baliozko eposta helbide bat."
+
+#: views/users/pwreset.thtml:74 views/users/register.thtml:70
+#: views/users/register.thtml:80 views/users/register.thtml:86
+#: views/users/edit.thtml:105 views/users/edit.thtml:111
+#: views/users/edit.thtml:192 views/admin/users_edit.thtml:78
+#: views/admin/users_edit.thtml:83 views/reviews/add.thtml:80
+#: views/reviews/add.thtml:104
+msgid "error_field_required"
+msgstr "Eremu hau ezin da hutsik utzi."
+
+#: controllers/files_controller.php:75 controllers/files_controller.php:93
+#: controllers/files_controller.php:96 controllers/files_controller.php:163
+#: controllers/files_controller.php:176 controllers/files_controller.php:185
+#: controllers/files_controller.php:204 controllers/editors_controller.php:412
+msgid "error_file_notfound"
+msgstr "Fitxategia ez da aurkitu!"
+
+#. %s is a filename
+#: controllers/editors_controller.php:430
+#, php-format
+msgid "error_file_x_notfound"
+msgstr "Fitxategi-errorea: %s ez da existitzen."
+
+#: views/collections/add.thtml:55 views/collections/edit.thtml:89
+#: views/users/register.thtml:54 views/users/edit.thtml:81
+#: views/reviews/add.thtml:70 controllers/groups_controller.php:80
+#: controllers/groups_controller.php:102
+msgid "error_formerrors"
+msgstr "Erroreak daude inprimaki honetan. Mesedez konpondu eta berriz bidali."
+
+#: views/users/register.thtml:109
+#, fuzzy
+msgid "error_invalid_captcha"
+msgstr "Invalid captcha, please try again!"
+
+#: views/users/register.thtml:100 views/users/edit.thtml:125
+#: views/admin/users_edit.thtml:101
+msgid "error_invalid_url"
+msgstr ""
+"URL honek formatu baliogabea du. Baliozko URLak honelakoak dira: http://"
+"example.com/my_page."
+
+#. %s is a string representing what's missing. Example: file_id
+#: controllers/downloads_controller.php:65
+#: controllers/users_controller.php:185 controllers/users_controller.php:264
+#: controllers/users_controller.php:559 controllers/users_controller.php:653
+#: controllers/reviews_controller.php:71
+#: controllers/reviews_controller.php:234
+#: controllers/reviews_controller.php:325
+#: controllers/reviews_controller.php:473
+#: controllers/reviews_controller.php:475
+#: controllers/addons_controller.php:182
+#: controllers/addons_controller.php:1381
+#: controllers/addons_controller.php:1455
+#: controllers/collections_controller.php:266
+#: controllers/collections_controller.php:285
+#: controllers/collections_controller.php:346
+#: controllers/collections_controller.php:443
+#: controllers/collections_controller.php:482
+#: controllers/collections_controller.php:936
+#: controllers/collections_controller.php:959
+#: controllers/collections_controller.php:960
+#: controllers/collections_controller.php:975
+#: controllers/collections_controller.php:977
+#: controllers/collections_controller.php:994
+#: controllers/collections_controller.php:1003
+#: controllers/collections_controller.php:1016
+#: controllers/collections_controller.php:1017
+#: controllers/collections_controller.php:1024
+#: controllers/collections_controller.php:1070
+#: controllers/collections_controller.php:1090
+#, php-format
+msgid "error_missing_argument"
+msgstr "Argumentua falta da: %s"
+
+#: controllers/components/amo.php:507 controllers/components/amo.php:532
+#, fuzzy
+msgid "error_no_files_in_addon"
+msgstr "No Files"
+
+#: controllers/previews_controller.php:200
+msgid "error_preview_notfound"
+msgstr "Aurrebista ez da aurkitu!"
+
+#: views/addons/display.thtml:400 views/reviews/add.thtml:98
+msgid "error_review_rating_required"
+msgstr "Puntuazio bat aukeratu behar duzu."
+
+#: controllers/users_controller.php:160
+msgid "error_user_already_confirmed"
+msgstr "Erabiltzaile kontu hau berretsirik dago dagoeneko."
+
+#: controllers/users_controller.php:202 controllers/users_controller.php:276
+#: controllers/users_controller.php:569 controllers/users_controller.php:581
+#: controllers/users_controller.php:587 controllers/users_controller.php:610
+#: controllers/users_controller.php:627
+msgid "error_user_badconfirmationcode"
+msgstr "Berrespen kode baliogabea!"
+
+#: views/users/pwreset.thtml:79 views/users/register.thtml:75
+#: views/users/edit.thtml:183
+msgid "error_user_confirmpw_nomatch"
+msgstr "Pasahitzak ez dira berdinak."
+
+#: views/users/register.thtml:65 views/users/edit.thtml:190
+#: controllers/users_controller.php:617
+msgid "error_user_email_notunique"
+msgstr "Beste erabiltzaile batek dagoeneko eposta helbide hau erabiltzen du."
+
+#: controllers/users_controller.php:596
+#, fuzzy
+msgid "error_user_emailchange_expired"
+msgstr ""
+"The email change has expired. Please change your email address again in your "
+"user profile and click the link in the confirmation email as soon as you "
+"receive it."
+
+#: controllers/collections_controller.php:985
+#, fuzzy
+msgid "error_user_exists"
+msgstr ""
+"Users can only have one role at a time. Please remove the user from any "
+"existing roles before continuing."
+
+#: views/users/register.thtml:91 views/users/edit.thtml:116
+#: views/admin/users_edit.thtml:88
+msgid "error_user_nickname_notunique"
+msgstr "Ezizen hau dagoeneko hartuta dago."
+
+#: views/users/pwreset.thtml:54 controllers/users_controller.php:191
+#: controllers/users_controller.php:270 controllers/users_controller.php:603
+#: controllers/users_controller.php:659
+#: controllers/collections_controller.php:988
+#: controllers/collections_controller.php:998
+msgid "error_user_notfound"
+msgstr "Erabiltzailea ez da aurkitu!"
+
+#: views/users/activatefirst.thtml:47
+msgid "error_user_unconfirmed"
+msgstr "Lehenik berretsi zure erabiltzaile kontua mesedez."
+
+#: views/users/login.thtml:67
+msgid "error_username_or_pw_wrong"
+msgstr "Erabiltzaile-izen edo pasahitz okerra!"
+
+#: controllers/editors_controller.php:260
+msgid "error_version_notfound"
+msgstr "Bertsioa ez da aurkitu!"
+
+#: views/users/delete.thtml:125 views/users/edit.thtml:173
+msgid "error_wrong_password"
+msgstr "Pasahitz okerra!"
+
+#: views/elements/amo2009/homepage_addon.thtml:122
+#: views/elements/feature.thtml:122
+msgid "feature_learnmore"
+msgstr "Ikasi gehiago"
+
+# %1 is the add-on name
+#. %1 is the add-on name
+#: views/elements/amo2009/homepage_addon.thtml:123
+#: views/elements/feature.thtml:123
+#, php-format
+msgid "feature_learnmore_about_addon"
+msgstr "Gehiago jakin %1$s buruz"
+
+#. %1$s is a number
+#: views/elements/amo2009/reviews.thtml:52
+#: views/elements/addon_listitem.thtml:112 views/elements/feature.thtml:99
+#: views/addons/browse_thumbs.thtml:86
+#, php-format
+msgid "feature_reviews"
+msgid_plural "feature_reviews"
+msgstr[0] "berrikuspen %1$s"
+msgstr[1] "%1$s berrikuspen"
+
+#: views/elements/amo2009/homepage_addon.thtml:127
+#: views/elements/feature.thtml:127
+msgid "feature_view_more_from_category"
+msgstr "Kategoria honetako gehiago:"
+
+#. This appears on a page that views the source of an add-on. This link will return
+#. the user to the add-on's main page
+#: views/files/browse.thtml:65
+#, fuzzy
+msgid "file_browser_link_addon"
+msgstr "Back to add-on"
+
+#. There is a list of directories and files on the page. Clicking this will show the
+#. contents of all the directories (normally you would click on each one to see the
+#. contents)
+#: views/files/browse.thtml:67
+#, fuzzy
+msgid "file_browser_link_expand_all"
+msgstr "Expand all"
+
+#. This appears on a page that views the source of an add-on. This link will return
+#. the user to the add-on's review page (it only appears if the add-on is being
+#. reviewed)
+#: views/files/browse.thtml:64
+#, fuzzy
+msgid "file_browser_link_review"
+msgstr "Back to review"
+
+#. The title of the page for viewing an add-on's source.
+#. %1$s is the name of the add-on
+#. %2$s is the name of the current application (e.g. Firefox or Thunderbird)
+#: views/files/browse.thtml:46
+#, fuzzy
+msgid "file_browser_title"
+msgstr "%1$s :: File Browser :: %2$s Add-ons"
+
+#. This appears on a page that views the source of an add-on. There is a list of
+#. directories and files on the page. Clicking this link will toggle between an
+#. expanded or a collapsed list. This string should be kept short.
+#: views/files/browse.thtml:68
+#, fuzzy
+msgid "file_browser_toggle_expand_collapse"
+msgstr "+/-"
+
+#. Link text for the AMO About page.
+#: views/elements/footer.thtml:72 views/layouts/amo2009.thtml:341
+#, fuzzy
+msgid "footer_a_about"
+msgstr "About"
+
+#. Link text to the AMO blog.
+#: views/elements/footer.thtml:74 views/layouts/amo2009.thtml:343
+#, fuzzy
+msgid "footer_a_blog"
+msgstr "Blog"
+
+#. Link text to the Frequently Asked Questions page.
+#: views/elements/footer.thtml:73 views/layouts/amo2009.thtml:342
+#, fuzzy
+msgid "footer_a_faq"
+msgstr "FAQ"
+
+#. Full text for the FAQ abbreviation.
+#: views/elements/footer.thtml:73 views/pages/collector_features.thtml:72
+#: views/layouts/amo2009.thtml:342
+#, fuzzy
+msgid "footer_abbr_faq"
+msgstr "Frequently Asked Questions"
+
+#: views/elements/footer.thtml:67 views/layouts/amo2009.thtml:336
+msgid "footer_all_rights_reserved"
+msgstr "Eskubide guztiak erreserbatuta"
+
+#: views/elements/footer.thtml:67 views/layouts/amo2009.thtml:336
+msgid "footer_copyright"
+msgstr "Copyright"
+
+#: views/elements/footer.thtml:71 views/layouts/amo2009.thtml:340
+msgid "footer_credits"
+msgstr "Kredituak"
+
+#: views/elements/footer.thtml:76 views/layouts/amo2009.thtml:346
+msgid "footer_disclaimer"
+msgstr ""
+"Mozillak aplikazio horietarako loturak kortesia gisa eskaintzen ditu eta ez "
+"da aplikazioen edo bertan agertutako edozein informazioren ordezkari. "
+"Aplikazioari buruzko edozein galdera, erreklamazio edo eskaera dagokion "
+"software saltzaileari zuzendu behar zaio."
+
+#: views/elements/footer.thtml:61 views/layouts/amo2009.thtml:332
+msgid "footer_lang_form_lang_submit_go"
+msgstr "Aurrera"
+
+#: views/elements/footer.thtml:70 views/layouts/amo2009.thtml:339
+msgid "footer_legal_notices"
+msgstr "Lege oharrak"
+
+# This is the lang code -- should be the same as the dir for this locale.
+#: views/elements/footer.thtml:50 views/layouts/amo2009.thtml:321
+msgid "footer_other_languages"
+msgstr "Beste hizkuntzak:"
+
+#: views/elements/footer.thtml:69 views/layouts/amo2009.thtml:338
+msgid "footer_privacy_policy"
+msgstr "Pribatutasun-politika"
+
+#: models/addontype.php:79
+msgid "general_addontype_dict"
+msgstr "Hiztegia"
+
+# Plural in this context means many of the add-on type
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:100
+msgid "general_addontype_dict_plural"
+msgstr "Hiztegiak"
+
+#: models/addontype.php:75
+msgid "general_addontype_extension"
+msgstr "Hedapena"
+
+# Plural in this context means many of the add-on type
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:98
+msgid "general_addontype_extension_plural"
+msgstr "Hedapenak"
+
+#: models/addontype.php:85
+msgid "general_addontype_lpaddon"
+msgstr "Hizkuntza Paketea (Gehigarria)"
+
+# Plural in this context means many of the add-on type
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:103
+msgid "general_addontype_lpaddon_plural"
+msgstr "Hizkuntza Paketeak (Gehigarriak)"
+
+#: models/addontype.php:83
+msgid "general_addontype_lpapp"
+msgstr "Hizkuntza Paketea (Aplikazioa)"
+
+# Plural in this context means many of the add-on type
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:102
+msgid "general_addontype_lpapp_plural"
+msgstr "Hizkuntza Paketeak (Aplikazioak)"
+
+#: models/addontype.php:87
+msgid "general_addontype_plugin"
+msgstr "Plugina"
+
+# Plural in this context means many of the add-on type
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:104
+msgid "general_addontype_plugin_plural"
+msgstr "Pluginak"
+
+#: models/addontype.php:81
+msgid "general_addontype_search"
+msgstr "Bilaketa Motorea"
+
+# Plural in this context means many of the add-on type
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:101
+msgid "general_addontype_search_plural"
+msgstr "Bilaketa Motoreak"
+
+#: models/addontype.php:77
+msgid "general_addontype_theme"
+msgstr "Gaia"
+
+# Plural in this context means many of the add-on type
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:99
+msgid "general_addontype_theme_plural"
+msgstr "Gaiak"
+
+#: config/language.php:367
+#, fuzzy
+msgid "general_languages_all_locales"
+msgstr "All Locales"
+
+#: views/layouts/amo2009.thtml:249
+#, fuzzy
+msgid "header_brand_name"
+msgstr "Mozilla"
+
+#. %1$s is the application name. Example: Firefox
+#: views/elements/header.thtml:111 views/elements/header.thtml:122
+#: views/layouts/amo2009.thtml:248
+#, php-format
+msgid "header_home_tooltip"
+msgstr "Itzuli %1$serako gehigarrien hasiera orrira"
+
+#: views/elements/header.thtml:87
+msgid "header_main_firefox_header"
+msgstr "Firefoxerako gehigarriak"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:218
+#, fuzzy
+msgid "header_main_firefox_header_with_logo"
+msgstr ""
+"Add-ons <em>for</em> <img alt=\"Firefox\" src=\"%1$s\" /> <strong>Firefox</"
+"strong>"
+
+#: views/elements/header.thtml:99
+msgid "header_main_header"
+msgstr "Gehigarriak"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:242
+#, fuzzy
+msgid "header_main_header_with_logo"
+msgstr "Add-ons <img alt=\"Add-ons\" src=\"%1$s\" />"
+
+#: views/elements/header.thtml:90
+msgid "header_main_seamonkey_header"
+msgstr "Seamonkeyrako gehigarriak"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:224
+#, fuzzy
+msgid "header_main_seamonkey_header_with_logo"
+msgstr ""
+"Add-ons <em>for</em> <img alt=\"seamonkey\" src=\"%1$s\" /> "
+"<strong>SeaMonkey</strong>"
+
+#: views/elements/header.thtml:93
+msgid "header_main_sunbird_header"
+msgstr "Sunbirderako gehigarriak"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:230
+#, fuzzy
+msgid "header_main_sunbird_header_with_logo"
+msgstr ""
+"Add-ons <em>for</em> <img alt=\"sunbird\" src=\"%1$s\" /> <strong>Sunbird</"
+"strong>"
+
+#: views/elements/header.thtml:96
+msgid "header_main_thunderbird_header"
+msgstr "Thunderbirderako gehigarriak"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:236
+#, fuzzy
+msgid "header_main_thunderbird_header_with_logo"
+msgstr ""
+"Add-ons <em>for</em> <img alt=\"thunderbird\" src=\"%1$s\" /> "
+"<strong>Thunderbird</strong>"
+
+#: views/layouts/amo2009.thtml:205
+#, fuzzy
+msgid "header_navaccess_applications_menu"
+msgstr "Skip to other applications menu"
+
+#: views/layouts/amo2009.thtml:204
+#, fuzzy
+msgid "header_navaccess_categories_menu"
+msgstr "Skip to categories menu"
+
+#: views/layouts/amo2009.thtml:202
+#, fuzzy
+msgid "header_navaccess_main_content"
+msgstr "Skip to main content"
+
+#: views/layouts/amo2009.thtml:203
+#, fuzzy
+msgid "header_navaccess_search_form"
+msgstr "Skip to search form"
+
+#: views/elements/header.thtml:62
+msgid "header_navlink_addons"
+msgstr "Gehigarriak"
+
+#: views/elements/developers/sidebar.thtml:72
+#: views/elements/developers/myaddons.thtml:50 views/elements/header.thtml:159
+#: views/addons/display.thtml:378
+msgid "header_navlink_login"
+msgstr "Hasi saioa"
+
+#: views/elements/header.thtml:156 views/layouts/amo2009.thtml:304
+msgid "header_navlink_logout"
+msgstr "Amaitu saioa"
+
+#: views/elements/header.thtml:145 views/layouts/amo2009.thtml:303
+msgid "header_navlink_myaccount"
+msgstr "Nire kontua"
+
+#: views/elements/header.thtml:158
+msgid "header_navlink_register"
+msgstr "Eman izena"
+
+#. %1 is the URL to the registration page
+#. %2 is the URL to the login page
+#: views/layouts/amo2009.thtml:278
+#, fuzzy
+msgid "header_navlink_register_or_login"
+msgstr "<a href=\"%1$s\">Register</a> or <a href=\"%2$s\">Log in</a>"
+
+#: views/layouts/amo2009.thtml:285
+#, fuzzy
+msgid "header_navlink_tools"
+msgstr "Tools"
+
+#. %s is the add-on name
+#: views/elements/collections_interactive_addon.thtml:62
+#: views/elements/amo2009/homepage_addon.thtml:77
+#: views/elements/addon_discussionheader.thtml:62
+#: views/elements/addon_listitem.thtml:67 views/elements/feature.thtml:84
+#: views/addons/category_landing.thtml:87 views/addons/browse_thumbs.thtml:60
+#, php-format
+msgid "img_preview_of"
+msgstr "%s(r)en aurrebista irudia"
+
+# %1 is the login URL for the link tag
+#. %1 is the login URL for the link tag
+#. %2 is the link to an explanatory page.
+#: views/elements/amo2009/install.thtml:307 views/elements/install.thtml:255
+msgid "install_a_login_to_install"
+msgstr "<a href=\"%1$s\">Hasi saioa</a> gehigarri hau instalatzeko"
+
+#. %1 is the URL for the Experimental Add-ons section of the FAQ page
+#: views/elements/amo2009/install.thtml:283 views/elements/install.thtml:232
+#, fuzzy
+msgid "install_button_confirm_exp_install"
+msgstr ""
+"Let me install this experimental add-on. <a href=\"%1$s\">What's this?</a>"
+
+#. %1$s is the application name. Example: Firefox
+#. %2$s is an optional string used to specify a platform. Example: (Windows)
+#: views/elements/amo2009/install.thtml:128 views/elements/install.thtml:75
+#, php-format
+msgid "install_button_text"
+msgstr "Gehitu %s(e)ra %s"
+
+# %1 is the add-on name, %2 is the app name
+#. %1 is the add-on name, %2 is the app name
+#: views/elements/amo2009/install.thtml:191
+#: views/elements/amo2009/install.thtml:206
+#: views/elements/amo2009/install.thtml:249
+#: views/elements/amo2009/install.thtml:298 views/elements/install.thtml:150
+#: views/elements/install.thtml:165 views/elements/install.thtml:202
+#: views/elements/install.thtml:246
+#, php-format
+msgid "install_button_title"
+msgstr "Gehitu %1$s(e)ra %2$s"
+
+#. %1$s is the add-on name
+#: views/elements/amo2009/install.thtml:200 views/elements/install.thtml:159
+#, php-format
+msgid "install_download"
+msgstr "Deskargatu %1$s"
+
+#: views/elements/amo2009/install.thtml:147 views/elements/install.thtml:94
+msgid "install_error_addon_not_found"
+msgstr "Gehigarri hau ez dago eskuragarri."
+
+#: views/addons/dictionaries.thtml:65
+#, fuzzy
+msgid "langtools_a11y_tablesummary"
+msgstr "List of language packs and dictionaries."
+
+#: views/addons/dictionaries.thtml:47
+msgid "langtools_download_dictionary"
+msgstr "Deskargatu hiztegia"
+
+#: views/addons/dictionaries.thtml:48
+msgid "langtools_download_langpack"
+msgstr "Deskargatu hizkuntza-paketea"
+
+#: views/addons/dictionaries.thtml:63 controllers/components/amo.php:685
+#: controllers/addons_controller.php:1239
+msgid "langtools_header_dicts_and_langpacks"
+msgstr "Hiztegiak eta hizkuntza-paketeak"
+
+#: views/addons/dictionaries.thtml:44
+msgid "langtools_install_dictionary"
+msgstr "Instalatu hiztegia"
+
+#: views/addons/dictionaries.thtml:45
+msgid "langtools_install_langpack"
+msgstr "Instalatu hizkuntza-paketea"
+
+#: views/addons/dictionaries.thtml:69
+msgid "langtools_tableheader_dictionary"
+msgstr "Hiztegia"
+
+#: views/addons/dictionaries.thtml:70
+msgid "langtools_tableheader_langpack"
+msgstr "Hizkuntza-paketea"
+
+#: views/addons/dictionaries.thtml:68
+msgid "langtools_tableheader_language"
+msgstr "Hizkuntza"
+
+#: models/license.php:65
+#, fuzzy
+msgid "license_custom"
+msgstr "Custom License"
+
+#: config/bootstrap.php:303
+#, fuzzy
+msgid "licenses_bsd"
+msgstr "BSD License"
+
+#: config/bootstrap.php:298
+#, fuzzy
+msgid "licenses_gpl_2.0"
+msgstr "GNU General Public License, version 2.0"
+
+#: config/bootstrap.php:299
+#, fuzzy
+msgid "licenses_gpl_3.0"
+msgstr "GNU General Public License, version 3.0"
+
+#: config/bootstrap.php:300
+#, fuzzy
+msgid "licenses_lgpl_2.1"
+msgstr "GNU Lesser General Public License, version 2.1"
+
+#: config/bootstrap.php:301
+#, fuzzy
+msgid "licenses_lgpl_3.0"
+msgstr "GNU Lesser General Public License, version 3.0"
+
+#: config/bootstrap.php:302
+#, fuzzy
+msgid "licenses_mit"
+msgstr "MIT/X11 License"
+
+#: config/bootstrap.php:297
+#, fuzzy
+msgid "licenses_mpl_1.1"
+msgstr "Mozilla Public License, version 1.1"
+
+#: views/users/emailchange.thtml:51 views/users/delete.thtml:55
+#: views/users/delete.thtml:137 views/users/edit.thtml:74
+#: views/reviews/flag.thtml:54
+#, fuzzy
+msgid "link_return_to_front_page"
+msgstr "Click here to return to the front page."
+
+#: views/elements/amo2009/addon_list_options.thtml:46
+#: views/elements/addon_list_options.thtml:46
+msgid "list_sortby_date"
+msgstr "Data"
+
+#: views/elements/amo2009/addon_list_options.thtml:47
+#: views/elements/addon_list_options.thtml:47
+msgid "list_sortby_downloads"
+msgstr "Deskargak"
+
+#: views/elements/amo2009/addon_list_options.thtml:45
+#: views/elements/addon_list_options.thtml:45
+msgid "list_sortby_name"
+msgstr "Gehigarriaren izena"
+
+#: views/elements/amo2009/addon_list_options.thtml:48
+#: views/elements/addon_list_options.thtml:48
+msgid "list_sortby_rating"
+msgstr "Balorazioa"
+
+#: config/bootstrap.php:278
+#, fuzzy
+msgid "main_prettyname_fennec"
+msgstr "Fennec"
+
+#: config/bootstrap.php:274
+msgid "main_prettyname_firefox"
+msgstr "Firefox"
+
+#: config/bootstrap.php:277
+msgid "main_prettyname_seamonkey"
+msgstr "SeaMonkey"
+
+#: config/bootstrap.php:276
+msgid "main_prettyname_sunbird"
+msgstr "Sunbird"
+
+#: config/bootstrap.php:275
+msgid "main_prettyname_thunderbird"
+msgstr "Thunderbird"
+
+#: views/elements/addon_categories.thtml:52
+#, fuzzy
+msgid "nav_category_dicts_langpacks"
+msgstr "Dictionaries & Language Packs"
+
+#: views/elements/addon_categories.thtml:55
+#, fuzzy
+msgid "nav_category_themes"
+msgstr "Themes"
+
+#: views/elements/app_chooser.thtml:47 views/layouts/amo2009.thtml:255
+#, fuzzy
+msgid "other_apps_tooltip"
+msgstr "Find add-ons for other applications"
+
+# In a user list: user 1, user 2, "others"
+#. In a user list: user 1, user 2, "others"
+#: views/helpers/addons_html.php:222
+msgid "other_users"
+msgstr "besteak"
+
+#: controllers/pages_controller.php:90
+#, fuzzy
+msgid "page_title_appversions"
+msgstr "Application Versions"
+
+#: controllers/pages_controller.php:115
+#, fuzzy
+msgid "page_title_collector"
+msgstr "Add-on Collector"
+
+#: controllers/pages_controller.php:117
+#, fuzzy
+msgid "page_title_collector_faq"
+msgstr "Add-on Collector FAQ"
+
+#: controllers/pages_controller.php:119
+#, fuzzy
+msgid "page_title_collector_features"
+msgstr "Add-on Collector Features"
+
+#: controllers/pages_controller.php:122
+#, fuzzy
+msgid "page_title_collector_firstrun"
+msgstr "Welcome to the Add-on Collector"
+
+#: controllers/pages_controller.php:92
+#, fuzzy
+msgid "page_title_credits"
+msgstr "Credits"
+
+#: controllers/pages_controller.php:113
+#, fuzzy
+msgid "page_title_developer_faq"
+msgstr "Developer FAQ"
+
+#: controllers/pages_controller.php:111
+#, fuzzy
+msgid "page_title_faq"
+msgstr "Frequently Asked Questions"
+
+#: controllers/pages_controller.php:94
+#, fuzzy
+msgid "page_title_fashionyourfirefox_faq"
+msgstr "Fashion your Firefox FAQ"
+
+#: controllers/pages_controller.php:101
+#, fuzzy
+msgid "page_title_policy"
+msgstr "Add-ons Policy"
+
+#: controllers/pages_controller.php:103
+#, fuzzy
+msgid "page_title_privacy"
+msgstr "Mozilla Privacy Policy"
+
+#: controllers/pages_controller.php:105
+#, fuzzy
+msgid "page_title_review_guide"
+msgstr "Review Guidelines"
+
+#: controllers/pages_controller.php:107
+#, fuzzy
+msgid "page_title_sandbox"
+msgstr "Sandbox Review System"
+
+#: controllers/pages_controller.php:109
+#, fuzzy
+msgid "page_title_submissionhelp"
+msgstr "Submission Help"
+
+#: views/pages/appversions.thtml:87
+msgid "pages_appversions_guid"
+msgstr "GUID"
+
+#: views/pages/appversions.thtml:79 controllers/pages_controller.php:90
+msgid "pages_appversions_header"
+msgstr "Baliozko aplikazio-bertsioak"
+
+#: views/pages/appversions.thtml:80
+msgid "pages_appversions_intro"
+msgstr ""
+"Mozilla Gehigarrien gunera bidalitako gehigarriei gutxienez azpian "
+"zehaztutako aplikazio baten euskarria izatea eskatzen zaie install.rdf "
+"fitxategian. Azpian zerrendatutako bertsioak onartuko dira soilik aplikazio "
+"horientzat."
+
+#. %s is a full <a> tag
+#: views/pages/appversions.thtml:93
+#, php-format
+msgid "pages_appversions_required_files"
+msgstr ""
+"Euskarria ematen diozun aplikazioak install.rdf fitxategia behar ez badu "
+"ere, halako bat sartu beharko duzu %s zehaztutako propietateekin."
+
+#. this is the text inside of an <a> tag for pages_appversions_required_files. This
+#. should be fixed.
+#: views/pages/appversions.thtml:93
+msgid "pages_appversions_required_files_link"
+msgstr "hemen"
+
+#: views/pages/appversions.thtml:88
+msgid "pages_appversions_versions"
+msgstr "Bertsioak"
+
+#: views/pages/policy.thtml:51
+msgid "pages_policy_sandbox_link"
+msgstr "Probaguneko informazio-orria"
+
+#: views/elements/pagination.thtml:53
+msgid "pagination_next_page"
+msgstr "hurrengoa"
+
+#: views/elements/pagination.thtml:52
+msgid "pagination_previous_page"
+msgstr "aurrekoa"
+
+#: views/elements/recaptcha.thtml:65
+#, fuzzy
+msgid "recaptcha_enter_both_words"
+msgstr ""
+"Please enter <strong>both words</strong> below, <strong>separated by a "
+"space</strong>."
+
+#: views/elements/recaptcha.thtml:83
+#, fuzzy
+msgid "recaptcha_enter_here"
+msgstr "Enter your answer here:"
+
+#: views/elements/recaptcha.thtml:74
+#, fuzzy
+msgid "recaptcha_enter_whatyouhear"
+msgstr "Please type what you hear."
+
+# %1 is the link switching refreshing the captcha
+# %2 is the link switching to a text captcha
+#. %1 is the link switching refreshing the captcha
+#. %2 is the link switching to a text captcha
+#: views/elements/recaptcha.thtml:77
+#, fuzzy
+msgid "recaptcha_hardtohear_text"
+msgstr ""
+"If this is hard to understand, you can <a href=\"%1$s\">listen to something "
+"else</a> or <a href=\"%2$s\">switch back to text</a>."
+
+# %1 is the link switching refreshing the captcha
+# %2 is the link switching to an audio captcha
+#. %1 is the link switching refreshing the captcha
+#. %2 is the link switching to an audio captcha
+#: views/elements/recaptcha.thtml:68
+#, fuzzy
+msgid "recaptcha_hardtoread_text"
+msgstr ""
+"If this is hard to read, you can <a href=\"%1$s\">try different words</a> or "
+"<a href=\"%2$s\">listen to something</a> instead."
+
+#: views/users/register.thtml:105
+#, fuzzy
+msgid "recaptcha_label"
+msgstr "Are you human?"
+
+#: views/users/register.thtml:106
+#, fuzzy
+msgid "recaptcha_whatsthis"
+msgstr "What's this?"
+
+#: controllers/reviews_controller.php:559
+#, fuzzy
+msgid "review_flag_error"
+msgstr "Error flagging this review!"
+
+#: models/reviews_moderation_flag.php:69
+#, fuzzy
+msgid "review_flag_reason_bug_support"
+msgstr "Misplaced bug report or support request"
+
+#: views/reviews/display.thtml:103 views/reviews/display.thtml:186
+#, fuzzy
+msgid "review_flag_reason_instructions"
+msgstr "Report this review (select a reason)"
+
+#: models/reviews_moderation_flag.php:67
+#, fuzzy
+msgid "review_flag_reason_language"
+msgstr "Inappropriate language/dialog"
+
+#: models/reviews_moderation_flag.php:71
+#, fuzzy
+msgid "review_flag_reason_other"
+msgstr "Other (please specify)"
+
+#: models/reviews_moderation_flag.php:65
+#, fuzzy
+msgid "review_flag_reason_spam"
+msgstr "Spam or otherwise non-review content"
+
+#: views/reviews/display.thtml:91 views/reviews/display.thtml:175
+#: controllers/reviews_controller.php:555
+#, fuzzy
+msgid "review_flag_success"
+msgstr "Thanks; this review has been flagged for editor approval."
+
+#: views/reviews/display.thtml:41
+#, fuzzy
+msgid "review_flag_this"
+msgstr "Report this review"
+
+#: views/reviews/display.thtml:42
+#, fuzzy
+msgid "review_flag_this_titletip"
+msgstr ""
+"Is this review inappropriate, inaccurate or spam? Click here to flag it for "
+"editor review."
+
+# %1 is the URL of the support section, %2 for the review guidelines
+#. %1 is the URL of the support section, %2 for the review guidelines
+#: views/reviews/add.thtml:53
+#, fuzzy
+msgid "review_guidelines_short"
+msgstr ""
+"<p>Keep these tips in mind:</p><ul><li>Write like you're telling a friend "
+"about your experience with the add-on. Give specifics and helpful details, "
+"such as what features you liked and/ordisliked, how easy to use it is, and "
+"any disadvantages it has. Avoid genericlanguage such as calling it \"Great"
+"\" or \"Bad\" unless you can give reasons whyyou believe this is so.</"
+"li><li>Please do not post bug reports in reviews. We do not make your email "
+"address available to add-on developers and they may need to contact you to "
+"help resolveyour issue. See the <a href=\"%1$s\">support section</a> to find "
+"out where to get assistance for this add-on.</li><li>Please keep reviews "
+"clean, avoid the use of improper language and do not post any personal "
+"information.</li></ul><p>Please read the <a href=\"%2$s\">Review Guidelines</"
+"a> for more detail about user add-on reviews.</p>"
+
+#. %1 is the add-on name
+#: views/reviews/flag.thtml:56 views/reviews/display.thtml:55
+#: views/reviews/review_added.thtml:50
+#, php-format
+msgid "reviews_header"
+msgstr "Berrikuspenak %s(r)entzat"
+
+#: controllers/addons_controller.php:435
+msgid "rss_featuredaddons"
+msgstr "Nabarmendutako gehigarriak"
+
+#: controllers/addons_controller.php:432
+msgid "rss_newestaddons"
+msgstr "Gehigarri berrienak"
+
+#: controllers/addons_controller.php:434
+#, fuzzy
+msgid "rss_popularaddons"
+msgstr "Popular Add-ons"
+
+#: controllers/addons_controller.php:433
+#, fuzzy
+msgid "rss_updatedaddons"
+msgstr "Updated Add-ons"
+
+#: views/elements/search_mini.thtml:70
+#, fuzzy
+msgid "search"
+msgstr "Search"
+
+#: views/search/collections.thtml:51
+#, fuzzy
+msgid "search_collections_header"
+msgstr "Collection Search Results"
+
+#: controllers/search_controller.php:297
+#, fuzzy
+msgid "search_collections_pagetitle"
+msgstr "Collection Search Results"
+
+#: controllers/search_controller.php:99
+msgid "search_disabled"
+msgstr "Bilaketa ezgaituta dago momentuz. Saia zaitez geroago."
+
+#: views/elements/amo2009/search.thtml:188 views/elements/search.thtml:187
+#: views/elements/search_mini.thtml:54
+msgid "search_form_all_addons"
+msgstr "gehigarri guztiak"
+
+#. This string is in the main category dropdown when searching
+#: views/elements/amo2009/search.thtml:204
+#, fuzzy
+msgid "search_form_all_collections"
+msgstr "all collections"
+
+#: views/elements/amo2009/search.thtml:184
+#: views/elements/amo2009/search.thtml:385
+#: views/elements/amo2009/search.thtml:408 views/elements/search.thtml:171
+#: views/elements/search.thtml:183 views/elements/search_mini.thtml:43
+#: views/elements/search_mini.thtml:49 views/layouts/mozilla.thtml:188
+msgid "search_form_default_text"
+msgstr "bilatu gehigarriak"
+
+#: views/elements/amo2009/search.thtml:184
+#: views/elements/amo2009/search.thtml:404
+#, fuzzy
+msgid "search_form_default_text_collections"
+msgstr "search for collections"
+
+#: views/elements/amo2009/search.thtml:206 views/elements/search.thtml:202
+#, fuzzy
+msgid "search_form_submit_tooltip"
+msgstr "Search for add-ons"
+
+#: views/elements/amo2009/search.thtml:184 views/elements/search.thtml:183
+#: views/elements/search_mini.thtml:49
+#, fuzzy
+msgid "search_form_tooltip"
+msgstr "Click to enter search terms"
+
+#: views/elements/amo2009/search.thtml:186 views/elements/search.thtml:185
+#: views/elements/search_mini.thtml:52
+msgid "search_form_within"
+msgstr "hemen:"
+
+#: views/addons/searchengines.thtml:118
+msgid "search_landing_all_search_engines"
+msgstr "Bilaketa-motor guztiak"
+
+#: views/addons/searchengines.thtml:114
+msgid "search_landing_browse_search_engines"
+msgstr "Arakatu bilaketa-motorrak"
+
+#: views/search/collections.thtml:58 views/search/index.thtml:59
+msgid "search_nothing_found"
+msgstr "Ez da emaitzarik aurkitu."
+
+#: controllers/search_controller.php:185
+msgid "search_pagetitle"
+msgstr "Bilatu gehigarriak"
+
+#: controllers/search_controller.php:242
+msgid "search_rss_description"
+msgstr "Bilaketa-emaitzen jarioa"
+
+#. %s is the terms the user is searching for (a string)
+#: controllers/search_controller.php:241
+#, php-format
+msgid "search_rss_results_for"
+msgstr "Bilaketaren emaitzak: %s"
+
+#: views/elements/header.thtml:154 views/layouts/amo2009.thtml:296
+msgid "sidebar_navlink_admin_tools"
+msgstr "Kudeaketa-tresnak"
+
+#: views/elements/header.thtml:146 views/layouts/amo2009.thtml:288
+msgid "sidebar_navlink_developer_tools"
+msgstr "Garatzaile-tresnak"
+
+#: views/elements/header.thtml:148 views/layouts/amo2009.thtml:290
+msgid "sidebar_navlink_editor_tools"
+msgstr "Editore-tresnak"
+
+#: views/layouts/amo2009.thtml:302
+msgid "sidebar_navlink_welcome"
+msgstr "Ongi etorri"
+
+#. %s is the user's name
+#: views/layouts/amo2009.thtml:302
+#, php-format
+msgid "sidebar_navlink_welcome_name"
+msgstr "Ongi etorri, %s"
+
+#: views/elements/pitch.thtml:50 views/elements/pitch.thtml:55
+msgid "sidebar_pitch_dictionary"
+msgstr "Hiztegia"
+
+#: views/elements/pitch.thtml:72
+#, fuzzy
+msgid "sidebar_pitch_featured_addons"
+msgstr "Featured Add-ons"
+
+#: views/elements/pitch.thtml:61
+msgid "sidebar_pitch_looking_for"
+msgstr "Honen bila nabil:"
+
+#: views/elements/pitch.thtml:70
+#, fuzzy
+msgid "sidebar_pitch_newest_addons"
+msgstr "Newest Add-ons"
+
+#: views/elements/pitch.thtml:49
+msgid "sidebar_pitch_search"
+msgstr "Bilaketa Plugina"
+
+#: views/elements/pitch.thtml:69
+#, fuzzy
+msgid "sidebar_pitch_subscribe_to"
+msgstr "Subscribe to"
+
+#: views/elements/pitch.thtml:48 views/elements/pitch.thtml:54
+msgid "sidebar_pitch_theme"
+msgstr "Gaia"
+
+#: views/elements/pitch.thtml:71
+#, fuzzy
+msgid "sidebar_pitch_updated_addons"
+msgstr "Updated Add-ons"
+
+#. %1$s is a number
+#: views/helpers/localization.php:65 views/developers/versions_edit.thtml:95
+#: views/addons/dictionaries.thtml:92
+#, php-format
+msgid "size_kb"
+msgstr "%1$s KB"
+
+#: views/elements/amo2009/stars.thtml:57 views/elements/stars.thtml:63
+msgid "stars_not_yet_rated"
+msgstr "Puntuatu gabe oraindik"
+
+# %1 is the number of stars this add-on has
+#. %1 is the number of stars this add-on has
+#: views/elements/amo2009/stars.thtml:49 views/elements/stars.thtml:54
+#, php-format
+msgid "stars_rated_x_outof_5"
+msgstr "5etik %s izarrekin baloratua"
+
+#: views/statistics/addon.thtml:59
+msgid "statistics_addon_dashboard_link"
+msgstr "Arbelaren hasiera orria"
+
+#: views/statistics/addon.thtml:58
+msgid "statistics_addon_developertools_link"
+msgstr "Garatzaile-tresnak"
+
+#: views/statistics/addon.thtml:53
+msgid "statistics_addon_switch"
+msgstr "Aldatu gehigarria"
+
+#. This is a date format.
+#. http://php.net/strftime
+#: views/statistics/rss/summary.thtml:54 views/statistics/addon.thtml:181
+msgid "statistics_date_shortmonth"
+msgstr "%b. %e"
+
+#. This is a date format.
+#. http://php.net/strftime
+#: views/statistics/rss/summary.thtml:40 views/statistics/addon.thtml:152
+msgid "statistics_date_shortmonthwithyear"
+msgstr "%Y %b. %e"
+
+#. This is a date format.
+#. http://php.net/strftime
+#: views/statistics/rss/summary.thtml:41 views/statistics/rss/summary.thtml:48
+#: views/statistics/addon.thtml:161 views/statistics/addon.thtml:172
+msgid "statistics_date_weekdayshortmonth"
+msgstr "%b. %e, %A"
+
+#. %1$s is an add-on name and version. Example: Add-on 3.5
+#: controllers/components/stats.php:519
+#, php-format
+msgid "statistics_events_addon_created"
+msgstr "%1$s sortu da"
+
+#. %1$s is an application name and version. Example: Firefox 3.5
+#: controllers/components/stats.php:500
+#, php-format
+msgid "statistics_events_app_released"
+msgstr "%1$s argitaratu da"
+
+#: views/statistics/addon.thtml:71
+msgid "statistics_help_close_link"
+msgstr "Itxi"
+
+#: views/statistics/addon.thtml:60
+msgid "statistics_help_link"
+msgstr "Laguntza"
+
+#: views/statistics/index.thtml:83
+msgid "statistics_index_anotheraddon"
+msgstr "edo, hautatu beste gehigarri bat"
+
+#: views/statistics/index.thtml:85
+msgid "statistics_index_anotheraddon_public"
+msgstr "edo, hautatu estatistika publikoak dituen gehigarri bat"
+
+#: views/statistics/index.thtml:71
+msgid "statistics_index_myaddons"
+msgstr "Aukeratu zure gehigarrietako bat bere estatistikak ikusteko"
+
+#: views/statistics/index.thtml:89
+msgid "statistics_index_selectaddon"
+msgstr "Aukeratu gehigarri bat estatistikak ikusteko"
+
+#: views/statistics/index.thtml:91
+msgid "statistics_index_selectaddon_public"
+msgstr "Aukeratu estatistika publikodun gehigarri bat"
+
+#: views/statistics/index.thtml:39
+msgid "statistics_index_title"
+msgstr "Estatistiken arbela"
+
+#: views/statistics/index.thtml:97
+msgid "statistics_index_view_button"
+msgstr "Ikusi estatistikak"
+
+#: views/statistics/addon.thtml:222 controllers/statistics_controller.php:247
+#, fuzzy
+msgid "statistics_js_download_csv"
+msgstr "View this table in CSV format"
+
+#: controllers/statistics_controller.php:246
+msgid "statistics_js_dropdowns_none"
+msgstr "bat ere ez"
+
+#: controllers/statistics_controller.php:245
+msgid "statistics_js_dropdowns_removeplot"
+msgstr "Ezabatu grafiko hau"
+
+#: controllers/statistics_controller.php:248
+#, fuzzy
+msgid "statistics_js_groupby_selector_date"
+msgstr "Group by: Day"
+
+#: controllers/statistics_controller.php:251
+#, fuzzy
+msgid "statistics_js_groupby_selector_month"
+msgstr "Group by: Month"
+
+#: controllers/statistics_controller.php:249
+#, fuzzy
+msgid "statistics_js_groupby_selector_week"
+msgstr "Group by: Week"
+
+#: controllers/statistics_controller.php:250
+#, fuzzy
+msgid "statistics_js_groupby_selector_week_over_week"
+msgstr "Compare by: Week"
+
+#: controllers/statistics_controller.php:260
+msgid "statistics_js_plotselection_foundinrange"
+msgstr "%s aurkitu dira heinean"
+
+#: controllers/statistics_controller.php:270
+msgid "statistics_js_plotselection_options_addplot_name"
+msgstr "Gehitu grafikoa"
+
+#: controllers/statistics_controller.php:271
+msgid "statistics_js_plotselection_options_addplot_tooltip"
+msgstr "Gehitu beste irudi bat grafikoari"
+
+#: controllers/statistics_controller.php:261
+msgid "statistics_js_plotselection_options_count_name_checked"
+msgstr "Ezkutatu kontu totala "
+
+#: controllers/statistics_controller.php:262
+msgid "statistics_js_plotselection_options_count_name_unchecked"
+msgstr "Erakutsi kontu totala"
+
+#: controllers/statistics_controller.php:263
+#, fuzzy
+msgid "statistics_js_plotselection_options_count_tooltip"
+msgstr "Plot the total count on this graph"
+
+#: controllers/statistics_controller.php:275
+msgid "statistics_js_plotselection_options_csv_name"
+msgstr "Ikusi datuak (CSV)"
+
+#: controllers/statistics_controller.php:276
+msgid "statistics_js_plotselection_options_csv_tooltip"
+msgstr "Lortu datu hauetatik komaz berizitako balioen (CSV) fitxategi bat"
+
+#: controllers/statistics_controller.php:267
+msgid "statistics_js_plotselection_options_events_addon_name_checked"
+msgstr "Ezkutatu %s(r)en gertaerak"
+
+#: controllers/statistics_controller.php:268
+msgid "statistics_js_plotselection_options_events_addon_name_unchecked"
+msgstr "Erakutsi %s(r)en gertaerak"
+
+#: controllers/statistics_controller.php:269
+msgid "statistics_js_plotselection_options_events_addon_tooltip"
+msgstr "Gainjarri grafikoetan gehigarrien kaleratze-datak"
+
+#: controllers/statistics_controller.php:264
+msgid "statistics_js_plotselection_options_events_firefox_name_checked"
+msgstr "Ezkutatu Firefoxen gertaerak"
+
+#: controllers/statistics_controller.php:265
+msgid "statistics_js_plotselection_options_events_firefox_name_unchecked"
+msgstr "Erakutsi Firefoxen gertaerak"
+
+#: controllers/statistics_controller.php:266
+msgid "statistics_js_plotselection_options_events_firefox_tooltip"
+msgstr "Gainjarri grafikoetan Firefoxen kaleratze-datak"
+
+#: controllers/statistics_controller.php:272
+msgid "statistics_js_plotselection_options_resize_name_checked"
+msgstr "Tolestu grafikoa"
+
+#: controllers/statistics_controller.php:273
+msgid "statistics_js_plotselection_options_resize_name_unchecked"
+msgstr "Zabaldu grafikoa"
+
+#: controllers/statistics_controller.php:274
+msgid "statistics_js_plotselection_options_resize_tooltip"
+msgstr "Aldatu tamainaz grafikoa"
+
+#: controllers/statistics_controller.php:254
+msgid "statistics_js_plotselection_selector_adu"
+msgstr "Eguneko erabiltzaile aktiboak"
+
+#: controllers/statistics_controller.php:256
+msgid "statistics_js_plotselection_selector_application"
+msgstr "Aplikazioa"
+
+#: controllers/statistics_controller.php:259
+msgid "statistics_js_plotselection_selector_custom"
+msgstr "Pertsonalizatu"
+
+#: controllers/statistics_controller.php:253
+msgid "statistics_js_plotselection_selector_downloads"
+msgstr "Deskargak"
+
+#: controllers/statistics_controller.php:258
+msgid "statistics_js_plotselection_selector_os"
+msgstr "Sistema Eragilea"
+
+#: controllers/statistics_controller.php:257
+msgid "statistics_js_plotselection_selector_status"
+msgstr "Gehigarriaren egoera"
+
+#: controllers/statistics_controller.php:252
+msgid "statistics_js_plotselection_selector_summary"
+msgstr "Laburpena"
+
+#: controllers/statistics_controller.php:255
+msgid "statistics_js_plotselection_selector_version"
+msgstr "Gehigarriaren bertsioa"
+
+#: controllers/components/stats.php:398
+msgid "statistics_longnames_application"
+msgstr "Aplikazioa"
+
+#: controllers/components/stats.php:400
+msgid "statistics_longnames_os"
+msgstr "Sistema Eragilea"
+
+#: controllers/components/stats.php:399
+msgid "statistics_longnames_status"
+msgstr "Gehigarriaren egoera"
+
+#: controllers/components/stats.php:401
+msgid "statistics_longnames_unknown"
+msgstr "Ezezaguna"
+
+#: controllers/components/stats.php:397
+msgid "statistics_longnames_version"
+msgstr "Gehigarriaren bertsioa"
+
+#: views/statistics/addon.thtml:118
+msgid "statistics_notice_data_insufficient"
+msgstr "Ez dago nahikoa datu grafikoa bistaratzeko. Saiatu beranduago."
+
+#: views/statistics/addon.thtml:130
+msgid "statistics_notice_data_none"
+msgstr "Ez dugu zure gehigarriaren daturik. Saiatu berriro egun gutxi barru."
+
+#: views/statistics/addon.thtml:41
+msgid "statistics_notice_data_updating"
+msgstr ""
+"Gehigarriaren estatistikak eguneratzeko bidean daude. Azkenaldiko datuak "
+"osatu gabe egon litezke, gure scriptak informazio hau eguneratzeko lanean "
+"baitabiltza. Saiatu berriro minutu batzuk barru."
+
+#: views/statistics/addon.thtml:136
+msgid "statistics_notice_disabled"
+msgstr "Estatistiken arbela ezgaituta dago. Saiatu beranduago."
+
+#: views/statistics/addon.thtml:123
+msgid "statistics_notice_nojavascript"
+msgstr "JavaScript beharrezkoa da estatistiken arbeleko grafikoak ikusteko."
+
+#: views/statistics/addon.thtml:44
+msgid "statistics_notice_settings_updated"
+msgstr "Zure ezarpenak eguneratu dira!"
+
+#: controllers/statistics_controller.php:60
+#: controllers/statistics_controller.php:71
+#: controllers/statistics_controller.php:74
+#: controllers/statistics_controller.php:240
+msgid "statistics_pagetitle"
+msgstr "Estatistiken arbela"
+
+#: views/statistics/addon.thtml:99
+msgid "statistics_plot_legend_adu"
+msgstr "Eguneko erabiltzaile aktiboak"
+
+#: views/statistics/addon.thtml:95
+msgid "statistics_plot_legend_downloads"
+msgstr "Eguneko deskargak"
+
+#: views/statistics/addon.thtml:107
+msgid "statistics_plot_options_zoomin_alt"
+msgstr "Gerturatu zooma"
+
+#: views/statistics/addon.thtml:106
+msgid "statistics_plot_options_zoomin_title"
+msgstr "Gerturatu zooma hilabete"
+
+#: views/statistics/addon.thtml:110
+msgid "statistics_plot_options_zoomout_alt"
+msgstr "Urrundu zooma"
+
+#: views/statistics/addon.thtml:109
+msgid "statistics_plot_options_zoomout_title"
+msgstr "Urrundu zooma hilabete"
+
+#: controllers/statistics_controller.php:283
+#, php-format
+msgid "statistics_rss_description"
+msgstr "Estatistiken eguneroko laburpena (%1$s)"
+
+#: views/statistics/rss/summary.thtml:68
+msgid "statistics_rss_title_fulldate"
+msgstr "%Y(e)ko %Bren %e(a), %A"
+
+#: views/statistics/rss/summary.thtml:68
+#, php-format
+msgid "statistics_rss_title_statsfordate"
+msgstr "Honen estatistikak: %1$s"
+
+#: views/statistics/settings.thtml:49
+msgid "statistics_settings_access_description"
+msgstr ""
+"Lehenetsita, zuk eta Mozilla-k soilik atzi dezakezue zure arbeleko "
+"informazioa. Publikora zabal dezakezu edonork ikus ditzan zure gehigarriaren "
+"datuak."
+
+#: views/statistics/settings.thtml:48
+msgid "statistics_settings_access_heading"
+msgstr "Arbelaren atzipena"
+
+#: views/statistics/settings.thtml:51
+msgid "statistics_settings_access_private"
+msgstr "Pribatua"
+
+#: views/statistics/settings.thtml:51
+msgid "statistics_settings_access_private_description"
+msgstr "Zuk eta Mozilla-k ikus ditzakezue soilik gehigarri honen estatistikak"
+
+#: views/statistics/settings.thtml:52
+msgid "statistics_settings_access_public"
+msgstr "Publikoa"
+
+#: views/statistics/settings.thtml:52
+msgid "statistics_settings_access_public_description"
+msgstr "Edonork ikus ditzake gehigarri honen estatistikak"
+
+#: views/statistics/addon.thtml:251
+msgid "statistics_settings_change_link"
+msgstr "Aldatu ezarpenak"
+
+#: views/statistics/addon.thtml:253
+msgid "statistics_settings_confidential"
+msgstr "Mesedez erabili informazio hau konfidentziala balitz bezala."
+
+#: views/statistics/addon.thtml:245
+msgid "statistics_settings_currently_private"
+msgstr "Arbel hau une honetan <b>pribatua</b> da."
+
+#: views/statistics/addon.thtml:241
+msgid "statistics_settings_currently_public"
+msgstr "Arbel hau une honetan <b>publikoa</b> da."
+
+#: views/statistics/addon.thtml:246
+msgid "statistics_settings_locked_alt"
+msgstr "Itxirik"
+
+#: views/statistics/settings.thtml:57
+msgid "statistics_settings_return_link"
+msgstr "Itzuli arbelera"
+
+#: views/statistics/settings.thtml:56
+msgid "statistics_settings_save_button"
+msgstr "Gorde ezarpenak"
+
+#: views/statistics/settings.thtml:46
+#, php-format
+msgid "statistics_settings_title"
+msgstr "Estatistiken arbelaren ezarpenak (%1$s)"
+
+#: views/statistics/addon.thtml:242
+msgid "statistics_settings_unlocked_alt"
+msgstr "Desblokeatua"
+
+#: controllers/components/stats.php:405
+msgid "statistics_shortnames_application"
+msgstr "Apl"
+
+#: controllers/components/stats.php:407
+msgid "statistics_shortnames_os"
+msgstr "SEa"
+
+#: controllers/components/stats.php:406
+msgid "statistics_shortnames_status"
+msgstr "Ego"
+
+#: controllers/components/stats.php:408
+msgid "statistics_shortnames_unknown"
+msgstr "Ee"
+
+#: controllers/components/stats.php:404
+msgid "statistics_shortnames_version"
+msgstr "Ber"
+
+#: views/statistics/rss/summary.thtml:42 views/statistics/addon.thtml:192
+msgid "statistics_summary_downloads_average"
+msgstr "Batez besteko eguneko deskargak"
+
+#: views/statistics/rss/summary.thtml:39
+msgid "statistics_summary_downloads_heading"
+msgstr "Deskargak"
+
+#: views/statistics/rss/summary.thtml:41 views/statistics/addon.thtml:171
+msgid "statistics_summary_downloads_lastcount"
+msgstr "Azken egunean"
+
+#: views/statistics/rss/summary.thtml:43 views/statistics/addon.thtml:199
+msgid "statistics_summary_downloads_lastweek"
+msgstr "Deskargak azken 7 egunetan"
+
+#: views/statistics/rss/summary.thtml:40 views/statistics/addon.thtml:151
+msgid "statistics_summary_downloads_total"
+msgstr "Deskargak guztira"
+
+#: views/statistics/rss/summary.thtml:40 views/statistics/addon.thtml:152
+#, php-format
+msgid "statistics_summary_downloads_total_sincedate"
+msgstr "%1$s(e)tik"
+
+#: views/statistics/rss/summary.thtml:50 views/statistics/rss/summary.thtml:56
+#: views/statistics/addon.thtml:163 views/statistics/addon.thtml:183
+msgid "statistics_summary_nodata"
+msgstr "Daturik ez oraindik"
+
+#: views/statistics/rss/summary.thtml:60 views/statistics/addon.thtml:195
+msgid "statistics_summary_updatepings_average"
+msgstr "Batez besteko eguneko erabiltzaile aktiboak"
+
+#: views/statistics/rss/summary.thtml:52 views/statistics/addon.thtml:177
+msgid "statistics_summary_updatepings_changefromprevious"
+msgstr "Aldaketa aurreko kontagailutik"
+
+#: views/statistics/rss/summary.thtml:54 views/statistics/addon.thtml:181
+#, php-format
+msgid "statistics_summary_updatepings_changefromprevious_ondate"
+msgstr "%1$s %2$s(e)an"
+
+#: views/statistics/rss/summary.thtml:45
+msgid "statistics_summary_updatepings_heading"
+msgstr "Eguneko erabiltzaile aktiboak"
+
+#: views/statistics/rss/summary.thtml:46 views/statistics/addon.thtml:157
+msgid "statistics_summary_updatepings_total"
+msgstr "Eguneko erabiltzaile aktiboak"
+
+#: views/statistics/rss/summary.thtml:48 views/statistics/addon.thtml:161
+#, php-format
+msgid "statistics_summary_updatepings_total_ondate"
+msgstr "%1$s"
+
+#: views/statistics/rss/summary.thtml:61 views/statistics/addon.thtml:203
+#, fuzzy
+msgid "statistics_summary_updatepings_weekly_average"
+msgstr "Average Daily Users this Week"
+
+#. %s is a percentage, like '+22.33%'. It sits next to another number, so
+#. the implied meaning is 'percentage change' from the previous stat point.
+#: views/statistics/rss/summary.thtml:62 views/statistics/addon.thtml:205
+#, fuzzy
+msgid "statistics_summary_updatepings_weekly_change"
+msgstr "%s from last week"
+
+#: views/statistics/addon.thtml:65 controllers/statistics_controller.php:184
+#: controllers/statistics_controller.php:282
+#, php-format
+msgid "statistics_title_addon_stats"
+msgstr "%1$s estatistikak"
+
+#: views/addons/themes_landing.thtml:113
+msgid "themes_landing_all_themes"
+msgstr "Gai guztiak"
+
+#: views/addons/themes_landing.thtml:109
+msgid "themes_landing_browse_themes"
+msgstr "Arakatu gaiak"
+
+#: views/users/edit.thtml:185
+#, fuzzy
+msgid "user_change_email"
+msgstr "Change Email Address"
+
+#: views/users/edit.thtml:169
+msgid "user_change_password"
+msgstr "Aldatu pasahitza"
+
+#: views/users/edit.thtml:96
+#, fuzzy
+msgid "user_change_password_or_email"
+msgstr "Change Password or Email"
+
+#: controllers/users_controller.php:197
+msgid "user_confirmationcode_resent"
+msgstr "Berrespen kodea berriz bidali da!"
+
+# %1 is the email address, %2 is the URL of the user registration page
+#. %1 is the email address, %2 is the URL of the user registration page
+#: views/users/delete.thtml:51
+#, fuzzy
+msgid "user_del_account_deleted"
+msgstr ""
+"Your user account %1$s has been successfully deleted. If you want to come "
+"back some time, you can re-register on the <a href=\"%2$s\">user "
+"registration page</a>."
+
+#: views/users/delete.thtml:102
+#, fuzzy
+msgid "user_del_community_sad"
+msgstr "The Mozilla Add-ons community is sad to see you go."
+
+#: views/users/delete.thtml:123
+#, fuzzy
+msgid "user_del_confirm_password"
+msgstr "Confirm Password"
+
+#: views/users/delete.thtml:134
+#, fuzzy
+msgid "user_del_deletenow"
+msgstr "Delete my user account now"
+
+# %1 is the URL of the user's info page
+#. %1 is the URL of the user's info page
+#: views/users/delete.thtml:64
+#, fuzzy
+msgid "user_del_error_addons"
+msgstr ""
+"You cannot delete your account if you are listed as an <a href=\"%1$s"
+"\">author of any add-ons</a>. To delete your account, please have another "
+"person in your development group delete you from the list of authors for "
+"your add-ons. Afterwards you will be able to delete your account here."
+
+# %1 is a link to the amo-editors mailing list
+#. %1 is a link to the amo-editors mailing list
+#: views/users/delete.thtml:71
+#, fuzzy
+msgid "user_del_error_addons_more_questions"
+msgstr "If you have additional questions, please contact %1$s for assistance."
+
+#: views/users/delete.thtml:78
+#, fuzzy
+msgid "user_del_error_checkbox"
+msgstr ""
+"You need to check the box \"I understand...\" before we can delete your "
+"account."
+
+#: views/users/delete.thtml:84
+#, fuzzy
+msgid "user_del_error_password"
+msgstr "Please enter your password correctly in order to perform this step."
+
+# %1 is a link to the amo-admins mailing list
+#. %1 is a link to the amo-admins mailing list
+#: views/users/delete.thtml:91
+#, fuzzy
+msgid "user_del_error_unknown"
+msgstr ""
+"An unknown error occured deleting your account. Please contact %1$s with the "
+"issue and we will delete it for you. We apologize for the inconvenience."
+
+#: views/users/delete.thtml:110
+#, fuzzy
+msgid "user_del_header_confirm_deletion"
+msgstr "Confirm account deletion"
+
+# %1 is the user's email address
+#. %1 is the user's email address
+#: views/users/delete.thtml:100
+#, fuzzy
+msgid "user_del_header_delete_account"
+msgstr "Delete User Account %1$s"
+
+#: views/users/delete.thtml:50
+#, fuzzy
+msgid "user_del_header_farewell"
+msgstr "Farewell!"
+
+#: views/users/delete.thtml:115
+#, fuzzy
+msgid "user_del_nologin"
+msgstr "You will not be able to log into Mozilla Add-ons anymore."
+
+#: views/users/delete.thtml:112
+#, fuzzy
+msgid "user_del_permanently_removed_means"
+msgstr ""
+"By clicking \"delete\" your account is going to be <strong>permanently "
+"removed</strong>. That means:"
+
+#: views/users/delete.thtml:116
+#, fuzzy
+msgid "user_del_reviews_anonymized"
+msgstr ""
+"Your reviews and ratings will not be deleted, but they will no longer be "
+"associated with you."
+
+# %1 is a link to the amo-editors mailing list
+#. %1 is a link to the amo-editors mailing list
+#: views/users/delete.thtml:104
+#, fuzzy
+msgid "user_del_specific_problem_editors"
+msgstr ""
+"If you have a specific problem we may help you with, please do not delete "
+"your account now, but contact us at %1$s and we will do our best to assist "
+"you in solving it."
+
+#: views/users/delete.thtml:130
+#, fuzzy
+msgid "user_del_understand_permanent"
+msgstr "I understand that this step cannot be undone."
+
+#: views/helpers/addons_html.php:192
+#, fuzzy
+msgid "user_deleted_nickname"
+msgstr "Deleted User"
+
+# %1 is the new email address
+#. %1 is the new email address
+#: views/users/edit.thtml:71
+#, fuzzy
+msgid "user_edit_confirm_email_sent"
+msgstr ""
+"An email has been sent to %1$s to confirm your new email address. For the "
+"change to take effect, you need to click on the link provided in this email. "
+"Until then, you can keep logging in with your current email address."
+
+#: views/users/edit.thtml:201
+#, fuzzy
+msgid "user_edit_delete_user"
+msgstr "Delete user account"
+
+# This contains the email sent to users when they signed up for a new
+# account:
+# %1 is the confirmation URL, %2 is the current app
+#. This contains the email sent to users when they signed up for a new
+#. account:
+#. %1 is the confirmation URL, %2 is the current app
+#: views/users/email/confirm_plain.thtml:6
+#, php-format
+msgid "user_email_confirm_account_nopass"
+msgstr ""
+"Ongi etorri Mozilla Gehigarrietara.\n"
+"\n"
+"Zure kontu berria erabili aurretik gaitu egin behar duzu (honek, erabili "
+"duzun eposta helbidea baliozkoa eta zure jabetzakoa dela egiaztatzen du).\n"
+"Zure kontua gaitzeko, egin klik azpiko loturan edo kopiatu eta itsatsi "
+"guztia nabigatzailearen helbide-barran:\n"
+"\n"
+"%1$s\n"
+"\n"
+"Behin zure kontua gaituta, eposta hau ezaba dezakezu.\n"
+"\n"
+"Milesker %2$s Gehigarriekin bat egiteagatik\n"
+"-- %2$s Gehigarrien Pertsonala"
+
+# %1 is the confirmation url, %2 is the application name
+#. %1 is the confirmation url, %2 is the application name
+#: views/users/email/emailchange_plain.thtml:5
+#, fuzzy
+msgid "user_email_confirm_emailchange"
+msgstr ""
+"You requested a change to your email address at %2$s Add-ons.\n"
+"\n"
+"In order to confirm the new address, please click the link below or copy and "
+"paste the whole thing into your browser's location bar:\n"
+"\n"
+"%1$s\n"
+"\n"
+"You have 48 hours to confirm the new address. If you do not want to change "
+"the address anymore, you can just ignore this email.\n"
+"\n"
+"Thanks!\n"
+"-- %2$s Add-ons Staff"
+
+#: controllers/users_controller.php:168
+#, php-format
+msgid "user_email_confirm_subject"
+msgstr "Milesker Mozilla Gehigarriekin bat egiteagatik"
+
+# This is the password reset email
+# %1 is the pw reset URL
+#. This is the password reset email
+#. %1 is the pw reset URL, %2 is the application
+#: views/users/email/pwreset_plain.thtml:5
+#, php-format
+msgid "user_email_pwreset"
+msgstr ""
+"Mozilla Gehigarrien pasahitza berrezartzea\n"
+"\n"
+"Kontu honen pasahitza berrezartzeko eskaera bat jaso da addons.mozilla.org "
+"gunean. Pasahitz hau aldatzeko egin klik ondorengo loturan edo itsatsi ezazu "
+"nabigatzailearen helbide-barran:\n"
+"\n"
+"%1$s\n"
+"\n"
+"Eposta hau zuk ez baduzu eskatu ez duzu inolako ekintzarik egin behar.\n"
+"\n"
+"Milesker,\n"
+"-- Mozilla Gehigarrien Pertsonala"
+
+#: controllers/users_controller.php:245
+#, php-format
+msgid "user_email_pwreset_subject"
+msgstr "Berrezarri Mozilla Gehigarrietako zure pasahitza"
+
+#: views/users/emailchange.thtml:50
+#, fuzzy
+msgid "user_emailchange_error"
+msgstr "Error!"
+
+# %1 is the application name
+#. %1 is the application name
+#: controllers/users_controller.php:533
+#, fuzzy
+msgid "user_emailchange_subject"
+msgstr "Please confirm your email address change at %1$s Add-ons"
+
+#: views/users/emailchange.thtml:48
+#, fuzzy
+msgid "user_emailchange_success"
+msgstr "Success!"
+
+# %1 is the new email address
+#. %1 is the new email address
+#: views/users/emailchange.thtml:49
+#, fuzzy
+msgid "user_emailchange_successful_description"
+msgstr ""
+"Your email address was changed successfully. From now on, please use %1$s to "
+"log in."
+
+#: views/users/edit.thtml:134 views/admin/users_edit.thtml:111
+#, fuzzy
+msgid "user_form_bio"
+msgstr "About me"
+
+#: views/users/edit.thtml:135 views/admin/users_edit.thtml:112
+#, fuzzy
+msgid "user_form_bio_description"
+msgstr ""
+"Introduce yourself to the community, if you like! This text will appear "
+"publicly on your user info page. Line breaks will be preserved, but no HTML "
+"is allowed."
+
+#: views/users/pwreset.thtml:77 views/users/register.thtml:73
+#: views/users/edit.thtml:181
+msgid "user_form_confirmpassword"
+msgstr "Berretsi pasahitza"
+
+#: views/users/edit.thtml:145
+#, fuzzy
+msgid "user_form_display_collections"
+msgstr "Display the collections I have created in my user profile"
+
+#: views/users/edit.thtml:149
+#, fuzzy
+msgid "user_form_display_collections_fav"
+msgstr "Display my favorite collections in my user profile"
+
+#: views/users/edit.thtml:86
+#, php-format
+msgid "user_form_editprofile"
+msgstr "Editatu %s erabiltzailearen profila"
+
+#: views/users/pwreset.thtml:52 views/users/login.thtml:81
+#: views/users/register.thtml:63 views/users/edit.thtml:187
+msgid "user_form_email"
+msgstr "Eposta helbidea"
+
+#: views/users/register.thtml:78 views/users/edit.thtml:103
+#: views/admin/users_edit.thtml:76
+msgid "user_form_firstname"
+msgstr "Izena"
+
+#: views/users/register.thtml:94 views/users/edit.thtml:119
+#: views/admin/users_edit.thtml:91
+msgid "user_form_hideemail"
+msgstr "Ezkutatu eposta helbidea"
+
+#: views/users/register.thtml:98 views/users/edit.thtml:123
+#: views/admin/users_edit.thtml:99
+msgid "user_form_homepage"
+msgstr "Webgunearen URLa"
+
+#: views/users/register.thtml:84 views/users/edit.thtml:109
+#: views/admin/users_edit.thtml:81
+msgid "user_form_lastname"
+msgstr "Abizena"
+
+#: controllers/users_controller.php:333
+msgid "user_form_login"
+msgstr "Erabiltzailearen saio-hasiera"
+
+#: views/users/pwreset.thtml:72 views/users/edit.thtml:176
+msgid "user_form_newpassword"
+msgstr "Pasahitz berria"
+
+#: views/users/register.thtml:89 views/users/edit.thtml:114
+#: views/admin/users_edit.thtml:86
+msgid "user_form_nickname"
+msgstr "Ezizena"
+
+#: views/users/edit.thtml:171
+msgid "user_form_oldpassword"
+msgstr "Pasahitz zaharra"
+
+#: views/users/edit.thtml:97 views/users/edit.thtml:200
+#, fuzzy
+msgid "user_form_otheractions"
+msgstr "Other Actions"
+
+#: views/users/login.thtml:85 views/users/register.thtml:68
+msgid "user_form_password"
+msgstr "Pasahitza"
+
+#: controllers/users_controller.php:93
+msgid "user_form_registration"
+msgstr "Erabiltzaile berriaren harpidetza"
+
+#: views/users/login.thtml:90
+#, fuzzy
+msgid "user_form_remember_me"
+msgstr "Remember me on this computer"
+
+#: views/admin/users_edit.thtml:95
+msgid "user_form_showsandbox"
+msgstr "Ikusi probagunea?"
+
+#: views/users/edit.thtml:205
+msgid "user_form_submit_edit"
+msgstr "Gorde"
+
+#: views/users/login.thtml:93
+msgid "user_form_submit_login"
+msgstr "Hasi saioa"
+
+#: views/users/register.thtml:113
+msgid "user_form_submit_register"
+msgstr "Harpidetu"
+
+#: views/users/info.thtml:75
+#, php-format
+msgid "user_info_usersince"
+msgstr "%s Gehigarrien erabiltzailea noiztik"
+
+#: views/users/login.thtml:102
+msgid "user_login_register_link"
+msgstr "Sortu erabiltzaile-kontu berria"
+
+#: views/users/edit.thtml:160
+#, fuzzy
+msgid "user_notifications_item_compat"
+msgstr "Add-on Compatibility (strongly recommended)"
+
+#: views/users/edit.thtml:161
+#, fuzzy
+msgid "user_notifications_item_events"
+msgstr "Upcoming events and contests"
+
+#: views/users/edit.thtml:156
+#, fuzzy
+msgid "user_notifications_none_available"
+msgstr "There are currently no notifications available for you to configure."
+
+#: views/users/edit.thtml:158
+#, fuzzy
+msgid "user_notifications_select_topics"
+msgstr ""
+"From time to time, Mozilla may send you email about upcoming releases and "
+"add-on events. Please select the topics you are interested in below:"
+
+#: views/users/edit.thtml:164
+#, fuzzy
+msgid "user_notifications_specific_contact"
+msgstr ""
+"Mozilla reserves the right to contact you individually about specific "
+"concerns with your hosted add-ons."
+
+#: controllers/users_controller.php:543
+msgid "user_profile_edit_error"
+msgstr ""
+"Erroreren bat dago egindako aldaketetan. Mesedez zuzendu itzazu eta bidali "
+"berriro..."
+
+#: controllers/users_controller.php:540
+msgid "user_profile_saved"
+msgstr "Profila eguneratuta."
+
+#: views/users/pwreset.thtml:65
+#, php-format
+msgid "user_pwreset_for_email"
+msgstr "%s(r)en pasahitza berrezarri da"
+
+#: controllers/users_controller.php:226
+msgid "user_pwreset_header"
+msgstr "Berrezarri pasahitza"
+
+#: views/users/login.thtml:103
+msgid "user_pwreset_link"
+msgstr "Zure pasahitza ahaztu duzu?"
+
+#: controllers/users_controller.php:248
+msgid "user_pwreset_link_sent"
+msgstr "Pasahitza berrezartzeko lotura zure eposta helbidera bidali da."
+
+#: controllers/users_controller.php:304
+msgid "user_pwreset_okay"
+msgstr "Pasahitza behar bezala berrezarri da."
+
+#: views/users/pwreset.thtml:82
+msgid "user_pwreset_submit_changepw"
+msgstr "Bidali pasahitz aldaketa"
+
+#: views/users/pwreset.thtml:57
+msgid "user_pwreset_submit_sendlink"
+msgstr "Bidali pasahitza berrezartzeko lotura"
+
+#: views/users/register_complete.thtml:51
+#, php-format
+msgid "user_register_amo_link"
+msgstr "%s Gehigarriak"
+
+# %1 is the user's email address, %2 is the current app
+#. %1 is the user's email address, %2 is the current app
+#: views/users/activatefirst.thtml:49
+#, php-format
+msgid "user_register_click_confirm_link"
+msgstr ""
+"Erabiltzaile kontua gaitzeko lotura %1$s eposta helbidera bidali da. Lotura "
+"hori jarraitu behar duzu %2$s gehigarrietan saioa hasi aurretik."
+
+# %1 is the user's email address
+#. %1 is the user's email address
+#: views/users/register_complete.thtml:49
+#, php-format
+msgid "user_register_confirm_email_sent"
+msgstr ""
+"Erabiltzaile kontua berresteko mezua %1$s eposta helbidera bidali da. Saioa "
+"hasi aurretik kontua gaitu behar duzu eposta horretan bidali den lotura "
+"jarraituz."
+
+#: views/users/activatefirst.thtml:51
+msgid "user_register_confirmation_link_text"
+msgstr "berriz bidali berrespen mezua"
+
+#: views/users/register_complete.thtml:47
+msgid "user_register_congratulations"
+msgstr "Zorionak! zure erabiltzaile kontua behar bezala sortu da!"
+
+#: views/users/register.thtml:50
+#, fuzzy
+msgid "user_register_details"
+msgstr ""
+"<p>Registration on AMO is <strong>not required</strong> if you simply want "
+"to download and install public add-ons.</p><p>You only need to register if:</"
+"p><ul><li>You want to submit reviews for add-ons</li><li>You are an add-on "
+"developer and want to upload your add-on for hosting on AMO</li></ul><p>Upon "
+"successful registration, you will be sent a confirmation email to the "
+"address you provided. Please follow the instructions there to confirm your "
+"account.</p><p>If you like, you can read our <a href='%1$s' title='Legal "
+"Notices'>Legal Notices</a> and <a href='%2$s' title='Privacy Policy'>Privacy "
+"Policy</a>.</p>"
+
+# %1 is the link to the "resend confirmation code" page
+#. %1 is the link to the "resend confirmation code" page
+#: views/users/activatefirst.thtml:51
+#, php-format
+msgid "user_register_resend_confirmation_link"
+msgstr ""
+"Berrespen mezua ez baduzu jasotzen, ziurtatu zure eposta zerbitzuak ez duela "
+"mezua \"zabor-posta\" edo \"spam\" bezala markatu. Behar izanez gero %1$s "
+"aurreko eposta helbidera berriz bidal dezakegu."
+
+# %1 is the link to the Mozilla Add-ons front page
+#. %1 is the link to the Mozilla Add-ons front page
+#: views/users/register_complete.thtml:51
+#, php-format
+msgid "user_register_welcome"
+msgstr "Milesker harpidetzeagatik eta ongi etorri %1$s(e)ra!"
+
+#: views/users/register.thtml:49
+#, fuzzy
+msgid "user_register_welcome_header"
+msgstr "Welcome to addons.mozilla.org (AMO)!"
+
+#: views/users/register.thtml:81 views/users/edit.thtml:106
+#, fuzzy
+msgid "user_required_firstlast_or_nickname"
+msgstr "A first name, last name or nickname is required."
+
+#: views/users/edit.thtml:94 views/users/edit.thtml:142
+#, fuzzy
+msgid "user_tab_collections"
+msgstr "Collections"
+
+#: views/users/edit.thtml:95 views/users/edit.thtml:154
+#, fuzzy
+msgid "user_tab_notifications"
+msgstr "Notifications"
+
+#: views/users/edit.thtml:93 views/users/edit.thtml:101
+#, fuzzy
+msgid "user_tab_profile"
+msgstr "User Profile"
+
+#: controllers/users_controller.php:209
+msgid "user_verified_okay"
+msgstr "Ondo egiaztatu da!"
+
+#: controllers/users_controller.php:723
+#, fuzzy
+msgid "users_delete_pagetitle"
+msgstr "Delete User Account"
+
+#: controllers/users_controller.php:414
+msgid "users_edit_pagetitle"
+msgstr "Erabiltzaile-kontuaren edizioa"
+
+#: views/users/info.thtml:71
+#, fuzzy
+msgid "users_info_aboutme"
+msgstr "About Me"
+
+#: views/users/info.thtml:96
+#, php-format
+msgid "users_info_addons_by_user"
+msgstr "%1$s(r)en gehigarriak"
+
+#: views/users/info.thtml:51
+msgid "users_info_author_name"
+msgstr "Izena"
+
+#: views/users/info.thtml:48
+msgid "users_info_author_profile"
+msgstr "Egilearen profila"
+
+#. %s is the user name
+#: views/users/info.thtml:137
+#, fuzzy
+msgid "users_info_collections_by_user"
+msgstr "Collections by %s"
+
+#: views/users/info.thtml:66
+msgid "users_info_email"
+msgstr "Eposta helbidea"
+
+#: views/users/info.thtml:155
+#, fuzzy
+msgid "users_info_fav_collections_by_user"
+msgstr "Favorite Collections"
+
+#: views/users/info.thtml:61
+msgid "users_info_homepage"
+msgstr "Webgunea"
+
+#: views/users/info.thtml:56
+msgid "users_info_nickname"
+msgstr "Ezizena"
+
+#: controllers/users_controller.php:707
+#, php-format
+msgid "users_info_pagetitle"
+msgstr "%1$s erabiltzailearen informazioa"
+
+# %1 is the user's name
+#. %1 is the user's name
+#: views/users/info.thtml:116
+#, fuzzy
+msgid "users_info_reviews_by_user"
+msgstr "Reviews by %s"
+
+#: controllers/users_controller.php:330 controllers/users_controller.php:332
+msgid "users_login_pagetitle"
+msgstr "Erabiltzailearen saio-hasiera"
+
+# %1 is the link to the sandbox/policy explanation page
+# This message is for a specific add-on not found
+#. %1 is the link to the sandbox/policy explanation page
+#. This message is for a specific add-on not found
+#: views/users/login.thtml:53
+#, php-format
+msgid "users_login_sandbox_display_warning"
+msgstr ""
+"Bila zabiltzan gehigarria probagunean dago momentuz. Dagoeneko Mozilla "
+"Gehigarrien gunean kontu bat baduzu, mesedez saioa hasi edo <a href=\"%1$s"
+"\">ikasi gehiago probaguneari buruz.</a>"
+
+# %1 is the link to the sandbox/policy explanation page
+# This message is for any given sandbox-related page not found
+#. %1 is the link to the sandbox/policy explanation page
+#. This message is for any given sandbox-related page not found
+#: views/users/login.thtml:56
+#, php-format
+msgid "users_login_sandbox_page_warning"
+msgstr ""
+"Bila zabiltzan orrialdea probagunearen zati da. Dagoeneko Mozilla "
+"Gehigarrien gunean kontu bat baduzu, mesedez saioa hasi edo <a href=\"%1$s"
+"\">ikasi gehiago probaguneari buruz.</a>"
+
+#: controllers/users_controller.php:223 controllers/users_controller.php:225
+msgid "users_pwreset_pagetitle"
+msgstr "Berrezarri erabiltzaile pasahitza"
+
+#: controllers/users_controller.php:90 controllers/users_controller.php:92
+msgid "users_register_pagetitle"
+msgstr "Erabiltzaile berriaren harpidetza"
+
+#. %1$s is an addon name, like <a>Firebug</a>
+#. %2$s is a version number, like <a>1.2</a>
+#: views/versions/license.thtml:52
+#, fuzzy
+msgid "versions_license_header_source"
+msgstr "Source code license for %1$s %2$s"
+
+#: views/addons/category_landing.thtml:147
+#, fuzzy
+msgid "view_recently_added"
+msgstr "View all recently added"
+
+#: views/addons/category_landing.thtml:161
+#, fuzzy
+msgid "view_top_downloads"
+msgstr "View all top downloads"
+
+#: views/addons/category_landing.thtml:175
+#, fuzzy
+msgid "view_top_rated"
+msgstr "View all top rated"
+
+#, fuzzy
+#~ msgid "addon_slider_tooltip_next"
+#~ msgstr "Next Add-on"
+
+#, fuzzy
+#~ msgid "addon_slider_tooltip_previous"
+#~ msgstr "Previous Add-on"
+
+#~ msgid "addon_versions_getlatesttext"
+#~ msgstr "Azken bertsio bateragarria"
+
+#~ msgid "addons_display_version_history"
+#~ msgstr "Bertsioen historia osoa"
+
+#~ msgid "addons_home_newest_header"
+#~ msgstr "Berriena:"
+
+#~ msgid "addons_home_popular_header"
+#~ msgstr "Arrakastatsuenak:"
+
+#~ msgid "addons_home_recommended_header"
+#~ msgstr "Gure gomendioak:"
+
+#~ msgid "addons_home_updated_header"
+#~ msgstr "Eguneratu berria:"
+
+#~ msgid "addons_home_view_all"
+#~ msgstr "Ikusi guztiak"
+
+#~ msgid "category_extra_allrecommended"
+#~ msgstr "Ikusi gomendatutako kategoriak"
+
+#~ msgid "category_extra_highestrated"
+#~ msgstr "Puntuaketa onenekoak aurrena"
+
+#~ msgid "category_extra_lastupdated"
+#~ msgstr "Azken eguneraketak lehenengo"
+
+#~ msgid "category_extra_mostpopular"
+#~ msgstr "Gogokoenak lehenengo"
+
+#, fuzzy
+#~ msgid "collections_detail_js_loading"
+#~ msgstr "Loading"
+
+#, fuzzy
+#~ msgid "collections_detail_more_info"
+#~ msgstr "Show More Info"
+
+#~ msgid "devcp_additem_firefox_notice"
+#~ msgstr ""
+#~ "Zure gehigarriaren bertsio hau ez da Firefox %1$s(r)ekin bateragarria. "
+#~ "Mozillak Firefoxen hurrengo bertsioa laster kaleratzeko asmoa du, beraz, "
+#~ "probatu zure gehigarria bertsio berrian eta eguneratu bateragarritasun "
+#~ "informazioa. Honi buruz gehiago irakur dezakezu <a href=\\\"%2$s\\"
+#~ "\">hemen</a>. Honako hau jakinarazpen bat baino ez da, eta bertsio hau "
+#~ "addons.mozilla.org(e)ra bidaltzen jarrai dezakezu."
+
+#~ msgid "devcp_addon_disabled_successfully"
+#~ msgstr "Gehigarria arrakastaz ezgaitu da"
+
+#~ msgid "devcp_addon_edit_pagetitle"
+#~ msgstr "Editatu gehigarria"
+
+#~ msgid "devcp_addon_enabled_successfully"
+#~ msgstr "Gehigarria arrakastaz gaitu da"
+
+#~ msgid "devcp_addon_field_description_displaytitle"
+#~ msgstr "Gehigarriaren azalpena"
+
+#~ msgid "devcp_addon_field_eula_displaytitle"
+#~ msgstr "AELK"
+
+#~ msgid "devcp_addon_field_homepage_displaytitle"
+#~ msgstr "Gehigarriaren webgunea"
+
+#~ msgid "devcp_addon_field_name_displaytitle"
+#~ msgstr "Gehigarriaren izena"
+
+#~ msgid "devcp_addon_field_privacy_displaytitle"
+#~ msgstr "Pribatutasun-politika"
+
+#~ msgid "devcp_addon_field_summary_displaytitle"
+#~ msgstr "Gehigarriaren laburpena"
+
+#~ msgid "devcp_addon_field_supportemail_displaytitle"
+#~ msgstr "Sostengurako Eposta"
+
+#~ msgid "devcp_addon_field_supporturl_displaytitle"
+#~ msgstr "Sostengurako URLa"
+
+#~ msgid "devcp_addon_field_versionnotes_displaytitle"
+#~ msgstr "Bertsio-oharrak"
+
+#~ msgid "devcp_addon_nominate_pagetitle"
+#~ msgstr "Proposatu gehigarria"
+
+#~ msgid "devcp_addon_nominated_successfully"
+#~ msgstr "Gehigarria arrakastaz proposatu da!"
+
+#, fuzzy
+#~ msgid "devcp_addon_status_criteria_review"
+#~ msgstr "Several user reviews of the add-on (may be external reviews)."
+
+# %1 is the addon edit link
+# %2 is the main dev CP link
+#~ msgid "devcp_addon_submission_makechanges"
+#~ msgstr ""
+#~ "%1$s orrira zure bidalketan aldaketak burutzeko edo %2$s orrira "
+#~ "Garatzailearen tresnetara itzultzeko."
+
+#~ msgid "devcp_addon_submission_makechanges_devcp_link"
+#~ msgstr "egin klik hemen"
+
+#~ msgid "devcp_addon_submission_makechanges_link"
+#~ msgstr "Editatu gehigarria"
+
+#~ msgid "devcp_addon_submission_pending"
+#~ msgstr ""
+#~ "Bertsio hau probagunera bidali da bertako probatzaileek eta Mozillako "
+#~ "editore batek berrikusteko. Berrikusketa burutzean posta elektronikoz "
+#~ "jakinaraziko zaizu."
+
+# %1 is the link to the sandbox information page
+#~ msgid "devcp_addon_submission_sandbox_readmore"
+#~ msgstr ""
+#~ "Probaguneko berrikusketa sistemari buruz gehiago irakur dezakezu %s."
+
+#~ msgid "devcp_addon_submission_sandbox_readmore_link"
+#~ msgstr "hemen"
+
+# %1 is the "nominate" link
+#~ msgid "devcp_addon_submission_sandboxed"
+#~ msgstr ""
+#~ "Bertsio hau probagunera bidali da esperientziadun erabiltzaileek erabil "
+#~ "dezaten. Gune publikoan argitaratzea nahi baduzu, zure gehigarria %s "
+#~ "beharko duzu eta berrikusketa prozesua burutu."
+
+#~ msgid "devcp_addon_submission_sandboxed_nominate_link"
+#~ msgstr "proposatu"
+
+#~ msgid "devcp_addon_submission_success"
+#~ msgstr "Zure gehigarriaren bidalketa ondo burutu da."
+
+#~ msgid "devcp_addon_submission_trusted_public"
+#~ msgstr ""
+#~ "Zure gehigarriak konfiantza duenez, bertsio hau automatikoki onartu da "
+#~ "gune publikorako."
+
+#~ msgid "devcp_addon_submit_pagetitle"
+#~ msgstr "Bidali gehigarria"
+
+#~ msgid "devcp_addon_updated_successfully"
+#~ msgstr "Gehigarria ondo eguneratu da"
+
+# %1 is the link to the preview upload page
+#~ msgid "devcp_addon_upload_preview"
+#~ msgstr "Agian %s nahiko duzu zure gehigarriaganako interesa gehitzeko."
+
+#~ msgid "devcp_addon_upload_preview_link"
+#~ msgstr "igo aurrebista"
+
+# #1 is the author email
+#~ msgid "devcp_author_lookup_none_found"
+#~ msgstr "Ez da egilerik aurkitu [%s]"
+
+#~ msgid "devcp_author_lookup_remove"
+#~ msgstr "Ezabatu"
+
+#~ msgid "devcp_button_cancel"
+#~ msgstr "Utzi"
+
+#~ msgid "devcp_button_cancel_confirm"
+#~ msgstr "Ziur zaude bidalketa utzi nahi duzula?"
+
+#~ msgid "devcp_button_next"
+#~ msgstr "Hurrengoa"
+
+#~ msgid "devcp_change_addontype"
+#~ msgstr "Aldatu gehigarri mota:"
+
+#~ msgid "devcp_comments_updated"
+#~ msgstr "Garatzailearen iruzkinak eguneratu dira."
+
+#~ msgid "devcp_details_addpreview_link"
+#~ msgstr "Gehitu aurrebista"
+
+#~ msgid "devcp_details_author"
+#~ msgstr "Egilea"
+
+#~ msgid "devcp_details_authors"
+#~ msgstr "Egileak"
+
+#~ msgid "devcp_details_authors_none"
+#~ msgstr "Bat ere ez"
+
+#~ msgid "devcp_details_categories"
+#~ msgstr "Kategoriak"
+
+#~ msgid "devcp_details_category"
+#~ msgstr "Kategoria"
+
+#~ msgid "devcp_details_description"
+#~ msgstr "Azalpena"
+
+#~ msgid "devcp_details_disabled"
+#~ msgstr "Ezgaituta"
+
+#~ msgid "devcp_details_guid"
+#~ msgstr "GUID"
+
+#~ msgid "devcp_details_header_details"
+#~ msgstr "Xehetasunak"
+
+#~ msgid "devcp_details_header_devcomments"
+#~ msgstr "Garatzailearen iruzkinak"
+
+#~ msgid "devcp_details_header_previews"
+#~ msgstr "Aurrebistak"
+
+#~ msgid "devcp_details_header_versions"
+#~ msgstr "Bertsioak"
+
+#~ msgid "devcp_details_homepage"
+#~ msgstr "Webgunea"
+
+#~ msgid "devcp_details_homepage_none"
+#~ msgstr "Bat ere ez"
+
+#~ msgid "devcp_details_preview_nocaption"
+#~ msgstr "Izenbururik ez"
+
+#~ msgid "devcp_details_previews_nonefound"
+#~ msgstr "Ez da aurrebistarik aurkitu."
+
+#~ msgid "devcp_details_submit_update"
+#~ msgstr "Eguneratu"
+
+#~ msgid "devcp_details_supportemail"
+#~ msgstr "Sostengurako Eposta"
+
+#~ msgid "devcp_details_supportemail_none"
+#~ msgstr "Garatzaileak ez du sostengurako epostarik eman."
+
+#~ msgid "devcp_details_supporturl"
+#~ msgstr "Sostengurako URLa"
+
+#~ msgid "devcp_details_supporturl_none"
+#~ msgstr "Garatzaileak ez du sostengurako URLrik eman."
+
+#~ msgid "devcp_details_trusted"
+#~ msgstr "Konfiantzazkoa"
+
+#~ msgid "devcp_details_versions_none_found"
+#~ msgstr "Ez da bertsiorik aurkitu."
+
+#~ msgid "devcp_disable_cancel"
+#~ msgstr "Utzi eta atzera itzuli"
+
+#~ msgid "devcp_disable_disable_button"
+#~ msgstr "Bai, ezgaitu"
+
+#~ msgid "devcp_disable_disable_confirm"
+#~ msgstr "Ziur gehigarri hau ezgaitu nahi duzula?"
+
+#~ msgid "devcp_disable_disable_description"
+#~ msgstr ""
+#~ "Gehigarri hau ezgaituz gero bilaketa eta zerrendetatik kanpo geratuko da. "
+#~ "Ezin izango da webgunetik deskargatu eta ez ditu eguneratzeak "
+#~ "jakinaraziko. Gehigarria ezabatu egingo da nolabait, nahiz eta hona "
+#~ "itzuli eta bergai dezakezun hala nahi izanez gero."
+
+#~ msgid "devcp_disable_disable_title"
+#~ msgstr "Ezgaitu %s"
+
+#~ msgid "devcp_disable_enable_button"
+#~ msgstr "Bai, gaitu"
+
+#~ msgid "devcp_disable_enable_confirm"
+#~ msgstr "Ziur gehigarri hau gaitu nahi duzula?"
+
+#~ msgid "devcp_disable_enable_description"
+#~ msgstr ""
+#~ "Gehigarri hau gaituz gero bilaketa eta zerrendetan agertuko da berriro. "
+#~ "Webgunetik eta bezeroen eguneraketen bidez deskargatu ahal izango da."
+
+#~ msgid "devcp_disable_enable_title"
+#~ msgstr "Gaitu %s"
+
+#~ msgid "devcp_edit_author_add"
+#~ msgstr "Gehitu egilea"
+
+#~ msgid "devcp_edit_author_email"
+#~ msgstr "Egilearen eposta helbidea"
+
+#~ msgid "devcp_edit_author_remove"
+#~ msgstr "Kendu"
+
+#~ msgid "devcp_edit_error_categories_unavailable"
+#~ msgstr "Ez dago kategoriarik eskuragarri gehigarri-mota honentzat."
+
+#, fuzzy
+#~ msgid "devcp_edit_file_error_incomplete"
+#~ msgstr "Incomplete transfer"
+
+#, fuzzy
+#~ msgid "devcp_edit_file_error_no"
+#~ msgstr "No file uploaded"
+
+#, fuzzy
+#~ msgid "devcp_edit_file_error_size"
+#~ msgstr "Exceeds maximum upload size"
+
+#~ msgid "devcp_edit_header_authors"
+#~ msgstr "Egileak"
+
+#~ msgid "devcp_edit_icon_add_link"
+#~ msgstr "Gehitu ikonoa"
+
+#~ msgid "devcp_edit_icon_change_link"
+#~ msgstr "Aldatu ikonoa"
+
+#~ msgid "devcp_edit_label_allow_viewsource"
+#~ msgstr "Baimendu erabiltzaileei iturburu-fitxategiak linean ikustea"
+
+#~ msgid "devcp_edit_label_categories"
+#~ msgstr "Kategoriak"
+
+#~ msgid "devcp_edit_label_defaultlocale"
+#~ msgstr "Lehenetsitako locale-a"
+
+#~ msgid "devcp_edit_label_icon_delete"
+#~ msgstr "Soilik uneko ikonoa ezabatu"
+
+#~ msgid "devcp_edit_label_icon_new"
+#~ msgstr "Ikono-fitxategi berria"
+
+#~ msgid "devcp_edit_label_info"
+#~ msgstr "Ikonoa"
+
+#~ msgid "devcp_edit_locale_disambiguation_explanation"
+#~ msgstr "info gehigarri laburra (adb. hizkera lokal baten izena)"
+
+#~ msgid "devcp_edit_submit_update"
+#~ msgstr "Eguneratu"
+
+#~ msgid "devcp_edit_target_locale_explanation"
+#~ msgstr ""
+#~ "<a href=\"http://wiki.mozilla.org/L10n:Simple_locale_names\">locale izen "
+#~ "arrunta</a>, hala nola 'en-US'"
+
+#~ msgid "devcp_editversion_checkedfiles_delete"
+#~ msgstr "Markatutako fitxategiak ezabatu egingo dira."
+
+# %1 is the file name
+# %2 is the file size (150 KB)
+#~ msgid "devcp_editversion_filename_size"
+#~ msgstr "%1$s (%2$s)"
+
+#~ msgid "devcp_editversion_label_files"
+#~ msgstr "Fitxategiak"
+
+#~ msgid "devcp_editversion_label_targetapps"
+#~ msgstr "Helburu-aplikazioak"
+
+#~ msgid "devcp_editversion_nofiles"
+#~ msgstr "Fitxategirik ez."
+
+#~ msgid "devcp_editversion_reviewernotes"
+#~ msgstr "Ikuskatzailearentzat oharrak"
+
+#~ msgid "devcp_editversion_submit_update"
+#~ msgstr "Eguneratu"
+
+#~ msgid "devcp_error_addon_field_summary_toolong"
+#~ msgstr ""
+#~ "Laburpenek 250 karaktereko muga dute.\n"
+#~ "(%s sartu dituzu)"
+
+#~ msgid "devcp_error_addonname_not_unique"
+#~ msgstr ""
+#~ "Zure gehigarriaren izena dagoeneko datu-basean existitzen da. Mesedez "
+#~ "ondorengoa ziurtatu: <br /><li>Zure GUID-ak bat datozela. Errore honen "
+#~ "ohiko arrazoia bat ez datozen GUID-ak dira.</li><li>Ez duzula "
+#~ "bikoiztutako sarrerarik datu-basean. Halakorik izatekotan, sarrera hori "
+#~ "eguneratu edo ezabatu beharko zenuke eta berriro saiatu.</li>"
+
+#~ msgid "devcp_error_describe_changes"
+#~ msgstr "Mesedez azaldu gehigarri honen eguneraketan egin diren aldaketak."
+
+#~ msgid "devcp_error_file_guids_dont_match"
+#~ msgstr "Fitxategi guztien GUID-ak ez datoz bat"
+
+#~ msgid "devcp_error_identical_version_exists"
+#~ msgstr ""
+#~ "Dagoeneko pareko bertsio bat (%s) existitzen da gehigarri eta plataforma "
+#~ "honetarako."
+
+#~ msgid "devcp_error_nominate_message"
+#~ msgstr "Eskatutako xehetasunak hornitu behar dituzu proposamenerako."
+
+#~ msgid "devcp_error_nominate_no_prerelease"
+#~ msgstr "Ezin duzu aurre-argitalpena proposatu."
+
+#~ msgid "devcp_error_nominate_sandbox_only"
+#~ msgstr ""
+#~ "Une honetan probagunean dauden gehigarriak soilik proposatu ditzakezu."
+
+#~ msgid "devcp_error_saving"
+#~ msgstr "Errore bat gertatu da zure datuak gordetzen saiatzean."
+
+#~ msgid "devcp_error_update_access_denied"
+#~ msgstr "Ez duzu baimenik gehigarri hau eguneratzeko."
+
+#~ msgid "devcp_file_addanother"
+#~ msgstr "Gehitu beste plataforma bateko fitxategia"
+
+#~ msgid "devcp_form_author_add"
+#~ msgstr "Gehitu egilea"
+
+#~ msgid "devcp_form_author_remove"
+#~ msgstr "Kendu"
+
+#~ msgid "devcp_form_categories_nextstep"
+#~ msgstr ""
+#~ "Zure gehigari-motarentzako kategoriak hurrengo urratsean egongo dira "
+#~ "eskuragarri."
+
+#~ msgid "devcp_form_error_categories_unavailable"
+#~ msgstr "Ez dago kategoriarik eskuragarri gehigarri-mota honentzat."
+
+#~ msgid "devcp_form_error_description_notempty"
+#~ msgstr "Sar ezazu gehigarriarentzako azalpen bat."
+
+#~ msgid "devcp_form_error_name_required"
+#~ msgstr "Sar ezazu gehigarriarentzako izena."
+
+#~ msgid "devcp_form_error_select_addontype"
+#~ msgstr "Aukera ezazu zein gehigarri-mota ari zaren bidaltzen."
+
+#~ msgid "devcp_form_error_summary_notempty"
+#~ msgstr "Sar ezazu gehigarriarentzako laburpen bat."
+
+#~ msgid "devcp_form_label_addonfile"
+#~ msgstr "Gehigarriaren fitxategia"
+
+#~ msgid "devcp_form_label_addonfile2"
+#~ msgstr "Gehigarriaren fitxategia 2"
+
+#~ msgid "devcp_form_label_addonfile3"
+#~ msgstr "Gehigarriaren fitxategia 3"
+
+#~ msgid "devcp_form_label_addontype"
+#~ msgstr "Gehigarri-mota"
+
+#~ msgid "devcp_form_label_allow_viewsource"
+#~ msgstr "Baimendu erabiltzaileak iturburu-fitxategiak linean ikustera"
+
+#~ msgid "devcp_form_label_author_email"
+#~ msgstr "Egilearen eposta helbidea"
+
+#~ msgid "devcp_form_label_authors"
+#~ msgstr "Egileak"
+
+#~ msgid "devcp_form_label_categories"
+#~ msgstr "Kategoriak"
+
+#~ msgid "devcp_form_label_defaultlocale"
+#~ msgstr "Lehenetsitako locale-a"
+
+#~ msgid "devcp_form_label_description"
+#~ msgstr "Azalpena"
+
+#~ msgid "devcp_form_label_eula"
+#~ msgstr "Azken Erabiltzailearentzako Lizentzia-kontratua (AELK)"
+
+#~ msgid "devcp_form_label_externalsoftware"
+#~ msgstr "Gehigarri honek kanpoko softwarea behar du"
+
+#~ msgid "devcp_form_label_files"
+#~ msgstr "Fitxategiak"
+
+#~ msgid "devcp_form_label_homepage"
+#~ msgstr "Webgunea"
+
+#~ msgid "devcp_form_label_iconfile"
+#~ msgstr "Ikono-fitxategia"
+
+#~ msgid "devcp_form_label_name"
+#~ msgstr "Izena"
+
+#~ msgid "devcp_form_label_platforms"
+#~ msgstr "Onartutako plataformak"
+
+#~ msgid "devcp_form_label_prerelease"
+#~ msgstr "Hau aurreargitalpen bat da"
+
+#~ msgid "devcp_form_label_privacy"
+#~ msgstr "Pribatutasun-politika"
+
+#~ msgid "devcp_form_label_sitespecific"
+#~ msgstr "Hau gune konkretu baterako gehigarria da"
+
+#~ msgid "devcp_form_label_summary"
+#~ msgstr "Laburpena"
+
+#~ msgid "devcp_form_label_supportemail"
+#~ msgstr "Sostengurako Eposta"
+
+#~ msgid "devcp_form_label_supporturl"
+#~ msgstr "Sostengurako URLa"
+
+#~ msgid "devcp_form_label_target_applications"
+#~ msgstr "Helburu-aplikazioak"
+
+#~ msgid "devcp_form_label_version"
+#~ msgstr "Bertsioa"
+
+#~ msgid "devcp_form_label_versionnotes"
+#~ msgstr "Bertsio-oharrak"
+
+#~ msgid "devcp_form_no_target_apps"
+#~ msgstr "Bat ere ez"
+
+#~ msgid "devcp_form_reviewernotes"
+#~ msgstr "Ikuskatzailearentzat oharrak"
+
+#~ msgid "devcp_form_trustedaddon_destination"
+#~ msgstr ""
+#~ "Zure gehigarria konfiantzazkoa denez, aukera ezazu bertsio honek non joan "
+#~ "beharko lukeen:"
+
+#~ msgid "devcp_form_trustedaddon_destination_public"
+#~ msgstr "Publikoa"
+
+#~ msgid "devcp_form_trustedaddon_destination_sandbox"
+#~ msgstr "Probagunea"
+
+#~ msgid "devcp_header_developer_agreement"
+#~ msgstr "Garatzaile-kontratua"
+
+#~ msgid "devcp_header_step1"
+#~ msgstr "1. urratsa"
+
+#~ msgid "devcp_header_step1_upload"
+#~ msgstr "Igo fitxategia"
+
+#~ msgid "devcp_header_step2"
+#~ msgstr "2. urratsa"
+
+#~ msgid "devcp_header_step2_addondetails"
+#~ msgstr "Gehigarriaren xehetasunak"
+
+#~ msgid "devcp_header_step3"
+#~ msgstr "3. urratsa"
+
+#~ msgid "devcp_header_step3_versiondetails"
+#~ msgstr "Bertsioaren xehetasunak"
+
+#~ msgid "devcp_header_step4"
+#~ msgstr "4. urratsa"
+
+#~ msgid "devcp_header_step4_localization"
+#~ msgstr "Lokalizazioa"
+
+#~ msgid "devcp_header_step5"
+#~ msgstr "5. urratsa"
+
+#~ msgid "devcp_header_step5_success"
+#~ msgstr "Eginda"
+
+#~ msgid "devcp_index_header_myaddons"
+#~ msgstr "Nire gehigarriak"
+
+#~ msgid "devcp_nominate_link_returnto_details"
+#~ msgstr "Itzuli gehigarriaren xehetasunetara"
+
+# %1 is the autodetected addon type
+#~ msgid "devcp_notice_autodetected_addontype"
+#~ msgstr "Automatikoki atzemandako gehigarri-mota: %s."
+
+# %1 is the default locale name (English (US))
+# %2 is the default locale code (en-US)
+# %3 is the current page locale name (Deutsch)
+# %4 is the current page locale code (de)
+#~ msgid "devcp_notice_different_defaultlocale"
+#~ msgstr ""
+#~ "Gehigarri honen lehenetsitako locale-a (%1$s [%2$s]) zuk aukeratuta "
+#~ "daukazunarekin alderatuta ezberdina da (%3$s [%4$s]). Azpiko eremuak %1$s "
+#~ "locale-an bete behar dira."
+
+#~ msgid "devcp_question_addontype_incorrect"
+#~ msgstr "Ezegokia?"
+
+#~ msgid "devcp_question_delete_file"
+#~ msgstr "Ziur zaude fitxategi hau ezabatu nahi duzula?"
+
+#~ msgid "devcp_skip_reviewing_addon_info"
+#~ msgstr "Saltatu nire uneko gehigarriaren informazioa berrikustea"
+
+#~ msgid "devcp_submissions_disabled"
+#~ msgstr ""
+#~ "Gehigarrien bidalketak ezgaituta daude momentuz. Mesedez beranduago "
+#~ "egiaztatu."
+
+#~ msgid "devcp_submit_accept_dev_agreement"
+#~ msgstr "Onartzen dut"
+
+#~ msgid "devcp_submit_decline_dev_agreement"
+#~ msgstr "Uko egiten dut"
+
+#~ msgid "devcp_summary_admin_disabled"
+#~ msgstr "Gehigarri hau kudeatzaileak ezgaitu du."
+
+#~ msgid "devcp_summary_header_disabled"
+#~ msgstr "Ezgaituta"
+
+#~ msgid "devcp_summary_header_trusted"
+#~ msgstr "Konfiantzazkoa"
+
+# %1 is a link to the addon submit page
+#~ msgid "devcp_summary_noaddons_submit_one"
+#~ msgstr "Ez duzu gehigarririk. Egin klik %s bat bidaltzeko."
+
+#~ msgid "devcp_summary_noaddons_submit_one_link"
+#~ msgstr "hemen"
+
+# %1 is the link to the preview upload page
+#~ msgid "devcp_theme_upload_preview"
+#~ msgstr "Mesedez egiaztatu zure gaiarentzat %s."
+
+#~ msgid "devcp_theme_upload_preview_link"
+#~ msgstr "aurrebista igotzeaz"
+
+#~ msgid "devcp_version_edit_pagetitle"
+#~ msgstr "Editatu bertsioa"
+
+#~ msgid "devcp_version_updated_successfully"
+#~ msgstr "Bertsioa arrakastaz eguneratu da."
+
+#~ msgid "editors_submissiontype_new"
+#~ msgstr "Berria"
+
+#~ msgid "editors_submissiontype_updated"
+#~ msgstr "Eguneratuta"
+
+#, fuzzy
+#~ msgid "editors_th_addon_age"
+#~ msgstr "Addon Age"
+
+#~ msgid "editors_th_addontypes"
+#~ msgstr "Gehigarri-motak"
+
+#~ msgid "editors_th_age"
+#~ msgstr "Adina"
+
+#~ msgid "editors_th_applications"
+#~ msgstr "Aplikazioak"
+
+#~ msgid "editors_th_platforms"
+#~ msgstr "Plataformak"
+
+#~ msgid "editors_th_submissiontypes"
+#~ msgstr "Bidalketa-motak"
+
+#~ msgid "error_notice"
+#~ msgstr "Oharra"
+
+#~ msgid "forum_save"
+#~ msgstr "Gorde"
+
+#, fuzzy
+#~ msgid "home"
+#~ msgstr "home"
+
+#, fuzzy
+#~ msgid "nav_category_plugins"
+#~ msgstr "Plugins"
+
+#, fuzzy
+#~ msgid "page_title_experimental_addons"
+#~ msgstr "Experimental Add-ons"
+
+#, fuzzy
+#~ msgid "pages_experimental_addons_backbutton"
+#~ msgstr "Back to the previous page"
+
+# %1 is page number, %2 is total page count
+#~ msgid "pagination_page_number_title"
+#~ msgstr "Orria: %1$s / %2$s"
+
+#~ msgid "search_matching_addons_number"
+#~ msgid_plural "search_matching_addons_number"
+#~ msgstr[0] "gehigarri %s aurkitu da"
+#~ msgstr[1] "%s gehigarri aurkitu dira"
+
+#~ msgid "statistics_rss_icon_title"
+#~ msgstr "Laburpen-datuen RSS jarioa"
diff --git a/site/app/locale/eu/images/sandbox-review.png b/site/app/locale/eu/images/sandbox-review.png
new file mode 100644
index 0000000..a18cfea
--- /dev/null
+++ b/site/app/locale/eu/images/sandbox-review.png
Binary files differ
diff --git a/site/app/locale/eu/pages/error404.thtml b/site/app/locale/eu/pages/error404.thtml
new file mode 100644
index 0000000..f062e40
--- /dev/null
+++ b/site/app/locale/eu/pages/error404.thtml
@@ -0,0 +1,16 @@
+<h1>Barkatu, baina ezin izan dugu bila zabiltzana aurkitu.</h1>
+
+<p>Eskatu duzun orria edo fitxategia ez da gure webgunean aurkitu. Agian zaharkituriko lotura bat klikatu duzu, edo ez duzu helbidea behar bezala idatzi.</p>
+
+<ul>
+<li>Helbidea zeuk idatzi baduzu, begiratu ondo idatzi duzun.</li>
+<li>Lotura bati jarraituz iritsi bazara hona, jakinaraziguzu <a href="mailto:webmaster@mozilla.com" title="Page Not Found on Mozilla.com">webmaster@mozilla.com</a> helbidera mezu bat bidaliz. Esaiguzu nondik etorri zaren eta zeren bila zenbiltzan, eta ahal dugun guztia egingo dugu arazoa konpontzeko.</li>
+</ul>
+
+<p>Bestela, webguneko orririk arrakastatsuenetako batera joan zaitezke.</p>
+
+<ul>
+<li>Ezagutu nahi al dituzu <a href="%1$s">gehigarririk arrakastatsuenak</a>?</li>
+<li>Edo <a href="%2$s">gehigarri bat bilatu</a> nahi duzu? Hala bada, zoaz <a href="%2$s">bilaketa orrira</a> edo erabili goiko bilaketa eremua.</li>
+<li>Hasieratik hastea nahiago baduzu, berriz, zoaz <a href="%3$s">gehigarrien hasiera orrira</a>.</li>
+</ul>
diff --git a/site/app/locale/eu/pages/nomination.thtml b/site/app/locale/eu/pages/nomination.thtml
new file mode 100644
index 0000000..0f1baf5
--- /dev/null
+++ b/site/app/locale/eu/pages/nomination.thtml
@@ -0,0 +1,8 @@
+<p>Probagunean dagoen gehigarri bat gune publikoko zati izateko proposatu daiteke, editore baten berrikuspenaren ondoren. Emaitza onak lortzeko, kontuan izan ondorengoa:</p>
+<ul>
+ <li>Aurrebista argazkiak beharrezkoak dira gaientzat eta oso gomendagarriak beste gehigarri motentzat</li>
+ <li>Gehigarriak probagunean nahikoa denbora iragan behar du, erabiltzaileen berrikuspen eta iritziak jasoz</li>
+ <li>Gehigarri publikoek probagunekoek baino kalitate hobea eduki eta weba hobetu behar dute</li>
+ <li>Proposamenetarako kriterioa eskuragarri dago <a href="%s">Gehigarrientzako Politika</a> orrian</li>
+</ul>
+<p>Zure gehigarriak goiko irizpideak betetzen baditu, proposatu dezakezu azpiko botoia sakatuz. Epostaz jakinaraziko zaizu proposamenaren egoera.</p>
diff --git a/site/app/locale/eu/pages/policy.thtml b/site/app/locale/eu/pages/policy.thtml
new file mode 100644
index 0000000..6d2bdde
--- /dev/null
+++ b/site/app/locale/eu/pages/policy.thtml
@@ -0,0 +1,111 @@
+<h1>Gehigarrientzako Arautegia</h1>
+
+<h2>Zer da probagunea?</h2>
+<p>Ikusi %s.</p>
+
+<h2>Zein gehigarri daude probagunean?</h2>
+<p>Probagunean AMO gunea ostatzen duten gehigarri guztiak daude. Gehigarri publikoen bertsio berriak dauzka, eta baita publikoak ez diren gehigarrien bertsioak ere. Gehigarri berri bat, edo existitzen den gehigarri baten eguneraketa bat AMOra bidaltzen denean probagunean kokatzen da.</p>
+
+<p>Gehigarri batzuk, eta hauen bertsio zehatzak, publiko egiten dira berrikuspen prozesuak publikoki erakusteko gertu daudela jakinarazten duenean. Beste gehigarri batzuk probagunean gelditzen dira betiko. Gehigarri hauek probagunea arakatzea erabakitzen duten erabiltzaileek eskuragarri izango dituzte bertako softwarearekin probak egiteko.</p>
+
+<h2>Nola bihurtzen dira gehigarriak publiko?</h2>
+
+<p>
+Probagunea ikusi eta han dauden paketeak probatzen dituzten AMO erabiltzaileak gehigarriak berrikusiko dituzte. AMO erabiltzaileak idatzitako berrikuspen hoiek gehigarria erabilgarria den, ondo eginda dagoen eta prest dagoen Firefox erabiltzaile guztiei eskaintzeko. Berrikuspen hauek, AMO taldeak egindako inspekzioekin batera, gehigarria publikoa egingo den ala ez erabakitzeko baliogarriak izango dira. Batzutan gehigarria prest ez dagoela erabakiko da, edo probagunetik kanpo ateratzea ez dela egokia .</p>
+
+<h2>Zelan sustatu dezaket nire gehigarria publikoa bihurtu dadin? </h2>
+
+<p>Zure gehigarria (eta zure jokabidea!) publikoa izateko baldintzak betetzen dituela uste baduzu, garapen kontrol panelean proposatu dezakezu.</p>
+
+<h2>Gehigarria publikoa izateko zeintzuk dira irizpideak?</h2>
+
+<p>AMOn publikoa den gehigarria kalitate handikoa izan behar du, erabiltzaileari web esperientzia hobea ematen dion bitartean. Erabakia hartzeko ondorengo gauzak begiratzen ditugu:</p>
+
+<h3>Interesa erakusten al duzu?</h3>
+
+<p>Bere gehigarria Firefox erabiltzaileei proposatu duen egileak ardura izan behar du arazo baten berri ematen denean. Bestalde berarekin harremanetan egoteko datuak eguneratuak izan behar ditu eta bere gehigarriak ere eguneratuak izan behar ditu hauek Firefoxeko azken bertsioekin eta AMOren arauen aldaketekin bateragarriak izan daitezen . Honek ez du esan nahi foroetan erabiltzaileek egindako galdera guztiak erantzun behar dituzunik, edo suertatutako akats guztiak konpondu behar dituzunik. Baina ugu arazoaren larritasunaren arabera erantzun egokia emango du espero dugu.zula</p>
+
+<h3>Gehigarria argi eta garbi deskribatuta al dago?</h3>
+
+<p>Erabiltzaileak gehigarri berri bat probatzen duenean gehigarri horretaz espero duena jasotzeak guretzako garrantzi handia dauka . Deskribapenak gehigarriak egiten duenaren xehetasunak eman behar ditu, zelan ateratzen zaion etekinik handiena eta zer espero behar den gehigarria instalatzerakoan. Kanpoko dokumentuei egindako loturak ondo daude, baina deskribapen berak oinarrizko kontzeptuak izan behar ditu, erabiltzaileari gehigarriarekin zer lortuko duen argi utzita.</p>
+
+<p>Bestalde gehigarria hobetzen eta eguneratzen duzun heinean, bertsio oharrak mantentzea garrantzitsua da. Erabiltzaile batek gehigarri baten aurreko bertsioa probatu eta gehigarri horren bertsio berri bat ikusten duenean argi izan behar du zeintzuk diren bertsioaren berrikuntzak eta zelako eragina izango duten eguneroko erabilpenean. (Momentu honetan eguneraketa bat dagoenean erabiltzaileak ez ditu bertsio oharrak ikusten, baina etorkizunean horrela gertatuko da. Bertsio oharrak ondo mantentzen badituzu, erabiltzaileak eskertuko dute.)</p>
+
+<h3>Pribatutasun eta segurtasun arazoak zehatz-mehatz azalduta al daude?</h3>
+
+<p>Galdera hau deskribapen atalari dagokio, baina pribatutasun eta segurtasun arazoak guretzako hain garrantzitsuak direnez aparteko aipamen bat merezi du. Oso erabilgarriak diren eta ondo garatutako hainbat gehigarri erabiltzailearen datu batzuk erabiltzen dituzte, edo gaizki erabiltzen badira segurtasun arriskuak sor ditzakete. Gehigarri hauek AMOren alde publikoan ongi etorriak dira, baina aldez aurretik erabiltzaileari argi utzi behar zaio zeintzuk diren eman daitezkeen arriskuak, eta zer egin dezaketen hauek saihesteko.</p>
+
+<h3>Gehigarria ondo probatu da, eta akats nabarmenik gabe al dabil?</h3>
+
+<p>Gehigarri bat probagunean dagoenean ondo probatua izan den edo ez, guretzako garrantzitsua da publikoa bihurtzeko erabakia hartu behar dugunean. Baita arazo larriak dituen edo nabigatzailean sortutako aldaketak eragin ezkorrak izan dituen edo ez jakitea garrantzi handikoa da. Berrikusleak arazo larrien berri eman badute, esate baterako: performantzia arazo larriak, kraskadurak, gehigarriaren funtzioak erabiltzeko zailtasunak, edo errore kontsolara heldutako etengabeko mezuak ... arazo hauek seriotan hartu behar dituzu eta konpondu arte gehigarria publikoa bihurtzeko proposamena bertan behera utzi beharko zenuke. Gehigarriak ez du zertan zero akats izan behar edo ez du zertan guztiz optimizatua egon behar -- Firefoxek berak ere ez du azken hau guztiz lortzen -- baina eragozpenak gutxitzeko ahalegin dezente espero dugu zugan.</p>
+
+<p>Zure gehigarria AMOren probagunetik kanpo probatua izan bada, zuk agindutako erabiltzaile talde baten bidez edo zure lantaldeko kalitate arduradun batzuen bidez, proposamena egiterakoan argi azaldu beharko zenuke. Egindako proben maila zein izan den jakitea benetan lagungarria izango da erabakia hartzerakoan.</p>
+
+<h3>Gehigarria eta bere egileak erabiltzailearekin daukaten harremana begirune osoz ematen al da?</h3>
+
+<p>Zure gehigarriak ez du zertan erabiltzailea mindu behar, erabiltzaileari iruzurrik egin, edo egiten dituen gauzak erabiltzailearengandik ezkutatu. Erabiltzaileak (eta erabiltzaileak ez direnak ere) iruzkinak egiterakoan batzutan zakarrak dira. Iruzkin hauek iragazteko ahaleginak egiten ditugu. Zuengandik ere erabiltzaileekin mendekua hartzea ekidituko duzuela espero dugu.</p>
+
+<h3>Gehigarria Firefox erabiltzaileen zati zabal batentzako erabilgarria al da?</h3>
+
+<p>Zure gehigarriak ez du zertan Greasemonkey edo FireBug bezain zabala izan behar, baina zure enpresako langile batzuentzako eginda badago edo komunitate oso txiki batentzako bakarrik erabilgarria baldin bada, agian Firefox erabiltzaile guztien aurrean publikoki jartzea ez litzateke egokia izango.</p>
+
+<p>Talde txiki batentzako garatu diren gehigarriak leku egokietan kokatzeko gune honen antolamendua etengabe hobetzen ari gara. Gehigarria modu egokian sailkatzeak eta bere metadatuak eguneratzeak asko lagunduko digu gehigarri hoiek modu egokian plazaratzeko eta bide batez gehigarri horren erabiltzaile potentzialak gehigarria erraz aurkitu dezaten.</p>
+
+<p>Zure gehigarriak zure webgunera bideratutako lastermarkak edo sarbidea baino ez ba du eskaintzen, seguruenik ez da aukeratua izango publikoa izateko. Web aplikazioak eta web zerbitzu berriak maite ditugu, baina AMOn kokatutako Firefoxentzako gehigarri batek erabiltzaileari nabigazio esperientzia hobea eskaini behar dio. Zure gehigarriaren deskribapena nabigazio esperientzian izango ditugun hobekuntzak baino, webgune edo zerbitzu bati buruzko aipamenak baldi baditu, bide okerretik zoaz.</p>
+
+<h3>Gehigarriak ba al ditu marka erregistratu edo egileen eskubideak urratzen?</h3>
+
+<p>Marka erregistratu edo egileen eskubideak urratzen dituzten gehigarriak ezin dira gure zerbitzarietan ostatu, nahiz eta zure nahia minik ez egitea izan. Zure gehigarrian dagoen erregistratutako izen edo irudi bat erabiltzeko baimenik ez baduzu, mesedez ez ezazu gehigarria AMOra igo. Zure gehigarrian beste garatzaile baten kodea erabiltzen baduzu eta egile horren baimenik ez baduzu, mesedez ez ezazu gehigarria AMOra igo. (Marka erregistratu edo egileen eskubidea duen objektu baten jabeak hau erabiltzeko eragozpenak jartzen badizkigu, kasua gure abokatuekin berrikusi eta gero, beharrezkoa bada gehigarria ezabatu egingo dugu. Guzti hau prozesu garestia da proiektuaren baliabideei dagokionez, denbora eta dirua barne. Faborez, izan zaitez begirunetsu eta ez ezazu trabarik jarri.)</p>
+
+<p>Zure gehigarriaren izena edo edukiren batengatik webgunean publikatuko ez dugula uste baduzu edo zalantzak badituzu, amo-editors@mozilla.org helbidean laguntza eskatu dezakezu. GARRANTZITSUA: Talde honek ez dizu aholku legalik emango, eta nahiz eta hasiera batean onetsi, etorkizunean erabakia aldatu dezakegu abokatuek emandako aholkuengatik.</p>
+
+<p>Beste gehigarrien kodea berrerabiltzerakoan, kontutan hartu egile batek horretarako baimenik argi eta garbi ez badu eman -- adibidez kode irekiko lizentziapean argitaratuz -- horretarako baimenik ez duzula onartu behar duzu. Egilearekin harremanetan jarri zaitezke bere baimena jasotzeko, baina ezin dizugu inolako baimen berezirik eman gehigarria aurretik AMO zerbitzarietan egon delako, edo bere egileak kasurik egiten ez dizulako. (Berriz ere aholkularitza legalik eskaintzen ez dugula argi utzi nahi dugu. Zure gehigarriak gure gunearen arauekin nola elkarreragiten duen ohartzen baino ez dizugu.)</p>
+
+<p>Azken hau Mozilla Foundationaren marka erregistratuei ere aplikatzen da, "Mozilla", "Firefox" eta "Thunderbird" barne. Marka erregistratuei buruz Mozillak daukan arautegia nahasteak ekiditeko eginda dago, eta bide batez marka erregistratuak babes ezagatik balio gabe gera ez daitezen; mesedez, babes honen beharra errespeta ezazu eta Mozilla Foundationaren balio handiko aktibo hauek mantentzen lagun gaitzazu.</p>
+
+<h2>Zer gertatzen da zerbait proposatu ostean?</h2>
+
+<p>Zure gehigarria proposatuta dagoenean, AMO Editoreak osatutako talde batek lehenago azaltzen diren irizpideen arabera aztertu egiten du. Publikoa bihurtzeko gertutzat hartzen bada, aztertu eta gero alde publikoan jarriko da eta horren berri eposta batean jasoko duzu.</p>
+
+<p>Gehigarriak AMOren alde publikoan egoteko baldintzak betetzen ez dituela uste badugu, mezu bat bidaliko dizugu horren zergatiekin, eta proposamena zerrendatik ezabatu egingo da. Etorkizunean mezu horretan agertzen diren zergatiak dagoeneko gaindituta daudela uste baduzu, berriz proposatu dezakezu. Errepikatutako proposamenak hobekuntza nabarmenak ez dauzkatenean ez dira begi onez ikusten, beraz hobe zuhurtziaz jokatzea; gailendu baino, haserretu gaitzakezu.</p>
+
+<h2>Beste baten gehigarria proposatu dezaket?</h2>
+
+<p>Momentuz proposamenak egitea gehigarrien egileei eskatzen diegu. Egilea aldaketarekin ados dagoela ziurtatu nahi dugu eta bide batez gehigarriaren egoera egokia dela publikoa bihurtzeko. Zurea ez den gehigarri bat prest dagoela uste baduzu, egilea AMOren arautegiarekin bat datorrela uste baduzu, eta Firefox, gure erabiltzaileak, eta weba orokorrean aldaketa honekin (hau da, ia ehun miloi erabiltzaileentzako erabilgarri jartzea) onura aterako dutela uste baduzu, orduan jarri zaitez gehigarriaren egilearekin harremanetan eta proposatzeko adorea eman.</p>
+
+<h2>Nire gehigarria proposatuen zerrendan denbora luze batez egon da, gorroto al nauzue?</h2>
+
+<p>Ez, ez zaitugu gorrotatzen. Gehigarrien garatzaileak maite ditugu, eta gogor lan egiten dugu pozik egon eta emankorrak izan daitezen. Modu honetan, mundu osoko erabiltzaileak beraien lanaz gozatu dezakete. Baina AMOren alde publikoan egoteak garrantzi handia du guretzako, beraz prozesua arintzeko erabakiak ezin ditugu arinegi hartu. Zure gehigarriaren azterketarako asko itxoiteak frustratzekoa izan daitekeela badakigu, eta itxaronaldia ahalik eta laburren izatea nahi dugu. Probagunean zenbat eta berrikuspen arduratsu eta garbiagoak izan, guretzako azterketak egitea gero eta errazagoa izango da. Zentzu horretan zuen esku dago laguntzea.</p>
+
+<h2>Akats larri bat aurkitu dut nire gehigarrian, eta konponbidea ahalik eta lasterren publikatu nahi dut. Zer egin beharko nuke?</h2>
+
+<p>Gehigarri batean akats larri bat (segurtasuna, egonkortasuna, funtzionaltasun arazo nagusia) badago eta eguneraketa bat berehala kaleratu behar baduzu, eguneraketa bidaltzerakoan "berrikuslearen oharretan" egoera zein den argi utzi behar duzu -- bertsio oharretan ere, noski! Gainera erabiltzaile batzuk bildu nahi izango duzu eguneraketa probatu dezaten eta emaitza probagunean xehetasunez eman dezaten. irc.mozilla.org zerbitzariko #addons gelan agertzen bazara, egoeraren berri eman dezakezu laguntza eske, baina jasankorra eta adeitsua izan zaitez faborez.</p>
+
+<p>Kontuz alarma faltsuekin. Lehentasun handiko eguneraketak ariniketan kaleratzen saiatzen gara, baina horrek bere denbora ematen du, beste gehigarrien azterketari denbora kentzen dio, eta sarritan loa edo gure lagunekin egoteko denbora kentzen digu. Beraz, zerrendan salto egiteko trikimailu hau erabiltzen baduzu, kontuz, ez dugulako begi onez ikusten. Zure gehigarriaren eguneraketarako bide hau egokia den ala ez oso argi ez baduzu, irc.mozilla.org zerbitzariko #addons gelan galdetzea lagungarria egingo zaizu.
+
+<h2>Nire gehigarriaren azterketa bidegabekoa izan dela uste dut. Zer egin dezaket?</h2>
+
+<p>Zure gehigarriari publiko egoera ukatzea akats bat izan dela uste baduzu, zure argudioen zehetasunak amo-editors@mozilla.org helbidera bidali beharko zenituzke. Mesedez, izan zaitez adeitsua eta argia eta saiatu zaitez gaizki ulertua ahalik eta hoberen arrazoitzen. </p>
+
+<p>(Ezezkoa emandakoan bidalitako mezuan agertzen ziren arazo *guztiak* dagoeneko konpondu badituzu, ez zenuke azterketa apelatu beharko, ordea Garapen Kontrol Panelean berriz proposatu beharko zenuke.)</p>
+
+<h2>Nire gehigarria lehen publikoa zen, baina orain probagunean dago. Zer gertatu da? </h2>
+
+<p>Gehigarriak dagoeneko alde publikoan egoteko irizpideak betetzen ez baditu, berriz probagunera mugitu dezakegu. Legalki ekiditen ez badigute behintzat, hau gertatzerakoan mezu bat bidaliko dizugu egindakoaren arrazoien berri ematen.</p>
+
+<p>Webgunean akats bat topatzen baduzu, Bugzillaren bitartez akatsaren berri eman beharko zenuke; "addons.mozilla.org" produktua eta "Public Pages" osagaiak erabili eta ahalik eta xehetasun gehien eman txostena idazterakoan.</p>
+
+<h2>Nire gehigarria publikoa da eta jendeari izugarri gustatzen zaio. Zer egin dezaket gomendatutako gehigarrien artea ager dadin?</h2>
+
+<p>Zure gehigarria gehigarrien boterearen adibide bikaina dela uste baduzu, webaren kontrola eta hedagarritasuna erakusten badu, eta erabiltzailearen esperientzia modu itzelean hobetzen duela uste baduzu, gomendatutako gehigarrien zerrendan egotea eskatu dezakezu. Hau egiteko, amo-editors@mozilla.org helbidera mezu bat bidali zure gehigarriaren ontasunak azaltzen.</p>
+
+<p><b>Gutxienez </b> ondorengo gauzak azaldu behar dituzu:</p>
+<ul>
+<li>erabiltzaileen web esperientzia nola hobetzen den</li>
+<li>gehigarria Firefox erabiltzaile multzo handi batentzako zelan den egokia</li>
+<li>gehigarriak Mozilla proiektuaren balioentzako daukan garrantzia; kontrola erabiltzailearen kontu, pribatutasunaren babesa eta segurtasuna, webaren sarbide unibertsala eta estandar irekiak gehienbat</li>
+<li>zure gehigarria zelan desberdintzen den antzerako gehigarriekin (zein zentzutan den hobea edo txarragoa)</li>
+<li>erabiltzaileengandik, berrikusleengandik, blogariengandik, astronautengandik edo zure etxeko animaliengandik, zelako erantzunak izan dituzun, baikorrak eta ezkorrak direnak</li>
+</ul>
+
+<p>Eskakizunean zenbat eta informazio zabalagoa eman, gero eta prestuago egongo gara onartzeko. Dena den, primeran idatzitako eta xehetasun osoko eskakizuna bidaltzeak ez du gomendatutakoen zerrendan agertzea bermatuko. Azkenean, zerrenda hori Mozillak mantendu behar du, eta erabiltzailearen esperientzia eta babesa beste edozeren gainetik egon behar du.</p>
diff --git a/site/app/locale/eu/pages/sandbox.thtml b/site/app/locale/eu/pages/sandbox.thtml
new file mode 100644
index 0000000..d558e6e
--- /dev/null
+++ b/site/app/locale/eu/pages/sandbox.thtml
@@ -0,0 +1,13 @@
+<h1>Probaguneko Berrikuspen Sistema</h1>
+<h2>Zer da probagunea?</h2>
+<p>Probagunea erabiltzaile aurreratuentzako gunea da, gehigarriak proba ditzaten erabilera orokorrerako baimendu baino lehen. Probagunera sartu ahal izateko zure kontuaren ezarpenetan gaitu beharra daukazu. Kontu handiz instalatu behar dira probaguneko gehigarriak, ez dira eta editore batek berrikusiak izan eta zure konputagailua hondatu dezakete.</p>
+
+<h2>Nola lor dezaket nire gehigarria gune publikoan egotea?</h2>
+<!-- To localize the flowchart image, see http://wiki.mozilla.org/Update:Remora_Sandbox_Flowchart -->
+<div style="text-align: center;">%s</div>
+<ol>
+ <li><b>Bidali zure gehigarria Garatzailearen Kontrol Paneletik.</b> Zure gehigarria berehala ageriko da Mozilla Gehigarrien "Probagunea"n, eta bertan erabiltzaile aurreratuek probatu eta beren iritzia emango dute. Probagunea ikusi ahal izateko zure kontuaren ezarpenetan gaitu beharko duzu.</li>
+ <li><b>Proposatu zure gehigarria publiko izan dadin.</b> Garatzailearen Kontrol Panelean zure gehigarria proposatzeko lotura bat aurkituko duzu. Proposamena egin ostean, zure gehigarria Editoreentzat Proposaturikoen Zerrendan agertuko da berrikuspen zain.</li>
+ <li><b>Editore batek zure gehigarria berrikusiko du.</b> Mozilla Gehigarrien guneko editore batek zure gehigarria instalatuko du eta funtzionatzen duen ikusiko. Probaguneko beste erabiltzaileek emandako iritziak ere kontuan hartuko ditu.</li>
+ <li><b>Zure gehigarria publiko egingo da edo probagunean mantenduko.</b> Editoreak zure gehigarria publiko egingo du, edo probagunean mantenduko. Probagunean uzten badu, editoreak iruzkinetan gomendaturiko aldaketak egin ostean berriro proposatu ahalko duzu. Publiko bilakatzen bada, zure gehigarriaren bertsio berriak probagunean agertuko dira berriro editore batek berrikusi eta publikatu arte. Behin zure gehigarria publiko bilakatzean, ez dago berriro proposatu beharrik - bertsio berriak automatikoki bidaliko dira berrikuspenerako zerrendara.</li>
+</ol> \ No newline at end of file
diff --git a/site/app/locale/eu/pages/submission_help.thtml b/site/app/locale/eu/pages/submission_help.thtml
new file mode 100644
index 0000000..4c83d5f
--- /dev/null
+++ b/site/app/locale/eu/pages/submission_help.thtml
@@ -0,0 +1,35 @@
+<h1>Bidalketarako Laguntza</h1>
+Nahitaez bete beharreko eremuak <b>hizki lodiz</b> daude. Hautazkoak <i>hizki etzanez</i>.
+<h2 id="step1">1. urratsa: Igo</h2>
+<ul class="submissionHelp">
+ <li><span class="required">Gehigarri Mota</span> - Defektuz, gehigarri mota igotako fitxategiaren arabera zehaztuko da automatikoki. Ez zenuke eremu honetako balioa aldatu beharrik izango.</li>
+ <li><span class="required">Gehigarri Fitxategia</span> - Zure gehigarriaren pakete fitxategia, osorik dagokion install.rdf fitxategiarekin. Fitxategiak plataforma zehatz batetan bakarrik funtzionatzen badu, plataforma hori aukeratuz fitxategi ugari aldi bakarrean igotzeko aukera dago.</li>
+ <li><span class="optional">Ikono Fitxategia</span> - Ikono fitxategia gehigarriaren izenaren alboan erakutsiko da, gehigarriaren orrian, eta baita instalatzerakoan ere. Automatikoki 32x32 pixeletara bihurtuko da, bere gutxi gora-beherako itxura mantenduz.</li>
+ <li><span class="required">Hizkuntza Lehenetsia</span> - Gehigarri baten hizkuntza lehenetsia honen hizkuntza nagusia da. Erabiltzaileak aukeraturiko hizkuntza ez badago eskuragarri, lehenetsitakoa da erabiliko dena.</li>
+ <li><span class="optional">Nire gehigarriaren uneko informazioa ez berrikusi</span> - Aurretik dagoen gehigarri bat eguneratzen bazabiltza, eremu hau azalduko zaizu. Aukera markatuz gero 3. urratsera egingo du jauzi, bertan bertsioari dagokion informazioa sartu ahal duzularik.</li>
+</ul>
+
+<h2 id="step2">2. urratsa: Gehigarriaren Xehetasunak</h2>
+<ul class="submissionHelp">
+ <li><span class="required">Izena</span> - Gehigarriaren izena hizkuntza lehenetsian.</li>
+ <li><span class="required">Egileak</span> - Gehigarrien zerrenda aldatzeko baimena duten erabiltzaile guztiak, gehigarriaren orrian egile gisa azalduko direnak.</li>
+ <li><span class="required">Kategoriak</span> - Gehigarriari egokitzen zaizkion kategoriak.</li>
+ <li><span class="optional">Webgunea</span> - Gehigarriaren webgunea hizkuntza lehenetsian.</li>
+ <li><span class="required">Laburpena</span> - Gehigarriaren deskribapen labur hizkuntza lehenetsian. Testu eremu honek gehienez 250 karaktere eduki ditzake, eta gehigarriaren orrian eta bilaketen emaitzetan erakutsiko da.</li>
+ <li><span class="required">Deskribapena</span> - Gehigarriaren deskribapena hizkuntza lehenetsian. Gehigarriaren orrian erakutsiko da, laburpenaren ondoren.</li>
+ <li><span class="optional">AELK</span> - Azken Erabiltzailearentzako Lizentzia Kontratua, hizkuntza lehenetsian, onartu beharko dute erabiltzaileek gehigarria jaitsi aurretik.</li>
+ <li><span class="optional">Pribatutasun Politika</span> - Gehigarriaren Pribatutasun Politika, hizkuntza lehenetsian. Pribatutasun Politikan zehazten da zer egiten den erabiltzaileen informazio pertsonalarekin, eta instalatzeko botoiaren alboan egongo den lotura batetik irakurri ahalko da gehigarriaren orrian. Pribatutasun Politikan sartu beharrekoa zer den eta zure gehigarriak halako bat behar ote duen jakiteko informazio gehiago <a href="%s">Gehigarrientzako Arautegia</a>n aurkitu duzu.</li>
+ <li><span class="optional">Erabiltzaileei iturburu fitxategiak online ikustea baimendu</span> - Aukera hau markatuz gero erabiltzaileek zure gehigarriaren iturburu fitxategietan zehar arakatu ahalko dute online.</li>
+ <li><span class="optional">Honakoa aurrebertsio bat da</span> - Aukera hau markatuz gehigarria aurrebertsio edo beta bertsio bat dela jakinaraziko da. Gehigarrien aurrebertsioak probagunean egon behar dira eta ezin dira publikatzeko proposatu etiketa hau kendu baino lehen.</li>
+ <li><span class="optional">Honakoa webgune zehatz baterako da</span> - Aukera hau markatuz gehigarria webgune jakin baterako dela zehazten da, hala nola wegune batek itxura aldatzeko, edo webgune bateko edukia bistaratzeko. Eremu hau lagungarria da editoreentzat eta etorkizunean bilaketak iragazteko erabili ahalko da.</li>
+ <li><span class="optional">Gehigarri honek kanpoko softwarea behar du</span> - Aukera hau markatuz gehigarri honek funtzionatzeko kanpoko softwarea beharrezkoa duela zehazten da. Eremu hau lagungarria da editoreentzat eta etorkizunean bilaketak iragazteko erabili ahalko da.</li>
+</ul>
+
+<h2 id="step3">3. urratsa: Bertsioaren Xehetasunak</h2>
+<ul class="submissionHelp">
+ <li><span class="required optional">Bertsio Oharrak</span> - Bertsio honetako aldaketen laburpen edo zerrendatze bat. Bidalketa berrientzat ez da beharrezkoa, baina eguneraketentzat bai.</li>
+ <li><span class="optional">Berrikusleentzako Oharrak</span> - Eremu hau gehigarria berrikusiko duten editoreei informazioa bidaltzeko erabiltzen da. Berrikuste kontuaren informazioa eta ohar bereziak eman beharko dira hemen.</li>
+</ul>
+
+<h2 id="step4">4. urratsa: Itzulpena</h2>
+Hemen itzul daitezke gehigarrien eremuak onartutako hizkuntza guztietara. Egin klik hizkuntza batean itzulpenak sartzeko eta kitto. \ No newline at end of file
diff --git a/site/app/locale/extract-po.sh b/site/app/locale/extract-po.sh
new file mode 100755
index 0000000..881fc5b
--- /dev/null
+++ b/site/app/locale/extract-po.sh
@@ -0,0 +1,18 @@
+#!/bin/bash
+SOURCE_DIRS="config models views controllers webroot"
+
+cd `dirname $0`/../
+touch messages.po
+
+for sourcedir in $SOURCE_DIRS; do \
+ find ./${sourcedir} -name "*thtml" -or -name "*.php" | xgettext \
+ --language=PHP \
+ --keyword=___ \
+ --keyword=n___:1,2 \
+ --force-po \
+ --omit-header \
+ --join-existing \
+ --sort-output \
+ --copyright-holder="Mozilla Corporation" \
+ --files-from=- # Pull from standard input (our find command) \
+done
diff --git a/site/app/locale/fa/LC_MESSAGES/messages.mo b/site/app/locale/fa/LC_MESSAGES/messages.mo
new file mode 100644
index 0000000..a679112
--- /dev/null
+++ b/site/app/locale/fa/LC_MESSAGES/messages.mo
Binary files differ
diff --git a/site/app/locale/fa/LC_MESSAGES/messages.po b/site/app/locale/fa/LC_MESSAGES/messages.po
new file mode 100644
index 0000000..c4a00e5
--- /dev/null
+++ b/site/app/locale/fa/LC_MESSAGES/messages.po
@@ -0,0 +1,7248 @@
+msgid ""
+msgstr ""
+"Project-Id-Version: addons.mozilla.org\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2009-01-16 11:45-0800\n"
+"PO-Revision-Date: 2009-06-06 17:15+0330\n"
+"Last-Translator: Ehsan Akhgari <ehsan.akhgari@gmail.com>\n"
+"Language-Team: Persian <LL@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=n != 1;\n"
+"X-Generator: Narro 0.9.4 on https://l10n.mozilla.org/narro\n"
+
+#: views/addons/policy.thtml:98
+msgid "a_cancel_installation"
+msgstr "انصرا٠از نصب"
+
+#. This is the text that appears on buttons to download add-ons.
+#. %$1s is an optional string that only appears if the add-on is only available for
+#. a certain platform. Examples: (Windows) or (Linux)
+#. Note that the parentheses are included in the string. :(
+#: views/elements/amo2009/install.thtml:126
+#: views/elements/amo2009/install.thtml:227
+#: views/elements/amo2009/install.thtml:257
+#: views/elements/amo2009/install.thtml:300
+#: views/elements/amo2009/install.thtml:312
+#: views/elements/install.thtml:73
+#: views/elements/install.thtml:181
+#: views/elements/install.thtml:205
+#: views/elements/install.thtml:248
+#: views/elements/install.thtml:260
+#: views/addons/plugins.thtml:66
+#: views/addons/plugins.thtml:76
+#: views/addons/plugins.thtml:86
+#: views/addons/plugins.thtml:96
+#: views/addons/plugins.thtml:119
+#, php-format
+msgid "a_download"
+msgstr "هم‌اکنون بارگیری کنید %s"
+
+#: views/addons/policy.thtml:72
+msgid "a_eula_download"
+msgstr "پذیرÙتن Ùˆ بارگیری"
+
+#: views/addons/policy.thtml:74
+msgid "a_eula_install"
+msgstr "پذیرÙتن Ùˆ نصب"
+
+#: views/elements/header.thtml:76
+#: views/elements/header.thtml:82
+#: views/api/api_addon.thtml:55
+#: views/api/collections_feed.thtml:75
+#: views/sharing_api/addon.thtml:64
+msgid "a_header_public"
+msgstr "عمومی"
+
+#: views/elements/header.thtml:58
+#: views/elements/header.thtml:75
+#: views/elements/header.thtml:80
+#: views/api/api_addon.thtml:57
+#: views/api/collections_feed.thtml:77
+#: views/sharing_api/addon.thtml:66
+msgid "a_header_sandbox"
+msgstr "گودال ماسه‌بازی"
+
+#. %s is a date in the _('date') format
+#: views/elements/amo2009/homepage_addon.thtml:115
+#: views/elements/addon_listitem.thtml:122
+#: views/elements/feature.thtml:106
+#: views/addons/display.thtml:104
+#: views/addons/browse_thumbs.thtml:73
+msgid "addon_detail_last_updated"
+msgstr "به‌هنگام شده در %s"
+
+#. %s is the version of the add-on. Example: 3.2a1
+#: views/elements/amo2009/addon_version_detail.thtml:51
+#: views/elements/addon_version_detail.thtml:51
+#, php-format
+msgid "addon_display_header_version"
+msgstr "نسخهٔ %s"
+
+#: views/addons/browse_thumbs.thtml:80
+msgid "addon_downloads"
+msgstr "بارگیری‌ها"
+
+#: views/addons/display.thtml:147
+msgid "addon_downloads_total"
+msgstr "بارگیری در کل"
+
+#: views/elements/amo2009/homepage_addon.thtml:106
+#: views/elements/addon_listitem.thtml:115
+#: views/elements/feature.thtml:101
+#: views/addons/category_landing.thtml:157
+#: views/addons/display.thtml:146
+#: views/addons/browse_thumbs.thtml:80
+msgid "addon_downloads_weekly"
+msgstr "بارگیری در این Ù‡Ùته"
+
+#. %1 is the add-on count, %2 the category name
+#: views/addons/browse_thumbs.thtml:104
+#: views/addons/browse.thtml:60
+#, php-format
+msgid "addon_list_category_totalcount"
+msgid_plural "addon_list_category_totalcount"
+msgstr[0] "%1$s اÙزودنی"
+msgstr[1] "%1$s اÙزودنی"
+
+#: views/elements/amo2009/addon_list_options.thtml:103
+#: views/elements/pagination.thtml:67
+#: views/elements/addon_list_options.thtml:94
+msgid "addon_list_perpage"
+msgstr "در هر صÙحه"
+
+#: views/elements/amo2009/addon_list_options.thtml:84
+#: views/elements/addon_list_options.thtml:98
+msgid "addon_list_sortby"
+msgstr "مرتب‌سازی بر حسب:"
+
+#: views/helpers/addons_html.php:568
+#: views/elements/amo2009/install.thtml:321
+#: views/elements/feature.thtml:89
+msgid "addon_listitem_flag_experimental"
+msgstr "آزمایشی"
+
+#: views/helpers/addons_html.php:570
+msgid "addon_listitem_flag_recommended"
+msgstr "پیشنهاد شده"
+
+#. %1 is the add-on name, %2 is the platform
+#: views/pages/js_constants.js.thtml:66
+msgid "addon_not_available_for_platform"
+msgstr "%1$s برای %2$s در دسترس نیست."
+
+#. %1 is the add-on name
+#: views/addons/policy.thtml:101
+#: views/addons/previews.thtml:60
+#: views/addons/versions.thtml:130
+#: views/reviews/flag.thtml:61
+#: views/reviews/add.thtml:114
+#: views/reviews/display.thtml:216
+#: views/reviews/review_added.thtml:57
+#, php-format
+msgid "addon_review_a_back_to_addon_x"
+msgstr "بازگشت به %1$s…"
+
+#. %1 is the add-on name
+#: views/reviews/flag.thtml:60
+#: views/reviews/add.thtml:113
+#: views/reviews/review_added.thtml:56
+#, php-format
+msgid "addon_review_a_back_to_reviews"
+msgstr "بازگشت به بررسی‌ها…"
+
+#: views/reviews/add.thtml:85
+msgid "addon_review_add_rating_field"
+msgstr "رتبه:"
+
+#: views/reviews/add.thtml:102
+msgid "addon_review_add_review_field"
+msgstr "بررسی:"
+
+#: views/reviews/add.thtml:107
+msgid "addon_review_add_submit"
+msgstr "ارسال بررسی شما"
+
+#. %s is the name of the add-on
+#: views/reviews/add.thtml:51
+#, php-format
+msgid "addon_review_add_title"
+msgstr "اÙزودن یک بررسی به %s"
+
+#: views/reviews/add.thtml:78
+msgid "addon_review_add_title_field"
+msgstr "عنوان/خلاصه:"
+
+#: views/reviews/display.thtml:77
+#: views/reviews/display.thtml:161
+msgid "addon_review_admin_delete"
+msgstr "حذÙ"
+
+#: views/reviews/display.thtml:76
+msgid "addon_review_author_reply_link"
+msgstr "پاسخ دادن"
+
+#: views/reviews/delete.thtml:62
+msgid "addon_review_confirm_delete"
+msgstr "آیا از حذ٠این بررسی اطمینان دارید؟"
+
+#: views/reviews/delete.thtml:63
+msgid "addon_review_confirm_no"
+msgstr "خیر"
+
+#: views/reviews/delete.thtml:64
+msgid "addon_review_confirm_yes"
+msgstr "بله"
+
+#: views/reviews/delete.thtml:48
+msgid "addon_review_delete_header"
+msgstr "حذ٠بررسی"
+
+#: controllers/reviews_controller.php:449
+msgid "addon_review_deleted_successfully"
+msgstr "بررسی با موÙقیت حذ٠گردید."
+
+#. %s is the name of the add-on
+#: views/reviews/add.thtml:51
+#, php-format
+msgid "addon_review_edit_title"
+msgstr "ویرایش بررسی برای %s"
+
+#. %1 is the count of characters entered as notes for the review flag reason.
+#: controllers/reviews_controller.php:539
+msgid "addon_review_flag_error_other_length"
+msgstr "علامت‌گذاری این بررسی با اشکال مواجه شد: یادداشت‌های مخصوص بررسی‌های علامت‌گذاری شده محدود به ۱۰ تا ۱۰۰ حر٠هستند؛ در حالی که شما %1$s حر٠وارد کرده‌اید."
+
+#. Removing an extra comma
+#: views/reviews/review_added.thtml:53
+msgid "addon_review_in_moderation"
+msgstr "لطÙاً توجه کنید: پیش از آن Ú©Ù‡ بررسی شما در وب‌گاه عمومی ظاهر شود، توسط یک ویرایش‌گر مورد بررسی قرار خواهد گرÙت."
+
+#: views/reviews/add.thtml:57
+msgid "addon_review_in_reply_to"
+msgstr "پاسخ توسعه‌دهنده به:"
+
+#. %1 is the review count, %2 is the nickname or full name of the user.
+#: views/reviews/display.thtml:131
+#, php-format
+msgid "addon_review_others_by_user"
+msgid_plural "addon_review_others_by_user"
+msgstr[0] "%1$s بررسی قبلی ارسال شده توسط %2$s برای این اÙزودنی را مشاهده کنید."
+msgstr[1] "%1$s بررسی قبلی ارسال شده توسط %2$s برای این اÙزودنی را مشاهده کنید."
+
+#. %1 is the add-on name
+#: controllers/reviews_controller.php:201
+#: controllers/reviews_controller.php:250
+#: controllers/reviews_controller.php:345
+#: controllers/reviews_controller.php:424
+#, php-format
+msgid "addon_review_pagetitle"
+msgstr "بررسی‌های %s"
+
+#. %1 is the user, %2 is the (localized) date
+#: views/reviews/display.thtml:160
+#, php-format
+msgid "addon_review_reply_on_x_by_y"
+msgstr "پاسخ از طر٠%1$s در تاریخ %2$s"
+
+#: views/reviews/display.thtml:157
+msgid "addon_review_reply_prefix"
+msgstr "پاسخ توسعه‌دهنده:"
+
+#: views/reviews/review_added.thtml:51
+msgid "addon_review_saved_successfully"
+msgstr "بررسی شما با موÙقیت ذخیره گردید. متشکریم!"
+
+#: views/addons/display.thtml:354
+#: views/reviews/display.thtml:72
+msgid "addon_reviewed_by_u_on_d"
+msgstr "توسط %1$s در تاریخ %2$s"
+
+#. %1 is the user, %2 is the (localized) date, %3 is the rating
+#: views/editors/reviews_queue.thtml:57
+#: views/editors/reviews_queue.thtml:68
+#: views/reviews/add.thtml:63
+#: views/reviews/delete.thtml:54
+#, php-format
+msgid "addon_reviewed_on_x_rated_y"
+msgstr "توسط %1$s در تاریخ %2$s (رتبهٔ %3$s)"
+
+#: views/elements/amo2009/addon_version_detail.thtml:52
+#: views/elements/addon_version_detail.thtml:52
+msgid "addon_version_permalink"
+msgstr "پیوند دائمی به این نسخه"
+
+#. %1 is the current Application name (e.g. Firefox)
+#. %2 is the Application's version number
+#: views/addons/versions.thtml:140
+msgid "addon_versions_getlatestversion"
+msgstr "جدیدترین نسخهٔ سازگار با %1$s %2$s"
+
+#: views/addons/display.thtml:447
+msgid "addons_author_addons_submit"
+msgstr "برو"
+
+#: views/elements/amo2009/homepage_addon.thtml:100
+#: views/elements/feature.thtml:95
+msgid "addons_author_tooltip"
+msgstr "مشاهدهٔ اطلاعات مؤلÙ"
+
+#. %1 is the name of the Application (eg. Firefox)
+#: controllers/addons_controller.php:1296
+msgid "addons_browse_all_themes_title"
+msgstr "مرور همهٔ تم‌ها :: اÙزودنی‌های %1$s"
+
+#. %s is the name of the category
+#: controllers/addons_controller.php:1016
+#, php-format
+msgid "addons_browse_browse_category"
+msgstr "مرور %s"
+
+#. %1 is the name of the theme category (eg. Modern)
+#. %2 is the name of the Application (eg. Firefox)
+#: controllers/addons_controller.php:664
+msgid "addons_browse_categories_header_theme"
+msgstr "مرور تم‌های %1$s :: اÙزودنی‌های %2$s"
+
+#: views/addons/display.thtml:249
+msgid "addons_display_a_license_what"
+msgstr "این چیست؟"
+
+#: views/reviews/display.thtml:222
+msgid "addons_display_add_review"
+msgstr "اÙزودن یک بررسی"
+
+#: views/addons/display.thtml:294
+msgid "addons_display_advanced_details"
+msgstr "جزئیات پیشرÙته"
+
+#: views/addons/display.thtml:98
+msgid "addons_display_categories"
+msgstr "دسته‌ها"
+
+#: views/addons/display.thtml:482
+msgid "addons_display_collection_add"
+msgstr "اÙزودن به یک مجموعه:"
+
+#: views/addons/display.thtml:491
+msgid "addons_display_collection_add_new"
+msgstr "مجموعهٔ جدید..."
+
+#: views/addons/display.thtml:487
+msgid "addons_display_collection_add_select_one"
+msgstr "انتخاب یک مجموعه..."
+
+#: views/addons/display.thtml:493
+msgid "addons_display_collection_add_submit"
+msgstr "منتشر کردن"
+
+#. %1$s is the add-on name
+#. %2$s is the collection name, linked to the collection's page
+#: views/pages/js_constants.js.thtml:103
+#: views/addons/display.thtml:61
+msgid "addons_display_collection_publish_success"
+msgstr "%1$s به مجموعهٔ %2$s اÙزوده شده است."
+
+#: views/addons/display.thtml:483
+msgid "addons_display_collection_whatsthis"
+msgstr "این چیست؟"
+
+#. %1$s is a number
+#: views/addons/display.thtml:473
+msgid "addons_display_collections_more"
+msgid_plural "addons_display_collections_more"
+msgstr[0] "و %1$s مجموعهٔ دیگر"
+msgstr[1] "و %1$s مجموعهٔ دیگر"
+
+#: views/addons/display.thtml:403
+msgid "addons_display_detailed_review"
+msgstr "بررسی Ù…Ùصل"
+
+#: views/reviews/add.thtml:89
+#: views/reviews/add.thtml:90
+msgid "addons_display_dont_like_it"
+msgstr "آن را دوست ندارم"
+
+#: views/reviews/display.thtml:220
+msgid "addons_display_edit_review"
+msgstr "ویرایش بررسی خود"
+
+#: views/addons/display.thtml:132
+msgid "addons_display_has_privacy"
+msgstr "این اÙزودنی دارای یک سیاست Ø­Ùظ حریم خصوصی است."
+
+#: views/reviews/add.thtml:87
+#: views/reviews/add.thtml:88
+msgid "addons_display_hate_it"
+msgstr "از آن متنÙرم"
+
+#: views/addons/display.thtml:462
+msgid "addons_display_header_collections"
+msgstr "مجموعه‌های مربوطه"
+
+#: views/addons/display.thtml:297
+msgid "addons_display_header_developer_comments"
+msgstr "توضیحات توسعه‌دهنده"
+
+#: views/addons/display.thtml:230
+msgid "addons_display_header_homepage"
+msgstr "صÙحهٔ آغازه"
+
+#: views/addons/display.thtml:247
+#: views/addons/versions.thtml:110
+msgid "addons_display_header_license"
+msgstr "مجوز کد منبع"
+
+#: views/addons/display.thtml:337
+msgid "addons_display_header_reviews"
+msgstr "بررسی‌ها"
+
+#: views/addons/display.thtml:261
+msgid "addons_display_header_support"
+msgstr "پشتیبانی"
+
+#: views/reviews/add.thtml:91
+#: views/reviews/add.thtml:92
+msgid "addons_display_like_it"
+msgstr "آن را دوست دارم"
+
+#: views/addons/display.thtml:210
+msgid "addons_display_long_description"
+msgstr "شرح کامل"
+
+#: views/reviews/add.thtml:95
+#: views/reviews/add.thtml:96
+msgid "addons_display_love_it"
+msgstr "عاشق آن هستم"
+
+#: views/addons/display.thtml:178
+msgid "addons_display_more_images"
+msgstr "تصاویر بیشتر"
+
+#: views/addons/display.thtml:465
+msgid "addons_display_nocollections"
+msgstr "این اÙزودنی هنوز در هیچ مجموعه‌ای قرار ندارد"
+
+#. %1$s is either an author's name or a comma separated list of authors. Using
+#. the list doesn't make sense in the English plural form so we ignore the
+#. variable.
+#: views/addons/display.thtml:436
+msgid "addons_display_other_addons_by"
+msgid_plural "addons_display_other_addons_by"
+msgstr[0] "دیگر اÙزودنی‌های %1$s"
+msgstr[1] "دیگر اÙزودنی‌های این مؤلÙان"
+
+#. %s is the name of the add-on and the add-on section. Example:
+#. Some Add-on :: Firefox Add-ons
+#. This should not be concatenated in the code and should be fixed.
+#: controllers/addons_controller.php:141
+#: controllers/addons_controller.php:280
+#: controllers/addons_controller.php:1442
+#, php-format
+msgid "addons_display_pagetitle"
+msgstr "%s"
+
+#. %s is an email address
+#: views/addons/display.thtml:286
+#, php-format
+msgid "addons_display_paragraph_supportinfoemail"
+msgstr "پشتیبانی از این اÙزودنی توسط توسعه‌دهنده در %s ارائه می‌شود"
+
+#. %$1s is a URL
+#. %$2s is an email address
+#: views/addons/display.thtml:269
+#, php-format
+msgid "addons_display_paragraph_supportinfoemailurl"
+msgstr "پشتیبانی از این اÙزودنی توسط توسعه‌دهنده در %s یا با ارسال پست الکترونیکی به %s ارائه می‌شود"
+
+#. %s is a URL
+#: views/addons/display.thtml:278
+#, php-format
+msgid "addons_display_paragraph_supportinfourl"
+msgstr "صÙحهٔ آغازه"
+
+#: views/addons/display.thtml:383
+msgid "addons_display_rate_it"
+msgstr "به این اÙزودنی رتبه بدهید"
+
+#: views/reviews/add.thtml:93
+#: views/reviews/add.thtml:94
+msgid "addons_display_really_like_it"
+msgstr "آن را خیلی دوست دارم"
+
+#: views/addons/display.thtml:410
+msgid "addons_display_review_etiquette"
+msgstr "لطÙاً گزارش مشکلات را در بررسی‌ها ارسال نکنید. ما نشانی پست الکترونیکی شما را در اختیار توسعه‌دهندگان اÙزودنی قرار نمی‌دهیم Ùˆ ممکن است آنها نیاز داشته باشند با شما تماس بگیرند تا به رÙع مشکلتان Ú©Ù…Ú© کنند."
+
+#. %1 is the review guidelines link
+#: views/addons/display.thtml:417
+msgid "addons_display_review_guidelines_link"
+msgstr "<a href=\"%s\">رهنمون‌های انجام بررسی</a>"
+
+#. %1 is the support section link
+#: views/addons/display.thtml:414
+msgid "addons_display_review_see_support"
+msgstr "از <a href=\"%1$s\">بخش پشتیبانی </a> برای Ú©Ù…Ú© گرÙتن دربارهٔ استÙاده از این اÙزودنی بازدید کنید."
+
+#: views/addons/display.thtml:404
+msgid "addons_display_review_submit"
+msgstr "ارسال"
+
+#: views/addons/display.thtml:430
+#, php-format
+msgid "addons_display_see_all_addons"
+msgstr "مشاهدهٔ تمام اÙزودنی‌های %1$s"
+
+#. %1 is the number of reviews
+#: views/addons/display.thtml:364
+#, php-format
+msgid "addons_display_see_all_reviews"
+msgstr "همهٔ بررسی‌ها را مشاهده کنید (تعداد: %1$s)"
+
+#: views/addons/display.thtml:219
+msgid "addons_display_see_all_versions"
+msgstr "مشاهدهٔ تمام نسخه‌ها"
+
+#: views/addons/display.thtml:321
+#: views/addons/versions.thtml:117
+msgid "addons_display_view_source"
+msgstr "مشاهدهٔ متن برنامه"
+
+#: views/addons/display.thtml:324
+msgid "addons_display_view_stats"
+msgstr "مشاهدهٔ آمار"
+
+#: views/addons/display.thtml:376
+msgid "addons_display_what_do_you_think"
+msgstr "شما Ú†Ù‡ Ùکر می‌کنید؟"
+
+#: views/elements/app_compatibility.thtml:49
+msgid "addons_display_workswith"
+msgstr "با این نسخه‌ها کار می‌کند:"
+
+#: views/addons/home.thtml:112
+msgid "addons_home_browse_new"
+msgstr "به تازگی اÙزوده شده"
+
+#: views/addons/home.thtml:110
+msgid "addons_home_browse_popular"
+msgstr "محبوب"
+
+#: views/addons/home.thtml:108
+msgid "addons_home_browse_recommended"
+msgstr "پیشنهاد شده"
+
+#: views/addons/home.thtml:127
+#: views/addons/home.thtml:134
+#: views/addons/home.thtml:141
+#: views/addons/home.thtml:148
+msgid "addons_home_browse_subscribe"
+msgstr "مشترک شدن"
+
+#: views/addons/home.thtml:101
+msgid "addons_home_browse_title"
+msgstr "مرور اÙزودنی‌ها"
+
+#: views/addons/home.thtml:114
+msgid "addons_home_browse_updated"
+msgstr "به‌هنگام شده"
+
+#: views/elements/amo2009/homepage_addon.thtml:100
+#: views/elements/addon_discussionheader.thtml:83
+#: views/elements/addon_listitem.thtml:109
+#: views/elements/feature.thtml:95
+#: views/addons/category_landing.thtml:66
+#: views/addons/policy.thtml:57
+#: views/addons/display.thtml:70
+#: views/addons/home.thtml:178
+msgid "addons_home_by"
+msgstr "توسط"
+
+#: views/addons/home.thtml:169
+msgid "addons_home_collection_popular_title"
+msgstr "مجموعه‌های محبوب"
+
+#: views/elements/amo2009/categories.thtml:69
+#: views/addons/home.thtml:160
+msgid "addons_home_collections"
+msgstr "مجموعه‌ها"
+
+#. %1$s is the count of addons in a collection
+#: views/elements/amo2009/collection_listing_item.thtml:51
+#: views/addons/home.thtml:185
+msgid "addons_home_collections_addon_count"
+msgid_plural "addons_home_collections_addon_count"
+msgstr[0] "<strong>%1$s</strong> اÙزودنی"
+msgstr[1] "<strong>%1$s</strong> اÙزودنی"
+
+#: views/addons/home.thtml:196
+msgid "addons_home_collections_all"
+msgstr "مشاهدهٔ همهٔ مجموعه‌ها"
+
+#: views/addons/home.thtml:162
+msgid "addons_home_collections_intro"
+msgstr "مجموعه‌ها روشی برای سÙارشی‌سازی، ترکیب، تطبیق Ùˆ مخلوط کردن اÙزودنی‌ها در اختیار شما قرار می‌دهند. می‌توانید به عضویت مجموعه‌های ایجاد شده توسط کاربران دیگر درآیید یا مجموعهٔ خود را ایجاد نمایید."
+
+#. %1$s is the count of subscribers for a collection
+#: views/elements/amo2009/collection_listing_item.thtml:58
+#: views/collections/detail.thtml:96
+#: views/addons/home.thtml:189
+msgid "addons_home_collections_subscribers"
+msgid_plural "addons_home_collections_subscribers"
+msgstr[0] "<strong>%1$s</strong> مشترک"
+msgstr[1] "<strong>%1$s</strong> مشترک"
+
+#: views/addons/searchengines.thtml:54
+#: views/addons/themes_landing.thtml:49
+msgid "addons_home_feature_head"
+msgstr "پیشنهاد ما"
+
+#: controllers/search_controller.php:218
+#: controllers/addons_controller.php:176
+#: controllers/addons_controller.php:428
+#: controllers/addons_controller.php:671
+#: controllers/addons_controller.php:871
+#: controllers/addons_controller.php:1103
+#: controllers/addons_controller.php:1242
+#: controllers/addons_controller.php:1298
+#, php-format
+msgid "addons_home_header_details"
+msgstr "اÙزودنی‌ها %1$s را گسترش می‌دهند، Ùˆ به شما امکان می‌دهند تجربهٔ مرور خود را منحصر به Ùرد سازید. نگاهی به اطرا٠بیاندازید Ùˆ %1$s را آن گونه Ú©Ù‡ مایلید تغییر دهید."
+
+#. %1$s is the HTML collection name link.
+#: views/elements/amo2009/teaser_collections.thtml:107
+msgid "addons_home_introduction_collection_link"
+msgstr "از این اÙزودنی‌ها راضی هستید؟ در %1$s می‌توانید اÙزودنی‌های بیشتری پیدا کنید."
+
+#: views/elements/amo2009/teaser_collections.thtml:60
+msgid "addons_home_introduction_extras"
+msgstr "<strong>بیش از ÛµÛ°Û°Û° اÙزودنی رایگان</strong> Ú©Ù‡ به شما امکان گسترش Ùˆ سÙارشی‌سازی ÙایرÙاکس را بر اساس نیازتان می‌دهند."
+
+#: views/elements/amo2009/teaser_collections.thtml:55
+msgid "addons_home_introduction_header"
+msgstr "اÙزودنی‌ها چیستند؟"
+
+#: views/elements/amo2009/teaser_collections.thtml:72
+msgid "addons_home_introduction_install"
+msgstr "<strong>عملیات نصب ساده است</strong>، و هنگامی که به‌هنگام‌سازی‌ای وجود داشته باشد مطلع خواهید شد."
+
+#: views/elements/amo2009/teaser_collections.thtml:45
+msgid "addons_home_introduction_name"
+msgstr "معرÙÛŒ"
+
+#: views/elements/amo2009/teaser_collections.thtml:66
+msgid "addons_home_introduction_themes"
+msgstr "نوار ابزارها، تم‌ها Ùˆ Ùراهم‌کنندگان جست‌وجویی Ú©Ù‡ <strong>به شما در کارهای معمول Ú©Ù…Ú© می‌کنند.</strong>"
+
+#: views/addons/home.thtml:161
+msgid "addons_home_new_indicator"
+msgstr "جدید!"
+
+#: views/elements/app_chooser.thtml:48
+#: views/layouts/amo2009.thtml:257
+msgid "addons_home_other_applications"
+msgstr "برنامه‌های دیگر"
+
+#. %1$s is the application the user is browsing. Examples: Thunderbird, Firefox,
+#. Sunbird
+#: views/pages/collector_faq.thtml:49
+#: views/pages/collector_firstrun.thtml:42
+#: views/pages/collector.thtml:46
+#: views/pages/collector_features.thtml:54
+#: controllers/developers_controller.php:87
+#: controllers/compatibility_controller.php:72
+#: controllers/components/simple_acl.php:81
+#: controllers/components/amo.php:607
+#: controllers/statistics_controller.php:60
+#: controllers/statistics_controller.php:240
+#: controllers/previews_controller.php:67
+#: controllers/users_controller.php:90
+#: controllers/users_controller.php:223
+#: controllers/users_controller.php:330
+#: controllers/users_controller.php:414
+#: controllers/users_controller.php:708
+#: controllers/users_controller.php:723
+#: controllers/reviews_controller.php:204
+#: controllers/reviews_controller.php:251
+#: controllers/reviews_controller.php:346
+#: controllers/reviews_controller.php:425
+#: controllers/search_controller.php:185
+#: controllers/search_controller.php:297
+#: controllers/search_controller.php:301
+#: controllers/addons_controller.php:147
+#: controllers/addons_controller.php:280
+#: controllers/addons_controller.php:370
+#: controllers/addons_controller.php:667
+#: controllers/addons_controller.php:874
+#: controllers/addons_controller.php:1019
+#: controllers/addons_controller.php:1034
+#: controllers/addons_controller.php:1101
+#: controllers/addons_controller.php:1121
+#: controllers/addons_controller.php:1240
+#: controllers/addons_controller.php:1357
+#: controllers/addons_controller.php:1364
+#: controllers/addons_controller.php:1442
+#: controllers/addons_controller.php:1477
+#: controllers/addons_controller.php:1538
+#: controllers/addons_controller.php:1543
+#: controllers/editors_controller.php:64
+#: controllers/pages_controller.php:132
+#: controllers/groups_controller.php:65
+#: controllers/groups_controller.php:71
+#: controllers/groups_controller.php:89
+#: controllers/groups_controller.php:111
+#: controllers/collections_controller.php:57
+#: controllers/collections_controller.php:121
+#: controllers/collections_controller.php:205
+#: controllers/collections_controller.php:365
+#: controllers/collections_controller.php:404
+#: controllers/collections_controller.php:466
+#: controllers/collections_controller.php:538
+#: controllers/collections_controller.php:828
+#: controllers/localizers_controller.php:72
+#, php-format
+msgid "addons_home_pagetitle"
+msgstr "اÙزودنی‌های %1$s"
+
+#. %1$s is the number of addons downloaded
+#: views/addons/home.thtml:57
+#, php-format
+msgid "addons_home_stats_downloaded"
+msgid_plural "addons_home_stats_downloaded"
+msgstr[0] "<strong>%1$s</strong> <span>اÙزودنی دریاÙت شده</span>"
+msgstr[1] "<strong>%1$s</strong> <span>اÙزودنی دریاÙت شده</span>"
+
+#. %1$s is the number of addons in use
+#: views/addons/home.thtml:63
+#, php-format
+msgid "addons_home_stats_inuse"
+msgid_plural "addons_home_stats_inuse"
+msgstr[0] "<strong>%1$s</strong> <span>اÙزودنی در حال استÙاده</span>"
+msgstr[1] "<strong>%1$s</strong> <span>اÙزودنی در حال استÙاده</span>"
+
+#: views/addons/home.thtml:136
+msgid "addons_home_view_all_newest_title"
+msgstr "مشاهدهٔ همهٔ اÙزودنی‌های به تازگی ایجاد شده"
+
+#: views/addons/home.thtml:129
+msgid "addons_home_view_all_popular_title"
+msgstr "مشاهدهٔ همهٔ اÙزودنی‌های محبوب"
+
+#: views/addons/home.thtml:150
+msgid "addons_home_view_all_recommended_title"
+msgstr "مشاهدهٔ همهٔ اÙزودنی‌های پیشنهاد شده"
+
+#: views/addons/home.thtml:143
+msgid "addons_home_view_all_updated_title"
+msgstr "مشاهدهٔ همهٔ اÙزودنی‌های به تازگی به‌هنگام شده"
+
+#: views/elements/amo2009/install.thtml:334
+#: views/elements/install.thtml:112
+msgid "addons_install_in_sunbird"
+msgstr "<ol><li>برای ذخیره کردن پرونده روی پیوند زیر کلیک کنید.</li><li>در موزیلا سان‌برد، از منوی ابزارها گزینهٔ اÙزودنی‌ها را انتخاب کنید.</li><li>دکمهٔ نصب را Ùشار دهید Ùˆ پرونده‌ای Ú©Ù‡ بارگیری نموده‌اید را انتخاب نمایید Ùˆ دکمهٔ «تأیید» را Ùشار دهید.</li></ol>"
+
+#: views/elements/amo2009/install.thtml:333
+#: views/elements/install.thtml:111
+msgid "addons_install_in_sunbird_title"
+msgstr "چگونه در سان‌برد نصب کنیم"
+
+#: views/elements/amo2009/install.thtml:331
+#: views/elements/install.thtml:106
+msgid "addons_install_in_thunderbird"
+msgstr "<ol><li>بر پیوند زیر کلیک راست کنید Ùˆ گزینهٔ «ذخیرهٔ پیوند به نام…» را انتخاب کنید تا پرونده بر روی دیسک سخت‌تان ذخیره شود.</li><li> در موزیلا تاندربرد، از منوی ابزارها، اÙزودنی‌ها را انتخاب کنید.</li><li>دکمهٔ «نصب» را Ùشار دهید، Ùˆ پرونده‌ای را Ú©Ù‡ بارگیری کرده‌اید انتخاب نمایید Ùˆ دکمهٔ «تأیید» را Ùشار دهید.</li></ol>"
+
+#: views/elements/amo2009/install.thtml:330
+#: views/elements/install.thtml:105
+msgid "addons_install_in_thunderbird_title"
+msgstr "چگونه در تاندربرد نصب کنیم"
+
+#: views/elements/amo2009/addon_list_options.thtml:108
+#: views/elements/addon_list_options.thtml:105
+msgid "addons_options_show_experimental"
+msgstr "نمایش اÙزودنی‌های آزمایشی"
+
+#: views/elements/amo2009/addon_list_options.thtml:113
+#: views/elements/addon_list_options.thtml:109
+msgid "addons_options_submit"
+msgstr "پشتیبانی از این اÙزودنی توسط توسعه‌دهنده در %s ارائه می‌شود"
+
+#: views/addons/plugins.thtml:63
+#: views/addons/plugins.thtml:73
+#: views/addons/plugins.thtml:83
+#: views/addons/plugins.thtml:93
+#: views/addons/plugins.thtml:103
+#: views/addons/plugins.thtml:116
+#: views/addons/plugins.thtml:126
+msgid "addons_plugins_by"
+msgstr "توسط"
+
+#: views/addons/plugins.thtml:107
+msgid "addons_plugins_for_linux"
+msgstr "مخصوص لینوکس"
+
+#: views/addons/plugins.thtml:108
+#: views/addons/plugins.thtml:131
+msgid "addons_plugins_for_macosx"
+msgstr "مخصوص مک‌اÙواÙس اÙکس"
+
+#: views/addons/plugins.thtml:106
+#: views/addons/plugins.thtml:129
+#: views/addons/plugins.thtml:130
+msgid "addons_plugins_for_windows"
+msgstr "مخصوص ویندوز"
+
+#. %1$s is a URL
+#: views/addons/plugins.thtml:139
+#, php-format
+msgid "addons_plugins_looking_for_more"
+msgstr "این صÙحه تنها تعدادی از معمول‌ترین Ùˆ محبوب‌ترین متصل‌شونده‌ها را Ùهرست کرده است. برای اطلاعات بیشتر دربارهٔ متصل‌شونده‌های دیگر در دسترس برای مرورگرهای بر پایهٔ موزیلا، از %1$s بازدید کنید"
+
+#: views/addons/plugins.thtml:137
+msgid "addons_plugins_looking_for_plugin"
+msgstr "به دنبال متصل‌شونده‌ای می‌گردید که در اینجا وجود ندارد؟"
+
+#: views/addons/plugins.thtml:58
+msgid "addons_plugins_main_description"
+msgstr "متصل‌شونده‌ها به مرورگرتان Ú©Ù…Ú© می‌کنند کارهای خاصی مانند مشاهدهٔ قالب‌های خاص گراÙیکی یا پخش پرونده‌های چندرسانه‌ای انجام دهد. متصل‌شونده‌ها Ú©Ù…ÛŒ با ضمیمه‌ها Ú©Ù‡ توانایی‌های موجود را گسترش می‌دهند یا بهبود می‌بخشند تÙاوت دارند."
+
+#. %1$s is the application name. Example: Firefox, Thunderbird, Sunbird
+#: controllers/addons_controller.php:1122
+#, php-format
+msgid "addons_plugins_main_header"
+msgstr "متصل‌شونده‌های %1$s"
+
+#: controllers/components/amo.php:698
+#: controllers/addons_controller.php:1121
+msgid "addons_plugins_pagetitle"
+msgstr "متصل‌شونده‌ها"
+
+#: views/addons/plugins.thtml:68
+#: views/addons/plugins.thtml:78
+#: views/addons/plugins.thtml:88
+#: views/addons/plugins.thtml:98
+#: views/addons/plugins.thtml:110
+#: views/addons/plugins.thtml:121
+#: views/addons/plugins.thtml:133
+msgid "addons_plugins_support_documentation"
+msgstr "مستندات پشتیبانی: "
+
+#. %s is the name of the add-on
+#: views/addons/policy.thtml:61
+#, php-format
+msgid "addons_policy_eula_require"
+msgstr "پیش از ادامهٔ نصب، %s شما را ملزم به پذیرÙتن تواÙق‌نامهٔ مجوز کاربر نهایی زیر می‌کند:"
+
+#. %1 is the add-on name
+#: controllers/addons_controller.php:1476
+#, php-format
+msgid "addons_previews_pagetitle"
+msgstr "پیش‌نمایش‌های مخصوص %s"
+
+#: views/addons/category_landing.thtml:135
+msgid "addons_recently_added"
+msgstr "به تازگی اÙزوده شده"
+
+#: views/addons/recommended.thtml:51
+#: controllers/addons_controller.php:1365
+msgid "addons_recommended_introduction"
+msgstr "با این همه اÙزودنی‌های عالی Ú©Ù‡ وجود دارد، هر کس چیزی پیدا خواهد کرد. برای شروع، این Ùهرستی از محبوب‌ترین اÙزودنی‌هاست. لذت ببرید!"
+
+#: controllers/addons_controller.php:1357
+#: controllers/addons_controller.php:1364
+msgid "addons_recommended_pagetitle"
+msgstr "اÙزودنی‌های پیشنهاد شده"
+
+#: controllers/addons_controller.php:1360
+msgid "addons_recommended_title"
+msgstr "اÙزودنی‌های پیشنهاد شده"
+
+#: views/addons/searchengines.thtml:136
+msgid "addons_searchengines_additional_resources"
+msgstr "منابع دیگر"
+
+#. link text devmo
+#: views/addons/searchengines.thtml:141
+msgid "addons_searchengines_devmo_link"
+msgstr "مرکز توسعه‌دهندگان موزیلا"
+
+#: views/pages/js_constants.js.thtml:67
+msgid "addons_searchengines_error_mozilla_browser_required"
+msgstr "متأسÙیم، شما نیاز به یک مرورگر بر پایهٔ موزیلا (مانند ÙایرÙاکس) دارید تا بتوانید یک متصل‌شوندهٔ جست‌وجو نصب کنید."
+
+#: views/addons/searchengines.thtml:49
+msgid "addons_searchengines_error_nojavascript"
+msgstr "جاوا اسکریپت برای نصب اÙزودنی‌ها لازم است، ولی به نظر می‌رسد شما آن را غیر Ùعال کرده‌اید. لطÙاً جاوا اسکریپت را پیش از تلاش برای نصب هر یک از متصل شونده‌های جست‌وجوی زیر Ùعال سازید."
+
+#. %1 is "make your own" link
+#. %2 is MDC link
+#: views/addons/searchengines.thtml:139
+msgid "addons_searchengines_learn_howto"
+msgstr "در %2$s یاد بگیرید چگونه %1$s."
+
+#. link path to search plugins instructions, relative to devmo
+#: views/addons/searchengines.thtml:140
+msgid "addons_searchengines_makeyourown_href"
+msgstr "/en/docs/Creating_OpenSearch_plugins_for_Firefox"
+
+#. link text for "make your own" (opensearch engine)
+#: views/addons/searchengines.thtml:140
+msgid "addons_searchengines_makeyourown_link"
+msgstr "اÙزودنی خود را بسازید"
+
+#. %1 is the link to mycroft.mozdev.org
+#: views/addons/searchengines.thtml:138
+msgid "addons_searchengines_more"
+msgstr "گشتن در میان موتورهای جست‌وجوی بیشتری در %1$s"
+
+#. link text to mycroft.mozdev.org
+#: views/addons/searchengines.thtml:138
+msgid "addons_searchengines_mycroft_link"
+msgstr "mycroft.mozdev.org"
+
+#: controllers/addons_controller.php:1100
+#: controllers/addons_controller.php:1110
+msgid "addons_searchengines_pagetitle"
+msgstr "موتورهای جست‌وجو"
+
+#: views/addons/searchengines.thtml:143
+msgid "addons_searchengines_thanks"
+msgstr "تشکر خاص از پروژهٔ مایکراÙت برای کار بر روی موتورهای جست‌وجوی ÙایرÙاکس."
+
+#: views/addons/display.thtml:154
+msgid "addons_share_button_text"
+msgstr "به اشتراک گذاشتن"
+
+#: controllers/addons_controller.php:89
+msgid "addons_share_label_delicious"
+msgstr "اÙزودن به Delicious"
+
+#: controllers/addons_controller.php:77
+msgid "addons_share_label_digg"
+msgstr "اÙزودن به Digg"
+
+#: controllers/addons_controller.php:83
+msgid "addons_share_label_facebook"
+msgstr "ارسال به Facebook"
+
+#: controllers/addons_controller.php:101
+msgid "addons_share_label_friendfeed"
+msgstr "به اشتراک گذاشتن در FriendFeed"
+
+#: controllers/addons_controller.php:95
+msgid "addons_share_label_myspace"
+msgstr "ارسال به MySpace"
+
+#: controllers/components/amo.php:201
+#: controllers/components/amo.php:229
+msgid "addons_status_disabled"
+msgstr "غیر Ùعال"
+
+#: controllers/components/amo.php:191
+#: controllers/components/amo.php:224
+msgid "addons_status_incomplete"
+msgstr "نسخهٔ ناقص"
+
+#: controllers/components/amo.php:197
+#: controllers/components/amo.php:227
+msgid "addons_status_nominated"
+msgstr "در گودال ماسه‌بازی، نامزد عمومی شدن"
+
+#: views/pages/js_constants.js.thtml:80
+#: controllers/components/amo.php:195
+#: controllers/components/amo.php:226
+msgid "addons_status_pending"
+msgstr "در گودال ماسه‌بازی، در انتظار بررسی"
+
+#: views/pages/js_constants.js.thtml:78
+#: controllers/components/amo.php:199
+#: controllers/components/amo.php:228
+msgid "addons_status_public"
+msgstr "عمومی"
+
+#: views/pages/js_constants.js.thtml:79
+#: controllers/components/amo.php:193
+#: controllers/components/amo.php:225
+msgid "addons_status_sandbox"
+msgstr "در گودال ماسه‌بازی"
+
+#: controllers/components/amo.php:203
+msgid "addons_status_unknown"
+msgstr "نامعلوم"
+
+#: views/elements/amo2009/teaser_collections.thtml:91
+#: views/elements/amo2009/homepage_addon.thtml:99
+#: views/elements/feature.thtml:94
+msgid "addons_title_tooltip"
+msgstr "دربارهٔ این اÙزودنی بیشتر بدانید"
+
+#: views/addons/category_landing.thtml:151
+msgid "addons_top_downloads"
+msgstr "بیشترین بارگیری"
+
+#: views/addons/category_landing.thtml:165
+msgid "addons_top_rated"
+msgstr "بالاترین رتبه"
+
+#: views/addons/versions.thtml:62
+msgid "addons_versions_careful"
+msgstr "مراقب نسخه‌های قدیمی باشید"
+
+#: views/addons/versions.thtml:63
+msgid "addons_versions_careful_introduction"
+msgstr "این نسخه‌ها تنها برای رجوع Ùˆ آزمایش نمایش داده می‌شوند. همیشه باید از جدیدترین نسخهٔ اÙزودنی استÙاده کنید."
+
+#: controllers/addons_controller.php:1549
+msgid "addons_versions_history"
+msgstr "تاریخچهٔ نسخه‌ها به همراه Ùهرست تغییرات"
+
+#. %1$s is the add-on name
+#: controllers/addons_controller.php:1535
+#, php-format
+msgid "addons_versions_pagetitle"
+msgstr "تاریخچهٔ نسخه‌های %1$s"
+
+#: controllers/groups_controller.php:71
+msgid "admin_group_add_pagetitle"
+msgstr "اÙزودن گروه"
+
+#: controllers/groups_controller.php:111
+msgid "admin_group_delete_pagetitle"
+msgstr "حذ٠گروه"
+
+#. %s is a number to identify the group
+#: controllers/groups_controller.php:117
+#, php-format
+msgid "admin_group_deleted"
+msgstr "گروه با شناسهٔ %s حذ٠گردید"
+
+#: controllers/groups_controller.php:89
+msgid "admin_group_edit_pagetitle"
+msgstr "ویرایش گروه"
+
+#: controllers/groups_controller.php:92
+#: controllers/groups_controller.php:113
+msgid "admin_group_error_invalid_id"
+msgstr "شناسهٔ نامعتبر برای گروه"
+
+#: controllers/groups_controller.php:65
+msgid "admin_group_pagetitle"
+msgstr "مدیر گروه"
+
+#: controllers/groups_controller.php:77
+#: controllers/groups_controller.php:99
+msgid "admin_group_saved"
+msgstr "گروه ذخیره گردید"
+
+#: views/elements/amo2009/search.thtml:257
+#: views/elements/search.thtml:239
+msgid "advanced_search_form"
+msgstr "پیشرÙته"
+
+#: views/elements/amo2009/search.thtml:126
+#: views/elements/search.thtml:125
+msgid "advanced_search_form_any_time"
+msgstr "هر زمان"
+
+#: views/elements/amo2009/search.thtml:97
+#: views/elements/amo2009/search.thtml:110
+#: views/elements/search.thtml:96
+#: views/elements/search.thtml:109
+msgid "advanced_search_form_any_type"
+msgstr "هرچه"
+
+#: views/elements/amo2009/search.thtml:275
+#: views/elements/search.thtml:254
+msgid "advanced_search_form_any_version"
+msgstr "هرچه"
+
+#: views/elements/amo2009/search.thtml:217
+#: views/elements/search.thtml:212
+msgid "advanced_search_form_application"
+msgstr "برنامه"
+
+#: views/elements/amo2009/search.thtml:143
+#: views/elements/search.thtml:142
+msgid "advanced_search_form_keyword_match"
+msgstr "تطابق واژهٔ کلیدی"
+
+#: views/elements/amo2009/search.thtml:251
+#: views/elements/search.thtml:225
+msgid "advanced_search_form_lastupdate"
+msgstr "آخرین به‌هنگام‌سازی"
+
+#: views/elements/amo2009/search.thtml:145
+#: views/elements/search.thtml:144
+msgid "advanced_search_form_name"
+msgstr "نام"
+
+#: views/elements/amo2009/search.thtml:144
+#: views/elements/search.thtml:143
+msgid "advanced_search_form_newest"
+msgstr "جدیدترین"
+
+#: views/elements/amo2009/search.thtml:130
+#: views/elements/search.thtml:129
+msgid "advanced_search_form_past_3_months"
+msgstr "۳ ماه گذشته"
+
+#: views/elements/amo2009/search.thtml:131
+#: views/elements/search.thtml:130
+msgid "advanced_search_form_past_6_months"
+msgstr "۶ ماه گذشته"
+
+#: views/elements/amo2009/search.thtml:127
+#: views/elements/search.thtml:126
+msgid "advanced_search_form_past_day"
+msgstr "روز گذشته"
+
+#: views/elements/amo2009/search.thtml:129
+#: views/elements/search.thtml:128
+msgid "advanced_search_form_past_month"
+msgstr "ماه گذشته"
+
+#: views/elements/amo2009/search.thtml:128
+#: views/elements/search.thtml:127
+msgid "advanced_search_form_past_week"
+msgstr "Ù‡Ùتهٔ گذشته"
+
+#: views/elements/amo2009/search.thtml:132
+#: views/elements/search.thtml:131
+msgid "advanced_search_form_past_year"
+msgstr "سال گذشته"
+
+#: views/elements/amo2009/search.thtml:239
+#: views/elements/search.thtml:230
+msgid "advanced_search_form_perpage"
+msgstr "در هر صÙحه"
+
+#: views/elements/amo2009/search.thtml:243
+#: views/elements/search.thtml:224
+msgid "advanced_search_form_platform"
+msgstr "بستر نرم‌اÙزاری"
+
+#: views/elements/amo2009/search.thtml:147
+#: views/elements/search.thtml:146
+msgid "advanced_search_form_popularity"
+msgstr "محبوبیت"
+
+#: views/elements/amo2009/search.thtml:146
+#: views/elements/search.thtml:145
+msgid "advanced_search_form_rating"
+msgstr "رتبه"
+
+#: views/elements/amo2009/search.thtml:247
+#: views/elements/search.thtml:231
+msgid "advanced_search_form_sortby"
+msgstr "مرتب‌سازی بر حسب"
+
+#: views/elements/amo2009/search.thtml:227
+#: views/elements/search.thtml:216
+msgid "advanced_search_form_to"
+msgstr "تا"
+
+#: views/elements/amo2009/search.thtml:257
+#: views/elements/search.thtml:237
+msgid "advanced_search_form_toggle_tooltip"
+msgstr "رÙتن به حالت جست‌وجوی پیشرÙته"
+
+#: views/elements/amo2009/search.thtml:235
+#: views/elements/search.thtml:223
+msgid "advanced_search_form_type"
+msgstr "نوع"
+
+#: views/elements/amo2009/search.thtml:222
+#: views/elements/search.thtml:214
+msgid "advanced_search_form_version"
+msgstr "نسخهٔ"
+
+#: views/elements/amo2009/pagination.thtml:42
+msgid "amo2009_pagination_next_page"
+msgstr "بعدی"
+
+#: views/elements/amo2009/pagination.thtml:41
+msgid "amo2009_pagination_previous_page"
+msgstr "قبلی"
+
+#: views/pages/js_constants.js.thtml:96
+msgid "app_compat_ignore_check"
+msgstr "صرÙ‌نظر از کنترل تطابق نسخهٔ اÙزودنی"
+
+#: views/pages/js_constants.js.thtml:72
+msgid "app_compat_older_firefox_only"
+msgstr "این اÙزودنی مخصوص نسخه‌های پیشین ÙایرÙاکس است"
+
+#. %1$s and %2$s are URLs
+#: views/pages/js_constants.js.thtml:74
+msgid "app_compat_older_version_or_ignore_check"
+msgstr "می‌توانید <a href=\"%1$s\">نسخه‌ای قدیمی‌تر را امتحان کنید</a> یا <a href=\"#\" onclick=\"%2$s\">از انجام این وارسی صرÙ‌نظر کنید</a>"
+
+#. %1$s is a URL
+#: views/pages/js_constants.js.thtml:71
+msgid "app_compat_try_old_version"
+msgstr "<a href=\"%1$s\">نسخه‌ای قدیمی‌تر</a> ممکن است به کار بیاید"
+
+#. %1$s is a URL
+#. %2$s is a version number. Example: 3.1
+#: views/pages/js_constants.js.thtml:73
+msgid "app_compat_unreleased_version"
+msgstr "این اÙزودنی نیازمند <a href=\"%1$s\">ÙایرÙاکس %2$s</a> است Ú©Ù‡ هنوز منتشر نشده است"
+
+#: views/pages/js_constants.js.thtml:70
+msgid "app_compat_update_firefox"
+msgstr "برای استÙاده از این اÙزودنی، <a href=\"http://getfirefox.com\">ÙایرÙاکس را ارتقا دهید</a>"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#. %3$s is a status, like Public.
+#: controllers/components/audit.php:79
+#, fuzzy
+msgid "audit_addon_status"
+msgstr "%1$s changed the status of %2$s to %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:221
+#, fuzzy
+msgid "audit_admin_default"
+msgstr "%1$s committed unknown admin action %2$s to ID %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:153
+#, fuzzy
+msgid "audit_admin_feature_remove"
+msgstr "%1$s removed feature %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is an application, like Firefox.
+#: controllers/components/audit.php:92
+#, fuzzy
+msgid "audit_application_create"
+msgstr "%1$s created application %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is an application, like Firefox.
+#: controllers/components/audit.php:95
+#, fuzzy
+msgid "audit_application_edit"
+msgstr "%1$s edited application %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a version number, like 3.5.
+#. %3$s is an application, like Firefox.
+#: controllers/components/audit.php:105
+#, fuzzy
+msgid "audit_appversion_create"
+msgstr "%1$s created version %2$s for %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a version number, like 3.5.
+#. %3$s is an application, like Firefox.
+#: controllers/components/audit.php:108
+#, fuzzy
+msgid "audit_appversion_delete"
+msgstr "%1$s deleted version %2$s for %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a config field, like "awesomeness".
+#. %3$s is a config value, like "off".
+#. %4$s is a config value, like "on".
+#: controllers/components/audit.php:210
+#, fuzzy
+msgid "audit_config"
+msgstr "%1$s changed config '%2$s' from '%3$s' to '%4$s'"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:258
+#, fuzzy
+msgid "audit_editor_default"
+msgstr "%1$s committed unknown editor action %2$s to ID %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#: controllers/components/audit.php:236
+#, fuzzy
+msgid "audit_editor_feature_remove"
+msgstr "%1$s removed addon %2$s from feature list"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#: controllers/components/audit.php:231
+#, fuzzy
+msgid "audit_feature_add"
+msgstr "%1$s added addon %2$s to feature list"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:149
+#, fuzzy
+msgid "audit_feature_edit"
+msgstr "%1$s changed a feature for %2$s locale"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#: controllers/components/audit.php:241
+#, fuzzy
+msgid "audit_feature_locale_change"
+msgstr "%1$s changed locales for addon %2$s on feature list"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:83
+#, fuzzy
+msgid "audit_file_recalchash"
+msgstr "%1$s recalculated the hash for file %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>user name</a>
+#. %3$s is <a>group name</a>
+#: controllers/components/audit.php:182
+#, fuzzy
+msgid "audit_group_addmember"
+msgstr "%1$s added %2$s to group %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:313
+#, fuzzy
+msgid "audit_group_associated"
+msgstr "%1$s associated themselves with %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:162
+#, fuzzy
+msgid "audit_group_create"
+msgstr "%1s created group %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:170
+#, fuzzy
+msgid "audit_group_delete"
+msgstr "%1$s deleted group %2$s (ID %3$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:165
+#, fuzzy
+msgid "audit_group_edit"
+msgstr "%1$s edited group %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>user name</a>
+#. %3$s is <a>group name</a>
+#: controllers/components/audit.php:188
+#, fuzzy
+msgid "audit_group_removemember"
+msgstr "%1$s removed %2$s from group %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:280
+#, fuzzy
+msgid "audit_l10n_default"
+msgstr "%1$s committed unknown action %2$s for %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:295
+#, fuzzy
+msgid "audit_modify_locked_group"
+msgstr "%1$s attempted to modify locked group %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:299
+#, fuzzy
+msgid "audit_modify_other_locale"
+msgstr "%1$s attempted to modify translations in %2$s without permission"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a platform, like <a>Windows</a>
+#: controllers/components/audit.php:135
+#, fuzzy
+msgid "audit_platform_create"
+msgstr "%1$s created platform %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a platform, like <a>Windows</a>
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:143
+#, fuzzy
+msgid "audit_platform_delete"
+msgstr "%1$s deleted platform %2$s (ID %3$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a platform, like <a>Windows</a>
+#: controllers/components/audit.php:138
+#, fuzzy
+msgid "audit_platform_edit"
+msgstr "%1$s edited platform %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a part of the admin, like 'Site Config'
+#: controllers/components/audit.php:288
+#, fuzzy
+msgid "audit_reauthentication_failure"
+msgstr "%1$s failed to re-authenticate to access %2$s."
+
+#. %1$s is <a>user name</a>
+#. %2$s is the name of a canned response, like 'Ready for the public'
+#: controllers/components/audit.php:198
+#, fuzzy
+msgid "audit_response_create"
+msgstr "%1$s created response %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is the name of a canned response, like 'Ready for the public'
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:206
+#, fuzzy
+msgid "audit_response_delete"
+msgstr "%1$s deleted response %2$s (ID %3$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is the name of a canned response, like 'Ready for the public'
+#: controllers/components/audit.php:201
+#, fuzzy
+msgid "audit_response_edit"
+msgstr "%1$s edited response %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:245
+#, fuzzy
+msgid "audit_review_approve"
+msgstr "%1$s approved review %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:250
+#: controllers/components/audit.php:253
+#, fuzzy
+msgid "audit_review_delete"
+msgstr "%1$s deleted review %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:303
+#, fuzzy
+msgid "audit_security_default"
+msgstr "%1$s committed unknown security action %2$s to ID %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a category name, like <a>Search Tools</a>
+#: controllers/components/audit.php:118
+#, fuzzy
+msgid "audit_tag_create"
+msgstr "%1$s created tag %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a category name, like <a>Search Tools</a>
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:126
+#, fuzzy
+msgid "audit_tag_delete"
+msgstr "%1$s deleted category %2$s (ID %3$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a category name, like <a>Search Tools</a>
+#: controllers/components/audit.php:121
+#, fuzzy
+msgid "audit_tag_edit"
+msgstr "%1$s edited category %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:266
+#, fuzzy
+msgid "audit_update_applications"
+msgstr "%1$s updated application translations for %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:277
+#, fuzzy
+msgid "audit_update_blog"
+msgstr "%1$s updated blog post translations for %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:274
+#, fuzzy
+msgid "audit_update_platforms"
+msgstr "%1$s updated platform translations for %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:270
+#, fuzzy
+msgid "audit_update_tags"
+msgstr "%1$s updated category translations for %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>user name</a>
+#: controllers/components/audit.php:217
+#, fuzzy
+msgid "audit_user_edit"
+msgstr "%1$s edited %2$s's user information"
+
+#: controllers/addons_controller.php:1012
+msgid "browse_addons_name"
+msgstr "اÙزودنی‌ها بر حسب نام"
+
+#: controllers/addons_controller.php:1010
+msgid "browse_addons_newest"
+msgstr "جدیدترین اÙزودنی‌ها"
+
+#: controllers/addons_controller.php:1008
+msgid "browse_addons_popular"
+msgstr "اÙزودنی‌های محبوب"
+
+#: controllers/addons_controller.php:1011
+msgid "browse_addons_rated"
+msgstr "اÙزودنی‌ها بر حسب رتبه"
+
+#: controllers/addons_controller.php:1009
+msgid "browse_addons_updated"
+msgstr "اÙزودنی‌های به تازگی به‌هنگام شده"
+
+#: views/elements/categories.thtml:73
+#: views/elements/categories.thtml:82
+msgid "categories_current_title"
+msgstr "دستهٔ Ùعلی"
+
+#: views/elements/categories.thtml:50
+#: views/elements/amo2009/categories.thtml:43
+#: views/elements/amo2009/categories.thtml:45
+msgid "categories_header"
+msgstr "دسته‌ها"
+
+#: views/elements/categories.thtml:50
+#: views/elements/amo2009/categories.thtml:41
+msgid "categories_header_title"
+msgstr "انتخاب یک دسته"
+
+#. %1$s is the category name
+#: views/addons/searchengines.thtml:129
+#, php-format
+msgid "category_extra_see_all"
+msgstr "مشاهدهٔ همهٔ اÙزودنی‌های دستهٔ %1$s"
+
+#. %1$s is a number.
+#: models/collection.php:130
+msgid "collection_description_limit"
+msgstr "شرح باید کمتر از %1$s نویسه باشد."
+
+#. %1$s is the name of the collection
+#: controllers/collections_controller.php:392
+msgid "collection_detail_rss_title"
+msgstr "مجموعهٔ %s"
+
+#: controllers/collections_controller.php:1065
+msgid "collection_error_deleting_addon"
+msgstr "خطا در حین حذ٠اÙزودنی!"
+
+#: controllers/collections_controller.php:1051
+msgid "collection_error_saving_addon"
+msgstr "خطا در حین ذخیرهٔ اÙزودنی!"
+
+#: controllers/collections_controller.php:1080
+msgid "collection_error_saving_comment"
+msgstr "خطا در حین ذخیرهٔ نظر!"
+
+#. %1$s is a number.
+#: models/collection.php:122
+msgid "collection_name_limit"
+msgstr "نام باید کمتر از %1$s نویسه باشد."
+
+#: controllers/collections_controller.php:352
+#: controllers/collections_controller.php:487
+msgid "collection_not_found"
+msgstr "مجموعه‌ای پیدا نشد!"
+
+#. %1$s is the text on the "create collection" button
+#: views/collections/add.thtml:91
+msgid "collections_add_formfield_addons_description"
+msgstr "اگر از قبل می‌دانید کدام اÙزودنی‌ها را می‌خواهید به مجموعهٔ خود اضاÙÙ‡ نمایید، تنها کاÙÛŒ است نام آنها را در Ùضای زیر وارد کنید. اگر می‌خواهید Ùعلاً دست Ù†Ú¯Ù‡ دارید Ùˆ بعداً این کار را انجام دهید، کاÙÛŒ است هم اکنون روی %1$s کلیک کنید."
+
+#: views/collections/add.thtml:90
+msgid "collections_add_formfield_firstaddons"
+msgstr "اولین اÙزودنی‌های خود را انتخاب نمایید"
+
+#: views/collections/add.thtml:48
+msgid "collections_add_header"
+msgstr "ایجاد یک مجموعه"
+
+#: views/collections/add.thtml:97
+msgid "collections_add_header_selectedaddons"
+msgstr "اÙزودنی‌های انتخاب شده"
+
+#: views/collections/add.thtml:50
+msgid "collections_add_intro"
+msgstr "ایجاد مجموعهٔ خودتان با پر کردن تعداد Ú©Ù…ÛŒ Ùیلد در زیر کار ساده‌ای است."
+
+#: views/collections/add.thtml:92
+#: views/collections/add.thtml:103
+msgid "collections_add_submit"
+msgstr "ایجاد مجموعه"
+
+#: views/pages/collector_faq.thtml:50
+#: views/pages/collector_firstrun.thtml:43
+#: views/pages/collector.thtml:47
+#: views/pages/collector_features.thtml:55
+#: controllers/search_controller.php:302
+#: controllers/collections_controller.php:206
+#: controllers/collections_controller.php:405
+#: controllers/collections_controller.php:467
+#: controllers/collections_controller.php:539
+msgid "collections_breadcrumb"
+msgstr "مجموعه‌ها"
+
+#: views/collections/detail.thtml:185
+msgid "collections_detail_a_learn"
+msgstr "بیشتر بدانید"
+
+#: views/elements/amo2009/collection_add_form.thtml:53
+#: views/elements/amo2009/collections_js_init.thtml:68
+#: views/pages/collector_firstrun.thtml:64
+msgid "collections_detail_button_add"
+msgstr "اÙزودن به اÙزودنی‌های محبوب"
+
+#: views/elements/amo2009/collection_add_form.thtml:50
+#: views/elements/amo2009/collections_js_init.thtml:71
+msgid "collections_detail_button_remove"
+msgstr "حذ٠از اÙزودنی‌های محبوب"
+
+#. %1$s is a URL.
+#. %2$s is a full <a href>.
+#: views/collections/detail.thtml:62
+#, fuzzy
+msgid "collections_detail_created_desc"
+msgstr "<p>You can view your new collection below. If you'd like to set a collection nickname, upload an icon, or change additional settings, please visit the <a href='%1$s'>Manage Collections</a> page.</p><p>Your collection can be accessed at this location: %2$s</p>"
+
+#: views/collections/detail.thtml:61
+#, fuzzy
+msgid "collections_detail_created_msg"
+msgstr "Your collection is now ready!"
+
+#: views/collections/detail.thtml:109
+msgid "collections_detail_header_about"
+msgstr "دربارهٔ این مجموعه"
+
+#. %1$s is a number.
+#: views/collections/detail.thtml:126
+msgid "collections_detail_header_count"
+msgid_plural "collections_detail_header_count"
+msgstr[0] "%1$s اÙزودنی در این مجموعه"
+msgstr[1] "%1$s اÙزودنی در این مجموعه"
+
+#: views/collections/detail.thtml:113
+msgid "collections_detail_info_created"
+msgstr "<strong>ایجاد شده توسط:</strong> %1$s"
+
+#: views/collections/detail.thtml:117
+msgid "collections_detail_info_updated"
+msgstr "<strong>به‌هنگام شده در:</strong>"
+
+#: views/elements/amo2009/collections_js_init.thtml:62
+#, fuzzy
+msgid "collections_detail_js_adding"
+msgstr "Adding to Favorites&hellip;"
+
+#: views/elements/amo2009/collections_js_init.thtml:65
+#, fuzzy
+msgid "collections_detail_js_removing"
+msgstr "Removing Favorite&hellip;"
+
+#. %1$s is a URL
+#: views/collections/detail.thtml:90
+#, fuzzy
+msgid "collections_detail_login"
+msgstr "<a href=\"%1$s\">Log in</a> to add this collection to your favorites."
+
+#: views/collections/detail.thtml:104
+#, fuzzy
+msgid "collections_detail_manage"
+msgstr "Manage Collection"
+
+#: controllers/collections_controller.php:298
+msgid "collections_detail_sort_date"
+msgstr "تاریخ اÙزوده شدن"
+
+#: controllers/collections_controller.php:299
+msgid "collections_detail_sort_name"
+msgstr "نام"
+
+#: controllers/collections_controller.php:300
+msgid "collections_detail_sort_popularity"
+msgstr "محبوبیت"
+
+#. %1$s is a number.
+#: views/collections/detail.thtml:166
+msgid "collections_detail_weekly_downloads"
+msgid_plural "collections_detail_weekly_downloads"
+msgstr[0] "%1$s بارگیری در Ù‡Ùتهٔ جاری"
+msgstr[1] "%1$s بارگیری در Ù‡Ùتهٔ جاری"
+
+#: views/collections/edit.thtml:255
+msgid "collections_edit_addons_delete_noscript"
+msgstr "اÙزودنی‌های انتخاب شده هنگام ذخیره‌سازی حذ٠خواهند گردید"
+
+#: views/collections/edit.thtml:247
+#, fuzzy
+msgid "collections_edit_addons_description"
+msgstr "To publish new add-ons to this collection, start typing their names below."
+
+#: views/collections/edit.thtml:248
+#, fuzzy
+msgid "collections_edit_addons_description_noscript"
+msgstr "To publish new add-ons to this collection, enter a comma-separated list of Add-on IDs below."
+
+#: views/collections/edit.thtml:247
+#: views/collections/edit.thtml:248
+#, fuzzy
+msgid "collections_edit_addons_description_publish_detailspage"
+msgstr "You can also publish an add-on from its normal listing page."
+
+#. %1$s is the date the add-on was added to the collection
+#. %1$s is the name of the user who added the add-on to the collection
+#: views/collections/edit.thtml:260
+msgid "collections_edit_addons_listitem_added"
+msgstr "اÙزوده شده در %1$s توسط %2$s"
+
+#: views/collections/edit.thtml:263
+msgid "collections_edit_addons_listitem_comment_add"
+msgstr "اÙزودن نظر منتشر کننده"
+
+#: views/collections/edit.thtml:266
+msgid "collections_edit_addons_listitem_comment_delete"
+msgstr "حذ٠نظر منتشر کننده"
+
+#: views/collections/edit.thtml:265
+msgid "collections_edit_addons_listitem_comment_edit"
+msgstr "ویرایش نظر منتشر کننده"
+
+#: views/collections/edit.thtml:271
+#, fuzzy
+msgid "collections_edit_addons_listitem_comment_note"
+msgstr "Note: Comment will appear as though written by original publisher on the original publication date"
+
+#: views/collections/edit.thtml:270
+msgid "collections_edit_addons_listitem_comment_submit"
+msgstr "ذخیرهٔ نظر"
+
+#: views/collections/edit.thtml:261
+msgid "collections_edit_addons_listitem_remove"
+msgstr "حذÙ"
+
+#: views/collections/edit.thtml:250
+msgid "collections_edit_addons_submit"
+msgstr "اÙزودن به مجموعه"
+
+#: views/collections/edit.thtml:153
+msgid "collections_edit_check_nickname"
+msgstr "بررسی در دسترس بودن"
+
+#: views/collections/edit.thtml:299
+#, fuzzy
+msgid "collections_edit_confirm_deletecollection"
+msgstr "Yes, I would like to delete this collection."
+
+#. %1$s is the label of the edit form's submit button
+#: views/collections/edit.thtml:300
+#, fuzzy
+msgid "collections_edit_confirm_deletecollection_description"
+msgstr "Check the box, then click on \"%1$s\" to delete this collection."
+
+#. %1$s is the "delete" submit button text
+#. %2$s is the title of the "advanced" tab
+#: views/collections/edit.thtml:95
+#, fuzzy
+msgid "collections_edit_delete_upon_submit"
+msgstr "Upon clicking \"%1$s\" below, your collection will be deleted. If you do not want to delete your collection, uncheck the confirmation box in the \"%2$s\" tab and continue editing your collection. If you leave this page without saving, your collection will also not be deleted."
+
+#: views/collections/edit.thtml:94
+#, fuzzy
+msgid "collections_edit_delete_warning"
+msgstr "Your collection is about to be deleted!"
+
+#: views/collections/add.thtml:76
+#: views/collections/edit.thtml:144
+#, fuzzy
+msgid "collections_edit_form_error_description"
+msgstr "You must provide a description of your collection."
+
+#: views/collections/edit.thtml:181
+#, fuzzy
+msgid "collections_edit_form_error_icon"
+msgstr "There was an error uploading your icon."
+
+#: views/collections/add.thtml:69
+#: views/collections/edit.thtml:130
+#, fuzzy
+msgid "collections_edit_form_error_name"
+msgstr "You must give your collection a name."
+
+#: views/collections/edit.thtml:158
+#, fuzzy
+msgid "collections_edit_form_error_nickname"
+msgstr "If you choose a nickname, it must be unique."
+
+#: views/collections/add.thtml:93
+#: views/collections/edit.thtml:249
+msgid "collections_edit_formfield_addons"
+msgstr "نام اÙزودنی:"
+
+#: views/collections/edit.thtml:281
+msgid "collections_edit_formfield_application"
+msgstr "برنامهٔ مربوطه"
+
+#: views/collections/edit.thtml:282
+msgid "collections_edit_formfield_application_description"
+msgstr "برنامه‌هایی که مجموعه‌تان از آنها پشتیبانی می‌کند را انتخاب کنید."
+
+#: views/collections/edit.thtml:288
+#, fuzzy
+msgid "collections_edit_formfield_collectiontype"
+msgstr "Collection Type"
+
+#: views/collections/edit.thtml:295
+msgid "collections_edit_formfield_deletecollection"
+msgstr "حذ٠مجموعه"
+
+#: views/collections/edit.thtml:296
+msgid "collections_edit_formfield_deletecollection_description"
+msgstr "حذ٠مجموعه آن را برای همیشه پاک می‌کند."
+
+#: views/collections/add.thtml:73
+#: views/collections/edit.thtml:140
+msgid "collections_edit_formfield_description"
+msgstr "شرح مجموعه"
+
+#: views/collections/add.thtml:74
+#: views/collections/edit.thtml:141
+msgid "collections_edit_formfield_description_description"
+msgstr "مجموعهٔ خود Ùˆ اÙزودنی‌های موجود در آن را به صورت خلاصه توضیح دهید"
+
+#: views/collections/edit.thtml:162
+msgid "collections_edit_formfield_icon"
+msgstr "شمایل"
+
+#: views/collections/edit.thtml:163
+msgid "collections_edit_formfield_icon_description"
+msgstr "می‌توانید یک شمایل JPGâ€ØŒ GIF یا PNG ارسال کنید Ú©Ù‡ اندازهٔ آن تبدیل به ۳۲×۳۲ نقطه خواهد گردید."
+
+#: views/collections/add.thtml:80
+#: views/collections/edit.thtml:189
+msgid "collections_edit_formfield_listed"
+msgstr "چه کسی می‌تواند مجموعهٔ شما را مشاهده کند؟"
+
+#: views/collections/add.thtml:81
+#: views/collections/edit.thtml:190
+msgid "collections_edit_formfield_listed_description"
+msgstr "به صورت پیش‌Ùرض، مجموعه‌ها در Ùهرست عمومی مجموعه‌ها ثبت می‌شوند Ùˆ توسط همه قابل مشاهده هستند. اگر می‌خواهید مجموعه‌تان تنها توسط اÙرادی Ú©Ù‡ پیوندی به آن دریاÙت می‌کنند قابل مشاهده باشد، گزینهٔ زیر را انتخاب نمایید."
+
+#: views/collections/add.thtml:84
+#: views/collections/edit.thtml:193
+msgid "collections_edit_formfield_listed_false"
+msgstr "تنها اشخاصی که از آنها دعوت می‌شود قادر به مشاهدهٔ این مجموعه باشند"
+
+#: views/collections/add.thtml:83
+#: views/collections/edit.thtml:192
+msgid "collections_edit_formfield_listed_true"
+msgstr "همه بتوانند مجموعهٔ من را در Ùهرست مجموعه‌ها مشاهده کنند"
+
+#: views/collections/edit.thtml:223
+msgid "collections_edit_formfield_managers"
+msgstr "چه کسی می‌تواند مجموعهٔ شما را مدیریت کند؟"
+
+#: views/collections/edit.thtml:224
+msgid "collections_edit_formfield_managers_description"
+msgstr "این کاربران می‌توانند اÙزودنی‌های جدید به مجموعه‌تان بیاÙزایند، همهٔ اÙزودنی‌ها Ùˆ تنظیمات را مدیریت کنند، Ùˆ به کاربران دیگر نیز اجازهٔ این کار را بدهند."
+
+#: views/collections/add.thtml:66
+#: views/collections/edit.thtml:126
+msgid "collections_edit_formfield_name"
+msgstr "نام مجموعه"
+
+#: views/collections/add.thtml:67
+#: views/collections/edit.thtml:127
+msgid "collections_edit_formfield_name_description"
+msgstr "به مجموعهٔ خود یک نام واضح بدهید، مثلاً «اÙزودنی‌های محبوب داوود دربارهٔ مساÙرت»"
+
+#: views/collections/edit.thtml:148
+msgid "collections_edit_formfield_nickname"
+msgstr "نام مستعار مجموعه"
+
+#: views/collections/edit.thtml:149
+msgid "collections_edit_formfield_nickname_description"
+msgstr "همچنین می‌توانید برای دسترسی سریع‌تر به اÙزودنی خود یک نام مستعار نیز تخصیص دهید:"
+
+#: views/collections/edit.thtml:201
+msgid "collections_edit_formfield_publishers"
+msgstr "Ú†Ù‡ کسی می‌تواند اÙزودنی‌های جدید در مجموعه‌تان منتشر کند؟"
+
+#: views/collections/edit.thtml:202
+msgid "collections_edit_formfield_publishers_description"
+msgstr "این کاربران می‌توانند اÙزودنی‌های جدید به مجموعه‌تان اضاÙÙ‡ کنند یا اÙزودنی‌هایی را Ú©Ù‡ قبلاً اضاÙÙ‡ کرده‌اند حذ٠کنند."
+
+#: views/collections/edit.thtml:210
+#: views/collections/edit.thtml:232
+msgid "collections_edit_formfield_users_add"
+msgstr "نشانی پست الکترونیک یک حساب کاربری اÙزودنی‌های ÙایرÙاکس را وارد کنید:"
+
+#: views/collections/edit.thtml:216
+#: views/collections/edit.thtml:238
+msgid "collections_edit_formfield_users_delete_noscript"
+msgstr "حساب‌های کاربری انتخاب شده در هنگام ذخیره‌سازی حذ٠خواهند گردید"
+
+#: views/collections/edit.thtml:215
+#: views/collections/edit.thtml:237
+msgid "collections_edit_formfield_users_new_noscript"
+msgstr "Ùهرستی از نشانی‌های پست الکترونیک اÙزودنی‌های ÙایرÙاکس را Ú©Ù‡ با ویرگول از یکدیگر جدا شده‌اند در اینجا وارد کنید"
+
+#: views/collections/edit.thtml:204
+#: views/collections/edit.thtml:226
+msgid "collections_edit_formfield_users_onlyme"
+msgstr "تنها خود من"
+
+#: views/collections/edit.thtml:205
+#: views/collections/edit.thtml:227
+msgid "collections_edit_formfield_users_otherusers"
+msgstr "من و این کاربران:"
+
+#: views/collections/edit.thtml:211
+#: views/collections/edit.thtml:233
+msgid "collections_edit_formfield_users_submit"
+msgstr "اÙزودن"
+
+#. %1$s is the name of the collection
+#: views/collections/edit.thtml:68
+msgid "collections_edit_header"
+msgstr "مدیریت %1$s"
+
+#: views/collections/edit.thtml:246
+msgid "collections_edit_header_addons"
+msgstr "مدیریت محتوای مجموعه"
+
+#: views/collections/edit.thtml:253
+#: views/collections/edit.thtml:258
+msgid "collections_edit_header_addons_current"
+msgstr "اÙزودنی‌های Ùعلی:"
+
+#: views/collections/edit.thtml:279
+msgid "collections_edit_header_advanced"
+msgstr "تنظیمات پیشرÙته"
+
+#: views/collections/edit.thtml:186
+msgid "collections_edit_header_permissions"
+msgstr "مدیریت مجوزهای مجموعه"
+
+#: views/collections/edit.thtml:170
+msgid "collections_edit_icon_cancel"
+msgstr "انصراÙ"
+
+#: views/collections/edit.thtml:174
+#: views/collections/edit.thtml:179
+msgid "collections_edit_icon_delete"
+msgstr "حذ٠شمایل"
+
+#: views/collections/edit.thtml:178
+msgid "collections_edit_icon_replace"
+msgstr "جایگزینی شمایل"
+
+#. %1$s is the label of the edit form's submit button
+#: views/collections/edit.thtml:169
+#, fuzzy
+msgid "collections_edit_icon_toberemoved"
+msgstr "Icon will be removed when \"%1$s\" is clicked below"
+
+#: views/collections/edit.thtml:155
+#, fuzzy
+msgid "collections_edit_nickname_available"
+msgstr "Nickname Available"
+
+#: controllers/collections_controller.php:943
+#, fuzzy
+msgid "collections_edit_nickname_error"
+msgstr "Your nickname contained invalid characters and was corrected. Please try again."
+
+#: views/collections/edit.thtml:156
+#, fuzzy
+msgid "collections_edit_nickname_taken"
+msgstr "Nickname Taken"
+
+#. This string is followed by a URL pointing to the collection's view page
+#: views/collections/edit.thtml:75
+#, fuzzy
+msgid "collections_edit_saved_nextstep"
+msgstr "Your collection can be accessed at this location:"
+
+#: views/collections/edit.thtml:74
+#, fuzzy
+msgid "collections_edit_saved_success"
+msgstr "Your collection was successfully saved!"
+
+#: views/collections/edit.thtml:169
+#: views/collections/edit.thtml:300
+#: views/collections/edit.thtml:308
+#: views/pages/js_constants.js.thtml:99
+#, fuzzy
+msgid "collections_edit_submit"
+msgstr "Update Collection"
+
+#: views/collections/edit.thtml:96
+#: views/collections/edit.thtml:297
+#: views/pages/js_constants.js.thtml:100
+#, fuzzy
+msgid "collections_edit_submit_deletecollection"
+msgstr "Delete Collection"
+
+#: views/collections/edit.thtml:111
+msgid "collections_edit_tabheader_addons"
+msgstr "اÙزودنی‌ها"
+
+#: views/collections/edit.thtml:97
+#: views/collections/edit.thtml:113
+msgid "collections_edit_tabheader_advanced"
+msgstr "پیشرÙته"
+
+#: views/collections/edit.thtml:108
+msgid "collections_edit_tabheader_details"
+msgstr "نام و جزئیات"
+
+#: views/collections/edit.thtml:109
+msgid "collections_edit_tabheader_permissions"
+msgstr "مجوزها"
+
+#: models/collection_promo.php:53
+msgid "collections_family_tagline"
+msgstr "مراقب Ùرزندان Ùˆ برنامهٔ خود باشید"
+
+#: models/collection_promo.php:53
+msgid "collections_family_title"
+msgstr "خانواده"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:70
+#, fuzzy
+msgid "collections_index_a_check_out"
+msgstr "Check out Add-on Collector"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:52
+#, fuzzy
+msgid "collections_index_a_create"
+msgstr "Create a Collection"
+
+#: views/collections/detail.thtml:139
+#: views/collections/listing.thtml:85
+#: views/search/collections.thtml:84
+msgid "collections_index_button_go"
+msgstr "برو"
+
+#. %1$s is a URL.
+#: controllers/collections_controller.php:182
+#, fuzzy
+msgid "collections_index_filler_favorites"
+msgstr "<p><strong>You don't have any favorite collections yet.</strong></p> <p>Collections you mark as favorites can be quickly accessed from this page, and will appear in the <a href='%1$s'>Add-on Collector</a> if you've installed it.</p>"
+
+#. %1$s is a URL.
+#: controllers/collections_controller.php:167
+#, fuzzy
+msgid "collections_index_filler_mine"
+msgstr "<p>You haven't created any collections yet. Collections are easy to create and fill with your favorite add-ons. <a href='%1$s'>Try it out</a>!</p>"
+
+#: views/collections/listing.thtml:51
+msgid "collections_index_header_collections"
+msgstr "مجموعه‌ها"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:60
+msgid "collections_index_header_collector"
+msgstr "مجموعه‌ساز اÙزودنی‌ها"
+
+#. %1$s is a comma-separated list of author names
+#: views/elements/amo2009/collection_listing_item.thtml:84
+#: views/collections/detail.thtml:151
+msgid "collections_index_header_created"
+msgstr "ایجاد شده توسط %1$s"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:47
+msgid "collections_index_header_what"
+msgstr "مجموعه‌ها چیستند؟"
+
+#: views/collections/detail.thtml:132
+#: views/collections/listing.thtml:78
+#: views/search/collections.thtml:66
+msgid "collections_index_label_sortby"
+msgstr "مرتب‌سازی بر حسب"
+
+#: controllers/collections_controller.php:130
+msgid "collections_index_li_editors"
+msgstr "منتخب ویرایش‌گران"
+
+#: views/collections/subscribe.thtml:64
+#: controllers/collections_controller.php:140
+msgid "collections_index_li_favorites"
+msgstr "اÙزودنی‌های محبوب من"
+
+#: controllers/collections_controller.php:138
+msgid "collections_index_li_mine"
+msgstr "اÙزودنی‌های من"
+
+#: controllers/collections_controller.php:132
+msgid "collections_index_li_popular"
+msgstr "اÙزودنی‌های محبوب"
+
+#: views/search/collections.thtml:74
+#: controllers/collections_controller.php:81
+msgid "collections_index_option_all"
+msgstr "محبوب‌ترین اÙزودنی‌ها در هر زمانی"
+
+#: views/search/collections.thtml:72
+#: controllers/collections_controller.php:78
+msgid "collections_index_option_month"
+msgstr "محبوب‌ترین اÙزودنی‌ها در ماه جاری"
+
+#: views/search/collections.thtml:76
+#: controllers/collections_controller.php:84
+msgid "collections_index_option_newest"
+msgstr "جدیدترین‌ها"
+
+#: views/search/collections.thtml:70
+#: controllers/collections_controller.php:75
+msgid "collections_index_option_week"
+msgstr "محبوب‌ترین اÙزودنی‌ها در این Ù‡Ùته"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:67
+#, fuzzy
+msgid "collections_index_p_collector"
+msgstr "There's a new way to manage and find favorite add-ons. Comment, share and sync collections, all from your browser"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:48
+#, fuzzy
+msgid "collections_index_p_what_are"
+msgstr "Collections are groups of related add-ons assembled for easy sharing."
+
+#. %s is a date in the _('date') format
+#: views/elements/collections_interactive_addon.thtml:85
+#, php-format
+msgid "collections_interactive_addon_added"
+msgstr "اضاÙÙ‡ گردید"
+
+#: models/collection_promo.php:55
+msgid "collections_reference_tagline"
+msgstr "در وب دربارهٔ همه‌چیز تحقیق کنید"
+
+#: models/collection_promo.php:55
+msgid "collections_reference_title"
+msgstr "مراجع"
+
+#: models/collection_promo.php:52
+msgid "collections_social_tagline"
+msgstr "مدیریت شبکه‌های اجتماعی"
+
+#: models/collection_promo.php:52
+msgid "collections_social_title"
+msgstr "اجتماعی"
+
+#: views/collections/subscribe.thtml:91
+msgid "collections_subscribe_button_close"
+msgstr "بستن"
+
+#: views/collections/subscribe.thtml:70
+#, fuzzy
+msgid "collections_subscribe_error"
+msgstr "An error occurred trying to add a favorite collection. Is this collection already a favorite?"
+
+#: views/collections/subscribe.thtml:96
+#, fuzzy
+msgid "collections_subscribe_label_bothersome"
+msgstr "Don't show me this message again."
+
+#. %1$s is the collection name
+#: views/collections/subscribe.thtml:60
+#, fuzzy
+msgid "collections_subscribe_success"
+msgstr "%1$s has been added to your favorite collections."
+
+#. %1$s is the link to the "My Favorites" tab on the main collections page
+#. %2$s is the localized title of the "My Favorites" tab
+#. %3$s is the link URL to the collector add-on
+#: views/collections/subscribe.thtml:62
+#, fuzzy
+msgid "collections_subscribe_success_desc"
+msgstr "You can now quickly find this collection from the <a href=\"%1$s\">%2$s</a> tab in the directory. For an even easier way to keep track of your favorite collections, try out our <a href=\"%3$s\">Add-on Collector</a> extension for Firefox."
+
+#: views/collections/listing.thtml:55
+msgid "collections_success_delete"
+msgstr "مجموعه با موÙقیت حذ٠گردید."
+
+#: models/collection_promo.php:54
+msgid "collections_travel_tagline"
+msgstr "برنامه‌ریزی برای سÙرهای کاری Ùˆ تعطیلات به یاد ماندنی"
+
+#: models/collection_promo.php:54
+msgid "collections_travel_title"
+msgstr "مساÙرت"
+
+#. A collection of add-ons that is automatically built for a user. They are "automatically published" to this collection.
+#: controllers/collections_controller.php:581
+msgid "collections_type_autopublisher"
+msgstr "خود منتشر شونده"
+
+#. A collection that has been chosen by an Editor as notable or exceptional
+#: controllers/collections_controller.php:582
+msgid "collections_type_editorspick"
+msgstr "منتخب ویرایش‌گران"
+
+#: controllers/collections_controller.php:580
+msgid "collections_type_normal"
+msgstr "معمولی"
+
+#: views/collections/subscribe.thtml:84
+#, fuzzy
+msgid "collections_unsubscribe_error"
+msgstr "An error occurred trying to remove a favorite collection. Was this collection not a favorite?"
+
+#. %1$s is the collection name
+#: views/collections/subscribe.thtml:78
+#, fuzzy
+msgid "collections_unsubscribe_success"
+msgstr "%1$s has been removed from your favorite collections."
+
+#: models/collection_promo.php:56
+msgid "collections_webdev_tagline"
+msgstr "بهترین وب‌گاه را بسازید"
+
+#: models/collection_promo.php:56
+msgid "collections_webdev_title"
+msgstr "توسعهٔ وب"
+
+#: views/elements/amo2009/collections_sidebar_whatare.thtml:40
+msgid "collections_whatare_header"
+msgstr "مجموعه‌ها چیستند؟"
+
+#: views/elements/amo2009/collections_sidebar_whatare.thtml:45
+msgid "collections_whatare_learnmore"
+msgstr "مطالعهٔ پرسش‌های متداول"
+
+#: views/elements/amo2009/collections_sidebar_whatare.thtml:44
+msgid "collections_whatare_text"
+msgstr "روشی جدید برای مدیریت Ùˆ یاÙتن اÙزودنی‌های محبوب وجود دارد. مجموعه‌هایی از اÙزودنی‌ها را می‌توانید از درون خود مرورگر به اشتراک گذاشته، روی آن‌ها نظر دهید Ùˆ آنها را با یکدیگر همسان سازید."
+
+#: views/pages/collector_faq.thtml:61
+#: views/pages/collector_features.thtml:67
+msgid "collector_features_a_home"
+msgstr "صÙحهٔ آغازهٔ مجموعه‌ساز اÙزودنی‌ها"
+
+#: views/elements/amo2009/collector_sidebar_download.thtml:46
+msgid "collector_features_heading_download"
+msgstr "بارگیری مجموعه‌ساز اÙزودنی‌ها:"
+
+#: views/elements/amo2009/collector_sidebar_download.thtml:43
+#: views/pages/collector_firstrun.thtml:116
+#: views/pages/collector.thtml:69
+msgid "collector_features_img_logo"
+msgstr "نشان مجموعه‌ساز اÙزودنی‌ها"
+
+#: views/compatibility/dashboard.thtml:49
+#: controllers/compatibility_controller.php:72
+msgid "compatibility_dashboard_center_header"
+msgstr "مرکز سازگاری اÙزودنی‌ها"
+
+#. %1$s is the name of an application and a version. Example: Firefox 3.0
+#. %2$s is the name of an application. Example: Firefox
+#: views/compatibility/dashboard.thtml:50
+msgid "compatibility_dashboard_intro"
+msgstr "با استÙاده از ابزارها Ùˆ اطلاعات مخصوص توسعه‌دهندگان اÙزودنی‌های %2$s Ú©Ù‡ در این بخش وجود دارد برای انتشار %1$s آماده شوید."
+
+#: views/compatibility/dashboard.thtml:103
+msgid "compatibility_dashboard_loading"
+msgstr "در حال بار کردن اطلاعات..."
+
+#: views/compatibility/dashboard.thtml:45
+msgid "compatibility_dashboard_main_link"
+msgstr "بازگشت به صÙحهٔ اصلی"
+
+#: views/compatibility/dashboard.thtml:100
+#: views/compatibility/report.thtml:43
+msgid "compatibility_dashboard_report"
+msgstr "گزارش سازگاری اÙزودنی‌ها"
+
+#: views/compatibility/dashboard.thtml:53
+#: views/compatibility/dashboard.thtml:110
+#: views/compatibility/developers.thtml:43
+msgid "compatibility_developer_info"
+msgstr "اطلاعات مخصوص توسعه‌دهندگان اÙزودنی‌ها"
+
+#: views/compatibility/developers.thtml:66
+msgid "compatibility_developers_adjust_maxversion"
+msgstr "تنظیم maxVersion بدون ارسال مجدد اÙزودنی"
+
+#: views/compatibility/dashboard.thtml:124
+msgid "compatibility_developers_check_status"
+msgstr "کنترل وضعیت اÙزودنی‌های من"
+
+#. %1$s is a URL
+#. %2$s is an application and version. Example: Firefox 3.0
+#: views/compatibility/dashboard.thtml:126
+msgid "compatibility_developers_login_first"
+msgstr "اگر اÙزودنی‌های خود را در وب‌گاه اÙزودنی‌های موزیلا میزبانی می‌کنید، لطÙاً برای تحلیل وضعیت اÙزودنی‌های %2$s خود <a href=\"%1$s\">وارد شوید</a>."
+
+#: views/compatibility/dashboard.thtml:114
+msgid "compatibility_developers_mdclogo_alt"
+msgstr "لوگوی مرکز توسعه‌دهندگان موزیلا"
+
+#: views/compatibility/developers.thtml:73
+msgid "compatibility_developers_no_addons"
+msgstr "شما هیچ اÙزودنی میزبانی شده در وب‌گاه اÙزودنی‌های موزیلا ندارید."
+
+#: views/compatibility/dashboard.thtml:133
+#: views/compatibility/developers.thtml:55
+msgid "compatibility_developers_results"
+msgstr "نتایج بررسی وضعیت اÙزودنی‌ها"
+
+#: views/compatibility/dashboard.thtml:137
+msgid "compatibility_developers_retrieving"
+msgstr "بازیابی وضعیت اÙزودنی‌های میزبانی شده..."
+
+#. %1$s is a number
+#. %2$s is an application name
+#. %3$s is a number.
+#. Full example: 50 Firefox users (10% of total)
+#: views/compatibility/developers.thtml:65
+msgid "compatibility_developers_user_count"
+msgstr "%1$s کاربر %2$s (%3$s٪ از کل)"
+
+#: views/compatibility/report.thtml:45
+msgid "compatibility_report_detail_intro"
+msgstr "بر اساس اطلاعاتی Ú©Ù‡ موزیلا در اختیار دارد، اÙزودنی‌های زیر Û¹ÛµÙª اÙزودنی‌های استÙاده شده توسط کاربران را تشکیل می‌دهند Ùˆ بر اساس مقدار استÙاده مرتب شده‌اند."
+
+#: views/compatibility/dashboard.thtml:94
+msgid "compatibility_report_detailed_link"
+msgstr "مشاهدهٔ گزارش جزئی"
+
+#. %1$s and %2$s are numbers
+#. %3$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:65
+msgid "compatibility_report_intro"
+msgstr "بر اساس اطلاعاتی Ú©Ù‡ موزیلا در اختیار دارد، از مجموع %1$s اÙزودنی Ú©Ù‡ Û¹ÛµÙª اÙزودنی‌های استÙاده شده را تشکیل می‌دهند، <b>%2$sÙª</b> در حال حاضر با آخرین نسخهٔ %3$s سازگار هستند."
+
+#: views/compatibility/dashboard.thtml:81
+msgid "compatibility_report_legend_alpha"
+msgstr "نسخه‌های آلÙا"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:81
+msgid "compatibility_report_legend_alpha_description"
+msgstr "اÙزودنی‌های سازگار با نسخهٔ آلÙایی از %1$s"
+
+#: views/compatibility/dashboard.thtml:85
+msgid "compatibility_report_legend_beta"
+msgstr "نسخه‌های بتا"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:85
+msgid "compatibility_report_legend_beta_description"
+msgstr "اÙزودنی‌های سازگار با نسخهٔ بتا یا نامزد انتشاری از %1$s"
+
+#: views/compatibility/dashboard.thtml:89
+msgid "compatibility_report_legend_latest"
+msgstr "جدیدترین نسخه"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:89
+msgid "compatibility_report_legend_latest_description"
+msgstr "اÙزودنی‌های سازگار با جدیدترین نسخه‌های %1$s"
+
+#: views/compatibility/dashboard.thtml:77
+msgid "compatibility_report_legend_other"
+msgstr "نسخه‌های دیگر"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:77
+msgid "compatibility_report_legend_other_description"
+msgstr "اÙزودنی‌های ناسازگار با هر نسخهٔ %1$s"
+
+#: views/compatibility/dashboard.thtml:62
+msgid "compatibility_report_title"
+msgstr "گزارش سازگاری اÙزودنی‌ها"
+
+#: views/compatibility/dashboard.thtml:54
+#: views/compatibility/dashboard.thtml:144
+#: views/compatibility/users.thtml:42
+msgid "compatibility_user_info"
+msgstr "اطلاعات مخصوص استÙاده‌کنندگان اÙزودنی‌ها"
+
+#: views/compatibility/dashboard.thtml:52
+msgid "compatibility_view_report"
+msgstr "مشاهدهٔ گزارش سازگاری"
+
+#. %s is a URL
+#: views/pages/credits.thtml:142
+#, php-format
+msgid "credits_contributing"
+msgstr "برای اطلاعات دربارهٔ مشارکت، لطÙاً از %s ما بازدید کنید."
+
+#: views/pages/credits.thtml:142
+msgid "credits_contributing_wikipage"
+msgstr "صÙحهٔ ویکی"
+
+#: views/pages/credits.thtml:99
+msgid "credits_intro"
+msgstr "موزیلا مایل به تشکر از اÙراد زیر برای مشارکت در پروژهٔ اÙزودنی‌های موزیلا در طول سالیان گذشته می‌باشد:"
+
+#: views/pages/credits.thtml:103
+msgid "credits_section_developers"
+msgstr "توسعه‌دهندگان"
+
+#: views/pages/credits.thtml:115
+msgid "credits_section_editors"
+msgstr "ویرایش‌کنندگان"
+
+#: views/pages/credits.thtml:109
+msgid "credits_section_localizers"
+msgstr "محلی‌سازان"
+
+#: views/pages/credits.thtml:121
+msgid "credits_section_other_contributors"
+msgstr "دیگر مشارکت کنندگان"
+
+#: views/pages/credits.thtml:127
+msgid "credits_section_past_developers"
+msgstr "توسعه‌دهندگان پیشین"
+
+#: views/pages/credits.thtml:133
+msgid "credits_section_software"
+msgstr "نرم‌اÙزار Ùˆ تصاویر"
+
+#: views/pages/credits.thtml:136
+msgid "credits_software_famfamfam"
+msgstr "بعضی شمایل‌ها از <a href=\"http://www.famfamfam.com/lab/icons/silk/\">مجموعهٔ شمایل famfamfam Silk</a>ØŒ تحت مجوز <a href=\"http://creativecommons.org/licenses/by/2.5/\">تخصیص کریتیو کامنز Û²Ù«Ûµ</a> مورد استÙاده قرار گرÙته‌اند."
+
+#: views/pages/credits.thtml:137
+msgid "credits_software_timeplot"
+msgstr "بعضی از صÙحه‌ها از قسمت‌هایی از <a href=\"http://www.simile-widgets.org/timeplot/\">Timeplot</a> تحت مجوز <a href=\"http://simile.mit.edu/license.html\">BSD</a> استÙاده می‌کنند."
+
+#. date format string as used in PHP's strftime():
+#. http://php.net/strftime
+#: views/elements/collections_interactive_addon.thtml:85
+#: views/elements/amo2009/addon_version_detail.thtml:53
+#: views/elements/amo2009/homepage_addon.thtml:115
+#: views/elements/addon_version_detail.thtml:54
+#: views/elements/addon_listitem.thtml:124
+#: views/elements/feature.thtml:106
+#: views/collections/detail.thtml:118
+#: views/collections/edit.thtml:325
+#: views/users/info.thtml:76
+#: views/editors/reviews_queue.thtml:57
+#: views/editors/reviews_queue.thtml:68
+#: views/developers/dashboard.thtml:65
+#: views/developers/versions_edit.thtml:208
+#: views/developers/versions.thtml:67
+#: views/search/rss/index.thtml:5
+#: views/addons/rss/versions.thtml:42
+#: views/addons/display.thtml:104
+#: views/addons/display.thtml:356
+#: views/addons/browse_thumbs.thtml:75
+#: views/reviews/add.thtml:63
+#: views/reviews/display.thtml:74
+#: views/reviews/display.thtml:160
+#: views/reviews/delete.thtml:54
+#: controllers/statistics_controller.php:244
+#: controllers/collections_controller.php:1047
+msgid "date"
+msgstr "%e %B %Y"
+
+#. date and time format string (strftime)
+#. http://php.net/strftime
+#: views/elements/addon_version_detail.thtml:53
+#: views/developers/discuss.thtml:52
+#: views/developers/discuss.thtml:62
+#: views/admin/addons_status.thtml:57
+msgid "datetime"
+msgstr "%e %B %Y، %I:%M %p"
+
+#: views/elements/developers/actionbar.thtml:47
+msgid "devcp_actionbar_link_details"
+msgstr "اطلاعات Ù…Ùصل"
+
+#: views/elements/developers/actionbar.thtml:42
+#: views/elements/developers/actionbar.thtml:50
+#: views/developers/dashboard.thtml:64
+msgid "devcp_actionbar_link_edit"
+msgstr "ویرایش اÙزودنی"
+
+#: views/elements/developers/actionbar.thtml:51
+msgid "devcp_actionbar_link_newversion"
+msgstr "بارگذاری نسخهٔ جدید"
+
+#: views/elements/developers/actionbar.thtml:44
+#: views/elements/developers/actionbar.thtml:49
+#: views/developers/dashboard.thtml:73
+msgid "devcp_actionbar_link_stats"
+msgstr "صÙحهٔ آمار"
+
+#. %1$s is a filename, e.g. "foo.txt"
+#. %2$s is the extension, e.g. ".txt"
+#. %3$s is a list of valid extensions, like ".png, .jpg, .gif"
+#: controllers/developers_controller.php:1361
+msgid "devcp_add_previews_extension_error"
+msgstr "پسوند پروندهٔ %1$s†(%2$s) معتبر نیست. پسوندهای معتبر: %3$s"
+
+#. %s is the filename.
+#: controllers/developers_controller.php:1394
+msgid "devcp_add_previews_save_error"
+msgstr "قادر به ذخیرهٔ پروندهٔ %s در پایگاه داده نبود. لطÙاً دوباره تلاش نمایید."
+
+#. %1$s is the preview ID number, %2$s is the filename.
+#: controllers/developers_controller.php:1389
+msgid "devcp_add_previews_success_replace"
+msgstr "پیش‌نمایش %1$s با موÙقیت با پروندهٔ %2$s جایگزین گردید."
+
+#. %s is the filename.
+#: controllers/developers_controller.php:1391
+msgid "devcp_add_previews_success_upload"
+msgstr "پروندهٔ %s با موÙقیت بارگذاری شد. در پایین می‌توانید شرحی برای آن بنویسید."
+
+#: controllers/components/developers.php:1163
+msgid "devcp_additem_addontype_autodetect"
+msgstr "(شناسایی خودکار)"
+
+#: views/elements/developers/additem.thtml:76
+msgid "devcp_additem_linktitle_opensin_newwindow"
+msgstr "در پنجره‌ای جدید باز می‌شود"
+
+#: views/elements/developers/additem.thtml:41
+msgid "devcp_additem_sidebar_title"
+msgstr "ارسال اÙزودنی"
+
+#: views/elements/developers/additem.thtml:53
+msgid "devcp_additem_step0_newlink"
+msgstr "تواÙق‌نامهٔ توسعه‌دهنده"
+
+#: views/elements/developers/additem.thtml:46
+msgid "devcp_additem_step1_link"
+msgstr "گام ۱: بارگذاری"
+
+#: views/elements/developers/additem.thtml:47
+msgid "devcp_additem_step2_link"
+msgstr "گام Û²: جزئیات اÙزودنی"
+
+#: views/elements/developers/additem.thtml:48
+msgid "devcp_additem_step3_link"
+msgstr "گام ۳: جزئیات نسخه"
+
+#: views/elements/developers/additem.thtml:49
+msgid "devcp_additem_step4_link"
+msgstr "گام ۴: محلی‌سازی"
+
+#: views/elements/developers/additem.thtml:50
+msgid "devcp_additem_step5_link"
+msgstr "گام Ûµ: موÙقیت"
+
+#: views/elements/developers/additem.thtml:76
+msgid "devcp_additem_submissionhelp_link"
+msgstr "راهنمای ارسال"
+
+#: controllers/previews_controller.php:168
+#: controllers/previews_controller.php:277
+msgid "devcp_addon_field_preview_caption_displaytitle"
+msgstr "عنوان پیش‌نمایش"
+
+#: views/developers/addon_status.thtml:177
+msgid "devcp_addon_status_action_activate"
+msgstr "Ùعال شود"
+
+#: views/developers/addon_status.thtml:178
+msgid "devcp_addon_status_action_activate_description"
+msgstr "برای نمایش اÙزودنی در Ùهرست‌های عمومی Ùˆ Ùعال کردن خدمات بررسی به‌هنگام‌سازی آن را Ùعال سازید."
+
+#: views/developers/addon_status.thtml:135
+msgid "devcp_addon_status_action_complete"
+msgstr "کامل شود"
+
+#: views/developers/addon_status.thtml:136
+msgid "devcp_addon_status_action_complete_description"
+msgstr "اÙزودنی خود را تکمیل کنید Ùˆ آن را به گودال ماسه‌بازی انتقال دهید"
+
+#: views/developers/addon_status.thtml:181
+msgid "devcp_addon_status_action_deactivate"
+msgstr "غیر Ùعال شود"
+
+#: views/developers/addon_status.thtml:182
+msgid "devcp_addon_status_action_deactivate_description"
+msgstr "برای نمایش ندادن اÙزودنی در Ùهرست‌های عمومی Ùˆ غیر Ùعال کردن خدمات بررسی به‌هنگام‌سازی آن را غیر Ùعال کنید."
+
+#: views/developers/addon_status.thtml:143
+msgid "devcp_addon_status_action_move"
+msgstr "به گودال ماسه‌بازی منتقل شود"
+
+#: views/developers/addon_status.thtml:144
+msgid "devcp_addon_status_action_move_description"
+msgstr "اÙزودنی خود را به گودال ماسه‌بازی برگردانید. این عمل غیر قابل برگشت است."
+
+#: views/developers/addon_status.thtml:139
+msgid "devcp_addon_status_action_nominate"
+msgstr "نامزد عمومی شدن شود"
+
+#: views/developers/addon_status.thtml:140
+msgid "devcp_addon_status_action_nominate_description"
+msgstr "اÙزودنی خود را برای عمومی شدن نامزد کنید"
+
+#: views/developers/addon_status.thtml:147
+msgid "devcp_addon_status_action_public"
+msgstr "عمومی شود"
+
+#: views/developers/addon_status.thtml:148
+msgid "devcp_addon_status_action_public_description"
+msgstr "اÙزودنی خود را بار دیگر عمومی کنید."
+
+#: views/developers/addon_status.thtml:169
+msgid "devcp_addon_status_active"
+msgstr "اÙزودنی شما <span class=\"inactive-0\">Ùعال</span> شده است. این بدان معنی است Ú©Ù‡ اÙزودنی شما در تمامی Ùهرست‌های مربوط به وضعیت آن در بالا نمایش داده خواهد شد."
+
+#: views/developers/addon_status.thtml:111
+msgid "devcp_addon_status_completion_disabled"
+msgstr "لطÙاً معیارهای بالا را پیش از تکمیل اÙزودنی خود Ùˆ انتقال آن به <span class=\"status-1\">گودال ماسه‌بازی</span> تکمیل نمایید."
+
+#: views/developers/addon_status.thtml:108
+msgid "devcp_addon_status_completion_enabled"
+msgstr "اکنون می‌توانید اÙزودنی خود را تکمیل نموده Ùˆ با Ùشردن دکمهٔ زیر آن را به <span class=\"status-1\">گودال ماسه‌بازی</span> انتقال دهید."
+
+#: views/developers/addon_status.thtml:102
+msgid "devcp_addon_status_criteria_category"
+msgstr "حداقل یک دسته باید انتخاب شود"
+
+#: views/developers/addon_status.thtml:101
+msgid "devcp_addon_status_criteria_description"
+msgstr "اÙزودنی نیاز به شرح دارد"
+
+#: views/developers/addon_status.thtml:99
+msgid "devcp_addon_status_criteria_name"
+msgstr "اÙزودنی نیاز به نام دارد"
+
+#: views/developers/addon_status.thtml:120
+msgid "devcp_addon_status_criteria_prerelease"
+msgstr "اÙزودنی به عنوان نسخهٔ پیش از انتشار معرÙÛŒ نشده است."
+
+#: views/developers/addon_status.thtml:119
+msgid "devcp_addon_status_criteria_preview"
+msgstr "ضمیمه‌ها و تم‌ها باید حداقل یک تصویر پیش‌نمایش داشته باشند."
+
+#: views/developers/addon_status.thtml:100
+msgid "devcp_addon_status_criteria_summary"
+msgstr "اÙزودنی نیاز به خلاصه دارد"
+
+#. %s is the status in a span, e.g. "<span>_('Public')</span>".
+#: views/developers/addon_status.thtml:58
+msgid "devcp_addon_status_header"
+msgstr "وضعیت اÙزودنی: %s"
+
+#: views/developers/addon_status.thtml:152
+#: views/developers/addon_status.thtml:173
+msgid "devcp_addon_status_header_actions"
+msgstr "اعمال موجود"
+
+#: views/developers/addon_status.thtml:168
+msgid "devcp_addon_status_header_active"
+msgstr "وضعیت اÙزودنی: <span class=\"inactive-0\">Ùعال</span>"
+
+#: views/developers/addon_status.thtml:97
+msgid "devcp_addon_status_header_criteria"
+msgstr "معیارهای کامل بودن اÙزودنی"
+
+#: views/developers/addon_status.thtml:164
+msgid "devcp_addon_status_header_inactive"
+msgstr "وضعیت اÙزودنی: <span class=\"inactive-1\">غیر Ùعال</span>"
+
+#: views/developers/addon_status.thtml:117
+msgid "devcp_addon_status_header_nomination"
+msgstr "معیارهای نامزدی برای عمومی شدن"
+
+#: views/developers/addon_status.thtml:190
+msgid "devcp_addon_status_header_trusted"
+msgstr "وضعیت اعتماد: <span class=\"status-4\">مورد اعتماد</span>"
+
+#: views/developers/addon_status.thtml:165
+msgid "devcp_addon_status_inactive"
+msgstr "اÙزودنی شما <span class=\"inactive-1\">غیر Ùعال</span> است. این بدان معنی است Ú©Ù‡ اÙزودنی شما بدون توجه به وضعیت آن در بالا در هیچ Ùهرستی ظاهر نخواهد شد. خدمات بررسی به‌هنگام‌سازی برای اÙزودنی شما هیچ به‌هنگام‌سازی پیشنهاد <b>نخواهند داد</b>."
+
+#: views/developers/addon_status.thtml:128
+#, fuzzy
+msgid "devcp_addon_status_nominate_disabled"
+msgstr "Please fulfill the criteria above before nominating your add-on to become <span class=\"status-4\">Public</span>."
+
+#: views/developers/addon_status.thtml:125
+#, fuzzy
+msgid "devcp_addon_status_nominate_enabled"
+msgstr "You may now nominate your add-on for <span class=\"status-4\">Public</span> by clicking the button below."
+
+#: views/developers/addon_status.thtml:64
+msgid "devcp_addon_status_public"
+msgstr "عمومی"
+
+#: views/developers/addon_status.thtml:63
+msgid "devcp_addon_status_sandbox"
+msgstr "گودال ماسه‌بازی"
+
+#. %s is an email address.
+#: views/developers/addon_status.thtml:89
+#, fuzzy
+msgid "devcp_addon_status_switch_disabled"
+msgstr "Your add-on was <span class=\"status-5\">Disabled</span> by an administrator and cannot be used. If you have any questions, please e-mail %s."
+
+#: views/developers/addon_status.thtml:67
+#, fuzzy
+msgid "devcp_addon_status_switch_incomplete"
+msgstr "Your add-on is currently <span class=\"status-0\">Incomplete</span>. This means your add-on is not showing up on any portion of the site or update check service. You may come to this page to complete your add-on after it meets the criteria below for completion and transfer to the <span class=\"status-1\">Sandbox</span>."
+
+#. %s is a number, perhaps 42.
+#: views/developers/addon_status.thtml:77
+#, fuzzy
+msgid "devcp_addon_status_switch_nominated"
+msgstr "Your add-on is currently nominated to become <span class=\"status-4\">Public</span> and is awaiting editor review. There are currently %s other add-ons in the nomination queue."
+
+#. %s is an email address.
+#: views/developers/addon_status.thtml:81
+#, fuzzy
+msgid "devcp_addon_status_switch_pending"
+msgstr "Your add-on is pending. This shouldn't have happened. Please e-mail %s with your add-on ID and state this error."
+
+#: views/developers/addon_status.thtml:85
+#, fuzzy
+msgid "devcp_addon_status_switch_public"
+msgstr "Your add-on is <span class=\"status-4\">Public</span>, which means it will show up in all listings and searches and can be downloaded without restriction. Updates are being provided to your add-on through the update check service."
+
+#: views/developers/addon_status.thtml:71
+#: views/developers/addon_status.thtml:75
+#, fuzzy
+msgid "devcp_addon_status_switch_sandbox"
+msgstr "Your add-on is in the <span class=\"status-1\">Sandbox</span>, which means it will show up in listings and searches, but users must log in to download it. Updates are <b>not</b> being provided to your add-on through the update check service."
+
+#. %s is the add-on name.
+#: views/developers/addon_status_nominate.thtml:43
+#: views/developers/addon_status_confirm.thtml:43
+#: views/developers/addon_status.thtml:43
+msgid "devcp_addon_status_title"
+msgstr "وضعیت %s"
+
+#: views/developers/addon_status.thtml:191
+#, fuzzy
+msgid "devcp_addon_status_trusted"
+msgstr "Your add-on is <span class=\"status-4\">Trusted</span>. This means you can submit updates to your add-on without editor review."
+
+#: views/developers/dashboard.thtml:68
+msgid "devcp_dashboard_active"
+msgstr "Ùعال"
+
+#. %1$s is the add-on type string
+#. %2$s is Inactive or Active in a <span>
+#. %3$s is the addon's public status (Public, In Sandbox, ...) in a <span>
+#: views/developers/dashboard.thtml:69
+msgid "devcp_dashboard_addontype_status"
+msgstr "%1$s در حال حاضر %2$s و %3$s است"
+
+#: views/developers/dashboard.thtml:67
+msgid "devcp_dashboard_change_status"
+msgstr "تغییر وضعیت"
+
+#. %s is the addons email address.
+#: views/developers/dashboard.thtml:99
+#, fuzzy
+msgid "devcp_dashboard_disabled_questions"
+msgstr "Your add-on was disabled by an administrator and cannot be used. If you have any questions, please email %s."
+
+#. %s is the (localized) add-on status string in a span, e.g. "Disabled"
+#: views/developers/dashboard.thtml:98
+msgid "devcp_dashboard_disabled_status"
+msgstr "وضعیت اÙزودنی: %s"
+
+#: views/developers/dashboard.thtml:43
+msgid "devcp_dashboard_header_main"
+msgstr "صÙحهٔ آمار توسعه‌دهندگان"
+
+#: views/developers/dashboard.thtml:110
+msgid "devcp_dashboard_header_welcome"
+msgstr "به صÙحهٔ آمار توسعه‌دهندگان خوش آمدید"
+
+#: views/developers/dashboard.thtml:68
+msgid "devcp_dashboard_inactive"
+msgstr "غیر Ùعال"
+
+#. %s is a date in the _('date') format
+#: views/developers/dashboard.thtml:65
+msgid "devcp_dashboard_last_edited"
+msgstr "آخرین ویرایش در تاریخ %s"
+
+#: views/developers/dashboard.thtml:111
+msgid "devcp_dashboard_learn"
+msgstr "شما در حال حاضر هیچ اÙزودنی در وب‌گاه اÙزودنی‌های موزیلا ندارید. برای یادگیری Ùرایند ارسال اولین اÙزودنی خود، بر روی «چگونه شروع کنیم» کلیک کنید."
+
+#: views/developers/dashboard.thtml:112
+msgid "devcp_dashboard_start"
+msgstr "چگونه شروع کنیم"
+
+#: views/developers/dashboard.thtml:82
+msgid "devcp_dashboard_versions"
+msgstr "نسخه‌ها و پرونده‌ها"
+
+#: views/developers/dashboard.thtml:91
+msgid "devcp_dashboard_versions_new"
+msgstr "ارسال نسخه‌ای جدید"
+
+#. %s is the preview ID number.
+#: controllers/developers_controller.php:1415
+msgid "devcp_delete_previews_error"
+msgstr "قادر به حذ٠پیش‌نمایش %s از پایگاه داده نبود. لطÙاً دوباره تلاش کنید."
+
+#. %s is the preview ID number.
+#: controllers/developers_controller.php:1413
+msgid "devcp_delete_previews_success"
+msgstr "پیش‌نمایش %s با موÙقیت حذ٠گردید."
+
+#: controllers/developers_controller.php:1089
+msgid "devcp_delete_version_priv_error"
+msgstr "شما مجوز لازم را برای حذ٠نسخه‌ها و پرونده‌ها ندارید."
+
+#. %1$s is the count of files, a number
+#. %2$s is a status string like _('Public') or _('Incomplete')
+#: controllers/components/amo.php:549
+msgid "devcp_describe_version_status"
+msgid_plural "devcp_describe_version_status"
+msgstr[0] "%1$s پروندهٔ‌ %2$s"
+msgstr[1] "%1$s پروندهٔ %2$s"
+
+#. %s is a version number. Example: 3.0
+#: views/developers/versions.thtml:65
+#, php-format
+msgid "devcp_details_version"
+msgstr "نسخهٔ %s"
+
+#: views/developers/discuss.thtml:68
+msgid "devcp_discuss_addreply_header"
+msgstr "اÙزودن پاسخ"
+
+#: views/developers/discuss.thtml:57
+msgid "devcp_discuss_allreplies_header"
+msgstr "پاسخ‌ها"
+
+#. notice when an error occurs saving a discussion reply
+#. %1 is the email address (linked) for the amo-editors list
+#: views/developers/discuss.thtml:70
+msgid "devcp_discuss_error_notice"
+msgstr "خطایی در ذخیره کردن پاسخ‌تان روی داد. لطÙاً در این مورد با %1$s تماس بگیرید."
+
+#. %1 is the add-on name, %2 is the add-on's version number currently being reviewed by an editor
+#: views/developers/discuss.thtml:46
+msgid "devcp_discuss_intro"
+msgstr "یکی از ویرایش‌گران اÙزودنی‌های موزیلا دربارهٔ نسخهٔ %2$s از اÙزودنی %1$s از شما اطلاعات بیشتری درخواست کرده است."
+
+#. %1 is the add-on name
+#: views/developers/discuss.thtml:43
+msgid "devcp_discuss_pagetitle"
+msgstr "Ùراهم کردن اطلاعات بیشتر برای بررسی اÙزودنی %1$s"
+
+#. submit button text
+#: views/developers/discuss.thtml:79
+msgid "devcp_discuss_submit_reply"
+msgstr "ارسال پاسخ"
+
+#: views/developers/discuss.thtml:72
+msgid "devcp_discuss_success_message"
+msgstr "پاسخ شما با موÙقیت ذخیره گردید. دیگر شرکت‌کنندگان در این بحث توسط نامه‌ای الکترونیکی باخبر خواهند شد."
+
+#. in an author/editor discussion about an add-on to be reviewed:
+#. %1 is the commenter's user name (linked).
+#. %2 is the full date the comment was made.
+#: views/developers/discuss.thtml:52
+#: views/developers/discuss.thtml:62
+msgid "devcp_discuss_writtenby"
+msgstr "نوشته شده توسط %1$s در تاریخ %2$s"
+
+#: views/developers/addon_edit_authors.thtml:72
+#: views/developers/addon_edit_authors.thtml:81
+msgid "devcp_edit_authors_add_author"
+msgstr "اÙزودن مؤل٠جدید"
+
+#: views/developers/addon_edit_authors.thtml:96
+msgid "devcp_edit_authors_add_author_button"
+msgstr "اÙزودن مؤلÙ"
+
+#: views/developers/addon_edit_authors.thtml:83
+msgid "devcp_edit_authors_add_email"
+msgstr "آدرس پست الکترونیکی حساب کاربری مؤلÙ:"
+
+#: views/developers/addon_edit_authors.thtml:98
+msgid "devcp_edit_authors_add_loading"
+msgstr "در حال بررسی آدرس پست الکترونیکی حساب کاربری مؤلÙ..."
+
+#: views/developers/addon_edit_authors.thtml:70
+msgid "devcp_edit_authors_click_save"
+msgstr "برای ذخیره کردن بر روی دکمهٔ به‌هنگام‌سازی مؤلÙان در پایین کلیک کنید."
+
+#: views/developers/addon_edit_authors.thtml:58
+msgid "devcp_edit_authors_header_current"
+msgstr "مؤلÙان Ùعلی"
+
+#: views/developers/addon_edit_authors.thtml:50
+msgid "devcp_edit_authors_header_manage"
+msgstr "مدیریت مؤلÙان اÙزودنی"
+
+#: views/developers/addon_edit_authors.thtml:93
+msgid "devcp_edit_authors_label_add_listed"
+msgstr "نمایش به عنوان مؤل٠در صÙحه‌های نمایش عمومی"
+
+#: views/developers/addon_edit_authors.thtml:89
+#, fuzzy
+msgid "devcp_edit_authors_label_developer"
+msgstr "<strong>Developer</strong> - Can manage all aspects of the add-on listing, except for adding and removing other authors."
+
+#: views/developers/addon_edit_authors.thtml:88
+#, fuzzy
+msgid "devcp_edit_authors_label_owner"
+msgstr "<strong>Owner</strong> - Can manage all aspects of the add-on listing, including adding and removing other authors."
+
+#: views/developers/addon_edit_authors.thtml:90
+#, fuzzy
+msgid "devcp_edit_authors_label_viewer"
+msgstr "<strong>Viewer</strong> - Can view add-on developer listing and statistics, but can't make any changes."
+
+#. Placeholder for the empty option in a <select>.
+#: views/developers/addon_edit_categories.thtml:69
+msgid "devcp_edit_authors_option_empty"
+msgstr "----------------"
+
+#: views/developers/addon_edit_authors.thtml:86
+msgid "devcp_edit_authors_select_role"
+msgstr "یک نقش برای مؤل٠انتخاب کنید:"
+
+#. Column name in a table.
+#: views/developers/addon_edit_authors.thtml:62
+msgid "devcp_edit_authors_th_author"
+msgstr "مؤلÙ"
+
+#. Column name in a table.
+#: views/developers/addon_edit_authors.thtml:64
+msgid "devcp_edit_authors_th_listed"
+msgstr "Ùهرست شده"
+
+#. Column name in a table.
+#: views/developers/addon_edit_authors.thtml:63
+msgid "devcp_edit_authors_th_role"
+msgstr "نقش"
+
+#: views/developers/addon_edit_authors.thtml:77
+msgid "devcp_edit_authors_update_author"
+msgstr "به‌هنگام‌سازی مؤلÙان"
+
+#: views/developers/addon_edit_categories.thtml:99
+msgid "devcp_edit_categories_button_update"
+msgstr "به‌هنگام‌سازی دسته‌ها"
+
+#: views/developers/addon_edit_categories.thtml:88
+msgid "devcp_edit_categories_does_not_fit"
+msgstr "اÙزودنی من مناسب هیچ یک از دسته‌های موجود نیست."
+
+#. %s is the application name (Firefox, Thunderbird).
+#: views/developers/addon_edit_categories.thtml:61
+msgid "devcp_edit_categories_header_application"
+msgstr "دسته‌های %s"
+
+#: views/developers/addon_edit_categories.thtml:49
+msgid "devcp_edit_categories_header_manage"
+msgstr "مدیریت دسته‌ها"
+
+#: views/developers/addon_edit_categories.thtml:91
+msgid "devcp_edit_categories_hover"
+msgstr "برای مشاهدهٔ شرح هر دسته مکان‌نما را روی آن قرار دهید."
+
+#. %s is the category number (1, 2, 3).
+#: views/developers/addon_edit_categories.thtml:67
+msgid "devcp_edit_categories_label_category_num"
+msgstr "دستهٔ %s"
+
+#: views/developers/addon_edit_categories.thtml:94
+#: views/developers/addon_edit_categories.thtml:103
+msgid "devcp_edit_categories_none_available"
+msgstr "هیج دسته‌ای برای این نوع اÙزودنی Ùˆ برنامه وجود ندارد."
+
+#: views/developers/addon_edit_categories.thtml:86
+#, fuzzy
+msgid "devcp_edit_categories_other"
+msgstr "Place your add-on into this category only if it does not fit into any other available categories."
+
+#. %s is the application name (Firefox, Thunderbird).
+#: views/developers/addon_edit_categories.thtml:63
+msgid "devcp_edit_categories_select_application_categories"
+msgstr "حداکثر سه دستهٔ مربوط به %s برای اÙزودنی خود انتخاب کنید"
+
+#: views/developers/addon_edit.thtml:47
+msgid "devcp_edit_dd_manage_authors"
+msgstr "کاربرانی Ú©Ù‡ قادر به مدیریت این اÙزودنی هستند را ویرایش نمایید."
+
+#: views/developers/addon_edit.thtml:49
+msgid "devcp_edit_dd_manage_categories"
+msgstr "دسته‌های مربوط به هر برنامه‌ای Ú©Ù‡ توسط اÙزودنی‌تان مورد پشتیبانی قرار می‌گیرد را انتخاب نمایید."
+
+#: views/developers/addon_edit.thtml:51
+msgid "devcp_edit_dd_manage_description"
+msgstr "ترجمه‌های خلاصه، شرح، تواÙق‌نامهٔ کاربر نهایی Ùˆ سیاست Ø­Ùظ حریم خصوصی اÙزودنی خود را ویرایش نمایید."
+
+#: views/developers/addon_edit.thtml:53
+msgid "devcp_edit_dd_manage_properties"
+msgstr "نام، صÙحهٔ آغازه، شمایل Ùˆ دیگر ویژگی‌های اÙزودنی خود را تغییر دهید."
+
+#: views/developers/addon_edit_descriptions.thtml:116
+msgid "devcp_edit_description_button_update"
+msgstr "به‌هنگام‌سازی شرح‌ها"
+
+#: views/developers/addon_edit_descriptions.thtml:115
+msgid "devcp_edit_description_correct_error"
+msgstr "لطÙاً اشکالات بالا را Ú©Ù‡ با رنگ قرمز مشخص شده‌اند تصحیح نمایید."
+
+#: views/developers/addon_edit_descriptions.thtml:51
+msgid "devcp_edit_descriptions_header"
+msgstr "ویرایش شرح‌های اÙزودنی"
+
+#: views/developers/addon_edit_descriptions.thtml:94
+msgid "devcp_edit_descriptions_transbox_comments_description"
+msgstr "اطلاعاتی Ú©Ù‡ برای کاربران Ù…Ùید است ولی لزوماً در خلاصه یا شرح اÙزودنی جایی ندارد. استÙاده‌های معمول شامل برشمردن اشکالات عمدهٔ معلوم اÙزودنی، اطلاعاتی در مورد چگونگی گزارش اشکالات، تاریخ تقریبی انتشار نسخه‌های جدید Ùˆ غیره می‌باشد."
+
+#: views/developers/addon_edit_descriptions.thtml:93
+msgid "devcp_edit_descriptions_transbox_comments_name"
+msgstr "توضیحات توسعه‌دهنده"
+
+#: views/developers/addon_edit_descriptions.thtml:86
+msgid "devcp_edit_descriptions_transbox_description_description"
+msgstr "شرح اÙزودنی توضیح بیشتری از ویژگی‌ها، کارایی‌ها Ùˆ دیگر اطلاعات مربوطه است. شرح در زیر خلاصهٔ اÙزودنی در صÙحهٔ مربوط به آن نمایش داده می‌شود."
+
+#: views/developers/addon_edit_descriptions.thtml:85
+msgid "devcp_edit_descriptions_transbox_description_name"
+msgstr "شرح اÙزودنی"
+
+#: views/developers/addon_edit_descriptions.thtml:103
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_eula_description"
+msgstr "If your add-on has an End-User License Agreement (EULA), please enter its text below. If set below, users will be required to agree to this before installing your add-on. Please note that a EULA is not the same as a code license such as GPL or MPL."
+
+#: views/developers/addon_edit_descriptions.thtml:102
+msgid "devcp_edit_descriptions_transbox_eula_name"
+msgstr "تواÙق‌نامهٔ مجوز کاربر نهایی"
+
+#: views/developers/addon_edit_descriptions.thtml:112
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_privacy_description"
+msgstr "If your add-on has a privacy policy, enter its text here. Your add-on's display page will display a link to the policy."
+
+#: views/developers/addon_edit_descriptions.thtml:111
+msgid "devcp_edit_descriptions_transbox_privacy_name"
+msgstr "سیاست Ø­Ùظ حریم خصوصی"
+
+#: views/developers/addon_edit_descriptions.thtml:78
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_summary_description"
+msgstr "The summary is a short explanation of your add-on's basic functionality that is displayed in search and browse listings, as well as at the top of your add-on's display page. <strong>Limit of 250 characters.</strong>"
+
+#: views/developers/addon_edit_descriptions.thtml:77
+msgid "devcp_edit_descriptions_transbox_summary_name"
+msgstr "خلاصهٔ اÙزودنی"
+
+#: views/developers/addon_edit.thtml:46
+msgid "devcp_edit_dt_manage_authors"
+msgstr "مدیریت مؤلÙان اÙزودنی"
+
+#: views/developers/addon_edit.thtml:48
+msgid "devcp_edit_dt_manage_categories"
+msgstr "مدیریت دسته‌های اÙزودنی"
+
+#: views/developers/addon_edit.thtml:50
+msgid "devcp_edit_dt_manage_descriptions"
+msgstr "مدیریت شرح اÙزودنی"
+
+#: views/developers/addon_edit.thtml:52
+msgid "devcp_edit_dt_manage_properties"
+msgstr "مدیریت ویژگی‌های اÙزودنی"
+
+#: views/developers/addon_edit_properties.thtml:170
+msgid "devcp_edit_label_externalsoftware"
+msgstr "این اÙزودنی به نرم‌اÙزار خارجی نیاز دارد"
+
+#: views/developers/addon_edit_properties.thtml:205
+msgid "devcp_edit_label_locale_disambiguation"
+msgstr "اطلاعات بیشتری از منطقه"
+
+#: views/developers/addon_edit_properties.thtml:168
+msgid "devcp_edit_label_prerelease"
+msgstr "این یک نسخهٔ پیش از انتشار است"
+
+#: views/developers/addon_edit_properties.thtml:169
+msgid "devcp_edit_label_sitespecific"
+msgstr "این اÙزودنی خاص یک وب‌گاه است"
+
+#: views/developers/addon_edit_properties.thtml:202
+msgid "devcp_edit_label_target_locale"
+msgstr "منطقهٔ مقصد"
+
+#: views/developers/addon_edit_properties.thtml:212
+msgid "devcp_edit_properties_button_update"
+msgstr "به‌هنگام‌سازی ویژگی‌ها"
+
+#: views/developers/addon_edit_properties.thtml:198
+msgid "devcp_edit_properties_change_guid"
+msgstr "تنها در صورتی که از اثر تغییرات اطلاع کامل دارید این موارد را تغییر دهید."
+
+#: views/developers/addon_edit_properties.thtml:109
+msgid "devcp_edit_properties_current_icon"
+msgstr "شمایل Ùعلی"
+
+#: views/developers/addon_edit_properties.thtml:85
+#, fuzzy
+msgid "devcp_edit_properties_default_locale"
+msgstr "An add-on's default locale is the main locale in which translations must be present. If translations for your add-on's descriptions are unavailable in a user's selected language, they will fall back to this default locale."
+
+#: views/developers/addon_edit_properties.thtml:167
+#, fuzzy
+msgid "devcp_edit_properties_flags"
+msgstr "These flags are used to filter and classify add-ons."
+
+#: views/developers/addon_edit_properties.thtml:174
+#, fuzzy
+msgid "devcp_edit_properties_guid"
+msgstr "The GUID of your add-on is specified in its install.rdf and uniquely identifies it. You cannot change your GUID once it is listed on Mozilla Add-ons."
+
+#: views/developers/addon_edit_properties.thtml:53
+msgid "devcp_edit_properties_header"
+msgstr "ویرایش ویژگی‌های اÙزودنی"
+
+#: views/developers/addon_edit_properties.thtml:186
+msgid "devcp_edit_properties_header_addon_type"
+msgstr "نوع اÙزودنی"
+
+#: views/developers/addon_edit_properties.thtml:181
+msgid "devcp_edit_properties_header_admin_settings"
+msgstr "تنظیمات مدیریتی"
+
+#: views/developers/addon_edit_properties.thtml:84
+msgid "devcp_edit_properties_header_default_locale"
+msgstr "زبان پیش‌Ùرض"
+
+#: views/developers/addon_edit_properties.thtml:166
+msgid "devcp_edit_properties_header_flags"
+msgstr "پرچم‌های اÙزودنی"
+
+#: views/developers/addon_edit_properties.thtml:173
+#: views/developers/addon_edit_properties.thtml:197
+msgid "devcp_edit_properties_header_guid"
+msgstr "شناسهٔ اÙزودنی"
+
+#: views/developers/addon_edit_properties.thtml:104
+msgid "devcp_edit_properties_header_icon"
+msgstr "شمایل اÙزودنی"
+
+#: views/developers/addon_edit_properties.thtml:159
+msgid "devcp_edit_properties_header_other_settings"
+msgstr "تنظیمات دیگر"
+
+#. A header on the admin page to toggle trusted status.
+#: views/developers/addon_edit_properties.thtml:182
+msgid "devcp_edit_properties_header_trusted"
+msgstr "آیا اÙزودنی مورد اعتماد است؟"
+
+#: views/developers/addon_edit_properties.thtml:160
+msgid "devcp_edit_properties_header_view_source"
+msgstr "مشاهدهٔ کد منبع به صورت متصل به شبکه"
+
+#. %s is a comma-separated list of image extensions ".png, .jpg"
+#: views/developers/addon_edit_properties.thtml:106
+#, fuzzy
+msgid "devcp_edit_properties_icon"
+msgstr "The add-on icon is a small image that is displayed next to your add-on's name in browse and search results, display pages, and in the add-on installation dialog. The image will automatically be resized to 32 x 32 pixels. Please use one of the following image types: %s"
+
+#: views/developers/addon_edit_properties.thtml:171
+msgid "devcp_edit_properties_label_binary"
+msgstr "این اÙزودنی حاوی مؤلÙه‌های دودویی است"
+
+#: views/developers/addon_edit_properties.thtml:185
+msgid "devcp_edit_properties_label_not_trusted"
+msgstr "غیر مورد اعتماد"
+
+#: views/developers/addon_edit_properties.thtml:184
+msgid "devcp_edit_properties_label_trusted"
+msgstr "مورد اعتماد"
+
+#: views/developers/addon_edit_properties.thtml:110
+msgid "devcp_edit_properties_new_icon"
+msgstr "شمایل جدید"
+
+#: views/developers/addon_edit_properties.thtml:118
+msgid "devcp_edit_properties_remove_icon"
+msgstr "حذ٠شمایل"
+
+#: views/developers/addon_edit_properties.thtml:136
+#, fuzzy
+msgid "devcp_edit_properties_transbox_homepage_description"
+msgstr "If your add-on has another homepage, enter its address here. Adding other translations is not necessary unless your website is localized into other languages."
+
+#: views/developers/addon_edit_properties.thtml:135
+msgid "devcp_edit_properties_transbox_homepage_name"
+msgstr "صÙحهٔ آغازهٔ اÙزودنی"
+
+#: views/developers/addon_edit_properties.thtml:79
+#, fuzzy
+msgid "devcp_edit_properties_transbox_name_description"
+msgstr "The name of your add-on is displayed everywhere your add-on is listed."
+
+#: views/developers/addon_edit_properties.thtml:78
+msgid "devcp_edit_properties_transbox_name_name"
+msgstr "نام اÙزودنی"
+
+#: views/developers/addon_edit_properties.thtml:145
+#, fuzzy
+msgid "devcp_edit_properties_transbox_supportemail_description"
+msgstr "If you have an email address for support inquiries, enter it here. Adding other translations is not necessary unless you have different email addresses for different languages."
+
+#: views/developers/addon_edit_properties.thtml:144
+msgid "devcp_edit_properties_transbox_supportemail_name"
+msgstr "نشانی پست الکترونیکی پشتیبانی"
+
+#: views/developers/addon_edit_properties.thtml:154
+#, fuzzy
+msgid "devcp_edit_properties_transbox_supporturl_description"
+msgstr "If your add-on has a support website or forum, enter its address here. Adding other translations is not necessary unless your website is localized into other languages."
+
+#: views/developers/addon_edit_properties.thtml:153
+msgid "devcp_edit_properties_transbox_supporturl_name"
+msgstr "وب‌گاه پشتیبانی"
+
+#: views/developers/addon_edit_properties.thtml:183
+msgid "devcp_edit_properties_trusted"
+msgstr "اÙزودنی‌های مورد اعتماد می‌توانند بدون بررسی ویرایش‌گران عمومی شوند."
+
+#. %s is href="..." and should stay in the <a> tag.
+#: views/developers/addon_edit_properties.thtml:119
+msgid "devcp_edit_properties_undelete"
+msgstr "شمایل هنگام ذخیره کردن حذ٠خواهد شد. <a %s>اگر منصر٠شده‌اید اینجا را کلیک کنید.</a>"
+
+#: views/developers/addon_edit_properties.thtml:161
+#, fuzzy
+msgid "devcp_edit_properties_view_source"
+msgstr "The source of your add-on files can be viewed online by any logged in user if you wish."
+
+#: views/developers/addon_edit_properties.thtml:162
+msgid "devcp_edit_properties_view_source_allow"
+msgstr "اجازهٔ مشاهدهٔ متصل کد منبع داده شود"
+
+#: views/developers/addon_edit_properties.thtml:163
+msgid "devcp_edit_properties_view_source_do_not_allow"
+msgstr "اجازهٔ مشاهدهٔ متصل کد منبع داده نشود"
+
+#: views/elements/developers/editbox.thtml:46
+msgid "devcp_editbox_authors"
+msgstr "مؤلÙان"
+
+#: views/elements/developers/editbox.thtml:47
+msgid "devcp_editbox_categories"
+msgstr "دسته‌ها"
+
+#: views/elements/developers/editbox.thtml:52
+msgid "devcp_editbox_change_status"
+msgstr "تغییر وضعیت"
+
+#: views/elements/developers/editbox.thtml:48
+msgid "devcp_editbox_descriptions"
+msgstr "شرح‌ها"
+
+#: views/elements/developers/editbox.thtml:43
+msgid "devcp_editbox_edit_addon"
+msgstr "ویرایش اÙزودنی"
+
+#: views/elements/developers/editbox.thtml:57
+msgid "devcp_editbox_new_version"
+msgstr "نسخهٔ جدید"
+
+#: views/elements/developers/editbox.thtml:49
+msgid "devcp_editbox_properties"
+msgstr "ویژگی‌ها"
+
+#: views/elements/developers/editbox.thtml:60
+msgid "devcp_editbox_screenshots"
+msgstr "تصاویر پیش‌نمایش"
+
+#: views/elements/developers/editbox.thtml:53
+msgid "devcp_editbox_statistics_dashboard"
+msgstr "صÙحهٔ آمار"
+
+#: views/elements/developers/editbox.thtml:54
+msgid "devcp_editbox_versions"
+msgstr "نسخه‌ها و پرونده‌ها"
+
+#: views/elements/developers/editbox.thtml:42
+msgid "devcp_editbox_view_listing"
+msgstr "مشاهدهٔ Ùهرست"
+
+#: views/elements/developers/editorsmenu.thtml:59
+msgid "devcp_editorsqueue_featured"
+msgstr "اÙزودنی‌های ویژه"
+
+#. %1 is the review count
+#: views/elements/developers/editorsqueue.thtml:42
+#: views/elements/developers/editorsmenu.thtml:56
+#, php-format
+msgid "devcp_editorsqueue_moderatedreviews"
+msgid_plural "devcp_editorsqueue_moderatedreviews"
+msgstr[0] "بررسی‌های تعدیل شده (%s)"
+msgstr[1] "بررسی‌های تعدیل شده (%s)"
+
+#. %1 is the nominated addons count
+#: views/elements/developers/editorsqueue.thtml:44
+#: views/elements/developers/editorsmenu.thtml:58
+#, php-format
+msgid "devcp_editorsqueue_nominated"
+msgid_plural "devcp_editorsqueue_nominated"
+msgstr[0] "اÙزودنی‌های نامزد شده (%s)"
+msgstr[1] "اÙزودنی‌های نامزد شده (%s)"
+
+#. %1 is the update count
+#: views/elements/developers/editorsqueue.thtml:43
+#: views/elements/developers/editorsmenu.thtml:57
+#, php-format
+msgid "devcp_editorsqueue_pendingupdates"
+msgid_plural "devcp_editorsqueue_pendingupdates"
+msgstr[0] "به‌هنگام‌سازی‌های باقی‌مانده (%s)"
+msgstr[1] "به‌هنگام‌سازی‌های باقی‌مانده (%s)"
+
+#: controllers/statistics_controller.php:147
+#: controllers/statistics_controller.php:361
+#: controllers/previews_controller.php:108
+#: controllers/previews_controller.php:211
+#: controllers/previews_controller.php:312
+msgid "devcp_error_addon_access_denied"
+msgstr "شما به آن اÙزودنی دسترسی ندارید."
+
+#. %s is a complete URL with the text from devcp_error_appversion_reference_link_text
+#. in the <a> tag. This should be fixed.
+#: controllers/components/developers.php:591
+#, php-format
+msgid "devcp_error_appversion_reference_link"
+msgstr "لطÙاً %s را به عنوان مرجع ملاحظه نمایید."
+
+#. This is the link text in the <a> for devcp_error_appversion_reference_link. This
+#. should be fixed.
+#: controllers/components/developers.php:591
+msgid "devcp_error_appversion_reference_link_text"
+msgstr "این صÙحه"
+
+#: views/developers/addon_edit_authors.thtml:76
+msgid "devcp_error_empty_authors"
+msgstr "اÙزودنی شما باید حداقل یک مؤل٠داشته باشد."
+
+#. %1$s is the name of the file
+#: controllers/components/developers.php:658
+msgid "devcp_error_file_exists"
+msgstr "یک نسخه از این اÙزودنی از قبل وجود دارد. برای جایگزین کردن آن، ابتدا باید پروندهٔ %1$s را حذ٠نمایید."
+
+#. %1$s is a file extension. Example: .exe
+#. %2$s is a comma separated list of extensions. Example: .xpi, .jar
+#: controllers/components/developers.php:355
+#, php-format
+msgid "devcp_error_file_extension"
+msgstr "این پسوند پرونده (%s) برای نوع اÙزودنی انتخاب شده مجاز نیست. لطÙاً از یکی از پسوندهای زیر استÙاده کنید: %s"
+
+#: controllers/components/developers.php:64
+msgid "devcp_error_five_categories"
+msgstr "لطÙاً بیش از Ûµ دسته انتخاب نکنید."
+
+#: controllers/components/developers.php:526
+msgid "devcp_error_guid_application"
+msgstr "شناسهٔ این اÙزودنی توسط برنامه‌ای مورد استÙاده قرار گرÙته است."
+
+#: controllers/components/developers.php:337
+#: controllers/components/developers.php:389
+msgid "devcp_error_http_incomplete"
+msgstr "انتقال نیمه‌کاره"
+
+#: controllers/components/developers.php:335
+#: controllers/components/developers.php:336
+#: controllers/components/developers.php:387
+#: controllers/components/developers.php:388
+msgid "devcp_error_http_maxupload"
+msgstr "اندازهٔ پرونده بیش از اندازهٔ بارگذاری مجاز"
+
+#: controllers/components/developers.php:338
+#: controllers/components/developers.php:390
+msgid "devcp_error_http_nofile"
+msgstr "هیچ پرونده‌ای بارگذاری نشد"
+
+#. %1$s is a file extension. Example: .exe
+#. %2$s is a comma separated list of extensions. Example: .xpi, .jar
+#: controllers/components/developers.php:401
+#, php-format
+msgid "devcp_error_icon_extension"
+msgstr "این پسوند پرونده (%s) برای شمایل مجاز نیست. لطÙاً از یکی از پسوندهای زیر استÙاده کنید: %s"
+
+#: controllers/developers_controller.php:504
+msgid "devcp_error_index_rdf_notfound"
+msgstr "پروندهٔ install.rdf وجود ندارد."
+
+#: controllers/components/developers.php:601
+msgid "devcp_error_install_manifest"
+msgstr "خطاهای زیر در پروندهٔ install.rdf پیدا شد:"
+
+#: controllers/developers_controller.php:1463
+#, fuzzy
+msgid "devcp_error_invalid_addontype"
+msgstr "شناسهٔ این اÙزودنی نامعتبر است: %s"
+
+#. %$1s is a version. Example: 3.1.1
+#. %$2s is an add-on name.
+#: controllers/components/developers.php:569
+#: controllers/components/developers.php:581
+#, php-format
+msgid "devcp_error_invalid_appversion"
+msgstr "%s نسخهٔ مجازی برای %s نیست"
+
+#. %s is a string
+#: controllers/components/developers.php:521
+#, php-format
+msgid "devcp_error_invalid_guid"
+msgstr "شناسهٔ این اÙزودنی نامعتبر است: %s"
+
+#. %$1s is a version. Example: 3.1.1
+#. %$2s is an add-on name.
+#: controllers/components/developers.php:572
+#, php-format
+msgid "devcp_error_invalid_minversion"
+msgstr "%s نسخهٔ معتبری برای %s نیست: نسخه‌های کمینه نمی‌توانند شامل * باشند"
+
+#: controllers/components/developers.php:536
+msgid "devcp_error_invalid_version"
+msgstr "نسخهٔ این اÙزودنی مجاز نیست: لطÙاً <a href=\"http://developer.mozilla.org/en/docs/Toolkit_version_format\">مشخصات</a> را ملاحظه کنید"
+
+#: controllers/components/developers.php:531
+msgid "devcp_error_invalid_version_spaces"
+msgstr "نسخهٔ این اÙزودنی معتبر نیست: نسخه‌ها نمی‌توانند شامل Ùاصله باشند."
+
+#. %s is an error message from the parser.
+#: controllers/components/developers.php:501
+#, php-format
+msgid "devcp_error_manifest_parse"
+msgstr "خطای زیر در هنگام تجزیهٔ install.rdf روی داد: %s"
+
+#: controllers/components/developers.php:373
+msgid "devcp_error_move_file"
+msgstr "تغییر مکان پرونده شکست خورد"
+
+#. %s is the name of a file
+#: controllers/components/developers.php:650
+#: controllers/components/developers.php:662
+#: controllers/components/developers.php:667
+#: controllers/components/developers.php:727
+#: controllers/components/developers.php:738
+#: controllers/components/developers.php:743
+#, php-format
+msgid "devcp_error_moving_file"
+msgstr "خطایی در تغییر مکان %s روی داد."
+
+#: controllers/components/developers.php:595
+msgid "devcp_error_mozilla_application"
+msgstr "باید کمینه یک برنامهٔ مقصد معتبر بر پایهٔ موزیلا را انتخاب کنید."
+
+#: controllers/components/developers.php:516
+msgid "devcp_error_no_guid"
+msgstr "شناسه‌ای برای این اÙزودنی در install.rdf تعری٠نشده است."
+
+#: controllers/components/developers.php:287
+msgid "devcp_error_no_platform"
+msgstr "سکوی نرم‌اÙزاری انتخاب نشده است"
+
+#: controllers/components/developers.php:59
+msgid "devcp_error_one_category"
+msgstr "لطÙاً کمینه یک دسته را انتخاب کنید."
+
+#: controllers/components/developers.php:92
+msgid "devcp_error_one_user"
+msgstr "کمینه یک مؤل٠برای این اÙزودنی باید تعری٠شده باشد."
+
+#. %1$s is a file extension. Example: .exe
+#. %2$s is a comma separated list of extensions. Example: .xpi, .jar
+#: controllers/components/developers.php:1081
+#, php-format
+msgid "devcp_error_preview_extension"
+msgstr "پسوند پروندهٔ (%s) برای یک پیش‌نمایش مجاز نیست. لطÙاً از یکی از پسوندهای زیر استÙاده کنید: %s"
+
+#: controllers/components/developers.php:511
+msgid "devcp_error_updatekey"
+msgstr "اÙزودنی‌ها قادر به استÙاده از updateKey نیستند. لطÙاً این را از install.rdf حذ٠کنید Ùˆ دوباره تلاش نمایید."
+
+#: controllers/components/developers.php:506
+msgid "devcp_error_updateurl"
+msgstr "اÙزودنی‌ها قادر به استÙاده از یک updateURL خارجی نیستند. لطÙاً این را از install.rdf حذ٠کنید Ùˆ دوباره تلاش نمایید."
+
+#: controllers/developers_controller.php:465
+#: controllers/components/developers.php:271
+msgid "devcp_error_upload_file"
+msgstr "لطÙاً یک پرونده بارگذاری نمایید."
+
+#: views/developers/uploader.thtml:135
+msgid "devcp_input_upload_file"
+msgstr "بارگذاری پرونده"
+
+#: views/pages/js_constants.js.thtml:89
+msgid "devcp_js_a_cancel"
+msgstr "انصراÙ"
+
+#: views/pages/js_constants.js.thtml:90
+msgid "devcp_js_add_email"
+msgstr "لطÙاً نشانی پست الکترونیکی حساب کاربری مؤلÙÛŒ را Ú©Ù‡ مایل به اÙزودن هستید وارد کنید."
+
+#. alt text for a down-arrow image.
+#: views/pages/js_constants.js.thtml:81
+msgid "devcp_js_img_move_down"
+msgstr "حرکت به پایین"
+
+#. alt text for an up-arrow image.
+#: views/pages/js_constants.js.thtml:82
+msgid "devcp_js_img_move_up"
+msgstr "انتقال به بالا"
+
+#: views/pages/js_constants.js.thtml:91
+msgid "devcp_js_img_remove_compat"
+msgstr "حذ٠سازگاری با برنامه‌ها"
+
+#: views/pages/js_constants.js.thtml:86
+msgid "devcp_js_input_list_author"
+msgstr "نمایش به عنوان مؤل٠در Ùهرست‌های عمومی"
+
+#: views/pages/js_constants.js.thtml:92
+msgid "devcp_js_license_select"
+msgstr "لطÙاً یک مجوز انتخاب کنید."
+
+#: views/pages/js_constants.js.thtml:93
+msgid "devcp_js_license_text"
+msgstr "لطÙاً متن مجوز خود را وارد نمایید."
+
+#. <option> text in a <select> for Author role in an add-on.
+#: views/pages/js_constants.js.thtml:84
+msgid "devcp_js_option_developer"
+msgstr "توسعه‌دهنده"
+
+#. <option> text in a <select> for Author role in an add-on.
+#: views/pages/js_constants.js.thtml:83
+msgid "devcp_js_option_owner"
+msgstr "صاحب"
+
+#. <option> text in a <select> for Author role in an add-on.
+#: views/pages/js_constants.js.thtml:85
+msgid "devcp_js_option_viewer"
+msgstr "مشاهده کننده"
+
+#: views/pages/js_constants.js.thtml:88
+msgid "devcp_js_remove_author"
+msgstr "حذ٠مؤلÙ"
+
+#: views/pages/js_constants.js.thtml:87
+msgid "devcp_js_sure_remove"
+msgstr "آیا از حذ٠این مؤل٠<strong>اطمینان دارید</strong>؟"
+
+#: views/pages/js_constants.js.thtml:77
+msgid "devcp_js_upload_alert"
+msgstr "باید یک پرونده برای بارگذاری انتخاب نمایید."
+
+#. %1$s is an addon id, like 32.
+#. %2$s is a version number, like 3.5.
+#: controllers/components/developers.php:1212
+msgid "devcp_license_existing"
+msgstr "مجوز خاص برای اÙزودنی %1$s نسخهٔ %2$s"
+
+#: views/elements/developers/localebox.thtml:44
+msgid "devcp_localebox_header_localizedfields"
+msgstr "Ùیلدهای محلی شده"
+
+#. %1 is the default locale
+#: views/elements/developers/localebox.thtml:48
+#, php-format
+msgid "devcp_localebox_intro"
+msgstr "بعضی از Ùیلدهای این صÙحه برای نمایش داده شدن به زبان مادری کاربر نهایی ترجمه شده‌اند. منطقه‌ای را از پایین برای ویرایش جزئیات اÙزودنی خود در آن زبان انتخاب کنید. اگر ترجمه‌ای برای یک منطقه وجود نداشته باشد، متن مربوطه از منطقهٔ پیش‌Ùرض انتخاب شده (%s) انتخاب خواهد شد."
+
+#: views/elements/developers/sidebar.thtml:68
+#: views/elements/developers/myaddons.thtml:75
+msgid "devcp_myaddons_admincp_link"
+msgstr "ابزارهای مدیر"
+
+#: views/elements/developers/sidebar.thtml:65
+#: views/elements/developers/myaddons.thtml:72
+msgid "devcp_myaddons_editorcp_link"
+msgstr "ابزارهای ویرایش‌گر"
+
+#: views/elements/developers/myaddons.thtml:52
+msgid "devcp_myaddons_link"
+msgstr "اÙزودنی‌های من"
+
+#: views/elements/developers/sidebar.thtml:70
+#: views/elements/developers/myaddons.thtml:77
+msgid "devcp_myaddons_mainpage_link"
+msgstr "بازگشت به صÙحهٔ اصلی"
+
+#: views/elements/developers/sidebar.thtml:63
+#: views/elements/developers/myaddons.thtml:70
+msgid "devcp_myaddons_statistics_link"
+msgstr "صÙحهٔ آمار"
+
+#: views/elements/developers/sidebar.thtml:62
+#: views/elements/developers/myaddons.thtml:69
+msgid "devcp_myaddons_submitaddon_link"
+msgstr "ارسال اÙزودنی"
+
+#: views/elements/developers/sidebar.thtml:48
+#: views/elements/developers/myaddons.thtml:67
+msgid "devcp_myaddons_title"
+msgstr "ابزارهای توسعه‌دهنده"
+
+#. %1$s is an add-on ID, perhaps 167.
+#. %2$s is a URL.
+#: controllers/developers_controller.php:256
+#, fuzzy
+msgid "devcp_new_addon_error"
+msgstr "This add-on ID (%1$s) already exists in the database. If this is your add-on, you can <a href=\"%2$s\">upload a new version</a>."
+
+#: views/developers/addon_status_nominate.thtml:62
+msgid "devcp_nominate_cancel"
+msgstr "انصرا٠و بازگشت"
+
+#. %1 is the add-on name
+#: views/developers/addon_status_nominate.thtml:61
+#, php-format
+msgid "devcp_nominate_submit_nominate"
+msgstr "نامزد کردن %s"
+
+#: views/developers/addon_edit_properties.thtml:50
+#: views/developers/addon_status.thtml:49
+#: views/developers/versions_edit.thtml:50
+#, fuzzy
+msgid "devcp_notice_changes_error"
+msgstr "<span>One or more of your changes couldn't be saved.</span><br />Please look for the errors below. The rest of your changes were successfully saved."
+
+#: views/developers/addon_edit_authors.thtml:47
+#: views/developers/addon_edit_properties.thtml:47
+#: views/developers/addon_status.thtml:46
+#: views/developers/addon_edit_descriptions.thtml:47
+#: views/developers/versions_edit.thtml:47
+#: views/developers/addon_edit_categories.thtml:46
+msgid "devcp_notice_changes_saved"
+msgstr "<span>تغییرات شما ذخیره گردید.</span><br />لطÙاً توجه نمایید Ú©Ù‡ منعکس شدن برخی تغییرات در تمام بخش‌های وب‌گاه ممکن است چندین ساعت به طول انجامد."
+
+#: controllers/previews_controller.php:252
+msgid "devcp_notice_cleardefault"
+msgstr "حذ٠پیش‌نمایش پیش‌Ùرض باعث می‌شود یک پیش‌نمایش دیگر به صورت خودکار به عنوان پیش‌نمایش پیش‌Ùرض انتخاب شود."
+
+#: controllers/previews_controller.php:184
+#: controllers/previews_controller.php:251
+msgid "devcp_notice_makedefault"
+msgstr "انتخاب این پیش‌نمایش به عنوان پیش‌نمایش پیش‌Ùرض باعث می‌شود پیش‌نمایش پیش‌Ùرض کنونی از حالت پیش‌Ùرضی خارج شود."
+
+#: views/developers/addon_edit_authors.thtml:70
+msgid "devcp_notice_unsaved_changes"
+msgstr "هنوز تغییرات ذخیره نشده‌ای دارید."
+
+#: controllers/developers_controller.php:87
+#: controllers/developers_controller.php:97
+#: controllers/developers_controller.php:100
+#: controllers/previews_controller.php:67
+#: controllers/previews_controller.php:79
+#: controllers/previews_controller.php:82
+msgid "devcp_pagetitle"
+msgstr "ابزارهای توسعه‌دهنده"
+
+#: controllers/previews_controller.php:103
+#: controllers/previews_controller.php:104
+msgid "devcp_preview_add_pagetitle"
+msgstr "اÙزودن پیش‌نمایش"
+
+#: controllers/previews_controller.php:135
+msgid "devcp_preview_added_successfully"
+msgstr "پیش‌نمایش با موÙقیت اضاÙÙ‡ شد."
+
+#: controllers/previews_controller.php:323
+msgid "devcp_preview_deleted_successfully"
+msgstr "پیش‌نمایش با موÙقیت حذ٠شد."
+
+#: controllers/previews_controller.php:194
+#: controllers/previews_controller.php:195
+msgid "devcp_preview_edit_pagetitle"
+msgstr "ویرایش پیش‌نمایش"
+
+#: controllers/previews_controller.php:237
+msgid "devcp_preview_updated_successfully"
+msgstr "پیش‌نمایش با موÙقیت به‌هنگام شد."
+
+#: views/developers/previews.thtml:120
+msgid "devcp_previews_a_another"
+msgstr "اÙزودن پیش‌نمایشی دیگر"
+
+#: views/developers/previews.thtml:96
+msgid "devcp_previews_a_delete"
+msgstr "حذ٠پیش‌نمایش"
+
+#: views/developers/previews.thtml:95
+msgid "devcp_previews_a_replace"
+msgstr "جایگزین نمودن پیش‌نمایش"
+
+#: views/developers/previews.thtml:126
+msgid "devcp_previews_a_update"
+msgstr "به‌هنگام‌سازی پیش‌نمایش‌ها"
+
+#: views/developers/previews.thtml:115
+#: views/developers/previews.thtml:124
+msgid "devcp_previews_add_new"
+msgstr "اÙزودن پیش‌نمایش جدید"
+
+#. %s is a list of file extensions, e.g. ".png, .gif"
+#: views/developers/previews.thtml:116
+#, fuzzy
+msgid "devcp_previews_add_select"
+msgstr "Select an image to upload below. Images larger than the maximum size of 700 pixels wide by 525 pixels tall will be resized. Allowed file types: %s"
+
+#: views/developers/previews.thtml:121
+msgid "devcp_previews_click_below"
+msgstr "برای بارگذاری بر روی دکمهٔ به‌هنگام‌سازی پیش‌نمایش‌ها در پایین کلیک کنید."
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/previews.thtml:102
+#, fuzzy
+msgid "devcp_previews_click_update"
+msgstr "Click the Update Previews button below to save this image. (<a %s>Cancel?</a>)"
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/previews.thtml:107
+#, fuzzy
+msgid "devcp_previews_error_message"
+msgstr "This preview will be deleted when Update Previews is clicked below. (<a %s>Cancel?</a>)"
+
+#: views/previews/add.thtml:45
+msgid "devcp_previews_filetype_info"
+msgstr "از Ùرم زیر برای بارگذاری یک تصویر از اÙزودنی‌تان با قالب PNGØŒ JPG یا GIF استÙاده کنید. تصاویر بزرگتر از Û·Û°Û° نقطه در ÛµÛ²Ûµ نقطه به صورت خودکار Ú©ÙˆÚ†Ú© می‌شوند."
+
+#: views/previews/add.thtml:43
+msgid "devcp_previews_header_add"
+msgstr "اÙزودن پیش‌نمایش"
+
+#: views/developers/previews.thtml:80
+msgid "devcp_previews_header_caption"
+msgstr "عنوان پیش‌نمایش"
+
+#: views/previews/edit.thtml:43
+msgid "devcp_previews_header_edit"
+msgstr "ویرایش پیش‌نمایش"
+
+#: views/developers/previews.thtml:93
+msgid "devcp_previews_label_default"
+msgstr "پیش‌نمایش پیش‌Ùرض"
+
+#: views/previews/add.thtml:54
+msgid "devcp_previews_label_file"
+msgstr "پروندهٔ پیش‌نمایش"
+
+#: views/previews/add.thtml:59
+#: views/previews/edit.thtml:50
+msgid "devcp_previews_label_makedefault"
+msgstr "این تصویر را به عنوان پیش‌نمایش پیش‌Ùرض قرار بده"
+
+#: views/developers/previews.thtml:100
+msgid "devcp_previews_label_new"
+msgstr "تصویر جدید:"
+
+#: views/developers/previews.thtml:118
+msgid "devcp_previews_label_upload"
+msgstr "ارسال پیش‌نمایش: "
+
+#: views/developers/previews.thtml:50
+msgid "devcp_previews_notice_error"
+msgstr "قادر به ذخیرهٔ یک یا چند عدد از پیش‌نمایش‌ها نبود."
+
+#: views/developers/previews.thtml:47
+msgid "devcp_previews_notice_success"
+msgstr "پیش‌نمایش‌های شما با موÙقیت به‌هنگام شدند."
+
+#: views/developers/previews.thtml:59
+msgid "devcp_previews_p_screenshots"
+msgstr "تصاویر پیش‌نمایش اÙزودنی شما در زیر نمایش داده شده‌اند. در اینجا می‌توانید تصاویر یا عناوین آنها را تغییر دهید. پیش‌نمایش پیش‌Ùرض پیش‌نمایشی است Ú©Ù‡ در Ùهرست‌های مرور Ùˆ جستجو کنار اÙزودنی‌تان نشان داده می‌شود."
+
+#: views/previews/edit.thtml:55
+msgid "devcp_previews_submit_delete"
+msgstr "حذ٠پیش‌نمایش"
+
+#: views/previews/edit.thtml:55
+msgid "devcp_previews_submit_delete_confirm"
+msgstr "آیا از حذ٠این پیش‌نمایش اطمینان دارید؟"
+
+#: views/previews/edit.thtml:54
+msgid "devcp_previews_submit_edit"
+msgstr "ویرایش پیش‌نمایش"
+
+#: views/previews/add.thtml:63
+msgid "devcp_previews_submit_upload"
+msgstr "بارگذاری پیش‌نمایش"
+
+#: views/developers/previews.thtml:78
+msgid "devcp_previews_thumbnail"
+msgstr "تصویر کوچک"
+
+#. %s is the add-on name.
+#: views/developers/previews.thtml:44
+msgid "devcp_previews_title"
+msgstr "مدیر پیش‌نمایش‌های %s"
+
+#: views/developers/uploader.thtml:74
+msgid "devcp_review_agreement_please"
+msgstr "لطÙاً تواÙق‌نامهٔ توسعه‌دهندهٔ زیر را بررسی کنید Ùˆ پیش از پیشروی با آن مواÙقت نمایید."
+
+#: views/elements/developers/rolecheck.thtml:42
+msgid "devcp_rolecheck_no_privs"
+msgstr "<span>شما برای تغییر این صÙحه مجوز کاÙÛŒ ندارید.</span><br />در صورتی Ú©Ù‡ نیاز به تغییر این قسمت‌ها دارید با مالک اÙزودنی تماس بگیرید."
+
+#: controllers/developers_controller.php:1315
+msgid "devcp_several_hours"
+msgstr "لطÙاً توجه نمایید Ú©Ù‡ اعمال برخی تغییرات در تمام بخش‌های وب‌گاه ممکن است چند ساعت به طول انجامد."
+
+#: views/elements/developers/sidebar.thtml:52
+msgid "devcp_sidebar_a_dashboard"
+msgstr "صÙحهٔ آمار"
+
+#. %s is a number
+#: views/elements/developers/statsbar.thtml:45
+#: views/developers/dashboard.thtml:79
+#, php-format
+msgid "devcp_statsbar_adu"
+msgstr "<em>%s</em> کاربر روزانهٔ Ùعال"
+
+#. %s is a number
+#: views/elements/developers/statsbar.thtml:41
+#: views/developers/dashboard.thtml:75
+#, php-format
+msgid "devcp_statsbar_total_downloads"
+msgstr "<em>%s</em> بارگیری در کل"
+
+#. %s is a number
+#: views/elements/developers/statsbar.thtml:43
+#: views/developers/dashboard.thtml:77
+#, php-format
+msgid "devcp_statsbar_weekly_downloads"
+msgstr "<em>%s</em> بارگیری در این Ù‡Ùته"
+
+#: views/developers/addon_status_confirm.thtml:59
+msgid "devcp_status_confirm_active"
+msgstr "Ùعال کردن این اÙزودنی باعث می‌شود Ú©Ù‡ بر حسب وضعیت در قسمت‌های عمومی وب‌گاه مانند Ùهرست‌های مرور Ùˆ جستجو ظاهر شود. اÙزودنی از وب‌گاه قابل دریاÙت خواهد بود Ùˆ بر حسب وضعیت آن ممکن است در بررسی‌های به‌هنگام‌سازی کاربران ظاهر شود. شما بسته به نیاز خود می‌توانید به این بخش بازگردید Ùˆ اÙزودنی خود را مجدداً غیرÙعال سازید."
+
+#: views/developers/addon_status_confirm.thtml:59
+msgid "devcp_status_confirm_active_sure"
+msgstr "آیا از Ùعال کردن این اÙزودنی اطیمنان دارید؟"
+
+#: views/developers/addon_status_confirm.thtml:50
+msgid "devcp_status_confirm_header_sure"
+msgstr "آیا مطمئن هستید؟"
+
+#: views/developers/addon_status_confirm.thtml:55
+msgid "devcp_status_confirm_inactive"
+msgstr "غیرÙعال کردن این اÙزودنی باعث می‌شود Ú©Ù‡ در هیچ بخش عمومی وب‌گاه مانند Ùهرست‌ها Ùˆ نتایج جست‌وجوها ظاهر نشود. اÙزودنی از وب‌گاه قابل دریاÙت نخواهد بود Ùˆ در به‌هنگام‌سازی‌ها به کاربران عرضه نخواهد شد. شما بر حسب نیاز می‌توانید به این بخش بازگردید Ùˆ آن را مجدداً Ùعال سازید."
+
+#: views/developers/addon_status_confirm.thtml:55
+msgid "devcp_status_confirm_inactive_sure"
+msgstr "آیا از غیر Ùعال کردن این اÙزودنی اطمینان دارید؟"
+
+#: views/developers/addon_status_confirm.thtml:74
+msgid "devcp_status_confirm_no"
+msgstr "خیر، انصراÙ"
+
+#: views/developers/addon_status_confirm.thtml:67
+msgid "devcp_status_confirm_public"
+msgstr "عمومی کردن این اÙزودنی باعث می‌شود Ú©Ù‡ همه بتوانند آن را دریاÙت کنند Ùˆ به‌هنگام‌سازی‌های آن در دسترس کاربران قرار گیرد."
+
+#: views/developers/addon_status_confirm.thtml:67
+msgid "devcp_status_confirm_public_sure"
+msgstr "آیا از عمومی کردن این اÙزودنی اطیمنان دارید؟"
+
+#: views/developers/addon_status_confirm.thtml:63
+#, fuzzy
+msgid "devcp_status_confirm_sandbox"
+msgstr "Moving this add-on back to the sandbox will require users to log in before downloading and updates will no longer be offered to existing users. Because your add-on is currently public, you will be able to return here at any time to make it public again."
+
+#: views/developers/addon_status_confirm.thtml:63
+msgid "devcp_status_confirm_sandbox_sure"
+msgstr "آیا از انتقال این اÙزودنی به گودال ماسه‌بازی اطمینان دارید؟"
+
+#: views/developers/addon_status_confirm.thtml:73
+msgid "devcp_status_confirm_yes"
+msgstr "بله، اطمینان دارم"
+
+#: views/developers/addon_status_nominate.thtml:46
+msgid "devcp_status_nominate_error_notice"
+msgstr "<spanبرای نامزد کردن این اÙزودنی یک پیام مورد نیاز است.</span><br />لطÙاً اطلاعات درخواست شده را در Ùضای متنی وارد کنید Ùˆ دوباره تلاش نمایید."
+
+#: views/developers/addon_status_nominate.thtml:55
+msgid "devcp_status_nominate_header"
+msgstr "نامزد کردن اÙزودنی"
+
+#: views/developers/dashboard.thtml:85
+msgid "devcp_summary_lastversion"
+msgstr "جدیدترین نسخه:"
+
+#. %s is the add-on name.
+#: views/developers/addon_edit.thtml:43
+#: views/developers/addon_edit_authors.thtml:44
+#: views/developers/versions_delete.thtml:43
+#: views/developers/addon_edit_properties.thtml:44
+#: views/developers/addon_edit_descriptions.thtml:44
+#: views/developers/versions_edit.thtml:44
+#: views/developers/addon_edit_categories.thtml:43
+#: views/developers/versions.thtml:43
+msgid "devcp_title_edit_addon"
+msgstr "ویرایش %s"
+
+#. title attribute for a javascript link that pops up a help dialog.
+#: views/elements/translationbox.thtml:68
+msgid "devcp_transbox_a_title_help"
+msgstr "راهنما (در همین صÙحه)"
+
+#: views/elements/translationbox.thtml:68
+msgid "devcp_transbox_alt_help"
+msgstr "راهنما"
+
+#. %1$s is <span>17</span>, %2$s is 42.
+#: views/elements/translationbox.thtml:101
+msgid "devcp_transbox_chars_used"
+msgstr "نویسه‌های استÙاده شده: %1$s از %2$s"
+
+#: views/elements/translationbox.thtml:132
+msgid "devcp_transbox_delete_sure"
+msgstr "آیا از حذ٠این ترجمه اطمینان دارید؟"
+
+#. %s is a locale, like en-US.
+#: views/elements/translationbox.thtml:143
+msgid "devcp_transbox_help_header_tabs"
+msgstr "زبانه‌های %s چیستند؟"
+
+#: views/elements/translationbox.thtml:145
+msgid "devcp_transbox_help_header_what"
+msgstr "اگر ترجمه‌ای در اختیار نداشته باشم چه باید کرد؟"
+
+#: views/elements/translationbox.thtml:147
+msgid "devcp_transbox_help_hide"
+msgstr "پنهان‌سازی راهنما"
+
+#: views/elements/translationbox.thtml:146
+#, fuzzy
+msgid "devcp_transbox_help_if"
+msgstr "If a user browses the site and a translation isn't available in their own language, it will fall back to your add-on's Default Locale, specified in the Edit Add-on Properties area. If you don't have any translations, just enter what you can into your Default Locale, which should be a language you speak."
+
+#: views/elements/translationbox.thtml:144
+#, fuzzy
+msgid "devcp_transbox_help_transbox"
+msgstr "This is a <i>Translation Box</i>. It allows you to localize a specific field into any other languages for which you might have a translation. You can add, edit, and remove translations using the locale tabs."
+
+#: views/elements/translationbox.thtml:85
+msgid "devcp_transbox_img_add_trans"
+msgstr "اÙزودن ترجمه"
+
+#: views/elements/translationbox.thtml:86
+msgid "devcp_transbox_img_remove_trans"
+msgstr "حذ٠ترجمه"
+
+#: views/elements/translationbox.thtml:123
+msgid "devcp_transbox_input_add_all"
+msgstr "اÙزودن زبان به همه"
+
+#: views/elements/translationbox.thtml:122
+msgid "devcp_transbox_input_add_locale"
+msgstr "اÙزودن زبان"
+
+#: views/elements/translationbox.thtml:124
+#: views/elements/translationbox.thtml:135
+msgid "devcp_transbox_input_cancel"
+msgstr "انصراÙ"
+
+#: views/elements/translationbox.thtml:134
+msgid "devcp_transbox_input_delete"
+msgstr "حذ٠شود"
+
+#: views/elements/translationbox.thtml:113
+msgid "devcp_transbox_select_locale"
+msgstr "زبان ترجمه‌ای Ú©Ù‡ می‌خواهید اضاÙÙ‡ کنید را انتخاب نمایید:"
+
+#. %1$s and %2$s are GUIDs.
+#: controllers/developers_controller.php:343
+msgid "devcp_update_addon_guid_error"
+msgstr "شناسهٔ اÙزودنی Ú©Ù‡ در این پرونده استÙاده شده است (%1$s) به شناسهٔ موجود این اÙزودنی (%2$s) مطابقت ندارد."
+
+#: controllers/developers_controller.php:334
+msgid "devcp_update_addon_priv_error"
+msgstr "شما مجوز لازم را برای حذ٠به‌هنگام‌سازی این اÙزودنی ندارید."
+
+#. %1$s is a version number, %2$s is an add-on ID.
+#: controllers/developers_controller.php:399
+msgid "devcp_update_addon_version_belong_error"
+msgstr "نسخهٔ مشخص شده (%1$s) مربوط به این اÙزودنی (%2$s) نیست."
+
+#. %1$s is a version number, maybe 1.1.
+#. %2$s is a URL.
+#: controllers/developers_controller.php:351
+#, fuzzy
+msgid "devcp_update_addon_version_exists_error"
+msgstr "The version number uploaded (%1$s) already exists for this add-on. If you are trying to add another file to this version, <a href=\"%2$s\">click here</a>."
+
+#. %1$s and %2$s are version numbers.
+#: controllers/developers_controller.php:405
+msgid "devcp_update_addon_version_match_error"
+msgstr "نسخهٔ ارسال شده (%1$s) با نسخهٔ موجود (%2$s) یکسان نیست."
+
+#: views/developers/uploader.thtml:68
+msgid "devcp_uploader_a_start"
+msgstr "چگونه شروع کنیم"
+
+#: views/developers/uploader.thtml:137
+msgid "devcp_uploader_ajax_loading"
+msgstr "در حال بارگذاری پرونده…"
+
+#: views/developers/uploader.thtml:82
+#, fuzzy
+msgid "devcp_uploader_button_agree"
+msgstr "Agree and continue"
+
+#: views/developers/uploader.thtml:157
+msgid "devcp_uploader_button_edit"
+msgstr "ویرایش اÙزودنی من"
+
+#: views/developers/uploader.thtml:158
+msgid "devcp_uploader_button_later"
+msgstr "بعداً اÙزودنی‌ام را تکمیل خواهم نمود."
+
+#: views/developers/uploader.thtml:168
+msgid "devcp_uploader_button_release"
+msgstr "اÙزودن یادداشت‌های انتشار"
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/uploader.thtml:156
+#, fuzzy
+msgid "devcp_uploader_created_results"
+msgstr "<p>Your add-on listing has been successfully created. The basic information obtained from your uploaded file has been stored, but there's a lot more to your listing that can be customized.</p><p>Your add-on is currently marked as <strong>Incomplete</strong>. In order to complete your add-on, you'll need to make sure it has an accurate name, summary, and description, as well as at least one selected category. You can edit your add-on's information using the link below and check the status of your add-on at any time on the <a %s>status page</a>."
+
+#: views/developers/uploader.thtml:143
+msgid "devcp_uploader_error_correct"
+msgstr "لطÙاً این مشکل را رÙع کنید Ùˆ پروندهٔ خود را مجدداً ارسال نمایید."
+
+#. %1$s is a version number, %2$s is a status, e.g Public or Incomplete.
+#: views/developers/uploader.thtml:175
+msgid "devcp_uploader_file_created"
+msgstr "پروندهٔ جدیدتان به نسخهٔ %1$s اÙزوده شده است Ùˆ هم‌اکنون %2$s است."
+
+#: views/developers/uploader.thtml:154
+msgid "devcp_uploader_header_created"
+msgstr "اÙزودنی ایجاد گردید!"
+
+#: views/developers/uploader.thtml:141
+msgid "devcp_uploader_header_error"
+msgstr "به نظر می‌رسد این پرونده مشکلی دارد…"
+
+#: views/developers/uploader.thtml:173
+msgid "devcp_uploader_header_file_added"
+msgstr "پرونده اÙزوده گردید!"
+
+#: views/developers/uploader.thtml:66
+msgid "devcp_uploader_header_how"
+msgstr "این قسمت چگونه کار می‌کند؟"
+
+#. %s is the version number, e.g. 3.2.
+#: views/developers/uploader.thtml:163
+msgid "devcp_uploader_header_update_created"
+msgstr "نسخهٔ %s ایجاد گردید"
+
+#: views/developers/uploader.thtml:117
+msgid "devcp_uploader_header_upload"
+msgstr "بارگذاری پرونده‌تان"
+
+#: views/developers/uploader.thtml:67
+#, fuzzy
+msgid "devcp_uploader_how"
+msgstr "<p>Thanks for your interest in submitting your add-on to Mozilla Add-ons. Hosting your add-on on Mozilla Add-ons is the easiest way to handle distribution of your add-on. Here's what you'll get:</p><ul><li>Each add-on will have a public display page with information you provide, such as a brief summary of the add-on's functionality, an optional longer description, and a showcase of preview screenshots of your add-on.</li><li>Your add-on will appear in search and browse listings across the site, and even in the Add-ons Manager of Firefox 3.</li><li>We'll take care of hosting all of your downloads and providing automatic updates to users when you upload a new version.</li><li>You'll have access to a statistics dashboard with detailed information about your user base.</li></ul><p>Add-ons hosted on the site must be reviewed by a Mozilla Add-ons Editor before they will have all of the features listed above. If you're ready to start the process and have your add-on package ready for upload, just click on Get Started below!</p>"
+
+#: views/developers/uploader.thtml:125
+msgid "devcp_uploader_label_platformtype"
+msgstr "سکوهای نرم‌اÙزاری پشتیبانی شده:"
+
+#: views/developers/uploader.thtml:124
+msgid "devcp_uploader_label_upload_field"
+msgstr "پروندهٔ اÙزودنی: "
+
+#: controllers/components/developers.php:1221
+msgid "devcp_uploader_option_other"
+msgstr "دیگر"
+
+#. %1$s is a number, %2$s is href="..." and should stay in the <a> tag.
+#: views/developers/uploader.thtml:176
+#, fuzzy
+msgid "devcp_uploader_p_pending_file"
+msgstr "The new file will be available to the public as soon as an editor is able to review it. There are currently %1$s other add-ons in the queue. Want to be reviewed faster? Consider <a %2$s>becoming an editor</a>."
+
+#. %1$s is a number, %2$s is href="..." and should stay in the <a> tag.
+#: views/developers/uploader.thtml:166
+#, fuzzy
+msgid "devcp_uploader_p_pending_version"
+msgstr "The new version will be available to the public as soon as an editor is able to review it. There are currently %1$s other add-ons in the queue. Want to be reviewed faster? Consider <a %2$s>becoming an editor</a>."
+
+#. %s is a status, e.g Public or Incomplete.
+#: views/developers/uploader.thtml:165
+msgid "devcp_uploader_p_update_created"
+msgstr "نسخهٔ جدید شما ایجاد گردید و در حال حاضر %s است."
+
+#. %1$s is href="..." and should stay in the 'Versions and Files' <a> tag.
+#. %2$s is href="..." and should stay in the 'current status' <a> tag.
+#: views/developers/uploader.thtml:177
+#, fuzzy
+msgid "devcp_uploader_p_update_file"
+msgstr "View your new file in the <a %1$s>Versions and Files page</a>, check out your add-on's <a %2$s>current status</a>, or <b>add release notes</b> by clicking the button below (highly recommended)."
+
+#. %1$s is href="..." and should stay in the 'Versions and Files' <a> tag.
+#. %2$s is href="..." and should stay in the 'current status' <a> tag.
+#: views/developers/uploader.thtml:167
+#, fuzzy
+msgid "devcp_uploader_p_update_version"
+msgstr "View your new version in the <a %1$s>Versions and Files page</a>, check out your add-on's <a %2$s>current status</a>, or <b>add release notes</b> by clicking the button below (highly recommended)."
+
+#: views/developers/uploader.thtml:118
+#, fuzzy
+msgid "devcp_uploader_p_upload"
+msgstr "Upload your add-on file using the form below. If you have multiple, platform-specific files to upload, choose a single file and then upload the others using the Versions and Files Manager."
+
+#: views/developers/uploader.thtml:125
+msgid "devcp_uploader_platformtype_all"
+msgstr "همه"
+
+#: views/developers/uploader.thtml:126
+msgid "devcp_uploader_platformtype_specific"
+msgstr "خاص:"
+
+#. Used as first item in a <select>.
+#: controllers/components/developers.php:1185
+msgid "devcp_uploader_please_choose"
+msgstr "لطÙاً انتخاب نمایید..."
+
+#. %1$s is the add-on name, %2$s is the version number.
+#: views/developers/uploader.thtml:57
+msgid "devcp_uploader_title_file"
+msgstr "اÙزودن پرونده به %1$s %2$s"
+
+#: views/developers/uploader.thtml:50
+msgid "devcp_uploader_title_submit"
+msgstr "ارسال اÙزودنی جدید"
+
+#. %s is the add-on name.
+#: views/developers/uploader.thtml:54
+msgid "devcp_uploader_title_update"
+msgstr "به‌هنگام‌سازی %s"
+
+#. %s is a full <a> tag
+#: controllers/developers_controller.php:503
+#, php-format
+msgid "devcp_valid_app_reference"
+msgstr "لطÙاً %s را به عنوان مرجع ملاحظه نمایید."
+
+#. This is the text in the <a> tag for devcp_valid_app_reference. This should be
+#. fixed.
+#: controllers/developers_controller.php:503
+msgid "devcp_valid_app_reference_linktext"
+msgstr "این صÙحه"
+
+#: controllers/developers_controller.php:581
+msgid "devcp_verify_author_error"
+msgstr "حساب کاربری برای این نشانی پست الکترونیکی وجود ندارد."
+
+#: controllers/developers_controller.php:553
+#, fuzzy
+msgid "devcp_verify_search_engine_error"
+msgstr "Either the XML is invalid or required fields are missing. Please <a href=\"https://developer.mozilla.org/en/Creating_OpenSearch_plugins_for_Firefox\">read the documentation</a>, verify your add-on, and try again."
+
+#: views/developers/versions.thtml:75
+msgid "devcp_versions_a_cancel"
+msgstr "انصراÙ"
+
+#: views/developers/versions.thtml:79
+msgid "devcp_versions_a_delete"
+msgstr "حذ٠نسخه"
+
+#: views/developers/versions.thtml:74
+msgid "devcp_versions_a_empty"
+msgstr "حذ٠نسخهٔ خالی"
+
+#: views/developers/versions.thtml:71
+msgid "devcp_versions_a_remove"
+msgstr "حذ٠شود؟"
+
+#: views/developers/versions.thtml:91
+msgid "devcp_versions_add"
+msgstr "اÙزودن نسخهٔ جدید"
+
+#: views/developers/versions_delete.thtml:58
+msgid "devcp_versions_delete_a_cancel"
+msgstr "انصراÙ"
+
+#: views/developers/versions_delete.thtml:56
+msgid "devcp_versions_delete_a_delete"
+msgstr "حذ٠نسخه"
+
+#. Followed by a list of reviews and files that will be removed.
+#: views/developers/versions_delete.thtml:50
+msgid "devcp_versions_delete_also"
+msgstr "این عمل موارد زیر را نیز حذ٠می‌کند:"
+
+#: views/developers/versions_delete.thtml:53
+msgid "devcp_versions_delete_files"
+msgid_plural "devcp_versions_delete_files"
+msgstr[0] "%s پرونده"
+msgstr[1] "%s پرونده"
+
+#. %s is the version number.
+#: views/developers/versions_delete.thtml:48
+msgid "devcp_versions_delete_header"
+msgstr "حذ٠نسخهٔ %s؟"
+
+#: views/developers/versions_delete.thtml:52
+msgid "devcp_versions_delete_reviews"
+msgid_plural "devcp_versions_delete_reviews"
+msgstr[0] "%s بررسی"
+msgstr[1] "%s بررسی"
+
+#. %s is the version number.
+#: views/developers/versions_delete.thtml:49
+msgid "devcp_versions_delete_sure"
+msgstr "آیا از حذ٠نسخهٔ %s برای همیشه اطمینان دارید؟"
+
+#: views/developers/versions_edit.thtml:102
+#: views/developers/versions_edit.thtml:155
+msgid "devcp_versions_edit_a_cancel"
+msgstr "انصراÙ"
+
+#: views/developers/versions_edit.thtml:101
+msgid "devcp_versions_edit_a_delete"
+msgstr "حذ٠پرونده"
+
+#: views/developers/versions_edit.thtml:165
+msgid "devcp_versions_edit_a_new_app"
+msgstr "اÙزودن برنامهٔ جدید"
+
+#: views/developers/versions_edit.thtml:154
+msgid "devcp_versions_edit_a_remove_app"
+msgstr "حذ٠برنامه"
+
+#: views/developers/versions_edit.thtml:114
+msgid "devcp_versions_edit_add"
+msgstr "اÙزودن پروندهٔ جدید"
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/versions_edit.thtml:121
+#, fuzzy
+msgid "devcp_versions_edit_adjust"
+msgstr "Adjusting application information here will allow users to install your add-on even if the install.rdf in the package indicates that the add-on is incompatible. <a %s>List of supported applications</a>"
+
+#: views/developers/versions_edit.thtml:153
+msgid "devcp_versions_edit_compat_sure"
+msgstr "آیا از حذ٠سازگاری با این برنامه <b>اطمینان دارید</b>؟"
+
+#: views/developers/versions_edit.thtml:100
+msgid "devcp_versions_edit_delete_sure"
+msgstr "آیا از حذ٠این پرونده برای همیشه <b>اطمینان دارید</b>؟"
+
+#: views/developers/versions_edit.thtml:203
+msgid "devcp_versions_edit_header_approval"
+msgstr "اطلاعات تأیید"
+
+#: views/developers/versions_edit.thtml:120
+msgid "devcp_versions_edit_header_compat"
+msgstr "برنامه‌های سازگار"
+
+#: views/developers/versions_edit.thtml:74
+msgid "devcp_versions_edit_header_file"
+msgstr "اطلاعات پرونده"
+
+#: views/developers/versions_edit.thtml:189
+msgid "devcp_versions_edit_header_license"
+msgstr "مجوز"
+
+#. %s is the version number.
+#: views/developers/versions_edit.thtml:53
+msgid "devcp_versions_edit_header_manage"
+msgstr "مدیریت نسخهٔ %s"
+
+#: views/developers/versions_edit.thtml:212
+msgid "devcp_versions_edit_header_notes"
+msgstr "یادداشت‌های تأیید"
+
+#: views/developers/versions_edit.thtml:98
+msgid "devcp_versions_edit_img_delete"
+msgstr "حذ٠پرونده"
+
+#. %1$s is the file id, e.g. 18723.
+#. %2$s is the platform name, e.g. ALL or Windows.
+#. %3$s is the _('date) created.
+#. %4$s is the status, e.g. "In Sandbox" or "Public".
+#. %5$s is the _('date') status was changed.
+#: views/developers/versions_edit.thtml:208
+msgid "devcp_versions_edit_li_file"
+msgstr "پروندهٔ %1$s (%2$s) در تاریخ %3$s ایجاد شده Ùˆ وضعیت آن در تاریخ %5$s به %4$s تغییر یاÙته است"
+
+#: views/developers/versions_edit.thtml:190
+msgid "devcp_versions_edit_license_description"
+msgstr "لطÙاً مجوز مناسب را برای اÙزودنی خود انتخاب کنید. این مجوز حقوقی Ú©Ù‡ در قبال کد منبع به دیگران عرضه می‌کنید را مشخص می‌کند."
+
+#: views/developers/versions_edit.thtml:111
+msgid "devcp_versions_edit_no_files"
+msgstr "هیچ پرونده‌ای پیدا نشد."
+
+#: views/developers/versions_edit.thtml:213
+msgid "devcp_versions_edit_optional"
+msgstr "اطلاعات اختیاری برای ویرایش‌گری که این نسخه را بررسی می‌کند."
+
+#: views/developers/versions_edit.thtml:151
+msgid "devcp_versions_edit_remove_compat"
+msgstr "حذ٠سازگاری با برنامه‌ها"
+
+#: views/developers/versions_edit.thtml:167
+msgid "devcp_versions_edit_select_app"
+msgstr "لطÙاً یک برنامه انتخاب نمایید"
+
+#: views/developers/versions_edit.thtml:78
+msgid "devcp_versions_edit_th_file"
+msgstr "پرونده"
+
+#: views/developers/versions_edit.thtml:79
+msgid "devcp_versions_edit_th_platform"
+msgstr "بستر نرم‌اÙزاری"
+
+#: views/developers/versions_edit.thtml:80
+msgid "devcp_versions_edit_th_size"
+msgstr "اندازه"
+
+#: views/developers/versions_edit.thtml:81
+msgid "devcp_versions_edit_th_status"
+msgstr "وضعیت"
+
+#: views/developers/versions_edit.thtml:183
+#, fuzzy
+msgid "devcp_versions_edit_transbox_releasenotes_description"
+msgstr "Information about changes in this release, new features, known bugs, and other useful information specific to this release/version. This information will also be available to users updating the add-on in the Firefox 3 Add-ons Manager interface."
+
+#: views/developers/versions_edit.thtml:182
+msgid "devcp_versions_edit_transbox_releasenotes_name"
+msgstr "یادداشت‌های انتشار"
+
+#: views/developers/versions_edit.thtml:164
+#, fuzzy
+msgid "devcp_versions_edit_unsaved_compat"
+msgstr "<strong>You have unsaved changes.</strong> Compatibility will not be deleted until you click Update Version below."
+
+#: views/developers/versions_edit.thtml:113
+#, fuzzy
+msgid "devcp_versions_edit_unsaved_files"
+msgstr "<strong>You have unsaved changes.</strong> Files will not be deleted until you click Update Version below."
+
+#: views/developers/versions_edit.thtml:218
+msgid "devcp_versions_edit_update"
+msgstr "به‌هنگام‌سازی نسخه‌ها"
+
+#: views/developers/versions.thtml:49
+msgid "devcp_versions_header_manage"
+msgstr "مدیریت نسخه‌ها و پرونده‌ها"
+
+#: views/developers/versions.thtml:87
+msgid "devcp_versions_no_versions"
+msgstr "نسخه‌ای پیدا نشد."
+
+#. %s is a version number, base 10.
+#: views/developers/versions.thtml:46
+msgid "devcp_versions_notice_success"
+msgstr "نسخهٔ %s با موÙقیت حذ٠گردید."
+
+#: views/developers/versions.thtml:73
+#, fuzzy
+msgid "devcp_versions_p_remove"
+msgstr "This version has no files associated with it and can be removed. Would you like to remove this version?"
+
+#: views/developers/versions.thtml:58
+msgid "devcp_versions_th_created"
+msgstr "ایجاد شده در تاریخ"
+
+#: views/developers/versions.thtml:57
+msgid "devcp_versions_th_status"
+msgstr "وضعیت"
+
+#: views/developers/versions.thtml:56
+msgid "devcp_versions_th_version"
+msgstr "نسخه"
+
+#: controllers/downloads_controller.php:91
+msgid "downloads_disable_warning"
+msgstr "این اÙزودنی غیر Ùعال است"
+
+#: controllers/components/editors.php:57
+msgid "editor_review_error_addon_not_nominated"
+msgstr "این اÙزودنی نامزد نشده است."
+
+#: controllers/components/editors.php:213
+msgid "editor_review_error_file_not_pending"
+msgstr "این پرونده در انتظار بررسی نیست."
+
+#. Actions are, for example: approving or rejecting
+#: controllers/components/editors.php:79
+#: controllers/components/editors.php:182
+msgid "editor_review_error_no_action"
+msgstr "لطÙاً یک عمل بررسی را انتخاب کنید."
+
+#: controllers/components/editors.php:192
+msgid "editor_review_error_no_applications"
+msgstr "لطÙاً برنامه‌هایی Ú©Ù‡ آزمایش نمودید را مشخص نمایید."
+
+#. Comments are required when an editor approves or rejects an add-on.
+#: controllers/components/editors.php:84
+#: controllers/components/editors.php:187
+msgid "editor_review_error_no_comments"
+msgstr "لطÙاً نظرات خود را دربارهٔ این بررسی وارد کنید."
+
+#: controllers/components/editors.php:161
+msgid "editor_review_error_no_files"
+msgstr "لطÙاً کمینه یک پرونده را برای بررسی انتخاب نمایید."
+
+#: controllers/components/editors.php:197
+msgid "editor_review_error_no_operating_system"
+msgstr "لطÙاً سیستم‌عامل‌هایی Ú©Ù‡ آزمایش نمودید را مشخص کنید."
+
+#: views/editors/logs.thtml:51
+msgid "editorcp_logs_button_filter"
+msgstr "صاÙÛŒ"
+
+#: views/editors/logs.thtml:44
+msgid "editorcp_logs_filter_by"
+msgstr "صاÙÛŒ بر حسب نوع/عمل"
+
+#: views/editors/logs.thtml:42
+#: controllers/editors_controller.php:964
+msgid "editorcp_logs_page_heading"
+msgstr "ثبت وقایع رویدادها"
+
+#: views/elements/developers/editorsmenu.thtml:60
+msgid "editorcp_menu_eventlog_link"
+msgstr "ثبت وقایع رویدادها"
+
+#: views/elements/developers/editorsmenu.thtml:62
+msgid "editorcp_menu_mainpage_link"
+msgstr "این صÙحه"
+
+#: views/elements/developers/editorsmenu.thtml:61
+msgid "editorcp_menu_reviewlog_link"
+msgstr "ثبت وقایع بررسی‌ها"
+
+#: views/elements/developers/editorsmenu.thtml:55
+msgid "editorcp_menu_summary_link"
+msgstr "خلاصهٔ ویرایش‌گر"
+
+#: views/elements/developers/editorsmenu.thtml:52
+msgid "editorcp_menu_title"
+msgstr "ابزارهای ویرایش‌گر"
+
+#: views/editors/reviewlog.thtml:49
+msgid "editorcp_reviewlog_button_filter"
+msgstr "صاÙÛŒ"
+
+#: views/editors/reviewlog.thtml:58
+msgid "editorcp_reviewlog_column_action"
+msgstr "عمل"
+
+#: views/editors/reviewlog.thtml:56
+msgid "editorcp_reviewlog_column_addon"
+msgstr "اÙزودنی"
+
+#: views/editors/reviewlog.thtml:55
+msgid "editorcp_reviewlog_column_date"
+msgstr "تاریخ"
+
+#: views/editors/reviewlog.thtml:57
+msgid "editorcp_reviewlog_column_editor"
+msgstr "ویرایش‌گر"
+
+#: views/editors/reviewlog.thtml:94
+msgid "editorcp_reviewlog_comments_hide"
+msgstr "مخÙÛŒ کردن نظرات"
+
+#: views/editors/reviewlog.thtml:93
+msgid "editorcp_reviewlog_comments_show"
+msgstr "نشان دادن نظرات"
+
+#. %1$s and %2$s are full <input> tags for dates
+#: views/editors/reviewlog.thtml:45
+#, php-format
+msgid "editorcp_reviewlog_entries_between"
+msgstr "مشاهدهٔ موارد بین %s و %s"
+
+#: views/editors/reviewlog.thtml:104
+msgid "editorcp_reviewlog_none_found"
+msgstr "هیچ بررسی در این دوره پیدا نشد."
+
+#: views/editors/reviewlog.thtml:42
+msgid "editorcp_reviewlog_page_heading"
+msgstr "ثبت وقایع بررسی‌ها"
+
+#: views/editors/summary.thtml:61
+msgid "editorcp_summary_monthreviews_heading"
+msgstr "بررسی‌های ماه"
+
+#: views/editors/summary.thtml:77
+msgid "editorcp_summary_neweditors_heading"
+msgstr "ویرایش‌گران جدید"
+
+#: views/editors/summary.thtml:42
+msgid "editorcp_summary_page_heading"
+msgstr "خلاصهٔ ویرایش‌گر"
+
+#: views/editors/summary.thtml:94
+msgid "editorcp_summary_recentactivity_heading"
+msgstr "Ùعالیت‌های اخیر ویرایش‌گر"
+
+#: views/editors/summary.thtml:45
+msgid "editorcp_summary_totalreviews_heading"
+msgstr "تعداد کل بررسی‌ها"
+
+#: controllers/editors_controller.php:248
+#: controllers/editors_controller.php:249
+msgid "editors_addon_review_pagetitle"
+msgstr "بررسی اÙزودنی"
+
+#: controllers/editors_controller.php:349
+msgid "editors_error_js-formerror"
+msgstr "لطÙاً Ùیلدهای زیر را تکمیل نمایید:"
+
+#: controllers/editors_controller.php:350
+msgid "editors_error_review_one_file"
+msgstr "لطÙاً کمینه یک پرونده را برای بررسی انتخاب نمایید."
+
+#: controllers/editors_controller.php:274
+msgid "editors_error_self_reviews_forbidden"
+msgstr "بررسی اÙزودنی‌های خود مجاز نیست."
+
+#: controllers/editors_controller.php:699
+msgid "editors_external_software"
+msgstr "نرم‌اÙزار خارجی"
+
+#: views/editors/featured.thtml:120
+#: views/editors/featured.thtml:121
+msgid "editors_featured_add_feature"
+msgstr "اÙزودن ویژگی"
+
+#: views/editors/featured.thtml:126
+msgid "editors_featured_add_feature_submit"
+msgstr "اÙزودن"
+
+#: views/editors/featured.thtml:49
+#: controllers/editors_controller.php:832
+#: controllers/editors_controller.php:848
+msgid "editors_featured_addon_add_failure"
+msgstr "اÙزودن ویژگی شکست خورد."
+
+#: controllers/editors_controller.php:851
+msgid "editors_featured_addon_add_success"
+msgstr "ویژگی با موÙقیت اÙزوده شد."
+
+#: views/editors/featured.thtml:50
+#: controllers/editors_controller.php:839
+#: controllers/editors_controller.php:868
+#: controllers/editors_controller.php:886
+msgid "editors_featured_addon_edit_failure"
+msgstr "ویرایش ویژگی شکست خورد."
+
+#: views/editors/featured.thtml:51
+#: controllers/editors_controller.php:888
+msgid "editors_featured_addon_edit_success"
+msgstr "ویرایش ویژگی با موÙقیت انجام شد."
+
+#: views/editors/featured.thtml:53
+#: controllers/editors_controller.php:861
+msgid "editors_featured_addon_invalid_locale"
+msgstr "یک یا چند منطقه نامعتبر است."
+
+#: views/editors/featured.thtml:52
+#: controllers/editors_controller.php:906
+msgid "editors_featured_addon_remove_failure"
+msgstr "حذ٠ویژگی شکست خورد."
+
+#: controllers/editors_controller.php:901
+msgid "editors_featured_addon_remove_success"
+msgstr "حذ٠ویژگی با موÙقیت انجام شد."
+
+#: controllers/editors_controller.php:915
+#: controllers/editors_controller.php:917
+msgid "editors_featured_addons_pagetitle"
+msgstr "اÙزودنی‌های ویژه"
+
+#: views/editors/featured.thtml:54
+#: views/editors/featured.thtml:107
+msgid "editors_featured_edit_feature_submit"
+msgstr "برو"
+
+#: views/editors/featured.thtml:90
+#: views/editors/featured.thtml:91
+msgid "editors_featured_remove_feature"
+msgstr "حذ٠ویژگی"
+
+#: views/editors/queue.thtml:46
+msgid "editors_filter_queue"
+msgstr "ص٠صاÙÛŒ"
+
+#: views/editors/queue.thtml:182
+msgid "editors_helpful_links"
+msgstr "پیوندهای Ù…Ùید"
+
+#: views/editors/queue.thtml:182
+msgid "editors_link_guide"
+msgstr "راهنمای ویرایش‌گر"
+
+#: views/editors/queue.thtml:182
+msgid "editors_link_policy"
+msgstr "سیاست اÙزودنی"
+
+#: views/editors/queue.thtml:47
+msgid "editors_notice_filter_session"
+msgstr "این صاÙی‌ها برای این نشست تا زمانی Ú©Ù‡ پاک شوند باقی خواهند ماند."
+
+#. %1 is the queue mode
+#: views/editors/queue.thtml:177
+#: views/admin/flagged_queue.thtml:89
+msgid "editors_notice_none_found"
+msgstr "در حال حاضر هیچ اÙزودنی از این نوع برای بررسی وجود ندارد."
+
+#: controllers/editors_controller.php:1040
+msgid "editors_one_day"
+msgstr "۱ روز"
+
+#: controllers/editors_controller.php:1048
+msgid "editors_one_hour"
+msgstr "۱ ساعت"
+
+#: controllers/editors_controller.php:1056
+msgid "editors_one_minute"
+msgstr "۱ دقیقه"
+
+#: controllers/editors_controller.php:64
+#: controllers/editors_controller.php:73
+#: controllers/editors_controller.php:77
+msgid "editors_pagetitle"
+msgstr "ابزارهای ویرایش‌گر"
+
+#. %s is a comma separated list of platforms. Example: Windows, OS X
+#: controllers/editors_controller.php:680
+#: controllers/editors_controller.php:683
+#, php-format
+msgid "editors_platform_x_only"
+msgstr "تنها %s"
+
+#: controllers/editors_controller.php:695
+msgid "editors_pre-release"
+msgstr "پیش از انتشار"
+
+#. %1 is the app name
+#: views/editors/queue.thtml:131
+#, php-format
+msgid "editors_queue_app_compatibility"
+msgstr "سازگاری با %s"
+
+#: views/editors/queue.thtml:51
+msgid "editors_queue_filter_label_addon"
+msgstr "نشانی پست الکترونیکی اÙزودنی یا مؤلÙ"
+
+#: views/editors/queue.thtml:72
+msgid "editors_queue_filter_label_addontypes"
+msgstr "انواع اÙزودنی"
+
+#: views/editors/queue.thtml:56
+msgid "editors_queue_filter_label_application"
+msgstr "برنامه"
+
+#: views/editors/queue.thtml:61
+msgid "editors_queue_filter_label_maxversion"
+msgstr "حداکثر نسخه"
+
+#: views/editors/queue.thtml:78
+msgid "editors_queue_filter_label_platforms"
+msgstr "سکوهای نرم‌اÙزاری"
+
+#: views/editors/queue.thtml:66
+msgid "editors_queue_filter_label_submissionage"
+msgstr "مدت زمان ارسال شده (بر حسب روز)"
+
+#. %1$s is a number
+#: views/editors/queue.thtml:90
+msgid "editors_queue_filter_result_count"
+msgid_plural "editors_queue_filter_result_count"
+msgstr[0] "نتایج جستجوی صاÙی‌شدهٔ شما: <strong>%1$s</strong> اÙزودنی"
+msgstr[1] "نتایج جستجوی صاÙی‌شدهٔ شما: <strong>%1$s</strong> اÙزودنی"
+
+#: views/editors/queue.thtml:84
+msgid "editors_queue_submit_clean"
+msgstr "پاک کردن"
+
+#: views/editors/queue.thtml:83
+msgid "editors_queue_submit_filter"
+msgstr "صاÙÛŒ"
+
+#: controllers/editors_controller.php:133
+msgid "editors_queues_disabled"
+msgstr "تمام صÙ‌های بررسی اکنون غیر Ùعال هستند. لطÙاً بعداً دوباره تلاش نمایید."
+
+#: views/editors/review.thtml:149
+msgid "editors_review_a_edit_item"
+msgstr "ویرایش"
+
+#: views/editors/review.thtml:146
+msgid "editors_review_a_item_history"
+msgstr "تاریخچهٔ مورد"
+
+#: views/editors/review.thtml:148
+msgid "editors_review_a_item_homepage"
+msgstr "صÙحهٔ آغازه"
+
+#: views/editors/review.thtml:145
+msgid "editors_review_a_item_overview"
+msgstr "شرح کلی مورد"
+
+#: views/editors/review.thtml:147
+msgid "editors_review_a_previews"
+msgstr "پیش‌نمایش‌ها"
+
+#: controllers/editors_controller.php:345
+msgid "editors_review_action"
+msgstr "عمل بررسی"
+
+#: views/editors/review.thtml:159
+msgid "editors_review_action_info"
+msgstr "درخواست اطلاعات بیشتر"
+
+#: views/editors/review.thtml:157
+msgid "editors_review_action_public"
+msgstr "عمومی کردن"
+
+#: views/editors/review.thtml:160
+msgid "editors_review_action_request_superreview"
+msgstr "درخواست بررسی ارشد"
+
+#: views/editors/review.thtml:158
+msgid "editors_review_action_sandbox"
+msgstr "نگه داشتن در گودال ماسه‌بازی"
+
+#: controllers/editors_controller.php:346
+msgid "editors_review_comments"
+msgstr "توضیحات بررسی"
+
+#: views/editors/review.thtml:182
+msgid "editors_review_details_info_request"
+msgstr "از این Ùرم برای درخواست اطلاعات بیشتر از مؤل٠استÙاده کنید. مؤلÙان نامه‌ای الکترونیکی دریاÙت خواهند کرد Ùˆ قادر خواهند بود در اینجا پاسخ دهند. هنگامی Ú©Ù‡ مؤلÙان پاسخی ارسال نمایند، شما توسط نامه‌ای الکترونیکی مطلع خواهید شد."
+
+#: views/editors/review.thtml:174
+msgid "editors_review_details_nominated_public"
+msgstr "این گزینه، اÙزودنی Ùˆ آخرین نسخهٔ آن را به صورت عمومی در خواهد آورد. نسخه‌های بعدی وارد گودال ماسه‌بازی می‌شوند تا توسط یک ویرایش‌گر بررسی گردند."
+
+#: views/editors/review.thtml:177
+msgid "editors_review_details_nominated_sandbox"
+msgstr "این گزینه اÙزودنی را در گودال ماسه‌بازی Ù†Ú¯Ù‡ خواهد داشت."
+
+#: views/editors/review.thtml:166
+msgid "editors_review_details_pending_public"
+msgstr "این گزینه یک نسخهٔ درون گودال ماسه‌بازی از اÙزودنی را عمومی می‌کند."
+
+#: views/editors/review.thtml:169
+msgid "editors_review_details_pending_sandbox"
+msgstr "این گزینه باعث می‌شود یک نسخهٔ درون گودال ماسه‌یازی از اÙزودنی در گودال ماسه‌بازی باقی بماند."
+
+#: views/editors/review.thtml:185
+msgid "editors_review_details_superreview"
+msgstr "اگر دربارهٔ امنیت این اÙزودنی، مسائل مربوط به حق msgid"
+
+#: views/editors/review.thtml:134
+msgid "editors_review_file_diff_link"
+msgstr "مقایسه با نسخهٔ عمومی"
+
+#: views/editors/review.thtml:131
+msgid "editors_review_file_viewcontents_link"
+msgstr "مشاهدهٔ محتویات"
+
+#: views/editors/review.thtml:65
+msgid "editors_review_header_authors"
+msgstr "مؤلÙان:"
+
+#: views/editors/review.thtml:79
+msgid "editors_review_header_categories"
+msgstr "دسته‌ها:"
+
+#: views/editors/review.thtml:92
+msgid "editors_review_header_compatibility"
+msgstr "سازگاری:"
+
+#: views/editors/review.thtml:251
+msgid "editors_review_header_description"
+msgstr "شرح"
+
+#: views/editors/review.thtml:275
+msgid "editors_review_header_devcomments"
+msgstr "توضیحات توسعه‌دهنده"
+
+#: views/editors/review.thtml:263
+msgid "editors_review_header_eula"
+msgstr "تواÙق‌نامهٔ مجوز کاربر نهایی"
+
+#: views/editors/review.thtml:115
+msgid "editors_review_header_files"
+msgstr "پرونده‌ها:"
+
+#: views/editors/review.thtml:284
+msgid "editors_review_header_itemhistory"
+msgstr "تاریخچهٔ مورد"
+
+#: views/editors/review.thtml:232
+msgid "editors_review_header_nominationmessage"
+msgstr "پیام نامزد شدن اÙزودنی"
+
+#: views/editors/review.thtml:311
+msgid "editors_review_header_previews"
+msgstr "پیش‌نمایش‌ها"
+
+#: views/editors/review.thtml:269
+msgid "editors_review_header_privacy"
+msgstr "سیاست Ø­Ùظ حریم خصوصی"
+
+#. %1 is the add-on name and version
+#: views/editors/review.thtml:56
+#, php-format
+msgid "editors_review_header_review"
+msgstr "بررسی %s"
+
+#: views/editors/review.thtml:239
+msgid "editors_review_header_reviewernotes"
+msgstr "یادداشت برای بررسی‌کنندگان"
+
+#: views/editors/review.thtml:245
+msgid "editors_review_header_summary"
+msgstr "خلاصه"
+
+#: views/editors/review.thtml:257
+msgid "editors_review_header_versionnotes"
+msgstr "یادداشت‌های نسخه"
+
+#. a noun: shown in an add-on's editor review history
+#: views/elements/developers/editors_review_history_item.thtml:80
+msgid "editors_review_history_info_reply"
+msgstr "پاسخ"
+
+#: views/elements/developers/editors_review_history_item.thtml:78
+msgid "editors_review_history_info_request"
+msgstr "درخواست اطلاعات"
+
+#: views/elements/developers/editors_review_history_item.thtml:62
+#: views/editors/reviewlog.thtml:77
+msgid "editors_review_history_nominated_adminreview"
+msgstr "بررسی مدیر"
+
+#: views/elements/developers/editors_review_history_item.thtml:56
+#: views/editors/reviewlog.thtml:71
+msgid "editors_review_history_nominated_approved"
+msgstr "با نامزدی اÙزودنی مواÙقت شد، اÙزودنی عمومی گردید"
+
+#: views/elements/developers/editors_review_history_item.thtml:59
+#: views/editors/reviewlog.thtml:74
+msgid "editors_review_history_nominated_denied"
+msgstr "با نامزدی اÙزودنی مواÙقت نشد/اÙزودنی در گودال ماسه‌بازی باقی ماند"
+
+#: views/editors/review.thtml:303
+msgid "editors_review_history_nonefound"
+msgstr "هیچ بررسی قبلی پیدا نشد."
+
+#: views/elements/developers/editors_review_history_item.thtml:73
+#: views/editors/reviewlog.thtml:88
+msgid "editors_review_history_pending_adminreview"
+msgstr "بررسی مدیر"
+
+#: views/elements/developers/editors_review_history_item.thtml:67
+#: views/editors/reviewlog.thtml:82
+msgid "editors_review_history_pending_approved"
+msgstr "تأیید شده/عمومی"
+
+#: views/elements/developers/editors_review_history_item.thtml:70
+#: views/editors/reviewlog.thtml:85
+msgid "editors_review_history_pending_denied"
+msgstr "تأیید نشده/گودال ماسه‌بازی"
+
+#. link text in an add-on's editor review history, allowing to hide and show an information request's replies
+#. %1 is the number of replies
+#: views/elements/developers/editors_review_history_item.thtml:90
+msgid "editors_review_history_show_hide_replies"
+msgid_plural "editors_review_history_show_hide_replies"
+msgstr[0] "نمایش/پنهان‌سازی پاسخ"
+msgstr[1] "نمایش/پنهان‌سازی پاسخ‌ها (%1$s)"
+
+#: views/editors/review.thtml:208
+msgid "editors_review_label_applications"
+msgstr "برنامه‌ها:"
+
+#: views/editors/review.thtml:196
+msgid "editors_review_label_cannedresponse"
+msgstr "یا یک پاسخ از پیش آماده انتخاب کنید:"
+
+#: views/editors/review.thtml:190
+msgid "editors_review_label_comments"
+msgstr "نظرها:"
+
+#: views/editors/review.thtml:204
+msgid "editors_review_label_operating_systems"
+msgstr "سیستم‌عامل‌ها:"
+
+#: views/editors/review.thtml:285
+#: views/editors/review.thtml:312
+msgid "editors_review_link_pagetop"
+msgstr "بالای صÙحه"
+
+#: views/editors/review.thtml:141
+msgid "editors_review_mulitple_notice"
+msgstr "توجه: تنها در صورتی بیش از یک پرونده را بررسی نمایید که همهٔ آن پرونده‌ها را جداگانه آزمایش کرده باشید."
+
+#: views/editors/review.thtml:51
+msgid "editors_review_next_link"
+msgstr "بعدی &raquo;"
+
+#: views/editors/review.thtml:322
+msgid "editors_review_previews_notfound"
+msgstr "یادداشت‌های نسخه"
+
+#: views/editors/review.thtml:50
+msgid "editors_review_previous_link"
+msgstr "&laquo; قبلی"
+
+#: controllers/editors_controller.php:144
+#: controllers/editors_controller.php:146
+msgid "editors_review_queue_pagetitle"
+msgstr "ص٠بررسی"
+
+#. %1 is the add-ons rank in the queue, %2 is the total queue length
+#: views/editors/review.thtml:47
+msgid "editors_review_rank_in_queue"
+msgstr "اÙزودنی <strong>%1$s</strong> از %2$s در این صÙ"
+
+#. %1 is the add-ons rank in the queue, %2 is the total queue length. Both numbers
+#: views/editors/review.thtml:45
+msgid "editors_review_rank_in_queue_filtered"
+msgstr "<strong>شمارهٔ %1$s</strong> از %2$s در ص٠(صاÙÛŒ شده)"
+
+#: views/editors/review.thtml:223
+msgid "editors_review_submit_process_action"
+msgstr "پردازش عمل"
+
+#: views/editors/review.thtml:293
+msgid "editors_review_th_action"
+msgstr "عمل"
+
+#: views/editors/review.thtml:294
+msgid "editors_review_th_comments"
+msgstr "نظرها"
+
+#: views/editors/review.thtml:291
+msgid "editors_review_th_date"
+msgstr "نظرها"
+
+#: views/editors/review.thtml:292
+msgid "editors_review_th_reviewer"
+msgstr "بررسی‌کننده"
+
+#: views/editors/review.thtml:290
+msgid "editors_review_th_version_file"
+msgstr "نسخه/پرونده"
+
+#: views/editors/review.thtml:217
+msgid "editors_review_update_notify_once"
+msgstr "دÙعهٔ بعدی Ú©Ù‡ این اÙزودنی به‌هنگام می‌شود به من اطلاع داده شود. (به‌هنگام‌سازی‌های بعدی باعث ارسال مجدد نامهٔ الکترونیکی نخواهند شد)"
+
+#: controllers/editors_controller.php:298
+msgid "editors_reviewed_successfully"
+msgstr "بررسی با موÙقیت پردازش گردید."
+
+#: views/editors/reviews_queue.thtml:106
+msgid "editors_reviews_action_delete_review"
+msgstr "حذ٠بررسی"
+
+#: views/editors/reviews_queue.thtml:104
+msgid "editors_reviews_action_keep"
+msgstr "حذ٠علامت‌گذاری؛ نگه داشتن بررسی"
+
+#: views/editors/reviews_queue.thtml:102
+msgid "editors_reviews_action_skip"
+msgstr "پرش به مورد بعدی"
+
+#: views/editors/reviews_queue.thtml:100
+msgid "editors_reviews_header_action"
+msgstr "عمل"
+
+#: views/editors/reviews_queue.thtml:67
+msgid "editors_reviews_in_reply_to"
+msgstr "در پاسخ به:"
+
+#: controllers/editors_controller.php:748
+msgid "editors_reviews_processed"
+msgstr "بررسی با موÙقیت پردازش گردید!"
+
+#: views/editors/reviews_queue.thtml:117
+msgid "editors_reviews_queue_empty"
+msgstr "در حال حاضر هیچ بررسی در ص٠تعدیل وجود ندارد."
+
+#: views/editors/reviews_queue.thtml:111
+msgid "editors_reviews_submit_process_reviews"
+msgstr "پردازش بررسی‌ها"
+
+#: controllers/editors_controller.php:691
+msgid "editors_site_specific"
+msgstr "مخصوص یک وب‌گاه"
+
+#: controllers/editors_controller.php:348
+msgid "editors_tested_app"
+msgstr "برنامهٔ مورد آزمایش"
+
+#: controllers/editors_controller.php:347
+msgid "editors_tested_os"
+msgstr "سیستم‌عامل‌های مورد آزمایش"
+
+#: views/editors/queue.thtml:151
+msgid "editors_th_additional_info"
+msgstr "اطلاعات اضاÙÛŒ"
+
+#: views/editors/featured.thtml:63
+#: views/editors/queue.thtml:109
+#: views/admin/flagged_queue.thtml:53
+msgid "editors_th_addon"
+msgstr "اÙزودنی"
+
+#: views/editors/queue.thtml:125
+msgid "editors_th_addontype"
+msgstr "حذÙ"
+
+#: views/editors/featured.thtml:64
+msgid "editors_th_locales"
+msgstr "محدود ساختن به منطقه‌ها؟"
+
+#: views/editors/queue.thtml:148
+msgid "editors_th_nomination_age"
+msgstr "مدت زمان باقی ماندن در صÙ"
+
+#: views/editors/queue.thtml:101
+#: views/editors/queue.thtml:117
+#: views/editors/queue.thtml:144
+msgid "editors_th_sort_ascending"
+msgstr "مرتب‌سازی صعودی"
+
+#: views/editors/queue.thtml:105
+#: views/editors/queue.thtml:121
+#: views/editors/queue.thtml:140
+msgid "editors_th_sort_descending"
+msgstr "مرتب‌سازی نزولی"
+
+#. %s is a number
+#: controllers/editors_controller.php:1036
+#, php-format
+msgid "editors_x_days"
+msgstr "%s روز"
+
+#. %s is a number
+#: controllers/editors_controller.php:1044
+#, php-format
+msgid "editors_x_hours"
+msgstr "%s ساعت"
+
+#. %s is a number
+#: controllers/editors_controller.php:1052
+#, php-format
+msgid "editors_x_minutes"
+msgstr "%s دقیقه"
+
+#: views/errors/error401.thtml:50
+#: controllers/components/simple_acl.php:81
+#: controllers/components/simple_acl.php:82
+#: controllers/components/simple_acl.php:83
+#: controllers/components/amo.php:607
+#: controllers/components/amo.php:608
+#: controllers/components/amo.php:609
+#: controllers/reviews_controller.php:353
+#: controllers/reviews_controller.php:485
+#: controllers/collections_controller.php:438
+#: controllers/collections_controller.php:496
+#: controllers/collections_controller.php:504
+#: controllers/collections_controller.php:971
+#: controllers/collections_controller.php:1034
+#: controllers/collections_controller.php:1077
+msgid "error_access_denied"
+msgstr "دسترسی مجاز نیست"
+
+#: views/errors/error401.thtml:52
+msgid "error_access_denied_message"
+msgstr "شما مجاز به مشاهدهٔ این صÙحه نیستید."
+
+#: controllers/collections_controller.php:1039
+msgid "error_addon_exists"
+msgstr "اÙزودنی از قبل وجود دارد!"
+
+#: controllers/developers_controller.php:200
+#: controllers/developers_controller.php:593
+#: controllers/developers_controller.php:1016
+#: controllers/developers_controller.php:1429
+#: controllers/downloads_controller.php:95
+#: controllers/downloads_controller.php:102
+#: controllers/downloads_controller.php:164
+#: controllers/statistics_controller.php:135
+#: controllers/previews_controller.php:115
+#: controllers/previews_controller.php:206
+#: controllers/previews_controller.php:307
+#: controllers/reviews_controller.php:77
+#: controllers/reviews_controller.php:240
+#: controllers/reviews_controller.php:332
+#: controllers/reviews_controller.php:340
+#: controllers/api_controller.php:123
+#: controllers/api_controller.php:759
+#: controllers/addons_controller.php:131
+#: controllers/addons_controller.php:197
+#: controllers/addons_controller.php:1407
+#: controllers/addons_controller.php:1465
+#: controllers/addons_controller.php:1469
+#: controllers/addons_controller.php:1503
+#: controllers/editors_controller.php:265
+#: controllers/collections_controller.php:1041
+#: controllers/collections_controller.php:1074
+msgid "error_addon_notfound"
+msgstr "اÙزودنی پیدا نشد!"
+
+#: controllers/files_controller.php:83
+#: controllers/files_controller.php:196
+msgid "error_addon_notviewable"
+msgstr "این اÙزودنی قابل مشاهده در اینجا نیست."
+
+#: controllers/reviews_controller.php:246
+msgid "error_addon_selfreview"
+msgstr "بررسی اÙزودنی خودتان ممکن نیست."
+
+#: controllers/addons_controller.php:970
+msgid "error_browse_no_addons"
+msgstr "هیچ اÙزودنی در این دسته وجود ندارد!"
+
+#: controllers/api_controller.php:424
+msgid "error_collection_feed_notfound"
+msgstr "خورد وبی اÙزودنی پیدا نشد"
+
+#: views/users/register.thtml:65
+#: views/users/edit.thtml:194
+msgid "error_email_invalid"
+msgstr "این نشانی پست الکترونیکی معتبر نیست."
+
+#: views/users/pwreset.thtml:74
+#: views/users/register.thtml:70
+#: views/users/register.thtml:80
+#: views/users/register.thtml:86
+#: views/users/edit.thtml:105
+#: views/users/edit.thtml:111
+#: views/users/edit.thtml:192
+#: views/admin/users_edit.thtml:78
+#: views/admin/users_edit.thtml:83
+#: views/reviews/add.thtml:80
+#: views/reviews/add.thtml:104
+msgid "error_field_required"
+msgstr "این Ùیلد نباید خالی باشد."
+
+#: controllers/files_controller.php:75
+#: controllers/files_controller.php:93
+#: controllers/files_controller.php:96
+#: controllers/files_controller.php:163
+#: controllers/files_controller.php:176
+#: controllers/files_controller.php:185
+#: controllers/files_controller.php:204
+#: controllers/editors_controller.php:412
+msgid "error_file_notfound"
+msgstr "پرونده پیدا نشد!"
+
+#. %s is a filename
+#: controllers/editors_controller.php:430
+#, php-format
+msgid "error_file_x_notfound"
+msgstr "خطای پرونده: %s وجود ندارد."
+
+#: views/collections/add.thtml:55
+#: views/collections/edit.thtml:89
+#: views/users/register.thtml:54
+#: views/users/edit.thtml:81
+#: views/reviews/add.thtml:70
+#: controllers/groups_controller.php:80
+#: controllers/groups_controller.php:102
+msgid "error_formerrors"
+msgstr "در این Ùرم خطاهایی وجود دارد. لطÙاً آنها را تصحیح کنید Ùˆ دوباره Ùرم را ارسال نمایید."
+
+#: views/users/register.thtml:109
+msgid "error_invalid_captcha"
+msgstr "کد وارد شده نامعتبر است، لطÙاً دوباره تلاش کنید!"
+
+#: views/users/register.thtml:100
+#: views/users/edit.thtml:125
+#: views/admin/users_edit.thtml:101
+msgid "error_invalid_url"
+msgstr "قالب این نشانی معتبر نیست. نشانی‌های معتبر مشابه htt_p://example.com/mypage هستند."
+
+#. %s is a string representing what's missing. Example: file_id
+#: controllers/downloads_controller.php:65
+#: controllers/users_controller.php:185
+#: controllers/users_controller.php:264
+#: controllers/users_controller.php:559
+#: controllers/users_controller.php:653
+#: controllers/reviews_controller.php:71
+#: controllers/reviews_controller.php:234
+#: controllers/reviews_controller.php:325
+#: controllers/reviews_controller.php:473
+#: controllers/reviews_controller.php:475
+#: controllers/addons_controller.php:182
+#: controllers/addons_controller.php:1381
+#: controllers/addons_controller.php:1455
+#: controllers/collections_controller.php:266
+#: controllers/collections_controller.php:285
+#: controllers/collections_controller.php:346
+#: controllers/collections_controller.php:443
+#: controllers/collections_controller.php:482
+#: controllers/collections_controller.php:936
+#: controllers/collections_controller.php:959
+#: controllers/collections_controller.php:960
+#: controllers/collections_controller.php:975
+#: controllers/collections_controller.php:977
+#: controllers/collections_controller.php:994
+#: controllers/collections_controller.php:1003
+#: controllers/collections_controller.php:1016
+#: controllers/collections_controller.php:1017
+#: controllers/collections_controller.php:1024
+#: controllers/collections_controller.php:1070
+#: controllers/collections_controller.php:1090
+#, php-format
+msgid "error_missing_argument"
+msgstr "آرگومان ناقص: %s"
+
+#: controllers/components/amo.php:507
+#: controllers/components/amo.php:532
+msgid "error_no_files_in_addon"
+msgstr "پرونده‌ای در اÙزودنی وجود ندارد"
+
+#: controllers/previews_controller.php:200
+msgid "error_preview_notfound"
+msgstr "پیش‌نمایش پیدا نشد!"
+
+#: views/addons/display.thtml:400
+#: views/reviews/add.thtml:98
+msgid "error_review_rating_required"
+msgstr "باید یک رتبه انتخاب کنید."
+
+#: controllers/users_controller.php:160
+msgid "error_user_already_confirmed"
+msgstr "این حساب کاربری قبلاً تأیید شده است."
+
+#: controllers/users_controller.php:202
+#: controllers/users_controller.php:276
+#: controllers/users_controller.php:569
+#: controllers/users_controller.php:581
+#: controllers/users_controller.php:587
+#: controllers/users_controller.php:610
+#: controllers/users_controller.php:627
+msgid "error_user_badconfirmationcode"
+msgstr "کد تأیید نامعتبر!"
+
+#: views/users/pwreset.thtml:79
+#: views/users/register.thtml:75
+#: views/users/edit.thtml:183
+msgid "error_user_confirmpw_nomatch"
+msgstr "گذرواژه‌ها یکسان نبودند."
+
+#: views/users/register.thtml:65
+#: views/users/edit.thtml:190
+#: controllers/users_controller.php:617
+msgid "error_user_email_notunique"
+msgstr "این نشانی پست الکترونیکی توسط کاربر دیگری ثبت شده است."
+
+#: controllers/users_controller.php:596
+msgid "error_user_emailchange_expired"
+msgstr "تغییر نشانی پست الکترونیکی منقضی شده است. لطÙاً نشانی پست الکترونیکی خود را در مجموعه تنظیمات کاربری خود دوباره تغییر دهید Ùˆ به محض دریاÙت نامهٔ تأییدیه بر روی پیوند موجود در آن کلیک کنید."
+
+#: controllers/collections_controller.php:985
+msgid "error_user_exists"
+msgstr "کاربران در هر زمان می‌توانند تنها یک نقش داشته باشند. لطÙاً پیش از ادامه این کاربر را از نقش‌های Ùعلی‌اش حذ٠کنید."
+
+#: views/users/register.thtml:91
+#: views/users/edit.thtml:116
+#: views/admin/users_edit.thtml:88
+msgid "error_user_nickname_notunique"
+msgstr "این نام مستعار قبلاً استÙاده شده است."
+
+#: views/users/pwreset.thtml:54
+#: controllers/users_controller.php:191
+#: controllers/users_controller.php:270
+#: controllers/users_controller.php:603
+#: controllers/users_controller.php:659
+#: controllers/collections_controller.php:988
+#: controllers/collections_controller.php:998
+msgid "error_user_notfound"
+msgstr "کاربر پیدا نشد!"
+
+#: views/users/activatefirst.thtml:47
+msgid "error_user_unconfirmed"
+msgstr "لطÙاً ابتدا توسط کدی Ú©Ù‡ در یک نامهٔ الکترونیکی دریاÙت نموده‌اید، حساب کاربری خود را تأیید کنید."
+
+#: views/users/login.thtml:67
+msgid "error_username_or_pw_wrong"
+msgstr "نام کاربری یا گذرواژهٔ اشتباه!"
+
+#: controllers/editors_controller.php:260
+msgid "error_version_notfound"
+msgstr "نسخه پیدا نشد!"
+
+#: views/users/delete.thtml:125
+#: views/users/edit.thtml:173
+msgid "error_wrong_password"
+msgstr "گذرواژهٔ اشتباه وارد شد!"
+
+#: views/elements/amo2009/homepage_addon.thtml:122
+#: views/elements/feature.thtml:122
+msgid "feature_learnmore"
+msgstr "بیشتر بدانید"
+
+#. %1 is the add-on name
+#: views/elements/amo2009/homepage_addon.thtml:123
+#: views/elements/feature.thtml:123
+#, php-format
+msgid "feature_learnmore_about_addon"
+msgstr "دربارهٔ %1$s بیشتر بدانید"
+
+#. %1$s is a number
+#: views/elements/amo2009/reviews.thtml:52
+#: views/elements/addon_listitem.thtml:112
+#: views/elements/feature.thtml:99
+#: views/addons/browse_thumbs.thtml:86
+#, php-format
+msgid "feature_reviews"
+msgid_plural "feature_reviews"
+msgstr[0] "%1$s بررسی"
+msgstr[1] "%1$s بررسی"
+
+#: views/elements/amo2009/homepage_addon.thtml:127
+#: views/elements/feature.thtml:127
+msgid "feature_view_more_from_category"
+msgstr "مشاهدهٔ موارد بیشتری از"
+
+#. This appears on a page that views the source of an add-on. This link will return
+#. the user to the add-on's main page
+#: views/files/browse.thtml:65
+msgid "file_browser_link_addon"
+msgstr "بازگشت به اÙزودنی"
+
+#. There is a list of directories and files on the page. Clicking this will show the
+#. contents of all the directories (normally you would click on each one to see the
+#. contents)
+#: views/files/browse.thtml:67
+msgid "file_browser_link_expand_all"
+msgstr "باز کردن همه"
+
+#. This appears on a page that views the source of an add-on. This link will return
+#. the user to the add-on's review page (it only appears if the add-on is being
+#. reviewed)
+#: views/files/browse.thtml:64
+msgid "file_browser_link_review"
+msgstr "بازگشت به بررسی"
+
+#. The title of the page for viewing an add-on's source.
+#. %1$s is the name of the add-on
+#. %2$s is the name of the current application (e.g. Firefox or Thunderbird)
+#: views/files/browse.thtml:46
+msgid "file_browser_title"
+msgstr "%1$s :: مرورگر پرونده :: اÙزودنی‌های %2$s"
+
+#. This appears on a page that views the source of an add-on. There is a list of
+#. directories and files on the page. Clicking this link will toggle between an
+#. expanded or a collapsed list. This string should be kept short.
+#: views/files/browse.thtml:68
+msgid "file_browser_toggle_expand_collapse"
+msgstr "+/-"
+
+#. Link text for the AMO About page.
+#: views/elements/footer.thtml:72
+#: views/layouts/amo2009.thtml:341
+msgid "footer_a_about"
+msgstr "درباره برنامه"
+
+#. Link text to the AMO blog.
+#: views/elements/footer.thtml:74
+#: views/layouts/amo2009.thtml:343
+msgid "footer_a_blog"
+msgstr "وب‌نوشت"
+
+#. Link text to the Frequently Asked Questions page.
+#: views/elements/footer.thtml:73
+#: views/layouts/amo2009.thtml:342
+msgid "footer_a_faq"
+msgstr "پرسش‌های متداول"
+
+#. Full text for the FAQ abbreviation.
+#: views/elements/footer.thtml:73
+#: views/pages/collector_features.thtml:72
+#: views/layouts/amo2009.thtml:342
+msgid "footer_abbr_faq"
+msgstr "پرسش‌های متداول"
+
+#: views/elements/footer.thtml:67
+#: views/layouts/amo2009.thtml:336
+msgid "footer_all_rights_reserved"
+msgstr "تمامی حقوق محÙوظ است."
+
+#: views/elements/footer.thtml:67
+#: views/layouts/amo2009.thtml:336
+msgid "footer_copyright"
+msgstr "حق رونوشت‌برداری"
+
+#: views/elements/footer.thtml:71
+#: views/layouts/amo2009.thtml:340
+msgid "footer_credits"
+msgstr "دست‌اندرکاران"
+
+#: views/elements/footer.thtml:76
+#: views/layouts/amo2009.thtml:346
+msgid "footer_disclaimer"
+msgstr "موزیلا پیوندهای به این برنامه‌ها را با حسن نیت ارائه می‌دهد، Ùˆ هیچ تضمینی در خصوص برنامه‌ها Ùˆ یا اطلاعات دیگر مربوط به آنها نمی‌دهد. هر گونه سؤال، شکایت یا دعوی مربوط به این برنامه‌ها باید به توزیع‌کنندهٔ نرم‌اÙزار مربوطه ارسال شود."
+
+#: views/elements/footer.thtml:61
+#: views/layouts/amo2009.thtml:332
+msgid "footer_lang_form_lang_submit_go"
+msgstr "برو"
+
+#: views/elements/footer.thtml:70
+#: views/layouts/amo2009.thtml:339
+msgid "footer_legal_notices"
+msgstr "یادداشت‌های قانونی"
+
+#: views/elements/footer.thtml:50
+#: views/layouts/amo2009.thtml:321
+msgid "footer_other_languages"
+msgstr "زبان‌های دیگر:"
+
+#: views/elements/footer.thtml:69
+#: views/layouts/amo2009.thtml:338
+msgid "footer_privacy_policy"
+msgstr "سیاست Ø­Ùظ حریم خصوصی"
+
+#: models/addontype.php:79
+msgid "general_addontype_dict"
+msgstr "واژه‌نامه"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:100
+msgid "general_addontype_dict_plural"
+msgstr "واژه‌نامه‌ها"
+
+#: models/addontype.php:75
+msgid "general_addontype_extension"
+msgstr "ضمیمه"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:98
+msgid "general_addontype_extension_plural"
+msgstr "ضمیمه‌ها"
+
+#: models/addontype.php:85
+msgid "general_addontype_lpaddon"
+msgstr "بستهٔ زبان (اÙزودنی)"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:103
+msgid "general_addontype_lpaddon_plural"
+msgstr "بسته‌های زبان (اÙزودنی)"
+
+#: models/addontype.php:83
+msgid "general_addontype_lpapp"
+msgstr "بستهٔ زبان (برنامه)"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:102
+msgid "general_addontype_lpapp_plural"
+msgstr "بسته‌های زبان (برنامه)"
+
+#: models/addontype.php:87
+msgid "general_addontype_plugin"
+msgstr "متصل‌شونده"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:104
+msgid "general_addontype_plugin_plural"
+msgstr "متصل‌شونده‌ها"
+
+#: models/addontype.php:81
+msgid "general_addontype_search"
+msgstr "موتور جست‌وجو"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:101
+msgid "general_addontype_search_plural"
+msgstr "موتورهای جست‌وجو"
+
+#: models/addontype.php:77
+msgid "general_addontype_theme"
+msgstr "تم"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:99
+msgid "general_addontype_theme_plural"
+msgstr "تم‌ها"
+
+#: config/language.php:367
+msgid "general_languages_all_locales"
+msgstr "همهٔ زبان‌ها"
+
+#: views/layouts/amo2009.thtml:249
+msgid "header_brand_name"
+msgstr "موزیلا"
+
+#. %1$s is the application name. Example: Firefox
+#: views/elements/header.thtml:111
+#: views/elements/header.thtml:122
+#: views/layouts/amo2009.thtml:248
+#, php-format
+msgid "header_home_tooltip"
+msgstr "بازگشت به صÙحهٔ آغازهٔ اÙزودنی‌های %1$s"
+
+#: views/elements/header.thtml:87
+msgid "header_main_firefox_header"
+msgstr "اÙزودنی‌های ÙایرÙاکس"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:218
+msgid "header_main_firefox_header_with_logo"
+msgstr "اÙزودنی‌های <img alt=\"ÙایرÙاکس\" src=\"%1$s\" /> <strong>ÙایرÙاکس</strong>"
+
+#: views/elements/header.thtml:99
+msgid "header_main_header"
+msgstr "اÙزودنی‌ها"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:242
+msgid "header_main_header_with_logo"
+msgstr "اÙزودنی‌ها <img alt=\"اÙزودنی‌ها\" src=\"%1$s\" />"
+
+#: views/elements/header.thtml:90
+msgid "header_main_seamonkey_header"
+msgstr "اÙزودنی‌های سی‌مانکی"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:224
+msgid "header_main_seamonkey_header_with_logo"
+msgstr "اÙزودنی‌های <img alt=\"سی‌مانکی\" src=\"%1$s\" /> <strong>سی‌مانکی</strong>"
+
+#: views/elements/header.thtml:93
+msgid "header_main_sunbird_header"
+msgstr "اÙزودنی‌های سان‌برد"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:230
+msgid "header_main_sunbird_header_with_logo"
+msgstr "اÙزودنی‌های <img alt=\"سان‌برد\" src=\"%1$s\" /> <strong>سان‌برد</strong>"
+
+#: views/elements/header.thtml:96
+msgid "header_main_thunderbird_header"
+msgstr "اÙزودنی‌های تاندربرد"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:236
+msgid "header_main_thunderbird_header_with_logo"
+msgstr "اÙزودنی‌های <img alt=\"تاندربرد\" src=\"%1$s\" /> <strong>تاندربرد</strong>"
+
+#: views/layouts/amo2009.thtml:205
+msgid "header_navaccess_applications_menu"
+msgstr "پرش به منوی برنامه‌های دیگر"
+
+#: views/layouts/amo2009.thtml:204
+msgid "header_navaccess_categories_menu"
+msgstr "پرش به منوی دسته‌ها"
+
+#: views/layouts/amo2009.thtml:202
+msgid "header_navaccess_main_content"
+msgstr "پرش به محتوای اصلی"
+
+#: views/layouts/amo2009.thtml:203
+msgid "header_navaccess_search_form"
+msgstr "پرش به Ùرم جست‌وجو"
+
+#: views/elements/header.thtml:62
+msgid "header_navlink_addons"
+msgstr "اÙزودنی‌ها"
+
+#: views/elements/developers/sidebar.thtml:72
+#: views/elements/developers/myaddons.thtml:50
+#: views/elements/header.thtml:159
+#: views/addons/display.thtml:378
+msgid "header_navlink_login"
+msgstr "ورود"
+
+#: views/elements/header.thtml:156
+#: views/layouts/amo2009.thtml:304
+msgid "header_navlink_logout"
+msgstr "خروج"
+
+#: views/elements/header.thtml:145
+#: views/layouts/amo2009.thtml:303
+msgid "header_navlink_myaccount"
+msgstr "حساب کاربری من"
+
+#: views/elements/header.thtml:158
+msgid "header_navlink_register"
+msgstr "ثبت نام"
+
+#. %1 is the URL to the registration page
+#. %2 is the URL to the login page
+#: views/layouts/amo2009.thtml:278
+msgid "header_navlink_register_or_login"
+msgstr "<a href=\"%1$s\">ثبت نام</a> یا <a href=\"%2$s\">ورود</a>"
+
+#: views/layouts/amo2009.thtml:285
+msgid "header_navlink_tools"
+msgstr "ابزارها"
+
+#. %s is the add-on name
+#: views/elements/collections_interactive_addon.thtml:62
+#: views/elements/amo2009/homepage_addon.thtml:77
+#: views/elements/addon_discussionheader.thtml:62
+#: views/elements/addon_listitem.thtml:67
+#: views/elements/feature.thtml:84
+#: views/addons/category_landing.thtml:87
+#: views/addons/browse_thumbs.thtml:60
+#, php-format
+msgid "img_preview_of"
+msgstr "تصویر پیش‌نمایش %s"
+
+#. %1 is the login URL for the link tag
+#. %2 is the link to an explanatory page.
+#: views/elements/amo2009/install.thtml:307
+#: views/elements/install.thtml:255
+msgid "install_a_login_to_install"
+msgstr "برای نصب این اÙزودنی آزمایشی <a href=\"%1$s\">وارد شوید</a>. <a href=\"%2$s\">چرا</a>ØŸ"
+
+#. %1 is the URL for the Experimental Add-ons section of the FAQ page
+#: views/elements/amo2009/install.thtml:283
+#: views/elements/install.thtml:232
+msgid "install_button_confirm_exp_install"
+msgstr "به من اجازهٔ نصب این اÙزودنی آزمایشی داده شود. <a href=\"%1$s\">یعنی چه؟</a>"
+
+#. %1$s is the application name. Example: Firefox
+#. %2$s is an optional string used to specify a platform. Example: (Windows)
+#: views/elements/amo2009/install.thtml:128
+#: views/elements/install.thtml:75
+#, php-format
+msgid "install_button_text"
+msgstr "اÙزودن به %s %s"
+
+#. %1 is the add-on name, %2 is the app name
+#: views/elements/amo2009/install.thtml:191
+#: views/elements/amo2009/install.thtml:206
+#: views/elements/amo2009/install.thtml:249
+#: views/elements/amo2009/install.thtml:298
+#: views/elements/install.thtml:150
+#: views/elements/install.thtml:165
+#: views/elements/install.thtml:202
+#: views/elements/install.thtml:246
+#, php-format
+msgid "install_button_title"
+msgstr "اÙزودن %1$s به %2$s"
+
+#. %1$s is the add-on name
+#: views/elements/amo2009/install.thtml:200
+#: views/elements/install.thtml:159
+#, php-format
+msgid "install_download"
+msgstr "بارگیری %1$s"
+
+#: views/elements/amo2009/install.thtml:147
+#: views/elements/install.thtml:94
+msgid "install_error_addon_not_found"
+msgstr "این اÙزودنی در دسترس نیست."
+
+#: views/addons/dictionaries.thtml:65
+msgid "langtools_a11y_tablesummary"
+msgstr "Ùهرست بسته‌های زبان Ùˆ واژه‌نامه‌ها."
+
+#: views/addons/dictionaries.thtml:47
+msgid "langtools_download_dictionary"
+msgstr "بارگیری واژه‌نامه"
+
+#: views/addons/dictionaries.thtml:48
+msgid "langtools_download_langpack"
+msgstr "بارگیری بستهٔ زبان"
+
+#: views/addons/dictionaries.thtml:63
+#: controllers/components/amo.php:685
+#: controllers/addons_controller.php:1239
+msgid "langtools_header_dicts_and_langpacks"
+msgstr "واژه‌نامه‌ها و بسته‌های زبان"
+
+#: views/addons/dictionaries.thtml:44
+msgid "langtools_install_dictionary"
+msgstr "نصب واژه‌نامه"
+
+#: views/addons/dictionaries.thtml:45
+msgid "langtools_install_langpack"
+msgstr "نصب بستهٔ زبان"
+
+#: views/addons/dictionaries.thtml:69
+msgid "langtools_tableheader_dictionary"
+msgstr "واژه‌نامه"
+
+#: views/addons/dictionaries.thtml:70
+msgid "langtools_tableheader_langpack"
+msgstr "بستهٔ زبان"
+
+#: views/addons/dictionaries.thtml:68
+msgid "langtools_tableheader_language"
+msgstr "زبان"
+
+#: models/license.php:65
+msgid "license_custom"
+msgstr "مجوز خاص"
+
+#: config/bootstrap.php:303
+msgid "licenses_bsd"
+msgstr "مجوز BSD"
+
+#: config/bootstrap.php:298
+msgid "licenses_gpl_2.0"
+msgstr "مجوز عمومی کلی گنو، نسخهٔ ۲٫۰"
+
+#: config/bootstrap.php:299
+msgid "licenses_gpl_3.0"
+msgstr "مجوز عمومی کلی گنو، نسخهٔ ۳٫۰"
+
+#: config/bootstrap.php:300
+msgid "licenses_lgpl_2.1"
+msgstr "مجوز عمومی Ú©Ù„ÛŒ کاهش‌یاÙتهٔ گنو، نسخهٔ Û²Ù«Û±"
+
+#: config/bootstrap.php:301
+msgid "licenses_lgpl_3.0"
+msgstr "مجوز عمومی Ú©Ù„ÛŒ کاهش‌یاÙتهٔ گنو، نسخهٔ Û³Ù«Û°"
+
+#: config/bootstrap.php:302
+msgid "licenses_mit"
+msgstr "مجوز MIT/X11"
+
+#: config/bootstrap.php:297
+msgid "licenses_mpl_1.1"
+msgstr "مجوز عمومی موزیلا، نسخهٔ ۱٫۱"
+
+#: views/users/emailchange.thtml:51
+#: views/users/delete.thtml:55
+#: views/users/delete.thtml:137
+#: views/users/edit.thtml:74
+#: views/reviews/flag.thtml:54
+msgid "link_return_to_front_page"
+msgstr "برای بازگشت به صÙحهٔ اصلی اینجا را کلیک کنید."
+
+#: views/elements/amo2009/addon_list_options.thtml:46
+#: views/elements/addon_list_options.thtml:46
+msgid "list_sortby_date"
+msgstr "تاریخ"
+
+#: views/elements/amo2009/addon_list_options.thtml:47
+#: views/elements/addon_list_options.thtml:47
+msgid "list_sortby_downloads"
+msgstr "بارگیری‌ها"
+
+#: views/elements/amo2009/addon_list_options.thtml:45
+#: views/elements/addon_list_options.thtml:45
+msgid "list_sortby_name"
+msgstr "نام اÙزودنی"
+
+#: views/elements/amo2009/addon_list_options.thtml:48
+#: views/elements/addon_list_options.thtml:48
+msgid "list_sortby_rating"
+msgstr "رتبه"
+
+#: config/bootstrap.php:278
+msgid "main_prettyname_fennec"
+msgstr "ÙÙ†Ú©"
+
+#: config/bootstrap.php:274
+msgid "main_prettyname_firefox"
+msgstr "ÙایرÙاکس"
+
+#: config/bootstrap.php:277
+msgid "main_prettyname_seamonkey"
+msgstr "سی‌مانکی"
+
+#: config/bootstrap.php:276
+msgid "main_prettyname_sunbird"
+msgstr "سان‌برد"
+
+#: config/bootstrap.php:275
+msgid "main_prettyname_thunderbird"
+msgstr "تاندربرد"
+
+#: views/elements/addon_categories.thtml:52
+msgid "nav_category_dicts_langpacks"
+msgstr "واژه‌نامه‌ها و بسته‌های زبان"
+
+#: views/elements/addon_categories.thtml:55
+msgid "nav_category_themes"
+msgstr "تم‌ها"
+
+#: views/elements/app_chooser.thtml:47
+#: views/layouts/amo2009.thtml:255
+msgid "other_apps_tooltip"
+msgstr "پیدا کردن اÙزودنی‌های برنامه‌های دیگر"
+
+#. In a user list: user 1, user 2, "others"
+#: views/helpers/addons_html.php:222
+msgid "other_users"
+msgstr "دیگران"
+
+#: controllers/pages_controller.php:90
+msgid "page_title_appversions"
+msgstr "نسخه‌های برنامه"
+
+#: controllers/pages_controller.php:115
+msgid "page_title_collector"
+msgstr "مجموعه‌ساز اÙزودنی‌ها"
+
+#: controllers/pages_controller.php:117
+msgid "page_title_collector_faq"
+msgstr "پرسش‌های متداول مجموعه‌ساز اÙزودنی‌ها"
+
+#: controllers/pages_controller.php:119
+msgid "page_title_collector_features"
+msgstr "ویژگی‌های مجموعه‌ساز اÙزودنی‌ها"
+
+#: controllers/pages_controller.php:122
+msgid "page_title_collector_firstrun"
+msgstr "به مجموعه‌ساز اÙزودنی‌ها خوش آمدید"
+
+#: controllers/pages_controller.php:92
+msgid "page_title_credits"
+msgstr "دست‌اندرکاران"
+
+#: controllers/pages_controller.php:113
+msgid "page_title_developer_faq"
+msgstr "پرسش‌های متداول توسعه‌دهندگان"
+
+#: controllers/pages_controller.php:111
+msgid "page_title_faq"
+msgstr "پرسش‌های متداول"
+
+#: controllers/pages_controller.php:94
+msgid "page_title_fashionyourfirefox_faq"
+msgstr "پرسش‌های معمول «به نمایش گذاشتن ÙایرÙاکس خود»"
+
+#: controllers/pages_controller.php:101
+msgid "page_title_policy"
+msgstr "سیاست اÙزودنی‌ها"
+
+#: controllers/pages_controller.php:103
+msgid "page_title_privacy"
+msgstr "سیاست Ø­Ùظ حریم خصوصی موزیلا"
+
+#: controllers/pages_controller.php:105
+msgid "page_title_review_guide"
+msgstr "رهنمون‌های بررسی"
+
+#: controllers/pages_controller.php:107
+msgid "page_title_sandbox"
+msgstr "نظام بررسی گودال ماسه‌بازی"
+
+#: controllers/pages_controller.php:109
+msgid "page_title_submissionhelp"
+msgstr "راهنمای ارسال"
+
+#: views/pages/appversions.thtml:87
+msgid "pages_appversions_guid"
+msgstr "GUID"
+
+#: views/pages/appversions.thtml:79
+#: controllers/pages_controller.php:90
+msgid "pages_appversions_header"
+msgstr "نسخه‌های معتبر برنامه"
+
+#: views/pages/appversions.thtml:80
+msgid "pages_appversions_intro"
+msgstr "اÙزودنی‌هایی Ú©Ù‡ به وب‌گاه اÙزودنی‌های موزیلا ارسال می‌شوند باید دارای یک پروندهٔ install.rdf با کمینه یکی از برنامه‌های پشتیبانی شدهٔ زیر باشند. تنها نسخه‌هایی Ú©Ù‡ در زیر ذکر شده‌اند برای این برنامه‌ها مجاز می‌باشند."
+
+#. %s is a full <a> tag
+#: views/pages/appversions.thtml:93
+#, php-format
+msgid "pages_appversions_required_files"
+msgstr "اگر برنامه‌ای Ú©Ù‡ از آن پشتیبانی می‌کنید نیازی به پروندهٔ install.rdf ندارد، باز هم باید این پرونده را با مشخصات مشخص شده %s درون اÙزودنی خود قرار دهید."
+
+#. this is the text inside of an <a> tag for pages_appversions_required_files. This
+#. should be fixed.
+#: views/pages/appversions.thtml:93
+msgid "pages_appversions_required_files_link"
+msgstr "اینجا"
+
+#: views/pages/appversions.thtml:88
+msgid "pages_appversions_versions"
+msgstr "نسخه‌ها"
+
+#: views/pages/policy.thtml:51
+msgid "pages_policy_sandbox_link"
+msgstr "صÙحهٔ اطلاعات گودال ماسه‌بازی"
+
+#: views/elements/pagination.thtml:53
+msgid "pagination_next_page"
+msgstr "بعدی"
+
+#: views/elements/pagination.thtml:52
+msgid "pagination_previous_page"
+msgstr "صÙحهٔ قبلی"
+
+#: views/elements/recaptcha.thtml:65
+msgid "recaptcha_enter_both_words"
+msgstr "لطÙاً <strong>هر دو کلمهٔ</strong> زیر را با <strong>یک Ùاصله از هم</strong> وارد کنید."
+
+#: views/elements/recaptcha.thtml:83
+msgid "recaptcha_enter_here"
+msgstr "پاسخ خود را اینجا وارد کنید:"
+
+#: views/elements/recaptcha.thtml:74
+msgid "recaptcha_enter_whatyouhear"
+msgstr "لطÙاً آنچه را Ú©Ù‡ می‌شنوید وارد نمایید."
+
+#. %1 is the link switching refreshing the captcha
+#. %2 is the link switching to a text captcha
+#: views/elements/recaptcha.thtml:77
+msgid "recaptcha_hardtohear_text"
+msgstr "اگر متوجه نشدید، می‌توانید <a href=\"%1$s\">به چیز دیگری گوش دهید</a> یا <a href=\"%2$s\">به حالت متنی بازگردید</a>."
+
+#. %1 is the link switching refreshing the captcha
+#. %2 is the link switching to an audio captcha
+#: views/elements/recaptcha.thtml:68
+msgid "recaptcha_hardtoread_text"
+msgstr "اگر قادر به خواندن این متن نیستید، می‌توانید <a href=\"%1$s\">واژه‌های دیگری را امتحان کنید</a> یا به جای آن <a href=\"%2$s\">به متنی گوش دهید</a>."
+
+#: views/users/register.thtml:105
+msgid "recaptcha_label"
+msgstr "آیا شما یک انسان هستید؟"
+
+#: views/users/register.thtml:106
+msgid "recaptcha_whatsthis"
+msgstr "این چیست؟"
+
+#: controllers/reviews_controller.php:559
+msgid "review_flag_error"
+msgstr "علامت‌گذاری این بررسی با خطا مواجه شد!"
+
+#: models/reviews_moderation_flag.php:69
+msgid "review_flag_reason_bug_support"
+msgstr "گزارش اشکال یا تقاضای پشتیبانی نابه‌جا"
+
+#: views/reviews/display.thtml:103
+#: views/reviews/display.thtml:186
+msgid "review_flag_reason_instructions"
+msgstr "این بررسی را (با ذکر یک دلیل) گزارش کنید"
+
+#: models/reviews_moderation_flag.php:67
+msgid "review_flag_reason_language"
+msgstr "استÙاده از لحن یا کلمات نامناسب"
+
+#: models/reviews_moderation_flag.php:71
+msgid "review_flag_reason_other"
+msgstr "دلایل دیگر (لطÙاً آنها را مشخص کنید)"
+
+#: models/reviews_moderation_flag.php:65
+msgid "review_flag_reason_spam"
+msgstr "هرزنوشته و مطلب نامربوط به بررسی"
+
+#: views/reviews/display.thtml:91
+#: views/reviews/display.thtml:175
+#: controllers/reviews_controller.php:555
+msgid "review_flag_success"
+msgstr "متشکریم؛ این بررسی برای تأیید ویرایش‌گران علامت خورد."
+
+#: views/reviews/display.thtml:41
+msgid "review_flag_this"
+msgstr "گزارش این بررسی"
+
+#: views/reviews/display.thtml:42
+msgid "review_flag_this_titletip"
+msgstr "آیا این بررسی نامناسب، غیر دقیق یا هرزنوشته است؟ اینجا را کلیک کنید تا آن را برای بررسی ویرایش‌گران علامت بزنید."
+
+#. %1 is the URL of the support section, %2 for the review guidelines
+#: views/reviews/add.thtml:53
+msgid "review_guidelines_short"
+msgstr "<p>این ترÙندها را در ذهن داشته باشید:</p><ul><li>طوری بنویسید Ú©Ù‡ انگار تجربهٔ خود از این اÙزودنی را برای یک دوست تعری٠می‌کنید. نکات ریز Ùˆ جزئیات Ù…Ùید مانند ویژگی‌هایی Ú©Ù‡ دوست داشتید یا دوست نداشتید، آسانی استÙاده از آن، Ùˆ معابیش را بیان کنید. از کلی‌گویی Ùˆ «عالی» یا «بد» خواندن اÙزودنی بپرهیزید مگر آن Ú©Ù‡ دلایل نظر خود را نیز بیان کنید.</li><li>لطÙاً گزارش مشکلات را در بررسی‌ها ارسال نکنید. ما نشانی پست الکترونیکی شما را در اختیار توسعه‌دهندگان اÙزودنی قرار نمی‌دهیم Ùˆ ممکن است آنها نیاز داشته باشند با شما تماس بگیرند تا به رÙع مشکلتان Ú©Ù…Ú© کنند. از <a href=\"%1$s\">بخش پشتیبانی </a> برای Ú©Ù…Ú© گرÙتن دربارهٔ استÙاده از این اÙزودنی بازدید کنید.</li><li>لطÙاً بررسی‌ها را عاری از الÙاظ نامناسب Ùˆ یا هر گونه اطلاعات شخصی Ù†Ú¯Ù‡ دارید.</li></ul><p>لطÙاً برای اطلاعات بیشتر از بررسی‌های اÙزودنی‌های کاربران، <a href=\"%2$s\">رهنمون‌های انجام بررسی</a> را مطالعه نمایید."
+
+#. %1 is the add-on name
+#: views/reviews/flag.thtml:56
+#: views/reviews/display.thtml:55
+#: views/reviews/review_added.thtml:50
+#, php-format
+msgid "reviews_header"
+msgstr "بررسی‌های %s"
+
+#: controllers/addons_controller.php:435
+msgid "rss_featuredaddons"
+msgstr "اÙزودنی‌های پیشنهاد شده"
+
+#: controllers/addons_controller.php:432
+msgid "rss_newestaddons"
+msgstr "جدیدترین اÙزودنی‌ها"
+
+#: controllers/addons_controller.php:434
+msgid "rss_popularaddons"
+msgstr "اÙزودنی‌های محبوب"
+
+#: controllers/addons_controller.php:433
+msgid "rss_updatedaddons"
+msgstr "اÙزودنی‌های به‌هنگام شده"
+
+#: views/elements/search_mini.thtml:70
+msgid "search"
+msgstr "جست‌وجو"
+
+#: views/search/collections.thtml:51
+msgid "search_collections_header"
+msgstr "نتایج جستجو در مجموعه‌ها"
+
+#: controllers/search_controller.php:297
+msgid "search_collections_pagetitle"
+msgstr "نتایج جستجو در مجموعه‌ها"
+
+#: controllers/search_controller.php:99
+msgid "search_disabled"
+msgstr "جست‌وجو در حال حاضر غیر Ùعال است. لطÙاً بعداً دوباره تلاش نمایید."
+
+#: views/elements/amo2009/search.thtml:188
+#: views/elements/search.thtml:187
+#: views/elements/search_mini.thtml:54
+msgid "search_form_all_addons"
+msgstr "همهٔ اÙزودنی‌ها"
+
+#. This string is in the main category dropdown when searching
+#: views/elements/amo2009/search.thtml:204
+msgid "search_form_all_collections"
+msgstr "همهٔ مجموعه‌ها"
+
+#: views/elements/amo2009/search.thtml:184
+#: views/elements/amo2009/search.thtml:385
+#: views/elements/amo2009/search.thtml:408
+#: views/elements/search.thtml:171
+#: views/elements/search.thtml:183
+#: views/elements/search_mini.thtml:43
+#: views/elements/search_mini.thtml:49
+#: views/layouts/mozilla.thtml:188
+msgid "search_form_default_text"
+msgstr "جست‌وجو برای اÙزودنی‌ها"
+
+#: views/elements/amo2009/search.thtml:184
+#: views/elements/amo2009/search.thtml:404
+msgid "search_form_default_text_collections"
+msgstr "جست‌وجو به دنبال مجموعه‌ها"
+
+#: views/elements/amo2009/search.thtml:206
+#: views/elements/search.thtml:202
+msgid "search_form_submit_tooltip"
+msgstr "جست‌وجو برای اÙزودنی‌ها"
+
+#: views/elements/amo2009/search.thtml:184
+#: views/elements/search.thtml:183
+#: views/elements/search_mini.thtml:49
+msgid "search_form_tooltip"
+msgstr "برای وارد کردن عبارت‌های جست‌وجو کلیک کنید"
+
+#: views/elements/amo2009/search.thtml:186
+#: views/elements/search.thtml:185
+#: views/elements/search_mini.thtml:52
+msgid "search_form_within"
+msgstr "درون"
+
+#: views/addons/searchengines.thtml:118
+msgid "search_landing_all_search_engines"
+msgstr "همهٔ موتورهای جست‌وجو"
+
+#: views/addons/searchengines.thtml:114
+msgid "search_landing_browse_search_engines"
+msgstr "مرور موتورهای جست‌وجو"
+
+#: views/search/collections.thtml:58
+#: views/search/index.thtml:59
+msgid "search_nothing_found"
+msgstr "هیچ نتیجه‌ای پیدا نشد."
+
+#: controllers/search_controller.php:185
+msgid "search_pagetitle"
+msgstr "جست‌وجو در اÙزودنی‌ها"
+
+#: controllers/search_controller.php:242
+msgid "search_rss_description"
+msgstr "خورد نتیجهٔ جست‌وجو"
+
+#. %s is the terms the user is searching for (a string)
+#: controllers/search_controller.php:241
+#, php-format
+msgid "search_rss_results_for"
+msgstr "نتایج جست‌وجو برای: %s"
+
+#: views/elements/header.thtml:154
+#: views/layouts/amo2009.thtml:296
+msgid "sidebar_navlink_admin_tools"
+msgstr "جدیدترین اÙزودنی‌ها"
+
+#: views/elements/header.thtml:146
+#: views/layouts/amo2009.thtml:288
+msgid "sidebar_navlink_developer_tools"
+msgstr "ابزارهای توسعه‌دهنده"
+
+#: views/elements/header.thtml:148
+#: views/layouts/amo2009.thtml:290
+msgid "sidebar_navlink_editor_tools"
+msgstr "ابزارهای ویرایش‌گر"
+
+#: views/layouts/amo2009.thtml:302
+msgid "sidebar_navlink_welcome"
+msgstr "خوش آمدید"
+
+#. %s is the user's name
+#: views/layouts/amo2009.thtml:302
+#, php-format
+msgid "sidebar_navlink_welcome_name"
+msgstr "%s، خوش آمدید"
+
+#: views/elements/pitch.thtml:50
+#: views/elements/pitch.thtml:55
+msgid "sidebar_pitch_dictionary"
+msgstr "واژه‌نامه"
+
+#: views/elements/pitch.thtml:72
+msgid "sidebar_pitch_featured_addons"
+msgstr "اÙزودنی‌های پیشنهاد شده"
+
+#: views/elements/pitch.thtml:61
+msgid "sidebar_pitch_looking_for"
+msgstr "به دنبال یکی از این موارد می‌گردم:"
+
+#: views/elements/pitch.thtml:70
+msgid "sidebar_pitch_newest_addons"
+msgstr "جدیدترین اÙزودنی‌ها"
+
+#: views/elements/pitch.thtml:49
+msgid "sidebar_pitch_search"
+msgstr "متصل‌شوندهٔ جست‌وجو"
+
+#: views/elements/pitch.thtml:69
+msgid "sidebar_pitch_subscribe_to"
+msgstr "آبونه شدن"
+
+#: views/elements/pitch.thtml:48
+#: views/elements/pitch.thtml:54
+msgid "sidebar_pitch_theme"
+msgstr "تم"
+
+#: views/elements/pitch.thtml:71
+msgid "sidebar_pitch_updated_addons"
+msgstr "اÙزودنی‌های به‌هنگام شده"
+
+#. %1$s is a number
+#: views/helpers/localization.php:65
+#: views/developers/versions_edit.thtml:95
+#: views/addons/dictionaries.thtml:92
+#, php-format
+msgid "size_kb"
+msgstr "%1$s کیلوبایت"
+
+#: views/elements/amo2009/stars.thtml:57
+#: views/elements/stars.thtml:63
+msgid "stars_not_yet_rated"
+msgstr "هنوز رتبه‌دهی نشده است"
+
+#. %1 is the number of stars this add-on has
+#: views/elements/amo2009/stars.thtml:49
+#: views/elements/stars.thtml:54
+#, php-format
+msgid "stars_rated_x_outof_5"
+msgstr "دارای رتبهٔ %s از ۵ ستاره"
+
+#: views/statistics/addon.thtml:59
+msgid "statistics_addon_dashboard_link"
+msgstr "صÙحهٔ آغازهٔ آمار"
+
+#: views/statistics/addon.thtml:58
+msgid "statistics_addon_developertools_link"
+msgstr "جدیدترین اÙزودنی‌ها"
+
+#: views/statistics/addon.thtml:53
+msgid "statistics_addon_switch"
+msgstr "تغییر اÙزودنی"
+
+#. This is a date format.
+#. http://php.net/strftime
+#: views/statistics/rss/summary.thtml:54
+#: views/statistics/addon.thtml:181
+msgid "statistics_date_shortmonth"
+msgstr "%e %B"
+
+#. This is a date format.
+#. http://php.net/strftime
+#: views/statistics/rss/summary.thtml:40
+#: views/statistics/addon.thtml:152
+msgid "statistics_date_shortmonthwithyear"
+msgstr "%e %B %Y"
+
+#. This is a date format.
+#. http://php.net/strftime
+#: views/statistics/rss/summary.thtml:41
+#: views/statistics/rss/summary.thtml:48
+#: views/statistics/addon.thtml:161
+#: views/statistics/addon.thtml:172
+msgid "statistics_date_weekdayshortmonth"
+msgstr "%A، %e %B"
+
+#. %1$s is an add-on name and version. Example: Add-on 3.5
+#: controllers/components/stats.php:519
+#, php-format
+msgid "statistics_events_addon_created"
+msgstr "%1$s ایجاد گردید"
+
+#. %1$s is an application name and version. Example: Firefox 3.5
+#: controllers/components/stats.php:500
+#, php-format
+msgid "statistics_events_app_released"
+msgstr "%1$s کنار گذاشته شد"
+
+#: views/statistics/addon.thtml:71
+msgid "statistics_help_close_link"
+msgstr "بستن"
+
+#: views/statistics/addon.thtml:60
+msgid "statistics_help_link"
+msgstr "راهنما"
+
+#: views/statistics/index.thtml:83
+msgid "statistics_index_anotheraddon"
+msgstr "یا اÙزودنی دیگری انتخاب کنید"
+
+#: views/statistics/index.thtml:85
+msgid "statistics_index_anotheraddon_public"
+msgstr "یا اÙزودنی دیگری با آمار عمومی انتخاب نمایید"
+
+#: views/statistics/index.thtml:71
+msgid "statistics_index_myaddons"
+msgstr "یکی از اÙزودنی‌های خود را انتخاب کنید تا آمارش را مشاهده نمایید"
+
+#: views/statistics/index.thtml:89
+msgid "statistics_index_selectaddon"
+msgstr "یک اÙزودنی انتخاب کنید تا آمارش را اینجا مشاهده نمایید"
+
+#: views/statistics/index.thtml:91
+msgid "statistics_index_selectaddon_public"
+msgstr "یک اÙزودنی با آمار عمومی انتخاب کنید"
+
+#: views/statistics/index.thtml:39
+msgid "statistics_index_title"
+msgstr "صÙحهٔ آمار"
+
+#: views/statistics/index.thtml:97
+msgid "statistics_index_view_button"
+msgstr "آمار مشاهده"
+
+#: views/statistics/addon.thtml:222
+#: controllers/statistics_controller.php:247
+msgid "statistics_js_download_csv"
+msgstr "مشاهدهٔ این جدول در قالب CSV"
+
+#: controllers/statistics_controller.php:246
+msgid "statistics_js_dropdowns_none"
+msgstr "خالی"
+
+#: controllers/statistics_controller.php:245
+msgid "statistics_js_dropdowns_removeplot"
+msgstr "حذ٠این نمودار"
+
+#: controllers/statistics_controller.php:248
+msgid "statistics_js_groupby_selector_date"
+msgstr "گروه‌بندی بر اساس: روز"
+
+#: controllers/statistics_controller.php:251
+msgid "statistics_js_groupby_selector_month"
+msgstr "گروه‌بندی بر اساس: ماه"
+
+#: controllers/statistics_controller.php:249
+msgid "statistics_js_groupby_selector_week"
+msgstr "گروه‌بندی بر اساس: Ù‡Ùته"
+
+#: controllers/statistics_controller.php:250
+msgid "statistics_js_groupby_selector_week_over_week"
+msgstr "مقایسه بر اساس: Ù‡Ùته"
+
+#: controllers/statistics_controller.php:260
+msgid "statistics_js_plotselection_foundinrange"
+msgstr "%s مورد در این بازه پیدا شد"
+
+#: controllers/statistics_controller.php:270
+msgid "statistics_js_plotselection_options_addplot_name"
+msgstr "اÙزودن نمودار"
+
+#: controllers/statistics_controller.php:271
+msgid "statistics_js_plotselection_options_addplot_tooltip"
+msgstr "اÙزودن نموداری دیگر به این Ø´Ú©Ù„"
+
+#: controllers/statistics_controller.php:261
+msgid "statistics_js_plotselection_options_count_name_checked"
+msgstr "پنهان کردن تعداد کل"
+
+#: controllers/statistics_controller.php:262
+msgid "statistics_js_plotselection_options_count_name_unchecked"
+msgstr "نمایش تعداد کل"
+
+#: controllers/statistics_controller.php:263
+msgid "statistics_js_plotselection_options_count_tooltip"
+msgstr "رسم تعداد کل این نمودار"
+
+#: controllers/statistics_controller.php:275
+msgid "statistics_js_plotselection_options_csv_name"
+msgstr "مشاهدهٔ اطلاعات (CSV)"
+
+#: controllers/statistics_controller.php:276
+msgid "statistics_js_plotselection_options_csv_tooltip"
+msgstr "دریاÙت یک پروندهٔ مقادیر جدا شده توسط ویرگول از این اطلاعات"
+
+#: controllers/statistics_controller.php:267
+msgid "statistics_js_plotselection_options_events_addon_name_checked"
+msgstr "پنهان کردن رویدادهای %s"
+
+#: controllers/statistics_controller.php:268
+msgid "statistics_js_plotselection_options_events_addon_name_unchecked"
+msgstr "تمایش رویدادهای %s"
+
+#: controllers/statistics_controller.php:269
+msgid "statistics_js_plotselection_options_events_addon_tooltip"
+msgstr "انداختن تاریخ‌های انتشار نسخه‌های اÙزودنی بر روی نمودار"
+
+#: controllers/statistics_controller.php:264
+msgid "statistics_js_plotselection_options_events_firefox_name_checked"
+msgstr "پنهان کردن رویدادهای ÙایرÙاکس"
+
+#: controllers/statistics_controller.php:265
+msgid "statistics_js_plotselection_options_events_firefox_name_unchecked"
+msgstr "نمایش رویدادهای ÙایرÙاکس"
+
+#: controllers/statistics_controller.php:266
+msgid "statistics_js_plotselection_options_events_firefox_tooltip"
+msgstr "انداختن تاریخ‌های انتشار ÙایرÙاکس بر روی نمودار"
+
+#: controllers/statistics_controller.php:272
+msgid "statistics_js_plotselection_options_resize_name_checked"
+msgstr "جمع کردن شکل"
+
+#: controllers/statistics_controller.php:273
+msgid "statistics_js_plotselection_options_resize_name_unchecked"
+msgstr "بسط دادن شکل"
+
+#: controllers/statistics_controller.php:274
+msgid "statistics_js_plotselection_options_resize_tooltip"
+msgstr "تغییر اندازهٔ شکل"
+
+#: controllers/statistics_controller.php:254
+msgid "statistics_js_plotselection_selector_adu"
+msgstr "کاربران Ùعال روزانه"
+
+#: controllers/statistics_controller.php:256
+msgid "statistics_js_plotselection_selector_application"
+msgstr "برنامه"
+
+#: controllers/statistics_controller.php:259
+msgid "statistics_js_plotselection_selector_custom"
+msgstr "سÙارشی"
+
+#: controllers/statistics_controller.php:253
+msgid "statistics_js_plotselection_selector_downloads"
+msgstr "بارگیری‌ها"
+
+#: controllers/statistics_controller.php:258
+msgid "statistics_js_plotselection_selector_os"
+msgstr "سیستم‌عامل"
+
+#: controllers/statistics_controller.php:257
+msgid "statistics_js_plotselection_selector_status"
+msgstr "وضعیت اÙزودنی"
+
+#: controllers/statistics_controller.php:252
+msgid "statistics_js_plotselection_selector_summary"
+msgstr "خلاصه"
+
+#: controllers/statistics_controller.php:255
+msgid "statistics_js_plotselection_selector_version"
+msgstr "نسخهٔ اÙزودنی"
+
+#: controllers/components/stats.php:398
+msgid "statistics_longnames_application"
+msgstr "برنامه"
+
+#: controllers/components/stats.php:400
+msgid "statistics_longnames_os"
+msgstr "سیستم‌عامل"
+
+#: controllers/components/stats.php:399
+msgid "statistics_longnames_status"
+msgstr "وضعیت اÙزودنی"
+
+#: controllers/components/stats.php:401
+msgid "statistics_longnames_unknown"
+msgstr "نامعلوم"
+
+#: controllers/components/stats.php:397
+msgid "statistics_longnames_version"
+msgstr "نسخهٔ اÙزودنی"
+
+#: views/statistics/addon.thtml:118
+msgid "statistics_notice_data_insufficient"
+msgstr "هنوز اطلاعات کاÙÛŒ برای نمایش نمودار جمع‌آوری نشده است. لطÙاً بعداً تلاش نمایید."
+
+#: views/statistics/addon.thtml:130
+msgid "statistics_notice_data_none"
+msgstr "ما هنوز از اÙزودنی شما اطلاعاتی نداریم. لطÙاً چند روز بعد مجدداً مراجعه نمایید."
+
+#: views/statistics/addon.thtml:41
+msgid "statistics_notice_data_updating"
+msgstr "آمار اÙزودنی‌ها هم‌اکنون در حال به‌هنگام شدن است. اطلاعات جدید ممکن است تا زمان انجام این به‌هنگام‌سازی ناقص باشد. لطÙاً چند دقیقهٔ بعد دوباره تلاش نمایید."
+
+#: views/statistics/addon.thtml:136
+msgid "statistics_notice_disabled"
+msgstr "صÙحهٔ آمار در حال حاضر غیر Ùعال است. لطÙاً بعداً دوباره تلاش نمایید."
+
+#: views/statistics/addon.thtml:123
+msgid "statistics_notice_nojavascript"
+msgstr "جاوا اسکریپت برای مشاهدهٔ نمودارهای صÙحهٔ آمار مورد نیاز است."
+
+#: views/statistics/addon.thtml:44
+msgid "statistics_notice_settings_updated"
+msgstr "تنظیمات شما به‌هنگام شدند!"
+
+#: controllers/statistics_controller.php:60
+#: controllers/statistics_controller.php:71
+#: controllers/statistics_controller.php:74
+#: controllers/statistics_controller.php:240
+msgid "statistics_pagetitle"
+msgstr "صÙحهٔ آمار"
+
+#: views/statistics/addon.thtml:99
+msgid "statistics_plot_legend_adu"
+msgstr "کاربران Ùعال روزانه"
+
+#: views/statistics/addon.thtml:95
+msgid "statistics_plot_legend_downloads"
+msgstr "بارگیری‌های روزانه"
+
+#: views/statistics/addon.thtml:107
+msgid "statistics_plot_options_zoomin_alt"
+msgstr "بزرگ‌نمایی"
+
+#: views/statistics/addon.thtml:106
+msgid "statistics_plot_options_zoomin_title"
+msgstr "بزرگ‌نمایی روی یک ماه"
+
+#: views/statistics/addon.thtml:110
+msgid "statistics_plot_options_zoomout_alt"
+msgstr "کوچک‌نمایی"
+
+#: views/statistics/addon.thtml:109
+msgid "statistics_plot_options_zoomout_title"
+msgstr "کوچک‌نمایی روی یک ماه"
+
+#: controllers/statistics_controller.php:283
+#, php-format
+msgid "statistics_rss_description"
+msgstr "خلاصهٔ روزانهٔ آمار %1$s"
+
+#: views/statistics/rss/summary.thtml:68
+msgid "statistics_rss_title_fulldate"
+msgstr "%A، %e %B %Y"
+
+#: views/statistics/rss/summary.thtml:68
+#, php-format
+msgid "statistics_rss_title_statsfordate"
+msgstr "آمار %1$s"
+
+#: views/statistics/settings.thtml:49
+msgid "statistics_settings_access_description"
+msgstr "به صورت پیش‌Ùرض، تنها شما Ùˆ موزیلا قادر به مشاهدهٔ این اطلاعات در صÙحهٔ آمار خود هستید. شما می‌توانید این صÙحه را به روی عموم بگشایید تا همه بتوانند اطلاعات اÙزودنی شما را مشاهده کنند."
+
+#: views/statistics/settings.thtml:48
+msgid "statistics_settings_access_heading"
+msgstr "دسترسی به آمار"
+
+#: views/statistics/settings.thtml:51
+msgid "statistics_settings_access_private"
+msgstr "خصوصی"
+
+#: views/statistics/settings.thtml:51
+msgid "statistics_settings_access_private_description"
+msgstr "تنها موزیلا قادر به مشاهدهٔ آمار این اÙزودنی باشد"
+
+#: views/statistics/settings.thtml:52
+msgid "statistics_settings_access_public"
+msgstr "صÙحهٔ آمار"
+
+#: views/statistics/settings.thtml:52
+msgid "statistics_settings_access_public_description"
+msgstr "همه بتوانند آمار این اÙزودنی را مشاهده کنند"
+
+#: views/statistics/addon.thtml:251
+msgid "statistics_settings_change_link"
+msgstr "تغییر تنظیمات"
+
+#: views/statistics/addon.thtml:253
+msgid "statistics_settings_confidential"
+msgstr "لطÙاً این اطلاعات را محرمانه تقلی کنید."
+
+#: views/statistics/addon.thtml:245
+msgid "statistics_settings_currently_private"
+msgstr "این صÙحهٔ آمار در حال حاضر <b>خصوصی</b> است."
+
+#: views/statistics/addon.thtml:241
+msgid "statistics_settings_currently_public"
+msgstr "این صÙحهٔ آمار در حال حاضر <b>عمومی</b> است."
+
+#: views/statistics/addon.thtml:246
+msgid "statistics_settings_locked_alt"
+msgstr "Ù‚ÙÙ„ شده"
+
+#: views/statistics/settings.thtml:57
+msgid "statistics_settings_return_link"
+msgstr "بازگشت به آمار"
+
+#: views/statistics/settings.thtml:56
+msgid "statistics_settings_save_button"
+msgstr "ذخیرهٔ تنظیمات"
+
+#: views/statistics/settings.thtml:46
+#, php-format
+msgid "statistics_settings_title"
+msgstr "تنظیمات صÙحهٔ آمار %1$s"
+
+#: views/statistics/addon.thtml:242
+msgid "statistics_settings_unlocked_alt"
+msgstr "Ù‚ÙÙ„ نشده"
+
+#: controllers/components/stats.php:405
+msgid "statistics_shortnames_application"
+msgstr "برنامه"
+
+#: controllers/components/stats.php:407
+msgid "statistics_shortnames_os"
+msgstr "سیستم‌عامل"
+
+#: controllers/components/stats.php:406
+msgid "statistics_shortnames_status"
+msgstr "نام کوتاه"
+
+#: controllers/components/stats.php:408
+msgid "statistics_shortnames_unknown"
+msgstr "نامعلوم"
+
+#: controllers/components/stats.php:404
+msgid "statistics_shortnames_version"
+msgstr "نسخه"
+
+#: views/statistics/rss/summary.thtml:42
+#: views/statistics/addon.thtml:192
+msgid "statistics_summary_downloads_average"
+msgstr "بارگیری‌های متوسط روزانه"
+
+#: views/statistics/rss/summary.thtml:39
+msgid "statistics_summary_downloads_heading"
+msgstr "بارگیری‌ها"
+
+#: views/statistics/rss/summary.thtml:41
+#: views/statistics/addon.thtml:171
+msgid "statistics_summary_downloads_lastcount"
+msgstr "تعداد آخرین روز"
+
+#: views/statistics/rss/summary.thtml:43
+#: views/statistics/addon.thtml:199
+msgid "statistics_summary_downloads_lastweek"
+msgstr "بارگیری‌ها در ۷ روز گذشته"
+
+#: views/statistics/rss/summary.thtml:40
+#: views/statistics/addon.thtml:151
+msgid "statistics_summary_downloads_total"
+msgstr "بارگیری‌ها"
+
+#: views/statistics/rss/summary.thtml:40
+#: views/statistics/addon.thtml:152
+#, php-format
+msgid "statistics_summary_downloads_total_sincedate"
+msgstr "از %1$s"
+
+#: views/statistics/rss/summary.thtml:50
+#: views/statistics/rss/summary.thtml:56
+#: views/statistics/addon.thtml:163
+#: views/statistics/addon.thtml:183
+msgid "statistics_summary_nodata"
+msgstr "هیچ اطلاعاتی هنوز وجود ندارد"
+
+#: views/statistics/rss/summary.thtml:60
+#: views/statistics/addon.thtml:195
+msgid "statistics_summary_updatepings_average"
+msgstr "متوسط کاربران Ùعال روزانه"
+
+#: views/statistics/rss/summary.thtml:52
+#: views/statistics/addon.thtml:177
+msgid "statistics_summary_updatepings_changefromprevious"
+msgstr "تغییر از تعداد قبلی"
+
+#: views/statistics/rss/summary.thtml:54
+#: views/statistics/addon.thtml:181
+#, php-format
+msgid "statistics_summary_updatepings_changefromprevious_ondate"
+msgstr "%1$s بر %2$s"
+
+#: views/statistics/rss/summary.thtml:45
+msgid "statistics_summary_updatepings_heading"
+msgstr "کاربران Ùعال روزانه"
+
+#: views/statistics/rss/summary.thtml:46
+#: views/statistics/addon.thtml:157
+msgid "statistics_summary_updatepings_total"
+msgstr "کاربران Ùعال روزانه"
+
+#: views/statistics/rss/summary.thtml:48
+#: views/statistics/addon.thtml:161
+#, php-format
+msgid "statistics_summary_updatepings_total_ondate"
+msgstr "در تاریخ %1$s"
+
+#: views/statistics/rss/summary.thtml:61
+#: views/statistics/addon.thtml:203
+msgid "statistics_summary_updatepings_weekly_average"
+msgstr "متوسط کاربران روزانه در این Ù‡Ùته"
+
+#. %s is a percentage, like '+22.33%'. It sits next to another number, so
+#. the implied meaning is 'percentage change' from the previous stat point.
+#: views/statistics/rss/summary.thtml:62
+#: views/statistics/addon.thtml:205
+msgid "statistics_summary_updatepings_weekly_change"
+msgstr "%s نسبت به Ù‡Ùتهٔ قبل"
+
+#: views/statistics/addon.thtml:65
+#: controllers/statistics_controller.php:184
+#: controllers/statistics_controller.php:282
+#, php-format
+msgid "statistics_title_addon_stats"
+msgstr "آمار %1$s"
+
+#: views/addons/themes_landing.thtml:113
+msgid "themes_landing_all_themes"
+msgstr "همهٔ تم‌ها"
+
+#: views/addons/themes_landing.thtml:109
+msgid "themes_landing_browse_themes"
+msgstr "مرور تم‌ها"
+
+#: views/users/edit.thtml:185
+msgid "user_change_email"
+msgstr "تغییر نشانی پست الکترونیکی"
+
+#: views/users/edit.thtml:169
+msgid "user_change_password"
+msgstr "تغییر گذرواژه"
+
+#: views/users/edit.thtml:96
+msgid "user_change_password_or_email"
+msgstr "تغییر گذرواژه یا نشانی پست الکترونیکی"
+
+#: controllers/users_controller.php:197
+msgid "user_confirmationcode_resent"
+msgstr "کد تأیید دوباره ارسال گردید!"
+
+#. %1 is the email address, %2 is the URL of the user registration page
+#: views/users/delete.thtml:51
+msgid "user_del_account_deleted"
+msgstr "حساب کاربری %1$s با موÙقیت حذ٠گردید. اگر بعداً بخواهید بازگردید، می‌توانید در <a href=\"%2$s\">صÙحهٔ ثبت نام کاربران</a> دوباره ثبت نام کنید."
+
+#: views/users/delete.thtml:102
+msgid "user_del_community_sad"
+msgstr "اجتماع اÙزودنی‌های موزیلا، از رÙتن شما اندوهگین است."
+
+#: views/users/delete.thtml:123
+msgid "user_del_confirm_password"
+msgstr "تأیید گذرواژه"
+
+#: views/users/delete.thtml:134
+msgid "user_del_deletenow"
+msgstr "هم‌اکنون حساب کاربری من را حذ٠کن"
+
+#. %1 is the URL of the user's info page
+#: views/users/delete.thtml:64
+msgid "user_del_error_addons"
+msgstr "اگر شما به عنوان <a href=\"%1$s\">مؤل٠یک اÙزودنی</a> ثبت شده باشید، نمی‌توانید حساب کاربری خود را حذ٠نمایید. برای حذ٠حساب کاربری خود، از یکی از اعضای دیگر تیم توسعه‌دهندگان بخواهید شما را از Ùهرست مؤلÙان اÙزودنی حذ٠کند. پس از آن خواهید توانست در این قسمت حساب کاربری خود را حذ٠نمایید."
+
+#. %1 is a link to the amo-editors mailing list
+#: views/users/delete.thtml:71
+msgid "user_del_error_addons_more_questions"
+msgstr "در صورتی که سؤال دیگری دارید، با %1$s تماس بگیرید."
+
+#: views/users/delete.thtml:78
+msgid "user_del_error_checkbox"
+msgstr "برای آن Ú©Ù‡ بتوانیم حساب کاربری شما را حذ٠کنیم، باید گزینهٔ «متوجه هستم Ú©Ù‡...» را Ùعال کنید."
+
+#: views/users/delete.thtml:84
+msgid "user_del_error_password"
+msgstr "لطÙاً برای انجام این کار، گذرواژهٔ خود را وارد نمایید."
+
+#. %1 is a link to the amo-admins mailing list
+#: views/users/delete.thtml:91
+msgid "user_del_error_unknown"
+msgstr "خطای نامعلومی در هنگام حذ٠حساب کاربری شما اتÙاق اÙتاد. لطÙاً مورد را به %1$s اطلاع دهید، Ùˆ ما عمل حذ٠را از طر٠شما انجام خواهیم داد. از مشکل پیش‌آمده متأسÙیم."
+
+#: views/users/delete.thtml:110
+msgid "user_del_header_confirm_deletion"
+msgstr "تأیید حذ٠حساب کاربری"
+
+#. %1 is the user's email address
+#: views/users/delete.thtml:100
+msgid "user_del_header_delete_account"
+msgstr "حذ٠حساب کاربری %1$s"
+
+#: views/users/delete.thtml:50
+msgid "user_del_header_farewell"
+msgstr "بدرود!"
+
+#: views/users/delete.thtml:115
+msgid "user_del_nologin"
+msgstr "از این پس قادر به ورود به وب‌گاه اÙزودنی‌های موزیلا نخواهید بود."
+
+#: views/users/delete.thtml:112
+msgid "user_del_permanently_removed_means"
+msgstr "با کلیک روی دکمهٔ «حذÙ»، حساب کاربری شما <strong>برای همیشه حذ٠خواهید گردید</strong>. این بدان معنی است Ú©Ù‡:"
+
+#: views/users/delete.thtml:116
+msgid "user_del_reviews_anonymized"
+msgstr "بررسی‌ها Ùˆ رتبه‌هایی Ú©Ù‡ به اÙزودنی‌ها داده‌اید حذ٠نخواهند شد، ولی از این پس با نام شما نمایش داده نخواهند شد."
+
+#. %1 is a link to the amo-editors mailing list
+#: views/users/delete.thtml:104
+msgid "user_del_specific_problem_editors"
+msgstr "اگر مشکل خاصی دارید Ú©Ù‡ امکان دارد بتوانیم در مورد آن به شما Ú©Ù…Ú© کنیم، لطÙاً حساب کاربری خود را Ùعلاً پاک نکنید، Ùˆ با %1$s تماس بگیرید Ùˆ ما نهایت تلاش خود را برای Ú©Ù…Ú© به رÙع آن انجام خواهیم داد."
+
+#: views/users/delete.thtml:130
+msgid "user_del_understand_permanent"
+msgstr "متوجه هستم که این عمل قابل بازگرداندن نیست."
+
+#: views/helpers/addons_html.php:192
+msgid "user_deleted_nickname"
+msgstr "کاربر حذ٠شده"
+
+#. %1 is the new email address
+#: views/users/edit.thtml:71
+msgid "user_edit_confirm_email_sent"
+msgstr "نامه‌ای به نشانی %1$s ارسال شد تا نشانی پست الکترونیکی جدیدتان را تأیید کند. برای این Ú©Ù‡ این تغییر اعمال شود، می‌توانید بر روی پیوند درون آن نامه کلیک کنید. تا آن زمان، می‌توانید با نشانی پست الکترونیک Ùعلی خود وارد شوید."
+
+#: views/users/edit.thtml:201
+msgid "user_edit_delete_user"
+msgstr "حذ٠حساب کاربری"
+
+#. This contains the email sent to users when they signed up for a new
+#. account:
+#. %1 is the confirmation URL, %2 is the current app
+#: views/users/email/confirm_plain.thtml:6
+#, php-format
+msgid "user_email_confirm_account_nopass"
+msgstr ""
+"به اÙزودنی‌های %2$s خوش آمدید.\n"
+"\n"
+"پیش از آن Ú©Ù‡ بتوانید از حساب کاربری جدید خود استÙاده کنید، باید آن را Ùعال سازید. این کار به ما اطمینان می‌دهد Ú©Ù‡ نشانی پست الکترونیکی شما معتبر است Ùˆ متعلق به شما می‌باشد.\n"
+"برای Ùعال کردن حساب کاربری‌تان، بر روی پیوند زیر کلیک کنید یا Ú©Ù„ أن را درون نوار مکان مرورگر خود بچسبانید:\n"
+"\n"
+"%1$s\n"
+"\n"
+"هنگامی Ú©Ù‡ حساب کاربری‌تان را با موÙقیت Ùعال کردید، می‌توانید این نامه را حذ٠کنید.\n"
+"\n"
+"از پیوستن شما به اÙزودنی‌های %2$s متشکریم\n"
+"--تیم اÙزودنی‌های %2$s"
+
+#. %1 is the confirmation url, %2 is the application name
+#: views/users/email/emailchange_plain.thtml:5
+msgid "user_email_confirm_emailchange"
+msgstr ""
+"شما درخواست تغییر نشانی پست الکترونیکی خود در اÙزودنی‌های %2$s داده‌اید.\n"
+"\n"
+"به منظور تأیید نشانی جدید، بر روی پیوند زیر کلیک کنید یا کل آن را درون نوار مکان مرورگرتان بچسبانید:\n"
+"\n"
+"%1$s\n"
+"\n"
+"برای تأیید نشانی جدید Û´Û¸ ساعت Ùرصت دارید. اگر از تغییر نشانی پست الکترونیکی‌تان منصر٠شدید۷ می‌توانید این نامه را نادیده بگیرید.\n"
+"\n"
+"با تشکر!\n"
+"-- تیم اÙزودنی‌های %2$s"
+
+#: controllers/users_controller.php:168
+#, php-format
+msgid "user_email_confirm_subject"
+msgstr "از پیوستن شما به اÙزودنی‌های %s متشکریم"
+
+#. This is the password reset email
+#. %1 is the pw reset URL, %2 is the application
+#: views/users/email/pwreset_plain.thtml:5
+#, php-format
+msgid "user_email_pwreset"
+msgstr ""
+"بازنشانی گذرواژهٔ اÙزودنی‌های %2$s\n"
+"\n"
+"درخواستی برای بازنشانی گذرواژهٔ این حساب کاربری در addons.mozilla.org دریاÙت شده است. برای تغییر این گذرواژه، لطÙاً بر روی پیوند زیر کلیک کنید، یا آن را درون نوار مکان مرورگر خود بچسبانید:\n"
+"\n"
+"%1$s\n"
+"\n"
+"اگر شما درخواست ارسال این نامه را نداده‌اید، نیازی به عملی از سوی شما نیست.\n"
+"\n"
+"با تشکر،\n"
+"-- تیم اÙزودنی‌های %2$s"
+
+#: controllers/users_controller.php:245
+#, php-format
+msgid "user_email_pwreset_subject"
+msgstr "بازنشانی گذرواژهٔ اÙزودنی‌های %s"
+
+#: views/users/emailchange.thtml:50
+msgid "user_emailchange_error"
+msgstr "خطا!"
+
+#. %1 is the application name
+#: controllers/users_controller.php:533
+msgid "user_emailchange_subject"
+msgstr "لطÙاً تغییر نشانی پست الکترونیکی خود در اÙزودنی‌های %1$s را تأیید کنید"
+
+#: views/users/emailchange.thtml:48
+msgid "user_emailchange_success"
+msgstr "موÙقیت!"
+
+#. %1 is the new email address
+#: views/users/emailchange.thtml:49
+msgid "user_emailchange_successful_description"
+msgstr "نشانی پست الکترونیکی شما با موÙقیت تغییر یاÙت. از این پس، لطÙاً از %1$s برای ورود استÙاده نمایید."
+
+#: views/users/edit.thtml:134
+#: views/admin/users_edit.thtml:111
+msgid "user_form_bio"
+msgstr "دربارهٔ من"
+
+#: views/users/edit.thtml:135
+#: views/admin/users_edit.thtml:112
+msgid "user_form_bio_description"
+msgstr "اگر مایل هستید، خود را به اجتماع کاربران معرÙÛŒ کنید! این متن در صÙحهٔ اطلاعات کاربر شما در دسترس همگان قرار می‌گیرد. خطوط جدید دست‌نخورده باقی می‌مانند ولی استÙاده از HTML مجاز نیست."
+
+#: views/users/pwreset.thtml:77
+#: views/users/register.thtml:73
+#: views/users/edit.thtml:181
+msgid "user_form_confirmpassword"
+msgstr "تأیید گذرواژه"
+
+#: views/users/edit.thtml:145
+msgid "user_form_display_collections"
+msgstr "مجموعه‌هایی Ú©Ù‡ ایجاد کرده‌ام در صÙحهٔ اطلاعات کاربری‌ام نمایش داده شود"
+
+#: views/users/edit.thtml:149
+msgid "user_form_display_collections_fav"
+msgstr "مجموعه‌های محبوبم در صÙحهٔ اطلاعات کاربری‌ام نمایش داده شود"
+
+#: views/users/edit.thtml:86
+#, php-format
+msgid "user_form_editprofile"
+msgstr "ویرایش مجموعه تنظیمات کاربری %s"
+
+#: views/users/pwreset.thtml:52
+#: views/users/login.thtml:81
+#: views/users/register.thtml:63
+#: views/users/edit.thtml:187
+msgid "user_form_email"
+msgstr "نشانی پست الکترونیکی"
+
+#: views/users/register.thtml:78
+#: views/users/edit.thtml:103
+#: views/admin/users_edit.thtml:76
+msgid "user_form_firstname"
+msgstr "نام"
+
+#: views/users/register.thtml:94
+#: views/users/edit.thtml:119
+#: views/admin/users_edit.thtml:91
+msgid "user_form_hideemail"
+msgstr "پنهان کردن نشانی پست الکترونیکی"
+
+#: views/users/register.thtml:98
+#: views/users/edit.thtml:123
+#: views/admin/users_edit.thtml:99
+msgid "user_form_homepage"
+msgstr "نشانی وب‌گاه"
+
+#: views/users/register.thtml:84
+#: views/users/edit.thtml:109
+#: views/admin/users_edit.thtml:81
+msgid "user_form_lastname"
+msgstr "نام خانوادگی"
+
+#: controllers/users_controller.php:333
+msgid "user_form_login"
+msgstr "ورود کاربر"
+
+#: views/users/pwreset.thtml:72
+#: views/users/edit.thtml:176
+msgid "user_form_newpassword"
+msgstr "گذرواژهٔ جدید"
+
+#: views/users/register.thtml:89
+#: views/users/edit.thtml:114
+#: views/admin/users_edit.thtml:86
+msgid "user_form_nickname"
+msgstr "نام مستعار"
+
+#: views/users/edit.thtml:171
+msgid "user_form_oldpassword"
+msgstr "گذرواژهٔ قدیمی"
+
+#: views/users/edit.thtml:97
+#: views/users/edit.thtml:200
+msgid "user_form_otheractions"
+msgstr "دیگر کارها"
+
+#: views/users/login.thtml:85
+#: views/users/register.thtml:68
+msgid "user_form_password"
+msgstr "گذرواژه"
+
+#: controllers/users_controller.php:93
+msgid "user_form_registration"
+msgstr "ثبت نام کاربر جدید"
+
+#: views/users/login.thtml:90
+msgid "user_form_remember_me"
+msgstr "من را روی این رایانه به خاطر بسپار"
+
+#: views/admin/users_edit.thtml:95
+msgid "user_form_showsandbox"
+msgstr "نمایش گودال ماسه‌بازی؟"
+
+#: views/users/edit.thtml:205
+msgid "user_form_submit_edit"
+msgstr "ارسال"
+
+#: views/users/login.thtml:93
+msgid "user_form_submit_login"
+msgstr "ورود"
+
+#: views/users/register.thtml:113
+msgid "user_form_submit_register"
+msgstr "ثبت نام"
+
+#: views/users/info.thtml:75
+#, php-format
+msgid "user_info_usersince"
+msgstr "کاربر اÙزودنی‌های %s از تاریخ"
+
+#: views/users/login.thtml:102
+msgid "user_login_register_link"
+msgstr "ایجاد یک حساب کاربری جدید"
+
+#: views/users/edit.thtml:160
+msgid "user_notifications_item_compat"
+msgstr "سازگاری اÙزودنی‌ها (به شدت توصیه می‌شود)"
+
+#: views/users/edit.thtml:161
+msgid "user_notifications_item_events"
+msgstr "رویدادها و مسابقه‌های پیش رو"
+
+#: views/users/edit.thtml:156
+msgid "user_notifications_none_available"
+msgstr "در حال حاضر هیچ اعلانی برای تنظیم کردن وجود ندارد."
+
+#: views/users/edit.thtml:158
+msgid "user_notifications_select_topics"
+msgstr "ممکن است موزیلا هر چند وقت یک بار دربارهٔ انتشارهای پیش رو Ùˆ رویدادهای مربوط به اÙزودنی‌ها نامه‌ای الکترونیکی ارسال کند. لطÙاً موضوعات مورد علاقهٔ خود را در ادامه انتخاب کنید:"
+
+#: views/users/edit.thtml:164
+msgid "user_notifications_specific_contact"
+msgstr "موزیلا حق تماس با شما را به صورت شخصی در خصوص موارد مربوط به اÙزودنی‌های‌تان برای خود محÙوظ Ù†Ú¯Ù‡ می‌دارد."
+
+#: controllers/users_controller.php:543
+msgid "user_profile_edit_error"
+msgstr "تغییراتی Ú©Ù‡ ایجاد کردید باعث ایجاد خطا گردید. لطÙاً خطاها را اصلاح کنید Ùˆ Ùرم را دوباره ارسال نمایید."
+
+#: controllers/users_controller.php:540
+msgid "user_profile_saved"
+msgstr "مجموعه تنظیمات به‌هنگام شد."
+
+#: views/users/pwreset.thtml:65
+#, php-format
+msgid "user_pwreset_for_email"
+msgstr "گذرواژه برای %s بازنشانده شد"
+
+#: controllers/users_controller.php:226
+msgid "user_pwreset_header"
+msgstr "گذرواژه بازنشانده شد"
+
+#: views/users/login.thtml:103
+msgid "user_pwreset_link"
+msgstr "گذرواژه‌تان را Ùراموش کرده‌اید؟"
+
+#: controllers/users_controller.php:248
+msgid "user_pwreset_link_sent"
+msgstr "پیوند بازنشانی گذرواژه به نشانی پست الکترونیکی شما ارسال شد."
+
+#: controllers/users_controller.php:304
+msgid "user_pwreset_okay"
+msgstr "گذرواژه با موÙقیت بازنشانده شد."
+
+#: views/users/pwreset.thtml:82
+msgid "user_pwreset_submit_changepw"
+msgstr "ارسال تغییر گذرواژه"
+
+#: views/users/pwreset.thtml:57
+msgid "user_pwreset_submit_sendlink"
+msgstr "ارسال پیوند بازنشانی گذرواژه"
+
+#: views/users/register_complete.thtml:51
+#, php-format
+msgid "user_register_amo_link"
+msgstr "اÙزودنی‌های %s"
+
+#. %1 is the user's email address, %2 is the current app
+#: views/users/activatefirst.thtml:49
+#, php-format
+msgid "user_register_click_confirm_link"
+msgstr "پیوندی برای Ùعال‌سازی حساب کاربری شما به نشانی پست الکترونیکی‌تان %1$s Ùرستاده گردید. پیش از آن Ú©Ù‡ بتوانید وارد وب‌گاه اÙزودنی‌های %2$s شوید باید بر روی آن کلیک نمایید."
+
+#. %1 is the user's email address
+#: views/users/register_complete.thtml:49
+#, php-format
+msgid "user_register_confirm_email_sent"
+msgstr "یک نامهٔ الکترونیک به نشانی شما %1$s Ùرستاده شد تا حساب کاربری‌تان تأیید شود. پیش از آن Ú©Ù‡ بتوانید وارد شوید، باید حساب کاربری‌تان را با کلیک بر روی پیوند موجود در این نامه Ùعال کنید."
+
+#: views/users/activatefirst.thtml:51
+msgid "user_register_confirmation_link_text"
+msgstr "ارسال مجدد پیام تأیید"
+
+#: views/users/register_complete.thtml:47
+msgid "user_register_congratulations"
+msgstr "به شما تبریک می‌گوییم! حساب کاربری شما با موÙقیت ایجاد گردید."
+
+#: views/users/register.thtml:50
+msgid "user_register_details"
+msgstr "<p>اگر تنها مایل به بارگیری Ùˆ نصب اÙزودنی‌های عمومی می‌باشید، ثبت نام در وب‌گاه اÙزودنی‌های موزیلا <strong>ضروری نیست</strong>.</p><p>تنها زمانی نیاز به ثبت نام کردن دارید Ú©Ù‡:</p><ul><li>می‌خواهید برای اÙزودنی‌ها بررسی ارسال کنید</li><li>خود یک توسعه‌دهندهٔ اÙزودنی هستید Ú©Ù‡ می‌خواهید اÙزودنی‌تان برای میزبانی به وب‌گاه اÙزودنی‌های موزیلا ارسال شود</li></ul><p>پس از انجام ثبت نام با موÙقیت، شما نامه‌ای الکترونیکی در تأیید نشانی پست الکترونیکی وارد شده‌تان دریاÙت می‌نمایید. لطÙاً برای تأیید حساب کاربری خود، از دستورالعمل موجود در آن نامه استÙاده کنید.</p><p>اگر مایل هستید می‌توانید <a href='%1$s' title='یادداشت‌های قانونی'>یادداشت‌های قانونی</a> ما Ùˆ <a href='%2$s' title='سیاست Ø­Ùظ حریم خصوصی'>سیاست Ø­Ùظ حریم خصوصی</a> ما را مطالعه نمایید.</p>"
+
+#. %1 is the link to the "resend confirmation code" page
+#: views/users/activatefirst.thtml:51
+#, php-format
+msgid "user_register_resend_confirmation_link"
+msgstr "اگر نامهٔ تأییدیه را دریاÙت نکرده‌اید، اطمینان حاصل نمایید Ú©Ù‡ سرویس پست الکترونیکی شما آن را به عنوان «هرزنامه» برچسب نزده باشد. اگر نیاز دارید، می‌توانید از ما درخواست %1$s به نشانی پست الکترونیکی Ùوق را بنمایید."
+
+#. %1 is the link to the Mozilla Add-ons front page
+#: views/users/register_complete.thtml:51
+#, php-format
+msgid "user_register_welcome"
+msgstr "از ثبت نام شما متشکریم، و به %1$s خوش آمدید!"
+
+#: views/users/register.thtml:49
+msgid "user_register_welcome_header"
+msgstr "به وب‌گاه اÙزودنی‌های موزیلا (AMO) خوش آمدید!"
+
+#: views/users/register.thtml:81
+#: views/users/edit.thtml:106
+msgid "user_required_firstlast_or_nickname"
+msgstr "نام، نام خانوادگی، یا نام مستعار مورد نیاز است."
+
+#: views/users/edit.thtml:94
+#: views/users/edit.thtml:142
+msgid "user_tab_collections"
+msgstr "مجموعه‌ها"
+
+#: views/users/edit.thtml:95
+#: views/users/edit.thtml:154
+msgid "user_tab_notifications"
+msgstr "اعلامیه‌ها"
+
+#: views/users/edit.thtml:93
+#: views/users/edit.thtml:101
+msgid "user_tab_profile"
+msgstr "مجموعه تنظیمات کاربر"
+
+#: controllers/users_controller.php:209
+msgid "user_verified_okay"
+msgstr "با موÙقیت تأیید گردید!"
+
+#: controllers/users_controller.php:723
+msgid "users_delete_pagetitle"
+msgstr "حذ٠حساب کاربری"
+
+#: controllers/users_controller.php:414
+msgid "users_edit_pagetitle"
+msgstr "ویرایش حساب کاربر"
+
+#: views/users/info.thtml:71
+msgid "users_info_aboutme"
+msgstr "دربارهٔ من"
+
+#: views/users/info.thtml:96
+#, php-format
+msgid "users_info_addons_by_user"
+msgstr "اÙزودنی‌های %1$s"
+
+#: views/users/info.thtml:51
+msgid "users_info_author_name"
+msgstr "نام"
+
+#: views/users/info.thtml:48
+msgid "users_info_author_profile"
+msgstr "مجموعه تنظیمات کاربر"
+
+#. %s is the user name
+#: views/users/info.thtml:137
+msgid "users_info_collections_by_user"
+msgstr "مجموعه‌های ایجاد شده توسط %s"
+
+#: views/users/info.thtml:66
+msgid "users_info_email"
+msgstr "نشانی پست الکترونیکی"
+
+#: views/users/info.thtml:155
+msgid "users_info_fav_collections_by_user"
+msgstr "مجموعه‌های محبوب"
+
+#: views/users/info.thtml:61
+msgid "users_info_homepage"
+msgstr "صÙحهٔ آغازه"
+
+#: views/users/info.thtml:56
+msgid "users_info_nickname"
+msgstr "نام مستعار"
+
+#: controllers/users_controller.php:707
+#, php-format
+msgid "users_info_pagetitle"
+msgstr "اطلاعات کاربری %1$s"
+
+#. %1 is the user's name
+#: views/users/info.thtml:116
+msgid "users_info_reviews_by_user"
+msgstr "بررسی توسط %s"
+
+#: controllers/users_controller.php:330
+#: controllers/users_controller.php:332
+msgid "users_login_pagetitle"
+msgstr "ورود کاربر"
+
+#. %1 is the link to the sandbox/policy explanation page
+#. This message is for a specific add-on not found
+#: views/users/login.thtml:53
+#, php-format
+msgid "users_login_sandbox_display_warning"
+msgstr "اÙزودنی Ú©Ù‡ به دنبالش هستید اکنون در گودال ماسه‌بازی است. اگر یک حساب کاربری در وب‌گاه اÙزودنی‌های موزیلا دارید، لطÙاً وارد شوید، یا <a href=\"%1$s\">در مورد گودال ماسه‌بازی بیشتر بدانید</a>."
+
+#. %1 is the link to the sandbox/policy explanation page
+#. This message is for any given sandbox-related page not found
+#: views/users/login.thtml:56
+#, php-format
+msgid "users_login_sandbox_page_warning"
+msgstr "صÙحه‌ای Ú©Ù‡ به دنبالش هستید بخشی از گودال ماسه‌بازی است. اگر یک حساب کاربری در وب‌گاه اÙزودنی‌های موزیلا دارید، لطÙاً وارد شوید، یا <a href=\"%1$s\">در مورد گودال ماسه‌بازی بیشتر بدانید</a>."
+
+#: controllers/users_controller.php:223
+#: controllers/users_controller.php:225
+msgid "users_pwreset_pagetitle"
+msgstr "بازنشانی گذرواژهٔ کاربر"
+
+#: controllers/users_controller.php:90
+#: controllers/users_controller.php:92
+msgid "users_register_pagetitle"
+msgstr "ثبت نام کاربر جدید"
+
+#. %1$s is an addon name, like <a>Firebug</a>
+#. %2$s is a version number, like <a>1.2</a>
+#: views/versions/license.thtml:52
+msgid "versions_license_header_source"
+msgstr "مجوز کد منبع برای اÙزودنی %1$s نسخهٔ %2$s"
+
+#: views/addons/category_landing.thtml:147
+msgid "view_recently_added"
+msgstr "مشاهدهٔ همهٔ موارد به تازگی اضاÙÙ‡ شده"
+
+#: views/addons/category_landing.thtml:161
+msgid "view_top_downloads"
+msgstr "مشاهدهٔ همهٔ موارد با بیشترین تعداد بارگیری"
+
+#: views/addons/category_landing.thtml:175
+msgid "view_top_rated"
+msgstr "مشاهدهٔ همهٔ موارد با بالاترین رتبه"
+
+#~ msgid "addon_slider_tooltip_next"
+#~ msgstr "اÙزودنی بعدی"
+#~ msgid "addon_slider_tooltip_previous"
+#~ msgstr "اÙزودنی قبلی"
+#~ msgid "addons_display_version_history"
+#~ msgstr "تاریخچهٔ کامل نسخه‌ها"
+#~ msgid "addons_home_newest_header"
+#~ msgstr "جدیدترین اÙزودنی‌ها:"
+#~ msgid "addons_home_popular_header"
+#~ msgstr "محبوب‌ترین اÙزودنی‌ها:"
+#~ msgid "addons_home_recommended_header"
+#~ msgstr "پیشنهاد ما:"
+#~ msgid "addons_home_updated_header"
+#~ msgstr "اÙزودنی‌های به تازگی به‌هنگام شده:"
+#~ msgid "addons_home_view_all"
+#~ msgstr "مشاهدهٔ همهٔ اÙزودنی‌ها"
+#~ msgid "category_extra_allrecommended"
+#~ msgstr "مشاهدهٔ تمام اÙزودنی‌های پیشنهاد شده"
+#~ msgid "category_extra_highestrated"
+#~ msgstr "تقدم با بالاترین رتبه‌ها"
+#~ msgid "category_extra_lastupdated"
+#~ msgstr "تقدم با تازه‌ترین به‌هنگام‌سازی‌ها"
+#~ msgid "category_extra_mostpopular"
+#~ msgstr "تقدم با محبوب‌ترین‌ها"
+#~ msgid "collections_detail_js_loading"
+#~ msgstr "در حال بارگیری"
+#~ msgid "collections_detail_more_info"
+#~ msgstr "نمایش اطلاعات بیشتر"
+#~ msgid "devcp_addon_status_criteria_review"
+#~ msgstr ""
+#~ "چندین بررسی اÙزودنی توسط کاربران (می‌تواند شامل بررسی‌های خارجی هم باشد)."
+#~ msgid "devcp_submit_accept_dev_agreement"
+#~ msgstr "قبول دارم"
+#~ msgid "devcp_submit_decline_dev_agreement"
+#~ msgstr "قبول ندارم"
+#~ msgid "editors_submissiontype_new"
+#~ msgstr "جدید"
+#~ msgid "editors_submissiontype_updated"
+#~ msgstr "به‌هنگام شده"
+#~ msgid "editors_th_addon_age"
+#~ msgstr "سن اÙزودنی"
+#~ msgid "editors_th_addontypes"
+#~ msgstr "انواع اÙزودنی"
+#~ msgid "editors_th_applications"
+#~ msgstr "برنامه‌ها"
+#~ msgid "editors_th_platforms"
+#~ msgstr "سکوهای نرم‌اÙزاری"
+#~ msgid "editors_th_submissiontypes"
+#~ msgstr "انواع ارسال"
+#~ msgid "forum_save"
+#~ msgstr "ذخیره کردن"
+#~ msgid "home"
+#~ msgstr "آغازه"
+#~ msgid "nav_category_plugins"
+#~ msgstr "متصل‌شونده‌ها"
+#~ msgid "pagination_page_number_title"
+#~ msgstr "این صÙحهٔ %1$s از %2$s است"
+#~ msgid "search_matching_addons_number"
+#~ msgid_plural "search_matching_addons_number"
+#~ msgstr[0] "%s اÙزودنی مطابق"
+#~ msgstr[1] "%s اÙزودنی مطابق"
+
diff --git a/site/app/locale/fa/images/sandbox-review.png b/site/app/locale/fa/images/sandbox-review.png
new file mode 100644
index 0000000..b787252
--- /dev/null
+++ b/site/app/locale/fa/images/sandbox-review.png
Binary files differ
diff --git a/site/app/locale/fa/pages/error404.thtml b/site/app/locale/fa/pages/error404.thtml
new file mode 100644
index 0000000..3f9adb5
--- /dev/null
+++ b/site/app/locale/fa/pages/error404.thtml
@@ -0,0 +1,16 @@
+<h1>متأسÙیم، ولی نتوانستیم آنچه به دنبالش هستید را پیدا کنیم.</h1>
+
+<p>صÙحه یا پرونده‌ای Ú©Ù‡ درخواست دادید روی پایگاه ما پیدا نشد. ممکن است بر روی پیوندی قدیمی یا اشتباه کلیک کرده باشید، یا نشانی مورد نظر خود را اشتباه وارد کرده باشید.</p>
+
+<ul>
+<li>اگر نشانی را خود وارد کرده‌اید، لطÙاً املای آن را مجدداً کنترل نمایید.</li>
+<li>اگر بر روی پیوندی در جای دیگری کلیک کرده‌اید، لطÙاً مراتب را به <a href="mailto:webmaster@mozilla.com" title="Page Not Found on Mozilla.com">webmaster@mozilla.com</a> گزارش دهید. به ما بگویید از کجا به این وب‌گاه آمده‌اید Ùˆ به دنبال Ú†Ù‡ بودید، Ùˆ ما حداکثر تلاشمان را می‌کنیم تا مشکل را برطر٠سازیم.</li>
+</ul>
+
+<p>یا می‌توانید به یکی از صÙحات محبوب وب‌گاه ما بروید.</p>
+
+<ul>
+<li>آیا علاقه‌مند به مشاهدهٔ <a href="%1$s">Ùهرست اÙزودنی‌های محبوب</a> هستید؟</li>
+<li>آیا می‌خواهید <a href="%2$s">به دنبال اÙزودنی‌ها جستجو کنید</a>ØŸ ممکن است بخواهید به <a href="%2$s">صÙحهٔ جستجو</a> بروید یا از Ùیلد جستجو در بالای همین صÙحه استÙاده کنید.</li>
+<li>اگر مایل هستید از ابتدا شروع کنید، کاÙÛŒ است به <a href="%3$s">صÙحهٔ اصلی اÙزودنی‌ها</a> بروید.</li>
+</ul>
diff --git a/site/app/locale/fa/pages/faq.thtml b/site/app/locale/fa/pages/faq.thtml
new file mode 100644
index 0000000..d045d14
--- /dev/null
+++ b/site/app/locale/fa/pages/faq.thtml
@@ -0,0 +1,56 @@
+<h1>Frequently Asked Questions</h1>
+
+<p>This FAQ for the <a href="http://addons.mozilla.org">AMO site</a> addresses some topics not currently covered by the Firefox Support website. The Support website includes introductory information about <a href="http://support.mozilla.com/kb/Customizing+Firefox+with+add-ons">customizing Firefox with add-ons</a> as well as articles on:</p>
+
+<ul>
+ <li> Troubleshooting <a href="http://support.mozilla.com/kb/Unable+to+install+add-ons">add-on installation</a>, <a href="http://support.mozilla.com/kb/Troubleshooting+plugins">plugins</a> &amp; <a href="http://support.mozilla.com/kb/Troubleshooting+extensions+and+themes">general issues</a>.</li>
+ <li> <a href="http://support.mozilla.com/kb/Uninstalling+add-ons">How to uninstall add-ons</a> and <a href="http://support.mozilla.com/kb/Cannot+uninstall+an+add-on">troubleshooting uninstallation</a>.</li>
+ <li> <a href="http://support.mozilla.com/kb/Gray+bar+below+the+status+bar">Dealing with problematic add-ons / Gray Bar issue</a></li>
+</ul>
+
+<p></p>
+
+<h2>Add-on Questions</h2>
+<dl>
+<dt>What is an Add-on?</dt>
+<dd>Add-ons let you add features which aren't part of the standard application. Themes change appearance without changing functionality. Search Plugins and Dictionaries/Language Packs add additional search engines and language support. Extensions add more extensive features to the browser; some add simple toolbars while others can add a wide range of new features.</dd>
+
+<dt>Are add-ons easy to install?</dt>
+<dd>Yes! Add-ons are very easy to install. They're generally much smaller than a normal application and download very quickly. If you don't like one, they are just as easy to remove or disable. Also, if an update is available for one of your add-ons, Firefox will inform you and let you upgrade with one click.</dd>
+
+<dt>How do I manage an add-on?</dt>
+<dd>In Firefox, go to "Add-ons" in the Tools menu to manage Themes and Extensions. If your Extension has special options, you can see them in the Extensions section of the Add-ons window. From here, you can also disable and uninstall add-ons. Dictionaries are installed as Extensions. Search Plugins can be managed in the Search Bar.</dd>
+
+<dt>Can add-ons make Firefox slower?</dt>
+<dd>In most cases, add-ons do not cause a perceivable slowdown in Firefox. However, since they are applications some may affect the performance of Firefox depending on your system configuration. If you suspect that an add-on is affecting the way Firefox runs on your machine try disabling it.</dd>
+
+<dt>Why would I disable an add-on?</dt>
+<dd>Disabling an add-on prevents it from loading when you start Firefox, but it doesn't remove the add-on or any of its settings. Enabling the add-on again will bring it back to where it was when you disabled it. For add-ons that you want to turn off without removing, disabling is the way to go.</dd>
+
+<dt>How do I backup all of the add-ons and themes that I've installed?</dt>
+<dd>You can backup your profile directory which will also backup your add-ons and themes. A third party application like MozBackup can help you with this.</dd>
+</dl>
+
+<h2>Website questions</h2>
+<dl>
+<dt>I see several add-ons which provide the same capabilities. How do I decide which one is best?</dt>
+<dd>In general, you can look at ratings and downloads which will give you an idea. Good add-ons tend to be downloaded more than bad ones. However, it's also easy to install both add-ons and decide which one you want to use. You may decide after trying them that you want to use both!</dd>
+
+<dt>I see a great add-on but it says that it's only compatible with Firefox 2.x. Can I still install it in Firefox 3.x?</dt>
+<dd>In general, no. Firefox 3.x has a number of new features and a large majority of add-on developers have updated their add-ons to support 3.x. If the add-on only supports Firefox 2, try searching for that add-on's title. In many cases there will be a new version that supports Firefox 3 with the same or similar title.</dd>
+
+<dt>I installed a new theme but would like to revert back to the Firefox default theme. How do I do that?</dt>
+<dd>Go to "Add-ons" in the "Tools" menu. Click the "Themes" section and from here you can select the default theme, or any others you have installed.</dd>
+
+<dt>If I have an issue with an add-on, should I contact Mozilla?</dt>
+<dd>Add-ons, with a few exceptions, are created by the community and not Mozilla. The best thing to do is to contact the developer directly with your question. To find contact info for a developer, click their name in the byline on the Add-on listing page.</dd>
+
+<dt>How are add-ons reviewed?</dt>
+<dd>Public add-ons are reviewed by our dedicated and talented editorial team. They review the code of all public add-ons and also test the add-ons to make sure that they are accurately described.</dd>
+
+<dt>I've upgraded to Firefox 3.1 but my add-on no longer works? Why is that?</dt>
+<dd>Most of our add-ons are now Firefox 3.1 compatible, and every day more are added. If your add-on worked on 3.0 but not 3.1, chances are they're already working on it. When they do upgrade their add-on, Firefox will notify you about the upgrade.</dd>
+
+<dt>What are experimental add-ons?</dt>
+<dd>Experimental Add-ons are generally the newest add-ons hosted on AMO. These Add-ons have not undergone the editorial review required to become public and are generally at some sort of prerelease level of quality. Since they haven't been reviewed, there is a higher chance of something going wrong when you install one.</dd>
+</dl>
diff --git a/site/app/locale/fa/pages/nomination.thtml b/site/app/locale/fa/pages/nomination.thtml
new file mode 100644
index 0000000..85c5118
--- /dev/null
+++ b/site/app/locale/fa/pages/nomination.thtml
@@ -0,0 +1,10 @@
+<p>اÙزودنی‌های گودال ماسه‌بازی را می‌توان به عنوان بخشی از وب‌گاه عمومی نامزد کرد تا پس از مورد بررسی قرار گرÙتن توسط یک ویرایش‌گر برای استÙادهٔ همهٔ کاربران در دسترس قرار گیرند. برای بهترین نتیجه، لطÙاً به این موارد توجه کنید:</p>
+<ul>
+ <li>تصاویر پیش‌نمایش برای تم‌ها الزامی هستند Ùˆ برای بقیهٔ انواع اÙزودنی‌ها قویاً توصیه می‌شوند.</li>
+ <li>اÙزودنی باید برای جمع‌آوری بررسی‌ها Ùˆ نظرات کاربران مدت کاÙÛŒ در گودال ماسه‌بازی مانده باشد.<b>برای عمومی شدن اÙزودنی، داشتن بررسی از طر٠کاربران الزامی است.</b></li>
+ <li>اÙزودنی‌های عمومی سطح Ú©ÛŒÙÛŒ بالاتری از اÙزودنی‌های گودال ماسه‌بازی دارند Ùˆ باید وب را گسترش بدهند.</li>
+ <li>شرایط کامل نامزدی در <a href="%s">سیاست اÙزودنی‌ها</a> ذکر شده است.</li>
+</ul>
+<p>اگر اÙزودنی شما واجد شرایط بالا است، می‌توانید با تکمیل Ùیلد زیر آن را نامزد کنید. در مورد وضعیت نامزدی اÙزودنی شما، از طریق پست الکترونیکی با شما تماس گرÙته خواهد شد.</p>
+
+<p>برای نامزد کردن اÙزودنی خود، لطÙاً شرح دهید Ú©Ù‡ آن را چگونه آزمایش کرده‌اید (Ùˆ این Ú©Ù‡ دارای خطا Ùˆ اخطار نیست) Ùˆ به Ú†Ù‡ نحوی برای کاربران وب Ù…Ùید است. شما همچنین می‌توانید پیوندهایی به بررسی‌های خارج از این وب‌گاه در مورد اÙزودنی‌تان ارائه دهید.</p>
diff --git a/site/app/locale/fa/pages/policy.thtml b/site/app/locale/fa/pages/policy.thtml
new file mode 100644
index 0000000..331355b
--- /dev/null
+++ b/site/app/locale/fa/pages/policy.thtml
@@ -0,0 +1,111 @@
+<h1>سیاست اÙزودنی‌ها</h1>
+
+<h2>گودال ماسه‌بازی چیست؟</h2>
+<p>از %s بازدید نمایید.</p>
+
+<h2>Ú†Ù‡ اÙزودنی‌هایی درون گودال ماسه‌بازی قرار می‌گیرند؟</h2>
+<p>گودال ماسه‌بازی محلی است Ú©Ù‡ تمام اÙزودنی‌هایی Ú©Ù‡ در وب‌گاه اÙزودنی‌های موزیلا میزبانی می‌شوند، برای شروع در آن وارد می‌شوند. نسخه‌های جدید اÙزودنی‌های عمومی Ùˆ نیز تمام نسخه‌های اÙزودنی‌های غیر عمومی در آن قرار دارند. هنگامی Ú©Ù‡ یک اÙزودنی جدید یا به‌هنگام‌سازی یک اÙزودنی موجود به وب‌گاه اÙزودنی‌های موزیلا ارسال می‌شود، در گودال ماسه‌بازی قرار می‌گیرد.</p>
+
+<p>برخی اÙزودنی‌ها، Ùˆ نسخه‌های خاصی از آنها، پس از آن Ú©Ù‡ رویهٔ بررسی مشخص می‌کند Ú©Ù‡ برای نمایش به عموم مناسب هستند، عمومی می‌شوند. برخی دیگر برای مدت نامعلومی در گودال ماسه‌بازی باقی می‌مانند، Ùˆ برای کاربرانی Ú©Ù‡ مایل به استÙاده از نرم‌اÙزارهای آزمایشی هستند از طریق مرور Ùهرست اÙزودنی‌های گودال ماسه‌بازی در دسترس هستند.</p>
+
+<h2>اÙزودنی‌ها چگونه عمومی می‌شوند؟</h2>
+
+<p>اÙزودنی‌ها توسط کاربرانی از وب‌گاه اÙزودنی‌های موزیلا Ú©Ù‡ گودال ماسه‌بازی را مشاهده می‌کنند Ùˆ اÙزودنی‌های موجود در آن را آزمایش می‌کنند، بررسی می‌شوند. بررسی‌های نوشته شده توسط کاربران وب‌گاه اÙزودنی‌های موزیلا مشخص می‌کنند Ú©Ù‡ آیا اÙزودنی به میزان کاÙÛŒ Ù…Ùید است، Ùˆ با Ú©ÛŒÙیت مورد نیاز برای نمایش به تمام کاربران ÙایرÙاکس نوشته شده است یا خیر. این بررسی‌ها، در کنار بررسی‌ها Ùˆ وارسی‌های احتمالی دیگر تیم وب‌گاه اÙزودنی‌های موزیلا، تعیین می‌کنند Ú©Ù‡ آیا اÙزودنی باید عمومی شود، یا برای دسترسی عمومی نیاز به کار بیشتری دارد، یا اصولاً برای نمایش داده شدن روی وب‌گاه اÙزودنی‌های موزیلا خارج از گودال ماسه‌بازی مناسب نیست.</p>
+
+<h2>چگونه درخواست عمومی شدن اÙزودنی خود را بدهم؟</h2>
+
+<p>اگر Ùکر می‌کنید Ú©Ù‡ اÙزودنی‌تان (Ùˆ رÙتارتان!) واجد شرایط اÙزودنی‌های عمومی است، می‌توانید آن را از «ابزارهای توسعه‌دهنده» نامزد کنید.</p>
+
+<h2>شرایط اÙزودنی‌های عمومی چیست؟</h2>
+
+<p>اÙزودنی‌هایی Ú©Ù‡ در وب‌گاه اÙزودنی‌های موزیلا عمومی می‌شوند باید دارای Ú©ÛŒÙیت بالایی باشند، Ùˆ تجربهٔ بهبودیاÙته‌ای از وب در اختیار کاربران قرار دهند. ما هنگام تصمیم‌گیری در مورد این Ú©Ù‡ آیا یک اÙزودنی برای بخش عمومی وب‌گاه اÙزودنی‌های موزیلا مناسب است یا خیر به دنبال موارد زیر هستیم:</p>
+
+<h3>آیا شما به سرعت پاسخ می‌دهید؟</h3>
+
+<p>ما انتظار داریم Ú©Ù‡ مؤلÙÛŒ Ú©Ù‡ اÙزودنی خود را در اختیار کاربران بسیار زیاد ÙایرÙاکس قرار می‌دهد، به گزارش اشکالات به سرعت پاسخ دهد، اطلاعات تماس خود را به‌هنگام Ù†Ú¯Ù‡ دارد، Ùˆ اÙزودنی خود را با انتشار نسخه‌های جدید ÙایرÙاکس یا تغییر سیاست‌های وب‌گاه اÙزودنی‌های موزیلا به سرعت به‌هنگام سازد. این بدان معنی نیست Ú©Ù‡ شما باید به همهٔ سؤالاتی Ú©Ù‡ مطرح می‌شود پاسخ دهید، یا حتی باید تمام اشکالات را رÙع سازید، ولی ما توقع داریم به هر مورد بر اساس شدت آن پاسخی به نحو مناسب بدهید.</p>
+
+<h3>آیا شرح اÙزودنی روشن Ùˆ کاÙÛŒ است؟</h3>
+
+<p>برای ما اهمیت Ùوق‌العاده زیادی دارد Ú©Ù‡ کاربران هنگام آزمایش یک اÙزودنی جدید آنچه خواسته‌اند را به دست آورند. شرح شما از اÙزودنی‌تان باید جزئیاتی در مورد کاری Ú©Ù‡ اÙزودنی انجام می‌دهد، چگونگی استÙاده از آن، Ùˆ این Ú©Ù‡ کاربر پس از نصب آن باید توقع Ú†Ù‡ چیزی را داشته باشد ارائه دهد. پیوند به مستندات خارجی برای راهنماهای Ù…Ùصل مورد قبول هستند، ولی خود شرح اÙزودنی باید موارد پایه‌ای را پوشش دهد Ùˆ به کاربران اطمینان بخشد Ú©Ù‡ می‌دانند پس از نصب اÙزودنی Ú†Ù‡ چیزی در انتظارشان است.</p>
+
+<p>همچنین، برای ما مهم است Ú©Ù‡ یادداشت‌های نسخه‌ها را همچنان Ú©Ù‡ اÙزودنی خود را بهبود می‌بخشید به صورت مناسبی Ù†Ú¯Ù‡ دارید. کاربران باید بتوانند بÙهمند در اÙزودنی Ú©Ù‡ قبلاً از آن استÙاده کرده‌اند Ú†Ù‡ تغییراتی روی داده است، Ùˆ باید در زمان به‌هنگام‌سازی از تغییراتی Ú©Ù‡ ممکن است در استÙادهٔ Ùعلی‌شان از اÙزودنی پس از به‌هنگام‌سازی ایجاد شود مطلع شوند. (در حال حاضر، کاربران یادداشت‌های نسخه را هنگامی Ú©Ù‡ مرورگر به آنها پیغام وجود یک به‌هنگام‌سازی را می‌دهد، نمی‌بینند، ولی ما تلاش خواهیم کرد این مشکل را رÙع کنیم. اگر شما یادداشت‌های نسخه‌ها را خوب Ù†Ú¯Ù‡ دارید، کاربران قبل Ùˆ پس از حل این مشکل از تلاش شما بهره خواهند برد.)</p>
+
+<h3>آیا تمام نگرانی‌های حریم خصوصی و امنیتی به روشنی بیان شده‌اند؟</h3>
+
+<p>این یک جنبه از شرحی دقیق Ùˆ روشن است، ولی به قدری اهمیت دارد Ú©Ù‡ باید جداگانه به آن اشاره شود. بسیاری اÙزودنی‌های بسیار Ù…Ùید Ùˆ با Ú©ÛŒÙیت بالا با گونه‌ای از اطلاعات کاربران کار می‌کنند، یا اگر بد استÙاده شوند می‌توانند خطرهای امنیتی ایجاد کنند؛ این اÙزودنی‌ها قابل نمایش در بخش عمومی وب‌گاه اÙزودنی‌های موزیلا هستند، ولی باید خطرهای متوجه کاربران Ùˆ روش محاÙظت در برابر آنها را به روشنی به کاربران توضیح دهند.</p>
+
+<h3>آیا اÙزودنی به خوبی آزمایش شده است، Ùˆ عاری از اشکالات واضح یا جدی است؟</h3>
+
+<p>یکی از موارد مهمی Ú©Ù‡ ما در تصمیم‌گیری برای عمومی شدن یک اÙزودنی آن را در نظر می‌گیریم آن است Ú©Ù‡ آیا در رویهٔ بررسی مورد آزمایش کامل قرار گرÙته است، Ùˆ آیا Ùاقد اشکالات جدی Ùˆ یا اثر منÙÛŒ روی مرورگر است یا خیر. اگر بررسی‌کنندگان اشکالاتی از جمله مشکلات کارایی جدی، Ùروپاشی، مشکلات متعدد در عملکرد اÙزودنی، یا پیام‌های بسیار زیاد در پیشانهٔ خطاها را گزارش کنند، شما باید این موارد را در نظر بگیرید Ùˆ اÙزودنی خود را پس از آن Ú©Ù‡ به بهترین وجهی Ú©Ù‡ برای‌تان ممکن است این موارد را اصلاح نموده‌اید، مجدداً نامزد کنید. ما توقع نداریم Ú©Ù‡ اÙزودنی بسیار عالی بهینه شود Ùˆ هیچ اشکالی نداشته باشد -- خود ÙایرÙاکس هم دائماً تحت بهبود در این موارد قرار دارد -- ولی ما می‌خواهیم Ú©Ù‡ شما تلاش معقولی برای حداقل کردن مشکلات بنمایید Ùˆ موارد باقی‌مانده Ú©Ù‡ ممکن است باعث تعجب کاربران شود را به دقت ذکر کنید.</p>
+
+<p>اگر اÙزودنی شما خارج از رویهٔ گودال ماسه‌بازی وب‌گاه اÙزودنی‌های موزیلا آزمایش شده است (مثلاً توسط گروهی از کاربران شما یا یک تیم کنترل Ú©ÛŒÙیت خارجی) باید این موضوع را در پیام نامزدی اÙزودنی‌تان ذکر کنید. این امر مسلماً به ما برای تعیین مقدار آزمایش انجام شده Ú©Ù…Ú© می‌کند Ùˆ به شما نیز در عمومی شدن اÙزودنی‌تان Ú©Ù…Ú© می‌کند.</p>
+
+<h3>آیا اÙزودنی Ùˆ مؤل٠آن با کاربران با احترام رÙتار می‌کنند؟</h3>
+
+<p>نرم‌اÙزار شما نباید بدون دلیل در کار کاربران دخالت کند، تلاش برای Ùریب کاربر کند، یا بخشی از Ùعالیت‌هایش را از کاربر مخÙÛŒ کند. کاربران (Ùˆ حتی اشخاص دیگر) بعضی مواقع در نظرهای خود ادب را رعایت نمی‌کنند، Ùˆ با وجود آن Ú©Ù‡ ما تلاش می‌کنیم این موارد را به محض گزارش به ما صاÙÛŒ کنیم، انتظار داریم Ú©Ù‡ مؤلÙان این نظرات را با بی‌ادبی پاسخ ندهند.</p>
+
+<h3>آیا اÙزودنی برای تعداد مناسبی از کاربران ÙایرÙاکس Ù…Ùید است؟</h3>
+
+<p>اÙزودنی شما نباید لزوماً Greasemonkey یا Firebug بعدی باشد، ولی اگر تنها برای اÙراد شرکت شما یا اعضای یک جامعهٔ Ú©ÙˆÚ†Ú© در وب Ù…Ùید است، ممکن است ما احساس کنیم قرار دادن آن در برابر تمام کاربران ÙایرÙاکس مناسب نیست.</p>
+
+<p>ما به صورت مداوم به دنبال راهی برای بهبود شرایط وب‌گاه برای اÙزودنی‌هایی هستیم Ú©Ù‡ از هر نظر عالی هستند ولی برای تنها بخش Ú©ÙˆÚ†Ú©ÛŒ از کاربران بالقوه ایجاد شده‌اند. دسته‌بندی صحیح Ùˆ به‌هنگام Ù†Ú¯Ù‡ داشتن اطلاعات اÙزودنی شما به ما Ú©Ù…Ú© می‌کند اÙزودنی‌های روزاÙزونی از این نوع را به اÙرادی Ú©Ù‡ به احتمال بسیار زیاد از آن بهره می‌برند ارائه نماییم.</p>
+
+<p>اگر اÙزودنی شما تنها چوب‌الÙ‌ها یا دیگر روش‌های سادهٔ دسترسی به وب‌گاه شما را Ùراهم می‌کند، به احتمال زیاد برای بخش عمومی وب‌گاه مناسب نیست. ما هم مانند بقیهٔ قسمت‌های پروژهٔ موزیلا، برنامه‌ها Ùˆ خدمات مبتنی بر وب را دوست داریم، ولی اÙزودنی‌های ÙایرÙاکس باید تجربهٔ مرور بهبود یاÙته‌ای به کاربران ارائه کنند Ùˆ نباید تنها روشی برای تبلیغ یک وب‌گاه یا خدمت جدید از طریق وب‌گاه اÙزودنی‌های موزیلا باشند. اگر شرح اÙزودنی شما بیش از آن Ú©Ù‡ در مورد تجربهٔ مرور کاربر باشد به خدمت مربوطه بپردازد، به احتمال زیاد شما از مسیر صحیح منحر٠گشته‌اید.</p>
+
+<h3>آیا اÙزودنی عاری از موارد مشمول حق نسخه‌برداری یا علائم تجاری بدون مجوز است؟</h3>
+
+<p>با این Ú©Ù‡ امکان دارد شما نیت بدی نسبت به صاحب یک علامت تجاری یا کاری دارای حق نسخه‌برداری نداشته باشید، ما نمی‌توانیم اÙزودنی‌هایی Ú©Ù‡ از علامات تجاری یا حقوق نسخه‌برداری تخطی می‌کنند را میزبانی کنیم. اگر اجازهٔ استÙاده از نام یا تصویری Ú©Ù‡ یک علامت تجاری است را ندارید، لطÙاً اÙزودنی خود را به وب‌گاه اÙزودنی‌های موزیلا ارسال نکنید. اگر اÙزودنی‌تان شامل کدی است Ú©Ù‡ حق نسخه‌برداری آن متعلق به شخص دیگری است، Ùˆ شما مجوز استÙاده از آن در اÙزودنی‌تان را ندارید، لطÙاً اÙزودنی خود را به وب‌گاه اÙزودنی‌های موزیلا ارسال نکنید. (اگر صاحب یک حق نسخه‌برداری یا علامت تجاری به استÙادهٔ شما از آن اعتراض کند، ما به احتمال زیاد مجبور خواهیم شد درخواست حذ٠اÙزودنی‌تان را با مشاور حقوقی‌مان مطرح کنیم Ùˆ اگر به لحاظ قانونی ملزم به حذ٠آن باشیم، آن را حذ٠خواهیم کرد. این رویه‌ای هزینه‌بر از منابع پروژه، شامل هزینهٔ مادی Ùˆ زمانی، است، بنابراین از شما می‌خواهیم به این اصول احترام بگذارید Ùˆ دشواری بیهوده‌ای ایجاد نکنید.)</p>
+
+<p>اگر از این Ú©Ù‡ آیا نام اÙزودنی خود، یا استÙاده از چیزی در آن ممکن است جلوی انتشار آن در وب‌گاه را بگیرید، مطمئن نیستید، می‌توانید از amo-editors@mozilla.org راهنمایی بخواهید. نکتهٔ مهم: لطÙاً توجه کنید Ú©Ù‡ این گروه قادر به ارائهٔ مشاورهٔ قانونی نیست، Ùˆ حتی اگر ما احساس کنیم Ú©Ù‡ استÙادهٔ شما قابل قبول است، امکان دارد این تصمیم را در اثر شکایات وارده از صاحبان حقوق یا مشاوره‌های حقوقی عوض کنیم.</p>
+
+<p>در مورد استÙاده از متن برنامهٔ اÙزودنی‌های دیگر، اگر مؤل٠به صراحت -- مثلاً با قرار دادن آن تحت یک مجوز متن باز -- Ù†Ú¯Ùته باشد Ú©Ù‡ مجاز به استÙاده از کد او در کار خود هستید، باید Ùرض کنید Ú©Ù‡ حق این کار را ندارید. شما می‌توانید برای کسب این اجازه با مؤل٠آن اÙزودنی تماس بگیرید، ولی ما نمی‌توانیم برای شما تنها به این دلیل Ú©Ù‡ آن اÙزودنی در وب‌گاه اÙزودنی‌های موزیلا بوده است، Ùˆ یا مؤل٠آن به درخواست شما پاسخی نداده است، حق خاصی قائل شویم. (Ùˆ برای بار دوم، ما قادر به ارائهٔ مشاورهٔ حقوقی نیستیم، تنها می‌توانیم در خصوص تطابق اÙزودنی شما با سیاست‌های این وب‌گاه مشاوره دهیم.)</p>
+
+<p>این شامل علائم تجاری بنیاد موزیلا، شامل «Mozilla»، «Firefox»، Ùˆ «Thunderbird» هم می‌شود. سیاست موزیلا در خصوص استÙاده از علائم تجاری برای محاÙظت در برابر سردرگمی کاربران، Ùˆ جلوگیری از غلبه بر علائم تجاری به دلیل عدم محاÙظت وضع شده است؛ Ùˆ لطÙاً به نیاز به چنین محاÙظتی احترام بگذارید، Ùˆ ما را برای نگهداری برخی از باارزش‌ترین سرمایه‌های بنیاد موزیلا یاری دهید.</p>
+
+<h2>پس از آن Ú©Ù‡ من یک اÙزودنی را نامزد می‌کنم Ú†Ù‡ اتÙاقی می‌اÙتد؟</h2>
+
+<p>هنگامی Ú©Ù‡ یک اÙزودنی نامزد شود، توسط تیمی از ویرایش‌گران وب‌گاه اÙزودنی‌های موزیلا بر اساس شرایط بالا ارزیابی می‌شود. اگر نتیجهٔ این ارزیابی مبنی بر آمادگی اÙزودنی برای نمایش به عموم باشد، پس از ارزیابی به بخش عمومی وب‌گاه منتقل می‌شود، Ùˆ شما نامهٔ اعلانی دریاÙت خواهید نمود.</p>
+
+<p>اگر ما احساس کنیم Ú©Ù‡ اÙزودنی شما هنوز برای بخش عمومی وب‌گاه اÙزودنی‌های موزیلا آماده نیست، شما یک نامهٔ اعلانی دریاÙت خواهید کرد Ú©Ù‡ شرح می‌دهد چرا این تصمیم گرÙته شده است، Ùˆ اÙزودنی شما از ص٠نامزدها حذ٠خواهد شد. اگر Ùکر می‌کنید Ú©Ù‡ موارد ذکر شده در نامهٔ اعلانی را رÙع کرده‌اید، Ùˆ می‌خواهید اÙزودنی‌تان دوباره ارزیابی شود، می‌توانید این درخواست را بدهید. نامزد کردن‌های متوالی بدون بهبودهای مشخصی در اÙزودنی جالب نیستند، پس بهتر است Ú©Ù…ÛŒ تأمل کنید؛ احتمال آن Ú©Ù‡ شما ما را خشمگین کنید بیشتر از آن است Ú©Ù‡ ما خسته شویم.</p>
+
+<h2>آیا می‌توانم اÙزودنی شخص دیگری را نامزد کنم؟</h2>
+
+<p>در حال حاضر، ما از مؤلÙان اÙزودنی‌ها می‌خواهیم کار خود را برای انتشار نامزد کنند. ما می‌خواهیم مطمئن شویم Ú©Ù‡ مؤل٠با اÙزایش مخاطبین مشکلی ندارد Ùˆ وضعیت Ùعلی اÙزودنی به درستی Ú©ÛŒÙیت کارش را منعکس می‌کند. اگر شما بر این باور هستید Ú©Ù‡ روی یک اÙزودنی به میزان کاÙÛŒ کار شده است Ùˆ مؤل٠آن به دلیل سیاست‌های وب‌گاه اÙزودنی‌های موزیلا اقدام به نامزد کردن اÙزودنی خود نمی‌کند، Ùˆ در دسترس قرار دادن این اÙزودنی به حدود یکصد میلیون کاربر در سراسر جهان برای ÙایرÙاکس، کاربران ما Ùˆ وب به صورت Ú©Ù„ÛŒ Ù…Ùید است، باید مؤل٠اÙزودنی را متقاعد کنید Ú©Ù‡ کار خود را نامزد کند.</p>
+
+<h2>اÙزودنی من مدت زیادی در ص٠نامزدها باقی مانده است. آیا شما از من متنÙرید؟</h2>
+
+<p>ما از شما متنÙر نیستیم. ما توسعه‌دهندگان اÙزودنی‌ها را دوست داریم، Ùˆ به سختی کار می‌کنیم تا آنها را راضی Ùˆ کارا Ù†Ú¯Ù‡ داریم، تا کاربران سراسر جهان بتوانند از کار آنها بهره‌مند شوند. ولی Ùهرست شدن در بخش عمومی وب‌گاه اÙزودنی‌های موزیلا ارزش‌مند است، زیرا ما دقت زیادی در این Ú©Ù‡ کدام اÙزودنی‌ها در آنجا قرار گیرند صر٠می‌کنیم، بنابراین نمی‌توانیم با عجله کردن این رویه را سریع‌تر کنیم. ما درک می‌کنیم Ú©Ù‡ انتظار برای ارزیابی شدن اÙزودنی‌تان ممکن است دشوار باشد، Ùˆ مایل هستیم این زمان را تا حد امکان کوتاه Ù†Ú¯Ù‡ داریم. هر Ú†Ù‡ اÙراد بیشتری بررسی‌های دقیق Ùˆ روشنی از اÙزودنی شما به عمل آورند، انجام ارزیابی برای ما آسان‌تر است، بنابراین اگر مایل هستید می‌توانید در این بخش هم Ú©Ù…Ú© کنید.</p>
+
+<h2>من یک اشکال بسیار جدی را در اÙزودنی‌ام تصحیح کردم Ùˆ می‌خواهم این تصحیح را هر Ú†Ù‡ سریع‌تر در اختیار کاربران قرار دهم. Ú†Ù‡ باید بکنم؟</h2>
+
+<p>اگر مشکلی جدی (مشکل امنیتی، پایداری یا مشکلات بزرگ عملکردی) در یک اÙزودنی وجود دارد Ùˆ نیاز دارید هر Ú†Ù‡ سریع‌تر یک به‌هنگام‌سازی از آن را منتشر کنید، روشن است Ú©Ù‡ باید این نکته را در «یادداشت‌های بررسی‌کننده» -- Ùˆ همچنین در یادداشت‌های نسخه -- در هنگام ارسال به‌هنگام‌سازی مشخص کنید. همچنین ممکن است بخواهید برخی از کاربران Ùعلی اÙزودنی‌تان را Ùهرست کنید تا بتوانند به‌هنگام‌سازی را آزمایش کنند Ùˆ نتایج آزمایش را دقیقاً در گودال ماسه‌بازی ثبت کنند. حضور در کانال <span dir="ltr">#addons</span> در irc.mozilla.org می‌تواند در اطلاع‌رسانی به دیگران دربارهٔ این موضوع Ú©Ù…Ú© کند، ولی لطÙاً صبور Ùˆ مؤدب باشید.</p>
+
+<p>
+ لطÙاً چوپان دروغگو نشوید. ما تلاش می‌کنیم به سرعت برای به‌هنگام‌سازی‌های با اولویت بالا اقدام کنیم، ولی این کار نه تنها زمان بررسی دیگر اÙزودنی‌های نامزد شده را می‌گیرد، بلکه اغلب زمان خواب ما یا زمانی Ú©Ù‡ با خانواده Ùˆ دوستانمان صر٠می‌کنیم را نیز می‌گیرد، بنابراین ما در مورد اÙرادی Ú©Ù‡ تلاش می‌کنند از این سازوکار برای پرش به قسمت‌های جلوتر ص٠سوءاستÙاده کنند نظر خوبی نداریم. اگر مطمئن نیستید Ú©Ù‡ این راه حل مناسب شماست، پرسش در کانال <span dir="ltr">#addons</span> در irc.mozilla.org می‌تواند Ú©Ù…Ú© کند تصمیم صحیحی بگیرید.</p>
+
+<h2>به نظر من بررسی اÙزودنی‌ام منصÙانه نبود. Ú†Ù‡ باید بکنم؟</h2>
+
+<p>اگر Ùکر می‌کنید اÙزونه‌تان اشتباه ارزیابی شده است، Ùˆ به خطا از دسترسی عمومی محروم شده است، باید یک نامهٔ الکترونیکی به amo-editors@mozilla.org حاوی دلایل خود بÙرستید. لطÙاً در نامهٔ خود مؤدب باشید Ùˆ موضوع را روشن بیان کنید، Ùˆ دلایل دقیق قضاوت ناصحیح در مورد اÙزودنی‌تان را بیان کنید.</p>
+
+<p>(اگر شما همهٔ موارد ذکر شده در نامهٔ اعلانی Ú©Ù‡ دریاÙت کرده‌اید را اصلاح نموده‌اید، به جای اعتراض به ارزیابی، باید اÙزودنی خود را از طریق «ابزارهای توسعه‌دهنده» دوباره نامزد کنید.)</p>
+
+<h2>اÙزودنی من قبلاً عمومی بود، ولی اکنون تنها در گودال ماسه‌بازی وجود دارد. Ú†Ù‡ اتÙاقی اÙتاده است؟</h2>
+
+<p>اگر یک اÙزودنی شرایط عمومی بودن را از دست بدهد، ما ممکن است آن را مجدداً به گودال ماسه‌بازی منتقل کنیم. در چنین صورتی ما Ø·ÛŒ یک نامهٔ الکترونیکی شما را مطلع می‌سازیم Ùˆ دلایل این کار را نیز ذکر خواهیم کرد، مگر این Ú©Ù‡ از نظر قانونی از این منع شده باشیم.</p>
+
+<p>همچنین امکان دارد شما اشکالی در وب‌گاه پیدا کرده باشید، Ú©Ù‡ در آن صورت باید آن را از طریق باگزیلا گزارش دهید؛ از محصول &quot;addons.mozilla.org&quot; Ùˆ مؤلÙÙ‡Ù” &quot;Public Pages&quot; برای گزارش استÙاده کنید، Ùˆ تا حد امکان جزئیات بیشتری را ارائه نمایید.</p>
+
+<h2>اÙزودنی من عمومی است، Ùˆ به نظر می‌رسد کاربران آن را خیلی دوست دارند. چگونه می‌توانم اÙزودنی‌ام را در Ùهرست اÙزودنی‌های پیشنهاد شده وارد کنم؟</h2>
+
+<p>اگر Ùکر می‌کنید اÙزودنی‌تان نمونه‌ای از قدرت اÙزودنی‌هاست، ارزش‌های موزیلا برای یک وب گسترش‌پذیر Ùˆ تحت کنترل کاربران را نمایش می‌دهد Ùˆ پیش می‌برد، Ùˆ تجربهٔ کاربری بسیار خوبی را Ùراهم می‌کند، می‌توانید درخواست اضاÙÙ‡ شدن آن به Ùهرست اÙزودنی‌های پیشنهاد شده را بدهید. برای این کار، یک نامهٔ الکترونیکی به amo-editors@mozilla.org بÙرستید Ùˆ دلیل عالی بودن اÙزودنی خود را توضیح دهید.</p>
+
+<p>نامهٔ شما <b>حداقل</b> باید شامل اطلاعاتی دربارهٔ این موارد باشد:</p>
+<ul>
+<li>تجربهٔ وب چگونه برای کاربران بهبود می‌یابد</li>
+<li>اÙزودنی شما چرا برای بخش بزرگی از کاربران ÙایرÙاکس Ù…Ùید است</li>
+<li>اÙزودنی شما چگونه ارزش‌های پروژهٔ موزیلا، خصوصاً دربارهٔ دادن اختیار به کاربران، Ø­Ùاظت از امنیت Ùˆ حریم خصوصی، دسترسی جهانی به وب Ùˆ استانداردها Ùˆ اطلاعات باز را رعایت می‌کند</li>
+<li>اÙزودنی شما Ú†Ù‡ تÙاوتی با اÙزودنی‌های مشابه دارد (هم مواردی Ú©Ù‡ اÙزودنی شما بهتر است Ùˆ هم مواردی Ú©Ù‡ بدتر است)</li>
+<li>عکس‌العمل‌های مثبت Ùˆ منÙÛŒ Ú©Ù‡ شما از کاربران، بررسی‌کنندگان، نویسنده‌های وب، ستاره‌شناسان، یا حیوانات خانگی‌تان دریاÙت کرده‌اید</li>
+</ul>
+
+<p>هر Ú†Ù‡ اطلاعاتی Ú©Ù‡ Ùراهم می‌کنید کامل‌تر باشد، احتمال مواÙقت ما با درخواست شما بیشتر است، با این حال درخواستی با نگارش بسیار عالی Ùˆ بسیار کامل هم تضمین‌کنندهٔ قرار گرÙتن اÙزودنی شما در Ùهرست اÙزودنی‌های پیشنهاد شده نیست. در نهایت، این Ùهرست باید تحت صلاحدید موزیلا تهیه شود، Ùˆ تجربهٔ کاربری Ùˆ Ø­Ùاظت از کاربران باید بالاترین اولویت را داشته باشند، همچنان Ú©Ù‡ اکنون نیز این موضوع صادق است.</p>
diff --git a/site/app/locale/fa/pages/privacy.thtml b/site/app/locale/fa/pages/privacy.thtml
new file mode 100644
index 0000000..00054c3
--- /dev/null
+++ b/site/app/locale/fa/pages/privacy.thtml
@@ -0,0 +1,164 @@
+<div dir="ltr">
+<h2>Mozilla Privacy Policy</h2>
+
+<p>June 2008</p>
+
+<p><i>Note: This privacy policy applies to the Mozilla.org Web sites and services. We have a separate privacy policy for our
+products and for some Mozilla.com web properties. Please see for example: <a
+href="http://www.mozilla.com/en-US/legal/privacy/firefox-en.html">Mozilla Firefox Privacy Policy</a>.</i></p>
+
+<div class="corner-box"> <h3>Website Visitors</h3>
+
+<p>Except as described below, the Mozilla Foundation ("Mozilla") does not collect or require visitors to
+its Web sites to furnish personally-identifying information such as names, email addresses and phone numbers.
+Like most Web site operators, Mozilla collects non-personally-identifying information of the sort that web
+browsers and servers typically make available, such as the browser type, language preferences, referring
+site, and date and time of each visitor request. Mozilla also collects potentially personally-identifying
+information like Internet Protocol (IP) addresses, which are non-personally identifying in and of themselves
+but could be used in conjunction with other information to personally identify users.</p>
+
+<p>Mozilla's purpose in collecting this information is to better understand how Mozilla's visitors use
+its Web sites. To that end, Mozilla may share potentially personally-identifying information with its
+employees, contractors, and its subsidiaries and related organizations. Mozilla may also release
+non-personally-identifying information about visitors (e.g., by publishing a report on Web site usage
+trends). Otherwise, Mozilla will not publicly release potentially personally-identifying information
+except under the same circumstances as Mozilla releases personally-identifying information. Those
+circumstances are explained below.</p>
+
+</div>
+
+<div class="corner-box"> <h3>Community Members</h3>
+
+<p>Certain members of the Mozilla community (contributors, customers, etc.) choose to interact with
+Mozilla in ways that require Mozilla and others to know more about them. The amount and type of
+information that Mozilla gathers from those members depends on the nature of the interaction. For
+example, members who wish to post content to certain portions of Mozilla's Web sites or participate
+in live chat session(s) are asked to provide usernames that identify that content as having been
+posted by a particular member. Developers, by comparison, are asked to provide contact information,
+up to and sometimes including telephone or fax numbers, so that they can be contacted as necessary.
+Customers of the Mozilla store are asked to provide even more information, including billing and
+shipping addresses and credit card or similar information. In each case, Mozilla collects
+personally-identifying information only insofar as is necessary to fulfill the purpose of the
+community member's interaction with Mozilla.</p>
+
+<p>Mozilla is an open organization that believes in sharing as much information as possible about
+its products, its operations and its associations. Accordingly, community members should assume&mdash;as
+should most folks who interact with Mozilla&mdash;that any personally-identifying information
+provided to Mozilla will be made available to the public. There are three broad exceptions to that rule:</p>
+
+<ol>
+<li>Mozilla does not publicly release information gathered in connection with commercial transactions
+(i.e., transactions involving money), including transactions conducted through the Mozilla Store or
+donations to the Mozilla Foundation.</li>
+
+<li>Mozilla does not make publicly available information that is used to authenticate users the publication
+of which would compromise the security of Mozilla's Web sites (e.g., passwords).</li>
+
+<li>Mozilla does not make publicly available information that it specifically promises at the time of
+collection to maintain in confidence.</li>
+
+</ol>
+
+<p>Outside those three contexts, visitors should assume that personally-identifying information provided
+through Mozilla's Web sites will be made available to the public.</p>
+
+</div>
+
+<div class="corner-box"> <h3>Interactive Product Features</h3>
+
+<p>Certain Mozilla products contain features that report, or that permit users to report, the user's
+usage patterns and problems&mdash;whether caused by Mozilla's software, third party software, or
+third-party Web sites&mdash;to Mozilla. The reports generated by these features typically include
+non-personally-identifying information such as the configuration of the user's computer and the code
+running at the time the problem occurred. Some of the features give users the option of providing
+personally-identifying information, though none of these features require it. Some Mozilla software
+features that do permit users to provide personally-identifying information advise, in advance, that
+such information will not be made publicly available. Mozilla analyzes the information provided by
+these interactive product features to develop a better understanding of how its products are performing
+and being used. It does not use the information to track the usage of its products by identifiable
+individuals.</p>
+
+</div>
+
+<div class="corner-box"> <h3>Protection of Certain Personally-Identifying Information</h3>
+
+<p>Where Mozilla has collected personally-identifying information subject to one of the three
+exceptions described in the Contributors and Customers section, above, it discloses that information
+only to those of its employees, contractors and its subsidiaries and related organizations that need
+to know that information in order to process it on Mozilla's behalf and that have agreed not to disclose
+it to others. Some of those employees, contractors and subsidiaries and related organizations may be
+located outside of a visitor's home country; by using Mozilla's Web sites, the visitor consents to
+the transfer of his/her information to them. Mozilla does not rent or sell such information to anyone.
+Other than to its employees, contractors or its subsidiaries and related organizations, as described
+above, Mozilla discloses such information only when required to do so by law, or when Mozilla believes
+in good faith that disclosure is reasonably necessary to protect the property or rights of Mozilla,
+members of the Mozilla community, or the public at large. Mozilla takes all measures reasonably
+necessary to protect against the unauthorized access, use, alteration or destruction of such
+information.</p>
+
+</div>
+
+<div class="corner-box"> <h3>Updating of Personally-Identifying Information</h3>
+
+<p>Mozilla permits users to freely update and correct their personally-identifying information as
+maintained by Mozilla. To do so, users should look for links or contact information available on
+whichever Mozilla Web sites store the relevant information (e.g., Bugzilla users should go to
+<a href="https://bugzilla.mozilla.org/userprefs.cgi?tab=account">https://bugzilla.mozilla.org/userprefs.cgi?tab=account</a>),
+or contact Mozilla by email.</p>
+
+</div>
+
+<div class="corner-box"> <h3>Cookies and Clear GIFs</h3>
+
+<p><b>What Are Cookies?</b> A cookie is a string of information that a Web site stores on a visitor's
+computer, and that the visitor's browser provides to the Web site each time the visitor returns.
+Most major web sites use cookies. Because the browser provides this cookie information to the website
+at each visit, cookies serve as a sort of label that allows a website to "recognize" a browser when it
+returns to the site. The domain name in Mozilla cookies will clearly identify their affiliation with
+Mozilla and, where applicable, its third party service provider.</p>
+
+<p><b>What Are Clear GIFs?</b> Clear gifs (also known as web beacons) are used in combination with
+cookies to help web site operators understand how visitors interact with their websites. A clear gif is
+typically a transparent graphic image (usually 1 pixel x 1 pixel) that is placed on a site. The use of
+a clear gif allows the site to measure the actions of the visitor opening the page that contains the
+clear gif. It makes it easer to follow and record the activities of a recognized browser, such as the
+path of pages visited at a website.</p>
+
+<p><b>How We Use Cookies and Clear GIFs.</b> Mozilla's Web sites use cookies and may use clear gifs in
+the future. These tools help Mozilla identify and track visitors, their usage of Mozilla Web sites, and
+their Web site access preferences across multiple requests and visits to Mozilla's Web sites. The basic
+idea is to gather aggregate data about how people use the Mozilla Web sites. The term usually used to
+describe this is "web analytics" and the cookies and clear gifs are the tools by which a website owner
+collects this web analytics data. Mozilla will use the web analytics data only to determine aggregate
+usage patterns for our Web sites as described above. The Mozilla Web sites (.org domains) do this
+using Mozilla's own internal analytics software, and currently do not utilize third party service
+providers. Mozilla uses the information provided by cookies and clear gifs to develop a better
+understanding of how Mozilla's visitors use Mozilla's Web sites, and to facilitate those visitors'
+interactions with Mozilla's Web sites. Mozilla may make the aggregate data it obtains publicly
+available. If the data is made available, none of the information will be personally-identifying
+information or potentially-personally-identifying information.</p>
+
+<p><b>How to Control the Use of Cookies.</b> Mozilla visitors have the ability to accept or decline
+cookies. Mozilla visitors who do not wish to have cookies placed on their computers by Mozilla, its
+contractors, or third-party service providers should set their browsers to refuse cookies before linking
+to Mozilla's Web sites. Certain features of Mozilla's Web sites may not function properly without the
+aid of cookies.</p>
+
+</div>
+
+<div class="corner-box"> <h3>Privacy Policy Changes</h3>
+
+<p>Mozilla may change its Privacy Policy from time to time. Any and all changes will be reflected on
+this page. Substantive changes will also be announced through the standard mechanisms through which
+Mozilla communicates with the Mozilla community, including Mozilla's
+<a href="http://lists.mozilla.org/listinfo/announce">"Mozilla-announce" mailing list</a> and
+<a href="http://groups.google.com/group/mozilla.announce">newsgroup</a>.</p>
+
+</div>
+
+<div class="corner-box"> <h3>For More Information</h3>
+
+<p>If you have questions about this privacy policy, please contact Mozilla at: privacy@mozilla.org.</p>
+
+</div>
+</div> \ No newline at end of file
diff --git a/site/app/locale/fa/pages/reviewguide.thtml b/site/app/locale/fa/pages/reviewguide.thtml
new file mode 100644
index 0000000..0f0e124
--- /dev/null
+++ b/site/app/locale/fa/pages/reviewguide.thtml
@@ -0,0 +1,92 @@
+<h1>رهنمون‌های انجام بررسی</h1>
+<p>بررسی‌های اÙزودنی‌ها راهی برای بیان نظر کاربران وب‌گاه اÙزودنی‌ها دربارهٔ
+اÙزودنی‌هایی است Ú©Ù‡ نصب Ùˆ استÙاده نموده‌اند. ویرایش‌گران حث رد کردن یا حذ٠بررسی‌هایی
+Ú©Ù‡ در تضاد با این رهنمون‌ها باشند را برای خود محÙوظ می‌دارد.</p>
+
+<div class="corner-box">
+ <h2>ترÙندهایی برای نوشتن یک بررسی عالی</h2>
+
+<h3><b>این کارها را انجام دهید:</b></h3>
+<ul>
+<li>طوری بنویسید Ú©Ù‡ انگار تجربهٔ خود از این اÙزودنی را برای یک دوست تعری٠می‌کنید.</li>
+<li>بررسی را کوتاه و ساده نگه دارید.</li>
+<li>به نکات خاص Ùˆ جزئیات Ù…Ùید اشاره کنید. مثلاً:
+<ul>
+ <li>آیا اÙزودنی آن گونه Ú©Ù‡ انتظار داشتید کار کرد؟</li>
+ <li>از Ú†Ù‡ ویژگی‌های اÙزودنی راضی یا ناراضی هستید؟</li>
+ <li>آیا Ù…Ùید بود؟</li>
+ <li>آیا برای استÙاده ساده بود؟</li>
+ <li>آیا به استÙاده از این اÙزودنی ادامه می‌دهید؟</li>
+</ul></li>
+
+<li>پیش از ارسال بررسی خود، آن را یک بار دیگر کنترل کنید تا از اشتباهات دستور زبان و اشتباهات کوچک خجالت‌آور دیگر اجتناب کنید.</li>
+
+<li>از اشاره به ارجاعات موضوعی یا زمانی خودداری نمایید، زیرا بررسی‌ها امکان دارد مدت بسیار زیادی بر روی وب‌گاه باقی بمانند.</li>
+</ul>
+
+<h3><b>این کارها را انجام ندهید:</b></h3>
+<ul>
+<li>بررسی‌های ساده‌ای مانند «عالی!»، «تعجب‌برانگیز!»، یا «بد» بدون توضیح دیگر خودداری نمایید.</li>
+<li>گزارش مشکلات را در بررسی‌ها ارسال نکنید. در عوض از امکانات پشتیبانی موجود برای هر اÙزودنی استÙاده کنید.</li>
+<li>برای اÙزودنی‌هایی Ú©Ù‡ خودتان شخصاً از آن استÙاده نکرده‌اید، بررسی ننویسید.</li>
+<li>از واژه‌های توهین‌آمیز، جنسی Ùˆ سایر واژه‌های تنÙرآمیز استÙاده نکنید.</li>
+<li>کد HTMLØŒ پیوند به نرم‌اÙزارهای مضر، کد منبع یا تکه کد در بررسی خود وارد نکنید. بررسی‌ها باید تنها شامل متن باشند.</li>
+<li>اظهارات نادرست ابراز نکنید Ùˆ مؤلÙان اÙزودنی را مورد هجوم شخصی یا توهین قرار ندهید.</li>
+<li>از بررسی‌ها به عنوان روشی برای درخواست پشتیبانی برای نسخهٔ خاصی از ÙایرÙاکس (یا برنامهٔ دیگری) استÙاده نکنید.</li>
+<li>نشانی پست الکترونیکی، شمارهٔ تلÙن، یا اطلاعات شخصی دیگر را در بررسی‌تان ننویسید.</li>
+<li>برای اÙزودنی‌های خودتان یا متعلق به سازمانی Ú©Ù‡ متعلق به آن هستید یا آن را نمایندگی می‌نمایید خودداری کنید.</li>
+</ul>
+</div>
+
+<div class="corner-box">
+ <h2>رهنمون‌هایی برای رتبه‌دهی به اÙزودنی</h2>
+
+<p>رتبه‌دهی اÙزودنی‌ها باید عادلانه باشد Ùˆ نشان خوبی از Ú©ÛŒÙیت Ùˆ Ù…Ùید بودن
+Ú©Ù„ÛŒ اÙزودنی باشد. لطÙاً تنها به این دلیل Ú©Ù‡ یک اÙزودنی را دوست دارید به آن
+۵ ستاره و یا به این دلیل که آن را دوست ندارید به آن ۱ ستاره ندهید.
+رتبه‌دهی دقیق بخش مهمی از هر بررسی است.</p>
+
+<ul>
+<li><b>۵ ستاره: عالی.</b> نه تنها هر کاری که ادعا می‌کند را به خوبی انجام
+می‌دهد، بلکه مشخصاً از بسیاری اÙزودنی‌های دیگر Ù…Ùیدتر است. این اÙزودنی به احتمال
+زیاد مورد استÙادهٔ مداوم قرار می‌گیرد Ùˆ شما به شدت آن را توصیه می‌کنید.</li>
+<li><b>Û´ ستاره: خوب.</b> این اÙزودنی Ù…Ùید است Ùˆ استÙاده از آن ساده است، ولی
+لزوماً اÙزودنی خاصی تلقی نمی‌شود. این اÙزودنی را توصیه می‌کنید ولی ممکن است
+برای بعضی اÙراد بیشتر از اÙراد دیگر Ù…Ùید باشد.</li>
+<li><b>Û³ ستاره: قابل استÙاده.</b> ممکن است اشکالات طراحی Ùˆ/یا ویژگی‌های ناقصی
+داشته باشد. مشکلات این اÙزودنی آن قدر شدید نیستند Ú©Ù‡ دیگران را به استÙاده از آن
+توصیه نکنید، Ùˆ برای بعضی اÙراد ممکن است Ù…Ùید باشد. این اÙزودنی را برای آنهایی
+که به آن نیاز دارند و مایل به امتحان آن هستند توصیه می‌کنید.</li>
+<li><b>Û² ستاره: ضعیÙ.</b> این اÙزودنی دارای Ú©ÛŒÙیت یا قابلیت استÙادهٔ Ú©Ù…ÛŒ است،
+یا آن Ú†Ù‡ را Ú©Ù‡ ادعا می‌کند انجام نمی‌دهد. شما استÙاده از این اÙزودنی را توصیه
+نمی‌کنید، ولی احتمال می‌دهید Ú©Ù‡ باز هم این اÙزودنی برای اÙراد Ú©Ù…ÛŒ دارای مقداری
+ارزش باشد.</li>
+<li><b>Û± ستاره: بد.</b> اÙزودنی یا به درستی کار نمی‌کند یا Ùوق‌العاده بی‌Ùایده
+است. شما دلیلی برای این Ú©Ù‡ کسی از آن استÙاده کند نمی‌بینید Ùˆ توصیه می‌کنید Ú©Ù‡
+اÙراد کلاً از این اÙزودنی اجتناب کنند.</li>
+</ul>
+
+<p>نوشتن یک بررسی عالی یا ناخوشایند برای یک اÙزودنی اشکالی ندارد، تنها کاÙÛŒ است
+دلیل این کار خود را بیان کنید. اگر این دلیل را بیان نکنید، این ستاره‌ها برای ما
+Ù…Ùهومی ندارند.</p>
+</div>
+
+<div class="corner-box">
+ <h2>پرسش‌های معمول دربارهٔ بررسی‌ها</h2>
+
+<h3>چگونه می‌توانم یک بررسی نادرست را گزارش کنم؟</h3>
+<p>لطÙاً هر بررسی غیر قابل اعتماد را با کلیک بر روی «گزارش این بررسی» گزارش
+کنید تا برای تعدیل به وب‌گاه ارسال شود. ویرایش‌گران با استÙاده از رهنمون‌های
+انجام بررسی حذ٠یا برگرداندن یک بررسی به وب‌گاه را ارزیابی می‌کنند.</p>
+
+<h3>من یک مؤل٠اÙزودنی هستم، آیا می‌توانم به یک بررسی پاسخ دهم؟</h3>
+<p>بله، مؤلÙان می‌توانند به هر بررسی یک پاسخ دهند. بحث‌های اضاÙÛŒ یا
+پیگیری‌ها باید در یک انجمن پشتیبانی یا یک گروه بحث انجام گیرد.</p>
+
+<h3>من یک مؤل٠اÙزودنی هستم، آیا می‌توانم بررسی‌ها Ùˆ رتبه‌های ناخوشایند را حذ٠کنم؟</h3>
+<p>در حالت کلی خیر. ولی اگر یک بررسی با رهنمون‌های انجام بررسی که در بالا شرح داده شد
+مطابقت ندارد، می‌توانید بر روی «گزارش این بررسی» کلیک کنید تا توسط یک ویرایش‌گر
+تعدیل شود. اگر یک بررسی حاوی شکایتی است Ú©Ù‡ با یک نسخهٔ جدید از اÙزودنی‌تان حل شده
+است، ما ممکن است تصمیم به حذ٠آن بررسی بگیریم. درخواست مشروح خود را به نشانی
+amo-editors@mozilla.org ارسال کنید.</p>
+</div>
diff --git a/site/app/locale/fa/pages/sandbox.thtml b/site/app/locale/fa/pages/sandbox.thtml
new file mode 100644
index 0000000..f9ff0bc
--- /dev/null
+++ b/site/app/locale/fa/pages/sandbox.thtml
@@ -0,0 +1,13 @@
+<h1>نظام بررسی گودال ماسه‌بازی</h1>
+<h2>گودال ماسه‌بازی چیست؟</h2>
+<p>گودال ماسه‌بازی منطقه‌ای برای کاربران پیشرÙته است تا بتوانند اÙزودنی‌ها را پیش از آن Ú©Ù‡ برای استÙادهٔ عمومی بررسی شوند، آزمایش کنند. برای دسترسی به گودال ماسه‌بازی، باید آن را در تنظیمات حساب کاربری خود Ùعال سازید. هنگام نصب اÙزودنی‌های موجود در گودال ماسه‌بازی باید مراقب باشید، زیرا این اÙزودنی‌ها توسط یک ویرایش‌گر آزمایش نشده‌اند Ùˆ ممکن است به رایانهٔ شما صدمه بزنند.</p>
+
+<h2>چگونه می‌توانم اÙزودنی خود را در وب‌گاه عمومی وارد کنم؟</h2>
+<!-- To localize the flowchart image, see http://wiki.mozilla.org/Update:Remora_Sandbox_Flowchart -->
+<div style="text-align: center;">%s</div>
+<ol>
+ <li><b>اÙزودنی خود را با استÙاده از «ابزارهای توسعه‌دهنده» ارسال کنید.</b> اÙزودنی‌تان بلاÙاصله در بخش «گودال ماسه‌بازی» وب‌گاه اÙزودنی‌های موزیلا ظاهر می‌شود، Ùˆ کاربران پیشرÙته به آزمایش آن می‌پردازند Ùˆ در مورد آن نظر می‌دهند. برای مشاهدهٔ گودال ماسه‌بازی، باید آن را در تنظیمات حساب کاربری خود Ùعال سازید.</li>
+ <li><b>اÙزودنی خود را نامزد عمومی شدن کنید.</b> در «ابزارهای توسعه‌دهنده»، برای نامزد کردن اÙزودنی‌تان پیوندی وجود دارد. پس از آن Ú©Ù‡ اÙزودنی‌تان نامزد عمومی شدن گردید، برای بررسی وارد ص٠نامزدهای ویرایش‌گران می‌شود.</li>
+ <li><b>یک ویرایش‌گر اÙزودنی‌تان را بررسی می‌کند.</b> یک ویرایش‌گر اÙزودنی‌های موزیلا اÙزودنی شما را نصب Ùˆ آزمایش می‌کند. ویرایش‌گر همچنین بررسی‌های آزمایش‌کنندگان دیگر گودال ماسه‌بازی در مورد اÙزودنی‌تان را مطالعه می‌کند.</li>
+ <li><b>اÙزودنی شما عمومی می‌شود یا در گودال ماسه‌بازی باقی می‌ماند.</b> ویرایش‌گر یا اÙزودنی شما را عمومی می‌کند یا آن را در گودال ماسه‌بازی Ù†Ú¯Ù‡ می‌دارد. اگر اÙزودنی شما در گودال ماسه‌بازی Ù†Ú¯Ù‡ داشته شود، بعداً می‌توانید پس از اعمال تغییرات پیشنهاد شده در نظر ویرایش‌گر آن را دوباره نامزد کنید. اگر اÙزودنی شما عمومی شود، نسخه‌های بعدی آن در گودال ماسه‌یازی قرار می‌گیرند تا وقتی Ú©Ù‡ آنها هم توسط یک ویرایش‌گر بررسی شوند Ùˆ عمومی گردند. هنگامی Ú©Ù‡ اÙزودنی شما عمومی شود، دیگر نیازی به نامزد کردن آن نیست، Ùˆ نسخه‌های بعدی به صورت خودکار وارد ص٠انتظار بررسی می‌شوند.</li>
+</ol>
diff --git a/site/app/locale/fa/pages/statistics_help.thtml b/site/app/locale/fa/pages/statistics_help.thtml
new file mode 100644
index 0000000..29760c3
--- /dev/null
+++ b/site/app/locale/fa/pages/statistics_help.thtml
@@ -0,0 +1,7 @@
+<h3>راهنما</h3>
+<p>صÙحهٔ آمار اطلاعات بارگیری Ùˆ درخواست‌های به‌هنگام‌سازی اÙزودنی شما را نشان می‌دهد.</p>
+<h4>بارگیری</h4>
+<p>تعداد بارگیری‌ها هر روز به‌هنگام می‌شوند Ùˆ تنها شامل بارگیری‌های اولیهٔ اÙزودنی Ùˆ نه دریاÙت به‌هنگام‌سازی‌ها می‌باشند.</p>
+
+<h4>درخواست‌های به‌هنگام‌سازی</h4>
+<p>اÙزودنی‌هایی Ú©Ù‡ از این وب‌گاه بارگیری می‌شوند، روزی یک بار برای یاÙتن به‌هنگام‌سازی‌ها درخواست می‌دهند، Ùˆ تعداد Ú©Ù„ این درخواست‌های به‌هنگام‌سازی روزانه به عنوان کاربران Ùعال روزانه شناخته می‌شود. کاربران Ùعال روزانه (ADU) را می‌توان بر اساس نسخهٔ اÙزودنی، سیستم‌عامل، وضعیت اÙزودنی، Ùˆ برنامه دسته‌بندی نمود. این اطلاعات در حال حاضر یک روز در هر Ù‡Ùته، روزهای چهارشنبه، ضبط می‌شود.</p> \ No newline at end of file
diff --git a/site/app/locale/fa/pages/submission_help.thtml b/site/app/locale/fa/pages/submission_help.thtml
new file mode 100644
index 0000000..111a77e
--- /dev/null
+++ b/site/app/locale/fa/pages/submission_help.thtml
@@ -0,0 +1,35 @@
+<h1>راهنمای ارسال</h1>
+Ùیلدهای الزامی به صورت <b>سیاه</b> نمایش داده می‌شوند. Ùیلدهای اختیاری به صورت <i>کج</i> نمایش داده می‌شوند.
+<h2 id="step1">گام ۱: ارسال</h2>
+<ul class="submissionHelp">
+ <li><span class="required">نوع اÙزودنی</span> - به صورت پیش‌Ùرض، نوع اÙزودنی به صورت خودکار بر اساس پروندهٔ بارگذاری شده تعیین می‌شود. به احتمال زیاد نباید نیازی به تغییر این Ùیلد داشته باشید.</li>
+ <li><span class="required">پروندهٔ اÙزودنی</span> - پروندهٔ بستهٔ اÙزودنی‌تان، به همراه یک پروندهٔ install.rdf. اگر پرونده تنها با یک سکوی نرم‌اÙزاری خاص کار می‌کند، انتخاب آن سکو به شما اجازهٔ بارگذاری چندین پرونده با هم را می‌دهد.</li>
+ <li><span class="optional">پروندهٔ شمایل</span> - پروندهٔ شمایلی Ú©Ù‡ در کنار نام اÙزودنی در صÙحهٔ مربوط به آن Ùˆ نیز در پنجرهٔ نصب اÙزودنی نمایش داده می‌شود. این تصویر با Ù†Ú¯Ù‡ داشتن نسبت طول Ùˆ عرض به صورت خودکار به ۳۲×۳۲ نقطه تغییر اندازه داده خواهد شد.</li>
+ <li><span class="required">منطقهٔ پیش‌Ùرض</span> - منطقهٔ پیش‌Ùرض اÙزودنی. اگر منطقهٔ انتخاب شده توسط کاربر در این اÙزودنی وجود نداشته باشد، متون ترجمه شده به صورت خودکار از منطقهٔ پیش‌Ùرض این اÙزودنی استÙاده خواهند شد.</li>
+ <li><span class="optional">از به‌هنگام‌سازی اطلاعات Ùعلی اÙزودنی من صرÙ‌نظر Ú©Ù†</span> - اگر یک اÙزودنی از پیش موجود را به‌هنگام می‌کنید، این Ùیلد ظاهر می‌شود. Ùعال کردن این گزینه شما را مستقیماً به گام Û³ برای ورود اطلاعات خاص نسخه می‌برد.</li>
+</ul>
+
+<h2 id="step2">گام Û²: جزئیات اÙزودنی</h2>
+<ul class="submissionHelp">
+ <li><span class="required">نام</span> - نام اÙزودنی به زبان پیش‌Ùرض آن.</li>
+ <li><span class="required">مؤلÙان</span> - تمام کاربرانی Ú©Ù‡ قادر به تغییر توضیحات این اÙزودنی هستند Ùˆ به عنوان مؤلÙان آن در صÙحهٔ اÙزودنی Ùهرست می‌شوند.</li>
+ <li><span class="required">دسته‌ها</span> - دسته‌هایی Ú©Ù‡ اÙزودنی مربوط به آنهاست.</li>
+ <li><span class="optional">صÙحهٔ آغازه</span> - وب‌گاه اÙزودنی به زبان پیش‌Ùرض آن.</li>
+ <li><span class="required">خلاصه</span> - خلاصه‌ای کوتاه از اÙزودنی به زبان پیش‌Ùرض آن. این Ùیلد حداکثر می‌تواند شامل Û²ÛµÛ° حر٠باشد، Ùˆ در صÙحهٔ مربوط به اÙزودنی Ùˆ نیز نتایج مرور Ùˆ جستجو نمایش داده خواهد شد.</li>
+ <li><span class="required">شرح</span> - شرحی از اÙزودنی به زبان پیش‌Ùرض آن. این متن در صÙحهٔ مربوط به اÙزودنی زیر خلاصه نمایش داده می‌شود.</li>
+ <li><span class="optional">تواÙق‌نامهٔ مجوز کاربر نهایی</span> - تواÙق‌نامهٔ مجوز کاربر نهایی به زبان پیش‌Ùرض اÙزودنی Ú©Ù‡ کاربران پیش از بارگیری ملزم به پذیرÙتن آن هستند.</li>
+ <li><span class="optional">سیاست محرمانگی</span> - سیاست محرمانگی اÙزودنی، به زبان پیش‌Ùرض آن. سیاست محرمانگی شرح می‌دهد Ú©Ù‡ با اطلاعات خصوصی کاربر Ú†Ù‡ خواهد شد، Ùˆ به آن در کنار دکمهٔ نصب اÙزودنی در صÙحهٔ مربوط به آن پیوند داده خواهد شد. اطلاعات بیشتر دربارهٔ چیزهایی Ú©Ù‡ باید در سیاست محرمانگی ذکر شود Ùˆ این Ú©Ù‡ آیا اÙزودنی شما نیاز به آن دارد یا خیر در <a href="%s">سیاست اÙزودنی‌ها</a> موجود است.</li>
+ <li><span class="optional">به کاربران اجازهٔ مشاهدهٔ متصل پرونده‌های متن برنامه را بده</span> - Ùعال کردن این گزینه به کاربران اجازهٔ مرور متن برنامهٔ اÙزودنی‌تان را به صورت متصل می‌دهد.</li>
+ <li><span class="optional">این یک نسخهٔ پیش از انتشار است</span> - Ùعال کردن این گزینه نشان می‌دهد Ú©Ù‡ این اÙزودنی نسخه‌ای «بتا» یا پیش از انتشار است. اÙزودنی‌های پیش از انتشار در گودال ماسه‌بازی باقی می‌مانند Ùˆ تا هنگامی Ú©Ù‡ این گزینه غیر Ùعال نشده است نمی‌توان آنها را نامزد عمومی شدن کرد.</li>
+ <li><span class="optional">این اÙزودنی خاص یک وب‌گاه است</span> - Ùعال کردن این گزینه نشان می‌دهد Ú©Ù‡ این اÙزودنی خاص یک وب‌گاه است، مثلاً اÙزودنی Ú©Ù‡ ظاهر یک وب‌گاه را تغییر می‌دهد یا محتوای یک وب‌گاه را نشان می‌دهد. این Ùیلد به ویرایش‌گران Ú©Ù…Ú© می‌کند Ùˆ امکان دارد در آینده برای صاÙÛŒ کردن جستجوها مورد استÙاده قرار گیرد.</li>
+ <li><span class="optional">این اÙزودنی به نرم‌اÙزار خارجی نیاز دارد</span> - Ùعال کردن این گزینه نشان می‌دهد Ú©Ù‡ اÙزودنی نیاز به نرم‌اÙزاری خارجی دارد. این Ùیلد به ویرایش‌گران Ú©Ù…Ú© می‌کند Ùˆ امکان دارد در آینده برای صاÙÛŒ کردن جستجوها مورد استÙاده قرار گیرد.</li>
+</ul>
+
+<h2 id="step3">گام ۳: جزئیات نسخه</h2>
+<ul class="submissionHelp">
+ <li><span class="required optional">یادداشت‌های نسخه</span> - خلاصه یا Ùهرستی از تغییرات داده شده در این نسخه. این Ùیلد برای ارسال‌های جدید اختیاری است، ولی برای به‌هنگام‌سازی‌ها الزامی است.</li>
+ <li><span class="optional">یادداشت برای بررسی‌کنندگان</span> - این Ùیلد برای اطلاع‌رسانی به ویرایش‌گرانی Ú©Ù‡ اÙزودنی شما را بررسی می‌کنند در نظر گرÙته شده است. اطلاعات حساب کاربری آزمایشی Ùˆ یادداشت‌های خاص در این محل باید وارد شوند.</li>
+</ul>
+
+<h2 id="step4">گام ۴: محلی‌سازی</h2>
+در اینجا Ùیلدهای اÙزودنی را می‌توان به زبان‌های پشتیبانی شده ترجمه کرد. تنها کاÙÛŒ است برای وارد کردن ترجمه روی نام منطقه کلیک کنید. \ No newline at end of file
diff --git a/site/app/locale/fi/LC_MESSAGES/messages.mo b/site/app/locale/fi/LC_MESSAGES/messages.mo
new file mode 100644
index 0000000..a2c139b
--- /dev/null
+++ b/site/app/locale/fi/LC_MESSAGES/messages.mo
Binary files differ
diff --git a/site/app/locale/fi/LC_MESSAGES/messages.po b/site/app/locale/fi/LC_MESSAGES/messages.po
new file mode 100644
index 0000000..ac8d775
--- /dev/null
+++ b/site/app/locale/fi/LC_MESSAGES/messages.po
@@ -0,0 +1,8805 @@
+# Remora Preliminary Language File
+# Copyright (C) 2006 Mozilla Corporation
+# This file is distributed under the same license as the REMORA package.
+# Wil Clouser <clouserw@mozilla.com>, 2006.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: REMORA 0.1\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2009-01-16 11:45-0800\n"
+"PO-Revision-Date: 2008-03-25 23:25+0300\n"
+"Last-Translator: Ville Pohjanheimo <villepohjanheimo+bugzilla@fastmail.fm>\n"
+"Language-Team: Finnish <yllapito@mozilla.fi>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=n != 1;\n"
+
+#: views/addons/policy.thtml:98
+msgid "a_cancel_installation"
+msgstr "Peruuta asennus"
+
+#. This is the text that appears on buttons to download add-ons.
+#. %$1s is an optional string that only appears if the add-on is only available for
+#. a certain platform. Examples: (Windows) or (Linux)
+#. Note that the parentheses are included in the string. :(
+#: views/elements/amo2009/install.thtml:126
+#: views/elements/amo2009/install.thtml:227
+#: views/elements/amo2009/install.thtml:257
+#: views/elements/amo2009/install.thtml:300
+#: views/elements/amo2009/install.thtml:312 views/elements/install.thtml:73
+#: views/elements/install.thtml:181 views/elements/install.thtml:205
+#: views/elements/install.thtml:248 views/elements/install.thtml:260
+#: views/addons/plugins.thtml:66 views/addons/plugins.thtml:76
+#: views/addons/plugins.thtml:86 views/addons/plugins.thtml:96
+#: views/addons/plugins.thtml:119
+#, php-format
+msgid "a_download"
+msgstr "Lataa %s"
+
+#: views/addons/policy.thtml:72
+msgid "a_eula_download"
+msgstr "Hyväksy ja lataa"
+
+#: views/addons/policy.thtml:74
+msgid "a_eula_install"
+msgstr "Hyväksy ja asenna"
+
+#: views/elements/header.thtml:76 views/elements/header.thtml:82
+#: views/api/api_addon.thtml:55 views/api/collections_feed.thtml:75
+#: views/sharing_api/addon.thtml:64
+msgid "a_header_public"
+msgstr "Julkinen"
+
+#: views/elements/header.thtml:58 views/elements/header.thtml:75
+#: views/elements/header.thtml:80 views/api/api_addon.thtml:57
+#: views/api/collections_feed.thtml:77 views/sharing_api/addon.thtml:66
+msgid "a_header_sandbox"
+msgstr "Hiekkalaatikko"
+
+#. %s is a date in the _('date') format
+#: views/elements/amo2009/homepage_addon.thtml:115
+#: views/elements/addon_listitem.thtml:122 views/elements/feature.thtml:106
+#: views/addons/display.thtml:104 views/addons/browse_thumbs.thtml:73
+#, fuzzy
+msgid "addon_detail_last_updated"
+msgstr "Updated %s"
+
+#. %s is the version of the add-on. Example: 3.2a1
+#: views/elements/amo2009/addon_version_detail.thtml:51
+#: views/elements/addon_version_detail.thtml:51
+#, php-format
+msgid "addon_display_header_version"
+msgstr "Versio %s"
+
+#: views/addons/browse_thumbs.thtml:80
+msgid "addon_downloads"
+msgstr "latausta"
+
+#: views/addons/display.thtml:147
+#, fuzzy
+msgid "addon_downloads_total"
+msgstr "total downloads"
+
+#: views/elements/amo2009/homepage_addon.thtml:106
+#: views/elements/addon_listitem.thtml:115 views/elements/feature.thtml:101
+#: views/addons/category_landing.thtml:157 views/addons/display.thtml:146
+#: views/addons/browse_thumbs.thtml:80
+#, fuzzy
+msgid "addon_downloads_weekly"
+msgstr "weekly downloads"
+
+#. %1 is the add-on count, %2 the category name
+#: views/addons/browse_thumbs.thtml:104 views/addons/browse.thtml:60
+#, php-format
+msgid "addon_list_category_totalcount"
+msgid_plural "addon_list_category_totalcount"
+msgstr[0] "%1$s lisäosa luokassa \"%2$s\""
+msgstr[1] "%1$s lisäosaa luokassa \"%2$s\""
+
+#: views/elements/amo2009/addon_list_options.thtml:103
+#: views/elements/pagination.thtml:67
+#: views/elements/addon_list_options.thtml:94
+msgid "addon_list_perpage"
+msgstr "yhdellä sivulla"
+
+#: views/elements/amo2009/addon_list_options.thtml:84
+#: views/elements/addon_list_options.thtml:98
+msgid "addon_list_sortby"
+msgstr "Järjestys:"
+
+#: views/helpers/addons_html.php:568 views/elements/amo2009/install.thtml:321
+#: views/elements/feature.thtml:89
+msgid "addon_listitem_flag_experimental"
+msgstr "kokeellinen"
+
+#: views/helpers/addons_html.php:570
+msgid "addon_listitem_flag_recommended"
+msgstr "suositeltu"
+
+#. %1 is the add-on name, %2 is the platform
+#: views/pages/js_constants.js.thtml:66
+msgid "addon_not_available_for_platform"
+msgstr "%1$s ei ole saatavilla alustalle %2$s."
+
+#. %1 is the add-on name
+#: views/addons/policy.thtml:101 views/addons/previews.thtml:60
+#: views/addons/versions.thtml:130 views/reviews/flag.thtml:61
+#: views/reviews/add.thtml:114 views/reviews/display.thtml:216
+#: views/reviews/review_added.thtml:57
+#, php-format
+msgid "addon_review_a_back_to_addon_x"
+msgstr "Palaa lisäosaan %1$s..."
+
+#. %1 is the add-on name
+#: views/reviews/flag.thtml:60 views/reviews/add.thtml:113
+#: views/reviews/review_added.thtml:56
+#, php-format
+msgid "addon_review_a_back_to_reviews"
+msgstr "Palaa arvosteluihin..."
+
+#: views/reviews/add.thtml:85
+msgid "addon_review_add_rating_field"
+msgstr "Pisteitä:"
+
+#: views/reviews/add.thtml:102
+msgid "addon_review_add_review_field"
+msgstr "Arvostelu:"
+
+#: views/reviews/add.thtml:107
+msgid "addon_review_add_submit"
+msgstr "Lähetä arvostelu"
+
+#. %s is the name of the add-on
+#: views/reviews/add.thtml:51
+#, php-format
+msgid "addon_review_add_title"
+msgstr "Kirjoita arvostelu lisäosalle %s"
+
+#: views/reviews/add.thtml:78
+msgid "addon_review_add_title_field"
+msgstr "Otsikko tai yhteenveto:"
+
+#: views/reviews/display.thtml:77 views/reviews/display.thtml:161
+msgid "addon_review_admin_delete"
+msgstr "Poista"
+
+#: views/reviews/display.thtml:76
+msgid "addon_review_author_reply_link"
+msgstr "Vastaa"
+
+#: views/reviews/delete.thtml:62
+msgid "addon_review_confirm_delete"
+msgstr "Poistetaanko arvostelu?"
+
+#: views/reviews/delete.thtml:63
+msgid "addon_review_confirm_no"
+msgstr "Ei"
+
+#: views/reviews/delete.thtml:64
+msgid "addon_review_confirm_yes"
+msgstr "Kyllä"
+
+#: views/reviews/delete.thtml:48
+msgid "addon_review_delete_header"
+msgstr "Poista arvostelu"
+
+#: controllers/reviews_controller.php:449
+msgid "addon_review_deleted_successfully"
+msgstr "Arvostelu poistettiin."
+
+#. %s is the name of the add-on
+#: views/reviews/add.thtml:51
+#, php-format
+msgid "addon_review_edit_title"
+msgstr "Muokkaa lisäosan %s arvostelua"
+
+#. %1 is the count of characters entered as notes for the review flag reason.
+#: controllers/reviews_controller.php:539
+#, fuzzy
+msgid "addon_review_flag_error_other_length"
+msgstr ""
+"Problem flagging review: Notes for flagged reviews are limited to between 10 "
+"and 100 characters; your character length was %1$s."
+
+#. Removing an extra comma
+#: views/reviews/review_added.thtml:53
+msgid "addon_review_in_moderation"
+msgstr ""
+"Huom.: Toimitus tarkistaa arvostelusi sisällön asiallisuuden ennen kuin se "
+"julkaistaan sivustolla."
+
+#: views/reviews/add.thtml:57
+msgid "addon_review_in_reply_to"
+msgstr "Tekijän vastaus:"
+
+#. %1 is the review count, %2 is the nickname or full name of the user.
+#: views/reviews/display.thtml:131
+#, fuzzy, php-format
+msgid "addon_review_others_by_user"
+msgid_plural "addon_review_others_by_user"
+msgstr[0] "See %1$s previous review submitted by %2$s for this add-on."
+msgstr[1] "See %1$s previous reviews submitted by %2$s for this add-on."
+
+#. %1 is the add-on name
+#: controllers/reviews_controller.php:201
+#: controllers/reviews_controller.php:250
+#: controllers/reviews_controller.php:345
+#: controllers/reviews_controller.php:424
+#, php-format
+msgid "addon_review_pagetitle"
+msgstr "Arvostelut lisäosasta %s"
+
+#. %1 is the user, %2 is the (localized) date
+#: views/reviews/display.thtml:160
+#, php-format
+msgid "addon_review_reply_on_x_by_y"
+msgstr "Vastauksen kirjoitti %1$s %2$s"
+
+#: views/reviews/display.thtml:157
+msgid "addon_review_reply_prefix"
+msgstr "Tekijän vastaus:"
+
+#: views/reviews/review_added.thtml:51
+msgid "addon_review_saved_successfully"
+msgstr "Arvostelusi tallennettiin. Kiitos vaivannäöstä!"
+
+#: views/addons/display.thtml:354 views/reviews/display.thtml:72
+#, fuzzy
+msgid "addon_reviewed_by_u_on_d"
+msgstr "by %1$s on %2$s"
+
+#. %1 is the user, %2 is the (localized) date, %3 is the rating
+#: views/editors/reviews_queue.thtml:57 views/editors/reviews_queue.thtml:68
+#: views/reviews/add.thtml:63 views/reviews/delete.thtml:54
+#, php-format
+msgid "addon_reviewed_on_x_rated_y"
+msgstr "Arvostelun kirjoitti %1$s %2$s (pisteitä %3$s)"
+
+#: views/elements/amo2009/addon_version_detail.thtml:52
+#: views/elements/addon_version_detail.thtml:52
+#, fuzzy
+msgid "addon_version_permalink"
+msgstr "Permanent link to this version"
+
+#. %1 is the current Application name (e.g. Firefox)
+#. %2 is the Application's version number
+#: views/addons/versions.thtml:140
+#, fuzzy
+msgid "addon_versions_getlatestversion"
+msgstr "The most recent version compatible with %1$s %2$s"
+
+#: views/addons/display.thtml:447
+#, fuzzy
+msgid "addons_author_addons_submit"
+msgstr "Go"
+
+#: views/elements/amo2009/homepage_addon.thtml:100
+#: views/elements/feature.thtml:95
+#, fuzzy
+msgid "addons_author_tooltip"
+msgstr "View Author's Profile"
+
+#. %1 is the name of the Application (eg. Firefox)
+#: controllers/addons_controller.php:1296
+#, fuzzy
+msgid "addons_browse_all_themes_title"
+msgstr "Browse all Themes :: %1$s Add-ons"
+
+#. %s is the name of the category
+#: controllers/addons_controller.php:1016
+#, php-format
+msgid "addons_browse_browse_category"
+msgstr "Selaa %s"
+
+#. %1 is the name of the theme category (eg. Modern)
+#. %2 is the name of the Application (eg. Firefox)
+#: controllers/addons_controller.php:664
+#, fuzzy
+msgid "addons_browse_categories_header_theme"
+msgstr "Browse %1$s Themes :: %2$s Add-ons"
+
+#: views/addons/display.thtml:249
+#, fuzzy
+msgid "addons_display_a_license_what"
+msgstr "What's this?"
+
+#: views/reviews/display.thtml:222
+msgid "addons_display_add_review"
+msgstr "Kirjoita arvostelu"
+
+#: views/addons/display.thtml:294
+msgid "addons_display_advanced_details"
+msgstr "Lisätietoja"
+
+#: views/addons/display.thtml:98
+msgid "addons_display_categories"
+msgstr "Luokat"
+
+#: views/addons/display.thtml:482
+#, fuzzy
+msgid "addons_display_collection_add"
+msgstr "Add to a collection:"
+
+#: views/addons/display.thtml:491
+#, fuzzy
+msgid "addons_display_collection_add_new"
+msgstr "New Collection..."
+
+#: views/addons/display.thtml:487
+#, fuzzy
+msgid "addons_display_collection_add_select_one"
+msgstr "Select a collection..."
+
+#: views/addons/display.thtml:493
+#, fuzzy
+msgid "addons_display_collection_add_submit"
+msgstr "Publish"
+
+#. %1$s is the add-on name
+#. %2$s is the collection name, linked to the collection's page
+#: views/pages/js_constants.js.thtml:103 views/addons/display.thtml:61
+#, fuzzy
+msgid "addons_display_collection_publish_success"
+msgstr "%1$s has been added to the %2$s collection."
+
+#: views/addons/display.thtml:483
+#, fuzzy
+msgid "addons_display_collection_whatsthis"
+msgstr "What's this?"
+
+#. %1$s is a number
+#: views/addons/display.thtml:473
+#, fuzzy
+msgid "addons_display_collections_more"
+msgid_plural "addons_display_collections_more"
+msgstr[0] "and %1$s more collection"
+msgstr[1] "and %1$s more collections"
+
+#: views/addons/display.thtml:403
+msgid "addons_display_detailed_review"
+msgstr "yksityiskohtainen arvostelu"
+
+#: views/reviews/add.thtml:89 views/reviews/add.thtml:90
+msgid "addons_display_dont_like_it"
+msgstr "En pidä"
+
+#: views/reviews/display.thtml:220
+msgid "addons_display_edit_review"
+msgstr "Muokkaa arvosteluasi"
+
+#: views/addons/display.thtml:132
+msgid "addons_display_has_privacy"
+msgstr "Lisäosalla on tietosuojakäytäntö"
+
+#: views/reviews/add.thtml:87 views/reviews/add.thtml:88
+msgid "addons_display_hate_it"
+msgstr "Vihaan"
+
+#: views/addons/display.thtml:462
+#, fuzzy
+msgid "addons_display_header_collections"
+msgstr "Related Collections"
+
+#: views/addons/display.thtml:297
+msgid "addons_display_header_developer_comments"
+msgstr "Tekijän kommentteja"
+
+#: views/addons/display.thtml:230
+#, fuzzy
+msgid "addons_display_header_homepage"
+msgstr "Homepage"
+
+#: views/addons/display.thtml:247 views/addons/versions.thtml:110
+#, fuzzy
+msgid "addons_display_header_license"
+msgstr "Source Code License"
+
+#: views/addons/display.thtml:337
+msgid "addons_display_header_reviews"
+msgstr "Arvostelut"
+
+#: views/addons/display.thtml:261
+#, fuzzy
+msgid "addons_display_header_support"
+msgstr "Support"
+
+#: views/reviews/add.thtml:91 views/reviews/add.thtml:92
+msgid "addons_display_like_it"
+msgstr "Pidän"
+
+#: views/addons/display.thtml:210
+msgid "addons_display_long_description"
+msgstr "Pitkä kuvaus"
+
+#: views/reviews/add.thtml:95 views/reviews/add.thtml:96
+msgid "addons_display_love_it"
+msgstr "Rakastan"
+
+#: views/addons/display.thtml:178
+msgid "addons_display_more_images"
+msgstr "Lisää kuvia"
+
+#: views/addons/display.thtml:465
+#, fuzzy
+msgid "addons_display_nocollections"
+msgstr "This add-on is not yet in any collections."
+
+#. %1$s is either an author's name or a comma separated list of authors. Using
+#. the list doesn't make sense in the English plural form so we ignore the
+#. variable.
+#: views/addons/display.thtml:436
+#, fuzzy
+msgid "addons_display_other_addons_by"
+msgid_plural "addons_display_other_addons_by"
+msgstr[0] "Muut lisäosat tekijältä %1$s"
+msgstr[1] "Other add-ons by these authors"
+
+#. %s is the name of the add-on and the add-on section. Example:
+#. Some Add-on :: Firefox Add-ons
+#. This should not be concatenated in the code and should be fixed.
+#: controllers/addons_controller.php:141 controllers/addons_controller.php:280
+#: controllers/addons_controller.php:1442
+#, php-format
+msgid "addons_display_pagetitle"
+msgstr "%s"
+
+#. %s is an email address
+#: views/addons/display.thtml:286
+#, fuzzy, php-format
+msgid "addons_display_paragraph_supportinfoemail"
+msgstr ""
+"Support for this Extension is available at %s.If you have a bug report it "
+"might be best to file it with the developer so that that they can follow up "
+"with you. Reviews are not really the place for detailed bug reports, and the "
+"developer may require several details in order to re-create the bug. Since "
+"we do not make your email address available to extension developers when you "
+"post a review, they will not be able to contact you to ask for more details "
+"or let you know if the bug has been fixed in an upcoming version."
+
+#. %$1s is a URL
+#. %$2s is an email address
+#: views/addons/display.thtml:269
+#, fuzzy, php-format
+msgid "addons_display_paragraph_supportinfoemailurl"
+msgstr ""
+"Support for this Extension is available at %s or %s. If you have a bug "
+"report it might be best to file it with the developer so that that they can "
+"follow up with you. Reviews are not really the place for detailed bug "
+"reports, and the developer may require several details in order to re-create "
+"the bug. Since we do not make your email address available to extension "
+"developers when you post a review, they will not be able to contact you to "
+"ask for more details or let you know if the bug has been fixed in an "
+"upcoming version."
+
+#. %s is a URL
+#: views/addons/display.thtml:278
+#, fuzzy, php-format
+msgid "addons_display_paragraph_supportinfourl"
+msgstr ""
+"Support for this Extension is available at %s. If you have a bug report it "
+"might be best to file it with the developer so that that they can follow up "
+"with you. Reviews are not really the place for detailed bug reports, and the "
+"developer may require several details in order to re-create the bug. Since "
+"we do not make your email address available to extension developers when you "
+"post a review, they will not be able to contact you to ask for more details "
+"or let you know if the bug has been fixed in an upcoming version."
+
+#: views/addons/display.thtml:383
+msgid "addons_display_rate_it"
+msgstr "Pisteytä lisäosa"
+
+#: views/reviews/add.thtml:93 views/reviews/add.thtml:94
+msgid "addons_display_really_like_it"
+msgstr "Tosissaan pidän"
+
+#: views/addons/display.thtml:410
+#, fuzzy
+msgid "addons_display_review_etiquette"
+msgstr ""
+"Please do not post bug reports in reviews. We do not make your email address "
+"available to add-on developers and they may need to contact you to help "
+"resolve your issue."
+
+#. %1 is the review guidelines link
+#: views/addons/display.thtml:417
+#, fuzzy
+msgid "addons_display_review_guidelines_link"
+msgstr "<a href=\"%s\">Review Guidelines</a>"
+
+#. %1 is the support section link
+#: views/addons/display.thtml:414
+#, fuzzy
+msgid "addons_display_review_see_support"
+msgstr ""
+"See the <a href=\"%1$s\">support section</a> to find out where to get "
+"assistance for this add-on."
+
+#: views/addons/display.thtml:404
+#, fuzzy
+msgid "addons_display_review_submit"
+msgstr "Save"
+
+#: views/addons/display.thtml:430
+#, php-format
+msgid "addons_display_see_all_addons"
+msgstr "Näytä kaikki \"%1$s\" lisäosat"
+
+#. %1 is the number of reviews
+#: views/addons/display.thtml:364
+#, php-format
+msgid "addons_display_see_all_reviews"
+msgstr "Näytä kaikki arvostelut (%1$s)"
+
+#: views/addons/display.thtml:219
+#, fuzzy
+msgid "addons_display_see_all_versions"
+msgstr "See All Versions"
+
+#: views/addons/display.thtml:321 views/addons/versions.thtml:117
+msgid "addons_display_view_source"
+msgstr "Näytä lähdekoodi"
+
+#: views/addons/display.thtml:324
+msgid "addons_display_view_stats"
+msgstr "Näytä tilastotietoja"
+
+#: views/addons/display.thtml:376
+msgid "addons_display_what_do_you_think"
+msgstr "Mitä mieltä olet?"
+
+#: views/elements/app_compatibility.thtml:49
+msgid "addons_display_workswith"
+msgstr "Toimii seuraavilla ohjelmaversioilla:"
+
+#: views/addons/home.thtml:112
+#, fuzzy
+msgid "addons_home_browse_new"
+msgstr "Just Added"
+
+#: views/addons/home.thtml:110
+#, fuzzy
+msgid "addons_home_browse_popular"
+msgstr "Popular"
+
+#: views/addons/home.thtml:108
+#, fuzzy
+msgid "addons_home_browse_recommended"
+msgstr "Recommended"
+
+#: views/addons/home.thtml:127 views/addons/home.thtml:134
+#: views/addons/home.thtml:141 views/addons/home.thtml:148
+#, fuzzy
+msgid "addons_home_browse_subscribe"
+msgstr "Subscribe"
+
+#: views/addons/home.thtml:101
+#, fuzzy
+msgid "addons_home_browse_title"
+msgstr "Browse Add-ons"
+
+#: views/addons/home.thtml:114
+#, fuzzy
+msgid "addons_home_browse_updated"
+msgstr "Updated"
+
+#: views/elements/amo2009/homepage_addon.thtml:100
+#: views/elements/addon_discussionheader.thtml:83
+#: views/elements/addon_listitem.thtml:109 views/elements/feature.thtml:95
+#: views/addons/category_landing.thtml:66 views/addons/policy.thtml:57
+#: views/addons/display.thtml:70 views/addons/home.thtml:178
+msgid "addons_home_by"
+msgstr "Tekijänä"
+
+#: views/addons/home.thtml:169
+#, fuzzy
+msgid "addons_home_collection_popular_title"
+msgstr "Popular Collections"
+
+#: views/elements/amo2009/categories.thtml:69 views/addons/home.thtml:160
+#, fuzzy
+msgid "addons_home_collections"
+msgstr "Collections"
+
+#. %1$s is the count of addons in a collection
+#: views/elements/amo2009/collection_listing_item.thtml:51
+#: views/addons/home.thtml:185
+#, fuzzy
+msgid "addons_home_collections_addon_count"
+msgid_plural "addons_home_collections_addon_count"
+msgstr[0] "<strong>%1$s</strong> add-on"
+msgstr[1] "<strong>%1$s</strong> add-ons"
+
+#: views/addons/home.thtml:196
+#, fuzzy
+msgid "addons_home_collections_all"
+msgstr "View All Collections"
+
+#: views/addons/home.thtml:162
+#, fuzzy
+msgid "addons_home_collections_intro"
+msgstr ""
+"Collections are a way for you to categorize, mix, match and mingle add-ons. "
+"Subscribe to collections created by other users or create your own."
+
+#. %1$s is the count of subscribers for a collection
+#: views/elements/amo2009/collection_listing_item.thtml:58
+#: views/collections/detail.thtml:96 views/addons/home.thtml:189
+#, fuzzy
+msgid "addons_home_collections_subscribers"
+msgid_plural "addons_home_collections_subscribers"
+msgstr[0] "<strong>%1$s</strong> subscriber"
+msgstr[1] "<strong>%1$s</strong> subscribers"
+
+#: views/addons/searchengines.thtml:54 views/addons/themes_landing.thtml:49
+msgid "addons_home_feature_head"
+msgstr "Suosittelemme"
+
+#: controllers/search_controller.php:218 controllers/addons_controller.php:176
+#: controllers/addons_controller.php:428 controllers/addons_controller.php:671
+#: controllers/addons_controller.php:871
+#: controllers/addons_controller.php:1103
+#: controllers/addons_controller.php:1242
+#: controllers/addons_controller.php:1298
+#, php-format
+msgid "addons_home_header_details"
+msgstr ""
+"Lisäosat muuttavat %1$sin toimintatapaa. Niiden avulla voit muuttaa ohjelman "
+"toimimaan haluamallasi tavalla. Tutki eri vaihtoehtoja ja tee %1$sista "
+"itsesi näköinen."
+
+#. %1$s is the HTML collection name link.
+#: views/elements/amo2009/teaser_collections.thtml:107
+#, fuzzy
+msgid "addons_home_introduction_collection_link"
+msgstr "Like these? Find more add-ons in %1$s."
+
+#: views/elements/amo2009/teaser_collections.thtml:60
+#, fuzzy
+msgid "addons_home_introduction_extras"
+msgstr ""
+"<strong>Over 5000 free extras</strong> that let you customize and extend "
+"Firefox to meet your needs."
+
+#: views/elements/amo2009/teaser_collections.thtml:55
+#, fuzzy
+msgid "addons_home_introduction_header"
+msgstr "What are Add-ons?"
+
+#: views/elements/amo2009/teaser_collections.thtml:72
+#, fuzzy
+msgid "addons_home_introduction_install"
+msgstr ""
+"<strong>Easy to install</strong>, get notified when updates are available."
+
+#: views/elements/amo2009/teaser_collections.thtml:45
+#, fuzzy
+msgid "addons_home_introduction_name"
+msgstr "Introduction"
+
+#: views/elements/amo2009/teaser_collections.thtml:66
+#, fuzzy
+msgid "addons_home_introduction_themes"
+msgstr ""
+"Toolbars, themes and search providers that <strong>help you perform common "
+"tasks.</strong>"
+
+#: views/addons/home.thtml:161
+#, fuzzy
+msgid "addons_home_new_indicator"
+msgstr "NEW!"
+
+#: views/elements/app_chooser.thtml:48 views/layouts/amo2009.thtml:257
+msgid "addons_home_other_applications"
+msgstr "Muut ohjelmat"
+
+#. %1$s is the application the user is browsing. Examples: Thunderbird, Firefox,
+#. Sunbird
+#: views/pages/collector_faq.thtml:49 views/pages/collector_firstrun.thtml:42
+#: views/pages/collector.thtml:46 views/pages/collector_features.thtml:54
+#: controllers/developers_controller.php:87
+#: controllers/compatibility_controller.php:72
+#: controllers/components/simple_acl.php:81 controllers/components/amo.php:607
+#: controllers/statistics_controller.php:60
+#: controllers/statistics_controller.php:240
+#: controllers/previews_controller.php:67 controllers/users_controller.php:90
+#: controllers/users_controller.php:223 controllers/users_controller.php:330
+#: controllers/users_controller.php:414 controllers/users_controller.php:708
+#: controllers/users_controller.php:723 controllers/reviews_controller.php:204
+#: controllers/reviews_controller.php:251
+#: controllers/reviews_controller.php:346
+#: controllers/reviews_controller.php:425
+#: controllers/search_controller.php:185 controllers/search_controller.php:297
+#: controllers/search_controller.php:301 controllers/addons_controller.php:147
+#: controllers/addons_controller.php:280 controllers/addons_controller.php:370
+#: controllers/addons_controller.php:667 controllers/addons_controller.php:874
+#: controllers/addons_controller.php:1019
+#: controllers/addons_controller.php:1034
+#: controllers/addons_controller.php:1101
+#: controllers/addons_controller.php:1121
+#: controllers/addons_controller.php:1240
+#: controllers/addons_controller.php:1357
+#: controllers/addons_controller.php:1364
+#: controllers/addons_controller.php:1442
+#: controllers/addons_controller.php:1477
+#: controllers/addons_controller.php:1538
+#: controllers/addons_controller.php:1543
+#: controllers/editors_controller.php:64 controllers/pages_controller.php:132
+#: controllers/groups_controller.php:65 controllers/groups_controller.php:71
+#: controllers/groups_controller.php:89 controllers/groups_controller.php:111
+#: controllers/collections_controller.php:57
+#: controllers/collections_controller.php:121
+#: controllers/collections_controller.php:205
+#: controllers/collections_controller.php:365
+#: controllers/collections_controller.php:404
+#: controllers/collections_controller.php:466
+#: controllers/collections_controller.php:538
+#: controllers/collections_controller.php:828
+#: controllers/localizers_controller.php:72
+#, php-format
+msgid "addons_home_pagetitle"
+msgstr "%1$sin lisäosat"
+
+#. %1$s is the number of addons downloaded
+#: views/addons/home.thtml:57
+#, fuzzy, php-format
+msgid "addons_home_stats_downloaded"
+msgid_plural "addons_home_stats_downloaded"
+msgstr[0] "<strong>%1$s</strong> <span>add-on downloaded</span>"
+msgstr[1] "<strong>%1$s</strong> <span>add-ons downloaded</span>"
+
+#. %1$s is the number of addons in use
+#: views/addons/home.thtml:63
+#, fuzzy, php-format
+msgid "addons_home_stats_inuse"
+msgid_plural "addons_home_stats_inuse"
+msgstr[0] "<strong>%1$s</strong> <span>add-on in use</span>"
+msgstr[1] "<strong>%1$s</strong> <span>add-ons in use</span>"
+
+#: views/addons/home.thtml:136
+#, fuzzy
+msgid "addons_home_view_all_newest_title"
+msgstr "View all newly created add-ons"
+
+#: views/addons/home.thtml:129
+msgid "addons_home_view_all_popular_title"
+msgstr "Näytä kaikki suositus lisäosat"
+
+#: views/addons/home.thtml:150
+msgid "addons_home_view_all_recommended_title"
+msgstr "Näytä kaikki suositellut lisäosat"
+
+#: views/addons/home.thtml:143
+#, fuzzy
+msgid "addons_home_view_all_updated_title"
+msgstr "View all recently updated add-ons"
+
+#: views/elements/amo2009/install.thtml:334 views/elements/install.thtml:112
+#, fuzzy
+msgid "addons_install_in_sunbird"
+msgstr ""
+"<ol><li>Click the link below to save the file.</li><li>In Mozilla Sunbird, "
+"open Add-ons from the Tools menu.</li><li>Click the Install button, and "
+"locate/select the file you downloaded and click \"OK\".</li></ol>"
+
+#: views/elements/amo2009/install.thtml:333 views/elements/install.thtml:111
+#, fuzzy
+msgid "addons_install_in_sunbird_title"
+msgstr "How to Install in Sunbird"
+
+#: views/elements/amo2009/install.thtml:331 views/elements/install.thtml:106
+msgid "addons_install_in_thunderbird"
+msgstr ""
+"<ol><li>Napsauta alla olevaa linkkiä hiiren oikealla painikkeella ja valitse "
+"\"Tallenna kohde levylle...\" Lisäosan asennustiedosto tallennetaan "
+"kiintolevylle.</li><li>Avaa lisäosien hallintaikkuna Mozilla Thunderbirdissä "
+"Työkalut-valikosta.</li><li>Napsauta Asenna-painiketta, valitse edellä "
+"tallentamasi asennustiedosto ja napsauta OK-painiketta.</li></ol>"
+
+#: views/elements/amo2009/install.thtml:330 views/elements/install.thtml:105
+msgid "addons_install_in_thunderbird_title"
+msgstr "Lisäosan asentaminen Thunderbirdiin"
+
+#: views/elements/amo2009/addon_list_options.thtml:108
+#: views/elements/addon_list_options.thtml:105
+msgid "addons_options_show_experimental"
+msgstr "näytä kokeelliset lisäosat"
+
+#: views/elements/amo2009/addon_list_options.thtml:113
+#: views/elements/addon_list_options.thtml:109
+msgid "addons_options_submit"
+msgstr "Valmis"
+
+#: views/addons/plugins.thtml:63 views/addons/plugins.thtml:73
+#: views/addons/plugins.thtml:83 views/addons/plugins.thtml:93
+#: views/addons/plugins.thtml:103 views/addons/plugins.thtml:116
+#: views/addons/plugins.thtml:126
+msgid "addons_plugins_by"
+msgstr "Tekijänä"
+
+#: views/addons/plugins.thtml:107
+msgid "addons_plugins_for_linux"
+msgstr "Linuxille"
+
+#: views/addons/plugins.thtml:108 views/addons/plugins.thtml:131
+msgid "addons_plugins_for_macosx"
+msgstr "Mac OS X:lle"
+
+#: views/addons/plugins.thtml:106 views/addons/plugins.thtml:129
+#: views/addons/plugins.thtml:130
+msgid "addons_plugins_for_windows"
+msgstr "Windowsille"
+
+#. %1$s is a URL
+#: views/addons/plugins.thtml:139
+#, php-format
+msgid "addons_plugins_looking_for_more"
+msgstr ""
+"Vain tavallisimmat ja suosituimmat liitännäiset on listattu tälle sivulle. "
+"Voit lukea muista Mozilla-pohjaisille selaimille olemassa olevista "
+"liitännäisistä sivulta %1$s"
+
+#: views/addons/plugins.thtml:137
+msgid "addons_plugins_looking_for_plugin"
+msgstr "Eikö etsimääsi liitännäistä löytynyt?"
+
+#: views/addons/plugins.thtml:58
+msgid "addons_plugins_main_description"
+msgstr ""
+"Liitännäisten avulla selaimet kykenevät näyttämään tiettyjä kuva- tai "
+"mediatiedostoja, joita ne eivät muuten voisi näyttää. Liitännäiset ovat "
+"kuitenkin eri asia kuin laajennukset, jotka nekin lisäävät tai muuttavat "
+"selaimen toimintaa."
+
+#. %1$s is the application name. Example: Firefox, Thunderbird, Sunbird
+#: controllers/addons_controller.php:1122
+#, php-format
+msgid "addons_plugins_main_header"
+msgstr "keskeisimmät liitännäiset"
+
+#: controllers/components/amo.php:698 controllers/addons_controller.php:1121
+msgid "addons_plugins_pagetitle"
+msgstr "Liitännäiset"
+
+#: views/addons/plugins.thtml:68 views/addons/plugins.thtml:78
+#: views/addons/plugins.thtml:88 views/addons/plugins.thtml:98
+#: views/addons/plugins.thtml:110 views/addons/plugins.thtml:121
+#: views/addons/plugins.thtml:133
+msgid "addons_plugins_support_documentation"
+msgstr "Ohjeita ongelmatilanteisiin: "
+
+#. %s is the name of the add-on
+#: views/addons/policy.thtml:61
+#, php-format
+msgid "addons_policy_eula_require"
+msgstr ""
+"Lisäosaa %s ei voi asentaa ennen kuin seuraava loppukäyttäjän lisenssi "
+"(EULA) hyväksytään:"
+
+#. %1 is the add-on name
+#: controllers/addons_controller.php:1476
+#, php-format
+msgid "addons_previews_pagetitle"
+msgstr "Esikatselukuvat lisäosasta %s"
+
+#: views/addons/category_landing.thtml:135
+#, fuzzy
+msgid "addons_recently_added"
+msgstr "Recently Added"
+
+#: views/addons/recommended.thtml:51 controllers/addons_controller.php:1365
+msgid "addons_recommended_introduction"
+msgstr ""
+"Lisäosia on niin paljon, että jokaiselle löytyy jotakin mieleistä. Alle on "
+"listattu muutama suosittu lisäosa, jotta pääsisit vauhtiin. Pidä hauskaa!"
+
+#: controllers/addons_controller.php:1357
+#: controllers/addons_controller.php:1364
+msgid "addons_recommended_pagetitle"
+msgstr "Suositeltuja lisäosia"
+
+#: controllers/addons_controller.php:1360
+msgid "addons_recommended_title"
+msgstr "suositeltuja lisäosia"
+
+#: views/addons/searchengines.thtml:136
+#, fuzzy
+msgid "addons_searchengines_additional_resources"
+msgstr "Additional Resources"
+
+#. link text devmo
+#: views/addons/searchengines.thtml:141
+#, fuzzy
+msgid "addons_searchengines_devmo_link"
+msgstr "Mozilla Developer Center"
+
+#: views/pages/js_constants.js.thtml:67
+msgid "addons_searchengines_error_mozilla_browser_required"
+msgstr ""
+"Ikävä kyllä näitä hakukoneita voi asentaa vain Mozilla-pohjaisiin selaimiin "
+"kuten Firefox."
+
+#: views/addons/searchengines.thtml:49
+msgid "addons_searchengines_error_nojavascript"
+msgstr ""
+"Hakukoneiden asentaminen onnistuu vain jos sivuston on sallittu käyttää "
+"JavaScript-komentosarjoja. Salli JavaScriptin käyttö ennen kuin yrität "
+"asentaa hakukoneita."
+
+#. %1 is "make your own" link
+#. %2 is MDC link
+#: views/addons/searchengines.thtml:139
+#, fuzzy
+msgid "addons_searchengines_learn_howto"
+msgstr "Learn how to %1$s at the %2$s."
+
+#. link path to search plugins instructions, relative to devmo
+#: views/addons/searchengines.thtml:140
+#, fuzzy
+msgid "addons_searchengines_makeyourown_href"
+msgstr "/en/docs/Creating_OpenSearch_plugins_for_Firefox"
+
+#. link text for "make your own" (opensearch engine)
+#: views/addons/searchengines.thtml:140
+#, fuzzy
+msgid "addons_searchengines_makeyourown_link"
+msgstr "make your own"
+
+#. %1 is the link to mycroft.mozdev.org
+#: views/addons/searchengines.thtml:138
+#, fuzzy
+msgid "addons_searchengines_more"
+msgstr "Browse through more search engines at %1$s"
+
+#. link text to mycroft.mozdev.org
+#: views/addons/searchengines.thtml:138
+#, fuzzy
+msgid "addons_searchengines_mycroft_link"
+msgstr "mycroft.mozdev.org"
+
+#: controllers/addons_controller.php:1100
+#: controllers/addons_controller.php:1110
+msgid "addons_searchengines_pagetitle"
+msgstr "Hakukoneet"
+
+#: views/addons/searchengines.thtml:143
+#, fuzzy
+msgid "addons_searchengines_thanks"
+msgstr ""
+"Special thanks to the Mycroft Project for their work on Firefox Search "
+"Engines."
+
+#: views/addons/display.thtml:154
+#, fuzzy
+msgid "addons_share_button_text"
+msgstr "Share this"
+
+#: controllers/addons_controller.php:89
+#, fuzzy
+msgid "addons_share_label_delicious"
+msgstr "Add to Delicious"
+
+#: controllers/addons_controller.php:77
+#, fuzzy
+msgid "addons_share_label_digg"
+msgstr "Digg this!"
+
+#: controllers/addons_controller.php:83
+#, fuzzy
+msgid "addons_share_label_facebook"
+msgstr "Post to Facebook"
+
+#: controllers/addons_controller.php:101
+#, fuzzy
+msgid "addons_share_label_friendfeed"
+msgstr "Share on FriendFeed"
+
+#: controllers/addons_controller.php:95
+#, fuzzy
+msgid "addons_share_label_myspace"
+msgstr "Post to MySpace"
+
+#: controllers/components/amo.php:201 controllers/components/amo.php:229
+#, fuzzy
+msgid "addons_status_disabled"
+msgstr "Disabled"
+
+#: controllers/components/amo.php:191 controllers/components/amo.php:224
+#, fuzzy
+msgid "addons_status_incomplete"
+msgstr "Incomplete Version"
+
+#: controllers/components/amo.php:197 controllers/components/amo.php:227
+#, fuzzy
+msgid "addons_status_nominated"
+msgstr "In Sandbox; Public Nomination"
+
+#: views/pages/js_constants.js.thtml:80 controllers/components/amo.php:195
+#: controllers/components/amo.php:226
+#, fuzzy
+msgid "addons_status_pending"
+msgstr "In Sandbox; Pending Review"
+
+#: views/pages/js_constants.js.thtml:78 controllers/components/amo.php:199
+#: controllers/components/amo.php:228
+#, fuzzy
+msgid "addons_status_public"
+msgstr "Public"
+
+#: views/pages/js_constants.js.thtml:79 controllers/components/amo.php:193
+#: controllers/components/amo.php:225
+#, fuzzy
+msgid "addons_status_sandbox"
+msgstr "In Sandbox"
+
+#: controllers/components/amo.php:203
+#, fuzzy
+msgid "addons_status_unknown"
+msgstr "Unknown"
+
+#: views/elements/amo2009/teaser_collections.thtml:91
+#: views/elements/amo2009/homepage_addon.thtml:99
+#: views/elements/feature.thtml:94
+#, fuzzy
+msgid "addons_title_tooltip"
+msgstr "Learn more about this add-on"
+
+#: views/addons/category_landing.thtml:151
+#, fuzzy
+msgid "addons_top_downloads"
+msgstr "Top Downloads"
+
+#: views/addons/category_landing.thtml:165
+#, fuzzy
+msgid "addons_top_rated"
+msgstr "Top Rated"
+
+#: views/addons/versions.thtml:62
+msgid "addons_versions_careful"
+msgstr "Olethan aina varovainen vanhojen versioiden kanssa"
+
+#: views/addons/versions.thtml:63
+msgid "addons_versions_careful_introduction"
+msgstr ""
+"Nämä versiot ovat esillä vain testaus- ja referenssimielessä. On aina "
+"suositeltua käyttää lisäosan viimeisintä versiota."
+
+#: controllers/addons_controller.php:1549
+msgid "addons_versions_history"
+msgstr "Versiohistoria muutostietojen kera"
+
+#. %1$s is the add-on name
+#: controllers/addons_controller.php:1535
+#, php-format
+msgid "addons_versions_pagetitle"
+msgstr "%1$s versiohistoria"
+
+#: controllers/groups_controller.php:71
+msgid "admin_group_add_pagetitle"
+msgstr "Lisää ryhmä"
+
+#: controllers/groups_controller.php:111
+msgid "admin_group_delete_pagetitle"
+msgstr "Poista ryhmä"
+
+#. %s is a number to identify the group
+#: controllers/groups_controller.php:117
+#, php-format
+msgid "admin_group_deleted"
+msgstr "Ryhmä, jonka tunnus oli %s, poistettiin"
+
+#: controllers/groups_controller.php:89
+msgid "admin_group_edit_pagetitle"
+msgstr "Muokkaa ryhmää"
+
+#: controllers/groups_controller.php:92 controllers/groups_controller.php:113
+msgid "admin_group_error_invalid_id"
+msgstr "Virheellinen ryhmätunnus"
+
+#: controllers/groups_controller.php:65
+msgid "admin_group_pagetitle"
+msgstr "Ryhmän ylläpitäjä"
+
+#: controllers/groups_controller.php:77 controllers/groups_controller.php:99
+msgid "admin_group_saved"
+msgstr "Ryhmä on tallennettu"
+
+#: views/elements/amo2009/search.thtml:257 views/elements/search.thtml:239
+#, fuzzy
+msgid "advanced_search_form"
+msgstr "Advanced"
+
+#: views/elements/amo2009/search.thtml:126 views/elements/search.thtml:125
+#, fuzzy
+msgid "advanced_search_form_any_time"
+msgstr "Any time"
+
+#: views/elements/amo2009/search.thtml:97
+#: views/elements/amo2009/search.thtml:110 views/elements/search.thtml:96
+#: views/elements/search.thtml:109
+#, fuzzy
+msgid "advanced_search_form_any_type"
+msgstr "Any"
+
+#: views/elements/amo2009/search.thtml:275 views/elements/search.thtml:254
+#, fuzzy
+msgid "advanced_search_form_any_version"
+msgstr "Any"
+
+#: views/elements/amo2009/search.thtml:217 views/elements/search.thtml:212
+#, fuzzy
+msgid "advanced_search_form_application"
+msgstr "Application"
+
+#: views/elements/amo2009/search.thtml:143 views/elements/search.thtml:142
+#, fuzzy
+msgid "advanced_search_form_keyword_match"
+msgstr "Keyword Match"
+
+#: views/elements/amo2009/search.thtml:251 views/elements/search.thtml:225
+#, fuzzy
+msgid "advanced_search_form_lastupdate"
+msgstr "Last Updated"
+
+#: views/elements/amo2009/search.thtml:145 views/elements/search.thtml:144
+#, fuzzy
+msgid "advanced_search_form_name"
+msgstr "Name"
+
+#: views/elements/amo2009/search.thtml:144 views/elements/search.thtml:143
+#, fuzzy
+msgid "advanced_search_form_newest"
+msgstr "Newest"
+
+#: views/elements/amo2009/search.thtml:130 views/elements/search.thtml:129
+#, fuzzy
+msgid "advanced_search_form_past_3_months"
+msgstr "Past 3 months"
+
+#: views/elements/amo2009/search.thtml:131 views/elements/search.thtml:130
+#, fuzzy
+msgid "advanced_search_form_past_6_months"
+msgstr "Past 6 months"
+
+#: views/elements/amo2009/search.thtml:127 views/elements/search.thtml:126
+#, fuzzy
+msgid "advanced_search_form_past_day"
+msgstr "Past Day"
+
+#: views/elements/amo2009/search.thtml:129 views/elements/search.thtml:128
+#, fuzzy
+msgid "advanced_search_form_past_month"
+msgstr "Past month"
+
+#: views/elements/amo2009/search.thtml:128 views/elements/search.thtml:127
+#, fuzzy
+msgid "advanced_search_form_past_week"
+msgstr "Past week"
+
+#: views/elements/amo2009/search.thtml:132 views/elements/search.thtml:131
+#, fuzzy
+msgid "advanced_search_form_past_year"
+msgstr "Past year"
+
+#: views/elements/amo2009/search.thtml:239 views/elements/search.thtml:230
+#, fuzzy
+msgid "advanced_search_form_perpage"
+msgstr "Per Page"
+
+#: views/elements/amo2009/search.thtml:243 views/elements/search.thtml:224
+#, fuzzy
+msgid "advanced_search_form_platform"
+msgstr "Platform"
+
+#: views/elements/amo2009/search.thtml:147 views/elements/search.thtml:146
+#, fuzzy
+msgid "advanced_search_form_popularity"
+msgstr "Popularity"
+
+#: views/elements/amo2009/search.thtml:146 views/elements/search.thtml:145
+#, fuzzy
+msgid "advanced_search_form_rating"
+msgstr "Rating"
+
+#: views/elements/amo2009/search.thtml:247 views/elements/search.thtml:231
+#, fuzzy
+msgid "advanced_search_form_sortby"
+msgstr "Sort By"
+
+#: views/elements/amo2009/search.thtml:227 views/elements/search.thtml:216
+#, fuzzy
+msgid "advanced_search_form_to"
+msgstr "to"
+
+#: views/elements/amo2009/search.thtml:257 views/elements/search.thtml:237
+#, fuzzy
+msgid "advanced_search_form_toggle_tooltip"
+msgstr "Toggle advanced search mode"
+
+#: views/elements/amo2009/search.thtml:235 views/elements/search.thtml:223
+#, fuzzy
+msgid "advanced_search_form_type"
+msgstr "Type"
+
+#: views/elements/amo2009/search.thtml:222 views/elements/search.thtml:214
+#, fuzzy
+msgid "advanced_search_form_version"
+msgstr "version"
+
+#: views/elements/amo2009/pagination.thtml:42
+#, fuzzy
+msgid "amo2009_pagination_next_page"
+msgstr "Next"
+
+#: views/elements/amo2009/pagination.thtml:41
+#, fuzzy
+msgid "amo2009_pagination_previous_page"
+msgstr "Prev"
+
+#: views/pages/js_constants.js.thtml:96
+#, fuzzy
+msgid "app_compat_ignore_check"
+msgstr "Ignore version check"
+
+#: views/pages/js_constants.js.thtml:72
+msgid "app_compat_older_firefox_only"
+msgstr "Tämä lisäosa on tarkoitettu vanhemmille versioille Firefoxista"
+
+#. %1$s and %2$s are URLs
+#: views/pages/js_constants.js.thtml:74
+#, fuzzy
+msgid "app_compat_older_version_or_ignore_check"
+msgstr ""
+"You can <a href=\"%1$s\">try an older version</a> or <a href=\"#\" onclick="
+"\"%2$s\">ignore this check</a>"
+
+#. %1$s is a URL
+#: views/pages/js_constants.js.thtml:71
+msgid "app_compat_try_old_version"
+msgstr "<a href=\"%1$s\">Aikaisempi versio</a> lisäosasta saattaa toimia"
+
+#. %1$s is a URL
+#. %2$s is a version number. Example: 3.1
+#: views/pages/js_constants.js.thtml:73
+#, fuzzy
+msgid "app_compat_unreleased_version"
+msgstr ""
+"This add-on requires the not-yet released <a href=\"%1$s\">Firefox %2$s</a>"
+
+#: views/pages/js_constants.js.thtml:70
+msgid "app_compat_update_firefox"
+msgstr ""
+"<a href=\"http://getfirefox.com\">Päivitä Firefoxisi</a> asentaaksesi tämän "
+"lisäosan"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#. %3$s is a status, like Public.
+#: controllers/components/audit.php:79
+#, fuzzy
+msgid "audit_addon_status"
+msgstr "%1$s changed the status of %2$s to %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:221
+#, fuzzy
+msgid "audit_admin_default"
+msgstr "%1$s committed unknown admin action %2$s to ID %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:153
+#, fuzzy
+msgid "audit_admin_feature_remove"
+msgstr "%1$s removed feature %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is an application, like Firefox.
+#: controllers/components/audit.php:92
+#, fuzzy
+msgid "audit_application_create"
+msgstr "%1$s created application %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is an application, like Firefox.
+#: controllers/components/audit.php:95
+#, fuzzy
+msgid "audit_application_edit"
+msgstr "%1$s edited application %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a version number, like 3.5.
+#. %3$s is an application, like Firefox.
+#: controllers/components/audit.php:105
+#, fuzzy
+msgid "audit_appversion_create"
+msgstr "%1$s created version %2$s for %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a version number, like 3.5.
+#. %3$s is an application, like Firefox.
+#: controllers/components/audit.php:108
+#, fuzzy
+msgid "audit_appversion_delete"
+msgstr "%1$s deleted version %2$s for %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a config field, like "awesomeness".
+#. %3$s is a config value, like "off".
+#. %4$s is a config value, like "on".
+#: controllers/components/audit.php:210
+#, fuzzy
+msgid "audit_config"
+msgstr "%1$s changed config '%2$s' from '%3$s' to '%4$s'"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:258
+#, fuzzy
+msgid "audit_editor_default"
+msgstr "%1$s committed unknown editor action %2$s to ID %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#: controllers/components/audit.php:236
+#, fuzzy
+msgid "audit_editor_feature_remove"
+msgstr "%1$s removed addon %2$s from feature list"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#: controllers/components/audit.php:231
+#, fuzzy
+msgid "audit_feature_add"
+msgstr "%1$s added addon %2$s to feature list"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:149
+#, fuzzy
+msgid "audit_feature_edit"
+msgstr "%1$s changed a feature for %2$s locale"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#: controllers/components/audit.php:241
+#, fuzzy
+msgid "audit_feature_locale_change"
+msgstr "%1$s changed locales for addon %2$s on feature list"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:83
+#, fuzzy
+msgid "audit_file_recalchash"
+msgstr "%1$s recalculated the hash for file %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>user name</a>
+#. %3$s is <a>group name</a>
+#: controllers/components/audit.php:182
+#, fuzzy
+msgid "audit_group_addmember"
+msgstr "%1$s added %2$s to group %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:313
+#, fuzzy
+msgid "audit_group_associated"
+msgstr "%1$s associated themselves with %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:162
+#, fuzzy
+msgid "audit_group_create"
+msgstr "%1s created group %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:170
+#, fuzzy
+msgid "audit_group_delete"
+msgstr "%1$s deleted group %2$s (ID %3$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:165
+#, fuzzy
+msgid "audit_group_edit"
+msgstr "%1$s edited group %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>user name</a>
+#. %3$s is <a>group name</a>
+#: controllers/components/audit.php:188
+#, fuzzy
+msgid "audit_group_removemember"
+msgstr "%1$s removed %2$s from group %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:280
+#, fuzzy
+msgid "audit_l10n_default"
+msgstr "%1$s committed unknown action %2$s for %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:295
+#, fuzzy
+msgid "audit_modify_locked_group"
+msgstr "%1$s attempted to modify locked group %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:299
+#, fuzzy
+msgid "audit_modify_other_locale"
+msgstr "%1$s attempted to modify translations in %2$s without permission"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a platform, like <a>Windows</a>
+#: controllers/components/audit.php:135
+#, fuzzy
+msgid "audit_platform_create"
+msgstr "%1$s created platform %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a platform, like <a>Windows</a>
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:143
+#, fuzzy
+msgid "audit_platform_delete"
+msgstr "%1$s deleted platform %2$s (ID %3$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a platform, like <a>Windows</a>
+#: controllers/components/audit.php:138
+#, fuzzy
+msgid "audit_platform_edit"
+msgstr "%1$s edited platform %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a part of the admin, like 'Site Config'
+#: controllers/components/audit.php:288
+#, fuzzy
+msgid "audit_reauthentication_failure"
+msgstr "%1$s failed to re-authenticate to access %2$s."
+
+#. %1$s is <a>user name</a>
+#. %2$s is the name of a canned response, like 'Ready for the public'
+#: controllers/components/audit.php:198
+#, fuzzy
+msgid "audit_response_create"
+msgstr "%1$s created response %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is the name of a canned response, like 'Ready for the public'
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:206
+#, fuzzy
+msgid "audit_response_delete"
+msgstr "%1$s deleted response %2$s (ID %3$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is the name of a canned response, like 'Ready for the public'
+#: controllers/components/audit.php:201
+#, fuzzy
+msgid "audit_response_edit"
+msgstr "%1$s edited response %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:245
+#, fuzzy
+msgid "audit_review_approve"
+msgstr "%1$s approved review %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:250 controllers/components/audit.php:253
+#, fuzzy
+msgid "audit_review_delete"
+msgstr "%1$s deleted review %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:303
+#, fuzzy
+msgid "audit_security_default"
+msgstr "%1$s committed unknown security action %2$s to ID %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a category name, like <a>Search Tools</a>
+#: controllers/components/audit.php:118
+#, fuzzy
+msgid "audit_tag_create"
+msgstr "%1$s created tag %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a category name, like <a>Search Tools</a>
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:126
+#, fuzzy
+msgid "audit_tag_delete"
+msgstr "%1$s deleted category %2$s (ID %3$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a category name, like <a>Search Tools</a>
+#: controllers/components/audit.php:121
+#, fuzzy
+msgid "audit_tag_edit"
+msgstr "%1$s edited category %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:266
+#, fuzzy
+msgid "audit_update_applications"
+msgstr "%1$s updated application translations for %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:277
+#, fuzzy
+msgid "audit_update_blog"
+msgstr "%1$s updated blog post translations for %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:274
+#, fuzzy
+msgid "audit_update_platforms"
+msgstr "%1$s updated platform translations for %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:270
+#, fuzzy
+msgid "audit_update_tags"
+msgstr "%1$s updated category translations for %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>user name</a>
+#: controllers/components/audit.php:217
+#, fuzzy
+msgid "audit_user_edit"
+msgstr "%1$s edited %2$s's user information"
+
+#: controllers/addons_controller.php:1012
+#, fuzzy
+msgid "browse_addons_name"
+msgstr "Add-ons by Name"
+
+#: controllers/addons_controller.php:1010
+#, fuzzy
+msgid "browse_addons_newest"
+msgstr "Newest Add-ons"
+
+#: controllers/addons_controller.php:1008
+#, fuzzy
+msgid "browse_addons_popular"
+msgstr "Popular Add-ons"
+
+#: controllers/addons_controller.php:1011
+#, fuzzy
+msgid "browse_addons_rated"
+msgstr "Add-ons by Rating"
+
+#: controllers/addons_controller.php:1009
+#, fuzzy
+msgid "browse_addons_updated"
+msgstr "Recently Updated Add-ons"
+
+#: views/elements/categories.thtml:73 views/elements/categories.thtml:82
+msgid "categories_current_title"
+msgstr "Valittu luokka"
+
+#: views/elements/categories.thtml:50
+#: views/elements/amo2009/categories.thtml:43
+#: views/elements/amo2009/categories.thtml:45
+msgid "categories_header"
+msgstr "Luokat"
+
+#: views/elements/categories.thtml:50
+#: views/elements/amo2009/categories.thtml:41
+msgid "categories_header_title"
+msgstr "Valitse luokka"
+
+#. %1$s is the category name
+#: views/addons/searchengines.thtml:129
+#, php-format
+msgid "category_extra_see_all"
+msgstr "Näytä kaikki luokassa \"%1$s\""
+
+#. %1$s is a number.
+#: models/collection.php:130
+#, fuzzy
+msgid "collection_description_limit"
+msgstr "The description should be less than %1$s characters."
+
+#. %1$s is the name of the collection
+#: controllers/collections_controller.php:392
+#, fuzzy
+msgid "collection_detail_rss_title"
+msgstr "%s Collection"
+
+#: controllers/collections_controller.php:1065
+#, fuzzy
+msgid "collection_error_deleting_addon"
+msgstr "Error deleting add-on!"
+
+#: controllers/collections_controller.php:1051
+#, fuzzy
+msgid "collection_error_saving_addon"
+msgstr "Error saving add-on!"
+
+#: controllers/collections_controller.php:1080
+#, fuzzy
+msgid "collection_error_saving_comment"
+msgstr "Error saving comment!"
+
+#. %1$s is a number.
+#: models/collection.php:122
+#, fuzzy
+msgid "collection_name_limit"
+msgstr "The name should be less than %1$s characters."
+
+#: controllers/collections_controller.php:352
+#: controllers/collections_controller.php:487
+#, fuzzy
+msgid "collection_not_found"
+msgstr "Collection not found!"
+
+#. %1$s is the text on the "create collection" button
+#: views/collections/add.thtml:91
+#, fuzzy
+msgid "collections_add_formfield_addons_description"
+msgstr ""
+"If you already know which add-ons you want to add to your collection, just "
+"start typing their names below. If you'd rather wait and do this later, just "
+"click %1$s now."
+
+#: views/collections/add.thtml:90
+#, fuzzy
+msgid "collections_add_formfield_firstaddons"
+msgstr "Choose your first add-ons"
+
+#: views/collections/add.thtml:48
+#, fuzzy
+msgid "collections_add_header"
+msgstr "Create a Collection"
+
+#: views/collections/add.thtml:97
+#, fuzzy
+msgid "collections_add_header_selectedaddons"
+msgstr "Selected Add-ons"
+
+#: views/collections/add.thtml:50
+#, fuzzy
+msgid "collections_add_intro"
+msgstr ""
+"It's easy to create your own collection of add-ons by filling in a few "
+"fields below."
+
+#: views/collections/add.thtml:92 views/collections/add.thtml:103
+#, fuzzy
+msgid "collections_add_submit"
+msgstr "Create Collection"
+
+#: views/pages/collector_faq.thtml:50 views/pages/collector_firstrun.thtml:43
+#: views/pages/collector.thtml:47 views/pages/collector_features.thtml:55
+#: controllers/search_controller.php:302
+#: controllers/collections_controller.php:206
+#: controllers/collections_controller.php:405
+#: controllers/collections_controller.php:467
+#: controllers/collections_controller.php:539
+#, fuzzy
+msgid "collections_breadcrumb"
+msgstr "Collections"
+
+#: views/collections/detail.thtml:185
+#, fuzzy
+msgid "collections_detail_a_learn"
+msgstr "Learn More"
+
+#: views/elements/amo2009/collection_add_form.thtml:53
+#: views/elements/amo2009/collections_js_init.thtml:68
+#: views/pages/collector_firstrun.thtml:64
+#, fuzzy
+msgid "collections_detail_button_add"
+msgstr "Add to Favorites"
+
+#: views/elements/amo2009/collection_add_form.thtml:50
+#: views/elements/amo2009/collections_js_init.thtml:71
+#, fuzzy
+msgid "collections_detail_button_remove"
+msgstr "Remove from Favorites"
+
+#. %1$s is a URL.
+#. %2$s is a full <a href>.
+#: views/collections/detail.thtml:62
+#, fuzzy
+msgid "collections_detail_created_desc"
+msgstr ""
+"<p>You can view your new collection below. If you'd like to set a collection "
+"nickname, upload an icon, or change additional settings, please visit the <a "
+"href='%1$s'>Manage Collections</a> page.</p><p>Your collection can be "
+"accessed at this location: %2$s</p>"
+
+#: views/collections/detail.thtml:61
+#, fuzzy
+msgid "collections_detail_created_msg"
+msgstr "Your collection is now ready!"
+
+#: views/collections/detail.thtml:109
+#, fuzzy
+msgid "collections_detail_header_about"
+msgstr "About This Collection"
+
+#. %1$s is a number.
+#: views/collections/detail.thtml:126
+#, fuzzy
+msgid "collections_detail_header_count"
+msgid_plural "collections_detail_header_count"
+msgstr[0] "%1$s Add-on in this Collection"
+msgstr[1] "%1$s Add-ons in this Collection"
+
+#: views/collections/detail.thtml:113
+#, fuzzy
+msgid "collections_detail_info_created"
+msgstr "<strong>Created by:</strong> %1$s"
+
+#: views/collections/detail.thtml:117
+#, fuzzy
+msgid "collections_detail_info_updated"
+msgstr "<strong>Updated:</strong>"
+
+#: views/elements/amo2009/collections_js_init.thtml:62
+#, fuzzy
+msgid "collections_detail_js_adding"
+msgstr "Adding to Favorites&hellip;"
+
+#: views/elements/amo2009/collections_js_init.thtml:65
+#, fuzzy
+msgid "collections_detail_js_removing"
+msgstr "Removing Favorite&hellip;"
+
+#. %1$s is a URL
+#: views/collections/detail.thtml:90
+#, fuzzy
+msgid "collections_detail_login"
+msgstr "<a href=\"%1$s\">Log in</a> to add this collection to your favorites."
+
+#: views/collections/detail.thtml:104
+#, fuzzy
+msgid "collections_detail_manage"
+msgstr "Manage Collection"
+
+#: controllers/collections_controller.php:298
+#, fuzzy
+msgid "collections_detail_sort_date"
+msgstr "Date Added"
+
+#: controllers/collections_controller.php:299
+#, fuzzy
+msgid "collections_detail_sort_name"
+msgstr "Name"
+
+#: controllers/collections_controller.php:300
+#, fuzzy
+msgid "collections_detail_sort_popularity"
+msgstr "Popularity"
+
+#. %1$s is a number.
+#: views/collections/detail.thtml:166
+#, fuzzy
+msgid "collections_detail_weekly_downloads"
+msgid_plural "collections_detail_weekly_downloads"
+msgstr[0] "%1$s download this week"
+msgstr[1] "%1$s downloads this week"
+
+#: views/collections/edit.thtml:255
+#, fuzzy
+msgid "collections_edit_addons_delete_noscript"
+msgstr "Selected add-ons will be removed upon Save"
+
+#: views/collections/edit.thtml:247
+#, fuzzy
+msgid "collections_edit_addons_description"
+msgstr ""
+"To publish new add-ons to this collection, start typing their names below."
+
+#: views/collections/edit.thtml:248
+#, fuzzy
+msgid "collections_edit_addons_description_noscript"
+msgstr ""
+"To publish new add-ons to this collection, enter a comma-separated list of "
+"Add-on IDs below."
+
+#: views/collections/edit.thtml:247 views/collections/edit.thtml:248
+#, fuzzy
+msgid "collections_edit_addons_description_publish_detailspage"
+msgstr "You can also publish an add-on from its normal listing page."
+
+#. %1$s is the date the add-on was added to the collection
+#. %1$s is the name of the user who added the add-on to the collection
+#: views/collections/edit.thtml:260
+#, fuzzy
+msgid "collections_edit_addons_listitem_added"
+msgstr "Added %1$s by %2$s"
+
+#: views/collections/edit.thtml:263
+#, fuzzy
+msgid "collections_edit_addons_listitem_comment_add"
+msgstr "Add publisher comment"
+
+#: views/collections/edit.thtml:266
+#, fuzzy
+msgid "collections_edit_addons_listitem_comment_delete"
+msgstr "Delete publisher comment"
+
+#: views/collections/edit.thtml:265
+#, fuzzy
+msgid "collections_edit_addons_listitem_comment_edit"
+msgstr "Edit publisher comment"
+
+#: views/collections/edit.thtml:271
+#, fuzzy
+msgid "collections_edit_addons_listitem_comment_note"
+msgstr ""
+"Note: Comment will appear as though written by original publisher on the "
+"original publication date"
+
+#: views/collections/edit.thtml:270
+#, fuzzy
+msgid "collections_edit_addons_listitem_comment_submit"
+msgstr "Save Comment"
+
+#: views/collections/edit.thtml:261
+#, fuzzy
+msgid "collections_edit_addons_listitem_remove"
+msgstr "Remove"
+
+#: views/collections/edit.thtml:250
+#, fuzzy
+msgid "collections_edit_addons_submit"
+msgstr "Add to Collection"
+
+#: views/collections/edit.thtml:153
+#, fuzzy
+msgid "collections_edit_check_nickname"
+msgstr "Check Availability"
+
+#: views/collections/edit.thtml:299
+#, fuzzy
+msgid "collections_edit_confirm_deletecollection"
+msgstr "Yes, I would like to delete this collection."
+
+#. %1$s is the label of the edit form's submit button
+#: views/collections/edit.thtml:300
+#, fuzzy
+msgid "collections_edit_confirm_deletecollection_description"
+msgstr "Check the box, then click on \"%1$s\" to delete this collection."
+
+#. %1$s is the "delete" submit button text
+#. %2$s is the title of the "advanced" tab
+#: views/collections/edit.thtml:95
+#, fuzzy
+msgid "collections_edit_delete_upon_submit"
+msgstr ""
+"Upon clicking \"%1$s\" below, your collection will be deleted. If you do not "
+"want to delete your collection, uncheck the confirmation box in the \"%2$s\" "
+"tab and continue editing your collection. If you leave this page without "
+"saving, your collection will also not be deleted."
+
+#: views/collections/edit.thtml:94
+#, fuzzy
+msgid "collections_edit_delete_warning"
+msgstr "Your collection is about to be deleted!"
+
+#: views/collections/add.thtml:76 views/collections/edit.thtml:144
+#, fuzzy
+msgid "collections_edit_form_error_description"
+msgstr "You must provide a description of your collection."
+
+#: views/collections/edit.thtml:181
+#, fuzzy
+msgid "collections_edit_form_error_icon"
+msgstr "There was an error uploading your icon."
+
+#: views/collections/add.thtml:69 views/collections/edit.thtml:130
+#, fuzzy
+msgid "collections_edit_form_error_name"
+msgstr "You must give your collection a name."
+
+#: views/collections/edit.thtml:158
+#, fuzzy
+msgid "collections_edit_form_error_nickname"
+msgstr "If you choose a nickname, it must be unique."
+
+#: views/collections/add.thtml:93 views/collections/edit.thtml:249
+#, fuzzy
+msgid "collections_edit_formfield_addons"
+msgstr "Add-on name:"
+
+#: views/collections/edit.thtml:281
+#, fuzzy
+msgid "collections_edit_formfield_application"
+msgstr "Associated Application"
+
+#: views/collections/edit.thtml:282
+#, fuzzy
+msgid "collections_edit_formfield_application_description"
+msgstr "Select the application that your collection supports."
+
+#: views/collections/edit.thtml:288
+#, fuzzy
+msgid "collections_edit_formfield_collectiontype"
+msgstr "Collection Type"
+
+#: views/collections/edit.thtml:295
+#, fuzzy
+msgid "collections_edit_formfield_deletecollection"
+msgstr "Delete Collection"
+
+#: views/collections/edit.thtml:296
+#, fuzzy
+msgid "collections_edit_formfield_deletecollection_description"
+msgstr "Deleting your collection will permanently erase it."
+
+#: views/collections/add.thtml:73 views/collections/edit.thtml:140
+#, fuzzy
+msgid "collections_edit_formfield_description"
+msgstr "Collection Description"
+
+#: views/collections/add.thtml:74 views/collections/edit.thtml:141
+#, fuzzy
+msgid "collections_edit_formfield_description_description"
+msgstr "Briefly describe your collection and the kind of add-ons in it"
+
+#: views/collections/edit.thtml:162
+#, fuzzy
+msgid "collections_edit_formfield_icon"
+msgstr "Icon"
+
+#: views/collections/edit.thtml:163
+#, fuzzy
+msgid "collections_edit_formfield_icon_description"
+msgstr ""
+"You can upload a JPG, GIF or PNG icon that will be resized to 32x32 pixels."
+
+#: views/collections/add.thtml:80 views/collections/edit.thtml:189
+#, fuzzy
+msgid "collections_edit_formfield_listed"
+msgstr "Who can view your collection?"
+
+#: views/collections/add.thtml:81 views/collections/edit.thtml:190
+#, fuzzy
+msgid "collections_edit_formfield_listed_description"
+msgstr ""
+"By default, collections appear in the public Collection Directory and are "
+"discoverable by anyone. If you want to restrict your collection to be "
+"viewable only by people who are given a special link, choose that option "
+"below."
+
+#: views/collections/add.thtml:84 views/collections/edit.thtml:193
+#, fuzzy
+msgid "collections_edit_formfield_listed_false"
+msgstr "Only people I invite can view my collection"
+
+#: views/collections/add.thtml:83 views/collections/edit.thtml:192
+#, fuzzy
+msgid "collections_edit_formfield_listed_true"
+msgstr "Everyone can view my collection in the directory"
+
+#: views/collections/edit.thtml:223
+#, fuzzy
+msgid "collections_edit_formfield_managers"
+msgstr "Who can manage my collection?"
+
+#: views/collections/edit.thtml:224
+#, fuzzy
+msgid "collections_edit_formfield_managers_description"
+msgstr ""
+"These users can publish add-ons to your collection, manage all add-ons and "
+"settings, and grant other users permission."
+
+#: views/collections/add.thtml:66 views/collections/edit.thtml:126
+#, fuzzy
+msgid "collections_edit_formfield_name"
+msgstr "Collection Name"
+
+#: views/collections/add.thtml:67 views/collections/edit.thtml:127
+#, fuzzy
+msgid "collections_edit_formfield_name_description"
+msgstr ""
+"Give your collection a descriptive name, such as \"Dave's Favorite Travel "
+"Add-ons\""
+
+#: views/collections/edit.thtml:148
+#, fuzzy
+msgid "collections_edit_formfield_nickname"
+msgstr "Collection Nickname"
+
+#: views/collections/edit.thtml:149
+#, fuzzy
+msgid "collections_edit_formfield_nickname_description"
+msgstr "Optionally, give your collection a unique nickname for quick access:"
+
+#: views/collections/edit.thtml:201
+#, fuzzy
+msgid "collections_edit_formfield_publishers"
+msgstr "Who can publish add-ons to your collection?"
+
+#: views/collections/edit.thtml:202
+#, fuzzy
+msgid "collections_edit_formfield_publishers_description"
+msgstr ""
+"These users can publish add-ons to your collection and remove add-ons that "
+"they publish."
+
+#: views/collections/edit.thtml:210 views/collections/edit.thtml:232
+#, fuzzy
+msgid "collections_edit_formfield_users_add"
+msgstr "Enter the e-mail address of a Firefox Add-ons account:"
+
+#: views/collections/edit.thtml:216 views/collections/edit.thtml:238
+#, fuzzy
+msgid "collections_edit_formfield_users_delete_noscript"
+msgstr "Selected accounts will be removed upon Save"
+
+#: views/collections/edit.thtml:215 views/collections/edit.thtml:237
+#, fuzzy
+msgid "collections_edit_formfield_users_new_noscript"
+msgstr ""
+"Enter a comma-separated list of e-mail addresses of Firefox Add-ons accounts"
+
+#: views/collections/edit.thtml:204 views/collections/edit.thtml:226
+#, fuzzy
+msgid "collections_edit_formfield_users_onlyme"
+msgstr "Only me"
+
+#: views/collections/edit.thtml:205 views/collections/edit.thtml:227
+#, fuzzy
+msgid "collections_edit_formfield_users_otherusers"
+msgstr "Myself and these users:"
+
+#: views/collections/edit.thtml:211 views/collections/edit.thtml:233
+#, fuzzy
+msgid "collections_edit_formfield_users_submit"
+msgstr "Add"
+
+#. %1$s is the name of the collection
+#: views/collections/edit.thtml:68
+#, fuzzy
+msgid "collections_edit_header"
+msgstr "Manage %1$s"
+
+#: views/collections/edit.thtml:246
+#, fuzzy
+msgid "collections_edit_header_addons"
+msgstr "Manage Collection Contents"
+
+#: views/collections/edit.thtml:253 views/collections/edit.thtml:258
+#, fuzzy
+msgid "collections_edit_header_addons_current"
+msgstr "Current Add-ons:"
+
+#: views/collections/edit.thtml:279
+#, fuzzy
+msgid "collections_edit_header_advanced"
+msgstr "Advanced Settings"
+
+#: views/collections/edit.thtml:186
+#, fuzzy
+msgid "collections_edit_header_permissions"
+msgstr "Manage Collection Permissions"
+
+#: views/collections/edit.thtml:170
+#, fuzzy
+msgid "collections_edit_icon_cancel"
+msgstr "Cancel"
+
+#: views/collections/edit.thtml:174 views/collections/edit.thtml:179
+#, fuzzy
+msgid "collections_edit_icon_delete"
+msgstr "Delete Icon"
+
+#: views/collections/edit.thtml:178
+#, fuzzy
+msgid "collections_edit_icon_replace"
+msgstr "Replace Icon"
+
+#. %1$s is the label of the edit form's submit button
+#: views/collections/edit.thtml:169
+#, fuzzy
+msgid "collections_edit_icon_toberemoved"
+msgstr "Icon will be removed when \"%1$s\" is clicked below"
+
+#: views/collections/edit.thtml:155
+#, fuzzy
+msgid "collections_edit_nickname_available"
+msgstr "Nickname Available"
+
+#: controllers/collections_controller.php:943
+#, fuzzy
+msgid "collections_edit_nickname_error"
+msgstr ""
+"Your nickname contained invalid characters and was corrected. Please try "
+"again."
+
+#: views/collections/edit.thtml:156
+#, fuzzy
+msgid "collections_edit_nickname_taken"
+msgstr "Nickname Taken"
+
+#. This string is followed by a URL pointing to the collection's view page
+#: views/collections/edit.thtml:75
+#, fuzzy
+msgid "collections_edit_saved_nextstep"
+msgstr "Your collection can be accessed at this location:"
+
+#: views/collections/edit.thtml:74
+#, fuzzy
+msgid "collections_edit_saved_success"
+msgstr "Your collection was successfully saved!"
+
+#: views/collections/edit.thtml:169 views/collections/edit.thtml:300
+#: views/collections/edit.thtml:308 views/pages/js_constants.js.thtml:99
+#, fuzzy
+msgid "collections_edit_submit"
+msgstr "Update Collection"
+
+#: views/collections/edit.thtml:96 views/collections/edit.thtml:297
+#: views/pages/js_constants.js.thtml:100
+#, fuzzy
+msgid "collections_edit_submit_deletecollection"
+msgstr "Delete Collection"
+
+#: views/collections/edit.thtml:111
+#, fuzzy
+msgid "collections_edit_tabheader_addons"
+msgstr "Add-ons"
+
+#: views/collections/edit.thtml:97 views/collections/edit.thtml:113
+#, fuzzy
+msgid "collections_edit_tabheader_advanced"
+msgstr "Advanced"
+
+#: views/collections/edit.thtml:108
+#, fuzzy
+msgid "collections_edit_tabheader_details"
+msgstr "Name &amp; Details"
+
+#: views/collections/edit.thtml:109
+#, fuzzy
+msgid "collections_edit_tabheader_permissions"
+msgstr "Permissions"
+
+#: models/collection_promo.php:53
+#, fuzzy
+msgid "collections_family_tagline"
+msgstr "Add-ons can keep an eye on your kids and your calendar."
+
+#: models/collection_promo.php:53
+#, fuzzy
+msgid "collections_family_title"
+msgstr "Family Organizer"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:70
+#, fuzzy
+msgid "collections_index_a_check_out"
+msgstr "Check out Add-on Collector"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:52
+#, fuzzy
+msgid "collections_index_a_create"
+msgstr "Create a Collection"
+
+#: views/collections/detail.thtml:139 views/collections/listing.thtml:85
+#: views/search/collections.thtml:84
+#, fuzzy
+msgid "collections_index_button_go"
+msgstr "Go"
+
+#. %1$s is a URL.
+#: controllers/collections_controller.php:182
+#, fuzzy
+msgid "collections_index_filler_favorites"
+msgstr ""
+"<p><strong>You don't have any favorite collections yet.</strong></p> "
+"<p>Collections you mark as favorites can be quickly accessed from this page, "
+"and will appear in the <a href='%1$s'>Add-on Collector</a> if you've "
+"installed it.</p>"
+
+#. %1$s is a URL.
+#: controllers/collections_controller.php:167
+#, fuzzy
+msgid "collections_index_filler_mine"
+msgstr ""
+"<p>You haven't created any collections yet. Collections are easy to create "
+"and fill with your favorite add-ons. <a href='%1$s'>Try it out</a>!</p>"
+
+#: views/collections/listing.thtml:51
+#, fuzzy
+msgid "collections_index_header_collections"
+msgstr "Collections"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:60
+#, fuzzy
+msgid "collections_index_header_collector"
+msgstr "Add-on Collector"
+
+#. %1$s is a comma-separated list of author names
+#: views/elements/amo2009/collection_listing_item.thtml:84
+#: views/collections/detail.thtml:151
+#, fuzzy
+msgid "collections_index_header_created"
+msgstr "created by %1$s"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:47
+#, fuzzy
+msgid "collections_index_header_what"
+msgstr "What are Collections?"
+
+#: views/collections/detail.thtml:132 views/collections/listing.thtml:78
+#: views/search/collections.thtml:66
+#, fuzzy
+msgid "collections_index_label_sortby"
+msgstr "Sort by"
+
+#: controllers/collections_controller.php:130
+#, fuzzy
+msgid "collections_index_li_editors"
+msgstr "Editor's Picks"
+
+#: views/collections/subscribe.thtml:64
+#: controllers/collections_controller.php:140
+#, fuzzy
+msgid "collections_index_li_favorites"
+msgstr "My Favorites"
+
+#: controllers/collections_controller.php:138
+#, fuzzy
+msgid "collections_index_li_mine"
+msgstr "My Collections"
+
+#: controllers/collections_controller.php:132
+#, fuzzy
+msgid "collections_index_li_popular"
+msgstr "Popular"
+
+#: views/search/collections.thtml:74 controllers/collections_controller.php:81
+#, fuzzy
+msgid "collections_index_option_all"
+msgstr "Most popular all time"
+
+#: views/search/collections.thtml:72 controllers/collections_controller.php:78
+#, fuzzy
+msgid "collections_index_option_month"
+msgstr "Most popular this month"
+
+#: views/search/collections.thtml:76 controllers/collections_controller.php:84
+#, fuzzy
+msgid "collections_index_option_newest"
+msgstr "Newest"
+
+#: views/search/collections.thtml:70 controllers/collections_controller.php:75
+#, fuzzy
+msgid "collections_index_option_week"
+msgstr "Most popular this week"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:67
+#, fuzzy
+msgid "collections_index_p_collector"
+msgstr ""
+"There's a new way to manage and find favorite add-ons. Comment, share and "
+"sync collections, all from your browser"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:48
+#, fuzzy
+msgid "collections_index_p_what_are"
+msgstr "Collections are groups of related add-ons assembled for easy sharing."
+
+#. %s is a date in the _('date') format
+#: views/elements/collections_interactive_addon.thtml:85
+#, fuzzy, php-format
+msgid "collections_interactive_addon_added"
+msgstr "Added %s"
+
+#: models/collection_promo.php:55
+#, fuzzy
+msgid "collections_reference_tagline"
+msgstr "Add-ons can do better research online."
+
+#: models/collection_promo.php:55
+#, fuzzy
+msgid "collections_reference_title"
+msgstr "Reference Desk"
+
+#: models/collection_promo.php:52
+#, fuzzy
+msgid "collections_social_tagline"
+msgstr "Add-ons can manage your social network."
+
+#: models/collection_promo.php:52
+#, fuzzy
+msgid "collections_social_title"
+msgstr "Social Circuit"
+
+#: views/collections/subscribe.thtml:91
+#, fuzzy
+msgid "collections_subscribe_button_close"
+msgstr "Close"
+
+#: views/collections/subscribe.thtml:70
+#, fuzzy
+msgid "collections_subscribe_error"
+msgstr ""
+"An error occurred trying to add a favorite collection. Is this collection "
+"already a favorite?"
+
+#: views/collections/subscribe.thtml:96
+#, fuzzy
+msgid "collections_subscribe_label_bothersome"
+msgstr "Don't show me this message again."
+
+#. %1$s is the collection name
+#: views/collections/subscribe.thtml:60
+#, fuzzy
+msgid "collections_subscribe_success"
+msgstr "%1$s has been added to your favorite collections."
+
+#. %1$s is the link to the "My Favorites" tab on the main collections page
+#. %2$s is the localized title of the "My Favorites" tab
+#. %3$s is the link URL to the collector add-on
+#: views/collections/subscribe.thtml:62
+#, fuzzy
+msgid "collections_subscribe_success_desc"
+msgstr ""
+"You can now quickly find this collection from the <a href=\"%1$s\">%2$s</a> "
+"tab in the directory. For an even easier way to keep track of your favorite "
+"collections, try out our <a href=\"%3$s\">Add-on Collector</a> extension for "
+"Firefox."
+
+#: views/collections/listing.thtml:55
+#, fuzzy
+msgid "collections_success_delete"
+msgstr "The collection has been deleted."
+
+#: models/collection_promo.php:54
+#, fuzzy
+msgid "collections_travel_tagline"
+msgstr "Add-ons can turn you into a travel agent."
+
+#: models/collection_promo.php:54
+#, fuzzy
+msgid "collections_travel_title"
+msgstr "The Traveler's Pack"
+
+#. A collection of add-ons that is automatically built for a user. They are "automatically published" to this collection.
+#: controllers/collections_controller.php:581
+#, fuzzy
+msgid "collections_type_autopublisher"
+msgstr "Auto-publisher"
+
+#. A collection that has been chosen by an Editor as notable or exceptional
+#: controllers/collections_controller.php:582
+#, fuzzy
+msgid "collections_type_editorspick"
+msgstr "Editor's Pick"
+
+#: controllers/collections_controller.php:580
+#, fuzzy
+msgid "collections_type_normal"
+msgstr "Normal"
+
+#: views/collections/subscribe.thtml:84
+#, fuzzy
+msgid "collections_unsubscribe_error"
+msgstr ""
+"An error occurred trying to remove a favorite collection. Was this "
+"collection not a favorite?"
+
+#. %1$s is the collection name
+#: views/collections/subscribe.thtml:78
+#, fuzzy
+msgid "collections_unsubscribe_success"
+msgstr "%1$s has been removed from your favorite collections."
+
+#: models/collection_promo.php:56
+#, fuzzy
+msgid "collections_webdev_tagline"
+msgstr "Add-ons make it easier to build the perfect website."
+
+#: models/collection_promo.php:56
+#, fuzzy
+msgid "collections_webdev_title"
+msgstr "Web Developer's Toolbox"
+
+#: views/elements/amo2009/collections_sidebar_whatare.thtml:40
+#, fuzzy
+msgid "collections_whatare_header"
+msgstr "What are Collections?"
+
+#: views/elements/amo2009/collections_sidebar_whatare.thtml:45
+#, fuzzy
+msgid "collections_whatare_learnmore"
+msgstr "Read the FAQ"
+
+#: views/elements/amo2009/collections_sidebar_whatare.thtml:44
+#, fuzzy
+msgid "collections_whatare_text"
+msgstr ""
+"There’s a new way to manage and find favorite add-ons. Comment, share and "
+"sync collections, all from your browser."
+
+#: views/pages/collector_faq.thtml:61 views/pages/collector_features.thtml:67
+#, fuzzy
+msgid "collector_features_a_home"
+msgstr "Add-on Collector Home"
+
+#: views/elements/amo2009/collector_sidebar_download.thtml:46
+#, fuzzy
+msgid "collector_features_heading_download"
+msgstr "Download the Add-on Collector:"
+
+#: views/elements/amo2009/collector_sidebar_download.thtml:43
+#: views/pages/collector_firstrun.thtml:116 views/pages/collector.thtml:69
+#, fuzzy
+msgid "collector_features_img_logo"
+msgstr "Add-on Collector Logo"
+
+#: views/compatibility/dashboard.thtml:49
+#: controllers/compatibility_controller.php:72
+#, fuzzy
+msgid "compatibility_dashboard_center_header"
+msgstr "Add-on Compatibility Center"
+
+#. %1$s is the name of an application and a version. Example: Firefox 3.0
+#. %2$s is the name of an application. Example: Firefox
+#: views/compatibility/dashboard.thtml:50
+#, fuzzy
+msgid "compatibility_dashboard_intro"
+msgstr ""
+"Be prepared for the release of %1$s with the tools and information available "
+"for the %2$s Add-ons community found below."
+
+#: views/compatibility/dashboard.thtml:103
+#, fuzzy
+msgid "compatibility_dashboard_loading"
+msgstr "Loading data..."
+
+#: views/compatibility/dashboard.thtml:45
+#, fuzzy
+msgid "compatibility_dashboard_main_link"
+msgstr "Back to Main"
+
+#: views/compatibility/dashboard.thtml:100 views/compatibility/report.thtml:43
+#, fuzzy
+msgid "compatibility_dashboard_report"
+msgstr "Add-on Compatibility Report"
+
+#: views/compatibility/dashboard.thtml:53
+#: views/compatibility/dashboard.thtml:110
+#: views/compatibility/developers.thtml:43
+#, fuzzy
+msgid "compatibility_developer_info"
+msgstr "Information for Add-on Developers"
+
+#: views/compatibility/developers.thtml:66
+#, fuzzy
+msgid "compatibility_developers_adjust_maxversion"
+msgstr "Adjust maxVersion without uploading"
+
+#: views/compatibility/dashboard.thtml:124
+#, fuzzy
+msgid "compatibility_developers_check_status"
+msgstr "Check Status of My Add-ons"
+
+#. %1$s is a URL
+#. %2$s is an application and version. Example: Firefox 3.0
+#: views/compatibility/dashboard.thtml:126
+#, fuzzy
+msgid "compatibility_developers_login_first"
+msgstr ""
+"If you have add-ons hosted on Mozilla Add-ons, <a href=\"%1$s\">please "
+"login</a> to analyze the status of your add-ons for %2$s."
+
+#: views/compatibility/dashboard.thtml:114
+#, fuzzy
+msgid "compatibility_developers_mdclogo_alt"
+msgstr "Mozilla Developer Center Logo"
+
+#: views/compatibility/developers.thtml:73
+#, fuzzy
+msgid "compatibility_developers_no_addons"
+msgstr "You do not have any add-ons hosted on Mozilla Add-ons."
+
+#: views/compatibility/dashboard.thtml:133
+#: views/compatibility/developers.thtml:55
+#, fuzzy
+msgid "compatibility_developers_results"
+msgstr "Add-on Status Check Results"
+
+#: views/compatibility/dashboard.thtml:137
+#, fuzzy
+msgid "compatibility_developers_retrieving"
+msgstr "Retrieving status of hosted add-ons..."
+
+#. %1$s is a number
+#. %2$s is an application name
+#. %3$s is a number.
+#. Full example: 50 Firefox users (10% of total)
+#: views/compatibility/developers.thtml:65
+#, fuzzy
+msgid "compatibility_developers_user_count"
+msgstr "%1$s %2$s users (%3$s&#37; of total)"
+
+#: views/compatibility/report.thtml:45
+#, fuzzy
+msgid "compatibility_report_detail_intro"
+msgstr ""
+"The add-ons below make up 95% of add-on usage known to Mozilla and are "
+"ordered by their usage size."
+
+#: views/compatibility/dashboard.thtml:94
+#, fuzzy
+msgid "compatibility_report_detailed_link"
+msgstr "View Detailed Report"
+
+#. %1$s and %2$s are numbers
+#. %3$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:65
+#, fuzzy
+msgid "compatibility_report_intro"
+msgstr ""
+"Of the %1$s add-ons that make up 95&#37; of add-on usage known to Mozilla, "
+"<b>%2$s&#37;</b> are currently considered compatible with the latest builds "
+"of %3$s."
+
+#: views/compatibility/dashboard.thtml:81
+#, fuzzy
+msgid "compatibility_report_legend_alpha"
+msgstr "Alpha Versions"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:81
+#, fuzzy
+msgid "compatibility_report_legend_alpha_description"
+msgstr "Add-ons compatible with an alpha version of %1$s"
+
+#: views/compatibility/dashboard.thtml:85
+#, fuzzy
+msgid "compatibility_report_legend_beta"
+msgstr "Beta Versions"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:85
+#, fuzzy
+msgid "compatibility_report_legend_beta_description"
+msgstr "Add-ons compatible with a beta version or release candidate of %1$s"
+
+#: views/compatibility/dashboard.thtml:89
+#, fuzzy
+msgid "compatibility_report_legend_latest"
+msgstr "Latest Version"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:89
+#, fuzzy
+msgid "compatibility_report_legend_latest_description"
+msgstr "Add-ons up-to-date with the latest builds of %1$s"
+
+#: views/compatibility/dashboard.thtml:77
+#, fuzzy
+msgid "compatibility_report_legend_other"
+msgstr "Other Versions"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:77
+#, fuzzy
+msgid "compatibility_report_legend_other_description"
+msgstr "Add-ons not compatible with any version of %1$s"
+
+#: views/compatibility/dashboard.thtml:62
+#, fuzzy
+msgid "compatibility_report_title"
+msgstr "Add-on Compatibility Report"
+
+#: views/compatibility/dashboard.thtml:54
+#: views/compatibility/dashboard.thtml:144 views/compatibility/users.thtml:42
+#, fuzzy
+msgid "compatibility_user_info"
+msgstr "Information for Add-on Users"
+
+#: views/compatibility/dashboard.thtml:52
+#, fuzzy
+msgid "compatibility_view_report"
+msgstr "View Compatibility Report"
+
+#. %s is a URL
+#: views/pages/credits.thtml:142
+#, php-format
+msgid "credits_contributing"
+msgstr "Lue lisätietoja avustamisesta %s."
+
+#: views/pages/credits.thtml:142
+msgid "credits_contributing_wikipage"
+msgstr "wiki-sivultamme"
+
+#: views/pages/credits.thtml:99
+msgid "credits_intro"
+msgstr ""
+"Mozilla haluaa kiittää seuraavia ihmisiä monta vuotta kestäneestä "
+"uutteruudesta addons.mozilla.orgin parissa:"
+
+#: views/pages/credits.thtml:103
+msgid "credits_section_developers"
+msgstr "Kehittäjät"
+
+#: views/pages/credits.thtml:115
+msgid "credits_section_editors"
+msgstr "Toimittajat"
+
+#: views/pages/credits.thtml:109
+msgid "credits_section_localizers"
+msgstr "Lokalisoijat"
+
+#: views/pages/credits.thtml:121
+msgid "credits_section_other_contributors"
+msgstr "Muut avustajat"
+
+#: views/pages/credits.thtml:127
+msgid "credits_section_past_developers"
+msgstr "Aikaisemmat kehittäjät"
+
+#: views/pages/credits.thtml:133
+#, fuzzy
+msgid "credits_section_software"
+msgstr "Software and Images"
+
+#: views/pages/credits.thtml:136
+#, fuzzy
+msgid "credits_software_famfamfam"
+msgstr ""
+"Some icons used are from the <a href=\"http://www.famfamfam.com/lab/icons/"
+"silk/\">famfamfam Silk Icon Set</a>, licensed under a <a href=\"http://"
+"creativecommons.org/licenses/by/2.5/\">Creative Commons Attribution 2.5 "
+"License</a>."
+
+#: views/pages/credits.thtml:137
+#, fuzzy
+msgid "credits_software_timeplot"
+msgstr ""
+"Some pages use elements of <a href=\"http://www.simile-widgets.org/timeplot/"
+"\">Timeplot</a>, licensed under a <a href=\"http://simile.mit.edu/license."
+"html\">BSD License</a>."
+
+#. date format string as used in PHP's strftime():
+#. http://php.net/strftime
+#: views/elements/collections_interactive_addon.thtml:85
+#: views/elements/amo2009/addon_version_detail.thtml:53
+#: views/elements/amo2009/homepage_addon.thtml:115
+#: views/elements/addon_version_detail.thtml:54
+#: views/elements/addon_listitem.thtml:124 views/elements/feature.thtml:106
+#: views/collections/detail.thtml:118 views/collections/edit.thtml:325
+#: views/users/info.thtml:76 views/editors/reviews_queue.thtml:57
+#: views/editors/reviews_queue.thtml:68 views/developers/dashboard.thtml:65
+#: views/developers/versions_edit.thtml:208 views/developers/versions.thtml:67
+#: views/search/rss/index.thtml:5 views/addons/rss/versions.thtml:42
+#: views/addons/display.thtml:104 views/addons/display.thtml:356
+#: views/addons/browse_thumbs.thtml:75 views/reviews/add.thtml:63
+#: views/reviews/display.thtml:74 views/reviews/display.thtml:160
+#: views/reviews/delete.thtml:54 controllers/statistics_controller.php:244
+#: controllers/collections_controller.php:1047
+msgid "date"
+msgstr "%e.%m.%Y"
+
+#. date and time format string (strftime)
+#. http://php.net/strftime
+#: views/elements/addon_version_detail.thtml:53
+#: views/developers/discuss.thtml:52 views/developers/discuss.thtml:62
+#: views/admin/addons_status.thtml:57
+msgid "datetime"
+msgstr "%e.%m.%Y, %H.%M"
+
+#: views/elements/developers/actionbar.thtml:47
+msgid "devcp_actionbar_link_details"
+msgstr "Lisätietoja"
+
+#: views/elements/developers/actionbar.thtml:42
+#: views/elements/developers/actionbar.thtml:50
+#: views/developers/dashboard.thtml:64
+msgid "devcp_actionbar_link_edit"
+msgstr "Muokkaa lisäosaa"
+
+#: views/elements/developers/actionbar.thtml:51
+msgid "devcp_actionbar_link_newversion"
+msgstr "Siirrä uusi versio"
+
+#: views/elements/developers/actionbar.thtml:44
+#: views/elements/developers/actionbar.thtml:49
+#: views/developers/dashboard.thtml:73
+msgid "devcp_actionbar_link_stats"
+msgstr "Tilastosivu"
+
+#. %1$s is a filename, e.g. "foo.txt"
+#. %2$s is the extension, e.g. ".txt"
+#. %3$s is a list of valid extensions, like ".png, .jpg, .gif"
+#: controllers/developers_controller.php:1361
+#, fuzzy
+msgid "devcp_add_previews_extension_error"
+msgstr "File %1$s has an invalid extension (%2$s). Allowed extensions: %3$s"
+
+#. %s is the filename.
+#: controllers/developers_controller.php:1394
+#, fuzzy
+msgid "devcp_add_previews_save_error"
+msgstr "File %s could not be saved to the database. Please try again."
+
+#. %1$s is the preview ID number, %2$s is the filename.
+#: controllers/developers_controller.php:1389
+#, fuzzy
+msgid "devcp_add_previews_success_replace"
+msgstr "Preview %1$s was replaced with file %2$s successfully."
+
+#. %s is the filename.
+#: controllers/developers_controller.php:1391
+#, fuzzy
+msgid "devcp_add_previews_success_upload"
+msgstr "File %s was uploaded successfully. You can add a caption below."
+
+#: controllers/components/developers.php:1163
+msgid "devcp_additem_addontype_autodetect"
+msgstr "(tunnista automaattisesti)"
+
+#: views/elements/developers/additem.thtml:76
+msgid "devcp_additem_linktitle_opensin_newwindow"
+msgstr "Avautuu uuteen ikkunaan"
+
+#: views/elements/developers/additem.thtml:41
+msgid "devcp_additem_sidebar_title"
+msgstr "Lähetä lisäosa"
+
+#: views/elements/developers/additem.thtml:53
+msgid "devcp_additem_step0_newlink"
+msgstr "Kehittäjäsopimus"
+
+#: views/elements/developers/additem.thtml:46
+msgid "devcp_additem_step1_link"
+msgstr "1. kohta: siirto"
+
+#: views/elements/developers/additem.thtml:47
+msgid "devcp_additem_step2_link"
+msgstr "2. kohta: lisäosan tiedot"
+
+#: views/elements/developers/additem.thtml:48
+msgid "devcp_additem_step3_link"
+msgstr "3. kohta: versiotiedot"
+
+#: views/elements/developers/additem.thtml:49
+msgid "devcp_additem_step4_link"
+msgstr "4. kohta: lokalisoinnit"
+
+#: views/elements/developers/additem.thtml:50
+msgid "devcp_additem_step5_link"
+msgstr "5. kohta: onnellinen loppu"
+
+#: views/elements/developers/additem.thtml:76
+msgid "devcp_additem_submissionhelp_link"
+msgstr "Apua lisäosan lisäämiseen"
+
+#: controllers/previews_controller.php:168
+#: controllers/previews_controller.php:277
+msgid "devcp_addon_field_preview_caption_displaytitle"
+msgstr "Esikatselun kuvateksti"
+
+#: views/developers/addon_status.thtml:177
+#, fuzzy
+msgid "devcp_addon_status_action_activate"
+msgstr "Make Active"
+
+#: views/developers/addon_status.thtml:178
+#, fuzzy
+msgid "devcp_addon_status_action_activate_description"
+msgstr ""
+"Make your add-on active for it to show up in public listings and enable the "
+"update check service."
+
+#: views/developers/addon_status.thtml:135
+#, fuzzy
+msgid "devcp_addon_status_action_complete"
+msgstr "Complete Add-on"
+
+#: views/developers/addon_status.thtml:136
+#, fuzzy
+msgid "devcp_addon_status_action_complete_description"
+msgstr "Complete your add-on and move to the Sandbox"
+
+#: views/developers/addon_status.thtml:181
+#, fuzzy
+msgid "devcp_addon_status_action_deactivate"
+msgstr "Make Inactive"
+
+#: views/developers/addon_status.thtml:182
+#, fuzzy
+msgid "devcp_addon_status_action_deactivate_description"
+msgstr ""
+"Make your add-on inactive to hide it from all public listings and disable "
+"the update check service."
+
+#: views/developers/addon_status.thtml:143
+#, fuzzy
+msgid "devcp_addon_status_action_move"
+msgstr "Move to Sandbox"
+
+#: views/developers/addon_status.thtml:144
+#, fuzzy
+msgid "devcp_addon_status_action_move_description"
+msgstr "Move your add-on back to the Sandbox. This is reversible."
+
+#: views/developers/addon_status.thtml:139
+#, fuzzy
+msgid "devcp_addon_status_action_nominate"
+msgstr "Nominate for Public"
+
+#: views/developers/addon_status.thtml:140
+#, fuzzy
+msgid "devcp_addon_status_action_nominate_description"
+msgstr "Nominate your add-on to become Public"
+
+#: views/developers/addon_status.thtml:147
+#, fuzzy
+msgid "devcp_addon_status_action_public"
+msgstr "Make Public"
+
+#: views/developers/addon_status.thtml:148
+#, fuzzy
+msgid "devcp_addon_status_action_public_description"
+msgstr "Make your add-on Public again."
+
+#: views/developers/addon_status.thtml:169
+#, fuzzy
+msgid "devcp_addon_status_active"
+msgstr ""
+"Your add-on is <span class=\"inactive-0\">Active</span>. This means your add-"
+"on is showing up in all available listings appropriate for its status above."
+
+#: views/developers/addon_status.thtml:111
+#, fuzzy
+msgid "devcp_addon_status_completion_disabled"
+msgstr ""
+"Please fulfill the criteria above before you can complete your add-on and "
+"move it to the <span class=\"status-1\">Sandbox</span>."
+
+#: views/developers/addon_status.thtml:108
+#, fuzzy
+msgid "devcp_addon_status_completion_enabled"
+msgstr ""
+"You may now complete your add-on and move it to the <span class=\"status-1"
+"\">Sandbox</span> by clicking the button below."
+
+#: views/developers/addon_status.thtml:102
+#, fuzzy
+msgid "devcp_addon_status_criteria_category"
+msgstr "At least one category selected"
+
+#: views/developers/addon_status.thtml:101
+#, fuzzy
+msgid "devcp_addon_status_criteria_description"
+msgstr "Add-on Description required"
+
+#: views/developers/addon_status.thtml:99
+#, fuzzy
+msgid "devcp_addon_status_criteria_name"
+msgstr "Add-on Name required"
+
+#: views/developers/addon_status.thtml:120
+#, fuzzy
+msgid "devcp_addon_status_criteria_prerelease"
+msgstr "Add-on is not marked as pre-release."
+
+#: views/developers/addon_status.thtml:119
+#, fuzzy
+msgid "devcp_addon_status_criteria_preview"
+msgstr "At least one preview image required for extensions and themes."
+
+#: views/developers/addon_status.thtml:100
+#, fuzzy
+msgid "devcp_addon_status_criteria_summary"
+msgstr "Add-on Summary required"
+
+#. %s is the status in a span, e.g. "<span>_('Public')</span>".
+#: views/developers/addon_status.thtml:58
+#, fuzzy
+msgid "devcp_addon_status_header"
+msgstr "Add-on Status: %s"
+
+#: views/developers/addon_status.thtml:152
+#: views/developers/addon_status.thtml:173
+#, fuzzy
+msgid "devcp_addon_status_header_actions"
+msgstr "Available Actions"
+
+#: views/developers/addon_status.thtml:168
+#, fuzzy
+msgid "devcp_addon_status_header_active"
+msgstr "Active Status: <span class=\"inactive-0\">Active</span>"
+
+#: views/developers/addon_status.thtml:97
+#, fuzzy
+msgid "devcp_addon_status_header_criteria"
+msgstr "Add-on Completion Criteria"
+
+#: views/developers/addon_status.thtml:164
+#, fuzzy
+msgid "devcp_addon_status_header_inactive"
+msgstr "Active Status: <span class=\"inactive-1\">Inactive</span>"
+
+#: views/developers/addon_status.thtml:117
+#, fuzzy
+msgid "devcp_addon_status_header_nomination"
+msgstr "Public Nomination Criteria"
+
+#: views/developers/addon_status.thtml:190
+#, fuzzy
+msgid "devcp_addon_status_header_trusted"
+msgstr "Trusted Status: <span class=\"status-4\">Trusted</span>"
+
+#: views/developers/addon_status.thtml:165
+#, fuzzy
+msgid "devcp_addon_status_inactive"
+msgstr ""
+"Your add-on is <span class=\"inactive-1\">Inactive</span>. This means your "
+"add-on will not show up in any listing, regardless of its status above. "
+"Updates are <b>not</b> being provided to your add-on through the update "
+"check service."
+
+#: views/developers/addon_status.thtml:128
+#, fuzzy
+msgid "devcp_addon_status_nominate_disabled"
+msgstr ""
+"Please fulfill the criteria above before nominating your add-on to become "
+"<span class=\"status-4\">Public</span>."
+
+#: views/developers/addon_status.thtml:125
+#, fuzzy
+msgid "devcp_addon_status_nominate_enabled"
+msgstr ""
+"You may now nominate your add-on for <span class=\"status-4\">Public</span> "
+"by clicking the button below."
+
+#: views/developers/addon_status.thtml:64
+#, fuzzy
+msgid "devcp_addon_status_public"
+msgstr "Public"
+
+#: views/developers/addon_status.thtml:63
+#, fuzzy
+msgid "devcp_addon_status_sandbox"
+msgstr "Sandbox"
+
+#. %s is an email address.
+#: views/developers/addon_status.thtml:89
+#, fuzzy
+msgid "devcp_addon_status_switch_disabled"
+msgstr ""
+"Your add-on was <span class=\"status-5\">Disabled</span> by an administrator "
+"and cannot be used. If you have any questions, please e-mail %s."
+
+#: views/developers/addon_status.thtml:67
+#, fuzzy
+msgid "devcp_addon_status_switch_incomplete"
+msgstr ""
+"Your add-on is currently <span class=\"status-0\">Incomplete</span>. This "
+"means your add-on is not showing up on any portion of the site or update "
+"check service. You may come to this page to complete your add-on after it "
+"meets the criteria below for completion and transfer to the <span class="
+"\"status-1\">Sandbox</span>."
+
+#. %s is a number, perhaps 42.
+#: views/developers/addon_status.thtml:77
+#, fuzzy
+msgid "devcp_addon_status_switch_nominated"
+msgstr ""
+"Your add-on is currently nominated to become <span class=\"status-4"
+"\">Public</span> and is awaiting editor review. There are currently %s other "
+"add-ons in the nomination queue."
+
+#. %s is an email address.
+#: views/developers/addon_status.thtml:81
+#, fuzzy
+msgid "devcp_addon_status_switch_pending"
+msgstr ""
+"Your add-on is pending. This shouldn't have happened. Please e-mail %s with "
+"your add-on ID and state this error."
+
+#: views/developers/addon_status.thtml:85
+#, fuzzy
+msgid "devcp_addon_status_switch_public"
+msgstr ""
+"Your add-on is <span class=\"status-4\">Public</span>, which means it will "
+"show up in all listings and searches and can be downloaded without "
+"restriction. Updates are being provided to your add-on through the update "
+"check service."
+
+#: views/developers/addon_status.thtml:71
+#: views/developers/addon_status.thtml:75
+#, fuzzy
+msgid "devcp_addon_status_switch_sandbox"
+msgstr ""
+"Your add-on is in the <span class=\"status-1\">Sandbox</span>, which means "
+"it will show up in listings and searches, but users must log in to download "
+"it. Updates are <b>not</b> being provided to your add-on through the update "
+"check service."
+
+#. %s is the add-on name.
+#: views/developers/addon_status_nominate.thtml:43
+#: views/developers/addon_status_confirm.thtml:43
+#: views/developers/addon_status.thtml:43
+#, fuzzy
+msgid "devcp_addon_status_title"
+msgstr "%s Status"
+
+#: views/developers/addon_status.thtml:191
+#, fuzzy
+msgid "devcp_addon_status_trusted"
+msgstr ""
+"Your add-on is <span class=\"status-4\">Trusted</span>. This means you can "
+"submit updates to your add-on without editor review."
+
+#: views/developers/dashboard.thtml:68
+#, fuzzy
+msgid "devcp_dashboard_active"
+msgstr "Active"
+
+#. %1$s is the add-on type string
+#. %2$s is Inactive or Active in a <span>
+#. %3$s is the addon's public status (Public, In Sandbox, ...) in a <span>
+#: views/developers/dashboard.thtml:69
+#, fuzzy
+msgid "devcp_dashboard_addontype_status"
+msgstr "%1$s currenty %2$s and %3$s"
+
+#: views/developers/dashboard.thtml:67
+#, fuzzy
+msgid "devcp_dashboard_change_status"
+msgstr "Change Status"
+
+#. %s is the addons email address.
+#: views/developers/dashboard.thtml:99
+#, fuzzy
+msgid "devcp_dashboard_disabled_questions"
+msgstr ""
+"Your add-on was disabled by an administrator and cannot be used. If you "
+"have any questions, please email %s."
+
+#. %s is the (localized) add-on status string in a span, e.g. "Disabled"
+#: views/developers/dashboard.thtml:98
+#, fuzzy
+msgid "devcp_dashboard_disabled_status"
+msgstr "Add-on Status: %s"
+
+#: views/developers/dashboard.thtml:43
+#, fuzzy
+msgid "devcp_dashboard_header_main"
+msgstr "Developer Dashboard"
+
+#: views/developers/dashboard.thtml:110
+#, fuzzy
+msgid "devcp_dashboard_header_welcome"
+msgstr "Welcome to the Developer Dashboard"
+
+#: views/developers/dashboard.thtml:68
+#, fuzzy
+msgid "devcp_dashboard_inactive"
+msgstr "Inactive"
+
+#. %s is a date in the _('date') format
+#: views/developers/dashboard.thtml:65
+#, fuzzy
+msgid "devcp_dashboard_last_edited"
+msgstr "Last edited on %s"
+
+#: views/developers/dashboard.thtml:111
+#, fuzzy
+msgid "devcp_dashboard_learn"
+msgstr ""
+"You don't currently have any add-ons hosted on Mozilla Add-ons. To learn how "
+"the process works and submit your first add-on, click Get Started below."
+
+#: views/developers/dashboard.thtml:112
+#, fuzzy
+msgid "devcp_dashboard_start"
+msgstr "Get Started"
+
+#: views/developers/dashboard.thtml:82
+#, fuzzy
+msgid "devcp_dashboard_versions"
+msgstr "Versions and Files"
+
+#: views/developers/dashboard.thtml:91
+#, fuzzy
+msgid "devcp_dashboard_versions_new"
+msgstr "Upload a new version"
+
+#. %s is the preview ID number.
+#: controllers/developers_controller.php:1415
+#, fuzzy
+msgid "devcp_delete_previews_error"
+msgstr "Preview %s could not be deleted from the database. Please try again."
+
+#. %s is the preview ID number.
+#: controllers/developers_controller.php:1413
+#, fuzzy
+msgid "devcp_delete_previews_success"
+msgstr "Preview %s has been deleted successfully."
+
+#: controllers/developers_controller.php:1089
+#, fuzzy
+msgid "devcp_delete_version_priv_error"
+msgstr "You do not have privileges to delete versions or files."
+
+#. %1$s is the count of files, a number
+#. %2$s is a status string like _('Public') or _('Incomplete')
+#: controllers/components/amo.php:549
+#, fuzzy
+msgid "devcp_describe_version_status"
+msgid_plural "devcp_describe_version_status"
+msgstr[0] "%1$s %2$s file"
+msgstr[1] "%1$s %2$s files"
+
+#. %s is a version number. Example: 3.0
+#: views/developers/versions.thtml:65
+#, php-format
+msgid "devcp_details_version"
+msgstr "Versio %s"
+
+#: views/developers/discuss.thtml:68
+#, fuzzy
+msgid "devcp_discuss_addreply_header"
+msgstr "Add Reply"
+
+#: views/developers/discuss.thtml:57
+#, fuzzy
+msgid "devcp_discuss_allreplies_header"
+msgstr "Replies"
+
+#. notice when an error occurs saving a discussion reply
+#. %1 is the email address (linked) for the amo-editors list
+#: views/developers/discuss.thtml:70
+#, fuzzy
+msgid "devcp_discuss_error_notice"
+msgstr ""
+"There was an error saving your reply. Please contact %1$s about the issue."
+
+#. %1 is the add-on name, %2 is the add-on's version number currently being reviewed by an editor
+#: views/developers/discuss.thtml:46
+#, fuzzy
+msgid "devcp_discuss_intro"
+msgstr ""
+"A Mozilla Add-ons Editor requested further information from you regarding "
+"version %2$s of your add-on %1$s."
+
+#. %1 is the add-on name
+#: views/developers/discuss.thtml:43
+#, fuzzy
+msgid "devcp_discuss_pagetitle"
+msgstr "Provide More Information For the Add-on Review of %1$s"
+
+#. submit button text
+#: views/developers/discuss.thtml:79
+#, fuzzy
+msgid "devcp_discuss_submit_reply"
+msgstr "Submit Reply"
+
+#: views/developers/discuss.thtml:72
+#, fuzzy
+msgid "devcp_discuss_success_message"
+msgstr ""
+"Your reply was successfully saved. The other participants of the discussion "
+"will be notified by email."
+
+#. in an author/editor discussion about an add-on to be reviewed:
+#. %1 is the commenter's user name (linked).
+#. %2 is the full date the comment was made.
+#: views/developers/discuss.thtml:52 views/developers/discuss.thtml:62
+#, fuzzy
+msgid "devcp_discuss_writtenby"
+msgstr "written by %1$s on %2$s"
+
+#: views/developers/addon_edit_authors.thtml:72
+#: views/developers/addon_edit_authors.thtml:81
+#, fuzzy
+msgid "devcp_edit_authors_add_author"
+msgstr "Add New Author"
+
+#: views/developers/addon_edit_authors.thtml:96
+#, fuzzy
+msgid "devcp_edit_authors_add_author_button"
+msgstr "Add Author"
+
+#: views/developers/addon_edit_authors.thtml:83
+#, fuzzy
+msgid "devcp_edit_authors_add_email"
+msgstr "Author Account Email:"
+
+#: views/developers/addon_edit_authors.thtml:98
+#, fuzzy
+msgid "devcp_edit_authors_add_loading"
+msgstr "Checking account email..."
+
+#: views/developers/addon_edit_authors.thtml:70
+#, fuzzy
+msgid "devcp_edit_authors_click_save"
+msgstr "Click the Update Authors button below to save."
+
+#: views/developers/addon_edit_authors.thtml:58
+#, fuzzy
+msgid "devcp_edit_authors_header_current"
+msgstr "Current Authors"
+
+#: views/developers/addon_edit_authors.thtml:50
+#, fuzzy
+msgid "devcp_edit_authors_header_manage"
+msgstr "Manage Add-on Authors"
+
+#: views/developers/addon_edit_authors.thtml:93
+#, fuzzy
+msgid "devcp_edit_authors_label_add_listed"
+msgstr "List as author in pubilc display pages"
+
+#: views/developers/addon_edit_authors.thtml:89
+#, fuzzy
+msgid "devcp_edit_authors_label_developer"
+msgstr ""
+"<strong>Developer</strong> - Can manage all aspects of the add-on listing, "
+"except for adding and removing other authors."
+
+#: views/developers/addon_edit_authors.thtml:88
+#, fuzzy
+msgid "devcp_edit_authors_label_owner"
+msgstr ""
+"<strong>Owner</strong> - Can manage all aspects of the add-on listing, "
+"including adding and removing other authors."
+
+#: views/developers/addon_edit_authors.thtml:90
+#, fuzzy
+msgid "devcp_edit_authors_label_viewer"
+msgstr ""
+"<strong>Viewer</strong> - Can view add-on developer listing and statistics, "
+"but can't make any changes."
+
+#. Placeholder for the empty option in a <select>.
+#: views/developers/addon_edit_categories.thtml:69
+#, fuzzy
+msgid "devcp_edit_authors_option_empty"
+msgstr "----------------"
+
+#: views/developers/addon_edit_authors.thtml:86
+#, fuzzy
+msgid "devcp_edit_authors_select_role"
+msgstr "Select a role for the author:"
+
+#. Column name in a table.
+#: views/developers/addon_edit_authors.thtml:62
+#, fuzzy
+msgid "devcp_edit_authors_th_author"
+msgstr "Author"
+
+#. Column name in a table.
+#: views/developers/addon_edit_authors.thtml:64
+#, fuzzy
+msgid "devcp_edit_authors_th_listed"
+msgstr "Listed"
+
+#. Column name in a table.
+#: views/developers/addon_edit_authors.thtml:63
+#, fuzzy
+msgid "devcp_edit_authors_th_role"
+msgstr "Role"
+
+#: views/developers/addon_edit_authors.thtml:77
+#, fuzzy
+msgid "devcp_edit_authors_update_author"
+msgstr "Update authors"
+
+#: views/developers/addon_edit_categories.thtml:99
+#, fuzzy
+msgid "devcp_edit_categories_button_update"
+msgstr "Update Categories"
+
+#: views/developers/addon_edit_categories.thtml:88
+#, fuzzy
+msgid "devcp_edit_categories_does_not_fit"
+msgstr "My add-on doesn't fit into any available categories."
+
+#. %s is the application name (Firefox, Thunderbird).
+#: views/developers/addon_edit_categories.thtml:61
+#, fuzzy
+msgid "devcp_edit_categories_header_application"
+msgstr "%s Categories"
+
+#: views/developers/addon_edit_categories.thtml:49
+#, fuzzy
+msgid "devcp_edit_categories_header_manage"
+msgstr "Manage Add-on Categories"
+
+#: views/developers/addon_edit_categories.thtml:91
+#, fuzzy
+msgid "devcp_edit_categories_hover"
+msgstr "Hover over a category to see its description."
+
+#. %s is the category number (1, 2, 3).
+#: views/developers/addon_edit_categories.thtml:67
+#, fuzzy
+msgid "devcp_edit_categories_label_category_num"
+msgstr "Category %s"
+
+#: views/developers/addon_edit_categories.thtml:94
+#: views/developers/addon_edit_categories.thtml:103
+#, fuzzy
+msgid "devcp_edit_categories_none_available"
+msgstr "No categories are available for this add-on type and application."
+
+#: views/developers/addon_edit_categories.thtml:86
+#, fuzzy
+msgid "devcp_edit_categories_other"
+msgstr ""
+"Place your add-on into this category only if it does not fit into any other "
+"available categories."
+
+#. %s is the application name (Firefox, Thunderbird).
+#: views/developers/addon_edit_categories.thtml:63
+#, fuzzy
+msgid "devcp_edit_categories_select_application_categories"
+msgstr "Select up to three %s categories for your add-on"
+
+#: views/developers/addon_edit.thtml:47
+#, fuzzy
+msgid "devcp_edit_dd_manage_authors"
+msgstr "Add or remove users that can manage this add-on."
+
+#: views/developers/addon_edit.thtml:49
+#, fuzzy
+msgid "devcp_edit_dd_manage_categories"
+msgstr ""
+"Select the relevant categories for each application your add-on supports."
+
+#: views/developers/addon_edit.thtml:51
+#, fuzzy
+msgid "devcp_edit_dd_manage_description"
+msgstr ""
+"Add and modify translations for your add-on's summary, description, end-user "
+"license, and privacy policy."
+
+#: views/developers/addon_edit.thtml:53
+#, fuzzy
+msgid "devcp_edit_dd_manage_properties"
+msgstr "Change your add-on's name, homepage, icon, and other flags."
+
+#: views/developers/addon_edit_descriptions.thtml:116
+#, fuzzy
+msgid "devcp_edit_description_button_update"
+msgstr "Update Descriptions"
+
+#: views/developers/addon_edit_descriptions.thtml:115
+#, fuzzy
+msgid "devcp_edit_description_correct_error"
+msgstr "Please correct the errors above indicated in red."
+
+#: views/developers/addon_edit_descriptions.thtml:51
+#, fuzzy
+msgid "devcp_edit_descriptions_header"
+msgstr "Edit Add-on Descriptions"
+
+#: views/developers/addon_edit_descriptions.thtml:94
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_comments_description"
+msgstr ""
+"Any information end users may want to know that isn't necessarily applicable "
+"to the add-on summary or description. Common uses include listing known "
+"major bugs, information on how to report bugs, anticipated release date of a "
+"new version, etc."
+
+#: views/developers/addon_edit_descriptions.thtml:93
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_comments_name"
+msgstr "Developer Comments"
+
+#: views/developers/addon_edit_descriptions.thtml:86
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_description_description"
+msgstr ""
+"The description of your add-on is a longer explanation of features, "
+"functionality, and other relevant information. It is displayed under the "
+"summary on the add-on's display page."
+
+#: views/developers/addon_edit_descriptions.thtml:85
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_description_name"
+msgstr "Add-on Description"
+
+#: views/developers/addon_edit_descriptions.thtml:103
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_eula_description"
+msgstr ""
+"If your add-on has an End-User License Agreement (EULA), please enter its "
+"text below. If set below, users will be required to agree to this before "
+"installing your add-on. Please note that a EULA is not the same as a code "
+"license such as GPL or MPL."
+
+#: views/developers/addon_edit_descriptions.thtml:102
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_eula_name"
+msgstr "End-User License Agreement"
+
+#: views/developers/addon_edit_descriptions.thtml:112
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_privacy_description"
+msgstr ""
+"If your add-on has a privacy policy, enter its text here. Your add-on's "
+"display page will display a link to the policy."
+
+#: views/developers/addon_edit_descriptions.thtml:111
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_privacy_name"
+msgstr "Privacy Policy"
+
+#: views/developers/addon_edit_descriptions.thtml:78
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_summary_description"
+msgstr ""
+"The summary is a short explanation of your add-on's basic functionality that "
+"is displayed in search and browse listings, as well as at the top of your "
+"add-on's display page. <strong>Limit of 250 characters.</strong>"
+
+#: views/developers/addon_edit_descriptions.thtml:77
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_summary_name"
+msgstr "Add-on Summary"
+
+#: views/developers/addon_edit.thtml:46
+#, fuzzy
+msgid "devcp_edit_dt_manage_authors"
+msgstr "Manage Add-on Authors"
+
+#: views/developers/addon_edit.thtml:48
+#, fuzzy
+msgid "devcp_edit_dt_manage_categories"
+msgstr "Manage Add-on Categories"
+
+#: views/developers/addon_edit.thtml:50
+#, fuzzy
+msgid "devcp_edit_dt_manage_descriptions"
+msgstr "Manage Add-on Descriptions"
+
+#: views/developers/addon_edit.thtml:52
+#, fuzzy
+msgid "devcp_edit_dt_manage_properties"
+msgstr "Manage Add-on Properties"
+
+#: views/developers/addon_edit_properties.thtml:170
+msgid "devcp_edit_label_externalsoftware"
+msgstr ""
+"Tämä lisäosa tarvitsee toimiakseen erikseen jaeltavan, itsenäisen ohjelman"
+
+#: views/developers/addon_edit_properties.thtml:205
+msgid "devcp_edit_label_locale_disambiguation"
+msgstr "Lisätietoja lokaalista"
+
+#: views/developers/addon_edit_properties.thtml:168
+msgid "devcp_edit_label_prerelease"
+msgstr "Tämä on esijulkaisuversio"
+
+#: views/developers/addon_edit_properties.thtml:169
+msgid "devcp_edit_label_sitespecific"
+msgstr "Tämä on sivustokohtainen lisäosa"
+
+#: views/developers/addon_edit_properties.thtml:202
+msgid "devcp_edit_label_target_locale"
+msgstr "Kohdelokaali"
+
+#: views/developers/addon_edit_properties.thtml:212
+#, fuzzy
+msgid "devcp_edit_properties_button_update"
+msgstr "Update Properties"
+
+#: views/developers/addon_edit_properties.thtml:198
+#, fuzzy
+msgid "devcp_edit_properties_change_guid"
+msgstr "Only change if you understand all of the consequences."
+
+#: views/developers/addon_edit_properties.thtml:109
+#, fuzzy
+msgid "devcp_edit_properties_current_icon"
+msgstr "Current Icon"
+
+#: views/developers/addon_edit_properties.thtml:85
+#, fuzzy
+msgid "devcp_edit_properties_default_locale"
+msgstr ""
+"An add-on's default locale is the main locale in which translations must be "
+"present. If translations for your add-on's descriptions are unavailable in a "
+"user's selected language, they will fall back to this default locale."
+
+#: views/developers/addon_edit_properties.thtml:167
+#, fuzzy
+msgid "devcp_edit_properties_flags"
+msgstr "These flags are used to filter and classify add-ons."
+
+#: views/developers/addon_edit_properties.thtml:174
+#, fuzzy
+msgid "devcp_edit_properties_guid"
+msgstr ""
+"The GUID of your add-on is specified in its install.rdf and uniquely "
+"identifies it. You cannot change your GUID once it is listed on Mozilla Add-"
+"ons."
+
+#: views/developers/addon_edit_properties.thtml:53
+#, fuzzy
+msgid "devcp_edit_properties_header"
+msgstr "Edit Add-on Properties"
+
+#: views/developers/addon_edit_properties.thtml:186
+#, fuzzy
+msgid "devcp_edit_properties_header_addon_type"
+msgstr "Add-on Type"
+
+#: views/developers/addon_edit_properties.thtml:181
+#, fuzzy
+msgid "devcp_edit_properties_header_admin_settings"
+msgstr "Admin Settings"
+
+#: views/developers/addon_edit_properties.thtml:84
+#, fuzzy
+msgid "devcp_edit_properties_header_default_locale"
+msgstr "Default Locale"
+
+#: views/developers/addon_edit_properties.thtml:166
+#, fuzzy
+msgid "devcp_edit_properties_header_flags"
+msgstr "Add-on Flags"
+
+#: views/developers/addon_edit_properties.thtml:173
+#: views/developers/addon_edit_properties.thtml:197
+#, fuzzy
+msgid "devcp_edit_properties_header_guid"
+msgstr "Add-on GUID"
+
+#: views/developers/addon_edit_properties.thtml:104
+#, fuzzy
+msgid "devcp_edit_properties_header_icon"
+msgstr "Add-on Icon"
+
+#: views/developers/addon_edit_properties.thtml:159
+#, fuzzy
+msgid "devcp_edit_properties_header_other_settings"
+msgstr "Other Settings"
+
+#. A header on the admin page to toggle trusted status.
+#: views/developers/addon_edit_properties.thtml:182
+#, fuzzy
+msgid "devcp_edit_properties_header_trusted"
+msgstr "Trusted Add-on?"
+
+#: views/developers/addon_edit_properties.thtml:160
+#, fuzzy
+msgid "devcp_edit_properties_header_view_source"
+msgstr "View Source Online"
+
+#. %s is a comma-separated list of image extensions ".png, .jpg"
+#: views/developers/addon_edit_properties.thtml:106
+#, fuzzy
+msgid "devcp_edit_properties_icon"
+msgstr ""
+"The add-on icon is a small image that is displayed next to your add-on's "
+"name in browse and search results, display pages, and in the add-on "
+"installation dialog. The image will automatically be resized to 32 x 32 "
+"pixels. Please use one of the following image types: %s"
+
+#: views/developers/addon_edit_properties.thtml:171
+#, fuzzy
+msgid "devcp_edit_properties_label_binary"
+msgstr "This add-on contains binary components"
+
+#: views/developers/addon_edit_properties.thtml:185
+#, fuzzy
+msgid "devcp_edit_properties_label_not_trusted"
+msgstr "Not Trusted"
+
+#: views/developers/addon_edit_properties.thtml:184
+#, fuzzy
+msgid "devcp_edit_properties_label_trusted"
+msgstr "Trusted"
+
+#: views/developers/addon_edit_properties.thtml:110
+#, fuzzy
+msgid "devcp_edit_properties_new_icon"
+msgstr "New Icon"
+
+#: views/developers/addon_edit_properties.thtml:118
+#, fuzzy
+msgid "devcp_edit_properties_remove_icon"
+msgstr "Remove Icon"
+
+#: views/developers/addon_edit_properties.thtml:136
+#, fuzzy
+msgid "devcp_edit_properties_transbox_homepage_description"
+msgstr ""
+"If your add-on has another homepage, enter its address here. Adding other "
+"translations is not necessary unless your website is localized into other "
+"languages."
+
+#: views/developers/addon_edit_properties.thtml:135
+#, fuzzy
+msgid "devcp_edit_properties_transbox_homepage_name"
+msgstr "Add-on Homepage"
+
+#: views/developers/addon_edit_properties.thtml:79
+#, fuzzy
+msgid "devcp_edit_properties_transbox_name_description"
+msgstr "The name of your add-on is displayed everywhere your add-on is listed."
+
+#: views/developers/addon_edit_properties.thtml:78
+#, fuzzy
+msgid "devcp_edit_properties_transbox_name_name"
+msgstr "Add-on Name"
+
+#: views/developers/addon_edit_properties.thtml:145
+#, fuzzy
+msgid "devcp_edit_properties_transbox_supportemail_description"
+msgstr ""
+"If you have an email address for support inquiries, enter it here. Adding "
+"other translations is not necessary unless you have different email "
+"addresses for different languages."
+
+#: views/developers/addon_edit_properties.thtml:144
+#, fuzzy
+msgid "devcp_edit_properties_transbox_supportemail_name"
+msgstr "Support Email Address"
+
+#: views/developers/addon_edit_properties.thtml:154
+#, fuzzy
+msgid "devcp_edit_properties_transbox_supporturl_description"
+msgstr ""
+"If your add-on has a support website or forum, enter its address here. "
+"Adding other translations is not necessary unless your website is localized "
+"into other languages."
+
+#: views/developers/addon_edit_properties.thtml:153
+#, fuzzy
+msgid "devcp_edit_properties_transbox_supporturl_name"
+msgstr "Support Website"
+
+#: views/developers/addon_edit_properties.thtml:183
+#, fuzzy
+msgid "devcp_edit_properties_trusted"
+msgstr "Trusted add-ons can become public without Editor review."
+
+#. %s is href="..." and should stay in the <a> tag.
+#: views/developers/addon_edit_properties.thtml:119
+#, fuzzy
+msgid "devcp_edit_properties_undelete"
+msgstr "Icon will be deleted on save. <a %s>Cancel?</a>"
+
+#: views/developers/addon_edit_properties.thtml:161
+#, fuzzy
+msgid "devcp_edit_properties_view_source"
+msgstr ""
+"The source of your add-on files can be viewed online by any logged in user "
+"if you wish."
+
+#: views/developers/addon_edit_properties.thtml:162
+#, fuzzy
+msgid "devcp_edit_properties_view_source_allow"
+msgstr "Allow online source viewing"
+
+#: views/developers/addon_edit_properties.thtml:163
+#, fuzzy
+msgid "devcp_edit_properties_view_source_do_not_allow"
+msgstr "Do not allow online source viewing"
+
+#: views/elements/developers/editbox.thtml:46
+#, fuzzy
+msgid "devcp_editbox_authors"
+msgstr "Authors"
+
+#: views/elements/developers/editbox.thtml:47
+#, fuzzy
+msgid "devcp_editbox_categories"
+msgstr "Categories"
+
+#: views/elements/developers/editbox.thtml:52
+#, fuzzy
+msgid "devcp_editbox_change_status"
+msgstr "Change Status"
+
+#: views/elements/developers/editbox.thtml:48
+#, fuzzy
+msgid "devcp_editbox_descriptions"
+msgstr "Descriptions"
+
+#: views/elements/developers/editbox.thtml:43
+#, fuzzy
+msgid "devcp_editbox_edit_addon"
+msgstr "Edit Add-on"
+
+#: views/elements/developers/editbox.thtml:57
+#, fuzzy
+msgid "devcp_editbox_new_version"
+msgstr "New Version"
+
+#: views/elements/developers/editbox.thtml:49
+#, fuzzy
+msgid "devcp_editbox_properties"
+msgstr "Properties"
+
+#: views/elements/developers/editbox.thtml:60
+#, fuzzy
+msgid "devcp_editbox_screenshots"
+msgstr "Preview Screenshots"
+
+#: views/elements/developers/editbox.thtml:53
+#, fuzzy
+msgid "devcp_editbox_statistics_dashboard"
+msgstr "Statistics Dashboard"
+
+#: views/elements/developers/editbox.thtml:54
+#, fuzzy
+msgid "devcp_editbox_versions"
+msgstr "Versions and Files"
+
+#: views/elements/developers/editbox.thtml:42
+#, fuzzy
+msgid "devcp_editbox_view_listing"
+msgstr "View Listing"
+
+#: views/elements/developers/editorsmenu.thtml:59
+msgid "devcp_editorsqueue_featured"
+msgstr "Näytteillä oleva lisäosa"
+
+#. %1 is the review count
+#: views/elements/developers/editorsqueue.thtml:42
+#: views/elements/developers/editorsmenu.thtml:56
+#, php-format
+msgid "devcp_editorsqueue_moderatedreviews"
+msgid_plural "devcp_editorsqueue_moderatedreviews"
+msgstr[0] "Suodatettu arvostelu"
+msgstr[1] "Suodatettuja arvosteluja (%s)"
+
+#. %1 is the nominated addons count
+#: views/elements/developers/editorsqueue.thtml:44
+#: views/elements/developers/editorsmenu.thtml:58
+#, php-format
+msgid "devcp_editorsqueue_nominated"
+msgid_plural "devcp_editorsqueue_nominated"
+msgstr[0] "Ehdolle asetettu lisäosa (%s)"
+msgstr[1] "Ehdolle asetetut lisäosat (%s)"
+
+#. %1 is the update count
+#: views/elements/developers/editorsqueue.thtml:43
+#: views/elements/developers/editorsmenu.thtml:57
+#, php-format
+msgid "devcp_editorsqueue_pendingupdates"
+msgid_plural "devcp_editorsqueue_pendingupdates"
+msgstr[0] "Odottaa päivitystä (%s)"
+msgstr[1] "Odottavat päivitystä (%s)"
+
+#: controllers/statistics_controller.php:147
+#: controllers/statistics_controller.php:361
+#: controllers/previews_controller.php:108
+#: controllers/previews_controller.php:211
+#: controllers/previews_controller.php:312
+msgid "devcp_error_addon_access_denied"
+msgstr "Sinulle ei ole oikeutta muokata tätä lisäosaa."
+
+#. %s is a complete URL with the text from devcp_error_appversion_reference_link_text
+#. in the <a> tag. This should be fixed.
+#: controllers/components/developers.php:591
+#, php-format
+msgid "devcp_error_appversion_reference_link"
+msgstr "Lue %s."
+
+#. This is the link text in the <a> for devcp_error_appversion_reference_link. This
+#. should be fixed.
+#: controllers/components/developers.php:591
+msgid "devcp_error_appversion_reference_link_text"
+msgstr "referenssisivu"
+
+#: views/developers/addon_edit_authors.thtml:76
+#, fuzzy
+msgid "devcp_error_empty_authors"
+msgstr "Your add-on must have at least one owner."
+
+#. %1$s is the name of the file
+#: controllers/components/developers.php:658
+#, fuzzy
+msgid "devcp_error_file_exists"
+msgstr ""
+"A version of that addon already exists. To replace it, you must delete the "
+"file %1$s first."
+
+#. %1$s is a file extension. Example: .exe
+#. %2$s is a comma separated list of extensions. Example: .xpi, .jar
+#: controllers/components/developers.php:355
+#, php-format
+msgid "devcp_error_file_extension"
+msgstr ""
+"Tiedostopääte (%s) ei ole kelvollinen valitun tyyppiselle lisäosalle. Oikea "
+"pääte on: %s"
+
+#: controllers/components/developers.php:64
+msgid "devcp_error_five_categories"
+msgstr "Älä valitse yli viittä luokkaa."
+
+#: controllers/components/developers.php:526
+msgid "devcp_error_guid_application"
+msgstr "Lisäosan tunnus (GUID on jo käytössä."
+
+#: controllers/components/developers.php:337
+#: controllers/components/developers.php:389
+msgid "devcp_error_http_incomplete"
+msgstr "Siirto katkesi kesken"
+
+#: controllers/components/developers.php:335
+#: controllers/components/developers.php:336
+#: controllers/components/developers.php:387
+#: controllers/components/developers.php:388
+msgid "devcp_error_http_maxupload"
+msgstr "Tiedostokoko ylittää suurimman sallitun koon"
+
+#: controllers/components/developers.php:338
+#: controllers/components/developers.php:390
+msgid "devcp_error_http_nofile"
+msgstr "Tiedostoa ei siirretty"
+
+#. %1$s is a file extension. Example: .exe
+#. %2$s is a comma separated list of extensions. Example: .xpi, .jar
+#: controllers/components/developers.php:401
+#, php-format
+msgid "devcp_error_icon_extension"
+msgstr ""
+"Tiedostopääte %s ei ole kelvollinen kuvakkeelle. Kuvakkeen tiedostopäätteen "
+"tulee olla jokin seuraavista: %s"
+
+#: controllers/developers_controller.php:504
+msgid "devcp_error_index_rdf_notfound"
+msgstr "Install.rdf-tiedostoa ei löytynyt."
+
+#: controllers/components/developers.php:601
+msgid "devcp_error_install_manifest"
+msgstr "Seuraavat virheet havaittiin install.rdf:ssä:"
+
+#: controllers/developers_controller.php:1463
+msgid "devcp_error_invalid_addontype"
+msgstr "Valitse kelvollinen lisäosatyyppi."
+
+#. %$1s is a version. Example: 3.1.1
+#. %$2s is an add-on name.
+#: controllers/components/developers.php:569
+#: controllers/components/developers.php:581
+#, php-format
+msgid "devcp_error_invalid_appversion"
+msgstr "%s ei ole kelvollinen versionumero ohjelmalle %s"
+
+#. %s is a string
+#: controllers/components/developers.php:521
+#, php-format
+msgid "devcp_error_invalid_guid"
+msgstr "Lisäosan tunnus (GUID) on virheellinen: %s"
+
+#. %$1s is a version. Example: 3.1.1
+#. %$2s is an add-on name.
+#: controllers/components/developers.php:572
+#, php-format
+msgid "devcp_error_invalid_minversion"
+msgstr ""
+"%s ei ole kelvollinen %sin versionumero: minimiversio ei voi sisältää *-"
+"merkkiä"
+
+#: controllers/components/developers.php:536
+msgid "devcp_error_invalid_version"
+msgstr ""
+"Lisäosan versionumero on virheellinen. Lue versionumeron <a href=\"http://"
+"developer.mozilla.org/en/docs/Toolkit_version_format\">määritelmä</a>."
+
+#: controllers/components/developers.php:531
+msgid "devcp_error_invalid_version_spaces"
+msgstr ""
+"Lisäosan versionumero on virheellinen. Versionumero ei voi sisältää "
+"välilyöntejä."
+
+#. %s is an error message from the parser.
+#: controllers/components/developers.php:501
+#, php-format
+msgid "devcp_error_manifest_parse"
+msgstr "Seuraava virhe tapahtui jäsennettäessä tiedostoa install.rdf: %s"
+
+#: controllers/components/developers.php:373
+msgid "devcp_error_move_file"
+msgstr "Tiedostoa ei voitu siirtää"
+
+#. %s is the name of a file
+#: controllers/components/developers.php:650
+#: controllers/components/developers.php:662
+#: controllers/components/developers.php:667
+#: controllers/components/developers.php:727
+#: controllers/components/developers.php:738
+#: controllers/components/developers.php:743
+#, php-format
+msgid "devcp_error_moving_file"
+msgstr "Virhe tapahtui siirrettäessä %s."
+
+#: controllers/components/developers.php:595
+msgid "devcp_error_mozilla_application"
+msgstr "Lisäosalla täytyy olla ainakin yksi kelvollinen kohdeohjelma."
+
+#: controllers/components/developers.php:516
+msgid "devcp_error_no_guid"
+msgstr "Lisäosan tunnusta (GUID) ei löytynyt install.rdf:stä."
+
+#: controllers/components/developers.php:287
+msgid "devcp_error_no_platform"
+msgstr "Alustaa ei valittu"
+
+#: controllers/components/developers.php:59
+msgid "devcp_error_one_category"
+msgstr "Valitse ainakin yksi luokka."
+
+#: controllers/components/developers.php:92
+msgid "devcp_error_one_user"
+msgstr "Lisäosalle täytyy merkitä ainakin yksi tekijä."
+
+#. %1$s is a file extension. Example: .exe
+#. %2$s is a comma separated list of extensions. Example: .xpi, .jar
+#: controllers/components/developers.php:1081
+#, php-format
+msgid "devcp_error_preview_extension"
+msgstr ""
+"Tiedostopääte %s ei ole kelvollinen esikatselukuvalle. Kuvan "
+"tiedostopäätteen tulee olla jokin seuraavista: %s"
+
+#: controllers/components/developers.php:511
+msgid "devcp_error_updatekey"
+msgstr ""
+"Lisäosalla ei voi olla updateKey-arvoa. Poista updateKey-arvo install.rdf:"
+"stä ja yritä uudestaan."
+
+#: controllers/components/developers.php:506
+msgid "devcp_error_updateurl"
+msgstr ""
+"Lisäosalla ei voi olla AMOn ulkopuolista päivitys URL:ää (updateURL). Poista "
+"päivitysosoite install.rdf:stä ja yritä uudelleen."
+
+#: controllers/developers_controller.php:465
+#: controllers/components/developers.php:271
+msgid "devcp_error_upload_file"
+msgstr "Siirrä tiedosto."
+
+#: views/developers/uploader.thtml:135
+#, fuzzy
+msgid "devcp_input_upload_file"
+msgstr "Upload File"
+
+#: views/pages/js_constants.js.thtml:89
+#, fuzzy
+msgid "devcp_js_a_cancel"
+msgstr "Cancel"
+
+#: views/pages/js_constants.js.thtml:90
+#, fuzzy
+msgid "devcp_js_add_email"
+msgstr "Please enter the account email of the author you wish to add."
+
+#. alt text for a down-arrow image.
+#: views/pages/js_constants.js.thtml:81
+#, fuzzy
+msgid "devcp_js_img_move_down"
+msgstr "Move Down"
+
+#. alt text for an up-arrow image.
+#: views/pages/js_constants.js.thtml:82
+#, fuzzy
+msgid "devcp_js_img_move_up"
+msgstr "Move Up"
+
+#: views/pages/js_constants.js.thtml:91
+#, fuzzy
+msgid "devcp_js_img_remove_compat"
+msgstr "Remove Application Compatibility"
+
+#: views/pages/js_constants.js.thtml:86
+#, fuzzy
+msgid "devcp_js_input_list_author"
+msgstr "List as author in public listings"
+
+#: views/pages/js_constants.js.thtml:92
+#, fuzzy
+msgid "devcp_js_license_select"
+msgstr "Please select a license."
+
+#: views/pages/js_constants.js.thtml:93
+#, fuzzy
+msgid "devcp_js_license_text"
+msgstr "Please enter text for your license."
+
+#. <option> text in a <select> for Author role in an add-on.
+#: views/pages/js_constants.js.thtml:84
+#, fuzzy
+msgid "devcp_js_option_developer"
+msgstr "Developer"
+
+#. <option> text in a <select> for Author role in an add-on.
+#: views/pages/js_constants.js.thtml:83
+#, fuzzy
+msgid "devcp_js_option_owner"
+msgstr "Owner"
+
+#. <option> text in a <select> for Author role in an add-on.
+#: views/pages/js_constants.js.thtml:85
+#, fuzzy
+msgid "devcp_js_option_viewer"
+msgstr "Viewer"
+
+#: views/pages/js_constants.js.thtml:88
+#, fuzzy
+msgid "devcp_js_remove_author"
+msgstr "Remove Author"
+
+#: views/pages/js_constants.js.thtml:87
+#, fuzzy
+msgid "devcp_js_sure_remove"
+msgstr "Are you <strong>sure</strong> you wish to remove this author?"
+
+#: views/pages/js_constants.js.thtml:77
+#, fuzzy
+msgid "devcp_js_upload_alert"
+msgstr "You must select a file to upload."
+
+#. %1$s is an addon id, like 32.
+#. %2$s is a version number, like 3.5.
+#: controllers/components/developers.php:1212
+#, fuzzy
+msgid "devcp_license_existing"
+msgstr "Custom license for add-on %1$s v%2$s"
+
+#: views/elements/developers/localebox.thtml:44
+msgid "devcp_localebox_header_localizedfields"
+msgstr "Lokalisoidut kentät"
+
+#. %1 is the default locale
+#: views/elements/developers/localebox.thtml:48
+#, php-format
+msgid "devcp_localebox_intro"
+msgstr ""
+"Jotkin tämän sivun kentistä on voidaan näyttää loppukäyttäjän omalla "
+"kielellä. Valitse alta kieli (lokaali) ja muokkaa lisäosan kuvausta "
+"valitulla kielellä. Jos käännöstä ei ole saatavissa jollekin kielelle, "
+"näytetään oletuslokaalin kuvaus (%s)."
+
+#: views/elements/developers/sidebar.thtml:68
+#: views/elements/developers/myaddons.thtml:75
+msgid "devcp_myaddons_admincp_link"
+msgstr "Ylläpitäjän ohjauspaneeli"
+
+#: views/elements/developers/sidebar.thtml:65
+#: views/elements/developers/myaddons.thtml:72
+msgid "devcp_myaddons_editorcp_link"
+msgstr "Toimittajan ohjauspaneeli"
+
+#: views/elements/developers/myaddons.thtml:52
+msgid "devcp_myaddons_link"
+msgstr "Lisäosani"
+
+#: views/elements/developers/sidebar.thtml:70
+#: views/elements/developers/myaddons.thtml:77
+msgid "devcp_myaddons_mainpage_link"
+msgstr "Palaa etusivulle"
+
+#: views/elements/developers/sidebar.thtml:63
+#: views/elements/developers/myaddons.thtml:70
+msgid "devcp_myaddons_statistics_link"
+msgstr "Tilastosivu"
+
+#: views/elements/developers/sidebar.thtml:62
+#: views/elements/developers/myaddons.thtml:69
+msgid "devcp_myaddons_submitaddon_link"
+msgstr "Lähetä lisäosa"
+
+#: views/elements/developers/sidebar.thtml:48
+#: views/elements/developers/myaddons.thtml:67
+msgid "devcp_myaddons_title"
+msgstr "Kehittäjän työkalut"
+
+#. %1$s is an add-on ID, perhaps 167.
+#. %2$s is a URL.
+#: controllers/developers_controller.php:256
+#, fuzzy
+msgid "devcp_new_addon_error"
+msgstr ""
+"This add-on ID (%1$s) already exists in the database. If this is your add-"
+"on, you can <a href=\"%2$s\">upload a new version</a>."
+
+#: views/developers/addon_status_nominate.thtml:62
+#, fuzzy
+msgid "devcp_nominate_cancel"
+msgstr "Cancel and return"
+
+#. %1 is the add-on name
+#: views/developers/addon_status_nominate.thtml:61
+#, php-format
+msgid "devcp_nominate_submit_nominate"
+msgstr "Ehdota lisäosaa %s"
+
+#: views/developers/addon_edit_properties.thtml:50
+#: views/developers/addon_status.thtml:49
+#: views/developers/versions_edit.thtml:50
+#, fuzzy
+msgid "devcp_notice_changes_error"
+msgstr ""
+"<span>One or more of your changes couldn't be saved.</span><br />Please look "
+"for the errors below. The rest of your changes were successfully saved."
+
+#: views/developers/addon_edit_authors.thtml:47
+#: views/developers/addon_edit_properties.thtml:47
+#: views/developers/addon_status.thtml:46
+#: views/developers/addon_edit_descriptions.thtml:47
+#: views/developers/versions_edit.thtml:47
+#: views/developers/addon_edit_categories.thtml:46
+#, fuzzy
+msgid "devcp_notice_changes_saved"
+msgstr ""
+"<span>Your changes have been saved.</span><br />Please note that some "
+"changes may take several hours to appear in all areas of the website."
+
+#: controllers/previews_controller.php:252
+msgid "devcp_notice_cleardefault"
+msgstr ""
+"Jostain toisesta kuvasta tulee oletuskuva jos nykyinen oletuskuva muutetaan "
+"normaaliksi esikatselukuvaksi."
+
+#: controllers/previews_controller.php:184
+#: controllers/previews_controller.php:251
+msgid "devcp_notice_makedefault"
+msgstr ""
+"Kuvan muuttaminen oletuskuvaksi muuttaa aikaisemman oletusesikatselukuvan "
+"normaaliksi kuvaksi."
+
+#: views/developers/addon_edit_authors.thtml:70
+#, fuzzy
+msgid "devcp_notice_unsaved_changes"
+msgstr "You have unsaved changes."
+
+#: controllers/developers_controller.php:87
+#: controllers/developers_controller.php:97
+#: controllers/developers_controller.php:100
+#: controllers/previews_controller.php:67
+#: controllers/previews_controller.php:79
+#: controllers/previews_controller.php:82
+msgid "devcp_pagetitle"
+msgstr "Kehittäjän ohjauspaneeli"
+
+#: controllers/previews_controller.php:103
+#: controllers/previews_controller.php:104
+msgid "devcp_preview_add_pagetitle"
+msgstr "Lisää esikatselukuva"
+
+#: controllers/previews_controller.php:135
+msgid "devcp_preview_added_successfully"
+msgstr "Esikatselukuvan lisääminen onnistui."
+
+#: controllers/previews_controller.php:323
+msgid "devcp_preview_deleted_successfully"
+msgstr "Esikatselukuvan poisto onnistui."
+
+#: controllers/previews_controller.php:194
+#: controllers/previews_controller.php:195
+msgid "devcp_preview_edit_pagetitle"
+msgstr "Muokkaa esikatselua"
+
+#: controllers/previews_controller.php:237
+msgid "devcp_preview_updated_successfully"
+msgstr "Esikatselun päivittäminen onnistui"
+
+#: views/developers/previews.thtml:120
+#, fuzzy
+msgid "devcp_previews_a_another"
+msgstr "Add Another Preview"
+
+#: views/developers/previews.thtml:96
+#, fuzzy
+msgid "devcp_previews_a_delete"
+msgstr "Delete Preview"
+
+#: views/developers/previews.thtml:95
+#, fuzzy
+msgid "devcp_previews_a_replace"
+msgstr "Replace Preview"
+
+#: views/developers/previews.thtml:126
+#, fuzzy
+msgid "devcp_previews_a_update"
+msgstr "Update Previews"
+
+#: views/developers/previews.thtml:115 views/developers/previews.thtml:124
+#, fuzzy
+msgid "devcp_previews_add_new"
+msgstr "Add New Preview"
+
+#. %s is a list of file extensions, e.g. ".png, .gif"
+#: views/developers/previews.thtml:116
+#, fuzzy
+msgid "devcp_previews_add_select"
+msgstr ""
+"Select an image to upload below. Images larger than the maximum size of 700 "
+"pixels wide by 525 pixels tall will be resized. Allowed file types: %s"
+
+#: views/developers/previews.thtml:121
+#, fuzzy
+msgid "devcp_previews_click_below"
+msgstr "Click Update Previews below to upload."
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/previews.thtml:102
+#, fuzzy
+msgid "devcp_previews_click_update"
+msgstr ""
+"Click the Update Previews button below to save this image. (<a %s>Cancel?</"
+"a>)"
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/previews.thtml:107
+#, fuzzy
+msgid "devcp_previews_error_message"
+msgstr ""
+"This preview will be deleted when Update Previews is clicked below. (<a %"
+"s>Cancel?</a>)"
+
+#: views/previews/add.thtml:45
+msgid "devcp_previews_filetype_info"
+msgstr ""
+"Siirrä alla olevalla lomakkeella PNG-, JPG-, tai GIF-kuvakaappaus "
+"lisäosasta. Kuvat, jotka ovat leveämpiä kuin 700 kuvapistettä tai korkeampia "
+"kuin 525 kuvapistettä, pienennetään."
+
+#: views/previews/add.thtml:43
+msgid "devcp_previews_header_add"
+msgstr "Lisää esikatselukuva"
+
+#: views/developers/previews.thtml:80
+#, fuzzy
+msgid "devcp_previews_header_caption"
+msgstr "Preview Caption"
+
+#: views/previews/edit.thtml:43
+msgid "devcp_previews_header_edit"
+msgstr "Muokkaa esikatselukuvaa"
+
+#: views/developers/previews.thtml:93
+#, fuzzy
+msgid "devcp_previews_label_default"
+msgstr "Default Preview"
+
+#: views/previews/add.thtml:54
+msgid "devcp_previews_label_file"
+msgstr "Esikatselutiedosto"
+
+#: views/previews/add.thtml:59 views/previews/edit.thtml:50
+msgid "devcp_previews_label_makedefault"
+msgstr "Aseta kuva oletusesikatselukuvaksi"
+
+#: views/developers/previews.thtml:100
+#, fuzzy
+msgid "devcp_previews_label_new"
+msgstr "New image:"
+
+#: views/developers/previews.thtml:118
+#, fuzzy
+msgid "devcp_previews_label_upload"
+msgstr "Upload Preview: "
+
+#: views/developers/previews.thtml:50
+#, fuzzy
+msgid "devcp_previews_notice_error"
+msgstr "One or more of your new previews could not be saved."
+
+#: views/developers/previews.thtml:47
+#, fuzzy
+msgid "devcp_previews_notice_success"
+msgstr "Your previews have been updated successfully."
+
+#: views/developers/previews.thtml:59
+#, fuzzy
+msgid "devcp_previews_p_screenshots"
+msgstr ""
+"The preview screenshots for your add-on are shown below. You can make "
+"changes to captions or images below. The Default Preview is the preview that "
+"is displayed next to your add-on in search and browse listings."
+
+#: views/previews/edit.thtml:55
+msgid "devcp_previews_submit_delete"
+msgstr "Poista esikatselukuva"
+
+#: views/previews/edit.thtml:55
+msgid "devcp_previews_submit_delete_confirm"
+msgstr "Poistetaanko kuva?"
+
+#: views/previews/edit.thtml:54
+msgid "devcp_previews_submit_edit"
+msgstr "Muokkkaa esikatselukuvaa"
+
+#: views/previews/add.thtml:63
+msgid "devcp_previews_submit_upload"
+msgstr "Siirrä kuva"
+
+#: views/developers/previews.thtml:78
+#, fuzzy
+msgid "devcp_previews_thumbnail"
+msgstr "Thumbnail"
+
+#. %s is the add-on name.
+#: views/developers/previews.thtml:44
+#, fuzzy
+msgid "devcp_previews_title"
+msgstr "%s Preview Manager"
+
+#: views/developers/uploader.thtml:74
+msgid "devcp_review_agreement_please"
+msgstr "Lue ja hyväksy seuraava kehittäjäsopimus ennen kuin jatkat."
+
+#: views/elements/developers/rolecheck.thtml:42
+#, fuzzy
+msgid "devcp_rolecheck_no_privs"
+msgstr ""
+"<span>You do not have sufficient privileges to make changes on this page.</"
+"span><br />Contact the Add-on Owner if you need to make changes."
+
+#: controllers/developers_controller.php:1315
+#, fuzzy
+msgid "devcp_several_hours"
+msgstr ""
+"Please note that some changes may take several hours to appear in all areas "
+"of the website."
+
+#: views/elements/developers/sidebar.thtml:52
+#, fuzzy
+msgid "devcp_sidebar_a_dashboard"
+msgstr "Dashboard"
+
+#. %s is a number
+#: views/elements/developers/statsbar.thtml:45
+#: views/developers/dashboard.thtml:79
+#, php-format
+msgid "devcp_statsbar_adu"
+msgstr "<em>%s</em> päivittäin aktiivista käyttäjää"
+
+#. %s is a number
+#: views/elements/developers/statsbar.thtml:41
+#: views/developers/dashboard.thtml:75
+#, php-format
+msgid "devcp_statsbar_total_downloads"
+msgstr "<em>%s</em> latausta yhteensä"
+
+#. %s is a number
+#: views/elements/developers/statsbar.thtml:43
+#: views/developers/dashboard.thtml:77
+#, php-format
+msgid "devcp_statsbar_weekly_downloads"
+msgstr "<em>%s</em> latausta viikottain"
+
+#: views/developers/addon_status_confirm.thtml:59
+#, fuzzy
+msgid "devcp_status_confirm_active"
+msgstr ""
+"Marking this add-on active will cause it to show up in public areas "
+"appropriate for its status, including search and browse listings. It will be "
+"downloadable from the website and could be returned in client update checks, "
+"depending on its status. You will be able to return here and disable it "
+"again at your convenience."
+
+#: views/developers/addon_status_confirm.thtml:59
+#, fuzzy
+msgid "devcp_status_confirm_active_sure"
+msgstr "Are you sure you wish to mark this add-on active?"
+
+#: views/developers/addon_status_confirm.thtml:50
+#, fuzzy
+msgid "devcp_status_confirm_header_sure"
+msgstr "Are you sure?"
+
+#: views/developers/addon_status_confirm.thtml:55
+#, fuzzy
+msgid "devcp_status_confirm_inactive"
+msgstr ""
+"Marking this add-on inactive will prevent it from showing up in any public "
+"areas, including search and browse listings. It will not be downloadable "
+"from the website and will not be returned in client update checks. You will "
+"be able to return here and re-enable it at your convenience."
+
+#: views/developers/addon_status_confirm.thtml:55
+#, fuzzy
+msgid "devcp_status_confirm_inactive_sure"
+msgstr "Are you sure you wish to mark this add-on inactive?'"
+
+#: views/developers/addon_status_confirm.thtml:74
+#, fuzzy
+msgid "devcp_status_confirm_no"
+msgstr "No, cancel"
+
+#: views/developers/addon_status_confirm.thtml:67
+#, fuzzy
+msgid "devcp_status_confirm_public"
+msgstr ""
+"Making this add-on public will make it available for anyone to download and "
+"will begin offering updates to existing users."
+
+#: views/developers/addon_status_confirm.thtml:67
+#, fuzzy
+msgid "devcp_status_confirm_public_sure"
+msgstr "Are you sure you wish to make this add-on public?"
+
+#: views/developers/addon_status_confirm.thtml:63
+#, fuzzy
+msgid "devcp_status_confirm_sandbox"
+msgstr ""
+"Moving this add-on back to the sandbox will require users to login before "
+"downloading and updates will no longer be offered to existing users. Because "
+"your add-on is currently public, you will be able to return here at any time "
+"to make it public again."
+
+#: views/developers/addon_status_confirm.thtml:63
+#, fuzzy
+msgid "devcp_status_confirm_sandbox_sure"
+msgstr "Are you sure you wish to move this add-on to the sandbox?"
+
+#: views/developers/addon_status_confirm.thtml:73
+#, fuzzy
+msgid "devcp_status_confirm_yes"
+msgstr "Yes, I'm Sure"
+
+#: views/developers/addon_status_nominate.thtml:46
+#, fuzzy
+msgid "devcp_status_nominate_error_notice"
+msgstr ""
+"<span>A nomination message is required.</span><br />Please fill in the text "
+"box with the requested information and try again."
+
+#: views/developers/addon_status_nominate.thtml:55
+#, fuzzy
+msgid "devcp_status_nominate_header"
+msgstr "Add-on Nomination"
+
+#: views/developers/dashboard.thtml:85
+msgid "devcp_summary_lastversion"
+msgstr "Viimeisin versio:"
+
+#. %s is the add-on name.
+#: views/developers/addon_edit.thtml:43
+#: views/developers/addon_edit_authors.thtml:44
+#: views/developers/versions_delete.thtml:43
+#: views/developers/addon_edit_properties.thtml:44
+#: views/developers/addon_edit_descriptions.thtml:44
+#: views/developers/versions_edit.thtml:44
+#: views/developers/addon_edit_categories.thtml:43
+#: views/developers/versions.thtml:43
+#, fuzzy
+msgid "devcp_title_edit_addon"
+msgstr "Edit %s"
+
+#. title attribute for a javascript link that pops up a help dialog.
+#: views/elements/translationbox.thtml:68
+#, fuzzy
+msgid "devcp_transbox_a_title_help"
+msgstr "Help (does not leave page)"
+
+#: views/elements/translationbox.thtml:68
+#, fuzzy
+msgid "devcp_transbox_alt_help"
+msgstr "Help"
+
+#. %1$s is <span>17</span>, %2$s is 42.
+#: views/elements/translationbox.thtml:101
+#, fuzzy
+msgid "devcp_transbox_chars_used"
+msgstr "Characters used: %1$s / %2$s"
+
+#: views/elements/translationbox.thtml:132
+#, fuzzy
+msgid "devcp_transbox_delete_sure"
+msgstr "Are you sure you wish to delete this translation?"
+
+#. %s is a locale, like en-US.
+#: views/elements/translationbox.thtml:143
+#, fuzzy
+msgid "devcp_transbox_help_header_tabs"
+msgstr "What are these %s tabs?"
+
+#: views/elements/translationbox.thtml:145
+#, fuzzy
+msgid "devcp_transbox_help_header_what"
+msgstr "What if I don't have any translations?"
+
+#: views/elements/translationbox.thtml:147
+#, fuzzy
+msgid "devcp_transbox_help_hide"
+msgstr "Hide Help"
+
+#: views/elements/translationbox.thtml:146
+#, fuzzy
+msgid "devcp_transbox_help_if"
+msgstr ""
+"If a user browses the site and a translation isn't available in their own "
+"language, it will fall back to your add-on's Default Locale, specified in "
+"the Edit Add-on Properties area. If you don't have any translations, just "
+"enter what you can into your Default Locale, which should be a language you "
+"speak."
+
+#: views/elements/translationbox.thtml:144
+#, fuzzy
+msgid "devcp_transbox_help_transbox"
+msgstr ""
+"This is a <i>Translation Box</i>. It allows you to localize a specific field "
+"into any other languages for which you might have a translation. You can "
+"add, edit, and remove translations using the locale tabs."
+
+#: views/elements/translationbox.thtml:85
+#, fuzzy
+msgid "devcp_transbox_img_add_trans"
+msgstr "Add Translation"
+
+#: views/elements/translationbox.thtml:86
+#, fuzzy
+msgid "devcp_transbox_img_remove_trans"
+msgstr "Remove Translation"
+
+#: views/elements/translationbox.thtml:123
+#, fuzzy
+msgid "devcp_transbox_input_add_all"
+msgstr "Add Locale to All"
+
+#: views/elements/translationbox.thtml:122
+#, fuzzy
+msgid "devcp_transbox_input_add_locale"
+msgstr "Add Locale"
+
+#: views/elements/translationbox.thtml:124
+#: views/elements/translationbox.thtml:135
+#, fuzzy
+msgid "devcp_transbox_input_cancel"
+msgstr "Cancel"
+
+#: views/elements/translationbox.thtml:134
+#, fuzzy
+msgid "devcp_transbox_input_delete"
+msgstr "Delete It"
+
+#: views/elements/translationbox.thtml:113
+#, fuzzy
+msgid "devcp_transbox_select_locale"
+msgstr "Select the locale of the translation to add:"
+
+#. %1$s and %2$s are GUIDs.
+#: controllers/developers_controller.php:343
+#, fuzzy
+msgid "devcp_update_addon_guid_error"
+msgstr ""
+"The add-on GUID used in this file (%1$s) does not match the existing GUID "
+"for this add-on (%2$s)."
+
+#: controllers/developers_controller.php:334
+#, fuzzy
+msgid "devcp_update_addon_priv_error"
+msgstr "You do not have sufficient privileges to update this add-on."
+
+#. %1$s is a version number, %2$s is an add-on ID.
+#: controllers/developers_controller.php:399
+#, fuzzy
+msgid "devcp_update_addon_version_belong_error"
+msgstr "The specified version (%1$s) does not belong to this add-on (%2$s)."
+
+#. %1$s is a version number, maybe 1.1.
+#. %2$s is a URL.
+#: controllers/developers_controller.php:351
+#, fuzzy
+msgid "devcp_update_addon_version_exists_error"
+msgstr ""
+"The version number uploaded (%1$s) already exists for this add-on. If you "
+"are trying to add another file to this version, <a href=\"%2$s\">click here</"
+"a>."
+
+#. %1$s and %2$s are version numbers.
+#: controllers/developers_controller.php:405
+#, fuzzy
+msgid "devcp_update_addon_version_match_error"
+msgstr ""
+"The uploaded version number (%1$s) does not match the existing version "
+"number (%2$s)."
+
+#: views/developers/uploader.thtml:68
+#, fuzzy
+msgid "devcp_uploader_a_start"
+msgstr "Get Started"
+
+#: views/developers/uploader.thtml:137
+#, fuzzy
+msgid "devcp_uploader_ajax_loading"
+msgstr "Uploading file..."
+
+#: views/developers/uploader.thtml:82
+#, fuzzy
+msgid "devcp_uploader_button_agree"
+msgstr "Agree and continue"
+
+#: views/developers/uploader.thtml:157
+#, fuzzy
+msgid "devcp_uploader_button_edit"
+msgstr "Edit My Add-on"
+
+#: views/developers/uploader.thtml:158
+#, fuzzy
+msgid "devcp_uploader_button_later"
+msgstr "I'll complete my add-on later."
+
+#: views/developers/uploader.thtml:168
+#, fuzzy
+msgid "devcp_uploader_button_release"
+msgstr "Add Release Notes"
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/uploader.thtml:156
+#, fuzzy
+msgid "devcp_uploader_created_results"
+msgstr ""
+"<p>Your add-on listing has been successfully created. The basic information "
+"obtained from your uploaded file has been stored, but there's a lot more to "
+"your listing that can be customized.</p><p>Your add-on is currently marked "
+"as <strong>Incomplete</strong>. In order to complete your add-on, you'll "
+"need to make sure it has an accurate name, summary, and description, as well "
+"as at least one selected category. You can edit your add-on's information "
+"using the link below and check the status of your add-on at any time on the "
+"<a %s>status page</a>."
+
+#: views/developers/uploader.thtml:143
+#, fuzzy
+msgid "devcp_uploader_error_correct"
+msgstr "Please correct this problem and upload your file again."
+
+#. %1$s is a version number, %2$s is a status, e.g Public or Incomplete.
+#: views/developers/uploader.thtml:175
+#, fuzzy
+msgid "devcp_uploader_file_created"
+msgstr ""
+"Your new file has been added to version %1$s and is currently marked as %2$s."
+
+#: views/developers/uploader.thtml:154
+#, fuzzy
+msgid "devcp_uploader_header_created"
+msgstr "Add-on Created!"
+
+#: views/developers/uploader.thtml:141
+#, fuzzy
+msgid "devcp_uploader_header_error"
+msgstr "Oops! There seems to be a problem with this file..."
+
+#: views/developers/uploader.thtml:173
+#, fuzzy
+msgid "devcp_uploader_header_file_added"
+msgstr "File Added!"
+
+#: views/developers/uploader.thtml:66
+#, fuzzy
+msgid "devcp_uploader_header_how"
+msgstr "How does it all work?"
+
+#. %s is the version number, e.g. 3.2.
+#: views/developers/uploader.thtml:163
+#, fuzzy
+msgid "devcp_uploader_header_update_created"
+msgstr "Version %s Created"
+
+#: views/developers/uploader.thtml:117
+#, fuzzy
+msgid "devcp_uploader_header_upload"
+msgstr "Upload Your File"
+
+#: views/developers/uploader.thtml:67
+#, fuzzy
+msgid "devcp_uploader_how"
+msgstr ""
+"<p>Thanks for your interest in submitting your add-on to Mozilla Add-ons. "
+"Hosting your add-on on Mozilla Add-ons is the easiest way to handle "
+"distribution of your add-on. Here's what you'll get:</p><ul><li>Each add-on "
+"will have a public display page with information you provide, such as a "
+"brief summary of the add-on's functionality, an optional longer description, "
+"and a showcase of preview screenshots of your add-on.</li><li>Your add-on "
+"will appear in search and browse listings across the site, and even in the "
+"Add-ons Manager of Firefox 3.</li><li>We'll take care of hosting all of your "
+"downloads and providing automatic updates to users when you upload a new "
+"version.</li><li>You'll have access to a statistics dashboard with detailed "
+"information about your user base.</li></ul><p>Add-ons hosted on the site "
+"must be reviewed by a Mozilla Add-ons Editor before they will have all of "
+"the features listed above. If you're ready to start the process and have "
+"your add-on package ready for upload, just click on Get Started below!</p>"
+
+#: views/developers/uploader.thtml:125
+#, fuzzy
+msgid "devcp_uploader_label_platformtype"
+msgstr "Supported Platforms:"
+
+#: views/developers/uploader.thtml:124
+#, fuzzy
+msgid "devcp_uploader_label_upload_field"
+msgstr "Add-on File: "
+
+#: controllers/components/developers.php:1221
+#, fuzzy
+msgid "devcp_uploader_option_other"
+msgstr "Other"
+
+#. %1$s is a number, %2$s is href="..." and should stay in the <a> tag.
+#: views/developers/uploader.thtml:176
+#, fuzzy
+msgid "devcp_uploader_p_pending_file"
+msgstr ""
+"The new file will be available to the public as soon as an editor is able to "
+"review it. There are currently %1$s other add-ons in the queue. Want to be "
+"reviewed faster? Consider <a %2$s>becoming an editor</a>."
+
+#. %1$s is a number, %2$s is href="..." and should stay in the <a> tag.
+#: views/developers/uploader.thtml:166
+#, fuzzy
+msgid "devcp_uploader_p_pending_version"
+msgstr ""
+"The new version will be available to the public as soon as an editor is able "
+"to review it. There are currently %1$s other add-ons in the queue. Want to "
+"be reviewed faster? Consider <a %2$s>becoming an editor</a>."
+
+#. %s is a status, e.g Public or Incomplete.
+#: views/developers/uploader.thtml:165
+#, fuzzy
+msgid "devcp_uploader_p_update_created"
+msgstr "Your new version has been created and is currently marked as %s."
+
+#. %1$s is href="..." and should stay in the 'Versions and Files' <a> tag.
+#. %2$s is href="..." and should stay in the 'current status' <a> tag.
+#: views/developers/uploader.thtml:177
+#, fuzzy
+msgid "devcp_uploader_p_update_file"
+msgstr ""
+"View your new file in the <a %1$s>Versions and Files page</a>, check out "
+"your add-on's <a %2$s>current status</a>, or <b>add release notes</b> by "
+"clicking the button below (highly recommended)."
+
+#. %1$s is href="..." and should stay in the 'Versions and Files' <a> tag.
+#. %2$s is href="..." and should stay in the 'current status' <a> tag.
+#: views/developers/uploader.thtml:167
+#, fuzzy
+msgid "devcp_uploader_p_update_version"
+msgstr ""
+"View your new version in the <a %1$s>Versions and Files page</a>, check out "
+"your add-on's <a %2$s>current status</a>, or <b>add release notes</b> by "
+"clicking the button below (highly recommended)."
+
+#: views/developers/uploader.thtml:118
+#, fuzzy
+msgid "devcp_uploader_p_upload"
+msgstr ""
+"Upload your add-on file using the form below. If you have multiple, platform-"
+"specific files to upload, choose a single file and then upload the others "
+"using the Versions and Files Manager."
+
+#: views/developers/uploader.thtml:125
+#, fuzzy
+msgid "devcp_uploader_platformtype_all"
+msgstr "All"
+
+#: views/developers/uploader.thtml:126
+#, fuzzy
+msgid "devcp_uploader_platformtype_specific"
+msgstr "Specific:"
+
+#. Used as first item in a <select>.
+#: controllers/components/developers.php:1185
+#, fuzzy
+msgid "devcp_uploader_please_choose"
+msgstr "Please Choose..."
+
+#. %1$s is the add-on name, %2$s is the version number.
+#: views/developers/uploader.thtml:57
+#, fuzzy
+msgid "devcp_uploader_title_file"
+msgstr "Add File to %1$s %2$s"
+
+#: views/developers/uploader.thtml:50
+#, fuzzy
+msgid "devcp_uploader_title_submit"
+msgstr "Submit New Add-on"
+
+#. %s is the add-on name.
+#: views/developers/uploader.thtml:54
+#, fuzzy
+msgid "devcp_uploader_title_update"
+msgstr "Update %s"
+
+#. %s is a full <a> tag
+#: controllers/developers_controller.php:503
+#, php-format
+msgid "devcp_valid_app_reference"
+msgstr "Lue %s."
+
+#. This is the text in the <a> tag for devcp_valid_app_reference. This should be
+#. fixed.
+#: controllers/developers_controller.php:503
+msgid "devcp_valid_app_reference_linktext"
+msgstr "lisätietoja"
+
+#: controllers/developers_controller.php:581
+#, fuzzy
+msgid "devcp_verify_author_error"
+msgstr "No account found for that email address."
+
+#: controllers/developers_controller.php:553
+#, fuzzy
+msgid "devcp_verify_search_engine_error"
+msgstr ""
+"Either the XML is invalid or required fields are missing. Please <a href="
+"\"https://developer.mozilla.org/en/Creating_OpenSearch_plugins_for_Firefox"
+"\">read the documentation</a>, verify your add-on, and try again."
+
+#: views/developers/versions.thtml:75
+#, fuzzy
+msgid "devcp_versions_a_cancel"
+msgstr "Cancel"
+
+#: views/developers/versions.thtml:79
+#, fuzzy
+msgid "devcp_versions_a_delete"
+msgstr "Delete Version"
+
+#: views/developers/versions.thtml:74
+#, fuzzy
+msgid "devcp_versions_a_empty"
+msgstr "Remove Empty Version"
+
+#: views/developers/versions.thtml:71
+#, fuzzy
+msgid "devcp_versions_a_remove"
+msgstr "Remove?"
+
+#: views/developers/versions.thtml:91
+#, fuzzy
+msgid "devcp_versions_add"
+msgstr "Add New Version"
+
+#: views/developers/versions_delete.thtml:58
+#, fuzzy
+msgid "devcp_versions_delete_a_cancel"
+msgstr "Cancel"
+
+#: views/developers/versions_delete.thtml:56
+#, fuzzy
+msgid "devcp_versions_delete_a_delete"
+msgstr "Delete Version"
+
+#. Followed by a list of reviews and files that will be removed.
+#: views/developers/versions_delete.thtml:50
+#, fuzzy
+msgid "devcp_versions_delete_also"
+msgstr "This will also delete:"
+
+#: views/developers/versions_delete.thtml:53
+#, fuzzy
+msgid "devcp_versions_delete_files"
+msgid_plural "devcp_versions_delete_files"
+msgstr[0] "%s file"
+msgstr[1] "%s files"
+
+#. %s is the version number.
+#: views/developers/versions_delete.thtml:48
+#, fuzzy
+msgid "devcp_versions_delete_header"
+msgstr "Delete Version %s?"
+
+#: views/developers/versions_delete.thtml:52
+#, fuzzy
+msgid "devcp_versions_delete_reviews"
+msgid_plural "devcp_versions_delete_reviews"
+msgstr[0] "%s review"
+msgstr[1] "%s reviews"
+
+#. %s is the version number.
+#: views/developers/versions_delete.thtml:49
+#, fuzzy
+msgid "devcp_versions_delete_sure"
+msgstr "Are you sure you want to permanently delete version %s?"
+
+#: views/developers/versions_edit.thtml:102
+#: views/developers/versions_edit.thtml:155
+#, fuzzy
+msgid "devcp_versions_edit_a_cancel"
+msgstr "Cancel"
+
+#: views/developers/versions_edit.thtml:101
+#, fuzzy
+msgid "devcp_versions_edit_a_delete"
+msgstr "Delete File"
+
+#: views/developers/versions_edit.thtml:165
+#, fuzzy
+msgid "devcp_versions_edit_a_new_app"
+msgstr "Add New Application"
+
+#: views/developers/versions_edit.thtml:154
+#, fuzzy
+msgid "devcp_versions_edit_a_remove_app"
+msgstr "Remove Application"
+
+#: views/developers/versions_edit.thtml:114
+#, fuzzy
+msgid "devcp_versions_edit_add"
+msgstr "Add New File"
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/versions_edit.thtml:121
+#, fuzzy
+msgid "devcp_versions_edit_adjust"
+msgstr ""
+"Adjusting application information here will allow users to install your add-"
+"on even if the install.rdf in the package indicates that the add-on is "
+"incompatible. <a %s>List of supported applications</a>"
+
+#: views/developers/versions_edit.thtml:153
+#, fuzzy
+msgid "devcp_versions_edit_compat_sure"
+msgstr ""
+"Are you <b>sure</b> you wish to remove compatibility with this application?"
+
+#: views/developers/versions_edit.thtml:100
+#, fuzzy
+msgid "devcp_versions_edit_delete_sure"
+msgstr "Are you <b>sure</b> you wish to permanently delete this file?"
+
+#: views/developers/versions_edit.thtml:203
+#, fuzzy
+msgid "devcp_versions_edit_header_approval"
+msgstr "Approval Information"
+
+#: views/developers/versions_edit.thtml:120
+#, fuzzy
+msgid "devcp_versions_edit_header_compat"
+msgstr "Compatible Applications"
+
+#: views/developers/versions_edit.thtml:74
+#, fuzzy
+msgid "devcp_versions_edit_header_file"
+msgstr "File Information"
+
+#: views/developers/versions_edit.thtml:189
+#, fuzzy
+msgid "devcp_versions_edit_header_license"
+msgstr "License"
+
+#. %s is the version number.
+#: views/developers/versions_edit.thtml:53
+#, fuzzy
+msgid "devcp_versions_edit_header_manage"
+msgstr "Manage Version %s"
+
+#: views/developers/versions_edit.thtml:212
+#, fuzzy
+msgid "devcp_versions_edit_header_notes"
+msgstr "Approval Notes"
+
+#: views/developers/versions_edit.thtml:98
+#, fuzzy
+msgid "devcp_versions_edit_img_delete"
+msgstr "Delete File"
+
+#. %1$s is the file id, e.g. 18723.
+#. %2$s is the platform name, e.g. ALL or Windows.
+#. %3$s is the _('date) created.
+#. %4$s is the status, e.g. "In Sandbox" or "Public".
+#. %5$s is the _('date') status was changed.
+#: views/developers/versions_edit.thtml:208
+#, fuzzy
+msgid "devcp_versions_edit_li_file"
+msgstr "File %1$s (%2$s) created on %3$s and changed to %4$s on %5$s"
+
+#: views/developers/versions_edit.thtml:190
+#, fuzzy
+msgid "devcp_versions_edit_license_description"
+msgstr ""
+"Please select the appropriate license for your add-on. This license "
+"specifies the rights you grant on your source code."
+
+#: views/developers/versions_edit.thtml:111
+#, fuzzy
+msgid "devcp_versions_edit_no_files"
+msgstr "No files found."
+
+#: views/developers/versions_edit.thtml:213
+#, fuzzy
+msgid "devcp_versions_edit_optional"
+msgstr "Optional information for the Editor that reviews this version."
+
+#: views/developers/versions_edit.thtml:151
+#, fuzzy
+msgid "devcp_versions_edit_remove_compat"
+msgstr "Remove Application Compatibility"
+
+#: views/developers/versions_edit.thtml:167
+#, fuzzy
+msgid "devcp_versions_edit_select_app"
+msgstr "Please Select an Application"
+
+#: views/developers/versions_edit.thtml:78
+#, fuzzy
+msgid "devcp_versions_edit_th_file"
+msgstr "File"
+
+#: views/developers/versions_edit.thtml:79
+#, fuzzy
+msgid "devcp_versions_edit_th_platform"
+msgstr "Platform"
+
+#: views/developers/versions_edit.thtml:80
+#, fuzzy
+msgid "devcp_versions_edit_th_size"
+msgstr "Size"
+
+#: views/developers/versions_edit.thtml:81
+#, fuzzy
+msgid "devcp_versions_edit_th_status"
+msgstr "Status"
+
+#: views/developers/versions_edit.thtml:183
+#, fuzzy
+msgid "devcp_versions_edit_transbox_releasenotes_description"
+msgstr ""
+"Information about changes in this release, new features, known bugs, and "
+"other useful information specific to this release/version. This information "
+"will also be available to users updating the add-on in the Firefox 3 Add-ons "
+"Manager interface."
+
+#: views/developers/versions_edit.thtml:182
+#, fuzzy
+msgid "devcp_versions_edit_transbox_releasenotes_name"
+msgstr "Release Notes"
+
+#: views/developers/versions_edit.thtml:164
+#, fuzzy
+msgid "devcp_versions_edit_unsaved_compat"
+msgstr ""
+"<strong>You have unsaved changes.</strong> Compatibility will not be deleted "
+"until you click Update Version below."
+
+#: views/developers/versions_edit.thtml:113
+#, fuzzy
+msgid "devcp_versions_edit_unsaved_files"
+msgstr ""
+"<strong>You have unsaved changes.</strong> Files will not be deleted until "
+"you click Update Version below."
+
+#: views/developers/versions_edit.thtml:218
+#, fuzzy
+msgid "devcp_versions_edit_update"
+msgstr "Update Versions"
+
+#: views/developers/versions.thtml:49
+#, fuzzy
+msgid "devcp_versions_header_manage"
+msgstr "Manage Versions and Files"
+
+#: views/developers/versions.thtml:87
+#, fuzzy
+msgid "devcp_versions_no_versions"
+msgstr "No versions."
+
+#. %s is a version number, base 10.
+#: views/developers/versions.thtml:46
+#, fuzzy
+msgid "devcp_versions_notice_success"
+msgstr "Version %s deleted successfully."
+
+#: views/developers/versions.thtml:73
+#, fuzzy
+msgid "devcp_versions_p_remove"
+msgstr ""
+"This version has no files associated with it and can be removed. Would you "
+"like to remove this version?"
+
+#: views/developers/versions.thtml:58
+#, fuzzy
+msgid "devcp_versions_th_created"
+msgstr "Created"
+
+#: views/developers/versions.thtml:57
+#, fuzzy
+msgid "devcp_versions_th_status"
+msgstr "Status"
+
+#: views/developers/versions.thtml:56
+#, fuzzy
+msgid "devcp_versions_th_version"
+msgstr "Version"
+
+#: controllers/downloads_controller.php:91
+msgid "downloads_disable_warning"
+msgstr "Lisäosa on poistettu käytöstä"
+
+#: controllers/components/editors.php:57
+#, fuzzy
+msgid "editor_review_error_addon_not_nominated"
+msgstr "This add-on has not been nominated."
+
+#: controllers/components/editors.php:213
+#, fuzzy
+msgid "editor_review_error_file_not_pending"
+msgstr "This file is not pending review."
+
+#. Actions are, for example: approving or rejecting
+#: controllers/components/editors.php:79
+#: controllers/components/editors.php:182
+#, fuzzy
+msgid "editor_review_error_no_action"
+msgstr "Please select a review action."
+
+#: controllers/components/editors.php:192
+#, fuzzy
+msgid "editor_review_error_no_applications"
+msgstr "Please enter the applications you tested."
+
+#. Comments are required when an editor approves or rejects an add-on.
+#: controllers/components/editors.php:84
+#: controllers/components/editors.php:187
+#, fuzzy
+msgid "editor_review_error_no_comments"
+msgstr "Please enter review comments."
+
+#: controllers/components/editors.php:161
+#, fuzzy
+msgid "editor_review_error_no_files"
+msgstr "Please select at least one file to review."
+
+#: controllers/components/editors.php:197
+#, fuzzy
+msgid "editor_review_error_no_operating_system"
+msgstr "Please enter the operating systems you tested."
+
+#: views/editors/logs.thtml:51
+msgid "editorcp_logs_button_filter"
+msgstr "Suodata"
+
+#: views/editors/logs.thtml:44
+msgid "editorcp_logs_filter_by"
+msgstr "Suodata tyypin ja toimen suhteen"
+
+#: views/editors/logs.thtml:42 controllers/editors_controller.php:964
+msgid "editorcp_logs_page_heading"
+msgstr "Tapahtumaloki"
+
+#: views/elements/developers/editorsmenu.thtml:60
+msgid "editorcp_menu_eventlog_link"
+msgstr "Tapahtumaloki"
+
+#: views/elements/developers/editorsmenu.thtml:62
+msgid "editorcp_menu_mainpage_link"
+msgstr "Palaa etusivulle"
+
+#: views/elements/developers/editorsmenu.thtml:61
+msgid "editorcp_menu_reviewlog_link"
+msgstr "Tarkastusloki"
+
+#: views/elements/developers/editorsmenu.thtml:55
+msgid "editorcp_menu_summary_link"
+msgstr "Toimittajan kuvaus"
+
+#: views/elements/developers/editorsmenu.thtml:52
+msgid "editorcp_menu_title"
+msgstr "Toimittajan työkalut"
+
+#: views/editors/reviewlog.thtml:49
+msgid "editorcp_reviewlog_button_filter"
+msgstr "Suodata"
+
+#: views/editors/reviewlog.thtml:58
+msgid "editorcp_reviewlog_column_action"
+msgstr "Toimi"
+
+#: views/editors/reviewlog.thtml:56
+msgid "editorcp_reviewlog_column_addon"
+msgstr "Lisäosa"
+
+#: views/editors/reviewlog.thtml:55
+msgid "editorcp_reviewlog_column_date"
+msgstr "Päiväys"
+
+#: views/editors/reviewlog.thtml:57
+msgid "editorcp_reviewlog_column_editor"
+msgstr "Toimittaja"
+
+#: views/editors/reviewlog.thtml:94
+msgid "editorcp_reviewlog_comments_hide"
+msgstr "Piilota kommentit"
+
+#: views/editors/reviewlog.thtml:93
+msgid "editorcp_reviewlog_comments_show"
+msgstr "Näytä kommentit"
+
+#. %1$s and %2$s are full <input> tags for dates
+#: views/editors/reviewlog.thtml:45
+#, php-format
+msgid "editorcp_reviewlog_entries_between"
+msgstr "Näytä merkinnät aikavälillä %s - %s"
+
+#: views/editors/reviewlog.thtml:104
+msgid "editorcp_reviewlog_none_found"
+msgstr "Ei tarkastuksia annetulla aikavälillä."
+
+#: views/editors/reviewlog.thtml:42
+msgid "editorcp_reviewlog_page_heading"
+msgstr "Tarkastusloki"
+
+#: views/editors/summary.thtml:61
+msgid "editorcp_summary_monthreviews_heading"
+msgstr "Tarkastuksia kuukaudessa"
+
+#: views/editors/summary.thtml:77
+msgid "editorcp_summary_neweditors_heading"
+msgstr "Uudet toimittajat"
+
+#: views/editors/summary.thtml:42
+msgid "editorcp_summary_page_heading"
+msgstr "Toimittajan kuvaus"
+
+#: views/editors/summary.thtml:94
+msgid "editorcp_summary_recentactivity_heading"
+msgstr "Toimittajan viimeaikaiset toimet"
+
+#: views/editors/summary.thtml:45
+msgid "editorcp_summary_totalreviews_heading"
+msgstr "Tarkastuksia yhteensä"
+
+#: controllers/editors_controller.php:248
+#: controllers/editors_controller.php:249
+msgid "editors_addon_review_pagetitle"
+msgstr "Tarkasta lisäosa"
+
+#: controllers/editors_controller.php:349
+msgid "editors_error_js-formerror"
+msgstr "Täytä seuraavat kentät:"
+
+#: controllers/editors_controller.php:350
+msgid "editors_error_review_one_file"
+msgstr "Valitse ainakin yksi tarkastettava tiedosto."
+
+#: controllers/editors_controller.php:274
+msgid "editors_error_self_reviews_forbidden"
+msgstr "Omia lisäosiaan ei voi tarkastaa."
+
+#: controllers/editors_controller.php:699
+msgid "editors_external_software"
+msgstr "Kolmannen osapuolen ohjelma"
+
+#: views/editors/featured.thtml:120 views/editors/featured.thtml:121
+msgid "editors_featured_add_feature"
+msgstr "Lisää ominaisuus"
+
+#: views/editors/featured.thtml:126
+msgid "editors_featured_add_feature_submit"
+msgstr "Lisää"
+
+#: views/editors/featured.thtml:49 controllers/editors_controller.php:832
+#: controllers/editors_controller.php:848
+msgid "editors_featured_addon_add_failure"
+msgstr "Ominaisuuden lisäys epäonnistui."
+
+#: controllers/editors_controller.php:851
+msgid "editors_featured_addon_add_success"
+msgstr "Ominaisuuden lisäys onnistui."
+
+#: views/editors/featured.thtml:50 controllers/editors_controller.php:839
+#: controllers/editors_controller.php:868
+#: controllers/editors_controller.php:886
+msgid "editors_featured_addon_edit_failure"
+msgstr "Ominaisuuden muokkaus ei onnistunut."
+
+#: views/editors/featured.thtml:51 controllers/editors_controller.php:888
+msgid "editors_featured_addon_edit_success"
+msgstr "Ominaisuuden muokkaus onnistui."
+
+#: views/editors/featured.thtml:53 controllers/editors_controller.php:861
+msgid "editors_featured_addon_invalid_locale"
+msgstr "Yksi tai useampi lokaali on virheellinen."
+
+#: views/editors/featured.thtml:52 controllers/editors_controller.php:906
+msgid "editors_featured_addon_remove_failure"
+msgstr "Ominaisuuden poisto ei onnistunut."
+
+#: controllers/editors_controller.php:901
+msgid "editors_featured_addon_remove_success"
+msgstr "Ominaisuuden poisto onnistui."
+
+#: controllers/editors_controller.php:915
+#: controllers/editors_controller.php:917
+msgid "editors_featured_addons_pagetitle"
+msgstr "Näytteillä olevat lisäosat"
+
+#: views/editors/featured.thtml:54 views/editors/featured.thtml:107
+msgid "editors_featured_edit_feature_submit"
+msgstr "Valmis"
+
+#: views/editors/featured.thtml:90 views/editors/featured.thtml:91
+msgid "editors_featured_remove_feature"
+msgstr "Poista ominaisuus"
+
+#: views/editors/queue.thtml:46
+msgid "editors_filter_queue"
+msgstr "Suodatettu jono"
+
+#: views/editors/queue.thtml:182
+msgid "editors_helpful_links"
+msgstr "Hyödyllisiä linkkejä"
+
+#: views/editors/queue.thtml:182
+msgid "editors_link_guide"
+msgstr "Toimittajan opas"
+
+#: views/editors/queue.thtml:182
+msgid "editors_link_policy"
+msgstr "Lisäosakäytäntö"
+
+#: views/editors/queue.thtml:47
+msgid "editors_notice_filter_session"
+msgstr "Nämä suodattimet poistuvat istunnon loputtua tai kun ne poistetaan."
+
+#. %1 is the queue mode
+#: views/editors/queue.thtml:177 views/admin/flagged_queue.thtml:89
+msgid "editors_notice_none_found"
+msgstr "Tällä hetkellä ei ole yhtään tarkastettavia %sin lisäosia."
+
+#: controllers/editors_controller.php:1040
+msgid "editors_one_day"
+msgstr "1 päivä"
+
+#: controllers/editors_controller.php:1048
+msgid "editors_one_hour"
+msgstr "1 tunti"
+
+#: controllers/editors_controller.php:1056
+msgid "editors_one_minute"
+msgstr "1 minuutti"
+
+#: controllers/editors_controller.php:64 controllers/editors_controller.php:73
+#: controllers/editors_controller.php:77
+msgid "editors_pagetitle"
+msgstr "Toimittajan ohjauspaneeli"
+
+#. %s is a comma separated list of platforms. Example: Windows, OS X
+#: controllers/editors_controller.php:680
+#: controllers/editors_controller.php:683
+#, php-format
+msgid "editors_platform_x_only"
+msgstr "Vain %s"
+
+#: controllers/editors_controller.php:695
+msgid "editors_pre-release"
+msgstr "Esijulkaisu"
+
+#. %1 is the app name
+#: views/editors/queue.thtml:131
+#, php-format
+msgid "editors_queue_app_compatibility"
+msgstr "%s yhteensopivuus"
+
+#: views/editors/queue.thtml:51
+#, fuzzy
+msgid "editors_queue_filter_label_addon"
+msgstr "Add-on or Author Email"
+
+#: views/editors/queue.thtml:72
+#, fuzzy
+msgid "editors_queue_filter_label_addontypes"
+msgstr "Add-on Types"
+
+#: views/editors/queue.thtml:56
+#, fuzzy
+msgid "editors_queue_filter_label_application"
+msgstr "Application"
+
+#: views/editors/queue.thtml:61
+#, fuzzy
+msgid "editors_queue_filter_label_maxversion"
+msgstr "Max. Version"
+
+#: views/editors/queue.thtml:78
+#, fuzzy
+msgid "editors_queue_filter_label_platforms"
+msgstr "Platforms"
+
+#: views/editors/queue.thtml:66
+#, fuzzy
+msgid "editors_queue_filter_label_submissionage"
+msgstr "Age of Submission (days)"
+
+#. %1$s is a number
+#: views/editors/queue.thtml:90
+#, fuzzy
+msgid "editors_queue_filter_result_count"
+msgid_plural "editors_queue_filter_result_count"
+msgstr[0] "Results of your filtered search: <strong>%1$s</strong> Add-on"
+msgstr[1] "Results of your filtered search: <strong>%1$s</strong> Add-ons"
+
+#: views/editors/queue.thtml:84
+msgid "editors_queue_submit_clean"
+msgstr "Tyhjennä"
+
+#: views/editors/queue.thtml:83
+msgid "editors_queue_submit_filter"
+msgstr "Suodatin"
+
+#: controllers/editors_controller.php:133
+msgid "editors_queues_disabled"
+msgstr "Kaikki tarkastusjonot ovat pois päältä. Yritä myöhemmin uudestaan."
+
+#: views/editors/review.thtml:149
+#, fuzzy
+msgid "editors_review_a_edit_item"
+msgstr "Edit Item"
+
+#: views/editors/review.thtml:146
+#, fuzzy
+msgid "editors_review_a_item_history"
+msgstr "Item History"
+
+#: views/editors/review.thtml:148
+#, fuzzy
+msgid "editors_review_a_item_homepage"
+msgstr "Item Homepage"
+
+#: views/editors/review.thtml:145
+#, fuzzy
+msgid "editors_review_a_item_overview"
+msgstr "Item Overview"
+
+#: views/editors/review.thtml:147
+#, fuzzy
+msgid "editors_review_a_previews"
+msgstr "Previews"
+
+#: controllers/editors_controller.php:345
+msgid "editors_review_action"
+msgstr "Tarkastustoimi"
+
+#: views/editors/review.thtml:159
+#, fuzzy
+msgid "editors_review_action_info"
+msgstr "Request More Information"
+
+#: views/editors/review.thtml:157
+msgid "editors_review_action_public"
+msgstr "Siirrä julkiselle puolelle"
+
+#: views/editors/review.thtml:160
+msgid "editors_review_action_request_superreview"
+msgstr "Pyydä Super-Review"
+
+#: views/editors/review.thtml:158
+msgid "editors_review_action_sandbox"
+msgstr "Säilytä hiekkalaatikossa"
+
+#: controllers/editors_controller.php:346
+msgid "editors_review_comments"
+msgstr "Tarkastuskommentit"
+
+#: views/editors/review.thtml:182
+#, fuzzy
+msgid "editors_review_details_info_request"
+msgstr ""
+"Use this form to request more information from the author. They will receive "
+"an email and be able to answer here. You will be notified by email when they "
+"reply."
+
+#: views/editors/review.thtml:174
+msgid "editors_review_details_nominated_public"
+msgstr ""
+"Tämä valinta merkitsee lisäosan ja sen tiedostojen uusimmat versiot "
+"julkiseksi. Tulevat versiot jäävät odottomaan tarkastusta hiekkalaatikkoon."
+
+#: views/editors/review.thtml:177
+msgid "editors_review_details_nominated_sandbox"
+msgstr "Tämä valinta jättää lisäosan hiekkalaatikkoon."
+
+#: views/editors/review.thtml:166
+msgid "editors_review_details_pending_public"
+msgstr ""
+"Tämä valinta hyväksyy hiekkalaatikossa olevan uuden version julkisella "
+"puolella olevasta lisäosasta."
+
+#: views/editors/review.thtml:169
+msgid "editors_review_details_pending_sandbox"
+msgstr ""
+"Tämä valinta jättää hiekkalaatikossa olevan uuden version julkisella "
+"puolella olevasta lisäosasta hiekkalaatikkoon."
+
+#: views/editors/review.thtml:185
+msgid "editors_review_details_superreview"
+msgstr ""
+"Jos uskot, että ylläpitäjän tulisi tarkistaa tämä lisäosa turvallisuus-, "
+"tekijänoikeus- tai muiden ongelmien takia, kirjoita tästä kommentteihin "
+"alle. Kommentteja ei lähetetä lisäosan tekijälle vaan vain ylläpidolle."
+
+#: views/editors/review.thtml:134
+#, fuzzy
+msgid "editors_review_file_diff_link"
+msgstr "Compare with public version"
+
+#: views/editors/review.thtml:131
+msgid "editors_review_file_viewcontents_link"
+msgstr "Näytä sisältö"
+
+#: views/editors/review.thtml:65
+msgid "editors_review_header_authors"
+msgstr "Tekijät:"
+
+#: views/editors/review.thtml:79
+msgid "editors_review_header_categories"
+msgstr "Luokat:"
+
+#: views/editors/review.thtml:92
+msgid "editors_review_header_compatibility"
+msgstr "Yhteensopivuus:"
+
+#: views/editors/review.thtml:251
+msgid "editors_review_header_description"
+msgstr "Kuvaus"
+
+#: views/editors/review.thtml:275
+msgid "editors_review_header_devcomments"
+msgstr "Kehittäjän kommentit"
+
+#: views/editors/review.thtml:263
+msgid "editors_review_header_eula"
+msgstr "EULA"
+
+#: views/editors/review.thtml:115
+msgid "editors_review_header_files"
+msgstr "Tiedostot:"
+
+#: views/editors/review.thtml:284
+msgid "editors_review_header_itemhistory"
+msgstr "Kohteen historia"
+
+#: views/editors/review.thtml:232
+msgid "editors_review_header_nominationmessage"
+msgstr "Viesti ehdolle asettamista"
+
+#: views/editors/review.thtml:311
+msgid "editors_review_header_previews"
+msgstr "Esikatselukuvat"
+
+#: views/editors/review.thtml:269
+msgid "editors_review_header_privacy"
+msgstr "Tietosuojakäytäntö"
+
+#. %1 is the add-on name and version
+#: views/editors/review.thtml:56
+#, php-format
+msgid "editors_review_header_review"
+msgstr "Tarkasta %s"
+
+#: views/editors/review.thtml:239
+msgid "editors_review_header_reviewernotes"
+msgstr "Kommentit tarkastajalle"
+
+#: views/editors/review.thtml:245
+msgid "editors_review_header_summary"
+msgstr "Yhteenveto"
+
+#: views/editors/review.thtml:257
+msgid "editors_review_header_versionnotes"
+msgstr "Versiokommentit"
+
+#. a noun: shown in an add-on's editor review history
+#: views/elements/developers/editors_review_history_item.thtml:80
+#, fuzzy
+msgid "editors_review_history_info_reply"
+msgstr "Reply"
+
+#: views/elements/developers/editors_review_history_item.thtml:78
+#, fuzzy
+msgid "editors_review_history_info_request"
+msgstr "Information Request"
+
+#: views/elements/developers/editors_review_history_item.thtml:62
+#: views/editors/reviewlog.thtml:77
+msgid "editors_review_history_nominated_adminreview"
+msgstr "Ylläpidon tarkastus"
+
+#: views/elements/developers/editors_review_history_item.thtml:56
+#: views/editors/reviewlog.thtml:71
+msgid "editors_review_history_nominated_approved"
+msgstr "Ehdotus hyväksytty/julkinen"
+
+#: views/elements/developers/editors_review_history_item.thtml:59
+#: views/editors/reviewlog.thtml:74
+msgid "editors_review_history_nominated_denied"
+msgstr "Ehdotus hylätty/hiekkalaatikko"
+
+#: views/editors/review.thtml:303
+msgid "editors_review_history_nonefound"
+msgstr "Aikaisempia tarkastusmerkintöjä ei löytynyt."
+
+#: views/elements/developers/editors_review_history_item.thtml:73
+#: views/editors/reviewlog.thtml:88
+msgid "editors_review_history_pending_adminreview"
+msgstr "Ylläpidon tarkastus"
+
+#: views/elements/developers/editors_review_history_item.thtml:67
+#: views/editors/reviewlog.thtml:82
+msgid "editors_review_history_pending_approved"
+msgstr "Hyväksytty/julkinen"
+
+#: views/elements/developers/editors_review_history_item.thtml:70
+#: views/editors/reviewlog.thtml:85
+msgid "editors_review_history_pending_denied"
+msgstr "Hylätty/hiekkalaatikko"
+
+#. link text in an add-on's editor review history, allowing to hide and show an information request's replies
+#. %1 is the number of replies
+#: views/elements/developers/editors_review_history_item.thtml:90
+#, fuzzy
+msgid "editors_review_history_show_hide_replies"
+msgid_plural "editors_review_history_show_hide_replies"
+msgstr[0] "Show/Hide Replies (%1$s)"
+msgstr[1] "Show/Hide Replies (%1$s)"
+
+#: views/editors/review.thtml:208
+msgid "editors_review_label_applications"
+msgstr "Ohjelmat:"
+
+#: views/editors/review.thtml:196
+msgid "editors_review_label_cannedresponse"
+msgstr "tai valitse evätty vastaus:"
+
+#: views/editors/review.thtml:190
+msgid "editors_review_label_comments"
+msgstr "Kommentit:"
+
+#: views/editors/review.thtml:204
+msgid "editors_review_label_operating_systems"
+msgstr "Käyttöjärjestelmät:"
+
+#: views/editors/review.thtml:285 views/editors/review.thtml:312
+msgid "editors_review_link_pagetop"
+msgstr "Alkuun"
+
+#: views/editors/review.thtml:141
+#, fuzzy
+msgid "editors_review_mulitple_notice"
+msgstr ""
+"Notice: Only review more than one file if you have tested EVERY file you "
+"select."
+
+#: views/editors/review.thtml:51
+#, fuzzy
+msgid "editors_review_next_link"
+msgstr "next &raquo;"
+
+#: views/editors/review.thtml:322
+msgid "editors_review_previews_notfound"
+msgstr "Esikatselukuvia ei löytynyt."
+
+#: views/editors/review.thtml:50
+#, fuzzy
+msgid "editors_review_previous_link"
+msgstr "&laquo; prev"
+
+#: controllers/editors_controller.php:144
+#: controllers/editors_controller.php:146
+msgid "editors_review_queue_pagetitle"
+msgstr "Tarkastusjono"
+
+#. %1 is the add-ons rank in the queue, %2 is the total queue length
+#: views/editors/review.thtml:47
+#, fuzzy
+msgid "editors_review_rank_in_queue"
+msgstr "<strong># %1$s</strong> of %2$s in queue"
+
+#. %1 is the add-ons rank in the queue, %2 is the total queue length. Both numbers
+#: views/editors/review.thtml:45
+#, fuzzy
+msgid "editors_review_rank_in_queue_filtered"
+msgstr "<strong># %1$s</strong> of %2$s in queue (filtered)"
+
+#: views/editors/review.thtml:223
+msgid "editors_review_submit_process_action"
+msgstr "Käsittele toiminnot"
+
+#: views/editors/review.thtml:293
+msgid "editors_review_th_action"
+msgstr "Toiminto"
+
+#: views/editors/review.thtml:294
+msgid "editors_review_th_comments"
+msgstr "Kommentit"
+
+#: views/editors/review.thtml:291
+msgid "editors_review_th_date"
+msgstr "Päiväys"
+
+#: views/editors/review.thtml:292
+msgid "editors_review_th_reviewer"
+msgstr "Arvostelija"
+
+#: views/editors/review.thtml:290
+msgid "editors_review_th_version_file"
+msgstr "Versio/tiedosto"
+
+#: views/editors/review.thtml:217
+#, fuzzy
+msgid "editors_review_update_notify_once"
+msgstr ""
+"Notify me the next time this add-on is updated. (Subsequent updates will not "
+"generate an email)"
+
+#: controllers/editors_controller.php:298
+msgid "editors_reviewed_successfully"
+msgstr "Arvostelu käsiteltiin."
+
+#: views/editors/reviews_queue.thtml:106
+#, fuzzy
+msgid "editors_reviews_action_delete_review"
+msgstr "Delete review"
+
+#: views/editors/reviews_queue.thtml:104
+#, fuzzy
+msgid "editors_reviews_action_keep"
+msgstr "Remove flags; keep review"
+
+#: views/editors/reviews_queue.thtml:102
+msgid "editors_reviews_action_skip"
+msgstr "Ohita"
+
+#: views/editors/reviews_queue.thtml:100
+msgid "editors_reviews_header_action"
+msgstr "Toiminto"
+
+#: views/editors/reviews_queue.thtml:67
+msgid "editors_reviews_in_reply_to"
+msgstr "Vastauksena kysymykseen:"
+
+#: controllers/editors_controller.php:748
+msgid "editors_reviews_processed"
+msgstr "Arvostelut käsiteltiin."
+
+#: views/editors/reviews_queue.thtml:117
+msgid "editors_reviews_queue_empty"
+msgstr "Yhtäkään arvostelua ei ole tarkistettavana."
+
+#: views/editors/reviews_queue.thtml:111
+msgid "editors_reviews_submit_process_reviews"
+msgstr "Käsittele arvostelut"
+
+#: controllers/editors_controller.php:691
+msgid "editors_site_specific"
+msgstr "Sivustokohtainen"
+
+#: controllers/editors_controller.php:348
+msgid "editors_tested_app"
+msgstr "Testattu ohjelma"
+
+#: controllers/editors_controller.php:347
+msgid "editors_tested_os"
+msgstr "Testatut käyttöjärjestelmät"
+
+#: views/editors/queue.thtml:151
+msgid "editors_th_additional_info"
+msgstr "Lisätietoja"
+
+#: views/editors/featured.thtml:63 views/editors/queue.thtml:109
+#: views/admin/flagged_queue.thtml:53
+msgid "editors_th_addon"
+msgstr "Lisäosa"
+
+#: views/editors/queue.thtml:125
+msgid "editors_th_addontype"
+msgstr "Tyyppi"
+
+#: views/editors/featured.thtml:64
+msgid "editors_th_locales"
+msgstr "Rajoitetaanko lokaaleihin?"
+
+#: views/editors/queue.thtml:148
+#, fuzzy
+msgid "editors_th_nomination_age"
+msgstr "Time in Queue"
+
+#: views/editors/queue.thtml:101 views/editors/queue.thtml:117
+#: views/editors/queue.thtml:144
+#, fuzzy
+msgid "editors_th_sort_ascending"
+msgstr "Ascending sort"
+
+#: views/editors/queue.thtml:105 views/editors/queue.thtml:121
+#: views/editors/queue.thtml:140
+#, fuzzy
+msgid "editors_th_sort_descending"
+msgstr "Descending sort"
+
+#. %s is a number
+#: controllers/editors_controller.php:1036
+#, php-format
+msgid "editors_x_days"
+msgstr "%s päivää"
+
+#. %s is a number
+#: controllers/editors_controller.php:1044
+#, php-format
+msgid "editors_x_hours"
+msgstr "%s tuntia"
+
+#. %s is a number
+#: controllers/editors_controller.php:1052
+#, php-format
+msgid "editors_x_minutes"
+msgstr "%s minuuttia"
+
+#: views/errors/error401.thtml:50 controllers/components/simple_acl.php:81
+#: controllers/components/simple_acl.php:82
+#: controllers/components/simple_acl.php:83 controllers/components/amo.php:607
+#: controllers/components/amo.php:608 controllers/components/amo.php:609
+#: controllers/reviews_controller.php:353
+#: controllers/reviews_controller.php:485
+#: controllers/collections_controller.php:438
+#: controllers/collections_controller.php:496
+#: controllers/collections_controller.php:504
+#: controllers/collections_controller.php:971
+#: controllers/collections_controller.php:1034
+#: controllers/collections_controller.php:1077
+msgid "error_access_denied"
+msgstr "Yhteys estetty"
+
+#: views/errors/error401.thtml:52
+msgid "error_access_denied_message"
+msgstr "Sinulla ei ole oikeutta avata sivua."
+
+#: controllers/collections_controller.php:1039
+#, fuzzy
+msgid "error_addon_exists"
+msgstr "Add-on already exists!"
+
+#: controllers/developers_controller.php:200
+#: controllers/developers_controller.php:593
+#: controllers/developers_controller.php:1016
+#: controllers/developers_controller.php:1429
+#: controllers/downloads_controller.php:95
+#: controllers/downloads_controller.php:102
+#: controllers/downloads_controller.php:164
+#: controllers/statistics_controller.php:135
+#: controllers/previews_controller.php:115
+#: controllers/previews_controller.php:206
+#: controllers/previews_controller.php:307
+#: controllers/reviews_controller.php:77
+#: controllers/reviews_controller.php:240
+#: controllers/reviews_controller.php:332
+#: controllers/reviews_controller.php:340 controllers/api_controller.php:123
+#: controllers/api_controller.php:759 controllers/addons_controller.php:131
+#: controllers/addons_controller.php:197
+#: controllers/addons_controller.php:1407
+#: controllers/addons_controller.php:1465
+#: controllers/addons_controller.php:1469
+#: controllers/addons_controller.php:1503
+#: controllers/editors_controller.php:265
+#: controllers/collections_controller.php:1041
+#: controllers/collections_controller.php:1074
+msgid "error_addon_notfound"
+msgstr "Lisäosaa ei löytynyt."
+
+#: controllers/files_controller.php:83 controllers/files_controller.php:196
+msgid "error_addon_notviewable"
+msgstr "Lisäosa ei ole esillä täällä."
+
+#: controllers/reviews_controller.php:246
+#, fuzzy
+msgid "error_addon_selfreview"
+msgstr "You cannot review your own add-on."
+
+#: controllers/addons_controller.php:970
+msgid "error_browse_no_addons"
+msgstr "Tässä luokassa ei ole lisäosia."
+
+#: controllers/api_controller.php:424
+#, fuzzy
+msgid "error_collection_feed_notfound"
+msgstr "Add-on feed not found."
+
+#: views/users/register.thtml:65 views/users/edit.thtml:194
+msgid "error_email_invalid"
+msgstr "Tämä sähköpostiosoite on virheellinen."
+
+#: views/users/pwreset.thtml:74 views/users/register.thtml:70
+#: views/users/register.thtml:80 views/users/register.thtml:86
+#: views/users/edit.thtml:105 views/users/edit.thtml:111
+#: views/users/edit.thtml:192 views/admin/users_edit.thtml:78
+#: views/admin/users_edit.thtml:83 views/reviews/add.thtml:80
+#: views/reviews/add.thtml:104
+msgid "error_field_required"
+msgstr "Tämä kenttä ei voi olla tyhjä."
+
+#: controllers/files_controller.php:75 controllers/files_controller.php:93
+#: controllers/files_controller.php:96 controllers/files_controller.php:163
+#: controllers/files_controller.php:176 controllers/files_controller.php:185
+#: controllers/files_controller.php:204 controllers/editors_controller.php:412
+msgid "error_file_notfound"
+msgstr "Tiedostoa ei löytynyt."
+
+#. %s is a filename
+#: controllers/editors_controller.php:430
+#, php-format
+msgid "error_file_x_notfound"
+msgstr "Tiedostovirhe: %s ei ole olemassa."
+
+#: views/collections/add.thtml:55 views/collections/edit.thtml:89
+#: views/users/register.thtml:54 views/users/edit.thtml:81
+#: views/reviews/add.thtml:70 controllers/groups_controller.php:80
+#: controllers/groups_controller.php:102
+msgid "error_formerrors"
+msgstr "Lomakkeessa on virheitä. Korjaa virheet ja lähetä lomake uudestaan."
+
+#: views/users/register.thtml:109
+#, fuzzy
+msgid "error_invalid_captcha"
+msgstr "Invalid captcha, please try again!"
+
+#: views/users/register.thtml:100 views/users/edit.thtml:125
+#: views/admin/users_edit.thtml:101
+msgid "error_invalid_url"
+msgstr ""
+"URL:n muoto on virheellinen. Oikean muotoiset URL:it ovat muotoa http://"
+"esimerkki.com/jokusivu."
+
+#. %s is a string representing what's missing. Example: file_id
+#: controllers/downloads_controller.php:65
+#: controllers/users_controller.php:185 controllers/users_controller.php:264
+#: controllers/users_controller.php:559 controllers/users_controller.php:653
+#: controllers/reviews_controller.php:71
+#: controllers/reviews_controller.php:234
+#: controllers/reviews_controller.php:325
+#: controllers/reviews_controller.php:473
+#: controllers/reviews_controller.php:475
+#: controllers/addons_controller.php:182
+#: controllers/addons_controller.php:1381
+#: controllers/addons_controller.php:1455
+#: controllers/collections_controller.php:266
+#: controllers/collections_controller.php:285
+#: controllers/collections_controller.php:346
+#: controllers/collections_controller.php:443
+#: controllers/collections_controller.php:482
+#: controllers/collections_controller.php:936
+#: controllers/collections_controller.php:959
+#: controllers/collections_controller.php:960
+#: controllers/collections_controller.php:975
+#: controllers/collections_controller.php:977
+#: controllers/collections_controller.php:994
+#: controllers/collections_controller.php:1003
+#: controllers/collections_controller.php:1016
+#: controllers/collections_controller.php:1017
+#: controllers/collections_controller.php:1024
+#: controllers/collections_controller.php:1070
+#: controllers/collections_controller.php:1090
+#, php-format
+msgid "error_missing_argument"
+msgstr "Valinta puuttuu: %s"
+
+#: controllers/components/amo.php:507 controllers/components/amo.php:532
+#, fuzzy
+msgid "error_no_files_in_addon"
+msgstr "No Files"
+
+#: controllers/previews_controller.php:200
+msgid "error_preview_notfound"
+msgstr "Esikatselukuvaa ei löytynyt."
+
+#: views/addons/display.thtml:400 views/reviews/add.thtml:98
+#, fuzzy
+msgid "error_review_rating_required"
+msgstr "You must select a rating."
+
+#: controllers/users_controller.php:160
+msgid "error_user_already_confirmed"
+msgstr "Käyttäjätili on jo varmistettu."
+
+#: controllers/users_controller.php:202 controllers/users_controller.php:276
+#: controllers/users_controller.php:569 controllers/users_controller.php:581
+#: controllers/users_controller.php:587 controllers/users_controller.php:610
+#: controllers/users_controller.php:627
+msgid "error_user_badconfirmationcode"
+msgstr "Virheellinen varmistuskoodi!"
+
+#: views/users/pwreset.thtml:79 views/users/register.thtml:75
+#: views/users/edit.thtml:183
+msgid "error_user_confirmpw_nomatch"
+msgstr "Salasanat eivät täsmää."
+
+#: views/users/register.thtml:65 views/users/edit.thtml:190
+#: controllers/users_controller.php:617
+msgid "error_user_email_notunique"
+msgstr "Sähköpostiosoite on jo toisen käyttäjätunnuksen varaama."
+
+#: controllers/users_controller.php:596
+#, fuzzy
+msgid "error_user_emailchange_expired"
+msgstr ""
+"The email change has expired. Please change your email address again in your "
+"user profile and click the link in the confirmation email as soon as you "
+"receive it."
+
+#: controllers/collections_controller.php:985
+#, fuzzy
+msgid "error_user_exists"
+msgstr ""
+"Users can only have one role at a time. Please remove the user from any "
+"existing roles before continuing."
+
+#: views/users/register.thtml:91 views/users/edit.thtml:116
+#: views/admin/users_edit.thtml:88
+msgid "error_user_nickname_notunique"
+msgstr "Käyttäjätunnus on jo varattu."
+
+#: views/users/pwreset.thtml:54 controllers/users_controller.php:191
+#: controllers/users_controller.php:270 controllers/users_controller.php:603
+#: controllers/users_controller.php:659
+#: controllers/collections_controller.php:988
+#: controllers/collections_controller.php:998
+msgid "error_user_notfound"
+msgstr "Käyttäjää ei löytynyt."
+
+#: views/users/activatefirst.thtml:47
+msgid "error_user_unconfirmed"
+msgstr "Varmista käyttäjätilisi koodilla, jonka sait sähköpostitse."
+
+#: views/users/login.thtml:67
+msgid "error_username_or_pw_wrong"
+msgstr "Virheellinen käyttäjätunnus tai salasana."
+
+#: controllers/editors_controller.php:260
+msgid "error_version_notfound"
+msgstr "Versiota ei löytynyt."
+
+#: views/users/delete.thtml:125 views/users/edit.thtml:173
+msgid "error_wrong_password"
+msgstr "Virheellinen salasana."
+
+#: views/elements/amo2009/homepage_addon.thtml:122
+#: views/elements/feature.thtml:122
+msgid "feature_learnmore"
+msgstr "Lue lisää"
+
+#. %1 is the add-on name
+#: views/elements/amo2009/homepage_addon.thtml:123
+#: views/elements/feature.thtml:123
+#, php-format
+msgid "feature_learnmore_about_addon"
+msgstr "Lue lisää lisäosasta %1$s"
+
+#. %1$s is a number
+#: views/elements/amo2009/reviews.thtml:52
+#: views/elements/addon_listitem.thtml:112 views/elements/feature.thtml:99
+#: views/addons/browse_thumbs.thtml:86
+#, php-format
+msgid "feature_reviews"
+msgid_plural "feature_reviews"
+msgstr[0] "arvostelu"
+msgstr[1] "arvostelua"
+
+#: views/elements/amo2009/homepage_addon.thtml:127
+#: views/elements/feature.thtml:127
+msgid "feature_view_more_from_category"
+msgstr "Näytä lisää luokasta"
+
+#. This appears on a page that views the source of an add-on. This link will return
+#. the user to the add-on's main page
+#: views/files/browse.thtml:65
+#, fuzzy
+msgid "file_browser_link_addon"
+msgstr "Back to add-on"
+
+#. There is a list of directories and files on the page. Clicking this will show the
+#. contents of all the directories (normally you would click on each one to see the
+#. contents)
+#: views/files/browse.thtml:67
+#, fuzzy
+msgid "file_browser_link_expand_all"
+msgstr "Expand all"
+
+#. This appears on a page that views the source of an add-on. This link will return
+#. the user to the add-on's review page (it only appears if the add-on is being
+#. reviewed)
+#: views/files/browse.thtml:64
+#, fuzzy
+msgid "file_browser_link_review"
+msgstr "Back to review"
+
+#. The title of the page for viewing an add-on's source.
+#. %1$s is the name of the add-on
+#. %2$s is the name of the current application (e.g. Firefox or Thunderbird)
+#: views/files/browse.thtml:46
+#, fuzzy
+msgid "file_browser_title"
+msgstr "%1$s :: File Browser :: %2$s Add-ons"
+
+#. This appears on a page that views the source of an add-on. There is a list of
+#. directories and files on the page. Clicking this link will toggle between an
+#. expanded or a collapsed list. This string should be kept short.
+#: views/files/browse.thtml:68
+#, fuzzy
+msgid "file_browser_toggle_expand_collapse"
+msgstr "+/-"
+
+#. Link text for the AMO About page.
+#: views/elements/footer.thtml:72 views/layouts/amo2009.thtml:341
+#, fuzzy
+msgid "footer_a_about"
+msgstr "About"
+
+#. Link text to the AMO blog.
+#: views/elements/footer.thtml:74 views/layouts/amo2009.thtml:343
+#, fuzzy
+msgid "footer_a_blog"
+msgstr "Blog"
+
+#. Link text to the Frequently Asked Questions page.
+#: views/elements/footer.thtml:73 views/layouts/amo2009.thtml:342
+#, fuzzy
+msgid "footer_a_faq"
+msgstr "FAQ"
+
+#. Full text for the FAQ abbreviation.
+#: views/elements/footer.thtml:73 views/pages/collector_features.thtml:72
+#: views/layouts/amo2009.thtml:342
+#, fuzzy
+msgid "footer_abbr_faq"
+msgstr "Frequently Asked Questions"
+
+#: views/elements/footer.thtml:67 views/layouts/amo2009.thtml:336
+msgid "footer_all_rights_reserved"
+msgstr "Kaikki oikeudet pidätetään."
+
+#: views/elements/footer.thtml:67 views/layouts/amo2009.thtml:336
+msgid "footer_copyright"
+msgstr "Tekijänoikeudet"
+
+#: views/elements/footer.thtml:71 views/layouts/amo2009.thtml:340
+msgid "footer_credits"
+msgstr "Tekijät"
+
+#: views/elements/footer.thtml:76 views/layouts/amo2009.thtml:346
+msgid "footer_disclaimer"
+msgstr ""
+"Mozilla tarjoaa linkit näihin ohjelmiin hyvässä tahdossa eikä vastaa "
+"ohjelmista tai niistä esitetyistä tiedoista. Kaikki kysymykset, valitukset "
+"ja vaatimukset ohjelmista tulee osoittaa kyseisen ohjelman tekijälle."
+
+#: views/elements/footer.thtml:61 views/layouts/amo2009.thtml:332
+msgid "footer_lang_form_lang_submit_go"
+msgstr "Siirry"
+
+#: views/elements/footer.thtml:70 views/layouts/amo2009.thtml:339
+msgid "footer_legal_notices"
+msgstr "Lakipykälät"
+
+#: views/elements/footer.thtml:50 views/layouts/amo2009.thtml:321
+msgid "footer_other_languages"
+msgstr "Muut kielet:"
+
+#: views/elements/footer.thtml:69 views/layouts/amo2009.thtml:338
+msgid "footer_privacy_policy"
+msgstr "Tietosuojakäytäntö"
+
+#: models/addontype.php:79
+msgid "general_addontype_dict"
+msgstr "Oikolukusanasto"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:100
+msgid "general_addontype_dict_plural"
+msgstr "Oikolukusanastot"
+
+#: models/addontype.php:75
+msgid "general_addontype_extension"
+msgstr "Laajennus"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:98
+msgid "general_addontype_extension_plural"
+msgstr "Laajennukset"
+
+#: models/addontype.php:85
+msgid "general_addontype_lpaddon"
+msgstr "Kielipaketti (lisäosan)"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:103
+msgid "general_addontype_lpaddon_plural"
+msgstr "Kielipaketit (lisäosan)"
+
+#: models/addontype.php:83
+msgid "general_addontype_lpapp"
+msgstr "Kielipaketti (ohjelman)"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:102
+msgid "general_addontype_lpapp_plural"
+msgstr "Kielipaketit (ohjelman)"
+
+#: models/addontype.php:87
+msgid "general_addontype_plugin"
+msgstr "Liitännäinen"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:104
+msgid "general_addontype_plugin_plural"
+msgstr "Liitännäiset"
+
+#: models/addontype.php:81
+msgid "general_addontype_search"
+msgstr "Hakukone"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:101
+msgid "general_addontype_search_plural"
+msgstr "Hakukoneet"
+
+#: models/addontype.php:77
+msgid "general_addontype_theme"
+msgstr "Teema"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:99
+msgid "general_addontype_theme_plural"
+msgstr "Teemat"
+
+#: config/language.php:367
+#, fuzzy
+msgid "general_languages_all_locales"
+msgstr "All Locales"
+
+#: views/layouts/amo2009.thtml:249
+#, fuzzy
+msgid "header_brand_name"
+msgstr "Mozilla"
+
+#. %1$s is the application name. Example: Firefox
+#: views/elements/header.thtml:111 views/elements/header.thtml:122
+#: views/layouts/amo2009.thtml:248
+#, php-format
+msgid "header_home_tooltip"
+msgstr "Palaa lisäosan %1$s kotisivulle"
+
+#: views/elements/header.thtml:87
+msgid "header_main_firefox_header"
+msgstr "Firefoxin lisäosat"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:218
+#, fuzzy
+msgid "header_main_firefox_header_with_logo"
+msgstr ""
+"Add-ons <em>for</em> <img alt=\"Firefox\" src=\"%1$s\" /> <strong>Firefox</"
+"strong>"
+
+#: views/elements/header.thtml:99
+msgid "header_main_header"
+msgstr "lisäosat"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:242
+#, fuzzy
+msgid "header_main_header_with_logo"
+msgstr "Add-ons <img alt=\"Add-ons\" src=\"%1$s\" />"
+
+#: views/elements/header.thtml:90
+msgid "header_main_seamonkey_header"
+msgstr "Seamonkeyn lisäosat"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:224
+#, fuzzy
+msgid "header_main_seamonkey_header_with_logo"
+msgstr ""
+"Add-ons <em>for</em> <img alt=\"seamonkey\" src=\"%1$s\" /> "
+"<strong>SeaMonkey</strong>"
+
+#: views/elements/header.thtml:93
+msgid "header_main_sunbird_header"
+msgstr "Sunbirdin lisäosat"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:230
+#, fuzzy
+msgid "header_main_sunbird_header_with_logo"
+msgstr ""
+"Add-ons <em>for</em> <img alt=\"sunbird\" src=\"%1$s\" /> <strong>Sunbird</"
+"strong>"
+
+#: views/elements/header.thtml:96
+msgid "header_main_thunderbird_header"
+msgstr "Thunderbirdin lisäosat"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:236
+#, fuzzy
+msgid "header_main_thunderbird_header_with_logo"
+msgstr ""
+"Add-ons <em>for</em> <img alt=\"thunderbird\" src=\"%1$s\" /> "
+"<strong>Thunderbird</strong>"
+
+#: views/layouts/amo2009.thtml:205
+#, fuzzy
+msgid "header_navaccess_applications_menu"
+msgstr "Skip to other applications menu"
+
+#: views/layouts/amo2009.thtml:204
+#, fuzzy
+msgid "header_navaccess_categories_menu"
+msgstr "Skip to categories menu"
+
+#: views/layouts/amo2009.thtml:202
+#, fuzzy
+msgid "header_navaccess_main_content"
+msgstr "Skip to main content"
+
+#: views/layouts/amo2009.thtml:203
+#, fuzzy
+msgid "header_navaccess_search_form"
+msgstr "Skip to search form"
+
+#: views/elements/header.thtml:62
+msgid "header_navlink_addons"
+msgstr "Lisäosat"
+
+#: views/elements/developers/sidebar.thtml:72
+#: views/elements/developers/myaddons.thtml:50 views/elements/header.thtml:159
+#: views/addons/display.thtml:378
+msgid "header_navlink_login"
+msgstr "Kirjaudu sisään"
+
+#: views/elements/header.thtml:156 views/layouts/amo2009.thtml:304
+msgid "header_navlink_logout"
+msgstr "Kirjaudu ulos"
+
+#: views/elements/header.thtml:145 views/layouts/amo2009.thtml:303
+msgid "header_navlink_myaccount"
+msgstr "Tilini"
+
+#: views/elements/header.thtml:158
+msgid "header_navlink_register"
+msgstr "Rekisteröidy"
+
+#. %1 is the URL to the registration page
+#. %2 is the URL to the login page
+#: views/layouts/amo2009.thtml:278
+#, fuzzy
+msgid "header_navlink_register_or_login"
+msgstr "<a href=\"%1$s\">Register</a> or <a href=\"%2$s\">Log in</a>"
+
+#: views/layouts/amo2009.thtml:285
+#, fuzzy
+msgid "header_navlink_tools"
+msgstr "Tools"
+
+#. %s is the add-on name
+#: views/elements/collections_interactive_addon.thtml:62
+#: views/elements/amo2009/homepage_addon.thtml:77
+#: views/elements/addon_discussionheader.thtml:62
+#: views/elements/addon_listitem.thtml:67 views/elements/feature.thtml:84
+#: views/addons/category_landing.thtml:87 views/addons/browse_thumbs.thtml:60
+#, php-format
+msgid "img_preview_of"
+msgstr "Esikatselukuva lisäosasta %s"
+
+#. %1 is the login URL for the link tag
+#. %2 is the link to an explanatory page.
+#: views/elements/amo2009/install.thtml:307 views/elements/install.thtml:255
+msgid "install_a_login_to_install"
+msgstr "<a href=\"%1$s\">Kirjaudu sisään</a> asentaaksesi lisäosan"
+
+#. %1 is the URL for the Experimental Add-ons section of the FAQ page
+#: views/elements/amo2009/install.thtml:283 views/elements/install.thtml:232
+#, fuzzy
+msgid "install_button_confirm_exp_install"
+msgstr ""
+"Let me install this experimental add-on. <a href=\"%1$s\">What's this?</a>"
+
+#. %1$s is the application name. Example: Firefox
+#. %2$s is an optional string used to specify a platform. Example: (Windows)
+#: views/elements/amo2009/install.thtml:128 views/elements/install.thtml:75
+#, php-format
+msgid "install_button_text"
+msgstr "Asenna %s %siin"
+
+#. %1 is the add-on name, %2 is the app name
+#: views/elements/amo2009/install.thtml:191
+#: views/elements/amo2009/install.thtml:206
+#: views/elements/amo2009/install.thtml:249
+#: views/elements/amo2009/install.thtml:298 views/elements/install.thtml:150
+#: views/elements/install.thtml:165 views/elements/install.thtml:202
+#: views/elements/install.thtml:246
+#, php-format
+msgid "install_button_title"
+msgstr "Asenna lisäosa %1$s %2$siin"
+
+#. %1$s is the add-on name
+#: views/elements/amo2009/install.thtml:200 views/elements/install.thtml:159
+#, php-format
+msgid "install_download"
+msgstr "Lataa %1$s"
+
+#: views/elements/amo2009/install.thtml:147 views/elements/install.thtml:94
+msgid "install_error_addon_not_found"
+msgstr "Lisäosa ei ole saatavilla."
+
+#: views/addons/dictionaries.thtml:65
+#, fuzzy
+msgid "langtools_a11y_tablesummary"
+msgstr "List of language packs and dictionaries."
+
+#: views/addons/dictionaries.thtml:47
+msgid "langtools_download_dictionary"
+msgstr "Lataa oikolukusanasto"
+
+#: views/addons/dictionaries.thtml:48
+msgid "langtools_download_langpack"
+msgstr "Lataa kielipaketti"
+
+#: views/addons/dictionaries.thtml:63 controllers/components/amo.php:685
+#: controllers/addons_controller.php:1239
+msgid "langtools_header_dicts_and_langpacks"
+msgstr "Oikolukusanastot ja kielipaketit"
+
+#: views/addons/dictionaries.thtml:44
+msgid "langtools_install_dictionary"
+msgstr "Asenna oikolukusanasto"
+
+#: views/addons/dictionaries.thtml:45
+msgid "langtools_install_langpack"
+msgstr "Asenna kielipaketti"
+
+#: views/addons/dictionaries.thtml:69
+msgid "langtools_tableheader_dictionary"
+msgstr "Oikolukusanasto"
+
+#: views/addons/dictionaries.thtml:70
+msgid "langtools_tableheader_langpack"
+msgstr "Kielipaketti"
+
+#: views/addons/dictionaries.thtml:68
+msgid "langtools_tableheader_language"
+msgstr "Kieli"
+
+#: models/license.php:65
+#, fuzzy
+msgid "license_custom"
+msgstr "Custom License"
+
+#: config/bootstrap.php:303
+#, fuzzy
+msgid "licenses_bsd"
+msgstr "BSD License"
+
+#: config/bootstrap.php:298
+#, fuzzy
+msgid "licenses_gpl_2.0"
+msgstr "GNU General Public License, version 2.0"
+
+#: config/bootstrap.php:299
+#, fuzzy
+msgid "licenses_gpl_3.0"
+msgstr "GNU General Public License, version 3.0"
+
+#: config/bootstrap.php:300
+#, fuzzy
+msgid "licenses_lgpl_2.1"
+msgstr "GNU Lesser General Public License, version 2.1"
+
+#: config/bootstrap.php:301
+#, fuzzy
+msgid "licenses_lgpl_3.0"
+msgstr "GNU Lesser General Public License, version 3.0"
+
+#: config/bootstrap.php:302
+#, fuzzy
+msgid "licenses_mit"
+msgstr "MIT/X11 License"
+
+#: config/bootstrap.php:297
+#, fuzzy
+msgid "licenses_mpl_1.1"
+msgstr "Mozilla Public License, version 1.1"
+
+#: views/users/emailchange.thtml:51 views/users/delete.thtml:55
+#: views/users/delete.thtml:137 views/users/edit.thtml:74
+#: views/reviews/flag.thtml:54
+#, fuzzy
+msgid "link_return_to_front_page"
+msgstr "Click here to return to the front page."
+
+#: views/elements/amo2009/addon_list_options.thtml:46
+#: views/elements/addon_list_options.thtml:46
+msgid "list_sortby_date"
+msgstr "Päiväys"
+
+#: views/elements/amo2009/addon_list_options.thtml:47
+#: views/elements/addon_list_options.thtml:47
+msgid "list_sortby_downloads"
+msgstr "Lataukset"
+
+#: views/elements/amo2009/addon_list_options.thtml:45
+#: views/elements/addon_list_options.thtml:45
+msgid "list_sortby_name"
+msgstr "Nimen mukaan"
+
+#: views/elements/amo2009/addon_list_options.thtml:48
+#: views/elements/addon_list_options.thtml:48
+msgid "list_sortby_rating"
+msgstr "Pisteitä"
+
+#: config/bootstrap.php:278
+#, fuzzy
+msgid "main_prettyname_fennec"
+msgstr "Fennec"
+
+#: config/bootstrap.php:274
+msgid "main_prettyname_firefox"
+msgstr "Firefox"
+
+#: config/bootstrap.php:277
+msgid "main_prettyname_seamonkey"
+msgstr "SeaMonkey"
+
+#: config/bootstrap.php:276
+msgid "main_prettyname_sunbird"
+msgstr "Sunbird"
+
+#: config/bootstrap.php:275
+msgid "main_prettyname_thunderbird"
+msgstr "Thunderbird"
+
+#: views/elements/addon_categories.thtml:52
+#, fuzzy
+msgid "nav_category_dicts_langpacks"
+msgstr "Dictionaries & Language Packs"
+
+#: views/elements/addon_categories.thtml:55
+#, fuzzy
+msgid "nav_category_themes"
+msgstr "Themes"
+
+#: views/elements/app_chooser.thtml:47 views/layouts/amo2009.thtml:255
+#, fuzzy
+msgid "other_apps_tooltip"
+msgstr "Find add-ons for other applications"
+
+#. In a user list: user 1, user 2, "others"
+#: views/helpers/addons_html.php:222
+msgid "other_users"
+msgstr "muut"
+
+#: controllers/pages_controller.php:90
+#, fuzzy
+msgid "page_title_appversions"
+msgstr "Application Versions"
+
+#: controllers/pages_controller.php:115
+#, fuzzy
+msgid "page_title_collector"
+msgstr "Add-on Collector"
+
+#: controllers/pages_controller.php:117
+#, fuzzy
+msgid "page_title_collector_faq"
+msgstr "Add-on Collector FAQ"
+
+#: controllers/pages_controller.php:119
+#, fuzzy
+msgid "page_title_collector_features"
+msgstr "Add-on Collector Features"
+
+#: controllers/pages_controller.php:122
+#, fuzzy
+msgid "page_title_collector_firstrun"
+msgstr "Welcome to the Add-on Collector"
+
+#: controllers/pages_controller.php:92
+#, fuzzy
+msgid "page_title_credits"
+msgstr "Credits"
+
+#: controllers/pages_controller.php:113
+#, fuzzy
+msgid "page_title_developer_faq"
+msgstr "Developer FAQ"
+
+#: controllers/pages_controller.php:111
+#, fuzzy
+msgid "page_title_faq"
+msgstr "Frequently Asked Questions"
+
+#: controllers/pages_controller.php:94
+#, fuzzy
+msgid "page_title_fashionyourfirefox_faq"
+msgstr "Fashion your Firefox FAQ"
+
+#: controllers/pages_controller.php:101
+#, fuzzy
+msgid "page_title_policy"
+msgstr "Add-ons Policy"
+
+#: controllers/pages_controller.php:103
+#, fuzzy
+msgid "page_title_privacy"
+msgstr "Mozilla Privacy Policy"
+
+#: controllers/pages_controller.php:105
+#, fuzzy
+msgid "page_title_review_guide"
+msgstr "Review Guidelines"
+
+#: controllers/pages_controller.php:107
+#, fuzzy
+msgid "page_title_sandbox"
+msgstr "Sandbox Review System"
+
+#: controllers/pages_controller.php:109
+#, fuzzy
+msgid "page_title_submissionhelp"
+msgstr "Submission Help"
+
+#: views/pages/appversions.thtml:87
+msgid "pages_appversions_guid"
+msgstr "GUID"
+
+#: views/pages/appversions.thtml:79 controllers/pages_controller.php:90
+msgid "pages_appversions_header"
+msgstr "Kelvolliset ohjelmaversiot"
+
+#: views/pages/appversions.thtml:80
+msgid "pages_appversions_intro"
+msgstr ""
+"Mozilla Add-ons:ssa olevien lisäosien täytyy sisältää install.rdf-tiedosto "
+"ja toimia ainakin yhdessä tuetuista ohjelmista. Vain alla luetellut versiot "
+"näistä ohjelmista on sallittu."
+
+#. %s is a full <a> tag
+#: views/pages/appversions.thtml:93
+#, php-format
+msgid "pages_appversions_required_files"
+msgstr ""
+"Vaikka tukemasi sallittu ohjelma ei vaatisi install.rdf-tiedostoa, sellainen "
+"täytyy lisäosassa kuitenkin olla, kuten %s."
+
+#. this is the text inside of an <a> tag for pages_appversions_required_files. This
+#. should be fixed.
+#: views/pages/appversions.thtml:93
+msgid "pages_appversions_required_files_link"
+msgstr "on määritelty"
+
+#: views/pages/appversions.thtml:88
+msgid "pages_appversions_versions"
+msgstr "Versiot"
+
+#: views/pages/policy.thtml:51
+msgid "pages_policy_sandbox_link"
+msgstr "Hiekkalaatikon tietosivu"
+
+#: views/elements/pagination.thtml:53
+msgid "pagination_next_page"
+msgstr "seuraava"
+
+#: views/elements/pagination.thtml:52
+msgid "pagination_previous_page"
+msgstr "edellinen"
+
+#: views/elements/recaptcha.thtml:65
+#, fuzzy
+msgid "recaptcha_enter_both_words"
+msgstr ""
+"Please enter <strong>both words</strong> below, <strong>separated by a "
+"space</strong>."
+
+#: views/elements/recaptcha.thtml:83
+#, fuzzy
+msgid "recaptcha_enter_here"
+msgstr "Enter your answer here:"
+
+#: views/elements/recaptcha.thtml:74
+#, fuzzy
+msgid "recaptcha_enter_whatyouhear"
+msgstr "Please type what you hear."
+
+#. %1 is the link switching refreshing the captcha
+#. %2 is the link switching to a text captcha
+#: views/elements/recaptcha.thtml:77
+#, fuzzy
+msgid "recaptcha_hardtohear_text"
+msgstr ""
+"If this is hard to understand, you can <a href=\"%1$s\">listen to something "
+"else</a> or <a href=\"%2$s\">switch back to text</a>."
+
+#. %1 is the link switching refreshing the captcha
+#. %2 is the link switching to an audio captcha
+#: views/elements/recaptcha.thtml:68
+#, fuzzy
+msgid "recaptcha_hardtoread_text"
+msgstr ""
+"If this is hard to read, you can <a href=\"%1$s\">try different words</a> or "
+"<a href=\"%2$s\">listen to something</a> instead."
+
+#: views/users/register.thtml:105
+#, fuzzy
+msgid "recaptcha_label"
+msgstr "Are you human?"
+
+#: views/users/register.thtml:106
+#, fuzzy
+msgid "recaptcha_whatsthis"
+msgstr "What's this?"
+
+#: controllers/reviews_controller.php:559
+#, fuzzy
+msgid "review_flag_error"
+msgstr "Error flagging this review!"
+
+#: models/reviews_moderation_flag.php:69
+#, fuzzy
+msgid "review_flag_reason_bug_support"
+msgstr "Misplaced bug report or support request"
+
+#: views/reviews/display.thtml:103 views/reviews/display.thtml:186
+#, fuzzy
+msgid "review_flag_reason_instructions"
+msgstr "Report this review (select a reason)"
+
+#: models/reviews_moderation_flag.php:67
+#, fuzzy
+msgid "review_flag_reason_language"
+msgstr "Inappropriate language/dialog"
+
+#: models/reviews_moderation_flag.php:71
+#, fuzzy
+msgid "review_flag_reason_other"
+msgstr "Other (please specify)"
+
+#: models/reviews_moderation_flag.php:65
+#, fuzzy
+msgid "review_flag_reason_spam"
+msgstr "Spam or otherwise non-review content"
+
+#: views/reviews/display.thtml:91 views/reviews/display.thtml:175
+#: controllers/reviews_controller.php:555
+#, fuzzy
+msgid "review_flag_success"
+msgstr "Thanks; this review has been flagged for editor approval."
+
+#: views/reviews/display.thtml:41
+#, fuzzy
+msgid "review_flag_this"
+msgstr "Report this review"
+
+#: views/reviews/display.thtml:42
+#, fuzzy
+msgid "review_flag_this_titletip"
+msgstr ""
+"Is this review inappropriate, inaccurate or spam? Click here to flag it for "
+"editor review."
+
+#. %1 is the URL of the support section, %2 for the review guidelines
+#: views/reviews/add.thtml:53
+#, fuzzy
+msgid "review_guidelines_short"
+msgstr ""
+"<p>Keep these tips in mind:</p><ul><li>Write like you're telling a friend "
+"about your experience with the add-on. Give specifics and helpful details, "
+"such as what features you liked and/ordisliked, how easy to use it is, and "
+"any disadvantages it has. Avoid genericlanguage such as calling it \"Great"
+"\" or \"Bad\" unless you can give reasons whyyou believe this is so.</"
+"li><li>Please do not post bug reports in reviews. We do not make your email "
+"address available to add-on developers and they may need to contact you to "
+"help resolveyour issue. See the <a href=\"%1$s\">support section</a> to find "
+"out where to get assistance for this add-on.</li><li>Please keep reviews "
+"clean, avoid the use of improper language and do not post any personal "
+"information.</li></ul><p>Please read the <a href=\"%2$s\">Review Guidelines</"
+"a> for more detail about user add-on reviews.</a></p><a href=\"%2$s\">"
+
+#. %1 is the add-on name
+#: views/reviews/flag.thtml:56 views/reviews/display.thtml:55
+#: views/reviews/review_added.thtml:50
+#, php-format
+msgid "reviews_header"
+msgstr "Arvosteluja lisäosalle %s"
+
+#: controllers/addons_controller.php:435
+msgid "rss_featuredaddons"
+msgstr "Esiteltävät lisäsosat"
+
+#: controllers/addons_controller.php:432
+msgid "rss_newestaddons"
+msgstr "Uusimmat lisäosat"
+
+#: controllers/addons_controller.php:434
+#, fuzzy
+msgid "rss_popularaddons"
+msgstr "Popular Add-ons"
+
+#: controllers/addons_controller.php:433
+#, fuzzy
+msgid "rss_updatedaddons"
+msgstr "Updated Add-ons"
+
+#: views/elements/search_mini.thtml:70
+#, fuzzy
+msgid "search"
+msgstr "Search"
+
+#: views/search/collections.thtml:51
+#, fuzzy
+msgid "search_collections_header"
+msgstr "Collection Search Results"
+
+#: controllers/search_controller.php:297
+#, fuzzy
+msgid "search_collections_pagetitle"
+msgstr "Collection Search Results"
+
+#: controllers/search_controller.php:99
+msgid "search_disabled"
+msgstr ""
+"Etsimistoiminto on tällä hetkellä pois käytöstä. Yritä myöhemmin uudestaan."
+
+#: views/elements/amo2009/search.thtml:188 views/elements/search.thtml:187
+#: views/elements/search_mini.thtml:54
+msgid "search_form_all_addons"
+msgstr "kaikki lisäosat"
+
+#. This string is in the main category dropdown when searching
+#: views/elements/amo2009/search.thtml:204
+#, fuzzy
+msgid "search_form_all_collections"
+msgstr "all collections"
+
+#: views/elements/amo2009/search.thtml:184
+#: views/elements/amo2009/search.thtml:385
+#: views/elements/amo2009/search.thtml:408 views/elements/search.thtml:171
+#: views/elements/search.thtml:183 views/elements/search_mini.thtml:43
+#: views/elements/search_mini.thtml:49 views/layouts/mozilla.thtml:188
+msgid "search_form_default_text"
+msgstr "etsi lisäosista"
+
+#: views/elements/amo2009/search.thtml:184
+#: views/elements/amo2009/search.thtml:404
+#, fuzzy
+msgid "search_form_default_text_collections"
+msgstr "search for collections"
+
+#: views/elements/amo2009/search.thtml:206 views/elements/search.thtml:202
+#, fuzzy
+msgid "search_form_submit_tooltip"
+msgstr "Search for add-ons"
+
+#: views/elements/amo2009/search.thtml:184 views/elements/search.thtml:183
+#: views/elements/search_mini.thtml:49
+#, fuzzy
+msgid "search_form_tooltip"
+msgstr "Click to enter search terms"
+
+#: views/elements/amo2009/search.thtml:186 views/elements/search.thtml:185
+#: views/elements/search_mini.thtml:52
+msgid "search_form_within"
+msgstr "kohteessa"
+
+#: views/addons/searchengines.thtml:118
+msgid "search_landing_all_search_engines"
+msgstr "Kaikki hakukoneet"
+
+#: views/addons/searchengines.thtml:114
+msgid "search_landing_browse_search_engines"
+msgstr "Selaa hakukoneita"
+
+#: views/search/collections.thtml:58 views/search/index.thtml:59
+msgid "search_nothing_found"
+msgstr "Osumia ei löytynyt."
+
+#: controllers/search_controller.php:185
+msgid "search_pagetitle"
+msgstr "Etsi lisäosista"
+
+#: controllers/search_controller.php:242
+msgid "search_rss_description"
+msgstr "Syöte hakutuloksista"
+
+#. %s is the terms the user is searching for (a string)
+#: controllers/search_controller.php:241
+#, php-format
+msgid "search_rss_results_for"
+msgstr "Hakutulokset haulle: %s"
+
+#: views/elements/header.thtml:154 views/layouts/amo2009.thtml:296
+msgid "sidebar_navlink_admin_tools"
+msgstr "Ylläpitäjien työkalut"
+
+#: views/elements/header.thtml:146 views/layouts/amo2009.thtml:288
+msgid "sidebar_navlink_developer_tools"
+msgstr "Kehittäjätyökalut"
+
+#: views/elements/header.thtml:148 views/layouts/amo2009.thtml:290
+msgid "sidebar_navlink_editor_tools"
+msgstr "Toimittajan työkalut"
+
+#: views/layouts/amo2009.thtml:302
+msgid "sidebar_navlink_welcome"
+msgstr "Tervetuloa"
+
+#. %s is the user's name
+#: views/layouts/amo2009.thtml:302
+#, php-format
+msgid "sidebar_navlink_welcome_name"
+msgstr "Tervetuloa %s"
+
+#: views/elements/pitch.thtml:50 views/elements/pitch.thtml:55
+msgid "sidebar_pitch_dictionary"
+msgstr "Oikolukusanasto"
+
+#: views/elements/pitch.thtml:72
+#, fuzzy
+msgid "sidebar_pitch_featured_addons"
+msgstr "Featured Add-ons"
+
+#: views/elements/pitch.thtml:61
+msgid "sidebar_pitch_looking_for"
+msgstr "Haen...:"
+
+#: views/elements/pitch.thtml:70
+#, fuzzy
+msgid "sidebar_pitch_newest_addons"
+msgstr "Newest Add-ons"
+
+#: views/elements/pitch.thtml:49
+msgid "sidebar_pitch_search"
+msgstr "Hakukone"
+
+#: views/elements/pitch.thtml:69
+#, fuzzy
+msgid "sidebar_pitch_subscribe_to"
+msgstr "Subscribe to"
+
+#: views/elements/pitch.thtml:48 views/elements/pitch.thtml:54
+msgid "sidebar_pitch_theme"
+msgstr "Teema"
+
+#: views/elements/pitch.thtml:71
+#, fuzzy
+msgid "sidebar_pitch_updated_addons"
+msgstr "Updated Add-ons"
+
+#. %1$s is a number
+#: views/helpers/localization.php:65 views/developers/versions_edit.thtml:95
+#: views/addons/dictionaries.thtml:92
+#, php-format
+msgid "size_kb"
+msgstr "%1$s kt"
+
+#: views/elements/amo2009/stars.thtml:57 views/elements/stars.thtml:63
+msgid "stars_not_yet_rated"
+msgstr "Ei vielä pisteytetty"
+
+#. %1 is the number of stars this add-on has
+#: views/elements/amo2009/stars.thtml:49 views/elements/stars.thtml:54
+#, php-format
+msgid "stars_rated_x_outof_5"
+msgstr "Pisteitä %s / 5"
+
+#: views/statistics/addon.thtml:59
+msgid "statistics_addon_dashboard_link"
+msgstr "Tilastosivu"
+
+#: views/statistics/addon.thtml:58
+msgid "statistics_addon_developertools_link"
+msgstr "Kehittäjän työkalut"
+
+#: views/statistics/addon.thtml:53
+msgid "statistics_addon_switch"
+msgstr "Vaihda lisäosaa"
+
+#. This is a date format.
+#. http://php.net/strftime
+#: views/statistics/rss/summary.thtml:54 views/statistics/addon.thtml:181
+msgid "statistics_date_shortmonth"
+msgstr "M. j"
+
+#. This is a date format.
+#. http://php.net/strftime
+#: views/statistics/rss/summary.thtml:40 views/statistics/addon.thtml:152
+msgid "statistics_date_shortmonthwithyear"
+msgstr "M. j, Y"
+
+#. This is a date format.
+#. http://php.net/strftime
+#: views/statistics/rss/summary.thtml:41 views/statistics/rss/summary.thtml:48
+#: views/statistics/addon.thtml:161 views/statistics/addon.thtml:172
+msgid "statistics_date_weekdayshortmonth"
+msgstr "l, M. j"
+
+#. %1$s is an add-on name and version. Example: Add-on 3.5
+#: controllers/components/stats.php:519
+#, php-format
+msgid "statistics_events_addon_created"
+msgstr "%1$s lisätty"
+
+#. %1$s is an application name and version. Example: Firefox 3.5
+#: controllers/components/stats.php:500
+#, php-format
+msgid "statistics_events_app_released"
+msgstr "%1$s julkaistu"
+
+#: views/statistics/addon.thtml:71
+msgid "statistics_help_close_link"
+msgstr "Sulje"
+
+#: views/statistics/addon.thtml:60
+msgid "statistics_help_link"
+msgstr "Ohje"
+
+#: views/statistics/index.thtml:83
+msgid "statistics_index_anotheraddon"
+msgstr "tai valitse toinen lisäosa"
+
+#: views/statistics/index.thtml:85
+msgid "statistics_index_anotheraddon_public"
+msgstr "tai valitse lisäosa, jonka tilastot ovat julkisia"
+
+#: views/statistics/index.thtml:71
+msgid "statistics_index_myaddons"
+msgstr "Valitse lisäosasi, jonka tilastot haluat nähdä"
+
+#: views/statistics/index.thtml:89
+msgid "statistics_index_selectaddon"
+msgstr "Valitse lisäosa nähdäksesi siitä tilastoja"
+
+#: views/statistics/index.thtml:91
+msgid "statistics_index_selectaddon_public"
+msgstr "Valitse lisäosa, jonka tilastot ovat julkisia"
+
+#: views/statistics/index.thtml:39
+msgid "statistics_index_title"
+msgstr "Tilastosivu"
+
+#: views/statistics/index.thtml:97
+msgid "statistics_index_view_button"
+msgstr "Näytä tilastoja"
+
+#: views/statistics/addon.thtml:222 controllers/statistics_controller.php:247
+#, fuzzy
+msgid "statistics_js_download_csv"
+msgstr "View this table in CSV format"
+
+#: controllers/statistics_controller.php:246
+msgid "statistics_js_dropdowns_none"
+msgstr "ei mitään"
+
+#: controllers/statistics_controller.php:245
+msgid "statistics_js_dropdowns_removeplot"
+msgstr "Poista tämä tietosarja"
+
+#: controllers/statistics_controller.php:248
+#, fuzzy
+msgid "statistics_js_groupby_selector_date"
+msgstr "Group by: Day"
+
+#: controllers/statistics_controller.php:251
+#, fuzzy
+msgid "statistics_js_groupby_selector_month"
+msgstr "Group by: Month"
+
+#: controllers/statistics_controller.php:249
+#, fuzzy
+msgid "statistics_js_groupby_selector_week"
+msgstr "Group by: Week"
+
+#: controllers/statistics_controller.php:250
+#, fuzzy
+msgid "statistics_js_groupby_selector_week_over_week"
+msgstr "Compare by: Week"
+
+#: controllers/statistics_controller.php:260
+msgid "statistics_js_plotselection_foundinrange"
+msgstr "%s löydettiin rajauksella"
+
+#: controllers/statistics_controller.php:270
+msgid "statistics_js_plotselection_options_addplot_name"
+msgstr "Lisää tietosarja"
+
+#: controllers/statistics_controller.php:271
+msgid "statistics_js_plotselection_options_addplot_tooltip"
+msgstr "Lisää tietosarja tähän kuvaajaan"
+
+#: controllers/statistics_controller.php:261
+msgid "statistics_js_plotselection_options_count_name_checked"
+msgstr "Piilota yhteyslukumäärä"
+
+#: controllers/statistics_controller.php:262
+msgid "statistics_js_plotselection_options_count_name_unchecked"
+msgstr "Näytä yhteyslukumäärä"
+
+#: controllers/statistics_controller.php:263
+#, fuzzy
+msgid "statistics_js_plotselection_options_count_tooltip"
+msgstr "Plot the total count on this graph"
+
+#: controllers/statistics_controller.php:275
+msgid "statistics_js_plotselection_options_csv_name"
+msgstr "Näytä data (CSV)"
+
+#: controllers/statistics_controller.php:276
+msgid "statistics_js_plotselection_options_csv_tooltip"
+msgstr "Lataa tämä data pilkkueroteltuna tiedostona (CSV)"
+
+#: controllers/statistics_controller.php:267
+msgid "statistics_js_plotselection_options_events_addon_name_checked"
+msgstr "Piilota %s tapahtumat"
+
+#: controllers/statistics_controller.php:268
+msgid "statistics_js_plotselection_options_events_addon_name_unchecked"
+msgstr "NÄytä %s tapahtumat"
+
+#: controllers/statistics_controller.php:269
+msgid "statistics_js_plotselection_options_events_addon_tooltip"
+msgstr "NÄytä lisäosan julkaisupäivät kuvaajassa"
+
+#: controllers/statistics_controller.php:264
+msgid "statistics_js_plotselection_options_events_firefox_name_checked"
+msgstr "Piilota Firefox-tapahtumat"
+
+#: controllers/statistics_controller.php:265
+msgid "statistics_js_plotselection_options_events_firefox_name_unchecked"
+msgstr "Näytä Firefox-tapahtumat"
+
+#: controllers/statistics_controller.php:266
+msgid "statistics_js_plotselection_options_events_firefox_tooltip"
+msgstr "Näytä Firefoxin julkaisupäivät kuvaajissa"
+
+#: controllers/statistics_controller.php:272
+msgid "statistics_js_plotselection_options_resize_name_checked"
+msgstr "Supista kuvaaja"
+
+#: controllers/statistics_controller.php:273
+msgid "statistics_js_plotselection_options_resize_name_unchecked"
+msgstr "Laajenna kuvaaja"
+
+#: controllers/statistics_controller.php:274
+msgid "statistics_js_plotselection_options_resize_tooltip"
+msgstr "Muuta kuvaajan kokoa"
+
+#: controllers/statistics_controller.php:254
+msgid "statistics_js_plotselection_selector_adu"
+msgstr "Aktiiviset päivittäiskäyttäjät"
+
+#: controllers/statistics_controller.php:256
+msgid "statistics_js_plotselection_selector_application"
+msgstr "Ohjelma"
+
+#: controllers/statistics_controller.php:259
+msgid "statistics_js_plotselection_selector_custom"
+msgstr "Oma"
+
+#: controllers/statistics_controller.php:253
+msgid "statistics_js_plotselection_selector_downloads"
+msgstr "Latauksia"
+
+#: controllers/statistics_controller.php:258
+msgid "statistics_js_plotselection_selector_os"
+msgstr "Käyttöjärjestelmä"
+
+#: controllers/statistics_controller.php:257
+msgid "statistics_js_plotselection_selector_status"
+msgstr "Lisäosan tila"
+
+#: controllers/statistics_controller.php:252
+msgid "statistics_js_plotselection_selector_summary"
+msgstr "Yhteenveto"
+
+#: controllers/statistics_controller.php:255
+msgid "statistics_js_plotselection_selector_version"
+msgstr "Lisäosan versio"
+
+#: controllers/components/stats.php:398
+msgid "statistics_longnames_application"
+msgstr "Ohjelma"
+
+#: controllers/components/stats.php:400
+msgid "statistics_longnames_os"
+msgstr "Käyttöjärjestelmä"
+
+#: controllers/components/stats.php:399
+msgid "statistics_longnames_status"
+msgstr "Lisäosan tila"
+
+#: controllers/components/stats.php:401
+msgid "statistics_longnames_unknown"
+msgstr "Tuntematon"
+
+#: controllers/components/stats.php:397
+msgid "statistics_longnames_version"
+msgstr "Lisäosan versio"
+
+#: views/statistics/addon.thtml:118
+msgid "statistics_notice_data_insufficient"
+msgstr ""
+"Tähän kuvaajaan ei ole vielä kerätty riittävästi dataa. Yritä myöhemmin "
+"uudestaan."
+
+#: views/statistics/addon.thtml:130
+msgid "statistics_notice_data_none"
+msgstr ""
+"Emme vielä ole keränneet yhtään dataa lisäosastasi. Yritä muutaman päivän "
+"päästä uudestaan."
+
+#: views/statistics/addon.thtml:41
+#, fuzzy
+msgid "statistics_notice_data_updating"
+msgstr ""
+"Add-on statistics are currently in the process of being updated. Recent data "
+"may be incomplete as our scripts work to update this information. Please "
+"check back in a few minutes."
+
+#: views/statistics/addon.thtml:136
+msgid "statistics_notice_disabled"
+msgstr ""
+"Tilastosivu on tällä hetkellä poissa käytöstä. Yritä myöhemmin uudestaan."
+
+#: views/statistics/addon.thtml:123
+msgid "statistics_notice_nojavascript"
+msgstr "Tilastosivun kuvaajat vaativat näkyäkseen JavaScriptin olevan päällä."
+
+#: views/statistics/addon.thtml:44
+msgid "statistics_notice_settings_updated"
+msgstr "Asetuksesi on päivitetty."
+
+#: controllers/statistics_controller.php:60
+#: controllers/statistics_controller.php:71
+#: controllers/statistics_controller.php:74
+#: controllers/statistics_controller.php:240
+msgid "statistics_pagetitle"
+msgstr "Tilastosivu"
+
+#: views/statistics/addon.thtml:99
+msgid "statistics_plot_legend_adu"
+msgstr "Aktiivista päivittäiskäyttäjää"
+
+#: views/statistics/addon.thtml:95
+msgid "statistics_plot_legend_downloads"
+msgstr "Latausta päivässä"
+
+#: views/statistics/addon.thtml:107
+msgid "statistics_plot_options_zoomin_alt"
+msgstr "Lähennä"
+
+#: views/statistics/addon.thtml:106
+msgid "statistics_plot_options_zoomin_title"
+msgstr "Lähennä yhteen kuukauteen"
+
+#: views/statistics/addon.thtml:110
+msgid "statistics_plot_options_zoomout_alt"
+msgstr "Loitonna"
+
+#: views/statistics/addon.thtml:109
+msgid "statistics_plot_options_zoomout_title"
+msgstr "Loitonna yksi kuukausi"
+
+#: controllers/statistics_controller.php:283
+#, php-format
+msgid "statistics_rss_description"
+msgstr "Päivän tilastoyhteenveto lisäosalle %1$s"
+
+#: views/statistics/rss/summary.thtml:68
+msgid "statistics_rss_title_fulldate"
+msgstr "l, F j, Y"
+
+#: views/statistics/rss/summary.thtml:68
+#, php-format
+msgid "statistics_rss_title_statsfordate"
+msgstr "Tilastot päivälle %1$s"
+
+#: views/statistics/settings.thtml:49
+#, fuzzy
+msgid "statistics_settings_access_description"
+msgstr ""
+"By default, only you and Mozilla can access the information in your "
+"dashboard. You can open this up to the public so that anyone can view your "
+"add-on's data."
+
+#: views/statistics/settings.thtml:48
+msgid "statistics_settings_access_heading"
+msgstr "Tilastojen lukuoikeus"
+
+#: views/statistics/settings.thtml:51
+msgid "statistics_settings_access_private"
+msgstr "Yksityinen"
+
+#: views/statistics/settings.thtml:51
+msgid "statistics_settings_access_private_description"
+msgstr "Vain sinä ja Mozilla voivat nähdä lisäosan tilastot"
+
+#: views/statistics/settings.thtml:52
+msgid "statistics_settings_access_public"
+msgstr "Julkinen"
+
+#: views/statistics/settings.thtml:52
+msgid "statistics_settings_access_public_description"
+msgstr "Kuka tahansa voi katsoa lisäosan tilastoja"
+
+#: views/statistics/addon.thtml:251
+msgid "statistics_settings_change_link"
+msgstr "Muokkaa asetuksia"
+
+#: views/statistics/addon.thtml:253
+msgid "statistics_settings_confidential"
+msgstr "Nämä tiedot ovat luottamuksellisia."
+
+#: views/statistics/addon.thtml:245
+msgid "statistics_settings_currently_private"
+msgstr "Tämä tilastosivu on asetettu <b>yksityiseksi</b>."
+
+#: views/statistics/addon.thtml:241
+msgid "statistics_settings_currently_public"
+msgstr "Tämä tilastosivu on asetettu <b>julkiseksi</b>."
+
+#: views/statistics/addon.thtml:246
+msgid "statistics_settings_locked_alt"
+msgstr "Lukittu"
+
+#: views/statistics/settings.thtml:57
+msgid "statistics_settings_return_link"
+msgstr "Palaa tilastosivulle"
+
+#: views/statistics/settings.thtml:56
+msgid "statistics_settings_save_button"
+msgstr "Tallenna asetukset"
+
+#: views/statistics/settings.thtml:46
+#, php-format
+msgid "statistics_settings_title"
+msgstr "Tilastosivuasetukset kohteelle %1$s"
+
+#: views/statistics/addon.thtml:242
+msgid "statistics_settings_unlocked_alt"
+msgstr "Ei lukittu"
+
+#: controllers/components/stats.php:405
+msgid "statistics_shortnames_application"
+msgstr "Ohj"
+
+#: controllers/components/stats.php:407
+msgid "statistics_shortnames_os"
+msgstr "OS"
+
+#: controllers/components/stats.php:406
+msgid "statistics_shortnames_status"
+msgstr "Tila"
+
+#: controllers/components/stats.php:408
+msgid "statistics_shortnames_unknown"
+msgstr "Tunt"
+
+#: controllers/components/stats.php:404
+msgid "statistics_shortnames_version"
+msgstr "Ver"
+
+#: views/statistics/rss/summary.thtml:42 views/statistics/addon.thtml:192
+msgid "statistics_summary_downloads_average"
+msgstr "Päivittäisiä latauksia keskimäärin"
+
+#: views/statistics/rss/summary.thtml:39
+msgid "statistics_summary_downloads_heading"
+msgstr "Latauksia"
+
+#: views/statistics/rss/summary.thtml:41 views/statistics/addon.thtml:171
+msgid "statistics_summary_downloads_lastcount"
+msgstr "Viimeisin tieto"
+
+#: views/statistics/rss/summary.thtml:43 views/statistics/addon.thtml:199
+msgid "statistics_summary_downloads_lastweek"
+msgstr "Latauksia viimeisen 7 päivän aikana"
+
+#: views/statistics/rss/summary.thtml:40 views/statistics/addon.thtml:151
+msgid "statistics_summary_downloads_total"
+msgstr "Latauksia yhteensä"
+
+#: views/statistics/rss/summary.thtml:40 views/statistics/addon.thtml:152
+#, php-format
+msgid "statistics_summary_downloads_total_sincedate"
+msgstr "%1$s lähtien"
+
+#: views/statistics/rss/summary.thtml:50 views/statistics/rss/summary.thtml:56
+#: views/statistics/addon.thtml:163 views/statistics/addon.thtml:183
+msgid "statistics_summary_nodata"
+msgstr "Ei dataa vielä"
+
+#: views/statistics/rss/summary.thtml:60 views/statistics/addon.thtml:195
+msgid "statistics_summary_updatepings_average"
+msgstr "Aktiivisia käyttäjiä päivittäin keskimäärin"
+
+#: views/statistics/rss/summary.thtml:52 views/statistics/addon.thtml:177
+msgid "statistics_summary_updatepings_changefromprevious"
+msgstr "Muutos viimeisestä mittauksesta"
+
+#: views/statistics/rss/summary.thtml:54 views/statistics/addon.thtml:181
+#, php-format
+msgid "statistics_summary_updatepings_changefromprevious_ondate"
+msgstr "%1$s, %2$s"
+
+#: views/statistics/rss/summary.thtml:45
+msgid "statistics_summary_updatepings_heading"
+msgstr "Aktiivisia käyttäjiä päivittäin"
+
+#: views/statistics/rss/summary.thtml:46 views/statistics/addon.thtml:157
+msgid "statistics_summary_updatepings_total"
+msgstr "Aktiivisia käyttäjiä päivittäin"
+
+#: views/statistics/rss/summary.thtml:48 views/statistics/addon.thtml:161
+#, php-format
+msgid "statistics_summary_updatepings_total_ondate"
+msgstr "%1$s"
+
+#: views/statistics/rss/summary.thtml:61 views/statistics/addon.thtml:203
+#, fuzzy
+msgid "statistics_summary_updatepings_weekly_average"
+msgstr "Average Daily Users this Week"
+
+#. %s is a percentage, like '+22.33%'. It sits next to another number, so
+#. the implied meaning is 'percentage change' from the previous stat point.
+#: views/statistics/rss/summary.thtml:62 views/statistics/addon.thtml:205
+#, fuzzy
+msgid "statistics_summary_updatepings_weekly_change"
+msgstr "%s from last week"
+
+#: views/statistics/addon.thtml:65 controllers/statistics_controller.php:184
+#: controllers/statistics_controller.php:282
+#, php-format
+msgid "statistics_title_addon_stats"
+msgstr "Tilastoja lisäosasta %1$s"
+
+#: views/addons/themes_landing.thtml:113
+msgid "themes_landing_all_themes"
+msgstr "Kaikki teemat"
+
+#: views/addons/themes_landing.thtml:109
+msgid "themes_landing_browse_themes"
+msgstr "Selaa teemoja"
+
+#: views/users/edit.thtml:185
+#, fuzzy
+msgid "user_change_email"
+msgstr "Change Email Address"
+
+#: views/users/edit.thtml:169
+msgid "user_change_password"
+msgstr "Muuta salasanaa"
+
+#: views/users/edit.thtml:96
+#, fuzzy
+msgid "user_change_password_or_email"
+msgstr "Change Password or Email"
+
+#: controllers/users_controller.php:197
+msgid "user_confirmationcode_resent"
+msgstr "Varmistuskoodi lähetettiin uudestaan."
+
+#. %1 is the email address, %2 is the URL of the user registration page
+#: views/users/delete.thtml:51
+#, fuzzy
+msgid "user_del_account_deleted"
+msgstr ""
+"Your user account %1$s has been successfully deleted. If you want to come "
+"back some time, you can re-register on the <a href=\"%2$s\">user "
+"registration page</a>."
+
+#: views/users/delete.thtml:102
+#, fuzzy
+msgid "user_del_community_sad"
+msgstr "The Mozilla Add-ons community is sad to see you go."
+
+#: views/users/delete.thtml:123
+#, fuzzy
+msgid "user_del_confirm_password"
+msgstr "Confirm Password"
+
+#: views/users/delete.thtml:134
+#, fuzzy
+msgid "user_del_deletenow"
+msgstr "Delete my user account now"
+
+#. %1 is the URL of the user's info page
+#: views/users/delete.thtml:64
+#, fuzzy
+msgid "user_del_error_addons"
+msgstr ""
+"You cannot delete your account if you are listed as an <a href=\"%1$s"
+"\">author of any add-ons</a>. To delete your account, please have another "
+"person in your development group delete you from the list of authors for "
+"your add-ons. Afterwards you will be able to delete your account here."
+
+#. %1 is a link to the amo-editors mailing list
+#: views/users/delete.thtml:71
+#, fuzzy
+msgid "user_del_error_addons_more_questions"
+msgstr "If you have additional questions, please contact %1$s for assistance."
+
+#: views/users/delete.thtml:78
+#, fuzzy
+msgid "user_del_error_checkbox"
+msgstr ""
+"You need to check the box \"I understand...\" before we can delete your "
+"account."
+
+#: views/users/delete.thtml:84
+#, fuzzy
+msgid "user_del_error_password"
+msgstr "Please enter your password correctly in order to perform this step."
+
+#. %1 is a link to the amo-admins mailing list
+#: views/users/delete.thtml:91
+#, fuzzy
+msgid "user_del_error_unknown"
+msgstr ""
+"An unknown error occured deleting your account. Please contact %1$s with the "
+"issue and we will delete it for you. We apologize for the inconvenience."
+
+#: views/users/delete.thtml:110
+#, fuzzy
+msgid "user_del_header_confirm_deletion"
+msgstr "Confirm account deletion"
+
+#. %1 is the user's email address
+#: views/users/delete.thtml:100
+#, fuzzy
+msgid "user_del_header_delete_account"
+msgstr "Delete User Account %1$s"
+
+#: views/users/delete.thtml:50
+#, fuzzy
+msgid "user_del_header_farewell"
+msgstr "Farewell!"
+
+#: views/users/delete.thtml:115
+#, fuzzy
+msgid "user_del_nologin"
+msgstr "You will not be able to log into Mozilla Add-ons anymore."
+
+#: views/users/delete.thtml:112
+#, fuzzy
+msgid "user_del_permanently_removed_means"
+msgstr ""
+"By clicking \"delete\" your account is going to be <strong>permanently "
+"removed</strong>. That means:"
+
+#: views/users/delete.thtml:116
+#, fuzzy
+msgid "user_del_reviews_anonymized"
+msgstr ""
+"Your reviews and ratings will not be deleted, but they will no longer be "
+"associated with you."
+
+#. %1 is a link to the amo-editors mailing list
+#: views/users/delete.thtml:104
+#, fuzzy
+msgid "user_del_specific_problem_editors"
+msgstr ""
+"If you have a specific problem we may help you with, please do not delete "
+"your account now, but contact us at %1$s and we will do our best to assist "
+"you in solving it."
+
+#: views/users/delete.thtml:130
+#, fuzzy
+msgid "user_del_understand_permanent"
+msgstr "I understand that this step cannot be undone."
+
+#: views/helpers/addons_html.php:192
+#, fuzzy
+msgid "user_deleted_nickname"
+msgstr "Deleted User"
+
+#. %1 is the new email address
+#: views/users/edit.thtml:71
+#, fuzzy
+msgid "user_edit_confirm_email_sent"
+msgstr ""
+"An email has been sent to %1$s to confirm your new email address. For the "
+"change to take effect, you need to click on the link provided in this email. "
+"Until then, you can keep logging in with your current email address."
+
+#: views/users/edit.thtml:201
+#, fuzzy
+msgid "user_edit_delete_user"
+msgstr "Delete user account"
+
+#. This contains the email sent to users when they signed up for a new
+#. account:
+#. %1 is the confirmation URL, %2 is the current app
+#: views/users/email/confirm_plain.thtml:6
+#, php-format
+msgid "user_email_confirm_account_nopass"
+msgstr ""
+"Tervetuloa %2$sin lisäosiin.\n"
+"\n"
+"Ennen kuin uutta tiliäsi voi käyttää, se pitää varmentaa, jotta voimme olla "
+"varmoja, että antamasi sähköpostiosoite on oikea.\n"
+"Varmenna tilisi napsauttamalla seuraavaa linkkiä tai kopioimalla sen "
+"kokonaisuudessaan selaimesi osoitepalkkiin:\n"
+"\n"
+"%1$s\n"
+"\n"
+"Voit poistaa tämän viestin kun tilisi on asianmukaisesti varmistettu.\n"
+"\n"
+"Kiitos rekisteröitymisestä %2$sin lisäosat -sivustolle\n"
+"-- %2$sin lisäosat -sivuston ylläpito"
+
+#. %1 is the confirmation url, %2 is the application name
+#: views/users/email/emailchange_plain.thtml:5
+#, fuzzy
+msgid "user_email_confirm_emailchange"
+msgstr ""
+"You requested a change to your email address at %2$s Add-ons.\n"
+"\n"
+"In order to confirm the new address, please click the link below or copy and "
+"paste the whole thing into your browser's location bar:\n"
+"\n"
+"%1$s\n"
+"\n"
+"You have 48 hours to confirm the new address. If you do not want to change "
+"the address anymore, you can just ignore this email.\n"
+"\n"
+"Thanks!\n"
+"-- %2$s Add-ons Staff"
+
+#: controllers/users_controller.php:168
+#, php-format
+msgid "user_email_confirm_subject"
+msgstr "Kiitokset rekisteröitymisestä %sin lisäosat -sivustolle"
+
+#. This is the password reset email
+#. %1 is the pw reset URL, %2 is the application
+#: views/users/email/pwreset_plain.thtml:5
+#, php-format
+msgid "user_email_pwreset"
+msgstr ""
+"%2$sin lisäosien salasanan nollaus\n"
+"\n"
+"Tämän tilin salasana addons.mozilla.orgissa haluttiin nollata. Napsauta "
+"seuraavaa linkkiä, jos haluat edelleen nollata vanhan salasana ja asettaa "
+"uuden salasanan. Voit myös tarvittaessa kopioida linkin selaimen "
+"sijaintipalkkiin:\n"
+"%1$s\n"
+"\n"
+"Jos et halua nollata salasanaasi sivustolla, jätä tämä sähköposti "
+"huomiotta.\n"
+"\n"
+"Kiitokset,\n"
+"-- %2$sin lisäosien ylläpito"
+
+#: controllers/users_controller.php:245
+#, php-format
+msgid "user_email_pwreset_subject"
+msgstr "Nollaa salasanasi %sin lisäosiin"
+
+#: views/users/emailchange.thtml:50
+#, fuzzy
+msgid "user_emailchange_error"
+msgstr "Error!"
+
+#. %1 is the application name
+#: controllers/users_controller.php:533
+#, fuzzy
+msgid "user_emailchange_subject"
+msgstr "Please confirm your email address change at %1$s Add-ons"
+
+#: views/users/emailchange.thtml:48
+#, fuzzy
+msgid "user_emailchange_success"
+msgstr "Success!"
+
+#. %1 is the new email address
+#: views/users/emailchange.thtml:49
+#, fuzzy
+msgid "user_emailchange_successful_description"
+msgstr ""
+"Your email address was changed successfully. From now on, please use %1$s to "
+"log in."
+
+#: views/users/edit.thtml:134 views/admin/users_edit.thtml:111
+#, fuzzy
+msgid "user_form_bio"
+msgstr "About me"
+
+#: views/users/edit.thtml:135 views/admin/users_edit.thtml:112
+#, fuzzy
+msgid "user_form_bio_description"
+msgstr ""
+"Introduce yourself to the community, if you like! This text will appear "
+"publicly on your user info page. Line breaks will be preserved, but no HTML "
+"is allowed."
+
+#: views/users/pwreset.thtml:77 views/users/register.thtml:73
+#: views/users/edit.thtml:181
+msgid "user_form_confirmpassword"
+msgstr "Vahvista salasana"
+
+#: views/users/edit.thtml:145
+#, fuzzy
+msgid "user_form_display_collections"
+msgstr "Display the collections I have created in my user profile"
+
+#: views/users/edit.thtml:149
+#, fuzzy
+msgid "user_form_display_collections_fav"
+msgstr "Display my favorite collections in my user profile"
+
+#: views/users/edit.thtml:86
+#, php-format
+msgid "user_form_editprofile"
+msgstr "Muokkaa käyttäjän %s tietoja"
+
+#: views/users/pwreset.thtml:52 views/users/login.thtml:81
+#: views/users/register.thtml:63 views/users/edit.thtml:187
+msgid "user_form_email"
+msgstr "Sähköpostiosoite"
+
+#: views/users/register.thtml:78 views/users/edit.thtml:103
+#: views/admin/users_edit.thtml:76
+msgid "user_form_firstname"
+msgstr "Etunimi"
+
+#: views/users/register.thtml:94 views/users/edit.thtml:119
+#: views/admin/users_edit.thtml:91
+msgid "user_form_hideemail"
+msgstr "Piilota sähköpostiosoite"
+
+#: views/users/register.thtml:98 views/users/edit.thtml:123
+#: views/admin/users_edit.thtml:99
+msgid "user_form_homepage"
+msgstr "WWW-sivun URL"
+
+#: views/users/register.thtml:84 views/users/edit.thtml:109
+#: views/admin/users_edit.thtml:81
+msgid "user_form_lastname"
+msgstr "Sukunimi"
+
+#: controllers/users_controller.php:333
+msgid "user_form_login"
+msgstr "Sisäänkirjautuminen"
+
+#: views/users/pwreset.thtml:72 views/users/edit.thtml:176
+msgid "user_form_newpassword"
+msgstr "Uusi salasana"
+
+#: views/users/register.thtml:89 views/users/edit.thtml:114
+#: views/admin/users_edit.thtml:86
+msgid "user_form_nickname"
+msgstr "Lempinimi"
+
+#: views/users/edit.thtml:171
+msgid "user_form_oldpassword"
+msgstr "Vanha salasana"
+
+#: views/users/edit.thtml:97 views/users/edit.thtml:200
+#, fuzzy
+msgid "user_form_otheractions"
+msgstr "Other Actions"
+
+#: views/users/login.thtml:85 views/users/register.thtml:68
+msgid "user_form_password"
+msgstr "Salasana"
+
+#: controllers/users_controller.php:93
+msgid "user_form_registration"
+msgstr "Uuden käyttäjän rekisteröinti"
+
+#: views/users/login.thtml:90
+#, fuzzy
+msgid "user_form_remember_me"
+msgstr "Remember me on this computer"
+
+#: views/admin/users_edit.thtml:95
+msgid "user_form_showsandbox"
+msgstr "Hiekkalaatikon sisältö näytetään"
+
+#: views/users/edit.thtml:205
+msgid "user_form_submit_edit"
+msgstr "Tallenna"
+
+#: views/users/login.thtml:93
+msgid "user_form_submit_login"
+msgstr "Kirjaudu sisään"
+
+#: views/users/register.thtml:113
+msgid "user_form_submit_register"
+msgstr "Rekisteröidy"
+
+#: views/users/info.thtml:75
+#, php-format
+msgid "user_info_usersince"
+msgstr "Rekisteröitynyt sivustolle "
+
+#: views/users/login.thtml:102
+msgid "user_login_register_link"
+msgstr "Luo uusi käyttäjätili"
+
+#: views/users/edit.thtml:160
+#, fuzzy
+msgid "user_notifications_item_compat"
+msgstr "Add-on Compatibility (strongly recommended)"
+
+#: views/users/edit.thtml:161
+#, fuzzy
+msgid "user_notifications_item_events"
+msgstr "Upcoming events and contests"
+
+#: views/users/edit.thtml:156
+#, fuzzy
+msgid "user_notifications_none_available"
+msgstr "There are currently no notifications available for you to configure."
+
+#: views/users/edit.thtml:158
+#, fuzzy
+msgid "user_notifications_select_topics"
+msgstr ""
+"From time to time, Mozilla may send you email about upcoming releases and "
+"add-on events. Please select the topics you are interested in below:"
+
+#: views/users/edit.thtml:164
+#, fuzzy
+msgid "user_notifications_specific_contact"
+msgstr ""
+"Mozilla reserves the right to contact you individually about specific "
+"concerns with your hosted add-ons."
+
+#: controllers/users_controller.php:543
+msgid "user_profile_edit_error"
+msgstr ""
+"Tehdyt muutokset olivat virheellisiä. Korjaa virheet ja lähetä tiedot "
+"uudestaan."
+
+#: controllers/users_controller.php:540
+msgid "user_profile_saved"
+msgstr "Käyttäjätiedot päivitettiin."
+
+#: views/users/pwreset.thtml:65
+#, php-format
+msgid "user_pwreset_for_email"
+msgstr "Salasanan nollaaminen käyttäjälle %s"
+
+#: controllers/users_controller.php:226
+msgid "user_pwreset_header"
+msgstr "Salasanan nollaaminen"
+
+#: views/users/login.thtml:103
+msgid "user_pwreset_link"
+msgstr "Oletko unohtanut salasanasi?"
+
+#: controllers/users_controller.php:248
+msgid "user_pwreset_link_sent"
+msgstr ""
+"Sähköposti, jossa on linkki salasanan nollaukseen, lähetettiin "
+"sähköpostiosoitteeseesi."
+
+#: controllers/users_controller.php:304
+msgid "user_pwreset_okay"
+msgstr "Salasanan nollaaminen onnistui."
+
+#: views/users/pwreset.thtml:82
+msgid "user_pwreset_submit_changepw"
+msgstr "Muuta salasanaa"
+
+#: views/users/pwreset.thtml:57
+msgid "user_pwreset_submit_sendlink"
+msgstr "Lähetä linkki salasanan nollaamiseen"
+
+#: views/users/register_complete.thtml:51
+#, php-format
+msgid "user_register_amo_link"
+msgstr "%sin lisäosat"
+
+#. %1 is the user's email address, %2 is the current app
+#: views/users/activatefirst.thtml:49
+#, php-format
+msgid "user_register_click_confirm_link"
+msgstr ""
+"Sähköpostiosoitteeseesi %1$s lähetettiin linkki, jolla voit aktivoida "
+"käyttäjätilisi. Linkkiä pitää napsauttaa ennen kuin voit seuraavan kerran "
+"kirjautua sivustolle."
+
+#. %1 is the user's email address
+#: views/users/register_complete.thtml:49
+#, php-format
+msgid "user_register_confirm_email_sent"
+msgstr ""
+"Sähköpostiosoitteeseesi %1$s lähetettiin vahvistusviesti tilin luonnista. "
+"Ennen kuin voit kirjautua sivustolle, tili pitää aktivoida avaamalla "
+"sähköpostissa oleva linkki."
+
+#: views/users/activatefirst.thtml:51
+msgid "user_register_confirmation_link_text"
+msgstr "lähettää vahvistusviestin uudelleen"
+
+#: views/users/register_complete.thtml:47
+msgid "user_register_congratulations"
+msgstr "Onneksi olkoon! Käyttäjätilisi luonti onnistui."
+
+#: views/users/register.thtml:50
+#, fuzzy
+msgid "user_register_details"
+msgstr ""
+"<p>Registration on AMO is <strong>not required</strong> if you simply want "
+"to download and install public add-ons.</p><p>You only need to register if:</"
+"p><ul><li>You want to submit reviews for add-ons</li><li>You are an add-on "
+"developer and want to upload your add-on for hosting on AMO</li></ul><p>Upon "
+"successful registration, you will be sent a confirmation email to the "
+"address you provided. Please follow the instructions there to confirm your "
+"account.</p><p>If you like, you can read our <a href='%1$s' title='Legal "
+"Notices'>Legal Notices</a> and <a href='%2$s' title='Privacy Policy'>Privacy "
+"Policy</a>.</p>"
+
+#. %1 is the link to the "resend confirmation code" page
+#: views/users/activatefirst.thtml:51
+#, php-format
+msgid "user_register_resend_confirmation_link"
+msgstr ""
+"Jos et saanut vahvistussähköpostia, varmista että sähköpostipalvelusi ei "
+"merkinnyt sähköpostia roskapostiksi. Jos haluat, voimme %1$s samaan "
+"sähköpostiosoitteeseen."
+
+#. %1 is the link to the Mozilla Add-ons front page
+#: views/users/register_complete.thtml:51
+#, php-format
+msgid "user_register_welcome"
+msgstr "Kiitos rekisteröitymisestä ja tervetuloa %1$s-sivustolle!"
+
+#: views/users/register.thtml:49
+#, fuzzy
+msgid "user_register_welcome_header"
+msgstr "Welcome to addons.mozilla.org (AMO)!"
+
+#: views/users/register.thtml:81 views/users/edit.thtml:106
+#, fuzzy
+msgid "user_required_firstlast_or_nickname"
+msgstr "A first name, last name or nickname is required."
+
+#: views/users/edit.thtml:94 views/users/edit.thtml:142
+#, fuzzy
+msgid "user_tab_collections"
+msgstr "Collections"
+
+#: views/users/edit.thtml:95 views/users/edit.thtml:154
+#, fuzzy
+msgid "user_tab_notifications"
+msgstr "Notifications"
+
+#: views/users/edit.thtml:93 views/users/edit.thtml:101
+#, fuzzy
+msgid "user_tab_profile"
+msgstr "User Profile"
+
+#: controllers/users_controller.php:209
+msgid "user_verified_okay"
+msgstr "Tili vahvistettu."
+
+#: controllers/users_controller.php:723
+#, fuzzy
+msgid "users_delete_pagetitle"
+msgstr "Delete User Account"
+
+#: controllers/users_controller.php:414
+msgid "users_edit_pagetitle"
+msgstr "Käyttäjätilin muokkaaminen"
+
+#: views/users/info.thtml:71
+#, fuzzy
+msgid "users_info_aboutme"
+msgstr "About Me"
+
+#: views/users/info.thtml:96
+#, php-format
+msgid "users_info_addons_by_user"
+msgstr "Lisäosat, joiden tekijä on %1$s"
+
+#: views/users/info.thtml:51
+msgid "users_info_author_name"
+msgstr "Nimi"
+
+#: views/users/info.thtml:48
+msgid "users_info_author_profile"
+msgstr "Käyttäjätiedot"
+
+#. %s is the user name
+#: views/users/info.thtml:137
+#, fuzzy
+msgid "users_info_collections_by_user"
+msgstr "Collections by %s"
+
+#: views/users/info.thtml:66
+msgid "users_info_email"
+msgstr "Sähköpostiosoite"
+
+#: views/users/info.thtml:155
+#, fuzzy
+msgid "users_info_fav_collections_by_user"
+msgstr "Favorite Collections"
+
+#: views/users/info.thtml:61
+msgid "users_info_homepage"
+msgstr "Kotisivu"
+
+#: views/users/info.thtml:56
+msgid "users_info_nickname"
+msgstr "Lempinimi"
+
+#: controllers/users_controller.php:707
+#, php-format
+msgid "users_info_pagetitle"
+msgstr "Käyttäjän %1$s tiedot"
+
+#. %1 is the user's name
+#: views/users/info.thtml:116
+#, fuzzy
+msgid "users_info_reviews_by_user"
+msgstr "Reviews by %s"
+
+#: controllers/users_controller.php:330 controllers/users_controller.php:332
+msgid "users_login_pagetitle"
+msgstr "Sisäänkirjautuminen"
+
+#. %1 is the link to the sandbox/policy explanation page
+#. This message is for a specific add-on not found
+#: views/users/login.thtml:53
+#, php-format
+msgid "users_login_sandbox_display_warning"
+msgstr ""
+"Etsimäsi lisäosa on tällä hetkellä niin sanotussa hiekkalaatikossa. Jos olet "
+"jo rekisteröitynyt Mozilla lisäosiin, kirjaudu sisään tai lue lisää </a><a "
+"href=\"%1$s\">hiekkalaatikosta.</a>"
+
+#. %1 is the link to the sandbox/policy explanation page
+#. This message is for any given sandbox-related page not found
+#: views/users/login.thtml:56
+#, php-format
+msgid "users_login_sandbox_page_warning"
+msgstr ""
+"Etsimäsi sivu on tällä hetkellä niin sanotussa hiekkalaatikossa. Jos olet jo "
+"rekisteröitynyt Mozilla Add-ons:iin, kirjaudu sisään tai lue lisää <a href="
+"\"%1$s\">hiekkalaatikosta.</a>"
+
+#: controllers/users_controller.php:223 controllers/users_controller.php:225
+msgid "users_pwreset_pagetitle"
+msgstr "Käyttäjän salasanan nollaaminen"
+
+#: controllers/users_controller.php:90 controllers/users_controller.php:92
+msgid "users_register_pagetitle"
+msgstr "Uuden käyttäjän rekisteröityminen"
+
+#. %1$s is an addon name, like <a>Firebug</a>
+#. %2$s is a version number, like <a>1.2</a>
+#: views/versions/license.thtml:52
+#, fuzzy
+msgid "versions_license_header_source"
+msgstr "Source code license for %1$s %2$s"
+
+#: views/addons/category_landing.thtml:147
+#, fuzzy
+msgid "view_recently_added"
+msgstr "View all recently added"
+
+#: views/addons/category_landing.thtml:161
+#, fuzzy
+msgid "view_top_downloads"
+msgstr "View all top downloads"
+
+#: views/addons/category_landing.thtml:175
+#, fuzzy
+msgid "view_top_rated"
+msgstr "View all top rated"
+
+#, fuzzy
+#~ msgid "addon_slider_tooltip_next"
+#~ msgstr "Next Add-on"
+
+#, fuzzy
+#~ msgid "addon_slider_tooltip_previous"
+#~ msgstr "Previous Add-on"
+
+#, fuzzy
+#~ msgid "addon_versions_getlatesttext"
+#~ msgstr "The most recent version compatible with"
+
+#~ msgid "addons_display_version_history"
+#~ msgstr "Täydellinen versiohistoria"
+
+#, fuzzy
+#~ msgid "addons_home_newest_header"
+#~ msgstr "Newest:"
+
+#~ msgid "addons_home_popular_header"
+#~ msgstr "Suosituimpia:"
+
+#~ msgid "addons_home_recommended_header"
+#~ msgstr "Suosittelememme:"
+
+#, fuzzy
+#~ msgid "addons_home_updated_header"
+#~ msgstr "Recently Updated:"
+
+#~ msgid "addons_home_view_all"
+#~ msgstr "Näytä kaikki"
+
+#~ msgid "category_extra_allrecommended"
+#~ msgstr "Näytä kaikki suositellut lisäosat"
+
+#~ msgid "category_extra_highestrated"
+#~ msgstr "Korkeimmin pisteytetty ensin"
+
+#~ msgid "category_extra_lastupdated"
+#~ msgstr "Viimeisin päivitys ensin"
+
+#~ msgid "category_extra_mostpopular"
+#~ msgstr "Suosituin ensin"
+
+#, fuzzy
+#~ msgid "collections_detail_js_loading"
+#~ msgstr "Loading"
+
+#, fuzzy
+#~ msgid "collections_detail_more_info"
+#~ msgstr "Show More Info"
+
+#, fuzzy
+#~ msgid "devcp_additem_firefox_notice"
+#~ msgstr ""
+#~ "This version of your add-on does not claim compatibility with Firefox %1"
+#~ "$s. Mozilla is expecting the next version of Firefox to be released soon, "
+#~ "so please test your add-on in the new version and update compatibility "
+#~ "information. You can find out more about this <a href=\"%2$s\">here</a>. "
+#~ "This is only a notice and you may continue to submit this version to "
+#~ "addons.mozilla.org."
+
+#~ msgid "devcp_addon_disabled_successfully"
+#~ msgstr "Lisäosan poisto käytöstä onnistui"
+
+#~ msgid "devcp_addon_edit_pagetitle"
+#~ msgstr "Muokkaa lisäosaa"
+
+#~ msgid "devcp_addon_enabled_successfully"
+#~ msgstr "Lisäosan käyttöönotto onnistui"
+
+#~ msgid "devcp_addon_field_description_displaytitle"
+#~ msgstr "Lisäosan kuvaus"
+
+#~ msgid "devcp_addon_field_eula_displaytitle"
+#~ msgstr "EULA"
+
+#~ msgid "devcp_addon_field_homepage_displaytitle"
+#~ msgstr "Lisäosan kotisivu"
+
+#~ msgid "devcp_addon_field_name_displaytitle"
+#~ msgstr "Lisäosan nimi"
+
+#~ msgid "devcp_addon_field_privacy_displaytitle"
+#~ msgstr "Tietosuojakäytäntö"
+
+#~ msgid "devcp_addon_field_summary_displaytitle"
+#~ msgstr "Lisäosan yhteenveto"
+
+#~ msgid "devcp_addon_field_supportemail_displaytitle"
+#~ msgstr "Tukisähköpostiosoite"
+
+#~ msgid "devcp_addon_field_supporturl_displaytitle"
+#~ msgstr "Tukisivu"
+
+#~ msgid "devcp_addon_field_versionnotes_displaytitle"
+#~ msgstr "Versiotietoja"
+
+#~ msgid "devcp_addon_nominate_pagetitle"
+#~ msgstr "Lisäosan ehdottaminen julkiselle puolelle"
+
+#~ msgid "devcp_addon_nominated_successfully"
+#~ msgstr "Lisäosaa ehdotettiin julkiselle puolelle."
+
+#, fuzzy
+#~ msgid "devcp_addon_status_criteria_review"
+#~ msgstr "Several user reviews of the add-on (may be external reviews)."
+
+#~ msgid "devcp_addon_submission_makechanges"
+#~ msgstr "Siirry %1$s-sivulle muuttaaksesi lisäyksesi tietoja tai palaa %2$s."
+
+#~ msgid "devcp_addon_submission_makechanges_devcp_link"
+#~ msgstr "kehittäjän ohjauspaneeliin"
+
+#~ msgid "devcp_addon_submission_makechanges_link"
+#~ msgstr "Muokkaa lisäosaa"
+
+#~ msgid "devcp_addon_submission_pending"
+#~ msgstr ""
+#~ "Tämä versio lisäosasta on laitettu hiekkalaatikkoon siksi aikaa kunnes "
+#~ "jokin hiekkalaatikkotestaaja arvioi ja sivuston ylläpitäjä tarkastaa sen. "
+#~ "Lisäosan tilan muutoksista ilmoitetaan sinulle sähköpostitse."
+
+#~ msgid "devcp_addon_submission_sandbox_readmore"
+#~ msgstr "Lue lisää %s."
+
+#~ msgid "devcp_addon_submission_sandbox_readmore_link"
+#~ msgstr "hiekkalaatikon tarkastusjärjestelmästä"
+
+#~ msgid "devcp_addon_submission_sandboxed"
+#~ msgstr ""
+#~ "Tämä versio lisäosasta on laitettu hiekkalaatikkoon vain kokeneille "
+#~ "käyttäjille. Aseta lisäosasi %s, jotta se tarkistettaisiin sivuston "
+#~ "julkiselle puolelle lisäystä varten."
+
+#~ msgid "devcp_addon_submission_sandboxed_nominate_link"
+#~ msgstr "ehdolle"
+
+#~ msgid "devcp_addon_submission_success"
+#~ msgstr "Lisäosasi lisättiin sivustolle."
+
+#~ msgid "devcp_addon_submission_trusted_public"
+#~ msgstr ""
+#~ "Lisäosasi luokitellaan luotettavaksi ja se on automaattisesti hyväksytty "
+#~ "ja lisätty sivuston julkiselle puolelle."
+
+#~ msgid "devcp_addon_submit_pagetitle"
+#~ msgstr "Lähetä lisäosa"
+
+#~ msgid "devcp_addon_updated_successfully"
+#~ msgstr "Lisäosa päivittiin"
+
+#~ msgid "devcp_addon_upload_preview"
+#~ msgstr "Kasvata lisäosasi käyttäjäkuntaa lisäämällä siitä sivulle %s."
+
+#~ msgid "devcp_addon_upload_preview_link"
+#~ msgstr "esikatselukuvia"
+
+#~ msgid "devcp_author_lookup_none_found"
+#~ msgstr "Tekijää ei löytynyt [%s]"
+
+#~ msgid "devcp_author_lookup_remove"
+#~ msgstr "Poista"
+
+#~ msgid "devcp_button_cancel"
+#~ msgstr "Peruuta"
+
+#~ msgid "devcp_button_cancel_confirm"
+#~ msgstr "Peruutetaanko lisäosan lisäys?"
+
+#~ msgid "devcp_button_next"
+#~ msgstr "Seuraava"
+
+#~ msgid "devcp_change_addontype"
+#~ msgstr "Muuta lisäosan tyyppiä:"
+
+#~ msgid "devcp_comments_updated"
+#~ msgstr "Tekijän kommentit päivitettiin."
+
+#~ msgid "devcp_details_addpreview_link"
+#~ msgstr "Lisää esikatselu"
+
+#~ msgid "devcp_details_author"
+#~ msgstr "Tekijä"
+
+#~ msgid "devcp_details_authors"
+#~ msgstr "Tekijät"
+
+#~ msgid "devcp_details_authors_none"
+#~ msgstr "Ei kukaan"
+
+#~ msgid "devcp_details_categories"
+#~ msgstr "Luokat"
+
+#~ msgid "devcp_details_category"
+#~ msgstr "Luokka"
+
+#~ msgid "devcp_details_description"
+#~ msgstr "Kuvaus"
+
+#~ msgid "devcp_details_disabled"
+#~ msgstr "Poistettu käytöstä"
+
+#~ msgid "devcp_details_guid"
+#~ msgstr "GUID"
+
+#~ msgid "devcp_details_header_details"
+#~ msgstr "Lisätiedot"
+
+#~ msgid "devcp_details_header_devcomments"
+#~ msgstr "Tekijän kommentit"
+
+#~ msgid "devcp_details_header_previews"
+#~ msgstr "Esikatselut"
+
+#~ msgid "devcp_details_header_versions"
+#~ msgstr "Versiot"
+
+#~ msgid "devcp_details_homepage"
+#~ msgstr "Kotisivu"
+
+#~ msgid "devcp_details_homepage_none"
+#~ msgstr "Ei mitään"
+
+#~ msgid "devcp_details_preview_nocaption"
+#~ msgstr "Ei kuvatekstiä"
+
+#~ msgid "devcp_details_previews_nonefound"
+#~ msgstr "Ei esikatselukuvia."
+
+#~ msgid "devcp_details_submit_update"
+#~ msgstr "Päivitä"
+
+#~ msgid "devcp_details_supportemail"
+#~ msgstr "Tukisähköpostiosoite"
+
+#~ msgid "devcp_details_supportemail_none"
+#~ msgstr "Tekijä ei ole kirjoittanut tukisähköpostin osoitetta."
+
+#~ msgid "devcp_details_supporturl"
+#~ msgstr "Tukisivu"
+
+#~ msgid "devcp_details_supporturl_none"
+#~ msgstr "Tekijä ei ole kirjoittanut tukisivun osoitetta."
+
+#~ msgid "devcp_details_trusted"
+#~ msgstr "Luotettu"
+
+#~ msgid "devcp_details_versions_none_found"
+#~ msgstr "Versioita ei löytynyt."
+
+#~ msgid "devcp_disable_cancel"
+#~ msgstr "Hylkää ja palaa"
+
+#~ msgid "devcp_disable_disable_button"
+#~ msgstr "Kyllä, poista saatavilta"
+
+#~ msgid "devcp_disable_disable_confirm"
+#~ msgstr "Poistetaanko tämä lisäosa saatavilta?"
+
+#, fuzzy
+#~ msgid "devcp_disable_disable_description"
+#~ msgstr ""
+#~ "Disabling this add-on will hide it from searches and listings. It will "
+#~ "not be downloadable from the website and will not be returned in client "
+#~ "update checks. The add-on will effectively be deleted, although you will "
+#~ "be able to return here and re-enable it at your convenience."
+
+#~ msgid "devcp_disable_disable_title"
+#~ msgstr "Poista %s saatavilta"
+
+#~ msgid "devcp_disable_enable_button"
+#~ msgstr "Kyllä, palauta saataville"
+
+#~ msgid "devcp_disable_enable_confirm"
+#~ msgstr "Palautetaanko lisäosa saataville?"
+
+#, fuzzy
+#~ msgid "devcp_disable_enable_description"
+#~ msgstr ""
+#~ "Enabling this add-on will cause it to once again appear in searches and "
+#~ "listings. It will be downloadable both from the website and from client "
+#~ "update checks."
+
+#~ msgid "devcp_disable_enable_title"
+#~ msgstr "Palauta %s saataville"
+
+#~ msgid "devcp_edit_author_add"
+#~ msgstr "Lisää tekijä"
+
+#~ msgid "devcp_edit_author_email"
+#~ msgstr "Tekijän sähköpostiosoite"
+
+#~ msgid "devcp_edit_author_remove"
+#~ msgstr "Poista"
+
+#~ msgid "devcp_edit_error_categories_unavailable"
+#~ msgstr "Lisäosatyypille ei ole luokkia."
+
+#, fuzzy
+#~ msgid "devcp_edit_file_error_incomplete"
+#~ msgstr "Incomplete transfer"
+
+#, fuzzy
+#~ msgid "devcp_edit_file_error_no"
+#~ msgstr "No file uploaded"
+
+#, fuzzy
+#~ msgid "devcp_edit_file_error_size"
+#~ msgstr "Exceeds maximum upload size"
+
+#~ msgid "devcp_edit_header_authors"
+#~ msgstr "Tekijät"
+
+#~ msgid "devcp_edit_icon_add_link"
+#~ msgstr "Lisää kuvake"
+
+#~ msgid "devcp_edit_icon_change_link"
+#~ msgstr "Muuta kuvaketta"
+
+#~ msgid "devcp_edit_label_allow_viewsource"
+#~ msgstr "Lähdekoodi on käyttäjien tarkasteltavissa"
+
+#~ msgid "devcp_edit_label_categories"
+#~ msgstr "Luokat"
+
+#~ msgid "devcp_edit_label_defaultlocale"
+#~ msgstr "Oletuslokaali"
+
+#~ msgid "devcp_edit_label_icon_delete"
+#~ msgstr "Poista vain nykyinen kuvake"
+
+#~ msgid "devcp_edit_label_icon_new"
+#~ msgstr "Uusi kuvaketiedosto"
+
+#~ msgid "devcp_edit_label_info"
+#~ msgstr "Kuvake"
+
+#~ msgid "devcp_edit_locale_disambiguation_explanation"
+#~ msgstr "lisätietoja lyhyesti (kuten paikallisen murteen nimi)"
+
+#~ msgid "devcp_edit_submit_update"
+#~ msgstr "Päivitä"
+
+#~ msgid "devcp_edit_target_locale_explanation"
+#~ msgstr ""
+#~ "<a href=\"http://wiki.mozilla.org/L10n:Simple_locale_names"
+#~ "\">yksinkertaiset lokaalinimet</a> kuten \"en-US\""
+
+#~ msgid "devcp_editversion_checkedfiles_delete"
+#~ msgstr "Valitut tiedostot poistetaan."
+
+#~ msgid "devcp_editversion_filename_size"
+#~ msgstr "%1$s (%2$s)"
+
+#~ msgid "devcp_editversion_label_files"
+#~ msgstr "Tiedostot"
+
+#~ msgid "devcp_editversion_label_targetapps"
+#~ msgstr "Ohjelmat, johon asennettavissa"
+
+#~ msgid "devcp_editversion_nofiles"
+#~ msgstr "Ei tiedostoja."
+
+#~ msgid "devcp_editversion_reviewernotes"
+#~ msgstr "Huomautuksia tarkastajalle"
+
+#~ msgid "devcp_editversion_submit_update"
+#~ msgstr "Päivitä"
+
+#~ msgid "devcp_error_addon_field_summary_toolong"
+#~ msgstr ""
+#~ "Yhteenveto voi olla enintään 250 merkkiä pitkä.\n"
+#~ "(Kirjoitit %s merkkiä)"
+
+#~ msgid "devcp_error_addonname_not_unique"
+#~ msgstr ""
+#~ "Saman niminen lisäosa on jo tietokannassa. Tarkista, että: <br /"
+#~ "><li>Käytät oikeaa tunnusta (GUID). Sekaannus tunnuksen kanssa on "
+#~ "tavanomainen syy tällaiseen virheeseen.</li><li>Ettet ole lisännyt "
+#~ "lisäosaa kahdesti tietokantaan. Jos näin on käynyt, päivitä vanhaa "
+#~ "merkintää tai poista se ja yritä uudelleen.</li>"
+
+#~ msgid "devcp_error_describe_changes"
+#~ msgstr "Kuvaile lisäosaan tehtyjä päivityksiä."
+
+#~ msgid "devcp_error_file_guids_dont_match"
+#~ msgstr "Kaikkien tiedostojen GUID:t eivät täsmää"
+
+#~ msgid "devcp_error_identical_version_exists"
+#~ msgstr "Identtinen versio (%s) lisäosasta tällä alustalla on jo olemassa."
+
+#
+#~ msgid "devcp_error_nominate_message"
+#~ msgstr "Pyydetyt tiedot täytyy antaa asetettaessa lisäosaa ehdolle."
+
+#~ msgid "devcp_error_nominate_no_prerelease"
+#~ msgstr ""
+#~ "Et voi ehdottaa lisäosan esijulkaisuversioita sivuston julkiselle "
+#~ "puolelle."
+
+#~ msgid "devcp_error_nominate_sandbox_only"
+#~ msgstr ""
+#~ "Voit asettaa ehdolle ainoastaan lisäosia, jotka ovat hiekkalaatikossa."
+
+#~ msgid "devcp_error_saving"
+#~ msgstr "Tietojen tallennus ei onnistunut."
+
+#~ msgid "devcp_error_update_access_denied"
+#~ msgstr "Sinulla ei ole oikeutta päivittää lisäosan tietoja."
+
+#~ msgid "devcp_file_addanother"
+#~ msgstr "Lisää alustakohtainen tiedosto"
+
+#~ msgid "devcp_form_author_add"
+#~ msgstr "Lisää tekijä"
+
+#~ msgid "devcp_form_author_remove"
+#~ msgstr "Poista"
+
+#~ msgid "devcp_form_categories_nextstep"
+#~ msgstr ""
+#~ "Voit asettaa uudelle lisäosalle sopivat luokat seuraavassa kohdassa."
+
+#~ msgid "devcp_form_error_categories_unavailable"
+#~ msgstr "Lisäosatyypille ei ole luokkia."
+
+#~ msgid "devcp_form_error_description_notempty"
+#~ msgstr "Kirjoita kuvaus lisäosasta."
+
+#~ msgid "devcp_form_error_name_required"
+#~ msgstr "Kirjoita lisäosan nimi."
+
+#~ msgid "devcp_form_error_select_addontype"
+#~ msgstr "Valitse lisäosan tyyppi."
+
+#~ msgid "devcp_form_error_summary_notempty"
+#~ msgstr "Kirjoita yhteenveto lisäosasta."
+
+#~ msgid "devcp_form_label_addonfile"
+#~ msgstr "Lisäosatiedosto"
+
+#~ msgid "devcp_form_label_addonfile2"
+#~ msgstr "2. lisäosatiedosto"
+
+#~ msgid "devcp_form_label_addonfile3"
+#~ msgstr "3. lisäosatiedosto"
+
+#~ msgid "devcp_form_label_addontype"
+#~ msgstr "Lisäosan tyyppi"
+
+#~ msgid "devcp_form_label_allow_viewsource"
+#~ msgstr "Lisäosan lähdekoodi on käyttäjien luettavissa"
+
+#~ msgid "devcp_form_label_author_email"
+#~ msgstr "Tekijän sähköpostiosoite"
+
+#~ msgid "devcp_form_label_authors"
+#~ msgstr "Tekijät"
+
+#~ msgid "devcp_form_label_categories"
+#~ msgstr "Luokat"
+
+#~ msgid "devcp_form_label_defaultlocale"
+#~ msgstr "Oletuslokaali"
+
+#~ msgid "devcp_form_label_description"
+#~ msgstr "Kuvaus"
+
+#~ msgid "devcp_form_label_eula"
+#~ msgstr "Loppukäyttäjän lisenssisopimus (EULA)"
+
+#~ msgid "devcp_form_label_externalsoftware"
+#~ msgstr ""
+#~ "Lisäosa tarvitsee toimiakseen erikseen jaeltavan, itsenäisen ohjelman"
+
+#~ msgid "devcp_form_label_files"
+#~ msgstr "Tiedostot"
+
+#~ msgid "devcp_form_label_homepage"
+#~ msgstr "Kotisivu"
+
+#~ msgid "devcp_form_label_iconfile"
+#~ msgstr "Kuvaketiedosto"
+
+#~ msgid "devcp_form_label_name"
+#~ msgstr "Nimi"
+
+#~ msgid "devcp_form_label_platforms"
+#~ msgstr "Tuetut alustat"
+
+#~ msgid "devcp_form_label_prerelease"
+#~ msgstr "Tämä on esijulkaisuversio"
+
+#~ msgid "devcp_form_label_privacy"
+#~ msgstr "Tietosuojakäytäntö"
+
+#~ msgid "devcp_form_label_sitespecific"
+#~ msgstr "Lisäosa on sivustokohtainen"
+
+#~ msgid "devcp_form_label_summary"
+#~ msgstr "Yhteenveto"
+
+#~ msgid "devcp_form_label_supportemail"
+#~ msgstr "Tukisähköpostiosoite"
+
+#~ msgid "devcp_form_label_supporturl"
+#~ msgstr "Tukisivu"
+
+#~ msgid "devcp_form_label_target_applications"
+#~ msgstr "Ohjelmat, joihin asennettavissa"
+
+#~ msgid "devcp_form_label_version"
+#~ msgstr "Versio"
+
+#~ msgid "devcp_form_label_versionnotes"
+#~ msgstr "Versiotiedot"
+
+#~ msgid "devcp_form_no_target_apps"
+#~ msgstr "Ei mitään"
+
+#~ msgid "devcp_form_reviewernotes"
+#~ msgstr "Huomautuksia lisäosan tarkastajalle"
+
+#~ msgid "devcp_form_trustedaddon_destination"
+#~ msgstr "Lisäosasi on luotettu. Valitse lisäosan sijainti sivustolla:"
+
+#~ msgid "devcp_form_trustedaddon_destination_public"
+#~ msgstr "Julkinen"
+
+#~ msgid "devcp_form_trustedaddon_destination_sandbox"
+#~ msgstr "Hiekkalaatikko"
+
+#~ msgid "devcp_header_developer_agreement"
+#~ msgstr "Kehittäjäsopimus"
+
+#~ msgid "devcp_header_step1"
+#~ msgstr "1. kohta"
+
+#~ msgid "devcp_header_step1_upload"
+#~ msgstr "Tiedostonsiirto"
+
+#~ msgid "devcp_header_step2"
+#~ msgstr "2. kohta"
+
+#~ msgid "devcp_header_step2_addondetails"
+#~ msgstr "Lisäosan tiedot"
+
+#~ msgid "devcp_header_step3"
+#~ msgstr "3. kohta"
+
+#~ msgid "devcp_header_step3_versiondetails"
+#~ msgstr "Versiotiedot"
+
+#~ msgid "devcp_header_step4"
+#~ msgstr "4. kohta"
+
+#~ msgid "devcp_header_step4_localization"
+#~ msgstr "Lokalisointi"
+
+#~ msgid "devcp_header_step5"
+#~ msgstr "5. kohta"
+
+#~ msgid "devcp_header_step5_success"
+#~ msgstr "Onnellinen loppu"
+
+#~ msgid "devcp_index_header_myaddons"
+#~ msgstr "Lisäosani"
+
+#~ msgid "devcp_nominate_link_returnto_details"
+#~ msgstr "Palaa lisäosan tietoihin"
+
+#~ msgid "devcp_notice_autodetected_addontype"
+#~ msgstr "Automaattisesti tunnistettu lisäosatyyppi: %s."
+
+#~ msgid "devcp_notice_different_defaultlocale"
+#~ msgstr ""
+#~ "Tämän lisäosan oletuslokaali, eli kieli- ja maa-asetus, (%1$s [%2$s]) "
+#~ "eroaa käytössä olevasta lokaalista (%3$s [%4$s]). Lisäosan kuvaus tulee "
+#~ "täyttää kielellä \"%1$s\"."
+
+#~ msgid "devcp_question_addontype_incorrect"
+#~ msgstr "Virheellinen?"
+
+#~ msgid "devcp_question_delete_file"
+#~ msgstr "Poistetaanko tiedosto?"
+
+#~ msgid "devcp_skip_reviewing_addon_info"
+#~ msgstr "Ohita lisäosan tietojen tarkistaminen"
+
+#~ msgid "devcp_submissions_disabled"
+#~ msgstr "Lisäosia ei juuri nyt voi lähettää. Kokeile myöhemmin uudestaan."
+
+#~ msgid "devcp_submit_accept_dev_agreement"
+#~ msgstr "Hyväksyn"
+
+#~ msgid "devcp_submit_decline_dev_agreement"
+#~ msgstr "En hyväksy"
+
+#~ msgid "devcp_summary_admin_disabled"
+#~ msgstr "Ylläpito on poistanut tämän lisäosan käytöstä."
+
+#~ msgid "devcp_summary_header_disabled"
+#~ msgstr "Poistettu käytöstä"
+
+#~ msgid "devcp_summary_header_trusted"
+#~ msgstr "Luotettu"
+
+#~ msgid "devcp_summary_noaddons_submit_one"
+#~ msgstr "Sinulla ei ole yhtään lisäosia. %s."
+
+#~ msgid "devcp_summary_noaddons_submit_one_link"
+#~ msgstr "Lisää sellainen"
+
+#~ msgid "devcp_theme_upload_preview"
+#~ msgstr "%s teemastasi."
+
+#~ msgid "devcp_theme_upload_preview_link"
+#~ msgstr "Siirräthän esikatselukuvan"
+
+#~ msgid "devcp_version_edit_pagetitle"
+#~ msgstr "Muokkaa versiota"
+
+#~ msgid "devcp_version_updated_successfully"
+#~ msgstr "Versio päivitettiin."
+
+#~ msgid "editors_submissiontype_new"
+#~ msgstr "Uusi"
+
+#~ msgid "editors_submissiontype_updated"
+#~ msgstr "Päivitetty"
+
+#, fuzzy
+#~ msgid "editors_th_addon_age"
+#~ msgstr "Addon Age"
+
+#~ msgid "editors_th_addontypes"
+#~ msgstr "Lisäosatyypit"
+
+#~ msgid "editors_th_age"
+#~ msgstr "Ikä"
+
+#~ msgid "editors_th_applications"
+#~ msgstr "Ohjelmat"
+
+#~ msgid "editors_th_platforms"
+#~ msgstr "Alustat"
+
+#~ msgid "editors_th_submissiontypes"
+#~ msgstr "Lähetystyyppi"
+
+#~ msgid "error_notice"
+#~ msgstr "Huomautus"
+
+#~ msgid "forum_save"
+#~ msgstr "Tallenna"
+
+#, fuzzy
+#~ msgid "home"
+#~ msgstr "home"
+
+#, fuzzy
+#~ msgid "nav_category_plugins"
+#~ msgstr "Plugins"
+
+#, fuzzy
+#~ msgid "page_title_experimental_addons"
+#~ msgstr "Experimental Add-ons"
+
+#, fuzzy
+#~ msgid "pages_experimental_addons_backbutton"
+#~ msgstr "Back to the previous page"
+
+#~ msgid "pagination_page_number_title"
+#~ msgstr "Tämä on sivu %1$s / %2$s"
+
+#~ msgid "search_matching_addons_number"
+#~ msgid_plural "search_matching_addons_number"
+#~ msgstr[0] "%s vastaava lisäosa"
+#~ msgstr[1] "%s hakua vastaavaa lisäosaa"
+
+#~ msgid "statistics_rss_icon_title"
+#~ msgstr "RSS-syöte yhteenvedosta"
diff --git a/site/app/locale/fi/images/sandbox-review.png b/site/app/locale/fi/images/sandbox-review.png
new file mode 100644
index 0000000..ab0b8af
--- /dev/null
+++ b/site/app/locale/fi/images/sandbox-review.png
Binary files differ
diff --git a/site/app/locale/fi/pages/error404.thtml b/site/app/locale/fi/pages/error404.thtml
new file mode 100644
index 0000000..6635ace
--- /dev/null
+++ b/site/app/locale/fi/pages/error404.thtml
@@ -0,0 +1,16 @@
+<h1>Hakemaasi sivua ei löytynyt.</h1>
+
+<p>Sivua, jota pyysit, ei löydy palvelimeltamme. Ehkä napsauttamasi linkki oli vanhentunut tai teit kirjoitusvirheen kirjoittaessasi osoitetta.</p>
+
+<ul>
+<li>Tarkista osoite kirjoitusvirheiden varalta jos kirjoitit sen itse.</li>
+<li>Jos napsautit linkkiä jollain toisella sivulla, kerro siitä meille osoitteeseen <a href="mailto:webmaster@mozilla.com" title="Page Not Found on Mozilla.com">webmaster@mozilla.com</a>. Kerro meille englanniksi, miltä sivulta olit tulossa sekä mitä olit hakemassa ja yritämme parhaamme mukaan korjata vian.</li>
+</ul>
+
+<p>Vaihtoehtoisesti voit avata jonkin seuraavista sivustomme suosituista sivuista.</p>
+
+<ul>
+<li>Haluatko nähdä listamme <a href="%1$s">suosituista lisäosista</a>?</li>
+<li>Haluatko <a href="%2$s">etsiä lisäosaa</a>? Siirry <a href="%2$s">hakusivullemme</a> tai käytä alla olevaa hakukenttää.</li>
+<li>Jos haluat aloittaa alusta, siirry <a href="%3$s">lisäosasivustomme etusivulle</a>.</li>
+</ul>
diff --git a/site/app/locale/fi/pages/nomination.thtml b/site/app/locale/fi/pages/nomination.thtml
new file mode 100644
index 0000000..365fdab
--- /dev/null
+++ b/site/app/locale/fi/pages/nomination.thtml
@@ -0,0 +1,8 @@
+<p>Hiekkalaatikossa olevaa lisäosaa voidaan ehdottaa siirrettäväksi sivuston julkiselle puolelle ja kaikkien sivustolla käyvien saataville. Ennen siirtoa jokin sivuston toimittajista tarkistaa lisäosan seuraavien kriteerien mukaisesti:</p>
+<ul>
+ <li>Teemoista tulee olla esikatselukuva. Kuvia suositellaan myös kaikille muille lisäosille.</li>
+ <li>Lisäosan pitäisi ennen ehdolle asettamista viettää hiekkalaatikossa niin kauan aikaa, että siitä on käyttäjien arvosteluja ja palautetta.</li>
+ <li>Julkisten lisäosien laatuvaatimukset ovat korkeammat kuin hiekkalaatikon lisäosien ja niiden vaikutuksen webbiin tulisi olla positiivinen.</li>
+ <li>Täydelliset ehdolle asettamisen kriteerit ovat luettavissa <a href="%s">lisäosakäytännöstä</a>.</li>
+</ul>
+<p>Jos lisäosasi täyttää yllä olevat ehdot, voit ehdottaa sitä sivuston julkiselle puolelle napsauttamalla alla olevaa painiketta. Saat sähköpostitse ilmoituksen ehdolle asettamisen tilassa tapahtuneista muutoksista.</p>
diff --git a/site/app/locale/fi/pages/policy.thtml b/site/app/locale/fi/pages/policy.thtml
new file mode 100644
index 0000000..b7567ee
--- /dev/null
+++ b/site/app/locale/fi/pages/policy.thtml
@@ -0,0 +1,110 @@
+<h1>Lisäosakäytäntö</h1>
+
+<h2>Mikä on hiekkalaatikko?</h2>
+<p>Lue lisää %s.</p>
+
+<h2>Mitkä lisäosat ovat hiekkalaatikossa?</h2>
+<p>Kaikki AMO:on (Mozilla-lisäosiin) lähetetyt lisäosat ovat aluksi hiekkalaatikossa. Hiekkalaatikossa on sivuston julkisella puolella olevien lisäosien uudet, testaamattomat versiot ja lisäosat, joita ei ole vielä siirretty julkiselle puolelle. Kun lisäosa lähetetään sivustolle tai päivitetään se siis menee hiekkalaatikkoon.</p>
+
+<p>Jotkin lisäosat ja niiden jotkin versiot siirretään sivuston julkiselle puolelle kun ne on testattu ja tarkastettu yleiseen käyttöön sopivaksi. Toiset lisäosat eivät ikinä poistu hiekkalaatikosta, mutta ovat kuitenkin siellä edistyneiden käyttäjien saatavilla.</p>
+
+<h2>Miten lisäosat siirtyvät julkiselle puolelle?</h2>
+
+<p>Hiekkalaatikon lisäosia voivat testata ja arvostella käyttäjät, jotka ovat asettaneet hiekkalaatikon näkymään asetuksistaan. Tällaisten käyttäjien kirjoittamat arvostelut kertovat sivuston toimittajille, onko lisäosa hyödyllinen, hyvin kirjoitettu ja täyttääkö se muut laatuvaatimukset sivuston julkiselle puolelle oleville lisäosille. Arvostelujen ja muiden mahdollisten tarkastusten perusteella ylläpito päättää tulisiko jokin lisäosa siirtää sivuston julkiselle puolelle vai tuleeko sitä vielä parantaa joillain tavoin.</p>
+
+<h2>Kuinka saan lisäosani siirretyksi sivuston julkiselle puolelle?</h2>
+
+<p>Jos uskot lisäosasi (ja oman toimintasi!) täyttävän julkisen puolen vaatimukset, voit ehdottaa lisäosaasi kehittäjien ohjauspaneelista.</p>
+
+<h2>Mitkä ovat julkisen puolen lisäosien kriteerit?</h2>
+
+<p>Julkiselle puolelle siirrettävän lisäosan tulisi olla korkealaatuinen ja parantaa käyttäjiensä selaamiskokemusta. Tarkastelemme erikseen seuraavia laatutekijöitä:</p>
+
+<h3>Vastaatko kyselyihin?</h3>
+
+<p>Odotamme AMO:ssa Mozilla-ohjelmien käyttäjäkunnalle lisäosaansa tarjoavan tekijän vastaavan käyttäjien raportoimiin ongelmiin, pitävän yhteystietonsa ajan tasalla ja päivittävän lisäosaansa uusien Mozilla-ohjelmaversioiden julkaisujen yhteydessä tai kun AMO:n käytännöt tai vaatimukset muuttuvat. Tämä ei tarkoita, että sinun tulee vastata jokaiseen käyttäjän esittämään kysymykseen tai, että sinun tulisi korjata jokainen raportoitu ohjelmavirhe. Odotamme sinun vain suhtautuvan kysymyksiin asiallisesti ja esitetyn ongelman vakavuuden mukaisesti.</p>
+
+<h3>Onko lisäosan kuvaus selkeä ja todenmukainen?</h3>
+
+<p>On erittäin tärkeää, että käyttäjien odotukset vastaavat tarjottua lisäosaa. Lisäosan kuvauksen pitäisi selventää, mitä lisäosa tekee, kuinka sitä käytetään ja mitä käyttäjä voi odottaa lisäosan asentamisen jälkeen. Linkit muille sivuille on sallittu, mutta kuvauksen pitäisi selvittää käyttäjälle välttämättömät tiedot ja sen, mitä odottaa.</p>
+
+<p>Riittävän seikkaperäisten versiotietojen eli muutoslokien pitäminen on myös tärkeää. Käyttäjien tulisi voida nähdä, mitä muutoksia lisäosan eri versioiden välillä on ja heille tulisi tehdä selväksi jos, ja miten, uuden version asentaminen muuttaa heidän käyttökokemustaan. (Käyttäjät eivät vielä näe versiotietoja päivittäessään lisäosaa selaimesta, mutta pyrimme muuttamaan tämän. Jos pidät versiotiedot hyvin ajan tasalla, lisäosasi käyttäjät hyötyvät siitä myöhemminkin.)</p>
+
+<h3>Esitetäänkö kaikki tietosuoja- ja turvallisuuskysymykset selkeästi?</h3>
+
+<p>Tässä on kysymys selkeästä ja tarkasta kuvauksesta niin tärkeällä osa-alueella, että haluamme erikseen painottaa sitä. Useat erittäin hyödylliset ja hyvin kirjoitetut lisäosat käyttävät hyväkseen joitain käyttäjätietoja tai voivat vaarantaa käyttäjän tietosuojan jos niitä käytetään väärin. Tällaiset lisäosat ovat tervetulleita AMO:n julkiselle puolelle jos niiden kuvauksesta selviää käyttäjälle lisäosan mahdolliset riskit ja miten käyttäjä voi välttää näitä riskejä.</p>
+
+<h3>Onko lisäosaa testattu riittävästi ja onko siinä nähtävissä selkeitä ja vakavia puutteita?</h3>
+
+<p>Tärkeä tekijä arvioitaessa, onko lisäosa valmis siirrettäväksi sivuston julkiselle puolelle, on sen hiekkalaatikossa saamien arvostelujen määrä ja laajuus. Muun muassa näiden perusteella päättelemme, onko lisäosaa testattu riittävästi ja onko lisäosa riittävän vakaa ja ilman suuria ongelmia. Jos arvostelijat kertovat merkittävistä hidastumisista, toistuvista ongelmista, kaatumisista tai ryppäistä virheilmoituksia virhekonsolissa, sinun tulisi ottaa nämä tiedot tosissasi ja ehdottaa lisäosaa julkiseksi vasta kun suurimmista ongelmista on päästy. Emme odota lisäosan olevan täydellinen nopeudessaan tai virheetön (eivät omat ohjelmammekaan ole), mutta haluamme, että pyrit minimoimaan lisäosan negatiiviset puolet ja kertomaan avoimesti kohdista ja asioista jotka vielä tarvitsevat lisähuomiota.</p>
+
+<p>Kerro lisäosan ehdottamispyynnössä jos lisäosaasi on testattu AMO:n hiekkalaatikon ulkopuolella esimerkiksi ohjelmistotalosi laadunvarmennustiimin tai lisäosasi olemassa olevien käyttäjien puolesta. Tällainen tieto auttaa meitä ymmärtämään tehdyn testauksen laatu ja mahdollisesti parantaa lisäosasi saumoja päästä sivuston julkiselle puolelle.</p>
+
+<h3>Kohteleeko lisäosa ja lisäosan tekijä käyttäjiään kunnioittavasti?</h3>
+
+<p>Lisäosasi ei tulisi häiritä käyttäjää tarpeettomasti, huijata käyttäjää tai peittää tekemisiään käyttäjältä. Käyttäjät (ja jopa ei-käyttäjät) antavat joskus epäasiallisia kommentteja ja vaikka pyrimme poistamaan tällaiset kommentit, odotamme lisäosan tekijöiden pitävän kielensä kurissa vaikka käyttäjät käyttäytyisivätkin sopimattomasti.</p>
+
+<h3>Onko lisäosa hyödyllinen merkittävälle osalle Firefoxin käyttäjäkuntaa?</h3>
+
+<p>Julkisella puolella olevan lisäosan ei täydy olla uusi Greasemonkey tai FireBug, mutta jos se on hyödyllinen vain yrityksesi henkilöstölle tai pienelle nettiyhteisölle, emme ehkä näe asianmukaiseksi asettaa lisäosaa kaikkien Firefox-käyttäjien eteen.</p>
+
+<p>Pyrimme jatkuvasti kehittämään sivuston rakennetta niin, että se pystyisi paremmin palvelemaan lisäosia, jotka ovat hyödyllisiä vain pienille käyttäjäryhmille. Lisäosasi tarkka luokittelu ja sen tietojen ylläpito auttavat meitä keksimään tapoja tuoda esille vastaavanlaisia lisäosia niille ihmisille, joille ne on tarkoitettu.</p>
+
+<p>Jos lisäosasi tarjoaa vain kirjanmerkkejä tai vastaavia sivuston löytämistä helpottavia lisiä, sen paikka ei todennäköisesti ole AMO:n julkisella puolella. Niin kuin Mozilla-projekti yleensäkin, pidämme AMO:ssa web-ohjelmia ja uusia web-palveluja tärkeinä asioina, mutta pelkästään tietyn palvelun tai sivuston mainostaminen ei mielestämme edistä näitä asioita. Jos lisäosasi kuvaus kertoo enemmän palvelusta, johon sillä pääsee käsiksi kuin sen parannuksista käyttäjän selauskokemukseen, olet AMO:ssa luultavasti hakoteillä .</p>
+
+<h3>Onko lisäosassa luvatta muiden tavaramerkkejä tai tekijänoikeuden alaisia osia?</h3>
+
+<p>Vaikka tarkoituksesi ei ole aiheuttaa tappiota tavaramerkin tai tekijänoikeuden omistajalle, emme voi jaella sivustoiltamme materiaalia, joka rikkoo tekijänoikeuksia. Jos sinulla ei ole oikeutta käyttää lisäosassasi käytettyä tavaramerkkiä, älä lähetä sitä AMO:on. Jos osia lisäosasi koodista on tekijänoikeuden mukaan toisten etkä sinulla ole lupaa käyttää koodia, älä lähetä lisäosaasi AMO:on. (Jos tavaramerkin tai tekijänoikeuden haltija vastustaa niiden käyttöä joudumme luultavasti tarkistuttamaan poistopyynnön asianajajallamme ja jos pyyntö todetaan aiheelliseksi, poistamme lisäosan sivustolta. Tämä prosessi vie huomattavasti projektin aikaa ja rahaa ja toivomme siksi, että kunnioitat toisten omaisuutta etkä aiheuta meille tarpeettomia vaikeuksia.)</p>
+
+<p>Jos et ole varma voisiko lisäosasi nimestä tai jostain sen osasta aiheutua ongelmia, jotka estävät sen lisäämisen sivustolle, kysy opastusta sähköpostiosoitteesta amo-editors@mozilla.org. HUOM.: Emme kykene tarjoamaan tästä osoitteesta opastusta lakiasioissa ja vaikka pitäisimmekin lisäosaasi täysin hyväksyttävänä, voimme muuttaa päätöstämme oikeudenhaltijoiden valitusten myötä.</p>
+
+<p>Muiden lisäosien koodia tulee kohdella kuten muidenkin ohjelmien koodia. Jos lisäosan tekijä ei erikseen anna lupaa koodin käyttämiseen johdannaisissa teoksissa, esimerkiksi lisensoimalla työtä avoimen lähdekoodin lisenssillä, sinulla ei ole oikeutta käyttää lisäosan koodia. Voit toki aina ottaa yhteyttä lisäosan tekijään ja pyytää tällaista lupaa, mutta lisäosan julkisuus AMO:ssa ei anna tällaista lupaa kuten ei myöskään se, että lisäosan tekijä ei vastaa kyselyihin. (Emme tässäkään tapauksessa kykene antamaan opastusta lakiasioissa vaan ainoastaan, kuinka hyvin lisäosa noudattaa sivuston käytäntöjä.)</p>
+
+<p>Edellä oleva pätee myös Mozilla-säätiön tavaramerkkeihin. Säätiön omaisuutta ovat mm. "Mozilla", "Firefox", ja "Thunderbird" -tavaramerkit. Mozillan tavaramerkkikäytäntö on suunniteltu suojelemaan käyttäjiä sekaannuksilta ja pitämään tavaramerkki säätiön omaisuutena. Toivomme, että kunnioitat tätä käytäntöä ja autat Mozilla-säätiötä pitämään kiinni yhdestä sen arvokkaimmasta omaisuudesta.</p>
+
+<h2>Mitä tapahtuu kun olen asettanut lisäosan ehdolle?</h2>
+
+<p>Kun lisäosasi on ehdolla julkiselle puolelle sitä arvioi AMO:n toimittajatiimi aiemmin kuvailtujen kriteerien mukaan. Jos lisäosan arvioidaan olevan valmis julkiselle puolelle, se siirretään julkiselle puolelle arvioinnin jälkeen. Saat sähköpostin, jossa ilmoitetaan päätöksestä.</p>
+
+<p>Jos tulemme siihen lopputulokseen, että lisäosa ei ole tällä hetkellä julkisen puolen vaatimusten mukainen, saat sähköpostin, jossa kerromme perustelut päätökselle. Voit halutessasi ehdottaa lisäosaa uudelleenarvioitavaksi jos ja kun olet mielestäsi ottanut toimittajiemme kommentit huomioon. Toistuvia ehdolle asetuksia ilman merkittäviä muutoksia lisäosassa ei katsota hyvällä. Toimittajat todennäköisemmin ärsyyntyvät jatkuviin ehdolle asettamisiin kuin antavat lopulta periksi.</p>
+
+<h2>Voinko asettaa jonkun toisen tekemän lisäosan ehdolle?</h2>
+
+<p>Pyydämme tällä hetkellä, että lisäosan tekijä itse asettaa lisäosansa ehdolle. Näin pyrimme varmistamaan, että tekijä itse haluaa sivuston julkiselle puolelle siirtymisen mahdollisesti mukanaan tuoman lisähuomion ja on sitä mieltä, että lisäosa on kirjoittajaansa edustavassa kunnossa. Jos uskot, että jokin lisäosa on loppuun asti viimeistelty, tekijä seuraa lisäosakäytäntöjen henkeä ja kirjainta ja että lisäosa hyödyttäisi lukemattomia Mozilla-käyttäjiä ja nettiä yleensäkin, olisi ehkä paikallaan, että kertoisit mielipiteesi lisäosan tekijälle ja kannustaisit häntä ehdottamaan luomustaan julkiselle puolelle.</p>
+
+<h2>Lisäosani on seissyt ehdotettujen lisäosien jonossa jo kauan. Vihaatteko minua vai missä on vika?</h2>
+
+<p>Emme vihaa sinua vaan päinvastoin rakastamme kaikkia lisäosakehittäjiä. Pyrimme parhaimman mukaamme pitämään heidät onnellisina ja tuotteliaina, jotta käyttäjämme ympäri maailman voivat hyötyä heidän töiden hedelmistä. AMO:n julkisen puolen arvo on kuitenkin juuri siinä, että pidämme tarkkaa lukua lisäosista, jotka pääsevät sinne, jonka takia emme voi kiirehtiä hyväksymisprosessin kanssa. Ymmärrämme, että ratkaisun odottaminen voi olla turhauttavaa ja teemme kaikkemme, jotta hyväksymisprosessi ei viivästyisi tarpeettomasti. Mitä useampi ihminen kirjoittaa hiekkalaatikossa oleville lisäosista tarkkoja ja asiantuntevia arvosteluja, sitä helpompaa on tehdä kokonaisarviointi lisäosan tilasta. Jos haluat voit siis auttaa meitä urakassamme kirjoittamalla arvosteluja muiden lisäosista.</p>
+
+<h2>Havaitsin vakavan bugin lisäosassani ja haluan saada korjatun version sivustolle pikimmiten. Mitä minun tulisi tehdä?</h2>
+
+<p>Jos lisäosassa on vakava bugi (turvallisuus-, vakaus- tai esimerkiksi keskeinen toiminnallisuusbugi) ja lisäosan korjattu versio pitäisi saada julkaistua pikaisesti, sinun pitää mainita tästä "huomautuksia tarkastajalle" -kentässä lisätessäsi päivitystä lisäosalle. Muista mainita asia myös versiotiedoissa! Voit myös yrittää saada joitain lisäosan nykyisiä käyttäjiä testaamaan päivitettyä versiota ja kertomaan kokemuksistaan nopeuttaaksesi hyväksymisprosessia. Irc.mozilla.orgin #addons-kanavalla pyörähtäminen ja asiasta kertominen voi auttaa asiaasi, mutta muista aina silloin olla kärsivällinen ja käyttäytyä asiallisesti.</p>
+
+<p>Ole rehellinen! Yritämme hoitaa vikkelästi tärkeät päivitykset, mutta niiden arvioimiseen käytetty aika on pois muilta lisäosilta, aiheuttaa usein univelkaa ja perheemme tai ystäviemme laiminlyöntiä. Emme siis arvosta kehittäjiä, jotka yrittävät tällä tavalla etuilla jonossa. Jos et ole varma, onko päivityksen kiirehtiminen paikallaan, kysyminen siitä #addons-kanavalla voi auttaa.
+
+<h2>Mielestäni lisäosani tarkastus ei sujunut reilusti. Mitä minun pitäisi tehdä?</h2>
+
+<p>Jos uskot, että lisäosasi arvioitiin virheellisesti eikä sitä virheellisesti hyväksytty julkiselle puolelle, sinun tulee lähettää sähköpostia osoitteeseen amo-editors@mozilla.org ja esittää asiasi (englanniksi). Muista olla kohtelias, esittää asiasi mahdollisimman selkeästi ja antaa yksityiskohtia tehdyistä virheistä.</p>
+
+<p>(Jos olet korjannut *kaikki* asiat, joista päätössähköpostissa huomautettiin, älä pyydä päätöksen uudelleenarviointia vaan aseta lisäosasi uudestaan ehdolle kehittäjien ohjauspaneelista.)</p>
+
+<h2>Lisäosani oli ennen julkisella puolelle, mutta on nyt hiekkalaatikossa. Mitä on tapahtunut?</h2>
+
+<p>Jos lisäosa ei enää tyydytä julkisella puolella olevien lisäosien kriteerejä, voimme siirtää sen takaisin hiekkalaatikkoon. Ilmoitamme siirrosta sinulle siihen johtaneen syyn kera sähköpostitse elleivät lakisyyt estä meitä tekemästä niin.</p>
+
+<p>On myös mahdollista, että olet löytänyt bugin sivuston toiminnassa. Tässä tapauksessa sinun tulisi raportoida siitä Bugzillaan. Käytä tuotetta "addons.mozilla.org" ja komponenttia "Public Pages" ja kerro mahdollisimman tarkasti, mitä tapahtui (englanniksi).</p>
+
+<h2>Lisäosani on julkisella puolella ja ihmiset näyttävät pitävän siitä. Kuinka saan lisäosan suositeltujen lisäosien listaan?</h2>
+
+<p>Jos olet vakaa uskossasi, että lisäosasi on loistoesimerkki kaikesta mikä on hienoa lisäosissa, että se tukee ja on Mozillan arvojen mukainen ja että siitä saatava käyttäjäkokemus on kaikin puolin hyvä voit ehdottaa sitä listalle. Kirjoita lisäosasi ansioista ja perustelusi osoitteeseen amo-editors@mozilla.org.</p>
+
+<p>Sähköpostisi tulisi sisältää tietoa <b>ainakin</b> seuraavista seikoista:</p>
+<ul>
+<li>kuinka lisäosa parantaa käyttäjien web-kokemusta</li>
+<li>lisäosasi sopivuudesta suurelle osaa Firefoxin käyttäjiä</li>
+<li>kuinka lisäosasi tuo esille tai palvelee Mozilla-projektin arvoja painottaen erityisesti pyrkimystä mahdollistaa käyttäjää ottamaan selauskokemus haltuunsa, tietosuojaa ja -turvallisuutta, universaalia yhteyttä webbiin sekä avoimia standardeja ja dataa</li>
+<li>mitä eroa lisäosasi ja muiden vastaavien lisäosien kanssa on (hyvässä ja huonossa mielessä)</li>
+<li>käyttäjien ja arvostelijoiden positiiviset ja negatiiviset reaktiot</li>
+</ul>
+
+<p>Mitä täydellisemmin vastaat yllä oleviin kysymyksiin sitä luultavammin myönnämme listauksen, vaikkei toki pelkkä täydellinen vastaus takaakaan pääsyä suositeltujen lisäosien listalle. Loppupeleissä listaa ylläpitää ja sen sisällöstä päättää Mozilla, jonka päätökseen vaikuttaa eniten käyttäjien kokemukset ja heidän intressien suojelu.</p>
diff --git a/site/app/locale/fi/pages/sandbox.thtml b/site/app/locale/fi/pages/sandbox.thtml
new file mode 100644
index 0000000..8378d22
--- /dev/null
+++ b/site/app/locale/fi/pages/sandbox.thtml
@@ -0,0 +1,13 @@
+<h1>Hiekkalaatikon tarkistusjärjestelmä</h1>
+<h2>Mikä on hiekkalaatikko?</h2>
+<p>Hiekkalaatikko on alue, jossa edistyneet käyttäjät voivat testata uusia lisäosia ennen kuin sivuston toimittaja tarkastaa niiden sopivuuden yleiseen käyttöön. Hiekkalaatikkoon pääsee käsiksi ottamalla sen käyttöön tiliasetuksista. Hiekkalaatikossa olevien lisäosien asentamisessa tulisi olla varovainen, koska niitä ei ole tarkastettu ja ne voivat vahingoittaa tietokonettasi.</p>
+
+<h2>Kuinka saan lisäosani siirrettyä sivuston julkiselle puolelle?</h2>
+<!-- To localize the flowchart image, see http://wiki.mozilla.org/Update:Remora_Sandbox_Flowchart -->
+<div style="text-align: center;">%s</div>
+<ol>
+ <li><b>Lähetä lisäosasi kehittäjien ohjauspaneelista.</b> Lisäosasi ilmestyy välittömästi "hiekkalaatikko"-puolelle Mozilla-lisäosissa ja edistyneet käyttäjät pääsevät testaamaan ja antamaan siitä palautetta. Pääset itse hiekkalaatikkoon ottamalla sen käyttöön tilisi asetuksista.</li>
+ <li><b>Ehdota lisäosaasi julkiselle puolelle.</b> Kehittäjien ohjauspaneelissa on linkki sivulle, josta voit ehdottaa lisäosaasi julkiselle puolelle. Ehdotuksen jälkeen lisäosasi odottaa tarkastusta toimittajien tarkastusjonossa.</li>
+ <li><b>Toimittaja tarkastaa ja arvioi lisäosasi.</b> Mozillan lisäosatoimittaja asentaa lisäosasi ja testaa sen toiminnan. Toimittaja lukee myös hiekkalaatikon testaajien lisäosasta antamat arvostelut.</li>
+ <li><b>Lisäosasi siirretään julkiselle puolelle tai jätetään hiekkalaatikkoon.</b> Toimittaja joko hyväksyy ehdotuksen siirtää lisäosa julkiselle puolelle tai päättää jättää lisäosan hiekkalaatikkoon. Jos lisäosa jää hiekkalaatikkoon, voit ehdottaa sitä uudestaan julkiselle puolelle kun toimittajan ehdottamat muutokset on tehty. Jos lisäosa siirretään julkiselle puolelle sen uudet versiot ilmestyvät edelleen ensin hiekkalaatikkoon. Uudet versiot kuitenkin siirtyvät automaattisesti tarkastusjonoon odottamaan toimittajan tarkistusta.</li>
+</ol>
diff --git a/site/app/locale/fi/pages/submission_help.thtml b/site/app/locale/fi/pages/submission_help.thtml
new file mode 100644
index 0000000..4a06397
--- /dev/null
+++ b/site/app/locale/fi/pages/submission_help.thtml
@@ -0,0 +1,35 @@
+<h1>Lisäosan lähettämisen ohje</h1>
+Pakolliset kentät on <b>lihavoitu</b> ja vapaavalintaiset kentät <i>kursivoitu</i>.
+<h2 id="step1">1. kohta: siirto</h2>
+<ul class="submissionHelp">
+ <li><span class="required">Lisäosan tyyppi</span> - Lisäosan tyyppi tunnistetaan automaattisesti oletuksena. Tähän kenttään ei pitäisi tarvita koskea.</li>
+ <li><span class="required">Lisäosatiedosto</span> - Lisäosasi xpi-pakettitiedosto, joka sisältää install.rdf-tiedoston. Jos tiedosto toimii vain tietyllä alustalla, alustan valitseminen mahdollistaa useiden tiedostojen siirtämisen samalla.</li>
+ <li><span class="optional">Kuvaketiedosto</span> - Kuvaketiedosto näkyy lisäosan nimen vieressä lisäosan sivulla ja lisäosan asennusikkunassa. Kuvake pienennetään tarvittaessa automaattisesti kokoon 32x32 kuvapistettä kuitenkin säilyttäen kuvasuhteen.</li>
+ <li><span class="required">Oletuslokaali</span> - Lisäosan oletuslokaali on sen ensisijainen kieli. Jos lisäosaa ei ole saatavilla käyttäjän valitsemalla kielellä, lisäosa näytetään sen ensisijaisella kielellä.</li>
+ <li><span class="optional">Ohita lisäosan tietojen tarkistus</span> - Tämä valinta on esillä jos olet päivittämässä olemassa olevaa lisäosaa. Valitsemalla kohdan hypätään seuraavan kohdan yli suoraan versiotietoihin (3. kohta).</li>
+</ul>
+
+<h2 id="step2">2. kohta: lisäosan tiedot</h2>
+<ul class="submissionHelp">
+ <li><span class="required">Nimi</span> - Lisäosan nimi oletuskielellä.</li>
+ <li><span class="required">Tekijät</span> - Kaikki käyttäjät, joilla on oikeus muokata lisäosaa. Tekijät listataan lisäosan sivulla.</li>
+ <li><span class="required">Luokat</span> - Luokat, joihin lisäosa kuuluu.</li>
+ <li><span class="optional">Kotisivut</span> - Lisäosan kotisivu oletuskielellä.</li>
+ <li><span class="required">Yhteenveto</span> - Lyhyt kuvaus lisäosasta oletuskielellä. Yhteenveto näytetään lisäosan sivulla, hakutuloksissa ja lisäosalistassa. Kenttään mahtuu enintään 250 merkkiä.</li>
+ <li><span class="required">Kuvaus</span> - Kuvaus lisäosasta oletuskielellä. Kuvaus näkyy yhteenvedon alla lisäosan sivulla.</li>
+ <li><span class="optional">Loppukäyttäjän lisenssi</span> - Loppukäyttäjän lisenssi oletuskielellä. Lisäosan käyttäjien täytyy hyväksyä lisenssi ennen kuin he voivat ladata lisäosaa.</li>
+ <li><span class="optional">Tietosuojakäytäntö</span> - Lisäosan tietosuojakäytäntö oletuskielellä. Tietosuojakäytännössä selitetään, mitä loppukäyttäjästä kerätyillä tiedoilla tehdään. Käytäntöön on linkki lisäosan sivulla asennus-linkin vieressä. Tarkempia tietoja tietosuojakäytännön sisällöstä ja siitä tarvitseeko lisäosasi tietosuojakäytännön lukee <a href="%s">lisäosakäytännössä</a>.</li>
+ <li><span class="optional">Lähdekoodi on käyttäjien tarkasteltavissa</span> - Valitsemalla kohdan käyttäjät voivat selata lisäosasi lähdekoodia sivustolla.</li>
+ <li><span class="optional">Tämä on esijulkaisuversio</span> - Valitsemalla kohdan teet selväksi, että lisäosa on esijulkaisu tai niin sanottu betaversio. Esijulkaisuversioiden tulisi pysyä hiekkalaatikossa eikä niitä voi ehdottaa siirrettäväksi sivuston julkiselle puolelle ennen kuin valinta tästä kohdasta on poistettu.</li>
+ <li><span class="optional">Lisäosa on sivustokohtainen</span> - Jos lisäosa toimii vain yhdellä sivustolla se on sivustokohtainen. Kohta auttaa sivuston toimittajia työssään ja saattaa joskus tulla etsimiskriteeriksi.</li>
+ <li><span class="optional">Lisäosa tarvitsee toimiakseen erikseen jaeltavan, itsenäisen ohjelman</span> - Valitse kohta jos lisäosa tarvitsee erillisen ohjelman toimiakseen. Kohta auttaa sivuston toimittajia työssään ja saattaa joskus tulla etsimiskriteeriksi.</li>
+</ul>
+
+<h2 id="step3">3. kohta: versiotiedot</h2>
+<ul class="submissionHelp">
+ <li><span class="required optional">Versiohuomautukset</span> - Yhteenveto tai lista version muutoksista. Kenttä on pakollinen päivityksille.</li>
+ <li><span class="optional">Huomioita tarkastajalle</span> - Kentässä voi kertoa sivuston toimittajille tietoja, jotka voivat auttaa heitä tarkastamaan lisäosaa. Testitilitiedot ja erikoishuomautukset tulisi kirjoittaa tänne.</li>
+</ul>
+
+<h2 id="step4">4. kohta: lokalisointi</h2>
+Jotkin lisäosasivun kentät ovat lokalisoitavissa. Kirjoita alle käännökset kentistä eri kielille. Valitse kieli ja täytä kentät valitulla kielellä.
diff --git a/site/app/locale/fr/LC_MESSAGES/messages.mo b/site/app/locale/fr/LC_MESSAGES/messages.mo
new file mode 100644
index 0000000..08a3555
--- /dev/null
+++ b/site/app/locale/fr/LC_MESSAGES/messages.mo
Binary files differ
diff --git a/site/app/locale/fr/LC_MESSAGES/messages.po b/site/app/locale/fr/LC_MESSAGES/messages.po
new file mode 100644
index 0000000..fbcabb9
--- /dev/null
+++ b/site/app/locale/fr/LC_MESSAGES/messages.po
@@ -0,0 +1,8610 @@
+# Remora Preliminary Language File
+# Copyright (C) 2006 Mozilla Corporation
+# This file is distributed under the same license as the REMORA package.
+# Wil Clouser <clouserw@mozilla.com>, 2006.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: REMORA 0.1\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2009-01-16 11:45-0800\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: Pascal Chevrel <pascal.chevrel@mozilla-europe.org>\n"
+"Language-Team: FR (Frenchmozilla + Mozilla Europe)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=n>1;\n"
+
+#: views/addons/policy.thtml:98
+msgid "a_cancel_installation"
+msgstr "Annuler l'installation"
+
+#. This is the text that appears on buttons to download add-ons.
+#. %$1s is an optional string that only appears if the add-on is only available for
+#. a certain platform. Examples: (Windows) or (Linux)
+#. Note that the parentheses are included in the string. :(
+#: views/elements/amo2009/install.thtml:126
+#: views/elements/amo2009/install.thtml:227
+#: views/elements/amo2009/install.thtml:257
+#: views/elements/amo2009/install.thtml:300
+#: views/elements/amo2009/install.thtml:312 views/elements/install.thtml:73
+#: views/elements/install.thtml:181 views/elements/install.thtml:205
+#: views/elements/install.thtml:248 views/elements/install.thtml:260
+#: views/addons/plugins.thtml:66 views/addons/plugins.thtml:76
+#: views/addons/plugins.thtml:86 views/addons/plugins.thtml:96
+#: views/addons/plugins.thtml:119
+#, php-format
+msgid "a_download"
+msgstr "Télécharger %s"
+
+#: views/addons/policy.thtml:72
+msgid "a_eula_download"
+msgstr "Accepter et télécharger"
+
+#: views/addons/policy.thtml:74
+msgid "a_eula_install"
+msgstr "Accepter et installer"
+
+#: views/elements/header.thtml:76 views/elements/header.thtml:82
+#: views/api/api_addon.thtml:55 views/api/collections_feed.thtml:75
+#: views/sharing_api/addon.thtml:64
+msgid "a_header_public"
+msgstr "Public"
+
+#: views/elements/header.thtml:58 views/elements/header.thtml:75
+#: views/elements/header.thtml:80 views/api/api_addon.thtml:57
+#: views/api/collections_feed.thtml:77 views/sharing_api/addon.thtml:66
+msgid "a_header_sandbox"
+msgstr "Bac à sable"
+
+#. %s is a date in the _('date') format
+#: views/elements/amo2009/homepage_addon.thtml:115
+#: views/elements/addon_listitem.thtml:122 views/elements/feature.thtml:106
+#: views/addons/display.thtml:104 views/addons/browse_thumbs.thtml:73
+msgid "addon_detail_last_updated"
+msgstr "Mis à jour le %s"
+
+#. %s is the version of the add-on. Example: 3.2a1
+#: views/elements/amo2009/addon_version_detail.thtml:51
+#: views/elements/addon_version_detail.thtml:51
+#, php-format
+msgid "addon_display_header_version"
+msgstr "Version %s"
+
+#: views/addons/browse_thumbs.thtml:80
+msgid "addon_downloads"
+msgstr "Téléchargements"
+
+#: views/addons/display.thtml:147
+msgid "addon_downloads_total"
+msgstr "Total des téléchargements"
+
+#: views/elements/amo2009/homepage_addon.thtml:106
+#: views/elements/addon_listitem.thtml:115 views/elements/feature.thtml:101
+#: views/addons/category_landing.thtml:157 views/addons/display.thtml:146
+#: views/addons/browse_thumbs.thtml:80
+msgid "addon_downloads_weekly"
+msgstr "Téléchargements hebdomadaires"
+
+#. %1 is the add-on count, %2 the category name
+#: views/addons/browse_thumbs.thtml:104 views/addons/browse.thtml:60
+#, php-format
+msgid "addon_list_category_totalcount"
+msgid_plural "addon_list_category_totalcount"
+msgstr[0] "%1$s module"
+msgstr[1] "%1$s modules"
+
+#: views/elements/amo2009/addon_list_options.thtml:103
+#: views/elements/pagination.thtml:67
+#: views/elements/addon_list_options.thtml:94
+msgid "addon_list_perpage"
+msgstr "par page"
+
+#: views/elements/amo2009/addon_list_options.thtml:84
+#: views/elements/addon_list_options.thtml:98
+msgid "addon_list_sortby"
+msgstr "Trier par&nbsp;:"
+
+#: views/helpers/addons_html.php:568 views/elements/amo2009/install.thtml:321
+#: views/elements/feature.thtml:89
+msgid "addon_listitem_flag_experimental"
+msgstr "expérimental"
+
+#: views/helpers/addons_html.php:570
+msgid "addon_listitem_flag_recommended"
+msgstr "recommandé"
+
+#. %1 is the add-on name, %2 is the platform
+#: views/pages/js_constants.js.thtml:66
+msgid "addon_not_available_for_platform"
+msgstr "%1$s n'est pas disponible pour %2$s"
+
+#. %1 is the add-on name
+#: views/addons/policy.thtml:101 views/addons/previews.thtml:60
+#: views/addons/versions.thtml:130 views/reviews/flag.thtml:61
+#: views/reviews/add.thtml:114 views/reviews/display.thtml:216
+#: views/reviews/review_added.thtml:57
+#, php-format
+msgid "addon_review_a_back_to_addon_x"
+msgstr "Retour à %1$s..."
+
+#. %1 is the add-on name
+#: views/reviews/flag.thtml:60 views/reviews/add.thtml:113
+#: views/reviews/review_added.thtml:56
+#, php-format
+msgid "addon_review_a_back_to_reviews"
+msgstr "Retour aux critiques..."
+
+#: views/reviews/add.thtml:85
+msgid "addon_review_add_rating_field"
+msgstr "Évaluation&nbsp;:"
+
+#: views/reviews/add.thtml:102
+msgid "addon_review_add_review_field"
+msgstr "Critique&nbsp;:"
+
+#: views/reviews/add.thtml:107
+msgid "addon_review_add_submit"
+msgstr "Envoyer votre critique"
+
+#. %s is the name of the add-on
+#: views/reviews/add.thtml:51
+#, php-format
+msgid "addon_review_add_title"
+msgstr "Ajouter une critique pour %s"
+
+#: views/reviews/add.thtml:78
+msgid "addon_review_add_title_field"
+msgstr "Titre/Résumé&nbsp;:"
+
+#: views/reviews/display.thtml:77 views/reviews/display.thtml:161
+msgid "addon_review_admin_delete"
+msgstr "Effacer"
+
+#: views/reviews/display.thtml:76
+msgid "addon_review_author_reply_link"
+msgstr "Répondre"
+
+#: views/reviews/delete.thtml:62
+msgid "addon_review_confirm_delete"
+msgstr "Êtes-vous certain de vouloir effacer cette critique&nbsp;?"
+
+#: views/reviews/delete.thtml:63
+msgid "addon_review_confirm_no"
+msgstr "Non"
+
+#: views/reviews/delete.thtml:64
+msgid "addon_review_confirm_yes"
+msgstr "Oui"
+
+#: views/reviews/delete.thtml:48
+msgid "addon_review_delete_header"
+msgstr "Effacer la critique"
+
+#: controllers/reviews_controller.php:449
+msgid "addon_review_deleted_successfully"
+msgstr "Critique effacée avec succès."
+
+#. %s is the name of the add-on
+#: views/reviews/add.thtml:51
+#, php-format
+msgid "addon_review_edit_title"
+msgstr "Éditer la critique de %s"
+
+#. %1 is the count of characters entered as notes for the review flag reason.
+#: controllers/reviews_controller.php:539
+msgid "addon_review_flag_error_other_length"
+msgstr ""
+"Problème lors du marquage de la critique&nbsp;: La longueur des commentaires "
+"des critiques marquées doit être de 10 à 100 caractères. Votre commentaire "
+"contenait %1$s caractères."
+
+#. Removing an extra comma
+#: views/reviews/review_added.thtml:53
+msgid "addon_review_in_moderation"
+msgstr ""
+"Attention&nbsp;: avant que votre critique n'apparaisse sur le site public, "
+"elle sera modérée par un éditeur."
+
+#: views/reviews/add.thtml:57
+msgid "addon_review_in_reply_to"
+msgstr "Réponse du développeur à&nbsp;:"
+
+#. %1 is the review count, %2 is the nickname or full name of the user.
+#: views/reviews/display.thtml:131
+#, php-format
+msgid "addon_review_others_by_user"
+msgid_plural "addon_review_others_by_user"
+msgstr[0] ""
+"Afficher %1$s critique précédemment envoyée par %2$s pour ce module."
+msgstr[1] ""
+"Afficher %1$s critiques précédemment envoyées par %2$s pour ce module"
+
+#. %1 is the add-on name
+#: controllers/reviews_controller.php:201
+#: controllers/reviews_controller.php:250
+#: controllers/reviews_controller.php:345
+#: controllers/reviews_controller.php:424
+#, php-format
+msgid "addon_review_pagetitle"
+msgstr "Critique de %s"
+
+#. %1 is the user, %2 is the (localized) date
+#: views/reviews/display.thtml:160
+#, php-format
+msgid "addon_review_reply_on_x_by_y"
+msgstr "Réponse de %1$s le %2$s"
+
+#: views/reviews/display.thtml:157
+msgid "addon_review_reply_prefix"
+msgstr "Réponse du développeur&nbsp;:"
+
+#: views/reviews/review_added.thtml:51
+msgid "addon_review_saved_successfully"
+msgstr "Votre critique a bien été enregistrée. Merci&nbsp;!"
+
+#: views/addons/display.thtml:354 views/reviews/display.thtml:72
+msgid "addon_reviewed_by_u_on_d"
+msgstr "par %1$s le %2$s"
+
+#. %1 is the user, %2 is the (localized) date, %3 is the rating
+#: views/editors/reviews_queue.thtml:57 views/editors/reviews_queue.thtml:68
+#: views/reviews/add.thtml:63 views/reviews/delete.thtml:54
+#, php-format
+msgid "addon_reviewed_on_x_rated_y"
+msgstr "par %1$s le %2$s (note&nbsp;: %3$s)"
+
+#: views/elements/amo2009/addon_version_detail.thtml:52
+#: views/elements/addon_version_detail.thtml:52
+msgid "addon_version_permalink"
+msgstr "Lien permanent vers cette version"
+
+#. %1 is the current Application name (e.g. Firefox)
+#. %2 is the Application's version number
+#: views/addons/versions.thtml:140
+msgid "addon_versions_getlatestversion"
+msgstr "La version la plus récente compatible avec %1$s %2$s"
+
+#: views/addons/display.thtml:447
+msgid "addons_author_addons_submit"
+msgstr "Ok"
+
+#: views/elements/amo2009/homepage_addon.thtml:100
+#: views/elements/feature.thtml:95
+msgid "addons_author_tooltip"
+msgstr "Afficher le profil de l'auteur"
+
+#. %1 is the name of the Application (eg. Firefox)
+#: controllers/addons_controller.php:1296
+msgid "addons_browse_all_themes_title"
+msgstr "Parcourir tous les thèmes :: %1$s modules"
+
+#. %s is the name of the category
+#: controllers/addons_controller.php:1016
+#, php-format
+msgid "addons_browse_browse_category"
+msgstr "Parcourir la catégorie %s"
+
+#. %1 is the name of the theme category (eg. Modern)
+#. %2 is the name of the Application (eg. Firefox)
+#: controllers/addons_controller.php:664
+msgid "addons_browse_categories_header_theme"
+msgstr "parcourir %1$s thèmes :: %2$s modules"
+
+#: views/addons/display.thtml:249
+msgid "addons_display_a_license_what"
+msgstr "Qu'est-ce que c'est?"
+
+#: views/reviews/display.thtml:222
+msgid "addons_display_add_review"
+msgstr "Ajouter une critique"
+
+#: views/addons/display.thtml:294
+msgid "addons_display_advanced_details"
+msgstr "Détails avancés"
+
+#: views/addons/display.thtml:98
+msgid "addons_display_categories"
+msgstr "Catégories"
+
+#: views/addons/display.thtml:482
+#, fuzzy
+msgid "addons_display_collection_add"
+msgstr "Add to a collection:"
+
+#: views/addons/display.thtml:491
+#, fuzzy
+msgid "addons_display_collection_add_new"
+msgstr "New Collection..."
+
+#: views/addons/display.thtml:487
+#, fuzzy
+msgid "addons_display_collection_add_select_one"
+msgstr "Select a collection..."
+
+#: views/addons/display.thtml:493
+#, fuzzy
+msgid "addons_display_collection_add_submit"
+msgstr "Publish"
+
+#. %1$s is the add-on name
+#. %2$s is the collection name, linked to the collection's page
+#: views/pages/js_constants.js.thtml:103 views/addons/display.thtml:61
+#, fuzzy
+msgid "addons_display_collection_publish_success"
+msgstr "%1$s has been added to the %2$s collection."
+
+#: views/addons/display.thtml:483
+#, fuzzy
+msgid "addons_display_collection_whatsthis"
+msgstr "What's this?"
+
+#. %1$s is a number
+#: views/addons/display.thtml:473
+#, fuzzy
+msgid "addons_display_collections_more"
+msgid_plural "addons_display_collections_more"
+msgstr[0] "and %1$s more collection"
+msgstr[1] "and %1$s more collections"
+
+#: views/addons/display.thtml:403
+msgid "addons_display_detailed_review"
+msgstr "critique détaillée"
+
+#: views/reviews/add.thtml:89 views/reviews/add.thtml:90
+msgid "addons_display_dont_like_it"
+msgstr "Opinion négative"
+
+#: views/reviews/display.thtml:220
+msgid "addons_display_edit_review"
+msgstr "Éditer votre critique"
+
+#: views/addons/display.thtml:132
+msgid "addons_display_has_privacy"
+msgstr "Ce module est pourvu d'une politique de confidentialité spécifique."
+
+#: views/reviews/add.thtml:87 views/reviews/add.thtml:88
+msgid "addons_display_hate_it"
+msgstr "Opinion très négative"
+
+#: views/addons/display.thtml:462
+#, fuzzy
+msgid "addons_display_header_collections"
+msgstr "Related Collections"
+
+#: views/addons/display.thtml:297
+msgid "addons_display_header_developer_comments"
+msgstr "Commentaires du développeur"
+
+#: views/addons/display.thtml:230
+msgid "addons_display_header_homepage"
+msgstr "Page d'accueil"
+
+#: views/addons/display.thtml:247 views/addons/versions.thtml:110
+#, fuzzy
+msgid "addons_display_header_license"
+msgstr "Source Code License"
+
+#: views/addons/display.thtml:337
+msgid "addons_display_header_reviews"
+msgstr "Critiques"
+
+#: views/addons/display.thtml:261
+msgid "addons_display_header_support"
+msgstr "Assistance"
+
+#: views/reviews/add.thtml:91 views/reviews/add.thtml:92
+msgid "addons_display_like_it"
+msgstr "Opinion positive"
+
+#: views/addons/display.thtml:210
+msgid "addons_display_long_description"
+msgstr "Description détaillée"
+
+#: views/reviews/add.thtml:95 views/reviews/add.thtml:96
+msgid "addons_display_love_it"
+msgstr "Opinion très positive"
+
+#: views/addons/display.thtml:178
+msgid "addons_display_more_images"
+msgstr "Plus d'images"
+
+#: views/addons/display.thtml:465
+#, fuzzy
+msgid "addons_display_nocollections"
+msgstr "This add-on is not yet in any collections."
+
+#. %1$s is either an author's name or a comma separated list of authors. Using
+#. the list doesn't make sense in the English plural form so we ignore the
+#. variable.
+#: views/addons/display.thtml:436
+msgid "addons_display_other_addons_by"
+msgid_plural "addons_display_other_addons_by"
+msgstr[0] "Autres modules de %1$s"
+msgstr[1] "Autres modules de ces auteurs"
+
+#. %s is the name of the add-on and the add-on section. Example:
+#. Some Add-on :: Firefox Add-ons
+#. This should not be concatenated in the code and should be fixed.
+#: controllers/addons_controller.php:141 controllers/addons_controller.php:280
+#: controllers/addons_controller.php:1442
+#, php-format
+msgid "addons_display_pagetitle"
+msgstr "%s"
+
+#. %s is an email address
+#: views/addons/display.thtml:286
+#, php-format
+msgid "addons_display_paragraph_supportinfoemail"
+msgstr ""
+"L'assistance pour cette extension est disponible auprès de son développeur "
+"ici&nbsp;: %s."
+
+#. %$1s is a URL
+#. %$2s is an email address
+#: views/addons/display.thtml:269
+#, php-format
+msgid "addons_display_paragraph_supportinfoemailurl"
+msgstr ""
+"L'assistance pour cette extension est disponible auprès de son développeur "
+"ici&nbsp;: %s ou bien par courriel à cette adresse&nbsp;: %s"
+
+#. %s is a URL
+#: views/addons/display.thtml:278
+#, php-format
+msgid "addons_display_paragraph_supportinfourl"
+msgstr ""
+"L'assistance pour cette extension est disponible auprès de son développeur "
+"ici&nbsp;: %s."
+
+#: views/addons/display.thtml:383
+msgid "addons_display_rate_it"
+msgstr "Votre évaluation"
+
+#: views/reviews/add.thtml:93 views/reviews/add.thtml:94
+msgid "addons_display_really_like_it"
+msgstr "Opinion très positive"
+
+#: views/addons/display.thtml:410
+msgid "addons_display_review_etiquette"
+msgstr ""
+"Veuillez ne pas poster de rapports de bugs dans vos critiques. Nous ne "
+"donnons pas accès à votre adresse électronique aux développeurs de modules "
+"hors ceux-ci pourraient avoir besoin de vous contacter pour résoudre votre "
+"problème."
+
+#. %1 is the review guidelines link
+#: views/addons/display.thtml:417
+msgid "addons_display_review_guidelines_link"
+msgstr "<a href=\"%s\">Instruction pour la critique</a>"
+
+#. %1 is the support section link
+#: views/addons/display.thtml:414
+msgid "addons_display_review_see_support"
+msgstr ""
+"Consultez la <a href=\"%1$s\">section d'assistance</a> pour toute question "
+"relative à ce module."
+
+#: views/addons/display.thtml:404
+msgid "addons_display_review_submit"
+msgstr "Enregistrer"
+
+#: views/addons/display.thtml:430
+#, php-format
+msgid "addons_display_see_all_addons"
+msgstr "Afficher tous les modules pour %1$s"
+
+#. %1 is the number of reviews
+#: views/addons/display.thtml:364
+#, php-format
+msgid "addons_display_see_all_reviews"
+msgstr "Voir toutes les critiques (%1$s)"
+
+#: views/addons/display.thtml:219
+msgid "addons_display_see_all_versions"
+msgstr "Afficher toutes les versions"
+
+#: views/addons/display.thtml:321 views/addons/versions.thtml:117
+msgid "addons_display_view_source"
+msgstr "Afficher la source"
+
+#: views/addons/display.thtml:324
+msgid "addons_display_view_stats"
+msgstr "Voir les statistiques"
+
+#: views/addons/display.thtml:376
+msgid "addons_display_what_do_you_think"
+msgstr "Qu'en pensez-vous&nbsp;?"
+
+#: views/elements/app_compatibility.thtml:49
+msgid "addons_display_workswith"
+msgstr "Fonctionne avec&nbsp;"
+
+#: views/addons/home.thtml:112
+#, fuzzy
+msgid "addons_home_browse_new"
+msgstr "Just Added"
+
+#: views/addons/home.thtml:110
+#, fuzzy
+msgid "addons_home_browse_popular"
+msgstr "Popular"
+
+#: views/addons/home.thtml:108
+#, fuzzy
+msgid "addons_home_browse_recommended"
+msgstr "Recommended"
+
+#: views/addons/home.thtml:127 views/addons/home.thtml:134
+#: views/addons/home.thtml:141 views/addons/home.thtml:148
+#, fuzzy
+msgid "addons_home_browse_subscribe"
+msgstr "Subscribe"
+
+#: views/addons/home.thtml:101
+#, fuzzy
+msgid "addons_home_browse_title"
+msgstr "Browse Add-ons"
+
+#: views/addons/home.thtml:114
+#, fuzzy
+msgid "addons_home_browse_updated"
+msgstr "Updated"
+
+#: views/elements/amo2009/homepage_addon.thtml:100
+#: views/elements/addon_discussionheader.thtml:83
+#: views/elements/addon_listitem.thtml:109 views/elements/feature.thtml:95
+#: views/addons/category_landing.thtml:66 views/addons/policy.thtml:57
+#: views/addons/display.thtml:70 views/addons/home.thtml:178
+msgid "addons_home_by"
+msgstr "par "
+
+#: views/addons/home.thtml:169
+#, fuzzy
+msgid "addons_home_collection_popular_title"
+msgstr "Popular Collections"
+
+#: views/elements/amo2009/categories.thtml:69 views/addons/home.thtml:160
+#, fuzzy
+msgid "addons_home_collections"
+msgstr "Collections"
+
+#. %1$s is the count of addons in a collection
+#: views/elements/amo2009/collection_listing_item.thtml:51
+#: views/addons/home.thtml:185
+#, fuzzy
+msgid "addons_home_collections_addon_count"
+msgid_plural "addons_home_collections_addon_count"
+msgstr[0] "<strong>%1$s</strong> add-on"
+msgstr[1] "<strong>%1$s</strong> add-ons"
+
+#: views/addons/home.thtml:196
+#, fuzzy
+msgid "addons_home_collections_all"
+msgstr "View All Collections"
+
+#: views/addons/home.thtml:162
+#, fuzzy
+msgid "addons_home_collections_intro"
+msgstr ""
+"Collections are a way for you to categorize, mix, match and mingle add-ons. "
+"Subscribe to collections created by other users or create your own."
+
+#. %1$s is the count of subscribers for a collection
+#: views/elements/amo2009/collection_listing_item.thtml:58
+#: views/collections/detail.thtml:96 views/addons/home.thtml:189
+#, fuzzy
+msgid "addons_home_collections_subscribers"
+msgid_plural "addons_home_collections_subscribers"
+msgstr[0] "<strong>%1$s</strong> subscriber"
+msgstr[1] "<strong>%1$s</strong> subscribers"
+
+#: views/addons/searchengines.thtml:54 views/addons/themes_landing.thtml:49
+msgid "addons_home_feature_head"
+msgstr "Nous vous recommandons"
+
+#: controllers/search_controller.php:218 controllers/addons_controller.php:176
+#: controllers/addons_controller.php:428 controllers/addons_controller.php:671
+#: controllers/addons_controller.php:871
+#: controllers/addons_controller.php:1103
+#: controllers/addons_controller.php:1242
+#: controllers/addons_controller.php:1298
+#, php-format
+msgid "addons_home_header_details"
+msgstr ""
+"Les modules complémentaires étendent %1$s en vous permettant de "
+"personnaliser votre navigation."
+
+#. %1$s is the HTML collection name link.
+#: views/elements/amo2009/teaser_collections.thtml:107
+#, fuzzy
+msgid "addons_home_introduction_collection_link"
+msgstr "Like these? Find more add-ons in %1$s."
+
+#: views/elements/amo2009/teaser_collections.thtml:60
+#, fuzzy
+msgid "addons_home_introduction_extras"
+msgstr ""
+"<strong>Over 5000 free extras</strong> that let you customize and extend "
+"Firefox to meet your needs."
+
+#: views/elements/amo2009/teaser_collections.thtml:55
+#, fuzzy
+msgid "addons_home_introduction_header"
+msgstr "What are Add-ons?"
+
+#: views/elements/amo2009/teaser_collections.thtml:72
+#, fuzzy
+msgid "addons_home_introduction_install"
+msgstr ""
+"<strong>Easy to install</strong>, get notified when updates are available."
+
+#: views/elements/amo2009/teaser_collections.thtml:45
+#, fuzzy
+msgid "addons_home_introduction_name"
+msgstr "Introduction"
+
+#: views/elements/amo2009/teaser_collections.thtml:66
+#, fuzzy
+msgid "addons_home_introduction_themes"
+msgstr ""
+"Toolbars, themes and search providers that <strong>help you perform common "
+"tasks.</strong>"
+
+#: views/addons/home.thtml:161
+#, fuzzy
+msgid "addons_home_new_indicator"
+msgstr "NEW!"
+
+#: views/elements/app_chooser.thtml:48 views/layouts/amo2009.thtml:257
+msgid "addons_home_other_applications"
+msgstr "Autres applications"
+
+#. %1$s is the application the user is browsing. Examples: Thunderbird, Firefox,
+#. Sunbird
+#: views/pages/collector_faq.thtml:49 views/pages/collector_firstrun.thtml:42
+#: views/pages/collector.thtml:46 views/pages/collector_features.thtml:54
+#: controllers/developers_controller.php:87
+#: controllers/compatibility_controller.php:72
+#: controllers/components/simple_acl.php:81 controllers/components/amo.php:607
+#: controllers/statistics_controller.php:60
+#: controllers/statistics_controller.php:240
+#: controllers/previews_controller.php:67 controllers/users_controller.php:90
+#: controllers/users_controller.php:223 controllers/users_controller.php:330
+#: controllers/users_controller.php:414 controllers/users_controller.php:708
+#: controllers/users_controller.php:723 controllers/reviews_controller.php:204
+#: controllers/reviews_controller.php:251
+#: controllers/reviews_controller.php:346
+#: controllers/reviews_controller.php:425
+#: controllers/search_controller.php:185 controllers/search_controller.php:297
+#: controllers/search_controller.php:301 controllers/addons_controller.php:147
+#: controllers/addons_controller.php:280 controllers/addons_controller.php:370
+#: controllers/addons_controller.php:667 controllers/addons_controller.php:874
+#: controllers/addons_controller.php:1019
+#: controllers/addons_controller.php:1034
+#: controllers/addons_controller.php:1101
+#: controllers/addons_controller.php:1121
+#: controllers/addons_controller.php:1240
+#: controllers/addons_controller.php:1357
+#: controllers/addons_controller.php:1364
+#: controllers/addons_controller.php:1442
+#: controllers/addons_controller.php:1477
+#: controllers/addons_controller.php:1538
+#: controllers/addons_controller.php:1543
+#: controllers/editors_controller.php:64 controllers/pages_controller.php:132
+#: controllers/groups_controller.php:65 controllers/groups_controller.php:71
+#: controllers/groups_controller.php:89 controllers/groups_controller.php:111
+#: controllers/collections_controller.php:57
+#: controllers/collections_controller.php:121
+#: controllers/collections_controller.php:205
+#: controllers/collections_controller.php:365
+#: controllers/collections_controller.php:404
+#: controllers/collections_controller.php:466
+#: controllers/collections_controller.php:538
+#: controllers/collections_controller.php:828
+#: controllers/localizers_controller.php:72
+#, php-format
+msgid "addons_home_pagetitle"
+msgstr "Modules pour %1$s"
+
+#. %1$s is the number of addons downloaded
+#: views/addons/home.thtml:57
+#, fuzzy, php-format
+msgid "addons_home_stats_downloaded"
+msgid_plural "addons_home_stats_downloaded"
+msgstr[0] "<strong>%1$s</strong> <span>add-on downloaded</span>"
+msgstr[1] "<strong>%1$s</strong> <span>add-ons downloaded</span>"
+
+#. %1$s is the number of addons in use
+#: views/addons/home.thtml:63
+#, fuzzy, php-format
+msgid "addons_home_stats_inuse"
+msgid_plural "addons_home_stats_inuse"
+msgstr[0] "<strong>%1$s</strong> <span>add-on in use</span>"
+msgstr[1] "<strong>%1$s</strong> <span>add-ons in use</span>"
+
+#: views/addons/home.thtml:136
+msgid "addons_home_view_all_newest_title"
+msgstr "Afficher tous les modules récemment créés"
+
+#: views/addons/home.thtml:129
+msgid "addons_home_view_all_popular_title"
+msgstr "Afficher tous les modules populaires"
+
+#: views/addons/home.thtml:150
+msgid "addons_home_view_all_recommended_title"
+msgstr "Afficher tous les modules recommandés"
+
+#: views/addons/home.thtml:143
+msgid "addons_home_view_all_updated_title"
+msgstr "Afficher tous les modules récemment mis à jour"
+
+#: views/elements/amo2009/install.thtml:334 views/elements/install.thtml:112
+msgid "addons_install_in_sunbird"
+msgstr ""
+"<ol><li>Cliquez sur le lien ci-dessous pour enregistrer le fichier.</"
+"li><li>Dans Mozilla Sunbird, cliquez sur Modules complémentaires depuis le "
+"menu Outils.</li><li>Cliquez sur le bouton Installer, sélectionnez le "
+"fichier téléchargé sur votre disque dur et cliquez sur \"OK\".</li></ol>"
+
+#: views/elements/amo2009/install.thtml:333 views/elements/install.thtml:111
+msgid "addons_install_in_sunbird_title"
+msgstr "Comment réaliser l'installation dans Sunbird"
+
+#: views/elements/amo2009/install.thtml:331 views/elements/install.thtml:106
+msgid "addons_install_in_thunderbird"
+msgstr ""
+"<ol><li>Faites un clic-droit sur le lien ci-dessous et choisissez "
+"\"Enregistrez la cible du lien sous...\" pour télécharger et enregistrer le "
+"fichier sur votre disque dur.</li><li>Depuis Mozilla Thunderbird, ouvrez la "
+"fenêtre des modules complémentaires depuis le menu Outils.</li><li>Cliquez "
+"sur le bouton Installer et choisissez le fichier que vous avez téléchargé "
+"puis cliquez sur \"OK\" (ou \"Ouvrir\" selon la terminologie de votre "
+"système d'exploitation).</li></ol>"
+
+#: views/elements/amo2009/install.thtml:330 views/elements/install.thtml:105
+msgid "addons_install_in_thunderbird_title"
+msgstr "Comment installer un module dans Thunderbird"
+
+#: views/elements/amo2009/addon_list_options.thtml:108
+#: views/elements/addon_list_options.thtml:105
+msgid "addons_options_show_experimental"
+msgstr "Afficher les modules expérimentaux"
+
+#: views/elements/amo2009/addon_list_options.thtml:113
+#: views/elements/addon_list_options.thtml:109
+msgid "addons_options_submit"
+msgstr "Valider"
+
+#: views/addons/plugins.thtml:63 views/addons/plugins.thtml:73
+#: views/addons/plugins.thtml:83 views/addons/plugins.thtml:93
+#: views/addons/plugins.thtml:103 views/addons/plugins.thtml:116
+#: views/addons/plugins.thtml:126
+msgid "addons_plugins_by"
+msgstr "par"
+
+#: views/addons/plugins.thtml:107
+msgid "addons_plugins_for_linux"
+msgstr "pour Linux"
+
+#: views/addons/plugins.thtml:108 views/addons/plugins.thtml:131
+msgid "addons_plugins_for_macosx"
+msgstr "pour Mac&nbsp;OS&nbsp;X"
+
+#: views/addons/plugins.thtml:106 views/addons/plugins.thtml:129
+#: views/addons/plugins.thtml:130
+msgid "addons_plugins_for_windows"
+msgstr "pour Windows"
+
+#. %1$s is a URL
+#: views/addons/plugins.thtml:139
+#, php-format
+msgid "addons_plugins_looking_for_more"
+msgstr ""
+"Cette page ne liste que quelques-uns des plugins parmi les plus populaires. "
+"Pour de plus amples informations sur les plugins pour navigateurs basés sur "
+"les navigateurs Mozilla, visitez %1$s"
+
+#: views/addons/plugins.thtml:137
+msgid "addons_plugins_looking_for_plugin"
+msgstr "Recherchez-vous un plugin non listé ici&nbsp;?"
+
+#: views/addons/plugins.thtml:58
+msgid "addons_plugins_main_description"
+msgstr ""
+"Les plugins aident votre navigateur à réaliser des tâches spécifiques telles "
+"que l'affichage de formats graphiques spéciaux ou la lecture de fichiers "
+"multimédias. Les plugins diffèrent donc légèrement des extensions qui ont "
+"elles pour but la modification ou l'ajout de fonctionnalités."
+
+#. %1$s is the application name. Example: Firefox, Thunderbird, Sunbird
+#: controllers/addons_controller.php:1122
+#, php-format
+msgid "addons_plugins_main_header"
+msgstr "Plugins courants pour %1$s"
+
+#: controllers/components/amo.php:698 controllers/addons_controller.php:1121
+msgid "addons_plugins_pagetitle"
+msgstr "Plugins"
+
+#: views/addons/plugins.thtml:68 views/addons/plugins.thtml:78
+#: views/addons/plugins.thtml:88 views/addons/plugins.thtml:98
+#: views/addons/plugins.thtml:110 views/addons/plugins.thtml:121
+#: views/addons/plugins.thtml:133
+msgid "addons_plugins_support_documentation"
+msgstr "Documentation de support"
+
+#. %s is the name of the add-on
+#: views/addons/policy.thtml:61
+#, php-format
+msgid "addons_policy_eula_require"
+msgstr ""
+"%s implique l'acceptation du Contrat de Licence Utilisateur Final ci-dessous "
+"avant de procéder à l'installation"
+
+#. %1 is the add-on name
+#: controllers/addons_controller.php:1476
+#, php-format
+msgid "addons_previews_pagetitle"
+msgstr "Prévisualisations de %s"
+
+#: views/addons/category_landing.thtml:135
+#, fuzzy
+msgid "addons_recently_added"
+msgstr "Recently Added"
+
+#: views/addons/recommended.thtml:51 controllers/addons_controller.php:1365
+msgid "addons_recommended_introduction"
+msgstr ""
+"Avec plus d'un millier de modules complémentaires disponibles, chacun "
+"trouvera son bonheur. Voici quelques-uns de nos modules préférés, n'hésitez-"
+"pas à les essayer&nbsp;!"
+
+#: controllers/addons_controller.php:1357
+#: controllers/addons_controller.php:1364
+msgid "addons_recommended_pagetitle"
+msgstr "Modules recommandés"
+
+#: controllers/addons_controller.php:1360
+msgid "addons_recommended_title"
+msgstr "Modules recommandés"
+
+#: views/addons/searchengines.thtml:136
+msgid "addons_searchengines_additional_resources"
+msgstr "Ressources supplémentaires"
+
+#. link text devmo
+#: views/addons/searchengines.thtml:141
+msgid "addons_searchengines_devmo_link"
+msgstr "Mozilla Developer Center"
+
+#: views/pages/js_constants.js.thtml:67
+msgid "addons_searchengines_error_mozilla_browser_required"
+msgstr ""
+"Désolé, vous devez utiliser un navigateur basé sur Mozilla pour installer un "
+"plugin de recherche."
+
+#: views/addons/searchengines.thtml:49
+msgid "addons_searchengines_error_nojavascript"
+msgstr ""
+"JavaScript est nécessaire pour installer ces moteurs de recherche, "
+"apparemment JavaScript est désactivé dans votre navigateur. Veuillez "
+"réactiver JavaScript avant d'essayer d'installer un des moteurs de recherche "
+"ci-dessous."
+
+#. %1 is "make your own" link
+#. %2 is MDC link
+#: views/addons/searchengines.thtml:139
+msgid "addons_searchengines_learn_howto"
+msgstr "Apprenez à %1$s sur le site %2$s."
+
+#. link path to search plugins instructions, relative to devmo
+#: views/addons/searchengines.thtml:140
+msgid "addons_searchengines_makeyourown_href"
+msgstr "/fr/docs/Cr%C3%A9ation_de_plugins_OpenSearch_pour_Firefox"
+
+#. link text for "make your own" (opensearch engine)
+#: views/addons/searchengines.thtml:140
+msgid "addons_searchengines_makeyourown_link"
+msgstr "créer votre propre plugin de recherche"
+
+#. %1 is the link to mycroft.mozdev.org
+#: views/addons/searchengines.thtml:138
+msgid "addons_searchengines_more"
+msgstr "Découvrez de nombreux autres moteurs de recherche sur le site %1$s"
+
+#. link text to mycroft.mozdev.org
+#: views/addons/searchengines.thtml:138
+msgid "addons_searchengines_mycroft_link"
+msgstr "mycroft.mozdev.org"
+
+#: controllers/addons_controller.php:1100
+#: controllers/addons_controller.php:1110
+msgid "addons_searchengines_pagetitle"
+msgstr "Moteurs de recherche"
+
+#: views/addons/searchengines.thtml:143
+msgid "addons_searchengines_thanks"
+msgstr ""
+"Nous tenons à remercier tout particulièrement le projet Mycroft pour leur "
+"travail sur les moteurs de recherche de Firefox"
+
+#: views/addons/display.thtml:154
+#, fuzzy
+msgid "addons_share_button_text"
+msgstr "Share this"
+
+#: controllers/addons_controller.php:89
+#, fuzzy
+msgid "addons_share_label_delicious"
+msgstr "Add to Delicious"
+
+#: controllers/addons_controller.php:77
+#, fuzzy
+msgid "addons_share_label_digg"
+msgstr "Digg this!"
+
+#: controllers/addons_controller.php:83
+#, fuzzy
+msgid "addons_share_label_facebook"
+msgstr "Post to Facebook"
+
+#: controllers/addons_controller.php:101
+#, fuzzy
+msgid "addons_share_label_friendfeed"
+msgstr "Share on FriendFeed"
+
+#: controllers/addons_controller.php:95
+#, fuzzy
+msgid "addons_share_label_myspace"
+msgstr "Post to MySpace"
+
+#: controllers/components/amo.php:201 controllers/components/amo.php:229
+msgid "addons_status_disabled"
+msgstr "Désactivé"
+
+#: controllers/components/amo.php:191 controllers/components/amo.php:224
+msgid "addons_status_incomplete"
+msgstr "Version incomplète"
+
+#: controllers/components/amo.php:197 controllers/components/amo.php:227
+msgid "addons_status_nominated"
+msgstr "Dans le bac à sable. Nomination publique"
+
+#: views/pages/js_constants.js.thtml:80 controllers/components/amo.php:195
+#: controllers/components/amo.php:226
+msgid "addons_status_pending"
+msgstr "Dans le bac à sable. En attente de révision."
+
+#: views/pages/js_constants.js.thtml:78 controllers/components/amo.php:199
+#: controllers/components/amo.php:228
+msgid "addons_status_public"
+msgstr "Public"
+
+#: views/pages/js_constants.js.thtml:79 controllers/components/amo.php:193
+#: controllers/components/amo.php:225
+msgid "addons_status_sandbox"
+msgstr "Dans le bac à sable"
+
+#: controllers/components/amo.php:203
+msgid "addons_status_unknown"
+msgstr "Inconnu"
+
+#: views/elements/amo2009/teaser_collections.thtml:91
+#: views/elements/amo2009/homepage_addon.thtml:99
+#: views/elements/feature.thtml:94
+msgid "addons_title_tooltip"
+msgstr "En savoir plus sur ce module"
+
+#: views/addons/category_landing.thtml:151
+#, fuzzy
+msgid "addons_top_downloads"
+msgstr "Top Downloads"
+
+#: views/addons/category_landing.thtml:165
+#, fuzzy
+msgid "addons_top_rated"
+msgstr "Top Rated"
+
+#: views/addons/versions.thtml:62
+msgid "addons_versions_careful"
+msgstr "Méfiez-vous des anciennes versions&nbsp;!"
+
+#: views/addons/versions.thtml:63
+msgid "addons_versions_careful_introduction"
+msgstr ""
+"Ces versions sont affichées pour référence et à des fins de tests. Il est "
+"fortement conseillé d'utiliser la toute dernière version du module et non "
+"une ancienne version."
+
+#: controllers/addons_controller.php:1549
+msgid "addons_versions_history"
+msgstr "Historique des versions et modifications correspondantes"
+
+#. %1$s is the add-on name
+#: controllers/addons_controller.php:1535
+#, php-format
+msgid "addons_versions_pagetitle"
+msgstr "Historique de version de %1$s"
+
+#: controllers/groups_controller.php:71
+msgid "admin_group_add_pagetitle"
+msgstr "Ajouter un groupe"
+
+#: controllers/groups_controller.php:111
+msgid "admin_group_delete_pagetitle"
+msgstr "Effacer un groupe"
+
+#. %s is a number to identify the group
+#: controllers/groups_controller.php:117
+#, php-format
+msgid "admin_group_deleted"
+msgstr "Le groupe ayant l'id %s a été effacé"
+
+#: controllers/groups_controller.php:89
+msgid "admin_group_edit_pagetitle"
+msgstr "Éditer le Groupe"
+
+#: controllers/groups_controller.php:92 controllers/groups_controller.php:113
+msgid "admin_group_error_invalid_id"
+msgstr "Id invalide pour le groupe"
+
+#: controllers/groups_controller.php:65
+msgid "admin_group_pagetitle"
+msgstr "Administration du groupe"
+
+#: controllers/groups_controller.php:77 controllers/groups_controller.php:99
+msgid "admin_group_saved"
+msgstr "Le groupe a été enregistré"
+
+#: views/elements/amo2009/search.thtml:257 views/elements/search.thtml:239
+msgid "advanced_search_form"
+msgstr "Avancé"
+
+#: views/elements/amo2009/search.thtml:126 views/elements/search.thtml:125
+msgid "advanced_search_form_any_time"
+msgstr "N'importe quand"
+
+#: views/elements/amo2009/search.thtml:97
+#: views/elements/amo2009/search.thtml:110 views/elements/search.thtml:96
+#: views/elements/search.thtml:109
+msgid "advanced_search_form_any_type"
+msgstr "Tous"
+
+#: views/elements/amo2009/search.thtml:275 views/elements/search.thtml:254
+msgid "advanced_search_form_any_version"
+msgstr "Toutes"
+
+#: views/elements/amo2009/search.thtml:217 views/elements/search.thtml:212
+msgid "advanced_search_form_application"
+msgstr "Logiciel"
+
+#: views/elements/amo2009/search.thtml:143 views/elements/search.thtml:142
+msgid "advanced_search_form_keyword_match"
+msgstr "Correspondance du mot-clef"
+
+#: views/elements/amo2009/search.thtml:251 views/elements/search.thtml:225
+msgid "advanced_search_form_lastupdate"
+msgstr "Dernière mise à jour"
+
+#: views/elements/amo2009/search.thtml:145 views/elements/search.thtml:144
+msgid "advanced_search_form_name"
+msgstr "Nom"
+
+#: views/elements/amo2009/search.thtml:144 views/elements/search.thtml:143
+msgid "advanced_search_form_newest"
+msgstr "Récents"
+
+#: views/elements/amo2009/search.thtml:130 views/elements/search.thtml:129
+msgid "advanced_search_form_past_3_months"
+msgstr "Les 3 derniers mois"
+
+#: views/elements/amo2009/search.thtml:131 views/elements/search.thtml:130
+msgid "advanced_search_form_past_6_months"
+msgstr "Les 6 derniers mois"
+
+#: views/elements/amo2009/search.thtml:127 views/elements/search.thtml:126
+msgid "advanced_search_form_past_day"
+msgstr "Hier"
+
+#: views/elements/amo2009/search.thtml:129 views/elements/search.thtml:128
+msgid "advanced_search_form_past_month"
+msgstr "Le mois dernier"
+
+#: views/elements/amo2009/search.thtml:128 views/elements/search.thtml:127
+msgid "advanced_search_form_past_week"
+msgstr "La semaine dernière"
+
+#: views/elements/amo2009/search.thtml:132 views/elements/search.thtml:131
+msgid "advanced_search_form_past_year"
+msgstr "L'année dernière"
+
+#: views/elements/amo2009/search.thtml:239 views/elements/search.thtml:230
+msgid "advanced_search_form_perpage"
+msgstr "Résultats par page"
+
+#: views/elements/amo2009/search.thtml:243 views/elements/search.thtml:224
+msgid "advanced_search_form_platform"
+msgstr "Platforme"
+
+#: views/elements/amo2009/search.thtml:147 views/elements/search.thtml:146
+msgid "advanced_search_form_popularity"
+msgstr "Popularité"
+
+#: views/elements/amo2009/search.thtml:146 views/elements/search.thtml:145
+msgid "advanced_search_form_rating"
+msgstr "Évaluation"
+
+#: views/elements/amo2009/search.thtml:247 views/elements/search.thtml:231
+msgid "advanced_search_form_sortby"
+msgstr "Trié par"
+
+#: views/elements/amo2009/search.thtml:227 views/elements/search.thtml:216
+msgid "advanced_search_form_to"
+msgstr "à"
+
+#: views/elements/amo2009/search.thtml:257 views/elements/search.thtml:237
+msgid "advanced_search_form_toggle_tooltip"
+msgstr "Passer au mode de recherche avancé"
+
+#: views/elements/amo2009/search.thtml:235 views/elements/search.thtml:223
+msgid "advanced_search_form_type"
+msgstr "Type"
+
+#: views/elements/amo2009/search.thtml:222 views/elements/search.thtml:214
+msgid "advanced_search_form_version"
+msgstr "version"
+
+#: views/elements/amo2009/pagination.thtml:42
+#, fuzzy
+msgid "amo2009_pagination_next_page"
+msgstr "Next"
+
+#: views/elements/amo2009/pagination.thtml:41
+#, fuzzy
+msgid "amo2009_pagination_previous_page"
+msgstr "Prev"
+
+#: views/pages/js_constants.js.thtml:96
+msgid "app_compat_ignore_check"
+msgstr "Ignorer la vérification de version"
+
+#: views/pages/js_constants.js.thtml:72
+msgid "app_compat_older_firefox_only"
+msgstr "Ce module est pour une ancienne version de Firefox"
+
+#. %1$s and %2$s are URLs
+#: views/pages/js_constants.js.thtml:74
+msgid "app_compat_older_version_or_ignore_check"
+msgstr ""
+"Vous pouvez <a href=\"%1$s\">essayer une ancienne version</a> ou bien <a "
+"href=\"#\" onclick=\"%2$s\">ignorer cet avertissement</a>"
+
+#. %1$s is a URL
+#: views/pages/js_constants.js.thtml:71
+msgid "app_compat_try_old_version"
+msgstr "Une <a href=\"%1$s\">version plus ancienne</a> pourrait fonctionner"
+
+#. %1$s is a URL
+#. %2$s is a version number. Example: 3.1
+#: views/pages/js_constants.js.thtml:73
+msgid "app_compat_unreleased_version"
+msgstr ""
+"Ce module est pour une version en préparation de Firefox, concrètement <a "
+"href=\"%1$s\">Firefox %2$s</a>."
+
+#: views/pages/js_constants.js.thtml:70
+msgid "app_compat_update_firefox"
+msgstr ""
+"<a href=\"http://getfirefox.com\">Mettez à jour votre Firefox</a> pour "
+"utiliser ce module"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#. %3$s is a status, like Public.
+#: controllers/components/audit.php:79
+#, fuzzy
+msgid "audit_addon_status"
+msgstr "%1$s changed the status of %2$s to %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:221
+#, fuzzy
+msgid "audit_admin_default"
+msgstr "%1$s committed unknown admin action %2$s to ID %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:153
+#, fuzzy
+msgid "audit_admin_feature_remove"
+msgstr "%1$s removed feature %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is an application, like Firefox.
+#: controllers/components/audit.php:92
+#, fuzzy
+msgid "audit_application_create"
+msgstr "%1$s created application %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is an application, like Firefox.
+#: controllers/components/audit.php:95
+#, fuzzy
+msgid "audit_application_edit"
+msgstr "%1$s edited application %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a version number, like 3.5.
+#. %3$s is an application, like Firefox.
+#: controllers/components/audit.php:105
+#, fuzzy
+msgid "audit_appversion_create"
+msgstr "%1$s created version %2$s for %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a version number, like 3.5.
+#. %3$s is an application, like Firefox.
+#: controllers/components/audit.php:108
+#, fuzzy
+msgid "audit_appversion_delete"
+msgstr "%1$s deleted version %2$s for %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a config field, like "awesomeness".
+#. %3$s is a config value, like "off".
+#. %4$s is a config value, like "on".
+#: controllers/components/audit.php:210
+#, fuzzy
+msgid "audit_config"
+msgstr "%1$s changed config '%2$s' from '%3$s' to '%4$s'"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:258
+#, fuzzy
+msgid "audit_editor_default"
+msgstr "%1$s committed unknown editor action %2$s to ID %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#: controllers/components/audit.php:236
+#, fuzzy
+msgid "audit_editor_feature_remove"
+msgstr "%1$s removed addon %2$s from feature list"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#: controllers/components/audit.php:231
+#, fuzzy
+msgid "audit_feature_add"
+msgstr "%1$s added addon %2$s to feature list"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:149
+#, fuzzy
+msgid "audit_feature_edit"
+msgstr "%1$s changed a feature for %2$s locale"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#: controllers/components/audit.php:241
+#, fuzzy
+msgid "audit_feature_locale_change"
+msgstr "%1$s changed locales for addon %2$s on feature list"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:83
+#, fuzzy
+msgid "audit_file_recalchash"
+msgstr "%1$s recalculated the hash for file %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>user name</a>
+#. %3$s is <a>group name</a>
+#: controllers/components/audit.php:182
+#, fuzzy
+msgid "audit_group_addmember"
+msgstr "%1$s added %2$s to group %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:313
+#, fuzzy
+msgid "audit_group_associated"
+msgstr "%1$s associated themselves with %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:162
+#, fuzzy
+msgid "audit_group_create"
+msgstr "%1s created group %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:170
+#, fuzzy
+msgid "audit_group_delete"
+msgstr "%1$s deleted group %2$s (ID %3$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:165
+#, fuzzy
+msgid "audit_group_edit"
+msgstr "%1$s edited group %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>user name</a>
+#. %3$s is <a>group name</a>
+#: controllers/components/audit.php:188
+#, fuzzy
+msgid "audit_group_removemember"
+msgstr "%1$s removed %2$s from group %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:280
+#, fuzzy
+msgid "audit_l10n_default"
+msgstr "%1$s committed unknown action %2$s for %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:295
+#, fuzzy
+msgid "audit_modify_locked_group"
+msgstr "%1$s attempted to modify locked group %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:299
+#, fuzzy
+msgid "audit_modify_other_locale"
+msgstr "%1$s attempted to modify translations in %2$s without permission"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a platform, like <a>Windows</a>
+#: controllers/components/audit.php:135
+#, fuzzy
+msgid "audit_platform_create"
+msgstr "%1$s created platform %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a platform, like <a>Windows</a>
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:143
+#, fuzzy
+msgid "audit_platform_delete"
+msgstr "%1$s deleted platform %2$s (ID %3$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a platform, like <a>Windows</a>
+#: controllers/components/audit.php:138
+#, fuzzy
+msgid "audit_platform_edit"
+msgstr "%1$s edited platform %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a part of the admin, like 'Site Config'
+#: controllers/components/audit.php:288
+#, fuzzy
+msgid "audit_reauthentication_failure"
+msgstr "%1$s failed to re-authenticate to access %2$s."
+
+#. %1$s is <a>user name</a>
+#. %2$s is the name of a canned response, like 'Ready for the public'
+#: controllers/components/audit.php:198
+#, fuzzy
+msgid "audit_response_create"
+msgstr "%1$s created response %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is the name of a canned response, like 'Ready for the public'
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:206
+#, fuzzy
+msgid "audit_response_delete"
+msgstr "%1$s deleted response %2$s (ID %3$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is the name of a canned response, like 'Ready for the public'
+#: controllers/components/audit.php:201
+#, fuzzy
+msgid "audit_response_edit"
+msgstr "%1$s edited response %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:245
+#, fuzzy
+msgid "audit_review_approve"
+msgstr "%1$s approved review %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:250 controllers/components/audit.php:253
+#, fuzzy
+msgid "audit_review_delete"
+msgstr "%1$s deleted review %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:303
+#, fuzzy
+msgid "audit_security_default"
+msgstr "%1$s committed unknown security action %2$s to ID %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a category name, like <a>Search Tools</a>
+#: controllers/components/audit.php:118
+#, fuzzy
+msgid "audit_tag_create"
+msgstr "%1$s created tag %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a category name, like <a>Search Tools</a>
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:126
+#, fuzzy
+msgid "audit_tag_delete"
+msgstr "%1$s deleted category %2$s (ID %3$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a category name, like <a>Search Tools</a>
+#: controllers/components/audit.php:121
+#, fuzzy
+msgid "audit_tag_edit"
+msgstr "%1$s edited category %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:266
+#, fuzzy
+msgid "audit_update_applications"
+msgstr "%1$s updated application translations for %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:277
+#, fuzzy
+msgid "audit_update_blog"
+msgstr "%1$s updated blog post translations for %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:274
+#, fuzzy
+msgid "audit_update_platforms"
+msgstr "%1$s updated platform translations for %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:270
+#, fuzzy
+msgid "audit_update_tags"
+msgstr "%1$s updated category translations for %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>user name</a>
+#: controllers/components/audit.php:217
+#, fuzzy
+msgid "audit_user_edit"
+msgstr "%1$s edited %2$s's user information"
+
+#: controllers/addons_controller.php:1012
+msgid "browse_addons_name"
+msgstr "Modules par nom"
+
+#: controllers/addons_controller.php:1010
+msgid "browse_addons_newest"
+msgstr "Modules récents"
+
+#: controllers/addons_controller.php:1008
+msgid "browse_addons_popular"
+msgstr "Modules populaires"
+
+#: controllers/addons_controller.php:1011
+msgid "browse_addons_rated"
+msgstr "Modules selon leur évaluation"
+
+#: controllers/addons_controller.php:1009
+msgid "browse_addons_updated"
+msgstr "Modules mis à jour récemment"
+
+#: views/elements/categories.thtml:73 views/elements/categories.thtml:82
+msgid "categories_current_title"
+msgstr "Catégorie en cours"
+
+#: views/elements/categories.thtml:50
+#: views/elements/amo2009/categories.thtml:43
+#: views/elements/amo2009/categories.thtml:45
+msgid "categories_header"
+msgstr "Catégories"
+
+#: views/elements/categories.thtml:50
+#: views/elements/amo2009/categories.thtml:41
+msgid "categories_header_title"
+msgstr "Choisir une catégorie"
+
+#. %1$s is the category name
+#: views/addons/searchengines.thtml:129
+#, php-format
+msgid "category_extra_see_all"
+msgstr "%1$s, tout afficher"
+
+#. %1$s is a number.
+#: models/collection.php:130
+#, fuzzy
+msgid "collection_description_limit"
+msgstr "The description should be less than %1$s characters."
+
+#. %1$s is the name of the collection
+#: controllers/collections_controller.php:392
+#, fuzzy
+msgid "collection_detail_rss_title"
+msgstr "%s Collection"
+
+#: controllers/collections_controller.php:1065
+#, fuzzy
+msgid "collection_error_deleting_addon"
+msgstr "Error deleting add-on!"
+
+#: controllers/collections_controller.php:1051
+#, fuzzy
+msgid "collection_error_saving_addon"
+msgstr "Error saving add-on!"
+
+#: controllers/collections_controller.php:1080
+#, fuzzy
+msgid "collection_error_saving_comment"
+msgstr "Error saving comment!"
+
+#. %1$s is a number.
+#: models/collection.php:122
+#, fuzzy
+msgid "collection_name_limit"
+msgstr "The name should be less than %1$s characters."
+
+#: controllers/collections_controller.php:352
+#: controllers/collections_controller.php:487
+msgid "collection_not_found"
+msgstr "Collection introuvable&nbsp;!"
+
+#. %1$s is the text on the "create collection" button
+#: views/collections/add.thtml:91
+#, fuzzy
+msgid "collections_add_formfield_addons_description"
+msgstr ""
+"If you already know which add-ons you want to add to your collection, just "
+"start typing their names below. If you'd rather wait and do this later, just "
+"click %1$s now."
+
+#: views/collections/add.thtml:90
+#, fuzzy
+msgid "collections_add_formfield_firstaddons"
+msgstr "Choose your first add-ons"
+
+#: views/collections/add.thtml:48
+#, fuzzy
+msgid "collections_add_header"
+msgstr "Create a Collection"
+
+#: views/collections/add.thtml:97
+#, fuzzy
+msgid "collections_add_header_selectedaddons"
+msgstr "Selected Add-ons"
+
+#: views/collections/add.thtml:50
+#, fuzzy
+msgid "collections_add_intro"
+msgstr ""
+"It's easy to create your own collection of add-ons by filling in a few "
+"fields below."
+
+#: views/collections/add.thtml:92 views/collections/add.thtml:103
+#, fuzzy
+msgid "collections_add_submit"
+msgstr "Create Collection"
+
+#: views/pages/collector_faq.thtml:50 views/pages/collector_firstrun.thtml:43
+#: views/pages/collector.thtml:47 views/pages/collector_features.thtml:55
+#: controllers/search_controller.php:302
+#: controllers/collections_controller.php:206
+#: controllers/collections_controller.php:405
+#: controllers/collections_controller.php:467
+#: controllers/collections_controller.php:539
+#, fuzzy
+msgid "collections_breadcrumb"
+msgstr "Collections"
+
+#: views/collections/detail.thtml:185
+#, fuzzy
+msgid "collections_detail_a_learn"
+msgstr "Learn More"
+
+#: views/elements/amo2009/collection_add_form.thtml:53
+#: views/elements/amo2009/collections_js_init.thtml:68
+#: views/pages/collector_firstrun.thtml:64
+#, fuzzy
+msgid "collections_detail_button_add"
+msgstr "Add to Favorites"
+
+#: views/elements/amo2009/collection_add_form.thtml:50
+#: views/elements/amo2009/collections_js_init.thtml:71
+#, fuzzy
+msgid "collections_detail_button_remove"
+msgstr "Remove from Favorites"
+
+#. %1$s is a URL.
+#. %2$s is a full <a href>.
+#: views/collections/detail.thtml:62
+#, fuzzy
+msgid "collections_detail_created_desc"
+msgstr ""
+"<p>You can view your new collection below. If you'd like to set a collection "
+"nickname, upload an icon, or change additional settings, please visit the <a "
+"href='%1$s'>Manage Collections</a> page.</p><p>Your collection can be "
+"accessed at this location: %2$s</p>"
+
+#: views/collections/detail.thtml:61
+#, fuzzy
+msgid "collections_detail_created_msg"
+msgstr "Your collection is now ready!"
+
+#: views/collections/detail.thtml:109
+#, fuzzy
+msgid "collections_detail_header_about"
+msgstr "About This Collection"
+
+#. %1$s is a number.
+#: views/collections/detail.thtml:126
+#, fuzzy
+msgid "collections_detail_header_count"
+msgid_plural "collections_detail_header_count"
+msgstr[0] "%1$s Add-on in this Collection"
+msgstr[1] "%1$s Add-ons in this Collection"
+
+#: views/collections/detail.thtml:113
+#, fuzzy
+msgid "collections_detail_info_created"
+msgstr "<strong>Created by:</strong> %1$s"
+
+#: views/collections/detail.thtml:117
+#, fuzzy
+msgid "collections_detail_info_updated"
+msgstr "<strong>Updated:</strong>"
+
+#: views/elements/amo2009/collections_js_init.thtml:62
+#, fuzzy
+msgid "collections_detail_js_adding"
+msgstr "Adding to Favorites&hellip;"
+
+#: views/elements/amo2009/collections_js_init.thtml:65
+#, fuzzy
+msgid "collections_detail_js_removing"
+msgstr "Removing Favorite&hellip;"
+
+#. %1$s is a URL
+#: views/collections/detail.thtml:90
+#, fuzzy
+msgid "collections_detail_login"
+msgstr "<a href=\"%1$s\">Log in</a> to add this collection to your favorites."
+
+#: views/collections/detail.thtml:104
+#, fuzzy
+msgid "collections_detail_manage"
+msgstr "Manage Collection"
+
+#: controllers/collections_controller.php:298
+#, fuzzy
+msgid "collections_detail_sort_date"
+msgstr "Date Added"
+
+#: controllers/collections_controller.php:299
+#, fuzzy
+msgid "collections_detail_sort_name"
+msgstr "Name"
+
+#: controllers/collections_controller.php:300
+#, fuzzy
+msgid "collections_detail_sort_popularity"
+msgstr "Popularity"
+
+#. %1$s is a number.
+#: views/collections/detail.thtml:166
+#, fuzzy
+msgid "collections_detail_weekly_downloads"
+msgid_plural "collections_detail_weekly_downloads"
+msgstr[0] "%1$s download this week"
+msgstr[1] "%1$s downloads this week"
+
+#: views/collections/edit.thtml:255
+#, fuzzy
+msgid "collections_edit_addons_delete_noscript"
+msgstr "Selected add-ons will be removed upon Save"
+
+#: views/collections/edit.thtml:247
+#, fuzzy
+msgid "collections_edit_addons_description"
+msgstr ""
+"To publish new add-ons to this collection, start typing their names below."
+
+#: views/collections/edit.thtml:248
+#, fuzzy
+msgid "collections_edit_addons_description_noscript"
+msgstr ""
+"To publish new add-ons to this collection, enter a comma-separated list of "
+"Add-on IDs below."
+
+#: views/collections/edit.thtml:247 views/collections/edit.thtml:248
+#, fuzzy
+msgid "collections_edit_addons_description_publish_detailspage"
+msgstr "You can also publish an add-on from its normal listing page."
+
+#. %1$s is the date the add-on was added to the collection
+#. %1$s is the name of the user who added the add-on to the collection
+#: views/collections/edit.thtml:260
+#, fuzzy
+msgid "collections_edit_addons_listitem_added"
+msgstr "Added %1$s by %2$s"
+
+#: views/collections/edit.thtml:263
+#, fuzzy
+msgid "collections_edit_addons_listitem_comment_add"
+msgstr "Add publisher comment"
+
+#: views/collections/edit.thtml:266
+#, fuzzy
+msgid "collections_edit_addons_listitem_comment_delete"
+msgstr "Delete publisher comment"
+
+#: views/collections/edit.thtml:265
+#, fuzzy
+msgid "collections_edit_addons_listitem_comment_edit"
+msgstr "Edit publisher comment"
+
+#: views/collections/edit.thtml:271
+#, fuzzy
+msgid "collections_edit_addons_listitem_comment_note"
+msgstr ""
+"Note: Comment will appear as though written by original publisher on the "
+"original publication date"
+
+#: views/collections/edit.thtml:270
+#, fuzzy
+msgid "collections_edit_addons_listitem_comment_submit"
+msgstr "Save Comment"
+
+#: views/collections/edit.thtml:261
+#, fuzzy
+msgid "collections_edit_addons_listitem_remove"
+msgstr "Remove"
+
+#: views/collections/edit.thtml:250
+#, fuzzy
+msgid "collections_edit_addons_submit"
+msgstr "Add to Collection"
+
+#: views/collections/edit.thtml:153
+#, fuzzy
+msgid "collections_edit_check_nickname"
+msgstr "Check Availability"
+
+#: views/collections/edit.thtml:299
+#, fuzzy
+msgid "collections_edit_confirm_deletecollection"
+msgstr "Yes, I would like to delete this collection."
+
+#. %1$s is the label of the edit form's submit button
+#: views/collections/edit.thtml:300
+#, fuzzy
+msgid "collections_edit_confirm_deletecollection_description"
+msgstr "Check the box, then click on \"%1$s\" to delete this collection."
+
+#. %1$s is the "delete" submit button text
+#. %2$s is the title of the "advanced" tab
+#: views/collections/edit.thtml:95
+#, fuzzy
+msgid "collections_edit_delete_upon_submit"
+msgstr ""
+"Upon clicking \"%1$s\" below, your collection will be deleted. If you do not "
+"want to delete your collection, uncheck the confirmation box in the \"%2$s\" "
+"tab and continue editing your collection. If you leave this page without "
+"saving, your collection will also not be deleted."
+
+#: views/collections/edit.thtml:94
+#, fuzzy
+msgid "collections_edit_delete_warning"
+msgstr "Your collection is about to be deleted!"
+
+#: views/collections/add.thtml:76 views/collections/edit.thtml:144
+#, fuzzy
+msgid "collections_edit_form_error_description"
+msgstr "You must provide a description of your collection."
+
+#: views/collections/edit.thtml:181
+#, fuzzy
+msgid "collections_edit_form_error_icon"
+msgstr "There was an error uploading your icon."
+
+#: views/collections/add.thtml:69 views/collections/edit.thtml:130
+#, fuzzy
+msgid "collections_edit_form_error_name"
+msgstr "You must give your collection a name."
+
+#: views/collections/edit.thtml:158
+#, fuzzy
+msgid "collections_edit_form_error_nickname"
+msgstr "If you choose a nickname, it must be unique."
+
+#: views/collections/add.thtml:93 views/collections/edit.thtml:249
+#, fuzzy
+msgid "collections_edit_formfield_addons"
+msgstr "Add-on name:"
+
+#: views/collections/edit.thtml:281
+#, fuzzy
+msgid "collections_edit_formfield_application"
+msgstr "Associated Application"
+
+#: views/collections/edit.thtml:282
+#, fuzzy
+msgid "collections_edit_formfield_application_description"
+msgstr "Select the application that your collection supports."
+
+#: views/collections/edit.thtml:288
+#, fuzzy
+msgid "collections_edit_formfield_collectiontype"
+msgstr "Collection Type"
+
+#: views/collections/edit.thtml:295
+#, fuzzy
+msgid "collections_edit_formfield_deletecollection"
+msgstr "Delete Collection"
+
+#: views/collections/edit.thtml:296
+#, fuzzy
+msgid "collections_edit_formfield_deletecollection_description"
+msgstr "Deleting your collection will permanently erase it."
+
+#: views/collections/add.thtml:73 views/collections/edit.thtml:140
+#, fuzzy
+msgid "collections_edit_formfield_description"
+msgstr "Collection Description"
+
+#: views/collections/add.thtml:74 views/collections/edit.thtml:141
+#, fuzzy
+msgid "collections_edit_formfield_description_description"
+msgstr "Briefly describe your collection and the kind of add-ons in it"
+
+#: views/collections/edit.thtml:162
+#, fuzzy
+msgid "collections_edit_formfield_icon"
+msgstr "Icon"
+
+#: views/collections/edit.thtml:163
+#, fuzzy
+msgid "collections_edit_formfield_icon_description"
+msgstr ""
+"You can upload a JPG, GIF or PNG icon that will be resized to 32x32 pixels."
+
+#: views/collections/add.thtml:80 views/collections/edit.thtml:189
+#, fuzzy
+msgid "collections_edit_formfield_listed"
+msgstr "Who can view your collection?"
+
+#: views/collections/add.thtml:81 views/collections/edit.thtml:190
+#, fuzzy
+msgid "collections_edit_formfield_listed_description"
+msgstr ""
+"By default, collections appear in the public Collection Directory and are "
+"discoverable by anyone. If you want to restrict your collection to be "
+"viewable only by people who are given a special link, choose that option "
+"below."
+
+#: views/collections/add.thtml:84 views/collections/edit.thtml:193
+#, fuzzy
+msgid "collections_edit_formfield_listed_false"
+msgstr "Only people I invite can view my collection"
+
+#: views/collections/add.thtml:83 views/collections/edit.thtml:192
+#, fuzzy
+msgid "collections_edit_formfield_listed_true"
+msgstr "Everyone can view my collection in the directory"
+
+#: views/collections/edit.thtml:223
+#, fuzzy
+msgid "collections_edit_formfield_managers"
+msgstr "Who can manage my collection?"
+
+#: views/collections/edit.thtml:224
+#, fuzzy
+msgid "collections_edit_formfield_managers_description"
+msgstr ""
+"These users can publish add-ons to your collection, manage all add-ons and "
+"settings, and grant other users permission."
+
+#: views/collections/add.thtml:66 views/collections/edit.thtml:126
+#, fuzzy
+msgid "collections_edit_formfield_name"
+msgstr "Collection Name"
+
+#: views/collections/add.thtml:67 views/collections/edit.thtml:127
+#, fuzzy
+msgid "collections_edit_formfield_name_description"
+msgstr ""
+"Give your collection a descriptive name, such as \"Dave's Favorite Travel "
+"Add-ons\""
+
+#: views/collections/edit.thtml:148
+#, fuzzy
+msgid "collections_edit_formfield_nickname"
+msgstr "Collection Nickname"
+
+#: views/collections/edit.thtml:149
+#, fuzzy
+msgid "collections_edit_formfield_nickname_description"
+msgstr "Optionally, give your collection a unique nickname for quick access:"
+
+#: views/collections/edit.thtml:201
+#, fuzzy
+msgid "collections_edit_formfield_publishers"
+msgstr "Who can publish add-ons to your collection?"
+
+#: views/collections/edit.thtml:202
+#, fuzzy
+msgid "collections_edit_formfield_publishers_description"
+msgstr ""
+"These users can publish add-ons to your collection and remove add-ons that "
+"they publish."
+
+#: views/collections/edit.thtml:210 views/collections/edit.thtml:232
+#, fuzzy
+msgid "collections_edit_formfield_users_add"
+msgstr "Enter the e-mail address of a Firefox Add-ons account:"
+
+#: views/collections/edit.thtml:216 views/collections/edit.thtml:238
+#, fuzzy
+msgid "collections_edit_formfield_users_delete_noscript"
+msgstr "Selected accounts will be removed upon Save"
+
+#: views/collections/edit.thtml:215 views/collections/edit.thtml:237
+#, fuzzy
+msgid "collections_edit_formfield_users_new_noscript"
+msgstr ""
+"Enter a comma-separated list of e-mail addresses of Firefox Add-ons accounts"
+
+#: views/collections/edit.thtml:204 views/collections/edit.thtml:226
+#, fuzzy
+msgid "collections_edit_formfield_users_onlyme"
+msgstr "Only me"
+
+#: views/collections/edit.thtml:205 views/collections/edit.thtml:227
+#, fuzzy
+msgid "collections_edit_formfield_users_otherusers"
+msgstr "Myself and these users:"
+
+#: views/collections/edit.thtml:211 views/collections/edit.thtml:233
+#, fuzzy
+msgid "collections_edit_formfield_users_submit"
+msgstr "Add"
+
+#. %1$s is the name of the collection
+#: views/collections/edit.thtml:68
+#, fuzzy
+msgid "collections_edit_header"
+msgstr "Manage %1$s"
+
+#: views/collections/edit.thtml:246
+#, fuzzy
+msgid "collections_edit_header_addons"
+msgstr "Manage Collection Contents"
+
+#: views/collections/edit.thtml:253 views/collections/edit.thtml:258
+#, fuzzy
+msgid "collections_edit_header_addons_current"
+msgstr "Current Add-ons:"
+
+#: views/collections/edit.thtml:279
+#, fuzzy
+msgid "collections_edit_header_advanced"
+msgstr "Advanced Settings"
+
+#: views/collections/edit.thtml:186
+#, fuzzy
+msgid "collections_edit_header_permissions"
+msgstr "Manage Collection Permissions"
+
+#: views/collections/edit.thtml:170
+#, fuzzy
+msgid "collections_edit_icon_cancel"
+msgstr "Cancel"
+
+#: views/collections/edit.thtml:174 views/collections/edit.thtml:179
+#, fuzzy
+msgid "collections_edit_icon_delete"
+msgstr "Delete Icon"
+
+#: views/collections/edit.thtml:178
+#, fuzzy
+msgid "collections_edit_icon_replace"
+msgstr "Replace Icon"
+
+#. %1$s is the label of the edit form's submit button
+#: views/collections/edit.thtml:169
+#, fuzzy
+msgid "collections_edit_icon_toberemoved"
+msgstr "Icon will be removed when \"%1$s\" is clicked below"
+
+#: views/collections/edit.thtml:155
+#, fuzzy
+msgid "collections_edit_nickname_available"
+msgstr "Nickname Available"
+
+#: controllers/collections_controller.php:943
+#, fuzzy
+msgid "collections_edit_nickname_error"
+msgstr ""
+"Your nickname contained invalid characters and was corrected. Please try "
+"again."
+
+#: views/collections/edit.thtml:156
+#, fuzzy
+msgid "collections_edit_nickname_taken"
+msgstr "Nickname Taken"
+
+#. This string is followed by a URL pointing to the collection's view page
+#: views/collections/edit.thtml:75
+#, fuzzy
+msgid "collections_edit_saved_nextstep"
+msgstr "Your collection can be accessed at this location:"
+
+#: views/collections/edit.thtml:74
+#, fuzzy
+msgid "collections_edit_saved_success"
+msgstr "Your collection was successfully saved!"
+
+#: views/collections/edit.thtml:169 views/collections/edit.thtml:300
+#: views/collections/edit.thtml:308 views/pages/js_constants.js.thtml:99
+#, fuzzy
+msgid "collections_edit_submit"
+msgstr "Update Collection"
+
+#: views/collections/edit.thtml:96 views/collections/edit.thtml:297
+#: views/pages/js_constants.js.thtml:100
+#, fuzzy
+msgid "collections_edit_submit_deletecollection"
+msgstr "Delete Collection"
+
+#: views/collections/edit.thtml:111
+#, fuzzy
+msgid "collections_edit_tabheader_addons"
+msgstr "Add-ons"
+
+#: views/collections/edit.thtml:97 views/collections/edit.thtml:113
+#, fuzzy
+msgid "collections_edit_tabheader_advanced"
+msgstr "Advanced"
+
+#: views/collections/edit.thtml:108
+#, fuzzy
+msgid "collections_edit_tabheader_details"
+msgstr "Name &amp; Details"
+
+#: views/collections/edit.thtml:109
+#, fuzzy
+msgid "collections_edit_tabheader_permissions"
+msgstr "Permissions"
+
+#: models/collection_promo.php:53
+#, fuzzy
+msgid "collections_family_tagline"
+msgstr "Add-ons can keep an eye on your kids and your calendar."
+
+#: models/collection_promo.php:53
+#, fuzzy
+msgid "collections_family_title"
+msgstr "Family Organizer"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:70
+#, fuzzy
+msgid "collections_index_a_check_out"
+msgstr "Check out Add-on Collector"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:52
+#, fuzzy
+msgid "collections_index_a_create"
+msgstr "Create a Collection"
+
+#: views/collections/detail.thtml:139 views/collections/listing.thtml:85
+#: views/search/collections.thtml:84
+#, fuzzy
+msgid "collections_index_button_go"
+msgstr "Go"
+
+#. %1$s is a URL.
+#: controllers/collections_controller.php:182
+#, fuzzy
+msgid "collections_index_filler_favorites"
+msgstr ""
+"<p><strong>You don't have any favorite collections yet.</strong></p> "
+"<p>Collections you mark as favorites can be quickly accessed from this page, "
+"and will appear in the <a href='%1$s'>Add-on Collector</a> if you've "
+"installed it.</p>"
+
+#. %1$s is a URL.
+#: controllers/collections_controller.php:167
+#, fuzzy
+msgid "collections_index_filler_mine"
+msgstr ""
+"<p>You haven't created any collections yet. Collections are easy to create "
+"and fill with your favorite add-ons. <a href='%1$s'>Try it out</a>!</p>"
+
+#: views/collections/listing.thtml:51
+#, fuzzy
+msgid "collections_index_header_collections"
+msgstr "Collections"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:60
+#, fuzzy
+msgid "collections_index_header_collector"
+msgstr "Add-on Collector"
+
+#. %1$s is a comma-separated list of author names
+#: views/elements/amo2009/collection_listing_item.thtml:84
+#: views/collections/detail.thtml:151
+#, fuzzy
+msgid "collections_index_header_created"
+msgstr "created by %1$s"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:47
+#, fuzzy
+msgid "collections_index_header_what"
+msgstr "What are Collections?"
+
+#: views/collections/detail.thtml:132 views/collections/listing.thtml:78
+#: views/search/collections.thtml:66
+#, fuzzy
+msgid "collections_index_label_sortby"
+msgstr "Sort by"
+
+#: controllers/collections_controller.php:130
+#, fuzzy
+msgid "collections_index_li_editors"
+msgstr "Editor's Picks"
+
+#: views/collections/subscribe.thtml:64
+#: controllers/collections_controller.php:140
+#, fuzzy
+msgid "collections_index_li_favorites"
+msgstr "My Favorites"
+
+#: controllers/collections_controller.php:138
+#, fuzzy
+msgid "collections_index_li_mine"
+msgstr "My Collections"
+
+#: controllers/collections_controller.php:132
+#, fuzzy
+msgid "collections_index_li_popular"
+msgstr "Popular"
+
+#: views/search/collections.thtml:74 controllers/collections_controller.php:81
+#, fuzzy
+msgid "collections_index_option_all"
+msgstr "Most popular all time"
+
+#: views/search/collections.thtml:72 controllers/collections_controller.php:78
+#, fuzzy
+msgid "collections_index_option_month"
+msgstr "Most popular this month"
+
+#: views/search/collections.thtml:76 controllers/collections_controller.php:84
+#, fuzzy
+msgid "collections_index_option_newest"
+msgstr "Newest"
+
+#: views/search/collections.thtml:70 controllers/collections_controller.php:75
+#, fuzzy
+msgid "collections_index_option_week"
+msgstr "Most popular this week"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:67
+#, fuzzy
+msgid "collections_index_p_collector"
+msgstr ""
+"There's a new way to manage and find favorite add-ons. Comment, share and "
+"sync collections, all from your browser"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:48
+#, fuzzy
+msgid "collections_index_p_what_are"
+msgstr "Collections are groups of related add-ons assembled for easy sharing."
+
+#. %s is a date in the _('date') format
+#: views/elements/collections_interactive_addon.thtml:85
+#, php-format
+msgid "collections_interactive_addon_added"
+msgstr "Ajouté le %s"
+
+#: models/collection_promo.php:55
+#, fuzzy
+msgid "collections_reference_tagline"
+msgstr "Add-ons can do better research online."
+
+#: models/collection_promo.php:55
+#, fuzzy
+msgid "collections_reference_title"
+msgstr "Reference Desk"
+
+#: models/collection_promo.php:52
+#, fuzzy
+msgid "collections_social_tagline"
+msgstr "Add-ons can manage your social network."
+
+#: models/collection_promo.php:52
+#, fuzzy
+msgid "collections_social_title"
+msgstr "Social Circuit"
+
+#: views/collections/subscribe.thtml:91
+#, fuzzy
+msgid "collections_subscribe_button_close"
+msgstr "Close"
+
+#: views/collections/subscribe.thtml:70
+#, fuzzy
+msgid "collections_subscribe_error"
+msgstr ""
+"An error occurred trying to add a favorite collection. Is this collection "
+"already a favorite?"
+
+#: views/collections/subscribe.thtml:96
+#, fuzzy
+msgid "collections_subscribe_label_bothersome"
+msgstr "Don't show me this message again."
+
+#. %1$s is the collection name
+#: views/collections/subscribe.thtml:60
+#, fuzzy
+msgid "collections_subscribe_success"
+msgstr "%1$s has been added to your favorite collections."
+
+#. %1$s is the link to the "My Favorites" tab on the main collections page
+#. %2$s is the localized title of the "My Favorites" tab
+#. %3$s is the link URL to the collector add-on
+#: views/collections/subscribe.thtml:62
+#, fuzzy
+msgid "collections_subscribe_success_desc"
+msgstr ""
+"You can now quickly find this collection from the <a href=\"%1$s\">%2$s</a> "
+"tab in the directory. For an even easier way to keep track of your favorite "
+"collections, try out our <a href=\"%3$s\">Add-on Collector</a> extension for "
+"Firefox."
+
+#: views/collections/listing.thtml:55
+#, fuzzy
+msgid "collections_success_delete"
+msgstr "The collection has been deleted."
+
+#: models/collection_promo.php:54
+#, fuzzy
+msgid "collections_travel_tagline"
+msgstr "Add-ons can turn you into a travel agent."
+
+#: models/collection_promo.php:54
+#, fuzzy
+msgid "collections_travel_title"
+msgstr "The Traveler's Pack"
+
+#. A collection of add-ons that is automatically built for a user. They are "automatically published" to this collection.
+#: controllers/collections_controller.php:581
+#, fuzzy
+msgid "collections_type_autopublisher"
+msgstr "Auto-publisher"
+
+#. A collection that has been chosen by an Editor as notable or exceptional
+#: controllers/collections_controller.php:582
+#, fuzzy
+msgid "collections_type_editorspick"
+msgstr "Editor's Pick"
+
+#: controllers/collections_controller.php:580
+#, fuzzy
+msgid "collections_type_normal"
+msgstr "Normal"
+
+#: views/collections/subscribe.thtml:84
+#, fuzzy
+msgid "collections_unsubscribe_error"
+msgstr ""
+"An error occurred trying to remove a favorite collection. Was this "
+"collection not a favorite?"
+
+#. %1$s is the collection name
+#: views/collections/subscribe.thtml:78
+#, fuzzy
+msgid "collections_unsubscribe_success"
+msgstr "%1$s has been removed from your favorite collections."
+
+#: models/collection_promo.php:56
+#, fuzzy
+msgid "collections_webdev_tagline"
+msgstr "Add-ons make it easier to build the perfect website."
+
+#: models/collection_promo.php:56
+#, fuzzy
+msgid "collections_webdev_title"
+msgstr "Web Developer's Toolbox"
+
+#: views/elements/amo2009/collections_sidebar_whatare.thtml:40
+#, fuzzy
+msgid "collections_whatare_header"
+msgstr "What are Collections?"
+
+#: views/elements/amo2009/collections_sidebar_whatare.thtml:45
+#, fuzzy
+msgid "collections_whatare_learnmore"
+msgstr "Read the FAQ"
+
+#: views/elements/amo2009/collections_sidebar_whatare.thtml:44
+#, fuzzy
+msgid "collections_whatare_text"
+msgstr ""
+"There’s a new way to manage and find favorite add-ons. Comment, share and "
+"sync collections, all from your browser."
+
+#: views/pages/collector_faq.thtml:61 views/pages/collector_features.thtml:67
+#, fuzzy
+msgid "collector_features_a_home"
+msgstr "Add-on Collector Home"
+
+#: views/elements/amo2009/collector_sidebar_download.thtml:46
+#, fuzzy
+msgid "collector_features_heading_download"
+msgstr "Download the Add-on Collector:"
+
+#: views/elements/amo2009/collector_sidebar_download.thtml:43
+#: views/pages/collector_firstrun.thtml:116 views/pages/collector.thtml:69
+#, fuzzy
+msgid "collector_features_img_logo"
+msgstr "Add-on Collector Logo"
+
+#: views/compatibility/dashboard.thtml:49
+#: controllers/compatibility_controller.php:72
+msgid "compatibility_dashboard_center_header"
+msgstr "Centre de compatibilité des modules complémentaires"
+
+#. %1$s is the name of an application and a version. Example: Firefox 3.0
+#. %2$s is the name of an application. Example: Firefox
+#: views/compatibility/dashboard.thtml:50
+msgid "compatibility_dashboard_intro"
+msgstr ""
+"Préparez-vous à la sortie de %1$s grâce aux outils et à l'information "
+"disponibles pour la communauté 2$s Add-ons ci-dessous."
+
+#: views/compatibility/dashboard.thtml:103
+msgid "compatibility_dashboard_loading"
+msgstr "Chargement des données..."
+
+#: views/compatibility/dashboard.thtml:45
+msgid "compatibility_dashboard_main_link"
+msgstr "Retour à la section principale"
+
+#: views/compatibility/dashboard.thtml:100 views/compatibility/report.thtml:43
+msgid "compatibility_dashboard_report"
+msgstr "Rapport de compatibilité du module complémentaire"
+
+#: views/compatibility/dashboard.thtml:53
+#: views/compatibility/dashboard.thtml:110
+#: views/compatibility/developers.thtml:43
+msgid "compatibility_developer_info"
+msgstr "Informations pour les développeurs de modules"
+
+#: views/compatibility/developers.thtml:66
+msgid "compatibility_developers_adjust_maxversion"
+msgstr "Ajuster maxVersion sans renvoyer le fichier"
+
+#: views/compatibility/dashboard.thtml:124
+msgid "compatibility_developers_check_status"
+msgstr "Vérifier le statut de mes modules"
+
+#. %1$s is a URL
+#. %2$s is an application and version. Example: Firefox 3.0
+#: views/compatibility/dashboard.thtml:126
+msgid "compatibility_developers_login_first"
+msgstr ""
+"Si vous avez des modules hébergés sur Mozilla Add-ons, <a href=\"%1$s"
+"\">veuillez vous connecter</a> pour analyser le statut de ceux-ci pour %2$s."
+
+#: views/compatibility/dashboard.thtml:114
+msgid "compatibility_developers_mdclogo_alt"
+msgstr "Logo Mozilla Developer Center"
+
+#: views/compatibility/developers.thtml:73
+msgid "compatibility_developers_no_addons"
+msgstr "Vous n'avez aucun module hébergé sur Mozilla Add-ons."
+
+#: views/compatibility/dashboard.thtml:133
+#: views/compatibility/developers.thtml:55
+msgid "compatibility_developers_results"
+msgstr "Vérification des résultats relatifs au statut des modules"
+
+#: views/compatibility/dashboard.thtml:137
+msgid "compatibility_developers_retrieving"
+msgstr "Extraction du statut des modules hébergés..."
+
+#. %1$s is a number
+#. %2$s is an application name
+#. %3$s is a number.
+#. Full example: 50 Firefox users (10% of total)
+#: views/compatibility/developers.thtml:65
+msgid "compatibility_developers_user_count"
+msgstr "%1$s utilisateurs de %2$s (%3$s&#37; du total)"
+
+#: views/compatibility/report.thtml:45
+msgid "compatibility_report_detail_intro"
+msgstr ""
+"Les modules listés ci-dessous par popularité représentent, à la connaissance "
+"de Mozilla, 95% des modules utilisés."
+
+#: views/compatibility/dashboard.thtml:94
+msgid "compatibility_report_detailed_link"
+msgstr "Afficher le rapport détaillé"
+
+#. %1$s and %2$s are numbers
+#. %3$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:65
+msgid "compatibility_report_intro"
+msgstr ""
+"Des %1$s modules représentant 95&#37; à la connaissance de Mozilla, 95% des "
+"modules utilisés, <b>%2$s&#37;</b> sont actuellement considérés comme "
+"compatibles avec les toutes dernières versions de %3$s."
+
+#: views/compatibility/dashboard.thtml:81
+msgid "compatibility_report_legend_alpha"
+msgstr "Versions alphas"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:81
+msgid "compatibility_report_legend_alpha_description"
+msgstr "Modules compatibles avec une version alpha de %1$s"
+
+#: views/compatibility/dashboard.thtml:85
+msgid "compatibility_report_legend_beta"
+msgstr "Versions bêtas"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:85
+msgid "compatibility_report_legend_beta_description"
+msgstr ""
+"Module compatible avec une version bêta ou une version candidate de %1$s"
+
+#: views/compatibility/dashboard.thtml:89
+msgid "compatibility_report_legend_latest"
+msgstr "Dernière version"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:89
+msgid "compatibility_report_legend_latest_description"
+msgstr "Modules acutualisé pour les dernières compilations de %1$s"
+
+#: views/compatibility/dashboard.thtml:77
+msgid "compatibility_report_legend_other"
+msgstr "Autres versions"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:77
+msgid "compatibility_report_legend_other_description"
+msgstr "Modules non-compatibles avec une quelconque version de %1$s"
+
+#: views/compatibility/dashboard.thtml:62
+msgid "compatibility_report_title"
+msgstr "Rapport de compatibilité du module"
+
+#: views/compatibility/dashboard.thtml:54
+#: views/compatibility/dashboard.thtml:144 views/compatibility/users.thtml:42
+msgid "compatibility_user_info"
+msgstr "Informations pour les utilisateurs du module"
+
+#: views/compatibility/dashboard.thtml:52
+msgid "compatibility_view_report"
+msgstr "Afficher le rapport de compatibilité"
+
+#. %s is a URL
+#: views/pages/credits.thtml:142
+#, php-format
+msgid "credits_contributing"
+msgstr ""
+"Pour vous renseigner sur les manières de contribuer au projet, consultez "
+"notre %s."
+
+#: views/pages/credits.thtml:142
+msgid "credits_contributing_wikipage"
+msgstr "Page wiki"
+
+#: views/pages/credits.thtml:99
+msgid "credits_intro"
+msgstr ""
+"Mozilla aimerait remercier les personnes suivantes pour leur contribution au "
+"projet addons.mozilla.org durant toutes ces années&nbsp;:"
+
+#: views/pages/credits.thtml:103
+msgid "credits_section_developers"
+msgstr "Développeurs"
+
+#: views/pages/credits.thtml:115
+msgid "credits_section_editors"
+msgstr "Éditeurs"
+
+#: views/pages/credits.thtml:109
+msgid "credits_section_localizers"
+msgstr "Traducteurs"
+
+#: views/pages/credits.thtml:121
+msgid "credits_section_other_contributors"
+msgstr "Autres contributeurs"
+
+#: views/pages/credits.thtml:127
+msgid "credits_section_past_developers"
+msgstr "Anciens développeurs"
+
+#: views/pages/credits.thtml:133
+msgid "credits_section_software"
+msgstr "Logiciel et images"
+
+#: views/pages/credits.thtml:136
+msgid "credits_software_famfamfam"
+msgstr ""
+"Certaines icônes utilisées proviennent du <a href=\"http://www.famfamfam.com/"
+"lab/icons/silk/\">jeu d'icônes famfamfam Silk</a> sous licence <a href="
+"\"http://creativecommons.org/licenses/by/2.5/\">Creative Commons Attribution "
+"2.5</a>."
+
+#: views/pages/credits.thtml:137
+#, fuzzy
+msgid "credits_software_timeplot"
+msgstr ""
+"Some pages use elements of <a href=\"http://www.simile-widgets.org/timeplot/"
+"\">Timeplot</a>, licensed under a <a href=\"http://simile.mit.edu/license."
+"html\">BSD License</a>."
+
+#. date format string as used in PHP's strftime():
+#. http://php.net/strftime
+#: views/elements/collections_interactive_addon.thtml:85
+#: views/elements/amo2009/addon_version_detail.thtml:53
+#: views/elements/amo2009/homepage_addon.thtml:115
+#: views/elements/addon_version_detail.thtml:54
+#: views/elements/addon_listitem.thtml:124 views/elements/feature.thtml:106
+#: views/collections/detail.thtml:118 views/collections/edit.thtml:325
+#: views/users/info.thtml:76 views/editors/reviews_queue.thtml:57
+#: views/editors/reviews_queue.thtml:68 views/developers/dashboard.thtml:65
+#: views/developers/versions_edit.thtml:208 views/developers/versions.thtml:67
+#: views/search/rss/index.thtml:5 views/addons/rss/versions.thtml:42
+#: views/addons/display.thtml:104 views/addons/display.thtml:356
+#: views/addons/browse_thumbs.thtml:75 views/reviews/add.thtml:63
+#: views/reviews/display.thtml:74 views/reviews/display.thtml:160
+#: views/reviews/delete.thtml:54 controllers/statistics_controller.php:244
+#: controllers/collections_controller.php:1047
+msgid "date"
+msgstr "%x"
+
+#. date and time format string (strftime)
+#. http://php.net/strftime
+#: views/elements/addon_version_detail.thtml:53
+#: views/developers/discuss.thtml:52 views/developers/discuss.thtml:62
+#: views/admin/addons_status.thtml:57
+msgid "datetime"
+msgstr "%x %X"
+
+#: views/elements/developers/actionbar.thtml:47
+msgid "devcp_actionbar_link_details"
+msgstr "Informations détaillées"
+
+#: views/elements/developers/actionbar.thtml:42
+#: views/elements/developers/actionbar.thtml:50
+#: views/developers/dashboard.thtml:64
+msgid "devcp_actionbar_link_edit"
+msgstr "Éditer le module"
+
+#: views/elements/developers/actionbar.thtml:51
+msgid "devcp_actionbar_link_newversion"
+msgstr "Envoyer la nouvelle version"
+
+#: views/elements/developers/actionbar.thtml:44
+#: views/elements/developers/actionbar.thtml:49
+#: views/developers/dashboard.thtml:73
+msgid "devcp_actionbar_link_stats"
+msgstr "Tableau de bord des statistiques"
+
+#. %1$s is a filename, e.g. "foo.txt"
+#. %2$s is the extension, e.g. ".txt"
+#. %3$s is a list of valid extensions, like ".png, .jpg, .gif"
+#: controllers/developers_controller.php:1361
+#, fuzzy
+msgid "devcp_add_previews_extension_error"
+msgstr "File %1$s has an invalid extension (%2$s). Allowed extensions: %3$s"
+
+#. %s is the filename.
+#: controllers/developers_controller.php:1394
+#, fuzzy
+msgid "devcp_add_previews_save_error"
+msgstr "File %s could not be saved to the database. Please try again."
+
+#. %1$s is the preview ID number, %2$s is the filename.
+#: controllers/developers_controller.php:1389
+#, fuzzy
+msgid "devcp_add_previews_success_replace"
+msgstr "Preview %1$s was replaced with file %2$s successfully."
+
+#. %s is the filename.
+#: controllers/developers_controller.php:1391
+#, fuzzy
+msgid "devcp_add_previews_success_upload"
+msgstr "File %s was uploaded successfully. You can add a caption below."
+
+#: controllers/components/developers.php:1163
+msgid "devcp_additem_addontype_autodetect"
+msgstr "(auto-détection)"
+
+#: views/elements/developers/additem.thtml:76
+msgid "devcp_additem_linktitle_opensin_newwindow"
+msgstr "S'ouvre dans une nouvelle fenêtre"
+
+#: views/elements/developers/additem.thtml:41
+msgid "devcp_additem_sidebar_title"
+msgstr "Envoi de module"
+
+#: views/elements/developers/additem.thtml:53
+msgid "devcp_additem_step0_newlink"
+msgstr "Accord du développeur"
+
+#: views/elements/developers/additem.thtml:46
+msgid "devcp_additem_step1_link"
+msgstr "Étape 1&nbsp;: envoi"
+
+#: views/elements/developers/additem.thtml:47
+msgid "devcp_additem_step2_link"
+msgstr "Étape 2&nbsp;: détails du module"
+
+#: views/elements/developers/additem.thtml:48
+msgid "devcp_additem_step3_link"
+msgstr "Étape 3&nbsp;: détails de la version"
+
+#: views/elements/developers/additem.thtml:49
+msgid "devcp_additem_step4_link"
+msgstr "Étape 4&nbsp;: localisation"
+
+#: views/elements/developers/additem.thtml:50
+msgid "devcp_additem_step5_link"
+msgstr "Étape 5&nbsp;: succès"
+
+#: views/elements/developers/additem.thtml:76
+msgid "devcp_additem_submissionhelp_link"
+msgstr "Aide à la soumission"
+
+#: controllers/previews_controller.php:168
+#: controllers/previews_controller.php:277
+msgid "devcp_addon_field_preview_caption_displaytitle"
+msgstr "Vignette de prévisualisation"
+
+#: views/developers/addon_status.thtml:177
+#, fuzzy
+msgid "devcp_addon_status_action_activate"
+msgstr "Make Active"
+
+#: views/developers/addon_status.thtml:178
+#, fuzzy
+msgid "devcp_addon_status_action_activate_description"
+msgstr ""
+"Make your add-on active for it to show up in public listings and enable the "
+"update check service."
+
+#: views/developers/addon_status.thtml:135
+#, fuzzy
+msgid "devcp_addon_status_action_complete"
+msgstr "Complete Add-on"
+
+#: views/developers/addon_status.thtml:136
+#, fuzzy
+msgid "devcp_addon_status_action_complete_description"
+msgstr "Complete your add-on and move to the Sandbox"
+
+#: views/developers/addon_status.thtml:181
+#, fuzzy
+msgid "devcp_addon_status_action_deactivate"
+msgstr "Make Inactive"
+
+#: views/developers/addon_status.thtml:182
+#, fuzzy
+msgid "devcp_addon_status_action_deactivate_description"
+msgstr ""
+"Make your add-on inactive to hide it from all public listings and disable "
+"the update check service."
+
+#: views/developers/addon_status.thtml:143
+#, fuzzy
+msgid "devcp_addon_status_action_move"
+msgstr "Move to Sandbox"
+
+#: views/developers/addon_status.thtml:144
+#, fuzzy
+msgid "devcp_addon_status_action_move_description"
+msgstr "Move your add-on back to the Sandbox. This is reversible."
+
+#: views/developers/addon_status.thtml:139
+#, fuzzy
+msgid "devcp_addon_status_action_nominate"
+msgstr "Nominate for Public"
+
+#: views/developers/addon_status.thtml:140
+#, fuzzy
+msgid "devcp_addon_status_action_nominate_description"
+msgstr "Nominate your add-on to become Public"
+
+#: views/developers/addon_status.thtml:147
+#, fuzzy
+msgid "devcp_addon_status_action_public"
+msgstr "Make Public"
+
+#: views/developers/addon_status.thtml:148
+#, fuzzy
+msgid "devcp_addon_status_action_public_description"
+msgstr "Make your add-on Public again."
+
+#: views/developers/addon_status.thtml:169
+#, fuzzy
+msgid "devcp_addon_status_active"
+msgstr ""
+"Your add-on is <span class=\"inactive-0\">Active</span>. This means your add-"
+"on is showing up in all available listings appropriate for its status above."
+
+#: views/developers/addon_status.thtml:111
+#, fuzzy
+msgid "devcp_addon_status_completion_disabled"
+msgstr ""
+"Please fulfill the criteria above before you can complete your add-on and "
+"move it to the <span class=\"status-1\">Sandbox</span>."
+
+#: views/developers/addon_status.thtml:108
+#, fuzzy
+msgid "devcp_addon_status_completion_enabled"
+msgstr ""
+"You may now complete your add-on and move it to the <span class=\"status-1"
+"\">Sandbox</span> by clicking the button below."
+
+#: views/developers/addon_status.thtml:102
+#, fuzzy
+msgid "devcp_addon_status_criteria_category"
+msgstr "At least one category selected"
+
+#: views/developers/addon_status.thtml:101
+#, fuzzy
+msgid "devcp_addon_status_criteria_description"
+msgstr "Add-on Description required"
+
+#: views/developers/addon_status.thtml:99
+#, fuzzy
+msgid "devcp_addon_status_criteria_name"
+msgstr "Add-on Name required"
+
+#: views/developers/addon_status.thtml:120
+#, fuzzy
+msgid "devcp_addon_status_criteria_prerelease"
+msgstr "Add-on is not marked as pre-release."
+
+#: views/developers/addon_status.thtml:119
+#, fuzzy
+msgid "devcp_addon_status_criteria_preview"
+msgstr "At least one preview image required for extensions and themes."
+
+#: views/developers/addon_status.thtml:100
+#, fuzzy
+msgid "devcp_addon_status_criteria_summary"
+msgstr "Add-on Summary required"
+
+#. %s is the status in a span, e.g. "<span>_('Public')</span>".
+#: views/developers/addon_status.thtml:58
+#, fuzzy
+msgid "devcp_addon_status_header"
+msgstr "Add-on Status: %s"
+
+#: views/developers/addon_status.thtml:152
+#: views/developers/addon_status.thtml:173
+#, fuzzy
+msgid "devcp_addon_status_header_actions"
+msgstr "Available Actions"
+
+#: views/developers/addon_status.thtml:168
+#, fuzzy
+msgid "devcp_addon_status_header_active"
+msgstr "Active Status: <span class=\"inactive-0\">Active</span>"
+
+#: views/developers/addon_status.thtml:97
+#, fuzzy
+msgid "devcp_addon_status_header_criteria"
+msgstr "Add-on Completion Criteria"
+
+#: views/developers/addon_status.thtml:164
+#, fuzzy
+msgid "devcp_addon_status_header_inactive"
+msgstr "Active Status: <span class=\"inactive-1\">Inactive</span>"
+
+#: views/developers/addon_status.thtml:117
+#, fuzzy
+msgid "devcp_addon_status_header_nomination"
+msgstr "Public Nomination Criteria"
+
+#: views/developers/addon_status.thtml:190
+#, fuzzy
+msgid "devcp_addon_status_header_trusted"
+msgstr "Trusted Status: <span class=\"status-4\">Trusted</span>"
+
+#: views/developers/addon_status.thtml:165
+#, fuzzy
+msgid "devcp_addon_status_inactive"
+msgstr ""
+"Your add-on is <span class=\"inactive-1\">Inactive</span>. This means your "
+"add-on will not show up in any listing, regardless of its status above. "
+"Updates are <b>not</b> being provided to your add-on through the update "
+"check service."
+
+#: views/developers/addon_status.thtml:128
+#, fuzzy
+msgid "devcp_addon_status_nominate_disabled"
+msgstr ""
+"Please fulfill the criteria above before nominating your add-on to become "
+"<span class=\"status-4\">Public</span>."
+
+#: views/developers/addon_status.thtml:125
+#, fuzzy
+msgid "devcp_addon_status_nominate_enabled"
+msgstr ""
+"You may now nominate your add-on for <span class=\"status-4\">Public</span> "
+"by clicking the button below."
+
+#: views/developers/addon_status.thtml:64
+#, fuzzy
+msgid "devcp_addon_status_public"
+msgstr "Public"
+
+#: views/developers/addon_status.thtml:63
+#, fuzzy
+msgid "devcp_addon_status_sandbox"
+msgstr "Sandbox"
+
+#. %s is an email address.
+#: views/developers/addon_status.thtml:89
+#, fuzzy
+msgid "devcp_addon_status_switch_disabled"
+msgstr ""
+"Your add-on was <span class=\"status-5\">Disabled</span> by an administrator "
+"and cannot be used. If you have any questions, please e-mail %s."
+
+#: views/developers/addon_status.thtml:67
+#, fuzzy
+msgid "devcp_addon_status_switch_incomplete"
+msgstr ""
+"Your add-on is currently <span class=\"status-0\">Incomplete</span>. This "
+"means your add-on is not showing up on any portion of the site or update "
+"check service. You may come to this page to complete your add-on after it "
+"meets the criteria below for completion and transfer to the <span class="
+"\"status-1\">Sandbox</span>."
+
+#. %s is a number, perhaps 42.
+#: views/developers/addon_status.thtml:77
+#, fuzzy
+msgid "devcp_addon_status_switch_nominated"
+msgstr ""
+"Your add-on is currently nominated to become <span class=\"status-4"
+"\">Public</span> and is awaiting editor review. There are currently %s other "
+"add-ons in the nomination queue."
+
+#. %s is an email address.
+#: views/developers/addon_status.thtml:81
+#, fuzzy
+msgid "devcp_addon_status_switch_pending"
+msgstr ""
+"Your add-on is pending. This shouldn't have happened. Please e-mail %s with "
+"your add-on ID and state this error."
+
+#: views/developers/addon_status.thtml:85
+#, fuzzy
+msgid "devcp_addon_status_switch_public"
+msgstr ""
+"Your add-on is <span class=\"status-4\">Public</span>, which means it will "
+"show up in all listings and searches and can be downloaded without "
+"restriction. Updates are being provided to your add-on through the update "
+"check service."
+
+#: views/developers/addon_status.thtml:71
+#: views/developers/addon_status.thtml:75
+#, fuzzy
+msgid "devcp_addon_status_switch_sandbox"
+msgstr ""
+"Your add-on is in the <span class=\"status-1\">Sandbox</span>, which means "
+"it will show up in listings and searches, but users must log in to download "
+"it. Updates are <b>not</b> being provided to your add-on through the update "
+"check service."
+
+#. %s is the add-on name.
+#: views/developers/addon_status_nominate.thtml:43
+#: views/developers/addon_status_confirm.thtml:43
+#: views/developers/addon_status.thtml:43
+#, fuzzy
+msgid "devcp_addon_status_title"
+msgstr "%s Status"
+
+#: views/developers/addon_status.thtml:191
+#, fuzzy
+msgid "devcp_addon_status_trusted"
+msgstr ""
+"Your add-on is <span class=\"status-4\">Trusted</span>. This means you can "
+"submit updates to your add-on without editor review."
+
+#: views/developers/dashboard.thtml:68
+#, fuzzy
+msgid "devcp_dashboard_active"
+msgstr "Active"
+
+#. %1$s is the add-on type string
+#. %2$s is Inactive or Active in a <span>
+#. %3$s is the addon's public status (Public, In Sandbox, ...) in a <span>
+#: views/developers/dashboard.thtml:69
+#, fuzzy
+msgid "devcp_dashboard_addontype_status"
+msgstr "%1$s currenty %2$s and %3$s"
+
+#: views/developers/dashboard.thtml:67
+#, fuzzy
+msgid "devcp_dashboard_change_status"
+msgstr "Change Status"
+
+#. %s is the addons email address.
+#: views/developers/dashboard.thtml:99
+#, fuzzy
+msgid "devcp_dashboard_disabled_questions"
+msgstr ""
+"Your add-on was disabled by an administrator and cannot be used. If you "
+"have any questions, please email %s."
+
+#. %s is the (localized) add-on status string in a span, e.g. "Disabled"
+#: views/developers/dashboard.thtml:98
+#, fuzzy
+msgid "devcp_dashboard_disabled_status"
+msgstr "Add-on Status: %s"
+
+#: views/developers/dashboard.thtml:43
+#, fuzzy
+msgid "devcp_dashboard_header_main"
+msgstr "Developer Dashboard"
+
+#: views/developers/dashboard.thtml:110
+#, fuzzy
+msgid "devcp_dashboard_header_welcome"
+msgstr "Welcome to the Developer Dashboard"
+
+#: views/developers/dashboard.thtml:68
+#, fuzzy
+msgid "devcp_dashboard_inactive"
+msgstr "Inactive"
+
+#. %s is a date in the _('date') format
+#: views/developers/dashboard.thtml:65
+#, fuzzy
+msgid "devcp_dashboard_last_edited"
+msgstr "Last edited on %s"
+
+#: views/developers/dashboard.thtml:111
+#, fuzzy
+msgid "devcp_dashboard_learn"
+msgstr ""
+"You don't currently have any add-ons hosted on Mozilla Add-ons. To learn how "
+"the process works and submit your first add-on, click Get Started below."
+
+#: views/developers/dashboard.thtml:112
+#, fuzzy
+msgid "devcp_dashboard_start"
+msgstr "Get Started"
+
+#: views/developers/dashboard.thtml:82
+#, fuzzy
+msgid "devcp_dashboard_versions"
+msgstr "Versions and Files"
+
+#: views/developers/dashboard.thtml:91
+#, fuzzy
+msgid "devcp_dashboard_versions_new"
+msgstr "Upload a new version"
+
+#. %s is the preview ID number.
+#: controllers/developers_controller.php:1415
+#, fuzzy
+msgid "devcp_delete_previews_error"
+msgstr "Preview %s could not be deleted from the database. Please try again."
+
+#. %s is the preview ID number.
+#: controllers/developers_controller.php:1413
+#, fuzzy
+msgid "devcp_delete_previews_success"
+msgstr "Preview %s has been deleted successfully."
+
+#: controllers/developers_controller.php:1089
+#, fuzzy
+msgid "devcp_delete_version_priv_error"
+msgstr "You do not have privileges to delete versions or files."
+
+#. %1$s is the count of files, a number
+#. %2$s is a status string like _('Public') or _('Incomplete')
+#: controllers/components/amo.php:549
+#, fuzzy
+msgid "devcp_describe_version_status"
+msgid_plural "devcp_describe_version_status"
+msgstr[0] "%1$s %2$s file"
+msgstr[1] "%1$s %2$s files"
+
+#. %s is a version number. Example: 3.0
+#: views/developers/versions.thtml:65
+#, php-format
+msgid "devcp_details_version"
+msgstr "Version %s"
+
+#: views/developers/discuss.thtml:68
+#, fuzzy
+msgid "devcp_discuss_addreply_header"
+msgstr "Add Reply"
+
+#: views/developers/discuss.thtml:57
+#, fuzzy
+msgid "devcp_discuss_allreplies_header"
+msgstr "Replies"
+
+#. notice when an error occurs saving a discussion reply
+#. %1 is the email address (linked) for the amo-editors list
+#: views/developers/discuss.thtml:70
+#, fuzzy
+msgid "devcp_discuss_error_notice"
+msgstr ""
+"There was an error saving your reply. Please contact %1$s about the issue."
+
+#. %1 is the add-on name, %2 is the add-on's version number currently being reviewed by an editor
+#: views/developers/discuss.thtml:46
+#, fuzzy
+msgid "devcp_discuss_intro"
+msgstr ""
+"A Mozilla Add-ons Editor requested further information from you regarding "
+"version %2$s of your add-on %1$s."
+
+#. %1 is the add-on name
+#: views/developers/discuss.thtml:43
+#, fuzzy
+msgid "devcp_discuss_pagetitle"
+msgstr "Provide More Information For the Add-on Review of %1$s"
+
+#. submit button text
+#: views/developers/discuss.thtml:79
+#, fuzzy
+msgid "devcp_discuss_submit_reply"
+msgstr "Submit Reply"
+
+#: views/developers/discuss.thtml:72
+#, fuzzy
+msgid "devcp_discuss_success_message"
+msgstr ""
+"Your reply was successfully saved. The other participants of the discussion "
+"will be notified by email."
+
+#. in an author/editor discussion about an add-on to be reviewed:
+#. %1 is the commenter's user name (linked).
+#. %2 is the full date the comment was made.
+#: views/developers/discuss.thtml:52 views/developers/discuss.thtml:62
+#, fuzzy
+msgid "devcp_discuss_writtenby"
+msgstr "written by %1$s on %2$s"
+
+#: views/developers/addon_edit_authors.thtml:72
+#: views/developers/addon_edit_authors.thtml:81
+#, fuzzy
+msgid "devcp_edit_authors_add_author"
+msgstr "Add New Author"
+
+#: views/developers/addon_edit_authors.thtml:96
+#, fuzzy
+msgid "devcp_edit_authors_add_author_button"
+msgstr "Add Author"
+
+#: views/developers/addon_edit_authors.thtml:83
+#, fuzzy
+msgid "devcp_edit_authors_add_email"
+msgstr "Author Account Email:"
+
+#: views/developers/addon_edit_authors.thtml:98
+#, fuzzy
+msgid "devcp_edit_authors_add_loading"
+msgstr "Checking account email..."
+
+#: views/developers/addon_edit_authors.thtml:70
+#, fuzzy
+msgid "devcp_edit_authors_click_save"
+msgstr "Click the Update Authors button below to save."
+
+#: views/developers/addon_edit_authors.thtml:58
+#, fuzzy
+msgid "devcp_edit_authors_header_current"
+msgstr "Current Authors"
+
+#: views/developers/addon_edit_authors.thtml:50
+#, fuzzy
+msgid "devcp_edit_authors_header_manage"
+msgstr "Manage Add-on Authors"
+
+#: views/developers/addon_edit_authors.thtml:93
+#, fuzzy
+msgid "devcp_edit_authors_label_add_listed"
+msgstr "List as author in pubilc display pages"
+
+#: views/developers/addon_edit_authors.thtml:89
+#, fuzzy
+msgid "devcp_edit_authors_label_developer"
+msgstr ""
+"<strong>Developer</strong> - Can manage all aspects of the add-on listing, "
+"except for adding and removing other authors."
+
+#: views/developers/addon_edit_authors.thtml:88
+#, fuzzy
+msgid "devcp_edit_authors_label_owner"
+msgstr ""
+"<strong>Owner</strong> - Can manage all aspects of the add-on listing, "
+"including adding and removing other authors."
+
+#: views/developers/addon_edit_authors.thtml:90
+#, fuzzy
+msgid "devcp_edit_authors_label_viewer"
+msgstr ""
+"<strong>Viewer</strong> - Can view add-on developer listing and statistics, "
+"but can't make any changes."
+
+#. Placeholder for the empty option in a <select>.
+#: views/developers/addon_edit_categories.thtml:69
+#, fuzzy
+msgid "devcp_edit_authors_option_empty"
+msgstr "----------------"
+
+#: views/developers/addon_edit_authors.thtml:86
+#, fuzzy
+msgid "devcp_edit_authors_select_role"
+msgstr "Select a role for the author:"
+
+#. Column name in a table.
+#: views/developers/addon_edit_authors.thtml:62
+#, fuzzy
+msgid "devcp_edit_authors_th_author"
+msgstr "Author"
+
+#. Column name in a table.
+#: views/developers/addon_edit_authors.thtml:64
+#, fuzzy
+msgid "devcp_edit_authors_th_listed"
+msgstr "Listed"
+
+#. Column name in a table.
+#: views/developers/addon_edit_authors.thtml:63
+#, fuzzy
+msgid "devcp_edit_authors_th_role"
+msgstr "Role"
+
+#: views/developers/addon_edit_authors.thtml:77
+#, fuzzy
+msgid "devcp_edit_authors_update_author"
+msgstr "Update authors"
+
+#: views/developers/addon_edit_categories.thtml:99
+#, fuzzy
+msgid "devcp_edit_categories_button_update"
+msgstr "Update Categories"
+
+#: views/developers/addon_edit_categories.thtml:88
+#, fuzzy
+msgid "devcp_edit_categories_does_not_fit"
+msgstr "My add-on doesn't fit into any available categories."
+
+#. %s is the application name (Firefox, Thunderbird).
+#: views/developers/addon_edit_categories.thtml:61
+#, fuzzy
+msgid "devcp_edit_categories_header_application"
+msgstr "%s Categories"
+
+#: views/developers/addon_edit_categories.thtml:49
+#, fuzzy
+msgid "devcp_edit_categories_header_manage"
+msgstr "Manage Add-on Categories"
+
+#: views/developers/addon_edit_categories.thtml:91
+#, fuzzy
+msgid "devcp_edit_categories_hover"
+msgstr "Hover over a category to see its description."
+
+#. %s is the category number (1, 2, 3).
+#: views/developers/addon_edit_categories.thtml:67
+#, fuzzy
+msgid "devcp_edit_categories_label_category_num"
+msgstr "Category %s"
+
+#: views/developers/addon_edit_categories.thtml:94
+#: views/developers/addon_edit_categories.thtml:103
+#, fuzzy
+msgid "devcp_edit_categories_none_available"
+msgstr "No categories are available for this add-on type and application."
+
+#: views/developers/addon_edit_categories.thtml:86
+#, fuzzy
+msgid "devcp_edit_categories_other"
+msgstr ""
+"Place your add-on into this category only if it does not fit into any other "
+"available categories."
+
+#. %s is the application name (Firefox, Thunderbird).
+#: views/developers/addon_edit_categories.thtml:63
+#, fuzzy
+msgid "devcp_edit_categories_select_application_categories"
+msgstr "Select up to three %s categories for your add-on"
+
+#: views/developers/addon_edit.thtml:47
+#, fuzzy
+msgid "devcp_edit_dd_manage_authors"
+msgstr "Add or remove users that can manage this add-on."
+
+#: views/developers/addon_edit.thtml:49
+#, fuzzy
+msgid "devcp_edit_dd_manage_categories"
+msgstr ""
+"Select the relevant categories for each application your add-on supports."
+
+#: views/developers/addon_edit.thtml:51
+#, fuzzy
+msgid "devcp_edit_dd_manage_description"
+msgstr ""
+"Add and modify translations for your add-on's summary, description, end-user "
+"license, and privacy policy."
+
+#: views/developers/addon_edit.thtml:53
+#, fuzzy
+msgid "devcp_edit_dd_manage_properties"
+msgstr "Change your add-on's name, homepage, icon, and other flags."
+
+#: views/developers/addon_edit_descriptions.thtml:116
+#, fuzzy
+msgid "devcp_edit_description_button_update"
+msgstr "Update Descriptions"
+
+#: views/developers/addon_edit_descriptions.thtml:115
+#, fuzzy
+msgid "devcp_edit_description_correct_error"
+msgstr "Please correct the errors above indicated in red."
+
+#: views/developers/addon_edit_descriptions.thtml:51
+#, fuzzy
+msgid "devcp_edit_descriptions_header"
+msgstr "Edit Add-on Descriptions"
+
+#: views/developers/addon_edit_descriptions.thtml:94
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_comments_description"
+msgstr ""
+"Any information end users may want to know that isn't necessarily applicable "
+"to the add-on summary or description. Common uses include listing known "
+"major bugs, information on how to report bugs, anticipated release date of a "
+"new version, etc."
+
+#: views/developers/addon_edit_descriptions.thtml:93
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_comments_name"
+msgstr "Developer Comments"
+
+#: views/developers/addon_edit_descriptions.thtml:86
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_description_description"
+msgstr ""
+"The description of your add-on is a longer explanation of features, "
+"functionality, and other relevant information. It is displayed under the "
+"summary on the add-on's display page."
+
+#: views/developers/addon_edit_descriptions.thtml:85
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_description_name"
+msgstr "Add-on Description"
+
+#: views/developers/addon_edit_descriptions.thtml:103
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_eula_description"
+msgstr ""
+"If your add-on has an End-User License Agreement (EULA), please enter its "
+"text below. If set below, users will be required to agree to this before "
+"installing your add-on. Please note that a EULA is not the same as a code "
+"license such as GPL or MPL."
+
+#: views/developers/addon_edit_descriptions.thtml:102
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_eula_name"
+msgstr "End-User License Agreement"
+
+#: views/developers/addon_edit_descriptions.thtml:112
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_privacy_description"
+msgstr ""
+"If your add-on has a privacy policy, enter its text here. Your add-on's "
+"display page will display a link to the policy."
+
+#: views/developers/addon_edit_descriptions.thtml:111
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_privacy_name"
+msgstr "Privacy Policy"
+
+#: views/developers/addon_edit_descriptions.thtml:78
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_summary_description"
+msgstr ""
+"The summary is a short explanation of your add-on's basic functionality that "
+"is displayed in search and browse listings, as well as at the top of your "
+"add-on's display page. <strong>Limit of 250 characters.</strong>"
+
+#: views/developers/addon_edit_descriptions.thtml:77
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_summary_name"
+msgstr "Add-on Summary"
+
+#: views/developers/addon_edit.thtml:46
+#, fuzzy
+msgid "devcp_edit_dt_manage_authors"
+msgstr "Manage Add-on Authors"
+
+#: views/developers/addon_edit.thtml:48
+#, fuzzy
+msgid "devcp_edit_dt_manage_categories"
+msgstr "Manage Add-on Categories"
+
+#: views/developers/addon_edit.thtml:50
+#, fuzzy
+msgid "devcp_edit_dt_manage_descriptions"
+msgstr "Manage Add-on Descriptions"
+
+#: views/developers/addon_edit.thtml:52
+#, fuzzy
+msgid "devcp_edit_dt_manage_properties"
+msgstr "Manage Add-on Properties"
+
+#: views/developers/addon_edit_properties.thtml:170
+msgid "devcp_edit_label_externalsoftware"
+msgstr "Ce module a besoin d'un logiciel externe"
+
+#: views/developers/addon_edit_properties.thtml:205
+msgid "devcp_edit_label_locale_disambiguation"
+msgstr "Information complémentaire sur la locale"
+
+#: views/developers/addon_edit_properties.thtml:168
+msgid "devcp_edit_label_prerelease"
+msgstr "Ceci est une pré-version"
+
+#: views/developers/addon_edit_properties.thtml:169
+msgid "devcp_edit_label_sitespecific"
+msgstr "Ce module concerne un site web spécifique"
+
+#: views/developers/addon_edit_properties.thtml:202
+msgid "devcp_edit_label_target_locale"
+msgstr "Locale cible"
+
+#: views/developers/addon_edit_properties.thtml:212
+#, fuzzy
+msgid "devcp_edit_properties_button_update"
+msgstr "Update Properties"
+
+#: views/developers/addon_edit_properties.thtml:198
+#, fuzzy
+msgid "devcp_edit_properties_change_guid"
+msgstr "Only change if you understand all of the consequences."
+
+#: views/developers/addon_edit_properties.thtml:109
+#, fuzzy
+msgid "devcp_edit_properties_current_icon"
+msgstr "Current Icon"
+
+#: views/developers/addon_edit_properties.thtml:85
+#, fuzzy
+msgid "devcp_edit_properties_default_locale"
+msgstr ""
+"An add-on's default locale is the main locale in which translations must be "
+"present. If translations for your add-on's descriptions are unavailable in a "
+"user's selected language, they will fall back to this default locale."
+
+#: views/developers/addon_edit_properties.thtml:167
+#, fuzzy
+msgid "devcp_edit_properties_flags"
+msgstr "These flags are used to filter and classify add-ons."
+
+#: views/developers/addon_edit_properties.thtml:174
+#, fuzzy
+msgid "devcp_edit_properties_guid"
+msgstr ""
+"The GUID of your add-on is specified in its install.rdf and uniquely "
+"identifies it. You cannot change your GUID once it is listed on Mozilla Add-"
+"ons."
+
+#: views/developers/addon_edit_properties.thtml:53
+#, fuzzy
+msgid "devcp_edit_properties_header"
+msgstr "Edit Add-on Properties"
+
+#: views/developers/addon_edit_properties.thtml:186
+#, fuzzy
+msgid "devcp_edit_properties_header_addon_type"
+msgstr "Add-on Type"
+
+#: views/developers/addon_edit_properties.thtml:181
+#, fuzzy
+msgid "devcp_edit_properties_header_admin_settings"
+msgstr "Admin Settings"
+
+#: views/developers/addon_edit_properties.thtml:84
+#, fuzzy
+msgid "devcp_edit_properties_header_default_locale"
+msgstr "Default Locale"
+
+#: views/developers/addon_edit_properties.thtml:166
+#, fuzzy
+msgid "devcp_edit_properties_header_flags"
+msgstr "Add-on Flags"
+
+#: views/developers/addon_edit_properties.thtml:173
+#: views/developers/addon_edit_properties.thtml:197
+#, fuzzy
+msgid "devcp_edit_properties_header_guid"
+msgstr "Add-on GUID"
+
+#: views/developers/addon_edit_properties.thtml:104
+#, fuzzy
+msgid "devcp_edit_properties_header_icon"
+msgstr "Add-on Icon"
+
+#: views/developers/addon_edit_properties.thtml:159
+#, fuzzy
+msgid "devcp_edit_properties_header_other_settings"
+msgstr "Other Settings"
+
+#. A header on the admin page to toggle trusted status.
+#: views/developers/addon_edit_properties.thtml:182
+#, fuzzy
+msgid "devcp_edit_properties_header_trusted"
+msgstr "Trusted Add-on?"
+
+#: views/developers/addon_edit_properties.thtml:160
+#, fuzzy
+msgid "devcp_edit_properties_header_view_source"
+msgstr "View Source Online"
+
+#. %s is a comma-separated list of image extensions ".png, .jpg"
+#: views/developers/addon_edit_properties.thtml:106
+#, fuzzy
+msgid "devcp_edit_properties_icon"
+msgstr ""
+"The add-on icon is a small image that is displayed next to your add-on's "
+"name in browse and search results, display pages, and in the add-on "
+"installation dialog. The image will automatically be resized to 32 x 32 "
+"pixels. Please use one of the following image types: %s"
+
+#: views/developers/addon_edit_properties.thtml:171
+#, fuzzy
+msgid "devcp_edit_properties_label_binary"
+msgstr "This add-on contains binary components"
+
+#: views/developers/addon_edit_properties.thtml:185
+#, fuzzy
+msgid "devcp_edit_properties_label_not_trusted"
+msgstr "Not Trusted"
+
+#: views/developers/addon_edit_properties.thtml:184
+#, fuzzy
+msgid "devcp_edit_properties_label_trusted"
+msgstr "Trusted"
+
+#: views/developers/addon_edit_properties.thtml:110
+#, fuzzy
+msgid "devcp_edit_properties_new_icon"
+msgstr "New Icon"
+
+#: views/developers/addon_edit_properties.thtml:118
+#, fuzzy
+msgid "devcp_edit_properties_remove_icon"
+msgstr "Remove Icon"
+
+#: views/developers/addon_edit_properties.thtml:136
+#, fuzzy
+msgid "devcp_edit_properties_transbox_homepage_description"
+msgstr ""
+"If your add-on has another homepage, enter its address here. Adding other "
+"translations is not necessary unless your website is localized into other "
+"languages."
+
+#: views/developers/addon_edit_properties.thtml:135
+#, fuzzy
+msgid "devcp_edit_properties_transbox_homepage_name"
+msgstr "Add-on Homepage"
+
+#: views/developers/addon_edit_properties.thtml:79
+#, fuzzy
+msgid "devcp_edit_properties_transbox_name_description"
+msgstr "The name of your add-on is displayed everywhere your add-on is listed."
+
+#: views/developers/addon_edit_properties.thtml:78
+#, fuzzy
+msgid "devcp_edit_properties_transbox_name_name"
+msgstr "Add-on Name"
+
+#: views/developers/addon_edit_properties.thtml:145
+#, fuzzy
+msgid "devcp_edit_properties_transbox_supportemail_description"
+msgstr ""
+"If you have an email address for support inquiries, enter it here. Adding "
+"other translations is not necessary unless you have different email "
+"addresses for different languages."
+
+#: views/developers/addon_edit_properties.thtml:144
+#, fuzzy
+msgid "devcp_edit_properties_transbox_supportemail_name"
+msgstr "Support Email Address"
+
+#: views/developers/addon_edit_properties.thtml:154
+#, fuzzy
+msgid "devcp_edit_properties_transbox_supporturl_description"
+msgstr ""
+"If your add-on has a support website or forum, enter its address here. "
+"Adding other translations is not necessary unless your website is localized "
+"into other languages."
+
+#: views/developers/addon_edit_properties.thtml:153
+#, fuzzy
+msgid "devcp_edit_properties_transbox_supporturl_name"
+msgstr "Support Website"
+
+#: views/developers/addon_edit_properties.thtml:183
+#, fuzzy
+msgid "devcp_edit_properties_trusted"
+msgstr "Trusted add-ons can become public without Editor review."
+
+#. %s is href="..." and should stay in the <a> tag.
+#: views/developers/addon_edit_properties.thtml:119
+#, fuzzy
+msgid "devcp_edit_properties_undelete"
+msgstr "Icon will be deleted on save. <a %s>Cancel?</a>"
+
+#: views/developers/addon_edit_properties.thtml:161
+#, fuzzy
+msgid "devcp_edit_properties_view_source"
+msgstr ""
+"The source of your add-on files can be viewed online by any logged in user "
+"if you wish."
+
+#: views/developers/addon_edit_properties.thtml:162
+#, fuzzy
+msgid "devcp_edit_properties_view_source_allow"
+msgstr "Allow online source viewing"
+
+#: views/developers/addon_edit_properties.thtml:163
+#, fuzzy
+msgid "devcp_edit_properties_view_source_do_not_allow"
+msgstr "Do not allow online source viewing"
+
+#: views/elements/developers/editbox.thtml:46
+#, fuzzy
+msgid "devcp_editbox_authors"
+msgstr "Authors"
+
+#: views/elements/developers/editbox.thtml:47
+#, fuzzy
+msgid "devcp_editbox_categories"
+msgstr "Categories"
+
+#: views/elements/developers/editbox.thtml:52
+#, fuzzy
+msgid "devcp_editbox_change_status"
+msgstr "Change Status"
+
+#: views/elements/developers/editbox.thtml:48
+#, fuzzy
+msgid "devcp_editbox_descriptions"
+msgstr "Descriptions"
+
+#: views/elements/developers/editbox.thtml:43
+#, fuzzy
+msgid "devcp_editbox_edit_addon"
+msgstr "Edit Add-on"
+
+#: views/elements/developers/editbox.thtml:57
+#, fuzzy
+msgid "devcp_editbox_new_version"
+msgstr "New Version"
+
+#: views/elements/developers/editbox.thtml:49
+#, fuzzy
+msgid "devcp_editbox_properties"
+msgstr "Properties"
+
+#: views/elements/developers/editbox.thtml:60
+#, fuzzy
+msgid "devcp_editbox_screenshots"
+msgstr "Preview Screenshots"
+
+#: views/elements/developers/editbox.thtml:53
+#, fuzzy
+msgid "devcp_editbox_statistics_dashboard"
+msgstr "Statistics Dashboard"
+
+#: views/elements/developers/editbox.thtml:54
+#, fuzzy
+msgid "devcp_editbox_versions"
+msgstr "Versions and Files"
+
+#: views/elements/developers/editbox.thtml:42
+#, fuzzy
+msgid "devcp_editbox_view_listing"
+msgstr "View Listing"
+
+#: views/elements/developers/editorsmenu.thtml:59
+msgid "devcp_editorsqueue_featured"
+msgstr "Modules essentiels"
+
+#. %1 is the review count
+#: views/elements/developers/editorsqueue.thtml:42
+#: views/elements/developers/editorsmenu.thtml:56
+#, php-format
+msgid "devcp_editorsqueue_moderatedreviews"
+msgid_plural "devcp_editorsqueue_moderatedreviews"
+msgstr[0] "Une révision modérée"
+msgstr[1] "Révisions modérées (%s)"
+
+#. %1 is the nominated addons count
+#: views/elements/developers/editorsqueue.thtml:44
+#: views/elements/developers/editorsmenu.thtml:58
+#, php-format
+msgid "devcp_editorsqueue_nominated"
+msgid_plural "devcp_editorsqueue_nominated"
+msgstr[0] "Un module nominé"
+msgstr[1] "Modules nominés (%s)"
+
+#. %1 is the update count
+#: views/elements/developers/editorsqueue.thtml:43
+#: views/elements/developers/editorsmenu.thtml:57
+#, php-format
+msgid "devcp_editorsqueue_pendingupdates"
+msgid_plural "devcp_editorsqueue_pendingupdates"
+msgstr[0] "Une mise à jour en attente"
+msgstr[1] "Mises à jour en attente (%s)"
+
+#: controllers/statistics_controller.php:147
+#: controllers/statistics_controller.php:361
+#: controllers/previews_controller.php:108
+#: controllers/previews_controller.php:211
+#: controllers/previews_controller.php:312
+msgid "devcp_error_addon_access_denied"
+msgstr "Vous n'avez pas accès à ce module."
+
+#. %s is a complete URL with the text from devcp_error_appversion_reference_link_text
+#. in the <a> tag. This should be fixed.
+#: controllers/components/developers.php:591
+#, php-format
+msgid "devcp_error_appversion_reference_link"
+msgstr "Veuillez consulter %s pour référence."
+
+#. This is the link text in the <a> for devcp_error_appversion_reference_link. This
+#. should be fixed.
+#: controllers/components/developers.php:591
+msgid "devcp_error_appversion_reference_link_text"
+msgstr "cette page"
+
+#: views/developers/addon_edit_authors.thtml:76
+#, fuzzy
+msgid "devcp_error_empty_authors"
+msgstr "Your add-on must have at least one owner."
+
+#. %1$s is the name of the file
+#: controllers/components/developers.php:658
+#, fuzzy
+msgid "devcp_error_file_exists"
+msgstr ""
+"A version of that addon already exists. To replace it, you must delete the "
+"file %1$s first."
+
+#. %1$s is a file extension. Example: .exe
+#. %2$s is a comma separated list of extensions. Example: .xpi, .jar
+#: controllers/components/developers.php:355
+#, php-format
+msgid "devcp_error_file_extension"
+msgstr ""
+"Cette extension de fichier (%s) n'est pas autorisée pour le type de module "
+"sélectionné. Veuillez utiliser l'une des extensions suivantes&nbsp;: %s"
+
+#: controllers/components/developers.php:64
+msgid "devcp_error_five_categories"
+msgstr "Vous ne pouvez pas sélectionner plus de cinq catégories."
+
+#: controllers/components/developers.php:526
+msgid "devcp_error_guid_application"
+msgstr "L'ID de ce module est déjà utilisée par une autre application."
+
+#: controllers/components/developers.php:337
+#: controllers/components/developers.php:389
+msgid "devcp_error_http_incomplete"
+msgstr "Transfert incomplet"
+
+#: controllers/components/developers.php:335
+#: controllers/components/developers.php:336
+#: controllers/components/developers.php:387
+#: controllers/components/developers.php:388
+msgid "devcp_error_http_maxupload"
+msgstr "La taille de fichier à l'envoi dépasse la limite maximale."
+
+#: controllers/components/developers.php:338
+#: controllers/components/developers.php:390
+msgid "devcp_error_http_nofile"
+msgstr "Aucun fichier envoyé"
+
+#. %1$s is a file extension. Example: .exe
+#. %2$s is a comma separated list of extensions. Example: .xpi, .jar
+#: controllers/components/developers.php:401
+#, php-format
+msgid "devcp_error_icon_extension"
+msgstr ""
+"Cette extension de fichier (%s) n'est pas autorisée pour une icône. Veuillez "
+"utiliser une des extensions suivantes&nbsp;: %s"
+
+#: controllers/developers_controller.php:504
+msgid "devcp_error_index_rdf_notfound"
+msgstr "install.rdf manquant."
+
+#: controllers/components/developers.php:601
+msgid "devcp_error_install_manifest"
+msgstr "Les erreurs suivantes ont été trouvées dans install.rdf:"
+
+#: controllers/developers_controller.php:1463
+msgid "devcp_error_invalid_addontype"
+msgstr "Veuillez sélectionner un type de module valide."
+
+#. %$1s is a version. Example: 3.1.1
+#. %$2s is an add-on name.
+#: controllers/components/developers.php:569
+#: controllers/components/developers.php:581
+#, php-format
+msgid "devcp_error_invalid_appversion"
+msgstr "%s n'est pas une version valide pour %s"
+
+#. %s is a string
+#: controllers/components/developers.php:521
+#, php-format
+msgid "devcp_error_invalid_guid"
+msgstr "L'ID de ce module est invalide&nbsp;: %s"
+
+#. %$1s is a version. Example: 3.1.1
+#. %$2s is an add-on name.
+#: controllers/components/developers.php:572
+#, php-format
+msgid "devcp_error_invalid_minversion"
+msgstr ""
+"%s n'est pas une version valide pour %s&nbsp;: Les versions minimales ne "
+"peuvent contenir le caratère *"
+
+#: controllers/components/developers.php:536
+msgid "devcp_error_invalid_version"
+msgstr ""
+"La version de ce module est invalide&nbsp;: veuillez consulter la <a href="
+"\"http://developer.mozilla.org/en/docs/Toolkit_version_format"
+"\">spécification</a>"
+
+#: controllers/components/developers.php:531
+msgid "devcp_error_invalid_version_spaces"
+msgstr ""
+"La version de ce module est invalide&nbsp;: les versions ne peuvent contenir "
+"d'espaces."
+
+#. %s is an error message from the parser.
+#: controllers/components/developers.php:501
+#, php-format
+msgid "devcp_error_manifest_parse"
+msgstr ""
+"L'erreur suivante a été rencontrée lors de l'analyse du fichier install."
+"rdf&nbsp;: %s"
+
+#: controllers/components/developers.php:373
+msgid "devcp_error_move_file"
+msgstr "Impossible de déplacer le fichier"
+
+#. %s is the name of a file
+#: controllers/components/developers.php:650
+#: controllers/components/developers.php:662
+#: controllers/components/developers.php:667
+#: controllers/components/developers.php:727
+#: controllers/components/developers.php:738
+#: controllers/components/developers.php:743
+#, php-format
+msgid "devcp_error_moving_file"
+msgstr "Une erreur a été rencontrée lors du déplacement de %s."
+
+#: controllers/components/developers.php:595
+msgid "devcp_error_mozilla_application"
+msgstr "Vous devez avoir au moins un application cible Mozilla valide."
+
+#: controllers/components/developers.php:516
+msgid "devcp_error_no_guid"
+msgstr "Aucun ID n'a été trouvé pour ce module dans install.rdf."
+
+#: controllers/components/developers.php:287
+msgid "devcp_error_no_platform"
+msgstr "Aucune plateforme sélectionnée"
+
+#: controllers/components/developers.php:59
+msgid "devcp_error_one_category"
+msgstr "Veuillez sélectionner au moins une catégorie."
+
+#: controllers/components/developers.php:92
+msgid "devcp_error_one_user"
+msgstr "Il doit y avoir au moins un auteur mentionné pour ce module."
+
+#. %1$s is a file extension. Example: .exe
+#. %2$s is a comma separated list of extensions. Example: .xpi, .jar
+#: controllers/components/developers.php:1081
+#, php-format
+msgid "devcp_error_preview_extension"
+msgstr ""
+"L'extension de fichier (%s) n'est pas autotisée pour une prévisualisation. "
+"Veuillez utiliser une des extensions suivantes&nbsp;: %s"
+
+#: controllers/components/developers.php:511
+msgid "devcp_error_updatekey"
+msgstr ""
+"Les modules ne peuvent utiliser un updateKey. Veuillez l'enlever du fichier "
+"install.rdf et recommencer."
+
+#: controllers/components/developers.php:506
+msgid "devcp_error_updateurl"
+msgstr ""
+"Les modules ne peuvent utiliser un updateURL externe. Veuillez l'effacer de "
+"votre fichier install.rdf et réessayer."
+
+#: controllers/developers_controller.php:465
+#: controllers/components/developers.php:271
+msgid "devcp_error_upload_file"
+msgstr "Veuillez envoyer un fichier."
+
+#: views/developers/uploader.thtml:135
+#, fuzzy
+msgid "devcp_input_upload_file"
+msgstr "Upload File"
+
+#: views/pages/js_constants.js.thtml:89
+#, fuzzy
+msgid "devcp_js_a_cancel"
+msgstr "Cancel"
+
+#: views/pages/js_constants.js.thtml:90
+#, fuzzy
+msgid "devcp_js_add_email"
+msgstr "Please enter the account email of the author you wish to add."
+
+#. alt text for a down-arrow image.
+#: views/pages/js_constants.js.thtml:81
+#, fuzzy
+msgid "devcp_js_img_move_down"
+msgstr "Move Down"
+
+#. alt text for an up-arrow image.
+#: views/pages/js_constants.js.thtml:82
+#, fuzzy
+msgid "devcp_js_img_move_up"
+msgstr "Move Up"
+
+#: views/pages/js_constants.js.thtml:91
+#, fuzzy
+msgid "devcp_js_img_remove_compat"
+msgstr "Remove Application Compatibility"
+
+#: views/pages/js_constants.js.thtml:86
+#, fuzzy
+msgid "devcp_js_input_list_author"
+msgstr "List as author in public listings"
+
+#: views/pages/js_constants.js.thtml:92
+#, fuzzy
+msgid "devcp_js_license_select"
+msgstr "Please select a license."
+
+#: views/pages/js_constants.js.thtml:93
+#, fuzzy
+msgid "devcp_js_license_text"
+msgstr "Please enter text for your license."
+
+#. <option> text in a <select> for Author role in an add-on.
+#: views/pages/js_constants.js.thtml:84
+#, fuzzy
+msgid "devcp_js_option_developer"
+msgstr "Developer"
+
+#. <option> text in a <select> for Author role in an add-on.
+#: views/pages/js_constants.js.thtml:83
+#, fuzzy
+msgid "devcp_js_option_owner"
+msgstr "Owner"
+
+#. <option> text in a <select> for Author role in an add-on.
+#: views/pages/js_constants.js.thtml:85
+#, fuzzy
+msgid "devcp_js_option_viewer"
+msgstr "Viewer"
+
+#: views/pages/js_constants.js.thtml:88
+#, fuzzy
+msgid "devcp_js_remove_author"
+msgstr "Remove Author"
+
+#: views/pages/js_constants.js.thtml:87
+#, fuzzy
+msgid "devcp_js_sure_remove"
+msgstr "Are you <strong>sure</strong> you wish to remove this author?"
+
+#: views/pages/js_constants.js.thtml:77
+#, fuzzy
+msgid "devcp_js_upload_alert"
+msgstr "You must select a file to upload."
+
+#. %1$s is an addon id, like 32.
+#. %2$s is a version number, like 3.5.
+#: controllers/components/developers.php:1212
+#, fuzzy
+msgid "devcp_license_existing"
+msgstr "Custom license for add-on %1$s v%2$s"
+
+#: views/elements/developers/localebox.thtml:44
+msgid "devcp_localebox_header_localizedfields"
+msgstr "Champs localisés"
+
+#. %1 is the default locale
+#: views/elements/developers/localebox.thtml:48
+#, php-format
+msgid "devcp_localebox_intro"
+msgstr ""
+"Certains champs de cette page sont traduits pour apparaître dans la langue "
+"de l'utilisateur final. Sélectionnez une langue ci-dessous pour éditer les "
+"détails de votre module dans cette langue. Si une traduction pour une langue "
+"n'est pas disponible, la langue sélectionnée par défaut sera utilisée (%s)."
+
+#: views/elements/developers/sidebar.thtml:68
+#: views/elements/developers/myaddons.thtml:75
+msgid "devcp_myaddons_admincp_link"
+msgstr "Panneau de contrôle administrateur"
+
+#: views/elements/developers/sidebar.thtml:65
+#: views/elements/developers/myaddons.thtml:72
+msgid "devcp_myaddons_editorcp_link"
+msgstr "Panneau de contrôle éditeur"
+
+#: views/elements/developers/myaddons.thtml:52
+msgid "devcp_myaddons_link"
+msgstr "Mes modules"
+
+#: views/elements/developers/sidebar.thtml:70
+#: views/elements/developers/myaddons.thtml:77
+msgid "devcp_myaddons_mainpage_link"
+msgstr "Retour à la section principale"
+
+#: views/elements/developers/sidebar.thtml:63
+#: views/elements/developers/myaddons.thtml:70
+msgid "devcp_myaddons_statistics_link"
+msgstr "Tableau de bord des statistiques"
+
+#: views/elements/developers/sidebar.thtml:62
+#: views/elements/developers/myaddons.thtml:69
+msgid "devcp_myaddons_submitaddon_link"
+msgstr "Soumettre un module"
+
+#: views/elements/developers/sidebar.thtml:48
+#: views/elements/developers/myaddons.thtml:67
+msgid "devcp_myaddons_title"
+msgstr "Outils de développement"
+
+#. %1$s is an add-on ID, perhaps 167.
+#. %2$s is a URL.
+#: controllers/developers_controller.php:256
+#, fuzzy
+msgid "devcp_new_addon_error"
+msgstr ""
+"This add-on ID (%1$s) already exists in the database. If this is your add-"
+"on, you can <a href=\"%2$s\">upload a new version</a>."
+
+#: views/developers/addon_status_nominate.thtml:62
+#, fuzzy
+msgid "devcp_nominate_cancel"
+msgstr "Cancel and return"
+
+#. %1 is the add-on name
+#: views/developers/addon_status_nominate.thtml:61
+#, php-format
+msgid "devcp_nominate_submit_nominate"
+msgstr "Nominer %s"
+
+#: views/developers/addon_edit_properties.thtml:50
+#: views/developers/addon_status.thtml:49
+#: views/developers/versions_edit.thtml:50
+#, fuzzy
+msgid "devcp_notice_changes_error"
+msgstr ""
+"<span>One or more of your changes couldn't be saved.</span><br />Please look "
+"for the errors below. The rest of your changes were successfully saved."
+
+#: views/developers/addon_edit_authors.thtml:47
+#: views/developers/addon_edit_properties.thtml:47
+#: views/developers/addon_status.thtml:46
+#: views/developers/addon_edit_descriptions.thtml:47
+#: views/developers/versions_edit.thtml:47
+#: views/developers/addon_edit_categories.thtml:46
+#, fuzzy
+msgid "devcp_notice_changes_saved"
+msgstr ""
+"<span>Your changes have been saved.</span><br />Please note that some "
+"changes may take several hours to appear in all areas of the website."
+
+#: controllers/previews_controller.php:252
+msgid "devcp_notice_cleardefault"
+msgstr ""
+"Supprimer la prévisualisation par défaut fera qu'une des autres "
+"prévisualisations deviendra automatiquement la prévisualisation par défaut."
+
+#: controllers/previews_controller.php:184
+#: controllers/previews_controller.php:251
+msgid "devcp_notice_makedefault"
+msgstr ""
+"Choisir ceci comme prévisualisation par défaut supprimera le statut par "
+"défaut de la prévisualisation par défaut actuelle."
+
+#: views/developers/addon_edit_authors.thtml:70
+#, fuzzy
+msgid "devcp_notice_unsaved_changes"
+msgstr "You have unsaved changes."
+
+#: controllers/developers_controller.php:87
+#: controllers/developers_controller.php:97
+#: controllers/developers_controller.php:100
+#: controllers/previews_controller.php:67
+#: controllers/previews_controller.php:79
+#: controllers/previews_controller.php:82
+msgid "devcp_pagetitle"
+msgstr "Panneau de contrôle du développeur"
+
+#: controllers/previews_controller.php:103
+#: controllers/previews_controller.php:104
+msgid "devcp_preview_add_pagetitle"
+msgstr "Ajouter une prévisualisation"
+
+#: controllers/previews_controller.php:135
+msgid "devcp_preview_added_successfully"
+msgstr "La prévisualisation a bien été ajoutée."
+
+#: controllers/previews_controller.php:323
+msgid "devcp_preview_deleted_successfully"
+msgstr "La prévisualisation a bien été supprimée."
+
+#: controllers/previews_controller.php:194
+#: controllers/previews_controller.php:195
+msgid "devcp_preview_edit_pagetitle"
+msgstr "Éditer la prévisualisation"
+
+#: controllers/previews_controller.php:237
+msgid "devcp_preview_updated_successfully"
+msgstr "La prévisualisation a bien été mise à jour."
+
+#: views/developers/previews.thtml:120
+#, fuzzy
+msgid "devcp_previews_a_another"
+msgstr "Add Another Preview"
+
+#: views/developers/previews.thtml:96
+#, fuzzy
+msgid "devcp_previews_a_delete"
+msgstr "Delete Preview"
+
+#: views/developers/previews.thtml:95
+#, fuzzy
+msgid "devcp_previews_a_replace"
+msgstr "Replace Preview"
+
+#: views/developers/previews.thtml:126
+#, fuzzy
+msgid "devcp_previews_a_update"
+msgstr "Update Previews"
+
+#: views/developers/previews.thtml:115 views/developers/previews.thtml:124
+#, fuzzy
+msgid "devcp_previews_add_new"
+msgstr "Add New Preview"
+
+#. %s is a list of file extensions, e.g. ".png, .gif"
+#: views/developers/previews.thtml:116
+#, fuzzy
+msgid "devcp_previews_add_select"
+msgstr ""
+"Select an image to upload below. Images larger than the maximum size of 700 "
+"pixels wide by 525 pixels tall will be resized. Allowed file types: %s"
+
+#: views/developers/previews.thtml:121
+#, fuzzy
+msgid "devcp_previews_click_below"
+msgstr "Click Update Previews below to upload."
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/previews.thtml:102
+#, fuzzy
+msgid "devcp_previews_click_update"
+msgstr ""
+"Click the Update Previews button below to save this image. (<a %s>Cancel?</"
+"a>)"
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/previews.thtml:107
+#, fuzzy
+msgid "devcp_previews_error_message"
+msgstr ""
+"This preview will be deleted when Update Previews is clicked below. (<a %"
+"s>Cancel?</a>)"
+
+#: views/previews/add.thtml:45
+msgid "devcp_previews_filetype_info"
+msgstr ""
+"Utilisez le formulaire ci-dessous pour envoyer une capture écran au format "
+"PNG, JPG, ou GIF de votre module. Les images de plus de 700 pixels de large "
+"et 525 pixels de hauteur seront automatiquement redimensionnées."
+
+#: views/previews/add.thtml:43
+msgid "devcp_previews_header_add"
+msgstr "Ajouter une prévisualisation"
+
+#: views/developers/previews.thtml:80
+#, fuzzy
+msgid "devcp_previews_header_caption"
+msgstr "Preview Caption"
+
+#: views/previews/edit.thtml:43
+msgid "devcp_previews_header_edit"
+msgstr "Éditer la prévisualisation"
+
+#: views/developers/previews.thtml:93
+#, fuzzy
+msgid "devcp_previews_label_default"
+msgstr "Default Preview"
+
+#: views/previews/add.thtml:54
+msgid "devcp_previews_label_file"
+msgstr "Prévisualiser le fichier"
+
+#: views/previews/add.thtml:59 views/previews/edit.thtml:50
+msgid "devcp_previews_label_makedefault"
+msgstr "Choisir comme image de prévisualisation par défaut"
+
+#: views/developers/previews.thtml:100
+#, fuzzy
+msgid "devcp_previews_label_new"
+msgstr "New image:"
+
+#: views/developers/previews.thtml:118
+#, fuzzy
+msgid "devcp_previews_label_upload"
+msgstr "Upload Preview: "
+
+#: views/developers/previews.thtml:50
+#, fuzzy
+msgid "devcp_previews_notice_error"
+msgstr "One or more of your new previews could not be saved."
+
+#: views/developers/previews.thtml:47
+#, fuzzy
+msgid "devcp_previews_notice_success"
+msgstr "Your previews have been updated successfully."
+
+#: views/developers/previews.thtml:59
+#, fuzzy
+msgid "devcp_previews_p_screenshots"
+msgstr ""
+"The preview screenshots for your add-on are shown below. You can make "
+"changes to captions or images below. The Default Preview is the preview that "
+"is displayed next to your add-on in search and browse listings."
+
+#: views/previews/edit.thtml:55
+msgid "devcp_previews_submit_delete"
+msgstr "Effacer la prévisualisation"
+
+#: views/previews/edit.thtml:55
+msgid "devcp_previews_submit_delete_confirm"
+msgstr "Êtes-vous sûr de vouloir effacer cette prévisualisation&nbsp;?"
+
+#: views/previews/edit.thtml:54
+msgid "devcp_previews_submit_edit"
+msgstr "Éditer la prévisualisation"
+
+#: views/previews/add.thtml:63
+msgid "devcp_previews_submit_upload"
+msgstr "Envoyer la prévisualisation"
+
+#: views/developers/previews.thtml:78
+#, fuzzy
+msgid "devcp_previews_thumbnail"
+msgstr "Thumbnail"
+
+#. %s is the add-on name.
+#: views/developers/previews.thtml:44
+#, fuzzy
+msgid "devcp_previews_title"
+msgstr "%s Preview Manager"
+
+#: views/developers/uploader.thtml:74
+msgid "devcp_review_agreement_please"
+msgstr ""
+"Merci de lire et d'accepter l'Accord Développeur ci-après avant de "
+"poursuivre."
+
+#: views/elements/developers/rolecheck.thtml:42
+#, fuzzy
+msgid "devcp_rolecheck_no_privs"
+msgstr ""
+"<span>You do not have sufficient privileges to make changes on this page.</"
+"span><br />Contact the Add-on Owner if you need to make changes."
+
+#: controllers/developers_controller.php:1315
+#, fuzzy
+msgid "devcp_several_hours"
+msgstr ""
+"Please note that some changes may take several hours to appear in all areas "
+"of the website."
+
+#: views/elements/developers/sidebar.thtml:52
+#, fuzzy
+msgid "devcp_sidebar_a_dashboard"
+msgstr "Dashboard"
+
+#. %s is a number
+#: views/elements/developers/statsbar.thtml:45
+#: views/developers/dashboard.thtml:79
+#, php-format
+msgid "devcp_statsbar_adu"
+msgstr "<em>%s</em> utilisateurs actifs par jour"
+
+#. %s is a number
+#: views/elements/developers/statsbar.thtml:41
+#: views/developers/dashboard.thtml:75
+#, php-format
+msgid "devcp_statsbar_total_downloads"
+msgstr "<em>%s</em> téléchargements au total"
+
+#. %s is a number
+#: views/elements/developers/statsbar.thtml:43
+#: views/developers/dashboard.thtml:77
+#, php-format
+msgid "devcp_statsbar_weekly_downloads"
+msgstr "<em>%s</em> téléchargements par semaine"
+
+#: views/developers/addon_status_confirm.thtml:59
+#, fuzzy
+msgid "devcp_status_confirm_active"
+msgstr ""
+"Marking this add-on active will cause it to show up in public areas "
+"appropriate for its status, including search and browse listings. It will be "
+"downloadable from the website and could be returned in client update checks, "
+"depending on its status. You will be able to return here and disable it "
+"again at your convenience."
+
+#: views/developers/addon_status_confirm.thtml:59
+#, fuzzy
+msgid "devcp_status_confirm_active_sure"
+msgstr "Are you sure you wish to mark this add-on active?"
+
+#: views/developers/addon_status_confirm.thtml:50
+#, fuzzy
+msgid "devcp_status_confirm_header_sure"
+msgstr "Are you sure?"
+
+#: views/developers/addon_status_confirm.thtml:55
+#, fuzzy
+msgid "devcp_status_confirm_inactive"
+msgstr ""
+"Marking this add-on inactive will prevent it from showing up in any public "
+"areas, including search and browse listings. It will not be downloadable "
+"from the website and will not be returned in client update checks. You will "
+"be able to return here and re-enable it at your convenience."
+
+#: views/developers/addon_status_confirm.thtml:55
+#, fuzzy
+msgid "devcp_status_confirm_inactive_sure"
+msgstr "Are you sure you wish to mark this add-on inactive?'"
+
+#: views/developers/addon_status_confirm.thtml:74
+#, fuzzy
+msgid "devcp_status_confirm_no"
+msgstr "No, cancel"
+
+#: views/developers/addon_status_confirm.thtml:67
+#, fuzzy
+msgid "devcp_status_confirm_public"
+msgstr ""
+"Making this add-on public will make it available for anyone to download and "
+"will begin offering updates to existing users."
+
+#: views/developers/addon_status_confirm.thtml:67
+#, fuzzy
+msgid "devcp_status_confirm_public_sure"
+msgstr "Are you sure you wish to make this add-on public?"
+
+#: views/developers/addon_status_confirm.thtml:63
+#, fuzzy
+msgid "devcp_status_confirm_sandbox"
+msgstr ""
+"Moving this add-on back to the sandbox will require users to login before "
+"downloading and updates will no longer be offered to existing users. Because "
+"your add-on is currently public, you will be able to return here at any time "
+"to make it public again."
+
+#: views/developers/addon_status_confirm.thtml:63
+#, fuzzy
+msgid "devcp_status_confirm_sandbox_sure"
+msgstr "Are you sure you wish to move this add-on to the sandbox?"
+
+#: views/developers/addon_status_confirm.thtml:73
+#, fuzzy
+msgid "devcp_status_confirm_yes"
+msgstr "Yes, I'm Sure"
+
+#: views/developers/addon_status_nominate.thtml:46
+#, fuzzy
+msgid "devcp_status_nominate_error_notice"
+msgstr ""
+"<span>A nomination message is required.</span><br />Please fill in the text "
+"box with the requested information and try again."
+
+#: views/developers/addon_status_nominate.thtml:55
+#, fuzzy
+msgid "devcp_status_nominate_header"
+msgstr "Add-on Nomination"
+
+#: views/developers/dashboard.thtml:85
+msgid "devcp_summary_lastversion"
+msgstr "Dernière version&nbsp;:"
+
+#. %s is the add-on name.
+#: views/developers/addon_edit.thtml:43
+#: views/developers/addon_edit_authors.thtml:44
+#: views/developers/versions_delete.thtml:43
+#: views/developers/addon_edit_properties.thtml:44
+#: views/developers/addon_edit_descriptions.thtml:44
+#: views/developers/versions_edit.thtml:44
+#: views/developers/addon_edit_categories.thtml:43
+#: views/developers/versions.thtml:43
+#, fuzzy
+msgid "devcp_title_edit_addon"
+msgstr "Edit %s"
+
+#. title attribute for a javascript link that pops up a help dialog.
+#: views/elements/translationbox.thtml:68
+#, fuzzy
+msgid "devcp_transbox_a_title_help"
+msgstr "Help (does not leave page)"
+
+#: views/elements/translationbox.thtml:68
+#, fuzzy
+msgid "devcp_transbox_alt_help"
+msgstr "Help"
+
+#. %1$s is <span>17</span>, %2$s is 42.
+#: views/elements/translationbox.thtml:101
+#, fuzzy
+msgid "devcp_transbox_chars_used"
+msgstr "Characters used: %1$s / %2$s"
+
+#: views/elements/translationbox.thtml:132
+#, fuzzy
+msgid "devcp_transbox_delete_sure"
+msgstr "Are you sure you wish to delete this translation?"
+
+#. %s is a locale, like en-US.
+#: views/elements/translationbox.thtml:143
+#, fuzzy
+msgid "devcp_transbox_help_header_tabs"
+msgstr "What are these %s tabs?"
+
+#: views/elements/translationbox.thtml:145
+#, fuzzy
+msgid "devcp_transbox_help_header_what"
+msgstr "What if I don't have any translations?"
+
+#: views/elements/translationbox.thtml:147
+#, fuzzy
+msgid "devcp_transbox_help_hide"
+msgstr "Hide Help"
+
+#: views/elements/translationbox.thtml:146
+#, fuzzy
+msgid "devcp_transbox_help_if"
+msgstr ""
+"If a user browses the site and a translation isn't available in their own "
+"language, it will fall back to your add-on's Default Locale, specified in "
+"the Edit Add-on Properties area. If you don't have any translations, just "
+"enter what you can into your Default Locale, which should be a language you "
+"speak."
+
+#: views/elements/translationbox.thtml:144
+#, fuzzy
+msgid "devcp_transbox_help_transbox"
+msgstr ""
+"This is a <i>Translation Box</i>. It allows you to localize a specific field "
+"into any other languages for which you might have a translation. You can "
+"add, edit, and remove translations using the locale tabs."
+
+#: views/elements/translationbox.thtml:85
+#, fuzzy
+msgid "devcp_transbox_img_add_trans"
+msgstr "Add Translation"
+
+#: views/elements/translationbox.thtml:86
+#, fuzzy
+msgid "devcp_transbox_img_remove_trans"
+msgstr "Remove Translation"
+
+#: views/elements/translationbox.thtml:123
+#, fuzzy
+msgid "devcp_transbox_input_add_all"
+msgstr "Add Locale to All"
+
+#: views/elements/translationbox.thtml:122
+#, fuzzy
+msgid "devcp_transbox_input_add_locale"
+msgstr "Add Locale"
+
+#: views/elements/translationbox.thtml:124
+#: views/elements/translationbox.thtml:135
+#, fuzzy
+msgid "devcp_transbox_input_cancel"
+msgstr "Cancel"
+
+#: views/elements/translationbox.thtml:134
+#, fuzzy
+msgid "devcp_transbox_input_delete"
+msgstr "Delete It"
+
+#: views/elements/translationbox.thtml:113
+#, fuzzy
+msgid "devcp_transbox_select_locale"
+msgstr "Select the locale of the translation to add:"
+
+#. %1$s and %2$s are GUIDs.
+#: controllers/developers_controller.php:343
+#, fuzzy
+msgid "devcp_update_addon_guid_error"
+msgstr ""
+"The add-on GUID used in this file (%1$s) does not match the existing GUID "
+"for this add-on (%2$s)."
+
+#: controllers/developers_controller.php:334
+#, fuzzy
+msgid "devcp_update_addon_priv_error"
+msgstr "You do not have sufficient privileges to update this add-on."
+
+#. %1$s is a version number, %2$s is an add-on ID.
+#: controllers/developers_controller.php:399
+#, fuzzy
+msgid "devcp_update_addon_version_belong_error"
+msgstr "The specified version (%1$s) does not belong to this add-on (%2$s)."
+
+#. %1$s is a version number, maybe 1.1.
+#. %2$s is a URL.
+#: controllers/developers_controller.php:351
+#, fuzzy
+msgid "devcp_update_addon_version_exists_error"
+msgstr ""
+"The version number uploaded (%1$s) already exists for this add-on. If you "
+"are trying to add another file to this version, <a href=\"%2$s\">click here</"
+"a>."
+
+#. %1$s and %2$s are version numbers.
+#: controllers/developers_controller.php:405
+#, fuzzy
+msgid "devcp_update_addon_version_match_error"
+msgstr ""
+"The uploaded version number (%1$s) does not match the existing version "
+"number (%2$s)."
+
+#: views/developers/uploader.thtml:68
+#, fuzzy
+msgid "devcp_uploader_a_start"
+msgstr "Get Started"
+
+#: views/developers/uploader.thtml:137
+#, fuzzy
+msgid "devcp_uploader_ajax_loading"
+msgstr "Uploading file..."
+
+#: views/developers/uploader.thtml:82
+#, fuzzy
+msgid "devcp_uploader_button_agree"
+msgstr "Agree and continue"
+
+#: views/developers/uploader.thtml:157
+#, fuzzy
+msgid "devcp_uploader_button_edit"
+msgstr "Edit My Add-on"
+
+#: views/developers/uploader.thtml:158
+#, fuzzy
+msgid "devcp_uploader_button_later"
+msgstr "I'll complete my add-on later."
+
+#: views/developers/uploader.thtml:168
+#, fuzzy
+msgid "devcp_uploader_button_release"
+msgstr "Add Release Notes"
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/uploader.thtml:156
+#, fuzzy
+msgid "devcp_uploader_created_results"
+msgstr ""
+"<p>Your add-on listing has been successfully created. The basic information "
+"obtained from your uploaded file has been stored, but there's a lot more to "
+"your listing that can be customized.</p><p>Your add-on is currently marked "
+"as <strong>Incomplete</strong>. In order to complete your add-on, you'll "
+"need to make sure it has an accurate name, summary, and description, as well "
+"as at least one selected category. You can edit your add-on's information "
+"using the link below and check the status of your add-on at any time on the "
+"<a %s>status page</a>."
+
+#: views/developers/uploader.thtml:143
+#, fuzzy
+msgid "devcp_uploader_error_correct"
+msgstr "Please correct this problem and upload your file again."
+
+#. %1$s is a version number, %2$s is a status, e.g Public or Incomplete.
+#: views/developers/uploader.thtml:175
+#, fuzzy
+msgid "devcp_uploader_file_created"
+msgstr ""
+"Your new file has been added to version %1$s and is currently marked as %2$s."
+
+#: views/developers/uploader.thtml:154
+#, fuzzy
+msgid "devcp_uploader_header_created"
+msgstr "Add-on Created!"
+
+#: views/developers/uploader.thtml:141
+#, fuzzy
+msgid "devcp_uploader_header_error"
+msgstr "Oops! There seems to be a problem with this file..."
+
+#: views/developers/uploader.thtml:173
+#, fuzzy
+msgid "devcp_uploader_header_file_added"
+msgstr "File Added!"
+
+#: views/developers/uploader.thtml:66
+#, fuzzy
+msgid "devcp_uploader_header_how"
+msgstr "How does it all work?"
+
+#. %s is the version number, e.g. 3.2.
+#: views/developers/uploader.thtml:163
+#, fuzzy
+msgid "devcp_uploader_header_update_created"
+msgstr "Version %s Created"
+
+#: views/developers/uploader.thtml:117
+#, fuzzy
+msgid "devcp_uploader_header_upload"
+msgstr "Upload Your File"
+
+#: views/developers/uploader.thtml:67
+#, fuzzy
+msgid "devcp_uploader_how"
+msgstr ""
+"<p>Thanks for your interest in submitting your add-on to Mozilla Add-ons. "
+"Hosting your add-on on Mozilla Add-ons is the easiest way to handle "
+"distribution of your add-on. Here's what you'll get:</p><ul><li>Each add-on "
+"will have a public display page with information you provide, such as a "
+"brief summary of the add-on's functionality, an optional longer description, "
+"and a showcase of preview screenshots of your add-on.</li><li>Your add-on "
+"will appear in search and browse listings across the site, and even in the "
+"Add-ons Manager of Firefox 3.</li><li>We'll take care of hosting all of your "
+"downloads and providing automatic updates to users when you upload a new "
+"version.</li><li>You'll have access to a statistics dashboard with detailed "
+"information about your user base.</li></ul><p>Add-ons hosted on the site "
+"must be reviewed by a Mozilla Add-ons Editor before they will have all of "
+"the features listed above. If you're ready to start the process and have "
+"your add-on package ready for upload, just click on Get Started below!</p>"
+
+#: views/developers/uploader.thtml:125
+#, fuzzy
+msgid "devcp_uploader_label_platformtype"
+msgstr "Supported Platforms:"
+
+#: views/developers/uploader.thtml:124
+#, fuzzy
+msgid "devcp_uploader_label_upload_field"
+msgstr "Add-on File: "
+
+#: controllers/components/developers.php:1221
+#, fuzzy
+msgid "devcp_uploader_option_other"
+msgstr "Other"
+
+#. %1$s is a number, %2$s is href="..." and should stay in the <a> tag.
+#: views/developers/uploader.thtml:176
+#, fuzzy
+msgid "devcp_uploader_p_pending_file"
+msgstr ""
+"The new file will be available to the public as soon as an editor is able to "
+"review it. There are currently %1$s other add-ons in the queue. Want to be "
+"reviewed faster? Consider <a %2$s>becoming an editor</a>."
+
+#. %1$s is a number, %2$s is href="..." and should stay in the <a> tag.
+#: views/developers/uploader.thtml:166
+#, fuzzy
+msgid "devcp_uploader_p_pending_version"
+msgstr ""
+"The new version will be available to the public as soon as an editor is able "
+"to review it. There are currently %1$s other add-ons in the queue. Want to "
+"be reviewed faster? Consider <a %2$s>becoming an editor</a>."
+
+#. %s is a status, e.g Public or Incomplete.
+#: views/developers/uploader.thtml:165
+#, fuzzy
+msgid "devcp_uploader_p_update_created"
+msgstr "Your new version has been created and is currently marked as %s."
+
+#. %1$s is href="..." and should stay in the 'Versions and Files' <a> tag.
+#. %2$s is href="..." and should stay in the 'current status' <a> tag.
+#: views/developers/uploader.thtml:177
+#, fuzzy
+msgid "devcp_uploader_p_update_file"
+msgstr ""
+"View your new file in the <a %1$s>Versions and Files page</a>, check out "
+"your add-on's <a %2$s>current status</a>, or <b>add release notes</b> by "
+"clicking the button below (highly recommended)."
+
+#. %1$s is href="..." and should stay in the 'Versions and Files' <a> tag.
+#. %2$s is href="..." and should stay in the 'current status' <a> tag.
+#: views/developers/uploader.thtml:167
+#, fuzzy
+msgid "devcp_uploader_p_update_version"
+msgstr ""
+"View your new version in the <a %1$s>Versions and Files page</a>, check out "
+"your add-on's <a %2$s>current status</a>, or <b>add release notes</b> by "
+"clicking the button below (highly recommended)."
+
+#: views/developers/uploader.thtml:118
+#, fuzzy
+msgid "devcp_uploader_p_upload"
+msgstr ""
+"Upload your add-on file using the form below. If you have multiple, platform-"
+"specific files to upload, choose a single file and then upload the others "
+"using the Versions and Files Manager."
+
+#: views/developers/uploader.thtml:125
+#, fuzzy
+msgid "devcp_uploader_platformtype_all"
+msgstr "All"
+
+#: views/developers/uploader.thtml:126
+#, fuzzy
+msgid "devcp_uploader_platformtype_specific"
+msgstr "Specific:"
+
+#. Used as first item in a <select>.
+#: controllers/components/developers.php:1185
+#, fuzzy
+msgid "devcp_uploader_please_choose"
+msgstr "Please Choose..."
+
+#. %1$s is the add-on name, %2$s is the version number.
+#: views/developers/uploader.thtml:57
+#, fuzzy
+msgid "devcp_uploader_title_file"
+msgstr "Add File to %1$s %2$s"
+
+#: views/developers/uploader.thtml:50
+#, fuzzy
+msgid "devcp_uploader_title_submit"
+msgstr "Submit New Add-on"
+
+#. %s is the add-on name.
+#: views/developers/uploader.thtml:54
+#, fuzzy
+msgid "devcp_uploader_title_update"
+msgstr "Update %s"
+
+#. %s is a full <a> tag
+#: controllers/developers_controller.php:503
+#, php-format
+msgid "devcp_valid_app_reference"
+msgstr "Veuillez consulter %s pour référence."
+
+#. This is the text in the <a> tag for devcp_valid_app_reference. This should be
+#. fixed.
+#: controllers/developers_controller.php:503
+msgid "devcp_valid_app_reference_linktext"
+msgstr "cette page"
+
+#: controllers/developers_controller.php:581
+#, fuzzy
+msgid "devcp_verify_author_error"
+msgstr "No account found for that email address."
+
+#: controllers/developers_controller.php:553
+#, fuzzy
+msgid "devcp_verify_search_engine_error"
+msgstr ""
+"Either the XML is invalid or required fields are missing. Please <a href="
+"\"https://developer.mozilla.org/en/Creating_OpenSearch_plugins_for_Firefox"
+"\">read the documentation</a>, verify your add-on, and try again."
+
+#: views/developers/versions.thtml:75
+#, fuzzy
+msgid "devcp_versions_a_cancel"
+msgstr "Cancel"
+
+#: views/developers/versions.thtml:79
+#, fuzzy
+msgid "devcp_versions_a_delete"
+msgstr "Delete Version"
+
+#: views/developers/versions.thtml:74
+#, fuzzy
+msgid "devcp_versions_a_empty"
+msgstr "Remove Empty Version"
+
+#: views/developers/versions.thtml:71
+#, fuzzy
+msgid "devcp_versions_a_remove"
+msgstr "Remove?"
+
+#: views/developers/versions.thtml:91
+#, fuzzy
+msgid "devcp_versions_add"
+msgstr "Add New Version"
+
+#: views/developers/versions_delete.thtml:58
+#, fuzzy
+msgid "devcp_versions_delete_a_cancel"
+msgstr "Cancel"
+
+#: views/developers/versions_delete.thtml:56
+#, fuzzy
+msgid "devcp_versions_delete_a_delete"
+msgstr "Delete Version"
+
+#. Followed by a list of reviews and files that will be removed.
+#: views/developers/versions_delete.thtml:50
+#, fuzzy
+msgid "devcp_versions_delete_also"
+msgstr "This will also delete:"
+
+#: views/developers/versions_delete.thtml:53
+#, fuzzy
+msgid "devcp_versions_delete_files"
+msgid_plural "devcp_versions_delete_files"
+msgstr[0] "%s file"
+msgstr[1] "%s files"
+
+#. %s is the version number.
+#: views/developers/versions_delete.thtml:48
+#, fuzzy
+msgid "devcp_versions_delete_header"
+msgstr "Delete Version %s?"
+
+#: views/developers/versions_delete.thtml:52
+#, fuzzy
+msgid "devcp_versions_delete_reviews"
+msgid_plural "devcp_versions_delete_reviews"
+msgstr[0] "%s review"
+msgstr[1] "%s reviews"
+
+#. %s is the version number.
+#: views/developers/versions_delete.thtml:49
+#, fuzzy
+msgid "devcp_versions_delete_sure"
+msgstr "Are you sure you want to permanently delete version %s?"
+
+#: views/developers/versions_edit.thtml:102
+#: views/developers/versions_edit.thtml:155
+#, fuzzy
+msgid "devcp_versions_edit_a_cancel"
+msgstr "Cancel"
+
+#: views/developers/versions_edit.thtml:101
+#, fuzzy
+msgid "devcp_versions_edit_a_delete"
+msgstr "Delete File"
+
+#: views/developers/versions_edit.thtml:165
+#, fuzzy
+msgid "devcp_versions_edit_a_new_app"
+msgstr "Add New Application"
+
+#: views/developers/versions_edit.thtml:154
+#, fuzzy
+msgid "devcp_versions_edit_a_remove_app"
+msgstr "Remove Application"
+
+#: views/developers/versions_edit.thtml:114
+#, fuzzy
+msgid "devcp_versions_edit_add"
+msgstr "Add New File"
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/versions_edit.thtml:121
+#, fuzzy
+msgid "devcp_versions_edit_adjust"
+msgstr ""
+"Adjusting application information here will allow users to install your add-"
+"on even if the install.rdf in the package indicates that the add-on is "
+"incompatible. <a %s>List of supported applications</a>"
+
+#: views/developers/versions_edit.thtml:153
+#, fuzzy
+msgid "devcp_versions_edit_compat_sure"
+msgstr ""
+"Are you <b>sure</b> you wish to remove compatibility with this application?"
+
+#: views/developers/versions_edit.thtml:100
+#, fuzzy
+msgid "devcp_versions_edit_delete_sure"
+msgstr "Are you <b>sure</b> you wish to permanently delete this file?"
+
+#: views/developers/versions_edit.thtml:203
+#, fuzzy
+msgid "devcp_versions_edit_header_approval"
+msgstr "Approval Information"
+
+#: views/developers/versions_edit.thtml:120
+#, fuzzy
+msgid "devcp_versions_edit_header_compat"
+msgstr "Compatible Applications"
+
+#: views/developers/versions_edit.thtml:74
+#, fuzzy
+msgid "devcp_versions_edit_header_file"
+msgstr "File Information"
+
+#: views/developers/versions_edit.thtml:189
+#, fuzzy
+msgid "devcp_versions_edit_header_license"
+msgstr "License"
+
+#. %s is the version number.
+#: views/developers/versions_edit.thtml:53
+#, fuzzy
+msgid "devcp_versions_edit_header_manage"
+msgstr "Manage Version %s"
+
+#: views/developers/versions_edit.thtml:212
+#, fuzzy
+msgid "devcp_versions_edit_header_notes"
+msgstr "Approval Notes"
+
+#: views/developers/versions_edit.thtml:98
+#, fuzzy
+msgid "devcp_versions_edit_img_delete"
+msgstr "Delete File"
+
+#. %1$s is the file id, e.g. 18723.
+#. %2$s is the platform name, e.g. ALL or Windows.
+#. %3$s is the _('date) created.
+#. %4$s is the status, e.g. "In Sandbox" or "Public".
+#. %5$s is the _('date') status was changed.
+#: views/developers/versions_edit.thtml:208
+#, fuzzy
+msgid "devcp_versions_edit_li_file"
+msgstr "File %1$s (%2$s) created on %3$s and changed to %4$s on %5$s"
+
+#: views/developers/versions_edit.thtml:190
+#, fuzzy
+msgid "devcp_versions_edit_license_description"
+msgstr ""
+"Please select the appropriate license for your add-on. This license "
+"specifies the rights you grant on your source code."
+
+#: views/developers/versions_edit.thtml:111
+#, fuzzy
+msgid "devcp_versions_edit_no_files"
+msgstr "No files found."
+
+#: views/developers/versions_edit.thtml:213
+#, fuzzy
+msgid "devcp_versions_edit_optional"
+msgstr "Optional information for the Editor that reviews this version."
+
+#: views/developers/versions_edit.thtml:151
+#, fuzzy
+msgid "devcp_versions_edit_remove_compat"
+msgstr "Remove Application Compatibility"
+
+#: views/developers/versions_edit.thtml:167
+#, fuzzy
+msgid "devcp_versions_edit_select_app"
+msgstr "Please Select an Application"
+
+#: views/developers/versions_edit.thtml:78
+#, fuzzy
+msgid "devcp_versions_edit_th_file"
+msgstr "File"
+
+#: views/developers/versions_edit.thtml:79
+#, fuzzy
+msgid "devcp_versions_edit_th_platform"
+msgstr "Platform"
+
+#: views/developers/versions_edit.thtml:80
+#, fuzzy
+msgid "devcp_versions_edit_th_size"
+msgstr "Size"
+
+#: views/developers/versions_edit.thtml:81
+#, fuzzy
+msgid "devcp_versions_edit_th_status"
+msgstr "Status"
+
+#: views/developers/versions_edit.thtml:183
+#, fuzzy
+msgid "devcp_versions_edit_transbox_releasenotes_description"
+msgstr ""
+"Information about changes in this release, new features, known bugs, and "
+"other useful information specific to this release/version. This information "
+"will also be available to users updating the add-on in the Firefox 3 Add-ons "
+"Manager interface."
+
+#: views/developers/versions_edit.thtml:182
+#, fuzzy
+msgid "devcp_versions_edit_transbox_releasenotes_name"
+msgstr "Release Notes"
+
+#: views/developers/versions_edit.thtml:164
+#, fuzzy
+msgid "devcp_versions_edit_unsaved_compat"
+msgstr ""
+"<strong>You have unsaved changes.</strong> Compatibility will not be deleted "
+"until you click Update Version below."
+
+#: views/developers/versions_edit.thtml:113
+#, fuzzy
+msgid "devcp_versions_edit_unsaved_files"
+msgstr ""
+"<strong>You have unsaved changes.</strong> Files will not be deleted until "
+"you click Update Version below."
+
+#: views/developers/versions_edit.thtml:218
+#, fuzzy
+msgid "devcp_versions_edit_update"
+msgstr "Update Versions"
+
+#: views/developers/versions.thtml:49
+#, fuzzy
+msgid "devcp_versions_header_manage"
+msgstr "Manage Versions and Files"
+
+#: views/developers/versions.thtml:87
+#, fuzzy
+msgid "devcp_versions_no_versions"
+msgstr "No versions."
+
+#. %s is a version number, base 10.
+#: views/developers/versions.thtml:46
+#, fuzzy
+msgid "devcp_versions_notice_success"
+msgstr "Version %s deleted successfully."
+
+#: views/developers/versions.thtml:73
+#, fuzzy
+msgid "devcp_versions_p_remove"
+msgstr ""
+"This version has no files associated with it and can be removed. Would you "
+"like to remove this version?"
+
+#: views/developers/versions.thtml:58
+#, fuzzy
+msgid "devcp_versions_th_created"
+msgstr "Created"
+
+#: views/developers/versions.thtml:57
+#, fuzzy
+msgid "devcp_versions_th_status"
+msgstr "Status"
+
+#: views/developers/versions.thtml:56
+#, fuzzy
+msgid "devcp_versions_th_version"
+msgstr "Version"
+
+#: controllers/downloads_controller.php:91
+msgid "downloads_disable_warning"
+msgstr "Ce module est désactivé."
+
+#: controllers/components/editors.php:57
+msgid "editor_review_error_addon_not_nominated"
+msgstr "Ce module n'a pas été nominé."
+
+#: controllers/components/editors.php:213
+msgid "editor_review_error_file_not_pending"
+msgstr "Ce fichier n'est oas en attente de critique."
+
+#. Actions are, for example: approving or rejecting
+#: controllers/components/editors.php:79
+#: controllers/components/editors.php:182
+msgid "editor_review_error_no_action"
+msgstr "Veuillez sélectioner une action de révision."
+
+#: controllers/components/editors.php:192
+msgid "editor_review_error_no_applications"
+msgstr "Veuillez indiquer les applications que vous avez testées."
+
+#. Comments are required when an editor approves or rejects an add-on.
+#: controllers/components/editors.php:84
+#: controllers/components/editors.php:187
+msgid "editor_review_error_no_comments"
+msgstr "Veuillez associer un commentaire à vos critiques."
+
+#: controllers/components/editors.php:161
+msgid "editor_review_error_no_files"
+msgstr "Ceuillez sélectionner au moins un fichier à critiquer."
+
+#: controllers/components/editors.php:197
+msgid "editor_review_error_no_operating_system"
+msgstr "Veuillez indiquer les systèmes d'exploitations que vous avez testés."
+
+#: views/editors/logs.thtml:51
+msgid "editorcp_logs_button_filter"
+msgstr "Filtrer"
+
+#: views/editors/logs.thtml:44
+msgid "editorcp_logs_filter_by"
+msgstr "Filtrer par type/action"
+
+#: views/editors/logs.thtml:42 controllers/editors_controller.php:964
+msgid "editorcp_logs_page_heading"
+msgstr "Journal des évènements"
+
+#: views/elements/developers/editorsmenu.thtml:60
+msgid "editorcp_menu_eventlog_link"
+msgstr "Journal des évènements"
+
+#: views/elements/developers/editorsmenu.thtml:62
+msgid "editorcp_menu_mainpage_link"
+msgstr "Retour à la section principale"
+
+#: views/elements/developers/editorsmenu.thtml:61
+msgid "editorcp_menu_reviewlog_link"
+msgstr "Journal des révisions"
+
+#: views/elements/developers/editorsmenu.thtml:55
+msgid "editorcp_menu_summary_link"
+msgstr "Résumé de l'éditeur"
+
+#: views/elements/developers/editorsmenu.thtml:52
+msgid "editorcp_menu_title"
+msgstr "Outils de l'éditeur"
+
+#: views/editors/reviewlog.thtml:49
+msgid "editorcp_reviewlog_button_filter"
+msgstr "Filtrer"
+
+#: views/editors/reviewlog.thtml:58
+msgid "editorcp_reviewlog_column_action"
+msgstr "Action"
+
+#: views/editors/reviewlog.thtml:56
+msgid "editorcp_reviewlog_column_addon"
+msgstr "Module"
+
+#: views/editors/reviewlog.thtml:55
+msgid "editorcp_reviewlog_column_date"
+msgstr "Date"
+
+#: views/editors/reviewlog.thtml:57
+msgid "editorcp_reviewlog_column_editor"
+msgstr "Éditeur"
+
+#: views/editors/reviewlog.thtml:94
+msgid "editorcp_reviewlog_comments_hide"
+msgstr "Cacher les commentaires"
+
+#: views/editors/reviewlog.thtml:93
+msgid "editorcp_reviewlog_comments_show"
+msgstr "Afficher les commentaires"
+
+#. %1$s and %2$s are full <input> tags for dates
+#: views/editors/reviewlog.thtml:45
+#, php-format
+msgid "editorcp_reviewlog_entries_between"
+msgstr "Afficher les items entre %s et %s"
+
+#: views/editors/reviewlog.thtml:104
+msgid "editorcp_reviewlog_none_found"
+msgstr "Aucune révision trouvée sur cette période."
+
+#: views/editors/reviewlog.thtml:42
+msgid "editorcp_reviewlog_page_heading"
+msgstr "journal des révisions"
+
+#: views/editors/summary.thtml:61
+msgid "editorcp_summary_monthreviews_heading"
+msgstr "Révisions mensuelles"
+
+#: views/editors/summary.thtml:77
+msgid "editorcp_summary_neweditors_heading"
+msgstr "Nouveaux éditeurs"
+
+#: views/editors/summary.thtml:42
+msgid "editorcp_summary_page_heading"
+msgstr "Résumé de l'éditeur"
+
+#: views/editors/summary.thtml:94
+msgid "editorcp_summary_recentactivity_heading"
+msgstr "Activité récente de l'éditeur"
+
+#: views/editors/summary.thtml:45
+msgid "editorcp_summary_totalreviews_heading"
+msgstr "Ensemble des révisions"
+
+#: controllers/editors_controller.php:248
+#: controllers/editors_controller.php:249
+msgid "editors_addon_review_pagetitle"
+msgstr "Révision du module"
+
+#: controllers/editors_controller.php:349
+msgid "editors_error_js-formerror"
+msgstr "Veuillez remplir les champs suivants&nbsp;:"
+
+#: controllers/editors_controller.php:350
+msgid "editors_error_review_one_file"
+msgstr "Veuillez sélectionner au moins un fichier à réviser."
+
+#: controllers/editors_controller.php:274
+msgid "editors_error_self_reviews_forbidden"
+msgstr "Il n'est pas permis de réviser ses propres modules."
+
+#: controllers/editors_controller.php:699
+msgid "editors_external_software"
+msgstr "Logiciel externe"
+
+#: views/editors/featured.thtml:120 views/editors/featured.thtml:121
+msgid "editors_featured_add_feature"
+msgstr "Ajouter aux essentiels"
+
+#: views/editors/featured.thtml:126
+msgid "editors_featured_add_feature_submit"
+msgstr "Ajouter"
+
+#: views/editors/featured.thtml:49 controllers/editors_controller.php:832
+#: controllers/editors_controller.php:848
+msgid "editors_featured_addon_add_failure"
+msgstr "Échec de l'ajout aux modules essentiels."
+
+#: controllers/editors_controller.php:851
+msgid "editors_featured_addon_add_success"
+msgstr "Ajout aux modules essentiels réussi."
+
+#: views/editors/featured.thtml:50 controllers/editors_controller.php:839
+#: controllers/editors_controller.php:868
+#: controllers/editors_controller.php:886
+msgid "editors_featured_addon_edit_failure"
+msgstr "Impossible de marquer comme module essentiel."
+
+#: views/editors/featured.thtml:51 controllers/editors_controller.php:888
+msgid "editors_featured_addon_edit_success"
+msgstr "Le module a bien été marqué comme essentiel."
+
+#: views/editors/featured.thtml:53 controllers/editors_controller.php:861
+msgid "editors_featured_addon_invalid_locale"
+msgstr "Une ou plusieurs locales sont invalides."
+
+#: views/editors/featured.thtml:52 controllers/editors_controller.php:906
+msgid "editors_featured_addon_remove_failure"
+msgstr "Impossible d'enlever des modules essentiels."
+
+#: controllers/editors_controller.php:901
+msgid "editors_featured_addon_remove_success"
+msgstr "Le module a bien été enlevé de la liste des essentiels."
+
+#: controllers/editors_controller.php:915
+#: controllers/editors_controller.php:917
+msgid "editors_featured_addons_pagetitle"
+msgstr "Modules essentiels"
+
+#: views/editors/featured.thtml:54 views/editors/featured.thtml:107
+msgid "editors_featured_edit_feature_submit"
+msgstr "valider"
+
+#: views/editors/featured.thtml:90 views/editors/featured.thtml:91
+msgid "editors_featured_remove_feature"
+msgstr "Enlever des essentiels"
+
+#: views/editors/queue.thtml:46
+msgid "editors_filter_queue"
+msgstr "Filtrer la queue"
+
+#: views/editors/queue.thtml:182
+msgid "editors_helpful_links"
+msgstr "Liens utiles"
+
+#: views/editors/queue.thtml:182
+msgid "editors_link_guide"
+msgstr "Guide de l'éditeur"
+
+#: views/editors/queue.thtml:182
+msgid "editors_link_policy"
+msgstr "Politique du module"
+
+#: views/editors/queue.thtml:47
+msgid "editors_notice_filter_session"
+msgstr ""
+"Ces filtres resteront actifs jusqu'à la fin de cette session ou bien jusqu'à "
+"ce qu'ils soient désactivés."
+
+#. %1 is the queue mode
+#: views/editors/queue.thtml:177 views/admin/flagged_queue.thtml:89
+msgid "editors_notice_none_found"
+msgstr "Il n'y a actuellement pas de module %s à réviser."
+
+#: controllers/editors_controller.php:1040
+msgid "editors_one_day"
+msgstr "1 jour"
+
+#: controllers/editors_controller.php:1048
+msgid "editors_one_hour"
+msgstr "1 heure"
+
+#: controllers/editors_controller.php:1056
+msgid "editors_one_minute"
+msgstr "1 minute"
+
+#: controllers/editors_controller.php:64 controllers/editors_controller.php:73
+#: controllers/editors_controller.php:77
+msgid "editors_pagetitle"
+msgstr "Panneau de contrôle de l'éditeur"
+
+#. %s is a comma separated list of platforms. Example: Windows, OS X
+#: controllers/editors_controller.php:680
+#: controllers/editors_controller.php:683
+#, php-format
+msgid "editors_platform_x_only"
+msgstr "%s uniquement"
+
+#: controllers/editors_controller.php:695
+msgid "editors_pre-release"
+msgstr "Pré-version"
+
+#. %1 is the app name
+#: views/editors/queue.thtml:131
+#, php-format
+msgid "editors_queue_app_compatibility"
+msgstr "Compatibilité %s"
+
+#: views/editors/queue.thtml:51
+#, fuzzy
+msgid "editors_queue_filter_label_addon"
+msgstr "Add-on or Author Email"
+
+#: views/editors/queue.thtml:72
+#, fuzzy
+msgid "editors_queue_filter_label_addontypes"
+msgstr "Add-on Types"
+
+#: views/editors/queue.thtml:56
+#, fuzzy
+msgid "editors_queue_filter_label_application"
+msgstr "Application"
+
+#: views/editors/queue.thtml:61
+#, fuzzy
+msgid "editors_queue_filter_label_maxversion"
+msgstr "Max. Version"
+
+#: views/editors/queue.thtml:78
+#, fuzzy
+msgid "editors_queue_filter_label_platforms"
+msgstr "Platforms"
+
+#: views/editors/queue.thtml:66
+#, fuzzy
+msgid "editors_queue_filter_label_submissionage"
+msgstr "Age of Submission (days)"
+
+#. %1$s is a number
+#: views/editors/queue.thtml:90
+#, fuzzy
+msgid "editors_queue_filter_result_count"
+msgid_plural "editors_queue_filter_result_count"
+msgstr[0] "Results of your filtered search: <strong>%1$s</strong> Add-on"
+msgstr[1] "Results of your filtered search: <strong>%1$s</strong> Add-ons"
+
+#: views/editors/queue.thtml:84
+msgid "editors_queue_submit_clean"
+msgstr "Nettoyer"
+
+#: views/editors/queue.thtml:83
+msgid "editors_queue_submit_filter"
+msgstr "Filtrer"
+
+#: controllers/editors_controller.php:133
+msgid "editors_queues_disabled"
+msgstr ""
+"Toutes les queues de révision sont actuellement désactivées. Veuillez "
+"revenir plus tard."
+
+#: views/editors/review.thtml:149
+#, fuzzy
+msgid "editors_review_a_edit_item"
+msgstr "Edit Item"
+
+#: views/editors/review.thtml:146
+#, fuzzy
+msgid "editors_review_a_item_history"
+msgstr "Item History"
+
+#: views/editors/review.thtml:148
+#, fuzzy
+msgid "editors_review_a_item_homepage"
+msgstr "Item Homepage"
+
+#: views/editors/review.thtml:145
+#, fuzzy
+msgid "editors_review_a_item_overview"
+msgstr "Item Overview"
+
+#: views/editors/review.thtml:147
+#, fuzzy
+msgid "editors_review_a_previews"
+msgstr "Previews"
+
+#: controllers/editors_controller.php:345
+msgid "editors_review_action"
+msgstr "Action de révision"
+
+#: views/editors/review.thtml:159
+#, fuzzy
+msgid "editors_review_action_info"
+msgstr "Request More Information"
+
+#: views/editors/review.thtml:157
+msgid "editors_review_action_public"
+msgstr "Envoi sur le site public"
+
+#: views/editors/review.thtml:160
+msgid "editors_review_action_request_superreview"
+msgstr "Demande de super-révision"
+
+#: views/editors/review.thtml:158
+msgid "editors_review_action_sandbox"
+msgstr "Garder dans le bac à sable"
+
+#: controllers/editors_controller.php:346
+msgid "editors_review_comments"
+msgstr "Commentaire de révision"
+
+#: views/editors/review.thtml:182
+#, fuzzy
+msgid "editors_review_details_info_request"
+msgstr ""
+"Use this form to request more information from the author. They will receive "
+"an email and be able to answer here. You will be notified by email when they "
+"reply."
+
+#: views/editors/review.thtml:174
+msgid "editors_review_details_nominated_public"
+msgstr ""
+"Ceci marquera le module dans sa dernière version ainsi que ses fichiers "
+"comme publics. Les versions futures resteront dans la bac à sable jusqu'à ce "
+"qu'elles soient revues par un éditeur."
+
+#: views/editors/review.thtml:177
+msgid "editors_review_details_nominated_sandbox"
+msgstr "Ceci gardera le module dans le bac à sable."
+
+#: views/editors/review.thtml:166
+msgid "editors_review_details_pending_public"
+msgstr ""
+"Ceci fera passer une version d'un module public actuellement dans le bac à "
+"sable vers la partie publique."
+
+#: views/editors/review.thtml:169
+msgid "editors_review_details_pending_sandbox"
+msgstr ""
+"Ceci gardera en quarantaine dans le bac à sable une version d'un module "
+"public déjà dans le bac à sable."
+
+#: views/editors/review.thtml:185
+msgid "editors_review_details_superreview"
+msgstr ""
+"Si vous avez des inquiétudes concernant la sécurité de ce module, son "
+"respect du copyright ou d'autres points qu'un administrateur devrait "
+"examiner, saisissez vos commentaires dans la zone de texte ci-dessous. Ces "
+"commentaires seront envoyés aux administrateurs, pas à l'auteur."
+
+#: views/editors/review.thtml:134
+msgid "editors_review_file_diff_link"
+msgstr "Comparer avec la version publique"
+
+#: views/editors/review.thtml:131
+msgid "editors_review_file_viewcontents_link"
+msgstr "Voir le contenu"
+
+#: views/editors/review.thtml:65
+msgid "editors_review_header_authors"
+msgstr "Auteurs&nbsp;:"
+
+#: views/editors/review.thtml:79
+msgid "editors_review_header_categories"
+msgstr "Catégories&nbsp;:"
+
+#: views/editors/review.thtml:92
+msgid "editors_review_header_compatibility"
+msgstr "Compatibilité&nbsp;:"
+
+#: views/editors/review.thtml:251
+msgid "editors_review_header_description"
+msgstr "Description"
+
+#: views/editors/review.thtml:275
+msgid "editors_review_header_devcomments"
+msgstr "Commentaires du développeur"
+
+#: views/editors/review.thtml:263
+msgid "editors_review_header_eula"
+msgstr "CLUF"
+
+#: views/editors/review.thtml:115
+msgid "editors_review_header_files"
+msgstr "Fichiers&nbsp;:"
+
+#: views/editors/review.thtml:284
+msgid "editors_review_header_itemhistory"
+msgstr "Item de l'historique"
+
+#: views/editors/review.thtml:232
+msgid "editors_review_header_nominationmessage"
+msgstr "Message de nomination"
+
+#: views/editors/review.thtml:311
+msgid "editors_review_header_previews"
+msgstr "Prévisualisation"
+
+#: views/editors/review.thtml:269
+msgid "editors_review_header_privacy"
+msgstr "Politique de confidentialité"
+
+#. %1 is the add-on name and version
+#: views/editors/review.thtml:56
+#, php-format
+msgid "editors_review_header_review"
+msgstr "révision de&nbsp: %s"
+
+#: views/editors/review.thtml:239
+msgid "editors_review_header_reviewernotes"
+msgstr "Notes au réviseur"
+
+#: views/editors/review.thtml:245
+msgid "editors_review_header_summary"
+msgstr "Résumé"
+
+#: views/editors/review.thtml:257
+msgid "editors_review_header_versionnotes"
+msgstr "Notes de version"
+
+#. a noun: shown in an add-on's editor review history
+#: views/elements/developers/editors_review_history_item.thtml:80
+#, fuzzy
+msgid "editors_review_history_info_reply"
+msgstr "Reply"
+
+#: views/elements/developers/editors_review_history_item.thtml:78
+#, fuzzy
+msgid "editors_review_history_info_request"
+msgstr "Information Request"
+
+#: views/elements/developers/editors_review_history_item.thtml:62
+#: views/editors/reviewlog.thtml:77
+msgid "editors_review_history_nominated_adminreview"
+msgstr "révision administrateur"
+
+#: views/elements/developers/editors_review_history_item.thtml:56
+#: views/editors/reviewlog.thtml:71
+msgid "editors_review_history_nominated_approved"
+msgstr "Nomination Approuvé/Public"
+
+#: views/elements/developers/editors_review_history_item.thtml:59
+#: views/editors/reviewlog.thtml:74
+msgid "editors_review_history_nominated_denied"
+msgstr "Nomination Refusé/Bac à sable"
+
+#: views/editors/review.thtml:303
+msgid "editors_review_history_nonefound"
+msgstr "Aucune révision antérieure trouvée."
+
+#: views/elements/developers/editors_review_history_item.thtml:73
+#: views/editors/reviewlog.thtml:88
+msgid "editors_review_history_pending_adminreview"
+msgstr "révision administrateur"
+
+#: views/elements/developers/editors_review_history_item.thtml:67
+#: views/editors/reviewlog.thtml:82
+msgid "editors_review_history_pending_approved"
+msgstr "Approuvé/Public"
+
+#: views/elements/developers/editors_review_history_item.thtml:70
+#: views/editors/reviewlog.thtml:85
+msgid "editors_review_history_pending_denied"
+msgstr "Refusé/Bac à sable"
+
+#. link text in an add-on's editor review history, allowing to hide and show an information request's replies
+#. %1 is the number of replies
+#: views/elements/developers/editors_review_history_item.thtml:90
+#, fuzzy
+msgid "editors_review_history_show_hide_replies"
+msgid_plural "editors_review_history_show_hide_replies"
+msgstr[0] "Afficher/Cacher les réponses Show/Hide Replies (%1$s)"
+msgstr[1] "Show/Hide Replies (%1$s)"
+
+#: views/editors/review.thtml:208
+msgid "editors_review_label_applications"
+msgstr "Applications&nbsp;:"
+
+#: views/editors/review.thtml:196
+msgid "editors_review_label_cannedresponse"
+msgstr "ou bien sélectionnez une réponse type&nbsp;:"
+
+#: views/editors/review.thtml:190
+msgid "editors_review_label_comments"
+msgstr "Commentaires&nbsp;:"
+
+#: views/editors/review.thtml:204
+msgid "editors_review_label_operating_systems"
+msgstr "Systèmes d'exploitation&nbsp;:"
+
+#: views/editors/review.thtml:285 views/editors/review.thtml:312
+msgid "editors_review_link_pagetop"
+msgstr "Haut de page"
+
+#: views/editors/review.thtml:141
+#, fuzzy
+msgid "editors_review_mulitple_notice"
+msgstr ""
+"Notice: Only review more than one file if you have tested EVERY file you "
+"select."
+
+#: views/editors/review.thtml:51
+msgid "editors_review_next_link"
+msgstr "suivant &raquo;"
+
+#: views/editors/review.thtml:322
+msgid "editors_review_previews_notfound"
+msgstr "Aucune prévisualisation trouvée."
+
+#: views/editors/review.thtml:50
+msgid "editors_review_previous_link"
+msgstr "&laquo; précédent"
+
+#: controllers/editors_controller.php:144
+#: controllers/editors_controller.php:146
+msgid "editors_review_queue_pagetitle"
+msgstr "Critiques en attente"
+
+#. %1 is the add-ons rank in the queue, %2 is the total queue length
+#: views/editors/review.thtml:47
+msgid "editors_review_rank_in_queue"
+msgstr "<strong># %1$s</strong> sur %2$s en attente"
+
+#. %1 is the add-ons rank in the queue, %2 is the total queue length. Both numbers
+#: views/editors/review.thtml:45
+#, fuzzy
+msgid "editors_review_rank_in_queue_filtered"
+msgstr "<strong># %1$s</strong> of %2$s in queue (filtered)"
+
+#: views/editors/review.thtml:223
+msgid "editors_review_submit_process_action"
+msgstr "Lancer l'action"
+
+#: views/editors/review.thtml:293
+msgid "editors_review_th_action"
+msgstr "Action"
+
+#: views/editors/review.thtml:294
+msgid "editors_review_th_comments"
+msgstr "Commentaires"
+
+#: views/editors/review.thtml:291
+msgid "editors_review_th_date"
+msgstr "Date"
+
+#: views/editors/review.thtml:292
+msgid "editors_review_th_reviewer"
+msgstr "Réviseur"
+
+#: views/editors/review.thtml:290
+msgid "editors_review_th_version_file"
+msgstr "Version/Fichier"
+
+#: views/editors/review.thtml:217
+msgid "editors_review_update_notify_once"
+msgstr ""
+"M'avertir la prochaine fois que ce module est mis à jour (les mises à jour "
+"ultérieures ne généreront pas l'envoi d'un courriel)."
+
+#: controllers/editors_controller.php:298
+msgid "editors_reviewed_successfully"
+msgstr "Révision traitée avec succès."
+
+#: views/editors/reviews_queue.thtml:106
+msgid "editors_reviews_action_delete_review"
+msgstr "Effacer la critique"
+
+#: views/editors/reviews_queue.thtml:104
+msgid "editors_reviews_action_keep"
+msgstr "Suprimer le marquage, garder la critique"
+
+#: views/editors/reviews_queue.thtml:102
+msgid "editors_reviews_action_skip"
+msgstr "Passer"
+
+#: views/editors/reviews_queue.thtml:100
+msgid "editors_reviews_header_action"
+msgstr "Action"
+
+#: views/editors/reviews_queue.thtml:67
+msgid "editors_reviews_in_reply_to"
+msgstr "En réponse à&nbsp;:"
+
+#: controllers/editors_controller.php:748
+msgid "editors_reviews_processed"
+msgstr "Révisions traitées avec succès&nbsp;!"
+
+#: views/editors/reviews_queue.thtml:117
+msgid "editors_reviews_queue_empty"
+msgstr "Il n'y a pas de révision actuellement en modération."
+
+#: views/editors/reviews_queue.thtml:111
+msgid "editors_reviews_submit_process_reviews"
+msgstr "Traiter les révisions"
+
+#: controllers/editors_controller.php:691
+msgid "editors_site_specific"
+msgstr "Specifique à un site"
+
+#: controllers/editors_controller.php:348
+msgid "editors_tested_app"
+msgstr "Application testée"
+
+#: controllers/editors_controller.php:347
+msgid "editors_tested_os"
+msgstr "Systèmes d'exploitation testés"
+
+#: views/editors/queue.thtml:151
+msgid "editors_th_additional_info"
+msgstr "Informations supplémentaires"
+
+#: views/editors/featured.thtml:63 views/editors/queue.thtml:109
+#: views/admin/flagged_queue.thtml:53
+msgid "editors_th_addon"
+msgstr "Module"
+
+#: views/editors/queue.thtml:125
+msgid "editors_th_addontype"
+msgstr "Type"
+
+#: views/editors/featured.thtml:64
+msgid "editors_th_locales"
+msgstr "Restreindre aux locales&nbsp;?"
+
+#: views/editors/queue.thtml:148
+msgid "editors_th_nomination_age"
+msgstr "Dans la file d'attente depuis"
+
+#: views/editors/queue.thtml:101 views/editors/queue.thtml:117
+#: views/editors/queue.thtml:144
+#, fuzzy
+msgid "editors_th_sort_ascending"
+msgstr "Ascending sort"
+
+#: views/editors/queue.thtml:105 views/editors/queue.thtml:121
+#: views/editors/queue.thtml:140
+#, fuzzy
+msgid "editors_th_sort_descending"
+msgstr "Descending sort"
+
+#. %s is a number
+#: controllers/editors_controller.php:1036
+#, php-format
+msgid "editors_x_days"
+msgstr "%s jours"
+
+#. %s is a number
+#: controllers/editors_controller.php:1044
+#, php-format
+msgid "editors_x_hours"
+msgstr "%s heures"
+
+#. %s is a number
+#: controllers/editors_controller.php:1052
+#, php-format
+msgid "editors_x_minutes"
+msgstr "%s minutes"
+
+#: views/errors/error401.thtml:50 controllers/components/simple_acl.php:81
+#: controllers/components/simple_acl.php:82
+#: controllers/components/simple_acl.php:83 controllers/components/amo.php:607
+#: controllers/components/amo.php:608 controllers/components/amo.php:609
+#: controllers/reviews_controller.php:353
+#: controllers/reviews_controller.php:485
+#: controllers/collections_controller.php:438
+#: controllers/collections_controller.php:496
+#: controllers/collections_controller.php:504
+#: controllers/collections_controller.php:971
+#: controllers/collections_controller.php:1034
+#: controllers/collections_controller.php:1077
+msgid "error_access_denied"
+msgstr "Accès refusé"
+
+#: views/errors/error401.thtml:52
+msgid "error_access_denied_message"
+msgstr "Vous n'êtes pas autorisé à afficher cette page"
+
+#: controllers/collections_controller.php:1039
+#, fuzzy
+msgid "error_addon_exists"
+msgstr "Add-on already exists!"
+
+#: controllers/developers_controller.php:200
+#: controllers/developers_controller.php:593
+#: controllers/developers_controller.php:1016
+#: controllers/developers_controller.php:1429
+#: controllers/downloads_controller.php:95
+#: controllers/downloads_controller.php:102
+#: controllers/downloads_controller.php:164
+#: controllers/statistics_controller.php:135
+#: controllers/previews_controller.php:115
+#: controllers/previews_controller.php:206
+#: controllers/previews_controller.php:307
+#: controllers/reviews_controller.php:77
+#: controllers/reviews_controller.php:240
+#: controllers/reviews_controller.php:332
+#: controllers/reviews_controller.php:340 controllers/api_controller.php:123
+#: controllers/api_controller.php:759 controllers/addons_controller.php:131
+#: controllers/addons_controller.php:197
+#: controllers/addons_controller.php:1407
+#: controllers/addons_controller.php:1465
+#: controllers/addons_controller.php:1469
+#: controllers/addons_controller.php:1503
+#: controllers/editors_controller.php:265
+#: controllers/collections_controller.php:1041
+#: controllers/collections_controller.php:1074
+msgid "error_addon_notfound"
+msgstr "Module non trouvé&nbsp;!"
+
+#: controllers/files_controller.php:83 controllers/files_controller.php:196
+msgid "error_addon_notviewable"
+msgstr "Ce module n'est pas affichable ici."
+
+#: controllers/reviews_controller.php:246
+msgid "error_addon_selfreview"
+msgstr "Vous ne pouvez pas critiquer votre propre module."
+
+#: controllers/addons_controller.php:970
+msgid "error_browse_no_addons"
+msgstr "Pas de module dans cette catégorie&nbsp;!"
+
+#: controllers/api_controller.php:424
+msgid "error_collection_feed_notfound"
+msgstr "Flux Web du module introuvable."
+
+#: views/users/register.thtml:65 views/users/edit.thtml:194
+msgid "error_email_invalid"
+msgstr "Cette adresse est invalide."
+
+#: views/users/pwreset.thtml:74 views/users/register.thtml:70
+#: views/users/register.thtml:80 views/users/register.thtml:86
+#: views/users/edit.thtml:105 views/users/edit.thtml:111
+#: views/users/edit.thtml:192 views/admin/users_edit.thtml:78
+#: views/admin/users_edit.thtml:83 views/reviews/add.thtml:80
+#: views/reviews/add.thtml:104
+msgid "error_field_required"
+msgstr "Ce champ doit être rempli."
+
+#: controllers/files_controller.php:75 controllers/files_controller.php:93
+#: controllers/files_controller.php:96 controllers/files_controller.php:163
+#: controllers/files_controller.php:176 controllers/files_controller.php:185
+#: controllers/files_controller.php:204 controllers/editors_controller.php:412
+msgid "error_file_notfound"
+msgstr "Fichier introuvable&nbsp;!"
+
+#. %s is a filename
+#: controllers/editors_controller.php:430
+#, php-format
+msgid "error_file_x_notfound"
+msgstr "Erreur fichier&nbsp;: %s n'existe pas."
+
+#: views/collections/add.thtml:55 views/collections/edit.thtml:89
+#: views/users/register.thtml:54 views/users/edit.thtml:81
+#: views/reviews/add.thtml:70 controllers/groups_controller.php:80
+#: controllers/groups_controller.php:102
+msgid "error_formerrors"
+msgstr ""
+"Le formulaire contient des erreurs. Merci de les corriger et de soumettre à "
+"nouveau les données du formulaire."
+
+#: views/users/register.thtml:109
+msgid "error_invalid_captcha"
+msgstr "Captcha invalide, veullez recommencer&nbsp;!"
+
+#: views/users/register.thtml:100 views/users/edit.thtml:125
+#: views/admin/users_edit.thtml:101
+msgid "error_invalid_url"
+msgstr ""
+"Cette URL a un format non valide. Une URL valide ressemble à ceci&nbsp;: "
+"http://exemple.com/ma_page."
+
+#. %s is a string representing what's missing. Example: file_id
+#: controllers/downloads_controller.php:65
+#: controllers/users_controller.php:185 controllers/users_controller.php:264
+#: controllers/users_controller.php:559 controllers/users_controller.php:653
+#: controllers/reviews_controller.php:71
+#: controllers/reviews_controller.php:234
+#: controllers/reviews_controller.php:325
+#: controllers/reviews_controller.php:473
+#: controllers/reviews_controller.php:475
+#: controllers/addons_controller.php:182
+#: controllers/addons_controller.php:1381
+#: controllers/addons_controller.php:1455
+#: controllers/collections_controller.php:266
+#: controllers/collections_controller.php:285
+#: controllers/collections_controller.php:346
+#: controllers/collections_controller.php:443
+#: controllers/collections_controller.php:482
+#: controllers/collections_controller.php:936
+#: controllers/collections_controller.php:959
+#: controllers/collections_controller.php:960
+#: controllers/collections_controller.php:975
+#: controllers/collections_controller.php:977
+#: controllers/collections_controller.php:994
+#: controllers/collections_controller.php:1003
+#: controllers/collections_controller.php:1016
+#: controllers/collections_controller.php:1017
+#: controllers/collections_controller.php:1024
+#: controllers/collections_controller.php:1070
+#: controllers/collections_controller.php:1090
+#, php-format
+msgid "error_missing_argument"
+msgstr "Argument manquant&nbsp;: %s"
+
+#: controllers/components/amo.php:507 controllers/components/amo.php:532
+msgid "error_no_files_in_addon"
+msgstr "Aucun fichier"
+
+#: controllers/previews_controller.php:200
+msgid "error_preview_notfound"
+msgstr "Prévisualisation introuvable&nbsp;!"
+
+#: views/addons/display.thtml:400 views/reviews/add.thtml:98
+msgid "error_review_rating_required"
+msgstr "Vous devez fournir une évaluation."
+
+#: controllers/users_controller.php:160
+msgid "error_user_already_confirmed"
+msgstr "Ce compte utilisateur a déjà été confirmé."
+
+#: controllers/users_controller.php:202 controllers/users_controller.php:276
+#: controllers/users_controller.php:569 controllers/users_controller.php:581
+#: controllers/users_controller.php:587 controllers/users_controller.php:610
+#: controllers/users_controller.php:627
+msgid "error_user_badconfirmationcode"
+msgstr "Code de confirmation invalide&nbsp;!"
+
+#: views/users/pwreset.thtml:79 views/users/register.thtml:75
+#: views/users/edit.thtml:183
+msgid "error_user_confirmpw_nomatch"
+msgstr "Les mots de passe ne correspondent pas."
+
+#: views/users/register.thtml:65 views/users/edit.thtml:190
+#: controllers/users_controller.php:617
+msgid "error_user_email_notunique"
+msgstr "Cette adresse est déjà utilisée par un autre compte."
+
+#: controllers/users_controller.php:596
+msgid "error_user_emailchange_expired"
+msgstr ""
+"Votre demande de changement d'adresse de messagerie est arrivée à "
+"expiration. Veuillez changer de nouveau votre adresse dans votre profil "
+"utilisateur et cliquer sur le lien inclus dans le message de confirmation "
+"que nous vous envoyons, ceci dès sa réception."
+
+#: controllers/collections_controller.php:985
+#, fuzzy
+msgid "error_user_exists"
+msgstr ""
+"Users can only have one role at a time. Please remove the user from any "
+"existing roles before continuing."
+
+#: views/users/register.thtml:91 views/users/edit.thtml:116
+#: views/admin/users_edit.thtml:88
+msgid "error_user_nickname_notunique"
+msgstr "Cet identifiant est déjà pris."
+
+#: views/users/pwreset.thtml:54 controllers/users_controller.php:191
+#: controllers/users_controller.php:270 controllers/users_controller.php:603
+#: controllers/users_controller.php:659
+#: controllers/collections_controller.php:988
+#: controllers/collections_controller.php:998
+msgid "error_user_notfound"
+msgstr "Utilisateur inconnu&nbsp;!"
+
+#: views/users/activatefirst.thtml:47
+msgid "error_user_unconfirmed"
+msgstr "Veuillez confirmer votre compte utilisateur."
+
+#: views/users/login.thtml:67
+msgid "error_username_or_pw_wrong"
+msgstr "Identifiant ou mot de passe incorrect&nbsp!"
+
+#: controllers/editors_controller.php:260
+msgid "error_version_notfound"
+msgstr "Version introuvable&nbsp;!"
+
+#: views/users/delete.thtml:125 views/users/edit.thtml:173
+msgid "error_wrong_password"
+msgstr "Mot de passe erroné&nbsp;!"
+
+#: views/elements/amo2009/homepage_addon.thtml:122
+#: views/elements/feature.thtml:122
+msgid "feature_learnmore"
+msgstr "En savoir plus"
+
+#. %1 is the add-on name
+#: views/elements/amo2009/homepage_addon.thtml:123
+#: views/elements/feature.thtml:123
+#, php-format
+msgid "feature_learnmore_about_addon"
+msgstr "En savoir plus sur %1$s"
+
+#. %1$s is a number
+#: views/elements/amo2009/reviews.thtml:52
+#: views/elements/addon_listitem.thtml:112 views/elements/feature.thtml:99
+#: views/addons/browse_thumbs.thtml:86
+#, php-format
+msgid "feature_reviews"
+msgid_plural "feature_reviews"
+msgstr[0] "%1$s critique"
+msgstr[1] "%1$s critiques"
+
+#: views/elements/amo2009/homepage_addon.thtml:127
+#: views/elements/feature.thtml:127
+msgid "feature_view_more_from_category"
+msgstr "Afficher plus&nbsp;:"
+
+#. This appears on a page that views the source of an add-on. This link will return
+#. the user to the add-on's main page
+#: views/files/browse.thtml:65
+msgid "file_browser_link_addon"
+msgstr "Retour au module"
+
+#. There is a list of directories and files on the page. Clicking this will show the
+#. contents of all the directories (normally you would click on each one to see the
+#. contents)
+#: views/files/browse.thtml:67
+msgid "file_browser_link_expand_all"
+msgstr "Tout afficher"
+
+#. This appears on a page that views the source of an add-on. This link will return
+#. the user to the add-on's review page (it only appears if the add-on is being
+#. reviewed)
+#: views/files/browse.thtml:64
+msgid "file_browser_link_review"
+msgstr "Retour à la critique"
+
+#. The title of the page for viewing an add-on's source.
+#. %1$s is the name of the add-on
+#. %2$s is the name of the current application (e.g. Firefox or Thunderbird)
+#: views/files/browse.thtml:46
+msgid "file_browser_title"
+msgstr "%1$s :: Navigateur de fichiers :: Module %2$s"
+
+#. This appears on a page that views the source of an add-on. There is a list of
+#. directories and files on the page. Clicking this link will toggle between an
+#. expanded or a collapsed list. This string should be kept short.
+#: views/files/browse.thtml:68
+msgid "file_browser_toggle_expand_collapse"
+msgstr "+/-"
+
+#. Link text for the AMO About page.
+#: views/elements/footer.thtml:72 views/layouts/amo2009.thtml:341
+msgid "footer_a_about"
+msgstr "À propos"
+
+#. Link text to the AMO blog.
+#: views/elements/footer.thtml:74 views/layouts/amo2009.thtml:343
+msgid "footer_a_blog"
+msgstr "Blog"
+
+#. Link text to the Frequently Asked Questions page.
+#: views/elements/footer.thtml:73 views/layouts/amo2009.thtml:342
+msgid "footer_a_faq"
+msgstr "FAQ"
+
+#. Full text for the FAQ abbreviation.
+#: views/elements/footer.thtml:73 views/pages/collector_features.thtml:72
+#: views/layouts/amo2009.thtml:342
+msgid "footer_abbr_faq"
+msgstr "Foire aux questions"
+
+#: views/elements/footer.thtml:67 views/layouts/amo2009.thtml:336
+msgid "footer_all_rights_reserved"
+msgstr "Tous droits réservés."
+
+#: views/elements/footer.thtml:67 views/layouts/amo2009.thtml:336
+msgid "footer_copyright"
+msgstr "Copyright"
+
+#: views/elements/footer.thtml:71 views/layouts/amo2009.thtml:340
+msgid "footer_credits"
+msgstr "Nos contributeurs"
+
+#: views/elements/footer.thtml:76 views/layouts/amo2009.thtml:346
+msgid "footer_disclaimer"
+msgstr ""
+"Mozilla fournit des liens vers ces applications tierces comme un service "
+"gracieux. Mozilla ne garantit ni le fonctionnement de ces applications ni "
+"les informations les concernant. Toute question, demande ou plainte "
+"concernant ces applications doit être dirigée vers leurs auteurs, seuls "
+"responsables."
+
+#: views/elements/footer.thtml:61 views/layouts/amo2009.thtml:332
+msgid "footer_lang_form_lang_submit_go"
+msgstr "Ok !"
+
+#: views/elements/footer.thtml:70 views/layouts/amo2009.thtml:339
+msgid "footer_legal_notices"
+msgstr "Avertissement légal"
+
+#: views/elements/footer.thtml:50 views/layouts/amo2009.thtml:321
+msgid "footer_other_languages"
+msgstr "Autres langues&nbsp;:"
+
+#: views/elements/footer.thtml:69 views/layouts/amo2009.thtml:338
+msgid "footer_privacy_policy"
+msgstr "Politique de confidentialité"
+
+#: models/addontype.php:79
+msgid "general_addontype_dict"
+msgstr "Dictionnaire"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:100
+msgid "general_addontype_dict_plural"
+msgstr "Dictionnaires"
+
+#: models/addontype.php:75
+msgid "general_addontype_extension"
+msgstr "Extension"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:98
+msgid "general_addontype_extension_plural"
+msgstr "Extensions"
+
+#: models/addontype.php:85
+msgid "general_addontype_lpaddon"
+msgstr "Pack de langue (module)"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:103
+msgid "general_addontype_lpaddon_plural"
+msgstr "Packs de langues (module)"
+
+#: models/addontype.php:83
+msgid "general_addontype_lpapp"
+msgstr "Pack de langue (application)"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:102
+msgid "general_addontype_lpapp_plural"
+msgstr "Packs de langues (application)"
+
+#: models/addontype.php:87
+msgid "general_addontype_plugin"
+msgstr "Plugin"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:104
+msgid "general_addontype_plugin_plural"
+msgstr "Plugins"
+
+#: models/addontype.php:81
+msgid "general_addontype_search"
+msgstr "Moteur de recherche"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:101
+msgid "general_addontype_search_plural"
+msgstr "Moteurs de recherche"
+
+#: models/addontype.php:77
+msgid "general_addontype_theme"
+msgstr "Thème"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:99
+msgid "general_addontype_theme_plural"
+msgstr "Thèmes"
+
+#: config/language.php:367
+#, fuzzy
+msgid "general_languages_all_locales"
+msgstr "All Locales"
+
+#: views/layouts/amo2009.thtml:249
+#, fuzzy
+msgid "header_brand_name"
+msgstr "Mozilla"
+
+#. %1$s is the application name. Example: Firefox
+#: views/elements/header.thtml:111 views/elements/header.thtml:122
+#: views/layouts/amo2009.thtml:248
+#, php-format
+msgid "header_home_tooltip"
+msgstr "Revenir à la page d'accueil des modules %1$s"
+
+#: views/elements/header.thtml:87
+msgid "header_main_firefox_header"
+msgstr "Modules Firefox"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:218
+#, fuzzy
+msgid "header_main_firefox_header_with_logo"
+msgstr ""
+"Add-ons <em>for</em> <img alt=\"Firefox\" src=\"%1$s\" /> <strong>Firefox</"
+"strong>"
+
+#: views/elements/header.thtml:99
+msgid "header_main_header"
+msgstr "Modules"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:242
+#, fuzzy
+msgid "header_main_header_with_logo"
+msgstr "Add-ons <img alt=\"Add-ons\" src=\"%1$s\" />"
+
+#: views/elements/header.thtml:90
+msgid "header_main_seamonkey_header"
+msgstr "Modules Seamonkey"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:224
+#, fuzzy
+msgid "header_main_seamonkey_header_with_logo"
+msgstr ""
+"Add-ons <em>for</em> <img alt=\"seamonkey\" src=\"%1$s\" /> "
+"<strong>SeaMonkey</strong>"
+
+#: views/elements/header.thtml:93
+msgid "header_main_sunbird_header"
+msgstr "Modules Sunbird"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:230
+#, fuzzy
+msgid "header_main_sunbird_header_with_logo"
+msgstr ""
+"Add-ons <em>for</em> <img alt=\"sunbird\" src=\"%1$s\" /> <strong>Sunbird</"
+"strong>"
+
+#: views/elements/header.thtml:96
+msgid "header_main_thunderbird_header"
+msgstr "Modules Thunderbird"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:236
+#, fuzzy
+msgid "header_main_thunderbird_header_with_logo"
+msgstr ""
+"Add-ons <em>for</em> <img alt=\"thunderbird\" src=\"%1$s\" /> "
+"<strong>Thunderbird</strong>"
+
+#: views/layouts/amo2009.thtml:205
+#, fuzzy
+msgid "header_navaccess_applications_menu"
+msgstr "Skip to other applications menu"
+
+#: views/layouts/amo2009.thtml:204
+#, fuzzy
+msgid "header_navaccess_categories_menu"
+msgstr "Skip to categories menu"
+
+#: views/layouts/amo2009.thtml:202
+#, fuzzy
+msgid "header_navaccess_main_content"
+msgstr "Skip to main content"
+
+#: views/layouts/amo2009.thtml:203
+#, fuzzy
+msgid "header_navaccess_search_form"
+msgstr "Skip to search form"
+
+#: views/elements/header.thtml:62
+msgid "header_navlink_addons"
+msgstr "Modules"
+
+#: views/elements/developers/sidebar.thtml:72
+#: views/elements/developers/myaddons.thtml:50 views/elements/header.thtml:159
+#: views/addons/display.thtml:378
+msgid "header_navlink_login"
+msgstr "Connexion"
+
+#: views/elements/header.thtml:156 views/layouts/amo2009.thtml:304
+msgid "header_navlink_logout"
+msgstr "Déconnexion"
+
+#: views/elements/header.thtml:145 views/layouts/amo2009.thtml:303
+msgid "header_navlink_myaccount"
+msgstr "Mon compte"
+
+#: views/elements/header.thtml:158
+msgid "header_navlink_register"
+msgstr "Inscription"
+
+#. %1 is the URL to the registration page
+#. %2 is the URL to the login page
+#: views/layouts/amo2009.thtml:278
+#, fuzzy
+msgid "header_navlink_register_or_login"
+msgstr "<a href=\"%1$s\">Register</a> or <a href=\"%2$s\">Log in</a>"
+
+#: views/layouts/amo2009.thtml:285
+#, fuzzy
+msgid "header_navlink_tools"
+msgstr "Tools"
+
+#. %s is the add-on name
+#: views/elements/collections_interactive_addon.thtml:62
+#: views/elements/amo2009/homepage_addon.thtml:77
+#: views/elements/addon_discussionheader.thtml:62
+#: views/elements/addon_listitem.thtml:67 views/elements/feature.thtml:84
+#: views/addons/category_landing.thtml:87 views/addons/browse_thumbs.thtml:60
+#, php-format
+msgid "img_preview_of"
+msgstr "Prévisualisation de l'image de %s"
+
+#. %1 is the login URL for the link tag
+#. %2 is the link to an explanatory page.
+#: views/elements/amo2009/install.thtml:307 views/elements/install.thtml:255
+msgid "install_a_login_to_install"
+msgstr "<a href=\"%1$s\">Connectez-vous</a> pour installer ce module."
+
+#. %1 is the URL for the Experimental Add-ons section of the FAQ page
+#: views/elements/amo2009/install.thtml:283 views/elements/install.thtml:232
+msgid "install_button_confirm_exp_install"
+msgstr ""
+"Je veux installer ce module expérimental. <a href=\"%1$s\">Qu'est-ce que "
+"c'est&nbsp;?</a>"
+
+#. %1$s is the application name. Example: Firefox
+#. %2$s is an optional string used to specify a platform. Example: (Windows)
+#: views/elements/amo2009/install.thtml:128 views/elements/install.thtml:75
+#, php-format
+msgid "install_button_text"
+msgstr "Ajouter à %s %s"
+
+#. %1 is the add-on name, %2 is the app name
+#: views/elements/amo2009/install.thtml:191
+#: views/elements/amo2009/install.thtml:206
+#: views/elements/amo2009/install.thtml:249
+#: views/elements/amo2009/install.thtml:298 views/elements/install.thtml:150
+#: views/elements/install.thtml:165 views/elements/install.thtml:202
+#: views/elements/install.thtml:246
+#, php-format
+msgid "install_button_title"
+msgstr "Ajouter %1$s à %2$s"
+
+#. %1$s is the add-on name
+#: views/elements/amo2009/install.thtml:200 views/elements/install.thtml:159
+#, php-format
+msgid "install_download"
+msgstr "Télécharger %1$s"
+
+#: views/elements/amo2009/install.thtml:147 views/elements/install.thtml:94
+msgid "install_error_addon_not_found"
+msgstr "Module non trouvé&nbsp;!"
+
+#: views/addons/dictionaries.thtml:65
+msgid "langtools_a11y_tablesummary"
+msgstr "Liste des dictionnaires et paquetages linguistiques."
+
+#: views/addons/dictionaries.thtml:47
+msgid "langtools_download_dictionary"
+msgstr "Télécharger le dictionnaire"
+
+#: views/addons/dictionaries.thtml:48
+msgid "langtools_download_langpack"
+msgstr "Télécharger le paquetage linguistique"
+
+#: views/addons/dictionaries.thtml:63 controllers/components/amo.php:685
+#: controllers/addons_controller.php:1239
+msgid "langtools_header_dicts_and_langpacks"
+msgstr "Dictionnaires et paquetages linguistiques"
+
+#: views/addons/dictionaries.thtml:44
+msgid "langtools_install_dictionary"
+msgstr "Installer le dictionnaire"
+
+#: views/addons/dictionaries.thtml:45
+msgid "langtools_install_langpack"
+msgstr "Installer le paquetage linguistique"
+
+#: views/addons/dictionaries.thtml:69
+msgid "langtools_tableheader_dictionary"
+msgstr "Dictionnaire"
+
+#: views/addons/dictionaries.thtml:70
+msgid "langtools_tableheader_langpack"
+msgstr "Paquetage linguistique"
+
+#: views/addons/dictionaries.thtml:68
+msgid "langtools_tableheader_language"
+msgstr "Langue"
+
+#: models/license.php:65
+msgid "license_custom"
+msgstr "Licence personnalisée"
+
+#: config/bootstrap.php:303
+msgid "licenses_bsd"
+msgstr "Licence BSD"
+
+#: config/bootstrap.php:298
+msgid "licenses_gpl_2.0"
+msgstr "GNU General Public License, version 2.0"
+
+#: config/bootstrap.php:299
+msgid "licenses_gpl_3.0"
+msgstr "GNU General Public License, version 3.0"
+
+#: config/bootstrap.php:300
+msgid "licenses_lgpl_2.1"
+msgstr "GNU Lesser General Public License, version 2.1"
+
+#: config/bootstrap.php:301
+msgid "licenses_lgpl_3.0"
+msgstr "GNU Lesser General Public License, version 3.0"
+
+#: config/bootstrap.php:302
+msgid "licenses_mit"
+msgstr "Licence MIT/X11"
+
+#: config/bootstrap.php:297
+msgid "licenses_mpl_1.1"
+msgstr "Mozilla Public License, version 1.1"
+
+#: views/users/emailchange.thtml:51 views/users/delete.thtml:55
+#: views/users/delete.thtml:137 views/users/edit.thtml:74
+#: views/reviews/flag.thtml:54
+msgid "link_return_to_front_page"
+msgstr "Cliquez ici pour retourner sur la page d'accueil."
+
+#: views/elements/amo2009/addon_list_options.thtml:46
+#: views/elements/addon_list_options.thtml:46
+msgid "list_sortby_date"
+msgstr "Date"
+
+#: views/elements/amo2009/addon_list_options.thtml:47
+#: views/elements/addon_list_options.thtml:47
+msgid "list_sortby_downloads"
+msgstr "Téléchargements"
+
+#: views/elements/amo2009/addon_list_options.thtml:45
+#: views/elements/addon_list_options.thtml:45
+msgid "list_sortby_name"
+msgstr "Nom du module"
+
+#: views/elements/amo2009/addon_list_options.thtml:48
+#: views/elements/addon_list_options.thtml:48
+msgid "list_sortby_rating"
+msgstr "Évaluation"
+
+#: config/bootstrap.php:278
+msgid "main_prettyname_fennec"
+msgstr "Fennec"
+
+#: config/bootstrap.php:274
+msgid "main_prettyname_firefox"
+msgstr "Firefox"
+
+#: config/bootstrap.php:277
+msgid "main_prettyname_seamonkey"
+msgstr "SeaMonkey"
+
+#: config/bootstrap.php:276
+msgid "main_prettyname_sunbird"
+msgstr "Sunbird"
+
+#: config/bootstrap.php:275
+msgid "main_prettyname_thunderbird"
+msgstr "Thunderbird"
+
+#: views/elements/addon_categories.thtml:52
+msgid "nav_category_dicts_langpacks"
+msgstr "Dictionnaires et paquetages linguistiques"
+
+#: views/elements/addon_categories.thtml:55
+msgid "nav_category_themes"
+msgstr "Thèmes"
+
+#: views/elements/app_chooser.thtml:47 views/layouts/amo2009.thtml:255
+msgid "other_apps_tooltip"
+msgstr "Trouver des modules pour d'autres logiciels"
+
+#. In a user list: user 1, user 2, "others"
+#: views/helpers/addons_html.php:222
+msgid "other_users"
+msgstr "Autres"
+
+#: controllers/pages_controller.php:90
+msgid "page_title_appversions"
+msgstr "Versions des logiciels"
+
+#: controllers/pages_controller.php:115
+#, fuzzy
+msgid "page_title_collector"
+msgstr "Add-on Collector"
+
+#: controllers/pages_controller.php:117
+#, fuzzy
+msgid "page_title_collector_faq"
+msgstr "Add-on Collector FAQ"
+
+#: controllers/pages_controller.php:119
+#, fuzzy
+msgid "page_title_collector_features"
+msgstr "Add-on Collector Features"
+
+#: controllers/pages_controller.php:122
+#, fuzzy
+msgid "page_title_collector_firstrun"
+msgstr "Welcome to the Add-on Collector"
+
+#: controllers/pages_controller.php:92
+msgid "page_title_credits"
+msgstr "Remerciements"
+
+#: controllers/pages_controller.php:113
+msgid "page_title_developer_faq"
+msgstr "FAQ du développeur"
+
+#: controllers/pages_controller.php:111
+msgid "page_title_faq"
+msgstr "Foire Aux Questions"
+
+#: controllers/pages_controller.php:94
+msgid "page_title_fashionyourfirefox_faq"
+msgstr "FAQ de 'Fashion your Firefox'"
+
+#: controllers/pages_controller.php:101
+msgid "page_title_policy"
+msgstr "Polique de confidentialité du module"
+
+#: controllers/pages_controller.php:103
+msgid "page_title_privacy"
+msgstr "Politique de confidentialité de Mozilla"
+
+#: controllers/pages_controller.php:105
+msgid "page_title_review_guide"
+msgstr "Instructions pour les critiques"
+
+#: controllers/pages_controller.php:107
+msgid "page_title_sandbox"
+msgstr "Système de révision du bac à sable"
+
+#: controllers/pages_controller.php:109
+msgid "page_title_submissionhelp"
+msgstr "Aide à l'envoi"
+
+#: views/pages/appversions.thtml:87
+msgid "pages_appversions_guid"
+msgstr "GUID"
+
+#: views/pages/appversions.thtml:79 controllers/pages_controller.php:90
+msgid "pages_appversions_header"
+msgstr "Versions valides de l'application"
+
+#: views/pages/appversions.thtml:80
+msgid "pages_appversions_intro"
+msgstr ""
+"Les modules soumis au site Mozilla Add-ons doivent être pourvus d'un fichier "
+"install.rdf comportant au moins l'une des applications supportées ci-"
+"dessous. Seules les versions listées ci-dessous sont autorisées pour ces "
+"applications."
+
+#. %s is a full <a> tag
+#: views/pages/appversions.thtml:93
+#, php-format
+msgid "pages_appversions_required_files"
+msgstr ""
+"Si l'application que vous supportez ne nécessite pas de fichier install.rdf, "
+"vous devez tout de même inclure ce fichier avec les propriétés requises "
+"comme spécifié %s."
+
+#. this is the text inside of an <a> tag for pages_appversions_required_files. This
+#. should be fixed.
+#: views/pages/appversions.thtml:93
+msgid "pages_appversions_required_files_link"
+msgstr "ici"
+
+#: views/pages/appversions.thtml:88
+msgid "pages_appversions_versions"
+msgstr "Versions"
+
+#: views/pages/policy.thtml:51
+msgid "pages_policy_sandbox_link"
+msgstr "Page d'information du bac à sable"
+
+#: views/elements/pagination.thtml:53
+msgid "pagination_next_page"
+msgstr "suivant"
+
+#: views/elements/pagination.thtml:52
+msgid "pagination_previous_page"
+msgstr "précédent"
+
+#: views/elements/recaptcha.thtml:65
+msgid "recaptcha_enter_both_words"
+msgstr ""
+"Veuillez taper les <strong>deux mots</strong> ci-dessous, <strong>séparés "
+"par un espace</strong>."
+
+#: views/elements/recaptcha.thtml:83
+msgid "recaptcha_enter_here"
+msgstr "Tapez votre réponse ici&nbsp;:"
+
+#: views/elements/recaptcha.thtml:74
+msgid "recaptcha_enter_whatyouhear"
+msgstr "Veuillez taper ce que vous entendez."
+
+#. %1 is the link switching refreshing the captcha
+#. %2 is the link switching to a text captcha
+#: views/elements/recaptcha.thtml:77
+msgid "recaptcha_hardtohear_text"
+msgstr ""
+"Si c'est difficilement compréhensible, vous pouvez <a href=\"%1$s\">écouter "
+"autre chose </a> ou bien <a href=\"%2$s\">utiliser le test textuel</a>."
+
+#. %1 is the link switching refreshing the captcha
+#. %2 is the link switching to an audio captcha
+#: views/elements/recaptcha.thtml:68
+msgid "recaptcha_hardtoread_text"
+msgstr ""
+"Si c'est illisible, vous pouvez <a href=\"%1$s\">essayer d'autres mots</a> "
+"ou bien <a href=\"%2$s\">utiliser le test auditif</a> à la place."
+
+#: views/users/register.thtml:105
+msgid "recaptcha_label"
+msgstr "Êtes-vous un être humain&nbsp;?"
+
+#: views/users/register.thtml:106
+msgid "recaptcha_whatsthis"
+msgstr "Qu'est-ce que ceci&nsbp;?"
+
+#: controllers/reviews_controller.php:559
+msgid "review_flag_error"
+msgstr "Erreur lors du marquage de cette critique&nbsp;!"
+
+#: models/reviews_moderation_flag.php:69
+msgid "review_flag_reason_bug_support"
+msgstr "Rapport de bug ou demande d'assistance inadéquate dans ce contexte"
+
+#: views/reviews/display.thtml:103 views/reviews/display.thtml:186
+msgid "review_flag_reason_instructions"
+msgstr "Dénoncer cette critique (selectionnez un motif)"
+
+#: models/reviews_moderation_flag.php:67
+msgid "review_flag_reason_language"
+msgstr "Langage inapproprié"
+
+#: models/reviews_moderation_flag.php:71
+msgid "review_flag_reason_other"
+msgstr "Autre (veuillez préciser)"
+
+#: models/reviews_moderation_flag.php:65
+msgid "review_flag_reason_spam"
+msgstr "Spam ou contenu qui n'est pas une critique du module"
+
+#: views/reviews/display.thtml:91 views/reviews/display.thtml:175
+#: controllers/reviews_controller.php:555
+msgid "review_flag_success"
+msgstr ""
+"Merci. Cette critique est maintenant en attente d'approbation par un "
+"modérateur."
+
+#: views/reviews/display.thtml:41
+msgid "review_flag_this"
+msgstr "Dénoncer cette critique"
+
+#: views/reviews/display.thtml:42
+msgid "review_flag_this_titletip"
+msgstr ""
+"Cette critique est-elle inappropriée, inexacte ou du spam&nbsp;? Cliquez ici "
+"pour demander sa modération."
+
+#. %1 is the URL of the support section, %2 for the review guidelines
+#: views/reviews/add.thtml:53
+msgid "review_guidelines_short"
+msgstr ""
+"<p>Veuillez garder ces conseils à l'esprit&nbsp;:</p><ul><li>Écrivez votre "
+"critique comme si vous parliez à un ami de votre expérience avec ce module. "
+"Donnez des détails précis et utiles, tels que les caractéristiques que vous "
+"avez apprécié ou pas, la facilité d'emploi et les éventuels inconvénients. "
+"Évitez les banalités et les jugements du type <em>super</em> ou <em>nul</em> "
+"à moins que vous ne justifiiez votre opinion par des faits.</li><li>Veuillez "
+"ne pas poster de rapports de bugs dans vos critiques. Nous ne donnons pas "
+"accès à votre adresse électronique aux développeurs de modules hors ceux-ci "
+"pourraient avoir besoin de vous contacter pour résoudre votre problème. "
+"Consultez la <a href=\"%1$s\">section d'assitance</a> pour toute question "
+"relative à ce module.</li><li>Veuillez poster des critiques correctes, "
+"évitez tout langage inapproprié et ne postez pas d'informations "
+"personnelles. </li></ul><p>Veuillez lire les <a href=\"%2$s\">instructions "
+"pour la critique</a> pour obtenir d'avantage de détails sur les critiques de "
+"modules.</p>"
+
+#. %1 is the add-on name
+#: views/reviews/flag.thtml:56 views/reviews/display.thtml:55
+#: views/reviews/review_added.thtml:50
+#, php-format
+msgid "reviews_header"
+msgstr "Critique de %s"
+
+#: controllers/addons_controller.php:435
+msgid "rss_featuredaddons"
+msgstr "Modules essentiels"
+
+#: controllers/addons_controller.php:432
+msgid "rss_newestaddons"
+msgstr "Modules récemment ajoutés"
+
+#: controllers/addons_controller.php:434
+#, fuzzy
+msgid "rss_popularaddons"
+msgstr "Popular Add-ons"
+
+#: controllers/addons_controller.php:433
+msgid "rss_updatedaddons"
+msgstr "Modules mis à jour"
+
+#: views/elements/search_mini.thtml:70
+msgid "search"
+msgstr "Recherche"
+
+#: views/search/collections.thtml:51
+#, fuzzy
+msgid "search_collections_header"
+msgstr "Collection Search Results"
+
+#: controllers/search_controller.php:297
+#, fuzzy
+msgid "search_collections_pagetitle"
+msgstr "Collection Search Results"
+
+#: controllers/search_controller.php:99
+msgid "search_disabled"
+msgstr "La recherche est actuellement désactivée. Veullez réessayer plus tard."
+
+#: views/elements/amo2009/search.thtml:188 views/elements/search.thtml:187
+#: views/elements/search_mini.thtml:54
+msgid "search_form_all_addons"
+msgstr "tous les modules"
+
+#. This string is in the main category dropdown when searching
+#: views/elements/amo2009/search.thtml:204
+#, fuzzy
+msgid "search_form_all_collections"
+msgstr "all collections"
+
+#: views/elements/amo2009/search.thtml:184
+#: views/elements/amo2009/search.thtml:385
+#: views/elements/amo2009/search.thtml:408 views/elements/search.thtml:171
+#: views/elements/search.thtml:183 views/elements/search_mini.thtml:43
+#: views/elements/search_mini.thtml:49 views/layouts/mozilla.thtml:188
+msgid "search_form_default_text"
+msgstr "recherche de modules"
+
+#: views/elements/amo2009/search.thtml:184
+#: views/elements/amo2009/search.thtml:404
+#, fuzzy
+msgid "search_form_default_text_collections"
+msgstr "search for collections"
+
+#: views/elements/amo2009/search.thtml:206 views/elements/search.thtml:202
+msgid "search_form_submit_tooltip"
+msgstr "Recherche de modules"
+
+#: views/elements/amo2009/search.thtml:184 views/elements/search.thtml:183
+#: views/elements/search_mini.thtml:49
+msgid "search_form_tooltip"
+msgstr "Cliquez vous saisir des termes de recherche"
+
+#: views/elements/amo2009/search.thtml:186 views/elements/search.thtml:185
+#: views/elements/search_mini.thtml:52
+msgid "search_form_within"
+msgstr "dans"
+
+#: views/addons/searchengines.thtml:118
+msgid "search_landing_all_search_engines"
+msgstr "Tous les moteurs de recherche"
+
+#: views/addons/searchengines.thtml:114
+msgid "search_landing_browse_search_engines"
+msgstr "Naviguer dans les moteurs de recherche"
+
+#: views/search/collections.thtml:58 views/search/index.thtml:59
+msgid "search_nothing_found"
+msgstr "Aucun résultat."
+
+#: controllers/search_controller.php:185
+msgid "search_pagetitle"
+msgstr "Recherche de modules"
+
+#: controllers/search_controller.php:242
+msgid "search_rss_description"
+msgstr "Fil des résultats de la recherche"
+
+#. %s is the terms the user is searching for (a string)
+#: controllers/search_controller.php:241
+#, php-format
+msgid "search_rss_results_for"
+msgstr "Résultat de la recherche pour&nbsp;: %s"
+
+#: views/elements/header.thtml:154 views/layouts/amo2009.thtml:296
+msgid "sidebar_navlink_admin_tools"
+msgstr "Outils d'administration"
+
+#: views/elements/header.thtml:146 views/layouts/amo2009.thtml:288
+msgid "sidebar_navlink_developer_tools"
+msgstr "Outils de développement"
+
+#: views/elements/header.thtml:148 views/layouts/amo2009.thtml:290
+msgid "sidebar_navlink_editor_tools"
+msgstr "Outils d'édition"
+
+#: views/layouts/amo2009.thtml:302
+msgid "sidebar_navlink_welcome"
+msgstr "Bienvenue"
+
+#. %s is the user's name
+#: views/layouts/amo2009.thtml:302
+#, php-format
+msgid "sidebar_navlink_welcome_name"
+msgstr "Bienvenue, %s"
+
+#: views/elements/pitch.thtml:50 views/elements/pitch.thtml:55
+msgid "sidebar_pitch_dictionary"
+msgstr "Dictionnaire"
+
+#: views/elements/pitch.thtml:72
+msgid "sidebar_pitch_featured_addons"
+msgstr "Modules essentiels"
+
+#: views/elements/pitch.thtml:61
+msgid "sidebar_pitch_looking_for"
+msgstr "Je recherche&nbsp;:"
+
+#: views/elements/pitch.thtml:70
+msgid "sidebar_pitch_newest_addons"
+msgstr "Modules récents"
+
+#: views/elements/pitch.thtml:49
+msgid "sidebar_pitch_search"
+msgstr "Plugin de recherche"
+
+#: views/elements/pitch.thtml:69
+msgid "sidebar_pitch_subscribe_to"
+msgstr "S'abonner à&nbsp;:"
+
+#: views/elements/pitch.thtml:48 views/elements/pitch.thtml:54
+msgid "sidebar_pitch_theme"
+msgstr "Thème"
+
+#: views/elements/pitch.thtml:71
+msgid "sidebar_pitch_updated_addons"
+msgstr "Modules mis à jour"
+
+#. %1$s is a number
+#: views/helpers/localization.php:65 views/developers/versions_edit.thtml:95
+#: views/addons/dictionaries.thtml:92
+#, php-format
+msgid "size_kb"
+msgstr "%1$s Ko"
+
+#: views/elements/amo2009/stars.thtml:57 views/elements/stars.thtml:63
+msgid "stars_not_yet_rated"
+msgstr "Pas encore évalué"
+
+#. %1 is the number of stars this add-on has
+#: views/elements/amo2009/stars.thtml:49 views/elements/stars.thtml:54
+#, php-format
+msgid "stars_rated_x_outof_5"
+msgstr "Évaluation de %s sur 5 étoiles"
+
+#: views/statistics/addon.thtml:59
+msgid "statistics_addon_dashboard_link"
+msgstr "Tableau de bord - Accueil"
+
+#: views/statistics/addon.thtml:58
+msgid "statistics_addon_developertools_link"
+msgstr "Outils de développement"
+
+#: views/statistics/addon.thtml:53
+msgid "statistics_addon_switch"
+msgstr "Changer de module"
+
+#. This is a date format.
+#. http://php.net/strftime
+#: views/statistics/rss/summary.thtml:54 views/statistics/addon.thtml:181
+msgid "statistics_date_shortmonth"
+msgstr "j M"
+
+#. This is a date format.
+#. http://php.net/strftime
+#: views/statistics/rss/summary.thtml:40 views/statistics/addon.thtml:152
+msgid "statistics_date_shortmonthwithyear"
+msgstr "%e %b. %Y"
+
+#. This is a date format.
+#. http://php.net/strftime
+#: views/statistics/rss/summary.thtml:41 views/statistics/rss/summary.thtml:48
+#: views/statistics/addon.thtml:161 views/statistics/addon.thtml:172
+msgid "statistics_date_weekdayshortmonth"
+msgstr "%A %e %b."
+
+#. %1$s is an add-on name and version. Example: Add-on 3.5
+#: controllers/components/stats.php:519
+#, php-format
+msgid "statistics_events_addon_created"
+msgstr "%1$s créé"
+
+#. %1$s is an application name and version. Example: Firefox 3.5
+#: controllers/components/stats.php:500
+#, php-format
+msgid "statistics_events_app_released"
+msgstr "%1$s publié"
+
+#: views/statistics/addon.thtml:71
+msgid "statistics_help_close_link"
+msgstr "Fermer"
+
+#: views/statistics/addon.thtml:60
+msgid "statistics_help_link"
+msgstr "Aide"
+
+#: views/statistics/index.thtml:83
+msgid "statistics_index_anotheraddon"
+msgstr "ou bien choisissez un autre module complémentaire"
+
+#: views/statistics/index.thtml:85
+msgid "statistics_index_anotheraddon_public"
+msgstr "ou bien choisissez un module disposant de statistiques publiques"
+
+#: views/statistics/index.thtml:71
+msgid "statistics_index_myaddons"
+msgstr "Sélectionnez l'un de vos modules pour afficher ses statistiques"
+
+#: views/statistics/index.thtml:89
+msgid "statistics_index_selectaddon"
+msgstr "Sélectionnez un module pour afficher ses statistiques"
+
+#: views/statistics/index.thtml:91
+msgid "statistics_index_selectaddon_public"
+msgstr "Sélectionnez un module disposant de statistiques publiques"
+
+#: views/statistics/index.thtml:39
+msgid "statistics_index_title"
+msgstr "Tableau de bord des statistiques"
+
+#: views/statistics/index.thtml:97
+msgid "statistics_index_view_button"
+msgstr "Voir les Statistiques"
+
+#: views/statistics/addon.thtml:222 controllers/statistics_controller.php:247
+msgid "statistics_js_download_csv"
+msgstr "Afficher ce tableau au format CSV"
+
+#: controllers/statistics_controller.php:246
+msgid "statistics_js_dropdowns_none"
+msgstr "aucun"
+
+#: controllers/statistics_controller.php:245
+msgid "statistics_js_dropdowns_removeplot"
+msgstr "Retirer cette courbe"
+
+#: controllers/statistics_controller.php:248
+msgid "statistics_js_groupby_selector_date"
+msgstr "Grouper par&nbsp;: jour"
+
+#: controllers/statistics_controller.php:251
+msgid "statistics_js_groupby_selector_month"
+msgstr "Grouper par&nbsp;: mois"
+
+#: controllers/statistics_controller.php:249
+msgid "statistics_js_groupby_selector_week"
+msgstr "Grouper par&nbsp;: semaine"
+
+#: controllers/statistics_controller.php:250
+msgid "statistics_js_groupby_selector_week_over_week"
+msgstr "Comparer par: semaine"
+
+#: controllers/statistics_controller.php:260
+msgid "statistics_js_plotselection_foundinrange"
+msgstr "%s trouvés sur cette tranche"
+
+#: controllers/statistics_controller.php:270
+msgid "statistics_js_plotselection_options_addplot_name"
+msgstr "Ajouter une courbe"
+
+#: controllers/statistics_controller.php:271
+msgid "statistics_js_plotselection_options_addplot_tooltip"
+msgstr "Ajouter une autre courbe sur ce graphique"
+
+#: controllers/statistics_controller.php:261
+msgid "statistics_js_plotselection_options_count_name_checked"
+msgstr "Cacher le compte total"
+
+#: controllers/statistics_controller.php:262
+msgid "statistics_js_plotselection_options_count_name_unchecked"
+msgstr "Afficher le compte total"
+
+#: controllers/statistics_controller.php:263
+msgid "statistics_js_plotselection_options_count_tooltip"
+msgstr "Tracer le décompte total sur ce graphique"
+
+#: controllers/statistics_controller.php:275
+msgid "statistics_js_plotselection_options_csv_name"
+msgstr "Afficher les données (CSV)"
+
+#: controllers/statistics_controller.php:276
+msgid "statistics_js_plotselection_options_csv_tooltip"
+msgstr ""
+"Obtenir ces données sous forme de fichier aux valeurs séparées par des "
+"virgules (CSV)."
+
+#: controllers/statistics_controller.php:267
+msgid "statistics_js_plotselection_options_events_addon_name_checked"
+msgstr "Cacher %s évènements"
+
+#: controllers/statistics_controller.php:268
+msgid "statistics_js_plotselection_options_events_addon_name_unchecked"
+msgstr "Afficher %s évènements"
+
+#: controllers/statistics_controller.php:269
+msgid "statistics_js_plotselection_options_events_addon_tooltip"
+msgstr "Superposer les dates de sortie des modules sur les courbes"
+
+#: controllers/statistics_controller.php:264
+msgid "statistics_js_plotselection_options_events_firefox_name_checked"
+msgstr "Cacher les évènements Firefox"
+
+#: controllers/statistics_controller.php:265
+msgid "statistics_js_plotselection_options_events_firefox_name_unchecked"
+msgstr "Afficher les évènements Firefox"
+
+#: controllers/statistics_controller.php:266
+msgid "statistics_js_plotselection_options_events_firefox_tooltip"
+msgstr "Superposer les dates de sortie de Firefox sur les courbes"
+
+#: controllers/statistics_controller.php:272
+msgid "statistics_js_plotselection_options_resize_name_checked"
+msgstr "Réduire le graphique"
+
+#: controllers/statistics_controller.php:273
+msgid "statistics_js_plotselection_options_resize_name_unchecked"
+msgstr "Dévelopepr le graphique"
+
+#: controllers/statistics_controller.php:274
+msgid "statistics_js_plotselection_options_resize_tooltip"
+msgstr "Redimensionner le graphique"
+
+#: controllers/statistics_controller.php:254
+msgid "statistics_js_plotselection_selector_adu"
+msgstr "Utilisateurs actifs par jour"
+
+#: controllers/statistics_controller.php:256
+msgid "statistics_js_plotselection_selector_application"
+msgstr "Application"
+
+#: controllers/statistics_controller.php:259
+msgid "statistics_js_plotselection_selector_custom"
+msgstr "Personnalisé"
+
+#: controllers/statistics_controller.php:253
+msgid "statistics_js_plotselection_selector_downloads"
+msgstr "Téléchargements"
+
+#: controllers/statistics_controller.php:258
+msgid "statistics_js_plotselection_selector_os"
+msgstr "Système d'exploitation"
+
+#: controllers/statistics_controller.php:257
+msgid "statistics_js_plotselection_selector_status"
+msgstr "Statut du module"
+
+#: controllers/statistics_controller.php:252
+msgid "statistics_js_plotselection_selector_summary"
+msgstr "Résumé"
+
+#: controllers/statistics_controller.php:255
+msgid "statistics_js_plotselection_selector_version"
+msgstr "Version du module"
+
+#: controllers/components/stats.php:398
+msgid "statistics_longnames_application"
+msgstr "Application"
+
+#: controllers/components/stats.php:400
+msgid "statistics_longnames_os"
+msgstr "Système d'exploitation"
+
+#: controllers/components/stats.php:399
+msgid "statistics_longnames_status"
+msgstr "Statut du module"
+
+#: controllers/components/stats.php:401
+msgid "statistics_longnames_unknown"
+msgstr "Inconnu"
+
+#: controllers/components/stats.php:397
+msgid "statistics_longnames_version"
+msgstr "Version du module"
+
+#: views/statistics/addon.thtml:118
+msgid "statistics_notice_data_insufficient"
+msgstr ""
+"Il n'y a pas assez de données pour afficher le graphique. Revenez un peu "
+"plus tard."
+
+#: views/statistics/addon.thtml:130
+msgid "statistics_notice_data_none"
+msgstr ""
+"Nous ne disposons pas encore d'assez de données pour votre module. Revenez "
+"d'ici quelques jours."
+
+#: views/statistics/addon.thtml:41
+msgid "statistics_notice_data_updating"
+msgstr ""
+"les statistiques sur les modules sont en cours d'actualisation. Les données "
+"récentes peuvent donc être incomplètes pendant cette opération. Revenez "
+"d'ici quelques minutes."
+
+#: views/statistics/addon.thtml:136
+msgid "statistics_notice_disabled"
+msgstr ""
+"Le tableau de bord des statistiques est actuellement désactivé. Revenez un "
+"peu plus tard."
+
+#: views/statistics/addon.thtml:123
+msgid "statistics_notice_nojavascript"
+msgstr ""
+"JavaScript est nécessaire pour afficher les graphiques du tableau de bord "
+"des statistiques."
+
+#: views/statistics/addon.thtml:44
+msgid "statistics_notice_settings_updated"
+msgstr "Vos réglages ont été mis à jour&nbsp;!"
+
+#: controllers/statistics_controller.php:60
+#: controllers/statistics_controller.php:71
+#: controllers/statistics_controller.php:74
+#: controllers/statistics_controller.php:240
+msgid "statistics_pagetitle"
+msgstr "Tableau de bord des statistiques"
+
+#: views/statistics/addon.thtml:99
+msgid "statistics_plot_legend_adu"
+msgstr "Utilisateurs actifs par jour"
+
+#: views/statistics/addon.thtml:95
+msgid "statistics_plot_legend_downloads"
+msgstr "Téléchargements par jour"
+
+#: views/statistics/addon.thtml:107
+msgid "statistics_plot_options_zoomin_alt"
+msgstr "Zoomer"
+
+#: views/statistics/addon.thtml:106
+msgid "statistics_plot_options_zoomin_title"
+msgstr "Zoomer un mois"
+
+#: views/statistics/addon.thtml:110
+msgid "statistics_plot_options_zoomout_alt"
+msgstr "Dézoomer"
+
+#: views/statistics/addon.thtml:109
+msgid "statistics_plot_options_zoomout_title"
+msgstr "Dézoomer un mois"
+
+#: controllers/statistics_controller.php:283
+#, php-format
+msgid "statistics_rss_description"
+msgstr "Résumé quotidien des statistiques pour %1$s"
+
+#: views/statistics/rss/summary.thtml:68
+msgid "statistics_rss_title_fulldate"
+msgstr "%A %e %B %Y"
+
+#: views/statistics/rss/summary.thtml:68
+#, php-format
+msgid "statistics_rss_title_statsfordate"
+msgstr "Statistiques pour %1$s"
+
+#: views/statistics/settings.thtml:49
+msgid "statistics_settings_access_description"
+msgstr ""
+"Par défaut, seul vous et Mozilla avez accès aux informations de votre "
+"tableau de bord. Vous pouvez rendre celui-ci public afin que tout le monde "
+"puisse voir les données concernant votre module."
+
+#: views/statistics/settings.thtml:48
+msgid "statistics_settings_access_heading"
+msgstr "Accès au tableau de bord"
+
+#: views/statistics/settings.thtml:51
+msgid "statistics_settings_access_private"
+msgstr "Privé"
+
+#: views/statistics/settings.thtml:51
+msgid "statistics_settings_access_private_description"
+msgstr "Seul vous et Mozilla avez accès aux statistiques de ce module"
+
+#: views/statistics/settings.thtml:52
+msgid "statistics_settings_access_public"
+msgstr "Public"
+
+#: views/statistics/settings.thtml:52
+msgid "statistics_settings_access_public_description"
+msgstr "Quiconque peut voir les statistiques de ce module"
+
+#: views/statistics/addon.thtml:251
+msgid "statistics_settings_change_link"
+msgstr "Changer les réglages"
+
+#: views/statistics/addon.thtml:253
+msgid "statistics_settings_confidential"
+msgstr "Veuillez considérer ces informations comme confidentielles."
+
+#: views/statistics/addon.thtml:245
+msgid "statistics_settings_currently_private"
+msgstr "Ce tableau de bord est actuellement <b>privé</b>."
+
+#: views/statistics/addon.thtml:241
+msgid "statistics_settings_currently_public"
+msgstr "Ce tableau de bord est actuellement <b>public</b>."
+
+#: views/statistics/addon.thtml:246
+msgid "statistics_settings_locked_alt"
+msgstr "Verrouillé"
+
+#: views/statistics/settings.thtml:57
+msgid "statistics_settings_return_link"
+msgstr "Retour au tableau de bord"
+
+#: views/statistics/settings.thtml:56
+msgid "statistics_settings_save_button"
+msgstr "Enregistrer les réglages"
+
+#: views/statistics/settings.thtml:46
+#, php-format
+msgid "statistics_settings_title"
+msgstr "Réglages du tableau de bord des statistiques pour %1$s"
+
+#: views/statistics/addon.thtml:242
+msgid "statistics_settings_unlocked_alt"
+msgstr "déverrouillé"
+
+#: controllers/components/stats.php:405
+msgid "statistics_shortnames_application"
+msgstr "Appli"
+
+#: controllers/components/stats.php:407
+msgid "statistics_shortnames_os"
+msgstr "SE"
+
+#: controllers/components/stats.php:406
+msgid "statistics_shortnames_status"
+msgstr "St"
+
+#: controllers/components/stats.php:408
+msgid "statistics_shortnames_unknown"
+msgstr "??"
+
+#: controllers/components/stats.php:404
+msgid "statistics_shortnames_version"
+msgstr "Ver"
+
+#: views/statistics/rss/summary.thtml:42 views/statistics/addon.thtml:192
+msgid "statistics_summary_downloads_average"
+msgstr "Moyenne des téléchargements quotidiens"
+
+#: views/statistics/rss/summary.thtml:39
+msgid "statistics_summary_downloads_heading"
+msgstr "Téléchargements"
+
+#: views/statistics/rss/summary.thtml:41 views/statistics/addon.thtml:171
+msgid "statistics_summary_downloads_lastcount"
+msgstr "Dernier jour compté"
+
+#: views/statistics/rss/summary.thtml:43 views/statistics/addon.thtml:199
+msgid "statistics_summary_downloads_lastweek"
+msgstr "Téléchargements ces 7 derniers jours"
+
+#: views/statistics/rss/summary.thtml:40 views/statistics/addon.thtml:151
+msgid "statistics_summary_downloads_total"
+msgstr "Téléchargements totaux"
+
+#: views/statistics/rss/summary.thtml:40 views/statistics/addon.thtml:152
+#, php-format
+msgid "statistics_summary_downloads_total_sincedate"
+msgstr "Depuis %1$s"
+
+#: views/statistics/rss/summary.thtml:50 views/statistics/rss/summary.thtml:56
+#: views/statistics/addon.thtml:163 views/statistics/addon.thtml:183
+msgid "statistics_summary_nodata"
+msgstr "Pas encore de données"
+
+#: views/statistics/rss/summary.thtml:60 views/statistics/addon.thtml:195
+msgid "statistics_summary_updatepings_average"
+msgstr "Moyenne des utilisateurs actifs par jour"
+
+#: views/statistics/rss/summary.thtml:52 views/statistics/addon.thtml:177
+msgid "statistics_summary_updatepings_changefromprevious"
+msgstr "Changement depuis le comptage précédent"
+
+#: views/statistics/rss/summary.thtml:54 views/statistics/addon.thtml:181
+#, php-format
+msgid "statistics_summary_updatepings_changefromprevious_ondate"
+msgstr "%1$s sur %2$s"
+
+#: views/statistics/rss/summary.thtml:45
+msgid "statistics_summary_updatepings_heading"
+msgstr "Utilisateurs actifs par jour"
+
+#: views/statistics/rss/summary.thtml:46 views/statistics/addon.thtml:157
+msgid "statistics_summary_updatepings_total"
+msgstr "Utilisateurs actifs par jour"
+
+#: views/statistics/rss/summary.thtml:48 views/statistics/addon.thtml:161
+#, php-format
+msgid "statistics_summary_updatepings_total_ondate"
+msgstr "Sur %1$s"
+
+#: views/statistics/rss/summary.thtml:61 views/statistics/addon.thtml:203
+msgid "statistics_summary_updatepings_weekly_average"
+msgstr "Moyenne quotidienne du nombre d'utilisateurs cette semaine"
+
+#. %s is a percentage, like '+22.33%'. It sits next to another number, so
+#. the implied meaning is 'percentage change' from the previous stat point.
+#: views/statistics/rss/summary.thtml:62 views/statistics/addon.thtml:205
+msgid "statistics_summary_updatepings_weekly_change"
+msgstr "%s par rapport à la semaine dernière"
+
+#: views/statistics/addon.thtml:65 controllers/statistics_controller.php:184
+#: controllers/statistics_controller.php:282
+#, php-format
+msgid "statistics_title_addon_stats"
+msgstr "Statistiques %1$s"
+
+#: views/addons/themes_landing.thtml:113
+msgid "themes_landing_all_themes"
+msgstr "Tous les thèmes"
+
+#: views/addons/themes_landing.thtml:109
+msgid "themes_landing_browse_themes"
+msgstr "Naviguer dans les thèmes"
+
+#: views/users/edit.thtml:185
+msgid "user_change_email"
+msgstr "Changer le courriel"
+
+#: views/users/edit.thtml:169
+msgid "user_change_password"
+msgstr "Changer le mot de passe"
+
+#: views/users/edit.thtml:96
+#, fuzzy
+msgid "user_change_password_or_email"
+msgstr "Change Password or Email"
+
+#: controllers/users_controller.php:197
+msgid "user_confirmationcode_resent"
+msgstr "Le code de confirmation a été renvoyé&nbsp;!"
+
+#. %1 is the email address, %2 is the URL of the user registration page
+#: views/users/delete.thtml:51
+msgid "user_del_account_deleted"
+msgstr ""
+"Votre compte utilisateur a bien été effacé. Si vous désirez revenir, vous "
+"pouvez vous réinscrire sur la <a href=\"%2$s\">page d'inscription des "
+"utilisateurs</a>"
+
+#: views/users/delete.thtml:102
+msgid "user_del_community_sad"
+msgstr "La communauté des Mozilla Add-ons regrette votre départ."
+
+#: views/users/delete.thtml:123
+msgid "user_del_confirm_password"
+msgstr "Confirmez le mot de passe"
+
+#: views/users/delete.thtml:134
+msgid "user_del_deletenow"
+msgstr "Effacer mon compte utilisateur maintenant"
+
+#. %1 is the URL of the user's info page
+#: views/users/delete.thtml:64
+msgid "user_del_error_addons"
+msgstr ""
+"Vous ne pouvez pas effacer votre compte si vous êtes listé comme <a href=\"%1"
+"$s\">auteur de modules</a>. Pour effacer votre compte, veuillez demander à "
+"un membre de votre groupe de développement de vous enlever de la liste des "
+"auteurs de vos modules. Une fois ceci fait, vous pourrez effacer votre "
+"compte depuis cette page."
+
+#. %1 is a link to the amo-editors mailing list
+#: views/users/delete.thtml:71
+msgid "user_del_error_addons_more_questions"
+msgstr ""
+"Si vous avez d'autres questions, veuillez contacter %1$s pour obtenir de "
+"l'assistance."
+
+#: views/users/delete.thtml:78
+msgid "user_del_error_checkbox"
+msgstr ""
+"You devez cocher la case \"Je comprends...\" avant que nous ne puissions "
+"effacer votre compte."
+
+#: views/users/delete.thtml:84
+msgid "user_del_error_password"
+msgstr ""
+"Veuillez saisir votre mot de passe correctement afin de passer cette étape."
+
+#. %1 is a link to the amo-admins mailing list
+#: views/users/delete.thtml:91
+msgid "user_del_error_unknown"
+msgstr ""
+"Une erreur non identifée s'est produite lors de la suppression de votre "
+"compte. Veuillez faire part de ce problème à %1$s et nous vous supprimerons "
+"votre compte. Veuillez nous excuser pour cette gêne."
+
+#: views/users/delete.thtml:110
+msgid "user_del_header_confirm_deletion"
+msgstr "Confirmer la suppression du compte"
+
+#. %1 is the user's email address
+#: views/users/delete.thtml:100
+msgid "user_del_header_delete_account"
+msgstr "Supprimer le compte utilisateur %1$s"
+
+#: views/users/delete.thtml:50
+msgid "user_del_header_farewell"
+msgstr "Au revoir&nbsp;!"
+
+#: views/users/delete.thtml:115
+msgid "user_del_nologin"
+msgstr "Vous ne pourrez plus vous connecter sur Mozilla Add-ons."
+
+#: views/users/delete.thtml:112
+msgid "user_del_permanently_removed_means"
+msgstr ""
+"En cliquant sur \"Supprimer\" votre compte sera <strong>effacé "
+"définitivement</strong>. Cela signifie que&nbsp;:"
+
+#: views/users/delete.thtml:116
+msgid "user_del_reviews_anonymized"
+msgstr ""
+"Vos critiques et évaluations ne seront pas effacées mais elle ne seront plus "
+"associées à votre nom."
+
+#. %1 is a link to the amo-editors mailing list
+#: views/users/delete.thtml:104
+msgid "user_del_specific_problem_editors"
+msgstr ""
+"Si vous avez un problème spécifique pour lequel vous avez besoin d'aide, ne "
+"supprimez pas votre compte maintenant mais contactez-nous via %1$s, nous "
+"ferons tout notre possible pour vous aider à le résoudre."
+
+#: views/users/delete.thtml:130
+msgid "user_del_understand_permanent"
+msgstr ""
+"Je comprend bien qu'une fois cette étape franchie, il n'y a pas de retour en "
+"arrière possible."
+
+#: views/helpers/addons_html.php:192
+msgid "user_deleted_nickname"
+msgstr "Utilisateur supprimé"
+
+#. %1 is the new email address
+#: views/users/edit.thtml:71
+msgid "user_edit_confirm_email_sent"
+msgstr ""
+"Un courriel a été envoyé à %1$s afin de confirmer votre nouvelle adresse "
+"électronique. Pour que ce changement soit effectif, vous devez cliquer sur "
+"le lien inclus dans ce courriel. En attendant, vous pouvez continuer de vous "
+"connecter avec votre adresse actuelle."
+
+#: views/users/edit.thtml:201
+msgid "user_edit_delete_user"
+msgstr "Supprimer le compte utilisateur"
+
+#. This contains the email sent to users when they signed up for a new
+#. account:
+#. %1 is the confirmation URL, %2 is the current app
+#: views/users/email/confirm_plain.thtml:6
+#, php-format
+msgid "user_email_confirm_account_nopass"
+msgstr ""
+"Bienvenue à %2$s Add-ons.\n"
+"\n"
+"Avant de pouvoir utiliser votre nouveau compte, vous devez l'activer. Cette "
+"mesure garantit que l'adresse électronique que vous avez utilisée est valide "
+"et vous appartient bien.\n"
+"Pour activer votre compte, cliquez sur le lien ci-dessous ou bien copiez-"
+"collez ce lien dans la barre d'adresse de votre navigateur :\n"
+"\n"
+"%1$s\n"
+"\n"
+"Une fois votre compte activé, vous pourrez détruire ce message.\n"
+"\n"
+"Merci de participer au site %2$s Add-ons.\n"
+"-- \n"
+"L'équipe %2$s Add-ons"
+
+#. %1 is the confirmation url, %2 is the application name
+#: views/users/email/emailchange_plain.thtml:5
+msgid "user_email_confirm_emailchange"
+msgstr ""
+"Vous avez demandé un changement de votre adresse électronique sur %2$s Add-"
+"ons.\n"
+"\n"
+"Afin de confirmer cette nouvelle adresse, veuillez cliquer sur le lien ci-"
+"dessous ou bien le copier-coller dans la barre d'adresse de votre "
+"navigateur:\n"
+"\n"
+"%1$s\n"
+"\n"
+"Vous avez 48 heures pour confirmer cette nouvelle adresse. Si vous ne voulez "
+"finalement plus changer d'adresse, ignorez ce message.\n"
+"\n"
+"Merci !\n"
+"-- \n"
+"L'équipe de %2$s Add-ons"
+
+#: controllers/users_controller.php:168
+#, php-format
+msgid "user_email_confirm_subject"
+msgstr "Merci de vous être inscrit à Mozilla Add-ons"
+
+#. This is the password reset email
+#. %1 is the pw reset URL, %2 is the application
+#: views/users/email/pwreset_plain.thtml:5
+#, php-format
+msgid "user_email_pwreset"
+msgstr ""
+"Réinitialisation du mot de passe pour Mozilla Add-ons\n"
+"\n"
+"Une demande de réinitialisation du mot de passe lié à cette adresse de "
+"messagerie a été faite. Pour changer votre mot de passe, veuillez cliquer "
+"sur le lien ci-dessous, ou bien le coller dans la barre d'adresse de votre "
+"navigateur:\n"
+"\n"
+"%1$s\n"
+"\n"
+"Si vous n'avez pas fait cette demande de modification, ignorez ce message.\n"
+"\n"
+"Merci.\n"
+"-- \n"
+"L'équipe de Mozilla Add-ons"
+
+#: controllers/users_controller.php:245
+#, php-format
+msgid "user_email_pwreset_subject"
+msgstr "Réinitialiser votre mot de passe AMO"
+
+#: views/users/emailchange.thtml:50
+msgid "user_emailchange_error"
+msgstr "Erreur&nbsp;!"
+
+#. %1 is the application name
+#: controllers/users_controller.php:533
+msgid "user_emailchange_subject"
+msgstr ""
+"Veuillez confirmer votre changement d'adresse électronique à %1$s Add-ons"
+
+#: views/users/emailchange.thtml:48
+msgid "user_emailchange_success"
+msgstr "Bravo&nbsp;!"
+
+#. %1 is the new email address
+#: views/users/emailchange.thtml:49
+msgid "user_emailchange_successful_description"
+msgstr ""
+"Votre adresse électronique a bien été changée. À partir de maintenant, "
+"utilisez %1$s pour vous connecter."
+
+#: views/users/edit.thtml:134 views/admin/users_edit.thtml:111
+msgid "user_form_bio"
+msgstr "À propos de moi"
+
+#: views/users/edit.thtml:135 views/admin/users_edit.thtml:112
+msgid "user_form_bio_description"
+msgstr ""
+"Présentez-vous à la communauté si vous le désirez! Ce texte sera affiché sur "
+"votre page publique d'utilisateur. Les sauts de ligne seront conservés mais "
+"l'utilisation du HTML n'est pas permise."
+
+#: views/users/pwreset.thtml:77 views/users/register.thtml:73
+#: views/users/edit.thtml:181
+msgid "user_form_confirmpassword"
+msgstr "Confirmez le mot de passe"
+
+#: views/users/edit.thtml:145
+#, fuzzy
+msgid "user_form_display_collections"
+msgstr "Display the collections I have created in my user profile"
+
+#: views/users/edit.thtml:149
+#, fuzzy
+msgid "user_form_display_collections_fav"
+msgstr "Display my favorite collections in my user profile"
+
+#: views/users/edit.thtml:86
+#, php-format
+msgid "user_form_editprofile"
+msgstr "Éditer le profil utilisateur de %s"
+
+#: views/users/pwreset.thtml:52 views/users/login.thtml:81
+#: views/users/register.thtml:63 views/users/edit.thtml:187
+msgid "user_form_email"
+msgstr "Courriel"
+
+#: views/users/register.thtml:78 views/users/edit.thtml:103
+#: views/admin/users_edit.thtml:76
+msgid "user_form_firstname"
+msgstr "Prénom"
+
+#: views/users/register.thtml:94 views/users/edit.thtml:119
+#: views/admin/users_edit.thtml:91
+msgid "user_form_hideemail"
+msgstr "Masquer l'adresse électronique"
+
+#: views/users/register.thtml:98 views/users/edit.thtml:123
+#: views/admin/users_edit.thtml:99
+msgid "user_form_homepage"
+msgstr "Site web (URL)"
+
+#: views/users/register.thtml:84 views/users/edit.thtml:109
+#: views/admin/users_edit.thtml:81
+msgid "user_form_lastname"
+msgstr "Nom"
+
+#: controllers/users_controller.php:333
+msgid "user_form_login"
+msgstr "Connexion utilisateur"
+
+#: views/users/pwreset.thtml:72 views/users/edit.thtml:176
+msgid "user_form_newpassword"
+msgstr "Nouveau mot de passe"
+
+#: views/users/register.thtml:89 views/users/edit.thtml:114
+#: views/admin/users_edit.thtml:86
+msgid "user_form_nickname"
+msgstr "Pseudo"
+
+#: views/users/edit.thtml:171
+msgid "user_form_oldpassword"
+msgstr "Ancien mot de passe"
+
+#: views/users/edit.thtml:97 views/users/edit.thtml:200
+msgid "user_form_otheractions"
+msgstr "Autres opérations"
+
+#: views/users/login.thtml:85 views/users/register.thtml:68
+msgid "user_form_password"
+msgstr "Mot de passe"
+
+#: controllers/users_controller.php:93
+msgid "user_form_registration"
+msgstr "Enregistrement d'un nouvel utilisateur"
+
+#: views/users/login.thtml:90
+msgid "user_form_remember_me"
+msgstr "Se souvenir de moi sur cet ordinateur"
+
+#: views/admin/users_edit.thtml:95
+msgid "user_form_showsandbox"
+msgstr "Afficher le bac à sable ?"
+
+#: views/users/edit.thtml:205
+msgid "user_form_submit_edit"
+msgstr "Enregistrer"
+
+#: views/users/login.thtml:93
+msgid "user_form_submit_login"
+msgstr "Se connecter"
+
+#: views/users/register.thtml:113
+msgid "user_form_submit_register"
+msgstr "S'enregistrer"
+
+#: views/users/info.thtml:75
+#, php-format
+msgid "user_info_usersince"
+msgstr "%s est un utilisateur AMO depuis "
+
+#: views/users/login.thtml:102
+msgid "user_login_register_link"
+msgstr "Créer un nouveau compte utilisateur"
+
+#: views/users/edit.thtml:160
+msgid "user_notifications_item_compat"
+msgstr "Compatibilité du module (fortement recommandé)"
+
+#: views/users/edit.thtml:161
+msgid "user_notifications_item_events"
+msgstr "Évènements et concours à venir"
+
+#: views/users/edit.thtml:156
+msgid "user_notifications_none_available"
+msgstr ""
+"Il n'y a actuellement aucune notification nécessitant une configuration de "
+"votre part."
+
+#: views/users/edit.thtml:158
+msgid "user_notifications_select_topics"
+msgstr ""
+"Occasionnellement, Mozilla peut vous envoyer un courriel concernant les "
+"prochaines sorties logicielles et des évènements liés aux modules. Veuillez "
+"sélectionnez ci-dessous les sujets susceptibles de vous intéresser&nbsp;:"
+
+#: views/users/edit.thtml:164
+msgid "user_notifications_specific_contact"
+msgstr ""
+"Mozilla se réserve le droit de vous contacter personnellement pour des "
+"problèmes particuliers liés à vos modules hébergés."
+
+#: controllers/users_controller.php:543
+msgid "user_profile_edit_error"
+msgstr ""
+"Les changements que vous avez effectués contenaient des erreurs. Veuillez "
+"les corriger avant de soumettre le formulaire à nouveau."
+
+#: controllers/users_controller.php:540
+msgid "user_profile_saved"
+msgstr "Profil mis à jour."
+
+#: views/users/pwreset.thtml:65
+#, php-format
+msgid "user_pwreset_for_email"
+msgstr "Mot de passe de %s réinitialisé"
+
+#: controllers/users_controller.php:226
+msgid "user_pwreset_header"
+msgstr "Réinitialisation du mot de passe"
+
+#: views/users/login.thtml:103
+msgid "user_pwreset_link"
+msgstr "Mot de passe oublié&nbsp;?"
+
+#: controllers/users_controller.php:248
+msgid "user_pwreset_link_sent"
+msgstr "Le lien de réinitialisation de votre mot de passe a été envoyé."
+
+#: controllers/users_controller.php:304
+msgid "user_pwreset_okay"
+msgstr "Mot de passe réinitialisé avec succès."
+
+#: views/users/pwreset.thtml:82
+msgid "user_pwreset_submit_changepw"
+msgstr "Envoyer le nouveau mot de passe"
+
+#: views/users/pwreset.thtml:57
+msgid "user_pwreset_submit_sendlink"
+msgstr "Envoyer un lien pour réinitialiser le mot de passe"
+
+#: views/users/register_complete.thtml:51
+#, php-format
+msgid "user_register_amo_link"
+msgstr "%s AMO"
+
+#. %1 is the user's email address, %2 is the current app
+#: views/users/activatefirst.thtml:49
+#, php-format
+msgid "user_register_click_confirm_link"
+msgstr ""
+"Un lien pour activer votre compte utilisateur vous a été envoyé par courriel "
+"à l'adresse %1$s. Vous devez cliquer sur ce lien avant de pouvoir vous "
+"connecter à Mozilla Add-ons."
+
+#. %1 is the user's email address
+#: views/users/register_complete.thtml:49
+#, php-format
+msgid "user_register_confirm_email_sent"
+msgstr ""
+"Un courriel a été envoyé à votre adresse %1$s afin de confirmer votre "
+"compte. Avant de pouvoir vous connecter, vous devez activer votre compte en "
+"cliquant sur le lien fourni dans ce message."
+
+#: views/users/activatefirst.thtml:51
+msgid "user_register_confirmation_link_text"
+msgstr "envoyer à nouveau le message de confirmation"
+
+#: views/users/register_complete.thtml:47
+msgid "user_register_congratulations"
+msgstr "Félicitations&nbsp;! Votre compte utilisateur a bien été créé."
+
+#: views/users/register.thtml:50
+#, fuzzy
+msgid "user_register_details"
+msgstr ""
+"<p>Registration on AMO is <strong>not required</strong> if you simply want "
+"to download and install public add-ons.</p><p>You only need to register if:</"
+"p><ul><li>You want to submit reviews for add-ons</li><li>You are an add-on "
+"developer and want to upload your add-on for hosting on AMO</li></ul><p>Upon "
+"successful registration, you will be sent a confirmation email to the "
+"address you provided. Please follow the instructions there to confirm your "
+"account.</p><p>If you like, you can read our <a href='%1$s' title='Legal "
+"Notices'>Legal Notices</a> and <a href='%2$s' title='Privacy Policy'>Privacy "
+"Policy</a>.</p>"
+
+#. %1 is the link to the "resend confirmation code" page
+#: views/users/activatefirst.thtml:51
+#, php-format
+msgid "user_register_resend_confirmation_link"
+msgstr ""
+"Si vous n'avez pas reçu le message de confirmation, assurez-vous que ce "
+"message n'a pas été marqué comme indésirable (spam) par votre fournisseur de "
+"courrier. Si nécessaire, nous pouvons %1$s à l'adresse de messagerie "
+"mentionnée ci-dessus."
+
+#. %1 is the link to the Mozilla Add-ons front page
+#: views/users/register_complete.thtml:51
+#, php-format
+msgid "user_register_welcome"
+msgstr "Merci de vous être inscrit et bienvenue sur %1$s!"
+
+#: views/users/register.thtml:49
+msgid "user_register_welcome_header"
+msgstr "Bienvenue sur addons.mozilla.org (AMO)&nbsp;!"
+
+#: views/users/register.thtml:81 views/users/edit.thtml:106
+msgid "user_required_firstlast_or_nickname"
+msgstr "Votre nom, prénom ou pseudo est nécessaire."
+
+#: views/users/edit.thtml:94 views/users/edit.thtml:142
+#, fuzzy
+msgid "user_tab_collections"
+msgstr "Collections"
+
+#: views/users/edit.thtml:95 views/users/edit.thtml:154
+msgid "user_tab_notifications"
+msgstr "Notifications"
+
+#: views/users/edit.thtml:93 views/users/edit.thtml:101
+msgid "user_tab_profile"
+msgstr "Profil utilisateur"
+
+#: controllers/users_controller.php:209
+msgid "user_verified_okay"
+msgstr "Vérification réussie&nbsp;!"
+
+#: controllers/users_controller.php:723
+msgid "users_delete_pagetitle"
+msgstr "Supprimer le compte utilisateur"
+
+#: controllers/users_controller.php:414
+msgid "users_edit_pagetitle"
+msgstr "Édition du compte utilisateur"
+
+#: views/users/info.thtml:71
+msgid "users_info_aboutme"
+msgstr "À propos de moi"
+
+#: views/users/info.thtml:96
+#, php-format
+msgid "users_info_addons_by_user"
+msgstr "Modules de %1$s"
+
+#: views/users/info.thtml:51
+msgid "users_info_author_name"
+msgstr "Nom"
+
+#: views/users/info.thtml:48
+msgid "users_info_author_profile"
+msgstr "Profil de l'auteur"
+
+#. %s is the user name
+#: views/users/info.thtml:137
+#, fuzzy
+msgid "users_info_collections_by_user"
+msgstr "Collections by %s"
+
+#: views/users/info.thtml:66
+msgid "users_info_email"
+msgstr "Courriel"
+
+#: views/users/info.thtml:155
+#, fuzzy
+msgid "users_info_fav_collections_by_user"
+msgstr "Favorite Collections"
+
+#: views/users/info.thtml:61
+msgid "users_info_homepage"
+msgstr "Site web"
+
+#: views/users/info.thtml:56
+msgid "users_info_nickname"
+msgstr "Pseudo"
+
+#: controllers/users_controller.php:707
+#, php-format
+msgid "users_info_pagetitle"
+msgstr "Information sur %1$s"
+
+#. %1 is the user's name
+#: views/users/info.thtml:116
+msgid "users_info_reviews_by_user"
+msgstr "Critiques de %s"
+
+#: controllers/users_controller.php:330 controllers/users_controller.php:332
+msgid "users_login_pagetitle"
+msgstr "Connexion utilisateur"
+
+#. %1 is the link to the sandbox/policy explanation page
+#. This message is for a specific add-on not found
+#: views/users/login.thtml:53
+#, php-format
+msgid "users_login_sandbox_display_warning"
+msgstr ""
+"Le module que vous recherchez est actuellement dans le bac à sable. Si vous "
+"avez déjà un compte Mozilla Add-ons, veuillez vous connecter, sinon, <a href="
+"\"%1$s\">consultez ces informations sur la zone de bac à sable.</a>"
+
+#. %1 is the link to the sandbox/policy explanation page
+#. This message is for any given sandbox-related page not found
+#: views/users/login.thtml:56
+#, php-format
+msgid "users_login_sandbox_page_warning"
+msgstr ""
+"La page que vous consultez actuellement fait partie de la zone appelée "
+"<em>bac à sable</em>. Si vous avez déjà un compte Mozilla Add-ons, veuillez "
+"vous connecter, sinon, <a href=\"%1$s\">consultez ces informations sur la "
+"zone de bac à sable.</a>"
+
+#: controllers/users_controller.php:223 controllers/users_controller.php:225
+msgid "users_pwreset_pagetitle"
+msgstr "Mot de passe utilisateur réinitialisé"
+
+#: controllers/users_controller.php:90 controllers/users_controller.php:92
+msgid "users_register_pagetitle"
+msgstr "Inscription d'un nouvel utilisateur"
+
+#. %1$s is an addon name, like <a>Firebug</a>
+#. %2$s is a version number, like <a>1.2</a>
+#: views/versions/license.thtml:52
+msgid "versions_license_header_source"
+msgstr "Licence du code source de %1$s %2$s"
+
+#: views/addons/category_landing.thtml:147
+msgid "view_recently_added"
+msgstr "Afficher tous les ajouts récents"
+
+#: views/addons/category_landing.thtml:161
+msgid "view_top_downloads"
+msgstr "Afficher les plus téléchargés"
+
+#: views/addons/category_landing.thtml:175
+msgid "view_top_rated"
+msgstr "Afficher les mieux notés"
+
+#~ msgid "addon_slider_tooltip_next"
+#~ msgstr "Module suivant"
+
+#~ msgid "addon_slider_tooltip_previous"
+#~ msgstr "Module précédent"
+
+#~ msgid "addon_versions_getlatesttext"
+#~ msgstr "La plus récente version compatible avec "
+
+#~ msgid "addons_display_version_history"
+#~ msgstr "Historique complet des versions"
+
+#~ msgid "addons_home_newest_header"
+#~ msgstr "Ajouts récents"
+
+#~ msgid "addons_home_popular_header"
+#~ msgstr "Les plus populaires&nbsp;:"
+
+#~ msgid "addons_home_recommended_header"
+#~ msgstr "Nous recommandons&nbsp;:"
+
+#~ msgid "addons_home_updated_header"
+#~ msgstr "Mises à jour récentes&nbsp;:"
+
+#~ msgid "addons_home_view_all"
+#~ msgstr "Tout afficher"
+
+#~ msgid "category_extra_allrecommended"
+#~ msgstr "Voir tous les modules recommandés"
+
+#~ msgid "category_extra_highestrated"
+#~ msgstr "Les mieux notés en premier"
+
+#~ msgid "category_extra_lastupdated"
+#~ msgstr "Les plus récemment mis à jour en premier"
+
+#~ msgid "category_extra_mostpopular"
+#~ msgstr "Les plus populaires en premier"
+
+#, fuzzy
+#~ msgid "collections_detail_js_loading"
+#~ msgstr "Loading"
+
+#, fuzzy
+#~ msgid "collections_detail_more_info"
+#~ msgstr "Show More Info"
+
+#~ msgid "devcp_additem_firefox_notice"
+#~ msgstr ""
+#~ "Cette version de votre module n'indique pas être compatible avec Firefox %"
+#~ "1$s. Mozilla a l'intention de sortir une nouvelle version de Firefox "
+#~ "bientôt, nous vous engageons à tester votre module dans la nouvelle "
+#~ "version et à mettre à jour les informations de compatibilité. Vous "
+#~ "trouverez de plus amples informations à ce sujet <a href=\"%2$s\">ici</"
+#~ "a>. Ce message vous est transmis à titre informatif, vous pouvez "
+#~ "continuer à envoyer cette version à addons.mozilla.org."
+
+#~ msgid "devcp_addon_disabled_successfully"
+#~ msgstr "Module désactivé avec succès"
+
+#~ msgid "devcp_addon_edit_pagetitle"
+#~ msgstr "Éditer le module"
+
+#~ msgid "devcp_addon_enabled_successfully"
+#~ msgstr "Module activé avec succès"
+
+#~ msgid "devcp_addon_field_description_displaytitle"
+#~ msgstr "Description du module"
+
+#~ msgid "devcp_addon_field_eula_displaytitle"
+#~ msgstr "CLUF"
+
+#~ msgid "devcp_addon_field_homepage_displaytitle"
+#~ msgstr "Page d'accueil du module"
+
+#~ msgid "devcp_addon_field_name_displaytitle"
+#~ msgstr "Nom du module"
+
+#~ msgid "devcp_addon_field_privacy_displaytitle"
+#~ msgstr "Politique de confidentialité"
+
+#~ msgid "devcp_addon_field_summary_displaytitle"
+#~ msgstr "Résumé du module"
+
+#~ msgid "devcp_addon_field_supportemail_displaytitle"
+#~ msgstr "Courriel d'assistance"
+
+#~ msgid "devcp_addon_field_supporturl_displaytitle"
+#~ msgstr "URL d'assistance"
+
+#~ msgid "devcp_addon_field_versionnotes_displaytitle"
+#~ msgstr "Notes de version"
+
+#~ msgid "devcp_addon_nominate_pagetitle"
+#~ msgstr "Proposer le module"
+
+#~ msgid "devcp_addon_nominated_successfully"
+#~ msgstr "Module proposé avec succès&nbsp;!"
+
+#, fuzzy
+#~ msgid "devcp_addon_status_criteria_review"
+#~ msgstr "Several user reviews of the add-on (may be external reviews)."
+
+#~ msgid "devcp_addon_submission_makechanges"
+#~ msgstr ""
+#~ "Visitez la page %1$s afin d'effectuer des changements à votre soumission "
+#~ "ou bien %2$s pour retourner au panneau de contrôle du développeur."
+
+#~ msgid "devcp_addon_submission_makechanges_devcp_link"
+#~ msgstr "Cliquez ici"
+
+#~ msgid "devcp_addon_submission_makechanges_link"
+#~ msgstr "Éditer le module"
+
+#~ msgid "devcp_addon_submission_pending"
+#~ msgstr ""
+#~ "Cette version a été placée dans le bac à sable jusqu'à ce qu'elle soit "
+#~ "validée par les testeurs de la zone de bac à sable ainsi qu'un éditeur. "
+#~ "Vous serez averti par courriel lorsqu'une mesure concernant votre module "
+#~ "aura été prise."
+
+#~ msgid "devcp_addon_submission_sandbox_readmore"
+#~ msgstr ""
+#~ "Vous pouvez en découvrir d'avantage sur le système de révision du bac à "
+#~ "sable %s."
+
+#~ msgid "devcp_addon_submission_sandbox_readmore_link"
+#~ msgstr "ici"
+
+#~ msgid "devcp_addon_submission_sandboxed"
+#~ msgstr ""
+#~ "Cette version a été placée dans le bac à sable pour être proposé à des "
+#~ "utilisateurs expérimentés. Afin de s'afficher sur le site public, vous "
+#~ "devez %s votre module et subir un processus de vérification."
+
+#~ msgid "devcp_addon_submission_sandboxed_nominate_link"
+#~ msgstr "nominer"
+
+#~ msgid "devcp_addon_submission_success"
+#~ msgstr "La soumission de votre module a été réalisée avec succès."
+
+#~ msgid "devcp_addon_submission_trusted_public"
+#~ msgstr ""
+#~ "Votre module étant considéré de confiance, cette version a été approuvée "
+#~ "automatiquement pour la zone publique."
+
+#~ msgid "devcp_addon_submit_pagetitle"
+#~ msgstr "Soumettre un module"
+
+#~ msgid "devcp_addon_updated_successfully"
+#~ msgstr "Module mis à jour avec succès"
+
+#~ msgid "devcp_addon_upload_preview"
+#~ msgstr "Vous désirez peut-être %s afin de promouvoir votre module."
+
+#~ msgid "devcp_addon_upload_preview_link"
+#~ msgstr "Envoyer une pré-version"
+
+#~ msgid "devcp_author_lookup_none_found"
+#~ msgstr "Aucun auteur trouvé [%s]"
+
+#~ msgid "devcp_author_lookup_remove"
+#~ msgstr "Enlever"
+
+#~ msgid "devcp_button_cancel"
+#~ msgstr "Annuler"
+
+#~ msgid "devcp_button_cancel_confirm"
+#~ msgstr "Êtes-vous certain de vouloir annuler votre soumission&nbsp;?"
+
+#~ msgid "devcp_button_next"
+#~ msgstr "Suivant"
+
+#~ msgid "devcp_change_addontype"
+#~ msgstr "Modifier le type de module&nbsp;:"
+
+#~ msgid "devcp_comments_updated"
+#~ msgstr "Commentaire développeur mis à jour."
+
+#~ msgid "devcp_details_addpreview_link"
+#~ msgstr "Ajouter une prévisualisation"
+
+#~ msgid "devcp_details_author"
+#~ msgstr "Auteur"
+
+#~ msgid "devcp_details_authors"
+#~ msgstr "Auteurs"
+
+#~ msgid "devcp_details_authors_none"
+#~ msgstr "Aucun"
+
+#~ msgid "devcp_details_categories"
+#~ msgstr "Catégories"
+
+#~ msgid "devcp_details_category"
+#~ msgstr "Catégorie"
+
+#~ msgid "devcp_details_description"
+#~ msgstr "Description"
+
+#~ msgid "devcp_details_disabled"
+#~ msgstr "Désactivé"
+
+#~ msgid "devcp_details_guid"
+#~ msgstr "GUID"
+
+#~ msgid "devcp_details_header_details"
+#~ msgstr "Détails"
+
+#~ msgid "devcp_details_header_devcomments"
+#~ msgstr "Commentaires du développeur"
+
+#~ msgid "devcp_details_header_previews"
+#~ msgstr "Prévisualisations"
+
+#~ msgid "devcp_details_header_versions"
+#~ msgstr "Versions"
+
+#~ msgid "devcp_details_homepage"
+#~ msgstr "Page d'accueil"
+
+#~ msgid "devcp_details_homepage_none"
+#~ msgstr "Aucun"
+
+#~ msgid "devcp_details_preview_nocaption"
+#~ msgstr "Aucun texte d'illustration"
+
+#~ msgid "devcp_details_previews_nonefound"
+#~ msgstr "Aucune prévisualisation trouvée."
+
+#~ msgid "devcp_details_submit_update"
+#~ msgstr "Mettre à jour"
+
+#~ msgid "devcp_details_supportemail"
+#~ msgstr "Courriel d'assistance"
+
+#~ msgid "devcp_details_supportemail_none"
+#~ msgstr "Le développeur n'a pas fourni de courriel d'assistance."
+
+#~ msgid "devcp_details_supporturl"
+#~ msgstr "URL d'assistance"
+
+#~ msgid "devcp_details_supporturl_none"
+#~ msgstr "Le développeur n'a pas fourni d'URL d'assistance."
+
+#~ msgid "devcp_details_trusted"
+#~ msgstr "De confiance"
+
+#~ msgid "devcp_details_versions_none_found"
+#~ msgstr "Aucune version trouvée."
+
+#~ msgid "devcp_disable_cancel"
+#~ msgstr "Annuler et revenir en arrière"
+
+#~ msgid "devcp_disable_disable_button"
+#~ msgstr "Oui, le désactiver"
+
+#~ msgid "devcp_disable_disable_confirm"
+#~ msgstr "Êtes-vous sûr de vouloir désactiver ce module&nbsp;?"
+
+#~ msgid "devcp_disable_disable_description"
+#~ msgstr ""
+#~ "Désactiver ce module le cachera des résultats de recherche et des pages "
+#~ "publiques. Celui-ci ne pourra plus être téléchargé depuis le site et ne "
+#~ "sera plus proposé via les vérifications automatiques de mise à jour. Le "
+#~ "module sera bel et bien effacé, néanmoins vous pourrez revenir ici et le "
+#~ "réactiver à votre guise. "
+
+#~ msgid "devcp_disable_disable_title"
+#~ msgstr "Désactiver %s"
+
+#~ msgid "devcp_disable_enable_button"
+#~ msgstr "Oui, je l'active"
+
+#~ msgid "devcp_disable_enable_confirm"
+#~ msgstr "Êtes-vous sûr de vouloir activer ce module&nbsp;?"
+
+#~ msgid "devcp_disable_enable_description"
+#~ msgstr ""
+#~ "Activer ce module permettra son affichage dans les résultats de "
+#~ "recherches et sur les pages publiques. Celui-ci sera téléchargeable à la "
+#~ "fois depuis le site Web et depuis les vérifications automatiques de mise "
+#~ "à jour des clients."
+
+#~ msgid "devcp_disable_enable_title"
+#~ msgstr "Activer %s"
+
+#~ msgid "devcp_edit_author_add"
+#~ msgstr "Ajouter l'auteur"
+
+#~ msgid "devcp_edit_author_email"
+#~ msgstr "Courriel de l'auteur"
+
+#~ msgid "devcp_edit_author_remove"
+#~ msgstr "Enlever"
+
+#~ msgid "devcp_edit_error_categories_unavailable"
+#~ msgstr "Aucune catégorie disponible pour ce type de module."
+
+#, fuzzy
+#~ msgid "devcp_edit_file_error_incomplete"
+#~ msgstr "Incomplete transfer"
+
+#, fuzzy
+#~ msgid "devcp_edit_file_error_no"
+#~ msgstr "No file uploaded"
+
+#, fuzzy
+#~ msgid "devcp_edit_file_error_size"
+#~ msgstr "Exceeds maximum upload size"
+
+#~ msgid "devcp_edit_header_authors"
+#~ msgstr "Auteurs"
+
+#~ msgid "devcp_edit_icon_add_link"
+#~ msgstr "Ajouter une icône"
+
+#~ msgid "devcp_edit_icon_change_link"
+#~ msgstr "Changer l'icône"
+
+#~ msgid "devcp_edit_label_allow_viewsource"
+#~ msgstr "Permettre aux utilisateurs de voir les fichiers sources en ligne"
+
+#~ msgid "devcp_edit_label_categories"
+#~ msgstr "Catégories"
+
+#~ msgid "devcp_edit_label_defaultlocale"
+#~ msgstr "Langue par défaut"
+
+#~ msgid "devcp_edit_label_icon_delete"
+#~ msgstr "N'effacer que l'icône actuelle"
+
+#~ msgid "devcp_edit_label_icon_new"
+#~ msgstr "Nouveau fichier icône"
+
+#~ msgid "devcp_edit_label_info"
+#~ msgstr "Icône"
+
+#~ msgid "devcp_edit_locale_disambiguation_explanation"
+#~ msgstr ""
+#~ "information suplémentaire succinte (telle que le nom de la langue "
+#~ "régionale)"
+
+#~ msgid "devcp_edit_submit_update"
+#~ msgstr "Mettre à jour"
+
+#~ msgid "devcp_edit_target_locale_explanation"
+#~ msgstr ""
+#~ "<a href=\"http://wiki.mozilla.org/L10n:Simple_locale_names\">code langue "
+#~ "simple</a> tel que 'en-US'"
+
+#~ msgid "devcp_editversion_checkedfiles_delete"
+#~ msgstr "Les fichiers cochés seront effacés."
+
+#~ msgid "devcp_editversion_filename_size"
+#~ msgstr "%1$s (%2$s)"
+
+#~ msgid "devcp_editversion_label_files"
+#~ msgstr "Fichiers"
+
+#~ msgid "devcp_editversion_label_targetapps"
+#~ msgstr "Applications cibles"
+
+#~ msgid "devcp_editversion_nofiles"
+#~ msgstr "Aucun fichier."
+
+#~ msgid "devcp_editversion_reviewernotes"
+#~ msgstr "Notes au réviseur"
+
+#~ msgid "devcp_editversion_submit_update"
+#~ msgstr "Mettre à jour"
+
+#~ msgid "devcp_error_addon_field_summary_toolong"
+#~ msgstr ""
+#~ "Les résumés sont limités à un maximum de 250 caractères.\n"
+#~ "(Vous en avez saisi %s)"
+
+#~ msgid "devcp_error_addonname_not_unique"
+#~ msgstr ""
+#~ "Le nom de votre module existe déjà dans la base de données. Assurez-vous "
+#~ "que&nbsp;: <br /><li>vos GUIDs correspondent. La cause la plus commune "
+#~ "pour cette erreur est la non correspondance des GUIDs.</li><li>Vous "
+#~ "n'avez pas d'entrée dupliquée dans la base de données. Si c'est le cas, "
+#~ "vous devriez mettre à jour cette entrée ou l'effacer et recommencer "
+#~ "l'opération.</li>"
+
+#~ msgid "devcp_error_describe_changes"
+#~ msgstr ""
+#~ "Veuillez décrire les changements apportés par la mise à jour de ce module."
+
+#~ msgid "devcp_error_file_guids_dont_match"
+#~ msgstr "Les GUIDs de tous les fichiers ne correspondent pas"
+
+#~ msgid "devcp_error_identical_version_exists"
+#~ msgstr ""
+#~ "Une version identique (%s) existe déjà pour ce module et cette plateforme."
+
+#~ msgid "devcp_error_nominate_message"
+#~ msgstr "Vous devez fournir les détails demandés pour la nomination."
+
+#~ msgid "devcp_error_nominate_no_prerelease"
+#~ msgstr "Vous ne pouvez sélectionner un module en pré-version."
+
+#~ msgid "devcp_error_nominate_sandbox_only"
+#~ msgstr ""
+#~ "Vous ne pouvez nominer que des modules actuellement dans le bac à sable."
+
+#~ msgid "devcp_error_saving"
+#~ msgstr "Une erreur s'est produite lors de l'enregistremnet de vos données."
+
+#~ msgid "devcp_error_update_access_denied"
+#~ msgstr "Vous n'avez pas l'autorisation de mettre à jour ce module."
+
+#~ msgid "devcp_file_addanother"
+#~ msgstr "Ajouter un autre fichier pour la plateforme"
+
+#~ msgid "devcp_form_author_add"
+#~ msgstr "Ajouter auteur"
+
+#~ msgid "devcp_form_author_remove"
+#~ msgstr "Supprimer"
+
+#~ msgid "devcp_form_categories_nextstep"
+#~ msgstr ""
+#~ "Les catégories pour votre module seront disponibles à l'étape suivante."
+
+#~ msgid "devcp_form_error_categories_unavailable"
+#~ msgstr "Aucune catégorie disponible pour ce type de module."
+
+#~ msgid "devcp_form_error_description_notempty"
+#~ msgstr "Veuillez saisir une description pour votre module."
+
+#~ msgid "devcp_form_error_name_required"
+#~ msgstr "Veuillez saisir le nom de votre module."
+
+#~ msgid "devcp_form_error_select_addontype"
+#~ msgstr "Veuillez sélectionner le type de module que vous proposez."
+
+#~ msgid "devcp_form_error_summary_notempty"
+#~ msgstr "Veuillez saisir un résumé de votre module."
+
+#~ msgid "devcp_form_label_addonfile"
+#~ msgstr "Fichier de module"
+
+#~ msgid "devcp_form_label_addonfile2"
+#~ msgstr "Fichier de module 2"
+
+#~ msgid "devcp_form_label_addonfile3"
+#~ msgstr "Fichier de module 3"
+
+#~ msgid "devcp_form_label_addontype"
+#~ msgstr "Type de module"
+
+#~ msgid "devcp_form_label_allow_viewsource"
+#~ msgstr "Permettre aux utilisateurs de voir les fichiers sources en ligne"
+
+#~ msgid "devcp_form_label_author_email"
+#~ msgstr "Courriel de l'auteur"
+
+#~ msgid "devcp_form_label_authors"
+#~ msgstr "Auteurs"
+
+#~ msgid "devcp_form_label_categories"
+#~ msgstr "Catégories"
+
+#~ msgid "devcp_form_label_defaultlocale"
+#~ msgstr "Langue par défaut"
+
+#~ msgid "devcp_form_label_description"
+#~ msgstr "Description"
+
+#~ msgid "devcp_form_label_eula"
+#~ msgstr "Contrat de License Utilisateur Final (CLUF)"
+
+#~ msgid "devcp_form_label_externalsoftware"
+#~ msgstr "Ce module a besoin d'un logiciel externe"
+
+#~ msgid "devcp_form_label_files"
+#~ msgstr "Fichiers"
+
+#~ msgid "devcp_form_label_homepage"
+#~ msgstr "Page d'accueil"
+
+#~ msgid "devcp_form_label_iconfile"
+#~ msgstr "Fichier icône"
+
+#~ msgid "devcp_form_label_name"
+#~ msgstr "Nom"
+
+#~ msgid "devcp_form_label_platforms"
+#~ msgstr "Plateformes supportées"
+
+#~ msgid "devcp_form_label_prerelease"
+#~ msgstr "Ceci est une pré-version"
+
+#~ msgid "devcp_form_label_privacy"
+#~ msgstr "Politique de confidentialité"
+
+#~ msgid "devcp_form_label_sitespecific"
+#~ msgstr "Ce module concerne un site web spécifique"
+
+#~ msgid "devcp_form_label_summary"
+#~ msgstr "Résumé"
+
+#~ msgid "devcp_form_label_supportemail"
+#~ msgstr "Courriel d'assistance"
+
+#~ msgid "devcp_form_label_supporturl"
+#~ msgstr "URL d'assistance"
+
+#~ msgid "devcp_form_label_target_applications"
+#~ msgstr "Applications cibles"
+
+#~ msgid "devcp_form_label_version"
+#~ msgstr "Version"
+
+#~ msgid "devcp_form_label_versionnotes"
+#~ msgstr "Notes de version"
+
+#~ msgid "devcp_form_no_target_apps"
+#~ msgstr "Aucun"
+
+#~ msgid "devcp_form_reviewernotes"
+#~ msgstr "Notes au réviseur"
+
+#~ msgid "devcp_form_trustedaddon_destination"
+#~ msgstr ""
+#~ "Votre module étant jugé de confiance, choisissez où cette version devrait "
+#~ "être placée&nbsp;:"
+
+#~ msgid "devcp_form_trustedaddon_destination_public"
+#~ msgstr "Public"
+
+#~ msgid "devcp_form_trustedaddon_destination_sandbox"
+#~ msgstr "Bac à sable"
+
+#~ msgid "devcp_header_developer_agreement"
+#~ msgstr "Accord du développeur"
+
+#~ msgid "devcp_header_step1"
+#~ msgstr "Étape 1"
+
+#~ msgid "devcp_header_step1_upload"
+#~ msgstr "Envoi du fichier"
+
+#~ msgid "devcp_header_step2"
+#~ msgstr "Étape 2"
+
+#~ msgid "devcp_header_step2_addondetails"
+#~ msgstr "Détails du module"
+
+#~ msgid "devcp_header_step3"
+#~ msgstr "Étape 3"
+
+#~ msgid "devcp_header_step3_versiondetails"
+#~ msgstr "Détails de la version"
+
+#~ msgid "devcp_header_step4"
+#~ msgstr "Étape 4"
+
+#~ msgid "devcp_header_step4_localization"
+#~ msgstr "Localisation"
+
+#~ msgid "devcp_header_step5"
+#~ msgstr "Étape 5"
+
+#~ msgid "devcp_header_step5_success"
+#~ msgstr "Succès"
+
+#~ msgid "devcp_index_header_myaddons"
+#~ msgstr "Mes modules"
+
+#~ msgid "devcp_nominate_link_returnto_details"
+#~ msgstr "Revenir aux détails du module"
+
+#~ msgid "devcp_notice_autodetected_addontype"
+#~ msgstr "Type de module automatiquement détecté&nbsp;: %s."
+
+#~ msgid "devcp_notice_different_defaultlocale"
+#~ msgstr ""
+#~ "La locale par défaut de ce module (%1$s [%2$s]) est différente de celle "
+#~ "que vous avez sélectionnée actuellement (%3$s [%4$s]). Les champs ci-"
+#~ "dessous devraient être remplis dans %1$s."
+
+#~ msgid "devcp_question_addontype_incorrect"
+#~ msgstr "Incorrect&nbsp;?"
+
+#~ msgid "devcp_question_delete_file"
+#~ msgstr "Êtes-vous sûr de vouloir effacer ce fichier&nbsp;?"
+
+#~ msgid "devcp_skip_reviewing_addon_info"
+#~ msgstr ""
+#~ "Passer l'étape de mise à jour des informations concernant mon module."
+
+#~ msgid "devcp_submissions_disabled"
+#~ msgstr ""
+#~ "Les soumissions de modules sont actuellement désactivées. Veuillez "
+#~ "réessayer plus tard."
+
+#~ msgid "devcp_submit_accept_dev_agreement"
+#~ msgstr "J'accepte"
+
+#~ msgid "devcp_submit_decline_dev_agreement"
+#~ msgstr "Je refuse"
+
+#~ msgid "devcp_summary_admin_disabled"
+#~ msgstr "Ce module a été désactivé par un administrateur."
+
+#~ msgid "devcp_summary_header_disabled"
+#~ msgstr "Désactivé"
+
+#~ msgid "devcp_summary_header_trusted"
+#~ msgstr "De confiance"
+
+#~ msgid "devcp_summary_noaddons_submit_one"
+#~ msgstr "Vous n'avez pas de modules. Cliquez %s pour en soumettre un."
+
+#~ msgid "devcp_summary_noaddons_submit_one_link"
+#~ msgstr "ici"
+
+#~ msgid "devcp_theme_upload_preview"
+#~ msgstr "Assurez-vous d'%s de votre thème."
+
+#~ msgid "devcp_theme_upload_preview_link"
+#~ msgstr "envoyer une prévisualisation"
+
+#~ msgid "devcp_version_edit_pagetitle"
+#~ msgstr "Éditer la version"
+
+#~ msgid "devcp_version_updated_successfully"
+#~ msgstr "Version mise à jour avec succès."
+
+#~ msgid "editors_submissiontype_new"
+#~ msgstr "Nouveau"
+
+#~ msgid "editors_submissiontype_updated"
+#~ msgstr "Mis à jour"
+
+#, fuzzy
+#~ msgid "editors_th_addon_age"
+#~ msgstr "Addon Age"
+
+#~ msgid "editors_th_addontypes"
+#~ msgstr "Types de modules"
+
+#~ msgid "editors_th_age"
+#~ msgstr "Âge"
+
+#~ msgid "editors_th_applications"
+#~ msgstr "Applications"
+
+#~ msgid "editors_th_platforms"
+#~ msgstr "Plateformes"
+
+#~ msgid "editors_th_submissiontypes"
+#~ msgstr "Types de soumissions"
+
+#~ msgid "error_notice"
+#~ msgstr "Avertissement"
+
+#~ msgid "forum_save"
+#~ msgstr "Enregistrer"
+
+#~ msgid "home"
+#~ msgstr "accueil"
+
+#~ msgid "nav_category_plugins"
+#~ msgstr "Plugins"
+
+#~ msgid "page_title_experimental_addons"
+#~ msgstr "Modules expérimentaux"
+
+#~ msgid "pages_experimental_addons_backbutton"
+#~ msgstr "Retour à la page précédente"
+
+#~ msgid "pagination_page_number_title"
+#~ msgstr "Ceci est la page %1$s sur %2$s"
+
+#~ msgid "search_matching_addons_number"
+#~ msgid_plural "search_matching_addons_number"
+#~ msgstr[0] "%s module correspondant"
+#~ msgstr[1] "%s modules correspondants"
+
+#~ msgid "statistics_rss_icon_title"
+#~ msgstr "Flux RSS du résumé des données"
diff --git a/site/app/locale/fr/images/sandbox-review.png b/site/app/locale/fr/images/sandbox-review.png
new file mode 100644
index 0000000..dd6a4d0
--- /dev/null
+++ b/site/app/locale/fr/images/sandbox-review.png
Binary files differ
diff --git a/site/app/locale/fr/pages/error404.thtml b/site/app/locale/fr/pages/error404.thtml
new file mode 100644
index 0000000..afd79ef
--- /dev/null
+++ b/site/app/locale/fr/pages/error404.thtml
@@ -0,0 +1,16 @@
+<h1>Nous somme désolés mais il nous a été impossible de trouver ce que vous cherchiez.</h1>
+
+<p>La page ou le fichier que vous avez demandé n'a pas été trouvée sur notre site. Il est possible que vous ayez cliqué sur un lien obsolète ou fait une faute de frappe en tapant l'adresse.</p>
+
+<ul>
+<li>Si vous avez tapé directement l'adresse, vérifiez que vous celle-ci est correcte.</li>
+<li>Si vous avez suivi un lien mort, merci d'en informer notre <a href="mailto:webmaster@mozilla.com" title="Page introuvable sur mozilla.com">webmaster@mozilla.com</a>. Indiquez-nous la page d'où vous veniez, ce que vous recherchiez et nous ferons de notre mieux pour réparer ce lien.</li>
+</ul>
+
+<p>Autrement, vous pouvez aussi vous rendre sur l'une des pages les plus populaires de notre site.</p>
+
+<ul>
+<li>Êtes-vous intéressé(e) par une <a href="%1$s">liste de modules complémentaires populaires&nbsp;</a>?</li>
+<li>Voulez-vous <a href="%2$s">rechercher des modules</a>&nbsp;? Vous pouvez vous rendre sur la <a href="%2$s">page de recherche</a> ou bien utiliser le champ de recherche ci-dessus.</li>
+<li>Si vous le préférez, vous pouvez aussi revenir <a href="%3$s">à la page d'accueil des modules complémentaires</a>.</li>
+</ul>
diff --git a/site/app/locale/fr/pages/nomination.thtml b/site/app/locale/fr/pages/nomination.thtml
new file mode 100644
index 0000000..cdb351d
--- /dev/null
+++ b/site/app/locale/fr/pages/nomination.thtml
@@ -0,0 +1,9 @@
+<p>Un module actuellement dans le bac à sable peut passer sur la zone publique, devenant ainsi disponible pour l'ensemble des utilisateurs, lorsqu'il a été révisé par un éditeur. Pour accélérer ce processus, veuillez noter les points suivants&nbsp;:</p>
+<ul>
+ <li>Les images de prévisualisations sont obligatoires pour les thèmes et sont chaudement recommandées pour les autres types de modules.</li>
+ <li>Le module doit avoir passé assez de temps dans le bac à sable pour accumuler les critiques et commentaires des utilisateurs.</li>
+ <li>Les modules de la zone publiques ont une exigence de qualité plus élevée que ceux de la zone de bac à sable t doivent clairement améliorer l'expérience utilisateur</li>
+ <li>La liste complète des critères de sélection est disponible dans la <a href="%s">politique des modules complémentaires</a></li>
+</ul>
+<p>Si votre module répond aux critères de sélection ci-dessus, vous pouvez le proposer en complétant le champ ci-dessous. Vous serez averti par courriel du statut de votre nomination.</p>
+ <p>Afin de procéder à la nomination de votre module, veuillez décrire le processus de tests qu'il a subi (en dehors du fait qu'il ne comporte pas d'erreurs et d'avertissements) et en quoi ce module est utile au web et à l'internet en général. Vous pouvez aussi inclure des liens vers des critiques externes de votre module.</p>
diff --git a/site/app/locale/fr/pages/sandbox.thtml b/site/app/locale/fr/pages/sandbox.thtml
new file mode 100644
index 0000000..f18454e
--- /dev/null
+++ b/site/app/locale/fr/pages/sandbox.thtml
@@ -0,0 +1,13 @@
+<h1>Système de revue du bac à sable</h1>
+<h2>Qu'est-ce que le bac à sable&nbsp;?</h2>
+<p>Le "bac à sable" est une zone de test des modules complémentaires destinée aux utilisateurs avancés avant que ces modules ne soient évalués pour le grand public. Si vous désirez accéder au bac à sable, vous devez activer cette option dans les paramètres de votre compte. La plus grande vigilance est nécessaire lorsque vous décidez d'installer des modules encore dans le bac à sable car ces modules n'ont pas encore été testés par un éditeur et sont donc potentiellement nocifs pour votre ordinateur.</p>
+
+<h2>Comment faire passer mon module du bac à sable à la zone publique&nbsp;?</h2>
+<!-- To localize the flowchart image, see http://wiki.mozilla.org/Update:Remora_Sandbox_Flowchart -->
+<div style="text-align: center;">%s</div>
+<ol>
+ <li><b>Proposez votre module depuis le Panneau de Contrôle du Développeur.</b> Votre proposition apparaît immédiatement dans la zone "bac à sable" de Mozilla Add-ons, où des utilisateurs expérimentés testeront le module et donneront leur opinion à son sujet. Si vous désirez visualiser le bac à sable, vous devez activer cette option dans les paramètres de votre compte.</li>
+ <li><b>Proposer votre module pour intégration à la partie publique.</b> Dans le Panneau de Contrôle du Développeur vous trouverez un lien pour proposer votre module pour la zone publique. Une fois proposé, votre module apparaîtra dans la file des modules en attente d'évaluation par un éditeur.</li>
+ <li><b>Un éditeur évalue votre module.</b> Un éditeur de Mozilla Add-ons installera votre module et testera son bon fonctionnement. Cet éditeur prendra aussi en compte les critiques fournies par les testeurs du bac à sable.</li>
+ <li><b>Votre module est promu à la zone publique ou reléguée au bac à sable.</b> L'éditeur déplace votre module dans la zone publique ou bien la laissera dans le bac à sable. S'il est retenu dans le bac à sable, vous pouvez le proposer de nouveau une fois que les modifications suggérées par l'éditeur dans les commentaires auront été appliquées. Si votre module est promu à la zone publique, les prochaines versions du module apparaîtront dans le bac à sable jusqu'à ce qu'elles aient été évaluées par un éditeur et promues à la zone publique. Lorsqu'un module est public, il est inutile de le proposer de nouveau, les versions futures seront automatiquement déplacées dans la file d'attente pour évaluation.</li>
+</ol>
diff --git a/site/app/locale/fr/pages/submission_help.thtml b/site/app/locale/fr/pages/submission_help.thtml
new file mode 100644
index 0000000..f82bd44
--- /dev/null
+++ b/site/app/locale/fr/pages/submission_help.thtml
@@ -0,0 +1,35 @@
+<h1>Aide à l'envoi de modules</h1>
+Les champs obligatoires sont en <b>gras</b>. Les champs optionnels sont en <i>italique</i>.
+<h2 id="step1">Étape 1&nbsp;: envoi</h2>
+<ul class="submissionHelp">
+ <li><span class="required">Type de module</span> - Par défaut, le type de module sera déterminé automatiquement par une analyse du fichier envoyé. Vous ne devriez donc pas avoir à modifier ce champ.</li>
+ <li><span class="required">Fichier du module</span> - Paquet d'installation de votre module comportant un fichier install.rdf. Si le paquet n'est compatible qu'avec une plateforme spécifique, la sélection de cette plateforme permet d'envoyer plusieurs fichiers en une fois.</li>
+ <li><span class="optional">Fichier icône</span> - Le fichier icône est affiché à côté du nom du module sur sa page de présentation ainsi que dans la boîte de dialogue d'installation du module. Il sera automatiquement redimensionné à 32x32 pixels, en conservant le rapport de taille.</li>
+ <li><span class="required">Langue par défaut</span> - La langue (locale) par défaut d'un module est sa langue principale. Si la langue de l'utilisateur n'est pas disponible pour le module, la locale par défaut du module sera utilisée.</li>
+ <li><span class="optional">Ne pas vérifier les informations concernant ce module</span> - Si vous mettez à jour un module déjà existant, ce champ sera affiché. Cocher cette case vous fera passer à l'étape 3 où vous pourrez enregistrer les informations spécifiques à cette version.</li>
+</ul>
+
+<h2 id="step2">Étape 2&nbsp;: détails du module</h2>
+<ul class="submissionHelp">
+ <li><span class="required">Nom</span> - Nome du module dans la locale par défaut.</li>
+ <li><span class="required">Auteurs</span> - Tous les utilisateurs pouvant modifier la fiche de ce module et qui seront listés comme auteurs.</li>
+ <li><span class="required">Catégories</span> - Catégories correspondant à ce module.</li>
+ <li><span class="optional">Page web</span> - Site web du module dans la locale par défaut.</li>
+ <li><span class="required">Résumé</span> - Un bref résumé desctriptif du module dans la locale par défaut. Ce champ a une taille maximale de 250 caractères et apparaîtra sur la page de présentation du module ainsi que dans les résultats de recherche et la navigation interne.</li>
+ <li><span class="required">Description</span> - Une description du module dans la locale par défaut. Ceci apparaîtra sur la page de présentation du module en dessous du résumé.</li>
+ <li><span class="optional">CLUF</span> - Le Contrat de Licence Utilisateur Final que les utilisateurs devront accepter avant le téléchargement, exprimé dans la locale par défaut.</li>
+ <li><span class="optional">Politique de vie privée</span> - La politique de respect de la vie privée du module, exprimée dans la locale par défaut. Les politiques de respect de la vie privée expliquent ce qui est fait des informations personnellles de l'utilisateur et apparaîtra comme un lien à côté du bouton d'installation sur la page de présentation du module. Des informations supplémentaires concernant ce qui devrait être inclus dans la politique de respect de la vie privée et si votre module devrait en fournir une sont disponibles dans la <a href="%s">politique des modules complémentaires</a>.</li>
+ <li><span class="optional">Permettre aux utilisateurs de voir les fichiers source en ligne</span> - Cocher cette case permettra aux utilisateurs de naviguer dans le code source de votre module en ligne.</li>
+ <li><span class="optional">Ceci est une pré-version</span> - Cocher cette case indiquera que ce module est une pré-version ou une version "bêta". Les pré-versions de modules restent dans la zone de "bac à sable" et ne peuvent être promues pour la zone publique jusqu'à ce que cette case ait été décochée.</li>
+ <li><span class="optional">Ceci est un module dédié à un site web</span> - Cocher cette case indiquera que ce module est écrit pour un site web spécifique, par exmple un module changeant l'apparence d'un site ou affichant des informations tirées d'un site web précis. Ce champ est utile aux éditeurs et pourrait dans l'avenir être utilisé pour filtrer des recherche.</li>
+ <li><span class="optional">Ce module a besoin d'un logiciel externe</span> - Cocher cette case indiquera que le module a besoin d'utiliser un logiciel externe. Ce champ est utile aux éditeurs et pourrait dans l'avenir être utilisé pour filtrer des recherche.</li>
+</ul>
+
+<h2 id="step3">Étape 3&nbsp;: détails de la version</h2>
+<ul class="submissionHelp">
+ <li><span class="required optional">Notes de version</span> - Un résumé ou une liste des changements apportés par cette version. Ce champ est optionnel pour les nouveaux modules mais nécessaires pour les mises à jour de modules.</li>
+ <li><span class="optional">Notes au réviseur</span> - Ce champ est utilisé pour communiquer des inbformations aux éditeurs qui réviseront votre module. Les informations telles que les comptes de test pour un webservice et autres informations spécifiques devraient être indiquées ici.</li>
+</ul>
+
+<h2 id="step4">Étape 4&nbsp;: Localisation</h2>
+Emplacement dédié à la traduction des champs du module pour toutes les langues supportées. Cliquez sur une langue pour taper les traductions.
diff --git a/site/app/locale/fy_NL/LC_MESSAGES/messages.mo b/site/app/locale/fy_NL/LC_MESSAGES/messages.mo
new file mode 100644
index 0000000..49ec6ae
--- /dev/null
+++ b/site/app/locale/fy_NL/LC_MESSAGES/messages.mo
Binary files differ
diff --git a/site/app/locale/fy_NL/LC_MESSAGES/messages.po b/site/app/locale/fy_NL/LC_MESSAGES/messages.po
new file mode 100644
index 0000000..487446a
--- /dev/null
+++ b/site/app/locale/fy_NL/LC_MESSAGES/messages.po
@@ -0,0 +1,9576 @@
+# Remora Preliminary Language File
+# Copyright (C) 2006 Mozilla Corporation
+# This file is distributed under the same license as the REMORA package.
+# Wil Clouser <clouserw@mozilla.com>, 2006.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: REMORA 0.1\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2009-01-16 11:45-0800\n"
+"PO-Revision-Date: 2008-09-22 13:20-0700\n"
+"Last-Translator: Wil Clouser <wclouser@mozilla.com>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=n != 1;\n"
+"X-Generator: Pootle 1.1.0\n"
+
+#: views/addons/policy.thtml:98
+#, fuzzy
+msgid "a_cancel_installation"
+msgstr "Cancel Installation"
+
+#. This is the text that appears on buttons to download add-ons.
+#. %$1s is an optional string that only appears if the add-on is only available for
+#. a certain platform. Examples: (Windows) or (Linux)
+#. Note that the parentheses are included in the string. :(
+#: views/elements/amo2009/install.thtml:126
+#: views/elements/amo2009/install.thtml:227
+#: views/elements/amo2009/install.thtml:257
+#: views/elements/amo2009/install.thtml:300
+#: views/elements/amo2009/install.thtml:312 views/elements/install.thtml:73
+#: views/elements/install.thtml:181 views/elements/install.thtml:205
+#: views/elements/install.thtml:248 views/elements/install.thtml:260
+#: views/addons/plugins.thtml:66 views/addons/plugins.thtml:76
+#: views/addons/plugins.thtml:86 views/addons/plugins.thtml:96
+#: views/addons/plugins.thtml:119
+#, fuzzy, php-format
+msgid "a_download"
+msgstr "Download Now %s"
+
+#: views/addons/policy.thtml:72
+#, fuzzy
+msgid "a_eula_download"
+msgstr "Accept and Download"
+
+#: views/addons/policy.thtml:74
+#, fuzzy
+msgid "a_eula_install"
+msgstr "Accept and Install"
+
+#: views/elements/header.thtml:76 views/elements/header.thtml:82
+#: views/api/api_addon.thtml:55 views/api/collections_feed.thtml:75
+#: views/sharing_api/addon.thtml:64
+#, fuzzy
+msgid "a_header_public"
+msgstr "Public"
+
+#: views/elements/header.thtml:58 views/elements/header.thtml:75
+#: views/elements/header.thtml:80 views/api/api_addon.thtml:57
+#: views/api/collections_feed.thtml:77 views/sharing_api/addon.thtml:66
+#, fuzzy
+msgid "a_header_sandbox"
+msgstr "Sandbox"
+
+#. %s is a date in the _('date') format
+#: views/elements/amo2009/homepage_addon.thtml:115
+#: views/elements/addon_listitem.thtml:122 views/elements/feature.thtml:106
+#: views/addons/display.thtml:104 views/addons/browse_thumbs.thtml:73
+#, fuzzy
+msgid "addon_detail_last_updated"
+msgstr "Updated %s"
+
+#. %s is the version of the add-on. Example: 3.2a1
+#: views/elements/amo2009/addon_version_detail.thtml:51
+#: views/elements/addon_version_detail.thtml:51
+#, fuzzy, php-format
+msgid "addon_display_header_version"
+msgstr "Version %s"
+
+#: views/addons/browse_thumbs.thtml:80
+#, fuzzy
+msgid "addon_downloads"
+msgstr "downloads"
+
+#: views/addons/display.thtml:147
+#, fuzzy
+msgid "addon_downloads_total"
+msgstr "total downloads"
+
+#: views/elements/amo2009/homepage_addon.thtml:106
+#: views/elements/addon_listitem.thtml:115 views/elements/feature.thtml:101
+#: views/addons/category_landing.thtml:157 views/addons/display.thtml:146
+#: views/addons/browse_thumbs.thtml:80
+#, fuzzy
+msgid "addon_downloads_weekly"
+msgstr "weekly downloads"
+
+# %1 is the add-on count, %2 the category name
+#. %1 is the add-on count, %2 the category name
+#: views/addons/browse_thumbs.thtml:104 views/addons/browse.thtml:60
+#, fuzzy, php-format
+msgid "addon_list_category_totalcount"
+msgid_plural "addon_list_category_totalcount"
+msgstr[0] "%1$s add-on"
+msgstr[1] "%1$s add-ons"
+
+#: views/elements/amo2009/addon_list_options.thtml:103
+#: views/elements/pagination.thtml:67
+#: views/elements/addon_list_options.thtml:94
+#, fuzzy
+msgid "addon_list_perpage"
+msgstr "per page"
+
+#: views/elements/amo2009/addon_list_options.thtml:84
+#: views/elements/addon_list_options.thtml:98
+#, fuzzy
+msgid "addon_list_sortby"
+msgstr "Sort by:"
+
+#: views/helpers/addons_html.php:568 views/elements/amo2009/install.thtml:321
+#: views/elements/feature.thtml:89
+#, fuzzy
+msgid "addon_listitem_flag_experimental"
+msgstr "experimental"
+
+#: views/helpers/addons_html.php:570
+#, fuzzy
+msgid "addon_listitem_flag_recommended"
+msgstr "recommended"
+
+# %1 is the addon name, %2 is the platform
+#. %1 is the add-on name, %2 is the platform
+#: views/pages/js_constants.js.thtml:66
+#, fuzzy
+msgid "addon_not_available_for_platform"
+msgstr "%1$s is not available for %2$s."
+
+# %1 is the addon name
+#. %1 is the add-on name
+#: views/addons/policy.thtml:101 views/addons/previews.thtml:60
+#: views/addons/versions.thtml:130 views/reviews/flag.thtml:61
+#: views/reviews/add.thtml:114 views/reviews/display.thtml:216
+#: views/reviews/review_added.thtml:57
+#, fuzzy, php-format
+msgid "addon_review_a_back_to_addon_x"
+msgstr "Back to %1$s..."
+
+# %1 is the addon name
+#. %1 is the add-on name
+#: views/reviews/flag.thtml:60 views/reviews/add.thtml:113
+#: views/reviews/review_added.thtml:56
+#, fuzzy, php-format
+msgid "addon_review_a_back_to_reviews"
+msgstr "Back to the reviews..."
+
+#: views/reviews/add.thtml:85
+#, fuzzy
+msgid "addon_review_add_rating_field"
+msgstr "Rating:"
+
+#: views/reviews/add.thtml:102
+#, fuzzy
+msgid "addon_review_add_review_field"
+msgstr "Review:"
+
+#: views/reviews/add.thtml:107
+#, fuzzy
+msgid "addon_review_add_submit"
+msgstr "Submit your review"
+
+#. %s is the name of the add-on
+#: views/reviews/add.thtml:51
+#, fuzzy, php-format
+msgid "addon_review_add_title"
+msgstr "Add a review for %s"
+
+#: views/reviews/add.thtml:78
+#, fuzzy
+msgid "addon_review_add_title_field"
+msgstr "Title/Summary:"
+
+#: views/reviews/display.thtml:77 views/reviews/display.thtml:161
+#, fuzzy
+msgid "addon_review_admin_delete"
+msgstr "Delete"
+
+#: views/reviews/display.thtml:76
+#, fuzzy
+msgid "addon_review_author_reply_link"
+msgstr "Reply"
+
+#: views/reviews/delete.thtml:62
+#, fuzzy
+msgid "addon_review_confirm_delete"
+msgstr "Are you sure you wish to delete this review?"
+
+#: views/reviews/delete.thtml:63
+#, fuzzy
+msgid "addon_review_confirm_no"
+msgstr "No"
+
+#: views/reviews/delete.thtml:64
+#, fuzzy
+msgid "addon_review_confirm_yes"
+msgstr "Yes"
+
+#: views/reviews/delete.thtml:48
+#, fuzzy
+msgid "addon_review_delete_header"
+msgstr "Delete Review"
+
+#: controllers/reviews_controller.php:449
+#, fuzzy
+msgid "addon_review_deleted_successfully"
+msgstr "Review deleted successfully."
+
+#. %s is the name of the add-on
+#: views/reviews/add.thtml:51
+#, fuzzy, php-format
+msgid "addon_review_edit_title"
+msgstr "Edit Review for %s"
+
+# %1 is the count of characters entered as notes for the review flag reason.
+#. %1 is the count of characters entered as notes for the review flag reason.
+#: controllers/reviews_controller.php:539
+#, fuzzy
+msgid "addon_review_flag_error_other_length"
+msgstr ""
+"Problem flagging review: Notes for flagged reviews are limited to between 10 "
+"and 100 characters; your character length was %1$s."
+
+# Removing an extra comma
+#. Removing an extra comma
+#: views/reviews/review_added.thtml:53
+#, fuzzy
+msgid "addon_review_in_moderation"
+msgstr ""
+"Please note: Before your review shows up on the public site it will be "
+"moderated by an editor."
+
+#: views/reviews/add.thtml:57
+#, fuzzy
+msgid "addon_review_in_reply_to"
+msgstr "Developer reply to:"
+
+# %1 is the review count, %2 is the nickname or full name of the user.
+#. %1 is the review count, %2 is the nickname or full name of the user.
+#: views/reviews/display.thtml:131
+#, fuzzy, php-format
+msgid "addon_review_others_by_user"
+msgid_plural "addon_review_others_by_user"
+msgstr[0] "See %1$s previous review submitted by %2$s for this add-on."
+msgstr[1] "See %1$s previous reviews submitted by %2$s for this add-on."
+
+# %1 is the addon name
+#. %1 is the add-on name
+#: controllers/reviews_controller.php:201
+#: controllers/reviews_controller.php:250
+#: controllers/reviews_controller.php:345
+#: controllers/reviews_controller.php:424
+#, fuzzy, php-format
+msgid "addon_review_pagetitle"
+msgstr "Reviews for %s"
+
+# %1 is the user, %2 is the (localized) date
+#. %1 is the user, %2 is the (localized) date
+#: views/reviews/display.thtml:160
+#, fuzzy, php-format
+msgid "addon_review_reply_on_x_by_y"
+msgstr "Reply by %1$s on %2$s"
+
+#: views/reviews/display.thtml:157
+#, fuzzy
+msgid "addon_review_reply_prefix"
+msgstr "Developer Reply:"
+
+#: views/reviews/review_added.thtml:51
+#, fuzzy
+msgid "addon_review_saved_successfully"
+msgstr "Your review was saved successfully. Thanks!"
+
+#: views/addons/display.thtml:354 views/reviews/display.thtml:72
+#, fuzzy
+msgid "addon_reviewed_by_u_on_d"
+msgstr "by %1$s on %2$s"
+
+# %1 is the user, %2 is the (localized) date, %3 is the rating
+#. %1 is the user, %2 is the (localized) date, %3 is the rating
+#: views/editors/reviews_queue.thtml:57 views/editors/reviews_queue.thtml:68
+#: views/reviews/add.thtml:63 views/reviews/delete.thtml:54
+#, fuzzy, php-format
+msgid "addon_reviewed_on_x_rated_y"
+msgstr "by %1$s on %2$s (rated %3$s)"
+
+#: views/elements/amo2009/addon_version_detail.thtml:52
+#: views/elements/addon_version_detail.thtml:52
+#, fuzzy
+msgid "addon_version_permalink"
+msgstr "Permanent link to this version"
+
+# %1 is the current Application name (e.g. Firefox)
+# %2 is the Application's version number
+#. %1 is the current Application name (e.g. Firefox)
+#. %2 is the Application's version number
+#: views/addons/versions.thtml:140
+#, fuzzy
+msgid "addon_versions_getlatestversion"
+msgstr "The most recent version compatible with %1$s %2$s"
+
+#: views/addons/display.thtml:447
+#, fuzzy
+msgid "addons_author_addons_submit"
+msgstr "Go"
+
+#: views/elements/amo2009/homepage_addon.thtml:100
+#: views/elements/feature.thtml:95
+#, fuzzy
+msgid "addons_author_tooltip"
+msgstr "View Author's Profile"
+
+# %1 is the name of the Application (eg. Firefox)
+#. %1 is the name of the Application (eg. Firefox)
+#: controllers/addons_controller.php:1296
+#, fuzzy
+msgid "addons_browse_all_themes_title"
+msgstr "Browse all Themes :: %1$s Add-ons"
+
+#. %s is the name of the category
+#: controllers/addons_controller.php:1016
+#, fuzzy, php-format
+msgid "addons_browse_browse_category"
+msgstr "Browse %s"
+
+# %1 is the name of the theme category (eg. Modern)
+# %2 is the name of the Application (eg. Firefox)
+#. %1 is the name of the theme category (eg. Modern)
+#. %2 is the name of the Application (eg. Firefox)
+#: controllers/addons_controller.php:664
+#, fuzzy
+msgid "addons_browse_categories_header_theme"
+msgstr "Browse %1$s Themes :: %2$s Add-ons"
+
+#: views/addons/display.thtml:249
+#, fuzzy
+msgid "addons_display_a_license_what"
+msgstr "What's this?"
+
+#: views/reviews/display.thtml:222
+#, fuzzy
+msgid "addons_display_add_review"
+msgstr "Add a review"
+
+#: views/addons/display.thtml:294
+#, fuzzy
+msgid "addons_display_advanced_details"
+msgstr "Advanced Details"
+
+#: views/addons/display.thtml:98
+#, fuzzy
+msgid "addons_display_categories"
+msgstr "Categories"
+
+#: views/addons/display.thtml:482
+#, fuzzy
+msgid "addons_display_collection_add"
+msgstr "Add to a collection:"
+
+#: views/addons/display.thtml:491
+#, fuzzy
+msgid "addons_display_collection_add_new"
+msgstr "New Collection..."
+
+#: views/addons/display.thtml:487
+#, fuzzy
+msgid "addons_display_collection_add_select_one"
+msgstr "Select a collection..."
+
+#: views/addons/display.thtml:493
+#, fuzzy
+msgid "addons_display_collection_add_submit"
+msgstr "Publish"
+
+#. %1$s is the add-on name
+#. %2$s is the collection name, linked to the collection's page
+#: views/pages/js_constants.js.thtml:103 views/addons/display.thtml:61
+#, fuzzy
+msgid "addons_display_collection_publish_success"
+msgstr "%1$s has been added to the %2$s collection."
+
+#: views/addons/display.thtml:483
+#, fuzzy
+msgid "addons_display_collection_whatsthis"
+msgstr "What's this?"
+
+#. %1$s is a number
+#: views/addons/display.thtml:473
+#, fuzzy
+msgid "addons_display_collections_more"
+msgid_plural "addons_display_collections_more"
+msgstr[0] "and %1$s more collection"
+msgstr[1] "and %1$s more collections"
+
+#: views/addons/display.thtml:403
+#, fuzzy
+msgid "addons_display_detailed_review"
+msgstr "detailed review"
+
+#: views/reviews/add.thtml:89 views/reviews/add.thtml:90
+#, fuzzy
+msgid "addons_display_dont_like_it"
+msgstr "Don't like it"
+
+#: views/reviews/display.thtml:220
+#, fuzzy
+msgid "addons_display_edit_review"
+msgstr "Edit your review"
+
+#: views/addons/display.thtml:132
+#, fuzzy
+msgid "addons_display_has_privacy"
+msgstr "This add-on has a privacy policy."
+
+#: views/reviews/add.thtml:87 views/reviews/add.thtml:88
+#, fuzzy
+msgid "addons_display_hate_it"
+msgstr "Hate it"
+
+#: views/addons/display.thtml:462
+#, fuzzy
+msgid "addons_display_header_collections"
+msgstr "Related Collections"
+
+#: views/addons/display.thtml:297
+#, fuzzy
+msgid "addons_display_header_developer_comments"
+msgstr "Developer Comments"
+
+#: views/addons/display.thtml:230
+#, fuzzy
+msgid "addons_display_header_homepage"
+msgstr "Homepage"
+
+#: views/addons/display.thtml:247 views/addons/versions.thtml:110
+#, fuzzy
+msgid "addons_display_header_license"
+msgstr "Source Code License"
+
+#: views/addons/display.thtml:337
+#, fuzzy
+msgid "addons_display_header_reviews"
+msgstr "Reviews"
+
+#: views/addons/display.thtml:261
+#, fuzzy
+msgid "addons_display_header_support"
+msgstr "Support"
+
+#: views/reviews/add.thtml:91 views/reviews/add.thtml:92
+#, fuzzy
+msgid "addons_display_like_it"
+msgstr "Like it"
+
+#: views/addons/display.thtml:210
+#, fuzzy
+msgid "addons_display_long_description"
+msgstr "Long Description"
+
+#: views/reviews/add.thtml:95 views/reviews/add.thtml:96
+#, fuzzy
+msgid "addons_display_love_it"
+msgstr "Love it"
+
+#: views/addons/display.thtml:178
+#, fuzzy
+msgid "addons_display_more_images"
+msgstr "More Images"
+
+#: views/addons/display.thtml:465
+#, fuzzy
+msgid "addons_display_nocollections"
+msgstr "This add-on is not yet in any collections."
+
+# %1$s is either an author's name or a comma separated list of authors. Using
+# the list doesn't make sense in the English plural form so we ignore the
+# variable.
+#. %1$s is either an author's name or a comma separated list of authors. Using
+#. the list doesn't make sense in the English plural form so we ignore the
+#. variable.
+#: views/addons/display.thtml:436
+#, fuzzy
+msgid "addons_display_other_addons_by"
+msgid_plural "addons_display_other_addons_by"
+msgstr[0] "Other add-ons by %1$s"
+msgstr[1] "Other add-ons by these authors"
+
+#. %s is the name of the add-on and the add-on section. Example:
+#. Some Add-on :: Firefox Add-ons
+#. This should not be concatenated in the code and should be fixed.
+#: controllers/addons_controller.php:141 controllers/addons_controller.php:280
+#: controllers/addons_controller.php:1442
+#, fuzzy, php-format
+msgid "addons_display_pagetitle"
+msgstr "%s"
+
+#. %s is an email address
+#: views/addons/display.thtml:286
+#, fuzzy, php-format
+msgid "addons_display_paragraph_supportinfoemail"
+msgstr "Support for this add-on is provided by the developer at %s"
+
+#. %$1s is a URL
+#. %$2s is an email address
+#: views/addons/display.thtml:269
+#, fuzzy, php-format
+msgid "addons_display_paragraph_supportinfoemailurl"
+msgstr ""
+"Support for this add-on is provided by the developer at %s or by sending an "
+"e-mail to %s"
+
+#. %s is a URL
+#: views/addons/display.thtml:278
+#, fuzzy, php-format
+msgid "addons_display_paragraph_supportinfourl"
+msgstr "Support for this add-on is provided by the developer at %s"
+
+#: views/addons/display.thtml:383
+#, fuzzy
+msgid "addons_display_rate_it"
+msgstr "Rate It"
+
+#: views/reviews/add.thtml:93 views/reviews/add.thtml:94
+#, fuzzy
+msgid "addons_display_really_like_it"
+msgstr "Really like it"
+
+#: views/addons/display.thtml:410
+#, fuzzy
+msgid "addons_display_review_etiquette"
+msgstr ""
+"Please do not post bug reports in reviews. We do not make your email address "
+"available to add-on developers and they may need to contact you to help "
+"resolve your issue."
+
+# %1 is the review guidelines link
+#. %1 is the review guidelines link
+#: views/addons/display.thtml:417
+#, fuzzy
+msgid "addons_display_review_guidelines_link"
+msgstr "<a href=\"%s\">Review Guidelines</a>"
+
+# %1 is the support section link
+#. %1 is the support section link
+#: views/addons/display.thtml:414
+#, fuzzy
+msgid "addons_display_review_see_support"
+msgstr ""
+"See the <a href=\"%1$s\">support section</a> to find out where to get "
+"assistance for this add-on."
+
+#: views/addons/display.thtml:404
+#, fuzzy
+msgid "addons_display_review_submit"
+msgstr "Save"
+
+#: views/addons/display.thtml:430
+#, fuzzy, php-format
+msgid "addons_display_see_all_addons"
+msgstr "See All %1$s Add-ons"
+
+# %1 is the number of reviews
+#. %1 is the number of reviews
+#: views/addons/display.thtml:364
+#, fuzzy, php-format
+msgid "addons_display_see_all_reviews"
+msgstr "See all reviews (%1$s)"
+
+#: views/addons/display.thtml:219
+#, fuzzy
+msgid "addons_display_see_all_versions"
+msgstr "See All Versions"
+
+#: views/addons/display.thtml:321 views/addons/versions.thtml:117
+#, fuzzy
+msgid "addons_display_view_source"
+msgstr "View the source"
+
+#: views/addons/display.thtml:324
+#, fuzzy
+msgid "addons_display_view_stats"
+msgstr "View statistics"
+
+#: views/addons/display.thtml:376
+#, fuzzy
+msgid "addons_display_what_do_you_think"
+msgstr "What do you think?"
+
+#: views/elements/app_compatibility.thtml:49
+#, fuzzy
+msgid "addons_display_workswith"
+msgstr "Works with:"
+
+#: views/addons/home.thtml:112
+#, fuzzy
+msgid "addons_home_browse_new"
+msgstr "Just Added"
+
+#: views/addons/home.thtml:110
+#, fuzzy
+msgid "addons_home_browse_popular"
+msgstr "Popular"
+
+#: views/addons/home.thtml:108
+#, fuzzy
+msgid "addons_home_browse_recommended"
+msgstr "Recommended"
+
+#: views/addons/home.thtml:127 views/addons/home.thtml:134
+#: views/addons/home.thtml:141 views/addons/home.thtml:148
+#, fuzzy
+msgid "addons_home_browse_subscribe"
+msgstr "Subscribe"
+
+#: views/addons/home.thtml:101
+#, fuzzy
+msgid "addons_home_browse_title"
+msgstr "Browse Add-ons"
+
+#: views/addons/home.thtml:114
+#, fuzzy
+msgid "addons_home_browse_updated"
+msgstr "Updated"
+
+#: views/elements/amo2009/homepage_addon.thtml:100
+#: views/elements/addon_discussionheader.thtml:83
+#: views/elements/addon_listitem.thtml:109 views/elements/feature.thtml:95
+#: views/addons/category_landing.thtml:66 views/addons/policy.thtml:57
+#: views/addons/display.thtml:70 views/addons/home.thtml:178
+#, fuzzy
+msgid "addons_home_by"
+msgstr "by"
+
+#: views/addons/home.thtml:169
+#, fuzzy
+msgid "addons_home_collection_popular_title"
+msgstr "Popular Collections"
+
+#: views/elements/amo2009/categories.thtml:69 views/addons/home.thtml:160
+#, fuzzy
+msgid "addons_home_collections"
+msgstr "Collections"
+
+#. %1$s is the count of addons in a collection
+#: views/elements/amo2009/collection_listing_item.thtml:51
+#: views/addons/home.thtml:185
+#, fuzzy
+msgid "addons_home_collections_addon_count"
+msgid_plural "addons_home_collections_addon_count"
+msgstr[0] "<strong>%1$s</strong> add-on"
+msgstr[1] "<strong>%1$s</strong> add-ons"
+
+#: views/addons/home.thtml:196
+#, fuzzy
+msgid "addons_home_collections_all"
+msgstr "View All Collections"
+
+#: views/addons/home.thtml:162
+#, fuzzy
+msgid "addons_home_collections_intro"
+msgstr ""
+"Collections are a way for you to categorize, mix, match and mingle add-ons. "
+"Subscribe to collections created by other users or create your own."
+
+#. %1$s is the count of subscribers for a collection
+#: views/elements/amo2009/collection_listing_item.thtml:58
+#: views/collections/detail.thtml:96 views/addons/home.thtml:189
+#, fuzzy
+msgid "addons_home_collections_subscribers"
+msgid_plural "addons_home_collections_subscribers"
+msgstr[0] "<strong>%1$s</strong> subscriber"
+msgstr[1] "<strong>%1$s</strong> subscribers"
+
+#: views/addons/searchengines.thtml:54 views/addons/themes_landing.thtml:49
+#, fuzzy
+msgid "addons_home_feature_head"
+msgstr "We Recommend"
+
+#: controllers/search_controller.php:218 controllers/addons_controller.php:176
+#: controllers/addons_controller.php:428 controllers/addons_controller.php:671
+#: controllers/addons_controller.php:871
+#: controllers/addons_controller.php:1103
+#: controllers/addons_controller.php:1242
+#: controllers/addons_controller.php:1298
+#, fuzzy, php-format
+msgid "addons_home_header_details"
+msgstr ""
+"Add-ons extend %1$s, letting you personalize your browsing experience. Take "
+"a look around and make %1$s your own."
+
+#. %1$s is the HTML collection name link.
+#: views/elements/amo2009/teaser_collections.thtml:107
+#, fuzzy
+msgid "addons_home_introduction_collection_link"
+msgstr "Like these? Find more add-ons in %1$s."
+
+#: views/elements/amo2009/teaser_collections.thtml:60
+#, fuzzy
+msgid "addons_home_introduction_extras"
+msgstr ""
+"<strong>Over 5000 free extras</strong> that let you customize and extend "
+"Firefox to meet your needs."
+
+#: views/elements/amo2009/teaser_collections.thtml:55
+#, fuzzy
+msgid "addons_home_introduction_header"
+msgstr "What are Add-ons?"
+
+#: views/elements/amo2009/teaser_collections.thtml:72
+#, fuzzy
+msgid "addons_home_introduction_install"
+msgstr ""
+"<strong>Easy to install</strong>, get notified when updates are available."
+
+#: views/elements/amo2009/teaser_collections.thtml:45
+#, fuzzy
+msgid "addons_home_introduction_name"
+msgstr "Introduction"
+
+#: views/elements/amo2009/teaser_collections.thtml:66
+#, fuzzy
+msgid "addons_home_introduction_themes"
+msgstr ""
+"Toolbars, themes and search providers that <strong>help you perform common "
+"tasks.</strong>"
+
+#: views/addons/home.thtml:161
+#, fuzzy
+msgid "addons_home_new_indicator"
+msgstr "NEW!"
+
+#: views/elements/app_chooser.thtml:48 views/layouts/amo2009.thtml:257
+#, fuzzy
+msgid "addons_home_other_applications"
+msgstr "Other Applications"
+
+#. %1$s is the application the user is browsing. Examples: Thunderbird, Firefox,
+#. Sunbird
+#: views/pages/collector_faq.thtml:49 views/pages/collector_firstrun.thtml:42
+#: views/pages/collector.thtml:46 views/pages/collector_features.thtml:54
+#: controllers/developers_controller.php:87
+#: controllers/compatibility_controller.php:72
+#: controllers/components/simple_acl.php:81 controllers/components/amo.php:607
+#: controllers/statistics_controller.php:60
+#: controllers/statistics_controller.php:240
+#: controllers/previews_controller.php:67 controllers/users_controller.php:90
+#: controllers/users_controller.php:223 controllers/users_controller.php:330
+#: controllers/users_controller.php:414 controllers/users_controller.php:708
+#: controllers/users_controller.php:723 controllers/reviews_controller.php:204
+#: controllers/reviews_controller.php:251
+#: controllers/reviews_controller.php:346
+#: controllers/reviews_controller.php:425
+#: controllers/search_controller.php:185 controllers/search_controller.php:297
+#: controllers/search_controller.php:301 controllers/addons_controller.php:147
+#: controllers/addons_controller.php:280 controllers/addons_controller.php:370
+#: controllers/addons_controller.php:667 controllers/addons_controller.php:874
+#: controllers/addons_controller.php:1019
+#: controllers/addons_controller.php:1034
+#: controllers/addons_controller.php:1101
+#: controllers/addons_controller.php:1121
+#: controllers/addons_controller.php:1240
+#: controllers/addons_controller.php:1357
+#: controllers/addons_controller.php:1364
+#: controllers/addons_controller.php:1442
+#: controllers/addons_controller.php:1477
+#: controllers/addons_controller.php:1538
+#: controllers/addons_controller.php:1543
+#: controllers/editors_controller.php:64 controllers/pages_controller.php:132
+#: controllers/groups_controller.php:65 controllers/groups_controller.php:71
+#: controllers/groups_controller.php:89 controllers/groups_controller.php:111
+#: controllers/collections_controller.php:57
+#: controllers/collections_controller.php:121
+#: controllers/collections_controller.php:205
+#: controllers/collections_controller.php:365
+#: controllers/collections_controller.php:404
+#: controllers/collections_controller.php:466
+#: controllers/collections_controller.php:538
+#: controllers/collections_controller.php:828
+#: controllers/localizers_controller.php:72
+#, fuzzy, php-format
+msgid "addons_home_pagetitle"
+msgstr "%1$s Add-ons"
+
+#. %1$s is the number of addons downloaded
+#: views/addons/home.thtml:57
+#, fuzzy, php-format
+msgid "addons_home_stats_downloaded"
+msgid_plural "addons_home_stats_downloaded"
+msgstr[0] "<strong>%1$s</strong> <span>add-on downloaded</span>"
+msgstr[1] "<strong>%1$s</strong> <span>add-ons downloaded</span>"
+
+#. %1$s is the number of addons in use
+#: views/addons/home.thtml:63
+#, fuzzy, php-format
+msgid "addons_home_stats_inuse"
+msgid_plural "addons_home_stats_inuse"
+msgstr[0] "<strong>%1$s</strong> <span>add-on in use</span>"
+msgstr[1] "<strong>%1$s</strong> <span>add-ons in use</span>"
+
+#: views/addons/home.thtml:136
+#, fuzzy
+msgid "addons_home_view_all_newest_title"
+msgstr "View all newly created add-ons"
+
+#: views/addons/home.thtml:129
+#, fuzzy
+msgid "addons_home_view_all_popular_title"
+msgstr "View all popular add-ons"
+
+#: views/addons/home.thtml:150
+#, fuzzy
+msgid "addons_home_view_all_recommended_title"
+msgstr "View all recommended add-ons"
+
+#: views/addons/home.thtml:143
+#, fuzzy
+msgid "addons_home_view_all_updated_title"
+msgstr "View all recently updated add-ons"
+
+#: views/elements/amo2009/install.thtml:334 views/elements/install.thtml:112
+#, fuzzy
+msgid "addons_install_in_sunbird"
+msgstr ""
+"<ol><li>Click the link below to save the file.</li><li>In Mozilla Sunbird, "
+"open Add-ons from the Tools menu.</li><li>Click the Install button, and "
+"locate/select the file you downloaded and click \"OK\".</li></ol>"
+
+#: views/elements/amo2009/install.thtml:333 views/elements/install.thtml:111
+#, fuzzy
+msgid "addons_install_in_sunbird_title"
+msgstr "How to Install in Sunbird"
+
+#: views/elements/amo2009/install.thtml:331 views/elements/install.thtml:106
+#, fuzzy
+msgid "addons_install_in_thunderbird"
+msgstr ""
+"<ol><li>Right-click the link below and choose \"Save Link As...\" to "
+"download and save the file to your hard disk.</li><li>In Mozilla "
+"Thunderbird, open Add-ons from the Tools menu.</li><li>Click the Install "
+"button, and locate/select the file you downloaded and click \"OK\".</li></ol>"
+
+#: views/elements/amo2009/install.thtml:330 views/elements/install.thtml:105
+#, fuzzy
+msgid "addons_install_in_thunderbird_title"
+msgstr "How to Install in Thunderbird"
+
+#: views/elements/amo2009/addon_list_options.thtml:108
+#: views/elements/addon_list_options.thtml:105
+#, fuzzy
+msgid "addons_options_show_experimental"
+msgstr "show experimental add-ons"
+
+#: views/elements/amo2009/addon_list_options.thtml:113
+#: views/elements/addon_list_options.thtml:109
+#, fuzzy
+msgid "addons_options_submit"
+msgstr "Go"
+
+#: views/addons/plugins.thtml:63 views/addons/plugins.thtml:73
+#: views/addons/plugins.thtml:83 views/addons/plugins.thtml:93
+#: views/addons/plugins.thtml:103 views/addons/plugins.thtml:116
+#: views/addons/plugins.thtml:126
+#, fuzzy
+msgid "addons_plugins_by"
+msgstr "By"
+
+#: views/addons/plugins.thtml:107
+#, fuzzy
+msgid "addons_plugins_for_linux"
+msgstr "for Linux"
+
+#: views/addons/plugins.thtml:108 views/addons/plugins.thtml:131
+#, fuzzy
+msgid "addons_plugins_for_macosx"
+msgstr "for Mac OS X"
+
+#: views/addons/plugins.thtml:106 views/addons/plugins.thtml:129
+#: views/addons/plugins.thtml:130
+#, fuzzy
+msgid "addons_plugins_for_windows"
+msgstr "for Windows"
+
+#. %1$s is a URL
+#: views/addons/plugins.thtml:139
+#, fuzzy, php-format
+msgid "addons_plugins_looking_for_more"
+msgstr ""
+"This page only lists some of the most common and most popular plugins. For "
+"more information about other plugins available for Mozilla-based Browsers, "
+"visit %1$s"
+
+#: views/addons/plugins.thtml:137
+#, fuzzy
+msgid "addons_plugins_looking_for_plugin"
+msgstr "Looking for a plugin not listed here?"
+
+#: views/addons/plugins.thtml:58
+#, fuzzy
+msgid "addons_plugins_main_description"
+msgstr ""
+"Plugins help your browser perform specific functions like viewing special "
+"graphic formats or playing multimedia files. Plugins are slightly different "
+"from extensions, which modify or add to existing functionality."
+
+#. %1$s is the application name. Example: Firefox, Thunderbird, Sunbird
+#: controllers/addons_controller.php:1122
+#, fuzzy, php-format
+msgid "addons_plugins_main_header"
+msgstr "Common Plugins for %1$s"
+
+#: controllers/components/amo.php:698 controllers/addons_controller.php:1121
+#, fuzzy
+msgid "addons_plugins_pagetitle"
+msgstr "Plugins"
+
+#: views/addons/plugins.thtml:68 views/addons/plugins.thtml:78
+#: views/addons/plugins.thtml:88 views/addons/plugins.thtml:98
+#: views/addons/plugins.thtml:110 views/addons/plugins.thtml:121
+#: views/addons/plugins.thtml:133
+#, fuzzy
+msgid "addons_plugins_support_documentation"
+msgstr "Support Documentation: "
+
+#. %s is the name of the add-on
+#: views/addons/policy.thtml:61
+#, fuzzy, php-format
+msgid "addons_policy_eula_require"
+msgstr ""
+"%s requires that you accept the following End-User License Agreement before "
+"installation can proceed:"
+
+# %1 is the addon name
+#. %1 is the add-on name
+#: controllers/addons_controller.php:1476
+#, fuzzy, php-format
+msgid "addons_previews_pagetitle"
+msgstr "Previews for %s"
+
+#: views/addons/category_landing.thtml:135
+#, fuzzy
+msgid "addons_recently_added"
+msgstr "Recently Added"
+
+#: views/addons/recommended.thtml:51 controllers/addons_controller.php:1365
+#, fuzzy
+msgid "addons_recommended_introduction"
+msgstr ""
+"With so many great add-ons available, there's something for everyone. To get "
+"you started, here's a list of some of the most popular. Enjoy!"
+
+#: controllers/addons_controller.php:1357
+#: controllers/addons_controller.php:1364
+#, fuzzy
+msgid "addons_recommended_pagetitle"
+msgstr "Recommended Add-ons"
+
+#: controllers/addons_controller.php:1360
+#, fuzzy
+msgid "addons_recommended_title"
+msgstr "Recommended Add-ons"
+
+#: views/addons/searchengines.thtml:136
+#, fuzzy
+msgid "addons_searchengines_additional_resources"
+msgstr "Additional Resources"
+
+# link text devmo
+#. link text devmo
+#: views/addons/searchengines.thtml:141
+#, fuzzy
+msgid "addons_searchengines_devmo_link"
+msgstr "Mozilla Developer Center"
+
+#: views/pages/js_constants.js.thtml:67
+#, fuzzy
+msgid "addons_searchengines_error_mozilla_browser_required"
+msgstr ""
+"Sorry, you need a Mozilla-based browser (such as Firefox) to install a "
+"search plugin."
+
+#: views/addons/searchengines.thtml:49
+#, fuzzy
+msgid "addons_searchengines_error_nojavascript"
+msgstr ""
+"JavaScript is required to install plugins, but it looks like you have it "
+"disabled. Please enable JavaScript before trying to install any of the "
+"search plugins below."
+
+# %1 is "make your own" link
+# %2 is MDC link
+#. %1 is "make your own" link
+#. %2 is MDC link
+#: views/addons/searchengines.thtml:139
+#, fuzzy
+msgid "addons_searchengines_learn_howto"
+msgstr "Learn how to %1$s at the %2$s."
+
+# link path to search plugins instructions, relative to devmo
+#. link path to search plugins instructions, relative to devmo
+#: views/addons/searchengines.thtml:140
+#, fuzzy
+msgid "addons_searchengines_makeyourown_href"
+msgstr "/en/docs/Creating_OpenSearch_plugins_for_Firefox"
+
+# link text for "make your own" (opensearch engine)
+#. link text for "make your own" (opensearch engine)
+#: views/addons/searchengines.thtml:140
+#, fuzzy
+msgid "addons_searchengines_makeyourown_link"
+msgstr "make your own"
+
+# %1 is the link to mycroft.mozdev.org
+#. %1 is the link to mycroft.mozdev.org
+#: views/addons/searchengines.thtml:138
+#, fuzzy
+msgid "addons_searchengines_more"
+msgstr "Browse through more search engines at %1$s"
+
+# link text to mycroft.mozdev.org
+#. link text to mycroft.mozdev.org
+#: views/addons/searchengines.thtml:138
+#, fuzzy
+msgid "addons_searchengines_mycroft_link"
+msgstr "mycroft.mozdev.org"
+
+#: controllers/addons_controller.php:1100
+#: controllers/addons_controller.php:1110
+#, fuzzy
+msgid "addons_searchengines_pagetitle"
+msgstr "Search Engines"
+
+#: views/addons/searchengines.thtml:143
+#, fuzzy
+msgid "addons_searchengines_thanks"
+msgstr ""
+"Special thanks to the Mycroft Project for their work on Firefox Search "
+"Engines."
+
+#: views/addons/display.thtml:154
+#, fuzzy
+msgid "addons_share_button_text"
+msgstr "Share this"
+
+#: controllers/addons_controller.php:89
+#, fuzzy
+msgid "addons_share_label_delicious"
+msgstr "Add to Delicious"
+
+#: controllers/addons_controller.php:77
+#, fuzzy
+msgid "addons_share_label_digg"
+msgstr "Digg this!"
+
+#: controllers/addons_controller.php:83
+#, fuzzy
+msgid "addons_share_label_facebook"
+msgstr "Post to Facebook"
+
+#: controllers/addons_controller.php:101
+#, fuzzy
+msgid "addons_share_label_friendfeed"
+msgstr "Share on FriendFeed"
+
+#: controllers/addons_controller.php:95
+#, fuzzy
+msgid "addons_share_label_myspace"
+msgstr "Post to MySpace"
+
+#: controllers/components/amo.php:201 controllers/components/amo.php:229
+#, fuzzy
+msgid "addons_status_disabled"
+msgstr "Disabled"
+
+#: controllers/components/amo.php:191 controllers/components/amo.php:224
+#, fuzzy
+msgid "addons_status_incomplete"
+msgstr "Incomplete Version"
+
+#: controllers/components/amo.php:197 controllers/components/amo.php:227
+#, fuzzy
+msgid "addons_status_nominated"
+msgstr "In Sandbox; Public Nomination"
+
+#: views/pages/js_constants.js.thtml:80 controllers/components/amo.php:195
+#: controllers/components/amo.php:226
+#, fuzzy
+msgid "addons_status_pending"
+msgstr "In Sandbox; Pending Review"
+
+#: views/pages/js_constants.js.thtml:78 controllers/components/amo.php:199
+#: controllers/components/amo.php:228
+#, fuzzy
+msgid "addons_status_public"
+msgstr "Public"
+
+#: views/pages/js_constants.js.thtml:79 controllers/components/amo.php:193
+#: controllers/components/amo.php:225
+#, fuzzy
+msgid "addons_status_sandbox"
+msgstr "In Sandbox"
+
+#: controllers/components/amo.php:203
+#, fuzzy
+msgid "addons_status_unknown"
+msgstr "Unknown"
+
+#: views/elements/amo2009/teaser_collections.thtml:91
+#: views/elements/amo2009/homepage_addon.thtml:99
+#: views/elements/feature.thtml:94
+#, fuzzy
+msgid "addons_title_tooltip"
+msgstr "Learn more about this add-on"
+
+#: views/addons/category_landing.thtml:151
+#, fuzzy
+msgid "addons_top_downloads"
+msgstr "Top Downloads"
+
+#: views/addons/category_landing.thtml:165
+#, fuzzy
+msgid "addons_top_rated"
+msgstr "Top Rated"
+
+#: views/addons/versions.thtml:62
+#, fuzzy
+msgid "addons_versions_careful"
+msgstr "Be Careful With Old Versions"
+
+#: views/addons/versions.thtml:63
+#, fuzzy
+msgid "addons_versions_careful_introduction"
+msgstr ""
+"These versions are displayed for reference and testing purposes. You should "
+"always use the latest version of an add-on."
+
+#: controllers/addons_controller.php:1549
+#, fuzzy
+msgid "addons_versions_history"
+msgstr "Version History with Changelogs"
+
+#. %1$s is the add-on name
+#: controllers/addons_controller.php:1535
+#, fuzzy, php-format
+msgid "addons_versions_pagetitle"
+msgstr "%1$s Version History"
+
+#: controllers/groups_controller.php:71
+#, fuzzy
+msgid "admin_group_add_pagetitle"
+msgstr "Add Group"
+
+#: controllers/groups_controller.php:111
+#, fuzzy
+msgid "admin_group_delete_pagetitle"
+msgstr "Delete Group"
+
+#. %s is a number to identify the group
+#: controllers/groups_controller.php:117
+#, fuzzy, php-format
+msgid "admin_group_deleted"
+msgstr "The Group with id %s was deleted"
+
+#: controllers/groups_controller.php:89
+#, fuzzy
+msgid "admin_group_edit_pagetitle"
+msgstr "Edit Group"
+
+#: controllers/groups_controller.php:92 controllers/groups_controller.php:113
+#, fuzzy
+msgid "admin_group_error_invalid_id"
+msgstr "Invalid id for Group"
+
+#: controllers/groups_controller.php:65
+#, fuzzy
+msgid "admin_group_pagetitle"
+msgstr "Group Admin"
+
+#: controllers/groups_controller.php:77 controllers/groups_controller.php:99
+#, fuzzy
+msgid "admin_group_saved"
+msgstr "The Group has been saved"
+
+#: views/elements/amo2009/search.thtml:257 views/elements/search.thtml:239
+#, fuzzy
+msgid "advanced_search_form"
+msgstr "Advanced"
+
+#: views/elements/amo2009/search.thtml:126 views/elements/search.thtml:125
+#, fuzzy
+msgid "advanced_search_form_any_time"
+msgstr "Any time"
+
+#: views/elements/amo2009/search.thtml:97
+#: views/elements/amo2009/search.thtml:110 views/elements/search.thtml:96
+#: views/elements/search.thtml:109
+#, fuzzy
+msgid "advanced_search_form_any_type"
+msgstr "Any"
+
+#: views/elements/amo2009/search.thtml:275 views/elements/search.thtml:254
+#, fuzzy
+msgid "advanced_search_form_any_version"
+msgstr "Any"
+
+#: views/elements/amo2009/search.thtml:217 views/elements/search.thtml:212
+#, fuzzy
+msgid "advanced_search_form_application"
+msgstr "Application"
+
+#: views/elements/amo2009/search.thtml:143 views/elements/search.thtml:142
+#, fuzzy
+msgid "advanced_search_form_keyword_match"
+msgstr "Keyword Match"
+
+#: views/elements/amo2009/search.thtml:251 views/elements/search.thtml:225
+#, fuzzy
+msgid "advanced_search_form_lastupdate"
+msgstr "Last Updated"
+
+#: views/elements/amo2009/search.thtml:145 views/elements/search.thtml:144
+#, fuzzy
+msgid "advanced_search_form_name"
+msgstr "Name"
+
+#: views/elements/amo2009/search.thtml:144 views/elements/search.thtml:143
+#, fuzzy
+msgid "advanced_search_form_newest"
+msgstr "Newest"
+
+#: views/elements/amo2009/search.thtml:130 views/elements/search.thtml:129
+#, fuzzy
+msgid "advanced_search_form_past_3_months"
+msgstr "Past 3 months"
+
+#: views/elements/amo2009/search.thtml:131 views/elements/search.thtml:130
+#, fuzzy
+msgid "advanced_search_form_past_6_months"
+msgstr "Past 6 months"
+
+#: views/elements/amo2009/search.thtml:127 views/elements/search.thtml:126
+#, fuzzy
+msgid "advanced_search_form_past_day"
+msgstr "Past Day"
+
+#: views/elements/amo2009/search.thtml:129 views/elements/search.thtml:128
+#, fuzzy
+msgid "advanced_search_form_past_month"
+msgstr "Past month"
+
+#: views/elements/amo2009/search.thtml:128 views/elements/search.thtml:127
+#, fuzzy
+msgid "advanced_search_form_past_week"
+msgstr "Past week"
+
+#: views/elements/amo2009/search.thtml:132 views/elements/search.thtml:131
+#, fuzzy
+msgid "advanced_search_form_past_year"
+msgstr "Past year"
+
+#: views/elements/amo2009/search.thtml:239 views/elements/search.thtml:230
+#, fuzzy
+msgid "advanced_search_form_perpage"
+msgstr "Per Page"
+
+#: views/elements/amo2009/search.thtml:243 views/elements/search.thtml:224
+#, fuzzy
+msgid "advanced_search_form_platform"
+msgstr "Platform"
+
+#: views/elements/amo2009/search.thtml:147 views/elements/search.thtml:146
+#, fuzzy
+msgid "advanced_search_form_popularity"
+msgstr "Popularity"
+
+#: views/elements/amo2009/search.thtml:146 views/elements/search.thtml:145
+#, fuzzy
+msgid "advanced_search_form_rating"
+msgstr "Rating"
+
+#: views/elements/amo2009/search.thtml:247 views/elements/search.thtml:231
+#, fuzzy
+msgid "advanced_search_form_sortby"
+msgstr "Sort By"
+
+#: views/elements/amo2009/search.thtml:227 views/elements/search.thtml:216
+#, fuzzy
+msgid "advanced_search_form_to"
+msgstr "to"
+
+#: views/elements/amo2009/search.thtml:257 views/elements/search.thtml:237
+#, fuzzy
+msgid "advanced_search_form_toggle_tooltip"
+msgstr "Toggle advanced search mode"
+
+#: views/elements/amo2009/search.thtml:235 views/elements/search.thtml:223
+#, fuzzy
+msgid "advanced_search_form_type"
+msgstr "Type"
+
+#: views/elements/amo2009/search.thtml:222 views/elements/search.thtml:214
+#, fuzzy
+msgid "advanced_search_form_version"
+msgstr "version"
+
+#: views/elements/amo2009/pagination.thtml:42
+#, fuzzy
+msgid "amo2009_pagination_next_page"
+msgstr "Next"
+
+#: views/elements/amo2009/pagination.thtml:41
+#, fuzzy
+msgid "amo2009_pagination_previous_page"
+msgstr "Prev"
+
+#: views/pages/js_constants.js.thtml:96
+#, fuzzy
+msgid "app_compat_ignore_check"
+msgstr "Ignore version check"
+
+#: views/pages/js_constants.js.thtml:72
+#, fuzzy
+msgid "app_compat_older_firefox_only"
+msgstr "This add-on is for older versions of Firefox"
+
+#. %1$s and %2$s are URLs
+#: views/pages/js_constants.js.thtml:74
+#, fuzzy
+msgid "app_compat_older_version_or_ignore_check"
+msgstr ""
+"You can <a href=\"%1$s\">try an older version</a> or <a href=\"#\" onclick="
+"\"%2$s\">ignore this check</a>"
+
+#. %1$s is a URL
+#: views/pages/js_constants.js.thtml:71
+#, fuzzy
+msgid "app_compat_try_old_version"
+msgstr "An <a href=\"%1$s\">older version</a> may work"
+
+#. %1$s is a URL
+#. %2$s is a version number. Example: 3.1
+#: views/pages/js_constants.js.thtml:73
+#, fuzzy
+msgid "app_compat_unreleased_version"
+msgstr ""
+"This add-on requires the not-yet released <a href=\"%1$s\">Firefox %2$s</a>"
+
+#: views/pages/js_constants.js.thtml:70
+#, fuzzy
+msgid "app_compat_update_firefox"
+msgstr ""
+"<a href=\"http://getfirefox.com\">Upgrade Firefox</a> to use this add-on"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#. %3$s is a status, like Public.
+#: controllers/components/audit.php:79
+#, fuzzy
+msgid "audit_addon_status"
+msgstr "%1$s changed the status of %2$s to %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:221
+#, fuzzy
+msgid "audit_admin_default"
+msgstr "%1$s committed unknown admin action %2$s to ID %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:153
+#, fuzzy
+msgid "audit_admin_feature_remove"
+msgstr "%1$s removed feature %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is an application, like Firefox.
+#: controllers/components/audit.php:92
+#, fuzzy
+msgid "audit_application_create"
+msgstr "%1$s created application %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is an application, like Firefox.
+#: controllers/components/audit.php:95
+#, fuzzy
+msgid "audit_application_edit"
+msgstr "%1$s edited application %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a version number, like 3.5.
+#. %3$s is an application, like Firefox.
+#: controllers/components/audit.php:105
+#, fuzzy
+msgid "audit_appversion_create"
+msgstr "%1$s created version %2$s for %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a version number, like 3.5.
+#. %3$s is an application, like Firefox.
+#: controllers/components/audit.php:108
+#, fuzzy
+msgid "audit_appversion_delete"
+msgstr "%1$s deleted version %2$s for %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a config field, like "awesomeness".
+#. %3$s is a config value, like "off".
+#. %4$s is a config value, like "on".
+#: controllers/components/audit.php:210
+#, fuzzy
+msgid "audit_config"
+msgstr "%1$s changed config '%2$s' from '%3$s' to '%4$s'"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:258
+#, fuzzy
+msgid "audit_editor_default"
+msgstr "%1$s committed unknown editor action %2$s to ID %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#: controllers/components/audit.php:236
+#, fuzzy
+msgid "audit_editor_feature_remove"
+msgstr "%1$s removed addon %2$s from feature list"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#: controllers/components/audit.php:231
+#, fuzzy
+msgid "audit_feature_add"
+msgstr "%1$s added addon %2$s to feature list"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:149
+#, fuzzy
+msgid "audit_feature_edit"
+msgstr "%1$s changed a feature for %2$s locale"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#: controllers/components/audit.php:241
+#, fuzzy
+msgid "audit_feature_locale_change"
+msgstr "%1$s changed locales for addon %2$s on feature list"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:83
+#, fuzzy
+msgid "audit_file_recalchash"
+msgstr "%1$s recalculated the hash for file %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>user name</a>
+#. %3$s is <a>group name</a>
+#: controllers/components/audit.php:182
+#, fuzzy
+msgid "audit_group_addmember"
+msgstr "%1$s added %2$s to group %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:313
+#, fuzzy
+msgid "audit_group_associated"
+msgstr "%1$s associated themselves with %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:162
+#, fuzzy
+msgid "audit_group_create"
+msgstr "%1s created group %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:170
+#, fuzzy
+msgid "audit_group_delete"
+msgstr "%1$s deleted group %2$s (ID %3$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:165
+#, fuzzy
+msgid "audit_group_edit"
+msgstr "%1$s edited group %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>user name</a>
+#. %3$s is <a>group name</a>
+#: controllers/components/audit.php:188
+#, fuzzy
+msgid "audit_group_removemember"
+msgstr "%1$s removed %2$s from group %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:280
+#, fuzzy
+msgid "audit_l10n_default"
+msgstr "%1$s committed unknown action %2$s for %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:295
+#, fuzzy
+msgid "audit_modify_locked_group"
+msgstr "%1$s attempted to modify locked group %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:299
+#, fuzzy
+msgid "audit_modify_other_locale"
+msgstr "%1$s attempted to modify translations in %2$s without permission"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a platform, like <a>Windows</a>
+#: controllers/components/audit.php:135
+#, fuzzy
+msgid "audit_platform_create"
+msgstr "%1$s created platform %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a platform, like <a>Windows</a>
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:143
+#, fuzzy
+msgid "audit_platform_delete"
+msgstr "%1$s deleted platform %2$s (ID %3$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a platform, like <a>Windows</a>
+#: controllers/components/audit.php:138
+#, fuzzy
+msgid "audit_platform_edit"
+msgstr "%1$s edited platform %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a part of the admin, like 'Site Config'
+#: controllers/components/audit.php:288
+#, fuzzy
+msgid "audit_reauthentication_failure"
+msgstr "%1$s failed to re-authenticate to access %2$s."
+
+#. %1$s is <a>user name</a>
+#. %2$s is the name of a canned response, like 'Ready for the public'
+#: controllers/components/audit.php:198
+#, fuzzy
+msgid "audit_response_create"
+msgstr "%1$s created response %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is the name of a canned response, like 'Ready for the public'
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:206
+#, fuzzy
+msgid "audit_response_delete"
+msgstr "%1$s deleted response %2$s (ID %3$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is the name of a canned response, like 'Ready for the public'
+#: controllers/components/audit.php:201
+#, fuzzy
+msgid "audit_response_edit"
+msgstr "%1$s edited response %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:245
+#, fuzzy
+msgid "audit_review_approve"
+msgstr "%1$s approved review %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:250 controllers/components/audit.php:253
+#, fuzzy
+msgid "audit_review_delete"
+msgstr "%1$s deleted review %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:303
+#, fuzzy
+msgid "audit_security_default"
+msgstr "%1$s committed unknown security action %2$s to ID %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a category name, like <a>Search Tools</a>
+#: controllers/components/audit.php:118
+#, fuzzy
+msgid "audit_tag_create"
+msgstr "%1$s created tag %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a category name, like <a>Search Tools</a>
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:126
+#, fuzzy
+msgid "audit_tag_delete"
+msgstr "%1$s deleted category %2$s (ID %3$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a category name, like <a>Search Tools</a>
+#: controllers/components/audit.php:121
+#, fuzzy
+msgid "audit_tag_edit"
+msgstr "%1$s edited category %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:266
+#, fuzzy
+msgid "audit_update_applications"
+msgstr "%1$s updated application translations for %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:277
+#, fuzzy
+msgid "audit_update_blog"
+msgstr "%1$s updated blog post translations for %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:274
+#, fuzzy
+msgid "audit_update_platforms"
+msgstr "%1$s updated platform translations for %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:270
+#, fuzzy
+msgid "audit_update_tags"
+msgstr "%1$s updated category translations for %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>user name</a>
+#: controllers/components/audit.php:217
+#, fuzzy
+msgid "audit_user_edit"
+msgstr "%1$s edited %2$s's user information"
+
+#: controllers/addons_controller.php:1012
+#, fuzzy
+msgid "browse_addons_name"
+msgstr "Add-ons by Name"
+
+#: controllers/addons_controller.php:1010
+#, fuzzy
+msgid "browse_addons_newest"
+msgstr "Newest Add-ons"
+
+#: controllers/addons_controller.php:1008
+#, fuzzy
+msgid "browse_addons_popular"
+msgstr "Popular Add-ons"
+
+#: controllers/addons_controller.php:1011
+#, fuzzy
+msgid "browse_addons_rated"
+msgstr "Add-ons by Rating"
+
+#: controllers/addons_controller.php:1009
+#, fuzzy
+msgid "browse_addons_updated"
+msgstr "Recently Updated Add-ons"
+
+#: views/elements/categories.thtml:73 views/elements/categories.thtml:82
+#, fuzzy
+msgid "categories_current_title"
+msgstr "Current Category"
+
+#: views/elements/categories.thtml:50
+#: views/elements/amo2009/categories.thtml:43
+#: views/elements/amo2009/categories.thtml:45
+#, fuzzy
+msgid "categories_header"
+msgstr "Categories"
+
+#: views/elements/categories.thtml:50
+#: views/elements/amo2009/categories.thtml:41
+#, fuzzy
+msgid "categories_header_title"
+msgstr "Choose a category"
+
+# %1 is the category name
+#. %1$s is the category name
+#: views/addons/searchengines.thtml:129
+#, fuzzy, php-format
+msgid "category_extra_see_all"
+msgstr "See All %1$s"
+
+#. %1$s is a number.
+#: models/collection.php:130
+#, fuzzy
+msgid "collection_description_limit"
+msgstr "The description should be less than %1$s characters."
+
+#. %1$s is the name of the collection
+#: controllers/collections_controller.php:392
+#, fuzzy
+msgid "collection_detail_rss_title"
+msgstr "%s Collection"
+
+#: controllers/collections_controller.php:1065
+#, fuzzy
+msgid "collection_error_deleting_addon"
+msgstr "Error deleting add-on!"
+
+#: controllers/collections_controller.php:1051
+#, fuzzy
+msgid "collection_error_saving_addon"
+msgstr "Error saving add-on!"
+
+#: controllers/collections_controller.php:1080
+#, fuzzy
+msgid "collection_error_saving_comment"
+msgstr "Error saving comment!"
+
+#. %1$s is a number.
+#: models/collection.php:122
+#, fuzzy
+msgid "collection_name_limit"
+msgstr "The name should be less than %1$s characters."
+
+#: controllers/collections_controller.php:352
+#: controllers/collections_controller.php:487
+#, fuzzy
+msgid "collection_not_found"
+msgstr "Collection not found!"
+
+#. %1$s is the text on the "create collection" button
+#: views/collections/add.thtml:91
+#, fuzzy
+msgid "collections_add_formfield_addons_description"
+msgstr ""
+"If you already know which add-ons you want to add to your collection, just "
+"start typing their names below. If you'd rather wait and do this later, just "
+"click %1$s now."
+
+#: views/collections/add.thtml:90
+#, fuzzy
+msgid "collections_add_formfield_firstaddons"
+msgstr "Choose your first add-ons"
+
+#: views/collections/add.thtml:48
+#, fuzzy
+msgid "collections_add_header"
+msgstr "Create a Collection"
+
+#: views/collections/add.thtml:97
+#, fuzzy
+msgid "collections_add_header_selectedaddons"
+msgstr "Selected Add-ons"
+
+#: views/collections/add.thtml:50
+#, fuzzy
+msgid "collections_add_intro"
+msgstr ""
+"It's easy to create your own collection of add-ons by filling in a few "
+"fields below."
+
+#: views/collections/add.thtml:92 views/collections/add.thtml:103
+#, fuzzy
+msgid "collections_add_submit"
+msgstr "Create Collection"
+
+#: views/pages/collector_faq.thtml:50 views/pages/collector_firstrun.thtml:43
+#: views/pages/collector.thtml:47 views/pages/collector_features.thtml:55
+#: controllers/search_controller.php:302
+#: controllers/collections_controller.php:206
+#: controllers/collections_controller.php:405
+#: controllers/collections_controller.php:467
+#: controllers/collections_controller.php:539
+#, fuzzy
+msgid "collections_breadcrumb"
+msgstr "Collections"
+
+#: views/collections/detail.thtml:185
+#, fuzzy
+msgid "collections_detail_a_learn"
+msgstr "Learn More"
+
+#: views/elements/amo2009/collection_add_form.thtml:53
+#: views/elements/amo2009/collections_js_init.thtml:68
+#: views/pages/collector_firstrun.thtml:64
+#, fuzzy
+msgid "collections_detail_button_add"
+msgstr "Add to Favorites"
+
+#: views/elements/amo2009/collection_add_form.thtml:50
+#: views/elements/amo2009/collections_js_init.thtml:71
+#, fuzzy
+msgid "collections_detail_button_remove"
+msgstr "Remove from Favorites"
+
+#. %1$s is a URL.
+#. %2$s is a full <a href>.
+#: views/collections/detail.thtml:62
+#, fuzzy
+msgid "collections_detail_created_desc"
+msgstr ""
+"<p>You can view your new collection below. If you'd like to set a collection "
+"nickname, upload an icon, or change additional settings, please visit the <a "
+"href='%1$s'>Manage Collections</a> page.</p><p>Your collection can be "
+"accessed at this location: %2$s</p>"
+
+#: views/collections/detail.thtml:61
+#, fuzzy
+msgid "collections_detail_created_msg"
+msgstr "Your collection is now ready!"
+
+#: views/collections/detail.thtml:109
+#, fuzzy
+msgid "collections_detail_header_about"
+msgstr "About This Collection"
+
+#. %1$s is a number.
+#: views/collections/detail.thtml:126
+#, fuzzy
+msgid "collections_detail_header_count"
+msgid_plural "collections_detail_header_count"
+msgstr[0] "%1$s Add-on in this Collection"
+msgstr[1] "%1$s Add-ons in this Collection"
+
+#: views/collections/detail.thtml:113
+#, fuzzy
+msgid "collections_detail_info_created"
+msgstr "<strong>Created by:</strong> %1$s"
+
+#: views/collections/detail.thtml:117
+#, fuzzy
+msgid "collections_detail_info_updated"
+msgstr "<strong>Updated:</strong>"
+
+#: views/elements/amo2009/collections_js_init.thtml:62
+#, fuzzy
+msgid "collections_detail_js_adding"
+msgstr "Adding to Favorites&hellip;"
+
+#: views/elements/amo2009/collections_js_init.thtml:65
+#, fuzzy
+msgid "collections_detail_js_removing"
+msgstr "Removing Favorite&hellip;"
+
+#. %1$s is a URL
+#: views/collections/detail.thtml:90
+#, fuzzy
+msgid "collections_detail_login"
+msgstr "<a href=\"%1$s\">Log in</a> to add this collection to your favorites."
+
+#: views/collections/detail.thtml:104
+#, fuzzy
+msgid "collections_detail_manage"
+msgstr "Manage Collection"
+
+#: controllers/collections_controller.php:298
+#, fuzzy
+msgid "collections_detail_sort_date"
+msgstr "Date Added"
+
+#: controllers/collections_controller.php:299
+#, fuzzy
+msgid "collections_detail_sort_name"
+msgstr "Name"
+
+#: controllers/collections_controller.php:300
+#, fuzzy
+msgid "collections_detail_sort_popularity"
+msgstr "Popularity"
+
+#. %1$s is a number.
+#: views/collections/detail.thtml:166
+#, fuzzy
+msgid "collections_detail_weekly_downloads"
+msgid_plural "collections_detail_weekly_downloads"
+msgstr[0] "%1$s download this week"
+msgstr[1] "%1$s downloads this week"
+
+#: views/collections/edit.thtml:255
+#, fuzzy
+msgid "collections_edit_addons_delete_noscript"
+msgstr "Selected add-ons will be removed upon Save"
+
+#: views/collections/edit.thtml:247
+#, fuzzy
+msgid "collections_edit_addons_description"
+msgstr ""
+"To publish new add-ons to this collection, start typing their names below."
+
+#: views/collections/edit.thtml:248
+#, fuzzy
+msgid "collections_edit_addons_description_noscript"
+msgstr ""
+"To publish new add-ons to this collection, enter a comma-separated list of "
+"Add-on IDs below."
+
+#: views/collections/edit.thtml:247 views/collections/edit.thtml:248
+#, fuzzy
+msgid "collections_edit_addons_description_publish_detailspage"
+msgstr "You can also publish an add-on from its normal listing page."
+
+#. %1$s is the date the add-on was added to the collection
+#. %1$s is the name of the user who added the add-on to the collection
+#: views/collections/edit.thtml:260
+#, fuzzy
+msgid "collections_edit_addons_listitem_added"
+msgstr "Added %1$s by %2$s"
+
+#: views/collections/edit.thtml:263
+#, fuzzy
+msgid "collections_edit_addons_listitem_comment_add"
+msgstr "Add publisher comment"
+
+#: views/collections/edit.thtml:266
+#, fuzzy
+msgid "collections_edit_addons_listitem_comment_delete"
+msgstr "Delete publisher comment"
+
+#: views/collections/edit.thtml:265
+#, fuzzy
+msgid "collections_edit_addons_listitem_comment_edit"
+msgstr "Edit publisher comment"
+
+#: views/collections/edit.thtml:271
+#, fuzzy
+msgid "collections_edit_addons_listitem_comment_note"
+msgstr ""
+"Note: Comment will appear as though written by original publisher on the "
+"original publication date"
+
+#: views/collections/edit.thtml:270
+#, fuzzy
+msgid "collections_edit_addons_listitem_comment_submit"
+msgstr "Save Comment"
+
+#: views/collections/edit.thtml:261
+#, fuzzy
+msgid "collections_edit_addons_listitem_remove"
+msgstr "Remove"
+
+#: views/collections/edit.thtml:250
+#, fuzzy
+msgid "collections_edit_addons_submit"
+msgstr "Add to Collection"
+
+#: views/collections/edit.thtml:153
+#, fuzzy
+msgid "collections_edit_check_nickname"
+msgstr "Check Availability"
+
+#: views/collections/edit.thtml:299
+#, fuzzy
+msgid "collections_edit_confirm_deletecollection"
+msgstr "Yes, I would like to delete this collection."
+
+#. %1$s is the label of the edit form's submit button
+#: views/collections/edit.thtml:300
+#, fuzzy
+msgid "collections_edit_confirm_deletecollection_description"
+msgstr "Check the box, then click on \"%1$s\" to delete this collection."
+
+#. %1$s is the "delete" submit button text
+#. %2$s is the title of the "advanced" tab
+#: views/collections/edit.thtml:95
+#, fuzzy
+msgid "collections_edit_delete_upon_submit"
+msgstr ""
+"Upon clicking \"%1$s\" below, your collection will be deleted. If you do not "
+"want to delete your collection, uncheck the confirmation box in the \"%2$s\" "
+"tab and continue editing your collection. If you leave this page without "
+"saving, your collection will also not be deleted."
+
+#: views/collections/edit.thtml:94
+#, fuzzy
+msgid "collections_edit_delete_warning"
+msgstr "Your collection is about to be deleted!"
+
+#: views/collections/add.thtml:76 views/collections/edit.thtml:144
+#, fuzzy
+msgid "collections_edit_form_error_description"
+msgstr "You must provide a description of your collection."
+
+#: views/collections/edit.thtml:181
+#, fuzzy
+msgid "collections_edit_form_error_icon"
+msgstr "There was an error uploading your icon."
+
+#: views/collections/add.thtml:69 views/collections/edit.thtml:130
+#, fuzzy
+msgid "collections_edit_form_error_name"
+msgstr "You must give your collection a name."
+
+#: views/collections/edit.thtml:158
+#, fuzzy
+msgid "collections_edit_form_error_nickname"
+msgstr "If you choose a nickname, it must be unique."
+
+#: views/collections/add.thtml:93 views/collections/edit.thtml:249
+#, fuzzy
+msgid "collections_edit_formfield_addons"
+msgstr "Add-on name:"
+
+#: views/collections/edit.thtml:281
+#, fuzzy
+msgid "collections_edit_formfield_application"
+msgstr "Associated Application"
+
+#: views/collections/edit.thtml:282
+#, fuzzy
+msgid "collections_edit_formfield_application_description"
+msgstr "Select the application that your collection supports."
+
+#: views/collections/edit.thtml:288
+#, fuzzy
+msgid "collections_edit_formfield_collectiontype"
+msgstr "Collection Type"
+
+#: views/collections/edit.thtml:295
+#, fuzzy
+msgid "collections_edit_formfield_deletecollection"
+msgstr "Delete Collection"
+
+#: views/collections/edit.thtml:296
+#, fuzzy
+msgid "collections_edit_formfield_deletecollection_description"
+msgstr "Deleting your collection will permanently erase it."
+
+#: views/collections/add.thtml:73 views/collections/edit.thtml:140
+#, fuzzy
+msgid "collections_edit_formfield_description"
+msgstr "Collection Description"
+
+#: views/collections/add.thtml:74 views/collections/edit.thtml:141
+#, fuzzy
+msgid "collections_edit_formfield_description_description"
+msgstr "Briefly describe your collection and the kind of add-ons in it"
+
+#: views/collections/edit.thtml:162
+#, fuzzy
+msgid "collections_edit_formfield_icon"
+msgstr "Icon"
+
+#: views/collections/edit.thtml:163
+#, fuzzy
+msgid "collections_edit_formfield_icon_description"
+msgstr ""
+"You can upload a JPG, GIF or PNG icon that will be resized to 32x32 pixels."
+
+#: views/collections/add.thtml:80 views/collections/edit.thtml:189
+#, fuzzy
+msgid "collections_edit_formfield_listed"
+msgstr "Who can view your collection?"
+
+#: views/collections/add.thtml:81 views/collections/edit.thtml:190
+#, fuzzy
+msgid "collections_edit_formfield_listed_description"
+msgstr ""
+"By default, collections appear in the public Collection Directory and are "
+"discoverable by anyone. If you want to restrict your collection to be "
+"viewable only by people who are given a special link, choose that option "
+"below."
+
+#: views/collections/add.thtml:84 views/collections/edit.thtml:193
+#, fuzzy
+msgid "collections_edit_formfield_listed_false"
+msgstr "Only people I invite can view my collection"
+
+#: views/collections/add.thtml:83 views/collections/edit.thtml:192
+#, fuzzy
+msgid "collections_edit_formfield_listed_true"
+msgstr "Everyone can view my collection in the directory"
+
+#: views/collections/edit.thtml:223
+#, fuzzy
+msgid "collections_edit_formfield_managers"
+msgstr "Who can manage my collection?"
+
+#: views/collections/edit.thtml:224
+#, fuzzy
+msgid "collections_edit_formfield_managers_description"
+msgstr ""
+"These users can publish add-ons to your collection, manage all add-ons and "
+"settings, and grant other users permission."
+
+#: views/collections/add.thtml:66 views/collections/edit.thtml:126
+#, fuzzy
+msgid "collections_edit_formfield_name"
+msgstr "Collection Name"
+
+#: views/collections/add.thtml:67 views/collections/edit.thtml:127
+#, fuzzy
+msgid "collections_edit_formfield_name_description"
+msgstr ""
+"Give your collection a descriptive name, such as \"Dave's Favorite Travel "
+"Add-ons\""
+
+#: views/collections/edit.thtml:148
+#, fuzzy
+msgid "collections_edit_formfield_nickname"
+msgstr "Collection Nickname"
+
+#: views/collections/edit.thtml:149
+#, fuzzy
+msgid "collections_edit_formfield_nickname_description"
+msgstr "Optionally, give your collection a unique nickname for quick access:"
+
+#: views/collections/edit.thtml:201
+#, fuzzy
+msgid "collections_edit_formfield_publishers"
+msgstr "Who can publish add-ons to your collection?"
+
+#: views/collections/edit.thtml:202
+#, fuzzy
+msgid "collections_edit_formfield_publishers_description"
+msgstr ""
+"These users can publish add-ons to your collection and remove add-ons that "
+"they publish."
+
+#: views/collections/edit.thtml:210 views/collections/edit.thtml:232
+#, fuzzy
+msgid "collections_edit_formfield_users_add"
+msgstr "Enter the e-mail address of a Firefox Add-ons account:"
+
+#: views/collections/edit.thtml:216 views/collections/edit.thtml:238
+#, fuzzy
+msgid "collections_edit_formfield_users_delete_noscript"
+msgstr "Selected accounts will be removed upon Save"
+
+#: views/collections/edit.thtml:215 views/collections/edit.thtml:237
+#, fuzzy
+msgid "collections_edit_formfield_users_new_noscript"
+msgstr ""
+"Enter a comma-separated list of e-mail addresses of Firefox Add-ons accounts"
+
+#: views/collections/edit.thtml:204 views/collections/edit.thtml:226
+#, fuzzy
+msgid "collections_edit_formfield_users_onlyme"
+msgstr "Only me"
+
+#: views/collections/edit.thtml:205 views/collections/edit.thtml:227
+#, fuzzy
+msgid "collections_edit_formfield_users_otherusers"
+msgstr "Myself and these users:"
+
+#: views/collections/edit.thtml:211 views/collections/edit.thtml:233
+#, fuzzy
+msgid "collections_edit_formfield_users_submit"
+msgstr "Add"
+
+#. %1$s is the name of the collection
+#: views/collections/edit.thtml:68
+#, fuzzy
+msgid "collections_edit_header"
+msgstr "Manage %1$s"
+
+#: views/collections/edit.thtml:246
+#, fuzzy
+msgid "collections_edit_header_addons"
+msgstr "Manage Collection Contents"
+
+#: views/collections/edit.thtml:253 views/collections/edit.thtml:258
+#, fuzzy
+msgid "collections_edit_header_addons_current"
+msgstr "Current Add-ons:"
+
+#: views/collections/edit.thtml:279
+#, fuzzy
+msgid "collections_edit_header_advanced"
+msgstr "Advanced Settings"
+
+#: views/collections/edit.thtml:186
+#, fuzzy
+msgid "collections_edit_header_permissions"
+msgstr "Manage Collection Permissions"
+
+#: views/collections/edit.thtml:170
+#, fuzzy
+msgid "collections_edit_icon_cancel"
+msgstr "Cancel"
+
+#: views/collections/edit.thtml:174 views/collections/edit.thtml:179
+#, fuzzy
+msgid "collections_edit_icon_delete"
+msgstr "Delete Icon"
+
+#: views/collections/edit.thtml:178
+#, fuzzy
+msgid "collections_edit_icon_replace"
+msgstr "Replace Icon"
+
+#. %1$s is the label of the edit form's submit button
+#: views/collections/edit.thtml:169
+#, fuzzy
+msgid "collections_edit_icon_toberemoved"
+msgstr "Icon will be removed when \"%1$s\" is clicked below"
+
+#: views/collections/edit.thtml:155
+#, fuzzy
+msgid "collections_edit_nickname_available"
+msgstr "Nickname Available"
+
+#: controllers/collections_controller.php:943
+#, fuzzy
+msgid "collections_edit_nickname_error"
+msgstr ""
+"Your nickname contained invalid characters and was corrected. Please try "
+"again."
+
+#: views/collections/edit.thtml:156
+#, fuzzy
+msgid "collections_edit_nickname_taken"
+msgstr "Nickname Taken"
+
+#. This string is followed by a URL pointing to the collection's view page
+#: views/collections/edit.thtml:75
+#, fuzzy
+msgid "collections_edit_saved_nextstep"
+msgstr "Your collection can be accessed at this location:"
+
+#: views/collections/edit.thtml:74
+#, fuzzy
+msgid "collections_edit_saved_success"
+msgstr "Your collection was successfully saved!"
+
+#: views/collections/edit.thtml:169 views/collections/edit.thtml:300
+#: views/collections/edit.thtml:308 views/pages/js_constants.js.thtml:99
+#, fuzzy
+msgid "collections_edit_submit"
+msgstr "Update Collection"
+
+#: views/collections/edit.thtml:96 views/collections/edit.thtml:297
+#: views/pages/js_constants.js.thtml:100
+#, fuzzy
+msgid "collections_edit_submit_deletecollection"
+msgstr "Delete Collection"
+
+#: views/collections/edit.thtml:111
+#, fuzzy
+msgid "collections_edit_tabheader_addons"
+msgstr "Add-ons"
+
+#: views/collections/edit.thtml:97 views/collections/edit.thtml:113
+#, fuzzy
+msgid "collections_edit_tabheader_advanced"
+msgstr "Advanced"
+
+#: views/collections/edit.thtml:108
+#, fuzzy
+msgid "collections_edit_tabheader_details"
+msgstr "Name &amp; Details"
+
+#: views/collections/edit.thtml:109
+#, fuzzy
+msgid "collections_edit_tabheader_permissions"
+msgstr "Permissions"
+
+#: models/collection_promo.php:53
+#, fuzzy
+msgid "collections_family_tagline"
+msgstr "Add-ons can keep an eye on your kids and your calendar."
+
+#: models/collection_promo.php:53
+#, fuzzy
+msgid "collections_family_title"
+msgstr "Family Organizer"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:70
+#, fuzzy
+msgid "collections_index_a_check_out"
+msgstr "Check out Add-on Collector"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:52
+#, fuzzy
+msgid "collections_index_a_create"
+msgstr "Create a Collection"
+
+#: views/collections/detail.thtml:139 views/collections/listing.thtml:85
+#: views/search/collections.thtml:84
+#, fuzzy
+msgid "collections_index_button_go"
+msgstr "Go"
+
+#. %1$s is a URL.
+#: controllers/collections_controller.php:182
+#, fuzzy
+msgid "collections_index_filler_favorites"
+msgstr ""
+"<p><strong>You don't have any favorite collections yet.</strong></p> "
+"<p>Collections you mark as favorites can be quickly accessed from this page, "
+"and will appear in the <a href='%1$s'>Add-on Collector</a> if you've "
+"installed it.</p>"
+
+#. %1$s is a URL.
+#: controllers/collections_controller.php:167
+#, fuzzy
+msgid "collections_index_filler_mine"
+msgstr ""
+"<p>You haven't created any collections yet. Collections are easy to create "
+"and fill with your favorite add-ons. <a href='%1$s'>Try it out</a>!</p>"
+
+#: views/collections/listing.thtml:51
+#, fuzzy
+msgid "collections_index_header_collections"
+msgstr "Collections"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:60
+#, fuzzy
+msgid "collections_index_header_collector"
+msgstr "Add-on Collector"
+
+#. %1$s is a comma-separated list of author names
+#: views/elements/amo2009/collection_listing_item.thtml:84
+#: views/collections/detail.thtml:151
+#, fuzzy
+msgid "collections_index_header_created"
+msgstr "created by %1$s"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:47
+#, fuzzy
+msgid "collections_index_header_what"
+msgstr "What are Collections?"
+
+#: views/collections/detail.thtml:132 views/collections/listing.thtml:78
+#: views/search/collections.thtml:66
+#, fuzzy
+msgid "collections_index_label_sortby"
+msgstr "Sort by"
+
+#: controllers/collections_controller.php:130
+#, fuzzy
+msgid "collections_index_li_editors"
+msgstr "Editor's Picks"
+
+#: views/collections/subscribe.thtml:64
+#: controllers/collections_controller.php:140
+#, fuzzy
+msgid "collections_index_li_favorites"
+msgstr "My Favorites"
+
+#: controllers/collections_controller.php:138
+#, fuzzy
+msgid "collections_index_li_mine"
+msgstr "My Collections"
+
+#: controllers/collections_controller.php:132
+#, fuzzy
+msgid "collections_index_li_popular"
+msgstr "Popular"
+
+#: views/search/collections.thtml:74 controllers/collections_controller.php:81
+#, fuzzy
+msgid "collections_index_option_all"
+msgstr "Most popular all time"
+
+#: views/search/collections.thtml:72 controllers/collections_controller.php:78
+#, fuzzy
+msgid "collections_index_option_month"
+msgstr "Most popular this month"
+
+#: views/search/collections.thtml:76 controllers/collections_controller.php:84
+#, fuzzy
+msgid "collections_index_option_newest"
+msgstr "Newest"
+
+#: views/search/collections.thtml:70 controllers/collections_controller.php:75
+#, fuzzy
+msgid "collections_index_option_week"
+msgstr "Most popular this week"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:67
+#, fuzzy
+msgid "collections_index_p_collector"
+msgstr ""
+"There's a new way to manage and find favorite add-ons. Comment, share and "
+"sync collections, all from your browser"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:48
+#, fuzzy
+msgid "collections_index_p_what_are"
+msgstr "Collections are groups of related add-ons assembled for easy sharing."
+
+#. %s is a date in the _('date') format
+#: views/elements/collections_interactive_addon.thtml:85
+#, fuzzy, php-format
+msgid "collections_interactive_addon_added"
+msgstr "Added %s"
+
+#: models/collection_promo.php:55
+#, fuzzy
+msgid "collections_reference_tagline"
+msgstr "Add-ons can do better research online."
+
+#: models/collection_promo.php:55
+#, fuzzy
+msgid "collections_reference_title"
+msgstr "Reference Desk"
+
+#: models/collection_promo.php:52
+#, fuzzy
+msgid "collections_social_tagline"
+msgstr "Add-ons can manage your social network."
+
+#: models/collection_promo.php:52
+#, fuzzy
+msgid "collections_social_title"
+msgstr "Social Circuit"
+
+#: views/collections/subscribe.thtml:91
+#, fuzzy
+msgid "collections_subscribe_button_close"
+msgstr "Close"
+
+#: views/collections/subscribe.thtml:70
+#, fuzzy
+msgid "collections_subscribe_error"
+msgstr ""
+"An error occurred trying to add a favorite collection. Is this collection "
+"already a favorite?"
+
+#: views/collections/subscribe.thtml:96
+#, fuzzy
+msgid "collections_subscribe_label_bothersome"
+msgstr "Don't show me this message again."
+
+#. %1$s is the collection name
+#: views/collections/subscribe.thtml:60
+#, fuzzy
+msgid "collections_subscribe_success"
+msgstr "%1$s has been added to your favorite collections."
+
+#. %1$s is the link to the "My Favorites" tab on the main collections page
+#. %2$s is the localized title of the "My Favorites" tab
+#. %3$s is the link URL to the collector add-on
+#: views/collections/subscribe.thtml:62
+#, fuzzy
+msgid "collections_subscribe_success_desc"
+msgstr ""
+"You can now quickly find this collection from the <a href=\"%1$s\">%2$s</a> "
+"tab in the directory. For an even easier way to keep track of your favorite "
+"collections, try out our <a href=\"%3$s\">Add-on Collector</a> extension for "
+"Firefox."
+
+#: views/collections/listing.thtml:55
+#, fuzzy
+msgid "collections_success_delete"
+msgstr "The collection has been deleted."
+
+#: models/collection_promo.php:54
+#, fuzzy
+msgid "collections_travel_tagline"
+msgstr "Add-ons can turn you into a travel agent."
+
+#: models/collection_promo.php:54
+#, fuzzy
+msgid "collections_travel_title"
+msgstr "The Traveler's Pack"
+
+#. A collection of add-ons that is automatically built for a user. They are "automatically published" to this collection.
+#: controllers/collections_controller.php:581
+#, fuzzy
+msgid "collections_type_autopublisher"
+msgstr "Auto-publisher"
+
+#. A collection that has been chosen by an Editor as notable or exceptional
+#: controllers/collections_controller.php:582
+#, fuzzy
+msgid "collections_type_editorspick"
+msgstr "Editor's Pick"
+
+#: controllers/collections_controller.php:580
+#, fuzzy
+msgid "collections_type_normal"
+msgstr "Normal"
+
+#: views/collections/subscribe.thtml:84
+#, fuzzy
+msgid "collections_unsubscribe_error"
+msgstr ""
+"An error occurred trying to remove a favorite collection. Was this "
+"collection not a favorite?"
+
+#. %1$s is the collection name
+#: views/collections/subscribe.thtml:78
+#, fuzzy
+msgid "collections_unsubscribe_success"
+msgstr "%1$s has been removed from your favorite collections."
+
+#: models/collection_promo.php:56
+#, fuzzy
+msgid "collections_webdev_tagline"
+msgstr "Add-ons make it easier to build the perfect website."
+
+#: models/collection_promo.php:56
+#, fuzzy
+msgid "collections_webdev_title"
+msgstr "Web Developer's Toolbox"
+
+#: views/elements/amo2009/collections_sidebar_whatare.thtml:40
+#, fuzzy
+msgid "collections_whatare_header"
+msgstr "What are Collections?"
+
+#: views/elements/amo2009/collections_sidebar_whatare.thtml:45
+#, fuzzy
+msgid "collections_whatare_learnmore"
+msgstr "Read the FAQ"
+
+#: views/elements/amo2009/collections_sidebar_whatare.thtml:44
+#, fuzzy
+msgid "collections_whatare_text"
+msgstr ""
+"There’s a new way to manage and find favorite add-ons. Comment, share and "
+"sync collections, all from your browser."
+
+#: views/pages/collector_faq.thtml:61 views/pages/collector_features.thtml:67
+#, fuzzy
+msgid "collector_features_a_home"
+msgstr "Add-on Collector Home"
+
+#: views/elements/amo2009/collector_sidebar_download.thtml:46
+#, fuzzy
+msgid "collector_features_heading_download"
+msgstr "Download the Add-on Collector:"
+
+#: views/elements/amo2009/collector_sidebar_download.thtml:43
+#: views/pages/collector_firstrun.thtml:116 views/pages/collector.thtml:69
+#, fuzzy
+msgid "collector_features_img_logo"
+msgstr "Add-on Collector Logo"
+
+#: views/compatibility/dashboard.thtml:49
+#: controllers/compatibility_controller.php:72
+#, fuzzy
+msgid "compatibility_dashboard_center_header"
+msgstr "Add-on Compatibility Center"
+
+#. %1$s is the name of an application and a version. Example: Firefox 3.0
+#. %2$s is the name of an application. Example: Firefox
+#: views/compatibility/dashboard.thtml:50
+#, fuzzy
+msgid "compatibility_dashboard_intro"
+msgstr ""
+"Be prepared for the release of %1$s with the tools and information available "
+"for the %2$s Add-ons community found below."
+
+#: views/compatibility/dashboard.thtml:103
+#, fuzzy
+msgid "compatibility_dashboard_loading"
+msgstr "Loading data..."
+
+#: views/compatibility/dashboard.thtml:45
+#, fuzzy
+msgid "compatibility_dashboard_main_link"
+msgstr "Back to Main"
+
+#: views/compatibility/dashboard.thtml:100 views/compatibility/report.thtml:43
+#, fuzzy
+msgid "compatibility_dashboard_report"
+msgstr "Add-on Compatibility Report"
+
+#: views/compatibility/dashboard.thtml:53
+#: views/compatibility/dashboard.thtml:110
+#: views/compatibility/developers.thtml:43
+#, fuzzy
+msgid "compatibility_developer_info"
+msgstr "Information for Add-on Developers"
+
+#: views/compatibility/developers.thtml:66
+#, fuzzy
+msgid "compatibility_developers_adjust_maxversion"
+msgstr "Adjust maxVersion without uploading"
+
+#: views/compatibility/dashboard.thtml:124
+#, fuzzy
+msgid "compatibility_developers_check_status"
+msgstr "Check Status of My Add-ons"
+
+#. %1$s is a URL
+#. %2$s is an application and version. Example: Firefox 3.0
+#: views/compatibility/dashboard.thtml:126
+#, fuzzy
+msgid "compatibility_developers_login_first"
+msgstr ""
+"If you have add-ons hosted on Mozilla Add-ons, <a href=\"%1$s\">please "
+"login</a> to analyze the status of your add-ons for %2$s."
+
+#: views/compatibility/dashboard.thtml:114
+#, fuzzy
+msgid "compatibility_developers_mdclogo_alt"
+msgstr "Mozilla Developer Center Logo"
+
+#: views/compatibility/developers.thtml:73
+#, fuzzy
+msgid "compatibility_developers_no_addons"
+msgstr "You do not have any add-ons hosted on Mozilla Add-ons."
+
+#: views/compatibility/dashboard.thtml:133
+#: views/compatibility/developers.thtml:55
+#, fuzzy
+msgid "compatibility_developers_results"
+msgstr "Add-on Status Check Results"
+
+#: views/compatibility/dashboard.thtml:137
+#, fuzzy
+msgid "compatibility_developers_retrieving"
+msgstr "Retrieving status of hosted add-ons..."
+
+#. %1$s is a number
+#. %2$s is an application name
+#. %3$s is a number.
+#. Full example: 50 Firefox users (10% of total)
+#: views/compatibility/developers.thtml:65
+#, fuzzy
+msgid "compatibility_developers_user_count"
+msgstr "%1$s %2$s users (%3$s&#37; of total)"
+
+#: views/compatibility/report.thtml:45
+#, fuzzy
+msgid "compatibility_report_detail_intro"
+msgstr ""
+"The add-ons below make up 95% of add-on usage known to Mozilla and are "
+"ordered by their usage size."
+
+#: views/compatibility/dashboard.thtml:94
+#, fuzzy
+msgid "compatibility_report_detailed_link"
+msgstr "View Detailed Report"
+
+#. %1$s and %2$s are numbers
+#. %3$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:65
+#, fuzzy
+msgid "compatibility_report_intro"
+msgstr ""
+"Of the %1$s add-ons that make up 95&#37; of add-on usage known to Mozilla, "
+"<b>%2$s&#37;</b> are currently considered compatible with the latest builds "
+"of %3$s."
+
+#: views/compatibility/dashboard.thtml:81
+#, fuzzy
+msgid "compatibility_report_legend_alpha"
+msgstr "Alpha Versions"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:81
+#, fuzzy
+msgid "compatibility_report_legend_alpha_description"
+msgstr "Add-ons compatible with an alpha version of %1$s"
+
+#: views/compatibility/dashboard.thtml:85
+#, fuzzy
+msgid "compatibility_report_legend_beta"
+msgstr "Beta Versions"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:85
+#, fuzzy
+msgid "compatibility_report_legend_beta_description"
+msgstr "Add-ons compatible with a beta version or release candidate of %1$s"
+
+#: views/compatibility/dashboard.thtml:89
+#, fuzzy
+msgid "compatibility_report_legend_latest"
+msgstr "Latest Version"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:89
+#, fuzzy
+msgid "compatibility_report_legend_latest_description"
+msgstr "Add-ons up-to-date with the latest builds of %1$s"
+
+#: views/compatibility/dashboard.thtml:77
+#, fuzzy
+msgid "compatibility_report_legend_other"
+msgstr "Other Versions"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:77
+#, fuzzy
+msgid "compatibility_report_legend_other_description"
+msgstr "Add-ons not compatible with any version of %1$s"
+
+#: views/compatibility/dashboard.thtml:62
+#, fuzzy
+msgid "compatibility_report_title"
+msgstr "Add-on Compatibility Report"
+
+#: views/compatibility/dashboard.thtml:54
+#: views/compatibility/dashboard.thtml:144 views/compatibility/users.thtml:42
+#, fuzzy
+msgid "compatibility_user_info"
+msgstr "Information for Add-on Users"
+
+#: views/compatibility/dashboard.thtml:52
+#, fuzzy
+msgid "compatibility_view_report"
+msgstr "View Compatibility Report"
+
+#. %s is a URL
+#: views/pages/credits.thtml:142
+#, fuzzy, php-format
+msgid "credits_contributing"
+msgstr "For information on contributing, please see our %s."
+
+#: views/pages/credits.thtml:142
+#, fuzzy
+msgid "credits_contributing_wikipage"
+msgstr "wiki page"
+
+#: views/pages/credits.thtml:99
+#, fuzzy
+msgid "credits_intro"
+msgstr ""
+"Mozilla would like to thank the following people for their contributions to "
+"the addons.mozilla.org project over the years:"
+
+#: views/pages/credits.thtml:103
+#, fuzzy
+msgid "credits_section_developers"
+msgstr "Developers"
+
+#: views/pages/credits.thtml:115
+#, fuzzy
+msgid "credits_section_editors"
+msgstr "Editors"
+
+#: views/pages/credits.thtml:109
+#, fuzzy
+msgid "credits_section_localizers"
+msgstr "Localizers"
+
+#: views/pages/credits.thtml:121
+#, fuzzy
+msgid "credits_section_other_contributors"
+msgstr "Other Contributors"
+
+#: views/pages/credits.thtml:127
+#, fuzzy
+msgid "credits_section_past_developers"
+msgstr "Past Developers"
+
+#: views/pages/credits.thtml:133
+#, fuzzy
+msgid "credits_section_software"
+msgstr "Software and Images"
+
+#: views/pages/credits.thtml:136
+#, fuzzy
+msgid "credits_software_famfamfam"
+msgstr ""
+"Some icons used are from the <a href=\"http://www.famfamfam.com/lab/icons/"
+"silk/\">famfamfam Silk Icon Set</a>, licensed under a <a href=\"http://"
+"creativecommons.org/licenses/by/2.5/\">Creative Commons Attribution 2.5 "
+"License</a>."
+
+#: views/pages/credits.thtml:137
+#, fuzzy
+msgid "credits_software_timeplot"
+msgstr ""
+"Some pages use elements of <a href=\"http://www.simile-widgets.org/timeplot/"
+"\">Timeplot</a>, licensed under a <a href=\"http://simile.mit.edu/license."
+"html\">BSD License</a>."
+
+# date format string as used in PHP's strftime():
+# http://php.net/strftime
+#. date format string as used in PHP's strftime():
+#. http://php.net/strftime
+#: views/elements/collections_interactive_addon.thtml:85
+#: views/elements/amo2009/addon_version_detail.thtml:53
+#: views/elements/amo2009/homepage_addon.thtml:115
+#: views/elements/addon_version_detail.thtml:54
+#: views/elements/addon_listitem.thtml:124 views/elements/feature.thtml:106
+#: views/collections/detail.thtml:118 views/collections/edit.thtml:325
+#: views/users/info.thtml:76 views/editors/reviews_queue.thtml:57
+#: views/editors/reviews_queue.thtml:68 views/developers/dashboard.thtml:65
+#: views/developers/versions_edit.thtml:208 views/developers/versions.thtml:67
+#: views/search/rss/index.thtml:5 views/addons/rss/versions.thtml:42
+#: views/addons/display.thtml:104 views/addons/display.thtml:356
+#: views/addons/browse_thumbs.thtml:75 views/reviews/add.thtml:63
+#: views/reviews/display.thtml:74 views/reviews/display.thtml:160
+#: views/reviews/delete.thtml:54 controllers/statistics_controller.php:244
+#: controllers/collections_controller.php:1047
+#, fuzzy
+msgid "date"
+msgstr "%B %e, %Y"
+
+# date and time format string (strftime)
+#. date and time format string (strftime)
+#. http://php.net/strftime
+#: views/elements/addon_version_detail.thtml:53
+#: views/developers/discuss.thtml:52 views/developers/discuss.thtml:62
+#: views/admin/addons_status.thtml:57
+#, fuzzy
+msgid "datetime"
+msgstr "%B %e, %Y, %I:%M %p"
+
+#: views/elements/developers/actionbar.thtml:47
+#, fuzzy
+msgid "devcp_actionbar_link_details"
+msgstr "Detailed Info"
+
+#: views/elements/developers/actionbar.thtml:42
+#: views/elements/developers/actionbar.thtml:50
+#: views/developers/dashboard.thtml:64
+#, fuzzy
+msgid "devcp_actionbar_link_edit"
+msgstr "Edit Add-on"
+
+#: views/elements/developers/actionbar.thtml:51
+#, fuzzy
+msgid "devcp_actionbar_link_newversion"
+msgstr "Upload New Version"
+
+#: views/elements/developers/actionbar.thtml:44
+#: views/elements/developers/actionbar.thtml:49
+#: views/developers/dashboard.thtml:73
+#, fuzzy
+msgid "devcp_actionbar_link_stats"
+msgstr "Statistics Dashboard"
+
+#. %1$s is a filename, e.g. "foo.txt"
+#. %2$s is the extension, e.g. ".txt"
+#. %3$s is a list of valid extensions, like ".png, .jpg, .gif"
+#: controllers/developers_controller.php:1361
+#, fuzzy
+msgid "devcp_add_previews_extension_error"
+msgstr "File %1$s has an invalid extension (%2$s). Allowed extensions: %3$s"
+
+#. %s is the filename.
+#: controllers/developers_controller.php:1394
+#, fuzzy
+msgid "devcp_add_previews_save_error"
+msgstr "File %s could not be saved to the database. Please try again."
+
+#. %1$s is the preview ID number, %2$s is the filename.
+#: controllers/developers_controller.php:1389
+#, fuzzy
+msgid "devcp_add_previews_success_replace"
+msgstr "Preview %1$s was replaced with file %2$s successfully."
+
+#. %s is the filename.
+#: controllers/developers_controller.php:1391
+#, fuzzy
+msgid "devcp_add_previews_success_upload"
+msgstr "File %s was uploaded successfully. You can add a caption below."
+
+#: controllers/components/developers.php:1163
+#, fuzzy
+msgid "devcp_additem_addontype_autodetect"
+msgstr "(auto-detect)"
+
+#: views/elements/developers/additem.thtml:76
+#, fuzzy
+msgid "devcp_additem_linktitle_opensin_newwindow"
+msgstr "Opens in a new window"
+
+#: views/elements/developers/additem.thtml:41
+#, fuzzy
+msgid "devcp_additem_sidebar_title"
+msgstr "Submit Add-on"
+
+#: views/elements/developers/additem.thtml:53
+#, fuzzy
+msgid "devcp_additem_step0_newlink"
+msgstr "Developer Agreement"
+
+#: views/elements/developers/additem.thtml:46
+#, fuzzy
+msgid "devcp_additem_step1_link"
+msgstr "Step 1: Upload"
+
+#: views/elements/developers/additem.thtml:47
+#, fuzzy
+msgid "devcp_additem_step2_link"
+msgstr "Step 2: Add-on Details"
+
+#: views/elements/developers/additem.thtml:48
+#, fuzzy
+msgid "devcp_additem_step3_link"
+msgstr "Step 3: Version Details"
+
+#: views/elements/developers/additem.thtml:49
+#, fuzzy
+msgid "devcp_additem_step4_link"
+msgstr "Step 4: Localization"
+
+#: views/elements/developers/additem.thtml:50
+#, fuzzy
+msgid "devcp_additem_step5_link"
+msgstr "Step 5: Success"
+
+#: views/elements/developers/additem.thtml:76
+#, fuzzy
+msgid "devcp_additem_submissionhelp_link"
+msgstr "Submission Help"
+
+#: controllers/previews_controller.php:168
+#: controllers/previews_controller.php:277
+#, fuzzy
+msgid "devcp_addon_field_preview_caption_displaytitle"
+msgstr "Preview Caption"
+
+#: views/developers/addon_status.thtml:177
+#, fuzzy
+msgid "devcp_addon_status_action_activate"
+msgstr "Make Active"
+
+#: views/developers/addon_status.thtml:178
+#, fuzzy
+msgid "devcp_addon_status_action_activate_description"
+msgstr ""
+"Make your add-on active for it to show up in public listings and enable the "
+"update check service."
+
+#: views/developers/addon_status.thtml:135
+#, fuzzy
+msgid "devcp_addon_status_action_complete"
+msgstr "Complete Add-on"
+
+#: views/developers/addon_status.thtml:136
+#, fuzzy
+msgid "devcp_addon_status_action_complete_description"
+msgstr "Complete your add-on and move to the Sandbox"
+
+#: views/developers/addon_status.thtml:181
+#, fuzzy
+msgid "devcp_addon_status_action_deactivate"
+msgstr "Make Inactive"
+
+#: views/developers/addon_status.thtml:182
+#, fuzzy
+msgid "devcp_addon_status_action_deactivate_description"
+msgstr ""
+"Make your add-on inactive to hide it from all public listings and disable "
+"the update check service."
+
+#: views/developers/addon_status.thtml:143
+#, fuzzy
+msgid "devcp_addon_status_action_move"
+msgstr "Move to Sandbox"
+
+#: views/developers/addon_status.thtml:144
+#, fuzzy
+msgid "devcp_addon_status_action_move_description"
+msgstr "Move your add-on back to the Sandbox. This is reversible."
+
+#: views/developers/addon_status.thtml:139
+#, fuzzy
+msgid "devcp_addon_status_action_nominate"
+msgstr "Nominate for Public"
+
+#: views/developers/addon_status.thtml:140
+#, fuzzy
+msgid "devcp_addon_status_action_nominate_description"
+msgstr "Nominate your add-on to become Public"
+
+#: views/developers/addon_status.thtml:147
+#, fuzzy
+msgid "devcp_addon_status_action_public"
+msgstr "Make Public"
+
+#: views/developers/addon_status.thtml:148
+#, fuzzy
+msgid "devcp_addon_status_action_public_description"
+msgstr "Make your add-on Public again."
+
+#: views/developers/addon_status.thtml:169
+#, fuzzy
+msgid "devcp_addon_status_active"
+msgstr ""
+"Your add-on is <span class=\"inactive-0\">Active</span>. This means your add-"
+"on is showing up in all available listings appropriate for its status above."
+
+#: views/developers/addon_status.thtml:111
+#, fuzzy
+msgid "devcp_addon_status_completion_disabled"
+msgstr ""
+"Please fulfill the criteria above before you can complete your add-on and "
+"move it to the <span class=\"status-1\">Sandbox</span>."
+
+#: views/developers/addon_status.thtml:108
+#, fuzzy
+msgid "devcp_addon_status_completion_enabled"
+msgstr ""
+"You may now complete your add-on and move it to the <span class=\"status-1"
+"\">Sandbox</span> by clicking the button below."
+
+#: views/developers/addon_status.thtml:102
+#, fuzzy
+msgid "devcp_addon_status_criteria_category"
+msgstr "At least one category selected"
+
+#: views/developers/addon_status.thtml:101
+#, fuzzy
+msgid "devcp_addon_status_criteria_description"
+msgstr "Add-on Description required"
+
+#: views/developers/addon_status.thtml:99
+#, fuzzy
+msgid "devcp_addon_status_criteria_name"
+msgstr "Add-on Name required"
+
+#: views/developers/addon_status.thtml:120
+#, fuzzy
+msgid "devcp_addon_status_criteria_prerelease"
+msgstr "Add-on is not marked as pre-release."
+
+#: views/developers/addon_status.thtml:119
+#, fuzzy
+msgid "devcp_addon_status_criteria_preview"
+msgstr "At least one preview image required for extensions and themes."
+
+#: views/developers/addon_status.thtml:100
+#, fuzzy
+msgid "devcp_addon_status_criteria_summary"
+msgstr "Add-on Summary required"
+
+#. %s is the status in a span, e.g. "<span>_('Public')</span>".
+#: views/developers/addon_status.thtml:58
+#, fuzzy
+msgid "devcp_addon_status_header"
+msgstr "Add-on Status: %s"
+
+#: views/developers/addon_status.thtml:152
+#: views/developers/addon_status.thtml:173
+#, fuzzy
+msgid "devcp_addon_status_header_actions"
+msgstr "Available Actions"
+
+#: views/developers/addon_status.thtml:168
+#, fuzzy
+msgid "devcp_addon_status_header_active"
+msgstr "Active Status: <span class=\"inactive-0\">Active</span>"
+
+#: views/developers/addon_status.thtml:97
+#, fuzzy
+msgid "devcp_addon_status_header_criteria"
+msgstr "Add-on Completion Criteria"
+
+#: views/developers/addon_status.thtml:164
+#, fuzzy
+msgid "devcp_addon_status_header_inactive"
+msgstr "Active Status: <span class=\"inactive-1\">Inactive</span>"
+
+#: views/developers/addon_status.thtml:117
+#, fuzzy
+msgid "devcp_addon_status_header_nomination"
+msgstr "Public Nomination Criteria"
+
+#: views/developers/addon_status.thtml:190
+#, fuzzy
+msgid "devcp_addon_status_header_trusted"
+msgstr "Trusted Status: <span class=\"status-4\">Trusted</span>"
+
+#: views/developers/addon_status.thtml:165
+#, fuzzy
+msgid "devcp_addon_status_inactive"
+msgstr ""
+"Your add-on is <span class=\"inactive-1\">Inactive</span>. This means your "
+"add-on will not show up in any listing, regardless of its status above. "
+"Updates are <b>not</b> being provided to your add-on through the update "
+"check service."
+
+#: views/developers/addon_status.thtml:128
+#, fuzzy
+msgid "devcp_addon_status_nominate_disabled"
+msgstr ""
+"Please fulfill the criteria above before nominating your add-on to become "
+"<span class=\"status-4\">Public</span>."
+
+#: views/developers/addon_status.thtml:125
+#, fuzzy
+msgid "devcp_addon_status_nominate_enabled"
+msgstr ""
+"You may now nominate your add-on for <span class=\"status-4\">Public</span> "
+"by clicking the button below."
+
+#: views/developers/addon_status.thtml:64
+#, fuzzy
+msgid "devcp_addon_status_public"
+msgstr "Public"
+
+#: views/developers/addon_status.thtml:63
+#, fuzzy
+msgid "devcp_addon_status_sandbox"
+msgstr "Sandbox"
+
+#. %s is an email address.
+#: views/developers/addon_status.thtml:89
+#, fuzzy
+msgid "devcp_addon_status_switch_disabled"
+msgstr ""
+"Your add-on was <span class=\"status-5\">Disabled</span> by an administrator "
+"and cannot be used. If you have any questions, please e-mail %s."
+
+#: views/developers/addon_status.thtml:67
+#, fuzzy
+msgid "devcp_addon_status_switch_incomplete"
+msgstr ""
+"Your add-on is currently <span class=\"status-0\">Incomplete</span>. This "
+"means your add-on is not showing up on any portion of the site or update "
+"check service. You may come to this page to complete your add-on after it "
+"meets the criteria below for completion and transfer to the <span class="
+"\"status-1\">Sandbox</span>."
+
+#. %s is a number, perhaps 42.
+#: views/developers/addon_status.thtml:77
+#, fuzzy
+msgid "devcp_addon_status_switch_nominated"
+msgstr ""
+"Your add-on is currently nominated to become <span class=\"status-4"
+"\">Public</span> and is awaiting editor review. There are currently %s other "
+"add-ons in the nomination queue."
+
+#. %s is an email address.
+#: views/developers/addon_status.thtml:81
+#, fuzzy
+msgid "devcp_addon_status_switch_pending"
+msgstr ""
+"Your add-on is pending. This shouldn't have happened. Please e-mail %s with "
+"your add-on ID and state this error."
+
+#: views/developers/addon_status.thtml:85
+#, fuzzy
+msgid "devcp_addon_status_switch_public"
+msgstr ""
+"Your add-on is <span class=\"status-4\">Public</span>, which means it will "
+"show up in all listings and searches and can be downloaded without "
+"restriction. Updates are being provided to your add-on through the update "
+"check service."
+
+#: views/developers/addon_status.thtml:71
+#: views/developers/addon_status.thtml:75
+#, fuzzy
+msgid "devcp_addon_status_switch_sandbox"
+msgstr ""
+"Your add-on is in the <span class=\"status-1\">Sandbox</span>, which means "
+"it will show up in listings and searches, but users must log in to download "
+"it. Updates are <b>not</b> being provided to your add-on through the update "
+"check service."
+
+#. %s is the add-on name.
+#: views/developers/addon_status_nominate.thtml:43
+#: views/developers/addon_status_confirm.thtml:43
+#: views/developers/addon_status.thtml:43
+#, fuzzy
+msgid "devcp_addon_status_title"
+msgstr "%s Status"
+
+#: views/developers/addon_status.thtml:191
+#, fuzzy
+msgid "devcp_addon_status_trusted"
+msgstr ""
+"Your add-on is <span class=\"status-4\">Trusted</span>. This means you can "
+"submit updates to your add-on without editor review."
+
+#: views/developers/dashboard.thtml:68
+#, fuzzy
+msgid "devcp_dashboard_active"
+msgstr "Active"
+
+#. %1$s is the add-on type string
+#. %2$s is Inactive or Active in a <span>
+#. %3$s is the addon's public status (Public, In Sandbox, ...) in a <span>
+#: views/developers/dashboard.thtml:69
+#, fuzzy
+msgid "devcp_dashboard_addontype_status"
+msgstr "%1$s currenty %2$s and %3$s"
+
+#: views/developers/dashboard.thtml:67
+#, fuzzy
+msgid "devcp_dashboard_change_status"
+msgstr "Change Status"
+
+#. %s is the addons email address.
+#: views/developers/dashboard.thtml:99
+#, fuzzy
+msgid "devcp_dashboard_disabled_questions"
+msgstr ""
+"Your add-on was disabled by an administrator and cannot be used. If you "
+"have any questions, please email %s."
+
+#. %s is the (localized) add-on status string in a span, e.g. "Disabled"
+#: views/developers/dashboard.thtml:98
+#, fuzzy
+msgid "devcp_dashboard_disabled_status"
+msgstr "Add-on Status: %s"
+
+#: views/developers/dashboard.thtml:43
+#, fuzzy
+msgid "devcp_dashboard_header_main"
+msgstr "Developer Dashboard"
+
+#: views/developers/dashboard.thtml:110
+#, fuzzy
+msgid "devcp_dashboard_header_welcome"
+msgstr "Welcome to the Developer Dashboard"
+
+#: views/developers/dashboard.thtml:68
+#, fuzzy
+msgid "devcp_dashboard_inactive"
+msgstr "Inactive"
+
+#. %s is a date in the _('date') format
+#: views/developers/dashboard.thtml:65
+#, fuzzy
+msgid "devcp_dashboard_last_edited"
+msgstr "Last edited on %s"
+
+#: views/developers/dashboard.thtml:111
+#, fuzzy
+msgid "devcp_dashboard_learn"
+msgstr ""
+"You don't currently have any add-ons hosted on Mozilla Add-ons. To learn how "
+"the process works and submit your first add-on, click Get Started below."
+
+#: views/developers/dashboard.thtml:112
+#, fuzzy
+msgid "devcp_dashboard_start"
+msgstr "Get Started"
+
+#: views/developers/dashboard.thtml:82
+#, fuzzy
+msgid "devcp_dashboard_versions"
+msgstr "Versions and Files"
+
+#: views/developers/dashboard.thtml:91
+#, fuzzy
+msgid "devcp_dashboard_versions_new"
+msgstr "Upload a new version"
+
+#. %s is the preview ID number.
+#: controllers/developers_controller.php:1415
+#, fuzzy
+msgid "devcp_delete_previews_error"
+msgstr "Preview %s could not be deleted from the database. Please try again."
+
+#. %s is the preview ID number.
+#: controllers/developers_controller.php:1413
+#, fuzzy
+msgid "devcp_delete_previews_success"
+msgstr "Preview %s has been deleted successfully."
+
+#: controllers/developers_controller.php:1089
+#, fuzzy
+msgid "devcp_delete_version_priv_error"
+msgstr "You do not have privileges to delete versions or files."
+
+#. %1$s is the count of files, a number
+#. %2$s is a status string like _('Public') or _('Incomplete')
+#: controllers/components/amo.php:549
+#, fuzzy
+msgid "devcp_describe_version_status"
+msgid_plural "devcp_describe_version_status"
+msgstr[0] "%1$s %2$s file"
+msgstr[1] "%1$s %2$s files"
+
+#. %s is a version number. Example: 3.0
+#: views/developers/versions.thtml:65
+#, fuzzy, php-format
+msgid "devcp_details_version"
+msgstr "Version %s"
+
+#: views/developers/discuss.thtml:68
+#, fuzzy
+msgid "devcp_discuss_addreply_header"
+msgstr "Add Reply"
+
+#: views/developers/discuss.thtml:57
+#, fuzzy
+msgid "devcp_discuss_allreplies_header"
+msgstr "Replies"
+
+#. notice when an error occurs saving a discussion reply
+#. %1 is the email address (linked) for the amo-editors list
+#: views/developers/discuss.thtml:70
+#, fuzzy
+msgid "devcp_discuss_error_notice"
+msgstr ""
+"There was an error saving your reply. Please contact %1$s about the issue."
+
+#. %1 is the add-on name, %2 is the add-on's version number currently being reviewed by an editor
+#: views/developers/discuss.thtml:46
+#, fuzzy
+msgid "devcp_discuss_intro"
+msgstr ""
+"A Mozilla Add-ons Editor requested further information from you regarding "
+"version %2$s of your add-on %1$s."
+
+#. %1 is the add-on name
+#: views/developers/discuss.thtml:43
+#, fuzzy
+msgid "devcp_discuss_pagetitle"
+msgstr "Provide More Information For the Add-on Review of %1$s"
+
+#. submit button text
+#: views/developers/discuss.thtml:79
+#, fuzzy
+msgid "devcp_discuss_submit_reply"
+msgstr "Submit Reply"
+
+#: views/developers/discuss.thtml:72
+#, fuzzy
+msgid "devcp_discuss_success_message"
+msgstr ""
+"Your reply was successfully saved. The other participants of the discussion "
+"will be notified by email."
+
+#. in an author/editor discussion about an add-on to be reviewed:
+#. %1 is the commenter's user name (linked).
+#. %2 is the full date the comment was made.
+#: views/developers/discuss.thtml:52 views/developers/discuss.thtml:62
+#, fuzzy
+msgid "devcp_discuss_writtenby"
+msgstr "written by %1$s on %2$s"
+
+#: views/developers/addon_edit_authors.thtml:72
+#: views/developers/addon_edit_authors.thtml:81
+#, fuzzy
+msgid "devcp_edit_authors_add_author"
+msgstr "Add New Author"
+
+#: views/developers/addon_edit_authors.thtml:96
+#, fuzzy
+msgid "devcp_edit_authors_add_author_button"
+msgstr "Add Author"
+
+#: views/developers/addon_edit_authors.thtml:83
+#, fuzzy
+msgid "devcp_edit_authors_add_email"
+msgstr "Author Account Email:"
+
+#: views/developers/addon_edit_authors.thtml:98
+#, fuzzy
+msgid "devcp_edit_authors_add_loading"
+msgstr "Checking account email..."
+
+#: views/developers/addon_edit_authors.thtml:70
+#, fuzzy
+msgid "devcp_edit_authors_click_save"
+msgstr "Click the Update Authors button below to save."
+
+#: views/developers/addon_edit_authors.thtml:58
+#, fuzzy
+msgid "devcp_edit_authors_header_current"
+msgstr "Current Authors"
+
+#: views/developers/addon_edit_authors.thtml:50
+#, fuzzy
+msgid "devcp_edit_authors_header_manage"
+msgstr "Manage Add-on Authors"
+
+#: views/developers/addon_edit_authors.thtml:93
+#, fuzzy
+msgid "devcp_edit_authors_label_add_listed"
+msgstr "List as author in pubilc display pages"
+
+#: views/developers/addon_edit_authors.thtml:89
+#, fuzzy
+msgid "devcp_edit_authors_label_developer"
+msgstr ""
+"<strong>Developer</strong> - Can manage all aspects of the add-on listing, "
+"except for adding and removing other authors."
+
+#: views/developers/addon_edit_authors.thtml:88
+#, fuzzy
+msgid "devcp_edit_authors_label_owner"
+msgstr ""
+"<strong>Owner</strong> - Can manage all aspects of the add-on listing, "
+"including adding and removing other authors."
+
+#: views/developers/addon_edit_authors.thtml:90
+#, fuzzy
+msgid "devcp_edit_authors_label_viewer"
+msgstr ""
+"<strong>Viewer</strong> - Can view add-on developer listing and statistics, "
+"but can't make any changes."
+
+#. Placeholder for the empty option in a <select>.
+#: views/developers/addon_edit_categories.thtml:69
+#, fuzzy
+msgid "devcp_edit_authors_option_empty"
+msgstr "----------------"
+
+#: views/developers/addon_edit_authors.thtml:86
+#, fuzzy
+msgid "devcp_edit_authors_select_role"
+msgstr "Select a role for the author:"
+
+#. Column name in a table.
+#: views/developers/addon_edit_authors.thtml:62
+#, fuzzy
+msgid "devcp_edit_authors_th_author"
+msgstr "Author"
+
+#. Column name in a table.
+#: views/developers/addon_edit_authors.thtml:64
+#, fuzzy
+msgid "devcp_edit_authors_th_listed"
+msgstr "Listed"
+
+#. Column name in a table.
+#: views/developers/addon_edit_authors.thtml:63
+#, fuzzy
+msgid "devcp_edit_authors_th_role"
+msgstr "Role"
+
+#: views/developers/addon_edit_authors.thtml:77
+#, fuzzy
+msgid "devcp_edit_authors_update_author"
+msgstr "Update authors"
+
+#: views/developers/addon_edit_categories.thtml:99
+#, fuzzy
+msgid "devcp_edit_categories_button_update"
+msgstr "Update Categories"
+
+#: views/developers/addon_edit_categories.thtml:88
+#, fuzzy
+msgid "devcp_edit_categories_does_not_fit"
+msgstr "My add-on doesn't fit into any available categories."
+
+#. %s is the application name (Firefox, Thunderbird).
+#: views/developers/addon_edit_categories.thtml:61
+#, fuzzy
+msgid "devcp_edit_categories_header_application"
+msgstr "%s Categories"
+
+#: views/developers/addon_edit_categories.thtml:49
+#, fuzzy
+msgid "devcp_edit_categories_header_manage"
+msgstr "Manage Add-on Categories"
+
+#: views/developers/addon_edit_categories.thtml:91
+#, fuzzy
+msgid "devcp_edit_categories_hover"
+msgstr "Hover over a category to see its description."
+
+#. %s is the category number (1, 2, 3).
+#: views/developers/addon_edit_categories.thtml:67
+#, fuzzy
+msgid "devcp_edit_categories_label_category_num"
+msgstr "Category %s"
+
+#: views/developers/addon_edit_categories.thtml:94
+#: views/developers/addon_edit_categories.thtml:103
+#, fuzzy
+msgid "devcp_edit_categories_none_available"
+msgstr "No categories are available for this add-on type and application."
+
+#: views/developers/addon_edit_categories.thtml:86
+#, fuzzy
+msgid "devcp_edit_categories_other"
+msgstr ""
+"Place your add-on into this category only if it does not fit into any other "
+"available categories."
+
+#. %s is the application name (Firefox, Thunderbird).
+#: views/developers/addon_edit_categories.thtml:63
+#, fuzzy
+msgid "devcp_edit_categories_select_application_categories"
+msgstr "Select up to three %s categories for your add-on"
+
+#: views/developers/addon_edit.thtml:47
+#, fuzzy
+msgid "devcp_edit_dd_manage_authors"
+msgstr "Add or remove users that can manage this add-on."
+
+#: views/developers/addon_edit.thtml:49
+#, fuzzy
+msgid "devcp_edit_dd_manage_categories"
+msgstr ""
+"Select the relevant categories for each application your add-on supports."
+
+#: views/developers/addon_edit.thtml:51
+#, fuzzy
+msgid "devcp_edit_dd_manage_description"
+msgstr ""
+"Add and modify translations for your add-on's summary, description, end-user "
+"license, and privacy policy."
+
+#: views/developers/addon_edit.thtml:53
+#, fuzzy
+msgid "devcp_edit_dd_manage_properties"
+msgstr "Change your add-on's name, homepage, icon, and other flags."
+
+#: views/developers/addon_edit_descriptions.thtml:116
+#, fuzzy
+msgid "devcp_edit_description_button_update"
+msgstr "Update Descriptions"
+
+#: views/developers/addon_edit_descriptions.thtml:115
+#, fuzzy
+msgid "devcp_edit_description_correct_error"
+msgstr "Please correct the errors above indicated in red."
+
+#: views/developers/addon_edit_descriptions.thtml:51
+#, fuzzy
+msgid "devcp_edit_descriptions_header"
+msgstr "Edit Add-on Descriptions"
+
+#: views/developers/addon_edit_descriptions.thtml:94
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_comments_description"
+msgstr ""
+"Any information end users may want to know that isn't necessarily applicable "
+"to the add-on summary or description. Common uses include listing known "
+"major bugs, information on how to report bugs, anticipated release date of a "
+"new version, etc."
+
+#: views/developers/addon_edit_descriptions.thtml:93
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_comments_name"
+msgstr "Developer Comments"
+
+#: views/developers/addon_edit_descriptions.thtml:86
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_description_description"
+msgstr ""
+"The description of your add-on is a longer explanation of features, "
+"functionality, and other relevant information. It is displayed under the "
+"summary on the add-on's display page."
+
+#: views/developers/addon_edit_descriptions.thtml:85
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_description_name"
+msgstr "Add-on Description"
+
+#: views/developers/addon_edit_descriptions.thtml:103
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_eula_description"
+msgstr ""
+"If your add-on has an End-User License Agreement (EULA), please enter its "
+"text below. If set below, users will be required to agree to this before "
+"installing your add-on. Please note that a EULA is not the same as a code "
+"license such as GPL or MPL."
+
+#: views/developers/addon_edit_descriptions.thtml:102
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_eula_name"
+msgstr "End-User License Agreement"
+
+#: views/developers/addon_edit_descriptions.thtml:112
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_privacy_description"
+msgstr ""
+"If your add-on has a privacy policy, enter its text here. Your add-on's "
+"display page will display a link to the policy."
+
+#: views/developers/addon_edit_descriptions.thtml:111
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_privacy_name"
+msgstr "Privacy Policy"
+
+#: views/developers/addon_edit_descriptions.thtml:78
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_summary_description"
+msgstr ""
+"The summary is a short explanation of your add-on's basic functionality that "
+"is displayed in search and browse listings, as well as at the top of your "
+"add-on's display page. <strong>Limit of 250 characters.</strong>"
+
+#: views/developers/addon_edit_descriptions.thtml:77
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_summary_name"
+msgstr "Add-on Summary"
+
+#: views/developers/addon_edit.thtml:46
+#, fuzzy
+msgid "devcp_edit_dt_manage_authors"
+msgstr "Manage Add-on Authors"
+
+#: views/developers/addon_edit.thtml:48
+#, fuzzy
+msgid "devcp_edit_dt_manage_categories"
+msgstr "Manage Add-on Categories"
+
+#: views/developers/addon_edit.thtml:50
+#, fuzzy
+msgid "devcp_edit_dt_manage_descriptions"
+msgstr "Manage Add-on Descriptions"
+
+#: views/developers/addon_edit.thtml:52
+#, fuzzy
+msgid "devcp_edit_dt_manage_properties"
+msgstr "Manage Add-on Properties"
+
+#: views/developers/addon_edit_properties.thtml:170
+#, fuzzy
+msgid "devcp_edit_label_externalsoftware"
+msgstr "This add-on requires external software"
+
+#: views/developers/addon_edit_properties.thtml:205
+#, fuzzy
+msgid "devcp_edit_label_locale_disambiguation"
+msgstr "Additional Locale Info"
+
+#: views/developers/addon_edit_properties.thtml:168
+#, fuzzy
+msgid "devcp_edit_label_prerelease"
+msgstr "This is a pre-release"
+
+#: views/developers/addon_edit_properties.thtml:169
+#, fuzzy
+msgid "devcp_edit_label_sitespecific"
+msgstr "This is a site-specific add-on"
+
+#: views/developers/addon_edit_properties.thtml:202
+#, fuzzy
+msgid "devcp_edit_label_target_locale"
+msgstr "Target Locale"
+
+#: views/developers/addon_edit_properties.thtml:212
+#, fuzzy
+msgid "devcp_edit_properties_button_update"
+msgstr "Update Properties"
+
+#: views/developers/addon_edit_properties.thtml:198
+#, fuzzy
+msgid "devcp_edit_properties_change_guid"
+msgstr "Only change if you understand all of the consequences."
+
+#: views/developers/addon_edit_properties.thtml:109
+#, fuzzy
+msgid "devcp_edit_properties_current_icon"
+msgstr "Current Icon"
+
+#: views/developers/addon_edit_properties.thtml:85
+#, fuzzy
+msgid "devcp_edit_properties_default_locale"
+msgstr ""
+"An add-on's default locale is the main locale in which translations must be "
+"present. If translations for your add-on's descriptions are unavailable in a "
+"user's selected language, they will fall back to this default locale."
+
+#: views/developers/addon_edit_properties.thtml:167
+#, fuzzy
+msgid "devcp_edit_properties_flags"
+msgstr "These flags are used to filter and classify add-ons."
+
+#: views/developers/addon_edit_properties.thtml:174
+#, fuzzy
+msgid "devcp_edit_properties_guid"
+msgstr ""
+"The GUID of your add-on is specified in its install.rdf and uniquely "
+"identifies it. You cannot change your GUID once it is listed on Mozilla Add-"
+"ons."
+
+#: views/developers/addon_edit_properties.thtml:53
+#, fuzzy
+msgid "devcp_edit_properties_header"
+msgstr "Edit Add-on Properties"
+
+#: views/developers/addon_edit_properties.thtml:186
+#, fuzzy
+msgid "devcp_edit_properties_header_addon_type"
+msgstr "Add-on Type"
+
+#: views/developers/addon_edit_properties.thtml:181
+#, fuzzy
+msgid "devcp_edit_properties_header_admin_settings"
+msgstr "Admin Settings"
+
+#: views/developers/addon_edit_properties.thtml:84
+#, fuzzy
+msgid "devcp_edit_properties_header_default_locale"
+msgstr "Default Locale"
+
+#: views/developers/addon_edit_properties.thtml:166
+#, fuzzy
+msgid "devcp_edit_properties_header_flags"
+msgstr "Add-on Flags"
+
+#: views/developers/addon_edit_properties.thtml:173
+#: views/developers/addon_edit_properties.thtml:197
+#, fuzzy
+msgid "devcp_edit_properties_header_guid"
+msgstr "Add-on GUID"
+
+#: views/developers/addon_edit_properties.thtml:104
+#, fuzzy
+msgid "devcp_edit_properties_header_icon"
+msgstr "Add-on Icon"
+
+#: views/developers/addon_edit_properties.thtml:159
+#, fuzzy
+msgid "devcp_edit_properties_header_other_settings"
+msgstr "Other Settings"
+
+#. A header on the admin page to toggle trusted status.
+#: views/developers/addon_edit_properties.thtml:182
+#, fuzzy
+msgid "devcp_edit_properties_header_trusted"
+msgstr "Trusted Add-on?"
+
+#: views/developers/addon_edit_properties.thtml:160
+#, fuzzy
+msgid "devcp_edit_properties_header_view_source"
+msgstr "View Source Online"
+
+#. %s is a comma-separated list of image extensions ".png, .jpg"
+#: views/developers/addon_edit_properties.thtml:106
+#, fuzzy
+msgid "devcp_edit_properties_icon"
+msgstr ""
+"The add-on icon is a small image that is displayed next to your add-on's "
+"name in browse and search results, display pages, and in the add-on "
+"installation dialog. The image will automatically be resized to 32 x 32 "
+"pixels. Please use one of the following image types: %s"
+
+#: views/developers/addon_edit_properties.thtml:171
+#, fuzzy
+msgid "devcp_edit_properties_label_binary"
+msgstr "This add-on contains binary components"
+
+#: views/developers/addon_edit_properties.thtml:185
+#, fuzzy
+msgid "devcp_edit_properties_label_not_trusted"
+msgstr "Not Trusted"
+
+#: views/developers/addon_edit_properties.thtml:184
+#, fuzzy
+msgid "devcp_edit_properties_label_trusted"
+msgstr "Trusted"
+
+#: views/developers/addon_edit_properties.thtml:110
+#, fuzzy
+msgid "devcp_edit_properties_new_icon"
+msgstr "New Icon"
+
+#: views/developers/addon_edit_properties.thtml:118
+#, fuzzy
+msgid "devcp_edit_properties_remove_icon"
+msgstr "Remove Icon"
+
+#: views/developers/addon_edit_properties.thtml:136
+#, fuzzy
+msgid "devcp_edit_properties_transbox_homepage_description"
+msgstr ""
+"If your add-on has another homepage, enter its address here. Adding other "
+"translations is not necessary unless your website is localized into other "
+"languages."
+
+#: views/developers/addon_edit_properties.thtml:135
+#, fuzzy
+msgid "devcp_edit_properties_transbox_homepage_name"
+msgstr "Add-on Homepage"
+
+#: views/developers/addon_edit_properties.thtml:79
+#, fuzzy
+msgid "devcp_edit_properties_transbox_name_description"
+msgstr "The name of your add-on is displayed everywhere your add-on is listed."
+
+#: views/developers/addon_edit_properties.thtml:78
+#, fuzzy
+msgid "devcp_edit_properties_transbox_name_name"
+msgstr "Add-on Name"
+
+#: views/developers/addon_edit_properties.thtml:145
+#, fuzzy
+msgid "devcp_edit_properties_transbox_supportemail_description"
+msgstr ""
+"If you have an email address for support inquiries, enter it here. Adding "
+"other translations is not necessary unless you have different email "
+"addresses for different languages."
+
+#: views/developers/addon_edit_properties.thtml:144
+#, fuzzy
+msgid "devcp_edit_properties_transbox_supportemail_name"
+msgstr "Support Email Address"
+
+#: views/developers/addon_edit_properties.thtml:154
+#, fuzzy
+msgid "devcp_edit_properties_transbox_supporturl_description"
+msgstr ""
+"If your add-on has a support website or forum, enter its address here. "
+"Adding other translations is not necessary unless your website is localized "
+"into other languages."
+
+#: views/developers/addon_edit_properties.thtml:153
+#, fuzzy
+msgid "devcp_edit_properties_transbox_supporturl_name"
+msgstr "Support Website"
+
+#: views/developers/addon_edit_properties.thtml:183
+#, fuzzy
+msgid "devcp_edit_properties_trusted"
+msgstr "Trusted add-ons can become public without Editor review."
+
+#. %s is href="..." and should stay in the <a> tag.
+#: views/developers/addon_edit_properties.thtml:119
+#, fuzzy
+msgid "devcp_edit_properties_undelete"
+msgstr "Icon will be deleted on save. <a %s>Cancel?</a>"
+
+#: views/developers/addon_edit_properties.thtml:161
+#, fuzzy
+msgid "devcp_edit_properties_view_source"
+msgstr ""
+"The source of your add-on files can be viewed online by any logged in user "
+"if you wish."
+
+#: views/developers/addon_edit_properties.thtml:162
+#, fuzzy
+msgid "devcp_edit_properties_view_source_allow"
+msgstr "Allow online source viewing"
+
+#: views/developers/addon_edit_properties.thtml:163
+#, fuzzy
+msgid "devcp_edit_properties_view_source_do_not_allow"
+msgstr "Do not allow online source viewing"
+
+#: views/elements/developers/editbox.thtml:46
+#, fuzzy
+msgid "devcp_editbox_authors"
+msgstr "Authors"
+
+#: views/elements/developers/editbox.thtml:47
+#, fuzzy
+msgid "devcp_editbox_categories"
+msgstr "Categories"
+
+#: views/elements/developers/editbox.thtml:52
+#, fuzzy
+msgid "devcp_editbox_change_status"
+msgstr "Change Status"
+
+#: views/elements/developers/editbox.thtml:48
+#, fuzzy
+msgid "devcp_editbox_descriptions"
+msgstr "Descriptions"
+
+#: views/elements/developers/editbox.thtml:43
+#, fuzzy
+msgid "devcp_editbox_edit_addon"
+msgstr "Edit Add-on"
+
+#: views/elements/developers/editbox.thtml:57
+#, fuzzy
+msgid "devcp_editbox_new_version"
+msgstr "New Version"
+
+#: views/elements/developers/editbox.thtml:49
+#, fuzzy
+msgid "devcp_editbox_properties"
+msgstr "Properties"
+
+#: views/elements/developers/editbox.thtml:60
+#, fuzzy
+msgid "devcp_editbox_screenshots"
+msgstr "Preview Screenshots"
+
+#: views/elements/developers/editbox.thtml:53
+#, fuzzy
+msgid "devcp_editbox_statistics_dashboard"
+msgstr "Statistics Dashboard"
+
+#: views/elements/developers/editbox.thtml:54
+#, fuzzy
+msgid "devcp_editbox_versions"
+msgstr "Versions and Files"
+
+#: views/elements/developers/editbox.thtml:42
+#, fuzzy
+msgid "devcp_editbox_view_listing"
+msgstr "View Listing"
+
+#: views/elements/developers/editorsmenu.thtml:59
+#, fuzzy
+msgid "devcp_editorsqueue_featured"
+msgstr "Featured Add-ons"
+
+# %1 is the review count
+#. %1 is the review count
+#: views/elements/developers/editorsqueue.thtml:42
+#: views/elements/developers/editorsmenu.thtml:56
+#, fuzzy, php-format
+msgid "devcp_editorsqueue_moderatedreviews"
+msgid_plural "devcp_editorsqueue_moderatedreviews"
+msgstr[0] "Moderated Reviews (%s)"
+msgstr[1] "Moderated Reviews (%s)"
+
+# %1 is the nominated addons count
+#. %1 is the nominated addons count
+#: views/elements/developers/editorsqueue.thtml:44
+#: views/elements/developers/editorsmenu.thtml:58
+#, fuzzy, php-format
+msgid "devcp_editorsqueue_nominated"
+msgid_plural "devcp_editorsqueue_nominated"
+msgstr[0] "Nominated Add-ons (%s)"
+msgstr[1] "Nominated Add-ons (%s)"
+
+# %1 is the update count
+#. %1 is the update count
+#: views/elements/developers/editorsqueue.thtml:43
+#: views/elements/developers/editorsmenu.thtml:57
+#, fuzzy, php-format
+msgid "devcp_editorsqueue_pendingupdates"
+msgid_plural "devcp_editorsqueue_pendingupdates"
+msgstr[0] "Pending Updates (%s)"
+msgstr[1] "Pending Updates (%s)"
+
+#: controllers/statistics_controller.php:147
+#: controllers/statistics_controller.php:361
+#: controllers/previews_controller.php:108
+#: controllers/previews_controller.php:211
+#: controllers/previews_controller.php:312
+#, fuzzy
+msgid "devcp_error_addon_access_denied"
+msgstr "You do not have access to that add-on."
+
+#. %s is a complete URL with the text from devcp_error_appversion_reference_link_text
+#. in the <a> tag. This should be fixed.
+#: controllers/components/developers.php:591
+#, fuzzy, php-format
+msgid "devcp_error_appversion_reference_link"
+msgstr "Please see %s for reference."
+
+#. This is the link text in the <a> for devcp_error_appversion_reference_link. This
+#. should be fixed.
+#: controllers/components/developers.php:591
+#, fuzzy
+msgid "devcp_error_appversion_reference_link_text"
+msgstr "this page"
+
+#: views/developers/addon_edit_authors.thtml:76
+#, fuzzy
+msgid "devcp_error_empty_authors"
+msgstr "Your add-on must have at least one owner."
+
+#. %1$s is the name of the file
+#: controllers/components/developers.php:658
+#, fuzzy
+msgid "devcp_error_file_exists"
+msgstr ""
+"A version of that addon already exists. To replace it, you must delete the "
+"file %1$s first."
+
+#. %1$s is a file extension. Example: .exe
+#. %2$s is a comma separated list of extensions. Example: .xpi, .jar
+#: controllers/components/developers.php:355
+#, fuzzy, php-format
+msgid "devcp_error_file_extension"
+msgstr ""
+"That file extension (%s) is not allowed for the selected add-on type. Please "
+"use one of the following: %s"
+
+#: controllers/components/developers.php:64
+#, fuzzy
+msgid "devcp_error_five_categories"
+msgstr "Please select no more than five categories."
+
+#: controllers/components/developers.php:526
+#, fuzzy
+msgid "devcp_error_guid_application"
+msgstr "The ID of this add-on is already used by an application."
+
+#: controllers/components/developers.php:337
+#: controllers/components/developers.php:389
+#, fuzzy
+msgid "devcp_error_http_incomplete"
+msgstr "Incomplete transfer"
+
+#: controllers/components/developers.php:335
+#: controllers/components/developers.php:336
+#: controllers/components/developers.php:387
+#: controllers/components/developers.php:388
+#, fuzzy
+msgid "devcp_error_http_maxupload"
+msgstr "Exceeds maximum upload size"
+
+#: controllers/components/developers.php:338
+#: controllers/components/developers.php:390
+#, fuzzy
+msgid "devcp_error_http_nofile"
+msgstr "No file uploaded"
+
+#. %1$s is a file extension. Example: .exe
+#. %2$s is a comma separated list of extensions. Example: .xpi, .jar
+#: controllers/components/developers.php:401
+#, fuzzy, php-format
+msgid "devcp_error_icon_extension"
+msgstr ""
+"That file extension (%s) is not allowed for an icon. Please use one of the "
+"following: %s"
+
+#: controllers/developers_controller.php:504
+#, fuzzy
+msgid "devcp_error_index_rdf_notfound"
+msgstr "No install.rdf present."
+
+#: controllers/components/developers.php:601
+#, fuzzy
+msgid "devcp_error_install_manifest"
+msgstr "The following errors were found in install.rdf:"
+
+#: controllers/developers_controller.php:1463
+#, fuzzy
+msgid "devcp_error_invalid_addontype"
+msgstr "Please select a valid add-on type."
+
+#. %$1s is a version. Example: 3.1.1
+#. %$2s is an add-on name.
+#: controllers/components/developers.php:569
+#: controllers/components/developers.php:581
+#, fuzzy, php-format
+msgid "devcp_error_invalid_appversion"
+msgstr "%s is not a valid version for %s"
+
+#. %s is a string
+#: controllers/components/developers.php:521
+#, fuzzy, php-format
+msgid "devcp_error_invalid_guid"
+msgstr "The ID of this add-on is invalid: %s"
+
+#. %$1s is a version. Example: 3.1.1
+#. %$2s is an add-on name.
+#: controllers/components/developers.php:572
+#, fuzzy, php-format
+msgid "devcp_error_invalid_minversion"
+msgstr "%s is not a valid version for %s: minimum versions cannot contain *"
+
+#: controllers/components/developers.php:536
+#, fuzzy
+msgid "devcp_error_invalid_version"
+msgstr ""
+"The version of this add-on is invalid: please see the <a href=\"http://"
+"developer.mozilla.org/en/docs/Toolkit_version_format\">specification</a>"
+
+#: controllers/components/developers.php:531
+#, fuzzy
+msgid "devcp_error_invalid_version_spaces"
+msgstr "The version of this add-on is invalid: versions cannot contain spaces."
+
+#. %s is an error message from the parser.
+#: controllers/components/developers.php:501
+#, fuzzy, php-format
+msgid "devcp_error_manifest_parse"
+msgstr "The following error occurred while parsing install.rdf: %s"
+
+#: controllers/components/developers.php:373
+#, fuzzy
+msgid "devcp_error_move_file"
+msgstr "Could not move file"
+
+#. %s is the name of a file
+#: controllers/components/developers.php:650
+#: controllers/components/developers.php:662
+#: controllers/components/developers.php:667
+#: controllers/components/developers.php:727
+#: controllers/components/developers.php:738
+#: controllers/components/developers.php:743
+#, fuzzy, php-format
+msgid "devcp_error_moving_file"
+msgstr "An error occurred moving %s."
+
+#: controllers/components/developers.php:595
+#, fuzzy
+msgid "devcp_error_mozilla_application"
+msgstr "You must have at least one valid Mozilla target application."
+
+#: controllers/components/developers.php:516
+#, fuzzy
+msgid "devcp_error_no_guid"
+msgstr "No ID could be found for this add-on in install.rdf."
+
+#: controllers/components/developers.php:287
+#, fuzzy
+msgid "devcp_error_no_platform"
+msgstr "No platform selected"
+
+#: controllers/components/developers.php:59
+#, fuzzy
+msgid "devcp_error_one_category"
+msgstr "Please select at least one category."
+
+#: controllers/components/developers.php:92
+#, fuzzy
+msgid "devcp_error_one_user"
+msgstr "There must be at least one author for this add-on."
+
+#. %1$s is a file extension. Example: .exe
+#. %2$s is a comma separated list of extensions. Example: .xpi, .jar
+#: controllers/components/developers.php:1081
+#, fuzzy, php-format
+msgid "devcp_error_preview_extension"
+msgstr ""
+"That file extension (%s) is not allowed for a preview. Please use one of the "
+"following: %s"
+
+#: controllers/components/developers.php:511
+#, fuzzy
+msgid "devcp_error_updatekey"
+msgstr ""
+"Add-ons cannot use an updateKey. Please remove this from install.rdf and try "
+"again."
+
+#: controllers/components/developers.php:506
+#, fuzzy
+msgid "devcp_error_updateurl"
+msgstr ""
+"Add-ons cannot use an external updateURL. Please remove this from install."
+"rdf and try again."
+
+#: controllers/developers_controller.php:465
+#: controllers/components/developers.php:271
+#, fuzzy
+msgid "devcp_error_upload_file"
+msgstr "Please upload a file."
+
+#: views/developers/uploader.thtml:135
+#, fuzzy
+msgid "devcp_input_upload_file"
+msgstr "Upload File"
+
+#: views/pages/js_constants.js.thtml:89
+#, fuzzy
+msgid "devcp_js_a_cancel"
+msgstr "Cancel"
+
+#: views/pages/js_constants.js.thtml:90
+#, fuzzy
+msgid "devcp_js_add_email"
+msgstr "Please enter the account email of the author you wish to add."
+
+#. alt text for a down-arrow image.
+#: views/pages/js_constants.js.thtml:81
+#, fuzzy
+msgid "devcp_js_img_move_down"
+msgstr "Move Down"
+
+#. alt text for an up-arrow image.
+#: views/pages/js_constants.js.thtml:82
+#, fuzzy
+msgid "devcp_js_img_move_up"
+msgstr "Move Up"
+
+#: views/pages/js_constants.js.thtml:91
+#, fuzzy
+msgid "devcp_js_img_remove_compat"
+msgstr "Remove Application Compatibility"
+
+#: views/pages/js_constants.js.thtml:86
+#, fuzzy
+msgid "devcp_js_input_list_author"
+msgstr "List as author in public listings"
+
+#: views/pages/js_constants.js.thtml:92
+#, fuzzy
+msgid "devcp_js_license_select"
+msgstr "Please select a license."
+
+#: views/pages/js_constants.js.thtml:93
+#, fuzzy
+msgid "devcp_js_license_text"
+msgstr "Please enter text for your license."
+
+#. <option> text in a <select> for Author role in an add-on.
+#: views/pages/js_constants.js.thtml:84
+#, fuzzy
+msgid "devcp_js_option_developer"
+msgstr "Developer"
+
+#. <option> text in a <select> for Author role in an add-on.
+#: views/pages/js_constants.js.thtml:83
+#, fuzzy
+msgid "devcp_js_option_owner"
+msgstr "Owner"
+
+#. <option> text in a <select> for Author role in an add-on.
+#: views/pages/js_constants.js.thtml:85
+#, fuzzy
+msgid "devcp_js_option_viewer"
+msgstr "Viewer"
+
+#: views/pages/js_constants.js.thtml:88
+#, fuzzy
+msgid "devcp_js_remove_author"
+msgstr "Remove Author"
+
+#: views/pages/js_constants.js.thtml:87
+#, fuzzy
+msgid "devcp_js_sure_remove"
+msgstr "Are you <strong>sure</strong> you wish to remove this author?"
+
+#: views/pages/js_constants.js.thtml:77
+#, fuzzy
+msgid "devcp_js_upload_alert"
+msgstr "You must select a file to upload."
+
+#. %1$s is an addon id, like 32.
+#. %2$s is a version number, like 3.5.
+#: controllers/components/developers.php:1212
+#, fuzzy
+msgid "devcp_license_existing"
+msgstr "Custom license for add-on %1$s v%2$s"
+
+#: views/elements/developers/localebox.thtml:44
+#, fuzzy
+msgid "devcp_localebox_header_localizedfields"
+msgstr "Localized Fields"
+
+# %1 is the default locale
+#. %1 is the default locale
+#: views/elements/developers/localebox.thtml:48
+#, fuzzy, php-format
+msgid "devcp_localebox_intro"
+msgstr ""
+"Some of the fields on this page are localized to appear in the end-user's "
+"native language. Select a locale below to edit your add-on's details in that "
+"language. If a translation for a locale is not available, it will fall back "
+"to the selected default locale (%s)."
+
+#: views/elements/developers/sidebar.thtml:68
+#: views/elements/developers/myaddons.thtml:75
+#, fuzzy
+msgid "devcp_myaddons_admincp_link"
+msgstr "Admin Tools"
+
+#: views/elements/developers/sidebar.thtml:65
+#: views/elements/developers/myaddons.thtml:72
+#, fuzzy
+msgid "devcp_myaddons_editorcp_link"
+msgstr "Editor Tools"
+
+#: views/elements/developers/myaddons.thtml:52
+#, fuzzy
+msgid "devcp_myaddons_link"
+msgstr "My Add-ons"
+
+#: views/elements/developers/sidebar.thtml:70
+#: views/elements/developers/myaddons.thtml:77
+#, fuzzy
+msgid "devcp_myaddons_mainpage_link"
+msgstr "Back to Main"
+
+#: views/elements/developers/sidebar.thtml:63
+#: views/elements/developers/myaddons.thtml:70
+#, fuzzy
+msgid "devcp_myaddons_statistics_link"
+msgstr "Statistics Dashboard"
+
+#: views/elements/developers/sidebar.thtml:62
+#: views/elements/developers/myaddons.thtml:69
+#, fuzzy
+msgid "devcp_myaddons_submitaddon_link"
+msgstr "Submit Add-on"
+
+#: views/elements/developers/sidebar.thtml:48
+#: views/elements/developers/myaddons.thtml:67
+#, fuzzy
+msgid "devcp_myaddons_title"
+msgstr "Developer Tools"
+
+#. %1$s is an add-on ID, perhaps 167.
+#. %2$s is a URL.
+#: controllers/developers_controller.php:256
+#, fuzzy
+msgid "devcp_new_addon_error"
+msgstr ""
+"This add-on ID (%1$s) already exists in the database. If this is your add-"
+"on, you can <a href=\"%2$s\">upload a new version</a>."
+
+#: views/developers/addon_status_nominate.thtml:62
+#, fuzzy
+msgid "devcp_nominate_cancel"
+msgstr "Cancel and return"
+
+# %1 is the addon name
+#. %1 is the add-on name
+#: views/developers/addon_status_nominate.thtml:61
+#, fuzzy, php-format
+msgid "devcp_nominate_submit_nominate"
+msgstr "Nominate %s"
+
+#: views/developers/addon_edit_properties.thtml:50
+#: views/developers/addon_status.thtml:49
+#: views/developers/versions_edit.thtml:50
+#, fuzzy
+msgid "devcp_notice_changes_error"
+msgstr ""
+"<span>One or more of your changes couldn't be saved.</span><br />Please look "
+"for the errors below. The rest of your changes were successfully saved."
+
+#: views/developers/addon_edit_authors.thtml:47
+#: views/developers/addon_edit_properties.thtml:47
+#: views/developers/addon_status.thtml:46
+#: views/developers/addon_edit_descriptions.thtml:47
+#: views/developers/versions_edit.thtml:47
+#: views/developers/addon_edit_categories.thtml:46
+#, fuzzy
+msgid "devcp_notice_changes_saved"
+msgstr ""
+"<span>Your changes have been saved.</span><br />Please note that some "
+"changes may take several hours to appear in all areas of the website."
+
+#: controllers/previews_controller.php:252
+#, fuzzy
+msgid "devcp_notice_cleardefault"
+msgstr ""
+"Removing this as the default preview will cause another preview to "
+"automatically become the default preview."
+
+#: controllers/previews_controller.php:184
+#: controllers/previews_controller.php:251
+#, fuzzy
+msgid "devcp_notice_makedefault"
+msgstr ""
+"Making this the default preview will remove default status from the current "
+"default preview."
+
+#: views/developers/addon_edit_authors.thtml:70
+#, fuzzy
+msgid "devcp_notice_unsaved_changes"
+msgstr "You have unsaved changes."
+
+#: controllers/developers_controller.php:87
+#: controllers/developers_controller.php:97
+#: controllers/developers_controller.php:100
+#: controllers/previews_controller.php:67
+#: controllers/previews_controller.php:79
+#: controllers/previews_controller.php:82
+#, fuzzy
+msgid "devcp_pagetitle"
+msgstr "Developer Tools"
+
+#: controllers/previews_controller.php:103
+#: controllers/previews_controller.php:104
+#, fuzzy
+msgid "devcp_preview_add_pagetitle"
+msgstr "Add Preview"
+
+#: controllers/previews_controller.php:135
+#, fuzzy
+msgid "devcp_preview_added_successfully"
+msgstr "Preview added successfully."
+
+#: controllers/previews_controller.php:323
+#, fuzzy
+msgid "devcp_preview_deleted_successfully"
+msgstr "Preview deleted successfully."
+
+#: controllers/previews_controller.php:194
+#: controllers/previews_controller.php:195
+#, fuzzy
+msgid "devcp_preview_edit_pagetitle"
+msgstr "Edit Preview"
+
+#: controllers/previews_controller.php:237
+#, fuzzy
+msgid "devcp_preview_updated_successfully"
+msgstr "Preview updated successfully."
+
+#: views/developers/previews.thtml:120
+#, fuzzy
+msgid "devcp_previews_a_another"
+msgstr "Add Another Preview"
+
+#: views/developers/previews.thtml:96
+#, fuzzy
+msgid "devcp_previews_a_delete"
+msgstr "Delete Preview"
+
+#: views/developers/previews.thtml:95
+#, fuzzy
+msgid "devcp_previews_a_replace"
+msgstr "Replace Preview"
+
+#: views/developers/previews.thtml:126
+#, fuzzy
+msgid "devcp_previews_a_update"
+msgstr "Update Previews"
+
+#: views/developers/previews.thtml:115 views/developers/previews.thtml:124
+#, fuzzy
+msgid "devcp_previews_add_new"
+msgstr "Add New Preview"
+
+#. %s is a list of file extensions, e.g. ".png, .gif"
+#: views/developers/previews.thtml:116
+#, fuzzy
+msgid "devcp_previews_add_select"
+msgstr ""
+"Select an image to upload below. Images larger than the maximum size of 700 "
+"pixels wide by 525 pixels tall will be resized. Allowed file types: %s"
+
+#: views/developers/previews.thtml:121
+#, fuzzy
+msgid "devcp_previews_click_below"
+msgstr "Click Update Previews below to upload."
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/previews.thtml:102
+#, fuzzy
+msgid "devcp_previews_click_update"
+msgstr ""
+"Click the Update Previews button below to save this image. (<a %s>Cancel?</"
+"a>)"
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/previews.thtml:107
+#, fuzzy
+msgid "devcp_previews_error_message"
+msgstr ""
+"This preview will be deleted when Update Previews is clicked below. (<a %"
+"s>Cancel?</a>)"
+
+#: views/previews/add.thtml:45
+#, fuzzy
+msgid "devcp_previews_filetype_info"
+msgstr ""
+"Use the form below to upload a PNG, JPG, or GIF screenshot of your add-on. "
+"Images larger than 700 pixels wide and 525 pixels high will automatically be "
+"resized."
+
+#: views/previews/add.thtml:43
+#, fuzzy
+msgid "devcp_previews_header_add"
+msgstr "Add Preview"
+
+#: views/developers/previews.thtml:80
+#, fuzzy
+msgid "devcp_previews_header_caption"
+msgstr "Preview Caption"
+
+#: views/previews/edit.thtml:43
+#, fuzzy
+msgid "devcp_previews_header_edit"
+msgstr "Edit Preview"
+
+#: views/developers/previews.thtml:93
+#, fuzzy
+msgid "devcp_previews_label_default"
+msgstr "Default Preview"
+
+#: views/previews/add.thtml:54
+#, fuzzy
+msgid "devcp_previews_label_file"
+msgstr "Preview File"
+
+#: views/previews/add.thtml:59 views/previews/edit.thtml:50
+#, fuzzy
+msgid "devcp_previews_label_makedefault"
+msgstr "Make this the default preview image"
+
+#: views/developers/previews.thtml:100
+#, fuzzy
+msgid "devcp_previews_label_new"
+msgstr "New image:"
+
+#: views/developers/previews.thtml:118
+#, fuzzy
+msgid "devcp_previews_label_upload"
+msgstr "Upload Preview: "
+
+#: views/developers/previews.thtml:50
+#, fuzzy
+msgid "devcp_previews_notice_error"
+msgstr "One or more of your new previews could not be saved."
+
+#: views/developers/previews.thtml:47
+#, fuzzy
+msgid "devcp_previews_notice_success"
+msgstr "Your previews have been updated successfully."
+
+#: views/developers/previews.thtml:59
+#, fuzzy
+msgid "devcp_previews_p_screenshots"
+msgstr ""
+"The preview screenshots for your add-on are shown below. You can make "
+"changes to captions or images below. The Default Preview is the preview that "
+"is displayed next to your add-on in search and browse listings."
+
+#: views/previews/edit.thtml:55
+#, fuzzy
+msgid "devcp_previews_submit_delete"
+msgstr "Delete Preview"
+
+#: views/previews/edit.thtml:55
+#, fuzzy
+msgid "devcp_previews_submit_delete_confirm"
+msgstr "Are you sure you wish to delete this preview?"
+
+#: views/previews/edit.thtml:54
+#, fuzzy
+msgid "devcp_previews_submit_edit"
+msgstr "Edit Preview"
+
+#: views/previews/add.thtml:63
+#, fuzzy
+msgid "devcp_previews_submit_upload"
+msgstr "Upload Preview"
+
+#: views/developers/previews.thtml:78
+#, fuzzy
+msgid "devcp_previews_thumbnail"
+msgstr "Thumbnail"
+
+#. %s is the add-on name.
+#: views/developers/previews.thtml:44
+#, fuzzy
+msgid "devcp_previews_title"
+msgstr "%s Preview Manager"
+
+#: views/developers/uploader.thtml:74
+#, fuzzy
+msgid "devcp_review_agreement_please"
+msgstr ""
+"Please review and accept the following Developer Agreement before proceeding."
+
+#: views/elements/developers/rolecheck.thtml:42
+#, fuzzy
+msgid "devcp_rolecheck_no_privs"
+msgstr ""
+"<span>You do not have sufficient privileges to make changes on this page.</"
+"span><br />Contact the Add-on Owner if you need to make changes."
+
+#: controllers/developers_controller.php:1315
+#, fuzzy
+msgid "devcp_several_hours"
+msgstr ""
+"Please note that some changes may take several hours to appear in all areas "
+"of the website."
+
+#: views/elements/developers/sidebar.thtml:52
+#, fuzzy
+msgid "devcp_sidebar_a_dashboard"
+msgstr "Dashboard"
+
+#. %s is a number
+#: views/elements/developers/statsbar.thtml:45
+#: views/developers/dashboard.thtml:79
+#, fuzzy, php-format
+msgid "devcp_statsbar_adu"
+msgstr "<em>%s</em> Active Daily Users"
+
+#. %s is a number
+#: views/elements/developers/statsbar.thtml:41
+#: views/developers/dashboard.thtml:75
+#, fuzzy, php-format
+msgid "devcp_statsbar_total_downloads"
+msgstr "<em>%s</em> Total Downloads"
+
+#. %s is a number
+#: views/elements/developers/statsbar.thtml:43
+#: views/developers/dashboard.thtml:77
+#, fuzzy, php-format
+msgid "devcp_statsbar_weekly_downloads"
+msgstr "<em>%s</em> Weekly Downloads"
+
+#: views/developers/addon_status_confirm.thtml:59
+#, fuzzy
+msgid "devcp_status_confirm_active"
+msgstr ""
+"Marking this add-on active will cause it to show up in public areas "
+"appropriate for its status, including search and browse listings. It will be "
+"downloadable from the website and could be returned in client update checks, "
+"depending on its status. You will be able to return here and disable it "
+"again at your convenience."
+
+#: views/developers/addon_status_confirm.thtml:59
+#, fuzzy
+msgid "devcp_status_confirm_active_sure"
+msgstr "Are you sure you wish to mark this add-on active?"
+
+#: views/developers/addon_status_confirm.thtml:50
+#, fuzzy
+msgid "devcp_status_confirm_header_sure"
+msgstr "Are you sure?"
+
+#: views/developers/addon_status_confirm.thtml:55
+#, fuzzy
+msgid "devcp_status_confirm_inactive"
+msgstr ""
+"Marking this add-on inactive will prevent it from showing up in any public "
+"areas, including search and browse listings. It will not be downloadable "
+"from the website and will not be returned in client update checks. You will "
+"be able to return here and re-enable it at your convenience."
+
+#: views/developers/addon_status_confirm.thtml:55
+#, fuzzy
+msgid "devcp_status_confirm_inactive_sure"
+msgstr "Are you sure you wish to mark this add-on inactive?'"
+
+#: views/developers/addon_status_confirm.thtml:74
+#, fuzzy
+msgid "devcp_status_confirm_no"
+msgstr "No, cancel"
+
+#: views/developers/addon_status_confirm.thtml:67
+#, fuzzy
+msgid "devcp_status_confirm_public"
+msgstr ""
+"Making this add-on public will make it available for anyone to download and "
+"will begin offering updates to existing users."
+
+#: views/developers/addon_status_confirm.thtml:67
+#, fuzzy
+msgid "devcp_status_confirm_public_sure"
+msgstr "Are you sure you wish to make this add-on public?"
+
+#: views/developers/addon_status_confirm.thtml:63
+#, fuzzy
+msgid "devcp_status_confirm_sandbox"
+msgstr ""
+"Moving this add-on back to the sandbox will require users to login before "
+"downloading and updates will no longer be offered to existing users. Because "
+"your add-on is currently public, you will be able to return here at any time "
+"to make it public again."
+
+#: views/developers/addon_status_confirm.thtml:63
+#, fuzzy
+msgid "devcp_status_confirm_sandbox_sure"
+msgstr "Are you sure you wish to move this add-on to the sandbox?"
+
+#: views/developers/addon_status_confirm.thtml:73
+#, fuzzy
+msgid "devcp_status_confirm_yes"
+msgstr "Yes, I'm Sure"
+
+#: views/developers/addon_status_nominate.thtml:46
+#, fuzzy
+msgid "devcp_status_nominate_error_notice"
+msgstr ""
+"<span>A nomination message is required.</span><br />Please fill in the text "
+"box with the requested information and try again."
+
+#: views/developers/addon_status_nominate.thtml:55
+#, fuzzy
+msgid "devcp_status_nominate_header"
+msgstr "Add-on Nomination"
+
+#: views/developers/dashboard.thtml:85
+#, fuzzy
+msgid "devcp_summary_lastversion"
+msgstr "Latest Version:"
+
+#. %s is the add-on name.
+#: views/developers/addon_edit.thtml:43
+#: views/developers/addon_edit_authors.thtml:44
+#: views/developers/versions_delete.thtml:43
+#: views/developers/addon_edit_properties.thtml:44
+#: views/developers/addon_edit_descriptions.thtml:44
+#: views/developers/versions_edit.thtml:44
+#: views/developers/addon_edit_categories.thtml:43
+#: views/developers/versions.thtml:43
+#, fuzzy
+msgid "devcp_title_edit_addon"
+msgstr "Edit %s"
+
+#. title attribute for a javascript link that pops up a help dialog.
+#: views/elements/translationbox.thtml:68
+#, fuzzy
+msgid "devcp_transbox_a_title_help"
+msgstr "Help (does not leave page)"
+
+#: views/elements/translationbox.thtml:68
+#, fuzzy
+msgid "devcp_transbox_alt_help"
+msgstr "Help"
+
+#. %1$s is <span>17</span>, %2$s is 42.
+#: views/elements/translationbox.thtml:101
+#, fuzzy
+msgid "devcp_transbox_chars_used"
+msgstr "Characters used: %1$s / %2$s"
+
+#: views/elements/translationbox.thtml:132
+#, fuzzy
+msgid "devcp_transbox_delete_sure"
+msgstr "Are you sure you wish to delete this translation?"
+
+#. %s is a locale, like en-US.
+#: views/elements/translationbox.thtml:143
+#, fuzzy
+msgid "devcp_transbox_help_header_tabs"
+msgstr "What are these %s tabs?"
+
+#: views/elements/translationbox.thtml:145
+#, fuzzy
+msgid "devcp_transbox_help_header_what"
+msgstr "What if I don't have any translations?"
+
+#: views/elements/translationbox.thtml:147
+#, fuzzy
+msgid "devcp_transbox_help_hide"
+msgstr "Hide Help"
+
+#: views/elements/translationbox.thtml:146
+#, fuzzy
+msgid "devcp_transbox_help_if"
+msgstr ""
+"If a user browses the site and a translation isn't available in their own "
+"language, it will fall back to your add-on's Default Locale, specified in "
+"the Edit Add-on Properties area. If you don't have any translations, just "
+"enter what you can into your Default Locale, which should be a language you "
+"speak."
+
+#: views/elements/translationbox.thtml:144
+#, fuzzy
+msgid "devcp_transbox_help_transbox"
+msgstr ""
+"This is a <i>Translation Box</i>. It allows you to localize a specific field "
+"into any other languages for which you might have a translation. You can "
+"add, edit, and remove translations using the locale tabs."
+
+#: views/elements/translationbox.thtml:85
+#, fuzzy
+msgid "devcp_transbox_img_add_trans"
+msgstr "Add Translation"
+
+#: views/elements/translationbox.thtml:86
+#, fuzzy
+msgid "devcp_transbox_img_remove_trans"
+msgstr "Remove Translation"
+
+#: views/elements/translationbox.thtml:123
+#, fuzzy
+msgid "devcp_transbox_input_add_all"
+msgstr "Add Locale to All"
+
+#: views/elements/translationbox.thtml:122
+#, fuzzy
+msgid "devcp_transbox_input_add_locale"
+msgstr "Add Locale"
+
+#: views/elements/translationbox.thtml:124
+#: views/elements/translationbox.thtml:135
+#, fuzzy
+msgid "devcp_transbox_input_cancel"
+msgstr "Cancel"
+
+#: views/elements/translationbox.thtml:134
+#, fuzzy
+msgid "devcp_transbox_input_delete"
+msgstr "Delete It"
+
+#: views/elements/translationbox.thtml:113
+#, fuzzy
+msgid "devcp_transbox_select_locale"
+msgstr "Select the locale of the translation to add:"
+
+#. %1$s and %2$s are GUIDs.
+#: controllers/developers_controller.php:343
+#, fuzzy
+msgid "devcp_update_addon_guid_error"
+msgstr ""
+"The add-on GUID used in this file (%1$s) does not match the existing GUID "
+"for this add-on (%2$s)."
+
+#: controllers/developers_controller.php:334
+#, fuzzy
+msgid "devcp_update_addon_priv_error"
+msgstr "You do not have sufficient privileges to update this add-on."
+
+#. %1$s is a version number, %2$s is an add-on ID.
+#: controllers/developers_controller.php:399
+#, fuzzy
+msgid "devcp_update_addon_version_belong_error"
+msgstr "The specified version (%1$s) does not belong to this add-on (%2$s)."
+
+#. %1$s is a version number, maybe 1.1.
+#. %2$s is a URL.
+#: controllers/developers_controller.php:351
+#, fuzzy
+msgid "devcp_update_addon_version_exists_error"
+msgstr ""
+"The version number uploaded (%1$s) already exists for this add-on. If you "
+"are trying to add another file to this version, <a href=\"%2$s\">click here</"
+"a>."
+
+#. %1$s and %2$s are version numbers.
+#: controllers/developers_controller.php:405
+#, fuzzy
+msgid "devcp_update_addon_version_match_error"
+msgstr ""
+"The uploaded version number (%1$s) does not match the existing version "
+"number (%2$s)."
+
+#: views/developers/uploader.thtml:68
+#, fuzzy
+msgid "devcp_uploader_a_start"
+msgstr "Get Started"
+
+#: views/developers/uploader.thtml:137
+#, fuzzy
+msgid "devcp_uploader_ajax_loading"
+msgstr "Uploading file..."
+
+#: views/developers/uploader.thtml:82
+#, fuzzy
+msgid "devcp_uploader_button_agree"
+msgstr "Agree and continue"
+
+#: views/developers/uploader.thtml:157
+#, fuzzy
+msgid "devcp_uploader_button_edit"
+msgstr "Edit My Add-on"
+
+#: views/developers/uploader.thtml:158
+#, fuzzy
+msgid "devcp_uploader_button_later"
+msgstr "I'll complete my add-on later."
+
+#: views/developers/uploader.thtml:168
+#, fuzzy
+msgid "devcp_uploader_button_release"
+msgstr "Add Release Notes"
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/uploader.thtml:156
+#, fuzzy
+msgid "devcp_uploader_created_results"
+msgstr ""
+"<p>Your add-on listing has been successfully created. The basic information "
+"obtained from your uploaded file has been stored, but there's a lot more to "
+"your listing that can be customized.</p><p>Your add-on is currently marked "
+"as <strong>Incomplete</strong>. In order to complete your add-on, you'll "
+"need to make sure it has an accurate name, summary, and description, as well "
+"as at least one selected category. You can edit your add-on's information "
+"using the link below and check the status of your add-on at any time on the "
+"<a %s>status page</a>."
+
+#: views/developers/uploader.thtml:143
+#, fuzzy
+msgid "devcp_uploader_error_correct"
+msgstr "Please correct this problem and upload your file again."
+
+#. %1$s is a version number, %2$s is a status, e.g Public or Incomplete.
+#: views/developers/uploader.thtml:175
+#, fuzzy
+msgid "devcp_uploader_file_created"
+msgstr ""
+"Your new file has been added to version %1$s and is currently marked as %2$s."
+
+#: views/developers/uploader.thtml:154
+#, fuzzy
+msgid "devcp_uploader_header_created"
+msgstr "Add-on Created!"
+
+#: views/developers/uploader.thtml:141
+#, fuzzy
+msgid "devcp_uploader_header_error"
+msgstr "Oops! There seems to be a problem with this file..."
+
+#: views/developers/uploader.thtml:173
+#, fuzzy
+msgid "devcp_uploader_header_file_added"
+msgstr "File Added!"
+
+#: views/developers/uploader.thtml:66
+#, fuzzy
+msgid "devcp_uploader_header_how"
+msgstr "How does it all work?"
+
+#. %s is the version number, e.g. 3.2.
+#: views/developers/uploader.thtml:163
+#, fuzzy
+msgid "devcp_uploader_header_update_created"
+msgstr "Version %s Created"
+
+#: views/developers/uploader.thtml:117
+#, fuzzy
+msgid "devcp_uploader_header_upload"
+msgstr "Upload Your File"
+
+#: views/developers/uploader.thtml:67
+#, fuzzy
+msgid "devcp_uploader_how"
+msgstr ""
+"<p>Thanks for your interest in submitting your add-on to Mozilla Add-ons. "
+"Hosting your add-on on Mozilla Add-ons is the easiest way to handle "
+"distribution of your add-on. Here's what you'll get:</p><ul><li>Each add-on "
+"will have a public display page with information you provide, such as a "
+"brief summary of the add-on's functionality, an optional longer description, "
+"and a showcase of preview screenshots of your add-on.</li><li>Your add-on "
+"will appear in search and browse listings across the site, and even in the "
+"Add-ons Manager of Firefox 3.</li><li>We'll take care of hosting all of your "
+"downloads and providing automatic updates to users when you upload a new "
+"version.</li><li>You'll have access to a statistics dashboard with detailed "
+"information about your user base.</li></ul><p>Add-ons hosted on the site "
+"must be reviewed by a Mozilla Add-ons Editor before they will have all of "
+"the features listed above. If you're ready to start the process and have "
+"your add-on package ready for upload, just click on Get Started below!</p>"
+
+#: views/developers/uploader.thtml:125
+#, fuzzy
+msgid "devcp_uploader_label_platformtype"
+msgstr "Supported Platforms:"
+
+#: views/developers/uploader.thtml:124
+#, fuzzy
+msgid "devcp_uploader_label_upload_field"
+msgstr "Add-on File: "
+
+#: controllers/components/developers.php:1221
+#, fuzzy
+msgid "devcp_uploader_option_other"
+msgstr "Other"
+
+#. %1$s is a number, %2$s is href="..." and should stay in the <a> tag.
+#: views/developers/uploader.thtml:176
+#, fuzzy
+msgid "devcp_uploader_p_pending_file"
+msgstr ""
+"The new file will be available to the public as soon as an editor is able to "
+"review it. There are currently %1$s other add-ons in the queue. Want to be "
+"reviewed faster? Consider <a %2$s>becoming an editor</a>."
+
+#. %1$s is a number, %2$s is href="..." and should stay in the <a> tag.
+#: views/developers/uploader.thtml:166
+#, fuzzy
+msgid "devcp_uploader_p_pending_version"
+msgstr ""
+"The new version will be available to the public as soon as an editor is able "
+"to review it. There are currently %1$s other add-ons in the queue. Want to "
+"be reviewed faster? Consider <a %2$s>becoming an editor</a>."
+
+#. %s is a status, e.g Public or Incomplete.
+#: views/developers/uploader.thtml:165
+#, fuzzy
+msgid "devcp_uploader_p_update_created"
+msgstr "Your new version has been created and is currently marked as %s."
+
+#. %1$s is href="..." and should stay in the 'Versions and Files' <a> tag.
+#. %2$s is href="..." and should stay in the 'current status' <a> tag.
+#: views/developers/uploader.thtml:177
+#, fuzzy
+msgid "devcp_uploader_p_update_file"
+msgstr ""
+"View your new file in the <a %1$s>Versions and Files page</a>, check out "
+"your add-on's <a %2$s>current status</a>, or <b>add release notes</b> by "
+"clicking the button below (highly recommended)."
+
+#. %1$s is href="..." and should stay in the 'Versions and Files' <a> tag.
+#. %2$s is href="..." and should stay in the 'current status' <a> tag.
+#: views/developers/uploader.thtml:167
+#, fuzzy
+msgid "devcp_uploader_p_update_version"
+msgstr ""
+"View your new version in the <a %1$s>Versions and Files page</a>, check out "
+"your add-on's <a %2$s>current status</a>, or <b>add release notes</b> by "
+"clicking the button below (highly recommended)."
+
+#: views/developers/uploader.thtml:118
+#, fuzzy
+msgid "devcp_uploader_p_upload"
+msgstr ""
+"Upload your add-on file using the form below. If you have multiple, platform-"
+"specific files to upload, choose a single file and then upload the others "
+"using the Versions and Files Manager."
+
+#: views/developers/uploader.thtml:125
+#, fuzzy
+msgid "devcp_uploader_platformtype_all"
+msgstr "All"
+
+#: views/developers/uploader.thtml:126
+#, fuzzy
+msgid "devcp_uploader_platformtype_specific"
+msgstr "Specific:"
+
+#. Used as first item in a <select>.
+#: controllers/components/developers.php:1185
+#, fuzzy
+msgid "devcp_uploader_please_choose"
+msgstr "Please Choose..."
+
+#. %1$s is the add-on name, %2$s is the version number.
+#: views/developers/uploader.thtml:57
+#, fuzzy
+msgid "devcp_uploader_title_file"
+msgstr "Add File to %1$s %2$s"
+
+#: views/developers/uploader.thtml:50
+#, fuzzy
+msgid "devcp_uploader_title_submit"
+msgstr "Submit New Add-on"
+
+#. %s is the add-on name.
+#: views/developers/uploader.thtml:54
+#, fuzzy
+msgid "devcp_uploader_title_update"
+msgstr "Update %s"
+
+#. %s is a full <a> tag
+#: controllers/developers_controller.php:503
+#, fuzzy, php-format
+msgid "devcp_valid_app_reference"
+msgstr "Please see %s for reference."
+
+#. This is the text in the <a> tag for devcp_valid_app_reference. This should be
+#. fixed.
+#: controllers/developers_controller.php:503
+#, fuzzy
+msgid "devcp_valid_app_reference_linktext"
+msgstr "this page"
+
+#: controllers/developers_controller.php:581
+#, fuzzy
+msgid "devcp_verify_author_error"
+msgstr "No account found for that email address."
+
+#: controllers/developers_controller.php:553
+#, fuzzy
+msgid "devcp_verify_search_engine_error"
+msgstr ""
+"Either the XML is invalid or required fields are missing. Please <a href="
+"\"https://developer.mozilla.org/en/Creating_OpenSearch_plugins_for_Firefox"
+"\">read the documentation</a>, verify your add-on, and try again."
+
+#: views/developers/versions.thtml:75
+#, fuzzy
+msgid "devcp_versions_a_cancel"
+msgstr "Cancel"
+
+#: views/developers/versions.thtml:79
+#, fuzzy
+msgid "devcp_versions_a_delete"
+msgstr "Delete Version"
+
+#: views/developers/versions.thtml:74
+#, fuzzy
+msgid "devcp_versions_a_empty"
+msgstr "Remove Empty Version"
+
+#: views/developers/versions.thtml:71
+#, fuzzy
+msgid "devcp_versions_a_remove"
+msgstr "Remove?"
+
+#: views/developers/versions.thtml:91
+#, fuzzy
+msgid "devcp_versions_add"
+msgstr "Add New Version"
+
+#: views/developers/versions_delete.thtml:58
+#, fuzzy
+msgid "devcp_versions_delete_a_cancel"
+msgstr "Cancel"
+
+#: views/developers/versions_delete.thtml:56
+#, fuzzy
+msgid "devcp_versions_delete_a_delete"
+msgstr "Delete Version"
+
+#. Followed by a list of reviews and files that will be removed.
+#: views/developers/versions_delete.thtml:50
+#, fuzzy
+msgid "devcp_versions_delete_also"
+msgstr "This will also delete:"
+
+#: views/developers/versions_delete.thtml:53
+#, fuzzy
+msgid "devcp_versions_delete_files"
+msgid_plural "devcp_versions_delete_files"
+msgstr[0] "%s file"
+msgstr[1] "%s files"
+
+#. %s is the version number.
+#: views/developers/versions_delete.thtml:48
+#, fuzzy
+msgid "devcp_versions_delete_header"
+msgstr "Delete Version %s?"
+
+#: views/developers/versions_delete.thtml:52
+#, fuzzy
+msgid "devcp_versions_delete_reviews"
+msgid_plural "devcp_versions_delete_reviews"
+msgstr[0] "%s review"
+msgstr[1] "%s reviews"
+
+#. %s is the version number.
+#: views/developers/versions_delete.thtml:49
+#, fuzzy
+msgid "devcp_versions_delete_sure"
+msgstr "Are you sure you want to permanently delete version %s?"
+
+#: views/developers/versions_edit.thtml:102
+#: views/developers/versions_edit.thtml:155
+#, fuzzy
+msgid "devcp_versions_edit_a_cancel"
+msgstr "Cancel"
+
+#: views/developers/versions_edit.thtml:101
+#, fuzzy
+msgid "devcp_versions_edit_a_delete"
+msgstr "Delete File"
+
+#: views/developers/versions_edit.thtml:165
+#, fuzzy
+msgid "devcp_versions_edit_a_new_app"
+msgstr "Add New Application"
+
+#: views/developers/versions_edit.thtml:154
+#, fuzzy
+msgid "devcp_versions_edit_a_remove_app"
+msgstr "Remove Application"
+
+#: views/developers/versions_edit.thtml:114
+#, fuzzy
+msgid "devcp_versions_edit_add"
+msgstr "Add New File"
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/versions_edit.thtml:121
+#, fuzzy
+msgid "devcp_versions_edit_adjust"
+msgstr ""
+"Adjusting application information here will allow users to install your add-"
+"on even if the install.rdf in the package indicates that the add-on is "
+"incompatible. <a %s>List of supported applications</a>"
+
+#: views/developers/versions_edit.thtml:153
+#, fuzzy
+msgid "devcp_versions_edit_compat_sure"
+msgstr ""
+"Are you <b>sure</b> you wish to remove compatibility with this application?"
+
+#: views/developers/versions_edit.thtml:100
+#, fuzzy
+msgid "devcp_versions_edit_delete_sure"
+msgstr "Are you <b>sure</b> you wish to permanently delete this file?"
+
+#: views/developers/versions_edit.thtml:203
+#, fuzzy
+msgid "devcp_versions_edit_header_approval"
+msgstr "Approval Information"
+
+#: views/developers/versions_edit.thtml:120
+#, fuzzy
+msgid "devcp_versions_edit_header_compat"
+msgstr "Compatible Applications"
+
+#: views/developers/versions_edit.thtml:74
+#, fuzzy
+msgid "devcp_versions_edit_header_file"
+msgstr "File Information"
+
+#: views/developers/versions_edit.thtml:189
+#, fuzzy
+msgid "devcp_versions_edit_header_license"
+msgstr "License"
+
+#. %s is the version number.
+#: views/developers/versions_edit.thtml:53
+#, fuzzy
+msgid "devcp_versions_edit_header_manage"
+msgstr "Manage Version %s"
+
+#: views/developers/versions_edit.thtml:212
+#, fuzzy
+msgid "devcp_versions_edit_header_notes"
+msgstr "Approval Notes"
+
+#: views/developers/versions_edit.thtml:98
+#, fuzzy
+msgid "devcp_versions_edit_img_delete"
+msgstr "Delete File"
+
+#. %1$s is the file id, e.g. 18723.
+#. %2$s is the platform name, e.g. ALL or Windows.
+#. %3$s is the _('date) created.
+#. %4$s is the status, e.g. "In Sandbox" or "Public".
+#. %5$s is the _('date') status was changed.
+#: views/developers/versions_edit.thtml:208
+#, fuzzy
+msgid "devcp_versions_edit_li_file"
+msgstr "File %1$s (%2$s) created on %3$s and changed to %4$s on %5$s"
+
+#: views/developers/versions_edit.thtml:190
+#, fuzzy
+msgid "devcp_versions_edit_license_description"
+msgstr ""
+"Please select the appropriate license for your add-on. This license "
+"specifies the rights you grant on your source code."
+
+#: views/developers/versions_edit.thtml:111
+#, fuzzy
+msgid "devcp_versions_edit_no_files"
+msgstr "No files found."
+
+#: views/developers/versions_edit.thtml:213
+#, fuzzy
+msgid "devcp_versions_edit_optional"
+msgstr "Optional information for the Editor that reviews this version."
+
+#: views/developers/versions_edit.thtml:151
+#, fuzzy
+msgid "devcp_versions_edit_remove_compat"
+msgstr "Remove Application Compatibility"
+
+#: views/developers/versions_edit.thtml:167
+#, fuzzy
+msgid "devcp_versions_edit_select_app"
+msgstr "Please Select an Application"
+
+#: views/developers/versions_edit.thtml:78
+#, fuzzy
+msgid "devcp_versions_edit_th_file"
+msgstr "File"
+
+#: views/developers/versions_edit.thtml:79
+#, fuzzy
+msgid "devcp_versions_edit_th_platform"
+msgstr "Platform"
+
+#: views/developers/versions_edit.thtml:80
+#, fuzzy
+msgid "devcp_versions_edit_th_size"
+msgstr "Size"
+
+#: views/developers/versions_edit.thtml:81
+#, fuzzy
+msgid "devcp_versions_edit_th_status"
+msgstr "Status"
+
+#: views/developers/versions_edit.thtml:183
+#, fuzzy
+msgid "devcp_versions_edit_transbox_releasenotes_description"
+msgstr ""
+"Information about changes in this release, new features, known bugs, and "
+"other useful information specific to this release/version. This information "
+"will also be available to users updating the add-on in the Firefox 3 Add-ons "
+"Manager interface."
+
+#: views/developers/versions_edit.thtml:182
+#, fuzzy
+msgid "devcp_versions_edit_transbox_releasenotes_name"
+msgstr "Release Notes"
+
+#: views/developers/versions_edit.thtml:164
+#, fuzzy
+msgid "devcp_versions_edit_unsaved_compat"
+msgstr ""
+"<strong>You have unsaved changes.</strong> Compatibility will not be deleted "
+"until you click Update Version below."
+
+#: views/developers/versions_edit.thtml:113
+#, fuzzy
+msgid "devcp_versions_edit_unsaved_files"
+msgstr ""
+"<strong>You have unsaved changes.</strong> Files will not be deleted until "
+"you click Update Version below."
+
+#: views/developers/versions_edit.thtml:218
+#, fuzzy
+msgid "devcp_versions_edit_update"
+msgstr "Update Versions"
+
+#: views/developers/versions.thtml:49
+#, fuzzy
+msgid "devcp_versions_header_manage"
+msgstr "Manage Versions and Files"
+
+#: views/developers/versions.thtml:87
+#, fuzzy
+msgid "devcp_versions_no_versions"
+msgstr "No versions."
+
+#. %s is a version number, base 10.
+#: views/developers/versions.thtml:46
+#, fuzzy
+msgid "devcp_versions_notice_success"
+msgstr "Version %s deleted successfully."
+
+#: views/developers/versions.thtml:73
+#, fuzzy
+msgid "devcp_versions_p_remove"
+msgstr ""
+"This version has no files associated with it and can be removed. Would you "
+"like to remove this version?"
+
+#: views/developers/versions.thtml:58
+#, fuzzy
+msgid "devcp_versions_th_created"
+msgstr "Created"
+
+#: views/developers/versions.thtml:57
+#, fuzzy
+msgid "devcp_versions_th_status"
+msgstr "Status"
+
+#: views/developers/versions.thtml:56
+#, fuzzy
+msgid "devcp_versions_th_version"
+msgstr "Version"
+
+#: controllers/downloads_controller.php:91
+#, fuzzy
+msgid "downloads_disable_warning"
+msgstr "This add-on is disabled"
+
+#: controllers/components/editors.php:57
+#, fuzzy
+msgid "editor_review_error_addon_not_nominated"
+msgstr "This add-on has not been nominated."
+
+#: controllers/components/editors.php:213
+#, fuzzy
+msgid "editor_review_error_file_not_pending"
+msgstr "This file is not pending review."
+
+#. Actions are, for example: approving or rejecting
+#: controllers/components/editors.php:79
+#: controllers/components/editors.php:182
+#, fuzzy
+msgid "editor_review_error_no_action"
+msgstr "Please select a review action."
+
+#: controllers/components/editors.php:192
+#, fuzzy
+msgid "editor_review_error_no_applications"
+msgstr "Please enter the applications you tested."
+
+#. Comments are required when an editor approves or rejects an add-on.
+#: controllers/components/editors.php:84
+#: controllers/components/editors.php:187
+#, fuzzy
+msgid "editor_review_error_no_comments"
+msgstr "Please enter review comments."
+
+#: controllers/components/editors.php:161
+#, fuzzy
+msgid "editor_review_error_no_files"
+msgstr "Please select at least one file to review."
+
+#: controllers/components/editors.php:197
+#, fuzzy
+msgid "editor_review_error_no_operating_system"
+msgstr "Please enter the operating systems you tested."
+
+#: views/editors/logs.thtml:51
+#, fuzzy
+msgid "editorcp_logs_button_filter"
+msgstr "Filter"
+
+#: views/editors/logs.thtml:44
+#, fuzzy
+msgid "editorcp_logs_filter_by"
+msgstr "Filter by type/action"
+
+#: views/editors/logs.thtml:42 controllers/editors_controller.php:964
+#, fuzzy
+msgid "editorcp_logs_page_heading"
+msgstr "Event Log"
+
+#: views/elements/developers/editorsmenu.thtml:60
+#, fuzzy
+msgid "editorcp_menu_eventlog_link"
+msgstr "Event Log"
+
+#: views/elements/developers/editorsmenu.thtml:62
+#, fuzzy
+msgid "editorcp_menu_mainpage_link"
+msgstr "Back to Main"
+
+#: views/elements/developers/editorsmenu.thtml:61
+#, fuzzy
+msgid "editorcp_menu_reviewlog_link"
+msgstr "Review Log"
+
+#: views/elements/developers/editorsmenu.thtml:55
+#, fuzzy
+msgid "editorcp_menu_summary_link"
+msgstr "Editor Summary"
+
+#: views/elements/developers/editorsmenu.thtml:52
+#, fuzzy
+msgid "editorcp_menu_title"
+msgstr "Editor Tools"
+
+#: views/editors/reviewlog.thtml:49
+#, fuzzy
+msgid "editorcp_reviewlog_button_filter"
+msgstr "Filter"
+
+#: views/editors/reviewlog.thtml:58
+#, fuzzy
+msgid "editorcp_reviewlog_column_action"
+msgstr "Action"
+
+#: views/editors/reviewlog.thtml:56
+#, fuzzy
+msgid "editorcp_reviewlog_column_addon"
+msgstr "Add-on"
+
+#: views/editors/reviewlog.thtml:55
+#, fuzzy
+msgid "editorcp_reviewlog_column_date"
+msgstr "Date"
+
+#: views/editors/reviewlog.thtml:57
+#, fuzzy
+msgid "editorcp_reviewlog_column_editor"
+msgstr "Editor"
+
+#: views/editors/reviewlog.thtml:94
+#, fuzzy
+msgid "editorcp_reviewlog_comments_hide"
+msgstr "Hide Comments"
+
+#: views/editors/reviewlog.thtml:93
+#, fuzzy
+msgid "editorcp_reviewlog_comments_show"
+msgstr "Show Comments"
+
+#. %1$s and %2$s are full <input> tags for dates
+#: views/editors/reviewlog.thtml:45
+#, fuzzy, php-format
+msgid "editorcp_reviewlog_entries_between"
+msgstr "View entries between %s and %s"
+
+#: views/editors/reviewlog.thtml:104
+#, fuzzy
+msgid "editorcp_reviewlog_none_found"
+msgstr "No reviews found for this period."
+
+#: views/editors/reviewlog.thtml:42
+#, fuzzy
+msgid "editorcp_reviewlog_page_heading"
+msgstr "Review Log"
+
+#: views/editors/summary.thtml:61
+#, fuzzy
+msgid "editorcp_summary_monthreviews_heading"
+msgstr "Month Reviews"
+
+#: views/editors/summary.thtml:77
+#, fuzzy
+msgid "editorcp_summary_neweditors_heading"
+msgstr "New Editors"
+
+#: views/editors/summary.thtml:42
+#, fuzzy
+msgid "editorcp_summary_page_heading"
+msgstr "Editor Summary"
+
+#: views/editors/summary.thtml:94
+#, fuzzy
+msgid "editorcp_summary_recentactivity_heading"
+msgstr "Recent Editor Activity"
+
+#: views/editors/summary.thtml:45
+#, fuzzy
+msgid "editorcp_summary_totalreviews_heading"
+msgstr "Total Reviews"
+
+#: controllers/editors_controller.php:248
+#: controllers/editors_controller.php:249
+#, fuzzy
+msgid "editors_addon_review_pagetitle"
+msgstr "Review Add-on"
+
+#: controllers/editors_controller.php:349
+#, fuzzy
+msgid "editors_error_js-formerror"
+msgstr "Please complete the following fields:"
+
+#: controllers/editors_controller.php:350
+#, fuzzy
+msgid "editors_error_review_one_file"
+msgstr "Please select at least one file to review."
+
+#: controllers/editors_controller.php:274
+#, fuzzy
+msgid "editors_error_self_reviews_forbidden"
+msgstr "Self-reviews are not allowed."
+
+#: controllers/editors_controller.php:699
+#, fuzzy
+msgid "editors_external_software"
+msgstr "External Software"
+
+#: views/editors/featured.thtml:120 views/editors/featured.thtml:121
+#, fuzzy
+msgid "editors_featured_add_feature"
+msgstr "Add feature"
+
+#: views/editors/featured.thtml:126
+#, fuzzy
+msgid "editors_featured_add_feature_submit"
+msgstr "Add"
+
+#: views/editors/featured.thtml:49 controllers/editors_controller.php:832
+#: controllers/editors_controller.php:848
+#, fuzzy
+msgid "editors_featured_addon_add_failure"
+msgstr "Failed to add feature."
+
+#: controllers/editors_controller.php:851
+#, fuzzy
+msgid "editors_featured_addon_add_success"
+msgstr "Successfully added feature."
+
+#: views/editors/featured.thtml:50 controllers/editors_controller.php:839
+#: controllers/editors_controller.php:868
+#: controllers/editors_controller.php:886
+#, fuzzy
+msgid "editors_featured_addon_edit_failure"
+msgstr "Failed to edit feature."
+
+#: views/editors/featured.thtml:51 controllers/editors_controller.php:888
+#, fuzzy
+msgid "editors_featured_addon_edit_success"
+msgstr "Successfully edited feature."
+
+#: views/editors/featured.thtml:53 controllers/editors_controller.php:861
+#, fuzzy
+msgid "editors_featured_addon_invalid_locale"
+msgstr "One or more locales are invalid."
+
+#: views/editors/featured.thtml:52 controllers/editors_controller.php:906
+#, fuzzy
+msgid "editors_featured_addon_remove_failure"
+msgstr "Failed to remove feature."
+
+#: controllers/editors_controller.php:901
+#, fuzzy
+msgid "editors_featured_addon_remove_success"
+msgstr "Successfully removed feature."
+
+#: controllers/editors_controller.php:915
+#: controllers/editors_controller.php:917
+#, fuzzy
+msgid "editors_featured_addons_pagetitle"
+msgstr "Featured Add-ons"
+
+#: views/editors/featured.thtml:54 views/editors/featured.thtml:107
+#, fuzzy
+msgid "editors_featured_edit_feature_submit"
+msgstr "Go"
+
+#: views/editors/featured.thtml:90 views/editors/featured.thtml:91
+#, fuzzy
+msgid "editors_featured_remove_feature"
+msgstr "Remove feature"
+
+#: views/editors/queue.thtml:46
+#, fuzzy
+msgid "editors_filter_queue"
+msgstr "Filter Queue"
+
+#: views/editors/queue.thtml:182
+#, fuzzy
+msgid "editors_helpful_links"
+msgstr "Helpful Links"
+
+#: views/editors/queue.thtml:182
+#, fuzzy
+msgid "editors_link_guide"
+msgstr "Editors' Guide"
+
+#: views/editors/queue.thtml:182
+#, fuzzy
+msgid "editors_link_policy"
+msgstr "Add-on Policy"
+
+#: views/editors/queue.thtml:47
+#, fuzzy
+msgid "editors_notice_filter_session"
+msgstr "These filters will remain in place for this session or until cleared."
+
+# %1 is the queue mode
+#. %1 is the queue mode
+#: views/editors/queue.thtml:177 views/admin/flagged_queue.thtml:89
+#, fuzzy
+msgid "editors_notice_none_found"
+msgstr "There are currently no add-ons of this type to review."
+
+#: controllers/editors_controller.php:1040
+#, fuzzy
+msgid "editors_one_day"
+msgstr "1 day"
+
+#: controllers/editors_controller.php:1048
+#, fuzzy
+msgid "editors_one_hour"
+msgstr "1 hour"
+
+#: controllers/editors_controller.php:1056
+#, fuzzy
+msgid "editors_one_minute"
+msgstr "1 minute"
+
+#: controllers/editors_controller.php:64 controllers/editors_controller.php:73
+#: controllers/editors_controller.php:77
+#, fuzzy
+msgid "editors_pagetitle"
+msgstr "Editor Tools"
+
+#. %s is a comma separated list of platforms. Example: Windows, OS X
+#: controllers/editors_controller.php:680
+#: controllers/editors_controller.php:683
+#, fuzzy, php-format
+msgid "editors_platform_x_only"
+msgstr "%s only"
+
+#: controllers/editors_controller.php:695
+#, fuzzy
+msgid "editors_pre-release"
+msgstr "Pre-release"
+
+# %1 is the app name
+#. %1 is the app name
+#: views/editors/queue.thtml:131
+#, fuzzy, php-format
+msgid "editors_queue_app_compatibility"
+msgstr "%s Compatibility"
+
+#: views/editors/queue.thtml:51
+#, fuzzy
+msgid "editors_queue_filter_label_addon"
+msgstr "Add-on or Author Email"
+
+#: views/editors/queue.thtml:72
+#, fuzzy
+msgid "editors_queue_filter_label_addontypes"
+msgstr "Add-on Types"
+
+#: views/editors/queue.thtml:56
+#, fuzzy
+msgid "editors_queue_filter_label_application"
+msgstr "Application"
+
+#: views/editors/queue.thtml:61
+#, fuzzy
+msgid "editors_queue_filter_label_maxversion"
+msgstr "Max. Version"
+
+#: views/editors/queue.thtml:78
+#, fuzzy
+msgid "editors_queue_filter_label_platforms"
+msgstr "Platforms"
+
+#: views/editors/queue.thtml:66
+#, fuzzy
+msgid "editors_queue_filter_label_submissionage"
+msgstr "Age of Submission (days)"
+
+#. %1$s is a number
+#: views/editors/queue.thtml:90
+#, fuzzy
+msgid "editors_queue_filter_result_count"
+msgid_plural "editors_queue_filter_result_count"
+msgstr[0] "Results of your filtered search: <strong>%1$s</strong> Add-on"
+msgstr[1] "Results of your filtered search: <strong>%1$s</strong> Add-ons"
+
+#: views/editors/queue.thtml:84
+#, fuzzy
+msgid "editors_queue_submit_clean"
+msgstr "Clear"
+
+#: views/editors/queue.thtml:83
+#, fuzzy
+msgid "editors_queue_submit_filter"
+msgstr "Filter"
+
+#: controllers/editors_controller.php:133
+#, fuzzy
+msgid "editors_queues_disabled"
+msgstr ""
+"All review queues are currently disabled. Please check back at a later time."
+
+#: views/editors/review.thtml:149
+#, fuzzy
+msgid "editors_review_a_edit_item"
+msgstr "Edit Item"
+
+#: views/editors/review.thtml:146
+#, fuzzy
+msgid "editors_review_a_item_history"
+msgstr "Item History"
+
+#: views/editors/review.thtml:148
+#, fuzzy
+msgid "editors_review_a_item_homepage"
+msgstr "Item Homepage"
+
+#: views/editors/review.thtml:145
+#, fuzzy
+msgid "editors_review_a_item_overview"
+msgstr "Item Overview"
+
+#: views/editors/review.thtml:147
+#, fuzzy
+msgid "editors_review_a_previews"
+msgstr "Previews"
+
+#: controllers/editors_controller.php:345
+#, fuzzy
+msgid "editors_review_action"
+msgstr "Review Action"
+
+#: views/editors/review.thtml:159
+#, fuzzy
+msgid "editors_review_action_info"
+msgstr "Request More Information"
+
+#: views/editors/review.thtml:157
+#, fuzzy
+msgid "editors_review_action_public"
+msgstr "Push to Public"
+
+#: views/editors/review.thtml:160
+#, fuzzy
+msgid "editors_review_action_request_superreview"
+msgstr "Request Super-Review"
+
+#: views/editors/review.thtml:158
+#, fuzzy
+msgid "editors_review_action_sandbox"
+msgstr "Retain in Sandbox"
+
+#: controllers/editors_controller.php:346
+#, fuzzy
+msgid "editors_review_comments"
+msgstr "Review Comments"
+
+#: views/editors/review.thtml:182
+#, fuzzy
+msgid "editors_review_details_info_request"
+msgstr ""
+"Use this form to request more information from the author. They will receive "
+"an email and be able to answer here. You will be notified by email when they "
+"reply."
+
+#: views/editors/review.thtml:174
+#, fuzzy
+msgid "editors_review_details_nominated_public"
+msgstr ""
+"This will mark the add-on and its most recent version and files as public. "
+"Future versions will go into the sandbox until they are reviewed by an "
+"editor."
+
+#: views/editors/review.thtml:177
+#, fuzzy
+msgid "editors_review_details_nominated_sandbox"
+msgstr "This will retain the add-on in the sandbox."
+
+#: views/editors/review.thtml:166
+#, fuzzy
+msgid "editors_review_details_pending_public"
+msgstr ""
+"This will approve a sandboxed version of a public add-on to appear on the "
+"public side."
+
+#: views/editors/review.thtml:169
+#, fuzzy
+msgid "editors_review_details_pending_sandbox"
+msgstr ""
+"This will cause a sandboxed version of a public add-on to remain in the "
+"sandbox."
+
+#: views/editors/review.thtml:185
+#, fuzzy
+msgid "editors_review_details_superreview"
+msgstr ""
+"If you have concerns about this add-on's security, copyright issues, or "
+"other concerns that an administrator should look into, enter your comments "
+"in the area below. They will be sent to administrators, not the author."
+
+#: views/editors/review.thtml:134
+#, fuzzy
+msgid "editors_review_file_diff_link"
+msgstr "Compare with public version"
+
+#: views/editors/review.thtml:131
+#, fuzzy
+msgid "editors_review_file_viewcontents_link"
+msgstr "View Contents"
+
+#: views/editors/review.thtml:65
+#, fuzzy
+msgid "editors_review_header_authors"
+msgstr "Authors:"
+
+#: views/editors/review.thtml:79
+#, fuzzy
+msgid "editors_review_header_categories"
+msgstr "Categories:"
+
+#: views/editors/review.thtml:92
+#, fuzzy
+msgid "editors_review_header_compatibility"
+msgstr "Compatibility:"
+
+#: views/editors/review.thtml:251
+#, fuzzy
+msgid "editors_review_header_description"
+msgstr "Description"
+
+#: views/editors/review.thtml:275
+#, fuzzy
+msgid "editors_review_header_devcomments"
+msgstr "Developer Comments"
+
+#: views/editors/review.thtml:263
+#, fuzzy
+msgid "editors_review_header_eula"
+msgstr "EULA"
+
+#: views/editors/review.thtml:115
+#, fuzzy
+msgid "editors_review_header_files"
+msgstr "Files:"
+
+#: views/editors/review.thtml:284
+#, fuzzy
+msgid "editors_review_header_itemhistory"
+msgstr "Item History"
+
+#: views/editors/review.thtml:232
+#, fuzzy
+msgid "editors_review_header_nominationmessage"
+msgstr "Nomination Message"
+
+#: views/editors/review.thtml:311
+#, fuzzy
+msgid "editors_review_header_previews"
+msgstr "Previews"
+
+#: views/editors/review.thtml:269
+#, fuzzy
+msgid "editors_review_header_privacy"
+msgstr "Privacy Policy"
+
+# %1 is the addon name and version
+#. %1 is the add-on name and version
+#: views/editors/review.thtml:56
+#, fuzzy, php-format
+msgid "editors_review_header_review"
+msgstr "Review %s"
+
+#: views/editors/review.thtml:239
+#, fuzzy
+msgid "editors_review_header_reviewernotes"
+msgstr "Notes to Reviewer"
+
+#: views/editors/review.thtml:245
+#, fuzzy
+msgid "editors_review_header_summary"
+msgstr "Summary"
+
+#: views/editors/review.thtml:257
+#, fuzzy
+msgid "editors_review_header_versionnotes"
+msgstr "Version Notes"
+
+#. a noun: shown in an add-on's editor review history
+#: views/elements/developers/editors_review_history_item.thtml:80
+#, fuzzy
+msgid "editors_review_history_info_reply"
+msgstr "Reply"
+
+#: views/elements/developers/editors_review_history_item.thtml:78
+#, fuzzy
+msgid "editors_review_history_info_request"
+msgstr "Information Request"
+
+#: views/elements/developers/editors_review_history_item.thtml:62
+#: views/editors/reviewlog.thtml:77
+#, fuzzy
+msgid "editors_review_history_nominated_adminreview"
+msgstr "Admin Review"
+
+#: views/elements/developers/editors_review_history_item.thtml:56
+#: views/editors/reviewlog.thtml:71
+#, fuzzy
+msgid "editors_review_history_nominated_approved"
+msgstr "Nomination Approved/Public"
+
+#: views/elements/developers/editors_review_history_item.thtml:59
+#: views/editors/reviewlog.thtml:74
+#, fuzzy
+msgid "editors_review_history_nominated_denied"
+msgstr "Nomination Denied/Sandbox"
+
+#: views/editors/review.thtml:303
+#, fuzzy
+msgid "editors_review_history_nonefound"
+msgstr "No previous review entries could be found."
+
+#: views/elements/developers/editors_review_history_item.thtml:73
+#: views/editors/reviewlog.thtml:88
+#, fuzzy
+msgid "editors_review_history_pending_adminreview"
+msgstr "Admin Review"
+
+#: views/elements/developers/editors_review_history_item.thtml:67
+#: views/editors/reviewlog.thtml:82
+#, fuzzy
+msgid "editors_review_history_pending_approved"
+msgstr "Approved/Public"
+
+#: views/elements/developers/editors_review_history_item.thtml:70
+#: views/editors/reviewlog.thtml:85
+#, fuzzy
+msgid "editors_review_history_pending_denied"
+msgstr "Denied/Sandbox"
+
+#. link text in an add-on's editor review history, allowing to hide and show an information request's replies
+#. %1 is the number of replies
+#: views/elements/developers/editors_review_history_item.thtml:90
+#, fuzzy
+msgid "editors_review_history_show_hide_replies"
+msgid_plural "editors_review_history_show_hide_replies"
+msgstr[0] "Show/Hide Replies (%1$s)"
+msgstr[1] "Show/Hide Replies (%1$s)"
+
+#: views/editors/review.thtml:208
+#, fuzzy
+msgid "editors_review_label_applications"
+msgstr "Applications:"
+
+#: views/editors/review.thtml:196
+#, fuzzy
+msgid "editors_review_label_cannedresponse"
+msgstr "or select a canned response:"
+
+#: views/editors/review.thtml:190
+#, fuzzy
+msgid "editors_review_label_comments"
+msgstr "Comments:"
+
+#: views/editors/review.thtml:204
+#, fuzzy
+msgid "editors_review_label_operating_systems"
+msgstr "Operating Systems:"
+
+#: views/editors/review.thtml:285 views/editors/review.thtml:312
+#, fuzzy
+msgid "editors_review_link_pagetop"
+msgstr "Top"
+
+#: views/editors/review.thtml:141
+#, fuzzy
+msgid "editors_review_mulitple_notice"
+msgstr ""
+"Notice: Only review more than one file if you have tested EVERY file you "
+"select."
+
+#: views/editors/review.thtml:51
+#, fuzzy
+msgid "editors_review_next_link"
+msgstr "next &raquo;"
+
+#: views/editors/review.thtml:322
+#, fuzzy
+msgid "editors_review_previews_notfound"
+msgstr "No previews found."
+
+#: views/editors/review.thtml:50
+#, fuzzy
+msgid "editors_review_previous_link"
+msgstr "&laquo; prev"
+
+#: controllers/editors_controller.php:144
+#: controllers/editors_controller.php:146
+#, fuzzy
+msgid "editors_review_queue_pagetitle"
+msgstr "Review Queue"
+
+# %1 is the add-ons rank in the queue, %2 is the total queue length
+#. %1 is the add-ons rank in the queue, %2 is the total queue length
+#: views/editors/review.thtml:47
+#, fuzzy
+msgid "editors_review_rank_in_queue"
+msgstr "<strong># %1$s</strong> of %2$s in queue"
+
+#. %1 is the add-ons rank in the queue, %2 is the total queue length. Both numbers
+#: views/editors/review.thtml:45
+#, fuzzy
+msgid "editors_review_rank_in_queue_filtered"
+msgstr "<strong># %1$s</strong> of %2$s in queue (filtered)"
+
+#: views/editors/review.thtml:223
+#, fuzzy
+msgid "editors_review_submit_process_action"
+msgstr "Process Action"
+
+#: views/editors/review.thtml:293
+#, fuzzy
+msgid "editors_review_th_action"
+msgstr "Action"
+
+#: views/editors/review.thtml:294
+#, fuzzy
+msgid "editors_review_th_comments"
+msgstr "Comments"
+
+#: views/editors/review.thtml:291
+#, fuzzy
+msgid "editors_review_th_date"
+msgstr "Date"
+
+#: views/editors/review.thtml:292
+#, fuzzy
+msgid "editors_review_th_reviewer"
+msgstr "Reviewer"
+
+#: views/editors/review.thtml:290
+#, fuzzy
+msgid "editors_review_th_version_file"
+msgstr "Version/File"
+
+#: views/editors/review.thtml:217
+#, fuzzy
+msgid "editors_review_update_notify_once"
+msgstr ""
+"Notify me the next time this add-on is updated. (Subsequent updates will not "
+"generate an email)"
+
+#: controllers/editors_controller.php:298
+#, fuzzy
+msgid "editors_reviewed_successfully"
+msgstr "Review successfully processed."
+
+#: views/editors/reviews_queue.thtml:106
+#, fuzzy
+msgid "editors_reviews_action_delete_review"
+msgstr "Delete review"
+
+#: views/editors/reviews_queue.thtml:104
+#, fuzzy
+msgid "editors_reviews_action_keep"
+msgstr "Remove flags; keep review"
+
+#: views/editors/reviews_queue.thtml:102
+#, fuzzy
+msgid "editors_reviews_action_skip"
+msgstr "Skip"
+
+#: views/editors/reviews_queue.thtml:100
+#, fuzzy
+msgid "editors_reviews_header_action"
+msgstr "Action"
+
+#: views/editors/reviews_queue.thtml:67
+#, fuzzy
+msgid "editors_reviews_in_reply_to"
+msgstr "In reply to:"
+
+#: controllers/editors_controller.php:748
+#, fuzzy
+msgid "editors_reviews_processed"
+msgstr "Reviews processed successfully!"
+
+#: views/editors/reviews_queue.thtml:117
+#, fuzzy
+msgid "editors_reviews_queue_empty"
+msgstr "There are currently no reviews in moderation."
+
+#: views/editors/reviews_queue.thtml:111
+#, fuzzy
+msgid "editors_reviews_submit_process_reviews"
+msgstr "Process Reviews"
+
+#: controllers/editors_controller.php:691
+#, fuzzy
+msgid "editors_site_specific"
+msgstr "Site Specific"
+
+#: controllers/editors_controller.php:348
+#, fuzzy
+msgid "editors_tested_app"
+msgstr "Tested Application"
+
+#: controllers/editors_controller.php:347
+#, fuzzy
+msgid "editors_tested_os"
+msgstr "Tested Operating Systems"
+
+#: views/editors/queue.thtml:151
+#, fuzzy
+msgid "editors_th_additional_info"
+msgstr "Additional Information"
+
+#: views/editors/featured.thtml:63 views/editors/queue.thtml:109
+#: views/admin/flagged_queue.thtml:53
+#, fuzzy
+msgid "editors_th_addon"
+msgstr "Add-on"
+
+#: views/editors/queue.thtml:125
+#, fuzzy
+msgid "editors_th_addontype"
+msgstr "Type"
+
+#: views/editors/featured.thtml:64
+#, fuzzy
+msgid "editors_th_locales"
+msgstr "Restrict to locales?"
+
+#: views/editors/queue.thtml:148
+#, fuzzy
+msgid "editors_th_nomination_age"
+msgstr "Time in Queue"
+
+#: views/editors/queue.thtml:101 views/editors/queue.thtml:117
+#: views/editors/queue.thtml:144
+#, fuzzy
+msgid "editors_th_sort_ascending"
+msgstr "Ascending sort"
+
+#: views/editors/queue.thtml:105 views/editors/queue.thtml:121
+#: views/editors/queue.thtml:140
+#, fuzzy
+msgid "editors_th_sort_descending"
+msgstr "Descending sort"
+
+#. %s is a number
+#: controllers/editors_controller.php:1036
+#, fuzzy, php-format
+msgid "editors_x_days"
+msgstr "%s days"
+
+#. %s is a number
+#: controllers/editors_controller.php:1044
+#, fuzzy, php-format
+msgid "editors_x_hours"
+msgstr "%s hours"
+
+#. %s is a number
+#: controllers/editors_controller.php:1052
+#, fuzzy, php-format
+msgid "editors_x_minutes"
+msgstr "%s minutes"
+
+#: views/errors/error401.thtml:50 controllers/components/simple_acl.php:81
+#: controllers/components/simple_acl.php:82
+#: controllers/components/simple_acl.php:83 controllers/components/amo.php:607
+#: controllers/components/amo.php:608 controllers/components/amo.php:609
+#: controllers/reviews_controller.php:353
+#: controllers/reviews_controller.php:485
+#: controllers/collections_controller.php:438
+#: controllers/collections_controller.php:496
+#: controllers/collections_controller.php:504
+#: controllers/collections_controller.php:971
+#: controllers/collections_controller.php:1034
+#: controllers/collections_controller.php:1077
+#, fuzzy
+msgid "error_access_denied"
+msgstr "Access Denied"
+
+#: views/errors/error401.thtml:52
+#, fuzzy
+msgid "error_access_denied_message"
+msgstr "You are not authorized to view this page."
+
+#: controllers/collections_controller.php:1039
+#, fuzzy
+msgid "error_addon_exists"
+msgstr "Add-on already exists!"
+
+#: controllers/developers_controller.php:200
+#: controllers/developers_controller.php:593
+#: controllers/developers_controller.php:1016
+#: controllers/developers_controller.php:1429
+#: controllers/downloads_controller.php:95
+#: controllers/downloads_controller.php:102
+#: controllers/downloads_controller.php:164
+#: controllers/statistics_controller.php:135
+#: controllers/previews_controller.php:115
+#: controllers/previews_controller.php:206
+#: controllers/previews_controller.php:307
+#: controllers/reviews_controller.php:77
+#: controllers/reviews_controller.php:240
+#: controllers/reviews_controller.php:332
+#: controllers/reviews_controller.php:340 controllers/api_controller.php:123
+#: controllers/api_controller.php:759 controllers/addons_controller.php:131
+#: controllers/addons_controller.php:197
+#: controllers/addons_controller.php:1407
+#: controllers/addons_controller.php:1465
+#: controllers/addons_controller.php:1469
+#: controllers/addons_controller.php:1503
+#: controllers/editors_controller.php:265
+#: controllers/collections_controller.php:1041
+#: controllers/collections_controller.php:1074
+#, fuzzy
+msgid "error_addon_notfound"
+msgstr "Add-on not found!"
+
+#: controllers/files_controller.php:83 controllers/files_controller.php:196
+#, fuzzy
+msgid "error_addon_notviewable"
+msgstr "This add-on is not viewable here."
+
+#: controllers/reviews_controller.php:246
+#, fuzzy
+msgid "error_addon_selfreview"
+msgstr "You cannot review your own add-on."
+
+#: controllers/addons_controller.php:970
+#, fuzzy
+msgid "error_browse_no_addons"
+msgstr "No add-ons in this category!"
+
+#: controllers/api_controller.php:424
+#, fuzzy
+msgid "error_collection_feed_notfound"
+msgstr "Add-on feed not found."
+
+#: views/users/register.thtml:65 views/users/edit.thtml:194
+#, fuzzy
+msgid "error_email_invalid"
+msgstr "This is not a valid email address."
+
+#: views/users/pwreset.thtml:74 views/users/register.thtml:70
+#: views/users/register.thtml:80 views/users/register.thtml:86
+#: views/users/edit.thtml:105 views/users/edit.thtml:111
+#: views/users/edit.thtml:192 views/admin/users_edit.thtml:78
+#: views/admin/users_edit.thtml:83 views/reviews/add.thtml:80
+#: views/reviews/add.thtml:104
+#, fuzzy
+msgid "error_field_required"
+msgstr "This field must not be empty."
+
+#: controllers/files_controller.php:75 controllers/files_controller.php:93
+#: controllers/files_controller.php:96 controllers/files_controller.php:163
+#: controllers/files_controller.php:176 controllers/files_controller.php:185
+#: controllers/files_controller.php:204 controllers/editors_controller.php:412
+#, fuzzy
+msgid "error_file_notfound"
+msgstr "File not found!"
+
+#. %s is a filename
+#: controllers/editors_controller.php:430
+#, fuzzy, php-format
+msgid "error_file_x_notfound"
+msgstr "File error: %s does not exist."
+
+#: views/collections/add.thtml:55 views/collections/edit.thtml:89
+#: views/users/register.thtml:54 views/users/edit.thtml:81
+#: views/reviews/add.thtml:70 controllers/groups_controller.php:80
+#: controllers/groups_controller.php:102
+#, fuzzy
+msgid "error_formerrors"
+msgstr "There are errors in this form. Please correct them and resubmit."
+
+#: views/users/register.thtml:109
+#, fuzzy
+msgid "error_invalid_captcha"
+msgstr "Invalid captcha, please try again!"
+
+#: views/users/register.thtml:100 views/users/edit.thtml:125
+#: views/admin/users_edit.thtml:101
+#, fuzzy
+msgid "error_invalid_url"
+msgstr ""
+"This URL has an invalid format. Valid URLs look like http://example.com/"
+"my_page."
+
+#. %s is a string representing what's missing. Example: file_id
+#: controllers/downloads_controller.php:65
+#: controllers/users_controller.php:185 controllers/users_controller.php:264
+#: controllers/users_controller.php:559 controllers/users_controller.php:653
+#: controllers/reviews_controller.php:71
+#: controllers/reviews_controller.php:234
+#: controllers/reviews_controller.php:325
+#: controllers/reviews_controller.php:473
+#: controllers/reviews_controller.php:475
+#: controllers/addons_controller.php:182
+#: controllers/addons_controller.php:1381
+#: controllers/addons_controller.php:1455
+#: controllers/collections_controller.php:266
+#: controllers/collections_controller.php:285
+#: controllers/collections_controller.php:346
+#: controllers/collections_controller.php:443
+#: controllers/collections_controller.php:482
+#: controllers/collections_controller.php:936
+#: controllers/collections_controller.php:959
+#: controllers/collections_controller.php:960
+#: controllers/collections_controller.php:975
+#: controllers/collections_controller.php:977
+#: controllers/collections_controller.php:994
+#: controllers/collections_controller.php:1003
+#: controllers/collections_controller.php:1016
+#: controllers/collections_controller.php:1017
+#: controllers/collections_controller.php:1024
+#: controllers/collections_controller.php:1070
+#: controllers/collections_controller.php:1090
+#, fuzzy, php-format
+msgid "error_missing_argument"
+msgstr "Missing argument: %s"
+
+#: controllers/components/amo.php:507 controllers/components/amo.php:532
+#, fuzzy
+msgid "error_no_files_in_addon"
+msgstr "No Files"
+
+#: controllers/previews_controller.php:200
+#, fuzzy
+msgid "error_preview_notfound"
+msgstr "Preview not found!"
+
+#: views/addons/display.thtml:400 views/reviews/add.thtml:98
+#, fuzzy
+msgid "error_review_rating_required"
+msgstr "You must select a rating."
+
+#: controllers/users_controller.php:160
+#, fuzzy
+msgid "error_user_already_confirmed"
+msgstr "This user account is already confirmed."
+
+#: controllers/users_controller.php:202 controllers/users_controller.php:276
+#: controllers/users_controller.php:569 controllers/users_controller.php:581
+#: controllers/users_controller.php:587 controllers/users_controller.php:610
+#: controllers/users_controller.php:627
+#, fuzzy
+msgid "error_user_badconfirmationcode"
+msgstr "Invalid confirmation code!"
+
+#: views/users/pwreset.thtml:79 views/users/register.thtml:75
+#: views/users/edit.thtml:183
+#, fuzzy
+msgid "error_user_confirmpw_nomatch"
+msgstr "The passwords did not match."
+
+#: views/users/register.thtml:65 views/users/edit.thtml:190
+#: controllers/users_controller.php:617
+#, fuzzy
+msgid "error_user_email_notunique"
+msgstr "This email address is already taken by another user."
+
+#: controllers/users_controller.php:596
+#, fuzzy
+msgid "error_user_emailchange_expired"
+msgstr ""
+"The email change has expired. Please change your email address again in your "
+"user profile and click the link in the confirmation email as soon as you "
+"receive it."
+
+#: controllers/collections_controller.php:985
+#, fuzzy
+msgid "error_user_exists"
+msgstr ""
+"Users can only have one role at a time. Please remove the user from any "
+"existing roles before continuing."
+
+#: views/users/register.thtml:91 views/users/edit.thtml:116
+#: views/admin/users_edit.thtml:88
+#, fuzzy
+msgid "error_user_nickname_notunique"
+msgstr "This nickname is already taken."
+
+#: views/users/pwreset.thtml:54 controllers/users_controller.php:191
+#: controllers/users_controller.php:270 controllers/users_controller.php:603
+#: controllers/users_controller.php:659
+#: controllers/collections_controller.php:988
+#: controllers/collections_controller.php:998
+#, fuzzy
+msgid "error_user_notfound"
+msgstr "User not found!"
+
+#: views/users/activatefirst.thtml:47
+#, fuzzy
+msgid "error_user_unconfirmed"
+msgstr ""
+"Please confirm your user account first with the code you received by email."
+
+#: views/users/login.thtml:67
+#, fuzzy
+msgid "error_username_or_pw_wrong"
+msgstr "Wrong username or password!"
+
+#: controllers/editors_controller.php:260
+#, fuzzy
+msgid "error_version_notfound"
+msgstr "Version not found!"
+
+#: views/users/delete.thtml:125 views/users/edit.thtml:173
+#, fuzzy
+msgid "error_wrong_password"
+msgstr "Wrong password entered!"
+
+#: views/elements/amo2009/homepage_addon.thtml:122
+#: views/elements/feature.thtml:122
+#, fuzzy
+msgid "feature_learnmore"
+msgstr "Learn more"
+
+# %1 is the add-on name
+#. %1 is the add-on name
+#: views/elements/amo2009/homepage_addon.thtml:123
+#: views/elements/feature.thtml:123
+#, fuzzy, php-format
+msgid "feature_learnmore_about_addon"
+msgstr "Learn more about %1$s"
+
+#. %1$s is a number
+#: views/elements/amo2009/reviews.thtml:52
+#: views/elements/addon_listitem.thtml:112 views/elements/feature.thtml:99
+#: views/addons/browse_thumbs.thtml:86
+#, fuzzy, php-format
+msgid "feature_reviews"
+msgid_plural "feature_reviews"
+msgstr[0] "%1$s review"
+msgstr[1] "%1$s reviews"
+
+#: views/elements/amo2009/homepage_addon.thtml:127
+#: views/elements/feature.thtml:127
+#, fuzzy
+msgid "feature_view_more_from_category"
+msgstr "View more from"
+
+#. This appears on a page that views the source of an add-on. This link will return
+#. the user to the add-on's main page
+#: views/files/browse.thtml:65
+#, fuzzy
+msgid "file_browser_link_addon"
+msgstr "Back to add-on"
+
+#. There is a list of directories and files on the page. Clicking this will show the
+#. contents of all the directories (normally you would click on each one to see the
+#. contents)
+#: views/files/browse.thtml:67
+#, fuzzy
+msgid "file_browser_link_expand_all"
+msgstr "Expand all"
+
+#. This appears on a page that views the source of an add-on. This link will return
+#. the user to the add-on's review page (it only appears if the add-on is being
+#. reviewed)
+#: views/files/browse.thtml:64
+#, fuzzy
+msgid "file_browser_link_review"
+msgstr "Back to review"
+
+#. The title of the page for viewing an add-on's source.
+#. %1$s is the name of the add-on
+#. %2$s is the name of the current application (e.g. Firefox or Thunderbird)
+#: views/files/browse.thtml:46
+#, fuzzy
+msgid "file_browser_title"
+msgstr "%1$s :: File Browser :: %2$s Add-ons"
+
+#. This appears on a page that views the source of an add-on. There is a list of
+#. directories and files on the page. Clicking this link will toggle between an
+#. expanded or a collapsed list. This string should be kept short.
+#: views/files/browse.thtml:68
+#, fuzzy
+msgid "file_browser_toggle_expand_collapse"
+msgstr "+/-"
+
+#. Link text for the AMO About page.
+#: views/elements/footer.thtml:72 views/layouts/amo2009.thtml:341
+#, fuzzy
+msgid "footer_a_about"
+msgstr "About"
+
+#. Link text to the AMO blog.
+#: views/elements/footer.thtml:74 views/layouts/amo2009.thtml:343
+#, fuzzy
+msgid "footer_a_blog"
+msgstr "Blog"
+
+#. Link text to the Frequently Asked Questions page.
+#: views/elements/footer.thtml:73 views/layouts/amo2009.thtml:342
+#, fuzzy
+msgid "footer_a_faq"
+msgstr "FAQ"
+
+#. Full text for the FAQ abbreviation.
+#: views/elements/footer.thtml:73 views/pages/collector_features.thtml:72
+#: views/layouts/amo2009.thtml:342
+#, fuzzy
+msgid "footer_abbr_faq"
+msgstr "Frequently Asked Questions"
+
+#: views/elements/footer.thtml:67 views/layouts/amo2009.thtml:336
+#, fuzzy
+msgid "footer_all_rights_reserved"
+msgstr "All rights reserved."
+
+#: views/elements/footer.thtml:67 views/layouts/amo2009.thtml:336
+#, fuzzy
+msgid "footer_copyright"
+msgstr "Copyright"
+
+#: views/elements/footer.thtml:71 views/layouts/amo2009.thtml:340
+#, fuzzy
+msgid "footer_credits"
+msgstr "Credits"
+
+#: views/elements/footer.thtml:76 views/layouts/amo2009.thtml:346
+#, fuzzy
+msgid "footer_disclaimer"
+msgstr ""
+"Mozilla is providing links to these applications as a courtesy, and makes no "
+"representations regarding the applications or any information related there "
+"to. Any questions, complaints or claims regarding the applications must be "
+"directed to the appropriate software vendor."
+
+#: views/elements/footer.thtml:61 views/layouts/amo2009.thtml:332
+#, fuzzy
+msgid "footer_lang_form_lang_submit_go"
+msgstr "Go"
+
+#: views/elements/footer.thtml:70 views/layouts/amo2009.thtml:339
+#, fuzzy
+msgid "footer_legal_notices"
+msgstr "Legal Notices"
+
+#: views/elements/footer.thtml:50 views/layouts/amo2009.thtml:321
+#, fuzzy
+msgid "footer_other_languages"
+msgstr "Other languages:"
+
+#: views/elements/footer.thtml:69 views/layouts/amo2009.thtml:338
+#, fuzzy
+msgid "footer_privacy_policy"
+msgstr "Privacy Policy"
+
+#: models/addontype.php:79
+#, fuzzy
+msgid "general_addontype_dict"
+msgstr "Dictionary"
+
+# Plural in this context means many of the add-on type
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:100
+#, fuzzy
+msgid "general_addontype_dict_plural"
+msgstr "Dictionaries"
+
+#: models/addontype.php:75
+#, fuzzy
+msgid "general_addontype_extension"
+msgstr "Extension"
+
+# Plural in this context means many of the add-on type
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:98
+#, fuzzy
+msgid "general_addontype_extension_plural"
+msgstr "Extensions"
+
+#: models/addontype.php:85
+#, fuzzy
+msgid "general_addontype_lpaddon"
+msgstr "Language Pack (Add-on)"
+
+# Plural in this context means many of the add-on type
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:103
+#, fuzzy
+msgid "general_addontype_lpaddon_plural"
+msgstr "Language Packs (Add-on)"
+
+#: models/addontype.php:83
+#, fuzzy
+msgid "general_addontype_lpapp"
+msgstr "Language Pack (Application)"
+
+# Plural in this context means many of the add-on type
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:102
+#, fuzzy
+msgid "general_addontype_lpapp_plural"
+msgstr "Language Packs (Application)"
+
+#: models/addontype.php:87
+#, fuzzy
+msgid "general_addontype_plugin"
+msgstr "Plugin"
+
+# Plural in this context means many of the add-on type
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:104
+#, fuzzy
+msgid "general_addontype_plugin_plural"
+msgstr "Plugins"
+
+#: models/addontype.php:81
+#, fuzzy
+msgid "general_addontype_search"
+msgstr "Search Engine"
+
+# Plural in this context means many of the add-on type
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:101
+#, fuzzy
+msgid "general_addontype_search_plural"
+msgstr "Search Engines"
+
+#: models/addontype.php:77
+#, fuzzy
+msgid "general_addontype_theme"
+msgstr "Theme"
+
+# Plural in this context means many of the add-on type
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:99
+#, fuzzy
+msgid "general_addontype_theme_plural"
+msgstr "Themes"
+
+#: config/language.php:367
+#, fuzzy
+msgid "general_languages_all_locales"
+msgstr "All Locales"
+
+#: views/layouts/amo2009.thtml:249
+#, fuzzy
+msgid "header_brand_name"
+msgstr "Mozilla"
+
+#. %1$s is the application name. Example: Firefox
+#: views/elements/header.thtml:111 views/elements/header.thtml:122
+#: views/layouts/amo2009.thtml:248
+#, fuzzy, php-format
+msgid "header_home_tooltip"
+msgstr "Return to the %1$s Add-ons homepage"
+
+#: views/elements/header.thtml:87
+#, fuzzy
+msgid "header_main_firefox_header"
+msgstr "Firefox Add-ons"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:218
+#, fuzzy
+msgid "header_main_firefox_header_with_logo"
+msgstr ""
+"Add-ons <em>for</em> <img alt=\"Firefox\" src=\"%1$s\" /> <strong>Firefox</"
+"strong>"
+
+#: views/elements/header.thtml:99
+#, fuzzy
+msgid "header_main_header"
+msgstr "Add-ons"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:242
+#, fuzzy
+msgid "header_main_header_with_logo"
+msgstr "Add-ons <img alt=\"Add-ons\" src=\"%1$s\" />"
+
+#: views/elements/header.thtml:90
+#, fuzzy
+msgid "header_main_seamonkey_header"
+msgstr "Seamonkey Add-ons"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:224
+#, fuzzy
+msgid "header_main_seamonkey_header_with_logo"
+msgstr ""
+"Add-ons <em>for</em> <img alt=\"seamonkey\" src=\"%1$s\" /> "
+"<strong>SeaMonkey</strong>"
+
+#: views/elements/header.thtml:93
+#, fuzzy
+msgid "header_main_sunbird_header"
+msgstr "Sunbird Add-ons"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:230
+#, fuzzy
+msgid "header_main_sunbird_header_with_logo"
+msgstr ""
+"Add-ons <em>for</em> <img alt=\"sunbird\" src=\"%1$s\" /> <strong>Sunbird</"
+"strong>"
+
+#: views/elements/header.thtml:96
+#, fuzzy
+msgid "header_main_thunderbird_header"
+msgstr "Thunderbird Add-ons"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:236
+#, fuzzy
+msgid "header_main_thunderbird_header_with_logo"
+msgstr ""
+"Add-ons <em>for</em> <img alt=\"thunderbird\" src=\"%1$s\" /> "
+"<strong>Thunderbird</strong>"
+
+#: views/layouts/amo2009.thtml:205
+#, fuzzy
+msgid "header_navaccess_applications_menu"
+msgstr "Skip to other applications menu"
+
+#: views/layouts/amo2009.thtml:204
+#, fuzzy
+msgid "header_navaccess_categories_menu"
+msgstr "Skip to categories menu"
+
+#: views/layouts/amo2009.thtml:202
+#, fuzzy
+msgid "header_navaccess_main_content"
+msgstr "Skip to main content"
+
+#: views/layouts/amo2009.thtml:203
+#, fuzzy
+msgid "header_navaccess_search_form"
+msgstr "Skip to search form"
+
+#: views/elements/header.thtml:62
+#, fuzzy
+msgid "header_navlink_addons"
+msgstr "Add-ons"
+
+#: views/elements/developers/sidebar.thtml:72
+#: views/elements/developers/myaddons.thtml:50 views/elements/header.thtml:159
+#: views/addons/display.thtml:378
+#, fuzzy
+msgid "header_navlink_login"
+msgstr "Log in"
+
+#: views/elements/header.thtml:156 views/layouts/amo2009.thtml:304
+#, fuzzy
+msgid "header_navlink_logout"
+msgstr "Log out"
+
+#: views/elements/header.thtml:145 views/layouts/amo2009.thtml:303
+#, fuzzy
+msgid "header_navlink_myaccount"
+msgstr "My Account"
+
+#: views/elements/header.thtml:158
+#, fuzzy
+msgid "header_navlink_register"
+msgstr "Register"
+
+#. %1 is the URL to the registration page
+#. %2 is the URL to the login page
+#: views/layouts/amo2009.thtml:278
+#, fuzzy
+msgid "header_navlink_register_or_login"
+msgstr "<a href=\"%1$s\">Register</a> or <a href=\"%2$s\">Log in</a>"
+
+#: views/layouts/amo2009.thtml:285
+#, fuzzy
+msgid "header_navlink_tools"
+msgstr "Tools"
+
+#. %s is the add-on name
+#: views/elements/collections_interactive_addon.thtml:62
+#: views/elements/amo2009/homepage_addon.thtml:77
+#: views/elements/addon_discussionheader.thtml:62
+#: views/elements/addon_listitem.thtml:67 views/elements/feature.thtml:84
+#: views/addons/category_landing.thtml:87 views/addons/browse_thumbs.thtml:60
+#, fuzzy, php-format
+msgid "img_preview_of"
+msgstr "Preview Image of %s"
+
+# %1 is the login URL for the link tag
+# %2 is the link to an explanatory page.
+#. %1 is the login URL for the link tag
+#. %2 is the link to an explanatory page.
+#: views/elements/amo2009/install.thtml:307 views/elements/install.thtml:255
+#, fuzzy
+msgid "install_a_login_to_install"
+msgstr ""
+"<a href=\"%1$s\">Log in</a> to install this experimental add-on. <a href=\"%2"
+"$s\">Why</a>?"
+
+#. %1 is the URL for the Experimental Add-ons section of the FAQ page
+#: views/elements/amo2009/install.thtml:283 views/elements/install.thtml:232
+#, fuzzy
+msgid "install_button_confirm_exp_install"
+msgstr ""
+"Let me install this experimental add-on. <a href=\"%1$s\">What's this?</a>"
+
+#. %1$s is the application name. Example: Firefox
+#. %2$s is an optional string used to specify a platform. Example: (Windows)
+#: views/elements/amo2009/install.thtml:128 views/elements/install.thtml:75
+#, fuzzy, php-format
+msgid "install_button_text"
+msgstr "Add to %s %s"
+
+# %1 is the add-on name, %2 is the app name
+#. %1 is the add-on name, %2 is the app name
+#: views/elements/amo2009/install.thtml:191
+#: views/elements/amo2009/install.thtml:206
+#: views/elements/amo2009/install.thtml:249
+#: views/elements/amo2009/install.thtml:298 views/elements/install.thtml:150
+#: views/elements/install.thtml:165 views/elements/install.thtml:202
+#: views/elements/install.thtml:246
+#, fuzzy, php-format
+msgid "install_button_title"
+msgstr "Add %1$s to %2$s"
+
+#. %1$s is the add-on name
+#: views/elements/amo2009/install.thtml:200 views/elements/install.thtml:159
+#, fuzzy, php-format
+msgid "install_download"
+msgstr "Download %1$s"
+
+#: views/elements/amo2009/install.thtml:147 views/elements/install.thtml:94
+#, fuzzy
+msgid "install_error_addon_not_found"
+msgstr "This add-on is not available."
+
+#: views/addons/dictionaries.thtml:65
+#, fuzzy
+msgid "langtools_a11y_tablesummary"
+msgstr "List of language packs and dictionaries."
+
+#: views/addons/dictionaries.thtml:47
+#, fuzzy
+msgid "langtools_download_dictionary"
+msgstr "Download Dictionary"
+
+#: views/addons/dictionaries.thtml:48
+#, fuzzy
+msgid "langtools_download_langpack"
+msgstr "Download Language Pack"
+
+#: views/addons/dictionaries.thtml:63 controllers/components/amo.php:685
+#: controllers/addons_controller.php:1239
+#, fuzzy
+msgid "langtools_header_dicts_and_langpacks"
+msgstr "Dictionaries & Language Packs"
+
+#: views/addons/dictionaries.thtml:44
+#, fuzzy
+msgid "langtools_install_dictionary"
+msgstr "Install Dictionary"
+
+#: views/addons/dictionaries.thtml:45
+#, fuzzy
+msgid "langtools_install_langpack"
+msgstr "Install Language Pack"
+
+#: views/addons/dictionaries.thtml:69
+#, fuzzy
+msgid "langtools_tableheader_dictionary"
+msgstr "Dictionary"
+
+#: views/addons/dictionaries.thtml:70
+#, fuzzy
+msgid "langtools_tableheader_langpack"
+msgstr "Language Pack"
+
+#: views/addons/dictionaries.thtml:68
+#, fuzzy
+msgid "langtools_tableheader_language"
+msgstr "Language"
+
+#: models/license.php:65
+#, fuzzy
+msgid "license_custom"
+msgstr "Custom License"
+
+#: config/bootstrap.php:303
+#, fuzzy
+msgid "licenses_bsd"
+msgstr "BSD License"
+
+#: config/bootstrap.php:298
+#, fuzzy
+msgid "licenses_gpl_2.0"
+msgstr "GNU General Public License, version 2.0"
+
+#: config/bootstrap.php:299
+#, fuzzy
+msgid "licenses_gpl_3.0"
+msgstr "GNU General Public License, version 3.0"
+
+#: config/bootstrap.php:300
+#, fuzzy
+msgid "licenses_lgpl_2.1"
+msgstr "GNU Lesser General Public License, version 2.1"
+
+#: config/bootstrap.php:301
+#, fuzzy
+msgid "licenses_lgpl_3.0"
+msgstr "GNU Lesser General Public License, version 3.0"
+
+#: config/bootstrap.php:302
+#, fuzzy
+msgid "licenses_mit"
+msgstr "MIT/X11 License"
+
+#: config/bootstrap.php:297
+#, fuzzy
+msgid "licenses_mpl_1.1"
+msgstr "Mozilla Public License, version 1.1"
+
+#: views/users/emailchange.thtml:51 views/users/delete.thtml:55
+#: views/users/delete.thtml:137 views/users/edit.thtml:74
+#: views/reviews/flag.thtml:54
+#, fuzzy
+msgid "link_return_to_front_page"
+msgstr "Click here to return to the front page."
+
+#: views/elements/amo2009/addon_list_options.thtml:46
+#: views/elements/addon_list_options.thtml:46
+#, fuzzy
+msgid "list_sortby_date"
+msgstr "Date"
+
+#: views/elements/amo2009/addon_list_options.thtml:47
+#: views/elements/addon_list_options.thtml:47
+#, fuzzy
+msgid "list_sortby_downloads"
+msgstr "Downloads"
+
+#: views/elements/amo2009/addon_list_options.thtml:45
+#: views/elements/addon_list_options.thtml:45
+#, fuzzy
+msgid "list_sortby_name"
+msgstr "Add-on Name"
+
+#: views/elements/amo2009/addon_list_options.thtml:48
+#: views/elements/addon_list_options.thtml:48
+#, fuzzy
+msgid "list_sortby_rating"
+msgstr "Rating"
+
+#: config/bootstrap.php:278
+#, fuzzy
+msgid "main_prettyname_fennec"
+msgstr "Fennec"
+
+#: config/bootstrap.php:274
+#, fuzzy
+msgid "main_prettyname_firefox"
+msgstr "Firefox"
+
+#: config/bootstrap.php:277
+#, fuzzy
+msgid "main_prettyname_seamonkey"
+msgstr "SeaMonkey"
+
+#: config/bootstrap.php:276
+#, fuzzy
+msgid "main_prettyname_sunbird"
+msgstr "Sunbird"
+
+#: config/bootstrap.php:275
+#, fuzzy
+msgid "main_prettyname_thunderbird"
+msgstr "Thunderbird"
+
+#: views/elements/addon_categories.thtml:52
+#, fuzzy
+msgid "nav_category_dicts_langpacks"
+msgstr "Dictionaries & Language Packs"
+
+#: views/elements/addon_categories.thtml:55
+#, fuzzy
+msgid "nav_category_themes"
+msgstr "Themes"
+
+#: views/elements/app_chooser.thtml:47 views/layouts/amo2009.thtml:255
+#, fuzzy
+msgid "other_apps_tooltip"
+msgstr "Find add-ons for other applications"
+
+# In a user list: user 1, user 2, "others"
+#. In a user list: user 1, user 2, "others"
+#: views/helpers/addons_html.php:222
+#, fuzzy
+msgid "other_users"
+msgstr "others"
+
+#: controllers/pages_controller.php:90
+#, fuzzy
+msgid "page_title_appversions"
+msgstr "Application Versions"
+
+#: controllers/pages_controller.php:115
+#, fuzzy
+msgid "page_title_collector"
+msgstr "Add-on Collector"
+
+#: controllers/pages_controller.php:117
+#, fuzzy
+msgid "page_title_collector_faq"
+msgstr "Add-on Collector FAQ"
+
+#: controllers/pages_controller.php:119
+#, fuzzy
+msgid "page_title_collector_features"
+msgstr "Add-on Collector Features"
+
+#: controllers/pages_controller.php:122
+#, fuzzy
+msgid "page_title_collector_firstrun"
+msgstr "Welcome to the Add-on Collector"
+
+#: controllers/pages_controller.php:92
+#, fuzzy
+msgid "page_title_credits"
+msgstr "Credits"
+
+#: controllers/pages_controller.php:113
+#, fuzzy
+msgid "page_title_developer_faq"
+msgstr "Developer FAQ"
+
+#: controllers/pages_controller.php:111
+#, fuzzy
+msgid "page_title_faq"
+msgstr "Frequently Asked Questions"
+
+#: controllers/pages_controller.php:94
+#, fuzzy
+msgid "page_title_fashionyourfirefox_faq"
+msgstr "Fashion your Firefox FAQ"
+
+#: controllers/pages_controller.php:101
+#, fuzzy
+msgid "page_title_policy"
+msgstr "Add-ons Policy"
+
+#: controllers/pages_controller.php:103
+#, fuzzy
+msgid "page_title_privacy"
+msgstr "Mozilla Privacy Policy"
+
+#: controllers/pages_controller.php:105
+#, fuzzy
+msgid "page_title_review_guide"
+msgstr "Review Guidelines"
+
+#: controllers/pages_controller.php:107
+#, fuzzy
+msgid "page_title_sandbox"
+msgstr "Sandbox Review System"
+
+#: controllers/pages_controller.php:109
+#, fuzzy
+msgid "page_title_submissionhelp"
+msgstr "Submission Help"
+
+#: views/pages/appversions.thtml:87
+#, fuzzy
+msgid "pages_appversions_guid"
+msgstr "GUID"
+
+#: views/pages/appversions.thtml:79 controllers/pages_controller.php:90
+#, fuzzy
+msgid "pages_appversions_header"
+msgstr "Valid Application Versions"
+
+#: views/pages/appversions.thtml:80
+#, fuzzy
+msgid "pages_appversions_intro"
+msgstr ""
+"Add-ons submitted to Mozilla Add-ons must have an install.rdf file with at "
+"least one of the below applications supported. Only the versions listed "
+"below are allowed for these applications."
+
+#. %s is a full <a> tag
+#: views/pages/appversions.thtml:93
+#, fuzzy, php-format
+msgid "pages_appversions_required_files"
+msgstr ""
+"If your supported application does not require an install.rdf file, you "
+"still must include one with the required properties as specified %s."
+
+#. this is the text inside of an <a> tag for pages_appversions_required_files. This
+#. should be fixed.
+#: views/pages/appversions.thtml:93
+#, fuzzy
+msgid "pages_appversions_required_files_link"
+msgstr "here"
+
+#: views/pages/appversions.thtml:88
+#, fuzzy
+msgid "pages_appversions_versions"
+msgstr "Versions"
+
+#: views/pages/policy.thtml:51
+#, fuzzy
+msgid "pages_policy_sandbox_link"
+msgstr "Sandbox Information Page"
+
+#: views/elements/pagination.thtml:53
+#, fuzzy
+msgid "pagination_next_page"
+msgstr "next"
+
+#: views/elements/pagination.thtml:52
+#, fuzzy
+msgid "pagination_previous_page"
+msgstr "previous"
+
+#: views/elements/recaptcha.thtml:65
+#, fuzzy
+msgid "recaptcha_enter_both_words"
+msgstr ""
+"Please enter <strong>both words</strong> below, <strong>separated by a "
+"space</strong>."
+
+#: views/elements/recaptcha.thtml:83
+#, fuzzy
+msgid "recaptcha_enter_here"
+msgstr "Enter your answer here:"
+
+#: views/elements/recaptcha.thtml:74
+#, fuzzy
+msgid "recaptcha_enter_whatyouhear"
+msgstr "Please type what you hear."
+
+# %1 is the link switching refreshing the captcha
+# %2 is the link switching to a text captcha
+#. %1 is the link switching refreshing the captcha
+#. %2 is the link switching to a text captcha
+#: views/elements/recaptcha.thtml:77
+#, fuzzy
+msgid "recaptcha_hardtohear_text"
+msgstr ""
+"If this is hard to understand, you can <a href=\"%1$s\">listen to something "
+"else</a> or <a href=\"%2$s\">switch back to text</a>."
+
+# %1 is the link switching refreshing the captcha
+# %2 is the link switching to an audio captcha
+#. %1 is the link switching refreshing the captcha
+#. %2 is the link switching to an audio captcha
+#: views/elements/recaptcha.thtml:68
+#, fuzzy
+msgid "recaptcha_hardtoread_text"
+msgstr ""
+"If this is hard to read, you can <a href=\"%1$s\">try different words</a> or "
+"<a href=\"%2$s\">listen to something</a> instead."
+
+#: views/users/register.thtml:105
+#, fuzzy
+msgid "recaptcha_label"
+msgstr "Are you human?"
+
+#: views/users/register.thtml:106
+#, fuzzy
+msgid "recaptcha_whatsthis"
+msgstr "What's this?"
+
+#: controllers/reviews_controller.php:559
+#, fuzzy
+msgid "review_flag_error"
+msgstr "Error flagging this review!"
+
+#: models/reviews_moderation_flag.php:69
+#, fuzzy
+msgid "review_flag_reason_bug_support"
+msgstr "Misplaced bug report or support request"
+
+#: views/reviews/display.thtml:103 views/reviews/display.thtml:186
+#, fuzzy
+msgid "review_flag_reason_instructions"
+msgstr "Report this review (select a reason)"
+
+#: models/reviews_moderation_flag.php:67
+#, fuzzy
+msgid "review_flag_reason_language"
+msgstr "Inappropriate language/dialog"
+
+#: models/reviews_moderation_flag.php:71
+#, fuzzy
+msgid "review_flag_reason_other"
+msgstr "Other (please specify)"
+
+#: models/reviews_moderation_flag.php:65
+#, fuzzy
+msgid "review_flag_reason_spam"
+msgstr "Spam or otherwise non-review content"
+
+#: views/reviews/display.thtml:91 views/reviews/display.thtml:175
+#: controllers/reviews_controller.php:555
+#, fuzzy
+msgid "review_flag_success"
+msgstr "Thanks; this review has been flagged for editor approval."
+
+#: views/reviews/display.thtml:41
+#, fuzzy
+msgid "review_flag_this"
+msgstr "Report this review"
+
+#: views/reviews/display.thtml:42
+#, fuzzy
+msgid "review_flag_this_titletip"
+msgstr ""
+"Is this review inappropriate, inaccurate or spam? Click here to flag it for "
+"editor review."
+
+# %1 is the URL of the support section, %2 for the review guidelines
+#. %1 is the URL of the support section, %2 for the review guidelines
+#: views/reviews/add.thtml:53
+#, fuzzy
+msgid "review_guidelines_short"
+msgstr ""
+"<p>Keep these tips in mind:</p><ul><li>Write like you're telling a friend "
+"about your experience with the add-on. Give specifics and helpful details, "
+"such as what features you liked and/or disliked, how easy to use it is, and "
+"any disadvantages it has. Avoid generic language such as calling it \"Great"
+"\" or \"Bad\" unless you can give reasons why you believe this is so.</"
+"li><li>Please do not post bug reports in reviews. We do not make your email "
+"address available to add-on developers and they may need to contact you to "
+"help resolve your issue. See the <a href=\"%1$s\">support section</a> to "
+"find out where to get assistance for this add-on.</li><li>Please keep "
+"reviews clean, avoid the use of improper language and do not post any "
+"personal information.</li></ul><p>Please read the <a href=\"%2$s\">Review "
+"Guidelines</a> for more detail about user add-on reviews.</p>"
+
+# %1 is the addon name
+#. %1 is the add-on name
+#: views/reviews/flag.thtml:56 views/reviews/display.thtml:55
+#: views/reviews/review_added.thtml:50
+#, fuzzy, php-format
+msgid "reviews_header"
+msgstr "Reviews for %s"
+
+#: controllers/addons_controller.php:435
+#, fuzzy
+msgid "rss_featuredaddons"
+msgstr "Featured Add-ons"
+
+#: controllers/addons_controller.php:432
+#, fuzzy
+msgid "rss_newestaddons"
+msgstr "Newest Add-ons"
+
+#: controllers/addons_controller.php:434
+#, fuzzy
+msgid "rss_popularaddons"
+msgstr "Popular Add-ons"
+
+#: controllers/addons_controller.php:433
+#, fuzzy
+msgid "rss_updatedaddons"
+msgstr "Updated Add-ons"
+
+#: views/elements/search_mini.thtml:70
+#, fuzzy
+msgid "search"
+msgstr "Search"
+
+#: views/search/collections.thtml:51
+#, fuzzy
+msgid "search_collections_header"
+msgstr "Collection Search Results"
+
+#: controllers/search_controller.php:297
+#, fuzzy
+msgid "search_collections_pagetitle"
+msgstr "Collection Search Results"
+
+#: controllers/search_controller.php:99
+#, fuzzy
+msgid "search_disabled"
+msgstr "Search is currently disabled. Please try again later."
+
+#: views/elements/amo2009/search.thtml:188 views/elements/search.thtml:187
+#: views/elements/search_mini.thtml:54
+#, fuzzy
+msgid "search_form_all_addons"
+msgstr "all add-ons"
+
+#. This string is in the main category dropdown when searching
+#: views/elements/amo2009/search.thtml:204
+#, fuzzy
+msgid "search_form_all_collections"
+msgstr "all collections"
+
+#: views/elements/amo2009/search.thtml:184
+#: views/elements/amo2009/search.thtml:385
+#: views/elements/amo2009/search.thtml:408 views/elements/search.thtml:171
+#: views/elements/search.thtml:183 views/elements/search_mini.thtml:43
+#: views/elements/search_mini.thtml:49 views/layouts/mozilla.thtml:188
+#, fuzzy
+msgid "search_form_default_text"
+msgstr "search for add-ons"
+
+#: views/elements/amo2009/search.thtml:184
+#: views/elements/amo2009/search.thtml:404
+#, fuzzy
+msgid "search_form_default_text_collections"
+msgstr "search for collections"
+
+#: views/elements/amo2009/search.thtml:206 views/elements/search.thtml:202
+#, fuzzy
+msgid "search_form_submit_tooltip"
+msgstr "Search for add-ons"
+
+#: views/elements/amo2009/search.thtml:184 views/elements/search.thtml:183
+#: views/elements/search_mini.thtml:49
+#, fuzzy
+msgid "search_form_tooltip"
+msgstr "Click to enter search terms"
+
+#: views/elements/amo2009/search.thtml:186 views/elements/search.thtml:185
+#: views/elements/search_mini.thtml:52
+#, fuzzy
+msgid "search_form_within"
+msgstr "within"
+
+#: views/addons/searchengines.thtml:118
+#, fuzzy
+msgid "search_landing_all_search_engines"
+msgstr "All Search Engines"
+
+#: views/addons/searchengines.thtml:114
+#, fuzzy
+msgid "search_landing_browse_search_engines"
+msgstr "Browse Search Engines"
+
+#: views/search/collections.thtml:58 views/search/index.thtml:59
+#, fuzzy
+msgid "search_nothing_found"
+msgstr "No results found."
+
+#: controllers/search_controller.php:185
+#, fuzzy
+msgid "search_pagetitle"
+msgstr "Search Add-ons"
+
+#: controllers/search_controller.php:242
+#, fuzzy
+msgid "search_rss_description"
+msgstr "Search results feed"
+
+#. %s is the terms the user is searching for (a string)
+#: controllers/search_controller.php:241
+#, fuzzy, php-format
+msgid "search_rss_results_for"
+msgstr "Search results for: %s"
+
+#: views/elements/header.thtml:154 views/layouts/amo2009.thtml:296
+#, fuzzy
+msgid "sidebar_navlink_admin_tools"
+msgstr "Admin Tools"
+
+#: views/elements/header.thtml:146 views/layouts/amo2009.thtml:288
+#, fuzzy
+msgid "sidebar_navlink_developer_tools"
+msgstr "Developer Tools"
+
+#: views/elements/header.thtml:148 views/layouts/amo2009.thtml:290
+#, fuzzy
+msgid "sidebar_navlink_editor_tools"
+msgstr "Editor Tools"
+
+#: views/layouts/amo2009.thtml:302
+#, fuzzy
+msgid "sidebar_navlink_welcome"
+msgstr "Welcome"
+
+#. %s is the user's name
+#: views/layouts/amo2009.thtml:302
+#, fuzzy, php-format
+msgid "sidebar_navlink_welcome_name"
+msgstr "Welcome, %s"
+
+#: views/elements/pitch.thtml:50 views/elements/pitch.thtml:55
+#, fuzzy
+msgid "sidebar_pitch_dictionary"
+msgstr "Dictionary"
+
+#: views/elements/pitch.thtml:72
+#, fuzzy
+msgid "sidebar_pitch_featured_addons"
+msgstr "Featured Add-ons"
+
+#: views/elements/pitch.thtml:61
+#, fuzzy
+msgid "sidebar_pitch_looking_for"
+msgstr "I am looking for a:"
+
+#: views/elements/pitch.thtml:70
+#, fuzzy
+msgid "sidebar_pitch_newest_addons"
+msgstr "Newest Add-ons"
+
+#: views/elements/pitch.thtml:49
+#, fuzzy
+msgid "sidebar_pitch_search"
+msgstr "Search Plugin"
+
+#: views/elements/pitch.thtml:69
+#, fuzzy
+msgid "sidebar_pitch_subscribe_to"
+msgstr "Subscribe to"
+
+#: views/elements/pitch.thtml:48 views/elements/pitch.thtml:54
+#, fuzzy
+msgid "sidebar_pitch_theme"
+msgstr "Theme"
+
+#: views/elements/pitch.thtml:71
+#, fuzzy
+msgid "sidebar_pitch_updated_addons"
+msgstr "Updated Add-ons"
+
+#. %1$s is a number
+#: views/helpers/localization.php:65 views/developers/versions_edit.thtml:95
+#: views/addons/dictionaries.thtml:92
+#, fuzzy, php-format
+msgid "size_kb"
+msgstr "%1$s KB"
+
+#: views/elements/amo2009/stars.thtml:57 views/elements/stars.thtml:63
+#, fuzzy
+msgid "stars_not_yet_rated"
+msgstr "Not yet rated"
+
+# %1 is the number of stars this add-on has
+#. %1 is the number of stars this add-on has
+#: views/elements/amo2009/stars.thtml:49 views/elements/stars.thtml:54
+#, fuzzy, php-format
+msgid "stars_rated_x_outof_5"
+msgstr "Rated %s out of 5 stars"
+
+#: views/statistics/addon.thtml:59
+#, fuzzy
+msgid "statistics_addon_dashboard_link"
+msgstr "Dashboard Home"
+
+#: views/statistics/addon.thtml:58
+#, fuzzy
+msgid "statistics_addon_developertools_link"
+msgstr "Developer Tools"
+
+#: views/statistics/addon.thtml:53
+#, fuzzy
+msgid "statistics_addon_switch"
+msgstr "Switch Add-on"
+
+#. This is a date format.
+#. http://php.net/strftime
+#: views/statistics/rss/summary.thtml:54 views/statistics/addon.thtml:181
+#, fuzzy
+msgid "statistics_date_shortmonth"
+msgstr "%b. %e"
+
+#. This is a date format.
+#. http://php.net/strftime
+#: views/statistics/rss/summary.thtml:40 views/statistics/addon.thtml:152
+#, fuzzy
+msgid "statistics_date_shortmonthwithyear"
+msgstr "%b. %e, %Y"
+
+#. This is a date format.
+#. http://php.net/strftime
+#: views/statistics/rss/summary.thtml:41 views/statistics/rss/summary.thtml:48
+#: views/statistics/addon.thtml:161 views/statistics/addon.thtml:172
+#, fuzzy
+msgid "statistics_date_weekdayshortmonth"
+msgstr "%A, %b. %e"
+
+#. %1$s is an add-on name and version. Example: Add-on 3.5
+#: controllers/components/stats.php:519
+#, fuzzy, php-format
+msgid "statistics_events_addon_created"
+msgstr "%1$s created"
+
+#. %1$s is an application name and version. Example: Firefox 3.5
+#: controllers/components/stats.php:500
+#, fuzzy, php-format
+msgid "statistics_events_app_released"
+msgstr "%1$s released"
+
+#: views/statistics/addon.thtml:71
+#, fuzzy
+msgid "statistics_help_close_link"
+msgstr "Close"
+
+#: views/statistics/addon.thtml:60
+#, fuzzy
+msgid "statistics_help_link"
+msgstr "Help"
+
+#: views/statistics/index.thtml:83
+#, fuzzy
+msgid "statistics_index_anotheraddon"
+msgstr "or, select another add-on"
+
+#: views/statistics/index.thtml:85
+#, fuzzy
+msgid "statistics_index_anotheraddon_public"
+msgstr "or, select an add-on with public statistics"
+
+#: views/statistics/index.thtml:71
+#, fuzzy
+msgid "statistics_index_myaddons"
+msgstr "Select one of your add-ons to view its statistics"
+
+#: views/statistics/index.thtml:89
+#, fuzzy
+msgid "statistics_index_selectaddon"
+msgstr "Select an add-on to view its statistics"
+
+#: views/statistics/index.thtml:91
+#, fuzzy
+msgid "statistics_index_selectaddon_public"
+msgstr "Select an add-on with public statistics"
+
+#: views/statistics/index.thtml:39
+#, fuzzy
+msgid "statistics_index_title"
+msgstr "Statistics Dashboard"
+
+#: views/statistics/index.thtml:97
+#, fuzzy
+msgid "statistics_index_view_button"
+msgstr "View Statistics"
+
+#: views/statistics/addon.thtml:222 controllers/statistics_controller.php:247
+#, fuzzy
+msgid "statistics_js_download_csv"
+msgstr "View this table in CSV format"
+
+#: controllers/statistics_controller.php:246
+#, fuzzy
+msgid "statistics_js_dropdowns_none"
+msgstr "none"
+
+#: controllers/statistics_controller.php:245
+#, fuzzy
+msgid "statistics_js_dropdowns_removeplot"
+msgstr "Remove this plot"
+
+#: controllers/statistics_controller.php:248
+#, fuzzy
+msgid "statistics_js_groupby_selector_date"
+msgstr "Group by: Day"
+
+#: controllers/statistics_controller.php:251
+#, fuzzy
+msgid "statistics_js_groupby_selector_month"
+msgstr "Group by: Month"
+
+#: controllers/statistics_controller.php:249
+#, fuzzy
+msgid "statistics_js_groupby_selector_week"
+msgstr "Group by: Week"
+
+#: controllers/statistics_controller.php:250
+#, fuzzy
+msgid "statistics_js_groupby_selector_week_over_week"
+msgstr "Compare by: Week"
+
+#: controllers/statistics_controller.php:260
+#, fuzzy
+msgid "statistics_js_plotselection_foundinrange"
+msgstr "%s found in range"
+
+#: controllers/statistics_controller.php:270
+#, fuzzy
+msgid "statistics_js_plotselection_options_addplot_name"
+msgstr "Add Plot"
+
+#: controllers/statistics_controller.php:271
+#, fuzzy
+msgid "statistics_js_plotselection_options_addplot_tooltip"
+msgstr "Add another plot to this graph"
+
+#: controllers/statistics_controller.php:261
+#, fuzzy
+msgid "statistics_js_plotselection_options_count_name_checked"
+msgstr "Hide Total Count"
+
+#: controllers/statistics_controller.php:262
+#, fuzzy
+msgid "statistics_js_plotselection_options_count_name_unchecked"
+msgstr "Show Total Count"
+
+#: controllers/statistics_controller.php:263
+#, fuzzy
+msgid "statistics_js_plotselection_options_count_tooltip"
+msgstr "Plot the total count on this graph"
+
+#: controllers/statistics_controller.php:275
+#, fuzzy
+msgid "statistics_js_plotselection_options_csv_name"
+msgstr "View Data (CSV)"
+
+#: controllers/statistics_controller.php:276
+#, fuzzy
+msgid "statistics_js_plotselection_options_csv_tooltip"
+msgstr "Get a Comma Separated Values file of this data"
+
+#: controllers/statistics_controller.php:267
+#, fuzzy
+msgid "statistics_js_plotselection_options_events_addon_name_checked"
+msgstr "Hide %s Events"
+
+#: controllers/statistics_controller.php:268
+#, fuzzy
+msgid "statistics_js_plotselection_options_events_addon_name_unchecked"
+msgstr "Show %s Events"
+
+#: controllers/statistics_controller.php:269
+#, fuzzy
+msgid "statistics_js_plotselection_options_events_addon_tooltip"
+msgstr "Overlay add-on release dates on the plots"
+
+#: controllers/statistics_controller.php:264
+#, fuzzy
+msgid "statistics_js_plotselection_options_events_firefox_name_checked"
+msgstr "Hide Firefox Events"
+
+#: controllers/statistics_controller.php:265
+#, fuzzy
+msgid "statistics_js_plotselection_options_events_firefox_name_unchecked"
+msgstr "Show Firefox Events"
+
+#: controllers/statistics_controller.php:266
+#, fuzzy
+msgid "statistics_js_plotselection_options_events_firefox_tooltip"
+msgstr "Overlay Firefox release dates on the plots"
+
+#: controllers/statistics_controller.php:272
+#, fuzzy
+msgid "statistics_js_plotselection_options_resize_name_checked"
+msgstr "Collapse Graph"
+
+#: controllers/statistics_controller.php:273
+#, fuzzy
+msgid "statistics_js_plotselection_options_resize_name_unchecked"
+msgstr "Expand Graph"
+
+#: controllers/statistics_controller.php:274
+#, fuzzy
+msgid "statistics_js_plotselection_options_resize_tooltip"
+msgstr "Resize the graph"
+
+#: controllers/statistics_controller.php:254
+#, fuzzy
+msgid "statistics_js_plotselection_selector_adu"
+msgstr "Active Daily Users"
+
+#: controllers/statistics_controller.php:256
+#, fuzzy
+msgid "statistics_js_plotselection_selector_application"
+msgstr "Application"
+
+#: controllers/statistics_controller.php:259
+#, fuzzy
+msgid "statistics_js_plotselection_selector_custom"
+msgstr "Custom"
+
+#: controllers/statistics_controller.php:253
+#, fuzzy
+msgid "statistics_js_plotselection_selector_downloads"
+msgstr "Downloads"
+
+#: controllers/statistics_controller.php:258
+#, fuzzy
+msgid "statistics_js_plotselection_selector_os"
+msgstr "Operating System"
+
+#: controllers/statistics_controller.php:257
+#, fuzzy
+msgid "statistics_js_plotselection_selector_status"
+msgstr "Add-on Status"
+
+#: controllers/statistics_controller.php:252
+#, fuzzy
+msgid "statistics_js_plotselection_selector_summary"
+msgstr "Summary"
+
+#: controllers/statistics_controller.php:255
+#, fuzzy
+msgid "statistics_js_plotselection_selector_version"
+msgstr "Add-on Version"
+
+#: controllers/components/stats.php:398
+#, fuzzy
+msgid "statistics_longnames_application"
+msgstr "Application"
+
+#: controllers/components/stats.php:400
+#, fuzzy
+msgid "statistics_longnames_os"
+msgstr "Operating System"
+
+#: controllers/components/stats.php:399
+#, fuzzy
+msgid "statistics_longnames_status"
+msgstr "Add-on Status"
+
+#: controllers/components/stats.php:401
+#, fuzzy
+msgid "statistics_longnames_unknown"
+msgstr "Unknown"
+
+#: controllers/components/stats.php:397
+#, fuzzy
+msgid "statistics_longnames_version"
+msgstr "Add-on Version"
+
+#: views/statistics/addon.thtml:118
+#, fuzzy
+msgid "statistics_notice_data_insufficient"
+msgstr ""
+"There is not yet enough data to display this graph. Please check back later."
+
+#: views/statistics/addon.thtml:130
+#, fuzzy
+msgid "statistics_notice_data_none"
+msgstr ""
+"We don't have any data for your add-on yet. Please check back in a few days."
+
+#: views/statistics/addon.thtml:41
+#, fuzzy
+msgid "statistics_notice_data_updating"
+msgstr ""
+"Add-on statistics are currently in the process of being updated. Recent data "
+"may be incomplete as our scripts work to update this information. Please "
+"check back in a few minutes."
+
+#: views/statistics/addon.thtml:136
+#, fuzzy
+msgid "statistics_notice_disabled"
+msgstr ""
+"The Statistics Dashboard is currently disabled. Please check back later."
+
+#: views/statistics/addon.thtml:123
+#, fuzzy
+msgid "statistics_notice_nojavascript"
+msgstr "JavaScript is required to view the Statistics Dashboard graphs."
+
+#: views/statistics/addon.thtml:44
+#, fuzzy
+msgid "statistics_notice_settings_updated"
+msgstr "Your settings have been updated!"
+
+#: controllers/statistics_controller.php:60
+#: controllers/statistics_controller.php:71
+#: controllers/statistics_controller.php:74
+#: controllers/statistics_controller.php:240
+#, fuzzy
+msgid "statistics_pagetitle"
+msgstr "Statistics Dashboard"
+
+#: views/statistics/addon.thtml:99
+#, fuzzy
+msgid "statistics_plot_legend_adu"
+msgstr "Active Daily Users"
+
+#: views/statistics/addon.thtml:95
+#, fuzzy
+msgid "statistics_plot_legend_downloads"
+msgstr "Daily Downloads"
+
+#: views/statistics/addon.thtml:107
+#, fuzzy
+msgid "statistics_plot_options_zoomin_alt"
+msgstr "Zoom In"
+
+#: views/statistics/addon.thtml:106
+#, fuzzy
+msgid "statistics_plot_options_zoomin_title"
+msgstr "Zoom in one month"
+
+#: views/statistics/addon.thtml:110
+#, fuzzy
+msgid "statistics_plot_options_zoomout_alt"
+msgstr "Zoom Out"
+
+#: views/statistics/addon.thtml:109
+#, fuzzy
+msgid "statistics_plot_options_zoomout_title"
+msgstr "Zoom out one month"
+
+#: controllers/statistics_controller.php:283
+#, fuzzy, php-format
+msgid "statistics_rss_description"
+msgstr "Daily summary of statistics for %1$s"
+
+#: views/statistics/rss/summary.thtml:68
+#, fuzzy
+msgid "statistics_rss_title_fulldate"
+msgstr "%A, %B %e, %Y"
+
+#: views/statistics/rss/summary.thtml:68
+#, fuzzy, php-format
+msgid "statistics_rss_title_statsfordate"
+msgstr "Statistics for %1$s"
+
+#: views/statistics/settings.thtml:49
+#, fuzzy
+msgid "statistics_settings_access_description"
+msgstr ""
+"By default, only you and Mozilla can access the information in your "
+"dashboard. You can open this up to the public so that anyone can view your "
+"add-on's data."
+
+#: views/statistics/settings.thtml:48
+#, fuzzy
+msgid "statistics_settings_access_heading"
+msgstr "Dashboard Access"
+
+#: views/statistics/settings.thtml:51
+#, fuzzy
+msgid "statistics_settings_access_private"
+msgstr "Private"
+
+#: views/statistics/settings.thtml:51
+#, fuzzy
+msgid "statistics_settings_access_private_description"
+msgstr "Only you and Mozilla can view this add-on's statistics"
+
+#: views/statistics/settings.thtml:52
+#, fuzzy
+msgid "statistics_settings_access_public"
+msgstr "Public"
+
+#: views/statistics/settings.thtml:52
+#, fuzzy
+msgid "statistics_settings_access_public_description"
+msgstr "Anyone can view this add-on's statistics"
+
+#: views/statistics/addon.thtml:251
+#, fuzzy
+msgid "statistics_settings_change_link"
+msgstr "Change Settings"
+
+#: views/statistics/addon.thtml:253
+#, fuzzy
+msgid "statistics_settings_confidential"
+msgstr "Please treat this information as confidential."
+
+#: views/statistics/addon.thtml:245
+#, fuzzy
+msgid "statistics_settings_currently_private"
+msgstr "This dashboard is currently <b>private</b>."
+
+#: views/statistics/addon.thtml:241
+#, fuzzy
+msgid "statistics_settings_currently_public"
+msgstr "This dashboard is currently <b>public</b>."
+
+#: views/statistics/addon.thtml:246
+#, fuzzy
+msgid "statistics_settings_locked_alt"
+msgstr "Locked"
+
+#: views/statistics/settings.thtml:57
+#, fuzzy
+msgid "statistics_settings_return_link"
+msgstr "Return to Dashboard"
+
+#: views/statistics/settings.thtml:56
+#, fuzzy
+msgid "statistics_settings_save_button"
+msgstr "Save Settings"
+
+#: views/statistics/settings.thtml:46
+#, fuzzy, php-format
+msgid "statistics_settings_title"
+msgstr "Statistics Dashboard Settings for %1$s"
+
+#: views/statistics/addon.thtml:242
+#, fuzzy
+msgid "statistics_settings_unlocked_alt"
+msgstr "Unlocked"
+
+#: controllers/components/stats.php:405
+#, fuzzy
+msgid "statistics_shortnames_application"
+msgstr "App"
+
+#: controllers/components/stats.php:407
+#, fuzzy
+msgid "statistics_shortnames_os"
+msgstr "OS"
+
+#: controllers/components/stats.php:406
+#, fuzzy
+msgid "statistics_shortnames_status"
+msgstr "St"
+
+#: controllers/components/stats.php:408
+#, fuzzy
+msgid "statistics_shortnames_unknown"
+msgstr "Uk"
+
+#: controllers/components/stats.php:404
+#, fuzzy
+msgid "statistics_shortnames_version"
+msgstr "Ver"
+
+#: views/statistics/rss/summary.thtml:42 views/statistics/addon.thtml:192
+#, fuzzy
+msgid "statistics_summary_downloads_average"
+msgstr "Average Daily Downloads"
+
+#: views/statistics/rss/summary.thtml:39
+#, fuzzy
+msgid "statistics_summary_downloads_heading"
+msgstr "Downloads"
+
+#: views/statistics/rss/summary.thtml:41 views/statistics/addon.thtml:171
+#, fuzzy
+msgid "statistics_summary_downloads_lastcount"
+msgstr "Last Day Count"
+
+#: views/statistics/rss/summary.thtml:43 views/statistics/addon.thtml:199
+#, fuzzy
+msgid "statistics_summary_downloads_lastweek"
+msgstr "Downloads in the last 7 days"
+
+#: views/statistics/rss/summary.thtml:40 views/statistics/addon.thtml:151
+#, fuzzy
+msgid "statistics_summary_downloads_total"
+msgstr "Total Downloads"
+
+#: views/statistics/rss/summary.thtml:40 views/statistics/addon.thtml:152
+#, fuzzy, php-format
+msgid "statistics_summary_downloads_total_sincedate"
+msgstr "Since %1$s"
+
+#: views/statistics/rss/summary.thtml:50 views/statistics/rss/summary.thtml:56
+#: views/statistics/addon.thtml:163 views/statistics/addon.thtml:183
+#, fuzzy
+msgid "statistics_summary_nodata"
+msgstr "No data yet"
+
+#: views/statistics/rss/summary.thtml:60 views/statistics/addon.thtml:195
+#, fuzzy
+msgid "statistics_summary_updatepings_average"
+msgstr "Average Daily Active Users"
+
+#: views/statistics/rss/summary.thtml:52 views/statistics/addon.thtml:177
+#, fuzzy
+msgid "statistics_summary_updatepings_changefromprevious"
+msgstr "Change from previous count"
+
+#: views/statistics/rss/summary.thtml:54 views/statistics/addon.thtml:181
+#, fuzzy, php-format
+msgid "statistics_summary_updatepings_changefromprevious_ondate"
+msgstr "%1$s on %2$s"
+
+#: views/statistics/rss/summary.thtml:45
+#, fuzzy
+msgid "statistics_summary_updatepings_heading"
+msgstr "Active Daily Users"
+
+#: views/statistics/rss/summary.thtml:46 views/statistics/addon.thtml:157
+#, fuzzy
+msgid "statistics_summary_updatepings_total"
+msgstr "Active Daily Users"
+
+#: views/statistics/rss/summary.thtml:48 views/statistics/addon.thtml:161
+#, fuzzy, php-format
+msgid "statistics_summary_updatepings_total_ondate"
+msgstr "On %1$s"
+
+#: views/statistics/rss/summary.thtml:61 views/statistics/addon.thtml:203
+#, fuzzy
+msgid "statistics_summary_updatepings_weekly_average"
+msgstr "Average Daily Users this Week"
+
+#. %s is a percentage, like '+22.33%'. It sits next to another number, so
+#. the implied meaning is 'percentage change' from the previous stat point.
+#: views/statistics/rss/summary.thtml:62 views/statistics/addon.thtml:205
+#, fuzzy
+msgid "statistics_summary_updatepings_weekly_change"
+msgstr "%s from last week"
+
+#: views/statistics/addon.thtml:65 controllers/statistics_controller.php:184
+#: controllers/statistics_controller.php:282
+#, fuzzy, php-format
+msgid "statistics_title_addon_stats"
+msgstr "%1$s Statistics"
+
+#: views/addons/themes_landing.thtml:113
+#, fuzzy
+msgid "themes_landing_all_themes"
+msgstr "All Themes"
+
+#: views/addons/themes_landing.thtml:109
+#, fuzzy
+msgid "themes_landing_browse_themes"
+msgstr "Browse Themes"
+
+#: views/users/edit.thtml:185
+#, fuzzy
+msgid "user_change_email"
+msgstr "Change Email Address"
+
+#: views/users/edit.thtml:169
+#, fuzzy
+msgid "user_change_password"
+msgstr "Change password"
+
+#: views/users/edit.thtml:96
+#, fuzzy
+msgid "user_change_password_or_email"
+msgstr "Change Password or Email"
+
+#: controllers/users_controller.php:197
+#, fuzzy
+msgid "user_confirmationcode_resent"
+msgstr "The confirmation code was resent!"
+
+# %1 is the email address, %2 is the URL of the user registration page
+#. %1 is the email address, %2 is the URL of the user registration page
+#: views/users/delete.thtml:51
+#, fuzzy
+msgid "user_del_account_deleted"
+msgstr ""
+"Your user account %1$s has been successfully deleted. If you want to come "
+"back some time, you can re-register on the <a href=\"%2$s\">user "
+"registration page</a>."
+
+#: views/users/delete.thtml:102
+#, fuzzy
+msgid "user_del_community_sad"
+msgstr "The Mozilla Add-ons community is sad to see you go."
+
+#: views/users/delete.thtml:123
+#, fuzzy
+msgid "user_del_confirm_password"
+msgstr "Confirm Password"
+
+#: views/users/delete.thtml:134
+#, fuzzy
+msgid "user_del_deletenow"
+msgstr "Delete my user account now"
+
+# %1 is the URL of the user's info page
+#. %1 is the URL of the user's info page
+#: views/users/delete.thtml:64
+#, fuzzy
+msgid "user_del_error_addons"
+msgstr ""
+"You cannot delete your account if you are listed as an <a href=\"%1$s"
+"\">author of any add-ons</a>. To delete your account, please have another "
+"person in your development group delete you from the list of authors for "
+"your add-ons. Afterwards you will be able to delete your account here."
+
+# %1 is a link to the amo-editors mailing list
+#. %1 is a link to the amo-editors mailing list
+#: views/users/delete.thtml:71
+#, fuzzy
+msgid "user_del_error_addons_more_questions"
+msgstr "If you have additional questions, please contact %1$s for assistance."
+
+#: views/users/delete.thtml:78
+#, fuzzy
+msgid "user_del_error_checkbox"
+msgstr ""
+"You need to check the box \"I understand...\" before we can delete your "
+"account."
+
+#: views/users/delete.thtml:84
+#, fuzzy
+msgid "user_del_error_password"
+msgstr "Please enter your password correctly in order to perform this step."
+
+# %1 is a link to the amo-admins mailing list
+#. %1 is a link to the amo-admins mailing list
+#: views/users/delete.thtml:91
+#, fuzzy
+msgid "user_del_error_unknown"
+msgstr ""
+"An unknown error occured deleting your account. Please contact %1$s with the "
+"issue and we will delete it for you. We apologize for the inconvenience."
+
+#: views/users/delete.thtml:110
+#, fuzzy
+msgid "user_del_header_confirm_deletion"
+msgstr "Confirm account deletion"
+
+# %1 is the user's email address
+#. %1 is the user's email address
+#: views/users/delete.thtml:100
+#, fuzzy
+msgid "user_del_header_delete_account"
+msgstr "Delete User Account %1$s"
+
+#: views/users/delete.thtml:50
+#, fuzzy
+msgid "user_del_header_farewell"
+msgstr "Farewell!"
+
+#: views/users/delete.thtml:115
+#, fuzzy
+msgid "user_del_nologin"
+msgstr "You will not be able to log into Mozilla Add-ons anymore."
+
+#: views/users/delete.thtml:112
+#, fuzzy
+msgid "user_del_permanently_removed_means"
+msgstr ""
+"By clicking \"delete\" your account is going to be <strong>permanently "
+"removed</strong>. That means:"
+
+#: views/users/delete.thtml:116
+#, fuzzy
+msgid "user_del_reviews_anonymized"
+msgstr ""
+"Your reviews and ratings will not be deleted, but they will no longer be "
+"associated with you."
+
+# %1 is a link to the amo-editors mailing list
+#. %1 is a link to the amo-editors mailing list
+#: views/users/delete.thtml:104
+#, fuzzy
+msgid "user_del_specific_problem_editors"
+msgstr ""
+"If you have a specific problem we may help you with, please do not delete "
+"your account now, but contact us at %1$s and we will do our best to assist "
+"you in solving it."
+
+#: views/users/delete.thtml:130
+#, fuzzy
+msgid "user_del_understand_permanent"
+msgstr "I understand that this step cannot be undone."
+
+#: views/helpers/addons_html.php:192
+#, fuzzy
+msgid "user_deleted_nickname"
+msgstr "Deleted User"
+
+# %1 is the new email address
+#. %1 is the new email address
+#: views/users/edit.thtml:71
+#, fuzzy
+msgid "user_edit_confirm_email_sent"
+msgstr ""
+"An email has been sent to %1$s to confirm your new email address. For the "
+"change to take effect, you need to click on the link provided in this email. "
+"Until then, you can keep logging in with your current email address."
+
+#: views/users/edit.thtml:201
+#, fuzzy
+msgid "user_edit_delete_user"
+msgstr "Delete user account"
+
+# This contains the email sent to users when they signed up for a new
+# account:
+# %1 is the confirmation URL, %2 is the current app
+#. This contains the email sent to users when they signed up for a new
+#. account:
+#. %1 is the confirmation URL, %2 is the current app
+#: views/users/email/confirm_plain.thtml:6
+#, fuzzy, php-format
+msgid "user_email_confirm_account_nopass"
+msgstr ""
+"Welcome to %2$s Add-ons.\n"
+"\n"
+"Before you can use your new account you must activate it - this ensures the "
+"e-mail address you used is valid and belongs to you.\n"
+"To activate your account, click the link below or copy and paste the whole "
+"thing into your browser's location bar:\n"
+"\n"
+"%1$s\n"
+"\n"
+"Once you successfully activated your account, you can throw away this e-"
+"mail.\n"
+"\n"
+"Thanks for joining %2$s Add-ons\n"
+"-- %2$s Add-ons Staff"
+
+# %1 is the confirmation url, %2 is the application name
+#. %1 is the confirmation url, %2 is the application name
+#: views/users/email/emailchange_plain.thtml:5
+#, fuzzy
+msgid "user_email_confirm_emailchange"
+msgstr ""
+"You requested a change to your email address at %2$s Add-ons.\n"
+"\n"
+"In order to confirm the new address, please click the link below or copy and "
+"paste the whole thing into your browser's location bar:\n"
+"\n"
+"%1$s\n"
+"\n"
+"You have 48 hours to confirm the new address. If you do not want to change "
+"the address anymore, you can just ignore this email.\n"
+"\n"
+"Thanks!\n"
+"-- %2$s Add-ons Staff"
+
+#: controllers/users_controller.php:168
+#, fuzzy, php-format
+msgid "user_email_confirm_subject"
+msgstr "Thanks for joining %s Add-ons"
+
+# This is the password reset email
+# %1 is the pw reset URL, %2 is the application
+#. This is the password reset email
+#. %1 is the pw reset URL, %2 is the application
+#: views/users/email/pwreset_plain.thtml:5
+#, fuzzy, php-format
+msgid "user_email_pwreset"
+msgstr ""
+"%2$s Add-ons Password Reset\n"
+"\n"
+"A request was received to reset the password for this account on addons."
+"mozilla.org. To change this password please click on the following link, or "
+"paste it into your browser's location bar:\n"
+"\n"
+"%1$s\n"
+"\n"
+"If you did not request this email there is no need for further action.\n"
+"\n"
+"Thanks,\n"
+"-- %2$s Add-ons Staff"
+
+#: controllers/users_controller.php:245
+#, fuzzy, php-format
+msgid "user_email_pwreset_subject"
+msgstr "Reset your %s Add-ons password"
+
+#: views/users/emailchange.thtml:50
+#, fuzzy
+msgid "user_emailchange_error"
+msgstr "Error!"
+
+# %1 is the application name
+#. %1 is the application name
+#: controllers/users_controller.php:533
+#, fuzzy
+msgid "user_emailchange_subject"
+msgstr "Please confirm your email address change at %1$s Add-ons"
+
+#: views/users/emailchange.thtml:48
+#, fuzzy
+msgid "user_emailchange_success"
+msgstr "Success!"
+
+# %1 is the new email address
+#. %1 is the new email address
+#: views/users/emailchange.thtml:49
+#, fuzzy
+msgid "user_emailchange_successful_description"
+msgstr ""
+"Your email address was changed successfully. From now on, please use %1$s to "
+"log in."
+
+#: views/users/edit.thtml:134 views/admin/users_edit.thtml:111
+#, fuzzy
+msgid "user_form_bio"
+msgstr "About me"
+
+#: views/users/edit.thtml:135 views/admin/users_edit.thtml:112
+#, fuzzy
+msgid "user_form_bio_description"
+msgstr ""
+"Introduce yourself to the community, if you like! This text will appear "
+"publicly on your user info page. Line breaks will be preserved, but no HTML "
+"is allowed."
+
+#: views/users/pwreset.thtml:77 views/users/register.thtml:73
+#: views/users/edit.thtml:181
+#, fuzzy
+msgid "user_form_confirmpassword"
+msgstr "Confirm password"
+
+#: views/users/edit.thtml:145
+#, fuzzy
+msgid "user_form_display_collections"
+msgstr "Display the collections I have created in my user profile"
+
+#: views/users/edit.thtml:149
+#, fuzzy
+msgid "user_form_display_collections_fav"
+msgstr "Display my favorite collections in my user profile"
+
+#: views/users/edit.thtml:86
+#, fuzzy, php-format
+msgid "user_form_editprofile"
+msgstr "Edit user profile for %s"
+
+#: views/users/pwreset.thtml:52 views/users/login.thtml:81
+#: views/users/register.thtml:63 views/users/edit.thtml:187
+#, fuzzy
+msgid "user_form_email"
+msgstr "Email address"
+
+#: views/users/register.thtml:78 views/users/edit.thtml:103
+#: views/admin/users_edit.thtml:76
+#, fuzzy
+msgid "user_form_firstname"
+msgstr "First name"
+
+#: views/users/register.thtml:94 views/users/edit.thtml:119
+#: views/admin/users_edit.thtml:91
+#, fuzzy
+msgid "user_form_hideemail"
+msgstr "Hide email address"
+
+#: views/users/register.thtml:98 views/users/edit.thtml:123
+#: views/admin/users_edit.thtml:99
+#, fuzzy
+msgid "user_form_homepage"
+msgstr "Website URL"
+
+#: views/users/register.thtml:84 views/users/edit.thtml:109
+#: views/admin/users_edit.thtml:81
+#, fuzzy
+msgid "user_form_lastname"
+msgstr "Last name"
+
+#: controllers/users_controller.php:333
+#, fuzzy
+msgid "user_form_login"
+msgstr "User Login"
+
+#: views/users/pwreset.thtml:72 views/users/edit.thtml:176
+#, fuzzy
+msgid "user_form_newpassword"
+msgstr "New password"
+
+#: views/users/register.thtml:89 views/users/edit.thtml:114
+#: views/admin/users_edit.thtml:86
+#, fuzzy
+msgid "user_form_nickname"
+msgstr "Nickname"
+
+#: views/users/edit.thtml:171
+#, fuzzy
+msgid "user_form_oldpassword"
+msgstr "Old password"
+
+#: views/users/edit.thtml:97 views/users/edit.thtml:200
+#, fuzzy
+msgid "user_form_otheractions"
+msgstr "Other Actions"
+
+#: views/users/login.thtml:85 views/users/register.thtml:68
+#, fuzzy
+msgid "user_form_password"
+msgstr "Password"
+
+#: controllers/users_controller.php:93
+#, fuzzy
+msgid "user_form_registration"
+msgstr "New User Registration"
+
+#: views/users/login.thtml:90
+#, fuzzy
+msgid "user_form_remember_me"
+msgstr "Remember me on this computer"
+
+#: views/admin/users_edit.thtml:95
+#, fuzzy
+msgid "user_form_showsandbox"
+msgstr "Show sandbox?"
+
+#: views/users/edit.thtml:205
+#, fuzzy
+msgid "user_form_submit_edit"
+msgstr "Save"
+
+#: views/users/login.thtml:93
+#, fuzzy
+msgid "user_form_submit_login"
+msgstr "Log in"
+
+#: views/users/register.thtml:113
+#, fuzzy
+msgid "user_form_submit_register"
+msgstr "Register"
+
+#: views/users/info.thtml:75
+#, fuzzy, php-format
+msgid "user_info_usersince"
+msgstr "%s Add-ons user since"
+
+#: views/users/login.thtml:102
+#, fuzzy
+msgid "user_login_register_link"
+msgstr "Create a new user account"
+
+#: views/users/edit.thtml:160
+#, fuzzy
+msgid "user_notifications_item_compat"
+msgstr "Add-on Compatibility (strongly recommended)"
+
+#: views/users/edit.thtml:161
+#, fuzzy
+msgid "user_notifications_item_events"
+msgstr "Upcoming events and contests"
+
+#: views/users/edit.thtml:156
+#, fuzzy
+msgid "user_notifications_none_available"
+msgstr "There are currently no notifications available for you to configure."
+
+#: views/users/edit.thtml:158
+#, fuzzy
+msgid "user_notifications_select_topics"
+msgstr ""
+"From time to time, Mozilla may send you email about upcoming releases and "
+"add-on events. Please select the topics you are interested in below:"
+
+#: views/users/edit.thtml:164
+#, fuzzy
+msgid "user_notifications_specific_contact"
+msgstr ""
+"Mozilla reserves the right to contact you individually about specific "
+"concerns with your hosted add-ons."
+
+#: controllers/users_controller.php:543
+#, fuzzy
+msgid "user_profile_edit_error"
+msgstr ""
+"There were errors in the changes you made. Please correct them and resubmit."
+
+#: controllers/users_controller.php:540
+#, fuzzy
+msgid "user_profile_saved"
+msgstr "Profile updated."
+
+#: views/users/pwreset.thtml:65
+#, fuzzy, php-format
+msgid "user_pwreset_for_email"
+msgstr "Password reset for %s"
+
+#: controllers/users_controller.php:226
+#, fuzzy
+msgid "user_pwreset_header"
+msgstr "Password Reset"
+
+#: views/users/login.thtml:103
+#, fuzzy
+msgid "user_pwreset_link"
+msgstr "Forgot your password?"
+
+#: controllers/users_controller.php:248
+#, fuzzy
+msgid "user_pwreset_link_sent"
+msgstr "The password reset link was sent to your email address."
+
+#: controllers/users_controller.php:304
+#, fuzzy
+msgid "user_pwreset_okay"
+msgstr "Password successfully reset."
+
+#: views/users/pwreset.thtml:82
+#, fuzzy
+msgid "user_pwreset_submit_changepw"
+msgstr "Submit password change"
+
+#: views/users/pwreset.thtml:57
+#, fuzzy
+msgid "user_pwreset_submit_sendlink"
+msgstr "Send password reset link"
+
+#: views/users/register_complete.thtml:51
+#, fuzzy, php-format
+msgid "user_register_amo_link"
+msgstr "%s Add-ons"
+
+# %1 is the user's email address, %2 is the current app
+#. %1 is the user's email address, %2 is the current app
+#: views/users/activatefirst.thtml:49
+#, fuzzy, php-format
+msgid "user_register_click_confirm_link"
+msgstr ""
+"A link to activate your user account was sent by email to your address %1$s. "
+"You have to click it before you can log into %2$s Add-ons."
+
+# %1 is the user's email address
+#. %1 is the user's email address
+#: views/users/register_complete.thtml:49
+#, fuzzy, php-format
+msgid "user_register_confirm_email_sent"
+msgstr ""
+"An email has been sent to your address %1$s to confirm your account. Before "
+"you can log in, you have to activate your account by clicking on the link "
+"provided in this email."
+
+#: views/users/activatefirst.thtml:51
+#, fuzzy
+msgid "user_register_confirmation_link_text"
+msgstr "resend the confirmation message"
+
+#: views/users/register_complete.thtml:47
+#, fuzzy
+msgid "user_register_congratulations"
+msgstr "Congratulations! Your user account was successfully created."
+
+#: views/users/register.thtml:50
+#, fuzzy
+msgid "user_register_details"
+msgstr ""
+"<p>Registration on AMO is <strong>not required</strong> if you simply want "
+"to download and install public add-ons.</p><p>You only need to register if:</"
+"p><ul><li>You want to submit reviews for add-ons</li><li>You are an add-on "
+"developer and want to upload your add-on for hosting on AMO</li></ul><p>Upon "
+"successful registration, you will be sent a confirmation email to the "
+"address you provided. Please follow the instructions there to confirm your "
+"account.</p><p>If you like, you can read our <a href='%1$s' title='Legal "
+"Notices'>Legal Notices</a> and <a href='%2$s' title='Privacy Policy'>Privacy "
+"Policy</a>.</p>"
+
+# %1 is the link to the "resend confirmation code" page
+#. %1 is the link to the "resend confirmation code" page
+#: views/users/activatefirst.thtml:51
+#, fuzzy, php-format
+msgid "user_register_resend_confirmation_link"
+msgstr ""
+"If you did not receive the confirmation email, make sure your email service "
+"did not mark it as \"junk mail\" or \"spam\". If you need to, you can have "
+"us %1$s to your email address mentioned above."
+
+# %1 is the link to the Mozilla Add-ons front page
+#. %1 is the link to the Mozilla Add-ons front page
+#: views/users/register_complete.thtml:51
+#, fuzzy, php-format
+msgid "user_register_welcome"
+msgstr "Thanks for registering and welcome to %1$s!"
+
+#: views/users/register.thtml:49
+#, fuzzy
+msgid "user_register_welcome_header"
+msgstr "Welcome to addons.mozilla.org (AMO)!"
+
+#: views/users/register.thtml:81 views/users/edit.thtml:106
+#, fuzzy
+msgid "user_required_firstlast_or_nickname"
+msgstr "A first name, last name or nickname is required."
+
+#: views/users/edit.thtml:94 views/users/edit.thtml:142
+#, fuzzy
+msgid "user_tab_collections"
+msgstr "Collections"
+
+#: views/users/edit.thtml:95 views/users/edit.thtml:154
+#, fuzzy
+msgid "user_tab_notifications"
+msgstr "Notifications"
+
+#: views/users/edit.thtml:93 views/users/edit.thtml:101
+#, fuzzy
+msgid "user_tab_profile"
+msgstr "User Profile"
+
+#: controllers/users_controller.php:209
+#, fuzzy
+msgid "user_verified_okay"
+msgstr "Successfully verified!"
+
+#: controllers/users_controller.php:723
+#, fuzzy
+msgid "users_delete_pagetitle"
+msgstr "Delete User Account"
+
+#: controllers/users_controller.php:414
+#, fuzzy
+msgid "users_edit_pagetitle"
+msgstr "User Account Editing"
+
+#: views/users/info.thtml:71
+#, fuzzy
+msgid "users_info_aboutme"
+msgstr "About Me"
+
+#: views/users/info.thtml:96
+#, fuzzy, php-format
+msgid "users_info_addons_by_user"
+msgstr "Add-ons by %1$s"
+
+#: views/users/info.thtml:51
+#, fuzzy
+msgid "users_info_author_name"
+msgstr "Name"
+
+#: views/users/info.thtml:48
+#, fuzzy
+msgid "users_info_author_profile"
+msgstr "User Profile"
+
+#. %s is the user name
+#: views/users/info.thtml:137
+#, fuzzy
+msgid "users_info_collections_by_user"
+msgstr "Collections by %s"
+
+#: views/users/info.thtml:66
+#, fuzzy
+msgid "users_info_email"
+msgstr "Email address"
+
+#: views/users/info.thtml:155
+#, fuzzy
+msgid "users_info_fav_collections_by_user"
+msgstr "Favorite Collections"
+
+#: views/users/info.thtml:61
+#, fuzzy
+msgid "users_info_homepage"
+msgstr "Homepage"
+
+#: views/users/info.thtml:56
+#, fuzzy
+msgid "users_info_nickname"
+msgstr "Nickname"
+
+#: controllers/users_controller.php:707
+#, fuzzy, php-format
+msgid "users_info_pagetitle"
+msgstr "User Info for %1$s"
+
+# %1 is the user's name
+#. %1 is the user's name
+#: views/users/info.thtml:116
+#, fuzzy
+msgid "users_info_reviews_by_user"
+msgstr "Reviews by %s"
+
+#: controllers/users_controller.php:330 controllers/users_controller.php:332
+#, fuzzy
+msgid "users_login_pagetitle"
+msgstr "User Login"
+
+# %1 is the link to the sandbox/policy explanation page
+# This message is for a specific add-on not found
+#. %1 is the link to the sandbox/policy explanation page
+#. This message is for a specific add-on not found
+#: views/users/login.thtml:53
+#, fuzzy, php-format
+msgid "users_login_sandbox_display_warning"
+msgstr ""
+"The add-on you're looking for is currently in the sandbox. If you already "
+"have an account on Mozilla Add-ons, please log in, or <a href=\"%1$s\">learn "
+"more about the sandbox.</a>"
+
+# %1 is the link to the sandbox/policy explanation page
+# This message is for any given sandbox-related page not found
+#. %1 is the link to the sandbox/policy explanation page
+#. This message is for any given sandbox-related page not found
+#: views/users/login.thtml:56
+#, fuzzy, php-format
+msgid "users_login_sandbox_page_warning"
+msgstr ""
+"The page you're looking for is part of the sandbox. If you already have an "
+"account on Mozilla Add-ons, please log in, or <a href=\"%1$s\">learn more "
+"about the sandbox.</a>"
+
+#: controllers/users_controller.php:223 controllers/users_controller.php:225
+#, fuzzy
+msgid "users_pwreset_pagetitle"
+msgstr "User Password Reset"
+
+#: controllers/users_controller.php:90 controllers/users_controller.php:92
+#, fuzzy
+msgid "users_register_pagetitle"
+msgstr "New User Registration"
+
+#. %1$s is an addon name, like <a>Firebug</a>
+#. %2$s is a version number, like <a>1.2</a>
+#: views/versions/license.thtml:52
+#, fuzzy
+msgid "versions_license_header_source"
+msgstr "Source code license for %1$s %2$s"
+
+#: views/addons/category_landing.thtml:147
+#, fuzzy
+msgid "view_recently_added"
+msgstr "View all recently added"
+
+#: views/addons/category_landing.thtml:161
+#, fuzzy
+msgid "view_top_downloads"
+msgstr "View all top downloads"
+
+#: views/addons/category_landing.thtml:175
+#, fuzzy
+msgid "view_top_rated"
+msgstr "View all top rated"
+
+#, fuzzy
+#~ msgid "addon_slider_tooltip_next"
+#~ msgstr "Next Add-on"
+
+#, fuzzy
+#~ msgid "addon_slider_tooltip_previous"
+#~ msgstr "Previous Add-on"
+
+#, fuzzy
+#~ msgid "addon_versions_getlatesttext"
+#~ msgstr "The most recent version compatible with"
+
+#, fuzzy
+#~ msgid "addons_display_version_history"
+#~ msgstr "Complete Version History"
+
+#, fuzzy
+#~ msgid "addons_home_newest_header"
+#~ msgstr "Newest:"
+
+#, fuzzy
+#~ msgid "addons_home_popular_header"
+#~ msgstr "Most Popular:"
+
+#, fuzzy
+#~ msgid "addons_home_recommended_header"
+#~ msgstr "We Recommend:"
+
+#, fuzzy
+#~ msgid "addons_home_updated_header"
+#~ msgstr "Recently Updated:"
+
+#, fuzzy
+#~ msgid "addons_home_view_all"
+#~ msgstr "View all"
+
+#, fuzzy
+#~ msgid "category_extra_allrecommended"
+#~ msgstr "See All Recommended Add-ons"
+
+#, fuzzy
+#~ msgid "category_extra_highestrated"
+#~ msgstr "Highest Rated First"
+
+#, fuzzy
+#~ msgid "category_extra_lastupdated"
+#~ msgstr "Last Updated First"
+
+#, fuzzy
+#~ msgid "category_extra_mostpopular"
+#~ msgstr "Most Popular First"
+
+#, fuzzy
+#~ msgid "collections_detail_js_loading"
+#~ msgstr "Loading"
+
+#, fuzzy
+#~ msgid "collections_detail_more_info"
+#~ msgstr "Show More Info"
+
+#, fuzzy
+#~ msgid "devcp_additem_firefox_notice"
+#~ msgstr ""
+#~ "This version of your add-on does not claim compatibility with Firefox %1"
+#~ "$s. Mozilla is expecting the next version of Firefox to be released soon, "
+#~ "so please test your add-on in the new version and update compatibility "
+#~ "information. You can find out more about this <a href=\"%2$s\">here</a>. "
+#~ "This is only a notice and you may continue to submit this version to "
+#~ "addons.mozilla.org."
+
+#, fuzzy
+#~ msgid "devcp_addon_disabled_successfully"
+#~ msgstr "Add-on disabled successfully"
+
+#, fuzzy
+#~ msgid "devcp_addon_edit_pagetitle"
+#~ msgstr "Edit Add-on"
+
+#, fuzzy
+#~ msgid "devcp_addon_enabled_successfully"
+#~ msgstr "Add-on enabled successfully"
+
+#, fuzzy
+#~ msgid "devcp_addon_field_description_displaytitle"
+#~ msgstr "Add-on Description"
+
+#, fuzzy
+#~ msgid "devcp_addon_field_eula_displaytitle"
+#~ msgstr "EULA"
+
+#, fuzzy
+#~ msgid "devcp_addon_field_homepage_displaytitle"
+#~ msgstr "Add-on Homepage"
+
+#, fuzzy
+#~ msgid "devcp_addon_field_name_displaytitle"
+#~ msgstr "Add-on Name"
+
+#, fuzzy
+#~ msgid "devcp_addon_field_privacy_displaytitle"
+#~ msgstr "Privacy Policy"
+
+#, fuzzy
+#~ msgid "devcp_addon_field_summary_displaytitle"
+#~ msgstr "Add-on Summary"
+
+#, fuzzy
+#~ msgid "devcp_addon_field_supportemail_displaytitle"
+#~ msgstr "Support Email"
+
+#, fuzzy
+#~ msgid "devcp_addon_field_supporturl_displaytitle"
+#~ msgstr "Support URL"
+
+#, fuzzy
+#~ msgid "devcp_addon_field_versionnotes_displaytitle"
+#~ msgstr "Version Notes"
+
+#, fuzzy
+#~ msgid "devcp_addon_nominate_pagetitle"
+#~ msgstr "Nominate Add-on"
+
+#, fuzzy
+#~ msgid "devcp_addon_nominated_successfully"
+#~ msgstr "Add-on nominated successfully!"
+
+#, fuzzy
+#~ msgid "devcp_addon_status_criteria_review"
+#~ msgstr "Several user reviews of the add-on (may be external reviews)."
+
+# %1 is the addon edit link
+# %2 is the main dev CP link
+#, fuzzy
+#~ msgid "devcp_addon_submission_makechanges"
+#~ msgstr ""
+#~ "Visit the %1$s page to make changes to your submission, or %2$s to return "
+#~ "to the Developer Tools."
+
+#, fuzzy
+#~ msgid "devcp_addon_submission_makechanges_devcp_link"
+#~ msgstr "click here"
+
+#, fuzzy
+#~ msgid "devcp_addon_submission_makechanges_link"
+#~ msgstr "Edit Add-on"
+
+#, fuzzy
+#~ msgid "devcp_addon_submission_pending"
+#~ msgstr ""
+#~ "This version has been placed in the sandbox while it awaits review from "
+#~ "sandbox testers and a Mozilla Add-ons editor. You will be notified by e-"
+#~ "mail when action has been taken."
+
+# %1 is the link to the sandbox information page
+#, fuzzy
+#~ msgid "devcp_addon_submission_sandbox_readmore"
+#~ msgstr "You can read more about the Sandbox Review System %s."
+
+#, fuzzy
+#~ msgid "devcp_addon_submission_sandbox_readmore_link"
+#~ msgstr "here"
+
+# %1 is the "nominate" link
+#, fuzzy
+#~ msgid "devcp_addon_submission_sandboxed"
+#~ msgstr ""
+#~ "This version has been placed in the sandbox for use by experienced users. "
+#~ "In order for it to be shown on the public site, you must %s your add-on "
+#~ "and undergo a review process."
+
+#, fuzzy
+#~ msgid "devcp_addon_submission_sandboxed_nominate_link"
+#~ msgstr "nominate"
+
+#, fuzzy
+#~ msgid "devcp_addon_submission_success"
+#~ msgstr "Your add-on submission has been completed successfully."
+
+#, fuzzy
+#~ msgid "devcp_addon_submission_trusted_public"
+#~ msgstr ""
+#~ "Because your add-on is trusted, this version has automatically been "
+#~ "approved for the public area."
+
+#, fuzzy
+#~ msgid "devcp_addon_submit_pagetitle"
+#~ msgstr "Submit Add-on"
+
+#, fuzzy
+#~ msgid "devcp_addon_updated_successfully"
+#~ msgstr "Add-on updated successfully"
+
+# %1 is the link to the preview upload page
+#, fuzzy
+#~ msgid "devcp_addon_upload_preview"
+#~ msgstr "You may wish to %s to increase interest in your add-on."
+
+#, fuzzy
+#~ msgid "devcp_addon_upload_preview_link"
+#~ msgstr "upload a preview"
+
+# #1 is the author email
+#, fuzzy
+#~ msgid "devcp_author_lookup_none_found"
+#~ msgstr "No author found [%s]"
+
+#, fuzzy
+#~ msgid "devcp_author_lookup_remove"
+#~ msgstr "Remove"
+
+#, fuzzy
+#~ msgid "devcp_button_cancel"
+#~ msgstr "Cancel"
+
+#, fuzzy
+#~ msgid "devcp_button_cancel_confirm"
+#~ msgstr "Are you sure you wish to cancel your submission?"
+
+#, fuzzy
+#~ msgid "devcp_button_next"
+#~ msgstr "Next"
+
+#, fuzzy
+#~ msgid "devcp_change_addontype"
+#~ msgstr "Change add-on type:"
+
+#, fuzzy
+#~ msgid "devcp_comments_updated"
+#~ msgstr "Developer Comments updated."
+
+#, fuzzy
+#~ msgid "devcp_details_addpreview_link"
+#~ msgstr "Add Preview"
+
+#, fuzzy
+#~ msgid "devcp_details_author"
+#~ msgstr "Author"
+
+#, fuzzy
+#~ msgid "devcp_details_authors"
+#~ msgstr "Authors"
+
+#, fuzzy
+#~ msgid "devcp_details_authors_none"
+#~ msgstr "None"
+
+#, fuzzy
+#~ msgid "devcp_details_categories"
+#~ msgstr "Categories"
+
+#, fuzzy
+#~ msgid "devcp_details_category"
+#~ msgstr "Category"
+
+#, fuzzy
+#~ msgid "devcp_details_description"
+#~ msgstr "Description"
+
+#, fuzzy
+#~ msgid "devcp_details_disabled"
+#~ msgstr "Disabled"
+
+#, fuzzy
+#~ msgid "devcp_details_guid"
+#~ msgstr "GUID"
+
+#, fuzzy
+#~ msgid "devcp_details_header_details"
+#~ msgstr "Details"
+
+#, fuzzy
+#~ msgid "devcp_details_header_devcomments"
+#~ msgstr "Developer Comments"
+
+#, fuzzy
+#~ msgid "devcp_details_header_previews"
+#~ msgstr "Previews"
+
+#, fuzzy
+#~ msgid "devcp_details_header_versions"
+#~ msgstr "Versions"
+
+#, fuzzy
+#~ msgid "devcp_details_homepage"
+#~ msgstr "Homepage"
+
+#, fuzzy
+#~ msgid "devcp_details_homepage_none"
+#~ msgstr "None"
+
+#, fuzzy
+#~ msgid "devcp_details_preview_nocaption"
+#~ msgstr "No caption"
+
+#, fuzzy
+#~ msgid "devcp_details_previews_nonefound"
+#~ msgstr "No previews found."
+
+#, fuzzy
+#~ msgid "devcp_details_submit_update"
+#~ msgstr "Update"
+
+#, fuzzy
+#~ msgid "devcp_details_supportemail"
+#~ msgstr "Support Email"
+
+#, fuzzy
+#~ msgid "devcp_details_supportemail_none"
+#~ msgstr "No support email provided by developer."
+
+#, fuzzy
+#~ msgid "devcp_details_supporturl"
+#~ msgstr "Support URL"
+
+#, fuzzy
+#~ msgid "devcp_details_supporturl_none"
+#~ msgstr "No support url provided by developer."
+
+#, fuzzy
+#~ msgid "devcp_details_trusted"
+#~ msgstr "Trusted"
+
+#, fuzzy
+#~ msgid "devcp_details_versions_none_found"
+#~ msgstr "No versions found."
+
+#, fuzzy
+#~ msgid "devcp_disable_cancel"
+#~ msgstr "Cancel and go back"
+
+#, fuzzy
+#~ msgid "devcp_disable_disable_button"
+#~ msgstr "Yes, disable it"
+
+#, fuzzy
+#~ msgid "devcp_disable_disable_confirm"
+#~ msgstr "Are you sure you want to disable this add-on?"
+
+#, fuzzy
+#~ msgid "devcp_disable_disable_description"
+#~ msgstr ""
+#~ "Disabling this add-on will hide it from searches and listings. It will "
+#~ "not be downloadable from the website and will not be returned in client "
+#~ "update checks. The add-on will effectively be deleted, although you will "
+#~ "be able to return here and re-enable it at your convenience."
+
+#, fuzzy
+#~ msgid "devcp_disable_disable_title"
+#~ msgstr "Disable %s"
+
+#, fuzzy
+#~ msgid "devcp_disable_enable_button"
+#~ msgstr "Yes, enable it"
+
+#, fuzzy
+#~ msgid "devcp_disable_enable_confirm"
+#~ msgstr "Are you sure you want to enable this add-on?"
+
+#, fuzzy
+#~ msgid "devcp_disable_enable_description"
+#~ msgstr ""
+#~ "Enabling this add-on will cause it to once again appear in searches and "
+#~ "listings. It will be downloadable both from the website and from client "
+#~ "update checks."
+
+#, fuzzy
+#~ msgid "devcp_disable_enable_title"
+#~ msgstr "Enable %s"
+
+#, fuzzy
+#~ msgid "devcp_edit_author_add"
+#~ msgstr "Add Author"
+
+#, fuzzy
+#~ msgid "devcp_edit_author_email"
+#~ msgstr "Author's Email Address"
+
+#, fuzzy
+#~ msgid "devcp_edit_author_remove"
+#~ msgstr "Remove"
+
+#, fuzzy
+#~ msgid "devcp_edit_error_categories_unavailable"
+#~ msgstr "No categories available for this add-on type."
+
+#, fuzzy
+#~ msgid "devcp_edit_file_error_incomplete"
+#~ msgstr "Incomplete transfer"
+
+#, fuzzy
+#~ msgid "devcp_edit_file_error_no"
+#~ msgstr "No file uploaded"
+
+#, fuzzy
+#~ msgid "devcp_edit_file_error_size"
+#~ msgstr "Exceeds maximum upload size"
+
+#, fuzzy
+#~ msgid "devcp_edit_header_authors"
+#~ msgstr "Authors"
+
+#, fuzzy
+#~ msgid "devcp_edit_icon_add_link"
+#~ msgstr "Add Icon"
+
+#, fuzzy
+#~ msgid "devcp_edit_icon_change_link"
+#~ msgstr "Change Icon"
+
+#, fuzzy
+#~ msgid "devcp_edit_label_allow_viewsource"
+#~ msgstr "Allow users to view the source files online"
+
+#, fuzzy
+#~ msgid "devcp_edit_label_categories"
+#~ msgstr "Categories"
+
+#, fuzzy
+#~ msgid "devcp_edit_label_defaultlocale"
+#~ msgstr "Default Locale"
+
+#, fuzzy
+#~ msgid "devcp_edit_label_icon_delete"
+#~ msgstr "Only clear the existing icon"
+
+#, fuzzy
+#~ msgid "devcp_edit_label_icon_new"
+#~ msgstr "New Icon File"
+
+#, fuzzy
+#~ msgid "devcp_edit_label_info"
+#~ msgstr "Icon"
+
+#, fuzzy
+#~ msgid "devcp_edit_locale_disambiguation_explanation"
+#~ msgstr "short additional info (such as a local dialect name)"
+
+#, fuzzy
+#~ msgid "devcp_edit_submit_update"
+#~ msgstr "Update"
+
+#, fuzzy
+#~ msgid "devcp_edit_target_locale_explanation"
+#~ msgstr ""
+#~ "<a href=\"http://wiki.mozilla.org/L10n:Simple_locale_names\">simple "
+#~ "locale name</a>, such as 'en-US'"
+
+#, fuzzy
+#~ msgid "devcp_editversion_checkedfiles_delete"
+#~ msgstr "Checked files will be deleted."
+
+# %1 is the file name
+# %2 is the file size (150 KB)
+#, fuzzy
+#~ msgid "devcp_editversion_filename_size"
+#~ msgstr "%1$s (%2$s)"
+
+#, fuzzy
+#~ msgid "devcp_editversion_label_files"
+#~ msgstr "Files"
+
+#, fuzzy
+#~ msgid "devcp_editversion_label_targetapps"
+#~ msgstr "Target Applications"
+
+#, fuzzy
+#~ msgid "devcp_editversion_nofiles"
+#~ msgstr "No files."
+
+#, fuzzy
+#~ msgid "devcp_editversion_reviewernotes"
+#~ msgstr "Notes to Reviewer"
+
+#, fuzzy
+#~ msgid "devcp_editversion_submit_update"
+#~ msgstr "Update"
+
+#, fuzzy
+#~ msgid "devcp_error_addon_field_summary_toolong"
+#~ msgstr ""
+#~ "Summaries are limited to a maximum of 250 characters.\n"
+#~ "(You entered %s)"
+
+#, fuzzy
+#~ msgid "devcp_error_addonname_not_unique"
+#~ msgstr ""
+#~ "The name for your add-on already exists in the database. Please make sure "
+#~ "that: <br /><li>Your GUIDs match. The most common cause for this error is "
+#~ "mismatched GUIDs.</li><li>You do not have a duplicate entry in the "
+#~ "database. If you do, you should update that entry or delete it and try "
+#~ "again.</li>"
+
+#, fuzzy
+#~ msgid "devcp_error_describe_changes"
+#~ msgstr "Please describe the changes made in this add-on update."
+
+#, fuzzy
+#~ msgid "devcp_error_file_guids_dont_match"
+#~ msgstr "Not all file GUIDs match"
+
+#, fuzzy
+#~ msgid "devcp_error_identical_version_exists"
+#~ msgstr ""
+#~ "An identical version (%s) already exists for this add-on and platform."
+
+#, fuzzy
+#~ msgid "devcp_error_nominate_message"
+#~ msgstr "You must supply the requested details for nomination."
+
+#, fuzzy
+#~ msgid "devcp_error_nominate_no_prerelease"
+#~ msgstr "You cannot nominate a pre-release add-on."
+
+#, fuzzy
+#~ msgid "devcp_error_nominate_sandbox_only"
+#~ msgstr "You can only nominate add-ons currently in the sandbox."
+
+#, fuzzy
+#~ msgid "devcp_error_saving"
+#~ msgstr "An error occurred trying to save your data."
+
+#, fuzzy
+#~ msgid "devcp_error_update_access_denied"
+#~ msgstr "You do not have permission to update this add-on."
+
+#, fuzzy
+#~ msgid "devcp_file_addanother"
+#~ msgstr "Add Another Platform File"
+
+#, fuzzy
+#~ msgid "devcp_form_author_add"
+#~ msgstr "Add Author"
+
+#, fuzzy
+#~ msgid "devcp_form_author_remove"
+#~ msgstr "Remove"
+
+#, fuzzy
+#~ msgid "devcp_form_categories_nextstep"
+#~ msgstr ""
+#~ "Categories for your new add-on type will be available in the next step."
+
+#, fuzzy
+#~ msgid "devcp_form_error_categories_unavailable"
+#~ msgstr "No categories available for this add-on type."
+
+#, fuzzy
+#~ msgid "devcp_form_error_description_notempty"
+#~ msgstr "Please enter a description of your add-on."
+
+#, fuzzy
+#~ msgid "devcp_form_error_name_required"
+#~ msgstr "Please enter the name of your add-on."
+
+#, fuzzy
+#~ msgid "devcp_form_error_select_addontype"
+#~ msgstr "Please select the type of add-on you are submitting."
+
+#, fuzzy
+#~ msgid "devcp_form_error_summary_notempty"
+#~ msgstr "Please enter a summary of your add-on."
+
+#, fuzzy
+#~ msgid "devcp_form_label_addonfile"
+#~ msgstr "Add-on File"
+
+#, fuzzy
+#~ msgid "devcp_form_label_addonfile2"
+#~ msgstr "Add-on File 2"
+
+#, fuzzy
+#~ msgid "devcp_form_label_addonfile3"
+#~ msgstr "Add-on File 3"
+
+#, fuzzy
+#~ msgid "devcp_form_label_addontype"
+#~ msgstr "Add-on Type"
+
+#, fuzzy
+#~ msgid "devcp_form_label_allow_viewsource"
+#~ msgstr "Allow users to view the source files online"
+
+#, fuzzy
+#~ msgid "devcp_form_label_author_email"
+#~ msgstr "Author's Email Address"
+
+#, fuzzy
+#~ msgid "devcp_form_label_authors"
+#~ msgstr "Authors"
+
+#, fuzzy
+#~ msgid "devcp_form_label_categories"
+#~ msgstr "Categories"
+
+#, fuzzy
+#~ msgid "devcp_form_label_defaultlocale"
+#~ msgstr "Default Locale"
+
+#, fuzzy
+#~ msgid "devcp_form_label_description"
+#~ msgstr "Description"
+
+#, fuzzy
+#~ msgid "devcp_form_label_eula"
+#~ msgstr "End-User License Agreement (EULA)"
+
+#, fuzzy
+#~ msgid "devcp_form_label_externalsoftware"
+#~ msgstr "This add-on requires external software"
+
+#, fuzzy
+#~ msgid "devcp_form_label_files"
+#~ msgstr "Files"
+
+#, fuzzy
+#~ msgid "devcp_form_label_homepage"
+#~ msgstr "Homepage"
+
+#, fuzzy
+#~ msgid "devcp_form_label_iconfile"
+#~ msgstr "Icon File"
+
+#, fuzzy
+#~ msgid "devcp_form_label_name"
+#~ msgstr "Name"
+
+#, fuzzy
+#~ msgid "devcp_form_label_platforms"
+#~ msgstr "Supported Platforms"
+
+#, fuzzy
+#~ msgid "devcp_form_label_prerelease"
+#~ msgstr "This is a pre-release"
+
+#, fuzzy
+#~ msgid "devcp_form_label_privacy"
+#~ msgstr "Privacy Policy"
+
+#, fuzzy
+#~ msgid "devcp_form_label_sitespecific"
+#~ msgstr "This is a site-specific add-on"
+
+#, fuzzy
+#~ msgid "devcp_form_label_summary"
+#~ msgstr "Summary"
+
+#, fuzzy
+#~ msgid "devcp_form_label_supportemail"
+#~ msgstr "Support Email"
+
+#, fuzzy
+#~ msgid "devcp_form_label_supporturl"
+#~ msgstr "Support URL"
+
+#, fuzzy
+#~ msgid "devcp_form_label_target_applications"
+#~ msgstr "Target Applications"
+
+#, fuzzy
+#~ msgid "devcp_form_label_version"
+#~ msgstr "Version"
+
+#, fuzzy
+#~ msgid "devcp_form_label_versionnotes"
+#~ msgstr "Version Notes"
+
+#, fuzzy
+#~ msgid "devcp_form_no_target_apps"
+#~ msgstr "None"
+
+#, fuzzy
+#~ msgid "devcp_form_reviewernotes"
+#~ msgstr "Notes to Reviewer"
+
+#, fuzzy
+#~ msgid "devcp_form_trustedaddon_destination"
+#~ msgstr ""
+#~ "Because your add-on is trusted, please choose where this version should "
+#~ "go:"
+
+#, fuzzy
+#~ msgid "devcp_form_trustedaddon_destination_public"
+#~ msgstr "Public"
+
+#, fuzzy
+#~ msgid "devcp_form_trustedaddon_destination_sandbox"
+#~ msgstr "Sandbox"
+
+#, fuzzy
+#~ msgid "devcp_header_developer_agreement"
+#~ msgstr "Developer Agreement"
+
+#, fuzzy
+#~ msgid "devcp_header_step1"
+#~ msgstr "Step 1"
+
+#, fuzzy
+#~ msgid "devcp_header_step1_upload"
+#~ msgstr "Upload File"
+
+#, fuzzy
+#~ msgid "devcp_header_step2"
+#~ msgstr "Step 2"
+
+#, fuzzy
+#~ msgid "devcp_header_step2_addondetails"
+#~ msgstr "Add-on Details"
+
+#, fuzzy
+#~ msgid "devcp_header_step3"
+#~ msgstr "Step 3"
+
+#, fuzzy
+#~ msgid "devcp_header_step3_versiondetails"
+#~ msgstr "Version Details"
+
+#, fuzzy
+#~ msgid "devcp_header_step4"
+#~ msgstr "Step 4"
+
+#, fuzzy
+#~ msgid "devcp_header_step4_localization"
+#~ msgstr "Localization"
+
+#, fuzzy
+#~ msgid "devcp_header_step5"
+#~ msgstr "Step 5"
+
+#, fuzzy
+#~ msgid "devcp_header_step5_success"
+#~ msgstr "Success"
+
+#, fuzzy
+#~ msgid "devcp_index_header_myaddons"
+#~ msgstr "My Add-ons"
+
+#, fuzzy
+#~ msgid "devcp_nominate_link_returnto_details"
+#~ msgstr "Return to add-on details"
+
+# %1 is the autodetected addon type
+#, fuzzy
+#~ msgid "devcp_notice_autodetected_addontype"
+#~ msgstr "Automatically detected add-on type: %s."
+
+# %1 is the default locale name (English (US))
+# %2 is the default locale code (en-US)
+# %3 is the current page locale name (Deutsch)
+# %4 is the current page locale code (de)
+#, fuzzy
+#~ msgid "devcp_notice_different_defaultlocale"
+#~ msgstr ""
+#~ "The default locale of this add-on (%1$s [%2$s]) is different from your "
+#~ "currently selected locale (%3$s [%4$s]). The fields below should be "
+#~ "completed in %1$s."
+
+#, fuzzy
+#~ msgid "devcp_question_addontype_incorrect"
+#~ msgstr "Incorrect?"
+
+#, fuzzy
+#~ msgid "devcp_question_delete_file"
+#~ msgstr "Are you sure you want to delete this file?"
+
+#, fuzzy
+#~ msgid "devcp_skip_reviewing_addon_info"
+#~ msgstr "Skip updating my current add-on information"
+
+#, fuzzy
+#~ msgid "devcp_submissions_disabled"
+#~ msgstr ""
+#~ "Add-on submissions are currently disabled. Please check back at a later "
+#~ "time."
+
+#, fuzzy
+#~ msgid "devcp_submit_accept_dev_agreement"
+#~ msgstr "I Accept"
+
+#, fuzzy
+#~ msgid "devcp_submit_decline_dev_agreement"
+#~ msgstr "I Decline"
+
+#, fuzzy
+#~ msgid "devcp_summary_admin_disabled"
+#~ msgstr "This add-on has been disabled by an administrator."
+
+#, fuzzy
+#~ msgid "devcp_summary_header_disabled"
+#~ msgstr "Disabled"
+
+#, fuzzy
+#~ msgid "devcp_summary_header_trusted"
+#~ msgstr "Trusted"
+
+# %1 is a link to the addon submit page
+#, fuzzy
+#~ msgid "devcp_summary_noaddons_submit_one"
+#~ msgstr "You don't have any add-ons. Click %s to submit one."
+
+#, fuzzy
+#~ msgid "devcp_summary_noaddons_submit_one_link"
+#~ msgstr "here"
+
+# %1 is the link to the preview upload page
+#, fuzzy
+#~ msgid "devcp_theme_upload_preview"
+#~ msgstr "Please be sure to %s for your theme."
+
+#, fuzzy
+#~ msgid "devcp_theme_upload_preview_link"
+#~ msgstr "upload a preview"
+
+#, fuzzy
+#~ msgid "devcp_version_edit_pagetitle"
+#~ msgstr "Edit Version"
+
+#, fuzzy
+#~ msgid "devcp_version_updated_successfully"
+#~ msgstr "Version updated successfully."
+
+#, fuzzy
+#~ msgid "editors_submissiontype_new"
+#~ msgstr "New"
+
+#, fuzzy
+#~ msgid "editors_submissiontype_updated"
+#~ msgstr "Updated"
+
+#, fuzzy
+#~ msgid "editors_th_addon_age"
+#~ msgstr "Addon Age"
+
+#, fuzzy
+#~ msgid "editors_th_addontypes"
+#~ msgstr "Add-on Types"
+
+#, fuzzy
+#~ msgid "editors_th_age"
+#~ msgstr "Age"
+
+#, fuzzy
+#~ msgid "editors_th_applications"
+#~ msgstr "Applications"
+
+#, fuzzy
+#~ msgid "editors_th_platforms"
+#~ msgstr "Platforms"
+
+#, fuzzy
+#~ msgid "editors_th_submissiontypes"
+#~ msgstr "Submission Types"
+
+#, fuzzy
+#~ msgid "error_notice"
+#~ msgstr "Notice"
+
+#, fuzzy
+#~ msgid "forum_save"
+#~ msgstr "Save"
+
+#, fuzzy
+#~ msgid "home"
+#~ msgstr "home"
+
+#, fuzzy
+#~ msgid "nav_category_plugins"
+#~ msgstr "Plugins"
+
+#, fuzzy
+#~ msgid "page_title_experimental_addons"
+#~ msgstr "Experimental Add-ons"
+
+#, fuzzy
+#~ msgid "pages_experimental_addons_backbutton"
+#~ msgstr "Back to the previous page"
+
+# %1 is page number, %2 is total page count
+#, fuzzy
+#~ msgid "pagination_page_number_title"
+#~ msgstr "This is page %1$s of %2$s"
+
+#, fuzzy
+#~ msgid "search_matching_addons_number"
+#~ msgid_plural "search_matching_addons_number"
+#~ msgstr[0] "%s matching add-on"
+#~ msgstr[1] "%s matching add-ons"
+
+#, fuzzy
+#~ msgid "statistics_rss_icon_title"
+#~ msgstr "RSS feed of summary data"
diff --git a/site/app/locale/ga_IE/LC_MESSAGES/messages.mo b/site/app/locale/ga_IE/LC_MESSAGES/messages.mo
new file mode 100644
index 0000000..e6948f9
--- /dev/null
+++ b/site/app/locale/ga_IE/LC_MESSAGES/messages.mo
Binary files differ
diff --git a/site/app/locale/ga_IE/LC_MESSAGES/messages.po b/site/app/locale/ga_IE/LC_MESSAGES/messages.po
new file mode 100644
index 0000000..7f8fa9e
--- /dev/null
+++ b/site/app/locale/ga_IE/LC_MESSAGES/messages.po
@@ -0,0 +1,7943 @@
+# Remora Preliminary Language File
+# Copyright (C) 2006 Mozilla Corporation
+# This file is distributed under the same license as the REMORA package.
+# Wil Clouser <clouserw@mozilla.com>, 2006.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: REMORA 0.1\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2009-01-16 11:45-0800\n"
+"PO-Revision-Date: 2008-04-08 00:00-0600\n"
+"Last-Translator: Kevin Scannell <kscanne@gmail.com>\n"
+"Language-Team: Irish <gaeilge-gnulinux@lists.sourceforge.net>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=5; plural=n==1 ? 0 : n==2 ? 1 : n<7 ? 2 : n < 11 ? "
+"3 : 4\n"
+
+#: views/addons/policy.thtml:98
+msgid "a_cancel_installation"
+msgstr "Cealaigh an tSuiteáil"
+
+#. This is the text that appears on buttons to download add-ons.
+#. %$1s is an optional string that only appears if the add-on is only available for
+#. a certain platform. Examples: (Windows) or (Linux)
+#. Note that the parentheses are included in the string. :(
+#: views/elements/amo2009/install.thtml:126
+#: views/elements/amo2009/install.thtml:227
+#: views/elements/amo2009/install.thtml:257
+#: views/elements/amo2009/install.thtml:300
+#: views/elements/amo2009/install.thtml:312 views/elements/install.thtml:73
+#: views/elements/install.thtml:181 views/elements/install.thtml:205
+#: views/elements/install.thtml:248 views/elements/install.thtml:260
+#: views/addons/plugins.thtml:66 views/addons/plugins.thtml:76
+#: views/addons/plugins.thtml:86 views/addons/plugins.thtml:96
+#: views/addons/plugins.thtml:119
+#, php-format
+msgid "a_download"
+msgstr "Ãosluchtaigh Anois %s"
+
+#: views/addons/policy.thtml:72
+msgid "a_eula_download"
+msgstr "Glac Leis agus Ãosluchtaigh"
+
+#: views/addons/policy.thtml:74
+msgid "a_eula_install"
+msgstr "Glac Leis agus Suiteáil"
+
+#: views/elements/header.thtml:76 views/elements/header.thtml:82
+#: views/api/api_addon.thtml:55 views/api/collections_feed.thtml:75
+#: views/sharing_api/addon.thtml:64
+msgid "a_header_public"
+msgstr "Poiblí"
+
+#: views/elements/header.thtml:58 views/elements/header.thtml:75
+#: views/elements/header.thtml:80 views/api/api_addon.thtml:57
+#: views/api/collections_feed.thtml:77 views/sharing_api/addon.thtml:66
+msgid "a_header_sandbox"
+msgstr "Bosca Gainimh"
+
+#. %s is a date in the _('date') format
+#: views/elements/amo2009/homepage_addon.thtml:115
+#: views/elements/addon_listitem.thtml:122 views/elements/feature.thtml:106
+#: views/addons/display.thtml:104 views/addons/browse_thumbs.thtml:73
+msgid "addon_detail_last_updated"
+msgstr "Nuashonraithe %s"
+
+#. %s is the version of the add-on. Example: 3.2a1
+#: views/elements/amo2009/addon_version_detail.thtml:51
+#: views/elements/addon_version_detail.thtml:51
+#, php-format
+msgid "addon_display_header_version"
+msgstr "Leagan %s"
+
+# preceded by a number I think
+#: views/addons/browse_thumbs.thtml:80
+msgid "addon_downloads"
+msgstr "íosluchtú"
+
+# preceded by a number
+#: views/addons/display.thtml:147
+msgid "addon_downloads_total"
+msgstr "íosluchtú san iomlán"
+
+# preceded by a number
+#: views/elements/amo2009/homepage_addon.thtml:106
+#: views/elements/addon_listitem.thtml:115 views/elements/feature.thtml:101
+#: views/addons/category_landing.thtml:157 views/addons/display.thtml:146
+#: views/addons/browse_thumbs.thtml:80
+msgid "addon_downloads_weekly"
+msgstr "íosluchtú sa tseachtain"
+
+# %1 is the add-on count, %2 the category name
+#. %1 is the add-on count, %2 the category name
+#: views/addons/browse_thumbs.thtml:104 views/addons/browse.thtml:60
+#, php-format
+msgid "addon_list_category_totalcount"
+msgid_plural "addon_list_category_totalcount"
+msgstr[0] "%1$s bhreiseán"
+msgstr[1] "%1$s bhreiseán"
+msgstr[2] "%1$s bhreiseán"
+msgstr[3] "%1$s mbreiseán"
+msgstr[4] "%1$s breiseán"
+
+#: views/elements/amo2009/addon_list_options.thtml:103
+#: views/elements/pagination.thtml:67
+#: views/elements/addon_list_options.thtml:94
+msgid "addon_list_perpage"
+msgstr "sa leathanach"
+
+#: views/elements/amo2009/addon_list_options.thtml:84
+#: views/elements/addon_list_options.thtml:98
+msgid "addon_list_sortby"
+msgstr "Sórtáil de réir:"
+
+#: views/helpers/addons_html.php:568 views/elements/amo2009/install.thtml:321
+#: views/elements/feature.thtml:89
+msgid "addon_listitem_flag_experimental"
+msgstr "turgnamhach"
+
+#: views/helpers/addons_html.php:570
+msgid "addon_listitem_flag_recommended"
+msgstr "molta"
+
+# %1 is the addon name, %2 is the platform
+#. %1 is the add-on name, %2 is the platform
+#: views/pages/js_constants.js.thtml:66
+msgid "addon_not_available_for_platform"
+msgstr "Níl %1$s ar fáil ar %2$s."
+
+# %1 is the addon name
+#. %1 is the add-on name
+#: views/addons/policy.thtml:101 views/addons/previews.thtml:60
+#: views/addons/versions.thtml:130 views/reviews/flag.thtml:61
+#: views/reviews/add.thtml:114 views/reviews/display.thtml:216
+#: views/reviews/review_added.thtml:57
+#, php-format
+msgid "addon_review_a_back_to_addon_x"
+msgstr "Ar ais go %1$s..."
+
+# %1 is the addon name
+#. %1 is the add-on name
+#: views/reviews/flag.thtml:60 views/reviews/add.thtml:113
+#: views/reviews/review_added.thtml:56
+#, php-format
+msgid "addon_review_a_back_to_reviews"
+msgstr "Ar ais go dtí na léirmheasanna..."
+
+#: views/reviews/add.thtml:85
+msgid "addon_review_add_rating_field"
+msgstr "Rátáil:"
+
+#: views/reviews/add.thtml:102
+msgid "addon_review_add_review_field"
+msgstr "Léirmheas:"
+
+#: views/reviews/add.thtml:107
+msgid "addon_review_add_submit"
+msgstr "Seol do léirmheas"
+
+#. %s is the name of the add-on
+#: views/reviews/add.thtml:51
+#, php-format
+msgid "addon_review_add_title"
+msgstr "Déan léirmheas ar %s"
+
+#: views/reviews/add.thtml:78
+msgid "addon_review_add_title_field"
+msgstr "Teideal/Achoimre:"
+
+#: views/reviews/display.thtml:77 views/reviews/display.thtml:161
+msgid "addon_review_admin_delete"
+msgstr "Scrios"
+
+#: views/reviews/display.thtml:76
+msgid "addon_review_author_reply_link"
+msgstr "Freagair"
+
+#: views/reviews/delete.thtml:62
+msgid "addon_review_confirm_delete"
+msgstr "An bhfuil tú cinnte go dteastaíonn uait an léirmheas seo a scriosadh?"
+
+#: views/reviews/delete.thtml:63
+msgid "addon_review_confirm_no"
+msgstr "Níl"
+
+#: views/reviews/delete.thtml:64
+msgid "addon_review_confirm_yes"
+msgstr "Tá"
+
+#: views/reviews/delete.thtml:48
+msgid "addon_review_delete_header"
+msgstr "Scrios an Léirmheas"
+
+#: controllers/reviews_controller.php:449
+msgid "addon_review_deleted_successfully"
+msgstr "Scriosadh an léirmheas."
+
+#. %s is the name of the add-on
+#: views/reviews/add.thtml:51
+#, php-format
+msgid "addon_review_edit_title"
+msgstr "Cuir Léirmheas ar %s in Eagar"
+
+#. %1 is the count of characters entered as notes for the review flag reason.
+#: controllers/reviews_controller.php:539
+#, fuzzy
+msgid "addon_review_flag_error_other_length"
+msgstr ""
+"Problem flagging review: Notes for flagged reviews are limited to between 10 "
+"and 100 characters; your character length was %1$s."
+
+# Removing an extra comma
+#. Removing an extra comma
+#: views/reviews/review_added.thtml:53
+msgid "addon_review_in_moderation"
+msgstr ""
+"Tabhair faoi deara nach mbeidh do léirmheas ar fáil ar an suíomh poiblí go "
+"dtí go ndéanfaidh eagarthóir iniúchadh air."
+
+#: views/reviews/add.thtml:57
+msgid "addon_review_in_reply_to"
+msgstr "Freagra chuig an bhforbróir:"
+
+# %1 is the review count, %2 is the nickname or full name of the user.
+#. %1 is the review count, %2 is the nickname or full name of the user.
+#: views/reviews/display.thtml:131
+#, php-format
+msgid "addon_review_others_by_user"
+msgid_plural "addon_review_others_by_user"
+msgstr[0] ""
+"Féach ar %1$s léirmheas a rinne %2$s ar an mbreiseán seo roimhe seo."
+msgstr[1] ""
+"Féach ar %1$s léirmheas a rinne %2$s ar an mbreiseán seo roimhe seo."
+msgstr[2] ""
+"Féach ar %1$s léirmheas a rinne %2$s ar an mbreiseán seo roimhe seo."
+msgstr[3] ""
+"Féach ar %1$s léirmheas a rinne %2$s ar an mbreiseán seo roimhe seo."
+msgstr[4] ""
+"Féach ar %1$s léirmheas a rinne %2$s ar an mbreiseán seo roimhe seo."
+
+# %1 is the addon name
+#. %1 is the add-on name
+#: controllers/reviews_controller.php:201
+#: controllers/reviews_controller.php:250
+#: controllers/reviews_controller.php:345
+#: controllers/reviews_controller.php:424
+#, php-format
+msgid "addon_review_pagetitle"
+msgstr "Léirmheasanna ar %s"
+
+# %1 is the user, %2 is the (localized) date
+#. %1 is the user, %2 is the (localized) date
+#: views/reviews/display.thtml:160
+#, php-format
+msgid "addon_review_reply_on_x_by_y"
+msgstr "Freagra ó %1$s ar %2$s"
+
+#: views/reviews/display.thtml:157
+msgid "addon_review_reply_prefix"
+msgstr "Freagra ón Fhorbróir:"
+
+#: views/reviews/review_added.thtml:51
+msgid "addon_review_saved_successfully"
+msgstr "Sábháladh do léirmheas. Go raibh maith agat!"
+
+#: views/addons/display.thtml:354 views/reviews/display.thtml:72
+msgid "addon_reviewed_by_u_on_d"
+msgstr "ag %1$s ar %2$s"
+
+# %1 is the user, %2 is the (localized) date, %3 is the rating
+#. %1 is the user, %2 is the (localized) date, %3 is the rating
+#: views/editors/reviews_queue.thtml:57 views/editors/reviews_queue.thtml:68
+#: views/reviews/add.thtml:63 views/reviews/delete.thtml:54
+#, php-format
+msgid "addon_reviewed_on_x_rated_y"
+msgstr "ag %1$s ar %2$s (rátáil %3$s)"
+
+#: views/elements/amo2009/addon_version_detail.thtml:52
+#: views/elements/addon_version_detail.thtml:52
+msgid "addon_version_permalink"
+msgstr "Nasc buan leis an leagan seo"
+
+#. %1 is the current Application name (e.g. Firefox)
+#. %2 is the Application's version number
+#: views/addons/versions.thtml:140
+msgid "addon_versions_getlatestversion"
+msgstr "An leagan is déanaí atá comhoiriúnach do %1$s %2$s"
+
+#: views/addons/display.thtml:447
+msgid "addons_author_addons_submit"
+msgstr "Téigh"
+
+#: views/elements/amo2009/homepage_addon.thtml:100
+#: views/elements/feature.thtml:95
+msgid "addons_author_tooltip"
+msgstr "Féach ar Phróifíl an Údair"
+
+# %1 is the name of the Application (eg. Firefox)
+#. %1 is the name of the Application (eg. Firefox)
+#: controllers/addons_controller.php:1296
+msgid "addons_browse_all_themes_title"
+msgstr "Brabhsáil gach Téama :: Breiseáin %1$s"
+
+#. %s is the name of the category
+#: controllers/addons_controller.php:1016
+#, php-format
+msgid "addons_browse_browse_category"
+msgstr "Brabhsáil %s"
+
+# %1 is the name of the theme category (eg. Modern)
+# %2 is the name of the Application (eg. Firefox)
+#. %1 is the name of the theme category (eg. Modern)
+#. %2 is the name of the Application (eg. Firefox)
+#: controllers/addons_controller.php:664
+msgid "addons_browse_categories_header_theme"
+msgstr "Brabhsáil Téamaí %1$s :: Breiseáin %2$s"
+
+#: views/addons/display.thtml:249
+#, fuzzy
+msgid "addons_display_a_license_what"
+msgstr "What's this?"
+
+#: views/reviews/display.thtml:222
+msgid "addons_display_add_review"
+msgstr "Cuir léirmheas leis"
+
+#: views/addons/display.thtml:294
+msgid "addons_display_advanced_details"
+msgstr "Mionsonraí Casta"
+
+#: views/addons/display.thtml:98
+msgid "addons_display_categories"
+msgstr "Catagóirí"
+
+#: views/addons/display.thtml:482
+#, fuzzy
+msgid "addons_display_collection_add"
+msgstr "Add to a collection:"
+
+#: views/addons/display.thtml:491
+#, fuzzy
+msgid "addons_display_collection_add_new"
+msgstr "New Collection..."
+
+#: views/addons/display.thtml:487
+#, fuzzy
+msgid "addons_display_collection_add_select_one"
+msgstr "Select a collection..."
+
+#: views/addons/display.thtml:493
+#, fuzzy
+msgid "addons_display_collection_add_submit"
+msgstr "Publish"
+
+#. %1$s is the add-on name
+#. %2$s is the collection name, linked to the collection's page
+#: views/pages/js_constants.js.thtml:103 views/addons/display.thtml:61
+#, fuzzy
+msgid "addons_display_collection_publish_success"
+msgstr "%1$s has been added to the %2$s collection."
+
+#: views/addons/display.thtml:483
+#, fuzzy
+msgid "addons_display_collection_whatsthis"
+msgstr "What's this?"
+
+#. %1$s is a number
+#: views/addons/display.thtml:473
+#, fuzzy
+msgid "addons_display_collections_more"
+msgid_plural "addons_display_collections_more"
+msgstr[0] "and %1$s more collection"
+msgstr[1] "and %1$s more collections"
+
+#: views/addons/display.thtml:403
+msgid "addons_display_detailed_review"
+msgstr "léirmheas mionsonraithe"
+
+#: views/reviews/add.thtml:89 views/reviews/add.thtml:90
+msgid "addons_display_dont_like_it"
+msgstr "Ní maith liom é"
+
+#: views/reviews/display.thtml:220
+msgid "addons_display_edit_review"
+msgstr "Cuir do léirmheas in eagar"
+
+#: views/addons/display.thtml:132
+msgid "addons_display_has_privacy"
+msgstr "Tá polasaí príobháideachta ag an mbreiseán seo."
+
+#: views/reviews/add.thtml:87 views/reviews/add.thtml:88
+msgid "addons_display_hate_it"
+msgstr "Is fuath liom é"
+
+#: views/addons/display.thtml:462
+#, fuzzy
+msgid "addons_display_header_collections"
+msgstr "Related Collections"
+
+#: views/addons/display.thtml:297
+msgid "addons_display_header_developer_comments"
+msgstr "Nótaí ón Fhorbróir"
+
+#: views/addons/display.thtml:230
+msgid "addons_display_header_homepage"
+msgstr "Leathanach Baile"
+
+#: views/addons/display.thtml:247 views/addons/versions.thtml:110
+#, fuzzy
+msgid "addons_display_header_license"
+msgstr "Source Code License"
+
+#: views/addons/display.thtml:337
+msgid "addons_display_header_reviews"
+msgstr "Léirmheasanna"
+
+#: views/addons/display.thtml:261
+msgid "addons_display_header_support"
+msgstr "Tacaíocht"
+
+#: views/reviews/add.thtml:91 views/reviews/add.thtml:92
+msgid "addons_display_like_it"
+msgstr "Is maith liom é"
+
+#: views/addons/display.thtml:210
+msgid "addons_display_long_description"
+msgstr "Cur Síos Fada"
+
+#: views/reviews/add.thtml:95 views/reviews/add.thtml:96
+msgid "addons_display_love_it"
+msgstr "Tá sé an-an-mhaith!"
+
+#: views/addons/display.thtml:178
+msgid "addons_display_more_images"
+msgstr "Tuilleadh Ãomhánna"
+
+#: views/addons/display.thtml:465
+#, fuzzy
+msgid "addons_display_nocollections"
+msgstr "This add-on is not yet in any collections."
+
+#. %1$s is either an author's name or a comma separated list of authors. Using
+#. the list doesn't make sense in the English plural form so we ignore the
+#. variable.
+#: views/addons/display.thtml:436
+msgid "addons_display_other_addons_by"
+msgid_plural "addons_display_other_addons_by"
+msgstr[0] "Breiseáin eile scríofa ag %1$s"
+msgstr[1] "Breiseáin eile scríofa ag na húdair seo"
+msgstr[2] "Breiseáin eile scríofa ag na húdair seo"
+msgstr[3] "Breiseáin eile scríofa ag na húdair seo"
+msgstr[4] "Breiseáin eile scríofa ag na húdair seo"
+
+#. %s is the name of the add-on and the add-on section. Example:
+#. Some Add-on :: Firefox Add-ons
+#. This should not be concatenated in the code and should be fixed.
+#: controllers/addons_controller.php:141 controllers/addons_controller.php:280
+#: controllers/addons_controller.php:1442
+#, php-format
+msgid "addons_display_pagetitle"
+msgstr "%s"
+
+#. %s is an email address
+#: views/addons/display.thtml:286
+#, php-format
+msgid "addons_display_paragraph_supportinfoemail"
+msgstr "Soláthraíonn an forbróir (%s) tacaíocht le haghaidh an bhreiseáin seo"
+
+#. %$1s is a URL
+#. %$2s is an email address
+#: views/addons/display.thtml:269
+#, php-format
+msgid "addons_display_paragraph_supportinfoemailurl"
+msgstr ""
+"Soláthraíonn an forbróir ag %1$s tacaíocht le haghaidh an bhreiseáin seo, nó "
+"b'fhéidir leat ríomhphoist a sheoladh chuig %2$s"
+
+#. %s is a URL
+#: views/addons/display.thtml:278
+#, php-format
+msgid "addons_display_paragraph_supportinfourl"
+msgstr "Soláthraíonn an forbróir ag %s tacaíocht le haghaidh an bhreiseáin seo"
+
+#: views/addons/display.thtml:383
+msgid "addons_display_rate_it"
+msgstr "Rátáil É"
+
+#: views/reviews/add.thtml:93 views/reviews/add.thtml:94
+msgid "addons_display_really_like_it"
+msgstr "Tá sé an-mhaith"
+
+#: views/addons/display.thtml:410
+msgid "addons_display_review_etiquette"
+msgstr ""
+"Ná cuir tuairiscí faoi fhabhtanna i do léirmheas, le do thoil. Ní chuirimid "
+"do sheoladh ríomhphoist ar fáil d'fhorbróirí an bhreiseáin, agus seans go "
+"mbeidh orthu dul i dteagmháil leat chun an fhadhb a réiteach."
+
+# %1 is the review guidelines link
+#. %1 is the review guidelines link
+#: views/addons/display.thtml:417
+msgid "addons_display_review_guidelines_link"
+msgstr "<a href=\"%s\">Treoirlínte do Léirmheasanna</a>"
+
+# %1 is the support section link
+#. %1 is the support section link
+#: views/addons/display.thtml:414
+msgid "addons_display_review_see_support"
+msgstr ""
+"Féach ar an <a href=\"%1$s\">Leathanach Tacaíochta</a> chun cabhair leis an "
+"mbreiseán seo a fháil."
+
+#: views/addons/display.thtml:404
+msgid "addons_display_review_submit"
+msgstr "Sábháil"
+
+# %1 is generally speaking, plural, "Uirlisí Forbróra", or "Foclóirí agus Pacáistí Teanga", etc.
+#: views/addons/display.thtml:430
+#, php-format
+msgid "addons_display_see_all_addons"
+msgstr "Féach ar na %1$s go léir"
+
+# %1 is the number of reviews
+#. %1 is the number of reviews
+#: views/addons/display.thtml:364
+#, php-format
+msgid "addons_display_see_all_reviews"
+msgstr "Féach ar gach léirmheas (%1$s)"
+
+#: views/addons/display.thtml:219
+msgid "addons_display_see_all_versions"
+msgstr "Féach Ar Gach Leagan"
+
+#: views/addons/display.thtml:321 views/addons/versions.thtml:117
+msgid "addons_display_view_source"
+msgstr "Amharc ar fhoinse"
+
+#: views/addons/display.thtml:324
+msgid "addons_display_view_stats"
+msgstr "Amharc ar staitisticí"
+
+#: views/addons/display.thtml:376
+msgid "addons_display_what_do_you_think"
+msgstr "Cad é do bharúil?"
+
+#: views/elements/app_compatibility.thtml:49
+msgid "addons_display_workswith"
+msgstr "Oibríonn sé le:"
+
+#: views/addons/home.thtml:112
+#, fuzzy
+msgid "addons_home_browse_new"
+msgstr "Just Added"
+
+#: views/addons/home.thtml:110
+#, fuzzy
+msgid "addons_home_browse_popular"
+msgstr "Popular"
+
+#: views/addons/home.thtml:108
+#, fuzzy
+msgid "addons_home_browse_recommended"
+msgstr "Recommended"
+
+#: views/addons/home.thtml:127 views/addons/home.thtml:134
+#: views/addons/home.thtml:141 views/addons/home.thtml:148
+#, fuzzy
+msgid "addons_home_browse_subscribe"
+msgstr "Subscribe"
+
+#: views/addons/home.thtml:101
+#, fuzzy
+msgid "addons_home_browse_title"
+msgstr "Browse Add-ons"
+
+#: views/addons/home.thtml:114
+#, fuzzy
+msgid "addons_home_browse_updated"
+msgstr "Updated"
+
+#: views/elements/amo2009/homepage_addon.thtml:100
+#: views/elements/addon_discussionheader.thtml:83
+#: views/elements/addon_listitem.thtml:109 views/elements/feature.thtml:95
+#: views/addons/category_landing.thtml:66 views/addons/policy.thtml:57
+#: views/addons/display.thtml:70 views/addons/home.thtml:178
+msgid "addons_home_by"
+msgstr "le"
+
+#: views/addons/home.thtml:169
+#, fuzzy
+msgid "addons_home_collection_popular_title"
+msgstr "Popular Collections"
+
+#: views/elements/amo2009/categories.thtml:69 views/addons/home.thtml:160
+#, fuzzy
+msgid "addons_home_collections"
+msgstr "Collections"
+
+#. %1$s is the count of addons in a collection
+#: views/elements/amo2009/collection_listing_item.thtml:51
+#: views/addons/home.thtml:185
+#, fuzzy
+msgid "addons_home_collections_addon_count"
+msgid_plural "addons_home_collections_addon_count"
+msgstr[0] "<strong>%1$s</strong> add-on"
+msgstr[1] "<strong>%1$s</strong> add-ons"
+
+#: views/addons/home.thtml:196
+#, fuzzy
+msgid "addons_home_collections_all"
+msgstr "View All Collections"
+
+#: views/addons/home.thtml:162
+#, fuzzy
+msgid "addons_home_collections_intro"
+msgstr ""
+"Collections are a way for you to categorize, mix, match and mingle add-ons. "
+"Subscribe to collections created by other users or create your own."
+
+#. %1$s is the count of subscribers for a collection
+#: views/elements/amo2009/collection_listing_item.thtml:58
+#: views/collections/detail.thtml:96 views/addons/home.thtml:189
+#, fuzzy
+msgid "addons_home_collections_subscribers"
+msgid_plural "addons_home_collections_subscribers"
+msgstr[0] "<strong>%1$s</strong> subscriber"
+msgstr[1] "<strong>%1$s</strong> subscribers"
+
+#: views/addons/searchengines.thtml:54 views/addons/themes_landing.thtml:49
+msgid "addons_home_feature_head"
+msgstr "Molaimid"
+
+#: controllers/search_controller.php:218 controllers/addons_controller.php:176
+#: controllers/addons_controller.php:428 controllers/addons_controller.php:671
+#: controllers/addons_controller.php:871
+#: controllers/addons_controller.php:1103
+#: controllers/addons_controller.php:1242
+#: controllers/addons_controller.php:1298
+#, php-format
+msgid "addons_home_header_details"
+msgstr ""
+"Le Breiseáin, is féidir do chuairt ar líne a shaincheapadh ar a lán bealaí. "
+"Breathnaigh thart agus cuir %1$s in oiriúint duit féin."
+
+#. %1$s is the HTML collection name link.
+#: views/elements/amo2009/teaser_collections.thtml:107
+#, fuzzy
+msgid "addons_home_introduction_collection_link"
+msgstr "Like these? Find more add-ons in %1$s."
+
+#: views/elements/amo2009/teaser_collections.thtml:60
+#, fuzzy
+msgid "addons_home_introduction_extras"
+msgstr ""
+"<strong>Over 5000 free extras</strong> that let you customize and extend "
+"Firefox to meet your needs."
+
+#: views/elements/amo2009/teaser_collections.thtml:55
+#, fuzzy
+msgid "addons_home_introduction_header"
+msgstr "What are Add-ons?"
+
+#: views/elements/amo2009/teaser_collections.thtml:72
+#, fuzzy
+msgid "addons_home_introduction_install"
+msgstr ""
+"<strong>Easy to install</strong>, get notified when updates are available."
+
+#: views/elements/amo2009/teaser_collections.thtml:45
+#, fuzzy
+msgid "addons_home_introduction_name"
+msgstr "Introduction"
+
+#: views/elements/amo2009/teaser_collections.thtml:66
+#, fuzzy
+msgid "addons_home_introduction_themes"
+msgstr ""
+"Toolbars, themes and search providers that <strong>help you perform common "
+"tasks.</strong>"
+
+#: views/addons/home.thtml:161
+#, fuzzy
+msgid "addons_home_new_indicator"
+msgstr "NEW!"
+
+#: views/elements/app_chooser.thtml:48 views/layouts/amo2009.thtml:257
+msgid "addons_home_other_applications"
+msgstr "Feidhmchláir Eile"
+
+#. %1$s is the application the user is browsing. Examples: Thunderbird, Firefox,
+#. Sunbird
+#: views/pages/collector_faq.thtml:49 views/pages/collector_firstrun.thtml:42
+#: views/pages/collector.thtml:46 views/pages/collector_features.thtml:54
+#: controllers/developers_controller.php:87
+#: controllers/compatibility_controller.php:72
+#: controllers/components/simple_acl.php:81 controllers/components/amo.php:607
+#: controllers/statistics_controller.php:60
+#: controllers/statistics_controller.php:240
+#: controllers/previews_controller.php:67 controllers/users_controller.php:90
+#: controllers/users_controller.php:223 controllers/users_controller.php:330
+#: controllers/users_controller.php:414 controllers/users_controller.php:708
+#: controllers/users_controller.php:723 controllers/reviews_controller.php:204
+#: controllers/reviews_controller.php:251
+#: controllers/reviews_controller.php:346
+#: controllers/reviews_controller.php:425
+#: controllers/search_controller.php:185 controllers/search_controller.php:297
+#: controllers/search_controller.php:301 controllers/addons_controller.php:147
+#: controllers/addons_controller.php:280 controllers/addons_controller.php:370
+#: controllers/addons_controller.php:667 controllers/addons_controller.php:874
+#: controllers/addons_controller.php:1019
+#: controllers/addons_controller.php:1034
+#: controllers/addons_controller.php:1101
+#: controllers/addons_controller.php:1121
+#: controllers/addons_controller.php:1240
+#: controllers/addons_controller.php:1357
+#: controllers/addons_controller.php:1364
+#: controllers/addons_controller.php:1442
+#: controllers/addons_controller.php:1477
+#: controllers/addons_controller.php:1538
+#: controllers/addons_controller.php:1543
+#: controllers/editors_controller.php:64 controllers/pages_controller.php:132
+#: controllers/groups_controller.php:65 controllers/groups_controller.php:71
+#: controllers/groups_controller.php:89 controllers/groups_controller.php:111
+#: controllers/collections_controller.php:57
+#: controllers/collections_controller.php:121
+#: controllers/collections_controller.php:205
+#: controllers/collections_controller.php:365
+#: controllers/collections_controller.php:404
+#: controllers/collections_controller.php:466
+#: controllers/collections_controller.php:538
+#: controllers/collections_controller.php:828
+#: controllers/localizers_controller.php:72
+#, php-format
+msgid "addons_home_pagetitle"
+msgstr "Breiseáin %1$s"
+
+#. %1$s is the number of addons downloaded
+#: views/addons/home.thtml:57
+#, fuzzy, php-format
+msgid "addons_home_stats_downloaded"
+msgid_plural "addons_home_stats_downloaded"
+msgstr[0] "<strong>%1$s</strong> <span>add-on downloaded</span>"
+msgstr[1] "<strong>%1$s</strong> <span>add-ons downloaded</span>"
+
+#. %1$s is the number of addons in use
+#: views/addons/home.thtml:63
+#, fuzzy, php-format
+msgid "addons_home_stats_inuse"
+msgid_plural "addons_home_stats_inuse"
+msgstr[0] "<strong>%1$s</strong> <span>add-on in use</span>"
+msgstr[1] "<strong>%1$s</strong> <span>add-ons in use</span>"
+
+#: views/addons/home.thtml:136
+msgid "addons_home_view_all_newest_title"
+msgstr "Féach ar na breiseáin is nuaí"
+
+#: views/addons/home.thtml:129
+msgid "addons_home_view_all_popular_title"
+msgstr "Taispeáin na breiseáin is mó éilimh orthu"
+
+#: views/addons/home.thtml:150
+msgid "addons_home_view_all_recommended_title"
+msgstr "Amharc ar gach breiseán molta"
+
+#: views/addons/home.thtml:143
+msgid "addons_home_view_all_updated_title"
+msgstr "Féach ar na breiseáin nuashonraithe le déanaí"
+
+#: views/elements/amo2009/install.thtml:334 views/elements/install.thtml:112
+msgid "addons_install_in_sunbird"
+msgstr ""
+"<ol><li>Cliceáil an nasc thíos chun an comhad a shábháil.</li><li>I Mozilla "
+"Sunbird, oscail Breiseáin ón roghchlár Uirlisí.</li><li>Cliceáil an cnaipe "
+"Suiteáil, aimsigh/roghnaigh an comhad a d'íosluchtaigh tú, agus cliceáil \"OK"
+"\".</li></ol>"
+
+#: views/elements/amo2009/install.thtml:333 views/elements/install.thtml:111
+msgid "addons_install_in_sunbird_title"
+msgstr "Conas is féidir suiteáil in Sunbird"
+
+#: views/elements/amo2009/install.thtml:331 views/elements/install.thtml:106
+msgid "addons_install_in_thunderbird"
+msgstr ""
+"<ol><li>Deaschliceáil an nasc thíos agus roghnaigh \"Sábháil Nasc Mar...\" "
+"chun an comhad a íosluchtú agus a shábháil ar do dhiosca crua.</li><li>Ó "
+"Thunderbird, oscail Breiseáin ón roghchlár Uirlisí.</li><li>Cliceáil an "
+"cnaipe Suiteáil, roghnaigh an comhad a d'íosluchtaigh tú, agus cliceáil \"OK"
+"\".</li></ol>"
+
+#: views/elements/amo2009/install.thtml:330 views/elements/install.thtml:105
+msgid "addons_install_in_thunderbird_title"
+msgstr "Conas is féidir suiteáil in Thunderbird"
+
+#: views/elements/amo2009/addon_list_options.thtml:108
+#: views/elements/addon_list_options.thtml:105
+msgid "addons_options_show_experimental"
+msgstr "taispeáin breiseáin thurgnamhacha"
+
+#: views/elements/amo2009/addon_list_options.thtml:113
+#: views/elements/addon_list_options.thtml:109
+msgid "addons_options_submit"
+msgstr "Téigh"
+
+#: views/addons/plugins.thtml:63 views/addons/plugins.thtml:73
+#: views/addons/plugins.thtml:83 views/addons/plugins.thtml:93
+#: views/addons/plugins.thtml:103 views/addons/plugins.thtml:116
+#: views/addons/plugins.thtml:126
+msgid "addons_plugins_by"
+msgstr "Le"
+
+#: views/addons/plugins.thtml:107
+msgid "addons_plugins_for_linux"
+msgstr "le haghaidh Linux"
+
+#: views/addons/plugins.thtml:108 views/addons/plugins.thtml:131
+msgid "addons_plugins_for_macosx"
+msgstr "le haghaidh Mac OS X"
+
+#: views/addons/plugins.thtml:106 views/addons/plugins.thtml:129
+#: views/addons/plugins.thtml:130
+msgid "addons_plugins_for_windows"
+msgstr "le haghaidh Windows"
+
+#. %1$s is a URL
+#: views/addons/plugins.thtml:139
+#, php-format
+msgid "addons_plugins_looking_for_more"
+msgstr ""
+"Taispeántar ar an leathanach seo na forlíontáin is coitianta agus is mó "
+"éilimh orthu. Le tuilleadh eolais a fháil maidir le forlíontáin eile le "
+"haghaidh Brabhsálaithe Mozilla, déan cuairt ar %1$s"
+
+#: views/addons/plugins.thtml:137
+msgid "addons_plugins_looking_for_plugin"
+msgstr "An bhfuil tú ag lorg forlíontán nach bhfuil anseo?"
+
+#: views/addons/plugins.thtml:58
+msgid "addons_plugins_main_description"
+msgstr ""
+"Cabhraíonn forlíontáin le do bhrabhsálaí feidhmeanna ar leith a dhéanamh, "
+"mar shampla formáidí speisialta grafacha a léamh nó comhaid ilmheán a "
+"sheinm. Ní ionann forlíontáin agus 'eisínteachtaí', cláir a athraíonn nó a "
+"fheabhsaíonn feidhmiúlacht atá ann cheana."
+
+#. %1$s is the application name. Example: Firefox, Thunderbird, Sunbird
+#: controllers/addons_controller.php:1122
+#, php-format
+msgid "addons_plugins_main_header"
+msgstr "Forlíontáin Choitianta le haghaidh %1$s"
+
+#: controllers/components/amo.php:698 controllers/addons_controller.php:1121
+msgid "addons_plugins_pagetitle"
+msgstr "Forlíontáin"
+
+#: views/addons/plugins.thtml:68 views/addons/plugins.thtml:78
+#: views/addons/plugins.thtml:88 views/addons/plugins.thtml:98
+#: views/addons/plugins.thtml:110 views/addons/plugins.thtml:121
+#: views/addons/plugins.thtml:133
+msgid "addons_plugins_support_documentation"
+msgstr "Doiciméadú: "
+
+#. %s is the name of the add-on
+#: views/addons/policy.thtml:61
+#, php-format
+msgid "addons_policy_eula_require"
+msgstr ""
+"Éilíonn %s go nglacfá leis an gComhaontú Ceadúnas Bogearra seo sular féidir "
+"dul ar aghaidh leis an tsuiteáil:"
+
+# %1 is the addon name
+#. %1 is the add-on name
+#: controllers/addons_controller.php:1476
+#, php-format
+msgid "addons_previews_pagetitle"
+msgstr "Réamhamhairc at %s"
+
+#: views/addons/category_landing.thtml:135
+#, fuzzy
+msgid "addons_recently_added"
+msgstr "Recently Added"
+
+#: views/addons/recommended.thtml:51 controllers/addons_controller.php:1365
+msgid "addons_recommended_introduction"
+msgstr ""
+"Tá a lán breiseán iontach ar fáil, agus seans maith go mbeidh rud éigin ann "
+"a bhfuil suim agat ann. Seo duit liosta de na breiseáin is mó éilimh "
+"orthu. Bain sult as!"
+
+#: controllers/addons_controller.php:1357
+#: controllers/addons_controller.php:1364
+msgid "addons_recommended_pagetitle"
+msgstr "Breiseáin Mholta"
+
+#: controllers/addons_controller.php:1360
+msgid "addons_recommended_title"
+msgstr "Breiseáin Mholta"
+
+#: views/addons/searchengines.thtml:136
+msgid "addons_searchengines_additional_resources"
+msgstr "Acmhainní Eile"
+
+# link text devmo
+#. link text devmo
+#: views/addons/searchengines.thtml:141
+msgid "addons_searchengines_devmo_link"
+msgstr "Lárionad Forbartha Mozilla"
+
+#: views/pages/js_constants.js.thtml:67
+msgid "addons_searchengines_error_mozilla_browser_required"
+msgstr ""
+"Ní mór duit brabhsálaí Mozilla (mar shampla Firefox) a úsáid chun forlíontán "
+"cuardaigh a shuiteáil."
+
+#: views/addons/searchengines.thtml:49
+msgid "addons_searchengines_error_nojavascript"
+msgstr ""
+"Tá JavaScript de dhíth chun forlíontáin a shuiteáil, agus tá sé "
+"díchumasaithe agat de réir cosúlachta. Ba chóir duit JavaScript a chumasú "
+"sula ndéanfaidh tú iarracht eile aon cheann de na forlíontáin chuardaigh "
+"thíos a shuiteáil."
+
+# %1 is "make your own" link
+# %2 is MDC link
+#. %1 is "make your own" link
+#. %2 is MDC link
+#: views/addons/searchengines.thtml:139
+msgid "addons_searchengines_learn_howto"
+msgstr "Foghlaim conas is féidir %1$s ag %2$s."
+
+# link path to search plugins instructions, relative to devmo
+#. link path to search plugins instructions, relative to devmo
+#: views/addons/searchengines.thtml:140
+msgid "addons_searchengines_makeyourown_href"
+msgstr "/en/docs/Creating_OpenSearch_plugins_for_Firefox"
+
+# link text for "make your own" (opensearch engine)
+#. link text for "make your own" (opensearch engine)
+#: views/addons/searchengines.thtml:140
+msgid "addons_searchengines_makeyourown_link"
+msgstr "do bhreiseán féin a dhéanamh"
+
+# %1 is the link to mycroft.mozdev.org
+#. %1 is the link to mycroft.mozdev.org
+#: views/addons/searchengines.thtml:138
+msgid "addons_searchengines_more"
+msgstr "Brabhsáil tuilleadh inneall cuardaigh ag %1$s"
+
+# link text to mycroft.mozdev.org
+#. link text to mycroft.mozdev.org
+#: views/addons/searchengines.thtml:138
+msgid "addons_searchengines_mycroft_link"
+msgstr "mycroft.mozdev.org"
+
+#: controllers/addons_controller.php:1100
+#: controllers/addons_controller.php:1110
+msgid "addons_searchengines_pagetitle"
+msgstr "Innill Chuardaigh"
+
+#: views/addons/searchengines.thtml:143
+msgid "addons_searchengines_thanks"
+msgstr ""
+"Táimid an-bhuíoch den Tionscadal Mycroft as a gcuid oibre go léir ar Innill "
+"Chuardaigh Firefox."
+
+#: views/addons/display.thtml:154
+msgid "addons_share_button_text"
+msgstr "Comhroinn é seo"
+
+#: controllers/addons_controller.php:89
+msgid "addons_share_label_delicious"
+msgstr "Cuir le Delicious"
+
+#: controllers/addons_controller.php:77
+msgid "addons_share_label_digg"
+msgstr "Digg é seo!"
+
+#: controllers/addons_controller.php:83
+msgid "addons_share_label_facebook"
+msgstr "Cuir le Facebook"
+
+#: controllers/addons_controller.php:101
+msgid "addons_share_label_friendfeed"
+msgstr "Comhroinn ar FriendFeed"
+
+#: controllers/addons_controller.php:95
+msgid "addons_share_label_myspace"
+msgstr "Cuir le MySpace"
+
+#: controllers/components/amo.php:201 controllers/components/amo.php:229
+msgid "addons_status_disabled"
+msgstr "Díchumasaithe"
+
+#: controllers/components/amo.php:191 controllers/components/amo.php:224
+msgid "addons_status_incomplete"
+msgstr "Leagan Neamhiomlán"
+
+#: controllers/components/amo.php:197 controllers/components/amo.php:227
+msgid "addons_status_nominated"
+msgstr "Sa Bhosca Gainimh; Ainmniú Poiblí"
+
+#: views/pages/js_constants.js.thtml:80 controllers/components/amo.php:195
+#: controllers/components/amo.php:226
+msgid "addons_status_pending"
+msgstr "Sa Bhosca Gainimh; ag fanacht le heagarthóir"
+
+#: views/pages/js_constants.js.thtml:78 controllers/components/amo.php:199
+#: controllers/components/amo.php:228
+msgid "addons_status_public"
+msgstr "Poiblí"
+
+#: views/pages/js_constants.js.thtml:79 controllers/components/amo.php:193
+#: controllers/components/amo.php:225
+msgid "addons_status_sandbox"
+msgstr "Sa Bhosca Gainimh"
+
+#: controllers/components/amo.php:203
+msgid "addons_status_unknown"
+msgstr "Anaithnid"
+
+#: views/elements/amo2009/teaser_collections.thtml:91
+#: views/elements/amo2009/homepage_addon.thtml:99
+#: views/elements/feature.thtml:94
+msgid "addons_title_tooltip"
+msgstr "Tuilleadh eolais faoin bhreiseán seo"
+
+#: views/addons/category_landing.thtml:151
+#, fuzzy
+msgid "addons_top_downloads"
+msgstr "Top Downloads"
+
+#: views/addons/category_landing.thtml:165
+#, fuzzy
+msgid "addons_top_rated"
+msgstr "Top Rated"
+
+#: views/addons/versions.thtml:62
+msgid "addons_versions_careful"
+msgstr "Bí Cúramach le Seanleaganacha"
+
+#: views/addons/versions.thtml:63
+msgid "addons_versions_careful_introduction"
+msgstr ""
+"Taispeántar na leaganacha seo le haghaidh tagartha agus tástála. Ba chóir "
+"duit an leagan is déanaí den bhreiseán a úsáid i gcónaí."
+
+#: controllers/addons_controller.php:1549
+msgid "addons_versions_history"
+msgstr "Stair na Leaganacha le Logchomhaid Athruithe"
+
+#. %1$s is the add-on name
+#: controllers/addons_controller.php:1535
+#, php-format
+msgid "addons_versions_pagetitle"
+msgstr "Stair na Leaganacha %1$s"
+
+#: controllers/groups_controller.php:71
+msgid "admin_group_add_pagetitle"
+msgstr "Cuir Grúpa Leis"
+
+#: controllers/groups_controller.php:111
+msgid "admin_group_delete_pagetitle"
+msgstr "Scrios Grúpa"
+
+#. %s is a number to identify the group
+#: controllers/groups_controller.php:117
+#, php-format
+msgid "admin_group_deleted"
+msgstr "Scriosadh an Grúpa le haitheantas %s"
+
+#: controllers/groups_controller.php:89
+msgid "admin_group_edit_pagetitle"
+msgstr "Cuir Grúpa in Eagar"
+
+#: controllers/groups_controller.php:92 controllers/groups_controller.php:113
+msgid "admin_group_error_invalid_id"
+msgstr "Aitheantas Neamhbhailí ar Ghrúpa"
+
+#: controllers/groups_controller.php:65
+msgid "admin_group_pagetitle"
+msgstr "Riarthóir an Ghrúpa"
+
+#: controllers/groups_controller.php:77 controllers/groups_controller.php:99
+msgid "admin_group_saved"
+msgstr "Sábháladh an Grúpa"
+
+#: views/elements/amo2009/search.thtml:257 views/elements/search.thtml:239
+msgid "advanced_search_form"
+msgstr "Cuardach Casta"
+
+#: views/elements/amo2009/search.thtml:126 views/elements/search.thtml:125
+msgid "advanced_search_form_any_time"
+msgstr "Am ar bith"
+
+#: views/elements/amo2009/search.thtml:97
+#: views/elements/amo2009/search.thtml:110 views/elements/search.thtml:96
+#: views/elements/search.thtml:109
+msgid "advanced_search_form_any_type"
+msgstr "Cineál ar bith"
+
+#: views/elements/amo2009/search.thtml:275 views/elements/search.thtml:254
+msgid "advanced_search_form_any_version"
+msgstr "Leagan ar bith"
+
+#: views/elements/amo2009/search.thtml:217 views/elements/search.thtml:212
+msgid "advanced_search_form_application"
+msgstr "Feidhmchlár"
+
+#: views/elements/amo2009/search.thtml:143 views/elements/search.thtml:142
+msgid "advanced_search_form_keyword_match"
+msgstr "Comhoiriúnacht Eochairfhocal"
+
+#: views/elements/amo2009/search.thtml:251 views/elements/search.thtml:225
+msgid "advanced_search_form_lastupdate"
+msgstr "Nuashonraithe"
+
+#: views/elements/amo2009/search.thtml:145 views/elements/search.thtml:144
+msgid "advanced_search_form_name"
+msgstr "Ainm"
+
+# "sort by"
+#: views/elements/amo2009/search.thtml:144 views/elements/search.thtml:143
+msgid "advanced_search_form_newest"
+msgstr "Dáta"
+
+#: views/elements/amo2009/search.thtml:130 views/elements/search.thtml:129
+msgid "advanced_search_form_past_3_months"
+msgstr "3 mhí is déanaí"
+
+#: views/elements/amo2009/search.thtml:131 views/elements/search.thtml:130
+msgid "advanced_search_form_past_6_months"
+msgstr "6 mhí is déanaí"
+
+#: views/elements/amo2009/search.thtml:127 views/elements/search.thtml:126
+msgid "advanced_search_form_past_day"
+msgstr "An lá is déanaí"
+
+#: views/elements/amo2009/search.thtml:129 views/elements/search.thtml:128
+msgid "advanced_search_form_past_month"
+msgstr "An mhí is déanaí"
+
+#: views/elements/amo2009/search.thtml:128 views/elements/search.thtml:127
+msgid "advanced_search_form_past_week"
+msgstr "An tseachtain is déanaí"
+
+#: views/elements/amo2009/search.thtml:132 views/elements/search.thtml:131
+msgid "advanced_search_form_past_year"
+msgstr "An bhliain is déanaí"
+
+#: views/elements/amo2009/search.thtml:239 views/elements/search.thtml:230
+msgid "advanced_search_form_perpage"
+msgstr "Gach Leathanach"
+
+#: views/elements/amo2009/search.thtml:243 views/elements/search.thtml:224
+msgid "advanced_search_form_platform"
+msgstr "Ardán"
+
+#: views/elements/amo2009/search.thtml:147 views/elements/search.thtml:146
+msgid "advanced_search_form_popularity"
+msgstr "Éileamh"
+
+#: views/elements/amo2009/search.thtml:146 views/elements/search.thtml:145
+msgid "advanced_search_form_rating"
+msgstr "Rátáil"
+
+#: views/elements/amo2009/search.thtml:247 views/elements/search.thtml:231
+msgid "advanced_search_form_sortby"
+msgstr "Sórtáil De Réir"
+
+#: views/elements/amo2009/search.thtml:227 views/elements/search.thtml:216
+msgid "advanced_search_form_to"
+msgstr "go"
+
+#: views/elements/amo2009/search.thtml:257 views/elements/search.thtml:237
+msgid "advanced_search_form_toggle_tooltip"
+msgstr "Scoránaigh cuardach casta"
+
+#: views/elements/amo2009/search.thtml:235 views/elements/search.thtml:223
+msgid "advanced_search_form_type"
+msgstr "Cineál"
+
+#: views/elements/amo2009/search.thtml:222 views/elements/search.thtml:214
+msgid "advanced_search_form_version"
+msgstr "leagan"
+
+#: views/elements/amo2009/pagination.thtml:42
+#, fuzzy
+msgid "amo2009_pagination_next_page"
+msgstr "Next"
+
+#: views/elements/amo2009/pagination.thtml:41
+#, fuzzy
+msgid "amo2009_pagination_previous_page"
+msgstr "Prev"
+
+#: views/pages/js_constants.js.thtml:96
+msgid "app_compat_ignore_check"
+msgstr "Déan neamhaird ar chinntiú an leagain"
+
+#: views/pages/js_constants.js.thtml:72
+msgid "app_compat_older_firefox_only"
+msgstr "Úsáidtear an breiseán seo le leaganacha níos sine de Firefox"
+
+#. %1$s and %2$s are URLs
+#: views/pages/js_constants.js.thtml:74
+msgid "app_compat_older_version_or_ignore_check"
+msgstr ""
+"Is féidir leat triail a bhaint as <a href=\"%1$s\">leagan níos sine</a> nó "
+"<a href=\"#\" onclick=\"%2$s\">déan neamhaird ar an deimhniú seo</a>"
+
+#. %1$s is a URL
+#: views/pages/js_constants.js.thtml:71
+msgid "app_compat_try_old_version"
+msgstr "Seans go n-oibreodh <a href=\"%1$s\">leagan níos sine</a>"
+
+#. %1$s is a URL
+#. %2$s is a version number. Example: 3.1
+#: views/pages/js_constants.js.thtml:73
+msgid "app_compat_unreleased_version"
+msgstr ""
+"Tá <a href=\"%1$s\">Firefox %2$s</a> de dhíth ar an mbreiseán seo ach níl sé "
+"ar fáil fós"
+
+#: views/pages/js_constants.js.thtml:70
+msgid "app_compat_update_firefox"
+msgstr ""
+"<a href=\"http://getfirefox.com\">Nuashonraigh Firefox</a> chun an breiseán "
+"seo a úsáid"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#. %3$s is a status, like Public.
+#: controllers/components/audit.php:79
+#, fuzzy
+msgid "audit_addon_status"
+msgstr "%1$s changed the status of %2$s to %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:221
+#, fuzzy
+msgid "audit_admin_default"
+msgstr "%1$s committed unknown admin action %2$s to ID %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:153
+#, fuzzy
+msgid "audit_admin_feature_remove"
+msgstr "%1$s removed feature %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is an application, like Firefox.
+#: controllers/components/audit.php:92
+#, fuzzy
+msgid "audit_application_create"
+msgstr "%1$s created application %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is an application, like Firefox.
+#: controllers/components/audit.php:95
+#, fuzzy
+msgid "audit_application_edit"
+msgstr "%1$s edited application %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a version number, like 3.5.
+#. %3$s is an application, like Firefox.
+#: controllers/components/audit.php:105
+#, fuzzy
+msgid "audit_appversion_create"
+msgstr "%1$s created version %2$s for %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a version number, like 3.5.
+#. %3$s is an application, like Firefox.
+#: controllers/components/audit.php:108
+#, fuzzy
+msgid "audit_appversion_delete"
+msgstr "%1$s deleted version %2$s for %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a config field, like "awesomeness".
+#. %3$s is a config value, like "off".
+#. %4$s is a config value, like "on".
+#: controllers/components/audit.php:210
+#, fuzzy
+msgid "audit_config"
+msgstr "%1$s changed config '%2$s' from '%3$s' to '%4$s'"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:258
+#, fuzzy
+msgid "audit_editor_default"
+msgstr "%1$s committed unknown editor action %2$s to ID %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#: controllers/components/audit.php:236
+#, fuzzy
+msgid "audit_editor_feature_remove"
+msgstr "%1$s removed addon %2$s from feature list"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#: controllers/components/audit.php:231
+#, fuzzy
+msgid "audit_feature_add"
+msgstr "%1$s added addon %2$s to feature list"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:149
+#, fuzzy
+msgid "audit_feature_edit"
+msgstr "%1$s changed a feature for %2$s locale"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#: controllers/components/audit.php:241
+#, fuzzy
+msgid "audit_feature_locale_change"
+msgstr "%1$s changed locales for addon %2$s on feature list"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:83
+#, fuzzy
+msgid "audit_file_recalchash"
+msgstr "%1$s recalculated the hash for file %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>user name</a>
+#. %3$s is <a>group name</a>
+#: controllers/components/audit.php:182
+#, fuzzy
+msgid "audit_group_addmember"
+msgstr "%1$s added %2$s to group %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:313
+#, fuzzy
+msgid "audit_group_associated"
+msgstr "%1$s associated themselves with %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:162
+#, fuzzy
+msgid "audit_group_create"
+msgstr "%1s created group %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:170
+#, fuzzy
+msgid "audit_group_delete"
+msgstr "%1$s deleted group %2$s (ID %3$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:165
+#, fuzzy
+msgid "audit_group_edit"
+msgstr "%1$s edited group %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>user name</a>
+#. %3$s is <a>group name</a>
+#: controllers/components/audit.php:188
+#, fuzzy
+msgid "audit_group_removemember"
+msgstr "%1$s removed %2$s from group %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:280
+#, fuzzy
+msgid "audit_l10n_default"
+msgstr "%1$s committed unknown action %2$s for %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:295
+#, fuzzy
+msgid "audit_modify_locked_group"
+msgstr "%1$s attempted to modify locked group %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:299
+#, fuzzy
+msgid "audit_modify_other_locale"
+msgstr "%1$s attempted to modify translations in %2$s without permission"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a platform, like <a>Windows</a>
+#: controllers/components/audit.php:135
+#, fuzzy
+msgid "audit_platform_create"
+msgstr "%1$s created platform %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a platform, like <a>Windows</a>
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:143
+#, fuzzy
+msgid "audit_platform_delete"
+msgstr "%1$s deleted platform %2$s (ID %3$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a platform, like <a>Windows</a>
+#: controllers/components/audit.php:138
+#, fuzzy
+msgid "audit_platform_edit"
+msgstr "%1$s edited platform %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a part of the admin, like 'Site Config'
+#: controllers/components/audit.php:288
+#, fuzzy
+msgid "audit_reauthentication_failure"
+msgstr "%1$s failed to re-authenticate to access %2$s."
+
+#. %1$s is <a>user name</a>
+#. %2$s is the name of a canned response, like 'Ready for the public'
+#: controllers/components/audit.php:198
+#, fuzzy
+msgid "audit_response_create"
+msgstr "%1$s created response %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is the name of a canned response, like 'Ready for the public'
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:206
+#, fuzzy
+msgid "audit_response_delete"
+msgstr "%1$s deleted response %2$s (ID %3$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is the name of a canned response, like 'Ready for the public'
+#: controllers/components/audit.php:201
+#, fuzzy
+msgid "audit_response_edit"
+msgstr "%1$s edited response %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:245
+#, fuzzy
+msgid "audit_review_approve"
+msgstr "%1$s approved review %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:250 controllers/components/audit.php:253
+#, fuzzy
+msgid "audit_review_delete"
+msgstr "%1$s deleted review %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:303
+#, fuzzy
+msgid "audit_security_default"
+msgstr "%1$s committed unknown security action %2$s to ID %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a category name, like <a>Search Tools</a>
+#: controllers/components/audit.php:118
+#, fuzzy
+msgid "audit_tag_create"
+msgstr "%1$s created tag %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a category name, like <a>Search Tools</a>
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:126
+#, fuzzy
+msgid "audit_tag_delete"
+msgstr "%1$s deleted category %2$s (ID %3$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a category name, like <a>Search Tools</a>
+#: controllers/components/audit.php:121
+#, fuzzy
+msgid "audit_tag_edit"
+msgstr "%1$s edited category %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:266
+#, fuzzy
+msgid "audit_update_applications"
+msgstr "%1$s updated application translations for %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:277
+#, fuzzy
+msgid "audit_update_blog"
+msgstr "%1$s updated blog post translations for %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:274
+#, fuzzy
+msgid "audit_update_platforms"
+msgstr "%1$s updated platform translations for %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:270
+#, fuzzy
+msgid "audit_update_tags"
+msgstr "%1$s updated category translations for %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>user name</a>
+#: controllers/components/audit.php:217
+#, fuzzy
+msgid "audit_user_edit"
+msgstr "%1$s edited %2$s's user information"
+
+#: controllers/addons_controller.php:1012
+msgid "browse_addons_name"
+msgstr "Breiseáin de réir Ainm"
+
+#: controllers/addons_controller.php:1010
+msgid "browse_addons_newest"
+msgstr "Breiseáin Is Nuaí"
+
+#: controllers/addons_controller.php:1008
+msgid "browse_addons_popular"
+msgstr "Breiseáin is mó éilimh orthu"
+
+#: controllers/addons_controller.php:1011
+msgid "browse_addons_rated"
+msgstr "Breiseáin de réir Rátála"
+
+#: controllers/addons_controller.php:1009
+msgid "browse_addons_updated"
+msgstr "Breiseáin Nuashonraithe Le Déanaí"
+
+#: views/elements/categories.thtml:73 views/elements/categories.thtml:82
+msgid "categories_current_title"
+msgstr "Catagóir Reatha"
+
+#: views/elements/categories.thtml:50
+#: views/elements/amo2009/categories.thtml:43
+#: views/elements/amo2009/categories.thtml:45
+msgid "categories_header"
+msgstr "Catagóirí"
+
+#: views/elements/categories.thtml:50
+#: views/elements/amo2009/categories.thtml:41
+msgid "categories_header_title"
+msgstr "Roghnaigh catagóir"
+
+# %1 is the category name
+# Generall speaking it will be plural, so "Taispeáin Gach %1" doesn't cut it.
+#. %1$s is the category name
+#: views/addons/searchengines.thtml:129
+#, php-format
+msgid "category_extra_see_all"
+msgstr "Taispeáin na %1$s go léir"
+
+#. %1$s is a number.
+#: models/collection.php:130
+#, fuzzy
+msgid "collection_description_limit"
+msgstr "The description should be less than %1$s characters."
+
+#. %1$s is the name of the collection
+#: controllers/collections_controller.php:392
+#, fuzzy
+msgid "collection_detail_rss_title"
+msgstr "%s Collection"
+
+#: controllers/collections_controller.php:1065
+#, fuzzy
+msgid "collection_error_deleting_addon"
+msgstr "Error deleting add-on!"
+
+#: controllers/collections_controller.php:1051
+#, fuzzy
+msgid "collection_error_saving_addon"
+msgstr "Error saving add-on!"
+
+#: controllers/collections_controller.php:1080
+#, fuzzy
+msgid "collection_error_saving_comment"
+msgstr "Error saving comment!"
+
+#. %1$s is a number.
+#: models/collection.php:122
+#, fuzzy
+msgid "collection_name_limit"
+msgstr "The name should be less than %1$s characters."
+
+#: controllers/collections_controller.php:352
+#: controllers/collections_controller.php:487
+msgid "collection_not_found"
+msgstr "Bailiúchán gan aimsiú!"
+
+#. %1$s is the text on the "create collection" button
+#: views/collections/add.thtml:91
+#, fuzzy
+msgid "collections_add_formfield_addons_description"
+msgstr ""
+"If you already know which add-ons you want to add to your collection, just "
+"start typing their names below. If you'd rather wait and do this later, just "
+"click %1$s now."
+
+#: views/collections/add.thtml:90
+#, fuzzy
+msgid "collections_add_formfield_firstaddons"
+msgstr "Choose your first add-ons"
+
+#: views/collections/add.thtml:48
+#, fuzzy
+msgid "collections_add_header"
+msgstr "Create a Collection"
+
+#: views/collections/add.thtml:97
+#, fuzzy
+msgid "collections_add_header_selectedaddons"
+msgstr "Selected Add-ons"
+
+#: views/collections/add.thtml:50
+#, fuzzy
+msgid "collections_add_intro"
+msgstr ""
+"It's easy to create your own collection of add-ons by filling in a few "
+"fields below."
+
+#: views/collections/add.thtml:92 views/collections/add.thtml:103
+#, fuzzy
+msgid "collections_add_submit"
+msgstr "Create Collection"
+
+#: views/pages/collector_faq.thtml:50 views/pages/collector_firstrun.thtml:43
+#: views/pages/collector.thtml:47 views/pages/collector_features.thtml:55
+#: controllers/search_controller.php:302
+#: controllers/collections_controller.php:206
+#: controllers/collections_controller.php:405
+#: controllers/collections_controller.php:467
+#: controllers/collections_controller.php:539
+#, fuzzy
+msgid "collections_breadcrumb"
+msgstr "Collections"
+
+#: views/collections/detail.thtml:185
+#, fuzzy
+msgid "collections_detail_a_learn"
+msgstr "Learn More"
+
+#: views/elements/amo2009/collection_add_form.thtml:53
+#: views/elements/amo2009/collections_js_init.thtml:68
+#: views/pages/collector_firstrun.thtml:64
+#, fuzzy
+msgid "collections_detail_button_add"
+msgstr "Add to Favorites"
+
+#: views/elements/amo2009/collection_add_form.thtml:50
+#: views/elements/amo2009/collections_js_init.thtml:71
+#, fuzzy
+msgid "collections_detail_button_remove"
+msgstr "Remove from Favorites"
+
+#. %1$s is a URL.
+#. %2$s is a full <a href>.
+#: views/collections/detail.thtml:62
+#, fuzzy
+msgid "collections_detail_created_desc"
+msgstr ""
+"<p>You can view your new collection below. If you'd like to set a collection "
+"nickname, upload an icon, or change additional settings, please visit the <a "
+"href='%1$s'>Manage Collections</a> page.</p><p>Your collection can be "
+"accessed at this location: %2$s</p>"
+
+#: views/collections/detail.thtml:61
+#, fuzzy
+msgid "collections_detail_created_msg"
+msgstr "Your collection is now ready!"
+
+#: views/collections/detail.thtml:109
+#, fuzzy
+msgid "collections_detail_header_about"
+msgstr "About This Collection"
+
+#. %1$s is a number.
+#: views/collections/detail.thtml:126
+#, fuzzy
+msgid "collections_detail_header_count"
+msgid_plural "collections_detail_header_count"
+msgstr[0] "%1$s Add-on in this Collection"
+msgstr[1] "%1$s Add-ons in this Collection"
+
+#: views/collections/detail.thtml:113
+#, fuzzy
+msgid "collections_detail_info_created"
+msgstr "<strong>Created by:</strong> %1$s"
+
+#: views/collections/detail.thtml:117
+#, fuzzy
+msgid "collections_detail_info_updated"
+msgstr "<strong>Updated:</strong>"
+
+#: views/elements/amo2009/collections_js_init.thtml:62
+#, fuzzy
+msgid "collections_detail_js_adding"
+msgstr "Adding to Favorites&hellip;"
+
+#: views/elements/amo2009/collections_js_init.thtml:65
+#, fuzzy
+msgid "collections_detail_js_removing"
+msgstr "Removing Favorite&hellip;"
+
+#. %1$s is a URL
+#: views/collections/detail.thtml:90
+#, fuzzy
+msgid "collections_detail_login"
+msgstr "<a href=\"%1$s\">Log in</a> to add this collection to your favorites."
+
+#: views/collections/detail.thtml:104
+#, fuzzy
+msgid "collections_detail_manage"
+msgstr "Manage Collection"
+
+#: controllers/collections_controller.php:298
+#, fuzzy
+msgid "collections_detail_sort_date"
+msgstr "Date Added"
+
+#: controllers/collections_controller.php:299
+#, fuzzy
+msgid "collections_detail_sort_name"
+msgstr "Name"
+
+#: controllers/collections_controller.php:300
+#, fuzzy
+msgid "collections_detail_sort_popularity"
+msgstr "Popularity"
+
+#. %1$s is a number.
+#: views/collections/detail.thtml:166
+#, fuzzy
+msgid "collections_detail_weekly_downloads"
+msgid_plural "collections_detail_weekly_downloads"
+msgstr[0] "%1$s download this week"
+msgstr[1] "%1$s downloads this week"
+
+#: views/collections/edit.thtml:255
+#, fuzzy
+msgid "collections_edit_addons_delete_noscript"
+msgstr "Selected add-ons will be removed upon Save"
+
+#: views/collections/edit.thtml:247
+#, fuzzy
+msgid "collections_edit_addons_description"
+msgstr ""
+"To publish new add-ons to this collection, start typing their names below."
+
+#: views/collections/edit.thtml:248
+#, fuzzy
+msgid "collections_edit_addons_description_noscript"
+msgstr ""
+"To publish new add-ons to this collection, enter a comma-separated list of "
+"Add-on IDs below."
+
+#: views/collections/edit.thtml:247 views/collections/edit.thtml:248
+#, fuzzy
+msgid "collections_edit_addons_description_publish_detailspage"
+msgstr "You can also publish an add-on from its normal listing page."
+
+#. %1$s is the date the add-on was added to the collection
+#. %1$s is the name of the user who added the add-on to the collection
+#: views/collections/edit.thtml:260
+#, fuzzy
+msgid "collections_edit_addons_listitem_added"
+msgstr "Added %1$s by %2$s"
+
+#: views/collections/edit.thtml:263
+#, fuzzy
+msgid "collections_edit_addons_listitem_comment_add"
+msgstr "Add publisher comment"
+
+#: views/collections/edit.thtml:266
+#, fuzzy
+msgid "collections_edit_addons_listitem_comment_delete"
+msgstr "Delete publisher comment"
+
+#: views/collections/edit.thtml:265
+#, fuzzy
+msgid "collections_edit_addons_listitem_comment_edit"
+msgstr "Edit publisher comment"
+
+#: views/collections/edit.thtml:271
+#, fuzzy
+msgid "collections_edit_addons_listitem_comment_note"
+msgstr ""
+"Note: Comment will appear as though written by original publisher on the "
+"original publication date"
+
+#: views/collections/edit.thtml:270
+#, fuzzy
+msgid "collections_edit_addons_listitem_comment_submit"
+msgstr "Save Comment"
+
+#: views/collections/edit.thtml:261
+#, fuzzy
+msgid "collections_edit_addons_listitem_remove"
+msgstr "Remove"
+
+#: views/collections/edit.thtml:250
+#, fuzzy
+msgid "collections_edit_addons_submit"
+msgstr "Add to Collection"
+
+#: views/collections/edit.thtml:153
+#, fuzzy
+msgid "collections_edit_check_nickname"
+msgstr "Check Availability"
+
+#: views/collections/edit.thtml:299
+#, fuzzy
+msgid "collections_edit_confirm_deletecollection"
+msgstr "Yes, I would like to delete this collection."
+
+#. %1$s is the label of the edit form's submit button
+#: views/collections/edit.thtml:300
+#, fuzzy
+msgid "collections_edit_confirm_deletecollection_description"
+msgstr "Check the box, then click on \"%1$s\" to delete this collection."
+
+#. %1$s is the "delete" submit button text
+#. %2$s is the title of the "advanced" tab
+#: views/collections/edit.thtml:95
+#, fuzzy
+msgid "collections_edit_delete_upon_submit"
+msgstr ""
+"Upon clicking \"%1$s\" below, your collection will be deleted. If you do not "
+"want to delete your collection, uncheck the confirmation box in the \"%2$s\" "
+"tab and continue editing your collection. If you leave this page without "
+"saving, your collection will also not be deleted."
+
+#: views/collections/edit.thtml:94
+#, fuzzy
+msgid "collections_edit_delete_warning"
+msgstr "Your collection is about to be deleted!"
+
+#: views/collections/add.thtml:76 views/collections/edit.thtml:144
+#, fuzzy
+msgid "collections_edit_form_error_description"
+msgstr "You must provide a description of your collection."
+
+#: views/collections/edit.thtml:181
+#, fuzzy
+msgid "collections_edit_form_error_icon"
+msgstr "There was an error uploading your icon."
+
+#: views/collections/add.thtml:69 views/collections/edit.thtml:130
+#, fuzzy
+msgid "collections_edit_form_error_name"
+msgstr "You must give your collection a name."
+
+#: views/collections/edit.thtml:158
+#, fuzzy
+msgid "collections_edit_form_error_nickname"
+msgstr "If you choose a nickname, it must be unique."
+
+#: views/collections/add.thtml:93 views/collections/edit.thtml:249
+#, fuzzy
+msgid "collections_edit_formfield_addons"
+msgstr "Add-on name:"
+
+#: views/collections/edit.thtml:281
+#, fuzzy
+msgid "collections_edit_formfield_application"
+msgstr "Associated Application"
+
+#: views/collections/edit.thtml:282
+#, fuzzy
+msgid "collections_edit_formfield_application_description"
+msgstr "Select the application that your collection supports."
+
+#: views/collections/edit.thtml:288
+#, fuzzy
+msgid "collections_edit_formfield_collectiontype"
+msgstr "Collection Type"
+
+#: views/collections/edit.thtml:295
+#, fuzzy
+msgid "collections_edit_formfield_deletecollection"
+msgstr "Delete Collection"
+
+#: views/collections/edit.thtml:296
+#, fuzzy
+msgid "collections_edit_formfield_deletecollection_description"
+msgstr "Deleting your collection will permanently erase it."
+
+#: views/collections/add.thtml:73 views/collections/edit.thtml:140
+#, fuzzy
+msgid "collections_edit_formfield_description"
+msgstr "Collection Description"
+
+#: views/collections/add.thtml:74 views/collections/edit.thtml:141
+#, fuzzy
+msgid "collections_edit_formfield_description_description"
+msgstr "Briefly describe your collection and the kind of add-ons in it"
+
+#: views/collections/edit.thtml:162
+#, fuzzy
+msgid "collections_edit_formfield_icon"
+msgstr "Icon"
+
+#: views/collections/edit.thtml:163
+#, fuzzy
+msgid "collections_edit_formfield_icon_description"
+msgstr ""
+"You can upload a JPG, GIF or PNG icon that will be resized to 32x32 pixels."
+
+#: views/collections/add.thtml:80 views/collections/edit.thtml:189
+#, fuzzy
+msgid "collections_edit_formfield_listed"
+msgstr "Who can view your collection?"
+
+#: views/collections/add.thtml:81 views/collections/edit.thtml:190
+#, fuzzy
+msgid "collections_edit_formfield_listed_description"
+msgstr ""
+"By default, collections appear in the public Collection Directory and are "
+"discoverable by anyone. If you want to restrict your collection to be "
+"viewable only by people who are given a special link, choose that option "
+"below."
+
+#: views/collections/add.thtml:84 views/collections/edit.thtml:193
+#, fuzzy
+msgid "collections_edit_formfield_listed_false"
+msgstr "Only people I invite can view my collection"
+
+#: views/collections/add.thtml:83 views/collections/edit.thtml:192
+#, fuzzy
+msgid "collections_edit_formfield_listed_true"
+msgstr "Everyone can view my collection in the directory"
+
+#: views/collections/edit.thtml:223
+#, fuzzy
+msgid "collections_edit_formfield_managers"
+msgstr "Who can manage my collection?"
+
+#: views/collections/edit.thtml:224
+#, fuzzy
+msgid "collections_edit_formfield_managers_description"
+msgstr ""
+"These users can publish add-ons to your collection, manage all add-ons and "
+"settings, and grant other users permission."
+
+#: views/collections/add.thtml:66 views/collections/edit.thtml:126
+#, fuzzy
+msgid "collections_edit_formfield_name"
+msgstr "Collection Name"
+
+#: views/collections/add.thtml:67 views/collections/edit.thtml:127
+#, fuzzy
+msgid "collections_edit_formfield_name_description"
+msgstr ""
+"Give your collection a descriptive name, such as \"Dave's Favorite Travel "
+"Add-ons\""
+
+#: views/collections/edit.thtml:148
+#, fuzzy
+msgid "collections_edit_formfield_nickname"
+msgstr "Collection Nickname"
+
+#: views/collections/edit.thtml:149
+#, fuzzy
+msgid "collections_edit_formfield_nickname_description"
+msgstr "Optionally, give your collection a unique nickname for quick access:"
+
+#: views/collections/edit.thtml:201
+#, fuzzy
+msgid "collections_edit_formfield_publishers"
+msgstr "Who can publish add-ons to your collection?"
+
+#: views/collections/edit.thtml:202
+#, fuzzy
+msgid "collections_edit_formfield_publishers_description"
+msgstr ""
+"These users can publish add-ons to your collection and remove add-ons that "
+"they publish."
+
+#: views/collections/edit.thtml:210 views/collections/edit.thtml:232
+#, fuzzy
+msgid "collections_edit_formfield_users_add"
+msgstr "Enter the e-mail address of a Firefox Add-ons account:"
+
+#: views/collections/edit.thtml:216 views/collections/edit.thtml:238
+#, fuzzy
+msgid "collections_edit_formfield_users_delete_noscript"
+msgstr "Selected accounts will be removed upon Save"
+
+#: views/collections/edit.thtml:215 views/collections/edit.thtml:237
+#, fuzzy
+msgid "collections_edit_formfield_users_new_noscript"
+msgstr ""
+"Enter a comma-separated list of e-mail addresses of Firefox Add-ons accounts"
+
+#: views/collections/edit.thtml:204 views/collections/edit.thtml:226
+#, fuzzy
+msgid "collections_edit_formfield_users_onlyme"
+msgstr "Only me"
+
+#: views/collections/edit.thtml:205 views/collections/edit.thtml:227
+#, fuzzy
+msgid "collections_edit_formfield_users_otherusers"
+msgstr "Myself and these users:"
+
+#: views/collections/edit.thtml:211 views/collections/edit.thtml:233
+#, fuzzy
+msgid "collections_edit_formfield_users_submit"
+msgstr "Add"
+
+#. %1$s is the name of the collection
+#: views/collections/edit.thtml:68
+#, fuzzy
+msgid "collections_edit_header"
+msgstr "Manage %1$s"
+
+#: views/collections/edit.thtml:246
+#, fuzzy
+msgid "collections_edit_header_addons"
+msgstr "Manage Collection Contents"
+
+#: views/collections/edit.thtml:253 views/collections/edit.thtml:258
+#, fuzzy
+msgid "collections_edit_header_addons_current"
+msgstr "Current Add-ons:"
+
+#: views/collections/edit.thtml:279
+#, fuzzy
+msgid "collections_edit_header_advanced"
+msgstr "Advanced Settings"
+
+#: views/collections/edit.thtml:186
+#, fuzzy
+msgid "collections_edit_header_permissions"
+msgstr "Manage Collection Permissions"
+
+#: views/collections/edit.thtml:170
+#, fuzzy
+msgid "collections_edit_icon_cancel"
+msgstr "Cancel"
+
+#: views/collections/edit.thtml:174 views/collections/edit.thtml:179
+#, fuzzy
+msgid "collections_edit_icon_delete"
+msgstr "Delete Icon"
+
+#: views/collections/edit.thtml:178
+#, fuzzy
+msgid "collections_edit_icon_replace"
+msgstr "Replace Icon"
+
+#. %1$s is the label of the edit form's submit button
+#: views/collections/edit.thtml:169
+#, fuzzy
+msgid "collections_edit_icon_toberemoved"
+msgstr "Icon will be removed when \"%1$s\" is clicked below"
+
+#: views/collections/edit.thtml:155
+#, fuzzy
+msgid "collections_edit_nickname_available"
+msgstr "Nickname Available"
+
+#: controllers/collections_controller.php:943
+#, fuzzy
+msgid "collections_edit_nickname_error"
+msgstr ""
+"Your nickname contained invalid characters and was corrected. Please try "
+"again."
+
+#: views/collections/edit.thtml:156
+#, fuzzy
+msgid "collections_edit_nickname_taken"
+msgstr "Nickname Taken"
+
+#. This string is followed by a URL pointing to the collection's view page
+#: views/collections/edit.thtml:75
+#, fuzzy
+msgid "collections_edit_saved_nextstep"
+msgstr "Your collection can be accessed at this location:"
+
+#: views/collections/edit.thtml:74
+#, fuzzy
+msgid "collections_edit_saved_success"
+msgstr "Your collection was successfully saved!"
+
+#: views/collections/edit.thtml:169 views/collections/edit.thtml:300
+#: views/collections/edit.thtml:308 views/pages/js_constants.js.thtml:99
+#, fuzzy
+msgid "collections_edit_submit"
+msgstr "Update Collection"
+
+#: views/collections/edit.thtml:96 views/collections/edit.thtml:297
+#: views/pages/js_constants.js.thtml:100
+#, fuzzy
+msgid "collections_edit_submit_deletecollection"
+msgstr "Delete Collection"
+
+#: views/collections/edit.thtml:111
+#, fuzzy
+msgid "collections_edit_tabheader_addons"
+msgstr "Add-ons"
+
+#: views/collections/edit.thtml:97 views/collections/edit.thtml:113
+#, fuzzy
+msgid "collections_edit_tabheader_advanced"
+msgstr "Advanced"
+
+#: views/collections/edit.thtml:108
+#, fuzzy
+msgid "collections_edit_tabheader_details"
+msgstr "Name &amp; Details"
+
+#: views/collections/edit.thtml:109
+#, fuzzy
+msgid "collections_edit_tabheader_permissions"
+msgstr "Permissions"
+
+#: models/collection_promo.php:53
+#, fuzzy
+msgid "collections_family_tagline"
+msgstr "Add-ons can keep an eye on your kids and your calendar."
+
+#: models/collection_promo.php:53
+#, fuzzy
+msgid "collections_family_title"
+msgstr "Family Organizer"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:70
+#, fuzzy
+msgid "collections_index_a_check_out"
+msgstr "Check out Add-on Collector"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:52
+#, fuzzy
+msgid "collections_index_a_create"
+msgstr "Create a Collection"
+
+#: views/collections/detail.thtml:139 views/collections/listing.thtml:85
+#: views/search/collections.thtml:84
+#, fuzzy
+msgid "collections_index_button_go"
+msgstr "Go"
+
+#. %1$s is a URL.
+#: controllers/collections_controller.php:182
+#, fuzzy
+msgid "collections_index_filler_favorites"
+msgstr ""
+"<p><strong>You don't have any favorite collections yet.</strong></p> "
+"<p>Collections you mark as favorites can be quickly accessed from this page, "
+"and will appear in the <a href='%1$s'>Add-on Collector</a> if you've "
+"installed it.</p>"
+
+#. %1$s is a URL.
+#: controllers/collections_controller.php:167
+#, fuzzy
+msgid "collections_index_filler_mine"
+msgstr ""
+"<p>You haven't created any collections yet. Collections are easy to create "
+"and fill with your favorite add-ons. <a href='%1$s'>Try it out</a>!</p>"
+
+#: views/collections/listing.thtml:51
+#, fuzzy
+msgid "collections_index_header_collections"
+msgstr "Collections"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:60
+#, fuzzy
+msgid "collections_index_header_collector"
+msgstr "Add-on Collector"
+
+#. %1$s is a comma-separated list of author names
+#: views/elements/amo2009/collection_listing_item.thtml:84
+#: views/collections/detail.thtml:151
+#, fuzzy
+msgid "collections_index_header_created"
+msgstr "created by %1$s"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:47
+#, fuzzy
+msgid "collections_index_header_what"
+msgstr "What are Collections?"
+
+#: views/collections/detail.thtml:132 views/collections/listing.thtml:78
+#: views/search/collections.thtml:66
+#, fuzzy
+msgid "collections_index_label_sortby"
+msgstr "Sort by"
+
+#: controllers/collections_controller.php:130
+#, fuzzy
+msgid "collections_index_li_editors"
+msgstr "Editor's Picks"
+
+#: views/collections/subscribe.thtml:64
+#: controllers/collections_controller.php:140
+#, fuzzy
+msgid "collections_index_li_favorites"
+msgstr "My Favorites"
+
+#: controllers/collections_controller.php:138
+#, fuzzy
+msgid "collections_index_li_mine"
+msgstr "My Collections"
+
+#: controllers/collections_controller.php:132
+#, fuzzy
+msgid "collections_index_li_popular"
+msgstr "Popular"
+
+#: views/search/collections.thtml:74 controllers/collections_controller.php:81
+#, fuzzy
+msgid "collections_index_option_all"
+msgstr "Most popular all time"
+
+#: views/search/collections.thtml:72 controllers/collections_controller.php:78
+#, fuzzy
+msgid "collections_index_option_month"
+msgstr "Most popular this month"
+
+#: views/search/collections.thtml:76 controllers/collections_controller.php:84
+#, fuzzy
+msgid "collections_index_option_newest"
+msgstr "Newest"
+
+#: views/search/collections.thtml:70 controllers/collections_controller.php:75
+#, fuzzy
+msgid "collections_index_option_week"
+msgstr "Most popular this week"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:67
+#, fuzzy
+msgid "collections_index_p_collector"
+msgstr ""
+"There's a new way to manage and find favorite add-ons. Comment, share and "
+"sync collections, all from your browser"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:48
+#, fuzzy
+msgid "collections_index_p_what_are"
+msgstr "Collections are groups of related add-ons assembled for easy sharing."
+
+#. %s is a date in the _('date') format
+#: views/elements/collections_interactive_addon.thtml:85
+#, php-format
+msgid "collections_interactive_addon_added"
+msgstr "Curtha Leis %s"
+
+#: models/collection_promo.php:55
+#, fuzzy
+msgid "collections_reference_tagline"
+msgstr "Add-ons can do better research online."
+
+#: models/collection_promo.php:55
+#, fuzzy
+msgid "collections_reference_title"
+msgstr "Reference Desk"
+
+#: models/collection_promo.php:52
+#, fuzzy
+msgid "collections_social_tagline"
+msgstr "Add-ons can manage your social network."
+
+#: models/collection_promo.php:52
+#, fuzzy
+msgid "collections_social_title"
+msgstr "Social Circuit"
+
+#: views/collections/subscribe.thtml:91
+#, fuzzy
+msgid "collections_subscribe_button_close"
+msgstr "Close"
+
+#: views/collections/subscribe.thtml:70
+#, fuzzy
+msgid "collections_subscribe_error"
+msgstr ""
+"An error occurred trying to add a favorite collection. Is this collection "
+"already a favorite?"
+
+#: views/collections/subscribe.thtml:96
+#, fuzzy
+msgid "collections_subscribe_label_bothersome"
+msgstr "Don't show me this message again."
+
+#. %1$s is the collection name
+#: views/collections/subscribe.thtml:60
+#, fuzzy
+msgid "collections_subscribe_success"
+msgstr "%1$s has been added to your favorite collections."
+
+#. %1$s is the link to the "My Favorites" tab on the main collections page
+#. %2$s is the localized title of the "My Favorites" tab
+#. %3$s is the link URL to the collector add-on
+#: views/collections/subscribe.thtml:62
+#, fuzzy
+msgid "collections_subscribe_success_desc"
+msgstr ""
+"You can now quickly find this collection from the <a href=\"%1$s\">%2$s</a> "
+"tab in the directory. For an even easier way to keep track of your favorite "
+"collections, try out our <a href=\"%3$s\">Add-on Collector</a> extension for "
+"Firefox."
+
+#: views/collections/listing.thtml:55
+#, fuzzy
+msgid "collections_success_delete"
+msgstr "The collection has been deleted."
+
+#: models/collection_promo.php:54
+#, fuzzy
+msgid "collections_travel_tagline"
+msgstr "Add-ons can turn you into a travel agent."
+
+#: models/collection_promo.php:54
+#, fuzzy
+msgid "collections_travel_title"
+msgstr "The Traveler's Pack"
+
+#. A collection of add-ons that is automatically built for a user. They are "automatically published" to this collection.
+#: controllers/collections_controller.php:581
+#, fuzzy
+msgid "collections_type_autopublisher"
+msgstr "Auto-publisher"
+
+#. A collection that has been chosen by an Editor as notable or exceptional
+#: controllers/collections_controller.php:582
+#, fuzzy
+msgid "collections_type_editorspick"
+msgstr "Editor's Pick"
+
+#: controllers/collections_controller.php:580
+#, fuzzy
+msgid "collections_type_normal"
+msgstr "Normal"
+
+#: views/collections/subscribe.thtml:84
+#, fuzzy
+msgid "collections_unsubscribe_error"
+msgstr ""
+"An error occurred trying to remove a favorite collection. Was this "
+"collection not a favorite?"
+
+#. %1$s is the collection name
+#: views/collections/subscribe.thtml:78
+#, fuzzy
+msgid "collections_unsubscribe_success"
+msgstr "%1$s has been removed from your favorite collections."
+
+#: models/collection_promo.php:56
+#, fuzzy
+msgid "collections_webdev_tagline"
+msgstr "Add-ons make it easier to build the perfect website."
+
+#: models/collection_promo.php:56
+#, fuzzy
+msgid "collections_webdev_title"
+msgstr "Web Developer's Toolbox"
+
+#: views/elements/amo2009/collections_sidebar_whatare.thtml:40
+#, fuzzy
+msgid "collections_whatare_header"
+msgstr "What are Collections?"
+
+#: views/elements/amo2009/collections_sidebar_whatare.thtml:45
+#, fuzzy
+msgid "collections_whatare_learnmore"
+msgstr "Read the FAQ"
+
+#: views/elements/amo2009/collections_sidebar_whatare.thtml:44
+#, fuzzy
+msgid "collections_whatare_text"
+msgstr ""
+"There’s a new way to manage and find favorite add-ons. Comment, share and "
+"sync collections, all from your browser."
+
+#: views/pages/collector_faq.thtml:61 views/pages/collector_features.thtml:67
+#, fuzzy
+msgid "collector_features_a_home"
+msgstr "Add-on Collector Home"
+
+#: views/elements/amo2009/collector_sidebar_download.thtml:46
+#, fuzzy
+msgid "collector_features_heading_download"
+msgstr "Download the Add-on Collector:"
+
+#: views/elements/amo2009/collector_sidebar_download.thtml:43
+#: views/pages/collector_firstrun.thtml:116 views/pages/collector.thtml:69
+#, fuzzy
+msgid "collector_features_img_logo"
+msgstr "Add-on Collector Logo"
+
+#: views/compatibility/dashboard.thtml:49
+#: controllers/compatibility_controller.php:72
+msgid "compatibility_dashboard_center_header"
+msgstr "Lárionad Comhoiriúnachta Breiseán"
+
+#. %1$s is the name of an application and a version. Example: Firefox 3.0
+#. %2$s is the name of an application. Example: Firefox
+#: views/compatibility/dashboard.thtml:50
+#, fuzzy
+msgid "compatibility_dashboard_intro"
+msgstr ""
+"Be prepared for the release of %1$s with the tools and information available "
+"for the %2$s Add-ons community found below."
+
+#: views/compatibility/dashboard.thtml:103
+msgid "compatibility_dashboard_loading"
+msgstr "Sonraí á luchtú..."
+
+#: views/compatibility/dashboard.thtml:45
+msgid "compatibility_dashboard_main_link"
+msgstr "Ar ais go dtí an Príomhleathanach"
+
+#: views/compatibility/dashboard.thtml:100 views/compatibility/report.thtml:43
+msgid "compatibility_dashboard_report"
+msgstr "Tuairisc Chomhoiriúnacht an Bhreiseáin"
+
+#: views/compatibility/dashboard.thtml:53
+#: views/compatibility/dashboard.thtml:110
+#: views/compatibility/developers.thtml:43
+msgid "compatibility_developer_info"
+msgstr "Eolas le haghaidh Forbróirí"
+
+#: views/compatibility/developers.thtml:66
+msgid "compatibility_developers_adjust_maxversion"
+msgstr "Athraigh maxVersion gan uasluchtú"
+
+#: views/compatibility/dashboard.thtml:124
+msgid "compatibility_developers_check_status"
+msgstr "Seiceáil Stádas de Mo Chuid Breiseán"
+
+#. %1$s is a URL
+#. %2$s is an application and version. Example: Firefox 3.0
+#: views/compatibility/dashboard.thtml:126
+msgid "compatibility_developers_login_first"
+msgstr ""
+"Má tá breiseáin agat óstáilte ag Breiseáin Mozilla, <a href=\"\"%1$s"
+"\">logáil isteach</a> chun anailís a dhéanamh ar stádas do chuid breiseán le "
+"haghaidh %2$s."
+
+#: views/compatibility/dashboard.thtml:114
+msgid "compatibility_developers_mdclogo_alt"
+msgstr "Lógó Lárionad Forbartha Mozilla"
+
+#: views/compatibility/developers.thtml:73
+msgid "compatibility_developers_no_addons"
+msgstr "Níl aon bhreiseáin óstáilte ag Breiseáin Mozilla agat."
+
+#: views/compatibility/dashboard.thtml:133
+#: views/compatibility/developers.thtml:55
+msgid "compatibility_developers_results"
+msgstr "Torthaí Seiceáil Stádais an Bhreiseáin"
+
+#: views/compatibility/dashboard.thtml:137
+msgid "compatibility_developers_retrieving"
+msgstr "Stádas do bhreiseáin óstáilte á fháil..."
+
+#. %1$s is a number
+#. %2$s is an application name
+#. %3$s is a number.
+#. Full example: 50 Firefox users (10% of total)
+#: views/compatibility/developers.thtml:65
+msgid "compatibility_developers_user_count"
+msgstr "%1$s úsáideoir %2$s (%3$s&#37; as an iomlán)"
+
+#: views/compatibility/report.thtml:45
+#, fuzzy
+msgid "compatibility_report_detail_intro"
+msgstr ""
+"The add-ons below make up 95% of add-on usage known to Mozilla and are "
+"ordered by their usage size."
+
+#: views/compatibility/dashboard.thtml:94
+msgid "compatibility_report_detailed_link"
+msgstr "Féach ar Thuairisc Mhionsonraithe"
+
+#. %1$s and %2$s are numbers
+#. %3$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:65
+#, fuzzy
+msgid "compatibility_report_intro"
+msgstr ""
+"Of the %1$s add-ons that make up 95&#37; of add-on usage known to Mozilla, "
+"<b>%2$s&#37;</b> are currently considered compatible with the latest builds "
+"of %3$s."
+
+#: views/compatibility/dashboard.thtml:81
+msgid "compatibility_report_legend_alpha"
+msgstr "Leaganacha Alfa"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:81
+msgid "compatibility_report_legend_alpha_description"
+msgstr "Breiseáin atá comhoiriúnach le leagan alfa de %1$s"
+
+#: views/compatibility/dashboard.thtml:85
+msgid "compatibility_report_legend_beta"
+msgstr "Leaganacha Béite"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:85
+msgid "compatibility_report_legend_beta_description"
+msgstr ""
+"Breiseáin atá comhoiriúnach le leagan béite nó leagan réamhscaoilte de %1$s"
+
+#: views/compatibility/dashboard.thtml:89
+msgid "compatibility_report_legend_latest"
+msgstr "Leagan Is Déanaí"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:89
+msgid "compatibility_report_legend_latest_description"
+msgstr "Breiseáin atá suas le dáta na leaganacha is déanaí de %1$s"
+
+#: views/compatibility/dashboard.thtml:77
+msgid "compatibility_report_legend_other"
+msgstr "Leaganacha Eile"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:77
+msgid "compatibility_report_legend_other_description"
+msgstr "Breiseáin nach bhfuil comhoiriúnach le haon leagan de %1$s"
+
+#: views/compatibility/dashboard.thtml:62
+msgid "compatibility_report_title"
+msgstr "Tuairisc Chomhoiriúnacht an Bhreiseáin"
+
+#: views/compatibility/dashboard.thtml:54
+#: views/compatibility/dashboard.thtml:144 views/compatibility/users.thtml:42
+msgid "compatibility_user_info"
+msgstr "Eolas le haghaidh Úsáideoirí"
+
+#: views/compatibility/dashboard.thtml:52
+msgid "compatibility_view_report"
+msgstr "Féach ar Thuairisc Chomhoiriúnachta"
+
+#. %s is a URL
+#: views/pages/credits.thtml:142
+#, php-format
+msgid "credits_contributing"
+msgstr ""
+"Le tuilleadh eolais a fháil maidir le conas b'fhéidir leat cabhrú linn, "
+"féach ar %s."
+
+#: views/pages/credits.thtml:142
+msgid "credits_contributing_wikipage"
+msgstr "leathanach vicí"
+
+#: views/pages/credits.thtml:99
+msgid "credits_intro"
+msgstr ""
+"Ba mhaith le Mozilla a bhuíochas a ghabháil leis na daoine seo a leanas as a "
+"gcuid oibre ar addons.mozilla.org le blianta anuas:"
+
+#: views/pages/credits.thtml:103
+msgid "credits_section_developers"
+msgstr "Forbróirí"
+
+#: views/pages/credits.thtml:115
+msgid "credits_section_editors"
+msgstr "Eagarthóirí"
+
+#: views/pages/credits.thtml:109
+msgid "credits_section_localizers"
+msgstr "Aistritheoirí"
+
+#: views/pages/credits.thtml:121
+msgid "credits_section_other_contributors"
+msgstr "Daoine eile a chuir leis an obair"
+
+#: views/pages/credits.thtml:127
+msgid "credits_section_past_developers"
+msgstr "Iarfhorbróirí"
+
+#: views/pages/credits.thtml:133
+msgid "credits_section_software"
+msgstr "Bogearraí agus Ãomhánna"
+
+#: views/pages/credits.thtml:136
+msgid "credits_software_famfamfam"
+msgstr ""
+"Úsáidtear deilbhíní ón <a href=\"http://www.famfamfam.com/lab/icons/silk/"
+"\">famfamfam Silk Icon Set</a>, ar fáil de réir coinníollacha an cheadúnais "
+"<a href=\"http://creativecommons.org/licenses/by/2.5/\">Creative Commons "
+"Attribution, leagan 2.5</a>."
+
+#: views/pages/credits.thtml:137
+msgid "credits_software_timeplot"
+msgstr ""
+"Úsáidtear codanna de <a href=\"http://www.simile-widgets.org/timeplot/"
+"\">Timeplot</a>, atá ar fáil faoi <a href=\"http://simile.mit.edu/license."
+"html\">Cheadúnas BSD</a>, ar leathanaigh áirithe."
+
+# date format string as used in PHP's strftime():
+# http://php.net/strftime
+#. date format string as used in PHP's strftime():
+#. http://php.net/strftime
+#: views/elements/collections_interactive_addon.thtml:85
+#: views/elements/amo2009/addon_version_detail.thtml:53
+#: views/elements/amo2009/homepage_addon.thtml:115
+#: views/elements/addon_version_detail.thtml:54
+#: views/elements/addon_listitem.thtml:124 views/elements/feature.thtml:106
+#: views/collections/detail.thtml:118 views/collections/edit.thtml:325
+#: views/users/info.thtml:76 views/editors/reviews_queue.thtml:57
+#: views/editors/reviews_queue.thtml:68 views/developers/dashboard.thtml:65
+#: views/developers/versions_edit.thtml:208 views/developers/versions.thtml:67
+#: views/search/rss/index.thtml:5 views/addons/rss/versions.thtml:42
+#: views/addons/display.thtml:104 views/addons/display.thtml:356
+#: views/addons/browse_thumbs.thtml:75 views/reviews/add.thtml:63
+#: views/reviews/display.thtml:74 views/reviews/display.thtml:160
+#: views/reviews/delete.thtml:54 controllers/statistics_controller.php:244
+#: controllers/collections_controller.php:1047
+msgid "date"
+msgstr "%e %B, %Y"
+
+# date and time format string (strftime)
+#. date and time format string (strftime)
+#. http://php.net/strftime
+#: views/elements/addon_version_detail.thtml:53
+#: views/developers/discuss.thtml:52 views/developers/discuss.thtml:62
+#: views/admin/addons_status.thtml:57
+msgid "datetime"
+msgstr "%e %B, %Y, %H:%M"
+
+#: views/elements/developers/actionbar.thtml:47
+msgid "devcp_actionbar_link_details"
+msgstr "Mioneolas"
+
+#: views/elements/developers/actionbar.thtml:42
+#: views/elements/developers/actionbar.thtml:50
+#: views/developers/dashboard.thtml:64
+msgid "devcp_actionbar_link_edit"
+msgstr "Cuir an Breiseán in Eagar"
+
+#: views/elements/developers/actionbar.thtml:51
+msgid "devcp_actionbar_link_newversion"
+msgstr "Uasluchtaigh Leagan Nua"
+
+#: views/elements/developers/actionbar.thtml:44
+#: views/elements/developers/actionbar.thtml:49
+#: views/developers/dashboard.thtml:73
+msgid "devcp_actionbar_link_stats"
+msgstr "Painéal na Staitisticí"
+
+#. %1$s is a filename, e.g. "foo.txt"
+#. %2$s is the extension, e.g. ".txt"
+#. %3$s is a list of valid extensions, like ".png, .jpg, .gif"
+#: controllers/developers_controller.php:1361
+msgid "devcp_add_previews_extension_error"
+msgstr ""
+"Iarmhír neamhbhailí (%2$s) ar chomhad %1$s. Iarmhíreanna ceadaithe: %3$s"
+
+#. %s is the filename.
+#: controllers/developers_controller.php:1394
+msgid "devcp_add_previews_save_error"
+msgstr ""
+"Níorbh fhéidir comhad %s a shábháil sa bhunachar sonraí. Bain triail eile as."
+
+#. %1$s is the preview ID number, %2$s is the filename.
+#: controllers/developers_controller.php:1389
+msgid "devcp_add_previews_success_replace"
+msgstr "Cuireadh comhad %2$s in ionad réamhamharc %1$s gan fhadhb."
+
+#. %s is the filename.
+#: controllers/developers_controller.php:1391
+msgid "devcp_add_previews_success_upload"
+msgstr ""
+"Uasluchtaíodh comhad %s gan fhadhb. Is féidir leat fotheideal a chur leis "
+"thíos."
+
+#: controllers/components/developers.php:1163
+msgid "devcp_additem_addontype_autodetect"
+msgstr "(braith go huathoibríoch)"
+
+#: views/elements/developers/additem.thtml:76
+msgid "devcp_additem_linktitle_opensin_newwindow"
+msgstr "Osclaíonn sé i bhfuinneog nua"
+
+#: views/elements/developers/additem.thtml:41
+msgid "devcp_additem_sidebar_title"
+msgstr "Seol Breiseán"
+
+#: views/elements/developers/additem.thtml:53
+msgid "devcp_additem_step0_newlink"
+msgstr "Comhaontú Forbróra"
+
+#: views/elements/developers/additem.thtml:46
+msgid "devcp_additem_step1_link"
+msgstr "Céim 1: Uasluchtú"
+
+#: views/elements/developers/additem.thtml:47
+msgid "devcp_additem_step2_link"
+msgstr "Céim 2: Mionsonraí an Bhreiseáin"
+
+#: views/elements/developers/additem.thtml:48
+msgid "devcp_additem_step3_link"
+msgstr "Céim 3: Mionsonraí an Leagain"
+
+#: views/elements/developers/additem.thtml:49
+msgid "devcp_additem_step4_link"
+msgstr "Céim 4: Logánú"
+
+#: views/elements/developers/additem.thtml:50
+msgid "devcp_additem_step5_link"
+msgstr "Céim 5: D'éirigh leat"
+
+#: views/elements/developers/additem.thtml:76
+msgid "devcp_additem_submissionhelp_link"
+msgstr "Cabhair le Seoladh Breiseán"
+
+#: controllers/previews_controller.php:168
+#: controllers/previews_controller.php:277
+msgid "devcp_addon_field_preview_caption_displaytitle"
+msgstr "Fotheideal an Réamhamhairc"
+
+#: views/developers/addon_status.thtml:177
+msgid "devcp_addon_status_action_activate"
+msgstr "Gníomhachtaigh"
+
+#: views/developers/addon_status.thtml:178
+#, fuzzy
+msgid "devcp_addon_status_action_activate_description"
+msgstr ""
+"Make your add-on active for it to show up in public listings and enable the "
+"update check service."
+
+#: views/developers/addon_status.thtml:135
+msgid "devcp_addon_status_action_complete"
+msgstr "Críochnaigh an Breiseán"
+
+#: views/developers/addon_status.thtml:136
+msgid "devcp_addon_status_action_complete_description"
+msgstr "Críochnaigh do bhreiseán agus cuir é sa Bhosca Gainimh"
+
+#: views/developers/addon_status.thtml:181
+msgid "devcp_addon_status_action_deactivate"
+msgstr "Díghníomhachtaigh"
+
+#: views/developers/addon_status.thtml:182
+#, fuzzy
+msgid "devcp_addon_status_action_deactivate_description"
+msgstr ""
+"Make your add-on inactive to hide it from all public listings and disable "
+"the update check service."
+
+#: views/developers/addon_status.thtml:143
+msgid "devcp_addon_status_action_move"
+msgstr "Cuir é sa Bhosca Gainimh"
+
+#: views/developers/addon_status.thtml:144
+msgid "devcp_addon_status_action_move_description"
+msgstr ""
+"Cuir do bhreiseán ar ais sa Bhosca Gainimh. Beidh tú in ann é seo a chealú."
+
+#: views/developers/addon_status.thtml:139
+#, fuzzy
+msgid "devcp_addon_status_action_nominate"
+msgstr "Nominate for Public"
+
+#: views/developers/addon_status.thtml:140
+msgid "devcp_addon_status_action_nominate_description"
+msgstr "Ainmnigh do bhreiseán chun é a bhogadh go dtí an taobh poiblí"
+
+#: views/developers/addon_status.thtml:147
+msgid "devcp_addon_status_action_public"
+msgstr "Foilsigh"
+
+#: views/developers/addon_status.thtml:148
+msgid "devcp_addon_status_action_public_description"
+msgstr "Foilsigh do bhreiseán arís."
+
+#: views/developers/addon_status.thtml:169
+#, fuzzy
+msgid "devcp_addon_status_active"
+msgstr ""
+"Your add-on is <span class=\"inactive-0\">Active</span>. This means your add-"
+"on is showing up in all available listings appropriate for its status above."
+
+#: views/developers/addon_status.thtml:111
+#, fuzzy
+msgid "devcp_addon_status_completion_disabled"
+msgstr ""
+"Please fulfill the criteria above before you can complete your add-on and "
+"move it to the <span class=\"status-1\">Sandbox</span>."
+
+#: views/developers/addon_status.thtml:108
+#, fuzzy
+msgid "devcp_addon_status_completion_enabled"
+msgstr ""
+"You may now complete your add-on and move it to the <span class=\"status-1"
+"\">Sandbox</span> by clicking the button below."
+
+#: views/developers/addon_status.thtml:102
+msgid "devcp_addon_status_criteria_category"
+msgstr "Roghnaíodh catagóir amháin ar a laghad"
+
+#: views/developers/addon_status.thtml:101
+msgid "devcp_addon_status_criteria_description"
+msgstr "Cur Síos ar an mBreiseán de dhíth"
+
+#: views/developers/addon_status.thtml:99
+msgid "devcp_addon_status_criteria_name"
+msgstr "Ainm de dhíth ar an Bhreiseán"
+
+#: views/developers/addon_status.thtml:120
+#, fuzzy
+msgid "devcp_addon_status_criteria_prerelease"
+msgstr "Add-on is not marked as pre-release."
+
+#: views/developers/addon_status.thtml:119
+msgid "devcp_addon_status_criteria_preview"
+msgstr "Ãomhá réamhamhairc de dhíth ar eisínteachtaí agus téamaí."
+
+#: views/developers/addon_status.thtml:100
+msgid "devcp_addon_status_criteria_summary"
+msgstr "Achoimre de dhíth ar an mBreiseán"
+
+#. %s is the status in a span, e.g. "<span>_('Public')</span>".
+#: views/developers/addon_status.thtml:58
+msgid "devcp_addon_status_header"
+msgstr "Stádas an Bhreiseáin: %s"
+
+#: views/developers/addon_status.thtml:152
+#: views/developers/addon_status.thtml:173
+msgid "devcp_addon_status_header_actions"
+msgstr "Gníomhartha Le Fáil"
+
+#: views/developers/addon_status.thtml:168
+msgid "devcp_addon_status_header_active"
+msgstr "Stádas Gníomhachtaithe: <span class=\"inactive-0\">Gníomhach</span>"
+
+#: views/developers/addon_status.thtml:97
+#, fuzzy
+msgid "devcp_addon_status_header_criteria"
+msgstr "Add-on Completion Criteria"
+
+#: views/developers/addon_status.thtml:164
+msgid "devcp_addon_status_header_inactive"
+msgstr ""
+"Stádas Gníomhachtaithe: <span class=\"inactive-1\">Neamhghníomhach</span>"
+
+#: views/developers/addon_status.thtml:117
+msgid "devcp_addon_status_header_nomination"
+msgstr "Critéir Ainmnithe"
+
+#: views/developers/addon_status.thtml:190
+msgid "devcp_addon_status_header_trusted"
+msgstr "Stádas Iontaoibhe: <span class=\"status-4\">Iontaofa</span>"
+
+#: views/developers/addon_status.thtml:165
+#, fuzzy
+msgid "devcp_addon_status_inactive"
+msgstr ""
+"Your add-on is <span class=\"inactive-1\">Inactive</span>. This means your "
+"add-on will not show up in any listing, regardless of its status above. "
+"Updates are <b>not</b> being provided to your add-on through the update "
+"check service."
+
+#: views/developers/addon_status.thtml:128
+#, fuzzy
+msgid "devcp_addon_status_nominate_disabled"
+msgstr ""
+"Please fulfill the criteria above before nominating your add-on to become "
+"<span class=\"status-4\">Public</span>."
+
+#: views/developers/addon_status.thtml:125
+msgid "devcp_addon_status_nominate_enabled"
+msgstr ""
+"Is féidir leat do bhreiseán a ainmniú chun é a bhogadh go dtí an taobh <span "
+"class=\"status-4\">Poiblí</span> trí chliceáil ar an gcnaipe thíos."
+
+#: views/developers/addon_status.thtml:64
+msgid "devcp_addon_status_public"
+msgstr "Poiblí"
+
+#: views/developers/addon_status.thtml:63
+msgid "devcp_addon_status_sandbox"
+msgstr "Bosca Gainimh"
+
+#. %s is an email address.
+#: views/developers/addon_status.thtml:89
+msgid "devcp_addon_status_switch_disabled"
+msgstr ""
+"Bhí do bhreiseán <span class=\"status-5\">Díchumasaithe</span> ag riarthóir "
+"agus ní féidir é a úsáid. Má tá ceisteanna ort, seol ríomhphost chuig %s."
+
+#: views/developers/addon_status.thtml:67
+#, fuzzy
+msgid "devcp_addon_status_switch_incomplete"
+msgstr ""
+"Your add-on is currently <span class=\"status-0\">Incomplete</span>. This "
+"means your add-on is not showing up on any portion of the site or update "
+"check service. You may come to this page to complete your add-on after it "
+"meets the criteria below for completion and transfer to the <span class="
+"\"status-1\">Sandbox</span>."
+
+#. %s is a number, perhaps 42.
+#: views/developers/addon_status.thtml:77
+#, fuzzy
+msgid "devcp_addon_status_switch_nominated"
+msgstr ""
+"Your add-on is currently nominated to become <span class=\"status-4"
+"\">Public</span> and is awaiting editor review. There are currently %s other "
+"add-ons in the nomination queue."
+
+#. %s is an email address.
+#: views/developers/addon_status.thtml:81
+#, fuzzy
+msgid "devcp_addon_status_switch_pending"
+msgstr ""
+"Your add-on is pending. This shouldn't have happened. Please e-mail %s with "
+"your add-on ID and state this error."
+
+#: views/developers/addon_status.thtml:85
+#, fuzzy
+msgid "devcp_addon_status_switch_public"
+msgstr ""
+"Your add-on is <span class=\"status-4\">Public</span>, which means it will "
+"show up in all listings and searches and can be downloaded without "
+"restriction. Updates are being provided to your add-on through the update "
+"check service."
+
+#: views/developers/addon_status.thtml:71
+#: views/developers/addon_status.thtml:75
+#, fuzzy
+msgid "devcp_addon_status_switch_sandbox"
+msgstr ""
+"Your add-on is in the <span class=\"status-1\">Sandbox</span>, which means "
+"it will show up in listings and searches, but users must log in to download "
+"it. Updates are <b>not</b> being provided to your add-on through the update "
+"check service."
+
+#. %s is the add-on name.
+#: views/developers/addon_status_nominate.thtml:43
+#: views/developers/addon_status_confirm.thtml:43
+#: views/developers/addon_status.thtml:43
+msgid "devcp_addon_status_title"
+msgstr "Stádas %s"
+
+#: views/developers/addon_status.thtml:191
+#, fuzzy
+msgid "devcp_addon_status_trusted"
+msgstr ""
+"Your add-on is <span class=\"status-4\">Trusted</span>. This means you can "
+"submit updates to your add-on without editor review."
+
+#: views/developers/dashboard.thtml:68
+msgid "devcp_dashboard_active"
+msgstr "Gníomhach"
+
+#. %1$s is the add-on type string
+#. %2$s is Inactive or Active in a <span>
+#. %3$s is the addon's public status (Public, In Sandbox, ...) in a <span>
+#: views/developers/dashboard.thtml:69
+msgid "devcp_dashboard_addontype_status"
+msgstr "Tá an %1$s %2$s agus %3$s faoi láthair"
+
+#: views/developers/dashboard.thtml:67
+msgid "devcp_dashboard_change_status"
+msgstr "Athraigh Stádas"
+
+#. %s is the addons email address.
+#: views/developers/dashboard.thtml:99
+msgid "devcp_dashboard_disabled_questions"
+msgstr ""
+"Bhí do bhreiseán díchumasaithe ag riarthóir agus ní féidir é a úsáid. Má tá "
+"ceisteanna ort, seol ríomhphost chuig %s."
+
+#. %s is the (localized) add-on status string in a span, e.g. "Disabled"
+#: views/developers/dashboard.thtml:98
+msgid "devcp_dashboard_disabled_status"
+msgstr "Stádas an Bhreiseáin: %s"
+
+#: views/developers/dashboard.thtml:43
+msgid "devcp_dashboard_header_main"
+msgstr "Painéal Forbróirí"
+
+#: views/developers/dashboard.thtml:110
+msgid "devcp_dashboard_header_welcome"
+msgstr "Fáilte go dtí an Painéal Forbróirí"
+
+#: views/developers/dashboard.thtml:68
+msgid "devcp_dashboard_inactive"
+msgstr "Neamhghníomhach"
+
+#. %s is a date in the _('date') format
+#: views/developers/dashboard.thtml:65
+msgid "devcp_dashboard_last_edited"
+msgstr "Athrú is déanaí: %s"
+
+#: views/developers/dashboard.thtml:111
+#, fuzzy
+msgid "devcp_dashboard_learn"
+msgstr ""
+"You don't currently have any add-ons hosted on Mozilla Add-ons. To learn how "
+"the process works and submit your first add-on, click Get Started below."
+
+#: views/developers/dashboard.thtml:112
+msgid "devcp_dashboard_start"
+msgstr "Tús Maith"
+
+#: views/developers/dashboard.thtml:82
+msgid "devcp_dashboard_versions"
+msgstr "Leaganacha agus Comhaid"
+
+#: views/developers/dashboard.thtml:91
+msgid "devcp_dashboard_versions_new"
+msgstr "Uasluchtaigh leagan nua"
+
+#. %s is the preview ID number.
+#: controllers/developers_controller.php:1415
+msgid "devcp_delete_previews_error"
+msgstr ""
+"Níorbh fhéidir réamhamharc %s a scriosadh ón bhunachar sonraí. Bain triail "
+"eile as."
+
+#. %s is the preview ID number.
+#: controllers/developers_controller.php:1413
+msgid "devcp_delete_previews_success"
+msgstr "Scriosadh réamhamharc %s."
+
+#: controllers/developers_controller.php:1089
+msgid "devcp_delete_version_priv_error"
+msgstr "Níl cead agat leaganacha ná comhaid a scriosadh."
+
+#. %1$s is the count of files, a number
+#. %2$s is a status string like _('Public') or _('Incomplete')
+#: controllers/components/amo.php:549
+msgid "devcp_describe_version_status"
+msgid_plural "devcp_describe_version_status"
+msgstr[0] "%1$s chomhad %2$s"
+msgstr[1] "%1$s chomhad %2$s"
+msgstr[2] "%1$s chomhad %2$s"
+msgstr[3] "%1$s gcomhad %2$s"
+msgstr[4] "%1$s comhad %2$s"
+
+#. %s is a version number. Example: 3.0
+#: views/developers/versions.thtml:65
+#, php-format
+msgid "devcp_details_version"
+msgstr "Leagan %s"
+
+#: views/developers/discuss.thtml:68
+msgid "devcp_discuss_addreply_header"
+msgstr "Cuir Freagra Leis"
+
+#: views/developers/discuss.thtml:57
+msgid "devcp_discuss_allreplies_header"
+msgstr "Freagraí"
+
+#. notice when an error occurs saving a discussion reply
+#. %1 is the email address (linked) for the amo-editors list
+#: views/developers/discuss.thtml:70
+msgid "devcp_discuss_error_notice"
+msgstr ""
+"Tharla earráid agus do fhreagra á shábháil. Téigh i dteagmháil le %1$s faoin "
+"fhadhb seo."
+
+#. %1 is the add-on name, %2 is the add-on's version number currently being reviewed by an editor
+#: views/developers/discuss.thtml:46
+#, fuzzy
+msgid "devcp_discuss_intro"
+msgstr ""
+"A Mozilla Add-ons Editor requested further information from you regarding "
+"version %2$s of your add-on %1$s."
+
+#. %1 is the add-on name
+#: views/developers/discuss.thtml:43
+#, fuzzy
+msgid "devcp_discuss_pagetitle"
+msgstr "Provide More Information For the Add-on Review of %1$s"
+
+#. submit button text
+#: views/developers/discuss.thtml:79
+msgid "devcp_discuss_submit_reply"
+msgstr "Seol Freagra"
+
+#: views/developers/discuss.thtml:72
+#, fuzzy
+msgid "devcp_discuss_success_message"
+msgstr ""
+"Your reply was successfully saved. The other participants of the discussion "
+"will be notified by email."
+
+#. in an author/editor discussion about an add-on to be reviewed:
+#. %1 is the commenter's user name (linked).
+#. %2 is the full date the comment was made.
+#: views/developers/discuss.thtml:52 views/developers/discuss.thtml:62
+msgid "devcp_discuss_writtenby"
+msgstr "scríofa ag %1$s ar %2$s"
+
+#: views/developers/addon_edit_authors.thtml:72
+#: views/developers/addon_edit_authors.thtml:81
+msgid "devcp_edit_authors_add_author"
+msgstr "Cuir Údar Nua Leis"
+
+#: views/developers/addon_edit_authors.thtml:96
+msgid "devcp_edit_authors_add_author_button"
+msgstr "Cuir Údar Leis"
+
+#: views/developers/addon_edit_authors.thtml:83
+#, fuzzy
+msgid "devcp_edit_authors_add_email"
+msgstr "Author Account Email:"
+
+#: views/developers/addon_edit_authors.thtml:98
+#, fuzzy
+msgid "devcp_edit_authors_add_loading"
+msgstr "Checking account email..."
+
+#: views/developers/addon_edit_authors.thtml:70
+#, fuzzy
+msgid "devcp_edit_authors_click_save"
+msgstr "Click the Update Authors button below to save."
+
+#: views/developers/addon_edit_authors.thtml:58
+msgid "devcp_edit_authors_header_current"
+msgstr "Údair Reatha"
+
+#: views/developers/addon_edit_authors.thtml:50
+msgid "devcp_edit_authors_header_manage"
+msgstr "Bainistigh Údair an Bhreiseáin"
+
+#: views/developers/addon_edit_authors.thtml:93
+#, fuzzy
+msgid "devcp_edit_authors_label_add_listed"
+msgstr "List as author in public display pages"
+
+#: views/developers/addon_edit_authors.thtml:89
+#, fuzzy
+msgid "devcp_edit_authors_label_developer"
+msgstr ""
+"<strong>Developer</strong> - Can manage all aspects of the add-on listing, "
+"except for adding and removing other authors."
+
+#: views/developers/addon_edit_authors.thtml:88
+#, fuzzy
+msgid "devcp_edit_authors_label_owner"
+msgstr ""
+"<strong>Owner</strong> - Can manage all aspects of the add-on listing, "
+"including adding and removing other authors."
+
+#: views/developers/addon_edit_authors.thtml:90
+#, fuzzy
+msgid "devcp_edit_authors_label_viewer"
+msgstr ""
+"<strong>Viewer</strong> - Can view add-on developer listing and statistics, "
+"but can't make any changes."
+
+#. Placeholder for the empty option in a <select>.
+#: views/developers/addon_edit_categories.thtml:69
+msgid "devcp_edit_authors_option_empty"
+msgstr "----------------"
+
+#: views/developers/addon_edit_authors.thtml:86
+msgid "devcp_edit_authors_select_role"
+msgstr "Roghnaigh ról an údair:"
+
+#. Column name in a table.
+#: views/developers/addon_edit_authors.thtml:62
+msgid "devcp_edit_authors_th_author"
+msgstr "Údar"
+
+#. Column name in a table.
+#: views/developers/addon_edit_authors.thtml:64
+msgid "devcp_edit_authors_th_listed"
+msgstr "Liostaithe"
+
+#. Column name in a table.
+#: views/developers/addon_edit_authors.thtml:63
+msgid "devcp_edit_authors_th_role"
+msgstr "Ról"
+
+#: views/developers/addon_edit_authors.thtml:77
+msgid "devcp_edit_authors_update_author"
+msgstr "Nuashonraigh na húdair"
+
+#: views/developers/addon_edit_categories.thtml:99
+msgid "devcp_edit_categories_button_update"
+msgstr "Nuashonraigh Catagóirí"
+
+#: views/developers/addon_edit_categories.thtml:88
+#, fuzzy
+msgid "devcp_edit_categories_does_not_fit"
+msgstr "My add-on doesn't fit into any available categories."
+
+#. %s is the application name (Firefox, Thunderbird).
+#: views/developers/addon_edit_categories.thtml:61
+msgid "devcp_edit_categories_header_application"
+msgstr "Catagóirí %s"
+
+#: views/developers/addon_edit_categories.thtml:49
+msgid "devcp_edit_categories_header_manage"
+msgstr "Bainistigh Catagóirí an Bhreiseáin"
+
+#: views/developers/addon_edit_categories.thtml:91
+#, fuzzy
+msgid "devcp_edit_categories_hover"
+msgstr "Hover over a category to see its description."
+
+#. %s is the category number (1, 2, 3).
+#: views/developers/addon_edit_categories.thtml:67
+msgid "devcp_edit_categories_label_category_num"
+msgstr "Catagóir %s"
+
+#: views/developers/addon_edit_categories.thtml:94
+#: views/developers/addon_edit_categories.thtml:103
+#, fuzzy
+msgid "devcp_edit_categories_none_available"
+msgstr "No categories are available for this add-on type and application."
+
+#: views/developers/addon_edit_categories.thtml:86
+#, fuzzy
+msgid "devcp_edit_categories_other"
+msgstr ""
+"Place your add-on into this category only if it does not fit into any other "
+"available categories."
+
+#. %s is the application name (Firefox, Thunderbird).
+#: views/developers/addon_edit_categories.thtml:63
+msgid "devcp_edit_categories_select_application_categories"
+msgstr "Roghnaigh suas le trí chatagóir %s le haghaidh do bhreiseáin"
+
+#: views/developers/addon_edit.thtml:47
+#, fuzzy
+msgid "devcp_edit_dd_manage_authors"
+msgstr "Add or remove users that can manage this add-on."
+
+#: views/developers/addon_edit.thtml:49
+#, fuzzy
+msgid "devcp_edit_dd_manage_categories"
+msgstr ""
+"Select the relevant categories for each application your add-on supports."
+
+#: views/developers/addon_edit.thtml:51
+#, fuzzy
+msgid "devcp_edit_dd_manage_description"
+msgstr ""
+"Add and modify translations for your add-on's summary, description, end-user "
+"license, and privacy policy."
+
+#: views/developers/addon_edit.thtml:53
+msgid "devcp_edit_dd_manage_properties"
+msgstr "Athraigh an t-ainm, leathanach baile, deilbhín, nó bratacha eile."
+
+#: views/developers/addon_edit_descriptions.thtml:116
+msgid "devcp_edit_description_button_update"
+msgstr "Athraigh an Cur Síos"
+
+#: views/developers/addon_edit_descriptions.thtml:115
+#, fuzzy
+msgid "devcp_edit_description_correct_error"
+msgstr "Please correct the errors above indicated in red."
+
+#: views/developers/addon_edit_descriptions.thtml:51
+msgid "devcp_edit_descriptions_header"
+msgstr "Cuir an Cur Síos ar an mBreiseáin in Eagar"
+
+#: views/developers/addon_edit_descriptions.thtml:94
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_comments_description"
+msgstr ""
+"Any information end users may want to know that isn't necessarily applicable "
+"to the add-on summary or description. Common uses include listing known "
+"major bugs, information on how to report bugs, anticipated release date of a "
+"new version, etc."
+
+#: views/developers/addon_edit_descriptions.thtml:93
+msgid "devcp_edit_descriptions_transbox_comments_name"
+msgstr "Nótaí ón Fhorbróir"
+
+#: views/developers/addon_edit_descriptions.thtml:86
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_description_description"
+msgstr ""
+"The description of your add-on is a longer explanation of features, "
+"functionality, and other relevant information. It is displayed under the "
+"summary on the add-on's display page."
+
+#: views/developers/addon_edit_descriptions.thtml:85
+msgid "devcp_edit_descriptions_transbox_description_name"
+msgstr "Cur Síos ar an mBreiseán"
+
+#: views/developers/addon_edit_descriptions.thtml:103
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_eula_description"
+msgstr ""
+"If your add-on has an End-User License Agreement (EULA), please enter its "
+"text below. If set below, users will be required to agree to this before "
+"installing your add-on. Please note that a EULA is not the same as a code "
+"license such as GPL or MPL."
+
+#: views/developers/addon_edit_descriptions.thtml:102
+msgid "devcp_edit_descriptions_transbox_eula_name"
+msgstr "Comhaontú Ceadúnais Úsáideoir Deiridh"
+
+#: views/developers/addon_edit_descriptions.thtml:112
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_privacy_description"
+msgstr ""
+"If your add-on has a privacy policy, enter its text here. Your add-on's "
+"display page will display a link to the policy."
+
+#: views/developers/addon_edit_descriptions.thtml:111
+msgid "devcp_edit_descriptions_transbox_privacy_name"
+msgstr "Polasaí Príobháideachta"
+
+#: views/developers/addon_edit_descriptions.thtml:78
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_summary_description"
+msgstr ""
+"The summary is a short explanation of your add-on's basic functionality that "
+"is displayed in search and browse listings, as well as at the top of your "
+"add-on's display page. <strong>Limit of 250 characters.</strong>"
+
+#: views/developers/addon_edit_descriptions.thtml:77
+msgid "devcp_edit_descriptions_transbox_summary_name"
+msgstr "Achoimre an Bhreiseáin"
+
+#: views/developers/addon_edit.thtml:46
+msgid "devcp_edit_dt_manage_authors"
+msgstr "Bainistigh Údair an Bhreiseáin"
+
+#: views/developers/addon_edit.thtml:48
+msgid "devcp_edit_dt_manage_categories"
+msgstr "Bainistigh Catagóirí an Bhreiseáin"
+
+#: views/developers/addon_edit.thtml:50
+msgid "devcp_edit_dt_manage_descriptions"
+msgstr "Bainistigh Cur Síos ar an mBreiseán"
+
+#: views/developers/addon_edit.thtml:52
+msgid "devcp_edit_dt_manage_properties"
+msgstr "Bainistigh Airíonna an Bhreiseáin"
+
+#: views/developers/addon_edit_properties.thtml:170
+msgid "devcp_edit_label_externalsoftware"
+msgstr "Tá bogearraí seachtracha de dhíth ar an mbreiseán seo"
+
+#: views/developers/addon_edit_properties.thtml:205
+msgid "devcp_edit_label_locale_disambiguation"
+msgstr "Eolas Breise faoin Logchaighdeán"
+
+#: views/developers/addon_edit_properties.thtml:168
+msgid "devcp_edit_label_prerelease"
+msgstr "Réamhleagan é seo"
+
+#: views/developers/addon_edit_properties.thtml:169
+msgid "devcp_edit_label_sitespecific"
+msgstr "Breiseán sainiúil do shuíomh é seo"
+
+#: views/developers/addon_edit_properties.thtml:202
+msgid "devcp_edit_label_target_locale"
+msgstr "Logchaighdeán Sprice"
+
+#: views/developers/addon_edit_properties.thtml:212
+msgid "devcp_edit_properties_button_update"
+msgstr "Nuashonraigh Airíonna"
+
+#: views/developers/addon_edit_properties.thtml:198
+#, fuzzy
+msgid "devcp_edit_properties_change_guid"
+msgstr "Only change if you understand all of the consequences."
+
+#: views/developers/addon_edit_properties.thtml:109
+msgid "devcp_edit_properties_current_icon"
+msgstr "Deilbhín Reatha"
+
+#: views/developers/addon_edit_properties.thtml:85
+#, fuzzy
+msgid "devcp_edit_properties_default_locale"
+msgstr ""
+"An add-on's default locale is the main locale in which translations must be "
+"present. If translations for your add-on's descriptions are unavailable in a "
+"user's selected language, they will fall back to this default locale."
+
+#: views/developers/addon_edit_properties.thtml:167
+#, fuzzy
+msgid "devcp_edit_properties_flags"
+msgstr "These flags are used to filter and classify add-ons."
+
+#: views/developers/addon_edit_properties.thtml:174
+#, fuzzy
+msgid "devcp_edit_properties_guid"
+msgstr ""
+"The GUID of your add-on is specified in its install.rdf and uniquely "
+"identifies it. You cannot change your GUID once it is listed on Mozilla Add-"
+"ons."
+
+#: views/developers/addon_edit_properties.thtml:53
+msgid "devcp_edit_properties_header"
+msgstr "Cuir Airíonna an Bhreiseáin in Eagar"
+
+#: views/developers/addon_edit_properties.thtml:186
+msgid "devcp_edit_properties_header_addon_type"
+msgstr "Cineál an Bhreiseáin"
+
+#: views/developers/addon_edit_properties.thtml:181
+msgid "devcp_edit_properties_header_admin_settings"
+msgstr "Socruithe Riaracháin"
+
+#: views/developers/addon_edit_properties.thtml:84
+msgid "devcp_edit_properties_header_default_locale"
+msgstr "Logchaighdeán Réamhshocraithe"
+
+#: views/developers/addon_edit_properties.thtml:166
+msgid "devcp_edit_properties_header_flags"
+msgstr "Bratacha an Bhreiseáin"
+
+#: views/developers/addon_edit_properties.thtml:173
+#: views/developers/addon_edit_properties.thtml:197
+msgid "devcp_edit_properties_header_guid"
+msgstr "GUID an Bhreiseáin"
+
+#: views/developers/addon_edit_properties.thtml:104
+msgid "devcp_edit_properties_header_icon"
+msgstr "Deilbhín an Bhreiseáin"
+
+#: views/developers/addon_edit_properties.thtml:159
+msgid "devcp_edit_properties_header_other_settings"
+msgstr "Socruithe Eile"
+
+#. A header on the admin page to toggle trusted status.
+#: views/developers/addon_edit_properties.thtml:182
+msgid "devcp_edit_properties_header_trusted"
+msgstr "Breiseán Iontaofa?"
+
+#: views/developers/addon_edit_properties.thtml:160
+msgid "devcp_edit_properties_header_view_source"
+msgstr "Féach ar an bhfoinse ar líne"
+
+#. %s is a comma-separated list of image extensions ".png, .jpg"
+#: views/developers/addon_edit_properties.thtml:106
+#, fuzzy
+msgid "devcp_edit_properties_icon"
+msgstr ""
+"The add-on icon is a small image that is displayed next to your add-on's "
+"name in browse and search results, display pages, and in the add-on "
+"installation dialog. The image will automatically be resized to 32 x 32 "
+"pixels. Please use one of the following image types: %s"
+
+#: views/developers/addon_edit_properties.thtml:171
+#, fuzzy
+msgid "devcp_edit_properties_label_binary"
+msgstr "This add-on contains binary components"
+
+#: views/developers/addon_edit_properties.thtml:185
+msgid "devcp_edit_properties_label_not_trusted"
+msgstr "Neamhiontaofa"
+
+#: views/developers/addon_edit_properties.thtml:184
+msgid "devcp_edit_properties_label_trusted"
+msgstr "Iontaofa"
+
+#: views/developers/addon_edit_properties.thtml:110
+msgid "devcp_edit_properties_new_icon"
+msgstr "Deilbhín Nua"
+
+#: views/developers/addon_edit_properties.thtml:118
+msgid "devcp_edit_properties_remove_icon"
+msgstr "Bain Deilbhín"
+
+#: views/developers/addon_edit_properties.thtml:136
+#, fuzzy
+msgid "devcp_edit_properties_transbox_homepage_description"
+msgstr ""
+"If your add-on has another homepage, enter its address here. Adding other "
+"translations is not necessary unless your website is localized into other "
+"languages."
+
+#: views/developers/addon_edit_properties.thtml:135
+msgid "devcp_edit_properties_transbox_homepage_name"
+msgstr "Leathanach Baile an Bhreiseáin"
+
+#: views/developers/addon_edit_properties.thtml:79
+#, fuzzy
+msgid "devcp_edit_properties_transbox_name_description"
+msgstr "The name of your add-on is displayed everywhere your add-on is listed."
+
+#: views/developers/addon_edit_properties.thtml:78
+msgid "devcp_edit_properties_transbox_name_name"
+msgstr "Ainm an Bhreiseáin"
+
+#: views/developers/addon_edit_properties.thtml:145
+#, fuzzy
+msgid "devcp_edit_properties_transbox_supportemail_description"
+msgstr ""
+"If you have an email address for support inquiries, enter it here. Adding "
+"other translations is not necessary unless you have different email "
+"addresses for different languages."
+
+#: views/developers/addon_edit_properties.thtml:144
+#, fuzzy
+msgid "devcp_edit_properties_transbox_supportemail_name"
+msgstr "Support Email Address"
+
+#: views/developers/addon_edit_properties.thtml:154
+#, fuzzy
+msgid "devcp_edit_properties_transbox_supporturl_description"
+msgstr ""
+"If your add-on has a support website or forum, enter its address here. "
+"Adding other translations is not necessary unless your website is localized "
+"into other languages."
+
+#: views/developers/addon_edit_properties.thtml:153
+#, fuzzy
+msgid "devcp_edit_properties_transbox_supporturl_name"
+msgstr "Support Website"
+
+#: views/developers/addon_edit_properties.thtml:183
+#, fuzzy
+msgid "devcp_edit_properties_trusted"
+msgstr "Trusted add-ons can become public without Editor review."
+
+#. %s is href="..." and should stay in the <a> tag.
+#: views/developers/addon_edit_properties.thtml:119
+msgid "devcp_edit_properties_undelete"
+msgstr "Scriosfar an deilbhín nuair a shábhálfaidh tú. <a %s>Cealaigh?</a>"
+
+#: views/developers/addon_edit_properties.thtml:161
+#, fuzzy
+msgid "devcp_edit_properties_view_source"
+msgstr ""
+"The source of your add-on files can be viewed online by any logged in user "
+"if you wish."
+
+#: views/developers/addon_edit_properties.thtml:162
+msgid "devcp_edit_properties_view_source_allow"
+msgstr "Ceadaigh d'úsáideoirí na comhaid fhoinseacha a fheiceáil ar líne"
+
+#: views/developers/addon_edit_properties.thtml:163
+msgid "devcp_edit_properties_view_source_do_not_allow"
+msgstr "Ná ceadaigh d'úsáideoirí na comhaid fhoinseacha a fheiceáil ar líne"
+
+#: views/elements/developers/editbox.thtml:46
+msgid "devcp_editbox_authors"
+msgstr "Údair"
+
+#: views/elements/developers/editbox.thtml:47
+msgid "devcp_editbox_categories"
+msgstr "Catagóirí"
+
+#: views/elements/developers/editbox.thtml:52
+msgid "devcp_editbox_change_status"
+msgstr "Athraigh Stádas"
+
+#: views/elements/developers/editbox.thtml:48
+msgid "devcp_editbox_descriptions"
+msgstr "Cur Síos"
+
+#: views/elements/developers/editbox.thtml:43
+msgid "devcp_editbox_edit_addon"
+msgstr "Cuir Breiseán in Eagar"
+
+#: views/elements/developers/editbox.thtml:57
+msgid "devcp_editbox_new_version"
+msgstr "Leagan Nua"
+
+#: views/elements/developers/editbox.thtml:49
+msgid "devcp_editbox_properties"
+msgstr "Airíonna"
+
+#: views/elements/developers/editbox.thtml:60
+#, fuzzy
+msgid "devcp_editbox_screenshots"
+msgstr "Preview Screenshots"
+
+#: views/elements/developers/editbox.thtml:53
+msgid "devcp_editbox_statistics_dashboard"
+msgstr "Painéal na Staitisticí"
+
+#: views/elements/developers/editbox.thtml:54
+msgid "devcp_editbox_versions"
+msgstr "Leaganacha agus Comhaid"
+
+#: views/elements/developers/editbox.thtml:42
+#, fuzzy
+msgid "devcp_editbox_view_listing"
+msgstr "View Listing"
+
+#: views/elements/developers/editorsmenu.thtml:59
+msgid "devcp_editorsqueue_featured"
+msgstr "Breiseáin Mhór-Le-Rá"
+
+# %1 is the review count
+#. %1 is the review count
+#: views/elements/developers/editorsqueue.thtml:42
+#: views/elements/developers/editorsmenu.thtml:56
+#, php-format
+msgid "devcp_editorsqueue_moderatedreviews"
+msgid_plural "devcp_editorsqueue_moderatedreviews"
+msgstr[0] "Léirmheasanna Iniúchta (%s)"
+msgstr[1] "Léirmheasanna Iniúchta (%s)"
+msgstr[2] "Léirmheasanna Iniúchta (%s)"
+msgstr[3] "Léirmheasanna Iniúchta (%s)"
+msgstr[4] "Léirmheasanna Iniúchta (%s)"
+
+# %1 is the nominated addons count
+#. %1 is the nominated addons count
+#: views/elements/developers/editorsqueue.thtml:44
+#: views/elements/developers/editorsmenu.thtml:58
+#, php-format
+msgid "devcp_editorsqueue_nominated"
+msgid_plural "devcp_editorsqueue_nominated"
+msgstr[0] "Breiseáin Ainmnithe (%s)"
+msgstr[1] "Breiseáin Ainmnithe (%s)"
+msgstr[2] "Breiseáin Ainmnithe (%s)"
+msgstr[3] "Breiseáin Ainmnithe (%s)"
+msgstr[4] "Breiseáin Ainmnithe (%s)"
+
+# %1 is the update count
+#. %1 is the update count
+#: views/elements/developers/editorsqueue.thtml:43
+#: views/elements/developers/editorsmenu.thtml:57
+#, php-format
+msgid "devcp_editorsqueue_pendingupdates"
+msgid_plural "devcp_editorsqueue_pendingupdates"
+msgstr[0] "Nuashonruithe Ar Feitheamh (%s)"
+msgstr[1] "Nuashonruithe Ar Feitheamh (%s)"
+msgstr[2] "Nuashonruithe Ar Feitheamh (%s)"
+msgstr[3] "Nuashonruithe Ar Feitheamh (%s)"
+msgstr[4] "Nuashonruithe Ar Feitheamh (%s)"
+
+#: controllers/statistics_controller.php:147
+#: controllers/statistics_controller.php:361
+#: controllers/previews_controller.php:108
+#: controllers/previews_controller.php:211
+#: controllers/previews_controller.php:312
+msgid "devcp_error_addon_access_denied"
+msgstr "Níl rochtain agat ar an mbreiseán sin."
+
+#. %s is a complete URL with the text from devcp_error_appversion_reference_link_text
+#. in the <a> tag. This should be fixed.
+#: controllers/components/developers.php:591
+#, php-format
+msgid "devcp_error_appversion_reference_link"
+msgstr "Féach ar %s mar thagairt."
+
+#. This is the link text in the <a> for devcp_error_appversion_reference_link. This
+#. should be fixed.
+#: controllers/components/developers.php:591
+msgid "devcp_error_appversion_reference_link_text"
+msgstr "an leathanach seo"
+
+#: views/developers/addon_edit_authors.thtml:76
+msgid "devcp_error_empty_authors"
+msgstr "Ní mór úinéir amháin ar a laghad a bheith ag do bhreiseán."
+
+#. %1$s is the name of the file
+#: controllers/components/developers.php:658
+#, fuzzy
+msgid "devcp_error_file_exists"
+msgstr ""
+"A version of that add-on already exists. To replace it, you must delete the "
+"file %1$s first."
+
+#. %1$s is a file extension. Example: .exe
+#. %2$s is a comma separated list of extensions. Example: .xpi, .jar
+#: controllers/components/developers.php:355
+#, php-format
+msgid "devcp_error_file_extension"
+msgstr ""
+"Ní cheadaítear an iarmhír sin (%1$s) ar bhreiseán den chineál roghnaithe. Ba "
+"chóir duit ceann de na hiarmhíreanna seo a leanas a úsáid: %2$s"
+
+#: controllers/components/developers.php:64
+msgid "devcp_error_five_categories"
+msgstr "Ná roghnaigh níos mó ná cúig chatagóir."
+
+#: controllers/components/developers.php:526
+msgid "devcp_error_guid_application"
+msgstr "Tá aitheantas an bhreiseáin seo in úsáid cheana ag feidhmchlár eile."
+
+#: controllers/components/developers.php:337
+#: controllers/components/developers.php:389
+msgid "devcp_error_http_incomplete"
+msgstr "Aistriú neamhiomlán"
+
+#: controllers/components/developers.php:335
+#: controllers/components/developers.php:336
+#: controllers/components/developers.php:387
+#: controllers/components/developers.php:388
+msgid "devcp_error_http_maxupload"
+msgstr "Níos mó ná uasmhéid uasluchtaithe"
+
+#: controllers/components/developers.php:338
+#: controllers/components/developers.php:390
+msgid "devcp_error_http_nofile"
+msgstr "Níor uasluchtaíodh aon chomhad"
+
+#. %1$s is a file extension. Example: .exe
+#. %2$s is a comma separated list of extensions. Example: .xpi, .jar
+#: controllers/components/developers.php:401
+#, php-format
+msgid "devcp_error_icon_extension"
+msgstr ""
+"Ní cheadaítear an iarmhír sin (%1$s) ar dheilbhín. Ba chóir duit ceann de na "
+"hiarmhíreanna seo a leanas a úsáid: %2$s"
+
+#: controllers/developers_controller.php:504
+msgid "devcp_error_index_rdf_notfound"
+msgstr "Níl install.rdf ann."
+
+#: controllers/components/developers.php:601
+msgid "devcp_error_install_manifest"
+msgstr "Aimsíodh na hearráidí seo a leanas i install.rdf:"
+
+#: controllers/developers_controller.php:1463
+#, fuzzy
+msgid "devcp_error_invalid_addontype"
+msgstr "Tá aitheantas an bhreiseáin seo neamhbhailí: %s"
+
+#. %$1s is a version. Example: 3.1.1
+#. %$2s is an add-on name.
+#: controllers/components/developers.php:569
+#: controllers/components/developers.php:581
+#, php-format
+msgid "devcp_error_invalid_appversion"
+msgstr "Ní leagan bailí é %1$s le haghaidh %2$s"
+
+#. %s is a string
+#: controllers/components/developers.php:521
+#, php-format
+msgid "devcp_error_invalid_guid"
+msgstr "Tá aitheantas an bhreiseáin seo neamhbhailí: %s"
+
+#. %$1s is a version. Example: 3.1.1
+#. %$2s is an add-on name.
+#: controllers/components/developers.php:572
+#, php-format
+msgid "devcp_error_invalid_minversion"
+msgstr ""
+"Ní leagan bailí é %1$s le haghaidh %2$s: ní cheadaítear * i leagan íosta"
+
+#: controllers/components/developers.php:536
+msgid "devcp_error_invalid_version"
+msgstr ""
+"Uimhir neamhbhailí leagain ar an mbreiseán seo: féach ar an <a href=\"http://"
+"developer.mozilla.org/en/docs/Toolkit_version_format\">tsonraíocht</a>"
+
+#: controllers/components/developers.php:531
+msgid "devcp_error_invalid_version_spaces"
+msgstr ""
+"Uimhir neamhbhailí leagain ar an mbreiseán seo: ní cheadaítear spásanna sa "
+"leagan."
+
+#. %s is an error message from the parser.
+#: controllers/components/developers.php:501
+#, php-format
+msgid "devcp_error_manifest_parse"
+msgstr "Tharla an earráid seo a leanas agus install.rdf á pharsáil: %s"
+
+#: controllers/components/developers.php:373
+msgid "devcp_error_move_file"
+msgstr "Níorbh fhéidir an comhad a bhogadh"
+
+#. %s is the name of a file
+#: controllers/components/developers.php:650
+#: controllers/components/developers.php:662
+#: controllers/components/developers.php:667
+#: controllers/components/developers.php:727
+#: controllers/components/developers.php:738
+#: controllers/components/developers.php:743
+#, php-format
+msgid "devcp_error_moving_file"
+msgstr "Tharla earráid agus %s á bhogadh."
+
+#: controllers/components/developers.php:595
+msgid "devcp_error_mozilla_application"
+msgstr ""
+"Ní mór duit feidhmchlár bailí amháin de chuid Mozilla a chur ann ar a laghad."
+
+#: controllers/components/developers.php:516
+msgid "devcp_error_no_guid"
+msgstr ""
+"Níor aimsíodh aon aitheantas le haghaidh an bhreiseáin seo in install.rdf."
+
+#: controllers/components/developers.php:287
+msgid "devcp_error_no_platform"
+msgstr "Níor roghnaíodh ardán"
+
+#: controllers/components/developers.php:59
+msgid "devcp_error_one_category"
+msgstr "Roghnaigh catagóir amháin ar a laghad."
+
+#: controllers/components/developers.php:92
+msgid "devcp_error_one_user"
+msgstr "Ní mór údar amháin ar a laghad a bheith ag an mbreiseán seo."
+
+#. %1$s is a file extension. Example: .exe
+#. %2$s is a comma separated list of extensions. Example: .xpi, .jar
+#: controllers/components/developers.php:1081
+#, php-format
+msgid "devcp_error_preview_extension"
+msgstr ""
+"Ní cheadaítear an iarmhír sin (%1$s) ar réamhamharc. Ba chóir duit ceann de "
+"na hiarmhíreanna seo a leanas a úsáid: %2$s"
+
+#: controllers/components/developers.php:511
+msgid "devcp_error_updatekey"
+msgstr ""
+"Ní féidir le breiseáin updateKey a úsáid. Bain é seo ó install.rdf agus "
+"déan iarracht eile."
+
+#: controllers/components/developers.php:506
+msgid "devcp_error_updateurl"
+msgstr ""
+"Ní féidir le breiseáin updateURL seachtrach a úsáid. Bain é seo ó install."
+"rdf agus déan iarracht eile."
+
+#: controllers/developers_controller.php:465
+#: controllers/components/developers.php:271
+msgid "devcp_error_upload_file"
+msgstr "Uasluchtaigh comhad, le do thoil."
+
+#: views/developers/uploader.thtml:135
+msgid "devcp_input_upload_file"
+msgstr "Uasluchtaigh Comhad"
+
+#: views/pages/js_constants.js.thtml:89
+msgid "devcp_js_a_cancel"
+msgstr "Cealaigh"
+
+#: views/pages/js_constants.js.thtml:90
+#, fuzzy
+msgid "devcp_js_add_email"
+msgstr "Please enter the account email of the author you wish to add."
+
+#. alt text for a down-arrow image.
+#: views/pages/js_constants.js.thtml:81
+msgid "devcp_js_img_move_down"
+msgstr "Bog Síos"
+
+#. alt text for an up-arrow image.
+#: views/pages/js_constants.js.thtml:82
+msgid "devcp_js_img_move_up"
+msgstr "Bog Suas"
+
+#: views/pages/js_constants.js.thtml:91
+#, fuzzy
+msgid "devcp_js_img_remove_compat"
+msgstr "Remove Application Compatibility"
+
+#: views/pages/js_constants.js.thtml:86
+#, fuzzy
+msgid "devcp_js_input_list_author"
+msgstr "List as author in public listings"
+
+#: views/pages/js_constants.js.thtml:92
+#, fuzzy
+msgid "devcp_js_license_select"
+msgstr "Please select a license."
+
+#: views/pages/js_constants.js.thtml:93
+#, fuzzy
+msgid "devcp_js_license_text"
+msgstr "Please enter text for your license."
+
+#. <option> text in a <select> for Author role in an add-on.
+#: views/pages/js_constants.js.thtml:84
+msgid "devcp_js_option_developer"
+msgstr "Forbróir"
+
+#. <option> text in a <select> for Author role in an add-on.
+#: views/pages/js_constants.js.thtml:83
+msgid "devcp_js_option_owner"
+msgstr "Úinéir"
+
+#. <option> text in a <select> for Author role in an add-on.
+#: views/pages/js_constants.js.thtml:85
+msgid "devcp_js_option_viewer"
+msgstr "Breathnóir"
+
+#: views/pages/js_constants.js.thtml:88
+msgid "devcp_js_remove_author"
+msgstr "Bain Údar"
+
+#: views/pages/js_constants.js.thtml:87
+msgid "devcp_js_sure_remove"
+msgstr ""
+"An bhfuil tú <strong>cinnte</strong> gur mian leat an t-údar seo a bhaint?"
+
+#: views/pages/js_constants.js.thtml:77
+msgid "devcp_js_upload_alert"
+msgstr "Ní mór duit comhad a roghnú le huasluchtú."
+
+#. %1$s is an addon id, like 32.
+#. %2$s is a version number, like 3.5.
+#: controllers/components/developers.php:1212
+#, fuzzy
+msgid "devcp_license_existing"
+msgstr "Custom license for add-on %1$s v%2$s"
+
+#: views/elements/developers/localebox.thtml:44
+msgid "devcp_localebox_header_localizedfields"
+msgstr "Réimsí Logánaithe"
+
+# %1 is the default locale
+#. %1 is the default locale
+#: views/elements/developers/localebox.thtml:48
+#, php-format
+msgid "devcp_localebox_intro"
+msgstr ""
+"Taispeántar roinnt réimsí ar an leathanach seo i dteanga dhúchais an "
+"úsáideora. Roghnaigh logchaighdeán thíos chun mionsonraí do bhreiseáin a "
+"chur in eagar sa teanga sin. Mura bhfuil aistriúchán ar fáil, taispeánfar é "
+"sa teanga réamhshocraithe (%s)."
+
+#: views/elements/developers/sidebar.thtml:68
+#: views/elements/developers/myaddons.thtml:75
+msgid "devcp_myaddons_admincp_link"
+msgstr "Uirlisí Riaracháin"
+
+#: views/elements/developers/sidebar.thtml:65
+#: views/elements/developers/myaddons.thtml:72
+msgid "devcp_myaddons_editorcp_link"
+msgstr "Uirlisí Eagarthóra"
+
+#: views/elements/developers/myaddons.thtml:52
+msgid "devcp_myaddons_link"
+msgstr "Mo Chuid Breiseán"
+
+#: views/elements/developers/sidebar.thtml:70
+#: views/elements/developers/myaddons.thtml:77
+msgid "devcp_myaddons_mainpage_link"
+msgstr "Ar ais go dtí an Príomhleathanach"
+
+#: views/elements/developers/sidebar.thtml:63
+#: views/elements/developers/myaddons.thtml:70
+msgid "devcp_myaddons_statistics_link"
+msgstr "Painéal na Staitisticí"
+
+#: views/elements/developers/sidebar.thtml:62
+#: views/elements/developers/myaddons.thtml:69
+msgid "devcp_myaddons_submitaddon_link"
+msgstr "Seol Breiseán"
+
+#: views/elements/developers/sidebar.thtml:48
+#: views/elements/developers/myaddons.thtml:67
+msgid "devcp_myaddons_title"
+msgstr "Uirlisí Forbróra"
+
+#. %1$s is an add-on ID, perhaps 167.
+#. %2$s is a URL.
+#: controllers/developers_controller.php:256
+#, fuzzy
+msgid "devcp_new_addon_error"
+msgstr ""
+"This add-on ID (%1$s) already exists in the database. If this is your add-"
+"on, you can <a href=\"%2$s\">upload a new version</a>."
+
+#: views/developers/addon_status_nominate.thtml:62
+msgid "devcp_nominate_cancel"
+msgstr "Cealaigh agus téigh ar ais"
+
+# %1 is the addon name
+#. %1 is the add-on name
+#: views/developers/addon_status_nominate.thtml:61
+#, php-format
+msgid "devcp_nominate_submit_nominate"
+msgstr "Ainmnigh %s"
+
+#: views/developers/addon_edit_properties.thtml:50
+#: views/developers/addon_status.thtml:49
+#: views/developers/versions_edit.thtml:50
+#, fuzzy
+msgid "devcp_notice_changes_error"
+msgstr ""
+"<span>One or more of your changes couldn't be saved.</span><br />Please look "
+"for the errors below. The rest of your changes were successfully saved."
+
+#: views/developers/addon_edit_authors.thtml:47
+#: views/developers/addon_edit_properties.thtml:47
+#: views/developers/addon_status.thtml:46
+#: views/developers/addon_edit_descriptions.thtml:47
+#: views/developers/versions_edit.thtml:47
+#: views/developers/addon_edit_categories.thtml:46
+#, fuzzy
+msgid "devcp_notice_changes_saved"
+msgstr ""
+"<span>Your changes have been saved.</span><br />Please note that some "
+"changes may take several hours to appear in all areas of the website."
+
+#: controllers/previews_controller.php:252
+msgid "devcp_notice_cleardefault"
+msgstr ""
+"Má bhaineann tú é seo mar réamhamharc réamhshocraithe, roghnófar réamhamharc "
+"eile mar réamhshocrú go huathoibríoch."
+
+#: controllers/previews_controller.php:184
+#: controllers/previews_controller.php:251
+msgid "devcp_notice_makedefault"
+msgstr ""
+"Má dhéanann tú réamhamharc réamhshocraithe de seo, rachaidh sé in áit an "
+"réamhamhairc réamhshocraithe atá ann faoi láthair."
+
+#: views/developers/addon_edit_authors.thtml:70
+msgid "devcp_notice_unsaved_changes"
+msgstr "Tá athruithe gan sábháil agat."
+
+#: controllers/developers_controller.php:87
+#: controllers/developers_controller.php:97
+#: controllers/developers_controller.php:100
+#: controllers/previews_controller.php:67
+#: controllers/previews_controller.php:79
+#: controllers/previews_controller.php:82
+msgid "devcp_pagetitle"
+msgstr "Uirlisí Forbróra"
+
+#: controllers/previews_controller.php:103
+#: controllers/previews_controller.php:104
+msgid "devcp_preview_add_pagetitle"
+msgstr "Cuir Réamhamharc Leis"
+
+#: controllers/previews_controller.php:135
+msgid "devcp_preview_added_successfully"
+msgstr "Cuireadh an réamhamharc leis."
+
+#: controllers/previews_controller.php:323
+msgid "devcp_preview_deleted_successfully"
+msgstr "Scriosadh an réamhamharc."
+
+#: controllers/previews_controller.php:194
+#: controllers/previews_controller.php:195
+msgid "devcp_preview_edit_pagetitle"
+msgstr "Cuir an Réamhamharc in Eagar"
+
+#: controllers/previews_controller.php:237
+msgid "devcp_preview_updated_successfully"
+msgstr "Nuashonraíodh an réamhamharc."
+
+#: views/developers/previews.thtml:120
+msgid "devcp_previews_a_another"
+msgstr "Cuir Réamhamharc Eile Leis"
+
+#: views/developers/previews.thtml:96
+msgid "devcp_previews_a_delete"
+msgstr "Scrios an Réamhamharc"
+
+#: views/developers/previews.thtml:95
+msgid "devcp_previews_a_replace"
+msgstr "Ionadaigh an Réamhamharc"
+
+#: views/developers/previews.thtml:126
+msgid "devcp_previews_a_update"
+msgstr "Nuashonraigh na Réamhamhairc"
+
+#: views/developers/previews.thtml:115 views/developers/previews.thtml:124
+msgid "devcp_previews_add_new"
+msgstr "Cuir Réamhamharc Nua Leis"
+
+#. %s is a list of file extensions, e.g. ".png, .gif"
+#: views/developers/previews.thtml:116
+#, fuzzy
+msgid "devcp_previews_add_select"
+msgstr ""
+"Select an image to upload below. Images larger than the maximum size of 700 "
+"pixels wide by 525 pixels tall will be resized. Allowed file types: %s"
+
+#: views/developers/previews.thtml:121
+#, fuzzy
+msgid "devcp_previews_click_below"
+msgstr "Click Update Previews below to upload."
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/previews.thtml:102
+msgid "devcp_previews_click_update"
+msgstr ""
+"Cliceáil ar an gcnaipe 'Nuashonraigh Réamhamhairc' chun an íomhá seo a "
+"shábháil. (<a %s>Cealaigh?</a>)"
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/previews.thtml:107
+msgid "devcp_previews_error_message"
+msgstr ""
+"Scriosfar an réamhamharc seo nuair a chliceálfar ar 'Nuashonraigh "
+"Réamhamhairc' thíos. (<a %s>Cealaigh?</a>)"
+
+#: views/previews/add.thtml:45
+msgid "devcp_previews_filetype_info"
+msgstr ""
+"Úsáid an fhoirm thíos chun íomhá PNG, JPG, nó GIF de do bhreiseán a "
+"uasluchtú. Athrófar méid na híomhá go huathoibríoch má tá sé níos mó ná 700 "
+"picteilín ar leithead nó 525 picteilín in airde."
+
+#: views/previews/add.thtml:43
+msgid "devcp_previews_header_add"
+msgstr "Cuir Réamhamharc Leis"
+
+#: views/developers/previews.thtml:80
+msgid "devcp_previews_header_caption"
+msgstr "Fotheideal an Réamhamhairc"
+
+#: views/previews/edit.thtml:43
+msgid "devcp_previews_header_edit"
+msgstr "Cuir Réamhamharc in Eagar"
+
+#: views/developers/previews.thtml:93
+msgid "devcp_previews_label_default"
+msgstr "Réamhamharc Réamhshocraithe"
+
+#: views/previews/add.thtml:54
+msgid "devcp_previews_label_file"
+msgstr "Comhad Réamhamhairc"
+
+#: views/previews/add.thtml:59 views/previews/edit.thtml:50
+msgid "devcp_previews_label_makedefault"
+msgstr "Úsáid é seo mar réamhamharc réamhshocraithe"
+
+#: views/developers/previews.thtml:100
+msgid "devcp_previews_label_new"
+msgstr "Ãomhá nua:"
+
+#: views/developers/previews.thtml:118
+msgid "devcp_previews_label_upload"
+msgstr "Uasluchtaigh Réamhamharc: "
+
+#: views/developers/previews.thtml:50
+#, fuzzy
+msgid "devcp_previews_notice_error"
+msgstr "One or more of your new previews could not be saved."
+
+#: views/developers/previews.thtml:47
+msgid "devcp_previews_notice_success"
+msgstr "Nuashonraíodh do chuid réamhamharc."
+
+#: views/developers/previews.thtml:59
+#, fuzzy
+msgid "devcp_previews_p_screenshots"
+msgstr ""
+"The preview screenshots for your add-on are shown below. You can make "
+"changes to captions or images below. The Default Preview is the preview that "
+"is displayed next to your add-on in search and browse listings."
+
+#: views/previews/edit.thtml:55
+msgid "devcp_previews_submit_delete"
+msgstr "Scrios an Réamhamharc"
+
+#: views/previews/edit.thtml:55
+msgid "devcp_previews_submit_delete_confirm"
+msgstr "An bhfuil tú cinnte gur mian leat an réamhamharc seo a scriosadh?"
+
+#: views/previews/edit.thtml:54
+msgid "devcp_previews_submit_edit"
+msgstr "Cuir Réamhamharc in Eagar"
+
+#: views/previews/add.thtml:63
+msgid "devcp_previews_submit_upload"
+msgstr "Uasluchtaigh Réamhamharc"
+
+#: views/developers/previews.thtml:78
+msgid "devcp_previews_thumbnail"
+msgstr "Mionsamhail"
+
+#. %s is the add-on name.
+#: views/developers/previews.thtml:44
+msgid "devcp_previews_title"
+msgstr "Bainisteoir Réamhamharc %s"
+
+#: views/developers/uploader.thtml:74
+msgid "devcp_review_agreement_please"
+msgstr "Léigh an Comhaontú Forbróra seo agus glac leis."
+
+#: views/elements/developers/rolecheck.thtml:42
+#, fuzzy
+msgid "devcp_rolecheck_no_privs"
+msgstr ""
+"<span>You do not have sufficient privileges to make changes on this page.</"
+"span><br />Contact the Add-on Owner if you need to make changes."
+
+#: controllers/developers_controller.php:1315
+#, fuzzy
+msgid "devcp_several_hours"
+msgstr ""
+"Please note that some changes may take several hours to appear in all areas "
+"of the website."
+
+#: views/elements/developers/sidebar.thtml:52
+msgid "devcp_sidebar_a_dashboard"
+msgstr "Painéal"
+
+#. %s is a number
+#: views/elements/developers/statsbar.thtml:45
+#: views/developers/dashboard.thtml:79
+#, php-format
+msgid "devcp_statsbar_adu"
+msgstr "<em>%s</em> Úsáideoir Gníomhach Laethúil"
+
+#. %s is a number
+#: views/elements/developers/statsbar.thtml:41
+#: views/developers/dashboard.thtml:75
+#, php-format
+msgid "devcp_statsbar_total_downloads"
+msgstr "<em>%s</em> Ãosluchtú Go hIomlán"
+
+#. %s is a number
+#: views/elements/developers/statsbar.thtml:43
+#: views/developers/dashboard.thtml:77
+#, php-format
+msgid "devcp_statsbar_weekly_downloads"
+msgstr "<em>%s</em> Ãosluchtú sa tSeachtain"
+
+#: views/developers/addon_status_confirm.thtml:59
+#, fuzzy
+msgid "devcp_status_confirm_active"
+msgstr ""
+"Marking this add-on active will cause it to show up in public areas "
+"appropriate for its status, including search and browse listings. It will be "
+"downloadable from the website and could be returned in client update checks, "
+"depending on its status. You will be able to return here and disable it "
+"again at your convenience."
+
+#: views/developers/addon_status_confirm.thtml:59
+#, fuzzy
+msgid "devcp_status_confirm_active_sure"
+msgstr "Are you sure you wish to mark this add-on active?"
+
+#: views/developers/addon_status_confirm.thtml:50
+msgid "devcp_status_confirm_header_sure"
+msgstr "An bhfuil tú cinnte?"
+
+#: views/developers/addon_status_confirm.thtml:55
+#, fuzzy
+msgid "devcp_status_confirm_inactive"
+msgstr ""
+"Marking this add-on inactive will prevent it from showing up in any public "
+"areas, including search and browse listings. It will not be downloadable "
+"from the website and will not be returned in client update checks. You will "
+"be able to return here and re-enable it at your convenience."
+
+#: views/developers/addon_status_confirm.thtml:55
+#, fuzzy
+msgid "devcp_status_confirm_inactive_sure"
+msgstr "Are you sure you wish to mark this add-on inactive?"
+
+#: views/developers/addon_status_confirm.thtml:74
+msgid "devcp_status_confirm_no"
+msgstr "Níl, cealaigh"
+
+#: views/developers/addon_status_confirm.thtml:67
+#, fuzzy
+msgid "devcp_status_confirm_public"
+msgstr ""
+"Making this add-on public will make it available for anyone to download and "
+"will begin offering updates to existing users."
+
+#: views/developers/addon_status_confirm.thtml:67
+msgid "devcp_status_confirm_public_sure"
+msgstr "An bhfuil tú cinnte gur mian leat an breiseán seo a fhoilsiú?"
+
+#: views/developers/addon_status_confirm.thtml:63
+#, fuzzy
+msgid "devcp_status_confirm_sandbox"
+msgstr ""
+"Moving this add-on back to the sandbox will require users to log in before "
+"downloading and updates will no longer be offered to existing users. Because "
+"your add-on is currently public, you will be able to return here at any time "
+"to make it public again."
+
+#: views/developers/addon_status_confirm.thtml:63
+msgid "devcp_status_confirm_sandbox_sure"
+msgstr ""
+"An bhfuil tú cinnte gur mian leat an breiseán seo a bhogadh go dtí an bosca "
+"gainimh?"
+
+#: views/developers/addon_status_confirm.thtml:73
+msgid "devcp_status_confirm_yes"
+msgstr "Táim Cinnte"
+
+#: views/developers/addon_status_nominate.thtml:46
+#, fuzzy
+msgid "devcp_status_nominate_error_notice"
+msgstr ""
+"<span>A nomination message is required.</span><br />Please fill in the text "
+"box with the requested information and try again."
+
+#: views/developers/addon_status_nominate.thtml:55
+msgid "devcp_status_nominate_header"
+msgstr "Ainmniú an Bhreiseáin"
+
+#: views/developers/dashboard.thtml:85
+msgid "devcp_summary_lastversion"
+msgstr "Leagan Is Déanaí:"
+
+#. %s is the add-on name.
+#: views/developers/addon_edit.thtml:43
+#: views/developers/addon_edit_authors.thtml:44
+#: views/developers/versions_delete.thtml:43
+#: views/developers/addon_edit_properties.thtml:44
+#: views/developers/addon_edit_descriptions.thtml:44
+#: views/developers/versions_edit.thtml:44
+#: views/developers/addon_edit_categories.thtml:43
+#: views/developers/versions.thtml:43
+msgid "devcp_title_edit_addon"
+msgstr "Cuir %s in Eagar"
+
+#. title attribute for a javascript link that pops up a help dialog.
+#: views/elements/translationbox.thtml:68
+msgid "devcp_transbox_a_title_help"
+msgstr "Cabhair (ná fág an leathanach)"
+
+#: views/elements/translationbox.thtml:68
+msgid "devcp_transbox_alt_help"
+msgstr "Cabhair"
+
+#. %1$s is <span>17</span>, %2$s is 42.
+#: views/elements/translationbox.thtml:101
+msgid "devcp_transbox_chars_used"
+msgstr "Carachtair a úsáideadh: %1$s / %2$s"
+
+#: views/elements/translationbox.thtml:132
+msgid "devcp_transbox_delete_sure"
+msgstr ""
+"An bhfuil tú cinnte go dteastaíonn uait an t-aistriúchán seo a scriosadh?"
+
+#. %s is a locale, like en-US.
+#: views/elements/translationbox.thtml:143
+msgid "devcp_transbox_help_header_tabs"
+msgstr "Cad iad na cluaisíní %s seo?"
+
+#: views/elements/translationbox.thtml:145
+msgid "devcp_transbox_help_header_what"
+msgstr "Cad é mura bhfuil aon aistriúcháin agam?"
+
+#: views/elements/translationbox.thtml:147
+msgid "devcp_transbox_help_hide"
+msgstr "Folaigh an Chabhair"
+
+#: views/elements/translationbox.thtml:146
+#, fuzzy
+msgid "devcp_transbox_help_if"
+msgstr ""
+"If a user browses the site and a translation isn't available in their own "
+"language, it will fall back to your add-on's Default Locale, specified in "
+"the Edit Add-on Properties area. If you don't have any translations, just "
+"enter what you can into your Default Locale, which should be a language you "
+"speak."
+
+#: views/elements/translationbox.thtml:144
+#, fuzzy
+msgid "devcp_transbox_help_transbox"
+msgstr ""
+"This is a <i>Translation Box</i>. It allows you to localize a specific field "
+"into any other languages for which you might have a translation. You can "
+"add, edit, and remove translations using the locale tabs."
+
+#: views/elements/translationbox.thtml:85
+msgid "devcp_transbox_img_add_trans"
+msgstr "Cuir Aistriúchán Leis"
+
+#: views/elements/translationbox.thtml:86
+msgid "devcp_transbox_img_remove_trans"
+msgstr "Bain Aistriúchán"
+
+#: views/elements/translationbox.thtml:123
+#, fuzzy
+msgid "devcp_transbox_input_add_all"
+msgstr "Add Locale to All"
+
+#: views/elements/translationbox.thtml:122
+msgid "devcp_transbox_input_add_locale"
+msgstr "Cuir Logchaighdeán Leis"
+
+#: views/elements/translationbox.thtml:124
+#: views/elements/translationbox.thtml:135
+msgid "devcp_transbox_input_cancel"
+msgstr "Cealaigh"
+
+#: views/elements/translationbox.thtml:134
+msgid "devcp_transbox_input_delete"
+msgstr "Scrios É"
+
+#: views/elements/translationbox.thtml:113
+msgid "devcp_transbox_select_locale"
+msgstr "Roghnaigh logchaighdeán an aistriúcháin le cur leis:"
+
+#. %1$s and %2$s are GUIDs.
+#: controllers/developers_controller.php:343
+#, fuzzy
+msgid "devcp_update_addon_guid_error"
+msgstr ""
+"The add-on GUID used in this file (%1$s) does not match the existing GUID "
+"for this add-on (%2$s)."
+
+#: controllers/developers_controller.php:334
+msgid "devcp_update_addon_priv_error"
+msgstr "Níl cead agat an breiseán seo a nuashonrú."
+
+#. %1$s is a version number, %2$s is an add-on ID.
+#: controllers/developers_controller.php:399
+#, fuzzy
+msgid "devcp_update_addon_version_belong_error"
+msgstr "The specified version (%1$s) does not belong to this add-on (%2$s)."
+
+#. %1$s is a version number, maybe 1.1.
+#. %2$s is a URL.
+#: controllers/developers_controller.php:351
+#, fuzzy
+msgid "devcp_update_addon_version_exists_error"
+msgstr ""
+"The version number uploaded (%1$s) already exists for this add-on. If you "
+"are trying to add another file to this version, <a href=\"%2$s\">click here</"
+"a>."
+
+#. %1$s and %2$s are version numbers.
+#: controllers/developers_controller.php:405
+#, fuzzy
+msgid "devcp_update_addon_version_match_error"
+msgstr ""
+"The uploaded version number (%1$s) does not match the existing version "
+"number (%2$s)."
+
+#: views/developers/uploader.thtml:68
+msgid "devcp_uploader_a_start"
+msgstr "Tús Maith"
+
+#: views/developers/uploader.thtml:137
+msgid "devcp_uploader_ajax_loading"
+msgstr "Comhad á uasluchtú..."
+
+#: views/developers/uploader.thtml:82
+#, fuzzy
+msgid "devcp_uploader_button_agree"
+msgstr "Agree and continue"
+
+#: views/developers/uploader.thtml:157
+msgid "devcp_uploader_button_edit"
+msgstr "Cuir Mo Bhreiseán in Eagar"
+
+#: views/developers/uploader.thtml:158
+msgid "devcp_uploader_button_later"
+msgstr "Críochnóidh mé mo bhreiseán ar ball."
+
+#: views/developers/uploader.thtml:168
+msgid "devcp_uploader_button_release"
+msgstr "Cuir Nótaí Eisiúna Leis"
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/uploader.thtml:156
+#, fuzzy
+msgid "devcp_uploader_created_results"
+msgstr ""
+"<p>Your add-on listing has been successfully created. The basic information "
+"obtained from your uploaded file has been stored, but there's a lot more to "
+"your listing that can be customized.</p><p>Your add-on is currently marked "
+"as <strong>Incomplete</strong>. In order to complete your add-on, you'll "
+"need to make sure it has an accurate name, summary, and description, as well "
+"as at least one selected category. You can edit your add-on's information "
+"using the link below and check the status of your add-on at any time on the "
+"<a %s>status page</a>."
+
+#: views/developers/uploader.thtml:143
+msgid "devcp_uploader_error_correct"
+msgstr "Réitigh an fhadhb seo agus uasluchtaigh do chomhad arís."
+
+#. %1$s is a version number, %2$s is a status, e.g Public or Incomplete.
+#: views/developers/uploader.thtml:175
+#, fuzzy
+msgid "devcp_uploader_file_created"
+msgstr ""
+"Your new file has been added to version %1$s and is currently marked as %2$s."
+
+#: views/developers/uploader.thtml:154
+msgid "devcp_uploader_header_created"
+msgstr "Cruthaíodh an Breiseán!"
+
+#: views/developers/uploader.thtml:141
+msgid "devcp_uploader_header_error"
+msgstr "Úps! Dealraíonn sé go bhfuil fadhb leis an gcomhad seo..."
+
+#: views/developers/uploader.thtml:173
+msgid "devcp_uploader_header_file_added"
+msgstr "Cuireadh an Comhad Leis!"
+
+#: views/developers/uploader.thtml:66
+msgid "devcp_uploader_header_how"
+msgstr "Conas a oibríonn sé?"
+
+#. %s is the version number, e.g. 3.2.
+#: views/developers/uploader.thtml:163
+msgid "devcp_uploader_header_update_created"
+msgstr "Cruthaíodh Leagan %s"
+
+#: views/developers/uploader.thtml:117
+msgid "devcp_uploader_header_upload"
+msgstr "Uasluchtaigh Do Chomhad"
+
+#: views/developers/uploader.thtml:67
+#, fuzzy
+msgid "devcp_uploader_how"
+msgstr ""
+"<p>Thanks for your interest in submitting your add-on to Mozilla Add-ons. "
+"Hosting your add-on on Mozilla Add-ons is the easiest way to handle "
+"distribution of your add-on. Here's what you'll get:</p><ul><li>Each add-on "
+"will have a public display page with information you provide, such as a "
+"brief summary of the add-on's functionality, an optional longer description, "
+"and a showcase of preview screenshots of your add-on.</li><li>Your add-on "
+"will appear in search and browse listings across the site, and even in the "
+"Add-ons Manager of Firefox 3.</li><li>We'll take care of hosting all of your "
+"downloads and providing automatic updates to users when you upload a new "
+"version.</li><li>You'll have access to a statistics dashboard with detailed "
+"information about your user base.</li></ul><p>Add-ons hosted on the site "
+"must be reviewed by a Mozilla Add-ons Editor before they will have all of "
+"the features listed above. If you're ready to start the process and have "
+"your add-on package ready for upload, just click on Get Started below!</p>"
+
+#: views/developers/uploader.thtml:125
+msgid "devcp_uploader_label_platformtype"
+msgstr "Ardáin a dtacaítear leo:"
+
+#: views/developers/uploader.thtml:124
+msgid "devcp_uploader_label_upload_field"
+msgstr "Comhad Breiseáin: "
+
+#: controllers/components/developers.php:1221
+#, fuzzy
+msgid "devcp_uploader_option_other"
+msgstr "Other"
+
+#. %1$s is a number, %2$s is href="..." and should stay in the <a> tag.
+#: views/developers/uploader.thtml:176
+#, fuzzy
+msgid "devcp_uploader_p_pending_file"
+msgstr ""
+"The new file will be available to the public as soon as an editor is able to "
+"review it. There are currently %1$s other add-ons in the queue. Want to be "
+"reviewed faster? Consider <a %2$s>becoming an editor</a>."
+
+#. %1$s is a number, %2$s is href="..." and should stay in the <a> tag.
+#: views/developers/uploader.thtml:166
+#, fuzzy
+msgid "devcp_uploader_p_pending_version"
+msgstr ""
+"The new version will be available to the public as soon as an editor is able "
+"to review it. There are currently %1$s other add-ons in the queue. Want to "
+"be reviewed faster? Consider <a %2$s>becoming an editor</a>."
+
+#. %s is a status, e.g Public or Incomplete.
+#: views/developers/uploader.thtml:165
+#, fuzzy
+msgid "devcp_uploader_p_update_created"
+msgstr "Your new version has been created and is currently marked as %s."
+
+#. %1$s is href="..." and should stay in the 'Versions and Files' <a> tag.
+#. %2$s is href="..." and should stay in the 'current status' <a> tag.
+#: views/developers/uploader.thtml:177
+#, fuzzy
+msgid "devcp_uploader_p_update_file"
+msgstr ""
+"View your new file in the <a %1$s>Versions and Files page</a>, check out "
+"your add-on's <a %2$s>current status</a>, or <b>add release notes</b> by "
+"clicking the button below (highly recommended)."
+
+#. %1$s is href="..." and should stay in the 'Versions and Files' <a> tag.
+#. %2$s is href="..." and should stay in the 'current status' <a> tag.
+#: views/developers/uploader.thtml:167
+#, fuzzy
+msgid "devcp_uploader_p_update_version"
+msgstr ""
+"View your new version in the <a %1$s>Versions and Files page</a>, check out "
+"your add-on's <a %2$s>current status</a>, or <b>add release notes</b> by "
+"clicking the button below (highly recommended)."
+
+#: views/developers/uploader.thtml:118
+#, fuzzy
+msgid "devcp_uploader_p_upload"
+msgstr ""
+"Upload your add-on file using the form below. If you have multiple, platform-"
+"specific files to upload, choose a single file and then upload the others "
+"using the Versions and Files Manager."
+
+#: views/developers/uploader.thtml:125
+msgid "devcp_uploader_platformtype_all"
+msgstr "Uile"
+
+#: views/developers/uploader.thtml:126
+msgid "devcp_uploader_platformtype_specific"
+msgstr "Sainiúil:"
+
+#. Used as first item in a <select>.
+#: controllers/components/developers.php:1185
+#, fuzzy
+msgid "devcp_uploader_please_choose"
+msgstr "Please Choose..."
+
+#. %1$s is the add-on name, %2$s is the version number.
+#: views/developers/uploader.thtml:57
+msgid "devcp_uploader_title_file"
+msgstr "Cuir an Comhad le %1$s %2$s"
+
+#: views/developers/uploader.thtml:50
+msgid "devcp_uploader_title_submit"
+msgstr "Seol Breiseán Nua"
+
+#. %s is the add-on name.
+#: views/developers/uploader.thtml:54
+msgid "devcp_uploader_title_update"
+msgstr "Nuashonraigh %s"
+
+#. %s is a full <a> tag
+#: controllers/developers_controller.php:503
+#, php-format
+msgid "devcp_valid_app_reference"
+msgstr "Féach ar %s mar thagairt."
+
+#. This is the text in the <a> tag for devcp_valid_app_reference. This should be
+#. fixed.
+#: controllers/developers_controller.php:503
+msgid "devcp_valid_app_reference_linktext"
+msgstr "an leathanach seo"
+
+#: controllers/developers_controller.php:581
+#, fuzzy
+msgid "devcp_verify_author_error"
+msgstr "No account found for that email address."
+
+#: controllers/developers_controller.php:553
+#, fuzzy
+msgid "devcp_verify_search_engine_error"
+msgstr ""
+"Either the XML is invalid or required fields are missing. Please <a href="
+"\"https://developer.mozilla.org/en/Creating_OpenSearch_plugins_for_Firefox"
+"\">read the documentation</a>, verify your add-on, and try again."
+
+#: views/developers/versions.thtml:75
+msgid "devcp_versions_a_cancel"
+msgstr "Cealaigh"
+
+#: views/developers/versions.thtml:79
+msgid "devcp_versions_a_delete"
+msgstr "Scrios Leagan"
+
+#: views/developers/versions.thtml:74
+msgid "devcp_versions_a_empty"
+msgstr "Bain Leagan Folamh"
+
+#: views/developers/versions.thtml:71
+msgid "devcp_versions_a_remove"
+msgstr "Bain?"
+
+#: views/developers/versions.thtml:91
+msgid "devcp_versions_add"
+msgstr "Cuir Leagan Nua Leis"
+
+#: views/developers/versions_delete.thtml:58
+msgid "devcp_versions_delete_a_cancel"
+msgstr "Cealaigh"
+
+#: views/developers/versions_delete.thtml:56
+msgid "devcp_versions_delete_a_delete"
+msgstr "Scrios Leagan"
+
+#. Followed by a list of reviews and files that will be removed.
+#: views/developers/versions_delete.thtml:50
+msgid "devcp_versions_delete_also"
+msgstr "Scriosfar iad seo freisin:"
+
+#: views/developers/versions_delete.thtml:53
+msgid "devcp_versions_delete_files"
+msgid_plural "devcp_versions_delete_files"
+msgstr[0] "%s chomhad"
+msgstr[1] "%s chomhad"
+msgstr[2] "%s chomhad"
+msgstr[3] "%s gcomhad"
+msgstr[4] "%s comhad"
+
+#. %s is the version number.
+#: views/developers/versions_delete.thtml:48
+msgid "devcp_versions_delete_header"
+msgstr "An bhfuil fonn ort leagan %s a scriosadh?"
+
+#: views/developers/versions_delete.thtml:52
+msgid "devcp_versions_delete_reviews"
+msgid_plural "devcp_versions_delete_reviews"
+msgstr[0] "%s léirmheas"
+msgstr[1] "%s léirmheas"
+msgstr[2] "%s léirmheas"
+msgstr[3] "%s léirmheas"
+msgstr[4] "%s léirmheas"
+
+#. %s is the version number.
+#: views/developers/versions_delete.thtml:49
+msgid "devcp_versions_delete_sure"
+msgstr "An bhfuil tú cinnte gur mhaith leat an leagan %s a scriosadh go buan?"
+
+#: views/developers/versions_edit.thtml:102
+#: views/developers/versions_edit.thtml:155
+msgid "devcp_versions_edit_a_cancel"
+msgstr "Cealaigh"
+
+#: views/developers/versions_edit.thtml:101
+msgid "devcp_versions_edit_a_delete"
+msgstr "Scrios an Comhad"
+
+#: views/developers/versions_edit.thtml:165
+msgid "devcp_versions_edit_a_new_app"
+msgstr "Cuir Feidhmchlár Nua Leis"
+
+#: views/developers/versions_edit.thtml:154
+msgid "devcp_versions_edit_a_remove_app"
+msgstr "Bain Feidhmchlár"
+
+#: views/developers/versions_edit.thtml:114
+msgid "devcp_versions_edit_add"
+msgstr "Cuir Comhad Nua Leis"
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/versions_edit.thtml:121
+#, fuzzy
+msgid "devcp_versions_edit_adjust"
+msgstr ""
+"Adjusting application information here will allow users to install your add-"
+"on even if the install.rdf in the package indicates that the add-on is "
+"incompatible. <a %s>List of supported applications</a>"
+
+#: views/developers/versions_edit.thtml:153
+#, fuzzy
+msgid "devcp_versions_edit_compat_sure"
+msgstr ""
+"Are you <b>sure</b> you wish to remove compatibility with this application?"
+
+#: views/developers/versions_edit.thtml:100
+msgid "devcp_versions_edit_delete_sure"
+msgstr ""
+"An bhfuil tú <b>cinnte</b> gur mian leat an comhad seo a scriosadh go buan?"
+
+#: views/developers/versions_edit.thtml:203
+#, fuzzy
+msgid "devcp_versions_edit_header_approval"
+msgstr "Approval Information"
+
+#: views/developers/versions_edit.thtml:120
+msgid "devcp_versions_edit_header_compat"
+msgstr "Feidhmchláir Chomhoiriúnacha"
+
+#: views/developers/versions_edit.thtml:74
+msgid "devcp_versions_edit_header_file"
+msgstr "Eolas faoin Chomhad"
+
+#: views/developers/versions_edit.thtml:189
+#, fuzzy
+msgid "devcp_versions_edit_header_license"
+msgstr "License"
+
+#. %s is the version number.
+#: views/developers/versions_edit.thtml:53
+msgid "devcp_versions_edit_header_manage"
+msgstr "Bainistigh Leagan %s"
+
+#: views/developers/versions_edit.thtml:212
+#, fuzzy
+msgid "devcp_versions_edit_header_notes"
+msgstr "Approval Notes"
+
+#: views/developers/versions_edit.thtml:98
+msgid "devcp_versions_edit_img_delete"
+msgstr "Scrios an Comhad"
+
+#. %1$s is the file id, e.g. 18723.
+#. %2$s is the platform name, e.g. ALL or Windows.
+#. %3$s is the _('date) created.
+#. %4$s is the status, e.g. "In Sandbox" or "Public".
+#. %5$s is the _('date') status was changed.
+#: views/developers/versions_edit.thtml:208
+msgid "devcp_versions_edit_li_file"
+msgstr "Cruthaíodh comhad %1$s (%2$s) ar %3$s agus athraíodh é go %4$s ar %5$s"
+
+#: views/developers/versions_edit.thtml:190
+#, fuzzy
+msgid "devcp_versions_edit_license_description"
+msgstr ""
+"Please select the appropriate license for your add-on. This license "
+"specifies the rights you grant on your source code."
+
+#: views/developers/versions_edit.thtml:111
+msgid "devcp_versions_edit_no_files"
+msgstr "Níor aimsíodh comhaid."
+
+#: views/developers/versions_edit.thtml:213
+#, fuzzy
+msgid "devcp_versions_edit_optional"
+msgstr "Optional information for the Editor that reviews this version."
+
+#: views/developers/versions_edit.thtml:151
+#, fuzzy
+msgid "devcp_versions_edit_remove_compat"
+msgstr "Remove Application Compatibility"
+
+#: views/developers/versions_edit.thtml:167
+msgid "devcp_versions_edit_select_app"
+msgstr "Roghnaigh Feidhmchlár"
+
+#: views/developers/versions_edit.thtml:78
+msgid "devcp_versions_edit_th_file"
+msgstr "Comhad"
+
+#: views/developers/versions_edit.thtml:79
+msgid "devcp_versions_edit_th_platform"
+msgstr "Ardán"
+
+#: views/developers/versions_edit.thtml:80
+msgid "devcp_versions_edit_th_size"
+msgstr "Méid"
+
+#: views/developers/versions_edit.thtml:81
+msgid "devcp_versions_edit_th_status"
+msgstr "Stádas"
+
+#: views/developers/versions_edit.thtml:183
+#, fuzzy
+msgid "devcp_versions_edit_transbox_releasenotes_description"
+msgstr ""
+"Information about changes in this release, new features, known bugs, and "
+"other useful information specific to this release/version. This information "
+"will also be available to users updating the add-on in the Firefox 3 Add-ons "
+"Manager interface."
+
+#: views/developers/versions_edit.thtml:182
+msgid "devcp_versions_edit_transbox_releasenotes_name"
+msgstr "Nótaí Eisiúna"
+
+#: views/developers/versions_edit.thtml:164
+#, fuzzy
+msgid "devcp_versions_edit_unsaved_compat"
+msgstr ""
+"<strong>You have unsaved changes.</strong> Compatibility will not be deleted "
+"until you click Update Version below."
+
+#: views/developers/versions_edit.thtml:113
+#, fuzzy
+msgid "devcp_versions_edit_unsaved_files"
+msgstr ""
+"<strong>You have unsaved changes.</strong> Files will not be deleted until "
+"you click Update Version below."
+
+#: views/developers/versions_edit.thtml:218
+msgid "devcp_versions_edit_update"
+msgstr "Nuashonraigh Leaganacha"
+
+#: views/developers/versions.thtml:49
+msgid "devcp_versions_header_manage"
+msgstr "Bainistigh Leaganacha agus Comhaid"
+
+#: views/developers/versions.thtml:87
+msgid "devcp_versions_no_versions"
+msgstr "Gan leaganacha."
+
+#. %s is a version number, base 10.
+#: views/developers/versions.thtml:46
+msgid "devcp_versions_notice_success"
+msgstr "Scriosadh leagan %s."
+
+#: views/developers/versions.thtml:73
+#, fuzzy
+msgid "devcp_versions_p_remove"
+msgstr ""
+"This version has no files associated with it and can be removed. Would you "
+"like to remove this version?"
+
+#: views/developers/versions.thtml:58
+msgid "devcp_versions_th_created"
+msgstr "Cruthaithe"
+
+#: views/developers/versions.thtml:57
+msgid "devcp_versions_th_status"
+msgstr "Stádas"
+
+#: views/developers/versions.thtml:56
+msgid "devcp_versions_th_version"
+msgstr "Leagan"
+
+#: controllers/downloads_controller.php:91
+msgid "downloads_disable_warning"
+msgstr "Tá an breiseán seo díchumasaithe"
+
+#: controllers/components/editors.php:57
+#, fuzzy
+msgid "editor_review_error_addon_not_nominated"
+msgstr "This add-on has not been nominated."
+
+#: controllers/components/editors.php:213
+#, fuzzy
+msgid "editor_review_error_file_not_pending"
+msgstr "This file is not pending review."
+
+#. Actions are, for example: approving or rejecting
+#: controllers/components/editors.php:79
+#: controllers/components/editors.php:182
+#, fuzzy
+msgid "editor_review_error_no_action"
+msgstr "Please select a review action."
+
+#: controllers/components/editors.php:192
+#, fuzzy
+msgid "editor_review_error_no_applications"
+msgstr "Please enter the applications you tested."
+
+#. Comments are required when an editor approves or rejects an add-on.
+#: controllers/components/editors.php:84
+#: controllers/components/editors.php:187
+#, fuzzy
+msgid "editor_review_error_no_comments"
+msgstr "Please enter review comments."
+
+#: controllers/components/editors.php:161
+#, fuzzy
+msgid "editor_review_error_no_files"
+msgstr "Please select at least one file to review."
+
+#: controllers/components/editors.php:197
+#, fuzzy
+msgid "editor_review_error_no_operating_system"
+msgstr "Please enter the operating systems you tested."
+
+#: views/editors/logs.thtml:51
+msgid "editorcp_logs_button_filter"
+msgstr "Scag"
+
+#: views/editors/logs.thtml:44
+msgid "editorcp_logs_filter_by"
+msgstr "Scagadh de réir cineáil/gnímh"
+
+#: views/editors/logs.thtml:42 controllers/editors_controller.php:964
+msgid "editorcp_logs_page_heading"
+msgstr "Logchomhad Imeachtaí"
+
+#: views/elements/developers/editorsmenu.thtml:60
+msgid "editorcp_menu_eventlog_link"
+msgstr "Logchomhad Imeachtaí"
+
+#: views/elements/developers/editorsmenu.thtml:62
+msgid "editorcp_menu_mainpage_link"
+msgstr "Ar ais go dtí an Príomhleathanach"
+
+#: views/elements/developers/editorsmenu.thtml:61
+msgid "editorcp_menu_reviewlog_link"
+msgstr "Logchomhad Iniúchta"
+
+#: views/elements/developers/editorsmenu.thtml:55
+msgid "editorcp_menu_summary_link"
+msgstr "Achoimre Eagarthóra"
+
+#: views/elements/developers/editorsmenu.thtml:52
+msgid "editorcp_menu_title"
+msgstr "Uirlisí Eagarthóra"
+
+#: views/editors/reviewlog.thtml:49
+msgid "editorcp_reviewlog_button_filter"
+msgstr "Scag"
+
+#: views/editors/reviewlog.thtml:58
+msgid "editorcp_reviewlog_column_action"
+msgstr "Gníomh"
+
+#: views/editors/reviewlog.thtml:56
+msgid "editorcp_reviewlog_column_addon"
+msgstr "Breiseán"
+
+#: views/editors/reviewlog.thtml:55
+msgid "editorcp_reviewlog_column_date"
+msgstr "Dáta"
+
+#: views/editors/reviewlog.thtml:57
+msgid "editorcp_reviewlog_column_editor"
+msgstr "Eagarthóir"
+
+#: views/editors/reviewlog.thtml:94
+msgid "editorcp_reviewlog_comments_hide"
+msgstr "Folaigh Nótaí"
+
+#: views/editors/reviewlog.thtml:93
+msgid "editorcp_reviewlog_comments_show"
+msgstr "Taispeáin Nótaí"
+
+#. %1$s and %2$s are full <input> tags for dates
+#: views/editors/reviewlog.thtml:45
+#, php-format
+msgid "editorcp_reviewlog_entries_between"
+msgstr "Féach ar iontrálacha idir %1$s agus %2$s"
+
+#: views/editors/reviewlog.thtml:104
+msgid "editorcp_reviewlog_none_found"
+msgstr "Níor aimsíodh aon rud sa tréimhse seo."
+
+#: views/editors/reviewlog.thtml:42
+msgid "editorcp_reviewlog_page_heading"
+msgstr "Logchomhad Iniúchta"
+
+#: views/editors/summary.thtml:61
+msgid "editorcp_summary_monthreviews_heading"
+msgstr "Breiseáin Iniúchta an Mhí Seo"
+
+#: views/editors/summary.thtml:77
+msgid "editorcp_summary_neweditors_heading"
+msgstr "Eagarthóirí Nua"
+
+#: views/editors/summary.thtml:42
+msgid "editorcp_summary_page_heading"
+msgstr "Achoimre Eagarthóra"
+
+#: views/editors/summary.thtml:94
+msgid "editorcp_summary_recentactivity_heading"
+msgstr "Gníomhaíocht Eagarthóireachta Le Déanaí"
+
+#: views/editors/summary.thtml:45
+msgid "editorcp_summary_totalreviews_heading"
+msgstr "Líon Iomlán Iniúchta"
+
+#: controllers/editors_controller.php:248
+#: controllers/editors_controller.php:249
+msgid "editors_addon_review_pagetitle"
+msgstr "Déan Iniúchadh ar Bhreiseán"
+
+#: controllers/editors_controller.php:349
+msgid "editors_error_js-formerror"
+msgstr "Líon isteach na réimsí seo a leanas:"
+
+#: controllers/editors_controller.php:350
+msgid "editors_error_review_one_file"
+msgstr "Roghnaigh comhad amháin ar a laghad a ndéanfaidh tú iniúchadh air."
+
+#: controllers/editors_controller.php:274
+msgid "editors_error_self_reviews_forbidden"
+msgstr "Níl cead agat do bhreiseán féin a iniúchadh."
+
+#: controllers/editors_controller.php:699
+msgid "editors_external_software"
+msgstr "Bogearra Seachtrach"
+
+#: views/editors/featured.thtml:120 views/editors/featured.thtml:121
+msgid "editors_featured_add_feature"
+msgstr "Cuir gné leis"
+
+#: views/editors/featured.thtml:126
+msgid "editors_featured_add_feature_submit"
+msgstr "Cuir Leis"
+
+#: views/editors/featured.thtml:49 controllers/editors_controller.php:832
+#: controllers/editors_controller.php:848
+msgid "editors_featured_addon_add_failure"
+msgstr "Níorbh fhéidir an ghné a chur leis."
+
+#: controllers/editors_controller.php:851
+msgid "editors_featured_addon_add_success"
+msgstr "Cuireadh an ghné leis."
+
+#: views/editors/featured.thtml:50 controllers/editors_controller.php:839
+#: controllers/editors_controller.php:868
+#: controllers/editors_controller.php:886
+msgid "editors_featured_addon_edit_failure"
+msgstr "Níorbh fhéidir an ghné a chur in eagar."
+
+#: views/editors/featured.thtml:51 controllers/editors_controller.php:888
+msgid "editors_featured_addon_edit_success"
+msgstr "Cuireadh an ghné in eagar."
+
+#: views/editors/featured.thtml:53 controllers/editors_controller.php:861
+msgid "editors_featured_addon_invalid_locale"
+msgstr "Tá logchaighdeán amháin neamhbhailí ar a laghad."
+
+#: views/editors/featured.thtml:52 controllers/editors_controller.php:906
+msgid "editors_featured_addon_remove_failure"
+msgstr "Níorbh fhéidir an ghné a bhaint."
+
+#: controllers/editors_controller.php:901
+msgid "editors_featured_addon_remove_success"
+msgstr "Baineadh an ghné amach."
+
+#: controllers/editors_controller.php:915
+#: controllers/editors_controller.php:917
+msgid "editors_featured_addons_pagetitle"
+msgstr "Breiseáin Shuntasacha"
+
+#: views/editors/featured.thtml:54 views/editors/featured.thtml:107
+msgid "editors_featured_edit_feature_submit"
+msgstr "Téigh"
+
+#: views/editors/featured.thtml:90 views/editors/featured.thtml:91
+msgid "editors_featured_remove_feature"
+msgstr "Bain gné"
+
+#: views/editors/queue.thtml:46
+msgid "editors_filter_queue"
+msgstr "Scag an Ciú"
+
+#: views/editors/queue.thtml:182
+msgid "editors_helpful_links"
+msgstr "Naisc Chabhracha"
+
+#: views/editors/queue.thtml:182
+msgid "editors_link_guide"
+msgstr "Lámhleabhar d'Eagarthóirí"
+
+#: views/editors/queue.thtml:182
+msgid "editors_link_policy"
+msgstr "Polasaí Breiseáin"
+
+#: views/editors/queue.thtml:47
+msgid "editors_notice_filter_session"
+msgstr ""
+"Coinnigh na scagairí seo le linn an tseisiúin seo, nó go dtí go nglanfar iad."
+
+# %1 is the queue mode
+#. %1 is the queue mode
+#: views/editors/queue.thtml:177 views/admin/flagged_queue.thtml:89
+msgid "editors_notice_none_found"
+msgstr "Níl aon bhreiseáin den chineál seo le hiniúchadh faoi láthair."
+
+#: controllers/editors_controller.php:1040
+msgid "editors_one_day"
+msgstr "1 lá"
+
+#: controllers/editors_controller.php:1048
+msgid "editors_one_hour"
+msgstr "1 uair"
+
+#: controllers/editors_controller.php:1056
+msgid "editors_one_minute"
+msgstr "1 nóiméad"
+
+#: controllers/editors_controller.php:64 controllers/editors_controller.php:73
+#: controllers/editors_controller.php:77
+msgid "editors_pagetitle"
+msgstr "Uirlisí Eagarthóra"
+
+#. %s is a comma separated list of platforms. Example: Windows, OS X
+#: controllers/editors_controller.php:680
+#: controllers/editors_controller.php:683
+#, php-format
+msgid "editors_platform_x_only"
+msgstr "%s amháin"
+
+#: controllers/editors_controller.php:695
+msgid "editors_pre-release"
+msgstr "Réamhleagan"
+
+# %1 is the app name
+#. %1 is the app name
+#: views/editors/queue.thtml:131
+#, php-format
+msgid "editors_queue_app_compatibility"
+msgstr "Comhoiriúnacht %s"
+
+#: views/editors/queue.thtml:51
+#, fuzzy
+msgid "editors_queue_filter_label_addon"
+msgstr "Add-on or Author Email"
+
+#: views/editors/queue.thtml:72
+#, fuzzy
+msgid "editors_queue_filter_label_addontypes"
+msgstr "Add-on Types"
+
+#: views/editors/queue.thtml:56
+#, fuzzy
+msgid "editors_queue_filter_label_application"
+msgstr "Application"
+
+#: views/editors/queue.thtml:61
+#, fuzzy
+msgid "editors_queue_filter_label_maxversion"
+msgstr "Max. Version"
+
+#: views/editors/queue.thtml:78
+#, fuzzy
+msgid "editors_queue_filter_label_platforms"
+msgstr "Platforms"
+
+#: views/editors/queue.thtml:66
+#, fuzzy
+msgid "editors_queue_filter_label_submissionage"
+msgstr "Age of Submission (days)"
+
+#. %1$s is a number
+#: views/editors/queue.thtml:90
+#, fuzzy
+msgid "editors_queue_filter_result_count"
+msgid_plural "editors_queue_filter_result_count"
+msgstr[0] "Results of your filtered search: <strong>%1$s</strong> Add-on"
+msgstr[1] "Results of your filtered search: <strong>%1$s</strong> Add-ons"
+
+#: views/editors/queue.thtml:84
+msgid "editors_queue_submit_clean"
+msgstr "Glan"
+
+#: views/editors/queue.thtml:83
+msgid "editors_queue_submit_filter"
+msgstr "Scag"
+
+#: controllers/editors_controller.php:133
+msgid "editors_queues_disabled"
+msgstr ""
+"Tá gach ciú iniúchta díchumasaithe faoi láthair. Déan iarracht eile ar ball."
+
+#: views/editors/review.thtml:149
+#, fuzzy
+msgid "editors_review_a_edit_item"
+msgstr "Edit Item"
+
+#: views/editors/review.thtml:146
+#, fuzzy
+msgid "editors_review_a_item_history"
+msgstr "Item History"
+
+#: views/editors/review.thtml:148
+#, fuzzy
+msgid "editors_review_a_item_homepage"
+msgstr "Item Homepage"
+
+#: views/editors/review.thtml:145
+#, fuzzy
+msgid "editors_review_a_item_overview"
+msgstr "Item Overview"
+
+#: views/editors/review.thtml:147
+#, fuzzy
+msgid "editors_review_a_previews"
+msgstr "Previews"
+
+#: controllers/editors_controller.php:345
+msgid "editors_review_action"
+msgstr "Gníomh"
+
+#: views/editors/review.thtml:159
+#, fuzzy
+msgid "editors_review_action_info"
+msgstr "Request More Information"
+
+#: views/editors/review.thtml:157
+msgid "editors_review_action_public"
+msgstr "Cuir ar an taobh Poiblí"
+
+#: views/editors/review.thtml:160
+msgid "editors_review_action_request_superreview"
+msgstr "Déan Iarratas ar Fhorbhreithniú"
+
+#: views/editors/review.thtml:158
+msgid "editors_review_action_sandbox"
+msgstr "Coinnigh sa Bhosca Gainimh"
+
+#: controllers/editors_controller.php:346
+msgid "editors_review_comments"
+msgstr "Nótaí ón Eagarthóir"
+
+#: views/editors/review.thtml:182
+#, fuzzy
+msgid "editors_review_details_info_request"
+msgstr ""
+"Use this form to request more information from the author. They will receive "
+"an email and be able to answer here. You will be notified by email when they "
+"reply."
+
+#: views/editors/review.thtml:174
+msgid "editors_review_details_nominated_public"
+msgstr ""
+"Cuirfidh sé seo an breiseán agus an leagan is déanaí de ar an taobh poiblí. "
+"Rachaidh leaganacha amach anseo sa bhosca gainimh go dtí go ndéanfaidh "
+"eagarthóir iniúchadh orthu."
+
+#: views/editors/review.thtml:177
+msgid "editors_review_details_nominated_sandbox"
+msgstr "Coinneoidh sé seo an breiseán sa bhosca gainimh."
+
+#: views/editors/review.thtml:166
+msgid "editors_review_details_pending_public"
+msgstr ""
+"Cuirfidh sé seo leagan atá sa bhosca gainimh de bhreiseán poiblí ar an taobh "
+"poiblí."
+
+#: views/editors/review.thtml:169
+msgid "editors_review_details_pending_sandbox"
+msgstr ""
+"Coinneoidh sé seo leagan atá sa bhosca gainimh de bhreiseán poiblí sa bhosca "
+"gainimh.poiblí."
+
+#: views/editors/review.thtml:185
+msgid "editors_review_details_superreview"
+msgstr ""
+"Má tá imní ort maidir le slándáil an bhreiseáin seo, cúrsaí cóipchirt, nó "
+"aon rud eile ba chóir do riarthóir a iniúchadh, cuir do chuid smaointe sa "
+"bhosca thíos. Seolfar iad chuig riarthóirí an tsuímh (in ionad an údair)."
+
+#: views/editors/review.thtml:134
+msgid "editors_review_file_diff_link"
+msgstr "Cuir i gcomparáid leis an leagan poiblí"
+
+#: views/editors/review.thtml:131
+msgid "editors_review_file_viewcontents_link"
+msgstr "Féach ar Inneachar"
+
+#: views/editors/review.thtml:65
+msgid "editors_review_header_authors"
+msgstr "Údair:"
+
+#: views/editors/review.thtml:79
+msgid "editors_review_header_categories"
+msgstr "Catagóirí:"
+
+#: views/editors/review.thtml:92
+msgid "editors_review_header_compatibility"
+msgstr "Comhoiriúnacht:"
+
+#: views/editors/review.thtml:251
+msgid "editors_review_header_description"
+msgstr "Cur Síos"
+
+#: views/editors/review.thtml:275
+msgid "editors_review_header_devcomments"
+msgstr "Nótaí ón Fhorbróir"
+
+#: views/editors/review.thtml:263
+msgid "editors_review_header_eula"
+msgstr "EULA"
+
+#: views/editors/review.thtml:115
+msgid "editors_review_header_files"
+msgstr "Comhaid:"
+
+#: views/editors/review.thtml:284
+msgid "editors_review_header_itemhistory"
+msgstr "Stair na Míre"
+
+#: views/editors/review.thtml:232
+msgid "editors_review_header_nominationmessage"
+msgstr "Teachtaireacht Ainmnithe"
+
+#: views/editors/review.thtml:311
+msgid "editors_review_header_previews"
+msgstr "Réamhamhairc"
+
+#: views/editors/review.thtml:269
+msgid "editors_review_header_privacy"
+msgstr "Polasaí Príobháideachta"
+
+# %1 is the addon name and version
+#. %1 is the add-on name and version
+#: views/editors/review.thtml:56
+#, php-format
+msgid "editors_review_header_review"
+msgstr "Déan Iniúchadh ar %s"
+
+#: views/editors/review.thtml:239
+msgid "editors_review_header_reviewernotes"
+msgstr "Nótaí don Eagarthóir"
+
+#: views/editors/review.thtml:245
+msgid "editors_review_header_summary"
+msgstr "Achoimre"
+
+#: views/editors/review.thtml:257
+msgid "editors_review_header_versionnotes"
+msgstr "Nótaí Eisiúna"
+
+#. a noun: shown in an add-on's editor review history
+#: views/elements/developers/editors_review_history_item.thtml:80
+msgid "editors_review_history_info_reply"
+msgstr "Freagra"
+
+#: views/elements/developers/editors_review_history_item.thtml:78
+msgid "editors_review_history_info_request"
+msgstr "Iarratas ar Eolas"
+
+#: views/elements/developers/editors_review_history_item.thtml:62
+#: views/editors/reviewlog.thtml:77
+msgid "editors_review_history_nominated_adminreview"
+msgstr "Iniúchadh Riaracháin"
+
+#: views/elements/developers/editors_review_history_item.thtml:56
+#: views/editors/reviewlog.thtml:71
+msgid "editors_review_history_nominated_approved"
+msgstr "Glacadh leis an Ainmniú/Poiblí"
+
+#: views/elements/developers/editors_review_history_item.thtml:59
+#: views/editors/reviewlog.thtml:74
+msgid "editors_review_history_nominated_denied"
+msgstr "Diúltaíodh an tAinmniú/Bosca Gainimh"
+
+#: views/editors/review.thtml:303
+msgid "editors_review_history_nonefound"
+msgstr "Níor aimsíodh aon iontrálacha iniúchta roimhe seo."
+
+#: views/elements/developers/editors_review_history_item.thtml:73
+#: views/editors/reviewlog.thtml:88
+msgid "editors_review_history_pending_adminreview"
+msgstr "Iniúchadh Riaracháin"
+
+#: views/elements/developers/editors_review_history_item.thtml:67
+#: views/editors/reviewlog.thtml:82
+msgid "editors_review_history_pending_approved"
+msgstr "Ceadaithe/Poiblí"
+
+#: views/elements/developers/editors_review_history_item.thtml:70
+#: views/editors/reviewlog.thtml:85
+msgid "editors_review_history_pending_denied"
+msgstr "Diúltaithe/Bosca Gainimh"
+
+#. link text in an add-on's editor review history, allowing to hide and show an information request's replies
+#. %1 is the number of replies
+#: views/elements/developers/editors_review_history_item.thtml:90
+msgid "editors_review_history_show_hide_replies"
+msgid_plural "editors_review_history_show_hide_replies"
+msgstr[0] "Taispeáin/Folaigh Freagraí (%1$s)"
+msgstr[1] "Taispeáin/Folaigh Freagraí (%1$s)"
+msgstr[2] "Taispeáin/Folaigh Freagraí (%1$s)"
+msgstr[3] "Taispeáin/Folaigh Freagraí (%1$s)"
+msgstr[4] "Taispeáin/Folaigh Freagraí (%1$s)"
+
+#: views/editors/review.thtml:208
+msgid "editors_review_label_applications"
+msgstr "Feidhmchláir:"
+
+#: views/editors/review.thtml:196
+msgid "editors_review_label_cannedresponse"
+msgstr "nó roghnaigh freagra coitianta:"
+
+#: views/editors/review.thtml:190
+msgid "editors_review_label_comments"
+msgstr "Nótaí:"
+
+#: views/editors/review.thtml:204
+msgid "editors_review_label_operating_systems"
+msgstr "Córais Oibriúcháin:"
+
+#: views/editors/review.thtml:285 views/editors/review.thtml:312
+msgid "editors_review_link_pagetop"
+msgstr "Barr"
+
+#: views/editors/review.thtml:141
+#, fuzzy
+msgid "editors_review_mulitple_notice"
+msgstr ""
+"Notice: Only review more than one file if you have tested EVERY file you "
+"select."
+
+#: views/editors/review.thtml:51
+msgid "editors_review_next_link"
+msgstr "ar aghaidh &raquo;"
+
+#: views/editors/review.thtml:322
+msgid "editors_review_previews_notfound"
+msgstr "Níor aimsíodh réamhamharc."
+
+#: views/editors/review.thtml:50
+msgid "editors_review_previous_link"
+msgstr "&laquo; roimhe seo"
+
+#: controllers/editors_controller.php:144
+#: controllers/editors_controller.php:146
+msgid "editors_review_queue_pagetitle"
+msgstr "Ciú Léirmheasanna"
+
+# %1 is the add-ons rank in the queue, %2 is the total queue length
+#. %1 is the add-ons rank in the queue, %2 is the total queue length
+#: views/editors/review.thtml:47
+msgid "editors_review_rank_in_queue"
+msgstr "<strong># %1$s</strong> as %2$s sa chiú"
+
+#. %1 is the add-ons rank in the queue, %2 is the total queue length. Both numbers
+#: views/editors/review.thtml:45
+#, fuzzy
+msgid "editors_review_rank_in_queue_filtered"
+msgstr "<strong># %1$s</strong> of %2$s in queue (filtered)"
+
+#: views/editors/review.thtml:223
+msgid "editors_review_submit_process_action"
+msgstr "Próiseáil Gníomh"
+
+#: views/editors/review.thtml:293
+msgid "editors_review_th_action"
+msgstr "Gníomh"
+
+#: views/editors/review.thtml:294
+msgid "editors_review_th_comments"
+msgstr "Nótaí"
+
+#: views/editors/review.thtml:291
+msgid "editors_review_th_date"
+msgstr "Dáta"
+
+#: views/editors/review.thtml:292
+msgid "editors_review_th_reviewer"
+msgstr "Eagarthóir"
+
+#: views/editors/review.thtml:290
+msgid "editors_review_th_version_file"
+msgstr "Leagan/Comhad"
+
+#: views/editors/review.thtml:217
+#, fuzzy
+msgid "editors_review_update_notify_once"
+msgstr ""
+"Notify me the next time this add-on is updated. (Subsequent updates will not "
+"generate an email)"
+
+#: controllers/editors_controller.php:298
+msgid "editors_reviewed_successfully"
+msgstr "Próiseáladh an léirmheas."
+
+#: views/editors/reviews_queue.thtml:106
+msgid "editors_reviews_action_delete_review"
+msgstr "Scrios an léirmheas"
+
+#: views/editors/reviews_queue.thtml:104
+msgid "editors_reviews_action_keep"
+msgstr "Bain bratacha; coinnigh an léirmheas"
+
+#: views/editors/reviews_queue.thtml:102
+msgid "editors_reviews_action_skip"
+msgstr "Scipeáil"
+
+#: views/editors/reviews_queue.thtml:100
+msgid "editors_reviews_header_action"
+msgstr "Gníomh"
+
+#: views/editors/reviews_queue.thtml:67
+msgid "editors_reviews_in_reply_to"
+msgstr "I bhfreagra ar:"
+
+#: controllers/editors_controller.php:748
+msgid "editors_reviews_processed"
+msgstr "Próiseáladh na léirmheasanna!"
+
+#: views/editors/reviews_queue.thtml:117
+msgid "editors_reviews_queue_empty"
+msgstr "Níl aon léirmheasanna le hiniúchadh faoi láthair."
+
+#: views/editors/reviews_queue.thtml:111
+msgid "editors_reviews_submit_process_reviews"
+msgstr "Próiseáil Léirmheasanna"
+
+#: controllers/editors_controller.php:691
+msgid "editors_site_specific"
+msgstr "Sainiúil do Shuíomh"
+
+#: controllers/editors_controller.php:348
+msgid "editors_tested_app"
+msgstr "Feidhmchlár Profa"
+
+#: controllers/editors_controller.php:347
+msgid "editors_tested_os"
+msgstr "Córais Oibriúcháin Profa"
+
+#: views/editors/queue.thtml:151
+msgid "editors_th_additional_info"
+msgstr "Tuilleadh Eolais"
+
+#: views/editors/featured.thtml:63 views/editors/queue.thtml:109
+#: views/admin/flagged_queue.thtml:53
+msgid "editors_th_addon"
+msgstr "Breiseán"
+
+#: views/editors/queue.thtml:125
+msgid "editors_th_addontype"
+msgstr "Cineál"
+
+#: views/editors/featured.thtml:64
+msgid "editors_th_locales"
+msgstr "Srian na logchaighdeáin?"
+
+#: views/editors/queue.thtml:148
+msgid "editors_th_nomination_age"
+msgstr "Tréimhse sa Chiú"
+
+#: views/editors/queue.thtml:101 views/editors/queue.thtml:117
+#: views/editors/queue.thtml:144
+#, fuzzy
+msgid "editors_th_sort_ascending"
+msgstr "Ascending sort"
+
+#: views/editors/queue.thtml:105 views/editors/queue.thtml:121
+#: views/editors/queue.thtml:140
+#, fuzzy
+msgid "editors_th_sort_descending"
+msgstr "Descending sort"
+
+#. %s is a number
+#: controllers/editors_controller.php:1036
+#, php-format
+msgid "editors_x_days"
+msgstr "%s lá"
+
+#. %s is a number
+#: controllers/editors_controller.php:1044
+#, php-format
+msgid "editors_x_hours"
+msgstr "%s uair"
+
+#. %s is a number
+#: controllers/editors_controller.php:1052
+#, php-format
+msgid "editors_x_minutes"
+msgstr "%s nóiméad"
+
+#: views/errors/error401.thtml:50 controllers/components/simple_acl.php:81
+#: controllers/components/simple_acl.php:82
+#: controllers/components/simple_acl.php:83 controllers/components/amo.php:607
+#: controllers/components/amo.php:608 controllers/components/amo.php:609
+#: controllers/reviews_controller.php:353
+#: controllers/reviews_controller.php:485
+#: controllers/collections_controller.php:438
+#: controllers/collections_controller.php:496
+#: controllers/collections_controller.php:504
+#: controllers/collections_controller.php:971
+#: controllers/collections_controller.php:1034
+#: controllers/collections_controller.php:1077
+msgid "error_access_denied"
+msgstr "Cead Rochtana Diúltaithe"
+
+#: views/errors/error401.thtml:52
+msgid "error_access_denied_message"
+msgstr "Níl cead agat féachaint ar an leathanach seo."
+
+#: controllers/collections_controller.php:1039
+#, fuzzy
+msgid "error_addon_exists"
+msgstr "Add-on already exists!"
+
+#: controllers/developers_controller.php:200
+#: controllers/developers_controller.php:593
+#: controllers/developers_controller.php:1016
+#: controllers/developers_controller.php:1429
+#: controllers/downloads_controller.php:95
+#: controllers/downloads_controller.php:102
+#: controllers/downloads_controller.php:164
+#: controllers/statistics_controller.php:135
+#: controllers/previews_controller.php:115
+#: controllers/previews_controller.php:206
+#: controllers/previews_controller.php:307
+#: controllers/reviews_controller.php:77
+#: controllers/reviews_controller.php:240
+#: controllers/reviews_controller.php:332
+#: controllers/reviews_controller.php:340 controllers/api_controller.php:123
+#: controllers/api_controller.php:759 controllers/addons_controller.php:131
+#: controllers/addons_controller.php:197
+#: controllers/addons_controller.php:1407
+#: controllers/addons_controller.php:1465
+#: controllers/addons_controller.php:1469
+#: controllers/addons_controller.php:1503
+#: controllers/editors_controller.php:265
+#: controllers/collections_controller.php:1041
+#: controllers/collections_controller.php:1074
+msgid "error_addon_notfound"
+msgstr "Breiseán gan aimsiú!"
+
+#: controllers/files_controller.php:83 controllers/files_controller.php:196
+msgid "error_addon_notviewable"
+msgstr "Níl an breiseán seo infheicthe anseo."
+
+#: controllers/reviews_controller.php:246
+msgid "error_addon_selfreview"
+msgstr "Níl cead agat léirmheas a dhéanamh ar do bhreiseán féin."
+
+#: controllers/addons_controller.php:970
+msgid "error_browse_no_addons"
+msgstr "Níl aon bhreiseán sa chatagóir seo!"
+
+#: controllers/api_controller.php:424
+msgid "error_collection_feed_notfound"
+msgstr "Fotha an bhreiseáin gan aimsiú."
+
+#: views/users/register.thtml:65 views/users/edit.thtml:194
+msgid "error_email_invalid"
+msgstr "Ní seoladh ríomhphoist bailí é seo."
+
+#: views/users/pwreset.thtml:74 views/users/register.thtml:70
+#: views/users/register.thtml:80 views/users/register.thtml:86
+#: views/users/edit.thtml:105 views/users/edit.thtml:111
+#: views/users/edit.thtml:192 views/admin/users_edit.thtml:78
+#: views/admin/users_edit.thtml:83 views/reviews/add.thtml:80
+#: views/reviews/add.thtml:104
+msgid "error_field_required"
+msgstr "Caithfidh tú an réimse seo a líonadh."
+
+#: controllers/files_controller.php:75 controllers/files_controller.php:93
+#: controllers/files_controller.php:96 controllers/files_controller.php:163
+#: controllers/files_controller.php:176 controllers/files_controller.php:185
+#: controllers/files_controller.php:204 controllers/editors_controller.php:412
+msgid "error_file_notfound"
+msgstr "Comhad gan aimsiú!"
+
+#. %s is a filename
+#: controllers/editors_controller.php:430
+#, php-format
+msgid "error_file_x_notfound"
+msgstr "Earráid chomhaid: níl %s ann."
+
+#: views/collections/add.thtml:55 views/collections/edit.thtml:89
+#: views/users/register.thtml:54 views/users/edit.thtml:81
+#: views/reviews/add.thtml:70 controllers/groups_controller.php:80
+#: controllers/groups_controller.php:102
+msgid "error_formerrors"
+msgstr "Tá earráidí san fhoirm seo. Ceartaigh iad agus seol é arís."
+
+#: views/users/register.thtml:109
+msgid "error_invalid_captcha"
+msgstr "Captcha neamhbhailí, bain triail eile as!"
+
+#: views/users/register.thtml:100 views/users/edit.thtml:125
+#: views/admin/users_edit.thtml:101
+msgid "error_invalid_url"
+msgstr ""
+"Tá formáid an URL seo neamhbhailí. Ba chóir dó a bheith cosúil le http://"
+"sampla.com/mo_leathanach."
+
+#. %s is a string representing what's missing. Example: file_id
+#: controllers/downloads_controller.php:65
+#: controllers/users_controller.php:185 controllers/users_controller.php:264
+#: controllers/users_controller.php:559 controllers/users_controller.php:653
+#: controllers/reviews_controller.php:71
+#: controllers/reviews_controller.php:234
+#: controllers/reviews_controller.php:325
+#: controllers/reviews_controller.php:473
+#: controllers/reviews_controller.php:475
+#: controllers/addons_controller.php:182
+#: controllers/addons_controller.php:1381
+#: controllers/addons_controller.php:1455
+#: controllers/collections_controller.php:266
+#: controllers/collections_controller.php:285
+#: controllers/collections_controller.php:346
+#: controllers/collections_controller.php:443
+#: controllers/collections_controller.php:482
+#: controllers/collections_controller.php:936
+#: controllers/collections_controller.php:959
+#: controllers/collections_controller.php:960
+#: controllers/collections_controller.php:975
+#: controllers/collections_controller.php:977
+#: controllers/collections_controller.php:994
+#: controllers/collections_controller.php:1003
+#: controllers/collections_controller.php:1016
+#: controllers/collections_controller.php:1017
+#: controllers/collections_controller.php:1024
+#: controllers/collections_controller.php:1070
+#: controllers/collections_controller.php:1090
+#, php-format
+msgid "error_missing_argument"
+msgstr "Argóint ar iarraidh: %s"
+
+#: controllers/components/amo.php:507 controllers/components/amo.php:532
+msgid "error_no_files_in_addon"
+msgstr "Gan Chomhaid"
+
+#: controllers/previews_controller.php:200
+msgid "error_preview_notfound"
+msgstr "Réamhamharc gan aimsiú!"
+
+#: views/addons/display.thtml:400 views/reviews/add.thtml:98
+msgid "error_review_rating_required"
+msgstr "Ní mór duit rátáil a roghnú."
+
+#: controllers/users_controller.php:160
+msgid "error_user_already_confirmed"
+msgstr "Tá an cuntas úsáideora seo dearbhaithe cheana."
+
+#: controllers/users_controller.php:202 controllers/users_controller.php:276
+#: controllers/users_controller.php:569 controllers/users_controller.php:581
+#: controllers/users_controller.php:587 controllers/users_controller.php:610
+#: controllers/users_controller.php:627
+msgid "error_user_badconfirmationcode"
+msgstr "Cód neamhbhailí dearbhaithe!"
+
+#: views/users/pwreset.thtml:79 views/users/register.thtml:75
+#: views/users/edit.thtml:183
+msgid "error_user_confirmpw_nomatch"
+msgstr "Ní ionann na focail fhaire."
+
+#: views/users/register.thtml:65 views/users/edit.thtml:190
+#: controllers/users_controller.php:617
+msgid "error_user_email_notunique"
+msgstr "Tá an seoladh ríomhphoist seo cláraithe cheana ag úsáideoir eile."
+
+#: controllers/users_controller.php:596
+msgid "error_user_emailchange_expired"
+msgstr ""
+"Chuaigh an t-iarratas athraithe ríomhphoist as feidhm. Athraigh do sheoladh "
+"ríomhphoist arís i do phróifíl úsáideora agus cliceáil an nasc sa "
+"teachtaireacht dearbhaithe chomh luath is a gheobhaidh tú é."
+
+#: controllers/collections_controller.php:985
+#, fuzzy
+msgid "error_user_exists"
+msgstr ""
+"Users can only have one role at a time. Please remove the user from any "
+"existing roles before continuing."
+
+#: views/users/register.thtml:91 views/users/edit.thtml:116
+#: views/admin/users_edit.thtml:88
+msgid "error_user_nickname_notunique"
+msgstr "Tá an leasainm seo cláraithe cheana."
+
+#: views/users/pwreset.thtml:54 controllers/users_controller.php:191
+#: controllers/users_controller.php:270 controllers/users_controller.php:603
+#: controllers/users_controller.php:659
+#: controllers/collections_controller.php:988
+#: controllers/collections_controller.php:998
+msgid "error_user_notfound"
+msgstr "Úsáideoir gan aimsiú!"
+
+#: views/users/activatefirst.thtml:47
+msgid "error_user_unconfirmed"
+msgstr ""
+"Dearbhaigh do chuntas úsáideora ar dtús leis an gcód a fuair tú trí "
+"ríomhphost."
+
+#: views/users/login.thtml:67
+msgid "error_username_or_pw_wrong"
+msgstr "Ainm an úsáideora nó focal faire mícheart!"
+
+#: controllers/editors_controller.php:260
+msgid "error_version_notfound"
+msgstr "Leagan gan aimsiú!"
+
+#: views/users/delete.thtml:125 views/users/edit.thtml:173
+msgid "error_wrong_password"
+msgstr "Focal faire mícheart!"
+
+#: views/elements/amo2009/homepage_addon.thtml:122
+#: views/elements/feature.thtml:122
+msgid "feature_learnmore"
+msgstr "Tuilleadh eolais"
+
+# %1 is the add-on name
+#. %1 is the add-on name
+#: views/elements/amo2009/homepage_addon.thtml:123
+#: views/elements/feature.thtml:123
+#, php-format
+msgid "feature_learnmore_about_addon"
+msgstr "Tuilleadh eolais faoi %1$s"
+
+#. %1$s is a number
+#: views/elements/amo2009/reviews.thtml:52
+#: views/elements/addon_listitem.thtml:112 views/elements/feature.thtml:99
+#: views/addons/browse_thumbs.thtml:86
+#, php-format
+msgid "feature_reviews"
+msgid_plural "feature_reviews"
+msgstr[0] "%1$s léirmheas"
+msgstr[1] "%1$s léirmheas"
+msgstr[2] "%1$s léirmheas"
+msgstr[3] "%1$s léirmheas"
+msgstr[4] "%1$s léirmheas"
+
+#: views/elements/amo2009/homepage_addon.thtml:127
+#: views/elements/feature.thtml:127
+msgid "feature_view_more_from_category"
+msgstr "Tuilleadh ó"
+
+#. This appears on a page that views the source of an add-on. This link will return
+#. the user to the add-on's main page
+#: views/files/browse.thtml:65
+msgid "file_browser_link_addon"
+msgstr "Ar ais go dtí an breiseán"
+
+#. There is a list of directories and files on the page. Clicking this will show the
+#. contents of all the directories (normally you would click on each one to see the
+#. contents)
+#: views/files/browse.thtml:67
+msgid "file_browser_link_expand_all"
+msgstr "Leathnaigh uile"
+
+#. This appears on a page that views the source of an add-on. This link will return
+#. the user to the add-on's review page (it only appears if the add-on is being
+#. reviewed)
+#: views/files/browse.thtml:64
+#, fuzzy
+msgid "file_browser_link_review"
+msgstr "Back to review"
+
+#. The title of the page for viewing an add-on's source.
+#. %1$s is the name of the add-on
+#. %2$s is the name of the current application (e.g. Firefox or Thunderbird)
+#: views/files/browse.thtml:46
+msgid "file_browser_title"
+msgstr "%1$s :: Brabhsálaí Comhad :: Breiseáin %2$s"
+
+#. This appears on a page that views the source of an add-on. There is a list of
+#. directories and files on the page. Clicking this link will toggle between an
+#. expanded or a collapsed list. This string should be kept short.
+#: views/files/browse.thtml:68
+msgid "file_browser_toggle_expand_collapse"
+msgstr "+/-"
+
+#. Link text for the AMO About page.
+#: views/elements/footer.thtml:72 views/layouts/amo2009.thtml:341
+msgid "footer_a_about"
+msgstr "Maidir Leis"
+
+#. Link text to the AMO blog.
+#: views/elements/footer.thtml:74 views/layouts/amo2009.thtml:343
+msgid "footer_a_blog"
+msgstr "Blag"
+
+#. Link text to the Frequently Asked Questions page.
+#: views/elements/footer.thtml:73 views/layouts/amo2009.thtml:342
+msgid "footer_a_faq"
+msgstr "Ceisteanna Coitianta"
+
+#. Full text for the FAQ abbreviation.
+#: views/elements/footer.thtml:73 views/pages/collector_features.thtml:72
+#: views/layouts/amo2009.thtml:342
+msgid "footer_abbr_faq"
+msgstr "Ceisteanna Coitianta"
+
+#: views/elements/footer.thtml:67 views/layouts/amo2009.thtml:336
+msgid "footer_all_rights_reserved"
+msgstr "Gach ceart ar cosaint."
+
+#: views/elements/footer.thtml:67 views/layouts/amo2009.thtml:336
+msgid "footer_copyright"
+msgstr "Cóipcheart"
+
+#: views/elements/footer.thtml:71 views/layouts/amo2009.thtml:340
+msgid "footer_credits"
+msgstr "Admhálacha"
+
+#: views/elements/footer.thtml:76 views/layouts/amo2009.thtml:346
+msgid "footer_disclaimer"
+msgstr ""
+"Soláthraíonn Mozilla naisc leis na feidhmchláir seo mar sheirbhís, agus ní "
+"dhéanaimid aon uiríoll maidir leis na feidhmchláir nó faisnéis a bhaineann "
+"leo. Ní mór duit ceisteanna, gearáin, nó éilimh a bhaineann leis na "
+"feidhmchláir a sheoladh chuig an bhforbróir oiriúnach."
+
+#: views/elements/footer.thtml:61 views/layouts/amo2009.thtml:332
+msgid "footer_lang_form_lang_submit_go"
+msgstr "Téigh"
+
+#: views/elements/footer.thtml:70 views/layouts/amo2009.thtml:339
+msgid "footer_legal_notices"
+msgstr "Fógraí Dlí"
+
+#: views/elements/footer.thtml:50 views/layouts/amo2009.thtml:321
+msgid "footer_other_languages"
+msgstr "Teangacha eile:"
+
+#: views/elements/footer.thtml:69 views/layouts/amo2009.thtml:338
+msgid "footer_privacy_policy"
+msgstr "Polasaí Príobháideachta"
+
+#: models/addontype.php:79
+msgid "general_addontype_dict"
+msgstr "Foclóir"
+
+# Plural in this context means many of the add-on type
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:100
+msgid "general_addontype_dict_plural"
+msgstr "Foclóirí"
+
+#: models/addontype.php:75
+msgid "general_addontype_extension"
+msgstr "Eisínteacht"
+
+# Plural in this context means many of the add-on type
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:98
+msgid "general_addontype_extension_plural"
+msgstr "Eisínteachtaí"
+
+#: models/addontype.php:85
+msgid "general_addontype_lpaddon"
+msgstr "Pacáiste Teanga (Breiseán)"
+
+# Plural in this context means many of the add-on type
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:103
+msgid "general_addontype_lpaddon_plural"
+msgstr "Pacáistí Teanga (Breiseán)"
+
+#: models/addontype.php:83
+msgid "general_addontype_lpapp"
+msgstr "Pacáiste Teanga (Feidhmchlár)"
+
+# Plural in this context means many of the add-on type
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:102
+msgid "general_addontype_lpapp_plural"
+msgstr "Pacáistí Teanga (Feidhmchlár)"
+
+#: models/addontype.php:87
+msgid "general_addontype_plugin"
+msgstr "Breiseán"
+
+# Plural in this context means many of the add-on type
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:104
+msgid "general_addontype_plugin_plural"
+msgstr "Breiseán"
+
+#: models/addontype.php:81
+msgid "general_addontype_search"
+msgstr "Inneall Cuardaigh"
+
+# Plural in this context means many of the add-on type
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:101
+msgid "general_addontype_search_plural"
+msgstr "Innill Chuardaigh"
+
+#: models/addontype.php:77
+msgid "general_addontype_theme"
+msgstr "Téama"
+
+# Plural in this context means many of the add-on type
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:99
+msgid "general_addontype_theme_plural"
+msgstr "Téamaí"
+
+#: config/language.php:367
+#, fuzzy
+msgid "general_languages_all_locales"
+msgstr "All Locales"
+
+#: views/layouts/amo2009.thtml:249
+#, fuzzy
+msgid "header_brand_name"
+msgstr "Mozilla"
+
+#. %1$s is the application name. Example: Firefox
+#: views/elements/header.thtml:111 views/elements/header.thtml:122
+#: views/layouts/amo2009.thtml:248
+#, php-format
+msgid "header_home_tooltip"
+msgstr "Ar ais go dtí leathanach baile Breiseáin %1$s"
+
+#: views/elements/header.thtml:87
+msgid "header_main_firefox_header"
+msgstr "Breiseáin Firefox"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:218
+#, fuzzy
+msgid "header_main_firefox_header_with_logo"
+msgstr ""
+"Add-ons <em>for</em> <img alt=\"Firefox\" src=\"%1$s\" /> <strong>Firefox</"
+"strong>"
+
+#: views/elements/header.thtml:99
+msgid "header_main_header"
+msgstr "Breiseáin"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:242
+#, fuzzy
+msgid "header_main_header_with_logo"
+msgstr "Add-ons <img alt=\"Add-ons\" src=\"%1$s\" />"
+
+#: views/elements/header.thtml:90
+msgid "header_main_seamonkey_header"
+msgstr "Breiseáin SeaMonkey"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:224
+#, fuzzy
+msgid "header_main_seamonkey_header_with_logo"
+msgstr ""
+"Add-ons <em>for</em> <img alt=\"seamonkey\" src=\"%1$s\" /> "
+"<strong>SeaMonkey</strong>"
+
+#: views/elements/header.thtml:93
+msgid "header_main_sunbird_header"
+msgstr "Breiseáin Sunbird"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:230
+#, fuzzy
+msgid "header_main_sunbird_header_with_logo"
+msgstr ""
+"Add-ons <em>for</em> <img alt=\"sunbird\" src=\"%1$s\" /> <strong>Sunbird</"
+"strong>"
+
+#: views/elements/header.thtml:96
+msgid "header_main_thunderbird_header"
+msgstr "Breiseáin Thunderbird"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:236
+#, fuzzy
+msgid "header_main_thunderbird_header_with_logo"
+msgstr ""
+"Add-ons <em>for</em> <img alt=\"thunderbird\" src=\"%1$s\" /> "
+"<strong>Thunderbird</strong>"
+
+#: views/layouts/amo2009.thtml:205
+#, fuzzy
+msgid "header_navaccess_applications_menu"
+msgstr "Skip to other applications menu"
+
+#: views/layouts/amo2009.thtml:204
+#, fuzzy
+msgid "header_navaccess_categories_menu"
+msgstr "Skip to categories menu"
+
+#: views/layouts/amo2009.thtml:202
+#, fuzzy
+msgid "header_navaccess_main_content"
+msgstr "Skip to main content"
+
+#: views/layouts/amo2009.thtml:203
+#, fuzzy
+msgid "header_navaccess_search_form"
+msgstr "Skip to search form"
+
+#: views/elements/header.thtml:62
+msgid "header_navlink_addons"
+msgstr "Breiseáin"
+
+#: views/elements/developers/sidebar.thtml:72
+#: views/elements/developers/myaddons.thtml:50 views/elements/header.thtml:159
+#: views/addons/display.thtml:378
+msgid "header_navlink_login"
+msgstr "Logáil isteach"
+
+#: views/elements/header.thtml:156 views/layouts/amo2009.thtml:304
+msgid "header_navlink_logout"
+msgstr "Logáil amach"
+
+#: views/elements/header.thtml:145 views/layouts/amo2009.thtml:303
+msgid "header_navlink_myaccount"
+msgstr "Mo Chuntas"
+
+#: views/elements/header.thtml:158
+msgid "header_navlink_register"
+msgstr "Cláraigh"
+
+#. %1 is the URL to the registration page
+#. %2 is the URL to the login page
+#: views/layouts/amo2009.thtml:278
+#, fuzzy
+msgid "header_navlink_register_or_login"
+msgstr "<a href=\"%1$s\">Register</a> or <a href=\"%2$s\">Log in</a>"
+
+#: views/layouts/amo2009.thtml:285
+#, fuzzy
+msgid "header_navlink_tools"
+msgstr "Tools"
+
+#. %s is the add-on name
+#: views/elements/collections_interactive_addon.thtml:62
+#: views/elements/amo2009/homepage_addon.thtml:77
+#: views/elements/addon_discussionheader.thtml:62
+#: views/elements/addon_listitem.thtml:67 views/elements/feature.thtml:84
+#: views/addons/category_landing.thtml:87 views/addons/browse_thumbs.thtml:60
+#, php-format
+msgid "img_preview_of"
+msgstr "Ãomhá Réamhamhairc de %s"
+
+# %1 is the login URL for the link tag
+# %2 is the link to an explanatory page.
+#. %1 is the login URL for the link tag
+#. %2 is the link to an explanatory page.
+#: views/elements/amo2009/install.thtml:307 views/elements/install.thtml:255
+msgid "install_a_login_to_install"
+msgstr ""
+"<a href=\"%1$s\">Logáil isteach</a> chun an breiseán turgnamhach seo a "
+"shuiteáil. <a href=\"%2$s\">Cén fáth</a>?"
+
+#. %1 is the URL for the Experimental Add-ons section of the FAQ page
+#: views/elements/amo2009/install.thtml:283 views/elements/install.thtml:232
+msgid "install_button_confirm_exp_install"
+msgstr ""
+"Ceadaigh dom an breiseán turgnamhach seo a shuiteáil. <a href=\"%1$s\">Cad É "
+"Seo?</a>"
+
+#. %1$s is the application name. Example: Firefox
+#. %2$s is an optional string used to specify a platform. Example: (Windows)
+#: views/elements/amo2009/install.thtml:128 views/elements/install.thtml:75
+#, php-format
+msgid "install_button_text"
+msgstr "Cuir le %1$s %2$s"
+
+# %1 is the add-on name, %2 is the app name
+#. %1 is the add-on name, %2 is the app name
+#: views/elements/amo2009/install.thtml:191
+#: views/elements/amo2009/install.thtml:206
+#: views/elements/amo2009/install.thtml:249
+#: views/elements/amo2009/install.thtml:298 views/elements/install.thtml:150
+#: views/elements/install.thtml:165 views/elements/install.thtml:202
+#: views/elements/install.thtml:246
+#, php-format
+msgid "install_button_title"
+msgstr "Cuir %1$s le %2$s"
+
+#. %1$s is the add-on name
+#: views/elements/amo2009/install.thtml:200 views/elements/install.thtml:159
+#, php-format
+msgid "install_download"
+msgstr "Ãosluchtaigh %1$s"
+
+#: views/elements/amo2009/install.thtml:147 views/elements/install.thtml:94
+msgid "install_error_addon_not_found"
+msgstr "Níl an breiseán seo ar fáil."
+
+#: views/addons/dictionaries.thtml:65
+msgid "langtools_a11y_tablesummary"
+msgstr "Liosta na bpacáistí teanga agus na bhfoclóirí."
+
+#: views/addons/dictionaries.thtml:47
+msgid "langtools_download_dictionary"
+msgstr "Ãosluchtaigh Foclóir"
+
+#: views/addons/dictionaries.thtml:48
+msgid "langtools_download_langpack"
+msgstr "Ãosluchtaigh Pacáiste Teanga"
+
+#: views/addons/dictionaries.thtml:63 controllers/components/amo.php:685
+#: controllers/addons_controller.php:1239
+msgid "langtools_header_dicts_and_langpacks"
+msgstr "Foclóirí agus Pacáistí Teanga"
+
+#: views/addons/dictionaries.thtml:44
+msgid "langtools_install_dictionary"
+msgstr "Suiteáil an Foclóir"
+
+#: views/addons/dictionaries.thtml:45
+msgid "langtools_install_langpack"
+msgstr "Suiteáil Pacáiste Teanga"
+
+#: views/addons/dictionaries.thtml:69
+msgid "langtools_tableheader_dictionary"
+msgstr "Foclóir"
+
+#: views/addons/dictionaries.thtml:70
+msgid "langtools_tableheader_langpack"
+msgstr "Pacáiste Teanga"
+
+#: views/addons/dictionaries.thtml:68
+msgid "langtools_tableheader_language"
+msgstr "Teanga"
+
+#: models/license.php:65
+#, fuzzy
+msgid "license_custom"
+msgstr "Custom License"
+
+#: config/bootstrap.php:303
+#, fuzzy
+msgid "licenses_bsd"
+msgstr "BSD License"
+
+#: config/bootstrap.php:298
+#, fuzzy
+msgid "licenses_gpl_2.0"
+msgstr "GNU General Public License, version 2.0"
+
+#: config/bootstrap.php:299
+#, fuzzy
+msgid "licenses_gpl_3.0"
+msgstr "GNU General Public License, version 3.0"
+
+#: config/bootstrap.php:300
+#, fuzzy
+msgid "licenses_lgpl_2.1"
+msgstr "GNU Lesser General Public License, version 2.1"
+
+#: config/bootstrap.php:301
+#, fuzzy
+msgid "licenses_lgpl_3.0"
+msgstr "GNU Lesser General Public License, version 3.0"
+
+#: config/bootstrap.php:302
+#, fuzzy
+msgid "licenses_mit"
+msgstr "MIT/X11 License"
+
+#: config/bootstrap.php:297
+#, fuzzy
+msgid "licenses_mpl_1.1"
+msgstr "Mozilla Public License, version 1.1"
+
+#: views/users/emailchange.thtml:51 views/users/delete.thtml:55
+#: views/users/delete.thtml:137 views/users/edit.thtml:74
+#: views/reviews/flag.thtml:54
+msgid "link_return_to_front_page"
+msgstr "Cliceáil anseo chun dul ar ais go dtí an príomhleathanach."
+
+#: views/elements/amo2009/addon_list_options.thtml:46
+#: views/elements/addon_list_options.thtml:46
+msgid "list_sortby_date"
+msgstr "Dáta"
+
+#: views/elements/amo2009/addon_list_options.thtml:47
+#: views/elements/addon_list_options.thtml:47
+msgid "list_sortby_downloads"
+msgstr "Líon na nÃosluchtuithe"
+
+#: views/elements/amo2009/addon_list_options.thtml:45
+#: views/elements/addon_list_options.thtml:45
+msgid "list_sortby_name"
+msgstr "Ainm an Bhreiseáin"
+
+#: views/elements/amo2009/addon_list_options.thtml:48
+#: views/elements/addon_list_options.thtml:48
+msgid "list_sortby_rating"
+msgstr "Rátáil"
+
+#: config/bootstrap.php:278
+msgid "main_prettyname_fennec"
+msgstr "Fennec"
+
+#: config/bootstrap.php:274
+msgid "main_prettyname_firefox"
+msgstr "Firefox"
+
+#: config/bootstrap.php:277
+msgid "main_prettyname_seamonkey"
+msgstr "SeaMonkey"
+
+#: config/bootstrap.php:276
+msgid "main_prettyname_sunbird"
+msgstr "Sunbird"
+
+#: config/bootstrap.php:275
+msgid "main_prettyname_thunderbird"
+msgstr "Thunderbird"
+
+#: views/elements/addon_categories.thtml:52
+msgid "nav_category_dicts_langpacks"
+msgstr "Foclóirí agus Pacáistí Teanga"
+
+#: views/elements/addon_categories.thtml:55
+msgid "nav_category_themes"
+msgstr "Téamaí"
+
+#: views/elements/app_chooser.thtml:47 views/layouts/amo2009.thtml:255
+msgid "other_apps_tooltip"
+msgstr "Aimsigh breiseáin le haghaidh feidhmchlár eile"
+
+# In a user list: user 1, user 2, "others"
+#. In a user list: user 1, user 2, "others"
+#: views/helpers/addons_html.php:222
+msgid "other_users"
+msgstr "eile"
+
+#: controllers/pages_controller.php:90
+msgid "page_title_appversions"
+msgstr "Leaganacha Feidhmchláir"
+
+#: controllers/pages_controller.php:115
+#, fuzzy
+msgid "page_title_collector"
+msgstr "Add-on Collector"
+
+#: controllers/pages_controller.php:117
+#, fuzzy
+msgid "page_title_collector_faq"
+msgstr "Add-on Collector FAQ"
+
+#: controllers/pages_controller.php:119
+#, fuzzy
+msgid "page_title_collector_features"
+msgstr "Add-on Collector Features"
+
+#: controllers/pages_controller.php:122
+#, fuzzy
+msgid "page_title_collector_firstrun"
+msgstr "Welcome to the Add-on Collector"
+
+#: controllers/pages_controller.php:92
+msgid "page_title_credits"
+msgstr "Admhálacha"
+
+#: controllers/pages_controller.php:113
+#, fuzzy
+msgid "page_title_developer_faq"
+msgstr "Developer FAQ"
+
+#: controllers/pages_controller.php:111
+msgid "page_title_faq"
+msgstr "Ceisteanna Coitianta"
+
+#: controllers/pages_controller.php:94
+#, fuzzy
+msgid "page_title_fashionyourfirefox_faq"
+msgstr "Fashion your Firefox FAQ"
+
+#: controllers/pages_controller.php:101
+msgid "page_title_policy"
+msgstr "Polasaí Breiseán"
+
+#: controllers/pages_controller.php:103
+msgid "page_title_privacy"
+msgstr "Polasaí Príobháideachta Mozilla"
+
+#: controllers/pages_controller.php:105
+msgid "page_title_review_guide"
+msgstr "Treoirlínte d'Eagarthóirí"
+
+#: controllers/pages_controller.php:107
+msgid "page_title_sandbox"
+msgstr "Córas Bosca Gainimh"
+
+#: controllers/pages_controller.php:109
+msgid "page_title_submissionhelp"
+msgstr "Cabhair le Seoladh Breiseán"
+
+#: views/pages/appversions.thtml:87
+msgid "pages_appversions_guid"
+msgstr "GUID"
+
+#: views/pages/appversions.thtml:79 controllers/pages_controller.php:90
+msgid "pages_appversions_header"
+msgstr "Leaganacha Bailí an Fheidhmchláir"
+
+#: views/pages/appversions.thtml:80
+msgid "pages_appversions_intro"
+msgstr ""
+"Ní mór comhad install.rdf a bheith ag gach breiseán a sheoltar chuig "
+"Breiseáin Mozilla, agus ní mór dó tacú le ceann de na feidhmchláir thíos ar "
+"a laghad. Ní cheadaítear ach na leaganacha seo a leanas do na feidhmchláir "
+"seo."
+
+#. %s is a full <a> tag
+#: views/pages/appversions.thtml:93
+#, php-format
+msgid "pages_appversions_required_files"
+msgstr ""
+"Fiú mura bhfuil comhad install.rdf de dhíth ar d'fheidhmchlár, caithfidh tú "
+"é a chur san áireamh mar sin féin, leis na réimsí riachtanacha mar a "
+"shonraítear %s."
+
+#. this is the text inside of an <a> tag for pages_appversions_required_files. This
+#. should be fixed.
+#: views/pages/appversions.thtml:93
+msgid "pages_appversions_required_files_link"
+msgstr "anseo"
+
+#: views/pages/appversions.thtml:88
+msgid "pages_appversions_versions"
+msgstr "Leaganacha"
+
+#: views/pages/policy.thtml:51
+msgid "pages_policy_sandbox_link"
+msgstr "Eolas faoin Bhosca Gainimh"
+
+#: views/elements/pagination.thtml:53
+msgid "pagination_next_page"
+msgstr "ar aghaidh"
+
+#: views/elements/pagination.thtml:52
+msgid "pagination_previous_page"
+msgstr "siar"
+
+#: views/elements/recaptcha.thtml:65
+msgid "recaptcha_enter_both_words"
+msgstr ""
+"Iontráil <strong>an dá fhocal</strong> thíos, <strong>le spás eatarthu</"
+"strong>."
+
+#: views/elements/recaptcha.thtml:83
+msgid "recaptcha_enter_here"
+msgstr "Cuir do fhreagra anseo:"
+
+#: views/elements/recaptcha.thtml:74
+msgid "recaptcha_enter_whatyouhear"
+msgstr "Clóscríobh an rud a chloiseann tú."
+
+# %1 is the link switching refreshing the captcha
+# %2 is the link switching to a text captcha
+#. %1 is the link switching refreshing the captcha
+#. %2 is the link switching to a text captcha
+#: views/elements/recaptcha.thtml:77
+msgid "recaptcha_hardtohear_text"
+msgstr ""
+"Mura bhfuil tú in ann é a thuiscint, is féidir leat <a href=\"%1$s"
+"\">éisteacht le ceann eile</a> nó <a href=\"%2$s\">athraigh go téacs arís</"
+"a>."
+
+# %1 is the link switching refreshing the captcha
+# %2 is the link switching to an audio captcha
+#. %1 is the link switching refreshing the captcha
+#. %2 is the link switching to an audio captcha
+#: views/elements/recaptcha.thtml:68
+msgid "recaptcha_hardtoread_text"
+msgstr ""
+"Mura bhfuil tú in ann é seo a léamh, is féidir leat triail a bhaint as <a "
+"href=\"%1$s\">focail eile</a> nó <a href=\"%2$s\">éisteacht le rud éigin</a>."
+
+#: views/users/register.thtml:105
+msgid "recaptcha_label"
+msgstr "An neach daonna thú?"
+
+#: views/users/register.thtml:106
+msgid "recaptcha_whatsthis"
+msgstr "Cad é seo?"
+
+#: controllers/reviews_controller.php:559
+msgid "review_flag_error"
+msgstr "Earráid agus bratach á cur leis an léirmheas seo!"
+
+#: models/reviews_moderation_flag.php:69
+#, fuzzy
+msgid "review_flag_reason_bug_support"
+msgstr "Misplaced bug report or support request"
+
+#: views/reviews/display.thtml:103 views/reviews/display.thtml:186
+msgid "review_flag_reason_instructions"
+msgstr "Déan gearán faoin léirmheas seo (roghnaigh an chúis)"
+
+#: models/reviews_moderation_flag.php:67
+msgid "review_flag_reason_language"
+msgstr "Plé/focail mhí-oiriúnacha"
+
+#: models/reviews_moderation_flag.php:71
+msgid "review_flag_reason_other"
+msgstr "Cúis eile (sonraigh, le do thoil)"
+
+#: models/reviews_moderation_flag.php:65
+msgid "review_flag_reason_spam"
+msgstr "Turscar nó ábhar nach mbaineann le léirmheas"
+
+#: views/reviews/display.thtml:91 views/reviews/display.thtml:175
+#: controllers/reviews_controller.php:555
+msgid "review_flag_success"
+msgstr ""
+"Go raibh maith agat; cuireadh bratach leis an léirmheas seo agus déanfaidh "
+"eagarthóir iniúchadh air."
+
+#: views/reviews/display.thtml:41
+msgid "review_flag_this"
+msgstr "Cuir bratach leis an léirmheas seo"
+
+#: views/reviews/display.thtml:42
+msgid "review_flag_this_titletip"
+msgstr ""
+"Léirmheas mí-oiriúnach nó míchruinn é seo? Turscar atá ann? Cliceáil "
+"anseo chun bratach a chur leis sa chaoi go ndéanfaidh eagarthóir iniúchadh "
+"air."
+
+#. %1 is the URL of the support section, %2 for the review guidelines
+#: views/reviews/add.thtml:53
+#, fuzzy
+msgid "review_guidelines_short"
+msgstr ""
+"<p>Keep these tips in mind:</p><ul><li>Write like you're telling a friend "
+"about your experience with the add-on. Give specifics and helpful details, "
+"such as what features you liked and/or disliked, how easy to use it is, and "
+"any disadvantages it has. Avoid generic language such as calling it \"Great"
+"\" or \"Bad\" unless you can give reasons why you believe this is so.</"
+"li><li>Please do not post bug reports in reviews. We do not make your email "
+"address available to add-on developers and they may need to contact you to "
+"help resolve your issue. See the <a href=\"%1$s\">support section</a> to "
+"find out where to get assistance for this add-on.</li><li>Please keep "
+"reviews clean, avoid the use of improper language and do not post any "
+"personal information.</li></ul><p>Please read the <a href=\"%2$s\">Review "
+"Guidelines</a> for more detail about user add-on reviews.</p>"
+
+#. %1 is the add-on name
+#: views/reviews/flag.thtml:56 views/reviews/display.thtml:55
+#: views/reviews/review_added.thtml:50
+#, php-format
+msgid "reviews_header"
+msgstr "Léirmheasanna ar %s"
+
+#: controllers/addons_controller.php:435
+msgid "rss_featuredaddons"
+msgstr "Breiseáin Mhór-Le-Rá"
+
+#: controllers/addons_controller.php:432
+msgid "rss_newestaddons"
+msgstr "Breiseáin Is Nuaí"
+
+#: controllers/addons_controller.php:434
+#, fuzzy
+msgid "rss_popularaddons"
+msgstr "Popular Add-ons"
+
+#: controllers/addons_controller.php:433
+msgid "rss_updatedaddons"
+msgstr "Breiseáin Nuashonraithe"
+
+#: views/elements/search_mini.thtml:70
+#, fuzzy
+msgid "search"
+msgstr "Search"
+
+#: views/search/collections.thtml:51
+#, fuzzy
+msgid "search_collections_header"
+msgstr "Collection Search Results"
+
+#: controllers/search_controller.php:297
+#, fuzzy
+msgid "search_collections_pagetitle"
+msgstr "Collection Search Results"
+
+#: controllers/search_controller.php:99
+msgid "search_disabled"
+msgstr ""
+"Tá an t-inneall cuardaigh díchumasaithe faoi láthair. Déan iarracht eile "
+"níos déanaí."
+
+#: views/elements/amo2009/search.thtml:188 views/elements/search.thtml:187
+#: views/elements/search_mini.thtml:54
+msgid "search_form_all_addons"
+msgstr "na mbreiseán go léir"
+
+#. This string is in the main category dropdown when searching
+#: views/elements/amo2009/search.thtml:204
+#, fuzzy
+msgid "search_form_all_collections"
+msgstr "all collections"
+
+#: views/elements/amo2009/search.thtml:184
+#: views/elements/amo2009/search.thtml:385
+#: views/elements/amo2009/search.thtml:408 views/elements/search.thtml:171
+#: views/elements/search.thtml:183 views/elements/search_mini.thtml:43
+#: views/elements/search_mini.thtml:49 views/layouts/mozilla.thtml:188
+msgid "search_form_default_text"
+msgstr "Lorg breiseáin"
+
+#: views/elements/amo2009/search.thtml:184
+#: views/elements/amo2009/search.thtml:404
+#, fuzzy
+msgid "search_form_default_text_collections"
+msgstr "search for collections"
+
+#: views/elements/amo2009/search.thtml:206 views/elements/search.thtml:202
+msgid "search_form_submit_tooltip"
+msgstr "Lorg breiseáin"
+
+#: views/elements/amo2009/search.thtml:184 views/elements/search.thtml:183
+#: views/elements/search_mini.thtml:49
+msgid "search_form_tooltip"
+msgstr "Cliceáil chun téarmaí cuardaigh a iontráil"
+
+# followed by "all add-ons", "
+#: views/elements/amo2009/search.thtml:186 views/elements/search.thtml:185
+#: views/elements/search_mini.thtml:52
+msgid "search_form_within"
+msgstr "i measc"
+
+#: views/addons/searchengines.thtml:118
+msgid "search_landing_all_search_engines"
+msgstr "Gach Inneall Cuardaigh"
+
+#: views/addons/searchengines.thtml:114
+msgid "search_landing_browse_search_engines"
+msgstr "Brabhsáil Innill Chuardaigh"
+
+#: views/search/collections.thtml:58 views/search/index.thtml:59
+msgid "search_nothing_found"
+msgstr "Níor aimsíodh aon rud."
+
+#: controllers/search_controller.php:185
+msgid "search_pagetitle"
+msgstr "Cuardaigh Breiseáin"
+
+#: controllers/search_controller.php:242
+msgid "search_rss_description"
+msgstr "Fotha na dtorthaí cuardaigh"
+
+#. %s is the terms the user is searching for (a string)
+#: controllers/search_controller.php:241
+#, php-format
+msgid "search_rss_results_for"
+msgstr "Torthaí cuardaigh le haghaidh: %s"
+
+#: views/elements/header.thtml:154 views/layouts/amo2009.thtml:296
+msgid "sidebar_navlink_admin_tools"
+msgstr "Uirlisí Riaracháin"
+
+#: views/elements/header.thtml:146 views/layouts/amo2009.thtml:288
+msgid "sidebar_navlink_developer_tools"
+msgstr "Uirlisí Forbróra"
+
+#: views/elements/header.thtml:148 views/layouts/amo2009.thtml:290
+msgid "sidebar_navlink_editor_tools"
+msgstr "Uirlisí Eagarthóra"
+
+#: views/layouts/amo2009.thtml:302
+msgid "sidebar_navlink_welcome"
+msgstr "Fáilte"
+
+#. %s is the user's name
+#: views/layouts/amo2009.thtml:302
+#, php-format
+msgid "sidebar_navlink_welcome_name"
+msgstr "Fáilte romhat, a %s"
+
+#: views/elements/pitch.thtml:50 views/elements/pitch.thtml:55
+msgid "sidebar_pitch_dictionary"
+msgstr "Foclóir"
+
+#: views/elements/pitch.thtml:72
+msgid "sidebar_pitch_featured_addons"
+msgstr "Breiseáin Shuntasacha"
+
+#: views/elements/pitch.thtml:61
+msgid "sidebar_pitch_looking_for"
+msgstr "Táim ag lorg:"
+
+#: views/elements/pitch.thtml:70
+msgid "sidebar_pitch_newest_addons"
+msgstr "Breiseáin Is Nuaí"
+
+#: views/elements/pitch.thtml:49
+msgid "sidebar_pitch_search"
+msgstr "Forlíontán Cuardaigh"
+
+#: views/elements/pitch.thtml:69
+msgid "sidebar_pitch_subscribe_to"
+msgstr "Liostáil le"
+
+#: views/elements/pitch.thtml:48 views/elements/pitch.thtml:54
+msgid "sidebar_pitch_theme"
+msgstr "Téama"
+
+#: views/elements/pitch.thtml:71
+msgid "sidebar_pitch_updated_addons"
+msgstr "Breiseáin Nuashonraithe"
+
+#. %1$s is a number
+#: views/helpers/localization.php:65 views/developers/versions_edit.thtml:95
+#: views/addons/dictionaries.thtml:92
+#, php-format
+msgid "size_kb"
+msgstr "%1$s kB"
+
+#: views/elements/amo2009/stars.thtml:57 views/elements/stars.thtml:63
+msgid "stars_not_yet_rated"
+msgstr "Gan rátáil fós"
+
+# %1 is the number of stars this add-on has
+#. %1 is the number of stars this add-on has
+#: views/elements/amo2009/stars.thtml:49 views/elements/stars.thtml:54
+#, php-format
+msgid "stars_rated_x_outof_5"
+msgstr "Rátáil %s as 5 réiltín"
+
+#: views/statistics/addon.thtml:59
+msgid "statistics_addon_dashboard_link"
+msgstr "Baile an Phainéil"
+
+#: views/statistics/addon.thtml:58
+msgid "statistics_addon_developertools_link"
+msgstr "Uirlisí Forbróra"
+
+#: views/statistics/addon.thtml:53
+msgid "statistics_addon_switch"
+msgstr "Athraigh an Breiseán"
+
+#. This is a date format.
+#. http://php.net/strftime
+#: views/statistics/rss/summary.thtml:54 views/statistics/addon.thtml:181
+msgid "statistics_date_shortmonth"
+msgstr "%e %b."
+
+#. This is a date format.
+#. http://php.net/strftime
+#: views/statistics/rss/summary.thtml:40 views/statistics/addon.thtml:152
+msgid "statistics_date_shortmonthwithyear"
+msgstr "%e %b., %Y"
+
+#. This is a date format.
+#. http://php.net/strftime
+#: views/statistics/rss/summary.thtml:41 views/statistics/rss/summary.thtml:48
+#: views/statistics/addon.thtml:161 views/statistics/addon.thtml:172
+msgid "statistics_date_weekdayshortmonth"
+msgstr "%A, %e %b."
+
+#. %1$s is an add-on name and version. Example: Add-on 3.5
+#: controllers/components/stats.php:519
+#, php-format
+msgid "statistics_events_addon_created"
+msgstr "Cruthaíodh %1$s"
+
+#. %1$s is an application name and version. Example: Firefox 3.5
+#: controllers/components/stats.php:500
+#, php-format
+msgid "statistics_events_app_released"
+msgstr "%1$s eisithe"
+
+#: views/statistics/addon.thtml:71
+msgid "statistics_help_close_link"
+msgstr "Dún"
+
+#: views/statistics/addon.thtml:60
+msgid "statistics_help_link"
+msgstr "Cabhair"
+
+#: views/statistics/index.thtml:83
+msgid "statistics_index_anotheraddon"
+msgstr "nó, roghnaigh breiseán eile"
+
+#: views/statistics/index.thtml:85
+msgid "statistics_index_anotheraddon_public"
+msgstr "nó, roghnaigh breiseán le staitisticí poiblí"
+
+#: views/statistics/index.thtml:71
+msgid "statistics_index_myaddons"
+msgstr "Roghnaigh ceann de do chuid breiseán chun a staitisticí a fheiceáil"
+
+#: views/statistics/index.thtml:89
+msgid "statistics_index_selectaddon"
+msgstr "Roghnaigh breiseán chun a staitisticí a fheiceáil"
+
+#: views/statistics/index.thtml:91
+msgid "statistics_index_selectaddon_public"
+msgstr "Roghnaigh breiseán le staitisticí poiblí"
+
+#: views/statistics/index.thtml:39
+msgid "statistics_index_title"
+msgstr "Painéal na Staitisticí"
+
+#: views/statistics/index.thtml:97
+msgid "statistics_index_view_button"
+msgstr "Amharc ar Staitisticí"
+
+#: views/statistics/addon.thtml:222 controllers/statistics_controller.php:247
+msgid "statistics_js_download_csv"
+msgstr "Féach ar an tábla seo i bhformáid CSV"
+
+#: controllers/statistics_controller.php:246
+msgid "statistics_js_dropdowns_none"
+msgstr "faic"
+
+#: controllers/statistics_controller.php:245
+msgid "statistics_js_dropdowns_removeplot"
+msgstr "Bain an graf seo"
+
+#: controllers/statistics_controller.php:248
+msgid "statistics_js_groupby_selector_date"
+msgstr "Grúpáil de réir: Lá"
+
+#: controllers/statistics_controller.php:251
+msgid "statistics_js_groupby_selector_month"
+msgstr "Grúpáil de réir: Mí"
+
+#: controllers/statistics_controller.php:249
+msgid "statistics_js_groupby_selector_week"
+msgstr "Grúpáil de réir: Seachtain"
+
+#: controllers/statistics_controller.php:250
+msgid "statistics_js_groupby_selector_week_over_week"
+msgstr "Cuir i gcomparáid de réir: Seachtain"
+
+#: controllers/statistics_controller.php:260
+msgid "statistics_js_plotselection_foundinrange"
+msgstr "Aimsíodh %s i raon"
+
+#: controllers/statistics_controller.php:270
+msgid "statistics_js_plotselection_options_addplot_name"
+msgstr "Cuir Graf Leis"
+
+#: controllers/statistics_controller.php:271
+msgid "statistics_js_plotselection_options_addplot_tooltip"
+msgstr "Cuir graf eile leis"
+
+#: controllers/statistics_controller.php:261
+msgid "statistics_js_plotselection_options_count_name_checked"
+msgstr "Folaigh an Líon Iomlán"
+
+#: controllers/statistics_controller.php:262
+msgid "statistics_js_plotselection_options_count_name_unchecked"
+msgstr "Taispeáin an Líon Iomlán"
+
+#: controllers/statistics_controller.php:263
+msgid "statistics_js_plotselection_options_count_tooltip"
+msgstr "Breac an líon iomlán ar an ngraf seo"
+
+#: controllers/statistics_controller.php:275
+msgid "statistics_js_plotselection_options_csv_name"
+msgstr "Amharc ar na Sonraí (CSV)"
+
+#: controllers/statistics_controller.php:276
+msgid "statistics_js_plotselection_options_csv_tooltip"
+msgstr "Faigh comhad CSV leis na sonraí seo"
+
+#: controllers/statistics_controller.php:267
+msgid "statistics_js_plotselection_options_events_addon_name_checked"
+msgstr "Folaigh Imeachtaí %s"
+
+#: controllers/statistics_controller.php:268
+msgid "statistics_js_plotselection_options_events_addon_name_unchecked"
+msgstr "Taispeáin Imeachtaí %s"
+
+#: controllers/statistics_controller.php:269
+msgid "statistics_js_plotselection_options_events_addon_tooltip"
+msgstr "Forleag dátaí eisiúna an bhreiseáin ar an ngraf"
+
+#: controllers/statistics_controller.php:264
+msgid "statistics_js_plotselection_options_events_firefox_name_checked"
+msgstr "Folaigh Imeachtaí Firefox"
+
+#: controllers/statistics_controller.php:265
+msgid "statistics_js_plotselection_options_events_firefox_name_unchecked"
+msgstr "Taispeáin Imeachtaí Firefox"
+
+#: controllers/statistics_controller.php:266
+msgid "statistics_js_plotselection_options_events_firefox_tooltip"
+msgstr "Forleag dátaí eisiúna Firefox ar an ngraf"
+
+#: controllers/statistics_controller.php:272
+msgid "statistics_js_plotselection_options_resize_name_checked"
+msgstr "Laghdaigh an Graf"
+
+#: controllers/statistics_controller.php:273
+msgid "statistics_js_plotselection_options_resize_name_unchecked"
+msgstr "Leathnaigh an Graf"
+
+#: controllers/statistics_controller.php:274
+msgid "statistics_js_plotselection_options_resize_tooltip"
+msgstr "Athraigh méid an ghraif"
+
+#: controllers/statistics_controller.php:254
+msgid "statistics_js_plotselection_selector_adu"
+msgstr "Úsáideoirí Gníomhacha Laethúla"
+
+#: controllers/statistics_controller.php:256
+msgid "statistics_js_plotselection_selector_application"
+msgstr "Feidhmchlár"
+
+#: controllers/statistics_controller.php:259
+msgid "statistics_js_plotselection_selector_custom"
+msgstr "Saincheaptha"
+
+#: controllers/statistics_controller.php:253
+msgid "statistics_js_plotselection_selector_downloads"
+msgstr "Ãosluchtuithe"
+
+#: controllers/statistics_controller.php:258
+msgid "statistics_js_plotselection_selector_os"
+msgstr "Córas Oibriúcháin"
+
+#: controllers/statistics_controller.php:257
+msgid "statistics_js_plotselection_selector_status"
+msgstr "Stádas an Bhreiseáin"
+
+#: controllers/statistics_controller.php:252
+msgid "statistics_js_plotselection_selector_summary"
+msgstr "Achoimre"
+
+#: controllers/statistics_controller.php:255
+msgid "statistics_js_plotselection_selector_version"
+msgstr "Leagan an Bhreiseáin"
+
+#: controllers/components/stats.php:398
+msgid "statistics_longnames_application"
+msgstr "Feidhmchlár"
+
+#: controllers/components/stats.php:400
+msgid "statistics_longnames_os"
+msgstr "Córas Oibriúcháin"
+
+#: controllers/components/stats.php:399
+msgid "statistics_longnames_status"
+msgstr "Stádas an Bhreiseáin"
+
+#: controllers/components/stats.php:401
+msgid "statistics_longnames_unknown"
+msgstr "Anaithnid"
+
+#: controllers/components/stats.php:397
+msgid "statistics_longnames_version"
+msgstr "Leagan an Bhreiseáin"
+
+#: views/statistics/addon.thtml:118
+msgid "statistics_notice_data_insufficient"
+msgstr ""
+"Níl go leor sonraí faoi láthair chun an graf seo a thaispeáint. Déan "
+"iarracht eile ar ball."
+
+#: views/statistics/addon.thtml:130
+msgid "statistics_notice_data_none"
+msgstr ""
+"Níl aon sonraí againn le haghaidh do bhreiseáin fós. Déan iarracht eile i "
+"gcúpla lá."
+
+#: views/statistics/addon.thtml:41
+msgid "statistics_notice_data_updating"
+msgstr ""
+"Tá na staitisticí breiseáin á nuashonrú faoi láthair. Seans go mbeidh na "
+"sonraí is déanaí ar iarraidh fad a oibríonn ár gcuid scripteanna chun an "
+"fhaisnéis seo a nuashonrú. Déan iarracht eile faoi cheann cúpla nóiméad."
+
+#: views/statistics/addon.thtml:136
+msgid "statistics_notice_disabled"
+msgstr ""
+"Tá Painéal na Staitisticí díchumasaithe faoi láthair. Déan iarracht eile ar "
+"ball."
+
+#: views/statistics/addon.thtml:123
+msgid "statistics_notice_nojavascript"
+msgstr "Tá JavaScript de dhíth chun Painéal na Staitisticí a fheiceáil."
+
+#: views/statistics/addon.thtml:44
+msgid "statistics_notice_settings_updated"
+msgstr "Nuashonraíodh do chuid socruithe!"
+
+#: controllers/statistics_controller.php:60
+#: controllers/statistics_controller.php:71
+#: controllers/statistics_controller.php:74
+#: controllers/statistics_controller.php:240
+msgid "statistics_pagetitle"
+msgstr "Painéal na Staitisticí"
+
+#: views/statistics/addon.thtml:99
+msgid "statistics_plot_legend_adu"
+msgstr "Úsáideoirí Gníomhacha Laethúla"
+
+#: views/statistics/addon.thtml:95
+msgid "statistics_plot_legend_downloads"
+msgstr "Ãosluchtuithe Laethúla"
+
+#: views/statistics/addon.thtml:107
+msgid "statistics_plot_options_zoomin_alt"
+msgstr "Súmáil Isteach"
+
+#: views/statistics/addon.thtml:106
+msgid "statistics_plot_options_zoomin_title"
+msgstr "Súmáil isteach mí amháin"
+
+#: views/statistics/addon.thtml:110
+msgid "statistics_plot_options_zoomout_alt"
+msgstr "Súmáil Amach"
+
+#: views/statistics/addon.thtml:109
+msgid "statistics_plot_options_zoomout_title"
+msgstr "Súmáil amach mí amháin"
+
+#: controllers/statistics_controller.php:283
+#, php-format
+msgid "statistics_rss_description"
+msgstr "Achoimre laethúil ar staitisticí do %1$s"
+
+#: views/statistics/rss/summary.thtml:68
+msgid "statistics_rss_title_fulldate"
+msgstr "%A, %e %B, %Y"
+
+#: views/statistics/rss/summary.thtml:68
+#, php-format
+msgid "statistics_rss_title_statsfordate"
+msgstr "Staitisticí le haghaidh %1$s"
+
+#: views/statistics/settings.thtml:49
+msgid "statistics_settings_access_description"
+msgstr ""
+"De réir réamhshocraithe, tá cead ag Mozilla agus agatsa féin faisnéis do "
+"phainéil a rochtain. Is féidir leat an painéal a oscailt sa chaoi gurbh "
+"fhéidir le héinne sonraí do bhreiseáin a fheiceáil."
+
+#: views/statistics/settings.thtml:48
+msgid "statistics_settings_access_heading"
+msgstr "Rochtain ar an bPainéal"
+
+#: views/statistics/settings.thtml:51
+msgid "statistics_settings_access_private"
+msgstr "Príobháideach"
+
+#: views/statistics/settings.thtml:51
+msgid "statistics_settings_access_private_description"
+msgstr ""
+"Tá cead ag Mozilla agus agatsa féin staitisticí an bhreiseáin seo a fheiceáil"
+
+#: views/statistics/settings.thtml:52
+msgid "statistics_settings_access_public"
+msgstr "Poiblí"
+
+#: views/statistics/settings.thtml:52
+msgid "statistics_settings_access_public_description"
+msgstr "Is féidir le héinne staitisticí an bhreiseáin seo a fheiceáil"
+
+#: views/statistics/addon.thtml:251
+msgid "statistics_settings_change_link"
+msgstr "Athraigh Socruithe"
+
+#: views/statistics/addon.thtml:253
+msgid "statistics_settings_confidential"
+msgstr "Ãirigh é seo mar eolas faoi rún."
+
+#: views/statistics/addon.thtml:245
+msgid "statistics_settings_currently_private"
+msgstr "Tá an painéal seo <b>príobháideach</b> faoi láthair."
+
+#: views/statistics/addon.thtml:241
+msgid "statistics_settings_currently_public"
+msgstr "Tá an painéal seo <b>poiblí</b> faoi láthair."
+
+#: views/statistics/addon.thtml:246
+msgid "statistics_settings_locked_alt"
+msgstr "Faoi Ghlas"
+
+#: views/statistics/settings.thtml:57
+msgid "statistics_settings_return_link"
+msgstr "Fill ar an bPainéal"
+
+#: views/statistics/settings.thtml:56
+msgid "statistics_settings_save_button"
+msgstr "Sábháil na Socruithe"
+
+#: views/statistics/settings.thtml:46
+#, php-format
+msgid "statistics_settings_title"
+msgstr "Socruithe Phainéal na Staitisticí le haghaidh %1$s"
+
+#: views/statistics/addon.thtml:242
+msgid "statistics_settings_unlocked_alt"
+msgstr "Díghlasáilte"
+
+#: controllers/components/stats.php:405
+msgid "statistics_shortnames_application"
+msgstr "Fdhm"
+
+#: controllers/components/stats.php:407
+msgid "statistics_shortnames_os"
+msgstr "CO"
+
+#: controllers/components/stats.php:406
+msgid "statistics_shortnames_status"
+msgstr "St"
+
+#: controllers/components/stats.php:408
+msgid "statistics_shortnames_unknown"
+msgstr "An"
+
+#: controllers/components/stats.php:404
+msgid "statistics_shortnames_version"
+msgstr "Leag"
+
+#: views/statistics/rss/summary.thtml:42 views/statistics/addon.thtml:192
+msgid "statistics_summary_downloads_average"
+msgstr "Meánlíon na nÃosluchtuithe sa lá"
+
+#: views/statistics/rss/summary.thtml:39
+msgid "statistics_summary_downloads_heading"
+msgstr "Ãosluchtuithe"
+
+#: views/statistics/rss/summary.thtml:41 views/statistics/addon.thtml:171
+msgid "statistics_summary_downloads_lastcount"
+msgstr "Líon sa lá is déanaí"
+
+#: views/statistics/rss/summary.thtml:43 views/statistics/addon.thtml:199
+msgid "statistics_summary_downloads_lastweek"
+msgstr "Ãosluchtuithe le linn na 7 lá is déanaí"
+
+#: views/statistics/rss/summary.thtml:40 views/statistics/addon.thtml:151
+msgid "statistics_summary_downloads_total"
+msgstr "Ãosluchtuithe Iomlána"
+
+#: views/statistics/rss/summary.thtml:40 views/statistics/addon.thtml:152
+#, php-format
+msgid "statistics_summary_downloads_total_sincedate"
+msgstr "Ó %1$s"
+
+#: views/statistics/rss/summary.thtml:50 views/statistics/rss/summary.thtml:56
+#: views/statistics/addon.thtml:163 views/statistics/addon.thtml:183
+msgid "statistics_summary_nodata"
+msgstr "Gan sonraí fós"
+
+#: views/statistics/rss/summary.thtml:60 views/statistics/addon.thtml:195
+msgid "statistics_summary_updatepings_average"
+msgstr "Meánlíon na nÚsáideoirí Gníomhacha sa lá"
+
+#: views/statistics/rss/summary.thtml:52 views/statistics/addon.thtml:177
+msgid "statistics_summary_updatepings_changefromprevious"
+msgstr "Athrú ón líon roimhe seo"
+
+#: views/statistics/rss/summary.thtml:54 views/statistics/addon.thtml:181
+#, php-format
+msgid "statistics_summary_updatepings_changefromprevious_ondate"
+msgstr "%1$s ar %2$s"
+
+#: views/statistics/rss/summary.thtml:45
+msgid "statistics_summary_updatepings_heading"
+msgstr "Úsáideoirí Gníomhacha Laethúla"
+
+#: views/statistics/rss/summary.thtml:46 views/statistics/addon.thtml:157
+msgid "statistics_summary_updatepings_total"
+msgstr "Úsáideoirí Gníomhacha Laethúla"
+
+#: views/statistics/rss/summary.thtml:48 views/statistics/addon.thtml:161
+#, php-format
+msgid "statistics_summary_updatepings_total_ondate"
+msgstr "Ar %1$s"
+
+#: views/statistics/rss/summary.thtml:61 views/statistics/addon.thtml:203
+#, fuzzy
+msgid "statistics_summary_updatepings_weekly_average"
+msgstr "Average Daily Users this Week"
+
+#. %s is a percentage, like '+22.33%'. It sits next to another number, so
+#. the implied meaning is 'percentage change' from the previous stat point.
+#: views/statistics/rss/summary.thtml:62 views/statistics/addon.thtml:205
+#, fuzzy
+msgid "statistics_summary_updatepings_weekly_change"
+msgstr "%s from last week"
+
+#: views/statistics/addon.thtml:65 controllers/statistics_controller.php:184
+#: controllers/statistics_controller.php:282
+#, php-format
+msgid "statistics_title_addon_stats"
+msgstr "Staitisticí %1$s"
+
+#: views/addons/themes_landing.thtml:113
+msgid "themes_landing_all_themes"
+msgstr "Gach Téama"
+
+#: views/addons/themes_landing.thtml:109
+msgid "themes_landing_browse_themes"
+msgstr "Brabhsáil Téamaí"
+
+#: views/users/edit.thtml:185
+msgid "user_change_email"
+msgstr "Athraigh Seoladh Ríomhphoist"
+
+#: views/users/edit.thtml:169
+msgid "user_change_password"
+msgstr "Athraigh focal faire"
+
+#: views/users/edit.thtml:96
+#, fuzzy
+msgid "user_change_password_or_email"
+msgstr "Change Password or Email"
+
+#: controllers/users_controller.php:197
+msgid "user_confirmationcode_resent"
+msgstr "Seoladh an cód dearbhaithe arís!"
+
+# %1 is the email address, %2 is the URL of the user registration page
+#. %1 is the email address, %2 is the URL of the user registration page
+#: views/users/delete.thtml:51
+msgid "user_del_account_deleted"
+msgstr ""
+"D'éirigh le scriosadh an chuntais %1$s. Más mian leat teacht ar ais linn lá "
+"breá éigin, b'fhéidir leat clárú arís ar an <a href=\"%2$s\">leathanach "
+"cláraithe</a>."
+
+#: views/users/delete.thtml:102
+msgid "user_del_community_sad"
+msgstr "Tá brón ar chomhphobal Breiseán Mozilla go bhfuil tú ag imeacht."
+
+#: views/users/delete.thtml:123
+msgid "user_del_confirm_password"
+msgstr "Dearbhaigh an Focal Faire"
+
+#: views/users/delete.thtml:134
+msgid "user_del_deletenow"
+msgstr "Scrios mo chuntas anois"
+
+#. %1 is the URL of the user's info page
+#: views/users/delete.thtml:64
+#, fuzzy
+msgid "user_del_error_addons"
+msgstr ""
+"You cannot delete your account if you are listed as an <a href=\"%1$s"
+"\">author of any add-ons</a>. To delete your account, please have another "
+"person in your development group delete you from the list of authors for "
+"your add-ons. Afterwards you will be able to delete your account here."
+
+# %1 is a link to the amo-editors mailing list
+#. %1 is a link to the amo-editors mailing list
+#: views/users/delete.thtml:71
+msgid "user_del_error_addons_more_questions"
+msgstr "Má tá ceisteanna eile agat, téigh i dteagmháil le %1$s."
+
+#: views/users/delete.thtml:78
+msgid "user_del_error_checkbox"
+msgstr ""
+"Caithfidh tú tic a chur sa bhosca \"Tuigim...\" sular féidir linn do chuntas "
+"a scriosadh."
+
+#: views/users/delete.thtml:84
+msgid "user_del_error_password"
+msgstr ""
+"Iontráil d'fhocal faire mar is ceart chun an chéim seo a chur i gcrích."
+
+# %1 is a link to the amo-admins mailing list
+#. %1 is a link to the amo-admins mailing list
+#: views/users/delete.thtml:91
+msgid "user_del_error_unknown"
+msgstr ""
+"Tharla earráid anaithnid agus do chuntas á scriosadh. Téigh i dteagmháil le %"
+"1$s agus scriosfaimid é ar do shon. Tá brón orainn."
+
+#: views/users/delete.thtml:110
+msgid "user_del_header_confirm_deletion"
+msgstr "Dearbhaigh scriosadh an chuntais"
+
+# %1 is the user's email address
+#. %1 is the user's email address
+#: views/users/delete.thtml:100
+msgid "user_del_header_delete_account"
+msgstr "Scrios Cuntas %1$s"
+
+#: views/users/delete.thtml:50
+msgid "user_del_header_farewell"
+msgstr "Slán agat!"
+
+#: views/users/delete.thtml:115
+msgid "user_del_nologin"
+msgstr "Ní bheidh tú in ann logáil isteach ar Bhreiseáin Mozilla a thuilleadh."
+
+#: views/users/delete.thtml:112
+msgid "user_del_permanently_removed_means"
+msgstr ""
+"Má chliceálfaidh tú \"scrios\", scriosfar do chuntas <strong>go brách</"
+"strong>. Ciallaíonn sé seo:"
+
+#: views/users/delete.thtml:116
+msgid "user_del_reviews_anonymized"
+msgstr ""
+"Ní scriosfar do chuid léirmheasanna agus rátálacha, ach ní bheidh bainte acu "
+"leatsa a thuilleadh."
+
+# %1 is a link to the amo-editors mailing list
+#. %1 is a link to the amo-editors mailing list
+#: views/users/delete.thtml:104
+msgid "user_del_specific_problem_editors"
+msgstr ""
+"Má tá fadhb ar leith agat, ná scrios do chuntas anois, ach téigh i "
+"dteagmháil linn ag %1$s agus déanfaimid ár ndícheall an fhadhb a réiteach."
+
+#: views/users/delete.thtml:130
+msgid "user_del_understand_permanent"
+msgstr "Tuigim nach mbeidh mé in ann dul ar ais tar éis na céime seo."
+
+#: views/helpers/addons_html.php:192
+msgid "user_deleted_nickname"
+msgstr "Úsáideoir Scriosta"
+
+# %1 is the new email address
+#. %1 is the new email address
+#: views/users/edit.thtml:71
+msgid "user_edit_confirm_email_sent"
+msgstr ""
+"Seoladh teachtaireacht ríomhphoist chuig %1$s chun do sheoladh nua a "
+"dhearbhú. Sular féidir an t-athrú a chur i gcrích, caithfidh tú cliceáil ar "
+"an nasc sa teachtaireacht seo. Go dtí sin, is féidir leat logáil isteach "
+"leis an seoladh ríomhphoist atá agat faoi láthair."
+
+#: views/users/edit.thtml:201
+msgid "user_edit_delete_user"
+msgstr "Scrios cuntas úsáideora"
+
+# This contains the email sent to users when they signed up for a new
+# account:
+# %1 is the confirmation URL, %2 is the current app
+#. This contains the email sent to users when they signed up for a new
+#. account:
+#. %1 is the confirmation URL, %2 is the current app
+#: views/users/email/confirm_plain.thtml:6
+#, php-format
+msgid "user_email_confirm_account_nopass"
+msgstr ""
+"Fáilte romhat go Breiseáin %2$s.\n"
+"\n"
+"Sular féidir leat do chuntas nua a úsáid, caithfidh tú é a ghníomhachtú - "
+"cinnteoidh sé seo gur seoladh bailí ríomhphoist atá agatsa.\n"
+"Chun do chuntas a ghníomhachtú, cliceáil an nasc thíos, nó cóipeáil agus "
+"greamaigh an nasc i mbarra suímh do bhrabhsálaí:\n"
+"\n"
+"%1$s\n"
+"\n"
+"Nuair atá do chuntas gníomhachtaithe, ní gá an teachtaireacht seo a "
+"choimeád.\n"
+"\n"
+"Go raibh maith agat as clárú le Breiseáin %2$s\n"
+"-- Foireann Breiseáin %2$s"
+
+# %1 is the confirmation url, %2 is the application name
+#. %1 is the confirmation url, %2 is the application name
+#: views/users/email/emailchange_plain.thtml:5
+msgid "user_email_confirm_emailchange"
+msgstr ""
+"D'iarr tú do sheoladh ríomhphoist a athrú ag Breiseáin %2$s.\n"
+"\n"
+"Chun an seoladh nua a dhearbhú, cliceáil an nasc thíos nó cóipeáil agus "
+"greamaigh é i mbarra suímh do bhrabhsálaí:\n"
+"\n"
+"%1$s\n"
+"\n"
+"Caithfidh tú an seoladh nua a dhearbhú laistigh de thréimhse 48 uair. Mura "
+"mian leat an seoladh a athrú, b'fhéidir leat neamhaird a dhéanamh den "
+"teachtaireacht seo.\n"
+"\n"
+"Go raibh maith agat!\n"
+"-- Foireann Breiseáin %2$s"
+
+#: controllers/users_controller.php:168
+#, php-format
+msgid "user_email_confirm_subject"
+msgstr "Go raibh maith agat as liostáil le Breiseáin %s"
+
+# This is the password reset email
+# %1 is the pw reset URL, %2 is the application
+#. This is the password reset email
+#. %1 is the pw reset URL, %2 is the application
+#: views/users/email/pwreset_plain.thtml:5
+#, php-format
+msgid "user_email_pwreset"
+msgstr ""
+"Breiseáin %2$s: Athshocrú Focail Faire\n"
+"\n"
+"Fuarthas iarratas ar fhocal faire do chuntais ar addons.mozilla.org a athrú."
+"Chun an focal faire seo a athrú, cliceáil an nasc seo a leanas, nó greamaigh "
+"é isteach i mbarra suímh do bhrabhsálaí:\n"
+"\n"
+"%1$s\n"
+"\n"
+"Mura ndearna tú an t-iarratas seo, ná bac leis an teachtaireacht.\n"
+"\n"
+"Go raibh maith agat,\n"
+"-- Foireann Breiseáin %2$s"
+
+#: controllers/users_controller.php:245
+#, php-format
+msgid "user_email_pwreset_subject"
+msgstr "Athshocraigh d'Fhocal Faire do Bhreiseáin %s"
+
+#: views/users/emailchange.thtml:50
+msgid "user_emailchange_error"
+msgstr "Earráid!"
+
+# %1 is the application name
+#. %1 is the application name
+#: controllers/users_controller.php:533
+msgid "user_emailchange_subject"
+msgstr "Dearbhaigh do sheoladh ríomhphoist nua ag Breiseáin %1$s"
+
+#: views/users/emailchange.thtml:48
+msgid "user_emailchange_success"
+msgstr "D'éirigh leis!"
+
+# %1 is the new email address
+#. %1 is the new email address
+#: views/users/emailchange.thtml:49
+msgid "user_emailchange_successful_description"
+msgstr ""
+"D'éirigh le hathrú do ríomhphoist. As seo amach, bain úsáid as %1$s chun "
+"logáil isteach."
+
+#: views/users/edit.thtml:134 views/admin/users_edit.thtml:111
+#, fuzzy
+msgid "user_form_bio"
+msgstr "About me"
+
+#: views/users/edit.thtml:135 views/admin/users_edit.thtml:112
+#, fuzzy
+msgid "user_form_bio_description"
+msgstr ""
+"Introduce yourself to the community, if you like! This text will appear "
+"publicly on your user info page. Line breaks will be preserved, but no HTML "
+"is allowed."
+
+#: views/users/pwreset.thtml:77 views/users/register.thtml:73
+#: views/users/edit.thtml:181
+msgid "user_form_confirmpassword"
+msgstr "Dearbhaigh an focal faire"
+
+#: views/users/edit.thtml:145
+#, fuzzy
+msgid "user_form_display_collections"
+msgstr "Display the collections I have created in my user profile"
+
+#: views/users/edit.thtml:149
+#, fuzzy
+msgid "user_form_display_collections_fav"
+msgstr "Display my favorite collections in my user profile"
+
+#: views/users/edit.thtml:86
+#, php-format
+msgid "user_form_editprofile"
+msgstr "Cuir an phróifíl úsáideora %s in eagar"
+
+#: views/users/pwreset.thtml:52 views/users/login.thtml:81
+#: views/users/register.thtml:63 views/users/edit.thtml:187
+msgid "user_form_email"
+msgstr "Seoladh ríomhphoist"
+
+#: views/users/register.thtml:78 views/users/edit.thtml:103
+#: views/admin/users_edit.thtml:76
+msgid "user_form_firstname"
+msgstr "Ainm"
+
+#: views/users/register.thtml:94 views/users/edit.thtml:119
+#: views/admin/users_edit.thtml:91
+msgid "user_form_hideemail"
+msgstr "Folaigh do sheoladh ríomhphoist"
+
+#: views/users/register.thtml:98 views/users/edit.thtml:123
+#: views/admin/users_edit.thtml:99
+msgid "user_form_homepage"
+msgstr "URL do shuímh Gréasáin"
+
+#: views/users/register.thtml:84 views/users/edit.thtml:109
+#: views/admin/users_edit.thtml:81
+msgid "user_form_lastname"
+msgstr "Sloinne"
+
+#: controllers/users_controller.php:333
+msgid "user_form_login"
+msgstr "Logáil Isteach"
+
+#: views/users/pwreset.thtml:72 views/users/edit.thtml:176
+msgid "user_form_newpassword"
+msgstr "Focal faire nua"
+
+#: views/users/register.thtml:89 views/users/edit.thtml:114
+#: views/admin/users_edit.thtml:86
+msgid "user_form_nickname"
+msgstr "Leasainm"
+
+#: views/users/edit.thtml:171
+msgid "user_form_oldpassword"
+msgstr "Focal faire roimhe seo"
+
+#: views/users/edit.thtml:97 views/users/edit.thtml:200
+msgid "user_form_otheractions"
+msgstr "Gníomhartha Eile"
+
+#: views/users/login.thtml:85 views/users/register.thtml:68
+msgid "user_form_password"
+msgstr "Focal Faire"
+
+#: controllers/users_controller.php:93
+msgid "user_form_registration"
+msgstr "Clárú Úsáideora Nua"
+
+#: views/users/login.thtml:90
+msgid "user_form_remember_me"
+msgstr "Meabhraigh mé ar an ríomhaire seo"
+
+#: views/admin/users_edit.thtml:95
+msgid "user_form_showsandbox"
+msgstr "Taispeáin an bosca gainimh?"
+
+#: views/users/edit.thtml:205
+msgid "user_form_submit_edit"
+msgstr "Sábháil"
+
+#: views/users/login.thtml:93
+msgid "user_form_submit_login"
+msgstr "Logáil isteach"
+
+#: views/users/register.thtml:113
+msgid "user_form_submit_register"
+msgstr "Cláraigh"
+
+#: views/users/info.thtml:75
+#, php-format
+msgid "user_info_usersince"
+msgstr "Úsáideoir Breiseáin %s ó"
+
+#: views/users/login.thtml:102
+msgid "user_login_register_link"
+msgstr "Cruthaigh cuntas nua úsáideora"
+
+#: views/users/edit.thtml:160
+msgid "user_notifications_item_compat"
+msgstr "Comhoiriúnacht an Bhreiseán (moltar é seo go láidir)"
+
+#: views/users/edit.thtml:161
+msgid "user_notifications_item_events"
+msgstr "Imeachtaí agus comórtais atá ag teacht"
+
+#: views/users/edit.thtml:156
+msgid "user_notifications_none_available"
+msgstr "Níl aon fhógairtí ar fáil le cumrú agat."
+
+#: views/users/edit.thtml:158
+msgid "user_notifications_select_topics"
+msgstr ""
+"Anois is arís, seolfaidh Mozilla teachtaireacht ríomhphoist maidir le "
+"leaganacha nua nó imeachtaí a bhaineann le breiseáin. Roghnaigh na hábhair "
+"thíos a bhfuil suim agat iontu:"
+
+#: views/users/edit.thtml:164
+#, fuzzy
+msgid "user_notifications_specific_contact"
+msgstr ""
+"Mozilla reserves the right to contact you individually about specific "
+"concerns with your hosted add-ons."
+
+#: controllers/users_controller.php:543
+msgid "user_profile_edit_error"
+msgstr ""
+"Bhí botúin sna hathruithe a rinne tú. Ceartaigh iad agus seol iad arís."
+
+#: controllers/users_controller.php:540
+msgid "user_profile_saved"
+msgstr "Nuashonraíodh an phróifíl."
+
+#: views/users/pwreset.thtml:65
+#, php-format
+msgid "user_pwreset_for_email"
+msgstr "Athshocraíodh an focal faire le haghaidh %s"
+
+#: controllers/users_controller.php:226
+msgid "user_pwreset_header"
+msgstr "Athshocrú Focail Faire"
+
+#: views/users/login.thtml:103
+msgid "user_pwreset_link"
+msgstr "An ndearna tú dearmad ar d'fhocal faire?"
+
+#: controllers/users_controller.php:248
+msgid "user_pwreset_link_sent"
+msgstr ""
+"Seoladh nasc chuig do sheoladh ríomhphoist lenar féidir d'fhocal faire a "
+"athshocrú."
+
+#: controllers/users_controller.php:304
+msgid "user_pwreset_okay"
+msgstr "D'éirigh le hathshocrú d'fhocail faire."
+
+#: views/users/pwreset.thtml:82
+msgid "user_pwreset_submit_changepw"
+msgstr "Cuir athrú an fhocail faire i bhfeidhm"
+
+#: views/users/pwreset.thtml:57
+msgid "user_pwreset_submit_sendlink"
+msgstr "Seol nasc lenar féidir d'fhocal faire a athshocrú"
+
+#: views/users/register_complete.thtml:51
+#, php-format
+msgid "user_register_amo_link"
+msgstr "Breiseáin %s"
+
+# %1 is the user's email address, %2 is the current app
+#. %1 is the user's email address, %2 is the current app
+#: views/users/activatefirst.thtml:49
+#, php-format
+msgid "user_register_click_confirm_link"
+msgstr ""
+"Seoladh nasc chuig %1$s lenar féidir do chuntas úsáideora a ghníomhachtú. "
+"Caithfidh tú an nasc seo a chliceáil sular féidir logáil isteach i "
+"mBreiseáin %2$s."
+
+# %1 is the user's email address
+#. %1 is the user's email address
+#: views/users/register_complete.thtml:49
+#, php-format
+msgid "user_register_confirm_email_sent"
+msgstr ""
+"Seoladh teachtaireacht ríomhphoist chuig %1$s chun do chuntas a dhearbhú. "
+"Sular féidir leat logáil isteach, caithfidh tú do chuntas a ghníomhachtú "
+"tríd an nasc sa teachtaireacht a chliceáil."
+
+#: views/users/activatefirst.thtml:51
+msgid "user_register_confirmation_link_text"
+msgstr "an teachtaireacht dearbhaithe a sheoladh arís"
+
+#: views/users/register_complete.thtml:47
+msgid "user_register_congratulations"
+msgstr "Comhghairdeas! Cruthaíodh do chuntas úsáideora."
+
+#: views/users/register.thtml:50
+#, fuzzy
+msgid "user_register_details"
+msgstr ""
+"<p>Registration on AMO is <strong>not required</strong> if you simply want "
+"to download and install public add-ons.</p><p>You only need to register if:</"
+"p><ul><li>You want to submit reviews for add-ons</li><li>You are an add-on "
+"developer and want to upload your add-on for hosting on AMO</li></ul><p>Upon "
+"successful registration, you will be sent a confirmation email to the "
+"address you provided. Please follow the instructions there to confirm your "
+"account.</p><p>If you like, you can read our <a href='%1$s' title='Legal "
+"Notices'>Legal Notices</a> and <a href='%2$s' title='Privacy Policy'>Privacy "
+"Policy</a>.</p>"
+
+# %1 is the link to the "resend confirmation code" page
+#. %1 is the link to the "resend confirmation code" page
+#: views/users/activatefirst.thtml:51
+#, php-format
+msgid "user_register_resend_confirmation_link"
+msgstr ""
+"Mura bhfuair tú an teachtaireacht dearbhaithe, bí cinnte nach raibh sé "
+"marcáilte mar \"dramhphost\" nó \"turscar\". Más gá, fiafraigh dínn %1$s "
+"chuig an seoladh ríomhphoist thuas."
+
+# %1 is the link to the Mozilla Add-ons front page
+#. %1 is the link to the Mozilla Add-ons front page
+#: views/users/register_complete.thtml:51
+#, php-format
+msgid "user_register_welcome"
+msgstr "Go raibh maith agat as clárú agus fáilte romhat go %1$s!"
+
+#: views/users/register.thtml:49
+msgid "user_register_welcome_header"
+msgstr "Fáilte go addons.mozilla.org (AMO)!"
+
+#: views/users/register.thtml:81 views/users/edit.thtml:106
+msgid "user_required_firstlast_or_nickname"
+msgstr "Ainm, sloinne, nó leasainm de dhíth."
+
+#: views/users/edit.thtml:94 views/users/edit.thtml:142
+#, fuzzy
+msgid "user_tab_collections"
+msgstr "Collections"
+
+#: views/users/edit.thtml:95 views/users/edit.thtml:154
+msgid "user_tab_notifications"
+msgstr "Fógairt"
+
+#: views/users/edit.thtml:93 views/users/edit.thtml:101
+msgid "user_tab_profile"
+msgstr "Próifíl Úsáideora"
+
+#: controllers/users_controller.php:209
+msgid "user_verified_okay"
+msgstr "D'éirigh leis an bhfíorú!"
+
+#: controllers/users_controller.php:723
+msgid "users_delete_pagetitle"
+msgstr "Scrios Cuntas"
+
+#: controllers/users_controller.php:414
+msgid "users_edit_pagetitle"
+msgstr "Cuntas Úsáideora le Cur in Eagar"
+
+#: views/users/info.thtml:71
+#, fuzzy
+msgid "users_info_aboutme"
+msgstr "About Me"
+
+#: views/users/info.thtml:96
+#, php-format
+msgid "users_info_addons_by_user"
+msgstr "Breiseáin le %1$s"
+
+#: views/users/info.thtml:51
+msgid "users_info_author_name"
+msgstr "Ainm"
+
+#: views/users/info.thtml:48
+msgid "users_info_author_profile"
+msgstr "Próifíl Úsáideora"
+
+#. %s is the user name
+#: views/users/info.thtml:137
+#, fuzzy
+msgid "users_info_collections_by_user"
+msgstr "Collections by %s"
+
+#: views/users/info.thtml:66
+msgid "users_info_email"
+msgstr "Seoladh ríomhphoist"
+
+#: views/users/info.thtml:155
+#, fuzzy
+msgid "users_info_fav_collections_by_user"
+msgstr "Favorite Collections"
+
+#: views/users/info.thtml:61
+msgid "users_info_homepage"
+msgstr "Leathanach baile"
+
+#: views/users/info.thtml:56
+msgid "users_info_nickname"
+msgstr "Leasainm"
+
+#: controllers/users_controller.php:707
+#, php-format
+msgid "users_info_pagetitle"
+msgstr "Faisnéis maidir le húsáideoir %1$s"
+
+# %1 is the user's name
+#. %1 is the user's name
+#: views/users/info.thtml:116
+msgid "users_info_reviews_by_user"
+msgstr "Léirmheasanna le %s"
+
+#: controllers/users_controller.php:330 controllers/users_controller.php:332
+msgid "users_login_pagetitle"
+msgstr "Logáil Isteach"
+
+# %1 is the link to the sandbox/policy explanation page
+# This message is for a specific add-on not found
+#. %1 is the link to the sandbox/policy explanation page
+#. This message is for a specific add-on not found
+#: views/users/login.thtml:53
+#, php-format
+msgid "users_login_sandbox_display_warning"
+msgstr ""
+"Tá an breiseán seo sa bhosca gainimh faoi láthair. Má tá cuntas Breiseáin "
+"Mozilla agat cheana, logáil isteach, nó faigh <a href=\"%1$s\">tuilleadh "
+"eolais faoin bhosca gainimh.</a>"
+
+# %1 is the link to the sandbox/policy explanation page
+# This message is for any given sandbox-related page not found
+#. %1 is the link to the sandbox/policy explanation page
+#. This message is for any given sandbox-related page not found
+#: views/users/login.thtml:56
+#, php-format
+msgid "users_login_sandbox_page_warning"
+msgstr ""
+"Tá an breiseán seo cuid den bhosca gainimh. Má tá cuntas Breiseáin Mozilla "
+"agat cheana, logáil isteach, nó faigh <a href=\"%1$s\">tuilleadh eolais "
+"faoin bhosca gainimh.</a>"
+
+#: controllers/users_controller.php:223 controllers/users_controller.php:225
+msgid "users_pwreset_pagetitle"
+msgstr "Athshocrú Focail Faire"
+
+#: controllers/users_controller.php:90 controllers/users_controller.php:92
+msgid "users_register_pagetitle"
+msgstr "Clárú Úsáideora Nua"
+
+#. %1$s is an addon name, like <a>Firebug</a>
+#. %2$s is a version number, like <a>1.2</a>
+#: views/versions/license.thtml:52
+#, fuzzy
+msgid "versions_license_header_source"
+msgstr "Source code license for %1$s %2$s"
+
+#: views/addons/category_landing.thtml:147
+#, fuzzy
+msgid "view_recently_added"
+msgstr "View all recently added"
+
+#: views/addons/category_landing.thtml:161
+#, fuzzy
+msgid "view_top_downloads"
+msgstr "View all top downloads"
+
+#: views/addons/category_landing.thtml:175
+#, fuzzy
+msgid "view_top_rated"
+msgstr "View all top rated"
+
+#~ msgid "addon_slider_tooltip_next"
+#~ msgstr "An Chéad Bhreiseán Eile"
+
+#~ msgid "addon_slider_tooltip_previous"
+#~ msgstr "An Breiseán Roimhe Seo"
+
+#~ msgid "addons_display_version_history"
+#~ msgstr "Stair Iomlán na Leaganacha"
+
+#~ msgid "addons_home_newest_header"
+#~ msgstr "Is Nuaí:"
+
+#~ msgid "addons_home_popular_header"
+#~ msgstr "Is Mó Éilimh Orthu:"
+
+#~ msgid "addons_home_recommended_header"
+#~ msgstr "Molaimid:"
+
+#~ msgid "addons_home_updated_header"
+#~ msgstr "Nuashonraithe Le Déanaí:"
+
+#~ msgid "addons_home_view_all"
+#~ msgstr "Taispeáin uile"
+
+#~ msgid "category_extra_allrecommended"
+#~ msgstr "Taispeáin Gach Breiseán Molta"
+
+#~ msgid "category_extra_highestrated"
+#~ msgstr "Rátáil is Airde Ar dTús"
+
+#~ msgid "category_extra_lastupdated"
+#~ msgstr "Nuashonrú Is Déanaí Ar dTús"
+
+# msgstr "Breiseáin Is Mó Éilimh Orthu Ar dTús" is a hair too long
+#~ msgid "category_extra_mostpopular"
+#~ msgstr "Is Mó Éilimh Orthu Ar dTús"
+
+#, fuzzy
+#~ msgid "collections_detail_js_loading"
+#~ msgstr "Loading"
+
+#, fuzzy
+#~ msgid "collections_detail_more_info"
+#~ msgstr "Show More Info"
+
+#, fuzzy
+#~ msgid "devcp_addon_status_criteria_review"
+#~ msgstr "Several user reviews of the add-on (may be external reviews)."
+
+#~ msgid "devcp_submit_accept_dev_agreement"
+#~ msgstr "Glacaim Leis"
+
+#~ msgid "devcp_submit_decline_dev_agreement"
+#~ msgstr "Diúltaím"
+
+#~ msgid "editors_submissiontype_new"
+#~ msgstr "Nua"
+
+#~ msgid "editors_submissiontype_updated"
+#~ msgstr "Nuashonraithe"
+
+#~ msgid "editors_th_addon_age"
+#~ msgstr "Aois an Bhreiseáin"
+
+#~ msgid "editors_th_addontypes"
+#~ msgstr "Cineálacha Breiseáin"
+
+#~ msgid "editors_th_applications"
+#~ msgstr "Feidhmchláir"
+
+#~ msgid "editors_th_platforms"
+#~ msgstr "Ardáin"
+
+#~ msgid "editors_th_submissiontypes"
+#~ msgstr "Cineálacha na mBreiseán"
+
+#~ msgid "forum_save"
+#~ msgstr "Sábháil"
+
+#, fuzzy
+#~ msgid "home"
+#~ msgstr "home"
+
+#~ msgid "nav_category_plugins"
+#~ msgstr "Breiseáin"
+
+# %1 is page number, %2 is total page count
+#~ msgid "pagination_page_number_title"
+#~ msgstr "Seo é leathanach %1$s as %2$s"
+
+#~ msgid "search_matching_addons_number"
+#~ msgid_plural "search_matching_addons_number"
+#~ msgstr[0] "%s bhreiseán comhoiriúnach"
+#~ msgstr[1] "%s bhreiseán chomhoiriúnacha"
+#~ msgstr[2] "%s bhreiseán chomhoiriúnacha"
+#~ msgstr[3] "%s mbreiseán chomhoiriúnacha"
+#~ msgstr[4] "%s breiseán chomhoiriúnacha"
+
+#~ msgid "statistics_rss_icon_title"
+#~ msgstr "Fotha RSS le sonraí achoimrithe"
diff --git a/site/app/locale/ga_IE/images/sandbox-review.png b/site/app/locale/ga_IE/images/sandbox-review.png
new file mode 100644
index 0000000..ba3488d
--- /dev/null
+++ b/site/app/locale/ga_IE/images/sandbox-review.png
Binary files differ
diff --git a/site/app/locale/ga_IE/pages/error404.thtml b/site/app/locale/ga_IE/pages/error404.thtml
new file mode 100644
index 0000000..ebfbc37
--- /dev/null
+++ b/site/app/locale/ga_IE/pages/error404.thtml
@@ -0,0 +1,16 @@
+<h1>Tá brón orainn, ach níor aimsíodh an comhad atá uait.</h1>
+
+<p>Níor aimsíodh an leathanach nó comhad a d'iarr tú ar ár suíomh. B'fhéidir gur chliceáil tú nasc atá as dáta, nó gur chuir tú seoladh mícheart isteach.</p>
+
+<ul>
+<li>Má chlóscríobh tú an seoladh, seiceáil an litriú arís.</li>
+<li>Má lean tú nasc ó áit éigin, abair linn ag <a href="mailto:webmaster@mozilla.com" title="Page Not Found on Mozilla.com">webmaster@mozilla.com</a>. Abair linn cén áit ar tháinig tú as, agus cad é a bhí tú ag lorg, agus déanfaidh muid ár ndícheall an fhadhb a réiteach.</li>
+</ul>
+
+<p>Nó, déan cuairt ar na leathanaigh is mó éilimh orthu ar ár suíomh.</p>
+
+<ul>
+<li>An bhfuil suim agat sna <a href="%1$s">breiseáin atá i mbéal an phobail</a>?</li>
+<li>Ar mhaith leat <a href="%2$s">breiseáin a lorg</a>? Déan cuairt ar an <a href="%2$s">leathanach cuardaigh</a> nó bain úsáid as an mbosca cuardaigh thuas.</li>
+<li>Má b'fhearr leat tosú arís, téigh go dtí an <a href="%3$s">leathanach baile</a>.</li>
+</ul>
diff --git a/site/app/locale/ga_IE/pages/nomination.thtml b/site/app/locale/ga_IE/pages/nomination.thtml
new file mode 100644
index 0000000..77dff98
--- /dev/null
+++ b/site/app/locale/ga_IE/pages/nomination.thtml
@@ -0,0 +1,10 @@
+<p>Is féidir breiseán atá sa bhosca gainimh faoi láthair a ainmniú sa chaoi go mbeidh sé cuid den suíomh poiblí agus ar fáil do gach úsáideoir tar éis go ndéanfaidh eagarthóir iniúchadh air. Chun na torthaí is fearr a bhaint amach, tabhair faoi deara na rudaí seo a leanas:</p>
+<ul>
+ <li>Tá íomhá réamhamhairc ag teastáil le haghaidh téamaí, agus moltar iad go láidir le haghaidh cineálacha eile breiseán.</li>
+ <li>Ba chóir don bhreiseán a bheith sa bhosca gainimh ar feadh tréimhse sách fada go bhfaighfeadh sé léirmheasanna agus aiseolas ó úsáideoirí. <b>Cuirfear na léirmheasanna go léir os comhair an tsaoil.</b></li>
+ <li>Ceaptar go mbeidh cáilíocht níos airde ag breiseáin phoiblí - ba chóir dóibh an Gréasán a fheabhsú ar shlí éigin.</li>
+ <li>Tá na critéir ainmnithe ina n-iomláine ar fáil sa <a href="%s">Pholasaí Breiseáin</a>.</li>
+</ul>
+<p>Má chomhlíonann do bhreiseán na critéir seo, is féidir é a ainmniú tríd an réimse thíos a líonadh. Rachaidh muid i dteagmháil leat trí ríomhphost maidir le stádas d'ainmniúcháin.</p>
+
+<p>Chun do bhreiseán a ainmniú, déan cur síos ar an bpróiseas tástála (agus cuir in iúl dúinn nach bhfuil aon earráidí nó rabhaidh ann) agus conas a bheidh sé áisiúil ar an nGréasán go ginearálta. Is féidir leat naisc le léirmheasanna seachtracha nó faisnéis eile a chur san áireamh.</p>
diff --git a/site/app/locale/ga_IE/pages/sandbox.thtml b/site/app/locale/ga_IE/pages/sandbox.thtml
new file mode 100644
index 0000000..e0449ea
--- /dev/null
+++ b/site/app/locale/ga_IE/pages/sandbox.thtml
@@ -0,0 +1,13 @@
+<h1>Córas Bosca Gainimh</h1>
+<h2>Cad é an bosca gainimh?</h2>
+<p>Is éard atá sa bhosca gainimh ná áit ar féidir le hardúsáideoirí breiseáin a thástáil sula gcuirfear iad ar fáil don saol mór. Chun an bosca gainimh a rochtain, caithfidh tú é a chumasú i socruithe do chuntais. Ba chóir duit a bheith cúramach agus breiseáin ón bhosca gainimh a shuiteáil, toisc nach ndearna eagarthóir iniúchadh orthu agus seans go ndéanfaidh siad dochar do do ríomhaire.</p>
+
+<h2>Conas is féidir mo bhreiseán a chur ar an taobh poiblí?</h2>
+<!-- To localize the flowchart image, see http://wiki.mozilla.org/Update:Remora_Sandbox_Flowchart -->
+<div style="text-align: center;">%s</div>
+<ol>
+ <li><b>Uasluchtaigh do bhreiseán sna hUirlisí Forbróra.</b> Feicfidh tú do bhreiseán láithreach ar an taobh "Bosca Gainimh" de Bhreiseáin Mhozilla, áit a ndéanfaidh ardúsáideoirí tástáil air. Chun an bosca gainimh a fheiceáil, caithfidh tú é a chumasú i socruithe do chuntais.</li>
+ <li><b>Ainmnigh do bhreiseán chun é a bhogadh go dtí an taobh poiblí.</b> Ó na hUirlisí Forbróra, beidh nasc ann lenar féidir do bhreiseán a ainmniú. Tar éis duit é a ainmniú, taispeánfar é sa Chiú Ainmniúchán go dtí go ndéanfaidh eagarthóir iniúchadh air.</li>
+ <li><b>Déanann eagarthóir iniúchadh ar do bhreiseán.</b> Suiteálfaidh eagarthóir ó Bhreiseáin Mhozilla do bhreiseán agus cinnteoidh sé/sí go bhfuil sé ag obair mar is ceart. Féachfaidh an t-eagarthóir ar na léirmheasanna ó thástálaithe sa bhosca gainimh freisin.</li>
+ <li><b>Cuirtear do bhreiseán ar an taobh poiblí nó coinnítear é sa bhosca gainimh.</b> Cuirfidh an t-eagarthóir do bhreiseán ar an taobh poiblí nó coinneoidh sé/sí é sa bhosca gainimh. Má fhanann sé sa bhosca gainimh, is féidir leat é a ainmniú arís tar éis duit na hathruithe a mholann an t-eagarthóir a chur i bhfeidhm. Má chuirtear é ar an taobh poiblí, cuirfear leaganacha do bhreiseáin amach anseo sa bhosca gainimh go dtí go ndéanfaidh eagarthóir iniúchadh orthu. Chomh luath is atá do bhreiseán poiblí, ní gá duit é a ainmniú arís - rachaidh leaganacha nua sa chiú ar feitheamh ar eagarthóir.</li>
+</ol>
diff --git a/site/app/locale/ga_IE/pages/statistics_help.thtml b/site/app/locale/ga_IE/pages/statistics_help.thtml
new file mode 100644
index 0000000..107264c
--- /dev/null
+++ b/site/app/locale/ga_IE/pages/statistics_help.thtml
@@ -0,0 +1,7 @@
+<h3>Cabhair</h3>
+<p>Ar Phainéal na Staitisticí, taispeántar sonraí bailithe ag an suíomh faoi íosluchtuithe agus faoi phingeanna nuashonraithe do bhreiseáin.</p>
+<h4>Ãosluchtuithe</h4>
+<p>Athshonraítear líon na n-íosluchtuithe gach lá, agus is iad íosluchtuithe an bhunleagain atá i gceist, gan leaganacha nuashonraithe a chur san áireamh.</p>
+
+<h4>Pingeanna Nuashonraithe</h4>
+<p>Nuair a íosluchtaíonn úsáideoir breiseán ón suíomh seo, lorgóidh sé nuashonruithe uair amháin sa lá. Tugtar \"Úsáideoirí Gníomhacha Laethúla\" ar líon iomlán na bpingeanna nuashonraithe seo. Is féidir na hÚsáideoirí Gníomhacha Laethúla a mhiondealú de réir leagan an bhreiseáin, córas oibriúcháin, stádas an bhreiseáin, agus feidhmchlár. Bailítear na sonraí seo lá amháin gach seachtain, ar an gCéadaoin.</p>
diff --git a/site/app/locale/ga_IE/pages/submission_help.thtml b/site/app/locale/ga_IE/pages/submission_help.thtml
new file mode 100644
index 0000000..c5cb9a6
--- /dev/null
+++ b/site/app/locale/ga_IE/pages/submission_help.thtml
@@ -0,0 +1,35 @@
+<h1>Cabhair le Seoladh Breiseán Nua</h1>
+Réimsí riachtanacha i <b>gcló trom</b> agus réimsí roghnacha i <i>gcló iodálach</i>.
+<h2 id="step1">Céim 1: Uasluchtú</h2>
+<ul class="submissionHelp">
+ <li><span class="required">Cineál an Bhreiseáin</span> - De réir réamhshocraithe, cinnfear cineál an bhreiseáin go huathoibríoch bunaithe ar an gcomhad uasluchtaithe. Ní dócha go mbeidh ort an réimse seo a athrú.</li>
+ <li><span class="required">Comhad Breiseáin</span> - Comhad pacáiste do bhreiseáin, le comhad install.rdf san áireamh. Má oibríonn an comhad ar chóras áirithe amháin, ceadófar duit ilchomhad a uasluchtú d'aon iarraidh má roghnaíonn tú an córas sin.</li>
+ <li><span class="optional">Comhad Deilbhín</span> - Taispeántar an comhad deilbhín in aice le hainm an bhreiseáin ar a leathanach taispeána, agus taispeántar é ar dhialóg shuiteáil an bhreiseáin. Athrófar a mhéid go 32x32 picteilín, agus coimeádfar an cóimheas treoíochta.</li>
+ <li><span class="required">Logchaighdeán Réamhshocraithe</span> - Príomh-logchaighdeán an bhreiseáin é a logchaighdeán réamhshocraithe. Mura bhfuil logchaighdeán an úsáideora ar fáil don bhreiseán, úsáidfear an logchaighdeán réamhshocraithe ina ionad.</li>
+ <li><span class="optional">Ní gá an t-eolas faoin bhreiseán seo a nuashonrú</span> - Má tá tú ag nuashonrú breiseáin atá ann, taispeánfar an réimse seo duit. Má chuireann tú tic sa bhosca, rachfar ar aghaidh go céim a trí, ina n-iontrálfaidh tú faisnéis sainiúil don leagan.</li>
+</ul>
+
+<h2 id="step2">Céim 2: Mionsonraí an Bhreiseáin</h2>
+<ul class="submissionHelp">
+ <li><span class="required">Ainm</span> - Ainm an bhreiseáin sa logchaighdeán réamhshocraithe.</li>
+ <li><span class="required">Údair</span> - Taispeánfar na húsáideoirí a bhfuil cead acu sonraí an bhreiseáin a athrú ar an leathanach taispeána mar údair.</li>
+ <li><span class="required">Catagóirí</span> - Catagóirí a bhaineann leis an mbreiseán.</li>
+ <li><span class="optional">Leathanach Baile</span> - Suíomh Gréasáin an bhreiseáin sa logchaighdeán réamhshocraithe.</li>
+ <li><span class="required">Achoimre</span> - Cur síos gairid ar an mbreiseán sa logchaighdeán réamhshocraithe. Ní cheadaítear níos mó ná 250 carachtar sa réimse seo, agus taispeánfar é ar leathanach taispeána an bhreiseáin, agus i dtorthaí cuardaigh.</li>
+ <li><span class="required">Cur Síos</span> - Cur síos níos faide ar an mbreiseán sa logchaighdeán réamhshocraithe. Taispeánfar é seo ar leathanach taispeána an bhreiseáin, faoin achoimre.</li>
+ <li><span class="optional">EULA</span> - Comhaontú um Cheadúnas a gcuirfear ar úsáideoirí glacadh leis sula n-íosluchtaíonn siad an breiseán, sa logchaighdeán réamhshocraithe.</li>
+ <li><span class="optional">Polasaí Príobháideachta</span> - Polasaí Príobháideachta an bhreiseáin, sa logchaighdeán réamhshocraithe. Míníonn sé cad a dhéanann an breiseán le faisnéis phearsanta an úsáideora, agus nascfar é in aice leis an gcnaipe suiteála ar leathanach taispeána an bhreiseáin. Tá tuilleadh eolais ar fáil sa <a href="%s">Pholasaí Breiseán</a> faoi cad is cóir a chur i bPolasaí Príobháideachta, agus eolas breise mura bhfuil tú cinnte an bhfuil a leithéid polasaí de dhíth ar do bhreiseán.</li>
+ <li><span class="optional">Ceadaigh d'úsáideoirí na comhaid fhoinseacha a fheiceáil ar líne</span> - Má chuireann tú tic sa bhosca seo, beidh úsáideoirí in ann comhaid fhoinseacha do bhreiseáin a bhrabhsáil ar líne.</li>
+ <li><span class="optional">Réamhleagan é seo</span> - Cuir tic sa bhosca seo má tá sé réamhleagan, nó leagan "béite" den bhreiseán. Ba chóir réamhleaganacha a fhágáil sa bhosca gainimh, agus ní féidir iad a ainmniú don taobh poiblí go dtí go mbainfidh tú an bhratach seo de.</li>
+ <li><span class="optional">Breiseán sainiúil do shuíomh é seo</span> - Cuir tic sa bhosca seo má tá an breiseán sainiúil do shuíomh aonair, mar shampla breiseán a athraíonn dealramh suíomh éigin, nó a thaispeánann ábhar ó shuíomh éigin. Cabhraíonn an réimse seo le heagarthóirí, agus seans go mbainfear úsáid as amach anseo chun cuardaigh a scagadh.</li>
+ <li><span class="optional">Tá bogearraí seachtracha de dhíth ar an mbreiseán seo</span> - Cuir tic sa bhosca seo má tá bogearraí seachtracha de dhíth ar an mbreiseán. Cabhraíonn an réimse seo le heagarthóirí, agus seans go mbainfear úsáid as amach anseo chun cuardaigh a scagadh.</li>
+</ul>
+
+<h2 id="step3">Céim 3: Mionsonraí an Bhreiseáin</h2>
+<ul class="submissionHelp">
+ <li><span class="required optional">Nótaí Eisiúna</span> - Achoimre nó liosta de na hathruithe sa leagan seo. Is roghnach é seo le haghaidh breiseáin nua, ach tá sé ag teastáil le haghaidh nuashonruithe.</li>
+ <li><span class="optional">Nótaí don Eagarthóir</span> - Úsáid an réimse seo chun eolas a thabhairt do na heagarthóirí a dhéanfaidh iniúchadh ar do bhreiseán. Ba chóir duit eolas faoi chuntas tástála agus nótaí speisialta a chur anseo.</li>
+</ul>
+
+<h2 id="step4">Céim 4: Logánú</h2>
+Seo é an áit ar féidir logánú a dhéanamh ar réimsí an bhreiseáin in aon cheann de na logchaighdeáin a dtacaítear leo. Cliceáil logchaighdeán ar bith chun na haistriúcháin a chur isteach.
diff --git a/site/app/locale/he/LC_MESSAGES/messages.mo b/site/app/locale/he/LC_MESSAGES/messages.mo
new file mode 100644
index 0000000..6084a83
--- /dev/null
+++ b/site/app/locale/he/LC_MESSAGES/messages.mo
Binary files differ
diff --git a/site/app/locale/he/LC_MESSAGES/messages.po b/site/app/locale/he/LC_MESSAGES/messages.po
new file mode 100644
index 0000000..1996967
--- /dev/null
+++ b/site/app/locale/he/LC_MESSAGES/messages.po
@@ -0,0 +1,8639 @@
+# Remora Preliminary Language File
+# Copyright (C) 2006 Mozilla Corporation
+# This file is distributed under the same license as the REMORA package.
+# Wil Clouser <clouserw@mozilla.com>, 2006.
+# Tomer Cohen <tomerc@gmail.com>
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: REMORA 0.1\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2009-01-16 11:45-0800\n"
+"PO-Revision-Date: 2008-09-11 20:53+0200\n"
+"Last-Translator: Amiad <amiadb@gmail.com>\n"
+"Language-Team: Hebrew\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=n != 1;\n"
+"X-Poedit-Language: Hebrew\n"
+"X-Poedit-Country: Israel\n"
+
+#: views/addons/policy.thtml:98
+msgid "a_cancel_installation"
+msgstr "בטל התקנה"
+
+#. This is the text that appears on buttons to download add-ons.
+#. %$1s is an optional string that only appears if the add-on is only available for
+#. a certain platform. Examples: (Windows) or (Linux)
+#. Note that the parentheses are included in the string. :(
+#: views/elements/amo2009/install.thtml:126
+#: views/elements/amo2009/install.thtml:227
+#: views/elements/amo2009/install.thtml:257
+#: views/elements/amo2009/install.thtml:300
+#: views/elements/amo2009/install.thtml:312 views/elements/install.thtml:73
+#: views/elements/install.thtml:181 views/elements/install.thtml:205
+#: views/elements/install.thtml:248 views/elements/install.thtml:260
+#: views/addons/plugins.thtml:66 views/addons/plugins.thtml:76
+#: views/addons/plugins.thtml:86 views/addons/plugins.thtml:96
+#: views/addons/plugins.thtml:119
+#, php-format
+msgid "a_download"
+msgstr "הורד עכשיו ×ת %s"
+
+#: views/addons/policy.thtml:72
+msgid "a_eula_download"
+msgstr "×”×¡×›× ×•×”×•×¨×“"
+
+#: views/addons/policy.thtml:74
+msgid "a_eula_install"
+msgstr "קבל והתקן"
+
+#: views/elements/header.thtml:76 views/elements/header.thtml:82
+#: views/api/api_addon.thtml:55 views/api/collections_feed.thtml:75
+#: views/sharing_api/addon.thtml:64
+msgid "a_header_public"
+msgstr "ציבורי"
+
+#: views/elements/header.thtml:58 views/elements/header.thtml:75
+#: views/elements/header.thtml:80 views/api/api_addon.thtml:57
+#: views/api/collections_feed.thtml:77 views/sharing_api/addon.thtml:66
+msgid "a_header_sandbox"
+msgstr "×רגז החול"
+
+#. %s is a date in the _('date') format
+#: views/elements/amo2009/homepage_addon.thtml:115
+#: views/elements/addon_listitem.thtml:122 views/elements/feature.thtml:106
+#: views/addons/display.thtml:104 views/addons/browse_thumbs.thtml:73
+msgid "addon_detail_last_updated"
+msgstr "%s עודכן"
+
+#. %s is the version of the add-on. Example: 3.2a1
+#: views/elements/amo2009/addon_version_detail.thtml:51
+#: views/elements/addon_version_detail.thtml:51
+#, php-format
+msgid "addon_display_header_version"
+msgstr "גירסה %s"
+
+#: views/addons/browse_thumbs.thtml:80
+msgid "addon_downloads"
+msgstr "הורדות"
+
+#: views/addons/display.thtml:147
+msgid "addon_downloads_total"
+msgstr "סה\"כ הורדות"
+
+#: views/elements/amo2009/homepage_addon.thtml:106
+#: views/elements/addon_listitem.thtml:115 views/elements/feature.thtml:101
+#: views/addons/category_landing.thtml:157 views/addons/display.thtml:146
+#: views/addons/browse_thumbs.thtml:80
+msgid "addon_downloads_weekly"
+msgstr "הורדות לשבוע"
+
+#. %1 is the add-on count, %2 the category name
+#: views/addons/browse_thumbs.thtml:104 views/addons/browse.thtml:60
+#, php-format
+msgid "addon_list_category_totalcount"
+msgid_plural "addon_list_category_totalcount"
+msgstr[0] "%1$s \"%2$s\" תוספת"
+msgstr[1] "%1$s \"%2$s\" תוספות"
+
+#: views/elements/amo2009/addon_list_options.thtml:103
+#: views/elements/pagination.thtml:67
+#: views/elements/addon_list_options.thtml:94
+msgid "addon_list_perpage"
+msgstr "לפי עמוד"
+
+#: views/elements/amo2009/addon_list_options.thtml:84
+#: views/elements/addon_list_options.thtml:98
+msgid "addon_list_sortby"
+msgstr "מיין לפי:"
+
+#: views/helpers/addons_html.php:568 views/elements/amo2009/install.thtml:321
+#: views/elements/feature.thtml:89
+msgid "addon_listitem_flag_experimental"
+msgstr "נסיוני"
+
+#: views/helpers/addons_html.php:570
+msgid "addon_listitem_flag_recommended"
+msgstr "מומלץ"
+
+#. %1 is the add-on name, %2 is the platform
+#: views/pages/js_constants.js.thtml:66
+msgid "addon_not_available_for_platform"
+msgstr "%1$s ×œ× ×–×ž×™×Ÿ עבור %2$s."
+
+#. %1 is the add-on name
+#: views/addons/policy.thtml:101 views/addons/previews.thtml:60
+#: views/addons/versions.thtml:130 views/reviews/flag.thtml:61
+#: views/reviews/add.thtml:114 views/reviews/display.thtml:216
+#: views/reviews/review_added.thtml:57
+#, php-format
+msgid "addon_review_a_back_to_addon_x"
+msgstr "חזרה ×ל %1$s..."
+
+#. %1 is the add-on name
+#: views/reviews/flag.thtml:60 views/reviews/add.thtml:113
+#: views/reviews/review_added.thtml:56
+#, php-format
+msgid "addon_review_a_back_to_reviews"
+msgstr "חזרה לסקירות..."
+
+#: views/reviews/add.thtml:85
+msgid "addon_review_add_rating_field"
+msgstr "דירוג:"
+
+#: views/reviews/add.thtml:102
+msgid "addon_review_add_review_field"
+msgstr "סקירה:"
+
+#: views/reviews/add.thtml:107
+msgid "addon_review_add_submit"
+msgstr "שלח ×ת הסקירה שלך"
+
+#. %s is the name of the add-on
+#: views/reviews/add.thtml:51
+#, php-format
+msgid "addon_review_add_title"
+msgstr "הוסף סקירה עבור %s"
+
+#: views/reviews/add.thtml:78
+msgid "addon_review_add_title_field"
+msgstr "כותרת/תקציר:"
+
+#: views/reviews/display.thtml:77 views/reviews/display.thtml:161
+msgid "addon_review_admin_delete"
+msgstr "מחק"
+
+#: views/reviews/display.thtml:76
+msgid "addon_review_author_reply_link"
+msgstr "תשובה"
+
+#: views/reviews/delete.thtml:62
+msgid "addon_review_confirm_delete"
+msgstr "×תה בטוח שברצונך למחוק ×ת הסקירה הזו?"
+
+#: views/reviews/delete.thtml:63
+msgid "addon_review_confirm_no"
+msgstr "ל×"
+
+#: views/reviews/delete.thtml:64
+msgid "addon_review_confirm_yes"
+msgstr "כן"
+
+#: views/reviews/delete.thtml:48
+msgid "addon_review_delete_header"
+msgstr "מחק סקירה"
+
+#: controllers/reviews_controller.php:449
+msgid "addon_review_deleted_successfully"
+msgstr "סקירה נמחקה בהצלחה."
+
+#. %s is the name of the add-on
+#: views/reviews/add.thtml:51
+#, php-format
+msgid "addon_review_edit_title"
+msgstr "עריכת סקירה עבור %s"
+
+#. %1 is the count of characters entered as notes for the review flag reason.
+#: controllers/reviews_controller.php:539
+#, fuzzy
+msgid "addon_review_flag_error_other_length"
+msgstr ""
+"Problem flagging review: Notes for flagged reviews are limited to between 10 "
+"and 100 characters; your character length was %1$s."
+
+#. Removing an extra comma
+#: views/reviews/review_added.thtml:53
+msgid "addon_review_in_moderation"
+msgstr "×©×™× ×œ×‘: לפני שהסקירה שלך תוצג ב×תר, ×”×™× ×ª×¢×‘×•×¨ ביקורת על־ידי עורך."
+
+#: views/reviews/add.thtml:57
+msgid "addon_review_in_reply_to"
+msgstr "תשובת מפתח ל:"
+
+#. %1 is the review count, %2 is the nickname or full name of the user.
+#: views/reviews/display.thtml:131
+#, fuzzy, php-format
+msgid "addon_review_others_by_user"
+msgid_plural "addon_review_others_by_user"
+msgstr[0] "See %1$s previous review submitted by %2$s for this add-on."
+msgstr[1] "See %1$s previous reviews submitted by %2$s for this add-on."
+
+#. %1 is the add-on name
+#: controllers/reviews_controller.php:201
+#: controllers/reviews_controller.php:250
+#: controllers/reviews_controller.php:345
+#: controllers/reviews_controller.php:424
+#, php-format
+msgid "addon_review_pagetitle"
+msgstr "סקירות עבור %s"
+
+#. %1 is the user, %2 is the (localized) date
+#: views/reviews/display.thtml:160
+#, php-format
+msgid "addon_review_reply_on_x_by_y"
+msgstr "תשובה מ×ת %1$s ב-%2$s"
+
+#: views/reviews/display.thtml:157
+msgid "addon_review_reply_prefix"
+msgstr "תשובת מפתח:"
+
+#: views/reviews/review_added.thtml:51
+msgid "addon_review_saved_successfully"
+msgstr "הסקירה שלך נשמרה בהצלחה. תודה!"
+
+#: views/addons/display.thtml:354 views/reviews/display.thtml:72
+msgid "addon_reviewed_by_u_on_d"
+msgstr "מ×ת %1$sב-%2$s"
+
+#. %1 is the user, %2 is the (localized) date, %3 is the rating
+#: views/editors/reviews_queue.thtml:57 views/editors/reviews_queue.thtml:68
+#: views/reviews/add.thtml:63 views/reviews/delete.thtml:54
+#, php-format
+msgid "addon_reviewed_on_x_rated_y"
+msgstr "סקירות על %1$s, מדורגות %2$d"
+
+#: views/elements/amo2009/addon_version_detail.thtml:52
+#: views/elements/addon_version_detail.thtml:52
+msgid "addon_version_permalink"
+msgstr "קישור קבוע לגירסה זו"
+
+#. %1 is the current Application name (e.g. Firefox)
+#. %2 is the Application's version number
+#: views/addons/versions.thtml:140
+#, fuzzy
+msgid "addon_versions_getlatestversion"
+msgstr "The most recent version compatible with %1$s %2$s"
+
+#: views/addons/display.thtml:447
+msgid "addons_author_addons_submit"
+msgstr "לך"
+
+#: views/elements/amo2009/homepage_addon.thtml:100
+#: views/elements/feature.thtml:95
+msgid "addons_author_tooltip"
+msgstr "צפה בפרופיל המחבר"
+
+#. %1 is the name of the Application (eg. Firefox)
+#: controllers/addons_controller.php:1296
+#, fuzzy
+msgid "addons_browse_all_themes_title"
+msgstr "Browse all Themes :: %1$s Add-ons"
+
+#. %s is the name of the category
+#: controllers/addons_controller.php:1016
+#, php-format
+msgid "addons_browse_browse_category"
+msgstr "עיין ב%s"
+
+#. %1 is the name of the theme category (eg. Modern)
+#. %2 is the name of the Application (eg. Firefox)
+#: controllers/addons_controller.php:664
+#, fuzzy
+msgid "addons_browse_categories_header_theme"
+msgstr "Browse %1$s Themes :: %2$s Add-ons"
+
+#: views/addons/display.thtml:249
+#, fuzzy
+msgid "addons_display_a_license_what"
+msgstr "What's this?"
+
+#: views/reviews/display.thtml:222
+msgid "addons_display_add_review"
+msgstr "הוסף סקירה"
+
+#: views/addons/display.thtml:294
+msgid "addons_display_advanced_details"
+msgstr "×¤×¨×˜×™× ×ž×ª×§×“×ž×™×"
+
+#: views/addons/display.thtml:98
+msgid "addons_display_categories"
+msgstr "קטגוריות"
+
+#: views/addons/display.thtml:482
+#, fuzzy
+msgid "addons_display_collection_add"
+msgstr "Add to a collection:"
+
+#: views/addons/display.thtml:491
+#, fuzzy
+msgid "addons_display_collection_add_new"
+msgstr "New Collection..."
+
+#: views/addons/display.thtml:487
+#, fuzzy
+msgid "addons_display_collection_add_select_one"
+msgstr "Select a collection..."
+
+#: views/addons/display.thtml:493
+#, fuzzy
+msgid "addons_display_collection_add_submit"
+msgstr "Publish"
+
+#. %1$s is the add-on name
+#. %2$s is the collection name, linked to the collection's page
+#: views/pages/js_constants.js.thtml:103 views/addons/display.thtml:61
+#, fuzzy
+msgid "addons_display_collection_publish_success"
+msgstr "%1$s has been added to the %2$s collection."
+
+#: views/addons/display.thtml:483
+#, fuzzy
+msgid "addons_display_collection_whatsthis"
+msgstr "What's this?"
+
+#. %1$s is a number
+#: views/addons/display.thtml:473
+#, fuzzy
+msgid "addons_display_collections_more"
+msgid_plural "addons_display_collections_more"
+msgstr[0] "and %1$s more collection"
+msgstr[1] "and %1$s more collections"
+
+#: views/addons/display.thtml:403
+msgid "addons_display_detailed_review"
+msgstr "סקירה מפורטת"
+
+#: views/reviews/add.thtml:89 views/reviews/add.thtml:90
+msgid "addons_display_dont_like_it"
+msgstr "×œ× ×והב"
+
+#: views/reviews/display.thtml:220
+msgid "addons_display_edit_review"
+msgstr "ערוך סקירה"
+
+#: views/addons/display.thtml:132
+msgid "addons_display_has_privacy"
+msgstr "לתוספת זו יש מדיניות פרטיות."
+
+#: views/reviews/add.thtml:87 views/reviews/add.thtml:88
+msgid "addons_display_hate_it"
+msgstr "שונ×"
+
+#: views/addons/display.thtml:462
+#, fuzzy
+msgid "addons_display_header_collections"
+msgstr "Related Collections"
+
+#: views/addons/display.thtml:297
+msgid "addons_display_header_developer_comments"
+msgstr "הערות המפתח"
+
+#: views/addons/display.thtml:230
+msgid "addons_display_header_homepage"
+msgstr "דף הבית"
+
+#: views/addons/display.thtml:247 views/addons/versions.thtml:110
+#, fuzzy
+msgid "addons_display_header_license"
+msgstr "Source Code License"
+
+#: views/addons/display.thtml:337
+msgid "addons_display_header_reviews"
+msgstr "סקירות"
+
+#: views/addons/display.thtml:261
+msgid "addons_display_header_support"
+msgstr "תמיכה"
+
+#: views/reviews/add.thtml:91 views/reviews/add.thtml:92
+msgid "addons_display_like_it"
+msgstr "×והב"
+
+#: views/addons/display.thtml:210
+msgid "addons_display_long_description"
+msgstr "תי×ור ×רוך"
+
+#: views/reviews/add.thtml:95 views/reviews/add.thtml:96
+msgid "addons_display_love_it"
+msgstr "מת עליו"
+
+#: views/addons/display.thtml:178
+msgid "addons_display_more_images"
+msgstr "עוד תמונות"
+
+#: views/addons/display.thtml:465
+#, fuzzy
+msgid "addons_display_nocollections"
+msgstr "This add-on is not yet in any collections."
+
+#. %1$s is either an author's name or a comma separated list of authors. Using
+#. the list doesn't make sense in the English plural form so we ignore the
+#. variable.
+#: views/addons/display.thtml:436
+#, fuzzy
+msgid "addons_display_other_addons_by"
+msgid_plural "addons_display_other_addons_by"
+msgstr[0] "תוספות ×חרות של %1$s"
+msgstr[1] "Other add-ons by these authors"
+
+#. %s is the name of the add-on and the add-on section. Example:
+#. Some Add-on :: Firefox Add-ons
+#. This should not be concatenated in the code and should be fixed.
+#: controllers/addons_controller.php:141 controllers/addons_controller.php:280
+#: controllers/addons_controller.php:1442
+#, php-format
+msgid "addons_display_pagetitle"
+msgstr "%s"
+
+#. %s is an email address
+#: views/addons/display.thtml:286
+#, php-format
+msgid "addons_display_paragraph_supportinfoemail"
+msgstr ""
+"תמיכה עבור ההרחבה הזו זמינה ב%s. ×× ×ž×¦×ת ב××’ מומלץ לדווח עליו למפתח ההרחבה "
+"כך ×©×”×•× ×™×•×›×œ להיות בקשר ×יתך. סקירות הן ×œ× ×”×ž×§×•× ×”×ž×ª××™× ×œ×“×™×•×•×— ב××’×™× ×ž×¤×•×¨×˜, "
+"והמפתח ×ולי יזדקק לכמה ×¤×¨×˜×™× ×›×“×™ לשחזר ×ת הב××’. מ×חר ו×נו ×œ× ×ž××¤×©×¨×™× ×œ×ž×¤×ª×—×™ "
+"ההרחבות לצפות בכתובת הדו×\"ל שלך כש×תה ×ž×¤×¨×¡× ×¡×§×™×¨×”, ×”× ×œ× ×™×•×›×œ×• ליצור ×יתך "
+"קשר כדי לבקש עוד ×¤×¨×˜×™× ×ו להודיע לך על תיקון הב××’ בגירס×ות הב×ות."
+
+#. %$1s is a URL
+#. %$2s is an email address
+#: views/addons/display.thtml:269
+#, php-format
+msgid "addons_display_paragraph_supportinfoemailurl"
+msgstr ""
+"תמיכה עבור ההרחבה הזו זמינה ב%s ×ו ב%s. ×× ×ž×¦×ת ב××’ מומלץ לדווח עליו למפתח "
+"ההרחבה כך ×©×”×•× ×™×•×›×œ להיות בקשר ×יתך. סקירות הן ×œ× ×”×ž×§×•× ×”×ž×ª××™× ×œ×“×™×•×•×— ב××’×™× "
+"מפורט, והמפתח ×ולי יזדקק לכמה ×¤×¨×˜×™× ×›×“×™ לשחזר ×ת הב××’. מ×חר ו×נו ×œ× ×ž××¤×©×¨×™× "
+"למפתחי ההרחבות לצפות בכתובת הדו×\"ל שלך כש×תה ×ž×¤×¨×¡× ×¡×§×™×¨×”, ×”× ×œ× ×™×•×›×œ×• ליצור "
+"×יתך קשר כדי לבקש עוד ×¤×¨×˜×™× ×ו להודיע לך על תיקון הב××’ בגירס×ות הב×ות."
+
+#. %s is a URL
+#: views/addons/display.thtml:278
+#, php-format
+msgid "addons_display_paragraph_supportinfourl"
+msgstr ""
+"תמיכה עבור ההרחבה הזו זמינה ב%s. ×× ×ž×¦×ת ב××’ מומלץ לדווח עליו למפתח ההרחבה "
+"כך ×©×”×•× ×™×•×›×œ להיות בקשר ×יתך. סקירות הן ×œ× ×”×ž×§×•× ×”×ž×ª××™× ×œ×“×™×•×•×— ב××’×™× ×ž×¤×•×¨×˜, "
+"והמפתח ×ולי יזדקק לכמה ×¤×¨×˜×™× ×›×“×™ לשחזר ×ת הב××’. מ×חר ו×נו ×œ× ×ž××¤×©×¨×™× ×œ×ž×¤×ª×—×™ "
+"ההרחבות לצפות בכתובת הדו×\"ל שלך כש×תה ×ž×¤×¨×¡× ×¡×§×™×¨×”, ×”× ×œ× ×™×•×›×œ×• ליצור ×יתך "
+"קשר כדי לבקש עוד ×¤×¨×˜×™× ×ו להודיע לך על תיקון הב××’ בגירס×ות הב×ות."
+
+#: views/addons/display.thtml:383
+msgid "addons_display_rate_it"
+msgstr "דרג"
+
+#: views/reviews/add.thtml:93 views/reviews/add.thtml:94
+msgid "addons_display_really_like_it"
+msgstr "×והב מ×וד"
+
+#: views/addons/display.thtml:410
+msgid "addons_display_review_etiquette"
+msgstr ""
+"בבקשה ×ל ×ª×¤×¨×¡× ×“×™×•×•×—×™ ב××’×™× ×‘×¡×§×™×¨×•×ª. ×נחנו ×œ× ×ž×¢×‘×™×¨×™× ×ת כתובת הדו×\"ל שלך "
+"למפתחי התוספות ×•×”× ×ולי יצטרכו ליצור ×יתך קשר על מנת לפתור ×ת הבעיה."
+
+#. %1 is the review guidelines link
+#: views/addons/display.thtml:417
+msgid "addons_display_review_guidelines_link"
+msgstr "<a href=\"%s\">×§×•×™× ×ž× ×—×™× ×œ×¡×§×™×¨×”</a>"
+
+#. %1 is the support section link
+#: views/addons/display.thtml:414
+msgid "addons_display_review_see_support"
+msgstr ""
+"בקר ב<a href=\"%1$s\">×יזור התמיכה</a> כדי לגלות ×יפה ניתן לקבל סיוע לתוספת "
+"זו."
+
+#: views/addons/display.thtml:404
+msgid "addons_display_review_submit"
+msgstr "שמור"
+
+#: views/addons/display.thtml:430
+#, php-format
+msgid "addons_display_see_all_addons"
+msgstr "צפה בכל התוספות ה%1$s "
+
+#. %1 is the number of reviews
+#: views/addons/display.thtml:364
+#, php-format
+msgid "addons_display_see_all_reviews"
+msgstr "הצג כל הסקירות (%1$s)"
+
+#: views/addons/display.thtml:219
+msgid "addons_display_see_all_versions"
+msgstr "צפה בכל הגירס×ות"
+
+#: views/addons/display.thtml:321 views/addons/versions.thtml:117
+msgid "addons_display_view_source"
+msgstr "הצג קוד מקור"
+
+#: views/addons/display.thtml:324
+msgid "addons_display_view_stats"
+msgstr "צפה בסטיסטיקות"
+
+#: views/addons/display.thtml:376
+msgid "addons_display_what_do_you_think"
+msgstr "מה ×תה חושב?"
+
+#: views/elements/app_compatibility.thtml:49
+msgid "addons_display_workswith"
+msgstr "עובד ×¢×:"
+
+#: views/addons/home.thtml:112
+#, fuzzy
+msgid "addons_home_browse_new"
+msgstr "Just Added"
+
+#: views/addons/home.thtml:110
+#, fuzzy
+msgid "addons_home_browse_popular"
+msgstr "Popular"
+
+#: views/addons/home.thtml:108
+#, fuzzy
+msgid "addons_home_browse_recommended"
+msgstr "Recommended"
+
+#: views/addons/home.thtml:127 views/addons/home.thtml:134
+#: views/addons/home.thtml:141 views/addons/home.thtml:148
+#, fuzzy
+msgid "addons_home_browse_subscribe"
+msgstr "Subscribe"
+
+#: views/addons/home.thtml:101
+#, fuzzy
+msgid "addons_home_browse_title"
+msgstr "Browse Add-ons"
+
+#: views/addons/home.thtml:114
+#, fuzzy
+msgid "addons_home_browse_updated"
+msgstr "Updated"
+
+#: views/elements/amo2009/homepage_addon.thtml:100
+#: views/elements/addon_discussionheader.thtml:83
+#: views/elements/addon_listitem.thtml:109 views/elements/feature.thtml:95
+#: views/addons/category_landing.thtml:66 views/addons/policy.thtml:57
+#: views/addons/display.thtml:70 views/addons/home.thtml:178
+msgid "addons_home_by"
+msgstr "מ×ת"
+
+#: views/addons/home.thtml:169
+#, fuzzy
+msgid "addons_home_collection_popular_title"
+msgstr "Popular Collections"
+
+#: views/elements/amo2009/categories.thtml:69 views/addons/home.thtml:160
+#, fuzzy
+msgid "addons_home_collections"
+msgstr "Collections"
+
+#. %1$s is the count of addons in a collection
+#: views/elements/amo2009/collection_listing_item.thtml:51
+#: views/addons/home.thtml:185
+#, fuzzy
+msgid "addons_home_collections_addon_count"
+msgid_plural "addons_home_collections_addon_count"
+msgstr[0] "<strong>%1$s</strong> add-on"
+msgstr[1] "<strong>%1$s</strong> add-ons"
+
+#: views/addons/home.thtml:196
+#, fuzzy
+msgid "addons_home_collections_all"
+msgstr "View All Collections"
+
+#: views/addons/home.thtml:162
+#, fuzzy
+msgid "addons_home_collections_intro"
+msgstr ""
+"Collections are a way for you to categorize, mix, match and mingle add-ons. "
+"Subscribe to collections created by other users or create your own."
+
+#. %1$s is the count of subscribers for a collection
+#: views/elements/amo2009/collection_listing_item.thtml:58
+#: views/collections/detail.thtml:96 views/addons/home.thtml:189
+#, fuzzy
+msgid "addons_home_collections_subscribers"
+msgid_plural "addons_home_collections_subscribers"
+msgstr[0] "<strong>%1$s</strong> subscriber"
+msgstr[1] "<strong>%1$s</strong> subscribers"
+
+#: views/addons/searchengines.thtml:54 views/addons/themes_landing.thtml:49
+msgid "addons_home_feature_head"
+msgstr "ההמלצות שלנו"
+
+#: controllers/search_controller.php:218 controllers/addons_controller.php:176
+#: controllers/addons_controller.php:428 controllers/addons_controller.php:671
+#: controllers/addons_controller.php:871
+#: controllers/addons_controller.php:1103
+#: controllers/addons_controller.php:1242
+#: controllers/addons_controller.php:1298
+#, php-format
+msgid "addons_home_header_details"
+msgstr ""
+"תוספות מרחיבות ×ת %1$s, ומ×פשרות לך להת××™× ×ישית ×ת חווית הגלישה שלך. עשה "
+"סיור בסביבה והפוך ×ת %1$s לשלך."
+
+#. %1$s is the HTML collection name link.
+#: views/elements/amo2009/teaser_collections.thtml:107
+#, fuzzy
+msgid "addons_home_introduction_collection_link"
+msgstr "Like these? Find more add-ons in %1$s."
+
+#: views/elements/amo2009/teaser_collections.thtml:60
+#, fuzzy
+msgid "addons_home_introduction_extras"
+msgstr ""
+"<strong>Over 5000 free extras</strong> that let you customize and extend "
+"Firefox to meet your needs."
+
+#: views/elements/amo2009/teaser_collections.thtml:55
+#, fuzzy
+msgid "addons_home_introduction_header"
+msgstr "What are Add-ons?"
+
+#: views/elements/amo2009/teaser_collections.thtml:72
+#, fuzzy
+msgid "addons_home_introduction_install"
+msgstr ""
+"<strong>Easy to install</strong>, get notified when updates are available."
+
+#: views/elements/amo2009/teaser_collections.thtml:45
+#, fuzzy
+msgid "addons_home_introduction_name"
+msgstr "Introduction"
+
+#: views/elements/amo2009/teaser_collections.thtml:66
+#, fuzzy
+msgid "addons_home_introduction_themes"
+msgstr ""
+"Toolbars, themes and search providers that <strong>help you perform common "
+"tasks.</strong>"
+
+#: views/addons/home.thtml:161
+#, fuzzy
+msgid "addons_home_new_indicator"
+msgstr "NEW!"
+
+#: views/elements/app_chooser.thtml:48 views/layouts/amo2009.thtml:257
+msgid "addons_home_other_applications"
+msgstr "×™×™×©×•×ž×™× ×חרי×"
+
+#. %1$s is the application the user is browsing. Examples: Thunderbird, Firefox,
+#. Sunbird
+#: views/pages/collector_faq.thtml:49 views/pages/collector_firstrun.thtml:42
+#: views/pages/collector.thtml:46 views/pages/collector_features.thtml:54
+#: controllers/developers_controller.php:87
+#: controllers/compatibility_controller.php:72
+#: controllers/components/simple_acl.php:81 controllers/components/amo.php:607
+#: controllers/statistics_controller.php:60
+#: controllers/statistics_controller.php:240
+#: controllers/previews_controller.php:67 controllers/users_controller.php:90
+#: controllers/users_controller.php:223 controllers/users_controller.php:330
+#: controllers/users_controller.php:414 controllers/users_controller.php:708
+#: controllers/users_controller.php:723 controllers/reviews_controller.php:204
+#: controllers/reviews_controller.php:251
+#: controllers/reviews_controller.php:346
+#: controllers/reviews_controller.php:425
+#: controllers/search_controller.php:185 controllers/search_controller.php:297
+#: controllers/search_controller.php:301 controllers/addons_controller.php:147
+#: controllers/addons_controller.php:280 controllers/addons_controller.php:370
+#: controllers/addons_controller.php:667 controllers/addons_controller.php:874
+#: controllers/addons_controller.php:1019
+#: controllers/addons_controller.php:1034
+#: controllers/addons_controller.php:1101
+#: controllers/addons_controller.php:1121
+#: controllers/addons_controller.php:1240
+#: controllers/addons_controller.php:1357
+#: controllers/addons_controller.php:1364
+#: controllers/addons_controller.php:1442
+#: controllers/addons_controller.php:1477
+#: controllers/addons_controller.php:1538
+#: controllers/addons_controller.php:1543
+#: controllers/editors_controller.php:64 controllers/pages_controller.php:132
+#: controllers/groups_controller.php:65 controllers/groups_controller.php:71
+#: controllers/groups_controller.php:89 controllers/groups_controller.php:111
+#: controllers/collections_controller.php:57
+#: controllers/collections_controller.php:121
+#: controllers/collections_controller.php:205
+#: controllers/collections_controller.php:365
+#: controllers/collections_controller.php:404
+#: controllers/collections_controller.php:466
+#: controllers/collections_controller.php:538
+#: controllers/collections_controller.php:828
+#: controllers/localizers_controller.php:72
+#, php-format
+msgid "addons_home_pagetitle"
+msgstr "×תר התוספות של Mozilla :: הוסף תכונות למוצרי Mozilla"
+
+#. %1$s is the number of addons downloaded
+#: views/addons/home.thtml:57
+#, fuzzy, php-format
+msgid "addons_home_stats_downloaded"
+msgid_plural "addons_home_stats_downloaded"
+msgstr[0] "<strong>%1$s</strong> <span>add-on downloaded</span>"
+msgstr[1] "<strong>%1$s</strong> <span>add-ons downloaded</span>"
+
+#. %1$s is the number of addons in use
+#: views/addons/home.thtml:63
+#, fuzzy, php-format
+msgid "addons_home_stats_inuse"
+msgid_plural "addons_home_stats_inuse"
+msgstr[0] "<strong>%1$s</strong> <span>add-on in use</span>"
+msgstr[1] "<strong>%1$s</strong> <span>add-ons in use</span>"
+
+#: views/addons/home.thtml:136
+msgid "addons_home_view_all_newest_title"
+msgstr "צפה בכל "
+
+#: views/addons/home.thtml:129
+msgid "addons_home_view_all_popular_title"
+msgstr "צפה בכל התוספות הפופולריות"
+
+#: views/addons/home.thtml:150
+msgid "addons_home_view_all_recommended_title"
+msgstr "צפה בכל התוספות המומלצות"
+
+#: views/addons/home.thtml:143
+msgid "addons_home_view_all_updated_title"
+msgstr "צפה בכל התוספות שעודכנו ל×חרונה"
+
+#: views/elements/amo2009/install.thtml:334 views/elements/install.thtml:112
+#, fuzzy
+msgid "addons_install_in_sunbird"
+msgstr ""
+"<ol><li>Click the link below to save the file.</li><li>In Mozilla Sunbird, "
+"open Add-ons from the Tools menu.</li><li>Click the Install button, and "
+"locate/select the file you downloaded and click \"OK\".</li></ol>"
+
+#: views/elements/amo2009/install.thtml:333 views/elements/install.thtml:111
+#, fuzzy
+msgid "addons_install_in_sunbird_title"
+msgstr "How to Install in Sunbird"
+
+#: views/elements/amo2009/install.thtml:331 views/elements/install.thtml:106
+msgid "addons_install_in_thunderbird"
+msgstr ""
+"<ol><li>לחץ על הלחצן הימני של העכבר על הקישור ×”×‘× ×•×‘×—×¨ ב\"שמור קישור בתור..."
+"\" כדי להוריד ולשמור ×ת הקובץ לכונן הקשיח שלך.</li><li>בתוך Mozilla "
+"Thunderbird, פתח ×ת מנהל התוספות מתוך התפריט כלי×.</li><li>לחץ על כפתור "
+"ההתקנה, בחר ×ת הקובץ שהורדת ולחץ על \"×ישור\".</li></ol>"
+
+#: views/elements/amo2009/install.thtml:330 views/elements/install.thtml:105
+msgid "addons_install_in_thunderbird_title"
+msgstr "כיצד להתקין ב־Thunderbird"
+
+#: views/elements/amo2009/addon_list_options.thtml:108
+#: views/elements/addon_list_options.thtml:105
+msgid "addons_options_show_experimental"
+msgstr "הצג תוספות נסיוניות"
+
+#: views/elements/amo2009/addon_list_options.thtml:113
+#: views/elements/addon_list_options.thtml:109
+msgid "addons_options_submit"
+msgstr "לך"
+
+#: views/addons/plugins.thtml:63 views/addons/plugins.thtml:73
+#: views/addons/plugins.thtml:83 views/addons/plugins.thtml:93
+#: views/addons/plugins.thtml:103 views/addons/plugins.thtml:116
+#: views/addons/plugins.thtml:126
+msgid "addons_plugins_by"
+msgstr "מ×ת"
+
+#: views/addons/plugins.thtml:107
+msgid "addons_plugins_for_linux"
+msgstr "עבור Linux"
+
+#: views/addons/plugins.thtml:108 views/addons/plugins.thtml:131
+msgid "addons_plugins_for_macosx"
+msgstr "עבור Mac OS X"
+
+#: views/addons/plugins.thtml:106 views/addons/plugins.thtml:129
+#: views/addons/plugins.thtml:130
+msgid "addons_plugins_for_windows"
+msgstr "עבור Windows"
+
+#. %1$s is a URL
+#: views/addons/plugins.thtml:139
+#, php-format
+msgid "addons_plugins_looking_for_more"
+msgstr ""
+"דף ×–×” מציג רשימה של ×”×ª×•×¡×¤×™× ×”×©×›×™×—×™× ×•×”×¤×•×¤×•×œ×¨×™×™× ×‘×™×•×ª×¨. למידע נוסף ×ודות "
+"×ª×•×¡×¤×™× ××—×¨×™× ×”×–×ž×™× ×™× ×¢×‘×•×¨ ×“×¤×“×¤× ×™× ×ž×‘×•×¡×¡×™ Mozilla, ר××” %1$s"
+
+#: views/addons/plugins.thtml:137
+msgid "addons_plugins_looking_for_plugin"
+msgstr "מחפש תוסף ×©×œ× ×ž×•×¤×™×¢ ×›×ן?"
+
+#: views/addons/plugins.thtml:58
+msgid "addons_plugins_main_description"
+msgstr ""
+"×ª×•×¡×¤×™× ×ž×¡×™×™×¢×™× ×œ×“×¤×“×¤×Ÿ לבצע פעולות מסוימות כגון צפיה ×‘×§×‘×¦×™× ×’×¨×¤×™×™× ×ž×™×•×—×“×™× ×ו "
+"השמעת קבצי מולטימדיה. ×ª×•×¡×¤×™× ×©×•× ×™× ×‘×ž×§×¦×ª מהרחבות, שמשנות ×ו מתווספות לפעולות "
+"הקיימות."
+
+#. %1$s is the application name. Example: Firefox, Thunderbird, Sunbird
+#: controllers/addons_controller.php:1122
+#, php-format
+msgid "addons_plugins_main_header"
+msgstr "×ª×•×¡×¤×™× ×©×›×™×—×™× ×¢×‘×•×¨ %1$s"
+
+#: controllers/components/amo.php:698 controllers/addons_controller.php:1121
+msgid "addons_plugins_pagetitle"
+msgstr "תוספי×"
+
+#: views/addons/plugins.thtml:68 views/addons/plugins.thtml:78
+#: views/addons/plugins.thtml:88 views/addons/plugins.thtml:98
+#: views/addons/plugins.thtml:110 views/addons/plugins.thtml:121
+#: views/addons/plugins.thtml:133
+msgid "addons_plugins_support_documentation"
+msgstr "תיעוד לתמיכה: "
+
+#. %s is the name of the add-on
+#: views/addons/policy.thtml:61
+#, php-format
+msgid "addons_policy_eula_require"
+msgstr "%s דורש ×©×ª×¡×›×™× ×œ×”×¡×›× ×”×ž×©×ª×ž×© ×”×‘× ×›×“×™ להמשיך בהתקנה:"
+
+#. %1 is the add-on name
+#: controllers/addons_controller.php:1476
+#, php-format
+msgid "addons_previews_pagetitle"
+msgstr "סקירות עבור %s"
+
+#: views/addons/category_landing.thtml:135
+#, fuzzy
+msgid "addons_recently_added"
+msgstr "Recently Added"
+
+#: views/addons/recommended.thtml:51 controllers/addons_controller.php:1365
+msgid "addons_recommended_introduction"
+msgstr ""
+"×¢× ×לף תוספות זמינות, יש משהו לכל ×חד. בתור התחלה, ×”× ×” רשימה של כמה "
+"×ž×”×ž×¢×•×“×¤×™× ×©×œ× ×•. תהנה!"
+
+#: controllers/addons_controller.php:1357
+#: controllers/addons_controller.php:1364
+msgid "addons_recommended_pagetitle"
+msgstr "תוספות מומלצות"
+
+#: controllers/addons_controller.php:1360
+msgid "addons_recommended_title"
+msgstr "תוספות מומלצות"
+
+#: views/addons/searchengines.thtml:136
+msgid "addons_searchengines_additional_resources"
+msgstr "מש××‘×™× × ×•×¡×¤×™×"
+
+#. link text devmo
+#: views/addons/searchengines.thtml:141
+msgid "addons_searchengines_devmo_link"
+msgstr "מרכז ×”×ž×¤×ª×—×™× ×©×œ מוזילה"
+
+#: views/pages/js_constants.js.thtml:67
+msgid "addons_searchengines_error_mozilla_browser_required"
+msgstr ""
+"מצטערי×, ×תה צריך דפדפן מבוסס Mozilla (כגון Firefox) בכדי להתקין תוספי חיפוש."
+
+#: views/addons/searchengines.thtml:49
+msgid "addons_searchengines_error_nojavascript"
+msgstr ""
+"כדי להתקין ×ª×•×¡×¤×™× ×—×™×™×‘×™× JavaScript, ×ך נר××” ×›×™ ביטלת ×–×ת. בבקשה הפעל ×ת "
+"×”Ö¾JavaScript בדפדפן שלך לפני ש×תה מנסה להתקין ×ת תוספי החיפוש הב××™×."
+
+#. %1 is "make your own" link
+#. %2 is MDC link
+#: views/addons/searchengines.thtml:139
+msgid "addons_searchengines_learn_howto"
+msgstr "למד ×יך %1$s ב%2$s."
+
+#. link path to search plugins instructions, relative to devmo
+#: views/addons/searchengines.thtml:140
+msgid "addons_searchengines_makeyourown_href"
+msgstr "/en/docs/Creating_OpenSearch_plugins_for_Firefox"
+
+#. link text for "make your own" (opensearch engine)
+#: views/addons/searchengines.thtml:140
+msgid "addons_searchengines_makeyourown_link"
+msgstr "ליצור מנועי חיפוש משלך"
+
+#. %1 is the link to mycroft.mozdev.org
+#: views/addons/searchengines.thtml:138
+msgid "addons_searchengines_more"
+msgstr "עיין במנועי חיפוש × ×•×¡×¤×™× ×‘-%1$s"
+
+#. link text to mycroft.mozdev.org
+#: views/addons/searchengines.thtml:138
+msgid "addons_searchengines_mycroft_link"
+msgstr "mycroft.mozdev.org"
+
+#: controllers/addons_controller.php:1100
+#: controllers/addons_controller.php:1110
+msgid "addons_searchengines_pagetitle"
+msgstr "מנועי חיפוש"
+
+#: views/addons/searchengines.thtml:143
+msgid "addons_searchengines_thanks"
+msgstr "תודה מיוחדת לפרוייקט Mycroft על ×¢×‘×•×“×ª× ×¢×œ מנועי חיפוש לפיירפוקס."
+
+#: views/addons/display.thtml:154
+#, fuzzy
+msgid "addons_share_button_text"
+msgstr "Share this"
+
+#: controllers/addons_controller.php:89
+#, fuzzy
+msgid "addons_share_label_delicious"
+msgstr "Add to Delicious"
+
+#: controllers/addons_controller.php:77
+#, fuzzy
+msgid "addons_share_label_digg"
+msgstr "Digg this!"
+
+#: controllers/addons_controller.php:83
+#, fuzzy
+msgid "addons_share_label_facebook"
+msgstr "Post to Facebook"
+
+#: controllers/addons_controller.php:101
+#, fuzzy
+msgid "addons_share_label_friendfeed"
+msgstr "Share on FriendFeed"
+
+#: controllers/addons_controller.php:95
+#, fuzzy
+msgid "addons_share_label_myspace"
+msgstr "Post to MySpace"
+
+#: controllers/components/amo.php:201 controllers/components/amo.php:229
+#, fuzzy
+msgid "addons_status_disabled"
+msgstr "Disabled"
+
+#: controllers/components/amo.php:191 controllers/components/amo.php:224
+#, fuzzy
+msgid "addons_status_incomplete"
+msgstr "Incomplete Version"
+
+#: controllers/components/amo.php:197 controllers/components/amo.php:227
+#, fuzzy
+msgid "addons_status_nominated"
+msgstr "In Sandbox; Public Nomination"
+
+#: views/pages/js_constants.js.thtml:80 controllers/components/amo.php:195
+#: controllers/components/amo.php:226
+#, fuzzy
+msgid "addons_status_pending"
+msgstr "In Sandbox; Pending Review"
+
+#: views/pages/js_constants.js.thtml:78 controllers/components/amo.php:199
+#: controllers/components/amo.php:228
+#, fuzzy
+msgid "addons_status_public"
+msgstr "Public"
+
+#: views/pages/js_constants.js.thtml:79 controllers/components/amo.php:193
+#: controllers/components/amo.php:225
+#, fuzzy
+msgid "addons_status_sandbox"
+msgstr "In Sandbox"
+
+#: controllers/components/amo.php:203
+#, fuzzy
+msgid "addons_status_unknown"
+msgstr "Unknown"
+
+#: views/elements/amo2009/teaser_collections.thtml:91
+#: views/elements/amo2009/homepage_addon.thtml:99
+#: views/elements/feature.thtml:94
+msgid "addons_title_tooltip"
+msgstr "למד עוד ×ודות תוספת זו"
+
+#: views/addons/category_landing.thtml:151
+#, fuzzy
+msgid "addons_top_downloads"
+msgstr "Top Downloads"
+
+#: views/addons/category_landing.thtml:165
+#, fuzzy
+msgid "addons_top_rated"
+msgstr "Top Rated"
+
+#: views/addons/versions.thtml:62
+msgid "addons_versions_careful"
+msgstr "×”×™×” זהיר ×¢× ×’×™×¨×¡×ות ישנות"
+
+#: views/addons/versions.thtml:63
+msgid "addons_versions_careful_introduction"
+msgstr ""
+"גירס×ות ×לו מוצגות למטרות התייחסות ובדיקות. ×תה מתבקש להשתמש תמיד בגירסה "
+"×”×חרונה של התוספת."
+
+#: controllers/addons_controller.php:1549
+msgid "addons_versions_history"
+msgstr "היסטורית גירס×ות ×¢× ×¨×™×©×•× ×©×™× ×•×™×™×"
+
+#. %1$s is the add-on name
+#: controllers/addons_controller.php:1535
+#, php-format
+msgid "addons_versions_pagetitle"
+msgstr "היסטורית הגירס×ות של %1$s"
+
+#: controllers/groups_controller.php:71
+msgid "admin_group_add_pagetitle"
+msgstr "הוסף קבוצה"
+
+#: controllers/groups_controller.php:111
+msgid "admin_group_delete_pagetitle"
+msgstr "מחק קבוצה"
+
+#. %s is a number to identify the group
+#: controllers/groups_controller.php:117
+#, php-format
+msgid "admin_group_deleted"
+msgstr "הקבוצה ×¢× ×ž×–×”×” %s נמחקה"
+
+#: controllers/groups_controller.php:89
+msgid "admin_group_edit_pagetitle"
+msgstr "ערוך קבוצה"
+
+#: controllers/groups_controller.php:92 controllers/groups_controller.php:113
+msgid "admin_group_error_invalid_id"
+msgstr "מזהה שגוי לקבוצה"
+
+#: controllers/groups_controller.php:65
+msgid "admin_group_pagetitle"
+msgstr "ניהול קבוצה"
+
+#: controllers/groups_controller.php:77 controllers/groups_controller.php:99
+msgid "admin_group_saved"
+msgstr "הקבוצה נשמרה"
+
+#: views/elements/amo2009/search.thtml:257 views/elements/search.thtml:239
+msgid "advanced_search_form"
+msgstr "מתקד×"
+
+#: views/elements/amo2009/search.thtml:126 views/elements/search.thtml:125
+msgid "advanced_search_form_any_time"
+msgstr "כל זמן"
+
+#: views/elements/amo2009/search.thtml:97
+#: views/elements/amo2009/search.thtml:110 views/elements/search.thtml:96
+#: views/elements/search.thtml:109
+msgid "advanced_search_form_any_type"
+msgstr "הכל"
+
+#: views/elements/amo2009/search.thtml:275 views/elements/search.thtml:254
+msgid "advanced_search_form_any_version"
+msgstr "הכל"
+
+#: views/elements/amo2009/search.thtml:217 views/elements/search.thtml:212
+msgid "advanced_search_form_application"
+msgstr "יישו×"
+
+#: views/elements/amo2009/search.thtml:143 views/elements/search.thtml:142
+msgid "advanced_search_form_keyword_match"
+msgstr "הת×מת מילת מפתח"
+
+#: views/elements/amo2009/search.thtml:251 views/elements/search.thtml:225
+msgid "advanced_search_form_lastupdate"
+msgstr "עודכן ל×חרונה"
+
+#: views/elements/amo2009/search.thtml:145 views/elements/search.thtml:144
+msgid "advanced_search_form_name"
+msgstr "ש×"
+
+#: views/elements/amo2009/search.thtml:144 views/elements/search.thtml:143
+msgid "advanced_search_form_newest"
+msgstr "החדש ביותר"
+
+#: views/elements/amo2009/search.thtml:130 views/elements/search.thtml:129
+msgid "advanced_search_form_past_3_months"
+msgstr "3 ×—×•×“×©×™× ×חרוני×"
+
+#: views/elements/amo2009/search.thtml:131 views/elements/search.thtml:130
+msgid "advanced_search_form_past_6_months"
+msgstr "6 ×—×•×“×©×™× ×חרוני×"
+
+#: views/elements/amo2009/search.thtml:127 views/elements/search.thtml:126
+msgid "advanced_search_form_past_day"
+msgstr "×”×™×•× ×”×חרון"
+
+#: views/elements/amo2009/search.thtml:129 views/elements/search.thtml:128
+msgid "advanced_search_form_past_month"
+msgstr "החודש ×”×חרון"
+
+#: views/elements/amo2009/search.thtml:128 views/elements/search.thtml:127
+msgid "advanced_search_form_past_week"
+msgstr "השבוע ×”×חרון"
+
+#: views/elements/amo2009/search.thtml:132 views/elements/search.thtml:131
+msgid "advanced_search_form_past_year"
+msgstr "השנה ×”×חרונה"
+
+#: views/elements/amo2009/search.thtml:239 views/elements/search.thtml:230
+msgid "advanced_search_form_perpage"
+msgstr "לפי עמוד"
+
+#: views/elements/amo2009/search.thtml:243 views/elements/search.thtml:224
+msgid "advanced_search_form_platform"
+msgstr "פלטפורמה"
+
+#: views/elements/amo2009/search.thtml:147 views/elements/search.thtml:146
+msgid "advanced_search_form_popularity"
+msgstr "פופולריות"
+
+#: views/elements/amo2009/search.thtml:146 views/elements/search.thtml:145
+msgid "advanced_search_form_rating"
+msgstr "דירוג"
+
+#: views/elements/amo2009/search.thtml:247 views/elements/search.thtml:231
+msgid "advanced_search_form_sortby"
+msgstr "מיין לפי"
+
+#: views/elements/amo2009/search.thtml:227 views/elements/search.thtml:216
+msgid "advanced_search_form_to"
+msgstr "ל-"
+
+#: views/elements/amo2009/search.thtml:257 views/elements/search.thtml:237
+msgid "advanced_search_form_toggle_tooltip"
+msgstr "עבור למצב חיפוש מתקד×"
+
+#: views/elements/amo2009/search.thtml:235 views/elements/search.thtml:223
+msgid "advanced_search_form_type"
+msgstr "סוג"
+
+#: views/elements/amo2009/search.thtml:222 views/elements/search.thtml:214
+msgid "advanced_search_form_version"
+msgstr "גירסה"
+
+#: views/elements/amo2009/pagination.thtml:42
+#, fuzzy
+msgid "amo2009_pagination_next_page"
+msgstr "Next"
+
+#: views/elements/amo2009/pagination.thtml:41
+#, fuzzy
+msgid "amo2009_pagination_previous_page"
+msgstr "Prev"
+
+#: views/pages/js_constants.js.thtml:96
+msgid "app_compat_ignore_check"
+msgstr "×”×ª×¢×œ× ×ž×‘×“×™×§×ª גירסה"
+
+#: views/pages/js_constants.js.thtml:72
+msgid "app_compat_older_firefox_only"
+msgstr "התוספת ×”×–×ת מיועדת לגירס×ות ישנות יותר של פיירפוקס"
+
+#. %1$s and %2$s are URLs
+#: views/pages/js_constants.js.thtml:74
+#, fuzzy
+msgid "app_compat_older_version_or_ignore_check"
+msgstr ""
+"You can <a href=\"%1$s\">try an older version</a> or <a href=\"#\" onclick="
+"\"%2$s\">ignore this check</a>"
+
+#. %1$s is a URL
+#: views/pages/js_constants.js.thtml:71
+msgid "app_compat_try_old_version"
+msgstr "<a href=\"%1$s\">גירסה ישנה יותר</a> ×ולי תעבוד"
+
+#. %1$s is a URL
+#. %2$s is a version number. Example: 3.1
+#: views/pages/js_constants.js.thtml:73
+#, fuzzy
+msgid "app_compat_unreleased_version"
+msgstr ""
+"This add-on requires the not-yet released <a href=\"%1$s\">Firefox %2$s</a>"
+
+#: views/pages/js_constants.js.thtml:70
+msgid "app_compat_update_firefox"
+msgstr ""
+"<a href=\"http://firefox.co.il\">שדרג ×ת פיירפוקס</a> כדי להשתמש בתוספת הזו"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#. %3$s is a status, like Public.
+#: controllers/components/audit.php:79
+#, fuzzy
+msgid "audit_addon_status"
+msgstr "%1$s changed the status of %2$s to %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:221
+#, fuzzy
+msgid "audit_admin_default"
+msgstr "%1$s committed unknown admin action %2$s to ID %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:153
+#, fuzzy
+msgid "audit_admin_feature_remove"
+msgstr "%1$s removed feature %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is an application, like Firefox.
+#: controllers/components/audit.php:92
+#, fuzzy
+msgid "audit_application_create"
+msgstr "%1$s created application %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is an application, like Firefox.
+#: controllers/components/audit.php:95
+#, fuzzy
+msgid "audit_application_edit"
+msgstr "%1$s edited application %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a version number, like 3.5.
+#. %3$s is an application, like Firefox.
+#: controllers/components/audit.php:105
+#, fuzzy
+msgid "audit_appversion_create"
+msgstr "%1$s created version %2$s for %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a version number, like 3.5.
+#. %3$s is an application, like Firefox.
+#: controllers/components/audit.php:108
+#, fuzzy
+msgid "audit_appversion_delete"
+msgstr "%1$s deleted version %2$s for %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a config field, like "awesomeness".
+#. %3$s is a config value, like "off".
+#. %4$s is a config value, like "on".
+#: controllers/components/audit.php:210
+#, fuzzy
+msgid "audit_config"
+msgstr "%1$s changed config '%2$s' from '%3$s' to '%4$s'"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:258
+#, fuzzy
+msgid "audit_editor_default"
+msgstr "%1$s committed unknown editor action %2$s to ID %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#: controllers/components/audit.php:236
+#, fuzzy
+msgid "audit_editor_feature_remove"
+msgstr "%1$s removed addon %2$s from feature list"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#: controllers/components/audit.php:231
+#, fuzzy
+msgid "audit_feature_add"
+msgstr "%1$s added addon %2$s to feature list"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:149
+#, fuzzy
+msgid "audit_feature_edit"
+msgstr "%1$s changed a feature for %2$s locale"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#: controllers/components/audit.php:241
+#, fuzzy
+msgid "audit_feature_locale_change"
+msgstr "%1$s changed locales for addon %2$s on feature list"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:83
+#, fuzzy
+msgid "audit_file_recalchash"
+msgstr "%1$s recalculated the hash for file %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>user name</a>
+#. %3$s is <a>group name</a>
+#: controllers/components/audit.php:182
+#, fuzzy
+msgid "audit_group_addmember"
+msgstr "%1$s added %2$s to group %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:313
+#, fuzzy
+msgid "audit_group_associated"
+msgstr "%1$s associated themselves with %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:162
+#, fuzzy
+msgid "audit_group_create"
+msgstr "%1s created group %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:170
+#, fuzzy
+msgid "audit_group_delete"
+msgstr "%1$s deleted group %2$s (ID %3$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:165
+#, fuzzy
+msgid "audit_group_edit"
+msgstr "%1$s edited group %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>user name</a>
+#. %3$s is <a>group name</a>
+#: controllers/components/audit.php:188
+#, fuzzy
+msgid "audit_group_removemember"
+msgstr "%1$s removed %2$s from group %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:280
+#, fuzzy
+msgid "audit_l10n_default"
+msgstr "%1$s committed unknown action %2$s for %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:295
+#, fuzzy
+msgid "audit_modify_locked_group"
+msgstr "%1$s attempted to modify locked group %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:299
+#, fuzzy
+msgid "audit_modify_other_locale"
+msgstr "%1$s attempted to modify translations in %2$s without permission"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a platform, like <a>Windows</a>
+#: controllers/components/audit.php:135
+#, fuzzy
+msgid "audit_platform_create"
+msgstr "%1$s created platform %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a platform, like <a>Windows</a>
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:143
+#, fuzzy
+msgid "audit_platform_delete"
+msgstr "%1$s deleted platform %2$s (ID %3$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a platform, like <a>Windows</a>
+#: controllers/components/audit.php:138
+#, fuzzy
+msgid "audit_platform_edit"
+msgstr "%1$s edited platform %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a part of the admin, like 'Site Config'
+#: controllers/components/audit.php:288
+#, fuzzy
+msgid "audit_reauthentication_failure"
+msgstr "%1$s failed to re-authenticate to access %2$s."
+
+#. %1$s is <a>user name</a>
+#. %2$s is the name of a canned response, like 'Ready for the public'
+#: controllers/components/audit.php:198
+#, fuzzy
+msgid "audit_response_create"
+msgstr "%1$s created response %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is the name of a canned response, like 'Ready for the public'
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:206
+#, fuzzy
+msgid "audit_response_delete"
+msgstr "%1$s deleted response %2$s (ID %3$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is the name of a canned response, like 'Ready for the public'
+#: controllers/components/audit.php:201
+#, fuzzy
+msgid "audit_response_edit"
+msgstr "%1$s edited response %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:245
+#, fuzzy
+msgid "audit_review_approve"
+msgstr "%1$s approved review %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:250 controllers/components/audit.php:253
+#, fuzzy
+msgid "audit_review_delete"
+msgstr "%1$s deleted review %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:303
+#, fuzzy
+msgid "audit_security_default"
+msgstr "%1$s committed unknown security action %2$s to ID %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a category name, like <a>Search Tools</a>
+#: controllers/components/audit.php:118
+#, fuzzy
+msgid "audit_tag_create"
+msgstr "%1$s created tag %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a category name, like <a>Search Tools</a>
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:126
+#, fuzzy
+msgid "audit_tag_delete"
+msgstr "%1$s deleted category %2$s (ID %3$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a category name, like <a>Search Tools</a>
+#: controllers/components/audit.php:121
+#, fuzzy
+msgid "audit_tag_edit"
+msgstr "%1$s edited category %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:266
+#, fuzzy
+msgid "audit_update_applications"
+msgstr "%1$s updated application translations for %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:277
+#, fuzzy
+msgid "audit_update_blog"
+msgstr "%1$s updated blog post translations for %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:274
+#, fuzzy
+msgid "audit_update_platforms"
+msgstr "%1$s updated platform translations for %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:270
+#, fuzzy
+msgid "audit_update_tags"
+msgstr "%1$s updated category translations for %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>user name</a>
+#: controllers/components/audit.php:217
+#, fuzzy
+msgid "audit_user_edit"
+msgstr "%1$s edited %2$s's user information"
+
+#: controllers/addons_controller.php:1012
+msgid "browse_addons_name"
+msgstr "תוספות לפי ש×"
+
+#: controllers/addons_controller.php:1010
+msgid "browse_addons_newest"
+msgstr "התוספות החדשות ביותר"
+
+#: controllers/addons_controller.php:1008
+msgid "browse_addons_popular"
+msgstr "התוספות הפופולריות"
+
+#: controllers/addons_controller.php:1011
+msgid "browse_addons_rated"
+msgstr "תוספות לפי הדירוג"
+
+#: controllers/addons_controller.php:1009
+msgid "browse_addons_updated"
+msgstr "תוספות שעודכנו ל×חרונה"
+
+#: views/elements/categories.thtml:73 views/elements/categories.thtml:82
+msgid "categories_current_title"
+msgstr "קטגוריה נוכחית"
+
+#: views/elements/categories.thtml:50
+#: views/elements/amo2009/categories.thtml:43
+#: views/elements/amo2009/categories.thtml:45
+msgid "categories_header"
+msgstr "קטגוריות"
+
+#: views/elements/categories.thtml:50
+#: views/elements/amo2009/categories.thtml:41
+msgid "categories_header_title"
+msgstr "בחר קטגוריה"
+
+#. %1$s is the category name
+#: views/addons/searchengines.thtml:129
+#, php-format
+msgid "category_extra_see_all"
+msgstr "הר××” ×ת כל %1$s"
+
+#. %1$s is a number.
+#: models/collection.php:130
+#, fuzzy
+msgid "collection_description_limit"
+msgstr "The description should be less than %1$s characters."
+
+#. %1$s is the name of the collection
+#: controllers/collections_controller.php:392
+#, fuzzy
+msgid "collection_detail_rss_title"
+msgstr "%s Collection"
+
+#: controllers/collections_controller.php:1065
+#, fuzzy
+msgid "collection_error_deleting_addon"
+msgstr "Error deleting add-on!"
+
+#: controllers/collections_controller.php:1051
+#, fuzzy
+msgid "collection_error_saving_addon"
+msgstr "Error saving add-on!"
+
+#: controllers/collections_controller.php:1080
+#, fuzzy
+msgid "collection_error_saving_comment"
+msgstr "Error saving comment!"
+
+#. %1$s is a number.
+#: models/collection.php:122
+#, fuzzy
+msgid "collection_name_limit"
+msgstr "The name should be less than %1$s characters."
+
+#: controllers/collections_controller.php:352
+#: controllers/collections_controller.php:487
+#, fuzzy
+msgid "collection_not_found"
+msgstr "Collection not found!"
+
+#. %1$s is the text on the "create collection" button
+#: views/collections/add.thtml:91
+#, fuzzy
+msgid "collections_add_formfield_addons_description"
+msgstr ""
+"If you already know which add-ons you want to add to your collection, just "
+"start typing their names below. If you'd rather wait and do this later, just "
+"click %1$s now."
+
+#: views/collections/add.thtml:90
+#, fuzzy
+msgid "collections_add_formfield_firstaddons"
+msgstr "Choose your first add-ons"
+
+#: views/collections/add.thtml:48
+#, fuzzy
+msgid "collections_add_header"
+msgstr "Create a Collection"
+
+#: views/collections/add.thtml:97
+#, fuzzy
+msgid "collections_add_header_selectedaddons"
+msgstr "Selected Add-ons"
+
+#: views/collections/add.thtml:50
+#, fuzzy
+msgid "collections_add_intro"
+msgstr ""
+"It's easy to create your own collection of add-ons by filling in a few "
+"fields below."
+
+#: views/collections/add.thtml:92 views/collections/add.thtml:103
+#, fuzzy
+msgid "collections_add_submit"
+msgstr "Create Collection"
+
+#: views/pages/collector_faq.thtml:50 views/pages/collector_firstrun.thtml:43
+#: views/pages/collector.thtml:47 views/pages/collector_features.thtml:55
+#: controllers/search_controller.php:302
+#: controllers/collections_controller.php:206
+#: controllers/collections_controller.php:405
+#: controllers/collections_controller.php:467
+#: controllers/collections_controller.php:539
+#, fuzzy
+msgid "collections_breadcrumb"
+msgstr "Collections"
+
+#: views/collections/detail.thtml:185
+#, fuzzy
+msgid "collections_detail_a_learn"
+msgstr "Learn More"
+
+#: views/elements/amo2009/collection_add_form.thtml:53
+#: views/elements/amo2009/collections_js_init.thtml:68
+#: views/pages/collector_firstrun.thtml:64
+#, fuzzy
+msgid "collections_detail_button_add"
+msgstr "Add to Favorites"
+
+#: views/elements/amo2009/collection_add_form.thtml:50
+#: views/elements/amo2009/collections_js_init.thtml:71
+#, fuzzy
+msgid "collections_detail_button_remove"
+msgstr "Remove from Favorites"
+
+#. %1$s is a URL.
+#. %2$s is a full <a href>.
+#: views/collections/detail.thtml:62
+#, fuzzy
+msgid "collections_detail_created_desc"
+msgstr ""
+"<p>You can view your new collection below. If you'd like to set a collection "
+"nickname, upload an icon, or change additional settings, please visit the <a "
+"href='%1$s'>Manage Collections</a> page.</p><p>Your collection can be "
+"accessed at this location: %2$s</p>"
+
+#: views/collections/detail.thtml:61
+#, fuzzy
+msgid "collections_detail_created_msg"
+msgstr "Your collection is now ready!"
+
+#: views/collections/detail.thtml:109
+#, fuzzy
+msgid "collections_detail_header_about"
+msgstr "About This Collection"
+
+#. %1$s is a number.
+#: views/collections/detail.thtml:126
+#, fuzzy
+msgid "collections_detail_header_count"
+msgid_plural "collections_detail_header_count"
+msgstr[0] "%1$s Add-on in this Collection"
+msgstr[1] "%1$s Add-ons in this Collection"
+
+#: views/collections/detail.thtml:113
+#, fuzzy
+msgid "collections_detail_info_created"
+msgstr "<strong>Created by:</strong> %1$s"
+
+#: views/collections/detail.thtml:117
+#, fuzzy
+msgid "collections_detail_info_updated"
+msgstr "<strong>Updated:</strong>"
+
+#: views/elements/amo2009/collections_js_init.thtml:62
+#, fuzzy
+msgid "collections_detail_js_adding"
+msgstr "Adding to Favorites&hellip;"
+
+#: views/elements/amo2009/collections_js_init.thtml:65
+#, fuzzy
+msgid "collections_detail_js_removing"
+msgstr "Removing Favorite&hellip;"
+
+#. %1$s is a URL
+#: views/collections/detail.thtml:90
+#, fuzzy
+msgid "collections_detail_login"
+msgstr "<a href=\"%1$s\">Log in</a> to add this collection to your favorites."
+
+#: views/collections/detail.thtml:104
+#, fuzzy
+msgid "collections_detail_manage"
+msgstr "Manage Collection"
+
+#: controllers/collections_controller.php:298
+#, fuzzy
+msgid "collections_detail_sort_date"
+msgstr "Date Added"
+
+#: controllers/collections_controller.php:299
+#, fuzzy
+msgid "collections_detail_sort_name"
+msgstr "Name"
+
+#: controllers/collections_controller.php:300
+#, fuzzy
+msgid "collections_detail_sort_popularity"
+msgstr "Popularity"
+
+#. %1$s is a number.
+#: views/collections/detail.thtml:166
+#, fuzzy
+msgid "collections_detail_weekly_downloads"
+msgid_plural "collections_detail_weekly_downloads"
+msgstr[0] "%1$s download this week"
+msgstr[1] "%1$s downloads this week"
+
+#: views/collections/edit.thtml:255
+#, fuzzy
+msgid "collections_edit_addons_delete_noscript"
+msgstr "Selected add-ons will be removed upon Save"
+
+#: views/collections/edit.thtml:247
+#, fuzzy
+msgid "collections_edit_addons_description"
+msgstr ""
+"To publish new add-ons to this collection, start typing their names below."
+
+#: views/collections/edit.thtml:248
+#, fuzzy
+msgid "collections_edit_addons_description_noscript"
+msgstr ""
+"To publish new add-ons to this collection, enter a comma-separated list of "
+"Add-on IDs below."
+
+#: views/collections/edit.thtml:247 views/collections/edit.thtml:248
+#, fuzzy
+msgid "collections_edit_addons_description_publish_detailspage"
+msgstr "You can also publish an add-on from its normal listing page."
+
+#. %1$s is the date the add-on was added to the collection
+#. %1$s is the name of the user who added the add-on to the collection
+#: views/collections/edit.thtml:260
+#, fuzzy
+msgid "collections_edit_addons_listitem_added"
+msgstr "Added %1$s by %2$s"
+
+#: views/collections/edit.thtml:263
+#, fuzzy
+msgid "collections_edit_addons_listitem_comment_add"
+msgstr "Add publisher comment"
+
+#: views/collections/edit.thtml:266
+#, fuzzy
+msgid "collections_edit_addons_listitem_comment_delete"
+msgstr "Delete publisher comment"
+
+#: views/collections/edit.thtml:265
+#, fuzzy
+msgid "collections_edit_addons_listitem_comment_edit"
+msgstr "Edit publisher comment"
+
+#: views/collections/edit.thtml:271
+#, fuzzy
+msgid "collections_edit_addons_listitem_comment_note"
+msgstr ""
+"Note: Comment will appear as though written by original publisher on the "
+"original publication date"
+
+#: views/collections/edit.thtml:270
+#, fuzzy
+msgid "collections_edit_addons_listitem_comment_submit"
+msgstr "Save Comment"
+
+#: views/collections/edit.thtml:261
+#, fuzzy
+msgid "collections_edit_addons_listitem_remove"
+msgstr "Remove"
+
+#: views/collections/edit.thtml:250
+#, fuzzy
+msgid "collections_edit_addons_submit"
+msgstr "Add to Collection"
+
+#: views/collections/edit.thtml:153
+#, fuzzy
+msgid "collections_edit_check_nickname"
+msgstr "Check Availability"
+
+#: views/collections/edit.thtml:299
+#, fuzzy
+msgid "collections_edit_confirm_deletecollection"
+msgstr "Yes, I would like to delete this collection."
+
+#. %1$s is the label of the edit form's submit button
+#: views/collections/edit.thtml:300
+#, fuzzy
+msgid "collections_edit_confirm_deletecollection_description"
+msgstr "Check the box, then click on \"%1$s\" to delete this collection."
+
+#. %1$s is the "delete" submit button text
+#. %2$s is the title of the "advanced" tab
+#: views/collections/edit.thtml:95
+#, fuzzy
+msgid "collections_edit_delete_upon_submit"
+msgstr ""
+"Upon clicking \"%1$s\" below, your collection will be deleted. If you do not "
+"want to delete your collection, uncheck the confirmation box in the \"%2$s\" "
+"tab and continue editing your collection. If you leave this page without "
+"saving, your collection will also not be deleted."
+
+#: views/collections/edit.thtml:94
+#, fuzzy
+msgid "collections_edit_delete_warning"
+msgstr "Your collection is about to be deleted!"
+
+#: views/collections/add.thtml:76 views/collections/edit.thtml:144
+#, fuzzy
+msgid "collections_edit_form_error_description"
+msgstr "You must provide a description of your collection."
+
+#: views/collections/edit.thtml:181
+#, fuzzy
+msgid "collections_edit_form_error_icon"
+msgstr "There was an error uploading your icon."
+
+#: views/collections/add.thtml:69 views/collections/edit.thtml:130
+#, fuzzy
+msgid "collections_edit_form_error_name"
+msgstr "You must give your collection a name."
+
+#: views/collections/edit.thtml:158
+#, fuzzy
+msgid "collections_edit_form_error_nickname"
+msgstr "If you choose a nickname, it must be unique."
+
+#: views/collections/add.thtml:93 views/collections/edit.thtml:249
+#, fuzzy
+msgid "collections_edit_formfield_addons"
+msgstr "Add-on name:"
+
+#: views/collections/edit.thtml:281
+#, fuzzy
+msgid "collections_edit_formfield_application"
+msgstr "Associated Application"
+
+#: views/collections/edit.thtml:282
+#, fuzzy
+msgid "collections_edit_formfield_application_description"
+msgstr "Select the application that your collection supports."
+
+#: views/collections/edit.thtml:288
+#, fuzzy
+msgid "collections_edit_formfield_collectiontype"
+msgstr "Collection Type"
+
+#: views/collections/edit.thtml:295
+#, fuzzy
+msgid "collections_edit_formfield_deletecollection"
+msgstr "Delete Collection"
+
+#: views/collections/edit.thtml:296
+#, fuzzy
+msgid "collections_edit_formfield_deletecollection_description"
+msgstr "Deleting your collection will permanently erase it."
+
+#: views/collections/add.thtml:73 views/collections/edit.thtml:140
+#, fuzzy
+msgid "collections_edit_formfield_description"
+msgstr "Collection Description"
+
+#: views/collections/add.thtml:74 views/collections/edit.thtml:141
+#, fuzzy
+msgid "collections_edit_formfield_description_description"
+msgstr "Briefly describe your collection and the kind of add-ons in it"
+
+#: views/collections/edit.thtml:162
+#, fuzzy
+msgid "collections_edit_formfield_icon"
+msgstr "Icon"
+
+#: views/collections/edit.thtml:163
+#, fuzzy
+msgid "collections_edit_formfield_icon_description"
+msgstr ""
+"You can upload a JPG, GIF or PNG icon that will be resized to 32x32 pixels."
+
+#: views/collections/add.thtml:80 views/collections/edit.thtml:189
+#, fuzzy
+msgid "collections_edit_formfield_listed"
+msgstr "Who can view your collection?"
+
+#: views/collections/add.thtml:81 views/collections/edit.thtml:190
+#, fuzzy
+msgid "collections_edit_formfield_listed_description"
+msgstr ""
+"By default, collections appear in the public Collection Directory and are "
+"discoverable by anyone. If you want to restrict your collection to be "
+"viewable only by people who are given a special link, choose that option "
+"below."
+
+#: views/collections/add.thtml:84 views/collections/edit.thtml:193
+#, fuzzy
+msgid "collections_edit_formfield_listed_false"
+msgstr "Only people I invite can view my collection"
+
+#: views/collections/add.thtml:83 views/collections/edit.thtml:192
+#, fuzzy
+msgid "collections_edit_formfield_listed_true"
+msgstr "Everyone can view my collection in the directory"
+
+#: views/collections/edit.thtml:223
+#, fuzzy
+msgid "collections_edit_formfield_managers"
+msgstr "Who can manage my collection?"
+
+#: views/collections/edit.thtml:224
+#, fuzzy
+msgid "collections_edit_formfield_managers_description"
+msgstr ""
+"These users can publish add-ons to your collection, manage all add-ons and "
+"settings, and grant other users permission."
+
+#: views/collections/add.thtml:66 views/collections/edit.thtml:126
+#, fuzzy
+msgid "collections_edit_formfield_name"
+msgstr "Collection Name"
+
+#: views/collections/add.thtml:67 views/collections/edit.thtml:127
+#, fuzzy
+msgid "collections_edit_formfield_name_description"
+msgstr ""
+"Give your collection a descriptive name, such as \"Dave's Favorite Travel "
+"Add-ons\""
+
+#: views/collections/edit.thtml:148
+#, fuzzy
+msgid "collections_edit_formfield_nickname"
+msgstr "Collection Nickname"
+
+#: views/collections/edit.thtml:149
+#, fuzzy
+msgid "collections_edit_formfield_nickname_description"
+msgstr "Optionally, give your collection a unique nickname for quick access:"
+
+#: views/collections/edit.thtml:201
+#, fuzzy
+msgid "collections_edit_formfield_publishers"
+msgstr "Who can publish add-ons to your collection?"
+
+#: views/collections/edit.thtml:202
+#, fuzzy
+msgid "collections_edit_formfield_publishers_description"
+msgstr ""
+"These users can publish add-ons to your collection and remove add-ons that "
+"they publish."
+
+#: views/collections/edit.thtml:210 views/collections/edit.thtml:232
+#, fuzzy
+msgid "collections_edit_formfield_users_add"
+msgstr "Enter the e-mail address of a Firefox Add-ons account:"
+
+#: views/collections/edit.thtml:216 views/collections/edit.thtml:238
+#, fuzzy
+msgid "collections_edit_formfield_users_delete_noscript"
+msgstr "Selected accounts will be removed upon Save"
+
+#: views/collections/edit.thtml:215 views/collections/edit.thtml:237
+#, fuzzy
+msgid "collections_edit_formfield_users_new_noscript"
+msgstr ""
+"Enter a comma-separated list of e-mail addresses of Firefox Add-ons accounts"
+
+#: views/collections/edit.thtml:204 views/collections/edit.thtml:226
+#, fuzzy
+msgid "collections_edit_formfield_users_onlyme"
+msgstr "Only me"
+
+#: views/collections/edit.thtml:205 views/collections/edit.thtml:227
+#, fuzzy
+msgid "collections_edit_formfield_users_otherusers"
+msgstr "Myself and these users:"
+
+#: views/collections/edit.thtml:211 views/collections/edit.thtml:233
+#, fuzzy
+msgid "collections_edit_formfield_users_submit"
+msgstr "Add"
+
+#. %1$s is the name of the collection
+#: views/collections/edit.thtml:68
+#, fuzzy
+msgid "collections_edit_header"
+msgstr "Manage %1$s"
+
+#: views/collections/edit.thtml:246
+#, fuzzy
+msgid "collections_edit_header_addons"
+msgstr "Manage Collection Contents"
+
+#: views/collections/edit.thtml:253 views/collections/edit.thtml:258
+#, fuzzy
+msgid "collections_edit_header_addons_current"
+msgstr "Current Add-ons:"
+
+#: views/collections/edit.thtml:279
+#, fuzzy
+msgid "collections_edit_header_advanced"
+msgstr "Advanced Settings"
+
+#: views/collections/edit.thtml:186
+#, fuzzy
+msgid "collections_edit_header_permissions"
+msgstr "Manage Collection Permissions"
+
+#: views/collections/edit.thtml:170
+#, fuzzy
+msgid "collections_edit_icon_cancel"
+msgstr "Cancel"
+
+#: views/collections/edit.thtml:174 views/collections/edit.thtml:179
+#, fuzzy
+msgid "collections_edit_icon_delete"
+msgstr "Delete Icon"
+
+#: views/collections/edit.thtml:178
+#, fuzzy
+msgid "collections_edit_icon_replace"
+msgstr "Replace Icon"
+
+#. %1$s is the label of the edit form's submit button
+#: views/collections/edit.thtml:169
+#, fuzzy
+msgid "collections_edit_icon_toberemoved"
+msgstr "Icon will be removed when \"%1$s\" is clicked below"
+
+#: views/collections/edit.thtml:155
+#, fuzzy
+msgid "collections_edit_nickname_available"
+msgstr "Nickname Available"
+
+#: controllers/collections_controller.php:943
+#, fuzzy
+msgid "collections_edit_nickname_error"
+msgstr ""
+"Your nickname contained invalid characters and was corrected. Please try "
+"again."
+
+#: views/collections/edit.thtml:156
+#, fuzzy
+msgid "collections_edit_nickname_taken"
+msgstr "Nickname Taken"
+
+#. This string is followed by a URL pointing to the collection's view page
+#: views/collections/edit.thtml:75
+#, fuzzy
+msgid "collections_edit_saved_nextstep"
+msgstr "Your collection can be accessed at this location:"
+
+#: views/collections/edit.thtml:74
+#, fuzzy
+msgid "collections_edit_saved_success"
+msgstr "Your collection was successfully saved!"
+
+#: views/collections/edit.thtml:169 views/collections/edit.thtml:300
+#: views/collections/edit.thtml:308 views/pages/js_constants.js.thtml:99
+#, fuzzy
+msgid "collections_edit_submit"
+msgstr "Update Collection"
+
+#: views/collections/edit.thtml:96 views/collections/edit.thtml:297
+#: views/pages/js_constants.js.thtml:100
+#, fuzzy
+msgid "collections_edit_submit_deletecollection"
+msgstr "Delete Collection"
+
+#: views/collections/edit.thtml:111
+#, fuzzy
+msgid "collections_edit_tabheader_addons"
+msgstr "Add-ons"
+
+#: views/collections/edit.thtml:97 views/collections/edit.thtml:113
+#, fuzzy
+msgid "collections_edit_tabheader_advanced"
+msgstr "Advanced"
+
+#: views/collections/edit.thtml:108
+#, fuzzy
+msgid "collections_edit_tabheader_details"
+msgstr "Name &amp; Details"
+
+#: views/collections/edit.thtml:109
+#, fuzzy
+msgid "collections_edit_tabheader_permissions"
+msgstr "Permissions"
+
+#: models/collection_promo.php:53
+#, fuzzy
+msgid "collections_family_tagline"
+msgstr "Add-ons can keep an eye on your kids and your calendar."
+
+#: models/collection_promo.php:53
+#, fuzzy
+msgid "collections_family_title"
+msgstr "Family Organizer"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:70
+#, fuzzy
+msgid "collections_index_a_check_out"
+msgstr "Check out Add-on Collector"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:52
+#, fuzzy
+msgid "collections_index_a_create"
+msgstr "Create a Collection"
+
+#: views/collections/detail.thtml:139 views/collections/listing.thtml:85
+#: views/search/collections.thtml:84
+#, fuzzy
+msgid "collections_index_button_go"
+msgstr "Go"
+
+#. %1$s is a URL.
+#: controllers/collections_controller.php:182
+#, fuzzy
+msgid "collections_index_filler_favorites"
+msgstr ""
+"<p><strong>You don't have any favorite collections yet.</strong></p> "
+"<p>Collections you mark as favorites can be quickly accessed from this page, "
+"and will appear in the <a href='%1$s'>Add-on Collector</a> if you've "
+"installed it.</p>"
+
+#. %1$s is a URL.
+#: controllers/collections_controller.php:167
+#, fuzzy
+msgid "collections_index_filler_mine"
+msgstr ""
+"<p>You haven't created any collections yet. Collections are easy to create "
+"and fill with your favorite add-ons. <a href='%1$s'>Try it out</a>!</p>"
+
+#: views/collections/listing.thtml:51
+#, fuzzy
+msgid "collections_index_header_collections"
+msgstr "Collections"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:60
+#, fuzzy
+msgid "collections_index_header_collector"
+msgstr "Add-on Collector"
+
+#. %1$s is a comma-separated list of author names
+#: views/elements/amo2009/collection_listing_item.thtml:84
+#: views/collections/detail.thtml:151
+#, fuzzy
+msgid "collections_index_header_created"
+msgstr "created by %1$s"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:47
+#, fuzzy
+msgid "collections_index_header_what"
+msgstr "What are Collections?"
+
+#: views/collections/detail.thtml:132 views/collections/listing.thtml:78
+#: views/search/collections.thtml:66
+#, fuzzy
+msgid "collections_index_label_sortby"
+msgstr "Sort by"
+
+#: controllers/collections_controller.php:130
+#, fuzzy
+msgid "collections_index_li_editors"
+msgstr "Editor's Picks"
+
+#: views/collections/subscribe.thtml:64
+#: controllers/collections_controller.php:140
+#, fuzzy
+msgid "collections_index_li_favorites"
+msgstr "My Favorites"
+
+#: controllers/collections_controller.php:138
+#, fuzzy
+msgid "collections_index_li_mine"
+msgstr "My Collections"
+
+#: controllers/collections_controller.php:132
+#, fuzzy
+msgid "collections_index_li_popular"
+msgstr "Popular"
+
+#: views/search/collections.thtml:74 controllers/collections_controller.php:81
+#, fuzzy
+msgid "collections_index_option_all"
+msgstr "Most popular all time"
+
+#: views/search/collections.thtml:72 controllers/collections_controller.php:78
+#, fuzzy
+msgid "collections_index_option_month"
+msgstr "Most popular this month"
+
+#: views/search/collections.thtml:76 controllers/collections_controller.php:84
+#, fuzzy
+msgid "collections_index_option_newest"
+msgstr "Newest"
+
+#: views/search/collections.thtml:70 controllers/collections_controller.php:75
+#, fuzzy
+msgid "collections_index_option_week"
+msgstr "Most popular this week"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:67
+#, fuzzy
+msgid "collections_index_p_collector"
+msgstr ""
+"There's a new way to manage and find favorite add-ons. Comment, share and "
+"sync collections, all from your browser"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:48
+#, fuzzy
+msgid "collections_index_p_what_are"
+msgstr "Collections are groups of related add-ons assembled for easy sharing."
+
+#. %s is a date in the _('date') format
+#: views/elements/collections_interactive_addon.thtml:85
+#, fuzzy, php-format
+msgid "collections_interactive_addon_added"
+msgstr "Added %s"
+
+#: models/collection_promo.php:55
+#, fuzzy
+msgid "collections_reference_tagline"
+msgstr "Add-ons can do better research online."
+
+#: models/collection_promo.php:55
+#, fuzzy
+msgid "collections_reference_title"
+msgstr "Reference Desk"
+
+#: models/collection_promo.php:52
+#, fuzzy
+msgid "collections_social_tagline"
+msgstr "Add-ons can manage your social network."
+
+#: models/collection_promo.php:52
+#, fuzzy
+msgid "collections_social_title"
+msgstr "Social Circuit"
+
+#: views/collections/subscribe.thtml:91
+#, fuzzy
+msgid "collections_subscribe_button_close"
+msgstr "Close"
+
+#: views/collections/subscribe.thtml:70
+#, fuzzy
+msgid "collections_subscribe_error"
+msgstr ""
+"An error occurred trying to add a favorite collection. Is this collection "
+"already a favorite?"
+
+#: views/collections/subscribe.thtml:96
+#, fuzzy
+msgid "collections_subscribe_label_bothersome"
+msgstr "Don't show me this message again."
+
+#. %1$s is the collection name
+#: views/collections/subscribe.thtml:60
+#, fuzzy
+msgid "collections_subscribe_success"
+msgstr "%1$s has been added to your favorite collections."
+
+#. %1$s is the link to the "My Favorites" tab on the main collections page
+#. %2$s is the localized title of the "My Favorites" tab
+#. %3$s is the link URL to the collector add-on
+#: views/collections/subscribe.thtml:62
+#, fuzzy
+msgid "collections_subscribe_success_desc"
+msgstr ""
+"You can now quickly find this collection from the <a href=\"%1$s\">%2$s</a> "
+"tab in the directory. For an even easier way to keep track of your favorite "
+"collections, try out our <a href=\"%3$s\">Add-on Collector</a> extension for "
+"Firefox."
+
+#: views/collections/listing.thtml:55
+#, fuzzy
+msgid "collections_success_delete"
+msgstr "The collection has been deleted."
+
+#: models/collection_promo.php:54
+#, fuzzy
+msgid "collections_travel_tagline"
+msgstr "Add-ons can turn you into a travel agent."
+
+#: models/collection_promo.php:54
+#, fuzzy
+msgid "collections_travel_title"
+msgstr "The Traveler's Pack"
+
+#. A collection of add-ons that is automatically built for a user. They are "automatically published" to this collection.
+#: controllers/collections_controller.php:581
+#, fuzzy
+msgid "collections_type_autopublisher"
+msgstr "Auto-publisher"
+
+#. A collection that has been chosen by an Editor as notable or exceptional
+#: controllers/collections_controller.php:582
+#, fuzzy
+msgid "collections_type_editorspick"
+msgstr "Editor's Pick"
+
+#: controllers/collections_controller.php:580
+#, fuzzy
+msgid "collections_type_normal"
+msgstr "Normal"
+
+#: views/collections/subscribe.thtml:84
+#, fuzzy
+msgid "collections_unsubscribe_error"
+msgstr ""
+"An error occurred trying to remove a favorite collection. Was this "
+"collection not a favorite?"
+
+#. %1$s is the collection name
+#: views/collections/subscribe.thtml:78
+#, fuzzy
+msgid "collections_unsubscribe_success"
+msgstr "%1$s has been removed from your favorite collections."
+
+#: models/collection_promo.php:56
+#, fuzzy
+msgid "collections_webdev_tagline"
+msgstr "Add-ons make it easier to build the perfect website."
+
+#: models/collection_promo.php:56
+#, fuzzy
+msgid "collections_webdev_title"
+msgstr "Web Developer's Toolbox"
+
+#: views/elements/amo2009/collections_sidebar_whatare.thtml:40
+#, fuzzy
+msgid "collections_whatare_header"
+msgstr "What are Collections?"
+
+#: views/elements/amo2009/collections_sidebar_whatare.thtml:45
+#, fuzzy
+msgid "collections_whatare_learnmore"
+msgstr "Read the FAQ"
+
+#: views/elements/amo2009/collections_sidebar_whatare.thtml:44
+#, fuzzy
+msgid "collections_whatare_text"
+msgstr ""
+"There’s a new way to manage and find favorite add-ons. Comment, share and "
+"sync collections, all from your browser."
+
+#: views/pages/collector_faq.thtml:61 views/pages/collector_features.thtml:67
+#, fuzzy
+msgid "collector_features_a_home"
+msgstr "Add-on Collector Home"
+
+#: views/elements/amo2009/collector_sidebar_download.thtml:46
+#, fuzzy
+msgid "collector_features_heading_download"
+msgstr "Download the Add-on Collector:"
+
+#: views/elements/amo2009/collector_sidebar_download.thtml:43
+#: views/pages/collector_firstrun.thtml:116 views/pages/collector.thtml:69
+#, fuzzy
+msgid "collector_features_img_logo"
+msgstr "Add-on Collector Logo"
+
+#: views/compatibility/dashboard.thtml:49
+#: controllers/compatibility_controller.php:72
+#, fuzzy
+msgid "compatibility_dashboard_center_header"
+msgstr "Add-on Compatibility Center"
+
+#. %1$s is the name of an application and a version. Example: Firefox 3.0
+#. %2$s is the name of an application. Example: Firefox
+#: views/compatibility/dashboard.thtml:50
+#, fuzzy
+msgid "compatibility_dashboard_intro"
+msgstr ""
+"Be prepared for the release of %1$s with the tools and information available "
+"for the %2$s Add-ons community found below."
+
+#: views/compatibility/dashboard.thtml:103
+#, fuzzy
+msgid "compatibility_dashboard_loading"
+msgstr "Loading data..."
+
+#: views/compatibility/dashboard.thtml:45
+#, fuzzy
+msgid "compatibility_dashboard_main_link"
+msgstr "Back to Main"
+
+#: views/compatibility/dashboard.thtml:100 views/compatibility/report.thtml:43
+#, fuzzy
+msgid "compatibility_dashboard_report"
+msgstr "Add-on Compatibility Report"
+
+#: views/compatibility/dashboard.thtml:53
+#: views/compatibility/dashboard.thtml:110
+#: views/compatibility/developers.thtml:43
+#, fuzzy
+msgid "compatibility_developer_info"
+msgstr "Information for Add-on Developers"
+
+#: views/compatibility/developers.thtml:66
+#, fuzzy
+msgid "compatibility_developers_adjust_maxversion"
+msgstr "Adjust maxVersion without uploading"
+
+#: views/compatibility/dashboard.thtml:124
+#, fuzzy
+msgid "compatibility_developers_check_status"
+msgstr "Check Status of My Add-ons"
+
+#. %1$s is a URL
+#. %2$s is an application and version. Example: Firefox 3.0
+#: views/compatibility/dashboard.thtml:126
+#, fuzzy
+msgid "compatibility_developers_login_first"
+msgstr ""
+"If you have add-ons hosted on Mozilla Add-ons, <a href=\"%1$s\">please "
+"login</a> to analyze the status of your add-ons for %2$s."
+
+#: views/compatibility/dashboard.thtml:114
+#, fuzzy
+msgid "compatibility_developers_mdclogo_alt"
+msgstr "Mozilla Developer Center Logo"
+
+#: views/compatibility/developers.thtml:73
+#, fuzzy
+msgid "compatibility_developers_no_addons"
+msgstr "You do not have any add-ons hosted on Mozilla Add-ons."
+
+#: views/compatibility/dashboard.thtml:133
+#: views/compatibility/developers.thtml:55
+#, fuzzy
+msgid "compatibility_developers_results"
+msgstr "Add-on Status Check Results"
+
+#: views/compatibility/dashboard.thtml:137
+#, fuzzy
+msgid "compatibility_developers_retrieving"
+msgstr "Retrieving status of hosted add-ons..."
+
+#. %1$s is a number
+#. %2$s is an application name
+#. %3$s is a number.
+#. Full example: 50 Firefox users (10% of total)
+#: views/compatibility/developers.thtml:65
+#, fuzzy
+msgid "compatibility_developers_user_count"
+msgstr "%1$s %2$s users (%3$s&#37; of total)"
+
+#: views/compatibility/report.thtml:45
+#, fuzzy
+msgid "compatibility_report_detail_intro"
+msgstr ""
+"The add-ons below make up 95% of add-on usage known to Mozilla and are "
+"ordered by their usage size."
+
+#: views/compatibility/dashboard.thtml:94
+#, fuzzy
+msgid "compatibility_report_detailed_link"
+msgstr "View Detailed Report"
+
+#. %1$s and %2$s are numbers
+#. %3$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:65
+#, fuzzy
+msgid "compatibility_report_intro"
+msgstr ""
+"Of the %1$s add-ons that make up 95&#37; of add-on usage known to Mozilla, "
+"<b>%2$s&#37;</b> are currently considered compatible with the latest builds "
+"of %3$s."
+
+#: views/compatibility/dashboard.thtml:81
+#, fuzzy
+msgid "compatibility_report_legend_alpha"
+msgstr "Alpha Versions"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:81
+#, fuzzy
+msgid "compatibility_report_legend_alpha_description"
+msgstr "Add-ons compatible with an alpha version of %1$s"
+
+#: views/compatibility/dashboard.thtml:85
+#, fuzzy
+msgid "compatibility_report_legend_beta"
+msgstr "Beta Versions"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:85
+#, fuzzy
+msgid "compatibility_report_legend_beta_description"
+msgstr "Add-ons compatible with a beta version or release candidate of %1$s"
+
+#: views/compatibility/dashboard.thtml:89
+#, fuzzy
+msgid "compatibility_report_legend_latest"
+msgstr "Latest Version"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:89
+#, fuzzy
+msgid "compatibility_report_legend_latest_description"
+msgstr "Add-ons up-to-date with the latest builds of %1$s"
+
+#: views/compatibility/dashboard.thtml:77
+#, fuzzy
+msgid "compatibility_report_legend_other"
+msgstr "Other Versions"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:77
+#, fuzzy
+msgid "compatibility_report_legend_other_description"
+msgstr "Add-ons not compatible with any version of %1$s"
+
+#: views/compatibility/dashboard.thtml:62
+#, fuzzy
+msgid "compatibility_report_title"
+msgstr "Add-on Compatibility Report"
+
+#: views/compatibility/dashboard.thtml:54
+#: views/compatibility/dashboard.thtml:144 views/compatibility/users.thtml:42
+#, fuzzy
+msgid "compatibility_user_info"
+msgstr "Information for Add-on Users"
+
+#: views/compatibility/dashboard.thtml:52
+#, fuzzy
+msgid "compatibility_view_report"
+msgstr "View Compatibility Report"
+
+#. %s is a URL
+#: views/pages/credits.thtml:142
+#, php-format
+msgid "credits_contributing"
+msgstr "למידע נוסף על תרומה, בבקשה ר××” ×ת %s שלנו."
+
+#: views/pages/credits.thtml:142
+msgid "credits_contributing_wikipage"
+msgstr "דף וויקי"
+
+#: views/pages/credits.thtml:99
+msgid "credits_intro"
+msgstr ""
+"Mozilla ×ž×¢×•× ×™×™× ×™× ×œ×”×•×“×•×ª ל×× ×©×™× ×”×‘××™× ×¢×œ ×ª×¨×•×ž×ª× ×œ×¤×¨×•×™×™×§×˜ addons.mozilla.org "
+"במשך השני×:"
+
+#: views/pages/credits.thtml:103
+msgid "credits_section_developers"
+msgstr "מפתחי×"
+
+#: views/pages/credits.thtml:115
+msgid "credits_section_editors"
+msgstr "עורכי×"
+
+#: views/pages/credits.thtml:109
+msgid "credits_section_localizers"
+msgstr "מתרגמי×"
+
+#: views/pages/credits.thtml:121
+msgid "credits_section_other_contributors"
+msgstr "×ª×•×¨×ž×™× ×חרי×"
+
+#: views/pages/credits.thtml:127
+msgid "credits_section_past_developers"
+msgstr "מפתחי עבר"
+
+#: views/pages/credits.thtml:133
+msgid "credits_section_software"
+msgstr "תוכנה ותמונות"
+
+#: views/pages/credits.thtml:136
+msgid "credits_software_famfamfam"
+msgstr ""
+"חלק מהצלמיות הן מ-<a href=\"http://www.famfamfam.com/lab/icons/silk/"
+"\">famfamfam Silk Icon Set</a>, ומשוחררות תחת רשיון <a href=\"http://"
+"creativecommons.org/licenses/by/2.5/\">Creative Commons Attribution 2.5 "
+"License</a>."
+
+#: views/pages/credits.thtml:137
+#, fuzzy
+msgid "credits_software_timeplot"
+msgstr ""
+"Some pages use elements of <a href=\"http://www.simile-widgets.org/timeplot/"
+"\">Timeplot</a>, licensed under a <a href=\"http://simile.mit.edu/license."
+"html\">BSD License</a>."
+
+#. date format string as used in PHP's strftime():
+#. http://php.net/strftime
+#: views/elements/collections_interactive_addon.thtml:85
+#: views/elements/amo2009/addon_version_detail.thtml:53
+#: views/elements/amo2009/homepage_addon.thtml:115
+#: views/elements/addon_version_detail.thtml:54
+#: views/elements/addon_listitem.thtml:124 views/elements/feature.thtml:106
+#: views/collections/detail.thtml:118 views/collections/edit.thtml:325
+#: views/users/info.thtml:76 views/editors/reviews_queue.thtml:57
+#: views/editors/reviews_queue.thtml:68 views/developers/dashboard.thtml:65
+#: views/developers/versions_edit.thtml:208 views/developers/versions.thtml:67
+#: views/search/rss/index.thtml:5 views/addons/rss/versions.thtml:42
+#: views/addons/display.thtml:104 views/addons/display.thtml:356
+#: views/addons/browse_thumbs.thtml:75 views/reviews/add.thtml:63
+#: views/reviews/display.thtml:74 views/reviews/display.thtml:160
+#: views/reviews/delete.thtml:54 controllers/statistics_controller.php:244
+#: controllers/collections_controller.php:1047
+msgid "date"
+msgstr "%d/%m/%y"
+
+#. date and time format string (strftime)
+#. http://php.net/strftime
+#: views/elements/addon_version_detail.thtml:53
+#: views/developers/discuss.thtml:52 views/developers/discuss.thtml:62
+#: views/admin/addons_status.thtml:57
+msgid "datetime"
+msgstr "%e ב%B %Y, %H:%M"
+
+#: views/elements/developers/actionbar.thtml:47
+msgid "devcp_actionbar_link_details"
+msgstr "מידע מפורט"
+
+#: views/elements/developers/actionbar.thtml:42
+#: views/elements/developers/actionbar.thtml:50
+#: views/developers/dashboard.thtml:64
+msgid "devcp_actionbar_link_edit"
+msgstr "ערוך תוספת"
+
+#: views/elements/developers/actionbar.thtml:51
+msgid "devcp_actionbar_link_newversion"
+msgstr "העלה גירסה חדשה"
+
+#: views/elements/developers/actionbar.thtml:44
+#: views/elements/developers/actionbar.thtml:49
+#: views/developers/dashboard.thtml:73
+msgid "devcp_actionbar_link_stats"
+msgstr "לוח סטיסטיקות"
+
+#. %1$s is a filename, e.g. "foo.txt"
+#. %2$s is the extension, e.g. ".txt"
+#. %3$s is a list of valid extensions, like ".png, .jpg, .gif"
+#: controllers/developers_controller.php:1361
+#, fuzzy
+msgid "devcp_add_previews_extension_error"
+msgstr "File %1$s has an invalid extension (%2$s). Allowed extensions: %3$s"
+
+#. %s is the filename.
+#: controllers/developers_controller.php:1394
+#, fuzzy
+msgid "devcp_add_previews_save_error"
+msgstr "File %s could not be saved to the database. Please try again."
+
+#. %1$s is the preview ID number, %2$s is the filename.
+#: controllers/developers_controller.php:1389
+#, fuzzy
+msgid "devcp_add_previews_success_replace"
+msgstr "Preview %1$s was replaced with file %2$s successfully."
+
+#. %s is the filename.
+#: controllers/developers_controller.php:1391
+#, fuzzy
+msgid "devcp_add_previews_success_upload"
+msgstr "File %s was uploaded successfully. You can add a caption below."
+
+#: controllers/components/developers.php:1163
+msgid "devcp_additem_addontype_autodetect"
+msgstr "(×בחנה ×וטומטית)"
+
+#: views/elements/developers/additem.thtml:76
+msgid "devcp_additem_linktitle_opensin_newwindow"
+msgstr "פתח בחלון חדש"
+
+#: views/elements/developers/additem.thtml:41
+msgid "devcp_additem_sidebar_title"
+msgstr "שלח תוספת"
+
+#: views/elements/developers/additem.thtml:53
+msgid "devcp_additem_step0_newlink"
+msgstr "רישיון מפתח"
+
+#: views/elements/developers/additem.thtml:46
+msgid "devcp_additem_step1_link"
+msgstr "שלב ר×שון: העל××”"
+
+#: views/elements/developers/additem.thtml:47
+msgid "devcp_additem_step2_link"
+msgstr "שלב שני: פרטי התוספת"
+
+#: views/elements/developers/additem.thtml:48
+msgid "devcp_additem_step3_link"
+msgstr "שלב שלישי: פרטי גירסה"
+
+#: views/elements/developers/additem.thtml:49
+msgid "devcp_additem_step4_link"
+msgstr "שלב רביעי: הת×מות שפה"
+
+#: views/elements/developers/additem.thtml:50
+msgid "devcp_additem_step5_link"
+msgstr "שלב חמישי: הצלחה"
+
+#: views/elements/developers/additem.thtml:76
+msgid "devcp_additem_submissionhelp_link"
+msgstr "הגשת עזרה"
+
+#: controllers/previews_controller.php:168
+#: controllers/previews_controller.php:277
+msgid "devcp_addon_field_preview_caption_displaytitle"
+msgstr "כותרת תצוגה מקדימה"
+
+#: views/developers/addon_status.thtml:177
+#, fuzzy
+msgid "devcp_addon_status_action_activate"
+msgstr "Make Active"
+
+#: views/developers/addon_status.thtml:178
+#, fuzzy
+msgid "devcp_addon_status_action_activate_description"
+msgstr ""
+"Make your add-on active for it to show up in public listings and enable the "
+"update check service."
+
+#: views/developers/addon_status.thtml:135
+#, fuzzy
+msgid "devcp_addon_status_action_complete"
+msgstr "Complete Add-on"
+
+#: views/developers/addon_status.thtml:136
+#, fuzzy
+msgid "devcp_addon_status_action_complete_description"
+msgstr "Complete your add-on and move to the Sandbox"
+
+#: views/developers/addon_status.thtml:181
+#, fuzzy
+msgid "devcp_addon_status_action_deactivate"
+msgstr "Make Inactive"
+
+#: views/developers/addon_status.thtml:182
+#, fuzzy
+msgid "devcp_addon_status_action_deactivate_description"
+msgstr ""
+"Make your add-on inactive to hide it from all public listings and disable "
+"the update check service."
+
+#: views/developers/addon_status.thtml:143
+#, fuzzy
+msgid "devcp_addon_status_action_move"
+msgstr "Move to Sandbox"
+
+#: views/developers/addon_status.thtml:144
+#, fuzzy
+msgid "devcp_addon_status_action_move_description"
+msgstr "Move your add-on back to the Sandbox. This is reversible."
+
+#: views/developers/addon_status.thtml:139
+#, fuzzy
+msgid "devcp_addon_status_action_nominate"
+msgstr "Nominate for Public"
+
+#: views/developers/addon_status.thtml:140
+#, fuzzy
+msgid "devcp_addon_status_action_nominate_description"
+msgstr "Nominate your add-on to become Public"
+
+#: views/developers/addon_status.thtml:147
+#, fuzzy
+msgid "devcp_addon_status_action_public"
+msgstr "Make Public"
+
+#: views/developers/addon_status.thtml:148
+#, fuzzy
+msgid "devcp_addon_status_action_public_description"
+msgstr "Make your add-on Public again."
+
+#: views/developers/addon_status.thtml:169
+#, fuzzy
+msgid "devcp_addon_status_active"
+msgstr ""
+"Your add-on is <span class=\"inactive-0\">Active</span>. This means your add-"
+"on is showing up in all available listings appropriate for its status above."
+
+#: views/developers/addon_status.thtml:111
+#, fuzzy
+msgid "devcp_addon_status_completion_disabled"
+msgstr ""
+"Please fulfill the criteria above before you can complete your add-on and "
+"move it to the <span class=\"status-1\">Sandbox</span>."
+
+#: views/developers/addon_status.thtml:108
+#, fuzzy
+msgid "devcp_addon_status_completion_enabled"
+msgstr ""
+"You may now complete your add-on and move it to the <span class=\"status-1"
+"\">Sandbox</span> by clicking the button below."
+
+#: views/developers/addon_status.thtml:102
+#, fuzzy
+msgid "devcp_addon_status_criteria_category"
+msgstr "At least one category selected"
+
+#: views/developers/addon_status.thtml:101
+#, fuzzy
+msgid "devcp_addon_status_criteria_description"
+msgstr "Add-on Description required"
+
+#: views/developers/addon_status.thtml:99
+#, fuzzy
+msgid "devcp_addon_status_criteria_name"
+msgstr "Add-on Name required"
+
+#: views/developers/addon_status.thtml:120
+#, fuzzy
+msgid "devcp_addon_status_criteria_prerelease"
+msgstr "Add-on is not marked as pre-release."
+
+#: views/developers/addon_status.thtml:119
+#, fuzzy
+msgid "devcp_addon_status_criteria_preview"
+msgstr "At least one preview image required for extensions and themes."
+
+#: views/developers/addon_status.thtml:100
+#, fuzzy
+msgid "devcp_addon_status_criteria_summary"
+msgstr "Add-on Summary required"
+
+#. %s is the status in a span, e.g. "<span>_('Public')</span>".
+#: views/developers/addon_status.thtml:58
+#, fuzzy
+msgid "devcp_addon_status_header"
+msgstr "Add-on Status: %s"
+
+#: views/developers/addon_status.thtml:152
+#: views/developers/addon_status.thtml:173
+#, fuzzy
+msgid "devcp_addon_status_header_actions"
+msgstr "Available Actions"
+
+#: views/developers/addon_status.thtml:168
+#, fuzzy
+msgid "devcp_addon_status_header_active"
+msgstr "Active Status: <span class=\"inactive-0\">Active</span>"
+
+#: views/developers/addon_status.thtml:97
+#, fuzzy
+msgid "devcp_addon_status_header_criteria"
+msgstr "Add-on Completion Criteria"
+
+#: views/developers/addon_status.thtml:164
+#, fuzzy
+msgid "devcp_addon_status_header_inactive"
+msgstr "Active Status: <span class=\"inactive-1\">Inactive</span>"
+
+#: views/developers/addon_status.thtml:117
+#, fuzzy
+msgid "devcp_addon_status_header_nomination"
+msgstr "Public Nomination Criteria"
+
+#: views/developers/addon_status.thtml:190
+#, fuzzy
+msgid "devcp_addon_status_header_trusted"
+msgstr "Trusted Status: <span class=\"status-4\">Trusted</span>"
+
+#: views/developers/addon_status.thtml:165
+#, fuzzy
+msgid "devcp_addon_status_inactive"
+msgstr ""
+"Your add-on is <span class=\"inactive-1\">Inactive</span>. This means your "
+"add-on will not show up in any listing, regardless of its status above. "
+"Updates are <b>not</b> being provided to your add-on through the update "
+"check service."
+
+#: views/developers/addon_status.thtml:128
+#, fuzzy
+msgid "devcp_addon_status_nominate_disabled"
+msgstr ""
+"Please fulfill the criteria above before nominating your add-on to become "
+"<span class=\"status-4\">Public</span>."
+
+#: views/developers/addon_status.thtml:125
+#, fuzzy
+msgid "devcp_addon_status_nominate_enabled"
+msgstr ""
+"You may now nominate your add-on for <span class=\"status-4\">Public</span> "
+"by clicking the button below."
+
+#: views/developers/addon_status.thtml:64
+#, fuzzy
+msgid "devcp_addon_status_public"
+msgstr "Public"
+
+#: views/developers/addon_status.thtml:63
+#, fuzzy
+msgid "devcp_addon_status_sandbox"
+msgstr "Sandbox"
+
+#. %s is an email address.
+#: views/developers/addon_status.thtml:89
+#, fuzzy
+msgid "devcp_addon_status_switch_disabled"
+msgstr ""
+"Your add-on was <span class=\"status-5\">Disabled</span> by an administrator "
+"and cannot be used. If you have any questions, please e-mail %s."
+
+#: views/developers/addon_status.thtml:67
+#, fuzzy
+msgid "devcp_addon_status_switch_incomplete"
+msgstr ""
+"Your add-on is currently <span class=\"status-0\">Incomplete</span>. This "
+"means your add-on is not showing up on any portion of the site or update "
+"check service. You may come to this page to complete your add-on after it "
+"meets the criteria below for completion and transfer to the <span class="
+"\"status-1\">Sandbox</span>."
+
+#. %s is a number, perhaps 42.
+#: views/developers/addon_status.thtml:77
+#, fuzzy
+msgid "devcp_addon_status_switch_nominated"
+msgstr ""
+"Your add-on is currently nominated to become <span class=\"status-4"
+"\">Public</span> and is awaiting editor review. There are currently %s other "
+"add-ons in the nomination queue."
+
+#. %s is an email address.
+#: views/developers/addon_status.thtml:81
+#, fuzzy
+msgid "devcp_addon_status_switch_pending"
+msgstr ""
+"Your add-on is pending. This shouldn't have happened. Please e-mail %s with "
+"your add-on ID and state this error."
+
+#: views/developers/addon_status.thtml:85
+#, fuzzy
+msgid "devcp_addon_status_switch_public"
+msgstr ""
+"Your add-on is <span class=\"status-4\">Public</span>, which means it will "
+"show up in all listings and searches and can be downloaded without "
+"restriction. Updates are being provided to your add-on through the update "
+"check service."
+
+#: views/developers/addon_status.thtml:71
+#: views/developers/addon_status.thtml:75
+#, fuzzy
+msgid "devcp_addon_status_switch_sandbox"
+msgstr ""
+"Your add-on is in the <span class=\"status-1\">Sandbox</span>, which means "
+"it will show up in listings and searches, but users must log in to download "
+"it. Updates are <b>not</b> being provided to your add-on through the update "
+"check service."
+
+#. %s is the add-on name.
+#: views/developers/addon_status_nominate.thtml:43
+#: views/developers/addon_status_confirm.thtml:43
+#: views/developers/addon_status.thtml:43
+#, fuzzy
+msgid "devcp_addon_status_title"
+msgstr "%s Status"
+
+#: views/developers/addon_status.thtml:191
+#, fuzzy
+msgid "devcp_addon_status_trusted"
+msgstr ""
+"Your add-on is <span class=\"status-4\">Trusted</span>. This means you can "
+"submit updates to your add-on without editor review."
+
+#: views/developers/dashboard.thtml:68
+#, fuzzy
+msgid "devcp_dashboard_active"
+msgstr "Active"
+
+#. %1$s is the add-on type string
+#. %2$s is Inactive or Active in a <span>
+#. %3$s is the addon's public status (Public, In Sandbox, ...) in a <span>
+#: views/developers/dashboard.thtml:69
+#, fuzzy
+msgid "devcp_dashboard_addontype_status"
+msgstr "%1$s currenty %2$s and %3$s"
+
+#: views/developers/dashboard.thtml:67
+#, fuzzy
+msgid "devcp_dashboard_change_status"
+msgstr "Change Status"
+
+#. %s is the addons email address.
+#: views/developers/dashboard.thtml:99
+#, fuzzy
+msgid "devcp_dashboard_disabled_questions"
+msgstr ""
+"Your add-on was disabled by an administrator and cannot be used. If you "
+"have any questions, please email %s."
+
+#. %s is the (localized) add-on status string in a span, e.g. "Disabled"
+#: views/developers/dashboard.thtml:98
+#, fuzzy
+msgid "devcp_dashboard_disabled_status"
+msgstr "Add-on Status: %s"
+
+#: views/developers/dashboard.thtml:43
+#, fuzzy
+msgid "devcp_dashboard_header_main"
+msgstr "Developer Dashboard"
+
+#: views/developers/dashboard.thtml:110
+#, fuzzy
+msgid "devcp_dashboard_header_welcome"
+msgstr "Welcome to the Developer Dashboard"
+
+#: views/developers/dashboard.thtml:68
+#, fuzzy
+msgid "devcp_dashboard_inactive"
+msgstr "Inactive"
+
+#. %s is a date in the _('date') format
+#: views/developers/dashboard.thtml:65
+#, fuzzy
+msgid "devcp_dashboard_last_edited"
+msgstr "Last edited on %s"
+
+#: views/developers/dashboard.thtml:111
+#, fuzzy
+msgid "devcp_dashboard_learn"
+msgstr ""
+"You don't currently have any add-ons hosted on Mozilla Add-ons. To learn how "
+"the process works and submit your first add-on, click Get Started below."
+
+#: views/developers/dashboard.thtml:112
+#, fuzzy
+msgid "devcp_dashboard_start"
+msgstr "Get Started"
+
+#: views/developers/dashboard.thtml:82
+#, fuzzy
+msgid "devcp_dashboard_versions"
+msgstr "Versions and Files"
+
+#: views/developers/dashboard.thtml:91
+#, fuzzy
+msgid "devcp_dashboard_versions_new"
+msgstr "Upload a new version"
+
+#. %s is the preview ID number.
+#: controllers/developers_controller.php:1415
+#, fuzzy
+msgid "devcp_delete_previews_error"
+msgstr "Preview %s could not be deleted from the database. Please try again."
+
+#. %s is the preview ID number.
+#: controllers/developers_controller.php:1413
+#, fuzzy
+msgid "devcp_delete_previews_success"
+msgstr "Preview %s has been deleted successfully."
+
+#: controllers/developers_controller.php:1089
+#, fuzzy
+msgid "devcp_delete_version_priv_error"
+msgstr "You do not have privileges to delete versions or files."
+
+#. %1$s is the count of files, a number
+#. %2$s is a status string like _('Public') or _('Incomplete')
+#: controllers/components/amo.php:549
+#, fuzzy
+msgid "devcp_describe_version_status"
+msgid_plural "devcp_describe_version_status"
+msgstr[0] "%1$s %2$s file"
+msgstr[1] "%1$s %2$s files"
+
+#. %s is a version number. Example: 3.0
+#: views/developers/versions.thtml:65
+#, php-format
+msgid "devcp_details_version"
+msgstr "גירסה %s"
+
+#: views/developers/discuss.thtml:68
+#, fuzzy
+msgid "devcp_discuss_addreply_header"
+msgstr "Add Reply"
+
+#: views/developers/discuss.thtml:57
+#, fuzzy
+msgid "devcp_discuss_allreplies_header"
+msgstr "Replies"
+
+#. notice when an error occurs saving a discussion reply
+#. %1 is the email address (linked) for the amo-editors list
+#: views/developers/discuss.thtml:70
+#, fuzzy
+msgid "devcp_discuss_error_notice"
+msgstr ""
+"There was an error saving your reply. Please contact %1$s about the issue."
+
+#. %1 is the add-on name, %2 is the add-on's version number currently being reviewed by an editor
+#: views/developers/discuss.thtml:46
+#, fuzzy
+msgid "devcp_discuss_intro"
+msgstr ""
+"A Mozilla Add-ons Editor requested further information from you regarding "
+"version %2$s of your add-on %1$s."
+
+#. %1 is the add-on name
+#: views/developers/discuss.thtml:43
+#, fuzzy
+msgid "devcp_discuss_pagetitle"
+msgstr "Provide More Information For the Add-on Review of %1$s"
+
+#. submit button text
+#: views/developers/discuss.thtml:79
+#, fuzzy
+msgid "devcp_discuss_submit_reply"
+msgstr "Submit Reply"
+
+#: views/developers/discuss.thtml:72
+#, fuzzy
+msgid "devcp_discuss_success_message"
+msgstr ""
+"Your reply was successfully saved. The other participants of the discussion "
+"will be notified by email."
+
+#. in an author/editor discussion about an add-on to be reviewed:
+#. %1 is the commenter's user name (linked).
+#. %2 is the full date the comment was made.
+#: views/developers/discuss.thtml:52 views/developers/discuss.thtml:62
+#, fuzzy
+msgid "devcp_discuss_writtenby"
+msgstr "written by %1$s on %2$s"
+
+#: views/developers/addon_edit_authors.thtml:72
+#: views/developers/addon_edit_authors.thtml:81
+#, fuzzy
+msgid "devcp_edit_authors_add_author"
+msgstr "Add New Author"
+
+#: views/developers/addon_edit_authors.thtml:96
+#, fuzzy
+msgid "devcp_edit_authors_add_author_button"
+msgstr "Add Author"
+
+#: views/developers/addon_edit_authors.thtml:83
+#, fuzzy
+msgid "devcp_edit_authors_add_email"
+msgstr "Author Account Email:"
+
+#: views/developers/addon_edit_authors.thtml:98
+#, fuzzy
+msgid "devcp_edit_authors_add_loading"
+msgstr "Checking account email..."
+
+#: views/developers/addon_edit_authors.thtml:70
+#, fuzzy
+msgid "devcp_edit_authors_click_save"
+msgstr "Click the Update Authors button below to save."
+
+#: views/developers/addon_edit_authors.thtml:58
+#, fuzzy
+msgid "devcp_edit_authors_header_current"
+msgstr "Current Authors"
+
+#: views/developers/addon_edit_authors.thtml:50
+#, fuzzy
+msgid "devcp_edit_authors_header_manage"
+msgstr "Manage Add-on Authors"
+
+#: views/developers/addon_edit_authors.thtml:93
+#, fuzzy
+msgid "devcp_edit_authors_label_add_listed"
+msgstr "List as author in pubilc display pages"
+
+#: views/developers/addon_edit_authors.thtml:89
+#, fuzzy
+msgid "devcp_edit_authors_label_developer"
+msgstr ""
+"<strong>Developer</strong> - Can manage all aspects of the add-on listing, "
+"except for adding and removing other authors."
+
+#: views/developers/addon_edit_authors.thtml:88
+#, fuzzy
+msgid "devcp_edit_authors_label_owner"
+msgstr ""
+"<strong>Owner</strong> - Can manage all aspects of the add-on listing, "
+"including adding and removing other authors."
+
+#: views/developers/addon_edit_authors.thtml:90
+#, fuzzy
+msgid "devcp_edit_authors_label_viewer"
+msgstr ""
+"<strong>Viewer</strong> - Can view add-on developer listing and statistics, "
+"but can't make any changes."
+
+#. Placeholder for the empty option in a <select>.
+#: views/developers/addon_edit_categories.thtml:69
+#, fuzzy
+msgid "devcp_edit_authors_option_empty"
+msgstr "----------------"
+
+#: views/developers/addon_edit_authors.thtml:86
+#, fuzzy
+msgid "devcp_edit_authors_select_role"
+msgstr "Select a role for the author:"
+
+#. Column name in a table.
+#: views/developers/addon_edit_authors.thtml:62
+#, fuzzy
+msgid "devcp_edit_authors_th_author"
+msgstr "Author"
+
+#. Column name in a table.
+#: views/developers/addon_edit_authors.thtml:64
+#, fuzzy
+msgid "devcp_edit_authors_th_listed"
+msgstr "Listed"
+
+#. Column name in a table.
+#: views/developers/addon_edit_authors.thtml:63
+#, fuzzy
+msgid "devcp_edit_authors_th_role"
+msgstr "Role"
+
+#: views/developers/addon_edit_authors.thtml:77
+#, fuzzy
+msgid "devcp_edit_authors_update_author"
+msgstr "Update authors"
+
+#: views/developers/addon_edit_categories.thtml:99
+#, fuzzy
+msgid "devcp_edit_categories_button_update"
+msgstr "Update Categories"
+
+#: views/developers/addon_edit_categories.thtml:88
+#, fuzzy
+msgid "devcp_edit_categories_does_not_fit"
+msgstr "My add-on doesn't fit into any available categories."
+
+#. %s is the application name (Firefox, Thunderbird).
+#: views/developers/addon_edit_categories.thtml:61
+#, fuzzy
+msgid "devcp_edit_categories_header_application"
+msgstr "%s Categories"
+
+#: views/developers/addon_edit_categories.thtml:49
+#, fuzzy
+msgid "devcp_edit_categories_header_manage"
+msgstr "Manage Add-on Categories"
+
+#: views/developers/addon_edit_categories.thtml:91
+#, fuzzy
+msgid "devcp_edit_categories_hover"
+msgstr "Hover over a category to see its description."
+
+#. %s is the category number (1, 2, 3).
+#: views/developers/addon_edit_categories.thtml:67
+#, fuzzy
+msgid "devcp_edit_categories_label_category_num"
+msgstr "Category %s"
+
+#: views/developers/addon_edit_categories.thtml:94
+#: views/developers/addon_edit_categories.thtml:103
+#, fuzzy
+msgid "devcp_edit_categories_none_available"
+msgstr "No categories are available for this add-on type and application."
+
+#: views/developers/addon_edit_categories.thtml:86
+#, fuzzy
+msgid "devcp_edit_categories_other"
+msgstr ""
+"Place your add-on into this category only if it does not fit into any other "
+"available categories."
+
+#. %s is the application name (Firefox, Thunderbird).
+#: views/developers/addon_edit_categories.thtml:63
+#, fuzzy
+msgid "devcp_edit_categories_select_application_categories"
+msgstr "Select up to three %s categories for your add-on"
+
+#: views/developers/addon_edit.thtml:47
+#, fuzzy
+msgid "devcp_edit_dd_manage_authors"
+msgstr "Add or remove users that can manage this add-on."
+
+#: views/developers/addon_edit.thtml:49
+#, fuzzy
+msgid "devcp_edit_dd_manage_categories"
+msgstr ""
+"Select the relevant categories for each application your add-on supports."
+
+#: views/developers/addon_edit.thtml:51
+#, fuzzy
+msgid "devcp_edit_dd_manage_description"
+msgstr ""
+"Add and modify translations for your add-on's summary, description, end-user "
+"license, and privacy policy."
+
+#: views/developers/addon_edit.thtml:53
+#, fuzzy
+msgid "devcp_edit_dd_manage_properties"
+msgstr "Change your add-on's name, homepage, icon, and other flags."
+
+#: views/developers/addon_edit_descriptions.thtml:116
+#, fuzzy
+msgid "devcp_edit_description_button_update"
+msgstr "Update Descriptions"
+
+#: views/developers/addon_edit_descriptions.thtml:115
+#, fuzzy
+msgid "devcp_edit_description_correct_error"
+msgstr "Please correct the errors above indicated in red."
+
+#: views/developers/addon_edit_descriptions.thtml:51
+#, fuzzy
+msgid "devcp_edit_descriptions_header"
+msgstr "Edit Add-on Descriptions"
+
+#: views/developers/addon_edit_descriptions.thtml:94
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_comments_description"
+msgstr ""
+"Any information end users may want to know that isn't necessarily applicable "
+"to the add-on summary or description. Common uses include listing known "
+"major bugs, information on how to report bugs, anticipated release date of a "
+"new version, etc."
+
+#: views/developers/addon_edit_descriptions.thtml:93
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_comments_name"
+msgstr "Developer Comments"
+
+#: views/developers/addon_edit_descriptions.thtml:86
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_description_description"
+msgstr ""
+"The description of your add-on is a longer explanation of features, "
+"functionality, and other relevant information. It is displayed under the "
+"summary on the add-on's display page."
+
+#: views/developers/addon_edit_descriptions.thtml:85
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_description_name"
+msgstr "Add-on Description"
+
+#: views/developers/addon_edit_descriptions.thtml:103
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_eula_description"
+msgstr ""
+"If your add-on has an End-User License Agreement (EULA), please enter its "
+"text below. If set below, users will be required to agree to this before "
+"installing your add-on. Please note that a EULA is not the same as a code "
+"license such as GPL or MPL."
+
+#: views/developers/addon_edit_descriptions.thtml:102
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_eula_name"
+msgstr "End-User License Agreement"
+
+#: views/developers/addon_edit_descriptions.thtml:112
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_privacy_description"
+msgstr ""
+"If your add-on has a privacy policy, enter its text here. Your add-on's "
+"display page will display a link to the policy."
+
+#: views/developers/addon_edit_descriptions.thtml:111
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_privacy_name"
+msgstr "Privacy Policy"
+
+#: views/developers/addon_edit_descriptions.thtml:78
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_summary_description"
+msgstr ""
+"The summary is a short explanation of your add-on's basic functionality that "
+"is displayed in search and browse listings, as well as at the top of your "
+"add-on's display page. <strong>Limit of 250 characters.</strong>"
+
+#: views/developers/addon_edit_descriptions.thtml:77
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_summary_name"
+msgstr "Add-on Summary"
+
+#: views/developers/addon_edit.thtml:46
+#, fuzzy
+msgid "devcp_edit_dt_manage_authors"
+msgstr "Manage Add-on Authors"
+
+#: views/developers/addon_edit.thtml:48
+#, fuzzy
+msgid "devcp_edit_dt_manage_categories"
+msgstr "Manage Add-on Categories"
+
+#: views/developers/addon_edit.thtml:50
+#, fuzzy
+msgid "devcp_edit_dt_manage_descriptions"
+msgstr "Manage Add-on Descriptions"
+
+#: views/developers/addon_edit.thtml:52
+#, fuzzy
+msgid "devcp_edit_dt_manage_properties"
+msgstr "Manage Add-on Properties"
+
+#: views/developers/addon_edit_properties.thtml:170
+msgid "devcp_edit_label_externalsoftware"
+msgstr "תוספת זו דורשת תוכנה חיצונית"
+
+#: views/developers/addon_edit_properties.thtml:205
+msgid "devcp_edit_label_locale_disambiguation"
+msgstr "מידע נוסף על השפה"
+
+#: views/developers/addon_edit_properties.thtml:168
+msgid "devcp_edit_label_prerelease"
+msgstr "×–×” ×§×“× ×©×—×¨×•×¨"
+
+#: views/developers/addon_edit_properties.thtml:169
+msgid "devcp_edit_label_sitespecific"
+msgstr "זו תוספת ל×תר מסויי×"
+
+#: views/developers/addon_edit_properties.thtml:202
+msgid "devcp_edit_label_target_locale"
+msgstr "שפת מטרה"
+
+#: views/developers/addon_edit_properties.thtml:212
+#, fuzzy
+msgid "devcp_edit_properties_button_update"
+msgstr "Update Properties"
+
+#: views/developers/addon_edit_properties.thtml:198
+#, fuzzy
+msgid "devcp_edit_properties_change_guid"
+msgstr "Only change if you understand all of the consequences."
+
+#: views/developers/addon_edit_properties.thtml:109
+#, fuzzy
+msgid "devcp_edit_properties_current_icon"
+msgstr "Current Icon"
+
+#: views/developers/addon_edit_properties.thtml:85
+#, fuzzy
+msgid "devcp_edit_properties_default_locale"
+msgstr ""
+"An add-on's default locale is the main locale in which translations must be "
+"present. If translations for your add-on's descriptions are unavailable in a "
+"user's selected language, they will fall back to this default locale."
+
+#: views/developers/addon_edit_properties.thtml:167
+#, fuzzy
+msgid "devcp_edit_properties_flags"
+msgstr "These flags are used to filter and classify add-ons."
+
+#: views/developers/addon_edit_properties.thtml:174
+#, fuzzy
+msgid "devcp_edit_properties_guid"
+msgstr ""
+"The GUID of your add-on is specified in its install.rdf and uniquely "
+"identifies it. You cannot change your GUID once it is listed on Mozilla Add-"
+"ons."
+
+#: views/developers/addon_edit_properties.thtml:53
+#, fuzzy
+msgid "devcp_edit_properties_header"
+msgstr "Edit Add-on Properties"
+
+#: views/developers/addon_edit_properties.thtml:186
+#, fuzzy
+msgid "devcp_edit_properties_header_addon_type"
+msgstr "Add-on Type"
+
+#: views/developers/addon_edit_properties.thtml:181
+#, fuzzy
+msgid "devcp_edit_properties_header_admin_settings"
+msgstr "Admin Settings"
+
+#: views/developers/addon_edit_properties.thtml:84
+#, fuzzy
+msgid "devcp_edit_properties_header_default_locale"
+msgstr "Default Locale"
+
+#: views/developers/addon_edit_properties.thtml:166
+#, fuzzy
+msgid "devcp_edit_properties_header_flags"
+msgstr "Add-on Flags"
+
+#: views/developers/addon_edit_properties.thtml:173
+#: views/developers/addon_edit_properties.thtml:197
+#, fuzzy
+msgid "devcp_edit_properties_header_guid"
+msgstr "Add-on GUID"
+
+#: views/developers/addon_edit_properties.thtml:104
+#, fuzzy
+msgid "devcp_edit_properties_header_icon"
+msgstr "Add-on Icon"
+
+#: views/developers/addon_edit_properties.thtml:159
+#, fuzzy
+msgid "devcp_edit_properties_header_other_settings"
+msgstr "Other Settings"
+
+#. A header on the admin page to toggle trusted status.
+#: views/developers/addon_edit_properties.thtml:182
+#, fuzzy
+msgid "devcp_edit_properties_header_trusted"
+msgstr "Trusted Add-on?"
+
+#: views/developers/addon_edit_properties.thtml:160
+#, fuzzy
+msgid "devcp_edit_properties_header_view_source"
+msgstr "View Source Online"
+
+#. %s is a comma-separated list of image extensions ".png, .jpg"
+#: views/developers/addon_edit_properties.thtml:106
+#, fuzzy
+msgid "devcp_edit_properties_icon"
+msgstr ""
+"The add-on icon is a small image that is displayed next to your add-on's "
+"name in browse and search results, display pages, and in the add-on "
+"installation dialog. The image will automatically be resized to 32 x 32 "
+"pixels. Please use one of the following image types: %s"
+
+#: views/developers/addon_edit_properties.thtml:171
+#, fuzzy
+msgid "devcp_edit_properties_label_binary"
+msgstr "This add-on contains binary components"
+
+#: views/developers/addon_edit_properties.thtml:185
+#, fuzzy
+msgid "devcp_edit_properties_label_not_trusted"
+msgstr "Not Trusted"
+
+#: views/developers/addon_edit_properties.thtml:184
+#, fuzzy
+msgid "devcp_edit_properties_label_trusted"
+msgstr "Trusted"
+
+#: views/developers/addon_edit_properties.thtml:110
+#, fuzzy
+msgid "devcp_edit_properties_new_icon"
+msgstr "New Icon"
+
+#: views/developers/addon_edit_properties.thtml:118
+#, fuzzy
+msgid "devcp_edit_properties_remove_icon"
+msgstr "Remove Icon"
+
+#: views/developers/addon_edit_properties.thtml:136
+#, fuzzy
+msgid "devcp_edit_properties_transbox_homepage_description"
+msgstr ""
+"If your add-on has another homepage, enter its address here. Adding other "
+"translations is not necessary unless your website is localized into other "
+"languages."
+
+#: views/developers/addon_edit_properties.thtml:135
+#, fuzzy
+msgid "devcp_edit_properties_transbox_homepage_name"
+msgstr "Add-on Homepage"
+
+#: views/developers/addon_edit_properties.thtml:79
+#, fuzzy
+msgid "devcp_edit_properties_transbox_name_description"
+msgstr "The name of your add-on is displayed everywhere your add-on is listed."
+
+#: views/developers/addon_edit_properties.thtml:78
+#, fuzzy
+msgid "devcp_edit_properties_transbox_name_name"
+msgstr "Add-on Name"
+
+#: views/developers/addon_edit_properties.thtml:145
+#, fuzzy
+msgid "devcp_edit_properties_transbox_supportemail_description"
+msgstr ""
+"If you have an email address for support inquiries, enter it here. Adding "
+"other translations is not necessary unless you have different email "
+"addresses for different languages."
+
+#: views/developers/addon_edit_properties.thtml:144
+#, fuzzy
+msgid "devcp_edit_properties_transbox_supportemail_name"
+msgstr "Support Email Address"
+
+#: views/developers/addon_edit_properties.thtml:154
+#, fuzzy
+msgid "devcp_edit_properties_transbox_supporturl_description"
+msgstr ""
+"If your add-on has a support website or forum, enter its address here. "
+"Adding other translations is not necessary unless your website is localized "
+"into other languages."
+
+#: views/developers/addon_edit_properties.thtml:153
+#, fuzzy
+msgid "devcp_edit_properties_transbox_supporturl_name"
+msgstr "Support Website"
+
+#: views/developers/addon_edit_properties.thtml:183
+#, fuzzy
+msgid "devcp_edit_properties_trusted"
+msgstr "Trusted add-ons can become public without Editor review."
+
+#. %s is href="..." and should stay in the <a> tag.
+#: views/developers/addon_edit_properties.thtml:119
+#, fuzzy
+msgid "devcp_edit_properties_undelete"
+msgstr "Icon will be deleted on save. <a %s>Cancel?</a>"
+
+#: views/developers/addon_edit_properties.thtml:161
+#, fuzzy
+msgid "devcp_edit_properties_view_source"
+msgstr ""
+"The source of your add-on files can be viewed online by any logged in user "
+"if you wish."
+
+#: views/developers/addon_edit_properties.thtml:162
+#, fuzzy
+msgid "devcp_edit_properties_view_source_allow"
+msgstr "Allow online source viewing"
+
+#: views/developers/addon_edit_properties.thtml:163
+#, fuzzy
+msgid "devcp_edit_properties_view_source_do_not_allow"
+msgstr "Do not allow online source viewing"
+
+#: views/elements/developers/editbox.thtml:46
+#, fuzzy
+msgid "devcp_editbox_authors"
+msgstr "Authors"
+
+#: views/elements/developers/editbox.thtml:47
+#, fuzzy
+msgid "devcp_editbox_categories"
+msgstr "Categories"
+
+#: views/elements/developers/editbox.thtml:52
+#, fuzzy
+msgid "devcp_editbox_change_status"
+msgstr "Change Status"
+
+#: views/elements/developers/editbox.thtml:48
+#, fuzzy
+msgid "devcp_editbox_descriptions"
+msgstr "Descriptions"
+
+#: views/elements/developers/editbox.thtml:43
+#, fuzzy
+msgid "devcp_editbox_edit_addon"
+msgstr "Edit Add-on"
+
+#: views/elements/developers/editbox.thtml:57
+#, fuzzy
+msgid "devcp_editbox_new_version"
+msgstr "New Version"
+
+#: views/elements/developers/editbox.thtml:49
+#, fuzzy
+msgid "devcp_editbox_properties"
+msgstr "Properties"
+
+#: views/elements/developers/editbox.thtml:60
+#, fuzzy
+msgid "devcp_editbox_screenshots"
+msgstr "Preview Screenshots"
+
+#: views/elements/developers/editbox.thtml:53
+#, fuzzy
+msgid "devcp_editbox_statistics_dashboard"
+msgstr "Statistics Dashboard"
+
+#: views/elements/developers/editbox.thtml:54
+#, fuzzy
+msgid "devcp_editbox_versions"
+msgstr "Versions and Files"
+
+#: views/elements/developers/editbox.thtml:42
+#, fuzzy
+msgid "devcp_editbox_view_listing"
+msgstr "View Listing"
+
+#: views/elements/developers/editorsmenu.thtml:59
+msgid "devcp_editorsqueue_featured"
+msgstr "×יפיון תוספות"
+
+#. %1 is the review count
+#: views/elements/developers/editorsqueue.thtml:42
+#: views/elements/developers/editorsmenu.thtml:56
+#, php-format
+msgid "devcp_editorsqueue_moderatedreviews"
+msgid_plural "devcp_editorsqueue_moderatedreviews"
+msgstr[0] "סקירות מרוסנות (%s)"
+msgstr[1] "סקירות מרוסנות (%s)"
+
+#. %1 is the nominated addons count
+#: views/elements/developers/editorsqueue.thtml:44
+#: views/elements/developers/editorsmenu.thtml:58
+#, php-format
+msgid "devcp_editorsqueue_nominated"
+msgid_plural "devcp_editorsqueue_nominated"
+msgstr[0] "תוספות שהוגשו (%s)"
+msgstr[1] "תוספות שהוגשו (%s)"
+
+#. %1 is the update count
+#: views/elements/developers/editorsqueue.thtml:43
+#: views/elements/developers/editorsmenu.thtml:57
+#, php-format
+msgid "devcp_editorsqueue_pendingupdates"
+msgid_plural "devcp_editorsqueue_pendingupdates"
+msgstr[0] "×¢×“×›×•× ×™× ×ž×ž×ª×™× ×™× (%s)"
+msgstr[1] "×¢×“×›×•× ×™× ×ž×ž×ª×™× ×™× (%s)"
+
+#: controllers/statistics_controller.php:147
+#: controllers/statistics_controller.php:361
+#: controllers/previews_controller.php:108
+#: controllers/previews_controller.php:211
+#: controllers/previews_controller.php:312
+msgid "devcp_error_addon_access_denied"
+msgstr "×ין לך גישה לתוספת ×”×–×ת."
+
+#. %s is a complete URL with the text from devcp_error_appversion_reference_link_text
+#. in the <a> tag. This should be fixed.
+#: controllers/components/developers.php:591
+#, php-format
+msgid "devcp_error_appversion_reference_link"
+msgstr "ר××” בבקשה %s לפירוט."
+
+#. This is the link text in the <a> for devcp_error_appversion_reference_link. This
+#. should be fixed.
+#: controllers/components/developers.php:591
+msgid "devcp_error_appversion_reference_link_text"
+msgstr "עמוד זה"
+
+#: views/developers/addon_edit_authors.thtml:76
+#, fuzzy
+msgid "devcp_error_empty_authors"
+msgstr "Your add-on must have at least one owner."
+
+#. %1$s is the name of the file
+#: controllers/components/developers.php:658
+#, fuzzy
+msgid "devcp_error_file_exists"
+msgstr ""
+"A version of that addon already exists. To replace it, you must delete the "
+"file %1$s first."
+
+#. %1$s is a file extension. Example: .exe
+#. %2$s is a comma separated list of extensions. Example: .xpi, .jar
+#: controllers/components/developers.php:355
+#, php-format
+msgid "devcp_error_file_extension"
+msgstr ""
+"קובץ ההרחבה ×”×–×” (%s) ×ינו מורשה עבור סוג התוספת שנבחר. השתמש בבקשה ב×חד "
+"מהב××™×: %s"
+
+#: controllers/components/developers.php:64
+msgid "devcp_error_five_categories"
+msgstr "בחר בבקשה ×œ× ×™×•×ª×¨ מחמש קטגוריות."
+
+#: controllers/components/developers.php:526
+msgid "devcp_error_guid_application"
+msgstr "הזהות של התוספת הזו כבר משתמשת ביישו×."
+
+#: controllers/components/developers.php:337
+#: controllers/components/developers.php:389
+msgid "devcp_error_http_incomplete"
+msgstr "העברה פגומה"
+
+#: controllers/components/developers.php:335
+#: controllers/components/developers.php:336
+#: controllers/components/developers.php:387
+#: controllers/components/developers.php:388
+msgid "devcp_error_http_maxupload"
+msgstr "חריגה מגודל ההעל××” המרבי"
+
+#: controllers/components/developers.php:338
+#: controllers/components/developers.php:390
+msgid "devcp_error_http_nofile"
+msgstr "×œ× ×”×•×¢×œ×” קובץ"
+
+#. %1$s is a file extension. Example: .exe
+#. %2$s is a comma separated list of extensions. Example: .xpi, .jar
+#: controllers/components/developers.php:401
+#, php-format
+msgid "devcp_error_icon_extension"
+msgstr ""
+"קובץ ההרחבה ×”×–×” (%s) ×ינו מורשה עבור הצלמית. השתמש בבקשה ב×חד מהב××™×: %s"
+
+#: controllers/developers_controller.php:504
+msgid "devcp_error_index_rdf_notfound"
+msgstr "×ין נוכחות install.rdf."
+
+#: controllers/components/developers.php:601
+msgid "devcp_error_install_manifest"
+msgstr "השגי×ות הב×ות נמצ×ו ב- install.rdf:"
+
+#: controllers/developers_controller.php:1463
+msgid "devcp_error_invalid_addontype"
+msgstr "בחר בבקשה סוג תוספת חוקי."
+
+#. %$1s is a version. Example: 3.1.1
+#. %$2s is an add-on name.
+#: controllers/components/developers.php:569
+#: controllers/components/developers.php:581
+#, php-format
+msgid "devcp_error_invalid_appversion"
+msgstr "%s ×”×™× ×œ× ×’×™×¨×¡×” חוקית עבור %s"
+
+#. %s is a string
+#: controllers/components/developers.php:521
+#, php-format
+msgid "devcp_error_invalid_guid"
+msgstr "הזהות של התוספת ×œ× ×—×•×§×™×ª: %s"
+
+#. %$1s is a version. Example: 3.1.1
+#. %$2s is an add-on name.
+#: controllers/components/developers.php:572
+#, php-format
+msgid "devcp_error_invalid_minversion"
+msgstr "%s ××™× ×” גירסה חוקית עבור %s: גירס×ות ×ž×™× ×™×ž×•× ×ינן יכולות להכיל *"
+
+#: controllers/components/developers.php:536
+msgid "devcp_error_invalid_version"
+msgstr ""
+"גירסת התוספת הזו ××™× ×” חוקית: ר××” בבקשה <a href=\"http://developer.mozilla."
+"org/en/docs/Toolkit_version_format\">מפרט</a>"
+
+#: controllers/components/developers.php:531
+msgid "devcp_error_invalid_version_spaces"
+msgstr "גירסת התוספת הזו ××™× ×” חוקית: גירס×ות ×ינן יכולות להכיל רווחי×s."
+
+#. %s is an error message from the parser.
+#: controllers/components/developers.php:501
+#, php-format
+msgid "devcp_error_manifest_parse"
+msgstr "השגי××” הב××” התרחשה כשנותח install.rdf: %s"
+
+#: controllers/components/developers.php:373
+msgid "devcp_error_move_file"
+msgstr "×œ× × ×™×ª×Ÿ להעביר קובץ"
+
+#. %s is the name of a file
+#: controllers/components/developers.php:650
+#: controllers/components/developers.php:662
+#: controllers/components/developers.php:667
+#: controllers/components/developers.php:727
+#: controllers/components/developers.php:738
+#: controllers/components/developers.php:743
+#, php-format
+msgid "devcp_error_moving_file"
+msgstr "התרחשה שגי××” בהעברה ×ל %s."
+
+#: controllers/components/developers.php:595
+msgid "devcp_error_mozilla_application"
+msgstr "×תה צריך להש×יר לפחות ×™×™×©×•× ×ž×˜×¨×” חוקי ×חד."
+
+#: controllers/components/developers.php:516
+msgid "devcp_error_no_guid"
+msgstr "×œ× × ×ž×¦××” זהות עבור תוספת זו ב-install.rdf."
+
+#: controllers/components/developers.php:287
+msgid "devcp_error_no_platform"
+msgstr "×œ× × ×‘×—×¨×” פלטפורמה"
+
+#: controllers/components/developers.php:59
+msgid "devcp_error_one_category"
+msgstr "בחר בבקשה לפחות קטגוריה ×חת."
+
+#: controllers/components/developers.php:92
+msgid "devcp_error_one_user"
+msgstr "חייב להיות לפחות מחבר ×חד לתוספת ×”×–×ת."
+
+#. %1$s is a file extension. Example: .exe
+#. %2$s is a comma separated list of extensions. Example: .xpi, .jar
+#: controllers/components/developers.php:1081
+#, php-format
+msgid "devcp_error_preview_extension"
+msgstr ""
+"קובץ ההרחבה ×”×–×” (%s) ×ינו מורשה לתצוגה מקדימה. בבקשה השתמש ב×חד מהב××™×: %s"
+
+#: controllers/components/developers.php:511
+msgid "devcp_error_updatekey"
+msgstr ""
+"תוספות ×œ× ×™×›×•×œ×•×ª להשתמש במפתח עדכון. הסר ×ותו בבקשה מקובץ install.rdf ונסה "
+"שוב."
+
+#: controllers/components/developers.php:506
+msgid "devcp_error_updateurl"
+msgstr ""
+"תוספת ×œ× ×™×›×•×œ×” להשתמש בכתובת עדכון חיצונית. בבקשה הסר ×–×ת מ-install.rdf ונסה "
+"שוב."
+
+#: controllers/developers_controller.php:465
+#: controllers/components/developers.php:271
+msgid "devcp_error_upload_file"
+msgstr "העלה קובץ בבקשה."
+
+#: views/developers/uploader.thtml:135
+#, fuzzy
+msgid "devcp_input_upload_file"
+msgstr "Upload File"
+
+#: views/pages/js_constants.js.thtml:89
+#, fuzzy
+msgid "devcp_js_a_cancel"
+msgstr "Cancel"
+
+#: views/pages/js_constants.js.thtml:90
+#, fuzzy
+msgid "devcp_js_add_email"
+msgstr "Please enter the account email of the author you wish to add."
+
+#. alt text for a down-arrow image.
+#: views/pages/js_constants.js.thtml:81
+#, fuzzy
+msgid "devcp_js_img_move_down"
+msgstr "Move Down"
+
+#. alt text for an up-arrow image.
+#: views/pages/js_constants.js.thtml:82
+#, fuzzy
+msgid "devcp_js_img_move_up"
+msgstr "Move Up"
+
+#: views/pages/js_constants.js.thtml:91
+#, fuzzy
+msgid "devcp_js_img_remove_compat"
+msgstr "Remove Application Compatibility"
+
+#: views/pages/js_constants.js.thtml:86
+#, fuzzy
+msgid "devcp_js_input_list_author"
+msgstr "List as author in public listings"
+
+#: views/pages/js_constants.js.thtml:92
+#, fuzzy
+msgid "devcp_js_license_select"
+msgstr "Please select a license."
+
+#: views/pages/js_constants.js.thtml:93
+#, fuzzy
+msgid "devcp_js_license_text"
+msgstr "Please enter text for your license."
+
+#. <option> text in a <select> for Author role in an add-on.
+#: views/pages/js_constants.js.thtml:84
+#, fuzzy
+msgid "devcp_js_option_developer"
+msgstr "Developer"
+
+#. <option> text in a <select> for Author role in an add-on.
+#: views/pages/js_constants.js.thtml:83
+#, fuzzy
+msgid "devcp_js_option_owner"
+msgstr "Owner"
+
+#. <option> text in a <select> for Author role in an add-on.
+#: views/pages/js_constants.js.thtml:85
+#, fuzzy
+msgid "devcp_js_option_viewer"
+msgstr "Viewer"
+
+#: views/pages/js_constants.js.thtml:88
+#, fuzzy
+msgid "devcp_js_remove_author"
+msgstr "Remove Author"
+
+#: views/pages/js_constants.js.thtml:87
+#, fuzzy
+msgid "devcp_js_sure_remove"
+msgstr "Are you <strong>sure</strong> you wish to remove this author?"
+
+#: views/pages/js_constants.js.thtml:77
+#, fuzzy
+msgid "devcp_js_upload_alert"
+msgstr "You must select a file to upload."
+
+#. %1$s is an addon id, like 32.
+#. %2$s is a version number, like 3.5.
+#: controllers/components/developers.php:1212
+#, fuzzy
+msgid "devcp_license_existing"
+msgstr "Custom license for add-on %1$s v%2$s"
+
+#: views/elements/developers/localebox.thtml:44
+msgid "devcp_localebox_header_localizedfields"
+msgstr "שדות מות×מי שפה"
+
+#. %1 is the default locale
+#: views/elements/developers/localebox.thtml:48
+#, php-format
+msgid "devcp_localebox_intro"
+msgstr ""
+"כמה מהשדות בעמוד ×”×–×” מות××ž×™× ×œ×”×•×¤×™×¢ בשפת ×”×× ×©×œ משתמש הקצה. בחר שפה מלמטה "
+"כדי לערוך ×ת פרטי התוספת שלך ב×ותה שפה. ×× ×”×ª×¨×’×•× ×œ×©×¤×” ×”×–×ת ×ינו זמין, תוחזר "
+"לבחור ×ת שפת ברירת המחדל (%s)."
+
+#: views/elements/developers/sidebar.thtml:68
+#: views/elements/developers/myaddons.thtml:75
+msgid "devcp_myaddons_admincp_link"
+msgstr "לוח בקרה למנהל"
+
+#: views/elements/developers/sidebar.thtml:65
+#: views/elements/developers/myaddons.thtml:72
+msgid "devcp_myaddons_editorcp_link"
+msgstr "לוח בקרה לעורך"
+
+#: views/elements/developers/myaddons.thtml:52
+msgid "devcp_myaddons_link"
+msgstr "התוספות שלי"
+
+#: views/elements/developers/sidebar.thtml:70
+#: views/elements/developers/myaddons.thtml:77
+msgid "devcp_myaddons_mainpage_link"
+msgstr "חזרה לר×שי"
+
+#: views/elements/developers/sidebar.thtml:63
+#: views/elements/developers/myaddons.thtml:70
+msgid "devcp_myaddons_statistics_link"
+msgstr "לוח סטיסטיקות"
+
+#: views/elements/developers/sidebar.thtml:62
+#: views/elements/developers/myaddons.thtml:69
+msgid "devcp_myaddons_submitaddon_link"
+msgstr "שלח תוספת"
+
+#: views/elements/developers/sidebar.thtml:48
+#: views/elements/developers/myaddons.thtml:67
+msgid "devcp_myaddons_title"
+msgstr "כלי מפתח"
+
+#. %1$s is an add-on ID, perhaps 167.
+#. %2$s is a URL.
+#: controllers/developers_controller.php:256
+#, fuzzy
+msgid "devcp_new_addon_error"
+msgstr ""
+"This add-on ID (%1$s) already exists in the database. If this is your add-"
+"on, you can <a href=\"%2$s\">upload a new version</a>."
+
+#: views/developers/addon_status_nominate.thtml:62
+#, fuzzy
+msgid "devcp_nominate_cancel"
+msgstr "Cancel and return"
+
+#. %1 is the add-on name
+#: views/developers/addon_status_nominate.thtml:61
+#, php-format
+msgid "devcp_nominate_submit_nominate"
+msgstr "הגשת %s"
+
+#: views/developers/addon_edit_properties.thtml:50
+#: views/developers/addon_status.thtml:49
+#: views/developers/versions_edit.thtml:50
+#, fuzzy
+msgid "devcp_notice_changes_error"
+msgstr ""
+"<span>One or more of your changes couldn't be saved.</span><br />Please look "
+"for the errors below. The rest of your changes were successfully saved."
+
+#: views/developers/addon_edit_authors.thtml:47
+#: views/developers/addon_edit_properties.thtml:47
+#: views/developers/addon_status.thtml:46
+#: views/developers/addon_edit_descriptions.thtml:47
+#: views/developers/versions_edit.thtml:47
+#: views/developers/addon_edit_categories.thtml:46
+#, fuzzy
+msgid "devcp_notice_changes_saved"
+msgstr ""
+"<span>Your changes have been saved.</span><br />Please note that some "
+"changes may take several hours to appear in all areas of the website."
+
+#: controllers/previews_controller.php:252
+msgid "devcp_notice_cleardefault"
+msgstr ""
+"תצוגה זו ××™× ×” ברירת המחדל מפני שתצוגה מקדימה ×חרת נבחרה ×וטומטית להיות ברירת "
+"המחדל."
+
+#: controllers/previews_controller.php:184
+#: controllers/previews_controller.php:251
+msgid "devcp_notice_makedefault"
+msgstr ""
+"הפיכת התצוגה הזו לברירת המחדל תסיר ×ת מצב ברירת המחדל מתצוגת ברירת המחדל "
+"הנוכחית."
+
+#: views/developers/addon_edit_authors.thtml:70
+#, fuzzy
+msgid "devcp_notice_unsaved_changes"
+msgstr "You have unsaved changes."
+
+#: controllers/developers_controller.php:87
+#: controllers/developers_controller.php:97
+#: controllers/developers_controller.php:100
+#: controllers/previews_controller.php:67
+#: controllers/previews_controller.php:79
+#: controllers/previews_controller.php:82
+msgid "devcp_pagetitle"
+msgstr "לוח בקרה למפתח"
+
+#: controllers/previews_controller.php:103
+#: controllers/previews_controller.php:104
+msgid "devcp_preview_add_pagetitle"
+msgstr "הוספת תצוגה מקדימה"
+
+#: controllers/previews_controller.php:135
+msgid "devcp_preview_added_successfully"
+msgstr "תצוגה מקדימה נוספה בהצלחה."
+
+#: controllers/previews_controller.php:323
+msgid "devcp_preview_deleted_successfully"
+msgstr "תצוגה מקדימה נמחקה בהצלחה"
+
+#: controllers/previews_controller.php:194
+#: controllers/previews_controller.php:195
+msgid "devcp_preview_edit_pagetitle"
+msgstr "עריכת תצוגה מקדימה"
+
+#: controllers/previews_controller.php:237
+msgid "devcp_preview_updated_successfully"
+msgstr "תצוגה מקדימה עודכנה בהצלחה."
+
+#: views/developers/previews.thtml:120
+#, fuzzy
+msgid "devcp_previews_a_another"
+msgstr "Add Another Preview"
+
+#: views/developers/previews.thtml:96
+#, fuzzy
+msgid "devcp_previews_a_delete"
+msgstr "Delete Preview"
+
+#: views/developers/previews.thtml:95
+#, fuzzy
+msgid "devcp_previews_a_replace"
+msgstr "Replace Preview"
+
+#: views/developers/previews.thtml:126
+#, fuzzy
+msgid "devcp_previews_a_update"
+msgstr "Update Previews"
+
+#: views/developers/previews.thtml:115 views/developers/previews.thtml:124
+#, fuzzy
+msgid "devcp_previews_add_new"
+msgstr "Add New Preview"
+
+#. %s is a list of file extensions, e.g. ".png, .gif"
+#: views/developers/previews.thtml:116
+#, fuzzy
+msgid "devcp_previews_add_select"
+msgstr ""
+"Select an image to upload below. Images larger than the maximum size of 700 "
+"pixels wide by 525 pixels tall will be resized. Allowed file types: %s"
+
+#: views/developers/previews.thtml:121
+#, fuzzy
+msgid "devcp_previews_click_below"
+msgstr "Click Update Previews below to upload."
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/previews.thtml:102
+#, fuzzy
+msgid "devcp_previews_click_update"
+msgstr ""
+"Click the Update Previews button below to save this image. (<a %s>Cancel?</"
+"a>)"
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/previews.thtml:107
+#, fuzzy
+msgid "devcp_previews_error_message"
+msgstr ""
+"This preview will be deleted when Update Previews is clicked below. (<a %"
+"s>Cancel?</a>)"
+
+#: views/previews/add.thtml:45
+msgid "devcp_previews_filetype_info"
+msgstr ""
+"השתמש בטופס ×”×‘× ×›×“×™ להעלות תצלומי מסך (בתבנית PNG, JPG, ×ו GIF) של התוספת "
+"שלך. תמונות שגדולות יותר מרוחב של 700 ×¤×™×§×¡×œ×™× ×•×ž×’×•×‘×” שך 525 ×¤×™×§×¡×œ×™× ×™×•×§×˜× ×• "
+"×וטומטית."
+
+#: views/previews/add.thtml:43
+msgid "devcp_previews_header_add"
+msgstr "הוספת תצוגה מקדימה"
+
+#: views/developers/previews.thtml:80
+#, fuzzy
+msgid "devcp_previews_header_caption"
+msgstr "Preview Caption"
+
+#: views/previews/edit.thtml:43
+msgid "devcp_previews_header_edit"
+msgstr "ערוך תצוגה מקדימה"
+
+#: views/developers/previews.thtml:93
+#, fuzzy
+msgid "devcp_previews_label_default"
+msgstr "Default Preview"
+
+#: views/previews/add.thtml:54
+msgid "devcp_previews_label_file"
+msgstr "קובץ תצוגה מקדימה"
+
+#: views/previews/add.thtml:59 views/previews/edit.thtml:50
+msgid "devcp_previews_label_makedefault"
+msgstr "קבע ×ת ×–×” כברירת מחדל לתמונת תצוגה מקדימה."
+
+#: views/developers/previews.thtml:100
+#, fuzzy
+msgid "devcp_previews_label_new"
+msgstr "New image:"
+
+#: views/developers/previews.thtml:118
+#, fuzzy
+msgid "devcp_previews_label_upload"
+msgstr "Upload Preview: "
+
+#: views/developers/previews.thtml:50
+#, fuzzy
+msgid "devcp_previews_notice_error"
+msgstr "One or more of your new previews could not be saved."
+
+#: views/developers/previews.thtml:47
+#, fuzzy
+msgid "devcp_previews_notice_success"
+msgstr "Your previews have been updated successfully."
+
+#: views/developers/previews.thtml:59
+#, fuzzy
+msgid "devcp_previews_p_screenshots"
+msgstr ""
+"The preview screenshots for your add-on are shown below. You can make "
+"changes to captions or images below. The Default Preview is the preview that "
+"is displayed next to your add-on in search and browse listings."
+
+#: views/previews/edit.thtml:55
+msgid "devcp_previews_submit_delete"
+msgstr "מחק תצוגה מקדימה"
+
+#: views/previews/edit.thtml:55
+msgid "devcp_previews_submit_delete_confirm"
+msgstr "×”×× ×תה בטוח שברצונך למחוק תצוגה מקדימה זו?"
+
+#: views/previews/edit.thtml:54
+msgid "devcp_previews_submit_edit"
+msgstr "ערוך תצוגה מקדימה"
+
+#: views/previews/add.thtml:63
+msgid "devcp_previews_submit_upload"
+msgstr "העלה תצוגה מקדימה"
+
+#: views/developers/previews.thtml:78
+#, fuzzy
+msgid "devcp_previews_thumbnail"
+msgstr "Thumbnail"
+
+#. %s is the add-on name.
+#: views/developers/previews.thtml:44
+#, fuzzy
+msgid "devcp_previews_title"
+msgstr "%s Preview Manager"
+
+#: views/developers/uploader.thtml:74
+msgid "devcp_review_agreement_please"
+msgstr "בבקשה ×§×¨× ×•×שר ×ת ×”×¡×›× ×”×ž×¤×ª×— ×”×‘× ×œ×¤× ×™ שתמשיך."
+
+#: views/elements/developers/rolecheck.thtml:42
+#, fuzzy
+msgid "devcp_rolecheck_no_privs"
+msgstr ""
+"<span>You do not have sufficient privileges to make changes on this page.</"
+"span><br />Contact the Add-on Owner if you need to make changes."
+
+#: controllers/developers_controller.php:1315
+#, fuzzy
+msgid "devcp_several_hours"
+msgstr ""
+"Please note that some changes may take several hours to appear in all areas "
+"of the website."
+
+#: views/elements/developers/sidebar.thtml:52
+#, fuzzy
+msgid "devcp_sidebar_a_dashboard"
+msgstr "Dashboard"
+
+#. %s is a number
+#: views/elements/developers/statsbar.thtml:45
+#: views/developers/dashboard.thtml:79
+#, php-format
+msgid "devcp_statsbar_adu"
+msgstr "<em>%s</em> ×ž×©×ª×ž×©×™× ×¤×¢×™×œ×™× ×œ×™×•×"
+
+#. %s is a number
+#: views/elements/developers/statsbar.thtml:41
+#: views/developers/dashboard.thtml:75
+#, php-format
+msgid "devcp_statsbar_total_downloads"
+msgstr "<em>%s</em> סך ההורדות"
+
+#. %s is a number
+#: views/elements/developers/statsbar.thtml:43
+#: views/developers/dashboard.thtml:77
+#, php-format
+msgid "devcp_statsbar_weekly_downloads"
+msgstr "<em>%s</em> הורדות לשבוע"
+
+#: views/developers/addon_status_confirm.thtml:59
+#, fuzzy
+msgid "devcp_status_confirm_active"
+msgstr ""
+"Marking this add-on active will cause it to show up in public areas "
+"appropriate for its status, including search and browse listings. It will be "
+"downloadable from the website and could be returned in client update checks, "
+"depending on its status. You will be able to return here and disable it "
+"again at your convenience."
+
+#: views/developers/addon_status_confirm.thtml:59
+#, fuzzy
+msgid "devcp_status_confirm_active_sure"
+msgstr "Are you sure you wish to mark this add-on active?"
+
+#: views/developers/addon_status_confirm.thtml:50
+#, fuzzy
+msgid "devcp_status_confirm_header_sure"
+msgstr "Are you sure?"
+
+#: views/developers/addon_status_confirm.thtml:55
+#, fuzzy
+msgid "devcp_status_confirm_inactive"
+msgstr ""
+"Marking this add-on inactive will prevent it from showing up in any public "
+"areas, including search and browse listings. It will not be downloadable "
+"from the website and will not be returned in client update checks. You will "
+"be able to return here and re-enable it at your convenience."
+
+#: views/developers/addon_status_confirm.thtml:55
+#, fuzzy
+msgid "devcp_status_confirm_inactive_sure"
+msgstr "Are you sure you wish to mark this add-on inactive?'"
+
+#: views/developers/addon_status_confirm.thtml:74
+#, fuzzy
+msgid "devcp_status_confirm_no"
+msgstr "No, cancel"
+
+#: views/developers/addon_status_confirm.thtml:67
+#, fuzzy
+msgid "devcp_status_confirm_public"
+msgstr ""
+"Making this add-on public will make it available for anyone to download and "
+"will begin offering updates to existing users."
+
+#: views/developers/addon_status_confirm.thtml:67
+#, fuzzy
+msgid "devcp_status_confirm_public_sure"
+msgstr "Are you sure you wish to make this add-on public?"
+
+#: views/developers/addon_status_confirm.thtml:63
+#, fuzzy
+msgid "devcp_status_confirm_sandbox"
+msgstr ""
+"Moving this add-on back to the sandbox will require users to login before "
+"downloading and updates will no longer be offered to existing users. Because "
+"your add-on is currently public, you will be able to return here at any time "
+"to make it public again."
+
+#: views/developers/addon_status_confirm.thtml:63
+#, fuzzy
+msgid "devcp_status_confirm_sandbox_sure"
+msgstr "Are you sure you wish to move this add-on to the sandbox?"
+
+#: views/developers/addon_status_confirm.thtml:73
+#, fuzzy
+msgid "devcp_status_confirm_yes"
+msgstr "Yes, I'm Sure"
+
+#: views/developers/addon_status_nominate.thtml:46
+#, fuzzy
+msgid "devcp_status_nominate_error_notice"
+msgstr ""
+"<span>A nomination message is required.</span><br />Please fill in the text "
+"box with the requested information and try again."
+
+#: views/developers/addon_status_nominate.thtml:55
+#, fuzzy
+msgid "devcp_status_nominate_header"
+msgstr "Add-on Nomination"
+
+#: views/developers/dashboard.thtml:85
+msgid "devcp_summary_lastversion"
+msgstr "גירסה ×חרונה:"
+
+#. %s is the add-on name.
+#: views/developers/addon_edit.thtml:43
+#: views/developers/addon_edit_authors.thtml:44
+#: views/developers/versions_delete.thtml:43
+#: views/developers/addon_edit_properties.thtml:44
+#: views/developers/addon_edit_descriptions.thtml:44
+#: views/developers/versions_edit.thtml:44
+#: views/developers/addon_edit_categories.thtml:43
+#: views/developers/versions.thtml:43
+#, fuzzy
+msgid "devcp_title_edit_addon"
+msgstr "Edit %s"
+
+#. title attribute for a javascript link that pops up a help dialog.
+#: views/elements/translationbox.thtml:68
+#, fuzzy
+msgid "devcp_transbox_a_title_help"
+msgstr "Help (does not leave page)"
+
+#: views/elements/translationbox.thtml:68
+#, fuzzy
+msgid "devcp_transbox_alt_help"
+msgstr "Help"
+
+#. %1$s is <span>17</span>, %2$s is 42.
+#: views/elements/translationbox.thtml:101
+#, fuzzy
+msgid "devcp_transbox_chars_used"
+msgstr "Characters used: %1$s / %2$s"
+
+#: views/elements/translationbox.thtml:132
+#, fuzzy
+msgid "devcp_transbox_delete_sure"
+msgstr "Are you sure you wish to delete this translation?"
+
+#. %s is a locale, like en-US.
+#: views/elements/translationbox.thtml:143
+#, fuzzy
+msgid "devcp_transbox_help_header_tabs"
+msgstr "What are these %s tabs?"
+
+#: views/elements/translationbox.thtml:145
+#, fuzzy
+msgid "devcp_transbox_help_header_what"
+msgstr "What if I don't have any translations?"
+
+#: views/elements/translationbox.thtml:147
+#, fuzzy
+msgid "devcp_transbox_help_hide"
+msgstr "Hide Help"
+
+#: views/elements/translationbox.thtml:146
+#, fuzzy
+msgid "devcp_transbox_help_if"
+msgstr ""
+"If a user browses the site and a translation isn't available in their own "
+"language, it will fall back to your add-on's Default Locale, specified in "
+"the Edit Add-on Properties area. If you don't have any translations, just "
+"enter what you can into your Default Locale, which should be a language you "
+"speak."
+
+#: views/elements/translationbox.thtml:144
+#, fuzzy
+msgid "devcp_transbox_help_transbox"
+msgstr ""
+"This is a <i>Translation Box</i>. It allows you to localize a specific field "
+"into any other languages for which you might have a translation. You can "
+"add, edit, and remove translations using the locale tabs."
+
+#: views/elements/translationbox.thtml:85
+#, fuzzy
+msgid "devcp_transbox_img_add_trans"
+msgstr "Add Translation"
+
+#: views/elements/translationbox.thtml:86
+#, fuzzy
+msgid "devcp_transbox_img_remove_trans"
+msgstr "Remove Translation"
+
+#: views/elements/translationbox.thtml:123
+#, fuzzy
+msgid "devcp_transbox_input_add_all"
+msgstr "Add Locale to All"
+
+#: views/elements/translationbox.thtml:122
+#, fuzzy
+msgid "devcp_transbox_input_add_locale"
+msgstr "Add Locale"
+
+#: views/elements/translationbox.thtml:124
+#: views/elements/translationbox.thtml:135
+#, fuzzy
+msgid "devcp_transbox_input_cancel"
+msgstr "Cancel"
+
+#: views/elements/translationbox.thtml:134
+#, fuzzy
+msgid "devcp_transbox_input_delete"
+msgstr "Delete It"
+
+#: views/elements/translationbox.thtml:113
+#, fuzzy
+msgid "devcp_transbox_select_locale"
+msgstr "Select the locale of the translation to add:"
+
+#. %1$s and %2$s are GUIDs.
+#: controllers/developers_controller.php:343
+#, fuzzy
+msgid "devcp_update_addon_guid_error"
+msgstr ""
+"The add-on GUID used in this file (%1$s) does not match the existing GUID "
+"for this add-on (%2$s)."
+
+#: controllers/developers_controller.php:334
+#, fuzzy
+msgid "devcp_update_addon_priv_error"
+msgstr "You do not have sufficient privileges to update this add-on."
+
+#. %1$s is a version number, %2$s is an add-on ID.
+#: controllers/developers_controller.php:399
+#, fuzzy
+msgid "devcp_update_addon_version_belong_error"
+msgstr "The specified version (%1$s) does not belong to this add-on (%2$s)."
+
+#. %1$s is a version number, maybe 1.1.
+#. %2$s is a URL.
+#: controllers/developers_controller.php:351
+#, fuzzy
+msgid "devcp_update_addon_version_exists_error"
+msgstr ""
+"The version number uploaded (%1$s) already exists for this add-on. If you "
+"are trying to add another file to this version, <a href=\"%2$s\">click here</"
+"a>."
+
+#. %1$s and %2$s are version numbers.
+#: controllers/developers_controller.php:405
+#, fuzzy
+msgid "devcp_update_addon_version_match_error"
+msgstr ""
+"The uploaded version number (%1$s) does not match the existing version "
+"number (%2$s)."
+
+#: views/developers/uploader.thtml:68
+#, fuzzy
+msgid "devcp_uploader_a_start"
+msgstr "Get Started"
+
+#: views/developers/uploader.thtml:137
+#, fuzzy
+msgid "devcp_uploader_ajax_loading"
+msgstr "Uploading file..."
+
+#: views/developers/uploader.thtml:82
+#, fuzzy
+msgid "devcp_uploader_button_agree"
+msgstr "Agree and continue"
+
+#: views/developers/uploader.thtml:157
+#, fuzzy
+msgid "devcp_uploader_button_edit"
+msgstr "Edit My Add-on"
+
+#: views/developers/uploader.thtml:158
+#, fuzzy
+msgid "devcp_uploader_button_later"
+msgstr "I'll complete my add-on later."
+
+#: views/developers/uploader.thtml:168
+#, fuzzy
+msgid "devcp_uploader_button_release"
+msgstr "Add Release Notes"
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/uploader.thtml:156
+#, fuzzy
+msgid "devcp_uploader_created_results"
+msgstr ""
+"<p>Your add-on listing has been successfully created. The basic information "
+"obtained from your uploaded file has been stored, but there's a lot more to "
+"your listing that can be customized.</p><p>Your add-on is currently marked "
+"as <strong>Incomplete</strong>. In order to complete your add-on, you'll "
+"need to make sure it has an accurate name, summary, and description, as well "
+"as at least one selected category. You can edit your add-on's information "
+"using the link below and check the status of your add-on at any time on the "
+"<a %s>status page</a>."
+
+#: views/developers/uploader.thtml:143
+#, fuzzy
+msgid "devcp_uploader_error_correct"
+msgstr "Please correct this problem and upload your file again."
+
+#. %1$s is a version number, %2$s is a status, e.g Public or Incomplete.
+#: views/developers/uploader.thtml:175
+#, fuzzy
+msgid "devcp_uploader_file_created"
+msgstr ""
+"Your new file has been added to version %1$s and is currently marked as %2$s."
+
+#: views/developers/uploader.thtml:154
+#, fuzzy
+msgid "devcp_uploader_header_created"
+msgstr "Add-on Created!"
+
+#: views/developers/uploader.thtml:141
+#, fuzzy
+msgid "devcp_uploader_header_error"
+msgstr "Oops! There seems to be a problem with this file..."
+
+#: views/developers/uploader.thtml:173
+#, fuzzy
+msgid "devcp_uploader_header_file_added"
+msgstr "File Added!"
+
+#: views/developers/uploader.thtml:66
+#, fuzzy
+msgid "devcp_uploader_header_how"
+msgstr "How does it all work?"
+
+#. %s is the version number, e.g. 3.2.
+#: views/developers/uploader.thtml:163
+#, fuzzy
+msgid "devcp_uploader_header_update_created"
+msgstr "Version %s Created"
+
+#: views/developers/uploader.thtml:117
+#, fuzzy
+msgid "devcp_uploader_header_upload"
+msgstr "Upload Your File"
+
+#: views/developers/uploader.thtml:67
+#, fuzzy
+msgid "devcp_uploader_how"
+msgstr ""
+"<p>Thanks for your interest in submitting your add-on to Mozilla Add-ons. "
+"Hosting your add-on on Mozilla Add-ons is the easiest way to handle "
+"distribution of your add-on. Here's what you'll get:</p><ul><li>Each add-on "
+"will have a public display page with information you provide, such as a "
+"brief summary of the add-on's functionality, an optional longer description, "
+"and a showcase of preview screenshots of your add-on.</li><li>Your add-on "
+"will appear in search and browse listings across the site, and even in the "
+"Add-ons Manager of Firefox 3.</li><li>We'll take care of hosting all of your "
+"downloads and providing automatic updates to users when you upload a new "
+"version.</li><li>You'll have access to a statistics dashboard with detailed "
+"information about your user base.</li></ul><p>Add-ons hosted on the site "
+"must be reviewed by a Mozilla Add-ons Editor before they will have all of "
+"the features listed above. If you're ready to start the process and have "
+"your add-on package ready for upload, just click on Get Started below!</p>"
+
+#: views/developers/uploader.thtml:125
+#, fuzzy
+msgid "devcp_uploader_label_platformtype"
+msgstr "Supported Platforms:"
+
+#: views/developers/uploader.thtml:124
+#, fuzzy
+msgid "devcp_uploader_label_upload_field"
+msgstr "Add-on File: "
+
+#: controllers/components/developers.php:1221
+#, fuzzy
+msgid "devcp_uploader_option_other"
+msgstr "Other"
+
+#. %1$s is a number, %2$s is href="..." and should stay in the <a> tag.
+#: views/developers/uploader.thtml:176
+#, fuzzy
+msgid "devcp_uploader_p_pending_file"
+msgstr ""
+"The new file will be available to the public as soon as an editor is able to "
+"review it. There are currently %1$s other add-ons in the queue. Want to be "
+"reviewed faster? Consider <a %2$s>becoming an editor</a>."
+
+#. %1$s is a number, %2$s is href="..." and should stay in the <a> tag.
+#: views/developers/uploader.thtml:166
+#, fuzzy
+msgid "devcp_uploader_p_pending_version"
+msgstr ""
+"The new version will be available to the public as soon as an editor is able "
+"to review it. There are currently %1$s other add-ons in the queue. Want to "
+"be reviewed faster? Consider <a %2$s>becoming an editor</a>."
+
+#. %s is a status, e.g Public or Incomplete.
+#: views/developers/uploader.thtml:165
+#, fuzzy
+msgid "devcp_uploader_p_update_created"
+msgstr "Your new version has been created and is currently marked as %s."
+
+#. %1$s is href="..." and should stay in the 'Versions and Files' <a> tag.
+#. %2$s is href="..." and should stay in the 'current status' <a> tag.
+#: views/developers/uploader.thtml:177
+#, fuzzy
+msgid "devcp_uploader_p_update_file"
+msgstr ""
+"View your new file in the <a %1$s>Versions and Files page</a>, check out "
+"your add-on's <a %2$s>current status</a>, or <b>add release notes</b> by "
+"clicking the button below (highly recommended)."
+
+#. %1$s is href="..." and should stay in the 'Versions and Files' <a> tag.
+#. %2$s is href="..." and should stay in the 'current status' <a> tag.
+#: views/developers/uploader.thtml:167
+#, fuzzy
+msgid "devcp_uploader_p_update_version"
+msgstr ""
+"View your new version in the <a %1$s>Versions and Files page</a>, check out "
+"your add-on's <a %2$s>current status</a>, or <b>add release notes</b> by "
+"clicking the button below (highly recommended)."
+
+#: views/developers/uploader.thtml:118
+#, fuzzy
+msgid "devcp_uploader_p_upload"
+msgstr ""
+"Upload your add-on file using the form below. If you have multiple, platform-"
+"specific files to upload, choose a single file and then upload the others "
+"using the Versions and Files Manager."
+
+#: views/developers/uploader.thtml:125
+#, fuzzy
+msgid "devcp_uploader_platformtype_all"
+msgstr "All"
+
+#: views/developers/uploader.thtml:126
+#, fuzzy
+msgid "devcp_uploader_platformtype_specific"
+msgstr "Specific:"
+
+#. Used as first item in a <select>.
+#: controllers/components/developers.php:1185
+#, fuzzy
+msgid "devcp_uploader_please_choose"
+msgstr "Please Choose..."
+
+#. %1$s is the add-on name, %2$s is the version number.
+#: views/developers/uploader.thtml:57
+#, fuzzy
+msgid "devcp_uploader_title_file"
+msgstr "Add File to %1$s %2$s"
+
+#: views/developers/uploader.thtml:50
+#, fuzzy
+msgid "devcp_uploader_title_submit"
+msgstr "Submit New Add-on"
+
+#. %s is the add-on name.
+#: views/developers/uploader.thtml:54
+#, fuzzy
+msgid "devcp_uploader_title_update"
+msgstr "Update %s"
+
+#. %s is a full <a> tag
+#: controllers/developers_controller.php:503
+#, php-format
+msgid "devcp_valid_app_reference"
+msgstr "ר××” %s להתייחסות."
+
+#. This is the text in the <a> tag for devcp_valid_app_reference. This should be
+#. fixed.
+#: controllers/developers_controller.php:503
+msgid "devcp_valid_app_reference_linktext"
+msgstr "דף זה"
+
+#: controllers/developers_controller.php:581
+#, fuzzy
+msgid "devcp_verify_author_error"
+msgstr "No account found for that email address."
+
+#: controllers/developers_controller.php:553
+#, fuzzy
+msgid "devcp_verify_search_engine_error"
+msgstr ""
+"Either the XML is invalid or required fields are missing. Please <a href="
+"\"https://developer.mozilla.org/en/Creating_OpenSearch_plugins_for_Firefox"
+"\">read the documentation</a>, verify your add-on, and try again."
+
+#: views/developers/versions.thtml:75
+#, fuzzy
+msgid "devcp_versions_a_cancel"
+msgstr "Cancel"
+
+#: views/developers/versions.thtml:79
+#, fuzzy
+msgid "devcp_versions_a_delete"
+msgstr "Delete Version"
+
+#: views/developers/versions.thtml:74
+#, fuzzy
+msgid "devcp_versions_a_empty"
+msgstr "Remove Empty Version"
+
+#: views/developers/versions.thtml:71
+#, fuzzy
+msgid "devcp_versions_a_remove"
+msgstr "Remove?"
+
+#: views/developers/versions.thtml:91
+#, fuzzy
+msgid "devcp_versions_add"
+msgstr "Add New Version"
+
+#: views/developers/versions_delete.thtml:58
+#, fuzzy
+msgid "devcp_versions_delete_a_cancel"
+msgstr "Cancel"
+
+#: views/developers/versions_delete.thtml:56
+#, fuzzy
+msgid "devcp_versions_delete_a_delete"
+msgstr "Delete Version"
+
+#. Followed by a list of reviews and files that will be removed.
+#: views/developers/versions_delete.thtml:50
+#, fuzzy
+msgid "devcp_versions_delete_also"
+msgstr "This will also delete:"
+
+#: views/developers/versions_delete.thtml:53
+#, fuzzy
+msgid "devcp_versions_delete_files"
+msgid_plural "devcp_versions_delete_files"
+msgstr[0] "%s file"
+msgstr[1] "%s files"
+
+#. %s is the version number.
+#: views/developers/versions_delete.thtml:48
+#, fuzzy
+msgid "devcp_versions_delete_header"
+msgstr "Delete Version %s?"
+
+#: views/developers/versions_delete.thtml:52
+#, fuzzy
+msgid "devcp_versions_delete_reviews"
+msgid_plural "devcp_versions_delete_reviews"
+msgstr[0] "%s review"
+msgstr[1] "%s reviews"
+
+#. %s is the version number.
+#: views/developers/versions_delete.thtml:49
+#, fuzzy
+msgid "devcp_versions_delete_sure"
+msgstr "Are you sure you want to permanently delete version %s?"
+
+#: views/developers/versions_edit.thtml:102
+#: views/developers/versions_edit.thtml:155
+#, fuzzy
+msgid "devcp_versions_edit_a_cancel"
+msgstr "Cancel"
+
+#: views/developers/versions_edit.thtml:101
+#, fuzzy
+msgid "devcp_versions_edit_a_delete"
+msgstr "Delete File"
+
+#: views/developers/versions_edit.thtml:165
+#, fuzzy
+msgid "devcp_versions_edit_a_new_app"
+msgstr "Add New Application"
+
+#: views/developers/versions_edit.thtml:154
+#, fuzzy
+msgid "devcp_versions_edit_a_remove_app"
+msgstr "Remove Application"
+
+#: views/developers/versions_edit.thtml:114
+#, fuzzy
+msgid "devcp_versions_edit_add"
+msgstr "Add New File"
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/versions_edit.thtml:121
+#, fuzzy
+msgid "devcp_versions_edit_adjust"
+msgstr ""
+"Adjusting application information here will allow users to install your add-"
+"on even if the install.rdf in the package indicates that the add-on is "
+"incompatible. <a %s>List of supported applications</a>"
+
+#: views/developers/versions_edit.thtml:153
+#, fuzzy
+msgid "devcp_versions_edit_compat_sure"
+msgstr ""
+"Are you <b>sure</b> you wish to remove compatibility with this application?"
+
+#: views/developers/versions_edit.thtml:100
+#, fuzzy
+msgid "devcp_versions_edit_delete_sure"
+msgstr "Are you <b>sure</b> you wish to permanently delete this file?"
+
+#: views/developers/versions_edit.thtml:203
+#, fuzzy
+msgid "devcp_versions_edit_header_approval"
+msgstr "Approval Information"
+
+#: views/developers/versions_edit.thtml:120
+#, fuzzy
+msgid "devcp_versions_edit_header_compat"
+msgstr "Compatible Applications"
+
+#: views/developers/versions_edit.thtml:74
+#, fuzzy
+msgid "devcp_versions_edit_header_file"
+msgstr "File Information"
+
+#: views/developers/versions_edit.thtml:189
+#, fuzzy
+msgid "devcp_versions_edit_header_license"
+msgstr "License"
+
+#. %s is the version number.
+#: views/developers/versions_edit.thtml:53
+#, fuzzy
+msgid "devcp_versions_edit_header_manage"
+msgstr "Manage Version %s"
+
+#: views/developers/versions_edit.thtml:212
+#, fuzzy
+msgid "devcp_versions_edit_header_notes"
+msgstr "Approval Notes"
+
+#: views/developers/versions_edit.thtml:98
+#, fuzzy
+msgid "devcp_versions_edit_img_delete"
+msgstr "Delete File"
+
+#. %1$s is the file id, e.g. 18723.
+#. %2$s is the platform name, e.g. ALL or Windows.
+#. %3$s is the _('date) created.
+#. %4$s is the status, e.g. "In Sandbox" or "Public".
+#. %5$s is the _('date') status was changed.
+#: views/developers/versions_edit.thtml:208
+#, fuzzy
+msgid "devcp_versions_edit_li_file"
+msgstr "File %1$s (%2$s) created on %3$s and changed to %4$s on %5$s"
+
+#: views/developers/versions_edit.thtml:190
+#, fuzzy
+msgid "devcp_versions_edit_license_description"
+msgstr ""
+"Please select the appropriate license for your add-on. This license "
+"specifies the rights you grant on your source code."
+
+#: views/developers/versions_edit.thtml:111
+#, fuzzy
+msgid "devcp_versions_edit_no_files"
+msgstr "No files found."
+
+#: views/developers/versions_edit.thtml:213
+#, fuzzy
+msgid "devcp_versions_edit_optional"
+msgstr "Optional information for the Editor that reviews this version."
+
+#: views/developers/versions_edit.thtml:151
+#, fuzzy
+msgid "devcp_versions_edit_remove_compat"
+msgstr "Remove Application Compatibility"
+
+#: views/developers/versions_edit.thtml:167
+#, fuzzy
+msgid "devcp_versions_edit_select_app"
+msgstr "Please Select an Application"
+
+#: views/developers/versions_edit.thtml:78
+#, fuzzy
+msgid "devcp_versions_edit_th_file"
+msgstr "File"
+
+#: views/developers/versions_edit.thtml:79
+#, fuzzy
+msgid "devcp_versions_edit_th_platform"
+msgstr "Platform"
+
+#: views/developers/versions_edit.thtml:80
+#, fuzzy
+msgid "devcp_versions_edit_th_size"
+msgstr "Size"
+
+#: views/developers/versions_edit.thtml:81
+#, fuzzy
+msgid "devcp_versions_edit_th_status"
+msgstr "Status"
+
+#: views/developers/versions_edit.thtml:183
+#, fuzzy
+msgid "devcp_versions_edit_transbox_releasenotes_description"
+msgstr ""
+"Information about changes in this release, new features, known bugs, and "
+"other useful information specific to this release/version. This information "
+"will also be available to users updating the add-on in the Firefox 3 Add-ons "
+"Manager interface."
+
+#: views/developers/versions_edit.thtml:182
+#, fuzzy
+msgid "devcp_versions_edit_transbox_releasenotes_name"
+msgstr "Release Notes"
+
+#: views/developers/versions_edit.thtml:164
+#, fuzzy
+msgid "devcp_versions_edit_unsaved_compat"
+msgstr ""
+"<strong>You have unsaved changes.</strong> Compatibility will not be deleted "
+"until you click Update Version below."
+
+#: views/developers/versions_edit.thtml:113
+#, fuzzy
+msgid "devcp_versions_edit_unsaved_files"
+msgstr ""
+"<strong>You have unsaved changes.</strong> Files will not be deleted until "
+"you click Update Version below."
+
+#: views/developers/versions_edit.thtml:218
+#, fuzzy
+msgid "devcp_versions_edit_update"
+msgstr "Update Versions"
+
+#: views/developers/versions.thtml:49
+#, fuzzy
+msgid "devcp_versions_header_manage"
+msgstr "Manage Versions and Files"
+
+#: views/developers/versions.thtml:87
+#, fuzzy
+msgid "devcp_versions_no_versions"
+msgstr "No versions."
+
+#. %s is a version number, base 10.
+#: views/developers/versions.thtml:46
+#, fuzzy
+msgid "devcp_versions_notice_success"
+msgstr "Version %s deleted successfully."
+
+#: views/developers/versions.thtml:73
+#, fuzzy
+msgid "devcp_versions_p_remove"
+msgstr ""
+"This version has no files associated with it and can be removed. Would you "
+"like to remove this version?"
+
+#: views/developers/versions.thtml:58
+#, fuzzy
+msgid "devcp_versions_th_created"
+msgstr "Created"
+
+#: views/developers/versions.thtml:57
+#, fuzzy
+msgid "devcp_versions_th_status"
+msgstr "Status"
+
+#: views/developers/versions.thtml:56
+#, fuzzy
+msgid "devcp_versions_th_version"
+msgstr "Version"
+
+#: controllers/downloads_controller.php:91
+msgid "downloads_disable_warning"
+msgstr "תוספת זו מנוטרלת"
+
+#: controllers/components/editors.php:57
+#, fuzzy
+msgid "editor_review_error_addon_not_nominated"
+msgstr "This add-on has not been nominated."
+
+#: controllers/components/editors.php:213
+#, fuzzy
+msgid "editor_review_error_file_not_pending"
+msgstr "This file is not pending review."
+
+#. Actions are, for example: approving or rejecting
+#: controllers/components/editors.php:79
+#: controllers/components/editors.php:182
+#, fuzzy
+msgid "editor_review_error_no_action"
+msgstr "Please select a review action."
+
+#: controllers/components/editors.php:192
+#, fuzzy
+msgid "editor_review_error_no_applications"
+msgstr "Please enter the applications you tested."
+
+#. Comments are required when an editor approves or rejects an add-on.
+#: controllers/components/editors.php:84
+#: controllers/components/editors.php:187
+#, fuzzy
+msgid "editor_review_error_no_comments"
+msgstr "Please enter review comments."
+
+#: controllers/components/editors.php:161
+#, fuzzy
+msgid "editor_review_error_no_files"
+msgstr "Please select at least one file to review."
+
+#: controllers/components/editors.php:197
+#, fuzzy
+msgid "editor_review_error_no_operating_system"
+msgstr "Please enter the operating systems you tested."
+
+#: views/editors/logs.thtml:51
+msgid "editorcp_logs_button_filter"
+msgstr "סינון"
+
+#: views/editors/logs.thtml:44
+msgid "editorcp_logs_filter_by"
+msgstr "סינון לפי סוג/פעולה"
+
+#: views/editors/logs.thtml:42 controllers/editors_controller.php:964
+msgid "editorcp_logs_page_heading"
+msgstr "×¨×™×©×•× ×”×ירועי×"
+
+#: views/elements/developers/editorsmenu.thtml:60
+msgid "editorcp_menu_eventlog_link"
+msgstr "×¨×™×©×•× ×ירועי×"
+
+#: views/elements/developers/editorsmenu.thtml:62
+msgid "editorcp_menu_mainpage_link"
+msgstr "חזור לר×שי"
+
+#: views/elements/developers/editorsmenu.thtml:61
+msgid "editorcp_menu_reviewlog_link"
+msgstr "×¨×™×©×•× ×¡×§×™×¨×”"
+
+#: views/elements/developers/editorsmenu.thtml:55
+msgid "editorcp_menu_summary_link"
+msgstr "תקציר עורך"
+
+#: views/elements/developers/editorsmenu.thtml:52
+msgid "editorcp_menu_title"
+msgstr "כלי עורך"
+
+#: views/editors/reviewlog.thtml:49
+msgid "editorcp_reviewlog_button_filter"
+msgstr "מסנן"
+
+#: views/editors/reviewlog.thtml:58
+msgid "editorcp_reviewlog_column_action"
+msgstr "פעולה"
+
+#: views/editors/reviewlog.thtml:56
+msgid "editorcp_reviewlog_column_addon"
+msgstr "תוספת"
+
+#: views/editors/reviewlog.thtml:55
+msgid "editorcp_reviewlog_column_date"
+msgstr "ת×ריך"
+
+#: views/editors/reviewlog.thtml:57
+msgid "editorcp_reviewlog_column_editor"
+msgstr "עורך"
+
+#: views/editors/reviewlog.thtml:94
+msgid "editorcp_reviewlog_comments_hide"
+msgstr "הסתר תגובות"
+
+#: views/editors/reviewlog.thtml:93
+msgid "editorcp_reviewlog_comments_show"
+msgstr "הצג תגובות"
+
+#. %1$s and %2$s are full <input> tags for dates
+#: views/editors/reviewlog.thtml:45
+#, php-format
+msgid "editorcp_reviewlog_entries_between"
+msgstr "הצג ×¢×¨×›×™× ×‘×™×Ÿ %s ל- %s"
+
+#: views/editors/reviewlog.thtml:104
+msgid "editorcp_reviewlog_none_found"
+msgstr "×œ× × ×ž×¦×ו סקירות בפרק הזמן."
+
+#: views/editors/reviewlog.thtml:42
+msgid "editorcp_reviewlog_page_heading"
+msgstr "×¨×™×©×•× ×¡×§×™×¨×”"
+
+#: views/editors/summary.thtml:61
+msgid "editorcp_summary_monthreviews_heading"
+msgstr "סקירות החודש"
+
+#: views/editors/summary.thtml:77
+msgid "editorcp_summary_neweditors_heading"
+msgstr "×¢×•×¨×›×™× ×—×“×©×™×"
+
+#: views/editors/summary.thtml:42
+msgid "editorcp_summary_page_heading"
+msgstr "×¡×™×›×•× ×¢×•×¨×š"
+
+#: views/editors/summary.thtml:94
+msgid "editorcp_summary_recentactivity_heading"
+msgstr "פעילות עורך ×חרונה"
+
+#: views/editors/summary.thtml:45
+msgid "editorcp_summary_totalreviews_heading"
+msgstr "סה\"כ סקירות"
+
+#: controllers/editors_controller.php:248
+#: controllers/editors_controller.php:249
+msgid "editors_addon_review_pagetitle"
+msgstr "סקירת תוספת"
+
+#: controllers/editors_controller.php:349
+msgid "editors_error_js-formerror"
+msgstr "× × ×”×©×œ× ×ת השדות הב××™×:"
+
+#: controllers/editors_controller.php:350
+msgid "editors_error_review_one_file"
+msgstr "בחר בבקשה לפחות קובץ ×חד לסקירה."
+
+#: controllers/editors_controller.php:274
+msgid "editors_error_self_reviews_forbidden"
+msgstr "סקירות עצמיות ×ינן מותרות."
+
+#: controllers/editors_controller.php:699
+msgid "editors_external_software"
+msgstr "תוכנה חיצונית"
+
+#: views/editors/featured.thtml:120 views/editors/featured.thtml:121
+msgid "editors_featured_add_feature"
+msgstr "הוסף מ×פיין"
+
+#: views/editors/featured.thtml:126
+msgid "editors_featured_add_feature_submit"
+msgstr "הוסף"
+
+#: views/editors/featured.thtml:49 controllers/editors_controller.php:832
+#: controllers/editors_controller.php:848
+msgid "editors_featured_addon_add_failure"
+msgstr "הוספת המ×פיין נכשלה."
+
+#: controllers/editors_controller.php:851
+msgid "editors_featured_addon_add_success"
+msgstr "הוספת המ×פיין הצליחה."
+
+#: views/editors/featured.thtml:50 controllers/editors_controller.php:839
+#: controllers/editors_controller.php:868
+#: controllers/editors_controller.php:886
+msgid "editors_featured_addon_edit_failure"
+msgstr "עריכת המ×פיין נכשלה."
+
+#: views/editors/featured.thtml:51 controllers/editors_controller.php:888
+msgid "editors_featured_addon_edit_success"
+msgstr "עריכת המ×פיין הצליחה."
+
+#: views/editors/featured.thtml:53 controllers/editors_controller.php:861
+msgid "editors_featured_addon_invalid_locale"
+msgstr "×חד ×ו כמה ×ž×”×ª×¨×’×•×ž×™× ×©×’×•×™×™×."
+
+#: views/editors/featured.thtml:52 controllers/editors_controller.php:906
+msgid "editors_featured_addon_remove_failure"
+msgstr "הסרת המ×פיין נכשלה."
+
+#: controllers/editors_controller.php:901
+msgid "editors_featured_addon_remove_success"
+msgstr "הסרת המ×פיין הצליחה."
+
+#: controllers/editors_controller.php:915
+#: controllers/editors_controller.php:917
+msgid "editors_featured_addons_pagetitle"
+msgstr "×יפיון תוספות"
+
+#: views/editors/featured.thtml:54 views/editors/featured.thtml:107
+msgid "editors_featured_edit_feature_submit"
+msgstr "לך"
+
+#: views/editors/featured.thtml:90 views/editors/featured.thtml:91
+msgid "editors_featured_remove_feature"
+msgstr "הסרת מ×פיין"
+
+#: views/editors/queue.thtml:46
+msgid "editors_filter_queue"
+msgstr "תור מסנן"
+
+#: views/editors/queue.thtml:182
+msgid "editors_helpful_links"
+msgstr "×§×™×©×•×¨×™× ×ž×•×¢×™×œ×™×"
+
+#: views/editors/queue.thtml:182
+msgid "editors_link_guide"
+msgstr "מדריך העורכי×"
+
+#: views/editors/queue.thtml:182
+msgid "editors_link_policy"
+msgstr "מדיניות תוספת"
+
+#: views/editors/queue.thtml:47
+msgid "editors_notice_filter_session"
+msgstr "×ž×¡× × ×™× ×לו יש×רו ×‘×ž×§×•×ž× ×‘×”×¤×¢×œ×” זו ×ו עד שימחקו"
+
+#. %1 is the queue mode
+#: views/editors/queue.thtml:177 views/admin/flagged_queue.thtml:89
+msgid "editors_notice_none_found"
+msgstr "כרגע ×ין %s תוספות לסקירה."
+
+#: controllers/editors_controller.php:1040
+msgid "editors_one_day"
+msgstr "יו×"
+
+#: controllers/editors_controller.php:1048
+msgid "editors_one_hour"
+msgstr "שעה"
+
+#: controllers/editors_controller.php:1056
+msgid "editors_one_minute"
+msgstr "דקה"
+
+#: controllers/editors_controller.php:64 controllers/editors_controller.php:73
+#: controllers/editors_controller.php:77
+msgid "editors_pagetitle"
+msgstr "לוח בקרה לעורכי×"
+
+#. %s is a comma separated list of platforms. Example: Windows, OS X
+#: controllers/editors_controller.php:680
+#: controllers/editors_controller.php:683
+#, php-format
+msgid "editors_platform_x_only"
+msgstr "%s בלבד"
+
+#: controllers/editors_controller.php:695
+msgid "editors_pre-release"
+msgstr "שחרור מקדי×"
+
+#. %1 is the app name
+#: views/editors/queue.thtml:131
+#, php-format
+msgid "editors_queue_app_compatibility"
+msgstr "ת×ימות ל־%s"
+
+#: views/editors/queue.thtml:51
+#, fuzzy
+msgid "editors_queue_filter_label_addon"
+msgstr "Add-on or Author Email"
+
+#: views/editors/queue.thtml:72
+#, fuzzy
+msgid "editors_queue_filter_label_addontypes"
+msgstr "Add-on Types"
+
+#: views/editors/queue.thtml:56
+#, fuzzy
+msgid "editors_queue_filter_label_application"
+msgstr "Application"
+
+#: views/editors/queue.thtml:61
+#, fuzzy
+msgid "editors_queue_filter_label_maxversion"
+msgstr "Max. Version"
+
+#: views/editors/queue.thtml:78
+#, fuzzy
+msgid "editors_queue_filter_label_platforms"
+msgstr "Platforms"
+
+#: views/editors/queue.thtml:66
+#, fuzzy
+msgid "editors_queue_filter_label_submissionage"
+msgstr "Age of Submission (days)"
+
+#. %1$s is a number
+#: views/editors/queue.thtml:90
+#, fuzzy
+msgid "editors_queue_filter_result_count"
+msgid_plural "editors_queue_filter_result_count"
+msgstr[0] "Results of your filtered search: <strong>%1$s</strong> Add-on"
+msgstr[1] "Results of your filtered search: <strong>%1$s</strong> Add-ons"
+
+#: views/editors/queue.thtml:84
+msgid "editors_queue_submit_clean"
+msgstr "מחק"
+
+#: views/editors/queue.thtml:83
+msgid "editors_queue_submit_filter"
+msgstr "סנן"
+
+#: controllers/editors_controller.php:133
+msgid "editors_queues_disabled"
+msgstr "כל תורות הסקירות כרגע מנוטרלי×. בדוק בבקשה מ×וחר יותר."
+
+#: views/editors/review.thtml:149
+#, fuzzy
+msgid "editors_review_a_edit_item"
+msgstr "Edit Item"
+
+#: views/editors/review.thtml:146
+#, fuzzy
+msgid "editors_review_a_item_history"
+msgstr "Item History"
+
+#: views/editors/review.thtml:148
+#, fuzzy
+msgid "editors_review_a_item_homepage"
+msgstr "Item Homepage"
+
+#: views/editors/review.thtml:145
+#, fuzzy
+msgid "editors_review_a_item_overview"
+msgstr "Item Overview"
+
+#: views/editors/review.thtml:147
+#, fuzzy
+msgid "editors_review_a_previews"
+msgstr "Previews"
+
+#: controllers/editors_controller.php:345
+msgid "editors_review_action"
+msgstr "פעולת סיקור"
+
+#: views/editors/review.thtml:159
+#, fuzzy
+msgid "editors_review_action_info"
+msgstr "Request More Information"
+
+#: views/editors/review.thtml:157
+msgid "editors_review_action_public"
+msgstr "דחוף לציבורי"
+
+#: views/editors/review.thtml:160
+msgid "editors_review_action_request_superreview"
+msgstr "דרושה סקירת-על"
+
+#: views/editors/review.thtml:158
+msgid "editors_review_action_sandbox"
+msgstr "שמור ב×רגז החול"
+
+#: controllers/editors_controller.php:346
+msgid "editors_review_comments"
+msgstr "הערות סקירה"
+
+#: views/editors/review.thtml:182
+#, fuzzy
+msgid "editors_review_details_info_request"
+msgstr ""
+"Use this form to request more information from the author. They will receive "
+"an email and be able to answer here. You will be notified by email when they "
+"reply."
+
+#: views/editors/review.thtml:174
+msgid "editors_review_details_nominated_public"
+msgstr ""
+"×–×” יסמן ×ת התוספת ו×ת הגירסה ×•×”×§×‘×¦×™× ×”××—×¨×•× ×™× ×©×œ×” כציבוריי×. גירס×ות עתידיות "
+"יופנו ל×רגז החול עד שיסוקרו בידי עורך."
+
+#: views/editors/review.thtml:177
+msgid "editors_review_details_nominated_sandbox"
+msgstr "×–×” ישמור ×ת התוספת ב×רגז החול."
+
+#: views/editors/review.thtml:166
+msgid "editors_review_details_pending_public"
+msgstr "×–×” ×™×שר לגירסת ×רגז החול של התוספת הציבורית להופיע בצד הציבורי."
+
+#: views/editors/review.thtml:169
+msgid "editors_review_details_pending_sandbox"
+msgstr "×–×” ×™×’×¨×•× ×©×’×™×¨×¡×ª ×רגז החול של התוספת הציבורית תש×ר ב×רגז החול."
+
+#: views/editors/review.thtml:185
+msgid "editors_review_details_superreview"
+msgstr ""
+"×× ×™×© לך ד×גות ×ודות ×”×בטחה וזכויות ×”×™×•×¦×¨×™× ×©×œ התוספת הזו ×ו ד×גות ×חרות "
+"שמנהל צריך לבדוק, הכנס ×ת ההערות ב×יזור מתחת. ההערות תשלחנה למנהלי×, ×œ× "
+"למחבר."
+
+#: views/editors/review.thtml:134
+msgid "editors_review_file_diff_link"
+msgstr "השווה ×¢× ×”×’×™×¨×¡×” הציבורית"
+
+#: views/editors/review.thtml:131
+msgid "editors_review_file_viewcontents_link"
+msgstr "הצג תכני×"
+
+#: views/editors/review.thtml:65
+msgid "editors_review_header_authors"
+msgstr "מחברי×:"
+
+#: views/editors/review.thtml:79
+msgid "editors_review_header_categories"
+msgstr "קטגוריות:"
+
+#: views/editors/review.thtml:92
+msgid "editors_review_header_compatibility"
+msgstr "ת×ימות:"
+
+#: views/editors/review.thtml:251
+msgid "editors_review_header_description"
+msgstr "תי×ור"
+
+#: views/editors/review.thtml:275
+msgid "editors_review_header_devcomments"
+msgstr "הערות המפתח"
+
+#: views/editors/review.thtml:263
+msgid "editors_review_header_eula"
+msgstr "×”×¡×›× ×ž×©×ª×ž×© (EULA)"
+
+#: views/editors/review.thtml:115
+msgid "editors_review_header_files"
+msgstr "קבצי×:"
+
+#: views/editors/review.thtml:284
+msgid "editors_review_header_itemhistory"
+msgstr "היסטוריית פריט"
+
+#: views/editors/review.thtml:232
+msgid "editors_review_header_nominationmessage"
+msgstr "הודעת הגשה"
+
+#: views/editors/review.thtml:311
+msgid "editors_review_header_previews"
+msgstr "תצוגות מקדימות"
+
+#: views/editors/review.thtml:269
+msgid "editors_review_header_privacy"
+msgstr "מדיניות פרטיות"
+
+#. %1 is the add-on name and version
+#: views/editors/review.thtml:56
+#, php-format
+msgid "editors_review_header_review"
+msgstr "סקירת %s"
+
+#: views/editors/review.thtml:239
+msgid "editors_review_header_reviewernotes"
+msgstr "הערות לסוקר"
+
+#: views/editors/review.thtml:245
+msgid "editors_review_header_summary"
+msgstr "סיכו×"
+
+#: views/editors/review.thtml:257
+msgid "editors_review_header_versionnotes"
+msgstr "הערות גירסה"
+
+#. a noun: shown in an add-on's editor review history
+#: views/elements/developers/editors_review_history_item.thtml:80
+#, fuzzy
+msgid "editors_review_history_info_reply"
+msgstr "Reply"
+
+#: views/elements/developers/editors_review_history_item.thtml:78
+#, fuzzy
+msgid "editors_review_history_info_request"
+msgstr "Information Request"
+
+#: views/elements/developers/editors_review_history_item.thtml:62
+#: views/editors/reviewlog.thtml:77
+msgid "editors_review_history_nominated_adminreview"
+msgstr "סקירת מנהל"
+
+#: views/elements/developers/editors_review_history_item.thtml:56
+#: views/editors/reviewlog.thtml:71
+msgid "editors_review_history_nominated_approved"
+msgstr "הגשה ×ושרה/ציבורי"
+
+#: views/elements/developers/editors_review_history_item.thtml:59
+#: views/editors/reviewlog.thtml:74
+msgid "editors_review_history_nominated_denied"
+msgstr "הגשה נדחתה/×רגז החול"
+
+#: views/editors/review.thtml:303
+msgid "editors_review_history_nonefound"
+msgstr "×œ× × ×ž×¦×ו ערכי סקירה קודמי×."
+
+#: views/elements/developers/editors_review_history_item.thtml:73
+#: views/editors/reviewlog.thtml:88
+msgid "editors_review_history_pending_adminreview"
+msgstr "סקירת מנהל"
+
+#: views/elements/developers/editors_review_history_item.thtml:67
+#: views/editors/reviewlog.thtml:82
+msgid "editors_review_history_pending_approved"
+msgstr "מ×ושר/ציבורי"
+
+#: views/elements/developers/editors_review_history_item.thtml:70
+#: views/editors/reviewlog.thtml:85
+msgid "editors_review_history_pending_denied"
+msgstr "נדחה/×רגז חול"
+
+#. link text in an add-on's editor review history, allowing to hide and show an information request's replies
+#. %1 is the number of replies
+#: views/elements/developers/editors_review_history_item.thtml:90
+#, fuzzy
+msgid "editors_review_history_show_hide_replies"
+msgid_plural "editors_review_history_show_hide_replies"
+msgstr[0] "Show/Hide Replies (%1$s)"
+msgstr[1] "Show/Hide Replies (%1$s)"
+
+#: views/editors/review.thtml:208
+msgid "editors_review_label_applications"
+msgstr "יישומי×:"
+
+#: views/editors/review.thtml:196
+msgid "editors_review_label_cannedresponse"
+msgstr "×ו בחר תגובה מוכנה:"
+
+#: views/editors/review.thtml:190
+msgid "editors_review_label_comments"
+msgstr "תגובות:"
+
+#: views/editors/review.thtml:204
+msgid "editors_review_label_operating_systems"
+msgstr "מערכות הפעלה:"
+
+#: views/editors/review.thtml:285 views/editors/review.thtml:312
+msgid "editors_review_link_pagetop"
+msgstr "למעלה"
+
+#: views/editors/review.thtml:141
+#, fuzzy
+msgid "editors_review_mulitple_notice"
+msgstr ""
+"Notice: Only review more than one file if you have tested EVERY file you "
+"select."
+
+#: views/editors/review.thtml:51
+#, fuzzy
+msgid "editors_review_next_link"
+msgstr "next &raquo;"
+
+#: views/editors/review.thtml:322
+msgid "editors_review_previews_notfound"
+msgstr "×œ× × ×ž×¦×ו סקירות."
+
+#: views/editors/review.thtml:50
+#, fuzzy
+msgid "editors_review_previous_link"
+msgstr "&laquo; prev"
+
+#: controllers/editors_controller.php:144
+#: controllers/editors_controller.php:146
+msgid "editors_review_queue_pagetitle"
+msgstr "תור סקירה"
+
+#. %1 is the add-ons rank in the queue, %2 is the total queue length
+#: views/editors/review.thtml:47
+#, fuzzy
+msgid "editors_review_rank_in_queue"
+msgstr "<strong># %1$s</strong> of %2$s in queue"
+
+#. %1 is the add-ons rank in the queue, %2 is the total queue length. Both numbers
+#: views/editors/review.thtml:45
+#, fuzzy
+msgid "editors_review_rank_in_queue_filtered"
+msgstr "<strong># %1$s</strong> of %2$s in queue (filtered)"
+
+#: views/editors/review.thtml:223
+msgid "editors_review_submit_process_action"
+msgstr "בצע פעולה"
+
+#: views/editors/review.thtml:293
+msgid "editors_review_th_action"
+msgstr "פעולה"
+
+#: views/editors/review.thtml:294
+msgid "editors_review_th_comments"
+msgstr "תגובות"
+
+#: views/editors/review.thtml:291
+msgid "editors_review_th_date"
+msgstr "ת×ריך"
+
+#: views/editors/review.thtml:292
+msgid "editors_review_th_reviewer"
+msgstr "סוקר"
+
+#: views/editors/review.thtml:290
+msgid "editors_review_th_version_file"
+msgstr "גירסה/קובץ"
+
+#: views/editors/review.thtml:217
+#, fuzzy
+msgid "editors_review_update_notify_once"
+msgstr ""
+"Notify me the next time this add-on is updated. (Subsequent updates will not "
+"generate an email)"
+
+#: controllers/editors_controller.php:298
+msgid "editors_reviewed_successfully"
+msgstr "הסקירה עובדה בהצלחה."
+
+#: views/editors/reviews_queue.thtml:106
+#, fuzzy
+msgid "editors_reviews_action_delete_review"
+msgstr "Delete review"
+
+#: views/editors/reviews_queue.thtml:104
+#, fuzzy
+msgid "editors_reviews_action_keep"
+msgstr "Remove flags; keep review"
+
+#: views/editors/reviews_queue.thtml:102
+msgid "editors_reviews_action_skip"
+msgstr "דלג"
+
+#: views/editors/reviews_queue.thtml:100
+msgid "editors_reviews_header_action"
+msgstr "פעולה"
+
+#: views/editors/reviews_queue.thtml:67
+msgid "editors_reviews_in_reply_to"
+msgstr "בתגובה ל:"
+
+#: controllers/editors_controller.php:748
+msgid "editors_reviews_processed"
+msgstr "הסקירות עובדו בהצלחה!"
+
+#: views/editors/reviews_queue.thtml:117
+msgid "editors_reviews_queue_empty"
+msgstr "×œ× ×§×™×™×ž×•×ª סקירות לניהול."
+
+#: views/editors/reviews_queue.thtml:111
+msgid "editors_reviews_submit_process_reviews"
+msgstr "עבד סקירות"
+
+#: controllers/editors_controller.php:691
+msgid "editors_site_specific"
+msgstr "×תר מסוי×"
+
+#: controllers/editors_controller.php:348
+msgid "editors_tested_app"
+msgstr "×™×©×•× × ×‘×“×§"
+
+#: controllers/editors_controller.php:347
+msgid "editors_tested_os"
+msgstr "מערכות הפעלה שנבדקו"
+
+#: views/editors/queue.thtml:151
+msgid "editors_th_additional_info"
+msgstr "מידע נוסף"
+
+#: views/editors/featured.thtml:63 views/editors/queue.thtml:109
+#: views/admin/flagged_queue.thtml:53
+msgid "editors_th_addon"
+msgstr "תוספת"
+
+#: views/editors/queue.thtml:125
+msgid "editors_th_addontype"
+msgstr "סוג"
+
+#: views/editors/featured.thtml:64
+msgid "editors_th_locales"
+msgstr "הגבלה לשפות?"
+
+#: views/editors/queue.thtml:148
+#, fuzzy
+msgid "editors_th_nomination_age"
+msgstr "Time in Queue"
+
+#: views/editors/queue.thtml:101 views/editors/queue.thtml:117
+#: views/editors/queue.thtml:144
+#, fuzzy
+msgid "editors_th_sort_ascending"
+msgstr "Ascending sort"
+
+#: views/editors/queue.thtml:105 views/editors/queue.thtml:121
+#: views/editors/queue.thtml:140
+#, fuzzy
+msgid "editors_th_sort_descending"
+msgstr "Descending sort"
+
+#. %s is a number
+#: controllers/editors_controller.php:1036
+#, php-format
+msgid "editors_x_days"
+msgstr "%s ימי×"
+
+#. %s is a number
+#: controllers/editors_controller.php:1044
+#, php-format
+msgid "editors_x_hours"
+msgstr "%s שעות"
+
+#. %s is a number
+#: controllers/editors_controller.php:1052
+#, php-format
+msgid "editors_x_minutes"
+msgstr "%s דקות"
+
+#: views/errors/error401.thtml:50 controllers/components/simple_acl.php:81
+#: controllers/components/simple_acl.php:82
+#: controllers/components/simple_acl.php:83 controllers/components/amo.php:607
+#: controllers/components/amo.php:608 controllers/components/amo.php:609
+#: controllers/reviews_controller.php:353
+#: controllers/reviews_controller.php:485
+#: controllers/collections_controller.php:438
+#: controllers/collections_controller.php:496
+#: controllers/collections_controller.php:504
+#: controllers/collections_controller.php:971
+#: controllers/collections_controller.php:1034
+#: controllers/collections_controller.php:1077
+msgid "error_access_denied"
+msgstr "×ין גישה"
+
+#: views/errors/error401.thtml:52
+msgid "error_access_denied_message"
+msgstr "×ינך רש××™ לצפות בדף ×–×”."
+
+#: controllers/collections_controller.php:1039
+#, fuzzy
+msgid "error_addon_exists"
+msgstr "Add-on already exists!"
+
+#: controllers/developers_controller.php:200
+#: controllers/developers_controller.php:593
+#: controllers/developers_controller.php:1016
+#: controllers/developers_controller.php:1429
+#: controllers/downloads_controller.php:95
+#: controllers/downloads_controller.php:102
+#: controllers/downloads_controller.php:164
+#: controllers/statistics_controller.php:135
+#: controllers/previews_controller.php:115
+#: controllers/previews_controller.php:206
+#: controllers/previews_controller.php:307
+#: controllers/reviews_controller.php:77
+#: controllers/reviews_controller.php:240
+#: controllers/reviews_controller.php:332
+#: controllers/reviews_controller.php:340 controllers/api_controller.php:123
+#: controllers/api_controller.php:759 controllers/addons_controller.php:131
+#: controllers/addons_controller.php:197
+#: controllers/addons_controller.php:1407
+#: controllers/addons_controller.php:1465
+#: controllers/addons_controller.php:1469
+#: controllers/addons_controller.php:1503
+#: controllers/editors_controller.php:265
+#: controllers/collections_controller.php:1041
+#: controllers/collections_controller.php:1074
+msgid "error_addon_notfound"
+msgstr "התוספת ×œ× × ×ž×¦××”!"
+
+#: controllers/files_controller.php:83 controllers/files_controller.php:196
+msgid "error_addon_notviewable"
+msgstr "תוספת זו ××™× ×” ניתנת לצפייה ×›×ן."
+
+#: controllers/reviews_controller.php:246
+msgid "error_addon_selfreview"
+msgstr "×תה ×œ× ×™×›×•×œ לסקור תוספת שלך."
+
+#: controllers/addons_controller.php:970
+msgid "error_browse_no_addons"
+msgstr "×ין תוספות בקטגוריה!"
+
+#: controllers/api_controller.php:424
+#, fuzzy
+msgid "error_collection_feed_notfound"
+msgstr "Add-on feed not found."
+
+#: views/users/register.thtml:65 views/users/edit.thtml:194
+msgid "error_email_invalid"
+msgstr "זוהי ××™× ×” כתובת דו×\"ל חוקית."
+
+#: views/users/pwreset.thtml:74 views/users/register.thtml:70
+#: views/users/register.thtml:80 views/users/register.thtml:86
+#: views/users/edit.thtml:105 views/users/edit.thtml:111
+#: views/users/edit.thtml:192 views/admin/users_edit.thtml:78
+#: views/admin/users_edit.thtml:83 views/reviews/add.thtml:80
+#: views/reviews/add.thtml:104
+msgid "error_field_required"
+msgstr "שדה ×–×” ×œ× ×™×›×•×œ להיות ריק."
+
+#: controllers/files_controller.php:75 controllers/files_controller.php:93
+#: controllers/files_controller.php:96 controllers/files_controller.php:163
+#: controllers/files_controller.php:176 controllers/files_controller.php:185
+#: controllers/files_controller.php:204 controllers/editors_controller.php:412
+msgid "error_file_notfound"
+msgstr "קובץ ×œ× × ×ž×¦×!"
+
+#. %s is a filename
+#: controllers/editors_controller.php:430
+#, php-format
+msgid "error_file_x_notfound"
+msgstr "שגי×ת קובץ: %s ×œ× ×§×™×™×."
+
+#: views/collections/add.thtml:55 views/collections/edit.thtml:89
+#: views/users/register.thtml:54 views/users/edit.thtml:81
+#: views/reviews/add.thtml:70 controllers/groups_controller.php:80
+#: controllers/groups_controller.php:102
+msgid "error_formerrors"
+msgstr "קיימות שגי×ות בטופס ×–×”. בבקשה תקן ×ותן ושלח שוב."
+
+#: views/users/register.thtml:109
+msgid "error_invalid_captcha"
+msgstr "קפ×צ'×” שגוייה, נסה שוב!"
+
+#: views/users/register.thtml:100 views/users/edit.thtml:125
+#: views/admin/users_edit.thtml:101
+msgid "error_invalid_url"
+msgstr ""
+"כתובת זו ×”×™× ×” בתבנית שגויה. כתובות תקינות נר×ות בסגנון של http://example.com/"
+"my_page."
+
+#. %s is a string representing what's missing. Example: file_id
+#: controllers/downloads_controller.php:65
+#: controllers/users_controller.php:185 controllers/users_controller.php:264
+#: controllers/users_controller.php:559 controllers/users_controller.php:653
+#: controllers/reviews_controller.php:71
+#: controllers/reviews_controller.php:234
+#: controllers/reviews_controller.php:325
+#: controllers/reviews_controller.php:473
+#: controllers/reviews_controller.php:475
+#: controllers/addons_controller.php:182
+#: controllers/addons_controller.php:1381
+#: controllers/addons_controller.php:1455
+#: controllers/collections_controller.php:266
+#: controllers/collections_controller.php:285
+#: controllers/collections_controller.php:346
+#: controllers/collections_controller.php:443
+#: controllers/collections_controller.php:482
+#: controllers/collections_controller.php:936
+#: controllers/collections_controller.php:959
+#: controllers/collections_controller.php:960
+#: controllers/collections_controller.php:975
+#: controllers/collections_controller.php:977
+#: controllers/collections_controller.php:994
+#: controllers/collections_controller.php:1003
+#: controllers/collections_controller.php:1016
+#: controllers/collections_controller.php:1017
+#: controllers/collections_controller.php:1024
+#: controllers/collections_controller.php:1070
+#: controllers/collections_controller.php:1090
+#, php-format
+msgid "error_missing_argument"
+msgstr "טיעון חסר: %s"
+
+#: controllers/components/amo.php:507 controllers/components/amo.php:532
+#, fuzzy
+msgid "error_no_files_in_addon"
+msgstr "No Files"
+
+#: controllers/previews_controller.php:200
+msgid "error_preview_notfound"
+msgstr "תצוגה מקדימה ×œ× × ×ž×¦××”!"
+
+#: views/addons/display.thtml:400 views/reviews/add.thtml:98
+msgid "error_review_rating_required"
+msgstr "×תה חייב לבחור דירוג."
+
+#: controllers/users_controller.php:160
+msgid "error_user_already_confirmed"
+msgstr "משתמש ×–×” כבר ×ומת בעבר."
+
+#: controllers/users_controller.php:202 controllers/users_controller.php:276
+#: controllers/users_controller.php:569 controllers/users_controller.php:581
+#: controllers/users_controller.php:587 controllers/users_controller.php:610
+#: controllers/users_controller.php:627
+msgid "error_user_badconfirmationcode"
+msgstr "קוד ×ימות שגוי!"
+
+#: views/users/pwreset.thtml:79 views/users/register.thtml:75
+#: views/users/edit.thtml:183
+msgid "error_user_confirmpw_nomatch"
+msgstr "הסיסמ×ות ×œ× ×ª×•×מות."
+
+#: views/users/register.thtml:65 views/users/edit.thtml:190
+#: controllers/users_controller.php:617
+msgid "error_user_email_notunique"
+msgstr "כתובת דו×\"ל זו כבר נלקחה על־ידי משתמש ×חר."
+
+#: controllers/users_controller.php:596
+msgid "error_user_emailchange_expired"
+msgstr ""
+"פג הזמן לשינוי כתובת הדו×\"ל שלך. בבקשה שנה שוב ×ת כתובת הדו×\"ל בפרופיל "
+"המשתמש שלך ולחץ על הקישור בהודעת ×”×ימות מיד כש×תה מקבל ×ותה."
+
+#: controllers/collections_controller.php:985
+#, fuzzy
+msgid "error_user_exists"
+msgstr ""
+"Users can only have one role at a time. Please remove the user from any "
+"existing roles before continuing."
+
+#: views/users/register.thtml:91 views/users/edit.thtml:116
+#: views/admin/users_edit.thtml:88
+msgid "error_user_nickname_notunique"
+msgstr "כינוי זה כבר נלקח."
+
+#: views/users/pwreset.thtml:54 controllers/users_controller.php:191
+#: controllers/users_controller.php:270 controllers/users_controller.php:603
+#: controllers/users_controller.php:659
+#: controllers/collections_controller.php:988
+#: controllers/collections_controller.php:998
+msgid "error_user_notfound"
+msgstr "משתמש ×œ× × ×ž×¦×!"
+
+#: views/users/activatefirst.thtml:47
+msgid "error_user_unconfirmed"
+msgstr "× × ×œ×מת ×ת החשבון לפני ביצוע הפעולה."
+
+#: views/users/login.thtml:67
+msgid "error_username_or_pw_wrong"
+msgstr "×©× ×ž×©×ª×ž×© ×ו סיסמה ×œ× × ×›×•× ×™×!"
+
+#: controllers/editors_controller.php:260
+msgid "error_version_notfound"
+msgstr "גירסה ×œ× × ×ž×¦××”!"
+
+#: views/users/delete.thtml:125 views/users/edit.thtml:173
+msgid "error_wrong_password"
+msgstr "הוכנסה סיסמה שגוייה!"
+
+#: views/elements/amo2009/homepage_addon.thtml:122
+#: views/elements/feature.thtml:122
+msgid "feature_learnmore"
+msgstr "למד עוד"
+
+#. %1 is the add-on name
+#: views/elements/amo2009/homepage_addon.thtml:123
+#: views/elements/feature.thtml:123
+#, php-format
+msgid "feature_learnmore_about_addon"
+msgstr "למד עוד על %1$s"
+
+#. %1$s is a number
+#: views/elements/amo2009/reviews.thtml:52
+#: views/elements/addon_listitem.thtml:112 views/elements/feature.thtml:99
+#: views/addons/browse_thumbs.thtml:86
+#, php-format
+msgid "feature_reviews"
+msgid_plural "feature_reviews"
+msgstr[0] "סקירות"
+msgstr[1] "סקירות"
+
+#: views/elements/amo2009/homepage_addon.thtml:127
+#: views/elements/feature.thtml:127
+msgid "feature_view_more_from_category"
+msgstr "צפה בעוד מ"
+
+#. This appears on a page that views the source of an add-on. This link will return
+#. the user to the add-on's main page
+#: views/files/browse.thtml:65
+#, fuzzy
+msgid "file_browser_link_addon"
+msgstr "Back to add-on"
+
+#. There is a list of directories and files on the page. Clicking this will show the
+#. contents of all the directories (normally you would click on each one to see the
+#. contents)
+#: views/files/browse.thtml:67
+#, fuzzy
+msgid "file_browser_link_expand_all"
+msgstr "Expand all"
+
+#. This appears on a page that views the source of an add-on. This link will return
+#. the user to the add-on's review page (it only appears if the add-on is being
+#. reviewed)
+#: views/files/browse.thtml:64
+#, fuzzy
+msgid "file_browser_link_review"
+msgstr "Back to review"
+
+#. The title of the page for viewing an add-on's source.
+#. %1$s is the name of the add-on
+#. %2$s is the name of the current application (e.g. Firefox or Thunderbird)
+#: views/files/browse.thtml:46
+#, fuzzy
+msgid "file_browser_title"
+msgstr "%1$s :: File Browser :: %2$s Add-ons"
+
+#. This appears on a page that views the source of an add-on. There is a list of
+#. directories and files on the page. Clicking this link will toggle between an
+#. expanded or a collapsed list. This string should be kept short.
+#: views/files/browse.thtml:68
+#, fuzzy
+msgid "file_browser_toggle_expand_collapse"
+msgstr "+/-"
+
+#. Link text for the AMO About page.
+#: views/elements/footer.thtml:72 views/layouts/amo2009.thtml:341
+#, fuzzy
+msgid "footer_a_about"
+msgstr "About"
+
+#. Link text to the AMO blog.
+#: views/elements/footer.thtml:74 views/layouts/amo2009.thtml:343
+#, fuzzy
+msgid "footer_a_blog"
+msgstr "Blog"
+
+#. Link text to the Frequently Asked Questions page.
+#: views/elements/footer.thtml:73 views/layouts/amo2009.thtml:342
+#, fuzzy
+msgid "footer_a_faq"
+msgstr "FAQ"
+
+#. Full text for the FAQ abbreviation.
+#: views/elements/footer.thtml:73 views/pages/collector_features.thtml:72
+#: views/layouts/amo2009.thtml:342
+#, fuzzy
+msgid "footer_abbr_faq"
+msgstr "Frequently Asked Questions"
+
+#: views/elements/footer.thtml:67 views/layouts/amo2009.thtml:336
+msgid "footer_all_rights_reserved"
+msgstr "כל הזכויות שמורות."
+
+#: views/elements/footer.thtml:67 views/layouts/amo2009.thtml:336
+msgid "footer_copyright"
+msgstr "זכויות יוצרי×"
+
+#: views/elements/footer.thtml:71 views/layouts/amo2009.thtml:340
+msgid "footer_credits"
+msgstr "קרדיטי×"
+
+#: views/elements/footer.thtml:76 views/layouts/amo2009.thtml:346
+msgid "footer_disclaimer"
+msgstr ""
+"מוזילה מספקת ×§×™×©×•×¨×™× ×œ×™×™×©×•×ž×™× ×לו מתוך נימוס, ו××™× ×” מייצגת ×ת ×ת ×”×™×™×©×•×ž×™× ×ו "
+"כל מידע בקשר ×ליה×. ש×לות, תלונות ×ו טענות בנוגע ×œ×™×™×©×•×ž×™× ×™×© להפנות למספק "
+"התוכנה המת××™×."
+
+#: views/elements/footer.thtml:61 views/layouts/amo2009.thtml:332
+msgid "footer_lang_form_lang_submit_go"
+msgstr "לך"
+
+#: views/elements/footer.thtml:70 views/layouts/amo2009.thtml:339
+msgid "footer_legal_notices"
+msgstr "הצהרה משפטית"
+
+#: views/elements/footer.thtml:50 views/layouts/amo2009.thtml:321
+msgid "footer_other_languages"
+msgstr "שפות ×חרות:"
+
+#: views/elements/footer.thtml:69 views/layouts/amo2009.thtml:338
+msgid "footer_privacy_policy"
+msgstr "הצהרת פרטיות"
+
+#: models/addontype.php:79
+msgid "general_addontype_dict"
+msgstr "מילון"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:100
+msgid "general_addontype_dict_plural"
+msgstr "מילוני×"
+
+#: models/addontype.php:75
+msgid "general_addontype_extension"
+msgstr "הרחבה"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:98
+msgid "general_addontype_extension_plural"
+msgstr "הרחבות"
+
+#: models/addontype.php:85
+msgid "general_addontype_lpaddon"
+msgstr "חבילת שפה (תוספות)"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:103
+msgid "general_addontype_lpaddon_plural"
+msgstr "חבילות שפה (תוספות)"
+
+#: models/addontype.php:83
+msgid "general_addontype_lpapp"
+msgstr "חבילות שפה (תוכנות)"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:102
+msgid "general_addontype_lpapp_plural"
+msgstr "חבילות שפה (תוכנות)"
+
+#: models/addontype.php:87
+msgid "general_addontype_plugin"
+msgstr "תוסף"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:104
+msgid "general_addontype_plugin_plural"
+msgstr "תוספי×"
+
+#: models/addontype.php:81
+msgid "general_addontype_search"
+msgstr "מנוע חיפוש"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:101
+msgid "general_addontype_search_plural"
+msgstr "מנועי חיפוש"
+
+#: models/addontype.php:77
+msgid "general_addontype_theme"
+msgstr "ערכת נוש×"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:99
+msgid "general_addontype_theme_plural"
+msgstr "ערכות נוש×"
+
+#: config/language.php:367
+#, fuzzy
+msgid "general_languages_all_locales"
+msgstr "All Locales"
+
+#: views/layouts/amo2009.thtml:249
+#, fuzzy
+msgid "header_brand_name"
+msgstr "Mozilla"
+
+#. %1$s is the application name. Example: Firefox
+#: views/elements/header.thtml:111 views/elements/header.thtml:122
+#: views/layouts/amo2009.thtml:248
+#, php-format
+msgid "header_home_tooltip"
+msgstr "חזור לדף הבית של תוספות %1$"
+
+#: views/elements/header.thtml:87
+msgid "header_main_firefox_header"
+msgstr "תוספות לפיירפוקס"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:218
+#, fuzzy
+msgid "header_main_firefox_header_with_logo"
+msgstr ""
+"Add-ons <em>for</em> <img alt=\"Firefox\" src=\"%1$s\" /> <strong>Firefox</"
+"strong>"
+
+#: views/elements/header.thtml:99
+msgid "header_main_header"
+msgstr "תוספות"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:242
+#, fuzzy
+msgid "header_main_header_with_logo"
+msgstr "Add-ons <img alt=\"Add-ons\" src=\"%1$s\" />"
+
+#: views/elements/header.thtml:90
+msgid "header_main_seamonkey_header"
+msgstr "תוספות לסימונקי"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:224
+#, fuzzy
+msgid "header_main_seamonkey_header_with_logo"
+msgstr ""
+"Add-ons <em>for</em> <img alt=\"seamonkey\" src=\"%1$s\" /> "
+"<strong>SeaMonkey</strong>"
+
+#: views/elements/header.thtml:93
+msgid "header_main_sunbird_header"
+msgstr "תוספות לס×נבירד"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:230
+#, fuzzy
+msgid "header_main_sunbird_header_with_logo"
+msgstr ""
+"Add-ons <em>for</em> <img alt=\"sunbird\" src=\"%1$s\" /> <strong>Sunbird</"
+"strong>"
+
+#: views/elements/header.thtml:96
+msgid "header_main_thunderbird_header"
+msgstr "תוספות לת'×נדבירד"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:236
+#, fuzzy
+msgid "header_main_thunderbird_header_with_logo"
+msgstr ""
+"Add-ons <em>for</em> <img alt=\"thunderbird\" src=\"%1$s\" /> "
+"<strong>Thunderbird</strong>"
+
+#: views/layouts/amo2009.thtml:205
+#, fuzzy
+msgid "header_navaccess_applications_menu"
+msgstr "Skip to other applications menu"
+
+#: views/layouts/amo2009.thtml:204
+#, fuzzy
+msgid "header_navaccess_categories_menu"
+msgstr "Skip to categories menu"
+
+#: views/layouts/amo2009.thtml:202
+#, fuzzy
+msgid "header_navaccess_main_content"
+msgstr "Skip to main content"
+
+#: views/layouts/amo2009.thtml:203
+#, fuzzy
+msgid "header_navaccess_search_form"
+msgstr "Skip to search form"
+
+#: views/elements/header.thtml:62
+msgid "header_navlink_addons"
+msgstr "×תר התוספות של Mozilla"
+
+#: views/elements/developers/sidebar.thtml:72
+#: views/elements/developers/myaddons.thtml:50 views/elements/header.thtml:159
+#: views/addons/display.thtml:378
+msgid "header_navlink_login"
+msgstr "כניסה"
+
+#: views/elements/header.thtml:156 views/layouts/amo2009.thtml:304
+msgid "header_navlink_logout"
+msgstr "התנתקות"
+
+#: views/elements/header.thtml:145 views/layouts/amo2009.thtml:303
+msgid "header_navlink_myaccount"
+msgstr "החשבון שלי"
+
+#: views/elements/header.thtml:158
+msgid "header_navlink_register"
+msgstr "הרשמה"
+
+#. %1 is the URL to the registration page
+#. %2 is the URL to the login page
+#: views/layouts/amo2009.thtml:278
+#, fuzzy
+msgid "header_navlink_register_or_login"
+msgstr "<a href=\"%1$s\">Register</a> or <a href=\"%2$s\">Log in</a>"
+
+#: views/layouts/amo2009.thtml:285
+#, fuzzy
+msgid "header_navlink_tools"
+msgstr "Tools"
+
+#. %s is the add-on name
+#: views/elements/collections_interactive_addon.thtml:62
+#: views/elements/amo2009/homepage_addon.thtml:77
+#: views/elements/addon_discussionheader.thtml:62
+#: views/elements/addon_listitem.thtml:67 views/elements/feature.thtml:84
+#: views/addons/category_landing.thtml:87 views/addons/browse_thumbs.thtml:60
+#, php-format
+msgid "img_preview_of"
+msgstr "תצוגה מקדימה של %s"
+
+#. %1 is the login URL for the link tag
+#. %2 is the link to an explanatory page.
+#: views/elements/amo2009/install.thtml:307 views/elements/install.thtml:255
+msgid "install_a_login_to_install"
+msgstr "<a href=\"%1$s\">התחבר</a> כדי להתקין ×ת התוספת הזו"
+
+#. %1 is the URL for the Experimental Add-ons section of the FAQ page
+#: views/elements/amo2009/install.thtml:283 views/elements/install.thtml:232
+#, fuzzy
+msgid "install_button_confirm_exp_install"
+msgstr ""
+"Let me install this experimental add-on. <a href=\"%1$s\">What's this?</a>"
+
+#. %1$s is the application name. Example: Firefox
+#. %2$s is an optional string used to specify a platform. Example: (Windows)
+#: views/elements/amo2009/install.thtml:128 views/elements/install.thtml:75
+#, php-format
+msgid "install_button_text"
+msgstr "הוסף ל-%s"
+
+#. %1 is the add-on name, %2 is the app name
+#: views/elements/amo2009/install.thtml:191
+#: views/elements/amo2009/install.thtml:206
+#: views/elements/amo2009/install.thtml:249
+#: views/elements/amo2009/install.thtml:298 views/elements/install.thtml:150
+#: views/elements/install.thtml:165 views/elements/install.thtml:202
+#: views/elements/install.thtml:246
+#, php-format
+msgid "install_button_title"
+msgstr "הוסף ×ת %1$sל%2$s"
+
+#. %1$s is the add-on name
+#: views/elements/amo2009/install.thtml:200 views/elements/install.thtml:159
+#, php-format
+msgid "install_download"
+msgstr "הורד ×ת %1$s"
+
+#: views/elements/amo2009/install.thtml:147 views/elements/install.thtml:94
+msgid "install_error_addon_not_found"
+msgstr "תוספת זו ×œ× ×–×ž×™× ×”."
+
+#: views/addons/dictionaries.thtml:65
+#, fuzzy
+msgid "langtools_a11y_tablesummary"
+msgstr "List of language packs and dictionaries."
+
+#: views/addons/dictionaries.thtml:47
+msgid "langtools_download_dictionary"
+msgstr "הורדת מילון"
+
+#: views/addons/dictionaries.thtml:48
+msgid "langtools_download_langpack"
+msgstr "הורד חבילת שפה"
+
+#: views/addons/dictionaries.thtml:63 controllers/components/amo.php:685
+#: controllers/addons_controller.php:1239
+msgid "langtools_header_dicts_and_langpacks"
+msgstr "×ž×™×œ×•× ×™× ×•×—×‘×™×œ×•×ª שפה"
+
+#: views/addons/dictionaries.thtml:44
+msgid "langtools_install_dictionary"
+msgstr "התקן מילון"
+
+#: views/addons/dictionaries.thtml:45
+msgid "langtools_install_langpack"
+msgstr "התקן חבילת שפה"
+
+#: views/addons/dictionaries.thtml:69
+msgid "langtools_tableheader_dictionary"
+msgstr "מילון"
+
+#: views/addons/dictionaries.thtml:70
+msgid "langtools_tableheader_langpack"
+msgstr "חבילת שפה"
+
+#: views/addons/dictionaries.thtml:68
+msgid "langtools_tableheader_language"
+msgstr "שפה"
+
+#: models/license.php:65
+#, fuzzy
+msgid "license_custom"
+msgstr "Custom License"
+
+#: config/bootstrap.php:303
+#, fuzzy
+msgid "licenses_bsd"
+msgstr "BSD License"
+
+#: config/bootstrap.php:298
+#, fuzzy
+msgid "licenses_gpl_2.0"
+msgstr "GNU General Public License, version 2.0"
+
+#: config/bootstrap.php:299
+#, fuzzy
+msgid "licenses_gpl_3.0"
+msgstr "GNU General Public License, version 3.0"
+
+#: config/bootstrap.php:300
+#, fuzzy
+msgid "licenses_lgpl_2.1"
+msgstr "GNU Lesser General Public License, version 2.1"
+
+#: config/bootstrap.php:301
+#, fuzzy
+msgid "licenses_lgpl_3.0"
+msgstr "GNU Lesser General Public License, version 3.0"
+
+#: config/bootstrap.php:302
+#, fuzzy
+msgid "licenses_mit"
+msgstr "MIT/X11 License"
+
+#: config/bootstrap.php:297
+#, fuzzy
+msgid "licenses_mpl_1.1"
+msgstr "Mozilla Public License, version 1.1"
+
+#: views/users/emailchange.thtml:51 views/users/delete.thtml:55
+#: views/users/delete.thtml:137 views/users/edit.thtml:74
+#: views/reviews/flag.thtml:54
+msgid "link_return_to_front_page"
+msgstr "לחץ ×›×ן כדי לשוב לעמוד הקדמי."
+
+#: views/elements/amo2009/addon_list_options.thtml:46
+#: views/elements/addon_list_options.thtml:46
+msgid "list_sortby_date"
+msgstr "ת×ריך"
+
+#: views/elements/amo2009/addon_list_options.thtml:47
+#: views/elements/addon_list_options.thtml:47
+msgid "list_sortby_downloads"
+msgstr "הורדות"
+
+#: views/elements/amo2009/addon_list_options.thtml:45
+#: views/elements/addon_list_options.thtml:45
+msgid "list_sortby_name"
+msgstr "×©× ×”×ª×•×¡×¤×ª"
+
+#: views/elements/amo2009/addon_list_options.thtml:48
+#: views/elements/addon_list_options.thtml:48
+msgid "list_sortby_rating"
+msgstr "דירוג"
+
+#: config/bootstrap.php:278
+#, fuzzy
+msgid "main_prettyname_fennec"
+msgstr "Fennec"
+
+#: config/bootstrap.php:274
+msgid "main_prettyname_firefox"
+msgstr "פיירפוקס"
+
+#: config/bootstrap.php:277
+msgid "main_prettyname_seamonkey"
+msgstr "סימונקי"
+
+#: config/bootstrap.php:276
+msgid "main_prettyname_sunbird"
+msgstr "ס×נבירד"
+
+#: config/bootstrap.php:275
+msgid "main_prettyname_thunderbird"
+msgstr "ת'×נדבירד"
+
+#: views/elements/addon_categories.thtml:52
+msgid "nav_category_dicts_langpacks"
+msgstr "×ž×™×œ×•× ×™× ×•×—×‘×™×œ×•×ª שפה"
+
+#: views/elements/addon_categories.thtml:55
+msgid "nav_category_themes"
+msgstr "ערכות נוש×"
+
+#: views/elements/app_chooser.thtml:47 views/layouts/amo2009.thtml:255
+msgid "other_apps_tooltip"
+msgstr "×ž×¦× ×ª×•×¡×¤×•×ª ×œ×™×™×©×•×ž×™× ×חרי×"
+
+#. In a user list: user 1, user 2, "others"
+#: views/helpers/addons_html.php:222
+msgid "other_users"
+msgstr "×חרי×"
+
+#: controllers/pages_controller.php:90
+#, fuzzy
+msgid "page_title_appversions"
+msgstr "Application Versions"
+
+#: controllers/pages_controller.php:115
+#, fuzzy
+msgid "page_title_collector"
+msgstr "Add-on Collector"
+
+#: controllers/pages_controller.php:117
+#, fuzzy
+msgid "page_title_collector_faq"
+msgstr "Add-on Collector FAQ"
+
+#: controllers/pages_controller.php:119
+#, fuzzy
+msgid "page_title_collector_features"
+msgstr "Add-on Collector Features"
+
+#: controllers/pages_controller.php:122
+#, fuzzy
+msgid "page_title_collector_firstrun"
+msgstr "Welcome to the Add-on Collector"
+
+#: controllers/pages_controller.php:92
+#, fuzzy
+msgid "page_title_credits"
+msgstr "Credits"
+
+#: controllers/pages_controller.php:113
+#, fuzzy
+msgid "page_title_developer_faq"
+msgstr "Developer FAQ"
+
+#: controllers/pages_controller.php:111
+#, fuzzy
+msgid "page_title_faq"
+msgstr "Frequently Asked Questions"
+
+#: controllers/pages_controller.php:94
+#, fuzzy
+msgid "page_title_fashionyourfirefox_faq"
+msgstr "Fashion your Firefox FAQ"
+
+#: controllers/pages_controller.php:101
+#, fuzzy
+msgid "page_title_policy"
+msgstr "Add-ons Policy"
+
+#: controllers/pages_controller.php:103
+#, fuzzy
+msgid "page_title_privacy"
+msgstr "Mozilla Privacy Policy"
+
+#: controllers/pages_controller.php:105
+#, fuzzy
+msgid "page_title_review_guide"
+msgstr "Review Guidelines"
+
+#: controllers/pages_controller.php:107
+#, fuzzy
+msgid "page_title_sandbox"
+msgstr "Sandbox Review System"
+
+#: controllers/pages_controller.php:109
+#, fuzzy
+msgid "page_title_submissionhelp"
+msgstr "Submission Help"
+
+#: views/pages/appversions.thtml:87
+msgid "pages_appversions_guid"
+msgstr "מזהה GUID"
+
+#: views/pages/appversions.thtml:79 controllers/pages_controller.php:90
+msgid "pages_appversions_header"
+msgstr "גירס×ות ×™×©×•× ×—×•×§×™×•×ª"
+
+#: views/pages/appversions.thtml:80
+msgid "pages_appversions_intro"
+msgstr ""
+"תוספות שנשלחות ×ל ×תר התוספות של Mozilla חייבות לכלול קובץ install.rdf ×¢× "
+"לפחות ×חת מהתוכנות הב×ות נתמכות. רק הגירס×ות הרשומות בהמשך מותרות לתוכנות "
+"×לו."
+
+#. %s is a full <a> tag
+#: views/pages/appversions.thtml:93
+#, php-format
+msgid "pages_appversions_required_files"
+msgstr ""
+"×× ×”×ª×•×›× ×” הנתמכת ×œ× ×“×•×¨×©×ª קובץ install.rdf, ×תה חייב עדיין לכלול ×ותו ×¢× "
+"המ××¤×™×™× ×™× ×”× ×“×¨×©×™× ×›×¤×™ שמצוין ב%s."
+
+#. this is the text inside of an <a> tag for pages_appversions_required_files. This
+#. should be fixed.
+#: views/pages/appversions.thtml:93
+msgid "pages_appversions_required_files_link"
+msgstr "×›×ן"
+
+#: views/pages/appversions.thtml:88
+msgid "pages_appversions_versions"
+msgstr "גירס×ות"
+
+#: views/pages/policy.thtml:51
+msgid "pages_policy_sandbox_link"
+msgstr "דף פרטי ×רגז החול"
+
+#: views/elements/pagination.thtml:53
+msgid "pagination_next_page"
+msgstr "הב×"
+
+#: views/elements/pagination.thtml:52
+msgid "pagination_previous_page"
+msgstr "קוד×"
+
+#: views/elements/recaptcha.thtml:65
+msgid "recaptcha_enter_both_words"
+msgstr ""
+"הכנס בבקשה ×ת <strong>שתי המילי×</strong> שמופיעות למטה, <strong>וביניהן "
+"רווח</strong>."
+
+#: views/elements/recaptcha.thtml:83
+msgid "recaptcha_enter_here"
+msgstr "הכנס ×›×ן ×ת התשובה שלך:"
+
+#: views/elements/recaptcha.thtml:74
+#, fuzzy
+msgid "recaptcha_enter_whatyouhear"
+msgstr "Please type what you hear."
+
+#. %1 is the link switching refreshing the captcha
+#. %2 is the link switching to a text captcha
+#: views/elements/recaptcha.thtml:77
+#, fuzzy
+msgid "recaptcha_hardtohear_text"
+msgstr ""
+"If this is hard to understand, you can <a href=\"%1$s\">listen to something "
+"else</a> or <a href=\"%2$s\">switch back to text</a>."
+
+#. %1 is the link switching refreshing the captcha
+#. %2 is the link switching to an audio captcha
+#: views/elements/recaptcha.thtml:68
+#, fuzzy
+msgid "recaptcha_hardtoread_text"
+msgstr ""
+"If this is hard to read, you can <a href=\"%1$s\">try different words</a> or "
+"<a href=\"%2$s\">listen to something</a> instead."
+
+#: views/users/register.thtml:105
+msgid "recaptcha_label"
+msgstr "×”×× ×תה ×נושי?"
+
+#: views/users/register.thtml:106
+msgid "recaptcha_whatsthis"
+msgstr "מה זה?"
+
+#: controllers/reviews_controller.php:559
+msgid "review_flag_error"
+msgstr "סימון על שגי××” בסקירה זו!"
+
+#: models/reviews_moderation_flag.php:69
+#, fuzzy
+msgid "review_flag_reason_bug_support"
+msgstr "Misplaced bug report or support request"
+
+#: views/reviews/display.thtml:103 views/reviews/display.thtml:186
+#, fuzzy
+msgid "review_flag_reason_instructions"
+msgstr "Report this review (select a reason)"
+
+#: models/reviews_moderation_flag.php:67
+#, fuzzy
+msgid "review_flag_reason_language"
+msgstr "Inappropriate language/dialog"
+
+#: models/reviews_moderation_flag.php:71
+#, fuzzy
+msgid "review_flag_reason_other"
+msgstr "Other (please specify)"
+
+#: models/reviews_moderation_flag.php:65
+#, fuzzy
+msgid "review_flag_reason_spam"
+msgstr "Spam or otherwise non-review content"
+
+#: views/reviews/display.thtml:91 views/reviews/display.thtml:175
+#: controllers/reviews_controller.php:555
+msgid "review_flag_success"
+msgstr "תודה; סקירה זו סומנה ל×ישור העורך."
+
+#: views/reviews/display.thtml:41
+msgid "review_flag_this"
+msgstr "דווח על סקירה זו"
+
+#: views/reviews/display.thtml:42
+msgid "review_flag_this_titletip"
+msgstr ""
+"×”×× ×”×¡×§×™×¨×” הזו ×œ× ×”×•×œ×ž×ª, ×œ× ×ž×“×•×™×§×ª ×ו זבל? ליץ ×›×ן כדי לסמן ×ותה לסקירת עורך."
+
+#. %1 is the URL of the support section, %2 for the review guidelines
+#: views/reviews/add.thtml:53
+msgid "review_guidelines_short"
+msgstr ""
+"<p>×”× ×” כמה טיפי×:</p><ul><li>כתוב ×›×ילו ×תה מספר לחברך על הניסיון שלך ×¢× "
+"התוספת. תן ×¤×¨×˜×™× ×ž×“×•×™×§×™×, כגון ×לו תכונות ×הבת ו/×ו שנ×ת, ×יך נוח להשתמש "
+"בה, וכל חיסרון שיש בה. המנע משפה כללית למשל קרי×ות בסגנון \"גדול\" ×ו \"גרוע"
+"\" בלי לתת סיבות לכך</li><li>×ל ×ª×¤×¨×¡× ×“×™×•×•×— על ב××’×™× ×‘×¡×§×™×¨×•×ª. ×נחנו ×œ× "
+"מ××¤×©×¨×™× ×œ×ž×¤×ª×—×™ התוספות לצפות בכתובת הדו×\"ל שלך ×•×”× ×ולי יצטרכו ליצור ×יתך "
+"קשר כדי לפתור ×ת הבעיה שלך. בקר ב<a href=\"%1$s\">×יזור התמיכה</a> כדי ×œ×ž×¦×•× "
+"היכן תוכל לקבל .</li><li>שמור בבקשה על נקיון הסקירות, המנע משימוש בשפה ש××™× ×” "
+"הולמת ו×ל ×ª×¤×¨×¡× ×ž×™×“×¢ ×ישי.</li></ul><p>×§×¨× ×ת <a href=\"%2$s\">×§×•×™× ×ž× ×—×™× "
+"לסקירה</a> בשביל עוד ×¤×¨×˜×™× ×¢×œ סקירות של משתמשי×.</p>"
+
+#. %1 is the add-on name
+#: views/reviews/flag.thtml:56 views/reviews/display.thtml:55
+#: views/reviews/review_added.thtml:50
+#, php-format
+msgid "reviews_header"
+msgstr "סקירות עבור %s"
+
+#: controllers/addons_controller.php:435
+msgid "rss_featuredaddons"
+msgstr "תוספות מככבות"
+
+#: controllers/addons_controller.php:432
+msgid "rss_newestaddons"
+msgstr "תוספות חדשות ביותר"
+
+#: controllers/addons_controller.php:434
+#, fuzzy
+msgid "rss_popularaddons"
+msgstr "Popular Add-ons"
+
+#: controllers/addons_controller.php:433
+msgid "rss_updatedaddons"
+msgstr "תוספות שעודכנו"
+
+#: views/elements/search_mini.thtml:70
+#, fuzzy
+msgid "search"
+msgstr "Search"
+
+#: views/search/collections.thtml:51
+#, fuzzy
+msgid "search_collections_header"
+msgstr "Collection Search Results"
+
+#: controllers/search_controller.php:297
+#, fuzzy
+msgid "search_collections_pagetitle"
+msgstr "Collection Search Results"
+
+#: controllers/search_controller.php:99
+msgid "search_disabled"
+msgstr "החיפוש ×ינו זמין כרגע. בבקשה נסה שוב מ×וחר יותר."
+
+#: views/elements/amo2009/search.thtml:188 views/elements/search.thtml:187
+#: views/elements/search_mini.thtml:54
+msgid "search_form_all_addons"
+msgstr "כל התוספות"
+
+#. This string is in the main category dropdown when searching
+#: views/elements/amo2009/search.thtml:204
+#, fuzzy
+msgid "search_form_all_collections"
+msgstr "all collections"
+
+#: views/elements/amo2009/search.thtml:184
+#: views/elements/amo2009/search.thtml:385
+#: views/elements/amo2009/search.thtml:408 views/elements/search.thtml:171
+#: views/elements/search.thtml:183 views/elements/search_mini.thtml:43
+#: views/elements/search_mini.thtml:49 views/layouts/mozilla.thtml:188
+msgid "search_form_default_text"
+msgstr "חיפוש תוספות"
+
+#: views/elements/amo2009/search.thtml:184
+#: views/elements/amo2009/search.thtml:404
+#, fuzzy
+msgid "search_form_default_text_collections"
+msgstr "search for collections"
+
+#: views/elements/amo2009/search.thtml:206 views/elements/search.thtml:202
+msgid "search_form_submit_tooltip"
+msgstr "חיפוש תוספות"
+
+#: views/elements/amo2009/search.thtml:184 views/elements/search.thtml:183
+#: views/elements/search_mini.thtml:49
+msgid "search_form_tooltip"
+msgstr "לחץ כדי להכנס למ×פייני החיפוש"
+
+#: views/elements/amo2009/search.thtml:186 views/elements/search.thtml:185
+#: views/elements/search_mini.thtml:52
+msgid "search_form_within"
+msgstr "בתוך"
+
+#: views/addons/searchengines.thtml:118
+msgid "search_landing_all_search_engines"
+msgstr "כל מנועי החיפוש"
+
+#: views/addons/searchengines.thtml:114
+msgid "search_landing_browse_search_engines"
+msgstr "עיין במנועי חיפוש"
+
+#: views/search/collections.thtml:58 views/search/index.thtml:59
+msgid "search_nothing_found"
+msgstr "×œ× × ×ž×¦×ו תוצ×ות."
+
+#: controllers/search_controller.php:185
+msgid "search_pagetitle"
+msgstr "חפש תוספות"
+
+#: controllers/search_controller.php:242
+msgid "search_rss_description"
+msgstr "הזנת תוצ×ות חיפוש"
+
+#. %s is the terms the user is searching for (a string)
+#: controllers/search_controller.php:241
+#, php-format
+msgid "search_rss_results_for"
+msgstr "תוצ×ות חיפוש עבור %s"
+
+#: views/elements/header.thtml:154 views/layouts/amo2009.thtml:296
+msgid "sidebar_navlink_admin_tools"
+msgstr "כלי מנהל"
+
+#: views/elements/header.thtml:146 views/layouts/amo2009.thtml:288
+msgid "sidebar_navlink_developer_tools"
+msgstr "כלי מפתח"
+
+#: views/elements/header.thtml:148 views/layouts/amo2009.thtml:290
+msgid "sidebar_navlink_editor_tools"
+msgstr "כלי עריכה"
+
+#: views/layouts/amo2009.thtml:302
+msgid "sidebar_navlink_welcome"
+msgstr "ברוך הב×"
+
+#. %s is the user's name
+#: views/layouts/amo2009.thtml:302
+#, php-format
+msgid "sidebar_navlink_welcome_name"
+msgstr "ברוך הב×, %s"
+
+#: views/elements/pitch.thtml:50 views/elements/pitch.thtml:55
+msgid "sidebar_pitch_dictionary"
+msgstr "מילון"
+
+#: views/elements/pitch.thtml:72
+msgid "sidebar_pitch_featured_addons"
+msgstr "תוספות מ×ופינות"
+
+#: views/elements/pitch.thtml:61
+msgid "sidebar_pitch_looking_for"
+msgstr "×× ×™ מחפש:"
+
+#: views/elements/pitch.thtml:70
+msgid "sidebar_pitch_newest_addons"
+msgstr "התוספות החדשות ביותר"
+
+#: views/elements/pitch.thtml:49
+msgid "sidebar_pitch_search"
+msgstr "תוסף חיפוש"
+
+#: views/elements/pitch.thtml:69
+msgid "sidebar_pitch_subscribe_to"
+msgstr "הרשמה ל-"
+
+#: views/elements/pitch.thtml:48 views/elements/pitch.thtml:54
+msgid "sidebar_pitch_theme"
+msgstr "ערכת נוש×"
+
+#: views/elements/pitch.thtml:71
+msgid "sidebar_pitch_updated_addons"
+msgstr "תוספות שעודכנו"
+
+#. %1$s is a number
+#: views/helpers/localization.php:65 views/developers/versions_edit.thtml:95
+#: views/addons/dictionaries.thtml:92
+#, php-format
+msgid "size_kb"
+msgstr "%1$s KB"
+
+#: views/elements/amo2009/stars.thtml:57 views/elements/stars.thtml:63
+msgid "stars_not_yet_rated"
+msgstr "×˜×¨× ×“×•×¨×’"
+
+#. %1 is the number of stars this add-on has
+#: views/elements/amo2009/stars.thtml:49 views/elements/stars.thtml:54
+#, php-format
+msgid "stars_rated_x_outof_5"
+msgstr "מדורג %s מתוך 5 כוכבי×"
+
+#: views/statistics/addon.thtml:59
+msgid "statistics_addon_dashboard_link"
+msgstr "דף פתיחה של הלוח"
+
+#: views/statistics/addon.thtml:58
+msgid "statistics_addon_developertools_link"
+msgstr "כלי מפתח"
+
+#: views/statistics/addon.thtml:53
+msgid "statistics_addon_switch"
+msgstr "החלף תוספת"
+
+#. This is a date format.
+#. http://php.net/strftime
+#: views/statistics/rss/summary.thtml:54 views/statistics/addon.thtml:181
+msgid "statistics_date_shortmonth"
+msgstr "חודש, יו×"
+
+#. This is a date format.
+#. http://php.net/strftime
+#: views/statistics/rss/summary.thtml:40 views/statistics/addon.thtml:152
+msgid "statistics_date_shortmonthwithyear"
+msgstr "חודש, יו×, שנה"
+
+#. This is a date format.
+#. http://php.net/strftime
+#: views/statistics/rss/summary.thtml:41 views/statistics/rss/summary.thtml:48
+#: views/statistics/addon.thtml:161 views/statistics/addon.thtml:172
+msgid "statistics_date_weekdayshortmonth"
+msgstr "×™×•× ×‘×©×‘×•×¢, חודש, יו×"
+
+#. %1$s is an add-on name and version. Example: Add-on 3.5
+#: controllers/components/stats.php:519
+#, php-format
+msgid "statistics_events_addon_created"
+msgstr "%1$s נוצר"
+
+#. %1$s is an application name and version. Example: Firefox 3.5
+#: controllers/components/stats.php:500
+#, php-format
+msgid "statistics_events_app_released"
+msgstr "%1$s שוחרר"
+
+#: views/statistics/addon.thtml:71
+msgid "statistics_help_close_link"
+msgstr "סגור"
+
+#: views/statistics/addon.thtml:60
+msgid "statistics_help_link"
+msgstr "עזרה"
+
+#: views/statistics/index.thtml:83
+msgid "statistics_index_anotheraddon"
+msgstr "×ו בחר תוספת ×חרת"
+
+#: views/statistics/index.thtml:85
+msgid "statistics_index_anotheraddon_public"
+msgstr "×ו בחר תוספת ×¢× ×¡×˜×™×¡×˜×™×§×” ציבורית"
+
+#: views/statistics/index.thtml:71
+msgid "statistics_index_myaddons"
+msgstr "בחר ×חת מהתוספות שלך כדי לצפות בסטיסטיקות שלה"
+
+#: views/statistics/index.thtml:89
+msgid "statistics_index_selectaddon"
+msgstr "בחר תוספת כדי לצפות בסטיסטיקות שלה"
+
+#: views/statistics/index.thtml:91
+msgid "statistics_index_selectaddon_public"
+msgstr "בחר תוספת ×¢× ×¡×˜×™×¡×˜×™×§×•×ª ציבוריות"
+
+#: views/statistics/index.thtml:39
+msgid "statistics_index_title"
+msgstr "לוח סטיסטיקות"
+
+#: views/statistics/index.thtml:97
+msgid "statistics_index_view_button"
+msgstr "צפה בסטיסטיקות"
+
+#: views/statistics/addon.thtml:222 controllers/statistics_controller.php:247
+#, fuzzy
+msgid "statistics_js_download_csv"
+msgstr "View this table in CSV format"
+
+#: controllers/statistics_controller.php:246
+msgid "statistics_js_dropdowns_none"
+msgstr "×ין"
+
+#: controllers/statistics_controller.php:245
+msgid "statistics_js_dropdowns_removeplot"
+msgstr "הסר ×ת ×”×ª×¨×©×™× ×”×–×”"
+
+#: controllers/statistics_controller.php:248
+#, fuzzy
+msgid "statistics_js_groupby_selector_date"
+msgstr "Group by: Day"
+
+#: controllers/statistics_controller.php:251
+#, fuzzy
+msgid "statistics_js_groupby_selector_month"
+msgstr "Group by: Month"
+
+#: controllers/statistics_controller.php:249
+#, fuzzy
+msgid "statistics_js_groupby_selector_week"
+msgstr "Group by: Week"
+
+#: controllers/statistics_controller.php:250
+#, fuzzy
+msgid "statistics_js_groupby_selector_week_over_week"
+msgstr "Compare by: Week"
+
+#: controllers/statistics_controller.php:260
+msgid "statistics_js_plotselection_foundinrange"
+msgstr "%s נמצ×ו בטווח"
+
+#: controllers/statistics_controller.php:270
+msgid "statistics_js_plotselection_options_addplot_name"
+msgstr "הוסף תרשי×"
+
+#: controllers/statistics_controller.php:271
+msgid "statistics_js_plotselection_options_addplot_tooltip"
+msgstr "הוסף ×ª×¨×©×™× ×חר לגרף ×–×”"
+
+#: controllers/statistics_controller.php:261
+msgid "statistics_js_plotselection_options_count_name_checked"
+msgstr "הסתר מונה כללי"
+
+#: controllers/statistics_controller.php:262
+msgid "statistics_js_plotselection_options_count_name_unchecked"
+msgstr "הצג מונה כללי"
+
+#: controllers/statistics_controller.php:263
+#, fuzzy
+msgid "statistics_js_plotselection_options_count_tooltip"
+msgstr "Plot the total count on this graph"
+
+#: controllers/statistics_controller.php:275
+msgid "statistics_js_plotselection_options_csv_name"
+msgstr "צפה במידע (CSV)"
+
+#: controllers/statistics_controller.php:276
+msgid "statistics_js_plotselection_options_csv_tooltip"
+msgstr "הורד קובץ CSV ×¢× ×”×ž×™×“×¢ ×”×–×”"
+
+#: controllers/statistics_controller.php:267
+msgid "statistics_js_plotselection_options_events_addon_name_checked"
+msgstr "הסתר ×ת ×”××™×¨×•×¢×™× ×©×œ %s "
+
+#: controllers/statistics_controller.php:268
+msgid "statistics_js_plotselection_options_events_addon_name_unchecked"
+msgstr "הצג ×ת ×”××™×¨×•×¢×™× ×©×œ %s "
+
+#: controllers/statistics_controller.php:269
+msgid "statistics_js_plotselection_options_events_addon_tooltip"
+msgstr "הצג ×ת ת×ריכי השחרור של התוספות על התרשימי×"
+
+#: controllers/statistics_controller.php:264
+msgid "statistics_js_plotselection_options_events_firefox_name_checked"
+msgstr "הסתר ×ת ×ירועי פיירפוקס"
+
+#: controllers/statistics_controller.php:265
+msgid "statistics_js_plotselection_options_events_firefox_name_unchecked"
+msgstr "הצג ×ת ×רועי פיירפוקס"
+
+#: controllers/statistics_controller.php:266
+msgid "statistics_js_plotselection_options_events_firefox_tooltip"
+msgstr "הצג ×ת ת×ריכי השחרור של פיירפוקס על התרשימי×"
+
+#: controllers/statistics_controller.php:272
+msgid "statistics_js_plotselection_options_resize_name_checked"
+msgstr "×¦×ž×¦× ×’×¨×£"
+
+#: controllers/statistics_controller.php:273
+msgid "statistics_js_plotselection_options_resize_name_unchecked"
+msgstr "הרחב גרף"
+
+#: controllers/statistics_controller.php:274
+msgid "statistics_js_plotselection_options_resize_tooltip"
+msgstr "שנה גודל גרף"
+
+#: controllers/statistics_controller.php:254
+msgid "statistics_js_plotselection_selector_adu"
+msgstr "פעילות ×ž×©×ª×ž×©×™× ×™×•×ž×™×ª"
+
+#: controllers/statistics_controller.php:256
+msgid "statistics_js_plotselection_selector_application"
+msgstr "יישו×"
+
+#: controllers/statistics_controller.php:259
+msgid "statistics_js_plotselection_selector_custom"
+msgstr "חופשי"
+
+#: controllers/statistics_controller.php:253
+msgid "statistics_js_plotselection_selector_downloads"
+msgstr "הורדות"
+
+#: controllers/statistics_controller.php:258
+msgid "statistics_js_plotselection_selector_os"
+msgstr "מערכת הפעלה"
+
+#: controllers/statistics_controller.php:257
+msgid "statistics_js_plotselection_selector_status"
+msgstr "מצב תוספת"
+
+#: controllers/statistics_controller.php:252
+msgid "statistics_js_plotselection_selector_summary"
+msgstr "סיכו×"
+
+#: controllers/statistics_controller.php:255
+msgid "statistics_js_plotselection_selector_version"
+msgstr "גירסת תוספת"
+
+#: controllers/components/stats.php:398
+msgid "statistics_longnames_application"
+msgstr "יישו×"
+
+#: controllers/components/stats.php:400
+msgid "statistics_longnames_os"
+msgstr "מערכת הפעלה"
+
+#: controllers/components/stats.php:399
+msgid "statistics_longnames_status"
+msgstr "מצב תוספת"
+
+#: controllers/components/stats.php:401
+msgid "statistics_longnames_unknown"
+msgstr "×œ× ×™×“×•×¢"
+
+#: controllers/components/stats.php:397
+msgid "statistics_longnames_version"
+msgstr "גירסת תוספת"
+
+#: views/statistics/addon.thtml:118
+msgid "statistics_notice_data_insufficient"
+msgstr "×ין עדיין מספיק מידע להציג בגרף ×–×”. שוב בבקשה מ×וחר יותר."
+
+#: views/statistics/addon.thtml:130
+msgid "statistics_notice_data_none"
+msgstr "עדיין ×ין לנו מידע על התוספת שלך. חזור בבקשה עוד מספר ימי×."
+
+#: views/statistics/addon.thtml:41
+msgid "statistics_notice_data_updating"
+msgstr ""
+"הסטיסטיקות של התוספת כרגע בתהליך עדכון. המידע ×”×חרון ×ולי ×™×”×™×” חלקי "
+"×›×©×”×ª×¡×¨×™×˜×™× ×©×œ× ×• ×¢×•×‘×“×™× ×›×“×™ לעדכן ×ותו. בדוק שוב בעוד כמה דקות."
+
+#: views/statistics/addon.thtml:136
+msgid "statistics_notice_disabled"
+msgstr "לוח הסטיסטיקות כרגע מנוטרל. נסה שוב מ×וחר יותר."
+
+#: views/statistics/addon.thtml:123
+msgid "statistics_notice_nojavascript"
+msgstr "×’'×ווהסקריפט צריך להיות מ×ופשר כדי לצפות ×‘×’×¨×¤×™× ×‘×œ×•×— הסטיסטיקות."
+
+#: views/statistics/addon.thtml:44
+msgid "statistics_notice_settings_updated"
+msgstr "ההגדרות שלך התעדכנו!"
+
+#: controllers/statistics_controller.php:60
+#: controllers/statistics_controller.php:71
+#: controllers/statistics_controller.php:74
+#: controllers/statistics_controller.php:240
+msgid "statistics_pagetitle"
+msgstr "לוח סטיסטיקות"
+
+#: views/statistics/addon.thtml:99
+msgid "statistics_plot_legend_adu"
+msgstr "×ž×©×ª×ž×©×™× ×¤×¢×™×œ×™× ×œ×™×•×"
+
+#: views/statistics/addon.thtml:95
+msgid "statistics_plot_legend_downloads"
+msgstr "הורדות ליו×"
+
+#: views/statistics/addon.thtml:107
+msgid "statistics_plot_options_zoomin_alt"
+msgstr "התקרבות"
+
+#: views/statistics/addon.thtml:106
+msgid "statistics_plot_options_zoomin_title"
+msgstr "התקרבות לחודש"
+
+#: views/statistics/addon.thtml:110
+msgid "statistics_plot_options_zoomout_alt"
+msgstr "התרחקות"
+
+#: views/statistics/addon.thtml:109
+msgid "statistics_plot_options_zoomout_title"
+msgstr "התרחקות לחודש"
+
+#: controllers/statistics_controller.php:283
+#, php-format
+msgid "statistics_rss_description"
+msgstr "×¡×™×›×•× ×™×•×ž×™ של סטיסטיקות עבור %1$s"
+
+#: views/statistics/rss/summary.thtml:68
+msgid "statistics_rss_title_fulldate"
+msgstr "יו×, חודש, שנה"
+
+#: views/statistics/rss/summary.thtml:68
+#, php-format
+msgid "statistics_rss_title_statsfordate"
+msgstr "סטיסטיקות ל-%1$s"
+
+#: views/statistics/settings.thtml:49
+msgid "statistics_settings_access_description"
+msgstr ""
+"כברירת מחדל, רק ×תה ומוזילה ×™×›×•×œ×™× ×œ×’×©×ª למידע שבלוח שלך. ×תה יכול להפוך ×ותו "
+"לציבורי כך שכל ×חד יוכל לצפות במידע על התוספת שלך."
+
+#: views/statistics/settings.thtml:48
+msgid "statistics_settings_access_heading"
+msgstr "גישה ללוח"
+
+#: views/statistics/settings.thtml:51
+msgid "statistics_settings_access_private"
+msgstr "פרטי"
+
+#: views/statistics/settings.thtml:51
+msgid "statistics_settings_access_private_description"
+msgstr "רק ×תה ומוזילה ×™×›×•×œ×™× ×œ×¦×¤×•×ª בסטיסטיקות של התוספת ×”×–×ת"
+
+#: views/statistics/settings.thtml:52
+msgid "statistics_settings_access_public"
+msgstr "ציבורי"
+
+#: views/statistics/settings.thtml:52
+msgid "statistics_settings_access_public_description"
+msgstr "כל ×חד יכול לצפות בסטיסטיקות של התוספת ×”×–×ת"
+
+#: views/statistics/addon.thtml:251
+msgid "statistics_settings_change_link"
+msgstr "שנה הגדרות"
+
+#: views/statistics/addon.thtml:253
+msgid "statistics_settings_confidential"
+msgstr "בבקשה התייחס למידע זה כחסוי."
+
+#: views/statistics/addon.thtml:245
+msgid "statistics_settings_currently_private"
+msgstr "כרגע לוח ×–×” ×”×•× <b>פרטי</b>."
+
+#: views/statistics/addon.thtml:241
+msgid "statistics_settings_currently_public"
+msgstr "כרגע לוח ×–×” ×”×•× <b>ציבורי</b>."
+
+#: views/statistics/addon.thtml:246
+msgid "statistics_settings_locked_alt"
+msgstr "ננעל"
+
+#: views/statistics/settings.thtml:57
+msgid "statistics_settings_return_link"
+msgstr "חזור ללוח"
+
+#: views/statistics/settings.thtml:56
+msgid "statistics_settings_save_button"
+msgstr "שמור הגדרות"
+
+#: views/statistics/settings.thtml:46
+#, php-format
+msgid "statistics_settings_title"
+msgstr "מ×פייני לוח סטיסטיקות עבור %1$s"
+
+#: views/statistics/addon.thtml:242
+msgid "statistics_settings_unlocked_alt"
+msgstr "שוחרר"
+
+#: controllers/components/stats.php:405
+msgid "statistics_shortnames_application"
+msgstr "ישו×"
+
+#: controllers/components/stats.php:407
+msgid "statistics_shortnames_os"
+msgstr "מ\"ה"
+
+#: controllers/components/stats.php:406
+msgid "statistics_shortnames_status"
+msgstr "סט"
+
+#: controllers/components/stats.php:408
+msgid "statistics_shortnames_unknown"
+msgstr "×œ× ×™×“×•×¢"
+
+#: controllers/components/stats.php:404
+msgid "statistics_shortnames_version"
+msgstr "גיר'"
+
+#: views/statistics/rss/summary.thtml:42 views/statistics/addon.thtml:192
+msgid "statistics_summary_downloads_average"
+msgstr "מומצע הורדות יומי"
+
+#: views/statistics/rss/summary.thtml:39
+msgid "statistics_summary_downloads_heading"
+msgstr "הורדות"
+
+#: views/statistics/rss/summary.thtml:41 views/statistics/addon.thtml:171
+msgid "statistics_summary_downloads_lastcount"
+msgstr "מונה ×”×™×•× ×”×חרון"
+
+#: views/statistics/rss/summary.thtml:43 views/statistics/addon.thtml:199
+msgid "statistics_summary_downloads_lastweek"
+msgstr "הורדות בשבוע ×”×חרון"
+
+#: views/statistics/rss/summary.thtml:40 views/statistics/addon.thtml:151
+msgid "statistics_summary_downloads_total"
+msgstr "סה\"כ הורדות"
+
+#: views/statistics/rss/summary.thtml:40 views/statistics/addon.thtml:152
+#, php-format
+msgid "statistics_summary_downloads_total_sincedate"
+msgstr "מ××– %1$s"
+
+#: views/statistics/rss/summary.thtml:50 views/statistics/rss/summary.thtml:56
+#: views/statistics/addon.thtml:163 views/statistics/addon.thtml:183
+msgid "statistics_summary_nodata"
+msgstr "×ין עדיין מידע"
+
+#: views/statistics/rss/summary.thtml:60 views/statistics/addon.thtml:195
+msgid "statistics_summary_updatepings_average"
+msgstr "פעילות ×ž×©×ª×ž×©×™× ×™×•×ž×™×ª ממוצעת"
+
+#: views/statistics/rss/summary.thtml:52 views/statistics/addon.thtml:177
+msgid "statistics_summary_updatepings_changefromprevious"
+msgstr "שנה ×ž×”×¡×›×•× ×”×§×•×“×"
+
+#: views/statistics/rss/summary.thtml:54 views/statistics/addon.thtml:181
+#, php-format
+msgid "statistics_summary_updatepings_changefromprevious_ondate"
+msgstr "%1$s ב%2$s"
+
+#: views/statistics/rss/summary.thtml:45
+msgid "statistics_summary_updatepings_heading"
+msgstr "פעילות ×ž×©×ª×ž×©×™× ×™×•×ž×™×ª"
+
+#: views/statistics/rss/summary.thtml:46 views/statistics/addon.thtml:157
+msgid "statistics_summary_updatepings_total"
+msgstr "פעילות ×ž×©×ª×ž×©×™× ×™×•×ž×™×ª"
+
+#: views/statistics/rss/summary.thtml:48 views/statistics/addon.thtml:161
+#, php-format
+msgid "statistics_summary_updatepings_total_ondate"
+msgstr "על %1$s"
+
+#: views/statistics/rss/summary.thtml:61 views/statistics/addon.thtml:203
+#, fuzzy
+msgid "statistics_summary_updatepings_weekly_average"
+msgstr "Average Daily Users this Week"
+
+#. %s is a percentage, like '+22.33%'. It sits next to another number, so
+#. the implied meaning is 'percentage change' from the previous stat point.
+#: views/statistics/rss/summary.thtml:62 views/statistics/addon.thtml:205
+#, fuzzy
+msgid "statistics_summary_updatepings_weekly_change"
+msgstr "%s from last week"
+
+#: views/statistics/addon.thtml:65 controllers/statistics_controller.php:184
+#: controllers/statistics_controller.php:282
+#, php-format
+msgid "statistics_title_addon_stats"
+msgstr "סטיסטיקות של %1$s"
+
+#: views/addons/themes_landing.thtml:113
+msgid "themes_landing_all_themes"
+msgstr "כל ערכות הנוש×"
+
+#: views/addons/themes_landing.thtml:109
+msgid "themes_landing_browse_themes"
+msgstr "עיין בערכות הנוש×"
+
+#: views/users/edit.thtml:185
+msgid "user_change_email"
+msgstr "שנה כתובת דו×\"ל"
+
+#: views/users/edit.thtml:169
+msgid "user_change_password"
+msgstr "שינוי סיסמה"
+
+#: views/users/edit.thtml:96
+#, fuzzy
+msgid "user_change_password_or_email"
+msgstr "Change Password or Email"
+
+#: controllers/users_controller.php:197
+msgid "user_confirmationcode_resent"
+msgstr "קוד ×”×ימות נשלח שוב!"
+
+#. %1 is the email address, %2 is the URL of the user registration page
+#: views/users/delete.thtml:51
+#, fuzzy
+msgid "user_del_account_deleted"
+msgstr ""
+"Your user account %1$s has been successfully deleted. If you want to come "
+"back some time, you can re-register on the <a href=\"%2$s\">user "
+"registration page</a>."
+
+#: views/users/delete.thtml:102
+#, fuzzy
+msgid "user_del_community_sad"
+msgstr "The Mozilla Add-ons community is sad to see you go."
+
+#: views/users/delete.thtml:123
+#, fuzzy
+msgid "user_del_confirm_password"
+msgstr "Confirm Password"
+
+#: views/users/delete.thtml:134
+#, fuzzy
+msgid "user_del_deletenow"
+msgstr "Delete my user account now"
+
+#. %1 is the URL of the user's info page
+#: views/users/delete.thtml:64
+#, fuzzy
+msgid "user_del_error_addons"
+msgstr ""
+"You cannot delete your account if you are listed as an <a href=\"%1$s"
+"\">author of any add-ons</a>. To delete your account, please have another "
+"person in your development group delete you from the list of authors for "
+"your add-ons. Afterwards you will be able to delete your account here."
+
+#. %1 is a link to the amo-editors mailing list
+#: views/users/delete.thtml:71
+#, fuzzy
+msgid "user_del_error_addons_more_questions"
+msgstr "If you have additional questions, please contact %1$s for assistance."
+
+#: views/users/delete.thtml:78
+#, fuzzy
+msgid "user_del_error_checkbox"
+msgstr ""
+"You need to check the box \"I understand...\" before we can delete your "
+"account."
+
+#: views/users/delete.thtml:84
+#, fuzzy
+msgid "user_del_error_password"
+msgstr "Please enter your password correctly in order to perform this step."
+
+#. %1 is a link to the amo-admins mailing list
+#: views/users/delete.thtml:91
+#, fuzzy
+msgid "user_del_error_unknown"
+msgstr ""
+"An unknown error occured deleting your account. Please contact %1$s with the "
+"issue and we will delete it for you. We apologize for the inconvenience."
+
+#: views/users/delete.thtml:110
+#, fuzzy
+msgid "user_del_header_confirm_deletion"
+msgstr "Confirm account deletion"
+
+#. %1 is the user's email address
+#: views/users/delete.thtml:100
+#, fuzzy
+msgid "user_del_header_delete_account"
+msgstr "Delete User Account %1$s"
+
+#: views/users/delete.thtml:50
+#, fuzzy
+msgid "user_del_header_farewell"
+msgstr "Farewell!"
+
+#: views/users/delete.thtml:115
+#, fuzzy
+msgid "user_del_nologin"
+msgstr "You will not be able to log into Mozilla Add-ons anymore."
+
+#: views/users/delete.thtml:112
+#, fuzzy
+msgid "user_del_permanently_removed_means"
+msgstr ""
+"By clicking \"delete\" your account is going to be <strong>permanently "
+"removed</strong>. That means:"
+
+#: views/users/delete.thtml:116
+#, fuzzy
+msgid "user_del_reviews_anonymized"
+msgstr ""
+"Your reviews and ratings will not be deleted, but they will no longer be "
+"associated with you."
+
+#. %1 is a link to the amo-editors mailing list
+#: views/users/delete.thtml:104
+#, fuzzy
+msgid "user_del_specific_problem_editors"
+msgstr ""
+"If you have a specific problem we may help you with, please do not delete "
+"your account now, but contact us at %1$s and we will do our best to assist "
+"you in solving it."
+
+#: views/users/delete.thtml:130
+#, fuzzy
+msgid "user_del_understand_permanent"
+msgstr "I understand that this step cannot be undone."
+
+#: views/helpers/addons_html.php:192
+#, fuzzy
+msgid "user_deleted_nickname"
+msgstr "Deleted User"
+
+#. %1 is the new email address
+#: views/users/edit.thtml:71
+msgid "user_edit_confirm_email_sent"
+msgstr ""
+"הודעת דו×\"ל נשלחה ×ל %1$s כדי ל×שר ×ת כתובת הדו×\"ל החדשה שלך. כדי שהשינוי "
+"יכנס לתוקפו, עליך ללחוץ על הקישור שמופיע בהודעה. עד ××–, תוכל להתחבר ×¢× ×›×ª×•×‘×ª "
+"הדו×\"ל הנוכחית שלך."
+
+#: views/users/edit.thtml:201
+#, fuzzy
+msgid "user_edit_delete_user"
+msgstr "Delete user account"
+
+#. This contains the email sent to users when they signed up for a new
+#. account:
+#. %1 is the confirmation URL, %2 is the current app
+#: views/users/email/confirm_plain.thtml:6
+#, php-format
+msgid "user_email_confirm_account_nopass"
+msgstr ""
+"ברוך ×”×‘× ×œ×תר התוספות של %2$s.\n"
+"\n"
+"לפני שתוכל להשתמש בחשבון החדש שלך ×תה חייב להפעיל ×ותו - פעולה זו תבטיח ×›×™ "
+"כתובת הדו×\"ל שסיפקת נכונה ו×כן שייכת לך.\n"
+"כדי להפעיל ×ת החשבון, לחץ על הקישור שבהמשך ×ו בצע העתקה והדבקה שלו לתוך שורת "
+"הכתובת בדפדפן שלך:\n"
+"\n"
+"%1$s\n"
+"\n"
+"ל×חר שהחשבון שלך יופעל בהצלחה, תוכל לזרוק ×ת הודעת דו×ר ×לקטרוני זו.\n"
+"\n"
+"תודה שהצטרפת ×ל ×תר התוספות של %2$s\n"
+"-- צוות ×תר התוספות של %2$s"
+
+#. %1 is the confirmation url, %2 is the application name
+#: views/users/email/emailchange_plain.thtml:5
+msgid "user_email_confirm_emailchange"
+msgstr ""
+"התבקשת לשנות כתובת דו×\"ל עבור התוספת %2$s .\n"
+"\n"
+"על מנת ל×שר ×ת הכתובת החדשה, לחץ בבקשה על הקישור למטה ×ו העתק ×ותו בשלמותו "
+"והדבק לתוך שורת הכתובת של הדפדפן:\n"
+"\n"
+"%1$s\n"
+"\n"
+"יש לך 48 שעות ל×שר ×ת הכתובת החדשה. ×× ×ינך רוצה לשנות ×ת הכתובת, ×תה יכול "
+"×œ×”×ª×¢×œ× ×ž×”×•×“×¢×” זו.\n"
+"\n"
+"תודה!\n"
+"-- %2$s צוות התוספת"
+
+#: controllers/users_controller.php:168
+#, php-format
+msgid "user_email_confirm_subject"
+msgstr "תודה שהצטרפת ×ל Mozilla Add-ons"
+
+#. This is the password reset email
+#. %1 is the pw reset URL, %2 is the application
+#: views/users/email/pwreset_plain.thtml:5
+#, php-format
+msgid "user_email_pwreset"
+msgstr ""
+"×יפוס סיסמה ל×תר Mozilla Add-ons\n"
+"\n"
+"התקבלה בקשה ל×יפוס הסיסמה של חשבון ×–×” ב×תר addons.mozilla.org. כדי לשנות ×ת "
+"הסיסמה בבקשה לחץ על הקישור המצורף, ×ו הדבק ×ותו לתוך שורת הכתובת בדפדפן:\n"
+"\n"
+"%1$s\n"
+"\n"
+"×× ×œ× ×‘×™×§×©×ª ×ת הודעת דו×\"ל זו ×œ× × ×“×¨×©×ª ממך ×©×•× ×¤×¢×•×œ×” נוספת.\n"
+"\n"
+"בתודה,\n"
+"-- צוות ×”×תר Mozilla Add-ons"
+
+#: controllers/users_controller.php:245
+#, php-format
+msgid "user_email_pwreset_subject"
+msgstr "×פס ×ת הסיסמה שלך ב×תר התוספות"
+
+#: views/users/emailchange.thtml:50
+msgid "user_emailchange_error"
+msgstr "שגי××”!"
+
+#. %1 is the application name
+#: controllers/users_controller.php:533
+msgid "user_emailchange_subject"
+msgstr "×שר בבקשה ×ת שינו כתובת הדו×\"ל שלך בתוספת %1$s"
+
+#: views/users/emailchange.thtml:48
+msgid "user_emailchange_success"
+msgstr "בוצע בהצלחה!"
+
+#. %1 is the new email address
+#: views/users/emailchange.thtml:49
+msgid "user_emailchange_successful_description"
+msgstr "כתובת הדו×\"ל שלך שונתה בהצלחה. מעכשיו, השתמש ב- %1$s כדי להתחבר."
+
+#: views/users/edit.thtml:134 views/admin/users_edit.thtml:111
+#, fuzzy
+msgid "user_form_bio"
+msgstr "About me"
+
+#: views/users/edit.thtml:135 views/admin/users_edit.thtml:112
+#, fuzzy
+msgid "user_form_bio_description"
+msgstr ""
+"Introduce yourself to the community, if you like! This text will appear "
+"publicly on your user info page. Line breaks will be preserved, but no HTML "
+"is allowed."
+
+#: views/users/pwreset.thtml:77 views/users/register.thtml:73
+#: views/users/edit.thtml:181
+msgid "user_form_confirmpassword"
+msgstr "×•×•×“× ×¡×™×¡×ž×”"
+
+#: views/users/edit.thtml:145
+#, fuzzy
+msgid "user_form_display_collections"
+msgstr "Display the collections I have created in my user profile"
+
+#: views/users/edit.thtml:149
+#, fuzzy
+msgid "user_form_display_collections_fav"
+msgstr "Display my favorite collections in my user profile"
+
+#: views/users/edit.thtml:86
+#, php-format
+msgid "user_form_editprofile"
+msgstr "עריכת פרופיל משתמש עבור %s"
+
+#: views/users/pwreset.thtml:52 views/users/login.thtml:81
+#: views/users/register.thtml:63 views/users/edit.thtml:187
+msgid "user_form_email"
+msgstr "כתובת דו×\"ל"
+
+#: views/users/register.thtml:78 views/users/edit.thtml:103
+#: views/admin/users_edit.thtml:76
+msgid "user_form_firstname"
+msgstr "×©× ×¤×¨×˜×™"
+
+#: views/users/register.thtml:94 views/users/edit.thtml:119
+#: views/admin/users_edit.thtml:91
+msgid "user_form_hideemail"
+msgstr "הסתר כתובת דו×ר ×לקטרוני"
+
+#: views/users/register.thtml:98 views/users/edit.thtml:123
+#: views/admin/users_edit.thtml:99
+msgid "user_form_homepage"
+msgstr "כתובת ×תר"
+
+#: views/users/register.thtml:84 views/users/edit.thtml:109
+#: views/admin/users_edit.thtml:81
+msgid "user_form_lastname"
+msgstr "×©× ×ž×©×¤×—×”"
+
+#: controllers/users_controller.php:333
+msgid "user_form_login"
+msgstr "התחברות משתמש"
+
+#: views/users/pwreset.thtml:72 views/users/edit.thtml:176
+msgid "user_form_newpassword"
+msgstr "סיסמה חדשה"
+
+#: views/users/register.thtml:89 views/users/edit.thtml:114
+#: views/admin/users_edit.thtml:86
+msgid "user_form_nickname"
+msgstr "כינוי"
+
+#: views/users/edit.thtml:171
+msgid "user_form_oldpassword"
+msgstr "סיסמה ישנה"
+
+#: views/users/edit.thtml:97 views/users/edit.thtml:200
+#, fuzzy
+msgid "user_form_otheractions"
+msgstr "Other Actions"
+
+#: views/users/login.thtml:85 views/users/register.thtml:68
+msgid "user_form_password"
+msgstr "סיסמה"
+
+#: controllers/users_controller.php:93
+msgid "user_form_registration"
+msgstr "×¨×™×©×•× ×ž×©×ª×ž×© חדש"
+
+#: views/users/login.thtml:90
+msgid "user_form_remember_me"
+msgstr "זכור ×ותי על מחשב ×–×”"
+
+#: views/admin/users_edit.thtml:95
+msgid "user_form_showsandbox"
+msgstr "הצג ×ת ×רגז החול?"
+
+#: views/users/edit.thtml:205
+msgid "user_form_submit_edit"
+msgstr "שמירה"
+
+#: views/users/login.thtml:93
+msgid "user_form_submit_login"
+msgstr "התחברות"
+
+#: views/users/register.thtml:113
+msgid "user_form_submit_register"
+msgstr "הרשמה"
+
+#: views/users/info.thtml:75
+#, php-format
+msgid "user_info_usersince"
+msgstr "חבר ב×תר התוספות של %s מ××–"
+
+#: views/users/login.thtml:102
+msgid "user_login_register_link"
+msgstr "צור חשבון משתמש חדש"
+
+#: views/users/edit.thtml:160
+#, fuzzy
+msgid "user_notifications_item_compat"
+msgstr "Add-on Compatibility (strongly recommended)"
+
+#: views/users/edit.thtml:161
+#, fuzzy
+msgid "user_notifications_item_events"
+msgstr "Upcoming events and contests"
+
+#: views/users/edit.thtml:156
+#, fuzzy
+msgid "user_notifications_none_available"
+msgstr "There are currently no notifications available for you to configure."
+
+#: views/users/edit.thtml:158
+#, fuzzy
+msgid "user_notifications_select_topics"
+msgstr ""
+"From time to time, Mozilla may send you email about upcoming releases and "
+"add-on events. Please select the topics you are interested in below:"
+
+#: views/users/edit.thtml:164
+#, fuzzy
+msgid "user_notifications_specific_contact"
+msgstr ""
+"Mozilla reserves the right to contact you individually about specific "
+"concerns with your hosted add-ons."
+
+#: controllers/users_controller.php:543
+msgid "user_profile_edit_error"
+msgstr "×ירעו שגי×ות ×‘×©×™× ×•×™×™× ×©×‘×™×¦×¢×ª. בבקשה תקן ×ותן ושלח שוב."
+
+#: controllers/users_controller.php:540
+msgid "user_profile_saved"
+msgstr "הפרופיל עודכן."
+
+#: views/users/pwreset.thtml:65
+#, php-format
+msgid "user_pwreset_for_email"
+msgstr "×יפוס סיסמה עבור %s"
+
+#: controllers/users_controller.php:226
+msgid "user_pwreset_header"
+msgstr "×יפוס סיסמה"
+
+#: views/users/login.thtml:103
+msgid "user_pwreset_link"
+msgstr "שכחת ×ת סיסמתך?"
+
+#: controllers/users_controller.php:248
+msgid "user_pwreset_link_sent"
+msgstr "קישור ל×יפוס הסיסמה נשלח ×ל כתובת הדו×ר ×”×לקטרוני שלך."
+
+#: controllers/users_controller.php:304
+msgid "user_pwreset_okay"
+msgstr "הסיסמה ×ופסה בהצלחה."
+
+#: views/users/pwreset.thtml:82
+msgid "user_pwreset_submit_changepw"
+msgstr "החלף סיסמה"
+
+#: views/users/pwreset.thtml:57
+msgid "user_pwreset_submit_sendlink"
+msgstr "שלח קישור ×יפוס סיסמה"
+
+#: views/users/register_complete.thtml:51
+#, php-format
+msgid "user_register_amo_link"
+msgstr "%s תוספות"
+
+#. %1 is the user's email address, %2 is the current app
+#: views/users/activatefirst.thtml:49
+#, php-format
+msgid "user_register_click_confirm_link"
+msgstr ""
+"קישור להפעלת החשבון שלך נשלח בדו×\"ל לכתובת %1$s. הינך נדרש ללחוץ על קישור "
+"×–×” לפני שתוכל להתחבר ל×תר התוספות של %2$s."
+
+#. %1 is the user's email address
+#: views/users/register_complete.thtml:49
+#, php-format
+msgid "user_register_confirm_email_sent"
+msgstr ""
+"הודעת דו×ר ×לקטרוני נשלחה לכתובת %1$s לצורך ×ימות חשבונך. לפני שתוכל להיכנס, "
+"הינך נדרש להפעיל ×ת החשבון שלך ב×מצעות לחיצה על הקישור שבהודעת דו×\"ל זו."
+
+#: views/users/activatefirst.thtml:51
+msgid "user_register_confirmation_link_text"
+msgstr "נשלח שוב ×ת הודעת ×”×ימות"
+
+#: views/users/register_complete.thtml:47
+msgid "user_register_congratulations"
+msgstr "ברכות! החשבון שלך נוצר בהצלחה."
+
+#: views/users/register.thtml:50
+#, fuzzy
+msgid "user_register_details"
+msgstr ""
+"<p>Registration on AMO is <strong>not required</strong> if you simply want "
+"to download and install public add-ons.</p><p>You only need to register if:</"
+"p><ul><li>You want to submit reviews for add-ons</li><li>You are an add-on "
+"developer and want to upload your add-on for hosting on AMO</li></ul><p>Upon "
+"successful registration, you will be sent a confirmation email to the "
+"address you provided. Please follow the instructions there to confirm your "
+"account.</p><p>If you like, you can read our <a href='%1$s' title='Legal "
+"Notices'>Legal Notices</a> and <a href='%2$s' title='Privacy Policy'>Privacy "
+"Policy</a>.</p>"
+
+#. %1 is the link to the "resend confirmation code" page
+#: views/users/activatefirst.thtml:51
+#, php-format
+msgid "user_register_resend_confirmation_link"
+msgstr ""
+"×× ×œ× ×§×™×‘×œ×ª ×ת הודעת ×”×ימות בדו×\"ל, ×•×•×“× ×›×™ שירות הדו×\"ל שלך ×œ× ×¡×™×ž×Ÿ ×ת "
+"ההודעה בתור \"דו×ר זבל\" ×ו \"ספ××\". ×× ×™×© צורך, ×תה יכול לבקש ש%1$s לכתובת "
+"שצויינה מעלה. "
+
+#. %1 is the link to the Mozilla Add-ons front page
+#: views/users/register_complete.thtml:51
+#, php-format
+msgid "user_register_welcome"
+msgstr "תודה שנרשמת וברוך ×”×‘× ×ל %1$s!"
+
+#: views/users/register.thtml:49
+#, fuzzy
+msgid "user_register_welcome_header"
+msgstr "Welcome to addons.mozilla.org (AMO)!"
+
+#: views/users/register.thtml:81 views/users/edit.thtml:106
+#, fuzzy
+msgid "user_required_firstlast_or_nickname"
+msgstr "A first name, last name or nickname is required."
+
+#: views/users/edit.thtml:94 views/users/edit.thtml:142
+#, fuzzy
+msgid "user_tab_collections"
+msgstr "Collections"
+
+#: views/users/edit.thtml:95 views/users/edit.thtml:154
+#, fuzzy
+msgid "user_tab_notifications"
+msgstr "Notifications"
+
+#: views/users/edit.thtml:93 views/users/edit.thtml:101
+#, fuzzy
+msgid "user_tab_profile"
+msgstr "User Profile"
+
+#: controllers/users_controller.php:209
+msgid "user_verified_okay"
+msgstr "×ומת בהצלחה!"
+
+#: controllers/users_controller.php:723
+#, fuzzy
+msgid "users_delete_pagetitle"
+msgstr "Delete User Account"
+
+#: controllers/users_controller.php:414
+msgid "users_edit_pagetitle"
+msgstr "עריכת חשבון משתמש"
+
+#: views/users/info.thtml:71
+#, fuzzy
+msgid "users_info_aboutme"
+msgstr "About Me"
+
+#: views/users/info.thtml:96
+#, php-format
+msgid "users_info_addons_by_user"
+msgstr "תוספות מ×ת %1$s"
+
+#: views/users/info.thtml:51
+msgid "users_info_author_name"
+msgstr "ש×"
+
+#: views/users/info.thtml:48
+msgid "users_info_author_profile"
+msgstr "פרופיל משתמש"
+
+#. %s is the user name
+#: views/users/info.thtml:137
+#, fuzzy
+msgid "users_info_collections_by_user"
+msgstr "Collections by %s"
+
+#: views/users/info.thtml:66
+msgid "users_info_email"
+msgstr "כתובת דו×\"ל"
+
+#: views/users/info.thtml:155
+#, fuzzy
+msgid "users_info_fav_collections_by_user"
+msgstr "Favorite Collections"
+
+#: views/users/info.thtml:61
+msgid "users_info_homepage"
+msgstr "דף בית"
+
+#: views/users/info.thtml:56
+msgid "users_info_nickname"
+msgstr "כינוי"
+
+#: controllers/users_controller.php:707
+#, php-format
+msgid "users_info_pagetitle"
+msgstr "פרטי משתמש עבור %1$s"
+
+#. %1 is the user's name
+#: views/users/info.thtml:116
+#, fuzzy
+msgid "users_info_reviews_by_user"
+msgstr "Reviews by %s"
+
+#: controllers/users_controller.php:330 controllers/users_controller.php:332
+msgid "users_login_pagetitle"
+msgstr "כניסת משתמש"
+
+#. %1 is the link to the sandbox/policy explanation page
+#. This message is for a specific add-on not found
+#: views/users/login.thtml:53
+#, php-format
+msgid "users_login_sandbox_display_warning"
+msgstr ""
+"התוספת שחיפשת × ×ž×¦× ×›×¨×’×¢ ב×רגז החול. ×× ×§×™×™× ×‘×¨×©×•×ª×š חשבון ב×תר התוספות של "
+"Mozilla, בבקשה היכנס לחשבון, ×ו <a href=\"%1$s\">למד ×ודות ×ודות ×רגז החול</"
+"a>."
+
+#. %1 is the link to the sandbox/policy explanation page
+#. This message is for any given sandbox-related page not found
+#: views/users/login.thtml:56
+#, php-format
+msgid "users_login_sandbox_page_warning"
+msgstr ""
+"הדף שחיפשת × ×ž×¦× ×›×¨×’×¢ ב×רגז החול. ×× ×§×™×™× ×‘×¨×©×•×ª×š חשבון ב×תר התוספות של "
+"Mozilla, בבקשה היכנס לחשבון, ×ו <a href=\"%1$s\">למד ×ודות ×ודות ×רגז החול</"
+"a>."
+
+#: controllers/users_controller.php:223 controllers/users_controller.php:225
+msgid "users_pwreset_pagetitle"
+msgstr "×יפוס סיסמת משתמש"
+
+#: controllers/users_controller.php:90 controllers/users_controller.php:92
+msgid "users_register_pagetitle"
+msgstr "הרשמת משתמש חדש"
+
+#. %1$s is an addon name, like <a>Firebug</a>
+#. %2$s is a version number, like <a>1.2</a>
+#: views/versions/license.thtml:52
+#, fuzzy
+msgid "versions_license_header_source"
+msgstr "Source code license for %1$s %2$s"
+
+#: views/addons/category_landing.thtml:147
+#, fuzzy
+msgid "view_recently_added"
+msgstr "View all recently added"
+
+#: views/addons/category_landing.thtml:161
+#, fuzzy
+msgid "view_top_downloads"
+msgstr "View all top downloads"
+
+#: views/addons/category_landing.thtml:175
+#, fuzzy
+msgid "view_top_rated"
+msgstr "View all top rated"
+
+#, fuzzy
+#~ msgid "addon_slider_tooltip_next"
+#~ msgstr "Next Add-on"
+
+#, fuzzy
+#~ msgid "addon_slider_tooltip_previous"
+#~ msgstr "Previous Add-on"
+
+#~ msgid "addon_versions_getlatesttext"
+#~ msgstr "הגירסה ×”×חרונה תו×מת ל-"
+
+#~ msgid "addons_display_version_history"
+#~ msgstr "היסטורית גירס×ות מל××”"
+
+#~ msgid "addons_home_newest_header"
+#~ msgstr "החדש ביותר:"
+
+#~ msgid "addons_home_popular_header"
+#~ msgstr "×”×¤×•×¤×•×œ×¨×™×™× ×‘×™×•×ª×¨:"
+
+#~ msgid "addons_home_recommended_header"
+#~ msgstr "ההמלצה שלנו:"
+
+#~ msgid "addons_home_updated_header"
+#~ msgstr "עודכנו ל×חרונה:"
+
+#~ msgid "addons_home_view_all"
+#~ msgstr "צפה בהכל"
+
+#~ msgid "category_extra_allrecommended"
+#~ msgstr "הר××” ×ת כל התוספות המומלצות"
+
+#~ msgid "category_extra_highestrated"
+#~ msgstr "מדורגות גבוה ר×שונות"
+
+#~ msgid "category_extra_lastupdated"
+#~ msgstr "עודכנו ל×חרונה ר×שונות"
+
+#~ msgid "category_extra_mostpopular"
+#~ msgstr "הפופולריות ביותר ר×שונות"
+
+#, fuzzy
+#~ msgid "collections_detail_js_loading"
+#~ msgstr "Loading"
+
+#, fuzzy
+#~ msgid "collections_detail_more_info"
+#~ msgstr "Show More Info"
+
+#~ msgid "devcp_additem_firefox_notice"
+#~ msgstr ""
+#~ "גירסה זו של התוספת שלך ××™× ×” מוגדרת כתו×מת ל־פיירפוקס %1$s. מוזילה מצפה "
+#~ "שהגירסה הב××” של פיירפוקס תשוחרר בקרוב, לכן בדוק בבקשה ×ת התוספת שלך על "
+#~ "הגירסה החדשה ועדכן ×ת מידע הת×ימות שלה. תוכל ×œ×§×¨×•× ×¢×•×“ ×‘× ×•×©× <a href=\"%2"
+#~ "$s\">×›×ן</a>. רק רגע של תשומת לב ותוכל להמשיך ולשלוח ×ת גירס×ות ×ל "
+#~ "addons.mozilla.org."
+
+#~ msgid "devcp_addon_disabled_successfully"
+#~ msgstr "תוספת נוטרלה בהצלחה"
+
+#~ msgid "devcp_addon_edit_pagetitle"
+#~ msgstr "עריכת תוספת"
+
+#~ msgid "devcp_addon_enabled_successfully"
+#~ msgstr "תוספת ×ופשרה בהצלחה"
+
+#~ msgid "devcp_addon_field_description_displaytitle"
+#~ msgstr "תי×ור התוספת"
+
+#~ msgid "devcp_addon_field_eula_displaytitle"
+#~ msgstr "×”×¡×›× ×ž×©×ª×ž×© (EULA)"
+
+#~ msgid "devcp_addon_field_homepage_displaytitle"
+#~ msgstr "דף הבית של התוספת"
+
+#~ msgid "devcp_addon_field_name_displaytitle"
+#~ msgstr "×©× ×”×ª×•×¡×¤×ª"
+
+#~ msgid "devcp_addon_field_privacy_displaytitle"
+#~ msgstr "מדיניות פרטיות "
+
+#~ msgid "devcp_addon_field_summary_displaytitle"
+#~ msgstr "×¡×™×›×•× ×ª×•×¡×¤×ª"
+
+#~ msgid "devcp_addon_field_supportemail_displaytitle"
+#~ msgstr "דו×\"ל לתמיכה"
+
+#~ msgid "devcp_addon_field_supporturl_displaytitle"
+#~ msgstr "כתובת ×ינטרנט לתמיכה"
+
+#~ msgid "devcp_addon_field_versionnotes_displaytitle"
+#~ msgstr "הערות גירסה"
+
+#~ msgid "devcp_addon_nominate_pagetitle"
+#~ msgstr "הגשת תוספת"
+
+#~ msgid "devcp_addon_nominated_successfully"
+#~ msgstr "תוספת הוגשה בהצלחה!"
+
+#, fuzzy
+#~ msgid "devcp_addon_status_criteria_review"
+#~ msgstr "Several user reviews of the add-on (may be external reviews)."
+
+#~ msgid "devcp_addon_submission_makechanges"
+#~ msgstr ""
+#~ "בקר בעמוד של %1$s כדי לערוך ×©×™× ×•×™×™× ×‘×”×’×©×” שלך, ×ו %2$s כדי לחזור ללוח "
+#~ "בקרה למפתח ."
+
+#~ msgid "devcp_addon_submission_makechanges_devcp_link"
+#~ msgstr "לחץ ×›×ן"
+
+#~ msgid "devcp_addon_submission_makechanges_link"
+#~ msgstr "עריכת תוספת"
+
+#~ msgid "devcp_addon_submission_pending"
+#~ msgstr ""
+#~ " הגירסה ×”×–×ת מוקמה ב×רגז החול ×•×”×™× ×ž×—×›×” לסקירה של בוחני ×רגז החול ושל "
+#~ "עורך התוספות של מוזילה. ×תה תקבל הודעה בדו×\"ל כשהפעולה תבוצע."
+
+#~ msgid "devcp_addon_submission_sandbox_readmore"
+#~ msgstr "×תה יכול ×œ×§×¨×•× ×¢×•×“ ×ודות מערכת הסקירה של ×רגז החול %s."
+
+#~ msgid "devcp_addon_submission_sandbox_readmore_link"
+#~ msgstr "×›×ן"
+
+#~ msgid "devcp_addon_submission_sandboxed"
+#~ msgstr ""
+#~ "הגירסה ×”×–×ת מוקמה ב×רגז החול לשימוש ×ž×©×ª×ž×©×™× ×ž× ×•×¡×™×. כדי ×©×”×™× ×ª×•×¦×’ ב×תר "
+#~ "הציבורי ×תה צריך %s ×ת התוספת שלך ולעבור ×ת תהליך הסקירה."
+
+#~ msgid "devcp_addon_submission_sandboxed_nominate_link"
+#~ msgstr "הגש"
+
+#~ msgid "devcp_addon_submission_success"
+#~ msgstr "שליחת התוספת שלך הסתיימה בהצלחה."
+
+#~ msgid "devcp_addon_submission_trusted_public"
+#~ msgstr "×ž×©×•× ×©×”×ª×•×¡×¤×ª שלך ×מינה, הגירסה ×”×–×ת ×וטומטית מ×ושרת ל×זור הציבורי."
+
+#~ msgid "devcp_addon_submit_pagetitle"
+#~ msgstr "שלח תוספת"
+
+#~ msgid "devcp_addon_updated_successfully"
+#~ msgstr "תוספת עודכנה בהצלחה"
+
+#~ msgid "devcp_addon_upload_preview"
+#~ msgstr "×תה ×ולי תרצה %s להגדיל ×ת ההתעניינות בתוספת שלך."
+
+#~ msgid "devcp_addon_upload_preview_link"
+#~ msgstr "העלה תצוגה מקדימה"
+
+#~ msgid "devcp_author_lookup_none_found"
+#~ msgstr "מחבר ×œ× × ×ž×¦× [%s]"
+
+#~ msgid "devcp_author_lookup_remove"
+#~ msgstr "הסר"
+
+#~ msgid "devcp_button_cancel"
+#~ msgstr "בטל"
+
+#~ msgid "devcp_button_cancel_confirm"
+#~ msgstr "×”×× ×תה בטוח שברצונך לבטל ×ת השליחה?"
+
+#~ msgid "devcp_button_next"
+#~ msgstr "הב×"
+
+#~ msgid "devcp_change_addontype"
+#~ msgstr "שנה סוג תוספת:"
+
+#~ msgid "devcp_comments_updated"
+#~ msgstr "הערות המפתח עודכנו."
+
+#~ msgid "devcp_details_addpreview_link"
+#~ msgstr "הוסף תצוגה מקדימה"
+
+#~ msgid "devcp_details_author"
+#~ msgstr "מחבר"
+
+#~ msgid "devcp_details_authors"
+#~ msgstr "מחברי×"
+
+#~ msgid "devcp_details_authors_none"
+#~ msgstr "×ין"
+
+#~ msgid "devcp_details_categories"
+#~ msgstr "קטגוריות"
+
+#~ msgid "devcp_details_category"
+#~ msgstr "קטגוריה"
+
+#~ msgid "devcp_details_description"
+#~ msgstr "תי×ור"
+
+#~ msgid "devcp_details_disabled"
+#~ msgstr "מנוטרל"
+
+#~ msgid "devcp_details_guid"
+#~ msgstr "מזהה (GUID)"
+
+#~ msgid "devcp_details_header_details"
+#~ msgstr "פרטי×"
+
+#~ msgid "devcp_details_header_devcomments"
+#~ msgstr "הערות המפתח"
+
+#~ msgid "devcp_details_header_previews"
+#~ msgstr "תצוגות מקדימות"
+
+#~ msgid "devcp_details_header_versions"
+#~ msgstr "גירס×ות"
+
+#~ msgid "devcp_details_homepage"
+#~ msgstr "דף בית"
+
+#~ msgid "devcp_details_homepage_none"
+#~ msgstr "×ין"
+
+#~ msgid "devcp_details_preview_nocaption"
+#~ msgstr "×ין כותרת"
+
+#~ msgid "devcp_details_previews_nonefound"
+#~ msgstr "×œ× × ×ž×¦×ו תצוגות מקדימות"
+
+#~ msgid "devcp_details_submit_update"
+#~ msgstr "עידכון"
+
+#~ msgid "devcp_details_supportemail"
+#~ msgstr "דו×\"ל לתמיכה"
+
+#~ msgid "devcp_details_supportemail_none"
+#~ msgstr "כתובת דו×\"ל לתמיכה ×œ× ×¡×•×¤×§×” ×¢\"×™ המפתח."
+
+#~ msgid "devcp_details_supporturl"
+#~ msgstr "כתובת ×ינטרנט לתמיכה"
+
+#~ msgid "devcp_details_supporturl_none"
+#~ msgstr "כתובת ×ינטרנט לתמיכה ×œ× ×¡×•×¤×§×” על ידי המפתח."
+
+#~ msgid "devcp_details_trusted"
+#~ msgstr "×ומת"
+
+#~ msgid "devcp_details_versions_none_found"
+#~ msgstr "×œ× × ×ž×¦×ו גירס×ות."
+
+#~ msgid "devcp_disable_cancel"
+#~ msgstr "בטל וחזור ×חורה"
+
+#~ msgid "devcp_disable_disable_button"
+#~ msgstr "כן, נטרל ×ת ×–×”"
+
+#~ msgid "devcp_disable_disable_confirm"
+#~ msgstr "×”×× ×תה בטוח שברצונך לנטרל ×ת התוספת הזו?"
+
+#~ msgid "devcp_disable_disable_description"
+#~ msgstr ""
+#~ "ניטרול התוספת הזו יסתיר ×ותה ×ž×”×—×™×¤×•×©×™× ×•×ž×”×¨×©×™×ž×•×ª. ×œ× ×™×”×™×” ניתן להוריד "
+#~ "×ותה מה×תר ×•×”×™× ×œ× ×ª×•×¤×™×¢ במנהל העידכוני×. התוספת למעשה תמחק, למרות שתוכל "
+#~ "לחזור לכ×ן ול×פשר ×ותה שוב מתי שתרצה."
+
+#~ msgid "devcp_disable_disable_title"
+#~ msgstr "נטרל ×ת %s"
+
+#~ msgid "devcp_disable_enable_button"
+#~ msgstr "כן, ×פשר ×ותה"
+
+#~ msgid "devcp_disable_enable_confirm"
+#~ msgstr "×”×× ×תה בטוח שברצונך ל×פשר ×ת התוספת ×”×–×ת?"
+
+#~ msgid "devcp_disable_enable_description"
+#~ msgstr ""
+#~ "×יפשור התוספת הזו ×™×’×¨×•× ×œ×” לשוב להופיע ×‘×—×™×¤×•×©×™× ×•×‘×¨×©×™×ž×•×ª. It will be "
+#~ "downloadable both from the website and from client update checks."
+
+#~ msgid "devcp_disable_enable_title"
+#~ msgstr "×פשר ×ת %s"
+
+#~ msgid "devcp_edit_author_add"
+#~ msgstr "הוסף מחבר"
+
+#~ msgid "devcp_edit_author_email"
+#~ msgstr "כתובת דו×\"ל של המחבר"
+
+#~ msgid "devcp_edit_author_remove"
+#~ msgstr "הסר"
+
+#~ msgid "devcp_edit_error_categories_unavailable"
+#~ msgstr "×ין קטגוריות זמינות עבור סוג התוספת ×”×–×ת."
+
+#, fuzzy
+#~ msgid "devcp_edit_file_error_incomplete"
+#~ msgstr "Incomplete transfer"
+
+#, fuzzy
+#~ msgid "devcp_edit_file_error_no"
+#~ msgstr "No file uploaded"
+
+#, fuzzy
+#~ msgid "devcp_edit_file_error_size"
+#~ msgstr "Exceeds maximum upload size"
+
+#~ msgid "devcp_edit_header_authors"
+#~ msgstr "מחברי×"
+
+#~ msgid "devcp_edit_icon_add_link"
+#~ msgstr "הוסף צלמית"
+
+#~ msgid "devcp_edit_icon_change_link"
+#~ msgstr "שנה צלמית"
+
+#~ msgid "devcp_edit_label_allow_viewsource"
+#~ msgstr "הרשה ×œ×ž×©×ª×ž×©×™× ×œ×¦×¤×•×ª בקוד ×”×§×‘×¦×™× ×‘×ž×¦×‘ מקוון"
+
+#~ msgid "devcp_edit_label_categories"
+#~ msgstr "קטגוריות"
+
+#~ msgid "devcp_edit_label_defaultlocale"
+#~ msgstr "שפת ברירת מחדל"
+
+#~ msgid "devcp_edit_label_icon_delete"
+#~ msgstr "נקה ×ת הצלמית הקיימת בלבד"
+
+#~ msgid "devcp_edit_label_icon_new"
+#~ msgstr "קובץ צלמית חדש"
+
+#~ msgid "devcp_edit_label_info"
+#~ msgstr "צלמית"
+
+#~ msgid "devcp_edit_locale_disambiguation_explanation"
+#~ msgstr "מידע קצר נוסף (כמו ×©× ×‘×©×¤×” המקומית)"
+
+#~ msgid "devcp_edit_submit_update"
+#~ msgstr "עדכן"
+
+#~ msgid "devcp_edit_target_locale_explanation"
+#~ msgstr ""
+#~ "<a href=\"http://wiki.mozilla.org/L10n:Simple_locale_names\">×©× ×©×¤×” "
+#~ "מקוצר</a>, למשל 'en-US'"
+
+#~ msgid "devcp_editversion_checkedfiles_delete"
+#~ msgstr "×”×§×‘×¦×™× ×”×ž×¡×•×ž× ×™× ×™×ž×—×§×•."
+
+#~ msgid "devcp_editversion_filename_size"
+#~ msgstr "%1$s (%2$s)"
+
+#~ msgid "devcp_editversion_label_files"
+#~ msgstr "קבצי×"
+
+#~ msgid "devcp_editversion_label_targetapps"
+#~ msgstr "מטרת היישומי×"
+
+#~ msgid "devcp_editversion_nofiles"
+#~ msgstr "×ין קבצי×."
+
+#~ msgid "devcp_editversion_reviewernotes"
+#~ msgstr "הערות לסוקר"
+
+#~ msgid "devcp_editversion_submit_update"
+#~ msgstr "עדכן"
+
+#~ msgid "devcp_error_addon_field_summary_toolong"
+#~ msgstr ""
+#~ "×¡×™×›×•×ž×™× ×ž×•×’×‘×œ×™× ×œ-250 תוי×.\n"
+#~ "(×תה הכנסת %s)"
+
+#~ msgid "devcp_error_addonname_not_unique"
+#~ msgstr ""
+#~ "×”×©× ×¢×‘×•×¨ התוספת שלך כבר ×¨×©×•× ×‘×ž×גר הנתוני×. בבקשה ×”×™×” בטוח ש: <br /"
+#~ "><li>×”×ž×–×”×™× (GUID) שלך תו×מי×. הסיבה הנפוצה לשגי××” הזו ×”×™× ×ž×–×”×™× ×©××™× × "
+#~ "מתו×מי×.</li><li>×ין לך ערך כפול במ×גר הנתוני×. ×× ×™×©, עדכן ×ת הערך "
+#~ "entry ×ו מחק ×ותו ונסה שוב.</li>"
+
+#~ msgid "devcp_error_describe_changes"
+#~ msgstr "ת×ר בבקשה ×ת ×”×©×™× ×•×™×™× ×©× ×¢×©×• בעידכון התוספת ×”×–×”."
+
+#~ msgid "devcp_error_file_guids_dont_match"
+#~ msgstr "×ין מזהי קובץ (GUIDs) תו×מי×"
+
+#~ msgid "devcp_error_identical_version_exists"
+#~ msgstr "גירסה ×–×”×” (%s) כבר קיימת עבור התוספת והפלטפורמה ×”×לה."
+
+#~ msgid "devcp_error_nominate_message"
+#~ msgstr "×תה צריך לספק ×ת ×”×¤×¨×˜×™× ×”× ×“×¨×©×™× ×¢×œ מנת להגיש."
+
+#~ msgid "devcp_error_nominate_no_prerelease"
+#~ msgstr "×תה ×œ× ×™×›×•×œ להגיש תוספת קד×-שחרור."
+
+#~ msgid "devcp_error_nominate_sandbox_only"
+#~ msgstr "×תה יכול להגיש רק תוספות שכרגע ב×רגז החול."
+
+#~ msgid "devcp_error_saving"
+#~ msgstr "התרחשה שגי××” בניסיון לשמור ×ת ×”× ×ª×•× ×™× ×©×œ×š."
+
+#~ msgid "devcp_error_update_access_denied"
+#~ msgstr "×ין לך רשות לעדכן ×ת התוספת ×”×–×ת."
+
+#~ msgid "devcp_file_addanother"
+#~ msgstr "הוסף קובץ פלטפורמה ×חר"
+
+#~ msgid "devcp_form_author_add"
+#~ msgstr "הוסף מחבר"
+
+#~ msgid "devcp_form_author_remove"
+#~ msgstr "הסר"
+
+#~ msgid "devcp_form_categories_nextstep"
+#~ msgstr "קטגוריות עבור הסוג של התוספת החדשה תהיינה זמינות בצעד הב×."
+
+#~ msgid "devcp_form_error_categories_unavailable"
+#~ msgstr "×ין קטגוריות זמינות עבור סוג התוספת ×”×–×”."
+
+#~ msgid "devcp_form_error_description_notempty"
+#~ msgstr "× × ×”×›× ×¡ תי×ור של התוספת שלך."
+
+#~ msgid "devcp_form_error_name_required"
+#~ msgstr "הכנס ×©× ×¢×‘×•×¨ התוספת שלך."
+
+#~ msgid "devcp_form_error_select_addontype"
+#~ msgstr "בחר בבקשה ×ת סוג התוספת ש×תה שולח."
+
+#~ msgid "devcp_form_error_summary_notempty"
+#~ msgstr "הכנס ×¡×™×›×•× ×¢×‘×•×¨ התוספת שלך."
+
+#~ msgid "devcp_form_label_addonfile"
+#~ msgstr "קובץ תוספת"
+
+#~ msgid "devcp_form_label_addonfile2"
+#~ msgstr "קובץ תוספת 2"
+
+#~ msgid "devcp_form_label_addonfile3"
+#~ msgstr "קובץ תוספת 3"
+
+#~ msgid "devcp_form_label_addontype"
+#~ msgstr "סוג תוספת"
+
+#~ msgid "devcp_form_label_allow_viewsource"
+#~ msgstr "הרשה ×œ×ž×©×ª×ž×©×™× ×œ×¦×¤×•×ª בקוד ×”×§×‘×¦×™× ×‘×ž×¦×‘ מקוון"
+
+#~ msgid "devcp_form_label_author_email"
+#~ msgstr "כתובת דו×\"ל של המחבר"
+
+#~ msgid "devcp_form_label_authors"
+#~ msgstr "מחברי×"
+
+#~ msgid "devcp_form_label_categories"
+#~ msgstr "קטגוריות"
+
+#~ msgid "devcp_form_label_defaultlocale"
+#~ msgstr "שפת ברירת מחדל"
+
+#~ msgid "devcp_form_label_description"
+#~ msgstr "תי×ור"
+
+#~ msgid "devcp_form_label_eula"
+#~ msgstr "×”×¡×›× ×¨×™×©×™×•×Ÿ למשתמש קצה (EULA)"
+
+#~ msgid "devcp_form_label_externalsoftware"
+#~ msgstr "תוספת זו דורשת תוכנה חיצונית"
+
+#~ msgid "devcp_form_label_files"
+#~ msgstr "קבצי×"
+
+#~ msgid "devcp_form_label_homepage"
+#~ msgstr "דף הבית"
+
+#~ msgid "devcp_form_label_iconfile"
+#~ msgstr "צלמית קובץ"
+
+#~ msgid "devcp_form_label_name"
+#~ msgstr "ש×"
+
+#~ msgid "devcp_form_label_platforms"
+#~ msgstr "פלטפורמות נתמכות"
+
+#~ msgid "devcp_form_label_prerelease"
+#~ msgstr "×–×” קד×-שחרור"
+
+#~ msgid "devcp_form_label_privacy"
+#~ msgstr "מדיניות פרטיות"
+
+#~ msgid "devcp_form_label_sitespecific"
+#~ msgstr "×–×ת תוספת ל×תר מסוי×"
+
+#~ msgid "devcp_form_label_summary"
+#~ msgstr "תקציר"
+
+#~ msgid "devcp_form_label_supportemail"
+#~ msgstr "דו×\"ל לתמיכה"
+
+#~ msgid "devcp_form_label_supporturl"
+#~ msgstr "כתובת ×ינטרנט לתמיכה"
+
+#~ msgid "devcp_form_label_target_applications"
+#~ msgstr "יישומי מטרה"
+
+#~ msgid "devcp_form_label_version"
+#~ msgstr "גירסה"
+
+#~ msgid "devcp_form_label_versionnotes"
+#~ msgstr "הערות גירסה"
+
+#~ msgid "devcp_form_no_target_apps"
+#~ msgstr "×ין"
+
+#~ msgid "devcp_form_reviewernotes"
+#~ msgstr "הערות לסוקר"
+
+#~ msgid "devcp_form_trustedaddon_destination"
+#~ msgstr "×ž×©×•× ×©×”×ª×•×¡×¤×ª שלך ×ומתה, בחר בבקשה להיכן הגירסה ×”×–×ת תלך:"
+
+#~ msgid "devcp_form_trustedaddon_destination_public"
+#~ msgstr "ציבורי"
+
+#~ msgid "devcp_form_trustedaddon_destination_sandbox"
+#~ msgstr "×רגז החול"
+
+#~ msgid "devcp_header_developer_agreement"
+#~ msgstr "×”×¡×›× ×ž×¤×ª×—"
+
+#~ msgid "devcp_header_step1"
+#~ msgstr "שלב 1"
+
+#~ msgid "devcp_header_step1_upload"
+#~ msgstr "העלה קובץ"
+
+#~ msgid "devcp_header_step2"
+#~ msgstr "שלב 2"
+
+#~ msgid "devcp_header_step2_addondetails"
+#~ msgstr "פרטי תוספת"
+
+#~ msgid "devcp_header_step3"
+#~ msgstr "שלב 3"
+
+#~ msgid "devcp_header_step3_versiondetails"
+#~ msgstr "פרטי גירסה"
+
+#~ msgid "devcp_header_step4"
+#~ msgstr "שלב 4"
+
+#~ msgid "devcp_header_step4_localization"
+#~ msgstr "הת×מות שפה"
+
+#~ msgid "devcp_header_step5"
+#~ msgstr "שלב 5"
+
+#~ msgid "devcp_header_step5_success"
+#~ msgstr "הצלחה"
+
+#~ msgid "devcp_index_header_myaddons"
+#~ msgstr "התוספות שלי"
+
+#~ msgid "devcp_nominate_link_returnto_details"
+#~ msgstr "חזרה לפרטי תוספת"
+
+#~ msgid "devcp_notice_autodetected_addontype"
+#~ msgstr "סוג תוספת ש×ובחן ×וטומטית: %s."
+
+#~ msgid "devcp_notice_different_defaultlocale"
+#~ msgstr ""
+#~ "שפת ברירת המחדל של התוספת הזו (%1$s [%2$s])שונה מהשפה הנוכחית שבחרת (%3"
+#~ "$s [%4$s]). השדות למטה יושלמו ב- %1$s."
+
+#~ msgid "devcp_question_addontype_incorrect"
+#~ msgstr "שגוי?"
+
+#~ msgid "devcp_question_delete_file"
+#~ msgstr "×”×× ×תה בטוח שברצונך למחוק קובץ ×–×”?"
+
+#~ msgid "devcp_skip_reviewing_addon_info"
+#~ msgstr "דלג על סיקור התוספת הנוכחית"
+
+#~ msgid "devcp_submissions_disabled"
+#~ msgstr "שליחת תוספות כרגע מנוטרלת. בדוק בבקשה מ×וחר יותר."
+
+#~ msgid "devcp_submit_accept_dev_agreement"
+#~ msgstr "×× ×™ מסכי×"
+
+#~ msgid "devcp_submit_decline_dev_agreement"
+#~ msgstr "×× ×™ מסרב"
+
+#~ msgid "devcp_summary_admin_disabled"
+#~ msgstr "תוספת זו נוטרלה בידי מנהל."
+
+#~ msgid "devcp_summary_header_disabled"
+#~ msgstr "מנוטרל"
+
+#~ msgid "devcp_summary_header_trusted"
+#~ msgstr "מ×ומת"
+
+#~ msgid "devcp_summary_noaddons_submit_one"
+#~ msgstr "×ין לך ××£ תוספת. לחץ %s כדי לשלוח ×חת."
+
+#~ msgid "devcp_summary_noaddons_submit_one_link"
+#~ msgstr "×›×ן"
+
+#~ msgid "devcp_theme_upload_preview"
+#~ msgstr "בבקשה ×•×•×“× ×©%s לערכת ×”× ×•×©× ×©×œ×š."
+
+#~ msgid "devcp_theme_upload_preview_link"
+#~ msgstr "העלת תצוגה מקדימה"
+
+#~ msgid "devcp_version_edit_pagetitle"
+#~ msgstr "ערוך גירסה"
+
+#~ msgid "devcp_version_updated_successfully"
+#~ msgstr "גירסה עודכנה בהצלחה."
+
+#~ msgid "editors_submissiontype_new"
+#~ msgstr "חדש"
+
+#~ msgid "editors_submissiontype_updated"
+#~ msgstr "עודכן"
+
+#, fuzzy
+#~ msgid "editors_th_addon_age"
+#~ msgstr "Addon Age"
+
+#~ msgid "editors_th_addontypes"
+#~ msgstr "סוגי תוספות"
+
+#~ msgid "editors_th_age"
+#~ msgstr "גיל"
+
+#~ msgid "editors_th_applications"
+#~ msgstr "יישומי×"
+
+#~ msgid "editors_th_platforms"
+#~ msgstr "פלטפורמות"
+
+#~ msgid "editors_th_submissiontypes"
+#~ msgstr "סוגי הגשה"
+
+#~ msgid "error_notice"
+#~ msgstr "הערה"
+
+#~ msgid "forum_save"
+#~ msgstr "שמור"
+
+#, fuzzy
+#~ msgid "home"
+#~ msgstr "home"
+
+#~ msgid "nav_category_plugins"
+#~ msgstr "תוספי×"
+
+#, fuzzy
+#~ msgid "page_title_experimental_addons"
+#~ msgstr "Experimental Add-ons"
+
+#~ msgid "pages_experimental_addons_backbutton"
+#~ msgstr "חזור לעמוד הקוד×"
+
+#~ msgid "pagination_page_number_title"
+#~ msgstr "עמוד %1$s מתוך %2$s"
+
+#~ msgid "search_matching_addons_number"
+#~ msgid_plural "search_matching_addons_number"
+#~ msgstr[0] "תוספת %s מת×ימה"
+#~ msgstr[1] "%s תוספות מת×ימות"
+
+#~ msgid "statistics_rss_icon_title"
+#~ msgstr "עידכוני RSS של ×¡×™×›×•× ×”×ž×™×“×¢"
diff --git a/site/app/locale/he/pages/error404.thtml b/site/app/locale/he/pages/error404.thtml
new file mode 100644
index 0000000..abca2b2
--- /dev/null
+++ b/site/app/locale/he/pages/error404.thtml
@@ -0,0 +1,16 @@
+<h1>מצטערי×, ×בל ×œ× ×™×›×•×œ× ×• ×œ×ž×¦×•× ×ת מה שחיפשת.</h1>
+
+<p>הדף ×ו הקובץ שביקשת ×œ× × ×ž×¦× ×‘×תר שלנו. ייתכן ולחצת על קישור ×œ× ×¢×“×›× ×™ ×ו שהקשת כתובת שגויה</p>
+
+<ul>
+<li>×× ×”×§×œ×“×ª ×ת הכתובת, בדוק שוב ×ת ×”×יות.</li>
+<li>×× ×¢×§×‘×ª ×חרי קישור מ×תר ×חר, בבקשה יידע ×ותנו ב־<a href="mailto:webmaster@mozilla.com" title="Page Not Found on Mozilla.com">webmaster@mozilla.com</a>. ספר לנו מ×יפה הגעת ומה חיפשת, ו×נחנו נעשה ×ת המירב כדי לתקן ×–×ת.</li>
+</ul>
+
+<p>×ו עבור ל×חד ×ž×”×“×¤×™× ×”×¤×•×¤×•×œ×¨×™×™× ×‘×תר שלנו.</p>
+
+<ul>
+<li>מתעניין ב<a href="%1$s">רשימת ההרחבות הפופולריותת</a>?</li>
+<li>מעוניין <a href="%2$s">לחפש הרחבות</a>? ×תה יכול לגשת ל<a href="%2$s">דף החיפוש</a> ×ו להשתמש בשדה החיפוש שבהמשך.</li>
+<li>×× ×תה מעוניין להתחיל מחדש, עבור ל<a href="%3$s">דף הר×שי של ×תר התוספות</a>.</li>
+</ul>
diff --git a/site/app/locale/he/pages/nomination.thtml b/site/app/locale/he/pages/nomination.thtml
new file mode 100644
index 0000000..4f57a9b
--- /dev/null
+++ b/site/app/locale/he/pages/nomination.thtml
@@ -0,0 +1,10 @@
+<p>תוספת שנמצ×ת ב×רגז החול תהיה מועמדת להופעה ב×תר הציבורי וזמינה לכלל ×”×ž×©×ª×ž×©×™× ×œ×חר בדיקה מעמיקה של ×חד העורכי×. לתוצ×ות הטובות ביותר, ×©×™× ×œ×‘ ×œ×§×¨×™×˜×¨×™×•× ×™× ×”×‘××™×:</p>
+<ul>
+ <li>תמונות תצוגה מקדימה דרושות לערכות × ×•×©× ×•×ž×•×ž×œ×¦×•×ª מ×ד עבור כל סוגי התוספות ×”×חרות.</li>
+ <li>התוספת חייבת להיות מספיק זמן ב×רגז החול כדי לצבור סקירות ותגובות ממשתמשי×. <b>סקירות נדרשות כדי לעבור ל×תר הציבורי.</b></li>
+ <li>לתוספות ציבוריות יש יותר דירוג ×יכות מ×שר תוספות ב×רגז החול ויכולות לשפר ×ת הרשת.<li>
+ <li>×§×¨×™×˜×¨×™×•× ×™× ×ž×œ××™× ×œ×”×’×©×ª מועמדות ×–×ž×™× ×™× ×‘<a href="%s">הצהרת התוספות</a>.</li>
+</ul>
+<p>במידה והתוספת שלך עומדת ×‘×§×¨×™×˜×¨×™×•× ×™× ×”× "ל, ב×פשרותך להגיש מועמדות ב×מצעות מילוי השדה הב×. ×תה תעודכן בדו×ר ×לקטרוני על המצב העדכני של הגשת המועמדות.</p>
+
+<p>כדי להגיש מועמדות לתוספת שלך, בבקשה ת×ר כיצד ×”×™× × ×‘×“×§×” (כולל בדיקה שלה משגי×ות ו×זהרות) וכיצד ×”×™× ×™×›×•×œ×” להיות שימושית לכלל הרשת. ב×פשרותך ×’× ×œ×¦×¨×£ ×§×™×©×•×¨×™× ×œ×¡×§×™×¨×•×ª חיצוניות של התוספת.</p>
diff --git a/site/app/locale/he/pages/submission_help.thtml b/site/app/locale/he/pages/submission_help.thtml
new file mode 100644
index 0000000..278d0c9
--- /dev/null
+++ b/site/app/locale/he/pages/submission_help.thtml
@@ -0,0 +1,35 @@
+<h1>עזרה בהגשה</h1>
+השדות ×”× ×“×¨×©×™× <b>מודגשי×</b>. השדות ×”××¤×©×¨×™×™× <i>נטויי×</i>.
+<h2 id="step1">שלב ר×שון: העל××”</h2>
+<ul class="submissionHelp">
+ <li><span class="required">סוג התוספת</span> - כברירת מחדל, סוג התוספת נקבע ×וטומטית בהתבסס על הקובץ שהועלה. ×ין ב×פשרותך לשנות ×ת השדה ×”×–×”.</li>
+ <li><span class="required">קובץ התוספת</span> - קובץ החבילה עבור התוספת שלך, ×”×•×©×œ× ×¢× ×§×•×‘×¥ install.rdf. ×× ×”×§×•×‘×¥ עובד רק על פלטפורמה מסוימת, בחירת הפלטפורמה ,ת×פשר ×”×¤×¢× ×˜×¢×™× ×” של ×§×‘×¦×™× ×ž×¨×•×‘×™×.</li>
+ <li><span class="optional">קובץ צלמית</span> - קובץ הצלמית שתוצג צמוד ×œ×©× ×”×ª×•×¡×¤×ª שלך בעמוד התצוגה שלה ובתיבת דו-שיח של התקנת התוספת. גודל הצלמית ישונה ×וטומטית ל- 32x32 פיקסלי×, ×¢× ×©×ž×™×¨×” על היחס.</li>
+ <li><span class="required">שפת ברירת המחדל</span> - שפת ברירת המחדל של התוספת ×”×™× ×”×©×¤×” הר×שית שלה. ×× ×”×©×¤×” שהמשתמש בחר ×œ× ×–×ž×™× ×” עבור התוספת, ,×ª×¨×’×•×ž×™× ×™×ª×‘×¡×¡×• על שפת ברירת המחדל.</li>
+ <li><span class="optional">דלג על הסקירה של מידע התוספת הנוכחית שלי</span> - ×× ×תה מעדכן תוספת קיימת, שדה ×–×” יופיע. סימון התיבה ידלג על השלב השלישי שבו ×תה יכול להזין מידע עבור גירסה מסויימת שלך.</li>
+</ul>
+
+<h2 id="step2">שלב שני: פרטי התוספת</h2>
+<ul class="submissionHelp">
+ <li><span class="required">ש×</span> - ×©× ×”×ª×•×¡×¤×ª בשפת ברירת המחדל.</li>
+ <li><span class="required">מחברי×</span> - כל ×”×ž×©×ª×ž×©×™× ×©×ª×”×™×” ×œ×”× ×’×™×©×” לעריכה של ×¨×™×©×•× ×”×ª×•×¡×¤×ª ויהיו ×¨×©×•×ž×™× ×›×ž×—×‘×¨×™× ×‘×¢×ž×•×“ התצוגה.</li>
+ <li><span class="required">קטגוריות</span> - קטגוריות שמת×ימות לתוספת שלך.</li>
+ <li><span class="optional">דף הבית</span> - ×”×תר של התוספת עבור שפת ברירת המחדל.</li>
+ <li><span class="required">תקציר</span> - ×¡×™×›×•× ×§×¦×¨ על התוספת בשפת ברירת המחדל. המספר המרבי של ×ª×•×™× ×‘×©×“×” ×–×” ×”×•× 250. התקציר יופיע בעמוד התצוגה של התוספת, כתוצ×ות חיפוש ×ו עיון.</li>
+ <li><span class="required">תי×ור</span> - תי×ור של התוספת בשפת ברירת המחדל. התי×ור יופיע בעמוד התוספת מתחת לתקציר.</li>
+ <li><span class="optional">×”×¡×›× ×ž×©×ª×ž×© (EULA)</span> - ×”×¡×›× ×œ×ž×©×ª×ž×© קצה ×©×”×ž×©×ª×ž×©×™× ×™×©×¨×©×• ל×שר לפני ההורדה, בשפת ברירת המחדל.</li>
+ <li><span class="optional">הצהרת פרטיות</span> - הצהרת הפרטיות של התוספת, בשפת ברירת המחדל. הצהרת פרטיות מסיברה מה ייעשה ×¢× ×”×ž×™×“×¢ ×”×ישי של משתמש הקצה, ההצהרה תופיעה לפני ההתקנה בעמוד התצוגה של התוספת. מידע נוסף על מה צריך להכלל בהצהרת הפרטיות וה×× ×‘×›×œ×œ התוספת שלך זקוקה להצהרה × ×ž×¦× ×‘- <a href="%s">הצהרה של תוספת</a>.</li>
+ <li><span class="optional">הרשה ×œ×ž×©×ª×ž×©×™× ×œ×¦×¤×•×ª בקוד ×”×§×‘×¦×™× ×‘×ž×¦×‘ מקוון</span> - סימון תיבה ×–×ת ×™×פשר ×œ×ž×©×ª×ž×©×™× ×œ×¢×™×™×Ÿ בקוד ×”×§×‘×¦×™× ×©×œ התוספת שלך במצב מקוון.</li>
+ <li><span class="optional">×–×” קד×-שחרור</span> - סימון תיבה זו יציין שהתוספת ×”×™× ×‘×’×™×¨×¡×ª קד×-שחרור ×ו בט×. תוספות בקד×-שחרור יש×רו ב×רגז החול ×•×œ× ×™×•×›×œ×• להיות מוגשות עבור ×”×ישור הציבורי עד שהסימון יוסר.</li>
+ <li><span class="optional">זו תוספת ל×תר מסוי×</span> - סימון התיבה הזו יציין שהתוספת מיועדת ל×תר ×ינטרנט מסוי×, כמו תוספת שמשנה ×ת המר××” של ×תר ×›×œ×©×”×•× ×ו מציגה תוכן מ×תר מסוי×. שדה ×–×” יעזור ×œ×¢×•×¨×›×™× ×•×ולי ×’× ×™×©×ž×© בעתיד לסינון בחיפושי×.</li>
+ <li><span class="optional">תוספת זו דורשת תוכנה חיצונית</span> - סימון התיבה הזו יציין שהתוספת דורשת תוכנה חיצונית. שדה ×–×” יעזור ×œ×¢×•×¨×›×™× ×•×ולי ×’× ×™×©×ž×© בעתיד לסינון בחיפושי×..</li>
+</ul>
+
+<h2 id="step3">שלב שלישי: פרטי גירסה</h2>
+<ul class="submissionHelp">
+ <li><span class="required optional">הערות גירסה</span> - תקציר ×ו רשימה של ×”×©×™× ×•×™×™× ×‘×’×™×¨×¡×” זו. ×–×” ×œ× ×—×•×‘×” עבור הגשות חדשות, ×בל נדרש עבור עידכוני×.</li>
+ <li><span class="optional">הערות לסוקר</span> - שדה ×–×” משמש להעברת מידע ×œ×¢×•×¨×›×™× ×©×™×¡×§×¨×• ×ת התוספת שלך. מידע על בדיקות שערכת והערות מיוחדות יכתבו ×›×ן</li>
+</ul>
+
+<h2 id="step4">שלב רביעי: הת×מות שפה</h2>
+×–×” ×”×ž×§×•× ×©×‘×• השדות של התוספת יוכלו להיות מות××ž×™× ×œ×›×œ השפות הנתמכות. פשוט לחץ על השפה והכנס תרגו×.
diff --git a/site/app/locale/hu/LC_MESSAGES/messages.mo b/site/app/locale/hu/LC_MESSAGES/messages.mo
new file mode 100644
index 0000000..f8eb878
--- /dev/null
+++ b/site/app/locale/hu/LC_MESSAGES/messages.mo
Binary files differ
diff --git a/site/app/locale/hu/LC_MESSAGES/messages.po b/site/app/locale/hu/LC_MESSAGES/messages.po
new file mode 100644
index 0000000..c9826af
--- /dev/null
+++ b/site/app/locale/hu/LC_MESSAGES/messages.po
@@ -0,0 +1,8676 @@
+# Remora Preliminary Language File
+# Copyright (C) 2009 THE addons.mozilla.org'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the addons.mozilla.org package.
+# Wil Clouser <clouserw@mozilla.com>, 2006.
+# Andras Timar <timar@fsf.hu>, 2009.
+# Kalman Kemenczy <kkemenczy@novell.com>, 2009.
+msgid ""
+msgstr ""
+"Project-Id-Version: addons\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2009-01-16 11:45-0800\n"
+"PO-Revision-Date: 2009-02-07 15:58+0100\n"
+"Last-Translator: Andras Timar <timar@fsf.hu>\n"
+"Language-Team: Hungarian <hu@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=n != 1;\n"
+"X-Generator: Pootle 1.1.0\n"
+
+#: views/addons/policy.thtml:98
+msgid "a_cancel_installation"
+msgstr "Telepítés megszakítása"
+
+#. This is the text that appears on buttons to download add-ons.
+#. %$1s is an optional string that only appears if the add-on is only available for
+#. a certain platform. Examples: (Windows) or (Linux)
+#. Note that the parentheses are included in the string. :(
+#: views/elements/amo2009/install.thtml:126
+#: views/elements/amo2009/install.thtml:227
+#: views/elements/amo2009/install.thtml:257
+#: views/elements/amo2009/install.thtml:300
+#: views/elements/amo2009/install.thtml:312 views/elements/install.thtml:73
+#: views/elements/install.thtml:181 views/elements/install.thtml:205
+#: views/elements/install.thtml:248 views/elements/install.thtml:260
+#: views/addons/plugins.thtml:66 views/addons/plugins.thtml:76
+#: views/addons/plugins.thtml:86 views/addons/plugins.thtml:96
+#: views/addons/plugins.thtml:119
+#, php-format
+msgid "a_download"
+msgstr "%s letöltése"
+
+#: views/addons/policy.thtml:72
+msgid "a_eula_download"
+msgstr "Elfogadás és letöltés"
+
+#: views/addons/policy.thtml:74
+msgid "a_eula_install"
+msgstr "Elfogadás és telepítés"
+
+#: views/elements/header.thtml:76 views/elements/header.thtml:82
+#: views/api/api_addon.thtml:55 views/api/collections_feed.thtml:75
+#: views/sharing_api/addon.thtml:64
+msgid "a_header_public"
+msgstr "Nyilvános"
+
+#: views/elements/header.thtml:58 views/elements/header.thtml:75
+#: views/elements/header.thtml:80 views/api/api_addon.thtml:57
+#: views/api/collections_feed.thtml:77 views/sharing_api/addon.thtml:66
+msgid "a_header_sandbox"
+msgstr "Homokozó"
+
+#. %s is a date in the _('date') format
+#: views/elements/amo2009/homepage_addon.thtml:115
+#: views/elements/addon_listitem.thtml:122 views/elements/feature.thtml:106
+#: views/addons/display.thtml:104 views/addons/browse_thumbs.thtml:73
+msgid "addon_detail_last_updated"
+msgstr "Frissítve: %s"
+
+#. %s is the version of the add-on. Example: 3.2a1
+#: views/elements/amo2009/addon_version_detail.thtml:51
+#: views/elements/addon_version_detail.thtml:51
+#, php-format
+msgid "addon_display_header_version"
+msgstr "%s verzió"
+
+#: views/addons/browse_thumbs.thtml:80
+msgid "addon_downloads"
+msgstr "letöltés"
+
+#: views/addons/display.thtml:147
+msgid "addon_downloads_total"
+msgstr "letöltés összesen"
+
+#: views/elements/amo2009/homepage_addon.thtml:106
+#: views/elements/addon_listitem.thtml:115 views/elements/feature.thtml:101
+#: views/addons/category_landing.thtml:157 views/addons/display.thtml:146
+#: views/addons/browse_thumbs.thtml:80
+msgid "addon_downloads_weekly"
+msgstr "letöltés a héten"
+
+# %1 is the add-on count, %2 the category name
+#. %1 is the add-on count, %2 the category name
+#: views/addons/browse_thumbs.thtml:104 views/addons/browse.thtml:60
+#, php-format
+msgid "addon_list_category_totalcount"
+msgid_plural "addon_list_category_totalcount"
+msgstr[0] "%1$s kiegészítő"
+msgstr[1] "%1$s kiegészítő"
+
+#: views/elements/amo2009/addon_list_options.thtml:103
+#: views/elements/pagination.thtml:67
+#: views/elements/addon_list_options.thtml:94
+msgid "addon_list_perpage"
+msgstr "oldalanként"
+
+#: views/elements/amo2009/addon_list_options.thtml:84
+#: views/elements/addon_list_options.thtml:98
+msgid "addon_list_sortby"
+msgstr "Rendezés:"
+
+#: views/helpers/addons_html.php:568 views/elements/amo2009/install.thtml:321
+#: views/elements/feature.thtml:89
+msgid "addon_listitem_flag_experimental"
+msgstr "kísérleti"
+
+#: views/helpers/addons_html.php:570
+msgid "addon_listitem_flag_recommended"
+msgstr "ajánlott"
+
+# %1 is the addon name, %2 is the platform
+#. %1 is the add-on name, %2 is the platform
+#: views/pages/js_constants.js.thtml:66
+msgid "addon_not_available_for_platform"
+msgstr "%1$s nem érhető el %2$s platformon."
+
+# %1 is the addon name
+#. %1 is the add-on name
+#: views/addons/policy.thtml:101 views/addons/previews.thtml:60
+#: views/addons/versions.thtml:130 views/reviews/flag.thtml:61
+#: views/reviews/add.thtml:114 views/reviews/display.thtml:216
+#: views/reviews/review_added.thtml:57
+#, php-format
+msgid "addon_review_a_back_to_addon_x"
+msgstr "Vissza ehhez: %1$s..."
+
+# %1 is the addon name
+#. %1 is the add-on name
+#: views/reviews/flag.thtml:60 views/reviews/add.thtml:113
+#: views/reviews/review_added.thtml:56
+#, php-format
+msgid "addon_review_a_back_to_reviews"
+msgstr "Vissza az értékelésekhez..."
+
+#: views/reviews/add.thtml:85
+msgid "addon_review_add_rating_field"
+msgstr "Osztályzat:"
+
+#: views/reviews/add.thtml:102
+msgid "addon_review_add_review_field"
+msgstr "Értékelés:"
+
+#: views/reviews/add.thtml:107
+msgid "addon_review_add_submit"
+msgstr "Értékelés beküldése"
+
+#. %s is the name of the add-on
+#: views/reviews/add.thtml:51
+#, php-format
+msgid "addon_review_add_title"
+msgstr "Értékelés hozzáadása: %s"
+
+#: views/reviews/add.thtml:78
+msgid "addon_review_add_title_field"
+msgstr "Cím/Összefoglaló:"
+
+#: views/reviews/display.thtml:77 views/reviews/display.thtml:161
+msgid "addon_review_admin_delete"
+msgstr "Törlés"
+
+#: views/reviews/display.thtml:76
+msgid "addon_review_author_reply_link"
+msgstr "Válasz"
+
+#: views/reviews/delete.thtml:62
+msgid "addon_review_confirm_delete"
+msgstr "Biztosan törli az értékelést?"
+
+#: views/reviews/delete.thtml:63
+msgid "addon_review_confirm_no"
+msgstr "Nem"
+
+#: views/reviews/delete.thtml:64
+msgid "addon_review_confirm_yes"
+msgstr "Igen"
+
+#: views/reviews/delete.thtml:48
+msgid "addon_review_delete_header"
+msgstr "Értékelés törlése"
+
+#: controllers/reviews_controller.php:449
+msgid "addon_review_deleted_successfully"
+msgstr "Értékelés sikeresen törölve."
+
+#. %s is the name of the add-on
+#: views/reviews/add.thtml:51
+#, php-format
+msgid "addon_review_edit_title"
+msgstr "%s értékelésének szerkesztése"
+
+# %1 is the count of characters entered as notes for the review flag reason.
+#. %1 is the count of characters entered as notes for the review flag reason.
+#: controllers/reviews_controller.php:539
+msgid "addon_review_flag_error_other_length"
+msgstr ""
+"Probléma az értékelés megjelölésénél: A megjelölt értékelések megjegyzései "
+"10 és 100 karakter közötti hosszúságúak lehetnek; a karakterszám %1$s volt."
+
+# Removing an extra comma
+#. Removing an extra comma
+#: views/reviews/review_added.thtml:53
+msgid "addon_review_in_moderation"
+msgstr ""
+"Jegyezze meg: mielőtt az értékelése megjelenne a nyilvános webhelyen, egy "
+"szerkesztő moderálni fogja."
+
+#: views/reviews/add.thtml:57
+msgid "addon_review_in_reply_to"
+msgstr "A fejlesztő válasza:"
+
+# %1 is the review count, %2 is the nickname or full name of the user.
+#. %1 is the review count, %2 is the nickname or full name of the user.
+#: views/reviews/display.thtml:131
+#, php-format
+msgid "addon_review_others_by_user"
+msgid_plural "addon_review_others_by_user"
+msgstr[0] ""
+"%2$s által ehhez a kiegészítőhöz beküldött %1$s korábbi értékelés "
+"megtekintése."
+msgstr[1] ""
+"%2$s által ehhez a kiegészítőhöz beküldött %1$s korábbi értékelés "
+"megtekintése."
+
+# %1 is the addon name
+#. %1 is the add-on name
+#: controllers/reviews_controller.php:201
+#: controllers/reviews_controller.php:250
+#: controllers/reviews_controller.php:345
+#: controllers/reviews_controller.php:424
+#, php-format
+msgid "addon_review_pagetitle"
+msgstr "%s értékelései"
+
+# %1 is the user, %2 is the (localized) date
+#. %1 is the user, %2 is the (localized) date
+#: views/reviews/display.thtml:160
+#, php-format
+msgid "addon_review_reply_on_x_by_y"
+msgstr "%1$s válasza, dátum: %2$s"
+
+#: views/reviews/display.thtml:157
+msgid "addon_review_reply_prefix"
+msgstr "A fejlesztő válasza:"
+
+#: views/reviews/review_added.thtml:51
+msgid "addon_review_saved_successfully"
+msgstr "Az értékelését mentettük. Köszönjük!"
+
+#: views/addons/display.thtml:354 views/reviews/display.thtml:72
+msgid "addon_reviewed_by_u_on_d"
+msgstr "értékelte: %1$s, dátum: %2$s"
+
+# %1 is the user, %2 is the (localized) date, %3 is the rating
+#. %1 is the user, %2 is the (localized) date, %3 is the rating
+#: views/editors/reviews_queue.thtml:57 views/editors/reviews_queue.thtml:68
+#: views/reviews/add.thtml:63 views/reviews/delete.thtml:54
+#, php-format
+msgid "addon_reviewed_on_x_rated_y"
+msgstr "értékelte: %1$s, dátum: %2$s, (osztályzat: %3$s)"
+
+#: views/elements/amo2009/addon_version_detail.thtml:52
+#: views/elements/addon_version_detail.thtml:52
+msgid "addon_version_permalink"
+msgstr "Ãllandó hivatkozás erre a verzióra"
+
+# %1 is the current Application name (e.g. Firefox)
+# %2 is the Application's version number
+#. %1 is the current Application name (e.g. Firefox)
+#. %2 is the Application's version number
+#: views/addons/versions.thtml:140
+msgid "addon_versions_getlatestversion"
+msgstr "A legújabb verzió, amely még kompatibilis ezzel: %1$s %2$s"
+
+#: views/addons/display.thtml:447
+msgid "addons_author_addons_submit"
+msgstr "Ugrás"
+
+#: views/elements/amo2009/homepage_addon.thtml:100
+#: views/elements/feature.thtml:95
+msgid "addons_author_tooltip"
+msgstr "A szerző profilja"
+
+# %1 is the name of the Application (eg. Firefox)
+#. %1 is the name of the Application (eg. Firefox)
+#: controllers/addons_controller.php:1296
+msgid "addons_browse_all_themes_title"
+msgstr "Témák böngészése :: %1$s-kiegészítők"
+
+#. %s is the name of the category
+#: controllers/addons_controller.php:1016
+#, php-format
+msgid "addons_browse_browse_category"
+msgstr "%s böngészése"
+
+# %1 is the name of the theme category (eg. Modern)
+# %2 is the name of the Application (eg. Firefox)
+#. %1 is the name of the theme category (eg. Modern)
+#. %2 is the name of the Application (eg. Firefox)
+#: controllers/addons_controller.php:664
+msgid "addons_browse_categories_header_theme"
+msgstr "%1$s témák böngészése :: %2$s-kiegészítők"
+
+#: views/addons/display.thtml:249
+#, fuzzy
+msgid "addons_display_a_license_what"
+msgstr "What's this?"
+
+#: views/reviews/display.thtml:222
+msgid "addons_display_add_review"
+msgstr "Értékelés hozzáadása"
+
+#: views/addons/display.thtml:294
+msgid "addons_display_advanced_details"
+msgstr "Részletek"
+
+#: views/addons/display.thtml:98
+msgid "addons_display_categories"
+msgstr "Kategóriák"
+
+#: views/addons/display.thtml:482
+#, fuzzy
+msgid "addons_display_collection_add"
+msgstr "Add to a collection:"
+
+#: views/addons/display.thtml:491
+#, fuzzy
+msgid "addons_display_collection_add_new"
+msgstr "New Collection..."
+
+#: views/addons/display.thtml:487
+#, fuzzy
+msgid "addons_display_collection_add_select_one"
+msgstr "Select a collection..."
+
+#: views/addons/display.thtml:493
+#, fuzzy
+msgid "addons_display_collection_add_submit"
+msgstr "Publish"
+
+#. %1$s is the add-on name
+#. %2$s is the collection name, linked to the collection's page
+#: views/pages/js_constants.js.thtml:103 views/addons/display.thtml:61
+#, fuzzy
+msgid "addons_display_collection_publish_success"
+msgstr "%1$s has been added to the %2$s collection."
+
+#: views/addons/display.thtml:483
+#, fuzzy
+msgid "addons_display_collection_whatsthis"
+msgstr "What's this?"
+
+#. %1$s is a number
+#: views/addons/display.thtml:473
+#, fuzzy
+msgid "addons_display_collections_more"
+msgid_plural "addons_display_collections_more"
+msgstr[0] "and %1$s more collection"
+msgstr[1] "and %1$s more collections"
+
+#: views/addons/display.thtml:403
+msgid "addons_display_detailed_review"
+msgstr "részletes értékelés"
+
+#: views/reviews/add.thtml:89 views/reviews/add.thtml:90
+msgid "addons_display_dont_like_it"
+msgstr "Nem tetszett"
+
+#: views/reviews/display.thtml:220
+msgid "addons_display_edit_review"
+msgstr "Értékelés szerkesztése"
+
+#: views/addons/display.thtml:132
+msgid "addons_display_has_privacy"
+msgstr "Ez a kiegészítő rendelkezik adatvédelmi irányelvekkel."
+
+#: views/reviews/add.thtml:87 views/reviews/add.thtml:88
+msgid "addons_display_hate_it"
+msgstr "Utálom"
+
+#: views/addons/display.thtml:462
+#, fuzzy
+msgid "addons_display_header_collections"
+msgstr "Related Collections"
+
+#: views/addons/display.thtml:297
+msgid "addons_display_header_developer_comments"
+msgstr "Fejlesztői megjegyzések"
+
+#: views/addons/display.thtml:230
+msgid "addons_display_header_homepage"
+msgstr "Honlap"
+
+#: views/addons/display.thtml:247 views/addons/versions.thtml:110
+#, fuzzy
+msgid "addons_display_header_license"
+msgstr "Source Code License"
+
+#: views/addons/display.thtml:337
+msgid "addons_display_header_reviews"
+msgstr "Értékelések"
+
+#: views/addons/display.thtml:261
+msgid "addons_display_header_support"
+msgstr "Támogatás"
+
+#: views/reviews/add.thtml:91 views/reviews/add.thtml:92
+msgid "addons_display_like_it"
+msgstr "Szeretem"
+
+#: views/addons/display.thtml:210
+msgid "addons_display_long_description"
+msgstr "Hosszú leírás"
+
+#: views/reviews/add.thtml:95 views/reviews/add.thtml:96
+msgid "addons_display_love_it"
+msgstr "Imádom"
+
+#: views/addons/display.thtml:178
+msgid "addons_display_more_images"
+msgstr "Több kép"
+
+#: views/addons/display.thtml:465
+#, fuzzy
+msgid "addons_display_nocollections"
+msgstr "This add-on is not yet in any collections."
+
+# %1$s is either an author's name or a comma separated list of authors. Using
+# the list doesn't make sense in the English plural form so we ignore the
+# variable.
+#. %1$s is either an author's name or a comma separated list of authors. Using
+#. the list doesn't make sense in the English plural form so we ignore the
+#. variable.
+#: views/addons/display.thtml:436
+msgid "addons_display_other_addons_by"
+msgid_plural "addons_display_other_addons_by"
+msgstr[0] "%1$s további kiegészítői"
+msgstr[1] "További kiegészítők ezektől a szerzőktől"
+
+#. %s is the name of the add-on and the add-on section. Example:
+#. Some Add-on :: Firefox Add-ons
+#. This should not be concatenated in the code and should be fixed.
+#: controllers/addons_controller.php:141 controllers/addons_controller.php:280
+#: controllers/addons_controller.php:1442
+#, php-format
+msgid "addons_display_pagetitle"
+msgstr "%s"
+
+#. %s is an email address
+#: views/addons/display.thtml:286
+#, php-format
+msgid "addons_display_paragraph_supportinfoemail"
+msgstr "Ehhez a kiegészítőhöz a fejlesztő a(z) %s helyen nyújt támogatást."
+
+#. %$1s is a URL
+#. %$2s is an email address
+#: views/addons/display.thtml:269
+#, php-format
+msgid "addons_display_paragraph_supportinfoemailurl"
+msgstr ""
+"Ehhez a kiegészítőhöz a fejlesztő a(z) %s helyen, illetve a(z) %s e-mail "
+"címen nyújt támogatást."
+
+#. %s is a URL
+#: views/addons/display.thtml:278
+#, php-format
+msgid "addons_display_paragraph_supportinfourl"
+msgstr "Ehhez a kiegészítőhöz a fejlesztő a(z) %s helyen nyújt támogatást."
+
+#: views/addons/display.thtml:383
+msgid "addons_display_rate_it"
+msgstr "Értékelés"
+
+#: views/reviews/add.thtml:93 views/reviews/add.thtml:94
+msgid "addons_display_really_like_it"
+msgstr "Nagyon szeretem"
+
+#: views/addons/display.thtml:410
+msgid "addons_display_review_etiquette"
+msgstr ""
+"Kérjük, ne írjon hibajelentést az értékelésbe. Az e-mail címét nem adjuk "
+"tovább a kiegészítők fejlesztőinek, és esetleg szükség lehet a "
+"kapcsolatfelvételre a probléma megoldásához."
+
+# %1 is the review guidelines link
+#. %1 is the review guidelines link
+#: views/addons/display.thtml:417
+msgid "addons_display_review_guidelines_link"
+msgstr "<a href=\"%s\">Értékelési útmutató</a>"
+
+# %1 is the support section link
+#. %1 is the support section link
+#: views/addons/display.thtml:414
+msgid "addons_display_review_see_support"
+msgstr ""
+"Nézze meg a <a href=\"%1$s\">támogatás szakaszban</a>, hogy milyen módon "
+"kaphat segítséget a kiegészítővel kapcsolatban."
+
+#: views/addons/display.thtml:404
+msgid "addons_display_review_submit"
+msgstr "Mentés"
+
+#: views/addons/display.thtml:430
+#, php-format
+msgid "addons_display_see_all_addons"
+msgstr "Minden %1$s kiegészítő megjelenítése"
+
+# %1 is the number of reviews
+#. %1 is the number of reviews
+#: views/addons/display.thtml:364
+#, php-format
+msgid "addons_display_see_all_reviews"
+msgstr "Minden értékelés (%1$s)"
+
+#: views/addons/display.thtml:219
+msgid "addons_display_see_all_versions"
+msgstr "Minden verzió megjelenítése"
+
+#: views/addons/display.thtml:321 views/addons/versions.thtml:117
+msgid "addons_display_view_source"
+msgstr "Forrás megtekintése"
+
+#: views/addons/display.thtml:324
+msgid "addons_display_view_stats"
+msgstr "Statisztika megtekintése"
+
+#: views/addons/display.thtml:376
+msgid "addons_display_what_do_you_think"
+msgstr "Mit gondol?"
+
+#: views/elements/app_compatibility.thtml:49
+msgid "addons_display_workswith"
+msgstr "Kompatibilis:"
+
+#: views/addons/home.thtml:112
+#, fuzzy
+msgid "addons_home_browse_new"
+msgstr "Just Added"
+
+#: views/addons/home.thtml:110
+#, fuzzy
+msgid "addons_home_browse_popular"
+msgstr "Popular"
+
+#: views/addons/home.thtml:108
+#, fuzzy
+msgid "addons_home_browse_recommended"
+msgstr "Recommended"
+
+#: views/addons/home.thtml:127 views/addons/home.thtml:134
+#: views/addons/home.thtml:141 views/addons/home.thtml:148
+#, fuzzy
+msgid "addons_home_browse_subscribe"
+msgstr "Subscribe"
+
+#: views/addons/home.thtml:101
+#, fuzzy
+msgid "addons_home_browse_title"
+msgstr "Browse Add-ons"
+
+#: views/addons/home.thtml:114
+#, fuzzy
+msgid "addons_home_browse_updated"
+msgstr "Updated"
+
+#: views/elements/amo2009/homepage_addon.thtml:100
+#: views/elements/addon_discussionheader.thtml:83
+#: views/elements/addon_listitem.thtml:109 views/elements/feature.thtml:95
+#: views/addons/category_landing.thtml:66 views/addons/policy.thtml:57
+#: views/addons/display.thtml:70 views/addons/home.thtml:178
+msgid "addons_home_by"
+msgstr ":"
+
+#: views/addons/home.thtml:169
+#, fuzzy
+msgid "addons_home_collection_popular_title"
+msgstr "Popular Collections"
+
+#: views/elements/amo2009/categories.thtml:69 views/addons/home.thtml:160
+#, fuzzy
+msgid "addons_home_collections"
+msgstr "Collections"
+
+#. %1$s is the count of addons in a collection
+#: views/elements/amo2009/collection_listing_item.thtml:51
+#: views/addons/home.thtml:185
+#, fuzzy
+msgid "addons_home_collections_addon_count"
+msgid_plural "addons_home_collections_addon_count"
+msgstr[0] "<strong>%1$s</strong> add-on"
+msgstr[1] "<strong>%1$s</strong> add-ons"
+
+#: views/addons/home.thtml:196
+#, fuzzy
+msgid "addons_home_collections_all"
+msgstr "View All Collections"
+
+#: views/addons/home.thtml:162
+#, fuzzy
+msgid "addons_home_collections_intro"
+msgstr ""
+"Collections are a way for you to categorize, mix, match and mingle add-ons. "
+"Subscribe to collections created by other users or create your own."
+
+#. %1$s is the count of subscribers for a collection
+#: views/elements/amo2009/collection_listing_item.thtml:58
+#: views/collections/detail.thtml:96 views/addons/home.thtml:189
+#, fuzzy
+msgid "addons_home_collections_subscribers"
+msgid_plural "addons_home_collections_subscribers"
+msgstr[0] "<strong>%1$s</strong> subscriber"
+msgstr[1] "<strong>%1$s</strong> subscribers"
+
+#: views/addons/searchengines.thtml:54 views/addons/themes_landing.thtml:49
+msgid "addons_home_feature_head"
+msgstr "Javasoljuk"
+
+#: controllers/search_controller.php:218 controllers/addons_controller.php:176
+#: controllers/addons_controller.php:428 controllers/addons_controller.php:671
+#: controllers/addons_controller.php:871
+#: controllers/addons_controller.php:1103
+#: controllers/addons_controller.php:1242
+#: controllers/addons_controller.php:1298
+#, php-format
+msgid "addons_home_header_details"
+msgstr ""
+"A kiegészítők bővítik a %1$s képességeit, lehetővé teszik a böngésző "
+"testreszabását. Nézzen körül, és szabja testre a %1$s alkalmazást!"
+
+#. %1$s is the HTML collection name link.
+#: views/elements/amo2009/teaser_collections.thtml:107
+#, fuzzy
+msgid "addons_home_introduction_collection_link"
+msgstr "Like these? Find more add-ons in %1$s."
+
+#: views/elements/amo2009/teaser_collections.thtml:60
+#, fuzzy
+msgid "addons_home_introduction_extras"
+msgstr ""
+"<strong>Over 5000 free extras</strong> that let you customize and extend "
+"Firefox to meet your needs."
+
+#: views/elements/amo2009/teaser_collections.thtml:55
+#, fuzzy
+msgid "addons_home_introduction_header"
+msgstr "What are Add-ons?"
+
+#: views/elements/amo2009/teaser_collections.thtml:72
+#, fuzzy
+msgid "addons_home_introduction_install"
+msgstr ""
+"<strong>Easy to install</strong>, get notified when updates are available."
+
+#: views/elements/amo2009/teaser_collections.thtml:45
+#, fuzzy
+msgid "addons_home_introduction_name"
+msgstr "Introduction"
+
+#: views/elements/amo2009/teaser_collections.thtml:66
+#, fuzzy
+msgid "addons_home_introduction_themes"
+msgstr ""
+"Toolbars, themes and search providers that <strong>help you perform common "
+"tasks.</strong>"
+
+#: views/addons/home.thtml:161
+#, fuzzy
+msgid "addons_home_new_indicator"
+msgstr "NEW!"
+
+#: views/elements/app_chooser.thtml:48 views/layouts/amo2009.thtml:257
+msgid "addons_home_other_applications"
+msgstr "Más alkalmazások"
+
+#. %1$s is the application the user is browsing. Examples: Thunderbird, Firefox,
+#. Sunbird
+#: views/pages/collector_faq.thtml:49 views/pages/collector_firstrun.thtml:42
+#: views/pages/collector.thtml:46 views/pages/collector_features.thtml:54
+#: controllers/developers_controller.php:87
+#: controllers/compatibility_controller.php:72
+#: controllers/components/simple_acl.php:81 controllers/components/amo.php:607
+#: controllers/statistics_controller.php:60
+#: controllers/statistics_controller.php:240
+#: controllers/previews_controller.php:67 controllers/users_controller.php:90
+#: controllers/users_controller.php:223 controllers/users_controller.php:330
+#: controllers/users_controller.php:414 controllers/users_controller.php:708
+#: controllers/users_controller.php:723 controllers/reviews_controller.php:204
+#: controllers/reviews_controller.php:251
+#: controllers/reviews_controller.php:346
+#: controllers/reviews_controller.php:425
+#: controllers/search_controller.php:185 controllers/search_controller.php:297
+#: controllers/search_controller.php:301 controllers/addons_controller.php:147
+#: controllers/addons_controller.php:280 controllers/addons_controller.php:370
+#: controllers/addons_controller.php:667 controllers/addons_controller.php:874
+#: controllers/addons_controller.php:1019
+#: controllers/addons_controller.php:1034
+#: controllers/addons_controller.php:1101
+#: controllers/addons_controller.php:1121
+#: controllers/addons_controller.php:1240
+#: controllers/addons_controller.php:1357
+#: controllers/addons_controller.php:1364
+#: controllers/addons_controller.php:1442
+#: controllers/addons_controller.php:1477
+#: controllers/addons_controller.php:1538
+#: controllers/addons_controller.php:1543
+#: controllers/editors_controller.php:64 controllers/pages_controller.php:132
+#: controllers/groups_controller.php:65 controllers/groups_controller.php:71
+#: controllers/groups_controller.php:89 controllers/groups_controller.php:111
+#: controllers/collections_controller.php:57
+#: controllers/collections_controller.php:121
+#: controllers/collections_controller.php:205
+#: controllers/collections_controller.php:365
+#: controllers/collections_controller.php:404
+#: controllers/collections_controller.php:466
+#: controllers/collections_controller.php:538
+#: controllers/collections_controller.php:828
+#: controllers/localizers_controller.php:72
+#, php-format
+msgid "addons_home_pagetitle"
+msgstr "%1$s-kiegészítők"
+
+#. %1$s is the number of addons downloaded
+#: views/addons/home.thtml:57
+#, fuzzy, php-format
+msgid "addons_home_stats_downloaded"
+msgid_plural "addons_home_stats_downloaded"
+msgstr[0] "<strong>%1$s</strong> <span>add-on downloaded</span>"
+msgstr[1] "<strong>%1$s</strong> <span>add-ons downloaded</span>"
+
+#. %1$s is the number of addons in use
+#: views/addons/home.thtml:63
+#, fuzzy, php-format
+msgid "addons_home_stats_inuse"
+msgid_plural "addons_home_stats_inuse"
+msgstr[0] "<strong>%1$s</strong> <span>add-on in use</span>"
+msgstr[1] "<strong>%1$s</strong> <span>add-ons in use</span>"
+
+#: views/addons/home.thtml:136
+msgid "addons_home_view_all_newest_title"
+msgstr "Az összes újonnan létrehozott kiegészítő megtekintése"
+
+#: views/addons/home.thtml:129
+msgid "addons_home_view_all_popular_title"
+msgstr "Az összes népszerű kiegészítő megtekintése"
+
+#: views/addons/home.thtml:150
+msgid "addons_home_view_all_recommended_title"
+msgstr "Az összes javasolt kiegészítő megtekintése"
+
+#: views/addons/home.thtml:143
+msgid "addons_home_view_all_updated_title"
+msgstr "Az összes nemrég frissített kiegészítő megtekintése"
+
+#: views/elements/amo2009/install.thtml:334 views/elements/install.thtml:112
+msgid "addons_install_in_sunbird"
+msgstr ""
+"<ol><li>A fájl mentéséhez kattintson az alábbi hivatkozásra.</li><li>A "
+"Mozilla Sunbirdben válassza az Eszközök menü Kiegészítők parancsát.</"
+"li><li>Kattintson a Telepítés gombra, majd keresse meg az imént letöltött "
+"fájlt, és kattintson az OK gombra.</li></ol>"
+
+#: views/elements/amo2009/install.thtml:333 views/elements/install.thtml:111
+msgid "addons_install_in_sunbird_title"
+msgstr "Telepítés a Sunbirdben"
+
+#: views/elements/amo2009/install.thtml:331 views/elements/install.thtml:106
+msgid "addons_install_in_thunderbird"
+msgstr ""
+"<ol><li>Kattintson a jobb egérgombbal az alábbi hivatkozásra, majd válassza "
+"a \"Hivatkozás mentése másként...\" lehetőséget a fájl letöltéséhez és "
+"merevlemezre mentéséhez.</li><li>A Mozilla Thunderbirdben válassza az "
+"Eszközök menü Kiegészítők parancsát.</li><li>Kattintson a Telepítés gombra, "
+"keresse meg az imént letöltött fájlt, majd kattintson az OK gombra.</li></ol>"
+
+#: views/elements/amo2009/install.thtml:330 views/elements/install.thtml:105
+msgid "addons_install_in_thunderbird_title"
+msgstr "Telepítés a Thunderbirdben"
+
+#: views/elements/amo2009/addon_list_options.thtml:108
+#: views/elements/addon_list_options.thtml:105
+msgid "addons_options_show_experimental"
+msgstr "kísérleti kiegészítők megjelenítése"
+
+#: views/elements/amo2009/addon_list_options.thtml:113
+#: views/elements/addon_list_options.thtml:109
+msgid "addons_options_submit"
+msgstr "Ugrás"
+
+#: views/addons/plugins.thtml:63 views/addons/plugins.thtml:73
+#: views/addons/plugins.thtml:83 views/addons/plugins.thtml:93
+#: views/addons/plugins.thtml:103 views/addons/plugins.thtml:116
+#: views/addons/plugins.thtml:126
+msgid "addons_plugins_by"
+msgstr ":"
+
+#: views/addons/plugins.thtml:107
+msgid "addons_plugins_for_linux"
+msgstr "Linuxra"
+
+#: views/addons/plugins.thtml:108 views/addons/plugins.thtml:131
+msgid "addons_plugins_for_macosx"
+msgstr "Mac OS X-re"
+
+#: views/addons/plugins.thtml:106 views/addons/plugins.thtml:129
+#: views/addons/plugins.thtml:130
+msgid "addons_plugins_for_windows"
+msgstr "Windowsra"
+
+#. %1$s is a URL
+#: views/addons/plugins.thtml:139
+#, php-format
+msgid "addons_plugins_looking_for_more"
+msgstr ""
+"Ez az oldal csak a leggyakrabban használt és legnépszerűbb bővítményeket "
+"sorolja fel. A Mozilla-alapú böngészőkhöz való bővítményekről szóló további "
+"információkért keresse fel a %1$s címet."
+
+#: views/addons/plugins.thtml:137
+msgid "addons_plugins_looking_for_plugin"
+msgstr "Olyan bővítményt keres, amely itt nincs felsorolva?"
+
+#: views/addons/plugins.thtml:58
+msgid "addons_plugins_main_description"
+msgstr ""
+"A bővítmények lehetővé teszik egyes speciális képfájlformátumok vagy "
+"multimédia fájlok megtekintését, illetve lejátszását a böngészőben. A "
+"bővítmények némileg különböznek a kiterjesztésektől, amelyek meglévő "
+"funkciót módosítanak vagy bővítenek."
+
+#. %1$s is the application name. Example: Firefox, Thunderbird, Sunbird
+#: controllers/addons_controller.php:1122
+#, php-format
+msgid "addons_plugins_main_header"
+msgstr "A %1$s legfontosabb bővítményei"
+
+#: controllers/components/amo.php:698 controllers/addons_controller.php:1121
+msgid "addons_plugins_pagetitle"
+msgstr "Bővítmények"
+
+#: views/addons/plugins.thtml:68 views/addons/plugins.thtml:78
+#: views/addons/plugins.thtml:88 views/addons/plugins.thtml:98
+#: views/addons/plugins.thtml:110 views/addons/plugins.thtml:121
+#: views/addons/plugins.thtml:133
+msgid "addons_plugins_support_documentation"
+msgstr "Támogató dokumentáció: "
+
+#. %s is the name of the add-on
+#: views/addons/policy.thtml:61
+#, php-format
+msgid "addons_policy_eula_require"
+msgstr ""
+"A(z) %s az kívánja, hogy fogadja el az EULA-t (végfelhasználói "
+"licencszerződést) a telepítés folytatása előtt:"
+
+# %1 is the addon name
+#. %1 is the add-on name
+#: controllers/addons_controller.php:1476
+#, php-format
+msgid "addons_previews_pagetitle"
+msgstr "%s előnézetei"
+
+#: views/addons/category_landing.thtml:135
+#, fuzzy
+msgid "addons_recently_added"
+msgstr "Recently Added"
+
+#: views/addons/recommended.thtml:51 controllers/addons_controller.php:1365
+msgid "addons_recommended_introduction"
+msgstr ""
+"A sok kiegészítő közül mindenki megtalálja a magának valót. Kezdésnek "
+"közreadunk egy listát a legnépszerűbbekről. Jó szórakozást!"
+
+#: controllers/addons_controller.php:1357
+#: controllers/addons_controller.php:1364
+msgid "addons_recommended_pagetitle"
+msgstr "Javasolt kiegészítők"
+
+#: controllers/addons_controller.php:1360
+msgid "addons_recommended_title"
+msgstr "Javasolt kiegészítők"
+
+#: views/addons/searchengines.thtml:136
+msgid "addons_searchengines_additional_resources"
+msgstr "További források"
+
+# link text devmo
+#. link text devmo
+#: views/addons/searchengines.thtml:141
+msgid "addons_searchengines_devmo_link"
+msgstr "Mozilla Developer Center"
+
+#: views/pages/js_constants.js.thtml:67
+msgid "addons_searchengines_error_mozilla_browser_required"
+msgstr ""
+"Sajnáljuk, de a keresők telepítéséhez Mozilla-alapú böngésző (például "
+"Firefox) szükséges."
+
+#: views/addons/searchengines.thtml:49
+msgid "addons_searchengines_error_nojavascript"
+msgstr ""
+"A keresők telepítéséhez JavaScript szükséges, de úgy tűnik, hogy ez le van "
+"tiltva. Engedélyezze a JavaScriptet a keresők telepítésének megkísérlése "
+"előtt."
+
+# %1 is "make your own" link
+# %2 is MDC link
+#. %1 is "make your own" link
+#. %2 is MDC link
+#: views/addons/searchengines.thtml:139
+msgid "addons_searchengines_learn_howto"
+msgstr "A %2$s webhelyen olvassa el, hogy %1$s."
+
+# link path to search plugins instructions, relative to devmo
+#. link path to search plugins instructions, relative to devmo
+#: views/addons/searchengines.thtml:140
+msgid "addons_searchengines_makeyourown_href"
+msgstr "/en/docs/Creating_OpenSearch_plugins_for_Firefox"
+
+# link text for "make your own" (opensearch engine)
+#. link text for "make your own" (opensearch engine)
+#: views/addons/searchengines.thtml:140
+msgid "addons_searchengines_makeyourown_link"
+msgstr "hozhat létre saját keresőt"
+
+# %1 is the link to mycroft.mozdev.org
+#. %1 is the link to mycroft.mozdev.org
+#: views/addons/searchengines.thtml:138
+msgid "addons_searchengines_more"
+msgstr "További keresők között böngészhet a %1$s webhelyen."
+
+# link text to mycroft.mozdev.org
+#. link text to mycroft.mozdev.org
+#: views/addons/searchengines.thtml:138
+msgid "addons_searchengines_mycroft_link"
+msgstr "mycroft.mozdev.org"
+
+#: controllers/addons_controller.php:1100
+#: controllers/addons_controller.php:1110
+msgid "addons_searchengines_pagetitle"
+msgstr "Keresők"
+
+#: views/addons/searchengines.thtml:143
+msgid "addons_searchengines_thanks"
+msgstr ""
+"Külön köszönet a Mycroft Projectnek a Firefox keresőivel kapcsolatos "
+"munkájukért."
+
+#: views/addons/display.thtml:154
+#, fuzzy
+msgid "addons_share_button_text"
+msgstr "Share this"
+
+#: controllers/addons_controller.php:89
+#, fuzzy
+msgid "addons_share_label_delicious"
+msgstr "Add to Delicious"
+
+#: controllers/addons_controller.php:77
+#, fuzzy
+msgid "addons_share_label_digg"
+msgstr "Digg this!"
+
+#: controllers/addons_controller.php:83
+#, fuzzy
+msgid "addons_share_label_facebook"
+msgstr "Post to Facebook"
+
+#: controllers/addons_controller.php:101
+#, fuzzy
+msgid "addons_share_label_friendfeed"
+msgstr "Share on FriendFeed"
+
+#: controllers/addons_controller.php:95
+#, fuzzy
+msgid "addons_share_label_myspace"
+msgstr "Post to MySpace"
+
+#: controllers/components/amo.php:201 controllers/components/amo.php:229
+msgid "addons_status_disabled"
+msgstr "Letiltva"
+
+#: controllers/components/amo.php:191 controllers/components/amo.php:224
+msgid "addons_status_incomplete"
+msgstr "Nem teljes verzió"
+
+#: controllers/components/amo.php:197 controllers/components/amo.php:227
+msgid "addons_status_nominated"
+msgstr "Homokozóban, nyilvánosnak jelölve"
+
+#: views/pages/js_constants.js.thtml:80 controllers/components/amo.php:195
+#: controllers/components/amo.php:226
+msgid "addons_status_pending"
+msgstr "Homokozóban, értékelés függőben"
+
+#: views/pages/js_constants.js.thtml:78 controllers/components/amo.php:199
+#: controllers/components/amo.php:228
+msgid "addons_status_public"
+msgstr "Nyilvános"
+
+#: views/pages/js_constants.js.thtml:79 controllers/components/amo.php:193
+#: controllers/components/amo.php:225
+msgid "addons_status_sandbox"
+msgstr "Homokozóban"
+
+#: controllers/components/amo.php:203
+msgid "addons_status_unknown"
+msgstr "Ismeretlen"
+
+#: views/elements/amo2009/teaser_collections.thtml:91
+#: views/elements/amo2009/homepage_addon.thtml:99
+#: views/elements/feature.thtml:94
+msgid "addons_title_tooltip"
+msgstr "További tudnivalók a kiegészítőről"
+
+#: views/addons/category_landing.thtml:151
+#, fuzzy
+msgid "addons_top_downloads"
+msgstr "Top Downloads"
+
+#: views/addons/category_landing.thtml:165
+#, fuzzy
+msgid "addons_top_rated"
+msgstr "Top Rated"
+
+#: views/addons/versions.thtml:62
+msgid "addons_versions_careful"
+msgstr "Legyen óvatos a régi verziókkal"
+
+#: views/addons/versions.thtml:63
+msgid "addons_versions_careful_introduction"
+msgstr ""
+"Ezek a verziók csak tanulmányozás és tesztelés céljából jelennek meg. Mindig "
+"a kiegészítő legújabb verzióját használja."
+
+#: controllers/addons_controller.php:1549
+msgid "addons_versions_history"
+msgstr "Verziótörténet a módosítások naplójával"
+
+#. %1$s is the add-on name
+#: controllers/addons_controller.php:1535
+#, php-format
+msgid "addons_versions_pagetitle"
+msgstr "%1$s verziótörténete"
+
+#: controllers/groups_controller.php:71
+msgid "admin_group_add_pagetitle"
+msgstr "Csoport hozzáadása"
+
+#: controllers/groups_controller.php:111
+msgid "admin_group_delete_pagetitle"
+msgstr "Csoport törlése"
+
+#. %s is a number to identify the group
+#: controllers/groups_controller.php:117
+#, php-format
+msgid "admin_group_deleted"
+msgstr "A(z) %s azonosítójú csoport törölve lett."
+
+#: controllers/groups_controller.php:89
+msgid "admin_group_edit_pagetitle"
+msgstr "Csoport szerkesztése"
+
+#: controllers/groups_controller.php:92 controllers/groups_controller.php:113
+msgid "admin_group_error_invalid_id"
+msgstr "Érvénytelen csoportazonosító"
+
+#: controllers/groups_controller.php:65
+msgid "admin_group_pagetitle"
+msgstr "Csoportadminisztrátor"
+
+#: controllers/groups_controller.php:77 controllers/groups_controller.php:99
+msgid "admin_group_saved"
+msgstr "A csoport mentve lett"
+
+#: views/elements/amo2009/search.thtml:257 views/elements/search.thtml:239
+msgid "advanced_search_form"
+msgstr "Speciális"
+
+#: views/elements/amo2009/search.thtml:126 views/elements/search.thtml:125
+msgid "advanced_search_form_any_time"
+msgstr "Bármikor"
+
+#: views/elements/amo2009/search.thtml:97
+#: views/elements/amo2009/search.thtml:110 views/elements/search.thtml:96
+#: views/elements/search.thtml:109
+msgid "advanced_search_form_any_type"
+msgstr "Bármilyen"
+
+#: views/elements/amo2009/search.thtml:275 views/elements/search.thtml:254
+msgid "advanced_search_form_any_version"
+msgstr "Bármelyik"
+
+#: views/elements/amo2009/search.thtml:217 views/elements/search.thtml:212
+msgid "advanced_search_form_application"
+msgstr "Alkalmazás"
+
+#: views/elements/amo2009/search.thtml:143 views/elements/search.thtml:142
+msgid "advanced_search_form_keyword_match"
+msgstr "Kulcsszóegyezés"
+
+#: views/elements/amo2009/search.thtml:251 views/elements/search.thtml:225
+msgid "advanced_search_form_lastupdate"
+msgstr "Utolsó frissítés"
+
+#: views/elements/amo2009/search.thtml:145 views/elements/search.thtml:144
+msgid "advanced_search_form_name"
+msgstr "Név"
+
+#: views/elements/amo2009/search.thtml:144 views/elements/search.thtml:143
+msgid "advanced_search_form_newest"
+msgstr "Legújabb"
+
+#: views/elements/amo2009/search.thtml:130 views/elements/search.thtml:129
+msgid "advanced_search_form_past_3_months"
+msgstr "Elmúlt 3 hónap"
+
+#: views/elements/amo2009/search.thtml:131 views/elements/search.thtml:130
+msgid "advanced_search_form_past_6_months"
+msgstr "Elmúlt 6 hónap"
+
+#: views/elements/amo2009/search.thtml:127 views/elements/search.thtml:126
+msgid "advanced_search_form_past_day"
+msgstr "Múlt nap"
+
+#: views/elements/amo2009/search.thtml:129 views/elements/search.thtml:128
+msgid "advanced_search_form_past_month"
+msgstr "Múlt hónap"
+
+#: views/elements/amo2009/search.thtml:128 views/elements/search.thtml:127
+msgid "advanced_search_form_past_week"
+msgstr "Múlt hét"
+
+#: views/elements/amo2009/search.thtml:132 views/elements/search.thtml:131
+msgid "advanced_search_form_past_year"
+msgstr "Múlt év"
+
+#: views/elements/amo2009/search.thtml:239 views/elements/search.thtml:230
+msgid "advanced_search_form_perpage"
+msgstr "Oldalanként"
+
+#: views/elements/amo2009/search.thtml:243 views/elements/search.thtml:224
+msgid "advanced_search_form_platform"
+msgstr "Platform"
+
+#: views/elements/amo2009/search.thtml:147 views/elements/search.thtml:146
+msgid "advanced_search_form_popularity"
+msgstr "Népszerűség"
+
+#: views/elements/amo2009/search.thtml:146 views/elements/search.thtml:145
+msgid "advanced_search_form_rating"
+msgstr "Osztályzat"
+
+#: views/elements/amo2009/search.thtml:247 views/elements/search.thtml:231
+msgid "advanced_search_form_sortby"
+msgstr "Rendezés"
+
+#: views/elements/amo2009/search.thtml:227 views/elements/search.thtml:216
+msgid "advanced_search_form_to"
+msgstr "-"
+
+#: views/elements/amo2009/search.thtml:257 views/elements/search.thtml:237
+msgid "advanced_search_form_toggle_tooltip"
+msgstr "Speciális keresés ki-/bekapcsolója"
+
+#: views/elements/amo2009/search.thtml:235 views/elements/search.thtml:223
+msgid "advanced_search_form_type"
+msgstr "Típus"
+
+#: views/elements/amo2009/search.thtml:222 views/elements/search.thtml:214
+msgid "advanced_search_form_version"
+msgstr "verzió"
+
+#: views/elements/amo2009/pagination.thtml:42
+#, fuzzy
+msgid "amo2009_pagination_next_page"
+msgstr "Next"
+
+#: views/elements/amo2009/pagination.thtml:41
+#, fuzzy
+msgid "amo2009_pagination_previous_page"
+msgstr "Prev"
+
+#: views/pages/js_constants.js.thtml:96
+msgid "app_compat_ignore_check"
+msgstr "Verzió-ellenőrzés kihagyása"
+
+#: views/pages/js_constants.js.thtml:72
+msgid "app_compat_older_firefox_only"
+msgstr "Ez a kiegészítő a Firefox régebbi verzióihoz való"
+
+#. %1$s and %2$s are URLs
+#: views/pages/js_constants.js.thtml:74
+msgid "app_compat_older_version_or_ignore_check"
+msgstr ""
+"<a href=\"%1$s\">Kipróbálhat egy régebbi verziót</a> vagy <a href=\"#\" "
+"onclick=\"%2$s\">kihagyhatja ezt az ellenőrzést</a>."
+
+#. %1$s is a URL
+#: views/pages/js_constants.js.thtml:71
+msgid "app_compat_try_old_version"
+msgstr "Egy <a href=\"%1$s\">régebbi verzió</a> működhet"
+
+#. %1$s is a URL
+#. %2$s is a version number. Example: 3.1
+#: views/pages/js_constants.js.thtml:73
+msgid "app_compat_unreleased_version"
+msgstr ""
+"Ez a kiegészítő a még meg nem jelent <a href=\"%1$s\">Firefox %2$s</a> "
+"verziót igényli"
+
+#: views/pages/js_constants.js.thtml:70
+msgid "app_compat_update_firefox"
+msgstr ""
+"<a href=\"http://getfirefox.com\">Frissítse a Firefoxot</a> a kiegészítő "
+"használatához"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#. %3$s is a status, like Public.
+#: controllers/components/audit.php:79
+#, fuzzy
+msgid "audit_addon_status"
+msgstr "%1$s changed the status of %2$s to %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:221
+#, fuzzy
+msgid "audit_admin_default"
+msgstr "%1$s committed unknown admin action %2$s to ID %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:153
+#, fuzzy
+msgid "audit_admin_feature_remove"
+msgstr "%1$s removed feature %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is an application, like Firefox.
+#: controllers/components/audit.php:92
+#, fuzzy
+msgid "audit_application_create"
+msgstr "%1$s created application %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is an application, like Firefox.
+#: controllers/components/audit.php:95
+#, fuzzy
+msgid "audit_application_edit"
+msgstr "%1$s edited application %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a version number, like 3.5.
+#. %3$s is an application, like Firefox.
+#: controllers/components/audit.php:105
+#, fuzzy
+msgid "audit_appversion_create"
+msgstr "%1$s created version %2$s for %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a version number, like 3.5.
+#. %3$s is an application, like Firefox.
+#: controllers/components/audit.php:108
+#, fuzzy
+msgid "audit_appversion_delete"
+msgstr "%1$s deleted version %2$s for %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a config field, like "awesomeness".
+#. %3$s is a config value, like "off".
+#. %4$s is a config value, like "on".
+#: controllers/components/audit.php:210
+#, fuzzy
+msgid "audit_config"
+msgstr "%1$s changed config '%2$s' from '%3$s' to '%4$s'"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:258
+#, fuzzy
+msgid "audit_editor_default"
+msgstr "%1$s committed unknown editor action %2$s to ID %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#: controllers/components/audit.php:236
+#, fuzzy
+msgid "audit_editor_feature_remove"
+msgstr "%1$s removed addon %2$s from feature list"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#: controllers/components/audit.php:231
+#, fuzzy
+msgid "audit_feature_add"
+msgstr "%1$s added addon %2$s to feature list"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:149
+#, fuzzy
+msgid "audit_feature_edit"
+msgstr "%1$s changed a feature for %2$s locale"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#: controllers/components/audit.php:241
+#, fuzzy
+msgid "audit_feature_locale_change"
+msgstr "%1$s changed locales for addon %2$s on feature list"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:83
+#, fuzzy
+msgid "audit_file_recalchash"
+msgstr "%1$s recalculated the hash for file %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>user name</a>
+#. %3$s is <a>group name</a>
+#: controllers/components/audit.php:182
+#, fuzzy
+msgid "audit_group_addmember"
+msgstr "%1$s added %2$s to group %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:313
+#, fuzzy
+msgid "audit_group_associated"
+msgstr "%1$s associated themselves with %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:162
+#, fuzzy
+msgid "audit_group_create"
+msgstr "%1s created group %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:170
+#, fuzzy
+msgid "audit_group_delete"
+msgstr "%1$s deleted group %2$s (ID %3$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:165
+#, fuzzy
+msgid "audit_group_edit"
+msgstr "%1$s edited group %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>user name</a>
+#. %3$s is <a>group name</a>
+#: controllers/components/audit.php:188
+#, fuzzy
+msgid "audit_group_removemember"
+msgstr "%1$s removed %2$s from group %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:280
+#, fuzzy
+msgid "audit_l10n_default"
+msgstr "%1$s committed unknown action %2$s for %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:295
+#, fuzzy
+msgid "audit_modify_locked_group"
+msgstr "%1$s attempted to modify locked group %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:299
+#, fuzzy
+msgid "audit_modify_other_locale"
+msgstr "%1$s attempted to modify translations in %2$s without permission"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a platform, like <a>Windows</a>
+#: controllers/components/audit.php:135
+#, fuzzy
+msgid "audit_platform_create"
+msgstr "%1$s created platform %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a platform, like <a>Windows</a>
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:143
+#, fuzzy
+msgid "audit_platform_delete"
+msgstr "%1$s deleted platform %2$s (ID %3$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a platform, like <a>Windows</a>
+#: controllers/components/audit.php:138
+#, fuzzy
+msgid "audit_platform_edit"
+msgstr "%1$s edited platform %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a part of the admin, like 'Site Config'
+#: controllers/components/audit.php:288
+#, fuzzy
+msgid "audit_reauthentication_failure"
+msgstr "%1$s failed to re-authenticate to access %2$s."
+
+#. %1$s is <a>user name</a>
+#. %2$s is the name of a canned response, like 'Ready for the public'
+#: controllers/components/audit.php:198
+#, fuzzy
+msgid "audit_response_create"
+msgstr "%1$s created response %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is the name of a canned response, like 'Ready for the public'
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:206
+#, fuzzy
+msgid "audit_response_delete"
+msgstr "%1$s deleted response %2$s (ID %3$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is the name of a canned response, like 'Ready for the public'
+#: controllers/components/audit.php:201
+#, fuzzy
+msgid "audit_response_edit"
+msgstr "%1$s edited response %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:245
+#, fuzzy
+msgid "audit_review_approve"
+msgstr "%1$s approved review %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:250 controllers/components/audit.php:253
+#, fuzzy
+msgid "audit_review_delete"
+msgstr "%1$s deleted review %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:303
+#, fuzzy
+msgid "audit_security_default"
+msgstr "%1$s committed unknown security action %2$s to ID %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a category name, like <a>Search Tools</a>
+#: controllers/components/audit.php:118
+#, fuzzy
+msgid "audit_tag_create"
+msgstr "%1$s created tag %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a category name, like <a>Search Tools</a>
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:126
+#, fuzzy
+msgid "audit_tag_delete"
+msgstr "%1$s deleted category %2$s (ID %3$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a category name, like <a>Search Tools</a>
+#: controllers/components/audit.php:121
+#, fuzzy
+msgid "audit_tag_edit"
+msgstr "%1$s edited category %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:266
+#, fuzzy
+msgid "audit_update_applications"
+msgstr "%1$s updated application translations for %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:277
+#, fuzzy
+msgid "audit_update_blog"
+msgstr "%1$s updated blog post translations for %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:274
+#, fuzzy
+msgid "audit_update_platforms"
+msgstr "%1$s updated platform translations for %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:270
+#, fuzzy
+msgid "audit_update_tags"
+msgstr "%1$s updated category translations for %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>user name</a>
+#: controllers/components/audit.php:217
+#, fuzzy
+msgid "audit_user_edit"
+msgstr "%1$s edited %2$s's user information"
+
+#: controllers/addons_controller.php:1012
+msgid "browse_addons_name"
+msgstr "Kiegészítők név szerint"
+
+#: controllers/addons_controller.php:1010
+msgid "browse_addons_newest"
+msgstr "Legújabb kiegészítők"
+
+#: controllers/addons_controller.php:1008
+msgid "browse_addons_popular"
+msgstr "Népszerű kiegészítők"
+
+#: controllers/addons_controller.php:1011
+msgid "browse_addons_rated"
+msgstr "Kiegészítők osztályzat szerint"
+
+#: controllers/addons_controller.php:1009
+msgid "browse_addons_updated"
+msgstr "Nemrég frissített kiegészítők"
+
+#: views/elements/categories.thtml:73 views/elements/categories.thtml:82
+msgid "categories_current_title"
+msgstr "Aktuális kategória"
+
+#: views/elements/categories.thtml:50
+#: views/elements/amo2009/categories.thtml:43
+#: views/elements/amo2009/categories.thtml:45
+msgid "categories_header"
+msgstr "Kategóriák"
+
+#: views/elements/categories.thtml:50
+#: views/elements/amo2009/categories.thtml:41
+msgid "categories_header_title"
+msgstr "Kategória választása"
+
+# %1 is the category name
+#. %1$s is the category name
+#: views/addons/searchengines.thtml:129
+#, php-format
+msgid "category_extra_see_all"
+msgstr "Minden %1$s megjelenítése"
+
+#. %1$s is a number.
+#: models/collection.php:130
+#, fuzzy
+msgid "collection_description_limit"
+msgstr "The description should be less than %1$s characters."
+
+#. %1$s is the name of the collection
+#: controllers/collections_controller.php:392
+#, fuzzy
+msgid "collection_detail_rss_title"
+msgstr "%s Collection"
+
+#: controllers/collections_controller.php:1065
+#, fuzzy
+msgid "collection_error_deleting_addon"
+msgstr "Error deleting add-on!"
+
+#: controllers/collections_controller.php:1051
+#, fuzzy
+msgid "collection_error_saving_addon"
+msgstr "Error saving add-on!"
+
+#: controllers/collections_controller.php:1080
+#, fuzzy
+msgid "collection_error_saving_comment"
+msgstr "Error saving comment!"
+
+#. %1$s is a number.
+#: models/collection.php:122
+#, fuzzy
+msgid "collection_name_limit"
+msgstr "The name should be less than %1$s characters."
+
+#: controllers/collections_controller.php:352
+#: controllers/collections_controller.php:487
+msgid "collection_not_found"
+msgstr "A gyűjtemény nem található!"
+
+#. %1$s is the text on the "create collection" button
+#: views/collections/add.thtml:91
+#, fuzzy
+msgid "collections_add_formfield_addons_description"
+msgstr ""
+"If you already know which add-ons you want to add to your collection, just "
+"start typing their names below. If you'd rather wait and do this later, just "
+"click %1$s now."
+
+#: views/collections/add.thtml:90
+#, fuzzy
+msgid "collections_add_formfield_firstaddons"
+msgstr "Choose your first add-ons"
+
+#: views/collections/add.thtml:48
+#, fuzzy
+msgid "collections_add_header"
+msgstr "Create a Collection"
+
+#: views/collections/add.thtml:97
+#, fuzzy
+msgid "collections_add_header_selectedaddons"
+msgstr "Selected Add-ons"
+
+#: views/collections/add.thtml:50
+#, fuzzy
+msgid "collections_add_intro"
+msgstr ""
+"It's easy to create your own collection of add-ons by filling in a few "
+"fields below."
+
+#: views/collections/add.thtml:92 views/collections/add.thtml:103
+#, fuzzy
+msgid "collections_add_submit"
+msgstr "Create Collection"
+
+#: views/pages/collector_faq.thtml:50 views/pages/collector_firstrun.thtml:43
+#: views/pages/collector.thtml:47 views/pages/collector_features.thtml:55
+#: controllers/search_controller.php:302
+#: controllers/collections_controller.php:206
+#: controllers/collections_controller.php:405
+#: controllers/collections_controller.php:467
+#: controllers/collections_controller.php:539
+#, fuzzy
+msgid "collections_breadcrumb"
+msgstr "Collections"
+
+#: views/collections/detail.thtml:185
+#, fuzzy
+msgid "collections_detail_a_learn"
+msgstr "Learn More"
+
+#: views/elements/amo2009/collection_add_form.thtml:53
+#: views/elements/amo2009/collections_js_init.thtml:68
+#: views/pages/collector_firstrun.thtml:64
+#, fuzzy
+msgid "collections_detail_button_add"
+msgstr "Add to Favorites"
+
+#: views/elements/amo2009/collection_add_form.thtml:50
+#: views/elements/amo2009/collections_js_init.thtml:71
+#, fuzzy
+msgid "collections_detail_button_remove"
+msgstr "Remove from Favorites"
+
+#. %1$s is a URL.
+#. %2$s is a full <a href>.
+#: views/collections/detail.thtml:62
+#, fuzzy
+msgid "collections_detail_created_desc"
+msgstr ""
+"<p>You can view your new collection below. If you'd like to set a collection "
+"nickname, upload an icon, or change additional settings, please visit the <a "
+"href='%1$s'>Manage Collections</a> page.</p><p>Your collection can be "
+"accessed at this location: %2$s</p>"
+
+#: views/collections/detail.thtml:61
+#, fuzzy
+msgid "collections_detail_created_msg"
+msgstr "Your collection is now ready!"
+
+#: views/collections/detail.thtml:109
+#, fuzzy
+msgid "collections_detail_header_about"
+msgstr "About This Collection"
+
+#. %1$s is a number.
+#: views/collections/detail.thtml:126
+#, fuzzy
+msgid "collections_detail_header_count"
+msgid_plural "collections_detail_header_count"
+msgstr[0] "%1$s Add-on in this Collection"
+msgstr[1] "%1$s Add-ons in this Collection"
+
+#: views/collections/detail.thtml:113
+#, fuzzy
+msgid "collections_detail_info_created"
+msgstr "<strong>Created by:</strong> %1$s"
+
+#: views/collections/detail.thtml:117
+#, fuzzy
+msgid "collections_detail_info_updated"
+msgstr "<strong>Updated:</strong>"
+
+#: views/elements/amo2009/collections_js_init.thtml:62
+#, fuzzy
+msgid "collections_detail_js_adding"
+msgstr "Adding to Favorites&hellip;"
+
+#: views/elements/amo2009/collections_js_init.thtml:65
+#, fuzzy
+msgid "collections_detail_js_removing"
+msgstr "Removing Favorite&hellip;"
+
+#. %1$s is a URL
+#: views/collections/detail.thtml:90
+#, fuzzy
+msgid "collections_detail_login"
+msgstr "<a href=\"%1$s\">Log in</a> to add this collection to your favorites."
+
+#: views/collections/detail.thtml:104
+#, fuzzy
+msgid "collections_detail_manage"
+msgstr "Manage Collection"
+
+#: controllers/collections_controller.php:298
+#, fuzzy
+msgid "collections_detail_sort_date"
+msgstr "Date Added"
+
+#: controllers/collections_controller.php:299
+#, fuzzy
+msgid "collections_detail_sort_name"
+msgstr "Name"
+
+#: controllers/collections_controller.php:300
+#, fuzzy
+msgid "collections_detail_sort_popularity"
+msgstr "Popularity"
+
+#. %1$s is a number.
+#: views/collections/detail.thtml:166
+#, fuzzy
+msgid "collections_detail_weekly_downloads"
+msgid_plural "collections_detail_weekly_downloads"
+msgstr[0] "%1$s download this week"
+msgstr[1] "%1$s downloads this week"
+
+#: views/collections/edit.thtml:255
+#, fuzzy
+msgid "collections_edit_addons_delete_noscript"
+msgstr "Selected add-ons will be removed upon Save"
+
+#: views/collections/edit.thtml:247
+#, fuzzy
+msgid "collections_edit_addons_description"
+msgstr ""
+"To publish new add-ons to this collection, start typing their names below."
+
+#: views/collections/edit.thtml:248
+#, fuzzy
+msgid "collections_edit_addons_description_noscript"
+msgstr ""
+"To publish new add-ons to this collection, enter a comma-separated list of "
+"Add-on IDs below."
+
+#: views/collections/edit.thtml:247 views/collections/edit.thtml:248
+#, fuzzy
+msgid "collections_edit_addons_description_publish_detailspage"
+msgstr "You can also publish an add-on from its normal listing page."
+
+#. %1$s is the date the add-on was added to the collection
+#. %1$s is the name of the user who added the add-on to the collection
+#: views/collections/edit.thtml:260
+#, fuzzy
+msgid "collections_edit_addons_listitem_added"
+msgstr "Added %1$s by %2$s"
+
+#: views/collections/edit.thtml:263
+#, fuzzy
+msgid "collections_edit_addons_listitem_comment_add"
+msgstr "Add publisher comment"
+
+#: views/collections/edit.thtml:266
+#, fuzzy
+msgid "collections_edit_addons_listitem_comment_delete"
+msgstr "Delete publisher comment"
+
+#: views/collections/edit.thtml:265
+#, fuzzy
+msgid "collections_edit_addons_listitem_comment_edit"
+msgstr "Edit publisher comment"
+
+#: views/collections/edit.thtml:271
+#, fuzzy
+msgid "collections_edit_addons_listitem_comment_note"
+msgstr ""
+"Note: Comment will appear as though written by original publisher on the "
+"original publication date"
+
+#: views/collections/edit.thtml:270
+#, fuzzy
+msgid "collections_edit_addons_listitem_comment_submit"
+msgstr "Save Comment"
+
+#: views/collections/edit.thtml:261
+#, fuzzy
+msgid "collections_edit_addons_listitem_remove"
+msgstr "Remove"
+
+#: views/collections/edit.thtml:250
+#, fuzzy
+msgid "collections_edit_addons_submit"
+msgstr "Add to Collection"
+
+#: views/collections/edit.thtml:153
+#, fuzzy
+msgid "collections_edit_check_nickname"
+msgstr "Check Availability"
+
+#: views/collections/edit.thtml:299
+#, fuzzy
+msgid "collections_edit_confirm_deletecollection"
+msgstr "Yes, I would like to delete this collection."
+
+#. %1$s is the label of the edit form's submit button
+#: views/collections/edit.thtml:300
+#, fuzzy
+msgid "collections_edit_confirm_deletecollection_description"
+msgstr "Check the box, then click on \"%1$s\" to delete this collection."
+
+#. %1$s is the "delete" submit button text
+#. %2$s is the title of the "advanced" tab
+#: views/collections/edit.thtml:95
+#, fuzzy
+msgid "collections_edit_delete_upon_submit"
+msgstr ""
+"Upon clicking \"%1$s\" below, your collection will be deleted. If you do not "
+"want to delete your collection, uncheck the confirmation box in the \"%2$s\" "
+"tab and continue editing your collection. If you leave this page without "
+"saving, your collection will also not be deleted."
+
+#: views/collections/edit.thtml:94
+#, fuzzy
+msgid "collections_edit_delete_warning"
+msgstr "Your collection is about to be deleted!"
+
+#: views/collections/add.thtml:76 views/collections/edit.thtml:144
+#, fuzzy
+msgid "collections_edit_form_error_description"
+msgstr "You must provide a description of your collection."
+
+#: views/collections/edit.thtml:181
+#, fuzzy
+msgid "collections_edit_form_error_icon"
+msgstr "There was an error uploading your icon."
+
+#: views/collections/add.thtml:69 views/collections/edit.thtml:130
+#, fuzzy
+msgid "collections_edit_form_error_name"
+msgstr "You must give your collection a name."
+
+#: views/collections/edit.thtml:158
+#, fuzzy
+msgid "collections_edit_form_error_nickname"
+msgstr "If you choose a nickname, it must be unique."
+
+#: views/collections/add.thtml:93 views/collections/edit.thtml:249
+#, fuzzy
+msgid "collections_edit_formfield_addons"
+msgstr "Add-on name:"
+
+#: views/collections/edit.thtml:281
+#, fuzzy
+msgid "collections_edit_formfield_application"
+msgstr "Associated Application"
+
+#: views/collections/edit.thtml:282
+#, fuzzy
+msgid "collections_edit_formfield_application_description"
+msgstr "Select the application that your collection supports."
+
+#: views/collections/edit.thtml:288
+#, fuzzy
+msgid "collections_edit_formfield_collectiontype"
+msgstr "Collection Type"
+
+#: views/collections/edit.thtml:295
+#, fuzzy
+msgid "collections_edit_formfield_deletecollection"
+msgstr "Delete Collection"
+
+#: views/collections/edit.thtml:296
+#, fuzzy
+msgid "collections_edit_formfield_deletecollection_description"
+msgstr "Deleting your collection will permanently erase it."
+
+#: views/collections/add.thtml:73 views/collections/edit.thtml:140
+#, fuzzy
+msgid "collections_edit_formfield_description"
+msgstr "Collection Description"
+
+#: views/collections/add.thtml:74 views/collections/edit.thtml:141
+#, fuzzy
+msgid "collections_edit_formfield_description_description"
+msgstr "Briefly describe your collection and the kind of add-ons in it"
+
+#: views/collections/edit.thtml:162
+#, fuzzy
+msgid "collections_edit_formfield_icon"
+msgstr "Icon"
+
+#: views/collections/edit.thtml:163
+#, fuzzy
+msgid "collections_edit_formfield_icon_description"
+msgstr ""
+"You can upload a JPG, GIF or PNG icon that will be resized to 32x32 pixels."
+
+#: views/collections/add.thtml:80 views/collections/edit.thtml:189
+#, fuzzy
+msgid "collections_edit_formfield_listed"
+msgstr "Who can view your collection?"
+
+#: views/collections/add.thtml:81 views/collections/edit.thtml:190
+#, fuzzy
+msgid "collections_edit_formfield_listed_description"
+msgstr ""
+"By default, collections appear in the public Collection Directory and are "
+"discoverable by anyone. If you want to restrict your collection to be "
+"viewable only by people who are given a special link, choose that option "
+"below."
+
+#: views/collections/add.thtml:84 views/collections/edit.thtml:193
+#, fuzzy
+msgid "collections_edit_formfield_listed_false"
+msgstr "Only people I invite can view my collection"
+
+#: views/collections/add.thtml:83 views/collections/edit.thtml:192
+#, fuzzy
+msgid "collections_edit_formfield_listed_true"
+msgstr "Everyone can view my collection in the directory"
+
+#: views/collections/edit.thtml:223
+#, fuzzy
+msgid "collections_edit_formfield_managers"
+msgstr "Who can manage my collection?"
+
+#: views/collections/edit.thtml:224
+#, fuzzy
+msgid "collections_edit_formfield_managers_description"
+msgstr ""
+"These users can publish add-ons to your collection, manage all add-ons and "
+"settings, and grant other users permission."
+
+#: views/collections/add.thtml:66 views/collections/edit.thtml:126
+#, fuzzy
+msgid "collections_edit_formfield_name"
+msgstr "Collection Name"
+
+#: views/collections/add.thtml:67 views/collections/edit.thtml:127
+#, fuzzy
+msgid "collections_edit_formfield_name_description"
+msgstr ""
+"Give your collection a descriptive name, such as \"Dave's Favorite Travel "
+"Add-ons\""
+
+#: views/collections/edit.thtml:148
+#, fuzzy
+msgid "collections_edit_formfield_nickname"
+msgstr "Collection Nickname"
+
+#: views/collections/edit.thtml:149
+#, fuzzy
+msgid "collections_edit_formfield_nickname_description"
+msgstr "Optionally, give your collection a unique nickname for quick access:"
+
+#: views/collections/edit.thtml:201
+#, fuzzy
+msgid "collections_edit_formfield_publishers"
+msgstr "Who can publish add-ons to your collection?"
+
+#: views/collections/edit.thtml:202
+#, fuzzy
+msgid "collections_edit_formfield_publishers_description"
+msgstr ""
+"These users can publish add-ons to your collection and remove add-ons that "
+"they publish."
+
+#: views/collections/edit.thtml:210 views/collections/edit.thtml:232
+#, fuzzy
+msgid "collections_edit_formfield_users_add"
+msgstr "Enter the e-mail address of a Firefox Add-ons account:"
+
+#: views/collections/edit.thtml:216 views/collections/edit.thtml:238
+#, fuzzy
+msgid "collections_edit_formfield_users_delete_noscript"
+msgstr "Selected accounts will be removed upon Save"
+
+#: views/collections/edit.thtml:215 views/collections/edit.thtml:237
+#, fuzzy
+msgid "collections_edit_formfield_users_new_noscript"
+msgstr ""
+"Enter a comma-separated list of e-mail addresses of Firefox Add-ons accounts"
+
+#: views/collections/edit.thtml:204 views/collections/edit.thtml:226
+#, fuzzy
+msgid "collections_edit_formfield_users_onlyme"
+msgstr "Only me"
+
+#: views/collections/edit.thtml:205 views/collections/edit.thtml:227
+#, fuzzy
+msgid "collections_edit_formfield_users_otherusers"
+msgstr "Myself and these users:"
+
+#: views/collections/edit.thtml:211 views/collections/edit.thtml:233
+#, fuzzy
+msgid "collections_edit_formfield_users_submit"
+msgstr "Add"
+
+#. %1$s is the name of the collection
+#: views/collections/edit.thtml:68
+#, fuzzy
+msgid "collections_edit_header"
+msgstr "Manage %1$s"
+
+#: views/collections/edit.thtml:246
+#, fuzzy
+msgid "collections_edit_header_addons"
+msgstr "Manage Collection Contents"
+
+#: views/collections/edit.thtml:253 views/collections/edit.thtml:258
+#, fuzzy
+msgid "collections_edit_header_addons_current"
+msgstr "Current Add-ons:"
+
+#: views/collections/edit.thtml:279
+#, fuzzy
+msgid "collections_edit_header_advanced"
+msgstr "Advanced Settings"
+
+#: views/collections/edit.thtml:186
+#, fuzzy
+msgid "collections_edit_header_permissions"
+msgstr "Manage Collection Permissions"
+
+#: views/collections/edit.thtml:170
+#, fuzzy
+msgid "collections_edit_icon_cancel"
+msgstr "Cancel"
+
+#: views/collections/edit.thtml:174 views/collections/edit.thtml:179
+#, fuzzy
+msgid "collections_edit_icon_delete"
+msgstr "Delete Icon"
+
+#: views/collections/edit.thtml:178
+#, fuzzy
+msgid "collections_edit_icon_replace"
+msgstr "Replace Icon"
+
+#. %1$s is the label of the edit form's submit button
+#: views/collections/edit.thtml:169
+#, fuzzy
+msgid "collections_edit_icon_toberemoved"
+msgstr "Icon will be removed when \"%1$s\" is clicked below"
+
+#: views/collections/edit.thtml:155
+#, fuzzy
+msgid "collections_edit_nickname_available"
+msgstr "Nickname Available"
+
+#: controllers/collections_controller.php:943
+#, fuzzy
+msgid "collections_edit_nickname_error"
+msgstr ""
+"Your nickname contained invalid characters and was corrected. Please try "
+"again."
+
+#: views/collections/edit.thtml:156
+#, fuzzy
+msgid "collections_edit_nickname_taken"
+msgstr "Nickname Taken"
+
+#. This string is followed by a URL pointing to the collection's view page
+#: views/collections/edit.thtml:75
+#, fuzzy
+msgid "collections_edit_saved_nextstep"
+msgstr "Your collection can be accessed at this location:"
+
+#: views/collections/edit.thtml:74
+#, fuzzy
+msgid "collections_edit_saved_success"
+msgstr "Your collection was successfully saved!"
+
+#: views/collections/edit.thtml:169 views/collections/edit.thtml:300
+#: views/collections/edit.thtml:308 views/pages/js_constants.js.thtml:99
+#, fuzzy
+msgid "collections_edit_submit"
+msgstr "Update Collection"
+
+#: views/collections/edit.thtml:96 views/collections/edit.thtml:297
+#: views/pages/js_constants.js.thtml:100
+#, fuzzy
+msgid "collections_edit_submit_deletecollection"
+msgstr "Delete Collection"
+
+#: views/collections/edit.thtml:111
+#, fuzzy
+msgid "collections_edit_tabheader_addons"
+msgstr "Add-ons"
+
+#: views/collections/edit.thtml:97 views/collections/edit.thtml:113
+#, fuzzy
+msgid "collections_edit_tabheader_advanced"
+msgstr "Advanced"
+
+#: views/collections/edit.thtml:108
+#, fuzzy
+msgid "collections_edit_tabheader_details"
+msgstr "Name &amp; Details"
+
+#: views/collections/edit.thtml:109
+#, fuzzy
+msgid "collections_edit_tabheader_permissions"
+msgstr "Permissions"
+
+#: models/collection_promo.php:53
+#, fuzzy
+msgid "collections_family_tagline"
+msgstr "Add-ons can keep an eye on your kids and your calendar."
+
+#: models/collection_promo.php:53
+#, fuzzy
+msgid "collections_family_title"
+msgstr "Family Organizer"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:70
+#, fuzzy
+msgid "collections_index_a_check_out"
+msgstr "Check out Add-on Collector"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:52
+#, fuzzy
+msgid "collections_index_a_create"
+msgstr "Create a Collection"
+
+#: views/collections/detail.thtml:139 views/collections/listing.thtml:85
+#: views/search/collections.thtml:84
+#, fuzzy
+msgid "collections_index_button_go"
+msgstr "Go"
+
+#. %1$s is a URL.
+#: controllers/collections_controller.php:182
+#, fuzzy
+msgid "collections_index_filler_favorites"
+msgstr ""
+"<p><strong>You don't have any favorite collections yet.</strong></p> "
+"<p>Collections you mark as favorites can be quickly accessed from this page, "
+"and will appear in the <a href='%1$s'>Add-on Collector</a> if you've "
+"installed it.</p>"
+
+#. %1$s is a URL.
+#: controllers/collections_controller.php:167
+#, fuzzy
+msgid "collections_index_filler_mine"
+msgstr ""
+"<p>You haven't created any collections yet. Collections are easy to create "
+"and fill with your favorite add-ons. <a href='%1$s'>Try it out</a>!</p>"
+
+#: views/collections/listing.thtml:51
+#, fuzzy
+msgid "collections_index_header_collections"
+msgstr "Collections"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:60
+#, fuzzy
+msgid "collections_index_header_collector"
+msgstr "Add-on Collector"
+
+#. %1$s is a comma-separated list of author names
+#: views/elements/amo2009/collection_listing_item.thtml:84
+#: views/collections/detail.thtml:151
+#, fuzzy
+msgid "collections_index_header_created"
+msgstr "created by %1$s"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:47
+#, fuzzy
+msgid "collections_index_header_what"
+msgstr "What are Collections?"
+
+#: views/collections/detail.thtml:132 views/collections/listing.thtml:78
+#: views/search/collections.thtml:66
+#, fuzzy
+msgid "collections_index_label_sortby"
+msgstr "Sort by"
+
+#: controllers/collections_controller.php:130
+#, fuzzy
+msgid "collections_index_li_editors"
+msgstr "Editor's Picks"
+
+#: views/collections/subscribe.thtml:64
+#: controllers/collections_controller.php:140
+#, fuzzy
+msgid "collections_index_li_favorites"
+msgstr "My Favorites"
+
+#: controllers/collections_controller.php:138
+#, fuzzy
+msgid "collections_index_li_mine"
+msgstr "My Collections"
+
+#: controllers/collections_controller.php:132
+#, fuzzy
+msgid "collections_index_li_popular"
+msgstr "Popular"
+
+#: views/search/collections.thtml:74 controllers/collections_controller.php:81
+#, fuzzy
+msgid "collections_index_option_all"
+msgstr "Most popular all time"
+
+#: views/search/collections.thtml:72 controllers/collections_controller.php:78
+#, fuzzy
+msgid "collections_index_option_month"
+msgstr "Most popular this month"
+
+#: views/search/collections.thtml:76 controllers/collections_controller.php:84
+#, fuzzy
+msgid "collections_index_option_newest"
+msgstr "Newest"
+
+#: views/search/collections.thtml:70 controllers/collections_controller.php:75
+#, fuzzy
+msgid "collections_index_option_week"
+msgstr "Most popular this week"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:67
+#, fuzzy
+msgid "collections_index_p_collector"
+msgstr ""
+"There's a new way to manage and find favorite add-ons. Comment, share and "
+"sync collections, all from your browser"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:48
+#, fuzzy
+msgid "collections_index_p_what_are"
+msgstr "Collections are groups of related add-ons assembled for easy sharing."
+
+#. %s is a date in the _('date') format
+#: views/elements/collections_interactive_addon.thtml:85
+#, php-format
+msgid "collections_interactive_addon_added"
+msgstr "Hozzáadva: %s"
+
+#: models/collection_promo.php:55
+#, fuzzy
+msgid "collections_reference_tagline"
+msgstr "Add-ons can do better research online."
+
+#: models/collection_promo.php:55
+#, fuzzy
+msgid "collections_reference_title"
+msgstr "Reference Desk"
+
+#: models/collection_promo.php:52
+#, fuzzy
+msgid "collections_social_tagline"
+msgstr "Add-ons can manage your social network."
+
+#: models/collection_promo.php:52
+#, fuzzy
+msgid "collections_social_title"
+msgstr "Social Circuit"
+
+#: views/collections/subscribe.thtml:91
+#, fuzzy
+msgid "collections_subscribe_button_close"
+msgstr "Close"
+
+#: views/collections/subscribe.thtml:70
+#, fuzzy
+msgid "collections_subscribe_error"
+msgstr ""
+"An error occurred trying to add a favorite collection. Is this collection "
+"already a favorite?"
+
+#: views/collections/subscribe.thtml:96
+#, fuzzy
+msgid "collections_subscribe_label_bothersome"
+msgstr "Don't show me this message again."
+
+#. %1$s is the collection name
+#: views/collections/subscribe.thtml:60
+#, fuzzy
+msgid "collections_subscribe_success"
+msgstr "%1$s has been added to your favorite collections."
+
+#. %1$s is the link to the "My Favorites" tab on the main collections page
+#. %2$s is the localized title of the "My Favorites" tab
+#. %3$s is the link URL to the collector add-on
+#: views/collections/subscribe.thtml:62
+#, fuzzy
+msgid "collections_subscribe_success_desc"
+msgstr ""
+"You can now quickly find this collection from the <a href=\"%1$s\">%2$s</a> "
+"tab in the directory. For an even easier way to keep track of your favorite "
+"collections, try out our <a href=\"%3$s\">Add-on Collector</a> extension for "
+"Firefox."
+
+#: views/collections/listing.thtml:55
+#, fuzzy
+msgid "collections_success_delete"
+msgstr "The collection has been deleted."
+
+#: models/collection_promo.php:54
+#, fuzzy
+msgid "collections_travel_tagline"
+msgstr "Add-ons can turn you into a travel agent."
+
+#: models/collection_promo.php:54
+#, fuzzy
+msgid "collections_travel_title"
+msgstr "The Traveler's Pack"
+
+#. A collection of add-ons that is automatically built for a user. They are "automatically published" to this collection.
+#: controllers/collections_controller.php:581
+#, fuzzy
+msgid "collections_type_autopublisher"
+msgstr "Auto-publisher"
+
+#. A collection that has been chosen by an Editor as notable or exceptional
+#: controllers/collections_controller.php:582
+#, fuzzy
+msgid "collections_type_editorspick"
+msgstr "Editor's Pick"
+
+#: controllers/collections_controller.php:580
+#, fuzzy
+msgid "collections_type_normal"
+msgstr "Normal"
+
+#: views/collections/subscribe.thtml:84
+#, fuzzy
+msgid "collections_unsubscribe_error"
+msgstr ""
+"An error occurred trying to remove a favorite collection. Was this "
+"collection not a favorite?"
+
+#. %1$s is the collection name
+#: views/collections/subscribe.thtml:78
+#, fuzzy
+msgid "collections_unsubscribe_success"
+msgstr "%1$s has been removed from your favorite collections."
+
+#: models/collection_promo.php:56
+#, fuzzy
+msgid "collections_webdev_tagline"
+msgstr "Add-ons make it easier to build the perfect website."
+
+#: models/collection_promo.php:56
+#, fuzzy
+msgid "collections_webdev_title"
+msgstr "Web Developer's Toolbox"
+
+#: views/elements/amo2009/collections_sidebar_whatare.thtml:40
+#, fuzzy
+msgid "collections_whatare_header"
+msgstr "What are Collections?"
+
+#: views/elements/amo2009/collections_sidebar_whatare.thtml:45
+#, fuzzy
+msgid "collections_whatare_learnmore"
+msgstr "Read the FAQ"
+
+#: views/elements/amo2009/collections_sidebar_whatare.thtml:44
+#, fuzzy
+msgid "collections_whatare_text"
+msgstr ""
+"There’s a new way to manage and find favorite add-ons. Comment, share and "
+"sync collections, all from your browser."
+
+#: views/pages/collector_faq.thtml:61 views/pages/collector_features.thtml:67
+#, fuzzy
+msgid "collector_features_a_home"
+msgstr "Add-on Collector Home"
+
+#: views/elements/amo2009/collector_sidebar_download.thtml:46
+#, fuzzy
+msgid "collector_features_heading_download"
+msgstr "Download the Add-on Collector:"
+
+#: views/elements/amo2009/collector_sidebar_download.thtml:43
+#: views/pages/collector_firstrun.thtml:116 views/pages/collector.thtml:69
+#, fuzzy
+msgid "collector_features_img_logo"
+msgstr "Add-on Collector Logo"
+
+#: views/compatibility/dashboard.thtml:49
+#: controllers/compatibility_controller.php:72
+msgid "compatibility_dashboard_center_header"
+msgstr "Kiegészítő-kompatibilitási központ"
+
+#. %1$s is the name of an application and a version. Example: Firefox 3.0
+#. %2$s is the name of an application. Example: Firefox
+#: views/compatibility/dashboard.thtml:50
+msgid "compatibility_dashboard_intro"
+msgstr ""
+"Készüljön fel a %1$s kiadására a %2$s Add-ons közössége számára alább "
+"rendelkezésre bocsátott eszközök és adatok segítségével."
+
+#: views/compatibility/dashboard.thtml:103
+msgid "compatibility_dashboard_loading"
+msgstr "Adatok betöltése..."
+
+#: views/compatibility/dashboard.thtml:45
+msgid "compatibility_dashboard_main_link"
+msgstr "Vissza a főoldalra"
+
+#: views/compatibility/dashboard.thtml:100 views/compatibility/report.thtml:43
+msgid "compatibility_dashboard_report"
+msgstr "Kiegészítő-kompatibilitási jelentés"
+
+#: views/compatibility/dashboard.thtml:53
+#: views/compatibility/dashboard.thtml:110
+#: views/compatibility/developers.thtml:43
+msgid "compatibility_developer_info"
+msgstr "Információk kiegészítőfejlesztőknek"
+
+#: views/compatibility/developers.thtml:66
+msgid "compatibility_developers_adjust_maxversion"
+msgstr "A maxVersion módosítása feltöltés nélkül"
+
+#: views/compatibility/dashboard.thtml:124
+msgid "compatibility_developers_check_status"
+msgstr "Saját kiegészítők állapotfelmérése"
+
+#. %1$s is a URL
+#. %2$s is an application and version. Example: Firefox 3.0
+#: views/compatibility/dashboard.thtml:126
+msgid "compatibility_developers_login_first"
+msgstr ""
+"Ha vannak kiegészítői a Mozilla Add-ons webhelyen, akkor <a href=\"%1$s"
+"\">jelentkezzen be</a>, hogy megnézze, hogy a kiegészítői kompatibilisek-e a "
+"%2$s verzióval."
+
+#: views/compatibility/dashboard.thtml:114
+msgid "compatibility_developers_mdclogo_alt"
+msgstr "Mozilla Developer Center logó"
+
+#: views/compatibility/developers.thtml:73
+msgid "compatibility_developers_no_addons"
+msgstr "Nincsenek kiegészítői a Mozilla Add-ons webhelyen."
+
+#: views/compatibility/dashboard.thtml:133
+#: views/compatibility/developers.thtml:55
+msgid "compatibility_developers_results"
+msgstr "Kiegészítők állapotfelmérésének eredménye"
+
+#: views/compatibility/dashboard.thtml:137
+msgid "compatibility_developers_retrieving"
+msgstr "A tárolt kiegészítők állapotának lekérdezése..."
+
+#. %1$s is a number
+#. %2$s is an application name
+#. %3$s is a number.
+#. Full example: 50 Firefox users (10% of total)
+#: views/compatibility/developers.thtml:65
+msgid "compatibility_developers_user_count"
+msgstr "%1$s %2$s felhasználó (az összes %3$s&#37;-a)"
+
+#: views/compatibility/report.thtml:45
+msgid "compatibility_report_detail_intro"
+msgstr ""
+"Az alábbi kiegészítők a Mozilla által ismert kiegészítőhasználat 95&#37;-át "
+"teszik ki, és a felhasználótáboruk mérete szerint vannak rendezve."
+
+#: views/compatibility/dashboard.thtml:94
+msgid "compatibility_report_detailed_link"
+msgstr "Részletes jelentés"
+
+#. %1$s and %2$s are numbers
+#. %3$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:65
+msgid "compatibility_report_intro"
+msgstr ""
+"A(z) %1$s kiegészítő közül, amelyek a Mozilla által ismert "
+"kiegészítőhasználat 95&#37;-át teszik ki, <b>%2$s&#37;</b> jelenleg "
+"kompatibilisnek tekinthető a %3$s legújabb verziójával."
+
+#: views/compatibility/dashboard.thtml:81
+msgid "compatibility_report_legend_alpha"
+msgstr "Alfaverziók"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:81
+msgid "compatibility_report_legend_alpha_description"
+msgstr "A %1$s alfaverzióival kompatibilis kiegészítők"
+
+#: views/compatibility/dashboard.thtml:85
+msgid "compatibility_report_legend_beta"
+msgstr "Bétaverziók"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:85
+msgid "compatibility_report_legend_beta_description"
+msgstr ""
+"A %1$s bétaverzióival vagy kiadásra jelölt verzióival kompatibilis "
+"kiegészítők"
+
+#: views/compatibility/dashboard.thtml:89
+msgid "compatibility_report_legend_latest"
+msgstr "Legújabb verzió"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:89
+msgid "compatibility_report_legend_latest_description"
+msgstr "A %1$s legújabb verziójával kompatibilis kiegészítők"
+
+#: views/compatibility/dashboard.thtml:77
+msgid "compatibility_report_legend_other"
+msgstr "Egyéb verziók"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:77
+msgid "compatibility_report_legend_other_description"
+msgstr "A %1$s egyik verziójával sem kompatibilis kiegészítők"
+
+#: views/compatibility/dashboard.thtml:62
+msgid "compatibility_report_title"
+msgstr "Kiegészítő-kompatibilitási jelentés"
+
+#: views/compatibility/dashboard.thtml:54
+#: views/compatibility/dashboard.thtml:144 views/compatibility/users.thtml:42
+msgid "compatibility_user_info"
+msgstr "Információk kiegészítő-felhasználóknak"
+
+#: views/compatibility/dashboard.thtml:52
+msgid "compatibility_view_report"
+msgstr "Kompatibilitási jelentés"
+
+#. %s is a URL
+#: views/pages/credits.thtml:142
+#, php-format
+msgid "credits_contributing"
+msgstr "A hozzájárulással kapcsolatos információkért lásd a %s."
+
+#: views/pages/credits.thtml:142
+msgid "credits_contributing_wikipage"
+msgstr "wikioldalunkat"
+
+#: views/pages/credits.thtml:99
+msgid "credits_intro"
+msgstr ""
+"A Mozilla a következő embereknek szeretne köszönetet mondani az addons."
+"mozilla.org projekthez az évek során adott munkájukért:"
+
+#: views/pages/credits.thtml:103
+msgid "credits_section_developers"
+msgstr "Fejlesztők"
+
+#: views/pages/credits.thtml:115
+msgid "credits_section_editors"
+msgstr "Szerkesztők"
+
+#: views/pages/credits.thtml:109
+msgid "credits_section_localizers"
+msgstr "Honosítók"
+
+#: views/pages/credits.thtml:121
+msgid "credits_section_other_contributors"
+msgstr "Egyéb hozzájárulók"
+
+#: views/pages/credits.thtml:127
+msgid "credits_section_past_developers"
+msgstr "Korábbi fejlesztők"
+
+#: views/pages/credits.thtml:133
+msgid "credits_section_software"
+msgstr "Szoftver és képek"
+
+#: views/pages/credits.thtml:136
+msgid "credits_software_famfamfam"
+msgstr ""
+"Egyes ikonok a <a href=\"http://www.famfamfam.com/lab/icons/silk/"
+"\">famfamfam Silk ikonkészletből</a> származnak, amelyre a <a href=\"http://"
+"creativecommons.org/licenses/by/2.5/\">Creative Commons Attribution 2.5 "
+"License</a> vonatkozik."
+
+#: views/pages/credits.thtml:137
+#, fuzzy
+msgid "credits_software_timeplot"
+msgstr ""
+"Some pages use elements of <a href=\"http://www.simile-widgets.org/timeplot/"
+"\">Timeplot</a>, licensed under a <a href=\"http://simile.mit.edu/license."
+"html\">BSD License</a>."
+
+# date format string as used in PHP's strftime():
+# http://php.net/strftime
+#. date format string as used in PHP's strftime():
+#. http://php.net/strftime
+#: views/elements/collections_interactive_addon.thtml:85
+#: views/elements/amo2009/addon_version_detail.thtml:53
+#: views/elements/amo2009/homepage_addon.thtml:115
+#: views/elements/addon_version_detail.thtml:54
+#: views/elements/addon_listitem.thtml:124 views/elements/feature.thtml:106
+#: views/collections/detail.thtml:118 views/collections/edit.thtml:325
+#: views/users/info.thtml:76 views/editors/reviews_queue.thtml:57
+#: views/editors/reviews_queue.thtml:68 views/developers/dashboard.thtml:65
+#: views/developers/versions_edit.thtml:208 views/developers/versions.thtml:67
+#: views/search/rss/index.thtml:5 views/addons/rss/versions.thtml:42
+#: views/addons/display.thtml:104 views/addons/display.thtml:356
+#: views/addons/browse_thumbs.thtml:75 views/reviews/add.thtml:63
+#: views/reviews/display.thtml:74 views/reviews/display.thtml:160
+#: views/reviews/delete.thtml:54 controllers/statistics_controller.php:244
+#: controllers/collections_controller.php:1047
+msgid "date"
+msgstr "%Y. %B %e."
+
+# date and time format string (strftime)
+#. date and time format string (strftime)
+#. http://php.net/strftime
+#: views/elements/addon_version_detail.thtml:53
+#: views/developers/discuss.thtml:52 views/developers/discuss.thtml:62
+#: views/admin/addons_status.thtml:57
+msgid "datetime"
+msgstr "%Y. %B %e., %I:%M %p"
+
+#: views/elements/developers/actionbar.thtml:47
+msgid "devcp_actionbar_link_details"
+msgstr "Részletes infó"
+
+#: views/elements/developers/actionbar.thtml:42
+#: views/elements/developers/actionbar.thtml:50
+#: views/developers/dashboard.thtml:64
+msgid "devcp_actionbar_link_edit"
+msgstr "Kiegészítő szerk."
+
+#: views/elements/developers/actionbar.thtml:51
+msgid "devcp_actionbar_link_newversion"
+msgstr "Új verzió feltöltése"
+
+#: views/elements/developers/actionbar.thtml:44
+#: views/elements/developers/actionbar.thtml:49
+#: views/developers/dashboard.thtml:73
+msgid "devcp_actionbar_link_stats"
+msgstr "Statisztikák"
+
+#. %1$s is a filename, e.g. "foo.txt"
+#. %2$s is the extension, e.g. ".txt"
+#. %3$s is a list of valid extensions, like ".png, .jpg, .gif"
+#: controllers/developers_controller.php:1361
+#, fuzzy
+msgid "devcp_add_previews_extension_error"
+msgstr "File %1$s has an invalid extension (%2$s). Allowed extensions: %3$s"
+
+#. %s is the filename.
+#: controllers/developers_controller.php:1394
+#, fuzzy
+msgid "devcp_add_previews_save_error"
+msgstr "File %s could not be saved to the database. Please try again."
+
+#. %1$s is the preview ID number, %2$s is the filename.
+#: controllers/developers_controller.php:1389
+#, fuzzy
+msgid "devcp_add_previews_success_replace"
+msgstr "Preview %1$s was replaced with file %2$s successfully."
+
+#. %s is the filename.
+#: controllers/developers_controller.php:1391
+#, fuzzy
+msgid "devcp_add_previews_success_upload"
+msgstr "File %s was uploaded successfully. You can add a caption below."
+
+#: controllers/components/developers.php:1163
+msgid "devcp_additem_addontype_autodetect"
+msgstr "(automatikus észlelés)"
+
+#: views/elements/developers/additem.thtml:76
+msgid "devcp_additem_linktitle_opensin_newwindow"
+msgstr "Új ablakban nyílik meg"
+
+#: views/elements/developers/additem.thtml:41
+msgid "devcp_additem_sidebar_title"
+msgstr "Kiegészítő beküldése"
+
+#: views/elements/developers/additem.thtml:53
+msgid "devcp_additem_step0_newlink"
+msgstr "Fejlesztői megállapodás"
+
+#: views/elements/developers/additem.thtml:46
+msgid "devcp_additem_step1_link"
+msgstr "1. lépés: Feltöltés"
+
+#: views/elements/developers/additem.thtml:47
+msgid "devcp_additem_step2_link"
+msgstr "2. lépés: Kiegészítő leírása"
+
+#: views/elements/developers/additem.thtml:48
+msgid "devcp_additem_step3_link"
+msgstr "3. lépés: Verzió leírása"
+
+#: views/elements/developers/additem.thtml:49
+msgid "devcp_additem_step4_link"
+msgstr "4. lépés: Honosítás"
+
+#: views/elements/developers/additem.thtml:50
+msgid "devcp_additem_step5_link"
+msgstr "5. lépés: Siker"
+
+#: views/elements/developers/additem.thtml:76
+msgid "devcp_additem_submissionhelp_link"
+msgstr "Segítség a beküldéshez"
+
+#: controllers/previews_controller.php:168
+#: controllers/previews_controller.php:277
+msgid "devcp_addon_field_preview_caption_displaytitle"
+msgstr "Előnézet képfelirata"
+
+#: views/developers/addon_status.thtml:177
+#, fuzzy
+msgid "devcp_addon_status_action_activate"
+msgstr "Make Active"
+
+#: views/developers/addon_status.thtml:178
+#, fuzzy
+msgid "devcp_addon_status_action_activate_description"
+msgstr ""
+"Make your add-on active for it to show up in public listings and enable the "
+"update check service."
+
+#: views/developers/addon_status.thtml:135
+#, fuzzy
+msgid "devcp_addon_status_action_complete"
+msgstr "Complete Add-on"
+
+#: views/developers/addon_status.thtml:136
+#, fuzzy
+msgid "devcp_addon_status_action_complete_description"
+msgstr "Complete your add-on and move to the Sandbox"
+
+#: views/developers/addon_status.thtml:181
+#, fuzzy
+msgid "devcp_addon_status_action_deactivate"
+msgstr "Make Inactive"
+
+#: views/developers/addon_status.thtml:182
+#, fuzzy
+msgid "devcp_addon_status_action_deactivate_description"
+msgstr ""
+"Make your add-on inactive to hide it from all public listings and disable "
+"the update check service."
+
+#: views/developers/addon_status.thtml:143
+#, fuzzy
+msgid "devcp_addon_status_action_move"
+msgstr "Move to Sandbox"
+
+#: views/developers/addon_status.thtml:144
+#, fuzzy
+msgid "devcp_addon_status_action_move_description"
+msgstr "Move your add-on back to the Sandbox. This is reversible."
+
+#: views/developers/addon_status.thtml:139
+#, fuzzy
+msgid "devcp_addon_status_action_nominate"
+msgstr "Nominate for Public"
+
+#: views/developers/addon_status.thtml:140
+#, fuzzy
+msgid "devcp_addon_status_action_nominate_description"
+msgstr "Nominate your add-on to become Public"
+
+#: views/developers/addon_status.thtml:147
+#, fuzzy
+msgid "devcp_addon_status_action_public"
+msgstr "Make Public"
+
+#: views/developers/addon_status.thtml:148
+#, fuzzy
+msgid "devcp_addon_status_action_public_description"
+msgstr "Make your add-on Public again."
+
+#: views/developers/addon_status.thtml:169
+#, fuzzy
+msgid "devcp_addon_status_active"
+msgstr ""
+"Your add-on is <span class=\"inactive-0\">Active</span>. This means your add-"
+"on is showing up in all available listings appropriate for its status above."
+
+#: views/developers/addon_status.thtml:111
+#, fuzzy
+msgid "devcp_addon_status_completion_disabled"
+msgstr ""
+"Please fulfill the criteria above before you can complete your add-on and "
+"move it to the <span class=\"status-1\">Sandbox</span>."
+
+#: views/developers/addon_status.thtml:108
+#, fuzzy
+msgid "devcp_addon_status_completion_enabled"
+msgstr ""
+"You may now complete your add-on and move it to the <span class=\"status-1"
+"\">Sandbox</span> by clicking the button below."
+
+#: views/developers/addon_status.thtml:102
+#, fuzzy
+msgid "devcp_addon_status_criteria_category"
+msgstr "At least one category selected"
+
+#: views/developers/addon_status.thtml:101
+#, fuzzy
+msgid "devcp_addon_status_criteria_description"
+msgstr "Add-on Description required"
+
+#: views/developers/addon_status.thtml:99
+#, fuzzy
+msgid "devcp_addon_status_criteria_name"
+msgstr "Add-on Name required"
+
+#: views/developers/addon_status.thtml:120
+#, fuzzy
+msgid "devcp_addon_status_criteria_prerelease"
+msgstr "Add-on is not marked as pre-release."
+
+#: views/developers/addon_status.thtml:119
+#, fuzzy
+msgid "devcp_addon_status_criteria_preview"
+msgstr "At least one preview image required for extensions and themes."
+
+#: views/developers/addon_status.thtml:100
+#, fuzzy
+msgid "devcp_addon_status_criteria_summary"
+msgstr "Add-on Summary required"
+
+#. %s is the status in a span, e.g. "<span>_('Public')</span>".
+#: views/developers/addon_status.thtml:58
+#, fuzzy
+msgid "devcp_addon_status_header"
+msgstr "Add-on Status: %s"
+
+#: views/developers/addon_status.thtml:152
+#: views/developers/addon_status.thtml:173
+#, fuzzy
+msgid "devcp_addon_status_header_actions"
+msgstr "Available Actions"
+
+#: views/developers/addon_status.thtml:168
+#, fuzzy
+msgid "devcp_addon_status_header_active"
+msgstr "Active Status: <span class=\"inactive-0\">Active</span>"
+
+#: views/developers/addon_status.thtml:97
+#, fuzzy
+msgid "devcp_addon_status_header_criteria"
+msgstr "Add-on Completion Criteria"
+
+#: views/developers/addon_status.thtml:164
+#, fuzzy
+msgid "devcp_addon_status_header_inactive"
+msgstr "Active Status: <span class=\"inactive-1\">Inactive</span>"
+
+#: views/developers/addon_status.thtml:117
+#, fuzzy
+msgid "devcp_addon_status_header_nomination"
+msgstr "Public Nomination Criteria"
+
+#: views/developers/addon_status.thtml:190
+#, fuzzy
+msgid "devcp_addon_status_header_trusted"
+msgstr "Trusted Status: <span class=\"status-4\">Trusted</span>"
+
+#: views/developers/addon_status.thtml:165
+#, fuzzy
+msgid "devcp_addon_status_inactive"
+msgstr ""
+"Your add-on is <span class=\"inactive-1\">Inactive</span>. This means your "
+"add-on will not show up in any listing, regardless of its status above. "
+"Updates are <b>not</b> being provided to your add-on through the update "
+"check service."
+
+#: views/developers/addon_status.thtml:128
+#, fuzzy
+msgid "devcp_addon_status_nominate_disabled"
+msgstr ""
+"Please fulfill the criteria above before nominating your add-on to become "
+"<span class=\"status-4\">Public</span>."
+
+#: views/developers/addon_status.thtml:125
+#, fuzzy
+msgid "devcp_addon_status_nominate_enabled"
+msgstr ""
+"You may now nominate your add-on for <span class=\"status-4\">Public</span> "
+"by clicking the button below."
+
+#: views/developers/addon_status.thtml:64
+#, fuzzy
+msgid "devcp_addon_status_public"
+msgstr "Public"
+
+#: views/developers/addon_status.thtml:63
+#, fuzzy
+msgid "devcp_addon_status_sandbox"
+msgstr "Sandbox"
+
+#. %s is an email address.
+#: views/developers/addon_status.thtml:89
+#, fuzzy
+msgid "devcp_addon_status_switch_disabled"
+msgstr ""
+"Your add-on was <span class=\"status-5\">Disabled</span> by an administrator "
+"and cannot be used. If you have any questions, please e-mail %s."
+
+#: views/developers/addon_status.thtml:67
+#, fuzzy
+msgid "devcp_addon_status_switch_incomplete"
+msgstr ""
+"Your add-on is currently <span class=\"status-0\">Incomplete</span>. This "
+"means your add-on is not showing up on any portion of the site or update "
+"check service. You may come to this page to complete your add-on after it "
+"meets the criteria below for completion and transfer to the <span class="
+"\"status-1\">Sandbox</span>."
+
+#. %s is a number, perhaps 42.
+#: views/developers/addon_status.thtml:77
+#, fuzzy
+msgid "devcp_addon_status_switch_nominated"
+msgstr ""
+"Your add-on is currently nominated to become <span class=\"status-4"
+"\">Public</span> and is awaiting editor review. There are currently %s other "
+"add-ons in the nomination queue."
+
+#. %s is an email address.
+#: views/developers/addon_status.thtml:81
+#, fuzzy
+msgid "devcp_addon_status_switch_pending"
+msgstr ""
+"Your add-on is pending. This shouldn't have happened. Please e-mail %s with "
+"your add-on ID and state this error."
+
+#: views/developers/addon_status.thtml:85
+#, fuzzy
+msgid "devcp_addon_status_switch_public"
+msgstr ""
+"Your add-on is <span class=\"status-4\">Public</span>, which means it will "
+"show up in all listings and searches and can be downloaded without "
+"restriction. Updates are being provided to your add-on through the update "
+"check service."
+
+#: views/developers/addon_status.thtml:71
+#: views/developers/addon_status.thtml:75
+#, fuzzy
+msgid "devcp_addon_status_switch_sandbox"
+msgstr ""
+"Your add-on is in the <span class=\"status-1\">Sandbox</span>, which means "
+"it will show up in listings and searches, but users must log in to download "
+"it. Updates are <b>not</b> being provided to your add-on through the update "
+"check service."
+
+#. %s is the add-on name.
+#: views/developers/addon_status_nominate.thtml:43
+#: views/developers/addon_status_confirm.thtml:43
+#: views/developers/addon_status.thtml:43
+#, fuzzy
+msgid "devcp_addon_status_title"
+msgstr "%s Status"
+
+#: views/developers/addon_status.thtml:191
+#, fuzzy
+msgid "devcp_addon_status_trusted"
+msgstr ""
+"Your add-on is <span class=\"status-4\">Trusted</span>. This means you can "
+"submit updates to your add-on without editor review."
+
+#: views/developers/dashboard.thtml:68
+#, fuzzy
+msgid "devcp_dashboard_active"
+msgstr "Active"
+
+#. %1$s is the add-on type string
+#. %2$s is Inactive or Active in a <span>
+#. %3$s is the addon's public status (Public, In Sandbox, ...) in a <span>
+#: views/developers/dashboard.thtml:69
+#, fuzzy
+msgid "devcp_dashboard_addontype_status"
+msgstr "%1$s currenty %2$s and %3$s"
+
+#: views/developers/dashboard.thtml:67
+#, fuzzy
+msgid "devcp_dashboard_change_status"
+msgstr "Change Status"
+
+#. %s is the addons email address.
+#: views/developers/dashboard.thtml:99
+#, fuzzy
+msgid "devcp_dashboard_disabled_questions"
+msgstr ""
+"Your add-on was disabled by an administrator and cannot be used. If you "
+"have any questions, please email %s."
+
+#. %s is the (localized) add-on status string in a span, e.g. "Disabled"
+#: views/developers/dashboard.thtml:98
+#, fuzzy
+msgid "devcp_dashboard_disabled_status"
+msgstr "Add-on Status: %s"
+
+#: views/developers/dashboard.thtml:43
+#, fuzzy
+msgid "devcp_dashboard_header_main"
+msgstr "Developer Dashboard"
+
+#: views/developers/dashboard.thtml:110
+#, fuzzy
+msgid "devcp_dashboard_header_welcome"
+msgstr "Welcome to the Developer Dashboard"
+
+#: views/developers/dashboard.thtml:68
+#, fuzzy
+msgid "devcp_dashboard_inactive"
+msgstr "Inactive"
+
+#. %s is a date in the _('date') format
+#: views/developers/dashboard.thtml:65
+#, fuzzy
+msgid "devcp_dashboard_last_edited"
+msgstr "Last edited on %s"
+
+#: views/developers/dashboard.thtml:111
+#, fuzzy
+msgid "devcp_dashboard_learn"
+msgstr ""
+"You don't currently have any add-ons hosted on Mozilla Add-ons. To learn how "
+"the process works and submit your first add-on, click Get Started below."
+
+#: views/developers/dashboard.thtml:112
+#, fuzzy
+msgid "devcp_dashboard_start"
+msgstr "Get Started"
+
+#: views/developers/dashboard.thtml:82
+#, fuzzy
+msgid "devcp_dashboard_versions"
+msgstr "Versions and Files"
+
+#: views/developers/dashboard.thtml:91
+#, fuzzy
+msgid "devcp_dashboard_versions_new"
+msgstr "Upload a new version"
+
+#. %s is the preview ID number.
+#: controllers/developers_controller.php:1415
+#, fuzzy
+msgid "devcp_delete_previews_error"
+msgstr "Preview %s could not be deleted from the database. Please try again."
+
+#. %s is the preview ID number.
+#: controllers/developers_controller.php:1413
+#, fuzzy
+msgid "devcp_delete_previews_success"
+msgstr "Preview %s has been deleted successfully."
+
+#: controllers/developers_controller.php:1089
+#, fuzzy
+msgid "devcp_delete_version_priv_error"
+msgstr "You do not have privileges to delete versions or files."
+
+#. %1$s is the count of files, a number
+#. %2$s is a status string like _('Public') or _('Incomplete')
+#: controllers/components/amo.php:549
+#, fuzzy
+msgid "devcp_describe_version_status"
+msgid_plural "devcp_describe_version_status"
+msgstr[0] "%1$s %2$s file"
+msgstr[1] "%1$s %2$s files"
+
+#. %s is a version number. Example: 3.0
+#: views/developers/versions.thtml:65
+#, php-format
+msgid "devcp_details_version"
+msgstr "%s verzió"
+
+#: views/developers/discuss.thtml:68
+#, fuzzy
+msgid "devcp_discuss_addreply_header"
+msgstr "Add Reply"
+
+#: views/developers/discuss.thtml:57
+#, fuzzy
+msgid "devcp_discuss_allreplies_header"
+msgstr "Replies"
+
+#. notice when an error occurs saving a discussion reply
+#. %1 is the email address (linked) for the amo-editors list
+#: views/developers/discuss.thtml:70
+#, fuzzy
+msgid "devcp_discuss_error_notice"
+msgstr ""
+"There was an error saving your reply. Please contact %1$s about the issue."
+
+#. %1 is the add-on name, %2 is the add-on's version number currently being reviewed by an editor
+#: views/developers/discuss.thtml:46
+#, fuzzy
+msgid "devcp_discuss_intro"
+msgstr ""
+"A Mozilla Add-ons Editor requested further information from you regarding "
+"version %2$s of your add-on %1$s."
+
+#. %1 is the add-on name
+#: views/developers/discuss.thtml:43
+#, fuzzy
+msgid "devcp_discuss_pagetitle"
+msgstr "Provide More Information For the Add-on Review of %1$s"
+
+#. submit button text
+#: views/developers/discuss.thtml:79
+#, fuzzy
+msgid "devcp_discuss_submit_reply"
+msgstr "Submit Reply"
+
+#: views/developers/discuss.thtml:72
+#, fuzzy
+msgid "devcp_discuss_success_message"
+msgstr ""
+"Your reply was successfully saved. The other participants of the discussion "
+"will be notified by email."
+
+#. in an author/editor discussion about an add-on to be reviewed:
+#. %1 is the commenter's user name (linked).
+#. %2 is the full date the comment was made.
+#: views/developers/discuss.thtml:52 views/developers/discuss.thtml:62
+#, fuzzy
+msgid "devcp_discuss_writtenby"
+msgstr "written by %1$s on %2$s"
+
+#: views/developers/addon_edit_authors.thtml:72
+#: views/developers/addon_edit_authors.thtml:81
+#, fuzzy
+msgid "devcp_edit_authors_add_author"
+msgstr "Add New Author"
+
+#: views/developers/addon_edit_authors.thtml:96
+#, fuzzy
+msgid "devcp_edit_authors_add_author_button"
+msgstr "Add Author"
+
+#: views/developers/addon_edit_authors.thtml:83
+#, fuzzy
+msgid "devcp_edit_authors_add_email"
+msgstr "Author Account Email:"
+
+#: views/developers/addon_edit_authors.thtml:98
+#, fuzzy
+msgid "devcp_edit_authors_add_loading"
+msgstr "Checking account email..."
+
+#: views/developers/addon_edit_authors.thtml:70
+#, fuzzy
+msgid "devcp_edit_authors_click_save"
+msgstr "Click the Update Authors button below to save."
+
+#: views/developers/addon_edit_authors.thtml:58
+#, fuzzy
+msgid "devcp_edit_authors_header_current"
+msgstr "Current Authors"
+
+#: views/developers/addon_edit_authors.thtml:50
+#, fuzzy
+msgid "devcp_edit_authors_header_manage"
+msgstr "Manage Add-on Authors"
+
+#: views/developers/addon_edit_authors.thtml:93
+#, fuzzy
+msgid "devcp_edit_authors_label_add_listed"
+msgstr "List as author in pubilc display pages"
+
+#: views/developers/addon_edit_authors.thtml:89
+#, fuzzy
+msgid "devcp_edit_authors_label_developer"
+msgstr ""
+"<strong>Developer</strong> - Can manage all aspects of the add-on listing, "
+"except for adding and removing other authors."
+
+#: views/developers/addon_edit_authors.thtml:88
+#, fuzzy
+msgid "devcp_edit_authors_label_owner"
+msgstr ""
+"<strong>Owner</strong> - Can manage all aspects of the add-on listing, "
+"including adding and removing other authors."
+
+#: views/developers/addon_edit_authors.thtml:90
+#, fuzzy
+msgid "devcp_edit_authors_label_viewer"
+msgstr ""
+"<strong>Viewer</strong> - Can view add-on developer listing and statistics, "
+"but can't make any changes."
+
+#. Placeholder for the empty option in a <select>.
+#: views/developers/addon_edit_categories.thtml:69
+#, fuzzy
+msgid "devcp_edit_authors_option_empty"
+msgstr "----------------"
+
+#: views/developers/addon_edit_authors.thtml:86
+#, fuzzy
+msgid "devcp_edit_authors_select_role"
+msgstr "Select a role for the author:"
+
+#. Column name in a table.
+#: views/developers/addon_edit_authors.thtml:62
+#, fuzzy
+msgid "devcp_edit_authors_th_author"
+msgstr "Author"
+
+#. Column name in a table.
+#: views/developers/addon_edit_authors.thtml:64
+#, fuzzy
+msgid "devcp_edit_authors_th_listed"
+msgstr "Listed"
+
+#. Column name in a table.
+#: views/developers/addon_edit_authors.thtml:63
+#, fuzzy
+msgid "devcp_edit_authors_th_role"
+msgstr "Role"
+
+#: views/developers/addon_edit_authors.thtml:77
+#, fuzzy
+msgid "devcp_edit_authors_update_author"
+msgstr "Update authors"
+
+#: views/developers/addon_edit_categories.thtml:99
+#, fuzzy
+msgid "devcp_edit_categories_button_update"
+msgstr "Update Categories"
+
+#: views/developers/addon_edit_categories.thtml:88
+#, fuzzy
+msgid "devcp_edit_categories_does_not_fit"
+msgstr "My add-on doesn't fit into any available categories."
+
+#. %s is the application name (Firefox, Thunderbird).
+#: views/developers/addon_edit_categories.thtml:61
+#, fuzzy
+msgid "devcp_edit_categories_header_application"
+msgstr "%s Categories"
+
+#: views/developers/addon_edit_categories.thtml:49
+#, fuzzy
+msgid "devcp_edit_categories_header_manage"
+msgstr "Manage Add-on Categories"
+
+#: views/developers/addon_edit_categories.thtml:91
+#, fuzzy
+msgid "devcp_edit_categories_hover"
+msgstr "Hover over a category to see its description."
+
+#. %s is the category number (1, 2, 3).
+#: views/developers/addon_edit_categories.thtml:67
+#, fuzzy
+msgid "devcp_edit_categories_label_category_num"
+msgstr "Category %s"
+
+#: views/developers/addon_edit_categories.thtml:94
+#: views/developers/addon_edit_categories.thtml:103
+#, fuzzy
+msgid "devcp_edit_categories_none_available"
+msgstr "No categories are available for this add-on type and application."
+
+#: views/developers/addon_edit_categories.thtml:86
+#, fuzzy
+msgid "devcp_edit_categories_other"
+msgstr ""
+"Place your add-on into this category only if it does not fit into any other "
+"available categories."
+
+#. %s is the application name (Firefox, Thunderbird).
+#: views/developers/addon_edit_categories.thtml:63
+#, fuzzy
+msgid "devcp_edit_categories_select_application_categories"
+msgstr "Select up to three %s categories for your add-on"
+
+#: views/developers/addon_edit.thtml:47
+#, fuzzy
+msgid "devcp_edit_dd_manage_authors"
+msgstr "Add or remove users that can manage this add-on."
+
+#: views/developers/addon_edit.thtml:49
+#, fuzzy
+msgid "devcp_edit_dd_manage_categories"
+msgstr ""
+"Select the relevant categories for each application your add-on supports."
+
+#: views/developers/addon_edit.thtml:51
+#, fuzzy
+msgid "devcp_edit_dd_manage_description"
+msgstr ""
+"Add and modify translations for your add-on's summary, description, end-user "
+"license, and privacy policy."
+
+#: views/developers/addon_edit.thtml:53
+#, fuzzy
+msgid "devcp_edit_dd_manage_properties"
+msgstr "Change your add-on's name, homepage, icon, and other flags."
+
+#: views/developers/addon_edit_descriptions.thtml:116
+#, fuzzy
+msgid "devcp_edit_description_button_update"
+msgstr "Update Descriptions"
+
+#: views/developers/addon_edit_descriptions.thtml:115
+#, fuzzy
+msgid "devcp_edit_description_correct_error"
+msgstr "Please correct the errors above indicated in red."
+
+#: views/developers/addon_edit_descriptions.thtml:51
+#, fuzzy
+msgid "devcp_edit_descriptions_header"
+msgstr "Edit Add-on Descriptions"
+
+#: views/developers/addon_edit_descriptions.thtml:94
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_comments_description"
+msgstr ""
+"Any information end users may want to know that isn't necessarily applicable "
+"to the add-on summary or description. Common uses include listing known "
+"major bugs, information on how to report bugs, anticipated release date of a "
+"new version, etc."
+
+#: views/developers/addon_edit_descriptions.thtml:93
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_comments_name"
+msgstr "Developer Comments"
+
+#: views/developers/addon_edit_descriptions.thtml:86
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_description_description"
+msgstr ""
+"The description of your add-on is a longer explanation of features, "
+"functionality, and other relevant information. It is displayed under the "
+"summary on the add-on's display page."
+
+#: views/developers/addon_edit_descriptions.thtml:85
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_description_name"
+msgstr "Add-on Description"
+
+#: views/developers/addon_edit_descriptions.thtml:103
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_eula_description"
+msgstr ""
+"If your add-on has an End-User License Agreement (EULA), please enter its "
+"text below. If set below, users will be required to agree to this before "
+"installing your add-on. Please note that a EULA is not the same as a code "
+"license such as GPL or MPL."
+
+#: views/developers/addon_edit_descriptions.thtml:102
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_eula_name"
+msgstr "End-User License Agreement"
+
+#: views/developers/addon_edit_descriptions.thtml:112
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_privacy_description"
+msgstr ""
+"If your add-on has a privacy policy, enter its text here. Your add-on's "
+"display page will display a link to the policy."
+
+#: views/developers/addon_edit_descriptions.thtml:111
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_privacy_name"
+msgstr "Privacy Policy"
+
+#: views/developers/addon_edit_descriptions.thtml:78
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_summary_description"
+msgstr ""
+"The summary is a short explanation of your add-on's basic functionality that "
+"is displayed in search and browse listings, as well as at the top of your "
+"add-on's display page. <strong>Limit of 250 characters.</strong>"
+
+#: views/developers/addon_edit_descriptions.thtml:77
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_summary_name"
+msgstr "Add-on Summary"
+
+#: views/developers/addon_edit.thtml:46
+#, fuzzy
+msgid "devcp_edit_dt_manage_authors"
+msgstr "Manage Add-on Authors"
+
+#: views/developers/addon_edit.thtml:48
+#, fuzzy
+msgid "devcp_edit_dt_manage_categories"
+msgstr "Manage Add-on Categories"
+
+#: views/developers/addon_edit.thtml:50
+#, fuzzy
+msgid "devcp_edit_dt_manage_descriptions"
+msgstr "Manage Add-on Descriptions"
+
+#: views/developers/addon_edit.thtml:52
+#, fuzzy
+msgid "devcp_edit_dt_manage_properties"
+msgstr "Manage Add-on Properties"
+
+#: views/developers/addon_edit_properties.thtml:170
+msgid "devcp_edit_label_externalsoftware"
+msgstr "Ez a kiegészítő külső szoftvert igényel"
+
+#: views/developers/addon_edit_properties.thtml:205
+msgid "devcp_edit_label_locale_disambiguation"
+msgstr "További területi beállítások"
+
+#: views/developers/addon_edit_properties.thtml:168
+msgid "devcp_edit_label_prerelease"
+msgstr "Ez egy előzetes kiadás"
+
+#: views/developers/addon_edit_properties.thtml:169
+msgid "devcp_edit_label_sitespecific"
+msgstr "Ez egy webhelyspecifikus kiegészítő"
+
+#: views/developers/addon_edit_properties.thtml:202
+msgid "devcp_edit_label_target_locale"
+msgstr "Cél területi beállítások"
+
+#: views/developers/addon_edit_properties.thtml:212
+#, fuzzy
+msgid "devcp_edit_properties_button_update"
+msgstr "Update Properties"
+
+#: views/developers/addon_edit_properties.thtml:198
+#, fuzzy
+msgid "devcp_edit_properties_change_guid"
+msgstr "Only change if you understand all of the consequences."
+
+#: views/developers/addon_edit_properties.thtml:109
+#, fuzzy
+msgid "devcp_edit_properties_current_icon"
+msgstr "Current Icon"
+
+#: views/developers/addon_edit_properties.thtml:85
+#, fuzzy
+msgid "devcp_edit_properties_default_locale"
+msgstr ""
+"An add-on's default locale is the main locale in which translations must be "
+"present. If translations for your add-on's descriptions are unavailable in a "
+"user's selected language, they will fall back to this default locale."
+
+#: views/developers/addon_edit_properties.thtml:167
+#, fuzzy
+msgid "devcp_edit_properties_flags"
+msgstr "These flags are used to filter and classify add-ons."
+
+#: views/developers/addon_edit_properties.thtml:174
+#, fuzzy
+msgid "devcp_edit_properties_guid"
+msgstr ""
+"The GUID of your add-on is specified in its install.rdf and uniquely "
+"identifies it. You cannot change your GUID once it is listed on Mozilla Add-"
+"ons."
+
+#: views/developers/addon_edit_properties.thtml:53
+#, fuzzy
+msgid "devcp_edit_properties_header"
+msgstr "Edit Add-on Properties"
+
+#: views/developers/addon_edit_properties.thtml:186
+#, fuzzy
+msgid "devcp_edit_properties_header_addon_type"
+msgstr "Add-on Type"
+
+#: views/developers/addon_edit_properties.thtml:181
+#, fuzzy
+msgid "devcp_edit_properties_header_admin_settings"
+msgstr "Admin Settings"
+
+#: views/developers/addon_edit_properties.thtml:84
+#, fuzzy
+msgid "devcp_edit_properties_header_default_locale"
+msgstr "Default Locale"
+
+#: views/developers/addon_edit_properties.thtml:166
+#, fuzzy
+msgid "devcp_edit_properties_header_flags"
+msgstr "Add-on Flags"
+
+#: views/developers/addon_edit_properties.thtml:173
+#: views/developers/addon_edit_properties.thtml:197
+#, fuzzy
+msgid "devcp_edit_properties_header_guid"
+msgstr "Add-on GUID"
+
+#: views/developers/addon_edit_properties.thtml:104
+#, fuzzy
+msgid "devcp_edit_properties_header_icon"
+msgstr "Add-on Icon"
+
+#: views/developers/addon_edit_properties.thtml:159
+#, fuzzy
+msgid "devcp_edit_properties_header_other_settings"
+msgstr "Other Settings"
+
+#. A header on the admin page to toggle trusted status.
+#: views/developers/addon_edit_properties.thtml:182
+#, fuzzy
+msgid "devcp_edit_properties_header_trusted"
+msgstr "Trusted Add-on?"
+
+#: views/developers/addon_edit_properties.thtml:160
+#, fuzzy
+msgid "devcp_edit_properties_header_view_source"
+msgstr "View Source Online"
+
+#. %s is a comma-separated list of image extensions ".png, .jpg"
+#: views/developers/addon_edit_properties.thtml:106
+#, fuzzy
+msgid "devcp_edit_properties_icon"
+msgstr ""
+"The add-on icon is a small image that is displayed next to your add-on's "
+"name in browse and search results, display pages, and in the add-on "
+"installation dialog. The image will automatically be resized to 32 x 32 "
+"pixels. Please use one of the following image types: %s"
+
+#: views/developers/addon_edit_properties.thtml:171
+#, fuzzy
+msgid "devcp_edit_properties_label_binary"
+msgstr "This add-on contains binary components"
+
+#: views/developers/addon_edit_properties.thtml:185
+#, fuzzy
+msgid "devcp_edit_properties_label_not_trusted"
+msgstr "Not Trusted"
+
+#: views/developers/addon_edit_properties.thtml:184
+#, fuzzy
+msgid "devcp_edit_properties_label_trusted"
+msgstr "Trusted"
+
+#: views/developers/addon_edit_properties.thtml:110
+#, fuzzy
+msgid "devcp_edit_properties_new_icon"
+msgstr "New Icon"
+
+#: views/developers/addon_edit_properties.thtml:118
+#, fuzzy
+msgid "devcp_edit_properties_remove_icon"
+msgstr "Remove Icon"
+
+#: views/developers/addon_edit_properties.thtml:136
+#, fuzzy
+msgid "devcp_edit_properties_transbox_homepage_description"
+msgstr ""
+"If your add-on has another homepage, enter its address here. Adding other "
+"translations is not necessary unless your website is localized into other "
+"languages."
+
+#: views/developers/addon_edit_properties.thtml:135
+#, fuzzy
+msgid "devcp_edit_properties_transbox_homepage_name"
+msgstr "Add-on Homepage"
+
+#: views/developers/addon_edit_properties.thtml:79
+#, fuzzy
+msgid "devcp_edit_properties_transbox_name_description"
+msgstr "The name of your add-on is displayed everywhere your add-on is listed."
+
+#: views/developers/addon_edit_properties.thtml:78
+#, fuzzy
+msgid "devcp_edit_properties_transbox_name_name"
+msgstr "Add-on Name"
+
+#: views/developers/addon_edit_properties.thtml:145
+#, fuzzy
+msgid "devcp_edit_properties_transbox_supportemail_description"
+msgstr ""
+"If you have an email address for support inquiries, enter it here. Adding "
+"other translations is not necessary unless you have different email "
+"addresses for different languages."
+
+#: views/developers/addon_edit_properties.thtml:144
+#, fuzzy
+msgid "devcp_edit_properties_transbox_supportemail_name"
+msgstr "Support Email Address"
+
+#: views/developers/addon_edit_properties.thtml:154
+#, fuzzy
+msgid "devcp_edit_properties_transbox_supporturl_description"
+msgstr ""
+"If your add-on has a support website or forum, enter its address here. "
+"Adding other translations is not necessary unless your website is localized "
+"into other languages."
+
+#: views/developers/addon_edit_properties.thtml:153
+#, fuzzy
+msgid "devcp_edit_properties_transbox_supporturl_name"
+msgstr "Support Website"
+
+#: views/developers/addon_edit_properties.thtml:183
+#, fuzzy
+msgid "devcp_edit_properties_trusted"
+msgstr "Trusted add-ons can become public without Editor review."
+
+#. %s is href="..." and should stay in the <a> tag.
+#: views/developers/addon_edit_properties.thtml:119
+#, fuzzy
+msgid "devcp_edit_properties_undelete"
+msgstr "Icon will be deleted on save. <a %s>Cancel?</a>"
+
+#: views/developers/addon_edit_properties.thtml:161
+#, fuzzy
+msgid "devcp_edit_properties_view_source"
+msgstr ""
+"The source of your add-on files can be viewed online by any logged in user "
+"if you wish."
+
+#: views/developers/addon_edit_properties.thtml:162
+#, fuzzy
+msgid "devcp_edit_properties_view_source_allow"
+msgstr "Allow online source viewing"
+
+#: views/developers/addon_edit_properties.thtml:163
+#, fuzzy
+msgid "devcp_edit_properties_view_source_do_not_allow"
+msgstr "Do not allow online source viewing"
+
+#: views/elements/developers/editbox.thtml:46
+#, fuzzy
+msgid "devcp_editbox_authors"
+msgstr "Authors"
+
+#: views/elements/developers/editbox.thtml:47
+#, fuzzy
+msgid "devcp_editbox_categories"
+msgstr "Categories"
+
+#: views/elements/developers/editbox.thtml:52
+#, fuzzy
+msgid "devcp_editbox_change_status"
+msgstr "Change Status"
+
+#: views/elements/developers/editbox.thtml:48
+#, fuzzy
+msgid "devcp_editbox_descriptions"
+msgstr "Descriptions"
+
+#: views/elements/developers/editbox.thtml:43
+#, fuzzy
+msgid "devcp_editbox_edit_addon"
+msgstr "Edit Add-on"
+
+#: views/elements/developers/editbox.thtml:57
+#, fuzzy
+msgid "devcp_editbox_new_version"
+msgstr "New Version"
+
+#: views/elements/developers/editbox.thtml:49
+#, fuzzy
+msgid "devcp_editbox_properties"
+msgstr "Properties"
+
+#: views/elements/developers/editbox.thtml:60
+#, fuzzy
+msgid "devcp_editbox_screenshots"
+msgstr "Preview Screenshots"
+
+#: views/elements/developers/editbox.thtml:53
+#, fuzzy
+msgid "devcp_editbox_statistics_dashboard"
+msgstr "Statistics Dashboard"
+
+#: views/elements/developers/editbox.thtml:54
+#, fuzzy
+msgid "devcp_editbox_versions"
+msgstr "Versions and Files"
+
+#: views/elements/developers/editbox.thtml:42
+#, fuzzy
+msgid "devcp_editbox_view_listing"
+msgstr "View Listing"
+
+#: views/elements/developers/editorsmenu.thtml:59
+msgid "devcp_editorsqueue_featured"
+msgstr "Kiemelt kiegészítők"
+
+# %1 is the review count
+#. %1 is the review count
+#: views/elements/developers/editorsqueue.thtml:42
+#: views/elements/developers/editorsmenu.thtml:56
+#, php-format
+msgid "devcp_editorsqueue_moderatedreviews"
+msgid_plural "devcp_editorsqueue_moderatedreviews"
+msgstr[0] "Moderált értékelések (%s)"
+msgstr[1] "Moderált értékelések (%s)"
+
+# %1 is the nominated addons count
+#. %1 is the nominated addons count
+#: views/elements/developers/editorsqueue.thtml:44
+#: views/elements/developers/editorsmenu.thtml:58
+#, php-format
+msgid "devcp_editorsqueue_nominated"
+msgid_plural "devcp_editorsqueue_nominated"
+msgstr[0] "Jelölt kiegészítők (%s)"
+msgstr[1] "Jelölt kiegészítők (%s)"
+
+# %1 is the update count
+#. %1 is the update count
+#: views/elements/developers/editorsqueue.thtml:43
+#: views/elements/developers/editorsmenu.thtml:57
+#, php-format
+msgid "devcp_editorsqueue_pendingupdates"
+msgid_plural "devcp_editorsqueue_pendingupdates"
+msgstr[0] "Függőben levő frissítések (%s)"
+msgstr[1] "Függőben levő frissítések (%s)"
+
+#: controllers/statistics_controller.php:147
+#: controllers/statistics_controller.php:361
+#: controllers/previews_controller.php:108
+#: controllers/previews_controller.php:211
+#: controllers/previews_controller.php:312
+msgid "devcp_error_addon_access_denied"
+msgstr "Nincs hozzáférése ehhez a kiegészítőhöz."
+
+#. %s is a complete URL with the text from devcp_error_appversion_reference_link_text
+#. in the <a> tag. This should be fixed.
+#: controllers/components/developers.php:591
+#, php-format
+msgid "devcp_error_appversion_reference_link"
+msgstr "Lásd %s referenciaként."
+
+#. This is the link text in the <a> for devcp_error_appversion_reference_link. This
+#. should be fixed.
+#: controllers/components/developers.php:591
+msgid "devcp_error_appversion_reference_link_text"
+msgstr "ezt az oldalt"
+
+#: views/developers/addon_edit_authors.thtml:76
+#, fuzzy
+msgid "devcp_error_empty_authors"
+msgstr "Your add-on must have at least one owner."
+
+#. %1$s is the name of the file
+#: controllers/components/developers.php:658
+#, fuzzy
+msgid "devcp_error_file_exists"
+msgstr ""
+"A version of that addon already exists. To replace it, you must delete the "
+"file %1$s first."
+
+#. %1$s is a file extension. Example: .exe
+#. %2$s is a comma separated list of extensions. Example: .xpi, .jar
+#: controllers/components/developers.php:355
+#, php-format
+msgid "devcp_error_file_extension"
+msgstr ""
+"Ez a fájlkiterjesztés (%s) nem engedélyezett a kijelölt kiegészítőtípushoz. "
+"Használja a következők egyikét: %s"
+
+#: controllers/components/developers.php:64
+msgid "devcp_error_five_categories"
+msgstr "Ne válasszon ötnél több kategóriát."
+
+#: controllers/components/developers.php:526
+msgid "devcp_error_guid_application"
+msgstr "A kiegészítő azonosítóját már használja egy alkalmazás."
+
+#: controllers/components/developers.php:337
+#: controllers/components/developers.php:389
+msgid "devcp_error_http_incomplete"
+msgstr "Az átvitel nem teljes"
+
+#: controllers/components/developers.php:335
+#: controllers/components/developers.php:336
+#: controllers/components/developers.php:387
+#: controllers/components/developers.php:388
+msgid "devcp_error_http_maxupload"
+msgstr "Túllépte a maximális feltöltési méretet"
+
+#: controllers/components/developers.php:338
+#: controllers/components/developers.php:390
+msgid "devcp_error_http_nofile"
+msgstr "Nincs fájl feltöltve"
+
+#. %1$s is a file extension. Example: .exe
+#. %2$s is a comma separated list of extensions. Example: .xpi, .jar
+#: controllers/components/developers.php:401
+#, php-format
+msgid "devcp_error_icon_extension"
+msgstr ""
+"Ez a fájlkiterjesztés (%s) nem engedélyezett az ikon számára. Használja a "
+"következők egyikét: %s"
+
+#: controllers/developers_controller.php:504
+msgid "devcp_error_index_rdf_notfound"
+msgstr "Nincs jelen az install.rdf."
+
+#: controllers/components/developers.php:601
+msgid "devcp_error_install_manifest"
+msgstr "A következő hibák vannak az install.rdf-ben:"
+
+#: controllers/developers_controller.php:1463
+msgid "devcp_error_invalid_addontype"
+msgstr "Válasszon egy érvényes kiegészítőtípust."
+
+#. %$1s is a version. Example: 3.1.1
+#. %$2s is an add-on name.
+#: controllers/components/developers.php:569
+#: controllers/components/developers.php:581
+#, php-format
+msgid "devcp_error_invalid_appversion"
+msgstr "%s nem érvényes verzió %s számára"
+
+#. %s is a string
+#: controllers/components/developers.php:521
+#, php-format
+msgid "devcp_error_invalid_guid"
+msgstr "A kiegészítő azonosítója érvénytelen: %s"
+
+#. %$1s is a version. Example: 3.1.1
+#. %$2s is an add-on name.
+#: controllers/components/developers.php:572
+#, php-format
+msgid "devcp_error_invalid_minversion"
+msgstr ""
+"%s nem érvényes verzió %s számára: a minimális verzió nem tartalmazhat *-ot"
+
+#: controllers/components/developers.php:536
+msgid "devcp_error_invalid_version"
+msgstr ""
+"A kiegészítő verziója érvénytelen: lásd a <a href=\"http://developer.mozilla."
+"org/en/docs/Toolkit_version_format\">specifikációt</a>"
+
+#: controllers/components/developers.php:531
+msgid "devcp_error_invalid_version_spaces"
+msgstr "A kiegészítő verziója érvénytelen: a verzió nem tartalmazhat szóközt."
+
+#. %s is an error message from the parser.
+#: controllers/components/developers.php:501
+#, php-format
+msgid "devcp_error_manifest_parse"
+msgstr "A következő hiba történt az install.rdf értelmezése közben: %s"
+
+#: controllers/components/developers.php:373
+msgid "devcp_error_move_file"
+msgstr "Fájl áthelyezése sikertelen"
+
+#. %s is the name of a file
+#: controllers/components/developers.php:650
+#: controllers/components/developers.php:662
+#: controllers/components/developers.php:667
+#: controllers/components/developers.php:727
+#: controllers/components/developers.php:738
+#: controllers/components/developers.php:743
+#, php-format
+msgid "devcp_error_moving_file"
+msgstr "Hiba történt a(z) %s áthelyezése közben."
+
+#: controllers/components/developers.php:595
+msgid "devcp_error_mozilla_application"
+msgstr "Legalább egy érvényes Mozilla-célalkalmazást meg kell adni."
+
+#: controllers/components/developers.php:516
+msgid "devcp_error_no_guid"
+msgstr "Nem található azonosító ehhez a kiterjesztéshez az install.rdf-ben."
+
+#: controllers/components/developers.php:287
+msgid "devcp_error_no_platform"
+msgstr "Nincs platform kiválasztva"
+
+#: controllers/components/developers.php:59
+msgid "devcp_error_one_category"
+msgstr "Válasszon legalább egy kategóriát."
+
+#: controllers/components/developers.php:92
+msgid "devcp_error_one_user"
+msgstr "Legalább egy szerzőt meg kell adni a kiegészítőhöz."
+
+#. %1$s is a file extension. Example: .exe
+#. %2$s is a comma separated list of extensions. Example: .xpi, .jar
+#: controllers/components/developers.php:1081
+#, php-format
+msgid "devcp_error_preview_extension"
+msgstr ""
+"Ez a fájlkiterjesztés (%s) nem engedélyezett az előnézet számára. Használja "
+"a következők egyikét: %s"
+
+#: controllers/components/developers.php:511
+msgid "devcp_error_updatekey"
+msgstr ""
+"A kiegészítők nem használhatnak updateKey-t. Törölje ezt az install.rdf-ből, "
+"és próbálja újra."
+
+#: controllers/components/developers.php:506
+msgid "devcp_error_updateurl"
+msgstr ""
+"A kiegészítők nem használhatnak külső updateURL-t. Törölje ezt az install."
+"rdf-ből, és próbálja újra."
+
+#: controllers/developers_controller.php:465
+#: controllers/components/developers.php:271
+msgid "devcp_error_upload_file"
+msgstr "Töltsön fel egy fájlt."
+
+#: views/developers/uploader.thtml:135
+#, fuzzy
+msgid "devcp_input_upload_file"
+msgstr "Upload File"
+
+#: views/pages/js_constants.js.thtml:89
+#, fuzzy
+msgid "devcp_js_a_cancel"
+msgstr "Cancel"
+
+#: views/pages/js_constants.js.thtml:90
+#, fuzzy
+msgid "devcp_js_add_email"
+msgstr "Please enter the account email of the author you wish to add."
+
+#. alt text for a down-arrow image.
+#: views/pages/js_constants.js.thtml:81
+#, fuzzy
+msgid "devcp_js_img_move_down"
+msgstr "Move Down"
+
+#. alt text for an up-arrow image.
+#: views/pages/js_constants.js.thtml:82
+#, fuzzy
+msgid "devcp_js_img_move_up"
+msgstr "Move Up"
+
+#: views/pages/js_constants.js.thtml:91
+#, fuzzy
+msgid "devcp_js_img_remove_compat"
+msgstr "Remove Application Compatibility"
+
+#: views/pages/js_constants.js.thtml:86
+#, fuzzy
+msgid "devcp_js_input_list_author"
+msgstr "List as author in public listings"
+
+#: views/pages/js_constants.js.thtml:92
+#, fuzzy
+msgid "devcp_js_license_select"
+msgstr "Please select a license."
+
+#: views/pages/js_constants.js.thtml:93
+#, fuzzy
+msgid "devcp_js_license_text"
+msgstr "Please enter text for your license."
+
+#. <option> text in a <select> for Author role in an add-on.
+#: views/pages/js_constants.js.thtml:84
+#, fuzzy
+msgid "devcp_js_option_developer"
+msgstr "Developer"
+
+#. <option> text in a <select> for Author role in an add-on.
+#: views/pages/js_constants.js.thtml:83
+#, fuzzy
+msgid "devcp_js_option_owner"
+msgstr "Owner"
+
+#. <option> text in a <select> for Author role in an add-on.
+#: views/pages/js_constants.js.thtml:85
+#, fuzzy
+msgid "devcp_js_option_viewer"
+msgstr "Viewer"
+
+#: views/pages/js_constants.js.thtml:88
+#, fuzzy
+msgid "devcp_js_remove_author"
+msgstr "Remove Author"
+
+#: views/pages/js_constants.js.thtml:87
+#, fuzzy
+msgid "devcp_js_sure_remove"
+msgstr "Are you <strong>sure</strong> you wish to remove this author?"
+
+#: views/pages/js_constants.js.thtml:77
+#, fuzzy
+msgid "devcp_js_upload_alert"
+msgstr "You must select a file to upload."
+
+#. %1$s is an addon id, like 32.
+#. %2$s is a version number, like 3.5.
+#: controllers/components/developers.php:1212
+#, fuzzy
+msgid "devcp_license_existing"
+msgstr "Custom license for add-on %1$s v%2$s"
+
+#: views/elements/developers/localebox.thtml:44
+msgid "devcp_localebox_header_localizedfields"
+msgstr "Honosított mezők"
+
+# %1 is the default locale
+#. %1 is the default locale
+#: views/elements/developers/localebox.thtml:48
+#, php-format
+msgid "devcp_localebox_intro"
+msgstr ""
+"Az oldal bizonyos mezői honosítva vannak, és a végfelhasználó anyanyelvén "
+"jelennek meg. Válasszon ki egy területi beállítást, és szerkessze a "
+"kiegészítő leírását azon a nyelven. Ha egy adott területi beállításhoz nem "
+"áll rendelkezésre a fordítás, akkor a kijelölt alapértelmezett területi "
+"beállítás (%s) lesz érvényes."
+
+#: views/elements/developers/sidebar.thtml:68
+#: views/elements/developers/myaddons.thtml:75
+msgid "devcp_myaddons_admincp_link"
+msgstr "Adminisztrációs eszközök"
+
+#: views/elements/developers/sidebar.thtml:65
+#: views/elements/developers/myaddons.thtml:72
+msgid "devcp_myaddons_editorcp_link"
+msgstr "Szerkesztőeszközök"
+
+#: views/elements/developers/myaddons.thtml:52
+msgid "devcp_myaddons_link"
+msgstr "Saját kiegészítők"
+
+#: views/elements/developers/sidebar.thtml:70
+#: views/elements/developers/myaddons.thtml:77
+msgid "devcp_myaddons_mainpage_link"
+msgstr "Vissza a főoldalra"
+
+#: views/elements/developers/sidebar.thtml:63
+#: views/elements/developers/myaddons.thtml:70
+msgid "devcp_myaddons_statistics_link"
+msgstr "Statisztikák"
+
+#: views/elements/developers/sidebar.thtml:62
+#: views/elements/developers/myaddons.thtml:69
+msgid "devcp_myaddons_submitaddon_link"
+msgstr "Kiegészítő beküldése"
+
+#: views/elements/developers/sidebar.thtml:48
+#: views/elements/developers/myaddons.thtml:67
+msgid "devcp_myaddons_title"
+msgstr "Fejlesztőeszközök"
+
+#. %1$s is an add-on ID, perhaps 167.
+#. %2$s is a URL.
+#: controllers/developers_controller.php:256
+#, fuzzy
+msgid "devcp_new_addon_error"
+msgstr ""
+"This add-on ID (%1$s) already exists in the database. If this is your add-"
+"on, you can <a href=\"%2$s\">upload a new version</a>."
+
+#: views/developers/addon_status_nominate.thtml:62
+#, fuzzy
+msgid "devcp_nominate_cancel"
+msgstr "Cancel and return"
+
+# %1 is the addon name
+#. %1 is the add-on name
+#: views/developers/addon_status_nominate.thtml:61
+#, php-format
+msgid "devcp_nominate_submit_nominate"
+msgstr "%s jelölése"
+
+#: views/developers/addon_edit_properties.thtml:50
+#: views/developers/addon_status.thtml:49
+#: views/developers/versions_edit.thtml:50
+#, fuzzy
+msgid "devcp_notice_changes_error"
+msgstr ""
+"<span>One or more of your changes couldn't be saved.</span><br />Please look "
+"for the errors below. The rest of your changes were successfully saved."
+
+#: views/developers/addon_edit_authors.thtml:47
+#: views/developers/addon_edit_properties.thtml:47
+#: views/developers/addon_status.thtml:46
+#: views/developers/addon_edit_descriptions.thtml:47
+#: views/developers/versions_edit.thtml:47
+#: views/developers/addon_edit_categories.thtml:46
+#, fuzzy
+msgid "devcp_notice_changes_saved"
+msgstr ""
+"<span>Your changes have been saved.</span><br />Please note that some "
+"changes may take several hours to appear in all areas of the website."
+
+#: controllers/previews_controller.php:252
+msgid "devcp_notice_cleardefault"
+msgstr ""
+"Ha eltávolítja ezt az alapértelmezett előnézetet, akkor egy másik előnézet "
+"lesz automatikusan az alapértelmezett előnézet."
+
+#: controllers/previews_controller.php:184
+#: controllers/previews_controller.php:251
+msgid "devcp_notice_makedefault"
+msgstr ""
+"Ha ezt az előnézetet jelöli ki alapértelmezettnek, akkor a jelenlegi "
+"alapértelmezett előnézet elveszíti ezt az állapotát."
+
+#: views/developers/addon_edit_authors.thtml:70
+#, fuzzy
+msgid "devcp_notice_unsaved_changes"
+msgstr "You have unsaved changes."
+
+#: controllers/developers_controller.php:87
+#: controllers/developers_controller.php:97
+#: controllers/developers_controller.php:100
+#: controllers/previews_controller.php:67
+#: controllers/previews_controller.php:79
+#: controllers/previews_controller.php:82
+msgid "devcp_pagetitle"
+msgstr "Fejlesztőeszközök"
+
+#: controllers/previews_controller.php:103
+#: controllers/previews_controller.php:104
+msgid "devcp_preview_add_pagetitle"
+msgstr "Előnézet hozzáadása"
+
+#: controllers/previews_controller.php:135
+msgid "devcp_preview_added_successfully"
+msgstr "Előnézet sikeresen hozzáadva."
+
+#: controllers/previews_controller.php:323
+msgid "devcp_preview_deleted_successfully"
+msgstr "Előnézet sikeresen törölve."
+
+#: controllers/previews_controller.php:194
+#: controllers/previews_controller.php:195
+msgid "devcp_preview_edit_pagetitle"
+msgstr "Előnézet szerkesztése"
+
+#: controllers/previews_controller.php:237
+msgid "devcp_preview_updated_successfully"
+msgstr "Előnézet sikeresen frissítve."
+
+#: views/developers/previews.thtml:120
+#, fuzzy
+msgid "devcp_previews_a_another"
+msgstr "Add Another Preview"
+
+#: views/developers/previews.thtml:96
+#, fuzzy
+msgid "devcp_previews_a_delete"
+msgstr "Delete Preview"
+
+#: views/developers/previews.thtml:95
+#, fuzzy
+msgid "devcp_previews_a_replace"
+msgstr "Replace Preview"
+
+#: views/developers/previews.thtml:126
+#, fuzzy
+msgid "devcp_previews_a_update"
+msgstr "Update Previews"
+
+#: views/developers/previews.thtml:115 views/developers/previews.thtml:124
+#, fuzzy
+msgid "devcp_previews_add_new"
+msgstr "Add New Preview"
+
+#. %s is a list of file extensions, e.g. ".png, .gif"
+#: views/developers/previews.thtml:116
+#, fuzzy
+msgid "devcp_previews_add_select"
+msgstr ""
+"Select an image to upload below. Images larger than the maximum size of 700 "
+"pixels wide by 525 pixels tall will be resized. Allowed file types: %s"
+
+#: views/developers/previews.thtml:121
+#, fuzzy
+msgid "devcp_previews_click_below"
+msgstr "Click Update Previews below to upload."
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/previews.thtml:102
+#, fuzzy
+msgid "devcp_previews_click_update"
+msgstr ""
+"Click the Update Previews button below to save this image. (<a %s>Cancel?</"
+"a>)"
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/previews.thtml:107
+#, fuzzy
+msgid "devcp_previews_error_message"
+msgstr ""
+"This preview will be deleted when Update Previews is clicked below. (<a %"
+"s>Cancel?</a>)"
+
+#: views/previews/add.thtml:45
+msgid "devcp_previews_filetype_info"
+msgstr ""
+"Az alábbi űrlap használatával töltsön fel PNG, JPG vagy GIF formátumú "
+"képernyőképet a kiegészítőjéről. A 700 képpontnál szélesebb és az 525 "
+"képpontnál magasabb képek automatikusan át lesznek méretezve."
+
+#: views/previews/add.thtml:43
+msgid "devcp_previews_header_add"
+msgstr "Előnézet hozzáadása"
+
+#: views/developers/previews.thtml:80
+#, fuzzy
+msgid "devcp_previews_header_caption"
+msgstr "Preview Caption"
+
+#: views/previews/edit.thtml:43
+msgid "devcp_previews_header_edit"
+msgstr "Előnézet szerkesztése"
+
+#: views/developers/previews.thtml:93
+#, fuzzy
+msgid "devcp_previews_label_default"
+msgstr "Default Preview"
+
+#: views/previews/add.thtml:54
+msgid "devcp_previews_label_file"
+msgstr "Előnézeti fájl"
+
+#: views/previews/add.thtml:59 views/previews/edit.thtml:50
+msgid "devcp_previews_label_makedefault"
+msgstr "Legyen ez az alapértelmezett előnézeti kép"
+
+#: views/developers/previews.thtml:100
+#, fuzzy
+msgid "devcp_previews_label_new"
+msgstr "New image:"
+
+#: views/developers/previews.thtml:118
+#, fuzzy
+msgid "devcp_previews_label_upload"
+msgstr "Upload Preview: "
+
+#: views/developers/previews.thtml:50
+#, fuzzy
+msgid "devcp_previews_notice_error"
+msgstr "One or more of your new previews could not be saved."
+
+#: views/developers/previews.thtml:47
+#, fuzzy
+msgid "devcp_previews_notice_success"
+msgstr "Your previews have been updated successfully."
+
+#: views/developers/previews.thtml:59
+#, fuzzy
+msgid "devcp_previews_p_screenshots"
+msgstr ""
+"The preview screenshots for your add-on are shown below. You can make "
+"changes to captions or images below. The Default Preview is the preview that "
+"is displayed next to your add-on in search and browse listings."
+
+#: views/previews/edit.thtml:55
+msgid "devcp_previews_submit_delete"
+msgstr "Előnézet törlése"
+
+#: views/previews/edit.thtml:55
+msgid "devcp_previews_submit_delete_confirm"
+msgstr "Biztosan törli az előnézetet?"
+
+#: views/previews/edit.thtml:54
+msgid "devcp_previews_submit_edit"
+msgstr "Előnézet szerkesztése"
+
+#: views/previews/add.thtml:63
+msgid "devcp_previews_submit_upload"
+msgstr "Előnézet feltöltése"
+
+#: views/developers/previews.thtml:78
+#, fuzzy
+msgid "devcp_previews_thumbnail"
+msgstr "Thumbnail"
+
+#. %s is the add-on name.
+#: views/developers/previews.thtml:44
+#, fuzzy
+msgid "devcp_previews_title"
+msgstr "%s Preview Manager"
+
+#: views/developers/uploader.thtml:74
+msgid "devcp_review_agreement_please"
+msgstr ""
+"Mielőtt folytatja, olvassa el és fogadja el a következő Fejlesztői "
+"megállapodást."
+
+#: views/elements/developers/rolecheck.thtml:42
+#, fuzzy
+msgid "devcp_rolecheck_no_privs"
+msgstr ""
+"<span>You do not have sufficient privileges to make changes on this page.</"
+"span><br />Contact the Add-on Owner if you need to make changes."
+
+#: controllers/developers_controller.php:1315
+#, fuzzy
+msgid "devcp_several_hours"
+msgstr ""
+"Please note that some changes may take several hours to appear in all areas "
+"of the website."
+
+#: views/elements/developers/sidebar.thtml:52
+#, fuzzy
+msgid "devcp_sidebar_a_dashboard"
+msgstr "Dashboard"
+
+#. %s is a number
+#: views/elements/developers/statsbar.thtml:45
+#: views/developers/dashboard.thtml:79
+#, php-format
+msgid "devcp_statsbar_adu"
+msgstr "<em>%s</em> aktív felhasználó"
+
+#. %s is a number
+#: views/elements/developers/statsbar.thtml:41
+#: views/developers/dashboard.thtml:75
+#, php-format
+msgid "devcp_statsbar_total_downloads"
+msgstr "<em>%s</em> letöltés összesen"
+
+#. %s is a number
+#: views/elements/developers/statsbar.thtml:43
+#: views/developers/dashboard.thtml:77
+#, php-format
+msgid "devcp_statsbar_weekly_downloads"
+msgstr "<em>%s</em> letöltés a héten"
+
+#: views/developers/addon_status_confirm.thtml:59
+#, fuzzy
+msgid "devcp_status_confirm_active"
+msgstr ""
+"Marking this add-on active will cause it to show up in public areas "
+"appropriate for its status, including search and browse listings. It will be "
+"downloadable from the website and could be returned in client update checks, "
+"depending on its status. You will be able to return here and disable it "
+"again at your convenience."
+
+#: views/developers/addon_status_confirm.thtml:59
+#, fuzzy
+msgid "devcp_status_confirm_active_sure"
+msgstr "Are you sure you wish to mark this add-on active?"
+
+#: views/developers/addon_status_confirm.thtml:50
+#, fuzzy
+msgid "devcp_status_confirm_header_sure"
+msgstr "Are you sure?"
+
+#: views/developers/addon_status_confirm.thtml:55
+#, fuzzy
+msgid "devcp_status_confirm_inactive"
+msgstr ""
+"Marking this add-on inactive will prevent it from showing up in any public "
+"areas, including search and browse listings. It will not be downloadable "
+"from the website and will not be returned in client update checks. You will "
+"be able to return here and re-enable it at your convenience."
+
+#: views/developers/addon_status_confirm.thtml:55
+#, fuzzy
+msgid "devcp_status_confirm_inactive_sure"
+msgstr "Are you sure you wish to mark this add-on inactive?'"
+
+#: views/developers/addon_status_confirm.thtml:74
+#, fuzzy
+msgid "devcp_status_confirm_no"
+msgstr "No, cancel"
+
+#: views/developers/addon_status_confirm.thtml:67
+#, fuzzy
+msgid "devcp_status_confirm_public"
+msgstr ""
+"Making this add-on public will make it available for anyone to download and "
+"will begin offering updates to existing users."
+
+#: views/developers/addon_status_confirm.thtml:67
+#, fuzzy
+msgid "devcp_status_confirm_public_sure"
+msgstr "Are you sure you wish to make this add-on public?"
+
+#: views/developers/addon_status_confirm.thtml:63
+#, fuzzy
+msgid "devcp_status_confirm_sandbox"
+msgstr ""
+"Moving this add-on back to the sandbox will require users to login before "
+"downloading and updates will no longer be offered to existing users. Because "
+"your add-on is currently public, you will be able to return here at any time "
+"to make it public again."
+
+#: views/developers/addon_status_confirm.thtml:63
+#, fuzzy
+msgid "devcp_status_confirm_sandbox_sure"
+msgstr "Are you sure you wish to move this add-on to the sandbox?"
+
+#: views/developers/addon_status_confirm.thtml:73
+#, fuzzy
+msgid "devcp_status_confirm_yes"
+msgstr "Yes, I'm Sure"
+
+#: views/developers/addon_status_nominate.thtml:46
+#, fuzzy
+msgid "devcp_status_nominate_error_notice"
+msgstr ""
+"<span>A nomination message is required.</span><br />Please fill in the text "
+"box with the requested information and try again."
+
+#: views/developers/addon_status_nominate.thtml:55
+#, fuzzy
+msgid "devcp_status_nominate_header"
+msgstr "Add-on Nomination"
+
+#: views/developers/dashboard.thtml:85
+msgid "devcp_summary_lastversion"
+msgstr "Legújabb verzió:"
+
+#. %s is the add-on name.
+#: views/developers/addon_edit.thtml:43
+#: views/developers/addon_edit_authors.thtml:44
+#: views/developers/versions_delete.thtml:43
+#: views/developers/addon_edit_properties.thtml:44
+#: views/developers/addon_edit_descriptions.thtml:44
+#: views/developers/versions_edit.thtml:44
+#: views/developers/addon_edit_categories.thtml:43
+#: views/developers/versions.thtml:43
+#, fuzzy
+msgid "devcp_title_edit_addon"
+msgstr "Edit %s"
+
+#. title attribute for a javascript link that pops up a help dialog.
+#: views/elements/translationbox.thtml:68
+#, fuzzy
+msgid "devcp_transbox_a_title_help"
+msgstr "Help (does not leave page)"
+
+#: views/elements/translationbox.thtml:68
+#, fuzzy
+msgid "devcp_transbox_alt_help"
+msgstr "Help"
+
+#. %1$s is <span>17</span>, %2$s is 42.
+#: views/elements/translationbox.thtml:101
+#, fuzzy
+msgid "devcp_transbox_chars_used"
+msgstr "Characters used: %1$s / %2$s"
+
+#: views/elements/translationbox.thtml:132
+#, fuzzy
+msgid "devcp_transbox_delete_sure"
+msgstr "Are you sure you wish to delete this translation?"
+
+#. %s is a locale, like en-US.
+#: views/elements/translationbox.thtml:143
+#, fuzzy
+msgid "devcp_transbox_help_header_tabs"
+msgstr "What are these %s tabs?"
+
+#: views/elements/translationbox.thtml:145
+#, fuzzy
+msgid "devcp_transbox_help_header_what"
+msgstr "What if I don't have any translations?"
+
+#: views/elements/translationbox.thtml:147
+#, fuzzy
+msgid "devcp_transbox_help_hide"
+msgstr "Hide Help"
+
+#: views/elements/translationbox.thtml:146
+#, fuzzy
+msgid "devcp_transbox_help_if"
+msgstr ""
+"If a user browses the site and a translation isn't available in their own "
+"language, it will fall back to your add-on's Default Locale, specified in "
+"the Edit Add-on Properties area. If you don't have any translations, just "
+"enter what you can into your Default Locale, which should be a language you "
+"speak."
+
+#: views/elements/translationbox.thtml:144
+#, fuzzy
+msgid "devcp_transbox_help_transbox"
+msgstr ""
+"This is a <i>Translation Box</i>. It allows you to localize a specific field "
+"into any other languages for which you might have a translation. You can "
+"add, edit, and remove translations using the locale tabs."
+
+#: views/elements/translationbox.thtml:85
+#, fuzzy
+msgid "devcp_transbox_img_add_trans"
+msgstr "Add Translation"
+
+#: views/elements/translationbox.thtml:86
+#, fuzzy
+msgid "devcp_transbox_img_remove_trans"
+msgstr "Remove Translation"
+
+#: views/elements/translationbox.thtml:123
+#, fuzzy
+msgid "devcp_transbox_input_add_all"
+msgstr "Add Locale to All"
+
+#: views/elements/translationbox.thtml:122
+#, fuzzy
+msgid "devcp_transbox_input_add_locale"
+msgstr "Add Locale"
+
+#: views/elements/translationbox.thtml:124
+#: views/elements/translationbox.thtml:135
+#, fuzzy
+msgid "devcp_transbox_input_cancel"
+msgstr "Cancel"
+
+#: views/elements/translationbox.thtml:134
+#, fuzzy
+msgid "devcp_transbox_input_delete"
+msgstr "Delete It"
+
+#: views/elements/translationbox.thtml:113
+#, fuzzy
+msgid "devcp_transbox_select_locale"
+msgstr "Select the locale of the translation to add:"
+
+#. %1$s and %2$s are GUIDs.
+#: controllers/developers_controller.php:343
+#, fuzzy
+msgid "devcp_update_addon_guid_error"
+msgstr ""
+"The add-on GUID used in this file (%1$s) does not match the existing GUID "
+"for this add-on (%2$s)."
+
+#: controllers/developers_controller.php:334
+#, fuzzy
+msgid "devcp_update_addon_priv_error"
+msgstr "You do not have sufficient privileges to update this add-on."
+
+#. %1$s is a version number, %2$s is an add-on ID.
+#: controllers/developers_controller.php:399
+#, fuzzy
+msgid "devcp_update_addon_version_belong_error"
+msgstr "The specified version (%1$s) does not belong to this add-on (%2$s)."
+
+#. %1$s is a version number, maybe 1.1.
+#. %2$s is a URL.
+#: controllers/developers_controller.php:351
+#, fuzzy
+msgid "devcp_update_addon_version_exists_error"
+msgstr ""
+"The version number uploaded (%1$s) already exists for this add-on. If you "
+"are trying to add another file to this version, <a href=\"%2$s\">click here</"
+"a>."
+
+#. %1$s and %2$s are version numbers.
+#: controllers/developers_controller.php:405
+#, fuzzy
+msgid "devcp_update_addon_version_match_error"
+msgstr ""
+"The uploaded version number (%1$s) does not match the existing version "
+"number (%2$s)."
+
+#: views/developers/uploader.thtml:68
+#, fuzzy
+msgid "devcp_uploader_a_start"
+msgstr "Get Started"
+
+#: views/developers/uploader.thtml:137
+#, fuzzy
+msgid "devcp_uploader_ajax_loading"
+msgstr "Uploading file..."
+
+#: views/developers/uploader.thtml:82
+#, fuzzy
+msgid "devcp_uploader_button_agree"
+msgstr "Agree and continue"
+
+#: views/developers/uploader.thtml:157
+#, fuzzy
+msgid "devcp_uploader_button_edit"
+msgstr "Edit My Add-on"
+
+#: views/developers/uploader.thtml:158
+#, fuzzy
+msgid "devcp_uploader_button_later"
+msgstr "I'll complete my add-on later."
+
+#: views/developers/uploader.thtml:168
+#, fuzzy
+msgid "devcp_uploader_button_release"
+msgstr "Add Release Notes"
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/uploader.thtml:156
+#, fuzzy
+msgid "devcp_uploader_created_results"
+msgstr ""
+"<p>Your add-on listing has been successfully created. The basic information "
+"obtained from your uploaded file has been stored, but there's a lot more to "
+"your listing that can be customized.</p><p>Your add-on is currently marked "
+"as <strong>Incomplete</strong>. In order to complete your add-on, you'll "
+"need to make sure it has an accurate name, summary, and description, as well "
+"as at least one selected category. You can edit your add-on's information "
+"using the link below and check the status of your add-on at any time on the "
+"<a %s>status page</a>."
+
+#: views/developers/uploader.thtml:143
+#, fuzzy
+msgid "devcp_uploader_error_correct"
+msgstr "Please correct this problem and upload your file again."
+
+#. %1$s is a version number, %2$s is a status, e.g Public or Incomplete.
+#: views/developers/uploader.thtml:175
+#, fuzzy
+msgid "devcp_uploader_file_created"
+msgstr ""
+"Your new file has been added to version %1$s and is currently marked as %2$s."
+
+#: views/developers/uploader.thtml:154
+#, fuzzy
+msgid "devcp_uploader_header_created"
+msgstr "Add-on Created!"
+
+#: views/developers/uploader.thtml:141
+#, fuzzy
+msgid "devcp_uploader_header_error"
+msgstr "Oops! There seems to be a problem with this file..."
+
+#: views/developers/uploader.thtml:173
+#, fuzzy
+msgid "devcp_uploader_header_file_added"
+msgstr "File Added!"
+
+#: views/developers/uploader.thtml:66
+#, fuzzy
+msgid "devcp_uploader_header_how"
+msgstr "How does it all work?"
+
+#. %s is the version number, e.g. 3.2.
+#: views/developers/uploader.thtml:163
+#, fuzzy
+msgid "devcp_uploader_header_update_created"
+msgstr "Version %s Created"
+
+#: views/developers/uploader.thtml:117
+#, fuzzy
+msgid "devcp_uploader_header_upload"
+msgstr "Upload Your File"
+
+#: views/developers/uploader.thtml:67
+#, fuzzy
+msgid "devcp_uploader_how"
+msgstr ""
+"<p>Thanks for your interest in submitting your add-on to Mozilla Add-ons. "
+"Hosting your add-on on Mozilla Add-ons is the easiest way to handle "
+"distribution of your add-on. Here's what you'll get:</p><ul><li>Each add-on "
+"will have a public display page with information you provide, such as a "
+"brief summary of the add-on's functionality, an optional longer description, "
+"and a showcase of preview screenshots of your add-on.</li><li>Your add-on "
+"will appear in search and browse listings across the site, and even in the "
+"Add-ons Manager of Firefox 3.</li><li>We'll take care of hosting all of your "
+"downloads and providing automatic updates to users when you upload a new "
+"version.</li><li>You'll have access to a statistics dashboard with detailed "
+"information about your user base.</li></ul><p>Add-ons hosted on the site "
+"must be reviewed by a Mozilla Add-ons Editor before they will have all of "
+"the features listed above. If you're ready to start the process and have "
+"your add-on package ready for upload, just click on Get Started below!</p>"
+
+#: views/developers/uploader.thtml:125
+#, fuzzy
+msgid "devcp_uploader_label_platformtype"
+msgstr "Supported Platforms:"
+
+#: views/developers/uploader.thtml:124
+#, fuzzy
+msgid "devcp_uploader_label_upload_field"
+msgstr "Add-on File: "
+
+#: controllers/components/developers.php:1221
+#, fuzzy
+msgid "devcp_uploader_option_other"
+msgstr "Other"
+
+#. %1$s is a number, %2$s is href="..." and should stay in the <a> tag.
+#: views/developers/uploader.thtml:176
+#, fuzzy
+msgid "devcp_uploader_p_pending_file"
+msgstr ""
+"The new file will be available to the public as soon as an editor is able to "
+"review it. There are currently %1$s other add-ons in the queue. Want to be "
+"reviewed faster? Consider <a %2$s>becoming an editor</a>."
+
+#. %1$s is a number, %2$s is href="..." and should stay in the <a> tag.
+#: views/developers/uploader.thtml:166
+#, fuzzy
+msgid "devcp_uploader_p_pending_version"
+msgstr ""
+"The new version will be available to the public as soon as an editor is able "
+"to review it. There are currently %1$s other add-ons in the queue. Want to "
+"be reviewed faster? Consider <a %2$s>becoming an editor</a>."
+
+#. %s is a status, e.g Public or Incomplete.
+#: views/developers/uploader.thtml:165
+#, fuzzy
+msgid "devcp_uploader_p_update_created"
+msgstr "Your new version has been created and is currently marked as %s."
+
+#. %1$s is href="..." and should stay in the 'Versions and Files' <a> tag.
+#. %2$s is href="..." and should stay in the 'current status' <a> tag.
+#: views/developers/uploader.thtml:177
+#, fuzzy
+msgid "devcp_uploader_p_update_file"
+msgstr ""
+"View your new file in the <a %1$s>Versions and Files page</a>, check out "
+"your add-on's <a %2$s>current status</a>, or <b>add release notes</b> by "
+"clicking the button below (highly recommended)."
+
+#. %1$s is href="..." and should stay in the 'Versions and Files' <a> tag.
+#. %2$s is href="..." and should stay in the 'current status' <a> tag.
+#: views/developers/uploader.thtml:167
+#, fuzzy
+msgid "devcp_uploader_p_update_version"
+msgstr ""
+"View your new version in the <a %1$s>Versions and Files page</a>, check out "
+"your add-on's <a %2$s>current status</a>, or <b>add release notes</b> by "
+"clicking the button below (highly recommended)."
+
+#: views/developers/uploader.thtml:118
+#, fuzzy
+msgid "devcp_uploader_p_upload"
+msgstr ""
+"Upload your add-on file using the form below. If you have multiple, platform-"
+"specific files to upload, choose a single file and then upload the others "
+"using the Versions and Files Manager."
+
+#: views/developers/uploader.thtml:125
+#, fuzzy
+msgid "devcp_uploader_platformtype_all"
+msgstr "All"
+
+#: views/developers/uploader.thtml:126
+#, fuzzy
+msgid "devcp_uploader_platformtype_specific"
+msgstr "Specific:"
+
+#. Used as first item in a <select>.
+#: controllers/components/developers.php:1185
+#, fuzzy
+msgid "devcp_uploader_please_choose"
+msgstr "Please Choose..."
+
+#. %1$s is the add-on name, %2$s is the version number.
+#: views/developers/uploader.thtml:57
+#, fuzzy
+msgid "devcp_uploader_title_file"
+msgstr "Add File to %1$s %2$s"
+
+#: views/developers/uploader.thtml:50
+#, fuzzy
+msgid "devcp_uploader_title_submit"
+msgstr "Submit New Add-on"
+
+#. %s is the add-on name.
+#: views/developers/uploader.thtml:54
+#, fuzzy
+msgid "devcp_uploader_title_update"
+msgstr "Update %s"
+
+#. %s is a full <a> tag
+#: controllers/developers_controller.php:503
+#, php-format
+msgid "devcp_valid_app_reference"
+msgstr "Lásd %s referenciaként."
+
+#. This is the text in the <a> tag for devcp_valid_app_reference. This should be
+#. fixed.
+#: controllers/developers_controller.php:503
+msgid "devcp_valid_app_reference_linktext"
+msgstr "ezt az oldalt"
+
+#: controllers/developers_controller.php:581
+#, fuzzy
+msgid "devcp_verify_author_error"
+msgstr "No account found for that email address."
+
+#: controllers/developers_controller.php:553
+#, fuzzy
+msgid "devcp_verify_search_engine_error"
+msgstr ""
+"Either the XML is invalid or required fields are missing. Please <a href="
+"\"https://developer.mozilla.org/en/Creating_OpenSearch_plugins_for_Firefox"
+"\">read the documentation</a>, verify your add-on, and try again."
+
+#: views/developers/versions.thtml:75
+#, fuzzy
+msgid "devcp_versions_a_cancel"
+msgstr "Cancel"
+
+#: views/developers/versions.thtml:79
+#, fuzzy
+msgid "devcp_versions_a_delete"
+msgstr "Delete Version"
+
+#: views/developers/versions.thtml:74
+#, fuzzy
+msgid "devcp_versions_a_empty"
+msgstr "Remove Empty Version"
+
+#: views/developers/versions.thtml:71
+#, fuzzy
+msgid "devcp_versions_a_remove"
+msgstr "Remove?"
+
+#: views/developers/versions.thtml:91
+#, fuzzy
+msgid "devcp_versions_add"
+msgstr "Add New Version"
+
+#: views/developers/versions_delete.thtml:58
+#, fuzzy
+msgid "devcp_versions_delete_a_cancel"
+msgstr "Cancel"
+
+#: views/developers/versions_delete.thtml:56
+#, fuzzy
+msgid "devcp_versions_delete_a_delete"
+msgstr "Delete Version"
+
+#. Followed by a list of reviews and files that will be removed.
+#: views/developers/versions_delete.thtml:50
+#, fuzzy
+msgid "devcp_versions_delete_also"
+msgstr "This will also delete:"
+
+#: views/developers/versions_delete.thtml:53
+#, fuzzy
+msgid "devcp_versions_delete_files"
+msgid_plural "devcp_versions_delete_files"
+msgstr[0] "%s file"
+msgstr[1] "%s files"
+
+#. %s is the version number.
+#: views/developers/versions_delete.thtml:48
+#, fuzzy
+msgid "devcp_versions_delete_header"
+msgstr "Delete Version %s?"
+
+#: views/developers/versions_delete.thtml:52
+#, fuzzy
+msgid "devcp_versions_delete_reviews"
+msgid_plural "devcp_versions_delete_reviews"
+msgstr[0] "%s review"
+msgstr[1] "%s reviews"
+
+#. %s is the version number.
+#: views/developers/versions_delete.thtml:49
+#, fuzzy
+msgid "devcp_versions_delete_sure"
+msgstr "Are you sure you want to permanently delete version %s?"
+
+#: views/developers/versions_edit.thtml:102
+#: views/developers/versions_edit.thtml:155
+#, fuzzy
+msgid "devcp_versions_edit_a_cancel"
+msgstr "Cancel"
+
+#: views/developers/versions_edit.thtml:101
+#, fuzzy
+msgid "devcp_versions_edit_a_delete"
+msgstr "Delete File"
+
+#: views/developers/versions_edit.thtml:165
+#, fuzzy
+msgid "devcp_versions_edit_a_new_app"
+msgstr "Add New Application"
+
+#: views/developers/versions_edit.thtml:154
+#, fuzzy
+msgid "devcp_versions_edit_a_remove_app"
+msgstr "Remove Application"
+
+#: views/developers/versions_edit.thtml:114
+#, fuzzy
+msgid "devcp_versions_edit_add"
+msgstr "Add New File"
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/versions_edit.thtml:121
+#, fuzzy
+msgid "devcp_versions_edit_adjust"
+msgstr ""
+"Adjusting application information here will allow users to install your add-"
+"on even if the install.rdf in the package indicates that the add-on is "
+"incompatible. <a %s>List of supported applications</a>"
+
+#: views/developers/versions_edit.thtml:153
+#, fuzzy
+msgid "devcp_versions_edit_compat_sure"
+msgstr ""
+"Are you <b>sure</b> you wish to remove compatibility with this application?"
+
+#: views/developers/versions_edit.thtml:100
+#, fuzzy
+msgid "devcp_versions_edit_delete_sure"
+msgstr "Are you <b>sure</b> you wish to permanently delete this file?"
+
+#: views/developers/versions_edit.thtml:203
+#, fuzzy
+msgid "devcp_versions_edit_header_approval"
+msgstr "Approval Information"
+
+#: views/developers/versions_edit.thtml:120
+#, fuzzy
+msgid "devcp_versions_edit_header_compat"
+msgstr "Compatible Applications"
+
+#: views/developers/versions_edit.thtml:74
+#, fuzzy
+msgid "devcp_versions_edit_header_file"
+msgstr "File Information"
+
+#: views/developers/versions_edit.thtml:189
+#, fuzzy
+msgid "devcp_versions_edit_header_license"
+msgstr "License"
+
+#. %s is the version number.
+#: views/developers/versions_edit.thtml:53
+#, fuzzy
+msgid "devcp_versions_edit_header_manage"
+msgstr "Manage Version %s"
+
+#: views/developers/versions_edit.thtml:212
+#, fuzzy
+msgid "devcp_versions_edit_header_notes"
+msgstr "Approval Notes"
+
+#: views/developers/versions_edit.thtml:98
+#, fuzzy
+msgid "devcp_versions_edit_img_delete"
+msgstr "Delete File"
+
+#. %1$s is the file id, e.g. 18723.
+#. %2$s is the platform name, e.g. ALL or Windows.
+#. %3$s is the _('date) created.
+#. %4$s is the status, e.g. "In Sandbox" or "Public".
+#. %5$s is the _('date') status was changed.
+#: views/developers/versions_edit.thtml:208
+#, fuzzy
+msgid "devcp_versions_edit_li_file"
+msgstr "File %1$s (%2$s) created on %3$s and changed to %4$s on %5$s"
+
+#: views/developers/versions_edit.thtml:190
+#, fuzzy
+msgid "devcp_versions_edit_license_description"
+msgstr ""
+"Please select the appropriate license for your add-on. This license "
+"specifies the rights you grant on your source code."
+
+#: views/developers/versions_edit.thtml:111
+#, fuzzy
+msgid "devcp_versions_edit_no_files"
+msgstr "No files found."
+
+#: views/developers/versions_edit.thtml:213
+#, fuzzy
+msgid "devcp_versions_edit_optional"
+msgstr "Optional information for the Editor that reviews this version."
+
+#: views/developers/versions_edit.thtml:151
+#, fuzzy
+msgid "devcp_versions_edit_remove_compat"
+msgstr "Remove Application Compatibility"
+
+#: views/developers/versions_edit.thtml:167
+#, fuzzy
+msgid "devcp_versions_edit_select_app"
+msgstr "Please Select an Application"
+
+#: views/developers/versions_edit.thtml:78
+#, fuzzy
+msgid "devcp_versions_edit_th_file"
+msgstr "File"
+
+#: views/developers/versions_edit.thtml:79
+#, fuzzy
+msgid "devcp_versions_edit_th_platform"
+msgstr "Platform"
+
+#: views/developers/versions_edit.thtml:80
+#, fuzzy
+msgid "devcp_versions_edit_th_size"
+msgstr "Size"
+
+#: views/developers/versions_edit.thtml:81
+#, fuzzy
+msgid "devcp_versions_edit_th_status"
+msgstr "Status"
+
+#: views/developers/versions_edit.thtml:183
+#, fuzzy
+msgid "devcp_versions_edit_transbox_releasenotes_description"
+msgstr ""
+"Information about changes in this release, new features, known bugs, and "
+"other useful information specific to this release/version. This information "
+"will also be available to users updating the add-on in the Firefox 3 Add-ons "
+"Manager interface."
+
+#: views/developers/versions_edit.thtml:182
+#, fuzzy
+msgid "devcp_versions_edit_transbox_releasenotes_name"
+msgstr "Release Notes"
+
+#: views/developers/versions_edit.thtml:164
+#, fuzzy
+msgid "devcp_versions_edit_unsaved_compat"
+msgstr ""
+"<strong>You have unsaved changes.</strong> Compatibility will not be deleted "
+"until you click Update Version below."
+
+#: views/developers/versions_edit.thtml:113
+#, fuzzy
+msgid "devcp_versions_edit_unsaved_files"
+msgstr ""
+"<strong>You have unsaved changes.</strong> Files will not be deleted until "
+"you click Update Version below."
+
+#: views/developers/versions_edit.thtml:218
+#, fuzzy
+msgid "devcp_versions_edit_update"
+msgstr "Update Versions"
+
+#: views/developers/versions.thtml:49
+#, fuzzy
+msgid "devcp_versions_header_manage"
+msgstr "Manage Versions and Files"
+
+#: views/developers/versions.thtml:87
+#, fuzzy
+msgid "devcp_versions_no_versions"
+msgstr "No versions."
+
+#. %s is a version number, base 10.
+#: views/developers/versions.thtml:46
+#, fuzzy
+msgid "devcp_versions_notice_success"
+msgstr "Version %s deleted successfully."
+
+#: views/developers/versions.thtml:73
+#, fuzzy
+msgid "devcp_versions_p_remove"
+msgstr ""
+"This version has no files associated with it and can be removed. Would you "
+"like to remove this version?"
+
+#: views/developers/versions.thtml:58
+#, fuzzy
+msgid "devcp_versions_th_created"
+msgstr "Created"
+
+#: views/developers/versions.thtml:57
+#, fuzzy
+msgid "devcp_versions_th_status"
+msgstr "Status"
+
+#: views/developers/versions.thtml:56
+#, fuzzy
+msgid "devcp_versions_th_version"
+msgstr "Version"
+
+#: controllers/downloads_controller.php:91
+msgid "downloads_disable_warning"
+msgstr "Ez a kiegészítő le van tiltva"
+
+#: controllers/components/editors.php:57
+msgid "editor_review_error_addon_not_nominated"
+msgstr "Ezt a kiegészítőt még nem jelölték."
+
+#: controllers/components/editors.php:213
+msgid "editor_review_error_file_not_pending"
+msgstr "Erre a fájlra nincs függőben értékelés."
+
+#. Actions are, for example: approving or rejecting
+#: controllers/components/editors.php:79
+#: controllers/components/editors.php:182
+msgid "editor_review_error_no_action"
+msgstr "Válasszon egy értékelési műveletet."
+
+#: controllers/components/editors.php:192
+msgid "editor_review_error_no_applications"
+msgstr "Adja meg a tesztelt alkalmazásokat."
+
+#. Comments are required when an editor approves or rejects an add-on.
+#: controllers/components/editors.php:84
+#: controllers/components/editors.php:187
+msgid "editor_review_error_no_comments"
+msgstr "Ãrja be az értékelÅ‘ megjegyzéseket."
+
+#: controllers/components/editors.php:161
+msgid "editor_review_error_no_files"
+msgstr "Válasszon legalább egy fájlt értékelésre."
+
+#: controllers/components/editors.php:197
+msgid "editor_review_error_no_operating_system"
+msgstr "Adja meg az operációs rendszert, amin tesztelt."
+
+#: views/editors/logs.thtml:51
+msgid "editorcp_logs_button_filter"
+msgstr "Szűrő"
+
+#: views/editors/logs.thtml:44
+msgid "editorcp_logs_filter_by"
+msgstr "Szűrés típus/művelet szerint"
+
+#: views/editors/logs.thtml:42 controllers/editors_controller.php:964
+msgid "editorcp_logs_page_heading"
+msgstr "Eseménynapló"
+
+#: views/elements/developers/editorsmenu.thtml:60
+msgid "editorcp_menu_eventlog_link"
+msgstr "Eseménynapló"
+
+#: views/elements/developers/editorsmenu.thtml:62
+msgid "editorcp_menu_mainpage_link"
+msgstr "Vissza a főoldalra"
+
+#: views/elements/developers/editorsmenu.thtml:61
+msgid "editorcp_menu_reviewlog_link"
+msgstr "Értékelési napló"
+
+#: views/elements/developers/editorsmenu.thtml:55
+msgid "editorcp_menu_summary_link"
+msgstr "Szerkesztő összefoglalója"
+
+#: views/elements/developers/editorsmenu.thtml:52
+msgid "editorcp_menu_title"
+msgstr "Szerkesztőeszközök"
+
+#: views/editors/reviewlog.thtml:49
+msgid "editorcp_reviewlog_button_filter"
+msgstr "Szűrő"
+
+#: views/editors/reviewlog.thtml:58
+msgid "editorcp_reviewlog_column_action"
+msgstr "Művelet"
+
+#: views/editors/reviewlog.thtml:56
+msgid "editorcp_reviewlog_column_addon"
+msgstr "Kiegészítő"
+
+#: views/editors/reviewlog.thtml:55
+msgid "editorcp_reviewlog_column_date"
+msgstr "Dátum"
+
+#: views/editors/reviewlog.thtml:57
+msgid "editorcp_reviewlog_column_editor"
+msgstr "Szerkesztő"
+
+#: views/editors/reviewlog.thtml:94
+msgid "editorcp_reviewlog_comments_hide"
+msgstr "Hozzászólások elrejtése"
+
+#: views/editors/reviewlog.thtml:93
+msgid "editorcp_reviewlog_comments_show"
+msgstr "Hozzászólások megjelenítése"
+
+#. %1$s and %2$s are full <input> tags for dates
+#: views/editors/reviewlog.thtml:45
+#, php-format
+msgid "editorcp_reviewlog_entries_between"
+msgstr "%s és %s közötti bejegyzések megtekintése"
+
+#: views/editors/reviewlog.thtml:104
+msgid "editorcp_reviewlog_none_found"
+msgstr "Nincsenek értékelések ebben az időszakban."
+
+#: views/editors/reviewlog.thtml:42
+msgid "editorcp_reviewlog_page_heading"
+msgstr "Értékelési napló"
+
+#: views/editors/summary.thtml:61
+msgid "editorcp_summary_monthreviews_heading"
+msgstr "Havi értékelések"
+
+#: views/editors/summary.thtml:77
+msgid "editorcp_summary_neweditors_heading"
+msgstr "Új szerkesztők"
+
+#: views/editors/summary.thtml:42
+msgid "editorcp_summary_page_heading"
+msgstr "Szerkesztő összefoglalója"
+
+#: views/editors/summary.thtml:94
+msgid "editorcp_summary_recentactivity_heading"
+msgstr "Szerkesztői tevékenység a közelmúltban"
+
+#: views/editors/summary.thtml:45
+msgid "editorcp_summary_totalreviews_heading"
+msgstr "Összes értékelés"
+
+#: controllers/editors_controller.php:248
+#: controllers/editors_controller.php:249
+msgid "editors_addon_review_pagetitle"
+msgstr "Kiegészítő értékelése"
+
+#: controllers/editors_controller.php:349
+msgid "editors_error_js-formerror"
+msgstr "Töltse ki a következő mezőket:"
+
+#: controllers/editors_controller.php:350
+msgid "editors_error_review_one_file"
+msgstr "Válasszon legalább egy fájlt az értékeléshez."
+
+#: controllers/editors_controller.php:274
+msgid "editors_error_self_reviews_forbidden"
+msgstr "Saját magát nem értékelheti."
+
+#: controllers/editors_controller.php:699
+msgid "editors_external_software"
+msgstr "Külső szoftver"
+
+#: views/editors/featured.thtml:120 views/editors/featured.thtml:121
+msgid "editors_featured_add_feature"
+msgstr "Kiemelés hozzáadása"
+
+#: views/editors/featured.thtml:126
+msgid "editors_featured_add_feature_submit"
+msgstr "Hozzáadás"
+
+#: views/editors/featured.thtml:49 controllers/editors_controller.php:832
+#: controllers/editors_controller.php:848
+msgid "editors_featured_addon_add_failure"
+msgstr "A kiemelés hozzáadása sikertelen."
+
+#: controllers/editors_controller.php:851
+msgid "editors_featured_addon_add_success"
+msgstr "A kiemelés hozzáadása sikeres."
+
+#: views/editors/featured.thtml:50 controllers/editors_controller.php:839
+#: controllers/editors_controller.php:868
+#: controllers/editors_controller.php:886
+msgid "editors_featured_addon_edit_failure"
+msgstr "A kiemelés szerkesztése sikertelen."
+
+#: views/editors/featured.thtml:51 controllers/editors_controller.php:888
+msgid "editors_featured_addon_edit_success"
+msgstr "A kiemelés szerkesztése sikeres."
+
+#: views/editors/featured.thtml:53 controllers/editors_controller.php:861
+msgid "editors_featured_addon_invalid_locale"
+msgstr "Egy vagy több területi beállítás érvénytelen."
+
+#: views/editors/featured.thtml:52 controllers/editors_controller.php:906
+msgid "editors_featured_addon_remove_failure"
+msgstr "A kiemelés eltávolítása sikertelen."
+
+#: controllers/editors_controller.php:901
+msgid "editors_featured_addon_remove_success"
+msgstr "A kiemelés eltávolítása sikeres."
+
+#: controllers/editors_controller.php:915
+#: controllers/editors_controller.php:917
+msgid "editors_featured_addons_pagetitle"
+msgstr "Kiemelt kiegészítők"
+
+#: views/editors/featured.thtml:54 views/editors/featured.thtml:107
+msgid "editors_featured_edit_feature_submit"
+msgstr "Ugrás"
+
+#: views/editors/featured.thtml:90 views/editors/featured.thtml:91
+msgid "editors_featured_remove_feature"
+msgstr "Kiemelés eltávolítása"
+
+#: views/editors/queue.thtml:46
+msgid "editors_filter_queue"
+msgstr "Szűrősor"
+
+#: views/editors/queue.thtml:182
+msgid "editors_helpful_links"
+msgstr "Hasznos hivatkozások"
+
+#: views/editors/queue.thtml:182
+msgid "editors_link_guide"
+msgstr "Útmutató szerkesztőknek"
+
+#: views/editors/queue.thtml:182
+msgid "editors_link_policy"
+msgstr "Irányelvek a kiegészítőkhöz"
+
+#: views/editors/queue.thtml:47
+msgid "editors_notice_filter_session"
+msgstr ""
+"Ezek a szűrők aktívak maradnak a munkamenet alatt, vagy amíg nem törli őket."
+
+# %1 is the queue mode
+#. %1 is the queue mode
+#: views/editors/queue.thtml:177 views/admin/flagged_queue.thtml:89
+msgid "editors_notice_none_found"
+msgstr "Jelenleg nincsenek értékelendő kiegészítők ebből a típusból."
+
+#: controllers/editors_controller.php:1040
+msgid "editors_one_day"
+msgstr "1 nap"
+
+#: controllers/editors_controller.php:1048
+msgid "editors_one_hour"
+msgstr "1 óra"
+
+#: controllers/editors_controller.php:1056
+msgid "editors_one_minute"
+msgstr "1 perc"
+
+#: controllers/editors_controller.php:64 controllers/editors_controller.php:73
+#: controllers/editors_controller.php:77
+msgid "editors_pagetitle"
+msgstr "Szerkesztőeszközök"
+
+#. %s is a comma separated list of platforms. Example: Windows, OS X
+#: controllers/editors_controller.php:680
+#: controllers/editors_controller.php:683
+#, php-format
+msgid "editors_platform_x_only"
+msgstr "csak %s"
+
+#: controllers/editors_controller.php:695
+msgid "editors_pre-release"
+msgstr "Előzetes kiadás"
+
+# %1 is the app name
+#. %1 is the app name
+#: views/editors/queue.thtml:131
+#, php-format
+msgid "editors_queue_app_compatibility"
+msgstr "%s kompatibilitás"
+
+#: views/editors/queue.thtml:51
+#, fuzzy
+msgid "editors_queue_filter_label_addon"
+msgstr "Add-on or Author Email"
+
+#: views/editors/queue.thtml:72
+#, fuzzy
+msgid "editors_queue_filter_label_addontypes"
+msgstr "Add-on Types"
+
+#: views/editors/queue.thtml:56
+#, fuzzy
+msgid "editors_queue_filter_label_application"
+msgstr "Application"
+
+#: views/editors/queue.thtml:61
+#, fuzzy
+msgid "editors_queue_filter_label_maxversion"
+msgstr "Max. Version"
+
+#: views/editors/queue.thtml:78
+#, fuzzy
+msgid "editors_queue_filter_label_platforms"
+msgstr "Platforms"
+
+#: views/editors/queue.thtml:66
+#, fuzzy
+msgid "editors_queue_filter_label_submissionage"
+msgstr "Age of Submission (days)"
+
+#. %1$s is a number
+#: views/editors/queue.thtml:90
+#, fuzzy
+msgid "editors_queue_filter_result_count"
+msgid_plural "editors_queue_filter_result_count"
+msgstr[0] "Results of your filtered search: <strong>%1$s</strong> Add-on"
+msgstr[1] "Results of your filtered search: <strong>%1$s</strong> Add-ons"
+
+#: views/editors/queue.thtml:84
+msgid "editors_queue_submit_clean"
+msgstr "Törlés"
+
+#: views/editors/queue.thtml:83
+msgid "editors_queue_submit_filter"
+msgstr "Szűrő"
+
+#: controllers/editors_controller.php:133
+msgid "editors_queues_disabled"
+msgstr "Jelenleg nem lehet értékelni. Jöjjön vissza később."
+
+#: views/editors/review.thtml:149
+#, fuzzy
+msgid "editors_review_a_edit_item"
+msgstr "Edit Item"
+
+#: views/editors/review.thtml:146
+#, fuzzy
+msgid "editors_review_a_item_history"
+msgstr "Item History"
+
+#: views/editors/review.thtml:148
+#, fuzzy
+msgid "editors_review_a_item_homepage"
+msgstr "Item Homepage"
+
+#: views/editors/review.thtml:145
+#, fuzzy
+msgid "editors_review_a_item_overview"
+msgstr "Item Overview"
+
+#: views/editors/review.thtml:147
+#, fuzzy
+msgid "editors_review_a_previews"
+msgstr "Previews"
+
+#: controllers/editors_controller.php:345
+msgid "editors_review_action"
+msgstr "Értékelési művelet"
+
+#: views/editors/review.thtml:159
+#, fuzzy
+msgid "editors_review_action_info"
+msgstr "Request More Information"
+
+#: views/editors/review.thtml:157
+msgid "editors_review_action_public"
+msgstr "Nyilvánossá tétel"
+
+#: views/editors/review.thtml:160
+msgid "editors_review_action_request_superreview"
+msgstr "Super-Review kérése"
+
+#: views/editors/review.thtml:158
+msgid "editors_review_action_sandbox"
+msgstr "Homokozóban tartás"
+
+#: controllers/editors_controller.php:346
+msgid "editors_review_comments"
+msgstr "Értékelési megjegyzések"
+
+#: views/editors/review.thtml:182
+#, fuzzy
+msgid "editors_review_details_info_request"
+msgstr ""
+"Use this form to request more information from the author. They will receive "
+"an email and be able to answer here. You will be notified by email when they "
+"reply."
+
+#: views/editors/review.thtml:174
+msgid "editors_review_details_nominated_public"
+msgstr ""
+"A kiegészítő legfrissebb verziójához tartozó fájlok publikussá válnak. A "
+"jövőbeli verziók a homokozóba kerülnek, amíg egy szerkesztő nem értékeli "
+"Å‘ket."
+
+#: views/editors/review.thtml:177
+msgid "editors_review_details_nominated_sandbox"
+msgstr "A kiegészítő a homokozóban marad."
+
+#: views/editors/review.thtml:166
+msgid "editors_review_details_pending_public"
+msgstr ""
+"Egy már nyilvános kiegészítő homokozóban levő verziója megjelenhet "
+"nyilvánosan."
+
+#: views/editors/review.thtml:169
+msgid "editors_review_details_pending_sandbox"
+msgstr ""
+"Egy már nyilvános kiegészítő homokozóban levő verziója a homokozóban marad."
+
+#: views/editors/review.thtml:185
+msgid "editors_review_details_superreview"
+msgstr ""
+"Ha kétségei vannak a kiegészítő biztonságát, szerzői jogi státuszát vagy "
+"egyebeket illetően, és szeretné, hogy egy adminisztrátor nézzen utána, írjon "
+"megjegyzést az alábbi területre. Ez az üzenet az adminisztrátorhoz kerül, "
+"nem a szerzőhöz."
+
+#: views/editors/review.thtml:134
+msgid "editors_review_file_diff_link"
+msgstr "Összehasonlítás a nyilvános verzióval"
+
+#: views/editors/review.thtml:131
+msgid "editors_review_file_viewcontents_link"
+msgstr "Tartalom megtekintése"
+
+#: views/editors/review.thtml:65
+msgid "editors_review_header_authors"
+msgstr "Szerzők:"
+
+#: views/editors/review.thtml:79
+msgid "editors_review_header_categories"
+msgstr "Kategóriák:"
+
+#: views/editors/review.thtml:92
+msgid "editors_review_header_compatibility"
+msgstr "Kompatibilitás:"
+
+#: views/editors/review.thtml:251
+msgid "editors_review_header_description"
+msgstr "Leírás"
+
+#: views/editors/review.thtml:275
+msgid "editors_review_header_devcomments"
+msgstr "Fejlesztői megjegyzések"
+
+#: views/editors/review.thtml:263
+msgid "editors_review_header_eula"
+msgstr "EULA"
+
+#: views/editors/review.thtml:115
+msgid "editors_review_header_files"
+msgstr "Fájlok:"
+
+#: views/editors/review.thtml:284
+msgid "editors_review_header_itemhistory"
+msgstr "Elem története"
+
+#: views/editors/review.thtml:232
+msgid "editors_review_header_nominationmessage"
+msgstr "Jelölési üzenet"
+
+#: views/editors/review.thtml:311
+msgid "editors_review_header_previews"
+msgstr "Előnézetek"
+
+#: views/editors/review.thtml:269
+msgid "editors_review_header_privacy"
+msgstr "Adatvédelmi nyilatkozat"
+
+# %1 is the addon name and version
+#. %1 is the add-on name and version
+#: views/editors/review.thtml:56
+#, php-format
+msgid "editors_review_header_review"
+msgstr "%s értékelése"
+
+#: views/editors/review.thtml:239
+msgid "editors_review_header_reviewernotes"
+msgstr "Megjegyzések az értékelőnek"
+
+#: views/editors/review.thtml:245
+msgid "editors_review_header_summary"
+msgstr "Összefoglaló"
+
+#: views/editors/review.thtml:257
+msgid "editors_review_header_versionnotes"
+msgstr "Megjegyzések a verzióhoz"
+
+#. a noun: shown in an add-on's editor review history
+#: views/elements/developers/editors_review_history_item.thtml:80
+#, fuzzy
+msgid "editors_review_history_info_reply"
+msgstr "Reply"
+
+#: views/elements/developers/editors_review_history_item.thtml:78
+#, fuzzy
+msgid "editors_review_history_info_request"
+msgstr "Information Request"
+
+#: views/elements/developers/editors_review_history_item.thtml:62
+#: views/editors/reviewlog.thtml:77
+msgid "editors_review_history_nominated_adminreview"
+msgstr "Értékelés adminisztrálása"
+
+#: views/elements/developers/editors_review_history_item.thtml:56
+#: views/editors/reviewlog.thtml:71
+msgid "editors_review_history_nominated_approved"
+msgstr "Jelölés jóváhagyva/Nyilvános"
+
+#: views/elements/developers/editors_review_history_item.thtml:59
+#: views/editors/reviewlog.thtml:74
+msgid "editors_review_history_nominated_denied"
+msgstr "Jelölés elutasítva/Homokozó"
+
+#: views/editors/review.thtml:303
+msgid "editors_review_history_nonefound"
+msgstr "Nincsenek korábbi értékelő bejegyzések."
+
+#: views/elements/developers/editors_review_history_item.thtml:73
+#: views/editors/reviewlog.thtml:88
+msgid "editors_review_history_pending_adminreview"
+msgstr "Értékelés adminisztrálása"
+
+#: views/elements/developers/editors_review_history_item.thtml:67
+#: views/editors/reviewlog.thtml:82
+msgid "editors_review_history_pending_approved"
+msgstr "Jóváhagyva/Nyilvános"
+
+#: views/elements/developers/editors_review_history_item.thtml:70
+#: views/editors/reviewlog.thtml:85
+msgid "editors_review_history_pending_denied"
+msgstr "Elutasítva/Homokozó"
+
+#. link text in an add-on's editor review history, allowing to hide and show an information request's replies
+#. %1 is the number of replies
+#: views/elements/developers/editors_review_history_item.thtml:90
+#, fuzzy
+msgid "editors_review_history_show_hide_replies"
+msgid_plural "editors_review_history_show_hide_replies"
+msgstr[0] "Show/Hide Replies (%1$s)"
+msgstr[1] "Show/Hide Replies (%1$s)"
+
+#: views/editors/review.thtml:208
+msgid "editors_review_label_applications"
+msgstr "Alkalmazások:"
+
+#: views/editors/review.thtml:196
+msgid "editors_review_label_cannedresponse"
+msgstr "vagy válasszon egy konzervválaszt:"
+
+#: views/editors/review.thtml:190
+msgid "editors_review_label_comments"
+msgstr "Megjegyzések:"
+
+#: views/editors/review.thtml:204
+msgid "editors_review_label_operating_systems"
+msgstr "Operációs rendszerek:"
+
+#: views/editors/review.thtml:285 views/editors/review.thtml:312
+msgid "editors_review_link_pagetop"
+msgstr "Fel"
+
+#: views/editors/review.thtml:141
+#, fuzzy
+msgid "editors_review_mulitple_notice"
+msgstr ""
+"Notice: Only review more than one file if you have tested EVERY file you "
+"select."
+
+#: views/editors/review.thtml:51
+msgid "editors_review_next_link"
+msgstr "következő &raquo;"
+
+#: views/editors/review.thtml:322
+msgid "editors_review_previews_notfound"
+msgstr "Nincs előnézet."
+
+#: views/editors/review.thtml:50
+msgid "editors_review_previous_link"
+msgstr "&laquo; előző"
+
+#: controllers/editors_controller.php:144
+#: controllers/editors_controller.php:146
+msgid "editors_review_queue_pagetitle"
+msgstr "Értékelési sor"
+
+# %1 is the add-ons rank in the queue, %2 is the total queue length
+#. %1 is the add-ons rank in the queue, %2 is the total queue length
+#: views/editors/review.thtml:47
+msgid "editors_review_rank_in_queue"
+msgstr "<strong># %1$s</strong> / %2$s a sorban"
+
+#. %1 is the add-ons rank in the queue, %2 is the total queue length. Both numbers
+#: views/editors/review.thtml:45
+#, fuzzy
+msgid "editors_review_rank_in_queue_filtered"
+msgstr "<strong># %1$s</strong> of %2$s in queue (filtered)"
+
+#: views/editors/review.thtml:223
+msgid "editors_review_submit_process_action"
+msgstr "Művelet feldolgozása"
+
+#: views/editors/review.thtml:293
+msgid "editors_review_th_action"
+msgstr "Művelet"
+
+#: views/editors/review.thtml:294
+msgid "editors_review_th_comments"
+msgstr "Megjegyzések"
+
+#: views/editors/review.thtml:291
+msgid "editors_review_th_date"
+msgstr "Dátum"
+
+#: views/editors/review.thtml:292
+msgid "editors_review_th_reviewer"
+msgstr "Értékelő"
+
+#: views/editors/review.thtml:290
+msgid "editors_review_th_version_file"
+msgstr "Verzió/Fájl"
+
+#: views/editors/review.thtml:217
+msgid "editors_review_update_notify_once"
+msgstr ""
+"Értesítés kérése a kiegészítő következő frissítésekor. (A további "
+"frissítésekről nem küld e-mailt a rendszer.)"
+
+#: controllers/editors_controller.php:298
+msgid "editors_reviewed_successfully"
+msgstr "Az értékelés sikeresen fel lett dolgozva."
+
+#: views/editors/reviews_queue.thtml:106
+msgid "editors_reviews_action_delete_review"
+msgstr "Értékelés törlése"
+
+#: views/editors/reviews_queue.thtml:104
+msgid "editors_reviews_action_keep"
+msgstr "Jelzők törlése, értékelés megtartása"
+
+#: views/editors/reviews_queue.thtml:102
+msgid "editors_reviews_action_skip"
+msgstr "Kihagyás"
+
+#: views/editors/reviews_queue.thtml:100
+msgid "editors_reviews_header_action"
+msgstr "Művelet"
+
+#: views/editors/reviews_queue.thtml:67
+msgid "editors_reviews_in_reply_to"
+msgstr "Válasz:"
+
+#: controllers/editors_controller.php:748
+msgid "editors_reviews_processed"
+msgstr "Az értékelések sikeresen fel lettek dolgozva!"
+
+#: views/editors/reviews_queue.thtml:117
+msgid "editors_reviews_queue_empty"
+msgstr "Jelenleg nincsenek moderálandó értékelések."
+
+#: views/editors/reviews_queue.thtml:111
+msgid "editors_reviews_submit_process_reviews"
+msgstr "Értékelések feldolgozása"
+
+#: controllers/editors_controller.php:691
+msgid "editors_site_specific"
+msgstr "Webhelyspecifikus"
+
+#: controllers/editors_controller.php:348
+msgid "editors_tested_app"
+msgstr "Tesztelt alkalmazás"
+
+#: controllers/editors_controller.php:347
+msgid "editors_tested_os"
+msgstr "Tesztelt operációs rendszer"
+
+#: views/editors/queue.thtml:151
+msgid "editors_th_additional_info"
+msgstr "További információk"
+
+#: views/editors/featured.thtml:63 views/editors/queue.thtml:109
+#: views/admin/flagged_queue.thtml:53
+msgid "editors_th_addon"
+msgstr "Kiegészítő"
+
+#: views/editors/queue.thtml:125
+msgid "editors_th_addontype"
+msgstr "Típus"
+
+#: views/editors/featured.thtml:64
+msgid "editors_th_locales"
+msgstr "Korlátozás adott területi beállításokra?"
+
+#: views/editors/queue.thtml:148
+#, fuzzy
+msgid "editors_th_nomination_age"
+msgstr "Time in Queue"
+
+#: views/editors/queue.thtml:101 views/editors/queue.thtml:117
+#: views/editors/queue.thtml:144
+#, fuzzy
+msgid "editors_th_sort_ascending"
+msgstr "Ascending sort"
+
+#: views/editors/queue.thtml:105 views/editors/queue.thtml:121
+#: views/editors/queue.thtml:140
+#, fuzzy
+msgid "editors_th_sort_descending"
+msgstr "Descending sort"
+
+#. %s is a number
+#: controllers/editors_controller.php:1036
+#, php-format
+msgid "editors_x_days"
+msgstr "%s nap"
+
+#. %s is a number
+#: controllers/editors_controller.php:1044
+#, php-format
+msgid "editors_x_hours"
+msgstr "%s óra"
+
+#. %s is a number
+#: controllers/editors_controller.php:1052
+#, php-format
+msgid "editors_x_minutes"
+msgstr "%s perc"
+
+#: views/errors/error401.thtml:50 controllers/components/simple_acl.php:81
+#: controllers/components/simple_acl.php:82
+#: controllers/components/simple_acl.php:83 controllers/components/amo.php:607
+#: controllers/components/amo.php:608 controllers/components/amo.php:609
+#: controllers/reviews_controller.php:353
+#: controllers/reviews_controller.php:485
+#: controllers/collections_controller.php:438
+#: controllers/collections_controller.php:496
+#: controllers/collections_controller.php:504
+#: controllers/collections_controller.php:971
+#: controllers/collections_controller.php:1034
+#: controllers/collections_controller.php:1077
+msgid "error_access_denied"
+msgstr "Hozzáférés megtagadva"
+
+#: views/errors/error401.thtml:52
+msgid "error_access_denied_message"
+msgstr "Nincs joga megtekinteni ezt az oldalt."
+
+#: controllers/collections_controller.php:1039
+#, fuzzy
+msgid "error_addon_exists"
+msgstr "Add-on already exists!"
+
+#: controllers/developers_controller.php:200
+#: controllers/developers_controller.php:593
+#: controllers/developers_controller.php:1016
+#: controllers/developers_controller.php:1429
+#: controllers/downloads_controller.php:95
+#: controllers/downloads_controller.php:102
+#: controllers/downloads_controller.php:164
+#: controllers/statistics_controller.php:135
+#: controllers/previews_controller.php:115
+#: controllers/previews_controller.php:206
+#: controllers/previews_controller.php:307
+#: controllers/reviews_controller.php:77
+#: controllers/reviews_controller.php:240
+#: controllers/reviews_controller.php:332
+#: controllers/reviews_controller.php:340 controllers/api_controller.php:123
+#: controllers/api_controller.php:759 controllers/addons_controller.php:131
+#: controllers/addons_controller.php:197
+#: controllers/addons_controller.php:1407
+#: controllers/addons_controller.php:1465
+#: controllers/addons_controller.php:1469
+#: controllers/addons_controller.php:1503
+#: controllers/editors_controller.php:265
+#: controllers/collections_controller.php:1041
+#: controllers/collections_controller.php:1074
+msgid "error_addon_notfound"
+msgstr "A kiegészítő nem található!"
+
+#: controllers/files_controller.php:83 controllers/files_controller.php:196
+msgid "error_addon_notviewable"
+msgstr "Ez a kiegészítő nem megtekinthető innen."
+
+#: controllers/reviews_controller.php:246
+msgid "error_addon_selfreview"
+msgstr "A saját kiegészítő nem értékelhető."
+
+#: controllers/addons_controller.php:970
+msgid "error_browse_no_addons"
+msgstr "Nincsenek kiegészítők ebben a kategóriában!"
+
+#: controllers/api_controller.php:424
+msgid "error_collection_feed_notfound"
+msgstr "A kiegészítő hírforrása nem található."
+
+#: views/users/register.thtml:65 views/users/edit.thtml:194
+msgid "error_email_invalid"
+msgstr "Ez nem érvényes e-mail cím."
+
+#: views/users/pwreset.thtml:74 views/users/register.thtml:70
+#: views/users/register.thtml:80 views/users/register.thtml:86
+#: views/users/edit.thtml:105 views/users/edit.thtml:111
+#: views/users/edit.thtml:192 views/admin/users_edit.thtml:78
+#: views/admin/users_edit.thtml:83 views/reviews/add.thtml:80
+#: views/reviews/add.thtml:104
+msgid "error_field_required"
+msgstr "Ez a mező nem maradhat üresen."
+
+#: controllers/files_controller.php:75 controllers/files_controller.php:93
+#: controllers/files_controller.php:96 controllers/files_controller.php:163
+#: controllers/files_controller.php:176 controllers/files_controller.php:185
+#: controllers/files_controller.php:204 controllers/editors_controller.php:412
+msgid "error_file_notfound"
+msgstr "A fájl nem található!"
+
+#. %s is a filename
+#: controllers/editors_controller.php:430
+#, php-format
+msgid "error_file_x_notfound"
+msgstr "Fájlhiba: %s nem létezik."
+
+#: views/collections/add.thtml:55 views/collections/edit.thtml:89
+#: views/users/register.thtml:54 views/users/edit.thtml:81
+#: views/reviews/add.thtml:70 controllers/groups_controller.php:80
+#: controllers/groups_controller.php:102
+msgid "error_formerrors"
+msgstr "Hibák vannak az űrlapon. Javítsa ki őket, és küldje újra."
+
+#: views/users/register.thtml:109
+msgid "error_invalid_captcha"
+msgstr "Érvénytelen captcha, próbálja újra!"
+
+#: views/users/register.thtml:100 views/users/edit.thtml:125
+#: views/admin/users_edit.thtml:101
+msgid "error_invalid_url"
+msgstr ""
+"Ez az URL érvénytelen formátumban van. Az érvényes URL-ek formátuma ehhez "
+"hasonló: http://példa.hu/saját_oldal."
+
+#. %s is a string representing what's missing. Example: file_id
+#: controllers/downloads_controller.php:65
+#: controllers/users_controller.php:185 controllers/users_controller.php:264
+#: controllers/users_controller.php:559 controllers/users_controller.php:653
+#: controllers/reviews_controller.php:71
+#: controllers/reviews_controller.php:234
+#: controllers/reviews_controller.php:325
+#: controllers/reviews_controller.php:473
+#: controllers/reviews_controller.php:475
+#: controllers/addons_controller.php:182
+#: controllers/addons_controller.php:1381
+#: controllers/addons_controller.php:1455
+#: controllers/collections_controller.php:266
+#: controllers/collections_controller.php:285
+#: controllers/collections_controller.php:346
+#: controllers/collections_controller.php:443
+#: controllers/collections_controller.php:482
+#: controllers/collections_controller.php:936
+#: controllers/collections_controller.php:959
+#: controllers/collections_controller.php:960
+#: controllers/collections_controller.php:975
+#: controllers/collections_controller.php:977
+#: controllers/collections_controller.php:994
+#: controllers/collections_controller.php:1003
+#: controllers/collections_controller.php:1016
+#: controllers/collections_controller.php:1017
+#: controllers/collections_controller.php:1024
+#: controllers/collections_controller.php:1070
+#: controllers/collections_controller.php:1090
+#, php-format
+msgid "error_missing_argument"
+msgstr "Hiányzó argumentum: %s"
+
+#: controllers/components/amo.php:507 controllers/components/amo.php:532
+msgid "error_no_files_in_addon"
+msgstr "Nincsenek fájlok"
+
+#: controllers/previews_controller.php:200
+msgid "error_preview_notfound"
+msgstr "Nincs előnézet!"
+
+#: views/addons/display.thtml:400 views/reviews/add.thtml:98
+msgid "error_review_rating_required"
+msgstr "Kötelező osztályzatot választani."
+
+#: controllers/users_controller.php:160
+msgid "error_user_already_confirmed"
+msgstr "Ezt a felhasználói fiókot már jóváhagyták."
+
+#: controllers/users_controller.php:202 controllers/users_controller.php:276
+#: controllers/users_controller.php:569 controllers/users_controller.php:581
+#: controllers/users_controller.php:587 controllers/users_controller.php:610
+#: controllers/users_controller.php:627
+msgid "error_user_badconfirmationcode"
+msgstr "Érvénytelen megerősítő kód!"
+
+#: views/users/pwreset.thtml:79 views/users/register.thtml:75
+#: views/users/edit.thtml:183
+msgid "error_user_confirmpw_nomatch"
+msgstr "A jelszavak nem egyeznek."
+
+#: views/users/register.thtml:65 views/users/edit.thtml:190
+#: controllers/users_controller.php:617
+msgid "error_user_email_notunique"
+msgstr "Ezt az e-mail címet már egy másik felhasználó használja."
+
+#: controllers/users_controller.php:596
+msgid "error_user_emailchange_expired"
+msgstr ""
+"A e-mail váltás lejárt. Változtassa meg ismét az e-mail címét a felhasználói "
+"profiljában, és kattintson a megerősítő e-mailben levő hivatkozásra a "
+"megérkezése után azonnal."
+
+#: controllers/collections_controller.php:985
+#, fuzzy
+msgid "error_user_exists"
+msgstr ""
+"Users can only have one role at a time. Please remove the user from any "
+"existing roles before continuing."
+
+#: views/users/register.thtml:91 views/users/edit.thtml:116
+#: views/admin/users_edit.thtml:88
+msgid "error_user_nickname_notunique"
+msgstr "Ezt a felhasználónevet már más használja."
+
+#: views/users/pwreset.thtml:54 controllers/users_controller.php:191
+#: controllers/users_controller.php:270 controllers/users_controller.php:603
+#: controllers/users_controller.php:659
+#: controllers/collections_controller.php:988
+#: controllers/collections_controller.php:998
+msgid "error_user_notfound"
+msgstr "A felhasználó nem található!"
+
+#: views/users/activatefirst.thtml:47
+msgid "error_user_unconfirmed"
+msgstr ""
+"Először igazolja vissza a felhasználói fiókját az e-mailben kapott kód "
+"segítségével."
+
+#: views/users/login.thtml:67
+msgid "error_username_or_pw_wrong"
+msgstr "Rossz felhasználónév vagy jelszó"
+
+#: controllers/editors_controller.php:260
+msgid "error_version_notfound"
+msgstr "A verzió nem található!"
+
+#: views/users/delete.thtml:125 views/users/edit.thtml:173
+msgid "error_wrong_password"
+msgstr "Rossz jelszót írt be!"
+
+#: views/elements/amo2009/homepage_addon.thtml:122
+#: views/elements/feature.thtml:122
+msgid "feature_learnmore"
+msgstr "Több infó"
+
+# %1 is the add-on name
+#. %1 is the add-on name
+#: views/elements/amo2009/homepage_addon.thtml:123
+#: views/elements/feature.thtml:123
+#, php-format
+msgid "feature_learnmore_about_addon"
+msgstr "%1$s - további tudnivalók"
+
+#. %1$s is a number
+#: views/elements/amo2009/reviews.thtml:52
+#: views/elements/addon_listitem.thtml:112 views/elements/feature.thtml:99
+#: views/addons/browse_thumbs.thtml:86
+#, php-format
+msgid "feature_reviews"
+msgid_plural "feature_reviews"
+msgstr[0] "%1$s értékelés"
+msgstr[1] "%1$s értékelés"
+
+#: views/elements/amo2009/homepage_addon.thtml:127
+#: views/elements/feature.thtml:127
+msgid "feature_view_more_from_category"
+msgstr "Még több"
+
+#. This appears on a page that views the source of an add-on. This link will return
+#. the user to the add-on's main page
+#: views/files/browse.thtml:65
+msgid "file_browser_link_addon"
+msgstr "Vissza a kiegészítőhöz"
+
+#. There is a list of directories and files on the page. Clicking this will show the
+#. contents of all the directories (normally you would click on each one to see the
+#. contents)
+#: views/files/browse.thtml:67
+msgid "file_browser_link_expand_all"
+msgstr "Kibontás"
+
+#. This appears on a page that views the source of an add-on. This link will return
+#. the user to the add-on's review page (it only appears if the add-on is being
+#. reviewed)
+#: views/files/browse.thtml:64
+msgid "file_browser_link_review"
+msgstr "Vissza az értékeléshez"
+
+#. The title of the page for viewing an add-on's source.
+#. %1$s is the name of the add-on
+#. %2$s is the name of the current application (e.g. Firefox or Thunderbird)
+#: views/files/browse.thtml:46
+msgid "file_browser_title"
+msgstr "%1$s :: Fájlböngésző :: %2$s-kiegészítők"
+
+#. This appears on a page that views the source of an add-on. There is a list of
+#. directories and files on the page. Clicking this link will toggle between an
+#. expanded or a collapsed list. This string should be kept short.
+#: views/files/browse.thtml:68
+msgid "file_browser_toggle_expand_collapse"
+msgstr "+/-"
+
+#. Link text for the AMO About page.
+#: views/elements/footer.thtml:72 views/layouts/amo2009.thtml:341
+#, fuzzy
+msgid "footer_a_about"
+msgstr "About"
+
+#. Link text to the AMO blog.
+#: views/elements/footer.thtml:74 views/layouts/amo2009.thtml:343
+#, fuzzy
+msgid "footer_a_blog"
+msgstr "Blog"
+
+#. Link text to the Frequently Asked Questions page.
+#: views/elements/footer.thtml:73 views/layouts/amo2009.thtml:342
+#, fuzzy
+msgid "footer_a_faq"
+msgstr "FAQ"
+
+#. Full text for the FAQ abbreviation.
+#: views/elements/footer.thtml:73 views/pages/collector_features.thtml:72
+#: views/layouts/amo2009.thtml:342
+#, fuzzy
+msgid "footer_abbr_faq"
+msgstr "Frequently Asked Questions"
+
+#: views/elements/footer.thtml:67 views/layouts/amo2009.thtml:336
+msgid "footer_all_rights_reserved"
+msgstr "Minden jog fenntartva."
+
+#: views/elements/footer.thtml:67 views/layouts/amo2009.thtml:336
+msgid "footer_copyright"
+msgstr "Copyright"
+
+#: views/elements/footer.thtml:71 views/layouts/amo2009.thtml:340
+msgid "footer_credits"
+msgstr "Stáblista"
+
+#: views/elements/footer.thtml:76 views/layouts/amo2009.thtml:346
+msgid "footer_disclaimer"
+msgstr ""
+"A Mozilla szívességből hivatkozásokat ad ezekre az alkalmazásokra, de nem "
+"felel ezeket az alkalmazásokért és az azokkal kapcsolatos információkért. Az "
+"alkalmazásokkal kapcsolatos minden kérdést, panaszt vagy követelést a "
+"megfelelő szoftvergyártó felé kell irányítani."
+
+#: views/elements/footer.thtml:61 views/layouts/amo2009.thtml:332
+msgid "footer_lang_form_lang_submit_go"
+msgstr "Ugrás"
+
+#: views/elements/footer.thtml:70 views/layouts/amo2009.thtml:339
+msgid "footer_legal_notices"
+msgstr "Jogi megjegyzések"
+
+#: views/elements/footer.thtml:50 views/layouts/amo2009.thtml:321
+msgid "footer_other_languages"
+msgstr "Más nyelvek:"
+
+#: views/elements/footer.thtml:69 views/layouts/amo2009.thtml:338
+msgid "footer_privacy_policy"
+msgstr "Adatvédelmi nyilatkozat"
+
+#: models/addontype.php:79
+msgid "general_addontype_dict"
+msgstr "Szótár"
+
+# Plural in this context means many of the add-on type
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:100
+msgid "general_addontype_dict_plural"
+msgstr "Szótárak"
+
+#: models/addontype.php:75
+msgid "general_addontype_extension"
+msgstr "Kiterjesztés"
+
+# Plural in this context means many of the add-on type
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:98
+msgid "general_addontype_extension_plural"
+msgstr "Kiterjesztések"
+
+#: models/addontype.php:85
+msgid "general_addontype_lpaddon"
+msgstr "Nyelvi csomag (kiegészítő)"
+
+# Plural in this context means many of the add-on type
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:103
+msgid "general_addontype_lpaddon_plural"
+msgstr "Nyelvi csomagok (kiegészítő)"
+
+#: models/addontype.php:83
+msgid "general_addontype_lpapp"
+msgstr "Nyelvi csomag (alkalmazás)"
+
+# Plural in this context means many of the add-on type
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:102
+msgid "general_addontype_lpapp_plural"
+msgstr "Nyelvi csomagok (alkalmazás)"
+
+#: models/addontype.php:87
+msgid "general_addontype_plugin"
+msgstr "Bővítmény"
+
+# Plural in this context means many of the add-on type
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:104
+msgid "general_addontype_plugin_plural"
+msgstr "Bővítmények"
+
+#: models/addontype.php:81
+msgid "general_addontype_search"
+msgstr "Kereső"
+
+# Plural in this context means many of the add-on type
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:101
+msgid "general_addontype_search_plural"
+msgstr "Keresők"
+
+#: models/addontype.php:77
+msgid "general_addontype_theme"
+msgstr "Téma"
+
+# Plural in this context means many of the add-on type
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:99
+msgid "general_addontype_theme_plural"
+msgstr "Témák"
+
+#: config/language.php:367
+#, fuzzy
+msgid "general_languages_all_locales"
+msgstr "All Locales"
+
+#: views/layouts/amo2009.thtml:249
+#, fuzzy
+msgid "header_brand_name"
+msgstr "Mozilla"
+
+#. %1$s is the application name. Example: Firefox
+#: views/elements/header.thtml:111 views/elements/header.thtml:122
+#: views/layouts/amo2009.thtml:248
+#, php-format
+msgid "header_home_tooltip"
+msgstr "Visszatérés a %1$s-kiegészítők honlapjára"
+
+#: views/elements/header.thtml:87
+msgid "header_main_firefox_header"
+msgstr "Firefox-kiegészítők"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:218
+#, fuzzy
+msgid "header_main_firefox_header_with_logo"
+msgstr ""
+"Add-ons <em>for</em> <img alt=\"Firefox\" src=\"%1$s\" /> <strong>Firefox</"
+"strong>"
+
+#: views/elements/header.thtml:99
+msgid "header_main_header"
+msgstr "Kiegészítők"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:242
+#, fuzzy
+msgid "header_main_header_with_logo"
+msgstr "Add-ons <img alt=\"Add-ons\" src=\"%1$s\" />"
+
+#: views/elements/header.thtml:90
+msgid "header_main_seamonkey_header"
+msgstr "Seamonkey-kiegészítők"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:224
+#, fuzzy
+msgid "header_main_seamonkey_header_with_logo"
+msgstr ""
+"Add-ons <em>for</em> <img alt=\"seamonkey\" src=\"%1$s\" /> "
+"<strong>SeaMonkey</strong>"
+
+#: views/elements/header.thtml:93
+msgid "header_main_sunbird_header"
+msgstr "Sunbird-kiegészítők"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:230
+#, fuzzy
+msgid "header_main_sunbird_header_with_logo"
+msgstr ""
+"Add-ons <em>for</em> <img alt=\"sunbird\" src=\"%1$s\" /> <strong>Sunbird</"
+"strong>"
+
+#: views/elements/header.thtml:96
+msgid "header_main_thunderbird_header"
+msgstr "Thunderbird-kiegészítők"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:236
+#, fuzzy
+msgid "header_main_thunderbird_header_with_logo"
+msgstr ""
+"Add-ons <em>for</em> <img alt=\"thunderbird\" src=\"%1$s\" /> "
+"<strong>Thunderbird</strong>"
+
+#: views/layouts/amo2009.thtml:205
+#, fuzzy
+msgid "header_navaccess_applications_menu"
+msgstr "Skip to other applications menu"
+
+#: views/layouts/amo2009.thtml:204
+#, fuzzy
+msgid "header_navaccess_categories_menu"
+msgstr "Skip to categories menu"
+
+#: views/layouts/amo2009.thtml:202
+#, fuzzy
+msgid "header_navaccess_main_content"
+msgstr "Skip to main content"
+
+#: views/layouts/amo2009.thtml:203
+#, fuzzy
+msgid "header_navaccess_search_form"
+msgstr "Skip to search form"
+
+#: views/elements/header.thtml:62
+msgid "header_navlink_addons"
+msgstr "Kiegészítők"
+
+#: views/elements/developers/sidebar.thtml:72
+#: views/elements/developers/myaddons.thtml:50 views/elements/header.thtml:159
+#: views/addons/display.thtml:378
+msgid "header_navlink_login"
+msgstr "Bejelentkezés"
+
+#: views/elements/header.thtml:156 views/layouts/amo2009.thtml:304
+msgid "header_navlink_logout"
+msgstr "Kijelentkezés"
+
+#: views/elements/header.thtml:145 views/layouts/amo2009.thtml:303
+msgid "header_navlink_myaccount"
+msgstr "Saját fiók"
+
+#: views/elements/header.thtml:158
+msgid "header_navlink_register"
+msgstr "Regisztrálás"
+
+#. %1 is the URL to the registration page
+#. %2 is the URL to the login page
+#: views/layouts/amo2009.thtml:278
+#, fuzzy
+msgid "header_navlink_register_or_login"
+msgstr "<a href=\"%1$s\">Register</a> or <a href=\"%2$s\">Log in</a>"
+
+#: views/layouts/amo2009.thtml:285
+#, fuzzy
+msgid "header_navlink_tools"
+msgstr "Tools"
+
+#. %s is the add-on name
+#: views/elements/collections_interactive_addon.thtml:62
+#: views/elements/amo2009/homepage_addon.thtml:77
+#: views/elements/addon_discussionheader.thtml:62
+#: views/elements/addon_listitem.thtml:67 views/elements/feature.thtml:84
+#: views/addons/category_landing.thtml:87 views/addons/browse_thumbs.thtml:60
+#, php-format
+msgid "img_preview_of"
+msgstr "%s előnézeti képe"
+
+# %1 is the login URL for the link tag
+# %2 is the link to an explanatory page.
+#. %1 is the login URL for the link tag
+#. %2 is the link to an explanatory page.
+#: views/elements/amo2009/install.thtml:307 views/elements/install.thtml:255
+msgid "install_a_login_to_install"
+msgstr ""
+"<a href=\"%1$s\">Jelentkezzen be</a> a kísérleti kiterjesztés telepítéséhez. "
+"<a href=\"%2$s\">Miért</a>?"
+
+#. %1 is the URL for the Experimental Add-ons section of the FAQ page
+#: views/elements/amo2009/install.thtml:283 views/elements/install.thtml:232
+#, fuzzy
+msgid "install_button_confirm_exp_install"
+msgstr ""
+"Let me install this experimental add-on. <a href=\"%1$s\">What's this?</a>"
+
+#. %1$s is the application name. Example: Firefox
+#. %2$s is an optional string used to specify a platform. Example: (Windows)
+#: views/elements/amo2009/install.thtml:128 views/elements/install.thtml:75
+#, php-format
+msgid "install_button_text"
+msgstr "Hozzáadás: %s %s"
+
+# %1 is the add-on name, %2 is the app name
+#. %1 is the add-on name, %2 is the app name
+#: views/elements/amo2009/install.thtml:191
+#: views/elements/amo2009/install.thtml:206
+#: views/elements/amo2009/install.thtml:249
+#: views/elements/amo2009/install.thtml:298 views/elements/install.thtml:150
+#: views/elements/install.thtml:165 views/elements/install.thtml:202
+#: views/elements/install.thtml:246
+#, php-format
+msgid "install_button_title"
+msgstr "%1$s hozzáadása: %2$s"
+
+#. %1$s is the add-on name
+#: views/elements/amo2009/install.thtml:200 views/elements/install.thtml:159
+#, php-format
+msgid "install_download"
+msgstr "%1$s letöltése"
+
+#: views/elements/amo2009/install.thtml:147 views/elements/install.thtml:94
+msgid "install_error_addon_not_found"
+msgstr "Ez a kiegészítő nem érhető el."
+
+#: views/addons/dictionaries.thtml:65
+msgid "langtools_a11y_tablesummary"
+msgstr "Nyelvi csomagok és szótárak listája"
+
+#: views/addons/dictionaries.thtml:47
+msgid "langtools_download_dictionary"
+msgstr "Szótár letöltése"
+
+#: views/addons/dictionaries.thtml:48
+msgid "langtools_download_langpack"
+msgstr "Nyelvi csomag letöltése"
+
+#: views/addons/dictionaries.thtml:63 controllers/components/amo.php:685
+#: controllers/addons_controller.php:1239
+msgid "langtools_header_dicts_and_langpacks"
+msgstr "Szótárak és nyelvi csomagok"
+
+#: views/addons/dictionaries.thtml:44
+msgid "langtools_install_dictionary"
+msgstr "Szótár telepítése"
+
+#: views/addons/dictionaries.thtml:45
+msgid "langtools_install_langpack"
+msgstr "Nyelvi csomag telepítése"
+
+#: views/addons/dictionaries.thtml:69
+msgid "langtools_tableheader_dictionary"
+msgstr "Szótár"
+
+#: views/addons/dictionaries.thtml:70
+msgid "langtools_tableheader_langpack"
+msgstr "Nyelvi csomag"
+
+#: views/addons/dictionaries.thtml:68
+msgid "langtools_tableheader_language"
+msgstr "Nyelv"
+
+#: models/license.php:65
+#, fuzzy
+msgid "license_custom"
+msgstr "Custom License"
+
+#: config/bootstrap.php:303
+#, fuzzy
+msgid "licenses_bsd"
+msgstr "BSD License"
+
+#: config/bootstrap.php:298
+#, fuzzy
+msgid "licenses_gpl_2.0"
+msgstr "GNU General Public License, version 2.0"
+
+#: config/bootstrap.php:299
+#, fuzzy
+msgid "licenses_gpl_3.0"
+msgstr "GNU General Public License, version 3.0"
+
+#: config/bootstrap.php:300
+#, fuzzy
+msgid "licenses_lgpl_2.1"
+msgstr "GNU Lesser General Public License, version 2.1"
+
+#: config/bootstrap.php:301
+#, fuzzy
+msgid "licenses_lgpl_3.0"
+msgstr "GNU Lesser General Public License, version 3.0"
+
+#: config/bootstrap.php:302
+#, fuzzy
+msgid "licenses_mit"
+msgstr "MIT/X11 License"
+
+#: config/bootstrap.php:297
+#, fuzzy
+msgid "licenses_mpl_1.1"
+msgstr "Mozilla Public License, version 1.1"
+
+#: views/users/emailchange.thtml:51 views/users/delete.thtml:55
+#: views/users/delete.thtml:137 views/users/edit.thtml:74
+#: views/reviews/flag.thtml:54
+msgid "link_return_to_front_page"
+msgstr "Kattintson ide a főoldalra való visszatéréshez."
+
+#: views/elements/amo2009/addon_list_options.thtml:46
+#: views/elements/addon_list_options.thtml:46
+msgid "list_sortby_date"
+msgstr "Dátum"
+
+#: views/elements/amo2009/addon_list_options.thtml:47
+#: views/elements/addon_list_options.thtml:47
+msgid "list_sortby_downloads"
+msgstr "Letöltések"
+
+#: views/elements/amo2009/addon_list_options.thtml:45
+#: views/elements/addon_list_options.thtml:45
+msgid "list_sortby_name"
+msgstr "Kiegészítő neve"
+
+#: views/elements/amo2009/addon_list_options.thtml:48
+#: views/elements/addon_list_options.thtml:48
+msgid "list_sortby_rating"
+msgstr "Osztályzat"
+
+#: config/bootstrap.php:278
+msgid "main_prettyname_fennec"
+msgstr "Fennec"
+
+#: config/bootstrap.php:274
+msgid "main_prettyname_firefox"
+msgstr "Firefox"
+
+#: config/bootstrap.php:277
+msgid "main_prettyname_seamonkey"
+msgstr "SeaMonkey"
+
+#: config/bootstrap.php:276
+msgid "main_prettyname_sunbird"
+msgstr "Sunbird"
+
+#: config/bootstrap.php:275
+msgid "main_prettyname_thunderbird"
+msgstr "Thunderbird"
+
+#: views/elements/addon_categories.thtml:52
+msgid "nav_category_dicts_langpacks"
+msgstr "Szótárak és nyelvi csomagok"
+
+#: views/elements/addon_categories.thtml:55
+msgid "nav_category_themes"
+msgstr "Témák"
+
+#: views/elements/app_chooser.thtml:47 views/layouts/amo2009.thtml:255
+msgid "other_apps_tooltip"
+msgstr "Kiegészítők keresése más alkalmazásokhoz"
+
+# In a user list: user 1, user 2, "others"
+#. In a user list: user 1, user 2, "others"
+#: views/helpers/addons_html.php:222
+msgid "other_users"
+msgstr "mások"
+
+#: controllers/pages_controller.php:90
+msgid "page_title_appversions"
+msgstr "Alkalmazásverziók"
+
+#: controllers/pages_controller.php:115
+#, fuzzy
+msgid "page_title_collector"
+msgstr "Add-on Collector"
+
+#: controllers/pages_controller.php:117
+#, fuzzy
+msgid "page_title_collector_faq"
+msgstr "Add-on Collector FAQ"
+
+#: controllers/pages_controller.php:119
+#, fuzzy
+msgid "page_title_collector_features"
+msgstr "Add-on Collector Features"
+
+#: controllers/pages_controller.php:122
+#, fuzzy
+msgid "page_title_collector_firstrun"
+msgstr "Welcome to the Add-on Collector"
+
+#: controllers/pages_controller.php:92
+msgid "page_title_credits"
+msgstr "Stáblista"
+
+#: controllers/pages_controller.php:113
+#, fuzzy
+msgid "page_title_developer_faq"
+msgstr "Developer FAQ"
+
+#: controllers/pages_controller.php:111
+msgid "page_title_faq"
+msgstr "Gyakran ismétlődő kérdések"
+
+#: controllers/pages_controller.php:94
+msgid "page_title_fashionyourfirefox_faq"
+msgstr "Firefox testreszabása GYIK"
+
+#: controllers/pages_controller.php:101
+msgid "page_title_policy"
+msgstr "Irányelvek a kiegészítőkhöz"
+
+#: controllers/pages_controller.php:103
+msgid "page_title_privacy"
+msgstr "A Mozilla adatvédelmi nyilatkozata"
+
+#: controllers/pages_controller.php:105
+msgid "page_title_review_guide"
+msgstr "Értékelési útmutató"
+
+#: controllers/pages_controller.php:107
+msgid "page_title_sandbox"
+msgstr "A homokozó értékelési rendszere"
+
+#: controllers/pages_controller.php:109
+msgid "page_title_submissionhelp"
+msgstr "Segítség a beküldéshez"
+
+#: views/pages/appversions.thtml:87
+msgid "pages_appversions_guid"
+msgstr "GUID"
+
+#: views/pages/appversions.thtml:79 controllers/pages_controller.php:90
+msgid "pages_appversions_header"
+msgstr "Érvényes alkalmazásverziók"
+
+#: views/pages/appversions.thtml:80
+msgid "pages_appversions_intro"
+msgstr ""
+"A Mozilla Add-ons webhelyre beküldött kiegészítőknek rendelkezniük kell "
+"install.rdf fájllal, amelyben fel kell tüntetni támogatottként legalább "
+"egyet az alábbi alkalmazások közül. Ezekhez az alkalmazásokhoz csak az "
+"alábbi verziók engedélyezettek."
+
+#. %s is a full <a> tag
+#: views/pages/appversions.thtml:93
+#, php-format
+msgid "pages_appversions_required_files"
+msgstr ""
+"Ha a támogatott alkalmazás nem igényli az install.rdf fájlt, akkor is "
+"mellékelni kell egyet az %s meghatározott tartalommal."
+
+#. this is the text inside of an <a> tag for pages_appversions_required_files. This
+#. should be fixed.
+#: views/pages/appversions.thtml:93
+msgid "pages_appversions_required_files_link"
+msgstr "itt"
+
+#: views/pages/appversions.thtml:88
+msgid "pages_appversions_versions"
+msgstr "Verziók"
+
+#: views/pages/policy.thtml:51
+msgid "pages_policy_sandbox_link"
+msgstr "Homokozó információs oldala"
+
+#: views/elements/pagination.thtml:53
+msgid "pagination_next_page"
+msgstr "következő"
+
+#: views/elements/pagination.thtml:52
+msgid "pagination_previous_page"
+msgstr "előző"
+
+#: views/elements/recaptcha.thtml:65
+msgid "recaptcha_enter_both_words"
+msgstr ""
+"Ãrja be <strong>mindkét szót</strong>, <strong>szóközzel elválasztva</"
+"strong>."
+
+#: views/elements/recaptcha.thtml:83
+msgid "recaptcha_enter_here"
+msgstr "Ãrja be itt a választ:"
+
+#: views/elements/recaptcha.thtml:74
+msgid "recaptcha_enter_whatyouhear"
+msgstr "Ãrja be, amit hall."
+
+# %1 is the link switching refreshing the captcha
+# %2 is the link switching to a text captcha
+#. %1 is the link switching refreshing the captcha
+#. %2 is the link switching to a text captcha
+#: views/elements/recaptcha.thtml:77
+msgid "recaptcha_hardtohear_text"
+msgstr ""
+"Ha ezt nehéz megérteni, akkor <a href=\"%1$s\">meghallgathat mást is</a>, "
+"vagy <a href=\"%2$s\">visszaválthat szövegre</a>."
+
+# %1 is the link switching refreshing the captcha
+# %2 is the link switching to an audio captcha
+#. %1 is the link switching refreshing the captcha
+#. %2 is the link switching to an audio captcha
+#: views/elements/recaptcha.thtml:68
+msgid "recaptcha_hardtoread_text"
+msgstr ""
+"Ha ezt nehéz elolvasni, akkor <a href=\"%1$s\">próbálkozhat más szavakkal</"
+"a>, vagy inkább <a href=\"%2$s\">meghallgathat valamit</a>."
+
+#: views/users/register.thtml:105
+msgid "recaptcha_label"
+msgstr "Ön ember?"
+
+#: views/users/register.thtml:106
+msgid "recaptcha_whatsthis"
+msgstr "Mi ez?"
+
+#: controllers/reviews_controller.php:559
+msgid "review_flag_error"
+msgstr "Hiba az értékelés megjelölésénél!"
+
+#: models/reviews_moderation_flag.php:69
+msgid "review_flag_reason_bug_support"
+msgstr "Rossz helyre küldött hibajelentés vagy támogatási kérés"
+
+#: views/reviews/display.thtml:103 views/reviews/display.thtml:186
+msgid "review_flag_reason_instructions"
+msgstr "Értékelés feljelentése (válasszon okot)"
+
+#: models/reviews_moderation_flag.php:67
+msgid "review_flag_reason_language"
+msgstr "Nem ideillő nyelvhasználat/veszekedés"
+
+#: models/reviews_moderation_flag.php:71
+msgid "review_flag_reason_other"
+msgstr "Egyéb (adja meg)"
+
+#: models/reviews_moderation_flag.php:65
+msgid "review_flag_reason_spam"
+msgstr "Hirdetés vagy nem értékeléssel kapcsolatos tartalom"
+
+#: views/reviews/display.thtml:91 views/reviews/display.thtml:175
+#: controllers/reviews_controller.php:555
+msgid "review_flag_success"
+msgstr "Köszönjük, ez az értékelés szerkesztői jóváhagyásra meg lett jelölve."
+
+#: views/reviews/display.thtml:41
+msgid "review_flag_this"
+msgstr "Értékelés feljelentése"
+
+#: views/reviews/display.thtml:42
+msgid "review_flag_this_titletip"
+msgstr ""
+"Ez az értékelés ide nem illő, pontatlan vagy hirdetés? Kattintson ide "
+"szerkesztői ellenőrzésre való megjelöléshez."
+
+# %1 is the URL of the support section, %2 for the review guidelines
+#. %1 is the URL of the support section, %2 for the review guidelines
+#: views/reviews/add.thtml:53
+msgid "review_guidelines_short"
+msgstr ""
+"<p>Tartsa észben a következÅ‘ket:</p><ul><li>Ãrjon úgy, mint ha egy "
+"barátjában mesélné el a kiegészítÅ‘vel szerzett tapasztalatait. Ãrjon "
+"részletesen, például milyen funkciók tetszettek/nem tetszettek, milyen "
+"könnyű volt a használat, mik a hátrányok. Lehetőleg nem tegyen általános "
+"kijelentéseket, például „Jó†vagy „Rosszâ€, hacsak nem indokolja meg a "
+"véleményét.</li><li>Nem írjon hibaüzeneteket az értékelésbe. Az e-mail címét "
+"nem adjuk tovább a kiegészítők fejlesztőinek, és esetleg szükség lehet a "
+"kapcsolatfelvételre a probléma megoldásához. Olvassa el a <a href=\"%1$s"
+"\">támogatási szakaszban</a>, hogy hol kaphat segítséget a kiegészítő "
+"használatához.</li><li>Az értékelés legyen tiszta, kerülje az ide nem illő "
+"nyelvezet használatát, és nem adjon meg személyes adatokat.</li></"
+"ul><p>Olvassa el az <a href=\"%2$s\">Értékelési útmutatót</a> a kiegészítők "
+"felhasználói értékelésével kapcsolatos további tudnivalókért.</p>"
+
+# %1 is the addon name
+#. %1 is the add-on name
+#: views/reviews/flag.thtml:56 views/reviews/display.thtml:55
+#: views/reviews/review_added.thtml:50
+#, php-format
+msgid "reviews_header"
+msgstr "%s értékelései"
+
+#: controllers/addons_controller.php:435
+msgid "rss_featuredaddons"
+msgstr "Kiemeltek"
+
+#: controllers/addons_controller.php:432
+msgid "rss_newestaddons"
+msgstr "Legújabbak"
+
+#: controllers/addons_controller.php:434
+#, fuzzy
+msgid "rss_popularaddons"
+msgstr "Popular Add-ons"
+
+#: controllers/addons_controller.php:433
+msgid "rss_updatedaddons"
+msgstr "Frissítettek"
+
+#: views/elements/search_mini.thtml:70
+#, fuzzy
+msgid "search"
+msgstr "Search"
+
+#: views/search/collections.thtml:51
+#, fuzzy
+msgid "search_collections_header"
+msgstr "Collection Search Results"
+
+#: controllers/search_controller.php:297
+#, fuzzy
+msgid "search_collections_pagetitle"
+msgstr "Collection Search Results"
+
+#: controllers/search_controller.php:99
+msgid "search_disabled"
+msgstr "A keresés jelenleg le van tiltva. Próbálja újra később."
+
+#: views/elements/amo2009/search.thtml:188 views/elements/search.thtml:187
+#: views/elements/search_mini.thtml:54
+msgid "search_form_all_addons"
+msgstr "minden kiegészítő"
+
+#. This string is in the main category dropdown when searching
+#: views/elements/amo2009/search.thtml:204
+#, fuzzy
+msgid "search_form_all_collections"
+msgstr "all collections"
+
+#: views/elements/amo2009/search.thtml:184
+#: views/elements/amo2009/search.thtml:385
+#: views/elements/amo2009/search.thtml:408 views/elements/search.thtml:171
+#: views/elements/search.thtml:183 views/elements/search_mini.thtml:43
+#: views/elements/search_mini.thtml:49 views/layouts/mozilla.thtml:188
+msgid "search_form_default_text"
+msgstr "kiegészítők keresése"
+
+#: views/elements/amo2009/search.thtml:184
+#: views/elements/amo2009/search.thtml:404
+#, fuzzy
+msgid "search_form_default_text_collections"
+msgstr "search for collections"
+
+#: views/elements/amo2009/search.thtml:206 views/elements/search.thtml:202
+msgid "search_form_submit_tooltip"
+msgstr "Kiegészítők keresése"
+
+#: views/elements/amo2009/search.thtml:184 views/elements/search.thtml:183
+#: views/elements/search_mini.thtml:49
+msgid "search_form_tooltip"
+msgstr "Kattintson a keresési kifejezések beviteléhez"
+
+#: views/elements/amo2009/search.thtml:186 views/elements/search.thtml:185
+#: views/elements/search_mini.thtml:52
+msgid "search_form_within"
+msgstr "itt"
+
+#: views/addons/searchengines.thtml:118
+msgid "search_landing_all_search_engines"
+msgstr "Minden kereső"
+
+#: views/addons/searchengines.thtml:114
+msgid "search_landing_browse_search_engines"
+msgstr "Tallózás a keresők között"
+
+#: views/search/collections.thtml:58 views/search/index.thtml:59
+msgid "search_nothing_found"
+msgstr "A keresés eredménytelen."
+
+#: controllers/search_controller.php:185
+msgid "search_pagetitle"
+msgstr "Kiegészítők keresése"
+
+#: controllers/search_controller.php:242
+msgid "search_rss_description"
+msgstr "Keresés eredményének hírforrása"
+
+#. %s is the terms the user is searching for (a string)
+#: controllers/search_controller.php:241
+#, php-format
+msgid "search_rss_results_for"
+msgstr "Keresés eredményének: %s"
+
+#: views/elements/header.thtml:154 views/layouts/amo2009.thtml:296
+msgid "sidebar_navlink_admin_tools"
+msgstr "Adminisztrációs eszközök"
+
+#: views/elements/header.thtml:146 views/layouts/amo2009.thtml:288
+msgid "sidebar_navlink_developer_tools"
+msgstr "Fejlesztőeszközök"
+
+#: views/elements/header.thtml:148 views/layouts/amo2009.thtml:290
+msgid "sidebar_navlink_editor_tools"
+msgstr "Szerkesztőeszközök"
+
+#: views/layouts/amo2009.thtml:302
+msgid "sidebar_navlink_welcome"
+msgstr "Üdvözlet"
+
+#. %s is the user's name
+#: views/layouts/amo2009.thtml:302
+#, php-format
+msgid "sidebar_navlink_welcome_name"
+msgstr "Üdvözlet, %s"
+
+#: views/elements/pitch.thtml:50 views/elements/pitch.thtml:55
+msgid "sidebar_pitch_dictionary"
+msgstr "Szótár"
+
+#: views/elements/pitch.thtml:72
+msgid "sidebar_pitch_featured_addons"
+msgstr "Kiemeltek"
+
+#: views/elements/pitch.thtml:61
+msgid "sidebar_pitch_looking_for"
+msgstr "Keresés:"
+
+#: views/elements/pitch.thtml:70
+msgid "sidebar_pitch_newest_addons"
+msgstr "Legújabbak"
+
+#: views/elements/pitch.thtml:49
+msgid "sidebar_pitch_search"
+msgstr "Kereső"
+
+#: views/elements/pitch.thtml:69
+msgid "sidebar_pitch_subscribe_to"
+msgstr "Feliratkozás"
+
+#: views/elements/pitch.thtml:48 views/elements/pitch.thtml:54
+msgid "sidebar_pitch_theme"
+msgstr "Téma"
+
+#: views/elements/pitch.thtml:71
+msgid "sidebar_pitch_updated_addons"
+msgstr "Frissítettek"
+
+#. %1$s is a number
+#: views/helpers/localization.php:65 views/developers/versions_edit.thtml:95
+#: views/addons/dictionaries.thtml:92
+#, php-format
+msgid "size_kb"
+msgstr "%1$s KB"
+
+#: views/elements/amo2009/stars.thtml:57 views/elements/stars.thtml:63
+msgid "stars_not_yet_rated"
+msgstr "Még nem osztályozott"
+
+# %1 is the number of stars this add-on has
+#. %1 is the number of stars this add-on has
+#: views/elements/amo2009/stars.thtml:49 views/elements/stars.thtml:54
+#, php-format
+msgid "stars_rated_x_outof_5"
+msgstr "Az osztályzat %s csillag az 5-ből"
+
+#: views/statistics/addon.thtml:59
+msgid "statistics_addon_dashboard_link"
+msgstr "Kezdőlap"
+
+#: views/statistics/addon.thtml:58
+msgid "statistics_addon_developertools_link"
+msgstr "Fejlesztőeszközök"
+
+#: views/statistics/addon.thtml:53
+msgid "statistics_addon_switch"
+msgstr "Kiegészítő váltása"
+
+#. This is a date format.
+#. http://php.net/strftime
+#: views/statistics/rss/summary.thtml:54 views/statistics/addon.thtml:181
+msgid "statistics_date_shortmonth"
+msgstr "%b. %e"
+
+#. This is a date format.
+#. http://php.net/strftime
+#: views/statistics/rss/summary.thtml:40 views/statistics/addon.thtml:152
+msgid "statistics_date_shortmonthwithyear"
+msgstr "%Y. %b. %e."
+
+#. This is a date format.
+#. http://php.net/strftime
+#: views/statistics/rss/summary.thtml:41 views/statistics/rss/summary.thtml:48
+#: views/statistics/addon.thtml:161 views/statistics/addon.thtml:172
+msgid "statistics_date_weekdayshortmonth"
+msgstr "%A, %b. %e."
+
+#. %1$s is an add-on name and version. Example: Add-on 3.5
+#: controllers/components/stats.php:519
+#, php-format
+msgid "statistics_events_addon_created"
+msgstr "%1$s létrehozva"
+
+#. %1$s is an application name and version. Example: Firefox 3.5
+#: controllers/components/stats.php:500
+#, php-format
+msgid "statistics_events_app_released"
+msgstr "%1$s kiadva"
+
+#: views/statistics/addon.thtml:71
+msgid "statistics_help_close_link"
+msgstr "Bezárás"
+
+#: views/statistics/addon.thtml:60
+msgid "statistics_help_link"
+msgstr "Súgó"
+
+#: views/statistics/index.thtml:83
+msgid "statistics_index_anotheraddon"
+msgstr "vagy válasszon másik kiegészítőt"
+
+#: views/statistics/index.thtml:85
+msgid "statistics_index_anotheraddon_public"
+msgstr "vagy válasszon nyilvános statisztikájú kiegészítőt"
+
+#: views/statistics/index.thtml:71
+msgid "statistics_index_myaddons"
+msgstr "Válassza ki az egyik kiegészítőjét, és nézze meg a statisztikáját"
+
+#: views/statistics/index.thtml:89
+msgid "statistics_index_selectaddon"
+msgstr "Válasszon ki egy kiegészítőt, és nézze meg a statisztikáját"
+
+#: views/statistics/index.thtml:91
+msgid "statistics_index_selectaddon_public"
+msgstr "Válasszon nyilvános statisztikájú kiegészítőt"
+
+#: views/statistics/index.thtml:39
+msgid "statistics_index_title"
+msgstr "Statisztikák"
+
+#: views/statistics/index.thtml:97
+msgid "statistics_index_view_button"
+msgstr "Statisztika megtekintése"
+
+#: views/statistics/addon.thtml:222 controllers/statistics_controller.php:247
+msgid "statistics_js_download_csv"
+msgstr "Táblázat megtekintése CSV formátumban"
+
+#: controllers/statistics_controller.php:246
+msgid "statistics_js_dropdowns_none"
+msgstr "nincs"
+
+#: controllers/statistics_controller.php:245
+msgid "statistics_js_dropdowns_removeplot"
+msgstr "Grafikon eltávolítása"
+
+#: controllers/statistics_controller.php:248
+msgid "statistics_js_groupby_selector_date"
+msgstr "Csoportosítás: nap"
+
+#: controllers/statistics_controller.php:251
+msgid "statistics_js_groupby_selector_month"
+msgstr "Csoportosítás: hónap"
+
+#: controllers/statistics_controller.php:249
+msgid "statistics_js_groupby_selector_week"
+msgstr "Csoportosítás: hét"
+
+#: controllers/statistics_controller.php:250
+msgid "statistics_js_groupby_selector_week_over_week"
+msgstr "Összehasonlítás: hét"
+
+#: controllers/statistics_controller.php:260
+msgid "statistics_js_plotselection_foundinrange"
+msgstr "%s van a tartományban"
+
+#: controllers/statistics_controller.php:270
+msgid "statistics_js_plotselection_options_addplot_name"
+msgstr "Grafikon hozzáadása"
+
+#: controllers/statistics_controller.php:271
+msgid "statistics_js_plotselection_options_addplot_tooltip"
+msgstr "Másik grafikon hozzáadása"
+
+#: controllers/statistics_controller.php:261
+msgid "statistics_js_plotselection_options_count_name_checked"
+msgstr "Teljes szám elrejtése"
+
+#: controllers/statistics_controller.php:262
+msgid "statistics_js_plotselection_options_count_name_unchecked"
+msgstr "Teljes szám megjelenítése"
+
+#: controllers/statistics_controller.php:263
+msgid "statistics_js_plotselection_options_count_tooltip"
+msgstr "A teljes szám megjelenítése ehhez a diagramhoz"
+
+#: controllers/statistics_controller.php:275
+msgid "statistics_js_plotselection_options_csv_name"
+msgstr "Adatok megtekintése (CSV)"
+
+#: controllers/statistics_controller.php:276
+msgid "statistics_js_plotselection_options_csv_tooltip"
+msgstr "Az adatok vesszővel elválasztott formában letölthetők"
+
+#: controllers/statistics_controller.php:267
+msgid "statistics_js_plotselection_options_events_addon_name_checked"
+msgstr "%s-események elrejtése"
+
+#: controllers/statistics_controller.php:268
+msgid "statistics_js_plotselection_options_events_addon_name_unchecked"
+msgstr "%s-események megjelenítése"
+
+#: controllers/statistics_controller.php:269
+msgid "statistics_js_plotselection_options_events_addon_tooltip"
+msgstr "A kiegészítő kiadási dátumainak felírása a grafikonokra"
+
+#: controllers/statistics_controller.php:264
+msgid "statistics_js_plotselection_options_events_firefox_name_checked"
+msgstr "Firefox-események elrejtése"
+
+#: controllers/statistics_controller.php:265
+msgid "statistics_js_plotselection_options_events_firefox_name_unchecked"
+msgstr "Firefox-események megjelenítése"
+
+#: controllers/statistics_controller.php:266
+msgid "statistics_js_plotselection_options_events_firefox_tooltip"
+msgstr "A Firefox kiadási dátumainak felírása a grafikonokra"
+
+#: controllers/statistics_controller.php:272
+msgid "statistics_js_plotselection_options_resize_name_checked"
+msgstr "Diagram összecsukása"
+
+#: controllers/statistics_controller.php:273
+msgid "statistics_js_plotselection_options_resize_name_unchecked"
+msgstr "Diagram széthúzása"
+
+#: controllers/statistics_controller.php:274
+msgid "statistics_js_plotselection_options_resize_tooltip"
+msgstr "Diagram átméretezése"
+
+#: controllers/statistics_controller.php:254
+msgid "statistics_js_plotselection_selector_adu"
+msgstr "Aktív felhasználók"
+
+#: controllers/statistics_controller.php:256
+msgid "statistics_js_plotselection_selector_application"
+msgstr "Alkalmazás"
+
+#: controllers/statistics_controller.php:259
+msgid "statistics_js_plotselection_selector_custom"
+msgstr "Egyéni"
+
+#: controllers/statistics_controller.php:253
+msgid "statistics_js_plotselection_selector_downloads"
+msgstr "Letöltések"
+
+#: controllers/statistics_controller.php:258
+msgid "statistics_js_plotselection_selector_os"
+msgstr "Operációs rendszer"
+
+#: controllers/statistics_controller.php:257
+msgid "statistics_js_plotselection_selector_status"
+msgstr "Kiegészítő állapota"
+
+#: controllers/statistics_controller.php:252
+msgid "statistics_js_plotselection_selector_summary"
+msgstr "Összefoglaló"
+
+#: controllers/statistics_controller.php:255
+msgid "statistics_js_plotselection_selector_version"
+msgstr "Kiegészítő verziója"
+
+#: controllers/components/stats.php:398
+msgid "statistics_longnames_application"
+msgstr "Alkalmazás"
+
+#: controllers/components/stats.php:400
+msgid "statistics_longnames_os"
+msgstr "Operációs rendszer"
+
+#: controllers/components/stats.php:399
+msgid "statistics_longnames_status"
+msgstr "Kiegészítő állapota"
+
+#: controllers/components/stats.php:401
+msgid "statistics_longnames_unknown"
+msgstr "Ismeretlen"
+
+#: controllers/components/stats.php:397
+msgid "statistics_longnames_version"
+msgstr "Kiegészítő verziója"
+
+#: views/statistics/addon.thtml:118
+msgid "statistics_notice_data_insufficient"
+msgstr "Még nincs elég adat a diagram megjelenítéséhez. Próbálja újra később."
+
+#: views/statistics/addon.thtml:130
+msgid "statistics_notice_data_none"
+msgstr ""
+"Még nincsenek adatok ehhez kiegészítőhöz. Pár nap múlva próbálja meg újra."
+
+#: views/statistics/addon.thtml:41
+msgid "statistics_notice_data_updating"
+msgstr ""
+"A kiegészítő statisztikája pillanatnyilag frissül. Az utolsó adatok "
+"pontatlanok lehetnek, mert a programok most frissítik ezeket az "
+"információkat. Pár perc múlva próbálja meg újra."
+
+#: views/statistics/addon.thtml:136
+msgid "statistics_notice_disabled"
+msgstr "A Statisztika modul jelenleg le van tiltva. Próbálja újra később."
+
+#: views/statistics/addon.thtml:123
+msgid "statistics_notice_nojavascript"
+msgstr ""
+"A Statisztika modul diagramjainak megtekintéséhez JavaScript szükséges."
+
+#: views/statistics/addon.thtml:44
+msgid "statistics_notice_settings_updated"
+msgstr "A beállítások frissítve lettek!"
+
+#: controllers/statistics_controller.php:60
+#: controllers/statistics_controller.php:71
+#: controllers/statistics_controller.php:74
+#: controllers/statistics_controller.php:240
+msgid "statistics_pagetitle"
+msgstr "Statisztikák"
+
+#: views/statistics/addon.thtml:99
+msgid "statistics_plot_legend_adu"
+msgstr "Aktív felhasználók"
+
+#: views/statistics/addon.thtml:95
+msgid "statistics_plot_legend_downloads"
+msgstr "Napi letöltésszám"
+
+#: views/statistics/addon.thtml:107
+msgid "statistics_plot_options_zoomin_alt"
+msgstr "Nagyítás"
+
+#: views/statistics/addon.thtml:106
+msgid "statistics_plot_options_zoomin_title"
+msgstr "Nagyítás egy hónapra"
+
+#: views/statistics/addon.thtml:110
+msgid "statistics_plot_options_zoomout_alt"
+msgstr "Kicsinyítés"
+
+#: views/statistics/addon.thtml:109
+msgid "statistics_plot_options_zoomout_title"
+msgstr "Kicsinyítés egy hónapra"
+
+#: controllers/statistics_controller.php:283
+#, php-format
+msgid "statistics_rss_description"
+msgstr "%1$s statisztikájának napi összefoglalója"
+
+#: views/statistics/rss/summary.thtml:68
+msgid "statistics_rss_title_fulldate"
+msgstr "%Y. %B %e., %A"
+
+#: views/statistics/rss/summary.thtml:68
+#, php-format
+msgid "statistics_rss_title_statsfordate"
+msgstr "%1$s statisztikája"
+
+#: views/statistics/settings.thtml:49
+msgid "statistics_settings_access_description"
+msgstr ""
+"Alapértelmezés szerint csak Ön és a Mozilla érheti el ezeket az "
+"információkat. Megnyithatja a nagyközönség számára, hogy bárki megnézhesse a "
+"kiegészítőjének adatait."
+
+#: views/statistics/settings.thtml:48
+msgid "statistics_settings_access_heading"
+msgstr "Hozzáférés-kezelés"
+
+#: views/statistics/settings.thtml:51
+msgid "statistics_settings_access_private"
+msgstr "Privát"
+
+#: views/statistics/settings.thtml:51
+msgid "statistics_settings_access_private_description"
+msgstr ""
+"Csak Ön és a Mozilla nézheti meg ennek a kiegészítőnek a statisztikáit."
+
+#: views/statistics/settings.thtml:52
+msgid "statistics_settings_access_public"
+msgstr "Nyilvános"
+
+#: views/statistics/settings.thtml:52
+msgid "statistics_settings_access_public_description"
+msgstr "Bárki megnézheti ennek a kiegészítőnek a statisztikáit."
+
+#: views/statistics/addon.thtml:251
+msgid "statistics_settings_change_link"
+msgstr "Beállítások megváltoztatása"
+
+#: views/statistics/addon.thtml:253
+msgid "statistics_settings_confidential"
+msgstr "Kezelje bizalmasan ezt az információt."
+
+#: views/statistics/addon.thtml:245
+msgid "statistics_settings_currently_private"
+msgstr "Ez az oldal jelenleg <b>privát</b>."
+
+#: views/statistics/addon.thtml:241
+msgid "statistics_settings_currently_public"
+msgstr "Ez az oldal jelenleg <b>nyilvános</b>."
+
+#: views/statistics/addon.thtml:246
+msgid "statistics_settings_locked_alt"
+msgstr "Zárolva"
+
+#: views/statistics/settings.thtml:57
+msgid "statistics_settings_return_link"
+msgstr "Vissza a statisztikákhoz"
+
+#: views/statistics/settings.thtml:56
+msgid "statistics_settings_save_button"
+msgstr "Beállítások mentése"
+
+#: views/statistics/settings.thtml:46
+#, php-format
+msgid "statistics_settings_title"
+msgstr "%1$s statisztikaoldalának beállításai"
+
+#: views/statistics/addon.thtml:242
+msgid "statistics_settings_unlocked_alt"
+msgstr "Nem zárolt"
+
+#: controllers/components/stats.php:405
+msgid "statistics_shortnames_application"
+msgstr "Alk."
+
+#: controllers/components/stats.php:407
+msgid "statistics_shortnames_os"
+msgstr "OS"
+
+#: controllers/components/stats.php:406
+msgid "statistics_shortnames_status"
+msgstr "Ãll."
+
+#: controllers/components/stats.php:408
+msgid "statistics_shortnames_unknown"
+msgstr "Is"
+
+#: controllers/components/stats.php:404
+msgid "statistics_shortnames_version"
+msgstr "Ver"
+
+#: views/statistics/rss/summary.thtml:42 views/statistics/addon.thtml:192
+msgid "statistics_summary_downloads_average"
+msgstr "Ãtlagos napi letöltésszám"
+
+#: views/statistics/rss/summary.thtml:39
+msgid "statistics_summary_downloads_heading"
+msgstr "Letöltések"
+
+#: views/statistics/rss/summary.thtml:41 views/statistics/addon.thtml:171
+msgid "statistics_summary_downloads_lastcount"
+msgstr "Utolsó napi szám"
+
+#: views/statistics/rss/summary.thtml:43 views/statistics/addon.thtml:199
+msgid "statistics_summary_downloads_lastweek"
+msgstr "Letöltések az elmúlt 7 napon"
+
+#: views/statistics/rss/summary.thtml:40 views/statistics/addon.thtml:151
+msgid "statistics_summary_downloads_total"
+msgstr "Összes letöltés"
+
+#: views/statistics/rss/summary.thtml:40 views/statistics/addon.thtml:152
+#, php-format
+msgid "statistics_summary_downloads_total_sincedate"
+msgstr "%1$s óta"
+
+#: views/statistics/rss/summary.thtml:50 views/statistics/rss/summary.thtml:56
+#: views/statistics/addon.thtml:163 views/statistics/addon.thtml:183
+msgid "statistics_summary_nodata"
+msgstr "Nincsenek még adatok"
+
+#: views/statistics/rss/summary.thtml:60 views/statistics/addon.thtml:195
+msgid "statistics_summary_updatepings_average"
+msgstr "Aktív felhasználók átlaga"
+
+#: views/statistics/rss/summary.thtml:52 views/statistics/addon.thtml:177
+msgid "statistics_summary_updatepings_changefromprevious"
+msgstr "Változás az előző számhoz képest"
+
+#: views/statistics/rss/summary.thtml:54 views/statistics/addon.thtml:181
+#, php-format
+msgid "statistics_summary_updatepings_changefromprevious_ondate"
+msgstr "%1$s dátum: %2$s"
+
+#: views/statistics/rss/summary.thtml:45
+msgid "statistics_summary_updatepings_heading"
+msgstr "Aktív felhasználók"
+
+#: views/statistics/rss/summary.thtml:46 views/statistics/addon.thtml:157
+msgid "statistics_summary_updatepings_total"
+msgstr "Aktív felhasználók"
+
+#: views/statistics/rss/summary.thtml:48 views/statistics/addon.thtml:161
+#, php-format
+msgid "statistics_summary_updatepings_total_ondate"
+msgstr "Dátum: %1$s"
+
+#: views/statistics/rss/summary.thtml:61 views/statistics/addon.thtml:203
+#, fuzzy
+msgid "statistics_summary_updatepings_weekly_average"
+msgstr "Average Daily Users this Week"
+
+#. %s is a percentage, like '+22.33%'. It sits next to another number, so
+#. the implied meaning is 'percentage change' from the previous stat point.
+#: views/statistics/rss/summary.thtml:62 views/statistics/addon.thtml:205
+#, fuzzy
+msgid "statistics_summary_updatepings_weekly_change"
+msgstr "%s from last week"
+
+#: views/statistics/addon.thtml:65 controllers/statistics_controller.php:184
+#: controllers/statistics_controller.php:282
+#, php-format
+msgid "statistics_title_addon_stats"
+msgstr "%1$s statisztikája"
+
+#: views/addons/themes_landing.thtml:113
+msgid "themes_landing_all_themes"
+msgstr "Minden téma"
+
+#: views/addons/themes_landing.thtml:109
+msgid "themes_landing_browse_themes"
+msgstr "Tallózás a témák között"
+
+#: views/users/edit.thtml:185
+msgid "user_change_email"
+msgstr "E-mail cím módosítása"
+
+#: views/users/edit.thtml:169
+msgid "user_change_password"
+msgstr "Jelszó módosítása"
+
+#: views/users/edit.thtml:96
+#, fuzzy
+msgid "user_change_password_or_email"
+msgstr "Change Password or Email"
+
+#: controllers/users_controller.php:197
+msgid "user_confirmationcode_resent"
+msgstr "A megerősítő kódot újra elküldtük!"
+
+# %1 is the email address, %2 is the URL of the user registration page
+#. %1 is the email address, %2 is the URL of the user registration page
+#: views/users/delete.thtml:51
+msgid "user_del_account_deleted"
+msgstr ""
+"A(z) %1$s felhasználói fiók sikeresen törlődött. Ha később visszatérne, "
+"regisztrálhatja magát a <a href=\"%2$s\">felhasználói regisztrációs oldalon</"
+"a>."
+
+#: views/users/delete.thtml:102
+msgid "user_del_community_sad"
+msgstr "A Mozilla Add-ons közössége szomorúan veszi tudomásul a távozását."
+
+#: views/users/delete.thtml:123
+msgid "user_del_confirm_password"
+msgstr "Jelszó megerősítése"
+
+#: views/users/delete.thtml:134
+msgid "user_del_deletenow"
+msgstr "Felhasználói fiók törlése"
+
+# %1 is the URL of the user's info page
+#. %1 is the URL of the user's info page
+#: views/users/delete.thtml:64
+msgid "user_del_error_addons"
+msgstr ""
+"Nem törölheti a fiókját, ha <a href=\"%1$s\">bármelyik kiegészítő "
+"szerzőjeként szerepel</a>. A fiók törléséhez először kérjen meg valakit a "
+"fejlesztőcsoportjából, hogy törölje a kiegészítőinek szerzői közül. Ezután "
+"tudja törölni itt a fiókját."
+
+# %1 is a link to the amo-editors mailing list
+#. %1 is a link to the amo-editors mailing list
+#: views/users/delete.thtml:71
+msgid "user_del_error_addons_more_questions"
+msgstr "További kérdéseivel forduljon segítségért az %1$s levelezőlistához."
+
+#: views/users/delete.thtml:78
+msgid "user_del_error_checkbox"
+msgstr "A fiók törlése előtt be kell jelölnie a „Megértettem...†négyzetet."
+
+#: views/users/delete.thtml:84
+msgid "user_del_error_password"
+msgstr "A lépés végrehajtásához írja be a jelszavát."
+
+# %1 is a link to the amo-admins mailing list
+#. %1 is a link to the amo-admins mailing list
+#: views/users/delete.thtml:91
+msgid "user_del_error_unknown"
+msgstr ""
+"Ismeretlen hiba történt a fiókjának törlésekor. A problémával forduljon az %1"
+"$s levelezőlistához, majd mi töröljük a fiókot. Elnézést kérünk a "
+"kellemetlenségért."
+
+#: views/users/delete.thtml:110
+msgid "user_del_header_confirm_deletion"
+msgstr "Fiók törlésének jóváhagyása"
+
+# %1 is the user's email address
+#. %1 is the user's email address
+#: views/users/delete.thtml:100
+msgid "user_del_header_delete_account"
+msgstr "%1$s felhasználói fiókjának törlése"
+
+#: views/users/delete.thtml:50
+msgid "user_del_header_farewell"
+msgstr "Viszlát!"
+
+#: views/users/delete.thtml:115
+msgid "user_del_nologin"
+msgstr "Nem fog tudni többé belépni a Mozilla Add-ons webhelyre."
+
+#: views/users/delete.thtml:112
+msgid "user_del_permanently_removed_means"
+msgstr ""
+"A „törlésâ€-re kattintva a fiók <strong>véglegesen törlÅ‘dik</strong>. Ez azt "
+"jelenti, hogy:"
+
+#: views/users/delete.thtml:116
+msgid "user_del_reviews_anonymized"
+msgstr ""
+"Értékelései és osztályzatai nem lesznek törölve, de többé nem lesznek Önhöz "
+"rendelve."
+
+# %1 is a link to the amo-editors mailing list
+#. %1 is a link to the amo-editors mailing list
+#: views/users/delete.thtml:104
+msgid "user_del_specific_problem_editors"
+msgstr ""
+"Ha olyan problémája van, amiben segíthetünk, kérjük, ne törölje még a "
+"fiókját, hanem forduljon hozzánk az %1$s levelezőlistán. Megpróbálunk "
+"legjobb tudásunk szerint segíteni."
+
+#: views/users/delete.thtml:130
+msgid "user_del_understand_permanent"
+msgstr "Megértettem, hogy ez a lépés nem vonható vissza."
+
+#: views/helpers/addons_html.php:192
+msgid "user_deleted_nickname"
+msgstr "Felhasználó törlése"
+
+# %1 is the new email address
+#. %1 is the new email address
+#: views/users/edit.thtml:71
+msgid "user_edit_confirm_email_sent"
+msgstr ""
+"Az új e-mail címet megerősítő hivatkozást e-mailben küldtük el a(z) %1$s "
+"címre. A módosítás hatályba léptetéséhez rá kell kattintania az ebben az e-"
+"mailben levő hivatkozásra. Addig továbbra is a régi e-mail címével "
+"jelentkezhet be."
+
+#: views/users/edit.thtml:201
+msgid "user_edit_delete_user"
+msgstr "Felhasználói fiók törlése"
+
+# This contains the email sent to users when they signed up for a new
+# account:
+# %1 is the confirmation URL, %2 is the current app
+#. This contains the email sent to users when they signed up for a new
+#. account:
+#. %1 is the confirmation URL, %2 is the current app
+#: views/users/email/confirm_plain.thtml:6
+#, php-format
+msgid "user_email_confirm_account_nopass"
+msgstr ""
+"Üdvözli a %2$s Add-ons!\n"
+"\n"
+"Az új fiók használata előtt aktiválnia kell azt - ez garantálja, hogy a "
+"használt e-mail cím érvényes és az Öné.\n"
+"A fiók aktiválásához kattintson az alábbi hivatkozásra, vagy másolja az "
+"egészet a böngésző címsávjába:\n"
+"\n"
+"%1$s\n"
+"\n"
+"A fiók sikeres aktiválása után eldobhatja ezt a levelet.\n"
+"\n"
+"Köszönjük, hogy regisztrált a %2$s Add-ons webhelyen!\n"
+"-- A %2$s Add-ons munkatársai"
+
+# %1 is the confirmation url, %2 is the application name
+#. %1 is the confirmation url, %2 is the application name
+#: views/users/email/emailchange_plain.thtml:5
+msgid "user_email_confirm_emailchange"
+msgstr ""
+"E-mail címének módosítását kérte a %2$s Add-ons webhelyen.\n"
+"\n"
+"Az új cím megerősítéséhez kattintson az alábbi hivatkozásra, vagy másolja az "
+"egészet a böngésző címsávjába:\n"
+"\n"
+"%1$s\n"
+"\n"
+"48 órája van az új cím megerősítésére. Ha mégsem szeretné megváltoztatni a "
+"címet, akkor hagyja figyelmen kívül ezt az e-mailt.\n"
+"\n"
+"Köszönjük!\n"
+"-- A %2$s Add-ons munkatársai"
+
+#: controllers/users_controller.php:168
+#, php-format
+msgid "user_email_confirm_subject"
+msgstr "Köszönjük, hogy regisztrált a %s Add-ons webhelyen!"
+
+# This is the password reset email
+# %1 is the pw reset URL, %2 is the application
+#. This is the password reset email
+#. %1 is the pw reset URL, %2 is the application
+#: views/users/email/pwreset_plain.thtml:5
+#, php-format
+msgid "user_email_pwreset"
+msgstr ""
+"A %2$s Add-ons jelszavának törlése\n"
+"\n"
+"Kérés érkezett az addons.mozilla.org ezen fiókja jelszavának törlésére. A "
+"jelszó módosításához kattintson a következő hivatkozásra, vagy másolja be a "
+"böngésző címsávjába:\n"
+"\n"
+"%1$s\n"
+"\n"
+"Ha nem Ön kérte ezt az e-mailt, akkor nem kell semmit tennie.\n"
+"\n"
+"Köszönjük!\n"
+"-- A %2$s Add-ons munkatársai"
+
+#: controllers/users_controller.php:245
+#, php-format
+msgid "user_email_pwreset_subject"
+msgstr "A %s Add-ons jelszavának törlése"
+
+#: views/users/emailchange.thtml:50
+msgid "user_emailchange_error"
+msgstr "Hiba!"
+
+# %1 is the application name
+#. %1 is the application name
+#: controllers/users_controller.php:533
+msgid "user_emailchange_subject"
+msgstr "Erősítse meg az e-mail címének módosítását a %1$sAdd-ons webhelyen"
+
+#: views/users/emailchange.thtml:48
+msgid "user_emailchange_success"
+msgstr "Sikeres!"
+
+# %1 is the new email address
+#. %1 is the new email address
+#: views/users/emailchange.thtml:49
+msgid "user_emailchange_successful_description"
+msgstr ""
+"Az e-mail címe sikeresen megváltozott. Ezentúl használja a(z) %1$s címet a "
+"bejelentkezéshez."
+
+#: views/users/edit.thtml:134 views/admin/users_edit.thtml:111
+#, fuzzy
+msgid "user_form_bio"
+msgstr "About me"
+
+#: views/users/edit.thtml:135 views/admin/users_edit.thtml:112
+#, fuzzy
+msgid "user_form_bio_description"
+msgstr ""
+"Introduce yourself to the community, if you like! This text will appear "
+"publicly on your user info page. Line breaks will be preserved, but no HTML "
+"is allowed."
+
+#: views/users/pwreset.thtml:77 views/users/register.thtml:73
+#: views/users/edit.thtml:181
+msgid "user_form_confirmpassword"
+msgstr "Jelszó megerősítése"
+
+#: views/users/edit.thtml:145
+#, fuzzy
+msgid "user_form_display_collections"
+msgstr "Display the collections I have created in my user profile"
+
+#: views/users/edit.thtml:149
+#, fuzzy
+msgid "user_form_display_collections_fav"
+msgstr "Display my favorite collections in my user profile"
+
+#: views/users/edit.thtml:86
+#, php-format
+msgid "user_form_editprofile"
+msgstr "%s felhasználói profiljának szerkesztése"
+
+#: views/users/pwreset.thtml:52 views/users/login.thtml:81
+#: views/users/register.thtml:63 views/users/edit.thtml:187
+msgid "user_form_email"
+msgstr "E-mail cím"
+
+#: views/users/register.thtml:78 views/users/edit.thtml:103
+#: views/admin/users_edit.thtml:76
+msgid "user_form_firstname"
+msgstr "Utónév"
+
+#: views/users/register.thtml:94 views/users/edit.thtml:119
+#: views/admin/users_edit.thtml:91
+msgid "user_form_hideemail"
+msgstr "E-mail cím elrejtése"
+
+#: views/users/register.thtml:98 views/users/edit.thtml:123
+#: views/admin/users_edit.thtml:99
+msgid "user_form_homepage"
+msgstr "Webhely URL"
+
+#: views/users/register.thtml:84 views/users/edit.thtml:109
+#: views/admin/users_edit.thtml:81
+msgid "user_form_lastname"
+msgstr "Vezetéknév"
+
+#: controllers/users_controller.php:333
+msgid "user_form_login"
+msgstr "Felhasználó bejelentkezése"
+
+#: views/users/pwreset.thtml:72 views/users/edit.thtml:176
+msgid "user_form_newpassword"
+msgstr "Új jelszó"
+
+#: views/users/register.thtml:89 views/users/edit.thtml:114
+#: views/admin/users_edit.thtml:86
+msgid "user_form_nickname"
+msgstr "Becenév"
+
+#: views/users/edit.thtml:171
+msgid "user_form_oldpassword"
+msgstr "Régi jelszó"
+
+#: views/users/edit.thtml:97 views/users/edit.thtml:200
+msgid "user_form_otheractions"
+msgstr "Egyéb műveletek"
+
+#: views/users/login.thtml:85 views/users/register.thtml:68
+msgid "user_form_password"
+msgstr "Jelszó"
+
+#: controllers/users_controller.php:93
+msgid "user_form_registration"
+msgstr "Új felhasználó regisztrációja"
+
+#: views/users/login.thtml:90
+msgid "user_form_remember_me"
+msgstr "Megjegyzés ezen a számítógépen"
+
+#: views/admin/users_edit.thtml:95
+msgid "user_form_showsandbox"
+msgstr "Homokozó megjelenítése?"
+
+#: views/users/edit.thtml:205
+msgid "user_form_submit_edit"
+msgstr "Mentés"
+
+#: views/users/login.thtml:93
+msgid "user_form_submit_login"
+msgstr "Bejelentkezés"
+
+#: views/users/register.thtml:113
+msgid "user_form_submit_register"
+msgstr "Regisztrálás"
+
+#: views/users/info.thtml:75
+#, php-format
+msgid "user_info_usersince"
+msgstr "%s Add-ons felhasználója ezóta:"
+
+#: views/users/login.thtml:102
+msgid "user_login_register_link"
+msgstr "Új felhasználói fiók létrehozása"
+
+#: views/users/edit.thtml:160
+msgid "user_notifications_item_compat"
+msgstr "Kiegészítő kompatibilitása (nagyon ajánlott)"
+
+#: views/users/edit.thtml:161
+msgid "user_notifications_item_events"
+msgstr "Soron következő események és versenyek"
+
+#: views/users/edit.thtml:156
+msgid "user_notifications_none_available"
+msgstr "Jelenleg nincsenek konfigurálható értesítések."
+
+#: views/users/edit.thtml:158
+msgid "user_notifications_select_topics"
+msgstr ""
+"A Mozilla időként küldhet e-mailt a soron következő kiadásokról és a "
+"kiegészítőket érintő eseményekről. Válassza ki az Önt érdeklő témákat:"
+
+#: views/users/edit.thtml:164
+msgid "user_notifications_specific_contact"
+msgstr ""
+"A Mozilla fenntartja a jogot, hogy egyénileg felvegye Önnel a kapcsolatot, "
+"ha aggasztónak találja az Ön által beküldött kiegészítőket."
+
+#: controllers/users_controller.php:543
+msgid "user_profile_edit_error"
+msgstr "Hibák voltak a módosításokban. Javítsa ki őket, és küldje újra."
+
+#: controllers/users_controller.php:540
+msgid "user_profile_saved"
+msgstr "A profil frissítve lett."
+
+#: views/users/pwreset.thtml:65
+#, php-format
+msgid "user_pwreset_for_email"
+msgstr "%s jelszavának törlése"
+
+#: controllers/users_controller.php:226
+msgid "user_pwreset_header"
+msgstr "Jelszó törlése"
+
+#: views/users/login.thtml:103
+msgid "user_pwreset_link"
+msgstr "Elfelejtette a jelszavát?"
+
+#: controllers/users_controller.php:248
+msgid "user_pwreset_link_sent"
+msgstr "A jelszót törlő hivatkozást e-mailben küldtük el."
+
+#: controllers/users_controller.php:304
+msgid "user_pwreset_okay"
+msgstr "A jelszó törlése sikeresen megtörtént."
+
+#: views/users/pwreset.thtml:82
+msgid "user_pwreset_submit_changepw"
+msgstr "Jelszómódosítás beküldése"
+
+#: views/users/pwreset.thtml:57
+msgid "user_pwreset_submit_sendlink"
+msgstr "Jelszót törlő hivatkozás küldése"
+
+#: views/users/register_complete.thtml:51
+#, php-format
+msgid "user_register_amo_link"
+msgstr "%s kiegészítők"
+
+# %1 is the user's email address, %2 is the current app
+#. %1 is the user's email address, %2 is the current app
+#: views/users/activatefirst.thtml:49
+#, php-format
+msgid "user_register_click_confirm_link"
+msgstr ""
+"A felhasználói fiókot aktiváló hivatkozást e-mailben küldtük el a(z) %1$s "
+"címre. Rá kell kattintania, mielőtt bejelentkezhetne a %2$s Add-ons "
+"webhelyre."
+
+# %1 is the user's email address
+#. %1 is the user's email address
+#: views/users/register_complete.thtml:49
+#, php-format
+msgid "user_register_confirm_email_sent"
+msgstr ""
+"A felhasználói fiókot aktiváló hivatkozást e-mailben küldtük el a(z) %1$s "
+"címre. Az első bejelentkezés előtt aktiválnia kell a fiókját az e-mailben "
+"küldött hivatkozásra való kattintással."
+
+#: views/users/activatefirst.thtml:51
+msgid "user_register_confirmation_link_text"
+msgstr "megerősítő üzenet újra elküldésére"
+
+#: views/users/register_complete.thtml:47
+msgid "user_register_congratulations"
+msgstr "Gratulálunk! A felhasználói fiók sikeresen létrejött."
+
+#: views/users/register.thtml:50
+#, fuzzy
+msgid "user_register_details"
+msgstr ""
+"<p>Registration on AMO is <strong>not required</strong> if you simply want "
+"to download and install public add-ons.</p><p>You only need to register if:</"
+"p><ul><li>You want to submit reviews for add-ons</li><li>You are an add-on "
+"developer and want to upload your add-on for hosting on AMO</li></ul><p>Upon "
+"successful registration, you will be sent a confirmation email to the "
+"address you provided. Please follow the instructions there to confirm your "
+"account.</p><p>If you like, you can read our <a href='%1$s' title='Legal "
+"Notices'>Legal Notices</a> and <a href='%2$s' title='Privacy Policy'>Privacy "
+"Policy</a>.</p>"
+
+# %1 is the link to the "resend confirmation code" page
+#. %1 is the link to the "resend confirmation code" page
+#: views/users/activatefirst.thtml:51
+#, php-format
+msgid "user_register_resend_confirmation_link"
+msgstr ""
+"Ha nem kapta meg a megerősítő e-mailt, ellenőrizze, hogy a levelezője nem "
+"jelölte-e meg levélszemétként vagy spamként. Ha szükséges, megkérhet minket "
+"a %1$s a fenti e-mail címre."
+
+# %1 is the link to the Mozilla Add-ons front page
+#. %1 is the link to the Mozilla Add-ons front page
+#: views/users/register_complete.thtml:51
+#, php-format
+msgid "user_register_welcome"
+msgstr "Köszönjük, hogy regisztrált, és üdvözli a %1$s!"
+
+#: views/users/register.thtml:49
+#, fuzzy
+msgid "user_register_welcome_header"
+msgstr "Welcome to addons.mozilla.org (AMO)!"
+
+#: views/users/register.thtml:81 views/users/edit.thtml:106
+msgid "user_required_firstlast_or_nickname"
+msgstr "Utónév, vezetéknév vagy becenév szükséges."
+
+#: views/users/edit.thtml:94 views/users/edit.thtml:142
+#, fuzzy
+msgid "user_tab_collections"
+msgstr "Collections"
+
+#: views/users/edit.thtml:95 views/users/edit.thtml:154
+msgid "user_tab_notifications"
+msgstr "Értesítések"
+
+#: views/users/edit.thtml:93 views/users/edit.thtml:101
+msgid "user_tab_profile"
+msgstr "Felhasználói profil"
+
+#: controllers/users_controller.php:209
+msgid "user_verified_okay"
+msgstr "Sikeresen ellenőrizve!"
+
+#: controllers/users_controller.php:723
+msgid "users_delete_pagetitle"
+msgstr "Felhasználói fiók törlése"
+
+#: controllers/users_controller.php:414
+msgid "users_edit_pagetitle"
+msgstr "Felhasználói fiók szerkesztése"
+
+#: views/users/info.thtml:71
+#, fuzzy
+msgid "users_info_aboutme"
+msgstr "About Me"
+
+#: views/users/info.thtml:96
+#, php-format
+msgid "users_info_addons_by_user"
+msgstr "%1$s kiegészítői"
+
+#: views/users/info.thtml:51
+msgid "users_info_author_name"
+msgstr "Név"
+
+#: views/users/info.thtml:48
+msgid "users_info_author_profile"
+msgstr "Felhasználói profil"
+
+#. %s is the user name
+#: views/users/info.thtml:137
+#, fuzzy
+msgid "users_info_collections_by_user"
+msgstr "Collections by %s"
+
+#: views/users/info.thtml:66
+msgid "users_info_email"
+msgstr "E-mail cím"
+
+#: views/users/info.thtml:155
+#, fuzzy
+msgid "users_info_fav_collections_by_user"
+msgstr "Favorite Collections"
+
+#: views/users/info.thtml:61
+msgid "users_info_homepage"
+msgstr "Honlap"
+
+#: views/users/info.thtml:56
+msgid "users_info_nickname"
+msgstr "Becenév"
+
+#: controllers/users_controller.php:707
+#, php-format
+msgid "users_info_pagetitle"
+msgstr "%1$s felhasználói adatai"
+
+# %1 is the user's name
+#. %1 is the user's name
+#: views/users/info.thtml:116
+msgid "users_info_reviews_by_user"
+msgstr "%s értékelései"
+
+#: controllers/users_controller.php:330 controllers/users_controller.php:332
+msgid "users_login_pagetitle"
+msgstr "Felhasználó bejelentkezése"
+
+# %1 is the link to the sandbox/policy explanation page
+# This message is for a specific add-on not found
+#. %1 is the link to the sandbox/policy explanation page
+#. This message is for a specific add-on not found
+#: views/users/login.thtml:53
+#, php-format
+msgid "users_login_sandbox_display_warning"
+msgstr ""
+"A keresett kiegészítő jelenleg a homokozóban van. Ha rendelkezik fiókkal a "
+"Mozilla Add-ons webhelyen, akkor jelentkezzen be, vagy <a href=\"%1$s"
+"\">olvassa el, hogy mi az a homokozó</a>."
+
+# %1 is the link to the sandbox/policy explanation page
+# This message is for any given sandbox-related page not found
+#. %1 is the link to the sandbox/policy explanation page
+#. This message is for any given sandbox-related page not found
+#: views/users/login.thtml:56
+#, php-format
+msgid "users_login_sandbox_page_warning"
+msgstr ""
+"A keresett oldal a homokozó része. Ha rendelkezik fiókkal a Mozilla Add-ons "
+"webhelyen, akkor jelentkezzen be, vagy <a href=\"%1$s\">olvassa el, hogy mi "
+"az a homokozó</a>."
+
+#: controllers/users_controller.php:223 controllers/users_controller.php:225
+msgid "users_pwreset_pagetitle"
+msgstr "Felhasználó jelszavának törlése"
+
+#: controllers/users_controller.php:90 controllers/users_controller.php:92
+msgid "users_register_pagetitle"
+msgstr "Új felhasználó regisztrációja"
+
+#. %1$s is an addon name, like <a>Firebug</a>
+#. %2$s is a version number, like <a>1.2</a>
+#: views/versions/license.thtml:52
+#, fuzzy
+msgid "versions_license_header_source"
+msgstr "Source code license for %1$s %2$s"
+
+#: views/addons/category_landing.thtml:147
+#, fuzzy
+msgid "view_recently_added"
+msgstr "View all recently added"
+
+#: views/addons/category_landing.thtml:161
+#, fuzzy
+msgid "view_top_downloads"
+msgstr "View all top downloads"
+
+#: views/addons/category_landing.thtml:175
+#, fuzzy
+msgid "view_top_rated"
+msgstr "View all top rated"
+
+#~ msgid "addon_slider_tooltip_next"
+#~ msgstr "Következő kiegészítő"
+
+#~ msgid "addon_slider_tooltip_previous"
+#~ msgstr "Előző kiegészítő"
+
+#~ msgid "addon_versions_getlatesttext"
+#~ msgstr "A legújabb verzió, amely még kompatibilis ezzel:"
+
+#~ msgid "addons_display_version_history"
+#~ msgstr "Teljes verziótörténet"
+
+#~ msgid "addons_home_newest_header"
+#~ msgstr "Legújabb:"
+
+#~ msgid "addons_home_popular_header"
+#~ msgstr "Legnépszerűbb:"
+
+#~ msgid "addons_home_recommended_header"
+#~ msgstr "Javasoljuk:"
+
+#~ msgid "addons_home_updated_header"
+#~ msgstr "Nemrég frissítve:"
+
+#~ msgid "addons_home_view_all"
+#~ msgstr "Összes"
+
+#~ msgid "category_extra_allrecommended"
+#~ msgstr "Minden javasolt kiegészítő megjelenítése"
+
+#~ msgid "category_extra_highestrated"
+#~ msgstr "Legjobbra értékelt felül"
+
+#~ msgid "category_extra_lastupdated"
+#~ msgstr "Utoljára frissített felül"
+
+#~ msgid "category_extra_mostpopular"
+#~ msgstr "Legnépszerűbb felül"
+
+#, fuzzy
+#~ msgid "collections_detail_js_loading"
+#~ msgstr "Loading"
+
+#, fuzzy
+#~ msgid "collections_detail_more_info"
+#~ msgstr "Show More Info"
+
+#~ msgid "devcp_additem_firefox_notice"
+#~ msgstr ""
+#~ "A kiegészítő ezen verziója nem hirdeti magáról, hogy kompatibilis lenne a "
+#~ "Firefox %1$s verzióval. A Mozilla hamarosan kiadja a Firefox következő "
+#~ "verzióját, ezért kérjük, hogy tesztelje a kiegészítőt ezzel az új "
+#~ "verzióval, és frissítse a kompatibilitási adatokat. További tudnivalókat "
+#~ "<a href=\"%2$s\">itt</a> találhat erről. Ez csak egy figyelmeztetés, "
+#~ "folytathatja ennek a verziónak a beküldését az addons.mozilla.org-ra."
+
+#~ msgid "devcp_addon_disabled_successfully"
+#~ msgstr "A kiegészítő sikeresen le lett tiltva"
+
+#~ msgid "devcp_addon_edit_pagetitle"
+#~ msgstr "Kiegészítő szerkesztése"
+
+#~ msgid "devcp_addon_enabled_successfully"
+#~ msgstr "A kiegészítő sikeresen engedélyezve lett"
+
+#~ msgid "devcp_addon_field_description_displaytitle"
+#~ msgstr "Kiegészítő leírása"
+
+#~ msgid "devcp_addon_field_eula_displaytitle"
+#~ msgstr "EULA"
+
+#~ msgid "devcp_addon_field_homepage_displaytitle"
+#~ msgstr "Kiegészítő honlapja"
+
+#~ msgid "devcp_addon_field_name_displaytitle"
+#~ msgstr "Kiegészítő neve"
+
+#~ msgid "devcp_addon_field_privacy_displaytitle"
+#~ msgstr "Adatvédelmi nyilatkozat"
+
+#~ msgid "devcp_addon_field_summary_displaytitle"
+#~ msgstr "Kiegészítő összefoglalója"
+
+#~ msgid "devcp_addon_field_supportemail_displaytitle"
+#~ msgstr "Támogató e-mail cím"
+
+#~ msgid "devcp_addon_field_supporturl_displaytitle"
+#~ msgstr "Támogató URL"
+
+#~ msgid "devcp_addon_field_versionnotes_displaytitle"
+#~ msgstr "Megjegyzések a verzióhoz"
+
+#~ msgid "devcp_addon_nominate_pagetitle"
+#~ msgstr "Kiegészítő jelölése"
+
+#~ msgid "devcp_addon_nominated_successfully"
+#~ msgstr "A kiegészítő sikeresen jelölve lett!"
+
+#, fuzzy
+#~ msgid "devcp_addon_status_criteria_review"
+#~ msgstr "Several user reviews of the add-on (may be external reviews)."
+
+# %1 is the addon edit link
+# %2 is the main dev CP link
+#~ msgid "devcp_addon_submission_makechanges"
+#~ msgstr ""
+#~ "Látogassa meg a %1$s oldalt a beküldés módosításához, vagy %2$s a "
+#~ "Fejlesztőeszközökhöz való visszatéréshez."
+
+#~ msgid "devcp_addon_submission_makechanges_devcp_link"
+#~ msgstr "kattintson ide"
+
+#~ msgid "devcp_addon_submission_makechanges_link"
+#~ msgstr "Kiegészítő szerkesztése"
+
+#~ msgid "devcp_addon_submission_pending"
+#~ msgstr ""
+#~ "Ez a verzió bekerült a homokozóba, és a homokozóban dolgozó tesztelők és "
+#~ "egy Mozilla Add-ons szerkesztő értékelésére vár. Értesítést fog kapni e-"
+#~ "mailen keresztül, ha történt valami."
+
+# %1 is the link to the sandbox information page
+#~ msgid "devcp_addon_submission_sandbox_readmore"
+#~ msgstr "%s olvashat bővebben a homokozó értékelési rendszeréről."
+
+#~ msgid "devcp_addon_submission_sandbox_readmore_link"
+#~ msgstr "Itt"
+
+# %1 is the "nominate" link
+#~ msgid "devcp_addon_submission_sandboxed"
+#~ msgstr ""
+#~ "Ez a verzió bekerült a homokozóba, ahol gyakorlott felhasználók "
+#~ "tesztelhetik. A nyilvános webhelyen megjelenéshez %s kell a "
+#~ "kiegészítőjét, hogy átmenjen egy értékelési folyamaton."
+
+#~ msgid "devcp_addon_submission_sandboxed_nominate_link"
+#~ msgstr "jelölnie"
+
+#~ msgid "devcp_addon_submission_success"
+#~ msgstr "A kiegészítő beküldése sikeresen véget ért."
+
+#~ msgid "devcp_addon_submission_trusted_public"
+#~ msgstr ""
+#~ "Mivel ez a kiegészítő megbízható, ez a verzió automatikusan jóvá lett "
+#~ "hagyva a nyilvános területen való megjelenéshez."
+
+#~ msgid "devcp_addon_submit_pagetitle"
+#~ msgstr "Kiegészítő beküldése"
+
+#~ msgid "devcp_addon_updated_successfully"
+#~ msgstr "A kiegészítő sikeresen frissítve lett"
+
+# %1 is the link to the preview upload page
+#~ msgid "devcp_addon_upload_preview"
+#~ msgstr "Fontolja meg, hogy %s megnövelje a kiegészítője iránti érdeklődést."
+
+#~ msgid "devcp_addon_upload_preview_link"
+#~ msgstr "előnézet feltöltésével"
+
+# #1 is the author email
+#~ msgid "devcp_author_lookup_none_found"
+#~ msgstr "Nem található szerző [%s]"
+
+#~ msgid "devcp_author_lookup_remove"
+#~ msgstr "Eltávolítás"
+
+#~ msgid "devcp_button_cancel"
+#~ msgstr "Mégse"
+
+#~ msgid "devcp_button_cancel_confirm"
+#~ msgstr "Biztosan megszakítja a beküldést?"
+
+#~ msgid "devcp_button_next"
+#~ msgstr "Következő"
+
+#~ msgid "devcp_change_addontype"
+#~ msgstr "Kiegészítő típusának módosítása:"
+
+#~ msgid "devcp_comments_updated"
+#~ msgstr "A fejlesztői megjegyzések frissítve lettek."
+
+#~ msgid "devcp_details_addpreview_link"
+#~ msgstr "Előnézet hozzáadása"
+
+#~ msgid "devcp_details_author"
+#~ msgstr "Szerző"
+
+#~ msgid "devcp_details_authors"
+#~ msgstr "Szerzők"
+
+#~ msgid "devcp_details_authors_none"
+#~ msgstr "Nincs"
+
+#~ msgid "devcp_details_categories"
+#~ msgstr "Kategóriák"
+
+#~ msgid "devcp_details_category"
+#~ msgstr "Kategória"
+
+#~ msgid "devcp_details_description"
+#~ msgstr "Leírás"
+
+#~ msgid "devcp_details_disabled"
+#~ msgstr "Letiltva"
+
+#~ msgid "devcp_details_guid"
+#~ msgstr "GUID"
+
+#~ msgid "devcp_details_header_details"
+#~ msgstr "Részletek"
+
+#~ msgid "devcp_details_header_devcomments"
+#~ msgstr "Fejlesztői megjegyzések"
+
+#~ msgid "devcp_details_header_previews"
+#~ msgstr "Előnézetek"
+
+#~ msgid "devcp_details_header_versions"
+#~ msgstr "Verziók"
+
+#~ msgid "devcp_details_homepage"
+#~ msgstr "Honlap"
+
+#~ msgid "devcp_details_homepage_none"
+#~ msgstr "Nincs"
+
+#~ msgid "devcp_details_preview_nocaption"
+#~ msgstr "Nincs képfelirat"
+
+#~ msgid "devcp_details_previews_nonefound"
+#~ msgstr "Nincs előnézet."
+
+#~ msgid "devcp_details_submit_update"
+#~ msgstr "Frissítés"
+
+#~ msgid "devcp_details_supportemail"
+#~ msgstr "Támogató e-mail cím"
+
+#~ msgid "devcp_details_supportemail_none"
+#~ msgstr "A fejlesztő nem adott meg támogató e-mail címet."
+
+#~ msgid "devcp_details_supporturl"
+#~ msgstr "Támogató URL"
+
+#~ msgid "devcp_details_supporturl_none"
+#~ msgstr "A fejlesztő nem adott meg támogató URL-t."
+
+#~ msgid "devcp_details_trusted"
+#~ msgstr "Megbízható"
+
+#~ msgid "devcp_details_versions_none_found"
+#~ msgstr "Nincsenek verziók."
+
+#~ msgid "devcp_disable_cancel"
+#~ msgstr "Mégse és vissza"
+
+#~ msgid "devcp_disable_disable_button"
+#~ msgstr "Igen, letiltás"
+
+#~ msgid "devcp_disable_disable_confirm"
+#~ msgstr "Biztosan letiltja ezt a kiegészítőt?"
+
+#~ msgid "devcp_disable_disable_description"
+#~ msgstr ""
+#~ "A kiegészítő letiltása azt jelenti, hogy nem jelenik meg a kereséseknél "
+#~ "és a felsorolásokban. Nem lesz letölthető a webhelyről, és nem lesz "
+#~ "javasolva az ügyfélprogramok frissítéskereséseinél. A kiegészítő "
+#~ "gyakorlatilag törölve lesz, bár később visszatérhet, és újra "
+#~ "engedélyezheti, ha szeretné."
+
+#~ msgid "devcp_disable_disable_title"
+#~ msgstr "%s letiltása"
+
+#~ msgid "devcp_disable_enable_button"
+#~ msgstr "Igen, engedélyezés"
+
+#~ msgid "devcp_disable_enable_confirm"
+#~ msgstr "Biztosan engedélyezi ezt a kiegészítőt?"
+
+#~ msgid "devcp_disable_enable_description"
+#~ msgstr ""
+#~ "A kiegészítő engedélyezése azt jelenti, hogy ismét megjelenik a "
+#~ "kereséseknél és a felsorolásokban. Letölthető lesz a webhelyről és az "
+#~ "ügyfélprogramok frissítéskereséseinél."
+
+#~ msgid "devcp_disable_enable_title"
+#~ msgstr "%s engedélyezése"
+
+#~ msgid "devcp_edit_author_add"
+#~ msgstr "Szerző hozzáadása"
+
+#~ msgid "devcp_edit_author_email"
+#~ msgstr "Szerző e-mail címe"
+
+#~ msgid "devcp_edit_author_remove"
+#~ msgstr "Eltávolítás"
+
+#~ msgid "devcp_edit_error_categories_unavailable"
+#~ msgstr "Nincsenek kategóriák ehhez a kiegészítőtípushoz."
+
+#, fuzzy
+#~ msgid "devcp_edit_file_error_incomplete"
+#~ msgstr "Incomplete transfer"
+
+#, fuzzy
+#~ msgid "devcp_edit_file_error_no"
+#~ msgstr "No file uploaded"
+
+#, fuzzy
+#~ msgid "devcp_edit_file_error_size"
+#~ msgstr "Exceeds maximum upload size"
+
+#~ msgid "devcp_edit_header_authors"
+#~ msgstr "Szerzők"
+
+#~ msgid "devcp_edit_icon_add_link"
+#~ msgstr "Ikon hozzáadása"
+
+#~ msgid "devcp_edit_icon_change_link"
+#~ msgstr "Ikon módosítása"
+
+#~ msgid "devcp_edit_label_allow_viewsource"
+#~ msgstr "A felhasználók megtekinthetik online a forrást"
+
+#~ msgid "devcp_edit_label_categories"
+#~ msgstr "Kategóriák"
+
+#~ msgid "devcp_edit_label_defaultlocale"
+#~ msgstr "Alapértelmezett területi beállítások"
+
+#~ msgid "devcp_edit_label_icon_delete"
+#~ msgstr "Csak a létező ikon törlése"
+
+#~ msgid "devcp_edit_label_icon_new"
+#~ msgstr "Új ikonfájl"
+
+#~ msgid "devcp_edit_label_info"
+#~ msgstr "Ikon"
+
+#~ msgid "devcp_edit_locale_disambiguation_explanation"
+#~ msgstr "további infók röviden (pl. a helyi dialektus neve)"
+
+#~ msgid "devcp_edit_submit_update"
+#~ msgstr "Frissítés"
+
+#~ msgid "devcp_edit_target_locale_explanation"
+#~ msgstr ""
+#~ "<a href=\"http://wiki.mozilla.org/L10n:Simple_locale_names\">területi "
+#~ "beállítás egyszerű neve</a> pl. „en-USâ€"
+
+#~ msgid "devcp_editversion_checkedfiles_delete"
+#~ msgstr "A bejelölt fájlok törölve lesznek."
+
+# %1 is the file name
+# %2 is the file size (150 KB)
+#~ msgid "devcp_editversion_filename_size"
+#~ msgstr "%1$s (%2$s)"
+
+#~ msgid "devcp_editversion_label_files"
+#~ msgstr "Fájlok"
+
+#~ msgid "devcp_editversion_label_targetapps"
+#~ msgstr "Célalkalmazások"
+
+#~ msgid "devcp_editversion_nofiles"
+#~ msgstr "Nincsenek fájlok."
+
+#~ msgid "devcp_editversion_reviewernotes"
+#~ msgstr "Megjegyzések az értékelőnek"
+
+#~ msgid "devcp_editversion_submit_update"
+#~ msgstr "Frissítés"
+
+#~ msgid "devcp_error_addon_field_summary_toolong"
+#~ msgstr ""
+#~ "Az összefoglaló legfeljebb 250 karakter lehet.\n"
+#~ "(Beírva %s)"
+
+#~ msgid "devcp_error_addonname_not_unique"
+#~ msgstr ""
+#~ "A kiegészítő neve már szerepel az adatbázisban. Győződjön meg arról, "
+#~ "hogy: <br /><li>A GUID-ok egyeznek-e. A hiba leggyakoribb oka, hogy a "
+#~ "GUID-ok nem egyeznek.</li><li>Nincs-e duplikált bejegyzés az "
+#~ "adatbázisban? Ha van, akkor frissítenie vagy törölnie kell azt a "
+#~ "bejegyzést, és újra megpróbálni.</li>"
+
+#~ msgid "devcp_error_describe_changes"
+#~ msgstr ""
+#~ "Ãrja le, hogy milyen módosítások történtek ebben a kiegészítÅ‘frissítésben."
+
+#~ msgid "devcp_error_file_guids_dont_match"
+#~ msgstr "Nem minden fájl GUID-ja egyezik"
+
+#~ msgid "devcp_error_identical_version_exists"
+#~ msgstr ""
+#~ "Ennek a kiegészítőnek ezen a platformon már van egy megegyező verziója (%"
+#~ "s)."
+
+#~ msgid "devcp_error_nominate_message"
+#~ msgstr "A jelöléshez meg kell adnia a kért részleteket."
+
+#~ msgid "devcp_error_nominate_no_prerelease"
+#~ msgstr "Egy kiegészítő előzetes kiadása nem jelölhető."
+
+#~ msgid "devcp_error_nominate_sandbox_only"
+#~ msgstr "Csak a homokozóban levő kiegészítők jelölhetők."
+
+#~ msgid "devcp_error_saving"
+#~ msgstr "Hiba történt az adatok mentése közben."
+
+#~ msgid "devcp_error_update_access_denied"
+#~ msgstr "Nincs joga frissíteni ezt a kiegészítőt."
+
+#~ msgid "devcp_file_addanother"
+#~ msgstr "Másik platformfájl hozzáadása"
+
+#~ msgid "devcp_form_author_add"
+#~ msgstr "Szerző hozzáadása"
+
+#~ msgid "devcp_form_author_remove"
+#~ msgstr "Eltávolítás"
+
+#~ msgid "devcp_form_categories_nextstep"
+#~ msgstr ""
+#~ "Az új kiegészítőtípus kategóriái a következő lépésben lesznek elérhetők."
+
+#~ msgid "devcp_form_error_categories_unavailable"
+#~ msgstr "Nincsenek kategóriák ehhez a kiegészítőtípushoz."
+
+#~ msgid "devcp_form_error_description_notempty"
+#~ msgstr "Adja meg a kiegészítőjének leírását."
+
+#~ msgid "devcp_form_error_name_required"
+#~ msgstr "Adja meg a kiegészítőjének nevét."
+
+#~ msgid "devcp_form_error_select_addontype"
+#~ msgstr "Elküldés előtt adja meg a kiegészítőjének típusát."
+
+#~ msgid "devcp_form_error_summary_notempty"
+#~ msgstr "Adjon meg egy összefoglalót a kiegészítőjéről."
+
+#~ msgid "devcp_form_label_addonfile"
+#~ msgstr "Kiegészítő fájlja"
+
+#~ msgid "devcp_form_label_addonfile2"
+#~ msgstr "Kiegészítő fájlja 2"
+
+#~ msgid "devcp_form_label_addonfile3"
+#~ msgstr "Kiegészítő fájlja 3"
+
+#~ msgid "devcp_form_label_addontype"
+#~ msgstr "Kiegészítő típusa"
+
+#~ msgid "devcp_form_label_allow_viewsource"
+#~ msgstr "A felhasználók megtekinthetik online a forrást"
+
+#~ msgid "devcp_form_label_author_email"
+#~ msgstr "Szerző e-mail címe"
+
+#~ msgid "devcp_form_label_authors"
+#~ msgstr "Szerzők"
+
+#~ msgid "devcp_form_label_categories"
+#~ msgstr "Kategóriák"
+
+#~ msgid "devcp_form_label_defaultlocale"
+#~ msgstr "Alapértelmezett területi beállítások"
+
+#~ msgid "devcp_form_label_description"
+#~ msgstr "Leírás"
+
+#~ msgid "devcp_form_label_eula"
+#~ msgstr "Végfelhasználói licencszerződés (EULA)"
+
+#~ msgid "devcp_form_label_externalsoftware"
+#~ msgstr "Ez a kiegészítő külső szoftvert igényel"
+
+#~ msgid "devcp_form_label_files"
+#~ msgstr "Fájlok"
+
+#~ msgid "devcp_form_label_homepage"
+#~ msgstr "Honlap"
+
+#~ msgid "devcp_form_label_iconfile"
+#~ msgstr "Ikonfájl"
+
+#~ msgid "devcp_form_label_name"
+#~ msgstr "Név"
+
+#~ msgid "devcp_form_label_platforms"
+#~ msgstr "Támogatott platformok"
+
+#~ msgid "devcp_form_label_prerelease"
+#~ msgstr "Ez egy előzetes kiadás"
+
+#~ msgid "devcp_form_label_privacy"
+#~ msgstr "Adatvédelmi nyilatkozat"
+
+#~ msgid "devcp_form_label_sitespecific"
+#~ msgstr "Ez egy webhelyspecifikus kiegészítő"
+
+#~ msgid "devcp_form_label_summary"
+#~ msgstr "Összefoglaló"
+
+#~ msgid "devcp_form_label_supportemail"
+#~ msgstr "Támogató e-mail cím"
+
+#~ msgid "devcp_form_label_supporturl"
+#~ msgstr "Támogató URL"
+
+#~ msgid "devcp_form_label_target_applications"
+#~ msgstr "Célalkalmazások"
+
+#~ msgid "devcp_form_label_version"
+#~ msgstr "Verzió"
+
+#~ msgid "devcp_form_label_versionnotes"
+#~ msgstr "Megjegyzések a verzióhoz"
+
+#~ msgid "devcp_form_no_target_apps"
+#~ msgstr "Nincs"
+
+#~ msgid "devcp_form_reviewernotes"
+#~ msgstr "Megjegyzések az értékelőnek"
+
+#~ msgid "devcp_form_trustedaddon_destination"
+#~ msgstr ""
+#~ "Mivel a kiegészítője megbízható, kiválaszthatja, hogy ez a verzió hova "
+#~ "kerüljön:"
+
+#~ msgid "devcp_form_trustedaddon_destination_public"
+#~ msgstr "Nyilvános"
+
+#~ msgid "devcp_form_trustedaddon_destination_sandbox"
+#~ msgstr "Homokozó"
+
+#~ msgid "devcp_header_developer_agreement"
+#~ msgstr "Fejlesztői megállapodás"
+
+#~ msgid "devcp_header_step1"
+#~ msgstr "1. lépés"
+
+#~ msgid "devcp_header_step1_upload"
+#~ msgstr "Fájl feltöltése"
+
+#~ msgid "devcp_header_step2"
+#~ msgstr "2. lépés"
+
+#~ msgid "devcp_header_step2_addondetails"
+#~ msgstr "Kiegészítő leírása"
+
+#~ msgid "devcp_header_step3"
+#~ msgstr "3. lépés"
+
+#~ msgid "devcp_header_step3_versiondetails"
+#~ msgstr "Verzió leírása"
+
+#~ msgid "devcp_header_step4"
+#~ msgstr "4. lépés"
+
+#~ msgid "devcp_header_step4_localization"
+#~ msgstr "Honosítás"
+
+#~ msgid "devcp_header_step5"
+#~ msgstr "5. lépés"
+
+#~ msgid "devcp_header_step5_success"
+#~ msgstr "Siker"
+
+#~ msgid "devcp_index_header_myaddons"
+#~ msgstr "Saját kiegészítők"
+
+#~ msgid "devcp_nominate_link_returnto_details"
+#~ msgstr "Vissza a kiegészítő leírásához"
+
+# %1 is the autodetected addon type
+#~ msgid "devcp_notice_autodetected_addontype"
+#~ msgstr "Automatikusan felismert kiegészítőtípus: %s."
+
+# %1 is the default locale name (English (US))
+# %2 is the default locale code (en-US)
+# %3 is the current page locale name (Deutsch)
+# %4 is the current page locale code (de)
+#~ msgid "devcp_notice_different_defaultlocale"
+#~ msgstr ""
+#~ "A kiegészítőhöz beállított alapértelmezett területi beállítás (%1$s [%2"
+#~ "$s]) különbözik a jelenleg kijelölt területi beállítástól (%3$s [%4$s]). "
+#~ "Az alábbi mezők kitöltéséhez használja ezt: %1$s."
+
+#~ msgid "devcp_question_addontype_incorrect"
+#~ msgstr "Helytelen?"
+
+#~ msgid "devcp_question_delete_file"
+#~ msgstr "Biztosan törli a fájlt?"
+
+#~ msgid "devcp_skip_reviewing_addon_info"
+#~ msgstr "A jelenlegi kiegészítőinformációk frissítésének kihagyása"
+
+#~ msgid "devcp_submissions_disabled"
+#~ msgstr "Jelenleg nem lehet kiegészítőket feltölteni. Jöjjön vissza később."
+
+#~ msgid "devcp_submit_accept_dev_agreement"
+#~ msgstr "Elfogadom"
+
+#~ msgid "devcp_submit_decline_dev_agreement"
+#~ msgstr "Elutasítom"
+
+#~ msgid "devcp_summary_admin_disabled"
+#~ msgstr "Ez a kiegészítőt egy adminisztrátor letiltotta."
+
+#~ msgid "devcp_summary_header_disabled"
+#~ msgstr "Letiltva"
+
+#~ msgid "devcp_summary_header_trusted"
+#~ msgstr "Megbízható"
+
+# %1 is a link to the addon submit page
+#~ msgid "devcp_summary_noaddons_submit_one"
+#~ msgstr "Nincsenek kiegészítői. Kattintson %s egy beküldéséhez."
+
+#~ msgid "devcp_summary_noaddons_submit_one_link"
+#~ msgstr "ide"
+
+# %1 is the link to the preview upload page
+#~ msgid "devcp_theme_upload_preview"
+#~ msgstr "Ne felejtsen el %s a témájához."
+
+#~ msgid "devcp_theme_upload_preview_link"
+#~ msgstr "előnézetet feltölteni"
+
+#~ msgid "devcp_version_edit_pagetitle"
+#~ msgstr "Verzió szerkesztése"
+
+#~ msgid "devcp_version_updated_successfully"
+#~ msgstr "Verzió sikeresen frissítve."
+
+#~ msgid "editors_submissiontype_new"
+#~ msgstr "Új"
+
+#~ msgid "editors_submissiontype_updated"
+#~ msgstr "Frissített"
+
+#, fuzzy
+#~ msgid "editors_th_addon_age"
+#~ msgstr "Addon Age"
+
+#~ msgid "editors_th_addontypes"
+#~ msgstr "Kiegészítőtípusok"
+
+#~ msgid "editors_th_age"
+#~ msgstr "Kor"
+
+#~ msgid "editors_th_applications"
+#~ msgstr "Alkalmazások"
+
+#~ msgid "editors_th_platforms"
+#~ msgstr "Platformok"
+
+#~ msgid "editors_th_submissiontypes"
+#~ msgstr "Beküldési típusok"
+
+#~ msgid "error_notice"
+#~ msgstr "Értesítés"
+
+#~ msgid "forum_save"
+#~ msgstr "Mentés"
+
+#, fuzzy
+#~ msgid "home"
+#~ msgstr "home"
+
+#~ msgid "nav_category_plugins"
+#~ msgstr "Bővítmények"
+
+#~ msgid "page_title_experimental_addons"
+#~ msgstr "Kísérleti kiegészítők"
+
+#~ msgid "pages_experimental_addons_backbutton"
+#~ msgstr "Vissza az előző oldalra"
+
+# %1 is page number, %2 is total page count
+#~ msgid "pagination_page_number_title"
+#~ msgstr "%1$s / %2$s oldal"
+
+#~ msgid "search_matching_addons_number"
+#~ msgid_plural "search_matching_addons_number"
+#~ msgstr[0] "%s egyező kiegészítő"
+#~ msgstr[1] "%s egyező kiegészítő"
+
+#~ msgid "statistics_rss_icon_title"
+#~ msgstr "Összesített adatok RSS-forrása"
diff --git a/site/app/locale/hu/images/sandbox-review.png b/site/app/locale/hu/images/sandbox-review.png
new file mode 100644
index 0000000..7e07795
--- /dev/null
+++ b/site/app/locale/hu/images/sandbox-review.png
Binary files differ
diff --git a/site/app/locale/hu/pages/about.thtml b/site/app/locale/hu/pages/about.thtml
new file mode 100644
index 0000000..8cc3ab8
--- /dev/null
+++ b/site/app/locale/hu/pages/about.thtml
@@ -0,0 +1,45 @@
+<h2>Mi az addons.mozilla.org?</h2>
+<p>
+ Az addons.mozilla.org (AMO) a Mozilla hivatalos weboldala, ez a Mozilla-alkalmazások kiegészítőinek otthona. A kiegészítők új funkciókat adnak hozzá a Firefox, Thunderbird, SeaMonkey és Sunbird alkalmazásokhoz. Az AMO-ról több ezer kiegészítőt tölthet le, amelyekkel megváltoztathatja az internet felhasználásának módját.
+</p>
+
+<h2>Ki készíti ezeket a kiegészítőket?</h2>
+<p>
+ KiegészítÅ‘fejlesztÅ‘k ezrei, a hobbiprogramozóktól kezdve a nagy vállalatokig. Minden nyilvános kiegészítÅ‘t elkötelezett önkéntesek csapata értékel a megjelenés elÅ‘tt. A kísérleti kiegészítÅ‘k megjelölése „kísérletiâ€, és nincsenek értékelve.
+</p>
+
+<h2>Hogyan követhetem figyelemmel, hogy mi történik az AMO-n?</h2>
+<p>
+ A <a href="http://blog.mozilla.com/addons/">blogunk</a> rendszeresen frissül, és gyakran jelentetünk meg írásokat a közösségtől. Van egy <a href="https://addons.mozilla.org/newsletter">hírlevelünk</a> is, amelyet havonta küldünk szét.
+</p>
+
+<h2>Ez jól hangzik! Hogyan kapcsolódhatok be?</h2>
+<p>
+ Sok módon bekapcsolódhat:
+</p>
+<ul>
+ <li>
+ <a href="https://wiki.mozilla.org/AMO:Editors/Applying">Legyen szerkesztő</a>. Szerkesztőink szakismeretekkel rendelkező AMO-rajongók, akik a kiegészítőket a kód minősége és a stabilitás szerint értékelik.
+ </li>
+ <li>
+ <a href="http://developer.mozilla.org/">Készítsen kiegészítőt</a>. Az AMO ingyenes tárterületet és frissítési szolgáltatást kínál, hogy nagy számú felhasználót érhessen el.
+ </li>
+ <li>
+ Mondja el az ismerőseinek! <a href="http://spreadfirefox.com/">Terjessze a Firefoxot</a>, és mondja el ismerőseinek, hogy milyen kiegészítőket használ.
+ </li>
+ <li>
+ Küldjön hibajelentéseket és javításokat. A <a href="https://bugzilla.mozilla.org/buglist.cgi?quicksearch=addons">Bugzilla</a> tartalmazza az AMO összes jelenlegi hibáját. Ha itt nem találja egy hiba leírását, küldje be, vagy küldjön javításokat.
+ </li>
+</ul>
+
+<h2>Kérdésem van</h2>
+<p>
+ A kezdéshez a legjobb hely a <a href="https://addons.mozilla.org/pages/faq"><abbr title="Gyakran ismétlődő kérdések">GYIK</abbr></a>. Ha nem találja itt a választ, akkor használja a lap alján megtalálható kapcsolatinformációkat. Egy adott kiegészítővel kapcsolatos kérdés esetén használja a kiegészítő oldalán megtalálható kapcsolatinformációkat.
+</p>
+
+<h2>Kapcsolatfelvétel</h2>
+<dl>
+ <dt> <abbr title="Internet Relay Chat">IRC</abbr>:</dt>
+ <dd><a href="irc://irc.mozilla.org/#addons">#addons</a> csatorna az irc.mozilla.org-on az általános kérdések és az értékelésekkel kapcsolatos kérdések megtárgyalására</dd>
+ <dd><a href="irc://irc.mozilla.org/#amo">#amo</a> csatorna az irc.mozilla.org-on az adminisztratív és a fejlesztési kérdések megtárgyalására</dd>
+</dl>
diff --git a/site/app/locale/hu/pages/compatibility_developer_tips.thtml b/site/app/locale/hu/pages/compatibility_developer_tips.thtml
new file mode 100644
index 0000000..553cfb8
--- /dev/null
+++ b/site/app/locale/hu/pages/compatibility_developer_tips.thtml
@@ -0,0 +1,6 @@
+<ul class="tips">
+ <li>Az információk a kiegészítők frissítéséről a %s verzióra ebben a <a href="https://developer.mozilla.org/En/Updating_extensions_for_%s">Mozilla Developer Center cikkben</a> találhatók.</li>
+ <li>Az információk a %s változásairól <a href="https://developer.mozilla.org/en/%s_for_developers">ebben a cikkben</a> találhatók.</li>
+ <li>Feliratkozhat az <a href="https://addons.mozilla.org/newsletter">about:addons hírlevélre</a> és a <a href="http://blog.mozilla.com/addons/">Mozilla Add-ons blogra</a> a további frissítésekért.</li>
+ <li>Ha a kiegészítőjének kódját nem kell módosítani ahhoz, hogy kompatibilis legyen, és a Mozilla Add-ons webhelyen tárolja, akkor online is megnövelheti a kompatibilitási maxVersion értéket új fájl feltöltése nélkül. Ehhez lépjen a <a href="%s">Fejlesztőeszközök területre</a>, vagy nézze meg az állapotát alább.</li>
+</ul> \ No newline at end of file
diff --git a/site/app/locale/hu/pages/compatibility_user_tips.thtml b/site/app/locale/hu/pages/compatibility_user_tips.thtml
new file mode 100644
index 0000000..c645019
--- /dev/null
+++ b/site/app/locale/hu/pages/compatibility_user_tips.thtml
@@ -0,0 +1,6 @@
+<ul class="tips">
+ <li>Sok kiegészítő a kód módosítása nélkül is támogatja a %s változásait, de lehetnek olyanok is, amelyeket kissé át kell írni, hogy simán menjen az új verzióra váltás. Kérjük, ne türelmetlenkedjen ez idő alatt. A kiegészítők fejlesztői a legtöbb esetben önkéntesek, és a szabadidejükben fejlesztenek.</li>
+ <li>A Mozilla nem tanácsolja a kompatibilitás ellenőrzésének kikapcsolását, mert ez súlyos problémákat okozhat a %s indításakor, és akár adatvesztés is bekövetkezhet, ha a kiterjesztés nem kompatibilis a %s új verziójával, de a használatát erőltetik.</li>
+ <li>Ha a használni próbált kiterjesztés nem kompatibilis a %s elindítása után, akkor nézze meg a webhelyén vagy a szerzőjének honlapján, hogy van-e valami hír a frissítésről.</li>
+ <li>Kereshet a %s programmal kompatibilis, hasonló funkcionalitású kiegészítőket a <a href="%s">%s-kiegészítők</a> webhelyen.</li>
+</ul> \ No newline at end of file
diff --git a/site/app/locale/hu/pages/error404.thtml b/site/app/locale/hu/pages/error404.thtml
new file mode 100644
index 0000000..9257969
--- /dev/null
+++ b/site/app/locale/hu/pages/error404.thtml
@@ -0,0 +1,16 @@
+<h1>Sajnos, a keresés eredménytelen.</h1>
+
+<p>A keresett lap vagy fájl nem található a weboldalon. Lehetséges, hogy olyan hivatkozásra kattintott, amely már nem érhető el, vagy a hivatkozás címe hibás.</p>
+
+<ul>
+<li>Ellenőrizze a beírt webcímet.</li>
+<li>Ha egy hivatkozásra kattintva jutott el ide, akkor kérjük, küldjön levelet a <a href="mailto:webmaster@mozilla.com" title="Page Not Found on Mozilla.com">webmaster@mozilla.com</a> címre. Ãrja le (angolul), hogy melyik oldalon találta a hibás hivatkozást, és igyekszünk a problémát minél hamarabb javítani.</li>
+</ul>
+
+<p>Vagy csak ugorjon át valamelyik népszerű oldalunkra.</p>
+
+<ul>
+<li>Érdekli a <a href="%1$s">legnépszerűbb kiterjesztések listája</a>?</li>
+<li>Szeretne <a href="%2$s">kiegészítőket keresni</a>? A keresést folytathatja a <a href="%2$s">keresőoldalon</a> vagy használja a fenti keresőmezőt.</li>
+<li>Ha elölről kívánja kezdeni, akkor menjen a <a href="%3$s">kiegészítők kezdőlapjára</a>.</li>
+</ul>
diff --git a/site/app/locale/hu/pages/faq.thtml b/site/app/locale/hu/pages/faq.thtml
new file mode 100644
index 0000000..dcb99bb
--- /dev/null
+++ b/site/app/locale/hu/pages/faq.thtml
@@ -0,0 +1,56 @@
+<h1>Gyakran ismétlődő kérdések</h1>
+
+<p>Ez a GYIK olyan kérdésekre ad választ az <a href="http://addons.mozilla.org">AMO webhellyel</a> kapcsolatban, amelyekre még nem található válasz a Firefox Support webhelyen. A Support webhelyen bevezető információk találhatók a <a href="http://support.mozilla.com/kb/Customizing+Firefox+with+add-ons">Firefox kiegészítőkkel való testreszabásáról</a>, valamint a következő témákról vannak ott cikkek:</p>
+
+<ul>
+ <li> Hibaelhárítás: <a href="http://support.mozilla.com/kb/Unable+to+install+add-ons">kiegészítők telepítése</a>, <a href="http://support.mozilla.com/kb/Troubleshooting+plugins">bővítmények</a> és <a href="http://support.mozilla.com/kb/Troubleshooting+extensions+and+themes">általános problémák</a>.</li>
+ <li> <a href="http://support.mozilla.com/kb/Uninstalling+add-ons">Kiegészítők eltávolítása</a> és <a href="http://support.mozilla.com/kb/Cannot+uninstall+an+add-on">eltávolítás hibaelhárítása</a>.</li>
+ <li> <a href="http://support.mozilla.com/kb/Gray+bar+below+the+status+bar">Problémás kiegészítők kezelése / a szürke sáv problémája</a></li>
+</ul>
+
+<p></p>
+
+<h2>Kérdések a kiegészítőkről</h2>
+<dl>
+<dt>Mik azok a kiegészítők?</dt>
+<dd>A kiegészítők olyan funkciókat adnak hozzá az alkalmazáshoz, amelyeket az alapesetben nem tartalmaz. A témák az alkalmazás kinézetét változtatják meg a funkcionalitás módosítása nélkül. A keresők és a szótárak/nyelvi csomagok további keresőket és nyelvek támogatását adják hozzá az alkalmazáshoz. A kiterjesztések az alkalmazás funkcionalitását bővítik, egyesek csak egy kis eszköztárat adnak hozzá, mások jelentős mennyiségű új funkciót.</dd>
+
+<dt>Könnyű telepíteni a kiegészítőket?</dt>
+<dd>Igen! A kiegészítÅ‘ket nagyon könnyű telepíteni. Ãltalában sokkal kisebbek, mint a normál alkalmazások, és nagyon gyorsan letöltÅ‘dnek. Ha nem tetszik valamelyik, ugyanolyan könnyen eltávolíthatók vagy letilthatók. Ezen kívül, ha frissítés jelenik meg valamelyik kiegészítÅ‘höz, a Firefox értesíti errÅ‘l a felhasználót, aki egy kattintással frissíthet.</dd>
+
+<dt>Hogyan kezelhető egy kiegészítő?</dt>
+<dd>A Firefoxban válassza az „Eszközök†menü „Kiegészítők†parancsát, hogy megjelenjen a Kiegészítők párbeszédpanel. Ha a kiterjesztésnek vannak speciális beállítási lehetőségei, akkor ezek a Kiegészítők ablak Kiterjesztések szakaszában láthatók. Itt végezhető el a kiegészítők letiltása és eltávolítása is. A szótárak kiterjesztésként települnek. A keresőket a keresősávon keresztül lehet kezelni.</dd>
+
+<dt>Lelassíthatják a kiegészítők a Firefoxot?</dt>
+<dd>A kiegészítők a legtöbb esetben nem okozzák a Firefox számottevő lassulását. Mindazonáltal mivel ezek is alkalmazások, a rendszer konfigurációjától függően hatással lehetnek a Firefox teljesítményére. Ha azt gyanítja, hogy egy kiegészítő hatással van Firefox futásteljesítményére, próbálja meg letiltani.</dd>
+
+<dt>Miért tiltanék le egy kiegészítőt?</dt>
+<dd>Egy kiegészítő letiltása megakadályozza azt, hogy a kiegészítő betöltődjön a Firefox indításakor, de a kiegészítő nem törlődik ettől, és a beállításai is megmaradnak. A kiegészítő ismételt engedélyezésekor abba az állapotba kerül vissza, amelyben a letiltáskor volt. Ha a kiterjesztést nem akarja törölni, csak kikapcsolni, akkor a letiltás a helyes megoldás.</dd>
+
+<dt>Hogyan készíthetek biztonsági mentést a telepített kiegészítőimről?</dt>
+<dd>Készíthet biztonsági mentést a profilkönyvtáráról, ekkor a kiegészítőiről is készül mentés. Erre a célra vannak alkalmazások független gyártóktól, például a MozBackup.</dd>
+</dl>
+
+<h2>Kérdések a webhellyel kapcsolatban</h2>
+<dl>
+<dt>Sok kiegészítőt látok, amelyek ugyanazt a funkciót nyújtják. Hogyan dönthetem el, hogy melyik a legjobb?</dt>
+<dd>Ãltalában az értékelések és a letöltések száma elég jól jellemzi a kiegészítÅ‘ minÅ‘ségét. A jó kiegészítÅ‘ket többen töltik le, mint a rosszakat. Mindazonáltal nyugodtan telepítheti mindkettÅ‘t, és eldöntheti, hogy melyiket akarja használni. Még az is lehet, hogy a kipróbálás után úgy dönt, hogy mindkettÅ‘t!</dd>
+
+<dt>Találtam egy tök jó kiegészítőt, de csak Firefox 2.x verziókkal kompatibilis. Telepíthetem Firefox 3.x alá?</dt>
+<dd>Ãltalában nem. A Firefox 3.x egy csomó új funkcióval rendelkezik, és a kiegészítÅ‘k fejlesztÅ‘inek többsége már frissítette a kiegészítÅ‘jét, hogy az támogassa a 3.x-et. Ha a kiegészítÅ‘ csak a Firefox 2-t támogatja, próbáljon meg rákeresni a kiegészítÅ‘ nevére. Sok esetben van a Firefox 3-at támogató újabb verzió ugyanazon a néven vagy hasonló néven.</dd>
+
+<dt>Telepítettem egy új témát, de szeretnék visszatérni a Firefox alapértelmezett témájához. Mit tegyek?</dt>
+<dd>Válassza az „Eszközök†menü „Kiegészítők†parancsát. Kattintson a „Témák†ikonra, majd jelölje ki az alapértelmezett témát, illetve itt választhat a telepített többi téma közül.</dd>
+
+<dt>Ha problémám van egy kiegészítővel, fordulhatok a Mozillához?</dt>
+<dd>A kiegészítők kevés kivételtől eltekintve nem a Mozilla fejlesztései, hanem a közösség készíti őket. A legjobb közvetlenül a fejlesztőnek feltenni a kérdést. A fejlesztő elérhetőségét általában megtalálhatja a kiegészítő névjegypanelén.</dd>
+
+<dt>Hogyan értékelik a kiegészítőket?</dt>
+<dd>A nyilvános kiegészítőket az odaadó és tehetséges szerkesztőcsapatunk értékeli. Ellenőrzik minden nyilvános kiegészítő kódját, és tesztelik is a kiegészítőket, hogy pontosan a leírásuknak megfelelően működnek-e.</dd>
+
+<dt>Frissítettem a Firefox 3.1-re, és a kiegészítőim nem működnek többé. Miért van ez?</dt>
+<dd>A legtöbb kiegészítőnk kompatibilis a Firefox 3.1-gyel, és napról napra több ilyen lesz. Ha a kiegészítő működött a 3.0-val de nem megy a 3.1-gyel, akkor valószínűleg már dolgoznak a problémán. Ha a kiegészítő új verziója megjelenik, a Firefox értesíteni fogja Önt a frissítési lehetőségről.</dd>
+
+<dt>Mik azok a kísérleti kiegészítők?</dt>
+<dd>A kísérleti kiegészítők általában a legújabb kiegészítők az AMO-n. Ezek a kiegészítők nem mentek még át a nyilvánossá váláshoz szükséges szerkesztői értékelési folyamaton, és a minőségük általában az előzetes kiadások minőségének felel meg. Mivel még nem lettek értékelve, nagyobb az esélye annak, hogy valami rosszul sül el, ha telepít egy ilyet.</dd>
+</dl>
diff --git a/site/app/locale/hu/pages/fashion_faq.thtml b/site/app/locale/hu/pages/fashion_faq.thtml
new file mode 100644
index 0000000..60f1078
--- /dev/null
+++ b/site/app/locale/hu/pages/fashion_faq.thtml
@@ -0,0 +1,56 @@
+<h3>Gyakran ismétlődő kérdések</h3>
+</div><!-- END branding -->
+
+<div id="content-main" class="faq">
+
+<dl>
+<dt>Mi az a Fashion Your Firefox (Firefox testreszabása)?</dt>
+<dd>A Firefox biztosítja a legtöbb lehetőséget az internetezés személyre szabására, lehetővé téve a böngésző testreszabását az egyéni webböngészési szokásokhoz. A Fashion Your Firefox egy egyszerű webalkalmazás, amely érdeklődésének és online tevékenységének megfelelően szabja testre a Firefox böngészőt. A Fashion Your Firefox segít kiválasztani az igényeinek megfelelő kiegészítőket, és lehetővé teszi a telepítésüket egyetlen kattintással.</dd>
+
+<dt>Mik azok a kiegészítők?</dt>
+<dd>A Firefox kiegészítői kis szoftverek, amelyek új jellemzőket vagy funkciókat adnak a böngészőhöz. A kiegészítők bővítik a Firefox képességeit, lehetővé teszik a böngésző igény és ízlés szerinti testreszabását. Több mint 5000 kiegészítő áll rendelkezésre ahhoz, hogy növelje a hatékonyságot, a felhasználói élményt és a kreativitást. </dd>
+
+<dt>Mit jelent a „Fashion Your Firefox�</dt>
+<dd>A Fashion Your Firefox az alkalmazás neve, amely képes testreszabni a Firefox böngészőt a mindennapi online tevékenység legjobb támogatása érdekében.</dd>
+
+<dt>A Fashion Your Firefox mindegyik Firefox-verzióval működik?</dt>
+<dd>A Fashion Your Firefox jelenleg csak a Firefox 3-mal kompatibilis. </dd>
+
+<dt>Hogyan adhatok hozzá több kiegészítőt a saját Fashion Your Firefox gyűjteményemhez?</dt>
+<dd>A Fashion Your Firefox segít végrehajtani ezt az egyszerű folyamatot – nem kell keresgélnie az igényeinek megfelelÅ‘ kiegészítÅ‘ket. Csak válassza ki a kiegészítÅ‘ket az Önt érdeklÅ‘ kategóriákból az „I want this add-on†(Kell ez a kiegészítÅ‘) gombra való kattintással, majd kattintson az alatta lévÅ‘ „Click here to install them†(Kattintson ide a telepítéshez) hivatkozásra. Ekkor a rendszer a választás megerÅ‘sítését kéri, majd a böngészÅ‘ újraindul, és a kijelölt kiegészítÅ‘k hozzá lesznek adva a Firefoxhoz anélkül, hogy egyesével kellene telepíteni Å‘ket. Ãme, kész a testreszabott böngészÅ‘!</dd>
+
+<dt>Fognak-e változni a Fashion Your Firefox által ajánlott kiegészítők?</dt>
+<dd>A Fashion Your Firefox az első kiegészítőgyűjtemény abban a sorozatban, amelynek további tagjai az év folyamán megjelennek majd.</dd>
+
+<dt>Hogyan választották ki a Fashion Your Firefox kiegészítőit?</dt>
+
+<dd>A beválogatott kiegészítők megfelelnek az alábbi feltételeknek:
+<ul>
+<li>Kerek egész funkcionalitással rendelkeznek.</li>
+<li>Könnyű használni.</li>
+<li>Népszerű a kategóriájában.</li>
+<li>Kompatibilis a Firefox 3-mal és a Mac/PC számítógépekkel.</li>
+</ul>
+</dd>
+
+<dt>Nem látom a kiegészítőmet a „Fashion Your Firefox†letöltése után. Hol van?</dt>
+<dd>Az egyes kiegészítők különböző helyeken jelenhetnek meg a Firefox böngészőben. Egyesek eszköztárakként vagy gombokként jelennek meg a böngészőablak felső részén, egyesek ikonként jelennek meg a böngészőablak alsó részén, míg mások a Firefox „Eszközök†menüjén keresztül érhetők el. Ha továbbra sem találja a Fashion Your Firefox alkalmazással kiválasztott kiegészítőt, akkor keressen rá az addons.mozilla.org-on, hogy az ott olvasható leírásból megtudja, hogy hol találja meg a kiegészítőt a böngészőben.</dd>
+
+<dt>Lehet-e egynél több témát telepíteni a „Decorator†kategóriából?</dt>
+<dd>Lehet egynél több témát telepíteni, de egyszerre csak egy fog megjelenni. Az témaváltáshoz válassza a Firefox „Eszközök†menüjének „Kiegészítők†parancsát, hogy megjelenjen a Kiegészítők párbeszédpanel. A felső sávon kattintson a „Témák†ikonra, majd kattintson a használni kívánt témára, és kattintson a „Téma használata†gombra.</dd>
+
+<dt>Hogyan távolíthatok el egy kiegészítőt a gyűjteményemből?</dt>
+<dd>Egy kiegészítő vagy téma eltávolításához válassza Firefox „Eszközök†menüjének „Kiegészítők†parancsát, hogy megjelenjen a Kiegészítők párbeszédpanel. Kattintson az eltávolítani kívánt kiegészítőre vagy témára, majd válassza az „Eltávolítás†gombot. A böngésző újraindítása után a nem kívánt téma vagy kiegészítő el lesz távolítva.</dd>
+
+<dt>Milyen nyelveket támogat a Fashion Your Firefox?</dt>
+<dd>Jelenleg a Fashion Your Firefox csak angolul érhető el, de azon dolgozunk, hogy más nyelveken is elérhető legyen. </dd>
+
+<dt>Lehetséges-e egyszerűen megosztani a Fashion Your Firefox kiegészítőgyűjteményét az ismerőseimmel?</dt>
+
+<dd>Jelenleg nem lehet megosztani a Fashion Your Firefox kiegészítőgyűjteményét az ismerősökkel, de elképzelhető, hogy a jövőben lehetséges lesz.</dd>
+
+<dt>Hogyan kaphatok további segítséget a Fashion Your Firefox használatával kapcsolatban?</dt>
+<dd>Ãltalános támogatásért látogasson el a Mozilla támogató webhelyére, a <a href="http://support.mozilla.com/">support.mozilla.com</a> webhelyre. A kiegészítÅ‘kkel kapcsolatos támogatásért látogasson el az <a href="http://addons.mozilla.org/">addons.mozilla.org</a> webhelyre.</dd>
+
+</dl>
+</div>
diff --git a/site/app/locale/hu/pages/nomination.thtml b/site/app/locale/hu/pages/nomination.thtml
new file mode 100644
index 0000000..45ed65e
--- /dev/null
+++ b/site/app/locale/hu/pages/nomination.thtml
@@ -0,0 +1,10 @@
+<p>Egy homokozóban levő kiegészítőt lehet jelölni arra, hogy a nyilvános webhely részévé váljon, és minden felhasználó számára elérhető legyen. Ehhez egy szerkesztői értékelésre van szükség. A legjobb eredmény érdekében a következőket jegyezze meg:</p>
+<ul>
+ <li>A témákhoz kötelező az előnézeti kép, a többi kiegészítőtípushoz ajánlott.</li>
+ <li>A kiegészítőnek elég időt el kell töltenie a homokozóban, hogy elég felhasználói értékelés és visszajelzés gyűljön össze. <b>A nyilvánossá váláshoz kötelezőek az értékelések.</b></li>
+ <li>A nyilvános kiegészítők minőségével szemben támasztott követelmények magasabbak, mint a homokozóban levő kiterjesztéseknél, és követelmény, hogy segítse a webböngészést.</li>
+ <li>A jelölés teljes feltételrendszere az <a href="%s">Irányelvek a kiegészítőkhöz</a> oldalon található.</li>
+</ul>
+<p>Ha a kiegészítő megfelel ezeknek a feltételeknek, akkor jelölheti az alábbi mező kitöltésével. A jelölés állásáról e-mailen keresztül fog értesítést kapni.</p>
+
+<p>A kiegészítő jelöléséhez írja le a tesztelés módját (beleértve azt is, hogy hibáktól és figyelmeztetésektől mentes), és hogy mi a haszna az internetező nagyközönség számára. Külső értékelésekre mutató hivatkozásokat is megadhat.</p>
diff --git a/site/app/locale/hu/pages/policy.thtml b/site/app/locale/hu/pages/policy.thtml
new file mode 100644
index 0000000..ac6a32c
--- /dev/null
+++ b/site/app/locale/hu/pages/policy.thtml
@@ -0,0 +1,110 @@
+<h1>Irányelvek a kiegészítőkhöz</h1>
+
+<h2>Mi az a homokozó?</h2>
+<p>Lásd %s.</p>
+
+<h2>Milyen kiegészítők vannak a homokozóban?</h2>
+<p>Minden AMO-n tárolt kiegészítő a homokozóban kezdi az életét. Itt vannak a nyilvános kiegészítők új verziói és a még nem nyilvános kiegészítők minden verziója. Amikor új kiegészítőt vagy egy meglévő kiegészítő frissítését beküldik az AMO-ra, az a homokozóba kerül.</p>
+
+<p>Egyes kiegészítők és adott verzióik nyilvánossá válnak az értékelési folyamat után, ami azt jelenti, hogy készen állnak és megfelelőek a nyilvános megjelenésre. Más kiegészítők határozatlan ideig a homokozóban maradnak, és onnan érhetők el az olyan felhasználók számára, akik a homokozóban is böngésznek, és szeretnek kísérletezni az ott található szoftverekkel.</p>
+
+<h2>Hogyan válik nyilvánossá egy kiegészítő?</h2>
+
+<p>A kiegészítőket azok az AMO-felhasználók értékelik, akik jelentkeztek a homokozó figyelésére és az ott található csomagok tesztelésére. Az AMO-felhasználók által írt értékelések jelezni fogják, hogy a kiegészítő elég hasznos-e, elég jól van-e megírva és eléggé kidolgozott-e ahhoz, hogy a Firefox-felhasználók elé kerülhessen. Ezek az értékelések és az AMO munkatársai által esetlegesen elvégzett további értékelések és vizsgálatok alapján meghatározható, hogy az adott kiegészítő nyilvánossá válhat-e, több munkára van-e szükség a kidolgozásához, vagy nem alkalmas a homokozón kívüli megjelenésre.</p>
+
+<h2>Hogyan jelölhetem nyilvánosnak a kiegészítőmet?</h2>
+
+<p>Ha úgy gondolja, hogy a kiegészítője (és a viselkedése!) megfelel a nyilvános kiegészítők feltételeinek, akkor a fejlesztőeszközöknél jelölheti azt.</p>
+
+<h2>Milyen feltételeknek vonatkoznak a nyilvános kiegészítőkre?</h2>
+
+<p>Az AMO-n nyilvánosságra hozott kiegészítőknek jó minőségűeknek kell lenniük, és növelniük kell a webböngészés élményét. A következő dolgokat figyeljük, miközben eldöntjük, hogy egy kiegészítő megfelelő-e az AMO nyilvános részére:</p>
+
+<h3>Gyorsan válaszol?</h3>
+
+<p>Elvárjuk, hogy a szerző, aki a kiegészítőjét a Firefox nagy számú felhasználója számára elérhetővé kívánja tenni, gyorsan reagáljon a hibajelentésekre, karbantartsa a kapcsolattartáshoz szükséges adatait, és azonnal frissítse a kiegészítőjét az újonnan megjelenő Firefox-verzióknak és az AMO szabályváltozásainak megfelelően. Ez nem azt jelenti, hogy minden kérdésre válaszolni kell, amit valaki feltesz egy fórumban, és nem kell minden hibát kijavítani, de elvárjuk, hogy a problémákra a probléma súlyának megfelelően adjon választ.</p>
+
+<h3>Világosan és pontosan van-e leírva a kiegészítő?</h3>
+
+<p>A legfontosabb dolog számunkra, hogy egy új kiegészítő kipróbálásakor a felhasználók azt kapják, amit várnak. A leírásnak részletesen ki kell térnie arra, hogy mi a kiegészítő funkciója, milyen előnnyel jár a felhasználó számára, és mit várhat a felhasználó, ha telepíti. Elfogadhatók külső dokumentációra mutató hivatkozások is, de a leírásnak magának is tartalmaznia kell az alapvető információkat, hogy a felhasználó biztos lehessen abban, hogy mit fog kapni.</p>
+
+<p>Emellett az is fontos, hogy megfelelően karbantartsa a verzióinformációkat, ahogy fejleszti és módosítja a kiegészítőt. A felhasználóknak látniuk kell, hogy mik az újdonságok az előzőleg kipróbált kiegészítőben, és tudniuk kell azokról a változásokról, amelyek befolyásolhatják a jelenleg használt kiegészítő viselkedését a frissítés után. (Jelenleg a felhasználók nem látják a verzióinformációkat, amikor a böngésző figyelmezteti őket a frissítésre, de ezt javítani szeretnénk. Ha jól tartja karban a verzióinformációkat, akkor az a felhasználók hasznára válik már most is, de a jövőben mindenképp.)</p>
+
+<h3>Minden adatvédelmi és biztonsági aggodalom el van-e oszlatva?</h3>
+
+<p>Ez tulajdonképpen beleértendő a világos és pontos leírás feltételébe, de olyan fontos, hogy önmagában is külön hangsúlyozzuk. Sok hasznos és jól megírt kiegészítő dolgozik valamilyen felhasználói adattal, vagy jelent biztonsági kockázatot helytelen használat esetén. Ezek a kiegészítők szívesen látottak az AMO nyilvános részén, de nagyon világosan fel kell hívni a felhasználók figyelmét, hogy milyen kockázatnak teszik ki magukat, és hogyan védhetik meg magukat.</p>
+
+<h3>Tesztelve van-e a kiegészítő, mentes-e nyilvánvaló vagy súlyos hibáktól?</h3>
+
+<p>Az egyik fontos dolog, amit figyelembe veszünk egy kiegészítő nyilvánossá tételekor, hogy a homokozóban írt értékelésekből az derül-e ki, hogy a kiegészítőt alaposan tesztelték, és nincsenek vele súlyos gondok, vagy nincs negatív hatása a böngészőre. Ha az értékelők problémákról számolnak be, például teljesítménycsökkenésről, összeomlásról, a kiegészítő funkcióinak gyakori problémáiról, vagy rengeteg hibakonzolra kiírt üzenetről, akkor ezeket a hibajelentéseket vegye komolyan, és akkor jelölje újra a kiegészítőt, ha ezeket a legjobb tudása szerint megoldotta. Nem várjuk el, hogy a kiegészítő tökéletes vagy hibátlan legyen – maga a Firefox is álladóan fejlődik e tekintetben –, de azt szeretnénk, hogy az ésszerűség határain belül tegyen meg mindent a hibák javításáért, és világosan jelölje meg azokat az eseteket, ahol a felhasználókat meglepetés érheti a megmaradt hibák miatt.</p>
+
+<p>Ha a kiegészítőt az AMO homokozón kívül tesztelték, például a szolgáltatását használó felhasználócsoport vagy egy belső tesztelőcsoport, akkor ezt jelezze a jelölési üzenetben. Ez mindenképpen segít megállapítani, hogy milyen szintű tesztelés zajlott le, és segíthet a kiegészítőt a webhelyre juttatni.</p>
+
+<h3>A kiegészítő és a kiegészítő szerzője tisztelettel bánik-e a felhasználóval?</h3>
+
+<p>A szoftver ne alkalmatlankodjon szükségtelenül, ne próbálja becsapni a felhasználót, és ne rejtse el a tevékenységét a felhasználó elől. A felhasználók (és mások is) időnként durván nyilvánulnak meg a hozzászólásaikban. Bár mindent megteszünk az ilyen hozzászólások azonnali törlése érdekében, ahogy erről értesítést kapunk, elvárjuk, hogy a szerzők tartózkodjanak a durva viszontválasztól.</p>
+
+<h3>A kiegészítő hasznos-e a Firefox-felhasználók kellően nagy része számára?</h3>
+
+<p>Nem szükséges, hogy a kiegészítő összemérhető legyen a Greasemonkey-val vagy a FireBuggal, de ha csak a munkatársai vagy egy kis webes közösség számára hasznos, akkor valószínűleg úgy fogunk dönteni, hogy még nem alkalmas arra, hogy az összes Firefox-felhasználó számára megjelenjen.</p>
+
+<p>Folyamatosan gondolkodunk a webhely elrendezésének fejlesztésén, hogy jobban elhelyezhessük a kivételes minőségű, de csak kevés felhasználót érdeklő kiegészítőket. A kiegészítő jó kategorizálása és a metaadatainak karbantartása segít abban, hogy az ilyen típusú kiegészítőket jobban megjeleníthessük azon felhasználók felé, akiknek hasznára válhatnak.</p>
+
+<p>Ha a kiegészítője csak könyvjelzőket vagy más, egyszerű elérési lehetőségeket biztosít a saját webhelyére, akkor valószínűleg nem megfelelő a webhely nyilvános részére. A Mozilla projekt többi részéhez hasonlóan nagyon szeretjük a webalkalmazásokat és az új webszolgáltatásokat, de a Firefox kiegészítőinek jobbá kell tenniük a böngészés élményét, nem elég az, hogy egy új webhelyet vagy szolgáltatást reklámoznak az AMO-n keresztül. Ha a kiegészítő leírásában több szó esik a szolgáltatásról, mint a felhasználó böngészési élményének javításáról, akkor valószínűleg tévúton jár.</p>
+
+<h3>A kiegészítő mentes-e a nem licencelt védjegyektől vagy szerzői joggal védett elemektől?</h3>
+
+<p>Meglehet, hogy nem okoz kárt a védjegy vagy a szerzői joggal védett alkotás jogtulajdonosának, ennek ellenére nem fogadunk el olyan kiegészítőt, amely védjegyet vagy szerzői jogot sért. Ha nincs engedélye használni egy védjegyoltalom alá eső nevet vagy képet, akkor ne küldje be a kiegészítőt az AMO-ra. Ha a kiegészítő olyan kódot tartalmaz, amelynek a szerzői joga másé, és Önnek nincs licence a felhasználásra a kiegészítőjében, akkor ne küldje be a kiegészítőt az AMO-ra. (Ha egy védjegy vagy egy szerzői joggal védett alkotás tulajdonosa ellenzi a védjegy felhasználását, akkor valószínűleg ügyvédhez kell fordulnunk az eltávolítás kérdésével, és el fogjuk távolítani a kiegészítőt, ha jogilag erre van szükség. Mivel ez költséges folyamat, erőforrásokat von el a projekttől, például időt és pénzt, kérjük, legyen körültekintő, és kíméljen meg minket ezektől a nehézségektől.)</p>
+
+<p>Ha nem biztos abban, hogy a kiegészítő neve, vagy valaminek a felhasználása a kiegészítőben akadálya-e az AMO-re való befogadásnak, kérhet tanácsot az amo-editors@mozilla.org címen. FONTOS: Ne feledje, hogy ez a csoport nem tud jogi tanácsot adni, és akkor is, ha úgy érezzük, hogy a felhasználás elfogadható, ezt a döntést megváltoztathatjuk a jogtulajdonosok panaszainak és az ügyvédünk tanácsainak hatására.</p>
+
+<p>Ami más kiegészítőkből származó forráskód újrafelhasználását illeti, ha a szerző nem nyilatkozott egyértelműen a kód újrafelhasználhatóságáról – például nyílt forrású licenc alatt adta ki – akkor azt kell feltételeznie, hogy ehhez nincs joga. Felveheti a kapcsolatot a szerzővel, hogy engedélyt kérjen, de nem adhatunk különleges jogokat csak azért, mert a kód az AMO-n van, vagy mert a szerző nem válaszol a kérésre. (Ismét hangsúlyozzuk, hogy nem adhatunk jogi tanácsot, csak arra vonatkozóan adunk tanácsot, hogy a kiegészítője hogyan felelhet meg a webhely irányelveinek.)</p>
+
+<p>Mindez a Mozilla Foundation védjegyeire is vonatkozik, beleértve a „Mozillaâ€, „Firefox†és „Thunderbird†neveket. A Mozilla védjegyekkel kapcsolatos irányelvei azt a célt szolgálják, hogy védjenek a félreértések ellen, és megvédjék a védjegyet a visszavonástól a védelem hiánya miatt. Kérjük, tartsa tiszteletben ezt a védelmet, és segítsen megtartani a Mozilla Foundation legértékesebb javait.</p>
+
+<h2>Mi történik, miután jelölök valamit?</h2>
+
+<p>A kiegészítő jelölése után azt az AMO szerkesztőcsoportja értékeli a fenti szempontok szerint. Ha a döntés az, hogy a kiegészítő készen áll a nyilvánossá tételre, akkor kikerül a nyilvános webhelyre az értékelés után, és a szerző értesítést kap e-mailben.</p>
+
+<p>Ha úgy érezzük, hogy a kiegészítő még nem áll készen az AMO nyilvános részén való megjelenésre, akkor kap egy levelet arról, hogy miért, és a jelölés a várósorból eltávolításra kerül. Amikor úgy érzi, hogy az értesítésben leírt problémákat megoldotta, és szeretné az ismételt értékelést, ezt megteheti. A kiegészítő értelmes javítások nélküli megismételt jelölése nem remélhet kedvező elbírálást, ezért kérjük, legyen belátó. Ebbe nem fáradunk bele, sokkal inkább felbosszant minket.</p>
+
+<h2>Jelölhetem más kiegészítőjét?</h2>
+
+<p>Jelenleg azt kérjük, hogy csak a kiegészítő szerzője jelölje a saját munkáját nyilvánossá tételre. Biztosak szeretnénk lenni abban, hogy a szerzőnek nincs ellenére a megnövekedett érdeklődés, és úgy érzi, hogy a kiegészítő a jelen állapotában megfelelően tükrözi a munkájának minőségét. Ha úgy gondolja, hogy a kiegészítő kidolgozott, a szerző megfelel az AMO-irányelvek betűjének és szellemének, és előnyére válik a Firefoxnak, a felhasználóinknak és a webnek általában, ha elérhetővé tesszük közel százmillió felhasználó számára világszerte, akkor bátran biztassa a kiegészítő szerzőjét, hogy jelölje művét.</p>
+
+<h2>A kiegészítőm régóta a jelölési várósorban van, utálnak engem?</h2>
+
+<p>Nem, nem utáljuk Önt. Nagyon szeretjük a kiegészítők fejlesztőit, és minden megteszünk, hogy boldogok és termelékenyek legyenek, ezáltal a felhasználók világszerte részesüljenek munkájuk gyümölcséből. Azonban az AMO nyilvános részén szerepelni pont azért értékes, mert odafigyelünk arra, hogy mi kerülhet oda, tehát nem kapkodhatjuk el a folyamatot, hogy gyorsabban végezzünk. Tudjuk, hogy frusztráló lehet sokat várni a kiegészítő értékelésére, és szeretnénk ezt az időt a lehető legrövidebbre leszorítani. Minél több ember ír alapos és világos értékelést a kiegészítőkről a homokozóban, annál könnyebben elvégezhető ez az értékelés. Amennyiben hajlandó rá, ebben várjuk az Ön segítségét is.</p>
+
+<h2>Súlyos hibát találtam a kiegészítőmben, nagyon gyorsan ki akarom adni a javítást. Mit tegyek?</h2>
+
+<p>Ha súlyos hibát (biztonság, stabilitás, súlyos funkcióbeli hiba) vesz észre a kiegészítőben, és azonnal frissíteni kell, jelezze ezt az értékelőnek szánt megjegyzés mezőben a frissítés beküldésekor, és természetesen a verzióinformációkban is. Jó lenne, ha a kiegészítő néhány jelenlegi felhasználóját rá tudná venni, hogy teszteljék a frissítést, és írják meg részletesen a tapasztalataikat a homokozóban. Az irc.mozilla.org #addons csatornáján értesítheti az embereket a helyzetről, de kérjük, legyen türelmes és udvarias.</p>
+
+<p>Ne kiáltson farkast! Megpróbálunk gyorsan reagálni a nagy fontosságú frissítésekre, de ez más jelölt kiegészítő vagy verzió értékelése, illetve gyakran az alvás és a családdal vagy a barátokkal töltött idő rovására megy, ezért rossz szemmel nézünk az olyan emberre, aki ezt a módszert választja a sorban előretolakodásra. Ha nem biztos abban, hogy ezt az utat kell választania, kérdezze meg az irc.mozilla.org #addons csatornáján, talán tudunk segíteni a döntésben.
+
+<h2>Azt hiszem, hogy nem igazságosan értékelték a kiegészítőmet. Mit tegyek?</h2>
+
+<p>Ha úgy gondolja, hogy a kiegészítőjét nem megfelelően értékelték, és tévedésből tagadták meg tőle a nyilvános státuszt, akkor küldjön e-mailt az amo-editors@mozilla.org címre részletes indoklással. Kérjük, legyen udvarias és fogalmazzon világosan. Feltétlenül térjen ki arra, hogy miért volt helytelenül megítélve a kiegészítő.</p>
+
+<p>(Ha az értesítő levélben szereplő *minden* hibát kijavított, akkor nem kell megfellebbeznie az értékelést, hanem ehelyett jelölje újra a kiegészítőt a Fejlesztőeszközök segítségével.)</p>
+
+<h2>A kiegészítőm nyilvános volt, de most csak a homokozóban van meg. Mi történt? </h2>
+
+<p>Ha egy kiegészítő nem felel meg többé a nyilvános webhelyen szereplés feltételeinek, akkor visszakerülhet a homokozóba. Hacsak nincs jogi akadálya, e-mailben értesíteni fogjuk erről, ha ez megtörténik, és meg is indokoljuk a döntést.</p>
+
+<p>Az is lehet, hogy talált egy hibát a webhelyen. Ebben az esetben ezt be kell jelenteni a Bugzillába az „addons.mozilla.org†termék „Public Pages†komponense alá. Ãrjon minél több részletet.</p>
+
+<h2>A kiegészítőm nyilvános, és a felhasználók kedvelik. Hogyan kerülhet fel a javasolt kiegészítők listájára?</h2>
+
+<p>Ha úgy gondolja, hogy a kiegészítője a kiegészítők hatékonyságának ékes példája, bemutatja és továbbviszi a Mozilla értékeit, miszerint a web legyen kiterjeszthető és felhasználó által vezérelt, és nagyszerű felhasználói élményt nyújt, akkor kérheti, hogy felkerülhessen a javasolt kiegészítők listájára. Ehhez küldjön egy e-mailt az amo-editors@mozilla.org címre, és írja le, hogy miért tartja jónak a kiegészítőjét.</p>
+
+<p>A levélnek tartalmaznia kell <b>legalább</b> az alábbi információkat:</p>
+<ul>
+<li>hogyan javul a webes felhasználói élmény</li>
+<li>miért alkalmas a kiegészítő nagy számú Firefox-felhasználó számára</li>
+<li>a kiegészítő hogyan mutatja be és/vagy szolgálja a Mozilla projekt értékeit, különösen a felhasználó felelősségével, az adatvédelemmel és biztonsággal, a web univerzális elérésével, valamint a nyílt szabványokkal és adatokkal kapcsolatban</li>
+<li>miben különbözik a kiegészítő a többi hasonló kiegészítőtől (miben jobb, miben rosszabb)</li>
+<li>milyen reakciók érkeztek a felhasználóktól, értékelőktől, bloggerektől, űrhajósoktól vagy a háziállataitól, pozitív és negatív egyaránt</li>
+</ul>
+
+<p>Minél teljesebb a kérésben rendelkezésre bocsátott információ, annál valószínűbb, hogy teljesítjük a kérést, habár egy csodásan megírt és teljes alkalmazás sem kerül fel garantáltan a javasolt kiegészítők listájára. Végső soron ezt a listát a Mozilla tartja karban, és a felhasználói élmény és a védelem a legfontosabb szempontok.</p>
diff --git a/site/app/locale/hu/pages/reviewguide.thtml b/site/app/locale/hu/pages/reviewguide.thtml
new file mode 100644
index 0000000..d21cb06
--- /dev/null
+++ b/site/app/locale/hu/pages/reviewguide.thtml
@@ -0,0 +1,66 @@
+<h1>Értékelési útmutató</h1>
+<p>A kiegészítők értékelése lehetőséget ad a webhely felhasználói számára, hogy az általuk telepített és használt kiegészítőkről véleményt mondjanak. A szerkesztők fenntartják a jogot arra, hogy elutasítsák vagy eltávolítsák azokat az értékeléseket, amelyek nem felelnek meg ennek az útmutatónak.</p>
+
+<div class="corner-box">
+ <h2>Néhány tanács jó értékelés írásához</h2>
+
+<h3><b>Javasoljuk:</b></h3>
+<ul>
+<li>Ãrjon úgy, mint ha egy barátjában mesélné el a kiegészítÅ‘vel szerzett tapasztalatait.</li>
+<li>Az értékelés legyen tömör és könnyen érthető.</li>
+<li>Térjen ki például a következőkre:
+<ul>
+ <li>A kiegészítő az elvárásoknak megfelelően működött?</li>
+ <li>Mi tetszett vagy mi nem tetszett?</li>
+ <li>Hasznos volt?</li>
+ <li>Könnyen használható volt?</li>
+ <li>Használni fogja továbbra is a kiegészítőt?</li>
+</ul></li>
+
+<li>Beküldés előtt olvassa át az értékelését, hogy ne legyen benne zavaró helyesírási vagy nyelvtani hiba.</li>
+
+<li>Kerülje az utalásokat a napi aktualitásokra, mert az értékelések hosszú ideig fennmaradhatnak a webhelyen.</li>
+</ul>
+
+<h3><b>Nem szabad:</b></h3>
+<ul>
+<li>Ne küldjön be indoklás nélküli egyszavas értékeléseket, például „jóâ€, „rossz†stb.</li>
+<li>Ne írjon hibajelentéseket az értékelésbe. Erre használja a kiegészítőhöz mellékelt támogatási lehetőségeket.</li>
+<li>Ne írjon értékelést olyan kiegészítőről, amelyet nem próbált ki.</li>
+<li>Ne használjon trágár, közönséges szavakat, és ne írjon gyűlöletkeltő dolgokat.</li>
+<li>Ne használjon HTML-t, ne helyezzen el hivatkozásokat rosszindulatú programokra, ne tegyen be forráskódot vagy forráskódrészletet. Az értékelések csak szövegesek lehetnek.</li>
+<li>Ne tegyen valótlan kijelentést, ne szólja le vagy sértegesse a kiegészítő szerzőit.</li>
+<li>Ne az értékelést használja arra, hogy kérje a Firefox (vagy más alkalmazás) adott verziójának támogatását.</li>
+<li>Ne adja meg a saját e-mail címét, telefonszámát vagy más személyes adatát.</li>
+<li>Ne írjon értékelést olyan kiegészítőről, amelyet Ön vagy a munkahelye írt vagy képvisel.</li>
+</ul>
+</div>
+
+<div class="corner-box">
+ <h2>Útmutató a kiegészítők osztályozásához</h2>
+
+<p>A kiegészítők osztályozásának igazságosnak kell lennie, és jeleznie kell a minőséget és a hasznosságot. Ne adjon 5 csillagot csak azért, mert tetszik, vagy 1 csillagot, mert utálja. A kiegyensúlyozott osztályzás fontos részét képezi az értékelésnek.</p>
+
+<ul>
+<li><b>5 csillag: Kitűnő.</b> Nem csak teljesen úgy működik, ahogy állítja magáról, hanem jelentősen hasznosabb, mint sok más kiegészítő. Ezt a kiegészítőt valószínűleg sokat fogja használni, és mindenkinek melegen ajánlja.</li>
+<li><b>4 csillag: Jó.</b> Hasznos és a könnyen használható, bár nem különösebben szükséges. Ez a kiegészítő ajánlott, de valószínűleg csak egyes felhasználócsoportok számára lesz érdekes.</li>
+<li><b>3 csillag: Elfogadható.</b> Lehet benne tervezési hiba és/vagy hiányzó funkciók. A meglévő problémák nem olyan súlyúak, hogy ellenjavallt legyen, és egyes felhasználók hasznosnak találhatják. Azoknak ajánlott, akiknek erre van szükségük, és hajlandók kipróbálni.</li>
+<li><b>2 csillag: Gyenge.</b> A kiegészítő rossz minőségű, nehezen használható, vagy nem azt csinálja, amit állít magáról. A használata ellenjavallt, bár egy kevés felhasználó számára jelenthet valami értéket.</li>
+<li><b>1 csillag: Rossz.</b> A kiegészítő vagy nem működik, vagy teljesen haszontalan. Nincs olyan jelentős ok, amiért valaki ki akarhatná próbálni, és javasolt teljesen kihagyni az életünkből.</li>
+</ul>
+
+<p>Nincs azzal semmi gond, ha valaki tökéletesre vagy borzalmasra értékel egy kiegészítőt, de az indoklás nem maradhat el. Indoklás nélkül a csillagok nem jelentenek semmit.</p>
+</div>
+
+<div class="corner-box">
+ <h2>Gyakran ismétlődő kérdések az értékelésekről</h2>
+
+<h3>Hogyan jelenthetek be egy problémás értékelést?</h3>
+<p>Kérjük, jelentse be vagy jelölje meg a megkérdőjelezhető értékeléseket az „Értékelés feljelentése†lehetőségre kattintva. Ezzel kérhető a moderálás. A szerkesztők az Értékelési útmutató alapján eldöntik, hogy törölni kell-e az értékelést, vagy maradhat-e a webhelyen.</p>
+
+<h3>Én vagyok a kiegészítő szerzője, válaszolhatok az értékelésekre?</h3>
+<p>Igen, a szerzők röviden válaszolhatnak az értékelésekre. A további vitát vagy viszontválaszokat egy fórumra vagy levelezőlistára kell áthelyezni.</p>
+
+<h3>Én vagyok a kiegészítő szerzője, törölhetem a kedvezőtlen értékeléseket vagy osztályzatokat?</h3>
+<p>Ãltalában nem, de ha az értékelés nem felel meg a fenti értékelési útmutatónak, kattinthat az „Értékelés feljelentése†lehetÅ‘ségre, és kérheti, hogy egy szerkesztÅ‘ moderálja. Ha egy értékelés olyan panaszt tartalmaz, amely már nem érvényes, mert a kiegészítÅ‘ új kiadásában javítva lett, akkor megfontoljuk az értékelés törlését. Részletes kérését küldje el az amo-editors@mozilla.org címre.</p>
+</div>
diff --git a/site/app/locale/hu/pages/sandbox.thtml b/site/app/locale/hu/pages/sandbox.thtml
new file mode 100644
index 0000000..fc2cea2
--- /dev/null
+++ b/site/app/locale/hu/pages/sandbox.thtml
@@ -0,0 +1,13 @@
+<h1>A homokozó értékelési rendszere</h1>
+<h2>Mi az a homokozó?</h2>
+<p>A homokozó a haladó szintű felhasználók területe, ahol tesztelhetők a kiegészítők az általános használatot megelőző értékelés előtt. A homokozó eléréséhez engedélyezni kell ezt a fiók beállításai között. Óvatosan kell eljárni a homokozóból telepített kiegészítőkkel, mert ezeket még nem tesztelte le egy szerkesztő, és árthatnak a számítógépnek.</p>
+
+<h2>Hogyan kerülhet át a kiegészítőm a nyilvános oldalra?</h2>
+<!-- To localize the flowchart image, see http://wiki.mozilla.org/Update:Remora_Sandbox_Flowchart -->
+<div style="text-align: center;">%s</div>
+<ol>
+ <li><b>Küldje be a kiegészítőjét a Fejlesztőeszközök segítségével.</b> A kiegészítő azonnal megjelenik a Mozilla Add-ons „Homokozó†oldalán, ahol a tapasztalt felhasználók tesztelhetik és értékelhetik. A homokozó eléréséhez engedélyezni kell ezt a fiók beállításai között.</li>
+ <li><b>Jelölje a kiegészítőjét nyilvánosnak.</b> A Fejlesztőeszközök között van egy hivatkozás, amellyel jelölhető a kiegészítő. A jelölés után a kiegészítő megjelenik értékelésre a szerkesztő jelölési várósorában.</li>
+ <li><b>Egy szerkesztő értékeli a kiegészítőt.</b> A Mozilla Add-ons egyik szerkesztője telepíti a kiegészítőt, és teszteli a működését. A szerkesztő elolvassa a homokozóban tevékenykedő tesztelők értékeléseit is.</li>
+ <li><b>A kiegészítő nyilvánossá válik, vagy a homokozóban marad.</b> A szerkesztő vagy nyilvánossá teszi a kiegészítőt, vagy a homokozóban hagyja. Ha a homokozóban maradt, akkor újra jelölhető, miután elvégezte a szerkesztő által javasolt módosításokat. Ha nyilvános lett, akkor a kiegészítő jövőbeli verziói a homokozóba kerülnek, amíg nem értékeli egy szerkesztő és nyilvánossá nem teszi. Miután a kiegészítő nyilvánossá vált, nem kell még egyszer jelölni – a jövőbeli verziók automatikusan az értékelés várósorába kerülnek.</li>
+</ol>
diff --git a/site/app/locale/hu/pages/statistics_help.thtml b/site/app/locale/hu/pages/statistics_help.thtml
new file mode 100644
index 0000000..cc40dde
--- /dev/null
+++ b/site/app/locale/hu/pages/statistics_help.thtml
@@ -0,0 +1,7 @@
+<h3>Súgó</h3>
+<p>A Statisztikák oldal a kiegészítőjéhez gyűjtött letöltési és a frissítéskeresési adatokat jeleníti meg.</p>
+<h4>Letöltések</h4>
+<p>A letöltések száma minden nap frissül, és csak az új kiegészítő-letöltéseket számolja, a frissítéseket nem.</p>
+
+<h4>Frissítések</h4>
+<p>Az erről a webhelyről letöltött kiegészítők naponta egyszer ellenőrzik, hogy jelent-e meg frissítés. Az ilyen frissítéskeresések teljes száma adja ki a napi aktív felhasználók számát. A napi aktív felhasználók száma tovább bontható a kiegészítő verziója, az operációs rendszer, a kiegészítő állapota és az alkalmazás szerint. A rendszer ezt az adatot jelenleg hetente egyszer, szerdánként jegyzi fel.</p> \ No newline at end of file
diff --git a/site/app/locale/hu/pages/submission_help.thtml b/site/app/locale/hu/pages/submission_help.thtml
new file mode 100644
index 0000000..7bbdd57
--- /dev/null
+++ b/site/app/locale/hu/pages/submission_help.thtml
@@ -0,0 +1,35 @@
+<h1>Segítség a beküldéshez</h1>
+A kötelező mezők <b>félkövérek</b>. Az opcionális mezők <i>dőltek</i>.
+<h2 id="step1">1. lépés: Feltöltés</h2>
+<ul class="submissionHelp">
+ <li><span class="required">Kiegészítő típusa</span> – Alapértelmezés szerint a kiegészítő típusa a feltöltött fájl alapján automatikusan meghatározásra kerül. Nem kell módosítania ezt a mezőt.</li>
+ <li><span class="required">Kiegészítő fájlja</span> – A kiegészítő csomagjának fájlja, amelyben benne van az install.rdf fájl is. Ha a fájl csak egy adott platformon működik, akkor a platform kiválasztásával lehetőség van egyszerre több fájl feltöltésére.</li>
+ <li><span class="optional">Ikonfájl</span> – Az ikonfájl jelenik meg a kiegészítő neve mellett a kiegészítő oldalán, és ez jelenik meg a kiegészítő telepítését végző párbeszédpanelen is. Automatikusan 32×32 képpont méretűre méreteződik át a képarány megtartásával.</li>
+ <li><span class="required">Alapértelmezett területi beállítás</span> – A kiegészítő alapértelmezett területi beállítása a fő területi beállítás. Ha a felhasználó által választott területi beállítás nem érhető el a kiegészítőhöz, akkor a fordítás az alapértelmezett területi beállítás nyelvén jelenik meg.</li>
+ <li><span class="optional">A jelenlegi kiegészítőinformációk frissítésének kihagyása</span> – Ha meglévő kiegészítőt frissít, akkor megjelenik ez a mező is. Ha bejelöli a négyzetet, akkor a 3. lépéssel folytathatja, és beírhatja a verzióspecifikus információkat.</li>
+</ul>
+
+<h2 id="step2">2. lépés: Kiegészítő leírása</h2>
+<ul class="submissionHelp">
+ <li><span class="required">Név</span> – A kiegészítő neve az alapértelmezett területi beállítás nyelvén.</li>
+ <li><span class="required">Szerzők</span> – A kiegészítő módosításának jogával rendelkező felhasználók szerzőként szerepelnek a kiegészítő oldalán.</li>
+ <li><span class="required">Kategóriák</span> – A kiegészítőre jellemző kategóriák.</li>
+ <li><span class="optional">Honlap</span> – A kiegészítő weblapja az alapértelmezett területi beállítás nyelvén.</li>
+ <li><span class="required">Összefoglaló</span> – A kiegészítő rövid összefoglalója az alapértelmezett területi beállítás nyelvén. Ez a mező legfeljebb 250 karaktert tartalmazhat, és a kiegészítő oldalán, valamint a keresési eredményekben jelenik meg.</li>
+ <li><span class="required">Leírás</span> – A kiegészítő leírása az alapértelmezett területi beállítás nyelvén. Ez fog megjelenni a kiegészítő oldalán az összefoglaló alatt.</li>
+ <li><span class="optional">EULA</span> – A végfelhasználói licencszerződés az alapértelmezett területi beállítás nyelvén, amelyet a felhasználónak el kell fogadnia letöltés előtt.</li>
+ <li><span class="optional">Adatvédelmi nyilatkozat</span> – A kiegészítő adatvédelmi nyilatkozata az alapértelmezett területi beállítás nyelvén. Az adatvédelmi nyilatkozat elmagyarázza, hogy mi történik a felhasználó személyes adataival, és a telepítést indító gomb mellé kerül a hivatkozása a kiegészítő oldalán. További információ arról, hogy mi kerüljön az adatvédelmi nyilatkozatba, és a kiegészítőjéhez szükséges-e ilyet mellékelni, az <a href="%s">Irányelvek a kiegészítőkhöz</a> oldalon olvasható el.</li>
+ <li><span class="optional"> A felhasználók megtekinthetik online a forrást</span> – Ha bejelöli ezt a négyzetet, akkor a felhasználók online böngészhetik a kiegészítő forrásfájljait.</li>
+ <li><span class="optional">Ez egy előzetes kiadás</span> – Ha bejelöli ezt a négyzetet, akkor ezzel jelzi, hogy a kiegészítő előzetes vagy „béta†kiadás. A kiegészítők előzetes kiadásainak a homokozóban kell maradniuk, és csak akkor jelölhetők nyilvánosságra hozásra, ha ez a jelzés el van távolítva.</li>
+ <li><span class="optional">Ez egy webhelyspecifikus kiegészítő</span> – Ha bejelöli ezt a négyzetet, azzal azt jelzi, hogy a kiegészítő egy adott webhelyre specifikus, például egy adott webhely kinézetét vagy megjelenített tartalmait módosítja. Ez a mező a szerkesztőket segíti, és a jövőben keresések szűkítő feltételeként lehet használható.</li>
+ <li><span class="optional">Ez a kiegészítő külső szoftvert igényel</span> – Ha bejelöli ezt a négyzetet, azzal azt jelzi, hogy ez a kiegészítő külső szoftvert igényel. Ez a mező a szerkesztőket segíti, és a jövőben keresések szűkítő feltételeként lehet használható.</li>
+</ul>
+
+<h2 id="step3">3. lépés: Verzió leírása</h2>
+<ul class="submissionHelp">
+ <li><span class="required optional">Megjegyzések a verzióhoz</span> – Az aktuális verzió módosításainak listája vagy összefoglalása. Ez a mező opcionális az új beküldéseknél, de kötelező a frissítéseknél.</li>
+ <li><span class="optional">Megjegyzések az értékelőnek</span> – Ebben a mezőben üzenhet a szerkesztőknek, akik értékelik a kiegészítőjét. Például ide kerülhetnek a tesztfiók adatai és a különleges megjegyzések.</li>
+</ul>
+
+<h2 id="step4">4. lépés: Honosítás</h2>
+Itt írhatók be a kiegészítő mezőinek fordításai az összes támogatott területi beállításhoz. Egyszerűen kattintson egy területi beállításra, és írja be a fordítást. \ No newline at end of file
diff --git a/site/app/locale/id/LC_MESSAGES/messages.mo b/site/app/locale/id/LC_MESSAGES/messages.mo
new file mode 100644
index 0000000..019917e
--- /dev/null
+++ b/site/app/locale/id/LC_MESSAGES/messages.mo
Binary files differ
diff --git a/site/app/locale/id/LC_MESSAGES/messages.po b/site/app/locale/id/LC_MESSAGES/messages.po
new file mode 100644
index 0000000..1cb7fea
--- /dev/null
+++ b/site/app/locale/id/LC_MESSAGES/messages.po
@@ -0,0 +1,8586 @@
+# translation of messages.po to Bahasa Indonesia
+# Remora Preliminary Language File
+# Copyright (C) 2006 Mozilla Corporation
+# This file is distributed under the same license as the REMORA package.
+#
+# Wil Clouser <clouserw@mozilla.com>, 2006.
+# Romi Hardiyanto <romihardiyanto@gmail.com>, 2008.
+msgid ""
+msgstr ""
+"Project-Id-Version: REMORA 0.1\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2009-01-16 11:45-0800\n"
+"PO-Revision-Date: 2009-03-10 13:12:50+0100\n"
+"Last-Translator: Romi Hardiyanto <romihardiyanto@gmail.com>\n"
+"Language-Team: Bahasa Indonesia <id@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=n != 1;\n"
+
+#: views/addons/policy.thtml:98
+msgid "a_cancel_installation"
+msgstr "Batalkan Pemasangan"
+
+#. This is the text that appears on buttons to download add-ons.
+#. %$1s is an optional string that only appears if the add-on is only available for
+#. a certain platform. Examples: (Windows) or (Linux)
+#. Note that the parentheses are included in the string. :(
+#: views/elements/amo2009/install.thtml:126
+#: views/elements/amo2009/install.thtml:227
+#: views/elements/amo2009/install.thtml:257
+#: views/elements/amo2009/install.thtml:300
+#: views/elements/amo2009/install.thtml:312 views/elements/install.thtml:73
+#: views/elements/install.thtml:181 views/elements/install.thtml:205
+#: views/elements/install.thtml:248 views/elements/install.thtml:260
+#: views/addons/plugins.thtml:66 views/addons/plugins.thtml:76
+#: views/addons/plugins.thtml:86 views/addons/plugins.thtml:96
+#: views/addons/plugins.thtml:119
+#, php-format
+msgid "a_download"
+msgstr "Unduh Sekarang %s"
+
+#: views/addons/policy.thtml:72
+msgid "a_eula_download"
+msgstr "Setuju dan Unduh"
+
+#: views/addons/policy.thtml:74
+msgid "a_eula_install"
+msgstr "Setuju dan Pasang"
+
+#: views/elements/header.thtml:76 views/elements/header.thtml:82
+#: views/api/api_addon.thtml:55 views/api/collections_feed.thtml:75
+#: views/sharing_api/addon.thtml:64
+msgid "a_header_public"
+msgstr "Publik"
+
+#: views/elements/header.thtml:58 views/elements/header.thtml:75
+#: views/elements/header.thtml:80 views/api/api_addon.thtml:57
+#: views/api/collections_feed.thtml:77 views/sharing_api/addon.thtml:66
+msgid "a_header_sandbox"
+msgstr "Sandbox"
+
+#. %s is a date in the _('date') format
+#: views/elements/amo2009/homepage_addon.thtml:115
+#: views/elements/addon_listitem.thtml:122 views/elements/feature.thtml:106
+#: views/addons/display.thtml:104 views/addons/browse_thumbs.thtml:73
+msgid "addon_detail_last_updated"
+msgstr "Diperbarui pada %s"
+
+#. %s is the version of the add-on. Example: 3.2a1
+#: views/elements/amo2009/addon_version_detail.thtml:51
+#: views/elements/addon_version_detail.thtml:51
+#, php-format
+msgid "addon_display_header_version"
+msgstr "Versi %s"
+
+#: views/addons/browse_thumbs.thtml:80
+msgid "addon_downloads"
+msgstr "unduhan"
+
+#: views/addons/display.thtml:147
+msgid "addon_downloads_total"
+msgstr "total unduhan"
+
+#: views/elements/amo2009/homepage_addon.thtml:106
+#: views/elements/addon_listitem.thtml:115 views/elements/feature.thtml:101
+#: views/addons/category_landing.thtml:157 views/addons/display.thtml:146
+#: views/addons/browse_thumbs.thtml:80
+msgid "addon_downloads_weekly"
+msgstr "unduhan mingguan"
+
+#. %1 is the add-on count, %2 the category name
+#: views/addons/browse_thumbs.thtml:104 views/addons/browse.thtml:60
+#, php-format
+msgid "addon_list_category_totalcount"
+msgid_plural "addon_list_category_totalcount"
+msgstr[0] "%1$s pengaya"
+msgstr[1] "%1$s pengaya"
+
+#: views/elements/amo2009/addon_list_options.thtml:103
+#: views/elements/pagination.thtml:67
+#: views/elements/addon_list_options.thtml:94
+msgid "addon_list_perpage"
+msgstr "per halaman"
+
+#: views/elements/amo2009/addon_list_options.thtml:84
+#: views/elements/addon_list_options.thtml:98
+msgid "addon_list_sortby"
+msgstr "Urut berdasar:"
+
+#: views/helpers/addons_html.php:568 views/elements/amo2009/install.thtml:321
+#: views/elements/feature.thtml:89
+msgid "addon_listitem_flag_experimental"
+msgstr "eksperimental"
+
+#: views/helpers/addons_html.php:570
+msgid "addon_listitem_flag_recommended"
+msgstr "rekomendasi kami"
+
+#. %1 is the add-on name, %2 is the platform
+#: views/pages/js_constants.js.thtml:66
+msgid "addon_not_available_for_platform"
+msgstr "%1$s tidak tersedia untuk %2$s."
+
+#. %1 is the add-on name
+#: views/addons/policy.thtml:101 views/addons/previews.thtml:60
+#: views/addons/versions.thtml:130 views/reviews/flag.thtml:61
+#: views/reviews/add.thtml:114 views/reviews/display.thtml:216
+#: views/reviews/review_added.thtml:57
+#, php-format
+msgid "addon_review_a_back_to_addon_x"
+msgstr "Kembali ke %1$s..."
+
+#. %1 is the add-on name
+#: views/reviews/flag.thtml:60 views/reviews/add.thtml:113
+#: views/reviews/review_added.thtml:56
+#, php-format
+msgid "addon_review_a_back_to_reviews"
+msgstr "Kembali ke tinjauan..."
+
+#: views/reviews/add.thtml:85
+msgid "addon_review_add_rating_field"
+msgstr "Peringkat:"
+
+#: views/reviews/add.thtml:102
+msgid "addon_review_add_review_field"
+msgstr "Tinjauan:"
+
+#: views/reviews/add.thtml:107
+msgid "addon_review_add_submit"
+msgstr "Kirim tinjauan anda"
+
+#. %s is the name of the add-on
+#: views/reviews/add.thtml:51
+#, php-format
+msgid "addon_review_add_title"
+msgstr "Tambah tinjauan untuk %s"
+
+#: views/reviews/add.thtml:78
+msgid "addon_review_add_title_field"
+msgstr "Judul/Ringkasan:"
+
+#: views/reviews/display.thtml:77 views/reviews/display.thtml:161
+msgid "addon_review_admin_delete"
+msgstr "Hapus"
+
+#: views/reviews/display.thtml:76
+msgid "addon_review_author_reply_link"
+msgstr "Balas"
+
+#: views/reviews/delete.thtml:62
+msgid "addon_review_confirm_delete"
+msgstr "Yakin akan menghapus tinjauan ini?"
+
+#: views/reviews/delete.thtml:63
+msgid "addon_review_confirm_no"
+msgstr "Tidak"
+
+#: views/reviews/delete.thtml:64
+msgid "addon_review_confirm_yes"
+msgstr "Ya"
+
+#: views/reviews/delete.thtml:48
+msgid "addon_review_delete_header"
+msgstr "Hapus Tinjauan"
+
+#: controllers/reviews_controller.php:449
+msgid "addon_review_deleted_successfully"
+msgstr "Tinjauan sukses dihapus."
+
+#. %s is the name of the add-on
+#: views/reviews/add.thtml:51
+#, php-format
+msgid "addon_review_edit_title"
+msgstr "Sunting Tinjauan untuk %s"
+
+#. %1 is the count of characters entered as notes for the review flag reason.
+#: controllers/reviews_controller.php:539
+msgid "addon_review_flag_error_other_length"
+msgstr ""
+"Terjadi masalah saat menandai tinjauan: Jumlah karakter untuk isian catatan "
+"untuk tinjauan yang ditandai dibatasi minimum 10 karakter, maksimum 100 "
+"karakter. Jumlah karakter yang Anda tulis: %1$S."
+
+#. Removing an extra comma
+#: views/reviews/review_added.thtml:53
+msgid "addon_review_in_moderation"
+msgstr ""
+"Catatan: Sebelum tinjauan anda muncul pada situs publik, tinjauan akan "
+"dimoderasi oleh penyunting."
+
+#: views/reviews/add.thtml:57
+msgid "addon_review_in_reply_to"
+msgstr "Balasan dari pengembang kepada:"
+
+#. %1 is the review count, %2 is the nickname or full name of the user.
+#: views/reviews/display.thtml:131
+#, php-format
+msgid "addon_review_others_by_user"
+msgid_plural "addon_review_others_by_user"
+msgstr[0] ""
+"Tampilkan %1$s tinjauan sebelumnya tentang pengaya ini yang dikirim oleh %2"
+"$s."
+msgstr[1] ""
+"Tampilkan %1$s tinjauan sebelumnya tentang pengaya ini yang dikirim oleh %2"
+"$s."
+
+#. %1 is the add-on name
+#: controllers/reviews_controller.php:201
+#: controllers/reviews_controller.php:250
+#: controllers/reviews_controller.php:345
+#: controllers/reviews_controller.php:424
+#, php-format
+msgid "addon_review_pagetitle"
+msgstr "Tinjauan untuk %s"
+
+#. %1 is the user, %2 is the (localized) date
+#: views/reviews/display.thtml:160
+#, php-format
+msgid "addon_review_reply_on_x_by_y"
+msgstr "Balasan oleh %1$s pada %2$s"
+
+#: views/reviews/display.thtml:157
+msgid "addon_review_reply_prefix"
+msgstr "Balasan Pengembang:"
+
+#: views/reviews/review_added.thtml:51
+msgid "addon_review_saved_successfully"
+msgstr "Tinjauan anda sukses disimpan. Terima kasih!"
+
+#: views/addons/display.thtml:354 views/reviews/display.thtml:72
+msgid "addon_reviewed_by_u_on_d"
+msgstr "oleh %1$s pada %2$s"
+
+#. %1 is the user, %2 is the (localized) date, %3 is the rating
+#: views/editors/reviews_queue.thtml:57 views/editors/reviews_queue.thtml:68
+#: views/reviews/add.thtml:63 views/reviews/delete.thtml:54
+#, php-format
+msgid "addon_reviewed_on_x_rated_y"
+msgstr "oleh %1$s pada %2$s (peringkat %3$s)"
+
+#: views/elements/amo2009/addon_version_detail.thtml:52
+#: views/elements/addon_version_detail.thtml:52
+msgid "addon_version_permalink"
+msgstr "Taut permanen ke versi ini"
+
+#. %1 is the current Application name (e.g. Firefox)
+#. %2 is the Application's version number
+#: views/addons/versions.thtml:140
+msgid "addon_versions_getlatestversion"
+msgstr "Versi terbaru yang kompatibel dengan %1$s %2$s"
+
+#: views/addons/display.thtml:447
+msgid "addons_author_addons_submit"
+msgstr "Kirim"
+
+#: views/elements/amo2009/homepage_addon.thtml:100
+#: views/elements/feature.thtml:95
+msgid "addons_author_tooltip"
+msgstr "Tampilkan profil penyusun"
+
+#. %1 is the name of the Application (eg. Firefox)
+#: controllers/addons_controller.php:1296
+msgid "addons_browse_all_themes_title"
+msgstr "Jelajahi semua Tema :: Pengaya %1$s"
+
+#. %s is the name of the category
+#: controllers/addons_controller.php:1016
+#, php-format
+msgid "addons_browse_browse_category"
+msgstr "Jelajahi %s"
+
+#. %1 is the name of the theme category (eg. Modern)
+#. %2 is the name of the Application (eg. Firefox)
+#: controllers/addons_controller.php:664
+msgid "addons_browse_categories_header_theme"
+msgstr "Jelajahi Tema %1$s :: Pengaya %2$s"
+
+#: views/addons/display.thtml:249
+#, fuzzy
+msgid "addons_display_a_license_what"
+msgstr "What's this?"
+
+#: views/reviews/display.thtml:222
+msgid "addons_display_add_review"
+msgstr "Tambahkan tinjauan"
+
+#: views/addons/display.thtml:294
+msgid "addons_display_advanced_details"
+msgstr "Detil Lebih Lanjut"
+
+#: views/addons/display.thtml:98
+msgid "addons_display_categories"
+msgstr "Kategori"
+
+#: views/addons/display.thtml:482
+#, fuzzy
+msgid "addons_display_collection_add"
+msgstr "Add to a collection:"
+
+#: views/addons/display.thtml:491
+#, fuzzy
+msgid "addons_display_collection_add_new"
+msgstr "New Collection..."
+
+#: views/addons/display.thtml:487
+#, fuzzy
+msgid "addons_display_collection_add_select_one"
+msgstr "Select a collection..."
+
+#: views/addons/display.thtml:493
+#, fuzzy
+msgid "addons_display_collection_add_submit"
+msgstr "Publish"
+
+#. %1$s is the add-on name
+#. %2$s is the collection name, linked to the collection's page
+#: views/pages/js_constants.js.thtml:103 views/addons/display.thtml:61
+#, fuzzy
+msgid "addons_display_collection_publish_success"
+msgstr "%1$s has been added to the %2$s collection."
+
+#: views/addons/display.thtml:483
+#, fuzzy
+msgid "addons_display_collection_whatsthis"
+msgstr "What's this?"
+
+#. %1$s is a number
+#: views/addons/display.thtml:473
+#, fuzzy
+msgid "addons_display_collections_more"
+msgid_plural "addons_display_collections_more"
+msgstr[0] "and %1$s more collection"
+msgstr[1] "and %1$s more collections"
+
+#: views/addons/display.thtml:403
+msgid "addons_display_detailed_review"
+msgstr "form tinjauan"
+
+#: views/reviews/add.thtml:89 views/reviews/add.thtml:90
+msgid "addons_display_dont_like_it"
+msgstr "Tidak suka"
+
+#: views/reviews/display.thtml:220
+msgid "addons_display_edit_review"
+msgstr "Sunting tinjauan anda"
+
+#: views/addons/display.thtml:132
+msgid "addons_display_has_privacy"
+msgstr "Pengaya ini memiliki kebijakan privasi."
+
+#: views/reviews/add.thtml:87 views/reviews/add.thtml:88
+msgid "addons_display_hate_it"
+msgstr "Benci"
+
+#: views/addons/display.thtml:462
+#, fuzzy
+msgid "addons_display_header_collections"
+msgstr "Related Collections"
+
+#: views/addons/display.thtml:297
+msgid "addons_display_header_developer_comments"
+msgstr "Komentar Pengembang"
+
+#: views/addons/display.thtml:230
+msgid "addons_display_header_homepage"
+msgstr "Beranda"
+
+#: views/addons/display.thtml:247 views/addons/versions.thtml:110
+#, fuzzy
+msgid "addons_display_header_license"
+msgstr "Source Code License"
+
+#: views/addons/display.thtml:337
+msgid "addons_display_header_reviews"
+msgstr "Tinjauan"
+
+#: views/addons/display.thtml:261
+msgid "addons_display_header_support"
+msgstr "Layanan Dukungan"
+
+#: views/reviews/add.thtml:91 views/reviews/add.thtml:92
+msgid "addons_display_like_it"
+msgstr "Suka"
+
+#: views/addons/display.thtml:210
+msgid "addons_display_long_description"
+msgstr "Deskripsi Lengkap"
+
+#: views/reviews/add.thtml:95 views/reviews/add.thtml:96
+msgid "addons_display_love_it"
+msgstr "Sangat suka sekali"
+
+#: views/addons/display.thtml:178
+msgid "addons_display_more_images"
+msgstr "Gambar Lainnya"
+
+#: views/addons/display.thtml:465
+#, fuzzy
+msgid "addons_display_nocollections"
+msgstr "This add-on is not yet in any collections."
+
+#. %1$s is either an author's name or a comma separated list of authors. Using
+#. the list doesn't make sense in the English plural form so we ignore the
+#. variable.
+#: views/addons/display.thtml:436
+msgid "addons_display_other_addons_by"
+msgid_plural "addons_display_other_addons_by"
+msgstr[0] "Pengaya lain dari %1$s"
+msgstr[1] "Pengaya lain dari penyusun ini"
+
+#. %s is the name of the add-on and the add-on section. Example:
+#. Some Add-on :: Firefox Add-ons
+#. This should not be concatenated in the code and should be fixed.
+#: controllers/addons_controller.php:141 controllers/addons_controller.php:280
+#: controllers/addons_controller.php:1442
+#, php-format
+msgid "addons_display_pagetitle"
+msgstr "%s"
+
+#. %s is an email address
+#: views/addons/display.thtml:286
+#, php-format
+msgid "addons_display_paragraph_supportinfoemail"
+msgstr ""
+"Dukungan untuk pengaya ini disediakan pengembang dengan mengirim email ke %s."
+
+#. %$1s is a URL
+#. %$2s is an email address
+#: views/addons/display.thtml:269
+#, php-format
+msgid "addons_display_paragraph_supportinfoemailurl"
+msgstr ""
+"Dukungan untuk pengaya ini disediakan pengembang di %s atau dengan mengirim "
+"email ke %s."
+
+#. %s is a URL
+#: views/addons/display.thtml:278
+#, php-format
+msgid "addons_display_paragraph_supportinfourl"
+msgstr "Dukungan untuk pengaya ini disediakan oleh pengembang di %s."
+
+#: views/addons/display.thtml:383
+msgid "addons_display_rate_it"
+msgstr "Peringkat"
+
+#: views/reviews/add.thtml:93 views/reviews/add.thtml:94
+msgid "addons_display_really_like_it"
+msgstr "Sangat suka"
+
+#: views/addons/display.thtml:410
+msgid "addons_display_review_etiquette"
+msgstr ""
+"Mohon tidak mengirimkan laporan bug atau kesalahan pada form tinjauan. Kami "
+"tidak memberitahukan alamat email anda kepada para developer yang mungkin "
+"mereka butuhkan untuk menghubungi anda agar masalah anda dapat diselesaikan."
+
+#. %1 is the review guidelines link
+#: views/addons/display.thtml:417
+msgid "addons_display_review_guidelines_link"
+msgstr "<a href=\"%s\">Petunjuk tentang Tinjauan</a>"
+
+#. %1 is the support section link
+#: views/addons/display.thtml:414
+msgid "addons_display_review_see_support"
+msgstr ""
+"Lihat <a href=\"%1$s\">bagian dukungan</a> untuk mencari tahu di mana anda "
+"menemukan bantuan untuk pengaya ini."
+
+#: views/addons/display.thtml:404
+msgid "addons_display_review_submit"
+msgstr "Simpan"
+
+#: views/addons/display.thtml:430
+#, php-format
+msgid "addons_display_see_all_addons"
+msgstr "Tampilkan Semua Pengaya %1$s"
+
+#. %1 is the number of reviews
+#: views/addons/display.thtml:364
+#, php-format
+msgid "addons_display_see_all_reviews"
+msgstr "Tampilkan semua tinjauan (%1$s)"
+
+#: views/addons/display.thtml:219
+msgid "addons_display_see_all_versions"
+msgstr "Tampilkan Semua Versi"
+
+#: views/addons/display.thtml:321 views/addons/versions.thtml:117
+msgid "addons_display_view_source"
+msgstr "Tampilkan kode sumber"
+
+#: views/addons/display.thtml:324
+msgid "addons_display_view_stats"
+msgstr "Tampilkan statistik"
+
+#: views/addons/display.thtml:376
+msgid "addons_display_what_do_you_think"
+msgstr "Pendapat anda?"
+
+#: views/elements/app_compatibility.thtml:49
+msgid "addons_display_workswith"
+msgstr "Bekerja pada:"
+
+#: views/addons/home.thtml:112
+#, fuzzy
+msgid "addons_home_browse_new"
+msgstr "Just Added"
+
+#: views/addons/home.thtml:110
+#, fuzzy
+msgid "addons_home_browse_popular"
+msgstr "Popular"
+
+#: views/addons/home.thtml:108
+#, fuzzy
+msgid "addons_home_browse_recommended"
+msgstr "Recommended"
+
+#: views/addons/home.thtml:127 views/addons/home.thtml:134
+#: views/addons/home.thtml:141 views/addons/home.thtml:148
+#, fuzzy
+msgid "addons_home_browse_subscribe"
+msgstr "Subscribe"
+
+#: views/addons/home.thtml:101
+#, fuzzy
+msgid "addons_home_browse_title"
+msgstr "Browse Add-ons"
+
+#: views/addons/home.thtml:114
+#, fuzzy
+msgid "addons_home_browse_updated"
+msgstr "Updated"
+
+#: views/elements/amo2009/homepage_addon.thtml:100
+#: views/elements/addon_discussionheader.thtml:83
+#: views/elements/addon_listitem.thtml:109 views/elements/feature.thtml:95
+#: views/addons/category_landing.thtml:66 views/addons/policy.thtml:57
+#: views/addons/display.thtml:70 views/addons/home.thtml:178
+msgid "addons_home_by"
+msgstr "oleh"
+
+#: views/addons/home.thtml:169
+#, fuzzy
+msgid "addons_home_collection_popular_title"
+msgstr "Popular Collections"
+
+#: views/elements/amo2009/categories.thtml:69 views/addons/home.thtml:160
+#, fuzzy
+msgid "addons_home_collections"
+msgstr "Collections"
+
+#. %1$s is the count of addons in a collection
+#: views/elements/amo2009/collection_listing_item.thtml:51
+#: views/addons/home.thtml:185
+#, fuzzy
+msgid "addons_home_collections_addon_count"
+msgid_plural "addons_home_collections_addon_count"
+msgstr[0] "<strong>%1$s</strong> add-on"
+msgstr[1] "<strong>%1$s</strong> add-ons"
+
+#: views/addons/home.thtml:196
+#, fuzzy
+msgid "addons_home_collections_all"
+msgstr "View All Collections"
+
+#: views/addons/home.thtml:162
+#, fuzzy
+msgid "addons_home_collections_intro"
+msgstr ""
+"Collections are a way for you to categorize, mix, match and mingle add-ons. "
+"Subscribe to collections created by other users or create your own."
+
+#. %1$s is the count of subscribers for a collection
+#: views/elements/amo2009/collection_listing_item.thtml:58
+#: views/collections/detail.thtml:96 views/addons/home.thtml:189
+#, fuzzy
+msgid "addons_home_collections_subscribers"
+msgid_plural "addons_home_collections_subscribers"
+msgstr[0] "<strong>%1$s</strong> subscriber"
+msgstr[1] "<strong>%1$s</strong> subscribers"
+
+#: views/addons/searchengines.thtml:54 views/addons/themes_landing.thtml:49
+msgid "addons_home_feature_head"
+msgstr "Rekomendasi Kami"
+
+#: controllers/search_controller.php:218 controllers/addons_controller.php:176
+#: controllers/addons_controller.php:428 controllers/addons_controller.php:671
+#: controllers/addons_controller.php:871
+#: controllers/addons_controller.php:1103
+#: controllers/addons_controller.php:1242
+#: controllers/addons_controller.php:1298
+#, php-format
+msgid "addons_home_header_details"
+msgstr ""
+"Pengaya (Add-on) memperkaya %1$s, membuat penjelajahan web anda lebih "
+"personal. Silakan melihat-lihat dan buat %1$s sesuai keinginan anda."
+
+#. %1$s is the HTML collection name link.
+#: views/elements/amo2009/teaser_collections.thtml:107
+#, fuzzy
+msgid "addons_home_introduction_collection_link"
+msgstr "Like these? Find more add-ons in %1$s."
+
+#: views/elements/amo2009/teaser_collections.thtml:60
+#, fuzzy
+msgid "addons_home_introduction_extras"
+msgstr ""
+"<strong>Over 5000 free extras</strong> that let you customize and extend "
+"Firefox to meet your needs."
+
+#: views/elements/amo2009/teaser_collections.thtml:55
+#, fuzzy
+msgid "addons_home_introduction_header"
+msgstr "What are Add-ons?"
+
+#: views/elements/amo2009/teaser_collections.thtml:72
+#, fuzzy
+msgid "addons_home_introduction_install"
+msgstr ""
+"<strong>Easy to install</strong>, get notified when updates are available."
+
+#: views/elements/amo2009/teaser_collections.thtml:45
+#, fuzzy
+msgid "addons_home_introduction_name"
+msgstr "Introduction"
+
+#: views/elements/amo2009/teaser_collections.thtml:66
+#, fuzzy
+msgid "addons_home_introduction_themes"
+msgstr ""
+"Toolbars, themes and search providers that <strong>help you perform common "
+"tasks.</strong>"
+
+#: views/addons/home.thtml:161
+#, fuzzy
+msgid "addons_home_new_indicator"
+msgstr "NEW!"
+
+#: views/elements/app_chooser.thtml:48 views/layouts/amo2009.thtml:257
+msgid "addons_home_other_applications"
+msgstr "Aplikasi Lain"
+
+#. %1$s is the application the user is browsing. Examples: Thunderbird, Firefox,
+#. Sunbird
+#: views/pages/collector_faq.thtml:49 views/pages/collector_firstrun.thtml:42
+#: views/pages/collector.thtml:46 views/pages/collector_features.thtml:54
+#: controllers/developers_controller.php:87
+#: controllers/compatibility_controller.php:72
+#: controllers/components/simple_acl.php:81 controllers/components/amo.php:607
+#: controllers/statistics_controller.php:60
+#: controllers/statistics_controller.php:240
+#: controllers/previews_controller.php:67 controllers/users_controller.php:90
+#: controllers/users_controller.php:223 controllers/users_controller.php:330
+#: controllers/users_controller.php:414 controllers/users_controller.php:708
+#: controllers/users_controller.php:723 controllers/reviews_controller.php:204
+#: controllers/reviews_controller.php:251
+#: controllers/reviews_controller.php:346
+#: controllers/reviews_controller.php:425
+#: controllers/search_controller.php:185 controllers/search_controller.php:297
+#: controllers/search_controller.php:301 controllers/addons_controller.php:147
+#: controllers/addons_controller.php:280 controllers/addons_controller.php:370
+#: controllers/addons_controller.php:667 controllers/addons_controller.php:874
+#: controllers/addons_controller.php:1019
+#: controllers/addons_controller.php:1034
+#: controllers/addons_controller.php:1101
+#: controllers/addons_controller.php:1121
+#: controllers/addons_controller.php:1240
+#: controllers/addons_controller.php:1357
+#: controllers/addons_controller.php:1364
+#: controllers/addons_controller.php:1442
+#: controllers/addons_controller.php:1477
+#: controllers/addons_controller.php:1538
+#: controllers/addons_controller.php:1543
+#: controllers/editors_controller.php:64 controllers/pages_controller.php:132
+#: controllers/groups_controller.php:65 controllers/groups_controller.php:71
+#: controllers/groups_controller.php:89 controllers/groups_controller.php:111
+#: controllers/collections_controller.php:57
+#: controllers/collections_controller.php:121
+#: controllers/collections_controller.php:205
+#: controllers/collections_controller.php:365
+#: controllers/collections_controller.php:404
+#: controllers/collections_controller.php:466
+#: controllers/collections_controller.php:538
+#: controllers/collections_controller.php:828
+#: controllers/localizers_controller.php:72
+#, php-format
+msgid "addons_home_pagetitle"
+msgstr "Pengaya %1$s"
+
+#. %1$s is the number of addons downloaded
+#: views/addons/home.thtml:57
+#, fuzzy, php-format
+msgid "addons_home_stats_downloaded"
+msgid_plural "addons_home_stats_downloaded"
+msgstr[0] "<strong>%1$s</strong> <span>add-on downloaded</span>"
+msgstr[1] "<strong>%1$s</strong> <span>add-ons downloaded</span>"
+
+#. %1$s is the number of addons in use
+#: views/addons/home.thtml:63
+#, fuzzy, php-format
+msgid "addons_home_stats_inuse"
+msgid_plural "addons_home_stats_inuse"
+msgstr[0] "<strong>%1$s</strong> <span>add-on in use</span>"
+msgstr[1] "<strong>%1$s</strong> <span>add-ons in use</span>"
+
+#: views/addons/home.thtml:136
+msgid "addons_home_view_all_newest_title"
+msgstr "Tampilkan semua pengaya yang baru dibuat"
+
+#: views/addons/home.thtml:129
+msgid "addons_home_view_all_popular_title"
+msgstr "Tampilkan pengaya populer"
+
+#: views/addons/home.thtml:150
+msgid "addons_home_view_all_recommended_title"
+msgstr "Tampilkan semua rekomendasi pengaya"
+
+#: views/addons/home.thtml:143
+msgid "addons_home_view_all_updated_title"
+msgstr "Tampilkan semua pengaya yang versinya dimutakhirkan"
+
+#: views/elements/amo2009/install.thtml:334 views/elements/install.thtml:112
+msgid "addons_install_in_sunbird"
+msgstr ""
+"<ol><li>Klik tautan di bawah untuk disimpan sebagai berkas.</li><li>Di "
+"Mozilla Sunbird, buka menu Pengaya pada menu Alat.</li><li>Klik tombol "
+"Pasang, dan pilih berkas yang anda unduh sebelumnya dan klik \"OK\".</li></"
+"ol>"
+
+#: views/elements/amo2009/install.thtml:333 views/elements/install.thtml:111
+msgid "addons_install_in_sunbird_title"
+msgstr "Cara Memasang di Sunbird"
+
+#: views/elements/amo2009/install.thtml:331 views/elements/install.thtml:106
+msgid "addons_install_in_thunderbird"
+msgstr ""
+"<ol><li>Klik kanan tautan di bawah dan pilih \"Simpan Tautan dengan Nama..."
+"\" untuk mengunduh berkas dan menyimpannya pada harddisk anda.</li><li>Di "
+"Mozilla Thunderbird, buka menu Pengaya pada menu Alat.</li><li>Klik tombol "
+"Pasang, dan pilih berkas yang anda unduh sebelumnya dan klik \"OK\".</li></"
+"ol>"
+
+#: views/elements/amo2009/install.thtml:330 views/elements/install.thtml:105
+msgid "addons_install_in_thunderbird_title"
+msgstr "Cara Memasang di Thunderbird"
+
+#: views/elements/amo2009/addon_list_options.thtml:108
+#: views/elements/addon_list_options.thtml:105
+msgid "addons_options_show_experimental"
+msgstr "tampilkan pengaya eksperimental"
+
+#: views/elements/amo2009/addon_list_options.thtml:113
+#: views/elements/addon_list_options.thtml:109
+msgid "addons_options_submit"
+msgstr "Buka"
+
+#: views/addons/plugins.thtml:63 views/addons/plugins.thtml:73
+#: views/addons/plugins.thtml:83 views/addons/plugins.thtml:93
+#: views/addons/plugins.thtml:103 views/addons/plugins.thtml:116
+#: views/addons/plugins.thtml:126
+msgid "addons_plugins_by"
+msgstr "Oleh"
+
+#: views/addons/plugins.thtml:107
+msgid "addons_plugins_for_linux"
+msgstr "untuk Linux"
+
+#: views/addons/plugins.thtml:108 views/addons/plugins.thtml:131
+msgid "addons_plugins_for_macosx"
+msgstr "untuk Mac OS X"
+
+#: views/addons/plugins.thtml:106 views/addons/plugins.thtml:129
+#: views/addons/plugins.thtml:130
+msgid "addons_plugins_for_windows"
+msgstr "untuk Windows"
+
+#. %1$s is a URL
+#: views/addons/plugins.thtml:139
+#, php-format
+msgid "addons_plugins_looking_for_more"
+msgstr ""
+"Halaman ini hanya berisi daftar plugin yang paling umum dan populer. Untuk "
+"informasi lebih lanjut tentang plugin untuk browser berbasis Mozilla "
+"lainnya, kunjungi %1$s"
+
+#: views/addons/plugins.thtml:137
+msgid "addons_plugins_looking_for_plugin"
+msgstr "Mencari plugin yang tidak ada di sini?"
+
+#: views/addons/plugins.thtml:58
+msgid "addons_plugins_main_description"
+msgstr ""
+"Plugin membantu browser untuk fungsi tertentu seperti menampilkan format "
+"grafik yang khusus atau memutar berkas multimedia. Plugin sedikit berbeda "
+"dengan ekstensi, yang mengubah atau menambah fungsi yang sudah ada "
+"sebelumnya."
+
+#. %1$s is the application name. Example: Firefox, Thunderbird, Sunbird
+#: controllers/addons_controller.php:1122
+#, php-format
+msgid "addons_plugins_main_header"
+msgstr "Plugin yang Umum untuk %1$s"
+
+#: controllers/components/amo.php:698 controllers/addons_controller.php:1121
+msgid "addons_plugins_pagetitle"
+msgstr "Plugin"
+
+#: views/addons/plugins.thtml:68 views/addons/plugins.thtml:78
+#: views/addons/plugins.thtml:88 views/addons/plugins.thtml:98
+#: views/addons/plugins.thtml:110 views/addons/plugins.thtml:121
+#: views/addons/plugins.thtml:133
+msgid "addons_plugins_support_documentation"
+msgstr "Dokumentasi Dukungan: "
+
+#. %s is the name of the add-on
+#: views/addons/policy.thtml:61
+#, php-format
+msgid "addons_policy_eula_require"
+msgstr ""
+"%s mewajibkan anda menyetujui Perjanjian Lisensi End-User (End User License "
+"Agreement-EULA) sebelum pemasangan dapat dilanjutkan:"
+
+#. %1 is the add-on name
+#: controllers/addons_controller.php:1476
+#, php-format
+msgid "addons_previews_pagetitle"
+msgstr "Pratinjau %s"
+
+#: views/addons/category_landing.thtml:135
+#, fuzzy
+msgid "addons_recently_added"
+msgstr "Recently Added"
+
+#: views/addons/recommended.thtml:51 controllers/addons_controller.php:1365
+msgid "addons_recommended_introduction"
+msgstr ""
+"Dari sekian banyak pengaya yang bagus yang tersedia, pasti ada satu yang "
+"cocok dengan selera anda. Untuk memulai, berikut adalah daftar pengaya "
+"terpopuler. Selamat menikmati!"
+
+#: controllers/addons_controller.php:1357
+#: controllers/addons_controller.php:1364
+msgid "addons_recommended_pagetitle"
+msgstr "Pengaya yang Direkomendasikan"
+
+#: controllers/addons_controller.php:1360
+msgid "addons_recommended_title"
+msgstr "Pengaya yang Direkomendasikan"
+
+#: views/addons/searchengines.thtml:136
+msgid "addons_searchengines_additional_resources"
+msgstr "Informasi terkait"
+
+#. link text devmo
+#: views/addons/searchengines.thtml:141
+msgid "addons_searchengines_devmo_link"
+msgstr "Mozilla Developer Center"
+
+#: views/pages/js_constants.js.thtml:67
+msgid "addons_searchengines_error_mozilla_browser_required"
+msgstr ""
+"Maaf, anda membutuhkan browser berbasis Mozilla (seperti Firefox) untuk "
+"dapat memasang plugin pencarian."
+
+#: views/addons/searchengines.thtml:49
+msgid "addons_searchengines_error_nojavascript"
+msgstr ""
+"JavaScript wajib diaktifkan untuk memasang plugin tapi tampaknya anda telah "
+"mematikannya. Silakan mengaktifkan JavaScript sebelum mencoba memasang "
+"plugin pencarian di bawah ini."
+
+#. %1 is "make your own" link
+#. %2 is MDC link
+#: views/addons/searchengines.thtml:139
+msgid "addons_searchengines_learn_howto"
+msgstr "Pelajari cara %1$s di %2$s (dalam Bahasa Inggris)."
+
+#. link path to search plugins instructions, relative to devmo
+#: views/addons/searchengines.thtml:140
+msgid "addons_searchengines_makeyourown_href"
+msgstr "/en/docs/Creating_OpenSearch_plugins_for_Firefox"
+
+#. link text for "make your own" (opensearch engine)
+#: views/addons/searchengines.thtml:140
+msgid "addons_searchengines_makeyourown_link"
+msgstr "membuat sendiri"
+
+#. %1 is the link to mycroft.mozdev.org
+#: views/addons/searchengines.thtml:138
+msgid "addons_searchengines_more"
+msgstr "Jelajahi lebih banyak mesin pencari di %1$s"
+
+#. link text to mycroft.mozdev.org
+#: views/addons/searchengines.thtml:138
+msgid "addons_searchengines_mycroft_link"
+msgstr "mycroft.mozdev.org"
+
+#: controllers/addons_controller.php:1100
+#: controllers/addons_controller.php:1110
+msgid "addons_searchengines_pagetitle"
+msgstr "Mesin Pencari"
+
+#: views/addons/searchengines.thtml:143
+msgid "addons_searchengines_thanks"
+msgstr ""
+"Terima kasih khusus kepada Proyek Mycroft atas hasil karyanya untuk Mesin "
+"Pencari Firefox."
+
+#: views/addons/display.thtml:154
+#, fuzzy
+msgid "addons_share_button_text"
+msgstr "Share this"
+
+#: controllers/addons_controller.php:89
+#, fuzzy
+msgid "addons_share_label_delicious"
+msgstr "Add to Delicious"
+
+#: controllers/addons_controller.php:77
+#, fuzzy
+msgid "addons_share_label_digg"
+msgstr "Digg this!"
+
+#: controllers/addons_controller.php:83
+#, fuzzy
+msgid "addons_share_label_facebook"
+msgstr "Post to Facebook"
+
+#: controllers/addons_controller.php:101
+#, fuzzy
+msgid "addons_share_label_friendfeed"
+msgstr "Share on FriendFeed"
+
+#: controllers/addons_controller.php:95
+#, fuzzy
+msgid "addons_share_label_myspace"
+msgstr "Post to MySpace"
+
+#: controllers/components/amo.php:201 controllers/components/amo.php:229
+msgid "addons_status_disabled"
+msgstr "Dimatikan"
+
+#: controllers/components/amo.php:191 controllers/components/amo.php:224
+msgid "addons_status_incomplete"
+msgstr "Versi Tidak Lengkap"
+
+#: controllers/components/amo.php:197 controllers/components/amo.php:227
+msgid "addons_status_nominated"
+msgstr "Dalam Sandbox; Nominasi Publik"
+
+#: views/pages/js_constants.js.thtml:80 controllers/components/amo.php:195
+#: controllers/components/amo.php:226
+msgid "addons_status_pending"
+msgstr "Dalam Sandbox; Tinjauan Ditunda"
+
+#: views/pages/js_constants.js.thtml:78 controllers/components/amo.php:199
+#: controllers/components/amo.php:228
+msgid "addons_status_public"
+msgstr "Publik"
+
+#: views/pages/js_constants.js.thtml:79 controllers/components/amo.php:193
+#: controllers/components/amo.php:225
+msgid "addons_status_sandbox"
+msgstr "Dalam Sandbox"
+
+#: controllers/components/amo.php:203
+msgid "addons_status_unknown"
+msgstr "Tidak Dikenali"
+
+#: views/elements/amo2009/teaser_collections.thtml:91
+#: views/elements/amo2009/homepage_addon.thtml:99
+#: views/elements/feature.thtml:94
+msgid "addons_title_tooltip"
+msgstr "Informasi lebih lanjut tentang pengaya ini"
+
+#: views/addons/category_landing.thtml:151
+#, fuzzy
+msgid "addons_top_downloads"
+msgstr "Top Downloads"
+
+#: views/addons/category_landing.thtml:165
+#, fuzzy
+msgid "addons_top_rated"
+msgstr "Top Rated"
+
+#: views/addons/versions.thtml:62
+msgid "addons_versions_careful"
+msgstr "Hati-hati dengan Versi Lama"
+
+#: views/addons/versions.thtml:63
+msgid "addons_versions_careful_introduction"
+msgstr ""
+"Versi berikut ditampilkan sebagai referensi dan untuk tujuan pengujian. "
+"Sebaiknya anda harus selalu menggunakan versi terbaru pengaya."
+
+#: controllers/addons_controller.php:1549
+msgid "addons_versions_history"
+msgstr "Riwayat Versi dengan Log Perubahan (Changelog)"
+
+#. %1$s is the add-on name
+#: controllers/addons_controller.php:1535
+#, php-format
+msgid "addons_versions_pagetitle"
+msgstr "Riwayat Versi %1$s"
+
+#: controllers/groups_controller.php:71
+msgid "admin_group_add_pagetitle"
+msgstr "Tambah Grup"
+
+#: controllers/groups_controller.php:111
+msgid "admin_group_delete_pagetitle"
+msgstr "Hapus Grup"
+
+#. %s is a number to identify the group
+#: controllers/groups_controller.php:117
+#, php-format
+msgid "admin_group_deleted"
+msgstr "Grup dengan ID %s telah dihapus"
+
+#: controllers/groups_controller.php:89
+msgid "admin_group_edit_pagetitle"
+msgstr "Ubah Grup"
+
+#: controllers/groups_controller.php:92 controllers/groups_controller.php:113
+msgid "admin_group_error_invalid_id"
+msgstr "ID grup tidak sah"
+
+#: controllers/groups_controller.php:65
+msgid "admin_group_pagetitle"
+msgstr "Admin Grup"
+
+#: controllers/groups_controller.php:77 controllers/groups_controller.php:99
+msgid "admin_group_saved"
+msgstr "Grup telah disimpan"
+
+#: views/elements/amo2009/search.thtml:257 views/elements/search.thtml:239
+msgid "advanced_search_form"
+msgstr "Canggih"
+
+#: views/elements/amo2009/search.thtml:126 views/elements/search.thtml:125
+msgid "advanced_search_form_any_time"
+msgstr "Kapan saja"
+
+#: views/elements/amo2009/search.thtml:97
+#: views/elements/amo2009/search.thtml:110 views/elements/search.thtml:96
+#: views/elements/search.thtml:109
+msgid "advanced_search_form_any_type"
+msgstr "Semua"
+
+#: views/elements/amo2009/search.thtml:275 views/elements/search.thtml:254
+msgid "advanced_search_form_any_version"
+msgstr "Apapun"
+
+#: views/elements/amo2009/search.thtml:217 views/elements/search.thtml:212
+msgid "advanced_search_form_application"
+msgstr "Aplikasi"
+
+#: views/elements/amo2009/search.thtml:143 views/elements/search.thtml:142
+msgid "advanced_search_form_keyword_match"
+msgstr "Kata yang Cocok"
+
+#: views/elements/amo2009/search.thtml:251 views/elements/search.thtml:225
+msgid "advanced_search_form_lastupdate"
+msgstr "Terakhir Diperbarui"
+
+#: views/elements/amo2009/search.thtml:145 views/elements/search.thtml:144
+msgid "advanced_search_form_name"
+msgstr "Nama"
+
+#: views/elements/amo2009/search.thtml:144 views/elements/search.thtml:143
+msgid "advanced_search_form_newest"
+msgstr "Terbaru"
+
+#: views/elements/amo2009/search.thtml:130 views/elements/search.thtml:129
+msgid "advanced_search_form_past_3_months"
+msgstr "3 bulan terakhir"
+
+#: views/elements/amo2009/search.thtml:131 views/elements/search.thtml:130
+msgid "advanced_search_form_past_6_months"
+msgstr "6 bulan terakhir"
+
+#: views/elements/amo2009/search.thtml:127 views/elements/search.thtml:126
+msgid "advanced_search_form_past_day"
+msgstr "Hari ini"
+
+#: views/elements/amo2009/search.thtml:129 views/elements/search.thtml:128
+msgid "advanced_search_form_past_month"
+msgstr "Sebulan terakhir"
+
+#: views/elements/amo2009/search.thtml:128 views/elements/search.thtml:127
+msgid "advanced_search_form_past_week"
+msgstr "Seminggu terakhir"
+
+#: views/elements/amo2009/search.thtml:132 views/elements/search.thtml:131
+msgid "advanced_search_form_past_year"
+msgstr "Setahun terakhir"
+
+#: views/elements/amo2009/search.thtml:239 views/elements/search.thtml:230
+msgid "advanced_search_form_perpage"
+msgstr "Item Per Halaman"
+
+#: views/elements/amo2009/search.thtml:243 views/elements/search.thtml:224
+msgid "advanced_search_form_platform"
+msgstr "Platform"
+
+#: views/elements/amo2009/search.thtml:147 views/elements/search.thtml:146
+msgid "advanced_search_form_popularity"
+msgstr "Popularitas"
+
+#: views/elements/amo2009/search.thtml:146 views/elements/search.thtml:145
+msgid "advanced_search_form_rating"
+msgstr "Peringkat"
+
+#: views/elements/amo2009/search.thtml:247 views/elements/search.thtml:231
+msgid "advanced_search_form_sortby"
+msgstr "Urut berdasar"
+
+#: views/elements/amo2009/search.thtml:227 views/elements/search.thtml:216
+msgid "advanced_search_form_to"
+msgstr "hingga"
+
+#: views/elements/amo2009/search.thtml:257 views/elements/search.thtml:237
+msgid "advanced_search_form_toggle_tooltip"
+msgstr "Aktif/matikan mode pencarian canggih"
+
+#: views/elements/amo2009/search.thtml:235 views/elements/search.thtml:223
+msgid "advanced_search_form_type"
+msgstr "Jenis"
+
+#: views/elements/amo2009/search.thtml:222 views/elements/search.thtml:214
+msgid "advanced_search_form_version"
+msgstr "versi"
+
+#: views/elements/amo2009/pagination.thtml:42
+#, fuzzy
+msgid "amo2009_pagination_next_page"
+msgstr "Next"
+
+#: views/elements/amo2009/pagination.thtml:41
+#, fuzzy
+msgid "amo2009_pagination_previous_page"
+msgstr "Prev"
+
+#: views/pages/js_constants.js.thtml:96
+msgid "app_compat_ignore_check"
+msgstr "Abaikan pengecekan versi"
+
+#: views/pages/js_constants.js.thtml:72
+msgid "app_compat_older_firefox_only"
+msgstr "Hanya untuk versi lama Firefox"
+
+#. %1$s and %2$s are URLs
+#: views/pages/js_constants.js.thtml:74
+msgid "app_compat_older_version_or_ignore_check"
+msgstr ""
+"Anda dapat <a href=\"%1$s\">mencoba versi yang lebih lama</a> atau <a href="
+"\"#\" onclick=\"%2$s\">mengabaikan proses pemeriksaan ini</a>"
+
+#. %1$s is a URL
+#: views/pages/js_constants.js.thtml:71
+msgid "app_compat_try_old_version"
+msgstr "Versi <a href=\"%1$s\">yang lama</a> mungkin dapat bekerja"
+
+#. %1$s is a URL
+#. %2$s is a version number. Example: 3.1
+#: views/pages/js_constants.js.thtml:73
+msgid "app_compat_unreleased_version"
+msgstr ""
+"Pengaya ini membutuhkan versi <a href=\"%1$s\">Firefox %2$s</a> yang belum "
+"dirilis"
+
+#: views/pages/js_constants.js.thtml:70
+msgid "app_compat_update_firefox"
+msgstr ""
+"<a href=\"http://getfirefox.com\">Perbarui Firefox</a> anda untuk "
+"menggunakan pengaya ini"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#. %3$s is a status, like Public.
+#: controllers/components/audit.php:79
+#, fuzzy
+msgid "audit_addon_status"
+msgstr "%1$s changed the status of %2$s to %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:221
+#, fuzzy
+msgid "audit_admin_default"
+msgstr "%1$s committed unknown admin action %2$s to ID %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:153
+#, fuzzy
+msgid "audit_admin_feature_remove"
+msgstr "%1$s removed feature %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is an application, like Firefox.
+#: controllers/components/audit.php:92
+#, fuzzy
+msgid "audit_application_create"
+msgstr "%1$s created application %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is an application, like Firefox.
+#: controllers/components/audit.php:95
+#, fuzzy
+msgid "audit_application_edit"
+msgstr "%1$s edited application %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a version number, like 3.5.
+#. %3$s is an application, like Firefox.
+#: controllers/components/audit.php:105
+#, fuzzy
+msgid "audit_appversion_create"
+msgstr "%1$s created version %2$s for %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a version number, like 3.5.
+#. %3$s is an application, like Firefox.
+#: controllers/components/audit.php:108
+#, fuzzy
+msgid "audit_appversion_delete"
+msgstr "%1$s deleted version %2$s for %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a config field, like "awesomeness".
+#. %3$s is a config value, like "off".
+#. %4$s is a config value, like "on".
+#: controllers/components/audit.php:210
+#, fuzzy
+msgid "audit_config"
+msgstr "%1$s changed config '%2$s' from '%3$s' to '%4$s'"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:258
+#, fuzzy
+msgid "audit_editor_default"
+msgstr "%1$s committed unknown editor action %2$s to ID %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#: controllers/components/audit.php:236
+#, fuzzy
+msgid "audit_editor_feature_remove"
+msgstr "%1$s removed addon %2$s from feature list"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#: controllers/components/audit.php:231
+#, fuzzy
+msgid "audit_feature_add"
+msgstr "%1$s added addon %2$s to feature list"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:149
+#, fuzzy
+msgid "audit_feature_edit"
+msgstr "%1$s changed a feature for %2$s locale"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#: controllers/components/audit.php:241
+#, fuzzy
+msgid "audit_feature_locale_change"
+msgstr "%1$s changed locales for addon %2$s on feature list"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:83
+#, fuzzy
+msgid "audit_file_recalchash"
+msgstr "%1$s recalculated the hash for file %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>user name</a>
+#. %3$s is <a>group name</a>
+#: controllers/components/audit.php:182
+#, fuzzy
+msgid "audit_group_addmember"
+msgstr "%1$s added %2$s to group %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:313
+#, fuzzy
+msgid "audit_group_associated"
+msgstr "%1$s associated themselves with %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:162
+#, fuzzy
+msgid "audit_group_create"
+msgstr "%1s created group %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:170
+#, fuzzy
+msgid "audit_group_delete"
+msgstr "%1$s deleted group %2$s (ID %3$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:165
+#, fuzzy
+msgid "audit_group_edit"
+msgstr "%1$s edited group %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>user name</a>
+#. %3$s is <a>group name</a>
+#: controllers/components/audit.php:188
+#, fuzzy
+msgid "audit_group_removemember"
+msgstr "%1$s removed %2$s from group %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:280
+#, fuzzy
+msgid "audit_l10n_default"
+msgstr "%1$s committed unknown action %2$s for %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:295
+#, fuzzy
+msgid "audit_modify_locked_group"
+msgstr "%1$s attempted to modify locked group %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:299
+#, fuzzy
+msgid "audit_modify_other_locale"
+msgstr "%1$s attempted to modify translations in %2$s without permission"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a platform, like <a>Windows</a>
+#: controllers/components/audit.php:135
+#, fuzzy
+msgid "audit_platform_create"
+msgstr "%1$s created platform %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a platform, like <a>Windows</a>
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:143
+#, fuzzy
+msgid "audit_platform_delete"
+msgstr "%1$s deleted platform %2$s (ID %3$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a platform, like <a>Windows</a>
+#: controllers/components/audit.php:138
+#, fuzzy
+msgid "audit_platform_edit"
+msgstr "%1$s edited platform %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a part of the admin, like 'Site Config'
+#: controllers/components/audit.php:288
+#, fuzzy
+msgid "audit_reauthentication_failure"
+msgstr "%1$s failed to re-authenticate to access %2$s."
+
+#. %1$s is <a>user name</a>
+#. %2$s is the name of a canned response, like 'Ready for the public'
+#: controllers/components/audit.php:198
+#, fuzzy
+msgid "audit_response_create"
+msgstr "%1$s created response %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is the name of a canned response, like 'Ready for the public'
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:206
+#, fuzzy
+msgid "audit_response_delete"
+msgstr "%1$s deleted response %2$s (ID %3$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is the name of a canned response, like 'Ready for the public'
+#: controllers/components/audit.php:201
+#, fuzzy
+msgid "audit_response_edit"
+msgstr "%1$s edited response %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:245
+#, fuzzy
+msgid "audit_review_approve"
+msgstr "%1$s approved review %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:250 controllers/components/audit.php:253
+#, fuzzy
+msgid "audit_review_delete"
+msgstr "%1$s deleted review %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:303
+#, fuzzy
+msgid "audit_security_default"
+msgstr "%1$s committed unknown security action %2$s to ID %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a category name, like <a>Search Tools</a>
+#: controllers/components/audit.php:118
+#, fuzzy
+msgid "audit_tag_create"
+msgstr "%1$s created tag %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a category name, like <a>Search Tools</a>
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:126
+#, fuzzy
+msgid "audit_tag_delete"
+msgstr "%1$s deleted category %2$s (ID %3$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a category name, like <a>Search Tools</a>
+#: controllers/components/audit.php:121
+#, fuzzy
+msgid "audit_tag_edit"
+msgstr "%1$s edited category %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:266
+#, fuzzy
+msgid "audit_update_applications"
+msgstr "%1$s updated application translations for %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:277
+#, fuzzy
+msgid "audit_update_blog"
+msgstr "%1$s updated blog post translations for %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:274
+#, fuzzy
+msgid "audit_update_platforms"
+msgstr "%1$s updated platform translations for %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:270
+#, fuzzy
+msgid "audit_update_tags"
+msgstr "%1$s updated category translations for %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>user name</a>
+#: controllers/components/audit.php:217
+#, fuzzy
+msgid "audit_user_edit"
+msgstr "%1$s edited %2$s's user information"
+
+#: controllers/addons_controller.php:1012
+msgid "browse_addons_name"
+msgstr "Urut Nama"
+
+#: controllers/addons_controller.php:1010
+msgid "browse_addons_newest"
+msgstr "Pengaya Baru"
+
+#: controllers/addons_controller.php:1008
+msgid "browse_addons_popular"
+msgstr "Pengaya Terpopuler"
+
+#: controllers/addons_controller.php:1011
+msgid "browse_addons_rated"
+msgstr "Urut Peringkat"
+
+#: controllers/addons_controller.php:1009
+msgid "browse_addons_updated"
+msgstr "Pengaya yang Baru Dimutakhirkan"
+
+#: views/elements/categories.thtml:73 views/elements/categories.thtml:82
+msgid "categories_current_title"
+msgstr "Kategori Sekarang"
+
+#: views/elements/categories.thtml:50
+#: views/elements/amo2009/categories.thtml:43
+#: views/elements/amo2009/categories.thtml:45
+msgid "categories_header"
+msgstr "Kategori"
+
+#: views/elements/categories.thtml:50
+#: views/elements/amo2009/categories.thtml:41
+msgid "categories_header_title"
+msgstr "Pilih kategori"
+
+#. %1$s is the category name
+#: views/addons/searchengines.thtml:129
+#, php-format
+msgid "category_extra_see_all"
+msgstr "Tampilkan Semua %1$s"
+
+#. %1$s is a number.
+#: models/collection.php:130
+#, fuzzy
+msgid "collection_description_limit"
+msgstr "The description should be less than %1$s characters."
+
+#. %1$s is the name of the collection
+#: controllers/collections_controller.php:392
+#, fuzzy
+msgid "collection_detail_rss_title"
+msgstr "%s Collection"
+
+#: controllers/collections_controller.php:1065
+#, fuzzy
+msgid "collection_error_deleting_addon"
+msgstr "Error deleting add-on!"
+
+#: controllers/collections_controller.php:1051
+#, fuzzy
+msgid "collection_error_saving_addon"
+msgstr "Error saving add-on!"
+
+#: controllers/collections_controller.php:1080
+#, fuzzy
+msgid "collection_error_saving_comment"
+msgstr "Error saving comment!"
+
+#. %1$s is a number.
+#: models/collection.php:122
+#, fuzzy
+msgid "collection_name_limit"
+msgstr "The name should be less than %1$s characters."
+
+#: controllers/collections_controller.php:352
+#: controllers/collections_controller.php:487
+msgid "collection_not_found"
+msgstr "Koleksi tidak ditemukan!"
+
+#. %1$s is the text on the "create collection" button
+#: views/collections/add.thtml:91
+#, fuzzy
+msgid "collections_add_formfield_addons_description"
+msgstr ""
+"If you already know which add-ons you want to add to your collection, just "
+"start typing their names below. If you'd rather wait and do this later, just "
+"click %1$s now."
+
+#: views/collections/add.thtml:90
+#, fuzzy
+msgid "collections_add_formfield_firstaddons"
+msgstr "Choose your first add-ons"
+
+#: views/collections/add.thtml:48
+#, fuzzy
+msgid "collections_add_header"
+msgstr "Create a Collection"
+
+#: views/collections/add.thtml:97
+#, fuzzy
+msgid "collections_add_header_selectedaddons"
+msgstr "Selected Add-ons"
+
+#: views/collections/add.thtml:50
+#, fuzzy
+msgid "collections_add_intro"
+msgstr ""
+"It's easy to create your own collection of add-ons by filling in a few "
+"fields below."
+
+#: views/collections/add.thtml:92 views/collections/add.thtml:103
+#, fuzzy
+msgid "collections_add_submit"
+msgstr "Create Collection"
+
+#: views/pages/collector_faq.thtml:50 views/pages/collector_firstrun.thtml:43
+#: views/pages/collector.thtml:47 views/pages/collector_features.thtml:55
+#: controllers/search_controller.php:302
+#: controllers/collections_controller.php:206
+#: controllers/collections_controller.php:405
+#: controllers/collections_controller.php:467
+#: controllers/collections_controller.php:539
+#, fuzzy
+msgid "collections_breadcrumb"
+msgstr "Collections"
+
+#: views/collections/detail.thtml:185
+#, fuzzy
+msgid "collections_detail_a_learn"
+msgstr "Learn More"
+
+#: views/elements/amo2009/collection_add_form.thtml:53
+#: views/elements/amo2009/collections_js_init.thtml:68
+#: views/pages/collector_firstrun.thtml:64
+#, fuzzy
+msgid "collections_detail_button_add"
+msgstr "Add to Favorites"
+
+#: views/elements/amo2009/collection_add_form.thtml:50
+#: views/elements/amo2009/collections_js_init.thtml:71
+#, fuzzy
+msgid "collections_detail_button_remove"
+msgstr "Remove from Favorites"
+
+#. %1$s is a URL.
+#. %2$s is a full <a href>.
+#: views/collections/detail.thtml:62
+#, fuzzy
+msgid "collections_detail_created_desc"
+msgstr ""
+"<p>You can view your new collection below. If you'd like to set a collection "
+"nickname, upload an icon, or change additional settings, please visit the <a "
+"href='%1$s'>Manage Collections</a> page.</p><p>Your collection can be "
+"accessed at this location: %2$s</p>"
+
+#: views/collections/detail.thtml:61
+#, fuzzy
+msgid "collections_detail_created_msg"
+msgstr "Your collection is now ready!"
+
+#: views/collections/detail.thtml:109
+#, fuzzy
+msgid "collections_detail_header_about"
+msgstr "About This Collection"
+
+#. %1$s is a number.
+#: views/collections/detail.thtml:126
+#, fuzzy
+msgid "collections_detail_header_count"
+msgid_plural "collections_detail_header_count"
+msgstr[0] "%1$s Add-on in this Collection"
+msgstr[1] "%1$s Add-ons in this Collection"
+
+#: views/collections/detail.thtml:113
+#, fuzzy
+msgid "collections_detail_info_created"
+msgstr "<strong>Created by:</strong> %1$s"
+
+#: views/collections/detail.thtml:117
+#, fuzzy
+msgid "collections_detail_info_updated"
+msgstr "<strong>Updated:</strong>"
+
+#: views/elements/amo2009/collections_js_init.thtml:62
+#, fuzzy
+msgid "collections_detail_js_adding"
+msgstr "Adding to Favorites&hellip;"
+
+#: views/elements/amo2009/collections_js_init.thtml:65
+#, fuzzy
+msgid "collections_detail_js_removing"
+msgstr "Removing Favorite&hellip;"
+
+#. %1$s is a URL
+#: views/collections/detail.thtml:90
+#, fuzzy
+msgid "collections_detail_login"
+msgstr "<a href=\"%1$s\">Log in</a> to add this collection to your favorites."
+
+#: views/collections/detail.thtml:104
+#, fuzzy
+msgid "collections_detail_manage"
+msgstr "Manage Collection"
+
+#: controllers/collections_controller.php:298
+#, fuzzy
+msgid "collections_detail_sort_date"
+msgstr "Date Added"
+
+#: controllers/collections_controller.php:299
+#, fuzzy
+msgid "collections_detail_sort_name"
+msgstr "Name"
+
+#: controllers/collections_controller.php:300
+#, fuzzy
+msgid "collections_detail_sort_popularity"
+msgstr "Popularity"
+
+#. %1$s is a number.
+#: views/collections/detail.thtml:166
+#, fuzzy
+msgid "collections_detail_weekly_downloads"
+msgid_plural "collections_detail_weekly_downloads"
+msgstr[0] "%1$s download this week"
+msgstr[1] "%1$s downloads this week"
+
+#: views/collections/edit.thtml:255
+#, fuzzy
+msgid "collections_edit_addons_delete_noscript"
+msgstr "Selected add-ons will be removed upon Save"
+
+#: views/collections/edit.thtml:247
+#, fuzzy
+msgid "collections_edit_addons_description"
+msgstr ""
+"To publish new add-ons to this collection, start typing their names below."
+
+#: views/collections/edit.thtml:248
+#, fuzzy
+msgid "collections_edit_addons_description_noscript"
+msgstr ""
+"To publish new add-ons to this collection, enter a comma-separated list of "
+"Add-on IDs below."
+
+#: views/collections/edit.thtml:247 views/collections/edit.thtml:248
+#, fuzzy
+msgid "collections_edit_addons_description_publish_detailspage"
+msgstr "You can also publish an add-on from its normal listing page."
+
+#. %1$s is the date the add-on was added to the collection
+#. %1$s is the name of the user who added the add-on to the collection
+#: views/collections/edit.thtml:260
+#, fuzzy
+msgid "collections_edit_addons_listitem_added"
+msgstr "Added %1$s by %2$s"
+
+#: views/collections/edit.thtml:263
+#, fuzzy
+msgid "collections_edit_addons_listitem_comment_add"
+msgstr "Add publisher comment"
+
+#: views/collections/edit.thtml:266
+#, fuzzy
+msgid "collections_edit_addons_listitem_comment_delete"
+msgstr "Delete publisher comment"
+
+#: views/collections/edit.thtml:265
+#, fuzzy
+msgid "collections_edit_addons_listitem_comment_edit"
+msgstr "Edit publisher comment"
+
+#: views/collections/edit.thtml:271
+#, fuzzy
+msgid "collections_edit_addons_listitem_comment_note"
+msgstr ""
+"Note: Comment will appear as though written by original publisher on the "
+"original publication date"
+
+#: views/collections/edit.thtml:270
+#, fuzzy
+msgid "collections_edit_addons_listitem_comment_submit"
+msgstr "Save Comment"
+
+#: views/collections/edit.thtml:261
+#, fuzzy
+msgid "collections_edit_addons_listitem_remove"
+msgstr "Remove"
+
+#: views/collections/edit.thtml:250
+#, fuzzy
+msgid "collections_edit_addons_submit"
+msgstr "Add to Collection"
+
+#: views/collections/edit.thtml:153
+#, fuzzy
+msgid "collections_edit_check_nickname"
+msgstr "Check Availability"
+
+#: views/collections/edit.thtml:299
+#, fuzzy
+msgid "collections_edit_confirm_deletecollection"
+msgstr "Yes, I would like to delete this collection."
+
+#. %1$s is the label of the edit form's submit button
+#: views/collections/edit.thtml:300
+#, fuzzy
+msgid "collections_edit_confirm_deletecollection_description"
+msgstr "Check the box, then click on \"%1$s\" to delete this collection."
+
+#. %1$s is the "delete" submit button text
+#. %2$s is the title of the "advanced" tab
+#: views/collections/edit.thtml:95
+#, fuzzy
+msgid "collections_edit_delete_upon_submit"
+msgstr ""
+"Upon clicking \"%1$s\" below, your collection will be deleted. If you do not "
+"want to delete your collection, uncheck the confirmation box in the \"%2$s\" "
+"tab and continue editing your collection. If you leave this page without "
+"saving, your collection will also not be deleted."
+
+#: views/collections/edit.thtml:94
+#, fuzzy
+msgid "collections_edit_delete_warning"
+msgstr "Your collection is about to be deleted!"
+
+#: views/collections/add.thtml:76 views/collections/edit.thtml:144
+#, fuzzy
+msgid "collections_edit_form_error_description"
+msgstr "You must provide a description of your collection."
+
+#: views/collections/edit.thtml:181
+#, fuzzy
+msgid "collections_edit_form_error_icon"
+msgstr "There was an error uploading your icon."
+
+#: views/collections/add.thtml:69 views/collections/edit.thtml:130
+#, fuzzy
+msgid "collections_edit_form_error_name"
+msgstr "You must give your collection a name."
+
+#: views/collections/edit.thtml:158
+#, fuzzy
+msgid "collections_edit_form_error_nickname"
+msgstr "If you choose a nickname, it must be unique."
+
+#: views/collections/add.thtml:93 views/collections/edit.thtml:249
+#, fuzzy
+msgid "collections_edit_formfield_addons"
+msgstr "Add-on name:"
+
+#: views/collections/edit.thtml:281
+#, fuzzy
+msgid "collections_edit_formfield_application"
+msgstr "Associated Application"
+
+#: views/collections/edit.thtml:282
+#, fuzzy
+msgid "collections_edit_formfield_application_description"
+msgstr "Select the application that your collection supports."
+
+#: views/collections/edit.thtml:288
+#, fuzzy
+msgid "collections_edit_formfield_collectiontype"
+msgstr "Collection Type"
+
+#: views/collections/edit.thtml:295
+#, fuzzy
+msgid "collections_edit_formfield_deletecollection"
+msgstr "Delete Collection"
+
+#: views/collections/edit.thtml:296
+#, fuzzy
+msgid "collections_edit_formfield_deletecollection_description"
+msgstr "Deleting your collection will permanently erase it."
+
+#: views/collections/add.thtml:73 views/collections/edit.thtml:140
+#, fuzzy
+msgid "collections_edit_formfield_description"
+msgstr "Collection Description"
+
+#: views/collections/add.thtml:74 views/collections/edit.thtml:141
+#, fuzzy
+msgid "collections_edit_formfield_description_description"
+msgstr "Briefly describe your collection and the kind of add-ons in it"
+
+#: views/collections/edit.thtml:162
+#, fuzzy
+msgid "collections_edit_formfield_icon"
+msgstr "Icon"
+
+#: views/collections/edit.thtml:163
+#, fuzzy
+msgid "collections_edit_formfield_icon_description"
+msgstr ""
+"You can upload a JPG, GIF or PNG icon that will be resized to 32x32 pixels."
+
+#: views/collections/add.thtml:80 views/collections/edit.thtml:189
+#, fuzzy
+msgid "collections_edit_formfield_listed"
+msgstr "Who can view your collection?"
+
+#: views/collections/add.thtml:81 views/collections/edit.thtml:190
+#, fuzzy
+msgid "collections_edit_formfield_listed_description"
+msgstr ""
+"By default, collections appear in the public Collection Directory and are "
+"discoverable by anyone. If you want to restrict your collection to be "
+"viewable only by people who are given a special link, choose that option "
+"below."
+
+#: views/collections/add.thtml:84 views/collections/edit.thtml:193
+#, fuzzy
+msgid "collections_edit_formfield_listed_false"
+msgstr "Only people I invite can view my collection"
+
+#: views/collections/add.thtml:83 views/collections/edit.thtml:192
+#, fuzzy
+msgid "collections_edit_formfield_listed_true"
+msgstr "Everyone can view my collection in the directory"
+
+#: views/collections/edit.thtml:223
+#, fuzzy
+msgid "collections_edit_formfield_managers"
+msgstr "Who can manage my collection?"
+
+#: views/collections/edit.thtml:224
+#, fuzzy
+msgid "collections_edit_formfield_managers_description"
+msgstr ""
+"These users can publish add-ons to your collection, manage all add-ons and "
+"settings, and grant other users permission."
+
+#: views/collections/add.thtml:66 views/collections/edit.thtml:126
+#, fuzzy
+msgid "collections_edit_formfield_name"
+msgstr "Collection Name"
+
+#: views/collections/add.thtml:67 views/collections/edit.thtml:127
+#, fuzzy
+msgid "collections_edit_formfield_name_description"
+msgstr ""
+"Give your collection a descriptive name, such as \"Dave's Favorite Travel "
+"Add-ons\""
+
+#: views/collections/edit.thtml:148
+#, fuzzy
+msgid "collections_edit_formfield_nickname"
+msgstr "Collection Nickname"
+
+#: views/collections/edit.thtml:149
+#, fuzzy
+msgid "collections_edit_formfield_nickname_description"
+msgstr "Optionally, give your collection a unique nickname for quick access:"
+
+#: views/collections/edit.thtml:201
+#, fuzzy
+msgid "collections_edit_formfield_publishers"
+msgstr "Who can publish add-ons to your collection?"
+
+#: views/collections/edit.thtml:202
+#, fuzzy
+msgid "collections_edit_formfield_publishers_description"
+msgstr ""
+"These users can publish add-ons to your collection and remove add-ons that "
+"they publish."
+
+#: views/collections/edit.thtml:210 views/collections/edit.thtml:232
+#, fuzzy
+msgid "collections_edit_formfield_users_add"
+msgstr "Enter the e-mail address of a Firefox Add-ons account:"
+
+#: views/collections/edit.thtml:216 views/collections/edit.thtml:238
+#, fuzzy
+msgid "collections_edit_formfield_users_delete_noscript"
+msgstr "Selected accounts will be removed upon Save"
+
+#: views/collections/edit.thtml:215 views/collections/edit.thtml:237
+#, fuzzy
+msgid "collections_edit_formfield_users_new_noscript"
+msgstr ""
+"Enter a comma-separated list of e-mail addresses of Firefox Add-ons accounts"
+
+#: views/collections/edit.thtml:204 views/collections/edit.thtml:226
+#, fuzzy
+msgid "collections_edit_formfield_users_onlyme"
+msgstr "Only me"
+
+#: views/collections/edit.thtml:205 views/collections/edit.thtml:227
+#, fuzzy
+msgid "collections_edit_formfield_users_otherusers"
+msgstr "Myself and these users:"
+
+#: views/collections/edit.thtml:211 views/collections/edit.thtml:233
+#, fuzzy
+msgid "collections_edit_formfield_users_submit"
+msgstr "Add"
+
+#. %1$s is the name of the collection
+#: views/collections/edit.thtml:68
+#, fuzzy
+msgid "collections_edit_header"
+msgstr "Manage %1$s"
+
+#: views/collections/edit.thtml:246
+#, fuzzy
+msgid "collections_edit_header_addons"
+msgstr "Manage Collection Contents"
+
+#: views/collections/edit.thtml:253 views/collections/edit.thtml:258
+#, fuzzy
+msgid "collections_edit_header_addons_current"
+msgstr "Current Add-ons:"
+
+#: views/collections/edit.thtml:279
+#, fuzzy
+msgid "collections_edit_header_advanced"
+msgstr "Advanced Settings"
+
+#: views/collections/edit.thtml:186
+#, fuzzy
+msgid "collections_edit_header_permissions"
+msgstr "Manage Collection Permissions"
+
+#: views/collections/edit.thtml:170
+#, fuzzy
+msgid "collections_edit_icon_cancel"
+msgstr "Cancel"
+
+#: views/collections/edit.thtml:174 views/collections/edit.thtml:179
+#, fuzzy
+msgid "collections_edit_icon_delete"
+msgstr "Delete Icon"
+
+#: views/collections/edit.thtml:178
+#, fuzzy
+msgid "collections_edit_icon_replace"
+msgstr "Replace Icon"
+
+#. %1$s is the label of the edit form's submit button
+#: views/collections/edit.thtml:169
+#, fuzzy
+msgid "collections_edit_icon_toberemoved"
+msgstr "Icon will be removed when \"%1$s\" is clicked below"
+
+#: views/collections/edit.thtml:155
+#, fuzzy
+msgid "collections_edit_nickname_available"
+msgstr "Nickname Available"
+
+#: controllers/collections_controller.php:943
+#, fuzzy
+msgid "collections_edit_nickname_error"
+msgstr ""
+"Your nickname contained invalid characters and was corrected. Please try "
+"again."
+
+#: views/collections/edit.thtml:156
+#, fuzzy
+msgid "collections_edit_nickname_taken"
+msgstr "Nickname Taken"
+
+#. This string is followed by a URL pointing to the collection's view page
+#: views/collections/edit.thtml:75
+#, fuzzy
+msgid "collections_edit_saved_nextstep"
+msgstr "Your collection can be accessed at this location:"
+
+#: views/collections/edit.thtml:74
+#, fuzzy
+msgid "collections_edit_saved_success"
+msgstr "Your collection was successfully saved!"
+
+#: views/collections/edit.thtml:169 views/collections/edit.thtml:300
+#: views/collections/edit.thtml:308 views/pages/js_constants.js.thtml:99
+#, fuzzy
+msgid "collections_edit_submit"
+msgstr "Update Collection"
+
+#: views/collections/edit.thtml:96 views/collections/edit.thtml:297
+#: views/pages/js_constants.js.thtml:100
+#, fuzzy
+msgid "collections_edit_submit_deletecollection"
+msgstr "Delete Collection"
+
+#: views/collections/edit.thtml:111
+#, fuzzy
+msgid "collections_edit_tabheader_addons"
+msgstr "Add-ons"
+
+#: views/collections/edit.thtml:97 views/collections/edit.thtml:113
+#, fuzzy
+msgid "collections_edit_tabheader_advanced"
+msgstr "Advanced"
+
+#: views/collections/edit.thtml:108
+#, fuzzy
+msgid "collections_edit_tabheader_details"
+msgstr "Name &amp; Details"
+
+#: views/collections/edit.thtml:109
+#, fuzzy
+msgid "collections_edit_tabheader_permissions"
+msgstr "Permissions"
+
+#: models/collection_promo.php:53
+#, fuzzy
+msgid "collections_family_tagline"
+msgstr "Add-ons can keep an eye on your kids and your calendar."
+
+#: models/collection_promo.php:53
+#, fuzzy
+msgid "collections_family_title"
+msgstr "Family Organizer"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:70
+#, fuzzy
+msgid "collections_index_a_check_out"
+msgstr "Check out Add-on Collector"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:52
+#, fuzzy
+msgid "collections_index_a_create"
+msgstr "Create a Collection"
+
+#: views/collections/detail.thtml:139 views/collections/listing.thtml:85
+#: views/search/collections.thtml:84
+#, fuzzy
+msgid "collections_index_button_go"
+msgstr "Go"
+
+#. %1$s is a URL.
+#: controllers/collections_controller.php:182
+#, fuzzy
+msgid "collections_index_filler_favorites"
+msgstr ""
+"<p><strong>You don't have any favorite collections yet.</strong></p> "
+"<p>Collections you mark as favorites can be quickly accessed from this page, "
+"and will appear in the <a href='%1$s'>Add-on Collector</a> if you've "
+"installed it.</p>"
+
+#. %1$s is a URL.
+#: controllers/collections_controller.php:167
+#, fuzzy
+msgid "collections_index_filler_mine"
+msgstr ""
+"<p>You haven't created any collections yet. Collections are easy to create "
+"and fill with your favorite add-ons. <a href='%1$s'>Try it out</a>!</p>"
+
+#: views/collections/listing.thtml:51
+#, fuzzy
+msgid "collections_index_header_collections"
+msgstr "Collections"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:60
+#, fuzzy
+msgid "collections_index_header_collector"
+msgstr "Add-on Collector"
+
+#. %1$s is a comma-separated list of author names
+#: views/elements/amo2009/collection_listing_item.thtml:84
+#: views/collections/detail.thtml:151
+#, fuzzy
+msgid "collections_index_header_created"
+msgstr "created by %1$s"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:47
+#, fuzzy
+msgid "collections_index_header_what"
+msgstr "What are Collections?"
+
+#: views/collections/detail.thtml:132 views/collections/listing.thtml:78
+#: views/search/collections.thtml:66
+#, fuzzy
+msgid "collections_index_label_sortby"
+msgstr "Sort by"
+
+#: controllers/collections_controller.php:130
+#, fuzzy
+msgid "collections_index_li_editors"
+msgstr "Editor's Picks"
+
+#: views/collections/subscribe.thtml:64
+#: controllers/collections_controller.php:140
+#, fuzzy
+msgid "collections_index_li_favorites"
+msgstr "My Favorites"
+
+#: controllers/collections_controller.php:138
+#, fuzzy
+msgid "collections_index_li_mine"
+msgstr "My Collections"
+
+#: controllers/collections_controller.php:132
+#, fuzzy
+msgid "collections_index_li_popular"
+msgstr "Popular"
+
+#: views/search/collections.thtml:74 controllers/collections_controller.php:81
+#, fuzzy
+msgid "collections_index_option_all"
+msgstr "Most popular all time"
+
+#: views/search/collections.thtml:72 controllers/collections_controller.php:78
+#, fuzzy
+msgid "collections_index_option_month"
+msgstr "Most popular this month"
+
+#: views/search/collections.thtml:76 controllers/collections_controller.php:84
+#, fuzzy
+msgid "collections_index_option_newest"
+msgstr "Newest"
+
+#: views/search/collections.thtml:70 controllers/collections_controller.php:75
+#, fuzzy
+msgid "collections_index_option_week"
+msgstr "Most popular this week"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:67
+#, fuzzy
+msgid "collections_index_p_collector"
+msgstr ""
+"There's a new way to manage and find favorite add-ons. Comment, share and "
+"sync collections, all from your browser"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:48
+#, fuzzy
+msgid "collections_index_p_what_are"
+msgstr "Collections are groups of related add-ons assembled for easy sharing."
+
+#. %s is a date in the _('date') format
+#: views/elements/collections_interactive_addon.thtml:85
+#, php-format
+msgid "collections_interactive_addon_added"
+msgstr "%s ditambahkan"
+
+#: models/collection_promo.php:55
+#, fuzzy
+msgid "collections_reference_tagline"
+msgstr "Add-ons can do better research online."
+
+#: models/collection_promo.php:55
+#, fuzzy
+msgid "collections_reference_title"
+msgstr "Reference Desk"
+
+#: models/collection_promo.php:52
+#, fuzzy
+msgid "collections_social_tagline"
+msgstr "Add-ons can manage your social network."
+
+#: models/collection_promo.php:52
+#, fuzzy
+msgid "collections_social_title"
+msgstr "Social Circuit"
+
+#: views/collections/subscribe.thtml:91
+#, fuzzy
+msgid "collections_subscribe_button_close"
+msgstr "Close"
+
+#: views/collections/subscribe.thtml:70
+#, fuzzy
+msgid "collections_subscribe_error"
+msgstr ""
+"An error occurred trying to add a favorite collection. Is this collection "
+"already a favorite?"
+
+#: views/collections/subscribe.thtml:96
+#, fuzzy
+msgid "collections_subscribe_label_bothersome"
+msgstr "Don't show me this message again."
+
+#. %1$s is the collection name
+#: views/collections/subscribe.thtml:60
+#, fuzzy
+msgid "collections_subscribe_success"
+msgstr "%1$s has been added to your favorite collections."
+
+#. %1$s is the link to the "My Favorites" tab on the main collections page
+#. %2$s is the localized title of the "My Favorites" tab
+#. %3$s is the link URL to the collector add-on
+#: views/collections/subscribe.thtml:62
+#, fuzzy
+msgid "collections_subscribe_success_desc"
+msgstr ""
+"You can now quickly find this collection from the <a href=\"%1$s\">%2$s</a> "
+"tab in the directory. For an even easier way to keep track of your favorite "
+"collections, try out our <a href=\"%3$s\">Add-on Collector</a> extension for "
+"Firefox."
+
+#: views/collections/listing.thtml:55
+#, fuzzy
+msgid "collections_success_delete"
+msgstr "The collection has been deleted."
+
+#: models/collection_promo.php:54
+#, fuzzy
+msgid "collections_travel_tagline"
+msgstr "Add-ons can turn you into a travel agent."
+
+#: models/collection_promo.php:54
+#, fuzzy
+msgid "collections_travel_title"
+msgstr "The Traveler's Pack"
+
+#. A collection of add-ons that is automatically built for a user. They are "automatically published" to this collection.
+#: controllers/collections_controller.php:581
+#, fuzzy
+msgid "collections_type_autopublisher"
+msgstr "Auto-publisher"
+
+#. A collection that has been chosen by an Editor as notable or exceptional
+#: controllers/collections_controller.php:582
+#, fuzzy
+msgid "collections_type_editorspick"
+msgstr "Editor's Pick"
+
+#: controllers/collections_controller.php:580
+#, fuzzy
+msgid "collections_type_normal"
+msgstr "Normal"
+
+#: views/collections/subscribe.thtml:84
+#, fuzzy
+msgid "collections_unsubscribe_error"
+msgstr ""
+"An error occurred trying to remove a favorite collection. Was this "
+"collection not a favorite?"
+
+#. %1$s is the collection name
+#: views/collections/subscribe.thtml:78
+#, fuzzy
+msgid "collections_unsubscribe_success"
+msgstr "%1$s has been removed from your favorite collections."
+
+#: models/collection_promo.php:56
+#, fuzzy
+msgid "collections_webdev_tagline"
+msgstr "Add-ons make it easier to build the perfect website."
+
+#: models/collection_promo.php:56
+#, fuzzy
+msgid "collections_webdev_title"
+msgstr "Web Developer's Toolbox"
+
+#: views/elements/amo2009/collections_sidebar_whatare.thtml:40
+#, fuzzy
+msgid "collections_whatare_header"
+msgstr "What are Collections?"
+
+#: views/elements/amo2009/collections_sidebar_whatare.thtml:45
+#, fuzzy
+msgid "collections_whatare_learnmore"
+msgstr "Read the FAQ"
+
+#: views/elements/amo2009/collections_sidebar_whatare.thtml:44
+#, fuzzy
+msgid "collections_whatare_text"
+msgstr ""
+"There’s a new way to manage and find favorite add-ons. Comment, share and "
+"sync collections, all from your browser."
+
+#: views/pages/collector_faq.thtml:61 views/pages/collector_features.thtml:67
+#, fuzzy
+msgid "collector_features_a_home"
+msgstr "Add-on Collector Home"
+
+#: views/elements/amo2009/collector_sidebar_download.thtml:46
+#, fuzzy
+msgid "collector_features_heading_download"
+msgstr "Download the Add-on Collector:"
+
+#: views/elements/amo2009/collector_sidebar_download.thtml:43
+#: views/pages/collector_firstrun.thtml:116 views/pages/collector.thtml:69
+#, fuzzy
+msgid "collector_features_img_logo"
+msgstr "Add-on Collector Logo"
+
+#: views/compatibility/dashboard.thtml:49
+#: controllers/compatibility_controller.php:72
+msgid "compatibility_dashboard_center_header"
+msgstr "Pusat Kompatibilitas Pengaya"
+
+#. %1$s is the name of an application and a version. Example: Firefox 3.0
+#. %2$s is the name of an application. Example: Firefox
+#: views/compatibility/dashboard.thtml:50
+msgid "compatibility_dashboard_intro"
+msgstr ""
+"Persiapkan selalu untuk rilis %1$s dengan perangkat dan informasi yang "
+"tersedia melalui komunitas Pengaya %2$s yang ada di bawah ini."
+
+#: views/compatibility/dashboard.thtml:103
+msgid "compatibility_dashboard_loading"
+msgstr "Memuat data..."
+
+#: views/compatibility/dashboard.thtml:45
+msgid "compatibility_dashboard_main_link"
+msgstr "Kembali ke Utama"
+
+#: views/compatibility/dashboard.thtml:100 views/compatibility/report.thtml:43
+msgid "compatibility_dashboard_report"
+msgstr "Laporan Kompatibilitas Pengaya"
+
+#: views/compatibility/dashboard.thtml:53
+#: views/compatibility/dashboard.thtml:110
+#: views/compatibility/developers.thtml:43
+msgid "compatibility_developer_info"
+msgstr "Informasi untuk Pengembang Pengaya"
+
+#: views/compatibility/developers.thtml:66
+msgid "compatibility_developers_adjust_maxversion"
+msgstr "Sesuaikan maxVersion tanpa mengunggah lagi"
+
+#: views/compatibility/dashboard.thtml:124
+msgid "compatibility_developers_check_status"
+msgstr "Perikas Status Pengaya Saya"
+
+#. %1$s is a URL
+#. %2$s is an application and version. Example: Firefox 3.0
+#: views/compatibility/dashboard.thtml:126
+msgid "compatibility_developers_login_first"
+msgstr ""
+"Jika anda memiliki pengaya yang diletakkan di situs Pengaya Mozilla, <a href="
+"\"%1$s\">silakan log-masuk</a> untuk menganalisis status pengaya anda untuk %"
+"2$s."
+
+#: views/compatibility/dashboard.thtml:114
+msgid "compatibility_developers_mdclogo_alt"
+msgstr "Logo Mozilla Developer Center"
+
+#: views/compatibility/developers.thtml:73
+msgid "compatibility_developers_no_addons"
+msgstr ""
+"Anda tidak memiliki pengaya yang diletakkan pada situs Pengaya Mozilla."
+
+#: views/compatibility/dashboard.thtml:133
+#: views/compatibility/developers.thtml:55
+msgid "compatibility_developers_results"
+msgstr "Hasil Pemeriksaan Status Pengaya"
+
+#: views/compatibility/dashboard.thtml:137
+msgid "compatibility_developers_retrieving"
+msgstr "Mengambil status pengaya yang diletakkan di sini..."
+
+#. %1$s is a number
+#. %2$s is an application name
+#. %3$s is a number.
+#. Full example: 50 Firefox users (10% of total)
+#: views/compatibility/developers.thtml:65
+msgid "compatibility_developers_user_count"
+msgstr "%1$s %2$s pengguna (total %3$s&#37;)"
+
+#: views/compatibility/report.thtml:45
+msgid "compatibility_report_detail_intro"
+msgstr ""
+"Pengaya berikut memiliki penggunaan hingga 95% yang diketahui Mozilla dan "
+"diurut berdasar ukuran penggunaannya."
+
+#: views/compatibility/dashboard.thtml:94
+msgid "compatibility_report_detailed_link"
+msgstr "Tampilkan Laporan Detail"
+
+#. %1$s and %2$s are numbers
+#. %3$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:65
+msgid "compatibility_report_intro"
+msgstr ""
+"Dari sebanyak %1$s pengaya yang memiliki penggunaan hingga 95&#37; yang "
+"diketahui Mozilla, <b>%2$s&#37;</b> dapat dipertimbangkan sebagai kompatibel "
+"dengan build terakhir %3$s."
+
+#: views/compatibility/dashboard.thtml:81
+msgid "compatibility_report_legend_alpha"
+msgstr "Versi Alfa"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:81
+msgid "compatibility_report_legend_alpha_description"
+msgstr "Pengaya yang kompatibel dengan versi alfa %1$s"
+
+#: views/compatibility/dashboard.thtml:85
+msgid "compatibility_report_legend_beta"
+msgstr "Versi Beta"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:85
+msgid "compatibility_report_legend_beta_description"
+msgstr "Pengaya yang kompatibel dengan versi beta atau kandidat rilis %1$s"
+
+#: views/compatibility/dashboard.thtml:89
+msgid "compatibility_report_legend_latest"
+msgstr "Versi Terbaru"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:89
+msgid "compatibility_report_legend_latest_description"
+msgstr "Pengaya sudah up-to-date dengan build terakhir %1$s"
+
+#: views/compatibility/dashboard.thtml:77
+msgid "compatibility_report_legend_other"
+msgstr "Versi Lainnya"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:77
+msgid "compatibility_report_legend_other_description"
+msgstr "Pengaya yang tidak kompatibel dengan versi %1$s apapun"
+
+#: views/compatibility/dashboard.thtml:62
+msgid "compatibility_report_title"
+msgstr "Laporan Kompatibilitas Pengaya"
+
+#: views/compatibility/dashboard.thtml:54
+#: views/compatibility/dashboard.thtml:144 views/compatibility/users.thtml:42
+msgid "compatibility_user_info"
+msgstr "Informasi untuk Pengguna Pengaya"
+
+#: views/compatibility/dashboard.thtml:52
+msgid "compatibility_view_report"
+msgstr "Tampilkan Laporan Kompatibilitas"
+
+#. %s is a URL
+#: views/pages/credits.thtml:142
+#, php-format
+msgid "credits_contributing"
+msgstr "Untuk informasi cara berkontribusi, silakan kunjungi %s kami."
+
+#: views/pages/credits.thtml:142
+msgid "credits_contributing_wikipage"
+msgstr "halaman wiki"
+
+#: views/pages/credits.thtml:99
+msgid "credits_intro"
+msgstr ""
+"Mozilla mengucapkan terima kasih kepada pihak-pihak berikut atas kontribusi "
+"mereka kepada proyek addons.mozilla.org selama ini:"
+
+#: views/pages/credits.thtml:103
+msgid "credits_section_developers"
+msgstr "Pengembang"
+
+#: views/pages/credits.thtml:115
+msgid "credits_section_editors"
+msgstr "Penyunting"
+
+#: views/pages/credits.thtml:109
+msgid "credits_section_localizers"
+msgstr "Alih Bahasa"
+
+#: views/pages/credits.thtml:121
+msgid "credits_section_other_contributors"
+msgstr "Kontributor Lainnya"
+
+#: views/pages/credits.thtml:127
+msgid "credits_section_past_developers"
+msgstr "Pengembang Sebelumnya"
+
+#: views/pages/credits.thtml:133
+msgid "credits_section_software"
+msgstr "Perangkat Lunak dan Gambar"
+
+#: views/pages/credits.thtml:136
+msgid "credits_software_famfamfam"
+msgstr ""
+"Beberapa ikon yang digunakan berasal dari <a href=\"http://www.famfamfam.com/"
+"lab/icons/silk/\">famfamfam Silk Icon Set</a>, yang menggunakan lisensi <a "
+"href=\"http://creativecommons.org/licenses/by/2.5/\">Creative Commons "
+"Attribution 2.5 License</a>."
+
+#: views/pages/credits.thtml:137
+#, fuzzy
+msgid "credits_software_timeplot"
+msgstr ""
+"Some pages use elements of <a href=\"http://www.simile-widgets.org/timeplot/"
+"\">Timeplot</a>, licensed under a <a href=\"http://simile.mit.edu/license."
+"html\">BSD License</a>."
+
+#. date format string as used in PHP's strftime():
+#. http://php.net/strftime
+#: views/elements/collections_interactive_addon.thtml:85
+#: views/elements/amo2009/addon_version_detail.thtml:53
+#: views/elements/amo2009/homepage_addon.thtml:115
+#: views/elements/addon_version_detail.thtml:54
+#: views/elements/addon_listitem.thtml:124 views/elements/feature.thtml:106
+#: views/collections/detail.thtml:118 views/collections/edit.thtml:325
+#: views/users/info.thtml:76 views/editors/reviews_queue.thtml:57
+#: views/editors/reviews_queue.thtml:68 views/developers/dashboard.thtml:65
+#: views/developers/versions_edit.thtml:208 views/developers/versions.thtml:67
+#: views/search/rss/index.thtml:5 views/addons/rss/versions.thtml:42
+#: views/addons/display.thtml:104 views/addons/display.thtml:356
+#: views/addons/browse_thumbs.thtml:75 views/reviews/add.thtml:63
+#: views/reviews/display.thtml:74 views/reviews/display.thtml:160
+#: views/reviews/delete.thtml:54 controllers/statistics_controller.php:244
+#: controllers/collections_controller.php:1047
+msgid "date"
+msgstr "%e %B %Y"
+
+#. date and time format string (strftime)
+#. http://php.net/strftime
+#: views/elements/addon_version_detail.thtml:53
+#: views/developers/discuss.thtml:52 views/developers/discuss.thtml:62
+#: views/admin/addons_status.thtml:57
+msgid "datetime"
+msgstr "%e %B %Y, %H:%M"
+
+#: views/elements/developers/actionbar.thtml:47
+msgid "devcp_actionbar_link_details"
+msgstr "Detil"
+
+#: views/elements/developers/actionbar.thtml:42
+#: views/elements/developers/actionbar.thtml:50
+#: views/developers/dashboard.thtml:64
+msgid "devcp_actionbar_link_edit"
+msgstr "Ubah Pengaya"
+
+#: views/elements/developers/actionbar.thtml:51
+msgid "devcp_actionbar_link_newversion"
+msgstr "Unggah Versi Baru"
+
+#: views/elements/developers/actionbar.thtml:44
+#: views/elements/developers/actionbar.thtml:49
+#: views/developers/dashboard.thtml:73
+msgid "devcp_actionbar_link_stats"
+msgstr "Panel Statistik"
+
+#. %1$s is a filename, e.g. "foo.txt"
+#. %2$s is the extension, e.g. ".txt"
+#. %3$s is a list of valid extensions, like ".png, .jpg, .gif"
+#: controllers/developers_controller.php:1361
+#, fuzzy
+msgid "devcp_add_previews_extension_error"
+msgstr "File %1$s has an invalid extension (%2$s). Allowed extensions: %3$s"
+
+#. %s is the filename.
+#: controllers/developers_controller.php:1394
+#, fuzzy
+msgid "devcp_add_previews_save_error"
+msgstr "File %s could not be saved to the database. Please try again."
+
+#. %1$s is the preview ID number, %2$s is the filename.
+#: controllers/developers_controller.php:1389
+#, fuzzy
+msgid "devcp_add_previews_success_replace"
+msgstr "Preview %1$s was replaced with file %2$s successfully."
+
+#. %s is the filename.
+#: controllers/developers_controller.php:1391
+#, fuzzy
+msgid "devcp_add_previews_success_upload"
+msgstr "File %s was uploaded successfully. You can add a caption below."
+
+#: controllers/components/developers.php:1163
+msgid "devcp_additem_addontype_autodetect"
+msgstr "(deteksi otomatis)"
+
+#: views/elements/developers/additem.thtml:76
+msgid "devcp_additem_linktitle_opensin_newwindow"
+msgstr "Buka di jendela baru"
+
+#: views/elements/developers/additem.thtml:41
+msgid "devcp_additem_sidebar_title"
+msgstr "Ajukan Pengaya"
+
+#: views/elements/developers/additem.thtml:53
+msgid "devcp_additem_step0_newlink"
+msgstr "Perjanjian Pengembang"
+
+#: views/elements/developers/additem.thtml:46
+msgid "devcp_additem_step1_link"
+msgstr "Langkah pertama: Unggah"
+
+#: views/elements/developers/additem.thtml:47
+msgid "devcp_additem_step2_link"
+msgstr "Langkah ke-2: Detil Pengaya"
+
+#: views/elements/developers/additem.thtml:48
+msgid "devcp_additem_step3_link"
+msgstr "Langkah ke-3: Detil Versi"
+
+#: views/elements/developers/additem.thtml:49
+msgid "devcp_additem_step4_link"
+msgstr "Langkah ke-4: Alih Bahasa (Localization)"
+
+#: views/elements/developers/additem.thtml:50
+msgid "devcp_additem_step5_link"
+msgstr "Langkah ke-5: Sukses"
+
+#: views/elements/developers/additem.thtml:76
+msgid "devcp_additem_submissionhelp_link"
+msgstr "Bantuan untuk Pengajuan"
+
+#: controllers/previews_controller.php:168
+#: controllers/previews_controller.php:277
+msgid "devcp_addon_field_preview_caption_displaytitle"
+msgstr "Judul Pratinjau"
+
+#: views/developers/addon_status.thtml:177
+#, fuzzy
+msgid "devcp_addon_status_action_activate"
+msgstr "Make Active"
+
+#: views/developers/addon_status.thtml:178
+#, fuzzy
+msgid "devcp_addon_status_action_activate_description"
+msgstr ""
+"Make your add-on active for it to show up in public listings and enable the "
+"update check service."
+
+#: views/developers/addon_status.thtml:135
+#, fuzzy
+msgid "devcp_addon_status_action_complete"
+msgstr "Complete Add-on"
+
+#: views/developers/addon_status.thtml:136
+#, fuzzy
+msgid "devcp_addon_status_action_complete_description"
+msgstr "Complete your add-on and move to the Sandbox"
+
+#: views/developers/addon_status.thtml:181
+#, fuzzy
+msgid "devcp_addon_status_action_deactivate"
+msgstr "Make Inactive"
+
+#: views/developers/addon_status.thtml:182
+#, fuzzy
+msgid "devcp_addon_status_action_deactivate_description"
+msgstr ""
+"Make your add-on inactive to hide it from all public listings and disable "
+"the update check service."
+
+#: views/developers/addon_status.thtml:143
+#, fuzzy
+msgid "devcp_addon_status_action_move"
+msgstr "Move to Sandbox"
+
+#: views/developers/addon_status.thtml:144
+#, fuzzy
+msgid "devcp_addon_status_action_move_description"
+msgstr "Move your add-on back to the Sandbox. This is reversible."
+
+#: views/developers/addon_status.thtml:139
+#, fuzzy
+msgid "devcp_addon_status_action_nominate"
+msgstr "Nominate for Public"
+
+#: views/developers/addon_status.thtml:140
+#, fuzzy
+msgid "devcp_addon_status_action_nominate_description"
+msgstr "Nominate your add-on to become Public"
+
+#: views/developers/addon_status.thtml:147
+#, fuzzy
+msgid "devcp_addon_status_action_public"
+msgstr "Make Public"
+
+#: views/developers/addon_status.thtml:148
+#, fuzzy
+msgid "devcp_addon_status_action_public_description"
+msgstr "Make your add-on Public again."
+
+#: views/developers/addon_status.thtml:169
+#, fuzzy
+msgid "devcp_addon_status_active"
+msgstr ""
+"Your add-on is <span class=\"inactive-0\">Active</span>. This means your add-"
+"on is showing up in all available listings appropriate for its status above."
+
+#: views/developers/addon_status.thtml:111
+#, fuzzy
+msgid "devcp_addon_status_completion_disabled"
+msgstr ""
+"Please fulfill the criteria above before you can complete your add-on and "
+"move it to the <span class=\"status-1\">Sandbox</span>."
+
+#: views/developers/addon_status.thtml:108
+#, fuzzy
+msgid "devcp_addon_status_completion_enabled"
+msgstr ""
+"You may now complete your add-on and move it to the <span class=\"status-1"
+"\">Sandbox</span> by clicking the button below."
+
+#: views/developers/addon_status.thtml:102
+#, fuzzy
+msgid "devcp_addon_status_criteria_category"
+msgstr "At least one category selected"
+
+#: views/developers/addon_status.thtml:101
+#, fuzzy
+msgid "devcp_addon_status_criteria_description"
+msgstr "Add-on Description required"
+
+#: views/developers/addon_status.thtml:99
+#, fuzzy
+msgid "devcp_addon_status_criteria_name"
+msgstr "Add-on Name required"
+
+#: views/developers/addon_status.thtml:120
+#, fuzzy
+msgid "devcp_addon_status_criteria_prerelease"
+msgstr "Add-on is not marked as pre-release."
+
+#: views/developers/addon_status.thtml:119
+#, fuzzy
+msgid "devcp_addon_status_criteria_preview"
+msgstr "At least one preview image required for extensions and themes."
+
+#: views/developers/addon_status.thtml:100
+#, fuzzy
+msgid "devcp_addon_status_criteria_summary"
+msgstr "Add-on Summary required"
+
+#. %s is the status in a span, e.g. "<span>_('Public')</span>".
+#: views/developers/addon_status.thtml:58
+#, fuzzy
+msgid "devcp_addon_status_header"
+msgstr "Add-on Status: %s"
+
+#: views/developers/addon_status.thtml:152
+#: views/developers/addon_status.thtml:173
+#, fuzzy
+msgid "devcp_addon_status_header_actions"
+msgstr "Available Actions"
+
+#: views/developers/addon_status.thtml:168
+#, fuzzy
+msgid "devcp_addon_status_header_active"
+msgstr "Active Status: <span class=\"inactive-0\">Active</span>"
+
+#: views/developers/addon_status.thtml:97
+#, fuzzy
+msgid "devcp_addon_status_header_criteria"
+msgstr "Add-on Completion Criteria"
+
+#: views/developers/addon_status.thtml:164
+#, fuzzy
+msgid "devcp_addon_status_header_inactive"
+msgstr "Active Status: <span class=\"inactive-1\">Inactive</span>"
+
+#: views/developers/addon_status.thtml:117
+#, fuzzy
+msgid "devcp_addon_status_header_nomination"
+msgstr "Public Nomination Criteria"
+
+#: views/developers/addon_status.thtml:190
+#, fuzzy
+msgid "devcp_addon_status_header_trusted"
+msgstr "Trusted Status: <span class=\"status-4\">Trusted</span>"
+
+#: views/developers/addon_status.thtml:165
+#, fuzzy
+msgid "devcp_addon_status_inactive"
+msgstr ""
+"Your add-on is <span class=\"inactive-1\">Inactive</span>. This means your "
+"add-on will not show up in any listing, regardless of its status above. "
+"Updates are <b>not</b> being provided to your add-on through the update "
+"check service."
+
+#: views/developers/addon_status.thtml:128
+#, fuzzy
+msgid "devcp_addon_status_nominate_disabled"
+msgstr ""
+"Please fulfill the criteria above before nominating your add-on to become "
+"<span class=\"status-4\">Public</span>."
+
+#: views/developers/addon_status.thtml:125
+#, fuzzy
+msgid "devcp_addon_status_nominate_enabled"
+msgstr ""
+"You may now nominate your add-on for <span class=\"status-4\">Public</span> "
+"by clicking the button below."
+
+#: views/developers/addon_status.thtml:64
+#, fuzzy
+msgid "devcp_addon_status_public"
+msgstr "Public"
+
+#: views/developers/addon_status.thtml:63
+#, fuzzy
+msgid "devcp_addon_status_sandbox"
+msgstr "Sandbox"
+
+#. %s is an email address.
+#: views/developers/addon_status.thtml:89
+#, fuzzy
+msgid "devcp_addon_status_switch_disabled"
+msgstr ""
+"Your add-on was <span class=\"status-5\">Disabled</span> by an administrator "
+"and cannot be used. If you have any questions, please e-mail %s."
+
+#: views/developers/addon_status.thtml:67
+#, fuzzy
+msgid "devcp_addon_status_switch_incomplete"
+msgstr ""
+"Your add-on is currently <span class=\"status-0\">Incomplete</span>. This "
+"means your add-on is not showing up on any portion of the site or update "
+"check service. You may come to this page to complete your add-on after it "
+"meets the criteria below for completion and transfer to the <span class="
+"\"status-1\">Sandbox</span>."
+
+#. %s is a number, perhaps 42.
+#: views/developers/addon_status.thtml:77
+#, fuzzy
+msgid "devcp_addon_status_switch_nominated"
+msgstr ""
+"Your add-on is currently nominated to become <span class=\"status-4"
+"\">Public</span> and is awaiting editor review. There are currently %s other "
+"add-ons in the nomination queue."
+
+#. %s is an email address.
+#: views/developers/addon_status.thtml:81
+#, fuzzy
+msgid "devcp_addon_status_switch_pending"
+msgstr ""
+"Your add-on is pending. This shouldn't have happened. Please e-mail %s with "
+"your add-on ID and state this error."
+
+#: views/developers/addon_status.thtml:85
+#, fuzzy
+msgid "devcp_addon_status_switch_public"
+msgstr ""
+"Your add-on is <span class=\"status-4\">Public</span>, which means it will "
+"show up in all listings and searches and can be downloaded without "
+"restriction. Updates are being provided to your add-on through the update "
+"check service."
+
+#: views/developers/addon_status.thtml:71
+#: views/developers/addon_status.thtml:75
+#, fuzzy
+msgid "devcp_addon_status_switch_sandbox"
+msgstr ""
+"Your add-on is in the <span class=\"status-1\">Sandbox</span>, which means "
+"it will show up in listings and searches, but users must log in to download "
+"it. Updates are <b>not</b> being provided to your add-on through the update "
+"check service."
+
+#. %s is the add-on name.
+#: views/developers/addon_status_nominate.thtml:43
+#: views/developers/addon_status_confirm.thtml:43
+#: views/developers/addon_status.thtml:43
+#, fuzzy
+msgid "devcp_addon_status_title"
+msgstr "%s Status"
+
+#: views/developers/addon_status.thtml:191
+#, fuzzy
+msgid "devcp_addon_status_trusted"
+msgstr ""
+"Your add-on is <span class=\"status-4\">Trusted</span>. This means you can "
+"submit updates to your add-on without editor review."
+
+#: views/developers/dashboard.thtml:68
+#, fuzzy
+msgid "devcp_dashboard_active"
+msgstr "Active"
+
+#. %1$s is the add-on type string
+#. %2$s is Inactive or Active in a <span>
+#. %3$s is the addon's public status (Public, In Sandbox, ...) in a <span>
+#: views/developers/dashboard.thtml:69
+#, fuzzy
+msgid "devcp_dashboard_addontype_status"
+msgstr "%1$s currenty %2$s and %3$s"
+
+#: views/developers/dashboard.thtml:67
+#, fuzzy
+msgid "devcp_dashboard_change_status"
+msgstr "Change Status"
+
+#. %s is the addons email address.
+#: views/developers/dashboard.thtml:99
+#, fuzzy
+msgid "devcp_dashboard_disabled_questions"
+msgstr ""
+"Your add-on was disabled by an administrator and cannot be used. If you "
+"have any questions, please email %s."
+
+#. %s is the (localized) add-on status string in a span, e.g. "Disabled"
+#: views/developers/dashboard.thtml:98
+#, fuzzy
+msgid "devcp_dashboard_disabled_status"
+msgstr "Add-on Status: %s"
+
+#: views/developers/dashboard.thtml:43
+#, fuzzy
+msgid "devcp_dashboard_header_main"
+msgstr "Developer Dashboard"
+
+#: views/developers/dashboard.thtml:110
+#, fuzzy
+msgid "devcp_dashboard_header_welcome"
+msgstr "Welcome to the Developer Dashboard"
+
+#: views/developers/dashboard.thtml:68
+#, fuzzy
+msgid "devcp_dashboard_inactive"
+msgstr "Inactive"
+
+#. %s is a date in the _('date') format
+#: views/developers/dashboard.thtml:65
+#, fuzzy
+msgid "devcp_dashboard_last_edited"
+msgstr "Last edited on %s"
+
+#: views/developers/dashboard.thtml:111
+#, fuzzy
+msgid "devcp_dashboard_learn"
+msgstr ""
+"You don't currently have any add-ons hosted on Mozilla Add-ons. To learn how "
+"the process works and submit your first add-on, click Get Started below."
+
+#: views/developers/dashboard.thtml:112
+#, fuzzy
+msgid "devcp_dashboard_start"
+msgstr "Get Started"
+
+#: views/developers/dashboard.thtml:82
+#, fuzzy
+msgid "devcp_dashboard_versions"
+msgstr "Versions and Files"
+
+#: views/developers/dashboard.thtml:91
+#, fuzzy
+msgid "devcp_dashboard_versions_new"
+msgstr "Upload a new version"
+
+#. %s is the preview ID number.
+#: controllers/developers_controller.php:1415
+#, fuzzy
+msgid "devcp_delete_previews_error"
+msgstr "Preview %s could not be deleted from the database. Please try again."
+
+#. %s is the preview ID number.
+#: controllers/developers_controller.php:1413
+#, fuzzy
+msgid "devcp_delete_previews_success"
+msgstr "Preview %s has been deleted successfully."
+
+#: controllers/developers_controller.php:1089
+#, fuzzy
+msgid "devcp_delete_version_priv_error"
+msgstr "You do not have privileges to delete versions or files."
+
+#. %1$s is the count of files, a number
+#. %2$s is a status string like _('Public') or _('Incomplete')
+#: controllers/components/amo.php:549
+#, fuzzy
+msgid "devcp_describe_version_status"
+msgid_plural "devcp_describe_version_status"
+msgstr[0] "%1$s %2$s file"
+msgstr[1] "%1$s %2$s files"
+
+#. %s is a version number. Example: 3.0
+#: views/developers/versions.thtml:65
+#, php-format
+msgid "devcp_details_version"
+msgstr "Versi %s"
+
+#: views/developers/discuss.thtml:68
+msgid "devcp_discuss_addreply_header"
+msgstr "Tambah Balasan"
+
+#: views/developers/discuss.thtml:57
+msgid "devcp_discuss_allreplies_header"
+msgstr "Balasan"
+
+#. notice when an error occurs saving a discussion reply
+#. %1 is the email address (linked) for the amo-editors list
+#: views/developers/discuss.thtml:70
+msgid "devcp_discuss_error_notice"
+msgstr ""
+"Terjadi kesalahan saat menyimpan balasan. Silakan hubungi %1$s tentang "
+"masalah ini."
+
+#. %1 is the add-on name, %2 is the add-on's version number currently being reviewed by an editor
+#: views/developers/discuss.thtml:46
+msgid "devcp_discuss_intro"
+msgstr ""
+"Seorang Editor Mozilla Add-ons meminta keterangan lebih lanjut mengenai "
+"versi %2$s pengaya %1$s Anda."
+
+#. %1 is the add-on name
+#: views/developers/discuss.thtml:43
+msgid "devcp_discuss_pagetitle"
+msgstr "Tambahkan Informasi Lainnya untuk Keperluan Peninjauan Pengaya %1$s"
+
+#. submit button text
+#: views/developers/discuss.thtml:79
+msgid "devcp_discuss_submit_reply"
+msgstr "Kirim Balasan"
+
+#: views/developers/discuss.thtml:72
+msgid "devcp_discuss_success_message"
+msgstr ""
+"Balasan Anda sukses disimpan. Peserta diskusi lainnya akan diberitahukan "
+"melalui email."
+
+#. in an author/editor discussion about an add-on to be reviewed:
+#. %1 is the commenter's user name (linked).
+#. %2 is the full date the comment was made.
+#: views/developers/discuss.thtml:52 views/developers/discuss.thtml:62
+msgid "devcp_discuss_writtenby"
+msgstr "ditulis oleh %1$s pada %2$s"
+
+#: views/developers/addon_edit_authors.thtml:72
+#: views/developers/addon_edit_authors.thtml:81
+#, fuzzy
+msgid "devcp_edit_authors_add_author"
+msgstr "Add New Author"
+
+#: views/developers/addon_edit_authors.thtml:96
+#, fuzzy
+msgid "devcp_edit_authors_add_author_button"
+msgstr "Add Author"
+
+#: views/developers/addon_edit_authors.thtml:83
+#, fuzzy
+msgid "devcp_edit_authors_add_email"
+msgstr "Author Account Email:"
+
+#: views/developers/addon_edit_authors.thtml:98
+#, fuzzy
+msgid "devcp_edit_authors_add_loading"
+msgstr "Checking account email..."
+
+#: views/developers/addon_edit_authors.thtml:70
+#, fuzzy
+msgid "devcp_edit_authors_click_save"
+msgstr "Click the Update Authors button below to save."
+
+#: views/developers/addon_edit_authors.thtml:58
+#, fuzzy
+msgid "devcp_edit_authors_header_current"
+msgstr "Current Authors"
+
+#: views/developers/addon_edit_authors.thtml:50
+#, fuzzy
+msgid "devcp_edit_authors_header_manage"
+msgstr "Manage Add-on Authors"
+
+#: views/developers/addon_edit_authors.thtml:93
+#, fuzzy
+msgid "devcp_edit_authors_label_add_listed"
+msgstr "List as author in pubilc display pages"
+
+#: views/developers/addon_edit_authors.thtml:89
+#, fuzzy
+msgid "devcp_edit_authors_label_developer"
+msgstr ""
+"<strong>Developer</strong> - Can manage all aspects of the add-on listing, "
+"except for adding and removing other authors."
+
+#: views/developers/addon_edit_authors.thtml:88
+#, fuzzy
+msgid "devcp_edit_authors_label_owner"
+msgstr ""
+"<strong>Owner</strong> - Can manage all aspects of the add-on listing, "
+"including adding and removing other authors."
+
+#: views/developers/addon_edit_authors.thtml:90
+#, fuzzy
+msgid "devcp_edit_authors_label_viewer"
+msgstr ""
+"<strong>Viewer</strong> - Can view add-on developer listing and statistics, "
+"but can't make any changes."
+
+#. Placeholder for the empty option in a <select>.
+#: views/developers/addon_edit_categories.thtml:69
+#, fuzzy
+msgid "devcp_edit_authors_option_empty"
+msgstr "----------------"
+
+#: views/developers/addon_edit_authors.thtml:86
+#, fuzzy
+msgid "devcp_edit_authors_select_role"
+msgstr "Select a role for the author:"
+
+#. Column name in a table.
+#: views/developers/addon_edit_authors.thtml:62
+#, fuzzy
+msgid "devcp_edit_authors_th_author"
+msgstr "Author"
+
+#. Column name in a table.
+#: views/developers/addon_edit_authors.thtml:64
+#, fuzzy
+msgid "devcp_edit_authors_th_listed"
+msgstr "Listed"
+
+#. Column name in a table.
+#: views/developers/addon_edit_authors.thtml:63
+#, fuzzy
+msgid "devcp_edit_authors_th_role"
+msgstr "Role"
+
+#: views/developers/addon_edit_authors.thtml:77
+#, fuzzy
+msgid "devcp_edit_authors_update_author"
+msgstr "Update authors"
+
+#: views/developers/addon_edit_categories.thtml:99
+#, fuzzy
+msgid "devcp_edit_categories_button_update"
+msgstr "Update Categories"
+
+#: views/developers/addon_edit_categories.thtml:88
+#, fuzzy
+msgid "devcp_edit_categories_does_not_fit"
+msgstr "My add-on doesn't fit into any available categories."
+
+#. %s is the application name (Firefox, Thunderbird).
+#: views/developers/addon_edit_categories.thtml:61
+#, fuzzy
+msgid "devcp_edit_categories_header_application"
+msgstr "%s Categories"
+
+#: views/developers/addon_edit_categories.thtml:49
+#, fuzzy
+msgid "devcp_edit_categories_header_manage"
+msgstr "Manage Add-on Categories"
+
+#: views/developers/addon_edit_categories.thtml:91
+#, fuzzy
+msgid "devcp_edit_categories_hover"
+msgstr "Hover over a category to see its description."
+
+#. %s is the category number (1, 2, 3).
+#: views/developers/addon_edit_categories.thtml:67
+#, fuzzy
+msgid "devcp_edit_categories_label_category_num"
+msgstr "Category %s"
+
+#: views/developers/addon_edit_categories.thtml:94
+#: views/developers/addon_edit_categories.thtml:103
+#, fuzzy
+msgid "devcp_edit_categories_none_available"
+msgstr "No categories are available for this add-on type and application."
+
+#: views/developers/addon_edit_categories.thtml:86
+#, fuzzy
+msgid "devcp_edit_categories_other"
+msgstr ""
+"Place your add-on into this category only if it does not fit into any other "
+"available categories."
+
+#. %s is the application name (Firefox, Thunderbird).
+#: views/developers/addon_edit_categories.thtml:63
+#, fuzzy
+msgid "devcp_edit_categories_select_application_categories"
+msgstr "Select up to three %s categories for your add-on"
+
+#: views/developers/addon_edit.thtml:47
+#, fuzzy
+msgid "devcp_edit_dd_manage_authors"
+msgstr "Add or remove users that can manage this add-on."
+
+#: views/developers/addon_edit.thtml:49
+#, fuzzy
+msgid "devcp_edit_dd_manage_categories"
+msgstr ""
+"Select the relevant categories for each application your add-on supports."
+
+#: views/developers/addon_edit.thtml:51
+#, fuzzy
+msgid "devcp_edit_dd_manage_description"
+msgstr ""
+"Add and modify translations for your add-on's summary, description, end-user "
+"license, and privacy policy."
+
+#: views/developers/addon_edit.thtml:53
+#, fuzzy
+msgid "devcp_edit_dd_manage_properties"
+msgstr "Change your add-on's name, homepage, icon, and other flags."
+
+#: views/developers/addon_edit_descriptions.thtml:116
+#, fuzzy
+msgid "devcp_edit_description_button_update"
+msgstr "Update Descriptions"
+
+#: views/developers/addon_edit_descriptions.thtml:115
+#, fuzzy
+msgid "devcp_edit_description_correct_error"
+msgstr "Please correct the errors above indicated in red."
+
+#: views/developers/addon_edit_descriptions.thtml:51
+#, fuzzy
+msgid "devcp_edit_descriptions_header"
+msgstr "Edit Add-on Descriptions"
+
+#: views/developers/addon_edit_descriptions.thtml:94
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_comments_description"
+msgstr ""
+"Any information end users may want to know that isn't necessarily applicable "
+"to the add-on summary or description. Common uses include listing known "
+"major bugs, information on how to report bugs, anticipated release date of a "
+"new version, etc."
+
+#: views/developers/addon_edit_descriptions.thtml:93
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_comments_name"
+msgstr "Developer Comments"
+
+#: views/developers/addon_edit_descriptions.thtml:86
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_description_description"
+msgstr ""
+"The description of your add-on is a longer explanation of features, "
+"functionality, and other relevant information. It is displayed under the "
+"summary on the add-on's display page."
+
+#: views/developers/addon_edit_descriptions.thtml:85
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_description_name"
+msgstr "Add-on Description"
+
+#: views/developers/addon_edit_descriptions.thtml:103
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_eula_description"
+msgstr ""
+"If your add-on has an End-User License Agreement (EULA), please enter its "
+"text below. If set below, users will be required to agree to this before "
+"installing your add-on. Please note that a EULA is not the same as a code "
+"license such as GPL or MPL."
+
+#: views/developers/addon_edit_descriptions.thtml:102
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_eula_name"
+msgstr "End-User License Agreement"
+
+#: views/developers/addon_edit_descriptions.thtml:112
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_privacy_description"
+msgstr ""
+"If your add-on has a privacy policy, enter its text here. Your add-on's "
+"display page will display a link to the policy."
+
+#: views/developers/addon_edit_descriptions.thtml:111
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_privacy_name"
+msgstr "Privacy Policy"
+
+#: views/developers/addon_edit_descriptions.thtml:78
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_summary_description"
+msgstr ""
+"The summary is a short explanation of your add-on's basic functionality that "
+"is displayed in search and browse listings, as well as at the top of your "
+"add-on's display page. <strong>Limit of 250 characters.</strong>"
+
+#: views/developers/addon_edit_descriptions.thtml:77
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_summary_name"
+msgstr "Add-on Summary"
+
+#: views/developers/addon_edit.thtml:46
+#, fuzzy
+msgid "devcp_edit_dt_manage_authors"
+msgstr "Manage Add-on Authors"
+
+#: views/developers/addon_edit.thtml:48
+#, fuzzy
+msgid "devcp_edit_dt_manage_categories"
+msgstr "Manage Add-on Categories"
+
+#: views/developers/addon_edit.thtml:50
+#, fuzzy
+msgid "devcp_edit_dt_manage_descriptions"
+msgstr "Manage Add-on Descriptions"
+
+#: views/developers/addon_edit.thtml:52
+#, fuzzy
+msgid "devcp_edit_dt_manage_properties"
+msgstr "Manage Add-on Properties"
+
+#: views/developers/addon_edit_properties.thtml:170
+msgid "devcp_edit_label_externalsoftware"
+msgstr "Pengaya ini membutuhkan perangkat lunak eksternal"
+
+#: views/developers/addon_edit_properties.thtml:205
+msgid "devcp_edit_label_locale_disambiguation"
+msgstr "Keterangan Bahasa (Locale) Tambahan"
+
+#: views/developers/addon_edit_properties.thtml:168
+msgid "devcp_edit_label_prerelease"
+msgstr "Masih prarilis"
+
+#: views/developers/addon_edit_properties.thtml:169
+msgid "devcp_edit_label_sitespecific"
+msgstr "Pengaya ini hanya untuk situs tertentu"
+
+#: views/developers/addon_edit_properties.thtml:202
+msgid "devcp_edit_label_target_locale"
+msgstr "Target Bahasa (Locale)"
+
+#: views/developers/addon_edit_properties.thtml:212
+#, fuzzy
+msgid "devcp_edit_properties_button_update"
+msgstr "Update Properties"
+
+#: views/developers/addon_edit_properties.thtml:198
+#, fuzzy
+msgid "devcp_edit_properties_change_guid"
+msgstr "Only change if you understand all of the consequences."
+
+#: views/developers/addon_edit_properties.thtml:109
+#, fuzzy
+msgid "devcp_edit_properties_current_icon"
+msgstr "Current Icon"
+
+#: views/developers/addon_edit_properties.thtml:85
+#, fuzzy
+msgid "devcp_edit_properties_default_locale"
+msgstr ""
+"An add-on's default locale is the main locale in which translations must be "
+"present. If translations for your add-on's descriptions are unavailable in a "
+"user's selected language, they will fall back to this default locale."
+
+#: views/developers/addon_edit_properties.thtml:167
+#, fuzzy
+msgid "devcp_edit_properties_flags"
+msgstr "These flags are used to filter and classify add-ons."
+
+#: views/developers/addon_edit_properties.thtml:174
+#, fuzzy
+msgid "devcp_edit_properties_guid"
+msgstr ""
+"The GUID of your add-on is specified in its install.rdf and uniquely "
+"identifies it. You cannot change your GUID once it is listed on Mozilla Add-"
+"ons."
+
+#: views/developers/addon_edit_properties.thtml:53
+#, fuzzy
+msgid "devcp_edit_properties_header"
+msgstr "Edit Add-on Properties"
+
+#: views/developers/addon_edit_properties.thtml:186
+#, fuzzy
+msgid "devcp_edit_properties_header_addon_type"
+msgstr "Add-on Type"
+
+#: views/developers/addon_edit_properties.thtml:181
+#, fuzzy
+msgid "devcp_edit_properties_header_admin_settings"
+msgstr "Admin Settings"
+
+#: views/developers/addon_edit_properties.thtml:84
+#, fuzzy
+msgid "devcp_edit_properties_header_default_locale"
+msgstr "Default Locale"
+
+#: views/developers/addon_edit_properties.thtml:166
+#, fuzzy
+msgid "devcp_edit_properties_header_flags"
+msgstr "Add-on Flags"
+
+#: views/developers/addon_edit_properties.thtml:173
+#: views/developers/addon_edit_properties.thtml:197
+#, fuzzy
+msgid "devcp_edit_properties_header_guid"
+msgstr "Add-on GUID"
+
+#: views/developers/addon_edit_properties.thtml:104
+#, fuzzy
+msgid "devcp_edit_properties_header_icon"
+msgstr "Add-on Icon"
+
+#: views/developers/addon_edit_properties.thtml:159
+#, fuzzy
+msgid "devcp_edit_properties_header_other_settings"
+msgstr "Other Settings"
+
+#. A header on the admin page to toggle trusted status.
+#: views/developers/addon_edit_properties.thtml:182
+#, fuzzy
+msgid "devcp_edit_properties_header_trusted"
+msgstr "Trusted Add-on?"
+
+#: views/developers/addon_edit_properties.thtml:160
+#, fuzzy
+msgid "devcp_edit_properties_header_view_source"
+msgstr "View Source Online"
+
+#. %s is a comma-separated list of image extensions ".png, .jpg"
+#: views/developers/addon_edit_properties.thtml:106
+#, fuzzy
+msgid "devcp_edit_properties_icon"
+msgstr ""
+"The add-on icon is a small image that is displayed next to your add-on's "
+"name in browse and search results, display pages, and in the add-on "
+"installation dialog. The image will automatically be resized to 32 x 32 "
+"pixels. Please use one of the following image types: %s"
+
+#: views/developers/addon_edit_properties.thtml:171
+#, fuzzy
+msgid "devcp_edit_properties_label_binary"
+msgstr "This add-on contains binary components"
+
+#: views/developers/addon_edit_properties.thtml:185
+#, fuzzy
+msgid "devcp_edit_properties_label_not_trusted"
+msgstr "Not Trusted"
+
+#: views/developers/addon_edit_properties.thtml:184
+#, fuzzy
+msgid "devcp_edit_properties_label_trusted"
+msgstr "Trusted"
+
+#: views/developers/addon_edit_properties.thtml:110
+#, fuzzy
+msgid "devcp_edit_properties_new_icon"
+msgstr "New Icon"
+
+#: views/developers/addon_edit_properties.thtml:118
+#, fuzzy
+msgid "devcp_edit_properties_remove_icon"
+msgstr "Remove Icon"
+
+#: views/developers/addon_edit_properties.thtml:136
+#, fuzzy
+msgid "devcp_edit_properties_transbox_homepage_description"
+msgstr ""
+"If your add-on has another homepage, enter its address here. Adding other "
+"translations is not necessary unless your website is localized into other "
+"languages."
+
+#: views/developers/addon_edit_properties.thtml:135
+#, fuzzy
+msgid "devcp_edit_properties_transbox_homepage_name"
+msgstr "Add-on Homepage"
+
+#: views/developers/addon_edit_properties.thtml:79
+#, fuzzy
+msgid "devcp_edit_properties_transbox_name_description"
+msgstr "The name of your add-on is displayed everywhere your add-on is listed."
+
+#: views/developers/addon_edit_properties.thtml:78
+#, fuzzy
+msgid "devcp_edit_properties_transbox_name_name"
+msgstr "Add-on Name"
+
+#: views/developers/addon_edit_properties.thtml:145
+#, fuzzy
+msgid "devcp_edit_properties_transbox_supportemail_description"
+msgstr ""
+"If you have an email address for support inquiries, enter it here. Adding "
+"other translations is not necessary unless you have different email "
+"addresses for different languages."
+
+#: views/developers/addon_edit_properties.thtml:144
+#, fuzzy
+msgid "devcp_edit_properties_transbox_supportemail_name"
+msgstr "Support Email Address"
+
+#: views/developers/addon_edit_properties.thtml:154
+#, fuzzy
+msgid "devcp_edit_properties_transbox_supporturl_description"
+msgstr ""
+"If your add-on has a support website or forum, enter its address here. "
+"Adding other translations is not necessary unless your website is localized "
+"into other languages."
+
+#: views/developers/addon_edit_properties.thtml:153
+#, fuzzy
+msgid "devcp_edit_properties_transbox_supporturl_name"
+msgstr "Support Website"
+
+#: views/developers/addon_edit_properties.thtml:183
+#, fuzzy
+msgid "devcp_edit_properties_trusted"
+msgstr "Trusted add-ons can become public without Editor review."
+
+#. %s is href="..." and should stay in the <a> tag.
+#: views/developers/addon_edit_properties.thtml:119
+#, fuzzy
+msgid "devcp_edit_properties_undelete"
+msgstr "Icon will be deleted on save. <a %s>Cancel?</a>"
+
+#: views/developers/addon_edit_properties.thtml:161
+#, fuzzy
+msgid "devcp_edit_properties_view_source"
+msgstr ""
+"The source of your add-on files can be viewed online by any logged in user "
+"if you wish."
+
+#: views/developers/addon_edit_properties.thtml:162
+#, fuzzy
+msgid "devcp_edit_properties_view_source_allow"
+msgstr "Allow online source viewing"
+
+#: views/developers/addon_edit_properties.thtml:163
+#, fuzzy
+msgid "devcp_edit_properties_view_source_do_not_allow"
+msgstr "Do not allow online source viewing"
+
+#: views/elements/developers/editbox.thtml:46
+#, fuzzy
+msgid "devcp_editbox_authors"
+msgstr "Authors"
+
+#: views/elements/developers/editbox.thtml:47
+#, fuzzy
+msgid "devcp_editbox_categories"
+msgstr "Categories"
+
+#: views/elements/developers/editbox.thtml:52
+#, fuzzy
+msgid "devcp_editbox_change_status"
+msgstr "Change Status"
+
+#: views/elements/developers/editbox.thtml:48
+#, fuzzy
+msgid "devcp_editbox_descriptions"
+msgstr "Descriptions"
+
+#: views/elements/developers/editbox.thtml:43
+#, fuzzy
+msgid "devcp_editbox_edit_addon"
+msgstr "Edit Add-on"
+
+#: views/elements/developers/editbox.thtml:57
+#, fuzzy
+msgid "devcp_editbox_new_version"
+msgstr "New Version"
+
+#: views/elements/developers/editbox.thtml:49
+#, fuzzy
+msgid "devcp_editbox_properties"
+msgstr "Properties"
+
+#: views/elements/developers/editbox.thtml:60
+#, fuzzy
+msgid "devcp_editbox_screenshots"
+msgstr "Preview Screenshots"
+
+#: views/elements/developers/editbox.thtml:53
+#, fuzzy
+msgid "devcp_editbox_statistics_dashboard"
+msgstr "Statistics Dashboard"
+
+#: views/elements/developers/editbox.thtml:54
+#, fuzzy
+msgid "devcp_editbox_versions"
+msgstr "Versions and Files"
+
+#: views/elements/developers/editbox.thtml:42
+#, fuzzy
+msgid "devcp_editbox_view_listing"
+msgstr "View Listing"
+
+#: views/elements/developers/editorsmenu.thtml:59
+msgid "devcp_editorsqueue_featured"
+msgstr "Pengaya Istimewa"
+
+#. %1 is the review count
+#: views/elements/developers/editorsqueue.thtml:42
+#: views/elements/developers/editorsmenu.thtml:56
+#, php-format
+msgid "devcp_editorsqueue_moderatedreviews"
+msgid_plural "devcp_editorsqueue_moderatedreviews"
+msgstr[0] "Tinjauan yang Dimoderasi (%s)"
+msgstr[1] "Tinjauan yang Dimoderasi (%s)"
+
+#. %1 is the nominated addons count
+#: views/elements/developers/editorsqueue.thtml:44
+#: views/elements/developers/editorsmenu.thtml:58
+#, php-format
+msgid "devcp_editorsqueue_nominated"
+msgid_plural "devcp_editorsqueue_nominated"
+msgstr[0] "Pengaya yang Dicalonkan (%s)"
+msgstr[1] "Pengaya yang Dicalonkan (%s)"
+
+#. %1 is the update count
+#: views/elements/developers/editorsqueue.thtml:43
+#: views/elements/developers/editorsmenu.thtml:57
+#, php-format
+msgid "devcp_editorsqueue_pendingupdates"
+msgid_plural "devcp_editorsqueue_pendingupdates"
+msgstr[0] "Pemutakhiran Tertunda (%s)"
+msgstr[1] "Pemutakhiran Tertunda (%s)"
+
+#: controllers/statistics_controller.php:147
+#: controllers/statistics_controller.php:361
+#: controllers/previews_controller.php:108
+#: controllers/previews_controller.php:211
+#: controllers/previews_controller.php:312
+msgid "devcp_error_addon_access_denied"
+msgstr "Anda tidak mempunyai hak akses pada pengaya tersebut."
+
+#. %s is a complete URL with the text from devcp_error_appversion_reference_link_text
+#. in the <a> tag. This should be fixed.
+#: controllers/components/developers.php:591
+#, php-format
+msgid "devcp_error_appversion_reference_link"
+msgstr "Silakan lihat referensi di %s."
+
+#. This is the link text in the <a> for devcp_error_appversion_reference_link. This
+#. should be fixed.
+#: controllers/components/developers.php:591
+msgid "devcp_error_appversion_reference_link_text"
+msgstr "halaman ini"
+
+#: views/developers/addon_edit_authors.thtml:76
+#, fuzzy
+msgid "devcp_error_empty_authors"
+msgstr "Your add-on must have at least one owner."
+
+#. %1$s is the name of the file
+#: controllers/components/developers.php:658
+msgid "devcp_error_file_exists"
+msgstr ""
+"Versi pengaya sudah ada. Untuk menggantikan versi tersebut, Anda harus "
+"menghapus berkas %1$s terlebih dahulu."
+
+#. %1$s is a file extension. Example: .exe
+#. %2$s is a comma separated list of extensions. Example: .xpi, .jar
+#: controllers/components/developers.php:355
+#, php-format
+msgid "devcp_error_file_extension"
+msgstr ""
+"Ekstensi berkas (%s) tidak diizinkan untuk digunakan pada jenis pengaya yang "
+"dipilih. Silakan gunakan salah satu dari daftar di bawah ini: %s"
+
+#: controllers/components/developers.php:64
+msgid "devcp_error_five_categories"
+msgstr "Mohon tidak memilih lebih dari lima kategori."
+
+#: controllers/components/developers.php:526
+msgid "devcp_error_guid_application"
+msgstr "ID pengaya ini telah digunakan oleh aplikasi lain."
+
+#: controllers/components/developers.php:337
+#: controllers/components/developers.php:389
+msgid "devcp_error_http_incomplete"
+msgstr "Proses transfer tidak selesai"
+
+#: controllers/components/developers.php:335
+#: controllers/components/developers.php:336
+#: controllers/components/developers.php:387
+#: controllers/components/developers.php:388
+msgid "devcp_error_http_maxupload"
+msgstr "Melebihi ukuran maksimum unggahan"
+
+#: controllers/components/developers.php:338
+#: controllers/components/developers.php:390
+msgid "devcp_error_http_nofile"
+msgstr "Tidak ada berkas yang diunggah"
+
+#. %1$s is a file extension. Example: .exe
+#. %2$s is a comma separated list of extensions. Example: .xpi, .jar
+#: controllers/components/developers.php:401
+#, php-format
+msgid "devcp_error_icon_extension"
+msgstr ""
+"Ekstensi berkas (%s) tidak diizinkan untuk digunakan sebagai ikon. Silakan "
+"gunakan salah satu dari daftar di bawah ini: %s"
+
+#: controllers/developers_controller.php:504
+msgid "devcp_error_index_rdf_notfound"
+msgstr "Tidak ada berkas install.rdf pada pengaya."
+
+#: controllers/components/developers.php:601
+msgid "devcp_error_install_manifest"
+msgstr "Kesalahan berikut ditemukan pada berkas install.rdf:"
+
+#: controllers/developers_controller.php:1463
+msgid "devcp_error_invalid_addontype"
+msgstr "Mohon pilih jenis pengaya yang sah."
+
+#. %$1s is a version. Example: 3.1.1
+#. %$2s is an add-on name.
+#: controllers/components/developers.php:569
+#: controllers/components/developers.php:581
+#, php-format
+msgid "devcp_error_invalid_appversion"
+msgstr "%s bukan versi yang sah untuk %s"
+
+#. %s is a string
+#: controllers/components/developers.php:521
+#, php-format
+msgid "devcp_error_invalid_guid"
+msgstr "ID pengaya ini tidak sah: %s"
+
+#. %$1s is a version. Example: 3.1.1
+#. %$2s is an add-on name.
+#: controllers/components/developers.php:572
+#, php-format
+msgid "devcp_error_invalid_minversion"
+msgstr ""
+"%s bukan versi yang sah untuk %s: versi minimum tidak diizinkan mengandung "
+"karakter *"
+
+#: controllers/components/developers.php:536
+msgid "devcp_error_invalid_version"
+msgstr ""
+"Versi pengaya ini tidak sah: silakan baca di <a href=\"http://developer."
+"mozilla.org/en/docs/Toolkit_version_format\">spesifikasi</a>"
+
+#: controllers/components/developers.php:531
+msgid "devcp_error_invalid_version_spaces"
+msgstr ""
+"Versi pengaya ini tidak sah: versi tidak dapat mengandung karakter spasi."
+
+#. %s is an error message from the parser.
+#: controllers/components/developers.php:501
+#, php-format
+msgid "devcp_error_manifest_parse"
+msgstr "Kesalahan berikut terjadi saat mem-parse berkas install.rdf: %s"
+
+#: controllers/components/developers.php:373
+msgid "devcp_error_move_file"
+msgstr "Tidak dapat memindahkan berkas"
+
+#. %s is the name of a file
+#: controllers/components/developers.php:650
+#: controllers/components/developers.php:662
+#: controllers/components/developers.php:667
+#: controllers/components/developers.php:727
+#: controllers/components/developers.php:738
+#: controllers/components/developers.php:743
+#, php-format
+msgid "devcp_error_moving_file"
+msgstr "Kesalahan terjadi saat memindahkan %s."
+
+#: controllers/components/developers.php:595
+msgid "devcp_error_mozilla_application"
+msgstr "Paling tidak satu dari aplikasi target Mozilla harus benar."
+
+#: controllers/components/developers.php:516
+msgid "devcp_error_no_guid"
+msgstr "Tidak ada ID yang ditemukan pada berkas install.rdf pada pengaya ini."
+
+#: controllers/components/developers.php:287
+msgid "devcp_error_no_platform"
+msgstr "Tidak ada platform yang dipilih"
+
+#: controllers/components/developers.php:59
+msgid "devcp_error_one_category"
+msgstr "Pilih paling sedikit satu kategori."
+
+#: controllers/components/developers.php:92
+msgid "devcp_error_one_user"
+msgstr "Paling tidak harus ada satu orang penyusun untuk pengaya ini."
+
+#. %1$s is a file extension. Example: .exe
+#. %2$s is a comma separated list of extensions. Example: .xpi, .jar
+#: controllers/components/developers.php:1081
+#, php-format
+msgid "devcp_error_preview_extension"
+msgstr ""
+"Ekstensi berkas ini (%s) tidak diizinkan untuk diunggah sebagai pratinjau. "
+"Silakan gunakan salah satu dari daftar di bawah ini: %s"
+
+#: controllers/components/developers.php:511
+msgid "devcp_error_updatekey"
+msgstr ""
+"Pengaya tidak diperbolehkan menggunakan updateKey. Mohon hapus updateKey "
+"dari install.rdf dan coba lagi."
+
+#: controllers/components/developers.php:506
+msgid "devcp_error_updateurl"
+msgstr ""
+"Pengaya tidak diperbolehkan menggunakan tautan updateURL eksternal. Mohon "
+"hapus tautan dari install.rdf dan coba lagi."
+
+#: controllers/developers_controller.php:465
+#: controllers/components/developers.php:271
+msgid "devcp_error_upload_file"
+msgstr "Mohon unggah satu berkas."
+
+#: views/developers/uploader.thtml:135
+#, fuzzy
+msgid "devcp_input_upload_file"
+msgstr "Upload File"
+
+#: views/pages/js_constants.js.thtml:89
+#, fuzzy
+msgid "devcp_js_a_cancel"
+msgstr "Cancel"
+
+#: views/pages/js_constants.js.thtml:90
+#, fuzzy
+msgid "devcp_js_add_email"
+msgstr "Please enter the account email of the author you wish to add."
+
+#. alt text for a down-arrow image.
+#: views/pages/js_constants.js.thtml:81
+#, fuzzy
+msgid "devcp_js_img_move_down"
+msgstr "Move Down"
+
+#. alt text for an up-arrow image.
+#: views/pages/js_constants.js.thtml:82
+#, fuzzy
+msgid "devcp_js_img_move_up"
+msgstr "Move Up"
+
+#: views/pages/js_constants.js.thtml:91
+#, fuzzy
+msgid "devcp_js_img_remove_compat"
+msgstr "Remove Application Compatibility"
+
+#: views/pages/js_constants.js.thtml:86
+#, fuzzy
+msgid "devcp_js_input_list_author"
+msgstr "List as author in public listings"
+
+#: views/pages/js_constants.js.thtml:92
+#, fuzzy
+msgid "devcp_js_license_select"
+msgstr "Please select a license."
+
+#: views/pages/js_constants.js.thtml:93
+#, fuzzy
+msgid "devcp_js_license_text"
+msgstr "Please enter text for your license."
+
+#. <option> text in a <select> for Author role in an add-on.
+#: views/pages/js_constants.js.thtml:84
+#, fuzzy
+msgid "devcp_js_option_developer"
+msgstr "Developer"
+
+#. <option> text in a <select> for Author role in an add-on.
+#: views/pages/js_constants.js.thtml:83
+#, fuzzy
+msgid "devcp_js_option_owner"
+msgstr "Owner"
+
+#. <option> text in a <select> for Author role in an add-on.
+#: views/pages/js_constants.js.thtml:85
+#, fuzzy
+msgid "devcp_js_option_viewer"
+msgstr "Viewer"
+
+#: views/pages/js_constants.js.thtml:88
+#, fuzzy
+msgid "devcp_js_remove_author"
+msgstr "Remove Author"
+
+#: views/pages/js_constants.js.thtml:87
+#, fuzzy
+msgid "devcp_js_sure_remove"
+msgstr "Are you <strong>sure</strong> you wish to remove this author?"
+
+#: views/pages/js_constants.js.thtml:77
+#, fuzzy
+msgid "devcp_js_upload_alert"
+msgstr "You must select a file to upload."
+
+#. %1$s is an addon id, like 32.
+#. %2$s is a version number, like 3.5.
+#: controllers/components/developers.php:1212
+#, fuzzy
+msgid "devcp_license_existing"
+msgstr "Custom license for add-on %1$s v%2$s"
+
+#: views/elements/developers/localebox.thtml:44
+msgid "devcp_localebox_header_localizedfields"
+msgstr "Isian Alih Bahasa"
+
+#. %1 is the default locale
+#: views/elements/developers/localebox.thtml:48
+#, php-format
+msgid "devcp_localebox_intro"
+msgstr ""
+"Beberapa isian pada halaman ini telah dialihbahasakan pada bahasa pengguna. "
+"Pilih bahasa di bawah ini untuk mengubah detil pengaya pada bahasa yang "
+"bersangkutan. Jika alih bahasa untuk bahasa tersebut tidak ada maka akan "
+"ditampilkan bahasa yang default (%s). "
+
+#: views/elements/developers/sidebar.thtml:68
+#: views/elements/developers/myaddons.thtml:75
+msgid "devcp_myaddons_admincp_link"
+msgstr "Perangkat Admin"
+
+#: views/elements/developers/sidebar.thtml:65
+#: views/elements/developers/myaddons.thtml:72
+msgid "devcp_myaddons_editorcp_link"
+msgstr "Perangkat Penyunting"
+
+#: views/elements/developers/myaddons.thtml:52
+msgid "devcp_myaddons_link"
+msgstr "Pengayaku"
+
+#: views/elements/developers/sidebar.thtml:70
+#: views/elements/developers/myaddons.thtml:77
+msgid "devcp_myaddons_mainpage_link"
+msgstr "Kembali ke Awal"
+
+#: views/elements/developers/sidebar.thtml:63
+#: views/elements/developers/myaddons.thtml:70
+msgid "devcp_myaddons_statistics_link"
+msgstr "Panel Statistik"
+
+#: views/elements/developers/sidebar.thtml:62
+#: views/elements/developers/myaddons.thtml:69
+msgid "devcp_myaddons_submitaddon_link"
+msgstr "Ajukan Pengaya"
+
+#: views/elements/developers/sidebar.thtml:48
+#: views/elements/developers/myaddons.thtml:67
+msgid "devcp_myaddons_title"
+msgstr "Perangkat Pengembang"
+
+#. %1$s is an add-on ID, perhaps 167.
+#. %2$s is a URL.
+#: controllers/developers_controller.php:256
+#, fuzzy
+msgid "devcp_new_addon_error"
+msgstr ""
+"This add-on ID (%1$s) already exists in the database. If this is your add-"
+"on, you can <a href=\"%2$s\">upload a new version</a>."
+
+#: views/developers/addon_status_nominate.thtml:62
+#, fuzzy
+msgid "devcp_nominate_cancel"
+msgstr "Cancel and return"
+
+#. %1 is the add-on name
+#: views/developers/addon_status_nominate.thtml:61
+#, php-format
+msgid "devcp_nominate_submit_nominate"
+msgstr "Calonkan %s"
+
+#: views/developers/addon_edit_properties.thtml:50
+#: views/developers/addon_status.thtml:49
+#: views/developers/versions_edit.thtml:50
+#, fuzzy
+msgid "devcp_notice_changes_error"
+msgstr ""
+"<span>One or more of your changes couldn't be saved.</span><br />Please look "
+"for the errors below. The rest of your changes were successfully saved."
+
+#: views/developers/addon_edit_authors.thtml:47
+#: views/developers/addon_edit_properties.thtml:47
+#: views/developers/addon_status.thtml:46
+#: views/developers/addon_edit_descriptions.thtml:47
+#: views/developers/versions_edit.thtml:47
+#: views/developers/addon_edit_categories.thtml:46
+#, fuzzy
+msgid "devcp_notice_changes_saved"
+msgstr ""
+"<span>Your changes have been saved.</span><br />Please note that some "
+"changes may take several hours to appear in all areas of the website."
+
+#: controllers/previews_controller.php:252
+msgid "devcp_notice_cleardefault"
+msgstr ""
+"Menghapus pratinjau berikut akan menyebabkan pratinjau lain (jika ada) "
+"secara otomatis menjadi pratinjau default."
+
+#: controllers/previews_controller.php:184
+#: controllers/previews_controller.php:251
+msgid "devcp_notice_makedefault"
+msgstr ""
+"Jika pratinjau ini disetel sebagai pratinjau default, status default pada "
+"pratinjau yang lama akan dihapus."
+
+#: views/developers/addon_edit_authors.thtml:70
+#, fuzzy
+msgid "devcp_notice_unsaved_changes"
+msgstr "You have unsaved changes."
+
+#: controllers/developers_controller.php:87
+#: controllers/developers_controller.php:97
+#: controllers/developers_controller.php:100
+#: controllers/previews_controller.php:67
+#: controllers/previews_controller.php:79
+#: controllers/previews_controller.php:82
+msgid "devcp_pagetitle"
+msgstr "Perangkat Pengembang"
+
+#: controllers/previews_controller.php:103
+#: controllers/previews_controller.php:104
+msgid "devcp_preview_add_pagetitle"
+msgstr "Tambah Pratinjau"
+
+#: controllers/previews_controller.php:135
+msgid "devcp_preview_added_successfully"
+msgstr "Pratinjau sukses ditambah."
+
+#: controllers/previews_controller.php:323
+msgid "devcp_preview_deleted_successfully"
+msgstr "Pratinjau sukses dihapus."
+
+#: controllers/previews_controller.php:194
+#: controllers/previews_controller.php:195
+msgid "devcp_preview_edit_pagetitle"
+msgstr "Ubah Pratinjau"
+
+#: controllers/previews_controller.php:237
+msgid "devcp_preview_updated_successfully"
+msgstr "Pratinjau sukses diperbarui."
+
+#: views/developers/previews.thtml:120
+#, fuzzy
+msgid "devcp_previews_a_another"
+msgstr "Add Another Preview"
+
+#: views/developers/previews.thtml:96
+#, fuzzy
+msgid "devcp_previews_a_delete"
+msgstr "Delete Preview"
+
+#: views/developers/previews.thtml:95
+#, fuzzy
+msgid "devcp_previews_a_replace"
+msgstr "Replace Preview"
+
+#: views/developers/previews.thtml:126
+#, fuzzy
+msgid "devcp_previews_a_update"
+msgstr "Update Previews"
+
+#: views/developers/previews.thtml:115 views/developers/previews.thtml:124
+#, fuzzy
+msgid "devcp_previews_add_new"
+msgstr "Add New Preview"
+
+#. %s is a list of file extensions, e.g. ".png, .gif"
+#: views/developers/previews.thtml:116
+#, fuzzy
+msgid "devcp_previews_add_select"
+msgstr ""
+"Select an image to upload below. Images larger than the maximum size of 700 "
+"pixels wide by 525 pixels tall will be resized. Allowed file types: %s"
+
+#: views/developers/previews.thtml:121
+#, fuzzy
+msgid "devcp_previews_click_below"
+msgstr "Click Update Previews below to upload."
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/previews.thtml:102
+#, fuzzy
+msgid "devcp_previews_click_update"
+msgstr ""
+"Click the Update Previews button below to save this image. (<a %s>Cancel?</"
+"a>)"
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/previews.thtml:107
+#, fuzzy
+msgid "devcp_previews_error_message"
+msgstr ""
+"This preview will be deleted when Update Previews is clicked below. (<a %"
+"s>Cancel?</a>)"
+
+#: views/previews/add.thtml:45
+msgid "devcp_previews_filetype_info"
+msgstr ""
+"Gunakan form di bawah ini untuk mengunggah berkas tangkapan layar pengaya "
+"anda dengan format PNG, JPG atau GIF. Gambar yang lebarnya lebih dari 700 "
+"piksel atau tinggi lebih dari 525 piksel akan otomatis disesuaikan ukurannya."
+
+#: views/previews/add.thtml:43
+msgid "devcp_previews_header_add"
+msgstr "Tambah Pratinjau"
+
+#: views/developers/previews.thtml:80
+#, fuzzy
+msgid "devcp_previews_header_caption"
+msgstr "Preview Caption"
+
+#: views/previews/edit.thtml:43
+msgid "devcp_previews_header_edit"
+msgstr "Ubah Pratinjau"
+
+#: views/developers/previews.thtml:93
+#, fuzzy
+msgid "devcp_previews_label_default"
+msgstr "Default Preview"
+
+#: views/previews/add.thtml:54
+msgid "devcp_previews_label_file"
+msgstr "Berkas Pratinjau"
+
+#: views/previews/add.thtml:59 views/previews/edit.thtml:50
+msgid "devcp_previews_label_makedefault"
+msgstr "Jadikan sebagai gambar pratinjau default"
+
+#: views/developers/previews.thtml:100
+#, fuzzy
+msgid "devcp_previews_label_new"
+msgstr "New image:"
+
+#: views/developers/previews.thtml:118
+#, fuzzy
+msgid "devcp_previews_label_upload"
+msgstr "Upload Preview: "
+
+#: views/developers/previews.thtml:50
+#, fuzzy
+msgid "devcp_previews_notice_error"
+msgstr "One or more of your new previews could not be saved."
+
+#: views/developers/previews.thtml:47
+#, fuzzy
+msgid "devcp_previews_notice_success"
+msgstr "Your previews have been updated successfully."
+
+#: views/developers/previews.thtml:59
+#, fuzzy
+msgid "devcp_previews_p_screenshots"
+msgstr ""
+"The preview screenshots for your add-on are shown below. You can make "
+"changes to captions or images below. The Default Preview is the preview that "
+"is displayed next to your add-on in search and browse listings."
+
+#: views/previews/edit.thtml:55
+msgid "devcp_previews_submit_delete"
+msgstr "Hapus Pratinjau"
+
+#: views/previews/edit.thtml:55
+msgid "devcp_previews_submit_delete_confirm"
+msgstr "Yakin akan menghapus pratinjau ini?"
+
+#: views/previews/edit.thtml:54
+msgid "devcp_previews_submit_edit"
+msgstr "Ubah Pratinjau"
+
+#: views/previews/add.thtml:63
+msgid "devcp_previews_submit_upload"
+msgstr "Unggah Pratinjau"
+
+#: views/developers/previews.thtml:78
+#, fuzzy
+msgid "devcp_previews_thumbnail"
+msgstr "Thumbnail"
+
+#. %s is the add-on name.
+#: views/developers/previews.thtml:44
+#, fuzzy
+msgid "devcp_previews_title"
+msgstr "%s Preview Manager"
+
+#: views/developers/uploader.thtml:74
+msgid "devcp_review_agreement_please"
+msgstr ""
+"Mohon dibaca dan disetujui Perjanjian Pengembang berikut sebelum melanjutkan."
+
+#: views/elements/developers/rolecheck.thtml:42
+#, fuzzy
+msgid "devcp_rolecheck_no_privs"
+msgstr ""
+"<span>You do not have sufficient privileges to make changes on this page.</"
+"span><br />Contact the Add-on Owner if you need to make changes."
+
+#: controllers/developers_controller.php:1315
+#, fuzzy
+msgid "devcp_several_hours"
+msgstr ""
+"Please note that some changes may take several hours to appear in all areas "
+"of the website."
+
+#: views/elements/developers/sidebar.thtml:52
+#, fuzzy
+msgid "devcp_sidebar_a_dashboard"
+msgstr "Dashboard"
+
+#. %s is a number
+#: views/elements/developers/statsbar.thtml:45
+#: views/developers/dashboard.thtml:79
+#, php-format
+msgid "devcp_statsbar_adu"
+msgstr "<em>%s</em> Pengguna Aktif Harian"
+
+#. %s is a number
+#: views/elements/developers/statsbar.thtml:41
+#: views/developers/dashboard.thtml:75
+#, php-format
+msgid "devcp_statsbar_total_downloads"
+msgstr "<em>%s</em> Jumlah Unduhan Total"
+
+#. %s is a number
+#: views/elements/developers/statsbar.thtml:43
+#: views/developers/dashboard.thtml:77
+#, php-format
+msgid "devcp_statsbar_weekly_downloads"
+msgstr "<em>%s</em> Jumlah Unduhan Mingguan"
+
+#: views/developers/addon_status_confirm.thtml:59
+#, fuzzy
+msgid "devcp_status_confirm_active"
+msgstr ""
+"Marking this add-on active will cause it to show up in public areas "
+"appropriate for its status, including search and browse listings. It will be "
+"downloadable from the website and could be returned in client update checks, "
+"depending on its status. You will be able to return here and disable it "
+"again at your convenience."
+
+#: views/developers/addon_status_confirm.thtml:59
+#, fuzzy
+msgid "devcp_status_confirm_active_sure"
+msgstr "Are you sure you wish to mark this add-on active?"
+
+#: views/developers/addon_status_confirm.thtml:50
+#, fuzzy
+msgid "devcp_status_confirm_header_sure"
+msgstr "Are you sure?"
+
+#: views/developers/addon_status_confirm.thtml:55
+#, fuzzy
+msgid "devcp_status_confirm_inactive"
+msgstr ""
+"Marking this add-on inactive will prevent it from showing up in any public "
+"areas, including search and browse listings. It will not be downloadable "
+"from the website and will not be returned in client update checks. You will "
+"be able to return here and re-enable it at your convenience."
+
+#: views/developers/addon_status_confirm.thtml:55
+#, fuzzy
+msgid "devcp_status_confirm_inactive_sure"
+msgstr "Are you sure you wish to mark this add-on inactive?'"
+
+#: views/developers/addon_status_confirm.thtml:74
+#, fuzzy
+msgid "devcp_status_confirm_no"
+msgstr "No, cancel"
+
+#: views/developers/addon_status_confirm.thtml:67
+#, fuzzy
+msgid "devcp_status_confirm_public"
+msgstr ""
+"Making this add-on public will make it available for anyone to download and "
+"will begin offering updates to existing users."
+
+#: views/developers/addon_status_confirm.thtml:67
+#, fuzzy
+msgid "devcp_status_confirm_public_sure"
+msgstr "Are you sure you wish to make this add-on public?"
+
+#: views/developers/addon_status_confirm.thtml:63
+#, fuzzy
+msgid "devcp_status_confirm_sandbox"
+msgstr ""
+"Moving this add-on back to the sandbox will require users to login before "
+"downloading and updates will no longer be offered to existing users. Because "
+"your add-on is currently public, you will be able to return here at any time "
+"to make it public again."
+
+#: views/developers/addon_status_confirm.thtml:63
+#, fuzzy
+msgid "devcp_status_confirm_sandbox_sure"
+msgstr "Are you sure you wish to move this add-on to the sandbox?"
+
+#: views/developers/addon_status_confirm.thtml:73
+#, fuzzy
+msgid "devcp_status_confirm_yes"
+msgstr "Yes, I'm Sure"
+
+#: views/developers/addon_status_nominate.thtml:46
+#, fuzzy
+msgid "devcp_status_nominate_error_notice"
+msgstr ""
+"<span>A nomination message is required.</span><br />Please fill in the text "
+"box with the requested information and try again."
+
+#: views/developers/addon_status_nominate.thtml:55
+#, fuzzy
+msgid "devcp_status_nominate_header"
+msgstr "Add-on Nomination"
+
+#: views/developers/dashboard.thtml:85
+msgid "devcp_summary_lastversion"
+msgstr "Versi Terbaru:"
+
+#. %s is the add-on name.
+#: views/developers/addon_edit.thtml:43
+#: views/developers/addon_edit_authors.thtml:44
+#: views/developers/versions_delete.thtml:43
+#: views/developers/addon_edit_properties.thtml:44
+#: views/developers/addon_edit_descriptions.thtml:44
+#: views/developers/versions_edit.thtml:44
+#: views/developers/addon_edit_categories.thtml:43
+#: views/developers/versions.thtml:43
+#, fuzzy
+msgid "devcp_title_edit_addon"
+msgstr "Edit %s"
+
+#. title attribute for a javascript link that pops up a help dialog.
+#: views/elements/translationbox.thtml:68
+#, fuzzy
+msgid "devcp_transbox_a_title_help"
+msgstr "Help (does not leave page)"
+
+#: views/elements/translationbox.thtml:68
+#, fuzzy
+msgid "devcp_transbox_alt_help"
+msgstr "Help"
+
+#. %1$s is <span>17</span>, %2$s is 42.
+#: views/elements/translationbox.thtml:101
+#, fuzzy
+msgid "devcp_transbox_chars_used"
+msgstr "Characters used: %1$s / %2$s"
+
+#: views/elements/translationbox.thtml:132
+#, fuzzy
+msgid "devcp_transbox_delete_sure"
+msgstr "Are you sure you wish to delete this translation?"
+
+#. %s is a locale, like en-US.
+#: views/elements/translationbox.thtml:143
+#, fuzzy
+msgid "devcp_transbox_help_header_tabs"
+msgstr "What are these %s tabs?"
+
+#: views/elements/translationbox.thtml:145
+#, fuzzy
+msgid "devcp_transbox_help_header_what"
+msgstr "What if I don't have any translations?"
+
+#: views/elements/translationbox.thtml:147
+#, fuzzy
+msgid "devcp_transbox_help_hide"
+msgstr "Hide Help"
+
+#: views/elements/translationbox.thtml:146
+#, fuzzy
+msgid "devcp_transbox_help_if"
+msgstr ""
+"If a user browses the site and a translation isn't available in their own "
+"language, it will fall back to your add-on's Default Locale, specified in "
+"the Edit Add-on Properties area. If you don't have any translations, just "
+"enter what you can into your Default Locale, which should be a language you "
+"speak."
+
+#: views/elements/translationbox.thtml:144
+#, fuzzy
+msgid "devcp_transbox_help_transbox"
+msgstr ""
+"This is a <i>Translation Box</i>. It allows you to localize a specific field "
+"into any other languages for which you might have a translation. You can "
+"add, edit, and remove translations using the locale tabs."
+
+#: views/elements/translationbox.thtml:85
+#, fuzzy
+msgid "devcp_transbox_img_add_trans"
+msgstr "Add Translation"
+
+#: views/elements/translationbox.thtml:86
+#, fuzzy
+msgid "devcp_transbox_img_remove_trans"
+msgstr "Remove Translation"
+
+#: views/elements/translationbox.thtml:123
+#, fuzzy
+msgid "devcp_transbox_input_add_all"
+msgstr "Add Locale to All"
+
+#: views/elements/translationbox.thtml:122
+#, fuzzy
+msgid "devcp_transbox_input_add_locale"
+msgstr "Add Locale"
+
+#: views/elements/translationbox.thtml:124
+#: views/elements/translationbox.thtml:135
+#, fuzzy
+msgid "devcp_transbox_input_cancel"
+msgstr "Cancel"
+
+#: views/elements/translationbox.thtml:134
+#, fuzzy
+msgid "devcp_transbox_input_delete"
+msgstr "Delete It"
+
+#: views/elements/translationbox.thtml:113
+#, fuzzy
+msgid "devcp_transbox_select_locale"
+msgstr "Select the locale of the translation to add:"
+
+#. %1$s and %2$s are GUIDs.
+#: controllers/developers_controller.php:343
+#, fuzzy
+msgid "devcp_update_addon_guid_error"
+msgstr ""
+"The add-on GUID used in this file (%1$s) does not match the existing GUID "
+"for this add-on (%2$s)."
+
+#: controllers/developers_controller.php:334
+#, fuzzy
+msgid "devcp_update_addon_priv_error"
+msgstr "You do not have sufficient privileges to update this add-on."
+
+#. %1$s is a version number, %2$s is an add-on ID.
+#: controllers/developers_controller.php:399
+#, fuzzy
+msgid "devcp_update_addon_version_belong_error"
+msgstr "The specified version (%1$s) does not belong to this add-on (%2$s)."
+
+#. %1$s is a version number, maybe 1.1.
+#. %2$s is a URL.
+#: controllers/developers_controller.php:351
+#, fuzzy
+msgid "devcp_update_addon_version_exists_error"
+msgstr ""
+"The version number uploaded (%1$s) already exists for this add-on. If you "
+"are trying to add another file to this version, <a href=\"%2$s\">click here</"
+"a>."
+
+#. %1$s and %2$s are version numbers.
+#: controllers/developers_controller.php:405
+#, fuzzy
+msgid "devcp_update_addon_version_match_error"
+msgstr ""
+"The uploaded version number (%1$s) does not match the existing version "
+"number (%2$s)."
+
+#: views/developers/uploader.thtml:68
+#, fuzzy
+msgid "devcp_uploader_a_start"
+msgstr "Get Started"
+
+#: views/developers/uploader.thtml:137
+#, fuzzy
+msgid "devcp_uploader_ajax_loading"
+msgstr "Uploading file..."
+
+#: views/developers/uploader.thtml:82
+#, fuzzy
+msgid "devcp_uploader_button_agree"
+msgstr "Agree and continue"
+
+#: views/developers/uploader.thtml:157
+#, fuzzy
+msgid "devcp_uploader_button_edit"
+msgstr "Edit My Add-on"
+
+#: views/developers/uploader.thtml:158
+#, fuzzy
+msgid "devcp_uploader_button_later"
+msgstr "I'll complete my add-on later."
+
+#: views/developers/uploader.thtml:168
+#, fuzzy
+msgid "devcp_uploader_button_release"
+msgstr "Add Release Notes"
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/uploader.thtml:156
+#, fuzzy
+msgid "devcp_uploader_created_results"
+msgstr ""
+"<p>Your add-on listing has been successfully created. The basic information "
+"obtained from your uploaded file has been stored, but there's a lot more to "
+"your listing that can be customized.</p><p>Your add-on is currently marked "
+"as <strong>Incomplete</strong>. In order to complete your add-on, you'll "
+"need to make sure it has an accurate name, summary, and description, as well "
+"as at least one selected category. You can edit your add-on's information "
+"using the link below and check the status of your add-on at any time on the "
+"<a %s>status page</a>."
+
+#: views/developers/uploader.thtml:143
+#, fuzzy
+msgid "devcp_uploader_error_correct"
+msgstr "Please correct this problem and upload your file again."
+
+#. %1$s is a version number, %2$s is a status, e.g Public or Incomplete.
+#: views/developers/uploader.thtml:175
+#, fuzzy
+msgid "devcp_uploader_file_created"
+msgstr ""
+"Your new file has been added to version %1$s and is currently marked as %2$s."
+
+#: views/developers/uploader.thtml:154
+#, fuzzy
+msgid "devcp_uploader_header_created"
+msgstr "Add-on Created!"
+
+#: views/developers/uploader.thtml:141
+#, fuzzy
+msgid "devcp_uploader_header_error"
+msgstr "Oops! There seems to be a problem with this file..."
+
+#: views/developers/uploader.thtml:173
+#, fuzzy
+msgid "devcp_uploader_header_file_added"
+msgstr "File Added!"
+
+#: views/developers/uploader.thtml:66
+#, fuzzy
+msgid "devcp_uploader_header_how"
+msgstr "How does it all work?"
+
+#. %s is the version number, e.g. 3.2.
+#: views/developers/uploader.thtml:163
+#, fuzzy
+msgid "devcp_uploader_header_update_created"
+msgstr "Version %s Created"
+
+#: views/developers/uploader.thtml:117
+#, fuzzy
+msgid "devcp_uploader_header_upload"
+msgstr "Upload Your File"
+
+#: views/developers/uploader.thtml:67
+#, fuzzy
+msgid "devcp_uploader_how"
+msgstr ""
+"<p>Thanks for your interest in submitting your add-on to Mozilla Add-ons. "
+"Hosting your add-on on Mozilla Add-ons is the easiest way to handle "
+"distribution of your add-on. Here's what you'll get:</p><ul><li>Each add-on "
+"will have a public display page with information you provide, such as a "
+"brief summary of the add-on's functionality, an optional longer description, "
+"and a showcase of preview screenshots of your add-on.</li><li>Your add-on "
+"will appear in search and browse listings across the site, and even in the "
+"Add-ons Manager of Firefox 3.</li><li>We'll take care of hosting all of your "
+"downloads and providing automatic updates to users when you upload a new "
+"version.</li><li>You'll have access to a statistics dashboard with detailed "
+"information about your user base.</li></ul><p>Add-ons hosted on the site "
+"must be reviewed by a Mozilla Add-ons Editor before they will have all of "
+"the features listed above. If you're ready to start the process and have "
+"your add-on package ready for upload, just click on Get Started below!</p>"
+
+#: views/developers/uploader.thtml:125
+#, fuzzy
+msgid "devcp_uploader_label_platformtype"
+msgstr "Supported Platforms:"
+
+#: views/developers/uploader.thtml:124
+#, fuzzy
+msgid "devcp_uploader_label_upload_field"
+msgstr "Add-on File: "
+
+#: controllers/components/developers.php:1221
+#, fuzzy
+msgid "devcp_uploader_option_other"
+msgstr "Other"
+
+#. %1$s is a number, %2$s is href="..." and should stay in the <a> tag.
+#: views/developers/uploader.thtml:176
+#, fuzzy
+msgid "devcp_uploader_p_pending_file"
+msgstr ""
+"The new file will be available to the public as soon as an editor is able to "
+"review it. There are currently %1$s other add-ons in the queue. Want to be "
+"reviewed faster? Consider <a %2$s>becoming an editor</a>."
+
+#. %1$s is a number, %2$s is href="..." and should stay in the <a> tag.
+#: views/developers/uploader.thtml:166
+#, fuzzy
+msgid "devcp_uploader_p_pending_version"
+msgstr ""
+"The new version will be available to the public as soon as an editor is able "
+"to review it. There are currently %1$s other add-ons in the queue. Want to "
+"be reviewed faster? Consider <a %2$s>becoming an editor</a>."
+
+#. %s is a status, e.g Public or Incomplete.
+#: views/developers/uploader.thtml:165
+#, fuzzy
+msgid "devcp_uploader_p_update_created"
+msgstr "Your new version has been created and is currently marked as %s."
+
+#. %1$s is href="..." and should stay in the 'Versions and Files' <a> tag.
+#. %2$s is href="..." and should stay in the 'current status' <a> tag.
+#: views/developers/uploader.thtml:177
+#, fuzzy
+msgid "devcp_uploader_p_update_file"
+msgstr ""
+"View your new file in the <a %1$s>Versions and Files page</a>, check out "
+"your add-on's <a %2$s>current status</a>, or <b>add release notes</b> by "
+"clicking the button below (highly recommended)."
+
+#. %1$s is href="..." and should stay in the 'Versions and Files' <a> tag.
+#. %2$s is href="..." and should stay in the 'current status' <a> tag.
+#: views/developers/uploader.thtml:167
+#, fuzzy
+msgid "devcp_uploader_p_update_version"
+msgstr ""
+"View your new version in the <a %1$s>Versions and Files page</a>, check out "
+"your add-on's <a %2$s>current status</a>, or <b>add release notes</b> by "
+"clicking the button below (highly recommended)."
+
+#: views/developers/uploader.thtml:118
+#, fuzzy
+msgid "devcp_uploader_p_upload"
+msgstr ""
+"Upload your add-on file using the form below. If you have multiple, platform-"
+"specific files to upload, choose a single file and then upload the others "
+"using the Versions and Files Manager."
+
+#: views/developers/uploader.thtml:125
+#, fuzzy
+msgid "devcp_uploader_platformtype_all"
+msgstr "All"
+
+#: views/developers/uploader.thtml:126
+#, fuzzy
+msgid "devcp_uploader_platformtype_specific"
+msgstr "Specific:"
+
+#. Used as first item in a <select>.
+#: controllers/components/developers.php:1185
+#, fuzzy
+msgid "devcp_uploader_please_choose"
+msgstr "Please Choose..."
+
+#. %1$s is the add-on name, %2$s is the version number.
+#: views/developers/uploader.thtml:57
+#, fuzzy
+msgid "devcp_uploader_title_file"
+msgstr "Add File to %1$s %2$s"
+
+#: views/developers/uploader.thtml:50
+#, fuzzy
+msgid "devcp_uploader_title_submit"
+msgstr "Submit New Add-on"
+
+#. %s is the add-on name.
+#: views/developers/uploader.thtml:54
+#, fuzzy
+msgid "devcp_uploader_title_update"
+msgstr "Update %s"
+
+#. %s is a full <a> tag
+#: controllers/developers_controller.php:503
+#, php-format
+msgid "devcp_valid_app_reference"
+msgstr "Silakan lihat %s untuk referensi."
+
+#. This is the text in the <a> tag for devcp_valid_app_reference. This should be
+#. fixed.
+#: controllers/developers_controller.php:503
+msgid "devcp_valid_app_reference_linktext"
+msgstr "halaman ini"
+
+#: controllers/developers_controller.php:581
+#, fuzzy
+msgid "devcp_verify_author_error"
+msgstr "No account found for that email address."
+
+#: controllers/developers_controller.php:553
+#, fuzzy
+msgid "devcp_verify_search_engine_error"
+msgstr ""
+"Either the XML is invalid or required fields are missing. Please <a href="
+"\"https://developer.mozilla.org/en/Creating_OpenSearch_plugins_for_Firefox"
+"\">read the documentation</a>, verify your add-on, and try again."
+
+#: views/developers/versions.thtml:75
+#, fuzzy
+msgid "devcp_versions_a_cancel"
+msgstr "Cancel"
+
+#: views/developers/versions.thtml:79
+#, fuzzy
+msgid "devcp_versions_a_delete"
+msgstr "Delete Version"
+
+#: views/developers/versions.thtml:74
+#, fuzzy
+msgid "devcp_versions_a_empty"
+msgstr "Remove Empty Version"
+
+#: views/developers/versions.thtml:71
+#, fuzzy
+msgid "devcp_versions_a_remove"
+msgstr "Remove?"
+
+#: views/developers/versions.thtml:91
+#, fuzzy
+msgid "devcp_versions_add"
+msgstr "Add New Version"
+
+#: views/developers/versions_delete.thtml:58
+#, fuzzy
+msgid "devcp_versions_delete_a_cancel"
+msgstr "Cancel"
+
+#: views/developers/versions_delete.thtml:56
+#, fuzzy
+msgid "devcp_versions_delete_a_delete"
+msgstr "Delete Version"
+
+#. Followed by a list of reviews and files that will be removed.
+#: views/developers/versions_delete.thtml:50
+#, fuzzy
+msgid "devcp_versions_delete_also"
+msgstr "This will also delete:"
+
+#: views/developers/versions_delete.thtml:53
+#, fuzzy
+msgid "devcp_versions_delete_files"
+msgid_plural "devcp_versions_delete_files"
+msgstr[0] "%s file"
+msgstr[1] "%s files"
+
+#. %s is the version number.
+#: views/developers/versions_delete.thtml:48
+#, fuzzy
+msgid "devcp_versions_delete_header"
+msgstr "Delete Version %s?"
+
+#: views/developers/versions_delete.thtml:52
+#, fuzzy
+msgid "devcp_versions_delete_reviews"
+msgid_plural "devcp_versions_delete_reviews"
+msgstr[0] "%s review"
+msgstr[1] "%s reviews"
+
+#. %s is the version number.
+#: views/developers/versions_delete.thtml:49
+#, fuzzy
+msgid "devcp_versions_delete_sure"
+msgstr "Are you sure you want to permanently delete version %s?"
+
+#: views/developers/versions_edit.thtml:102
+#: views/developers/versions_edit.thtml:155
+#, fuzzy
+msgid "devcp_versions_edit_a_cancel"
+msgstr "Cancel"
+
+#: views/developers/versions_edit.thtml:101
+#, fuzzy
+msgid "devcp_versions_edit_a_delete"
+msgstr "Delete File"
+
+#: views/developers/versions_edit.thtml:165
+#, fuzzy
+msgid "devcp_versions_edit_a_new_app"
+msgstr "Add New Application"
+
+#: views/developers/versions_edit.thtml:154
+#, fuzzy
+msgid "devcp_versions_edit_a_remove_app"
+msgstr "Remove Application"
+
+#: views/developers/versions_edit.thtml:114
+#, fuzzy
+msgid "devcp_versions_edit_add"
+msgstr "Add New File"
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/versions_edit.thtml:121
+#, fuzzy
+msgid "devcp_versions_edit_adjust"
+msgstr ""
+"Adjusting application information here will allow users to install your add-"
+"on even if the install.rdf in the package indicates that the add-on is "
+"incompatible. <a %s>List of supported applications</a>"
+
+#: views/developers/versions_edit.thtml:153
+#, fuzzy
+msgid "devcp_versions_edit_compat_sure"
+msgstr ""
+"Are you <b>sure</b> you wish to remove compatibility with this application?"
+
+#: views/developers/versions_edit.thtml:100
+#, fuzzy
+msgid "devcp_versions_edit_delete_sure"
+msgstr "Are you <b>sure</b> you wish to permanently delete this file?"
+
+#: views/developers/versions_edit.thtml:203
+#, fuzzy
+msgid "devcp_versions_edit_header_approval"
+msgstr "Approval Information"
+
+#: views/developers/versions_edit.thtml:120
+#, fuzzy
+msgid "devcp_versions_edit_header_compat"
+msgstr "Compatible Applications"
+
+#: views/developers/versions_edit.thtml:74
+#, fuzzy
+msgid "devcp_versions_edit_header_file"
+msgstr "File Information"
+
+#: views/developers/versions_edit.thtml:189
+#, fuzzy
+msgid "devcp_versions_edit_header_license"
+msgstr "License"
+
+#. %s is the version number.
+#: views/developers/versions_edit.thtml:53
+#, fuzzy
+msgid "devcp_versions_edit_header_manage"
+msgstr "Manage Version %s"
+
+#: views/developers/versions_edit.thtml:212
+#, fuzzy
+msgid "devcp_versions_edit_header_notes"
+msgstr "Approval Notes"
+
+#: views/developers/versions_edit.thtml:98
+#, fuzzy
+msgid "devcp_versions_edit_img_delete"
+msgstr "Delete File"
+
+#. %1$s is the file id, e.g. 18723.
+#. %2$s is the platform name, e.g. ALL or Windows.
+#. %3$s is the _('date) created.
+#. %4$s is the status, e.g. "In Sandbox" or "Public".
+#. %5$s is the _('date') status was changed.
+#: views/developers/versions_edit.thtml:208
+#, fuzzy
+msgid "devcp_versions_edit_li_file"
+msgstr "File %1$s (%2$s) created on %3$s and changed to %4$s on %5$s"
+
+#: views/developers/versions_edit.thtml:190
+#, fuzzy
+msgid "devcp_versions_edit_license_description"
+msgstr ""
+"Please select the appropriate license for your add-on. This license "
+"specifies the rights you grant on your source code."
+
+#: views/developers/versions_edit.thtml:111
+#, fuzzy
+msgid "devcp_versions_edit_no_files"
+msgstr "No files found."
+
+#: views/developers/versions_edit.thtml:213
+#, fuzzy
+msgid "devcp_versions_edit_optional"
+msgstr "Optional information for the Editor that reviews this version."
+
+#: views/developers/versions_edit.thtml:151
+#, fuzzy
+msgid "devcp_versions_edit_remove_compat"
+msgstr "Remove Application Compatibility"
+
+#: views/developers/versions_edit.thtml:167
+#, fuzzy
+msgid "devcp_versions_edit_select_app"
+msgstr "Please Select an Application"
+
+#: views/developers/versions_edit.thtml:78
+#, fuzzy
+msgid "devcp_versions_edit_th_file"
+msgstr "File"
+
+#: views/developers/versions_edit.thtml:79
+#, fuzzy
+msgid "devcp_versions_edit_th_platform"
+msgstr "Platform"
+
+#: views/developers/versions_edit.thtml:80
+#, fuzzy
+msgid "devcp_versions_edit_th_size"
+msgstr "Size"
+
+#: views/developers/versions_edit.thtml:81
+#, fuzzy
+msgid "devcp_versions_edit_th_status"
+msgstr "Status"
+
+#: views/developers/versions_edit.thtml:183
+#, fuzzy
+msgid "devcp_versions_edit_transbox_releasenotes_description"
+msgstr ""
+"Information about changes in this release, new features, known bugs, and "
+"other useful information specific to this release/version. This information "
+"will also be available to users updating the add-on in the Firefox 3 Add-ons "
+"Manager interface."
+
+#: views/developers/versions_edit.thtml:182
+#, fuzzy
+msgid "devcp_versions_edit_transbox_releasenotes_name"
+msgstr "Release Notes"
+
+#: views/developers/versions_edit.thtml:164
+#, fuzzy
+msgid "devcp_versions_edit_unsaved_compat"
+msgstr ""
+"<strong>You have unsaved changes.</strong> Compatibility will not be deleted "
+"until you click Update Version below."
+
+#: views/developers/versions_edit.thtml:113
+#, fuzzy
+msgid "devcp_versions_edit_unsaved_files"
+msgstr ""
+"<strong>You have unsaved changes.</strong> Files will not be deleted until "
+"you click Update Version below."
+
+#: views/developers/versions_edit.thtml:218
+#, fuzzy
+msgid "devcp_versions_edit_update"
+msgstr "Update Versions"
+
+#: views/developers/versions.thtml:49
+#, fuzzy
+msgid "devcp_versions_header_manage"
+msgstr "Manage Versions and Files"
+
+#: views/developers/versions.thtml:87
+#, fuzzy
+msgid "devcp_versions_no_versions"
+msgstr "No versions."
+
+#. %s is a version number, base 10.
+#: views/developers/versions.thtml:46
+#, fuzzy
+msgid "devcp_versions_notice_success"
+msgstr "Version %s deleted successfully."
+
+#: views/developers/versions.thtml:73
+#, fuzzy
+msgid "devcp_versions_p_remove"
+msgstr ""
+"This version has no files associated with it and can be removed. Would you "
+"like to remove this version?"
+
+#: views/developers/versions.thtml:58
+#, fuzzy
+msgid "devcp_versions_th_created"
+msgstr "Created"
+
+#: views/developers/versions.thtml:57
+#, fuzzy
+msgid "devcp_versions_th_status"
+msgstr "Status"
+
+#: views/developers/versions.thtml:56
+#, fuzzy
+msgid "devcp_versions_th_version"
+msgstr "Version"
+
+#: controllers/downloads_controller.php:91
+msgid "downloads_disable_warning"
+msgstr "Pengaya ini dimatikan"
+
+#: controllers/components/editors.php:57
+msgid "editor_review_error_addon_not_nominated"
+msgstr "Pengaya ini belum dinominasikan."
+
+#: controllers/components/editors.php:213
+msgid "editor_review_error_file_not_pending"
+msgstr "Berkas ini tidak dalam status penundaan tinjauan."
+
+#. Actions are, for example: approving or rejecting
+#: controllers/components/editors.php:79
+#: controllers/components/editors.php:182
+msgid "editor_review_error_no_action"
+msgstr "Silakan pilih aksi."
+
+#: controllers/components/editors.php:192
+msgid "editor_review_error_no_applications"
+msgstr "Masukkan aplikasi yang diuji."
+
+#. Comments are required when an editor approves or rejects an add-on.
+#: controllers/components/editors.php:84
+#: controllers/components/editors.php:187
+msgid "editor_review_error_no_comments"
+msgstr "Masukkan komentar tinjauan."
+
+#: controllers/components/editors.php:161
+msgid "editor_review_error_no_files"
+msgstr "Pilih paling tidak satu berkas untuk ditinjau."
+
+#: controllers/components/editors.php:197
+msgid "editor_review_error_no_operating_system"
+msgstr "Masukkan sistem operasi yang diujikan."
+
+#: views/editors/logs.thtml:51
+msgid "editorcp_logs_button_filter"
+msgstr "Filter"
+
+#: views/editors/logs.thtml:44
+msgid "editorcp_logs_filter_by"
+msgstr "Filter berdasar jenis/aksi"
+
+#: views/editors/logs.thtml:42 controllers/editors_controller.php:964
+msgid "editorcp_logs_page_heading"
+msgstr "Log Event"
+
+#: views/elements/developers/editorsmenu.thtml:60
+msgid "editorcp_menu_eventlog_link"
+msgstr "Log Event"
+
+#: views/elements/developers/editorsmenu.thtml:62
+msgid "editorcp_menu_mainpage_link"
+msgstr "Kembali ke Awal"
+
+#: views/elements/developers/editorsmenu.thtml:61
+msgid "editorcp_menu_reviewlog_link"
+msgstr "Log Tinjauan"
+
+#: views/elements/developers/editorsmenu.thtml:55
+msgid "editorcp_menu_summary_link"
+msgstr "Ringkasan oleh Penyunting"
+
+#: views/elements/developers/editorsmenu.thtml:52
+msgid "editorcp_menu_title"
+msgstr "Perangkat Penyunting"
+
+#: views/editors/reviewlog.thtml:49
+msgid "editorcp_reviewlog_button_filter"
+msgstr "Filter"
+
+#: views/editors/reviewlog.thtml:58
+msgid "editorcp_reviewlog_column_action"
+msgstr "Aksi"
+
+#: views/editors/reviewlog.thtml:56
+msgid "editorcp_reviewlog_column_addon"
+msgstr "Pengaya"
+
+#: views/editors/reviewlog.thtml:55
+msgid "editorcp_reviewlog_column_date"
+msgstr "Tanggal"
+
+#: views/editors/reviewlog.thtml:57
+msgid "editorcp_reviewlog_column_editor"
+msgstr "Penyunting"
+
+#: views/editors/reviewlog.thtml:94
+msgid "editorcp_reviewlog_comments_hide"
+msgstr "Sembunyikan Komentar"
+
+#: views/editors/reviewlog.thtml:93
+msgid "editorcp_reviewlog_comments_show"
+msgstr "Tampilkan Komentar"
+
+#. %1$s and %2$s are full <input> tags for dates
+#: views/editors/reviewlog.thtml:45
+#, php-format
+msgid "editorcp_reviewlog_entries_between"
+msgstr "Tampikan entri sejak %s hingga %s"
+
+#: views/editors/reviewlog.thtml:104
+msgid "editorcp_reviewlog_none_found"
+msgstr "Tidak ada tinjauan untuk periode ini."
+
+#: views/editors/reviewlog.thtml:42
+msgid "editorcp_reviewlog_page_heading"
+msgstr "Log Tinjauan"
+
+#: views/editors/summary.thtml:61
+msgid "editorcp_summary_monthreviews_heading"
+msgstr "Tinjauan Bulanan"
+
+#: views/editors/summary.thtml:77
+msgid "editorcp_summary_neweditors_heading"
+msgstr "Penyunting Baru"
+
+#: views/editors/summary.thtml:42
+msgid "editorcp_summary_page_heading"
+msgstr "Ringkasan Penyunting"
+
+#: views/editors/summary.thtml:94
+msgid "editorcp_summary_recentactivity_heading"
+msgstr "Aktivitas Penyunting Terbaru"
+
+#: views/editors/summary.thtml:45
+msgid "editorcp_summary_totalreviews_heading"
+msgstr "Total Tinjauan"
+
+#: controllers/editors_controller.php:248
+#: controllers/editors_controller.php:249
+msgid "editors_addon_review_pagetitle"
+msgstr "Tinjau Pengaya"
+
+#: controllers/editors_controller.php:349
+msgid "editors_error_js-formerror"
+msgstr "Mohon lengkapi isian berikut:"
+
+#: controllers/editors_controller.php:350
+msgid "editors_error_review_one_file"
+msgstr "Silakan pilih minimum satu berkas untuk ditinjau."
+
+#: controllers/editors_controller.php:274
+msgid "editors_error_self_reviews_forbidden"
+msgstr "Tinjauan untuk pengaya milik diri sendiri tidak diizinkan."
+
+#: controllers/editors_controller.php:699
+msgid "editors_external_software"
+msgstr "Perangkat Lunak Eksternal"
+
+#: views/editors/featured.thtml:120 views/editors/featured.thtml:121
+msgid "editors_featured_add_feature"
+msgstr "Tambah pengaya istimewa"
+
+#: views/editors/featured.thtml:126
+msgid "editors_featured_add_feature_submit"
+msgstr "Tambah"
+
+#: views/editors/featured.thtml:49 controllers/editors_controller.php:832
+#: controllers/editors_controller.php:848
+msgid "editors_featured_addon_add_failure"
+msgstr "Gagal menambah pengaya istimewa."
+
+#: controllers/editors_controller.php:851
+msgid "editors_featured_addon_add_success"
+msgstr "Sukses menambah pengaya istimewa."
+
+#: views/editors/featured.thtml:50 controllers/editors_controller.php:839
+#: controllers/editors_controller.php:868
+#: controllers/editors_controller.php:886
+msgid "editors_featured_addon_edit_failure"
+msgstr "Gagal menyunting pengaya istimewa."
+
+#: views/editors/featured.thtml:51 controllers/editors_controller.php:888
+msgid "editors_featured_addon_edit_success"
+msgstr "Sukses menyunting pengaya istimewa"
+
+#: views/editors/featured.thtml:53 controllers/editors_controller.php:861
+msgid "editors_featured_addon_invalid_locale"
+msgstr "Satu atau lebih bahasa (locale) tidak sah."
+
+#: views/editors/featured.thtml:52 controllers/editors_controller.php:906
+msgid "editors_featured_addon_remove_failure"
+msgstr "Gagal menghapus pengaya istimewa."
+
+#: controllers/editors_controller.php:901
+msgid "editors_featured_addon_remove_success"
+msgstr "Sukses menghapus pengaya istimewa."
+
+#: controllers/editors_controller.php:915
+#: controllers/editors_controller.php:917
+msgid "editors_featured_addons_pagetitle"
+msgstr "Pengaya Istimewa"
+
+#: views/editors/featured.thtml:54 views/editors/featured.thtml:107
+msgid "editors_featured_edit_feature_submit"
+msgstr "Kirim"
+
+#: views/editors/featured.thtml:90 views/editors/featured.thtml:91
+msgid "editors_featured_remove_feature"
+msgstr "Hapus pengaya istimewa"
+
+#: views/editors/queue.thtml:46
+msgid "editors_filter_queue"
+msgstr "Antrian Filter"
+
+#: views/editors/queue.thtml:182
+msgid "editors_helpful_links"
+msgstr "Tautan yang Berkaitan"
+
+#: views/editors/queue.thtml:182
+msgid "editors_link_guide"
+msgstr "Petunjuk untuk Penyunting"
+
+#: views/editors/queue.thtml:182
+msgid "editors_link_policy"
+msgstr "Kebijakan Pengaya"
+
+#: views/editors/queue.thtml:47
+msgid "editors_notice_filter_session"
+msgstr "Filter ini akan tetap berlaku untuk sesi ini atau hingga dibersihkan."
+
+#. %1 is the queue mode
+#: views/editors/queue.thtml:177 views/admin/flagged_queue.thtml:89
+msgid "editors_notice_none_found"
+msgstr "Tidak ada pengaya yang berada pada jenis tinjauan ini."
+
+#: controllers/editors_controller.php:1040
+msgid "editors_one_day"
+msgstr "1 hari"
+
+#: controllers/editors_controller.php:1048
+msgid "editors_one_hour"
+msgstr "1 jam"
+
+#: controllers/editors_controller.php:1056
+msgid "editors_one_minute"
+msgstr "1 menit"
+
+#: controllers/editors_controller.php:64 controllers/editors_controller.php:73
+#: controllers/editors_controller.php:77
+msgid "editors_pagetitle"
+msgstr "Perangkat Penyunting"
+
+#. %s is a comma separated list of platforms. Example: Windows, OS X
+#: controllers/editors_controller.php:680
+#: controllers/editors_controller.php:683
+#, php-format
+msgid "editors_platform_x_only"
+msgstr "hanya %s"
+
+#: controllers/editors_controller.php:695
+msgid "editors_pre-release"
+msgstr "Prarilis"
+
+#. %1 is the app name
+#: views/editors/queue.thtml:131
+#, php-format
+msgid "editors_queue_app_compatibility"
+msgstr "Kompatibilitas dengan %s"
+
+#: views/editors/queue.thtml:51
+#, fuzzy
+msgid "editors_queue_filter_label_addon"
+msgstr "Add-on or Author Email"
+
+#: views/editors/queue.thtml:72
+#, fuzzy
+msgid "editors_queue_filter_label_addontypes"
+msgstr "Add-on Types"
+
+#: views/editors/queue.thtml:56
+#, fuzzy
+msgid "editors_queue_filter_label_application"
+msgstr "Application"
+
+#: views/editors/queue.thtml:61
+#, fuzzy
+msgid "editors_queue_filter_label_maxversion"
+msgstr "Max. Version"
+
+#: views/editors/queue.thtml:78
+#, fuzzy
+msgid "editors_queue_filter_label_platforms"
+msgstr "Platforms"
+
+#: views/editors/queue.thtml:66
+#, fuzzy
+msgid "editors_queue_filter_label_submissionage"
+msgstr "Age of Submission (days)"
+
+#. %1$s is a number
+#: views/editors/queue.thtml:90
+#, fuzzy
+msgid "editors_queue_filter_result_count"
+msgid_plural "editors_queue_filter_result_count"
+msgstr[0] "Results of your filtered search: <strong>%1$s</strong> Add-on"
+msgstr[1] "Results of your filtered search: <strong>%1$s</strong> Add-ons"
+
+#: views/editors/queue.thtml:84
+msgid "editors_queue_submit_clean"
+msgstr "Bersihkan"
+
+#: views/editors/queue.thtml:83
+msgid "editors_queue_submit_filter"
+msgstr "Filter"
+
+#: controllers/editors_controller.php:133
+msgid "editors_queues_disabled"
+msgstr "Semua tinjauan sedang dimatikan. Mohon kembali lagi nanti."
+
+#: views/editors/review.thtml:149
+#, fuzzy
+msgid "editors_review_a_edit_item"
+msgstr "Edit Item"
+
+#: views/editors/review.thtml:146
+#, fuzzy
+msgid "editors_review_a_item_history"
+msgstr "Item History"
+
+#: views/editors/review.thtml:148
+#, fuzzy
+msgid "editors_review_a_item_homepage"
+msgstr "Item Homepage"
+
+#: views/editors/review.thtml:145
+#, fuzzy
+msgid "editors_review_a_item_overview"
+msgstr "Item Overview"
+
+#: views/editors/review.thtml:147
+#, fuzzy
+msgid "editors_review_a_previews"
+msgstr "Previews"
+
+#: controllers/editors_controller.php:345
+msgid "editors_review_action"
+msgstr "Aksi Peninjauan"
+
+#: views/editors/review.thtml:159
+msgid "editors_review_action_info"
+msgstr "Permintaan Informasi Lebih Lanjut"
+
+#: views/editors/review.thtml:157
+msgid "editors_review_action_public"
+msgstr "Masukkan ke Status Publik"
+
+#: views/editors/review.thtml:160
+msgid "editors_review_action_request_superreview"
+msgstr "Permintaan Tinjauan-Super"
+
+#: views/editors/review.thtml:158
+msgid "editors_review_action_sandbox"
+msgstr "Tetapkan dalam Sandbox"
+
+#: controllers/editors_controller.php:346
+msgid "editors_review_comments"
+msgstr "Tinjau Komentar"
+
+#: views/editors/review.thtml:182
+msgid "editors_review_details_info_request"
+msgstr ""
+"Gunakan formulir ini untuk meminta informasi tambahan dari penyusun. "
+"Penyusun akan menerima email dan dapat menjawabnya di sini. Anda akan "
+"diberitahukan melalui email ketika ada balasan."
+
+#: views/editors/review.thtml:174
+msgid "editors_review_details_nominated_public"
+msgstr ""
+"Ini akan menandai pengaya dan versi terbarunya dengan status publik. Versi "
+"yang akan datang akan tetap berada pada sandbox sampai ditinjau oleh seorang "
+"penyunting."
+
+#: views/editors/review.thtml:177
+msgid "editors_review_details_nominated_sandbox"
+msgstr "Ini akan menetapkan pengaya dalam status sandbox."
+
+#: views/editors/review.thtml:166
+msgid "editors_review_details_pending_public"
+msgstr ""
+"Ini akan menetapkan persetujuan pada versi sandbox untuk ditampilkan pada "
+"situs publik."
+
+#: views/editors/review.thtml:169
+msgid "editors_review_details_pending_sandbox"
+msgstr ""
+"Ini berakibat pada versi publik yang berada dalam sandbox akan tetap berada "
+"dalam sandbox."
+
+#: views/editors/review.thtml:185
+msgid "editors_review_details_superreview"
+msgstr ""
+"Jika anda mempunyai kekhawatiran yang ingin disampaikan kepada administrator "
+"tentang keamanan, masalah hak cipta atau hal lain tentang pengaya ini, "
+"masukkan komentar pada isian di bawah ini. Data ini akan dikirimkan kepada "
+"administrator, bukan kepada penyusun."
+
+#: views/editors/review.thtml:134
+msgid "editors_review_file_diff_link"
+msgstr "Bandingkan dengan versi publik"
+
+#: views/editors/review.thtml:131
+msgid "editors_review_file_viewcontents_link"
+msgstr "Tampilkan Isi"
+
+#: views/editors/review.thtml:65
+msgid "editors_review_header_authors"
+msgstr "Penyusun:"
+
+#: views/editors/review.thtml:79
+msgid "editors_review_header_categories"
+msgstr "Kategori:"
+
+#: views/editors/review.thtml:92
+msgid "editors_review_header_compatibility"
+msgstr "Kompatibilitas:"
+
+#: views/editors/review.thtml:251
+msgid "editors_review_header_description"
+msgstr "Deskripsi"
+
+#: views/editors/review.thtml:275
+msgid "editors_review_header_devcomments"
+msgstr "Komentar oleh Pengembang"
+
+#: views/editors/review.thtml:263
+msgid "editors_review_header_eula"
+msgstr "EULA"
+
+#: views/editors/review.thtml:115
+msgid "editors_review_header_files"
+msgstr "Berkas:"
+
+#: views/editors/review.thtml:284
+msgid "editors_review_header_itemhistory"
+msgstr "Riwayat Item"
+
+#: views/editors/review.thtml:232
+msgid "editors_review_header_nominationmessage"
+msgstr "Pesan Pencalonan"
+
+#: views/editors/review.thtml:311
+msgid "editors_review_header_previews"
+msgstr "Pratinjau"
+
+#: views/editors/review.thtml:269
+msgid "editors_review_header_privacy"
+msgstr "Kebijakan Privasi"
+
+#. %1 is the add-on name and version
+#: views/editors/review.thtml:56
+#, php-format
+msgid "editors_review_header_review"
+msgstr "Tinjau %s"
+
+#: views/editors/review.thtml:239
+msgid "editors_review_header_reviewernotes"
+msgstr "Catatan untuk Peninjau"
+
+#: views/editors/review.thtml:245
+msgid "editors_review_header_summary"
+msgstr "Ringkasan"
+
+#: views/editors/review.thtml:257
+msgid "editors_review_header_versionnotes"
+msgstr "Catatan Versi"
+
+#. a noun: shown in an add-on's editor review history
+#: views/elements/developers/editors_review_history_item.thtml:80
+msgid "editors_review_history_info_reply"
+msgstr "Balas"
+
+#: views/elements/developers/editors_review_history_item.thtml:78
+msgid "editors_review_history_info_request"
+msgstr "Permintaan Keterangan"
+
+#: views/elements/developers/editors_review_history_item.thtml:62
+#: views/editors/reviewlog.thtml:77
+msgid "editors_review_history_nominated_adminreview"
+msgstr "Tinjauan Admin"
+
+#: views/elements/developers/editors_review_history_item.thtml:56
+#: views/editors/reviewlog.thtml:71
+msgid "editors_review_history_nominated_approved"
+msgstr "Persetujuan Pencalonan/Publik"
+
+#: views/elements/developers/editors_review_history_item.thtml:59
+#: views/editors/reviewlog.thtml:74
+msgid "editors_review_history_nominated_denied"
+msgstr "Penolakan Pencalonan/Sandbox"
+
+#: views/editors/review.thtml:303
+msgid "editors_review_history_nonefound"
+msgstr "Tidak ada entri tinjauan ditemukan."
+
+#: views/elements/developers/editors_review_history_item.thtml:73
+#: views/editors/reviewlog.thtml:88
+msgid "editors_review_history_pending_adminreview"
+msgstr "Tinjauan Admin"
+
+#: views/elements/developers/editors_review_history_item.thtml:67
+#: views/editors/reviewlog.thtml:82
+msgid "editors_review_history_pending_approved"
+msgstr "Disetujui/Publik"
+
+#: views/elements/developers/editors_review_history_item.thtml:70
+#: views/editors/reviewlog.thtml:85
+msgid "editors_review_history_pending_denied"
+msgstr "Ditolak/Sandbox"
+
+#. link text in an add-on's editor review history, allowing to hide and show an information request's replies
+#. %1 is the number of replies
+#: views/elements/developers/editors_review_history_item.thtml:90
+msgid "editors_review_history_show_hide_replies"
+msgid_plural "editors_review_history_show_hide_replies"
+msgstr[0] "Tampilkan/Sembunyikan Balasan (%1$s)"
+msgstr[1] "Tampilkan/Sembunyikan Balasan (%1$s)"
+
+#: views/editors/review.thtml:208
+msgid "editors_review_label_applications"
+msgstr "Aplikasi:"
+
+#: views/editors/review.thtml:196
+msgid "editors_review_label_cannedresponse"
+msgstr "atau pilih balasan tertentu:"
+
+#: views/editors/review.thtml:190
+msgid "editors_review_label_comments"
+msgstr "Komentar:"
+
+#: views/editors/review.thtml:204
+msgid "editors_review_label_operating_systems"
+msgstr "Sistem Operasi:"
+
+#: views/editors/review.thtml:285 views/editors/review.thtml:312
+msgid "editors_review_link_pagetop"
+msgstr "Atas"
+
+#: views/editors/review.thtml:141
+#, fuzzy
+msgid "editors_review_mulitple_notice"
+msgstr ""
+"Notice: Only review more than one file if you have tested EVERY file you "
+"select."
+
+#: views/editors/review.thtml:51
+msgid "editors_review_next_link"
+msgstr "selanjutnya &raquo;"
+
+#: views/editors/review.thtml:322
+msgid "editors_review_previews_notfound"
+msgstr "Tidak ada pratinjau ditemukan."
+
+#: views/editors/review.thtml:50
+msgid "editors_review_previous_link"
+msgstr "&laquo; sebelumnya"
+
+#: controllers/editors_controller.php:144
+#: controllers/editors_controller.php:146
+msgid "editors_review_queue_pagetitle"
+msgstr "Antrian Tinjauan"
+
+#. %1 is the add-ons rank in the queue, %2 is the total queue length
+#: views/editors/review.thtml:47
+msgid "editors_review_rank_in_queue"
+msgstr "<strong># %1$s</strong> dari %2$s dalam antrian"
+
+#. %1 is the add-ons rank in the queue, %2 is the total queue length. Both numbers
+#: views/editors/review.thtml:45
+#, fuzzy
+msgid "editors_review_rank_in_queue_filtered"
+msgstr "<strong># %1$s</strong> of %2$s in queue (filtered)"
+
+#: views/editors/review.thtml:223
+msgid "editors_review_submit_process_action"
+msgstr "Proses Aksi"
+
+#: views/editors/review.thtml:293
+msgid "editors_review_th_action"
+msgstr "Aksi"
+
+#: views/editors/review.thtml:294
+msgid "editors_review_th_comments"
+msgstr "Komentar"
+
+#: views/editors/review.thtml:291
+msgid "editors_review_th_date"
+msgstr "Tanggal"
+
+#: views/editors/review.thtml:292
+msgid "editors_review_th_reviewer"
+msgstr "Peninjau"
+
+#: views/editors/review.thtml:290
+msgid "editors_review_th_version_file"
+msgstr "Versi/Berkas"
+
+#: views/editors/review.thtml:217
+msgid "editors_review_update_notify_once"
+msgstr ""
+"Kirim pemberitahuan kepada saya saat pengaya ini dimutakhirkan (Pemutakhiran "
+"berikutnya tidak akan menyebabkan email dikirim)"
+
+#: controllers/editors_controller.php:298
+msgid "editors_reviewed_successfully"
+msgstr "Tinjauan sukses diproses."
+
+#: views/editors/reviews_queue.thtml:106
+msgid "editors_reviews_action_delete_review"
+msgstr "Hapus tinjauan"
+
+#: views/editors/reviews_queue.thtml:104
+msgid "editors_reviews_action_keep"
+msgstr "Hapus tanda, tetap simpan isi tinjauan"
+
+#: views/editors/reviews_queue.thtml:102
+msgid "editors_reviews_action_skip"
+msgstr "Lewati"
+
+#: views/editors/reviews_queue.thtml:100
+msgid "editors_reviews_header_action"
+msgstr "Aksi"
+
+#: views/editors/reviews_queue.thtml:67
+msgid "editors_reviews_in_reply_to"
+msgstr "Balasan untuk:"
+
+#: controllers/editors_controller.php:748
+msgid "editors_reviews_processed"
+msgstr "Tinjauan sukses diproses!"
+
+#: views/editors/reviews_queue.thtml:117
+msgid "editors_reviews_queue_empty"
+msgstr "Tidak ada tinjauan pada antrian moderasi."
+
+#: views/editors/reviews_queue.thtml:111
+msgid "editors_reviews_submit_process_reviews"
+msgstr "Proses Tinjauan"
+
+#: controllers/editors_controller.php:691
+msgid "editors_site_specific"
+msgstr "Situs Tertentu"
+
+#: controllers/editors_controller.php:348
+msgid "editors_tested_app"
+msgstr "Aplikasi yang Diujikan"
+
+#: controllers/editors_controller.php:347
+msgid "editors_tested_os"
+msgstr "Sistem Operasi yang Diujikan"
+
+#: views/editors/queue.thtml:151
+msgid "editors_th_additional_info"
+msgstr "Informasi Lain"
+
+#: views/editors/featured.thtml:63 views/editors/queue.thtml:109
+#: views/admin/flagged_queue.thtml:53
+msgid "editors_th_addon"
+msgstr "Pengaya"
+
+#: views/editors/queue.thtml:125
+msgid "editors_th_addontype"
+msgstr "Jenis"
+
+#: views/editors/featured.thtml:64
+msgid "editors_th_locales"
+msgstr "Dibatasi untuk bahasa (locale)?"
+
+#: views/editors/queue.thtml:148
+#, fuzzy
+msgid "editors_th_nomination_age"
+msgstr "Time in Queue"
+
+#: views/editors/queue.thtml:101 views/editors/queue.thtml:117
+#: views/editors/queue.thtml:144
+#, fuzzy
+msgid "editors_th_sort_ascending"
+msgstr "Ascending sort"
+
+#: views/editors/queue.thtml:105 views/editors/queue.thtml:121
+#: views/editors/queue.thtml:140
+#, fuzzy
+msgid "editors_th_sort_descending"
+msgstr "Descending sort"
+
+#. %s is a number
+#: controllers/editors_controller.php:1036
+#, php-format
+msgid "editors_x_days"
+msgstr "%s hari"
+
+#. %s is a number
+#: controllers/editors_controller.php:1044
+#, php-format
+msgid "editors_x_hours"
+msgstr "%s jam"
+
+#. %s is a number
+#: controllers/editors_controller.php:1052
+#, php-format
+msgid "editors_x_minutes"
+msgstr "%s menit"
+
+#: views/errors/error401.thtml:50 controllers/components/simple_acl.php:81
+#: controllers/components/simple_acl.php:82
+#: controllers/components/simple_acl.php:83 controllers/components/amo.php:607
+#: controllers/components/amo.php:608 controllers/components/amo.php:609
+#: controllers/reviews_controller.php:353
+#: controllers/reviews_controller.php:485
+#: controllers/collections_controller.php:438
+#: controllers/collections_controller.php:496
+#: controllers/collections_controller.php:504
+#: controllers/collections_controller.php:971
+#: controllers/collections_controller.php:1034
+#: controllers/collections_controller.php:1077
+msgid "error_access_denied"
+msgstr "Akses ditolak"
+
+#: views/errors/error401.thtml:52
+msgid "error_access_denied_message"
+msgstr "Anda tidak diizinkan untuk membuka halaman ini."
+
+#: controllers/collections_controller.php:1039
+#, fuzzy
+msgid "error_addon_exists"
+msgstr "Add-on already exists!"
+
+#: controllers/developers_controller.php:200
+#: controllers/developers_controller.php:593
+#: controllers/developers_controller.php:1016
+#: controllers/developers_controller.php:1429
+#: controllers/downloads_controller.php:95
+#: controllers/downloads_controller.php:102
+#: controllers/downloads_controller.php:164
+#: controllers/statistics_controller.php:135
+#: controllers/previews_controller.php:115
+#: controllers/previews_controller.php:206
+#: controllers/previews_controller.php:307
+#: controllers/reviews_controller.php:77
+#: controllers/reviews_controller.php:240
+#: controllers/reviews_controller.php:332
+#: controllers/reviews_controller.php:340 controllers/api_controller.php:123
+#: controllers/api_controller.php:759 controllers/addons_controller.php:131
+#: controllers/addons_controller.php:197
+#: controllers/addons_controller.php:1407
+#: controllers/addons_controller.php:1465
+#: controllers/addons_controller.php:1469
+#: controllers/addons_controller.php:1503
+#: controllers/editors_controller.php:265
+#: controllers/collections_controller.php:1041
+#: controllers/collections_controller.php:1074
+msgid "error_addon_notfound"
+msgstr "Pengaya tidak ditemukan!"
+
+#: controllers/files_controller.php:83 controllers/files_controller.php:196
+msgid "error_addon_notviewable"
+msgstr "Tidak ada pengaya pada kategori ini!"
+
+#: controllers/reviews_controller.php:246
+msgid "error_addon_selfreview"
+msgstr "Anda tidak bisa memberikan tinjauan kepada pengaya anda sendiri."
+
+#: controllers/addons_controller.php:970
+msgid "error_browse_no_addons"
+msgstr "Tidak ada pengaya pada kategori ini!"
+
+#: controllers/api_controller.php:424
+#, fuzzy
+msgid "error_collection_feed_notfound"
+msgstr "Add-on feed not found."
+
+#: views/users/register.thtml:65 views/users/edit.thtml:194
+msgid "error_email_invalid"
+msgstr "Alamat email ini tidak sah."
+
+#: views/users/pwreset.thtml:74 views/users/register.thtml:70
+#: views/users/register.thtml:80 views/users/register.thtml:86
+#: views/users/edit.thtml:105 views/users/edit.thtml:111
+#: views/users/edit.thtml:192 views/admin/users_edit.thtml:78
+#: views/admin/users_edit.thtml:83 views/reviews/add.thtml:80
+#: views/reviews/add.thtml:104
+msgid "error_field_required"
+msgstr "Isian ini tidak boleh kosong."
+
+#: controllers/files_controller.php:75 controllers/files_controller.php:93
+#: controllers/files_controller.php:96 controllers/files_controller.php:163
+#: controllers/files_controller.php:176 controllers/files_controller.php:185
+#: controllers/files_controller.php:204 controllers/editors_controller.php:412
+msgid "error_file_notfound"
+msgstr "Berkas tidak ditemukan!"
+
+#. %s is a filename
+#: controllers/editors_controller.php:430
+#, php-format
+msgid "error_file_x_notfound"
+msgstr "Kesalahan pada berkas: %s tidak ada."
+
+#: views/collections/add.thtml:55 views/collections/edit.thtml:89
+#: views/users/register.thtml:54 views/users/edit.thtml:81
+#: views/reviews/add.thtml:70 controllers/groups_controller.php:80
+#: controllers/groups_controller.php:102
+msgid "error_formerrors"
+msgstr "Ada kesalahan pada form ini. Mohon dikoreksi kemudian kirim ulang."
+
+#: views/users/register.thtml:109
+msgid "error_invalid_captcha"
+msgstr "Kata atau angka yang anda ketikkan salah, silakan coba lagi!"
+
+#: views/users/register.thtml:100 views/users/edit.thtml:125
+#: views/admin/users_edit.thtml:101
+msgid "error_invalid_url"
+msgstr ""
+"Format URL salah. Format yang benar adalah seperti http://example.com/"
+"namahalaman."
+
+#. %s is a string representing what's missing. Example: file_id
+#: controllers/downloads_controller.php:65
+#: controllers/users_controller.php:185 controllers/users_controller.php:264
+#: controllers/users_controller.php:559 controllers/users_controller.php:653
+#: controllers/reviews_controller.php:71
+#: controllers/reviews_controller.php:234
+#: controllers/reviews_controller.php:325
+#: controllers/reviews_controller.php:473
+#: controllers/reviews_controller.php:475
+#: controllers/addons_controller.php:182
+#: controllers/addons_controller.php:1381
+#: controllers/addons_controller.php:1455
+#: controllers/collections_controller.php:266
+#: controllers/collections_controller.php:285
+#: controllers/collections_controller.php:346
+#: controllers/collections_controller.php:443
+#: controllers/collections_controller.php:482
+#: controllers/collections_controller.php:936
+#: controllers/collections_controller.php:959
+#: controllers/collections_controller.php:960
+#: controllers/collections_controller.php:975
+#: controllers/collections_controller.php:977
+#: controllers/collections_controller.php:994
+#: controllers/collections_controller.php:1003
+#: controllers/collections_controller.php:1016
+#: controllers/collections_controller.php:1017
+#: controllers/collections_controller.php:1024
+#: controllers/collections_controller.php:1070
+#: controllers/collections_controller.php:1090
+#, php-format
+msgid "error_missing_argument"
+msgstr "Argumen tidak lengkap: %s"
+
+#: controllers/components/amo.php:507 controllers/components/amo.php:532
+msgid "error_no_files_in_addon"
+msgstr "Tidak ada berkas"
+
+#: controllers/previews_controller.php:200
+msgid "error_preview_notfound"
+msgstr "Pratinjau tidak ditemukan!"
+
+#: views/addons/display.thtml:400 views/reviews/add.thtml:98
+msgid "error_review_rating_required"
+msgstr "Anda harus memilih salah satu peringkat."
+
+#: controllers/users_controller.php:160
+msgid "error_user_already_confirmed"
+msgstr "Akun pengguna ini sudah dikonfirmasi."
+
+#: controllers/users_controller.php:202 controllers/users_controller.php:276
+#: controllers/users_controller.php:569 controllers/users_controller.php:581
+#: controllers/users_controller.php:587 controllers/users_controller.php:610
+#: controllers/users_controller.php:627
+msgid "error_user_badconfirmationcode"
+msgstr "Kode konfirmasi tidak cocok!"
+
+#: views/users/pwreset.thtml:79 views/users/register.thtml:75
+#: views/users/edit.thtml:183
+msgid "error_user_confirmpw_nomatch"
+msgstr "Kata sandi yang dimasukkan tidak cocok."
+
+#: views/users/register.thtml:65 views/users/edit.thtml:190
+#: controllers/users_controller.php:617
+msgid "error_user_email_notunique"
+msgstr "Alamat email ini sudah digunakan pengguna lain."
+
+#: controllers/users_controller.php:596
+msgid "error_user_emailchange_expired"
+msgstr ""
+"Proses perubahan email telah kadaluarsa. Mohon ganti alamat email anda lagi "
+"pada profil pengguna anda dan klik tautan pada email yang dikirimkan kepada "
+"anda untuk mengkonfirmasi perubahan alamat email tersebut."
+
+#: controllers/collections_controller.php:985
+#, fuzzy
+msgid "error_user_exists"
+msgstr ""
+"Users can only have one role at a time. Please remove the user from any "
+"existing roles before continuing."
+
+#: views/users/register.thtml:91 views/users/edit.thtml:116
+#: views/admin/users_edit.thtml:88
+msgid "error_user_nickname_notunique"
+msgstr "Nama alias (nick) sudah diambil."
+
+#: views/users/pwreset.thtml:54 controllers/users_controller.php:191
+#: controllers/users_controller.php:270 controllers/users_controller.php:603
+#: controllers/users_controller.php:659
+#: controllers/collections_controller.php:988
+#: controllers/collections_controller.php:998
+msgid "error_user_notfound"
+msgstr "Pengguna tidak ditemukan!"
+
+#: views/users/activatefirst.thtml:47
+msgid "error_user_unconfirmed"
+msgstr ""
+"Mohon akun anda dikonfirmasi terlebih dahulu dengan kode yang telah dikirim "
+"melalui email yang anda terima."
+
+#: views/users/login.thtml:67
+msgid "error_username_or_pw_wrong"
+msgstr "Nama pengguna atau kata sandi salah!"
+
+#: controllers/editors_controller.php:260
+msgid "error_version_notfound"
+msgstr "Versi tidak ditemukan!"
+
+#: views/users/delete.thtml:125 views/users/edit.thtml:173
+msgid "error_wrong_password"
+msgstr "Kata sandi salah!"
+
+#: views/elements/amo2009/homepage_addon.thtml:122
+#: views/elements/feature.thtml:122
+msgid "feature_learnmore"
+msgstr "Lebih lanjut"
+
+#. %1 is the add-on name
+#: views/elements/amo2009/homepage_addon.thtml:123
+#: views/elements/feature.thtml:123
+#, php-format
+msgid "feature_learnmore_about_addon"
+msgstr "Lebih lanjut tentang %s"
+
+#. %1$s is a number
+#: views/elements/amo2009/reviews.thtml:52
+#: views/elements/addon_listitem.thtml:112 views/elements/feature.thtml:99
+#: views/addons/browse_thumbs.thtml:86
+#, php-format
+msgid "feature_reviews"
+msgid_plural "feature_reviews"
+msgstr[0] "Satu tinjauan"
+msgstr[1] "%1$s tinjauan"
+
+#: views/elements/amo2009/homepage_addon.thtml:127
+#: views/elements/feature.thtml:127
+msgid "feature_view_more_from_category"
+msgstr "tampilkan lebih banyak dari kategori"
+
+#. This appears on a page that views the source of an add-on. This link will return
+#. the user to the add-on's main page
+#: views/files/browse.thtml:65
+msgid "file_browser_link_addon"
+msgstr "Kembali ke pengaya"
+
+#. There is a list of directories and files on the page. Clicking this will show the
+#. contents of all the directories (normally you would click on each one to see the
+#. contents)
+#: views/files/browse.thtml:67
+msgid "file_browser_link_expand_all"
+msgstr "Bentangkan semua"
+
+#. This appears on a page that views the source of an add-on. This link will return
+#. the user to the add-on's review page (it only appears if the add-on is being
+#. reviewed)
+#: views/files/browse.thtml:64
+msgid "file_browser_link_review"
+msgstr "Kembali ke tinjauan"
+
+#. The title of the page for viewing an add-on's source.
+#. %1$s is the name of the add-on
+#. %2$s is the name of the current application (e.g. Firefox or Thunderbird)
+#: views/files/browse.thtml:46
+msgid "file_browser_title"
+msgstr "%1$s :: Penjelajah Berkas :: Pengaya %2$s"
+
+#. This appears on a page that views the source of an add-on. There is a list of
+#. directories and files on the page. Clicking this link will toggle between an
+#. expanded or a collapsed list. This string should be kept short.
+#: views/files/browse.thtml:68
+msgid "file_browser_toggle_expand_collapse"
+msgstr "+/-"
+
+#. Link text for the AMO About page.
+#: views/elements/footer.thtml:72 views/layouts/amo2009.thtml:341
+#, fuzzy
+msgid "footer_a_about"
+msgstr "About"
+
+#. Link text to the AMO blog.
+#: views/elements/footer.thtml:74 views/layouts/amo2009.thtml:343
+#, fuzzy
+msgid "footer_a_blog"
+msgstr "Blog"
+
+#. Link text to the Frequently Asked Questions page.
+#: views/elements/footer.thtml:73 views/layouts/amo2009.thtml:342
+#, fuzzy
+msgid "footer_a_faq"
+msgstr "FAQ"
+
+#. Full text for the FAQ abbreviation.
+#: views/elements/footer.thtml:73 views/pages/collector_features.thtml:72
+#: views/layouts/amo2009.thtml:342
+#, fuzzy
+msgid "footer_abbr_faq"
+msgstr "Frequently Asked Questions"
+
+#: views/elements/footer.thtml:67 views/layouts/amo2009.thtml:336
+msgid "footer_all_rights_reserved"
+msgstr "Hak Cipta dilindungi undang-undang."
+
+#: views/elements/footer.thtml:67 views/layouts/amo2009.thtml:336
+msgid "footer_copyright"
+msgstr "Hak Cipta"
+
+#: views/elements/footer.thtml:71 views/layouts/amo2009.thtml:340
+msgid "footer_credits"
+msgstr "Kredit"
+
+#: views/elements/footer.thtml:76 views/layouts/amo2009.thtml:346
+msgid "footer_disclaimer"
+msgstr ""
+"Mozilla menyediakan tautan ke aplikasi ini dengan alasan kesopanan dan tidak "
+"mewakili hal apapun tentang aplikasi atau informasi yang berkaitan "
+"dengannya. Semua pertanyaan, keluhan, atau klaim tentang aplikasi tersebut "
+"harus langsung ditujukan kepada vendor perangkat lunak yang bersangkutan."
+
+#: views/elements/footer.thtml:61 views/layouts/amo2009.thtml:332
+msgid "footer_lang_form_lang_submit_go"
+msgstr "Kirim"
+
+#: views/elements/footer.thtml:70 views/layouts/amo2009.thtml:339
+msgid "footer_legal_notices"
+msgstr "Pernyataan Hukum"
+
+#: views/elements/footer.thtml:50 views/layouts/amo2009.thtml:321
+msgid "footer_other_languages"
+msgstr "Bahasa lainnya:"
+
+#: views/elements/footer.thtml:69 views/layouts/amo2009.thtml:338
+msgid "footer_privacy_policy"
+msgstr "Kebijakan Privasi"
+
+#: models/addontype.php:79
+msgid "general_addontype_dict"
+msgstr "Kamus"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:100
+msgid "general_addontype_dict_plural"
+msgstr "Kamus"
+
+#: models/addontype.php:75
+msgid "general_addontype_extension"
+msgstr "Ekstensi"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:98
+msgid "general_addontype_extension_plural"
+msgstr "Ekstensi"
+
+#: models/addontype.php:85
+msgid "general_addontype_lpaddon"
+msgstr "Paket Bahasa (Pengaya)"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:103
+msgid "general_addontype_lpaddon_plural"
+msgstr "Paket Bahasa (Pengaya)"
+
+#: models/addontype.php:83
+msgid "general_addontype_lpapp"
+msgstr "Paket Bahasa (Aplikasi)"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:102
+msgid "general_addontype_lpapp_plural"
+msgstr "Paket Bahasa (Aplikasi)"
+
+#: models/addontype.php:87
+msgid "general_addontype_plugin"
+msgstr "Plugin"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:104
+msgid "general_addontype_plugin_plural"
+msgstr "Plugin"
+
+#: models/addontype.php:81
+msgid "general_addontype_search"
+msgstr "Mesin Pencari"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:101
+msgid "general_addontype_search_plural"
+msgstr "Mesin pencari"
+
+#: models/addontype.php:77
+msgid "general_addontype_theme"
+msgstr "Tema"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:99
+msgid "general_addontype_theme_plural"
+msgstr "Tema"
+
+#: config/language.php:367
+#, fuzzy
+msgid "general_languages_all_locales"
+msgstr "All Locales"
+
+#: views/layouts/amo2009.thtml:249
+#, fuzzy
+msgid "header_brand_name"
+msgstr "Mozilla"
+
+#. %1$s is the application name. Example: Firefox
+#: views/elements/header.thtml:111 views/elements/header.thtml:122
+#: views/layouts/amo2009.thtml:248
+#, php-format
+msgid "header_home_tooltip"
+msgstr "Kembali ke beranda Pengaya %1$s"
+
+#: views/elements/header.thtml:87
+msgid "header_main_firefox_header"
+msgstr "Pengaya Firefox"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:218
+#, fuzzy
+msgid "header_main_firefox_header_with_logo"
+msgstr ""
+"Add-ons <em>for</em> <img alt=\"Firefox\" src=\"%1$s\" /> <strong>Firefox</"
+"strong>"
+
+#: views/elements/header.thtml:99
+msgid "header_main_header"
+msgstr "Pengaya"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:242
+#, fuzzy
+msgid "header_main_header_with_logo"
+msgstr "Add-ons <img alt=\"Add-ons\" src=\"%1$s\" />"
+
+#: views/elements/header.thtml:90
+msgid "header_main_seamonkey_header"
+msgstr "Pengaya Seamonkey"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:224
+#, fuzzy
+msgid "header_main_seamonkey_header_with_logo"
+msgstr ""
+"Add-ons <em>for</em> <img alt=\"seamonkey\" src=\"%1$s\" /> "
+"<strong>SeaMonkey</strong>"
+
+#: views/elements/header.thtml:93
+msgid "header_main_sunbird_header"
+msgstr "Pengaya Sunbird"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:230
+#, fuzzy
+msgid "header_main_sunbird_header_with_logo"
+msgstr ""
+"Add-ons <em>for</em> <img alt=\"sunbird\" src=\"%1$s\" /> <strong>Sunbird</"
+"strong>"
+
+#: views/elements/header.thtml:96
+msgid "header_main_thunderbird_header"
+msgstr "Pengaya Thunderbird"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:236
+#, fuzzy
+msgid "header_main_thunderbird_header_with_logo"
+msgstr ""
+"Add-ons <em>for</em> <img alt=\"thunderbird\" src=\"%1$s\" /> "
+"<strong>Thunderbird</strong>"
+
+#: views/layouts/amo2009.thtml:205
+#, fuzzy
+msgid "header_navaccess_applications_menu"
+msgstr "Skip to other applications menu"
+
+#: views/layouts/amo2009.thtml:204
+#, fuzzy
+msgid "header_navaccess_categories_menu"
+msgstr "Skip to categories menu"
+
+#: views/layouts/amo2009.thtml:202
+#, fuzzy
+msgid "header_navaccess_main_content"
+msgstr "Skip to main content"
+
+#: views/layouts/amo2009.thtml:203
+#, fuzzy
+msgid "header_navaccess_search_form"
+msgstr "Skip to search form"
+
+#: views/elements/header.thtml:62
+msgid "header_navlink_addons"
+msgstr "Pengaya"
+
+#: views/elements/developers/sidebar.thtml:72
+#: views/elements/developers/myaddons.thtml:50 views/elements/header.thtml:159
+#: views/addons/display.thtml:378
+msgid "header_navlink_login"
+msgstr "Log-masuk"
+
+#: views/elements/header.thtml:156 views/layouts/amo2009.thtml:304
+msgid "header_navlink_logout"
+msgstr "Log-keluar"
+
+#: views/elements/header.thtml:145 views/layouts/amo2009.thtml:303
+msgid "header_navlink_myaccount"
+msgstr "Akun Saya"
+
+#: views/elements/header.thtml:158
+msgid "header_navlink_register"
+msgstr "Daftar"
+
+#. %1 is the URL to the registration page
+#. %2 is the URL to the login page
+#: views/layouts/amo2009.thtml:278
+#, fuzzy
+msgid "header_navlink_register_or_login"
+msgstr "<a href=\"%1$s\">Register</a> or <a href=\"%2$s\">Log in</a>"
+
+#: views/layouts/amo2009.thtml:285
+#, fuzzy
+msgid "header_navlink_tools"
+msgstr "Tools"
+
+#. %s is the add-on name
+#: views/elements/collections_interactive_addon.thtml:62
+#: views/elements/amo2009/homepage_addon.thtml:77
+#: views/elements/addon_discussionheader.thtml:62
+#: views/elements/addon_listitem.thtml:67 views/elements/feature.thtml:84
+#: views/addons/category_landing.thtml:87 views/addons/browse_thumbs.thtml:60
+#, php-format
+msgid "img_preview_of"
+msgstr "Gambar Pratinjau %s"
+
+#. %1 is the login URL for the link tag
+#. %2 is the link to an explanatory page.
+#: views/elements/amo2009/install.thtml:307 views/elements/install.thtml:255
+msgid "install_a_login_to_install"
+msgstr ""
+"<a href=\"%1$s\">Log-Masuk</a> untuk memasang pengaya ini. <a href=\"%2$s"
+"\">Mengapa</a>?"
+
+#. %1 is the URL for the Experimental Add-ons section of the FAQ page
+#: views/elements/amo2009/install.thtml:283 views/elements/install.thtml:232
+#, fuzzy
+msgid "install_button_confirm_exp_install"
+msgstr ""
+"Let me install this experimental add-on. <a href=\"%1$s\">What's this?</a>"
+
+#. %1$s is the application name. Example: Firefox
+#. %2$s is an optional string used to specify a platform. Example: (Windows)
+#: views/elements/amo2009/install.thtml:128 views/elements/install.thtml:75
+#, php-format
+msgid "install_button_text"
+msgstr "Pasang untuk %s %s"
+
+#. %1 is the add-on name, %2 is the app name
+#: views/elements/amo2009/install.thtml:191
+#: views/elements/amo2009/install.thtml:206
+#: views/elements/amo2009/install.thtml:249
+#: views/elements/amo2009/install.thtml:298 views/elements/install.thtml:150
+#: views/elements/install.thtml:165 views/elements/install.thtml:202
+#: views/elements/install.thtml:246
+#, php-format
+msgid "install_button_title"
+msgstr "Pasang %1$s untuk %2$s"
+
+#. %1$s is the add-on name
+#: views/elements/amo2009/install.thtml:200 views/elements/install.thtml:159
+#, php-format
+msgid "install_download"
+msgstr "Unduh %1$s"
+
+#: views/elements/amo2009/install.thtml:147 views/elements/install.thtml:94
+msgid "install_error_addon_not_found"
+msgstr "Pengaya ini tidak tersedia."
+
+#: views/addons/dictionaries.thtml:65
+msgid "langtools_a11y_tablesummary"
+msgstr "Daftar paket bahasa dan kamus."
+
+#: views/addons/dictionaries.thtml:47
+msgid "langtools_download_dictionary"
+msgstr "Unduh Kamus"
+
+#: views/addons/dictionaries.thtml:48
+msgid "langtools_download_langpack"
+msgstr "Unduh Paket Bahasa"
+
+#: views/addons/dictionaries.thtml:63 controllers/components/amo.php:685
+#: controllers/addons_controller.php:1239
+msgid "langtools_header_dicts_and_langpacks"
+msgstr "Kamus & Paket Bahasa"
+
+#: views/addons/dictionaries.thtml:44
+msgid "langtools_install_dictionary"
+msgstr "Pasang Kamus"
+
+#: views/addons/dictionaries.thtml:45
+msgid "langtools_install_langpack"
+msgstr "Pasang Paket Bahasa"
+
+#: views/addons/dictionaries.thtml:69
+msgid "langtools_tableheader_dictionary"
+msgstr "Kamus"
+
+#: views/addons/dictionaries.thtml:70
+msgid "langtools_tableheader_langpack"
+msgstr "Paket Bahasa"
+
+#: views/addons/dictionaries.thtml:68
+msgid "langtools_tableheader_language"
+msgstr "Bahasa"
+
+#: models/license.php:65
+#, fuzzy
+msgid "license_custom"
+msgstr "Custom License"
+
+#: config/bootstrap.php:303
+#, fuzzy
+msgid "licenses_bsd"
+msgstr "BSD License"
+
+#: config/bootstrap.php:298
+#, fuzzy
+msgid "licenses_gpl_2.0"
+msgstr "GNU General Public License, version 2.0"
+
+#: config/bootstrap.php:299
+#, fuzzy
+msgid "licenses_gpl_3.0"
+msgstr "GNU General Public License, version 3.0"
+
+#: config/bootstrap.php:300
+#, fuzzy
+msgid "licenses_lgpl_2.1"
+msgstr "GNU Lesser General Public License, version 2.1"
+
+#: config/bootstrap.php:301
+#, fuzzy
+msgid "licenses_lgpl_3.0"
+msgstr "GNU Lesser General Public License, version 3.0"
+
+#: config/bootstrap.php:302
+#, fuzzy
+msgid "licenses_mit"
+msgstr "MIT/X11 License"
+
+#: config/bootstrap.php:297
+#, fuzzy
+msgid "licenses_mpl_1.1"
+msgstr "Mozilla Public License, version 1.1"
+
+#: views/users/emailchange.thtml:51 views/users/delete.thtml:55
+#: views/users/delete.thtml:137 views/users/edit.thtml:74
+#: views/reviews/flag.thtml:54
+msgid "link_return_to_front_page"
+msgstr "Klik di sini untuk kembali ke halaman utama."
+
+#: views/elements/amo2009/addon_list_options.thtml:46
+#: views/elements/addon_list_options.thtml:46
+msgid "list_sortby_date"
+msgstr "Tanggal"
+
+#: views/elements/amo2009/addon_list_options.thtml:47
+#: views/elements/addon_list_options.thtml:47
+msgid "list_sortby_downloads"
+msgstr "Unduhan"
+
+#: views/elements/amo2009/addon_list_options.thtml:45
+#: views/elements/addon_list_options.thtml:45
+msgid "list_sortby_name"
+msgstr "Nama"
+
+#: views/elements/amo2009/addon_list_options.thtml:48
+#: views/elements/addon_list_options.thtml:48
+msgid "list_sortby_rating"
+msgstr "Peringkat"
+
+#: config/bootstrap.php:278
+msgid "main_prettyname_fennec"
+msgstr "Fennec"
+
+#: config/bootstrap.php:274
+msgid "main_prettyname_firefox"
+msgstr "Firefox"
+
+#: config/bootstrap.php:277
+msgid "main_prettyname_seamonkey"
+msgstr "SeaMonkey"
+
+#: config/bootstrap.php:276
+msgid "main_prettyname_sunbird"
+msgstr "Sunbird"
+
+#: config/bootstrap.php:275
+msgid "main_prettyname_thunderbird"
+msgstr "Thunderbird"
+
+#: views/elements/addon_categories.thtml:52
+msgid "nav_category_dicts_langpacks"
+msgstr "Kamus & Paket Bahasa"
+
+#: views/elements/addon_categories.thtml:55
+msgid "nav_category_themes"
+msgstr "Tema"
+
+#: views/elements/app_chooser.thtml:47 views/layouts/amo2009.thtml:255
+msgid "other_apps_tooltip"
+msgstr "Temukan pengaya untuk aplikasi lain"
+
+#. In a user list: user 1, user 2, "others"
+#: views/helpers/addons_html.php:222
+msgid "other_users"
+msgstr "lainnya"
+
+#: controllers/pages_controller.php:90
+msgid "page_title_appversions"
+msgstr "Versi Aplikasi"
+
+#: controllers/pages_controller.php:115
+#, fuzzy
+msgid "page_title_collector"
+msgstr "Add-on Collector"
+
+#: controllers/pages_controller.php:117
+#, fuzzy
+msgid "page_title_collector_faq"
+msgstr "Add-on Collector FAQ"
+
+#: controllers/pages_controller.php:119
+#, fuzzy
+msgid "page_title_collector_features"
+msgstr "Add-on Collector Features"
+
+#: controllers/pages_controller.php:122
+#, fuzzy
+msgid "page_title_collector_firstrun"
+msgstr "Welcome to the Add-on Collector"
+
+#: controllers/pages_controller.php:92
+msgid "page_title_credits"
+msgstr "Kredit"
+
+#: controllers/pages_controller.php:113
+#, fuzzy
+msgid "page_title_developer_faq"
+msgstr "Developer FAQ"
+
+#: controllers/pages_controller.php:111
+msgid "page_title_faq"
+msgstr "Tanya-Jawab"
+
+#: controllers/pages_controller.php:94
+msgid "page_title_fashionyourfirefox_faq"
+msgstr "Tanya-Jawab untuk Gaya Firefoxmu"
+
+#: controllers/pages_controller.php:101
+msgid "page_title_policy"
+msgstr "Kebijakan tentang Pengaya"
+
+#: controllers/pages_controller.php:103
+msgid "page_title_privacy"
+msgstr "Kebijakan Privasi Mozilla"
+
+#: controllers/pages_controller.php:105
+msgid "page_title_review_guide"
+msgstr "Petunjuk Umum Tinjauan"
+
+#: controllers/pages_controller.php:107
+msgid "page_title_sandbox"
+msgstr "Sistem Peninjauan Sandbox"
+
+#: controllers/pages_controller.php:109
+msgid "page_title_submissionhelp"
+msgstr "Bantuan Pengajuan"
+
+#: views/pages/appversions.thtml:87
+msgid "pages_appversions_guid"
+msgstr "GUID"
+
+#: views/pages/appversions.thtml:79 controllers/pages_controller.php:90
+msgid "pages_appversions_header"
+msgstr "Versi Aplikasi yang Sah"
+
+#: views/pages/appversions.thtml:80
+msgid "pages_appversions_intro"
+msgstr ""
+"Pengaya yang diajukan ke Pengaya Mozilla harus memiliki berkas install.rdf "
+"yang paling sedikit mengandung satu aplikasi yang ingin didukung di bawah "
+"ini. Hanya versi di bawah ini yang diizinkan untuk aplikasi tersebut."
+
+#. %s is a full <a> tag
+#: views/pages/appversions.thtml:93
+#, php-format
+msgid "pages_appversions_required_files"
+msgstr ""
+"Jika aplikasi yang ingin didukung tidak membutuhkan berkas install.rdf, anda "
+"masih diharuskan untuk menyertakannya dengan properti yang diwajibkan "
+"seperti pada disebutkan dalam spesifikasi %s."
+
+#. this is the text inside of an <a> tag for pages_appversions_required_files. This
+#. should be fixed.
+#: views/pages/appversions.thtml:93
+msgid "pages_appversions_required_files_link"
+msgstr "di sini"
+
+#: views/pages/appversions.thtml:88
+msgid "pages_appversions_versions"
+msgstr "Versi"
+
+#: views/pages/policy.thtml:51
+msgid "pages_policy_sandbox_link"
+msgstr "Halaman Informasi Sandbox"
+
+#: views/elements/pagination.thtml:53
+msgid "pagination_next_page"
+msgstr "selanjutnya"
+
+#: views/elements/pagination.thtml:52
+msgid "pagination_previous_page"
+msgstr "sebelumnya"
+
+#: views/elements/recaptcha.thtml:65
+msgid "recaptcha_enter_both_words"
+msgstr ""
+"Ketikkan <strong>dua kata</strong> di bawah ini, <strong>dipisahkan dengan "
+"spasi</strong>."
+
+#: views/elements/recaptcha.thtml:83
+msgid "recaptcha_enter_here"
+msgstr "Ketik di sini:"
+
+#: views/elements/recaptcha.thtml:74
+msgid "recaptcha_enter_whatyouhear"
+msgstr "Ketikkan apa yang telah Anda dengar."
+
+#. %1 is the link switching refreshing the captcha
+#. %2 is the link switching to a text captcha
+#: views/elements/recaptcha.thtml:77
+msgid "recaptcha_hardtohear_text"
+msgstr ""
+"Jika susah dimengerti, Anda dapat <a href=\"%1$s\">mendengarkan lainnya</a> "
+"atau <a href=\"%2$s\">kembali ke mode tulisan</a>."
+
+#. %1 is the link switching refreshing the captcha
+#. %2 is the link switching to an audio captcha
+#: views/elements/recaptcha.thtml:68
+msgid "recaptcha_hardtoread_text"
+msgstr ""
+"Jika susah dibaca, Anda dapat <a href=\"%1$s\">mencoba kata lains</a> atau "
+"<a href=\"%2$s\">mendengarkan sesuatu</a>."
+
+#: views/users/register.thtml:105
+msgid "recaptcha_label"
+msgstr "Benarkah anda manusia?"
+
+#: views/users/register.thtml:106
+msgid "recaptcha_whatsthis"
+msgstr "Apa artinya?"
+
+#: controllers/reviews_controller.php:559
+msgid "review_flag_error"
+msgstr "Kesalahan terjadi saat menandai tinjauan ini!"
+
+#: models/reviews_moderation_flag.php:69
+msgid "review_flag_reason_bug_support"
+msgstr "Laporan kesalahan atau permintaan layanan dukungan yang salah sasaran"
+
+#: views/reviews/display.thtml:103 views/reviews/display.thtml:186
+msgid "review_flag_reason_instructions"
+msgstr "Laporkan tinjauan ini (dan pilih alasannya)"
+
+#: models/reviews_moderation_flag.php:67
+msgid "review_flag_reason_language"
+msgstr "Bahasa yang tidak sopan"
+
+#: models/reviews_moderation_flag.php:71
+msgid "review_flag_reason_other"
+msgstr "Lainnya (silakan tulis)"
+
+#: models/reviews_moderation_flag.php:65
+msgid "review_flag_reason_spam"
+msgstr "Spam atau isi yang tidak dapat ditinjau"
+
+#: views/reviews/display.thtml:91 views/reviews/display.thtml:175
+#: controllers/reviews_controller.php:555
+msgid "review_flag_success"
+msgstr ""
+"Terima kasih, tinjauan ini telah ditandai untuk mendapatkan persetujuan "
+"penyunting."
+
+#: views/reviews/display.thtml:41
+msgid "review_flag_this"
+msgstr "Laporkan tinjauan ini"
+
+#: views/reviews/display.thtml:42
+msgid "review_flag_this_titletip"
+msgstr ""
+"Apakah tinjauan ini tidak pantas, tidak akurat atau spam? Jika ya, klik di "
+"sini untuk menandai tinjauan ini agar ditinjau oleh penyunting."
+
+#. %1 is the URL of the support section, %2 for the review guidelines
+#: views/reviews/add.thtml:53
+msgid "review_guidelines_short"
+msgstr ""
+"<p>Perhatikan tips berikut ini:</p><ul><li>Tulislah tinjauan seperti anda "
+"menulis untuk teman anda tentang pengalaman menggunakan pengaya ini. Berikan "
+"keterangan yang lengkap dan jelas seperti fitur apa yang anda sukai/tidak "
+"sukai, kemudahan apa yang anda temukan dalam menggunakannya, serta kerugian "
+"apa yang anda tidak sukai. Hindari penggunaan kata-kata umum seperti \"Bagus"
+"\" atau \"Jelek\" tanpa memberikan alasan tertentu mengapa anda mengatakan "
+"hal tersebut.</li><li>Mohon tidak melaporkan laporan kerusakan (bug) pada "
+"form tinjauan ini. Kami tidak memberitahukan email anda kepada pengembang "
+"pengaya yang mungkin mereka butuhkan untuk mendapatkan keterangan lebih "
+"lanjut untuk membantu menyelesaikan masalah anda. Kunjungi <a href=\"%1$s"
+"\">bagian layanan dukungan</a> untuk mengetahui cara mendapatkan bantuan "
+"tentang pengaya ini</li><li>Mohon dijaga agar tinjauan ini agar tetap dalam "
+"keadaan baik. Hindari menyebutkan sesuatu dalam bahasa yang tidak sopan atau "
+"informasi pribadi.</li></ul><p>Silakan kunjungi <a href=\"%2$s\">Petunjuk "
+"tentang Tinjauan</a> untuk keterangan lebih lanjut tentang tinjauan pengguna "
+"untuk pengaya ini</p>"
+
+#. %1 is the add-on name
+#: views/reviews/flag.thtml:56 views/reviews/display.thtml:55
+#: views/reviews/review_added.thtml:50
+#, php-format
+msgid "reviews_header"
+msgstr "Tinjauan untuk for %s"
+
+#: controllers/addons_controller.php:435
+msgid "rss_featuredaddons"
+msgstr "Rekomendasi Pengaya"
+
+#: controllers/addons_controller.php:432
+msgid "rss_newestaddons"
+msgstr "Pengaya Baru"
+
+#: controllers/addons_controller.php:434
+#, fuzzy
+msgid "rss_popularaddons"
+msgstr "Popular Add-ons"
+
+#: controllers/addons_controller.php:433
+msgid "rss_updatedaddons"
+msgstr "Versi Baru Pengaya"
+
+#: views/elements/search_mini.thtml:70
+#, fuzzy
+msgid "search"
+msgstr "Search"
+
+#: views/search/collections.thtml:51
+#, fuzzy
+msgid "search_collections_header"
+msgstr "Collection Search Results"
+
+#: controllers/search_controller.php:297
+#, fuzzy
+msgid "search_collections_pagetitle"
+msgstr "Collection Search Results"
+
+#: controllers/search_controller.php:99
+msgid "search_disabled"
+msgstr "Pencarian sedang dimatikan. Mohon coba lagi nanti."
+
+#: views/elements/amo2009/search.thtml:188 views/elements/search.thtml:187
+#: views/elements/search_mini.thtml:54
+msgid "search_form_all_addons"
+msgstr "semua pengaya"
+
+#. This string is in the main category dropdown when searching
+#: views/elements/amo2009/search.thtml:204
+#, fuzzy
+msgid "search_form_all_collections"
+msgstr "all collections"
+
+#: views/elements/amo2009/search.thtml:184
+#: views/elements/amo2009/search.thtml:385
+#: views/elements/amo2009/search.thtml:408 views/elements/search.thtml:171
+#: views/elements/search.thtml:183 views/elements/search_mini.thtml:43
+#: views/elements/search_mini.thtml:49 views/layouts/mozilla.thtml:188
+msgid "search_form_default_text"
+msgstr "cari pengaya"
+
+#: views/elements/amo2009/search.thtml:184
+#: views/elements/amo2009/search.thtml:404
+#, fuzzy
+msgid "search_form_default_text_collections"
+msgstr "search for collections"
+
+#: views/elements/amo2009/search.thtml:206 views/elements/search.thtml:202
+msgid "search_form_submit_tooltip"
+msgstr "Cari pengaya"
+
+#: views/elements/amo2009/search.thtml:184 views/elements/search.thtml:183
+#: views/elements/search_mini.thtml:49
+msgid "search_form_tooltip"
+msgstr "Klik untuk mengetikkan kata yang dicari"
+
+#: views/elements/amo2009/search.thtml:186 views/elements/search.thtml:185
+#: views/elements/search_mini.thtml:52
+msgid "search_form_within"
+msgstr "di"
+
+#: views/addons/searchengines.thtml:118
+msgid "search_landing_all_search_engines"
+msgstr "Semua Mesin Pencari"
+
+#: views/addons/searchengines.thtml:114
+msgid "search_landing_browse_search_engines"
+msgstr "Jelajahi Mesin Pencari"
+
+#: views/search/collections.thtml:58 views/search/index.thtml:59
+msgid "search_nothing_found"
+msgstr "Tidak ada yang ditemukan."
+
+#: controllers/search_controller.php:185
+msgid "search_pagetitle"
+msgstr "Cari Pengaya"
+
+#: controllers/search_controller.php:242
+msgid "search_rss_description"
+msgstr "Feed hasil pencarian"
+
+#. %s is the terms the user is searching for (a string)
+#: controllers/search_controller.php:241
+#, php-format
+msgid "search_rss_results_for"
+msgstr "Hasil pencarian untuk: %s"
+
+#: views/elements/header.thtml:154 views/layouts/amo2009.thtml:296
+msgid "sidebar_navlink_admin_tools"
+msgstr "Perangkat Admin"
+
+#: views/elements/header.thtml:146 views/layouts/amo2009.thtml:288
+msgid "sidebar_navlink_developer_tools"
+msgstr "Perangkat Pengembang"
+
+#: views/elements/header.thtml:148 views/layouts/amo2009.thtml:290
+msgid "sidebar_navlink_editor_tools"
+msgstr "Perangkat Penyunting"
+
+#: views/layouts/amo2009.thtml:302
+msgid "sidebar_navlink_welcome"
+msgstr "Selamat Datang"
+
+#. %s is the user's name
+#: views/layouts/amo2009.thtml:302
+#, php-format
+msgid "sidebar_navlink_welcome_name"
+msgstr "Selamat Datang, %s"
+
+#: views/elements/pitch.thtml:50 views/elements/pitch.thtml:55
+msgid "sidebar_pitch_dictionary"
+msgstr "Kamus"
+
+#: views/elements/pitch.thtml:72
+msgid "sidebar_pitch_featured_addons"
+msgstr "Rekomendasi Kami"
+
+#: views/elements/pitch.thtml:61
+msgid "sidebar_pitch_looking_for"
+msgstr "Saya mencari:"
+
+#: views/elements/pitch.thtml:70
+msgid "sidebar_pitch_newest_addons"
+msgstr "Pengaya Baru"
+
+#: views/elements/pitch.thtml:49
+msgid "sidebar_pitch_search"
+msgstr "Mesin Pencari"
+
+#: views/elements/pitch.thtml:69
+msgid "sidebar_pitch_subscribe_to"
+msgstr "Berlangganan"
+
+#: views/elements/pitch.thtml:48 views/elements/pitch.thtml:54
+msgid "sidebar_pitch_theme"
+msgstr "Tema"
+
+#: views/elements/pitch.thtml:71
+msgid "sidebar_pitch_updated_addons"
+msgstr "Versi Baru Pengaya"
+
+#. %1$s is a number
+#: views/helpers/localization.php:65 views/developers/versions_edit.thtml:95
+#: views/addons/dictionaries.thtml:92
+#, php-format
+msgid "size_kb"
+msgstr "%1$s KB"
+
+#: views/elements/amo2009/stars.thtml:57 views/elements/stars.thtml:63
+msgid "stars_not_yet_rated"
+msgstr "Belum diperingkat"
+
+#. %1 is the number of stars this add-on has
+#: views/elements/amo2009/stars.thtml:49 views/elements/stars.thtml:54
+#, php-format
+msgid "stars_rated_x_outof_5"
+msgstr "Peringkat %s dari 5 bintang"
+
+#: views/statistics/addon.thtml:59
+msgid "statistics_addon_dashboard_link"
+msgstr "Beranda Statistik"
+
+#: views/statistics/addon.thtml:58
+msgid "statistics_addon_developertools_link"
+msgstr "Perangkat Pengembang"
+
+#: views/statistics/addon.thtml:53
+msgid "statistics_addon_switch"
+msgstr "Pindah ke"
+
+#. This is a date format.
+#. http://php.net/strftime
+#: views/statistics/rss/summary.thtml:54 views/statistics/addon.thtml:181
+msgid "statistics_date_shortmonth"
+msgstr "%e %b"
+
+#. This is a date format.
+#. http://php.net/strftime
+#: views/statistics/rss/summary.thtml:40 views/statistics/addon.thtml:152
+msgid "statistics_date_shortmonthwithyear"
+msgstr "%e %b %Y"
+
+#. This is a date format.
+#. http://php.net/strftime
+#: views/statistics/rss/summary.thtml:41 views/statistics/rss/summary.thtml:48
+#: views/statistics/addon.thtml:161 views/statistics/addon.thtml:172
+msgid "statistics_date_weekdayshortmonth"
+msgstr "%A, %e %b"
+
+#. %1$s is an add-on name and version. Example: Add-on 3.5
+#: controllers/components/stats.php:519
+#, php-format
+msgid "statistics_events_addon_created"
+msgstr "%1$s dibuat"
+
+#. %1$s is an application name and version. Example: Firefox 3.5
+#: controllers/components/stats.php:500
+#, php-format
+msgid "statistics_events_app_released"
+msgstr "%1$s dirilis"
+
+#: views/statistics/addon.thtml:71
+msgid "statistics_help_close_link"
+msgstr "Tutup"
+
+#: views/statistics/addon.thtml:60
+msgid "statistics_help_link"
+msgstr "Bantuan"
+
+#: views/statistics/index.thtml:83
+msgid "statistics_index_anotheraddon"
+msgstr "atau pilih pengaya lain"
+
+#: views/statistics/index.thtml:85
+msgid "statistics_index_anotheraddon_public"
+msgstr "atau pilih pengaya dengan statistik publik"
+
+#: views/statistics/index.thtml:71
+msgid "statistics_index_myaddons"
+msgstr "Pilih salah satu pengaya anda untuk ditampilkan statistiknya"
+
+#: views/statistics/index.thtml:89
+msgid "statistics_index_selectaddon"
+msgstr "Pilih sebuah pengaya untuk ditampilkan statistiknya"
+
+#: views/statistics/index.thtml:91
+msgid "statistics_index_selectaddon_public"
+msgstr "Pilih pengaya dengan statistik publik"
+
+#: views/statistics/index.thtml:39
+msgid "statistics_index_title"
+msgstr "Panel Statistik"
+
+#: views/statistics/index.thtml:97
+msgid "statistics_index_view_button"
+msgstr "Tampilkan Statistik"
+
+#: views/statistics/addon.thtml:222 controllers/statistics_controller.php:247
+msgid "statistics_js_download_csv"
+msgstr "Tampilkan tabel ini dalam format CSV"
+
+#: controllers/statistics_controller.php:246
+msgid "statistics_js_dropdowns_none"
+msgstr "tidak ada"
+
+#: controllers/statistics_controller.php:245
+msgid "statistics_js_dropdowns_removeplot"
+msgstr "Hapus plot ini"
+
+#: controllers/statistics_controller.php:248
+msgid "statistics_js_groupby_selector_date"
+msgstr "Dikelompokkan: Hari"
+
+#: controllers/statistics_controller.php:251
+msgid "statistics_js_groupby_selector_month"
+msgstr "Dikelompokkan: Bulan"
+
+#: controllers/statistics_controller.php:249
+msgid "statistics_js_groupby_selector_week"
+msgstr "Dikelompokkan: Mingguan"
+
+#: controllers/statistics_controller.php:250
+msgid "statistics_js_groupby_selector_week_over_week"
+msgstr "Bandingkan dalam: Mingguan"
+
+#: controllers/statistics_controller.php:260
+msgid "statistics_js_plotselection_foundinrange"
+msgstr "%s ditemukan pada rentang"
+
+#: controllers/statistics_controller.php:270
+msgid "statistics_js_plotselection_options_addplot_name"
+msgstr "Tambahkan plot"
+
+#: controllers/statistics_controller.php:271
+msgid "statistics_js_plotselection_options_addplot_tooltip"
+msgstr "Tambahkan plot lain pada grafik ini"
+
+#: controllers/statistics_controller.php:261
+msgid "statistics_js_plotselection_options_count_name_checked"
+msgstr "Sembunyikan Jumlah Total"
+
+#: controllers/statistics_controller.php:262
+msgid "statistics_js_plotselection_options_count_name_unchecked"
+msgstr "Tampilkan Jumlah Total"
+
+#: controllers/statistics_controller.php:263
+msgid "statistics_js_plotselection_options_count_tooltip"
+msgstr "Buat plot jumlah total pada grafik ini"
+
+#: controllers/statistics_controller.php:275
+msgid "statistics_js_plotselection_options_csv_name"
+msgstr "Tampilkan data (format CSV)"
+
+#: controllers/statistics_controller.php:276
+msgid "statistics_js_plotselection_options_csv_tooltip"
+msgstr "Ambil berkas Comma Separated Values untuk data ini"
+
+#: controllers/statistics_controller.php:267
+msgid "statistics_js_plotselection_options_events_addon_name_checked"
+msgstr "Sembunyikan Event untuk %s"
+
+#: controllers/statistics_controller.php:268
+msgid "statistics_js_plotselection_options_events_addon_name_unchecked"
+msgstr "Tampilkan Event untuk %s"
+
+#: controllers/statistics_controller.php:269
+msgid "statistics_js_plotselection_options_events_addon_tooltip"
+msgstr "Tampilkan tanggal rilis pengaya di atas plot"
+
+#: controllers/statistics_controller.php:264
+msgid "statistics_js_plotselection_options_events_firefox_name_checked"
+msgstr "Sembunyikan Event untuk Firefox"
+
+#: controllers/statistics_controller.php:265
+msgid "statistics_js_plotselection_options_events_firefox_name_unchecked"
+msgstr "Tampilkan Event untuk Firefox"
+
+#: controllers/statistics_controller.php:266
+msgid "statistics_js_plotselection_options_events_firefox_tooltip"
+msgstr "Tampilkan tanggal rilis Firefox di atas plot"
+
+#: controllers/statistics_controller.php:272
+msgid "statistics_js_plotselection_options_resize_name_checked"
+msgstr "Perkecil Grafik"
+
+#: controllers/statistics_controller.php:273
+msgid "statistics_js_plotselection_options_resize_name_unchecked"
+msgstr "Perlebar Grafik"
+
+#: controllers/statistics_controller.php:274
+msgid "statistics_js_plotselection_options_resize_tooltip"
+msgstr "Ganti ukuran grafik"
+
+#: controllers/statistics_controller.php:254
+msgid "statistics_js_plotselection_selector_adu"
+msgstr "Pengguna Aktif Harian"
+
+#: controllers/statistics_controller.php:256
+msgid "statistics_js_plotselection_selector_application"
+msgstr "Aplikasi"
+
+#: controllers/statistics_controller.php:259
+msgid "statistics_js_plotselection_selector_custom"
+msgstr "Suka-suka"
+
+#: controllers/statistics_controller.php:253
+msgid "statistics_js_plotselection_selector_downloads"
+msgstr "Jumlah Unduhan"
+
+#: controllers/statistics_controller.php:258
+msgid "statistics_js_plotselection_selector_os"
+msgstr "Sistem Operasi"
+
+#: controllers/statistics_controller.php:257
+msgid "statistics_js_plotselection_selector_status"
+msgstr "Status Pengaya"
+
+#: controllers/statistics_controller.php:252
+msgid "statistics_js_plotselection_selector_summary"
+msgstr "Ringkasan"
+
+#: controllers/statistics_controller.php:255
+msgid "statistics_js_plotselection_selector_version"
+msgstr "Versi Pengaya"
+
+#: controllers/components/stats.php:398
+msgid "statistics_longnames_application"
+msgstr "Aplikasi"
+
+#: controllers/components/stats.php:400
+msgid "statistics_longnames_os"
+msgstr "Sistem Operasi"
+
+#: controllers/components/stats.php:399
+msgid "statistics_longnames_status"
+msgstr "Status Pengaya"
+
+#: controllers/components/stats.php:401
+msgid "statistics_longnames_unknown"
+msgstr "Tidak Diketahui"
+
+#: controllers/components/stats.php:397
+msgid "statistics_longnames_version"
+msgstr "Versi Pengaya"
+
+#: views/statistics/addon.thtml:118
+msgid "statistics_notice_data_insufficient"
+msgstr ""
+"Data masih belum cukup untuk ditampilkan pada grafik. Mohon periksa lagi "
+"nanti."
+
+#: views/statistics/addon.thtml:130
+msgid "statistics_notice_data_none"
+msgstr ""
+"Kami masih tidak memiliki data untuk pengaya anda. Mohon periksa lagi "
+"beberapa hari ke depan."
+
+#: views/statistics/addon.thtml:41
+msgid "statistics_notice_data_updating"
+msgstr ""
+"Statistik pengaya sedang dalam proses pemutakhiran. Data terbaru mungkin "
+"masih belum diperbarui pada saat skrip kami sedang memproses informasi "
+"tersebut. Mohon periksa lagi beberapa menit lagi."
+
+#: views/statistics/addon.thtml:136
+msgid "statistics_notice_disabled"
+msgstr "Panel Statistik sedang dimatikan. Mohon periksa lagi nanti."
+
+#: views/statistics/addon.thtml:123
+msgid "statistics_notice_nojavascript"
+msgstr "JavaScript harus diaktifkan untuk menampilkan grafik Panel Statistik."
+
+#: views/statistics/addon.thtml:44
+msgid "statistics_notice_settings_updated"
+msgstr "Pengaturan baru anda telah disimpan!"
+
+#: controllers/statistics_controller.php:60
+#: controllers/statistics_controller.php:71
+#: controllers/statistics_controller.php:74
+#: controllers/statistics_controller.php:240
+msgid "statistics_pagetitle"
+msgstr "Panel Statistik"
+
+#: views/statistics/addon.thtml:99
+msgid "statistics_plot_legend_adu"
+msgstr "Pengguna Aktif Harian"
+
+#: views/statistics/addon.thtml:95
+msgid "statistics_plot_legend_downloads"
+msgstr "Jumlah Unduhan Harian"
+
+#: views/statistics/addon.thtml:107
+msgid "statistics_plot_options_zoomin_alt"
+msgstr "Perbesar"
+
+#: views/statistics/addon.thtml:106
+msgid "statistics_plot_options_zoomin_title"
+msgstr "Perbesar satu bulan"
+
+#: views/statistics/addon.thtml:110
+msgid "statistics_plot_options_zoomout_alt"
+msgstr "Perkecil"
+
+#: views/statistics/addon.thtml:109
+msgid "statistics_plot_options_zoomout_title"
+msgstr "Perkecil satu bulan"
+
+#: controllers/statistics_controller.php:283
+#, php-format
+msgid "statistics_rss_description"
+msgstr "Ringkasan harian statistik untuk %1$s"
+
+#: views/statistics/rss/summary.thtml:68
+msgid "statistics_rss_title_fulldate"
+msgstr "%A, %e %B %Y"
+
+#: views/statistics/rss/summary.thtml:68
+#, php-format
+msgid "statistics_rss_title_statsfordate"
+msgstr "Statistik untuk %1$s"
+
+#: views/statistics/settings.thtml:49
+msgid "statistics_settings_access_description"
+msgstr ""
+"Secara default, hanya anda dan pihak Mozilla yang dapat mengakses informasi "
+"pada panel anda. Anda dapat membukanya untuk publik sehingga semua orang "
+"dapat melihat data pengaya anda."
+
+#: views/statistics/settings.thtml:48
+msgid "statistics_settings_access_heading"
+msgstr "Hak Akses Panel"
+
+#: views/statistics/settings.thtml:51
+msgid "statistics_settings_access_private"
+msgstr "Pribadi"
+
+#: views/statistics/settings.thtml:51
+msgid "statistics_settings_access_private_description"
+msgstr "Hanya anda dan pihak Mozilla yang dapat melihat statistik pengaya ini"
+
+#: views/statistics/settings.thtml:52
+msgid "statistics_settings_access_public"
+msgstr "Publik"
+
+#: views/statistics/settings.thtml:52
+msgid "statistics_settings_access_public_description"
+msgstr "Semua orang dapat melihat statistik pengaya ini"
+
+#: views/statistics/addon.thtml:251
+msgid "statistics_settings_change_link"
+msgstr "Ubah Pengaturan"
+
+#: views/statistics/addon.thtml:253
+msgid "statistics_settings_confidential"
+msgstr "Mohon perlakukan informasi ini secara rahasia."
+
+#: views/statistics/addon.thtml:245
+msgid "statistics_settings_currently_private"
+msgstr "Panel dalam mode <b>pribadi</b>."
+
+#: views/statistics/addon.thtml:241
+msgid "statistics_settings_currently_public"
+msgstr "Panel dalam mode <b>publik</b>."
+
+#: views/statistics/addon.thtml:246
+msgid "statistics_settings_locked_alt"
+msgstr "Terkunci"
+
+#: views/statistics/settings.thtml:57
+msgid "statistics_settings_return_link"
+msgstr "Kembali ke Panel"
+
+#: views/statistics/settings.thtml:56
+msgid "statistics_settings_save_button"
+msgstr "Simpan Pengaturan"
+
+#: views/statistics/settings.thtml:46
+#, php-format
+msgid "statistics_settings_title"
+msgstr "Pengaturan Panel Statistik untuk %1$s"
+
+#: views/statistics/addon.thtml:242
+msgid "statistics_settings_unlocked_alt"
+msgstr "Tidak Terkunci"
+
+#: controllers/components/stats.php:405
+msgid "statistics_shortnames_application"
+msgstr "App"
+
+#: controllers/components/stats.php:407
+msgid "statistics_shortnames_os"
+msgstr "OS"
+
+#: controllers/components/stats.php:406
+msgid "statistics_shortnames_status"
+msgstr "St"
+
+#: controllers/components/stats.php:408
+msgid "statistics_shortnames_unknown"
+msgstr "Uk"
+
+#: controllers/components/stats.php:404
+msgid "statistics_shortnames_version"
+msgstr "Ver"
+
+#: views/statistics/rss/summary.thtml:42 views/statistics/addon.thtml:192
+msgid "statistics_summary_downloads_average"
+msgstr "Rata-rata Jumlah Unduhan Harian"
+
+#: views/statistics/rss/summary.thtml:39
+msgid "statistics_summary_downloads_heading"
+msgstr "Unduhan"
+
+#: views/statistics/rss/summary.thtml:41 views/statistics/addon.thtml:171
+msgid "statistics_summary_downloads_lastcount"
+msgstr "Perhitungan Harian Terakhir"
+
+#: views/statistics/rss/summary.thtml:43 views/statistics/addon.thtml:199
+msgid "statistics_summary_downloads_lastweek"
+msgstr "Unduhan sejak 7 hari terakhir"
+
+#: views/statistics/rss/summary.thtml:40 views/statistics/addon.thtml:151
+msgid "statistics_summary_downloads_total"
+msgstr "Unduhan Total"
+
+#: views/statistics/rss/summary.thtml:40 views/statistics/addon.thtml:152
+#, php-format
+msgid "statistics_summary_downloads_total_sincedate"
+msgstr "Sejak %1$s"
+
+#: views/statistics/rss/summary.thtml:50 views/statistics/rss/summary.thtml:56
+#: views/statistics/addon.thtml:163 views/statistics/addon.thtml:183
+msgid "statistics_summary_nodata"
+msgstr "Belum ada data"
+
+#: views/statistics/rss/summary.thtml:60 views/statistics/addon.thtml:195
+msgid "statistics_summary_updatepings_average"
+msgstr "Rata-rata Pengguna Aktif Harian"
+
+#: views/statistics/rss/summary.thtml:52 views/statistics/addon.thtml:177
+msgid "statistics_summary_updatepings_changefromprevious"
+msgstr "Perubahan sejak perhitungan sebelumnya"
+
+#: views/statistics/rss/summary.thtml:54 views/statistics/addon.thtml:181
+#, php-format
+msgid "statistics_summary_updatepings_changefromprevious_ondate"
+msgstr "%1$s pada %2$s"
+
+#: views/statistics/rss/summary.thtml:45
+msgid "statistics_summary_updatepings_heading"
+msgstr "Pengguna Aktif Harian"
+
+#: views/statistics/rss/summary.thtml:46 views/statistics/addon.thtml:157
+msgid "statistics_summary_updatepings_total"
+msgstr "Pengguna Aktif Harian"
+
+#: views/statistics/rss/summary.thtml:48 views/statistics/addon.thtml:161
+#, php-format
+msgid "statistics_summary_updatepings_total_ondate"
+msgstr "Pada %1$s"
+
+#: views/statistics/rss/summary.thtml:61 views/statistics/addon.thtml:203
+#, fuzzy
+msgid "statistics_summary_updatepings_weekly_average"
+msgstr "Average Daily Users this Week"
+
+#. %s is a percentage, like '+22.33%'. It sits next to another number, so
+#. the implied meaning is 'percentage change' from the previous stat point.
+#: views/statistics/rss/summary.thtml:62 views/statistics/addon.thtml:205
+#, fuzzy
+msgid "statistics_summary_updatepings_weekly_change"
+msgstr "%s from last week"
+
+#: views/statistics/addon.thtml:65 controllers/statistics_controller.php:184
+#: controllers/statistics_controller.php:282
+#, php-format
+msgid "statistics_title_addon_stats"
+msgstr "Statistik %1$s"
+
+#: views/addons/themes_landing.thtml:113
+msgid "themes_landing_all_themes"
+msgstr "Semua Tema"
+
+#: views/addons/themes_landing.thtml:109
+msgid "themes_landing_browse_themes"
+msgstr "Jelajahi Tema"
+
+#: views/users/edit.thtml:185
+msgid "user_change_email"
+msgstr "Ganti Alamat Email"
+
+#: views/users/edit.thtml:169
+msgid "user_change_password"
+msgstr "Ubah kata sandi"
+
+#: views/users/edit.thtml:96
+#, fuzzy
+msgid "user_change_password_or_email"
+msgstr "Change Password or Email"
+
+#: controllers/users_controller.php:197
+msgid "user_confirmationcode_resent"
+msgstr "Kode konfirmasi telah dikirim ulang!"
+
+#. %1 is the email address, %2 is the URL of the user registration page
+#: views/users/delete.thtml:51
+msgid "user_del_account_deleted"
+msgstr ""
+"Akun anda %1$s telah sukses dihapus. Jika nanti anda ingin kembali, anda "
+"dapat mendaftar ulang dari <a href=\"%2$s\">halaman pendaftaran pengguna</a>."
+
+#: views/users/delete.thtml:102
+msgid "user_del_community_sad"
+msgstr "Komunitas Pengaya Mozilla bersedih hati, melihat anda melangkah pergi."
+
+#: views/users/delete.thtml:123
+msgid "user_del_confirm_password"
+msgstr "Konfirmasi Kata Sandi"
+
+#: views/users/delete.thtml:134
+msgid "user_del_deletenow"
+msgstr "Hapus akun pengguna saya sekarang"
+
+#. %1 is the URL of the user's info page
+#: views/users/delete.thtml:64
+msgid "user_del_error_addons"
+msgstr ""
+"Anda tidak dapat menghapus akun anda jika akun tersebut terdaftar sebagai "
+"salah satu <a href=\"%1$s\">penyusun pengaya</a>. Untuk menghapus akun anda, "
+"silakan menghubungi orang lain yang berada kelompok pengembang anda yang "
+"dapat menghapus akun anda dari daftar penyusun pengaya pada pengaya anda. "
+"Setelah itu, baru anda dapat menghapus akun anda dari halaman ini."
+
+#. %1 is a link to the amo-editors mailing list
+#: views/users/delete.thtml:71
+msgid "user_del_error_addons_more_questions"
+msgstr ""
+"Jika anda memiliki pertanyaan lainnya, silakan hubungi %1$s untuk "
+"mendapatkan bantuan."
+
+#: views/users/delete.thtml:78
+msgid "user_del_error_checkbox"
+msgstr ""
+"Anda harus mencentang pilihan \"Saya paham...\" sebelum kami dapat menghapus "
+"akun anda."
+
+#: views/users/delete.thtml:84
+msgid "user_del_error_password"
+msgstr "Silakan masukkan kata sandi dengan benar untuk melanjutkan proses ini."
+
+#. %1 is a link to the amo-admins mailing list
+#: views/users/delete.thtml:91
+msgid "user_del_error_unknown"
+msgstr ""
+"Kesalahan yang tidak dikenali terjadi ketika menghapus akun anda. Mohon "
+"menghubungi %1$s beserta penjelasan masalah ini dan kami akan menghapusnya "
+"untuk anda. Kami mohon maaf atas ketidaknyamanan ini."
+
+#: views/users/delete.thtml:110
+msgid "user_del_header_confirm_deletion"
+msgstr "Konfirmasi penghapusan akun"
+
+#. %1 is the user's email address
+#: views/users/delete.thtml:100
+msgid "user_del_header_delete_account"
+msgstr "Hapus Akun Pengguna %1$s"
+
+#: views/users/delete.thtml:50
+msgid "user_del_header_farewell"
+msgstr "Selamat Tinggal!"
+
+#: views/users/delete.thtml:115
+msgid "user_del_nologin"
+msgstr ""
+"Anda tidak akan lagi dapat log-masuk ke situs Pengaya Mozilla dengan "
+"menggunakan informasi log-masuk ini."
+
+#: views/users/delete.thtml:112
+msgid "user_del_permanently_removed_means"
+msgstr ""
+"Dengan mengklik tombol \"hapus\" akun anda akan <strong>dihapus selamanya</"
+"strong>. Artinya:"
+
+#: views/users/delete.thtml:116
+msgid "user_del_reviews_anonymized"
+msgstr ""
+"Tinjauan dan pemeringkatan yang anda kirimkan tidak akan dihapus, tetapi "
+"tidak akan lagi dihubungkan dengan informasi tentang anda."
+
+#. %1 is a link to the amo-editors mailing list
+#: views/users/delete.thtml:104
+msgid "user_del_specific_problem_editors"
+msgstr ""
+"Jika anda mempunyai masalah tertentu yang sekiranya dapat kami bantu, "
+"dimohon tidak menghapus akun anda sekarang, tetapi mohon menghubungi kami di "
+"%1$s dan kami akan berusaha sebaik mungkin untuk membantu anda memecahkan "
+"masalah tersebut."
+
+#: views/users/delete.thtml:130
+msgid "user_del_understand_permanent"
+msgstr ""
+"Saya sadar dan paham bahwa langkah ini tidak akan dapat mengembalikan "
+"informasi akun saya seperti sedia kala."
+
+#: views/helpers/addons_html.php:192
+msgid "user_deleted_nickname"
+msgstr "Pengguna yang Dihapus"
+
+#. %1 is the new email address
+#: views/users/edit.thtml:71
+msgid "user_edit_confirm_email_sent"
+msgstr ""
+"Sebuah email telah dikirim ke %1$s untuk mengkonfirmasi alamat email baru "
+"anda. Agar proses perubahan email ini selesai, anda wajib mengklik tautan "
+"yang tersedia pada email tersebut. Sebelum anda mengklik tautan tersebut, "
+"anda masih dapat log-masuk dengan alamat email lama anda."
+
+#: views/users/edit.thtml:201
+msgid "user_edit_delete_user"
+msgstr "Hapus akun pengguna"
+
+#. This contains the email sent to users when they signed up for a new
+#. account:
+#. %1 is the confirmation URL, %2 is the current app
+#: views/users/email/confirm_plain.thtml:6
+#, php-format
+msgid "user_email_confirm_account_nopass"
+msgstr ""
+"Selamat datang di Pengaya %2$s.\n"
+"\n"
+"Sebelum anda dapat menggunakan akun anda, anda diharuskan untuk "
+"mengaktifkannya terlebih dahulu. Ini digunakan untuk memastikan email yang "
+"anda gunakan benar dan milik anda sepenuhnya.\n"
+"Untuk mengaktifkan akun, klik tautan di bawah ini atau salin dan tempel "
+"semuanya ke bar lokasi pada browser:\n"
+"\n"
+"%1$s\n"
+"\n"
+"Setelah anda sukses mengaktifkan akun anda, anda bisa menghapus email ini.\n"
+"\n"
+"Terima kasih telah bergabung dengan Pengaya %2$s\n"
+"-- Staf Pengaya %2$s"
+
+#. %1 is the confirmation url, %2 is the application name
+#: views/users/email/emailchange_plain.thtml:5
+msgid "user_email_confirm_emailchange"
+msgstr ""
+"Anda telah meminta perubahan alamat email akun anda pada situs Pengaya %2"
+"$s.\n"
+"\n"
+"Untuk konfirmasi alamat email ini, silakan klik tautan di bawah ini, atau "
+"salin dan tempel semuanya pada bar lokasi browser anda::\n"
+"\n"
+"%1$s\n"
+"\n"
+"Anda harus melakukan proses konfirmasi pada tautan tersebut dalam waktu 48 "
+"jam. Jika anda tidak ingin mengubah alamat email sebelumnya, abaikan saja "
+"email ini.\n"
+"\n"
+"Terima kasih!\n"
+"-- Staf Pengaya %2$s"
+
+#: controllers/users_controller.php:168
+#, php-format
+msgid "user_email_confirm_subject"
+msgstr "Terima kasih telah bergabung dengan Pengaya %s"
+
+#. This is the password reset email
+#. %1 is the pw reset URL, %2 is the application
+#: views/users/email/pwreset_plain.thtml:5
+#, php-format
+msgid "user_email_pwreset"
+msgstr ""
+"Reset Kata Sandi Pengaya %2$s\n"
+"\n"
+"Sebuah permintaan untuk mereset kata sandi akun telah diterima oleh situs "
+"addons.mozilla.org. Untuk benar-benar mengubah kata sandi, silakan klik "
+"tautan berikut atau salin dan tempel ke bar lokasi browser:\n"
+"\n"
+"%1$s\n"
+"\n"
+"Jika anda tidak meminta email ini, tidak ada aksi yang perlu dilakukan.\n"
+"\n"
+"Terima Kasih,\n"
+"-- Staf Pengaya %2$s"
+
+#: controllers/users_controller.php:245
+#, php-format
+msgid "user_email_pwreset_subject"
+msgstr "Reset kata sandi Pengaya %s anda"
+
+#: views/users/emailchange.thtml:50
+msgid "user_emailchange_error"
+msgstr "Kesalahan!"
+
+#. %1 is the application name
+#: controllers/users_controller.php:533
+msgid "user_emailchange_subject"
+msgstr "Mohon konfirmasi perubahan alamat email anda di Pengaya %1$s"
+
+#: views/users/emailchange.thtml:48
+msgid "user_emailchange_success"
+msgstr "Sukses!"
+
+#. %1 is the new email address
+#: views/users/emailchange.thtml:49
+msgid "user_emailchange_successful_description"
+msgstr ""
+"Alamat email anda telah sukses diubah. Sejak saat ini, selalu gunakan %1$s "
+"untuk melakukan proses log-masuk situs ini."
+
+#: views/users/edit.thtml:134 views/admin/users_edit.thtml:111
+#, fuzzy
+msgid "user_form_bio"
+msgstr "About me"
+
+#: views/users/edit.thtml:135 views/admin/users_edit.thtml:112
+#, fuzzy
+msgid "user_form_bio_description"
+msgstr ""
+"Introduce yourself to the community, if you like! This text will appear "
+"publicly on your user info page. Line breaks will be preserved, but no HTML "
+"is allowed."
+
+#: views/users/pwreset.thtml:77 views/users/register.thtml:73
+#: views/users/edit.thtml:181
+msgid "user_form_confirmpassword"
+msgstr "Konfirmasi kata sandi"
+
+#: views/users/edit.thtml:145
+#, fuzzy
+msgid "user_form_display_collections"
+msgstr "Display the collections I have created in my user profile"
+
+#: views/users/edit.thtml:149
+#, fuzzy
+msgid "user_form_display_collections_fav"
+msgstr "Display my favorite collections in my user profile"
+
+#: views/users/edit.thtml:86
+#, php-format
+msgid "user_form_editprofile"
+msgstr "Ubah profil pengguna untuk %s"
+
+#: views/users/pwreset.thtml:52 views/users/login.thtml:81
+#: views/users/register.thtml:63 views/users/edit.thtml:187
+msgid "user_form_email"
+msgstr "Alamat email"
+
+#: views/users/register.thtml:78 views/users/edit.thtml:103
+#: views/admin/users_edit.thtml:76
+msgid "user_form_firstname"
+msgstr "Nama depan"
+
+#: views/users/register.thtml:94 views/users/edit.thtml:119
+#: views/admin/users_edit.thtml:91
+msgid "user_form_hideemail"
+msgstr "Sembunyikan alamat email"
+
+#: views/users/register.thtml:98 views/users/edit.thtml:123
+#: views/admin/users_edit.thtml:99
+msgid "user_form_homepage"
+msgstr "URL Situs Web"
+
+#: views/users/register.thtml:84 views/users/edit.thtml:109
+#: views/admin/users_edit.thtml:81
+msgid "user_form_lastname"
+msgstr "Nama belakang"
+
+#: controllers/users_controller.php:333
+msgid "user_form_login"
+msgstr "Log-masuk Pengguna"
+
+#: views/users/pwreset.thtml:72 views/users/edit.thtml:176
+msgid "user_form_newpassword"
+msgstr "Kata sandi baru"
+
+#: views/users/register.thtml:89 views/users/edit.thtml:114
+#: views/admin/users_edit.thtml:86
+msgid "user_form_nickname"
+msgstr "Nama alias (nick)"
+
+#: views/users/edit.thtml:171
+msgid "user_form_oldpassword"
+msgstr "Kata sandi lama"
+
+#: views/users/edit.thtml:97 views/users/edit.thtml:200
+msgid "user_form_otheractions"
+msgstr "Aksi Lainnya"
+
+#: views/users/login.thtml:85 views/users/register.thtml:68
+msgid "user_form_password"
+msgstr "Kata sandi"
+
+#: controllers/users_controller.php:93
+msgid "user_form_registration"
+msgstr "Pendaftaran Pengguna Baru"
+
+#: views/users/login.thtml:90
+msgid "user_form_remember_me"
+msgstr "Otomatis log-masuk dari komputer ini"
+
+#: views/admin/users_edit.thtml:95
+msgid "user_form_showsandbox"
+msgstr "Tampilkan sandbox?"
+
+#: views/users/edit.thtml:205
+msgid "user_form_submit_edit"
+msgstr "Simpan"
+
+#: views/users/login.thtml:93
+msgid "user_form_submit_login"
+msgstr "Log-masuk"
+
+#: views/users/register.thtml:113
+msgid "user_form_submit_register"
+msgstr "Daftar"
+
+#: views/users/info.thtml:75
+#, php-format
+msgid "user_info_usersince"
+msgstr "Pengguna %s sejak"
+
+#: views/users/login.thtml:102
+msgid "user_login_register_link"
+msgstr "Pendaftaran akun pengguna baru"
+
+#: views/users/edit.thtml:160
+msgid "user_notifications_item_compat"
+msgstr "Kompatibilitas Pengaya (sangat disarankan)"
+
+#: views/users/edit.thtml:161
+msgid "user_notifications_item_events"
+msgstr "Event dan Kontes yang Akan Berlangsung"
+
+#: views/users/edit.thtml:156
+msgid "user_notifications_none_available"
+msgstr "Tidak ada peringatan yang tersedia untuk diatur."
+
+#: views/users/edit.thtml:158
+msgid "user_notifications_select_topics"
+msgstr ""
+"Dari waktu ke waktu, Mozilla mungkin akan mengirimkan email kepada Anda "
+"mengenai event dan rilis pengaya yang akan berlangsung. Silakan pilih topik "
+"yang anda sukai di bawah ini:"
+
+#: views/users/edit.thtml:164
+msgid "user_notifications_specific_contact"
+msgstr ""
+"Mozilla mempunyai hak untuk menghubungi anda secara pribadi mengenai hal "
+"tertentu yang bersangkutan dengan pengaya anda yang diletakkan di sini."
+
+#: controllers/users_controller.php:543
+msgid "user_profile_edit_error"
+msgstr ""
+"Ada kesalahan pada perubahan yang dilakukan sebelumnya. Mohon dikoreksi dan "
+"simpan ulang."
+
+#: controllers/users_controller.php:540
+msgid "user_profile_saved"
+msgstr "Profil diperbarui."
+
+#: views/users/pwreset.thtml:65
+#, php-format
+msgid "user_pwreset_for_email"
+msgstr "Reset kata sandi untuk %s"
+
+#: controllers/users_controller.php:226
+msgid "user_pwreset_header"
+msgstr "Reset Kata Sandi"
+
+#: views/users/login.thtml:103
+msgid "user_pwreset_link"
+msgstr "Lupa kata sandi?"
+
+#: controllers/users_controller.php:248
+msgid "user_pwreset_link_sent"
+msgstr "Tautan untuk mereset kata sandi telah dikirimkan ke alamat email anda."
+
+#: controllers/users_controller.php:304
+msgid "user_pwreset_okay"
+msgstr "Kata sandi sukses direset."
+
+#: views/users/pwreset.thtml:82
+msgid "user_pwreset_submit_changepw"
+msgstr "Simpan perubahan kata sandi"
+
+#: views/users/pwreset.thtml:57
+msgid "user_pwreset_submit_sendlink"
+msgstr "Kirim tautan untuk mereset kata sandi"
+
+#: views/users/register_complete.thtml:51
+#, php-format
+msgid "user_register_amo_link"
+msgstr "Pengaya %s"
+
+#. %1 is the user's email address, %2 is the current app
+#: views/users/activatefirst.thtml:49
+#, php-format
+msgid "user_register_click_confirm_link"
+msgstr ""
+"Sebuah tautan untuk akitvasi akun pengguna telah dikirimkan ke alamat email "
+"anda di %1$s. Anda harus mengklik tautan tersebut sebelum bisa log-masuk ke "
+"Pengaya %2$s."
+
+#. %1 is the user's email address
+#: views/users/register_complete.thtml:49
+#, php-format
+msgid "user_register_confirm_email_sent"
+msgstr ""
+"Email telah dikirim ke alamat email di %1$s untuk mengkonfirmasi akun anda. "
+"Sebelum anda bisa log-masuk, anda harus mengaktifkan akun dengan mengklik "
+"tautan yang ada pada email konfirmasi tersebut."
+
+#: views/users/activatefirst.thtml:51
+msgid "user_register_confirmation_link_text"
+msgstr "kirim ulang email konfirmasi"
+
+#: views/users/register_complete.thtml:47
+msgid "user_register_congratulations"
+msgstr "Selamat! Akun anda telah sukses dibuat."
+
+#: views/users/register.thtml:50
+#, fuzzy
+msgid "user_register_details"
+msgstr ""
+"<p>Registration on AMO is <strong>not required</strong> if you simply want "
+"to download and install public add-ons.</p><p>You only need to register if:</"
+"p><ul><li>You want to submit reviews for add-ons</li><li>You are an add-on "
+"developer and want to upload your add-on for hosting on AMO</li></ul><p>Upon "
+"successful registration, you will be sent a confirmation email to the "
+"address you provided. Please follow the instructions there to confirm your "
+"account.</p><p>If you like, you can read our <a href='%1$s' title='Legal "
+"Notices'>Legal Notices</a> and <a href='%2$s' title='Privacy Policy'>Privacy "
+"Policy</a>.</p>"
+
+#. %1 is the link to the "resend confirmation code" page
+#: views/users/activatefirst.thtml:51
+#, php-format
+msgid "user_register_resend_confirmation_link"
+msgstr ""
+"Jika anda tidak menerima email konfirmasi, pastikan layanan email anda tidak "
+"menandainya sebagai \"email sampah (junk)\" atau \"spam\". Jika masih tidak "
+"ada anda bisa meminta %1$s untuk mengirim ulang ke alamat email di atas."
+
+#. %1 is the link to the Mozilla Add-ons front page
+#: views/users/register_complete.thtml:51
+#, php-format
+msgid "user_register_welcome"
+msgstr "Terima kasih telah mendaftar dan selamat datang di %1$s!"
+
+#: views/users/register.thtml:49
+#, fuzzy
+msgid "user_register_welcome_header"
+msgstr "Welcome to addons.mozilla.org (AMO)!"
+
+#: views/users/register.thtml:81 views/users/edit.thtml:106
+msgid "user_required_firstlast_or_nickname"
+msgstr ""
+"Salah satu dari: nama depan, atau nama belakang, atau nama alias (nick) "
+"diwajibkan untuk diisi."
+
+#: views/users/edit.thtml:94 views/users/edit.thtml:142
+#, fuzzy
+msgid "user_tab_collections"
+msgstr "Collections"
+
+#: views/users/edit.thtml:95 views/users/edit.thtml:154
+msgid "user_tab_notifications"
+msgstr "Peringatan"
+
+#: views/users/edit.thtml:93 views/users/edit.thtml:101
+msgid "user_tab_profile"
+msgstr "Profil Pengguna"
+
+#: controllers/users_controller.php:209
+msgid "user_verified_okay"
+msgstr "Verifikasi sukses!"
+
+#: controllers/users_controller.php:723
+msgid "users_delete_pagetitle"
+msgstr "Hapus Akun Pengguna"
+
+#: controllers/users_controller.php:414
+msgid "users_edit_pagetitle"
+msgstr "Pengubahan Akun Pengguna"
+
+#: views/users/info.thtml:71
+#, fuzzy
+msgid "users_info_aboutme"
+msgstr "About Me"
+
+#: views/users/info.thtml:96
+#, php-format
+msgid "users_info_addons_by_user"
+msgstr "Pengaya oleh %1$s"
+
+#: views/users/info.thtml:51
+msgid "users_info_author_name"
+msgstr "Nama"
+
+#: views/users/info.thtml:48
+msgid "users_info_author_profile"
+msgstr "Profil Pengguna"
+
+#. %s is the user name
+#: views/users/info.thtml:137
+#, fuzzy
+msgid "users_info_collections_by_user"
+msgstr "Collections by %s"
+
+#: views/users/info.thtml:66
+msgid "users_info_email"
+msgstr "Alamat email"
+
+#: views/users/info.thtml:155
+#, fuzzy
+msgid "users_info_fav_collections_by_user"
+msgstr "Favorite Collections"
+
+#: views/users/info.thtml:61
+msgid "users_info_homepage"
+msgstr "Beranda"
+
+#: views/users/info.thtml:56
+msgid "users_info_nickname"
+msgstr "Nama alias (nick)"
+
+#: controllers/users_controller.php:707
+#, php-format
+msgid "users_info_pagetitle"
+msgstr "Keterangan Pengguna %1$s"
+
+#. %1 is the user's name
+#: views/users/info.thtml:116
+msgid "users_info_reviews_by_user"
+msgstr "Tinjauan oleh %s"
+
+#: controllers/users_controller.php:330 controllers/users_controller.php:332
+msgid "users_login_pagetitle"
+msgstr "Log-masuk Pengguna"
+
+#. %1 is the link to the sandbox/policy explanation page
+#. This message is for a specific add-on not found
+#: views/users/login.thtml:53
+#, php-format
+msgid "users_login_sandbox_display_warning"
+msgstr ""
+"Pengaya yang anda cari masih berada dalam sandbox. Jika anda mempunyai akun "
+"di situs Pengaya Mozilla, mohon log-masuk terlebih dulu atau <a href=\"%1$s"
+"\">baca lebih lanjut tentang sandbox.</a>"
+
+#. %1 is the link to the sandbox/policy explanation page
+#. This message is for any given sandbox-related page not found
+#: views/users/login.thtml:56
+#, php-format
+msgid "users_login_sandbox_page_warning"
+msgstr ""
+"Halaman yang anda buka merupakan bagian dari sandbox. Jika anda mempunyai "
+"akun di situs Pengaya Mozilla, mohon log-masuk terlebih dulu atau <a href=\"%"
+"1$s\">baca lebih lanjut tentang sandbox.</a>"
+
+#: controllers/users_controller.php:223 controllers/users_controller.php:225
+msgid "users_pwreset_pagetitle"
+msgstr "Reset Kata Sandi Pengguna"
+
+#: controllers/users_controller.php:90 controllers/users_controller.php:92
+msgid "users_register_pagetitle"
+msgstr "Pendaftaran Pengguna Baru"
+
+#. %1$s is an addon name, like <a>Firebug</a>
+#. %2$s is a version number, like <a>1.2</a>
+#: views/versions/license.thtml:52
+#, fuzzy
+msgid "versions_license_header_source"
+msgstr "Source code license for %1$s %2$s"
+
+#: views/addons/category_landing.thtml:147
+#, fuzzy
+msgid "view_recently_added"
+msgstr "View all recently added"
+
+#: views/addons/category_landing.thtml:161
+#, fuzzy
+msgid "view_top_downloads"
+msgstr "View all top downloads"
+
+#: views/addons/category_landing.thtml:175
+#, fuzzy
+msgid "view_top_rated"
+msgstr "View all top rated"
+
+#~ msgid "addon_slider_tooltip_next"
+#~ msgstr "Pengaya Berikutnya"
+
+#~ msgid "addon_slider_tooltip_previous"
+#~ msgstr "Pengaya Sebelumnya"
+
+#~ msgid "addon_versions_getlatesttext"
+#~ msgstr "Versi terakhir kompatibel dengan"
+
+#~ msgid "addons_display_version_history"
+#~ msgstr "Riwayat Versi Lengkap"
+
+#~ msgid "addons_home_newest_header"
+#~ msgstr "Terbaru:"
+
+#~ msgid "addons_home_popular_header"
+#~ msgstr "Terpopuler:"
+
+#~ msgid "addons_home_recommended_header"
+#~ msgstr "Rekomendasi Kami:"
+
+#~ msgid "addons_home_updated_header"
+#~ msgstr "Baru Dimutakhirkan:"
+
+#~ msgid "addons_home_view_all"
+#~ msgstr "Tampilkan semua"
+
+#~ msgid "category_extra_allrecommended"
+#~ msgstr "Tampilkan Semua Rekomendasi Pengaya"
+
+#~ msgid "category_extra_highestrated"
+#~ msgstr "Peringkat Tertinggi"
+
+#~ msgid "category_extra_lastupdated"
+#~ msgstr "Paling Terakhir Diperbarui"
+
+#~ msgid "category_extra_mostpopular"
+#~ msgstr "Paling Populer"
+
+#, fuzzy
+#~ msgid "collections_detail_js_loading"
+#~ msgstr "Loading"
+
+#, fuzzy
+#~ msgid "collections_detail_more_info"
+#~ msgstr "Show More Info"
+
+#~ msgid "devcp_additem_firefox_notice"
+#~ msgstr ""
+#~ "Versi pengaya anda tidak menyebutkan kompatibilitas dengan Firefox %1$s. "
+#~ "Mozilla berharap versi terbaru Firefox akan dirilis secepatnya. Oleh "
+#~ "karena itu, mohon pengaya anda diuji pada versi baru Firefox dan perbarui "
+#~ "informasi kompatibilitas yang berkaitan. Anda dapat membaca tentang hal "
+#~ "tersebut <a href=\"%2$s\">di sini</a>. Tulisan ini hanya bersifat "
+#~ "peringatan dan anda tetap dapat melanjutkan proses pengajuan versi ini "
+#~ "kepada addons.mozilla.org."
+
+#~ msgid "devcp_addon_disabled_successfully"
+#~ msgstr "Pengaya sukses dimatikan"
+
+#~ msgid "devcp_addon_edit_pagetitle"
+#~ msgstr "Ubah Pengaya"
+
+#~ msgid "devcp_addon_enabled_successfully"
+#~ msgstr "Pengaya sukses diaktifkan"
+
+#~ msgid "devcp_addon_field_description_displaytitle"
+#~ msgstr "Deskripsi Pengaya"
+
+#~ msgid "devcp_addon_field_eula_displaytitle"
+#~ msgstr "EULA"
+
+#~ msgid "devcp_addon_field_homepage_displaytitle"
+#~ msgstr "Beranda Pengaya"
+
+#~ msgid "devcp_addon_field_name_displaytitle"
+#~ msgstr "Nama Pengaya"
+
+#~ msgid "devcp_addon_field_privacy_displaytitle"
+#~ msgstr "Kebijakan Privasi"
+
+#~ msgid "devcp_addon_field_summary_displaytitle"
+#~ msgstr "Ringkasan Pengaya"
+
+#~ msgid "devcp_addon_field_supportemail_displaytitle"
+#~ msgstr "Email Layanan Dukungan"
+
+#~ msgid "devcp_addon_field_supporturl_displaytitle"
+#~ msgstr "URL Layanan Dukungan"
+
+#~ msgid "devcp_addon_field_versionnotes_displaytitle"
+#~ msgstr "Catatan Versi"
+
+#~ msgid "devcp_addon_nominate_pagetitle"
+#~ msgstr "Calonkan Pengaya"
+
+#~ msgid "devcp_addon_nominated_successfully"
+#~ msgstr "Pengaya sukses dicalonkan!"
+
+#, fuzzy
+#~ msgid "devcp_addon_status_criteria_review"
+#~ msgstr "Several user reviews of the add-on (may be external reviews)."
+
+#~ msgid "devcp_addon_submission_makechanges"
+#~ msgstr ""
+#~ "Kunjungi halaman %1$s untuk membuat perubahan pada pengaya yang anda "
+#~ "ajukan, atau %2$s untuk kembali ke Perangkat Pengembang."
+
+#~ msgid "devcp_addon_submission_makechanges_devcp_link"
+#~ msgstr "klik di sini"
+
+#~ msgid "devcp_addon_submission_makechanges_link"
+#~ msgstr "Ubah Pengaya"
+
+#~ msgid "devcp_addon_submission_pending"
+#~ msgstr ""
+#~ "Versi ini telah ditempatkan di sandbox untuk menunggu proses peninjauan "
+#~ "dari para penguji sandbox dan seorang penyunting dari pihak Mozilla. Jika "
+#~ "sudah ada aksi yang dilakukan maka anda akan diberitahu melalui email."
+
+#~ msgid "devcp_addon_submission_sandbox_readmore"
+#~ msgstr "Anda dapat membaca tentang Sistem Peninjauan Sandbox %s."
+
+#~ msgid "devcp_addon_submission_sandbox_readmore_link"
+#~ msgstr "di sini"
+
+#~ msgid "devcp_addon_submission_sandboxed"
+#~ msgstr ""
+#~ "Versi ini telah ditempatkan pada sandbox untuk digunakan oleh pengguna "
+#~ "berpengalaman. Agar dapat tampil pada situs publik, anda harus %s pengaya "
+#~ "anda dan melewati proses peninjauan."
+
+#~ msgid "devcp_addon_submission_sandboxed_nominate_link"
+#~ msgstr "mencalonkan"
+
+#~ msgid "devcp_addon_submission_success"
+#~ msgstr "Pengajuan pengaya anda sukses."
+
+#~ msgid "devcp_addon_submission_trusted_public"
+#~ msgstr ""
+#~ "Oleh karena pengaya ini terpercaya, versi ini secara otomatis disetujui "
+#~ "untuk tampil pada situs publik."
+
+#~ msgid "devcp_addon_submit_pagetitle"
+#~ msgstr "Ajukan Pengaya"
+
+#~ msgid "devcp_addon_updated_successfully"
+#~ msgstr "Pengaya sukses diperbarui"
+
+#~ msgid "devcp_addon_upload_preview"
+#~ msgstr "Mungkin anda ingin untuk %s agar pengaya anda lebih menarik."
+
+#~ msgid "devcp_addon_upload_preview_link"
+#~ msgstr "mengunggah pratinjau"
+
+#~ msgid "devcp_author_lookup_none_found"
+#~ msgstr "Tidak ada penyusun ditemukan [%s]"
+
+#~ msgid "devcp_author_lookup_remove"
+#~ msgstr "Hapus"
+
+#~ msgid "devcp_button_cancel"
+#~ msgstr "Batal"
+
+#~ msgid "devcp_button_cancel_confirm"
+#~ msgstr "Yakin akan membatalkan pengajuan?"
+
+#~ msgid "devcp_button_next"
+#~ msgstr "Lanjut"
+
+#~ msgid "devcp_change_addontype"
+#~ msgstr "Ganti jenis pengaya:"
+
+#~ msgid "devcp_comments_updated"
+#~ msgstr "Komentar Pengembang diperbarui."
+
+#~ msgid "devcp_details_addpreview_link"
+#~ msgstr "Tambah Pratinjau"
+
+#~ msgid "devcp_details_author"
+#~ msgstr "Penyusun"
+
+#~ msgid "devcp_details_authors"
+#~ msgstr "Penyusun"
+
+#~ msgid "devcp_details_authors_none"
+#~ msgstr "Tidak ada"
+
+#~ msgid "devcp_details_categories"
+#~ msgstr "Kategori"
+
+#~ msgid "devcp_details_category"
+#~ msgstr "Kategori"
+
+#~ msgid "devcp_details_description"
+#~ msgstr "Deskripsi"
+
+#~ msgid "devcp_details_disabled"
+#~ msgstr "Dimatikan"
+
+#~ msgid "devcp_details_guid"
+#~ msgstr "GUID"
+
+#~ msgid "devcp_details_header_details"
+#~ msgstr "Detil"
+
+#~ msgid "devcp_details_header_devcomments"
+#~ msgstr "Komentar Pengembang"
+
+#~ msgid "devcp_details_header_previews"
+#~ msgstr "Pratinjau"
+
+#~ msgid "devcp_details_header_versions"
+#~ msgstr "Versi"
+
+#~ msgid "devcp_details_homepage"
+#~ msgstr "Beranda"
+
+#~ msgid "devcp_details_homepage_none"
+#~ msgstr "Tidak Ada"
+
+#~ msgid "devcp_details_preview_nocaption"
+#~ msgstr "Tanpa Judul"
+
+#~ msgid "devcp_details_previews_nonefound"
+#~ msgstr "Tidak ada pratinjau ditemukan."
+
+#~ msgid "devcp_details_submit_update"
+#~ msgstr "Perbarui"
+
+#~ msgid "devcp_details_supportemail"
+#~ msgstr "Email Layanan Dukungan"
+
+#~ msgid "devcp_details_supportemail_none"
+#~ msgstr "Tidak ada email layanan dukungan yang disediakan pengembang."
+
+#~ msgid "devcp_details_supporturl"
+#~ msgstr "URL Layanan Dukungan"
+
+#~ msgid "devcp_details_supporturl_none"
+#~ msgstr "Tidak ada URL layanan dukungan yang disediakan pengembang."
+
+#~ msgid "devcp_details_trusted"
+#~ msgstr "Terpercaya"
+
+#~ msgid "devcp_details_versions_none_found"
+#~ msgstr "Tidak ada versi ditemukan."
+
+#~ msgid "devcp_disable_cancel"
+#~ msgstr "Batal dan kembali"
+
+#~ msgid "devcp_disable_disable_button"
+#~ msgstr "Ya, matikan"
+
+#~ msgid "devcp_disable_disable_confirm"
+#~ msgstr "Yakin akan mematikan pengaya ini?"
+
+#~ msgid "devcp_disable_disable_description"
+#~ msgstr ""
+#~ "Mematikan pengaya ini akan berakibat pengaya ini akan disembunyikan dari "
+#~ "pencarian dan daftar pengaya. Pengaya juga tidak akan dapat diunduh dari "
+#~ "situs dan tidak akan tersedia pada pemutakhiran versi dari aplikasi. "
+#~ "Secara singkat, pengaya akan 'dihapus'. Akan tetapi anda dapat kembali "
+#~ "mengunjungi situs sini dan mengaktifkannya lagi."
+
+#~ msgid "devcp_disable_disable_title"
+#~ msgstr "Matikan %s"
+
+#~ msgid "devcp_disable_enable_button"
+#~ msgstr "Ya, aktifkan"
+
+#~ msgid "devcp_disable_enable_confirm"
+#~ msgstr "Yakin akan mengaktifkan pengaya ini?"
+
+#~ msgid "devcp_disable_enable_description"
+#~ msgstr ""
+#~ "Mengaktifkan pengaya ini akan berakibat pengaya ini akan segera tampil "
+#~ "pada pencarian dan daftar pengaya. Pengaya juga akan dapat diunduh dari "
+#~ "situs dan juga dari pemeriksaan versi baru dari aplikasi."
+
+#~ msgid "devcp_disable_enable_title"
+#~ msgstr "Aktifkan %s"
+
+#~ msgid "devcp_edit_author_add"
+#~ msgstr "Tambah Penyusun"
+
+#~ msgid "devcp_edit_author_email"
+#~ msgstr "Alamat Email Penyusun"
+
+#~ msgid "devcp_edit_author_remove"
+#~ msgstr "Hapus"
+
+#~ msgid "devcp_edit_error_categories_unavailable"
+#~ msgstr "Tidak ada kategori yang cocok dengan jenis pengaya ini."
+
+#, fuzzy
+#~ msgid "devcp_edit_file_error_incomplete"
+#~ msgstr "Incomplete transfer"
+
+#, fuzzy
+#~ msgid "devcp_edit_file_error_no"
+#~ msgstr "No file uploaded"
+
+#, fuzzy
+#~ msgid "devcp_edit_file_error_size"
+#~ msgstr "Exceeds maximum upload size"
+
+#~ msgid "devcp_edit_header_authors"
+#~ msgstr "Penyusun"
+
+#~ msgid "devcp_edit_icon_add_link"
+#~ msgstr "Tambah Ikon"
+
+#~ msgid "devcp_edit_icon_change_link"
+#~ msgstr "Ganti Ikon"
+
+#~ msgid "devcp_edit_label_allow_viewsource"
+#~ msgstr "Izinkan pengguna untuk melihat kode sumber secara online"
+
+#~ msgid "devcp_edit_label_categories"
+#~ msgstr "Kategori"
+
+#~ msgid "devcp_edit_label_defaultlocale"
+#~ msgstr "Bahasa (Locale) Default"
+
+#~ msgid "devcp_edit_label_icon_delete"
+#~ msgstr "Hanya bersihkan ikon yang ada"
+
+#~ msgid "devcp_edit_label_icon_new"
+#~ msgstr "Berkas Ikon Baru"
+
+#~ msgid "devcp_edit_label_info"
+#~ msgstr "Ikon"
+
+#~ msgid "devcp_edit_locale_disambiguation_explanation"
+#~ msgstr "keterangan tambahan singkat (contohnya nama dialek bahasa)"
+
+#~ msgid "devcp_edit_submit_update"
+#~ msgstr "Perbarui"
+
+#~ msgid "devcp_edit_target_locale_explanation"
+#~ msgstr ""
+#~ "<a href=\"http://wiki.mozilla.org/L10n:Simple_locale_names\"><em>simple "
+#~ "locale name</em></a>, contohnya 'en-US' atau 'id'"
+
+#~ msgid "devcp_editversion_checkedfiles_delete"
+#~ msgstr "Berkas yang ditandai akan dihapus."
+
+#~ msgid "devcp_editversion_filename_size"
+#~ msgstr "%1$s (%2$s)"
+
+#~ msgid "devcp_editversion_label_files"
+#~ msgstr "Berkas"
+
+#~ msgid "devcp_editversion_label_targetapps"
+#~ msgstr "Aplikasi Target"
+
+#~ msgid "devcp_editversion_nofiles"
+#~ msgstr "Tidak ada berkas."
+
+#~ msgid "devcp_editversion_reviewernotes"
+#~ msgstr "Catatan untuk Peninjau"
+
+#~ msgid "devcp_editversion_submit_update"
+#~ msgstr "Perbarui"
+
+#~ msgid "devcp_error_addon_field_summary_toolong"
+#~ msgstr ""
+#~ "Jumlah karakter untuk ringkasan dibatasi sebanyak 250 karakter.\n"
+#~ "(Anda memasukkan %s)"
+
+#~ msgid "devcp_error_addonname_not_unique"
+#~ msgstr ""
+#~ "Nama pengaya anda telah ada pada basis data. Pastikan bahwa: <br /"
+#~ "><li>GUID pengaya sesuai. Kesalahan umum yang sering terjadi adalah "
+#~ "karena GUID tidak cocok.</li><li>anda tidak mempunyai entri ganda pada "
+#~ "basis data. Jika ada, anda seharusnya memperbarui entri tersebut atau "
+#~ "hapus entri tersebut dan coba lagi.</li>"
+
+#~ msgid "devcp_error_describe_changes"
+#~ msgstr "Ceritakan perubahan yang terjadi pada versi baru pengaya ini."
+
+#~ msgid "devcp_error_file_guids_dont_match"
+#~ msgstr "Tidak semua GUID berkas cocok"
+
+#~ msgid "devcp_error_identical_version_exists"
+#~ msgstr "Versi yang sama (%s) telah ada untuk pengaya dan platform."
+
+#~ msgid "devcp_error_nominate_message"
+#~ msgstr "Anda harus mengisi informasi yang diminta untuk proses pencalonan."
+
+#~ msgid "devcp_error_nominate_no_prerelease"
+#~ msgstr ""
+#~ "Anda tidak dapat mencalonkan pengaya yang sedang dalam status prarilis."
+
+#~ msgid "devcp_error_nominate_sandbox_only"
+#~ msgstr "Anda hanya dapat mencalonkan pengaya yang berada pada sandbox."
+
+#~ msgid "devcp_error_saving"
+#~ msgstr "Kesalahan saat menyimpan data anda."
+
+#~ msgid "devcp_error_update_access_denied"
+#~ msgstr "Anda tidak diizinkan untuk memperbarui pengaya ini."
+
+#~ msgid "devcp_file_addanother"
+#~ msgstr "Tambah Berkas untuk Platform Lain"
+
+#~ msgid "devcp_form_author_add"
+#~ msgstr "Tambah Penyusun"
+
+#~ msgid "devcp_form_author_remove"
+#~ msgstr "Hapus"
+
+#~ msgid "devcp_form_categories_nextstep"
+#~ msgstr "Kategori pengaya anda akan tersedia pada langkah berikutnya."
+
+#~ msgid "devcp_form_error_categories_unavailable"
+#~ msgstr ""
+#~ "Tidak ada kategori yang cocok yang tersedia untuk jenis pengaya ini."
+
+#~ msgid "devcp_form_error_description_notempty"
+#~ msgstr "Isi deskripsi pengaya anda."
+
+#~ msgid "devcp_form_error_name_required"
+#~ msgstr "Isi nama pengaya anda."
+
+#~ msgid "devcp_form_error_select_addontype"
+#~ msgstr "Pilih jenis pengaya yang anda ajukan."
+
+#~ msgid "devcp_form_error_summary_notempty"
+#~ msgstr "Isi ringkasan tentang pengaya anda."
+
+#~ msgid "devcp_form_label_addonfile"
+#~ msgstr "Berkas Pengaya"
+
+#~ msgid "devcp_form_label_addonfile2"
+#~ msgstr "Berkas Pengaya 2"
+
+#~ msgid "devcp_form_label_addonfile3"
+#~ msgstr "Berkas Pengaya 3"
+
+#~ msgid "devcp_form_label_addontype"
+#~ msgstr "Jenis Pengaya"
+
+#~ msgid "devcp_form_label_allow_viewsource"
+#~ msgstr "Izinkan pengguna untuk membaca kode sumber secara online"
+
+#~ msgid "devcp_form_label_author_email"
+#~ msgstr "Alamat Email Penyusun"
+
+#~ msgid "devcp_form_label_authors"
+#~ msgstr "Penyusun"
+
+#~ msgid "devcp_form_label_categories"
+#~ msgstr "Kategori"
+
+#~ msgid "devcp_form_label_defaultlocale"
+#~ msgstr "Bahasa (Locale) Default"
+
+#~ msgid "devcp_form_label_description"
+#~ msgstr "Deskripsi"
+
+#~ msgid "devcp_form_label_eula"
+#~ msgstr "Perjanjian Lisensi End-User (End User License Agreement-EULA)"
+
+#~ msgid "devcp_form_label_externalsoftware"
+#~ msgstr "Pengaya ini membutuhkan perangkat lunak eksternal"
+
+#~ msgid "devcp_form_label_files"
+#~ msgstr "Berkas"
+
+#~ msgid "devcp_form_label_homepage"
+#~ msgstr "Beranda"
+
+#~ msgid "devcp_form_label_iconfile"
+#~ msgstr "Berkas Ikon"
+
+#~ msgid "devcp_form_label_name"
+#~ msgstr "Nama"
+
+#~ msgid "devcp_form_label_platforms"
+#~ msgstr "Platform yang Didukung"
+
+#~ msgid "devcp_form_label_prerelease"
+#~ msgstr "Masih prarilis"
+
+#~ msgid "devcp_form_label_privacy"
+#~ msgstr "Kebijakan Privasi"
+
+#~ msgid "devcp_form_label_sitespecific"
+#~ msgstr "Pengaya ini untuk hanya bekerja situs tertentu"
+
+#~ msgid "devcp_form_label_summary"
+#~ msgstr "Ringkasan"
+
+#~ msgid "devcp_form_label_supportemail"
+#~ msgstr "Email Layanan Dukungan"
+
+#~ msgid "devcp_form_label_supporturl"
+#~ msgstr "URL Layanan Dukungan"
+
+#~ msgid "devcp_form_label_target_applications"
+#~ msgstr "Aplikasi Target"
+
+#~ msgid "devcp_form_label_version"
+#~ msgstr "Versi"
+
+#~ msgid "devcp_form_label_versionnotes"
+#~ msgstr "Catatan Versi"
+
+#~ msgid "devcp_form_no_target_apps"
+#~ msgstr "Tidak Ada"
+
+#~ msgid "devcp_form_reviewernotes"
+#~ msgstr "Catatan untuk Peninjau"
+
+#~ msgid "devcp_form_trustedaddon_destination"
+#~ msgstr ""
+#~ "Oleh karena pengaya anda terpercaya, silakan pilih ke mana versi ini akan "
+#~ "ditempatkan:"
+
+#~ msgid "devcp_form_trustedaddon_destination_public"
+#~ msgstr "Publik"
+
+#~ msgid "devcp_form_trustedaddon_destination_sandbox"
+#~ msgstr "Sandbox"
+
+#~ msgid "devcp_header_developer_agreement"
+#~ msgstr "Perjanjian Pengembang"
+
+#~ msgid "devcp_header_step1"
+#~ msgstr "Langkah Pertama"
+
+#~ msgid "devcp_header_step1_upload"
+#~ msgstr "Unggah Berkas"
+
+#~ msgid "devcp_header_step2"
+#~ msgstr "Langkah ke-2"
+
+#~ msgid "devcp_header_step2_addondetails"
+#~ msgstr "Detil Pengaya"
+
+#~ msgid "devcp_header_step3"
+#~ msgstr "Langkah ke-3"
+
+#~ msgid "devcp_header_step3_versiondetails"
+#~ msgstr "Detil Versi"
+
+#~ msgid "devcp_header_step4"
+#~ msgstr "Langkah ke-4"
+
+#~ msgid "devcp_header_step4_localization"
+#~ msgstr "Bahasa (Localization)"
+
+#~ msgid "devcp_header_step5"
+#~ msgstr "Langkah ke-5"
+
+#~ msgid "devcp_header_step5_success"
+#~ msgstr "Sukses"
+
+#~ msgid "devcp_index_header_myaddons"
+#~ msgstr "Pengayaku"
+
+#~ msgid "devcp_nominate_link_returnto_details"
+#~ msgstr "Kembali ke detil pengaya"
+
+#~ msgid "devcp_notice_autodetected_addontype"
+#~ msgstr "Deteksi otomatis jenis pengaya: %s."
+
+#~ msgid "devcp_notice_different_defaultlocale"
+#~ msgstr ""
+#~ "Bahasa (locale) default pengaya ini (%1$s [%2$s]) berbeda dengan bahasa "
+#~ "yang anda pilih (%3$s [%4$s]). Isian berikut harus dilengkapi dalam %1$s."
+
+#~ msgid "devcp_question_addontype_incorrect"
+#~ msgstr "Salah?"
+
+#~ msgid "devcp_question_delete_file"
+#~ msgstr "Yakin akan menghapus berkas ini?"
+
+#~ msgid "devcp_skip_reviewing_addon_info"
+#~ msgstr "Lewati pemutakhiran informasi pengaya yang ada"
+
+#~ msgid "devcp_submissions_disabled"
+#~ msgstr "Fitur Pengajuan Pengaya sedang dimatikan. Mohon kembali lagi nanti."
+
+#~ msgid "devcp_submit_accept_dev_agreement"
+#~ msgstr "Saya Setuju"
+
+#~ msgid "devcp_submit_decline_dev_agreement"
+#~ msgstr "Saya Tidak Setuju"
+
+#~ msgid "devcp_summary_admin_disabled"
+#~ msgstr "Pengaya ini telah dimatikan oleh administrator."
+
+#~ msgid "devcp_summary_header_disabled"
+#~ msgstr "Dimatikan"
+
+#~ msgid "devcp_summary_header_trusted"
+#~ msgstr "Terpercaya"
+
+#~ msgid "devcp_summary_noaddons_submit_one"
+#~ msgstr "Anda tidak mempunyai pengaya. Klik %s untuk mengajukan."
+
+#~ msgid "devcp_summary_noaddons_submit_one_link"
+#~ msgstr "di sini"
+
+#~ msgid "devcp_theme_upload_preview"
+#~ msgstr "Pastikan untuk %s untuk tema anda."
+
+#~ msgid "devcp_theme_upload_preview_link"
+#~ msgstr "mengunggah pratinjau"
+
+#~ msgid "devcp_version_edit_pagetitle"
+#~ msgstr "Ubah Versi"
+
+#~ msgid "devcp_version_updated_successfully"
+#~ msgstr "Versi sukses diperbarui."
+
+#~ msgid "editors_submissiontype_new"
+#~ msgstr "Baru"
+
+#~ msgid "editors_submissiontype_updated"
+#~ msgstr "Diperbarui"
+
+#, fuzzy
+#~ msgid "editors_th_addon_age"
+#~ msgstr "Addon Age"
+
+#~ msgid "editors_th_addontypes"
+#~ msgstr "Jenis Pengaya"
+
+#~ msgid "editors_th_age"
+#~ msgstr "Umur"
+
+#~ msgid "editors_th_applications"
+#~ msgstr "Aplikasi"
+
+#~ msgid "editors_th_platforms"
+#~ msgstr "Platform"
+
+#~ msgid "editors_th_submissiontypes"
+#~ msgstr "Jenis Pengajuan"
+
+#~ msgid "error_notice"
+#~ msgstr "Perhatian"
+
+#~ msgid "forum_save"
+#~ msgstr "Simpan"
+
+#, fuzzy
+#~ msgid "home"
+#~ msgstr "home"
+
+#~ msgid "nav_category_plugins"
+#~ msgstr "Plugin"
+
+#~ msgid "page_title_experimental_addons"
+#~ msgstr "Pengaya Eksperimental"
+
+#~ msgid "pages_experimental_addons_backbutton"
+#~ msgstr "Kembali ke halaman sebelumnya"
+
+#~ msgid "pagination_page_number_title"
+#~ msgstr "Halaman %1$s dari %2$s"
+
+#~ msgid "search_matching_addons_number"
+#~ msgid_plural "search_matching_addons_number"
+#~ msgstr[0] "%s pengaya yang cocok"
+#~ msgstr[1] "%s pengaya yang cocok"
+
+#~ msgid "statistics_rss_icon_title"
+#~ msgstr "Feed RSS data ringkasan"
diff --git a/site/app/locale/id/images/sandbox-review.png b/site/app/locale/id/images/sandbox-review.png
new file mode 100644
index 0000000..320bf8b
--- /dev/null
+++ b/site/app/locale/id/images/sandbox-review.png
Binary files differ
diff --git a/site/app/locale/id/pages/compatibility_developer_tips.thtml b/site/app/locale/id/pages/compatibility_developer_tips.thtml
new file mode 100644
index 0000000..11aec76
--- /dev/null
+++ b/site/app/locale/id/pages/compatibility_developer_tips.thtml
@@ -0,0 +1,6 @@
+<ul class="tips">
+ <li>Informasi mengenai cara memutakhirkan pengaya anda untuk %s dapat ditemukan di <a href="https://developer.mozilla.org/En/Updating_extensions_for_%s">artikel Mozilla Developer Center</a>.</li>
+ <li>Informasi mengenai segala perubahan yang ada pada %s dapat ditemukan di <a href="https://developer.mozilla.org/en/%s_for_developers">artikel ini</a>.</li>
+ <li>Anda dapat berlangganan <a href="https://addons.mozilla.org/newsletter">newsletter about:addons</a> dan <a href="http://blog.mozilla.com/addons/">Blog Mozilla Add-ons</a> untuk perkembangan lainnya.</li>
+ <li>Jika pengaya anda tidak membutuhkan perubahan pada kode untuk menjadi kompatibel dan juga diletakkan pada situs Pengaya Mozilla, anda dapat mengubah maxVersion yang sesuai dan kompatibel secara online tanpa mengunggah berkas baru melalui <a href="%s">Perangkat Pengembang</a> atau dengan memperhatikan status di bawah ini.</li>
+</ul> \ No newline at end of file
diff --git a/site/app/locale/id/pages/compatibility_user_tips.thtml b/site/app/locale/id/pages/compatibility_user_tips.thtml
new file mode 100644
index 0000000..58710ee
--- /dev/null
+++ b/site/app/locale/id/pages/compatibility_user_tips.thtml
@@ -0,0 +1,6 @@
+<ul class="tips">
+ <li>Walaupun banyak dari pengaya yang telah mendukung perubahan yang ada pada %s tanpa perubahan pada kode program, beberapa pengaya lain masih membutuhkan penanganan lebih lanjut dari para penyusun pengaya agar proses pemutakhiran pengaya dapat berlangsung dengan baik. Mohon agar bersabar selama proses pengananan tersebut berlangsung karena banyak dari pengembang pengaya melakukan pekerjaan memelihara pengaya secara sukarela dan sebagai hobi.</li>
+ <li>Mozilla tidak menyarankan mematikan pengaturan pengecekan kompatibilitas karena dapat menyebabkan masalah yang serius ketika %s dimulai atau bahkan kehilangan data jika pengaya yang tidak kompatibel dengan versi baru %s dipaksa untuk digunakan.</li>
+ <li>Jika extensi yang Anda coba gunakan tidak kompatibel dengan %s pada saat diluncurkan, Anda dapat mengunjungi situs web ekstensi atau situs web penyusun untuk mengikuti perkembangan berita mengenai versi terbarunya.</li>
+ <li>Anda juga dapat menggunakan pengaya lain yang memiliki fungsi serupa yang telah mendukung %s pada situs web <a href="%s">Pengaya %s</a>.</li>
+</ul> \ No newline at end of file
diff --git a/site/app/locale/id/pages/error404.thtml b/site/app/locale/id/pages/error404.thtml
new file mode 100644
index 0000000..5621658
--- /dev/null
+++ b/site/app/locale/id/pages/error404.thtml
@@ -0,0 +1,16 @@
+<h1>Kami mohon maaf karena anda tidak dapat menemukan apa yang ingin dicari.</h1>
+
+<p>Halaman atau berkas yang anda minta tidak ditemukan pada situs kami. Mungkin saja anda telah mengklik yang sudah sangat lama atau terjadi kesalahan penulisan alamat.</p>
+
+<ul>
+<li>Jika anda mengetikkan alamat untuk membuka situs ini, mohon periksa lagi tulisannya.</li>
+<li>Jika anda mengklik tautan ini dari situs lain, mohon beritahu kami lewat <a href="mailto:webmaster@mozilla.com" title="Page Not Found on Mozilla.com">webmaster@mozilla.com</a>. Ceritakan dari mana situs asal yang anda klik dan apa yang ingin dicari. Kami akan berusaha untuk memperbaikinya.</li>
+</ul>
+
+<p>Atau anda dapat langsung menuju halaman yang paling populer pada situs web kami.</p>
+
+<ul>
+<li>Anda tertarik pada <a href="%1$s">pengaya yang populer</a>?</li>
+<li>Anda ingin <a href="%2$s">mencari pengaya</a>? Anda juga dapat menuju <a href="%2$s">halaman pencarian</a> atau gunakan saja kotak pencarian di atas.</li>
+<li>Jika anda ingin memulai dari awal, langsung saja menuju <a href="%3$s">halaman awal pengaya</a>.</li>
+</ul>
diff --git a/site/app/locale/id/pages/nomination.thtml b/site/app/locale/id/pages/nomination.thtml
new file mode 100644
index 0000000..3d95f43
--- /dev/null
+++ b/site/app/locale/id/pages/nomination.thtml
@@ -0,0 +1,10 @@
+<p>Sebuah pengaya yang berada pada sandbox dapat mungkin dicalonkan untuk tampil pada situs publik dan tersedia untuk semua pengguna setelah melewati proses peninjauan oleh penyunting. Untuk hasil terbaik, mohon perhatikan hal-hal di bawah ini:</p>
+<ul>
+ <li>Gambar pratinjau diwajibkan untuk tema dan sangat disarankan untuk jenis pengaya lainnya.</li>
+ <li>Pengaya telah berada pada sandbox dalam jangka waktu yang cukup untuk mengumpulkan tinjauan dan saran dari pengguna. <b>Tinjauan diwajibkan untuk menjadikan pengaya bersifat publik.</b></li>
+ <li>Pengaya publik memiliki kualitas yang lebih tinggi dari kualitas pengaya yang berada pada sandbox dan memiliki kelebihan untuk menambah fungsi penjelajahan web.</li>
+ <li>Kriteria lengkap pencalonan tersedia di <a href="%s">Kebijakan Pengaya</a>.</li>
+</ul>
+<p>Jika pengaya anda telah memenuhi kriteria di atas, anda dapat mencalonkannya dengan melengkapi isian di bawah. Anda akan dihubungi lewat alamat email tentang status pencalonan pengaya anda.</p>
+
+<p>Untuk mencalonkan pengaya anda, mohon beri keterangan yang lengkap (termasuk apakah sudah bebas dari kesalahan dan peringatan) dan bagaimana pengaya tersebut dapat lebih berguna untuk penggunaan penjelajahan web secara umum. Anda juga dapat menyertakan tautan ke tinjauan eksternal lain tentang pengaya anda.</p>
diff --git a/site/app/locale/id/pages/policy.thtml b/site/app/locale/id/pages/policy.thtml
new file mode 100644
index 0000000..2ac2e26
--- /dev/null
+++ b/site/app/locale/id/pages/policy.thtml
@@ -0,0 +1,111 @@
+<h1>Kebijakan Pengaya</h1>
+
+<h2>Apakah sandbox itu?</h2>
+<p>Kunjungi %s.</p>
+
+<h2>Pengaya bagaimana yang berada di sandbox?</h2>
+<p>Sandbox adalah tempat semua pengaya diletakkan di AMO sebagai permulaan. Di sini selain merupakan tempat versi pengaya baru publik diletakkan, juga merupakan tempat pengaya yang masih belum dimasukkan ke situs publik. Pada saat pengaya baru atau pemutakhiran versi pengaya lama diajukan kepada AMO, semuanya akan ditempatkan di sandbox.</p>
+
+<p>Beberapa pengaya dan versi tertentu pengaya tersebut telah dibuat menjadi publik setelah melewati proses peninjauan. Jika proses peninjauan menunjukkan bahwa pengaya yang berkaitan siap dan memenuhi syarat tertentu untuk, pengaya tersebut akan ditampilkan pada situs publik. Pengaya lain masih akan tetap berada pada sandbox hingga waktu yang tidak ditentukan. Pengaya ini masih tetap tersedia bagi pengguna yang menjelajahi daftar sandbox dan mencoba bereksperimen menggunakan pengaya yang ada di sandbox.</p>
+
+<h2>Bagaimana cara pengaya dapat menjadi publik?</h2>
+
+<p>Pengaya akan ditinjau oleh pengguna AMO yang telah memilih untuk mencoba pengaya sandbox dan menguji coba pengaya tersebut. Tinjauan yang dihasilkan oleh pengguna ini akan menandakan apakah sebuah pengaya berfungsi dengan baik, dibuat dengan baik, dan baik untuk semua pengguna Firefox. Tinjauan ini juga mungkin akan ditambah dengan tinjauan dan pemeriksaan oleh tim AMO akan menentukan apakah pengaya yang berkaitan dapat dibuat menjadi publik, perlu diperbaiki, atau tidak cocok untuk dipromosikan pada situs AMO di luar sandbox.</p>
+
+<h2>Bagaimana cara pengaya saya dapat dipromosikan menjadi publik?</h2>
+
+<p>Jika anda yakin pengaya (dan juga perilaku anda!) telah memenuhi syarat untuk pengaya publik, anda dapat mencalonkannya dari Perangkat Pengembang.</p>
+
+<h2>Kriteria apa saja yang berkaitan dengan pengaya publik?</h2>
+
+<p>Pengaya yang telah dibuat publik pada AMO telah memenuhi syarat kualitas dan membantu pengguna dalam hal kenyamanan dan pengalaman yang lebih baik untuk penjelajahan web. Dalam mengambil keputusan apakah sebuah pengaya cocok untuk ditempatkan pada situs publik AMO, kami mencari hal-hal berikut:
+</p>
+
+<h3>Anda cepat tanggap?</h3>
+
+<p>Kami berharap penyusun yang mempromosikan pengaya miliknya kepada para pengguna Firefox untuk cepat tanggap terhadap laporan permasalahan, tanggap dalam berkomunikasi menggunakan informasi kontak yang telah diberikan, dan tanggap untuk memperbarui pengaya miliknya agar selaras dengan rilis Firefox dan perubahan pada kebijakan AMO. Hal ini tidak berarti anda harus menjawab setiap pertanyaan yang ada pada halaman diskusi atau anda harus memperbaiki setiap bug yang ada pada pengaya anda. Kami sangat berharap anda cepat tanggap terhadap permasalahan yang anda sesuai dengan tingkat permasalahan yang ada pada pertanyaan tersebut.</p>
+
+<h3>Apakah keterangan pengaya anda cukup jelas dan akurat??</h3>
+
+<p>Sangat penting bagi pengguna agar mereka mendapatkan apa yang mereka inginkan ketika mereka mencoba pengaya baru. Deskripsi yang anda berikan harus memiliki detil yang cukup tentang apa yang dikerjakan oleh pengaya, bagaimana cara pengguna mendapatkan kelebihan yang disediakan pengaya, dan apa yang dapat diharapkan oleh pengguna setelah memasang pengaya anda. Tautan pada dokumentasi eksternal mengenai instruksi lengkap juga cukup, tapi deskripsi pengaya juga harus menyertakan informasi dasar yang cukup agar pengguna yakin apakah mereka sudah mendapatkan fungsi yang mereka inginkan.</p>
+
+<p>Sangat penting juga agar anda selalu membuat catatan versi dengan baik sejalan dengan perbaikan dan perubahan yang terjadi pada pengaya anda. Sebaiknya pengguna dapat melihat hal yang baru dari pengaya yang telah mereka coba sebelumnya dan mengetahui perubahan apa yang diharapkan setelah memperbarui pengaya mereka serta efeknya pada penggunaan pengaya tersebut. (Saat ini pengguna tidak dapat melihat catatan perubahan apapun saat browser menanyakan untuk memperbarui pengaya mereka, tapi kami sedang memperbaiki hal ini. Jika anda mempunyai catatan versi yang baik, pengguna akan sangat diuntungkan sebelum dan sesudah perbaikan kami selesai.)</p>
+
+<h3>Apakah masalah privasi dan keamanan sudah dijelaskan dengan baik?</h3>
+
+<p>Aspek ini berkaitan erat dengan deskripsi yang jelas dan benar dan kami merasa sangat perlu untuk menjelaskannya dengan tuntas. Banyak pengaya yang bagus dan berguna berusaha mengubah data pengguna atau dapat menyebabkan kerusakan pada keamanan jika disalahgunakan. Pengaya ini masih dapat tampil pada situs publik AMO dengan syarat pengaya tersebut dapat menjelaskan dengan baik kepada pengguna semua resiko yang mungkin terjadi dan apa yang harus dikerjakan untuk melindungi diri-sendiri dari masalah tersebut.</p>
+
+<h3>Apakah pengaya telah diuji dengan baik dan apakah sudah bebas dari kerusakan yang serius?</h3>
+
+<p>Salah satu hal penting yang kami pertimbangkan dalam menjadikan pengaya dapat diakses publik adalah apakah tinjauan sandbox menandakan pengaya tersebut telah melalui pengujian yang cukup dan tidak memiliki masalah serius atau berdampak negatif terhadap browser. Jika pada proses peninjauan terdapat laporan masalah seperti performa yang jelek, crash, seringnya sebuah fungsi bermasalah atau pesan yang tidak berguna di konsol kesalahan, anda harus menerimanya dengan lapang dada dan mencalonkan kembali pengaya anda setelah anda mengatasinya sebaik mungkin. Kami tidak mengharapkan anda untuk mengoptimalkan pengaya anda dengan sempurna atau pengaya anda tidak mempunyai bug -- Firefox sendiri juga selalu mendapatkan perbaikan yang terus-menerus dalam permasalahan ini -- tapi kami benar-benar berharap anda berusaha semaksimal mungkin untuk memperkecil kemungkinan permasalahan dan menjelaskan sebaik-baiknya kepada pengguna yang mungkin akan terkejut ketika menemukan masalah tersebut.</p>
+
+<p>Jika pengaya anda telah diuji coba di luar proses sandbox AMO, contohnya oleh sekelompok orang dari tim anda atau tim kontrol kualitas pada lingkungan anda, anda harus menjelaskannya pada keterangan pencalonan anda. Ini akan sangat membantu kami dalam menentukan tingkat pengujian yang telah dilakukan dan dapat membantu pengaya anda untuk tampil pada situs.</p>
+
+<h3>Apakah pengaya dan penyusun pengaya memperlakukan pengguna dengan baik dan hormat?</h3>
+
+<p>Perangkat lunak anda tidak boleh mengganggu pengguna secara tidak perlu, mencoba menipu pengguna atau merahasiakan aktivitasnya dari pengguna. Pengguna (atau mungkin juga bukan pengguna) sangat ganas dalam berkomentar dan walaupun kami akan berusaha sebaik-baiknya untuk menyaring semua laporan mereka, kami sangat berharap penyusun dapat menghindari hal ini dari diri penyusun sendiri.</p>
+
+<h3>Apakah pengaya dapat berguna untuk sebagian besar pengguna Firefox?</h3>
+
+<p>Pengaya anda tidak perlu berusaha menjadi Greasemonkey atau FireBug yang berikutnya, tapi jika pengaya tersebut hanya berguna bagi sekelompok orang pada perusahaan anda atau sebagian kecil dari komunitas web, kami merasa bahwa pengaya tersebut kurang cocok untuk ditampilkan pada semua pengguna Firefox.</p>
+
+<p>Kami selalu berusaha mencari cara untuk memperbaiki susunan situs agar dapat mengakomodasi kebutuhan pengaya yang ditujukan untuk komunitas potensial yang lebih kecil. Untuk keperluan ini kami sangat terbantu jika anda memilih kategori yang tepat dan selalu memelihara metadata pengaya anda. Dengan bantuan ini kami dapat mencari cara untuk mengakomodasi kebutuhan tersebut di atas untuk melayani pengguna yang akan diuntungkan dengan fitur ini.</p>
+
+<p>Jika pengaya anda hanya menyediakan bookmark atau penunjuk sederhana ke situs anda, kemungkinan besar pengaya ini tidak cocok untuk tampil di situs publik. Seperti halnya dengan proyek Mozilla lainnya, kami menyukai aplikasi web dan layanan web baru. Akan tetapi pengaya Firefox seharusnya menyediakan penambahan pengalaman menjelajah web untuk para pengguna dan bukan untuk mempromosikan situs baru atau layanan baru dengan menggunakan daftar AMO. Jika deskripsi pengaya anda berkaitan erat dengan sebuah layanan dan tidak berorientasi pada penambahan/perbaikan pengalaman menjelajah web, kemungkinan besar anda berada pada jalur yang salah.</p>
+
+<h3>Apakah bebas dari masalah lisensi merk dagang atau hak cipta?</h3>
+
+<p>Walaupun anda tidak bermaksud untuk merugikan pemegang merk dagang atau pemilik karya yang dilindungi hak cipta, kami tidak dapat menyediakan tempat pengaya yang melanggar merk dagang dan hak cipta. Jika anda tidak memiliki izin penggunaan nama atau gambar merk dagang, mohon pengaya anda tidak diajukan kepada AMO. Jika pengaya anda mengandung kode sumber pihak lain yang dilindungi hak cipta dan tidak dilisensikan kepada anda untuk digunakan pada pengaya, mohon pengaya anda tidak diajukan kepada AMO. (Jika pemegang merk dagang atau hak cipta menyatakan keberatan tentang penggunaan merk dagang dan hak cipta tersebut, kami pasti akan diminta untuk menghapusnya oleh pengacara kami dan kami pasti akan menghapusnya sesuai dengan proses hukum yang berlaku. Proses ini sangat mahal dalam hitungan sumber daya proyek, termasuk waktu dan uang sehingga kamu meminta anda untuk tetap hormat dan tidak menyebabkan kesulitan semacam ini yang tidak perlu.)</p>
+
+<p>Jika anda tidak yakin tentang nama pengaya anda, atau yang terkandung pada nama pengaya anda, pengaya anda akan diblokir untuk tampil daftar apapun pada situs ini. Anda dapat bertanya kepada amo-editors@mozilla.org untuk petunjuk lebih lanjut. PENTING: Perhatikan bahwa grup ini tidak dapat menyediakan bantuan hukum walaupun kami berpendapat bahwa penggunaannya cukup dapat diterima. Kami akan kembali memikirkan keputusan ini berdasarkan saran pihak-pihak yang berkepentingan dan saran dari pengacara hukum.</p>
+
+<p>Mengenai penggunaan kode sumber pengaya dari pengaya lainnya, jika penyusun pengaya tersebut tidak secara jelas menjelaskan bahwa anda diizinkan untuk menggunakan kode sumber mereka untuk digunakan oleh pengaya anda -- seperti halnya dengan menempatkannya di bawah lisensi kode sumber terbuka (open source) -- anda harus tetap menganggap bahwa anda tidak memiliki izin untuk melakukan hal tersebut. Anda dapat menghubungi penyusun yang bersangkutan untuk berusaha mendapatkan izin tersebut. Kami tidak menyediakan hak khusus untuk hal tersebut hanya karena pengaya lain tersebut telah berada di situs AMO atau penyusun tidak membalas permintaan anda. (Dan sekali lagi, kami tidak menyediakan bantuan hukum, kami hanya mempunyai saran tentang hubungan pengaya anda dengan kebijakan situs ini.)</p>
+
+<p>Hal ini juga berlaku untuk penggunaan merk dagang Yayasan Mozilla, termasuk "Mozilla", "Firefox", dan "Thunderbird". Kebijakan Mozilla pada penggunaan merk dagang didesain untuk melindungi merk tersebut dari kebingungan dan mencegah peralihan kepemilikan merk dagang karena kurangnya perlindungan; mohon dihormati kebutuhan perlindungan ini dan bantu kami untuk melindungi aset yang paling berharga dari Mozilla Foundation.</p>
+
+<h2>Apa yang terjadi setelah saya mencalonkan sebuah pengaya?</h2>
+
+<p>Setelah pengaya anda dicalonkan, pengaya akan dievaluasi oleh sebuah tim Penyunting AMO sesuai dengan kriteria yang telah disebutkan di atas. Jika pengaya dianggap siap untuk tampil ke situs publik, pengaya akan dimasukkan ke situs publik setelah dievaluasi dan anda akan menerima pemberitahuan lewat email.</p>
+
+<p>Jika kami merasa bahwa pengaya yang bersangkutan tidak sesuai untuk ditampilkan pada situs publik AMO, anda akan menerima email pemberitahuan yang berisi tentang alasan yang berkaitan dan pengaya anda akan dihapus dari antrian. Jika anda merasa bahwa anda telah memenuhi semua syarat yang disampaikan pada email tersebut, pengaya anda akan dievaluasi ulang, dan anda memiliki hak penuh untuk melakukannya. Pencalonan yang berulang-ulang tanpa ada perbaikan yang berarti tidak akan dicoba lagi untuk dievaluasi. Oleh karena itu mohon dipertimbangkan penggunaan hak tersebut; anda mungkin hanya akan membuat kami lebih gusar dan capek.</p>
+
+<h2>Dapatkah saya mencalonkan pengaya dari penyusun lainnya?</h2>
+
+<p>Saat ini, kami meminta untuk mencalonkan pengaya hasil karya mereka sendiri untuk diterbitkan. Kami ingin memastikan bahwa penyusun merasa nyaman dengan perhatian yang bertambah dan perasaan bahwa status yang ada mencerminkan kualitas hasil kerja mereka. Jika anda berpendapat bahwa sebuah pengaya cukup bagus tetapi sang penyusun hanya diam tak melakukan apapun dan pengaya tersebut akan menguntungkan Firefox, anda dapat langsung menganjurkan penyusun tersebut untuk mencalonkan hasil kreasinya.</p>
+
+<h2>Pengaya saya sudah sejak lama berada pada antrian pencalonan. Kamu benci saya?</h2>
+
+<p>Tidak, kami tidak membenci anda. Kami sangat menyukai pengembang pengaya, dan kami bekerja keras untuk membuat mereka senang dan produktif agar semua pengguna di seluruh belahan dunia dapat diuntungkan dari hasil kerja mereka. Akan tetapi dengan berada pada situs publik AMO berarti kami harus memelihara apa yang ada di sana, jadi kami tidak dapat terburu-buru untuk melakukan hal tersebut. Kami sangat menghargai kesabaran anda untuk menunggu pengaya anda dalam masa evaluasi dan kami ingin tetap melakukannya secepat mungkin. Akan lebih mudah bagi kami jika lebih banyak orang yang dapat menyediakan tinjauan yang jelas dan hati-hati tentang pengaya yang ada pada proses evaluasi sandbox ini dan anda mungkin dapat mempertimbangkan untuk membantu dalam hal ini jika anda benar-benar ingin.</p>
+
+<h2>Saya menemukan bug yang serius pada pengaya saya dan saya ingin memperbaiki secepatnya. Apa yang harus saya lakukan?</h2>
+
+<p>Jika bug ini cukup serius (keamanan, stabilitas, permasalahan pada fungsi utama) dan anda ingin segera menampilkan pemutakhiran, anda disarankan untuk menyebutkan hal ini pada "catatan untuk peninjau" pada saat mengajukan pemutakhiran beserta - tentu saja - catatan versi yang lengkap. Anda juga mungkin ingin mendaftarkan pengguna yang ada untuk meminta pengujian dan melaporkan hasilnya secara lengkap pada sandbox. Memberitahukan hal ini pada kanal #addons di irc.mozilla.org dapat membantu orang lain untuk mengetahui situasi ini. Akan tetapi mohon untuk selalu bersikap sabar dan sopan jika anda melakukannya.</p>
+
+<p>Maaf, jangan merengek. Kami berusaha untuk selalu tanggap pada pembaruan dengan tingkat prioritas tinggi, tapi mengevaluasi pengaya atau versi lainnya membutuhkan waktu dan sering kami bayar dengan waktu tidur kami atau waktu kami untuk keluarga dan teman yang berkurang. Oleh karena itu kami akan berpaling dari orang-orang yang ingin mengambil keuntungan dari mekanisme ini yaitu yang "menyelonong dalam antrian". Jika anda tidak yakin apakah sebaiknya anda harus menempuh cara ini, bertanya melalui kanal #addons di irc.mozilla.org mungkin akan membantu anda untuk memutuskannya.
+
+<h2>Saya rasa saya tidak diperlakukan dengan adil pada tahap evaluasi pengaya saya. Apa yang harus saya lakukan?</h2>
+
+<p>Jika anda merasa pengaya anda telah dievaluasi secara tidak benar dan ditolak status publiknya, anda dapat mengirim email ke amo-editors@mozilla.org dengan keterangan lengkap mengenai alasan anda. Mohon email disampaikan dengan sopan dan jelas dan pastikan anda menjelaskan hal apa yang menyebabkan pengaya anda telah dievaluasi secara tidak adil.</p>
+
+<p>(Jika anda telah memperbaiki *semua* hal yang disebutkan sebagai permasalahan dalam email, anda tidak perlu mengirimkan email tentang hal ini, anda cukup mencalonkan ulang pengaya anda lewat Perangkat Pengembang.)</p>
+
+<h2>Dulu pengaya saya sudah berada pada situs publik. Sekarang kembali ke sandbox. Apa yang terjadi? </h2>
+
+<p>Jika pengaya tidak lagi memenuhi kriteria untuk ditampilkan pada situs publik, kami dapat memindahkannya kembali ke sandbox. Kecuali jika secara hukum kami tidak boleh melakukan hal tersebut, kami akan menghubungi anda melalui email saat hal tersebut terjadi dan menjelaskan alasan pemindahan tersebut.</p>
+
+<p>Mungkin juga anda telah menemukan sebuah bug pada situs kami. Pada kasus ini sebaiknya anda melaporkannya menggunakan Bugzilla; gunakan produk "addons.mozilla.org" dan komponen "Public Pages" pada laporan anda dan masukkan keterangan sebanyak yang anda tahu.</p>
+
+<h2>Pengaya saya sudah berada pada situs publik, dan banyak orang yang suka. Bagaimana caranya supaya masuk menjadi pengaya istimewa?</h2>
+
+<p>Jika anda merasa bahwa pengaya anda adalah salah satu contoh bagus tentang kelebihan yang dapat ditunjukkan oleh pengaya dan dapat menunjukkan nilai-nilai Mozilla tentang pengembangan web dan kekuatan pengguna web secara umum dan juga menyediakan pengalaman terbaik bagi para pengguna, anda dapat meminta kami untuk mempertimbangkan pengaya tersebut masuk ke dalam pengaya istimewa. Untuk melakukan hal ini, anda dapat mengirim email ke amo-editors@mozilla.org yang menjelaskan mengapa pengaya anda sangat bagus.</p>
+
+<p>Email anda <b>paling tidak</b> menyertakan informasi tentang hal-hal berikut:</p>
+<ul>
+<li>bagaimana pengguna web dapat menambah pengalaman menjelajah web</li>
+<li>mengapa pengaya anda sangat cocok untuk sebagian besar pengguna Firefox</li>
+<li>bagaimana pengaya anda dapat menunjukkan dan/atau mengikuti nilai-nilai dari proyek Mozilla, terutama tentang kendali penuh oleh pengguna, perlindungan privasi dan keamanan, akses web secara universal, dan data serta standard terbuka</li>
+<li>bagaimana pengaya anda berbeda dengan pengaya lain yang mirip (baik dari segi negatif maupun positif)</li>
+<li>reaksi apa yang anda ketahui dari pengguna, peninjau, blogger, astronot, atau binatang piaraan anda, baik positif maupun negatif</li>
+</ul>
+
+<p>Semakin lengkap informasi yang diberikan dalam permintaan anda, semakin mungkin kami akan memasukkan pengaya tersebut. Walaupun sebuah pengaya yang dibuat dengan bagus bukan garansi untuk mendapatkan tempat pada daftar istimewa. Pada akhirnya, daftar tersebut akan tetap dikelola Mozilla secara penuh, dan pengalaman dan perlindungan pengguna adalah hal yang paling utama.</p>
diff --git a/site/app/locale/id/pages/reviewguide.thtml b/site/app/locale/id/pages/reviewguide.thtml
new file mode 100644
index 0000000..272c913
--- /dev/null
+++ b/site/app/locale/id/pages/reviewguide.thtml
@@ -0,0 +1,113 @@
+<h1>Petunjuk tentang Tinjauan</h1>
+<p>Tinjauan Pengaya adalah sebuah cara untuk para pengguna situs pengaya untuk
+berbagi pendapat tentang pengaya yang mereka pasang dan gunakan. Penyunting
+memiliki hak untuk menolak atau menghapus tinjauan yang tidak sesuai dengan
+petunjuk berikut.</p>
+
+<div class="corner-box">
+ <h2>Beberapa tips menulis tinjauan</h2>
+
+<h3><b>Lakukan:</b></h3>
+<ul>
+<li>Tulislah tinjauan seperti anda menulis untuk teman anda tentang pengalaman
+menggunakan pengaya ini.</li>
+<li>Perhatikan agar tinjauan tetap ringkas dan mudah dimengerti.</li>
+<li>Berikan keterangan yang lengkap dan jelas. Misalnya:
+<ul>
+ <li>Apakah pengaya dapat berfungsi seperti yang anda harapkan?</li>
+ <li>Fitur apa yang anda sukai/tidak sukai?</li>
+ <li>Hal-hal apa yang berguna untuk anda?</li>
+ <li>Apakah anda mendapatkan kemudahan dalam menggunakannya?</li>
+ <li>Apakah anda akan tetap menggunakan pengaya ini?</li>
+</ul></li>
+
+<li>Mohon dibaca kembali sejenak tinjauan anda sebelum mengirimkannya untuk
+menghindari kesalahan ejaan atau susunan kata.</li>
+
+<li>Hindari rujukan topik atau yang bersifat sementara karena tinjauan akan
+tetap disimpan pada situs untuk waktu yang cukup lama.</li>
+</ul>
+
+<h3><b>Jangan:</b></h3>
+<ul>
+<li>Mengirimkan tinjauan sederhana hanya dengan kata-kata umum seperti "bagus
+sekali!", "berguna sekali", atau "tak berguna" tanpa keterangan lebih
+lanjut.</li>
+<li>Melaporkan kesalahan atau masalah pada tinjauan. Gunakan pilihan layanan
+dukungan yang tersedia pada setiap pengaya.</li>
+<li>Menuliskan tinjauan pengaya yang tidak anda gunakan sendiri.</li>
+<li>Menggunakan kata-kata yang tidak sopan atau yang bersifat
+menjelek-jelekkan.</li>
+<li>Memasukkan kode HTML, tautan kepada "malware", kode sumber atau potongan
+kode sumber. Tinjauan hanya dimaksudkan untuk diisi dengan teks biasa.</li>
+<li>Menggunakan pernyataan yang tidak benar, mengolok-olok atau
+menjelek-jelekkan penyusun pengaya.</li>
+<li>Menggunakan tinjauan untuk meminta bantuan untuk versi tertentu Firefox
+(atau aplikasi lainnya).</li>
+<li>Menuliskan email anda sendiri, nomor telepon, atau data pribadi
+lainnya.</li>
+<li>Mengirimkan tinjauan untuk pengaya dibuat oleh anda, organisasi anda atau
+organisasi yang anda wakili.</li>
+</ul>
+</div>
+
+<div class="corner-box">
+ <h2>Tinjauan untuk peringkat pengaya</h2>
+
+<p>Pemberian peringkat pengaya diharapkan dilakukan secara jujur dan memberikan
+pertanda tentang tingkat kualitas secara umum serta kegunaannya. Jangan hanya
+memberikan peringkat bintang 5 hanya karena anda suka atau bintang 1 hanya
+karena anda tidak suka. Pemberian peringkat yang konsisten adalah bagian
+terpenting untuk tinjauan secara umum.</p>
+
+<ul>
+<li><b>5 bintang: Bagus Sekali.</b> Tak hanya pengaya tersebut bekerja sesuai
+dengan fitur apa yang diberikan, tapi sangat berguna dibandingkan pengaya lain.
+Biasanya pengaya ini cukup sering anda gunakan dan anda sangat menyarankan
+penggunaannya.</li>
+<li><b>4 bintang: Bagus.</b> Berguna dan mudah digunakan walau tidak terlalu
+spesial. Pengaya ini disarankan untuk digunakan walau mungkin hanya berguna
+untuk sebagian orang saja.</li>
+<li><b>3 bintang: Cukup.</b> Mungkin mempunyai masalah dengan desain dan/atau
+tidak memiliki beberapa fitur penting. Beberapa masalah mungkin tidak terlalu
+penting sehingga tidak untuk tidak disarankan serta beberapa orang mungkin
+masih berpendapat bahwa pengaya tersebut cukup berguna. Disarankan untuk anda
+yang membutuhkan dan ingin mencobanya.</li>
+<li><b>2 bintang: Jelek.</b> Kualitas dan usabilitas yang rendah, atau tidak
+berfungsi sesuai dengan apa yang telah diklaim. Anda tidak menyarankan pengaya
+ini dan memberi pendapat bahwa mungkin masih berguna untuk beberapa orang.</li>
+<li><b>1 bintang: Jelek Sekali.</b> Pengaya tidak bekerja dengan benar atau
+tidak berguna sama sekali. Anda tidak mempunyai alasan apapun agar orang lain
+mau mencoba dan menyarankan agar menghindarinya.</li>
+</ul>
+
+<p>Tak ada masalah jika anda memberikan tinjauan sempurna atau buruk sekali
+pada sebuah pengaya, tetapi berikan alasan kenapa anda berpendapat demikian.
+Bintang-bintang peringkat akan menjadi tak berarti jika anda tidak menyebutkan
+alasannya.</p>
+</div>
+
+<div class="corner-box">
+ <h2>Pertanyaan yang Sering Diajukan tentang Tinjauan</h2>
+
+<h3>Bagaimana saya melaporkan tinjauan yang bermasalah?</h3>
+<p>Silakan melaporkan atau menandai laporan yang dipertanyakan dengan mengklik
+"Laporkan tinjauan ini" yang akan dikirimkan untuk keperluan moderasi.
+Penyunting akan menggunakan Petunjuk tentang Tinjauan ini untuk mengevaluasi
+apakah akan menghapus tinjauan atau mengembalikannya untuk ditampilkan kembali
+di situs.</p>
+
+<h3>Saya adalah penyusun pengaya, dapatkah saya membalas tinjauan?</h3>
+<p>Tentu saja, penyusun pengaya dapat memberikan sebuah balasan pada sebuah
+tinjauan. Diskusi lebih lanjut atau tindakan lebih lanjut sebaiknya diarahkan
+ke forum layanan dukungan atau diskusi grup.</p>
+
+<h3>Saya adalah penyusun pengaya, bolehkah saya menghapus tinjauan atau
+peringkat yang tidak saya sukai?</h3>
+<p>Secara umum tidak. Akan tetapi tinjauan yang tidak memenuhi syarat petunjuk
+tinjauan di atas dapat dilaporkan untuk dimoderasi oleh seorang penyunting
+dengan cara mengklik "Laporkan tinjauan ini". Jika tinjauan menyertakan keluhan
+yang tidak lagi sesuai karena rilis pengaya baru anda, kami akan
+mempertimbangkan untuk menghapus tinjauan tersebut. Kirimkan permintaan secara
+detil kepada amo-editors@mozilla.org.</p>
+</div>
diff --git a/site/app/locale/id/pages/sandbox.thtml b/site/app/locale/id/pages/sandbox.thtml
new file mode 100644
index 0000000..fc8638c
--- /dev/null
+++ b/site/app/locale/id/pages/sandbox.thtml
@@ -0,0 +1,13 @@
+<h1>Sistem Peninjauan pada Sandbox</h1>
+<h2>Apakah sandbox itu?</h2>
+<p>Sandbox adalah tempat para pengguna berpengalaman untuk menguji coba pengaya sebelum ditinjau dan sebelum digunakan untuk publik. Untuk mengakses sandbox, anda harus mengaktifkannya pada pengaturan akun anda. Anda harus selalu berhati-hati untuk memasang dan menggunakan pengaya yang berada pada sandbox karena pengaya tersebut belum diuji coba oleh penyunting dan mungkin dapat merusak sistem pada komputer anda.</p>
+
+<h2>Bagaimana supaya pengaya milik saya dapat tampil pada situs publik?</h2>
+<!-- To localize the flowchart image, see http://wiki.mozilla.org/Update:Remora_Sandbox_Flowchart -->
+<div style="text-align: center;">%s</div>
+<ol>
+ <li><b>Ajukan pengaya anda dengan menggunakan Perangkat Pengembang.</b> Pengaya anda akan langsung tampil pada situs "Sandbox" pada situs Pengaya Mozilla. Pada situs ini para pengguna berpengalaman akan menguji dan memberikan tanggapan. Untuk menampilkan sandbox, anda harus mengaktifkannya lewat pengaturan akun anda.</li>
+ <li><b>Calonkan pengaya anda ke situs publik.</b> Dari Perangkat Pengembang, terdapat tautan untuk mencalonkan pengaya anda. Setelah dicalonkan, pengaya akan disertakan pada Antrian Pencalonan Penyunting untuk ditinjau.</li>
+ <li><b>Seorang penyunting akan meninjau pengaya anda.</b> Seorang penyunting Pengaya Mozilla akan memasang pengaya anda dan mengujinya apakah bekerja dengan baik. Penyunting juga akan membaca tinjauan para penguji lainnya yang dilakukan oleh pengguna berpengalaman yang telah memasang dan menguji pengaya anda.</li>
+ <li><b>Pengaya anda akan dimasukkan pada situs publik atau tetap berada pada sandbox.</b> Penyunting akan memilih untuk memasukkan pengaya anda ke situs publik atau tetap berada pada sandbox. Jika pengaya tetap berada di dalam sandbox, anda dapat mencalonkannya kembali setelah membuat perubahan yang disarankan oleh penyunting. Jika dimasukkan ke situs publik, versi baru yang akan datang akan tetap berada pada sandbox sampai ditinjau oleh pengaya dan dimasukkan ke dalam situs publik. Setelah pengaya anda berada pada situs publik, anda tidak perlu mencalonkannya lagi untuk ditinjau. Versi baru yang akan datang ini akan secara otomatis dimasukkan ke dalam antrian peninjauan.</li>
+</ol>
diff --git a/site/app/locale/id/pages/statistics_help.thtml b/site/app/locale/id/pages/statistics_help.thtml
new file mode 100644
index 0000000..232fc24
--- /dev/null
+++ b/site/app/locale/id/pages/statistics_help.thtml
@@ -0,0 +1,7 @@
+<h3>Bantuan</h3>
+<p>Panel Statistik berfungsi menampilkan data unduhan dan data ping yang dikumpulkan dari pengaya anda.</p>
+<h4>Unduhan</h4>
+<p>Jumlah unduhan dimutakhirkan setiap hari dan hanya menyertakan data unduhan pertama tanpa memasukkan data unduhan versi baru (<em>add-on update</em>).</p>
+
+<h4>Pemutakhiran Data Ping</h4>
+<p>Pengaya yang diunduh dari situs ini akan memeriksa versi baru (menge-ping) satu kali dalam satu hari. Jumlah total ping disebut sebagai Pengguna Aktif Harian. Data Pengguna Aktif Harian (Active Daily Users-ADU) dikelompokkan berdasar versi pengaya, sistem operasi, status pengaya, dan aplikasi. Rekaman data ini dimutakhirkan satu kali dalam seminggu pada hari Rabu.</p>
diff --git a/site/app/locale/id/pages/submission_help.thtml b/site/app/locale/id/pages/submission_help.thtml
new file mode 100644
index 0000000..ae30918
--- /dev/null
+++ b/site/app/locale/id/pages/submission_help.thtml
@@ -0,0 +1,35 @@
+<h1>Bantuan Pengajuan Pengaya</h1>
+Isian yang wajib diisi dicetak <b>tebal</b>. Isian yang tidak wajib diisi dicetak <i>miring</i>.
+<h2 id="step1">Langkah Pertama: Unggah</h2>
+<ul class="submissionHelp">
+ <li><span class="required">Jenis Pengaya</span> - Secara default, jenis pengaya akan ditentukan secara otomatis berdasarkan berkas yang diunggah. Sebaiknya anda tidak mengubah isian ini.</li>
+ <li><span class="required">Berkas Pengaya</span> - Berkas paket pengaya anda, lengkap dengan berkas install.rdf. Dengan memilih platform, anda dapat mengunggah beberapa berkas sekaligus jika setiap platform membutuhkan berkas yang berbeda.</li>
+ <li><span class="optional">Berkas Ikon</span> - Berkas ikon yang akan tampil di samping nama pengaya pada halaman tampilan dan pada dialog pemasangan pengaya. Berkas ini akan diubah ukurannya secara otomatis menjadi 32x32 piksel tanpa mengubah rasio perbandingan panjang dan lebar.</li>
+ <li><span class="required">Bahasa (Locale) Default</span> - Bahasa default pengaya adalah bahasa utama. Jika bahasa yang digunakan pengguna tidak tersedia maka akan digunakan bahasa yang default.</li>
+ <li><span class="optional">Lewati peninjauan detil pengaya yang lama</span> - Jika anda sedang memperbarui pengaya yang ada, isian ini akan tampil. Tandai pilihan ini untuk melewati langkah ke-3 untuk langsung memasukkan informasi yang spesifik tentang versi.</li>
+</ul>
+
+<h2 id="step2">Langkah ke-2: Detil Pengaya</h2>
+<ul class="submissionHelp">
+ <li><span class="required">Nama</span> - Nama pengaya dalam bahasa default.</li>
+ <li><span class="required">Penyusun</span> - Semua pengguna yang memiliki hak akses untuk mengubah daftar penyusun pengaya akan ditampilkan sebagai penyusun pengaya pada halaman tampilan.</li>
+ <li><span class="required">Kategori</span> - Kategori yang cocok untuk pengaya.</li>
+ <li><span class="optional">Beranda</span> - Situs web pengaya dalam bahasa default.</li>
+ <li><span class="required">Ringkasan</span> - Keterangan singkat tentang pengaya pada bahasa default. Jumlah karakter pada isian ini tidak boleh melebihi 250 karakter dan akan tampil pada halaman tampilan pengaya, hasil pencarian, dan daftar pengaya.</li>
+ <li><span class="required">Deskripsi</span> - Deskripsi tentang pengaya dalam bahasa default. Isian ini akan tampil di bawah ringkasan pada halaman tampilan.</li>
+ <li><span class="optional">EULA</span> - Perjanjian Lisensi End-User (End User License Agreement) dalam bahasa default yang diwajibkan disetujui pengguna sebelum proses pengunduhan pengaya.</li>
+ <li><span class="optional">Kebijakan Privasi</span> - Kebijakan privasi pengaya dalam bahasa default. Kebijakan privasi menjelaskan tentang apa saja yang akan dilakukan atas semua informasi yang berasal dari end-user. Kebijakan ini akan ditampilkan melalui tombol di samping tombol pemasangan pada halaman tampilan pengaya. Informasi lebih lanjut tentang apa yang harus disertakan pada Kebijakan Privasi ini dan ketentuan tentang pengaya yang bagaimana yang membutuhkan hal ini tersedia di <a href="%s">Kebijakan Pengaya</a>.</li>
+ <li><span class="optional">Izinkan pengguna untuk membaca kode sumber secara online</span> - Menandai pilihan ini akan mengizinkan pengguna untuk menjelajahi dan membaca kode sumber pengaya anda secara online.</li>
+ <li><span class="optional">Masih prarilis</span> - Menandai pilihan ini menandakan bahwa pengaya ini masih dalam tahap prarilis atau versi beta. Pengaya prarilis akan tetap berada pada sandbox dan tidak dapat dicalonkan untuk tampil pada situs publik sampai pilihan ini dimatikan.</li>
+ <li><span class="optional">Pengaya ini untuk hanya bekerja situs tertentu</span> - Menandai pilihan ini berarti pengaya yang diajukan hanya berfungsi pada situs tertentu. Contohnya adalah pengaya yang memodifikasi tampilan suatu situs. Isian ini berguna untuk para penyunting dan nantinya dapat digunakan sebagai filter pencarian.</li>
+ <li><span class="optional">Pengaya ini membutuhkan perangkat lunak eksternal</span> - Menandai pilihan ini menandakan pengaya membutuhkan perangkat lunak eksternal untuk dapat berfungsi. Isian ini berguna untuk para penyunting dan nantinya dapat digunakan sebagai filter pencarian.</li>
+</ul>
+
+<h2 id="step3">Langkah ke-3: Detil Versi</h2>
+<ul class="submissionHelp">
+ <li><span class="required optional">Catatan Versi</span> - Ringkasan atau daftar perubahan yang terjadi pada versi baru ini. Isian ini bersifat opsional untuk pengajuan pengaya baru namun diwajibkan untuk pembaruan versi pada pengaya lama.</li>
+ <li><span class="optional">Catatan untuk Peninjau</span> - Isian ini digunakan untuk menyampaikan informasi untuk para penyunting yang akan meninjau pengaya anda. Informasi nama akun testing dan catatan khusus harus disebutkan dalam isian ini.</li>
+</ul>
+
+<h2 id="step4">Langkah ke-4: Alih Bahasa (Localization)</h2>
+Di sini adalah daftar item isian untuk pengaya yang dapat dialihbahasakan pada bahasa yang ingin didukung. Klik pada pilihan bahasa yang berkaitan untuk memasukkan teks alih bahasa yang diinginkan.
diff --git a/site/app/locale/it/LC_MESSAGES/messages.mo b/site/app/locale/it/LC_MESSAGES/messages.mo
new file mode 100644
index 0000000..03d9008
--- /dev/null
+++ b/site/app/locale/it/LC_MESSAGES/messages.mo
Binary files differ
diff --git a/site/app/locale/it/LC_MESSAGES/messages.po b/site/app/locale/it/LC_MESSAGES/messages.po
new file mode 100644
index 0000000..b676edf
--- /dev/null
+++ b/site/app/locale/it/LC_MESSAGES/messages.po
@@ -0,0 +1,7544 @@
+# Remora Preliminary Language File
+# Copyright (C) 2006 Mozilla Corporation
+# This file is distributed under the same license as the REMORA package.
+# Wil Clouser <clouserw@mozilla.com>, 2006.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: REMORA 0.1\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2009-01-16 11:45-0800\n"
+"PO-Revision-Date: 2009-06-05 19:42+0100\n"
+"Last-Translator: Francesco Lodolo <francesco.lodolo@mozillaitalia.org>\n"
+"Language-Team: ITALIAN <francesco.lodolo@mozillaitalia.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=n != 1;\n"
+
+#: views/addons/policy.thtml:98
+msgid "a_cancel_installation"
+msgstr "Annulla installazione"
+
+#. This is the text that appears on buttons to download add-ons.
+#. %$1s is an optional string that only appears if the add-on is only available for
+#. a certain platform. Examples: (Windows) or (Linux)
+#. Note that the parentheses are included in the string. :(
+#: views/elements/amo2009/install.thtml:126
+#: views/elements/amo2009/install.thtml:227
+#: views/elements/amo2009/install.thtml:257
+#: views/elements/amo2009/install.thtml:300
+#: views/elements/amo2009/install.thtml:312
+#: views/elements/install.thtml:73
+#: views/elements/install.thtml:181
+#: views/elements/install.thtml:205
+#: views/elements/install.thtml:248
+#: views/elements/install.thtml:260
+#: views/addons/plugins.thtml:66
+#: views/addons/plugins.thtml:76
+#: views/addons/plugins.thtml:86
+#: views/addons/plugins.thtml:96
+#: views/addons/plugins.thtml:119
+#, php-format
+msgid "a_download"
+msgstr "Scarica ora %$1s"
+
+#: views/addons/policy.thtml:72
+msgid "a_eula_download"
+msgstr "Accetta e scarica"
+
+#: views/addons/policy.thtml:74
+msgid "a_eula_install"
+msgstr "Accetta e installa"
+
+#: views/elements/header.thtml:76
+#: views/elements/header.thtml:82
+#: views/api/api_addon.thtml:55
+#: views/api/collections_feed.thtml:75
+#: views/sharing_api/addon.thtml:64
+msgid "a_header_public"
+msgstr "Pubblicato"
+
+#: views/elements/header.thtml:58
+#: views/elements/header.thtml:75
+#: views/elements/header.thtml:80
+#: views/api/api_addon.thtml:57
+#: views/api/collections_feed.thtml:77
+#: views/sharing_api/addon.thtml:66
+msgid "a_header_sandbox"
+msgstr "Sandbox"
+
+#. %s is a date in the _('date') format
+#: views/elements/amo2009/homepage_addon.thtml:115
+#: views/elements/addon_listitem.thtml:122
+#: views/elements/feature.thtml:106
+#: views/addons/display.thtml:104
+#: views/addons/browse_thumbs.thtml:73
+msgid "addon_detail_last_updated"
+msgstr "Aggiornato il %s"
+
+#. %s is the version of the add-on. Example: 3.2a1
+#: views/elements/amo2009/addon_version_detail.thtml:51
+#: views/elements/addon_version_detail.thtml:51
+#, php-format
+msgid "addon_display_header_version"
+msgstr "Versione %s"
+
+#: views/addons/browse_thumbs.thtml:80
+msgid "addon_downloads"
+msgstr "download"
+
+#: views/addons/display.thtml:147
+msgid "addon_downloads_total"
+msgstr "download totali"
+
+#: views/elements/amo2009/homepage_addon.thtml:106
+#: views/elements/addon_listitem.thtml:115
+#: views/elements/feature.thtml:101
+#: views/addons/category_landing.thtml:157
+#: views/addons/display.thtml:146
+#: views/addons/browse_thumbs.thtml:80
+msgid "addon_downloads_weekly"
+msgstr "download settimanali"
+
+#. %1 is the add-on count, %2 the category name
+#: views/addons/browse_thumbs.thtml:104
+#: views/addons/browse.thtml:60
+#, php-format
+msgid "addon_list_category_totalcount"
+msgid_plural "addon_list_category_totalcount"
+msgstr[0] "%1$s componente aggiuntivo"
+msgstr[1] "%1$s componenti aggiuntivi"
+
+#: views/elements/amo2009/addon_list_options.thtml:103
+#: views/elements/pagination.thtml:67
+#: views/elements/addon_list_options.thtml:94
+msgid "addon_list_perpage"
+msgstr "per pagina"
+
+#: views/elements/amo2009/addon_list_options.thtml:84
+#: views/elements/addon_list_options.thtml:98
+msgid "addon_list_sortby"
+msgstr "Ordinato per:"
+
+#: views/helpers/addons_html.php:568
+#: views/elements/amo2009/install.thtml:321
+#: views/elements/feature.thtml:89
+msgid "addon_listitem_flag_experimental"
+msgstr "sperimentale"
+
+#: views/helpers/addons_html.php:570
+msgid "addon_listitem_flag_recommended"
+msgstr "consigliato"
+
+#. %1 is the add-on name, %2 is the platform
+#: views/pages/js_constants.js.thtml:66
+msgid "addon_not_available_for_platform"
+msgstr "%1$s non è disponibile per %2$s."
+
+#. %1 is the add-on name
+#: views/addons/policy.thtml:101
+#: views/addons/previews.thtml:60
+#: views/addons/versions.thtml:130
+#: views/reviews/flag.thtml:61
+#: views/reviews/add.thtml:114
+#: views/reviews/display.thtml:216
+#: views/reviews/review_added.thtml:57
+#, php-format
+msgid "addon_review_a_back_to_addon_x"
+msgstr "Torna a %1$s…"
+
+#. %1 is the add-on name
+#: views/reviews/flag.thtml:60
+#: views/reviews/add.thtml:113
+#: views/reviews/review_added.thtml:56
+#, php-format
+msgid "addon_review_a_back_to_reviews"
+msgstr "Torna alle recensioni…"
+
+#: views/reviews/add.thtml:85
+msgid "addon_review_add_rating_field"
+msgstr "Voto:"
+
+#: views/reviews/add.thtml:102
+msgid "addon_review_add_review_field"
+msgstr "Recensione:"
+
+#: views/reviews/add.thtml:107
+msgid "addon_review_add_submit"
+msgstr "Invia la tua recensione"
+
+#. %s is the name of the add-on
+#: views/reviews/add.thtml:51
+#, php-format
+msgid "addon_review_add_title"
+msgstr "Aggiungi una recensione per %s"
+
+#: views/reviews/add.thtml:78
+msgid "addon_review_add_title_field"
+msgstr "Titolo/Sommario:"
+
+#: views/reviews/display.thtml:77
+#: views/reviews/display.thtml:161
+msgid "addon_review_admin_delete"
+msgstr "Elimina"
+
+#: views/reviews/display.thtml:76
+msgid "addon_review_author_reply_link"
+msgstr "Rispondi"
+
+#: views/reviews/delete.thtml:62
+msgid "addon_review_confirm_delete"
+msgstr "Sei sicuro di voler eliminare questa recensione?"
+
+#: views/reviews/delete.thtml:63
+msgid "addon_review_confirm_no"
+msgstr "No"
+
+#: views/reviews/delete.thtml:64
+msgid "addon_review_confirm_yes"
+msgstr "Sì"
+
+#: views/reviews/delete.thtml:48
+msgid "addon_review_delete_header"
+msgstr "Elimina recensione"
+
+#: controllers/reviews_controller.php:449
+msgid "addon_review_deleted_successfully"
+msgstr "Recensione eliminata con successo."
+
+#. %s is the name of the add-on
+#: views/reviews/add.thtml:51
+#, php-format
+msgid "addon_review_edit_title"
+msgstr "Modifica la recensione per %s"
+
+#. %1 is the count of characters entered as notes for the review flag reason.
+#: controllers/reviews_controller.php:539
+msgid "addon_review_flag_error_other_length"
+msgstr "Problema durante la segnalazione: la lunghezza massima delle note è compresa tra 10 e 100 caratteri, la nota inserita conteneva %1$s caratteri."
+
+#. Removing an extra comma
+#: views/reviews/review_added.thtml:53
+msgid "addon_review_in_moderation"
+msgstr "Attenzione: affinché la recensione possa apparire sul sito pubblico, dovrà essere approvata da un revisore."
+
+#: views/reviews/add.thtml:57
+msgid "addon_review_in_reply_to"
+msgstr "Risposta dello sviluppatore a:"
+
+#. %1 is the review count, %2 is the nickname or full name of the user.
+#: views/reviews/display.thtml:131
+#, php-format
+msgid "addon_review_others_by_user"
+msgid_plural "addon_review_others_by_user"
+msgstr[0] "Visualizza %1$s recensione precedente inserita da %2$s per questo componente aggiuntivo."
+msgstr[1] "Visualizza %1$s recensioni precedenti inserite da %2$s per questo componente aggiuntivo."
+
+#. %1 is the add-on name
+#: controllers/reviews_controller.php:201
+#: controllers/reviews_controller.php:250
+#: controllers/reviews_controller.php:345
+#: controllers/reviews_controller.php:424
+#, php-format
+msgid "addon_review_pagetitle"
+msgstr "Recensioni per %s"
+
+#. %1 is the user, %2 is the (localized) date
+#: views/reviews/display.thtml:160
+#, php-format
+msgid "addon_review_reply_on_x_by_y"
+msgstr "Risposta di %1$s su %2$s"
+
+#: views/reviews/display.thtml:157
+msgid "addon_review_reply_prefix"
+msgstr "Risposta dello sviluppatore:"
+
+#: views/reviews/review_added.thtml:51
+msgid "addon_review_saved_successfully"
+msgstr "La tua recensione è stata salvata con successo."
+
+#: views/addons/display.thtml:354
+#: views/reviews/display.thtml:72
+msgid "addon_reviewed_by_u_on_d"
+msgstr "di %1$s del %2$s"
+
+#. %1 is the user, %2 is the (localized) date, %3 is the rating
+#: views/editors/reviews_queue.thtml:57
+#: views/editors/reviews_queue.thtml:68
+#: views/reviews/add.thtml:63
+#: views/reviews/delete.thtml:54
+#, php-format
+msgid "addon_reviewed_on_x_rated_y"
+msgstr "di %1$s del %2$s (voto %3$s)"
+
+#: views/elements/amo2009/addon_version_detail.thtml:52
+#: views/elements/addon_version_detail.thtml:52
+msgid "addon_version_permalink"
+msgstr "Collegamento permanente a questa versione"
+
+#. %1 is the current Application name (e.g. Firefox)
+#. %2 is the Application's version number
+#: views/addons/versions.thtml:140
+msgid "addon_versions_getlatestversion"
+msgstr "La versione più recente compatibile con %1$s %2$s"
+
+#: views/addons/display.thtml:447
+msgid "addons_author_addons_submit"
+msgstr "Vai"
+
+#: views/elements/amo2009/homepage_addon.thtml:100
+#: views/elements/feature.thtml:95
+msgid "addons_author_tooltip"
+msgstr "Visualizza il profilo dell'autore"
+
+#. %1 is the name of the Application (eg. Firefox)
+#: controllers/addons_controller.php:1296
+msgid "addons_browse_all_themes_title"
+msgstr "Visualizza tutti i temi :: %1$s Add-on"
+
+#. %s is the name of the category
+#: controllers/addons_controller.php:1016
+#, php-format
+msgid "addons_browse_browse_category"
+msgstr "Visualizza %s"
+
+#. %1 is the name of the theme category (eg. Modern)
+#. %2 is the name of the Application (eg. Firefox)
+#: controllers/addons_controller.php:664
+msgid "addons_browse_categories_header_theme"
+msgstr "Visualizza i temi in %1$s :: %2$s Add-on"
+
+#: views/addons/display.thtml:249
+msgid "addons_display_a_license_what"
+msgstr "Che cos'è questo?"
+
+#: views/reviews/display.thtml:222
+msgid "addons_display_add_review"
+msgstr "Aggiungi una recensione"
+
+#: views/addons/display.thtml:294
+msgid "addons_display_advanced_details"
+msgstr "Dettagli"
+
+#: views/addons/display.thtml:98
+msgid "addons_display_categories"
+msgstr "Categorie"
+
+#: views/addons/display.thtml:482
+msgid "addons_display_collection_add"
+msgstr "Aggiungi alla raccolta:"
+
+#: views/addons/display.thtml:491
+msgid "addons_display_collection_add_new"
+msgstr "Nuova raccolta…"
+
+#: views/addons/display.thtml:487
+msgid "addons_display_collection_add_select_one"
+msgstr "Seleziona una raccolta…"
+
+#: views/addons/display.thtml:493
+msgid "addons_display_collection_add_submit"
+msgstr "Pubblica"
+
+#. %1$s is the add-on name
+#. %2$s is the collection name, linked to the collection's page
+#: views/pages/js_constants.js.thtml:103
+#: views/addons/display.thtml:61
+msgid "addons_display_collection_publish_success"
+msgstr "%1$s è stata aggiunto alla raccolta %2$s."
+
+#: views/addons/display.thtml:483
+msgid "addons_display_collection_whatsthis"
+msgstr "Che cos'è questo?"
+
+#. %1$s is a number
+#: views/addons/display.thtml:473
+msgid "addons_display_collections_more"
+msgid_plural "addons_display_collections_more"
+msgstr[0] "e un'altra raccolta"
+msgstr[1] "e altre %1$s raccolte"
+
+#: views/addons/display.thtml:403
+msgid "addons_display_detailed_review"
+msgstr "Recensione completa"
+
+#: views/reviews/add.thtml:89
+#: views/reviews/add.thtml:90
+msgid "addons_display_dont_like_it"
+msgstr "Non mi piace"
+
+#: views/reviews/display.thtml:220
+msgid "addons_display_edit_review"
+msgstr "Modifica la tua recensione"
+
+#: views/addons/display.thtml:132
+msgid "addons_display_has_privacy"
+msgstr "Questo componente aggiuntivo include un'informativa sulla privacy"
+
+#: views/reviews/add.thtml:87
+#: views/reviews/add.thtml:88
+msgid "addons_display_hate_it"
+msgstr "Lo odio"
+
+#: views/addons/display.thtml:462
+msgid "addons_display_header_collections"
+msgstr "Raccolte correlate"
+
+#: views/addons/display.thtml:297
+msgid "addons_display_header_developer_comments"
+msgstr "Commenti dello sviluppatore"
+
+#: views/addons/display.thtml:230
+msgid "addons_display_header_homepage"
+msgstr "Sito web"
+
+#: views/addons/display.thtml:247
+#: views/addons/versions.thtml:110
+msgid "addons_display_header_license"
+msgstr "Licenza del codice sorgente"
+
+#: views/addons/display.thtml:337
+msgid "addons_display_header_reviews"
+msgstr "Recensioni"
+
+#: views/addons/display.thtml:261
+msgid "addons_display_header_support"
+msgstr "Supporto"
+
+#: views/reviews/add.thtml:91
+#: views/reviews/add.thtml:92
+msgid "addons_display_like_it"
+msgstr "Mi piace"
+
+#: views/addons/display.thtml:210
+msgid "addons_display_long_description"
+msgstr "Descrizione"
+
+#: views/reviews/add.thtml:95
+#: views/reviews/add.thtml:96
+msgid "addons_display_love_it"
+msgstr "Lo adoro"
+
+#: views/addons/display.thtml:178
+msgid "addons_display_more_images"
+msgstr "Altre immagini"
+
+#: views/addons/display.thtml:465
+msgid "addons_display_nocollections"
+msgstr "Questo componente aggiuntivo non fa ancora parte di alcuna raccolta."
+
+#. %1$s is either an author's name or a comma separated list of authors. Using
+#. the list doesn't make sense in the English plural form so we ignore the
+#. variable.
+#: views/addons/display.thtml:436
+msgid "addons_display_other_addons_by"
+msgid_plural "addons_display_other_addons_by"
+msgstr[0] "Altri componenti aggiuntivi di %1$s"
+msgstr[1] "Altri componenti aggiuntivi dei seguenti autori"
+
+#. %s is the name of the add-on and the add-on section. Example:
+#. Some Add-on :: Firefox Add-ons
+#. This should not be concatenated in the code and should be fixed.
+#: controllers/addons_controller.php:141
+#: controllers/addons_controller.php:280
+#: controllers/addons_controller.php:1442
+#, php-format
+msgid "addons_display_pagetitle"
+msgstr "%s"
+
+#. %s is an email address
+#: views/addons/display.thtml:286
+#, php-format
+msgid "addons_display_paragraph_supportinfoemail"
+msgstr "Il supporto per questa estensione è fornito dalla sviluppatore inviando una e-mail a %s."
+
+#. %$1s is a URL
+#. %$2s is an email address
+#: views/addons/display.thtml:269
+#, php-format
+msgid "addons_display_paragraph_supportinfoemailurl"
+msgstr "Il supporto per questa estensione è fornito dallo sviluppatore su %1$s o inviando una e-mail a %2$s."
+
+#. %s is a URL
+#: views/addons/display.thtml:278
+#, php-format
+msgid "addons_display_paragraph_supportinfourl"
+msgstr "Il supporto per questa estensione è fornito dallo sviluppatore su %s."
+
+#: views/addons/display.thtml:383
+msgid "addons_display_rate_it"
+msgstr "Vota"
+
+#: views/reviews/add.thtml:93
+#: views/reviews/add.thtml:94
+msgid "addons_display_really_like_it"
+msgstr "Mi piace molto"
+
+#: views/addons/display.thtml:410
+msgid "addons_display_review_etiquette"
+msgstr "Non segnalare dei bug attraverso le recensioni. Il tuo indirizzo e-mail non è visibile allo sviluppatore che potrebbe avere bisogno di contattarti per risolvere il problema."
+
+#. %1 is the review guidelines link
+#: views/addons/display.thtml:417
+msgid "addons_display_review_guidelines_link"
+msgstr "<a href=\"%s\">Linee guida per la recensione</a>"
+
+#. %1 is the support section link
+#: views/addons/display.thtml:414
+msgid "addons_display_review_see_support"
+msgstr "Consultare la <a href=\"%1$s\">sezione del supporto</a> per scoprire dove ottenere assistenza per questo componente aggiuntivo."
+
+#: views/addons/display.thtml:404
+msgid "addons_display_review_submit"
+msgstr "Invia"
+
+#: views/addons/display.thtml:430
+#, php-format
+msgid "addons_display_see_all_addons"
+msgstr "Visualizza tutti i componenti aggiuntivi in %1$s"
+
+#. %1 is the number of reviews
+#: views/addons/display.thtml:364
+#, php-format
+msgid "addons_display_see_all_reviews"
+msgstr "Visualizza tutte le recensioni (%1$s)"
+
+#: views/addons/display.thtml:219
+msgid "addons_display_see_all_versions"
+msgstr "Mostra tutte le versioni"
+
+#: views/addons/display.thtml:321
+#: views/addons/versions.thtml:117
+msgid "addons_display_view_source"
+msgstr "Visualizza i sorgenti"
+
+#: views/addons/display.thtml:324
+msgid "addons_display_view_stats"
+msgstr "Visualizza statistiche"
+
+#: views/addons/display.thtml:376
+msgid "addons_display_what_do_you_think"
+msgstr "Che cosa ne pensi?"
+
+#: views/elements/app_compatibility.thtml:49
+msgid "addons_display_workswith"
+msgstr "È compatibile con:"
+
+#: views/addons/home.thtml:112
+msgid "addons_home_browse_new"
+msgstr "Appena aggiunti"
+
+#: views/addons/home.thtml:110
+msgid "addons_home_browse_popular"
+msgstr "Più popolari"
+
+#: views/addons/home.thtml:108
+msgid "addons_home_browse_recommended"
+msgstr "Consigliati"
+
+#: views/addons/home.thtml:127
+#: views/addons/home.thtml:134
+#: views/addons/home.thtml:141
+#: views/addons/home.thtml:148
+msgid "addons_home_browse_subscribe"
+msgstr "Iscriviti"
+
+#: views/addons/home.thtml:101
+msgid "addons_home_browse_title"
+msgstr "Esplora i componenti aggiuntivi"
+
+#: views/addons/home.thtml:114
+msgid "addons_home_browse_updated"
+msgstr "Aggiornati"
+
+#: views/elements/amo2009/homepage_addon.thtml:100
+#: views/elements/addon_discussionheader.thtml:83
+#: views/elements/addon_listitem.thtml:109
+#: views/elements/feature.thtml:95
+#: views/addons/category_landing.thtml:66
+#: views/addons/policy.thtml:57
+#: views/addons/display.thtml:70
+#: views/addons/home.thtml:178
+msgid "addons_home_by"
+msgstr "di"
+
+#: views/addons/home.thtml:169
+msgid "addons_home_collection_popular_title"
+msgstr "Raccolte più popolari"
+
+#: views/elements/amo2009/categories.thtml:69
+#: views/addons/home.thtml:160
+msgid "addons_home_collections"
+msgstr "Raccolte"
+
+#. %1$s is the count of addons in a collection
+#: views/elements/amo2009/collection_listing_item.thtml:51
+#: views/addons/home.thtml:185
+msgid "addons_home_collections_addon_count"
+msgid_plural "addons_home_collections_addon_count"
+msgstr[0] "<strong>%1$s</strong> componente aggiuntivo"
+msgstr[1] "<strong>%1$s</strong> componenti aggiuntivi"
+
+#: views/addons/home.thtml:196
+msgid "addons_home_collections_all"
+msgstr "Visualizza tutte le raccolte"
+
+#: views/addons/home.thtml:162
+msgid "addons_home_collections_intro"
+msgstr "Le raccolte sono uno strumento per suddividere in categorie, combinare e associare i componenti aggiuntivi. Puoi abbonarti alle raccolte pubblicate da altri utenti o crearne di tue."
+
+#. %1$s is the count of subscribers for a collection
+#: views/elements/amo2009/collection_listing_item.thtml:58
+#: views/collections/detail.thtml:96
+#: views/addons/home.thtml:189
+msgid "addons_home_collections_subscribers"
+msgid_plural "addons_home_collections_subscribers"
+msgstr[0] "<strong>%1$s</strong> iscritto"
+msgstr[1] "<strong>%1$s</strong> iscritti"
+
+#: views/addons/searchengines.thtml:54
+#: views/addons/themes_landing.thtml:49
+msgid "addons_home_feature_head"
+msgstr "Consigliati da noi"
+
+#: controllers/search_controller.php:218
+#: controllers/addons_controller.php:176
+#: controllers/addons_controller.php:428
+#: controllers/addons_controller.php:671
+#: controllers/addons_controller.php:871
+#: controllers/addons_controller.php:1103
+#: controllers/addons_controller.php:1242
+#: controllers/addons_controller.php:1298
+#, php-format
+msgid "addons_home_header_details"
+msgstr "I componenti aggiuntivi permettono di estendere %1$s e personalizzare la tua esperienza di navigazione. Dai un'occhiata in giro e rendi %1$s veramente unico."
+
+#. %1$s is the HTML collection name link.
+#: views/elements/amo2009/teaser_collections.thtml:107
+msgid "addons_home_introduction_collection_link"
+msgstr "Ti piace? Scopri altri componenti aggiuntivi in %1$s."
+
+#: views/elements/amo2009/teaser_collections.thtml:60
+msgid "addons_home_introduction_extras"
+msgstr "<strong>Oltre 5000 componenti aggiuntivi gratuiti</strong> che ti permettono di personalizzare Firefox e adattarlo alle tue esigenze."
+
+#: views/elements/amo2009/teaser_collections.thtml:55
+msgid "addons_home_introduction_header"
+msgstr "Che cosa sono i componenti aggiuntivi?"
+
+#: views/elements/amo2009/teaser_collections.thtml:72
+msgid "addons_home_introduction_install"
+msgstr "<strong>Facili da installare</strong> e da aggiornare."
+
+#: views/elements/amo2009/teaser_collections.thtml:45
+msgid "addons_home_introduction_name"
+msgstr "Introduzione"
+
+#: views/elements/amo2009/teaser_collections.thtml:66
+msgid "addons_home_introduction_themes"
+msgstr "Barre degli strumenti, temi e motori di ricerca in grado di <strong>aiutarti nelle operazioni di ogni giorno.</strong>"
+
+#: views/addons/home.thtml:161
+msgid "addons_home_new_indicator"
+msgstr "Novità"
+
+#: views/elements/app_chooser.thtml:48
+#: views/layouts/amo2009.thtml:257
+msgid "addons_home_other_applications"
+msgstr "Altre applicazioni"
+
+#. %1$s is the application the user is browsing. Examples: Thunderbird, Firefox,
+#. Sunbird
+#: views/pages/collector_faq.thtml:49
+#: views/pages/collector_firstrun.thtml:42
+#: views/pages/collector.thtml:46
+#: views/pages/collector_features.thtml:54
+#: controllers/developers_controller.php:87
+#: controllers/compatibility_controller.php:72
+#: controllers/components/simple_acl.php:81
+#: controllers/components/amo.php:607
+#: controllers/statistics_controller.php:60
+#: controllers/statistics_controller.php:240
+#: controllers/previews_controller.php:67
+#: controllers/users_controller.php:90
+#: controllers/users_controller.php:223
+#: controllers/users_controller.php:330
+#: controllers/users_controller.php:414
+#: controllers/users_controller.php:708
+#: controllers/users_controller.php:723
+#: controllers/reviews_controller.php:204
+#: controllers/reviews_controller.php:251
+#: controllers/reviews_controller.php:346
+#: controllers/reviews_controller.php:425
+#: controllers/search_controller.php:185
+#: controllers/search_controller.php:297
+#: controllers/search_controller.php:301
+#: controllers/addons_controller.php:147
+#: controllers/addons_controller.php:280
+#: controllers/addons_controller.php:370
+#: controllers/addons_controller.php:667
+#: controllers/addons_controller.php:874
+#: controllers/addons_controller.php:1019
+#: controllers/addons_controller.php:1034
+#: controllers/addons_controller.php:1101
+#: controllers/addons_controller.php:1121
+#: controllers/addons_controller.php:1240
+#: controllers/addons_controller.php:1357
+#: controllers/addons_controller.php:1364
+#: controllers/addons_controller.php:1442
+#: controllers/addons_controller.php:1477
+#: controllers/addons_controller.php:1538
+#: controllers/addons_controller.php:1543
+#: controllers/editors_controller.php:64
+#: controllers/pages_controller.php:132
+#: controllers/groups_controller.php:65
+#: controllers/groups_controller.php:71
+#: controllers/groups_controller.php:89
+#: controllers/groups_controller.php:111
+#: controllers/collections_controller.php:57
+#: controllers/collections_controller.php:121
+#: controllers/collections_controller.php:205
+#: controllers/collections_controller.php:365
+#: controllers/collections_controller.php:404
+#: controllers/collections_controller.php:466
+#: controllers/collections_controller.php:538
+#: controllers/collections_controller.php:828
+#: controllers/localizers_controller.php:72
+#, php-format
+msgid "addons_home_pagetitle"
+msgstr "Componenti aggiuntivi per %1$s"
+
+#. %1$s is the number of addons downloaded
+#: views/addons/home.thtml:57
+#, php-format
+msgid "addons_home_stats_downloaded"
+msgid_plural "addons_home_stats_downloaded"
+msgstr[0] "<strong>%1$s</strong> <span>componente aggiuntivo scaricato</span>"
+msgstr[1] "<strong>%1$s</strong> <span>componenti aggiuntivi scaricati</span>"
+
+#. %1$s is the number of addons in use
+#: views/addons/home.thtml:63
+#, php-format
+msgid "addons_home_stats_inuse"
+msgid_plural "addons_home_stats_inuse"
+msgstr[0] "<strong>%1$s</strong> <span>componente aggiuntivo in uso</span>"
+msgstr[1] "<strong>%1$s</strong> <span>componenti aggiuntivi in uso</span>"
+
+#: views/addons/home.thtml:136
+msgid "addons_home_view_all_newest_title"
+msgstr "Visualizza tutti i nuovi componenti aggiuntivi"
+
+#: views/addons/home.thtml:129
+msgid "addons_home_view_all_popular_title"
+msgstr "Visualizza tutti i componenti aggiuntivi più popolari"
+
+#: views/addons/home.thtml:150
+msgid "addons_home_view_all_recommended_title"
+msgstr "Visualizza tutti i componenti aggiuntivi consigliati"
+
+#: views/addons/home.thtml:143
+msgid "addons_home_view_all_updated_title"
+msgstr "Visualizza tutti i componenti aggiuntivi aggiornati di recente"
+
+#: views/elements/amo2009/install.thtml:334
+#: views/elements/install.thtml:112
+msgid "addons_install_in_sunbird"
+msgstr "<ol><li>Fare clic sul link seguente per salvare il file.</li><li>In Mozilla Sunbird selezionare Componenti aggiuntivi dal menu Strumenti.</li><li>Fare clic sul pulsante Installa, individuare il file scaricato e fare clic su \"OK\".</li></ol>"
+
+#: views/elements/amo2009/install.thtml:333
+#: views/elements/install.thtml:111
+msgid "addons_install_in_sunbird_title"
+msgstr "Come installare in Sunbird"
+
+#: views/elements/amo2009/install.thtml:331
+#: views/elements/install.thtml:106
+msgid "addons_install_in_thunderbird"
+msgstr "<ol><li>Fai clic con il tasto destro sul collegamento seguente e seleziona \"Salva destinazione con nome…\" per scaricare il file sul tuo disco fisso.</li><li>In Mozilla Thunderbird seleziona Componenti aggiuntivi nel menu Strumenti.</li><li>Fai clic sul pulsante Installa, seleziona il file scaricato in precedenza e premi \"OK\".</li></ol>"
+
+#: views/elements/amo2009/install.thtml:330
+#: views/elements/install.thtml:105
+msgid "addons_install_in_thunderbird_title"
+msgstr "Come installare componenti aggiuntivi in Thunderbird"
+
+#: views/elements/amo2009/addon_list_options.thtml:108
+#: views/elements/addon_list_options.thtml:105
+msgid "addons_options_show_experimental"
+msgstr "Visualizza i componenti aggiuntivi sperimentali"
+
+#: views/elements/amo2009/addon_list_options.thtml:113
+#: views/elements/addon_list_options.thtml:109
+msgid "addons_options_submit"
+msgstr "Vai"
+
+#: views/addons/plugins.thtml:63
+#: views/addons/plugins.thtml:73
+#: views/addons/plugins.thtml:83
+#: views/addons/plugins.thtml:93
+#: views/addons/plugins.thtml:103
+#: views/addons/plugins.thtml:116
+#: views/addons/plugins.thtml:126
+msgid "addons_plugins_by"
+msgstr "Di"
+
+#: views/addons/plugins.thtml:107
+msgid "addons_plugins_for_linux"
+msgstr "per Linux"
+
+#: views/addons/plugins.thtml:108
+#: views/addons/plugins.thtml:131
+msgid "addons_plugins_for_macosx"
+msgstr "per Mac OS X"
+
+#: views/addons/plugins.thtml:106
+#: views/addons/plugins.thtml:129
+#: views/addons/plugins.thtml:130
+msgid "addons_plugins_for_windows"
+msgstr "per Windows"
+
+#. %1$s is a URL
+#: views/addons/plugins.thtml:139
+#, php-format
+msgid "addons_plugins_looking_for_more"
+msgstr "Questa pagina contiene un elenco dei plugin più comuni e popolari. Per ulteriori informazioni sugli altri plugin disponibili per i browser basati su Mozilla, visita %1$s"
+
+#: views/addons/plugins.thtml:137
+msgid "addons_plugins_looking_for_plugin"
+msgstr "Stai cercando un plugin che non risulta tra quelli disponibili?"
+
+#: views/addons/plugins.thtml:58
+msgid "addons_plugins_main_description"
+msgstr "I plugin consentono al browser di eseguire operazioni specifiche come visualizzare determinati formati grafici oppure riprodurre file multimediali. I plugin sono leggermente diversi dalle estensioni, in grado di modificare o aggiungere nuove funzionalità al software."
+
+#. %1$s is the application name. Example: Firefox, Thunderbird, Sunbird
+#: controllers/addons_controller.php:1122
+#, php-format
+msgid "addons_plugins_main_header"
+msgstr "Plugin più comuni per %1$s"
+
+#: controllers/components/amo.php:698
+#: controllers/addons_controller.php:1121
+msgid "addons_plugins_pagetitle"
+msgstr "Plugin"
+
+#: views/addons/plugins.thtml:68
+#: views/addons/plugins.thtml:78
+#: views/addons/plugins.thtml:88
+#: views/addons/plugins.thtml:98
+#: views/addons/plugins.thtml:110
+#: views/addons/plugins.thtml:121
+#: views/addons/plugins.thtml:133
+msgid "addons_plugins_support_documentation"
+msgstr "Documentazione di supporto: "
+
+#. %s is the name of the add-on
+#: views/addons/policy.thtml:61
+#, php-format
+msgid "addons_policy_eula_require"
+msgstr "%s richiede l'accettazione della seguente End User License Agreement (accordo di licenza con l'utente finale) prima di procedere con l'installazione:"
+
+#. %1 is the add-on name
+#: controllers/addons_controller.php:1476
+#, php-format
+msgid "addons_previews_pagetitle"
+msgstr "Anteprime per %s"
+
+#: views/addons/category_landing.thtml:135
+msgid "addons_recently_added"
+msgstr "Aggiunto di recente"
+
+#: views/addons/recommended.thtml:51
+#: controllers/addons_controller.php:1365
+msgid "addons_recommended_introduction"
+msgstr "Con una simile varietà di straordinari componenti aggiuntivi c'è sicuramente qualcosa di interessante per tutti. Per cominciare ecco un elenco dei più popolari. Divertiti!"
+
+#: controllers/addons_controller.php:1357
+#: controllers/addons_controller.php:1364
+msgid "addons_recommended_pagetitle"
+msgstr "Componenti aggiuntivi consigliati"
+
+#: controllers/addons_controller.php:1360
+msgid "addons_recommended_title"
+msgstr "consigliati da noi"
+
+#: views/addons/searchengines.thtml:136
+msgid "addons_searchengines_additional_resources"
+msgstr "Risorse aggiuntive"
+
+#. link text devmo
+#: views/addons/searchengines.thtml:141
+msgid "addons_searchengines_devmo_link"
+msgstr "Mozilla Developer Center"
+
+#: views/pages/js_constants.js.thtml:67
+msgid "addons_searchengines_error_mozilla_browser_required"
+msgstr "Spiacente, bisogna utilizzare un browser basato su Mozilla (come Firefox) per poter installare un motore di ricerca."
+
+#: views/addons/searchengines.thtml:49
+msgid "addons_searchengines_error_nojavascript"
+msgstr "JavaScript deve essere attivo per installare un motore di ricerca e sembra che sia stato disattivato. Attivare JavaScript prima di tentare l'installazione di uno dei plugin di ricerca disponibili."
+
+#. %1 is "make your own" link
+#. %2 is MDC link
+#: views/addons/searchengines.thtml:139
+msgid "addons_searchengines_learn_howto"
+msgstr "Scopri come %1$s nel %2$s."
+
+#. link path to search plugins instructions, relative to devmo
+#: views/addons/searchengines.thtml:140
+msgid "addons_searchengines_makeyourown_href"
+msgstr "/en/docs/Creating_OpenSearch_plugins_for_Firefox"
+
+#. link text for "make your own" (opensearch engine)
+#: views/addons/searchengines.thtml:140
+msgid "addons_searchengines_makeyourown_link"
+msgstr "realizzare il tuo"
+
+#. %1 is the link to mycroft.mozdev.org
+#: views/addons/searchengines.thtml:138
+msgid "addons_searchengines_more"
+msgstr "Scopri altri motori di ricerca su %1$s"
+
+#. link text to mycroft.mozdev.org
+#: views/addons/searchengines.thtml:138
+msgid "addons_searchengines_mycroft_link"
+msgstr "mycroft.mozdev.org"
+
+#: controllers/addons_controller.php:1100
+#: controllers/addons_controller.php:1110
+msgid "addons_searchengines_pagetitle"
+msgstr "Motori di ricerca"
+
+#: views/addons/searchengines.thtml:143
+msgid "addons_searchengines_thanks"
+msgstr "Un ringraziamento speciale al progetto Mycroft per il lavoro sui motori di ricerca di Firefox."
+
+#: views/addons/display.thtml:154
+msgid "addons_share_button_text"
+msgstr "Condividi"
+
+#: controllers/addons_controller.php:89
+msgid "addons_share_label_delicious"
+msgstr "Delicious"
+
+#: controllers/addons_controller.php:77
+msgid "addons_share_label_digg"
+msgstr "Digg"
+
+#: controllers/addons_controller.php:83
+msgid "addons_share_label_facebook"
+msgstr "Facebook"
+
+#: controllers/addons_controller.php:101
+msgid "addons_share_label_friendfeed"
+msgstr "FriendFeed"
+
+#: controllers/addons_controller.php:95
+msgid "addons_share_label_myspace"
+msgstr "MySpace"
+
+#: controllers/components/amo.php:201
+#: controllers/components/amo.php:229
+msgid "addons_status_disabled"
+msgstr "Disattivato"
+
+#: controllers/components/amo.php:191
+#: controllers/components/amo.php:224
+msgid "addons_status_incomplete"
+msgstr "Versione incompleta"
+
+#: controllers/components/amo.php:197
+#: controllers/components/amo.php:227
+msgid "addons_status_nominated"
+msgstr "Nella Sandbox; segnalato"
+
+#: views/pages/js_constants.js.thtml:80
+#: controllers/components/amo.php:195
+#: controllers/components/amo.php:226
+msgid "addons_status_pending"
+msgstr "Nella Sandbox; in attesa di revisione"
+
+#: views/pages/js_constants.js.thtml:78
+#: controllers/components/amo.php:199
+#: controllers/components/amo.php:228
+msgid "addons_status_public"
+msgstr "pubblicato"
+
+#: views/pages/js_constants.js.thtml:79
+#: controllers/components/amo.php:193
+#: controllers/components/amo.php:225
+msgid "addons_status_sandbox"
+msgstr "Nella Sandbox"
+
+#: controllers/components/amo.php:203
+msgid "addons_status_unknown"
+msgstr "Sconosciuto"
+
+#: views/elements/amo2009/teaser_collections.thtml:91
+#: views/elements/amo2009/homepage_addon.thtml:99
+#: views/elements/feature.thtml:94
+msgid "addons_title_tooltip"
+msgstr "Scopri ulteriori informazioni su questo componente aggiuntivo"
+
+#: views/addons/category_landing.thtml:151
+msgid "addons_top_downloads"
+msgstr "I più scaricati"
+
+#: views/addons/category_landing.thtml:165
+msgid "addons_top_rated"
+msgstr "I più votati"
+
+#: views/addons/versions.thtml:62
+msgid "addons_versions_careful"
+msgstr "Attenzione alle vecchie versioni"
+
+#: views/addons/versions.thtml:63
+msgid "addons_versions_careful_introduction"
+msgstr "Queste versioni sono visualizzate solo a scopo di test e archivio. Dovresti sempre utilizzare l'ultima versione disponibile di un componente aggiuntivo."
+
+#: controllers/addons_controller.php:1549
+msgid "addons_versions_history"
+msgstr "Cronologia delle versioni con elenco delle modifiche (changelog)"
+
+#. %1$s is the add-on name
+#: controllers/addons_controller.php:1535
+#, php-format
+msgid "addons_versions_pagetitle"
+msgstr "%1$s cronologia delle versioni"
+
+#: controllers/groups_controller.php:71
+msgid "admin_group_add_pagetitle"
+msgstr "Aggiungi gruppo"
+
+#: controllers/groups_controller.php:111
+msgid "admin_group_delete_pagetitle"
+msgstr "Elimina gruppo"
+
+#. %s is a number to identify the group
+#: controllers/groups_controller.php:117
+#, php-format
+msgid "admin_group_deleted"
+msgstr "Il gruppo con ID %s è stato eliminato"
+
+#: controllers/groups_controller.php:89
+msgid "admin_group_edit_pagetitle"
+msgstr "Modifica gruppo"
+
+#: controllers/groups_controller.php:92
+#: controllers/groups_controller.php:113
+msgid "admin_group_error_invalid_id"
+msgstr "ID non valido per il gruppo"
+
+#: controllers/groups_controller.php:65
+msgid "admin_group_pagetitle"
+msgstr "Amministratore del gruppo"
+
+#: controllers/groups_controller.php:77
+#: controllers/groups_controller.php:99
+msgid "admin_group_saved"
+msgstr "Il gruppo è stato salvato"
+
+#: views/elements/amo2009/search.thtml:257
+#: views/elements/search.thtml:239
+msgid "advanced_search_form"
+msgstr "Avanzata"
+
+#: views/elements/amo2009/search.thtml:126
+#: views/elements/search.thtml:125
+msgid "advanced_search_form_any_time"
+msgstr "qualsiasi periodo"
+
+#: views/elements/amo2009/search.thtml:97
+#: views/elements/amo2009/search.thtml:110
+#: views/elements/search.thtml:96
+#: views/elements/search.thtml:109
+msgid "advanced_search_form_any_type"
+msgstr "qualsiasi"
+
+#: views/elements/amo2009/search.thtml:275
+#: views/elements/search.thtml:254
+msgid "advanced_search_form_any_version"
+msgstr "qualsiasi"
+
+#: views/elements/amo2009/search.thtml:217
+#: views/elements/search.thtml:212
+msgid "advanced_search_form_application"
+msgstr "Applicazione"
+
+#: views/elements/amo2009/search.thtml:143
+#: views/elements/search.thtml:142
+msgid "advanced_search_form_keyword_match"
+msgstr "corrispondenza"
+
+#: views/elements/amo2009/search.thtml:251
+#: views/elements/search.thtml:225
+msgid "advanced_search_form_lastupdate"
+msgstr "Ultimo aggiornamento"
+
+#: views/elements/amo2009/search.thtml:145
+#: views/elements/search.thtml:144
+msgid "advanced_search_form_name"
+msgstr "nome"
+
+#: views/elements/amo2009/search.thtml:144
+#: views/elements/search.thtml:143
+msgid "advanced_search_form_newest"
+msgstr "più recente"
+
+#: views/elements/amo2009/search.thtml:130
+#: views/elements/search.thtml:129
+msgid "advanced_search_form_past_3_months"
+msgstr "ultimi 3 mesi"
+
+#: views/elements/amo2009/search.thtml:131
+#: views/elements/search.thtml:130
+msgid "advanced_search_form_past_6_months"
+msgstr "ultimi 6 mesi"
+
+#: views/elements/amo2009/search.thtml:127
+#: views/elements/search.thtml:126
+msgid "advanced_search_form_past_day"
+msgstr "ultime 24 ore"
+
+#: views/elements/amo2009/search.thtml:129
+#: views/elements/search.thtml:128
+msgid "advanced_search_form_past_month"
+msgstr "ultimo mese"
+
+#: views/elements/amo2009/search.thtml:128
+#: views/elements/search.thtml:127
+msgid "advanced_search_form_past_week"
+msgstr "ultima settimana"
+
+#: views/elements/amo2009/search.thtml:132
+#: views/elements/search.thtml:131
+msgid "advanced_search_form_past_year"
+msgstr "ultimo anno"
+
+#: views/elements/amo2009/search.thtml:239
+#: views/elements/search.thtml:230
+msgid "advanced_search_form_perpage"
+msgstr "Per pagina"
+
+#: views/elements/amo2009/search.thtml:243
+#: views/elements/search.thtml:224
+msgid "advanced_search_form_platform"
+msgstr "Piattaforma"
+
+#: views/elements/amo2009/search.thtml:147
+#: views/elements/search.thtml:146
+msgid "advanced_search_form_popularity"
+msgstr "popolarità"
+
+#: views/elements/amo2009/search.thtml:146
+#: views/elements/search.thtml:145
+msgid "advanced_search_form_rating"
+msgstr "voto"
+
+#: views/elements/amo2009/search.thtml:247
+#: views/elements/search.thtml:231
+msgid "advanced_search_form_sortby"
+msgstr "Ordina per"
+
+#: views/elements/amo2009/search.thtml:227
+#: views/elements/search.thtml:216
+msgid "advanced_search_form_to"
+msgstr "a"
+
+#: views/elements/amo2009/search.thtml:257
+#: views/elements/search.thtml:237
+msgid "advanced_search_form_toggle_tooltip"
+msgstr "Attiva la ricerca avanzata"
+
+#: views/elements/amo2009/search.thtml:235
+#: views/elements/search.thtml:223
+msgid "advanced_search_form_type"
+msgstr "Tipo"
+
+#: views/elements/amo2009/search.thtml:222
+#: views/elements/search.thtml:214
+msgid "advanced_search_form_version"
+msgstr "versione"
+
+#: views/elements/amo2009/pagination.thtml:42
+msgid "amo2009_pagination_next_page"
+msgstr "Successivo"
+
+#: views/elements/amo2009/pagination.thtml:41
+msgid "amo2009_pagination_previous_page"
+msgstr "Precedente"
+
+#: views/pages/js_constants.js.thtml:96
+msgid "app_compat_ignore_check"
+msgstr "Ignora i controlli di compatibilità"
+
+#: views/pages/js_constants.js.thtml:72
+msgid "app_compat_older_firefox_only"
+msgstr "Questo componente aggiuntivo è compatibile con le versioni precedenti di Firefox"
+
+#. %1$s and %2$s are URLs
+#: views/pages/js_constants.js.thtml:74
+msgid "app_compat_older_version_or_ignore_check"
+msgstr "È possibile <a href=\"%1$s\">provare una vecchia versione</a> oppure <a href=\"#\" onclick=\"%2$s\">ignorare questo controllo</a>"
+
+#. %1$s is a URL
+#: views/pages/js_constants.js.thtml:71
+msgid "app_compat_try_old_version"
+msgstr "Una <a href=\"%1$s\">versione precedente</a> potrebbe funzionare"
+
+#. %1$s is a URL
+#. %2$s is a version number. Example: 3.1
+#: views/pages/js_constants.js.thtml:73
+msgid "app_compat_unreleased_version"
+msgstr "Questo componente aggiuntivo richiede una versione di <a href=\"%1$s\">Firefox %2$s</a> non ancora rilasciata"
+
+#: views/pages/js_constants.js.thtml:70
+msgid "app_compat_update_firefox"
+msgstr "<a href=\"http://getfirefox.com\">Aggiorna Firefox</a> per utilizzare questo componente aggiuntivo"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#. %3$s is a status, like Public.
+#: controllers/components/audit.php:79
+msgid "audit_addon_status"
+msgstr "%1$s ha modificato in %3$s lo stato di %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:221
+msgid "audit_admin_default"
+msgstr "%1$s ha eseguito un'azione amministrativa sconosciuta %2$s all'elemento con ID %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:153
+msgid "audit_admin_feature_remove"
+msgstr "%1$s ha eliminato la funzione %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is an application, like Firefox.
+#: controllers/components/audit.php:92
+msgid "audit_application_create"
+msgstr "%1$s ha creato l'applicazione %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is an application, like Firefox.
+#: controllers/components/audit.php:95
+msgid "audit_application_edit"
+msgstr "%1$s ha modificato l'applicazione %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a version number, like 3.5.
+#. %3$s is an application, like Firefox.
+#: controllers/components/audit.php:105
+msgid "audit_appversion_create"
+msgstr "%1$s ha creato la versione %2$s per %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a version number, like 3.5.
+#. %3$s is an application, like Firefox.
+#: controllers/components/audit.php:108
+msgid "audit_appversion_delete"
+msgstr "%1$s ha eliminato la versione %2$s per %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a config field, like "awesomeness".
+#. %3$s is a config value, like "off".
+#. %4$s is a config value, like "on".
+#: controllers/components/audit.php:210
+msgid "audit_config"
+msgstr "%1$s ha modificato il parametro '%2$s' da '%3$s' a '%4$s'"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:258
+msgid "audit_editor_default"
+msgstr "%1$s ha eseguito un'azione di revisione sconosciuto %2$s all'elemento con ID %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#: controllers/components/audit.php:236
+msgid "audit_editor_feature_remove"
+msgstr "%1$s ha eliminato %2$s dall'elenco dei componenti consigliati"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#: controllers/components/audit.php:231
+msgid "audit_feature_add"
+msgstr "%1$s ha aggiunto %2$s all'elenco dei componenti consigliati"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:149
+msgid "audit_feature_edit"
+msgstr "%1$s ha modificato una funzione per il locale %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#: controllers/components/audit.php:241
+msgid "audit_feature_locale_change"
+msgstr "%1$s ha modificato i locale per %2$s nella lista dei componenti consigliati"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:83
+msgid "audit_file_recalchash"
+msgstr "%1$s ha ricalcolato l'hash per il file %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>user name</a>
+#. %3$s is <a>group name</a>
+#: controllers/components/audit.php:182
+msgid "audit_group_addmember"
+msgstr "%1$s ha aggiunto %2$s al gruppo %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:313
+msgid "audit_group_associated"
+msgstr "%1$s si è aggiunto al gruppo %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:162
+msgid "audit_group_create"
+msgstr "%1s ha creato il gruppo %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:170
+msgid "audit_group_delete"
+msgstr "%1$s ha eliminato il gruppo %2$s (ID %3$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:165
+msgid "audit_group_edit"
+msgstr "%1$s ha modificato il gruppo %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>user name</a>
+#. %3$s is <a>group name</a>
+#: controllers/components/audit.php:188
+msgid "audit_group_removemember"
+msgstr "%1$s ha eliminato %2$s dal gruppo %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:280
+msgid "audit_l10n_default"
+msgstr "%1$s ha eseguito un'azione sconosciuta %2$s per %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:295
+msgid "audit_modify_locked_group"
+msgstr "%1$s ha cercato di modificare il gruppo bloccato %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:299
+msgid "audit_modify_other_locale"
+msgstr "%1$s ha cercato di modificare le traduzioni in %2$s senza averne i permessi"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a platform, like <a>Windows</a>
+#: controllers/components/audit.php:135
+msgid "audit_platform_create"
+msgstr "%1$s ha creato la piattaforma %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a platform, like <a>Windows</a>
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:143
+msgid "audit_platform_delete"
+msgstr "%1$s da eliminato la piattaforma %2$s (ID %3$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a platform, like <a>Windows</a>
+#: controllers/components/audit.php:138
+msgid "audit_platform_edit"
+msgstr "%1$s ha modificato la piattaforma %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a part of the admin, like 'Site Config'
+#: controllers/components/audit.php:288
+msgid "audit_reauthentication_failure"
+msgstr "%1$s non è riuscito a rieffettuare l'autenticazione per l'accesso a %2$s."
+
+#. %1$s is <a>user name</a>
+#. %2$s is the name of a canned response, like 'Ready for the public'
+#: controllers/components/audit.php:198
+msgid "audit_response_create"
+msgstr "%1$s ha creato la risposta %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is the name of a canned response, like 'Ready for the public'
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:206
+msgid "audit_response_delete"
+msgstr "%1$s ha eliminato la risposta %2$s (ID %3$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is the name of a canned response, like 'Ready for the public'
+#: controllers/components/audit.php:201
+msgid "audit_response_edit"
+msgstr "%1$s ha modificato la risposta %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:245
+msgid "audit_review_approve"
+msgstr "%1$s ha approvato la recensione %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:250
+#: controllers/components/audit.php:253
+msgid "audit_review_delete"
+msgstr "%1$s ha eliminato la recensione %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:303
+msgid "audit_security_default"
+msgstr "%1$s ha eseguito un'azione di sicurezza sconosciuta %2$s sull'elemento con ID %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a category name, like <a>Search Tools</a>
+#: controllers/components/audit.php:118
+msgid "audit_tag_create"
+msgstr "%1$s ha creato l'etichetta %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a category name, like <a>Search Tools</a>
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:126
+msgid "audit_tag_delete"
+msgstr "%1$s ha eliminato la categoria %2$s (ID %3$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a category name, like <a>Search Tools</a>
+#: controllers/components/audit.php:121
+msgid "audit_tag_edit"
+msgstr "%1$s ha modificato la categoria %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:266
+msgid "audit_update_applications"
+msgstr "%1$s ha aggiornato la traduzione delle applicazioni per %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:277
+msgid "audit_update_blog"
+msgstr "%1$s ha aggiornato la traduzione del post sul blog per %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:274
+msgid "audit_update_platforms"
+msgstr "%1$s ha aggiornato la traduzione delle piattaforme per %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:270
+msgid "audit_update_tags"
+msgstr "%1$s ha aggiornato la traduzione delle categorie per %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>user name</a>
+#: controllers/components/audit.php:217
+msgid "audit_user_edit"
+msgstr "%1$s ha modificato le informazioni utente di %2$s"
+
+#: controllers/addons_controller.php:1012
+msgid "browse_addons_name"
+msgstr "componenti per nome"
+
+#: controllers/addons_controller.php:1010
+msgid "browse_addons_newest"
+msgstr "i nuovi arrivi"
+
+#: controllers/addons_controller.php:1008
+msgid "browse_addons_popular"
+msgstr "i più popolari"
+
+#: controllers/addons_controller.php:1011
+msgid "browse_addons_rated"
+msgstr "componenti per voto"
+
+#: controllers/addons_controller.php:1009
+msgid "browse_addons_updated"
+msgstr "ultimi aggiornamenti"
+
+#: views/elements/categories.thtml:73
+#: views/elements/categories.thtml:82
+msgid "categories_current_title"
+msgstr "Categoria corrente"
+
+#: views/elements/categories.thtml:50
+#: views/elements/amo2009/categories.thtml:43
+#: views/elements/amo2009/categories.thtml:45
+msgid "categories_header"
+msgstr "Categorie"
+
+#: views/elements/categories.thtml:50
+#: views/elements/amo2009/categories.thtml:41
+msgid "categories_header_title"
+msgstr "Scegliere una categoria"
+
+#. %1$s is the category name
+#: views/addons/searchengines.thtml:129
+#, php-format
+msgid "category_extra_see_all"
+msgstr "Visualizza tutti %1$s"
+
+#. %1$s is a number.
+#: models/collection.php:130
+msgid "collection_description_limit"
+msgstr "La descrizione deve essere lunga meno di %1$s caratteri."
+
+#. %1$s is the name of the collection
+#: controllers/collections_controller.php:392
+msgid "collection_detail_rss_title"
+msgstr "Raccolta %s"
+
+#: controllers/collections_controller.php:1065
+msgid "collection_error_deleting_addon"
+msgstr "Errore durante l'eliminazione del componente aggiuntivo"
+
+#: controllers/collections_controller.php:1051
+msgid "collection_error_saving_addon"
+msgstr "Errore durante il salvataggio del componente aggiuntivo"
+
+#: controllers/collections_controller.php:1080
+msgid "collection_error_saving_comment"
+msgstr "Errore durante il salvataggio del commento"
+
+#. %1$s is a number.
+#: models/collection.php:122
+msgid "collection_name_limit"
+msgstr "La lunghezza del nome deve essere inferiore a %1$s caratteri."
+
+#: controllers/collections_controller.php:352
+#: controllers/collections_controller.php:487
+msgid "collection_not_found"
+msgstr "Raccolta non trovata!"
+
+#. %1$s is the text on the "create collection" button
+#: views/collections/add.thtml:91
+msgid "collections_add_formfield_addons_description"
+msgstr "Se sai già quali componenti aggiuntivi inserire nella tua raccolta, inizia ad inserire i nome nel campo seguenti. Se preferisci farlo in un secondo momento, fai clic su %1$s."
+
+#: views/collections/add.thtml:90
+msgid "collections_add_formfield_firstaddons"
+msgstr "Scegli il primo componente aggiuntivo"
+
+#: views/collections/add.thtml:48
+msgid "collections_add_header"
+msgstr "Crea una raccolta"
+
+#: views/collections/add.thtml:97
+msgid "collections_add_header_selectedaddons"
+msgstr "Componenti selezionati"
+
+#: views/collections/add.thtml:50
+msgid "collections_add_intro"
+msgstr "Per creare la tua raccolta di componenti aggiuntivi è sufficiente compilare i seguenti campi."
+
+#: views/collections/add.thtml:92
+#: views/collections/add.thtml:103
+msgid "collections_add_submit"
+msgstr "Crea raccolta"
+
+#: views/pages/collector_faq.thtml:50
+#: views/pages/collector_firstrun.thtml:43
+#: views/pages/collector.thtml:47
+#: views/pages/collector_features.thtml:55
+#: controllers/search_controller.php:302
+#: controllers/collections_controller.php:206
+#: controllers/collections_controller.php:405
+#: controllers/collections_controller.php:467
+#: controllers/collections_controller.php:539
+msgid "collections_breadcrumb"
+msgstr "Raccolte"
+
+#: views/collections/detail.thtml:185
+msgid "collections_detail_a_learn"
+msgstr "Ulteriori informazioni"
+
+#: views/elements/amo2009/collection_add_form.thtml:53
+#: views/elements/amo2009/collections_js_init.thtml:68
+#: views/pages/collector_firstrun.thtml:64
+msgid "collections_detail_button_add"
+msgstr "Aggiungi ai preferiti"
+
+#: views/elements/amo2009/collection_add_form.thtml:50
+#: views/elements/amo2009/collections_js_init.thtml:71
+msgid "collections_detail_button_remove"
+msgstr "Rimuovi dai preferiti"
+
+#. %1$s is a URL.
+#. %2$s is a full <a href>.
+#: views/collections/detail.thtml:62
+msgid "collections_detail_created_desc"
+msgstr "<p>In questa sezione puoi visualizzare le tue raccolte. Se vuoi impostare uno pseudonimo, caricare un'immagine o modificare altre impostazioni, consulta la pagina <a href='%1$s'>Gestione raccolte</a>.</p><p>La tua raccolta può essere visualizzata a questo indirizzo: %2$s</p>"
+
+#: views/collections/detail.thtml:61
+msgid "collections_detail_created_msg"
+msgstr "La tua raccolta è pronta"
+
+#: views/collections/detail.thtml:109
+msgid "collections_detail_header_about"
+msgstr "Informazioni su questa raccolta"
+
+#. %1$s is a number.
+#: views/collections/detail.thtml:126
+msgid "collections_detail_header_count"
+msgid_plural "collections_detail_header_count"
+msgstr[0] "%1$s elemento in questa raccolta"
+msgstr[1] "%1$s elementi in questa raccolta"
+
+#: views/collections/detail.thtml:113
+msgid "collections_detail_info_created"
+msgstr "<strong>Realizzata da:</strong> %1$s"
+
+#: views/collections/detail.thtml:117
+msgid "collections_detail_info_updated"
+msgstr "<strong>Aggiornata:</strong>"
+
+#: views/elements/amo2009/collections_js_init.thtml:62
+msgid "collections_detail_js_adding"
+msgstr "Inserimento in corso nei preferiti&hellip;"
+
+#: views/elements/amo2009/collections_js_init.thtml:65
+msgid "collections_detail_js_removing"
+msgstr "Rimozione in corso dai preferiti&hellip;"
+
+#. %1$s is a URL
+#: views/collections/detail.thtml:90
+msgid "collections_detail_login"
+msgstr "<a href=\"%1$s\">Accedi</a> per aggiungere questa raccolta ai tuoi preferiti."
+
+#: views/collections/detail.thtml:104
+msgid "collections_detail_manage"
+msgstr "Gestione raccolte"
+
+#: controllers/collections_controller.php:298
+msgid "collections_detail_sort_date"
+msgstr "Data inserimento"
+
+#: controllers/collections_controller.php:299
+msgid "collections_detail_sort_name"
+msgstr "Nome"
+
+#: controllers/collections_controller.php:300
+msgid "collections_detail_sort_popularity"
+msgstr "Popolarità"
+
+#. %1$s is a number.
+#: views/collections/detail.thtml:166
+msgid "collections_detail_weekly_downloads"
+msgid_plural "collections_detail_weekly_downloads"
+msgstr[0] "%1$s download questa settimana"
+msgstr[1] "%1$s download questa settimana"
+
+#: views/collections/edit.thtml:255
+msgid "collections_edit_addons_delete_noscript"
+msgstr "I componenti aggiuntivi selezionati verranno rimossi in fase di salvataggio"
+
+#: views/collections/edit.thtml:247
+msgid "collections_edit_addons_description"
+msgstr "Per aggiungere nuovi componenti aggiuntivi a questa raccolta, digitarne i nomi nel campo seguente."
+
+#: views/collections/edit.thtml:248
+msgid "collections_edit_addons_description_noscript"
+msgstr "Per pubblicare nuovi elementi in questa raccolta, inserisci un elenco di ID dei componenti aggiuntivi separandoli con delle virgole."
+
+#: views/collections/edit.thtml:247
+#: views/collections/edit.thtml:248
+msgid "collections_edit_addons_description_publish_detailspage"
+msgstr "È possibile pubblicare un componente aggiuntivo anche dalla sua scheda."
+
+#. %1$s is the date the add-on was added to the collection
+#. %1$s is the name of the user who added the add-on to the collection
+#: views/collections/edit.thtml:260
+msgid "collections_edit_addons_listitem_added"
+msgstr "Aggiunto il %1$s da %2$s"
+
+#: views/collections/edit.thtml:263
+msgid "collections_edit_addons_listitem_comment_add"
+msgstr "Aggiungi commento"
+
+#: views/collections/edit.thtml:266
+msgid "collections_edit_addons_listitem_comment_delete"
+msgstr "Elimina commento"
+
+#: views/collections/edit.thtml:265
+msgid "collections_edit_addons_listitem_comment_edit"
+msgstr "Modificato commento"
+
+#: views/collections/edit.thtml:271
+msgid "collections_edit_addons_listitem_comment_note"
+msgstr "Nota: il commento risulterà scritto dall'autore originale della raccolta nella data di pubblicazione della raccolta stessa"
+
+#: views/collections/edit.thtml:270
+msgid "collections_edit_addons_listitem_comment_submit"
+msgstr "Salva commento"
+
+#: views/collections/edit.thtml:261
+msgid "collections_edit_addons_listitem_remove"
+msgstr "Rimuovi"
+
+#: views/collections/edit.thtml:250
+msgid "collections_edit_addons_submit"
+msgstr "Aggiungi ad una raccolta"
+
+#: views/collections/edit.thtml:153
+msgid "collections_edit_check_nickname"
+msgstr "Controlla disponibilità"
+
+#: views/collections/edit.thtml:299
+msgid "collections_edit_confirm_deletecollection"
+msgstr "Sì, voglio eliminare questa raccolta."
+
+#. %1$s is the label of the edit form's submit button
+#: views/collections/edit.thtml:300
+msgid "collections_edit_confirm_deletecollection_description"
+msgstr "Selezionare la casella e fare clic su \"%1$s\" per eliminare questa raccolta."
+
+#. %1$s is the "delete" submit button text
+#. %2$s is the title of the "advanced" tab
+#: views/collections/edit.thtml:95
+msgid "collections_edit_delete_upon_submit"
+msgstr "Facendo clic su \"%1$s\", la raccolta verrà eliminata. Se non vuoi eliminare la tua raccolta, disattiva l'opzione nella scheda \"%2$s\" e prosegui con le modifiche. Se abbandoni questa pagina senza salvare, la raccolta non verrà eliminata."
+
+#: views/collections/edit.thtml:94
+msgid "collections_edit_delete_warning"
+msgstr "Questa raccolta sta per essere eliminata."
+
+#: views/collections/add.thtml:76
+#: views/collections/edit.thtml:144
+msgid "collections_edit_form_error_description"
+msgstr "La descrizione della raccolta è un campo obbligatorio."
+
+#: views/collections/edit.thtml:181
+msgid "collections_edit_form_error_icon"
+msgstr "Si è verificato un errore durante il caricamento dell'immagine."
+
+#: views/collections/add.thtml:69
+#: views/collections/edit.thtml:130
+msgid "collections_edit_form_error_name"
+msgstr "È necessario assegnare un nome alla raccolta."
+
+#: views/collections/edit.thtml:158
+msgid "collections_edit_form_error_nickname"
+msgstr "Se scegli di assegnare uno pseudonimo, deve essere unico."
+
+#: views/collections/add.thtml:93
+#: views/collections/edit.thtml:249
+msgid "collections_edit_formfield_addons"
+msgstr "Nome componente aggiuntivo:"
+
+#: views/collections/edit.thtml:281
+msgid "collections_edit_formfield_application"
+msgstr "Applicazione associata"
+
+#: views/collections/edit.thtml:282
+msgid "collections_edit_formfield_application_description"
+msgstr "Selezionare l'applicazione compatibile con la tua raccolta."
+
+#: views/collections/edit.thtml:288
+msgid "collections_edit_formfield_collectiontype"
+msgstr "Tipo di raccolta"
+
+#: views/collections/edit.thtml:295
+msgid "collections_edit_formfield_deletecollection"
+msgstr "Elimina raccolta"
+
+#: views/collections/edit.thtml:296
+msgid "collections_edit_formfield_deletecollection_description"
+msgstr "L'eliminazione della raccolta è un'operazione non reversibile."
+
+#: views/collections/add.thtml:73
+#: views/collections/edit.thtml:140
+msgid "collections_edit_formfield_description"
+msgstr "Descrizione raccolta"
+
+#: views/collections/add.thtml:74
+#: views/collections/edit.thtml:141
+msgid "collections_edit_formfield_description_description"
+msgstr "Descrivi brevemente la tua raccolta e il tipo di componenti aggiuntivi presenti"
+
+#: views/collections/edit.thtml:162
+msgid "collections_edit_formfield_icon"
+msgstr "Immagine"
+
+#: views/collections/edit.thtml:163
+msgid "collections_edit_formfield_icon_description"
+msgstr "È possibile utilizzare un'immagine JPG, GIF o PNG che verrà ridimensionata a 32x32 pixel."
+
+#: views/collections/add.thtml:80
+#: views/collections/edit.thtml:189
+msgid "collections_edit_formfield_listed"
+msgstr "Chi può visualizzare la tua raccolta?"
+
+#: views/collections/add.thtml:81
+#: views/collections/edit.thtml:190
+msgid "collections_edit_formfield_listed_description"
+msgstr "Come impostazioni predefinita, le raccolte appaiono in un elenco pubblico e sono consultabili da qualsiasi utente. Se vuoi fare in modo che la tua raccolta sia visibile solo ad un numero ristretto di persone a cui hai comunicato l'apposito link, seleziona l'opzione seguente."
+
+#: views/collections/add.thtml:84
+#: views/collections/edit.thtml:193
+msgid "collections_edit_formfield_listed_false"
+msgstr "Sole le persone che ricevono un mio invito possono visualizzare la mia raccolta"
+
+#: views/collections/add.thtml:83
+#: views/collections/edit.thtml:192
+msgid "collections_edit_formfield_listed_true"
+msgstr "Chiunque può visualizzare la mia raccolta"
+
+#: views/collections/edit.thtml:223
+msgid "collections_edit_formfield_managers"
+msgstr "Chi può gestire la mia raccolta?"
+
+#: views/collections/edit.thtml:224
+msgid "collections_edit_formfield_managers_description"
+msgstr "Questi utenti possono aggiungere elementi alla tua raccolta, gestire tutti i componenti aggiuntivi e le impostazioni, e modificare i permessi degli altri utenti."
+
+#: views/collections/add.thtml:66
+#: views/collections/edit.thtml:126
+msgid "collections_edit_formfield_name"
+msgstr "Nome raccolta"
+
+#: views/collections/add.thtml:67
+#: views/collections/edit.thtml:127
+msgid "collections_edit_formfield_name_description"
+msgstr "Assegna alla tua raccolta un nome descrittivo, come ad esempio \"Estensioni preferite di Paolo per netbook\""
+
+#: views/collections/edit.thtml:148
+msgid "collections_edit_formfield_nickname"
+msgstr "Pseudonimo raccolta"
+
+#: views/collections/edit.thtml:149
+msgid "collections_edit_formfield_nickname_description"
+msgstr "Se vuoi, è possibile assegnare un pseudonimo alla tua raccolta per velocizzare l'accesso:"
+
+#: views/collections/edit.thtml:201
+msgid "collections_edit_formfield_publishers"
+msgstr "Chi può pubblicare elementi nella tua raccolta?"
+
+#: views/collections/edit.thtml:202
+msgid "collections_edit_formfield_publishers_description"
+msgstr "Questi utenti possono aggiungere componenti aggiuntivi alla tua raccolta ed eliminare gli elementi che hanno pubblicato."
+
+#: views/collections/edit.thtml:210
+#: views/collections/edit.thtml:232
+msgid "collections_edit_formfield_users_add"
+msgstr "Inserisci l'indirizzo e-mail di un account per questo sito (Firefox Add-ons):"
+
+#: views/collections/edit.thtml:216
+#: views/collections/edit.thtml:238
+msgid "collections_edit_formfield_users_delete_noscript"
+msgstr "Gli account selezionati verranno rimossi in fase di salvataggio"
+
+#: views/collections/edit.thtml:215
+#: views/collections/edit.thtml:237
+msgid "collections_edit_formfield_users_new_noscript"
+msgstr "Inserisci gli indirizzi e-mail degli account per Firefox Add-ons separandoli con delle virgole"
+
+#: views/collections/edit.thtml:204
+#: views/collections/edit.thtml:226
+msgid "collections_edit_formfield_users_onlyme"
+msgstr "Solo io"
+
+#: views/collections/edit.thtml:205
+#: views/collections/edit.thtml:227
+msgid "collections_edit_formfield_users_otherusers"
+msgstr "Io e questi utenti:"
+
+#: views/collections/edit.thtml:211
+#: views/collections/edit.thtml:233
+msgid "collections_edit_formfield_users_submit"
+msgstr "Aggiungi"
+
+#. %1$s is the name of the collection
+#: views/collections/edit.thtml:68
+msgid "collections_edit_header"
+msgstr "Gestione %1$s"
+
+#: views/collections/edit.thtml:246
+msgid "collections_edit_header_addons"
+msgstr "Gestisci il contenuto della raccolta"
+
+#: views/collections/edit.thtml:253
+#: views/collections/edit.thtml:258
+msgid "collections_edit_header_addons_current"
+msgstr "Elementi correnti:"
+
+#: views/collections/edit.thtml:279
+msgid "collections_edit_header_advanced"
+msgstr "Impostazioni avanzate"
+
+#: views/collections/edit.thtml:186
+msgid "collections_edit_header_permissions"
+msgstr "Gestisci i permessi della raccolta"
+
+#: views/collections/edit.thtml:170
+msgid "collections_edit_icon_cancel"
+msgstr "Annulla"
+
+#: views/collections/edit.thtml:174
+#: views/collections/edit.thtml:179
+msgid "collections_edit_icon_delete"
+msgstr "Elimina immagine"
+
+#: views/collections/edit.thtml:178
+msgid "collections_edit_icon_replace"
+msgstr "Sostituisci immagine"
+
+#. %1$s is the label of the edit form's submit button
+#: views/collections/edit.thtml:169
+msgid "collections_edit_icon_toberemoved"
+msgstr "L'immagine verrà rimossa facendo clic su \"%1$s\""
+
+#: views/collections/edit.thtml:155
+msgid "collections_edit_nickname_available"
+msgstr "Pseudonimo disponibile"
+
+#: controllers/collections_controller.php:943
+msgid "collections_edit_nickname_error"
+msgstr "Lo pseudonimo scelto contiene caratteri non validi ed è stato corretto. Riprovare."
+
+#: views/collections/edit.thtml:156
+msgid "collections_edit_nickname_taken"
+msgstr "Pseudonimo già utilizzato"
+
+#. This string is followed by a URL pointing to the collection's view page
+#: views/collections/edit.thtml:75
+msgid "collections_edit_saved_nextstep"
+msgstr "La tua raccolta è disponibile a questo indirizzo:"
+
+#: views/collections/edit.thtml:74
+msgid "collections_edit_saved_success"
+msgstr "La raccolta è stata salvata con successo."
+
+#: views/collections/edit.thtml:169
+#: views/collections/edit.thtml:300
+#: views/collections/edit.thtml:308
+#: views/pages/js_constants.js.thtml:99
+msgid "collections_edit_submit"
+msgstr "Aggiorna raccolta"
+
+#: views/collections/edit.thtml:96
+#: views/collections/edit.thtml:297
+#: views/pages/js_constants.js.thtml:100
+msgid "collections_edit_submit_deletecollection"
+msgstr "Elimina raccolta"
+
+#: views/collections/edit.thtml:111
+msgid "collections_edit_tabheader_addons"
+msgstr "Componenti aggiuntivi"
+
+#: views/collections/edit.thtml:97
+#: views/collections/edit.thtml:113
+msgid "collections_edit_tabheader_advanced"
+msgstr "Avanzate"
+
+#: views/collections/edit.thtml:108
+msgid "collections_edit_tabheader_details"
+msgstr "Nome e dettagli"
+
+#: views/collections/edit.thtml:109
+msgid "collections_edit_tabheader_permissions"
+msgstr "Permessi"
+
+#: models/collection_promo.php:53
+msgid "collections_family_tagline"
+msgstr "Tieni d'occhio i tuoi bambini e la tua agenda."
+
+#: models/collection_promo.php:53
+msgid "collections_family_title"
+msgstr "Famiglia"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:70
+msgid "collections_index_a_check_out"
+msgstr "Prova Add-on Collector"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:52
+msgid "collections_index_a_create"
+msgstr "Crea una raccolta"
+
+#: views/collections/detail.thtml:139
+#: views/collections/listing.thtml:85
+#: views/search/collections.thtml:84
+msgid "collections_index_button_go"
+msgstr "Vai"
+
+#. %1$s is a URL.
+#: controllers/collections_controller.php:182
+msgid "collections_index_filler_favorites"
+msgstr "<p><strong>Non hai ancora nessuna raccolta preferita.</strong></p> <p>Le raccolte che imposti come preferite possono essere gestite attraverso questa pagina e, se hai installata questa estensione, appariranno anche in <a href='%1$s'>Add-on Collector</a>.</p>"
+
+#. %1$s is a URL.
+#: controllers/collections_controller.php:167
+msgid "collections_index_filler_mine"
+msgstr "<p>Non hai ancora creato nessuna raccolta. È molto semplice creare nuove raccolte con i tuoi componenti aggiuntivi preferiti. <a href='%1$s'>Fai una prova</a>.</p>"
+
+#: views/collections/listing.thtml:51
+msgid "collections_index_header_collections"
+msgstr "Raccolte"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:60
+msgid "collections_index_header_collector"
+msgstr "Add-on Collector"
+
+#. %1$s is a comma-separated list of author names
+#: views/elements/amo2009/collection_listing_item.thtml:84
+#: views/collections/detail.thtml:151
+msgid "collections_index_header_created"
+msgstr "realizzata da %1$s"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:47
+msgid "collections_index_header_what"
+msgstr "Che cosa sono le raccolte?"
+
+#: views/collections/detail.thtml:132
+#: views/collections/listing.thtml:78
+#: views/search/collections.thtml:66
+msgid "collections_index_label_sortby"
+msgstr "Ordina per"
+
+#: controllers/collections_controller.php:130
+msgid "collections_index_li_editors"
+msgstr "Le nostre scelte"
+
+#: views/collections/subscribe.thtml:64
+#: controllers/collections_controller.php:140
+msgid "collections_index_li_favorites"
+msgstr "Mie preferite"
+
+#: controllers/collections_controller.php:138
+msgid "collections_index_li_mine"
+msgstr "Mie raccolte"
+
+#: controllers/collections_controller.php:132
+msgid "collections_index_li_popular"
+msgstr "Popolare"
+
+#: views/search/collections.thtml:74
+#: controllers/collections_controller.php:81
+msgid "collections_index_option_all"
+msgstr "Più popolare di sempre"
+
+#: views/search/collections.thtml:72
+#: controllers/collections_controller.php:78
+msgid "collections_index_option_month"
+msgstr "Più popolare di questo mese"
+
+#: views/search/collections.thtml:76
+#: controllers/collections_controller.php:84
+msgid "collections_index_option_newest"
+msgstr "Più recente"
+
+#: views/search/collections.thtml:70
+#: controllers/collections_controller.php:75
+msgid "collections_index_option_week"
+msgstr "Più popolare di questa settimana"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:67
+msgid "collections_index_p_collector"
+msgstr "C'è un nuovo modo per gestire e trovare i tuoi componenti aggiuntivi preferiti. Commenta, condividi e sincronizza le raccolte, tutto direttamente dal tuo browser."
+
+#: views/elements/amo2009/collector_info_secondary.thtml:48
+msgid "collections_index_p_what_are"
+msgstr "Le raccolte sono gruppi di componenti aggiuntivi, aggregati per renderne più semplice la condivisione."
+
+#. %s is a date in the _('date') format
+#: views/elements/collections_interactive_addon.thtml:85
+#, php-format
+msgid "collections_interactive_addon_added"
+msgstr "Aggiunto %s"
+
+#: models/collection_promo.php:55
+msgid "collections_reference_tagline"
+msgstr "Cerca informazioni online."
+
+#: models/collection_promo.php:55
+msgid "collections_reference_title"
+msgstr "Informazioni"
+
+#: models/collection_promo.php:52
+msgid "collections_social_tagline"
+msgstr "Gestisci i tuoi social network."
+
+#: models/collection_promo.php:52
+msgid "collections_social_title"
+msgstr "Social"
+
+#: views/collections/subscribe.thtml:91
+msgid "collections_subscribe_button_close"
+msgstr "Chiudi"
+
+#: views/collections/subscribe.thtml:70
+msgid "collections_subscribe_error"
+msgstr "Si è verificato un errore nel tentativo di impostare questa raccolta come preferita. Questa raccolta è già presente tra i preferiti?"
+
+#: views/collections/subscribe.thtml:96
+msgid "collections_subscribe_label_bothersome"
+msgstr "Non visualizzare questo messaggio in futuro."
+
+#. %1$s is the collection name
+#: views/collections/subscribe.thtml:60
+msgid "collections_subscribe_success"
+msgstr "%1$s è stata aggiunta alle tue raccolte preferite."
+
+#. %1$s is the link to the "My Favorites" tab on the main collections page
+#. %2$s is the localized title of the "My Favorites" tab
+#. %3$s is the link URL to the collector add-on
+#: views/collections/subscribe.thtml:62
+msgid "collections_subscribe_success_desc"
+msgstr "Da questo momento puoi trovare questa raccolta nella scheda <a href=\"%1$s\">%2$s</a>. Per una gestire le tue raccolte in modo ancora più semplice, prova la nostra estensione <a href=\"%3$s\">Add-on Collector</a> per Firefox."
+
+#: views/collections/listing.thtml:55
+msgid "collections_success_delete"
+msgstr "La raccolta è stata eliminata."
+
+#: models/collection_promo.php:54
+msgid "collections_travel_tagline"
+msgstr "Progetta viaggi di lavoro e vacanze indimenticabili."
+
+#: models/collection_promo.php:54
+msgid "collections_travel_title"
+msgstr "Viaggi"
+
+#. A collection of add-ons that is automatically built for a user. They are "automatically published" to this collection.
+#: controllers/collections_controller.php:581
+msgid "collections_type_autopublisher"
+msgstr "Pubblicazione automatica"
+
+#. A collection that has been chosen by an Editor as notable or exceptional
+#: controllers/collections_controller.php:582
+msgid "collections_type_editorspick"
+msgstr "Scelta da noi"
+
+#: controllers/collections_controller.php:580
+msgid "collections_type_normal"
+msgstr "Normale"
+
+#: views/collections/subscribe.thtml:84
+msgid "collections_unsubscribe_error"
+msgstr "Si è verificato un errore durante la rimozione della raccolta dai preferiti. La raccolta non era presente tra i tuoi preferiti?"
+
+#. %1$s is the collection name
+#: views/collections/subscribe.thtml:78
+msgid "collections_unsubscribe_success"
+msgstr "%1$s è stata rimossa dalle tue raccolte preferite."
+
+#: models/collection_promo.php:56
+msgid "collections_webdev_tagline"
+msgstr "Realizza siti web perfetti."
+
+#: models/collection_promo.php:56
+msgid "collections_webdev_title"
+msgstr "Sviluppo web"
+
+#: views/elements/amo2009/collections_sidebar_whatare.thtml:40
+msgid "collections_whatare_header"
+msgstr "Che cosa sono le raccolte?"
+
+#: views/elements/amo2009/collections_sidebar_whatare.thtml:45
+msgid "collections_whatare_learnmore"
+msgstr "Leggi le FAQ"
+
+#: views/elements/amo2009/collections_sidebar_whatare.thtml:44
+msgid "collections_whatare_text"
+msgstr "C'è un nuovo modo per gestire e trovare i tuoi componenti aggiuntivi preferiti. Commenta, condividi e sincronizza le raccolte, tutto direttamente dal tuo browser."
+
+#: views/pages/collector_faq.thtml:61
+#: views/pages/collector_features.thtml:67
+msgid "collector_features_a_home"
+msgstr "Add-on Collector"
+
+#: views/elements/amo2009/collector_sidebar_download.thtml:46
+msgid "collector_features_heading_download"
+msgstr "Scarica Add-on Collector:"
+
+#: views/elements/amo2009/collector_sidebar_download.thtml:43
+#: views/pages/collector_firstrun.thtml:116
+#: views/pages/collector.thtml:69
+msgid "collector_features_img_logo"
+msgstr "Logo di Add-on Collector"
+
+#: views/compatibility/dashboard.thtml:49
+#: controllers/compatibility_controller.php:72
+msgid "compatibility_dashboard_center_header"
+msgstr "Centro compatibilità componenti aggiuntivi"
+
+#. %1$s is the name of an application and a version. Example: Firefox 3.0
+#. %2$s is the name of an application. Example: Firefox
+#: views/compatibility/dashboard.thtml:50
+msgid "compatibility_dashboard_intro"
+msgstr "Preparati al rilascio di %1$s con gli strumenti e le informazioni disponibili per la community %2$s Add-on."
+
+#: views/compatibility/dashboard.thtml:103
+msgid "compatibility_dashboard_loading"
+msgstr "Caricamento dati…"
+
+#: views/compatibility/dashboard.thtml:45
+msgid "compatibility_dashboard_main_link"
+msgstr "Ritorna alla pagina principale"
+
+#: views/compatibility/dashboard.thtml:100
+#: views/compatibility/report.thtml:43
+msgid "compatibility_dashboard_report"
+msgstr "Rapporto compatibilità componenti aggiuntivi"
+
+#: views/compatibility/dashboard.thtml:53
+#: views/compatibility/dashboard.thtml:110
+#: views/compatibility/developers.thtml:43
+msgid "compatibility_developer_info"
+msgstr "Informazioni per gli sviluppatori"
+
+#: views/compatibility/developers.thtml:66
+msgid "compatibility_developers_adjust_maxversion"
+msgstr "Modifica maxVersion senza upload"
+
+#: views/compatibility/dashboard.thtml:124
+msgid "compatibility_developers_check_status"
+msgstr "Controlla lo stato dei miei componenti aggiuntivi"
+
+#. %1$s is a URL
+#. %2$s is an application and version. Example: Firefox 3.0
+#: views/compatibility/dashboard.thtml:126
+msgid "compatibility_developers_login_first"
+msgstr "Se alcuni dei tuoi componenti aggiuntivi sono ospitati su Mozilla Add-On, <a href=\"%1$s\">accedi</a> per esaminare lo stato dei tuoi componenti aggiuntivi per %2$s."
+
+#: views/compatibility/dashboard.thtml:114
+msgid "compatibility_developers_mdclogo_alt"
+msgstr "Logo Mozilla Developer Center"
+
+#: views/compatibility/developers.thtml:73
+msgid "compatibility_developers_no_addons"
+msgstr "Non risultati tuoi componenti aggiuntivi ospitati su Mozilla Add-on."
+
+#: views/compatibility/dashboard.thtml:133
+#: views/compatibility/developers.thtml:55
+msgid "compatibility_developers_results"
+msgstr "Risultati del controllo compatibilità"
+
+#: views/compatibility/dashboard.thtml:137
+msgid "compatibility_developers_retrieving"
+msgstr "Recupero stato dei componenti aggiuntivi ospitati…"
+
+#. %1$s is a number
+#. %2$s is an application name
+#. %3$s is a number.
+#. Full example: 50 Firefox users (10% of total)
+#: views/compatibility/developers.thtml:65
+msgid "compatibility_developers_user_count"
+msgstr "%1$s %2$s utenti (%3$s&#37; del totale)"
+
+#: views/compatibility/report.thtml:45
+msgid "compatibility_report_detail_intro"
+msgstr "In base ai dati in possesso di Mozilla, i seguenti componenti aggiuntivi costituiscono il 95% degli utilizzatori. L'ordine di visualizzazione è dato dalla dimensione della base utenti."
+
+#: views/compatibility/dashboard.thtml:94
+msgid "compatibility_report_detailed_link"
+msgstr "Mostra rapporto dettagliato"
+
+#. %1$s and %2$s are numbers
+#. %3$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:65
+msgid "compatibility_report_intro"
+msgstr "Dei %1$s componenti aggiuntivi che rappresentano il 95&#37; degli utilizzatori noti a Mozilla, il <b>%2$s&#37;</b> è attualmente considerato compatibile con le ultime versioni di %3$s."
+
+#: views/compatibility/dashboard.thtml:81
+msgid "compatibility_report_legend_alpha"
+msgstr "Versioni alfa"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:81
+msgid "compatibility_report_legend_alpha_description"
+msgstr "Componenti aggiuntivi compatibili con una versione alfa di %1$s"
+
+#: views/compatibility/dashboard.thtml:85
+msgid "compatibility_report_legend_beta"
+msgstr "Versioni beta"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:85
+msgid "compatibility_report_legend_beta_description"
+msgstr "Componenti aggiuntivi compatibili con una versione beta o release candidate di %1$s"
+
+#: views/compatibility/dashboard.thtml:89
+msgid "compatibility_report_legend_latest"
+msgstr "Ultima versione"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:89
+msgid "compatibility_report_legend_latest_description"
+msgstr "Componenti aggiuntivi compatibili con le ultime versioni di %1$s"
+
+#: views/compatibility/dashboard.thtml:77
+msgid "compatibility_report_legend_other"
+msgstr "Altre versioni"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:77
+msgid "compatibility_report_legend_other_description"
+msgstr "Componenti aggiuntivi non compatibili con alcuna versione di %1$s"
+
+#: views/compatibility/dashboard.thtml:62
+msgid "compatibility_report_title"
+msgstr "Rapporto compatibilità componenti aggiuntivi"
+
+#: views/compatibility/dashboard.thtml:54
+#: views/compatibility/dashboard.thtml:144
+#: views/compatibility/users.thtml:42
+msgid "compatibility_user_info"
+msgstr "Informazioni per gli utenti"
+
+#: views/compatibility/dashboard.thtml:52
+msgid "compatibility_view_report"
+msgstr "Visualizza il rapporto compatibilità"
+
+#. %s is a URL
+#: views/pages/credits.thtml:142
+#, php-format
+msgid "credits_contributing"
+msgstr "Per informazioni su come contribuire, consultare il nostro %s."
+
+#: views/pages/credits.thtml:142
+msgid "credits_contributing_wikipage"
+msgstr "pagina wiki"
+
+#: views/pages/credits.thtml:99
+msgid "credits_intro"
+msgstr "Mozilla desidera ringraziare le seguenti persone per il loro contributo al progetto addons.mozilla.org nel corso degli anni:"
+
+#: views/pages/credits.thtml:103
+msgid "credits_section_developers"
+msgstr "Sviluppatori"
+
+#: views/pages/credits.thtml:115
+msgid "credits_section_editors"
+msgstr "Revisori"
+
+#: views/pages/credits.thtml:109
+msgid "credits_section_localizers"
+msgstr "Localizzatori"
+
+#: views/pages/credits.thtml:121
+msgid "credits_section_other_contributors"
+msgstr "Altri collaboratori"
+
+#: views/pages/credits.thtml:127
+msgid "credits_section_past_developers"
+msgstr "Sviluppatori precedenti"
+
+#: views/pages/credits.thtml:133
+msgid "credits_section_software"
+msgstr "Software e immagini"
+
+#: views/pages/credits.thtml:136
+msgid "credits_software_famfamfam"
+msgstr "Alcune delle icone utilizzate appartengono al <a href=\"http://www.famfamfam.com/lab/icons/silk/\">famfamfam Silk Icon Set</a>, rilasciato sotto <a href=\"http://creativecommons.org/licenses/by/2.5/\">Licenza Creative Commons Attribution 2.5</a>."
+
+#: views/pages/credits.thtml:137
+msgid "credits_software_timeplot"
+msgstr "Alcune pagine utilizzano elementi di <a href=\"http://www.simile-widgets.org/timeplot/\">Timeplot</a>, distribuito con <a href=\"http://simile.mit.edu/license.html\">licenza BSD</a>."
+
+#. date format string as used in PHP's strftime():
+#. http://php.net/strftime
+#: views/elements/collections_interactive_addon.thtml:85
+#: views/elements/amo2009/addon_version_detail.thtml:53
+#: views/elements/amo2009/homepage_addon.thtml:115
+#: views/elements/addon_version_detail.thtml:54
+#: views/elements/addon_listitem.thtml:124
+#: views/elements/feature.thtml:106
+#: views/collections/detail.thtml:118
+#: views/collections/edit.thtml:325
+#: views/users/info.thtml:76
+#: views/editors/reviews_queue.thtml:57
+#: views/editors/reviews_queue.thtml:68
+#: views/developers/dashboard.thtml:65
+#: views/developers/versions_edit.thtml:208
+#: views/developers/versions.thtml:67
+#: views/search/rss/index.thtml:5
+#: views/addons/rss/versions.thtml:42
+#: views/addons/display.thtml:104
+#: views/addons/display.thtml:356
+#: views/addons/browse_thumbs.thtml:75
+#: views/reviews/add.thtml:63
+#: views/reviews/display.thtml:74
+#: views/reviews/display.thtml:160
+#: views/reviews/delete.thtml:54
+#: controllers/statistics_controller.php:244
+#: controllers/collections_controller.php:1047
+msgid "date"
+msgstr "%e %B %Y"
+
+#. date and time format string (strftime)
+#. http://php.net/strftime
+#: views/elements/addon_version_detail.thtml:53
+#: views/developers/discuss.thtml:52
+#: views/developers/discuss.thtml:62
+#: views/admin/addons_status.thtml:57
+msgid "datetime"
+msgstr "%e %B %Y, %I:%M:%p"
+
+#: views/elements/developers/actionbar.thtml:47
+msgid "devcp_actionbar_link_details"
+msgstr "Dettaglio"
+
+#: views/elements/developers/actionbar.thtml:42
+#: views/elements/developers/actionbar.thtml:50
+#: views/developers/dashboard.thtml:64
+msgid "devcp_actionbar_link_edit"
+msgstr "Modifica"
+
+#: views/elements/developers/actionbar.thtml:51
+msgid "devcp_actionbar_link_newversion"
+msgstr "Carica una nuova versione"
+
+#: views/elements/developers/actionbar.thtml:44
+#: views/elements/developers/actionbar.thtml:49
+#: views/developers/dashboard.thtml:73
+msgid "devcp_actionbar_link_stats"
+msgstr "Pannello statistiche"
+
+#. %1$s is a filename, e.g. "foo.txt"
+#. %2$s is the extension, e.g. ".txt"
+#. %3$s is a list of valid extensions, like ".png, .jpg, .gif"
+#: controllers/developers_controller.php:1361
+msgid "devcp_add_previews_extension_error"
+msgstr "Il file %1$s ha un'estensione non valida (%2$s). Estensioni consentite: %3$s"
+
+#. %s is the filename.
+#: controllers/developers_controller.php:1394
+msgid "devcp_add_previews_save_error"
+msgstr "Il file %s non può essere salvato nel database. Riprovare in seguito."
+
+#. %1$s is the preview ID number, %2$s is the filename.
+#: controllers/developers_controller.php:1389
+msgid "devcp_add_previews_success_replace"
+msgstr "L'anteprima %1$s è stata sostituita correttamente con il file %2$s."
+
+#. %s is the filename.
+#: controllers/developers_controller.php:1391
+msgid "devcp_add_previews_success_upload"
+msgstr "Il file %s è stato caricato correttamente. È possibile aggiungere una descrizione."
+
+#: controllers/components/developers.php:1163
+msgid "devcp_additem_addontype_autodetect"
+msgstr "(rilevazione automatica)"
+
+#: views/elements/developers/additem.thtml:76
+msgid "devcp_additem_linktitle_opensin_newwindow"
+msgstr "Apri in una nuova finestra"
+
+#: views/elements/developers/additem.thtml:41
+msgid "devcp_additem_sidebar_title"
+msgstr "Invia componente aggiuntivo"
+
+#: views/elements/developers/additem.thtml:53
+msgid "devcp_additem_step0_newlink"
+msgstr "Accordo di licenza per sviluppatori"
+
+#: views/elements/developers/additem.thtml:46
+msgid "devcp_additem_step1_link"
+msgstr "Passaggio 1: carica il file"
+
+#: views/elements/developers/additem.thtml:47
+msgid "devcp_additem_step2_link"
+msgstr "Passaggio 2: informazioni sul componente aggiuntivo"
+
+#: views/elements/developers/additem.thtml:48
+msgid "devcp_additem_step3_link"
+msgstr "Passaggio 3: dettagli sulla versione"
+
+#: views/elements/developers/additem.thtml:49
+msgid "devcp_additem_step4_link"
+msgstr "Passaggio 4: localizzazione"
+
+#: views/elements/developers/additem.thtml:50
+msgid "devcp_additem_step5_link"
+msgstr "Passaggio 5: operazione terminata"
+
+#: views/elements/developers/additem.thtml:76
+msgid "devcp_additem_submissionhelp_link"
+msgstr "Guida per l'inserimento"
+
+#: controllers/previews_controller.php:168
+#: controllers/previews_controller.php:277
+msgid "devcp_addon_field_preview_caption_displaytitle"
+msgstr "Descrizione dell'anteprima"
+
+#: views/developers/addon_status.thtml:177
+msgid "devcp_addon_status_action_activate"
+msgstr "Attiva"
+
+#: views/developers/addon_status.thtml:178
+msgid "devcp_addon_status_action_activate_description"
+msgstr "Attiva il componente aggiuntivo per farlo comparire nell'elenco pubblico e attivare il servizio di aggiornamento automatico."
+
+#: views/developers/addon_status.thtml:135
+msgid "devcp_addon_status_action_complete"
+msgstr "Imposta come completo"
+
+#: views/developers/addon_status.thtml:136
+msgid "devcp_addon_status_action_complete_description"
+msgstr "Imposta come completo il componente aggiuntivo e spostalo nella Sandbox"
+
+#: views/developers/addon_status.thtml:181
+msgid "devcp_addon_status_action_deactivate"
+msgstr "Disattiva"
+
+#: views/developers/addon_status.thtml:182
+msgid "devcp_addon_status_action_deactivate_description"
+msgstr "Disattiva il componente aggiuntivo per rimuoverlo dall'elenco pubblico e disattivare il servizio di aggiornamento automatico."
+
+#: views/developers/addon_status.thtml:143
+msgid "devcp_addon_status_action_move"
+msgstr "Sposta nella Sandbox"
+
+#: views/developers/addon_status.thtml:144
+msgid "devcp_addon_status_action_move_description"
+msgstr "Sposta il componente aggiuntivo nella Sandbox. L'azione può essere annullata."
+
+#: views/developers/addon_status.thtml:139
+msgid "devcp_addon_status_action_nominate"
+msgstr "Nomina per la pubblicazione"
+
+#: views/developers/addon_status.thtml:140
+msgid "devcp_addon_status_action_nominate_description"
+msgstr "Nomina il componente aggiuntivo per la pubblicazione"
+
+#: views/developers/addon_status.thtml:147
+msgid "devcp_addon_status_action_public"
+msgstr "Pubblica"
+
+#: views/developers/addon_status.thtml:148
+msgid "devcp_addon_status_action_public_description"
+msgstr "Rendi nuovamente disponibile al pubblico il componente aggiuntivo."
+
+#: views/developers/addon_status.thtml:169
+msgid "devcp_addon_status_active"
+msgstr "Il componente aggiuntivo è <span class=\"inactive-0\">attivo</span>. Questo significa che verrà visualizzato in tutti gli elenchi disponibili e riservati ai componenti in questo stato."
+
+#: views/developers/addon_status.thtml:111
+msgid "devcp_addon_status_completion_disabled"
+msgstr "È necessario soddisfare i criteri indicati per poter impostare il componente aggiuntivo come completo e spostarlo nella <span class=\"status-1\">Sandbox</span>."
+
+#: views/developers/addon_status.thtml:108
+msgid "devcp_addon_status_completion_enabled"
+msgstr "È ora possibile impostare il componente aggiuntivo come completo e spostarlo nella <span class=\"status-1\">Sandbox</span> facendo clic sul pulsante seguente."
+
+#: views/developers/addon_status.thtml:102
+msgid "devcp_addon_status_criteria_category"
+msgstr "Selezionare almeno una categoria"
+
+#: views/developers/addon_status.thtml:101
+msgid "devcp_addon_status_criteria_description"
+msgstr "La descrizione è obbligatoria"
+
+#: views/developers/addon_status.thtml:99
+msgid "devcp_addon_status_criteria_name"
+msgstr "Il nome è obbligatorio"
+
+#: views/developers/addon_status.thtml:120
+msgid "devcp_addon_status_criteria_prerelease"
+msgstr "Il componente aggiuntivo non è segnalato come pre-release."
+
+#: views/developers/addon_status.thtml:119
+msgid "devcp_addon_status_criteria_preview"
+msgstr "È necessario inserire almeno un'anteprima per estensioni e temi."
+
+#: views/developers/addon_status.thtml:100
+msgid "devcp_addon_status_criteria_summary"
+msgstr "Il riepilogo è obbligatorio"
+
+#. %s is the status in a span, e.g. "<span>_('Public')</span>".
+#: views/developers/addon_status.thtml:58
+msgid "devcp_addon_status_header"
+msgstr "Stato: %s"
+
+#: views/developers/addon_status.thtml:152
+#: views/developers/addon_status.thtml:173
+msgid "devcp_addon_status_header_actions"
+msgstr "Azioni disponibili"
+
+#: views/developers/addon_status.thtml:168
+msgid "devcp_addon_status_header_active"
+msgstr "Stato attività: <span class=\"inactive-0\">attivo</span>"
+
+#: views/developers/addon_status.thtml:97
+msgid "devcp_addon_status_header_criteria"
+msgstr "Criteri per il completamento"
+
+#: views/developers/addon_status.thtml:164
+msgid "devcp_addon_status_header_inactive"
+msgstr "Stato attività: <span class=\"inactive-1\">disattivato</span>"
+
+#: views/developers/addon_status.thtml:117
+msgid "devcp_addon_status_header_nomination"
+msgstr "Criteri per la pubblicazione"
+
+#: views/developers/addon_status.thtml:190
+msgid "devcp_addon_status_header_trusted"
+msgstr "Stato fiducia: <span class=\"status-4\">affidabile</span>"
+
+#: views/developers/addon_status.thtml:165
+msgid "devcp_addon_status_inactive"
+msgstr "Il componente aggiuntivo è <span class=\"inactive-1\">disattivato</span>. Questo significa che non verrà mostrato in nessun elenco, a prescindere dallo stato. Inoltre <b>non</b> verranno distribuiti aggiornamenti attraverso il meccanismo di aggiornamento automatico."
+
+#: views/developers/addon_status.thtml:128
+msgid "devcp_addon_status_nominate_disabled"
+msgstr "È necessario soddisfare i criteri indicati prima di nominare un componente aggiuntivo e renderlo <span class=\"status-4\">pubblicato</span>."
+
+#: views/developers/addon_status.thtml:125
+msgid "devcp_addon_status_nominate_enabled"
+msgstr "È ora possibile nominare il componente aggiuntivo per la <span class=\"status-4\">pubblicazione</span> facendo clic sul pulsante seguente."
+
+#: views/developers/addon_status.thtml:64
+msgid "devcp_addon_status_public"
+msgstr "Pubblico"
+
+#: views/developers/addon_status.thtml:63
+msgid "devcp_addon_status_sandbox"
+msgstr "Sandbox"
+
+#. %s is an email address.
+#: views/developers/addon_status.thtml:89
+msgid "devcp_addon_status_switch_disabled"
+msgstr "Il componente aggiuntivo è stato <span class=\"status-5\">disattivato</span> da un amministratore e non può essere usato. Per ulteriori informazioni inviare una e-mail a %s."
+
+#: views/developers/addon_status.thtml:67
+msgid "devcp_addon_status_switch_incomplete"
+msgstr "Il componente aggiuntivo è attualmente <span class=\"status-0\">incompleto</span>. Questo significa che non appare in nessuna sezione del sito e non può utilizzare il meccanismo di aggiornamento automatico. È possibile ritornare a questa pagina dopo aver soddisfatto i criteri necessari per il completamento e spostarlo nella \"status-1\">Sandbox</span>."
+
+#. %s is a number, perhaps 42.
+#: views/developers/addon_status.thtml:77
+msgid "devcp_addon_status_switch_nominated"
+msgstr "Il componente aggiuntivo è stato nominato per la <span class=\"status-4\">pubblicazione</span> ed è in attesa della revisione. Attualmente ci sono altri %s elementi in coda."
+
+#. %s is an email address.
+#: views/developers/addon_status.thtml:81
+msgid "devcp_addon_status_switch_pending"
+msgstr "Il componente aggiuntivo è in sospeso. Questo non dovrebbe accadere. Inviare una e-mail a %s con l'ID del componente aggiuntivo e segnalare questo errore."
+
+#: views/developers/addon_status.thtml:85
+msgid "devcp_addon_status_switch_public"
+msgstr "Il componente aggiuntivo è <span class=\"status-4\">pubblicato</span>, questo significa che verrà visualizzato in tutti gli elenchi, nei risultati di ricerca e potrà essere scaricato senza restrizioni. Gli aggiornamenti per questo componente aggiuntivo saranno disponibili attraverso il sistema di aggiornamento automatico."
+
+#: views/developers/addon_status.thtml:71
+#: views/developers/addon_status.thtml:75
+msgid "devcp_addon_status_switch_sandbox"
+msgstr "Il componente aggiuntivo si trova nella <span class=\"status-1\">Sandbox</span>, questo significa che verrà visualizzato negli elenchi e tra i risultati di ricerca, ma gli utenti dovranno effettuare il login per scaricarlo. Gli aggiornamenti <b>non</b> verranno forniti con il sistema di aggiornamento automatico."
+
+#. %s is the add-on name.
+#: views/developers/addon_status_nominate.thtml:43
+#: views/developers/addon_status_confirm.thtml:43
+#: views/developers/addon_status.thtml:43
+msgid "devcp_addon_status_title"
+msgstr "Stato %s"
+
+#: views/developers/addon_status.thtml:191
+msgid "devcp_addon_status_trusted"
+msgstr "Il componente aggiuntivo è segnalato come <span class=\"status-4\">affidabile</span>. Questo significa che puoi caricare aggiornamenti senza passare attraverso il controllo di un revisore."
+
+#: views/developers/dashboard.thtml:68
+msgid "devcp_dashboard_active"
+msgstr "attivo"
+
+#. %1$s is the add-on type string
+#. %2$s is Inactive or Active in a <span>
+#. %3$s is the addon's public status (Public, In Sandbox, ...) in a <span>
+#: views/developers/dashboard.thtml:69
+msgid "devcp_dashboard_addontype_status"
+msgstr "è attualmente %2$s e %3$s nella categoria %1$s"
+
+#: views/developers/dashboard.thtml:67
+msgid "devcp_dashboard_change_status"
+msgstr "Modifica stato"
+
+#. %s is the addons email address.
+#: views/developers/dashboard.thtml:99
+msgid "devcp_dashboard_disabled_questions"
+msgstr "Il componente aggiuntivo è stato disattivato da un amministratore e non può essere usato. Per ulteriori informazioni inviare una email a %s."
+
+#. %s is the (localized) add-on status string in a span, e.g. "Disabled"
+#: views/developers/dashboard.thtml:98
+msgid "devcp_dashboard_disabled_status"
+msgstr "Stato: %s"
+
+#: views/developers/dashboard.thtml:43
+msgid "devcp_dashboard_header_main"
+msgstr "Dashboard per sviluppatori"
+
+#: views/developers/dashboard.thtml:110
+msgid "devcp_dashboard_header_welcome"
+msgstr "Benvenuto nella dashboard per sviluppatori"
+
+#: views/developers/dashboard.thtml:68
+msgid "devcp_dashboard_inactive"
+msgstr "disattivato"
+
+#. %s is a date in the _('date') format
+#: views/developers/dashboard.thtml:65
+msgid "devcp_dashboard_last_edited"
+msgstr "Ultima modifica il %s"
+
+#: views/developers/dashboard.thtml:111
+msgid "devcp_dashboard_learn"
+msgstr "Al momento non risultano presenti tuoi componenti aggiuntivi ospitati su Mozilla Add-ons. Per scoprire come funziona la procedura e inviare il tuo primo componente aggiuntivo, fare clic su Per iniziare."
+
+#: views/developers/dashboard.thtml:112
+msgid "devcp_dashboard_start"
+msgstr "Per iniziare"
+
+#: views/developers/dashboard.thtml:82
+msgid "devcp_dashboard_versions"
+msgstr "Versioni e file"
+
+#: views/developers/dashboard.thtml:91
+msgid "devcp_dashboard_versions_new"
+msgstr "Carica una nuova versione"
+
+#. %s is the preview ID number.
+#: controllers/developers_controller.php:1415
+msgid "devcp_delete_previews_error"
+msgstr "L'anteprima %s non può essere eliminata dal database. Riprovare in seguito."
+
+#. %s is the preview ID number.
+#: controllers/developers_controller.php:1413
+msgid "devcp_delete_previews_success"
+msgstr "L'anteprima %s è stata eliminata correttamente."
+
+#: controllers/developers_controller.php:1089
+msgid "devcp_delete_version_priv_error"
+msgstr "Non si dispone dei permessi necessari per rimuovere versioni e file."
+
+#. %1$s is the count of files, a number
+#. %2$s is a status string like _('Public') or _('Incomplete')
+#: controllers/components/amo.php:549
+msgid "devcp_describe_version_status"
+msgid_plural "devcp_describe_version_status"
+msgstr[0] "%1$s file %2$s"
+msgstr[1] "%1$s file %2$s"
+
+#. %s is a version number. Example: 3.0
+#: views/developers/versions.thtml:65
+#, php-format
+msgid "devcp_details_version"
+msgstr "Versione %s"
+
+#: views/developers/discuss.thtml:68
+msgid "devcp_discuss_addreply_header"
+msgstr "Rispondi"
+
+#: views/developers/discuss.thtml:57
+msgid "devcp_discuss_allreplies_header"
+msgstr "Risposte"
+
+#. notice when an error occurs saving a discussion reply
+#. %1 is the email address (linked) for the amo-editors list
+#: views/developers/discuss.thtml:70
+msgid "devcp_discuss_error_notice"
+msgstr "Si è verificato un errore nel salvataggio della risposta. Contattare %1$s per segnalare il problema."
+
+#. %1 is the add-on name, %2 is the add-on's version number currently being reviewed by an editor
+#: views/developers/discuss.thtml:46
+msgid "devcp_discuss_intro"
+msgstr "Un revisore di Mozilla Add-ons ha richiesto ulteriori informazioni sulla versione %2$s del componente aggiuntivo %1$s."
+
+#. %1 is the add-on name
+#: views/developers/discuss.thtml:43
+msgid "devcp_discuss_pagetitle"
+msgstr "Fornisci ulteriori informazioni per la revisione del componente aggiuntivo %1$s"
+
+#. submit button text
+#: views/developers/discuss.thtml:79
+msgid "devcp_discuss_submit_reply"
+msgstr "Invia risposta"
+
+#: views/developers/discuss.thtml:72
+msgid "devcp_discuss_success_message"
+msgstr "La risposta è stata salvata correttamente. Gli altri partecipanti alla discussione riceveranno una notifica via e-mail."
+
+#. in an author/editor discussion about an add-on to be reviewed:
+#. %1 is the commenter's user name (linked).
+#. %2 is the full date the comment was made.
+#: views/developers/discuss.thtml:52
+#: views/developers/discuss.thtml:62
+msgid "devcp_discuss_writtenby"
+msgstr "scritto da %1$s il %2$s"
+
+#: views/developers/addon_edit_authors.thtml:72
+#: views/developers/addon_edit_authors.thtml:81
+msgid "devcp_edit_authors_add_author"
+msgstr "Aggiungi nuovo autore"
+
+#: views/developers/addon_edit_authors.thtml:96
+msgid "devcp_edit_authors_add_author_button"
+msgstr "Aggiungi autore"
+
+#: views/developers/addon_edit_authors.thtml:83
+msgid "devcp_edit_authors_add_email"
+msgstr "E-mail autore:"
+
+#: views/developers/addon_edit_authors.thtml:98
+msgid "devcp_edit_authors_add_loading"
+msgstr "Controllo e-mail..."
+
+#: views/developers/addon_edit_authors.thtml:70
+msgid "devcp_edit_authors_click_save"
+msgstr "Fare clic sul pulsante Aggiorna autori per salvare."
+
+#: views/developers/addon_edit_authors.thtml:58
+msgid "devcp_edit_authors_header_current"
+msgstr "Autori attuali"
+
+#: views/developers/addon_edit_authors.thtml:50
+msgid "devcp_edit_authors_header_manage"
+msgstr "Gestione autori"
+
+#: views/developers/addon_edit_authors.thtml:93
+msgid "devcp_edit_authors_label_add_listed"
+msgstr "Indica come autore nella pagina pubblica"
+
+#: views/developers/addon_edit_authors.thtml:89
+msgid "devcp_edit_authors_label_developer"
+msgstr "<strong>Sviluppatore</strong> - Può gestire tutti gli aspetti di questo componente, tranne aggiungere o rimuovere altri autori."
+
+#: views/developers/addon_edit_authors.thtml:88
+msgid "devcp_edit_authors_label_owner"
+msgstr "<strong>Proprietario</strong> - Può gestire tutti gli aspetti di questo componente, compreso aggiungere o rimuovere altri autori."
+
+#: views/developers/addon_edit_authors.thtml:90
+msgid "devcp_edit_authors_label_viewer"
+msgstr "<strong>Ospite</strong> - Può visualizzare i dettagli e le statistiche del componente aggiuntivo, ma non può effettuare alcuna modifica."
+
+#. Placeholder for the empty option in a <select>.
+#: views/developers/addon_edit_categories.thtml:69
+msgid "devcp_edit_authors_option_empty"
+msgstr "----------------"
+
+#: views/developers/addon_edit_authors.thtml:86
+msgid "devcp_edit_authors_select_role"
+msgstr "Selezionare un ruolo per l'autore:"
+
+#. Column name in a table.
+#: views/developers/addon_edit_authors.thtml:62
+msgid "devcp_edit_authors_th_author"
+msgstr "Autore"
+
+#. Column name in a table.
+#: views/developers/addon_edit_authors.thtml:64
+msgid "devcp_edit_authors_th_listed"
+msgstr "Visualizzato"
+
+#. Column name in a table.
+#: views/developers/addon_edit_authors.thtml:63
+msgid "devcp_edit_authors_th_role"
+msgstr "Ruolo"
+
+#: views/developers/addon_edit_authors.thtml:77
+msgid "devcp_edit_authors_update_author"
+msgstr "Aggiorna autori"
+
+#: views/developers/addon_edit_categories.thtml:99
+msgid "devcp_edit_categories_button_update"
+msgstr "Aggiorna categorie"
+
+#: views/developers/addon_edit_categories.thtml:88
+msgid "devcp_edit_categories_does_not_fit"
+msgstr "Il mio componente aggiuntivo non rientra in nessuna delle categorie disponibili."
+
+#. %s is the application name (Firefox, Thunderbird).
+#: views/developers/addon_edit_categories.thtml:61
+msgid "devcp_edit_categories_header_application"
+msgstr "Categorie %s"
+
+#: views/developers/addon_edit_categories.thtml:49
+msgid "devcp_edit_categories_header_manage"
+msgstr "Gestione categorie componenti aggiuntivi"
+
+#: views/developers/addon_edit_categories.thtml:91
+msgid "devcp_edit_categories_hover"
+msgstr "Posizionare il mouse sopra ad una categoria per visualizzare la descrizione."
+
+#. %s is the category number (1, 2, 3).
+#: views/developers/addon_edit_categories.thtml:67
+msgid "devcp_edit_categories_label_category_num"
+msgstr "Categoria %s"
+
+#: views/developers/addon_edit_categories.thtml:94
+#: views/developers/addon_edit_categories.thtml:103
+msgid "devcp_edit_categories_none_available"
+msgstr "Nessuna categoria disponibile per questo tipo di componente aggiuntivo e applicazione."
+
+#: views/developers/addon_edit_categories.thtml:86
+msgid "devcp_edit_categories_other"
+msgstr "Utilizzare questa categoria solo se il componente aggiuntivo non è adatto a nessuno delle altre categorie disponibili."
+
+#. %s is the application name (Firefox, Thunderbird).
+#: views/developers/addon_edit_categories.thtml:63
+msgid "devcp_edit_categories_select_application_categories"
+msgstr "Selezionare fino a 3 categorie per %s"
+
+#: views/developers/addon_edit.thtml:47
+msgid "devcp_edit_dd_manage_authors"
+msgstr "Aggiungi o rimuovi utenti in grado di gestire questo componente aggiuntivo."
+
+#: views/developers/addon_edit.thtml:49
+msgid "devcp_edit_dd_manage_categories"
+msgstr "Selezionare le categorie rilevanti per ogni applicazione con cui il componente aggiuntivo è compatibile."
+
+#: views/developers/addon_edit.thtml:51
+msgid "devcp_edit_dd_manage_description"
+msgstr "Aggiungi o modifica le traduzioni del riepilogo, della descrizione, della licenza per l'utente finale e dell'informativa sulla privacy."
+
+#: views/developers/addon_edit.thtml:53
+msgid "devcp_edit_dd_manage_properties"
+msgstr "Modifica il nome del componente aggiuntivo, il sito web, l'icona e altri parametri."
+
+#: views/developers/addon_edit_descriptions.thtml:116
+msgid "devcp_edit_description_button_update"
+msgstr "Aggiorna descrizioni"
+
+#: views/developers/addon_edit_descriptions.thtml:115
+msgid "devcp_edit_description_correct_error"
+msgstr "Correggere gli errori evidenziati in colore rosso."
+
+#: views/developers/addon_edit_descriptions.thtml:51
+msgid "devcp_edit_descriptions_header"
+msgstr "Modifica la descrizione"
+
+#: views/developers/addon_edit_descriptions.thtml:94
+msgid "devcp_edit_descriptions_transbox_comments_description"
+msgstr "Inserire qualsiasi informazione utile per l'utente che non è adatta ai campi riepilogo e descrizione. Ad esempio è possibile inserire eventuali bug, informazioni su come segnalare bug, anticipare la data di rilascio di una nuova versione, ecc. "
+
+#: views/developers/addon_edit_descriptions.thtml:93
+msgid "devcp_edit_descriptions_transbox_comments_name"
+msgstr "Commenti dello sviluppatore"
+
+#: views/developers/addon_edit_descriptions.thtml:86
+msgid "devcp_edit_descriptions_transbox_description_description"
+msgstr "La descrizione del componente aggiuntivo è una spiegazione più dettagliata delle caratteristiche, delle funzioni e di altre informazioni rilevanti. Viene visualizzata sotto al riepilogo nella scheda del componente aggiuntivo."
+
+#: views/developers/addon_edit_descriptions.thtml:85
+msgid "devcp_edit_descriptions_transbox_description_name"
+msgstr "Descrizione"
+
+#: views/developers/addon_edit_descriptions.thtml:103
+msgid "devcp_edit_descriptions_transbox_eula_description"
+msgstr "Se il componente aggiuntivo prevede una Licenza per l'utente finale (EULA), inserirne il testo in questo spazio. È possibile fare in modo che l'accettazione della licenza sia un passo obbligatorio per l'installazione. Attenzione: un EULA non è la stessa cosa di una licenza software, come ad esempio GPL o MPL.If your add-on has an End-User License Agreement (EULA), please enter its text below. If set below, users will be required to agree to this before installing your add-on. Please note that a EULA is not the same as a code license such as GPL or MPL."
+
+#: views/developers/addon_edit_descriptions.thtml:102
+msgid "devcp_edit_descriptions_transbox_eula_name"
+msgstr "Licenza per l'utente finale"
+
+#: views/developers/addon_edit_descriptions.thtml:112
+msgid "devcp_edit_descriptions_transbox_privacy_description"
+msgstr "Se il componente aggiuntivo prevede un'informativa per la privacy, inserirne il testo in questo spazio. Verrà visualizzato un link all'informativa nella scheda del componente aggiuntivo."
+
+#: views/developers/addon_edit_descriptions.thtml:111
+msgid "devcp_edit_descriptions_transbox_privacy_name"
+msgstr "Informativa sulla privacy"
+
+#: views/developers/addon_edit_descriptions.thtml:78
+msgid "devcp_edit_descriptions_transbox_summary_description"
+msgstr "Il riepilogo è una breve spiegazione delle funzioni di base del componente aggiuntivo e viene visualizzato nelle ricerche e negli elenchi, così come nella parte superiore della scheda del componente aggiuntivo. <strong>Limitare il testo a 250 caratteri.</strong>"
+
+#: views/developers/addon_edit_descriptions.thtml:77
+msgid "devcp_edit_descriptions_transbox_summary_name"
+msgstr "Riepilogo"
+
+#: views/developers/addon_edit.thtml:46
+msgid "devcp_edit_dt_manage_authors"
+msgstr "Gestisci autori"
+
+#: views/developers/addon_edit.thtml:48
+msgid "devcp_edit_dt_manage_categories"
+msgstr "Gestisci categorie"
+
+#: views/developers/addon_edit.thtml:50
+msgid "devcp_edit_dt_manage_descriptions"
+msgstr "Gestisci descrizioni"
+
+#: views/developers/addon_edit.thtml:52
+msgid "devcp_edit_dt_manage_properties"
+msgstr "Gestisci altre proprietà"
+
+#: views/developers/addon_edit_properties.thtml:170
+msgid "devcp_edit_label_externalsoftware"
+msgstr "Questo componente aggiuntivo richiede la presenza di software esterno"
+
+#: views/developers/addon_edit_properties.thtml:205
+msgid "devcp_edit_label_locale_disambiguation"
+msgstr "Altre informazioni sul locale"
+
+#: views/developers/addon_edit_properties.thtml:168
+msgid "devcp_edit_label_prerelease"
+msgstr "Questa è una pre-release"
+
+#: views/developers/addon_edit_properties.thtml:169
+msgid "devcp_edit_label_sitespecific"
+msgstr "Questo componente aggiuntivo è specifico per un determinato sito web"
+
+#: views/developers/addon_edit_properties.thtml:202
+msgid "devcp_edit_label_target_locale"
+msgstr "Locale di riferimento"
+
+#: views/developers/addon_edit_properties.thtml:212
+msgid "devcp_edit_properties_button_update"
+msgstr "Aggiorna proprietà"
+
+#: views/developers/addon_edit_properties.thtml:198
+msgid "devcp_edit_properties_change_guid"
+msgstr "Modificare solo se si comprendono tutte le possibili conseguenze."
+
+#: views/developers/addon_edit_properties.thtml:109
+msgid "devcp_edit_properties_current_icon"
+msgstr "Icona attuale"
+
+#: views/developers/addon_edit_properties.thtml:85
+msgid "devcp_edit_properties_default_locale"
+msgstr "Il locale predefinito di un componente aggiuntivo è il locale principale per cui deve essere presente la traduzione. Se la traduzione di una descrizione non è disponibile nella lingua dell'utente, verrà utilizzata la descrizione nel locale predefinito."
+
+#: views/developers/addon_edit_properties.thtml:167
+msgid "devcp_edit_properties_flags"
+msgstr "Questi parametri vengono usati per filtrare e classificare i componenti aggiuntivi."
+
+#: views/developers/addon_edit_properties.thtml:174
+msgid "devcp_edit_properties_guid"
+msgstr "Il GUID viene specificato nel file install.rdf e identifica in modo univoco un componente aggiuntivo. Non è possibile modificare il GUID una volta che l'estensione è presente su Mozilla Add-ons."
+
+#: views/developers/addon_edit_properties.thtml:53
+msgid "devcp_edit_properties_header"
+msgstr "Modifica proprietà"
+
+#: views/developers/addon_edit_properties.thtml:186
+msgid "devcp_edit_properties_header_addon_type"
+msgstr "Tipo"
+
+#: views/developers/addon_edit_properties.thtml:181
+msgid "devcp_edit_properties_header_admin_settings"
+msgstr "Impostazioni amministratore"
+
+#: views/developers/addon_edit_properties.thtml:84
+msgid "devcp_edit_properties_header_default_locale"
+msgstr "Locale predefinito"
+
+#: views/developers/addon_edit_properties.thtml:166
+msgid "devcp_edit_properties_header_flags"
+msgstr "Parametri"
+
+#: views/developers/addon_edit_properties.thtml:173
+#: views/developers/addon_edit_properties.thtml:197
+msgid "devcp_edit_properties_header_guid"
+msgstr "GUID"
+
+#: views/developers/addon_edit_properties.thtml:104
+msgid "devcp_edit_properties_header_icon"
+msgstr "Icona"
+
+#: views/developers/addon_edit_properties.thtml:159
+msgid "devcp_edit_properties_header_other_settings"
+msgstr "Altre impostazioni"
+
+#. A header on the admin page to toggle trusted status.
+#: views/developers/addon_edit_properties.thtml:182
+msgid "devcp_edit_properties_header_trusted"
+msgstr "Affidabile?"
+
+#: views/developers/addon_edit_properties.thtml:160
+msgid "devcp_edit_properties_header_view_source"
+msgstr "Visualizza sorgente online"
+
+#. %s is a comma-separated list of image extensions ".png, .jpg"
+#: views/developers/addon_edit_properties.thtml:106
+msgid "devcp_edit_properties_icon"
+msgstr "L'icona del componente aggiuntivo è una piccola immagine visualizzata accanto al nome nei risultati di ricerca, nella scheda e nella finestra di installazione. L'immagine verrà automaticamente ridimensionata a 32x32 pixel. Utilizzare uno dei seguenti formati: %s"
+
+#: views/developers/addon_edit_properties.thtml:171
+msgid "devcp_edit_properties_label_binary"
+msgstr "Questo componente aggiuntivo contiene elementi compilati"
+
+#: views/developers/addon_edit_properties.thtml:185
+msgid "devcp_edit_properties_label_not_trusted"
+msgstr "Non affidabile"
+
+#: views/developers/addon_edit_properties.thtml:184
+msgid "devcp_edit_properties_label_trusted"
+msgstr "Affidabile"
+
+#: views/developers/addon_edit_properties.thtml:110
+msgid "devcp_edit_properties_new_icon"
+msgstr "Nuova icona"
+
+#: views/developers/addon_edit_properties.thtml:118
+msgid "devcp_edit_properties_remove_icon"
+msgstr "Rimuovi icona"
+
+#: views/developers/addon_edit_properties.thtml:136
+msgid "devcp_edit_properties_transbox_homepage_description"
+msgstr "Se il componente aggiuntivo ha un altro sito web, inserire l'indirizzo in questo campo. Non è necessario aggiungere altre traduzioni, a meno che il sito sia localizzato in diverse lingue."
+
+#: views/developers/addon_edit_properties.thtml:135
+msgid "devcp_edit_properties_transbox_homepage_name"
+msgstr "Sito web"
+
+#: views/developers/addon_edit_properties.thtml:79
+msgid "devcp_edit_properties_transbox_name_description"
+msgstr "Il nome del componente aggiuntivo viene utilizzato in tutti gli elenchi."
+
+#: views/developers/addon_edit_properties.thtml:78
+msgid "devcp_edit_properties_transbox_name_name"
+msgstr "Nome"
+
+#: views/developers/addon_edit_properties.thtml:145
+msgid "devcp_edit_properties_transbox_supportemail_description"
+msgstr "Se esiste un indirizzo e-mail per richieste di supporto, inserirlo in questo campo. Non è necessario aggiungere altre traduzioni, a meno che vengano usati indirizzi e-mail diversi per lingue diverse."
+
+#: views/developers/addon_edit_properties.thtml:144
+msgid "devcp_edit_properties_transbox_supportemail_name"
+msgstr "Indirizzo e-mail per il supporto"
+
+#: views/developers/addon_edit_properties.thtml:154
+msgid "devcp_edit_properties_transbox_supporturl_description"
+msgstr "Se esiste un sito web o un forum di supporto, inserire l'indirizzo in questo campo. Non è necessario aggiungere altre traduzioni, a meno che il sito sia localizzato in diverse lingue."
+
+#: views/developers/addon_edit_properties.thtml:153
+msgid "devcp_edit_properties_transbox_supporturl_name"
+msgstr "Sito web per il supporto"
+
+#: views/developers/addon_edit_properties.thtml:183
+msgid "devcp_edit_properties_trusted"
+msgstr "Un componente aggiuntivo affidabile può venire pubblicato senza l'intervento di un revisore."
+
+#. %s is href="..." and should stay in the <a> tag.
+#: views/developers/addon_edit_properties.thtml:119
+msgid "devcp_edit_properties_undelete"
+msgstr "Proseguendo con il salvataggio l'icona verrò eliminata. <a %s>Annullare?</a>"
+
+#: views/developers/addon_edit_properties.thtml:161
+msgid "devcp_edit_properties_view_source"
+msgstr "È possibile fare in modo che il codice sorgente del componente aggiuntivo venga visualizzato solo dagli utenti registrati."
+
+#: views/developers/addon_edit_properties.thtml:162
+msgid "devcp_edit_properties_view_source_allow"
+msgstr "Consenti la visualizzazione online dei sorgenti"
+
+#: views/developers/addon_edit_properties.thtml:163
+msgid "devcp_edit_properties_view_source_do_not_allow"
+msgstr "Impedisci la visualizzazione online dei sorgenti"
+
+#: views/elements/developers/editbox.thtml:46
+msgid "devcp_editbox_authors"
+msgstr "Autori"
+
+#: views/elements/developers/editbox.thtml:47
+msgid "devcp_editbox_categories"
+msgstr "Categorie"
+
+#: views/elements/developers/editbox.thtml:52
+msgid "devcp_editbox_change_status"
+msgstr "Modifica stato"
+
+#: views/elements/developers/editbox.thtml:48
+msgid "devcp_editbox_descriptions"
+msgstr "Descrizioni"
+
+#: views/elements/developers/editbox.thtml:43
+msgid "devcp_editbox_edit_addon"
+msgstr "Modifica componente aggiuntivo"
+
+#: views/elements/developers/editbox.thtml:57
+msgid "devcp_editbox_new_version"
+msgstr "Nuova versione"
+
+#: views/elements/developers/editbox.thtml:49
+msgid "devcp_editbox_properties"
+msgstr "Proprietà"
+
+#: views/elements/developers/editbox.thtml:60
+msgid "devcp_editbox_screenshots"
+msgstr "Anteprime"
+
+#: views/elements/developers/editbox.thtml:53
+msgid "devcp_editbox_statistics_dashboard"
+msgstr "Dashboard statistiche"
+
+#: views/elements/developers/editbox.thtml:54
+msgid "devcp_editbox_versions"
+msgstr "Versioni e file"
+
+#: views/elements/developers/editbox.thtml:42
+msgid "devcp_editbox_view_listing"
+msgstr "Visualizza elenco"
+
+#: views/elements/developers/editorsmenu.thtml:59
+msgid "devcp_editorsqueue_featured"
+msgstr "Componenti aggiuntivi consigliati"
+
+#. %1 is the review count
+#: views/elements/developers/editorsqueue.thtml:42
+#: views/elements/developers/editorsmenu.thtml:56
+#, php-format
+msgid "devcp_editorsqueue_moderatedreviews"
+msgid_plural "devcp_editorsqueue_moderatedreviews"
+msgstr[0] "Recensioni moderate (%s)"
+msgstr[1] "Recensioni moderate (%s)"
+
+#. %1 is the nominated addons count
+#: views/elements/developers/editorsqueue.thtml:44
+#: views/elements/developers/editorsmenu.thtml:58
+#, php-format
+msgid "devcp_editorsqueue_nominated"
+msgid_plural "devcp_editorsqueue_nominated"
+msgstr[0] "Componenti aggiuntivi segnalati (%s)"
+msgstr[1] "Componenti aggiuntivi segnalati (%s)"
+
+#. %1 is the update count
+#: views/elements/developers/editorsqueue.thtml:43
+#: views/elements/developers/editorsmenu.thtml:57
+#, php-format
+msgid "devcp_editorsqueue_pendingupdates"
+msgid_plural "devcp_editorsqueue_pendingupdates"
+msgstr[0] "Aggiornamenti in sospeso (%s)"
+msgstr[1] "Aggiornamenti in sospeso (%s)"
+
+#: controllers/statistics_controller.php:147
+#: controllers/statistics_controller.php:361
+#: controllers/previews_controller.php:108
+#: controllers/previews_controller.php:211
+#: controllers/previews_controller.php:312
+msgid "devcp_error_addon_access_denied"
+msgstr "Non hai accesso a questo componente aggiuntivo."
+
+#. %s is a complete URL with the text from devcp_error_appversion_reference_link_text
+#. in the <a> tag. This should be fixed.
+#: controllers/components/developers.php:591
+#, php-format
+msgid "devcp_error_appversion_reference_link"
+msgstr "Consultare %s come riferimento."
+
+#. This is the link text in the <a> for devcp_error_appversion_reference_link. This
+#. should be fixed.
+#: controllers/components/developers.php:591
+msgid "devcp_error_appversion_reference_link_text"
+msgstr "questa pagina"
+
+#: views/developers/addon_edit_authors.thtml:76
+msgid "devcp_error_empty_authors"
+msgstr "Il componente aggiuntivo deve avere almeno un proprietario."
+
+#. %1$s is the name of the file
+#: controllers/components/developers.php:658
+msgid "devcp_error_file_exists"
+msgstr "È già presente una versione di questo componente aggiuntivo. Per sostituirla, è prima necessario rimuovere il file %1$s."
+
+#. %1$s is a file extension. Example: .exe
+#. %2$s is a comma separated list of extensions. Example: .xpi, .jar
+#: controllers/components/developers.php:355
+#, php-format
+msgid "devcp_error_file_extension"
+msgstr "Questa estensione (%s) non è consentita per questo tipo di componente aggiuntivo. Utilizzare una delle seguenti estensioni: %s"
+
+#: controllers/components/developers.php:64
+msgid "devcp_error_five_categories"
+msgstr "Non selezionare più di cinque categorie."
+
+#: controllers/components/developers.php:526
+msgid "devcp_error_guid_application"
+msgstr "L'ID di questo componente aggiuntivo è già utilizzato da un'applicazione."
+
+#: controllers/components/developers.php:337
+#: controllers/components/developers.php:389
+msgid "devcp_error_http_incomplete"
+msgstr "Trasferimento interrotto"
+
+#: controllers/components/developers.php:335
+#: controllers/components/developers.php:336
+#: controllers/components/developers.php:387
+#: controllers/components/developers.php:388
+msgid "devcp_error_http_maxupload"
+msgstr "Eccede la dimensione massima consentita per l'upload"
+
+#: controllers/components/developers.php:338
+#: controllers/components/developers.php:390
+msgid "devcp_error_http_nofile"
+msgstr "Non è stato caricato nessun file"
+
+#. %1$s is a file extension. Example: .exe
+#. %2$s is a comma separated list of extensions. Example: .xpi, .jar
+#: controllers/components/developers.php:401
+#, php-format
+msgid "devcp_error_icon_extension"
+msgstr "Questa estensione (%1$s) non è consentita per un'icona. Utilizzare una delle seguenti estensioni: %1$s"
+
+#: controllers/developers_controller.php:504
+msgid "devcp_error_index_rdf_notfound"
+msgstr "Non è presente il file install.rdf."
+
+#: controllers/components/developers.php:601
+msgid "devcp_error_install_manifest"
+msgstr "Sono stati rilevati i seguenti errori nel file install.rdf:"
+
+#: controllers/developers_controller.php:1463
+msgid "devcp_error_invalid_addontype"
+msgstr "Selezionare una tipologia valida per il componente aggiuntivo."
+
+#. %$1s is a version. Example: 3.1.1
+#. %$2s is an add-on name.
+#: controllers/components/developers.php:569
+#: controllers/components/developers.php:581
+#, php-format
+msgid "devcp_error_invalid_appversion"
+msgstr "%1$s non è una versione valida per %2$s"
+
+#. %s is a string
+#: controllers/components/developers.php:521
+#, php-format
+msgid "devcp_error_invalid_guid"
+msgstr "L'ID di questo componente aggiuntivo non è valido: %s"
+
+#. %$1s is a version. Example: 3.1.1
+#. %$2s is an add-on name.
+#: controllers/components/developers.php:572
+#, php-format
+msgid "devcp_error_invalid_minversion"
+msgstr "%1$s non è una versione valida per %2$s: le versioni minime non possono contenere *"
+
+#: controllers/components/developers.php:536
+msgid "devcp_error_invalid_version"
+msgstr "La versione di questo componente aggiuntivo non è valida: consultare le <a href=\"http://developer.mozilla.org/en/docs/Toolkit_version_format\">specifiche</a>"
+
+#: controllers/components/developers.php:531
+msgid "devcp_error_invalid_version_spaces"
+msgstr "La versione di questo componente aggiuntivo non è valida: le versioni non possono contenere spazi."
+
+#. %s is an error message from the parser.
+#: controllers/components/developers.php:501
+#, php-format
+msgid "devcp_error_manifest_parse"
+msgstr "Si sono verificati i seguenti errori durante l'elaborazione del file install.rdf: %s"
+
+#: controllers/components/developers.php:373
+msgid "devcp_error_move_file"
+msgstr "Non è possibile spostare il file"
+
+#. %s is the name of a file
+#: controllers/components/developers.php:650
+#: controllers/components/developers.php:662
+#: controllers/components/developers.php:667
+#: controllers/components/developers.php:727
+#: controllers/components/developers.php:738
+#: controllers/components/developers.php:743
+#, php-format
+msgid "devcp_error_moving_file"
+msgstr "Si è verificato un errore durante lo spostamento di %s."
+
+#: controllers/components/developers.php:595
+msgid "devcp_error_mozilla_application"
+msgstr "È necessario indicare almeno un'applicazione Mozilla di riferimento."
+
+#: controllers/components/developers.php:516
+msgid "devcp_error_no_guid"
+msgstr "Impossibile trovare un ID per questo componente aggiuntivo nel file install.rdf."
+
+#: controllers/components/developers.php:287
+msgid "devcp_error_no_platform"
+msgstr "Nessuna piattaforma selezionata"
+
+#: controllers/components/developers.php:59
+msgid "devcp_error_one_category"
+msgstr "Selezionare almeno una categoria."
+
+#: controllers/components/developers.php:92
+msgid "devcp_error_one_user"
+msgstr "È necessario indicare almeno un autore per questo componente aggiuntivo."
+
+#. %1$s is a file extension. Example: .exe
+#. %2$s is a comma separated list of extensions. Example: .xpi, .jar
+#: controllers/components/developers.php:1081
+#, php-format
+msgid "devcp_error_preview_extension"
+msgstr "Questa estensione (%1$s) non è consentita per un'anteprima. Utilizzare una delle seguenti estensioni: %2$s"
+
+#: controllers/components/developers.php:511
+msgid "devcp_error_updatekey"
+msgstr "I componenti aggiuntivi non possono avere un updateKey. Rimuovere questa chiave dal file install.rdf e riprovare."
+
+#: controllers/components/developers.php:506
+msgid "devcp_error_updateurl"
+msgstr "I componenti aggiuntivi non possono utilizzare un updateURL esterno. Rimuoverlo da install.rdf e riprovare."
+
+#: controllers/developers_controller.php:465
+#: controllers/components/developers.php:271
+msgid "devcp_error_upload_file"
+msgstr "Inserire un file da caricare."
+
+#: views/developers/uploader.thtml:135
+msgid "devcp_input_upload_file"
+msgstr "Carica file"
+
+#: views/pages/js_constants.js.thtml:89
+msgid "devcp_js_a_cancel"
+msgstr "Annulla"
+
+#: views/pages/js_constants.js.thtml:90
+msgid "devcp_js_add_email"
+msgstr "Inserire l'indirizzo e-mail dell'autore da aggiungere."
+
+#. alt text for a down-arrow image.
+#: views/pages/js_constants.js.thtml:81
+msgid "devcp_js_img_move_down"
+msgstr "Sposta in basso"
+
+#. alt text for an up-arrow image.
+#: views/pages/js_constants.js.thtml:82
+msgid "devcp_js_img_move_up"
+msgstr "Sposta in alto"
+
+#: views/pages/js_constants.js.thtml:91
+msgid "devcp_js_img_remove_compat"
+msgstr "Rimuovi compatibilità applicazione"
+
+#: views/pages/js_constants.js.thtml:86
+msgid "devcp_js_input_list_author"
+msgstr "Visualizza come autore negli elenchi pubblici"
+
+#: views/pages/js_constants.js.thtml:92
+msgid "devcp_js_license_select"
+msgstr "Selezionare una licenza."
+
+#: views/pages/js_constants.js.thtml:93
+msgid "devcp_js_license_text"
+msgstr "Inserire il testo della licenza."
+
+#. <option> text in a <select> for Author role in an add-on.
+#: views/pages/js_constants.js.thtml:84
+msgid "devcp_js_option_developer"
+msgstr "Sviluppatore"
+
+#. <option> text in a <select> for Author role in an add-on.
+#: views/pages/js_constants.js.thtml:83
+msgid "devcp_js_option_owner"
+msgstr "Proprietario"
+
+#. <option> text in a <select> for Author role in an add-on.
+#: views/pages/js_constants.js.thtml:85
+msgid "devcp_js_option_viewer"
+msgstr "Ospite"
+
+#: views/pages/js_constants.js.thtml:88
+msgid "devcp_js_remove_author"
+msgstr "Rimuovi autore"
+
+#: views/pages/js_constants.js.thtml:87
+msgid "devcp_js_sure_remove"
+msgstr "<strong>Rimuovere</strong> questo autore?"
+
+#: views/pages/js_constants.js.thtml:77
+msgid "devcp_js_upload_alert"
+msgstr "Selezionare il file da caricare."
+
+#. %1$s is an addon id, like 32.
+#. %2$s is a version number, like 3.5.
+#: controllers/components/developers.php:1212
+msgid "devcp_license_existing"
+msgstr "Licenza personalizzata per %1$s v%2$s"
+
+#: views/elements/developers/localebox.thtml:44
+msgid "devcp_localebox_header_localizedfields"
+msgstr "Campi localizzati"
+
+#. %1 is the default locale
+#: views/elements/developers/localebox.thtml:48
+#, php-format
+msgid "devcp_localebox_intro"
+msgstr "È possibile far comparire alcuni campi presenti in questa pagina nella lingua dell'utente finale. Selezionare un locale tra quelli disponibili per farlo comparire nelle lingue di destinazione. Se la traduzione in una determinata lingua non è disponibile le informazioni verranno visualizzate utilizzando il locale predefinito (%s)."
+
+#: views/elements/developers/sidebar.thtml:68
+#: views/elements/developers/myaddons.thtml:75
+msgid "devcp_myaddons_admincp_link"
+msgstr "Pannello di amministrazione"
+
+#: views/elements/developers/sidebar.thtml:65
+#: views/elements/developers/myaddons.thtml:72
+msgid "devcp_myaddons_editorcp_link"
+msgstr "Pannello di amministrazione per revisori"
+
+#: views/elements/developers/myaddons.thtml:52
+msgid "devcp_myaddons_link"
+msgstr "I miei componenti aggiuntivi"
+
+#: views/elements/developers/sidebar.thtml:70
+#: views/elements/developers/myaddons.thtml:77
+msgid "devcp_myaddons_mainpage_link"
+msgstr "Torna alla pagina principale"
+
+#: views/elements/developers/sidebar.thtml:63
+#: views/elements/developers/myaddons.thtml:70
+msgid "devcp_myaddons_statistics_link"
+msgstr "Pannello statistiche"
+
+#: views/elements/developers/sidebar.thtml:62
+#: views/elements/developers/myaddons.thtml:69
+msgid "devcp_myaddons_submitaddon_link"
+msgstr "Inserisci un nuovo componente aggiuntivo"
+
+#: views/elements/developers/sidebar.thtml:48
+#: views/elements/developers/myaddons.thtml:67
+msgid "devcp_myaddons_title"
+msgstr "Strumenti per sviluppatori"
+
+#. %1$s is an add-on ID, perhaps 167.
+#. %2$s is a URL.
+#: controllers/developers_controller.php:256
+msgid "devcp_new_addon_error"
+msgstr "L'ID (%1$s) di questo componente aggiuntivo risulta già presente nel database. Se questo è il tuo componente aggiuntivo, puoi <a href=\"%2$s\">caricare una nuova versione</a>."
+
+#: views/developers/addon_status_nominate.thtml:62
+msgid "devcp_nominate_cancel"
+msgstr "Annullare e tornare indietro"
+
+#. %1 is the add-on name
+#: views/developers/addon_status_nominate.thtml:61
+#, php-format
+msgid "devcp_nominate_submit_nominate"
+msgstr "Segnala %s"
+
+#: views/developers/addon_edit_properties.thtml:50
+#: views/developers/addon_status.thtml:49
+#: views/developers/versions_edit.thtml:50
+msgid "devcp_notice_changes_error"
+msgstr "<span>Impossibile salvare una o più modifiche.</span><br />Verificare gli errori segnalati. Le altre modifiche sono state salvate correttamente."
+
+#: views/developers/addon_edit_authors.thtml:47
+#: views/developers/addon_edit_properties.thtml:47
+#: views/developers/addon_status.thtml:46
+#: views/developers/addon_edit_descriptions.thtml:47
+#: views/developers/versions_edit.thtml:47
+#: views/developers/addon_edit_categories.thtml:46
+msgid "devcp_notice_changes_saved"
+msgstr "<span>Le modifiche sono state salvate.</span><br /> Potrebbero trascorrere diverse ore prima che le modifiche appaiano in tutte le sezioni del sito web."
+
+#: controllers/previews_controller.php:252
+msgid "devcp_notice_cleardefault"
+msgstr "Se si elimina questa immagine come anteprima predefinita, un'altra immagine verrà scelta automaticamente al suo posto."
+
+#: controllers/previews_controller.php:184
+#: controllers/previews_controller.php:251
+msgid "devcp_notice_makedefault"
+msgstr "Se si usa questa immagine come anteprima predefinita ne verrà automaticamente eliminato lo status dall'immagine usata in precedenza."
+
+#: views/developers/addon_edit_authors.thtml:70
+msgid "devcp_notice_unsaved_changes"
+msgstr "Sono presenti modifiche non salvate."
+
+#: controllers/developers_controller.php:87
+#: controllers/developers_controller.php:97
+#: controllers/developers_controller.php:100
+#: controllers/previews_controller.php:67
+#: controllers/previews_controller.php:79
+#: controllers/previews_controller.php:82
+msgid "devcp_pagetitle"
+msgstr "Strumenti per sviluppatori"
+
+#: controllers/previews_controller.php:103
+#: controllers/previews_controller.php:104
+msgid "devcp_preview_add_pagetitle"
+msgstr "Aggiungi anteprima"
+
+#: controllers/previews_controller.php:135
+msgid "devcp_preview_added_successfully"
+msgstr "Anteprima aggiunta con successo."
+
+#: controllers/previews_controller.php:323
+msgid "devcp_preview_deleted_successfully"
+msgstr "Anteprima cancellata con successo."
+
+#: controllers/previews_controller.php:194
+#: controllers/previews_controller.php:195
+msgid "devcp_preview_edit_pagetitle"
+msgstr "Modifica anteprima"
+
+#: controllers/previews_controller.php:237
+msgid "devcp_preview_updated_successfully"
+msgstr "Anteprima aggiornata con successo."
+
+#: views/developers/previews.thtml:120
+msgid "devcp_previews_a_another"
+msgstr "Aggiungi un'altra anteprima"
+
+#: views/developers/previews.thtml:96
+msgid "devcp_previews_a_delete"
+msgstr "Elimina anteprima"
+
+#: views/developers/previews.thtml:95
+msgid "devcp_previews_a_replace"
+msgstr "Sostituisci anteprima"
+
+#: views/developers/previews.thtml:126
+msgid "devcp_previews_a_update"
+msgstr "Aggiorna anteprima"
+
+#: views/developers/previews.thtml:115
+#: views/developers/previews.thtml:124
+msgid "devcp_previews_add_new"
+msgstr "Aggiungi nuova anteprima"
+
+#. %s is a list of file extensions, e.g. ".png, .gif"
+#: views/developers/previews.thtml:116
+msgid "devcp_previews_add_select"
+msgstr "Selezionare un'immagine da caricare. Le immagini che eccedono la larghezza di 700 pixel e l'altezza di 525 pixel verranno ridimensionate. Formati accettati: %s"
+
+#: views/developers/previews.thtml:121
+msgid "devcp_previews_click_below"
+msgstr "Fare clic sul pulsante Aggiorna anteprima per caricare il file."
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/previews.thtml:102
+msgid "devcp_previews_click_update"
+msgstr "Fare clic sul pulsante Aggiorna anteprime per salvare questa immagine. (<a %s>Annulla?</a>)"
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/previews.thtml:107
+msgid "devcp_previews_error_message"
+msgstr "Questa anteprima verrà eliminata premendo il pulsante Aggiorna anteprime. (<a %s>Annulla?</a>)"
+
+#: views/previews/add.thtml:45
+msgid "devcp_previews_filetype_info"
+msgstr "Usare il modulo seguente per caricare uno screenshot in formato PNG, JPG o GIF del proprio componente aggiuntivo. Le immagini con dimensioni superiori a 700 pixel di larghezza e 525 pixel di altezza verranno automaticamente ridimensionate."
+
+#: views/previews/add.thtml:43
+msgid "devcp_previews_header_add"
+msgstr "Aggiungi anteprima"
+
+#: views/developers/previews.thtml:80
+msgid "devcp_previews_header_caption"
+msgstr "Descrizione anteprima"
+
+#: views/previews/edit.thtml:43
+msgid "devcp_previews_header_edit"
+msgstr "Modifica anteprima"
+
+#: views/developers/previews.thtml:93
+msgid "devcp_previews_label_default"
+msgstr "Anteprima predefinita"
+
+#: views/previews/add.thtml:54
+msgid "devcp_previews_label_file"
+msgstr "Anteprima"
+
+#: views/previews/add.thtml:59
+#: views/previews/edit.thtml:50
+msgid "devcp_previews_label_makedefault"
+msgstr "Usa questa immagine come anteprima predefinita"
+
+#: views/developers/previews.thtml:100
+msgid "devcp_previews_label_new"
+msgstr "Nuova immagine:"
+
+#: views/developers/previews.thtml:118
+msgid "devcp_previews_label_upload"
+msgstr "Carica anteprima: "
+
+#: views/developers/previews.thtml:50
+msgid "devcp_previews_notice_error"
+msgstr "Impossibile salvare una o più nuove anteprime."
+
+#: views/developers/previews.thtml:47
+msgid "devcp_previews_notice_success"
+msgstr "L'anteprima è stata aggiornata correttamente."
+
+#: views/developers/previews.thtml:59
+msgid "devcp_previews_p_screenshots"
+msgstr "Le anteprime del componente aggiuntivo sono visualizzate in seguito. È possibile modificare le descrizioni o le immagini. L'anteprima predefinita verrà mostrata accanto al componente aggiuntivo negli elenchi e nei risultati di ricerca."
+
+#: views/previews/edit.thtml:55
+msgid "devcp_previews_submit_delete"
+msgstr "Elimina anteprima"
+
+#: views/previews/edit.thtml:55
+msgid "devcp_previews_submit_delete_confirm"
+msgstr "Vuoi eliminare questa anteprima?"
+
+#: views/previews/edit.thtml:54
+msgid "devcp_previews_submit_edit"
+msgstr "Modifica anteprima"
+
+#: views/previews/add.thtml:63
+msgid "devcp_previews_submit_upload"
+msgstr "Carica anteprima"
+
+#: views/developers/previews.thtml:78
+msgid "devcp_previews_thumbnail"
+msgstr "Miniatura"
+
+#. %s is the add-on name.
+#: views/developers/previews.thtml:44
+msgid "devcp_previews_title"
+msgstr "Gestione anteprime - %s"
+
+#: views/developers/uploader.thtml:74
+msgid "devcp_review_agreement_please"
+msgstr "Prima di procedere è necessario leggere e accettare il seguente accordo di licenza per sviluppatori."
+
+#: views/elements/developers/rolecheck.thtml:42
+msgid "devcp_rolecheck_no_privs"
+msgstr "<span>Non si dispone di permessi sufficienti per modificare questa pagina.</span><br />Contattare il proprietario del componente aggiuntivo per eventuali modifiche."
+
+#: controllers/developers_controller.php:1315
+msgid "devcp_several_hours"
+msgstr "Potrebbero trascorrere diverse ore prima che le modifiche appaiano in tutte le sezioni del sito web."
+
+#: views/elements/developers/sidebar.thtml:52
+msgid "devcp_sidebar_a_dashboard"
+msgstr "Dashboard"
+
+#. %s is a number
+#: views/elements/developers/statsbar.thtml:45
+#: views/developers/dashboard.thtml:79
+#, php-format
+msgid "devcp_statsbar_adu"
+msgstr "<em>%s</em> utenti attivi per giorno"
+
+#. %s is a number
+#: views/elements/developers/statsbar.thtml:41
+#: views/developers/dashboard.thtml:75
+#, php-format
+msgid "devcp_statsbar_total_downloads"
+msgstr "<em>%s</em> download totali"
+
+#. %s is a number
+#: views/elements/developers/statsbar.thtml:43
+#: views/developers/dashboard.thtml:77
+#, php-format
+msgid "devcp_statsbar_weekly_downloads"
+msgstr "<em>%s</em> download settimanali"
+
+#: views/developers/addon_status_confirm.thtml:59
+msgid "devcp_status_confirm_active"
+msgstr "Se si imposta il componente aggiuntivo come attivo, verrà visualizzato in tutte le sezioni pubbliche riservate a questo stato, inclusi risultati di ricerca ed elenchi. Potrà essere scaricato dal sito web e verrà incluso negli aggiornamenti automatici, a seconda dello stato. Sarà comunque possibile ritornare a questa sezione e disattivarlo nel caso lo si ritenga necessario."
+
+#: views/developers/addon_status_confirm.thtml:59
+msgid "devcp_status_confirm_active_sure"
+msgstr "Impostare questo componente aggiuntivo come attivo?"
+
+#: views/developers/addon_status_confirm.thtml:50
+msgid "devcp_status_confirm_header_sure"
+msgstr "Sei sicuro?"
+
+#: views/developers/addon_status_confirm.thtml:55
+msgid "devcp_status_confirm_inactive"
+msgstr "Se si imposta il componente aggiuntivo come disattivato, verrà escluso da tutte le sezioni pubbliche, inclusi risultati di ricerca ed elenchi. Non potrà essere scaricato dal sito web e non verrà incluso negli aggiornamenti automatici.Sarà comunque possibile ritornare a questa sezione e riattivarlo nel caso lo si ritenga necessario.Marking this add-on inactive will prevent it from showing up in any public areas, including search and browse listings. It will not be downloadable from the website and will not be returned in client update checks. You will be able to return here and re-enable it at your convenience."
+
+#: views/developers/addon_status_confirm.thtml:55
+msgid "devcp_status_confirm_inactive_sure"
+msgstr "Impostare questo componente aggiuntivo come disattivato?"
+
+#: views/developers/addon_status_confirm.thtml:74
+msgid "devcp_status_confirm_no"
+msgstr "No, annulla"
+
+#: views/developers/addon_status_confirm.thtml:67
+msgid "devcp_status_confirm_public"
+msgstr "Se si imposta questo componente aggiuntivo come pubblicato, qualunque utente potrà scaricarlo e verranno forniti aggiornamenti automatici agli utenti esistenti."
+
+#: views/developers/addon_status_confirm.thtml:67
+msgid "devcp_status_confirm_public_sure"
+msgstr "Impostare questo componente aggiuntivo come pubblicato?"
+
+#: views/developers/addon_status_confirm.thtml:63
+msgid "devcp_status_confirm_sandbox"
+msgstr "Se si sposta questo componente aggiuntivo nella sandbox, gli utenti dovranno effettuare il login per poterlo scaricare e gli utenti esistenti non riceveranno gli aggiornamenti automatici. Dal momento che il componente aggiuntivo è attualmente pubblico, sarà possibile ritornare in questa sezione e renderlo nuovamente pubblico."
+
+#: views/developers/addon_status_confirm.thtml:63
+msgid "devcp_status_confirm_sandbox_sure"
+msgstr "Spostare questo componente aggiuntivo nella sandbox?"
+
+#: views/developers/addon_status_confirm.thtml:73
+msgid "devcp_status_confirm_yes"
+msgstr "Sì, sono sicuro"
+
+#: views/developers/addon_status_nominate.thtml:46
+msgid "devcp_status_nominate_error_notice"
+msgstr "<span>È obbligatorio inserire un messaggio per la segnalazione.</span><br />Inserire il testo richiesto e riprovare."
+
+#: views/developers/addon_status_nominate.thtml:55
+msgid "devcp_status_nominate_header"
+msgstr "Segnalazione componente aggiuntivo"
+
+#: views/developers/dashboard.thtml:85
+msgid "devcp_summary_lastversion"
+msgstr "Ultima versione:"
+
+#. %s is the add-on name.
+#: views/developers/addon_edit.thtml:43
+#: views/developers/addon_edit_authors.thtml:44
+#: views/developers/versions_delete.thtml:43
+#: views/developers/addon_edit_properties.thtml:44
+#: views/developers/addon_edit_descriptions.thtml:44
+#: views/developers/versions_edit.thtml:44
+#: views/developers/addon_edit_categories.thtml:43
+#: views/developers/versions.thtml:43
+msgid "devcp_title_edit_addon"
+msgstr "Modifica %s"
+
+#. title attribute for a javascript link that pops up a help dialog.
+#: views/elements/translationbox.thtml:68
+msgid "devcp_transbox_a_title_help"
+msgstr "Guida (la pagina corrente non verrà chiusa)"
+
+#: views/elements/translationbox.thtml:68
+msgid "devcp_transbox_alt_help"
+msgstr "Guida"
+
+#. %1$s is <span>17</span>, %2$s is 42.
+#: views/elements/translationbox.thtml:101
+msgid "devcp_transbox_chars_used"
+msgstr "Caratteri utilizzati: %1$s / %2$s"
+
+#: views/elements/translationbox.thtml:132
+msgid "devcp_transbox_delete_sure"
+msgstr "Eliminare questa traduzione?"
+
+#. %s is a locale, like en-US.
+#: views/elements/translationbox.thtml:143
+msgid "devcp_transbox_help_header_tabs"
+msgstr "Cosa sono queste schede %s?"
+
+#: views/elements/translationbox.thtml:145
+msgid "devcp_transbox_help_header_what"
+msgstr "Cosa succede se non ho nessuna traduzione?"
+
+#: views/elements/translationbox.thtml:147
+msgid "devcp_transbox_help_hide"
+msgstr "Nascondi guida"
+
+#: views/elements/translationbox.thtml:146
+msgid "devcp_transbox_help_if"
+msgstr "Se un utente naviga sul sito e non è disponibile una traduzione nella sua lingua, verrà utilizzato il locale predefinito specificato nella sezione Modifica proprietà.Se non è disponibile alcuna traduzione, inserire le informazioni disponibili nel locale predefinito (dovrebbe corrispondere alla tua lingua madre)."
+
+#: views/elements/translationbox.thtml:144
+msgid "devcp_transbox_help_transbox"
+msgstr "Questo è un <i>campo per la traduzione</i>. Permette di localizzare un campo specifico in qualsiasi lingua in cui è disponibile il componente aggiuntivo. È possibile aggiungere, modificare o eliminare le traduzioni usando la scheda Locale."
+
+#: views/elements/translationbox.thtml:85
+msgid "devcp_transbox_img_add_trans"
+msgstr "Aggiungi traduzione"
+
+#: views/elements/translationbox.thtml:86
+msgid "devcp_transbox_img_remove_trans"
+msgstr "Elimina traduzione"
+
+#: views/elements/translationbox.thtml:123
+msgid "devcp_transbox_input_add_all"
+msgstr "Aggiungi locale a tutti"
+
+#: views/elements/translationbox.thtml:122
+msgid "devcp_transbox_input_add_locale"
+msgstr "Aggiungi locale"
+
+#: views/elements/translationbox.thtml:124
+#: views/elements/translationbox.thtml:135
+msgid "devcp_transbox_input_cancel"
+msgstr "Annulla"
+
+#: views/elements/translationbox.thtml:134
+msgid "devcp_transbox_input_delete"
+msgstr "Elimina"
+
+#: views/elements/translationbox.thtml:113
+msgid "devcp_transbox_select_locale"
+msgstr "Selezionare il locale della traduzione da aggiungere:"
+
+#. %1$s and %2$s are GUIDs.
+#: controllers/developers_controller.php:343
+msgid "devcp_update_addon_guid_error"
+msgstr "Il GUID usato in questo file (%1$s) non corrisponde al GUID di questo componente aggiuntivo (%2$s)."
+
+#: controllers/developers_controller.php:334
+msgid "devcp_update_addon_priv_error"
+msgstr "Non si dispone dei permessi necessari per aggiornare questo componente aggiuntivo."
+
+#. %1$s is a version number, %2$s is an add-on ID.
+#: controllers/developers_controller.php:399
+msgid "devcp_update_addon_version_belong_error"
+msgstr "La versione specificata (%1$s) non appartiene a questo componente aggiuntivo (%2$s)."
+
+#. %1$s is a version number, maybe 1.1.
+#. %2$s is a URL.
+#: controllers/developers_controller.php:351
+msgid "devcp_update_addon_version_exists_error"
+msgstr "Il numero di versione caricato (%1$s) è già presente per questo componente aggiuntivo. Se stai cercando di aggiungere un nuovo file a questa versione, <a href=\"%2$s\">fai clic qui</a>."
+
+#. %1$s and %2$s are version numbers.
+#: controllers/developers_controller.php:405
+msgid "devcp_update_addon_version_match_error"
+msgstr "Il numero di versione caricato (%1$s) non corrisponde al numero di versione esistente (%2$s)."
+
+#: views/developers/uploader.thtml:68
+msgid "devcp_uploader_a_start"
+msgstr "Per iniziare"
+
+#: views/developers/uploader.thtml:137
+msgid "devcp_uploader_ajax_loading"
+msgstr "Caricamento file in corso..."
+
+#: views/developers/uploader.thtml:82
+msgid "devcp_uploader_button_agree"
+msgstr "Accetta e continua"
+
+#: views/developers/uploader.thtml:157
+msgid "devcp_uploader_button_edit"
+msgstr "Modifica il mio componente aggiuntivo"
+
+#: views/developers/uploader.thtml:158
+msgid "devcp_uploader_button_later"
+msgstr "Completerò il componente aggiuntivo in seguito."
+
+#: views/developers/uploader.thtml:168
+msgid "devcp_uploader_button_release"
+msgstr "Aggiungi note di versione"
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/uploader.thtml:156
+msgid "devcp_uploader_created_results"
+msgstr "<p>Le informazioni sul componente aggiuntivo sono state correttamente registrate. Sono stati salvati i dati principali recuperati dal file caricato, ma ci sono molte altre informazioni che possono essere personalizzate.</p><p>Il componente aggiuntivo è attualmente considerato come <strong>Incompleto</strong>. Per completarlo, bisogna verificare il nome, il riepilogo, la descrizione e controllare che sia inserito in almeno una categoria. È possibile modificare queste informazioni utilizzando i link seguenti e verificare lo stato del componente aggiuntivo controllando la <a %s>pagina sullo stato</a>."
+
+#: views/developers/uploader.thtml:143
+msgid "devcp_uploader_error_correct"
+msgstr "Correggere questo problema e caricare nuovamente il file."
+
+#. %1$s is a version number, %2$s is a status, e.g Public or Incomplete.
+#: views/developers/uploader.thtml:175
+msgid "devcp_uploader_file_created"
+msgstr "Il nuovo file è stato aggiunto alla versione %1$s ed è attualmente impostato come %2$s."
+
+#: views/developers/uploader.thtml:154
+msgid "devcp_uploader_header_created"
+msgstr "Creazione componente aggiuntivo completata"
+
+#: views/developers/uploader.thtml:141
+msgid "devcp_uploader_header_error"
+msgstr "Oops! Sembra esserci un problema con questo file..."
+
+#: views/developers/uploader.thtml:173
+msgid "devcp_uploader_header_file_added"
+msgstr "File aggiunto"
+
+#: views/developers/uploader.thtml:66
+msgid "devcp_uploader_header_how"
+msgstr "Come funziona il sistema?"
+
+#. %s is the version number, e.g. 3.2.
+#: views/developers/uploader.thtml:163
+msgid "devcp_uploader_header_update_created"
+msgstr "Creata versione %s"
+
+#: views/developers/uploader.thtml:117
+msgid "devcp_uploader_header_upload"
+msgstr "Carica il file"
+
+#: views/developers/uploader.thtml:67
+msgid "devcp_uploader_how"
+msgstr "<p>Grazie per aver caricato il tuo componente aggiuntivo su Mozilla Add-ons. Ospitare il tuo componente aggiuntivo su Mozilla Add-ons è la scelto più semplice per assicurare la migliore distribuzione del tuo lavoro. Ecco alcuni vantaggi: </p><ul><li>ogni componente aggiuntivo avrà una scheda pubblica con le informazioni che inserirai, come un breve riepilogo delle funzionalità dei componenti aggiuntivi, le funzioni disponibili e una galleria di anteprime del componente aggiuntivo in funzione;</li><li>il componente aggiuntivo verrà visualizzato nei risultati di ricerca, negli elenchi pubblici e anche nella finestra del Gestore dei componenti aggiuntivi di Firefox 3;</li><li>ci prenderemo cura di ospitare tutti i file per il download e di fornire aggiornamenti automatici;</li><li>avrai accesso ad una bacheca delle statistiche con informazioni dettagliate sugli utenti che utilizzano il tuo componente aggiuntivo.</li><li></ul><p>I componenti aggiuntivi ospitati su Mozilla Add-ons devono essere approvati da un revisore prima di beneficiare di tutte le possibilità descritte. Se sei pronto per iniziare il processo e il pacchetto è già pronto per essere caricato, fai clic su Per iniziare.<p>"
+
+#: views/developers/uploader.thtml:125
+msgid "devcp_uploader_label_platformtype"
+msgstr "Piattaforme supportate:"
+
+#: views/developers/uploader.thtml:124
+msgid "devcp_uploader_label_upload_field"
+msgstr "File: "
+
+#: controllers/components/developers.php:1221
+msgid "devcp_uploader_option_other"
+msgstr "Altro"
+
+#. %1$s is a number, %2$s is href="..." and should stay in the <a> tag.
+#: views/developers/uploader.thtml:176
+msgid "devcp_uploader_p_pending_file"
+msgstr "Il nuovo file sarà disponibile al pubblico non appena un revisore l'avrà controllata. Attualmente ci sono altri %1$s componenti aggiuntivi in coda. Vorresti una revisione più rapida? Perché non <a %2$s>diventare un revisore</a>?"
+
+#. %1$s is a number, %2$s is href="..." and should stay in the <a> tag.
+#: views/developers/uploader.thtml:166
+msgid "devcp_uploader_p_pending_version"
+msgstr "La nuova versione sarà disponibile al pubblico non appena un revisore l'avrà controllata. Attualmente ci sono altri %1$s componenti aggiuntivi in coda. Vorresti una revisione più rapida? Perché non <a %2$s>diventare un revisore</a>?"
+
+#. %s is a status, e.g Public or Incomplete.
+#: views/developers/uploader.thtml:165
+msgid "devcp_uploader_p_update_created"
+msgstr "È stata creata una nuova versione ed è attualmente impostata come %s."
+
+#. %1$s is href="..." and should stay in the 'Versions and Files' <a> tag.
+#. %2$s is href="..." and should stay in the 'current status' <a> tag.
+#: views/developers/uploader.thtml:177
+msgid "devcp_uploader_p_update_file"
+msgstr "Visualizza il nuovo file nella pagina <a %1$s>Versioni e file</a>, controlla lo <a %2$s>stato</a> del tuo componente aggiuntivo, oppure <b>aggiungi le note di versione</b> facendo clic sul pulsante seguente (altamente raccomandato)."
+
+#. %1$s is href="..." and should stay in the 'Versions and Files' <a> tag.
+#. %2$s is href="..." and should stay in the 'current status' <a> tag.
+#: views/developers/uploader.thtml:167
+msgid "devcp_uploader_p_update_version"
+msgstr "Visualizza la nuova versione nella pagina <a %1$s>Versioni e file</a>, controlla lo <a %2$s>stato</a> del tuo componente aggiuntivo, oppure <b>aggiungi le note di versione</b> facendo clic sul pulsante seguente (altamente raccomandato)."
+
+#: views/developers/uploader.thtml:118
+msgid "devcp_uploader_p_upload"
+msgstr "Utilizzare il seguente modulo per caricare nuovi file. Se sono presenti più file, oppure file specifici per una piattaforma, selezionare un singolo file e caricare i successivi usando la Gestione versioni e file."
+
+#: views/developers/uploader.thtml:125
+msgid "devcp_uploader_platformtype_all"
+msgstr "Tutto"
+
+#: views/developers/uploader.thtml:126
+msgid "devcp_uploader_platformtype_specific"
+msgstr "Specifico:"
+
+#. Used as first item in a <select>.
+#: controllers/components/developers.php:1185
+msgid "devcp_uploader_please_choose"
+msgstr "Selezionare un elemento…"
+
+#. %1$s is the add-on name, %2$s is the version number.
+#: views/developers/uploader.thtml:57
+msgid "devcp_uploader_title_file"
+msgstr "Aggiungi file a %1$s %2$s"
+
+#: views/developers/uploader.thtml:50
+msgid "devcp_uploader_title_submit"
+msgstr "Carica nuovo componente aggiuntivo"
+
+#. %s is the add-on name.
+#: views/developers/uploader.thtml:54
+msgid "devcp_uploader_title_update"
+msgstr "Aggiorna %s"
+
+#. %s is a full <a> tag
+#: controllers/developers_controller.php:503
+#, php-format
+msgid "devcp_valid_app_reference"
+msgstr "Consultare %s per ulteriori riferimenti."
+
+#. This is the text in the <a> tag for devcp_valid_app_reference. This should be
+#. fixed.
+#: controllers/developers_controller.php:503
+msgid "devcp_valid_app_reference_linktext"
+msgstr "questa pagina"
+
+#: controllers/developers_controller.php:581
+msgid "devcp_verify_author_error"
+msgstr "Nessun account trovato per questo indirizzo e-mail."
+
+#: controllers/developers_controller.php:553
+msgid "devcp_verify_search_engine_error"
+msgstr "Il file XML non è valido oppure uno dei campi obbligatori non è stato compilato. <a href=\"https://developer.mozilla.org/en/Creating_OpenSearch_plugins_for_Firefox\">Consulta la documentazione</a>, verifica il componente aggiuntivo e riprova."
+
+#: views/developers/versions.thtml:75
+msgid "devcp_versions_a_cancel"
+msgstr "Annulla"
+
+#: views/developers/versions.thtml:79
+msgid "devcp_versions_a_delete"
+msgstr "Elimina versione"
+
+#: views/developers/versions.thtml:74
+msgid "devcp_versions_a_empty"
+msgstr "Elimina versione vuota"
+
+#: views/developers/versions.thtml:71
+msgid "devcp_versions_a_remove"
+msgstr "Eliminare?"
+
+#: views/developers/versions.thtml:91
+msgid "devcp_versions_add"
+msgstr "Aggiungi nuova versione"
+
+#: views/developers/versions_delete.thtml:58
+msgid "devcp_versions_delete_a_cancel"
+msgstr "Annulla"
+
+#: views/developers/versions_delete.thtml:56
+msgid "devcp_versions_delete_a_delete"
+msgstr "Elimina versione"
+
+#. Followed by a list of reviews and files that will be removed.
+#: views/developers/versions_delete.thtml:50
+msgid "devcp_versions_delete_also"
+msgstr "Verranno eliminati anche:"
+
+#: views/developers/versions_delete.thtml:53
+msgid "devcp_versions_delete_files"
+msgid_plural "devcp_versions_delete_files"
+msgstr[0] "%s file"
+msgstr[1] "%s file"
+
+#. %s is the version number.
+#: views/developers/versions_delete.thtml:48
+msgid "devcp_versions_delete_header"
+msgstr "Elimina versione %s?"
+
+#: views/developers/versions_delete.thtml:52
+msgid "devcp_versions_delete_reviews"
+msgid_plural "devcp_versions_delete_reviews"
+msgstr[0] "%s recensione"
+msgstr[1] "%s recensioni"
+
+#. %s is the version number.
+#: views/developers/versions_delete.thtml:49
+msgid "devcp_versions_delete_sure"
+msgstr "Eliminare in modo permanente la versione %s?"
+
+#: views/developers/versions_edit.thtml:102
+#: views/developers/versions_edit.thtml:155
+msgid "devcp_versions_edit_a_cancel"
+msgstr "Annulla"
+
+#: views/developers/versions_edit.thtml:101
+msgid "devcp_versions_edit_a_delete"
+msgstr "Elimina file"
+
+#: views/developers/versions_edit.thtml:165
+msgid "devcp_versions_edit_a_new_app"
+msgstr "Aggiungi nuova applicazione"
+
+#: views/developers/versions_edit.thtml:154
+msgid "devcp_versions_edit_a_remove_app"
+msgstr "Elimina applicazione"
+
+#: views/developers/versions_edit.thtml:114
+msgid "devcp_versions_edit_add"
+msgstr "Aggiungi nuovo file"
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/versions_edit.thtml:121
+msgid "devcp_versions_edit_adjust"
+msgstr "Se si modificano le informazioni relative alle applicazioni in questa sezione, gli utenti saranno in grado di completare l'installazione anche se il file install.rdf presente nel pacchetto indica che il componente aggiuntivo non è compatibile. <a %s>Elenco delle applicazioni supportate</a>"
+
+#: views/developers/versions_edit.thtml:153
+msgid "devcp_versions_edit_compat_sure"
+msgstr "Eliminare la compatibilità con questa applicazione?"
+
+#: views/developers/versions_edit.thtml:100
+msgid "devcp_versions_edit_delete_sure"
+msgstr "Eliminare in modo permanente questo file?"
+
+#: views/developers/versions_edit.thtml:203
+msgid "devcp_versions_edit_header_approval"
+msgstr "Informazioni approvazione"
+
+#: views/developers/versions_edit.thtml:120
+msgid "devcp_versions_edit_header_compat"
+msgstr "Applicazioni compatibili"
+
+#: views/developers/versions_edit.thtml:74
+msgid "devcp_versions_edit_header_file"
+msgstr "Informazioni file"
+
+#: views/developers/versions_edit.thtml:189
+msgid "devcp_versions_edit_header_license"
+msgstr "Licenza"
+
+#. %s is the version number.
+#: views/developers/versions_edit.thtml:53
+msgid "devcp_versions_edit_header_manage"
+msgstr "Gestisci versione %s"
+
+#: views/developers/versions_edit.thtml:212
+msgid "devcp_versions_edit_header_notes"
+msgstr "Note approvazione"
+
+#: views/developers/versions_edit.thtml:98
+msgid "devcp_versions_edit_img_delete"
+msgstr "Elimina file"
+
+#. %1$s is the file id, e.g. 18723.
+#. %2$s is the platform name, e.g. ALL or Windows.
+#. %3$s is the _('date) created.
+#. %4$s is the status, e.g. "In Sandbox" or "Public".
+#. %5$s is the _('date') status was changed.
+#: views/developers/versions_edit.thtml:208
+msgid "devcp_versions_edit_li_file"
+msgstr "File %1$s (%2$s) creato il %3$s e impostato come %4$s il %5$s"
+
+#: views/developers/versions_edit.thtml:190
+msgid "devcp_versions_edit_license_description"
+msgstr "Selezionare la licenza adatta al proprio componente aggiuntivo. Questa licenza specifica i diritti concessi sull'utilizzo del codice sorgente."
+
+#: views/developers/versions_edit.thtml:111
+msgid "devcp_versions_edit_no_files"
+msgstr "Nessun file trovato."
+
+#: views/developers/versions_edit.thtml:213
+msgid "devcp_versions_edit_optional"
+msgstr "Informazioni facoltative per il revisore che effettuerà la revisione di questo componente aggiuntivo."
+
+#: views/developers/versions_edit.thtml:151
+msgid "devcp_versions_edit_remove_compat"
+msgstr "Rimuovi compatibilità applicazione"
+
+#: views/developers/versions_edit.thtml:167
+msgid "devcp_versions_edit_select_app"
+msgstr "Selezionare un'applicazione"
+
+#: views/developers/versions_edit.thtml:78
+msgid "devcp_versions_edit_th_file"
+msgstr "File"
+
+#: views/developers/versions_edit.thtml:79
+msgid "devcp_versions_edit_th_platform"
+msgstr "Piattaforma"
+
+#: views/developers/versions_edit.thtml:80
+msgid "devcp_versions_edit_th_size"
+msgstr "Dimensione"
+
+#: views/developers/versions_edit.thtml:81
+msgid "devcp_versions_edit_th_status"
+msgstr "Stato"
+
+#: views/developers/versions_edit.thtml:183
+msgid "devcp_versions_edit_transbox_releasenotes_description"
+msgstr "Informazioni sulle modifiche contenute in questa versione, nuove funzioni, bug conosciuti e altre informazioni utili specifiche per questa versione. Questa informazione verrà visualizzata dagli utenti che utilizzano la gestione integrata degli aggiornamenti di Firefox 3."
+
+#: views/developers/versions_edit.thtml:182
+msgid "devcp_versions_edit_transbox_releasenotes_name"
+msgstr "Note di versione"
+
+#: views/developers/versions_edit.thtml:164
+msgid "devcp_versions_edit_unsaved_compat"
+msgstr "<strong>Sono presenti modifiche non salvate.</strong> La compatibilità verrà eliminata facendo clic su Aggiorna versione."
+
+#: views/developers/versions_edit.thtml:113
+msgid "devcp_versions_edit_unsaved_files"
+msgstr "<strong>Sono presenti modifiche non salvate.</strong> I file verranno eliminati facendo clic su Aggiorna versione."
+
+#: views/developers/versions_edit.thtml:218
+msgid "devcp_versions_edit_update"
+msgstr "Aggiorna versioni"
+
+#: views/developers/versions.thtml:49
+msgid "devcp_versions_header_manage"
+msgstr "Gestisci versioni e file"
+
+#: views/developers/versions.thtml:87
+msgid "devcp_versions_no_versions"
+msgstr "Nessuna versione."
+
+#. %s is a version number, base 10.
+#: views/developers/versions.thtml:46
+msgid "devcp_versions_notice_success"
+msgstr "Versione %s eliminata correttamente."
+
+#: views/developers/versions.thtml:73
+msgid "devcp_versions_p_remove"
+msgstr "Questa versione non ha file associati e può essere eliminata. Rimuovere questa versione?"
+
+#: views/developers/versions.thtml:58
+msgid "devcp_versions_th_created"
+msgstr "Creato"
+
+#: views/developers/versions.thtml:57
+msgid "devcp_versions_th_status"
+msgstr "Stato"
+
+#: views/developers/versions.thtml:56
+msgid "devcp_versions_th_version"
+msgstr "Versione"
+
+#: controllers/downloads_controller.php:91
+msgid "downloads_disable_warning"
+msgstr "Questo componente aggiuntivo è disattivato"
+
+#: controllers/components/editors.php:57
+msgid "editor_review_error_addon_not_nominated"
+msgstr "Questo componente aggiuntivo è stato segnalato."
+
+#: controllers/components/editors.php:213
+msgid "editor_review_error_file_not_pending"
+msgstr "Questo file non è in attesa di revisione."
+
+#. Actions are, for example: approving or rejecting
+#: controllers/components/editors.php:79
+#: controllers/components/editors.php:182
+msgid "editor_review_error_no_action"
+msgstr "Selezionare un'azione di revisione."
+
+#: controllers/components/editors.php:192
+msgid "editor_review_error_no_applications"
+msgstr "Inserire l'applicazione con cui è stato testato."
+
+#. Comments are required when an editor approves or rejects an add-on.
+#: controllers/components/editors.php:84
+#: controllers/components/editors.php:187
+msgid "editor_review_error_no_comments"
+msgstr "Inserire i commenti sulla revisione."
+
+#: controllers/components/editors.php:161
+msgid "editor_review_error_no_files"
+msgstr "Selezionare almeno un file da revisionare."
+
+#: controllers/components/editors.php:197
+msgid "editor_review_error_no_operating_system"
+msgstr "Inserire i sistemi operativi su cui è stata testato."
+
+#: views/editors/logs.thtml:51
+msgid "editorcp_logs_button_filter"
+msgstr "Filtra"
+
+#: views/editors/logs.thtml:44
+msgid "editorcp_logs_filter_by"
+msgstr "Filtra per tipo/azione"
+
+#: views/editors/logs.thtml:42
+#: controllers/editors_controller.php:964
+msgid "editorcp_logs_page_heading"
+msgstr "Registro eventi"
+
+#: views/elements/developers/editorsmenu.thtml:60
+msgid "editorcp_menu_eventlog_link"
+msgstr "Registro eventi"
+
+#: views/elements/developers/editorsmenu.thtml:62
+msgid "editorcp_menu_mainpage_link"
+msgstr "Torna alla pagina principale"
+
+#: views/elements/developers/editorsmenu.thtml:61
+msgid "editorcp_menu_reviewlog_link"
+msgstr "Esamina registro"
+
+#: views/elements/developers/editorsmenu.thtml:55
+msgid "editorcp_menu_summary_link"
+msgstr "Sommario revisione"
+
+#: views/elements/developers/editorsmenu.thtml:52
+msgid "editorcp_menu_title"
+msgstr "Strumenti per revisori"
+
+#: views/editors/reviewlog.thtml:49
+msgid "editorcp_reviewlog_button_filter"
+msgstr "Filtra"
+
+#: views/editors/reviewlog.thtml:58
+msgid "editorcp_reviewlog_column_action"
+msgstr "Azione"
+
+#: views/editors/reviewlog.thtml:56
+msgid "editorcp_reviewlog_column_addon"
+msgstr "Componente aggiuntivo"
+
+#: views/editors/reviewlog.thtml:55
+msgid "editorcp_reviewlog_column_date"
+msgstr "Data"
+
+#: views/editors/reviewlog.thtml:57
+msgid "editorcp_reviewlog_column_editor"
+msgstr "Revisore"
+
+#: views/editors/reviewlog.thtml:94
+msgid "editorcp_reviewlog_comments_hide"
+msgstr "Nascondi commenti"
+
+#: views/editors/reviewlog.thtml:93
+msgid "editorcp_reviewlog_comments_show"
+msgstr "Visualizza commenti"
+
+#. %1$s and %2$s are full <input> tags for dates
+#: views/editors/reviewlog.thtml:45
+#, php-format
+msgid "editorcp_reviewlog_entries_between"
+msgstr "Visualizza elementi compresi tra %1$s e %2$s"
+
+#: views/editors/reviewlog.thtml:104
+msgid "editorcp_reviewlog_none_found"
+msgstr "Nessuna revisione disponibile nel periodo richiesto."
+
+#: views/editors/reviewlog.thtml:42
+msgid "editorcp_reviewlog_page_heading"
+msgstr "Registro revisioni"
+
+#: views/editors/summary.thtml:61
+msgid "editorcp_summary_monthreviews_heading"
+msgstr "Revisioni del mese"
+
+#: views/editors/summary.thtml:77
+msgid "editorcp_summary_neweditors_heading"
+msgstr "Nuovi revisori"
+
+#: views/editors/summary.thtml:42
+msgid "editorcp_summary_page_heading"
+msgstr "Riepilogo revisore"
+
+#: views/editors/summary.thtml:94
+msgid "editorcp_summary_recentactivity_heading"
+msgstr "Ultime operazioni del revisore"
+
+#: views/editors/summary.thtml:45
+msgid "editorcp_summary_totalreviews_heading"
+msgstr "Totale revisioni"
+
+#: controllers/editors_controller.php:248
+#: controllers/editors_controller.php:249
+msgid "editors_addon_review_pagetitle"
+msgstr "Revisione componente aggiuntivo"
+
+#: controllers/editors_controller.php:349
+msgid "editors_error_js-formerror"
+msgstr "Compila i campi seguenti:"
+
+#: controllers/editors_controller.php:350
+msgid "editors_error_review_one_file"
+msgstr "Seleziona almeno un file da revisionare."
+
+#: controllers/editors_controller.php:274
+msgid "editors_error_self_reviews_forbidden"
+msgstr "Le auto-revisioni non sono consentite."
+
+#: controllers/editors_controller.php:699
+msgid "editors_external_software"
+msgstr "Software esterno"
+
+#: views/editors/featured.thtml:120
+#: views/editors/featured.thtml:121
+msgid "editors_featured_add_feature"
+msgstr "Aggiungi funzionalità"
+
+#: views/editors/featured.thtml:126
+msgid "editors_featured_add_feature_submit"
+msgstr "Aggiungi"
+
+#: views/editors/featured.thtml:49
+#: controllers/editors_controller.php:832
+#: controllers/editors_controller.php:848
+msgid "editors_featured_addon_add_failure"
+msgstr "Impossibile aggiungere la funzionalità."
+
+#: controllers/editors_controller.php:851
+msgid "editors_featured_addon_add_success"
+msgstr "Funzionalità aggiunta con successo."
+
+#: views/editors/featured.thtml:50
+#: controllers/editors_controller.php:839
+#: controllers/editors_controller.php:868
+#: controllers/editors_controller.php:886
+msgid "editors_featured_addon_edit_failure"
+msgstr "Impossibile modificare la funzionalità."
+
+#: views/editors/featured.thtml:51
+#: controllers/editors_controller.php:888
+msgid "editors_featured_addon_edit_success"
+msgstr "Funzionalità modificata con successo."
+
+#: views/editors/featured.thtml:53
+#: controllers/editors_controller.php:861
+msgid "editors_featured_addon_invalid_locale"
+msgstr "Uno o più locale risultano non validi."
+
+#: views/editors/featured.thtml:52
+#: controllers/editors_controller.php:906
+msgid "editors_featured_addon_remove_failure"
+msgstr "Impossibile rimuovere la funzionalità."
+
+#: controllers/editors_controller.php:901
+msgid "editors_featured_addon_remove_success"
+msgstr "Funzionalità eliminata con successo."
+
+#: controllers/editors_controller.php:915
+#: controllers/editors_controller.php:917
+msgid "editors_featured_addons_pagetitle"
+msgstr "Componenti aggiuntivi consigliati"
+
+#: views/editors/featured.thtml:54
+#: views/editors/featured.thtml:107
+msgid "editors_featured_edit_feature_submit"
+msgstr "Vai"
+
+#: views/editors/featured.thtml:90
+#: views/editors/featured.thtml:91
+msgid "editors_featured_remove_feature"
+msgstr "Rimuovi funzionalità"
+
+#: views/editors/queue.thtml:46
+msgid "editors_filter_queue"
+msgstr "Filtra la coda"
+
+#: views/editors/queue.thtml:182
+msgid "editors_helpful_links"
+msgstr "Link utili"
+
+#: views/editors/queue.thtml:182
+msgid "editors_link_guide"
+msgstr "Guida per i revisori"
+
+#: views/editors/queue.thtml:182
+msgid "editors_link_policy"
+msgstr "Policy dei componenti aggiuntivi"
+
+#: views/editors/queue.thtml:47
+msgid "editors_notice_filter_session"
+msgstr "I filtri impostati rimarranno attivi per questa sessione oppure fino a quando non verranno reimpostati."
+
+#. %1 is the queue mode
+#: views/editors/queue.thtml:177
+#: views/admin/flagged_queue.thtml:89
+msgid "editors_notice_none_found"
+msgstr "Attualmente non ci sono componenti aggiuntivi da revisionare."
+
+#: controllers/editors_controller.php:1040
+msgid "editors_one_day"
+msgstr "1 giorno"
+
+#: controllers/editors_controller.php:1048
+msgid "editors_one_hour"
+msgstr "1 ora"
+
+#: controllers/editors_controller.php:1056
+msgid "editors_one_minute"
+msgstr "1 minuto"
+
+#: controllers/editors_controller.php:64
+#: controllers/editors_controller.php:73
+#: controllers/editors_controller.php:77
+msgid "editors_pagetitle"
+msgstr "Strumenti per revisori"
+
+#. %s is a comma separated list of platforms. Example: Windows, OS X
+#: controllers/editors_controller.php:680
+#: controllers/editors_controller.php:683
+#, php-format
+msgid "editors_platform_x_only"
+msgstr "Solo %s"
+
+#: controllers/editors_controller.php:695
+msgid "editors_pre-release"
+msgstr "Pre-release"
+
+#. %1 is the app name
+#: views/editors/queue.thtml:131
+#, php-format
+msgid "editors_queue_app_compatibility"
+msgstr "Compatibilità %s"
+
+#: views/editors/queue.thtml:51
+msgid "editors_queue_filter_label_addon"
+msgstr "E-mail componente aggiuntivo o autore"
+
+#: views/editors/queue.thtml:72
+msgid "editors_queue_filter_label_addontypes"
+msgstr "Tipologie componenti"
+
+#: views/editors/queue.thtml:56
+msgid "editors_queue_filter_label_application"
+msgstr "Applicazione"
+
+#: views/editors/queue.thtml:61
+msgid "editors_queue_filter_label_maxversion"
+msgstr "Versione massima"
+
+#: views/editors/queue.thtml:78
+msgid "editors_queue_filter_label_platforms"
+msgstr "Piattaforme"
+
+#: views/editors/queue.thtml:66
+msgid "editors_queue_filter_label_submissionage"
+msgstr "Tempo trascorso dalla richiesta (giorni)"
+
+#. %1$s is a number
+#: views/editors/queue.thtml:90
+msgid "editors_queue_filter_result_count"
+msgid_plural "editors_queue_filter_result_count"
+msgstr[0] "Risultati della ricerca con filtro: <strong>%1$s</strong> elemento"
+msgstr[1] "Risultati della ricerca con filtro: <strong>%1$s</strong> elementi"
+
+#: views/editors/queue.thtml:84
+msgid "editors_queue_submit_clean"
+msgstr "Reimposta"
+
+#: views/editors/queue.thtml:83
+msgid "editors_queue_submit_filter"
+msgstr "Filtro"
+
+#: controllers/editors_controller.php:133
+msgid "editors_queues_disabled"
+msgstr "Al momento tutte le code di revisione sono disattivate. Riprovare più tardi."
+
+#: views/editors/review.thtml:149
+msgid "editors_review_a_edit_item"
+msgstr "Modifica"
+
+#: views/editors/review.thtml:146
+msgid "editors_review_a_item_history"
+msgstr "Cronologia"
+
+#: views/editors/review.thtml:148
+msgid "editors_review_a_item_homepage"
+msgstr "Sito web"
+
+#: views/editors/review.thtml:145
+msgid "editors_review_a_item_overview"
+msgstr "Anteprima elemento"
+
+#: views/editors/review.thtml:147
+msgid "editors_review_a_previews"
+msgstr "Anteprime"
+
+#: controllers/editors_controller.php:345
+msgid "editors_review_action"
+msgstr "Revisione"
+
+#: views/editors/review.thtml:159
+msgid "editors_review_action_info"
+msgstr "Richiedi ulteriori informazioni"
+
+#: views/editors/review.thtml:157
+msgid "editors_review_action_public"
+msgstr "Rendi pubblica"
+
+#: views/editors/review.thtml:160
+msgid "editors_review_action_request_superreview"
+msgstr "Richiedi revisione più approfondita"
+
+#: views/editors/review.thtml:158
+msgid "editors_review_action_sandbox"
+msgstr "Lascia nella sandbox"
+
+#: controllers/editors_controller.php:346
+msgid "editors_review_comments"
+msgstr "Commenti del revisore"
+
+#: views/editors/review.thtml:182
+msgid "editors_review_details_info_request"
+msgstr "È possibile utilizzare questo modulo per chiedere informazioni all'autore, che riceverà una e-mail e potrà rispondere direttamente. Riceverai una notifica via e-mail quando l'autore avrà risposto."
+
+#: views/editors/review.thtml:174
+msgid "editors_review_details_nominated_public"
+msgstr "In questo modo l'ultima versione del componente aggiuntivo verrà reso pubblico con i relativi file. Le versioni future verranno inserite nella sandbox e dovranno essere approvate da un revisore."
+
+#: views/editors/review.thtml:177
+msgid "editors_review_details_nominated_sandbox"
+msgstr "In questo modo il componente aggiuntivo verrà lasciato nella sandbox."
+
+#: views/editors/review.thtml:166
+msgid "editors_review_details_pending_public"
+msgstr "In questo modo la nuova versione del componente aggiuntivo presente nella sandbox verrà rilasciata nella sezione pubblica."
+
+#: views/editors/review.thtml:169
+msgid "editors_review_details_pending_sandbox"
+msgstr "In questo modo la nuova versione del componente aggiuntivo presente nella sandboxrimarrà nella sandbox."
+
+#: views/editors/review.thtml:185
+msgid "editors_review_details_superreview"
+msgstr "Se temi che questo componente aggiuntivo violi: la tua sicurezza, il copyright o altri punti che dovrebbero essere comunicati a un amministratore, inserisci i tuoi commenti nell'area seguente. Questi commenti verranno inviati solo agli amministratori ma non all'autore."
+
+#: views/editors/review.thtml:134
+msgid "editors_review_file_diff_link"
+msgstr "Confronta con la versione pubblica"
+
+#: views/editors/review.thtml:131
+msgid "editors_review_file_viewcontents_link"
+msgstr "Visualizza contenuti"
+
+#: views/editors/review.thtml:65
+msgid "editors_review_header_authors"
+msgstr "Autori:"
+
+#: views/editors/review.thtml:79
+msgid "editors_review_header_categories"
+msgstr "Categorie:"
+
+#: views/editors/review.thtml:92
+msgid "editors_review_header_compatibility"
+msgstr "Compatibilità:"
+
+#: views/editors/review.thtml:251
+msgid "editors_review_header_description"
+msgstr "Descrizione"
+
+#: views/editors/review.thtml:275
+msgid "editors_review_header_devcomments"
+msgstr "Commenti dello sviluppatore"
+
+#: views/editors/review.thtml:263
+msgid "editors_review_header_eula"
+msgstr "EULA"
+
+#: views/editors/review.thtml:115
+msgid "editors_review_header_files"
+msgstr "File:"
+
+#: views/editors/review.thtml:284
+msgid "editors_review_header_itemhistory"
+msgstr "Cronologia delle versioni"
+
+#: views/editors/review.thtml:232
+msgid "editors_review_header_nominationmessage"
+msgstr "Messaggio di segnalazione"
+
+#: views/editors/review.thtml:311
+msgid "editors_review_header_previews"
+msgstr "Anteprime"
+
+#: views/editors/review.thtml:269
+msgid "editors_review_header_privacy"
+msgstr "Informativa sulla privacy"
+
+#. %1 is the add-on name and version
+#: views/editors/review.thtml:56
+#, php-format
+msgid "editors_review_header_review"
+msgstr "Revisioni %s"
+
+#: views/editors/review.thtml:239
+msgid "editors_review_header_reviewernotes"
+msgstr "Note per i revisori"
+
+#: views/editors/review.thtml:245
+msgid "editors_review_header_summary"
+msgstr "Riepilogo"
+
+#: views/editors/review.thtml:257
+msgid "editors_review_header_versionnotes"
+msgstr "Note sulla versione"
+
+#. a noun: shown in an add-on's editor review history
+#: views/elements/developers/editors_review_history_item.thtml:80
+msgid "editors_review_history_info_reply"
+msgstr "Rispondi"
+
+#: views/elements/developers/editors_review_history_item.thtml:78
+msgid "editors_review_history_info_request"
+msgstr "Richiesta informazioni"
+
+#: views/elements/developers/editors_review_history_item.thtml:62
+#: views/editors/reviewlog.thtml:77
+msgid "editors_review_history_nominated_adminreview"
+msgstr "Revisione di un amministratore"
+
+#: views/elements/developers/editors_review_history_item.thtml:56
+#: views/editors/reviewlog.thtml:71
+msgid "editors_review_history_nominated_approved"
+msgstr "Approva segnalazione/Area pubblica"
+
+#: views/elements/developers/editors_review_history_item.thtml:59
+#: views/editors/reviewlog.thtml:74
+msgid "editors_review_history_nominated_denied"
+msgstr "Non approvare la segnalazione/Sandbox"
+
+#: views/editors/review.thtml:303
+msgid "editors_review_history_nonefound"
+msgstr "Non sono disponibili revisioni precedenti."
+
+#: views/elements/developers/editors_review_history_item.thtml:73
+#: views/editors/reviewlog.thtml:88
+msgid "editors_review_history_pending_adminreview"
+msgstr "Revisione di un amministratore"
+
+#: views/elements/developers/editors_review_history_item.thtml:67
+#: views/editors/reviewlog.thtml:82
+msgid "editors_review_history_pending_approved"
+msgstr "Approvata/Area pubblica"
+
+#: views/elements/developers/editors_review_history_item.thtml:70
+#: views/editors/reviewlog.thtml:85
+msgid "editors_review_history_pending_denied"
+msgstr "Non approvata/Sandbox"
+
+#. link text in an add-on's editor review history, allowing to hide and show an information request's replies
+#. %1 is the number of replies
+#: views/elements/developers/editors_review_history_item.thtml:90
+msgid "editors_review_history_show_hide_replies"
+msgid_plural "editors_review_history_show_hide_replies"
+msgstr[0] "Mostra/Nascondi risposta (%1$s)"
+msgstr[1] "Mostra/Nascondi risposte (%1$s)"
+
+#: views/editors/review.thtml:208
+msgid "editors_review_label_applications"
+msgstr "Applicazioni:"
+
+#: views/editors/review.thtml:196
+msgid "editors_review_label_cannedresponse"
+msgstr "o seleziona una risposta preimpostata:"
+
+#: views/editors/review.thtml:190
+msgid "editors_review_label_comments"
+msgstr "Commenti:"
+
+#: views/editors/review.thtml:204
+msgid "editors_review_label_operating_systems"
+msgstr "Sistemi operativi:"
+
+#: views/editors/review.thtml:285
+#: views/editors/review.thtml:312
+msgid "editors_review_link_pagetop"
+msgstr "Torna all'inizio"
+
+#: views/editors/review.thtml:141
+msgid "editors_review_mulitple_notice"
+msgstr "Attenzione: selezionare solo i file effettivamente verificati."
+
+#: views/editors/review.thtml:51
+msgid "editors_review_next_link"
+msgstr "successiva &raquo;"
+
+#: views/editors/review.thtml:322
+msgid "editors_review_previews_notfound"
+msgstr "Nessuna anteprima disponibile."
+
+#: views/editors/review.thtml:50
+msgid "editors_review_previous_link"
+msgstr "&laquo; precedente"
+
+#: controllers/editors_controller.php:144
+#: controllers/editors_controller.php:146
+msgid "editors_review_queue_pagetitle"
+msgstr "Coda di revisione"
+
+#. %1 is the add-ons rank in the queue, %2 is the total queue length
+#: views/editors/review.thtml:47
+msgid "editors_review_rank_in_queue"
+msgstr "<strong># %1$s</strong> di %2$s in coda"
+
+#. %1 is the add-ons rank in the queue, %2 is the total queue length. Both numbers
+#: views/editors/review.thtml:45
+msgid "editors_review_rank_in_queue_filtered"
+msgstr "<strong># %1$s</strong> di %2$s in coda (con filtro)"
+
+#: views/editors/review.thtml:223
+msgid "editors_review_submit_process_action"
+msgstr "Esegui azione"
+
+#: views/editors/review.thtml:293
+msgid "editors_review_th_action"
+msgstr "Azione"
+
+#: views/editors/review.thtml:294
+msgid "editors_review_th_comments"
+msgstr "Commenti"
+
+#: views/editors/review.thtml:291
+msgid "editors_review_th_date"
+msgstr "Data"
+
+#: views/editors/review.thtml:292
+msgid "editors_review_th_reviewer"
+msgstr "Revisore"
+
+#: views/editors/review.thtml:290
+msgid "editors_review_th_version_file"
+msgstr "Versione/File"
+
+#: views/editors/review.thtml:217
+msgid "editors_review_update_notify_once"
+msgstr "Invia una segnalazione al prossimo aggiornamento di questo componente aggiuntivo. (non verranno inviate e-mail per aggiornamenti successivi)"
+
+#: controllers/editors_controller.php:298
+msgid "editors_reviewed_successfully"
+msgstr "Revisione eseguita con successo."
+
+#: views/editors/reviews_queue.thtml:106
+msgid "editors_reviews_action_delete_review"
+msgstr "Elimina revisione"
+
+#: views/editors/reviews_queue.thtml:104
+msgid "editors_reviews_action_keep"
+msgstr "Rimuovi i flag; mantieni la revisione"
+
+#: views/editors/reviews_queue.thtml:102
+msgid "editors_reviews_action_skip"
+msgstr "Ignora"
+
+#: views/editors/reviews_queue.thtml:100
+msgid "editors_reviews_header_action"
+msgstr "Azione"
+
+#: views/editors/reviews_queue.thtml:67
+msgid "editors_reviews_in_reply_to"
+msgstr "In risposta a:"
+
+#: controllers/editors_controller.php:748
+msgid "editors_reviews_processed"
+msgstr "Processo di revisione completato con successo."
+
+#: views/editors/reviews_queue.thtml:117
+msgid "editors_reviews_queue_empty"
+msgstr "Attualmente non ci sono revisioni in moderazione."
+
+#: views/editors/reviews_queue.thtml:111
+msgid "editors_reviews_submit_process_reviews"
+msgstr "Elabora revisioni"
+
+#: controllers/editors_controller.php:691
+msgid "editors_site_specific"
+msgstr "Specifico per un determinato sito web"
+
+#: controllers/editors_controller.php:348
+msgid "editors_tested_app"
+msgstr "Applicazione verificata"
+
+#: controllers/editors_controller.php:347
+msgid "editors_tested_os"
+msgstr "Sistemi operativi verificati"
+
+#: views/editors/queue.thtml:151
+msgid "editors_th_additional_info"
+msgstr "Informazioni aggiuntive"
+
+#: views/editors/featured.thtml:63
+#: views/editors/queue.thtml:109
+#: views/admin/flagged_queue.thtml:53
+msgid "editors_th_addon"
+msgstr "Componente aggiuntivo"
+
+#: views/editors/queue.thtml:125
+msgid "editors_th_addontype"
+msgstr "Tipologia"
+
+#: views/editors/featured.thtml:64
+msgid "editors_th_locales"
+msgstr "Limita ai locale?"
+
+#: views/editors/queue.thtml:148
+msgid "editors_th_nomination_age"
+msgstr "Tempo in coda"
+
+#: views/editors/queue.thtml:101
+#: views/editors/queue.thtml:117
+#: views/editors/queue.thtml:144
+msgid "editors_th_sort_ascending"
+msgstr "Ordine ascendente"
+
+#: views/editors/queue.thtml:105
+#: views/editors/queue.thtml:121
+#: views/editors/queue.thtml:140
+msgid "editors_th_sort_descending"
+msgstr "Ordine discendente"
+
+#. %s is a number
+#: controllers/editors_controller.php:1036
+#, php-format
+msgid "editors_x_days"
+msgstr "%s giorni"
+
+#. %s is a number
+#: controllers/editors_controller.php:1044
+#, php-format
+msgid "editors_x_hours"
+msgstr "%s ore"
+
+#. %s is a number
+#: controllers/editors_controller.php:1052
+#, php-format
+msgid "editors_x_minutes"
+msgstr "%s minuti"
+
+#: views/errors/error401.thtml:50
+#: controllers/components/simple_acl.php:81
+#: controllers/components/simple_acl.php:82
+#: controllers/components/simple_acl.php:83
+#: controllers/components/amo.php:607
+#: controllers/components/amo.php:608
+#: controllers/components/amo.php:609
+#: controllers/reviews_controller.php:353
+#: controllers/reviews_controller.php:485
+#: controllers/collections_controller.php:438
+#: controllers/collections_controller.php:496
+#: controllers/collections_controller.php:504
+#: controllers/collections_controller.php:971
+#: controllers/collections_controller.php:1034
+#: controllers/collections_controller.php:1077
+msgid "error_access_denied"
+msgstr "Accesso negato"
+
+#: views/errors/error401.thtml:52
+msgid "error_access_denied_message"
+msgstr "Non possiedi l'autorizzazione per visualizzare questa pagina."
+
+#: controllers/collections_controller.php:1039
+msgid "error_addon_exists"
+msgstr "Il componente aggiuntivo è già presente"
+
+#: controllers/developers_controller.php:200
+#: controllers/developers_controller.php:593
+#: controllers/developers_controller.php:1016
+#: controllers/developers_controller.php:1429
+#: controllers/downloads_controller.php:95
+#: controllers/downloads_controller.php:102
+#: controllers/downloads_controller.php:164
+#: controllers/statistics_controller.php:135
+#: controllers/previews_controller.php:115
+#: controllers/previews_controller.php:206
+#: controllers/previews_controller.php:307
+#: controllers/reviews_controller.php:77
+#: controllers/reviews_controller.php:240
+#: controllers/reviews_controller.php:332
+#: controllers/reviews_controller.php:340
+#: controllers/api_controller.php:123
+#: controllers/api_controller.php:759
+#: controllers/addons_controller.php:131
+#: controllers/addons_controller.php:197
+#: controllers/addons_controller.php:1407
+#: controllers/addons_controller.php:1465
+#: controllers/addons_controller.php:1469
+#: controllers/addons_controller.php:1503
+#: controllers/editors_controller.php:265
+#: controllers/collections_controller.php:1041
+#: controllers/collections_controller.php:1074
+msgid "error_addon_notfound"
+msgstr "Impossibile trovare il componente aggiuntivo"
+
+#: controllers/files_controller.php:83
+#: controllers/files_controller.php:196
+msgid "error_addon_notviewable"
+msgstr "Questo componente aggiuntivo non può essere visualizzato."
+
+#: controllers/reviews_controller.php:246
+msgid "error_addon_selfreview"
+msgstr "Non è consentito fare la recensione di un componente aggiuntivo."
+
+#: controllers/addons_controller.php:970
+msgid "error_browse_no_addons"
+msgstr "Impossibile trovare componenti aggiuntivi in questa categoria"
+
+#: controllers/api_controller.php:424
+msgid "error_collection_feed_notfound"
+msgstr "Impossibile trovare il feed del componente aggiuntivo."
+
+#: views/users/register.thtml:65
+#: views/users/edit.thtml:194
+msgid "error_email_invalid"
+msgstr "Indirizzo e-mail non valido."
+
+#: views/users/pwreset.thtml:74
+#: views/users/register.thtml:70
+#: views/users/register.thtml:80
+#: views/users/register.thtml:86
+#: views/users/edit.thtml:105
+#: views/users/edit.thtml:111
+#: views/users/edit.thtml:192
+#: views/admin/users_edit.thtml:78
+#: views/admin/users_edit.thtml:83
+#: views/reviews/add.thtml:80
+#: views/reviews/add.thtml:104
+msgid "error_field_required"
+msgstr "Questo campo non può essere lasciato vuoto."
+
+#: controllers/files_controller.php:75
+#: controllers/files_controller.php:93
+#: controllers/files_controller.php:96
+#: controllers/files_controller.php:163
+#: controllers/files_controller.php:176
+#: controllers/files_controller.php:185
+#: controllers/files_controller.php:204
+#: controllers/editors_controller.php:412
+msgid "error_file_notfound"
+msgstr "Impossibile trovare il file."
+
+#. %s is a filename
+#: controllers/editors_controller.php:430
+#, php-format
+msgid "error_file_x_notfound"
+msgstr "Errore: %s non esiste."
+
+#: views/collections/add.thtml:55
+#: views/collections/edit.thtml:89
+#: views/users/register.thtml:54
+#: views/users/edit.thtml:81
+#: views/reviews/add.thtml:70
+#: controllers/groups_controller.php:80
+#: controllers/groups_controller.php:102
+msgid "error_formerrors"
+msgstr "Sono presenti degli errori nel modulo: si prega di correggerli e inviare nuovamente."
+
+#: views/users/register.thtml:109
+msgid "error_invalid_captcha"
+msgstr "Captcha non valido, riprova"
+
+#: views/users/register.thtml:100
+#: views/users/edit.thtml:125
+#: views/admin/users_edit.thtml:101
+msgid "error_invalid_url"
+msgstr "Questo URL è in formato non valido. Un URL valido deve avere una struttura del tipo http://example.com/my_page."
+
+#. %s is a string representing what's missing. Example: file_id
+#: controllers/downloads_controller.php:65
+#: controllers/users_controller.php:185
+#: controllers/users_controller.php:264
+#: controllers/users_controller.php:559
+#: controllers/users_controller.php:653
+#: controllers/reviews_controller.php:71
+#: controllers/reviews_controller.php:234
+#: controllers/reviews_controller.php:325
+#: controllers/reviews_controller.php:473
+#: controllers/reviews_controller.php:475
+#: controllers/addons_controller.php:182
+#: controllers/addons_controller.php:1381
+#: controllers/addons_controller.php:1455
+#: controllers/collections_controller.php:266
+#: controllers/collections_controller.php:285
+#: controllers/collections_controller.php:346
+#: controllers/collections_controller.php:443
+#: controllers/collections_controller.php:482
+#: controllers/collections_controller.php:936
+#: controllers/collections_controller.php:959
+#: controllers/collections_controller.php:960
+#: controllers/collections_controller.php:975
+#: controllers/collections_controller.php:977
+#: controllers/collections_controller.php:994
+#: controllers/collections_controller.php:1003
+#: controllers/collections_controller.php:1016
+#: controllers/collections_controller.php:1017
+#: controllers/collections_controller.php:1024
+#: controllers/collections_controller.php:1070
+#: controllers/collections_controller.php:1090
+#, php-format
+msgid "error_missing_argument"
+msgstr "Argomento assente: %s"
+
+#: controllers/components/amo.php:507
+#: controllers/components/amo.php:532
+msgid "error_no_files_in_addon"
+msgstr "Nessun file"
+
+#: controllers/previews_controller.php:200
+msgid "error_preview_notfound"
+msgstr "Impossibile trovare l'anteprima"
+
+#: views/addons/display.thtml:400
+#: views/reviews/add.thtml:98
+msgid "error_review_rating_required"
+msgstr "Bisogna assegnare un voto."
+
+#: controllers/users_controller.php:160
+msgid "error_user_already_confirmed"
+msgstr "Questo account utente è già attivo."
+
+#: controllers/users_controller.php:202
+#: controllers/users_controller.php:276
+#: controllers/users_controller.php:569
+#: controllers/users_controller.php:581
+#: controllers/users_controller.php:587
+#: controllers/users_controller.php:610
+#: controllers/users_controller.php:627
+msgid "error_user_badconfirmationcode"
+msgstr "Codice di conferma non valido"
+
+#: views/users/pwreset.thtml:79
+#: views/users/register.thtml:75
+#: views/users/edit.thtml:183
+msgid "error_user_confirmpw_nomatch"
+msgstr "Le password non corrispondono."
+
+#: views/users/register.thtml:65
+#: views/users/edit.thtml:190
+#: controllers/users_controller.php:617
+msgid "error_user_email_notunique"
+msgstr "Questo indirizzo e-mail è già utilizzato da un altro utente."
+
+#: controllers/users_controller.php:596
+msgid "error_user_emailchange_expired"
+msgstr "Il tempo massimo per il cambio e-mail è scaduto. Modificare nuovamente l'indirizzo e-mail nel profilo utente e fare clic sul link nella mail di conferma non appena si riceve il messaggio."
+
+#: controllers/collections_controller.php:985
+msgid "error_user_exists"
+msgstr "Un utente può avere un solo ruolo. Rimuovere i ruoli esistenti prima di proseguire."
+
+#: views/users/register.thtml:91
+#: views/users/edit.thtml:116
+#: views/admin/users_edit.thtml:88
+msgid "error_user_nickname_notunique"
+msgstr "Questo nome utente è già utilizzato."
+
+#: views/users/pwreset.thtml:54
+#: controllers/users_controller.php:191
+#: controllers/users_controller.php:270
+#: controllers/users_controller.php:603
+#: controllers/users_controller.php:659
+#: controllers/collections_controller.php:988
+#: controllers/collections_controller.php:998
+msgid "error_user_notfound"
+msgstr "Utente non trovato"
+
+#: views/users/activatefirst.thtml:47
+msgid "error_user_unconfirmed"
+msgstr "Attivare il proprio account utilizzando il codice di conferma ricevuto via e-mail."
+
+#: views/users/login.thtml:67
+msgid "error_username_or_pw_wrong"
+msgstr "Nome utente o password non corretti"
+
+#: controllers/editors_controller.php:260
+msgid "error_version_notfound"
+msgstr "Impossibile trovare la versione"
+
+#: views/users/delete.thtml:125
+#: views/users/edit.thtml:173
+msgid "error_wrong_password"
+msgstr "La password inserita non è corretta"
+
+#: views/elements/amo2009/homepage_addon.thtml:122
+#: views/elements/feature.thtml:122
+msgid "feature_learnmore"
+msgstr "Dettagli"
+
+#. %1 is the add-on name
+#: views/elements/amo2009/homepage_addon.thtml:123
+#: views/elements/feature.thtml:123
+#, php-format
+msgid "feature_learnmore_about_addon"
+msgstr "Ulteriori informazioni su %1$s"
+
+#. %1$s is a number
+#: views/elements/amo2009/reviews.thtml:52
+#: views/elements/addon_listitem.thtml:112
+#: views/elements/feature.thtml:99
+#: views/addons/browse_thumbs.thtml:86
+#, php-format
+msgid "feature_reviews"
+msgid_plural "feature_reviews"
+msgstr[0] "%1$s recensioni"
+msgstr[1] "%1$s recensioni"
+
+#: views/elements/amo2009/homepage_addon.thtml:127
+#: views/elements/feature.thtml:127
+msgid "feature_view_more_from_category"
+msgstr "Visualizza altri in"
+
+#. This appears on a page that views the source of an add-on. This link will return
+#. the user to the add-on's main page
+#: views/files/browse.thtml:65
+msgid "file_browser_link_addon"
+msgstr "Torna al componente aggiuntivo"
+
+#. There is a list of directories and files on the page. Clicking this will show the
+#. contents of all the directories (normally you would click on each one to see the
+#. contents)
+#: views/files/browse.thtml:67
+msgid "file_browser_link_expand_all"
+msgstr "Espandi tutto"
+
+#. This appears on a page that views the source of an add-on. This link will return
+#. the user to the add-on's review page (it only appears if the add-on is being
+#. reviewed)
+#: views/files/browse.thtml:64
+msgid "file_browser_link_review"
+msgstr "Torna alla recensione"
+
+#. The title of the page for viewing an add-on's source.
+#. %1$s is the name of the add-on
+#. %2$s is the name of the current application (e.g. Firefox or Thunderbird)
+#: views/files/browse.thtml:46
+msgid "file_browser_title"
+msgstr "%1$s :: Esplora file :: %2$s Add-ons"
+
+#. This appears on a page that views the source of an add-on. There is a list of
+#. directories and files on the page. Clicking this link will toggle between an
+#. expanded or a collapsed list. This string should be kept short.
+#: views/files/browse.thtml:68
+msgid "file_browser_toggle_expand_collapse"
+msgstr "+/-"
+
+#. Link text for the AMO About page.
+#: views/elements/footer.thtml:72
+#: views/layouts/amo2009.thtml:341
+msgid "footer_a_about"
+msgstr "Informazioni su"
+
+#. Link text to the AMO blog.
+#: views/elements/footer.thtml:74
+#: views/layouts/amo2009.thtml:343
+msgid "footer_a_blog"
+msgstr "Blog"
+
+#. Link text to the Frequently Asked Questions page.
+#: views/elements/footer.thtml:73
+#: views/layouts/amo2009.thtml:342
+msgid "footer_a_faq"
+msgstr "FAQ"
+
+#. Full text for the FAQ abbreviation.
+#: views/elements/footer.thtml:73
+#: views/pages/collector_features.thtml:72
+#: views/layouts/amo2009.thtml:342
+msgid "footer_abbr_faq"
+msgstr "Domande più frequenti"
+
+#: views/elements/footer.thtml:67
+#: views/layouts/amo2009.thtml:336
+msgid "footer_all_rights_reserved"
+msgstr "Tutti i diritti riservati."
+
+#: views/elements/footer.thtml:67
+#: views/layouts/amo2009.thtml:336
+msgid "footer_copyright"
+msgstr "Copyright"
+
+#: views/elements/footer.thtml:71
+#: views/layouts/amo2009.thtml:340
+msgid "footer_credits"
+msgstr "Crediti"
+
+#: views/elements/footer.thtml:76
+#: views/layouts/amo2009.thtml:346
+msgid "footer_disclaimer"
+msgstr "Mozilla fornisce link a queste applicazioni ma non garantisce in alcun modo il corretto funzionamento di tali software o l'attendibilità delle informazioni visualizzate. Qualsiasi domanda, reclamo o pretesa riguardanti queste applicazioni va diretta al rivenditore di riferimento del software."
+
+#: views/elements/footer.thtml:61
+#: views/layouts/amo2009.thtml:332
+msgid "footer_lang_form_lang_submit_go"
+msgstr "Vai"
+
+#: views/elements/footer.thtml:70
+#: views/layouts/amo2009.thtml:339
+msgid "footer_legal_notices"
+msgstr "Note legali"
+
+#: views/elements/footer.thtml:50
+#: views/layouts/amo2009.thtml:321
+msgid "footer_other_languages"
+msgstr "Altre lingue:"
+
+#: views/elements/footer.thtml:69
+#: views/layouts/amo2009.thtml:338
+msgid "footer_privacy_policy"
+msgstr "Informativa sulla privacy"
+
+#: models/addontype.php:79
+msgid "general_addontype_dict"
+msgstr "dizionari"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:100
+msgid "general_addontype_dict_plural"
+msgstr "dizionari"
+
+#: models/addontype.php:75
+msgid "general_addontype_extension"
+msgstr "estensioni"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:98
+msgid "general_addontype_extension_plural"
+msgstr "estensioni"
+
+#: models/addontype.php:85
+msgid "general_addontype_lpaddon"
+msgstr "language pack (componente aggiuntivo)"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:103
+msgid "general_addontype_lpaddon_plural"
+msgstr "language pack (componente aggiuntivo)"
+
+#: models/addontype.php:83
+msgid "general_addontype_lpapp"
+msgstr "language pack (applicazione)"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:102
+msgid "general_addontype_lpapp_plural"
+msgstr "language pack (applicazione)"
+
+#: models/addontype.php:87
+msgid "general_addontype_plugin"
+msgstr "plugin"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:104
+msgid "general_addontype_plugin_plural"
+msgstr "plugin"
+
+#: models/addontype.php:81
+msgid "general_addontype_search"
+msgstr "motori di ricerca"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:101
+msgid "general_addontype_search_plural"
+msgstr "motori di ricerca"
+
+#: models/addontype.php:77
+msgid "general_addontype_theme"
+msgstr "tema"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:99
+msgid "general_addontype_theme_plural"
+msgstr "temi"
+
+#: config/language.php:367
+msgid "general_languages_all_locales"
+msgstr "Tutti i locale"
+
+#: views/layouts/amo2009.thtml:249
+msgid "header_brand_name"
+msgstr "Mozilla"
+
+#. %1$s is the application name. Example: Firefox
+#: views/elements/header.thtml:111
+#: views/elements/header.thtml:122
+#: views/layouts/amo2009.thtml:248
+#, php-format
+msgid "header_home_tooltip"
+msgstr "Ritorna alla pagina iniziale di %1$s Add-ons"
+
+#: views/elements/header.thtml:87
+msgid "header_main_firefox_header"
+msgstr "Firefox Add-ons"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:218
+msgid "header_main_firefox_header_with_logo"
+msgstr "Add-ons <em>per</em> <img alt=\"Firefox\" src=\"%1$s\" /> <strong>Firefox</strong>"
+
+#: views/elements/header.thtml:99
+msgid "header_main_header"
+msgstr "Add-ons"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:242
+msgid "header_main_header_with_logo"
+msgstr "Add-ons <img alt=\"Add-ons\" src=\"%1$s\" />"
+
+#: views/elements/header.thtml:90
+msgid "header_main_seamonkey_header"
+msgstr "Seamonkey Add-ons"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:224
+msgid "header_main_seamonkey_header_with_logo"
+msgstr "Add-ons <em>per</em> <img alt=\"seamonkey\" src=\"%1$s\" /> <strong>SeaMonkey</strong>"
+
+#: views/elements/header.thtml:93
+msgid "header_main_sunbird_header"
+msgstr "Sunbird Add-ons"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:230
+msgid "header_main_sunbird_header_with_logo"
+msgstr "Add-ons <em>per</em> <img alt=\"sunbird\" src=\"%1$s\" /> <strong>Sunbird</strong>"
+
+#: views/elements/header.thtml:96
+msgid "header_main_thunderbird_header"
+msgstr "Thunderbird Add-ons"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:236
+msgid "header_main_thunderbird_header_with_logo"
+msgstr "Add-ons <em>per</em> <img alt=\"thunderbird\" src=\"%1$s\" /> <strong>Thunderbird</strong>"
+
+#: views/layouts/amo2009.thtml:205
+msgid "header_navaccess_applications_menu"
+msgstr "Vai al menu altre applicazioni"
+
+#: views/layouts/amo2009.thtml:204
+msgid "header_navaccess_categories_menu"
+msgstr "Vai al menu categorie"
+
+#: views/layouts/amo2009.thtml:202
+msgid "header_navaccess_main_content"
+msgstr "Vai al contenuto principale"
+
+#: views/layouts/amo2009.thtml:203
+msgid "header_navaccess_search_form"
+msgstr "Vai al campo di ricerca"
+
+#: views/elements/header.thtml:62
+msgid "header_navlink_addons"
+msgstr "Componenti aggiuntivi"
+
+#: views/elements/developers/sidebar.thtml:72
+#: views/elements/developers/myaddons.thtml:50
+#: views/elements/header.thtml:159
+#: views/addons/display.thtml:378
+msgid "header_navlink_login"
+msgstr "Accedi"
+
+#: views/elements/header.thtml:156
+#: views/layouts/amo2009.thtml:304
+msgid "header_navlink_logout"
+msgstr "Disconnetti"
+
+#: views/elements/header.thtml:145
+#: views/layouts/amo2009.thtml:303
+msgid "header_navlink_myaccount"
+msgstr "Il mio profilo"
+
+#: views/elements/header.thtml:158
+msgid "header_navlink_register"
+msgstr "Registrati"
+
+#. %1 is the URL to the registration page
+#. %2 is the URL to the login page
+#: views/layouts/amo2009.thtml:278
+msgid "header_navlink_register_or_login"
+msgstr "<a href=\"%1$s\">Registrati</a> o <a href=\"%2$s\">accedi</a>"
+
+#: views/layouts/amo2009.thtml:285
+msgid "header_navlink_tools"
+msgstr "Strumenti"
+
+#. %s is the add-on name
+#: views/elements/collections_interactive_addon.thtml:62
+#: views/elements/amo2009/homepage_addon.thtml:77
+#: views/elements/addon_discussionheader.thtml:62
+#: views/elements/addon_listitem.thtml:67
+#: views/elements/feature.thtml:84
+#: views/addons/category_landing.thtml:87
+#: views/addons/browse_thumbs.thtml:60
+#, php-format
+msgid "img_preview_of"
+msgstr "Anteprima immagine di %s"
+
+#. %1 is the login URL for the link tag
+#. %2 is the link to an explanatory page.
+#: views/elements/amo2009/install.thtml:307
+#: views/elements/install.thtml:255
+msgid "install_a_login_to_install"
+msgstr "<a href=\"%1$s\">Accedere</a> per installare questo componente aggiuntivo. <a href=\"%2$s\">Perché</a>?"
+
+#. %1 is the URL for the Experimental Add-ons section of the FAQ page
+#: views/elements/amo2009/install.thtml:283
+#: views/elements/install.thtml:232
+msgid "install_button_confirm_exp_install"
+msgstr "Lasciami installare questo componente aggiuntivo sperimentale. <a href=\"%1$s\">Che cos'è questo?</a>"
+
+#. %1$s is the application name. Example: Firefox
+#. %2$s is an optional string used to specify a platform. Example: (Windows)
+#: views/elements/amo2009/install.thtml:128
+#: views/elements/install.thtml:75
+#, php-format
+msgid "install_button_text"
+msgstr "Aggiungi a %1$s %2$s"
+
+#. %1 is the add-on name, %2 is the app name
+#: views/elements/amo2009/install.thtml:191
+#: views/elements/amo2009/install.thtml:206
+#: views/elements/amo2009/install.thtml:249
+#: views/elements/amo2009/install.thtml:298
+#: views/elements/install.thtml:150
+#: views/elements/install.thtml:165
+#: views/elements/install.thtml:202
+#: views/elements/install.thtml:246
+#, php-format
+msgid "install_button_title"
+msgstr "Aggiungi %1$s a %2$s"
+
+#. %1$s is the add-on name
+#: views/elements/amo2009/install.thtml:200
+#: views/elements/install.thtml:159
+#, php-format
+msgid "install_download"
+msgstr "Scarica %1$s"
+
+#: views/elements/amo2009/install.thtml:147
+#: views/elements/install.thtml:94
+msgid "install_error_addon_not_found"
+msgstr "Questo componente aggiuntivo non è disponibile."
+
+#: views/addons/dictionaries.thtml:65
+msgid "langtools_a11y_tablesummary"
+msgstr "Elenco dei language pack e dei dizionari."
+
+#: views/addons/dictionaries.thtml:47
+msgid "langtools_download_dictionary"
+msgstr "Scarica dizionario"
+
+#: views/addons/dictionaries.thtml:48
+msgid "langtools_download_langpack"
+msgstr "Scarica language pack"
+
+#: views/addons/dictionaries.thtml:63
+#: controllers/components/amo.php:685
+#: controllers/addons_controller.php:1239
+msgid "langtools_header_dicts_and_langpacks"
+msgstr "Dizionari e language pack"
+
+#: views/addons/dictionaries.thtml:44
+msgid "langtools_install_dictionary"
+msgstr "Installa dizionario"
+
+#: views/addons/dictionaries.thtml:45
+msgid "langtools_install_langpack"
+msgstr "Installa language pack"
+
+#: views/addons/dictionaries.thtml:69
+msgid "langtools_tableheader_dictionary"
+msgstr "Dizionari"
+
+#: views/addons/dictionaries.thtml:70
+msgid "langtools_tableheader_langpack"
+msgstr "Language pack"
+
+#: views/addons/dictionaries.thtml:68
+msgid "langtools_tableheader_language"
+msgstr "Lingua"
+
+#: models/license.php:65
+msgid "license_custom"
+msgstr "Licenza personalizzata"
+
+#: config/bootstrap.php:303
+msgid "licenses_bsd"
+msgstr "Licenza BSD"
+
+#: config/bootstrap.php:298
+msgid "licenses_gpl_2.0"
+msgstr "Licenza GNU General Public License, versione 2.0"
+
+#: config/bootstrap.php:299
+msgid "licenses_gpl_3.0"
+msgstr "Licenza GNU General Public License, versione 3.0"
+
+#: config/bootstrap.php:300
+msgid "licenses_lgpl_2.1"
+msgstr "Licenza GNU Lesser General Public License, versione 2.1"
+
+#: config/bootstrap.php:301
+msgid "licenses_lgpl_3.0"
+msgstr "Licenza GNU Lesser General Public License, versione 3.0"
+
+#: config/bootstrap.php:302
+msgid "licenses_mit"
+msgstr "Licenza MIT/X11"
+
+#: config/bootstrap.php:297
+msgid "licenses_mpl_1.1"
+msgstr "Licenza Mozilla Public License, versione 1.1"
+
+#: views/users/emailchange.thtml:51
+#: views/users/delete.thtml:55
+#: views/users/delete.thtml:137
+#: views/users/edit.thtml:74
+#: views/reviews/flag.thtml:54
+msgid "link_return_to_front_page"
+msgstr "Fare clic qui per tornare alla pagina iniziale."
+
+#: views/elements/amo2009/addon_list_options.thtml:46
+#: views/elements/addon_list_options.thtml:46
+msgid "list_sortby_date"
+msgstr "Data"
+
+#: views/elements/amo2009/addon_list_options.thtml:47
+#: views/elements/addon_list_options.thtml:47
+msgid "list_sortby_downloads"
+msgstr "Download"
+
+#: views/elements/amo2009/addon_list_options.thtml:45
+#: views/elements/addon_list_options.thtml:45
+msgid "list_sortby_name"
+msgstr "Nome"
+
+#: views/elements/amo2009/addon_list_options.thtml:48
+#: views/elements/addon_list_options.thtml:48
+msgid "list_sortby_rating"
+msgstr "Voto"
+
+#: config/bootstrap.php:278
+msgid "main_prettyname_fennec"
+msgstr "Fennec"
+
+#: config/bootstrap.php:274
+msgid "main_prettyname_firefox"
+msgstr "Firefox"
+
+#: config/bootstrap.php:277
+msgid "main_prettyname_seamonkey"
+msgstr "SeaMonkey"
+
+#: config/bootstrap.php:276
+msgid "main_prettyname_sunbird"
+msgstr "Sunbird"
+
+#: config/bootstrap.php:275
+msgid "main_prettyname_thunderbird"
+msgstr "Thunderbird"
+
+#: views/elements/addon_categories.thtml:52
+msgid "nav_category_dicts_langpacks"
+msgstr "Dizionari e language pack"
+
+#: views/elements/addon_categories.thtml:55
+msgid "nav_category_themes"
+msgstr "Temi"
+
+#: views/elements/app_chooser.thtml:47
+#: views/layouts/amo2009.thtml:255
+msgid "other_apps_tooltip"
+msgstr "Scopri i componenti aggiuntivi per le altre applicazioni"
+
+#. In a user list: user 1, user 2, "others"
+#: views/helpers/addons_html.php:222
+msgid "other_users"
+msgstr "altri"
+
+#: controllers/pages_controller.php:90
+msgid "page_title_appversions"
+msgstr "Versioni applicazione"
+
+#: controllers/pages_controller.php:115
+msgid "page_title_collector"
+msgstr "Add-on Collector"
+
+#: controllers/pages_controller.php:117
+msgid "page_title_collector_faq"
+msgstr "FAQ di Add-on Collector"
+
+#: controllers/pages_controller.php:119
+msgid "page_title_collector_features"
+msgstr "Funzioni di Add-on Collector"
+
+#: controllers/pages_controller.php:122
+msgid "page_title_collector_firstrun"
+msgstr "Benvenuto in Add-on Collector"
+
+#: controllers/pages_controller.php:92
+msgid "page_title_credits"
+msgstr "Credit"
+
+#: controllers/pages_controller.php:113
+msgid "page_title_developer_faq"
+msgstr "FAQ sviluppatori"
+
+#: controllers/pages_controller.php:111
+msgid "page_title_faq"
+msgstr "Domande più frequenti"
+
+#: controllers/pages_controller.php:94
+msgid "page_title_fashionyourfirefox_faq"
+msgstr "FAQ - Migliora lo stile di Firefox"
+
+#: controllers/pages_controller.php:101
+msgid "page_title_policy"
+msgstr "Policy per i componenti aggiuntivi"
+
+#: controllers/pages_controller.php:103
+msgid "page_title_privacy"
+msgstr "Informativa sulla privacy di Mozilla"
+
+#: controllers/pages_controller.php:105
+msgid "page_title_review_guide"
+msgstr "Linee guida per la revisione"
+
+#: controllers/pages_controller.php:107
+msgid "page_title_sandbox"
+msgstr "Sistema di revisione e Sandbox"
+
+#: controllers/pages_controller.php:109
+msgid "page_title_submissionhelp"
+msgstr "Guida per l'inserimento"
+
+#: views/pages/appversions.thtml:87
+msgid "pages_appversions_guid"
+msgstr "GUID"
+
+#: views/pages/appversions.thtml:79
+#: controllers/pages_controller.php:90
+msgid "pages_appversions_header"
+msgstr "Versioni consentite delle applicazioni"
+
+#: views/pages/appversions.thtml:80
+msgid "pages_appversions_intro"
+msgstr "I componenti aggiuntivi inviati a Mozilla Add-ons devono contenere un file install.rdf con il supporto ad almeno una delle seguenti applicazioni. Verranno accettate solo le versioni delle applicazioni indicate nell'elenco seguente."
+
+#. %s is a full <a> tag
+#: views/pages/appversions.thtml:93
+#, php-format
+msgid "pages_appversions_required_files"
+msgstr "Se l'applicazione di riferimento non richiede la presenza del file install.rdf, è comunque necessario includerne uno con le caratteristiche specificate %s."
+
+#. this is the text inside of an <a> tag for pages_appversions_required_files. This
+#. should be fixed.
+#: views/pages/appversions.thtml:93
+msgid "pages_appversions_required_files_link"
+msgstr "qui"
+
+#: views/pages/appversions.thtml:88
+msgid "pages_appversions_versions"
+msgstr "Versioni"
+
+#: views/pages/policy.thtml:51
+msgid "pages_policy_sandbox_link"
+msgstr "Pagina di informazioni sulla sandbox"
+
+#: views/elements/pagination.thtml:53
+msgid "pagination_next_page"
+msgstr "successivo"
+
+#: views/elements/pagination.thtml:52
+msgid "pagination_previous_page"
+msgstr "precedente"
+
+#: views/elements/recaptcha.thtml:65
+msgid "recaptcha_enter_both_words"
+msgstr "Inserire <strong>entrambe le parole</strong> seguenti, <strong>separate da uno spazio</strong>."
+
+#: views/elements/recaptcha.thtml:83
+msgid "recaptcha_enter_here"
+msgstr "Inserisci qui la risposta:"
+
+#: views/elements/recaptcha.thtml:74
+msgid "recaptcha_enter_whatyouhear"
+msgstr "Digita quello che hai ascoltato."
+
+#. %1 is the link switching refreshing the captcha
+#. %2 is the link switching to a text captcha
+#: views/elements/recaptcha.thtml:77
+msgid "recaptcha_hardtohear_text"
+msgstr "Se è difficile da comprendere, puoi <a href=\"%1$s\">provare con un testo diverso</a> oppure <a href=\"%2$s\">tornare al testo</a>."
+
+#. %1 is the link switching refreshing the captcha
+#. %2 is the link switching to an audio captcha
+#: views/elements/recaptcha.thtml:68
+msgid "recaptcha_hardtoread_text"
+msgstr "Se è difficile da leggere, puoi <a href=\"%1$s\">provare con un testo diverso</a> oppure <a href=\"%2$s\">tornare al testo</a>."
+
+#: views/users/register.thtml:105
+msgid "recaptcha_label"
+msgstr "Sei umano?"
+
+#: views/users/register.thtml:106
+msgid "recaptcha_whatsthis"
+msgstr "Che cos'è questo?"
+
+#: controllers/reviews_controller.php:559
+msgid "review_flag_error"
+msgstr "Errore durante la segnalazione di questa recensione"
+
+#: models/reviews_moderation_flag.php:69
+msgid "review_flag_reason_bug_support"
+msgstr "Segnalazione bug o richiesta di supporto inserita nella sezione non corretta"
+
+#: views/reviews/display.thtml:103
+#: views/reviews/display.thtml:186
+msgid "review_flag_reason_instructions"
+msgstr "Segnala questa recensione (selezionare un motivo)"
+
+#: models/reviews_moderation_flag.php:67
+msgid "review_flag_reason_language"
+msgstr "Linguaggio non appropriato"
+
+#: models/reviews_moderation_flag.php:71
+msgid "review_flag_reason_other"
+msgstr "Altro (specificare)"
+
+#: models/reviews_moderation_flag.php:65
+msgid "review_flag_reason_spam"
+msgstr "Spam o contenuti fuori luogo"
+
+#: views/reviews/display.thtml:91
+#: views/reviews/display.thtml:175
+#: controllers/reviews_controller.php:555
+msgid "review_flag_success"
+msgstr "Grazie; questa recensione è stata segnalata e verrà controllata da un revisore."
+
+#: views/reviews/display.thtml:41
+msgid "review_flag_this"
+msgstr "Segnala questa recensione"
+
+#: views/reviews/display.thtml:42
+msgid "review_flag_this_titletip"
+msgstr "Questa recensione è inappropriata, non accurata o si tratta di spam? Fai clic qui per segnalarla e farla verificare da un revisore."
+
+#. %1 is the URL of the support section, %2 for the review guidelines
+#: views/reviews/add.thtml:53
+msgid "review_guidelines_short"
+msgstr "<p>Ricorda questi suggerimenti:</p><ul><li>scrivi come se stessi descrivendo a un amico la tua esperienza con questo componente aggiuntivo. Fornisci informazioni utili e dettagliate, ad esempio spiegando quali funzioni hai apprezzato oppure non hai trovato utili, quanto è semplice usarlo e quali sono i difetti. Evita espressioni generiche come \"Grandioso\" oppure \"Pessimo\", a meno di fornire delle motivazioni valide per simili giudizi.</li><li>non inserire segnalazioni di bug o errori. Gli sviluppatori non sono in grado di visualizzare il tuo indirizzo e-mail e potrebbero aver bisogno di contattarti per aiutarti a risolvere il problema. Consulta la <a href=\"%1$s\">sezione di supporto</a> per scoprire come ottenere assistenza per questo componente aggiuntivo.</li><li>cerca di mantenere in ordine le recensioni, evita l'utilizzo di un linguaggio non appropriato e non inserire alcuna informazione personale.</li></ul><p>Consulta le <a href=\"%2$s\">Guide linea per la recensione</a> per ulteriori dettagli sulle recensioni dei componenti aggiuntivi.</p>"
+
+#. %1 is the add-on name
+#: views/reviews/flag.thtml:56
+#: views/reviews/display.thtml:55
+#: views/reviews/review_added.thtml:50
+#, php-format
+msgid "reviews_header"
+msgstr "Recensioni per %s"
+
+#: controllers/addons_controller.php:435
+msgid "rss_featuredaddons"
+msgstr "Componenti aggiuntivi disponibili"
+
+#: controllers/addons_controller.php:432
+msgid "rss_newestaddons"
+msgstr "Nuovi componenti aggiuntivi"
+
+#: controllers/addons_controller.php:434
+msgid "rss_popularaddons"
+msgstr "Componenti aggiuntivi più popolari"
+
+#: controllers/addons_controller.php:433
+msgid "rss_updatedaddons"
+msgstr "Componenti aggiornati"
+
+#: views/elements/search_mini.thtml:70
+msgid "search"
+msgstr "Cerca"
+
+#: views/search/collections.thtml:51
+msgid "search_collections_header"
+msgstr "Risultati ricerca raccolte"
+
+#: controllers/search_controller.php:297
+msgid "search_collections_pagetitle"
+msgstr "Risultati ricerca raccolte"
+
+#: controllers/search_controller.php:99
+msgid "search_disabled"
+msgstr "La ricerca è attualmente disattivata. Riprovare più tardi."
+
+#: views/elements/amo2009/search.thtml:188
+#: views/elements/search.thtml:187
+#: views/elements/search_mini.thtml:54
+msgid "search_form_all_addons"
+msgstr "tutte le categorie"
+
+#. This string is in the main category dropdown when searching
+#: views/elements/amo2009/search.thtml:204
+msgid "search_form_all_collections"
+msgstr "tutte le raccolte"
+
+#: views/elements/amo2009/search.thtml:184
+#: views/elements/amo2009/search.thtml:385
+#: views/elements/amo2009/search.thtml:408
+#: views/elements/search.thtml:171
+#: views/elements/search.thtml:183
+#: views/elements/search_mini.thtml:43
+#: views/elements/search_mini.thtml:49
+#: views/layouts/mozilla.thtml:188
+msgid "search_form_default_text"
+msgstr "cerca tra i componenti aggiuntivi"
+
+#: views/elements/amo2009/search.thtml:184
+#: views/elements/amo2009/search.thtml:404
+msgid "search_form_default_text_collections"
+msgstr "cerca una raccolta"
+
+#: views/elements/amo2009/search.thtml:206
+#: views/elements/search.thtml:202
+msgid "search_form_submit_tooltip"
+msgstr "Cerca tra i componenti aggiuntivi"
+
+#: views/elements/amo2009/search.thtml:184
+#: views/elements/search.thtml:183
+#: views/elements/search_mini.thtml:49
+msgid "search_form_tooltip"
+msgstr "Fare clic per digitare i termini di ricerca"
+
+#: views/elements/amo2009/search.thtml:186
+#: views/elements/search.thtml:185
+#: views/elements/search_mini.thtml:52
+msgid "search_form_within"
+msgstr "in"
+
+#: views/addons/searchengines.thtml:118
+msgid "search_landing_all_search_engines"
+msgstr "Tutti i Motori di ricerca"
+
+#: views/addons/searchengines.thtml:114
+msgid "search_landing_browse_search_engines"
+msgstr "Esplora i Motori di ricerca"
+
+#: views/search/collections.thtml:58
+#: views/search/index.thtml:59
+msgid "search_nothing_found"
+msgstr "Nessun risultato."
+
+#: controllers/search_controller.php:185
+msgid "search_pagetitle"
+msgstr "Cerca componenti aggiuntivi"
+
+#: controllers/search_controller.php:242
+msgid "search_rss_description"
+msgstr "Feed dei risultati di ricerca"
+
+#. %s is the terms the user is searching for (a string)
+#: controllers/search_controller.php:241
+#, php-format
+msgid "search_rss_results_for"
+msgstr "Risultati della ricerca per: %s"
+
+#: views/elements/header.thtml:154
+#: views/layouts/amo2009.thtml:296
+msgid "sidebar_navlink_admin_tools"
+msgstr "Strumenti di amministrazione"
+
+#: views/elements/header.thtml:146
+#: views/layouts/amo2009.thtml:288
+msgid "sidebar_navlink_developer_tools"
+msgstr "Strumenti per sviluppatori"
+
+#: views/elements/header.thtml:148
+#: views/layouts/amo2009.thtml:290
+msgid "sidebar_navlink_editor_tools"
+msgstr "Strumenti per revisori"
+
+#: views/layouts/amo2009.thtml:302
+msgid "sidebar_navlink_welcome"
+msgstr "Benvenuto"
+
+#. %s is the user's name
+#: views/layouts/amo2009.thtml:302
+#, php-format
+msgid "sidebar_navlink_welcome_name"
+msgstr "Benvenuto, %s"
+
+#: views/elements/pitch.thtml:50
+#: views/elements/pitch.thtml:55
+msgid "sidebar_pitch_dictionary"
+msgstr "dizionario"
+
+#: views/elements/pitch.thtml:72
+msgid "sidebar_pitch_featured_addons"
+msgstr "Consigliati da noi"
+
+#: views/elements/pitch.thtml:61
+msgid "sidebar_pitch_looking_for"
+msgstr "Stai cercando un:"
+
+#: views/elements/pitch.thtml:70
+msgid "sidebar_pitch_newest_addons"
+msgstr "Nuovi arrivi"
+
+#: views/elements/pitch.thtml:49
+msgid "sidebar_pitch_search"
+msgstr "motore di ricerca"
+
+#: views/elements/pitch.thtml:69
+msgid "sidebar_pitch_subscribe_to"
+msgstr "Abbonati a:"
+
+#: views/elements/pitch.thtml:48
+#: views/elements/pitch.thtml:54
+msgid "sidebar_pitch_theme"
+msgstr "tema"
+
+#: views/elements/pitch.thtml:71
+msgid "sidebar_pitch_updated_addons"
+msgstr "Aggiornamenti"
+
+#. %1$s is a number
+#: views/helpers/localization.php:65
+#: views/developers/versions_edit.thtml:95
+#: views/addons/dictionaries.thtml:92
+#, php-format
+msgid "size_kb"
+msgstr "%1$s KB"
+
+#: views/elements/amo2009/stars.thtml:57
+#: views/elements/stars.thtml:63
+msgid "stars_not_yet_rated"
+msgstr "Nessun voto"
+
+#. %1 is the number of stars this add-on has
+#: views/elements/amo2009/stars.thtml:49
+#: views/elements/stars.thtml:54
+#, php-format
+msgid "stars_rated_x_outof_5"
+msgstr "Voto %s stelle su 5"
+
+#: views/statistics/addon.thtml:59
+msgid "statistics_addon_dashboard_link"
+msgstr "Pannello statistiche"
+
+#: views/statistics/addon.thtml:58
+msgid "statistics_addon_developertools_link"
+msgstr "Strumenti per sviluppatori"
+
+#: views/statistics/addon.thtml:53
+msgid "statistics_addon_switch"
+msgstr "Cambia componente aggiuntivo"
+
+#. This is a date format.
+#. http://php.net/strftime
+#: views/statistics/rss/summary.thtml:54
+#: views/statistics/addon.thtml:181
+msgid "statistics_date_shortmonth"
+msgstr "%e %b."
+
+#. This is a date format.
+#. http://php.net/strftime
+#: views/statistics/rss/summary.thtml:40
+#: views/statistics/addon.thtml:152
+msgid "statistics_date_shortmonthwithyear"
+msgstr "%e %b. %Y"
+
+#. This is a date format.
+#. http://php.net/strftime
+#: views/statistics/rss/summary.thtml:41
+#: views/statistics/rss/summary.thtml:48
+#: views/statistics/addon.thtml:161
+#: views/statistics/addon.thtml:172
+msgid "statistics_date_weekdayshortmonth"
+msgstr "%A %e %b."
+
+#. %1$s is an add-on name and version. Example: Add-on 3.5
+#: controllers/components/stats.php:519
+#, php-format
+msgid "statistics_events_addon_created"
+msgstr "%1$s realizzati"
+
+#. %1$s is an application name and version. Example: Firefox 3.5
+#: controllers/components/stats.php:500
+#, php-format
+msgid "statistics_events_app_released"
+msgstr "%1$s rilasciati"
+
+#: views/statistics/addon.thtml:71
+msgid "statistics_help_close_link"
+msgstr "Chiudi"
+
+#: views/statistics/addon.thtml:60
+msgid "statistics_help_link"
+msgstr "Guida"
+
+#: views/statistics/index.thtml:83
+msgid "statistics_index_anotheraddon"
+msgstr "oppure selezionare un altro componente aggiuntivo"
+
+#: views/statistics/index.thtml:85
+msgid "statistics_index_anotheraddon_public"
+msgstr "oppure selezionare un componente aggiuntivo con statistiche pubbliche"
+
+#: views/statistics/index.thtml:71
+msgid "statistics_index_myaddons"
+msgstr "Selezionare uno dei propri componenti aggiuntivi per visualizzarne le statistiche"
+
+#: views/statistics/index.thtml:89
+msgid "statistics_index_selectaddon"
+msgstr "Selezionare un componente aggiuntivo per visualizzarne le statistiche"
+
+#: views/statistics/index.thtml:91
+msgid "statistics_index_selectaddon_public"
+msgstr "Selezionare un componente aggiuntivo con statistiche pubbliche"
+
+#: views/statistics/index.thtml:39
+msgid "statistics_index_title"
+msgstr "Pannello statistiche"
+
+#: views/statistics/index.thtml:97
+msgid "statistics_index_view_button"
+msgstr "Visualizza statistiche"
+
+#: views/statistics/addon.thtml:222
+#: controllers/statistics_controller.php:247
+msgid "statistics_js_download_csv"
+msgstr "Visualizza questa tabella in formato CSV"
+
+#: controllers/statistics_controller.php:246
+msgid "statistics_js_dropdowns_none"
+msgstr "nessuno"
+
+#: controllers/statistics_controller.php:245
+msgid "statistics_js_dropdowns_removeplot"
+msgstr "Rimuovi questo plot"
+
+#: controllers/statistics_controller.php:248
+msgid "statistics_js_groupby_selector_date"
+msgstr "Raggruppa per: giorno"
+
+#: controllers/statistics_controller.php:251
+msgid "statistics_js_groupby_selector_month"
+msgstr "Raggruppa per: mese"
+
+#: controllers/statistics_controller.php:249
+msgid "statistics_js_groupby_selector_week"
+msgstr "Raggruppa per: settimana"
+
+#: controllers/statistics_controller.php:250
+msgid "statistics_js_groupby_selector_week_over_week"
+msgstr "Confronta per: settimana"
+
+#: controllers/statistics_controller.php:260
+msgid "statistics_js_plotselection_foundinrange"
+msgstr "%s trovato nei criteri"
+
+#: controllers/statistics_controller.php:270
+msgid "statistics_js_plotselection_options_addplot_name"
+msgstr "Aggiungi plot"
+
+#: controllers/statistics_controller.php:271
+msgid "statistics_js_plotselection_options_addplot_tooltip"
+msgstr "Aggiungi un altro plot a questo grafico"
+
+#: controllers/statistics_controller.php:261
+msgid "statistics_js_plotselection_options_count_name_checked"
+msgstr "Nascondi il conteggio totale"
+
+#: controllers/statistics_controller.php:262
+msgid "statistics_js_plotselection_options_count_name_unchecked"
+msgstr "Visualizza il conteggio totale"
+
+#: controllers/statistics_controller.php:263
+msgid "statistics_js_plotselection_options_count_tooltip"
+msgstr "Aggiungi al grafico il conteggio totale"
+
+#: controllers/statistics_controller.php:275
+msgid "statistics_js_plotselection_options_csv_name"
+msgstr "Visualizza dati (CSV)"
+
+#: controllers/statistics_controller.php:276
+msgid "statistics_js_plotselection_options_csv_tooltip"
+msgstr "Scarica questi dati in un file separato da virgole (CVS)"
+
+#: controllers/statistics_controller.php:267
+msgid "statistics_js_plotselection_options_events_addon_name_checked"
+msgstr "Nascondi %s eventi"
+
+#: controllers/statistics_controller.php:268
+msgid "statistics_js_plotselection_options_events_addon_name_unchecked"
+msgstr "Visualizza %s eventi"
+
+#: controllers/statistics_controller.php:269
+msgid "statistics_js_plotselection_options_events_addon_tooltip"
+msgstr "Sovrapponi date di rilascio dei componenti aggiuntivi ai grafici"
+
+#: controllers/statistics_controller.php:264
+msgid "statistics_js_plotselection_options_events_firefox_name_checked"
+msgstr "Nascondi eventi Firefox"
+
+#: controllers/statistics_controller.php:265
+msgid "statistics_js_plotselection_options_events_firefox_name_unchecked"
+msgstr "Visualizza eventi Firefox"
+
+#: controllers/statistics_controller.php:266
+msgid "statistics_js_plotselection_options_events_firefox_tooltip"
+msgstr "Sovrapponi date di rilascio di Firefox ai grafici"
+
+#: controllers/statistics_controller.php:272
+msgid "statistics_js_plotselection_options_resize_name_checked"
+msgstr "Contrai il grafico"
+
+#: controllers/statistics_controller.php:273
+msgid "statistics_js_plotselection_options_resize_name_unchecked"
+msgstr "Espandi il grafico"
+
+#: controllers/statistics_controller.php:274
+msgid "statistics_js_plotselection_options_resize_tooltip"
+msgstr "Ridimensiona il grafico"
+
+#: controllers/statistics_controller.php:254
+msgid "statistics_js_plotselection_selector_adu"
+msgstr "Utenti attivi per giorno"
+
+#: controllers/statistics_controller.php:256
+msgid "statistics_js_plotselection_selector_application"
+msgstr "Applicazione"
+
+#: controllers/statistics_controller.php:259
+msgid "statistics_js_plotselection_selector_custom"
+msgstr "Personalizzato"
+
+#: controllers/statistics_controller.php:253
+msgid "statistics_js_plotselection_selector_downloads"
+msgstr "Download"
+
+#: controllers/statistics_controller.php:258
+msgid "statistics_js_plotselection_selector_os"
+msgstr "Sistema operativo"
+
+#: controllers/statistics_controller.php:257
+msgid "statistics_js_plotselection_selector_status"
+msgstr "Stato del componente aggiuntivo"
+
+#: controllers/statistics_controller.php:252
+msgid "statistics_js_plotselection_selector_summary"
+msgstr "Sommario"
+
+#: controllers/statistics_controller.php:255
+msgid "statistics_js_plotselection_selector_version"
+msgstr "Versione del componente aggiuntivo"
+
+#: controllers/components/stats.php:398
+msgid "statistics_longnames_application"
+msgstr "Applicazione"
+
+#: controllers/components/stats.php:400
+msgid "statistics_longnames_os"
+msgstr "Sistema operativo"
+
+#: controllers/components/stats.php:399
+msgid "statistics_longnames_status"
+msgstr "Stato del componente aggiuntivo"
+
+#: controllers/components/stats.php:401
+msgid "statistics_longnames_unknown"
+msgstr "Sconosciuto"
+
+#: controllers/components/stats.php:397
+msgid "statistics_longnames_version"
+msgstr "Versione del componente aggiuntivo"
+
+#: views/statistics/addon.thtml:118
+msgid "statistics_notice_data_insufficient"
+msgstr "Non sono presenti dati sufficienti per visualizzare questo grafico. Riprovare più tardi."
+
+#: views/statistics/addon.thtml:130
+msgid "statistics_notice_data_none"
+msgstr "Non sono ancora presenti dati per questo componente aggiuntivo. Riprovare tra qualche giorno."
+
+#: views/statistics/addon.thtml:41
+msgid "statistics_notice_data_updating"
+msgstr "È in corso un ricalcolo delle statistiche. I dati recenti potrebbero non essere significativi in quanto gli script stanno aggiornando queste informazioni. Riprovare tra alcuni minuti."
+
+#: views/statistics/addon.thtml:136
+msgid "statistics_notice_disabled"
+msgstr "Il pannello statistiche in questo momento risulta disabilitato. Riprovare più tardi."
+
+#: views/statistics/addon.thtml:123
+msgid "statistics_notice_nojavascript"
+msgstr "JavaScript deve essere abilitato per visualizzare i grafici nel pannello statistiche."
+
+#: views/statistics/addon.thtml:44
+msgid "statistics_notice_settings_updated"
+msgstr "Le impostazioni sono state aggiornate"
+
+#: controllers/statistics_controller.php:60
+#: controllers/statistics_controller.php:71
+#: controllers/statistics_controller.php:74
+#: controllers/statistics_controller.php:240
+msgid "statistics_pagetitle"
+msgstr "Pannello statistiche"
+
+#: views/statistics/addon.thtml:99
+msgid "statistics_plot_legend_adu"
+msgstr "Utenti attivi per giorno"
+
+#: views/statistics/addon.thtml:95
+msgid "statistics_plot_legend_downloads"
+msgstr "Download per giorno"
+
+#: views/statistics/addon.thtml:107
+msgid "statistics_plot_options_zoomin_alt"
+msgstr "Zoom In"
+
+#: views/statistics/addon.thtml:106
+msgid "statistics_plot_options_zoomin_title"
+msgstr "Zoom in (un mese)"
+
+#: views/statistics/addon.thtml:110
+msgid "statistics_plot_options_zoomout_alt"
+msgstr "Zoom Out"
+
+#: views/statistics/addon.thtml:109
+msgid "statistics_plot_options_zoomout_title"
+msgstr "Zoom out (un mese)"
+
+#: controllers/statistics_controller.php:283
+#, php-format
+msgid "statistics_rss_description"
+msgstr "Sintesi quotidiana delle statistiche per %1$s"
+
+#: views/statistics/rss/summary.thtml:68
+msgid "statistics_rss_title_fulldate"
+msgstr "%A %e %b. %Y"
+
+#: views/statistics/rss/summary.thtml:68
+#, php-format
+msgid "statistics_rss_title_statsfordate"
+msgstr "Statistiche per %1$s"
+
+#: views/statistics/settings.thtml:49
+msgid "statistics_settings_access_description"
+msgstr "Come impostazione predefinita solo l'autore e Mozilla hanno accesso alle informazioni presenti nel pannello. È comunque possibile aprire l'accesso al pubblico in modo che qualsiasi persona possa visualizzare le informazioni relative a questo componente aggiuntivo."
+
+#: views/statistics/settings.thtml:48
+msgid "statistics_settings_access_heading"
+msgstr "Accesso al pannello"
+
+#: views/statistics/settings.thtml:51
+msgid "statistics_settings_access_private"
+msgstr "Privato"
+
+#: views/statistics/settings.thtml:51
+msgid "statistics_settings_access_private_description"
+msgstr "Solo tu e Mozilla potete visualizzare le statistiche di questo componente aggiuntivo"
+
+#: views/statistics/settings.thtml:52
+msgid "statistics_settings_access_public"
+msgstr "Pubblico"
+
+#: views/statistics/settings.thtml:52
+msgid "statistics_settings_access_public_description"
+msgstr "Chiunque può visualizzare le statistiche di questo componente aggiuntivo"
+
+#: views/statistics/addon.thtml:251
+msgid "statistics_settings_change_link"
+msgstr "Cambia impostazioni"
+
+#: views/statistics/addon.thtml:253
+msgid "statistics_settings_confidential"
+msgstr "Mantenere queste informazioni come confidenziali."
+
+#: views/statistics/addon.thtml:245
+msgid "statistics_settings_currently_private"
+msgstr "Questo pannello è attualmente <b>privato</b>."
+
+#: views/statistics/addon.thtml:241
+msgid "statistics_settings_currently_public"
+msgstr "Questo pannello è attualmente <b>pubblico</b>."
+
+#: views/statistics/addon.thtml:246
+msgid "statistics_settings_locked_alt"
+msgstr "Bloccato"
+
+#: views/statistics/settings.thtml:57
+msgid "statistics_settings_return_link"
+msgstr "Ritorna al pannello"
+
+#: views/statistics/settings.thtml:56
+msgid "statistics_settings_save_button"
+msgstr "Salva impostazioni"
+
+#: views/statistics/settings.thtml:46
+#, php-format
+msgid "statistics_settings_title"
+msgstr "Impostazioni pannello statistiche per %1$s"
+
+#: views/statistics/addon.thtml:242
+msgid "statistics_settings_unlocked_alt"
+msgstr "Sbloccato"
+
+#: controllers/components/stats.php:405
+msgid "statistics_shortnames_application"
+msgstr "App"
+
+#: controllers/components/stats.php:407
+msgid "statistics_shortnames_os"
+msgstr "SO"
+
+#: controllers/components/stats.php:406
+msgid "statistics_shortnames_status"
+msgstr "St"
+
+#: controllers/components/stats.php:408
+msgid "statistics_shortnames_unknown"
+msgstr "Sc"
+
+#: controllers/components/stats.php:404
+msgid "statistics_shortnames_version"
+msgstr "Ver"
+
+#: views/statistics/rss/summary.thtml:42
+#: views/statistics/addon.thtml:192
+msgid "statistics_summary_downloads_average"
+msgstr "Media download per giorno"
+
+#: views/statistics/rss/summary.thtml:39
+msgid "statistics_summary_downloads_heading"
+msgstr "Download"
+
+#: views/statistics/rss/summary.thtml:41
+#: views/statistics/addon.thtml:171
+msgid "statistics_summary_downloads_lastcount"
+msgstr "Totale ultimo giorno"
+
+#: views/statistics/rss/summary.thtml:43
+#: views/statistics/addon.thtml:199
+msgid "statistics_summary_downloads_lastweek"
+msgstr "Download negli ultimi 7 giorni"
+
+#: views/statistics/rss/summary.thtml:40
+#: views/statistics/addon.thtml:151
+msgid "statistics_summary_downloads_total"
+msgstr "Download complessivi"
+
+#: views/statistics/rss/summary.thtml:40
+#: views/statistics/addon.thtml:152
+#, php-format
+msgid "statistics_summary_downloads_total_sincedate"
+msgstr "Dal %1$s"
+
+#: views/statistics/rss/summary.thtml:50
+#: views/statistics/rss/summary.thtml:56
+#: views/statistics/addon.thtml:163
+#: views/statistics/addon.thtml:183
+msgid "statistics_summary_nodata"
+msgstr "Nessun dato presente"
+
+#: views/statistics/rss/summary.thtml:60
+#: views/statistics/addon.thtml:195
+msgid "statistics_summary_updatepings_average"
+msgstr "Numero medio di utenti attivi per giorno"
+
+#: views/statistics/rss/summary.thtml:52
+#: views/statistics/addon.thtml:177
+msgid "statistics_summary_updatepings_changefromprevious"
+msgstr "Cambiamento dal conteggio precedente"
+
+#: views/statistics/rss/summary.thtml:54
+#: views/statistics/addon.thtml:181
+#, php-format
+msgid "statistics_summary_updatepings_changefromprevious_ondate"
+msgstr "%1$s il %2$s"
+
+#: views/statistics/rss/summary.thtml:45
+msgid "statistics_summary_updatepings_heading"
+msgstr "Utenti attivi per giorno"
+
+#: views/statistics/rss/summary.thtml:46
+#: views/statistics/addon.thtml:157
+msgid "statistics_summary_updatepings_total"
+msgstr "Utenti attivi per giorno"
+
+#: views/statistics/rss/summary.thtml:48
+#: views/statistics/addon.thtml:161
+#, php-format
+msgid "statistics_summary_updatepings_total_ondate"
+msgstr "Il %1$s"
+
+#: views/statistics/rss/summary.thtml:61
+#: views/statistics/addon.thtml:203
+msgid "statistics_summary_updatepings_weekly_average"
+msgstr "Media giornaliera degli utenti attivi in questa settimana"
+
+#. %s is a percentage, like '+22.33%'. It sits next to another number, so
+#. the implied meaning is 'percentage change' from the previous stat point.
+#: views/statistics/rss/summary.thtml:62
+#: views/statistics/addon.thtml:205
+msgid "statistics_summary_updatepings_weekly_change"
+msgstr "%s dalla settimana scorsa"
+
+#: views/statistics/addon.thtml:65
+#: controllers/statistics_controller.php:184
+#: controllers/statistics_controller.php:282
+#, php-format
+msgid "statistics_title_addon_stats"
+msgstr "Statistiche %1$s"
+
+#: views/addons/themes_landing.thtml:113
+msgid "themes_landing_all_themes"
+msgstr "Tutti i temi"
+
+#: views/addons/themes_landing.thtml:109
+msgid "themes_landing_browse_themes"
+msgstr "Esplora temi"
+
+#: views/users/edit.thtml:185
+msgid "user_change_email"
+msgstr "Cambia indirizzo e-mail"
+
+#: views/users/edit.thtml:169
+msgid "user_change_password"
+msgstr "Modifica password"
+
+#: views/users/edit.thtml:96
+msgid "user_change_password_or_email"
+msgstr "Cambia password o e-mail"
+
+#: controllers/users_controller.php:197
+msgid "user_confirmationcode_resent"
+msgstr "Il codice di conferma è stato reinviato"
+
+#. %1 is the email address, %2 is the URL of the user registration page
+#: views/users/delete.thtml:51
+msgid "user_del_account_deleted"
+msgstr "L'account %1$s è stato eliminato. Per tornare a visitarci in futuro, è possibile registrarsi nuovamente nella <a href=\"%2$s\">pagina di registrazione</a>."
+
+#: views/users/delete.thtml:102
+msgid "user_del_community_sad"
+msgstr "La community di Mozilla Add-ons è triste per il tuo abbandono."
+
+#: views/users/delete.thtml:123
+msgid "user_del_confirm_password"
+msgstr "Conferma password"
+
+#: views/users/delete.thtml:134
+msgid "user_del_deletenow"
+msgstr "Elimina ora il mio account utente"
+
+#. %1 is the URL of the user's info page
+#: views/users/delete.thtml:64
+msgid "user_del_error_addons"
+msgstr "Non è possibile eliminare l'account nel caso in cui si risulti come <a href=\"%1$s\">autore</a> di un qualsiasi componente aggiuntivo. Per eliminare l'account, chiedere a un altro componente del team di sviluppo di rimuovere l'account dall'elenco degli autori. Una volta completata questa operazione, sarà possibile procedere con l'eliminazione dell'account in questa sezione."
+
+#. %1 is a link to the amo-editors mailing list
+#: views/users/delete.thtml:71
+msgid "user_del_error_addons_more_questions"
+msgstr "In caso di dubbi o domande, contattare %1$s per assistenza."
+
+#: views/users/delete.thtml:78
+msgid "user_del_error_checkbox"
+msgstr "È necessario selezionare la casella \"Ho compreso…\" per poter eliminare l'account."
+
+#: views/users/delete.thtml:84
+msgid "user_del_error_password"
+msgstr "Inserire correttamente la password per procedere."
+
+#. %1 is a link to the amo-admins mailing list
+#: views/users/delete.thtml:91
+msgid "user_del_error_unknown"
+msgstr "Si è verificato un errore sconosciuto durante l'eliminazione dell'account. Contattare %1$s spiegando il problema, in questo modo potremo procedere alla rimozione dell'account. Ci scusiamo per l'inconveniente."
+
+#: views/users/delete.thtml:110
+msgid "user_del_header_confirm_deletion"
+msgstr "Conferma eliminazione account"
+
+#. %1 is the user's email address
+#: views/users/delete.thtml:100
+msgid "user_del_header_delete_account"
+msgstr "Elimina account utente %1$s"
+
+#: views/users/delete.thtml:50
+msgid "user_del_header_farewell"
+msgstr "Arrivederci"
+
+#: views/users/delete.thtml:115
+msgid "user_del_nologin"
+msgstr "da questo momento non sarà più possibile fare il login su Mozilla Add-ons"
+
+#: views/users/delete.thtml:112
+msgid "user_del_permanently_removed_means"
+msgstr "Facendo clic su \"elimina\" l'account verrà <strong>eliminato definitivamente</strong>. Questo significa che:"
+
+#: views/users/delete.thtml:116
+msgid "user_del_reviews_anonymized"
+msgstr "le recensioni e i voti non verranno eliminati, ma non saranno più associati a questo account"
+
+#. %1 is a link to the amo-editors mailing list
+#: views/users/delete.thtml:104
+msgid "user_del_specific_problem_editors"
+msgstr "Se si tratta di un problema specifico per cui possiamo essere d'aiuto, non eliminare l'account ma contattaci via %1$s e cercheremo di fornire assistenza nel migliore dei modi per risolverlo."
+
+#: views/users/delete.thtml:130
+msgid "user_del_understand_permanent"
+msgstr "Ho compreso che questo passaggio non potrà essere annullato."
+
+#: views/helpers/addons_html.php:192
+msgid "user_deleted_nickname"
+msgstr "Utente eliminato"
+
+#. %1 is the new email address
+#: views/users/edit.thtml:71
+msgid "user_edit_confirm_email_sent"
+msgstr "Una e-mail è stata inviata a %1$s per confermare il nuovo indirizzo e-mail. Per rendere effettiva la modifica è necessario fare clic sul link contenuto in questa mail. Fino a quel momento sarò possibile continuare ad accedere con l'indirizzo e-mail corrente."
+
+#: views/users/edit.thtml:201
+msgid "user_edit_delete_user"
+msgstr "Elimina account utente"
+
+#. This contains the email sent to users when they signed up for a new
+#. account:
+#. %1 is the confirmation URL, %2 is the current app
+#: views/users/email/confirm_plain.thtml:6
+#, php-format
+msgid "user_email_confirm_account_nopass"
+msgstr ""
+"Benvenuto in %2$s Add-ons.\n"
+"\n"
+"Per potere utilizzare il tuo nuovo account devi prima attivarlo. Ciò garantisce che l'indirizzo e-mail utilizzato sia valido e appartenga davvero a te.\n"
+"Per attivare il tuo nuovo account fai clic sul link successivo oppure copia e incolla il link completo nella barra degli indirizzi del tuo browser:\n"
+"\n"
+"%1$s\n"
+"\n"
+"Dopo aver attivato il tuo account potrai tranquillamente cestinare questa e-mail.\n"
+"\n"
+"Grazie per aver scelto %2$s Add-ons\n"
+"-- Lo staff di %2$s Add-ons"
+
+#. %1 is the confirmation url, %2 is the application name
+#: views/users/email/emailchange_plain.thtml:5
+msgid "user_email_confirm_emailchange"
+msgstr ""
+"Hai richiesto un cambio di indirizzo e-mail su %2$s Add-ons.\n"
+"\n"
+"Per confermare il nuovo indirizzo fai clic sul link seguente oppure copia e incolla l'intera stringa nella barra degli indirizzi del browser:\n"
+"\n"
+"%1$s\n"
+"\n"
+"Hai 48 ore per confermare il nuovo indirizzo e-mail. Se non desideri modificare l'indirizzo, puoi semplicemente ignorare questo messaggio.\n"
+"\n"
+"Grazie.\n"
+"-- Lo staff di %2$s Add-ons"
+
+#: controllers/users_controller.php:168
+#, php-format
+msgid "user_email_confirm_subject"
+msgstr "Grazie per aver scelto %s Add-ons"
+
+#. This is the password reset email
+#. %1 is the pw reset URL, %2 is the application
+#: views/users/email/pwreset_plain.thtml:5
+#, php-format
+msgid "user_email_pwreset"
+msgstr ""
+"%2$s Add-ons reimpostazione della password\n"
+"\n"
+"Abbiamo ricevuto la richiesta di reimpostare la password per questo account su addons.mozilla.org. Per modificare la password fai clic sul link successivo oppure copia e incolla il link completo nella barra degli indirizzi del tuo browser:\n"
+"\n"
+"%1$s\n"
+"\n"
+"Se non hai richiesto questa e-mail non devi fare nulla.\n"
+"\n"
+"Grazie,\n"
+"-- Lo staff di %2$s Add-ons"
+
+#: controllers/users_controller.php:245
+#, php-format
+msgid "user_email_pwreset_subject"
+msgstr "Reimposta la tua password per %s Add-ons"
+
+#: views/users/emailchange.thtml:50
+msgid "user_emailchange_error"
+msgstr "Errore"
+
+#. %1 is the application name
+#: controllers/users_controller.php:533
+msgid "user_emailchange_subject"
+msgstr "Confermare il cambio di indirizzo e-mail per %1$s Add-ons"
+
+#: views/users/emailchange.thtml:48
+msgid "user_emailchange_success"
+msgstr "Operazione completata"
+
+#. %1 is the new email address
+#: views/users/emailchange.thtml:49
+msgid "user_emailchange_successful_description"
+msgstr "Il tuo indirizzo e-mail è stato modificato con successo. Da questo momento, utilizza %1$s per accedere al sito."
+
+#: views/users/edit.thtml:134
+#: views/admin/users_edit.thtml:111
+msgid "user_form_bio"
+msgstr "Chi sono"
+
+#: views/users/edit.thtml:135
+#: views/admin/users_edit.thtml:112
+msgid "user_form_bio_description"
+msgstr "Presentati alla comunità! Questo testo apparirà nella sezione pubblica della pagina di informazioni sul tuo utente. Le interruzioni di linea verranno mantenute, non è consentito l'uso di HTML."
+
+#: views/users/pwreset.thtml:77
+#: views/users/register.thtml:73
+#: views/users/edit.thtml:181
+msgid "user_form_confirmpassword"
+msgstr "Conferma password"
+
+#: views/users/edit.thtml:145
+msgid "user_form_display_collections"
+msgstr "Visualizza nel mio profilo utente le raccolte che ho creato"
+
+#: views/users/edit.thtml:149
+msgid "user_form_display_collections_fav"
+msgstr "Visualizza nel mio profilo utente le raccolte preferite"
+
+#: views/users/edit.thtml:86
+#, php-format
+msgid "user_form_editprofile"
+msgstr "Modifica il profilo utente di %s"
+
+#: views/users/pwreset.thtml:52
+#: views/users/login.thtml:81
+#: views/users/register.thtml:63
+#: views/users/edit.thtml:187
+msgid "user_form_email"
+msgstr "Indirizzo e-mail"
+
+#: views/users/register.thtml:78
+#: views/users/edit.thtml:103
+#: views/admin/users_edit.thtml:76
+msgid "user_form_firstname"
+msgstr "Nome"
+
+#: views/users/register.thtml:94
+#: views/users/edit.thtml:119
+#: views/admin/users_edit.thtml:91
+msgid "user_form_hideemail"
+msgstr "Nascondi indirizzo e-mail"
+
+#: views/users/register.thtml:98
+#: views/users/edit.thtml:123
+#: views/admin/users_edit.thtml:99
+msgid "user_form_homepage"
+msgstr "URL sito web"
+
+#: views/users/register.thtml:84
+#: views/users/edit.thtml:109
+#: views/admin/users_edit.thtml:81
+msgid "user_form_lastname"
+msgstr "Cognome"
+
+#: controllers/users_controller.php:333
+msgid "user_form_login"
+msgstr "Accesso utente"
+
+#: views/users/pwreset.thtml:72
+#: views/users/edit.thtml:176
+msgid "user_form_newpassword"
+msgstr "Nuova password"
+
+#: views/users/register.thtml:89
+#: views/users/edit.thtml:114
+#: views/admin/users_edit.thtml:86
+msgid "user_form_nickname"
+msgstr "Nickname"
+
+#: views/users/edit.thtml:171
+msgid "user_form_oldpassword"
+msgstr "Vecchia password"
+
+#: views/users/edit.thtml:97
+#: views/users/edit.thtml:200
+msgid "user_form_otheractions"
+msgstr "Altre azioni"
+
+#: views/users/login.thtml:85
+#: views/users/register.thtml:68
+msgid "user_form_password"
+msgstr "Password"
+
+#: controllers/users_controller.php:93
+msgid "user_form_registration"
+msgstr "Registrazione nuovo utente"
+
+#: views/users/login.thtml:90
+msgid "user_form_remember_me"
+msgstr "Ricordami su questo computer"
+
+#: views/admin/users_edit.thtml:95
+msgid "user_form_showsandbox"
+msgstr "Visualizza sandbox?"
+
+#: views/users/edit.thtml:205
+msgid "user_form_submit_edit"
+msgstr "Salva"
+
+#: views/users/login.thtml:93
+msgid "user_form_submit_login"
+msgstr "Accedi"
+
+#: views/users/register.thtml:113
+msgid "user_form_submit_register"
+msgstr "Registra"
+
+#: views/users/info.thtml:75
+#, php-format
+msgid "user_info_usersince"
+msgstr "Utente di %s Add-ons dal"
+
+#: views/users/login.thtml:102
+msgid "user_login_register_link"
+msgstr "Crea un nuovo account utente"
+
+#: views/users/edit.thtml:160
+msgid "user_notifications_item_compat"
+msgstr "Compatibilità componenti aggiuntivi (fortemente consigliato)"
+
+#: views/users/edit.thtml:161
+msgid "user_notifications_item_events"
+msgstr "Eventi e concorsi in programma"
+
+#: views/users/edit.thtml:156
+msgid "user_notifications_none_available"
+msgstr "Al momento non sono presenti notifiche da configurare."
+
+#: views/users/edit.thtml:158
+msgid "user_notifications_select_topics"
+msgstr "Mozilla può inviarti periodicamente delle e-mail per segnalare nuove versioni o eventi legati ai componenti aggiuntivi. Scegli gli argomenti a cui sei interessato:"
+
+#: views/users/edit.thtml:164
+msgid "user_notifications_specific_contact"
+msgstr "Mozilla si riserva il diritto di contattarti personalmente per problemi legati ai componenti aggiuntivi che hai realizzato e che sono ospitati su questo sito."
+
+#: controllers/users_controller.php:543
+msgid "user_profile_edit_error"
+msgstr "Le modifiche effettuate contengono degli errori. Correggili e invia di nuovo…"
+
+#: controllers/users_controller.php:540
+msgid "user_profile_saved"
+msgstr "Profilo aggiornato."
+
+#: views/users/pwreset.thtml:65
+#, php-format
+msgid "user_pwreset_for_email"
+msgstr "Reimposta la password %s"
+
+#: controllers/users_controller.php:226
+msgid "user_pwreset_header"
+msgstr "Reimposta la password"
+
+#: views/users/login.thtml:103
+msgid "user_pwreset_link"
+msgstr "Password dimenticata?"
+
+#: controllers/users_controller.php:248
+msgid "user_pwreset_link_sent"
+msgstr "Il link per reimpostare la password è stato inviato al tuo indirizzo e-mail."
+
+#: controllers/users_controller.php:304
+msgid "user_pwreset_okay"
+msgstr "Password reimpostata con successo."
+
+#: views/users/pwreset.thtml:82
+msgid "user_pwreset_submit_changepw"
+msgstr "Salva modifica password"
+
+#: views/users/pwreset.thtml:57
+msgid "user_pwreset_submit_sendlink"
+msgstr "Invia il link per reimpostare la password"
+
+#: views/users/register_complete.thtml:51
+#, php-format
+msgid "user_register_amo_link"
+msgstr "%s Add-ons"
+
+#. %1 is the user's email address, %2 is the current app
+#: views/users/activatefirst.thtml:49
+#, php-format
+msgid "user_register_click_confirm_link"
+msgstr "Un link per attivare il tuo account è stato inviato al tuo indirizzo e-mail %1$s. Fai clic su questo link per accedere a %2$s Add-ons."
+
+#. %1 is the user's email address
+#: views/users/register_complete.thtml:49
+#, php-format
+msgid "user_register_confirm_email_sent"
+msgstr "È stata inviata una e-mail al tuo indirizzo %1$s per attivare il tuo account. Per poter accedere è necessario fare clic sul link contenuto in questo messaggio e-mail."
+
+#: views/users/activatefirst.thtml:51
+msgid "user_register_confirmation_link_text"
+msgstr "reinviare l'e-mail di conferma"
+
+#: views/users/register_complete.thtml:47
+msgid "user_register_congratulations"
+msgstr "Complimenti, il tuo account utente è stato creato con successo."
+
+#: views/users/register.thtml:50
+msgid "user_register_details"
+msgstr "<p>La registrazione su AMO <strong>non è obbligatoria</strong> per scaricare e installare i componenti aggiuntivi presenti nella sezione pubblica.</p><p>È necessario registrarsi solo se:</p><ul><li>vuoi inserire delle recensioni</li><li>sei uno sviluppatore e vuoi usare AMO per ospitare il tuo componente aggiuntivo</li></ul><p> Dopo aver completato la registrazione, riceverai una mail di conferma all'indirizzo fornito: segui le istruzioni presenti nel messaggio per concludere la creazione dell'account.</p><p>Per ulteriori informazioni sono disponibili le <a href='%1$s' title='Note legali'>Note legali</a> e l'<a href='%2$s' title='Informativa sulla privacy'>Informativa sulla privacy</a>.</p>"
+
+#. %1 is the link to the "resend confirmation code" page
+#: views/users/activatefirst.thtml:51
+#, php-format
+msgid "user_register_resend_confirmation_link"
+msgstr "Se non hai ricevuto una e-mail di conferma, verifica che il messaggio non sia stato contrassegnato come \"posta indesiderata\" o \"spam\". Se necessario possiamo %1$s all'indirizzo indicato."
+
+#. %1 is the link to the Mozilla Add-ons front page
+#: views/users/register_complete.thtml:51
+#, php-format
+msgid "user_register_welcome"
+msgstr "Grazie per esserti registrato e benvenuto in %1$s"
+
+#: views/users/register.thtml:49
+msgid "user_register_welcome_header"
+msgstr "Benvenuto su addons.mozilla.org (AMO)!"
+
+#: views/users/register.thtml:81
+#: views/users/edit.thtml:106
+msgid "user_required_firstlast_or_nickname"
+msgstr "È necessario inserire il nome, il cognome oppure il nick."
+
+#: views/users/edit.thtml:94
+#: views/users/edit.thtml:142
+msgid "user_tab_collections"
+msgstr "Raccolte"
+
+#: views/users/edit.thtml:95
+#: views/users/edit.thtml:154
+msgid "user_tab_notifications"
+msgstr "Notifiche"
+
+#: views/users/edit.thtml:93
+#: views/users/edit.thtml:101
+msgid "user_tab_profile"
+msgstr "Profilo utente"
+
+#: controllers/users_controller.php:209
+msgid "user_verified_okay"
+msgstr "Verificato con successo"
+
+#: controllers/users_controller.php:723
+msgid "users_delete_pagetitle"
+msgstr "Eliminazione account utente"
+
+#: controllers/users_controller.php:414
+msgid "users_edit_pagetitle"
+msgstr "Modifica account utente"
+
+#: views/users/info.thtml:71
+msgid "users_info_aboutme"
+msgstr "Chi sono"
+
+#: views/users/info.thtml:96
+#, php-format
+msgid "users_info_addons_by_user"
+msgstr "Componenti aggiuntivi di %1$s"
+
+#: views/users/info.thtml:51
+msgid "users_info_author_name"
+msgstr "Nome"
+
+#: views/users/info.thtml:48
+msgid "users_info_author_profile"
+msgstr "Profilo autore"
+
+#. %s is the user name
+#: views/users/info.thtml:137
+msgid "users_info_collections_by_user"
+msgstr "Raccolte di %s"
+
+#: views/users/info.thtml:66
+msgid "users_info_email"
+msgstr "Indirizzo e-mail"
+
+#: views/users/info.thtml:155
+msgid "users_info_fav_collections_by_user"
+msgstr "Raccolte preferite"
+
+#: views/users/info.thtml:61
+msgid "users_info_homepage"
+msgstr "Sito web"
+
+#: views/users/info.thtml:56
+msgid "users_info_nickname"
+msgstr "Nickname"
+
+#: controllers/users_controller.php:707
+#, php-format
+msgid "users_info_pagetitle"
+msgstr "Informazioni utente per %1$s"
+
+#. %1 is the user's name
+#: views/users/info.thtml:116
+msgid "users_info_reviews_by_user"
+msgstr "Recensioni di %s"
+
+#: controllers/users_controller.php:330
+#: controllers/users_controller.php:332
+msgid "users_login_pagetitle"
+msgstr "Accesso utente"
+
+#. %1 is the link to the sandbox/policy explanation page
+#. This message is for a specific add-on not found
+#: views/users/login.thtml:53
+#, php-format
+msgid "users_login_sandbox_display_warning"
+msgstr "Il componente aggiuntivo che stai cercando al momento si trova nella sandbox. Se già possiedi un account su Mozilla Add-ons, effettua l'accesso oppure <a href=\"%1$s\">leggi ulteriori informazioni sulla sandbox.</a>"
+
+#. %1 is the link to the sandbox/policy explanation page
+#. This message is for any given sandbox-related page not found
+#: views/users/login.thtml:56
+#, php-format
+msgid "users_login_sandbox_page_warning"
+msgstr "La pagina che stai cercando fa parte della sandbox. Se già possiedi un account su Mozilla Add-ons, effettua l'accesso oppure <a href=\"%1$s\">leggi ulteriori informazioni sulla sandbox.</a>"
+
+#: controllers/users_controller.php:223
+#: controllers/users_controller.php:225
+msgid "users_pwreset_pagetitle"
+msgstr "Reimposta la password dell'utente"
+
+#: controllers/users_controller.php:90
+#: controllers/users_controller.php:92
+msgid "users_register_pagetitle"
+msgstr "Registrazione nuovo utente"
+
+#. %1$s is an addon name, like <a>Firebug</a>
+#. %2$s is a version number, like <a>1.2</a>
+#: views/versions/license.thtml:52
+msgid "versions_license_header_source"
+msgstr "Licenza del codice sorgente per %1$s %2$s"
+
+#: views/addons/category_landing.thtml:147
+msgid "view_recently_added"
+msgstr "Visualizza elementi aggiunti di recente"
+
+#: views/addons/category_landing.thtml:161
+msgid "view_top_downloads"
+msgstr "Visualizza i più scaricati"
+
+#: views/addons/category_landing.thtml:175
+msgid "view_top_rated"
+msgstr "Visualizza i più votati"
+
+#~ msgid "addon_slider_tooltip_next"
+#~ msgstr "Componente aggiuntivo successivo"
+#~ msgid "addon_slider_tooltip_previous"
+#~ msgstr "Componente aggiuntivo precedente"
+#~ msgid "addons_display_version_history"
+#~ msgstr "Cronologia completa delle versioni"
+#~ msgid "addons_home_newest_header"
+#~ msgstr "Nuovi:"
+#~ msgid "addons_home_popular_header"
+#~ msgstr "Più popolari:"
+#~ msgid "addons_home_recommended_header"
+#~ msgstr "Consigliati da noi:"
+#~ msgid "addons_home_updated_header"
+#~ msgstr "Aggiornati di recente:"
+#~ msgid "addons_home_view_all"
+#~ msgstr "Visualizza tutti"
+#~ msgid "category_extra_allrecommended"
+#~ msgstr "Visualizza tutti i componenti aggiuntivi consigliati"
+#~ msgid "category_extra_highestrated"
+#~ msgstr "Ordina per voto"
+#~ msgid "category_extra_lastupdated"
+#~ msgstr "Ordina per aggiornamento"
+#~ msgid "category_extra_mostpopular"
+#~ msgstr "Ordina per popolarità"
+#~ msgid "collections_detail_js_loading"
+#~ msgstr "Caricamento in corso"
+#~ msgid "collections_detail_more_info"
+#~ msgstr "Visualizza altre informazioni"
+#~ msgid "devcp_additem_firefox_notice"
+#~ msgstr ""
+#~ "Questa versione del componente aggiuntivo non dichiara la propria "
+#~ "compatibilità con Firefox %1$s. Mozilla ha in programma di rilasciare la "
+#~ "prossima versione in tempi brevi, consigliamo di verificare il componente "
+#~ "aggiuntivo con la nuova versione e aggiornarne la compatibilità. "
+#~ "Ulteriori informazioni su questo argomento sono disponibili <a href=\"%2$s"
+#~ "\">qui</a>. Questo è solo un avviso e sarà comunque possibile proseguire "
+#~ "con l'inserimento di questa versione in addons.mozilla.org."
+#~ msgid "devcp_addon_disabled_successfully"
+#~ msgstr "Componente aggiuntivo disattivato con successo"
+#~ msgid "devcp_addon_edit_pagetitle"
+#~ msgstr "Modifica componente aggiuntivo"
+#~ msgid "devcp_addon_enabled_successfully"
+#~ msgstr "Componente aggiuntivo attivato con successo"
+#~ msgid "devcp_addon_field_description_displaytitle"
+#~ msgstr "Descrizione"
+#~ msgid "devcp_addon_field_eula_displaytitle"
+#~ msgstr "EULA"
+#~ msgid "devcp_addon_field_homepage_displaytitle"
+#~ msgstr "Sito web"
+#~ msgid "devcp_addon_field_name_displaytitle"
+#~ msgstr "Nome"
+#~ msgid "devcp_addon_field_privacy_displaytitle"
+#~ msgstr "Informativa sulla privacy"
+#~ msgid "devcp_addon_field_summary_displaytitle"
+#~ msgstr "Riepilogo"
+#~ msgid "devcp_addon_field_supportemail_displaytitle"
+#~ msgstr "E-mail per il supporto"
+#~ msgid "devcp_addon_field_supporturl_displaytitle"
+#~ msgstr "URL per il supporto"
+#~ msgid "devcp_addon_field_versionnotes_displaytitle"
+#~ msgstr "Note sulla versione"
+#~ msgid "devcp_addon_nominate_pagetitle"
+#~ msgstr "Segnala il componente aggiuntivo"
+#~ msgid "devcp_addon_nominated_successfully"
+#~ msgstr "Componente aggiuntivo segnalato con successo"
+#~ msgid "devcp_addon_status_criteria_review"
+#~ msgstr ""
+#~ "Diverse recensioni di utenti (possono essere anche recensioni esterne)."
+#~ msgid "devcp_addon_submission_makechanges"
+#~ msgstr ""
+#~ "Visita la pagina %1$s per modificare le tue estensioni, oppure %2$s per "
+#~ "tornare agli strumenti per sviluppatori."
+#~ msgid "devcp_addon_submission_makechanges_devcp_link"
+#~ msgstr "fai clic qui"
+#~ msgid "devcp_addon_submission_makechanges_link"
+#~ msgstr "modifica componente aggiuntivo"
+#~ msgid "devcp_addon_submission_pending"
+#~ msgstr ""
+#~ "Questa versione è stata inserita nella sandbox in attesa di verifiche da "
+#~ "parte dei tester e di un revisore di Mozilla Add-ons. Riceverai una "
+#~ "notifica via e-mail non appena ne verrà ultimato il controllo."
+#~ msgid "devcp_addon_submission_sandbox_readmore"
+#~ msgstr ""
+#~ "Puoi ottenere ulteriori informazioni sul sistema di revisione collegato "
+#~ "alla Sandbox leggendo %s."
+#~ msgid "devcp_addon_submission_sandbox_readmore_link"
+#~ msgstr "questa pagina"
+#~ msgid "devcp_addon_submission_sandboxed"
+#~ msgstr ""
+#~ "Questa versione è stata inserita nella sandbox e l'utilizzo è consigliato "
+#~ "solo ad utenti esperti. Affinché l'estensione venga pubblicata sul sito "
+#~ "ufficiale, è necessario %s il proprio componente aggiuntivo e attendere "
+#~ "l'esito del processo di revisione."
+#~ msgid "devcp_addon_submission_sandboxed_nominate_link"
+#~ msgstr "segnalare"
+#~ msgid "devcp_addon_submission_success"
+#~ msgstr ""
+#~ "L'inserimento del componente aggiuntivo è stato completato con successo."
+#~ msgid "devcp_addon_submission_trusted_public"
+#~ msgstr ""
+#~ "Dal momento che il componente aggiuntivo è considerato affidabile, questa "
+#~ "versione è stata automaticamente approvata e inserita nella sezione "
+#~ "pubblica."
+#~ msgid "devcp_addon_submit_pagetitle"
+#~ msgstr "Carica un nuovo componente aggiuntivo"
+#~ msgid "devcp_addon_updated_successfully"
+#~ msgstr "Componente aggiuntivo aggiornato con successo"
+#~ msgid "devcp_addon_upload_preview"
+#~ msgstr ""
+#~ "È consigliabile %s per accrescere l'interesse nei confronti del tuo "
+#~ "componente aggiuntivo"
+#~ msgid "devcp_addon_upload_preview_link"
+#~ msgstr "caricare un'anteprima"
+#~ msgid "devcp_author_lookup_none_found"
+#~ msgstr "Impossibile trovare l'autore [%s]"
+#~ msgid "devcp_author_lookup_remove"
+#~ msgstr "Rimuovi"
+#~ msgid "devcp_button_cancel"
+#~ msgstr "Annulla"
+#~ msgid "devcp_button_cancel_confirm"
+#~ msgstr "Vuoi annullare l'inserimento?"
+#~ msgid "devcp_button_next"
+#~ msgstr "Successivo"
+#~ msgid "devcp_change_addontype"
+#~ msgstr "Modifica tipologia del componente aggiuntivo:"
+#~ msgid "devcp_comments_updated"
+#~ msgstr "I commenti dello sviluppatore sono stati aggiornati."
+#~ msgid "devcp_details_addpreview_link"
+#~ msgstr "Aggiungi anteprima"
+#~ msgid "devcp_details_author"
+#~ msgstr "Autore"
+#~ msgid "devcp_details_authors"
+#~ msgstr "Autori"
+#~ msgid "devcp_details_authors_none"
+#~ msgstr "Non presente"
+#~ msgid "devcp_details_categories"
+#~ msgstr "Categorie"
+#~ msgid "devcp_details_category"
+#~ msgstr "Categoria"
+#~ msgid "devcp_details_description"
+#~ msgstr "Descrizione"
+#~ msgid "devcp_details_disabled"
+#~ msgstr "Disattivato"
+#~ msgid "devcp_details_guid"
+#~ msgstr "GUID"
+#~ msgid "devcp_details_header_details"
+#~ msgstr "Dettagli"
+#~ msgid "devcp_details_header_devcomments"
+#~ msgstr "Commenti dello sviluppatore"
+#~ msgid "devcp_details_header_previews"
+#~ msgstr "Anteprime"
+#~ msgid "devcp_details_header_versions"
+#~ msgstr "Versioni"
+#~ msgid "devcp_details_homepage"
+#~ msgstr "Sito web"
+#~ msgid "devcp_details_homepage_none"
+#~ msgstr "Non presente"
+#~ msgid "devcp_details_preview_nocaption"
+#~ msgstr "Descrizione non presente"
+#~ msgid "devcp_details_previews_nonefound"
+#~ msgstr "Anteprime non presenti."
+#~ msgid "devcp_details_submit_update"
+#~ msgstr "Aggiorna"
+#~ msgid "devcp_details_supportemail"
+#~ msgstr "E-mail per il supporto"
+#~ msgid "devcp_details_supportemail_none"
+#~ msgstr "Lo sviluppatore non ha fornito una e-mail per il supporto."
+#~ msgid "devcp_details_supporturl"
+#~ msgstr "URL per il supporto"
+#~ msgid "devcp_details_supporturl_none"
+#~ msgstr "Lo sviluppatore non ha fornito una URL per il supporto."
+#~ msgid "devcp_details_trusted"
+#~ msgstr "Affidabile"
+#~ msgid "devcp_details_versions_none_found"
+#~ msgstr "Nessuna versione disponibile."
+#~ msgid "devcp_disable_cancel"
+#~ msgstr "Annulla e torna indietro"
+#~ msgid "devcp_disable_disable_button"
+#~ msgstr "Sì, disabilita"
+#~ msgid "devcp_disable_disable_confirm"
+#~ msgstr "Disabilitare questo componente aggiuntivo?"
+#~ msgid "devcp_disable_disable_description"
+#~ msgstr ""
+#~ "Un componente aggiuntivo disabilitato non verrà mostrato nei risultati "
+#~ "delle ricerche e negli elenchi. Non sarà possibile scaricarlo dal sito e "
+#~ "non verrà segnalato dagli aggiornamenti automatici dei software client. A "
+#~ "tutti gli effetti il componente aggiuntivo verrà eliminato, anche se in "
+#~ "realtà sarà possibile ritornare in questa sezione e riabilitarlo in caso "
+#~ "di necessità."
+#~ msgid "devcp_disable_disable_title"
+#~ msgstr "Disabilita %s"
+#~ msgid "devcp_disable_enable_button"
+#~ msgstr "Sì, abilita"
+#~ msgid "devcp_disable_enable_confirm"
+#~ msgstr "Abilitare questo componente aggiuntivo?"
+#~ msgid "devcp_disable_enable_description"
+#~ msgstr ""
+#~ "Questo componente aggiuntivo, una volta abilitato, verrà nuovamente "
+#~ "mostrato nei risultati delle ricerche e negli elenchi. Sarà inoltre "
+#~ "possibile scaricarlo dal sito e verrà segnalato dagli aggiornamenti "
+#~ "automatici dei software client."
+#~ msgid "devcp_disable_enable_title"
+#~ msgstr "Abilita %s"
+#~ msgid "devcp_edit_author_add"
+#~ msgstr "Aggiungi autore"
+#~ msgid "devcp_edit_author_email"
+#~ msgstr "Indirizzo e-mail dell'autore"
+#~ msgid "devcp_edit_author_remove"
+#~ msgstr "Rimuovi"
+#~ msgid "devcp_edit_error_categories_unavailable"
+#~ msgstr ""
+#~ "Nessuna categoria disponibile per questo tipo di componente aggiuntivo."
+#~ msgid "devcp_edit_file_error_incomplete"
+#~ msgstr "Trasferimento non completato"
+#~ msgid "devcp_edit_file_error_no"
+#~ msgstr "Nessun file caricato"
+#~ msgid "devcp_edit_file_error_size"
+#~ msgstr "Il file eccede la dimensione massima per l'upload"
+#~ msgid "devcp_edit_header_authors"
+#~ msgstr "Autori"
+#~ msgid "devcp_edit_icon_add_link"
+#~ msgstr "Aggiungi icona"
+#~ msgid "devcp_edit_icon_change_link"
+#~ msgstr "Modifica icona"
+#~ msgid "devcp_edit_label_allow_viewsource"
+#~ msgstr "Permetti agli utenti di visualizzare i sorgenti online"
+#~ msgid "devcp_edit_label_categories"
+#~ msgstr "Categorie"
+#~ msgid "devcp_edit_label_defaultlocale"
+#~ msgstr "Locale predefinito"
+#~ msgid "devcp_edit_label_icon_delete"
+#~ msgstr "Elimina solo l'icona esistente"
+#~ msgid "devcp_edit_label_icon_new"
+#~ msgstr "Nuova icona"
+#~ msgid "devcp_edit_label_info"
+#~ msgstr "Icona"
+#~ msgid "devcp_edit_locale_disambiguation_explanation"
+#~ msgstr "brevi dettagli (ad es. il nome del dialetto locale)"
+#~ msgid "devcp_edit_submit_update"
+#~ msgstr "Aggiorna"
+#~ msgid "devcp_edit_target_locale_explanation"
+#~ msgstr ""
+#~ "<a href=\"http://wiki.mozilla.org/L10n:Simple_locale_names\">nome "
+#~ "semplificato del locale</a>, come ad es. 'en-US'"
+#~ msgid "devcp_editversion_checkedfiles_delete"
+#~ msgstr "I file selezionati verranno eliminati."
+#~ msgid "devcp_editversion_filename_size"
+#~ msgstr "%1$s (%2$s)"
+#~ msgid "devcp_editversion_label_files"
+#~ msgstr "File"
+#~ msgid "devcp_editversion_label_targetapps"
+#~ msgstr "Applicazioni di destinazione"
+#~ msgid "devcp_editversion_nofiles"
+#~ msgstr "Nessun file."
+#~ msgid "devcp_editversion_reviewernotes"
+#~ msgstr "Note per i revisori"
+#~ msgid "devcp_editversion_submit_update"
+#~ msgstr "Aggiorna"
+#~ msgid "devcp_error_addon_field_summary_toolong"
+#~ msgstr ""
+#~ "La lunghezza massima per un riepilogo è di 250 caratteri.\n"
+#~ "(Ne hai inseriti %s)"
+#~ msgid "devcp_error_addonname_not_unique"
+#~ msgstr ""
+#~ "Il nome scelto per il componente aggiuntivo è già presente nel database. "
+#~ "Assicurati che: <br /><li>il GUID sia corretto. La causa più comune per "
+#~ "questo tipo di errori è un GUID errato.</li><li>nel database non sia "
+#~ "effettivamente presente un elemento duplicato. In questo caso è "
+#~ "necessario modificare l'elemento esistente oppure eliminarlo e riprovare."
+#~ "</li>"
+#~ msgid "devcp_error_describe_changes"
+#~ msgstr "Descrivi le modifiche introdotte in questo aggiornamento."
+#~ msgid "devcp_error_file_guids_dont_match"
+#~ msgstr "Non tutte le GUID del file corrispondono"
+#~ msgid "devcp_error_identical_version_exists"
+#~ msgstr ""
+#~ "Una versione identica (%s) è già presente per questo componente "
+#~ "aggiuntivo e questa piattaforma."
+#~ msgid "devcp_error_nominate_message"
+#~ msgstr "È necessario fornire i dettagli richiesti per la segnalazione."
+#~ msgid "devcp_error_nominate_no_prerelease"
+#~ msgstr "Non è possibile segnalare un componente aggiuntivo in pre-release."
+#~ msgid "devcp_error_nominate_sandbox_only"
+#~ msgstr ""
+#~ "Puoi segnalare solamente i componenti aggiuntivi che si trovano nella "
+#~ "sandbox."
+#~ msgid "devcp_error_saving"
+#~ msgstr "Si è verificato un errore durante il salvataggio dei dati."
+#~ msgid "devcp_error_update_access_denied"
+#~ msgstr "Non hai il permesso per aggiornare questo componente aggiuntivo."
+#~ msgid "devcp_file_addanother"
+#~ msgstr "Aggiungi un file per un'altra piattaforma"
+#~ msgid "devcp_form_author_add"
+#~ msgstr "Aggiungi autore"
+#~ msgid "devcp_form_author_remove"
+#~ msgstr "Rimuovi"
+#~ msgid "devcp_form_categories_nextstep"
+#~ msgstr ""
+#~ "Le categorie per la nuova tipologia di componente aggiuntivo saranno "
+#~ "disponibili al passaggio successivo."
+#~ msgid "devcp_form_error_categories_unavailable"
+#~ msgstr ""
+#~ "Non sono disponibili categorie per questo tipo di componente aggiuntivo."
+#~ msgid "devcp_form_error_description_notempty"
+#~ msgstr "Inserisci una descrizione per il componente aggiuntivo."
+#~ msgid "devcp_form_error_name_required"
+#~ msgstr "Inserisci un nome per il componente aggiuntivo."
+#~ msgid "devcp_form_error_select_addontype"
+#~ msgstr "Seleziona la tipologia del componente aggiuntivo."
+#~ msgid "devcp_form_error_summary_notempty"
+#~ msgstr "Inserisci un riepilogo per il componente aggiuntivo."
+#~ msgid "devcp_form_label_addonfile"
+#~ msgstr "Componente aggiuntivo"
+#~ msgid "devcp_form_label_addonfile2"
+#~ msgstr "Componente aggiuntivo 2"
+#~ msgid "devcp_form_label_addonfile3"
+#~ msgstr "Componente aggiuntivo 3"
+#~ msgid "devcp_form_label_addontype"
+#~ msgstr "Tipologia"
+#~ msgid "devcp_form_label_allow_viewsource"
+#~ msgstr "Permetti agli utenti di visualizzare i sorgenti online"
+#~ msgid "devcp_form_label_author_email"
+#~ msgstr "Indirizzo e-mail dell'autore"
+#~ msgid "devcp_form_label_authors"
+#~ msgstr "Autori"
+#~ msgid "devcp_form_label_categories"
+#~ msgstr "Categorie"
+#~ msgid "devcp_form_label_defaultlocale"
+#~ msgstr "Locale predefinito"
+#~ msgid "devcp_form_label_description"
+#~ msgstr "Descrizione"
+#~ msgid "devcp_form_label_eula"
+#~ msgstr "Accordo di licenza con l'utente finale (EULA)"
+#~ msgid "devcp_form_label_externalsoftware"
+#~ msgstr ""
+#~ "Questo componente aggiuntivo richiede la presenza di software esterno"
+#~ msgid "devcp_form_label_files"
+#~ msgstr "File"
+#~ msgid "devcp_form_label_homepage"
+#~ msgstr "Sito web"
+#~ msgid "devcp_form_label_iconfile"
+#~ msgstr "Icona"
+#~ msgid "devcp_form_label_name"
+#~ msgstr "Nome"
+#~ msgid "devcp_form_label_platforms"
+#~ msgstr "Piattaforme supportate"
+#~ msgid "devcp_form_label_prerelease"
+#~ msgstr "Si tratta di una pre-release"
+#~ msgid "devcp_form_label_privacy"
+#~ msgstr "Informativa sulla privacy"
+#~ msgid "devcp_form_label_sitespecific"
+#~ msgstr ""
+#~ "Questo componente aggiuntivo è specifico per un determinato sito web"
+#~ msgid "devcp_form_label_summary"
+#~ msgstr "Riepilogo"
+#~ msgid "devcp_form_label_supportemail"
+#~ msgstr "E-mail per il supporto"
+#~ msgid "devcp_form_label_supporturl"
+#~ msgstr "URL per il supporto"
+#~ msgid "devcp_form_label_target_applications"
+#~ msgstr "Applicazioni di destinazione"
+#~ msgid "devcp_form_label_version"
+#~ msgstr "Versione"
+#~ msgid "devcp_form_label_versionnotes"
+#~ msgstr "Note sulla versione"
+#~ msgid "devcp_form_no_target_apps"
+#~ msgstr "Nessuna"
+#~ msgid "devcp_form_reviewernotes"
+#~ msgstr "Note per i revisori"
+#~ msgid "devcp_form_trustedaddon_destination"
+#~ msgstr ""
+#~ "Poiché il componente aggiuntivo è considerato affidabile, puoi scegliere "
+#~ "dove inserire questa versione:"
+#~ msgid "devcp_form_trustedaddon_destination_public"
+#~ msgstr "area pubblica"
+#~ msgid "devcp_form_trustedaddon_destination_sandbox"
+#~ msgstr "Sandbox"
+#~ msgid "devcp_header_developer_agreement"
+#~ msgstr "Accordo di licenza per sviluppatori"
+#~ msgid "devcp_header_step1"
+#~ msgstr "Passaggio 1"
+#~ msgid "devcp_header_step1_upload"
+#~ msgstr "Carica i file"
+#~ msgid "devcp_header_step2"
+#~ msgstr "Passaggio 2"
+#~ msgid "devcp_header_step2_addondetails"
+#~ msgstr "Informazioni sul componente aggiuntivo"
+#~ msgid "devcp_header_step3"
+#~ msgstr "Passaggio 3"
+#~ msgid "devcp_header_step3_versiondetails"
+#~ msgstr "Dettagli sulla versione"
+#~ msgid "devcp_header_step4"
+#~ msgstr "Passaggio 4"
+#~ msgid "devcp_header_step4_localization"
+#~ msgstr "Localizzazione"
+#~ msgid "devcp_header_step5"
+#~ msgstr "Passaggio 5"
+#~ msgid "devcp_header_step5_success"
+#~ msgstr "Operazione completata"
+#~ msgid "devcp_index_header_myaddons"
+#~ msgstr "I miei componenti aggiuntivi"
+#~ msgid "devcp_nominate_link_returnto_details"
+#~ msgstr "Ritorno ai dettagli del componente aggiuntivo"
+#~ msgid "devcp_notice_autodetected_addontype"
+#~ msgstr "Tipologia del componente aggiuntivo rilevata automaticamente: %s."
+#~ msgid "devcp_notice_different_defaultlocale"
+#~ msgstr ""
+#~ "Il locale predefinito di questo componente aggiuntivo (%1$s [%2$s]) è "
+#~ "diverso dal locale attualmente selezionato (%3$s [%4$s]). I campi "
+#~ "successivi dovrebbero essere compilati in %1$s."
+#~ msgid "devcp_question_addontype_incorrect"
+#~ msgstr "Non corretto?"
+#~ msgid "devcp_question_delete_file"
+#~ msgstr "Vuoi eliminare questo file?"
+#~ msgid "devcp_skip_reviewing_addon_info"
+#~ msgstr ""
+#~ "Non effettuare la revisione delle informazioni per questa versione del "
+#~ "componente aggiuntivo"
+#~ msgid "devcp_submissions_disabled"
+#~ msgstr ""
+#~ "Al momento non è possibile inserire nuovi componenti aggiuntivi. "
+#~ "Riprovare più tardi."
+#~ msgid "devcp_submit_accept_dev_agreement"
+#~ msgstr "Accetto"
+#~ msgid "devcp_submit_decline_dev_agreement"
+#~ msgstr "Non accetto"
+#~ msgid "devcp_summary_admin_disabled"
+#~ msgstr ""
+#~ "Questo componente aggiuntivo è stato disattivato da un amministratore."
+#~ msgid "devcp_summary_header_disabled"
+#~ msgstr "Disattivato"
+#~ msgid "devcp_summary_header_trusted"
+#~ msgstr "Affidabile"
+#~ msgid "devcp_summary_noaddons_submit_one"
+#~ msgstr ""
+#~ "Non hai ancora pubblicato alcun componente aggiuntivo. Fai clic %s per "
+#~ "inserirne uno."
+#~ msgid "devcp_summary_noaddons_submit_one_link"
+#~ msgstr "qui"
+#~ msgid "devcp_theme_upload_preview"
+#~ msgstr "Assicurati di %s per il tuo tema."
+#~ msgid "devcp_theme_upload_preview_link"
+#~ msgstr "aver caricato un'anteprima"
+#~ msgid "devcp_version_edit_pagetitle"
+#~ msgstr "Modifica versione"
+#~ msgid "devcp_version_updated_successfully"
+#~ msgstr "Versione aggiornata con successo."
+#~ msgid "editors_submissiontype_new"
+#~ msgstr "Nuovo"
+#~ msgid "editors_submissiontype_updated"
+#~ msgstr "Aggiornato"
+#~ msgid "editors_th_addon_age"
+#~ msgstr "Età"
+#~ msgid "editors_th_addontypes"
+#~ msgstr "Tipologie di componente aggiuntivo"
+#~ msgid "editors_th_age"
+#~ msgstr "Età"
+#~ msgid "editors_th_applications"
+#~ msgstr "Applicazioni"
+#~ msgid "editors_th_platforms"
+#~ msgstr "Piattaforme"
+#~ msgid "editors_th_submissiontypes"
+#~ msgstr "Tipi di proposta"
+#~ msgid "error_notice"
+#~ msgstr "Notifica"
+#~ msgid "forum_save"
+#~ msgstr "Salva"
+#~ msgid "home"
+#~ msgstr "home"
+#~ msgid "nav_category_plugins"
+#~ msgstr "Plugin"
+#~ msgid "page_title_experimental_addons"
+#~ msgstr "Componenti aggiuntivi sperimentali"
+#~ msgid "pages_experimental_addons_backbutton"
+#~ msgstr "Torna alla pagina precedente"
+#~ msgid "pagination_page_number_title"
+#~ msgstr "Pagina %1$s di %2$s"
+#~ msgid "search_matching_addons_number"
+#~ msgid_plural "search_matching_addons_number"
+#~ msgstr[0] "%s componente aggiuntivo corrispondente"
+#~ msgstr[1] "%s componenti aggiuntivi corrispondenti"
+#~ msgid "statistics_rss_icon_title"
+#~ msgstr "Feed RSS dei dati sintetici"
+
diff --git a/site/app/locale/it/images/sandbox-review.png b/site/app/locale/it/images/sandbox-review.png
new file mode 100644
index 0000000..844b2fe
--- /dev/null
+++ b/site/app/locale/it/images/sandbox-review.png
Binary files differ
diff --git a/site/app/locale/it/pages/error404.thtml b/site/app/locale/it/pages/error404.thtml
new file mode 100644
index 0000000..67b4052
--- /dev/null
+++ b/site/app/locale/it/pages/error404.thtml
@@ -0,0 +1,16 @@
+<h1>Spiacenti, non è possibile trovare le informazioni desiderate.</h1>
+
+<p>La pagina o il documento richiesto non è stato trovato. È possibile che il collegamento selezionato non sia aggiornato o che l'indirizzo sia errato.</p>
+
+<ul>
+<li>Se hai digitato l'indirizzo verifica il testo inserito.</li>
+<li>Se hai seguito un link da un'altra pagina, inviaci una segnalazione a <a href="mailto:webmaster@mozilla.com" title="Page Not Found on Mozilla.com">webmaster@mozilla.com</a>, specificando il sito di provenienza e l'oggetto della ricerca, faremo il possibile per risolvere il problema.</li>
+</ul>
+
+<p>In alternativa puoi visitare alcune delle pagine più visitate del nostro sito.</p>
+
+<ul>
+<li>Ti interessa un <a href="%1$s">elenco dei componenti aggiuntivi più popolari</a>?</li>
+<li>Vuoi <a href="%2$s">cercare dei componenti aggiuntivi</a>? Puoi andare alla <a href="%2$s">pagina di ricerca</a> oppure usare il campo di ricerca in alto nella pagina.</li>
+<li>Se preferisci ripartire dall'inizio, vai alla <a href="%3$s">pagina principale dei componenti aggiuntivi</a>.</li>
+</ul>
diff --git a/site/app/locale/it/pages/nomination.thtml b/site/app/locale/it/pages/nomination.thtml
new file mode 100644
index 0000000..b64f9bc
--- /dev/null
+++ b/site/app/locale/it/pages/nomination.thtml
@@ -0,0 +1,8 @@
+<p>Un componente aggiuntivo attualmente nella sandbox può essere segnalato per comparire nella sezione pubblica del sito e diventare disponibile a tutti gli utenti dopo essere stato sottoposto ad un controllo da parte di un revisore. Per una procedura efficiente seguire queste indicazioni:</p>
+<ul>
+ <li>le immagini di anteprima sono obbligatorie per i temi e altamente consigliate per le altre tipologie di componenti aggiuntivi</li>
+ <li>il componente aggiuntivo deve rimanere per un certo periodo nella sandbox in modo da raccogliere recensioni e commenti degli utenti</li>
+ <li>i componenti aggiuntivi pubblicati hanno uno standard qualitativo più elevato di quelli presenti nella sandbox e dovrebbero migliorare la navigazione sul web</li>
+ <li>i criteri completi per la segnalazione sono consultabili nella nostra <a href="%s">Policy componenti aggiuntivi</a></li>
+</ul>
+<p>Se il tuo componente aggiuntivo risponde ai criteri descritti, puoi segnalarlo utilizzando il pulsante seguente. Riceverai una notifica via e-mail sullo stato della segnalazione.</p>
diff --git a/site/app/locale/it/pages/policy.thtml b/site/app/locale/it/pages/policy.thtml
new file mode 100644
index 0000000..8cd6922
--- /dev/null
+++ b/site/app/locale/it/pages/policy.thtml
@@ -0,0 +1,110 @@
+<h1>Policy</h1>
+
+<h2>Che cos'è la sandbox?</h2>
+<p>Vedi %s.</p>
+
+<h2>Quali componenti aggiuntivi si trovano nella sandbox?</h2>
+<p>Inizialmente tutti i componenti aggiuntivi inseriti su AMO vengono posizionati nella sandbox. Questa sezione contiene le nuove versioni dei componenti aggiuntivi pubblicati così come tutte le versioni di quelli non pubblicati. Quando viene caricato un nuovo componente aggiuntivo, o un aggiornamento di un componente aggiuntivo esistente, questo viene inserito nella sandbox.</p>
+
+<p>Alcuni componenti aggiuntivi, e alcune versioni specifiche, vengono resi pubblici nel momento in cui il processo di revisione ne stabilisce l'idoneità. Altri invece possono rimanere indefinitamente nella sandbox, a disposizione degli utenti che vogliano esplorare la sezione e sperimentare con il software presente.</p>
+
+<h2>Quando un componente aggiuntivo viene reso pubblico?</h2>
+
+<p>Gli utenti di AMO che utilizzano la sandbox e provano i componenti aggiuntivi presenti possono scriverne delle recensioni. Tali recensioni potranno indicare se un componente aggiuntivo è sufficientemente utile, ben scritto e curato da essere presentato a tutti gli utilizzatori di Firefox. Queste recensioni, in aggiunta a eventuali revisioni e approfondimenti da parte dello staff di AMO, vengono utilizzate per determinare se un dato componente aggiuntivo possa essere pubblicato, se necessita di ulteriori modifiche prima di ottenere una visibilità maggiore, o se non è adatto a essere spostato dalla sandbox alla sezione pubblica del sito di AMO.</p>
+
+<h2>Come posso far pubblicare il mio componente aggiuntivo?</h2>
+
+<p>Se sei convinto che il tuo componente aggiuntivo (e il tuo comportamento) soddisfino i requisiti richiesti per un componente aggiuntivo pubblico, potrai nominarlo usando gli Strumenti per sviluppatori.</p>
+
+<h2>Quali requisiti devono possedere i componenti aggiuntivi pubblicati?</h2>
+
+<p>Un componente aggiuntivo pubblicato su AMO deve avere un'alta qualità e migliorare l'esperienza degli utenti sul web. Nel prendere la decisione di rendere pubblico o meno un componente aggiuntivo su AMO, verranno valutati i seguenti aspetti:</p>
+
+<h3>Sei in grado di fornire riposte?</h3>
+
+<p>Ci si attende che un autore che vuole promuovere il proprio componente aggiuntivo ai tanti utenti di Firefox sia capace di fornire risposte alle richieste di supporto, mantenere aggiornati i propri dati e mantenere compatibile il componente aggiuntivo con le nuove versioni di Firefox e le modifiche alle policy di AMO. Ciò non implica l'obbligo di rispondere a tutte le domande che vengono poste, o di correggere ogni bug trovato, ma ci si aspetta che un autore risponda a tali richieste in maniera proporzionata alla gravità del problema riscontrato.</p>
+
+<h3>La descrizione del componente aggiuntivo è chiara e dettagliata?</h3>
+
+<p>È della massima importanza che gli utenti, quando provano un nuovo componente aggiuntivo, ottengano quello che si aspettano. La descrizione dovrebbe fornire particolari sulle funzioni di un componente aggiuntivo e illustrare cosa succederà quando l'utente l'avrà installato. È perfettamente legittimo inserire link a documenti esterni, ma la descrizione dovrebbe comunque fornire le informazioni basilari e consentire agli utenti di sapere ciò che otterranno.</p>
+
+<p>È inoltre importante aggiornare le note di versione in maniera coerente con i miglioramenti e le modifiche apportati ai componenti aggiuntivi. Gli utenti dovrebbero poter vedere quali novità sono state introdotte nei componenti aggiuntivi che hanno installato in passato, e dovrebbero essere messi a conoscenza di quali cambiamenti potrebbero incontrare nell'utilizzo del componente aggiuntivo in caso di aggiornamento. (Attualmente gli utenti non possono leggere le note di versione quando ricevono una notifica di aggiornamento dal browser, ma sono in programma aggiornamenti in questa direzione – e mantenere aggiornate le note di versione produrrà comunque grandi vantaggi prima e dopo il completamento di questo nuovo sviluppo).</p>
+
+<h3>Eventuali rischi riguardanti privacy e sicurezza sono indicati in modo chiaro?</h3>
+
+<p>Per quanto questo punto sia collegato a quanto già scritto sulla necessità di una descrizione chiara e accurata, si tratta di un aspetto che merita di essere esaminato in modo specifico. Molti componenti aggiuntivi utili e ben scritti operano in diversi modi sui dati dell'utente, o possono presentare rischi legati alla sicurezza in caso di utilizzo poco consapevole; questi componenti possono comunque essere presenti nella sezione pubblica di AMO, ma gli utenti devono avere ben chiari i rischi che il loro utilizzo comporta, e in che modo possono proteggersi.</p>
+
+<h3>Il componente aggiuntivo è stata testato in modo adeguato e risulta privo di problemi evidenti o gravi anomalie?</h3>
+
+<p>Un altro elemento importante per ottenere la pubblicazione è la presenza nella sandbox di recensioni che assicurino una fase di test approfondita, l'assenza di problemi gravi o effetti negativi sul browser. Se i revisori riportano problemi come riduzione della velocità, crash, problemi frequenti nell'utilizzo delle funzioni del componente aggiuntivo o messaggi anomali nella console degli errori, l'autore dovrebbe occuparsi immediatamente di questo tipo di segnalazioni, risolvere i problemi al meglio delle proprie possibilità e rilasciare una nuova versione. Nessuno si aspetta che il componente aggiuntivo sia perfettamente ottimizzato o sia privo di bug, anche il browser Firefox viene costantemente sottoposto a questo tipo di verifiche – allo stesso tempo è necessario minimizzare i difetti, e indicare con chiarezza i casi in cui un utente potrebbe essere soggetto alle anomalie ancora presenti.</p>
+
+<p>Se un componente aggiuntivo ha seguito una fase di test al di fuori della sandbox di AMO, ad esempio da parte di un gruppo di collaboratori o un team di controllo qualità, ciò dovrebbe essere indicato nel messaggio di segnalazione. Questa segnalazione aiuterà sicuramente lo staff di AMO a stabilire il grado di affidabilità di questi test, e potrà influire sulla decisione di pubblicare il componente nell'area pubblica.</p>
+
+<h3>Il componente aggiuntivo e il suo autore rispettano l'utente?</h3>
+
+<p>Un software non dovrebbe mai interferire con le attività dell'utente, tentare di ingannarlo o nascondere le proprie azioni. Gli utilizzatori del componente aggiuntivo (e perfino coloro che non lo utilizzano) possono risultare eccessivamente volgari nei commenti; lo staff di AMO si occuperà di eliminare i commenti segnalati, ma ci si aspetta comunque che gli autori non assumano a loro volta atteggiamenti denigratori nelle risposte.</p>
+
+<h3>Il componente aggiuntivo può risultare utile a un numero sufficientemente ampio dli utilizzatori di Firefox</h3>
+
+<p>Non è necessario che un componente aggiuntivo raggiunga la popolarità di Greasemonkey o FireBug, ma se risulta utile solamente al personale di una singola azienda o ai partecipanti di una piccola comunità web, potrebbe non essere appropriato renderlo visibile a tutti gli utilizzatori di Firefox.</p>
+
+<p>Lo staff di AMO è alla costante ricerca di nuovi modi per migliorare l'organizzazione del sito e gestire al meglio i componenti aggiungitivi di ottima qualità ma indirizzati a piccole comunità di potenziali utenti. Assegnando correttamente le categorie e aggiornando le informazioni aggiuntive del componente aggiuntivo, gli autori aiuteranno gli sviluppatori del sito a suggerire questo tipo di componenti alle persone che maggiormente potranno trarne vantaggio.</p>
+
+<p>Se un componente fornisce solamente un gruppo di segnalibri o un modo per accedere a un sito web specifico, probabilmente non è adatto alla sezione pubblica di AMO. Tutti coloro che gravitano attorno al progetto Mozilla sono molto attenti alle applicazioni web e ai nuovi servizi, ma i componenti aggiuntivi di Firefox dovrebbero aumentare la qualità dell'esperienza sul web degli utenti e non essere solamente un modo per promuovere un nuovo sito o servizio utilizzando il canale di AMO. Se la descrizione del tuo componente aggiuntivo insiste più sul servizio che sul miglioramento dell'esperienza sul web degli utenti, hai probabilmente bisogno di effettuare qualche correzione.</p>
+
+<h3>Il componente aggiuntivo è privo di vincoli di licenza su marchi registrati o diritti d'autore?</h3>
+
+<p>Anche se probabilmente non c'è nessuna intenzione di danneggiare il detentore di un marchio registrato o di un lavoro protetto da diritto d'autore, non è possibile ospitare su AMO componenti aggiuntivi in cui vengono utilizzati senza consenso marchi registrati e opere protette da diritti d'autore. Se non hai il permesso di utilizzare un nome o un marchio registrato, sei pregato di non caricare i tuoi componenti aggiuntivi su AMO. (Se il detentore di un marchio o dei diritti d'autore di un'opera contesta l'uso del proprio marchio, verosimilmente tale richiesta dovrà essere approvata dall'ufficio legale, e qualora ciò venisse giudicato necessario da un punto di vista legale il componente verrebbe rimosso. Questo processo è costoso in termini di tempo e denaro, e per questo chiediamo agli autori di mostrare rispetto e non causare difficoltà indesiderate.)</p>
+
+<p>Se non sei sicuro che il nome dato al tuo componente aggiuntivo o l'utilizzo di elementi al suo interno possa impedirne la pubblicazione, puoi inviare una richiesta di assistenza via e-mail a amo-editors@mozilla.org. IMPORTANTE: il gruppo che risponde a questa lista di distribuzione non ha la possibilità di fornire assistenza legale, se anche trovasse accettabile l'utilizzo tale decisione potrebbe essere rivista alla luce di lamentele dai detentori dei diritti d'autore e segnalazione dell'ufficio legale.</p>
+
+<p>Riguardo all'utilizzo di codice sorgente presente in altri componenti aggiuntivi, se l'autore non ha esplicitamente stabilito che tale codice possa essere riutilizzato – ad esempio distribuendolo con una licenza Open Source – è da intendersi che non si hanno i diritti per farlo. Puoi contattare l'autore originario per ottenere questo consenso, ma questo non verrà automaticamente fornito solo perché il componente originario era già su AMO o perché l'autore originario non ha risposto alla richiesta. (Si ricorda che è impossibile fornire assistenza legale, ma solamente indicazioni su come un componente possa accordarsi con le policy del sito.)</p>
+
+<p>Ciò si applica anche ai marchi registrati della Mozilla Foundation, inclusi "Mozilla", "Firefox" e "Thunderbird". La politica di Mozilla sull'utilizzo dei marchi è progettata per evitare confusione e impedisce ai marchi registrati di essere danneggiati per mancanza di protezione; rispetta quindi la necessità di queste policy, e aiutaci a conservare alcuni dei beni più preziosi della Mozilla Foundation.</p>
+
+<h2>Che cosa avviene dopo aver nominato un componente aggiuntivo?</h2>
+
+<p>Dopo aver nominato un componente aggiuntivo, ogni elemento viene valutato da un gruppo di revisori che ne verificano le caratteristiche in accordo con quanto indicato in precedenza. Se il componente viene giudicato idoneo alla pubblicazione, viene spostato in area pubblica e riceverai una notifica tramite e-mail.</p>
+
+<p>Se invece non viene giudicato sufficientemente maturo per la sezione pubblica di AMO, riceverai una e-mail in cui saranno indicate le motivazioni di tale decisione e la nomina verrà rimossa dalla coda di revisione. Dopo aver risolto tutti i problemi emersi nell'e-mail di spiegazione, potrai richiedere una nuova valutazione a tua discrezione. Ripetute richieste di valutazione di uno stesso componente aggiuntivo senza miglioramenti significativi non vengono valutate favorevolmente: gli autori sono quindi pregati di operare con giudizio.</p>
+
+<h2>Posso nominare il componente di un altro autore?</h2>
+
+<p>Al momento lo staff chiede che ogni autore nomini unicamente il proprio lavoro per la pubblicazione. Solo in questo modo si è infatti certi che questi sarà consapevole dell'aumento di visibilità e che il componente aggiuntivo, allo stato dell'arte, rifletterà la qualità del proprio lavoro. Se un utente è convinto che un dato componente sia ben rifinito, che il suo autore si conformi pienamente alla lettera e allo spirito delle policy di AMO, e che la sua disponibilità a quasi cento milioni di utenti in tutto il mondo porterà vantaggi a Firefox, ai suoi utilizzatori e al web in generale, allora è bene incoraggiare l'autore del componente aggiuntivo a nominare la propria estensione.</p>
+
+<h2>Il mio componente aggiuntivo è rimasto in coda di revisione per lungo tempo, mi odiate?</h2>
+
+<p>No, non ti odiamo. Adoriamo gli sviluppatori e lavoriamo in modo che possano essere sempre contenti e produttivi, così che gli utenti di tutto il mondo possano beneficiare del loro lavoro. Ma l'area pubblica di AMO ha valore proprio per l'attenzione posta a ciò che può essere pubblicato, e non è possibile stringere i tempi rischiando di essere superficiali. Lo staff è consapevole di quanto possa essere frustrante l'attesa di una valutazione, e cercherà di abbreviare i tempi quando possibile. Maggiore sarà il numero di coloro che lasceranno attente e chiare recensioni sui componenti in sandbox, e più agevole sarà il compito di valutarli: gli autori considerino quindi la possibilità di insistere su questo aspetto.</p>
+
+<h2>Ho trovato un bug grave nel mio componente aggiuntivo e voglio rilasciare rapidamente una correzione. Come posso fare?</h2>
+
+<p>Se esiste un bug grave (che riguarda sicurezza, stabilità o problemi di funzionamento) in un componente aggiuntivo per cui l'autore ritenga necessario rilasciare subito un aggiornamento, ciò deve essere indicato nelle "Note per i revisori" in fase di inserimento, insieme alle altre note di versione. Può essere utile far registrare altri utilizzatori del componente per effettuare i test e aggiornare i risultati in dettaglio nella sandbox. Puoi anche utilizzare il canale #addons su irc.mozilla.org per avvertire i presenti della situazione, ma in questo caso sei pregati di essere paziente ed educato.</p>
+
+<p>È anche opportuno non generare allarmismi. Lo staff cercherà di gestire rapidamente le richieste di aggiornamento a priorità alta, ma è bene ricordare che il tempo che i membri dello staff dedicano al processo di valutazione dei componenti è spesso tempo sottratto al sonno, alla famiglia o agli amici: non saranno quindi giudicati in maniera favorevole coloro che utilizzano questo mezzo per "evitare la coda". In caso di dubbio è meglio rivolgersi a #addons su irc.mozilla.org dove si potrà trovare aiuto nel prendere una decisione in tal senso.</p>
+
+<h2>Ritengo che la valutazione del mio componente aggiuntivo sia stata fatta in modo poco corretto. Che cosa posso fare?</h2>
+
+<p>Se sei convinto che il tuo componente aggiuntivo sia stato valutato in maniera non corretta, e che sia stato un errore precludergli la pubblicazione, puoi inviare un'e-mail a amo-editors@mozilla.org spiegando nel dettaglio le tue ragioni. Ti preghiamo di essere educato ed esaustivo nella tua spiegazione, e assicurati di avere buoni motivi per contestare il giudizio espresso.</p>
+
+<p>Se hai posto rimedio a tutti gli aspetti indicati come problemi nel messaggio e-mail di notifica, non è opportuno contestare la valutazione ma effettuare invece un nuovo rilascio attraverso gli Strumenti per sviluppatori.</p>
+
+<h2>Il mio componente aggiuntivo si trovava nella sezione pubblica ma ora si trova solo nella sandbox. Che cosa è successo?</h2>
+
+<p>Se un componente aggiuntivo non incontra più i requisiti richiesti per rimanere in area pubblica, può essere riportato in sandbox. A meno di non essere impossibilitati legalmente dal farlo, lo staff notificherà per e-mail l'avvenuto spostamento indicandone i motivi.</p>
+
+<p>È anche possibile che ci si trovi in presenza di un bug del sito web, nel qual caso dovrebbe essere creata una segnalazione di bug via Bugzilla; indicare come prodotto "addons.mozilla.org" e "Public Pages" come componente, e includere il maggior numero di dettagli possibile.</p>
+
+<h2>Il mio componente aggiuntivo è stato pubblicato ed è apprezzato dagli utenti, che cosa posso fare affinché venga incluso nell'elenco dei componenti aggiuntivi consigliati?</h2>
+
+<p>Se sei convinto che il tuo componente aggiuntivo sia un fulgido esempio della potenza delle estensioni, che testimoni e porti avanti i valori di Mozilla per un web personalizzabile e controllato dall'utente, e che garantisca all'utente una eccezionale esperienza sul web, puoi chiedere che venga aggiunto all'elenco dei componenti aggiuntivi consigliati. Per ottenere questo risultato è necessario inviare una e-mail a amo-editors@mozilla.org spiegando i motivi per cui sei convinto dell'eccezionalità del tuo componente.</p>
+
+<p>Questa e-mail dovrebbe includere <b>almeno</b> le seguenti informazioni:<p>
+<ul>
+<li>come l'esperienza degli utenti sul web risulta migliorata;</li>
+<li>perché il componente aggiuntivo è adatto a una larga parte degli utilizzatori di Firefox;</li>
+<li>in che modo il componente aggiuntivo testimonia i valori del progetto Mozilla, con particolare riferimento alla centralità dell'utente, alla protezione della privacy e della sicurezza, all'accesso universale al web, ai dati e agli standard aperti;</li>
+<li>in che modo il componente aggiuntivo differisce da altri componenti simili (nel bene e nel male);</li>
+<li>quali reazioni, positive e negative, sono state registrate in utenti, revisori, blogger, astronauti, casalinghe e animali domestici durante l'utilizzo;</li>
+</ul>
+
+<p>Maggiore sarà la completezza delle informazioni fornite e maggiore sarà la probabilità di raggiungere questo scopo, sebbene anche un'applicazione scritta in maniera sopraffina e completa non ottenga automaticamente la garanzia di comparire nell'elenco dei componenti aggiuntivi consigliati. In ultima analisi, tale elenco deve essere – come infatti è – mantenuto da Mozilla, e ogni aspetto è subordinato alla protezione e all'esperienza sul web degli utenti.</p>
diff --git a/site/app/locale/it/pages/sandbox.thtml b/site/app/locale/it/pages/sandbox.thtml
new file mode 100644
index 0000000..5bb9333
--- /dev/null
+++ b/site/app/locale/it/pages/sandbox.thtml
@@ -0,0 +1,13 @@
+<h1>Sistema di revisione sandbox</h1>
+<h2>Cos'è la sandbox?</h2>
+<p>La sandbox è un'area per utenti avanzati in cui è possibile provare un componente aggiuntivo prima che venga pubblicato. Per accedere alla sandbox è necessario attivarla nelle preferenze del proprio account. Consigliamo la massima cautela a chi intendesse installare uno o più componenti aggiuntivi presenti nella sandbox, poiché, non essendo stati ancora verificati da un revisore ufficiale, potrebbero causare danni al proprio computer.</p>
+
+<h2>Come posso far comparire il mio componente aggiuntivo nella sezione pubblica?</h2>
+<!-- Per localizzare l'immagine del diagramma di flusso, consulta il sito http://wiki.mozilla.org/Update:Remora_Sandbox_Flowchart -->
+<div style="text-align: center;">%s</div>
+<ol>
+ <li><b>Invia il tuo componente aggiuntivo tramite il pannello di controllo degli sviluppatori.</b> Non appena l'avrai inviato, comparirà immediatamente nella sezione Sandbox di Mozilla Add-ons. In questa sezione verrà poi provato da utenti esperti che provvederanno ad inviare i risultati dei loro test. Per poter visualizzare la sandbox è necessario attivarla nelle preferenze del tuo account.</li>
+ <li><b>Segnala il tuo componente aggiuntivo per renderlo visibile nella sezione pubblica.</b> Nel pannello di controllo degli sviluppatori troverai un link che ti permetterà di segnalare il tuo componente aggiuntivo. Dopo la segnalazione, il tuo componente aggiuntivo comparirà nella coda di segnalazione dei revisori per essere controllato.</li>
+ <li><b>Controllo del tuo componente aggiuntivo da parte di un revisore.</b> Un revisore di Mozilla Add-ons installerà il tuo componente aggiuntivo e ne verificherà il corretto funzionamento, tenendo conto anche dei commenti inviati dai tester sandbox.</li>
+ <li><b>Il tuo componente aggiuntivo viene pubblicato o mantenuto nella sandbox.</b> Il revisore deciderà se pubblicare il tuo componente aggiuntivo o se mantenerlo nella sandbox. Se verrà deciso che il tuo componente aggiuntivo debba restare nella sandbox, potrai segnalarlo di nuovo dopo aver eseguito i cambiamenti richiesti dal revisore nei suoi commenti. Una volta che il tuo componente aggiuntivo sarà stato pubblicato definitivamente, non sarà più necessario segnalarlo nuovamente. Le versioni successive verranno automaticamente inserite nella coda d'attesa per la revisione. Nota bene: se segnalerai nuove versioni del tuo componente aggiuntivo mentre la versione iniziale è ancora in fase di revisione oppure non è ancora stata pubblicata definitivamente, le nuove versioni verranno comunque prima inserite nella sandbox finché non saranno state anch'esse controllate da un revisore e quindi pubblicate.</li>
+</ol>
diff --git a/site/app/locale/it/pages/statistics_help.thtml b/site/app/locale/it/pages/statistics_help.thtml
new file mode 100644
index 0000000..3400928
--- /dev/null
+++ b/site/app/locale/it/pages/statistics_help.thtml
@@ -0,0 +1,8 @@
+<h3>Guida</h3>
+<p>La Dashboard statistiche visualizza informazioni sui download e le richieste di aggiornamento per il tuo componente aggiuntivo.</p>
+<h4>Download</h4>
+<p>Il calcolo del numero dei download viene aggiornato ogni giorno e include solo i download del componente aggiuntivo originale, non gli aggiornamenti.</p>
+
+<h4>Richieste di aggiornamento</h4>
+<p>I componenti aggiuntivi scaricati da questo sito verificano la presenza di aggiornamenti una volta al giorno, e il numero complessivo di richieste viene definito Utenti attivi per giorno (ADU, Active Daily User).
+Il numero di utenti attivi per giorno (ADU) può essere suddiviso in base alla versione del componente aggiuntivo, al sistema operativo, allo stato del componente aggiuntivo e all'applicazione. Queste informazioni attualmente vengono aggiornate su base settimanale (ogni mercoledì).</p> \ No newline at end of file
diff --git a/site/app/locale/it/pages/submission_help.thtml b/site/app/locale/it/pages/submission_help.thtml
new file mode 100644
index 0000000..f376ac0
--- /dev/null
+++ b/site/app/locale/it/pages/submission_help.thtml
@@ -0,0 +1,35 @@
+<h1>Guida per l'inserimento</h1>
+I campi obbligatori sono in <b>grassetto</b>. I campi facoltativi sono in <i>corsivo</i>.
+<h2 id="step1">Passo 1: upload</h2>
+<ul class="submissionHelp">
+ <li><span class="required">Tipologia del componente aggiuntivo</span> - Come impostazione predefinita la tipologia del componente aggiuntivo verrà determinata automaticamente in base al file caricato. Si consiglia di non modificare questo campo.</li>
+ <li><span class="required">File del componente aggiuntivo</span> - Il pacchetto del componente aggiuntivo, comprensivo del file install.rdf. Se il file è compatibile solo con una piattaforma specifica, selezionando la piattaforma sarà possibile caricare più file contemporaneamente.</li>
+ <li><span class="optional">Icona del componente aggiuntivo</span> - L'icona viene visualizzata accanto al nome del componente aggiuntivo ed è utilizzata nella finestra di installazione. Verrà automaticamente ridimensionata a 32x32 pixel, mantenendo le proporzioni originali.</li>
+ <li><span class="required">Locale predefinito</span> - Il locale predefinito di un componente aggiuntivo è il locale principale: se per un determinato componente aggiuntivo il locale utilizzato da un utente non è disponibile, la lingua utilizzata sarà quella del locale predefinito.</li>
+ <li><span class="optional">Non effettuare la revisione delle informazioni per questa versione del componente aggiuntivo</span> - Questo campo verrà visualizzato nel caso in cui si stia aggiornando un componente aggiuntivo esistente. Selezionando questa casella si passerà direttamente al passo 3, dove sarà possibile inserire informazioni specifiche per questa versione.</li>
+</ul>
+
+<h2 id="step2">Passo 2: dettagli del componente aggiuntivo</h2>
+<ul class="submissionHelp">
+ <li><span class="required">Nome</span> - Nome del componente aggiuntivo nel locale predefinito.</li>
+ <li><span class="required">Autori</span> - Tutti gli utenti che hanno accesso ai dati di questo componente aggiuntivo (verranno visualizzati come autori nella scheda del componente aggiuntivo).</li>
+ <li><span class="required">Categorie</span> - Categorie applicabili al componente aggiuntivo.</li>
+ <li><span class="optional">Sito web</span> - Il sito web del componente aggiuntivo nel locale predefinito.</li>
+ <li><span class="required">Riepilogo</span> - Una sintesi delle informazioni relative al componente aggiuntivo nel locale predefinito. Questo campo ha una lunghezza massimo di 250 caratteri e verrà visualizzato nella scheda del componente aggiuntivo, così come nei risultati di ricerca e durante la navigazione tra i componenti disponibili.</li>
+ <li><span class="required">Descrizione</span> - Una descrizione del componente aggiuntivo nel locale predefinito. Questa informazione verrà visualizzata nella scheda del componente aggiuntivo accanto al riepilogo.</li>
+ <li><span class="optional">EULA</span> - L'accordo di licenza con l'utente finale (nel locale predefinito) che gli utenti devono accettare prima di scaricare il componente aggiuntivo.</li>
+ <li><span class="optional">Informativa sulla privacy</span> - L'informativa sulla privacy del componente aggiuntivo nel locale predefinito. Questa informativa spiega come verranno utilizzati i dati personali dell'utente finale; un collegamento all'informativa verrà visualizzato accanto al pulsante Installa nella scheda del componente aggiuntivo. Ulteriori informazioni sulle indicazioni da inserire nell'informativa e sulla necessità di fornirne una sono disponibili nella pagina <a href="%s">Policy dei componenti aggiuntivi</a>.</li>
+ <li><span class="optional">Permetti agli utenti di visualizzare i sorgenti online</span> - Questa opzione permetterà agli utenti di visualizzare online i sorgenti del componente aggiuntivo.</li>
+ <li><span class="optional">Questa è una pre-release</span> - Attivando questa opzione si segnala che si sta inserendo una pre-release, o e versione "beta", del componente aggiuntivo. I componenti aggiuntivi in pre-release rimarranno nella sandbox e non potranno essere nominati per la pubblicazione finché sarà presente questo flag..</li>
+ <li><span class="optional">Questo componente aggiuntivo è specifico per un determinato sito web</span> - Attivando questa opzione si segnala che il componente aggiuntivo inserito è specifico per un singolo sito web: ad esempio si tratta di un componente aggiuntivo che modifica l'aspetto di un sito oppure ne visualizza il contenuto. Questo campo è utile per i revisori e potrebbe essere utilizzato in futuro come filtro per le ricerche.</li>
+ <li><span class="optional">Questo componente aggiuntivo richiede la presenza di software esterno</span> - Attivando questa opzione si segnala che il componente aggiuntivo richiede la presenza di software esterno per funzionare. Questo campo è utile per i revisori e potrebbe essere utilizzato in futuro come filtro per le ricerche.</li>
+</ul>
+
+<h2 id="step3">Passo 3: dettagli sulla versione</h2>
+<ul class="submissionHelp">
+ <li><span class="required optional">Note di versione</span> - Una sintesi oppure un elenco delle modifiche introdotte in questa versione. Si tratta di un campo facoltativo per le nuove estensioni mentre è obbligatorio per gli aggiornamenti.</li>
+ <li><span class="optional">Note per i revisori</span> - Questo campo può essere utilizzato per comunicare informazioni al revisore che controllerà questo componente aggiuntivo. Inserire in questo campo informazioni su account di test oppure delle note specifiche.</li>
+</ul>
+
+<h2 id="step4">Passo 4: localizzazione</h2>
+In questa sezione è possibile localizzare i campi dell'estensione in tutte le lingue supportate. Fare clic su un locale per inserire la traduzione. \ No newline at end of file
diff --git a/site/app/locale/ja/LC_MESSAGES/messages.mo b/site/app/locale/ja/LC_MESSAGES/messages.mo
new file mode 100644
index 0000000..9dd2b3b
--- /dev/null
+++ b/site/app/locale/ja/LC_MESSAGES/messages.mo
Binary files differ
diff --git a/site/app/locale/ja/LC_MESSAGES/messages.po b/site/app/locale/ja/LC_MESSAGES/messages.po
new file mode 100644
index 0000000..99e0ba6
--- /dev/null
+++ b/site/app/locale/ja/LC_MESSAGES/messages.po
@@ -0,0 +1,7351 @@
+# Remora Preliminary Language File
+# Copyright (C) 2006 Mozilla Corporation
+# This file is distributed under the same license as the REMORA package.
+# Wil Clouser <clouserw@mozilla.com>, 2006.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: REMORA 0.1\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2009-01-16 11:45-0800\n"
+"PO-Revision-Date: 2009-05-26 13:17+0900\n"
+"Last-Translator: Wil Clouser <clouserw@mozilla.com>\n"
+"Language-Team: Kohei Yoshino <yoshino@mozilla-japan.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=n != 1;\n"
+
+#: views/addons/policy.thtml:98
+msgid "a_cancel_installation"
+msgstr "åŒæ„ã—ãªã„"
+
+#. This is the text that appears on buttons to download add-ons.
+#. %$1s is an optional string that only appears if the add-on is only available for
+#. a certain platform. Examples: (Windows) or (Linux)
+#. Note that the parentheses are included in the string. :(
+#: views/elements/amo2009/install.thtml:126
+#: views/elements/amo2009/install.thtml:227
+#: views/elements/amo2009/install.thtml:257
+#: views/elements/amo2009/install.thtml:300
+#: views/elements/amo2009/install.thtml:312 views/elements/install.thtml:73
+#: views/elements/install.thtml:181 views/elements/install.thtml:205
+#: views/elements/install.thtml:248 views/elements/install.thtml:260
+#: views/addons/plugins.thtml:66 views/addons/plugins.thtml:76
+#: views/addons/plugins.thtml:86 views/addons/plugins.thtml:96
+#: views/addons/plugins.thtml:119
+#, php-format
+msgid "a_download"
+msgstr "今ã™ãダウンロード %s"
+
+#: views/addons/policy.thtml:72
+msgid "a_eula_download"
+msgstr "åŒæ„ã—ã¦ãƒ€ã‚¦ãƒ³ãƒ­ãƒ¼ãƒ‰"
+
+#: views/addons/policy.thtml:74
+msgid "a_eula_install"
+msgstr "åŒæ„ã—ã¦ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«"
+
+#: views/elements/header.thtml:76 views/elements/header.thtml:82
+#: views/api/api_addon.thtml:55 views/api/collections_feed.thtml:75
+#: views/sharing_api/addon.thtml:64
+msgid "a_header_public"
+msgstr "公開ページ"
+
+#: views/elements/header.thtml:58 views/elements/header.thtml:75
+#: views/elements/header.thtml:80 views/api/api_addon.thtml:57
+#: views/api/collections_feed.thtml:77 views/sharing_api/addon.thtml:66
+msgid "a_header_sandbox"
+msgstr "サンドボックス"
+
+#. %s is a date in the _('date') format
+#: views/elements/amo2009/homepage_addon.thtml:115
+#: views/elements/addon_listitem.thtml:122 views/elements/feature.thtml:106
+#: views/addons/display.thtml:104 views/addons/browse_thumbs.thtml:73
+msgid "addon_detail_last_updated"
+msgstr "%s æ›´æ–°"
+
+#. %s is the version of the add-on. Example: 3.2a1
+#: views/elements/amo2009/addon_version_detail.thtml:51
+#: views/elements/addon_version_detail.thtml:51
+#, php-format
+msgid "addon_display_header_version"
+msgstr "ãƒãƒ¼ã‚¸ãƒ§ãƒ³ %s"
+
+#: views/addons/browse_thumbs.thtml:80
+msgid "addon_downloads"
+msgstr "ダウンロード"
+
+#: views/addons/display.thtml:147
+msgid "addon_downloads_total"
+msgstr "ダウンロード (累計)"
+
+#: views/elements/amo2009/homepage_addon.thtml:106
+#: views/elements/addon_listitem.thtml:115 views/elements/feature.thtml:101
+#: views/addons/category_landing.thtml:157 views/addons/display.thtml:146
+#: views/addons/browse_thumbs.thtml:80
+msgid "addon_downloads_weekly"
+msgstr "ダウンロード (週間)"
+
+#. %1 is the add-on count, %2 the category name
+#: views/addons/browse_thumbs.thtml:104 views/addons/browse.thtml:60
+#, php-format
+msgid "addon_list_category_totalcount"
+msgid_plural "addon_list_category_totalcount"
+msgstr[0] "%1$s 個ã®ã‚¢ãƒ‰ã‚ªãƒ³"
+msgstr[1] "%1$s 個ã®ã‚¢ãƒ‰ã‚ªãƒ³"
+
+#: views/elements/amo2009/addon_list_options.thtml:103
+#: views/elements/pagination.thtml:67
+#: views/elements/addon_list_options.thtml:94
+msgid "addon_list_perpage"
+msgstr "件ã”ã¨ã«è¡¨ç¤º"
+
+#: views/elements/amo2009/addon_list_options.thtml:84
+#: views/elements/addon_list_options.thtml:98
+msgid "addon_list_sortby"
+msgstr "並ã³æ›¿ãˆ:"
+
+#: views/helpers/addons_html.php:568 views/elements/amo2009/install.thtml:321
+#: views/elements/feature.thtml:89
+msgid "addon_listitem_flag_experimental"
+msgstr "実験的ãªã‚¢ãƒ‰ã‚ªãƒ³"
+
+#: views/helpers/addons_html.php:570
+msgid "addon_listitem_flag_recommended"
+msgstr "ãŠã™ã™ã‚ã®ã‚¢ãƒ‰ã‚ªãƒ³"
+
+#. %1 is the add-on name, %2 is the platform
+#: views/pages/js_constants.js.thtml:66
+msgid "addon_not_available_for_platform"
+msgstr "%1$s 㯠%2$s ã§ã¯åˆ©ç”¨ã§ãã¾ã›ã‚“"
+
+#. %1 is the add-on name
+#: views/addons/policy.thtml:101 views/addons/previews.thtml:60
+#: views/addons/versions.thtml:130 views/reviews/flag.thtml:61
+#: views/reviews/add.thtml:114 views/reviews/display.thtml:216
+#: views/reviews/review_added.thtml:57
+#, php-format
+msgid "addon_review_a_back_to_addon_x"
+msgstr "%1$s ã®ãƒšãƒ¼ã‚¸ã¸æˆ»ã‚‹"
+
+#. %1 is the add-on name
+#: views/reviews/flag.thtml:60 views/reviews/add.thtml:113
+#: views/reviews/review_added.thtml:56
+#, php-format
+msgid "addon_review_a_back_to_reviews"
+msgstr "レビューã®ãƒšãƒ¼ã‚¸ã¸æˆ»ã‚‹"
+
+#: views/reviews/add.thtml:85
+msgid "addon_review_add_rating_field"
+msgstr "評価:"
+
+#: views/reviews/add.thtml:102
+msgid "addon_review_add_review_field"
+msgstr "レビュー:"
+
+#: views/reviews/add.thtml:107
+msgid "addon_review_add_submit"
+msgstr "レビューをé€ä¿¡"
+
+#. %s is the name of the add-on
+#: views/reviews/add.thtml:51
+#, php-format
+msgid "addon_review_add_title"
+msgstr "%s ã®ãƒ¬ãƒ“ューを投稿"
+
+#: views/reviews/add.thtml:78
+msgid "addon_review_add_title_field"
+msgstr "タイトル・概è¦:"
+
+#: views/reviews/display.thtml:77 views/reviews/display.thtml:161
+msgid "addon_review_admin_delete"
+msgstr "削除"
+
+#: views/reviews/display.thtml:76
+msgid "addon_review_author_reply_link"
+msgstr "返信"
+
+#: views/reviews/delete.thtml:62
+msgid "addon_review_confirm_delete"
+msgstr "ã“ã®ãƒ¬ãƒ“ューを削除ã—ã¦ã‚‚よã‚ã—ã„ã§ã™ã‹ï¼Ÿ"
+
+#: views/reviews/delete.thtml:63
+msgid "addon_review_confirm_no"
+msgstr "ã„ã„ãˆ"
+
+#: views/reviews/delete.thtml:64
+msgid "addon_review_confirm_yes"
+msgstr "ã¯ã„"
+
+#: views/reviews/delete.thtml:48
+msgid "addon_review_delete_header"
+msgstr "レビューã®å‰Šé™¤"
+
+#: controllers/reviews_controller.php:449
+msgid "addon_review_deleted_successfully"
+msgstr "レビューã¯å‰Šé™¤ã•ã‚Œã¾ã—ãŸã€‚"
+
+#. %s is the name of the add-on
+#: views/reviews/add.thtml:51
+#, php-format
+msgid "addon_review_edit_title"
+msgstr "%s ã®ãƒ¬ãƒ“ューを編集"
+
+#. %1 is the count of characters entered as notes for the review flag reason.
+#: controllers/reviews_controller.php:539
+msgid "addon_review_flag_error_other_length"
+msgstr ""
+"レビューã¸ã®ãƒ•ãƒ©ã‚°ä»˜ã‘ã§å•é¡ŒãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚フラグ付ãレビューã¸ã®æ³¨é‡ˆã¯åŠè§’ "
+"10 文字以上 100 文字以下ã§ãªã‘ã‚Œã°ãªã‚Šã¾ã›ã‚“。入力ã•ã‚ŒãŸæ–‡å­—数㯠%1$s ã§ã™ã€‚"
+
+#. Removing an extra comma
+#: views/reviews/review_added.thtml:53
+msgid "addon_review_in_moderation"
+msgstr ""
+"注æ„: 投稿ã•ã‚ŒãŸãƒ¬ãƒ“ューã®å†…容ã¯ã€å…¬é–‹ãƒšãƒ¼ã‚¸ã«æŽ²è¼‰ã•ã‚Œã‚‹å‰ã«ã‚¨ãƒ‡ã‚£ã‚¿ã«ã‚ˆã£ã¦"
+"確èªã•ã‚Œã¾ã™ã€‚"
+
+#: views/reviews/add.thtml:57
+msgid "addon_review_in_reply_to"
+msgstr "開発者ã®è¿”ä¿¡:"
+
+#. %1 is the review count, %2 is the nickname or full name of the user.
+#: views/reviews/display.thtml:131
+#, php-format
+msgid "addon_review_others_by_user"
+msgid_plural "addon_review_others_by_user"
+msgstr[0] "%2$s ãŒä»¥å‰æŠ•ç¨¿ã—ãŸã“ã®ã‚¢ãƒ‰ã‚ªãƒ³ã®ãƒ¬ãƒ“ュー (%1$s) を見る"
+msgstr[1] "%2$s ãŒä»¥å‰æŠ•ç¨¿ã—ãŸã“ã®ã‚¢ãƒ‰ã‚ªãƒ³ã®ãƒ¬ãƒ“ュー (%1$s) を見る"
+
+#. %1 is the add-on name
+#: controllers/reviews_controller.php:201
+#: controllers/reviews_controller.php:250
+#: controllers/reviews_controller.php:345
+#: controllers/reviews_controller.php:424
+#, php-format
+msgid "addon_review_pagetitle"
+msgstr "%s ã®ãƒ¬ãƒ“ュー"
+
+#. %1 is the user, %2 is the (localized) date
+#: views/reviews/display.thtml:160
+#, php-format
+msgid "addon_review_reply_on_x_by_y"
+msgstr "%1$s ã«ã‚ˆã‚‹è¿”ä¿¡ - 投稿日時: %2$s"
+
+#: views/reviews/display.thtml:157
+msgid "addon_review_reply_prefix"
+msgstr "開発者ã®è¿”ä¿¡:"
+
+#: views/reviews/review_added.thtml:51
+msgid "addon_review_saved_successfully"
+msgstr "レビューã¯é€ä¿¡ã•ã‚Œã¾ã—ãŸã€‚"
+
+#: views/addons/display.thtml:354 views/reviews/display.thtml:72
+msgid "addon_reviewed_by_u_on_d"
+msgstr "投稿者: %1$s - 投稿日時: %2$s"
+
+#. %1 is the user, %2 is the (localized) date, %3 is the rating
+#: views/editors/reviews_queue.thtml:57 views/editors/reviews_queue.thtml:68
+#: views/reviews/add.thtml:63 views/reviews/delete.thtml:54
+#, php-format
+msgid "addon_reviewed_on_x_rated_y"
+msgstr "投稿者: %1$s - 投稿日時: %2$s - 評価: %3$s"
+
+#: views/elements/amo2009/addon_version_detail.thtml:52
+#: views/elements/addon_version_detail.thtml:52
+msgid "addon_version_permalink"
+msgstr "ã“ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã¸ã®å›ºå®šãƒªãƒ³ã‚¯"
+
+#. %1 is the current Application name (e.g. Firefox)
+#. %2 is the Application's version number
+#: views/addons/versions.thtml:140
+msgid "addon_versions_getlatestversion"
+msgstr "%1$s %2$s ã¨äº’æ›æ€§ã®ã‚る最新版"
+
+#: views/addons/display.thtml:447
+msgid "addons_author_addons_submit"
+msgstr "é€ä¿¡"
+
+#: views/elements/amo2009/homepage_addon.thtml:100
+#: views/elements/feature.thtml:95
+msgid "addons_author_tooltip"
+msgstr "作者ã®ãƒ—ロフィールを見る"
+
+#. %1 is the name of the Application (eg. Firefox)
+#: controllers/addons_controller.php:1296
+msgid "addons_browse_all_themes_title"
+msgstr "ã™ã¹ã¦ã®ãƒ†ãƒ¼ãƒžã‚’ブラウズ :: %1$s Add-ons"
+
+#. %s is the name of the category
+#: controllers/addons_controller.php:1016
+#, php-format
+msgid "addons_browse_browse_category"
+msgstr "%s をブラウズ"
+
+#. %1 is the name of the theme category (eg. Modern)
+#. %2 is the name of the Application (eg. Firefox)
+#: controllers/addons_controller.php:664
+msgid "addons_browse_categories_header_theme"
+msgstr "「%1$sã€ã‚«ãƒ†ã‚´ãƒªã®ãƒ†ãƒ¼ãƒžã‚’ブラウズ :: %2$s Add-ons"
+
+#: views/addons/display.thtml:249
+msgid "addons_display_a_license_what"
+msgstr "ã“ã‚Œã¯ä½•ï¼Ÿ"
+
+#: views/reviews/display.thtml:222
+msgid "addons_display_add_review"
+msgstr "レビューを投稿"
+
+#: views/addons/display.thtml:294
+msgid "addons_display_advanced_details"
+msgstr "詳細"
+
+#: views/addons/display.thtml:98
+msgid "addons_display_categories"
+msgstr "カテゴリ"
+
+#: views/addons/display.thtml:482
+msgid "addons_display_collection_add"
+msgstr "コレクションã¸è¿½åŠ :"
+
+#: views/addons/display.thtml:491
+msgid "addons_display_collection_add_new"
+msgstr "æ–°ã—ã„コレクション..."
+
+#: views/addons/display.thtml:487
+msgid "addons_display_collection_add_select_one"
+msgstr "コレクションをé¸æŠž..."
+
+#: views/addons/display.thtml:493
+msgid "addons_display_collection_add_submit"
+msgstr "公開"
+
+#. %1$s is the add-on name
+#. %2$s is the collection name, linked to the collection's page
+#: views/pages/js_constants.js.thtml:103 views/addons/display.thtml:61
+msgid "addons_display_collection_publish_success"
+msgstr "%1$s 㯠%2$s コレクションã¸è¿½åŠ ã•ã‚Œã¾ã—ãŸã€‚"
+
+#: views/addons/display.thtml:483
+msgid "addons_display_collection_whatsthis"
+msgstr "ã“ã‚Œã¯ä½•ï¼Ÿ"
+
+#. %1$s is a number
+#: views/addons/display.thtml:473
+msgid "addons_display_collections_more"
+msgid_plural "addons_display_collections_more"
+msgstr[0] "㨠%1$s 個ã®ã‚³ãƒ¬ã‚¯ã‚·ãƒ§ãƒ³"
+msgstr[1] "㨠%1$s 個ã®ã‚³ãƒ¬ã‚¯ã‚·ãƒ§ãƒ³"
+
+#: views/addons/display.thtml:403
+msgid "addons_display_detailed_review"
+msgstr "詳細"
+
+#: views/reviews/add.thtml:89 views/reviews/add.thtml:90
+msgid "addons_display_dont_like_it"
+msgstr "å«Œã„"
+
+#: views/reviews/display.thtml:220
+msgid "addons_display_edit_review"
+msgstr "レビューを編集"
+
+#: views/addons/display.thtml:132
+msgid "addons_display_has_privacy"
+msgstr "ã“ã®ã‚¢ãƒ‰ã‚ªãƒ³ã«ã¯ãƒ—ライãƒã‚·ãƒ¼ãƒãƒªã‚·ãƒ¼ãŒæä¾›ã•ã‚Œã¦ã„ã¾ã™ã€‚"
+
+#: views/reviews/add.thtml:87 views/reviews/add.thtml:88
+msgid "addons_display_hate_it"
+msgstr "大嫌ã„"
+
+#: views/addons/display.thtml:462
+msgid "addons_display_header_collections"
+msgstr "関連ã™ã‚‹ã‚³ãƒ¬ã‚¯ã‚·ãƒ§ãƒ³"
+
+#: views/addons/display.thtml:297
+msgid "addons_display_header_developer_comments"
+msgstr "作者ã®ã‚³ãƒ¡ãƒ³ãƒˆ"
+
+#: views/addons/display.thtml:230
+msgid "addons_display_header_homepage"
+msgstr "ホームページ"
+
+#: views/addons/display.thtml:247 views/addons/versions.thtml:110
+msgid "addons_display_header_license"
+msgstr "ソースコードライセンス"
+
+#: views/addons/display.thtml:337
+msgid "addons_display_header_reviews"
+msgstr "レビュー"
+
+#: views/addons/display.thtml:261
+msgid "addons_display_header_support"
+msgstr "サãƒãƒ¼ãƒˆ"
+
+#: views/reviews/add.thtml:91 views/reviews/add.thtml:92
+msgid "addons_display_like_it"
+msgstr "好ã"
+
+#: views/addons/display.thtml:210
+msgid "addons_display_long_description"
+msgstr "詳ã—ã„説明"
+
+#: views/reviews/add.thtml:95 views/reviews/add.thtml:96
+msgid "addons_display_love_it"
+msgstr "éžå¸¸ã«å¥½ã"
+
+#: views/addons/display.thtml:178
+msgid "addons_display_more_images"
+msgstr "ä»–ã®ç”»åƒ"
+
+#: views/addons/display.thtml:465
+msgid "addons_display_nocollections"
+msgstr "ã“ã®ã‚¢ãƒ‰ã‚ªãƒ³ã¯ã©ã®ã‚³ãƒ¬ã‚¯ã‚·ãƒ§ãƒ³ã«ã‚‚追加ã•ã‚Œã¦ã„ã¾ã›ã‚“。"
+
+#. %1$s is either an author's name or a comma separated list of authors. Using
+#. the list doesn't make sense in the English plural form so we ignore the
+#. variable.
+#: views/addons/display.thtml:436
+msgid "addons_display_other_addons_by"
+msgid_plural "addons_display_other_addons_by"
+msgstr[0] "%1$s ã«ã‚ˆã£ã¦ä½œæˆã•ã‚Œã¦ã„ã‚‹ä»–ã®ã‚¢ãƒ‰ã‚ªãƒ³"
+msgstr[1] "ã“れらã®ä½œè€…ã«ã‚ˆã£ã¦ä½œæˆã•ã‚Œã¦ã„ã‚‹ä»–ã®ã‚¢ãƒ‰ã‚ªãƒ³"
+
+#. %s is the name of the add-on and the add-on section. Example:
+#. Some Add-on :: Firefox Add-ons
+#. This should not be concatenated in the code and should be fixed.
+#: controllers/addons_controller.php:141 controllers/addons_controller.php:280
+#: controllers/addons_controller.php:1442
+#, php-format
+msgid "addons_display_pagetitle"
+msgstr "%s"
+
+#. %s is an email address
+#: views/addons/display.thtml:286
+#, php-format
+msgid "addons_display_paragraph_supportinfoemail"
+msgstr "ã“ã®ã‚¢ãƒ‰ã‚ªãƒ³ã®ã‚µãƒãƒ¼ãƒˆã¯é–‹ç™ºè€… (%s) ã‹ã‚‰å—ã‘られã¾ã™ã€‚"
+
+#. %$1s is a URL
+#. %$2s is an email address
+#: views/addons/display.thtml:269
+#, php-format
+msgid "addons_display_paragraph_supportinfoemailurl"
+msgstr ""
+"ã“ã®ã‚¢ãƒ‰ã‚ªãƒ³ã®ã‚µãƒãƒ¼ãƒˆã¯é–‹ç™ºè€…ã®ã‚µã‚¤ãƒˆ (%s) ã§å—ã‘られã¾ã™ã€‚メールã«ã‚ˆã‚‹é€£çµ¡"
+"å…ˆ (%s) も公開ã•ã‚Œã¦ã„ã¾ã™ã€‚"
+
+#. %s is a URL
+#: views/addons/display.thtml:278
+#, php-format
+msgid "addons_display_paragraph_supportinfourl"
+msgstr "ã“ã®ã‚¢ãƒ‰ã‚ªãƒ³ã®ã‚µãƒãƒ¼ãƒˆã¯é–‹ç™ºè€…ã®ã‚µã‚¤ãƒˆ (%s) ã§å—ã‘られã¾ã™ã€‚"
+
+#: views/addons/display.thtml:383
+msgid "addons_display_rate_it"
+msgstr "評価ã™ã‚‹"
+
+#: views/reviews/add.thtml:93 views/reviews/add.thtml:94
+msgid "addons_display_really_like_it"
+msgstr "大好ã"
+
+#: views/addons/display.thtml:410
+msgid "addons_display_review_etiquette"
+msgstr ""
+"ãƒã‚°å ±å‘Šã‚’レビューã¨ã—ã¦æŠ•ç¨¿ã—ãªã„ã§ãã ã•ã„。ã‚ãªãŸã®ãƒ¡ãƒ¼ãƒ«ã‚¢ãƒ‰ãƒ¬ã‚¹ã¯ã‚¢ãƒ‰ã‚ª"
+"ン作者ã«å…¬é–‹ã•ã‚Œã¾ã›ã‚“ã®ã§ã€ä½œè€…ãŒå•é¡Œè§£æ±ºã®ãŸã‚ã‚ãªãŸã«å”力をãŠé¡˜ã„ã—ãŸã„ã¨"
+"æ€ã£ã¦ã‚‚ã€é€£çµ¡ã‚’å–ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“。"
+
+#. %1 is the review guidelines link
+#: views/addons/display.thtml:417
+msgid "addons_display_review_guidelines_link"
+msgstr "<a href=\"%s\">レビューガイドライン</a>"
+
+#. %1 is the support section link
+#: views/addons/display.thtml:414
+msgid "addons_display_review_see_support"
+msgstr ""
+"ã“ã®ã‚¢ãƒ‰ã‚ªãƒ³ã«ã¤ã„ã¦ä½•ã‹ã‚µãƒãƒ¼ãƒˆã‚’å¿…è¦ã¨ã•ã‚Œã¦ã„ã‚‹å ´åˆã¯ã€<a href=\"%1$s\">サ"
+"ãƒãƒ¼ãƒˆ</a> ã®é …目をå‚ç…§ã—ã¦ãã ã•ã„。"
+
+#: views/addons/display.thtml:404
+msgid "addons_display_review_submit"
+msgstr "é€ä¿¡"
+
+#: views/addons/display.thtml:430
+#, php-format
+msgid "addons_display_see_all_addons"
+msgstr "「%1$sã€ã‚«ãƒ†ã‚´ãƒªã®ã™ã¹ã¦ã®ã‚¢ãƒ‰ã‚ªãƒ³ã‚’見る"
+
+#. %1 is the number of reviews
+#: views/addons/display.thtml:364
+#, php-format
+msgid "addons_display_see_all_reviews"
+msgstr "ã™ã¹ã¦ã®ãƒ¬ãƒ“ュー (%1$s) を表示"
+
+#: views/addons/display.thtml:219
+msgid "addons_display_see_all_versions"
+msgstr "ã™ã¹ã¦ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã‚’表示"
+
+#: views/addons/display.thtml:321 views/addons/versions.thtml:117
+msgid "addons_display_view_source"
+msgstr "ソースを表示"
+
+#: views/addons/display.thtml:324
+msgid "addons_display_view_stats"
+msgstr "統計を表示"
+
+#: views/addons/display.thtml:376
+msgid "addons_display_what_do_you_think"
+msgstr "ã‚ãªãŸã®æ„見をèžã‹ã›ã¦ãã ã•ã„"
+
+#: views/elements/app_compatibility.thtml:49
+msgid "addons_display_workswith"
+msgstr "対応ãƒãƒ¼ã‚¸ãƒ§ãƒ³"
+
+#: views/addons/home.thtml:112
+msgid "addons_home_browse_new"
+msgstr "最近追加ã•ã‚ŒãŸã‚¢ãƒ‰ã‚ªãƒ³"
+
+#: views/addons/home.thtml:110
+msgid "addons_home_browse_popular"
+msgstr "人気ã®ã‚¢ãƒ‰ã‚ªãƒ³"
+
+#: views/addons/home.thtml:108
+msgid "addons_home_browse_recommended"
+msgstr "ãŠã™ã™ã‚ã®ã‚¢ãƒ‰ã‚ªãƒ³"
+
+#: views/addons/home.thtml:127 views/addons/home.thtml:134
+#: views/addons/home.thtml:141 views/addons/home.thtml:148
+msgid "addons_home_browse_subscribe"
+msgstr "購読"
+
+#: views/addons/home.thtml:101
+msgid "addons_home_browse_title"
+msgstr "アドオンをブラウズ"
+
+#: views/addons/home.thtml:114
+msgid "addons_home_browse_updated"
+msgstr "最近更新ã•ã‚ŒãŸã‚¢ãƒ‰ã‚ªãƒ³"
+
+#: views/elements/amo2009/homepage_addon.thtml:100
+#: views/elements/addon_discussionheader.thtml:83
+#: views/elements/addon_listitem.thtml:109 views/elements/feature.thtml:95
+#: views/addons/category_landing.thtml:66 views/addons/policy.thtml:57
+#: views/addons/display.thtml:70 views/addons/home.thtml:178
+msgid "addons_home_by"
+msgstr "作者:"
+
+#: views/addons/home.thtml:169
+msgid "addons_home_collection_popular_title"
+msgstr "人気ã®ã‚³ãƒ¬ã‚¯ã‚·ãƒ§ãƒ³"
+
+#: views/elements/amo2009/categories.thtml:69 views/addons/home.thtml:160
+msgid "addons_home_collections"
+msgstr "コレクション"
+
+#. %1$s is the count of addons in a collection
+#: views/elements/amo2009/collection_listing_item.thtml:51
+#: views/addons/home.thtml:185
+msgid "addons_home_collections_addon_count"
+msgid_plural "addons_home_collections_addon_count"
+msgstr[0] "<strong>%1$s</strong> 個ã®ã‚¢ãƒ‰ã‚ªãƒ³"
+msgstr[1] "<strong>%1$s</strong> 個ã®ã‚¢ãƒ‰ã‚ªãƒ³"
+
+#: views/addons/home.thtml:196
+msgid "addons_home_collections_all"
+msgstr "ã™ã¹ã¦ã®ã‚³ãƒ¬ã‚¯ã‚·ãƒ§ãƒ³ã‚’見る"
+
+#: views/addons/home.thtml:162
+msgid "addons_home_collections_intro"
+msgstr ""
+"コレクションã¯ã€ã‚¢ãƒ‰ã‚ªãƒ³ã‚’分類ã€èª¿å’Œã€ä¸€è‡´ã€æ··åˆã•ã›ã‚‹ãŸã‚ã®æ–¹æ³•ã§ã™ã€‚ä»–ã®äºº"
+"ãŒä½œã£ãŸã‚³ãƒ¬ã‚¯ã‚·ãƒ§ãƒ³ã‚’購読ã—ãŸã‚Šã€è‡ªåˆ†ã§ã‚³ãƒ¬ã‚¯ã‚·ãƒ§ãƒ³ã‚’作るã“ã¨ãŒã§ãã¾ã™ã€‚"
+
+#. %1$s is the count of subscribers for a collection
+#: views/elements/amo2009/collection_listing_item.thtml:58
+#: views/collections/detail.thtml:96 views/addons/home.thtml:189
+msgid "addons_home_collections_subscribers"
+msgid_plural "addons_home_collections_subscribers"
+msgstr[0] "<strong>%1$s</strong> 人ã®è³¼èª­è€…"
+msgstr[1] "<strong>%1$s</strong> 人ã®è³¼èª­è€…"
+
+#: views/addons/searchengines.thtml:54 views/addons/themes_landing.thtml:49
+msgid "addons_home_feature_head"
+msgstr "スタッフã®ãŠã™ã™ã‚"
+
+#: controllers/search_controller.php:218 controllers/addons_controller.php:176
+#: controllers/addons_controller.php:428 controllers/addons_controller.php:671
+#: controllers/addons_controller.php:871
+#: controllers/addons_controller.php:1103
+#: controllers/addons_controller.php:1242
+#: controllers/addons_controller.php:1298
+#, php-format
+msgid "addons_home_header_details"
+msgstr ""
+"アドオンを使ãˆã°ã€%1$s ã®æ©Ÿèƒ½ã‚’æ‹¡å¼µã—ã¦è‡ªåˆ†å¥½ã¿ã«ã‚«ã‚¹ã‚¿ãƒžã‚¤ã‚ºã§ãã¾ã™ã€‚ãœã²ãŠ"
+"æ°—ã«å…¥ã‚Šã®ã‚¢ãƒ‰ã‚ªãƒ³ã‚’見ã¤ã‘ã¦ã¿ã¾ã—ょã†ã€‚注æ„: ã“ã®ã‚µã‚¤ãƒˆã«ç™»éŒ²ã•ã‚Œã¦ã„るアド"
+"オンã¯ã€ã¾ã ã»ã¨ã‚“ã©ãŒæ—¥æœ¬èªžåŒ–ã•ã‚Œã¦ã„ã¾ã›ã‚“。日本語化ã•ã‚Œã¦ã„るアドオンã®ä¸€"
+"覧㯠Mozilla Japan ã®ã‚µã‚¤ãƒˆ (https://addons.mozilla.jp/) ã§ã”覧ã„ãŸã ã‘ã¾ã™ã€‚"
+
+#. %1$s is the HTML collection name link.
+#: views/elements/amo2009/teaser_collections.thtml:107
+msgid "addons_home_introduction_collection_link"
+msgstr "ã“ã‚ŒãŒæ°—ã«å…¥ã‚Šã¾ã—ãŸã‹ï¼Ÿ %1$s ã§ã‚‚ã£ã¨å¤šãã®ã‚¢ãƒ‰ã‚ªãƒ³ã‚’見ã¤ã‘ã¾ã—ょã†ã€‚"
+
+#: views/elements/amo2009/teaser_collections.thtml:60
+msgid "addons_home_introduction_extras"
+msgstr ""
+"自分ã®ãƒ‹ãƒ¼ã‚ºã«åˆã‚ã›ã¦ Firefox をカスタマイズã€æ‹¡å¼µã§ãã‚‹ã€<strong>5000 以上"
+"ã®ç„¡æ–™ã®è¿½åŠ æ©Ÿèƒ½</strong>ã§ã™ã€‚"
+
+#: views/elements/amo2009/teaser_collections.thtml:55
+msgid "addons_home_introduction_header"
+msgstr "アドオンã¨ã¯ï¼Ÿ"
+
+#: views/elements/amo2009/teaser_collections.thtml:72
+msgid "addons_home_introduction_install"
+msgstr ""
+"<strong>インストールã¯ç°¡å˜</strong>ã§ã€æ–°ãƒãƒ¼ã‚¸ãƒ§ãƒ³ãŒå…¬é–‹ã•ã‚ŒãŸã¨ãã¯è‡ªå‹•çš„ã«"
+"ãŠçŸ¥ã‚‰ã›ãŒè¡¨ç¤ºã•ã‚Œã¾ã™ã€‚"
+
+#: views/elements/amo2009/teaser_collections.thtml:45
+msgid "addons_home_introduction_name"
+msgstr "イントロダクション"
+
+#: views/elements/amo2009/teaser_collections.thtml:66
+msgid "addons_home_introduction_themes"
+msgstr ""
+"<strong>一般的ãªä½œæ¥­ã‚’支æ´ã™ã‚‹</strong>ã€å„種ツールãƒãƒ¼ã€ãƒ†ãƒ¼ãƒžã€æ¤œç´¢ã‚¨ãƒ³ã‚¸ãƒ³"
+"ã§ã™ã€‚"
+
+#: views/addons/home.thtml:161
+msgid "addons_home_new_indicator"
+msgstr "æ–°ç€ï¼"
+
+#: views/elements/app_chooser.thtml:48 views/layouts/amo2009.thtml:257
+msgid "addons_home_other_applications"
+msgstr "ä»–ã®ã‚¢ãƒ—リケーション"
+
+#. %1$s is the application the user is browsing. Examples: Thunderbird, Firefox,
+#. Sunbird
+#: views/pages/collector_faq.thtml:49 views/pages/collector_firstrun.thtml:42
+#: views/pages/collector.thtml:46 views/pages/collector_features.thtml:54
+#: controllers/developers_controller.php:87
+#: controllers/compatibility_controller.php:72
+#: controllers/components/simple_acl.php:81 controllers/components/amo.php:607
+#: controllers/statistics_controller.php:60
+#: controllers/statistics_controller.php:240
+#: controllers/previews_controller.php:67 controllers/users_controller.php:90
+#: controllers/users_controller.php:223 controllers/users_controller.php:330
+#: controllers/users_controller.php:414 controllers/users_controller.php:708
+#: controllers/users_controller.php:723 controllers/reviews_controller.php:204
+#: controllers/reviews_controller.php:251
+#: controllers/reviews_controller.php:346
+#: controllers/reviews_controller.php:425
+#: controllers/search_controller.php:185 controllers/search_controller.php:297
+#: controllers/search_controller.php:301 controllers/addons_controller.php:147
+#: controllers/addons_controller.php:280 controllers/addons_controller.php:370
+#: controllers/addons_controller.php:667 controllers/addons_controller.php:874
+#: controllers/addons_controller.php:1019
+#: controllers/addons_controller.php:1034
+#: controllers/addons_controller.php:1101
+#: controllers/addons_controller.php:1121
+#: controllers/addons_controller.php:1240
+#: controllers/addons_controller.php:1357
+#: controllers/addons_controller.php:1364
+#: controllers/addons_controller.php:1442
+#: controllers/addons_controller.php:1477
+#: controllers/addons_controller.php:1538
+#: controllers/addons_controller.php:1543
+#: controllers/editors_controller.php:64 controllers/pages_controller.php:132
+#: controllers/groups_controller.php:65 controllers/groups_controller.php:71
+#: controllers/groups_controller.php:89 controllers/groups_controller.php:111
+#: controllers/collections_controller.php:57
+#: controllers/collections_controller.php:121
+#: controllers/collections_controller.php:205
+#: controllers/collections_controller.php:365
+#: controllers/collections_controller.php:404
+#: controllers/collections_controller.php:466
+#: controllers/collections_controller.php:538
+#: controllers/collections_controller.php:828
+#: controllers/localizers_controller.php:72
+#, php-format
+msgid "addons_home_pagetitle"
+msgstr "%1$s Add-ons"
+
+#. %1$s is the number of addons downloaded
+#: views/addons/home.thtml:57
+#, php-format
+msgid "addons_home_stats_downloaded"
+msgid_plural "addons_home_stats_downloaded"
+msgstr[0] ""
+"<strong>%1$s</strong> <span>個ã®ã‚¢ãƒ‰ã‚ªãƒ³ãŒãƒ€ã‚¦ãƒ³ãƒ­ãƒ¼ãƒ‰ã•ã‚Œã¾ã—ãŸ</span>"
+msgstr[1] ""
+"<strong>%1$s</strong> <span>個ã®ã‚¢ãƒ‰ã‚ªãƒ³ãŒãƒ€ã‚¦ãƒ³ãƒ­ãƒ¼ãƒ‰ã•ã‚Œã¾ã—ãŸ</span>"
+
+#. %1$s is the number of addons in use
+#: views/addons/home.thtml:63
+#, php-format
+msgid "addons_home_stats_inuse"
+msgid_plural "addons_home_stats_inuse"
+msgstr[0] "<strong>%1$s</strong> <span>個ã®ã‚¢ãƒ‰ã‚ªãƒ³ãŒåˆ©ç”¨ã•ã‚Œã¦ã„ã¾ã™</span>"
+msgstr[1] "<strong>%1$s</strong> <span>個ã®ã‚¢ãƒ‰ã‚ªãƒ³ãŒåˆ©ç”¨ã•ã‚Œã¦ã„ã¾ã™</span>"
+
+#: views/addons/home.thtml:136
+msgid "addons_home_view_all_newest_title"
+msgstr "最近公開ã•ã‚ŒãŸã‚¢ãƒ‰ã‚ªãƒ³ã‚’ã™ã¹ã¦è¦‹ã‚‹"
+
+#: views/addons/home.thtml:129
+msgid "addons_home_view_all_popular_title"
+msgstr "人気ã®ã‚¢ãƒ‰ã‚ªãƒ³ã‚’ã™ã¹ã¦è¦‹ã‚‹"
+
+#: views/addons/home.thtml:150
+msgid "addons_home_view_all_recommended_title"
+msgstr "ãŠã™ã™ã‚ã®ã‚¢ãƒ‰ã‚ªãƒ³ã‚’ã™ã¹ã¦è¦‹ã‚‹"
+
+#: views/addons/home.thtml:143
+msgid "addons_home_view_all_updated_title"
+msgstr "最近更新ã•ã‚ŒãŸã‚¢ãƒ‰ã‚ªãƒ³ã‚’ã™ã¹ã¦è¦‹ã‚‹"
+
+#: views/elements/amo2009/install.thtml:334 views/elements/install.thtml:112
+msgid "addons_install_in_sunbird"
+msgstr ""
+"<ol><li>以下ã®ãƒªãƒ³ã‚¯ã‚’クリックã—ã¦ãƒ•ã‚¡ã‚¤ãƒ«ã‚’ä¿å­˜ã—ã¦ãã ã•ã„。</"
+"li><li>Mozilla Sunbird ã® [ツール] メニューã‹ã‚‰ [アドオン] ã‚’é¸æŠžã—ã¾ã™ã€‚</"
+"li><li>[インストール] ボタンをクリックã—ã€ãƒ€ã‚¦ãƒ³ãƒ­ãƒ¼ãƒ‰ã—ãŸãƒ•ã‚¡ã‚¤ãƒ«ã‚’見ã¤ã‘ã¦"
+"é¸æŠžã—ãŸã‚‰ [OK] をクリックã—ã¾ã™ã€‚</li></ol>"
+
+#: views/elements/amo2009/install.thtml:333 views/elements/install.thtml:111
+msgid "addons_install_in_sunbird_title"
+msgstr "Sunbird ã¸ã®ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«æ–¹æ³•"
+
+#: views/elements/amo2009/install.thtml:331 views/elements/install.thtml:106
+msgid "addons_install_in_thunderbird"
+msgstr ""
+"<ol><li>下ã®ãƒªãƒ³ã‚¯ã‚’å³ã‚¯ãƒªãƒƒã‚¯ã—㦠[åå‰ã‚’付ã‘ã¦ãƒªãƒ³ã‚¯å…ˆã‚’ä¿å­˜] ã‚’é¸æŠžã—ã€"
+"ファイルをãƒãƒ¼ãƒ‰ãƒ‡ã‚£ã‚¹ã‚¯ã«ãƒ€ã‚¦ãƒ³ãƒ­ãƒ¼ãƒ‰ã—ã¾ã™ã€‚</li><li>Thunderbird ã‚’é–‹ãã€"
+"[ツール] メニューã‹ã‚‰ [アドオン] ã‚’é¸æŠžã—ã¾ã™ã€‚</li><li>[インストール] ボタン"
+"をクリックã—ã¦ã€ãƒ€ã‚¦ãƒ³ãƒ­ãƒ¼ãƒ‰ã—ãŸãƒ•ã‚¡ã‚¤ãƒ«ã‚’é¸æŠžã—ã€[OK] をクリックã—ã¾ã™ã€‚"
+
+#: views/elements/amo2009/install.thtml:330 views/elements/install.thtml:105
+msgid "addons_install_in_thunderbird_title"
+msgstr "Thunderbird ã¸ã®ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«æ–¹æ³•"
+
+#: views/elements/amo2009/addon_list_options.thtml:108
+#: views/elements/addon_list_options.thtml:105
+msgid "addons_options_show_experimental"
+msgstr "実験的ãªã‚¢ãƒ‰ã‚ªãƒ³ã‚’表示ã™ã‚‹"
+
+#: views/elements/amo2009/addon_list_options.thtml:113
+#: views/elements/addon_list_options.thtml:109
+msgid "addons_options_submit"
+msgstr "移動"
+
+#: views/addons/plugins.thtml:63 views/addons/plugins.thtml:73
+#: views/addons/plugins.thtml:83 views/addons/plugins.thtml:93
+#: views/addons/plugins.thtml:103 views/addons/plugins.thtml:116
+#: views/addons/plugins.thtml:126
+msgid "addons_plugins_by"
+msgstr "開発元:"
+
+#: views/addons/plugins.thtml:107
+msgid "addons_plugins_for_linux"
+msgstr "Linux 版"
+
+#: views/addons/plugins.thtml:108 views/addons/plugins.thtml:131
+msgid "addons_plugins_for_macosx"
+msgstr "Mac OS X 版"
+
+#: views/addons/plugins.thtml:106 views/addons/plugins.thtml:129
+#: views/addons/plugins.thtml:130
+msgid "addons_plugins_for_windows"
+msgstr "Windows 版"
+
+#. %1$s is a URL
+#: views/addons/plugins.thtml:139
+#, php-format
+msgid "addons_plugins_looking_for_more"
+msgstr ""
+"ã“ã®ãƒšãƒ¼ã‚¸ã§ã¯ã€æœ€ã‚‚一般的ã§äººæ°—ã®ã‚るプラグインã ã‘ã‚’ã”紹介ã—ã¦ã„ã¾ã™ã€‚"
+"Firefox ãªã© Mozilla ベースã®ãƒ–ラウザã§åˆ©ç”¨å¯èƒ½ãªä»–ã®ãƒ—ラグインã®æƒ…å ±ã¯ã€%1"
+"$s ã‚’ã”覧ãã ã•ã„。"
+
+#: views/addons/plugins.thtml:137
+msgid "addons_plugins_looking_for_plugin"
+msgstr "ã“ã“ã«è¼‰ã£ã¦ã„ãªã„プラグインをãŠæŽ¢ã—ã§ã™ã‹ï¼Ÿ"
+
+#: views/addons/plugins.thtml:58
+msgid "addons_plugins_main_description"
+msgstr ""
+"プラグインã¯ã€ç‰¹æ®Šãªå½¢å¼ã®ç”»åƒã‚’表示ã—ãŸã‚Šã€ãƒžãƒ«ãƒãƒ¡ãƒ‡ã‚£ã‚¢ãƒ•ã‚¡ã‚¤ãƒ«ã‚’å†ç”Ÿã™ã‚‹"
+"å ´åˆãªã©ã€ãƒ–ラウザãŒç‰¹å®šã®æ©Ÿèƒ½ã‚’実行ã§ãるよã†ã«ã™ã‚‹å½¹å‰²ã‚’æžœãŸã—ã¾ã™ã€‚ブラウ"
+"ザã®æ©Ÿèƒ½ã‚’追加ã—ãŸã‚Šå¤‰æ›´ã‚’加ãˆã‚‹æ‹¡å¼µæ©Ÿèƒ½ã¨ã¯è‹¥å¹²æ€§è³ªãŒç•°ãªã‚Šã¾ã™ã€‚"
+
+#. %1$s is the application name. Example: Firefox, Thunderbird, Sunbird
+#: controllers/addons_controller.php:1122
+#, php-format
+msgid "addons_plugins_main_header"
+msgstr "%1$s 用ã®ä¸€èˆ¬çš„ãªãƒ—ラグイン"
+
+#: controllers/components/amo.php:698 controllers/addons_controller.php:1121
+msgid "addons_plugins_pagetitle"
+msgstr "プラグイン"
+
+#: views/addons/plugins.thtml:68 views/addons/plugins.thtml:78
+#: views/addons/plugins.thtml:88 views/addons/plugins.thtml:98
+#: views/addons/plugins.thtml:110 views/addons/plugins.thtml:121
+#: views/addons/plugins.thtml:133
+msgid "addons_plugins_support_documentation"
+msgstr "サãƒãƒ¼ãƒˆæƒ…å ±: "
+
+#. %s is the name of the add-on
+#: views/addons/policy.thtml:61
+#, php-format
+msgid "addons_policy_eula_require"
+msgstr ""
+"%s をインストールã™ã‚‹ã«ã¯ã€ä»¥ä¸‹ã®ã‚¨ãƒ³ãƒ‰ãƒ¦ãƒ¼ã‚¶ãƒ©ã‚¤ã‚»ãƒ³ã‚¹å¥‘ç´„ã«åŒæ„ã™ã‚‹å¿…è¦ãŒã‚"
+"ã‚Šã¾ã™ã€‚"
+
+#. %1 is the add-on name
+#: controllers/addons_controller.php:1476
+#, php-format
+msgid "addons_previews_pagetitle"
+msgstr "%s ã®ãƒ—レビュー画åƒ"
+
+#: views/addons/category_landing.thtml:135
+msgid "addons_recently_added"
+msgstr "最近追加ã•ã‚ŒãŸã‚¢ãƒ‰ã‚ªãƒ³"
+
+#: views/addons/recommended.thtml:51 controllers/addons_controller.php:1365
+msgid "addons_recommended_introduction"
+msgstr ""
+"アドオンã«ã¯ãŸãã•ã‚“ã®ç¨®é¡žãŒã‚ã‚Šã¾ã™ã®ã§ã€ãŠæ°—ã«å…¥ã‚Šã®ã‚‚ã®ãŒãã£ã¨è¦‹ã¤ã‹ã‚‹ã¯"
+"ãšã§ã™ã€‚ã“ã“ã§ã¯ã‚¹ã‚¿ãƒƒãƒ•ãŠã™ã™ã‚ã®ã‚¢ãƒ‰ã‚ªãƒ³ã‚’ã”紹介ã—ã¾ã™ã€‚ãœã²ãŠè©¦ã—ãã ã•"
+"ã„。"
+
+#: controllers/addons_controller.php:1357
+#: controllers/addons_controller.php:1364
+msgid "addons_recommended_pagetitle"
+msgstr "ãŠã™ã™ã‚ã®ã‚¢ãƒ‰ã‚ªãƒ³"
+
+#: controllers/addons_controller.php:1360
+msgid "addons_recommended_title"
+msgstr "ãŠã™ã™ã‚ã®ã‚¢ãƒ‰ã‚ªãƒ³"
+
+#: views/addons/searchengines.thtml:136
+msgid "addons_searchengines_additional_resources"
+msgstr "関連情報"
+
+#. link text devmo
+#: views/addons/searchengines.thtml:141
+msgid "addons_searchengines_devmo_link"
+msgstr "Mozilla Developer Center"
+
+#: views/pages/js_constants.js.thtml:67
+msgid "addons_searchengines_error_mozilla_browser_required"
+msgstr ""
+"申ã—訳ã‚ã‚Šã¾ã›ã‚“。検索エンジンをインストールã™ã‚‹ã«ã¯ã€Firefox ãªã© Mozilla "
+"ベースã®ãƒ–ラウザをã”利用ãã ã•ã„。"
+
+#: views/addons/searchengines.thtml:49
+msgid "addons_searchengines_error_nojavascript"
+msgstr ""
+"検索エンジンã®ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã«ã¯ JavaScript を使用ã—ã¾ã™ãŒã€ãŠä½¿ã„ã®ãƒ–ラウザã§"
+"ã¯ãã®è¨­å®šãŒç„¡åŠ¹ã«ãªã£ã¦ã„ã¾ã™ã€‚インストールを行ã†ã«ã¯ JavaScript ã®è¨­å®šã‚’有"
+"効ã«ã—ã¦ãã ã•ã„。"
+
+#. %1 is "make your own" link
+#. %2 is MDC link
+#: views/addons/searchengines.thtml:139
+msgid "addons_searchengines_learn_howto"
+msgstr "%1$s 方法ã¯ã€%2$s ã‚’ã”覧ãã ã•ã„。"
+
+#. link path to search plugins instructions, relative to devmo
+#: views/addons/searchengines.thtml:140
+msgid "addons_searchengines_makeyourown_href"
+msgstr "/ja/Creating_OpenSearch_plugins_for_Firefox"
+
+#. link text for "make your own" (opensearch engine)
+#: views/addons/searchengines.thtml:140
+msgid "addons_searchengines_makeyourown_link"
+msgstr "独自ã®æ¤œç´¢ã‚¨ãƒ³ã‚¸ãƒ³ã‚’作æˆã™ã‚‹"
+
+#. %1 is the link to mycroft.mozdev.org
+#: views/addons/searchengines.thtml:138
+msgid "addons_searchengines_more"
+msgstr "%1$s ã§ã•ã‚‰ã«å¤šãã®æ¤œç´¢ã‚¨ãƒ³ã‚¸ãƒ³ã‚’ブラウズ"
+
+#. link text to mycroft.mozdev.org
+#: views/addons/searchengines.thtml:138
+msgid "addons_searchengines_mycroft_link"
+msgstr "mycroft.mozdev.org"
+
+#: controllers/addons_controller.php:1100
+#: controllers/addons_controller.php:1110
+msgid "addons_searchengines_pagetitle"
+msgstr "検索エンジン"
+
+#: views/addons/searchengines.thtml:143
+msgid "addons_searchengines_thanks"
+msgstr ""
+"ã“ã“ã§ã”紹介ã—ã¦ã„る検索エンジンã®ä½œæˆã«ã¯ Mycroft プロジェクトã®å”力をã„ãŸã "
+"ã„ã¦ã„ã¾ã™ã€‚"
+
+#: views/addons/display.thtml:154
+msgid "addons_share_button_text"
+msgstr "ã“ã®ã‚¢ãƒ‰ã‚ªãƒ³ã‚’共有"
+
+#: controllers/addons_controller.php:89
+msgid "addons_share_label_delicious"
+msgstr "Delicious ã¸è¿½åŠ "
+
+#: controllers/addons_controller.php:77
+msgid "addons_share_label_digg"
+msgstr "Digg ã¸æŠ•ç¨¿"
+
+#: controllers/addons_controller.php:83
+msgid "addons_share_label_facebook"
+msgstr "Facebook ã¸æŠ•ç¨¿"
+
+#: controllers/addons_controller.php:101
+msgid "addons_share_label_friendfeed"
+msgstr "FriendFeed ã§å…±æœ‰"
+
+#: controllers/addons_controller.php:95
+msgid "addons_share_label_myspace"
+msgstr "MySpace ã¸æŠ•ç¨¿"
+
+#: controllers/components/amo.php:201 controllers/components/amo.php:229
+msgid "addons_status_disabled"
+msgstr "無効"
+
+#: controllers/components/amo.php:191 controllers/components/amo.php:224
+msgid "addons_status_incomplete"
+msgstr "ä¸å®Œå…¨ãªãƒãƒ¼ã‚¸ãƒ§ãƒ³"
+
+#: controllers/components/amo.php:197 controllers/components/amo.php:227
+msgid "addons_status_nominated"
+msgstr "サンドボックス内 - 公開申請中"
+
+#: views/pages/js_constants.js.thtml:80 controllers/components/amo.php:195
+#: controllers/components/amo.php:226
+msgid "addons_status_pending"
+msgstr "サンドボックス内 - レビュー待ã¡"
+
+#: views/pages/js_constants.js.thtml:78 controllers/components/amo.php:199
+#: controllers/components/amo.php:228
+msgid "addons_status_public"
+msgstr "公開"
+
+#: views/pages/js_constants.js.thtml:79 controllers/components/amo.php:193
+#: controllers/components/amo.php:225
+msgid "addons_status_sandbox"
+msgstr "サンドボックス内"
+
+#: controllers/components/amo.php:203
+msgid "addons_status_unknown"
+msgstr "ä¸æ˜Ž"
+
+#: views/elements/amo2009/teaser_collections.thtml:91
+#: views/elements/amo2009/homepage_addon.thtml:99
+#: views/elements/feature.thtml:94
+msgid "addons_title_tooltip"
+msgstr "ã“ã®ã‚¢ãƒ‰ã‚ªãƒ³ã«é–¢ã™ã‚‹è©³ç´°"
+
+#: views/addons/category_landing.thtml:151
+msgid "addons_top_downloads"
+msgstr "人気ã®ã‚¢ãƒ‰ã‚ªãƒ³"
+
+#: views/addons/category_landing.thtml:165
+msgid "addons_top_rated"
+msgstr "評価ã®é«˜ã„アドオン"
+
+#: views/addons/versions.thtml:62
+msgid "addons_versions_careful"
+msgstr "ã“ã“ã«è¼‰ã£ã¦ã„ã‚‹ã®ã¯å¤ã„ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã§ã™"
+
+#: views/addons/versions.thtml:63
+msgid "addons_versions_careful_introduction"
+msgstr ""
+"ã“れらã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã¯ã€å‚考ã¨ã—ã¦ã€ã¾ãŸãƒ†ã‚¹ãƒˆç›®çš„ã§åˆ©ç”¨ã§ãるよã†ã«å…¬é–‹ã•ã‚Œã¦"
+"ã„ã¾ã™ã€‚特別ãªç†ç”±ãŒãªã„é™ã‚Šã€å¸¸ã«æœ€æ–°ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã‚’ã”利用ãã ã•ã„。"
+
+#: controllers/addons_controller.php:1549
+msgid "addons_versions_history"
+msgstr "ãƒãƒ¼ã‚¸ãƒ§ãƒ³å±¥æ­´ãƒ»å¤‰æ›´ç‚¹"
+
+#. %1$s is the add-on name
+#: controllers/addons_controller.php:1535
+#, php-format
+msgid "addons_versions_pagetitle"
+msgstr "%1$s ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³å±¥æ­´"
+
+#: controllers/groups_controller.php:71
+msgid "admin_group_add_pagetitle"
+msgstr "グループを追加"
+
+#: controllers/groups_controller.php:111
+msgid "admin_group_delete_pagetitle"
+msgstr "グループを削除"
+
+#. %s is a number to identify the group
+#: controllers/groups_controller.php:117
+#, php-format
+msgid "admin_group_deleted"
+msgstr "グループ (ID %s) ã¯å‰Šé™¤ã•ã‚Œã¾ã—ãŸ"
+
+#: controllers/groups_controller.php:89
+msgid "admin_group_edit_pagetitle"
+msgstr "グループを編集"
+
+#: controllers/groups_controller.php:92 controllers/groups_controller.php:113
+msgid "admin_group_error_invalid_id"
+msgstr "ä¸æ­£ãªã‚°ãƒ«ãƒ¼ãƒ— ID"
+
+#: controllers/groups_controller.php:65
+msgid "admin_group_pagetitle"
+msgstr "グループ管ç†è€…"
+
+#: controllers/groups_controller.php:77 controllers/groups_controller.php:99
+msgid "admin_group_saved"
+msgstr "グループã®è¨­å®šã¯ä¿å­˜ã•ã‚Œã¾ã—ãŸ"
+
+#: views/elements/amo2009/search.thtml:257 views/elements/search.thtml:239
+msgid "advanced_search_form"
+msgstr "検索オプション"
+
+#: views/elements/amo2009/search.thtml:126 views/elements/search.thtml:125
+msgid "advanced_search_form_any_time"
+msgstr "指定ãªã—"
+
+#: views/elements/amo2009/search.thtml:97
+#: views/elements/amo2009/search.thtml:110 views/elements/search.thtml:96
+#: views/elements/search.thtml:109
+msgid "advanced_search_form_any_type"
+msgstr "ã™ã¹ã¦"
+
+#: views/elements/amo2009/search.thtml:275 views/elements/search.thtml:254
+msgid "advanced_search_form_any_version"
+msgstr "ã™ã¹ã¦ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³"
+
+#: views/elements/amo2009/search.thtml:217 views/elements/search.thtml:212
+msgid "advanced_search_form_application"
+msgstr "アプリケーション"
+
+#: views/elements/amo2009/search.thtml:143 views/elements/search.thtml:142
+msgid "advanced_search_form_keyword_match"
+msgstr "一致順"
+
+#: views/elements/amo2009/search.thtml:251 views/elements/search.thtml:225
+msgid "advanced_search_form_lastupdate"
+msgstr "最終更新日"
+
+#: views/elements/amo2009/search.thtml:145 views/elements/search.thtml:144
+msgid "advanced_search_form_name"
+msgstr "タイトル"
+
+#: views/elements/amo2009/search.thtml:144 views/elements/search.thtml:143
+msgid "advanced_search_form_newest"
+msgstr "æ›´æ–°æ—¥"
+
+#: views/elements/amo2009/search.thtml:130 views/elements/search.thtml:129
+msgid "advanced_search_form_past_3_months"
+msgstr "3 ã‹æœˆä»¥å†…"
+
+#: views/elements/amo2009/search.thtml:131 views/elements/search.thtml:130
+msgid "advanced_search_form_past_6_months"
+msgstr "6 ã‹æœˆä»¥å†…"
+
+#: views/elements/amo2009/search.thtml:127 views/elements/search.thtml:126
+msgid "advanced_search_form_past_day"
+msgstr "24 時間以内"
+
+#: views/elements/amo2009/search.thtml:129 views/elements/search.thtml:128
+msgid "advanced_search_form_past_month"
+msgstr "1 ã‹æœˆä»¥å†…"
+
+#: views/elements/amo2009/search.thtml:128 views/elements/search.thtml:127
+msgid "advanced_search_form_past_week"
+msgstr "1 週間以内"
+
+#: views/elements/amo2009/search.thtml:132 views/elements/search.thtml:131
+msgid "advanced_search_form_past_year"
+msgstr "1 年以内"
+
+#: views/elements/amo2009/search.thtml:239 views/elements/search.thtml:230
+msgid "advanced_search_form_perpage"
+msgstr "表示件数"
+
+#: views/elements/amo2009/search.thtml:243 views/elements/search.thtml:224
+msgid "advanced_search_form_platform"
+msgstr "プラットフォーム"
+
+#: views/elements/amo2009/search.thtml:147 views/elements/search.thtml:146
+msgid "advanced_search_form_popularity"
+msgstr "ダウンロード数"
+
+#: views/elements/amo2009/search.thtml:146 views/elements/search.thtml:145
+msgid "advanced_search_form_rating"
+msgstr "評価"
+
+#: views/elements/amo2009/search.thtml:247 views/elements/search.thtml:231
+msgid "advanced_search_form_sortby"
+msgstr "並ã¹æ›¿ãˆ"
+
+#: views/elements/amo2009/search.thtml:227 views/elements/search.thtml:216
+msgid "advanced_search_form_to"
+msgstr "ã‹ã‚‰"
+
+#: views/elements/amo2009/search.thtml:257 views/elements/search.thtml:237
+msgid "advanced_search_form_toggle_tooltip"
+msgstr "検索オプションã®è¡¨ç¤ºãƒ»éžè¡¨ç¤ºã‚’切り替ãˆ"
+
+#: views/elements/amo2009/search.thtml:235 views/elements/search.thtml:223
+msgid "advanced_search_form_type"
+msgstr "種類"
+
+#: views/elements/amo2009/search.thtml:222 views/elements/search.thtml:214
+msgid "advanced_search_form_version"
+msgstr "ãƒãƒ¼ã‚¸ãƒ§ãƒ³"
+
+#: views/elements/amo2009/pagination.thtml:42
+msgid "amo2009_pagination_next_page"
+msgstr "次ã¸"
+
+#: views/elements/amo2009/pagination.thtml:41
+msgid "amo2009_pagination_previous_page"
+msgstr "å‰ã¸"
+
+#: views/pages/js_constants.js.thtml:96
+msgid "app_compat_ignore_check"
+msgstr "ãƒãƒ¼ã‚¸ãƒ§ãƒ³ãƒã‚§ãƒƒã‚¯ã‚’無視"
+
+#: views/pages/js_constants.js.thtml:72
+msgid "app_compat_older_firefox_only"
+msgstr "ã“ã®ã‚¢ãƒ‰ã‚ªãƒ³ã¯å¤ã„ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã® Firefox å‘ã‘ã§ã™"
+
+#. %1$s and %2$s are URLs
+#: views/pages/js_constants.js.thtml:74
+msgid "app_compat_older_version_or_ignore_check"
+msgstr ""
+"<a href=\"%1$s\">éŽåŽ»ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã‚’試ã™</a> ã‹ <a href=\"#\" onclick=\"%2$s"
+"\">ã“ã®ãƒã‚§ãƒƒã‚¯ã‚’無視</a> ã§ãã¾ã™"
+
+#. %1$s is a URL
+#: views/pages/js_constants.js.thtml:71
+msgid "app_compat_try_old_version"
+msgstr "<a href=\"%1$s\">å¤ã„ãƒãƒ¼ã‚¸ãƒ§ãƒ³</a> ã¯åˆ©ç”¨ã§ãã‚‹å¯èƒ½æ€§ã‚‚ã‚ã‚Šã¾ã™"
+
+#. %1$s is a URL
+#. %2$s is a version number. Example: 3.1
+#: views/pages/js_constants.js.thtml:73
+msgid "app_compat_unreleased_version"
+msgstr ""
+"ã“ã®ã‚¢ãƒ‰ã‚ªãƒ³ã¯ã€ã¾ã ãƒªãƒªãƒ¼ã‚¹ã•ã‚Œã¦ã„ãªã„ <a href=\"%1$s\">Firefox %2$s</a> ã‚’"
+"å¿…è¦ã¨ã—ã¦ã„ã¾ã™ã€‚"
+
+#: views/pages/js_constants.js.thtml:70
+msgid "app_compat_update_firefox"
+msgstr ""
+"ã“ã®ã‚¢ãƒ‰ã‚ªãƒ³ã‚’利用ã™ã‚‹ã«ã¯ <a href=\"http://getfirefox.com\">Firefox をアップ"
+"グレード</a> ã—ã¦ãã ã•ã„"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#. %3$s is a status, like Public.
+#: controllers/components/audit.php:79
+msgid "audit_addon_status"
+msgstr "%1$s ㌠%2$s ã®ã‚¹ãƒ†ãƒ¼ã‚¿ã‚¹ã‚’ %3$s ã«å¤‰æ›´ã—ã¾ã—ãŸ"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:221
+msgid "audit_admin_default"
+msgstr "%1$s ãŒä¸æ˜Žãªç®¡ç†è€…アクション %2$s ã‚’ ID %3$s ã¸ã‚³ãƒŸãƒƒãƒˆã—ã¾ã—ãŸ"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:153
+msgid "audit_admin_feature_remove"
+msgstr "%1$s ãŒæ©Ÿèƒ½ %2$s を削除ã—ã¾ã—ãŸ"
+
+#. %1$s is <a>user name</a>
+#. %2$s is an application, like Firefox.
+#: controllers/components/audit.php:92
+msgid "audit_application_create"
+msgstr "%1$s ãŒã‚¢ãƒ—リケーション %2$s を作æˆã—ã¾ã—ãŸ"
+
+#. %1$s is <a>user name</a>
+#. %2$s is an application, like Firefox.
+#: controllers/components/audit.php:95
+msgid "audit_application_edit"
+msgstr "%1$s ãŒã‚¢ãƒ—リケーション %2$s を編集ã—ã¾ã—ãŸ"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a version number, like 3.5.
+#. %3$s is an application, like Firefox.
+#: controllers/components/audit.php:105
+msgid "audit_appversion_create"
+msgstr "%1$s ㌠%3$s ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ %2$s を作æˆã—ã¾ã—ãŸ"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a version number, like 3.5.
+#. %3$s is an application, like Firefox.
+#: controllers/components/audit.php:108
+msgid "audit_appversion_delete"
+msgstr "%1$s ㌠%3$s ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ %2$s を削除ã—ã¾ã—ãŸ"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a config field, like "awesomeness".
+#. %3$s is a config value, like "off".
+#. %4$s is a config value, like "on".
+#: controllers/components/audit.php:210
+msgid "audit_config"
+msgstr "%1$s ㌠'%2$s' ã®è¨­å®šã‚’ '%3$s' ã‹ã‚‰ '%4$s' ã¸å¤‰æ›´ã—ã¾ã—ãŸ"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:258
+msgid "audit_editor_default"
+msgstr "%1$s ãŒä¸æ˜Žãªã‚¨ãƒ‡ã‚£ã‚¿ã‚¢ã‚¯ã‚·ãƒ§ãƒ³ %2$s ã‚’ ID %3$s ã¸ã‚³ãƒŸãƒƒãƒˆã—ã¾ã—ãŸ"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#: controllers/components/audit.php:236
+msgid "audit_editor_feature_remove"
+msgstr "%1$s ãŒã‚¢ãƒ‰ã‚ªãƒ³ %2$s を注目リストã‹ã‚‰å‰Šé™¤ã—ã¾ã—ãŸ"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#: controllers/components/audit.php:231
+msgid "audit_feature_add"
+msgstr "%1$s ãŒã‚¢ãƒ‰ã‚ªãƒ³ %2$s を注目リストã¸è¿½åŠ ã—ã¾ã—ãŸ"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:149
+msgid "audit_feature_edit"
+msgstr "%1$s ãŒãƒ­ã‚±ãƒ¼ãƒ« %2$s ã®æ©Ÿèƒ½ã‚’変更ã—ã¾ã—ãŸ"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#: controllers/components/audit.php:241
+msgid "audit_feature_locale_change"
+msgstr ""
+"%1$s ãŒæ³¨ç›®ãƒªã‚¹ãƒˆã«æŽ²è¼‰ã•ã‚Œã¦ã„るアドオン %2$s ã®ãƒ­ã‚±ãƒ¼ãƒ«ã‚’変更ã—ã¾ã—ãŸ"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:83
+msgid "audit_file_recalchash"
+msgstr "%1$s ãŒãƒ•ã‚¡ã‚¤ãƒ« %2$s ã®ãƒãƒƒã‚·ãƒ¥å€¤ã‚’å†è¨ˆç®—ã—ã¾ã—ãŸ"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>user name</a>
+#. %3$s is <a>group name</a>
+#: controllers/components/audit.php:182
+msgid "audit_group_addmember"
+msgstr "%1$s ㌠%2$s ã‚’ %3$s グループã¸è¿½åŠ ã—ã¾ã—ãŸ"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:313
+msgid "audit_group_associated"
+msgstr "%1$s ãŒè‡ªåˆ†è‡ªèº«ã‚’ %2$s グループã¸é–¢é€£ä»˜ã‘ã¾ã—ãŸ"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:162
+msgid "audit_group_create"
+msgstr "%1s ㌠%2$s グループを作æˆã—ã¾ã—ãŸ"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:170
+msgid "audit_group_delete"
+msgstr "%1$s ㌠%2$s グループ (ID %3$s) を削除ã—ã¾ã—ãŸ"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:165
+msgid "audit_group_edit"
+msgstr "%1$s ㌠%2$s グループを編集ã—ã¾ã—ãŸ"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>user name</a>
+#. %3$s is <a>group name</a>
+#: controllers/components/audit.php:188
+msgid "audit_group_removemember"
+msgstr "%1$s ㌠%2$s ã‚’ %3$s グループã‹ã‚‰å‰Šé™¤ã—ã¾ã—ãŸ"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:280
+msgid "audit_l10n_default"
+msgstr "%1$s ãŒä¸æ˜Žãªã‚¢ã‚¯ã‚·ãƒ§ãƒ³ %2$s ã‚’ ID %3$s ã¸ã‚³ãƒŸãƒƒãƒˆã—ã¾ã—ãŸ"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:295
+msgid "audit_modify_locked_group"
+msgstr "%1$s ãŒãƒ­ãƒƒã‚¯ã•ã‚Œã¦ã„ã‚‹ %2$s グループを編集ã—よã†ã¨ã—ã¾ã—ãŸ"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:299
+msgid "audit_modify_other_locale"
+msgstr "%1$s ㌠%2$s ã®ç¿»è¨³ã‚’許å¯ãªã編集ã—よã†ã¨ã—ã¾ã—ãŸ"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a platform, like <a>Windows</a>
+#: controllers/components/audit.php:135
+msgid "audit_platform_create"
+msgstr "%1$s ㌠%2$s プラットフォームを作æˆã—ã¾ã—ãŸ"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a platform, like <a>Windows</a>
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:143
+msgid "audit_platform_delete"
+msgstr "%1$s ㌠%2$s プラットフォーム (ID %3$s) を削除ã—ã¾ã—ãŸ"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a platform, like <a>Windows</a>
+#: controllers/components/audit.php:138
+msgid "audit_platform_edit"
+msgstr "%1$s ㌠%2$s プラットフォームを編集ã—ã¾ã—ãŸ"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a part of the admin, like 'Site Config'
+#: controllers/components/audit.php:288
+msgid "audit_reauthentication_failure"
+msgstr "%1$s ㌠%2$s ã¸ã‚¢ã‚¯ã‚»ã‚¹ã™ã‚‹ãŸã‚ã®å†èªè¨¼ã«å¤±æ•—ã—ã¾ã—ãŸ"
+
+#. %1$s is <a>user name</a>
+#. %2$s is the name of a canned response, like 'Ready for the public'
+#: controllers/components/audit.php:198
+msgid "audit_response_create"
+msgstr "%1$s ãŒè¿”ä¿¡ %2$s を作æˆã—ã¾ã—ãŸ"
+
+#. %1$s is <a>user name</a>
+#. %2$s is the name of a canned response, like 'Ready for the public'
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:206
+msgid "audit_response_delete"
+msgstr "%1$s ãŒè¿”ä¿¡ %2$s (ID %3$s) を削除ã—ã¾ã—ãŸ"
+
+#. %1$s is <a>user name</a>
+#. %2$s is the name of a canned response, like 'Ready for the public'
+#: controllers/components/audit.php:201
+msgid "audit_response_edit"
+msgstr "%1$s ãŒè¿”ä¿¡ %2$s を編集ã—ã¾ã—ãŸ"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:245
+msgid "audit_review_approve"
+msgstr "%1$s ãŒãƒ¬ãƒ“ュー %2$s を承èªã—ã¾ã—ãŸ"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:250 controllers/components/audit.php:253
+msgid "audit_review_delete"
+msgstr "%1$s ãŒãƒ¬ãƒ“ュー %2$s を削除ã—ã¾ã—ãŸ"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:303
+msgid "audit_security_default"
+msgstr "%1$s ãŒä¸æ˜Žãªã‚»ã‚­ãƒ¥ãƒªãƒ†ã‚£ã‚¢ã‚¯ã‚·ãƒ§ãƒ³ %2$s ã‚’ ID %3$s ã¸ã‚³ãƒŸãƒƒãƒˆã—ã¾ã—ãŸ"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a category name, like <a>Search Tools</a>
+#: controllers/components/audit.php:118
+msgid "audit_tag_create"
+msgstr "%1$s ãŒã‚¿ã‚° %2$s を作æˆã—ã¾ã—ãŸ"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a category name, like <a>Search Tools</a>
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:126
+msgid "audit_tag_delete"
+msgstr "%1$s ãŒã‚«ãƒ†ã‚´ãƒª %2$s (ID %3$s) を削除ã—ã¾ã—ãŸ"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a category name, like <a>Search Tools</a>
+#: controllers/components/audit.php:121
+msgid "audit_tag_edit"
+msgstr "%1$s ãŒã‚«ãƒ†ã‚´ãƒª %2$s を編集ã—ã¾ã—ãŸ"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:266
+msgid "audit_update_applications"
+msgstr "%1$s ㌠%2$s ロケールã®ã‚¢ãƒ—リケーションã®ç¿»è¨³ã‚’æ›´æ–°ã—ã¾ã—ãŸ"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:277
+msgid "audit_update_blog"
+msgstr "%1$s ㌠%2$s ロケールã®ãƒ–ログ記事ã®ç¿»è¨³ã‚’æ›´æ–°ã—ã¾ã—ãŸ"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:274
+msgid "audit_update_platforms"
+msgstr "%1$s ㌠%2$s ロケールã®ãƒ—ラットフォームã®ç¿»è¨³ã‚’æ›´æ–°ã—ã¾ã—ãŸ"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:270
+msgid "audit_update_tags"
+msgstr "%1$s ㌠%2$s ロケールã®ã‚«ãƒ†ã‚´ãƒªã®ç¿»è¨³ã‚’æ›´æ–°ã—ã¾ã—ãŸ"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>user name</a>
+#: controllers/components/audit.php:217
+msgid "audit_user_edit"
+msgstr "%1$s ㌠%2$s ã®ãƒ¦ãƒ¼ã‚¶æƒ…報を編集ã—ã¾ã—ãŸ"
+
+#: controllers/addons_controller.php:1012
+msgid "browse_addons_name"
+msgstr "タイトル順"
+
+#: controllers/addons_controller.php:1010
+msgid "browse_addons_newest"
+msgstr "最近公開ã•ã‚ŒãŸã‚¢ãƒ‰ã‚ªãƒ³"
+
+#: controllers/addons_controller.php:1008
+msgid "browse_addons_popular"
+msgstr "人気ã®ã‚¢ãƒ‰ã‚ªãƒ³"
+
+#: controllers/addons_controller.php:1011
+msgid "browse_addons_rated"
+msgstr "評価順"
+
+#: controllers/addons_controller.php:1009
+msgid "browse_addons_updated"
+msgstr "最近更新ã•ã‚ŒãŸã‚¢ãƒ‰ã‚ªãƒ³"
+
+#: views/elements/categories.thtml:73 views/elements/categories.thtml:82
+msgid "categories_current_title"
+msgstr "ç¾åœ¨ã®ã‚«ãƒ†ã‚´ãƒª"
+
+#: views/elements/categories.thtml:50
+#: views/elements/amo2009/categories.thtml:43
+#: views/elements/amo2009/categories.thtml:45
+msgid "categories_header"
+msgstr "カテゴリ"
+
+#: views/elements/categories.thtml:50
+#: views/elements/amo2009/categories.thtml:41
+msgid "categories_header_title"
+msgstr "カテゴリをé¸æŠž"
+
+#. %1$s is the category name
+#: views/addons/searchengines.thtml:129
+#, php-format
+msgid "category_extra_see_all"
+msgstr "「%1$sã€ã‚«ãƒ†ã‚´ãƒªã®ã‚¢ãƒ‰ã‚ªãƒ³ã‚’ã™ã¹ã¦è¦‹ã‚‹"
+
+#. %1$s is a number.
+#: models/collection.php:130
+msgid "collection_description_limit"
+msgstr "説明文㯠%1$s 文字以下ã§è¨˜è¿°ã—ã¦ãã ã•ã„。"
+
+#. %1$s is the name of the collection
+#: controllers/collections_controller.php:392
+msgid "collection_detail_rss_title"
+msgstr "%s コレクション"
+
+#: controllers/collections_controller.php:1065
+msgid "collection_error_deleting_addon"
+msgstr "アドオンã®å‰Šé™¤ä¸­ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸï¼"
+
+#: controllers/collections_controller.php:1051
+msgid "collection_error_saving_addon"
+msgstr "アドオンã®ä¿å­˜ä¸­ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸï¼"
+
+#: controllers/collections_controller.php:1080
+msgid "collection_error_saving_comment"
+msgstr "コメントã®ä¿å­˜ä¸­ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸï¼"
+
+#. %1$s is a number.
+#: models/collection.php:122
+msgid "collection_name_limit"
+msgstr "åå‰ã¯ %1$s 文字以下ã§è¨˜è¿°ã—ã¦ãã ã•ã„。"
+
+#: controllers/collections_controller.php:352
+#: controllers/collections_controller.php:487
+msgid "collection_not_found"
+msgstr "コレクションãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“"
+
+#. %1$s is the text on the "create collection" button
+#: views/collections/add.thtml:91
+msgid "collections_add_formfield_addons_description"
+msgstr ""
+"コレクションã¸è¿½åŠ ã—ãŸã„アドオンãŒåˆ†ã‹ã£ã¦ã„ã‚‹å ´åˆã¯ã€ä¸‹ã«ãã®åå‰ã‚’入力ã—ã¦"
+"ãã ã•ã„。今ã¯ä½•ã‚‚ã›ãšå¾Œã§è¿½åŠ ã™ã‚‹å ´åˆã¯ %1$s をクリックã—ã¦ãã ã•ã„。"
+
+#: views/collections/add.thtml:90
+msgid "collections_add_formfield_firstaddons"
+msgstr "最åˆã®ã‚¢ãƒ‰ã‚ªãƒ³ã‚’é¸æŠž"
+
+#: views/collections/add.thtml:48
+msgid "collections_add_header"
+msgstr "コレクションを作æˆ"
+
+#: views/collections/add.thtml:97
+msgid "collections_add_header_selectedaddons"
+msgstr "é¸æŠžã•ã‚ŒãŸã‚¢ãƒ‰ã‚ªãƒ³"
+
+#: views/collections/add.thtml:50
+msgid "collections_add_intro"
+msgstr ""
+"自分ã®ã‚¢ãƒ‰ã‚ªãƒ³ã‚³ãƒ¬ã‚¯ã‚·ãƒ§ãƒ³ã‚’作るã®ã¯ç°¡å˜ã§ã™ã€‚下ã®å…¥åŠ›æ¬„ã«å¿…è¦äº‹é …を記入ã—ã¦"
+"ãã ã•ã„。"
+
+#: views/collections/add.thtml:92 views/collections/add.thtml:103
+msgid "collections_add_submit"
+msgstr "コレクションを作æˆ"
+
+#: views/pages/collector_faq.thtml:50 views/pages/collector_firstrun.thtml:43
+#: views/pages/collector.thtml:47 views/pages/collector_features.thtml:55
+#: controllers/search_controller.php:302
+#: controllers/collections_controller.php:206
+#: controllers/collections_controller.php:405
+#: controllers/collections_controller.php:467
+#: controllers/collections_controller.php:539
+msgid "collections_breadcrumb"
+msgstr "コレクション"
+
+#: views/collections/detail.thtml:185
+msgid "collections_detail_a_learn"
+msgstr "詳細"
+
+#: views/elements/amo2009/collection_add_form.thtml:53
+#: views/elements/amo2009/collections_js_init.thtml:68
+#: views/pages/collector_firstrun.thtml:64
+msgid "collections_detail_button_add"
+msgstr "ãŠæ°—ã«å…¥ã‚Šã¸è¿½åŠ "
+
+#: views/elements/amo2009/collection_add_form.thtml:50
+#: views/elements/amo2009/collections_js_init.thtml:71
+msgid "collections_detail_button_remove"
+msgstr "ãŠæ°—ã«å…¥ã‚Šã‹ã‚‰å‰Šé™¤"
+
+#. %1$s is a URL.
+#. %2$s is a full <a href>.
+#: views/collections/detail.thtml:62
+msgid "collections_detail_created_desc"
+msgstr ""
+"<p>æ–°ã—ã„コレクションã¯ä¸‹ã§è¦‹ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚コレクションã«ãƒ‹ãƒƒã‚¯ãƒãƒ¼ãƒ ã‚’付"
+"ã‘ãŸã‚Šã€ã‚¢ã‚¤ã‚³ãƒ³ã‚’アップロードã—ãŸã‚Šã€è©³ç´°è¨­å®šã‚’変更ã—ãŸã„å ´åˆã¯ã€<a href=\""
+"%1$s\">コレクションã®ç®¡ç†</a> ページã¸ç§»å‹•ã—ã¦ãã ã•ã„。</p><p>ã‚ãªãŸã®ã‚³ãƒ¬ã‚¯"
+"ションã¯ã“ã®å ´æ‰€ã§ã‚¢ã‚¯ã‚»ã‚¹ã§ãã¾ã™: %2$s</p>"
+
+#: views/collections/detail.thtml:61
+msgid "collections_detail_created_msg"
+msgstr "ã‚ãªãŸã®ã‚³ãƒ¬ã‚¯ã‚·ãƒ§ãƒ³ãŒä½œæˆã•ã‚Œã¾ã—ãŸï¼"
+
+#: views/collections/detail.thtml:109
+msgid "collections_detail_header_about"
+msgstr "ã“ã®ã‚³ãƒ¬ã‚¯ã‚·ãƒ§ãƒ³ã«ã¤ã„ã¦"
+
+#. %1$s is a number.
+#: views/collections/detail.thtml:126
+msgid "collections_detail_header_count"
+msgid_plural "collections_detail_header_count"
+msgstr[0] "ã“ã®ã‚³ãƒ¬ã‚¯ã‚·ãƒ§ãƒ³ã«ã¯ %1$s 個ã®ã‚¢ãƒ‰ã‚ªãƒ³ãŒå«ã¾ã‚Œã¦ã„ã¾ã™"
+msgstr[1] "ã“ã®ã‚³ãƒ¬ã‚¯ã‚·ãƒ§ãƒ³ã«ã¯ %1$s 個ã®ã‚¢ãƒ‰ã‚ªãƒ³ãŒå«ã¾ã‚Œã¦ã„ã¾ã™"
+
+#: views/collections/detail.thtml:113
+msgid "collections_detail_info_created"
+msgstr "<strong>作æˆè€…:</strong> %1$s"
+
+#: views/collections/detail.thtml:117
+msgid "collections_detail_info_updated"
+msgstr "<strong>æ›´æ–°æ—¥</strong>"
+
+#: views/elements/amo2009/collections_js_init.thtml:62
+msgid "collections_detail_js_adding"
+msgstr "ãŠæ°—ã«å…¥ã‚Šã«è¿½åŠ ..."
+
+#: views/elements/amo2009/collections_js_init.thtml:65
+msgid "collections_detail_js_removing"
+msgstr "ãŠæ°—ã«å…¥ã‚Šã‹ã‚‰å‰Šé™¤..."
+
+#. %1$s is a URL
+#: views/collections/detail.thtml:90
+msgid "collections_detail_login"
+msgstr ""
+"ã“ã®ã‚³ãƒ¬ã‚¯ã‚·ãƒ§ãƒ³ã‚’ã‚ãªãŸã®ãŠæ°—ã«å…¥ã‚Šã«è¿½åŠ ã™ã‚‹ã«ã¯ <a href=\"%1$s\">ログイン"
+"</a> ã—ã¦ãã ã•ã„。"
+
+#: views/collections/detail.thtml:104
+msgid "collections_detail_manage"
+msgstr "コレクションã®ç®¡ç†"
+
+#: controllers/collections_controller.php:298
+msgid "collections_detail_sort_date"
+msgstr "追加日"
+
+#: controllers/collections_controller.php:299
+msgid "collections_detail_sort_name"
+msgstr "åå‰"
+
+#: controllers/collections_controller.php:300
+msgid "collections_detail_sort_popularity"
+msgstr "人気度"
+
+#. %1$s is a number.
+#: views/collections/detail.thtml:166
+msgid "collections_detail_weekly_downloads"
+msgid_plural "collections_detail_weekly_downloads"
+msgstr[0] "今週ã®ãƒ€ã‚¦ãƒ³ãƒ­ãƒ¼ãƒ‰æ•°: %1$s"
+msgstr[1] "今週ã®ãƒ€ã‚¦ãƒ³ãƒ­ãƒ¼ãƒ‰æ•°: %1$s"
+
+#: views/collections/edit.thtml:255
+msgid "collections_edit_addons_delete_noscript"
+msgstr "é¸æŠžã•ã‚ŒãŸã‚¢ãƒ‰ã‚ªãƒ³ã¯ä¿å­˜æ™‚ã«å‰Šé™¤ã•ã‚Œã¾ã™"
+
+#: views/collections/edit.thtml:247
+msgid "collections_edit_addons_description"
+msgstr ""
+"ã“ã®ã‚³ãƒ¬ã‚¯ã‚·ãƒ§ãƒ³ã«æ–°ã—ã„アドオンを追加ã—ã¦å…¬é–‹ã™ã‚‹ã«ã¯ã€ä¸‹ã®æ¬„ã«åå‰ã‚’入力ã—"
+"ã¦ãã ã•ã„。"
+
+#: views/collections/edit.thtml:248
+msgid "collections_edit_addons_description_noscript"
+msgstr ""
+"ã“ã®ã‚³ãƒ¬ã‚¯ã‚·ãƒ§ãƒ³ã«æ–°ã—ã„アドオンを追加ã—ã¦å…¬é–‹ã™ã‚‹ã«ã¯ã€ä¸‹ã®æ¬„ã«ã‚¢ãƒ‰ã‚ªãƒ³ ID "
+"をカンマ区切りã§å…¥åŠ›ã—ã¦ãã ã•ã„。"
+
+#: views/collections/edit.thtml:247 views/collections/edit.thtml:248
+msgid "collections_edit_addons_description_publish_detailspage"
+msgstr "通常ã®ä¸€è¦§ãƒšãƒ¼ã‚¸ã‹ã‚‰ã‚¢ãƒ‰ã‚ªãƒ³ã‚’追加ã™ã‚‹ã“ã¨ã‚‚ã§ãã¾ã™ã€‚"
+
+#. %1$s is the date the add-on was added to the collection
+#. %1$s is the name of the user who added the add-on to the collection
+#: views/collections/edit.thtml:260
+msgid "collections_edit_addons_listitem_added"
+msgstr "追加日: %1$s / ユーザ: %2$s"
+
+#: views/collections/edit.thtml:263
+msgid "collections_edit_addons_listitem_comment_add"
+msgstr "公開者ã®ã‚³ãƒ¡ãƒ³ãƒˆã‚’追加"
+
+#: views/collections/edit.thtml:266
+msgid "collections_edit_addons_listitem_comment_delete"
+msgstr "公開者ã®ã‚³ãƒ¡ãƒ³ãƒˆã‚’削除"
+
+#: views/collections/edit.thtml:265
+msgid "collections_edit_addons_listitem_comment_edit"
+msgstr "公開者ã®ã‚³ãƒ¡ãƒ³ãƒˆã‚’編集"
+
+#: views/collections/edit.thtml:271
+msgid "collections_edit_addons_listitem_comment_note"
+msgstr ""
+"注æ„: コメントã¯ã€å…ƒã®å…¬é–‹æ—¥ã«å…ƒã®å…¬é–‹è€…ã«ã‚ˆã£ã¦æ›¸ã‹ã‚ŒãŸã‚‚ã®ã¨ã—ã¦è¨˜è¼‰ã•ã‚Œã¾"
+"ã™ã€‚"
+
+#: views/collections/edit.thtml:270
+msgid "collections_edit_addons_listitem_comment_submit"
+msgstr "コメントをä¿å­˜"
+
+#: views/collections/edit.thtml:261
+msgid "collections_edit_addons_listitem_remove"
+msgstr "削除"
+
+#: views/collections/edit.thtml:250
+msgid "collections_edit_addons_submit"
+msgstr "コレクションã¸è¿½åŠ "
+
+#: views/collections/edit.thtml:153
+msgid "collections_edit_check_nickname"
+msgstr "利用å¯èƒ½ã‹ã©ã†ã‹ã‚’確èª"
+
+#: views/collections/edit.thtml:299
+msgid "collections_edit_confirm_deletecollection"
+msgstr "ã¯ã„ã€ã“ã®ã‚³ãƒ¬ã‚¯ã‚·ãƒ§ãƒ³ã‚’削除ã—ã¾ã™ã€‚"
+
+#. %1$s is the label of the edit form's submit button
+#: views/collections/edit.thtml:300
+msgid "collections_edit_confirm_deletecollection_description"
+msgstr ""
+"ã“ã®ã‚³ãƒ¬ã‚¯ã‚·ãƒ§ãƒ³ã‚’削除ã™ã‚‹ã«ã¯ã€ãƒã‚§ãƒƒã‚¯ãƒœãƒƒã‚¯ã‚¹ã«ãƒã‚§ãƒƒã‚¯ã‚’入れã¦ã‹ã‚‰ã€Œ%1"
+"$sã€ã‚’クリックã—ã¦ãã ã•ã„。"
+
+#. %1$s is the "delete" submit button text
+#. %2$s is the title of the "advanced" tab
+#: views/collections/edit.thtml:95
+msgid "collections_edit_delete_upon_submit"
+msgstr ""
+"下ã®ã€Œ%1$sã€ã‚’クリックã™ã‚‹ã¨ã€ã‚ãªãŸã®ã‚³ãƒ¬ã‚¯ã‚·ãƒ§ãƒ³ã¯å‰Šé™¤ã•ã‚Œã¾ã™ã€‚コレクショ"
+"ンを削除ã—ãŸããªã„å ´åˆã¯ã€ã€Œ%2$sã€ã‚¿ãƒ–ã«ã‚る確èªãƒã‚§ãƒƒã‚¯ãƒœãƒƒã‚¯ã‚¹ã®ãƒã‚§ãƒƒã‚¯ã‚’"
+"外ã—ã¦ã‹ã‚‰ã‚³ãƒ¬ã‚¯ã‚·ãƒ§ãƒ³ã®ç·¨é›†ã‚’続ã‘ã¦ãã ã•ã„。ã¾ãŸã€ä¿å­˜ã›ãšã«ã“ã®ãƒšãƒ¼ã‚¸ã‹ã‚‰"
+"離れã¦ã‚‚ã€ã‚³ãƒ¬ã‚¯ã‚·ãƒ§ãƒ³ã¯å‰Šé™¤ã•ã‚Œã¾ã›ã‚“。"
+
+#: views/collections/edit.thtml:94
+msgid "collections_edit_delete_warning"
+msgstr "ã‚ãªãŸã®ã‚³ãƒ¬ã‚¯ã‚·ãƒ§ãƒ³ã¯å‰Šé™¤ã•ã‚Œã¾ã™ï¼"
+
+#: views/collections/add.thtml:76 views/collections/edit.thtml:144
+msgid "collections_edit_form_error_description"
+msgstr "コレクションã®èª¬æ˜Žã‚’入力ã—ã¦ãã ã•ã„。"
+
+#: views/collections/edit.thtml:181
+msgid "collections_edit_form_error_icon"
+msgstr "アイコンã®ã‚¢ãƒƒãƒ—ロード中ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚"
+
+#: views/collections/add.thtml:69 views/collections/edit.thtml:130
+msgid "collections_edit_form_error_name"
+msgstr "コレクションã®åå‰ã‚’入力ã—ã¦ãã ã•ã„。"
+
+#: views/collections/edit.thtml:158
+msgid "collections_edit_form_error_nickname"
+msgstr "ニックãƒãƒ¼ãƒ ã‚’é¸æŠžã—ãŸå ´åˆã¯ã€ä¸€æ„ã§ã‚ã‚‹å¿…è¦ãŒã‚ã‚Šã¾ã™ã€‚"
+
+#: views/collections/add.thtml:93 views/collections/edit.thtml:249
+msgid "collections_edit_formfield_addons"
+msgstr "アドオンã®åå‰:"
+
+#: views/collections/edit.thtml:281
+msgid "collections_edit_formfield_application"
+msgstr "対応アプリケーション"
+
+#: views/collections/edit.thtml:282
+msgid "collections_edit_formfield_application_description"
+msgstr "ã“ã®ã‚³ãƒ¬ã‚¯ã‚·ãƒ§ãƒ³ãŒå¯¾å¿œã™ã‚‹ã‚¢ãƒ—リケーションをé¸æŠžã—ã¦ãã ã•ã„。"
+
+#: views/collections/edit.thtml:288
+msgid "collections_edit_formfield_collectiontype"
+msgstr "コレクションã®ç¨®é¡ž"
+
+#: views/collections/edit.thtml:295
+msgid "collections_edit_formfield_deletecollection"
+msgstr "コレクションを削除"
+
+#: views/collections/edit.thtml:296
+msgid "collections_edit_formfield_deletecollection_description"
+msgstr "コレクションを削除ã™ã‚‹ã¨ã€å…ƒã«æˆ»ã™ã“ã¨ã¯ã§ãã¾ã›ã‚“。"
+
+#: views/collections/add.thtml:73 views/collections/edit.thtml:140
+msgid "collections_edit_formfield_description"
+msgstr "コレクションã®èª¬æ˜Ž"
+
+#: views/collections/add.thtml:74 views/collections/edit.thtml:141
+msgid "collections_edit_formfield_description_description"
+msgstr "コレクションã¨ãã®ä¸­ã«å«ã¾ã‚Œã¦ã„るアドオンã®ç¨®é¡žã«é–¢ã™ã‚‹ç°¡å˜ãªèª¬æ˜Ž"
+
+#: views/collections/edit.thtml:162
+msgid "collections_edit_formfield_icon"
+msgstr "アイコン"
+
+#: views/collections/edit.thtml:163
+msgid "collections_edit_formfield_icon_description"
+msgstr ""
+"JPGã€GIF ã‚‚ã—ã㯠PNG å½¢å¼ã®ã‚¢ã‚¤ã‚³ãƒ³ã‚’アップロードã§ãã¾ã™ã€‚アップロードã•ã‚Œ"
+"ãŸã‚¢ã‚¤ã‚³ãƒ³ã¯ 32x32 ピクセルã«ãƒªã‚µã‚¤ã‚ºã•ã‚Œã¾ã™ã€‚"
+
+#: views/collections/add.thtml:80 views/collections/edit.thtml:189
+msgid "collections_edit_formfield_listed"
+msgstr "自分ã®ã‚³ãƒ¬ã‚¯ã‚·ãƒ§ãƒ³ã‚’見るã“ã¨ãŒã§ãるユーザ"
+
+#: views/collections/add.thtml:81 views/collections/edit.thtml:190
+msgid "collections_edit_formfield_listed_description"
+msgstr ""
+"åˆæœŸè¨­å®šã§ã¯ã€ã‚³ãƒ¬ã‚¯ã‚·ãƒ§ãƒ³ã¯å…¬é–‹ã®ã‚³ãƒ¬ã‚¯ã‚·ãƒ§ãƒ³ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã§å…¬é–‹ã•ã‚Œã€èª°ã§ã‚‚"
+"見るã“ã¨ãŒã§ãã¾ã™ã€‚特別ãªãƒªãƒ³ã‚¯ã‚’å—ã‘å–ã£ãŸäººã ã‘ãŒã‚³ãƒ¬ã‚¯ã‚·ãƒ§ãƒ³ã‚’見られるよ"
+"ã†ã«åˆ¶é™ã‚’掛ã‘ãŸã„å ´åˆã¯ã€ä¸‹ã®ã‚ªãƒ—ションをé¸æŠžã—ã¦ãã ã•ã„。"
+
+#: views/collections/add.thtml:84 views/collections/edit.thtml:193
+msgid "collections_edit_formfield_listed_false"
+msgstr "自分ãŒæ‹›å¾…ã—ãŸäººã ã‘ãŒè‡ªåˆ†ã®ã‚³ãƒ¬ã‚¯ã‚·ãƒ§ãƒ³ã‚’見るã“ã¨ãŒã§ãã¾ã™"
+
+#: views/collections/add.thtml:83 views/collections/edit.thtml:192
+msgid "collections_edit_formfield_listed_true"
+msgstr "誰ã§ã‚‚自分ã®ã‚³ãƒ¬ã‚¯ã‚·ãƒ§ãƒ³ã‚’ディレクトリ内ã§è¦‹ã‚‹ã“ã¨ãŒã§ãã¾ã™"
+
+#: views/collections/edit.thtml:223
+msgid "collections_edit_formfield_managers"
+msgstr "自分ã®ã‚³ãƒ¬ã‚¯ã‚·ãƒ§ãƒ³ã‚’管ç†ã§ãるユーザ"
+
+#: views/collections/edit.thtml:224
+msgid "collections_edit_formfield_managers_description"
+msgstr ""
+"以下ã®ãƒ¦ãƒ¼ã‚¶ã¯ã€ã‚ãªãŸã®ã‚³ãƒ¬ã‚¯ã‚·ãƒ§ãƒ³ã«ã‚¢ãƒ‰ã‚ªãƒ³ã‚’追加ã—ãŸã‚Šã€ã™ã¹ã¦ã®ã‚¢ãƒ‰ã‚ªãƒ³"
+"や設定を管ç†ã—ãŸã‚Šã€ä»–ã®ãƒ¦ãƒ¼ã‚¶ã«æ¨©é™ã‚’与ãˆã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚"
+
+#: views/collections/add.thtml:66 views/collections/edit.thtml:126
+msgid "collections_edit_formfield_name"
+msgstr "コレクションã®åå‰"
+
+#: views/collections/add.thtml:67 views/collections/edit.thtml:127
+msgid "collections_edit_formfield_name_description"
+msgstr ""
+"コレクションã«åˆ†ã‹ã‚Šã‚„ã™ã„åå‰ã‚’付ã‘ã¦ãã ã•ã„。例ãˆã°ã€Œãƒ‡ã‚¤ãƒ–ã®ãŠæ°—ã«å…¥ã‚Šæ—…"
+"行用アドオンã€ãªã©ãŒè‰¯ã„例ã§ã™ã€‚"
+
+#: views/collections/edit.thtml:148
+msgid "collections_edit_formfield_nickname"
+msgstr "コレクションã®ãƒ‹ãƒƒã‚¯ãƒãƒ¼ãƒ "
+
+#: views/collections/edit.thtml:149
+msgid "collections_edit_formfield_nickname_description"
+msgstr ""
+"オプションã¨ã—ã¦ã€ç°¡å˜ã«ã‚¢ã‚¯ã‚»ã‚¹ã§ãるよã†ã€ã‚³ãƒ¬ã‚¯ã‚·ãƒ§ãƒ³ã«ä¸€æ„ã®ãƒ‹ãƒƒã‚¯ãƒãƒ¼ãƒ "
+"を付ã‘ã‚‹ã“ã¨ãŒã§ãã¾ã™:"
+
+#: views/collections/edit.thtml:201
+msgid "collections_edit_formfield_publishers"
+msgstr "コレクションã«ã‚¢ãƒ‰ã‚ªãƒ³ã‚’追加ã§ãるユーザ"
+
+#: views/collections/edit.thtml:202
+msgid "collections_edit_formfield_publishers_description"
+msgstr ""
+"以下ã®ãƒ¦ãƒ¼ã‚¶ã¯ã€ã‚ãªãŸã®ã‚³ãƒ¬ã‚¯ã‚·ãƒ§ãƒ³ã«ã‚¢ãƒ‰ã‚ªãƒ³ã‚’追加ã—ãŸã‚Šã€ã‚³ãƒ¬ã‚¯ã‚·ãƒ§ãƒ³ã‹ã‚‰"
+"アドオンを削除ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚"
+
+#: views/collections/edit.thtml:210 views/collections/edit.thtml:232
+msgid "collections_edit_formfield_users_add"
+msgstr "Firefox Add-ons ã«ç™»éŒ²ã•ã‚Œã¦ã„るメールアドレスを入力ã—ã¦ãã ã•ã„:"
+
+#: views/collections/edit.thtml:216 views/collections/edit.thtml:238
+msgid "collections_edit_formfield_users_delete_noscript"
+msgstr "é¸æŠžã•ã‚ŒãŸã‚¢ã‚«ã‚¦ãƒ³ãƒˆã¯ä¿å­˜æ™‚ã«å‰Šé™¤ã•ã‚Œã¾ã™"
+
+#: views/collections/edit.thtml:215 views/collections/edit.thtml:237
+msgid "collections_edit_formfield_users_new_noscript"
+msgstr ""
+"Firefox Add-ons ã«ç™»éŒ²ã•ã‚Œã¦ã„るアカウントã®ãƒ¡ãƒ¼ãƒ«ã‚¢ãƒ‰ãƒ¬ã‚¹ã‚’カンマ区切りã§å…¥"
+"力ã—ã¦ãã ã•ã„"
+
+#: views/collections/edit.thtml:204 views/collections/edit.thtml:226
+msgid "collections_edit_formfield_users_onlyme"
+msgstr "自分ã®ã¿"
+
+#: views/collections/edit.thtml:205 views/collections/edit.thtml:227
+msgid "collections_edit_formfield_users_otherusers"
+msgstr "自分ã¨ä»¥ä¸‹ã®ãƒ¦ãƒ¼ã‚¶:"
+
+#: views/collections/edit.thtml:211 views/collections/edit.thtml:233
+msgid "collections_edit_formfield_users_submit"
+msgstr "追加"
+
+#. %1$s is the name of the collection
+#: views/collections/edit.thtml:68
+msgid "collections_edit_header"
+msgstr "%1$s を管ç†"
+
+#: views/collections/edit.thtml:246
+msgid "collections_edit_header_addons"
+msgstr "コレクションã®å†…容を管ç†"
+
+#: views/collections/edit.thtml:253 views/collections/edit.thtml:258
+msgid "collections_edit_header_addons_current"
+msgstr "ç¾åœ¨å«ã¾ã‚Œã¦ã„るアドオン:"
+
+#: views/collections/edit.thtml:279
+msgid "collections_edit_header_advanced"
+msgstr "詳細設定"
+
+#: views/collections/edit.thtml:186
+msgid "collections_edit_header_permissions"
+msgstr "コレクションã®æ¨©é™ã‚’管ç†"
+
+#: views/collections/edit.thtml:170
+msgid "collections_edit_icon_cancel"
+msgstr "キャンセル"
+
+#: views/collections/edit.thtml:174 views/collections/edit.thtml:179
+msgid "collections_edit_icon_delete"
+msgstr "アイコンを削除"
+
+#: views/collections/edit.thtml:178
+msgid "collections_edit_icon_replace"
+msgstr "アイコンを変更"
+
+#. %1$s is the label of the edit form's submit button
+#: views/collections/edit.thtml:169
+msgid "collections_edit_icon_toberemoved"
+msgstr "下ã®ã€Œ%1$sã€ã‚’クリックã™ã‚‹ã¨ã‚¢ã‚¤ã‚³ãƒ³ã¯å‰Šé™¤ã•ã‚Œã¾ã™"
+
+#: views/collections/edit.thtml:155
+msgid "collections_edit_nickname_available"
+msgstr "使用å¯èƒ½ãªãƒ‹ãƒƒã‚¯ãƒãƒ¼ãƒ "
+
+#: controllers/collections_controller.php:943
+msgid "collections_edit_nickname_error"
+msgstr ""
+"ã‚ãªãŸãŒå…¥åŠ›ã—ãŸãƒ‹ãƒƒã‚¯ãƒãƒ¼ãƒ ã«ã¯ä¸æ­£ãªæ–‡å­—ãŒå«ã¾ã‚Œã¦ãŠã‚Šã€ä¿®æ­£ãŒè¡Œã‚ã‚Œã¾ã—"
+"ãŸã€‚å†åº¦è©¦ã—ã¦ãã ã•ã„。"
+
+#: views/collections/edit.thtml:156
+msgid "collections_edit_nickname_taken"
+msgstr "æ—¢ã«ä½¿ç”¨ã•ã‚Œã¦ã„るニックãƒãƒ¼ãƒ "
+
+#. This string is followed by a URL pointing to the collection's view page
+#: views/collections/edit.thtml:75
+msgid "collections_edit_saved_nextstep"
+msgstr "ã‚ãªãŸã®ã‚³ãƒ¬ã‚¯ã‚·ãƒ§ãƒ³ã¯ä»¥ä¸‹ã® URL ã§ã‚¢ã‚¯ã‚»ã‚¹ã§ãã¾ã™:"
+
+#: views/collections/edit.thtml:74
+msgid "collections_edit_saved_success"
+msgstr "コレクションã®ä¿å­˜ãŒå®Œäº†ã—ã¾ã—ãŸï¼"
+
+#: views/collections/edit.thtml:169 views/collections/edit.thtml:300
+#: views/collections/edit.thtml:308 views/pages/js_constants.js.thtml:99
+msgid "collections_edit_submit"
+msgstr "コレクションを更新"
+
+#: views/collections/edit.thtml:96 views/collections/edit.thtml:297
+#: views/pages/js_constants.js.thtml:100
+msgid "collections_edit_submit_deletecollection"
+msgstr "コレクションを削除"
+
+#: views/collections/edit.thtml:111
+msgid "collections_edit_tabheader_addons"
+msgstr "アドオン"
+
+#: views/collections/edit.thtml:97 views/collections/edit.thtml:113
+msgid "collections_edit_tabheader_advanced"
+msgstr "詳細"
+
+#: views/collections/edit.thtml:108
+msgid "collections_edit_tabheader_details"
+msgstr "åå‰ã¨è©³ç´°"
+
+#: views/collections/edit.thtml:109
+msgid "collections_edit_tabheader_permissions"
+msgstr "権é™"
+
+#: models/collection_promo.php:53
+msgid "collections_family_tagline"
+msgstr "ã‚ãªãŸã®å­ã©ã‚‚やカレンダーを見守るアドオン"
+
+#: models/collection_promo.php:53
+msgid "collections_family_title"
+msgstr "家æ—ã®ã‚¹ã‚±ã‚¸ãƒ¥ãƒ¼ãƒ«ç®¡ç†"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:70
+msgid "collections_index_a_check_out"
+msgstr "アドオンコレクターをãƒã‚§ãƒƒã‚¯"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:52
+msgid "collections_index_a_create"
+msgstr "コレクションを作æˆ"
+
+#: views/collections/detail.thtml:139 views/collections/listing.thtml:85
+#: views/search/collections.thtml:84
+msgid "collections_index_button_go"
+msgstr "表示"
+
+#. %1$s is a URL.
+#: controllers/collections_controller.php:182
+msgid "collections_index_filler_favorites"
+msgstr ""
+"<p><strong>ã‚ãªãŸã¯ã¾ã ã²ã¨ã¤ã‚‚ãŠæ°—ã«å…¥ã‚Šã®ã‚³ãƒ¬ã‚¯ã‚·ãƒ§ãƒ³ã‚’æŒã£ã¦ã„ã¾ã›ã‚“。"
+"</strong></p><p>ãŠæ°—ã«å…¥ã‚Šã«è¿½åŠ ã—ãŸã‚³ãƒ¬ã‚¯ã‚·ãƒ§ãƒ³ã¯ã“ã®ãƒšãƒ¼ã‚¸ã‹ã‚‰ã™ã°ã‚„ãアク"
+"セスã§ãるよã†ã«ãªã‚Šã€<a href='%1$s'>アドオンコレクター</a> をインストールã—"
+"ã¦ã„ã‚‹å ´åˆã¯ãã®ç”»é¢ã«ã‚‚表示ã•ã‚Œã¾ã™ã€‚"
+
+#. %1$s is a URL.
+#: controllers/collections_controller.php:167
+msgid "collections_index_filler_mine"
+msgstr ""
+"<p>ã‚ãªãŸã¯ã¾ã ã‚³ãƒ¬ã‚¯ã‚·ãƒ§ãƒ³ã‚’作æˆã—ã¦ã„ã¾ã›ã‚“。コレクションã¯ç°¡å˜ã«ä½œã‚Œã¦ã€ãŠ"
+"æ°—ã«å…¥ã‚Šã®ã‚¢ãƒ‰ã‚ªãƒ³ã‚’ã¾ã¨ã‚ã¦ãŠãã“ã¨ãŒã§ãã¾ã™ã€‚<a href=\"%1$s\">ãœã²ãŠè©¦ã—ã"
+"ã ã•ã„</a>。</p>"
+
+#: views/collections/listing.thtml:51
+msgid "collections_index_header_collections"
+msgstr "コレクション"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:60
+msgid "collections_index_header_collector"
+msgstr "アドオンコレクター"
+
+#. %1$s is a comma-separated list of author names
+#: views/elements/amo2009/collection_listing_item.thtml:84
+#: views/collections/detail.thtml:151
+msgid "collections_index_header_created"
+msgstr "作æˆè€…: %1$s"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:47
+msgid "collections_index_header_what"
+msgstr "コレクションã¨ã¯ï¼Ÿ"
+
+#: views/collections/detail.thtml:132 views/collections/listing.thtml:78
+#: views/search/collections.thtml:66
+msgid "collections_index_label_sortby"
+msgstr "並ã¹æ›¿ãˆ"
+
+#: controllers/collections_controller.php:130
+msgid "collections_index_li_editors"
+msgstr "エディタ・ピックアップ"
+
+#: views/collections/subscribe.thtml:64
+#: controllers/collections_controller.php:140
+msgid "collections_index_li_favorites"
+msgstr "自分ã®ãŠæ°—ã«å…¥ã‚Š"
+
+#: controllers/collections_controller.php:138
+msgid "collections_index_li_mine"
+msgstr "自分ã®ã‚³ãƒ¬ã‚¯ã‚·ãƒ§ãƒ³"
+
+#: controllers/collections_controller.php:132
+msgid "collections_index_li_popular"
+msgstr "人気"
+
+#: views/search/collections.thtml:74 controllers/collections_controller.php:81
+msgid "collections_index_option_all"
+msgstr "ã“ã‚Œã¾ã§ã§æœ€ã‚‚人気"
+
+#: views/search/collections.thtml:72 controllers/collections_controller.php:78
+msgid "collections_index_option_month"
+msgstr "今月最も人気"
+
+#: views/search/collections.thtml:76 controllers/collections_controller.php:84
+msgid "collections_index_option_newest"
+msgstr "最新"
+
+#: views/search/collections.thtml:70 controllers/collections_controller.php:75
+msgid "collections_index_option_week"
+msgstr "今週最も人気"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:67
+msgid "collections_index_p_collector"
+msgstr ""
+"ãŠæ°—ã«å…¥ã‚Šã®ã‚¢ãƒ‰ã‚ªãƒ³ã‚’管ç†ã€ç™ºè¦‹ã™ã‚‹æ–°ã—ã„方法ãŒã‚ã‚Šã¾ã™ã€‚コレクションã®ã‚³ãƒ¡"
+"ントã€å…±æœ‰ã€åŒæœŸã‚’ã€ã™ã¹ã¦ãƒ–ラウザ上ã§è¡Œãˆã¾ã™ã€‚"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:48
+msgid "collections_index_p_what_are"
+msgstr ""
+"コレクションã¨ã¯ã€é–¢é€£ã™ã‚‹ã‚¢ãƒ‰ã‚ªãƒ³ã‚’集ã‚ã¦ç°¡å˜ã«å…±æœ‰ã§ãるよã†ã‚°ãƒ«ãƒ¼ãƒ—ã§ã™ã€‚"
+
+#. %s is a date in the _('date') format
+#: views/elements/collections_interactive_addon.thtml:85
+#, php-format
+msgid "collections_interactive_addon_added"
+msgstr "追加日: %s"
+
+#: models/collection_promo.php:55
+msgid "collections_reference_tagline"
+msgstr "オンラインã§ã®èª¿æŸ»ã‚’支æ´ã™ã‚‹ã‚¢ãƒ‰ã‚ªãƒ³"
+
+#: models/collection_promo.php:55
+msgid "collections_reference_title"
+msgstr "リファレンス・デスク"
+
+#: models/collection_promo.php:52
+msgid "collections_social_tagline"
+msgstr "自分ã®ã‚½ãƒ¼ã‚·ãƒ£ãƒ«ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯ã‚’管ç†ã™ã‚‹ã‚¢ãƒ‰ã‚ªãƒ³"
+
+#: models/collection_promo.php:52
+msgid "collections_social_title"
+msgstr "ソーシャル・サーキット"
+
+#: views/collections/subscribe.thtml:91
+msgid "collections_subscribe_button_close"
+msgstr "é–‰ã˜ã‚‹"
+
+#: views/collections/subscribe.thtml:70
+msgid "collections_subscribe_error"
+msgstr ""
+"ãŠæ°—ã«å…¥ã‚Šã®ã‚³ãƒ¬ã‚¯ã‚·ãƒ§ãƒ³ã‚’追加ã™ã‚‹éš›ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚ã“ã®ã‚³ãƒ¬ã‚¯ã‚·ãƒ§ãƒ³"
+"ã¯ã™ã§ã«ãŠæ°—ã«å…¥ã‚Šã¨ã—ã¦è¿½åŠ ã•ã‚Œã¦ã„ã¾ã›ã‚“ã‹ï¼Ÿ"
+
+#: views/collections/subscribe.thtml:96
+msgid "collections_subscribe_label_bothersome"
+msgstr "今後ã“ã®ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã‚’表示ã—ãªã„"
+
+#. %1$s is the collection name
+#: views/collections/subscribe.thtml:60
+msgid "collections_subscribe_success"
+msgstr "%1$s ãŒãŠæ°—ã«å…¥ã‚Šã®ã‚³ãƒ¬ã‚¯ã‚·ãƒ§ãƒ³ã«è¿½åŠ ã•ã‚Œã¾ã—ãŸã€‚"
+
+#. %1$s is the link to the "My Favorites" tab on the main collections page
+#. %2$s is the localized title of the "My Favorites" tab
+#. %3$s is the link URL to the collector add-on
+#: views/collections/subscribe.thtml:62
+msgid "collections_subscribe_success_desc"
+msgstr ""
+"今後ã“ã®ã‚³ãƒ¬ã‚¯ã‚·ãƒ§ãƒ³ã¯ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªå†…ã® <a href=\"%1$s\">%2$s</a> タブã‹ã‚‰ã™ã°"
+"ã‚„ã見ã¤ã‘ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚ã‚‚ã£ã¨ç°¡å˜ã«ãŠæ°—ã«å…¥ã‚Šã®ã‚³ãƒ¬ã‚¯ã‚·ãƒ§ãƒ³ã‚’ãƒã‚§ãƒƒã‚¯ã™"
+"る方法もã‚ã‚Šã¾ã™ã€‚Firefox 用㮠<a href=\"%3$s\">アドオンコレクター</a> ã‚’ãŠè©¦"
+"ã—ãã ã•ã„。"
+
+#: views/collections/listing.thtml:55
+msgid "collections_success_delete"
+msgstr "ã“ã®ã‚³ãƒ¬ã‚¯ã‚·ãƒ§ãƒ³ã¯å‰Šé™¤ã•ã‚Œã¾ã—ãŸã€‚"
+
+#: models/collection_promo.php:54
+msgid "collections_travel_tagline"
+msgstr "ã‚ãªãŸã‚’旅行代ç†åº—ã«å¤‰èº«ã•ã›ã‚‹ã‚¢ãƒ‰ã‚ªãƒ³"
+
+#: models/collection_promo.php:54
+msgid "collections_travel_title"
+msgstr "旅行者å‘ã‘パック"
+
+#. A collection of add-ons that is automatically built for a user. They are "automatically published" to this collection.
+#: controllers/collections_controller.php:581
+msgid "collections_type_autopublisher"
+msgstr "自動追加"
+
+#. A collection that has been chosen by an Editor as notable or exceptional
+#: controllers/collections_controller.php:582
+msgid "collections_type_editorspick"
+msgstr "エディタã®ãŠã™ã™ã‚"
+
+#: controllers/collections_controller.php:580
+msgid "collections_type_normal"
+msgstr "通常"
+
+#: views/collections/subscribe.thtml:84
+msgid "collections_unsubscribe_error"
+msgstr ""
+"ãŠæ°—ã«å…¥ã‚Šã®ã‚³ãƒ¬ã‚¯ã‚·ãƒ§ãƒ³ã‚’削除ã™ã‚‹éš›ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚ã“ã®ã‚³ãƒ¬ã‚¯ã‚·ãƒ§ãƒ³"
+"ã¯ãŠæ°—ã«å…¥ã‚Šã§ã¯ãªã„å¯èƒ½æ€§ãŒã‚ã‚Šã¾ã™ã€‚"
+
+#. %1$s is the collection name
+#: views/collections/subscribe.thtml:78
+msgid "collections_unsubscribe_success"
+msgstr "%1$s ã¯ãŠæ°—ã«å…¥ã‚Šã®ã‚³ãƒ¬ã‚¯ã‚·ãƒ§ãƒ³ã‹ã‚‰å‰Šé™¤ã•ã‚Œã¾ã—ãŸã€‚"
+
+#: models/collection_promo.php:56
+msgid "collections_webdev_tagline"
+msgstr "完璧㪠Web サイトを簡å˜ã«ä½œã‚‹ãŸã‚ã®ã‚¢ãƒ‰ã‚ªãƒ³"
+
+#: models/collection_promo.php:56
+msgid "collections_webdev_title"
+msgstr "Web 開発者å‘ã‘ツール"
+
+#: views/elements/amo2009/collections_sidebar_whatare.thtml:40
+msgid "collections_whatare_header"
+msgstr "コレクションã¨ã¯ï¼Ÿ"
+
+#: views/elements/amo2009/collections_sidebar_whatare.thtml:45
+msgid "collections_whatare_learnmore"
+msgstr "FAQ を読む"
+
+#: views/elements/amo2009/collections_sidebar_whatare.thtml:44
+msgid "collections_whatare_text"
+msgstr ""
+"ãŠæ°—ã«å…¥ã‚Šã®ã‚¢ãƒ‰ã‚ªãƒ³ã‚’管ç†ã€ç™ºè¦‹ã™ã‚‹æ–°ã—ã„方法ãŒã‚ã‚Šã¾ã™ã€‚コレクションã®ã‚³ãƒ¡"
+"ントã€å…±æœ‰ã€åŒæœŸã‚’ã€ã™ã¹ã¦ãƒ–ラウザ上ã§è¡Œãˆã¾ã™ã€‚"
+
+#: views/pages/collector_faq.thtml:61 views/pages/collector_features.thtml:67
+msgid "collector_features_a_home"
+msgstr "アドオンコレクターã®ãƒ›ãƒ¼ãƒ "
+
+#: views/elements/amo2009/collector_sidebar_download.thtml:46
+msgid "collector_features_heading_download"
+msgstr "アドオンコレクターをダウンロード:"
+
+#: views/elements/amo2009/collector_sidebar_download.thtml:43
+#: views/pages/collector_firstrun.thtml:116 views/pages/collector.thtml:69
+msgid "collector_features_img_logo"
+msgstr "アドオンコレクターã®ãƒ­ã‚´"
+
+#: views/compatibility/dashboard.thtml:49
+#: controllers/compatibility_controller.php:72
+msgid "compatibility_dashboard_center_header"
+msgstr "アドオン互æ›æ€§ã‚»ãƒ³ã‚¿ãƒ¼"
+
+#. %1$s is the name of an application and a version. Example: Firefox 3.0
+#. %2$s is the name of an application. Example: Firefox
+#: views/compatibility/dashboard.thtml:50
+msgid "compatibility_dashboard_intro"
+msgstr ""
+"%2$s Add-ons コミュニティã«å‘ã‘ã¦å…¬é–‹ã•ã‚Œã¦ã„ã‚‹ã“れらã®ãƒ„ールã¨æƒ…報を活用ã—"
+"ã¦ã€%1$s ã®ãƒªãƒªãƒ¼ã‚¹ã«å‚™ãˆã¾ã—ょã†ã€‚"
+
+#: views/compatibility/dashboard.thtml:103
+msgid "compatibility_dashboard_loading"
+msgstr "データを読ã¿è¾¼ã‚“ã§ã„ã¾ã™..."
+
+#: views/compatibility/dashboard.thtml:45
+msgid "compatibility_dashboard_main_link"
+msgstr "メインページã¸æˆ»ã‚‹"
+
+#: views/compatibility/dashboard.thtml:100 views/compatibility/report.thtml:43
+msgid "compatibility_dashboard_report"
+msgstr "アドオン互æ›æ€§ãƒ¬ãƒãƒ¼ãƒˆ"
+
+#: views/compatibility/dashboard.thtml:53
+#: views/compatibility/dashboard.thtml:110
+#: views/compatibility/developers.thtml:43
+msgid "compatibility_developer_info"
+msgstr "アドオン開発者å‘ã‘ã®æƒ…å ±"
+
+#: views/compatibility/developers.thtml:66
+msgid "compatibility_developers_adjust_maxversion"
+msgstr "アップロードを行ã‚ãšã« maxVersion を変更"
+
+#: views/compatibility/dashboard.thtml:124
+msgid "compatibility_developers_check_status"
+msgstr "自分ã®ã‚¢ãƒ‰ã‚ªãƒ³ã®ã‚¹ãƒ†ãƒ¼ã‚¿ã‚¹ã‚’確èª"
+
+#. %1$s is a URL
+#. %2$s is an application and version. Example: Firefox 3.0
+#: views/compatibility/dashboard.thtml:126
+msgid "compatibility_developers_login_first"
+msgstr ""
+"Mozilla Add-ons ã«ã‚¢ãƒ‰ã‚ªãƒ³ã‚’登録ã•ã‚Œã¦ã„ã‚‹å ´åˆã¯ã€<a href=\"%1$s\">ログイン</"
+"a> ã—ã¦ã€%2$s ã«å‘ã‘ãŸã‚¢ãƒ‰ã‚ªãƒ³ã®ã‚¹ãƒ†ãƒ¼ã‚¿ã‚¹ã‚’分æžã—ã¦ãã ã•ã„。"
+
+#: views/compatibility/dashboard.thtml:114
+msgid "compatibility_developers_mdclogo_alt"
+msgstr "Mozilla Developer Center ロゴ"
+
+#: views/compatibility/developers.thtml:73
+msgid "compatibility_developers_no_addons"
+msgstr "Mozilla Add-ons ã«ç™»éŒ²ã•ã‚Œã¦ã„ã‚‹ã‚ãªãŸã®ã‚¢ãƒ‰ã‚ªãƒ³ã¯ã‚ã‚Šã¾ã›ã‚“。"
+
+#: views/compatibility/dashboard.thtml:133
+#: views/compatibility/developers.thtml:55
+msgid "compatibility_developers_results"
+msgstr "アドオンã®ã‚¹ãƒ†ãƒ¼ã‚¿ã‚¹ç¢ºèªã®çµæžœ"
+
+#: views/compatibility/dashboard.thtml:137
+msgid "compatibility_developers_retrieving"
+msgstr "登録ã•ã‚Œã¦ã„るアドオンã®ã‚¹ãƒ†ãƒ¼ã‚¿ã‚¹ã‚’å–å¾—ã—ã¦ã„ã¾ã™..."
+
+#. %1$s is a number
+#. %2$s is an application name
+#. %3$s is a number.
+#. Full example: 50 Firefox users (10% of total)
+#: views/compatibility/developers.thtml:65
+msgid "compatibility_developers_user_count"
+msgstr "%1$s %2$s ユーザ (全体㮠%3$s&#37;)"
+
+#: views/compatibility/report.thtml:45
+msgid "compatibility_report_detail_intro"
+msgstr ""
+"以下ã®ã‚¢ãƒ‰ã‚ªãƒ³ã¯ã€Mozilla ãŒæŠŠæ¡ã—ã¦ã„るアドオン利用者㮠95% ã«ä½¿ã‚ã‚Œã¦ã„ã‚‹ã‚‚"
+"ã®ã§ã€åˆ©ç”¨è€…ãŒå¤šã„é †ã«ä¸¦ã¹ã‚‰ã‚Œã¦ã„ã¾ã™ã€‚"
+
+#: views/compatibility/dashboard.thtml:94
+msgid "compatibility_report_detailed_link"
+msgstr "詳細ãªãƒ¬ãƒãƒ¼ãƒˆã‚’表示"
+
+#. %1$s and %2$s are numbers
+#. %3$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:65
+msgid "compatibility_report_intro"
+msgstr ""
+"Mozilla ãŒæŠŠæ¡ã—ã¦ã„るアドオン利用者㮠95% ã«ä½¿ã‚ã‚Œã¦ã„ã‚‹ %1$s 個ã®ã‚¢ãƒ‰ã‚ªãƒ³ã®"
+"ã†ã¡ã€ç¾æ™‚点㧠<b>%2$s&#37;</b> 個㌠%3$s ã®æœ€æ–°ãƒ“ルドã«å¯¾å¿œã—ã¦ã„ã‚‹ã¨åˆ¤æ–­ã•"
+"ã‚Œã¦ã„ã¾ã™ã€‚"
+
+#: views/compatibility/dashboard.thtml:81
+msgid "compatibility_report_legend_alpha"
+msgstr "アルファ版"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:81
+msgid "compatibility_report_legend_alpha_description"
+msgstr "%1$s ã®ã‚¢ãƒ«ãƒ•ã‚¡ç‰ˆã¨äº’æ›æ€§ã®ã‚るアドオン"
+
+#: views/compatibility/dashboard.thtml:85
+msgid "compatibility_report_legend_beta"
+msgstr "ベータ版"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:85
+msgid "compatibility_report_legend_beta_description"
+msgstr "%1$s ã®ãƒ™ãƒ¼ã‚¿ç‰ˆã‚‚ã—ãã¯ãƒªãƒªãƒ¼ã‚¹å€™è£œç‰ˆã¨äº’æ›æ€§ã®ã‚るアドオン"
+
+#: views/compatibility/dashboard.thtml:89
+msgid "compatibility_report_legend_latest"
+msgstr "最新版"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:89
+msgid "compatibility_report_legend_latest_description"
+msgstr "%1$s ã®æœ€æ–°ãƒ“ルドã«å¯¾å¿œã—ã¦ã„るアドオン"
+
+#: views/compatibility/dashboard.thtml:77
+msgid "compatibility_report_legend_other"
+msgstr "ãã®ä»–ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:77
+msgid "compatibility_report_legend_other_description"
+msgstr "%1$s ã®ã„ãšã‚Œã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã¨ã‚‚互æ›æ€§ã®ãªã„アドオン"
+
+#: views/compatibility/dashboard.thtml:62
+msgid "compatibility_report_title"
+msgstr "アドオン互æ›æ€§ãƒ¬ãƒãƒ¼ãƒˆ"
+
+#: views/compatibility/dashboard.thtml:54
+#: views/compatibility/dashboard.thtml:144 views/compatibility/users.thtml:42
+msgid "compatibility_user_info"
+msgstr "アドオンユーザå‘ã‘ã®æƒ…å ±"
+
+#: views/compatibility/dashboard.thtml:52
+msgid "compatibility_view_report"
+msgstr "互æ›æ€§ãƒ¬ãƒãƒ¼ãƒˆã‚’表示"
+
+#. %s is a URL
+#: views/pages/credits.thtml:142
+#, php-format
+msgid "credits_contributing"
+msgstr "å”力方法ã«é–¢ã™ã‚‹æƒ…報㯠%s ã‚’ã”覧ãã ã•ã„。"
+
+#: views/pages/credits.thtml:142
+msgid "credits_contributing_wikipage"
+msgstr "MozillaWiki ã®ãƒšãƒ¼ã‚¸"
+
+#: views/pages/credits.thtml:99
+msgid "credits_intro"
+msgstr ""
+"Mozilla ã¯ã€addons.mozilla.org プロジェクトã«é•·ã„ã“ã¨å”力ã„ãŸã ã„ã¦ã„る以下ã®"
+"皆様ã«æ„Ÿè¬ã„ãŸã—ã¾ã™ã€‚"
+
+#: views/pages/credits.thtml:103
+msgid "credits_section_developers"
+msgstr "開発者"
+
+#: views/pages/credits.thtml:115
+msgid "credits_section_editors"
+msgstr "エディタ"
+
+#: views/pages/credits.thtml:109
+msgid "credits_section_localizers"
+msgstr "ローカライズ担当者"
+
+#: views/pages/credits.thtml:121
+msgid "credits_section_other_contributors"
+msgstr "ãã®ä»–ã®å”力者"
+
+#: views/pages/credits.thtml:127
+msgid "credits_section_past_developers"
+msgstr "éŽåŽ»ã«å”力ã„ãŸã ã„ãŸé–‹ç™ºè€…"
+
+#: views/pages/credits.thtml:133
+msgid "credits_section_software"
+msgstr "ソフトウェアã¨ç”»åƒ"
+
+#: views/pages/credits.thtml:136
+msgid "credits_software_famfamfam"
+msgstr ""
+"ã“ã®ã‚µã‚¤ãƒˆã§ä½¿ç”¨ã—ã¦ã„る一部ã®ã‚¢ã‚¤ã‚³ãƒ³ã¯ã€<a href=\"http://creativecommons."
+"org/licenses/by/2.5/\">Creative Commons Attribution 2.5 License</a> ã®ä¸‹ã§å…¬"
+"é–‹ã•ã‚Œã¦ã„ã‚‹ <a href=\"http://www.famfamfam.com/lab/icons/silk/\">famfamfam "
+"Silk Icon Set</a> ã«å«ã¾ã‚Œã¦ã„ã‚‹ã‚‚ã®ã§ã™ã€‚"
+
+#: views/pages/credits.thtml:137
+msgid "credits_software_timeplot"
+msgstr ""
+"一部ã®ãƒšãƒ¼ã‚¸ã§ã¯ã€<a href=\"http://simile.mit.edu/license.html\">BSD ライセン"
+"ス</a> ã®ä¸‹ã§å…¬é–‹ã•ã‚Œã¦ã„ã‚‹ <a href=\"http://www.simile-widgets.org/timeplot/"
+"\">Timeplot</a> ã®è¦ç´ ã‚’使用ã—ã¦ã„ã¾ã™ã€‚"
+
+#. date format string as used in PHP's strftime():
+#. http://php.net/strftime
+#: views/elements/collections_interactive_addon.thtml:85
+#: views/elements/amo2009/addon_version_detail.thtml:53
+#: views/elements/amo2009/homepage_addon.thtml:115
+#: views/elements/addon_version_detail.thtml:54
+#: views/elements/addon_listitem.thtml:124 views/elements/feature.thtml:106
+#: views/collections/detail.thtml:118 views/collections/edit.thtml:325
+#: views/users/info.thtml:76 views/editors/reviews_queue.thtml:57
+#: views/editors/reviews_queue.thtml:68 views/developers/dashboard.thtml:65
+#: views/developers/versions_edit.thtml:208 views/developers/versions.thtml:67
+#: views/search/rss/index.thtml:5 views/addons/rss/versions.thtml:42
+#: views/addons/display.thtml:104 views/addons/display.thtml:356
+#: views/addons/browse_thumbs.thtml:75 views/reviews/add.thtml:63
+#: views/reviews/display.thtml:74 views/reviews/display.thtml:160
+#: views/reviews/delete.thtml:54 controllers/statistics_controller.php:244
+#: controllers/collections_controller.php:1047
+msgid "date"
+msgstr "%Yå¹´ %b %eæ—¥"
+
+#. date and time format string (strftime)
+#. http://php.net/strftime
+#: views/elements/addon_version_detail.thtml:53
+#: views/developers/discuss.thtml:52 views/developers/discuss.thtml:62
+#: views/admin/addons_status.thtml:57
+msgid "datetime"
+msgstr "%Yå¹´ %b %eæ—¥ %H:%M"
+
+#: views/elements/developers/actionbar.thtml:47
+msgid "devcp_actionbar_link_details"
+msgstr "詳細情報"
+
+#: views/elements/developers/actionbar.thtml:42
+#: views/elements/developers/actionbar.thtml:50
+#: views/developers/dashboard.thtml:64
+msgid "devcp_actionbar_link_edit"
+msgstr "アドオンを編集"
+
+#: views/elements/developers/actionbar.thtml:51
+msgid "devcp_actionbar_link_newversion"
+msgstr "æ–°ã—ã„ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã‚’アップロード"
+
+#: views/elements/developers/actionbar.thtml:44
+#: views/elements/developers/actionbar.thtml:49
+#: views/developers/dashboard.thtml:73
+msgid "devcp_actionbar_link_stats"
+msgstr "統計ダッシュボード"
+
+#. %1$s is a filename, e.g. "foo.txt"
+#. %2$s is the extension, e.g. ".txt"
+#. %3$s is a list of valid extensions, like ".png, .jpg, .gif"
+#: controllers/developers_controller.php:1361
+msgid "devcp_add_previews_extension_error"
+msgstr "ファイル %1$s ã®æ‹¡å¼µå­ (%2$s) ã¯ç„¡åŠ¹ã§ã™ã€‚有効ãªæ‹¡å¼µå­ã¯ %3$s ã§ã™ã€‚"
+
+#. %s is the filename.
+#: controllers/developers_controller.php:1394
+msgid "devcp_add_previews_save_error"
+msgstr "ファイル %s をデータベースã«ä¿å­˜ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚å†åº¦ãŠè©¦ã—ãã ã•ã„。"
+
+#. %1$s is the preview ID number, %2$s is the filename.
+#: controllers/developers_controller.php:1389
+msgid "devcp_add_previews_success_replace"
+msgstr "プレビュー %1$s ã¯ãƒ•ã‚¡ã‚¤ãƒ« %2$s ã«ç½®ãæ›ãˆã‚‰ã‚Œã¾ã—ãŸã€‚"
+
+#. %s is the filename.
+#: controllers/developers_controller.php:1391
+msgid "devcp_add_previews_success_upload"
+msgstr ""
+"ファイル %s ã®ã‚¢ãƒƒãƒ—ロードãŒå®Œäº†ã—ã¾ã—ãŸã€‚下ã®ãƒ•ã‚©ãƒ¼ãƒ ã§ã‚­ãƒ£ãƒ—ションを追加ã§"
+"ãã¾ã™ã€‚"
+
+#: controllers/components/developers.php:1163
+msgid "devcp_additem_addontype_autodetect"
+msgstr "(自動判別)"
+
+#: views/elements/developers/additem.thtml:76
+msgid "devcp_additem_linktitle_opensin_newwindow"
+msgstr "æ–°ã—ã„ウィンドウã§é–‹ã"
+
+#: views/elements/developers/additem.thtml:41
+msgid "devcp_additem_sidebar_title"
+msgstr "アドオンを登録"
+
+#: views/elements/developers/additem.thtml:53
+msgid "devcp_additem_step0_newlink"
+msgstr "開発者利用è¦ç´„"
+
+#: views/elements/developers/additem.thtml:46
+msgid "devcp_additem_step1_link"
+msgstr "ステップ 1: アップロード"
+
+#: views/elements/developers/additem.thtml:47
+msgid "devcp_additem_step2_link"
+msgstr "ステップ 2: アドオンã®è©³ç´°"
+
+#: views/elements/developers/additem.thtml:48
+msgid "devcp_additem_step3_link"
+msgstr "ステップ 3: ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã®è©³ç´°"
+
+#: views/elements/developers/additem.thtml:49
+msgid "devcp_additem_step4_link"
+msgstr "ステップ 4: ローカライズ"
+
+#: views/elements/developers/additem.thtml:50
+msgid "devcp_additem_step5_link"
+msgstr "ステップ 5: 完了"
+
+#: views/elements/developers/additem.thtml:76
+msgid "devcp_additem_submissionhelp_link"
+msgstr "申請ã«é–¢ã™ã‚‹ãƒ˜ãƒ«ãƒ—"
+
+#: controllers/previews_controller.php:168
+#: controllers/previews_controller.php:277
+msgid "devcp_addon_field_preview_caption_displaytitle"
+msgstr "プレビュー画åƒã®ã‚­ãƒ£ãƒ—ション"
+
+#: views/developers/addon_status.thtml:177
+msgid "devcp_addon_status_action_activate"
+msgstr "有効化"
+
+#: views/developers/addon_status.thtml:178
+msgid "devcp_addon_status_action_activate_description"
+msgstr ""
+"アドオンを有効化ã™ã‚‹ã¨ã€å…¬é–‹ãƒšãƒ¼ã‚¸ã¸ã®æŽ²è¼‰ãŒé–‹å§‹ã•ã‚Œã‚‹ã¨ã¨ã‚‚ã«ã€æ›´æ–°ç¢ºèªã‚µãƒ¼"
+"ビスãŒæœ‰åŠ¹ã«ãªã‚Šã¾ã™ã€‚"
+
+#: views/developers/addon_status.thtml:135
+msgid "devcp_addon_status_action_complete"
+msgstr "アドオンを完æˆã•ã›ã‚‹"
+
+#: views/developers/addon_status.thtml:136
+msgid "devcp_addon_status_action_complete_description"
+msgstr "ã“ã®ã‚¢ãƒ‰ã‚ªãƒ³ã‚’完æˆã•ã›ã¦ã‚µãƒ³ãƒ‰ãƒœãƒƒã‚¯ã‚¹ã¸ç§»å‹•ã—ã¾ã™ã€‚"
+
+#: views/developers/addon_status.thtml:181
+msgid "devcp_addon_status_action_deactivate"
+msgstr "無効化"
+
+#: views/developers/addon_status.thtml:182
+msgid "devcp_addon_status_action_deactivate_description"
+msgstr ""
+"アドオンを無効化ã™ã‚‹ã¨ã€å…¬é–‹ãƒšãƒ¼ã‚¸ã«æŽ²è¼‰ã•ã‚Œãªããªã‚Šã€æ›´æ–°ç¢ºèªã‚µãƒ¼ãƒ“スも無効"
+"ã¨ãªã‚Šã¾ã™ã€‚"
+
+#: views/developers/addon_status.thtml:143
+msgid "devcp_addon_status_action_move"
+msgstr "サンドボックスã¸ç§»å‹•"
+
+#: views/developers/addon_status.thtml:144
+msgid "devcp_addon_status_action_move_description"
+msgstr ""
+"ã“ã®ã‚¢ãƒ‰ã‚ªãƒ³ã‚’サンドボックスã¸æˆ»ã—ã¾ã™ã€‚後ã§ã¾ãŸå…¬é–‹ã™ã‚‹ã“ã¨ã‚‚ã§ãã¾ã™ã€‚"
+
+#: views/developers/addon_status.thtml:139
+msgid "devcp_addon_status_action_nominate"
+msgstr "公開を申請"
+
+#: views/developers/addon_status.thtml:140
+msgid "devcp_addon_status_action_nominate_description"
+msgstr "ã“ã®ã‚¢ãƒ‰ã‚ªãƒ³ã®ä¸€èˆ¬å…¬é–‹ã‚’申請ã—ã¾ã™ã€‚"
+
+#: views/developers/addon_status.thtml:147
+msgid "devcp_addon_status_action_public"
+msgstr "公開"
+
+#: views/developers/addon_status.thtml:148
+msgid "devcp_addon_status_action_public_description"
+msgstr "ã“ã®ã‚¢ãƒ‰ã‚ªãƒ³ã‚’å†åº¦å…¬é–‹ã—ã¾ã™ã€‚"
+
+#: views/developers/addon_status.thtml:169
+msgid "devcp_addon_status_active"
+msgstr ""
+"ã“ã®ã‚¢ãƒ‰ã‚ªãƒ³ã¯ <span class=\"inactive-0\">有効</span> ã§ã™ã€‚上記ã®ã‚¹ãƒ†ãƒ¼ã‚¿ã‚¹"
+"ã«å¿œã˜ãŸã™ã¹ã¦ã®å…¬é–‹ãƒšãƒ¼ã‚¸ã«æŽ²è¼‰ã•ã‚Œã¾ã™ã€‚"
+
+#: views/developers/addon_status.thtml:111
+msgid "devcp_addon_status_completion_disabled"
+msgstr ""
+"ã“ã®ã‚¢ãƒ‰ã‚ªãƒ³ã‚’完æˆã•ã›ã¦ <span class=\"status-1\">サンドボックス</span> ã¸ç§»"
+"å‹•ã™ã‚‹ã«ã¯ã€ä¸Šè¨˜ã®è¦ä»¶ã‚’満ãŸã—ã¦ãã ã•ã„。"
+
+#: views/developers/addon_status.thtml:108
+msgid "devcp_addon_status_completion_enabled"
+msgstr ""
+"下ã®ãƒœã‚¿ãƒ³ã‚’クリックã™ã‚‹ã¨ã€ã“ã®ã‚¢ãƒ‰ã‚ªãƒ³ã‚’完æˆã•ã›ã¦ <span class=\"status-1"
+"\">サンドボックス</span> ã¸ç§»å‹•ã•ã›ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚"
+
+#: views/developers/addon_status.thtml:102
+msgid "devcp_addon_status_criteria_category"
+msgstr "å°‘ãªãã¨ã‚‚ã²ã¨ã¤ã¯ã‚«ãƒ†ã‚´ãƒªã‚’é¸æŠžã—ã¦ãã ã•ã„。"
+
+#: views/developers/addon_status.thtml:101
+msgid "devcp_addon_status_criteria_description"
+msgstr "アドオンã®èª¬æ˜Žã‚’入力ã—ã¦ãã ã•ã„。"
+
+#: views/developers/addon_status.thtml:99
+msgid "devcp_addon_status_criteria_name"
+msgstr "アドオンã®ã‚¿ã‚¤ãƒˆãƒ«ã‚’入力ã—ã¦ãã ã•ã„。"
+
+#: views/developers/addon_status.thtml:120
+msgid "devcp_addon_status_criteria_prerelease"
+msgstr "「リリースå‰ã®ã‚¢ãƒ‰ã‚ªãƒ³ã€ã«æŒ‡å®šã•ã‚Œã¦ã„ã¾ã›ã‚“。"
+
+#: views/developers/addon_status.thtml:119
+msgid "devcp_addon_status_criteria_preview"
+msgstr "拡張機能ã¨ãƒ†ãƒ¼ãƒžã«ã¯ã€å°‘ãªãã¨ã‚‚ã²ã¨ã¤ã¯ãƒ—レビュー画åƒãŒå¿…è¦ã§ã™ã€‚"
+
+#: views/developers/addon_status.thtml:100
+msgid "devcp_addon_status_criteria_summary"
+msgstr "アドオンã®è¦ç´„を入力ã—ã¦ãã ã•ã„。"
+
+#. %s is the status in a span, e.g. "<span>_('Public')</span>".
+#: views/developers/addon_status.thtml:58
+msgid "devcp_addon_status_header"
+msgstr "アドオンã®ã‚¹ãƒ†ãƒ¼ã‚¿ã‚¹: %s"
+
+#: views/developers/addon_status.thtml:152
+#: views/developers/addon_status.thtml:173
+msgid "devcp_addon_status_header_actions"
+msgstr "å¯èƒ½ãªã‚¢ã‚¯ã‚·ãƒ§ãƒ³"
+
+#: views/developers/addon_status.thtml:168
+msgid "devcp_addon_status_header_active"
+msgstr "有効ステータス: <span class=\"inactive-0\">有効</span>"
+
+#: views/developers/addon_status.thtml:97
+msgid "devcp_addon_status_header_criteria"
+msgstr "アドオン完æˆè¦ä»¶"
+
+#: views/developers/addon_status.thtml:164
+msgid "devcp_addon_status_header_inactive"
+msgstr "有効ステータス: <span class=\"inactive-1\">無効</span>"
+
+#: views/developers/addon_status.thtml:117
+msgid "devcp_addon_status_header_nomination"
+msgstr "公開申請è¦ä»¶"
+
+#: views/developers/addon_status.thtml:190
+msgid "devcp_addon_status_header_trusted"
+msgstr "信頼ステータス: <span class=\"status-4\">ä¿¡é ¼ã•ã‚Œã¦ã„ã¾ã™</span>"
+
+#: views/developers/addon_status.thtml:165
+msgid "devcp_addon_status_inactive"
+msgstr ""
+"ã“ã®ã‚¢ãƒ‰ã‚ªãƒ³ã¯ <span class=\"inactive-1\">無効</span> ã§ã™ã€‚上記ã®è¦ä»¶ã«ã‹ã‹"
+"ã‚らãšã€ã©ã®å…¬é–‹ãƒšãƒ¼ã‚¸ã«ã‚‚掲載ã•ã‚Œã¾ã›ã‚“。更新確èªã‚µãƒ¼ãƒ“スを通ã˜ãŸã‚¢ãƒ‰ã‚ªãƒ³ã®"
+"æ›´æ–°ã‚‚<b>æä¾›ã•ã‚Œã¾ã›ã‚“</b>。"
+
+#: views/developers/addon_status.thtml:128
+msgid "devcp_addon_status_nominate_disabled"
+msgstr ""
+"ã“ã®ã‚¢ãƒ‰ã‚ªãƒ³ã® <span class=\"status-4\">公開</span> を申請ã™ã‚‹ã«ã¯ã€ä¸Šè¨˜ã®è¦"
+"件を満ãŸã—ã¦ãã ã•ã„。"
+
+#: views/developers/addon_status.thtml:125
+msgid "devcp_addon_status_nominate_enabled"
+msgstr ""
+"下ã®ãƒœã‚¿ãƒ³ã‚’クリックã™ã‚‹ã¨ã€ã“ã®ã‚¢ãƒ‰ã‚ªãƒ³ã® <span class=\"status-1\">公開</"
+"span> を申請ã§ãã¾ã™ã€‚"
+
+#: views/developers/addon_status.thtml:64
+msgid "devcp_addon_status_public"
+msgstr "公開"
+
+#: views/developers/addon_status.thtml:63
+msgid "devcp_addon_status_sandbox"
+msgstr "サンドボックス"
+
+#. %s is an email address.
+#: views/developers/addon_status.thtml:89
+msgid "devcp_addon_status_switch_disabled"
+msgstr ""
+"ã“ã®ã‚¢ãƒ‰ã‚ªãƒ³ã¯ã€ç®¡ç†è€…ã«ã‚ˆã£ã¦ <span class=\"status-5\">無効</span> 化ã•ã‚Œã€"
+"使用ä¸å¯ã¨ãªã£ã¦ã„ã¾ã™ã€‚何ã‹è³ªå•ãŒã‚ã‚‹å ´åˆã¯ %s ã¸ãƒ¡ãƒ¼ãƒ«ã‚’é€ã£ã¦ãã ã•ã„。"
+
+#: views/developers/addon_status.thtml:67
+msgid "devcp_addon_status_switch_incomplete"
+msgstr ""
+"ã“ã®ã‚¢ãƒ‰ã‚ªãƒ³ã¯ã€ç¾æ™‚点ã§ã¯ã¾ã  <span class=\"status-0\">ä¸å®Œå…¨</span> ãªçŠ¶æ…‹"
+"ã§ã™ã€‚サイト上ã®å…¬é–‹ãƒšãƒ¼ã‚¸ã«ã¯ä¸€åˆ‡æŽ²è¼‰ã•ã‚Œãšã€æ›´æ–°ç¢ºèªã‚µãƒ¼ãƒ“スを通ã˜ãŸæ›´æ–°ã‚‚"
+"æä¾›ã•ã‚Œã¾ã›ã‚“。以下ã®è¦ä»¶ã‚’満ãŸã—ã¦ã‹ã‚‰ã“ã®ãƒšãƒ¼ã‚¸ã¸æˆ»ã£ã¦ãã‚Œã°ã€ã‚¢ãƒ‰ã‚ªãƒ³ã‚’"
+"完æˆã•ã›ã¦ <span class=\"status-1\">サンドボックス</span> ã¸ç§»å‹•ã™ã‚‹ã“ã¨ãŒã§"
+"ãã¾ã™ã€‚"
+
+#. %s is a number, perhaps 42.
+#: views/developers/addon_status.thtml:77
+msgid "devcp_addon_status_switch_nominated"
+msgstr ""
+"ã“ã®ã‚¢ãƒ‰ã‚ªãƒ³ã¯ã€<span class=\"status-4\">公開</span> 申請ãŒè¡Œã‚ã‚Œã¦ãŠã‚Šã€ã‚¨"
+"ディタã«ã‚ˆã‚‹ãƒ¬ãƒ“ューã®å®Œäº†ã‚’å¾…ã£ã¦ã„ã¾ã™ã€‚ç¾åœ¨ä»–ã« %s 個ã®ã‚¢ãƒ‰ã‚ªãƒ³ãŒãƒ¬ãƒ“ュー"
+"ã‚’å¾…ã£ã¦ã„ã¾ã™ã€‚"
+
+#. %s is an email address.
+#: views/developers/addon_status.thtml:81
+msgid "devcp_addon_status_switch_pending"
+msgstr ""
+"ã“ã®ã‚¢ãƒ‰ã‚ªãƒ³ã¯ä¿ç•™ã•ã‚Œã¦ã„ã¾ã™ã€‚ã“ã‚Œã¯äºˆæœŸã›ã¬çŠ¶æ…‹ã§ã™ã€‚アドオン㮠ID を記載"
+"ã—ãŸãƒ¡ãƒ¼ãƒ«ã‚’ %s ã¸é€ã‚Šã€ã“ã®ã‚¨ãƒ©ãƒ¼ã«ã¤ã„ã¦çŸ¥ã‚‰ã›ã¦ãã ã•ã„。"
+
+#: views/developers/addon_status.thtml:85
+msgid "devcp_addon_status_switch_public"
+msgstr ""
+"ã“ã®ã‚¢ãƒ‰ã‚ªãƒ³ã¯ <span class=\"status-4\">公開</span> ã•ã‚Œã¦ã„ã¾ã™ã€‚ã™ã¹ã¦ã®å…¬"
+"開ページや検索çµæžœã«æŽ²è¼‰ã•ã‚Œã¦ãŠã‚Šã€èª°ã§ã‚‚制é™ãªã—ã«ãƒ€ã‚¦ãƒ³ãƒ­ãƒ¼ãƒ‰ã§ãるよã†ã«"
+"ãªã£ã¦ã„ã¾ã™ã€‚更新確èªã‚µãƒ¼ãƒ“スを通ã˜ãŸã‚¢ãƒ‰ã‚ªãƒ³ã®æ›´æ–°ã‚‚æä¾›ã•ã‚Œã¦ã„ã¾ã™ã€‚"
+
+#: views/developers/addon_status.thtml:71
+#: views/developers/addon_status.thtml:75
+msgid "devcp_addon_status_switch_sandbox"
+msgstr ""
+"ã“ã®ã‚¢ãƒ‰ã‚ªãƒ³ã¯ <span class=\"status-1\">サンドボックス</span> ã«ç½®ã‹ã‚Œã¦ã„ã¾"
+"ã™ã€‚公開ページや検索çµæžœã«æŽ²è¼‰ã•ã‚Œã¦ã„ã¾ã™ãŒã€ãƒ€ã‚¦ãƒ³ãƒ­ãƒ¼ãƒ‰ã®éš›ã«ãƒ¦ãƒ¼ã‚¶ã®ãƒ­ã‚°"
+"インを必è¦ã¨ã—ã¾ã™ã€‚更新確èªã‚µãƒ¼ãƒ“スを通ã˜ãŸã‚¢ãƒ‰ã‚ªãƒ³ã®æ›´æ–°ã¯<b>æä¾›ã•ã‚Œã¦ã„ã¾"
+"ã›ã‚“</b>。"
+
+#. %s is the add-on name.
+#: views/developers/addon_status_nominate.thtml:43
+#: views/developers/addon_status_confirm.thtml:43
+#: views/developers/addon_status.thtml:43
+msgid "devcp_addon_status_title"
+msgstr "%s ã®ã‚¹ãƒ†ãƒ¼ã‚¿ã‚¹"
+
+#: views/developers/addon_status.thtml:191
+msgid "devcp_addon_status_trusted"
+msgstr ""
+"ã“ã®ã‚¢ãƒ‰ã‚ªãƒ³ã¯ <span class=\"status-4\">ä¿¡é ¼ã•ã‚Œã¦ã„ã¾ã™</span>。エディタã«ã‚ˆ"
+"るレビューをå—ã‘ã‚‹ã“ã¨ãªãæ–°ã—ã„ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã‚’公開ã§ãã¾ã™ã€‚"
+
+#: views/developers/dashboard.thtml:68
+msgid "devcp_dashboard_active"
+msgstr "有効"
+
+#. %1$s is the add-on type string
+#. %2$s is Inactive or Active in a <span>
+#. %3$s is the addon's public status (Public, In Sandbox, ...) in a <span>
+#: views/developers/dashboard.thtml:69
+msgid "devcp_dashboard_addontype_status"
+msgstr "アドオンã®ç¨®é¡žã¯ %1$sã€ã‚¹ãƒ†ãƒ¼ã‚¿ã‚¹ã¯ %2$sã€%3$s ã§ã™"
+
+#: views/developers/dashboard.thtml:67
+msgid "devcp_dashboard_change_status"
+msgstr "ステータスを変更"
+
+#. %s is the addons email address.
+#: views/developers/dashboard.thtml:99
+msgid "devcp_dashboard_disabled_questions"
+msgstr ""
+"ã“ã®ã‚¢ãƒ‰ã‚ªãƒ³ã¯ç®¡ç†è€…ã«ã‚ˆã£ã¦ç„¡åŠ¹åŒ–ã•ã‚Œã€ä½¿ç”¨ä¸å¯ã¨ãªã£ã¦ã„ã¾ã™ã€‚何ã‹è³ªå•ãŒã‚"
+"ã‚‹å ´åˆã¯ %s ã¸ãƒ¡ãƒ¼ãƒ«ã‚’é€ã£ã¦ãã ã•ã„。"
+
+#. %s is the (localized) add-on status string in a span, e.g. "Disabled"
+#: views/developers/dashboard.thtml:98
+msgid "devcp_dashboard_disabled_status"
+msgstr "アドオンã®ã‚¹ãƒ†ãƒ¼ã‚¿ã‚¹: %s"
+
+#: views/developers/dashboard.thtml:43
+msgid "devcp_dashboard_header_main"
+msgstr "開発者ダッシュボード"
+
+#: views/developers/dashboard.thtml:110
+msgid "devcp_dashboard_header_welcome"
+msgstr "開発者ダッシュボードã¸ã‚ˆã†ã“ã"
+
+#: views/developers/dashboard.thtml:68
+msgid "devcp_dashboard_inactive"
+msgstr "無効"
+
+#. %s is a date in the _('date') format
+#: views/developers/dashboard.thtml:65
+msgid "devcp_dashboard_last_edited"
+msgstr "最終更新日: %s"
+
+#: views/developers/dashboard.thtml:111
+msgid "devcp_dashboard_learn"
+msgstr ""
+"ã‚ãªãŸã¯ã¾ã  Mozilla Add-ons ã«ä½•ã‚‚アドオンを登録ã—ã¦ã„ã¾ã›ã‚“。公開ã¾ã§ã®æµã‚Œ"
+"ã«ã¤ã„ã¦çŸ¥ã‚Šã€æœ€åˆã®ã‚¢ãƒ‰ã‚ªãƒ³ã‚’登録ã™ã‚‹ã«ã¯ã€ä¸‹ã®ã€Œã‚¹ã‚¿ãƒ¼ãƒˆã€ã‚’クリックã—ã¦ã"
+"ã ã•ã„。"
+
+#: views/developers/dashboard.thtml:112
+msgid "devcp_dashboard_start"
+msgstr "スタート"
+
+#: views/developers/dashboard.thtml:82
+msgid "devcp_dashboard_versions"
+msgstr "ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã¨ãƒ•ã‚¡ã‚¤ãƒ«"
+
+#: views/developers/dashboard.thtml:91
+msgid "devcp_dashboard_versions_new"
+msgstr "æ–°ã—ã„ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã‚’アップロード"
+
+#. %s is the preview ID number.
+#: controllers/developers_controller.php:1415
+msgid "devcp_delete_previews_error"
+msgstr ""
+"プレビュー %s をデータベースã‹ã‚‰å‰Šé™¤ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚å†åº¦ãŠè©¦ã—ãã ã•ã„。"
+
+#. %s is the preview ID number.
+#: controllers/developers_controller.php:1413
+msgid "devcp_delete_previews_success"
+msgstr "プレビュー %s ã®å‰Šé™¤ãŒå®Œäº†ã—ã¾ã—ãŸã€‚"
+
+#: controllers/developers_controller.php:1089
+msgid "devcp_delete_version_priv_error"
+msgstr "ã‚ãªãŸã«ã¯ã“ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã‚‚ã—ãã¯ãƒ•ã‚¡ã‚¤ãƒ«ã‚’削除ã™ã‚‹æ¨©é™ãŒã‚ã‚Šã¾ã›ã‚“。"
+
+#. %1$s is the count of files, a number
+#. %2$s is a status string like _('Public') or _('Incomplete')
+#: controllers/components/amo.php:549
+msgid "devcp_describe_version_status"
+msgid_plural "devcp_describe_version_status"
+msgstr[0] "%1$s 件㮠%2$s ファイル"
+msgstr[1] "%1$s 件㮠%2$s ファイル"
+
+#. %s is a version number. Example: 3.0
+#: views/developers/versions.thtml:65
+#, php-format
+msgid "devcp_details_version"
+msgstr "ãƒãƒ¼ã‚¸ãƒ§ãƒ³ %s"
+
+#: views/developers/discuss.thtml:68
+msgid "devcp_discuss_addreply_header"
+msgstr "返信を追加"
+
+#: views/developers/discuss.thtml:57
+msgid "devcp_discuss_allreplies_header"
+msgstr "返信"
+
+#. notice when an error occurs saving a discussion reply
+#. %1 is the email address (linked) for the amo-editors list
+#: views/developers/discuss.thtml:70
+msgid "devcp_discuss_error_notice"
+msgstr ""
+"返信をä¿å­˜ã™ã‚‹éš›ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚%1$s ã¾ã§ã“ã®å•é¡Œã‚’ã”報告ãã ã•ã„。"
+
+#. %1 is the add-on name, %2 is the add-on's version number currently being reviewed by an editor
+#: views/developers/discuss.thtml:46
+msgid "devcp_discuss_intro"
+msgstr ""
+"Mozilla Add-ons ã®ã‚¨ãƒ‡ã‚£ã‚¿ãŒã€ã‚ãªãŸã®ã‚¢ãƒ‰ã‚ªãƒ³ %1$s ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ %2$s ã«é–¢ã—"
+"ã¦ã€ã‚ˆã‚Šè©³ã—ã„情報をæä¾›ã™ã‚‹ã‚ˆã†æ±‚ã‚ã¾ã—ãŸã€‚"
+
+#. %1 is the add-on name
+#: views/developers/discuss.thtml:43
+msgid "devcp_discuss_pagetitle"
+msgstr "%1$s ã®ã‚¢ãƒ‰ã‚ªãƒ³ãƒ¬ãƒ“ューã«ã¤ã„ã¦ã‚ˆã‚Šè©³ã—ã„情報をæä¾›ã™ã‚‹"
+
+#. submit button text
+#: views/developers/discuss.thtml:79
+msgid "devcp_discuss_submit_reply"
+msgstr "返信を往信"
+
+#: views/developers/discuss.thtml:72
+msgid "devcp_discuss_success_message"
+msgstr ""
+"返信ã®ä¿å­˜ãŒå®Œäº†ã—ã¾ã—ãŸã€‚è­°è«–ã«å‚加ã—ã¦ã„ã‚‹ä»–ã®äººã«ã¯ã€ãƒ¡ãƒ¼ãƒ«ã«ã‚ˆã‚‹é€šçŸ¥ãŒé€"
+"られã¾ã™ã€‚"
+
+#. in an author/editor discussion about an add-on to be reviewed:
+#. %1 is the commenter's user name (linked).
+#. %2 is the full date the comment was made.
+#: views/developers/discuss.thtml:52 views/developers/discuss.thtml:62
+msgid "devcp_discuss_writtenby"
+msgstr "投稿者: %1$s - 投稿日時: %2$s"
+
+#: views/developers/addon_edit_authors.thtml:72
+#: views/developers/addon_edit_authors.thtml:81
+msgid "devcp_edit_authors_add_author"
+msgstr "æ–°ã—ã„作者を追加"
+
+#: views/developers/addon_edit_authors.thtml:96
+msgid "devcp_edit_authors_add_author_button"
+msgstr "作者を追加"
+
+#: views/developers/addon_edit_authors.thtml:83
+msgid "devcp_edit_authors_add_email"
+msgstr "作者アカウントã®ãƒ¡ãƒ¼ãƒ«ã‚¢ãƒ‰ãƒ¬ã‚¹:"
+
+#: views/developers/addon_edit_authors.thtml:98
+msgid "devcp_edit_authors_add_loading"
+msgstr "アカウントã®ãƒ¡ãƒ¼ãƒ«ã‚¢ãƒ‰ãƒ¬ã‚¹ã‚’確èªã—ã¦ã„ã¾ã™..."
+
+#: views/developers/addon_edit_authors.thtml:70
+msgid "devcp_edit_authors_click_save"
+msgstr "ä¿å­˜ã™ã‚‹ã«ã¯ã€ä¸‹ã®ã€Œä½œè€…情報を更新ã€ãƒœã‚¿ãƒ³ã‚’クリックã—ã¦ãã ã•ã„。"
+
+#: views/developers/addon_edit_authors.thtml:58
+msgid "devcp_edit_authors_header_current"
+msgstr "ç¾åœ¨ã®ä½œè€…"
+
+#: views/developers/addon_edit_authors.thtml:50
+msgid "devcp_edit_authors_header_manage"
+msgstr "アドオンã®ä½œè€…を管ç†"
+
+#: views/developers/addon_edit_authors.thtml:93
+msgid "devcp_edit_authors_label_add_listed"
+msgstr "公開ページã«ä½œè€…ã¨ã—ã¦è¨˜è¼‰ã™ã‚‹"
+
+#: views/developers/addon_edit_authors.thtml:89
+msgid "devcp_edit_authors_label_developer"
+msgstr ""
+"<strong>開発者</strong> - アドオンã®å…¬é–‹ã«é–¢ã™ã‚‹ã™ã¹ã¦ã®æƒ…報を管ç†ã§ãã¾ã™ã€‚"
+"ãŸã ã—ã€ä»–ã®ä½œè€…を追加ã—ãŸã‚Šå‰Šé™¤ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“。"
+
+#: views/developers/addon_edit_authors.thtml:88
+msgid "devcp_edit_authors_label_owner"
+msgstr ""
+"<strong>オーナー</strong> - アドオンã®å…¬é–‹ã«é–¢ã™ã‚‹ã™ã¹ã¦ã®æƒ…報を管ç†ã§ãã¾"
+"ã™ã€‚ä»–ã®ä½œè€…を追加ã—ãŸã‚Šå‰Šé™¤ã™ã‚‹ã“ã¨ã‚‚ã§ãã¾ã™ã€‚"
+
+#: views/developers/addon_edit_authors.thtml:90
+msgid "devcp_edit_authors_label_viewer"
+msgstr ""
+"<strong>閲覧者</strong> - アドオンã®é–‹ç™ºè€…情報や統計情報を見るã“ã¨ã¯ã§ãã¾ã™"
+"ãŒã€å¤‰æ›´ã‚’è¡Œã†ã“ã¨ã¯ã§ãã¾ã›ã‚“。"
+
+#. Placeholder for the empty option in a <select>.
+#: views/developers/addon_edit_categories.thtml:69
+msgid "devcp_edit_authors_option_empty"
+msgstr "----------------"
+
+#: views/developers/addon_edit_authors.thtml:86
+msgid "devcp_edit_authors_select_role"
+msgstr "作者ã®å½¹å‰²ã‚’é¸æŠžã—ã¦ãã ã•ã„:"
+
+#. Column name in a table.
+#: views/developers/addon_edit_authors.thtml:62
+msgid "devcp_edit_authors_th_author"
+msgstr "作者"
+
+#. Column name in a table.
+#: views/developers/addon_edit_authors.thtml:64
+msgid "devcp_edit_authors_th_listed"
+msgstr "表示"
+
+#. Column name in a table.
+#: views/developers/addon_edit_authors.thtml:63
+msgid "devcp_edit_authors_th_role"
+msgstr "役割"
+
+#: views/developers/addon_edit_authors.thtml:77
+msgid "devcp_edit_authors_update_author"
+msgstr "作者情報を更新"
+
+#: views/developers/addon_edit_categories.thtml:99
+msgid "devcp_edit_categories_button_update"
+msgstr "カテゴリを更新"
+
+#: views/developers/addon_edit_categories.thtml:88
+msgid "devcp_edit_categories_does_not_fit"
+msgstr "自分ã®ã‚¢ãƒ‰ã‚ªãƒ³ã¯æ—¢å­˜ã®ã©ã®ã‚«ãƒ†ã‚´ãƒªã«ã‚‚当ã¦ã¯ã¾ã‚Šã¾ã›ã‚“。"
+
+#. %s is the application name (Firefox, Thunderbird).
+#: views/developers/addon_edit_categories.thtml:61
+msgid "devcp_edit_categories_header_application"
+msgstr "%s ã®ã‚«ãƒ†ã‚´ãƒª"
+
+#: views/developers/addon_edit_categories.thtml:49
+msgid "devcp_edit_categories_header_manage"
+msgstr "アドオンã®ã‚«ãƒ†ã‚´ãƒªã‚’管ç†"
+
+#: views/developers/addon_edit_categories.thtml:91
+msgid "devcp_edit_categories_hover"
+msgstr "å„カテゴリã«ãƒžã‚¦ã‚¹ã‚«ãƒ¼ã‚½ãƒ«ã‚’ä¹—ã›ã‚‹ã¨èª¬æ˜Žã‚’見るã“ã¨ãŒã§ãã¾ã™ã€‚"
+
+#. %s is the category number (1, 2, 3).
+#: views/developers/addon_edit_categories.thtml:67
+msgid "devcp_edit_categories_label_category_num"
+msgstr "カテゴリ %s"
+
+#: views/developers/addon_edit_categories.thtml:94
+#: views/developers/addon_edit_categories.thtml:103
+msgid "devcp_edit_categories_none_available"
+msgstr "ã“ã®ã‚¢ãƒ‰ã‚ªãƒ³ã®ç¨®é¡žã¨ã‚¢ãƒ—リケーションã«æŒ‡å®šã§ãるカテゴリã¯ã‚ã‚Šã¾ã›ã‚“。"
+
+#: views/developers/addon_edit_categories.thtml:86
+msgid "devcp_edit_categories_other"
+msgstr ""
+"既存ã®ä»–ã®ã‚«ãƒ†ã‚´ãƒªã«å½“ã¦ã¯ã¾ã‚‰ãªã„å ´åˆã®ã¿ã€ã“ã®ã‚«ãƒ†ã‚´ãƒªã‚’指定ã—ã¦ãã ã•ã„。"
+
+#. %s is the application name (Firefox, Thunderbird).
+#: views/developers/addon_edit_categories.thtml:63
+msgid "devcp_edit_categories_select_application_categories"
+msgstr "ã“ã®ã‚¢ãƒ‰ã‚ªãƒ³ã®ã‚«ãƒ†ã‚´ãƒªã‚’最大 3 ã¤ã¾ã§é¸æŠžã—ã¦ãã ã•ã„。"
+
+#: views/developers/addon_edit.thtml:47
+msgid "devcp_edit_dd_manage_authors"
+msgstr "ã“ã®ã‚¢ãƒ‰ã‚ªãƒ³ã‚’管ç†ã§ãるユーザを追加ã€å‰Šé™¤ã—ã¾ã™ã€‚"
+
+#: views/developers/addon_edit.thtml:49
+msgid "devcp_edit_dd_manage_categories"
+msgstr ""
+"ã“ã®ã‚¢ãƒ‰ã‚ªãƒ³ãŒå¯¾å¿œã—ã¦ã„ã‚‹å„アプリケーションã«ã¤ã„ã¦ã€é–¢é€£ã™ã‚‹ã‚«ãƒ†ã‚´ãƒªã‚’é¸æŠž"
+"ã—ã¦ãã ã•ã„。"
+
+#: views/developers/addon_edit.thtml:51
+msgid "devcp_edit_dd_manage_description"
+msgstr ""
+"ã“ã®ã‚¢ãƒ‰ã‚ªãƒ³ã®è¦ç´„ã€èª¬æ˜Žã€ã‚¨ãƒ³ãƒ‰ãƒ¦ãƒ¼ã‚¶ãƒ©ã‚¤ã‚»ãƒ³ã‚¹å¥‘ç´„ã€ãƒ—ライãƒã‚·ãƒ¼ãƒãƒªã‚·ãƒ¼ã®"
+"翻訳を追加ã€ç·¨é›†ã—ã¾ã™ã€‚"
+
+#: views/developers/addon_edit.thtml:53
+msgid "devcp_edit_dd_manage_properties"
+msgstr ""
+"ã“ã®ã‚¢ãƒ‰ã‚ªãƒ³ã®ã‚¿ã‚¤ãƒˆãƒ«ã€ãƒ›ãƒ¼ãƒ ãƒšãƒ¼ã‚¸ã€ã‚¢ã‚¤ã‚³ãƒ³ã€ãã®ä»–ã®ãƒ•ãƒ©ã‚°ã‚’変更ã—ã¾ã™ã€‚"
+
+#: views/developers/addon_edit_descriptions.thtml:116
+msgid "devcp_edit_description_button_update"
+msgstr "説明を更新"
+
+#: views/developers/addon_edit_descriptions.thtml:115
+msgid "devcp_edit_description_correct_error"
+msgstr "赤色ã§ç¤ºã•ã‚Œã¦ã„る上記ã®ã‚¨ãƒ©ãƒ¼ã‚’訂正ã—ã¦ãã ã•ã„。"
+
+#: views/developers/addon_edit_descriptions.thtml:51
+msgid "devcp_edit_descriptions_header"
+msgstr "アドオンã®èª¬æ˜Žã‚’編集"
+
+#: views/developers/addon_edit_descriptions.thtml:94
+msgid "devcp_edit_descriptions_transbox_comments_description"
+msgstr ""
+"アドオンã®è¦ç´„や説明ã«ã¯è©²å½“ã—ãªã„ã€ã‚¨ãƒ³ãƒ‰ãƒ¦ãƒ¼ã‚¶ãŒçŸ¥ã‚ŠãŸã„ã¨æ€ã‚れるã‚らゆる"
+"情報を記述ã—ã¾ã™ã€‚例ãˆã°ã€ä¸»ãªæ—¢çŸ¥ã®ãƒã‚°ã€ãƒã‚°å ±å‘Šã®æ‰‹é †ã€æ–°ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã®ãƒª"
+"リース予定日ãªã©ã‚’記載ã™ã‚‹ã®ã«ä½¿ç”¨ã§ãã¾ã™ã€‚"
+
+#: views/developers/addon_edit_descriptions.thtml:93
+msgid "devcp_edit_descriptions_transbox_comments_name"
+msgstr "開発者ã®ã‚³ãƒ¡ãƒ³ãƒˆ"
+
+#: views/developers/addon_edit_descriptions.thtml:86
+msgid "devcp_edit_descriptions_transbox_description_description"
+msgstr ""
+"説明ã«ã¯ã€ã“ã®ã‚¢ãƒ‰ã‚ªãƒ³ã®æ©Ÿèƒ½ã‚„特長ã€ãã®ä»–関連情報をより詳ã—ã記述ã—ã¾ã™ã€‚ã“"
+"ã®æƒ…å ±ã¯ã‚¢ãƒ‰ã‚ªãƒ³å…¬é–‹ãƒšãƒ¼ã‚¸ã®è¦ç´„ã®ä¸‹ã«è¡¨ç¤ºã•ã‚Œã¾ã™ã€‚"
+
+#: views/developers/addon_edit_descriptions.thtml:85
+msgid "devcp_edit_descriptions_transbox_description_name"
+msgstr "アドオンã®èª¬æ˜Ž"
+
+#: views/developers/addon_edit_descriptions.thtml:103
+msgid "devcp_edit_descriptions_transbox_eula_description"
+msgstr ""
+"ã“ã®ã‚¢ãƒ‰ã‚ªãƒ³ã«ã‚¨ãƒ³ãƒ‰ãƒ¦ãƒ¼ã‚¶ãƒ©ã‚¤ã‚»ãƒ³ã‚¹å¥‘ç´„ (EULA) ãŒä»˜éšã™ã‚‹å ´åˆã¯ã€ãã®å†…容を"
+"以下ã®æ¬„ã«å…¥åŠ›ã—ã¦ãã ã•ã„。ã“ã“㧠EULA を設定ã™ã‚‹ã¨ã€ãƒ¦ãƒ¼ã‚¶ã¯ã‚¢ãƒ‰ã‚ªãƒ³ã‚’イン"
+"ストールã™ã‚‹å‰ã«åŒæ„を求ã‚られã¾ã™ã€‚EULA ã¯ã€GPL ã‚„ MPL ãªã©ã‚½ãƒ¼ã‚¹ã‚³ãƒ¼ãƒ‰ã®ãƒ©"
+"イセンスã¨åŒã˜ã§ã¯ãªã„ã“ã¨ã«æ³¨æ„ã—ã¦ãã ã•ã„。"
+
+#: views/developers/addon_edit_descriptions.thtml:102
+msgid "devcp_edit_descriptions_transbox_eula_name"
+msgstr "エンドユーザライセンス契約"
+
+#: views/developers/addon_edit_descriptions.thtml:112
+msgid "devcp_edit_descriptions_transbox_privacy_description"
+msgstr ""
+"ã“ã®ã‚¢ãƒ‰ã‚ªãƒ³ã«ãƒ—ライãƒã‚·ãƒ¼ãƒãƒªã‚·ãƒ¼ãŒä»˜éšã™ã‚‹å ´åˆã¯ã€ãã®å†…容を以下ã®æ¬„ã«å…¥åŠ›"
+"ã—ã¦ãã ã•ã„。アドオンã®å…¬é–‹ãƒšãƒ¼ã‚¸ã«ãƒãƒªã‚·ãƒ¼ã¸ã®ãƒªãƒ³ã‚¯ãŒè¡¨ç¤ºã•ã‚Œã¾ã™ã€‚"
+
+#: views/developers/addon_edit_descriptions.thtml:111
+msgid "devcp_edit_descriptions_transbox_privacy_name"
+msgstr "プライãƒã‚·ãƒ¼ãƒãƒªã‚·ãƒ¼"
+
+#: views/developers/addon_edit_descriptions.thtml:78
+msgid "devcp_edit_descriptions_transbox_summary_description"
+msgstr ""
+"è¦ç´„ã«ã¯ã€æ¤œç´¢çµæžœã‚„アドオン公開ページã®æœ€ä¸Šéƒ¨ã«è¡¨ç¤ºã•ã‚Œã‚‹ã€ã‚¢ãƒ‰ã‚ªãƒ³ã®åŸºæœ¬æ©Ÿ"
+"能ã®ç°¡å˜ãªèª¬æ˜Žã‚’記述ã—ã¾ã™ã€‚<strong>åŠè§’ 250 文字ã¾ã§</strong>入力ã§ãã¾ã™ã€‚"
+
+#: views/developers/addon_edit_descriptions.thtml:77
+msgid "devcp_edit_descriptions_transbox_summary_name"
+msgstr "アドオンã®è¦ç´„"
+
+#: views/developers/addon_edit.thtml:46
+msgid "devcp_edit_dt_manage_authors"
+msgstr "アドオンã®ä½œè€…情報を管ç†"
+
+#: views/developers/addon_edit.thtml:48
+msgid "devcp_edit_dt_manage_categories"
+msgstr "アドオンã®ã‚«ãƒ†ã‚´ãƒªã‚’管ç†"
+
+#: views/developers/addon_edit.thtml:50
+msgid "devcp_edit_dt_manage_descriptions"
+msgstr "アドオンã®èª¬æ˜Žã‚’管ç†"
+
+#: views/developers/addon_edit.thtml:52
+msgid "devcp_edit_dt_manage_properties"
+msgstr "アドオンã®ãƒ—ロパティを管ç†"
+
+#: views/developers/addon_edit_properties.thtml:170
+msgid "devcp_edit_label_externalsoftware"
+msgstr "ã“ã®ã‚¢ãƒ‰ã‚ªãƒ³ã¯å¤–部アプリケーションを必è¦ã¨ã—ã¾ã™"
+
+#: views/developers/addon_edit_properties.thtml:205
+msgid "devcp_edit_label_locale_disambiguation"
+msgstr "追加ã®ãƒ­ã‚±ãƒ¼ãƒ«æƒ…å ±"
+
+#: views/developers/addon_edit_properties.thtml:168
+msgid "devcp_edit_label_prerelease"
+msgstr "ã“ã‚Œã¯æ­£å¼ãƒªãƒªãƒ¼ã‚¹å‰ã®ã‚¢ãƒ‰ã‚ªãƒ³ã§ã™"
+
+#: views/developers/addon_edit_properties.thtml:169
+msgid "devcp_edit_label_sitespecific"
+msgstr "ã“ã‚Œã¯ç‰¹å®šã®ã‚µã‚¤ãƒˆç”¨ã®ã‚¢ãƒ‰ã‚ªãƒ³ã§ã™"
+
+#: views/developers/addon_edit_properties.thtml:202
+msgid "devcp_edit_label_target_locale"
+msgstr "対象ロケール"
+
+#: views/developers/addon_edit_properties.thtml:212
+msgid "devcp_edit_properties_button_update"
+msgstr "プロパティを更新"
+
+#: views/developers/addon_edit_properties.thtml:198
+msgid "devcp_edit_properties_change_guid"
+msgstr "変更ã—ãŸçµæžœã‚’完全ã«ç†è§£ã—ã¦ã„ã‚‹å ´åˆã®ã¿ã€å¤‰æ›´ã‚’è¡Œã£ã¦ãã ã•ã„。"
+
+#: views/developers/addon_edit_properties.thtml:109
+msgid "devcp_edit_properties_current_icon"
+msgstr "ç¾åœ¨ã®ã‚¢ã‚¤ã‚³ãƒ³"
+
+#: views/developers/addon_edit_properties.thtml:85
+msgid "devcp_edit_properties_default_locale"
+msgstr ""
+"既定ã®ãƒ­ã‚±ãƒ¼ãƒ«ã¨ã¯ã€å¿…ãšç¿»è¨³ã‚’用æ„ã—ãªã‘ã‚Œã°ãªã‚‰ãªã„主è¦ãƒ­ã‚±ãƒ¼ãƒ«ã§ã™ã€‚アドオ"
+"ンã®èª¬æ˜ŽãŒãƒ¦ãƒ¼ã‚¶ãŒé¸æŠžã—ãŸè¨€èªžã«ç¿»è¨³ã•ã‚Œã¦ã„ãªã„å ´åˆã‚‚ã€ã“ã®æ—¢å®šã®ãƒ­ã‚±ãƒ¼ãƒ«ã§"
+"表示ã•ã‚Œã¾ã™ã€‚"
+
+#: views/developers/addon_edit_properties.thtml:167
+msgid "devcp_edit_properties_flags"
+msgstr "ã“れらã®ãƒ•ãƒ©ã‚°ã¯ã€ã‚¢ãƒ‰ã‚ªãƒ³ã®æ¤œç´¢ã‚„分類ã«ä½¿ç”¨ã•ã‚Œã¾ã™ã€‚"
+
+#: views/developers/addon_edit_properties.thtml:174
+msgid "devcp_edit_properties_guid"
+msgstr ""
+"アドオン㮠GUID ã¯ã€install.rdf 内ã§æŒ‡å®šã—ã€ã“ã®ã‚¢ãƒ‰ã‚ªãƒ³ã‚’一æ„ã«è­˜åˆ¥ã™ã‚‹ã‚‚ã®"
+"ã§ã™ã€‚一度アドオンを Mozilla Add-ons ã«ç™»éŒ²ã—ãŸã‚‰ã€GUID を変更ã™ã‚‹ã“ã¨ã¯ã§ã"
+"ã¾ã›ã‚“。"
+
+#: views/developers/addon_edit_properties.thtml:53
+msgid "devcp_edit_properties_header"
+msgstr "アドオンã®ãƒ—ロパティを編集"
+
+#: views/developers/addon_edit_properties.thtml:186
+msgid "devcp_edit_properties_header_addon_type"
+msgstr "アドオンã®ç¨®é¡ž"
+
+#: views/developers/addon_edit_properties.thtml:181
+msgid "devcp_edit_properties_header_admin_settings"
+msgstr "管ç†è€…設定"
+
+#: views/developers/addon_edit_properties.thtml:84
+msgid "devcp_edit_properties_header_default_locale"
+msgstr "既定ã®ãƒ­ã‚±ãƒ¼ãƒ«"
+
+#: views/developers/addon_edit_properties.thtml:166
+msgid "devcp_edit_properties_header_flags"
+msgstr "アドオンã®ãƒ•ãƒ©ã‚°"
+
+#: views/developers/addon_edit_properties.thtml:173
+#: views/developers/addon_edit_properties.thtml:197
+msgid "devcp_edit_properties_header_guid"
+msgstr "アドオン㮠GUID"
+
+#: views/developers/addon_edit_properties.thtml:104
+msgid "devcp_edit_properties_header_icon"
+msgstr "アドオンã®ã‚¢ã‚¤ã‚³ãƒ³"
+
+#: views/developers/addon_edit_properties.thtml:159
+msgid "devcp_edit_properties_header_other_settings"
+msgstr "ãã®ä»–ã®è¨­å®š"
+
+#. A header on the admin page to toggle trusted status.
+#: views/developers/addon_edit_properties.thtml:182
+msgid "devcp_edit_properties_header_trusted"
+msgstr "ä¿¡é ¼ã•ã‚Œã¦ã„るアドオン"
+
+#: views/developers/addon_edit_properties.thtml:160
+msgid "devcp_edit_properties_header_view_source"
+msgstr "ソースをオンラインã§è¡¨ç¤º"
+
+#. %s is a comma-separated list of image extensions ".png, .jpg"
+#: views/developers/addon_edit_properties.thtml:106
+msgid "devcp_edit_properties_icon"
+msgstr ""
+"アイコンã¯ã€æ¤œç´¢çµæžœã€å…¬é–‹ãƒšãƒ¼ã‚¸ã€ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ãƒ€ã‚¤ã‚¢ãƒ­ã‚°ä¸Šã§ã€ã“ã®ã‚¢ãƒ‰ã‚ªãƒ³ã®"
+"タイトルã¨ã¨ã‚‚ã«è¡¨ç¤ºã•ã‚Œã‚‹ã€å°ã•ãªç”»åƒã§ã™ã€‚ç”»åƒã¯ 32 x 32 ピクセルã¸è‡ªå‹•çš„ã«"
+"サイズ調整ã•ã‚Œã¾ã™ã€‚ç”»åƒã®ç¨®é¡žã¯ %s ã®ã„ãšã‚Œã‹ã‚’使用ã—ã¦ãã ã•ã„。"
+
+#: views/developers/addon_edit_properties.thtml:171
+msgid "devcp_edit_properties_label_binary"
+msgstr "ã“ã®ã‚¢ãƒ‰ã‚ªãƒ³ã«ã¯ãƒã‚¤ãƒŠãƒªã‚³ãƒ³ãƒãƒ¼ãƒãƒ³ãƒˆãŒå«ã¾ã‚Œã¦ã„ã¾ã™"
+
+#: views/developers/addon_edit_properties.thtml:185
+msgid "devcp_edit_properties_label_not_trusted"
+msgstr "ä¿¡é ¼ã•ã‚Œã¦ã„ã¾ã›ã‚“"
+
+#: views/developers/addon_edit_properties.thtml:184
+msgid "devcp_edit_properties_label_trusted"
+msgstr "ä¿¡é ¼ã•ã‚Œã¦ã„ã¾ã™"
+
+#: views/developers/addon_edit_properties.thtml:110
+msgid "devcp_edit_properties_new_icon"
+msgstr "æ–°ã—ã„アイコン"
+
+#: views/developers/addon_edit_properties.thtml:118
+msgid "devcp_edit_properties_remove_icon"
+msgstr "アイコンを削除"
+
+#: views/developers/addon_edit_properties.thtml:136
+msgid "devcp_edit_properties_transbox_homepage_description"
+msgstr ""
+"ã“ã®ã‚¢ãƒ‰ã‚ªãƒ³ã®ãƒ›ãƒ¼ãƒ ãƒšãƒ¼ã‚¸ã‚’別ã«æŒã£ã¦ã„ã‚‹å ´åˆã¯ã€URL を入力ã—ã¦ãã ã•ã„。ã"
+"ã®ã‚µã‚¤ãƒˆãŒä»–ã®è¨€èªžã«ãƒ­ãƒ¼ã‚«ãƒ©ã‚¤ã‚ºã•ã‚Œã¦ã„ãªã„ã®ã§ã‚ã‚Œã°ã€ä»–ã®ç¿»è¨³ã‚’追加ã™ã‚‹å¿…"
+"è¦ã¯ã‚ã‚Šã¾ã›ã‚“。"
+
+#: views/developers/addon_edit_properties.thtml:135
+msgid "devcp_edit_properties_transbox_homepage_name"
+msgstr "アドオンã®ãƒ›ãƒ¼ãƒ ãƒšãƒ¼ã‚¸"
+
+#: views/developers/addon_edit_properties.thtml:79
+msgid "devcp_edit_properties_transbox_name_description"
+msgstr "アドオンãŒæŽ²è¼‰ã•ã‚Œã‚‹ã‚らゆる場所ã«è¡¨ç¤ºã•ã‚Œã‚‹ã€ã‚¢ãƒ‰ã‚ªãƒ³ã®åå‰ã§ã™ã€‚"
+
+#: views/developers/addon_edit_properties.thtml:78
+msgid "devcp_edit_properties_transbox_name_name"
+msgstr "アドオンã®ã‚¿ã‚¤ãƒˆãƒ«"
+
+#: views/developers/addon_edit_properties.thtml:145
+msgid "devcp_edit_properties_transbox_supportemail_description"
+msgstr ""
+"サãƒãƒ¼ãƒˆã«é–¢ã™ã‚‹å•ã„åˆã‚ã›ã‚’å—ã‘付ã‘るメールアドレスをæŒã£ã¦ã„ã‚‹å ´åˆã¯ã€ãã®"
+"アドレスを入力ã—ã¦ãã ã•ã„。他ã®è¨€èªžã«å¯¾å¿œã™ã‚‹ã‚¢ãƒ‰ãƒ¬ã‚¹ã‚’æŒã£ã¦ã„ãªã„ã®ã§ã‚ã‚Œ"
+"ã°ã€ä»–ã®ç¿»è¨³ã‚’追加ã™ã‚‹å¿…è¦ã¯ã‚ã‚Šã¾ã›ã‚“。"
+
+#: views/developers/addon_edit_properties.thtml:144
+msgid "devcp_edit_properties_transbox_supportemail_name"
+msgstr "サãƒãƒ¼ãƒˆç”¨ãƒ¡ãƒ¼ãƒ«ã‚¢ãƒ‰ãƒ¬ã‚¹"
+
+#: views/developers/addon_edit_properties.thtml:154
+msgid "devcp_edit_properties_transbox_supporturl_description"
+msgstr ""
+"サãƒãƒ¼ãƒˆã‚’æä¾›ã™ã‚‹ Web サイトやフォーラムをæŒã£ã¦ã„ã‚‹å ´åˆã¯ã€ãã® URL を入力"
+"ã—ã¦ãã ã•ã„。ãã®ã‚µã‚¤ãƒˆãŒä»–ã®è¨€èªžã«ãƒ­ãƒ¼ã‚«ãƒ©ã‚¤ã‚ºã•ã‚Œã¦ã„ãªã„ã®ã§ã‚ã‚Œã°ã€ä»–ã®"
+"翻訳を追加ã™ã‚‹å¿…è¦ã¯ã‚ã‚Šã¾ã›ã‚“。"
+
+#: views/developers/addon_edit_properties.thtml:153
+msgid "devcp_edit_properties_transbox_supporturl_name"
+msgstr "サãƒãƒ¼ãƒˆç”¨ Web サイト"
+
+#: views/developers/addon_edit_properties.thtml:183
+msgid "devcp_edit_properties_trusted"
+msgstr ""
+"ä¿¡é ¼ã•ã‚Œã¦ã„るアドオンã¯ã€ã‚¨ãƒ‡ã‚£ã‚¿ã®ãƒ¬ãƒ“ューをå—ã‘ã‚‹ã“ã¨ãªã公開ã•ã‚Œã¾ã™ã€‚"
+
+#. %s is href="..." and should stay in the <a> tag.
+#: views/developers/addon_edit_properties.thtml:119
+msgid "devcp_edit_properties_undelete"
+msgstr "アイコンã¯ä¿å­˜æ™‚ã«å‰Šé™¤ã•ã‚Œã¾ã™ã€‚<a %s>キャンセル</a>"
+
+#: views/developers/addon_edit_properties.thtml:161
+msgid "devcp_edit_properties_view_source"
+msgstr ""
+"ã‚ãªãŸãŒè¨±å¯ã™ã‚Œã°ã€ã‚¢ãƒ‰ã‚ªãƒ³ã«å«ã¾ã‚Œã¦ã„るファイルã®ã‚½ãƒ¼ã‚¹ã‚³ãƒ¼ãƒ‰ã‚’ã€ãƒ­ã‚°ã‚¤ãƒ³"
+"ã—ã¦ã„ã‚‹ã™ã¹ã¦ã®ãƒ¦ãƒ¼ã‚¶ãŒè¡¨ç¤ºã§ãã¾ã™ã€‚"
+
+#: views/developers/addon_edit_properties.thtml:162
+msgid "devcp_edit_properties_view_source_allow"
+msgstr "オンラインã§ã®ã‚½ãƒ¼ã‚¹ã®è¡¨ç¤ºã‚’許å¯ã™ã‚‹"
+
+#: views/developers/addon_edit_properties.thtml:163
+msgid "devcp_edit_properties_view_source_do_not_allow"
+msgstr "オンラインã§ã®ã‚½ãƒ¼ã‚¹ã®è¡¨ç¤ºã‚’許å¯ã—ãªã„"
+
+#: views/elements/developers/editbox.thtml:46
+msgid "devcp_editbox_authors"
+msgstr "作者"
+
+#: views/elements/developers/editbox.thtml:47
+msgid "devcp_editbox_categories"
+msgstr "カテゴリ"
+
+#: views/elements/developers/editbox.thtml:52
+msgid "devcp_editbox_change_status"
+msgstr "ステータスを変更"
+
+#: views/elements/developers/editbox.thtml:48
+msgid "devcp_editbox_descriptions"
+msgstr "説明"
+
+#: views/elements/developers/editbox.thtml:43
+msgid "devcp_editbox_edit_addon"
+msgstr "アドオンを編集"
+
+#: views/elements/developers/editbox.thtml:57
+msgid "devcp_editbox_new_version"
+msgstr "æ–°ã—ã„ãƒãƒ¼ã‚¸ãƒ§ãƒ³"
+
+#: views/elements/developers/editbox.thtml:49
+msgid "devcp_editbox_properties"
+msgstr "プロパティ"
+
+#: views/elements/developers/editbox.thtml:60
+msgid "devcp_editbox_screenshots"
+msgstr "プレビュー用スクリーンショット"
+
+#: views/elements/developers/editbox.thtml:53
+msgid "devcp_editbox_statistics_dashboard"
+msgstr "統計ダッシュボード"
+
+#: views/elements/developers/editbox.thtml:54
+msgid "devcp_editbox_versions"
+msgstr "ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã¨ãƒ•ã‚¡ã‚¤ãƒ«"
+
+#: views/elements/developers/editbox.thtml:42
+msgid "devcp_editbox_view_listing"
+msgstr "公開ページを表示"
+
+#: views/elements/developers/editorsmenu.thtml:59
+msgid "devcp_editorsqueue_featured"
+msgstr "注目ã®ã‚¢ãƒ‰ã‚ªãƒ³"
+
+#. %1 is the review count
+#: views/elements/developers/editorsqueue.thtml:42
+#: views/elements/developers/editorsmenu.thtml:56
+#, php-format
+msgid "devcp_editorsqueue_moderatedreviews"
+msgid_plural "devcp_editorsqueue_moderatedreviews"
+msgstr[0] "処ç†ã•ã‚ŒãŸãƒ¬ãƒ“ュー (%s)"
+msgstr[1] "処ç†ã•ã‚ŒãŸãƒ¬ãƒ“ュー (%s)"
+
+#. %1 is the nominated addons count
+#: views/elements/developers/editorsqueue.thtml:44
+#: views/elements/developers/editorsmenu.thtml:58
+#, php-format
+msgid "devcp_editorsqueue_nominated"
+msgid_plural "devcp_editorsqueue_nominated"
+msgstr[0] "公開申請ã•ã‚Œã¦ã„るアドオン (%s)"
+msgstr[1] "公開申請ã•ã‚Œã¦ã„るアドオン (%s)"
+
+#. %1 is the update count
+#: views/elements/developers/editorsqueue.thtml:43
+#: views/elements/developers/editorsmenu.thtml:57
+#, php-format
+msgid "devcp_editorsqueue_pendingupdates"
+msgid_plural "devcp_editorsqueue_pendingupdates"
+msgstr[0] "ä¿ç•™ã•ã‚Œã¦ã„ã‚‹æ›´æ–° (%s)"
+msgstr[1] "ä¿ç•™ã•ã‚Œã¦ã„ã‚‹æ›´æ–° (%s)"
+
+#: controllers/statistics_controller.php:147
+#: controllers/statistics_controller.php:361
+#: controllers/previews_controller.php:108
+#: controllers/previews_controller.php:211
+#: controllers/previews_controller.php:312
+msgid "devcp_error_addon_access_denied"
+msgstr "ã“ã®ã‚¢ãƒ‰ã‚ªãƒ³ã¸ã‚¢ã‚¯ã‚»ã‚¹ã™ã‚‹æ¨©é™ãŒã‚ã‚Šã¾ã›ã‚“。"
+
+#. %s is a complete URL with the text from devcp_error_appversion_reference_link_text
+#. in the <a> tag. This should be fixed.
+#: controllers/components/developers.php:591
+#, php-format
+msgid "devcp_error_appversion_reference_link"
+msgstr "%s ã‚’å‚考ã«ã—ã¦ãã ã•ã„。"
+
+#. This is the link text in the <a> for devcp_error_appversion_reference_link. This
+#. should be fixed.
+#: controllers/components/developers.php:591
+msgid "devcp_error_appversion_reference_link_text"
+msgstr "ã“ã¡ã‚‰ã®ãƒšãƒ¼ã‚¸"
+
+#: views/developers/addon_edit_authors.thtml:76
+msgid "devcp_error_empty_authors"
+msgstr "アドオンã«ã¯ã€å°‘ãªãã¨ã‚‚ã²ã¨ã‚Šã¯ã‚ªãƒ¼ãƒŠãƒ¼ã‚’設定ã™ã‚‹å¿…è¦ãŒã‚ã‚Šã¾ã™ã€‚"
+
+#. %1$s is the name of the file
+#: controllers/components/developers.php:658
+msgid "devcp_error_file_exists"
+msgstr ""
+"ã“ã®ã‚¢ãƒ‰ã‚ªãƒ³ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã¯æ—¢ã«å­˜åœ¨ã—ã¾ã™ã€‚ç½®ãæ›ãˆã‚‹ã«ã¯ã€ã¾ãšãƒ•ã‚¡ã‚¤ãƒ« %1$s "
+"を削除ã™ã‚‹å¿…è¦ãŒã‚ã‚Šã¾ã™ã€‚"
+
+#. %1$s is a file extension. Example: .exe
+#. %2$s is a comma separated list of extensions. Example: .xpi, .jar
+#: controllers/components/developers.php:355
+#, php-format
+msgid "devcp_error_file_extension"
+msgstr ""
+"ã“ã®ãƒ•ã‚¡ã‚¤ãƒ«æ‹¡å¼µå­ (%s) ã¯é¸æŠžã•ã‚ŒãŸç¨®é¡žã®ã‚¢ãƒ‰ã‚ªãƒ³ã«ã¯ä½¿ç”¨ã§ãã¾ã›ã‚“。以下ã®"
+"ã„ãšã‚Œã‹ã‚’使用ã—ã¦ãã ã•ã„: %s"
+
+#: controllers/components/developers.php:64
+msgid "devcp_error_five_categories"
+msgstr "é¸æŠžã§ãるカテゴリ㯠5 ã¤ã¾ã§ã§ã™ã€‚"
+
+#: controllers/components/developers.php:526
+msgid "devcp_error_guid_application"
+msgstr "ã“ã®ã‚¢ãƒ‰ã‚ªãƒ³ã® ID ã¯æ—¢ã«ã‚¢ãƒ—リケーションã«ã‚ˆã£ã¦ä½¿ç”¨ã•ã‚Œã¦ã„ã¾ã™ã€‚"
+
+#: controllers/components/developers.php:337
+#: controllers/components/developers.php:389
+msgid "devcp_error_http_incomplete"
+msgstr "アップロードãŒå®Œäº†ã—ã¾ã›ã‚“ã§ã—ãŸ"
+
+#: controllers/components/developers.php:335
+#: controllers/components/developers.php:336
+#: controllers/components/developers.php:387
+#: controllers/components/developers.php:388
+msgid "devcp_error_http_maxupload"
+msgstr "最大アップロードサイズを超ãˆã¦ã„ã¾ã™"
+
+#: controllers/components/developers.php:338
+#: controllers/components/developers.php:390
+msgid "devcp_error_http_nofile"
+msgstr "アップロードã•ã‚ŒãŸãƒ•ã‚¡ã‚¤ãƒ«ã¯ã‚ã‚Šã¾ã›ã‚“"
+
+#. %1$s is a file extension. Example: .exe
+#. %2$s is a comma separated list of extensions. Example: .xpi, .jar
+#: controllers/components/developers.php:401
+#, php-format
+msgid "devcp_error_icon_extension"
+msgstr ""
+"ã“ã®ãƒ•ã‚¡ã‚¤ãƒ«æ‹¡å¼µå­ (%s) ã¯ã‚¢ã‚¤ã‚³ãƒ³ã«ã¯ä½¿ç”¨ã§ãã¾ã›ã‚“。以下ã®ã„ãšã‚Œã‹ã‚’使用ã—"
+"ã¦ãã ã•ã„: %s"
+
+#: controllers/developers_controller.php:504
+msgid "devcp_error_index_rdf_notfound"
+msgstr "install.rdf ファイルãŒå«ã¾ã‚Œã¦ã„ã¾ã›ã‚“。"
+
+#: controllers/components/developers.php:601
+msgid "devcp_error_install_manifest"
+msgstr "install.rdf ファイルã«ä»¥ä¸‹ã®ã‚¨ãƒ©ãƒ¼ãŒã‚ã‚Šã¾ã™:"
+
+#: controllers/developers_controller.php:1463
+msgid "devcp_error_invalid_addontype"
+msgstr ""
+
+#. %$1s is a version. Example: 3.1.1
+#. %$2s is an add-on name.
+#: controllers/components/developers.php:569
+#: controllers/components/developers.php:581
+#, php-format
+msgid "devcp_error_invalid_appversion"
+msgstr "%s 㯠%s ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã«ã¯ä½¿ç”¨ã§ãã¾ã›ã‚“"
+
+#. %s is a string
+#: controllers/components/developers.php:521
+#, php-format
+msgid "devcp_error_invalid_guid"
+msgstr "ã“ã®ã‚¢ãƒ‰ã‚ªãƒ³ã® ID ã¯ä¸æ­£ãªå½¢å¼ã§ã™: %s"
+
+#. %$1s is a version. Example: 3.1.1
+#. %$2s is an add-on name.
+#: controllers/components/developers.php:572
+#, php-format
+msgid "devcp_error_invalid_minversion"
+msgstr ""
+"%s 㯠%s ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã«ã¯ä½¿ç”¨ã§ãã¾ã›ã‚“: 最å°ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã« * ã‚’å«ã‚ã‚‹ã“ã‚‹ã“ã¨"
+"ã¯ã§ãã¾ã›ã‚“。"
+
+#: controllers/components/developers.php:536
+msgid "devcp_error_invalid_version"
+msgstr ""
+"ã“ã®ã‚¢ãƒ‰ã‚ªãƒ³ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã¯ä¸æ­£ãªå½¢å¼ã§ã™: <a href=\"https://developer."
+"mozilla.org/ja/Toolkit_version_format\">仕様</a> ã‚’ã”確èªãã ã•ã„。"
+
+#: controllers/components/developers.php:531
+msgid "devcp_error_invalid_version_spaces"
+msgstr ""
+"ã“ã®ã‚¢ãƒ‰ã‚ªãƒ³ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã¯ä¸æ­£ãªå½¢å¼ã§ã™: ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã«ã‚¹ãƒšãƒ¼ã‚¹ã‚’å«ã‚ã‚‹ã“ã¨ã¯"
+"ã§ãã¾ã›ã‚“。"
+
+#. %s is an error message from the parser.
+#: controllers/components/developers.php:501
+#, php-format
+msgid "devcp_error_manifest_parse"
+msgstr "install.rdf ã®ãƒ‘ース中ã«ä»¥ä¸‹ã®ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ: %s"
+
+#: controllers/components/developers.php:373
+msgid "devcp_error_move_file"
+msgstr "ファイルを移動ã§ãã¾ã›ã‚“"
+
+#. %s is the name of a file
+#: controllers/components/developers.php:650
+#: controllers/components/developers.php:662
+#: controllers/components/developers.php:667
+#: controllers/components/developers.php:727
+#: controllers/components/developers.php:738
+#: controllers/components/developers.php:743
+#, php-format
+msgid "devcp_error_moving_file"
+msgstr "%s を移動ã™ã‚‹éš›ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚"
+
+#: controllers/components/developers.php:595
+msgid "devcp_error_mozilla_application"
+msgstr ""
+"å°‘ãªãã¨ã‚‚ã²ã¨ã¤ã¯æ­£ã—ã„ Mozilla ã®å¯¾è±¡ã‚¢ãƒ—リケーションを設定ã™ã‚‹å¿…è¦ãŒã‚ã‚Šã¾"
+"ã™ã€‚"
+
+#: controllers/components/developers.php:516
+msgid "devcp_error_no_guid"
+msgstr "ã“ã®ã‚¢ãƒ‰ã‚ªãƒ³ã® ID ㌠install.rdf ファイルã§æŒ‡å®šã•ã‚Œã¦ã„ã¾ã›ã‚“。"
+
+#: controllers/components/developers.php:287
+msgid "devcp_error_no_platform"
+msgstr "プラットフォームãŒé¸æŠžã•ã‚Œã¦ã„ã¾ã›ã‚“"
+
+#: controllers/components/developers.php:59
+msgid "devcp_error_one_category"
+msgstr "å°‘ãªãã¨ã‚‚ã²ã¨ã¤ã¯ã‚«ãƒ†ã‚´ãƒªã‚’é¸æŠžã—ã¦ãã ã•ã„。"
+
+#: controllers/components/developers.php:92
+msgid "devcp_error_one_user"
+msgstr "å°‘ãªãã¨ã‚‚ã²ã¨ã‚Šã¯ä½œè€…を指定ã™ã‚‹å¿…è¦ãŒã‚ã‚Šã¾ã™ã€‚"
+
+#. %1$s is a file extension. Example: .exe
+#. %2$s is a comma separated list of extensions. Example: .xpi, .jar
+#: controllers/components/developers.php:1081
+#, php-format
+msgid "devcp_error_preview_extension"
+msgstr ""
+"ã“ã®ãƒ•ã‚¡ã‚¤ãƒ«æ‹¡å¼µå­ (%s) ã¯ãƒ—レビュー画åƒã«ã¯ä½¿ç”¨ã§ãã¾ã›ã‚“。以下ã®ã„ãšã‚Œã‹ã‚’"
+"使用ã—ã¦ãã ã•ã„: %s"
+
+#: controllers/components/developers.php:511
+msgid "devcp_error_updatekey"
+msgstr ""
+"アドオン㫠updateKey を指定ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“。install.rdf ファイルã‹ã‚‰ "
+"updateKey を削除ã—ãŸä¸Šã§ã€å†åº¦ã‚¢ãƒƒãƒ—ロードã—ã¦ãã ã•ã„。"
+
+#: controllers/components/developers.php:506
+msgid "devcp_error_updateurl"
+msgstr ""
+"addons.mozilla.org 以外㮠updateURL を指定ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“。install.rdf"
+"ファイルã‹ã‚‰ updateURL を削除ã—ãŸä¸Šã§ã€å†åº¦ã‚¢ãƒƒãƒ—ロードã—ã¦ãã ã•ã„。"
+
+#: controllers/developers_controller.php:465
+#: controllers/components/developers.php:271
+msgid "devcp_error_upload_file"
+msgstr "ファイルをアップロードã—ã¦ãã ã•ã„。"
+
+#: views/developers/uploader.thtml:135
+msgid "devcp_input_upload_file"
+msgstr "ファイルをアップロード"
+
+#: views/pages/js_constants.js.thtml:89
+msgid "devcp_js_a_cancel"
+msgstr "キャンセル"
+
+#: views/pages/js_constants.js.thtml:90
+msgid "devcp_js_add_email"
+msgstr "追加ã—ãŸã„作者ã®ç™»éŒ²ãƒ¡ãƒ¼ãƒ«ã‚¢ãƒ‰ãƒ¬ã‚¹ã‚’入力ã—ã¦ãã ã•ã„。"
+
+#. alt text for a down-arrow image.
+#: views/pages/js_constants.js.thtml:81
+msgid "devcp_js_img_move_down"
+msgstr "下ã¸ç§»å‹•"
+
+#. alt text for an up-arrow image.
+#: views/pages/js_constants.js.thtml:82
+msgid "devcp_js_img_move_up"
+msgstr "上ã¸ç§»å‹•"
+
+#: views/pages/js_constants.js.thtml:91
+msgid "devcp_js_img_remove_compat"
+msgstr "アプリケーション互æ›æ€§ã‚’削除"
+
+#: views/pages/js_constants.js.thtml:86
+msgid "devcp_js_input_list_author"
+msgstr "公開ページã«ä½œè€…ã¨ã—ã¦è¨˜è¼‰ã™ã‚‹"
+
+#: views/pages/js_constants.js.thtml:92
+msgid "devcp_js_license_select"
+msgstr "ライセンスをé¸æŠžã—ã¦ãã ã•ã„。"
+
+#: views/pages/js_constants.js.thtml:93
+msgid "devcp_js_license_text"
+msgstr "ライセンスを入力ã—ã¦ãã ã•ã„。"
+
+#. <option> text in a <select> for Author role in an add-on.
+#: views/pages/js_constants.js.thtml:84
+msgid "devcp_js_option_developer"
+msgstr "開発者"
+
+#. <option> text in a <select> for Author role in an add-on.
+#: views/pages/js_constants.js.thtml:83
+msgid "devcp_js_option_owner"
+msgstr "オーナー"
+
+#. <option> text in a <select> for Author role in an add-on.
+#: views/pages/js_constants.js.thtml:85
+msgid "devcp_js_option_viewer"
+msgstr "閲覧者"
+
+#: views/pages/js_constants.js.thtml:88
+msgid "devcp_js_remove_author"
+msgstr "作者を削除"
+
+#: views/pages/js_constants.js.thtml:87
+msgid "devcp_js_sure_remove"
+msgstr "ã“ã®ä½œè€…を削除ã—ã¦ã‚‚よã‚ã—ã„ã§ã™ã‹ï¼Ÿ"
+
+#: views/pages/js_constants.js.thtml:77
+msgid "devcp_js_upload_alert"
+msgstr "アップロードã™ã‚‹ãƒ•ã‚¡ã‚¤ãƒ«ã‚’é¸æŠžã—ã¦ãã ã•ã„。"
+
+#. %1$s is an addon id, like 32.
+#. %2$s is a version number, like 3.5.
+#: controllers/components/developers.php:1212
+msgid "devcp_license_existing"
+msgstr "アドオン %1$s ãƒãƒ¼ã‚¸ãƒ§ãƒ³ %2$s ã®ç‹¬è‡ªãƒ©ã‚¤ã‚»ãƒ³ã‚¹"
+
+#: views/elements/developers/localebox.thtml:44
+msgid "devcp_localebox_header_localizedfields"
+msgstr "ローカライズå¯èƒ½ãªé …ç›®"
+
+#. %1 is the default locale
+#: views/elements/developers/localebox.thtml:48
+#, php-format
+msgid "devcp_localebox_intro"
+msgstr ""
+"ã“ã®ãƒšãƒ¼ã‚¸ã®ä¸€éƒ¨ã®é …ç›®ã¯ã€ã‚¨ãƒ³ãƒ‰ãƒ¦ãƒ¼ã‚¶ã®ä½¿ç”¨è¨€èªžã«ã‚ã‚ã›ã¦è¡¨ç¤ºã§ãるよã†ã€"
+"ローカライズå¯èƒ½ã«ãªã£ã¦ã„ã¾ã™ã€‚ロケールをé¸æŠžã—ã€ãã®è¨€èªžã§ã‚¢ãƒ‰ã‚ªãƒ³ã®è©³ç´°ã‚’"
+"入力ã—ã¦ãã ã•ã„。ユーザã®è¨€èªžã«åˆã£ãŸç¿»è¨³ãŒå­˜åœ¨ã—ãªã„å ´åˆã¯ã€é¸æŠžã•ã‚Œã¦ã„ã‚‹"
+"既定ã®ãƒ­ã‚±ãƒ¼ãƒ« (%s) ã§è¡¨ç¤ºã•ã‚Œã¾ã™ã€‚"
+
+#: views/elements/developers/sidebar.thtml:68
+#: views/elements/developers/myaddons.thtml:75
+msgid "devcp_myaddons_admincp_link"
+msgstr "管ç†è€…用コントロールパãƒãƒ«"
+
+#: views/elements/developers/sidebar.thtml:65
+#: views/elements/developers/myaddons.thtml:72
+msgid "devcp_myaddons_editorcp_link"
+msgstr "エディタ用コントロールパãƒãƒ«"
+
+#: views/elements/developers/myaddons.thtml:52
+msgid "devcp_myaddons_link"
+msgstr "自分ã®ã‚¢ãƒ‰ã‚ªãƒ³"
+
+#: views/elements/developers/sidebar.thtml:70
+#: views/elements/developers/myaddons.thtml:77
+msgid "devcp_myaddons_mainpage_link"
+msgstr "メインページã¸æˆ»ã‚‹"
+
+#: views/elements/developers/sidebar.thtml:63
+#: views/elements/developers/myaddons.thtml:70
+msgid "devcp_myaddons_statistics_link"
+msgstr "統計ダッシュボード"
+
+#: views/elements/developers/sidebar.thtml:62
+#: views/elements/developers/myaddons.thtml:69
+msgid "devcp_myaddons_submitaddon_link"
+msgstr "アドオンを登録"
+
+#: views/elements/developers/sidebar.thtml:48
+#: views/elements/developers/myaddons.thtml:67
+msgid "devcp_myaddons_title"
+msgstr "開発者用ツール"
+
+#. %1$s is an add-on ID, perhaps 167.
+#. %2$s is a URL.
+#: controllers/developers_controller.php:256
+msgid "devcp_new_addon_error"
+msgstr ""
+"ã“ã®ã‚¢ãƒ‰ã‚ªãƒ³ã® ID (%1$s) ã¯æ—¢ã«ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ä¸Šã«å­˜åœ¨ã—ã¾ã™ã€‚ã“ã‚ŒãŒã‚ãªãŸã®ã‚¢ãƒ‰"
+"オンã§ã‚ã‚‹å ´åˆã¯ã€<a href=\"%2$s\">æ–°ã—ã„ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã‚’アップロード</a> ã§ãã¾"
+"ã™ã€‚"
+
+#: views/developers/addon_status_nominate.thtml:62
+msgid "devcp_nominate_cancel"
+msgstr "キャンセルã—ã¦æˆ»ã‚‹"
+
+#. %1 is the add-on name
+#: views/developers/addon_status_nominate.thtml:61
+#, php-format
+msgid "devcp_nominate_submit_nominate"
+msgstr "%s ã®å…¬é–‹ã‚’申請"
+
+#: views/developers/addon_edit_properties.thtml:50
+#: views/developers/addon_status.thtml:49
+#: views/developers/versions_edit.thtml:50
+msgid "devcp_notice_changes_error"
+msgstr ""
+"<span>ã²ã¨ã¤ã‚ã‚‹ã„ã¯è¤‡æ•°ã®å¤‰æ›´ã‚’ä¿å­˜ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚</span><br />以下ã®ã‚¨"
+"ラーをå‚ç…§ã—ã¦ãã ã•ã„。ãã®ä»–ã®å¤‰æ›´ã¯æ­£ã—ãä¿å­˜ã•ã‚Œã¾ã—ãŸã€‚"
+
+#: views/developers/addon_edit_authors.thtml:47
+#: views/developers/addon_edit_properties.thtml:47
+#: views/developers/addon_status.thtml:46
+#: views/developers/addon_edit_descriptions.thtml:47
+#: views/developers/versions_edit.thtml:47
+#: views/developers/addon_edit_categories.thtml:46
+msgid "devcp_notice_changes_saved"
+msgstr ""
+"<span>変更ã®ä¿å­˜ãŒå®Œäº†ã—ã¾ã—ãŸã€‚</span><br />一部ã®å¤‰æ›´ã¯ã€Mozilla Add-ons ã®"
+"ã™ã¹ã¦ã®ãƒšãƒ¼ã‚¸ã«å映ã•ã‚Œã‚‹ã¾ã§æ•°æ™‚é–“ã‹ã‹ã‚‹ã“ã¨ã‚‚ã‚ã‚Šã¾ã™ã€‚"
+
+#: controllers/previews_controller.php:252
+msgid "devcp_notice_cleardefault"
+msgstr ""
+"ã“ã®ç”»åƒã‚’既定ã®ãƒ—レビュー画åƒã«è¨­å®šã—ãŸã¾ã¾å‰Šé™¤ã™ã‚‹ã¨ã€ä»–ã®ãƒ—レビュー画åƒãŒ"
+"自動的ã«æ—¢å®šã®ãƒ—レビュー画åƒã«ãªã‚Šã¾ã™ã€‚"
+
+#: controllers/previews_controller.php:184
+#: controllers/previews_controller.php:251
+msgid "devcp_notice_makedefault"
+msgstr ""
+"ã“ã®ç”»åƒã‚’既定ã®ãƒ—レビュー画åƒã«ã™ã‚‹ã¨ã€ç¾åœ¨ã®æ—¢å®šã®ãƒ—レビュー画åƒã¯æ—¢å®šã§ã¯"
+"ãªããªã‚Šã¾ã™ã€‚"
+
+#: views/developers/addon_edit_authors.thtml:70
+msgid "devcp_notice_unsaved_changes"
+msgstr "ä¿å­˜ã•ã‚Œã¦ã„ãªã„変更ãŒã‚ã‚Šã¾ã™ã€‚"
+
+#: controllers/developers_controller.php:87
+#: controllers/developers_controller.php:97
+#: controllers/developers_controller.php:100
+#: controllers/previews_controller.php:67
+#: controllers/previews_controller.php:79
+#: controllers/previews_controller.php:82
+msgid "devcp_pagetitle"
+msgstr "開発者用コントロールパãƒãƒ«"
+
+#: controllers/previews_controller.php:103
+#: controllers/previews_controller.php:104
+msgid "devcp_preview_add_pagetitle"
+msgstr "プレビュー画åƒã®è¿½åŠ "
+
+#: controllers/previews_controller.php:135
+msgid "devcp_preview_added_successfully"
+msgstr "プレビュー画åƒãŒè¿½åŠ ã•ã‚Œã¾ã—ãŸã€‚"
+
+#: controllers/previews_controller.php:323
+msgid "devcp_preview_deleted_successfully"
+msgstr "プレビュー画åƒã¯å‰Šé™¤ã•ã‚Œã¾ã—ãŸã€‚"
+
+#: controllers/previews_controller.php:194
+#: controllers/previews_controller.php:195
+msgid "devcp_preview_edit_pagetitle"
+msgstr "プレビュー画åƒã®ç·¨é›†"
+
+#: controllers/previews_controller.php:237
+msgid "devcp_preview_updated_successfully"
+msgstr "プレビュー画åƒã¯æ›´æ–°ã•ã‚Œã¾ã—ãŸã€‚"
+
+#: views/developers/previews.thtml:120
+msgid "devcp_previews_a_another"
+msgstr "ä»–ã®ãƒ—レビュー画åƒã‚’追加"
+
+#: views/developers/previews.thtml:96
+msgid "devcp_previews_a_delete"
+msgstr "プレビュー画åƒã‚’削除"
+
+#: views/developers/previews.thtml:95
+msgid "devcp_previews_a_replace"
+msgstr "プレビュー画åƒã‚’ç½®ãæ›ãˆ"
+
+#: views/developers/previews.thtml:126
+msgid "devcp_previews_a_update"
+msgstr "プレビュー画åƒã‚’æ›´æ–°"
+
+#: views/developers/previews.thtml:115 views/developers/previews.thtml:124
+msgid "devcp_previews_add_new"
+msgstr "æ–°ã—ã„プレビュー画åƒã‚’追加"
+
+#. %s is a list of file extensions, e.g. ".png, .gif"
+#: views/developers/previews.thtml:116
+msgid "devcp_previews_add_select"
+msgstr ""
+"アップロードã™ã‚‹ç”»åƒã‚’é¸æŠžã—ã¦ãã ã•ã„。幅 700 ピクセルã€é«˜ã• 525 ピクセル以"
+"上ã®ç”»åƒã¯è‡ªå‹•çš„ã«ç¸®å°ã•ã‚Œã¾ã™ã€‚使用å¯èƒ½ãªå½¢å¼ã¯ %s ã§ã™ã€‚"
+
+#: views/developers/previews.thtml:121
+msgid "devcp_previews_click_below"
+msgstr ""
+"アップロードを行ã†ã«ã¯ã€ä¸‹ã®ã€Œãƒ—レビュー画åƒã‚’æ›´æ–°ã€ã‚’クリックã—ã¦ãã ã•ã„。"
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/previews.thtml:102
+msgid "devcp_previews_click_update"
+msgstr ""
+"ã“ã®ç”»åƒã‚’ä¿å­˜ã™ã‚‹ã«ã¯ã€ä¸‹ã®ã€Œãƒ—レビュー画åƒã‚’æ›´æ–°ã€ã‚’クリックã—ã¦ãã ã•ã„。"
+"(<a %s>キャンセル</a>)"
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/previews.thtml:107
+msgid "devcp_previews_error_message"
+msgstr ""
+"ã“ã®ãƒ—レビュー画åƒã¯ã€ä¸‹ã®ã€Œãƒ—レビュー画åƒã‚’æ›´æ–°ã€ã‚’クリックã™ã‚‹ã¨å‰Šé™¤ã•ã‚Œã¾"
+"ã™ã€‚(<a %s>キャンセル</a>)"
+
+#: views/previews/add.thtml:45
+msgid "devcp_previews_filetype_info"
+msgstr ""
+"アドオンã®ã‚¹ã‚¯ãƒªãƒ¼ãƒ³ã‚·ãƒ§ãƒƒãƒˆã‚’アップロードã™ã‚‹ã«ã¯ã€ä»¥ä¸‹ã®ãƒ•ã‚©ãƒ¼ãƒ ã‚’ã”利用ã"
+"ã ã•ã„。画åƒå½¢å¼ã¯ PNGã€JPEGã€GIF ã®ã¿ã«å¯¾å¿œã—ã¦ã„ã¾ã™ã€‚å¹… 700 ピクセルã€é«˜"
+"ã• 525 ピクセル以上ã®ç”»åƒã¯è‡ªå‹•çš„ã«ç¸®å°ã•ã‚Œã¾ã™ã€‚"
+
+#: views/previews/add.thtml:43
+msgid "devcp_previews_header_add"
+msgstr "プレビュー画åƒã‚’追加"
+
+#: views/developers/previews.thtml:80
+msgid "devcp_previews_header_caption"
+msgstr "プレビュー画åƒã®ã‚­ãƒ£ãƒ—ション"
+
+#: views/previews/edit.thtml:43
+msgid "devcp_previews_header_edit"
+msgstr "プレビュー画åƒã‚’編集"
+
+#: views/developers/previews.thtml:93
+msgid "devcp_previews_label_default"
+msgstr "既定ã®ãƒ—レビュー画åƒ"
+
+#: views/previews/add.thtml:54
+msgid "devcp_previews_label_file"
+msgstr "プレビュー画åƒã®ãƒ•ã‚¡ã‚¤ãƒ«"
+
+#: views/previews/add.thtml:59 views/previews/edit.thtml:50
+msgid "devcp_previews_label_makedefault"
+msgstr "ã“ã®ç”»åƒã‚’既定ã®ãƒ—レビュー画åƒã«ã™ã‚‹"
+
+#: views/developers/previews.thtml:100
+msgid "devcp_previews_label_new"
+msgstr "æ–°ã—ã„ç”»åƒ:"
+
+#: views/developers/previews.thtml:118
+msgid "devcp_previews_label_upload"
+msgstr "プレビュー画åƒã‚’アップロード: "
+
+#: views/developers/previews.thtml:50
+msgid "devcp_previews_notice_error"
+msgstr "ã²ã¨ã¤ã¾ãŸã¯ã„ãã¤ã‹ã®ãƒ—レビュー画åƒã‚’ä¿å­˜ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚"
+
+#: views/developers/previews.thtml:47
+msgid "devcp_previews_notice_success"
+msgstr "プレビュー画åƒã®ã‚¢ãƒƒãƒ—ロードãŒå®Œäº†ã—ã¾ã—ãŸã€‚"
+
+#: views/developers/previews.thtml:59
+msgid "devcp_previews_p_screenshots"
+msgstr ""
+"ã“ã®ã‚¢ãƒ‰ã‚ªãƒ³ã®ãƒ—レビュー用スクリーンショットãŒä¸‹ã«è¡¨ç¤ºã•ã‚Œã¦ã„ã¾ã™ã€‚ã“ã“ã§"
+"キャプションや画åƒã‚’変更ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚既定ã®ãƒ—レビュー画åƒã¯ã€æ¤œç´¢çµæžœ"
+"ãªã©ã«ã‚¿ã‚¤ãƒˆãƒ«ã¨ã¨ã‚‚ã«è¡¨ç¤ºã•ã‚Œã‚‹ç”»åƒã§ã™ã€‚"
+
+#: views/previews/edit.thtml:55
+msgid "devcp_previews_submit_delete"
+msgstr "プレビュー画åƒã‚’削除"
+
+#: views/previews/edit.thtml:55
+msgid "devcp_previews_submit_delete_confirm"
+msgstr "ã“ã®ãƒ—レビュー画åƒã‚’削除ã—ã¦ã‚‚よã‚ã—ã„ã§ã™ã‹ï¼Ÿ"
+
+#: views/previews/edit.thtml:54
+msgid "devcp_previews_submit_edit"
+msgstr "プレビュー画åƒã‚’編集"
+
+#: views/previews/add.thtml:63
+msgid "devcp_previews_submit_upload"
+msgstr "プレビュー画åƒã‚’アップロード"
+
+#: views/developers/previews.thtml:78
+msgid "devcp_previews_thumbnail"
+msgstr "サムãƒã‚¤ãƒ«"
+
+#. %s is the add-on name.
+#: views/developers/previews.thtml:44
+msgid "devcp_previews_title"
+msgstr "%s ã®ãƒ—レビュー画åƒãƒžãƒãƒ¼ã‚¸ãƒ£"
+
+#: views/developers/uploader.thtml:74
+msgid "devcp_review_agreement_please"
+msgstr "次ã«é€²ã‚€å‰ã«ã€ä»¥ä¸‹ã®åˆ©ç”¨è¦ç´„をよã読んã§åŒæ„ã™ã‚‹å¿…è¦ãŒã‚ã‚Šã¾ã™ã€‚"
+
+#: views/elements/developers/rolecheck.thtml:42
+msgid "devcp_rolecheck_no_privs"
+msgstr ""
+"<span>ã‚ãªãŸã«ã¯ã“ã®ãƒšãƒ¼ã‚¸ã‚’変更ã§ãる権é™ãŒã‚ã‚Šã¾ã›ã‚“。</span><br />変更を行"
+"ã„ãŸã„å ´åˆã¯ã‚¢ãƒ‰ã‚ªãƒ³ã®ã‚ªãƒ¼ãƒŠãƒ¼ã«é€£çµ¡ã‚’å–ã£ã¦ãã ã•ã„。"
+
+#: controllers/developers_controller.php:1315
+msgid "devcp_several_hours"
+msgstr ""
+"一部ã®å¤‰æ›´ã¯ã€Mozilla Add-ons ã®ã™ã¹ã¦ã®ãƒšãƒ¼ã‚¸ã«å映ã•ã‚Œã‚‹ã¾ã§æ•°æ™‚é–“ã‹ã‹ã‚‹ã“"
+"ã¨ã‚‚ã‚ã‚Šã¾ã™ã€‚"
+
+#: views/elements/developers/sidebar.thtml:52
+msgid "devcp_sidebar_a_dashboard"
+msgstr "ダッシュボード"
+
+#. %s is a number
+#: views/elements/developers/statsbar.thtml:45
+#: views/developers/dashboard.thtml:79
+#, php-format
+msgid "devcp_statsbar_adu"
+msgstr "1 æ—¥ã®ã‚¢ã‚¯ãƒ†ã‚£ãƒ–ユーザ: <em>%s</em>"
+
+#. %s is a number
+#: views/elements/developers/statsbar.thtml:41
+#: views/developers/dashboard.thtml:75
+#, php-format
+msgid "devcp_statsbar_total_downloads"
+msgstr "累計ダウンロード数: <em>%s</em>"
+
+#. %s is a number
+#: views/elements/developers/statsbar.thtml:43
+#: views/developers/dashboard.thtml:77
+#, php-format
+msgid "devcp_statsbar_weekly_downloads"
+msgstr "週間ダウンロード数: <em>%s</em>"
+
+#: views/developers/addon_status_confirm.thtml:59
+msgid "devcp_status_confirm_active"
+msgstr ""
+"アドオンを有効ã«ã™ã‚‹ã¨ã€ã‚¹ãƒ†ãƒ¼ã‚¿ã‚¹ã«å¿œã˜ã¦ã€æ¤œç´¢çµæžœãªã©ã®å…¬é–‹ãƒšãƒ¼ã‚¸ã«æŽ²è¼‰ã•"
+"ã‚Œã¾ã™ã€‚åŒæ§˜ã«ã€ã‚¹ãƒ†ãƒ¼ã‚¿ã‚¹ã«å¿œã˜ã¦ã€Web サイトã‹ã‚‰ãƒ€ã‚¦ãƒ³ãƒ­ãƒ¼ãƒ‰ãŒå¯èƒ½ã¨ãªã‚Šã€"
+"更新確èªã‚µãƒ¼ãƒ“スを通ã˜ã¦æ›´æ–°ãŒæä¾›ã•ã‚Œã¾ã™ã€‚ã“ã®ãƒšãƒ¼ã‚¸ã«æˆ»ã£ã¦ãã‚Œã°ã€ã¾ãŸã„"
+"ã¤ã§ã‚‚無効ã«ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚"
+
+#: views/developers/addon_status_confirm.thtml:59
+msgid "devcp_status_confirm_active_sure"
+msgstr "ã“ã®ã‚¢ãƒ‰ã‚ªãƒ³ã‚’有効ã«ã—ã¦ã‚‚よã‚ã—ã„ã§ã™ã‹ï¼Ÿ"
+
+#: views/developers/addon_status_confirm.thtml:50
+msgid "devcp_status_confirm_header_sure"
+msgstr "よã‚ã—ã„ã§ã™ã‹ï¼Ÿ"
+
+#: views/developers/addon_status_confirm.thtml:55
+msgid "devcp_status_confirm_inactive"
+msgstr ""
+"アドオンを無効ã«ã™ã‚‹ã¨ã€æ¤œç´¢çµæžœãªã©ã®å…¬é–‹ãƒšãƒ¼ã‚¸ã«ã¯ä¸€åˆ‡è¡¨ç¤ºã•ã‚Œãªããªã‚Šã¾"
+"ã™ã€‚ã¾ãŸã€Web サイトã‹ã‚‰ãƒ€ã‚¦ãƒ³ãƒ­ãƒ¼ãƒ‰ã§ããªããªã‚Šã€æ›´æ–°ç¢ºèªã‚µãƒ¼ãƒ“スを通ã˜ãŸæ›´"
+"æ–°ã‚‚æä¾›ã•ã‚Œãªããªã‚Šã¾ã™ã€‚ã“ã®ãƒšãƒ¼ã‚¸ã«æˆ»ã£ã¦ãã‚Œã°ã€ã¾ãŸã„ã¤ã§ã‚‚有効ã«ã™ã‚‹ã“"
+"ã¨ãŒã§ãã¾ã™ã€‚"
+
+#: views/developers/addon_status_confirm.thtml:55
+msgid "devcp_status_confirm_inactive_sure"
+msgstr "ã“ã®ã‚¢ãƒ‰ã‚ªãƒ³ã‚’無効ã«ã—ã¦ã‚‚よã‚ã—ã„ã§ã™ã‹ï¼Ÿ"
+
+#: views/developers/addon_status_confirm.thtml:74
+msgid "devcp_status_confirm_no"
+msgstr "ã„ã„ãˆã€ã‚­ãƒ£ãƒ³ã‚»ãƒ«ã—ã¾ã™"
+
+#: views/developers/addon_status_confirm.thtml:67
+msgid "devcp_status_confirm_public"
+msgstr ""
+"アドオンを公開ã™ã‚‹ã¨ã€èª°ã§ã‚‚ダウンロードå¯èƒ½ã«ãªã‚Šã€æ—¢å­˜ã®ãƒ¦ãƒ¼ã‚¶ã¸å‘ã‘ãŸæ›´æ–°"
+"ã®æä¾›ãŒé–‹å§‹ã•ã‚Œã¾ã™ã€‚"
+
+#: views/developers/addon_status_confirm.thtml:67
+msgid "devcp_status_confirm_public_sure"
+msgstr "ã“ã®ã‚¢ãƒ‰ã‚ªãƒ³ã‚’公開ã—ã¦ã‚‚よã‚ã—ã„ã§ã™ã‹ï¼Ÿ"
+
+#: views/developers/addon_status_confirm.thtml:63
+msgid "devcp_status_confirm_sandbox"
+msgstr ""
+"アドオンをサンドボックスã¸æˆ»ã™ã¨ã€ãƒ€ã‚¦ãƒ³ãƒ­ãƒ¼ãƒ‰ã®éš›ã«ãƒ¦ãƒ¼ã‚¶ã®ãƒ­ã‚°ã‚¤ãƒ³ã‚’å¿…è¦ã¨"
+"ã™ã‚‹ã‚ˆã†ã«ãªã‚Šã€æ—¢å­˜ã®ãƒ¦ãƒ¼ã‚¶ã«å¯¾ã—ã¦ã‚‚æ›´æ–°ãŒæä¾›ã•ã‚Œãªããªã‚Šã¾ã™ã€‚ã‚ãªãŸã®ã‚¢"
+"ドオンã¯ç¾åœ¨æ—¢ã«å…¬é–‹ã•ã‚Œã¦ã„ã¾ã™ã®ã§ã€ã“ã®ãƒšãƒ¼ã‚¸ã«æˆ»ã£ã¦ãã‚Œã°ã€ã¾ãŸã„ã¤ã§ã‚‚"
+"公開ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚"
+
+#: views/developers/addon_status_confirm.thtml:63
+msgid "devcp_status_confirm_sandbox_sure"
+msgstr "ã“ã®ã‚¢ãƒ‰ã‚ªãƒ³ã‚’サンドボックスã¸ç§»å‹•ã—ã¦ã‚‚よã‚ã—ã„ã§ã™ã‹ï¼Ÿ"
+
+#: views/developers/addon_status_confirm.thtml:73
+msgid "devcp_status_confirm_yes"
+msgstr "ã¯ã„ã€ãã†ã—ã¾ã™ã€‚"
+
+#: views/developers/addon_status_nominate.thtml:46
+msgid "devcp_status_nominate_error_notice"
+msgstr ""
+"<span>公開申請ã®ãŸã‚ã®ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ãŒå¿…è¦ã§ã™ã€‚</span><br />å¿…è¦ãªæƒ…報をテキスト"
+"ボックスã«å…¥åŠ›ã—ã¦ã‹ã‚‰ã€å†åº¦ç”³è«‹ã—ã¦ãã ã•ã„。"
+
+#: views/developers/addon_status_nominate.thtml:55
+msgid "devcp_status_nominate_header"
+msgstr "アドオンã®å…¬é–‹ç”³è«‹"
+
+#: views/developers/dashboard.thtml:85
+msgid "devcp_summary_lastversion"
+msgstr "最新ãƒãƒ¼ã‚¸ãƒ§ãƒ³:"
+
+#. %s is the add-on name.
+#: views/developers/addon_edit.thtml:43
+#: views/developers/addon_edit_authors.thtml:44
+#: views/developers/versions_delete.thtml:43
+#: views/developers/addon_edit_properties.thtml:44
+#: views/developers/addon_edit_descriptions.thtml:44
+#: views/developers/versions_edit.thtml:44
+#: views/developers/addon_edit_categories.thtml:43
+#: views/developers/versions.thtml:43
+msgid "devcp_title_edit_addon"
+msgstr "%s を編集"
+
+#. title attribute for a javascript link that pops up a help dialog.
+#: views/elements/translationbox.thtml:68
+msgid "devcp_transbox_a_title_help"
+msgstr "ヘルプ (ã“ã®ãƒšãƒ¼ã‚¸ã‹ã‚‰ç§»å‹•ã—ã¾ã›ã‚“)"
+
+#: views/elements/translationbox.thtml:68
+msgid "devcp_transbox_alt_help"
+msgstr "ヘルプ"
+
+#. %1$s is <span>17</span>, %2$s is 42.
+#: views/elements/translationbox.thtml:101
+msgid "devcp_transbox_chars_used"
+msgstr "入力済ã¿æ–‡å­—æ•°: %1$s / %2$s"
+
+#: views/elements/translationbox.thtml:132
+msgid "devcp_transbox_delete_sure"
+msgstr "ã“ã®ç¿»è¨³ã‚’削除ã—ã¦ã‚‚よã‚ã—ã„ã§ã™ã‹ï¼Ÿ"
+
+#. %s is a locale, like en-US.
+#: views/elements/translationbox.thtml:143
+msgid "devcp_transbox_help_header_tabs"
+msgstr "ã“れら㮠%s タブã¯ä½•ã§ã™ã‹ï¼Ÿ"
+
+#: views/elements/translationbox.thtml:145
+msgid "devcp_transbox_help_header_what"
+msgstr "翻訳を用æ„ã—ã¦ã„ãªã„å ´åˆã¯ã©ã†ãªã‚Šã¾ã™ã‹ï¼Ÿ"
+
+#: views/elements/translationbox.thtml:147
+msgid "devcp_transbox_help_hide"
+msgstr "ヘルプを隠ã™"
+
+#: views/elements/translationbox.thtml:146
+msgid "devcp_transbox_help_if"
+msgstr ""
+"ユーザãŒã‚µã‚¤ãƒˆã‚’閲覧ã—ãŸã¨ãã«æ¯å›½èªžã®ç¿»è¨³ãŒæä¾›ã•ã‚Œã¦ã„ãªã„å ´åˆã¯ã€ã‚¢ãƒ‰ã‚ªãƒ³"
+"ã®ãƒ—ロパティ編集画é¢ã§æŒ‡å®šã•ã‚ŒãŸæ—¢å®šã®ãƒ­ã‚±ãƒ¼ãƒ«ãŒä½¿ç”¨ã•ã‚Œã¾ã™ã€‚ã‚ãªãŸãŒç¿»è¨³ã‚’"
+"ã¾ã£ãŸã用æ„ã—ã¦ã„ãªã„å ´åˆã¯ã€å…¥åŠ›å¯èƒ½ãªè¨€èªžã€ã¤ã¾ã‚Šã‚ãªãŸè‡ªèº«ã®æ¯å›½èªžã‚’既定"
+"ã®ãƒ­ã‚±ãƒ¼ãƒ«ã«æŒ‡å®šã—ã¦ãã ã•ã„。"
+
+#: views/elements/translationbox.thtml:144
+msgid "devcp_transbox_help_transbox"
+msgstr ""
+"ã“れ㯠<b>翻訳ボックス</b> ã§ã™ã€‚特定ã®å…¥åŠ›æ¬„ã‚’ã€ç¿»è¨³ã‚’用æ„ã—ã¦ã„ã‚‹ä»–ã®è¨€èªžã«"
+"ローカライズã§ãã¾ã™ã€‚ロケールã®ã‚¿ãƒ–を使用ã™ã‚‹ã“ã¨ã§ã€ç¿»è¨³ã‚’追加ã€ç·¨é›†ã€å‰Šé™¤"
+"ã§ãã¾ã™ã€‚"
+
+#: views/elements/translationbox.thtml:85
+msgid "devcp_transbox_img_add_trans"
+msgstr "翻訳を追加"
+
+#: views/elements/translationbox.thtml:86
+msgid "devcp_transbox_img_remove_trans"
+msgstr "翻訳を削除"
+
+#: views/elements/translationbox.thtml:123
+msgid "devcp_transbox_input_add_all"
+msgstr "ã™ã¹ã¦ã®æ¬„ã«ãƒ­ã‚±ãƒ¼ãƒ«ã‚’追加"
+
+#: views/elements/translationbox.thtml:122
+msgid "devcp_transbox_input_add_locale"
+msgstr "ロケールを追加"
+
+#: views/elements/translationbox.thtml:124
+#: views/elements/translationbox.thtml:135
+msgid "devcp_transbox_input_cancel"
+msgstr "キャンセル"
+
+#: views/elements/translationbox.thtml:134
+msgid "devcp_transbox_input_delete"
+msgstr "削除"
+
+#: views/elements/translationbox.thtml:113
+msgid "devcp_transbox_select_locale"
+msgstr "追加ã™ã‚‹ç¿»è¨³ã®ãƒ­ã‚±ãƒ¼ãƒ«ã‚’é¸æŠžã—ã¦ãã ã•ã„:"
+
+#. %1$s and %2$s are GUIDs.
+#: controllers/developers_controller.php:343
+msgid "devcp_update_addon_guid_error"
+msgstr ""
+"ã“ã®ãƒ•ã‚¡ã‚¤ãƒ«ã§ä½¿ç”¨ã•ã‚Œã¦ã„るアドオン㮠GUID (%1$s) ã¯ã€ã“ã®ã‚¢ãƒ‰ã‚ªãƒ³ã®æ—¢å­˜ã®"
+"GUID (%2$s) ã¨ä¸€è‡´ã—ã¾ã›ã‚“。"
+
+#: controllers/developers_controller.php:334
+msgid "devcp_update_addon_priv_error"
+msgstr "ã‚ãªãŸã«ã¯ã“ã®ã‚¢ãƒ‰ã‚ªãƒ³æ›´æ–°ã™ã‚‹æ¨©é™ãŒã‚ã‚Šã¾ã›ã‚“。"
+
+#. %1$s is a version number, %2$s is an add-on ID.
+#: controllers/developers_controller.php:399
+msgid "devcp_update_addon_version_belong_error"
+msgstr "指定ã•ã‚ŒãŸãƒãƒ¼ã‚¸ãƒ§ãƒ³ (%1$s) ã¯ã“ã®ã‚¢ãƒ‰ã‚ªãƒ³ (%2$s) ã«å±žã—ã¾ã›ã‚“。"
+
+#. %1$s is a version number, maybe 1.1.
+#. %2$s is a URL.
+#: controllers/developers_controller.php:351
+msgid "devcp_update_addon_version_exists_error"
+msgstr ""
+"アップロードã•ã‚ŒãŸãƒãƒ¼ã‚¸ãƒ§ãƒ³ (%1$s) ã¯æ—¢ã«å­˜åœ¨ã—ã¾ã™ã€‚ã“ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã«ä»–ã®"
+"ファイルを追加ã™ã‚‹ã«ã¯ã€<a href=\"%2$s\">ã“ã“をクリック</a> ã—ã¦ãã ã•ã„。"
+
+#. %1$s and %2$s are version numbers.
+#: controllers/developers_controller.php:405
+msgid "devcp_update_addon_version_match_error"
+msgstr ""
+"アップロードã•ã‚ŒãŸãƒãƒ¼ã‚¸ãƒ§ãƒ³ç•ªå· (%1$s) ã¯ã€æ—¢å­˜ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ç•ªå· (%2$s) ã¨ä¸€"
+"致ã—ã¾ã›ã‚“。"
+
+#: views/developers/uploader.thtml:68
+msgid "devcp_uploader_a_start"
+msgstr "スタート"
+
+#: views/developers/uploader.thtml:137
+msgid "devcp_uploader_ajax_loading"
+msgstr "ファイルをアップロードã—ã¦ã„ã¾ã™..."
+
+#: views/developers/uploader.thtml:82
+msgid "devcp_uploader_button_agree"
+msgstr "åŒæ„ã—ã¦ç¶šã‘ã‚‹"
+
+#: views/developers/uploader.thtml:157
+msgid "devcp_uploader_button_edit"
+msgstr "自分ã®ã‚¢ãƒ‰ã‚ªãƒ³ã‚’編集"
+
+#: views/developers/uploader.thtml:158
+msgid "devcp_uploader_button_later"
+msgstr "アドオンã¯å¾Œã§å®Œæˆã•ã›ã¾ã™ã€‚"
+
+#: views/developers/uploader.thtml:168
+msgid "devcp_uploader_button_release"
+msgstr "リリースノートを追加"
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/uploader.thtml:156
+msgid "devcp_uploader_created_results"
+msgstr ""
+"<p>アドオンã®ç™»éŒ²ãŒå®Œäº†ã—ã¾ã—ãŸã€‚アップロードã•ã‚ŒãŸãƒ•ã‚¡ã‚¤ãƒ«ã‹ã‚‰å–å¾—ã•ã‚ŒãŸåŸºæœ¬"
+"情報ã¯ä¿å­˜ã•ã‚Œã¾ã—ãŸãŒã€ä»–ã«ã‚‚公開ページã«æŽ²è¼‰ã™ã‚‹æƒ…報を編集ã§ãã¾ã™ã€‚</p><p>"
+"ã“ã®ã‚¢ãƒ‰ã‚ªãƒ³ã¯ã€ç¾æ™‚点ã§ã¯ã¾ã  <strong>未完æˆ</strong> ã¨ã•ã‚Œã¦ã„ã¾ã™ã€‚アドオ"
+"ンを完æˆã•ã›ã‚‹ã«ã¯ã€çš„確ãªã‚¿ã‚¤ãƒˆãƒ«ã€è¦ç´„ã€èª¬æ˜Žã‚’記述ã™ã‚‹ã¨ã¨ã‚‚ã«ã€å°‘ãªãã¨ã‚‚"
+"ã²ã¨ã¤ã¯ã‚«ãƒ†ã‚´ãƒªã‚’é¸æŠžã™ã‚‹å¿…è¦ãŒã‚ã‚Šã¾ã™ã€‚アドオンã®æƒ…å ±ã¯ä»¥ä¸‹ã®ãƒªãƒ³ã‚¯ã‚’使用"
+"ã—ã¦ç·¨é›†ã§ãã¾ã™ã€‚ã¾ãŸã€ã‚¢ãƒ‰ã‚ªãƒ³ã®ã‚¹ãƒ†ãƒ¼ã‚¿ã‚¹ã¯ <a %s>ステータスページ</a> ã§"
+"ã„ã¤ã§ã‚‚確èªã§ãã¾ã™ã€‚"
+
+#: views/developers/uploader.thtml:143
+msgid "devcp_uploader_error_correct"
+msgstr "ã“ã®å•é¡Œã‚’修正ã—ãŸä¸Šã§å†åº¦ãƒ•ã‚¡ã‚¤ãƒ«ã‚’アップロードã—ã¦ãã ã•ã„。"
+
+#. %1$s is a version number, %2$s is a status, e.g Public or Incomplete.
+#: views/developers/uploader.thtml:175
+msgid "devcp_uploader_file_created"
+msgstr "æ–°ã—ã„ファイルã¯ãƒãƒ¼ã‚¸ãƒ§ãƒ³ %1$s ã¸è¿½åŠ ã•ã‚Œã€ç¾åœ¨ %2$s ã¨ã•ã‚Œã¦ã„ã¾ã™ã€‚"
+
+#: views/developers/uploader.thtml:154
+msgid "devcp_uploader_header_created"
+msgstr "アドオンãŒä½œæˆã•ã‚Œã¾ã—ãŸã€‚"
+
+#: views/developers/uploader.thtml:141
+msgid "devcp_uploader_header_error"
+msgstr "ã“ã®ãƒ•ã‚¡ã‚¤ãƒ«ã«ã¯å•é¡ŒãŒã‚るよã†ã§ã™ã€‚"
+
+#: views/developers/uploader.thtml:173
+msgid "devcp_uploader_header_file_added"
+msgstr "ファイルãŒè¿½åŠ ã•ã‚Œã¾ã—ãŸã€‚"
+
+#: views/developers/uploader.thtml:66
+msgid "devcp_uploader_header_how"
+msgstr "ã“ã‚Œã¯ã©ã®ã‚ˆã†ã«ä½¿ã†ã®ã§ã™ã‹ï¼Ÿ"
+
+#. %s is the version number, e.g. 3.2.
+#: views/developers/uploader.thtml:163
+msgid "devcp_uploader_header_update_created"
+msgstr "ãƒãƒ¼ã‚¸ãƒ§ãƒ³ %s ãŒä½œæˆã•ã‚Œã¾ã—ãŸ"
+
+#: views/developers/uploader.thtml:117
+msgid "devcp_uploader_header_upload"
+msgstr "ファイルをアップロード"
+
+#: views/developers/uploader.thtml:67
+msgid "devcp_uploader_how"
+msgstr ""
+"<p>Mozilla Add-ons ã¸ã®ã‚¢ãƒ‰ã‚ªãƒ³ã®ç™»éŒ²ã«èˆˆå‘³ã‚’ãŠæŒã¡ã„ãŸã ãã€ã‚ã‚ŠãŒã¨ã†ã”ã–ã„"
+"ã¾ã™ã€‚Mozilla Add-ons ã§ã®ã‚¢ãƒ‰ã‚ªãƒ³ã®ãƒ›ã‚¹ãƒ†ã‚£ãƒ³ã‚°ã¯ã€ã‚¢ãƒ‰ã‚ªãƒ³ã®é…布を管ç†ã™ã‚‹"
+"最も簡å˜ãªæ–¹æ³•ã§ã™ã€‚ã“ã®ã‚µã‚¤ãƒˆã§ã¯ä»¥ä¸‹ã®ã‚ˆã†ãªæ©Ÿèƒ½ã‚’利用ã§ãã¾ã™ã€‚</"
+"p><ul><li>å„アドオンã«ã¯ã€ã‚ãªãŸãŒæä¾›ã—ãŸæƒ…報をå«ã‚€å…¬é–‹ãƒšãƒ¼ã‚¸ãŒæä¾›ã•ã‚Œã¾"
+"ã™ã€‚ã“ã“ã«ã¯ã€ã‚¢ãƒ‰ã‚ªãƒ³ã®æ©Ÿèƒ½ã®ç°¡å˜ãªè¦ç´„ã€ã‚ˆã‚Šè©³ã—ã„説明ã€ãƒ—レビュー用スク"
+"リーンショットãªã©ã‚’掲載ã§ãã¾ã™ã€‚</li><li>ã‚ãªãŸã®ã‚¢ãƒ‰ã‚ªãƒ³ã¯ã€ã‚µã‚¤ãƒˆå…¨ä½“ã®æ¤œ"
+"ç´¢çµæžœãªã©ã«åŠ ãˆã¦ã€Firefox 3 ã®ã‚¢ãƒ‰ã‚ªãƒ³ãƒžãƒãƒ¼ã‚¸ãƒ£ã«ã‚‚表示ã•ã‚Œã¾ã™ã€‚</li><li>"
+"ダウンロードã®ãŸã‚ã®ã™ã¹ã¦ã®ãƒ›ã‚¹ãƒ†ã‚£ãƒ³ã‚°ãŒæä¾›ã•ã‚Œã€ã‚ãªãŸãŒæ–°ã—ã„ãƒãƒ¼ã‚¸ãƒ§ãƒ³"
+"をアップロードã—ãŸã¨ãã«ã¯ã€æ—¢å­˜ã®ãƒ¦ãƒ¼ã‚¶å‘ã‘ã«è‡ªå‹•æ›´æ–°ãŒè¡Œã‚ã‚Œã¾ã™ã€‚</li><li>"
+"ユーザã®åˆ©ç”¨çŠ¶æ³ã«é–¢ã™ã‚‹è©³ã—ã„情報を閲覧ã§ãる統計ダッシュボードãŒæä¾›ã•ã‚Œã¾"
+"ã™ã€‚</li></ul><p>Mozilla Add-ons ã®ã‚µã‚¤ãƒˆã«ç™»éŒ²ã•ã‚ŒãŸã‚¢ãƒ‰ã‚ªãƒ³ãŒã€ã“れらã™ã¹ã¦"
+"ã®æ©Ÿèƒ½ã‚’利用ã§ãるよã†ã«ãªã‚‹ã«ã¯ã€ã‚¨ãƒ‡ã‚£ã‚¿ã«ã‚ˆã‚‹ãƒ¬ãƒ“ューをå—ã‘ã‚‹å¿…è¦ãŒã‚ã‚Šã¾"
+"ã™ã€‚ã“ã®ãƒ—ロセスを始ã‚る準備ãŒã§ãã¦ã„ã¦ã€æ—¢ã«ã‚¢ãƒƒãƒ—ロードã™ã‚‹ã‚¢ãƒ‰ã‚ªãƒ³ãƒ‘ッ"
+"ケージをãŠæŒã¡ãªã‚‰ã€ä¸‹ã®ã€Œã‚¹ã‚¿ãƒ¼ãƒˆã€ã‚’クリックã—ã¦ãã ã•ã„ï¼</p>"
+
+#: views/developers/uploader.thtml:125
+msgid "devcp_uploader_label_platformtype"
+msgstr "対応プラットフォーム:"
+
+#: views/developers/uploader.thtml:124
+msgid "devcp_uploader_label_upload_field"
+msgstr "アドオンã®ãƒ•ã‚¡ã‚¤ãƒ«: "
+
+#: controllers/components/developers.php:1221
+msgid "devcp_uploader_option_other"
+msgstr "ãã®ä»–"
+
+#. %1$s is a number, %2$s is href="..." and should stay in the <a> tag.
+#: views/developers/uploader.thtml:176
+msgid "devcp_uploader_p_pending_file"
+msgstr ""
+"æ–°ã—ã„ファイルã¯ã€ã‚¨ãƒ‡ã‚£ã‚¿ã«ã‚ˆã‚‹ãƒ¬ãƒ“ューãŒå®Œäº†æ¬¡ç¬¬ã€ä¸€èˆ¬ã«å…¬é–‹ã•ã‚Œã¾ã™ã€‚ç¾åœ¨"
+"ä»–ã« %1$s 個ã®ã‚¢ãƒ‰ã‚ªãƒ³ãŒãƒ¬ãƒ“ューを待ã£ã¦ã„ã¾ã™ã€‚ã‚‚ã£ã¨æ—©ãレビューをå—ã‘ãŸã„"
+"ã§ã™ã‹ï¼Ÿ ãã‚Œãªã‚‰ <a %2$s>エディタã«ãªã‚‹</a> ã“ã¨ã‚’ã”検討ãã ã•ã„。"
+
+#. %1$s is a number, %2$s is href="..." and should stay in the <a> tag.
+#: views/developers/uploader.thtml:166
+msgid "devcp_uploader_p_pending_version"
+msgstr ""
+"æ–°ã—ã„ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã¯ã€ã‚¨ãƒ‡ã‚£ã‚¿ã«ã‚ˆã‚‹ãƒ¬ãƒ“ューãŒå®Œäº†æ¬¡ç¬¬ã€ä¸€èˆ¬ã«å…¬é–‹ã•ã‚Œã¾ã™ã€‚ç¾"
+"在他㫠%1$s 個ã®ã‚¢ãƒ‰ã‚ªãƒ³ãŒãƒ¬ãƒ“ューを待ã£ã¦ã„ã¾ã™ã€‚ã‚‚ã£ã¨æ—©ãレビューをå—ã‘ãŸ"
+"ã„ã§ã™ã‹ï¼Ÿ ãã‚Œãªã‚‰ <a %2$s>エディタã«ãªã‚‹</a> ã“ã¨ã‚’ã”検討ãã ã•ã„。"
+
+#. %s is a status, e.g Public or Incomplete.
+#: views/developers/uploader.thtml:165
+msgid "devcp_uploader_p_update_created"
+msgstr "æ–°ã—ã„ãƒãƒ¼ã‚¸ãƒ§ãƒ³ãŒä½œæˆã•ã‚Œã€ç¾åœ¨ %s ã¨ã•ã‚Œã¦ã„ã¾ã™ã€‚"
+
+#. %1$s is href="..." and should stay in the 'Versions and Files' <a> tag.
+#. %2$s is href="..." and should stay in the 'current status' <a> tag.
+#: views/developers/uploader.thtml:177
+msgid "devcp_uploader_p_update_file"
+msgstr ""
+"æ–°ã—ã„ファイル㯠<a %1$s>ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã¨ãƒ•ã‚¡ã‚¤ãƒ«</a> ã®ãƒšãƒ¼ã‚¸ã§è¡¨ç¤ºã§ãã¾ã™ã€‚ã‚¢"
+"ドオン㮠<a %2$s>ç¾åœ¨ã®ã‚¹ãƒ†ãƒ¼ã‚¿ã‚¹</a> を確èªã—ãŸã‚Šã€ä¸‹ã®ãƒœã‚¿ãƒ³ã‚’クリックã—ã¦"
+"<b>リリースノートを追加</b>ã™ã‚‹ã“ã¨ã‚‚ã§ãã¾ã™ (å¼·ã推奨ã—ã¾ã™)。"
+
+#. %1$s is href="..." and should stay in the 'Versions and Files' <a> tag.
+#. %2$s is href="..." and should stay in the 'current status' <a> tag.
+#: views/developers/uploader.thtml:167
+msgid "devcp_uploader_p_update_version"
+msgstr ""
+"æ–°ã—ã„ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã¯ <a %1$s>ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã¨ãƒ•ã‚¡ã‚¤ãƒ«</a> ã®ãƒšãƒ¼ã‚¸ã§è¡¨ç¤ºã§ãã¾ã™ã€‚"
+"アドオン㮠<a %2$s>ç¾åœ¨ã®ã‚¹ãƒ†ãƒ¼ã‚¿ã‚¹</a> を確èªã—ãŸã‚Šã€ä¸‹ã®ãƒœã‚¿ãƒ³ã‚’クリックã—"
+"ã¦<b>リリースノートを追加</b>ã™ã‚‹ã“ã¨ã‚‚ã§ãã¾ã™ (å¼·ã推奨ã—ã¾ã™)。"
+
+#: views/developers/uploader.thtml:118
+msgid "devcp_uploader_p_upload"
+msgstr ""
+"アドオンã®ãƒ•ã‚¡ã‚¤ãƒ«ã‚’アップロードã™ã‚‹ã«ã¯ä¸‹ã®ãƒ•ã‚©ãƒ¼ãƒ ã‚’使用ã—ã¾ã™ã€‚複数ã®ãƒ—"
+"ラットフォームã”ã¨ã®ãƒ•ã‚¡ã‚¤ãƒ«ã‚’アップロードã™ã‚‹ã«ã¯ã€ã¾ãšã“ã“ã§ã²ã¨ã¤ã®ãƒ•ã‚¡ã‚¤"
+"ルをé¸æŠžã—ã€ãã‚Œã‹ã‚‰ä»–ã®ãƒ•ã‚¡ã‚¤ãƒ«ã‚’「ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã¨ãƒ•ã‚¡ã‚¤ãƒ«ã€ç®¡ç†ç”»é¢ã§ã‚¢ãƒƒãƒ—"
+"ロードã—ã¦ãã ã•ã„。"
+
+#: views/developers/uploader.thtml:125
+msgid "devcp_uploader_platformtype_all"
+msgstr "ã™ã¹ã¦"
+
+#: views/developers/uploader.thtml:126
+msgid "devcp_uploader_platformtype_specific"
+msgstr "特定:"
+
+#. Used as first item in a <select>.
+#: controllers/components/developers.php:1185
+msgid "devcp_uploader_please_choose"
+msgstr "é¸æŠžã—ã¦ãã ã•ã„..."
+
+#. %1$s is the add-on name, %2$s is the version number.
+#: views/developers/uploader.thtml:57
+msgid "devcp_uploader_title_file"
+msgstr "%1$s %2$s ã¸ãƒ•ã‚¡ã‚¤ãƒ«ã‚’追加"
+
+#: views/developers/uploader.thtml:50
+msgid "devcp_uploader_title_submit"
+msgstr "æ–°ã—ã„アドオンを登録"
+
+#. %s is the add-on name.
+#: views/developers/uploader.thtml:54
+msgid "devcp_uploader_title_update"
+msgstr "%s ã‚’æ›´æ–°"
+
+#. %s is a full <a> tag
+#: controllers/developers_controller.php:503
+#, php-format
+msgid "devcp_valid_app_reference"
+msgstr "å‚考ã¨ã—㦠%s ã‚’ã”覧ãã ã•ã„。"
+
+#. This is the text in the <a> tag for devcp_valid_app_reference. This should be
+#. fixed.
+#: controllers/developers_controller.php:503
+msgid "devcp_valid_app_reference_linktext"
+msgstr "ã“ã¡ã‚‰ã®ãƒšãƒ¼ã‚¸"
+
+#: controllers/developers_controller.php:581
+msgid "devcp_verify_author_error"
+msgstr "ã“ã®ãƒ¡ãƒ¼ãƒ«ã‚¢ãƒ‰ãƒ¬ã‚¹ã‚’æŒã¤ã‚¢ã‚«ã‚¦ãƒ³ãƒˆã¯è¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ã§ã—ãŸã€‚"
+
+#: controllers/developers_controller.php:553
+msgid "devcp_verify_search_engine_error"
+msgstr ""
+"XML ã®å½¢å¼ãŒæ­£ã—ããªã„ã‹ã€å¿…須項目ãŒä¸è¶³ã—ã¦ã„ã¾ã™ã€‚<a href=\"https://"
+"developer.mozilla.org/ja/Creating_OpenSearch_plugins_for_Firefox\">ドキュメン"
+"ト</a> を読んã§ã‚¢ãƒ‰ã‚ªãƒ³ã‚’確èªã—ã€å†åº¦è©¦ã—ã¦ãã ã•ã„。"
+
+#: views/developers/versions.thtml:75
+msgid "devcp_versions_a_cancel"
+msgstr "キャンセル"
+
+#: views/developers/versions.thtml:79
+msgid "devcp_versions_a_delete"
+msgstr "ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã‚’削除"
+
+#: views/developers/versions.thtml:74
+msgid "devcp_versions_a_empty"
+msgstr "空ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã‚’削除"
+
+#: views/developers/versions.thtml:71
+msgid "devcp_versions_a_remove"
+msgstr "削除ã—ã¾ã™ã‹ï¼Ÿ"
+
+#: views/developers/versions.thtml:91
+msgid "devcp_versions_add"
+msgstr "æ–°ã—ã„ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã‚’追加"
+
+#: views/developers/versions_delete.thtml:58
+msgid "devcp_versions_delete_a_cancel"
+msgstr "キャンセル"
+
+#: views/developers/versions_delete.thtml:56
+msgid "devcp_versions_delete_a_delete"
+msgstr "ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã‚’削除"
+
+#. Followed by a list of reviews and files that will be removed.
+#: views/developers/versions_delete.thtml:50
+msgid "devcp_versions_delete_also"
+msgstr "ã“ã‚Œã«ã‚ˆã‚Šä»¥ä¸‹ã®é …目も削除ã•ã‚Œã¾ã™:"
+
+#: views/developers/versions_delete.thtml:53
+msgid "devcp_versions_delete_files"
+msgid_plural "devcp_versions_delete_files"
+msgstr[0] "%s ファイル"
+msgstr[1] "%s ファイル"
+
+#. %s is the version number.
+#: views/developers/versions_delete.thtml:48
+msgid "devcp_versions_delete_header"
+msgstr "ãƒãƒ¼ã‚¸ãƒ§ãƒ³ %s を削除ã—ã¾ã™ã‹ï¼Ÿ"
+
+#: views/developers/versions_delete.thtml:52
+msgid "devcp_versions_delete_reviews"
+msgid_plural "devcp_versions_delete_reviews"
+msgstr[0] "%s レビュー"
+msgstr[1] "%s レビュー"
+
+#. %s is the version number.
+#: views/developers/versions_delete.thtml:49
+msgid "devcp_versions_delete_sure"
+msgstr "ãƒãƒ¼ã‚¸ãƒ§ãƒ³ %s を完全ã«å‰Šé™¤ã—ã¦ã‚‚よã‚ã—ã„ã§ã™ã‹ï¼Ÿ"
+
+#: views/developers/versions_edit.thtml:102
+#: views/developers/versions_edit.thtml:155
+msgid "devcp_versions_edit_a_cancel"
+msgstr "キャンセル"
+
+#: views/developers/versions_edit.thtml:101
+msgid "devcp_versions_edit_a_delete"
+msgstr "ファイルを削除"
+
+#: views/developers/versions_edit.thtml:165
+msgid "devcp_versions_edit_a_new_app"
+msgstr "æ–°ã—ã„アプリケーションを追加"
+
+#: views/developers/versions_edit.thtml:154
+msgid "devcp_versions_edit_a_remove_app"
+msgstr "アプリケーションを削除"
+
+#: views/developers/versions_edit.thtml:114
+msgid "devcp_versions_edit_add"
+msgstr "æ–°ã—ã„ファイルを追加"
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/versions_edit.thtml:121
+msgid "devcp_versions_edit_adjust"
+msgstr ""
+"ã“ã“ã§ã‚¢ãƒ—リケーション情報を編集ã™ã‚‹ã¨ã€ã‚¢ãƒ‰ã‚ªãƒ³ã®ãƒ‘ッケージã«å«ã¾ã‚Œã¦ã„ã‚‹ "
+"install.rdf ã§ã¯äº’æ›æ€§ãŒãªã„ã¨åˆ¤æ–­ã•ã‚Œã‚‹å ´åˆã§ã‚ã£ã¦ã‚‚ã€ãƒ¦ãƒ¼ã‚¶ãŒã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«"
+"ã§ãるよã†ã«ãªã‚Šã¾ã™ã€‚<a %s>対応アプリケーションã®ä¸€è¦§</a>"
+
+#: views/developers/versions_edit.thtml:153
+msgid "devcp_versions_edit_compat_sure"
+msgstr "ã“ã®ã‚¢ãƒ—リケーションã¨ã®äº’æ›æ€§ã‚’削除ã—ã¦ã‚‚よã‚ã—ã„ã§ã™ã‹ï¼Ÿ"
+
+#: views/developers/versions_edit.thtml:100
+msgid "devcp_versions_edit_delete_sure"
+msgstr "ã“ã®ãƒ•ã‚¡ã‚¤ãƒ«ã‚’完全ã«å‰Šé™¤ã—ã¦ã‚‚よã‚ã—ã„ã§ã™ã‹ï¼Ÿ"
+
+#: views/developers/versions_edit.thtml:203
+msgid "devcp_versions_edit_header_approval"
+msgstr "承èªã«é–¢ã™ã‚‹æƒ…å ±"
+
+#: views/developers/versions_edit.thtml:120
+msgid "devcp_versions_edit_header_compat"
+msgstr "互æ›æ€§ã®ã‚るアプリケーション"
+
+#: views/developers/versions_edit.thtml:74
+msgid "devcp_versions_edit_header_file"
+msgstr "ファイル情報"
+
+#: views/developers/versions_edit.thtml:189
+msgid "devcp_versions_edit_header_license"
+msgstr "ライセンス"
+
+#. %s is the version number.
+#: views/developers/versions_edit.thtml:53
+msgid "devcp_versions_edit_header_manage"
+msgstr "ãƒãƒ¼ã‚¸ãƒ§ãƒ³ %s を管ç†"
+
+#: views/developers/versions_edit.thtml:212
+msgid "devcp_versions_edit_header_notes"
+msgstr "承èªã«é–¢ã™ã‚‹æ³¨æ„"
+
+#: views/developers/versions_edit.thtml:98
+msgid "devcp_versions_edit_img_delete"
+msgstr "ファイルを削除"
+
+#. %1$s is the file id, e.g. 18723.
+#. %2$s is the platform name, e.g. ALL or Windows.
+#. %3$s is the _('date) created.
+#. %4$s is the status, e.g. "In Sandbox" or "Public".
+#. %5$s is the _('date') status was changed.
+#: views/developers/versions_edit.thtml:208
+msgid "devcp_versions_edit_li_file"
+msgstr "ファイル %1$s (%2$s) 㯠%3$s ã«ä½œæˆã•ã‚Œã€%5$s ã« %4$s ã«å¤‰æ›´ã•ã‚Œã¾ã—ãŸ"
+
+#: views/developers/versions_edit.thtml:190
+msgid "devcp_versions_edit_license_description"
+msgstr ""
+"ã‚ãªãŸã®ã‚¢ãƒ‰ã‚ªãƒ³ã®é©åˆ‡ãªãƒ©ã‚¤ã‚»ãƒ³ã‚¹ã‚’é¸æŠžã—ã¦ãã ã•ã„。ã“ã®ãƒ©ã‚¤ã‚»ãƒ³ã‚¹ã¯ã€ã‚¢ãƒ‰"
+"オンã«å«ã¾ã‚Œã‚‹ã‚½ãƒ¼ã‚¹ã‚³ãƒ¼ãƒ‰ã«å¯¾ã—ã¦ä¸Žãˆã‚‹æ¨©åˆ©ã‚’明記ã™ã‚‹ã‚‚ã®ã§ã™ã€‚"
+
+#: views/developers/versions_edit.thtml:111
+msgid "devcp_versions_edit_no_files"
+msgstr "ファイルãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ã§ã—ãŸã€‚"
+
+#: views/developers/versions_edit.thtml:213
+msgid "devcp_versions_edit_optional"
+msgstr "ã“ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã‚’レビューã™ã‚‹ã‚¨ãƒ‡ã‚£ã‚¿ã«ä¼ãˆãŸã„ä»»æ„ã®æƒ…å ±ã§ã™ã€‚"
+
+#: views/developers/versions_edit.thtml:151
+msgid "devcp_versions_edit_remove_compat"
+msgstr "アプリケーション互æ›æ€§ã‚’削除"
+
+#: views/developers/versions_edit.thtml:167
+msgid "devcp_versions_edit_select_app"
+msgstr "アプリケーションをé¸æŠžã—ã¦ãã ã•ã„"
+
+#: views/developers/versions_edit.thtml:78
+msgid "devcp_versions_edit_th_file"
+msgstr "ファイル"
+
+#: views/developers/versions_edit.thtml:79
+msgid "devcp_versions_edit_th_platform"
+msgstr "プラットフォーム"
+
+#: views/developers/versions_edit.thtml:80
+msgid "devcp_versions_edit_th_size"
+msgstr "サイズ"
+
+#: views/developers/versions_edit.thtml:81
+msgid "devcp_versions_edit_th_status"
+msgstr "ステータス"
+
+#: views/developers/versions_edit.thtml:183
+msgid "devcp_versions_edit_transbox_releasenotes_description"
+msgstr ""
+"ã“ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã§ã®å¤‰æ›´ç‚¹ã€æ–°æ©Ÿèƒ½ã€æ—¢çŸ¥ã®ãƒã‚°ã€ãã®ä»–ã“ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã«é™ã£ãŸå‚"
+"考ã«ãªã‚‹æƒ…報を入力ã—ã¾ã™ã€‚ã“れらã®æƒ…å ±ã¯ã€ãƒ¦ãƒ¼ã‚¶ãŒ Firefox 3 ã®ã‚¢ãƒ‰ã‚ªãƒ³ãƒžãƒãƒ¼"
+"ジャ画é¢ã‹ã‚‰ã‚¢ãƒ‰ã‚ªãƒ³ã‚’æ›´æ–°ã™ã‚‹éš›ã«ã‚‚表示ã•ã›ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚"
+
+#: views/developers/versions_edit.thtml:182
+msgid "devcp_versions_edit_transbox_releasenotes_name"
+msgstr "リリースノート"
+
+#: views/developers/versions_edit.thtml:164
+msgid "devcp_versions_edit_unsaved_compat"
+msgstr ""
+"<strong>ä¿å­˜ã•ã‚Œã¦ã„ãªã„変更ãŒã‚ã‚Šã¾ã™ã€‚</strong> 互æ›æ€§æƒ…å ±ã¯ã€ä¸‹ã®ã€Œãƒãƒ¼"
+"ジョン情報を更新ã€ã‚’クリックã™ã‚‹ã¾ã§å‰Šé™¤ã•ã‚Œã¾ã›ã‚“。"
+
+#: views/developers/versions_edit.thtml:113
+msgid "devcp_versions_edit_unsaved_files"
+msgstr ""
+"<strong>ä¿å­˜ã•ã‚Œã¦ã„ãªã„変更ãŒã‚ã‚Šã¾ã™ã€‚</strong> ファイルã¯ã€ä¸‹ã®ã€Œãƒãƒ¼ã‚¸ãƒ§"
+"ン情報を更新ã€ã‚’クリックã™ã‚‹ã¾ã§å‰Šé™¤ã•ã‚Œã¾ã›ã‚“。"
+
+#: views/developers/versions_edit.thtml:218
+msgid "devcp_versions_edit_update"
+msgstr "ãƒãƒ¼ã‚¸ãƒ§ãƒ³æƒ…報を更新"
+
+#: views/developers/versions.thtml:49
+msgid "devcp_versions_header_manage"
+msgstr "ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã¨ãƒ•ã‚¡ã‚¤ãƒ«ã®ç®¡ç†"
+
+#: views/developers/versions.thtml:87
+msgid "devcp_versions_no_versions"
+msgstr "ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã¯è¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ã§ã—ãŸã€‚"
+
+#. %s is a version number, base 10.
+#: views/developers/versions.thtml:46
+msgid "devcp_versions_notice_success"
+msgstr "ãƒãƒ¼ã‚¸ãƒ§ãƒ³ %s ã¯å‰Šé™¤ã•ã‚Œã¾ã—ãŸã€‚"
+
+#: views/developers/versions.thtml:73
+msgid "devcp_versions_p_remove"
+msgstr ""
+"ã“ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã«ã¯ã€é–¢é€£ä»˜ã‘られãŸå‰Šé™¤å¯èƒ½ãªãƒ•ã‚¡ã‚¤ãƒ«ãŒã‚ã‚Šã¾ã›ã‚“。ã“ã®ãƒãƒ¼"
+"ジョンを削除ã—ã¾ã™ã‹ï¼Ÿ"
+
+#: views/developers/versions.thtml:58
+msgid "devcp_versions_th_created"
+msgstr "作æˆæ—¥"
+
+#: views/developers/versions.thtml:57
+msgid "devcp_versions_th_status"
+msgstr "ステータス"
+
+#: views/developers/versions.thtml:56
+msgid "devcp_versions_th_version"
+msgstr "ãƒãƒ¼ã‚¸ãƒ§ãƒ³"
+
+#: controllers/downloads_controller.php:91
+msgid "downloads_disable_warning"
+msgstr "ã“ã®ã‚¢ãƒ‰ã‚ªãƒ³ã®å…¬é–‹ã¯ä¸­æ­¢ã•ã‚Œã¦ã„ã¾ã™"
+
+#: controllers/components/editors.php:57
+msgid "editor_review_error_addon_not_nominated"
+msgstr "ã“ã®ã‚¢ãƒ‰ã‚ªãƒ³ã¯ã¾ã å…¬é–‹ç”³è«‹ã•ã‚Œã¦ã„ã¾ã›ã‚“。"
+
+#: controllers/components/editors.php:213
+msgid "editor_review_error_file_not_pending"
+msgstr "ã“ã®ãƒ•ã‚¡ã‚¤ãƒ«ã¯ãƒ¬ãƒ“ュー待ã¡ã®çŠ¶æ…‹ã§ã¯ã‚ã‚Šã¾ã›ã‚“。"
+
+#. Actions are, for example: approving or rejecting
+#: controllers/components/editors.php:79
+#: controllers/components/editors.php:182
+msgid "editor_review_error_no_action"
+msgstr "レビューアクションをé¸æŠžã—ã¦ãã ã•ã„。"
+
+#: controllers/components/editors.php:192
+msgid "editor_review_error_no_applications"
+msgstr "テストを行ã£ãŸã‚¢ãƒ—リケーションを入力ã—ã¦ãã ã•ã„。"
+
+#. Comments are required when an editor approves or rejects an add-on.
+#: controllers/components/editors.php:84
+#: controllers/components/editors.php:187
+msgid "editor_review_error_no_comments"
+msgstr "レビューコメントを入力ã—ã¦ãã ã•ã„。"
+
+#: controllers/components/editors.php:161
+msgid "editor_review_error_no_files"
+msgstr "レビューを行ã†ãƒ•ã‚¡ã‚¤ãƒ«ã‚’å°‘ãªãã¨ã‚‚ã²ã¨ã¤ã¯é¸æŠžã—ã¦ãã ã•ã„。"
+
+#: controllers/components/editors.php:197
+msgid "editor_review_error_no_operating_system"
+msgstr "テストを行ã£ãŸ OS を入力ã—ã¦ãã ã•ã„。"
+
+#: views/editors/logs.thtml:51
+msgid "editorcp_logs_button_filter"
+msgstr "フィルタ"
+
+#: views/editors/logs.thtml:44
+msgid "editorcp_logs_filter_by"
+msgstr "種類・アクションã«ã‚ˆã‚‹ãƒ•ã‚£ãƒ«ã‚¿"
+
+#: views/editors/logs.thtml:42 controllers/editors_controller.php:964
+msgid "editorcp_logs_page_heading"
+msgstr "イベントログ"
+
+#: views/elements/developers/editorsmenu.thtml:60
+msgid "editorcp_menu_eventlog_link"
+msgstr "イベント履歴"
+
+#: views/elements/developers/editorsmenu.thtml:62
+msgid "editorcp_menu_mainpage_link"
+msgstr "メインページã¸æˆ»ã‚‹"
+
+#: views/elements/developers/editorsmenu.thtml:61
+msgid "editorcp_menu_reviewlog_link"
+msgstr "レビュー履歴"
+
+#: views/elements/developers/editorsmenu.thtml:55
+msgid "editorcp_menu_summary_link"
+msgstr "エディタã«ã¤ã„ã¦"
+
+#: views/elements/developers/editorsmenu.thtml:52
+msgid "editorcp_menu_title"
+msgstr "エディタ用ツール"
+
+#: views/editors/reviewlog.thtml:49
+msgid "editorcp_reviewlog_button_filter"
+msgstr "フィルタ"
+
+#: views/editors/reviewlog.thtml:58
+msgid "editorcp_reviewlog_column_action"
+msgstr "アクション"
+
+#: views/editors/reviewlog.thtml:56
+msgid "editorcp_reviewlog_column_addon"
+msgstr "アドオン"
+
+#: views/editors/reviewlog.thtml:55
+msgid "editorcp_reviewlog_column_date"
+msgstr "日付"
+
+#: views/editors/reviewlog.thtml:57
+msgid "editorcp_reviewlog_column_editor"
+msgstr "エディタ"
+
+#: views/editors/reviewlog.thtml:94
+msgid "editorcp_reviewlog_comments_hide"
+msgstr "コメントを隠ã™"
+
+#: views/editors/reviewlog.thtml:93
+msgid "editorcp_reviewlog_comments_show"
+msgstr "コメントを表示"
+
+#. %1$s and %2$s are full <input> tags for dates
+#: views/editors/reviewlog.thtml:45
+#, php-format
+msgid "editorcp_reviewlog_entries_between"
+msgstr "%s ã‹ã‚‰ %s ã¾ã§ã®ã‚¨ãƒ³ãƒˆãƒªãƒ¼ã‚’表示"
+
+#: views/editors/reviewlog.thtml:104
+msgid "editorcp_reviewlog_none_found"
+msgstr "ã“ã®æœŸé–“ã«ãƒ¬ãƒ“ューãŒè¡Œã‚ã‚ŒãŸã‚¢ãƒ‰ã‚ªãƒ³ã¯ã‚ã‚Šã¾ã›ã‚“。"
+
+#: views/editors/reviewlog.thtml:42
+msgid "editorcp_reviewlog_page_heading"
+msgstr "レビュー履歴"
+
+#: views/editors/summary.thtml:61
+msgid "editorcp_summary_monthreviews_heading"
+msgstr "月ã”ã¨ã®ãƒ¬ãƒ“ュー"
+
+#: views/editors/summary.thtml:77
+msgid "editorcp_summary_neweditors_heading"
+msgstr "æ–°ã—ã„エディタ"
+
+#: views/editors/summary.thtml:42
+msgid "editorcp_summary_page_heading"
+msgstr "エディタã«ã¤ã„ã¦"
+
+#: views/editors/summary.thtml:94
+msgid "editorcp_summary_recentactivity_heading"
+msgstr "最近ã®ã‚¨ãƒ‡ã‚£ã‚¿ã®æ´»å‹•"
+
+#: views/editors/summary.thtml:45
+msgid "editorcp_summary_totalreviews_heading"
+msgstr "レビューã®åˆè¨ˆ"
+
+#: controllers/editors_controller.php:248
+#: controllers/editors_controller.php:249
+msgid "editors_addon_review_pagetitle"
+msgstr "アドオンã®ãƒ¬ãƒ“ュー"
+
+#: controllers/editors_controller.php:349
+msgid "editors_error_js-formerror"
+msgstr "以下ã®é …目を入力ã—ã¦ãã ã•ã„:"
+
+#: controllers/editors_controller.php:350
+msgid "editors_error_review_one_file"
+msgstr "å°‘ãªãã¨ã‚‚ã²ã¨ã¤ã¯ãƒ¬ãƒ“ューを行ã†ãƒ•ã‚¡ã‚¤ãƒ«ã‚’é¸æŠžã—ã¦ãã ã•ã„。"
+
+#: controllers/editors_controller.php:274
+msgid "editors_error_self_reviews_forbidden"
+msgstr "作者自身ã«ã‚ˆã‚‹ãƒ¬ãƒ“ューã¯è¨±å¯ã•ã‚Œã¦ã„ã¾ã›ã‚“。"
+
+#: controllers/editors_controller.php:699
+msgid "editors_external_software"
+msgstr "外部アプリケーション"
+
+#: views/editors/featured.thtml:120 views/editors/featured.thtml:121
+msgid "editors_featured_add_feature"
+msgstr "注目ã®ã‚¢ãƒ‰ã‚ªãƒ³ã‚’追加"
+
+#: views/editors/featured.thtml:126
+msgid "editors_featured_add_feature_submit"
+msgstr "追加"
+
+#: views/editors/featured.thtml:49 controllers/editors_controller.php:832
+#: controllers/editors_controller.php:848
+msgid "editors_featured_addon_add_failure"
+msgstr "注目ã®ã‚¢ãƒ‰ã‚ªãƒ³ã‚’追加ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚"
+
+#: controllers/editors_controller.php:851
+msgid "editors_featured_addon_add_success"
+msgstr "注目ã®ã‚¢ãƒ‰ã‚ªãƒ³ã®è¿½åŠ ãŒå®Œäº†ã—ã¾ã—ãŸã€‚"
+
+#: views/editors/featured.thtml:50 controllers/editors_controller.php:839
+#: controllers/editors_controller.php:868
+#: controllers/editors_controller.php:886
+msgid "editors_featured_addon_edit_failure"
+msgstr "注目ã®ã‚¢ãƒ‰ã‚ªãƒ³ã‚’編集ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚"
+
+#: views/editors/featured.thtml:51 controllers/editors_controller.php:888
+msgid "editors_featured_addon_edit_success"
+msgstr "注目ã®ã‚¢ãƒ‰ã‚ªãƒ³ã®ç·¨é›†ãŒå®Œäº†ã—ã¾ã—ãŸã€‚"
+
+#: views/editors/featured.thtml:53 controllers/editors_controller.php:861
+msgid "editors_featured_addon_invalid_locale"
+msgstr "1 ã¤ã¾ãŸã¯è¤‡æ•°ã®ãƒ­ã‚±ãƒ¼ãƒ«ãŒä¸æ­£ã§ã™ã€‚"
+
+#: views/editors/featured.thtml:52 controllers/editors_controller.php:906
+msgid "editors_featured_addon_remove_failure"
+msgstr "注目ã®ã‚¢ãƒ‰ã‚ªãƒ³ã‚’削除ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚"
+
+#: controllers/editors_controller.php:901
+msgid "editors_featured_addon_remove_success"
+msgstr "注目ã®ã‚¢ãƒ‰ã‚ªãƒ³ã®å‰Šé™¤ãŒå®Œäº†ã—ã¾ã—ãŸã€‚"
+
+#: controllers/editors_controller.php:915
+#: controllers/editors_controller.php:917
+msgid "editors_featured_addons_pagetitle"
+msgstr "注目ã®ã‚¢ãƒ‰ã‚ªãƒ³"
+
+#: views/editors/featured.thtml:54 views/editors/featured.thtml:107
+msgid "editors_featured_edit_feature_submit"
+msgstr "実行"
+
+#: views/editors/featured.thtml:90 views/editors/featured.thtml:91
+msgid "editors_featured_remove_feature"
+msgstr "注目ã®ã‚¢ãƒ‰ã‚ªãƒ³ã‚’削除"
+
+#: views/editors/queue.thtml:46
+msgid "editors_filter_queue"
+msgstr "レビュー待ã¡ã‚’æ¡ä»¶ã§çµžã‚Šè¾¼ã¿"
+
+#: views/editors/queue.thtml:182
+msgid "editors_helpful_links"
+msgstr "å‚考リンク"
+
+#: views/editors/queue.thtml:182
+msgid "editors_link_guide"
+msgstr "エディタå‘ã‘ガイド"
+
+#: views/editors/queue.thtml:182
+msgid "editors_link_policy"
+msgstr "アドオンãƒãƒªã‚·ãƒ¼"
+
+#: views/editors/queue.thtml:47
+msgid "editors_notice_filter_session"
+msgstr ""
+"ã“れらã®ãƒ•ã‚£ãƒ«ã‚¿ã¯ã€ç¾åœ¨ã®ã‚»ãƒƒã‚·ãƒ§ãƒ³ä¸­ã¾ãŸã¯ã‚¯ãƒªã‚¢ã‚’é¸æŠžã™ã‚‹ã¾ã§é©ç”¨ã•ã‚Œã¾"
+"ã™ã€‚"
+
+#. %1 is the queue mode
+#: views/editors/queue.thtml:177 views/admin/flagged_queue.thtml:89
+msgid "editors_notice_none_found"
+msgstr "ç¾åœ¨ãƒ¬ãƒ“ュー待ã¡ã® %s アドオンã¯ã‚ã‚Šã¾ã›ã‚“。"
+
+#: controllers/editors_controller.php:1040
+msgid "editors_one_day"
+msgstr "1 æ—¥"
+
+#: controllers/editors_controller.php:1048
+msgid "editors_one_hour"
+msgstr "1 時間"
+
+#: controllers/editors_controller.php:1056
+msgid "editors_one_minute"
+msgstr "1 分"
+
+#: controllers/editors_controller.php:64 controllers/editors_controller.php:73
+#: controllers/editors_controller.php:77
+msgid "editors_pagetitle"
+msgstr "エディタ用コントロールパãƒãƒ«"
+
+#. %s is a comma separated list of platforms. Example: Windows, OS X
+#: controllers/editors_controller.php:680
+#: controllers/editors_controller.php:683
+#, php-format
+msgid "editors_platform_x_only"
+msgstr "%s 専用"
+
+#: controllers/editors_controller.php:695
+msgid "editors_pre-release"
+msgstr "æ­£å¼ãƒªãƒªãƒ¼ã‚¹å‰ã®ã‚¢ãƒ‰ã‚ªãƒ³"
+
+#. %1 is the app name
+#: views/editors/queue.thtml:131
+#, php-format
+msgid "editors_queue_app_compatibility"
+msgstr "%s ã¨ã®äº’æ›æ€§"
+
+#: views/editors/queue.thtml:51
+msgid "editors_queue_filter_label_addon"
+msgstr "アドオンもã—ãã¯ä½œè€…ã®ãƒ¡ãƒ¼ãƒ«ã‚¢ãƒ‰ãƒ¬ã‚¹"
+
+#: views/editors/queue.thtml:72
+msgid "editors_queue_filter_label_addontypes"
+msgstr "アドオンã®ç¨®é¡ž"
+
+#: views/editors/queue.thtml:56
+msgid "editors_queue_filter_label_application"
+msgstr "アプリケーション"
+
+#: views/editors/queue.thtml:61
+msgid "editors_queue_filter_label_maxversion"
+msgstr "最大ãƒãƒ¼ã‚¸ãƒ§ãƒ³"
+
+#: views/editors/queue.thtml:78
+msgid "editors_queue_filter_label_platforms"
+msgstr "プラットフォーム"
+
+#: views/editors/queue.thtml:66
+msgid "editors_queue_filter_label_submissionage"
+msgstr "登録ã‹ã‚‰ã®æœŸé–“ (日数)"
+
+#. %1$s is a number
+#: views/editors/queue.thtml:90
+msgid "editors_queue_filter_result_count"
+msgid_plural "editors_queue_filter_result_count"
+msgstr[0] "絞り込ã¿æ¤œç´¢ã®çµæžœ: <strong>%1$s</strong> 個ã®ã‚¢ãƒ‰ã‚ªãƒ³"
+msgstr[1] "絞り込ã¿æ¤œç´¢ã®çµæžœ: <strong>%1$s</strong> 個ã®ã‚¢ãƒ‰ã‚ªãƒ³"
+
+#: views/editors/queue.thtml:84
+msgid "editors_queue_submit_clean"
+msgstr "クリア"
+
+#: views/editors/queue.thtml:83
+msgid "editors_queue_submit_filter"
+msgstr "フィルタ"
+
+#: controllers/editors_controller.php:133
+msgid "editors_queues_disabled"
+msgstr "ç¾åœ¨ãƒ¬ãƒ“ュー待ã¡ã¯ä¸­æ­¢ã•ã‚Œã¦ã„ã¾ã™ã€‚後日ã¾ãŸãƒã‚§ãƒƒã‚¯ã—ã¦ãã ã•ã„。"
+
+#: views/editors/review.thtml:149
+msgid "editors_review_a_edit_item"
+msgstr "アイテムを編集"
+
+#: views/editors/review.thtml:146
+msgid "editors_review_a_item_history"
+msgstr "アイテムã®å±¥æ­´"
+
+#: views/editors/review.thtml:148
+msgid "editors_review_a_item_homepage"
+msgstr "アイテムã®ãƒ›ãƒ¼ãƒ ãƒšãƒ¼ã‚¸"
+
+#: views/editors/review.thtml:145
+msgid "editors_review_a_item_overview"
+msgstr "アイテムã®æ¦‚è¦"
+
+#: views/editors/review.thtml:147
+msgid "editors_review_a_previews"
+msgstr "プレビュー"
+
+#: controllers/editors_controller.php:345
+msgid "editors_review_action"
+msgstr "レビューアクション"
+
+#: views/editors/review.thtml:159
+msgid "editors_review_action_info"
+msgstr "より詳ã—ã„情報を求ã‚ã‚‹"
+
+#: views/editors/review.thtml:157
+msgid "editors_review_action_public"
+msgstr "公開ページã«æŽ²è¼‰"
+
+#: views/editors/review.thtml:160
+msgid "editors_review_action_request_superreview"
+msgstr "スーパーレビューを申請"
+
+#: views/editors/review.thtml:158
+msgid "editors_review_action_sandbox"
+msgstr "サンドボックスã«ä¿ç•™"
+
+#: controllers/editors_controller.php:346
+msgid "editors_review_comments"
+msgstr "レビュー担当者ã®ã‚³ãƒ¡ãƒ³ãƒˆ"
+
+#: views/editors/review.thtml:182
+msgid "editors_review_details_info_request"
+msgstr ""
+"作者ã«ã‚ˆã‚Šè©³ã—ã„情報を求ã‚ã‚‹ã«ã¯ã“ã®ãƒ•ã‚©ãƒ¼ãƒ ã‚’使用ã—ã¦ãã ã•ã„。作者ã«ã¯ãƒ¡ãƒ¼"
+"ルãŒé€ã‚‰ã‚Œã€ã“ã“ã§å›žç­”ã‚’è¡Œãˆã‚‹ã‚ˆã†ã«ãªã‚Šã¾ã™ã€‚返信ãŒã‚ã£ãŸã¨ãã¯ã€ã‚ãªãŸã«ã‚‚"
+"メールã«ã‚ˆã‚‹é€šçŸ¥ãŒé€ã‚‰ã‚Œã¾ã™ã€‚"
+
+#: views/editors/review.thtml:174
+msgid "editors_review_details_nominated_public"
+msgstr ""
+"アドオンã¨ã€ãã®æœ€æ–°ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã€æœ€æ–°ãƒ•ã‚¡ã‚¤ãƒ«ã®å…¬é–‹ã‚’承èªã—ã¾ã™ã€‚今後ã®ãƒãƒ¼"
+"ジョンã¯ã€ã‚¨ãƒ‡ã‚£ã‚¿ã«ã‚ˆã‚‹ãƒ¬ãƒ“ューをå—ã‘ã‚‹ã¾ã§ã€ã‚µãƒ³ãƒ‰ãƒœãƒƒã‚¯ã‚¹ã«ç½®ã‹ã‚Œã¾ã™ã€‚"
+
+#: views/editors/review.thtml:177
+msgid "editors_review_details_nominated_sandbox"
+msgstr "アドオンをサンドボックスã«ä¿ç•™ã—ã¾ã™ã€‚"
+
+#: views/editors/review.thtml:166
+msgid "editors_review_details_pending_public"
+msgstr ""
+"公開済ã¿ã‚¢ãƒ‰ã‚ªãƒ³ã®ã‚µãƒ³ãƒ‰ãƒœãƒƒã‚¯ã‚¹ã«ã‚ã‚‹ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã‚’公開ページã«æŽ²è¼‰ã—ã¾ã™ã€‚"
+
+#: views/editors/review.thtml:169
+msgid "editors_review_details_pending_sandbox"
+msgstr "公開済ã¿ã‚¢ãƒ‰ã‚ªãƒ³ã®ã‚µãƒ³ãƒ‰ãƒœãƒƒã‚¯ã‚¹ã«ã‚ã‚‹ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã‚’ãã®ã¾ã¾ä¿ç•™ã—ã¾ã™ã€‚"
+
+#: views/editors/review.thtml:185
+msgid "editors_review_details_superreview"
+msgstr ""
+"アドオンã®ã‚»ã‚­ãƒ¥ãƒªãƒ†ã‚£ã‚„著作権ãªã©ã«ã¤ã„ã¦ã€ç®¡ç†è€…ã«ã‚ˆã‚‹èª¿æŸ»ã‚’å¿…è¦ã¨ã™ã‚‹ã‚ˆã†"
+"ãªæ‡¸å¿µãŒã‚ã‚‹å ´åˆã¯ã€ä¸‹ã®æ¬„ã«ã‚³ãƒ¡ãƒ³ãƒˆã‚’入力ã—ã¦ãã ã•ã„。ã“ã®å†…容ã¯ã€ä½œè€…ã§ã¯"
+"ãªã管ç†è€…ã«é€ã‚‰ã‚Œã¾ã™ã€‚"
+
+#: views/editors/review.thtml:134
+msgid "editors_review_file_diff_link"
+msgstr "公開ã•ã‚Œã¦ã„ã‚‹ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã¨æ¯”較"
+
+#: views/editors/review.thtml:131
+msgid "editors_review_file_viewcontents_link"
+msgstr "コメントを表示"
+
+#: views/editors/review.thtml:65
+msgid "editors_review_header_authors"
+msgstr "作者:"
+
+#: views/editors/review.thtml:79
+msgid "editors_review_header_categories"
+msgstr "カテゴリ:"
+
+#: views/editors/review.thtml:92
+msgid "editors_review_header_compatibility"
+msgstr "互æ›æ€§:"
+
+#: views/editors/review.thtml:251
+msgid "editors_review_header_description"
+msgstr "説明"
+
+#: views/editors/review.thtml:275
+msgid "editors_review_header_devcomments"
+msgstr "作者ã®ã‚³ãƒ¡ãƒ³ãƒˆ"
+
+#: views/editors/review.thtml:263
+msgid "editors_review_header_eula"
+msgstr "EULA"
+
+#: views/editors/review.thtml:115
+msgid "editors_review_header_files"
+msgstr "ファイル:"
+
+#: views/editors/review.thtml:284
+msgid "editors_review_header_itemhistory"
+msgstr "履歴"
+
+#: views/editors/review.thtml:232
+msgid "editors_review_header_nominationmessage"
+msgstr "公開申請メッセージ"
+
+#: views/editors/review.thtml:311
+msgid "editors_review_header_previews"
+msgstr "プレビュー画åƒ"
+
+#: views/editors/review.thtml:269
+msgid "editors_review_header_privacy"
+msgstr "プライãƒã‚·ãƒ¼ãƒãƒªã‚·ãƒ¼"
+
+#. %1 is the add-on name and version
+#: views/editors/review.thtml:56
+#, php-format
+msgid "editors_review_header_review"
+msgstr "%s をレビュー"
+
+#: views/editors/review.thtml:239
+msgid "editors_review_header_reviewernotes"
+msgstr "レビュー担当者ã¸ã®æ³¨æ„"
+
+#: views/editors/review.thtml:245
+msgid "editors_review_header_summary"
+msgstr "概è¦"
+
+#: views/editors/review.thtml:257
+msgid "editors_review_header_versionnotes"
+msgstr "ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã®èª¬æ˜Ž"
+
+#. a noun: shown in an add-on's editor review history
+#: views/elements/developers/editors_review_history_item.thtml:80
+msgid "editors_review_history_info_reply"
+msgstr "返信"
+
+#: views/elements/developers/editors_review_history_item.thtml:78
+msgid "editors_review_history_info_request"
+msgstr "情報ã®ãƒªã‚¯ã‚¨ã‚¹ãƒˆ"
+
+#: views/elements/developers/editors_review_history_item.thtml:62
+#: views/editors/reviewlog.thtml:77
+msgid "editors_review_history_nominated_adminreview"
+msgstr "管ç†è€…レビュー"
+
+#: views/elements/developers/editors_review_history_item.thtml:56
+#: views/editors/reviewlog.thtml:71
+msgid "editors_review_history_nominated_approved"
+msgstr "ç”³è«‹ã‚’æ‰¿èª (一般ã«å…¬é–‹)"
+
+#: views/elements/developers/editors_review_history_item.thtml:59
+#: views/editors/reviewlog.thtml:74
+msgid "editors_review_history_nominated_denied"
+msgstr "申請をå´ä¸‹ (サンドボックスã«ä¿ç•™)"
+
+#: views/editors/review.thtml:303
+msgid "editors_review_history_nonefound"
+msgstr "ã“ã‚Œã¾ã§ã«ãƒ¬ãƒ“ューをå—ã‘ãŸãƒãƒ¼ã‚¸ãƒ§ãƒ³ã¯ã‚ã‚Šã¾ã›ã‚“。"
+
+#: views/elements/developers/editors_review_history_item.thtml:73
+#: views/editors/reviewlog.thtml:88
+msgid "editors_review_history_pending_adminreview"
+msgstr "管ç†è€…レビュー"
+
+#: views/elements/developers/editors_review_history_item.thtml:67
+#: views/editors/reviewlog.thtml:82
+msgid "editors_review_history_pending_approved"
+msgstr "ç”³è«‹ã‚’æ‰¿èª (一般ã«å…¬é–‹)"
+
+#: views/elements/developers/editors_review_history_item.thtml:70
+#: views/editors/reviewlog.thtml:85
+msgid "editors_review_history_pending_denied"
+msgstr "申請をå´ä¸‹ (サンドボックスã«ä¿ç•™)"
+
+#. link text in an add-on's editor review history, allowing to hide and show an information request's replies
+#. %1 is the number of replies
+#: views/elements/developers/editors_review_history_item.thtml:90
+msgid "editors_review_history_show_hide_replies"
+msgid_plural "editors_review_history_show_hide_replies"
+msgstr[0] "返信を表示・隠㙠(%1$s)"
+msgstr[1] "返信を表示・隠㙠(%1$s)"
+
+#: views/editors/review.thtml:208
+msgid "editors_review_label_applications"
+msgstr "アプリケーション:"
+
+#: views/editors/review.thtml:196
+msgid "editors_review_label_cannedresponse"
+msgstr "ã¾ãŸã¯å®šåž‹æ–‡ã‚’é¸æŠžã—ã¦ãã ã•ã„:"
+
+#: views/editors/review.thtml:190
+msgid "editors_review_label_comments"
+msgstr "コメント:"
+
+#: views/editors/review.thtml:204
+msgid "editors_review_label_operating_systems"
+msgstr "OS:"
+
+#: views/editors/review.thtml:285 views/editors/review.thtml:312
+msgid "editors_review_link_pagetop"
+msgstr "トップ"
+
+#: views/editors/review.thtml:141
+msgid "editors_review_mulitple_notice"
+msgstr ""
+"注æ„: é¸æŠžã—ãŸã™ã¹ã¦ã®ãƒ•ã‚¡ã‚¤ãƒ«ã‚’テストã—ãŸå ´åˆã¯ã€ã²ã¨ã¤ä»¥ä¸Šã®ãƒ•ã‚¡ã‚¤ãƒ«ã‚’レ"
+"ビューã—ã¦ãã ã•ã„。"
+
+#: views/editors/review.thtml:51
+msgid "editors_review_next_link"
+msgstr "次㸠&raquo;"
+
+#: views/editors/review.thtml:322
+msgid "editors_review_previews_notfound"
+msgstr "プレビュー画åƒãŒã‚ã‚Šã¾ã›ã‚“。"
+
+#: views/editors/review.thtml:50
+msgid "editors_review_previous_link"
+msgstr "&laquo; å‰ã¸"
+
+#: controllers/editors_controller.php:144
+#: controllers/editors_controller.php:146
+msgid "editors_review_queue_pagetitle"
+msgstr "レビュー待ã¡"
+
+#. %1 is the add-ons rank in the queue, %2 is the total queue length
+#: views/editors/review.thtml:47
+msgid "editors_review_rank_in_queue"
+msgstr "レビュー待ã¡ã‚¢ãƒ‰ã‚ªãƒ³: %2$s 件中 <strong>%1$s</strong> 件目"
+
+#. %1 is the add-ons rank in the queue, %2 is the total queue length. Both numbers
+#: views/editors/review.thtml:45
+msgid "editors_review_rank_in_queue_filtered"
+msgstr "レビュー待㡠%2$s 件中㮠<strong>%1$s</strong> 件目 (フィルタé©ç”¨æ¸ˆã¿)"
+
+#: views/editors/review.thtml:223
+msgid "editors_review_submit_process_action"
+msgstr "アクションを実行"
+
+#: views/editors/review.thtml:293
+msgid "editors_review_th_action"
+msgstr "アクション"
+
+#: views/editors/review.thtml:294
+msgid "editors_review_th_comments"
+msgstr "コメント"
+
+#: views/editors/review.thtml:291
+msgid "editors_review_th_date"
+msgstr "日付"
+
+#: views/editors/review.thtml:292
+msgid "editors_review_th_reviewer"
+msgstr "レビュー担当者"
+
+#: views/editors/review.thtml:290
+msgid "editors_review_th_version_file"
+msgstr "ãƒãƒ¼ã‚¸ãƒ§ãƒ³ãƒ»ãƒ•ã‚¡ã‚¤ãƒ«"
+
+#: views/editors/review.thtml:217
+msgid "editors_review_update_notify_once"
+msgstr ""
+"次回ã“ã®ã‚¢ãƒ‰ã‚ªãƒ³ãŒæ›´æ–°ã•ã‚ŒãŸã¨ãã€ãƒ¡ãƒ¼ãƒ«ã«ã‚ˆã‚‹é€šçŸ¥ã‚’å—ã‘å–ã‚‹ (ãã®å¾Œã®æ›´æ–°æ™‚"
+"ã«ã¯ãƒ¡ãƒ¼ãƒ«ã¯é€ã‚‰ã‚Œã¾ã›ã‚“)"
+
+#: controllers/editors_controller.php:298
+msgid "editors_reviewed_successfully"
+msgstr "レビューãŒå®Œäº†ã—ã¾ã—ãŸã€‚"
+
+#: views/editors/reviews_queue.thtml:106
+msgid "editors_reviews_action_delete_review"
+msgstr "レビューを削除"
+
+#: views/editors/reviews_queue.thtml:104
+msgid "editors_reviews_action_keep"
+msgstr "フラグを削除ã—ã¦ãƒ¬ãƒ“ューを残ã™"
+
+#: views/editors/reviews_queue.thtml:102
+msgid "editors_reviews_action_skip"
+msgstr "スキップ"
+
+#: views/editors/reviews_queue.thtml:100
+msgid "editors_reviews_header_action"
+msgstr "アクション"
+
+#: views/editors/reviews_queue.thtml:67
+msgid "editors_reviews_in_reply_to"
+msgstr "ã“ã®ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã¸ã®è¿”ä¿¡:"
+
+#: controllers/editors_controller.php:748
+msgid "editors_reviews_processed"
+msgstr "レビューãŒå®Œäº†ã—ã¾ã—ãŸã€‚"
+
+#: views/editors/reviews_queue.thtml:117
+msgid "editors_reviews_queue_empty"
+msgstr "担当ã—ã¦ã„るレビューã¯ã‚ã‚Šã¾ã›ã‚“。"
+
+#: views/editors/reviews_queue.thtml:111
+msgid "editors_reviews_submit_process_reviews"
+msgstr "レビュー処ç†ã‚’実行"
+
+#: controllers/editors_controller.php:691
+msgid "editors_site_specific"
+msgstr "特定ã®ã‚µã‚¤ãƒˆç”¨"
+
+#: controllers/editors_controller.php:348
+msgid "editors_tested_app"
+msgstr "テストを行ã£ãŸã‚¢ãƒ—リケーション"
+
+#: controllers/editors_controller.php:347
+msgid "editors_tested_os"
+msgstr "テストを行ã£ãŸ OS"
+
+#: views/editors/queue.thtml:151
+msgid "editors_th_additional_info"
+msgstr "備考"
+
+#: views/editors/featured.thtml:63 views/editors/queue.thtml:109
+#: views/admin/flagged_queue.thtml:53
+msgid "editors_th_addon"
+msgstr "アドオン"
+
+#: views/editors/queue.thtml:125
+msgid "editors_th_addontype"
+msgstr "種類"
+
+#: views/editors/featured.thtml:64
+msgid "editors_th_locales"
+msgstr "ロケールをé™å®šã—ã¾ã™ã‹ï¼Ÿ"
+
+#: views/editors/queue.thtml:148
+msgid "editors_th_nomination_age"
+msgstr "å¾…ã¡æ™‚é–“"
+
+#: views/editors/queue.thtml:101 views/editors/queue.thtml:117
+#: views/editors/queue.thtml:144
+msgid "editors_th_sort_ascending"
+msgstr "昇順ã§ä¸¦ã¹æ›¿ãˆ"
+
+#: views/editors/queue.thtml:105 views/editors/queue.thtml:121
+#: views/editors/queue.thtml:140
+msgid "editors_th_sort_descending"
+msgstr "é™é †ã§ä¸¦ã¹æ›¿ãˆ"
+
+#. %s is a number
+#: controllers/editors_controller.php:1036
+#, php-format
+msgid "editors_x_days"
+msgstr "%s æ—¥"
+
+#. %s is a number
+#: controllers/editors_controller.php:1044
+#, php-format
+msgid "editors_x_hours"
+msgstr "%s 時間"
+
+#. %s is a number
+#: controllers/editors_controller.php:1052
+#, php-format
+msgid "editors_x_minutes"
+msgstr "%s 分"
+
+#: views/errors/error401.thtml:50 controllers/components/simple_acl.php:81
+#: controllers/components/simple_acl.php:82
+#: controllers/components/simple_acl.php:83 controllers/components/amo.php:607
+#: controllers/components/amo.php:608 controllers/components/amo.php:609
+#: controllers/reviews_controller.php:353
+#: controllers/reviews_controller.php:485
+#: controllers/collections_controller.php:438
+#: controllers/collections_controller.php:496
+#: controllers/collections_controller.php:504
+#: controllers/collections_controller.php:971
+#: controllers/collections_controller.php:1034
+#: controllers/collections_controller.php:1077
+msgid "error_access_denied"
+msgstr "アクセスã¯æ‹’å¦ã•ã‚Œã¾ã—ãŸ"
+
+#: views/errors/error401.thtml:52
+msgid "error_access_denied_message"
+msgstr "ã“ã®ãƒšãƒ¼ã‚¸ã‚’表示ã™ã‚‹æ¨©é™ãŒã‚ã‚Šã¾ã›ã‚“。"
+
+#: controllers/collections_controller.php:1039
+msgid "error_addon_exists"
+msgstr "アドオンã¯æ—¢ã«å­˜åœ¨ã—ã¾ã™ï¼"
+
+#: controllers/developers_controller.php:200
+#: controllers/developers_controller.php:593
+#: controllers/developers_controller.php:1016
+#: controllers/developers_controller.php:1429
+#: controllers/downloads_controller.php:95
+#: controllers/downloads_controller.php:102
+#: controllers/downloads_controller.php:164
+#: controllers/statistics_controller.php:135
+#: controllers/previews_controller.php:115
+#: controllers/previews_controller.php:206
+#: controllers/previews_controller.php:307
+#: controllers/reviews_controller.php:77
+#: controllers/reviews_controller.php:240
+#: controllers/reviews_controller.php:332
+#: controllers/reviews_controller.php:340 controllers/api_controller.php:123
+#: controllers/api_controller.php:759 controllers/addons_controller.php:131
+#: controllers/addons_controller.php:197
+#: controllers/addons_controller.php:1407
+#: controllers/addons_controller.php:1465
+#: controllers/addons_controller.php:1469
+#: controllers/addons_controller.php:1503
+#: controllers/editors_controller.php:265
+#: controllers/collections_controller.php:1041
+#: controllers/collections_controller.php:1074
+msgid "error_addon_notfound"
+msgstr "該当ã™ã‚‹ã‚¢ãƒ‰ã‚ªãƒ³ã¯ã‚ã‚Šã¾ã›ã‚“。"
+
+#: controllers/files_controller.php:83 controllers/files_controller.php:196
+msgid "error_addon_notviewable"
+msgstr "ã“ã®ã‚¢ãƒ‰ã‚ªãƒ³ã¯ç¾åœ¨è¡¨ç¤ºã§ãã¾ã›ã‚“。"
+
+#: controllers/reviews_controller.php:246
+msgid "error_addon_selfreview"
+msgstr "自分ã®ã‚¢ãƒ‰ã‚ªãƒ³ã‚’レビューã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“。"
+
+#: controllers/addons_controller.php:970
+msgid "error_browse_no_addons"
+msgstr "ã“ã®ã‚«ãƒ†ã‚´ãƒªã«ã¯ã¾ã ã‚¢ãƒ‰ã‚ªãƒ³ãŒç™»éŒ²ã•ã‚Œã¦ã„ã¾ã›ã‚“。"
+
+#: controllers/api_controller.php:424
+msgid "error_collection_feed_notfound"
+msgstr "アドオンã®ãƒ•ã‚£ãƒ¼ãƒ‰ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ã§ã—ãŸã€‚"
+
+#: views/users/register.thtml:65 views/users/edit.thtml:194
+msgid "error_email_invalid"
+msgstr "メールアドレスã®å½¢å¼ãŒæ­£ã—ãã‚ã‚Šã¾ã›ã‚“。"
+
+#: views/users/pwreset.thtml:74 views/users/register.thtml:70
+#: views/users/register.thtml:80 views/users/register.thtml:86
+#: views/users/edit.thtml:105 views/users/edit.thtml:111
+#: views/users/edit.thtml:192 views/admin/users_edit.thtml:78
+#: views/admin/users_edit.thtml:83 views/reviews/add.thtml:80
+#: views/reviews/add.thtml:104
+msgid "error_field_required"
+msgstr "ã“ã®é …ç›®ã¯å¿…é ˆã§ã™ã€‚"
+
+#: controllers/files_controller.php:75 controllers/files_controller.php:93
+#: controllers/files_controller.php:96 controllers/files_controller.php:163
+#: controllers/files_controller.php:176 controllers/files_controller.php:185
+#: controllers/files_controller.php:204 controllers/editors_controller.php:412
+msgid "error_file_notfound"
+msgstr "ファイルãŒã‚ã‚Šã¾ã›ã‚“。"
+
+#. %s is a filename
+#: controllers/editors_controller.php:430
+#, php-format
+msgid "error_file_x_notfound"
+msgstr "ファイルエラー: %s ãŒå­˜åœ¨ã—ã¾ã›ã‚“。"
+
+#: views/collections/add.thtml:55 views/collections/edit.thtml:89
+#: views/users/register.thtml:54 views/users/edit.thtml:81
+#: views/reviews/add.thtml:70 controllers/groups_controller.php:80
+#: controllers/groups_controller.php:102
+msgid "error_formerrors"
+msgstr "入力内容ã«ã‚¨ãƒ©ãƒ¼ãŒã‚ã‚Šã¾ã™ã€‚確èªã®ä¸Šã€å†åº¦é€ä¿¡ã—ã¦ãã ã•ã„。"
+
+#: views/users/register.thtml:109
+msgid "error_invalid_captcha"
+msgstr "ä¸æ­£ãª captcha ã§ã™ã€‚ã‚‚ã†ä¸€åº¦å…¥åŠ›ã—ã¦ãã ã•ã„。"
+
+#: views/users/register.thtml:100 views/users/edit.thtml:125
+#: views/admin/users_edit.thtml:101
+msgid "error_invalid_url"
+msgstr ""
+"ã“ã® URL ã¯ä¸æ­£ãªå½¢å¼ã§ã™ã€‚有効㪠URL 㯠http://example.com/my_page ã®ã‚ˆã†ãª"
+"å½¢å¼ã§ã™ã€‚"
+
+#. %s is a string representing what's missing. Example: file_id
+#: controllers/downloads_controller.php:65
+#: controllers/users_controller.php:185 controllers/users_controller.php:264
+#: controllers/users_controller.php:559 controllers/users_controller.php:653
+#: controllers/reviews_controller.php:71
+#: controllers/reviews_controller.php:234
+#: controllers/reviews_controller.php:325
+#: controllers/reviews_controller.php:473
+#: controllers/reviews_controller.php:475
+#: controllers/addons_controller.php:182
+#: controllers/addons_controller.php:1381
+#: controllers/addons_controller.php:1455
+#: controllers/collections_controller.php:266
+#: controllers/collections_controller.php:285
+#: controllers/collections_controller.php:346
+#: controllers/collections_controller.php:443
+#: controllers/collections_controller.php:482
+#: controllers/collections_controller.php:936
+#: controllers/collections_controller.php:959
+#: controllers/collections_controller.php:960
+#: controllers/collections_controller.php:975
+#: controllers/collections_controller.php:977
+#: controllers/collections_controller.php:994
+#: controllers/collections_controller.php:1003
+#: controllers/collections_controller.php:1016
+#: controllers/collections_controller.php:1017
+#: controllers/collections_controller.php:1024
+#: controllers/collections_controller.php:1070
+#: controllers/collections_controller.php:1090
+#, php-format
+msgid "error_missing_argument"
+msgstr "引数ãŒä¸è¶³ã—ã¦ã„ã¾ã™: %s"
+
+#: controllers/components/amo.php:507 controllers/components/amo.php:532
+msgid "error_no_files_in_addon"
+msgstr "ファイルãŒã‚ã‚Šã¾ã›ã‚“"
+
+#: controllers/previews_controller.php:200
+msgid "error_preview_notfound"
+msgstr "プレビュー画åƒãŒã‚ã‚Šã¾ã›ã‚“。"
+
+#: views/addons/display.thtml:400 views/reviews/add.thtml:98
+msgid "error_review_rating_required"
+msgstr "評価をé¸æŠžã—ã¦ãã ã•ã„。"
+
+#: controllers/users_controller.php:160
+msgid "error_user_already_confirmed"
+msgstr "ã“ã®ãƒ¦ãƒ¼ã‚¶ã‚¢ã‚«ã‚¦ãƒ³ãƒˆã®ç¢ºèªã¯å®Œäº†ã—ã¦ã„ã¾ã™ã€‚"
+
+#: controllers/users_controller.php:202 controllers/users_controller.php:276
+#: controllers/users_controller.php:569 controllers/users_controller.php:581
+#: controllers/users_controller.php:587 controllers/users_controller.php:610
+#: controllers/users_controller.php:627
+msgid "error_user_badconfirmationcode"
+msgstr "ä¸æ­£ãªç¢ºèªã‚³ãƒ¼ãƒ‰ã§ã™ã€‚"
+
+#: views/users/pwreset.thtml:79 views/users/register.thtml:75
+#: views/users/edit.thtml:183
+msgid "error_user_confirmpw_nomatch"
+msgstr "パスワードãŒä¸€è‡´ã—ã¾ã›ã‚“。"
+
+#: views/users/register.thtml:65 views/users/edit.thtml:190
+#: controllers/users_controller.php:617
+msgid "error_user_email_notunique"
+msgstr "ã“ã®ãƒ¡ãƒ¼ãƒ«ã‚¢ãƒ‰ãƒ¬ã‚¹ã¯æ—¢ã«ä»–ã®ãƒ¦ãƒ¼ã‚¶ã«ä½¿ã‚ã‚Œã¦ã„ã¾ã™ã€‚"
+
+#: controllers/users_controller.php:596
+msgid "error_user_emailchange_expired"
+msgstr ""
+"メールアドレスã®å¤‰æ›´ã¯æ™‚間切れã¨ãªã‚Šã¾ã—ãŸã€‚ユーザプロフィールã‹ã‚‰å†åº¦ã‚¢ãƒ‰ãƒ¬"
+"スを変更ã—ã¦ã€ç¢ºèªã®ãƒ¡ãƒ¼ãƒ«ãŒå±Šã„ãŸã‚‰ã™ãã«ã€æœ¬æ–‡ä¸­ã®ãƒªãƒ³ã‚¯ã‚’クリックã—ã¦ãã "
+"ã•ã„。"
+
+#: controllers/collections_controller.php:985
+msgid "error_user_exists"
+msgstr ""
+"ユーザã«å‰²ã‚Šå½“ã¦ã‚‰ã‚Œã‚‹ãƒ­ãƒ¼ãƒ«ã¯ä¸€åº¦ã«ã²ã¨ã¤ã ã‘ã§ã™ã€‚続ã‘ã‚‹å‰ã«ã€æ—¢å­˜ã®ãƒ­ãƒ¼ãƒ«"
+"ã‹ã‚‰ãƒ¦ãƒ¼ã‚¶ã‚’削除ã—ã¦ãã ã•ã„。"
+
+#: views/users/register.thtml:91 views/users/edit.thtml:116
+#: views/admin/users_edit.thtml:88
+msgid "error_user_nickname_notunique"
+msgstr "ã“ã®ãƒ‹ãƒƒã‚¯ãƒãƒ¼ãƒ ã¯æ—¢ã«ä»–ã®ãƒ¦ãƒ¼ã‚¶ã«ä½¿ã‚ã‚Œã¦ã„ã¾ã™ã€‚"
+
+#: views/users/pwreset.thtml:54 controllers/users_controller.php:191
+#: controllers/users_controller.php:270 controllers/users_controller.php:603
+#: controllers/users_controller.php:659
+#: controllers/collections_controller.php:988
+#: controllers/collections_controller.php:998
+msgid "error_user_notfound"
+msgstr "該当ã™ã‚‹ãƒ¦ãƒ¼ã‚¶ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“。"
+
+#: views/users/activatefirst.thtml:47
+msgid "error_user_unconfirmed"
+msgstr "åˆã‚ã«ã€ãƒ¡ãƒ¼ãƒ«ã§å—ã‘å–ã£ãŸã‚³ãƒ¼ãƒ‰ã§ã‚¢ã‚«ã‚¦ãƒ³ãƒˆã®èªè¨¼ã‚’è¡Œã£ã¦ãã ã•ã„。"
+
+#: views/users/login.thtml:67
+msgid "error_username_or_pw_wrong"
+msgstr "ユーザåã¾ãŸã¯ãƒ‘スワードãŒæ­£ã—ãã‚ã‚Šã¾ã›ã‚“。"
+
+#: controllers/editors_controller.php:260
+msgid "error_version_notfound"
+msgstr "ãƒãƒ¼ã‚¸ãƒ§ãƒ³ãŒã‚ã‚Šã¾ã›ã‚“。"
+
+#: views/users/delete.thtml:125 views/users/edit.thtml:173
+msgid "error_wrong_password"
+msgstr "入力ã•ã‚ŒãŸãƒ‘スワードãŒæ­£ã—ãã‚ã‚Šã¾ã›ã‚“。"
+
+#: views/elements/amo2009/homepage_addon.thtml:122
+#: views/elements/feature.thtml:122
+msgid "feature_learnmore"
+msgstr "詳細"
+
+#. %1 is the add-on name
+#: views/elements/amo2009/homepage_addon.thtml:123
+#: views/elements/feature.thtml:123
+#, php-format
+msgid "feature_learnmore_about_addon"
+msgstr "%1$s ã®è©³ç´°"
+
+#. %1$s is a number
+#: views/elements/amo2009/reviews.thtml:52
+#: views/elements/addon_listitem.thtml:112 views/elements/feature.thtml:99
+#: views/addons/browse_thumbs.thtml:86
+#, php-format
+msgid "feature_reviews"
+msgid_plural "feature_reviews"
+msgstr[0] "レビュー (%1$s)"
+msgstr[1] "レビュー (%1$s)"
+
+#: views/elements/amo2009/homepage_addon.thtml:127
+#: views/elements/feature.thtml:127
+msgid "feature_view_more_from_category"
+msgstr "åŒã˜ã‚«ãƒ†ã‚´ãƒªã®ä»–ã®ã‚¢ãƒ‰ã‚ªãƒ³ã‚’見る:"
+
+#. This appears on a page that views the source of an add-on. This link will return
+#. the user to the add-on's main page
+#: views/files/browse.thtml:65
+msgid "file_browser_link_addon"
+msgstr "アドオンã®è©³ç´°ã¸æˆ»ã‚‹"
+
+#. There is a list of directories and files on the page. Clicking this will show the
+#. contents of all the directories (normally you would click on each one to see the
+#. contents)
+#: views/files/browse.thtml:67
+msgid "file_browser_link_expand_all"
+msgstr "ã™ã¹ã¦å±•é–‹"
+
+#. This appears on a page that views the source of an add-on. This link will return
+#. the user to the add-on's review page (it only appears if the add-on is being
+#. reviewed)
+#: views/files/browse.thtml:64
+msgid "file_browser_link_review"
+msgstr "レビューã¸æˆ»ã‚‹"
+
+#. The title of the page for viewing an add-on's source.
+#. %1$s is the name of the add-on
+#. %2$s is the name of the current application (e.g. Firefox or Thunderbird)
+#: views/files/browse.thtml:46
+msgid "file_browser_title"
+msgstr "%1$s :: ファイルブラウザ :: %2$s Add-ons"
+
+#. This appears on a page that views the source of an add-on. There is a list of
+#. directories and files on the page. Clicking this link will toggle between an
+#. expanded or a collapsed list. This string should be kept short.
+#: views/files/browse.thtml:68
+msgid "file_browser_toggle_expand_collapse"
+msgstr "+/-"
+
+#. Link text for the AMO About page.
+#: views/elements/footer.thtml:72 views/layouts/amo2009.thtml:341
+msgid "footer_a_about"
+msgstr "ã“ã®ã‚µã‚¤ãƒˆã«ã¤ã„ã¦"
+
+#. Link text to the AMO blog.
+#: views/elements/footer.thtml:74 views/layouts/amo2009.thtml:343
+msgid "footer_a_blog"
+msgstr "ブログ"
+
+#. Link text to the Frequently Asked Questions page.
+#: views/elements/footer.thtml:73 views/layouts/amo2009.thtml:342
+msgid "footer_a_faq"
+msgstr "FAQ"
+
+#. Full text for the FAQ abbreviation.
+#: views/elements/footer.thtml:73 views/pages/collector_features.thtml:72
+#: views/layouts/amo2009.thtml:342
+msgid "footer_abbr_faq"
+msgstr "よãã‚る質å•"
+
+#: views/elements/footer.thtml:67 views/layouts/amo2009.thtml:336
+msgid "footer_all_rights_reserved"
+msgstr "All rights reserved."
+
+#: views/elements/footer.thtml:67 views/layouts/amo2009.thtml:336
+msgid "footer_copyright"
+msgstr "Copyright"
+
+#: views/elements/footer.thtml:71 views/layouts/amo2009.thtml:340
+msgid "footer_credits"
+msgstr "クレジット"
+
+#: views/elements/footer.thtml:76 views/layouts/amo2009.thtml:346
+msgid "footer_disclaimer"
+msgstr ""
+"Mozilla Add-ons ã«ç™»éŒ²ã•ã‚Œã¦ã„るアドオンã¸ã®ãƒªãƒ³ã‚¯ã¯ã€Mozilla ãŒä¾¿å®œçš„ã«æä¾›"
+"ã—ã¦ã„ã‚‹ã‚‚ã®ã§ã™ã€‚Mozilla ã¯ã€ã“れらã®ã‚¢ãƒ‰ã‚ªãƒ³ã‚„関連情報ã«ã¤ã„ã¦ä¸€åˆ‡ã®è²¬ä»»ã‚’"
+"è² ã„ã¾ã›ã‚“。アドオンã«é–¢ã™ã‚‹ã”æ„見やã”質å•ã¯ãã‚Œãžã‚Œã®ä½œè€…ã¾ã§ãŠé¡˜ã„ã„ãŸã—ã¾"
+"ã™ã€‚"
+
+#: views/elements/footer.thtml:61 views/layouts/amo2009.thtml:332
+msgid "footer_lang_form_lang_submit_go"
+msgstr "変更"
+
+#: views/elements/footer.thtml:70 views/layouts/amo2009.thtml:339
+msgid "footer_legal_notices"
+msgstr "法的通知"
+
+#: views/elements/footer.thtml:50 views/layouts/amo2009.thtml:321
+msgid "footer_other_languages"
+msgstr "ä»–ã®è¨€èªž:"
+
+#: views/elements/footer.thtml:69 views/layouts/amo2009.thtml:338
+msgid "footer_privacy_policy"
+msgstr "プライãƒã‚·ãƒ¼ãƒãƒªã‚·ãƒ¼"
+
+#: models/addontype.php:79
+msgid "general_addontype_dict"
+msgstr "スペルãƒã‚§ãƒƒã‚¯è¾žæ›¸"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:100
+msgid "general_addontype_dict_plural"
+msgstr "スペルãƒã‚§ãƒƒã‚¯è¾žæ›¸"
+
+#: models/addontype.php:75
+msgid "general_addontype_extension"
+msgstr "拡張機能"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:98
+msgid "general_addontype_extension_plural"
+msgstr "拡張機能"
+
+#: models/addontype.php:85
+msgid "general_addontype_lpaddon"
+msgstr "言語パック (アドオン)"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:103
+msgid "general_addontype_lpaddon_plural"
+msgstr "言語パック (アドオン)"
+
+#: models/addontype.php:83
+msgid "general_addontype_lpapp"
+msgstr "言語パック (アプリケーション)"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:102
+msgid "general_addontype_lpapp_plural"
+msgstr "言語パック (アプリケーション)"
+
+#: models/addontype.php:87
+msgid "general_addontype_plugin"
+msgstr "プラグイン"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:104
+msgid "general_addontype_plugin_plural"
+msgstr "プラグイン"
+
+#: models/addontype.php:81
+msgid "general_addontype_search"
+msgstr "検索エンジン"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:101
+msgid "general_addontype_search_plural"
+msgstr "検索エンジン"
+
+#: models/addontype.php:77
+msgid "general_addontype_theme"
+msgstr "テーマ"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:99
+msgid "general_addontype_theme_plural"
+msgstr "テーマ"
+
+#: config/language.php:367
+msgid "general_languages_all_locales"
+msgstr "ã™ã¹ã¦ã®ãƒ­ã‚±ãƒ¼ãƒ«"
+
+#: views/layouts/amo2009.thtml:249
+msgid "header_brand_name"
+msgstr "Mozilla"
+
+#. %1$s is the application name. Example: Firefox
+#: views/elements/header.thtml:111 views/elements/header.thtml:122
+#: views/layouts/amo2009.thtml:248
+#, php-format
+msgid "header_home_tooltip"
+msgstr "%1$s Add-ons ã®ãƒ›ãƒ¼ãƒ ãƒšãƒ¼ã‚¸ã¸æˆ»ã‚‹"
+
+#: views/elements/header.thtml:87
+msgid "header_main_firefox_header"
+msgstr "Firefox Add-ons"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:218
+msgid "header_main_firefox_header_with_logo"
+msgstr ""
+"Add-ons <em>for</em> <img alt=\"Firefox\" src=\"%1$s\" /> <strong>Firefox</"
+"strong>"
+
+#: views/elements/header.thtml:99
+msgid "header_main_header"
+msgstr "Add-ons"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:242
+msgid "header_main_header_with_logo"
+msgstr "Add-ons <img alt=\"Add-ons\" src=\"%1$s\" />"
+
+#: views/elements/header.thtml:90
+msgid "header_main_seamonkey_header"
+msgstr "Seamonkey Add-ons"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:224
+msgid "header_main_seamonkey_header_with_logo"
+msgstr ""
+"Add-ons <em>for</em> <img alt=\"seamonkey\" src=\"%1$s\" /> "
+"<strong>SeaMonkey</strong>"
+
+#: views/elements/header.thtml:93
+msgid "header_main_sunbird_header"
+msgstr "Sunbird Add-ons"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:230
+msgid "header_main_sunbird_header_with_logo"
+msgstr ""
+"Add-ons <em>for</em> <img alt=\"sunbird\" src=\"%1$s\" /> <strong>Sunbird</"
+"strong>"
+
+#: views/elements/header.thtml:96
+msgid "header_main_thunderbird_header"
+msgstr "Thunderbird Add-ons"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:236
+msgid "header_main_thunderbird_header_with_logo"
+msgstr ""
+"Add-ons <em>for</em> <img alt=\"thunderbird\" src=\"%1$s\" /> "
+"<strong>Thunderbird</strong>"
+
+#: views/layouts/amo2009.thtml:205
+msgid "header_navaccess_applications_menu"
+msgstr "ä»–ã®ã‚¢ãƒ—リケーションメニューã¸ã‚¹ã‚­ãƒƒãƒ—"
+
+#: views/layouts/amo2009.thtml:204
+msgid "header_navaccess_categories_menu"
+msgstr "カテゴリメニューã¸ã‚¹ã‚­ãƒƒãƒ—"
+
+#: views/layouts/amo2009.thtml:202
+msgid "header_navaccess_main_content"
+msgstr "メインコンテンツã¸ã‚¹ã‚­ãƒƒãƒ—"
+
+#: views/layouts/amo2009.thtml:203
+msgid "header_navaccess_search_form"
+msgstr "検索フォームã¸ã‚¹ã‚­ãƒƒãƒ—"
+
+#: views/elements/header.thtml:62
+msgid "header_navlink_addons"
+msgstr "アドオン"
+
+#: views/elements/developers/sidebar.thtml:72
+#: views/elements/developers/myaddons.thtml:50 views/elements/header.thtml:159
+#: views/addons/display.thtml:378
+msgid "header_navlink_login"
+msgstr "ログイン"
+
+#: views/elements/header.thtml:156 views/layouts/amo2009.thtml:304
+msgid "header_navlink_logout"
+msgstr "ログアウト"
+
+#: views/elements/header.thtml:145 views/layouts/amo2009.thtml:303
+msgid "header_navlink_myaccount"
+msgstr "アカウント"
+
+#: views/elements/header.thtml:158
+msgid "header_navlink_register"
+msgstr "ユーザ登録"
+
+#. %1 is the URL to the registration page
+#. %2 is the URL to the login page
+#: views/layouts/amo2009.thtml:278
+msgid "header_navlink_register_or_login"
+msgstr "<a href=\"%1$s\">ユーザ登録</a> / <a href=\"%2$s\">ログイン</a>"
+
+#: views/layouts/amo2009.thtml:285
+msgid "header_navlink_tools"
+msgstr "ツール"
+
+#. %s is the add-on name
+#: views/elements/collections_interactive_addon.thtml:62
+#: views/elements/amo2009/homepage_addon.thtml:77
+#: views/elements/addon_discussionheader.thtml:62
+#: views/elements/addon_listitem.thtml:67 views/elements/feature.thtml:84
+#: views/addons/category_landing.thtml:87 views/addons/browse_thumbs.thtml:60
+#, php-format
+msgid "img_preview_of"
+msgstr "%s ã®ãƒ—レビュー画åƒ"
+
+#. %1 is the login URL for the link tag
+#. %2 is the link to an explanatory page.
+#: views/elements/amo2009/install.thtml:307 views/elements/install.thtml:255
+msgid "install_a_login_to_install"
+msgstr ""
+"ã“ã®å®Ÿé¨“çš„ãªã‚¢ãƒ‰ã‚ªãƒ³ã‚’インストールã™ã‚‹ã«ã¯ <a href=\"%1$s\">ログイン</a> ã—ã¦"
+"ãã ã•ã„。<a href=\"%2$s\">詳細</a>"
+
+#. %1 is the URL for the Experimental Add-ons section of the FAQ page
+#: views/elements/amo2009/install.thtml:283 views/elements/install.thtml:232
+msgid "install_button_confirm_exp_install"
+msgstr ""
+"ã“ã®å®Ÿé¨“çš„ãªã‚¢ãƒ‰ã‚ªãƒ³ã‚’インストールã—ã¾ã™ã€‚<a href=\"%1$s\">ã“ã‚Œã¯ä½•ï¼Ÿ</a>"
+
+#. %1$s is the application name. Example: Firefox
+#. %2$s is an optional string used to specify a platform. Example: (Windows)
+#: views/elements/amo2009/install.thtml:128 views/elements/install.thtml:75
+#, php-format
+msgid "install_button_text"
+msgstr "%s %s ã¸ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«"
+
+#. %1 is the add-on name, %2 is the app name
+#: views/elements/amo2009/install.thtml:191
+#: views/elements/amo2009/install.thtml:206
+#: views/elements/amo2009/install.thtml:249
+#: views/elements/amo2009/install.thtml:298 views/elements/install.thtml:150
+#: views/elements/install.thtml:165 views/elements/install.thtml:202
+#: views/elements/install.thtml:246
+#, php-format
+msgid "install_button_title"
+msgstr "%1$s ã‚’ %2$s ã¸ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«"
+
+#. %1$s is the add-on name
+#: views/elements/amo2009/install.thtml:200 views/elements/install.thtml:159
+#, php-format
+msgid "install_download"
+msgstr "%1$s をダウンロード"
+
+#: views/elements/amo2009/install.thtml:147 views/elements/install.thtml:94
+msgid "install_error_addon_not_found"
+msgstr "ã“ã®ã‚¢ãƒ‰ã‚ªãƒ³ã¯åˆ©ç”¨ã§ãã¾ã›ã‚“。"
+
+#: views/addons/dictionaries.thtml:65
+msgid "langtools_a11y_tablesummary"
+msgstr "言語パックã¨ã‚¹ãƒšãƒ«ãƒã‚§ãƒƒã‚¯è¾žæ›¸ã®ä¸€è¦§ã§ã™ã€‚"
+
+#: views/addons/dictionaries.thtml:47
+msgid "langtools_download_dictionary"
+msgstr "辞書をダウンロード"
+
+#: views/addons/dictionaries.thtml:48
+msgid "langtools_download_langpack"
+msgstr "言語パックをダウンロード"
+
+#: views/addons/dictionaries.thtml:63 controllers/components/amo.php:685
+#: controllers/addons_controller.php:1239
+msgid "langtools_header_dicts_and_langpacks"
+msgstr "スペルãƒã‚§ãƒƒã‚¯è¾žæ›¸ã¨è¨€èªžãƒ‘ック"
+
+#: views/addons/dictionaries.thtml:44
+msgid "langtools_install_dictionary"
+msgstr "辞書をインストール"
+
+#: views/addons/dictionaries.thtml:45
+msgid "langtools_install_langpack"
+msgstr "言語パックをインストール"
+
+#: views/addons/dictionaries.thtml:69
+msgid "langtools_tableheader_dictionary"
+msgstr "スペルãƒã‚§ãƒƒã‚¯è¾žæ›¸"
+
+#: views/addons/dictionaries.thtml:70
+msgid "langtools_tableheader_langpack"
+msgstr "言語パック"
+
+#: views/addons/dictionaries.thtml:68
+msgid "langtools_tableheader_language"
+msgstr "言語"
+
+#: models/license.php:65
+msgid "license_custom"
+msgstr "独自ライセンス"
+
+#: config/bootstrap.php:303
+msgid "licenses_bsd"
+msgstr "BSD License"
+
+#: config/bootstrap.php:298
+msgid "licenses_gpl_2.0"
+msgstr "GNU General Public License ãƒãƒ¼ã‚¸ãƒ§ãƒ³ 2.0"
+
+#: config/bootstrap.php:299
+msgid "licenses_gpl_3.0"
+msgstr "GNU General Public License ãƒãƒ¼ã‚¸ãƒ§ãƒ³ 3.0"
+
+#: config/bootstrap.php:300
+msgid "licenses_lgpl_2.1"
+msgstr "GNU Lesser General Public License ãƒãƒ¼ã‚¸ãƒ§ãƒ³ 2.1"
+
+#: config/bootstrap.php:301
+msgid "licenses_lgpl_3.0"
+msgstr "GNU Lesser General Public License ãƒãƒ¼ã‚¸ãƒ§ãƒ³ 3.0"
+
+#: config/bootstrap.php:302
+msgid "licenses_mit"
+msgstr "MIT/X11 License"
+
+#: config/bootstrap.php:297
+msgid "licenses_mpl_1.1"
+msgstr "Mozilla Public License ãƒãƒ¼ã‚¸ãƒ§ãƒ³ 1.1"
+
+#: views/users/emailchange.thtml:51 views/users/delete.thtml:55
+#: views/users/delete.thtml:137 views/users/edit.thtml:74
+#: views/reviews/flag.thtml:54
+msgid "link_return_to_front_page"
+msgstr "トップページã«æˆ»ã‚‹ã«ã¯ã“ã“をクリックã—ã¦ãã ã•ã„。"
+
+#: views/elements/amo2009/addon_list_options.thtml:46
+#: views/elements/addon_list_options.thtml:46
+msgid "list_sortby_date"
+msgstr "æ›´æ–°æ—¥"
+
+#: views/elements/amo2009/addon_list_options.thtml:47
+#: views/elements/addon_list_options.thtml:47
+msgid "list_sortby_downloads"
+msgstr "ダウンロード数"
+
+#: views/elements/amo2009/addon_list_options.thtml:45
+#: views/elements/addon_list_options.thtml:45
+msgid "list_sortby_name"
+msgstr "タイトル"
+
+#: views/elements/amo2009/addon_list_options.thtml:48
+#: views/elements/addon_list_options.thtml:48
+msgid "list_sortby_rating"
+msgstr "評価"
+
+#: config/bootstrap.php:278
+msgid "main_prettyname_fennec"
+msgstr "Fennec"
+
+#: config/bootstrap.php:274
+msgid "main_prettyname_firefox"
+msgstr "Firefox"
+
+#: config/bootstrap.php:277
+msgid "main_prettyname_seamonkey"
+msgstr "SeaMonkey"
+
+#: config/bootstrap.php:276
+msgid "main_prettyname_sunbird"
+msgstr "Sunbird"
+
+#: config/bootstrap.php:275
+msgid "main_prettyname_thunderbird"
+msgstr "Thunderbird"
+
+#: views/elements/addon_categories.thtml:52
+msgid "nav_category_dicts_langpacks"
+msgstr "スペルãƒã‚§ãƒƒã‚¯è¾žæ›¸ã¨è¨€èªžãƒ‘ック"
+
+#: views/elements/addon_categories.thtml:55
+msgid "nav_category_themes"
+msgstr "テーマ"
+
+#: views/elements/app_chooser.thtml:47 views/layouts/amo2009.thtml:255
+msgid "other_apps_tooltip"
+msgstr "ä»–ã®ã‚¢ãƒ—リケーション用ã®ã‚¢ãƒ‰ã‚ªãƒ³ã‚’探ã™"
+
+#. In a user list: user 1, user 2, "others"
+#: views/helpers/addons_html.php:222
+msgid "other_users"
+msgstr "ãã®ä»–"
+
+#: controllers/pages_controller.php:90
+msgid "page_title_appversions"
+msgstr "アプリケーションã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³"
+
+#: controllers/pages_controller.php:115
+msgid "page_title_collector"
+msgstr "アドオンコレクター"
+
+#: controllers/pages_controller.php:117
+msgid "page_title_collector_faq"
+msgstr "アドオンコレクター㮠FAQ"
+
+#: controllers/pages_controller.php:119
+msgid "page_title_collector_features"
+msgstr "アドオンコレクターã®æ©Ÿèƒ½"
+
+#: controllers/pages_controller.php:122
+msgid "page_title_collector_firstrun"
+msgstr "アドオンコレクターã¸ã‚ˆã†ã“ã"
+
+#: controllers/pages_controller.php:92
+msgid "page_title_credits"
+msgstr "クレジット"
+
+#: controllers/pages_controller.php:113
+msgid "page_title_developer_faq"
+msgstr "開発者å‘ã‘ FAQ"
+
+#: controllers/pages_controller.php:111
+msgid "page_title_faq"
+msgstr "よãã‚る質å•"
+
+#: controllers/pages_controller.php:94
+msgid "page_title_fashionyourfirefox_faq"
+msgstr "Fashion Your Firefox ã«é–¢ã™ã‚‹ FAQ"
+
+#: controllers/pages_controller.php:101
+msgid "page_title_policy"
+msgstr "アドオンãƒãƒªã‚·ãƒ¼"
+
+#: controllers/pages_controller.php:103
+msgid "page_title_privacy"
+msgstr "Mozilla プライãƒã‚·ãƒ¼ãƒãƒªã‚·ãƒ¼"
+
+#: controllers/pages_controller.php:105
+msgid "page_title_review_guide"
+msgstr "レビューガイドライン"
+
+#: controllers/pages_controller.php:107
+msgid "page_title_sandbox"
+msgstr "サンドボックスレビューシステム"
+
+#: controllers/pages_controller.php:109
+msgid "page_title_submissionhelp"
+msgstr "申請ã«é–¢ã™ã‚‹ãƒ˜ãƒ«ãƒ—"
+
+#: views/pages/appversions.thtml:87
+msgid "pages_appversions_guid"
+msgstr "GUID"
+
+#: views/pages/appversions.thtml:79 controllers/pages_controller.php:90
+msgid "pages_appversions_header"
+msgstr "æ­£ã—ã„アプリケーションã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³"
+
+#: views/pages/appversions.thtml:80
+msgid "pages_appversions_intro"
+msgstr ""
+"Mozilla Add-ons ã«ç™»éŒ²ã™ã‚‹ã‚¢ãƒ‰ã‚ªãƒ³ã«ã¯ã€ä»¥ä¸‹ã®ã‚¢ãƒ—リケーションã®ã†ã¡å°‘ãªãã¨"
+"ã‚‚ã„ãšã‚Œã‹ã«å¯¾å¿œã•ã›ãŸ install.rdf ファイルをåŒæ¢±ã™ã‚‹å¿…è¦ãŒã‚ã‚Šã¾ã™ã€‚å„アプリ"
+"ケーションã¨ã‚‚ã€ä»¥ä¸‹ã«è¡¨è¨˜ã•ã‚ŒãŸãƒãƒ¼ã‚¸ãƒ§ãƒ³ã®ã¿æŒ‡å®šå¯èƒ½ã§ã™ã€‚"
+
+#. %s is a full <a> tag
+#: views/pages/appversions.thtml:93
+#, php-format
+msgid "pages_appversions_required_files"
+msgstr ""
+"登録ã™ã‚‹ã‚¢ãƒ‰ã‚ªãƒ³ã®å¯¾å¿œã‚¢ãƒ—リケーション㌠install.rdf ファイルを必è¦ã¨ã—ãªã„å ´"
+"åˆã§ã‚‚ã€%s ã«æ›¸ã‹ã‚Œã¦ã„る必須プロパティを指定ã—㟠install.rdf ã¯å¿…ãšåŒæ¢±ã™ã‚‹"
+"å¿…è¦ãŒã‚ã‚Šã¾ã™ã€‚"
+
+#. this is the text inside of an <a> tag for pages_appversions_required_files. This
+#. should be fixed.
+#: views/pages/appversions.thtml:93
+msgid "pages_appversions_required_files_link"
+msgstr "ã“ã¡ã‚‰ã®ãƒšãƒ¼ã‚¸"
+
+#: views/pages/appversions.thtml:88
+msgid "pages_appversions_versions"
+msgstr "ãƒãƒ¼ã‚¸ãƒ§ãƒ³"
+
+#: views/pages/policy.thtml:51
+msgid "pages_policy_sandbox_link"
+msgstr "サンドボックスã«é–¢ã™ã‚‹æƒ…å ±"
+
+#: views/elements/pagination.thtml:53
+msgid "pagination_next_page"
+msgstr "次ã¸"
+
+#: views/elements/pagination.thtml:52
+msgid "pagination_previous_page"
+msgstr "å‰ã¸"
+
+#: views/elements/recaptcha.thtml:65
+msgid "recaptcha_enter_both_words"
+msgstr ""
+"以下㮠<strong>å˜èªžã‚’両方ã¨ã‚‚</strong>ã€<strong>åŠè§’スペースã§åŒºåˆ‡ã£ã¦</"
+"strong> 入力ã—ã¦ãã ã•ã„。"
+
+#: views/elements/recaptcha.thtml:83
+msgid "recaptcha_enter_here"
+msgstr "ç­”ãˆã‚’入力ã—ã¦ãã ã•ã„:"
+
+#: views/elements/recaptcha.thtml:74
+msgid "recaptcha_enter_whatyouhear"
+msgstr "èžã“ãˆãŸè¨€è‘‰ã‚’以下ã«å…¥åŠ›ã—ã¦ãã ã•ã„。"
+
+#. %1 is the link switching refreshing the captcha
+#. %2 is the link switching to a text captcha
+#: views/elements/recaptcha.thtml:77
+msgid "recaptcha_hardtohear_text"
+msgstr ""
+"ã‚‚ã—ã“ã‚ŒãŒåˆ†ã‹ã‚Šã¥ã‚‰ã„å ´åˆã¯ã€<a href=\"%1$s\">別ã®è¨€è‘‰ã‚’試ã™</a> ã‹ã€<a "
+"href=\"%2$s\">文字列ã«åˆ‡ã‚Šæ›¿ãˆã‚‹</a> ã“ã¨ã‚‚ã§ãã¾ã™ã€‚"
+
+#. %1 is the link switching refreshing the captcha
+#. %2 is the link switching to an audio captcha
+#: views/elements/recaptcha.thtml:68
+msgid "recaptcha_hardtoread_text"
+msgstr ""
+"ã‚‚ã—ã“ã‚ŒãŒåˆ†ã‹ã‚Šã¥ã‚‰ã„å ´åˆã¯ã€<a href=\"%1$s\">別ã®å˜èªžã‚’試ã™</a> ã‹ã€ä»£ã‚ã‚Š"
+"ã« <a href=\"%2$s\">音声ã§èžã</a> ã“ã¨ã‚‚ã§ãã¾ã™ã€‚"
+
+#: views/users/register.thtml:105
+msgid "recaptcha_label"
+msgstr "ã‚ãªãŸã¯äººé–“ã§ã™ã‹ï¼Ÿ"
+
+#: views/users/register.thtml:106
+msgid "recaptcha_whatsthis"
+msgstr "ã“ã‚Œã¯ä½•ã§ã—ょã†ï¼Ÿ"
+
+#: controllers/reviews_controller.php:559
+msgid "review_flag_error"
+msgstr "ã“ã®ãƒ¬ãƒ“ューを通知ã™ã‚‹éš›ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸï¼"
+
+#: models/reviews_moderation_flag.php:69
+msgid "review_flag_reason_bug_support"
+msgstr "å ´é•ã„ãªãƒã‚°å ±å‘Šã¾ãŸã¯ã‚µãƒãƒ¼ãƒˆãƒªã‚¯ã‚¨ã‚¹ãƒˆ"
+
+#: views/reviews/display.thtml:103 views/reviews/display.thtml:186
+msgid "review_flag_reason_instructions"
+msgstr "ã“ã®ãƒ¬ãƒ“ューを報告 (ç†ç”±ã‚’é¸æŠžã—ã¦ãã ã•ã„)"
+
+#: models/reviews_moderation_flag.php:67
+msgid "review_flag_reason_language"
+msgstr "ä¸é©åˆ‡ãªè¨€è‘‰/会話"
+
+#: models/reviews_moderation_flag.php:71
+msgid "review_flag_reason_other"
+msgstr "ãã®ä»– (具体的ã«æ›¸ã„ã¦ãã ã•ã„)"
+
+#: models/reviews_moderation_flag.php:65
+msgid "review_flag_reason_spam"
+msgstr "スパムã‚ã‚‹ã„ã¯ãã®ä»–レビューã¨ç„¡é–¢ä¿‚ã®å†…容"
+
+#: views/reviews/display.thtml:91 views/reviews/display.thtml:175
+#: controllers/reviews_controller.php:555
+msgid "review_flag_success"
+msgstr "ã‚ã‚ŠãŒã¨ã†ã”ã–ã„ã¾ã™ã€‚ã“ã®ãƒ¬ãƒ“ューã¯ã‚¨ãƒ‡ã‚£ã‚¿ã«é€šçŸ¥ã•ã‚Œã¾ã—ãŸã€‚"
+
+#: views/reviews/display.thtml:41
+msgid "review_flag_this"
+msgstr "ã“ã®ãƒ¬ãƒ“ューを報告"
+
+#: views/reviews/display.thtml:42
+msgid "review_flag_this_titletip"
+msgstr ""
+"ã“ã®ãƒ¬ãƒ“ューãŒä¸é©åˆ‡ã€ä¸æ­£ç¢ºã€ã‚ã‚‹ã„ã¯ã‚¹ãƒ‘ムã ã¨æ€ã‚ã‚Œã¾ã™ã‹ï¼Ÿ ã“ã“をクリック"
+"ã—ã¦ã‚¨ãƒ‡ã‚£ã‚¿ã«é€šçŸ¥ã—ã¦ãã ã•ã„。"
+
+#. %1 is the URL of the support section, %2 for the review guidelines
+#: views/reviews/add.thtml:53
+msgid "review_guidelines_short"
+msgstr ""
+"<p>レビューを書ãéš›ã¯ä»¥ä¸‹ã®ã“ã¨ã‚’念頭ã«ç½®ã„ã¦ãã ã•ã„。</p><ul><li>アドオンã«"
+"よã£ã¦å¾—られãŸçµŒé¨“ã‚’å‹äººã«ä¼ãˆã‚‹ã‚ˆã†ã«æ›¸ã„ã¦ãã ã•ã„。気ã«å…¥ã£ãŸã€ã‚ã‚‹ã„ã¯æ°—"
+"ã«å…¥ã‚‰ãªã„機能ã€ä½¿ã„ã‚„ã™ã•ã€ä¸éƒ½åˆãªç‚¹ã¨ã„ã£ãŸã€å…·ä½“çš„ãªã“ã¨ã‚„å½¹ã«ç«‹ã¤ã“ã¨ã‚’"
+"書ã„ã¦ãã ã•ã„。「ã™ã”ã„ã€ã€Œæ‚ªã„ã€ã¨ã„ã£ãŸä¸€èˆ¬çš„ãªèªžå¥ã¯ã€ãã®ã‚ˆã†ã«æ€ã†ç†ç”±"
+"を併記ã—ãªã„é™ã‚Šé¿ã‘ã¦ãã ã•ã„。</li><li>ãƒã‚°å ±å‘Šã‚’レビューã¨ã—ã¦æŠ•ç¨¿ã—ãªã„ã§"
+"ãã ã•ã„。ã‚ãªãŸã®ãƒ¡ãƒ¼ãƒ«ã‚¢ãƒ‰ãƒ¬ã‚¹ã¯ã‚¢ãƒ‰ã‚ªãƒ³ä½œè€…ã«å…¬é–‹ã•ã‚Œã¾ã›ã‚“ã®ã§ã€ä½œè€…ãŒå•"
+"題解決ã®ãŸã‚ã‚ãªãŸã«å”力をãŠé¡˜ã„ã—ãŸã„ã¨æ€ã£ã¦ã‚‚ã€é€£çµ¡ã‚’å–ã‚‹ã“ã¨ãŒã§ãã¾ã›"
+"ん。ã“ã®ã‚¢ãƒ‰ã‚ªãƒ³ã«ã¤ã„ã¦ä½•ã‹ã‚µãƒãƒ¼ãƒˆã‚’å¿…è¦ã¨ã•ã‚Œã¦ã„ã‚‹å ´åˆã¯ã€<a href=\"%1$s"
+"\">サãƒãƒ¼ãƒˆ</a> ã®é …目をå‚ç…§ã—ã¦ãã ã•ã„。</li><li>ä¸é©åˆ‡ãªè¨€è‘‰ã¯é¿ã‘ã¦ãã ã•"
+"ã„。ã¾ãŸã€ã„ã‹ãªã‚‹å€‹äººæƒ…報も投稿ã—ã¦ã¯ãªã‚Šã¾ã›ã‚“。</li></ul><p>ユーザã«ã‚ˆã‚‹ã‚¢"
+"ドオンレビューã®è©³ç´°ã¯ <a href=\"%2$s\">レビューガイドライン</a> ã‚’å‚ç…§ã—ã¦ã"
+"ã ã•ã„。"
+
+#. %1 is the add-on name
+#: views/reviews/flag.thtml:56 views/reviews/display.thtml:55
+#: views/reviews/review_added.thtml:50
+#, php-format
+msgid "reviews_header"
+msgstr "%s ã®ãƒ¬ãƒ“ュー"
+
+#: controllers/addons_controller.php:435
+msgid "rss_featuredaddons"
+msgstr "注目ã®ã‚¢ãƒ‰ã‚ªãƒ³"
+
+#: controllers/addons_controller.php:432
+msgid "rss_newestaddons"
+msgstr "最近公開ã•ã‚ŒãŸã‚¢ãƒ‰ã‚ªãƒ³"
+
+#: controllers/addons_controller.php:434
+msgid "rss_popularaddons"
+msgstr "人気ã®ã‚¢ãƒ‰ã‚ªãƒ³"
+
+#: controllers/addons_controller.php:433
+msgid "rss_updatedaddons"
+msgstr "最近更新ã•ã‚ŒãŸã‚¢ãƒ‰ã‚ªãƒ³"
+
+#: views/elements/search_mini.thtml:70
+msgid "search"
+msgstr "検索"
+
+#: views/search/collections.thtml:51
+msgid "search_collections_header"
+msgstr "コレクションã®æ¤œç´¢çµæžœ"
+
+#: controllers/search_controller.php:297
+msgid "search_collections_pagetitle"
+msgstr "コレクションã®æ¤œç´¢çµæžœ"
+
+#: controllers/search_controller.php:99
+msgid "search_disabled"
+msgstr "ç¾åœ¨ã€æ¤œç´¢æ©Ÿèƒ½ã¯åˆ©ç”¨ã§ãã¾ã›ã‚“。ã¾ãŸå¾Œã§ãŠè©¦ã—ãã ã•ã„。"
+
+#: views/elements/amo2009/search.thtml:188 views/elements/search.thtml:187
+#: views/elements/search_mini.thtml:54
+msgid "search_form_all_addons"
+msgstr "ã™ã¹ã¦"
+
+#. This string is in the main category dropdown when searching
+#: views/elements/amo2009/search.thtml:204
+msgid "search_form_all_collections"
+msgstr "ã™ã¹ã¦ã®ã‚³ãƒ¬ã‚¯ã‚·ãƒ§ãƒ³"
+
+#: views/elements/amo2009/search.thtml:184
+#: views/elements/amo2009/search.thtml:385
+#: views/elements/amo2009/search.thtml:408 views/elements/search.thtml:171
+#: views/elements/search.thtml:183 views/elements/search_mini.thtml:43
+#: views/elements/search_mini.thtml:49 views/layouts/mozilla.thtml:188
+msgid "search_form_default_text"
+msgstr "アドオンを検索"
+
+#: views/elements/amo2009/search.thtml:184
+#: views/elements/amo2009/search.thtml:404
+msgid "search_form_default_text_collections"
+msgstr "コレクションを検索"
+
+#: views/elements/amo2009/search.thtml:206 views/elements/search.thtml:202
+msgid "search_form_submit_tooltip"
+msgstr "アドオンを検索"
+
+#: views/elements/amo2009/search.thtml:184 views/elements/search.thtml:183
+#: views/elements/search_mini.thtml:49
+msgid "search_form_tooltip"
+msgstr "クリックã—ã¦æ¤œç´¢èªžã‚’入力"
+
+#: views/elements/amo2009/search.thtml:186 views/elements/search.thtml:185
+#: views/elements/search_mini.thtml:52
+msgid "search_form_within"
+msgstr "カテゴリ"
+
+#: views/addons/searchengines.thtml:118
+msgid "search_landing_all_search_engines"
+msgstr "ã™ã¹ã¦ã®æ¤œç´¢ã‚¨ãƒ³ã‚¸ãƒ³"
+
+#: views/addons/searchengines.thtml:114
+msgid "search_landing_browse_search_engines"
+msgstr "検索エンジンをブラウズ"
+
+#: views/search/collections.thtml:58 views/search/index.thtml:59
+msgid "search_nothing_found"
+msgstr "該当ã™ã‚‹ã‚¢ãƒ‰ã‚ªãƒ³ã¯ã‚ã‚Šã¾ã›ã‚“。"
+
+#: controllers/search_controller.php:185
+msgid "search_pagetitle"
+msgstr "アドオンã®æ¤œç´¢"
+
+#: controllers/search_controller.php:242
+msgid "search_rss_description"
+msgstr "検索çµæžœã®ãƒ•ã‚£ãƒ¼ãƒ‰"
+
+#. %s is the terms the user is searching for (a string)
+#: controllers/search_controller.php:241
+#, php-format
+msgid "search_rss_results_for"
+msgstr "%s ã®æ¤œç´¢çµæžœ"
+
+#: views/elements/header.thtml:154 views/layouts/amo2009.thtml:296
+msgid "sidebar_navlink_admin_tools"
+msgstr "管ç†è€…用ツール"
+
+#: views/elements/header.thtml:146 views/layouts/amo2009.thtml:288
+msgid "sidebar_navlink_developer_tools"
+msgstr "開発者用ツール"
+
+#: views/elements/header.thtml:148 views/layouts/amo2009.thtml:290
+msgid "sidebar_navlink_editor_tools"
+msgstr "エディタ用ツール"
+
+#: views/layouts/amo2009.thtml:302
+msgid "sidebar_navlink_welcome"
+msgstr "よã†ã“ã"
+
+#. %s is the user's name
+#: views/layouts/amo2009.thtml:302
+#, php-format
+msgid "sidebar_navlink_welcome_name"
+msgstr "よã†ã“ã %s ã•ã‚“"
+
+#: views/elements/pitch.thtml:50 views/elements/pitch.thtml:55
+msgid "sidebar_pitch_dictionary"
+msgstr "スペルãƒã‚§ãƒƒã‚¯è¾žæ›¸"
+
+#: views/elements/pitch.thtml:72
+msgid "sidebar_pitch_featured_addons"
+msgstr "ãŠã™ã™ã‚ã®ã‚¢ãƒ‰ã‚ªãƒ³"
+
+#: views/elements/pitch.thtml:61
+msgid "sidebar_pitch_looking_for"
+msgstr "探ã—ã¦ã„ã‚‹ã‚‚ã®ã¯"
+
+#: views/elements/pitch.thtml:70
+msgid "sidebar_pitch_newest_addons"
+msgstr "最近公開ã•ã‚ŒãŸã‚¢ãƒ‰ã‚ªãƒ³"
+
+#: views/elements/pitch.thtml:49
+msgid "sidebar_pitch_search"
+msgstr "検索プラグイン"
+
+#: views/elements/pitch.thtml:69
+msgid "sidebar_pitch_subscribe_to"
+msgstr "フィードを購読"
+
+#: views/elements/pitch.thtml:48 views/elements/pitch.thtml:54
+msgid "sidebar_pitch_theme"
+msgstr "テーマ"
+
+#: views/elements/pitch.thtml:71
+msgid "sidebar_pitch_updated_addons"
+msgstr "最近更新ã•ã‚ŒãŸã‚¢ãƒ‰ã‚ªãƒ³"
+
+#. %1$s is a number
+#: views/helpers/localization.php:65 views/developers/versions_edit.thtml:95
+#: views/addons/dictionaries.thtml:92
+#, php-format
+msgid "size_kb"
+msgstr "%1$s KB"
+
+#: views/elements/amo2009/stars.thtml:57 views/elements/stars.thtml:63
+msgid "stars_not_yet_rated"
+msgstr "ã¾ã è©•ä¾¡ã•ã‚Œã¦ã„ã¾ã›ã‚“"
+
+#. %1 is the number of stars this add-on has
+#: views/elements/amo2009/stars.thtml:49 views/elements/stars.thtml:54
+#, php-format
+msgid "stars_rated_x_outof_5"
+msgstr "5 ã¤æ˜Ÿã®ã†ã¡ %s ã¤ã®è©•ä¾¡ã‚’å—ã‘ã¦ã„ã¾ã™"
+
+#: views/statistics/addon.thtml:59
+msgid "statistics_addon_dashboard_link"
+msgstr "ダッシュボードã®ãƒ›ãƒ¼ãƒ "
+
+#: views/statistics/addon.thtml:58
+msgid "statistics_addon_developertools_link"
+msgstr "開発者用ツール"
+
+#: views/statistics/addon.thtml:53
+msgid "statistics_addon_switch"
+msgstr "アドオンを切り替ãˆ"
+
+#. This is a date format.
+#. http://php.net/strftime
+#: views/statistics/rss/summary.thtml:54 views/statistics/addon.thtml:181
+msgid "statistics_date_shortmonth"
+msgstr "%b %e æ—¥"
+
+#. This is a date format.
+#. http://php.net/strftime
+#: views/statistics/rss/summary.thtml:40 views/statistics/addon.thtml:152
+msgid "statistics_date_shortmonthwithyear"
+msgstr "%Yå¹´ %b %eæ—¥"
+
+#. This is a date format.
+#. http://php.net/strftime
+#: views/statistics/rss/summary.thtml:41 views/statistics/rss/summary.thtml:48
+#: views/statistics/addon.thtml:161 views/statistics/addon.thtml:172
+msgid "statistics_date_weekdayshortmonth"
+msgstr "%b %eæ—¥ (%a)"
+
+#. %1$s is an add-on name and version. Example: Add-on 3.5
+#: controllers/components/stats.php:519
+#, php-format
+msgid "statistics_events_addon_created"
+msgstr "%1$s 作æˆ"
+
+#. %1$s is an application name and version. Example: Firefox 3.5
+#: controllers/components/stats.php:500
+#, php-format
+msgid "statistics_events_app_released"
+msgstr "%1$s 公開"
+
+#: views/statistics/addon.thtml:71
+msgid "statistics_help_close_link"
+msgstr "é–‰ã˜ã‚‹"
+
+#: views/statistics/addon.thtml:60
+msgid "statistics_help_link"
+msgstr "ヘルプ"
+
+#: views/statistics/index.thtml:83
+msgid "statistics_index_anotheraddon"
+msgstr "ã¾ãŸã¯ã€åˆ¥ã®ã‚¢ãƒ‰ã‚ªãƒ³ã‚’é¸æŠžã—ã¦ãã ã•ã„"
+
+#: views/statistics/index.thtml:85
+msgid "statistics_index_anotheraddon_public"
+msgstr "ã¾ãŸã¯ã€çµ±è¨ˆæƒ…å ±ãŒå…¬é–‹ã•ã‚Œã¦ã„るアドオンをé¸æŠžã—ã¦ãã ã•ã„"
+
+#: views/statistics/index.thtml:71
+msgid "statistics_index_myaddons"
+msgstr "統計情報を表示ã™ã‚‹ã«ã¯ã€ã‚ãªãŸã®ã‚¢ãƒ‰ã‚ªãƒ³ã‚’ã²ã¨ã¤é¸æŠžã—ã¦ãã ã•ã„"
+
+#: views/statistics/index.thtml:89
+msgid "statistics_index_selectaddon"
+msgstr "統計情報を表示ã™ã‚‹ã«ã¯ã€ã‚¢ãƒ‰ã‚ªãƒ³ã‚’é¸æŠžã—ã¦ãã ã•ã„"
+
+#: views/statistics/index.thtml:91
+msgid "statistics_index_selectaddon_public"
+msgstr "統計情報ãŒå…¬é–‹ã•ã‚Œã¦ã„るアドオンをé¸æŠž"
+
+#: views/statistics/index.thtml:39
+msgid "statistics_index_title"
+msgstr "統計ダッシュボード"
+
+#: views/statistics/index.thtml:97
+msgid "statistics_index_view_button"
+msgstr "統計を表示"
+
+#: views/statistics/addon.thtml:222 controllers/statistics_controller.php:247
+msgid "statistics_js_download_csv"
+msgstr "ã“ã®è¡¨ã‚’ CSV å½¢å¼ã§è¡¨ç¤º"
+
+#: controllers/statistics_controller.php:246
+msgid "statistics_js_dropdowns_none"
+msgstr "ãªã—"
+
+#: controllers/statistics_controller.php:245
+msgid "statistics_js_dropdowns_removeplot"
+msgstr "ã“ã®åº§æ¨™ã‚’削除"
+
+#: controllers/statistics_controller.php:248
+msgid "statistics_js_groupby_selector_date"
+msgstr "グループ化: 1 日"
+
+#: controllers/statistics_controller.php:251
+msgid "statistics_js_groupby_selector_month"
+msgstr "グループ化: 1 ã‹æœˆ"
+
+#: controllers/statistics_controller.php:249
+msgid "statistics_js_groupby_selector_week"
+msgstr "グループ化: 1 週間"
+
+#: controllers/statistics_controller.php:250
+msgid "statistics_js_groupby_selector_week_over_week"
+msgstr "一定期間ã®æ¯”較: 週ã”ã¨"
+
+#: controllers/statistics_controller.php:260
+msgid "statistics_js_plotselection_foundinrange"
+msgstr "範囲内㫠%s 件見ã¤ã‹ã‚Šã¾ã—ãŸ"
+
+#: controllers/statistics_controller.php:270
+msgid "statistics_js_plotselection_options_addplot_name"
+msgstr "座標を追加"
+
+#: controllers/statistics_controller.php:271
+msgid "statistics_js_plotselection_options_addplot_tooltip"
+msgstr "ã“ã®ã‚°ãƒ©ãƒ•ã«åˆ¥ã®åº§æ¨™ã‚’追加"
+
+#: controllers/statistics_controller.php:261
+msgid "statistics_js_plotselection_options_count_name_checked"
+msgstr "åˆè¨ˆæ•°ã‚’éš ã™"
+
+#: controllers/statistics_controller.php:262
+msgid "statistics_js_plotselection_options_count_name_unchecked"
+msgstr "åˆè¨ˆæ•°ã‚’表示"
+
+#: controllers/statistics_controller.php:263
+msgid "statistics_js_plotselection_options_count_tooltip"
+msgstr "ã“ã®ã‚°ãƒ©ãƒ•ä¸Šã«åˆè¨ˆæ•°ã‚’表示ã™ã‚‹"
+
+#: controllers/statistics_controller.php:275
+msgid "statistics_js_plotselection_options_csv_name"
+msgstr "データを表示 (CSV)"
+
+#: controllers/statistics_controller.php:276
+msgid "statistics_js_plotselection_options_csv_tooltip"
+msgstr "ã“ã®ãƒ‡ãƒ¼ã‚¿ã®ã‚«ãƒ³ãƒžåŒºåˆ‡ã‚Šãƒ•ã‚¡ã‚¤ãƒ«ã‚’ダウンロード"
+
+#: controllers/statistics_controller.php:267
+msgid "statistics_js_plotselection_options_events_addon_name_checked"
+msgstr "%s ã®ã‚¤ãƒ™ãƒ³ãƒˆã‚’éš ã™"
+
+#: controllers/statistics_controller.php:268
+msgid "statistics_js_plotselection_options_events_addon_name_unchecked"
+msgstr "%s ã®ã‚¤ãƒ™ãƒ³ãƒˆã‚’表示"
+
+#: controllers/statistics_controller.php:269
+msgid "statistics_js_plotselection_options_events_addon_tooltip"
+msgstr "座標上ã«ã‚¢ãƒ‰ã‚ªãƒ³ã®ãƒªãƒªãƒ¼ã‚¹æ—¥ã‚’表示"
+
+#: controllers/statistics_controller.php:264
+msgid "statistics_js_plotselection_options_events_firefox_name_checked"
+msgstr "Firefox ã®ã‚¤ãƒ™ãƒ³ãƒˆã‚’éš ã™"
+
+#: controllers/statistics_controller.php:265
+msgid "statistics_js_plotselection_options_events_firefox_name_unchecked"
+msgstr "Firefox ã®ã‚¤ãƒ™ãƒ³ãƒˆã‚’表示"
+
+#: controllers/statistics_controller.php:266
+msgid "statistics_js_plotselection_options_events_firefox_tooltip"
+msgstr "座標上㫠Firefox ã®ãƒªãƒªãƒ¼ã‚¹æ—¥ã‚’表示"
+
+#: controllers/statistics_controller.php:272
+msgid "statistics_js_plotselection_options_resize_name_checked"
+msgstr "グラフを縮å°"
+
+#: controllers/statistics_controller.php:273
+msgid "statistics_js_plotselection_options_resize_name_unchecked"
+msgstr "グラフを拡大"
+
+#: controllers/statistics_controller.php:274
+msgid "statistics_js_plotselection_options_resize_tooltip"
+msgstr "グラフã®ã‚µã‚¤ã‚ºã‚’変更"
+
+#: controllers/statistics_controller.php:254
+msgid "statistics_js_plotselection_selector_adu"
+msgstr "1 æ—¥ã®ã‚¢ã‚¯ãƒ†ã‚£ãƒ–ユーザ数"
+
+#: controllers/statistics_controller.php:256
+msgid "statistics_js_plotselection_selector_application"
+msgstr "アプリケーション"
+
+#: controllers/statistics_controller.php:259
+msgid "statistics_js_plotselection_selector_custom"
+msgstr "カスタム"
+
+#: controllers/statistics_controller.php:253
+msgid "statistics_js_plotselection_selector_downloads"
+msgstr "ダウンロード"
+
+#: controllers/statistics_controller.php:258
+msgid "statistics_js_plotselection_selector_os"
+msgstr "OS"
+
+#: controllers/statistics_controller.php:257
+msgid "statistics_js_plotselection_selector_status"
+msgstr "アドオンã®çŠ¶æ…‹"
+
+#: controllers/statistics_controller.php:252
+msgid "statistics_js_plotselection_selector_summary"
+msgstr "概è¦"
+
+#: controllers/statistics_controller.php:255
+msgid "statistics_js_plotselection_selector_version"
+msgstr "アドオンã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³"
+
+#: controllers/components/stats.php:398
+msgid "statistics_longnames_application"
+msgstr "アプリケーション"
+
+#: controllers/components/stats.php:400
+msgid "statistics_longnames_os"
+msgstr "OS"
+
+#: controllers/components/stats.php:399
+msgid "statistics_longnames_status"
+msgstr "アドオンã®çŠ¶æ…‹"
+
+#: controllers/components/stats.php:401
+msgid "statistics_longnames_unknown"
+msgstr "ä¸æ˜Ž"
+
+#: controllers/components/stats.php:397
+msgid "statistics_longnames_version"
+msgstr "アドオンã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³"
+
+#: views/statistics/addon.thtml:118
+msgid "statistics_notice_data_insufficient"
+msgstr ""
+"ã“ã®ã‚°ãƒ©ãƒ•ä¸Šã«è¡¨ç¤ºã§ãるデータãŒã¾ã å分ã«é›†ã¾ã£ã¦ã„ã¾ã›ã‚“。ã¾ãŸå¾Œã§ç¢ºèªã—ã¦"
+"ãã ã•ã„。"
+
+#: views/statistics/addon.thtml:130
+msgid "statistics_notice_data_none"
+msgstr ""
+"ã“ã®ã‚¢ãƒ‰ã‚ªãƒ³ã®ãƒ‡ãƒ¼ã‚¿ã¯ã¾ã é›†ã¾ã£ã¦ã„ã¾ã›ã‚“。数日後ã«ã¾ãŸç¢ºèªã—ã¦ãã ã•ã„。"
+
+#: views/statistics/addon.thtml:41
+msgid "statistics_notice_data_updating"
+msgstr ""
+"ç¾åœ¨ã€ã‚¢ãƒ‰ã‚ªãƒ³ã®çµ±è¨ˆã¯æ›´æ–°ä¸­ã§ã™ã€‚プログラムã«ã‚ˆã£ã¦æƒ…å ±ã®æ›´æ–°ãŒå®Œäº†ã™ã‚‹ã¾"
+"ã§ã€æœ€è¿‘ã®ãƒ‡ãƒ¼ã‚¿ã¯ä¸å®Œå…¨ã§ã™ã€‚数分後ã«ã¾ãŸç¢ºèªã—ã¦ãã ã•ã„。"
+
+#: views/statistics/addon.thtml:136
+msgid "statistics_notice_disabled"
+msgstr "統計ダッシュボードã¯ç¾åœ¨ã”利用ã«ãªã‚Œã¾ã›ã‚“。ã¾ãŸå¾Œã§ç¢ºèªã—ã¦ãã ã•ã„。"
+
+#: views/statistics/addon.thtml:123
+msgid "statistics_notice_nojavascript"
+msgstr ""
+"統計ダッシュボードã®ã‚°ãƒ©ãƒ•ã‚’表示ã™ã‚‹ã«ã¯ JavaScript を有効ã«ã—ã¦ãã ã•ã„。"
+
+#: views/statistics/addon.thtml:44
+msgid "statistics_notice_settings_updated"
+msgstr "設定ãŒæ›´æ–°ã•ã‚Œã¾ã—ãŸã€‚"
+
+#: controllers/statistics_controller.php:60
+#: controllers/statistics_controller.php:71
+#: controllers/statistics_controller.php:74
+#: controllers/statistics_controller.php:240
+msgid "statistics_pagetitle"
+msgstr "統計ダッシュボード"
+
+#: views/statistics/addon.thtml:99
+msgid "statistics_plot_legend_adu"
+msgstr "1 æ—¥ã®ã‚¢ã‚¯ãƒ†ã‚£ãƒ–ユーザ数"
+
+#: views/statistics/addon.thtml:95
+msgid "statistics_plot_legend_downloads"
+msgstr "1 æ—¥ã®ãƒ€ã‚¦ãƒ³ãƒ­ãƒ¼ãƒ‰æ•°"
+
+#: views/statistics/addon.thtml:107
+msgid "statistics_plot_options_zoomin_alt"
+msgstr "拡大"
+
+#: views/statistics/addon.thtml:106
+msgid "statistics_plot_options_zoomin_title"
+msgstr "1 ã‹æœˆåˆ†æ‹¡å¤§"
+
+#: views/statistics/addon.thtml:110
+msgid "statistics_plot_options_zoomout_alt"
+msgstr "縮å°"
+
+#: views/statistics/addon.thtml:109
+msgid "statistics_plot_options_zoomout_title"
+msgstr "1 ã‹æœˆåˆ†ç¸®å°"
+
+#: controllers/statistics_controller.php:283
+#, php-format
+msgid "statistics_rss_description"
+msgstr "%1$s ã®çµ±è¨ˆ: 1 æ—¥ã®æ¦‚è¦"
+
+#: views/statistics/rss/summary.thtml:68
+msgid "statistics_rss_title_fulldate"
+msgstr "%Yå¹´ %b %eæ—¥ (%a)"
+
+#: views/statistics/rss/summary.thtml:68
+#, php-format
+msgid "statistics_rss_title_statsfordate"
+msgstr "%1$s ã®çµ±è¨ˆ"
+
+#: views/statistics/settings.thtml:49
+msgid "statistics_settings_access_description"
+msgstr ""
+"åˆæœŸè¨­å®šã§ã¯ã€ãƒ€ãƒƒã‚·ãƒ¥ãƒœãƒ¼ãƒ‰ã«è¡¨ç¤ºã•ã‚Œã¦ã„る情報ã«ã‚¢ã‚¯ã‚»ã‚¹ã§ãã‚‹ã®ã¯ã€ã‚ãªãŸ"
+"㨠Mozilla ã ã‘ã§ã™ã€‚ã‚ãªãŸã¯ã“ã®æƒ…報を一般ã«å…¬é–‹ã™ã‚‹ã“ã¨ã‚‚ã§ãã¾ã™ã€‚ãã†ã™ã‚Œ"
+"ã°ã€èª°ã§ã‚‚ã“ã®ã‚¢ãƒ‰ã‚ªãƒ³ã®çµ±è¨ˆæƒ…報を見るã“ã¨ãŒã§ãã¾ã™ã€‚"
+
+#: views/statistics/settings.thtml:48
+msgid "statistics_settings_access_heading"
+msgstr "ダッシュボードã¸ã®ã‚¢ã‚¯ã‚»ã‚¹æ¨©é™ã®è¨­å®š"
+
+#: views/statistics/settings.thtml:51
+msgid "statistics_settings_access_private"
+msgstr "éžå…¬é–‹"
+
+#: views/statistics/settings.thtml:51
+msgid "statistics_settings_access_private_description"
+msgstr "ã‚ãªãŸã¨ Mozilla ã ã‘ãŒã“ã®ã‚¢ãƒ‰ã‚ªãƒ³ã®çµ±è¨ˆã‚’表示ã§ãã¾ã™"
+
+#: views/statistics/settings.thtml:52
+msgid "statistics_settings_access_public"
+msgstr "公開"
+
+#: views/statistics/settings.thtml:52
+msgid "statistics_settings_access_public_description"
+msgstr "誰ã§ã‚‚ã“ã®ã‚¢ãƒ‰ã‚ªãƒ³ã®çµ±è¨ˆã‚’表示ã§ãã¾ã™"
+
+#: views/statistics/addon.thtml:251
+msgid "statistics_settings_change_link"
+msgstr "設定を変更"
+
+#: views/statistics/addon.thtml:253
+msgid "statistics_settings_confidential"
+msgstr "ã“ã®æƒ…å ±ã¯æ©Ÿå¯†æ‰±ã„ã¨ã—ã¦ãã ã•ã„。"
+
+#: views/statistics/addon.thtml:245
+msgid "statistics_settings_currently_private"
+msgstr "ã“ã®ãƒ€ãƒƒã‚·ãƒ¥ãƒœãƒ¼ãƒ‰ã¯ç¾åœ¨ <b>éžå…¬é–‹ã§ã™</b>。"
+
+#: views/statistics/addon.thtml:241
+msgid "statistics_settings_currently_public"
+msgstr "ã“ã®ãƒ€ãƒƒã‚·ãƒ¥ãƒœãƒ¼ãƒ‰ã¯ç¾åœ¨ <b>公開ã•ã‚Œã¦ã„ã¾ã™</b>。"
+
+#: views/statistics/addon.thtml:246
+msgid "statistics_settings_locked_alt"
+msgstr "ロックã•ã‚Œã¦ã„ã¾ã™"
+
+#: views/statistics/settings.thtml:57
+msgid "statistics_settings_return_link"
+msgstr "ダッシュボードã¸æˆ»ã‚‹"
+
+#: views/statistics/settings.thtml:56
+msgid "statistics_settings_save_button"
+msgstr "設定をä¿å­˜"
+
+#: views/statistics/settings.thtml:46
+#, php-format
+msgid "statistics_settings_title"
+msgstr "%1$s ã®çµ±è¨ˆãƒ€ãƒƒã‚·ãƒ¥ãƒœãƒ¼ãƒ‰è¨­å®š"
+
+#: views/statistics/addon.thtml:242
+msgid "statistics_settings_unlocked_alt"
+msgstr "ロック解除ã•ã‚Œã¦ã„ã¾ã™"
+
+#: controllers/components/stats.php:405
+msgid "statistics_shortnames_application"
+msgstr "アプリ"
+
+#: controllers/components/stats.php:407
+msgid "statistics_shortnames_os"
+msgstr "OS"
+
+#: controllers/components/stats.php:406
+msgid "statistics_shortnames_status"
+msgstr "状態"
+
+#: controllers/components/stats.php:408
+msgid "statistics_shortnames_unknown"
+msgstr "ä¸æ˜Ž"
+
+#: controllers/components/stats.php:404
+msgid "statistics_shortnames_version"
+msgstr "Ver"
+
+#: views/statistics/rss/summary.thtml:42 views/statistics/addon.thtml:192
+msgid "statistics_summary_downloads_average"
+msgstr "1 æ—¥ã®å¹³å‡ãƒ€ã‚¦ãƒ³ãƒ­ãƒ¼ãƒ‰æ•°"
+
+#: views/statistics/rss/summary.thtml:39
+msgid "statistics_summary_downloads_heading"
+msgstr "ダウンロード"
+
+#: views/statistics/rss/summary.thtml:41 views/statistics/addon.thtml:171
+msgid "statistics_summary_downloads_lastcount"
+msgstr "最新ã®æ•°å­—"
+
+#: views/statistics/rss/summary.thtml:43 views/statistics/addon.thtml:199
+msgid "statistics_summary_downloads_lastweek"
+msgstr "éŽåŽ» 7 日間ã®ãƒ€ã‚¦ãƒ³ãƒ­ãƒ¼ãƒ‰æ•°"
+
+#: views/statistics/rss/summary.thtml:40 views/statistics/addon.thtml:151
+msgid "statistics_summary_downloads_total"
+msgstr "累計ダウンロード数"
+
+#: views/statistics/rss/summary.thtml:40 views/statistics/addon.thtml:152
+#, php-format
+msgid "statistics_summary_downloads_total_sincedate"
+msgstr "%1$s 以é™"
+
+#: views/statistics/rss/summary.thtml:50 views/statistics/rss/summary.thtml:56
+#: views/statistics/addon.thtml:163 views/statistics/addon.thtml:183
+msgid "statistics_summary_nodata"
+msgstr "ã¾ã ãƒ‡ãƒ¼ã‚¿ãŒã‚ã‚Šã¾ã›ã‚“"
+
+#: views/statistics/rss/summary.thtml:60 views/statistics/addon.thtml:195
+msgid "statistics_summary_updatepings_average"
+msgstr "1 æ—¥ã®å¹³å‡ã‚¢ã‚¯ãƒ†ã‚£ãƒ–ユーザ"
+
+#: views/statistics/rss/summary.thtml:52 views/statistics/addon.thtml:177
+msgid "statistics_summary_updatepings_changefromprevious"
+msgstr "å‰å›žãƒ‡ãƒ¼ã‚¿ã‹ã‚‰ã®å¤‰æ›´"
+
+#: views/statistics/rss/summary.thtml:54 views/statistics/addon.thtml:181
+#, php-format
+msgid "statistics_summary_updatepings_changefromprevious_ondate"
+msgstr "%1$s (%2$s ç¾åœ¨)"
+
+#: views/statistics/rss/summary.thtml:45
+msgid "statistics_summary_updatepings_heading"
+msgstr "1 æ—¥ã®å¹³å‡ã‚¢ã‚¯ãƒ†ã‚£ãƒ–ユーザ"
+
+#: views/statistics/rss/summary.thtml:46 views/statistics/addon.thtml:157
+msgid "statistics_summary_updatepings_total"
+msgstr "1 æ—¥ã®å¹³å‡ã‚¢ã‚¯ãƒ†ã‚£ãƒ–ユーザ"
+
+#: views/statistics/rss/summary.thtml:48 views/statistics/addon.thtml:161
+#, php-format
+msgid "statistics_summary_updatepings_total_ondate"
+msgstr "%1$s ç¾åœ¨"
+
+#: views/statistics/rss/summary.thtml:61 views/statistics/addon.thtml:203
+msgid "statistics_summary_updatepings_weekly_average"
+msgstr "今週ã®æ—¥åˆ¥å¹³å‡ãƒ¦ãƒ¼ã‚¶æ•°"
+
+#. %s is a percentage, like '+22.33%'. It sits next to another number, so
+#. the implied meaning is 'percentage change' from the previous stat point.
+#: views/statistics/rss/summary.thtml:62 views/statistics/addon.thtml:205
+msgid "statistics_summary_updatepings_weekly_change"
+msgstr "先週ã‹ã‚‰ã®å¢—減: %s"
+
+#: views/statistics/addon.thtml:65 controllers/statistics_controller.php:184
+#: controllers/statistics_controller.php:282
+#, php-format
+msgid "statistics_title_addon_stats"
+msgstr "%1$s ã®çµ±è¨ˆ"
+
+#: views/addons/themes_landing.thtml:113
+msgid "themes_landing_all_themes"
+msgstr "ã™ã¹ã¦ã®ãƒ†ãƒ¼ãƒž"
+
+#: views/addons/themes_landing.thtml:109
+msgid "themes_landing_browse_themes"
+msgstr "テーマをブラウズ"
+
+#: views/users/edit.thtml:185
+msgid "user_change_email"
+msgstr "メールアドレスã®å¤‰æ›´"
+
+#: views/users/edit.thtml:169
+msgid "user_change_password"
+msgstr "パスワードã®å¤‰æ›´"
+
+#: views/users/edit.thtml:96
+msgid "user_change_password_or_email"
+msgstr "パスワードã¾ãŸã¯ãƒ¡ãƒ¼ãƒ«ã‚¢ãƒ‰ãƒ¬ã‚¹ã‚’変更"
+
+#: controllers/users_controller.php:197
+msgid "user_confirmationcode_resent"
+msgstr "確èªã‚³ãƒ¼ãƒ‰ã‚’å†é€ä¿¡ã—ã¾ã—ãŸã€‚"
+
+#. %1 is the email address, %2 is the URL of the user registration page
+#: views/users/delete.thtml:51
+msgid "user_del_account_deleted"
+msgstr ""
+"ã‚ãªãŸã®ãƒ¦ãƒ¼ã‚¶ã‚¢ã‚«ã‚¦ãƒ³ãƒˆ %1$s ã¯æ­£å¸¸ã«å‰Šé™¤ã•ã‚Œã¾ã—ãŸã€‚後日ã¾ãŸãƒ­ã‚°ã‚¤ãƒ³ãŒå¿…è¦"
+"ã«ãªã£ãŸã¨ãã¯ã€<a href=\"%2$s\">ユーザ登録ページ</a> ã‹ã‚‰å†ç™»éŒ²ã—ã¦ãã ã•"
+"ã„。"
+
+#: views/users/delete.thtml:102
+msgid "user_del_community_sad"
+msgstr "Mozilla Add-ons コミュニティã¯ã‚ãªãŸãŒã„ãªããªã‚‹ã®ã‚’残念ã«æ€ã„ã¾ã™ã€‚"
+
+#: views/users/delete.thtml:123
+msgid "user_del_confirm_password"
+msgstr "パスワードをå†åº¦å…¥åŠ›"
+
+#: views/users/delete.thtml:134
+msgid "user_del_deletenow"
+msgstr "今ã™ãユーザアカウントを削除"
+
+#. %1 is the URL of the user's info page
+#: views/users/delete.thtml:64
+msgid "user_del_error_addons"
+msgstr ""
+"ã‚ãªãŸãŒ <a href=\"%1$s\">アドオンã®ä½œè€…</a> ã¨ã—ã¦ç™»éŒ²ã•ã‚Œã¦ã„ã‚‹å ´åˆã€ã‚¢ã‚«ã‚¦"
+"ントを削除ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“。アカウントを削除ã™ã‚‹ã«ã¯ã€é–‹ç™ºã‚°ãƒ«ãƒ¼ãƒ—ã«å‚加"
+"ã—ã¦ã„ã‚‹ä»–ã®äººã«é ¼ã‚“ã§ã€ã‚ãªãŸã‚’アドオンã®ä½œè€…ã‹ã‚‰å¤–ã—ã¦ã‚‚らã£ã¦ãã ã•ã„。ã"
+"ã†ã™ã‚Œã°ã€ã“ã“ã§ã‚¢ã‚«ã‚¦ãƒ³ãƒˆã®å‰Šé™¤ãŒå¯èƒ½ã«ãªã‚Šã¾ã™ã€‚"
+
+#. %1 is a link to the amo-editors mailing list
+#: views/users/delete.thtml:71
+msgid "user_del_error_addons_more_questions"
+msgstr "ä»–ã«è³ªå•ãŒã‚ã‚‹å ´åˆã¯ã€%1$s ã¾ã§ãŠå•ã„åˆã‚ã›ãã ã•ã„。"
+
+#: views/users/delete.thtml:78
+msgid "user_del_error_checkbox"
+msgstr "アカウントを削除ã™ã‚‹ã«ã¯ã€ã€Œäº†è§£ã—ã¾ã—ãŸã€ã«ãƒã‚§ãƒƒã‚¯ã‚’入れã¦ãã ã•ã„。"
+
+#: views/users/delete.thtml:84
+msgid "user_del_error_password"
+msgstr "ã“ã®ã‚¹ãƒ†ãƒƒãƒ—を進ã‚ã‚‹ã«ã¯ã€ãƒ‘スワードを正ã—ã入力ã—ã¦ãã ã•ã„。"
+
+#. %1 is a link to the amo-admins mailing list
+#: views/users/delete.thtml:91
+msgid "user_del_error_unknown"
+msgstr ""
+"アカウントã®å‰Šé™¤ä¸­ã«äºˆæœŸã›ã¬ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚%1$s ã¾ã§å•é¡ŒãŒèµ·ããŸã“ã¨ã‚’"
+"ã”報告ã„ãŸã ã‘ã‚Œã°ã€ã‚¢ã‚«ã‚¦ãƒ³ãƒˆã‚’削除ã•ã›ã¦ã„ãŸã ãã¾ã™ã€‚ã”ä¸ä¾¿ã‚’ãŠã‹ã‘ã—ã¦ç”³"
+"ã—訳ã‚ã‚Šã¾ã›ã‚“。"
+
+#: views/users/delete.thtml:110
+msgid "user_del_header_confirm_deletion"
+msgstr "アカウントã®å‰Šé™¤ã‚’確èª"
+
+#. %1 is the user's email address
+#: views/users/delete.thtml:100
+msgid "user_del_header_delete_account"
+msgstr "ユーザアカウント %1$s を削除"
+
+#: views/users/delete.thtml:50
+msgid "user_del_header_farewell"
+msgstr "ã•ã‚ˆã†ãªã‚‰ï¼"
+
+#: views/users/delete.thtml:115
+msgid "user_del_nologin"
+msgstr "今後 Mozilla Add-ons ã«ãƒ­ã‚°ã‚¤ãƒ³ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“。"
+
+#: views/users/delete.thtml:112
+msgid "user_del_permanently_removed_means"
+msgstr ""
+"「削除ã€ã‚’クリックã™ã‚‹ã¨ã€ã‚ãªãŸã®ã‚¢ã‚«ã‚¦ãƒ³ãƒˆã¯ <strong>永久ã«å‰Šé™¤</strong>ã•"
+"ã‚Œã¾ã™ã€‚ã“ã‚Œã¯ã¤ã¾ã‚Šã€"
+
+#: views/users/delete.thtml:116
+msgid "user_del_reviews_anonymized"
+msgstr ""
+"ã‚ãªãŸãŒæŠ•ç¨¿ã—ãŸãƒ¬ãƒ“ューや評価ã¯å‰Šé™¤ã•ã‚Œã¾ã›ã‚“ãŒã€ã‚ãªãŸã¨ã®é–¢é€£ä»˜ã‘ã¯å¤±ã‚ã‚Œ"
+"ã¾ã™ã€‚"
+
+#. %1 is a link to the amo-editors mailing list
+#: views/users/delete.thtml:104
+msgid "user_del_specific_problem_editors"
+msgstr ""
+"ç§ãŸã¡ãŒä½•ã‹æ‰‹åŠ©ã‘ã§ãる具体的ãªå•é¡ŒãŒã‚ã‚‹å ´åˆã¯ã€ä»Šã™ãã«ã‚¢ã‚«ã‚¦ãƒ³ãƒˆã‚’削除ã—"
+"ãªã„ã§ã€%1$s ã¾ã§ãŠå•ã„åˆã‚ã›ãã ã•ã„。å•é¡Œã‚’解決ã§ãるよã†ã€ã§ãã‚‹é™ã‚Šã®ã‚µ"
+"ãƒãƒ¼ãƒˆã‚’è¡Œã„ã¾ã™ã€‚"
+
+#: views/users/delete.thtml:130
+msgid "user_del_understand_permanent"
+msgstr "ã“ã®ã‚¹ãƒ†ãƒƒãƒ—ã¯å–り消ã›ãªã„ã“ã¨ã‚’了解ã—ã¾ã—ãŸã€‚"
+
+#: views/helpers/addons_html.php:192
+msgid "user_deleted_nickname"
+msgstr "ユーザを削除"
+
+#. %1 is the new email address
+#: views/users/edit.thtml:71
+msgid "user_edit_confirm_email_sent"
+msgstr ""
+"メールアドレスã®å¤‰æ›´ã‚’å—ã‘付ã‘ã‚‹ãŸã‚ã€%1$s ã‚ã¦ã«ç¢ºèªã®ãƒ¡ãƒ¼ãƒ«ã‚’é€ä¿¡ã—ã¾ã—ãŸã€‚"
+"変更を完了ã™ã‚‹ã«ã¯ã€ãƒ¡ãƒ¼ãƒ«æœ¬æ–‡ã«è¨˜è¼‰ã•ã‚Œã¦ã„るリンクをクリックã—ã¦ãã ã•ã„。"
+"ãã‚Œã¾ã§ã¯ã€ä»ŠãŠä½¿ã„ã®ãƒ¡ãƒ¼ãƒ«ã‚¢ãƒ‰ãƒ¬ã‚¹ã§ãƒ­ã‚°ã‚¤ãƒ³å¯èƒ½ã§ã™ã€‚"
+
+#: views/users/edit.thtml:201
+msgid "user_edit_delete_user"
+msgstr "ユーザアカウントを削除"
+
+#. This contains the email sent to users when they signed up for a new
+#. account:
+#. %1 is the confirmation URL, %2 is the current app
+#: views/users/email/confirm_plain.thtml:6
+#, php-format
+msgid "user_email_confirm_account_nopass"
+msgstr ""
+"%2$s Add-ons ã¸ã‚ˆã†ã“ã\n"
+"\n"
+"アカウントã®åˆ©ç”¨ã‚’開始ã™ã‚‹ã«ã¯èªè¨¼æ‰‹ç¶šãã‚’è¡Œã†å¿…è¦ãŒã‚ã‚Šã¾ã™ã€‚ã“ã®æ‰‹ç¶šãã¯ã€"
+"ãŠä½¿ã„ã®ãƒ¡ãƒ¼ãƒ«ã‚¢ãƒ‰ãƒ¬ã‚¹ãŒæ­£ã—ã„ã‹ã©ã†ã‹ã¨ã„ã†ã“ã¨ã¨ã€ã‚ãªãŸè‡ªèº«ã®ã‚¢ãƒ‰ãƒ¬ã‚¹ã§ã‚"
+"ã‚‹ã“ã¨ã‚’確ã‹ã‚ã‚‹ã‚‚ã®ã§ã™ã€‚\n"
+"アカウントを有効ã«ã™ã‚‹ã«ã¯ã€ä»¥ä¸‹ã®ãƒªãƒ³ã‚¯ã‚’クリックã™ã‚‹ã‹ã€ãƒªãƒ³ã‚¯ã®æ–‡å­—列全体"
+"をブラウザã®ãƒ­ã‚±ãƒ¼ã‚·ãƒ§ãƒ³ãƒãƒ¼ã«è²¼ã‚Šä»˜ã‘ã¦ãã ã•ã„。\n"
+"\n"
+"%1$s\n"
+"\n"
+"èªè¨¼æ‰‹ç¶šããŒå®Œäº†ã—ãŸã‚‰ã€ã“ã®ãƒ¡ãƒ¼ãƒ«ã¯å‰Šé™¤ã—ã¦ã‚‚構ã„ã¾ã›ã‚“。\n"
+"\n"
+"%2$s Add-ons ã«ã”登録ã„ãŸã ãã‚ã‚ŠãŒã¨ã†ã”ã–ã„ã¾ã™ã€‚\n"
+"-- %2$s Add-ons スタッフ一åŒ"
+
+#. %1 is the confirmation url, %2 is the application name
+#: views/users/email/emailchange_plain.thtml:5
+msgid "user_email_confirm_emailchange"
+msgstr ""
+"%2$s Add-ons ã«ç™»éŒ²ã•ã‚Œã¦ã„ã‚‹ã‚ãªãŸã®ãƒ¡ãƒ¼ãƒ«ã‚¢ãƒ‰ãƒ¬ã‚¹ã‚’変更ã™ã‚‹ãƒªã‚¯ã‚¨ã‚¹ãƒˆãŒè¡Œã‚"
+"ã‚Œã¾ã—ãŸã€‚\n"
+"\n"
+"æ–°ã—ã„アドレスã¸ã®å¤‰æ›´ã‚’完了ã™ã‚‹ã«ã¯ã€ä»¥ä¸‹ã®ãƒªãƒ³ã‚¯ã‚’クリックã™ã‚‹ã‹ã€ãƒªãƒ³ã‚¯ã®"
+"文字列全体をブラウザã®ãƒ­ã‚±ãƒ¼ã‚·ãƒ§ãƒ³ãƒãƒ¼ã«è²¼ã‚Šä»˜ã‘ã¦ãã ã•ã„。\n"
+"\n"
+"%1$s\n"
+"\n"
+"リクエスト㯠48 時間後ã«æ™‚間切れã¨ãªã‚Šã¾ã™ã€‚アドレスを変更ã—ãŸããªã„å ´åˆã¯ã€"
+"ã“ã®ãƒ¡ãƒ¼ãƒ«ã‚’破棄ã—ã¦ãã ã•ã„。\n"
+"\n"
+"ã”利用ã‚ã‚ŠãŒã¨ã†ã”ã–ã„ã¾ã™ã€‚\n"
+"-- %2$s Add-ons スタッフ"
+
+#: controllers/users_controller.php:168
+#, php-format
+msgid "user_email_confirm_subject"
+msgstr "%s Add-ons ã¸ã”登録ã„ãŸã ãã‚ã‚ŠãŒã¨ã†ã”ã–ã„ã¾ã™"
+
+#. This is the password reset email
+#. %1 is the pw reset URL, %2 is the application
+#: views/users/email/pwreset_plain.thtml:5
+#, php-format
+msgid "user_email_pwreset"
+msgstr ""
+"%2$s Add-ons ã®ç™»éŒ²ãƒ‘スワード変更\n"
+"\n"
+"addons.mozilla.org ã«ç™»éŒ²ã•ã‚Œã¦ã„るアカウントã®ãƒ‘スワード変更リクエストをå—ã‘"
+"付ã‘ã¾ã—ãŸã€‚パスワードを変更ã™ã‚‹ã«ã¯ã€ä»¥ä¸‹ã®ãƒªãƒ³ã‚¯ã‚’クリックã™ã‚‹ã‹ã€ãƒªãƒ³ã‚¯ã®"
+"文字列全体をブラウザã®ãƒ­ã‚±ãƒ¼ã‚·ãƒ§ãƒ³ãƒãƒ¼ã«è²¼ã‚Šä»˜ã‘ã¦ãã ã•ã„。\n"
+"\n"
+"%1$s\n"
+"\n"
+"リクエストをã—ãŸè¦šãˆãŒãªã„å ´åˆã¯ã€ã“ã®ãƒ¡ãƒ¼ãƒ«ã¯ç„¡è¦–ã—ã¦ãã ã•ã„。\n"
+"\n"
+"ã”利用ã‚ã‚ŠãŒã¨ã†ã”ã–ã„ã¾ã™ã€‚\n"
+"-- %2$s Add-ons スタッフ"
+
+#: controllers/users_controller.php:245
+#, php-format
+msgid "user_email_pwreset_subject"
+msgstr "%s Add-ons ã®ãƒ‘スワード変更"
+
+#: views/users/emailchange.thtml:50
+msgid "user_emailchange_error"
+msgstr "エラーï¼"
+
+#. %1 is the application name
+#: controllers/users_controller.php:533
+msgid "user_emailchange_subject"
+msgstr "%1$s Add-ons 登録メールアドレス変更ã®ç¢ºèª"
+
+#: views/users/emailchange.thtml:48
+msgid "user_emailchange_success"
+msgstr "æˆåŠŸï¼"
+
+#. %1 is the new email address
+#: views/users/emailchange.thtml:49
+msgid "user_emailchange_successful_description"
+msgstr ""
+"メールアドレスã®å¤‰æ›´ãŒå®Œäº†ã—ã¾ã—ãŸã€‚今後ログインã™ã‚‹éš›ã¯ %1$s ã®ã‚¢ãƒ‰ãƒ¬ã‚¹ã‚’使"
+"用ã—ã¦ã—ã¦ãã ã•ã„。"
+
+#: views/users/edit.thtml:134 views/admin/users_edit.thtml:111
+msgid "user_form_bio"
+msgstr "自分ã«ã¤ã„ã¦"
+
+#: views/users/edit.thtml:135 views/admin/users_edit.thtml:112
+msgid "user_form_bio_description"
+msgstr ""
+"ã‚‚ã—よã‚ã—ã‘ã‚Œã°ã€ã‚³ãƒŸãƒ¥ãƒ‹ãƒ†ã‚£ã«å‘ã‘ã¦è‡ªå·±ç´¹ä»‹ã—ã¦ãã ã•ã„ï¼ ã“ã“ã«å…¥åŠ›ã—ãŸæ–‡"
+"ç« ã¯ã‚ãªãŸã®ãƒ¦ãƒ¼ã‚¶æƒ…報ページã§å…¬é–‹ã•ã‚Œã¾ã™ã€‚改行ã¯ãã®ã¾ã¾ã®çŠ¶æ…‹ã§è¡¨ç¤ºã•ã‚Œã¾"
+"ã™ãŒã€HTML ã¯ä½¿ç”¨ã§ãã¾ã›ã‚“。"
+
+#: views/users/pwreset.thtml:77 views/users/register.thtml:73
+#: views/users/edit.thtml:181
+msgid "user_form_confirmpassword"
+msgstr "æ–°ã—ã„パスワードをå†å…¥åŠ›"
+
+#: views/users/edit.thtml:145
+msgid "user_form_display_collections"
+msgstr "自分ãŒä½œæˆã—ãŸã‚³ãƒ¬ã‚¯ã‚·ãƒ§ãƒ³ã‚’ユーザプロファイルã«è¡¨ç¤ºã™ã‚‹"
+
+#: views/users/edit.thtml:149
+msgid "user_form_display_collections_fav"
+msgstr "自分ã®ãŠæ°—ã«å…¥ã‚Šã®ã‚³ãƒ¬ã‚¯ã‚·ãƒ§ãƒ³ã‚’ユーザプロファイルã«è¡¨ç¤ºã™ã‚‹"
+
+#: views/users/edit.thtml:86
+#, php-format
+msgid "user_form_editprofile"
+msgstr "%s ã®ãƒ—ロフィールを編集"
+
+#: views/users/pwreset.thtml:52 views/users/login.thtml:81
+#: views/users/register.thtml:63 views/users/edit.thtml:187
+msgid "user_form_email"
+msgstr "メールアドレス"
+
+#: views/users/register.thtml:78 views/users/edit.thtml:103
+#: views/admin/users_edit.thtml:76
+msgid "user_form_firstname"
+msgstr "å (例: Taro)"
+
+#: views/users/register.thtml:94 views/users/edit.thtml:119
+#: views/admin/users_edit.thtml:91
+msgid "user_form_hideemail"
+msgstr "メールアドレスを公開ã—ãªã„"
+
+#: views/users/register.thtml:98 views/users/edit.thtml:123
+#: views/admin/users_edit.thtml:99
+msgid "user_form_homepage"
+msgstr "Web サイト URL"
+
+#: views/users/register.thtml:84 views/users/edit.thtml:109
+#: views/admin/users_edit.thtml:81
+msgid "user_form_lastname"
+msgstr "姓 (例: Yamada)"
+
+#: controllers/users_controller.php:333
+msgid "user_form_login"
+msgstr "ログイン"
+
+#: views/users/pwreset.thtml:72 views/users/edit.thtml:176
+msgid "user_form_newpassword"
+msgstr "æ–°ã—ã„パスワード"
+
+#: views/users/register.thtml:89 views/users/edit.thtml:114
+#: views/admin/users_edit.thtml:86
+msgid "user_form_nickname"
+msgstr "ニックãƒãƒ¼ãƒ "
+
+#: views/users/edit.thtml:171
+msgid "user_form_oldpassword"
+msgstr "ç¾åœ¨ã®ãƒ‘スワード"
+
+#: views/users/edit.thtml:97 views/users/edit.thtml:200
+msgid "user_form_otheractions"
+msgstr "ä»–ã®ã‚¢ã‚¯ã‚·ãƒ§ãƒ³"
+
+#: views/users/login.thtml:85 views/users/register.thtml:68
+msgid "user_form_password"
+msgstr "パスワード"
+
+#: controllers/users_controller.php:93
+msgid "user_form_registration"
+msgstr "ユーザ登録"
+
+#: views/users/login.thtml:90
+msgid "user_form_remember_me"
+msgstr "ã“ã®ã‚³ãƒ³ãƒ”ュータã«ãƒ­ã‚°ã‚¤ãƒ³æƒ…報をä¿å­˜ã™ã‚‹"
+
+#: views/admin/users_edit.thtml:95
+msgid "user_form_showsandbox"
+msgstr "サンドボックスを表示"
+
+#: views/users/edit.thtml:205
+msgid "user_form_submit_edit"
+msgstr "ä¿å­˜"
+
+#: views/users/login.thtml:93
+msgid "user_form_submit_login"
+msgstr "ログイン"
+
+#: views/users/register.thtml:113
+msgid "user_form_submit_register"
+msgstr "登録"
+
+#: views/users/info.thtml:75
+#, php-format
+msgid "user_info_usersince"
+msgstr "%s Add-ons ã¸ã®ãƒ¦ãƒ¼ã‚¶ç™»éŒ²æ—¥"
+
+#: views/users/login.thtml:102
+msgid "user_login_register_link"
+msgstr "ユーザアカウントを作æˆ"
+
+#: views/users/edit.thtml:160
+msgid "user_notifications_item_compat"
+msgstr "アドオンã®äº’æ›æ€§ (å¼·ããŠå‹§ã‚ã—ã¾ã™)"
+
+#: views/users/edit.thtml:161
+msgid "user_notifications_item_events"
+msgstr "今後開催予定ã®ã‚¤ãƒ™ãƒ³ãƒˆã¨ã‚³ãƒ³ãƒ†ã‚¹ãƒˆ"
+
+#: views/users/edit.thtml:156
+msgid "user_notifications_none_available"
+msgstr "今ã®ã¨ã“ã‚ã€ã‚ãªãŸãŒè¨­å®šå¯èƒ½ãªé€šçŸ¥ã¯ã‚ã‚Šã¾ã›ã‚“。"
+
+#: views/users/edit.thtml:158
+msgid "user_notifications_select_topics"
+msgstr ""
+"Mozilla ã§ã¯æ™‚々ã€ãƒªãƒªãƒ¼ã‚¹äºˆå®šã‚„アドオン関連イベントã«ã¤ã„ã¦ã®ãƒ¡ãƒ¼ãƒ«ã‚’ãŠé€ã‚Š"
+"ã—ã¾ã™ã€‚ã‚ãªãŸãŒèˆˆå‘³ã®ã‚るトピックを以下ã‹ã‚‰ãŠé¸ã³ãã ã•ã„。"
+
+#: views/users/edit.thtml:164
+msgid "user_notifications_specific_contact"
+msgstr ""
+"Mozilla ã¯ã€ã“ã®ã‚µã‚¤ãƒˆã§ç™»éŒ²ã•ã‚ŒãŸã‚¢ãƒ‰ã‚ªãƒ³ã«é–¢ã™ã‚‹å…·ä½“çš„ãªäº‹æŸ„ã«ã¤ã„ã¦ã€ã‚ãª"
+"ãŸã«å€‹åˆ¥ã«é€£çµ¡ã‚’å–る権利を留ä¿ã—ã¾ã™ã€‚"
+
+#: controllers/users_controller.php:543
+msgid "user_profile_edit_error"
+msgstr "変更ã•ã‚ŒãŸå†…容ã«ã‚¨ãƒ©ãƒ¼ãŒã‚ã‚Šã¾ã™ã€‚確èªã®ä¸Šã€å†åº¦é€ä¿¡ã—ã¦ãã ã•ã„。"
+
+#: controllers/users_controller.php:540
+msgid "user_profile_saved"
+msgstr "プロフィールã¯æ›´æ–°ã•ã‚Œã¾ã—ãŸã€‚"
+
+#: views/users/pwreset.thtml:65
+#, php-format
+msgid "user_pwreset_for_email"
+msgstr "%s ã®ãƒ‘スワード変更"
+
+#: controllers/users_controller.php:226
+msgid "user_pwreset_header"
+msgstr "パスワードã®å¤‰æ›´"
+
+#: views/users/login.thtml:103
+msgid "user_pwreset_link"
+msgstr "パスワードを忘れãŸå ´åˆ"
+
+#: controllers/users_controller.php:248
+msgid "user_pwreset_link_sent"
+msgstr ""
+"登録ã•ã‚Œã¦ã„るメールアドレスã«ãƒ‘スワード変更ã®ãŸã‚ã®ãƒªãƒ³ã‚¯ã‚’é€ä¿¡ã—ã¾ã—ãŸã€‚"
+
+#: controllers/users_controller.php:304
+msgid "user_pwreset_okay"
+msgstr "パスワードã®å¤‰æ›´ãŒå®Œäº†ã—ã¾ã—ãŸã€‚"
+
+#: views/users/pwreset.thtml:82
+msgid "user_pwreset_submit_changepw"
+msgstr "パスワードを変更"
+
+#: views/users/pwreset.thtml:57
+msgid "user_pwreset_submit_sendlink"
+msgstr "パスワード変更ã®ãŸã‚ã®ãƒªãƒ³ã‚¯ã‚’メールã§é€ä¿¡"
+
+#: views/users/register_complete.thtml:51
+#, php-format
+msgid "user_register_amo_link"
+msgstr "%s Add-ons"
+
+#. %1 is the user's email address, %2 is the current app
+#: views/users/activatefirst.thtml:49
+#, php-format
+msgid "user_register_click_confirm_link"
+msgstr ""
+"ã‚ãªãŸã®ãƒ¡ãƒ¼ãƒ«ã‚¢ãƒ‰ãƒ¬ã‚¹ (%1$s) ã«ã€ã‚¢ã‚«ã‚¦ãƒ³ãƒˆã‚’有効化ã™ã‚‹ãŸã‚ã®ãƒªãƒ³ã‚¯ã‚’メール"
+"ã§é€ä¿¡ã—ã¾ã—ãŸã€‚%2$s Add-ons ã«ãƒ­ã‚°ã‚¤ãƒ³ã™ã‚‹å‰ã«ã€ãã®ãƒ¡ãƒ¼ãƒ«ã«æ›¸ã‹ã‚ŒãŸãƒªãƒ³ã‚¯ã‚’"
+"クリックã—ã¦ãã ã•ã„。"
+
+#. %1 is the user's email address
+#: views/users/register_complete.thtml:49
+#, php-format
+msgid "user_register_confirm_email_sent"
+msgstr ""
+"入力ã•ã‚ŒãŸãƒ¡ãƒ¼ãƒ«ã‚¢ãƒ‰ãƒ¬ã‚¹ (%1$s) ã«ã‚¢ã‚«ã‚¦ãƒ³ãƒˆç¢ºèªã®ãŸã‚ã®ãƒ¡ãƒ¼ãƒ«ã‚’é€ä¿¡ã—ã¾ã—"
+"ãŸã€‚ログインã™ã‚‹å‰ã«ã€ãã®ãƒ¡ãƒ¼ãƒ«ã«æ›¸ã‹ã‚ŒãŸãƒªãƒ³ã‚¯ã‚’クリックã—ã¦ã€èªè¨¼æ‰‹ç¶šãã‚’"
+"è¡Œã£ã¦ãã ã•ã„。"
+
+#: views/users/activatefirst.thtml:51
+msgid "user_register_confirmation_link_text"
+msgstr "確èªãƒ¡ãƒ¼ãƒ«ã‚’å†é€ä¿¡"
+
+#: views/users/register_complete.thtml:47
+msgid "user_register_congratulations"
+msgstr "ã‚ã‚ŠãŒã¨ã†ã”ã–ã„ã¾ã™ã€‚ユーザアカウントã®ç™»éŒ²ãŒå®Œäº†ã—ã¾ã—ãŸã€‚"
+
+#: views/users/register.thtml:50
+msgid "user_register_details"
+msgstr ""
+"<p>一般ã«å…¬é–‹ã•ã‚Œã¦ã„るアドオンをダウンロードã€ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã™ã‚‹ã ã‘ã§ã‚ã‚Œã°ã€"
+"AMO ã¸ã®ãƒ¦ãƒ¼ã‚¶ç™»éŒ²ã¯<strong>å¿…è¦ã‚ã‚Šã¾ã›ã‚“</strong>。</p><p>登録ãŒå¿…è¦ãªã®ã¯"
+"以下ã®å ´åˆã®ã¿ã§ã™ã€‚</p><ul><li>アドオンã®ãƒ¬ãƒ“ューを投稿ã—ãŸã„å ´åˆ</li><li>ã‚¢"
+"ドオンã®é–‹ç™ºè€…ãŒã€è‡ªåˆ†ã®ã‚¢ãƒ‰ã‚ªãƒ³ã‚’アップロードã—㦠AMO ã«æŽ²è¼‰ã—ãŸã„å ´åˆ</"
+"li></ul><p>ユーザ登録ãŒè¡Œã‚れるã¨ã€å…¥åŠ›ã•ã‚ŒãŸã‚¢ãƒ‰ãƒ¬ã‚¹ã‚ã¦ã«ç¢ºèªã®ãŸã‚ã®ãƒ¡ãƒ¼ãƒ«"
+"ãŒé€ã‚‰ã‚Œã¾ã™ã€‚ãã“ã«æ›¸ã‹ã‚ŒãŸæ‰‹é †ã«å¾“ã£ã¦ã‚¢ã‚«ã‚¦ãƒ³ãƒˆã®ç¢ºèªã‚’è¡Œã£ã¦ãã ã•ã„。</"
+"p><p>ã”希望ãªã‚‰ã€Mozilla ã® <a href='%1$s'>法的通知</a> 㨠<a href='%2$s'>プ"
+"ライãƒã‚·ãƒ¼ãƒãƒªã‚·ãƒ¼</a> ã‚’ã”覧ã„ãŸã ã‘ã¾ã™ã€‚"
+
+#. %1 is the link to the "resend confirmation code" page
+#: views/users/activatefirst.thtml:51
+#, php-format
+msgid "user_register_resend_confirmation_link"
+msgstr ""
+"確èªãƒ¡ãƒ¼ãƒ«ãŒå±Šã‹ãªã„å ´åˆã¯ã€ãŠä½¿ã„ã®ãƒ¡ãƒ¼ãƒ«ã‚µãƒ¼ãƒ“スやメールソフトã«ã‚ˆã£ã¦ã€ã"
+"ã®ãƒ¡ãƒ¼ãƒ«ãŒã€Œè¿·æƒ‘メールã€ã‚ã‚‹ã„ã¯ã€ŒSPAMã€ã¨åˆ¤å®šã•ã‚Œã¦ã„ãªã„ã‹ã©ã†ã‹ã”確èªãã "
+"ã•ã„。必è¦ã«å¿œã˜ã¦ã€ä¸Šã«æ›¸ã‹ã‚ŒãŸãƒ¡ãƒ¼ãƒ«ã‚¢ãƒ‰ãƒ¬ã‚¹ã« %1$s ã§ãã¾ã™ã€‚"
+
+#. %1 is the link to the Mozilla Add-ons front page
+#: views/users/register_complete.thtml:51
+#, php-format
+msgid "user_register_welcome"
+msgstr "ã”登録ã‚ã‚ŠãŒã¨ã†ã”ã–ã„ã¾ã™ã€‚%1$s ã¸ã‚ˆã†ã“ãï¼"
+
+#: views/users/register.thtml:49
+msgid "user_register_welcome_header"
+msgstr "addons.mozilla.org (AMO) ã¸ã‚ˆã†ã“ãï¼"
+
+#: views/users/register.thtml:81 views/users/edit.thtml:106
+msgid "user_required_firstlast_or_nickname"
+msgstr "åã€å§“ã€ã‚‚ã—ãã¯ãƒ‹ãƒƒã‚¯ãƒãƒ¼ãƒ ã®å…¥åŠ›ãŒå¿…è¦ã§ã™ã€‚"
+
+#: views/users/edit.thtml:94 views/users/edit.thtml:142
+msgid "user_tab_collections"
+msgstr "コレクション"
+
+#: views/users/edit.thtml:95 views/users/edit.thtml:154
+msgid "user_tab_notifications"
+msgstr "通知"
+
+#: views/users/edit.thtml:93 views/users/edit.thtml:101
+msgid "user_tab_profile"
+msgstr "ユーザプロフィール"
+
+#: controllers/users_controller.php:209
+msgid "user_verified_okay"
+msgstr "èªè¨¼ãŒå®Œäº†ã—ã¾ã—ãŸã€‚"
+
+#: controllers/users_controller.php:723
+msgid "users_delete_pagetitle"
+msgstr "ユーザアカウントを削除"
+
+#: controllers/users_controller.php:414
+msgid "users_edit_pagetitle"
+msgstr "ユーザアカウントã®ç·¨é›†"
+
+#: views/users/info.thtml:71
+msgid "users_info_aboutme"
+msgstr "自分ã«ã¤ã„ã¦"
+
+#: views/users/info.thtml:96
+#, php-format
+msgid "users_info_addons_by_user"
+msgstr "%1$s ãŒä½œæˆã—ãŸã‚¢ãƒ‰ã‚ªãƒ³"
+
+#: views/users/info.thtml:51
+msgid "users_info_author_name"
+msgstr "åå‰"
+
+#: views/users/info.thtml:48
+msgid "users_info_author_profile"
+msgstr "ユーザプロフィール"
+
+#. %s is the user name
+#: views/users/info.thtml:137
+msgid "users_info_collections_by_user"
+msgstr "%s ãŒä½œæˆã—ãŸã‚³ãƒ¬ã‚¯ã‚·ãƒ§ãƒ³"
+
+#: views/users/info.thtml:66
+msgid "users_info_email"
+msgstr "メールアドレス"
+
+#: views/users/info.thtml:155
+msgid "users_info_fav_collections_by_user"
+msgstr "ãŠæ°—ã«å…¥ã‚Šã®ã‚³ãƒ¬ã‚¯ã‚·ãƒ§ãƒ³"
+
+#: views/users/info.thtml:61
+msgid "users_info_homepage"
+msgstr "ホームページ"
+
+#: views/users/info.thtml:56
+msgid "users_info_nickname"
+msgstr "ニックãƒãƒ¼ãƒ "
+
+#: controllers/users_controller.php:707
+#, php-format
+msgid "users_info_pagetitle"
+msgstr "%1$s ã®ãƒ—ロフィール"
+
+#. %1 is the user's name
+#: views/users/info.thtml:116
+msgid "users_info_reviews_by_user"
+msgstr "%s ãŒãƒ¬ãƒ“ューã—ãŸã‚¢ãƒ‰ã‚ªãƒ³"
+
+#: controllers/users_controller.php:330 controllers/users_controller.php:332
+msgid "users_login_pagetitle"
+msgstr "ログイン"
+
+#. %1 is the link to the sandbox/policy explanation page
+#. This message is for a specific add-on not found
+#: views/users/login.thtml:53
+#, php-format
+msgid "users_login_sandbox_display_warning"
+msgstr ""
+"ãŠæŽ¢ã—ã®ã‚¢ãƒ‰ã‚ªãƒ³ã¯ç¾åœ¨ã‚µãƒ³ãƒ‰ãƒœãƒƒã‚¯ã‚¹ã«ç½®ã‹ã‚Œã¦ã„ã¾ã™ã€‚Mozilla Add-ons ã«ã‚¢ã‚«"
+"ウントをãŠæŒã¡ãªã‚‰ã€ãƒ­ã‚°ã‚¤ãƒ³ã—ã¦ã„ãŸã ãã‹ã€<a href=\"%1$s\">サンドボックス関"
+"ã™ã‚‹è©³ç´°</a> ã‚’ã”覧ãã ã•ã„。"
+
+#. %1 is the link to the sandbox/policy explanation page
+#. This message is for any given sandbox-related page not found
+#: views/users/login.thtml:56
+#, php-format
+msgid "users_login_sandbox_page_warning"
+msgstr ""
+"ãŠæŽ¢ã—ã®ã‚¢ãƒ‰ã‚ªãƒ³ã¯ç¾åœ¨ã‚µãƒ³ãƒ‰ãƒœãƒƒã‚¯ã‚¹ã«ç½®ã‹ã‚Œã¦ã„ã¾ã™ã€‚Mozilla Add-ons ã«ã‚¢ã‚«"
+"ウントをãŠæŒã¡ãªã‚‰ã€ãƒ­ã‚°ã‚¤ãƒ³ã—ã¦ã„ãŸã ãã‹ã€<a href=\"%1$s\">サンドボックス関"
+"ã™ã‚‹è©³ç´°</a> ã‚’ã”覧ãã ã•ã„。"
+
+#: controllers/users_controller.php:223 controllers/users_controller.php:225
+msgid "users_pwreset_pagetitle"
+msgstr "パスワードã®å¤‰æ›´"
+
+#: controllers/users_controller.php:90 controllers/users_controller.php:92
+msgid "users_register_pagetitle"
+msgstr "ユーザ登録"
+
+#. %1$s is an addon name, like <a>Firebug</a>
+#. %2$s is a version number, like <a>1.2</a>
+#: views/versions/license.thtml:52
+msgid "versions_license_header_source"
+msgstr "%1$s %2$s ã®ã‚½ãƒ¼ã‚¹ã‚³ãƒ¼ãƒ‰ãƒ©ã‚¤ã‚»ãƒ³ã‚¹"
+
+#: views/addons/category_landing.thtml:147
+msgid "view_recently_added"
+msgstr "最近追加ã•ã‚ŒãŸã‚¢ãƒ‰ã‚ªãƒ³ã‚’ã™ã¹ã¦è¦‹ã‚‹"
+
+#: views/addons/category_landing.thtml:161
+msgid "view_top_downloads"
+msgstr "人気ã®ã‚¢ãƒ‰ã‚ªãƒ³ã‚’ã™ã¹ã¦è¦‹ã‚‹"
+
+#: views/addons/category_landing.thtml:175
+msgid "view_top_rated"
+msgstr "評価ã®é«˜ã„アドオンをã™ã¹ã¦è¦‹ã‚‹"
+
+#~ msgid "addon_slider_tooltip_next"
+#~ msgstr "次ã®ã‚¢ãƒ‰ã‚ªãƒ³"
+
+#~ msgid "addon_slider_tooltip_previous"
+#~ msgstr "å‰ã®ã‚¢ãƒ‰ã‚ªãƒ³"
+
+#~ msgid "addons_display_version_history"
+#~ msgstr "ã™ã¹ã¦ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³å±¥æ­´"
+
+#~ msgid "addons_home_newest_header"
+#~ msgstr "最近公開ã•ã‚ŒãŸã‚¢ãƒ‰ã‚ªãƒ³:"
+
+#~ msgid "addons_home_popular_header"
+#~ msgstr "人気ã®ã‚¢ãƒ‰ã‚ªãƒ³"
+
+#~ msgid "addons_home_recommended_header"
+#~ msgstr "ãŠã™ã™ã‚ã®ã‚¢ãƒ‰ã‚ªãƒ³"
+
+#~ msgid "addons_home_updated_header"
+#~ msgstr "最近更新ã•ã‚ŒãŸã‚¢ãƒ‰ã‚ªãƒ³:"
+
+#~ msgid "addons_home_view_all"
+#~ msgstr "ã™ã¹ã¦è¦‹ã‚‹"
+
+#~ msgid "category_extra_allrecommended"
+#~ msgstr "ãŠã™ã™ã‚"
+
+#~ msgid "category_extra_highestrated"
+#~ msgstr "評価順"
+
+#~ msgid "category_extra_lastupdated"
+#~ msgstr "最終更新順"
+
+#~ msgid "category_extra_mostpopular"
+#~ msgstr "人気順"
+
+#~ msgid "collections_detail_js_loading"
+#~ msgstr "読ã¿è¾¼ã¿ä¸­"
+
+#~ msgid "collections_detail_more_info"
+#~ msgstr "詳細を表示"
+
+#~ msgid "devcp_addon_status_criteria_review"
+#~ msgstr "ユーザã«ã‚ˆã‚‹ãƒ¬ãƒ“ューãŒå¿…è¦ã§ã™ã€‚(外部サイトã®ãƒ¬ãƒ“ューã§ã‚‚å¯)"
+
+#~ msgid "editors_submissiontype_new"
+#~ msgstr "æ–°è¦"
+
+#~ msgid "editors_submissiontype_updated"
+#~ msgstr "æ›´æ–°"
+
+#~ msgid "editors_th_addon_age"
+#~ msgstr "公開ã‹ã‚‰ã®æœŸé–“"
+
+#~ msgid "editors_th_addontypes"
+#~ msgstr "アドオンã®ç¨®é¡ž"
+
+#~ msgid "editors_th_applications"
+#~ msgstr "アプリケーション"
+
+#~ msgid "editors_th_platforms"
+#~ msgstr "プラットフォーム"
+
+#~ msgid "editors_th_submissiontypes"
+#~ msgstr "申請ã®ç¨®é¡ž"
+
+#~ msgid "forum_save"
+#~ msgstr "ä¿å­˜"
+
+#~ msgid "home"
+#~ msgstr "ホーム"
+
+#~ msgid "nav_category_plugins"
+#~ msgstr "プラグイン"
+
+#~ msgid "pagination_page_number_title"
+#~ msgstr "ç¾åœ¨ %2$s ページ中 %1$s ページ目を表示ã—ã¦ã„ã¾ã™"
+
+#~ msgid "search_matching_addons_number"
+#~ msgid_plural "search_matching_addons_number"
+#~ msgstr[0] "%s 個ã®ã‚¢ãƒ‰ã‚ªãƒ³"
+#~ msgstr[1] "%s 個ã®ã‚¢ãƒ‰ã‚ªãƒ³"
diff --git a/site/app/locale/ja/images/sandbox-review.png b/site/app/locale/ja/images/sandbox-review.png
new file mode 100644
index 0000000..fba3f46
--- /dev/null
+++ b/site/app/locale/ja/images/sandbox-review.png
Binary files differ
diff --git a/site/app/locale/ja/pages/about.thtml b/site/app/locale/ja/pages/about.thtml
new file mode 100644
index 0000000..2c60836
--- /dev/null
+++ b/site/app/locale/ja/pages/about.thtml
@@ -0,0 +1,27 @@
+<h2>addons.mozilla.org ã¨ã¯ï¼Ÿ</h2>
+<p>addons.mozilla.org (AMO) ã¯ã€Mozilla アプリケーションã®ãŸã‚ã®ã‚¢ãƒ‰ã‚ªãƒ³ã‚’紹介ã—ã¦ã„ã‚‹ Mozilla ã®å…¬å¼ã‚µã‚¤ãƒˆã§ã™ã€‚アドオンをインストールã™ã‚‹ã¨ã€Firefox ã‚„ Thunderbirdã€SeaMonkeyã€Sunbird ã«æ–°æ©Ÿèƒ½ã‚’追加ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚AMO ã§ã¯ã€ã‚ãªãŸã®ã‚¤ãƒ³ã‚¿ãƒ¼ãƒãƒƒãƒˆã®ä½¿ã„方を変ãˆã‚‹ä½•åƒã‚‚ã®ã‚¢ãƒ‰ã‚ªãƒ³ã‚’ã€è‡ªç”±ã«é–²è¦§ã€ãƒ€ã‚¦ãƒ³ãƒ­ãƒ¼ãƒ‰ã§ãã¾ã™ã€‚</p>
+
+<h2>ã“れらã®ã‚¢ãƒ‰ã‚ªãƒ³ã¯èª°ãŒä½œã£ã¦ã„ã‚‹ã®ã§ã™ã‹ï¼Ÿ</h2>
+<p>個人ã®æ„›å¥½å®¶ã‹ã‚‰å¤§ä¼æ¥­ã¾ã§ã€å¤šæ•°ã®ã‚¢ãƒ‰ã‚ªãƒ³é–‹ç™ºè€…ã«ã‚ˆã£ã¦ä½œæˆã•ã‚Œã¦ã„ã¾ã™ã€‚公開ã•ã‚Œã¦ã„るアドオンã¯ã™ã¹ã¦ã€ãƒªãƒªãƒ¼ã‚¹å‰ã«ç†±å¿ƒãªãƒœãƒ©ãƒ³ãƒ†ã‚£ã‚¢ã®ã‚¹ã‚¿ãƒƒãƒ•ã«ã‚ˆã£ã¦ãƒ¬ãƒ“ューã•ã‚Œã¦ã„ã¾ã™ã€‚実験的ãªã‚¢ãƒ‰ã‚ªãƒ³ã¯ã€å®Ÿé¨“çš„ã§ã‚ã‚‹ã“ã¨ãŒæ˜Žè¨˜ã•ã‚Œã¦ãŠã‚Šã€ãƒ¬ãƒ“ューをå—ã‘ã¦ã„ã¾ã›ã‚“。</p>
+
+<h2>AMO ã®æœ€æ–°æƒ…報を入手ã™ã‚‹ã«ã¯ï¼Ÿ</h2>
+<p>ç§ãŸã¡ã® <a href="http://blog.mozilla.com/addons/">ブログ</a> ã¯æ—¥é ƒã‹ã‚‰æ›´æ–°ã•ã‚Œã¦ãŠã‚Šã€æ™‚々コミュニティ全体ã‹ã‚‰ã®æŠ•ç¨¿ã‚’å–り上ã’ã‚‹ã“ã¨ã‚‚ã‚ã‚Šã¾ã™ã€‚月刊ã§é…ä¿¡ã•ã‚Œã¦ã„ã‚‹ <a href="/newsletter">ニュースレター</a> も購読ã§ãã¾ã™ã€‚</p>
+
+<h2>ãã‚Œã¯ã™ã”ã„ï¼ è‡ªåˆ†ã‚‚å‚加ã™ã‚‹ã«ã¯ã©ã†ã™ã‚Œã°ã„ã„ã§ã™ã‹ï¼Ÿ</h2>
+<p>AMO ã«ã¯æ§˜ã€…ãªæ–¹æ³•ã§å‚加ã§ãã¾ã™ã€‚</p>
+<ul>
+ <li><a href="https://wiki.mozilla.org/AMO:Editors/Applying">エディタã«ãªã‚‹</a> &mdash; AMO ã®ã‚¨ãƒ‡ã‚£ã‚¿ã¯ã€æŠ€è¡“çš„ãªãƒãƒƒã‚¯ã‚°ãƒ©ã‚¦ãƒ³ãƒ‰ã‚’æŒã¡ã€ã‚³ãƒ¼ãƒ‰ã®å“質や安定性ã®è¦³ç‚¹ã‹ã‚‰ã‚¢ãƒ‰ã‚ªãƒ³ã‚’レビューã—ã¦ã„ã‚‹ AMO ファンã®çš†ã•ã‚“ã§ã™ã€‚</li>
+ <li><a href="https://developer.mozilla.org/ja/">自分ã§ã‚¢ãƒ‰ã‚ªãƒ³ã‚’作る</a> &mdash; AMO ã¯ç„¡å„Ÿã®ãƒ›ã‚¹ãƒ†ã‚£ãƒ³ã‚°ã¨æ›´æ–°ã‚µãƒ¼ãƒ“スをæä¾›ã—ã¦ãŠã‚Šã€å¹…広ã„ユーザã«ãƒªãƒ¼ãƒã™ã‚‹ã®ã«å½¹ç«‹ã£ã¦ã„ã¾ã™ã€‚</li>
+ <li>å‹é”ã«çŸ¥ã‚‰ã›ã‚‹ &mdash; Firefox ユーザã®è¼ªã‚’広ã’ã¦ã€è‡ªåˆ†ãŒã©ã®ã‚¢ãƒ‰ã‚ªãƒ³ã‚’使ã£ã¦ã„ã‚‹ã‹æ•™ãˆã¦ã‚ã’ã¾ã—ょã†ã€‚<a href="http://www.spreadfirefox.com/">Spread Firefox</a> ã®ã‚µã‚¤ãƒˆã‚‚ãœã²ã”覧ãã ã•ã„。</li>
+ <li>ãƒã‚°ã‚’報告ã—ã¦ä¿®æ­£ã™ã‚‹ &mdash; <a href="https://bugzilla.mozilla.org/buglist.cgi?quicksearch=addons">Bugzilla</a> ã«ã¯ AMO ã«é–¢ã™ã‚‹æ—¢çŸ¥ã®ãƒã‚°ãŒã™ã¹ã¦ç™»éŒ²ã•ã‚Œã¦ã„ã¾ã™ã€‚ã¾ã ç™ºè¦‹ã•ã‚Œã¦ã„ãªã„ãƒã‚°ãŒã‚ã£ãŸã‚‰ç™»éŒ²ã—ã¦ã€ãœã²ãƒ‘ッãƒã‚’æä¾›ã—ã¦ãã ã•ã„。</li>
+</ul>
+
+<h2>質å•ãŒã‚ã‚Šã¾ã™ã€‚</h2>
+<p>ã¾ãšã¯ <a href="/pages/faq">よãã‚ã‚‹è³ªå• (<abbr title="Frequently Asked Questions">FAQ</abbr>)</a> ã®ãƒšãƒ¼ã‚¸ã‚’ã”覧ãã ã•ã„。ã“ã“ã§ç­”ãˆã‚’見ã¤ã‘られãªã‹ã£ãŸå ´åˆã¯ã€ã“ã®ãƒšãƒ¼ã‚¸ã®ä¸€ç•ªä¸‹ã«æ›¸ã‹ã‚Œã¦ã„る連絡先ã¸ãŠå•ã„åˆã‚ã›ãã ã•ã„。特定ã®ã‚¢ãƒ‰ã‚ªãƒ³ã«é–¢ã™ã‚‹è³ªå•ã¯ã€å„アドオンã®å…¬é–‹ãƒšãƒ¼ã‚¸ã«è¨˜è¼‰ã•ã‚Œã¦ã„る連絡先ã¸ãŠé¡˜ã„ã—ã¾ã™ã€‚</p>
+
+<h2>ãŠå•ã„åˆã‚ã›</h2>
+<dl>
+ <dt><abbr title="Internet Relay Chat">IRC</abbr> (訳注: 以下ã®ãƒãƒ£ãƒ³ãƒãƒ«ã®ä½¿ç”¨è¨€èªžã¯è‹±èªžã§ã™)</dt>
+ <dd>irc.mozilla.org ã® <a href="irc://irc.mozilla.org/#addons">#addons</a> &mdash; 一般的ãªè³ªå•ã‚„レビューã«é–¢ã™ã‚‹ãŠå•ã„åˆã‚ã›</dd>
+ <dd>irc.mozilla.org ã® <a href="irc://irc.mozilla.org/#amo">#amo</a> &mdash; AMO ã®é‹å–¶ã‚„開発ã«é–¢ã™ã‚‹ãŠå•ã„åˆã‚ã›</dd>
+</dl>
diff --git a/site/app/locale/ja/pages/compatibility_developer_tips.thtml b/site/app/locale/ja/pages/compatibility_developer_tips.thtml
new file mode 100644
index 0000000..f77df93
--- /dev/null
+++ b/site/app/locale/ja/pages/compatibility_developer_tips.thtml
@@ -0,0 +1,6 @@
+<ul class="tips">
+ <li>%s ã«å‘ã‘ãŸã‚¢ãƒ‰ã‚ªãƒ³ã®æ›´æ–°ã«é–¢ã™ã‚‹æƒ…å ±ã¯ã€ã“ã® <a href="https://developer.mozilla.org/ja/Updating_extensions_for_%s">Mozilla Developer Center ã®è¨˜äº‹</a> ã§ç¢ºèªã§ãã¾ã™ã€‚</li>
+ <li>%s ã§è¡Œã‚ã‚ŒãŸå¤‰æ›´å…¨èˆ¬ã«é–¢ã™ã‚‹æƒ…å ±ã¯ã€<a href="https://developer.mozilla.org/ja/%s_for_developers">ã“ã®è¨˜äº‹</a> ã‚’å‚ç…§ã—ã¦ãã ã•ã„。</li>
+ <li><a href="https://addons.mozilla.org/newsletter">about:addons ニュースレター</a> ã‚„ <a href="http://blog.mozilla.com/addons/">Mozilla Add-ons ブログ</a> を購読ã™ã‚Œã°ã€ã‚ˆã‚Šè©³ã—ã„情報を入手ã§ãã¾ã™ã€‚</li>
+ <li>ã‚ãªãŸã®ã‚¢ãƒ‰ã‚ªãƒ³ãŒã‚³ãƒ¼ãƒ‰ã«å¤‰æ›´ã‚’加ãˆãªãã¦ã‚‚互æ›æ€§ã‚’確ä¿ã§ãã€ãれ㌠Mozilla Add-ons ã«ç™»éŒ²ã•ã‚Œã¦ã„ã‚‹å ´åˆã¯ã€<a href="%s">Developer Tools</a> を利用ã™ã‚‹ã‹ã€ä»¥ä¸‹ã§ã‚¹ãƒ†ãƒ¼ã‚¿ã‚¹ã‚’表示ã™ã‚‹ã“ã¨ã§ã€æ–°ãŸã«ã‚¢ãƒƒãƒ—ロードを行ã‚ãªãã¦ã‚‚互æ›æ€§ã®ã‚ã‚‹ maxVersion をオンラインã§æ›´æ–°ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚</li>
+</ul> \ No newline at end of file
diff --git a/site/app/locale/ja/pages/compatibility_user_tips.thtml b/site/app/locale/ja/pages/compatibility_user_tips.thtml
new file mode 100644
index 0000000..86c79dd
--- /dev/null
+++ b/site/app/locale/ja/pages/compatibility_user_tips.thtml
@@ -0,0 +1,6 @@
+<ul class="tips">
+ <li>多ãã®ã‚¢ãƒ‰ã‚ªãƒ³ã¯ã€ã‚³ãƒ¼ãƒ‰ã«ä¸€åˆ‡å¤‰æ›´ã‚’加ãˆãªãã¦ã‚‚ %s ã§è¡Œã‚ã‚ŒãŸå¤‰æ›´ã«å¯¾å¿œã§ãã¾ã™ãŒã€ä¸€éƒ¨ã®ã‚¢ãƒ‰ã‚ªãƒ³ã¯ã€ã‚¹ãƒ ãƒ¼ã‚ºã«æ›´æ–°ã§ãるよã†ã€ä½œè€…ã«ã‚ˆã‚‹è‹¥å¹²ã®ä½œæ¥­ãŒå¿…è¦ã¨ãªã‚Šã¾ã™ã€‚ãŸã„ã¦ã„ã®ã‚¢ãƒ‰ã‚ªãƒ³ä½œè€…ã¯è¶£å‘³ã§è‡ªä¸»çš„ã«ã‚¢ãƒ‰ã‚ªãƒ³ã‚’æä¾›ã—ã¦ã„ã¾ã™ã®ã§ã€ã©ã†ã‹æ›´æ–°ãŒå®Œäº†ã™ã‚‹ã¾ã§æˆ‘æ…¢ã—ã¦ãã ã•ã„。</li>
+ <li>Mozilla ã§ã¯ã€äº’æ›æ€§ãƒã‚§ãƒƒã‚¯ã®è¨­å®šã‚’無効化ã™ã‚‹ã“ã¨ã¯æŽ¨å¥¨ã§ãã¾ã›ã‚“。ã“ã®è¨­å®šã‚’無効化ã—ãŸå ´åˆã€%s ã®èµ·å‹•ã«æ·±åˆ»ãªå•é¡ŒãŒç™ºç”Ÿã—ãŸã‚Šã€%s ã®æ–°ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã¨äº’æ›æ€§ã®ãªã„拡張機能ãŒå¼·åˆ¶çš„ã«åˆ©ç”¨ã•ã‚ŒãŸå ´åˆã€ãƒ‡ãƒ¼ã‚¿ã®æ失ã«ã¤ãªãŒã‚‹å ´åˆãŒã‚ã‚Šã¾ã™ã€‚</li>
+ <li>%s ã®ãƒªãƒªãƒ¼ã‚¹å¾Œã‚‚ãŠä½¿ã„ã®æ‹¡å¼µæ©Ÿèƒ½ã®äº’æ›æ€§ãŒæ›´æ–°ã•ã‚Œãªã„å ´åˆã¯ã€ãã®ã‚¢ãƒ‰ã‚ªãƒ³ã®é…布サイトã‹ä½œè€…ã®ã‚µã‚¤ãƒˆã§å¯¾å¿œçŠ¶æ³ã‚’確èªã—ã¦ãã ã•ã„。</li>
+ <li>ã‚ã‚‹ã„ã¯ã€%s ã«å¯¾å¿œæ¸ˆã¿ã§åŒã˜ã‚ˆã†ãªæ©Ÿèƒ½ã‚’æŒã£ãŸä»–ã®ã‚¢ãƒ‰ã‚ªãƒ³ã‚’ <a href="%s">%s Add-ons</a> ã®ã‚µã‚¤ãƒˆã§æŽ¢ã™ã“ã¨ã‚‚ã§ãã¾ã™ã€‚</li>
+</ul> \ No newline at end of file
diff --git a/site/app/locale/ja/pages/error404.thtml b/site/app/locale/ja/pages/error404.thtml
new file mode 100644
index 0000000..40fbd9f
--- /dev/null
+++ b/site/app/locale/ja/pages/error404.thtml
@@ -0,0 +1,12 @@
+<h1>申ã—訳ã‚ã‚Šã¾ã›ã‚“ãŒã€ãŠæŽ¢ã—ã®ãƒšãƒ¼ã‚¸ã¯è¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ã§ã—ãŸã€‚</h1>
+<p>è¦æ±‚ã•ã‚ŒãŸãƒšãƒ¼ã‚¸ã¾ãŸã¯ãƒ•ã‚¡ã‚¤ãƒ«ã¯è¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ã§ã—ãŸã€‚å¤ã„リンクをクリックã•ã‚ŒãŸã‹ã€é–“é•ã£ãŸã‚¢ãƒ‰ãƒ¬ã‚¹ã‚’入力ã•ã‚ŒãŸå¯èƒ½æ€§ãŒã‚ã‚Šã¾ã™ã€‚</p>
+<ul>
+<li>アドレスを直接入力ã•ã‚ŒãŸå ´åˆã¯ã€ã‚‚ã†ä¸€åº¦ã‚¹ãƒšãƒ«ã‚’確èªã—ã¦ãã ã•ã„。</li>
+<li>ã©ã“ã‹ã®ãƒªãƒ³ã‚¯ã‚’クリックã—ã¦ã“ã®ãƒšãƒ¼ã‚¸ã«ãŸã©ã‚Šç€ã‹ã‚ŒãŸå ´åˆã¯ã€<a href="mailto:webmaster@mozilla.com" title="Page Not Found on Mozilla.com">webmaster@mozilla.com</a> ã¾ã§ã”連絡ãã ã•ã„。ã©ã®ãƒšãƒ¼ã‚¸ã‹ã‚‰æ¥ã¦ä½•ã‚’探ã—ã¦ã„ã‚‹ã®ã‹ã‚’ãŠçŸ¥ã‚‰ã›ãã ã•ã„。ã§ãã‚‹é™ã‚Šä¿®æ­£ã•ã›ã¦ã„ãŸã ãã¾ã™ã€‚</li>
+</ul>
+<p>ã¾ãŸã€ä»¥ä¸‹ã®ãƒšãƒ¼ã‚¸ãŒãŠå½¹ã«ç«‹ã¤ã‹ã‚‚ã—ã‚Œã¾ã›ã‚“。</p>
+<ul>
+<li><a href="%1$s">人気ã®ã‚¢ãƒ‰ã‚ªãƒ³ä¸€è¦§</a> ã«èˆˆå‘³ãŒãŠã‚ã‚Šã§ã™ã‹ï¼Ÿ</li>
+<li>アドオンをãŠæŽ¢ã—ã§ã™ã‹ï¼Ÿ <a href="%2$s">検索ページ</a> ã‹ä¸‹ã®æ¤œç´¢ãƒ•ã‚©ãƒ¼ãƒ ã‚’ã”利用ãã ã•ã„。</li>
+<li>ã©ã†ã™ã‚Œã°è‰¯ã„ã‹è¿·ã‚ã‚ŒãŸå ´åˆã¯ã€<a href="%3$s">アドオンã®ãƒˆãƒƒãƒ—ページ</a> ã‹ã‚‰ã‚µã‚¤ãƒˆã‚’ã”利用ãã ã•ã„。</li>
+</ul>
diff --git a/site/app/locale/ja/pages/faq.thtml b/site/app/locale/ja/pages/faq.thtml
new file mode 100644
index 0000000..8fe6cb1
--- /dev/null
+++ b/site/app/locale/ja/pages/faq.thtml
@@ -0,0 +1,56 @@
+<h1>よãã‚ã‚‹è³ªå• (FAQ)</h1>
+
+<p>ã“ã® <a href="https://addons.mozilla.org/ja/">Mozilla Add-ons サイト</a> ã«é–¢ã™ã‚‹ FAQ ã¯ã€ç¾æ™‚点ã§ã¾ã  <a href="http://support.mozilla.com/ja/kb/">Firefox サãƒãƒ¼ãƒˆ</a> ã®ã‚µã‚¤ãƒˆã«æŽ²è¼‰ã•ã‚Œã¦ã„ãªã„ã€ã„ãã¤ã‹ã®ãƒˆãƒ”ックã«ã¤ã„ã¦èª¬æ˜Žã—ã¾ã™ã€‚Firefox サãƒãƒ¼ãƒˆã®ã‚µã‚¤ãƒˆã«ã¯ã€<a href="http://support.mozilla.com/ja/kb/Customizing+Firefox+with+add-ons">アドオン㧠Firefox を活用ã™ã‚‹</a> ã¨ã„ã£ãŸå…¥é–€ã‚¬ã‚¤ãƒ‰ã®ä»–ã€æ¬¡ã®ã‚ˆã†ãªè¨˜äº‹ãŒæŽ²è¼‰ã•ã‚Œã¦ã„ã¾ã™ã€‚</p>
+
+<ul>
+ <li><a href="http://support.mozilla.com/ja/kb/Unable+to+install+add-ons">アドオンã®ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«</a>ã€<a href="http://support.mozilla.com/ja/kb/Troubleshooting+plugins">プラグイン</a>ã€<a href="http://support.mozilla.com/ja/kb/Troubleshooting+extensions+and+themes">一般的ãªå•é¡Œ</a> ã®ãƒˆãƒ©ãƒ–ルシューティング</li>
+ <li><a href="http://support.mozilla.com/ja/kb/Uninstalling+add-ons">アドオンã®å‰Šé™¤</a> 㨠<a href="http://support.mozilla.com/ja/kb/Cannot+uninstall+an+add-on">削除ã«é–¢ã™ã‚‹ãƒˆãƒ©ãƒ–ルシューティング</a></li>
+ <li><a href="http://support.mozilla.com/ja/kb/Gray+bar+below+the+status+bar">å•é¡Œã®ã‚るアドオンã¸ã®å¯¾å¿œ (ステータスãƒãƒ¼ã®ä¸‹ã«ã‚°ãƒ¬ãƒ¼ã®é ˜åŸŸãŒç¾ã‚Œã‚‹)</a></li>
+</ul>
+
+<p></p>
+
+<h2>アドオンã«é–¢ã™ã‚‹è³ªå•</h2>
+<dl>
+<dt>アドオンã¨ã¯ä½•ã§ã™ã‹ï¼Ÿ</dt>
+<dd>アドオンã¯ã€æ¨™æº–ã®ã‚¢ãƒ—リケーションã«ã¯å«ã¾ã‚Œã¦ã„ãªã„機能ã®è¿½åŠ ã‚’å¯èƒ½ã«ã™ã‚‹ã‚‚ã®ã§ã™ã€‚テーマã¯ã€æ©Ÿèƒ½çš„ãªå¤‰æ›´ã¯è¡Œã„ã¾ã›ã‚“ãŒã€è¦‹ãŸç›®ã«å¤‰æ›´ã‚’加ãˆã¾ã™ã€‚検索エンジンã¨ã‚¹ãƒšãƒ«ãƒã‚§ãƒƒã‚¯è¾žæ›¸ãƒ»è¨€èªžãƒ‘ックã¯ã€æ¤œç´¢ã‚¨ãƒ³ã‚¸ãƒ³ã‚„言語サãƒãƒ¼ãƒˆã‚’追加ã—ã¾ã™ã€‚拡張機能ã¯ã€ã‚ˆã‚Šåºƒç¯„ãªæ©Ÿèƒ½ã‚’ブラウザã«è¿½åŠ ã™ã‚‹ã‚‚ã®ã§ã€ã‚·ãƒ³ãƒ—ルãªãƒ„ールãƒãƒ¼ã‹ã‚‰ã€æ§˜ã€…ãªæ–°æ©Ÿèƒ½ã‚’æä¾›ã™ã‚‹ã‚‚ã®ã¾ã§ã€å¤šãã®ç¨®é¡žãŒã‚ã‚Šã¾ã™ã€‚</dd>
+
+<dt>アドオンã®ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã¯ç°¡å˜ã§ã™ã‹ï¼Ÿ</dt>
+<dd>ã¯ã„。アドオンã®ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã¯éžå¸¸ã«ç°¡å˜ã§ã™ã€‚アドオンã¯é€šå¸¸ã€ä¸€èˆ¬çš„ãªã‚¢ãƒ—リケーションよりã¯ã‚‹ã‹ã«ã‚µã‚¤ã‚ºãŒå°ã•ã„ãŸã‚ã€ã”ã短時間ã§ãƒ€ã‚¦ãƒ³ãƒ­ãƒ¼ãƒ‰ã§ãã¾ã™ã€‚ã‚‚ã—æ°—ã«å…¥ã‚‰ãªã„å ´åˆã¯ã€ç°¡å˜ã«å‰Šé™¤ã—ãŸã‚Šç„¡åŠ¹åŒ–ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚ã¾ãŸã€ãŠä½¿ã„ã®ã‚¢ãƒ‰ã‚ªãƒ³ã®æ–°ã—ã„ãƒãƒ¼ã‚¸ãƒ§ãƒ³ãŒå…¬é–‹ã•ã‚ŒãŸå ´åˆã¯ã€Firefox ã‹ã‚‰é€šçŸ¥ãŒè¡¨ç¤ºã•ã‚Œã€ãƒ¯ãƒ³ã‚¯ãƒªãƒƒã‚¯ã§æ›´æ–°ã§ãã¾ã™ã€‚</dd>
+
+<dt>アドオンã¯ã©ã®ã‚ˆã†ã«ç®¡ç†ã™ã‚‹ã®ã§ã™ã‹ï¼Ÿ</dt>
+<dd>Firefox ã§ã¯ã€[ツール] メニューã‹ã‚‰ [アドオン] ã‚’é¸æŠžã™ã‚‹ã¨ã€æ‹¡å¼µæ©Ÿèƒ½ã‚„テーマを管ç†ã§ãã¾ã™ã€‚ãŠä½¿ã„ã®æ‹¡å¼µæ©Ÿèƒ½ã«ç‰¹åˆ¥ãªã‚ªãƒ—ションãŒã‚ã‚‹å ´åˆã¯ã€ã“ã®ã‚¢ãƒ‰ã‚ªãƒ³ãƒžãƒãƒ¼ã‚¸ãƒ£ã®æ‹¡å¼µæ©Ÿèƒ½ã‚¿ãƒ–ã‹ã‚‰è¨­å®šã‚’è¡Œã†ã“ã¨ãŒã§ãã¾ã™ã€‚ã¾ãŸã€ã‚¢ãƒ‰ã‚ªãƒ³ã®ç„¡åŠ¹åŒ–や削除もã“ã“ã§è¡Œãˆã¾ã™ã€‚スペルãƒã‚§ãƒƒã‚¯è¾žæ›¸ã¯æ‹¡å¼µæ©Ÿèƒ½ã¨ã—ã¦ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã•ã‚Œã¾ã™ã€‚検索エンジンã¯æ¤œç´¢ãƒãƒ¼ä¸Šã§ç®¡ç†ã§ãã¾ã™ã€‚</dd>
+
+<dt>アドオンをインストールã™ã‚‹ã¨ Firefox ãŒé…ããªã‚Šã¾ã™ã‹ï¼Ÿ</dt>
+<dd>ã»ã¨ã‚“ã©ã®ã‚¢ãƒ‰ã‚ªãƒ³ã¯ã€ä½“æ„Ÿçš„ã«åˆ†ã‹ã‚‹ã»ã© Firefox ã®é€Ÿåº¦ã‚’低下ã•ã›ã‚‹ã“ã¨ã¯ã‚ã‚Šã¾ã›ã‚“。ã—ã‹ã—ã€ã‚¢ãƒ‰ã‚ªãƒ³ã¯ã‚¢ãƒ—リケーションã§ã™ã®ã§ã€ã‚·ã‚¹ãƒ†ãƒ ã®è¨­å®šã«ã‚ˆã£ã¦ã¯ Firefox ã®ãƒ‘フォーマンスã«å½±éŸ¿ã™ã‚‹å ´åˆãŒã‚ã‚Šã¾ã™ã€‚ã‚るアドオンãŒãŠä½¿ã„ã®ãƒžã‚·ãƒ³ã§ Firefox ã®å‹•ä½œã«å½±éŸ¿ã‚’åŠã¼ã—ã¦ã„ã‚‹ã¨æ€ã‚れる場åˆã¯ã€ãれを無効化ã—ã¦ã¿ã¦ãã ã•ã„。</dd>
+
+<dt>ãªãœã‚¢ãƒ‰ã‚ªãƒ³ã‚’無効化ã™ã‚‹ã®ã§ã™ã‹ï¼Ÿ</dt>
+<dd>アドオンを無効化ã™ã‚‹ã¨ã€Firefox ã‚’èµ·å‹•ã™ã‚‹ã¨ãã«èª­ã¿è¾¼ã¾ã‚Œãªããªã‚Šã¾ã™ãŒã€ã‚¢ãƒ‰ã‚ªãƒ³ã‚„設定ãã®ã‚‚ã®ã¯ä¸€åˆ‡å‰Šé™¤ã•ã‚Œã¾ã›ã‚“。å†åº¦ã‚¢ãƒ‰ã‚ªãƒ³ã‚’有効化ã™ã‚Œã°ã€ç„¡åŠ¹åŒ–å‰ã®çŠ¶æ…‹ã«æˆ»ã™ã“ã¨ãŒã§ãã¾ã™ã€‚アドオンを削除ã›ãšã«ä½¿ç”¨ã‚’中止ã—ãŸã„å ´åˆã¯ã€ç„¡åŠ¹åŒ–ã™ã‚‹ã®ãŒè‰¯ã„ã§ã—ょã†ã€‚</dd>
+
+<dt>インストールã—ãŸæ‹¡å¼µæ©Ÿèƒ½ã‚„テーマã¯ã©ã†ã™ã‚Œã°ãƒãƒƒã‚¯ã‚¢ãƒƒãƒ—ã§ãã¾ã™ã‹ï¼Ÿ</dt>
+<dd>プロファイルディレクトリをãƒãƒƒã‚¯ã‚¢ãƒƒãƒ—ã™ã‚‹ã¨ã€æ‹¡å¼µæ©Ÿèƒ½ã‚„テーマもåŒæ™‚ã«ãƒãƒƒã‚¯ã‚¢ãƒƒãƒ—ã•ã‚Œã¾ã™ã€‚MozBackup ãªã©ã®ã‚µãƒ¼ãƒ‰ãƒ‘ーティ製アプリケーションã§ã‚‚ãƒãƒƒã‚¯ã‚¢ãƒƒãƒ—ãŒå¯èƒ½ã§ã™ã€‚</dd>
+</dl>
+
+<h2>Web サイトã«é–¢ã™ã‚‹è³ªå•</h2>
+<dl>
+<dt>ã„ãã¤ã‹ã®ã‚¢ãƒ‰ã‚ªãƒ³ã¯åŒã˜ã‚ˆã†ãªæ©Ÿèƒ½ã‚’æä¾›ã—ã¦ã„るよã†ã§ã™ãŒã€ã©ã‚ŒãŒå„ªã‚Œã¦ã„ã‚‹ã‹ã€ã©ã®ã‚ˆã†ã«åˆ¤æ–­ã—ãŸã‚‰è‰¯ã„ã§ã—ょã†ã‹ï¼Ÿ</dt>
+<dd>一般的ã«ã¯ã€è©•ä¾¡ã‚„ダウンロード数ãŒå‚考ã«ãªã‚‹ã§ã—ょã†ã€‚優れãŸã‚¢ãƒ‰ã‚ªãƒ³ã¯ä»–ã®ã‚¢ãƒ‰ã‚ªãƒ³ã‚ˆã‚Šã‚‚多ãダウンロードã•ã‚Œã‚‹å‚¾å‘ãŒã‚ã‚Šã¾ã™ã€‚ã—ã‹ã—ã€ãã‚Œãžã‚Œã®ã‚¢ãƒ‰ã‚ªãƒ³ã‚’インストールã—ã¦ã¿ã¦ã€ã©ã¡ã‚‰ã‚’使ã„ãŸã„ã‹æ±ºã‚ã‚‹ã®ã‚‚ç°¡å˜ã§ã™ã€‚試ã—ãŸå¾Œã€ä¸¡æ–¹ã®ã‚¢ãƒ‰ã‚ªãƒ³ã‚’併用ã—ãŸã„ã¨æ€ã†å ´åˆã‚‚ã‚ã‚‹ã§ã—ょã†ã€‚</dd>
+
+<dt>良ã•ãã†ãªã‚¢ãƒ‰ã‚ªãƒ³ã‚’見ã¤ã‘ã¾ã—ãŸãŒã€Firefox 2 ã«ã—ã‹å¯¾å¿œã—ã¦ã„ãªã„ã¨æ›¸ã‹ã‚Œã¦ã„ã¾ã™ã€‚Firefox 3 ã«ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“ã‹ï¼Ÿ</dt>
+<dd>通常ã¯ã§ãã¾ã›ã‚“。Firefox 3 ã«ã¯æ§˜ã€…ãªæ–°æ©Ÿèƒ½ãŒæ­è¼‰ã•ã‚Œã¦ãŠã‚Šã€å¤šãã®ã‚¢ãƒ‰ã‚ªãƒ³ä½œè€…ã¯ã‚¢ãƒ‰ã‚ªãƒ³ã‚’æ›´æ–°ã—㦠Firefox 3 ã«å¯¾å¿œã•ã›ã¦ã„ã¾ã™ã€‚使ã„ãŸã„アドオン㌠Firefox 2 ã«ã—ã‹å¯¾å¿œã—ã¦ã„ãªã„å ´åˆã¯ã€ãã®ã‚¢ãƒ‰ã‚ªãƒ³ã®åå‰ã§æ¤œç´¢ã—ã¦ã¿ã¦ãã ã•ã„。ãŸã„ã¦ã„ã®å ´åˆã€åŒã˜åå‰ã‚‚ã—ãã¯ä¼¼ãŸåå‰ã§ Firefox 3 ã«å¯¾å¿œã—ã¦ã„ã‚‹æ–°ã—ã„ãƒãƒ¼ã‚¸ãƒ§ãƒ³ãŒã‚ã‚Šã¾ã™ã€‚</dd>
+
+<dt>æ–°ã—ã„テーマをインストールã—ã¾ã—ãŸãŒã€Firefox ã®æ¨™æº–テーマã«æˆ»ã—ãŸã„ã¨æ€ã„ã¾ã™ã€‚ã©ã†ã™ã‚Œã°è‰¯ã„ã§ã™ã‹ï¼Ÿ</dt>
+<dd>[ツール] メニューã‹ã‚‰ [アドオン] ã‚’é¸æŠžã—ã¾ã™ã€‚アドオンマãƒãƒ¼ã‚¸ãƒ£ãŒé–‹ã„ãŸã‚‰ [テーマ] ã®ã‚¿ãƒ–をクリックã—ã¦ã€æ¨™æº–ã®ãƒ†ãƒ¼ãƒžã‹ã€ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã•ã‚Œã¦ã„ã‚‹ä»–ã®ãƒ†ãƒ¼ãƒžã‚’é¸æŠžã—ã¾ã™ã€‚</dd>
+
+<dt>アドオンã«ã¤ã„ã¦å•é¡ŒãŒã‚ã‚‹å ´åˆã¯ã€Mozilla ã«é€£çµ¡ã‚’å–ã‚‹ã¹ãã§ã™ã‹ï¼Ÿ</dt>
+<dd>アドオンã¯ã€ã”ã一部ã®ä¾‹å¤–を除ã„ã¦ã€Mozilla ã§ã¯ãªãコミュニティã«ã‚ˆã£ã¦ä½œæˆã•ã‚Œã¦ã„ã¾ã™ã€‚最も良ã„方法ã¯ã€ãã®ã‚¢ãƒ‰ã‚ªãƒ³ã®ä½œè€…ã«ç›´æŽ¥å•ã„åˆã‚ã›ã‚‹ã“ã¨ã§ã™ã€‚作者ã®é€£çµ¡å…ˆã‚’見ã¤ã‘ã‚‹ã«ã¯ã€ã‚¢ãƒ‰ã‚ªãƒ³ä¸€è¦§ãƒšãƒ¼ã‚¸ã«è¼‰ã£ã¦ã„る作者åをクリックã—ã¦ãã ã•ã„。</dd>
+
+<dt>アドオンã¯ã©ã®ã‚ˆã†ã«ãƒ¬ãƒ“ューã•ã‚Œã¦ã„ã‚‹ã®ã§ã™ã‹ï¼Ÿ</dt>
+<dd>公開ã®ã‚¢ãƒ‰ã‚ªãƒ³ã¯ã€ç†±å¿ƒã§æœ‰èƒ½ãªç·¨é›†ãƒãƒ¼ãƒ ã«ã‚ˆã£ã¦ãƒ¬ãƒ“ューã•ã‚Œã¦ã„ã¾ã™ã€‚レビュー担当者ã¯ã€å…¬é–‹ã•ã‚Œã¦ã„ã‚‹ã™ã¹ã¦ã®ã‚¢ãƒ‰ã‚ªãƒ³ã®ã‚³ãƒ¼ãƒ‰ã‚’レビューã™ã‚‹ã¨ã¨ã‚‚ã«ã€ãれらã®èª¬æ˜ŽãŒæ­£ã—ã„ã‹ã©ã†ã‹ã‚’テストã—ã¦ã„ã¾ã™ã€‚</dd>
+
+<dt>Firefox 3.1 ã«æ›´æ–°ã—ã¾ã—ãŸãŒã€ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã•ã‚Œã¦ã„るアドオンãŒå‹•ä½œã—ã¾ã›ã‚“。ãªãœã§ã—ょã†ã‹ï¼Ÿ</dt>
+<dd>多ãã®ã‚¢ãƒ‰ã‚ªãƒ³ã¯ã™ã§ã« Firefox 3.1 ã«å¯¾å¿œã—ã¦ãŠã‚Šã€ãã®æ•°ã¯æ—¥ã«æ—¥ã«å¢—ãˆã¦ã„ã¾ã™ã€‚ãŠä½¿ã„ã®ã‚¢ãƒ‰ã‚ªãƒ³ãŒ 3.1 ã§å‹•ä½œã—ãªã„å ´åˆã§ã‚‚ã€ä½œè€…ãŒæ—¢ã«å¯¾å¿œä½œæ¥­ã‚’進ã‚ã¦ã„ã‚‹å¯èƒ½æ€§ãŒã‚ã‚Šã¾ã™ã€‚アドオンãŒæ›´æ–°ã•ã‚Œã¦ 3.1 ã«å¯¾å¿œã—ãŸã¨ãã¯ã€Firefox ãŒé€šçŸ¥ã—ã¦ãã‚Œã¾ã™ã€‚</dd>
+
+<dt>実験的ãªã‚¢ãƒ‰ã‚ªãƒ³ã¨ã¯ä½•ã§ã™ã‹ï¼Ÿ</dt>
+<dd>実験的ãªã‚¢ãƒ‰ã‚ªãƒ³ã®å¤šãã¯ã€æœ€è¿‘ Mozilla Add-ons ã«ç™»éŒ²ã•ã‚ŒãŸã‚¢ãƒ‰ã‚ªãƒ³ã§ã™ã€‚ã“れらã®ã‚¢ãƒ‰ã‚ªãƒ³ã¯ä¸€èˆ¬å…¬é–‹ã«å¿…è¦ãªãƒ¬ãƒ“ュープロセスを経ã¦ãŠã‚‰ãšã€ãŸã„ã¦ã„ã®å ´åˆã€å“質ãŒå…¬é–‹ã§ãるレベルã«é”ã—ã¦ã„ã¾ã›ã‚“。レビューをå—ã‘ã¦ã„ãªã„ã“ã¨ã‹ã‚‰ã€ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã™ã‚‹ã¨ä½•ã‚‰ã‹ã®ä¸å…·åˆã‚’引ãèµ·ã“ã™å¯èƒ½æ€§ãŒé«˜ã„ã§ã—ょã†ã€‚</dd>
+</dl>
diff --git a/site/app/locale/ja/pages/nomination.thtml b/site/app/locale/ja/pages/nomination.thtml
new file mode 100644
index 0000000..2a85ad6
--- /dev/null
+++ b/site/app/locale/ja/pages/nomination.thtml
@@ -0,0 +1,9 @@
+<p>サンドボックスã«ã‚るアドオンã¯ã€ã‚¨ãƒ‡ã‚£ã‚¿ã«ã‚ˆã‚‹ãƒ¬ãƒ“ューをå—ã‘ã¦ã„ã¾ã™ã€‚承èªã•ã‚ŒãŸå ´åˆã¯ã€å…¬é–‹ãƒšãƒ¼ã‚¸ã«æŽ²è¼‰ã•ã‚Œã€ãƒ¦ãƒ¼ã‚¶ãŒåˆ©ç”¨ã§ãるよã†ã«ãªã‚Šã¾ã™ã€‚レビューをスムーズã«é€²ã‚ã‚‹ãŸã‚ã€ä»¥ä¸‹ã®ç‚¹ã«ã”注æ„ãã ã•ã„。</p>
+<ul>
+<li>テーマを登録ã™ã‚‹å ´åˆã€ãƒ—レビュー画åƒã‚‚ä½µã›ã¦ç™»éŒ²ã™ã‚‹å¿…è¦ãŒã‚ã‚Šã¾ã™ã€‚ä»–ã®ç¨®é¡žã®ã‚¢ãƒ‰ã‚ªãƒ³ã«ã¤ã„ã¦ã‚‚ã€ãƒ—レビュー画åƒã®æŽ²è¼‰ã‚’å¼·ããŠå‹§ã‚ã—ã¾ã™ã€‚</li>
+<li>登録ã•ã‚ŒãŸã‚¢ãƒ‰ã‚ªãƒ³ã¯ã€ã‚¨ãƒ‡ã‚£ã‚¿ã«ã‚ˆã‚‹ãƒ¬ãƒ“ューã¨ãƒ¦ãƒ¼ã‚¶ã‹ã‚‰ã®ãƒ•ã‚£ãƒ¼ãƒ‰ãƒãƒƒã‚¯ãŒå分ã«è“„ç©ã•ã‚Œã‚‹ã¾ã§ã€ã‚µãƒ³ãƒ‰ãƒœãƒƒã‚¯ã‚¹ã«ç½®ã‹ã‚Œã¾ã™ã€‚<strong>公開ã«ã‚ãŸã£ã¦ã¯ãƒ¬ãƒ“ューãŒå¿…è¦ã§ã™ã€‚</strong></li>
+<li>一般ã«å…¬é–‹ã™ã‚‹ã‚¢ãƒ‰ã‚ªãƒ³ã¯ã€ã‚µãƒ³ãƒ‰ãƒœãƒƒã‚¯ã‚¹ã«ç½®ã‹ã‚Œã¦ã„るアドオンよりもå“質ãŒé«˜ãã€Web ã®åˆ©ç”¨ä¾¡å€¤ã‚’高ã‚ã‚‹ã‚‚ã®ã§ãªãã¦ã¯ãªã‚Šã¾ã›ã‚“。</li>
+<li>詳細ãªç”³è«‹æ¡ä»¶ã¯ <a href="%s">アドオンãƒãƒªã‚·ãƒ¼</a> ã§ã”覧ã„ãŸã ã‘ã¾ã™ã€‚</li>
+</ul>
+<p>ã‚ãªãŸã®ã‚¢ãƒ‰ã‚ªãƒ³ãŒä¸Šè¨˜ã®é …目を満ãŸã—ã¦ã„ã‚‹å ´åˆã¯ã€ä»¥ä¸‹ã®ãƒ•ã‚©ãƒ¼ãƒ ã«å¿…è¦äº‹é …を記入ã—ã¦ã€ãƒ¬ãƒ“ューを申請をã—ã¦ãã ã•ã„。最新ã®ã‚¹ãƒ†ãƒ¼ã‚¿ã‚¹ã¯ãƒ¡ãƒ¼ãƒ«ã§ãŠçŸ¥ã‚‰ã›ã—ã¾ã™ã€‚</p>
+<p>アドオンã®å…¬é–‹ã‚’申請ã™ã‚‹ã«ã¯ã€(エラーや警告ãŒå‡ºãªã„ã“ã¨ã‚’å«ã‚ã¦) ã©ã®ã‚ˆã†ãªãƒ†ã‚¹ãƒˆã‚’è¡Œã£ãŸã‹ã‚„ã€å¤šãã®ãƒ¦ãƒ¼ã‚¶ã«ã¨ã£ã¦ã©ã“ãŒä¾¿åˆ©ã‹ã‚’記述ã—ã¦ãã ã•ã„。第三者ã«ã‚ˆã‚‹ãƒ¬ãƒ“ューãŒã‚ã‚‹å ´åˆã¯ã€ãã® URL ã‚‚å«ã‚ã¦ãã ã•ã„。</p>
diff --git a/site/app/locale/ja/pages/policy.thtml b/site/app/locale/ja/pages/policy.thtml
new file mode 100644
index 0000000..6bcb40b
--- /dev/null
+++ b/site/app/locale/ja/pages/policy.thtml
@@ -0,0 +1,79 @@
+<h1>アドオンãƒãƒªã‚·ãƒ¼</h1>
+
+<h2>サンドボックスã¨ã¯ä½•ã§ã™ã‹ï¼Ÿ</h2>
+<p>%s ã‚’ã”覧ãã ã•ã„。</p>
+
+<h2>サンドボックスã«ç½®ã‹ã‚Œã¦ã„るアドオンã¯ä½•ã§ã™ã‹ï¼Ÿ</h2>
+<p>サンドボックスã¯ã€addons.mozilla.org (AMO) ã«ç™»éŒ²ã•ã‚ŒãŸã™ã¹ã¦ã®ã‚¢ãƒ‰ã‚ªãƒ³ãŒæœ€åˆã«ç½®ã‹ã‚Œã‚‹å ´æ‰€ã§ã™ã€‚公開ã•ã‚Œã¦ã„るアドオンã®æ–°ã—ã„ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã‚„ã€ã¾ã å…¬é–‹ã•ã‚Œã¦ã„ãªã„アドオンã®ã™ã¹ã¦ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ãŒç½®ã‹ã‚Œã¦ã„ã¾ã™ã€‚æ–°ã—ã„アドオンや既存ã®ã‚¢ãƒ‰ã‚ªãƒ³ã®æ›´æ–°ç‰ˆã¯ã€AMO ã«ç™»éŒ²ã•ã‚Œã‚‹ã¨ã¾ãšã“ã®ã‚µãƒ³ãƒ‰ãƒœãƒƒã‚¯ã‚¹ã«ç½®ã‹ã‚Œã¾ã™ã€‚</p>
+<p>ãŸã„ã¦ã„ã®ã‚¢ãƒ‰ã‚ªãƒ³ã‚„ãれらã®ç‰¹å®šã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã¯ã€ãƒ¬ãƒ“ューをå—ã‘ã¦ã€å…¬é–‹å¯èƒ½ãªçŠ¶æ…‹ã«ãªã£ã¦ã„ã‚‹ã‹ã‚„ AMO ã¸ã®æŽ²è¼‰ãŒå¦¥å½“ã‹ã©ã†ã‹ã®æ¤œè¨ŽãŒè¡Œã‚ã‚ŒãŸå¾Œã«å…¬é–‹ã•ã‚Œã¾ã™ã€‚ãれ以外ã®ã‚¢ãƒ‰ã‚ªãƒ³ã¯ã‚µãƒ³ãƒ‰ãƒœãƒƒã‚¯ã‚¹ã«ã„ã¤ã¾ã§ã‚‚ä¿ç•™ã•ã‚Œã€ã‚µãƒ³ãƒ‰ãƒœãƒƒã‚¯ã‚¹ã‚’å‚ç…§ã—ã¦ãã“ã«ç½®ã‹ã‚ŒãŸã‚¢ãƒ‰ã‚ªãƒ³ã‚’進んã§è©¦ãã†ã¨ã™ã‚‹ãƒ¦ãƒ¼ã‚¶ã®ã¿ãŒåˆ©ç”¨ã§ãã¾ã™ã€‚</p>
+
+<h2>アドオンã¯ã©ã®ã‚ˆã†ã«å…¬é–‹ã•ã‚Œã‚‹ã®ã§ã™ã‹ï¼Ÿ</h2>
+<p>アドオンã¯ã€ã‚µãƒ³ãƒ‰ãƒœãƒƒã‚¯ã‚¹ã‚’å‚ç…§ã—ã¦ãã“ã«ç½®ã‹ã‚ŒãŸã‚¢ãƒ‰ã‚ªãƒ³ã‚’進んã§è©¦ãã†ã¨ã™ã‚‹ AMO ユーザã«ã‚ˆã‚‹ãƒ¬ãƒ“ューをå—ã‘ã¾ã™ã€‚ユーザãŒæ›¸ã込むレビューã¯ã€ã‚¢ãƒ‰ã‚ªãƒ³ã‚’ã™ã¹ã¦ã® Firefox ユーザã«å…¬é–‹ã™ã‚‹ã«ã‚ãŸã£ã¦ã€å分ã«å½¹ã«ç«‹ã¤ã‹ã€ã—ã£ã‹ã‚Šã¨ä½œã‚Šè¾¼ã¾ã‚Œã¦ã„ã‚‹ã‹ã€æ´—ç·´ã•ã‚Œã¦ã„ã‚‹ã‹ã€ã¨ã„ã£ãŸã“ã¨ã®æŒ‡æ¨™ã«ãªã‚Šã¾ã™ã€‚ãれらã®ãƒ¬ãƒ“ューã¯ã€AMO ãƒãƒ¼ãƒ ã«ã‚ˆã‚‹ä»–ã®ãƒ¬ãƒ“ューや調査ã¨ã¨ã‚‚ã«ã€å¹…広ã„公開ã®ãŸã‚ã«ã•ã‚‰ãªã‚‹æ´—ç·´ãŒå¿…è¦ã§ãªã„ã‹ã€ã‚ã‚‹ã„㯠AMO ã§ã®ç´¹ä»‹ã«ãµã•ã‚ã—ã„ã‹ãªã©ã€ãã®ã‚¢ãƒ‰ã‚ªãƒ³ã®å…¬é–‹ãŒå¦¥å½“ã‹ã©ã†ã‹ã®åˆ¤æ–­ææ–™ã¨ã—ã¦åˆ©ç”¨ã•ã‚Œã¾ã™ã€‚</p>
+
+<h2>自分ã®ã‚¢ãƒ‰ã‚ªãƒ³ã‚’公開ã™ã‚‹ã«ã¯ã©ã†ã™ã‚Œã°è‰¯ã„ã§ã™ã‹ï¼Ÿ</h2>
+<p>自分ã®ã‚¢ãƒ‰ã‚ªãƒ³ (ã¨è‡ªåˆ†ã®è¡Œã„) ãŒå…¬é–‹ã®ã‚¢ãƒ‰ã‚ªãƒ³ã®æ¡ä»¶ã‚’満ãŸã—ã¦ã„ã‚‹ã¨è€ƒãˆã‚‰ã‚Œã‚‹å ´åˆã¯ã€é–‹ç™ºè€…å‘ã‘コントロールパãƒãƒ«ã‹ã‚‰ç”³è«‹ã‚’è¡Œã†ã“ã¨ãŒã§ãã¾ã™ã€‚</p>
+
+<h2>公開ã®ã‚¢ãƒ‰ã‚ªãƒ³ã®æ¡ä»¶ã¨ã¯ï¼Ÿ</h2>
+<p>AMO 上ã§å…¬é–‹ã•ã‚Œã‚‹ã‚¢ãƒ‰ã‚ªãƒ³ã¯ã€å分ãªå“質を備ãˆã€ãƒ¦ãƒ¼ã‚¶ã«ã‚ˆã‚Šè‰¯ã„ Web 体験をæä¾›ã™ã‚‹ã‚‚ã®ã§ãªãã¦ã¯ãªã‚Šã¾ã›ã‚“。ç§ãŸã¡ã¯ã€å…¬é–‹ãƒšãƒ¼ã‚¸ã¸ã®æŽ²è¼‰ãŒå¦¥å½“ã‹ã©ã†ã‹ã‚’判断ã™ã‚‹ã«ã‚ãŸã£ã¦ã€ä»¥ä¸‹ã®ã“ã¨ã‚’求ã‚ã¦ã„ã¾ã™ã€‚</p>
+
+<h3>ã™ã°ã‚„ã„対応を行ãˆã‚‹ã‹</h3>
+<p>ç§ãŸã¡ã¯ã€å¤šãã® Firefox ユーザã«å‘ã‘ã¦ã‚¢ãƒ‰ã‚ªãƒ³ã‚’宣ä¼ã—よã†ã¨ã™ã‚‹ä½œè€…ã®çš†ã•ã‚“ã«å¯¾ã—ã¦ã€å ±å‘Šã•ã‚ŒãŸå•é¡Œã«è²¬ä»»ã‚’æŒã¡ã€å¸¸ã«æœ€æ–°ã®é€£çµ¡å…ˆæƒ…報をæä¾›ã—ã€Firefox ã®ãƒªãƒªãƒ¼ã‚¹ã‚„ AMO ã®ãƒãƒªã‚·ãƒ¼å¤‰æ›´ãŒè¡Œã‚ã‚ŒãŸéš›ã¯ãã‚Œã«è¿½éšã—ã¦è¿…速ã«ã‚¢ãƒ‰ã‚ªãƒ³ã‚’æ›´æ–°ã—ã¦ã„ãŸã ãã“ã¨ã‚’期待ã—ã¦ã„ã¾ã™ã€‚ã“ã‚Œã¯ã€ãƒ‡ã‚£ã‚¹ã‚«ãƒƒã‚·ãƒ§ãƒ³ã®ä¸­ã§æŠ•ç¨¿ã•ã‚ŒãŸè³ªå•ã«ã¯å¿…ãšå›žç­”ã—ã€ãƒã‚°ã‚‚ã™ã¹ã¦ä¿®æ­£ã—ãªã‘ã‚Œã°ãªã‚‰ãªã„ã€ã¨ã„ã†ã“ã¨ã§ã¯ã‚ã‚Šã¾ã›ã‚“。ã—ã‹ã—ã€å ±å‘Šã•ã‚ŒãŸå•é¡Œã®é‡è¦åº¦ã«å¿œã˜ã¦é©åˆ‡ãªå¯¾å¿œã‚’å–られるã“ã¨ã‚’å¼·ã期待ã—ã¾ã™ã€‚</p>
+
+<h3>アドオンã®èª¬æ˜ŽãŒã¯ã£ãã‚Šã¨æ­£ç¢ºã«è¨˜è¿°ã•ã‚Œã¦ã„ã‚‹ã‹</h3>
+<p>ç§ãŸã¡ã¯ã€ãƒ¦ãƒ¼ã‚¶ãŒæ–°ã—ã„アドオンを試ã™ã¨ãã«æœŸå¾…ã—ãŸæ©Ÿèƒ½ã‚’得られるã‹ã©ã†ã‹ã€ã¨ã„ã†ã“ã¨ã‚’最もé‡è¦–ã—ã¦ã„ã¾ã™ã€‚アドオンã®èª¬æ˜Žã«ã¯ã€ã©ã®ã‚ˆã†ãªæ©Ÿèƒ½ãŒå«ã¾ã‚Œã¦ã„ã‚‹ã‹ã€ã©ã†ã™ã‚Œã°æ´»ç”¨ã§ãã‚‹ã‹ã€ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã™ã‚‹ã“ã¨ã§ä½•ãŒæœŸå¾…ã§ãã‚‹ã‹ã€ã¨ã„ã£ãŸã“ã¨ã‚’詳述ã—ã¦ãã ã•ã„。より詳ã—ã„利用方法ã«é–¢ã—ã¦ã¯å¤–部ã®æ–‡æ›¸ã«ãƒªãƒ³ã‚¯ã‚’å¼µã£ã¦ã‚‚構ã„ã¾ã›ã‚“ãŒã€ãã®èª¬æ˜Žã ã‘ã§ã‚‚基本的ãªæƒ…報を網羅ã—ã€ã©ã®ã‚ˆã†ãªæ©Ÿèƒ½ã‚’利用ã§ãã‚‹ã®ã‹ãƒ¦ãƒ¼ã‚¶ã«æ­£ã—ãç†è§£ã—ã¦ã‚‚らãˆã‚‹ã‚ˆã†ã«ã™ã‚‹å¿…è¦ãŒã‚ã‚Šã¾ã™ã€‚</p>
+<p>ã¾ãŸã€ã‚¢ãƒ‰ã‚ªãƒ³ã«æ”¹è‰¯ã‚„変更を加ãˆãŸéš›ã«é©åˆ‡ãªãƒãƒ¼ã‚¸ãƒ§ãƒ³å±¥æ­´ã‚’æä¾›ã™ã‚‹ã“ã¨ã‚‚é‡è¦ã§ã™ã€‚ã™ã§ã«ãã®ã‚¢ãƒ‰ã‚ªãƒ³ã‚’インストールã—ã¦ã„るユーザãŒã€æ–°ã—ã„ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã§ã®æ–°æ©Ÿèƒ½ã‚„改良点を分ã‹ã‚‹ã‚ˆã†ã«ã—ã¦ãã ã•ã„。更新ã«ã‚ˆã£ã¦ä½¿ç”¨ä¸Šä½•ã‚‰ã‹ã®å½±éŸ¿ãŒè€ƒãˆã‚‰ã‚Œã‚‹å ´åˆã¯ã€å¿…ãšãã‚Œã«é–¢ã™ã‚‹å¤‰æ›´ç‚¹ã‚‚説明ã—ãªã‘ã‚Œã°ãªã‚Šã¾ã›ã‚“。(ç¾æ™‚点ã§ã¯ã€ãƒ–ラウザ内ã§å—ã‘å–れる更新通知ã¨ã¨ã‚‚ã«ãƒãƒ¼ã‚¸ãƒ§ãƒ³å±¥æ­´ã‚’表示ã™ã‚‹æ–¹æ³•ã¯ã‚ã‚Šã¾ã›ã‚“ãŒã€ä»Šå¾Œã“ã®ç‚¹ã«ã¤ã„ã¦ã¯ä¿®æ­£ã‚’è¡Œã†äºˆå®šã§ã™ã€‚ãƒãƒ¼ã‚¸ãƒ§ãƒ³å±¥æ­´ã‚’ãã¡ã‚“ã¨æä¾›ã—ã¦ã„ã‚Œã°ã€æ›´æ–°ã®å‰ã§ã‚‚後ã§ã‚‚ã€ãƒ¦ãƒ¼ã‚¶ã«ã¨ã£ã¦ã¯å¤§ã„ã«å½¹ç«‹ã¡ã¾ã™ã€‚)</p>
+
+<h3>プライãƒã‚·ãƒ¼ã‚„セキュリティã«é–¢ã™ã‚‹æ‡¸å¿µãŒã™ã¹ã¦æ˜Žè¨˜ã•ã‚Œã¦ã„ã‚‹ã‹</h3>
+<p>ã“ã‚Œã¯ã€æ˜Žçž­ã§çš„確ãªèª¬æ˜ŽãŒã©ã®ã‚ˆã†ãªã‚‚ã®ã‹ã¨ã„ã†è§£é‡ˆã«ã‚‚よりã¾ã™ãŒã€ç§ãŸã¡ã¨ã—ã¦ã¯ã€å…·ä½“çš„ãªè¨€åŠã‚’è¡Œã†ã¹ãé‡è¦ãªã“ã¨ã®ã²ã¨ã¤ã§ã‚ã‚‹ã¨è€ƒãˆã¦ã„ã¾ã™ã€‚大変便利ã§ã‚ˆã作り込ã¾ã‚ŒãŸã‚¢ãƒ‰ã‚ªãƒ³ã¯ã€ãŸã„ã¦ã„ã®å ´åˆã€ä½•ã‚‰ã‹ã®å½¢ã§ãƒ¦ãƒ¼ã‚¶ã®ãƒ‡ãƒ¼ã‚¿ã‚’æ“作ã—ã¦ã„ãŸã‚Šã€ã‚ã‚‹ã„ã¯èª¤ã£ãŸä½¿ã„方をã—ãŸã¨ãã«ã‚»ã‚­ãƒ¥ãƒªãƒ†ã‚£ä¸Šã®ãƒªã‚¹ã‚¯ãŒè¡¨é¢åŒ–ã™ã‚‹å¯èƒ½æ€§ã‚’å«ã‚“ã§ã„ã¾ã™ã€‚ãれら㮠AMO ã¸ã®æŽ²è¼‰ã¯æ­“è¿Žã•ã‚Œã¾ã™ãŒã€ãƒ¦ãƒ¼ã‚¶ã«å¯¾ã—ã¦ã€ã©ã®ã‚ˆã†ãªãƒªã‚¹ã‚¯ã‚’ä¼´ã†å¯èƒ½æ€§ãŒã‚ã‚‹ã®ã‹ã‚„ã€ãƒ¦ãƒ¼ã‚¶è‡ªèº«ãŒãれらã®ãƒªã‚¹ã‚¯ã‹ã‚‰èº«ã‚’守る方法をã€ã¯ã£ãã‚Šã¨èª¬æ˜Žã—ãªã‘ã‚Œã°ãªã‚Šã¾ã›ã‚“。</p>
+
+<h3>アドオンã¯å分ãªãƒ†ã‚¹ãƒˆãŒè¡Œã‚ã‚Œã¦ãŠã‚Šã€æ˜Žã‚‰ã‹ãªã€ã‚ã‚‹ã„ã¯é‡å¤§ãªæ¬ é™¥ã¯ãªã„ã‹</h3>
+<p>ç§ãŸã¡ã¯ã€ã‚¢ãƒ‰ã‚ªãƒ³ã®ä¸€èˆ¬å…¬é–‹ã‚’検討ã™ã‚‹éš›ã€ã‚µãƒ³ãƒ‰ãƒœãƒƒã‚¯ã‚¹ã«ã‚ã‚‹ãã®ã‚¢ãƒ‰ã‚ªãƒ³ã®ãƒ¬ãƒ“ューãŒå®Ÿéš›ã®ãƒ†ã‚¹ãƒˆã‚’å—ã‘ã¦å¯„ã›ã‚‰ã‚ŒãŸã‚‚ã®ã‹ã¨ã„ã†ã“ã¨ã¨ã€æ·±åˆ»ãªå•é¡Œã‚„ブラウザã«å¯¾ã™ã‚‹æ‚ªå½±éŸ¿ãŒãªã„ã‹ã¨ã„ã†ã“ã¨ã‚’ã€é‡è¦ãªæ¡ä»¶ã®ã²ã¨ã¤ã¨ã—ã¦è€ƒãˆã¦ã„ã¾ã™ã€‚ãã®ã‚¢ãƒ‰ã‚ªãƒ³ã®æ©Ÿèƒ½ã‚’テストã—ã¦ã„ã‚‹ã¨ãã«é‡å¤§ãªãƒ‘フォーマンスã®å•é¡Œã‚„クラッシュã«é­é‡ã—ãŸã€ãƒˆãƒ©ãƒ–ルãŒé »ç¹ã«ç™ºç”Ÿã—ãŸã€ã‚ã‚‹ã„ã¯ã‚³ãƒ³ã‚½ãƒ¼ãƒ«ã«å¤šæ•°ã®ã‚¨ãƒ©ãƒ¼ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ãŒå‡ºåŠ›ã•ã‚ŒãŸã€ã¨ã„ã£ãŸã“ã¨ãŒãƒ¬ãƒ“ュー担当者ã‹ã‚‰å ±å‘Šã•ã‚ŒãŸå ´åˆã€ãれらã®å ±å‘Šã‚’真剣ã«æ‰ãˆã€ã§ãã‚‹é™ã‚Šå•é¡Œã‚’解決ã—ãŸä¸Šã§å†åº¦å…¬é–‹ç”³è«‹ã‚’è¡Œã£ã¦ãã ã•ã„。ç§ãŸã¡ã¯ã€å®Œå…¨ãªæœ€é©åŒ–ã‚„ã€ã™ã¹ã¦ã®ãƒã‚°ã®ä¿®æ­£ã‚’求ã‚ã¦ã„ã‚‹ã‚ã‘ã§ã¯ã‚ã‚Šã¾ã›ã‚“。ã“れらã®èª²é¡Œã«é–¢ã—ã¦ã¯ Firefox 自体も継続的ãªæ”¹å–„ã‚’è¡Œã£ã¦ãã¦ã„ã¾ã™ã€‚ã—ã‹ã—ã€å•é¡Œã‚’最å°é™ã«æŠ‘ãˆã‚‹ãŸã‚ã«ç›¸å½“ã®åŠªåŠ›ã‚’è¡Œã„ã€ãªãŠã‹ã¤å•é¡ŒãŒæ®‹ã£ã¦ã„ã¦ãã‚ŒãŒãƒ¦ãƒ¼ã‚¶ã«å½±éŸ¿ã‚’ã‚‚ãŸã‚‰ã™å ´åˆã«ã¯ã€ãã®å†…容を明記ã™ã‚‹ã“ã¨ã‚’期待ã—ã¦ã„ã¾ã™ã€‚</p>
+<p>AMO ã®ã‚µãƒ³ãƒ‰ãƒœãƒƒã‚¯ã‚¹ã§ã¯ãªãã€è‡ªç¤¾æ供サービスã®ãƒ¦ãƒ¼ã‚¶ã‚°ãƒ«ãƒ¼ãƒ—や社内ã®å“質ä¿è¨¼ãƒãƒ¼ãƒ ãªã©ã€å¤–部ã®ãƒ—ロセスを通ã˜ã¦ãƒ†ã‚¹ãƒˆã‚’è¡Œã£ãŸå ´åˆã¯ã€å…¬é–‹ç”³è«‹ã®éš›ã«ãã®ã“ã¨ã‚’知らã›ã¦ãã ã•ã„。ã©ã®ç¨‹åº¦ã®ãƒ†ã‚¹ãƒˆãŒè¡Œã‚ã‚ŒãŸã®ã‹ã‚’確実ã«ç«‹è¨¼ã§ãã€ã‚¢ãƒ‰ã‚ªãƒ³ã®å…¬é–‹ã«ã‚ãŸã£ã¦ã®å‚考情報ã¨ãªã‚Šã¾ã™ã€‚</p>
+
+<h3>アドオンや作者ã¯ãƒ¦ãƒ¼ã‚¶ã«æ•¬æ„を払ã£ã¦ã„ã‚‹ã‹</h3>
+<p>アドオンã¯ã€ä¸å¿…è¦ã«ãƒ¦ãƒ¼ã‚¶ã®ãƒ—ライãƒã‚·ãƒ¼ã‚’侵害ã—ãŸã‚Šã€ãƒ¦ãƒ¼ã‚¶ã‚’ã ã¾ãã†ã¨ã—ãŸã‚Šã€æ©Ÿèƒ½ã‚’éš ãºã„ã—よã†ã¨ã—ã¦ã¯ã„ã‘ã¾ã›ã‚“。ã¾ãŸã€ãƒ¦ãƒ¼ã‚¶ã¯ (ã‚ã‚‹ã„ã¯ãƒ¦ãƒ¼ã‚¶ã§ãªãã¦ã‚‚) 時ã¨ã—ã¦å¤±ç¤¼ãªã‚³ãƒ¡ãƒ³ãƒˆã‚’投稿ã™ã‚‹ã“ã¨ãŒã‚ã‚Šã€ç§ãŸã¡ã¯ãã†ã—ãŸå ±å‘Šã‚’極力排除ã—よã†ã¨åŠªåŠ›ã—ã¦ã„ã¾ã™ãŒã€ã¿ãšã‹ã‚‰ç„¡ç¤¼ãªæ…‹åº¦ã§å¿œã˜ãªã„よã†ã€ä½œè€…ã®çš†ã•ã‚“ã«ã¯ãŠé¡˜ã„ã„ãŸã—ã¾ã™ã€‚</p>
+
+<h3>アドオンã¯ã‚る程度幅広ã„ユーザ層ã«ã¨ã£ã¦å½¹ç«‹ã¤ã‚‚ã®ã‹</h3>
+<p>Greasemonkey ã‚„ FireBug ã®ã‚ˆã†ãªãƒ’ット作を狙ã†å¿…è¦ã¯ã‚ã‚Šã¾ã›ã‚“ãŒã€ç™»éŒ²ã•ã‚ŒãŸã‚¢ãƒ‰ã‚ªãƒ³ãŒã‚ãªãŸã®ä¼šç¤¾ã®ç¤¾å“¡ã‚„å°è¦æ¨¡ãª Web コミュニティã®ãƒ¡ãƒ³ãƒãƒ¼ã«ã—ã‹å½¹ã«ç«‹ãŸãªã„よã†ãªå ´åˆã€ç§ãŸã¡ã¯ã€ã™ã¹ã¦ã® Firefox ユーザã«å‘ã‘ã¦å…¬é–‹ã™ã‚‹ã«ã¯ã¾ã å¦¥å½“ã§ãªã„ã¨åˆ¤æ–­ã™ã‚‹ã§ã—ょã†ã€‚</p>
+<p>ç§ãŸã¡ã¯å¸¸ã«ã‚µã‚¤ãƒˆæ§‹æˆã‚’改善ã—ã€ã‚る部分ã§ã¯ä»–ã®ã‚¢ãƒ‰ã‚ªãƒ³ã®æ¨¡ç¯„ã¨ãªã‚‹ä¸€æ–¹ã€æ½œåœ¨çš„ãªãƒ¦ãƒ¼ã‚¶ã®å°è¦æ¨¡ãªã‚³ãƒŸãƒ¥ãƒ‹ãƒ†ã‚£ã®ã¿ã‚’対象ã¨ã—ã¦ã„るアドオンをã€ã©ã®ã‚ˆã†ã«æ‰±ã†ã¹ãã‹ã‚’模索ã—ã¦ã„ã¾ã™ã€‚作者ã®çš†ã•ã‚“ãŒã‚¢ãƒ‰ã‚ªãƒ³ã®åˆ†é¡žã¨ãƒ¡ã‚¿ãƒ‡ãƒ¼ã‚¿ã®æ›´æ–°ã‚’é©åˆ‡ã«è¡Œã£ã¦ãã ã•ã‚Œã°ã€ãã†ã—ãŸã‚¢ãƒ‰ã‚ªãƒ³ã«ã‚ˆã£ã¦æœ€ã‚‚æ©æµã‚’å—ã‘られるã¨æ€ã‚れるユーザã«å‘ã‘ã¦ã€ã‚ˆã‚Šã‚¢ãƒ”ールã™ã‚‹æ–¹æ³•ã‚’見ã¤ã‘出ã™ã“ã¨ãŒã§ãã¾ã™ã€‚</p>
+<p>ã‚ãªãŸã®ã‚¢ãƒ‰ã‚ªãƒ³ãŒã€ã‚ãªãŸã®ã‚µã‚¤ãƒˆã¸ã®ãƒ–ックマークãªã©å˜ç´”ãªã‚¢ã‚¯ã‚»ã‚¹æ–¹æ³•ã‚’æä¾›ã™ã‚‹ã ã‘ã®å ´åˆã€AMO ã§ã®å…¬é–‹ã«ã¯ãµã•ã‚ã—ããªã„ã§ã—ょã†ã€‚ä»–ã® Mozilla プロジェクトã¨åŒæ§˜ã«ã€ç§ãŸã¡ã¯ Web アプリケーションや新ã—ã„ Web サービスを大切ã«ã—ã¦ã„ã¾ã™ãŒã€Firefox ã®ã‚¢ãƒ‰ã‚ªãƒ³ã¯ã‚ˆã‚Šè‰¯ã„ブラウジング体験をユーザã«æä¾›ã™ã¹ãã‚‚ã®ã§ã‚ã£ã¦ã€AMO ã¸ã®æŽ²è¼‰ã‚’通ã˜ãŸå˜ãªã‚‹æ–°ã‚µã‚¤ãƒˆãƒ»æ–°ã‚µãƒ¼ãƒ“スã®å®£ä¼æ‰‹æ®µã§ã¯ã‚ã‚Šã¾ã›ã‚“。アドオンã®èª¬æ˜ŽãŒã€ãƒ¦ãƒ¼ã‚¶ã®ãƒ–ラウジング体験ã®å‘上ã«é–¢ã™ã‚‹ã“ã¨ã§ã¯ãªãã€ä¸»ã«ã‚µãƒ¼ãƒ“スã«é–¢ã™ã‚‹å†…容ã§ã‚ã£ãŸå ´åˆã€ãã‚Œã¯æ­£ã—ã„æ–¹å‘ã¨ã¯è¨€ãˆãªã„ã§ã—ょã†ã€‚</p>
+
+<h3>アドオンã«å•†æ¨™ã‚„著作権ã®ä¾µå®³ã¯å«ã¾ã‚Œã¦ã„ãªã„ã‹</h3>
+<p>第三者ã®å•†æ¨™ã‚„著作権を侵害ã—ã¦ã„るアドオンã¯ã€æ¨©åˆ©è€…ã«ã¨ã£ã¦ç‰¹ã«ä¸éƒ½åˆã¯ãªã„ã¨æ€ã‚れる場åˆã§ã‚‚ã€ç™»éŒ²ã‚’å—ã‘付ã‘られã¾ã›ã‚“。商標ã¨ãªã£ã¦ã„ã‚‹å称やロゴを使用ã™ã‚‹è¨±å¯ã‚’å¾—ã¦ã„ãªã„å ´åˆã€ãã®ã‚¢ãƒ‰ã‚ªãƒ³ã‚’ AMO ã«ç™»éŒ²ã™ã‚‹ã“ã¨ã¯ãŠã‚„ã‚ãã ã•ã„。アドオンã«ç¬¬ä¸‰è€…ãŒè‘—作権をä¿æœ‰ã™ã‚‹ã‚½ãƒ¼ã‚¹ã‚³ãƒ¼ãƒ‰ãŒå«ã¾ã‚Œã¦ã„ã¦ã€ãã®ã‚¢ãƒ‰ã‚ªãƒ³ã«ãŠã‘る使用許å¯ã‚’å¾—ã¦ã„ãªã„å ´åˆã‚‚ã€åŒæ§˜ã«ç™»éŒ²ã¯ãŠæ–­ã‚Šã—ã¾ã™ã€‚(権利者ã‹ã‚‰ã€å•†æ¨™ã‚„著作物ã®ä½¿ç”¨ã«é–¢ã—ã¦ç•°è­°ç”³ã—ç«‹ã¦ãŒã‚ã£ãŸå ´åˆã€å°‚門家ã«å‰Šé™¤è¦æ±‚ã®ãƒ¬ãƒ“ューをä¾é ¼ã—ãªã‘ã‚Œã°ãªã‚‰ãªããªã‚‹å¯èƒ½æ€§ãŒé«˜ãã€æ³•çš„ã«å¿…è¦ã§ã‚ã‚‹ã¨åˆ¤æ–­ã•ã‚Œã‚Œã°ãã®ã‚¢ãƒ‰ã‚ªãƒ³ã‚’削除ã™ã‚‹ã“ã¨ã«ãªã‚Šã¾ã™ã€‚ã“ã‚Œã¯ã€æ™‚é–“ã¨ãŠé‡‘ã®ä¸¡é¢ã‹ã‚‰ã€ãƒ—ロジェクトã®ãƒªã‚½ãƒ¼ã‚¹ã‚’浪費ã™ã‚‹ãƒ—ロセスã§ã‚ã‚‹ãŸã‚ã€ä½œè€…ã®çš†ã•ã‚“ã«ã¯ã€ç¬¬ä¸‰è€…ã®æ¨©åˆ©ã‚’å°Šé‡ã—ã€ç§ãŸã¡ã«éŽåº¦ãªè² æ‹…ã‚’ã‹ã‘ãªã„よã†ãŠé¡˜ã„ã—ã¾ã™ã€‚)</p>
+<p>アドオンã®ã‚¿ã‚¤ãƒˆãƒ«ã‚„ã€ä¸­ã«å«ã¾ã‚Œã¦ã„るソースコードãªã©ãŒåŽŸå› ã§ã€AMO ã¸ã®æŽ²è¼‰ãŒå¯èƒ½ã‹ç¢ºä¿¡ãŒæŒã¦ãªã„å ´åˆã¯ã€amo-editors@mozilla.org ã«æŒ‡å°Žã‚’ä»°ãã“ã¨ãŒã§ãã¾ã™ã€‚é‡è¦ãªæ³¨æ„: ã“ã®ã‚°ãƒ«ãƒ¼ãƒ—ã¯æ³•çš„ãªã‚¢ãƒ‰ãƒã‚¤ã‚¹ã‚’è¡Œã†ã“ã¨ã¯ã§ãã¾ã›ã‚“。ã¾ãŸã€ä¸€åº¦ç§ãŸã¡ãŒã‚ãªãŸã®ä½¿ç”¨å½¢æ…‹ã‚’許容範囲ã§ã‚ã‚‹ã¨åˆ¤æ–­ã—ãŸå ´åˆã§ã‚‚ã€æ¨©åˆ©è€…ã®ã‚¯ãƒ¬ãƒ¼ãƒ ã‚„専門家ã®ã‚¢ãƒ‰ãƒã‚¤ã‚¹ã«å¿œã˜ã¦å†æ¤œè¨Žã‚’è¡Œã†å¯èƒ½æ€§ãŒã‚ã‚Šã¾ã™ã€‚</p>
+<p>ä»–ã®ã‚¢ãƒ‰ã‚ªãƒ³ã«å«ã¾ã‚Œã‚‹ã‚½ãƒ¼ã‚¹ã‚³ãƒ¼ãƒ‰ã®å†åˆ©ç”¨ã«é–¢ã—ã¦ã¯ã€ä¾‹ãˆã°ã‚ªãƒ¼ãƒ—ンソースライセンスãªã©ã€ä»–ã®ã‚¢ãƒ‰ã‚ªãƒ³ã«ãŠã‘るコードã®ä½¿ç”¨è¨±å¯ãŒãã®ä½œè€…ã«ã‚ˆã£ã¦æ˜Žè¨˜ã•ã‚Œã¦ã„ãªã„é™ã‚Šã€ä½¿ç”¨è¨±å¯ã‚’å¾—ã¦ã„ãªã„ã¨è€ƒãˆã¦ãã ã•ã„。ãã®å ´åˆã€ä½œè€…ã«é€£çµ¡ã‚’å–ã£ã¦è¨±å¯ã‚’求ã‚ã‚‹ã®ãŒè‰¯ã„ã§ã—ょã†ã€‚ãã®ã‚¢ãƒ‰ã‚ªãƒ³ãŒ AMO ã«ç™»éŒ²ã•ã‚Œã¦ã„ã‚‹ã‹ã‚‰ã€ã‚ã‚‹ã„ã¯ä½œè€…ã‹ã‚‰è¿”ä¿¡ãŒãªã„ã‹ã‚‰ã¨ã„ã£ãŸäº‹æƒ…ãŒã‚ã£ãŸã¨ã—ã¦ã‚‚ã€ç§ãŸã¡ã¯ã‚ãªãŸã«ç‰¹åˆ¥ãªè¨±å¯ã‚’与ãˆã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“。(ã¾ãŸã€ç¹°ã‚Šè¿”ã—ã¾ã™ãŒã€ç§ãŸã¡ã¯æ³•çš„ãªã‚¢ãƒ‰ãƒã‚¤ã‚¹ã‚’è¡Œã†ã“ã¨ã¯ã§ãã¾ã›ã‚“。ã©ã†ã™ã‚Œã°ã“ã®ã‚µã‚¤ãƒˆã®ãƒãƒªã‚·ãƒ¼ã«æ²¿ã£ãŸã‚¢ãƒ‰ã‚ªãƒ³ã‚’登録ã§ãã‚‹ã‹ã€ã¨ã„ã£ãŸä¸€èˆ¬çš„ãªç¯„囲ã§ã®ã‚¢ãƒ‰ãƒã‚¤ã‚¹ã§ã‚ã‚Œã°æä¾›ã§ãã¾ã™ã€‚)</p>
+<p>以上ã®ã“ã¨ã¯ã€ã€ŒMozillaã€ã€ŒFirefoxã€ã€ŒThunderbirdã€ã¨ã„ã£ãŸ Mozilla Foundation ã®å•†æ¨™ã«ã‚‚当ã¦ã¯ã¾ã‚Šã¾ã™ã€‚Mozilla ã®å•†æ¨™ãƒãƒªã‚·ãƒ¼ã¯ã€æ··ä¹±ã‚’é¿ã‘ã‚‹ã¨åŒæ™‚ã«ã€æ³•çš„ãªä¿è­·ã‚’è¡Œã‚ãªã‹ã£ãŸå ´åˆã«ç¬¬ä¸‰è€…ã«å•†æ¨™ãŒè¦†ã•ã‚Œã¦ã—ã¾ã†ã®ã‚’防ã目的ã§ä½œã‚‰ã‚Œã¦ã„ã¾ã™ã€‚ãã†ã—ãŸä¿è­·ã®å¿…è¦æ€§ã‚’考慮ã—ã¦ã„ãŸã ãã€Mozilla Foundation ã®æœ€ã‚‚è²´é‡ãªè²¡ç”£ã®ç¶­æŒã«ã”å”力ãã ã•ã„。</p>
+
+<h2>アドオンã®å…¬é–‹ã‚’申請ã—ãŸå¾Œã€ã©ã®ã‚ˆã†ãªæ‰‹ç¶šããŒè¡Œã‚ã‚Œã¾ã™ã‹ï¼Ÿ</h2>
+<p>公開申請ã•ã‚ŒãŸã‚¢ãƒ‰ã‚ªãƒ³ã¯ã€AMO ã®ã‚¨ãƒ‡ã‚£ã‚¿ãƒãƒ¼ãƒ ã«ã‚ˆã‚Šã€ä¸Šè¨˜ã®æ¡ä»¶ã«ç…§ã‚‰ã—ã¦è©•ä¾¡ã•ã‚Œã¾ã™ã€‚公開ã«ãµã•ã‚ã—ã„ã¨åˆ¤æ–­ã•ã‚ŒãŸå ´åˆã¯ã€è©•ä¾¡çµ‚了後ã«å…¬é–‹ãƒšãƒ¼ã‚¸ã«æŽ²è¼‰ã•ã‚Œã€ä½œè€…ã«ã¯ãƒ¡ãƒ¼ãƒ«ã«ã‚ˆã‚‹é€šçŸ¥ãŒé€ã‚‰ã‚Œã¾ã™ã€‚</p>
+<p>ãã®æ™‚点㧠AMO ã¸ã®æŽ²è¼‰ãŒå¦¥å½“ã§ãªã„ã¨åˆ¤æ–­ã•ã‚ŒãŸå ´åˆã¯ã€ãã®ç†ç”±ã‚’記ã—ãŸé€šçŸ¥ãŒé€ã‚‰ã‚Œã€ç”³è«‹ã¯ã‚­ãƒ£ãƒ³ã‚»ãƒ«ã•ã‚Œã¾ã™ã€‚ãã®é€šçŸ¥ã«æ›¸ã‹ã‚ŒãŸæ‡¸å¿µã‚’解決ã—ã¦ã‹ã‚‰ã€å†åº¦è©•ä¾¡ã‚’ä¾é ¼ã—ãŸã„å ´åˆã¯ã€ã”自分ã®åˆ¤æ–­ã§ç”³è«‹ã‚’è¡Œã£ã¦ãã ã•ã„。ãªãŠã€ã‚¢ãƒ‰ã‚ªãƒ³ã«ãŸã„ã—ãŸæ”¹å–„ã‚’è¡Œã‚ãšã«å†åº¦ç”³è«‹ã‚’ã—ã¦ã‚‚ã€ãã®ç”³è«‹ã¯å¥½æ„çš„ã«è¦‹ã‚‰ã‚Œãšã€æ‹…当者ã®æ°—力をããã©ã“ã‚怒らã›ã‚‹ã“ã¨ã«ãªã‚Šã¾ã™ã®ã§ã€ã©ã†ã‹æ…Žé‡ãªå§¿å‹¢ã§è‡¨ã‚“ã§ãã ã•ã„。</p>
+
+<h2>他人ã®ã‚¢ãƒ‰ã‚ªãƒ³ã®å…¬é–‹ã‚’申請ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã™ã‹ï¼Ÿ</h2>
+<p>ç¾åœ¨ã®ã¨ã“ã‚ã€ä½œè€…ã®çš†ã•ã‚“ã«ã¯ã€è‡ªä½œã®ã‚¢ãƒ‰ã‚ªãƒ³ã®ã¿ã‚’申請ã—ã¦ã„ãŸã ãよã†ãŠé¡˜ã„ã—ã¦ã„ã¾ã™ã€‚ç§ãŸã¡ã¯ã€ä½œè€…ã®çš†ã•ã‚“ãŒå…¬é–‹ã®æ©Ÿä¼šãŒå¢—ãˆã‚‹ã“ã¨ã‚’良ãæ€ã£ã¦ã„ã‚‹ã‹ã©ã†ã‹ã€ã‚ã‚‹ã„ã¯ä½œè€…ã«ã‚ˆã‚‹ä½œæ¥­å†…容ãŒç¾çŠ¶ã®ã‚¢ãƒ‰ã‚ªãƒ³ã«é©åˆ‡ã«å映ã•ã‚Œã¦ã„ã‚‹ã‹ã©ã†ã‹ã‚’確ã‹ã‚ãŸã„ã¨è€ƒãˆã¦ã„ã¾ã™ã€‚ã‚‚ã—ã€ã‚るアドオンãŒæ´—ç·´ã•ã‚Œã€ãã®ä½œè€…ãŒå®Ÿè³ªã¨ã‚‚ã« AMO ã®ãƒãƒªã‚·ãƒ¼ã«å¾“ã£ã¦ãŠã‚Šã€ãªãŠã‹ã¤ä¸–界約 1 億人ã«å‘ã‘ã¦ãれを公開ã™ã‚‹ã“ã¨ã§ã€Firefox ã¨ãã®ãƒ¦ãƒ¼ã‚¶ã€ãã—㦠Web 一般ã«æ©æµãŒã‚‚ãŸã‚‰ã•ã‚Œã‚‹ã¨æ€ã‚れる場åˆã¯ã€ã©ã†ãžé æ…®ãªã作者ã«ã‚¢ãƒ‰ã‚ªãƒ³ã®ç™»éŒ²ã‚’勧ã‚ã¦ãã ã•ã„。</p>
+
+<h2>自分ã®ã‚¢ãƒ‰ã‚ªãƒ³ã¯é•·ã„ã“ã¨ãƒ¬ãƒ“ュー待ã¡ã®ã¾ã¾ã§ã™ãŒã€è‡ªåˆ†ã¯å«Œã‚ã‚Œã¦ã„ã‚‹ã®ã§ã—ょã†ã‹ï¼Ÿ</h2>
+<p>ç§ãŸã¡ã¯ã‚ãªãŸã®ã“ã¨ã‚’å«Œã£ãŸã‚Šã¯ã—ã¾ã›ã‚“。ç§ãŸã¡ã¯ã‚¢ãƒ‰ã‚ªãƒ³é–‹ç™ºè€…ã®çš†ã•ã‚“を大切ã«æ€ã£ã¦ãŠã‚Šã€æº€è¶³åº¦ã¨ç”Ÿç”£æ€§ã‚’上ã’られるよã†ã€ã¾ãŸã€ä¸–界中ã®ãƒ¦ãƒ¼ã‚¶ãŒãã®æˆæžœã«ã‚ˆã£ã¦æ©æµã‚’å—ã‘られるよã†åŠªåŠ›ã—ã¦ã„ã¾ã™ã€‚ã§ã™ãŒã€æœ€çµ‚çš„ã«æŽ²è¼‰ã•ã‚Œã‚‹ã‚¢ãƒ‰ã‚ªãƒ³ã®å¯©æŸ»ã«ã¯æ…Žé‡ã‚’è¦ã™ã‚‹ãŸã‚ã€AMO ã¸ã®æŽ²è¼‰ã¯ã¾ã•ã—ãé‡è¦ãªã“ã¨ã§ã‚ã‚Šã€æ€¥ã„ã§ãã®å‡¦ç†ã‚’進ã‚ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“。ç§ãŸã¡ã¯ã€è©•ä¾¡çµæžœã‚’å¾…ã¤ã“ã¨ã¯æ™‚ã«ã‚¹ãƒˆãƒ¬ã‚¹ã®ãŸã¾ã‚‹ã“ã¨ã§ã‚ã‚‹ã¨ã„ã†å®ŸçŠ¶ã‚’ç†è§£ã—ã¦ãŠã‚Šã€å¾…ã¡æ™‚é–“ã‚’ã§ãã‚‹é™ã‚ŠçŸ­ãã—ãŸã„ã¨è€ƒãˆã¦ã„ã¾ã™ã€‚サンドボックス内ã§ã‚ˆã‚Šå¤šãã®ãƒ¦ãƒ¼ã‚¶ãŒå…¥å¿µã‹ã¤æ˜Žç¢ºãªãƒ¬ãƒ“ューを投稿ã—ã¦ãã ã•ã‚Œã°ã€ã“ã†ã—ãŸè©•ä¾¡ã®å®Ÿæ–½ãŒã‚ˆã‚Šç°¡å˜ã«ãªã‚Šã¾ã™ã®ã§ã€ã‚‚ã—サンドボックスã«ã‚ãªãŸãŒèˆˆå‘³ã‚’引ã‹ã‚ŒãŸã‚¢ãƒ‰ã‚ªãƒ³ãŒã‚ã‚Œã°ã€ãœã²ãã®ãƒ¬ãƒ“ューã«ã‚‚ã”å”力ãã ã•ã„。</p>
+
+<h2>自分ã®ã‚¢ãƒ‰ã‚ªãƒ³ã«æ·±åˆ»ãªãƒã‚°ã‚’見ã¤ã‘ã¾ã—ãŸã€‚ã™ãã«ä¿®æ­£ç‰ˆã‚’公開ã—ãŸã„ã¨æ€ã„ã¾ã™ãŒã€ã©ã†ã—ãŸã‚‰è‰¯ã„ã§ã—ょã†ã‹ï¼Ÿ</h2>
+<p>更新版を直ã¡ã«å…¬é–‹ã™ã‚‹å¿…è¦ã®ã‚る深刻ãªãƒã‚° (セキュリティや安定性ã€ãã®ä»–é‡å¤§ãªæ©Ÿèƒ½ã®å•é¡Œ) ãŒã‚¢ãƒ‰ã‚ªãƒ³ã«è¦‹ã¤ã‹ã£ãŸå ´åˆã¯ã€æ›´æ–°ç‰ˆã‚’登録ã™ã‚‹éš›ã€ã€Œãƒ¬ãƒ“ュー担当者ã¸ã®é€£çµ¡äº‹é …ã€ã‚’通ã˜ã¦ãれを知らã›ã¦ãã ã•ã„。もã¡ã‚ã‚“ãƒãƒ¼ã‚¸ãƒ§ãƒ³å±¥æ­´ã«ã‚‚ãã®å†…容を明記ã—ã¦ãã ã•ã„。ã¾ãŸã€ä½•äººã‹ã®æ—¢å­˜ãƒ¦ãƒ¼ã‚¶ã«å”力を求ã‚ã¦ã€ã‚µãƒ³ãƒ‰ãƒœãƒƒã‚¯ã‚¹å†…ã§æ›´æ–°ç‰ˆã®ãƒ†ã‚¹ãƒˆã‚’è¡Œã„ã€ãã®çµæžœã‚’詳ã—ã報告ã—ã¦ã‚‚らã†ã®ã‚‚ã²ã¨ã¤ã®æ‰‹ã§ã™ã€‚irc.mozilla.org ã® #addons ãƒãƒ£ãƒ³ãƒãƒ«ã«å…¥ã‚Œã°ã€æ‹…当者ã«ç›´æŽ¥çŠ¶æ³ã‚’知らã›ã‚‹ã“ã¨ã‚‚ã§ãã¾ã™ãŒã€ãã®å ´åˆã¯ã©ã†ã‹ã€è¾›æŠ±å¼·ãã€ç¤¼å„€æ­£ã—ãã—ã¦ãã ã•ã„。</p>
+<p>ãªãŠã€ãã‚Œãれも嘘ã¯ã¤ã‹ãªã„よã†ã«ã—ã¦ãã ã•ã„。ç§ãŸã¡ã¯å„ªå…ˆåº¦ã®é«˜ã„æ›´æ–°ã«ã¤ã„ã¦ã¯æ—©æ€¥ã«ãƒ¬ãƒ“ューを行ã†ã‚ˆã†å¿ƒæŽ›ã‘ã¦ã„ã¾ã™ãŒã€ãã®ä½œæ¥­ã«ã‚ˆã£ã¦ã€ç”³è«‹ã•ã‚Œã¦ã„ã‚‹ä»–ã®ã‚¢ãƒ‰ã‚ªãƒ³ã‚„ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã‚’評価ã™ã‚‹æ™‚間を失ã„ã€æ™‚ã«ã¯å¯ã‚‹æ™‚é–“ã‚„å‹äººãƒ»å®¶æ—ã¨ã®æ™‚é–“ã¾ã§ã‚‚犠牲ã«ã™ã‚‹ã“ã¨ã«ãªã‚‹ãŸã‚ã€ã“ã®ä»•çµ„ã¿ã‚’「レビュー待ã¡ã®åˆ—ã¸ã®å‰²ã‚Šè¾¼ã¿ã€ã«åˆ©ç”¨ã—よã†ã¨ã™ã‚‹é–‹ç™ºè€…ã«ã¯æ„Ÿå¿ƒã—ã¾ã›ã‚“。ã“ã®ä»•çµ„ã¿ã‚’利用ã—ã¦ã‚‚良ã„ã‹è‡ªä¿¡ãŒãªã„ã¨ãã¯ã€irc.mozilla.org ã® #addons ãƒãƒ£ãƒ³ãƒãƒ«ã§ã‚¢ãƒ‰ãƒã‚¤ã‚¹ã‚’求ã‚ã¦ãã ã•ã„。</p>
+
+<h2>自分ã®ã‚¢ãƒ‰ã‚ªãƒ³ã¯ä¸å½“ãªè©•ä¾¡ã‚’å—ã‘ãŸã®ã§ã¯ãªã„ã‹ã¨æ€ã„ã¾ã™ã€‚ã©ã†ã—ãŸã‚‰è‰¯ã„ã§ã—ょã†ã‹ï¼Ÿ</h2>
+<p>ã‚ãªãŸã®ã‚¢ãƒ‰ã‚ªãƒ³ãŒä¸å½“ã«è©•ä¾¡ã•ã‚Œã€ãã®çµæžœèª¤ã£ã¦å…¬é–‹ç”³è«‹ãŒå´ä¸‹ã•ã‚ŒãŸã¨æ€ã‚れる場åˆã¯ã€amo-editors@mozilla.org ã«ãƒ¡ãƒ¼ãƒ«ã‚’é€ã‚Šã€ãã®æŽ¨è«–を詳ã—ã説明ã—ã¦ãã ã•ã„。礼儀正ã—ãã¯ã£ãã‚Šã¨ã—ãŸæ–‡é¢ã§ã€ãã®ã‚¢ãƒ‰ã‚ªãƒ³ãŒã©ã†ä¸å½“ã«è©•ä¾¡ã•ã‚ŒãŸã®ã‹ã‚’具体的ã«èª¬æ˜Žã—ã¦ãã ã•ã„。</p>
+<p>(公開申請ã®çµæžœé€šçŸ¥ã«å•é¡ŒãŒæ›¸ã‹ã‚Œã¦ã„ã¦ã€ãれらã®ä¿®æ­£ãŒã™ã¹ã¦å®Œäº†ã—ãŸå ´åˆã¯ã€è©•ä¾¡çµæžœã«æŠ—è­°ã™ã‚‹ã®ã§ã¯ãªãã€é–‹ç™ºè€…å‘ã‘コントロールパãƒãƒ«ã‚’通ã˜ã¦å†åº¦ç”³è«‹ã‚’è¡Œã£ã¦ãã ã•ã„。)</p>
+
+<h2>自分ã®ã‚¢ãƒ‰ã‚ªãƒ³ã¯ã“ã‚Œã¾ã§å…¬é–‹ã•ã‚Œã¦ã„ãŸã®ã«ã€ã‚µãƒ³ãƒ‰ãƒœãƒƒã‚¯ã‚¹ã«ç½®ã‹ã‚Œã¦ã—ã¾ã„ã¾ã—ãŸã€‚何ãŒã‚ã£ãŸã®ã§ã—ょã†ã‹ï¼Ÿ</h2>
+<p>アドオン㌠AMO サイトã¸ã®å…¬é–‹æ¡ä»¶ã«åˆã‚ãªããªã£ãŸå ´åˆã€ãã®ã‚¢ãƒ‰ã‚ªãƒ³ã¯ã‚µãƒ³ãƒ‰ãƒœãƒƒã‚¯ã‚¹ã«æˆ»ã•ã‚Œã¾ã™ã€‚ãã†ã—ãŸå‡¦ç†ã‚’è¡Œã†éš›ã¯ã€æ³•çš„制é™ãŒãªã„é™ã‚Šä½œè€…ã«ãƒ¡ãƒ¼ãƒ«ã§é€šçŸ¥ã—ã€éžå…¬é–‹ã«ãªã£ãŸç†ç”±ã‚’説明ã—ã¾ã™ã€‚</p>
+<p>アドオンã®å…¬é–‹ã«é–¢ã—ã¦ã€ã‚µã‚¤ãƒˆã«ãƒã‚°ã‚’見ã¤ã‘ãŸå ´åˆã¯ã€Bugzilla を通ã˜ã¦å ±å‘Šã‚’è¡Œã£ã¦ãã ã•ã„。「addons.mozilla.orgã€ãƒ—ロダクトã®ã€ŒPublic Pagesã€ã‚³ãƒ³ãƒãƒ¼ãƒãƒ³ãƒˆã‚’é¸æŠžã—ã¦ã€ã§ãã‚‹é™ã‚Šè©³ã—ã状æ³ã‚’説明ã—ã¦ãã ã•ã„。</p>
+
+<h2>自分ã®ã‚¢ãƒ‰ã‚ªãƒ³ã¯å…¬é–‹ã•ã‚Œã¦ã„ã¦ã€äººæ°—ãŒã‚るよã†ã§ã™ã€‚ã©ã†ã™ã‚Œã°ã€ŒãŠã™ã™ã‚ã®ã‚¢ãƒ‰ã‚ªãƒ³ã€ä¸€è¦§ã«è¼‰ã›ã¦ã‚‚らãˆã¾ã™ã‹ï¼Ÿ</h2>
+<p>ã‚ãªãŸã®æˆæžœãŒã€ã‚¢ãƒ‰ã‚ªãƒ³ã®åŠ›ã‚’見ã›ã¤ã‘る優れãŸäº‹ä¾‹ã¨ãªã‚Šã€æ‹¡å¼µæ€§ã¨ã‚«ã‚¹ã‚¿ãƒžã‚¤ã‚ºæ€§ã«å„ªã‚ŒãŸ Web ブラウザã¨ã„ㆠFirefox ã®ä¾¡å€¤ã‚’実証・促進ã—ã€å„ªã‚ŒãŸãƒ¦ãƒ¼ã‚¶ä½“験をæä¾›ã§ãã‚‹ã¨è€ƒãˆã‚‰ã‚Œã‚‹ãªã‚‰ã€ã€ŒãŠã™ã™ã‚ã®ã‚¢ãƒ‰ã‚ªãƒ³ã€ä¸€è¦§ã¸ã®è¿½åŠ æ¤œè¨Žã‚’ä¾é ¼ã•ã‚Œã¦ã¿ã¦ã¯ã„ã‹ãŒã§ã—ょã†ã‹ã€‚amo-editors@mozilla.org ã¸ãƒ¡ãƒ¼ãƒ«ã‚’é€ã‚Šã€ã‚ãªãŸã®ã‚¢ãƒ‰ã‚ªãƒ³ãŒã©ã®ã‚ˆã†ã«ç´ æ™´ã‚‰ã—ã„ã‹ã‚’説明ã—ã¦ãã ã•ã„。</p>
+<p>メールã«ã¯ã€ã€Œå°‘ãªãã¨ã‚‚ã€ä»¥ä¸‹ã®é …ç›®ã«é–¢ã™ã‚‹æƒ…報を記述ã—ã¦ãã ã•ã„。</p>
+<ul>
+<li>ユーザ㮠Web 体験ãŒã©ã‚Œã ã‘å‘上ã™ã‚‹ã‹</li>
+<li>大åŠã® Firefox ユーザã«ã¨ã£ã¦ã€ãã®ã‚¢ãƒ‰ã‚ªãƒ³ãŒã©ã‚Œã ã‘ãµã•ã‚ã—ã„ã‹</li>
+<li>ãã®ã‚¢ãƒ‰ã‚ªãƒ³ãŒã©ã‚Œã ã‘ Mozilla プロジェクトã®ä¾¡å€¤ã‚’実証・æä¾›ã§ãã‚‹ã‹ã€‚特ã«ã€ãƒ¦ãƒ¼ã‚¶ã«å¯¾ã™ã‚‹ã‚«ã‚¹ã‚¿ãƒžã‚¤ã‚ºæ€§ã®æä¾›ã€ãƒ—ライãƒã‚·ãƒ¼ã‚„セキュリティã®ä¿è­·ã€Web ã¸ã®ãƒ¦ãƒ‹ãƒãƒ¼ã‚µãƒ«ã‚¢ã‚¯ã‚»ã‚¹ã€ã‚ªãƒ¼ãƒ—ンãªæ¨™æº–ã¨ãƒ‡ãƒ¼ã‚¿ã®æ´»ç”¨ã«ã¤ã„ã¦ã€‚</li>
+<li>ãã®ã‚¢ãƒ‰ã‚ªãƒ³ãŒä»–ã®åŒã˜ã‚ˆã†ãªã‚¢ãƒ‰ã‚ªãƒ³ã¨ã©ã†ç•°ãªã‚‹ã®ã‹ (優劣ã®ä¸¡é¢ã‹ã‚‰)</li>
+<li>ユーザやレビュー担当者ã€ãƒ–ロガーã€å®‡å®™é£›è¡Œå£«ã€ã‚ã‚‹ã„ã¯å®¶åº­ã®ãƒšãƒƒãƒˆã‹ã‚‰ã©ã®ã‚ˆã†ãªåå¿œãŒã‚ã£ãŸã‹ (優劣ã®ä¸¡é¢ã‹ã‚‰)</li>
+</ul>
+<p>ã©ã‚Œã ã‘素晴らã—ã作り込ã¾ã‚ŒãŸå®Œç’§ãªã‚¢ãƒ‰ã‚ªãƒ³ã§ã‚‚「ãŠã™ã™ã‚ã®ã‚¢ãƒ‰ã‚ªãƒ³ã€ä¸€è¦§ã«æŽ²è¼‰ã•ã‚Œã‚‹ä¿è¨¼ã¯ã‚ã‚Šã¾ã›ã‚“ãŒã€ä¾é ¼ã®ãƒ¡ãƒ¼ãƒ«ã«ã‚ˆã‚Šå®Œå…¨ãªæƒ…報を書ã込むã“ã¨ã§ã€ç§ãŸã¡ãŒãれを承諾ã§ãã‚‹å¯èƒ½æ€§ã‚‚高ã¾ã‚Šã¾ã™ã€‚ã¤ã¾ã‚Šã€ã“ã®ä¸€è¦§ã¯ Mozilla ã®è£é‡ã«ã‚ˆã£ã¦ä¿å®ˆã•ã‚Œã‚‹ã¹ãã§ã€å®Ÿéš›ã«ãã®é€šã‚Šã«é‹å–¶ã•ã‚Œã¦ãŠã‚Šã€ãƒ¦ãƒ¼ã‚¶ã® Web 体験ã¨ä¿è­·ãŒä½•ã‚ˆã‚Šã‚‚é‡è¦–ã•ã‚Œã‚‹ã¨ã“ã‚ãªã®ã§ã™ã€‚</p>
diff --git a/site/app/locale/ja/pages/sandbox.thtml b/site/app/locale/ja/pages/sandbox.thtml
new file mode 100644
index 0000000..4fa9146
--- /dev/null
+++ b/site/app/locale/ja/pages/sandbox.thtml
@@ -0,0 +1,12 @@
+<h1>サンドボックスã®ãƒ¬ãƒ“ューシステム</h1>
+<h2>サンドボックスã¨ã¯</h2>
+<p>サンドボックスã¯ã€çµŒé¨“豊富ãªãƒ¦ãƒ¼ã‚¶ãŒä¸€èˆ¬å…¬é–‹å‰ã®ã‚¢ãƒ‰ã‚ªãƒ³ã‚’テストã™ã‚‹å ´æ‰€ã§ã™ã€‚サンドボックスã¸ã®ã‚¢ã‚¯ã‚»ã‚¹ã¯ã‚¢ã‚«ã‚¦ãƒ³ãƒˆè¨­å®šã§æœ‰åŠ¹ã«ã§ãã¾ã™ã€‚サンドボックスã«ã‚るアドオンã¯ã‚¨ãƒ‡ã‚£ã‚¿ã«ã‚ˆã‚‹ãƒ†ã‚¹ãƒˆã‚’経ã¦ãŠã‚‰ãšã€ã‚ãªãŸã®ã‚³ãƒ³ãƒ”ュータã«æ‚ªå½±éŸ¿ã‚’åŠã¼ã™ãŠãã‚ŒãŒã‚ã‚Šã¾ã™ã®ã§ã€ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã•ã‚Œã‚‹å ´åˆã¯æ³¨æ„ãŒå¿…è¦ã§ã™ã€‚</p>
+<h2>アドオンを公開ã™ã‚‹ã«ã¯</h2>
+<!-- To localize the flowchart image, see http://wiki.mozilla.org/Update:Remora_Sandbox_Flowchart -->
+<div style="text-align: center;">%s</div>
+<ol>
+<li><strong>開発者å‘ã‘コントロールパãƒãƒ«ã§ã‚¢ãƒ‰ã‚ªãƒ³ã‚’登録ã—ã¾ã™</strong>。ã‚ãªãŸã®ã‚¢ãƒ‰ã‚ªãƒ³ã¯ã™ãã« Mozilla Add-ons ã®ã€Œã‚µãƒ³ãƒ‰ãƒœãƒƒã‚¯ã‚¹ã€ãƒšãƒ¼ã‚¸ã«è¡¨ç¤ºã•ã‚Œã¾ã™ã€‚サンドボックスã§ã¯çµŒé¨“豊富ãªãƒ¦ãƒ¼ã‚¶ãŒãƒ†ã‚¹ãƒˆã‚’ã—ãŸä¸Šã§ãƒ•ã‚£ãƒ¼ãƒ‰ãƒãƒƒã‚¯ã‚’è¡Œã„ã¾ã™ã€‚サンドボックスã¸ã®ã‚¢ã‚¯ã‚»ã‚¹ã¯ã‚¢ã‚«ã‚¦ãƒ³ãƒˆè¨­å®šã§æœ‰åŠ¹ã«ã§ãã¾ã™ã€‚</li>
+<li><strong>アドオンã®å…¬é–‹ã‚’申請ã—ã¾ã™</strong>。開発者å‘ã‘コントロールパãƒãƒ«ã«ã‚¢ãƒ‰ã‚ªãƒ³ã®å…¬é–‹ã‚’申請ã™ã‚‹ãŸã‚ã®ãƒªãƒ³ã‚¯ãŒã‚ã‚Šã¾ã™ã€‚申請を行ã†ã¨ã€ã‚ãªãŸã®ã‚¢ãƒ‰ã‚ªãƒ³ã¯ã‚¨ãƒ‡ã‚£ã‚¿ã®ãƒ¬ãƒ“ュー待ã¡ä¸€è¦§ã«è¿½åŠ ã•ã‚Œã¾ã™ã€‚</li>
+<li><strong>エディタãŒã‚ãªãŸã®ã‚¢ãƒ‰ã‚ªãƒ³ã‚’レビューã—ã¾ã™</strong>。Mozilla Add-ons ã®ã‚¨ãƒ‡ã‚£ã‚¿ãŒã‚ãªãŸã®ã‚¢ãƒ‰ã‚ªãƒ³ã‚’インストールã—ã¦ã€æ­£ã—ã動作ã™ã‚‹ã‹ã©ã†ã‹ãƒ†ã‚¹ãƒˆã‚’è¡Œã„ã¾ã™ã€‚エディタã¯ã‚µãƒ³ãƒ‰ãƒœãƒƒã‚¯ã‚¹ãƒ†ã‚¹ã‚¿ãƒ¼ã«ã‚ˆã‚‹ãƒ¬ãƒ“ューもå‚ç…§ã—ã¾ã™ã€‚</li>
+<li><strong>アドオンを一般ã«å…¬é–‹ã™ã‚‹ã‹ã©ã†ã‹ãŒæ±ºã¾ã‚Šã¾ã™</strong>。エディタã¯ã€ã‚ãªãŸã®ã‚¢ãƒ‰ã‚ªãƒ³ã‚’公開ページã«è¼‰ã›ã‚‹ã‹ã€ã‚µãƒ³ãƒ‰ãƒœãƒƒã‚¯ã‚¹ã«ä¿ç•™ã—ã¾ã™ã€‚公開ãŒä¿ç•™ã•ã‚ŒãŸå ´åˆã€ã‚¨ãƒ‡ã‚£ã‚¿ã®ã‚³ãƒ¡ãƒ³ãƒˆã«å¾“ã£ã¦å¤‰æ›´ã‚’加ãˆãŸå¾Œã€å†åº¦å…¬é–‹ç”³è«‹ã‚’è¡Œã†ã“ã¨ãŒã§ãã¾ã™ã€‚公開ページã«æŽ²è¼‰ã•ã‚ŒãŸå ´åˆã€ä»Šå¾Œç™»éŒ²ã—ãŸãƒãƒ¼ã‚¸ãƒ§ãƒ³ã¯ã€ã‚¨ãƒ‡ã‚£ã‚¿ã®ãƒ¬ãƒ“ューをå—ã‘ã¦å…¬é–‹ãƒšãƒ¼ã‚¸ã«æŽ²è¼‰ã•ã‚Œã‚‹ã¾ã§ã‚µãƒ³ãƒ‰ãƒœãƒƒã‚¯ã‚¹ã«è¡¨ç¤ºã•ã‚Œã¾ã™ã€‚一度公開ページã«æŽ²è¼‰ã•ã‚Œã‚Œã°å†åº¦å…¬é–‹ç”³è«‹ã‚’è¡Œã†å¿…è¦ã¯ãªãã€ä»¥é™ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã¯è‡ªå‹•çš„ã«ãƒ¬ãƒ“ュー待ã¡ãƒªã‚¹ãƒˆã«è¿½åŠ ã•ã‚Œã¾ã™ã€‚</li>
+</ol>
diff --git a/site/app/locale/ja/pages/statistics_help.thtml b/site/app/locale/ja/pages/statistics_help.thtml
new file mode 100644
index 0000000..1a15a46
--- /dev/null
+++ b/site/app/locale/ja/pages/statistics_help.thtml
@@ -0,0 +1,8 @@
+<h3>ヘルプ</h3>
+<p>統計ダッシュボードã«ã¯ã€ã‚ãªãŸã®ã‚¢ãƒ‰ã‚ªãƒ³ã®ãŸã‚ã«åŽé›†ã•ã‚ŒãŸã€ãƒ€ã‚¦ãƒ³ãƒ­ãƒ¼ãƒ‰ã‚„æ›´æ–°ãƒã‚§ãƒƒã‚¯ã«é–¢ã™ã‚‹ãƒ‡ãƒ¼ã‚¿ãŒè¡¨ç¤ºã•ã‚Œã¾ã™ã€‚</p>
+
+<h4>ダウンロード</h4>
+<p>ダウンロード数ã¯æ¯Žæ—¥æ›´æ–°ã•ã‚Œã¾ã™ã€‚ã“ã‚Œã¯ã€åˆã‚ã«ãƒ€ã‚¦ãƒ³ãƒ­ãƒ¼ãƒ‰ã•ã‚ŒãŸã‚¢ãƒ‰ã‚ªãƒ³ã®ã¿ã§ã€æ›´æ–°ã¯å«ã¾ã‚Œã¾ã›ã‚“。</p>
+
+<h4>æ›´æ–°ãƒã‚§ãƒƒã‚¯</h4>
+<p>ã“ã®ã‚µã‚¤ãƒˆã‹ã‚‰ãƒ€ã‚¦ãƒ³ãƒ­ãƒ¼ãƒ‰ã•ã‚ŒãŸã‚¢ãƒ‰ã‚ªãƒ³ã¯ã€1 æ—¥ 1 回ã€æ›´æ–°ã®ãƒã‚§ãƒƒã‚¯ãŒè¡Œã‚ã‚Œã¾ã™ã€‚ã“れらã®æ›´æ–°ãƒã‚§ãƒƒã‚¯ã®åˆè¨ˆæ•°ãŒã€Œ1 æ—¥ã®ã‚¢ã‚¯ãƒ†ã‚£ãƒ–ユーザ数ã€ã¨ã—ã¦è¡¨ç¤ºã•ã‚Œã¾ã™ã€‚「1 æ—¥ã®ã‚¢ã‚¯ãƒ†ã‚£ãƒ–ユーザ数 (ADU)ã€ã¯ã€ã‚¢ãƒ‰ã‚ªãƒ³ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã€ãƒ—ラットフォーム (OS)ã€ã‚¢ãƒ‰ã‚ªãƒ³ã®ã‚¹ãƒ†ãƒ¼ã‚¿ã‚¹ã€ã‚¢ãƒ—リケーションã«ã‚ˆã£ã¦åˆ†é¡žã•ã‚Œã¾ã™ã€‚ã“ã®ãƒ‡ãƒ¼ã‚¿ã¯ä»Šã®ã¨ã“ã‚ã€æ¯Žé€± 1 æ—¥ã€æ°´æ›œæ—¥ã«è¨˜éŒ²ã•ã‚Œã¾ã™ã€‚</p>
diff --git a/site/app/locale/ja/pages/submission_help.thtml b/site/app/locale/ja/pages/submission_help.thtml
new file mode 100644
index 0000000..31e3f42
--- /dev/null
+++ b/site/app/locale/ja/pages/submission_help.thtml
@@ -0,0 +1,35 @@
+<h1>申請ã®æµã‚Œã«é–¢ã™ã‚‹ãƒ˜ãƒ«ãƒ—</h1>
+<p><b>太字</b> ã§è¡¨è¨˜ã•ã‚Œã¦ã„ã‚‹é …ç›®ã¯å¿…é ˆã§ã™ã€‚ãれ以外ã®é …ç›®ã¯ä»»æ„ã§ã™ã€‚</p>
+<h2 id="step1">ステップ 1: アップロード</h2>
+<ul class="submissionHelp">
+ <li><span class="required">アドオンã®ç¨®é¡ž</span> - アップロードã•ã‚ŒãŸãƒ•ã‚¡ã‚¤ãƒ«ã«åŸºã¥ã„ã¦è‡ªå‹•çš„ã«åˆ¤åˆ¥ã•ã‚Œã¾ã™ã®ã§ã€é€šå¸¸ã¯å¤‰æ›´ã™ã‚‹å¿…è¦ã¯ã‚ã‚Šã¾ã›ã‚“。</li>
+ <li><span class="required">アドオンファイル</span> - install.rdf ファイルを内包ã—ãŸã‚¢ãƒ‰ã‚ªãƒ³ã®ãƒ‘ッケージファイルをé¸æŠžã—ã¾ã™ã€‚ファイルãŒç‰¹å®šã®ãƒ—ラットフォームã®ã¿ã«å¯¾å¿œã—ã¦ã„ã‚‹å ´åˆã¯ã€ãã®ãƒ—ラットフォームをé¸æŠžã™ã‚‹ã“ã¨ã§ã€ãƒ—ラットフォームã”ã¨ã®ãƒ•ã‚¡ã‚¤ãƒ«ã‚’一度ã«ã‚¢ãƒƒãƒ—ロードã§ãã¾ã™ã€‚</li>
+ <li>アイコンファイル - Mozilla Add-ons ã®ã‚µã‚¤ãƒˆä¸Šã§ã¯ã‚¢ãƒ‰ã‚ªãƒ³ã®ã‚¿ã‚¤ãƒˆãƒ«ã¨ã¨ã‚‚ã«è¡¨ç¤ºã•ã‚Œã€ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«å¾Œã¯ã‚¢ãƒ‰ã‚ªãƒ³ãƒžãƒãƒ¼ã‚¸ãƒ£ã«ã‚‚表示ã•ã‚Œã¾ã™ã€‚32x32 ピクセルより大ãã„å ´åˆã¯ã€ç¸¦æ¨ªæ¯”ã‚’ä¿ã£ãŸã¾ã¾è‡ªå‹•çš„ã«ãƒªã‚µã‚¤ã‚ºã•ã‚Œã¾ã™ã€‚</li>
+ <li><span class="required">デフォルトã®ãƒ­ã‚±ãƒ¼ãƒ«</span> - アドオンã®ä¸»è¦ãƒ­ã‚±ãƒ¼ãƒ« (言語+地域設定) を指定ã—ã¾ã™ã€‚ユーザãŒé¸æŠžã—ãŸãƒ­ã‚±ãƒ¼ãƒ«ãŒã‚¢ãƒ‰ã‚ªãƒ³ã«å«ã¾ã‚Œã¦ã„ãªã„å ´åˆã€ã“ã®ãƒ­ã‚±ãƒ¼ãƒ«ãŒåˆ©ç”¨ã•ã‚Œã¾ã™ã€‚</li>
+ <li>ç¾åœ¨ç™»éŒ²ã•ã‚Œã¦ã„るアドオン情報ã®ç¢ºèªã‚’スキップ - 既存ã®ã‚¢ãƒ‰ã‚ªãƒ³ã‚’æ›´æ–°ã™ã‚‹å ´åˆã€ã“ã®é …ç›®ãŒè¡¨ç¤ºã•ã‚Œã¾ã™ã€‚ã“ã®é …ç›®ã«ãƒã‚§ãƒƒã‚¯ã‚’入れるã¨ã€ã‚¹ãƒ†ãƒƒãƒ— 2 を飛ã°ã—ã¦ã€ã‚¹ãƒ†ãƒƒãƒ— 3 ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³æƒ…報を入力ã™ã‚‹ç”»é¢ã«ç§»å‹•ã—ã¾ã™ã€‚</li>
+</ul>
+
+<h2 id="step2">ステップ 2: アドオンã®è©³ç´°</h2>
+<ul class="submissionHelp">
+ <li><span class="required">タイトル</span> - アドオンã®ã‚¿ã‚¤ãƒˆãƒ«ã‚’ã§ãƒ‡ãƒ•ã‚©ãƒ«ãƒˆã®ãƒ­ã‚±ãƒ¼ãƒ«ã§å…¥åŠ›ã—ã¾ã™ã€‚</li>
+ <li><span class="required">作者</span> - アドオンã®ç·¨é›†æ¨©é™ã‚’æŒã£ã¦ã„ã‚‹ã™ã¹ã¦ã®ãƒ¦ãƒ¼ã‚¶ã§ã€ã‚¢ãƒ‰ã‚ªãƒ³ã®ã‚¿ã‚¤ãƒˆãƒ«ã¨ã¨ã‚‚ã«è¡¨ç¤ºã•ã‚Œã¾ã™ã€‚</li>
+ <li><span class="required">カテゴリ</span> - 該当ã™ã‚‹ã‚«ãƒ†ã‚´ãƒªã‚’é¸æŠžã—ã¾ã™ã€‚</li>
+ <li>ホームページ - デフォルトã®ãƒ­ã‚±ãƒ¼ãƒ«ã§è¨˜è¿°ã•ã‚ŒãŸã‚¢ãƒ‰ã‚ªãƒ³ã® Web サイトを入力ã—ã¾ã™ã€‚</li>
+ <li><span class="required">è¦ç´„</span> - アドオンã®æ¦‚è¦ã‚’デフォルトã®ãƒ­ã‚±ãƒ¼ãƒ«ã§å…¥åŠ›ã—ã¾ã™ã€‚250 文字ã¾ã§å…¥åŠ›å¯èƒ½ã§ã™ã€‚アドオンã®å…¬é–‹ãƒšãƒ¼ã‚¸ãŠã‚ˆã³æ¤œç´¢çµæžœã«è¡¨ç¤ºã•ã‚Œã¾ã™ã€‚</li>
+ <li><span class="required">説明</span> - アドオンã®èª¬æ˜Žã‚’デフォルトã®ãƒ­ã‚±ãƒ¼ãƒ«ã§å…¥åŠ›ã—ã¾ã™ã€‚アドオンã®å…¬é–‹ãƒšãƒ¼ã‚¸ã§è¦ç´„ã®ä¸‹ã«è¡¨ç¤ºã•ã‚Œã¾ã™ã€‚</li>
+ <li>EULA - ユーザã«ãƒ€ã‚¦ãƒ³ãƒ­ãƒ¼ãƒ‰ã®å‰ã«åŒæ„を求ã‚るエンドユーザライセンス契約をデフォルトã®ãƒ­ã‚±ãƒ¼ãƒ«ã§å…¥åŠ›ã—ã¾ã™ã€‚</li>
+ <li>プライãƒã‚·ãƒ¼ãƒãƒªã‚·ãƒ¼ - アドオンã®ãƒ—ライãƒã‚·ãƒ¼ãƒãƒªã‚·ãƒ¼ã‚’デフォルトã®ãƒ­ã‚±ãƒ¼ãƒ«ã§å…¥åŠ›ã—ã¾ã™ã€‚エンドユーザã®å€‹äººæƒ…å ±ã®å–り扱ã„ã«ã¤ã„ã¦èª¬æ˜Žã—ã¦ãã ã•ã„。アドオンã®å…¬é–‹ãƒšãƒ¼ã‚¸ã«ã‚るインストールボタンã¨ä¸¦ã‚“ã§ãƒªãƒ³ã‚¯ã•ã‚Œã¾ã™ã€‚プライãƒã‚·ãƒ¼ãƒãƒªã‚·ãƒ¼ã«ã©ã®ã‚ˆã†ãªè¨˜è¿°ãŒå¿…è¦ã‹ã€ã‚ã‚‹ã„ã¯ã‚ãªãŸã®ã‚¢ãƒ‰ã‚ªãƒ³ã«ãƒ—ライãƒã‚·ãƒ¼ãƒãƒªã‚·ãƒ¼ãŒå¿…è¦ã‹ã€ã¨ã„ã£ãŸã“ã¨ã¯ã€<a href="%s">アドオンãƒãƒªã‚·ãƒ¼</a> ã®ãƒšãƒ¼ã‚¸ã§ã”確èªãã ã•ã„。</li>
+ <li>サイト上ã§ã®ã‚½ãƒ¼ã‚¹ãƒ•ã‚¡ã‚¤ãƒ«ã®è¡¨ç¤ºã‚’許å¯ã™ã‚‹ - ã“ã®é …ç›®ã«ãƒã‚§ãƒƒã‚¯ã‚’入れるã¨ã€ãƒ¦ãƒ¼ã‚¶ãŒã‚µã‚¤ãƒˆä¸Šã§ã‚¢ãƒ‰ã‚ªãƒ³ã®ã‚½ãƒ¼ã‚¹ã‚³ãƒ¼ãƒ‰ã‚’見られるよã†ã«ãªã‚Šã¾ã™ã€‚</li>
+ <li>ã“ã‚Œã¯æ­£å¼ãƒªãƒªãƒ¼ã‚¹å‰ã®ã‚¢ãƒ‰ã‚ªãƒ³ã§ã™ - ã“ã®é …ç›®ã«ãƒã‚§ãƒƒã‚¯ã‚’入れるã¨ã€ãƒ™ãƒ¼ã‚¿ç‰ˆã®ã‚¢ãƒ‰ã‚ªãƒ³ã§ã‚ã‚‹ã“ã¨ãŒæ˜Žè¨˜ã•ã‚Œã¾ã™ã€‚リリースå‰ã®ã‚¢ãƒ‰ã‚ªãƒ³ã¯ã‚µãƒ³ãƒ‰ãƒœãƒƒã‚¯ã‚¹ã«ä¿ç•™ã•ã‚Œã€ã“ã®ãƒ•ãƒ©ã‚°ãŒå¤–ã•ã‚Œã‚‹ã¾ã§å…¬é–‹ç”³è«‹ã‚’è¡Œã†ã“ã¨ã¯ã§ãã¾ã›ã‚“。</li>
+ <li>ã“ã‚Œã¯ç‰¹å®šã®ã‚µã‚¤ãƒˆç”¨ã®ã‚¢ãƒ‰ã‚ªãƒ³ã§ã™ - ã“ã®é …ç›®ã«ãƒã‚§ãƒƒã‚¯ã‚’入れるã¨ã€ç‰¹å®šã® Web サイトã«å¯¾å¿œã—ãŸã‚¢ãƒ‰ã‚ªãƒ³ã§ã‚ã‚‹ã“ã¨ãŒæ˜Žè¨˜ã•ã‚Œã¾ã™ã€‚例ãˆã°ã€ç‰¹å®šã®ã‚µã‚¤ãƒˆã®è¦‹ãŸç›®ã«å¤‰æ›´ã‚’加ãˆã‚‹ã‚‚ã®ã‚„ã€ç‰¹å®šã®ã‚µã‚¤ãƒˆã®ã‚³ãƒ³ãƒ†ãƒ³ãƒ„を表示ã™ã‚‹ã‚‚ã®ãªã©ãŒè©²å½“ã—ã¾ã™ã€‚ã“ã®é …ç›®ã¯ã‚¨ãƒ‡ã‚£ã‚¿ã®å‚考ã«ãªã‚Šã€ã¾ãŸä»Šå¾Œã€æ¤œç´¢æ¡ä»¶ã¨ã—ã¦ã‚‚利用ã§ãるよã†ã«ãªã‚‹äºˆå®šã§ã™ã€‚</li>
+ <li>ã“ã®ã‚¢ãƒ‰ã‚ªãƒ³ã¯å¤–部アプリケーションを必è¦ã¨ã—ã¾ã™ - ã“ã®é …ç›®ã«ãƒã‚§ãƒƒã‚¯ã‚’入れるã¨ã€ä»–ã®ã‚¢ãƒ—リケーションを利用ã™ã‚‹ã‚¢ãƒ‰ã‚ªãƒ³ã§ã‚ã‚‹ã“ã¨ãŒæ˜Žè¨˜ã•ã‚Œã¾ã™ã€‚ã“ã®é …ç›®ã¯ã‚¨ãƒ‡ã‚£ã‚¿ã®å‚考ã«ãªã‚Šã€ã¾ãŸä»Šå¾Œã€æ¤œç´¢æ¡ä»¶ã¨ã—ã¦ã‚‚利用ã§ãるよã†ã«ãªã‚‹äºˆå®šã§ã™ã€‚</li>
+</ul>
+
+<h2 id="step3">ステップ 3: ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã®è©³ç´°</h2>
+<ul class="submissionHelp">
+ <li><span class="required">ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã®èª¬æ˜Ž</span> - 登録ã™ã‚‹ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã®è¦ç´„ã‚ã‚‹ã„ã¯å¤‰æ›´ç‚¹ã‚’入力ã—ã¾ã™ã€‚ã“ã®é …ç›®ã¯ã€æ–°ãŸã«ç™»éŒ²ã‚’è¡Œã†å ´åˆã¯ä»»æ„ã§ã™ãŒã€æ›´æ–°ã®éš›ã¯å¿…é ˆã§ã™ã€‚</li>
+ <li>レビュー担当者ã¸ã®é€£çµ¡äº‹é … - アドオンã®ãƒ¬ãƒ“ューを行ã†ã‚¨ãƒ‡ã‚£ã‚¿ã«æƒ…報をä¼ãˆã‚‹å‚™è€ƒæ¬„ã§ã™ã€‚テスト用アカウントã®æƒ…報や特別ãªæ³¨æ„点ã¯ã“ã“ã«å…¥åŠ›ã—ã¾ã™ã€‚</li>
+</ul>
+
+<h2 id="step4">ステップ 4: ローカライズ</h2>
+<p>上記ã®ã‚¹ãƒ†ãƒƒãƒ—ã§å…¥åŠ›ã—ãŸé …目をã€å¯¾å¿œã—ã¦ã„ã‚‹ã™ã¹ã¦ã®ãƒ­ã‚±ãƒ¼ãƒ«ã«ãƒ­ãƒ¼ã‚«ãƒ©ã‚¤ã‚ºã§ãã¾ã™ã€‚ロケールをé¸æŠžã—ã¦ç¿»è¨³ã‚’入力ã—ã¾ã™ã€‚</p>
diff --git a/site/app/locale/ko/LC_MESSAGES/messages.mo b/site/app/locale/ko/LC_MESSAGES/messages.mo
new file mode 100644
index 0000000..ebfef18
--- /dev/null
+++ b/site/app/locale/ko/LC_MESSAGES/messages.mo
Binary files differ
diff --git a/site/app/locale/ko/LC_MESSAGES/messages.po b/site/app/locale/ko/LC_MESSAGES/messages.po
new file mode 100644
index 0000000..3a1025c
--- /dev/null
+++ b/site/app/locale/ko/LC_MESSAGES/messages.po
@@ -0,0 +1,8738 @@
+# Remora Preliminary Language File
+# Copyright (C) 2006 Mozilla Corporation
+# This file is distributed under the same license as the REMORA package.
+# Wil Clouser <clouserw@mozilla.com>, 2006.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: REMORA 0.1\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2009-01-16 11:45-0800\n"
+"PO-Revision-Date: 2008-09-18 13:55+0900\n"
+"Last-Translator: \n"
+"Language-Team: Korean <kmozup@googlegroups.com>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=n != 1;\n"
+
+#: views/addons/policy.thtml:98
+msgid "a_cancel_installation"
+msgstr "설치 취소"
+
+#. This is the text that appears on buttons to download add-ons.
+#. %$1s is an optional string that only appears if the add-on is only available for
+#. a certain platform. Examples: (Windows) or (Linux)
+#. Note that the parentheses are included in the string. :(
+#: views/elements/amo2009/install.thtml:126
+#: views/elements/amo2009/install.thtml:227
+#: views/elements/amo2009/install.thtml:257
+#: views/elements/amo2009/install.thtml:300
+#: views/elements/amo2009/install.thtml:312 views/elements/install.thtml:73
+#: views/elements/install.thtml:181 views/elements/install.thtml:205
+#: views/elements/install.thtml:248 views/elements/install.thtml:260
+#: views/addons/plugins.thtml:66 views/addons/plugins.thtml:76
+#: views/addons/plugins.thtml:86 views/addons/plugins.thtml:96
+#: views/addons/plugins.thtml:119
+#, php-format
+msgid "a_download"
+msgstr "%s 다운로드"
+
+#: views/addons/policy.thtml:72
+msgid "a_eula_download"
+msgstr "ë™ì˜ ë° ë‹¤ìš´ë¡œë“œ"
+
+#: views/addons/policy.thtml:74
+msgid "a_eula_install"
+msgstr "ë™ì˜ ë° ì„¤ì¹˜"
+
+#: views/elements/header.thtml:76 views/elements/header.thtml:82
+#: views/api/api_addon.thtml:55 views/api/collections_feed.thtml:75
+#: views/sharing_api/addon.thtml:64
+msgid "a_header_public"
+msgstr "공개"
+
+#: views/elements/header.thtml:58 views/elements/header.thtml:75
+#: views/elements/header.thtml:80 views/api/api_addon.thtml:57
+#: views/api/collections_feed.thtml:77 views/sharing_api/addon.thtml:66
+msgid "a_header_sandbox"
+msgstr "샌드박스"
+
+#. %s is a date in the _('date') format
+#: views/elements/amo2009/homepage_addon.thtml:115
+#: views/elements/addon_listitem.thtml:122 views/elements/feature.thtml:106
+#: views/addons/display.thtml:104 views/addons/browse_thumbs.thtml:73
+msgid "addon_detail_last_updated"
+msgstr "최근 ë³€ê²½ì¼ %s"
+
+#. %s is the version of the add-on. Example: 3.2a1
+#: views/elements/amo2009/addon_version_detail.thtml:51
+#: views/elements/addon_version_detail.thtml:51
+#, php-format
+msgid "addon_display_header_version"
+msgstr "버전 %s"
+
+#: views/addons/browse_thumbs.thtml:80
+msgid "addon_downloads"
+msgstr "다운로드"
+
+#: views/addons/display.thtml:147
+msgid "addon_downloads_total"
+msgstr "ì´ ë‹¤ìš´ë¡œë“œ 수"
+
+#: views/elements/amo2009/homepage_addon.thtml:106
+#: views/elements/addon_listitem.thtml:115 views/elements/feature.thtml:101
+#: views/addons/category_landing.thtml:157 views/addons/display.thtml:146
+#: views/addons/browse_thumbs.thtml:80
+msgid "addon_downloads_weekly"
+msgstr "주간 다운로드 수"
+
+# %1 is the add-on count, %2 the category name
+#. %1 is the add-on count, %2 the category name
+#: views/addons/browse_thumbs.thtml:104 views/addons/browse.thtml:60
+#, php-format
+msgid "addon_list_category_totalcount"
+msgid_plural "addon_list_category_totalcount"
+msgstr[0] "%1$s \"%2$s\" 부가 기능"
+msgstr[1] "%1$s \"%2$s\"부가 기능"
+
+#: views/elements/amo2009/addon_list_options.thtml:103
+#: views/elements/pagination.thtml:67
+#: views/elements/addon_list_options.thtml:94
+msgid "addon_list_perpage"
+msgstr "페ì´ì§€ 당"
+
+#: views/elements/amo2009/addon_list_options.thtml:84
+#: views/elements/addon_list_options.thtml:98
+msgid "addon_list_sortby"
+msgstr "분류 ë°©ì‹"
+
+#: views/helpers/addons_html.php:568 views/elements/amo2009/install.thtml:321
+#: views/elements/feature.thtml:89
+msgid "addon_listitem_flag_experimental"
+msgstr "테스트용"
+
+#: views/helpers/addons_html.php:570
+msgid "addon_listitem_flag_recommended"
+msgstr "추천"
+
+#. %1 is the add-on name, %2 is the platform
+#: views/pages/js_constants.js.thtml:66
+msgid "addon_not_available_for_platform"
+msgstr "%1$sì€ %2$sì— ì‚¬ìš©í•  수 없습니다."
+
+# %1 is the addon name
+#. %1 is the add-on name
+#: views/addons/policy.thtml:101 views/addons/previews.thtml:60
+#: views/addons/versions.thtml:130 views/reviews/flag.thtml:61
+#: views/reviews/add.thtml:114 views/reviews/display.thtml:216
+#: views/reviews/review_added.thtml:57
+#, php-format
+msgid "addon_review_a_back_to_addon_x"
+msgstr "%1$s ëŒì•„가기."
+
+# %1 is the addon name
+#. %1 is the add-on name
+#: views/reviews/flag.thtml:60 views/reviews/add.thtml:113
+#: views/reviews/review_added.thtml:56
+#, php-format
+msgid "addon_review_a_back_to_reviews"
+msgstr "í‰ê°€ 화면으로 ëŒì•„가기..."
+
+#: views/reviews/add.thtml:85
+msgid "addon_review_add_rating_field"
+msgstr "별ì :"
+
+#: views/reviews/add.thtml:102
+msgid "addon_review_add_review_field"
+msgstr "í‰ê°€:"
+
+#: views/reviews/add.thtml:107
+msgid "addon_review_add_submit"
+msgstr "í‰ê°€ 완료"
+
+#. %s is the name of the add-on
+#: views/reviews/add.thtml:51
+#, php-format
+msgid "addon_review_add_title"
+msgstr "%s í‰ê°€ 추가"
+
+#: views/reviews/add.thtml:78
+msgid "addon_review_add_title_field"
+msgstr "제목/요약:"
+
+#: views/reviews/display.thtml:77 views/reviews/display.thtml:161
+msgid "addon_review_admin_delete"
+msgstr "삭제"
+
+#: views/reviews/display.thtml:76
+msgid "addon_review_author_reply_link"
+msgstr "답변"
+
+#: views/reviews/delete.thtml:62
+msgid "addon_review_confirm_delete"
+msgstr "현재 í‰ê°€ë¥¼ 삭제하시겠습니까?"
+
+#: views/reviews/delete.thtml:63
+msgid "addon_review_confirm_no"
+msgstr "아니오"
+
+#: views/reviews/delete.thtml:64
+msgid "addon_review_confirm_yes"
+msgstr "예"
+
+#: views/reviews/delete.thtml:48
+msgid "addon_review_delete_header"
+msgstr "í‰ê°€ ì‚­ì œ"
+
+#: controllers/reviews_controller.php:449
+msgid "addon_review_deleted_successfully"
+msgstr "í‰ê°€ í•­ëª©ì„ ì‚­ì œí•˜ì˜€ìŠµë‹ˆë‹¤."
+
+#. %s is the name of the add-on
+#: views/reviews/add.thtml:51
+#, php-format
+msgid "addon_review_edit_title"
+msgstr "%s í‰ê°€ 수정"
+
+# %1 is the count of characters entered as notes for the review flag reason.
+#. %1 is the count of characters entered as notes for the review flag reason.
+#: controllers/reviews_controller.php:539
+#, fuzzy
+msgid "addon_review_flag_error_other_length"
+msgstr ""
+"Problem flagging review: Notes for flagged reviews are limited to between 10 "
+"and 100 characters; your character length was %1$s."
+
+#. Removing an extra comma
+#: views/reviews/review_added.thtml:53
+msgid "addon_review_in_moderation"
+msgstr ""
+"ì£¼ì˜ ì‚¬í•­: ë³´ë‚´ 주신 í‰ê°€ë¥¼ 실제 사ì´íŠ¸ì— ë³´ì´ê¸° ì „ì— íŽ¸ì§‘ìžì— ì˜í•œ í‰ê°€ê°€ 진"
+"í–‰ ë©ë‹ˆë‹¤."
+
+#: views/reviews/add.thtml:57
+msgid "addon_review_in_reply_to"
+msgstr "ê°œë°œìž ë‹µë³€:"
+
+# %1 is the review count, %2 is the nickname or full name of the user.
+#. %1 is the review count, %2 is the nickname or full name of the user.
+#: views/reviews/display.thtml:131
+#, fuzzy, php-format
+msgid "addon_review_others_by_user"
+msgid_plural "addon_review_others_by_user"
+msgstr[0] "See %1$s previous review submitted by %2$s for this add-on."
+msgstr[1] "See %1$s previous reviews submitted by %2$s for this add-on."
+
+# %1 is the addon name
+#. %1 is the add-on name
+#: controllers/reviews_controller.php:201
+#: controllers/reviews_controller.php:250
+#: controllers/reviews_controller.php:345
+#: controllers/reviews_controller.php:424
+#, php-format
+msgid "addon_review_pagetitle"
+msgstr "%sì— ëŒ€í•œ í‰ê°€"
+
+# %1 is the user, %2 is the (localized) date
+#. %1 is the user, %2 is the (localized) date
+#: views/reviews/display.thtml:160
+#, php-format
+msgid "addon_review_reply_on_x_by_y"
+msgstr "답변ìž: %1$s 날짜: %2$s"
+
+#: views/reviews/display.thtml:157
+msgid "addon_review_reply_prefix"
+msgstr "ê°œë°œìž ë‹µë³€:"
+
+#: views/reviews/review_added.thtml:51
+msgid "addon_review_saved_successfully"
+msgstr "í‰ê°€ 결과가 성공ì ìœ¼ë¡œ 저장ë˜ì—ˆìŠµë‹ˆë‹¤. ê°ì‚¬í•©ë‹ˆë‹¤!"
+
+#: views/addons/display.thtml:354 views/reviews/display.thtml:72
+msgid "addon_reviewed_by_u_on_d"
+msgstr "검토ìž: %1$s, 검토ì¼: %2$s"
+
+# %1 is the (localized) date, y is the rating
+#. %1 is the user, %2 is the (localized) date, %3 is the rating
+#: views/editors/reviews_queue.thtml:57 views/editors/reviews_queue.thtml:68
+#: views/reviews/add.thtml:63 views/reviews/delete.thtml:54
+#, php-format
+msgid "addon_reviewed_on_x_rated_y"
+msgstr "- %2$s/ %1$s (별ì : %3$d)"
+
+#: views/elements/amo2009/addon_version_detail.thtml:52
+#: views/elements/addon_version_detail.thtml:52
+msgid "addon_version_permalink"
+msgstr "ìƒì„¸ URL"
+
+# %1 is the current Application name (e.g. Firefox)
+# %2 is the Application's version number
+#. %1 is the current Application name (e.g. Firefox)
+#. %2 is the Application's version number
+#: views/addons/versions.thtml:140
+#, fuzzy
+msgid "addon_versions_getlatestversion"
+msgstr "The most recent version compatible with %1$s %2$s"
+
+#: views/addons/display.thtml:447
+msgid "addons_author_addons_submit"
+msgstr "확ì¸"
+
+#: views/elements/amo2009/homepage_addon.thtml:100
+#: views/elements/feature.thtml:95
+msgid "addons_author_tooltip"
+msgstr "ê°œë°œìž í”„ë¡œí•„ 보기"
+
+# %1 is the name of the Application (eg. Firefox)
+#. %1 is the name of the Application (eg. Firefox)
+#: controllers/addons_controller.php:1296
+#, fuzzy
+msgid "addons_browse_all_themes_title"
+msgstr "Browse all Themes :: %1$s Add-ons"
+
+#. %s is the name of the category
+#: controllers/addons_controller.php:1016
+#, php-format
+msgid "addons_browse_browse_category"
+msgstr "%s를 보기"
+
+# %1 is the name of the theme category (eg. Modern)
+# %2 is the name of the Application (eg. Firefox)
+#. %1 is the name of the theme category (eg. Modern)
+#. %2 is the name of the Application (eg. Firefox)
+#: controllers/addons_controller.php:664
+#, fuzzy
+msgid "addons_browse_categories_header_theme"
+msgstr "Browse %1$s Themes :: %2$s Add-ons"
+
+#: views/addons/display.thtml:249
+#, fuzzy
+msgid "addons_display_a_license_what"
+msgstr "What's this?"
+
+#: views/reviews/display.thtml:222
+msgid "addons_display_add_review"
+msgstr "í‰ê°€ 추가"
+
+#: views/addons/display.thtml:294
+msgid "addons_display_advanced_details"
+msgstr "고급 사항"
+
+#: views/addons/display.thtml:98
+msgid "addons_display_categories"
+msgstr "분류"
+
+#: views/addons/display.thtml:482
+#, fuzzy
+msgid "addons_display_collection_add"
+msgstr "Add to a collection:"
+
+#: views/addons/display.thtml:491
+#, fuzzy
+msgid "addons_display_collection_add_new"
+msgstr "New Collection..."
+
+#: views/addons/display.thtml:487
+#, fuzzy
+msgid "addons_display_collection_add_select_one"
+msgstr "Select a collection..."
+
+#: views/addons/display.thtml:493
+#, fuzzy
+msgid "addons_display_collection_add_submit"
+msgstr "Publish"
+
+#. %1$s is the add-on name
+#. %2$s is the collection name, linked to the collection's page
+#: views/pages/js_constants.js.thtml:103 views/addons/display.thtml:61
+#, fuzzy
+msgid "addons_display_collection_publish_success"
+msgstr "%1$s has been added to the %2$s collection."
+
+#: views/addons/display.thtml:483
+#, fuzzy
+msgid "addons_display_collection_whatsthis"
+msgstr "What's this?"
+
+#. %1$s is a number
+#: views/addons/display.thtml:473
+#, fuzzy
+msgid "addons_display_collections_more"
+msgid_plural "addons_display_collections_more"
+msgstr[0] "and %1$s more collection"
+msgstr[1] "and %1$s more collections"
+
+#: views/addons/display.thtml:403
+msgid "addons_display_detailed_review"
+msgstr "세부 리뷰"
+
+#: views/reviews/add.thtml:89 views/reviews/add.thtml:90
+msgid "addons_display_dont_like_it"
+msgstr "나ì¨"
+
+#: views/reviews/display.thtml:220
+msgid "addons_display_edit_review"
+msgstr "í‰ê°€ 편집"
+
+#: views/addons/display.thtml:132
+msgid "addons_display_has_privacy"
+msgstr "ì´ ë¶€ê°€ ê¸°ëŠ¥ì€ ê°œì¸ ì •ë³´ ì •ì±…ì„ ê°€ì§€ê³  있습니다."
+
+#: views/reviews/add.thtml:87 views/reviews/add.thtml:88
+msgid "addons_display_hate_it"
+msgstr "매우 나ì¨"
+
+#: views/addons/display.thtml:462
+#, fuzzy
+msgid "addons_display_header_collections"
+msgstr "Related Collections"
+
+#: views/addons/display.thtml:297
+msgid "addons_display_header_developer_comments"
+msgstr "다른 연결 방법"
+
+#: views/addons/display.thtml:230
+msgid "addons_display_header_homepage"
+msgstr "홈페ì´ì§€"
+
+#: views/addons/display.thtml:247 views/addons/versions.thtml:110
+#, fuzzy
+msgid "addons_display_header_license"
+msgstr "Source Code License"
+
+#: views/addons/display.thtml:337
+msgid "addons_display_header_reviews"
+msgstr "í‰ê°€"
+
+#: views/addons/display.thtml:261
+msgid "addons_display_header_support"
+msgstr "기술 지ì›"
+
+#: views/reviews/add.thtml:91 views/reviews/add.thtml:92
+msgid "addons_display_like_it"
+msgstr "보통"
+
+#: views/addons/display.thtml:210
+msgid "addons_display_long_description"
+msgstr "ìƒì„¸ 설명"
+
+#: views/reviews/add.thtml:95 views/reviews/add.thtml:96
+msgid "addons_display_love_it"
+msgstr "좋ìŒ"
+
+#: views/addons/display.thtml:178
+msgid "addons_display_more_images"
+msgstr "스í¬ë¦°ìƒ· ë”보기"
+
+#: views/addons/display.thtml:465
+#, fuzzy
+msgid "addons_display_nocollections"
+msgstr "This add-on is not yet in any collections."
+
+# %1$s is either an author's name or a comma separated list of authors. Using
+# the list doesn't make sense in the English plural form so we ignore the
+# variable.
+#. %1$s is either an author's name or a comma separated list of authors. Using
+#. the list doesn't make sense in the English plural form so we ignore the
+#. variable.
+#: views/addons/display.thtml:436
+#, fuzzy
+msgid "addons_display_other_addons_by"
+msgid_plural "addons_display_other_addons_by"
+msgstr[0] "%1$s로 보기"
+msgstr[1] "Other add-ons by these authors"
+
+#. %s is the name of the add-on and the add-on section. Example:
+#. Some Add-on :: Firefox Add-ons
+#. This should not be concatenated in the code and should be fixed.
+#: controllers/addons_controller.php:141 controllers/addons_controller.php:280
+#: controllers/addons_controller.php:1442
+#, php-format
+msgid "addons_display_pagetitle"
+msgstr "%s"
+
+#. %s is an email address
+#: views/addons/display.thtml:286
+#, php-format
+msgid "addons_display_paragraph_supportinfoemail"
+msgstr ""
+"현재 부가 ê¸°ëŠ¥ì— ëŒ€í•œ 모든 기술 지ì›ì€ %s ë¡œ 하시면 ë©ë‹ˆë‹¤. ì—¬ëŸ¬ë¶„ì´ ê°œë°œìžì—"
+"게 ê°ì¢… 정보를 제공하면 ë” ì¢‹ì€ í”„ë¡œê·¸ëž¨ì„ ì–»ì„ ìˆ˜ 있습니다. 개발ìžëŠ” 몇 ê°€"
+"지 ë” í•„ìš”í•œ ì‚¬í•­ì„ ìš”êµ¬í•  수 있습니다. 리뷰를 올리ë”ë¼ë„ ì—¬ëŸ¬ë¶„ì˜ ì´ë©”ì¼ì´ "
+"개발ìžì—게 전달 ë˜ì§€ 않기 ë•Œë¬¸ì— ê°œë°œìžê°€ ì§ì ‘ 여러분ì—게 ì—°ë½ í•˜ê±°ë‚˜ 향후 ë³€"
+"ê²½ ë‚´ì—­ì„ ë°›ê±°ë‚˜ í•  수 ì—†ìŒì„ 양지해 주십시오."
+
+#. %$1s is a URL
+#. %$2s is an email address
+#: views/addons/display.thtml:269
+#, php-format
+msgid "addons_display_paragraph_supportinfoemailurl"
+msgstr ""
+"현재 부가 ê¸°ëŠ¥ì— ëŒ€í•œ 모든 기술 지ì›ì€ %s í˜¹ì€ %s 사ì´íŠ¸ì—ì„œ 진행 합니다. ì—¬"
+"ëŸ¬ë¶„ì´ ê°œë°œìžì—게 ê°ì¢… 정보를 제공하면 ë” ì¢‹ì€ í”„ë¡œê·¸ëž¨ì„ ì–»ì„ ìˆ˜ 있습니다. "
+"개발ìžëŠ” 몇 가지 ë” í•„ìš”í•œ ì‚¬í•­ì„ ìš”êµ¬í•  수 있습니다. 리뷰를 올리ë”ë¼ë„ 여러"
+"ë¶„ì˜ ì´ë©”ì¼ì´ 개발ìžì—게 전달 ë˜ì§€ 않기 ë•Œë¬¸ì— ê°œë°œìžê°€ ì§ì ‘ 여러분ì—게 ì—°ë½ "
+"하거나 향후 변경 ë‚´ì—­ì„ ë°›ê±°ë‚˜ í•  수 ì—†ìŒì„ 양지해 주십시오."
+
+#. %s is a URL
+#: views/addons/display.thtml:278
+#, php-format
+msgid "addons_display_paragraph_supportinfourl"
+msgstr ""
+"현재 부가 ê¸°ëŠ¥ì— ëŒ€í•œ 모든 기술 지ì›ì€ %s 사ì´íŠ¸ì—ì„œ 진행 합니다. ì—¬ëŸ¬ë¶„ì´ ê°œ"
+"ë°œìžì—게 ê°ì¢… 정보를 제공하면 ë” ì¢‹ì€ í”„ë¡œê·¸ëž¨ì„ ì–»ì„ ìˆ˜ 있습니다. 개발ìžëŠ” "
+"몇 가지 ë” í•„ìš”í•œ ì‚¬í•­ì„ ìš”êµ¬í•  수 있습니다. 리뷰를 올리ë”ë¼ë„ ì—¬ëŸ¬ë¶„ì˜ ì´ë©”"
+"ì¼ì´ 개발ìžì—게 전달 ë˜ì§€ 않기 ë•Œë¬¸ì— ê°œë°œìžê°€ ì§ì ‘ 여러분ì—게 ì—°ë½ í•˜ê±°ë‚˜ í–¥"
+"후 변경 ë‚´ì—­ì„ ë°›ê±°ë‚˜ í•  수 ì—†ìŒì„ 양지해 주십시오."
+
+#: views/addons/display.thtml:383
+msgid "addons_display_rate_it"
+msgstr "í‰ê°€ 하기"
+
+#: views/reviews/add.thtml:93 views/reviews/add.thtml:94
+msgid "addons_display_really_like_it"
+msgstr "매우 좋ìŒ"
+
+#: views/addons/display.thtml:410
+msgid "addons_display_review_etiquette"
+msgstr ""
+"리뷰를 ì ëŠ” ëž€ì— ë²„ê·¸ 리í¬íŠ¸ë¥¼ 올리지 마십시오. ì—¬ëŸ¬ë¶„ì˜ ì´ë©”ì¼ ì£¼ì†Œë¥¼ 개발ìž"
+"ì—게 전달하지 않기 ë•Œë¬¸ì— ë¬¸ì œë¥¼ í•´ê²° í•  수 없습니다. ë²„ê·¸ì— ëŒ€í•´ì„œëŠ” 개발ìž"
+"와 ì§ì ‘ ì—°ë½í•˜ì‹œê¸° ë°”ëžë‹ˆë‹¤."
+
+# %1 is the review guidelines link
+#. %1 is the review guidelines link
+#: views/addons/display.thtml:417
+msgid "addons_display_review_guidelines_link"
+msgstr "<a href=\"%s\">리뷰 ê°€ì´ë“œë¼ì¸</a>"
+
+# %1 is the support section link
+#. %1 is the support section link
+#: views/addons/display.thtml:414
+msgid "addons_display_review_see_support"
+msgstr ""
+"부가 ê¸°ëŠ¥ì— ëŒ€í•œ 지ì›ì„ 얻으시려면 <a href=\"%1$s\">ê³ ê° ì§€ì›</a> í•­ëª©ì„ ì‚´"
+"펴 보십시오."
+
+#: views/addons/display.thtml:404
+msgid "addons_display_review_submit"
+msgstr "저장"
+
+#: views/addons/display.thtml:430
+#, php-format
+msgid "addons_display_see_all_addons"
+msgstr "전체 %1$s 분류 부가 기능 보기"
+
+# %1 is the number of reviews
+#. %1 is the number of reviews
+#: views/addons/display.thtml:364
+#, php-format
+msgid "addons_display_see_all_reviews"
+msgstr "ì „ì²´ í‰ê°€ 보기 (%1$s)"
+
+#: views/addons/display.thtml:219
+msgid "addons_display_see_all_versions"
+msgstr "모든 버전 보기"
+
+#: views/addons/display.thtml:321 views/addons/versions.thtml:117
+msgid "addons_display_view_source"
+msgstr "소스 보기"
+
+#: views/addons/display.thtml:324
+msgid "addons_display_view_stats"
+msgstr "통계 보기"
+
+#: views/addons/display.thtml:376
+msgid "addons_display_what_do_you_think"
+msgstr "ì—¬ëŸ¬ë¶„ì˜ ì˜ê²¬ì€ 어떠세요?"
+
+#: views/elements/app_compatibility.thtml:49
+msgid "addons_display_workswith"
+msgstr "ê³µë™ ìž‘ì—…:"
+
+#: views/addons/home.thtml:112
+#, fuzzy
+msgid "addons_home_browse_new"
+msgstr "Just Added"
+
+#: views/addons/home.thtml:110
+#, fuzzy
+msgid "addons_home_browse_popular"
+msgstr "Popular"
+
+#: views/addons/home.thtml:108
+#, fuzzy
+msgid "addons_home_browse_recommended"
+msgstr "Recommended"
+
+#: views/addons/home.thtml:127 views/addons/home.thtml:134
+#: views/addons/home.thtml:141 views/addons/home.thtml:148
+#, fuzzy
+msgid "addons_home_browse_subscribe"
+msgstr "Subscribe"
+
+#: views/addons/home.thtml:101
+#, fuzzy
+msgid "addons_home_browse_title"
+msgstr "Browse Add-ons"
+
+#: views/addons/home.thtml:114
+#, fuzzy
+msgid "addons_home_browse_updated"
+msgstr "Updated"
+
+#: views/elements/amo2009/homepage_addon.thtml:100
+#: views/elements/addon_discussionheader.thtml:83
+#: views/elements/addon_listitem.thtml:109 views/elements/feature.thtml:95
+#: views/addons/category_landing.thtml:66 views/addons/policy.thtml:57
+#: views/addons/display.thtml:70 views/addons/home.thtml:178
+msgid "addons_home_by"
+msgstr " / "
+
+#: views/addons/home.thtml:169
+#, fuzzy
+msgid "addons_home_collection_popular_title"
+msgstr "Popular Collections"
+
+#: views/elements/amo2009/categories.thtml:69 views/addons/home.thtml:160
+#, fuzzy
+msgid "addons_home_collections"
+msgstr "Collections"
+
+#. %1$s is the count of addons in a collection
+#: views/elements/amo2009/collection_listing_item.thtml:51
+#: views/addons/home.thtml:185
+#, fuzzy
+msgid "addons_home_collections_addon_count"
+msgid_plural "addons_home_collections_addon_count"
+msgstr[0] "<strong>%1$s</strong> add-on"
+msgstr[1] "<strong>%1$s</strong> add-ons"
+
+#: views/addons/home.thtml:196
+#, fuzzy
+msgid "addons_home_collections_all"
+msgstr "View All Collections"
+
+#: views/addons/home.thtml:162
+#, fuzzy
+msgid "addons_home_collections_intro"
+msgstr ""
+"Collections are a way for you to categorize, mix, match and mingle add-ons. "
+"Subscribe to collections created by other users or create your own."
+
+#. %1$s is the count of subscribers for a collection
+#: views/elements/amo2009/collection_listing_item.thtml:58
+#: views/collections/detail.thtml:96 views/addons/home.thtml:189
+#, fuzzy
+msgid "addons_home_collections_subscribers"
+msgid_plural "addons_home_collections_subscribers"
+msgstr[0] "<strong>%1$s</strong> subscriber"
+msgstr[1] "<strong>%1$s</strong> subscribers"
+
+#: views/addons/searchengines.thtml:54 views/addons/themes_landing.thtml:49
+msgid "addons_home_feature_head"
+msgstr "추천 부가 기능"
+
+#: controllers/search_controller.php:218 controllers/addons_controller.php:176
+#: controllers/addons_controller.php:428 controllers/addons_controller.php:671
+#: controllers/addons_controller.php:871
+#: controllers/addons_controller.php:1103
+#: controllers/addons_controller.php:1242
+#: controllers/addons_controller.php:1298
+#, php-format
+msgid "addons_home_header_details"
+msgstr ""
+"부가 ê¸°ëŠ¥ì€ %1$s를 확장하여 좀 ë” ë©‹ì§„ ë‚˜ë§Œì˜ ì›¹ 브ë¼ìš°ì§•ì„ ë„와 ì¤ë‹ˆë‹¤.다양"
+"í•œ 부가 ê¸°ëŠ¥ì„ í†µí•´ %1$s를 ë‚˜ë§Œì˜ ê²ƒìœ¼ë¡œ 바꾸어 보세요!"
+
+#. %1$s is the HTML collection name link.
+#: views/elements/amo2009/teaser_collections.thtml:107
+#, fuzzy
+msgid "addons_home_introduction_collection_link"
+msgstr "Like these? Find more add-ons in %1$s."
+
+#: views/elements/amo2009/teaser_collections.thtml:60
+#, fuzzy
+msgid "addons_home_introduction_extras"
+msgstr ""
+"<strong>Over 5000 free extras</strong> that let you customize and extend "
+"Firefox to meet your needs."
+
+#: views/elements/amo2009/teaser_collections.thtml:55
+#, fuzzy
+msgid "addons_home_introduction_header"
+msgstr "What are Add-ons?"
+
+#: views/elements/amo2009/teaser_collections.thtml:72
+#, fuzzy
+msgid "addons_home_introduction_install"
+msgstr ""
+"<strong>Easy to install</strong>, get notified when updates are available."
+
+#: views/elements/amo2009/teaser_collections.thtml:45
+#, fuzzy
+msgid "addons_home_introduction_name"
+msgstr "Introduction"
+
+#: views/elements/amo2009/teaser_collections.thtml:66
+#, fuzzy
+msgid "addons_home_introduction_themes"
+msgstr ""
+"Toolbars, themes and search providers that <strong>help you perform common "
+"tasks.</strong>"
+
+#: views/addons/home.thtml:161
+#, fuzzy
+msgid "addons_home_new_indicator"
+msgstr "NEW!"
+
+#: views/elements/app_chooser.thtml:48 views/layouts/amo2009.thtml:257
+msgid "addons_home_other_applications"
+msgstr "기타 프로그램"
+
+#. %1$s is the application the user is browsing. Examples: Thunderbird, Firefox,
+#. Sunbird
+#: views/pages/collector_faq.thtml:49 views/pages/collector_firstrun.thtml:42
+#: views/pages/collector.thtml:46 views/pages/collector_features.thtml:54
+#: controllers/developers_controller.php:87
+#: controllers/compatibility_controller.php:72
+#: controllers/components/simple_acl.php:81 controllers/components/amo.php:607
+#: controllers/statistics_controller.php:60
+#: controllers/statistics_controller.php:240
+#: controllers/previews_controller.php:67 controllers/users_controller.php:90
+#: controllers/users_controller.php:223 controllers/users_controller.php:330
+#: controllers/users_controller.php:414 controllers/users_controller.php:708
+#: controllers/users_controller.php:723 controllers/reviews_controller.php:204
+#: controllers/reviews_controller.php:251
+#: controllers/reviews_controller.php:346
+#: controllers/reviews_controller.php:425
+#: controllers/search_controller.php:185 controllers/search_controller.php:297
+#: controllers/search_controller.php:301 controllers/addons_controller.php:147
+#: controllers/addons_controller.php:280 controllers/addons_controller.php:370
+#: controllers/addons_controller.php:667 controllers/addons_controller.php:874
+#: controllers/addons_controller.php:1019
+#: controllers/addons_controller.php:1034
+#: controllers/addons_controller.php:1101
+#: controllers/addons_controller.php:1121
+#: controllers/addons_controller.php:1240
+#: controllers/addons_controller.php:1357
+#: controllers/addons_controller.php:1364
+#: controllers/addons_controller.php:1442
+#: controllers/addons_controller.php:1477
+#: controllers/addons_controller.php:1538
+#: controllers/addons_controller.php:1543
+#: controllers/editors_controller.php:64 controllers/pages_controller.php:132
+#: controllers/groups_controller.php:65 controllers/groups_controller.php:71
+#: controllers/groups_controller.php:89 controllers/groups_controller.php:111
+#: controllers/collections_controller.php:57
+#: controllers/collections_controller.php:121
+#: controllers/collections_controller.php:205
+#: controllers/collections_controller.php:365
+#: controllers/collections_controller.php:404
+#: controllers/collections_controller.php:466
+#: controllers/collections_controller.php:538
+#: controllers/collections_controller.php:828
+#: controllers/localizers_controller.php:72
+#, php-format
+msgid "addons_home_pagetitle"
+msgstr "Firefox 부가 기능"
+
+#. %1$s is the number of addons downloaded
+#: views/addons/home.thtml:57
+#, fuzzy, php-format
+msgid "addons_home_stats_downloaded"
+msgid_plural "addons_home_stats_downloaded"
+msgstr[0] "<strong>%1$s</strong> <span>add-on downloaded</span>"
+msgstr[1] "<strong>%1$s</strong> <span>add-ons downloaded</span>"
+
+#. %1$s is the number of addons in use
+#: views/addons/home.thtml:63
+#, fuzzy, php-format
+msgid "addons_home_stats_inuse"
+msgid_plural "addons_home_stats_inuse"
+msgstr[0] "<strong>%1$s</strong> <span>add-on in use</span>"
+msgstr[1] "<strong>%1$s</strong> <span>add-ons in use</span>"
+
+#: views/addons/home.thtml:136
+msgid "addons_home_view_all_newest_title"
+msgstr "새로 올ë¼ì˜¨ 부가 기능 보기"
+
+#: views/addons/home.thtml:129
+msgid "addons_home_view_all_popular_title"
+msgstr "ì „ì²´ ì¸ê¸° 부가 기능 보기"
+
+#: views/addons/home.thtml:150
+msgid "addons_home_view_all_recommended_title"
+msgstr "전체 추천 부가 기능 보기"
+
+#: views/addons/home.thtml:143
+msgid "addons_home_view_all_updated_title"
+msgstr "ìµœê·¼ì— ì—…ë°ì´íŠ¸í•œ 부가 기능 보기"
+
+#: views/elements/amo2009/install.thtml:334 views/elements/install.thtml:112
+#, fuzzy
+msgid "addons_install_in_sunbird"
+msgstr ""
+"<ol><li>Click the link below to save the file.</li><li>In Mozilla Sunbird, "
+"open Add-ons from the Tools menu.</li><li>Click the Install button, and "
+"locate/select the file you downloaded and click \"OK\".</li></ol>"
+
+#: views/elements/amo2009/install.thtml:333 views/elements/install.thtml:111
+#, fuzzy
+msgid "addons_install_in_sunbird_title"
+msgstr "How to Install in Sunbird"
+
+#: views/elements/amo2009/install.thtml:331 views/elements/install.thtml:106
+msgid "addons_install_in_thunderbird"
+msgstr ""
+"<ol><li>ë§í¬ë¥¼ ì„ íƒí•œ 후 오른쪽 ë²„íŠ¼ì„ ëˆŒëŸ¬ \"새 ì´ë¦„으로 ë§í¬ 저장...\"ì„ ì„ "
+"íƒí•œ 후 파ì¼ì„ 저장 합니다.</li><li>Mozilla Thunderbirdì—ì„œ ë„구 ë©”ë‰´ì˜ ë¶€ê°€ "
+"ê¸°ëŠ¥ì„ í´ë¦­í•˜ì—¬ jar 파ì¼ì„ 엽니다.</li><li>설치 ë²„íŠ¼ì„ ëˆ„ë¥´ê³  다운로드한 파ì¼"
+"ì„ ì„ íƒí•œí›„ \"확ì¸\"ì„ ëˆ„ë¥´ë©´ ë©ë‹ˆë‹¤.</li></ol>"
+
+#: views/elements/amo2009/install.thtml:330 views/elements/install.thtml:105
+msgid "addons_install_in_thunderbird_title"
+msgstr "Thunderbird 설치 방법"
+
+#: views/elements/amo2009/addon_list_options.thtml:108
+#: views/elements/addon_list_options.thtml:105
+msgid "addons_options_show_experimental"
+msgstr "테스트 ì¤‘ì¸ ë¶€ê°€ 기능 보기"
+
+#: views/elements/amo2009/addon_list_options.thtml:113
+#: views/elements/addon_list_options.thtml:109
+msgid "addons_options_submit"
+msgstr "전송"
+
+#: views/addons/plugins.thtml:63 views/addons/plugins.thtml:73
+#: views/addons/plugins.thtml:83 views/addons/plugins.thtml:93
+#: views/addons/plugins.thtml:103 views/addons/plugins.thtml:116
+#: views/addons/plugins.thtml:126
+msgid "addons_plugins_by"
+msgstr " / "
+
+#: views/addons/plugins.thtml:107
+msgid "addons_plugins_for_linux"
+msgstr "리눅스용"
+
+#: views/addons/plugins.thtml:108 views/addons/plugins.thtml:131
+msgid "addons_plugins_for_macosx"
+msgstr "맥 OS X용"
+
+#: views/addons/plugins.thtml:106 views/addons/plugins.thtml:129
+#: views/addons/plugins.thtml:130
+msgid "addons_plugins_for_windows"
+msgstr "윈ë„ìš°ìš©"
+
+#. %1$s is a URL
+#: views/addons/plugins.thtml:139
+#, php-format
+msgid "addons_plugins_looking_for_more"
+msgstr ""
+"현재 페ì´ì§€ëŠ” 가장 ë§Žì´ ì‚¬ìš©ë˜ëŠ” 플러그ì¸ë§Œ 모아ë‘었습니다.Mozilla 기반 웹 브"
+"ë¼ìš°ì €ì—ì„œ êµ¬ë™ ê°€ëŠ¥í•œ 플러그ì¸ì— 대한 정보는%1$s를 방문하십시오."
+
+#: views/addons/plugins.thtml:137
+msgid "addons_plugins_looking_for_plugin"
+msgstr "찾으시는 플러그ì¸ì´ 없습니까?"
+
+#: views/addons/plugins.thtml:58
+msgid "addons_plugins_main_description"
+msgstr ""
+"플러그ì¸ì€ 브ë¼ìš°ì €ê°€ 특별한 ê¸°ëŠ¥ì„ ìˆ˜í–‰í•˜ëŠ”ë° ë„ì›€ì„ ì¤ë‹ˆë‹¤.ì´ë¯¸ì§€ë¥¼ ë³´ì—¬ 주"
+"거나 ë° ë©€í‹°ë¯¸ë””ì–´ 정보를 표시하는 ë° ìœ ìš© 합니다.외부 기능과 ì—°ë™í•œë‹¤ëŠ” ì ì—"
+"서 확장 기능과 조금 다릅니다."
+
+#. %1$s is the application name. Example: Firefox, Thunderbird, Sunbird
+#: controllers/addons_controller.php:1122
+#, php-format
+msgid "addons_plugins_main_header"
+msgstr "Mozilla Firefoxìš© 플러그ì¸"
+
+#: controllers/components/amo.php:698 controllers/addons_controller.php:1121
+msgid "addons_plugins_pagetitle"
+msgstr "플러그ì¸"
+
+#: views/addons/plugins.thtml:68 views/addons/plugins.thtml:78
+#: views/addons/plugins.thtml:88 views/addons/plugins.thtml:98
+#: views/addons/plugins.thtml:110 views/addons/plugins.thtml:121
+#: views/addons/plugins.thtml:133
+msgid "addons_plugins_support_documentation"
+msgstr "문서 정보"
+
+#. %s is the name of the add-on
+#: views/addons/policy.thtml:61
+#, php-format
+msgid "addons_policy_eula_require"
+msgstr ""
+"%s는 설치를 진행하기 위해 ì•„ëž˜ì˜ ì¼ë°˜ ì‚¬ìš©ìž ì•½ê´€ì—ë™ì˜ë¥¼ 필요로 합니다."
+
+# %1 is the addon name
+#. %1 is the add-on name
+#: controllers/addons_controller.php:1476
+#, php-format
+msgid "addons_previews_pagetitle"
+msgstr "%s 미리 보기"
+
+#: views/addons/category_landing.thtml:135
+#, fuzzy
+msgid "addons_recently_added"
+msgstr "Recently Added"
+
+#: views/addons/recommended.thtml:51 controllers/addons_controller.php:1365
+msgid "addons_recommended_introduction"
+msgstr ""
+"수 ì²œì—¬ê°œì˜ ë¶€ê°€ 기능 중ì—는 당신ì—게 ì í•©í•œ 부가 ê¸°ëŠ¥ë„ ìžˆìŠµë‹ˆë‹¤. 가장 ì¸ê¸°"
+"있는 부가 기능들 ì¤‘ì— ê³¨ë¼ì„œ 사용해 보십시오!"
+
+#: controllers/addons_controller.php:1357
+#: controllers/addons_controller.php:1364
+msgid "addons_recommended_pagetitle"
+msgstr "추천 부가 기능"
+
+#: controllers/addons_controller.php:1360
+msgid "addons_recommended_title"
+msgstr "추천 부가 기능"
+
+#: views/addons/searchengines.thtml:136
+msgid "addons_searchengines_additional_resources"
+msgstr "부가 정보"
+
+#. link text devmo
+#: views/addons/searchengines.thtml:141
+msgid "addons_searchengines_devmo_link"
+msgstr "Mozilla ê°œë°œìž ì„¼í„°"
+
+#: views/pages/js_constants.js.thtml:67
+msgid "addons_searchengines_error_mozilla_browser_required"
+msgstr ""
+"죄송합니다. ì´ ê²€ìƒ‰ 플러그ì¸ì„ 설치하시려면 Firefox와 ê°™ì€Mozilla 기반 웹 브"
+"ë¼ìš°ì €ë¥¼ ì´ìš©í•˜ì‹­ì‹œì˜¤."
+
+#: views/addons/searchengines.thtml:49
+msgid "addons_searchengines_error_nojavascript"
+msgstr ""
+"플러그ì¸ì„ 설치하려면 ìžë°”스í¬ë¦½íŠ¸ê°€ 필요합니다. 아마 ìžë°”스í¬ë¦½íŠ¸ 사용 설정"
+"ì„ êº¼ë‘ì‹  것 같습니다. 검색 í”ŒëŸ¬ê·¸ì¸ ì„¤ì¹˜ë¥¼ 위해 설정ì—ì„œ ìžë°” 스í¬ë¦½íŠ¸ 사용 "
+"ì˜µì…˜ì„ ì¼œ 주십시오."
+
+#. %1 is "make your own" link
+#. %2 is MDC link
+#: views/addons/searchengines.thtml:139
+#, fuzzy
+msgid "addons_searchengines_learn_howto"
+msgstr "%2$sì—ì„œ %1$s 방법 ìµížˆê¸°"
+
+# link path to search plugins instructions, relative to devmo
+#. link path to search plugins instructions, relative to devmo
+#: views/addons/searchengines.thtml:140
+msgid "addons_searchengines_makeyourown_href"
+msgstr "/ko/docs/Creating_OpenSearch_plugins_for_Firefox"
+
+#. link text for "make your own" (opensearch engine)
+#: views/addons/searchengines.thtml:140
+msgid "addons_searchengines_makeyourown_link"
+msgstr "ê°œì¸í™”"
+
+#. %1 is the link to mycroft.mozdev.org
+#: views/addons/searchengines.thtml:138
+#, fuzzy
+msgid "addons_searchengines_more"
+msgstr "%1$sì—ì„œ 검색 엔진 찾기"
+
+#. link text to mycroft.mozdev.org
+#: views/addons/searchengines.thtml:138
+msgid "addons_searchengines_mycroft_link"
+msgstr "mycroft.mozdev.org"
+
+# %1 is the addon name
+#: controllers/addons_controller.php:1100
+#: controllers/addons_controller.php:1110
+msgid "addons_searchengines_pagetitle"
+msgstr "검색 엔진"
+
+#: views/addons/searchengines.thtml:143
+msgid "addons_searchengines_thanks"
+msgstr "Firefox 검색 엔진 ìž‘ì—…ì„ ìœ„í•´ 수고해 주신 Mycroftì—ê°ì‚¬ 드립니다."
+
+#: views/addons/display.thtml:154
+#, fuzzy
+msgid "addons_share_button_text"
+msgstr "Share this"
+
+#: controllers/addons_controller.php:89
+#, fuzzy
+msgid "addons_share_label_delicious"
+msgstr "Add to Delicious"
+
+#: controllers/addons_controller.php:77
+#, fuzzy
+msgid "addons_share_label_digg"
+msgstr "Digg this!"
+
+#: controllers/addons_controller.php:83
+#, fuzzy
+msgid "addons_share_label_facebook"
+msgstr "Post to Facebook"
+
+#: controllers/addons_controller.php:101
+#, fuzzy
+msgid "addons_share_label_friendfeed"
+msgstr "Share on FriendFeed"
+
+#: controllers/addons_controller.php:95
+#, fuzzy
+msgid "addons_share_label_myspace"
+msgstr "Post to MySpace"
+
+#: controllers/components/amo.php:201 controllers/components/amo.php:229
+#, fuzzy
+msgid "addons_status_disabled"
+msgstr "Disabled"
+
+#: controllers/components/amo.php:191 controllers/components/amo.php:224
+#, fuzzy
+msgid "addons_status_incomplete"
+msgstr "Incomplete Version"
+
+#: controllers/components/amo.php:197 controllers/components/amo.php:227
+#, fuzzy
+msgid "addons_status_nominated"
+msgstr "In Sandbox; Public Nomination"
+
+#: views/pages/js_constants.js.thtml:80 controllers/components/amo.php:195
+#: controllers/components/amo.php:226
+#, fuzzy
+msgid "addons_status_pending"
+msgstr "In Sandbox; Pending Review"
+
+#: views/pages/js_constants.js.thtml:78 controllers/components/amo.php:199
+#: controllers/components/amo.php:228
+#, fuzzy
+msgid "addons_status_public"
+msgstr "Public"
+
+#: views/pages/js_constants.js.thtml:79 controllers/components/amo.php:193
+#: controllers/components/amo.php:225
+#, fuzzy
+msgid "addons_status_sandbox"
+msgstr "In Sandbox"
+
+#: controllers/components/amo.php:203
+#, fuzzy
+msgid "addons_status_unknown"
+msgstr "Unknown"
+
+#: views/elements/amo2009/teaser_collections.thtml:91
+#: views/elements/amo2009/homepage_addon.thtml:99
+#: views/elements/feature.thtml:94
+msgid "addons_title_tooltip"
+msgstr "ìƒì„¸ ì •ë³´ 보기"
+
+#: views/addons/category_landing.thtml:151
+#, fuzzy
+msgid "addons_top_downloads"
+msgstr "Top Downloads"
+
+#: views/addons/category_landing.thtml:165
+#, fuzzy
+msgid "addons_top_rated"
+msgstr "Top Rated"
+
+#: views/addons/versions.thtml:62
+msgid "addons_versions_careful"
+msgstr "구 버전 주ì˜"
+
+#: views/addons/versions.thtml:63
+msgid "addons_versions_careful_introduction"
+msgstr ""
+"현재 ë²„ì „ë“¤ì€ í…ŒìŠ¤íŠ¸ ë° ì°¸ì¡°ìš©ìœ¼ë¡œ 제공ë©ë‹ˆë‹¤.최신 부가 ê¸°ëŠ¥ì„ ì‚¬ìš©í•˜ê³  있습"
+"니다."
+
+#: controllers/addons_controller.php:1549
+msgid "addons_versions_history"
+msgstr "버전별 변경 사항"
+
+#. %1$s is the add-on name
+#: controllers/addons_controller.php:1535
+#, php-format
+msgid "addons_versions_pagetitle"
+msgstr "%1$s 버전 기ë¡"
+
+#: controllers/groups_controller.php:71
+msgid "admin_group_add_pagetitle"
+msgstr "그룹 추가"
+
+#: controllers/groups_controller.php:111
+msgid "admin_group_delete_pagetitle"
+msgstr "그룹 삭제"
+
+#. %s is a number to identify the group
+#: controllers/groups_controller.php:117
+#, php-format
+msgid "admin_group_deleted"
+msgstr "그룹 ì•„ì´ë”” %s를 삭제함"
+
+#: controllers/groups_controller.php:89
+msgid "admin_group_edit_pagetitle"
+msgstr "그룹 편집"
+
+#: controllers/groups_controller.php:92 controllers/groups_controller.php:113
+msgid "admin_group_error_invalid_id"
+msgstr "그룹 idê°€ 유효하지 ì•ŠìŒ"
+
+#: controllers/groups_controller.php:65
+msgid "admin_group_pagetitle"
+msgstr "그룹 관리ìž"
+
+#: controllers/groups_controller.php:77 controllers/groups_controller.php:99
+msgid "admin_group_saved"
+msgstr "ê·¸ë£¹ì„ ì €ìž¥í•¨"
+
+#: views/elements/amo2009/search.thtml:257 views/elements/search.thtml:239
+msgid "advanced_search_form"
+msgstr "고급 검색"
+
+#: views/elements/amo2009/search.thtml:126 views/elements/search.thtml:125
+msgid "advanced_search_form_any_time"
+msgstr "모든 시간"
+
+#: views/elements/amo2009/search.thtml:97
+#: views/elements/amo2009/search.thtml:110 views/elements/search.thtml:96
+#: views/elements/search.thtml:109
+msgid "advanced_search_form_any_type"
+msgstr "모든 형ì‹"
+
+#: views/elements/amo2009/search.thtml:275 views/elements/search.thtml:254
+msgid "advanced_search_form_any_version"
+msgstr "모든 버전"
+
+#: views/elements/amo2009/search.thtml:217 views/elements/search.thtml:212
+msgid "advanced_search_form_application"
+msgstr "애플리케ì´ì…˜"
+
+#: views/elements/amo2009/search.thtml:143 views/elements/search.thtml:142
+msgid "advanced_search_form_keyword_match"
+msgstr "검색어만 찾기"
+
+#: views/elements/amo2009/search.thtml:251 views/elements/search.thtml:225
+msgid "advanced_search_form_lastupdate"
+msgstr "최근 ì—…ë°ì´íŠ¸"
+
+#: views/elements/amo2009/search.thtml:145 views/elements/search.thtml:144
+msgid "advanced_search_form_name"
+msgstr "ì´ë¦„"
+
+#: views/elements/amo2009/search.thtml:144 views/elements/search.thtml:143
+msgid "advanced_search_form_newest"
+msgstr "최신"
+
+#: views/elements/amo2009/search.thtml:130 views/elements/search.thtml:129
+msgid "advanced_search_form_past_3_months"
+msgstr "3개월간"
+
+#: views/elements/amo2009/search.thtml:131 views/elements/search.thtml:130
+msgid "advanced_search_form_past_6_months"
+msgstr "6개월간"
+
+#: views/elements/amo2009/search.thtml:127 views/elements/search.thtml:126
+msgid "advanced_search_form_past_day"
+msgstr "하루전"
+
+#: views/elements/amo2009/search.thtml:129 views/elements/search.thtml:128
+msgid "advanced_search_form_past_month"
+msgstr "한달간"
+
+#: views/elements/amo2009/search.thtml:128 views/elements/search.thtml:127
+msgid "advanced_search_form_past_week"
+msgstr "한주간"
+
+#: views/elements/amo2009/search.thtml:132 views/elements/search.thtml:131
+msgid "advanced_search_form_past_year"
+msgstr "ì¼ë…„ê°„"
+
+#: views/elements/amo2009/search.thtml:239 views/elements/search.thtml:230
+msgid "advanced_search_form_perpage"
+msgstr "페ì´ì§€ë‹¹"
+
+#: views/elements/amo2009/search.thtml:243 views/elements/search.thtml:224
+msgid "advanced_search_form_platform"
+msgstr "플랫í¼"
+
+#: views/elements/amo2009/search.thtml:147 views/elements/search.thtml:146
+msgid "advanced_search_form_popularity"
+msgstr "ì¸ê¸°ë„"
+
+#: views/elements/amo2009/search.thtml:146 views/elements/search.thtml:145
+msgid "advanced_search_form_rating"
+msgstr "별ì "
+
+#: views/elements/amo2009/search.thtml:247 views/elements/search.thtml:231
+msgid "advanced_search_form_sortby"
+msgstr "분류 ë°©ì‹"
+
+#: views/elements/amo2009/search.thtml:227 views/elements/search.thtml:216
+msgid "advanced_search_form_to"
+msgstr " - "
+
+#: views/elements/amo2009/search.thtml:257 views/elements/search.thtml:237
+msgid "advanced_search_form_toggle_tooltip"
+msgstr "고급 검색 모드 바꾸기"
+
+#: views/elements/amo2009/search.thtml:235 views/elements/search.thtml:223
+msgid "advanced_search_form_type"
+msgstr "형ì‹"
+
+#: views/elements/amo2009/search.thtml:222 views/elements/search.thtml:214
+msgid "advanced_search_form_version"
+msgstr "버전"
+
+#: views/elements/amo2009/pagination.thtml:42
+#, fuzzy
+msgid "amo2009_pagination_next_page"
+msgstr "Next"
+
+#: views/elements/amo2009/pagination.thtml:41
+#, fuzzy
+msgid "amo2009_pagination_previous_page"
+msgstr "Prev"
+
+#: views/pages/js_constants.js.thtml:96
+msgid "app_compat_ignore_check"
+msgstr "버전 í™•ì¸ ë¬´ì‹œ"
+
+#: views/pages/js_constants.js.thtml:72
+msgid "app_compat_older_firefox_only"
+msgstr "Firefox ì´ì „ ë²„ì „ì„ ìœ„í•œ 부가 기능"
+
+#. %1$s and %2$s are URLs
+#: views/pages/js_constants.js.thtml:74
+#, fuzzy
+msgid "app_compat_older_version_or_ignore_check"
+msgstr ""
+"You can <a href=\"%1$s\">try an older version</a> or <a href=\"#\" onclick="
+"\"%2$s\">ignore this check</a>"
+
+#. %1$s is a URL
+#: views/pages/js_constants.js.thtml:71
+msgid "app_compat_try_old_version"
+msgstr "<a href=\"%1$s\">ì´ì „ 버전</a> 사용 가능"
+
+#. %1$s is a URL
+#. %2$s is a version number. Example: 3.1
+#: views/pages/js_constants.js.thtml:73
+#, fuzzy
+msgid "app_compat_unreleased_version"
+msgstr ""
+"This add-on requires the not-yet released <a href=\"%1$s\">Firefox %2$s</a>"
+
+#: views/pages/js_constants.js.thtml:70
+msgid "app_compat_update_firefox"
+msgstr ""
+"부가 ê¸°ëŠ¥ì„ ì‚¬ìš©í•˜ë ¤ë©´ <a href=\"http://getfirefox.com\">Firefox 업그레ì´ë“œ</"
+"a>를 하세요."
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#. %3$s is a status, like Public.
+#: controllers/components/audit.php:79
+#, fuzzy
+msgid "audit_addon_status"
+msgstr "%1$s changed the status of %2$s to %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:221
+#, fuzzy
+msgid "audit_admin_default"
+msgstr "%1$s committed unknown admin action %2$s to ID %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:153
+#, fuzzy
+msgid "audit_admin_feature_remove"
+msgstr "%1$s removed feature %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is an application, like Firefox.
+#: controllers/components/audit.php:92
+#, fuzzy
+msgid "audit_application_create"
+msgstr "%1$s created application %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is an application, like Firefox.
+#: controllers/components/audit.php:95
+#, fuzzy
+msgid "audit_application_edit"
+msgstr "%1$s edited application %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a version number, like 3.5.
+#. %3$s is an application, like Firefox.
+#: controllers/components/audit.php:105
+#, fuzzy
+msgid "audit_appversion_create"
+msgstr "%1$s created version %2$s for %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a version number, like 3.5.
+#. %3$s is an application, like Firefox.
+#: controllers/components/audit.php:108
+#, fuzzy
+msgid "audit_appversion_delete"
+msgstr "%1$s deleted version %2$s for %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a config field, like "awesomeness".
+#. %3$s is a config value, like "off".
+#. %4$s is a config value, like "on".
+#: controllers/components/audit.php:210
+#, fuzzy
+msgid "audit_config"
+msgstr "%1$s changed config '%2$s' from '%3$s' to '%4$s'"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:258
+#, fuzzy
+msgid "audit_editor_default"
+msgstr "%1$s committed unknown editor action %2$s to ID %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#: controllers/components/audit.php:236
+#, fuzzy
+msgid "audit_editor_feature_remove"
+msgstr "%1$s removed addon %2$s from feature list"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#: controllers/components/audit.php:231
+#, fuzzy
+msgid "audit_feature_add"
+msgstr "%1$s added addon %2$s to feature list"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:149
+#, fuzzy
+msgid "audit_feature_edit"
+msgstr "%1$s changed a feature for %2$s locale"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#: controllers/components/audit.php:241
+#, fuzzy
+msgid "audit_feature_locale_change"
+msgstr "%1$s changed locales for addon %2$s on feature list"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:83
+#, fuzzy
+msgid "audit_file_recalchash"
+msgstr "%1$s recalculated the hash for file %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>user name</a>
+#. %3$s is <a>group name</a>
+#: controllers/components/audit.php:182
+#, fuzzy
+msgid "audit_group_addmember"
+msgstr "%1$s added %2$s to group %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:313
+#, fuzzy
+msgid "audit_group_associated"
+msgstr "%1$s associated themselves with %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:162
+#, fuzzy
+msgid "audit_group_create"
+msgstr "%1s created group %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:170
+#, fuzzy
+msgid "audit_group_delete"
+msgstr "%1$s deleted group %2$s (ID %3$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:165
+#, fuzzy
+msgid "audit_group_edit"
+msgstr "%1$s edited group %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>user name</a>
+#. %3$s is <a>group name</a>
+#: controllers/components/audit.php:188
+#, fuzzy
+msgid "audit_group_removemember"
+msgstr "%1$s removed %2$s from group %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:280
+#, fuzzy
+msgid "audit_l10n_default"
+msgstr "%1$s committed unknown action %2$s for %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:295
+#, fuzzy
+msgid "audit_modify_locked_group"
+msgstr "%1$s attempted to modify locked group %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:299
+#, fuzzy
+msgid "audit_modify_other_locale"
+msgstr "%1$s attempted to modify translations in %2$s without permission"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a platform, like <a>Windows</a>
+#: controllers/components/audit.php:135
+#, fuzzy
+msgid "audit_platform_create"
+msgstr "%1$s created platform %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a platform, like <a>Windows</a>
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:143
+#, fuzzy
+msgid "audit_platform_delete"
+msgstr "%1$s deleted platform %2$s (ID %3$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a platform, like <a>Windows</a>
+#: controllers/components/audit.php:138
+#, fuzzy
+msgid "audit_platform_edit"
+msgstr "%1$s edited platform %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a part of the admin, like 'Site Config'
+#: controllers/components/audit.php:288
+#, fuzzy
+msgid "audit_reauthentication_failure"
+msgstr "%1$s failed to re-authenticate to access %2$s."
+
+#. %1$s is <a>user name</a>
+#. %2$s is the name of a canned response, like 'Ready for the public'
+#: controllers/components/audit.php:198
+#, fuzzy
+msgid "audit_response_create"
+msgstr "%1$s created response %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is the name of a canned response, like 'Ready for the public'
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:206
+#, fuzzy
+msgid "audit_response_delete"
+msgstr "%1$s deleted response %2$s (ID %3$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is the name of a canned response, like 'Ready for the public'
+#: controllers/components/audit.php:201
+#, fuzzy
+msgid "audit_response_edit"
+msgstr "%1$s edited response %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:245
+#, fuzzy
+msgid "audit_review_approve"
+msgstr "%1$s approved review %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:250 controllers/components/audit.php:253
+#, fuzzy
+msgid "audit_review_delete"
+msgstr "%1$s deleted review %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:303
+#, fuzzy
+msgid "audit_security_default"
+msgstr "%1$s committed unknown security action %2$s to ID %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a category name, like <a>Search Tools</a>
+#: controllers/components/audit.php:118
+#, fuzzy
+msgid "audit_tag_create"
+msgstr "%1$s created tag %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a category name, like <a>Search Tools</a>
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:126
+#, fuzzy
+msgid "audit_tag_delete"
+msgstr "%1$s deleted category %2$s (ID %3$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a category name, like <a>Search Tools</a>
+#: controllers/components/audit.php:121
+#, fuzzy
+msgid "audit_tag_edit"
+msgstr "%1$s edited category %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:266
+#, fuzzy
+msgid "audit_update_applications"
+msgstr "%1$s updated application translations for %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:277
+#, fuzzy
+msgid "audit_update_blog"
+msgstr "%1$s updated blog post translations for %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:274
+#, fuzzy
+msgid "audit_update_platforms"
+msgstr "%1$s updated platform translations for %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:270
+#, fuzzy
+msgid "audit_update_tags"
+msgstr "%1$s updated category translations for %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>user name</a>
+#: controllers/components/audit.php:217
+#, fuzzy
+msgid "audit_user_edit"
+msgstr "%1$s edited %2$s's user information"
+
+#: controllers/addons_controller.php:1012
+msgid "browse_addons_name"
+msgstr "부가 기능 ì´ë¦„순"
+
+#: controllers/addons_controller.php:1010
+msgid "browse_addons_newest"
+msgstr "최신 부가 기능순"
+
+#: controllers/addons_controller.php:1008
+msgid "browse_addons_popular"
+msgstr "ì¸ê¸° 부가 기능순"
+
+#: controllers/addons_controller.php:1011
+msgid "browse_addons_rated"
+msgstr "부가 기능 ë³„ì  ìˆœ"
+
+#: controllers/addons_controller.php:1009
+msgid "browse_addons_updated"
+msgstr "최근 ì—…ë°ì´íŠ¸ìˆœ"
+
+#: views/elements/categories.thtml:73 views/elements/categories.thtml:82
+msgid "categories_current_title"
+msgstr "현재 분류"
+
+#: views/elements/categories.thtml:50
+#: views/elements/amo2009/categories.thtml:43
+#: views/elements/amo2009/categories.thtml:45
+msgid "categories_header"
+msgstr "분류"
+
+#: views/elements/categories.thtml:50
+#: views/elements/amo2009/categories.thtml:41
+msgid "categories_header_title"
+msgstr "분류 ì„ íƒ"
+
+# %1 is the category name
+#. %1$s is the category name
+#: views/addons/searchengines.thtml:129
+#, php-format
+msgid "category_extra_see_all"
+msgstr "ëª¨ë‘ ë³´ê¸°- %1$s"
+
+#. %1$s is a number.
+#: models/collection.php:130
+#, fuzzy
+msgid "collection_description_limit"
+msgstr "The description should be less than %1$s characters."
+
+#. %1$s is the name of the collection
+#: controllers/collections_controller.php:392
+#, fuzzy
+msgid "collection_detail_rss_title"
+msgstr "%s Collection"
+
+#: controllers/collections_controller.php:1065
+#, fuzzy
+msgid "collection_error_deleting_addon"
+msgstr "Error deleting add-on!"
+
+#: controllers/collections_controller.php:1051
+#, fuzzy
+msgid "collection_error_saving_addon"
+msgstr "Error saving add-on!"
+
+#: controllers/collections_controller.php:1080
+#, fuzzy
+msgid "collection_error_saving_comment"
+msgstr "Error saving comment!"
+
+#. %1$s is a number.
+#: models/collection.php:122
+#, fuzzy
+msgid "collection_name_limit"
+msgstr "The name should be less than %1$s characters."
+
+#: controllers/collections_controller.php:352
+#: controllers/collections_controller.php:487
+#, fuzzy
+msgid "collection_not_found"
+msgstr "Collection not found!"
+
+#. %1$s is the text on the "create collection" button
+#: views/collections/add.thtml:91
+#, fuzzy
+msgid "collections_add_formfield_addons_description"
+msgstr ""
+"If you already know which add-ons you want to add to your collection, just "
+"start typing their names below. If you'd rather wait and do this later, just "
+"click %1$s now."
+
+#: views/collections/add.thtml:90
+#, fuzzy
+msgid "collections_add_formfield_firstaddons"
+msgstr "Choose your first add-ons"
+
+#: views/collections/add.thtml:48
+#, fuzzy
+msgid "collections_add_header"
+msgstr "Create a Collection"
+
+#: views/collections/add.thtml:97
+#, fuzzy
+msgid "collections_add_header_selectedaddons"
+msgstr "Selected Add-ons"
+
+#: views/collections/add.thtml:50
+#, fuzzy
+msgid "collections_add_intro"
+msgstr ""
+"It's easy to create your own collection of add-ons by filling in a few "
+"fields below."
+
+#: views/collections/add.thtml:92 views/collections/add.thtml:103
+#, fuzzy
+msgid "collections_add_submit"
+msgstr "Create Collection"
+
+#: views/pages/collector_faq.thtml:50 views/pages/collector_firstrun.thtml:43
+#: views/pages/collector.thtml:47 views/pages/collector_features.thtml:55
+#: controllers/search_controller.php:302
+#: controllers/collections_controller.php:206
+#: controllers/collections_controller.php:405
+#: controllers/collections_controller.php:467
+#: controllers/collections_controller.php:539
+#, fuzzy
+msgid "collections_breadcrumb"
+msgstr "Collections"
+
+#: views/collections/detail.thtml:185
+#, fuzzy
+msgid "collections_detail_a_learn"
+msgstr "Learn More"
+
+#: views/elements/amo2009/collection_add_form.thtml:53
+#: views/elements/amo2009/collections_js_init.thtml:68
+#: views/pages/collector_firstrun.thtml:64
+#, fuzzy
+msgid "collections_detail_button_add"
+msgstr "Add to Favorites"
+
+#: views/elements/amo2009/collection_add_form.thtml:50
+#: views/elements/amo2009/collections_js_init.thtml:71
+#, fuzzy
+msgid "collections_detail_button_remove"
+msgstr "Remove from Favorites"
+
+#. %1$s is a URL.
+#. %2$s is a full <a href>.
+#: views/collections/detail.thtml:62
+#, fuzzy
+msgid "collections_detail_created_desc"
+msgstr ""
+"<p>You can view your new collection below. If you'd like to set a collection "
+"nickname, upload an icon, or change additional settings, please visit the <a "
+"href='%1$s'>Manage Collections</a> page.</p><p>Your collection can be "
+"accessed at this location: %2$s</p>"
+
+#: views/collections/detail.thtml:61
+#, fuzzy
+msgid "collections_detail_created_msg"
+msgstr "Your collection is now ready!"
+
+#: views/collections/detail.thtml:109
+#, fuzzy
+msgid "collections_detail_header_about"
+msgstr "About This Collection"
+
+#. %1$s is a number.
+#: views/collections/detail.thtml:126
+#, fuzzy
+msgid "collections_detail_header_count"
+msgid_plural "collections_detail_header_count"
+msgstr[0] "%1$s Add-on in this Collection"
+msgstr[1] "%1$s Add-ons in this Collection"
+
+#: views/collections/detail.thtml:113
+#, fuzzy
+msgid "collections_detail_info_created"
+msgstr "<strong>Created by:</strong> %1$s"
+
+#: views/collections/detail.thtml:117
+#, fuzzy
+msgid "collections_detail_info_updated"
+msgstr "<strong>Updated:</strong>"
+
+#: views/elements/amo2009/collections_js_init.thtml:62
+#, fuzzy
+msgid "collections_detail_js_adding"
+msgstr "Adding to Favorites&hellip;"
+
+#: views/elements/amo2009/collections_js_init.thtml:65
+#, fuzzy
+msgid "collections_detail_js_removing"
+msgstr "Removing Favorite&hellip;"
+
+#. %1$s is a URL
+#: views/collections/detail.thtml:90
+#, fuzzy
+msgid "collections_detail_login"
+msgstr "<a href=\"%1$s\">Log in</a> to add this collection to your favorites."
+
+#: views/collections/detail.thtml:104
+#, fuzzy
+msgid "collections_detail_manage"
+msgstr "Manage Collection"
+
+#: controllers/collections_controller.php:298
+#, fuzzy
+msgid "collections_detail_sort_date"
+msgstr "Date Added"
+
+#: controllers/collections_controller.php:299
+#, fuzzy
+msgid "collections_detail_sort_name"
+msgstr "Name"
+
+#: controllers/collections_controller.php:300
+#, fuzzy
+msgid "collections_detail_sort_popularity"
+msgstr "Popularity"
+
+#. %1$s is a number.
+#: views/collections/detail.thtml:166
+#, fuzzy
+msgid "collections_detail_weekly_downloads"
+msgid_plural "collections_detail_weekly_downloads"
+msgstr[0] "%1$s download this week"
+msgstr[1] "%1$s downloads this week"
+
+#: views/collections/edit.thtml:255
+#, fuzzy
+msgid "collections_edit_addons_delete_noscript"
+msgstr "Selected add-ons will be removed upon Save"
+
+#: views/collections/edit.thtml:247
+#, fuzzy
+msgid "collections_edit_addons_description"
+msgstr ""
+"To publish new add-ons to this collection, start typing their names below."
+
+#: views/collections/edit.thtml:248
+#, fuzzy
+msgid "collections_edit_addons_description_noscript"
+msgstr ""
+"To publish new add-ons to this collection, enter a comma-separated list of "
+"Add-on IDs below."
+
+#: views/collections/edit.thtml:247 views/collections/edit.thtml:248
+#, fuzzy
+msgid "collections_edit_addons_description_publish_detailspage"
+msgstr "You can also publish an add-on from its normal listing page."
+
+#. %1$s is the date the add-on was added to the collection
+#. %1$s is the name of the user who added the add-on to the collection
+#: views/collections/edit.thtml:260
+#, fuzzy
+msgid "collections_edit_addons_listitem_added"
+msgstr "Added %1$s by %2$s"
+
+#: views/collections/edit.thtml:263
+#, fuzzy
+msgid "collections_edit_addons_listitem_comment_add"
+msgstr "Add publisher comment"
+
+#: views/collections/edit.thtml:266
+#, fuzzy
+msgid "collections_edit_addons_listitem_comment_delete"
+msgstr "Delete publisher comment"
+
+#: views/collections/edit.thtml:265
+#, fuzzy
+msgid "collections_edit_addons_listitem_comment_edit"
+msgstr "Edit publisher comment"
+
+#: views/collections/edit.thtml:271
+#, fuzzy
+msgid "collections_edit_addons_listitem_comment_note"
+msgstr ""
+"Note: Comment will appear as though written by original publisher on the "
+"original publication date"
+
+#: views/collections/edit.thtml:270
+#, fuzzy
+msgid "collections_edit_addons_listitem_comment_submit"
+msgstr "Save Comment"
+
+#: views/collections/edit.thtml:261
+#, fuzzy
+msgid "collections_edit_addons_listitem_remove"
+msgstr "Remove"
+
+#: views/collections/edit.thtml:250
+#, fuzzy
+msgid "collections_edit_addons_submit"
+msgstr "Add to Collection"
+
+#: views/collections/edit.thtml:153
+#, fuzzy
+msgid "collections_edit_check_nickname"
+msgstr "Check Availability"
+
+#: views/collections/edit.thtml:299
+#, fuzzy
+msgid "collections_edit_confirm_deletecollection"
+msgstr "Yes, I would like to delete this collection."
+
+#. %1$s is the label of the edit form's submit button
+#: views/collections/edit.thtml:300
+#, fuzzy
+msgid "collections_edit_confirm_deletecollection_description"
+msgstr "Check the box, then click on \"%1$s\" to delete this collection."
+
+#. %1$s is the "delete" submit button text
+#. %2$s is the title of the "advanced" tab
+#: views/collections/edit.thtml:95
+#, fuzzy
+msgid "collections_edit_delete_upon_submit"
+msgstr ""
+"Upon clicking \"%1$s\" below, your collection will be deleted. If you do not "
+"want to delete your collection, uncheck the confirmation box in the \"%2$s\" "
+"tab and continue editing your collection. If you leave this page without "
+"saving, your collection will also not be deleted."
+
+#: views/collections/edit.thtml:94
+#, fuzzy
+msgid "collections_edit_delete_warning"
+msgstr "Your collection is about to be deleted!"
+
+#: views/collections/add.thtml:76 views/collections/edit.thtml:144
+#, fuzzy
+msgid "collections_edit_form_error_description"
+msgstr "You must provide a description of your collection."
+
+#: views/collections/edit.thtml:181
+#, fuzzy
+msgid "collections_edit_form_error_icon"
+msgstr "There was an error uploading your icon."
+
+#: views/collections/add.thtml:69 views/collections/edit.thtml:130
+#, fuzzy
+msgid "collections_edit_form_error_name"
+msgstr "You must give your collection a name."
+
+#: views/collections/edit.thtml:158
+#, fuzzy
+msgid "collections_edit_form_error_nickname"
+msgstr "If you choose a nickname, it must be unique."
+
+#: views/collections/add.thtml:93 views/collections/edit.thtml:249
+#, fuzzy
+msgid "collections_edit_formfield_addons"
+msgstr "Add-on name:"
+
+#: views/collections/edit.thtml:281
+#, fuzzy
+msgid "collections_edit_formfield_application"
+msgstr "Associated Application"
+
+#: views/collections/edit.thtml:282
+#, fuzzy
+msgid "collections_edit_formfield_application_description"
+msgstr "Select the application that your collection supports."
+
+#: views/collections/edit.thtml:288
+#, fuzzy
+msgid "collections_edit_formfield_collectiontype"
+msgstr "Collection Type"
+
+#: views/collections/edit.thtml:295
+#, fuzzy
+msgid "collections_edit_formfield_deletecollection"
+msgstr "Delete Collection"
+
+#: views/collections/edit.thtml:296
+#, fuzzy
+msgid "collections_edit_formfield_deletecollection_description"
+msgstr "Deleting your collection will permanently erase it."
+
+#: views/collections/add.thtml:73 views/collections/edit.thtml:140
+#, fuzzy
+msgid "collections_edit_formfield_description"
+msgstr "Collection Description"
+
+#: views/collections/add.thtml:74 views/collections/edit.thtml:141
+#, fuzzy
+msgid "collections_edit_formfield_description_description"
+msgstr "Briefly describe your collection and the kind of add-ons in it"
+
+#: views/collections/edit.thtml:162
+#, fuzzy
+msgid "collections_edit_formfield_icon"
+msgstr "Icon"
+
+#: views/collections/edit.thtml:163
+#, fuzzy
+msgid "collections_edit_formfield_icon_description"
+msgstr ""
+"You can upload a JPG, GIF or PNG icon that will be resized to 32x32 pixels."
+
+#: views/collections/add.thtml:80 views/collections/edit.thtml:189
+#, fuzzy
+msgid "collections_edit_formfield_listed"
+msgstr "Who can view your collection?"
+
+#: views/collections/add.thtml:81 views/collections/edit.thtml:190
+#, fuzzy
+msgid "collections_edit_formfield_listed_description"
+msgstr ""
+"By default, collections appear in the public Collection Directory and are "
+"discoverable by anyone. If you want to restrict your collection to be "
+"viewable only by people who are given a special link, choose that option "
+"below."
+
+#: views/collections/add.thtml:84 views/collections/edit.thtml:193
+#, fuzzy
+msgid "collections_edit_formfield_listed_false"
+msgstr "Only people I invite can view my collection"
+
+#: views/collections/add.thtml:83 views/collections/edit.thtml:192
+#, fuzzy
+msgid "collections_edit_formfield_listed_true"
+msgstr "Everyone can view my collection in the directory"
+
+#: views/collections/edit.thtml:223
+#, fuzzy
+msgid "collections_edit_formfield_managers"
+msgstr "Who can manage my collection?"
+
+#: views/collections/edit.thtml:224
+#, fuzzy
+msgid "collections_edit_formfield_managers_description"
+msgstr ""
+"These users can publish add-ons to your collection, manage all add-ons and "
+"settings, and grant other users permission."
+
+#: views/collections/add.thtml:66 views/collections/edit.thtml:126
+#, fuzzy
+msgid "collections_edit_formfield_name"
+msgstr "Collection Name"
+
+#: views/collections/add.thtml:67 views/collections/edit.thtml:127
+#, fuzzy
+msgid "collections_edit_formfield_name_description"
+msgstr ""
+"Give your collection a descriptive name, such as \"Dave's Favorite Travel "
+"Add-ons\""
+
+#: views/collections/edit.thtml:148
+#, fuzzy
+msgid "collections_edit_formfield_nickname"
+msgstr "Collection Nickname"
+
+#: views/collections/edit.thtml:149
+#, fuzzy
+msgid "collections_edit_formfield_nickname_description"
+msgstr "Optionally, give your collection a unique nickname for quick access:"
+
+#: views/collections/edit.thtml:201
+#, fuzzy
+msgid "collections_edit_formfield_publishers"
+msgstr "Who can publish add-ons to your collection?"
+
+#: views/collections/edit.thtml:202
+#, fuzzy
+msgid "collections_edit_formfield_publishers_description"
+msgstr ""
+"These users can publish add-ons to your collection and remove add-ons that "
+"they publish."
+
+#: views/collections/edit.thtml:210 views/collections/edit.thtml:232
+#, fuzzy
+msgid "collections_edit_formfield_users_add"
+msgstr "Enter the e-mail address of a Firefox Add-ons account:"
+
+#: views/collections/edit.thtml:216 views/collections/edit.thtml:238
+#, fuzzy
+msgid "collections_edit_formfield_users_delete_noscript"
+msgstr "Selected accounts will be removed upon Save"
+
+#: views/collections/edit.thtml:215 views/collections/edit.thtml:237
+#, fuzzy
+msgid "collections_edit_formfield_users_new_noscript"
+msgstr ""
+"Enter a comma-separated list of e-mail addresses of Firefox Add-ons accounts"
+
+#: views/collections/edit.thtml:204 views/collections/edit.thtml:226
+#, fuzzy
+msgid "collections_edit_formfield_users_onlyme"
+msgstr "Only me"
+
+#: views/collections/edit.thtml:205 views/collections/edit.thtml:227
+#, fuzzy
+msgid "collections_edit_formfield_users_otherusers"
+msgstr "Myself and these users:"
+
+#: views/collections/edit.thtml:211 views/collections/edit.thtml:233
+#, fuzzy
+msgid "collections_edit_formfield_users_submit"
+msgstr "Add"
+
+#. %1$s is the name of the collection
+#: views/collections/edit.thtml:68
+#, fuzzy
+msgid "collections_edit_header"
+msgstr "Manage %1$s"
+
+#: views/collections/edit.thtml:246
+#, fuzzy
+msgid "collections_edit_header_addons"
+msgstr "Manage Collection Contents"
+
+#: views/collections/edit.thtml:253 views/collections/edit.thtml:258
+#, fuzzy
+msgid "collections_edit_header_addons_current"
+msgstr "Current Add-ons:"
+
+#: views/collections/edit.thtml:279
+#, fuzzy
+msgid "collections_edit_header_advanced"
+msgstr "Advanced Settings"
+
+#: views/collections/edit.thtml:186
+#, fuzzy
+msgid "collections_edit_header_permissions"
+msgstr "Manage Collection Permissions"
+
+#: views/collections/edit.thtml:170
+#, fuzzy
+msgid "collections_edit_icon_cancel"
+msgstr "Cancel"
+
+#: views/collections/edit.thtml:174 views/collections/edit.thtml:179
+#, fuzzy
+msgid "collections_edit_icon_delete"
+msgstr "Delete Icon"
+
+#: views/collections/edit.thtml:178
+#, fuzzy
+msgid "collections_edit_icon_replace"
+msgstr "Replace Icon"
+
+#. %1$s is the label of the edit form's submit button
+#: views/collections/edit.thtml:169
+#, fuzzy
+msgid "collections_edit_icon_toberemoved"
+msgstr "Icon will be removed when \"%1$s\" is clicked below"
+
+#: views/collections/edit.thtml:155
+#, fuzzy
+msgid "collections_edit_nickname_available"
+msgstr "Nickname Available"
+
+#: controllers/collections_controller.php:943
+#, fuzzy
+msgid "collections_edit_nickname_error"
+msgstr ""
+"Your nickname contained invalid characters and was corrected. Please try "
+"again."
+
+#: views/collections/edit.thtml:156
+#, fuzzy
+msgid "collections_edit_nickname_taken"
+msgstr "Nickname Taken"
+
+#. This string is followed by a URL pointing to the collection's view page
+#: views/collections/edit.thtml:75
+#, fuzzy
+msgid "collections_edit_saved_nextstep"
+msgstr "Your collection can be accessed at this location:"
+
+#: views/collections/edit.thtml:74
+#, fuzzy
+msgid "collections_edit_saved_success"
+msgstr "Your collection was successfully saved!"
+
+#: views/collections/edit.thtml:169 views/collections/edit.thtml:300
+#: views/collections/edit.thtml:308 views/pages/js_constants.js.thtml:99
+#, fuzzy
+msgid "collections_edit_submit"
+msgstr "Update Collection"
+
+#: views/collections/edit.thtml:96 views/collections/edit.thtml:297
+#: views/pages/js_constants.js.thtml:100
+#, fuzzy
+msgid "collections_edit_submit_deletecollection"
+msgstr "Delete Collection"
+
+#: views/collections/edit.thtml:111
+#, fuzzy
+msgid "collections_edit_tabheader_addons"
+msgstr "Add-ons"
+
+#: views/collections/edit.thtml:97 views/collections/edit.thtml:113
+#, fuzzy
+msgid "collections_edit_tabheader_advanced"
+msgstr "Advanced"
+
+#: views/collections/edit.thtml:108
+#, fuzzy
+msgid "collections_edit_tabheader_details"
+msgstr "Name &amp; Details"
+
+#: views/collections/edit.thtml:109
+#, fuzzy
+msgid "collections_edit_tabheader_permissions"
+msgstr "Permissions"
+
+#: models/collection_promo.php:53
+#, fuzzy
+msgid "collections_family_tagline"
+msgstr "Add-ons can keep an eye on your kids and your calendar."
+
+#: models/collection_promo.php:53
+#, fuzzy
+msgid "collections_family_title"
+msgstr "Family Organizer"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:70
+#, fuzzy
+msgid "collections_index_a_check_out"
+msgstr "Check out Add-on Collector"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:52
+#, fuzzy
+msgid "collections_index_a_create"
+msgstr "Create a Collection"
+
+#: views/collections/detail.thtml:139 views/collections/listing.thtml:85
+#: views/search/collections.thtml:84
+#, fuzzy
+msgid "collections_index_button_go"
+msgstr "Go"
+
+#. %1$s is a URL.
+#: controllers/collections_controller.php:182
+#, fuzzy
+msgid "collections_index_filler_favorites"
+msgstr ""
+"<p><strong>You don't have any favorite collections yet.</strong></p> "
+"<p>Collections you mark as favorites can be quickly accessed from this page, "
+"and will appear in the <a href='%1$s'>Add-on Collector</a> if you've "
+"installed it.</p>"
+
+#. %1$s is a URL.
+#: controllers/collections_controller.php:167
+#, fuzzy
+msgid "collections_index_filler_mine"
+msgstr ""
+"<p>You haven't created any collections yet. Collections are easy to create "
+"and fill with your favorite add-ons. <a href='%1$s'>Try it out</a>!</p>"
+
+#: views/collections/listing.thtml:51
+#, fuzzy
+msgid "collections_index_header_collections"
+msgstr "Collections"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:60
+#, fuzzy
+msgid "collections_index_header_collector"
+msgstr "Add-on Collector"
+
+#. %1$s is a comma-separated list of author names
+#: views/elements/amo2009/collection_listing_item.thtml:84
+#: views/collections/detail.thtml:151
+#, fuzzy
+msgid "collections_index_header_created"
+msgstr "created by %1$s"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:47
+#, fuzzy
+msgid "collections_index_header_what"
+msgstr "What are Collections?"
+
+#: views/collections/detail.thtml:132 views/collections/listing.thtml:78
+#: views/search/collections.thtml:66
+#, fuzzy
+msgid "collections_index_label_sortby"
+msgstr "Sort by"
+
+#: controllers/collections_controller.php:130
+#, fuzzy
+msgid "collections_index_li_editors"
+msgstr "Editor's Picks"
+
+#: views/collections/subscribe.thtml:64
+#: controllers/collections_controller.php:140
+#, fuzzy
+msgid "collections_index_li_favorites"
+msgstr "My Favorites"
+
+#: controllers/collections_controller.php:138
+#, fuzzy
+msgid "collections_index_li_mine"
+msgstr "My Collections"
+
+#: controllers/collections_controller.php:132
+#, fuzzy
+msgid "collections_index_li_popular"
+msgstr "Popular"
+
+#: views/search/collections.thtml:74 controllers/collections_controller.php:81
+#, fuzzy
+msgid "collections_index_option_all"
+msgstr "Most popular all time"
+
+#: views/search/collections.thtml:72 controllers/collections_controller.php:78
+#, fuzzy
+msgid "collections_index_option_month"
+msgstr "Most popular this month"
+
+#: views/search/collections.thtml:76 controllers/collections_controller.php:84
+#, fuzzy
+msgid "collections_index_option_newest"
+msgstr "Newest"
+
+#: views/search/collections.thtml:70 controllers/collections_controller.php:75
+#, fuzzy
+msgid "collections_index_option_week"
+msgstr "Most popular this week"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:67
+#, fuzzy
+msgid "collections_index_p_collector"
+msgstr ""
+"There's a new way to manage and find favorite add-ons. Comment, share and "
+"sync collections, all from your browser"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:48
+#, fuzzy
+msgid "collections_index_p_what_are"
+msgstr "Collections are groups of related add-ons assembled for easy sharing."
+
+#. %s is a date in the _('date') format
+#: views/elements/collections_interactive_addon.thtml:85
+#, fuzzy, php-format
+msgid "collections_interactive_addon_added"
+msgstr "Added %s"
+
+#: models/collection_promo.php:55
+#, fuzzy
+msgid "collections_reference_tagline"
+msgstr "Add-ons can do better research online."
+
+#: models/collection_promo.php:55
+#, fuzzy
+msgid "collections_reference_title"
+msgstr "Reference Desk"
+
+#: models/collection_promo.php:52
+#, fuzzy
+msgid "collections_social_tagline"
+msgstr "Add-ons can manage your social network."
+
+#: models/collection_promo.php:52
+#, fuzzy
+msgid "collections_social_title"
+msgstr "Social Circuit"
+
+#: views/collections/subscribe.thtml:91
+#, fuzzy
+msgid "collections_subscribe_button_close"
+msgstr "Close"
+
+#: views/collections/subscribe.thtml:70
+#, fuzzy
+msgid "collections_subscribe_error"
+msgstr ""
+"An error occurred trying to add a favorite collection. Is this collection "
+"already a favorite?"
+
+#: views/collections/subscribe.thtml:96
+#, fuzzy
+msgid "collections_subscribe_label_bothersome"
+msgstr "Don't show me this message again."
+
+#. %1$s is the collection name
+#: views/collections/subscribe.thtml:60
+#, fuzzy
+msgid "collections_subscribe_success"
+msgstr "%1$s has been added to your favorite collections."
+
+#. %1$s is the link to the "My Favorites" tab on the main collections page
+#. %2$s is the localized title of the "My Favorites" tab
+#. %3$s is the link URL to the collector add-on
+#: views/collections/subscribe.thtml:62
+#, fuzzy
+msgid "collections_subscribe_success_desc"
+msgstr ""
+"You can now quickly find this collection from the <a href=\"%1$s\">%2$s</a> "
+"tab in the directory. For an even easier way to keep track of your favorite "
+"collections, try out our <a href=\"%3$s\">Add-on Collector</a> extension for "
+"Firefox."
+
+#: views/collections/listing.thtml:55
+#, fuzzy
+msgid "collections_success_delete"
+msgstr "The collection has been deleted."
+
+#: models/collection_promo.php:54
+#, fuzzy
+msgid "collections_travel_tagline"
+msgstr "Add-ons can turn you into a travel agent."
+
+#: models/collection_promo.php:54
+#, fuzzy
+msgid "collections_travel_title"
+msgstr "The Traveler's Pack"
+
+#. A collection of add-ons that is automatically built for a user. They are "automatically published" to this collection.
+#: controllers/collections_controller.php:581
+#, fuzzy
+msgid "collections_type_autopublisher"
+msgstr "Auto-publisher"
+
+#. A collection that has been chosen by an Editor as notable or exceptional
+#: controllers/collections_controller.php:582
+#, fuzzy
+msgid "collections_type_editorspick"
+msgstr "Editor's Pick"
+
+#: controllers/collections_controller.php:580
+#, fuzzy
+msgid "collections_type_normal"
+msgstr "Normal"
+
+#: views/collections/subscribe.thtml:84
+#, fuzzy
+msgid "collections_unsubscribe_error"
+msgstr ""
+"An error occurred trying to remove a favorite collection. Was this "
+"collection not a favorite?"
+
+#. %1$s is the collection name
+#: views/collections/subscribe.thtml:78
+#, fuzzy
+msgid "collections_unsubscribe_success"
+msgstr "%1$s has been removed from your favorite collections."
+
+#: models/collection_promo.php:56
+#, fuzzy
+msgid "collections_webdev_tagline"
+msgstr "Add-ons make it easier to build the perfect website."
+
+#: models/collection_promo.php:56
+#, fuzzy
+msgid "collections_webdev_title"
+msgstr "Web Developer's Toolbox"
+
+#: views/elements/amo2009/collections_sidebar_whatare.thtml:40
+#, fuzzy
+msgid "collections_whatare_header"
+msgstr "What are Collections?"
+
+#: views/elements/amo2009/collections_sidebar_whatare.thtml:45
+#, fuzzy
+msgid "collections_whatare_learnmore"
+msgstr "Read the FAQ"
+
+#: views/elements/amo2009/collections_sidebar_whatare.thtml:44
+#, fuzzy
+msgid "collections_whatare_text"
+msgstr ""
+"There’s a new way to manage and find favorite add-ons. Comment, share and "
+"sync collections, all from your browser."
+
+#: views/pages/collector_faq.thtml:61 views/pages/collector_features.thtml:67
+#, fuzzy
+msgid "collector_features_a_home"
+msgstr "Add-on Collector Home"
+
+#: views/elements/amo2009/collector_sidebar_download.thtml:46
+#, fuzzy
+msgid "collector_features_heading_download"
+msgstr "Download the Add-on Collector:"
+
+#: views/elements/amo2009/collector_sidebar_download.thtml:43
+#: views/pages/collector_firstrun.thtml:116 views/pages/collector.thtml:69
+#, fuzzy
+msgid "collector_features_img_logo"
+msgstr "Add-on Collector Logo"
+
+#: views/compatibility/dashboard.thtml:49
+#: controllers/compatibility_controller.php:72
+#, fuzzy
+msgid "compatibility_dashboard_center_header"
+msgstr "Add-on Compatibility Center"
+
+#. %1$s is the name of an application and a version. Example: Firefox 3.0
+#. %2$s is the name of an application. Example: Firefox
+#: views/compatibility/dashboard.thtml:50
+#, fuzzy
+msgid "compatibility_dashboard_intro"
+msgstr ""
+"Be prepared for the release of %1$s with the tools and information available "
+"for the %2$s Add-ons community found below."
+
+#: views/compatibility/dashboard.thtml:103
+#, fuzzy
+msgid "compatibility_dashboard_loading"
+msgstr "Loading data..."
+
+#: views/compatibility/dashboard.thtml:45
+#, fuzzy
+msgid "compatibility_dashboard_main_link"
+msgstr "Back to Main"
+
+#: views/compatibility/dashboard.thtml:100 views/compatibility/report.thtml:43
+#, fuzzy
+msgid "compatibility_dashboard_report"
+msgstr "Add-on Compatibility Report"
+
+#: views/compatibility/dashboard.thtml:53
+#: views/compatibility/dashboard.thtml:110
+#: views/compatibility/developers.thtml:43
+#, fuzzy
+msgid "compatibility_developer_info"
+msgstr "Information for Add-on Developers"
+
+#: views/compatibility/developers.thtml:66
+#, fuzzy
+msgid "compatibility_developers_adjust_maxversion"
+msgstr "Adjust maxVersion without uploading"
+
+#: views/compatibility/dashboard.thtml:124
+#, fuzzy
+msgid "compatibility_developers_check_status"
+msgstr "Check Status of My Add-ons"
+
+#. %1$s is a URL
+#. %2$s is an application and version. Example: Firefox 3.0
+#: views/compatibility/dashboard.thtml:126
+#, fuzzy
+msgid "compatibility_developers_login_first"
+msgstr ""
+"If you have add-ons hosted on Mozilla Add-ons, <a href=\"%1$s\">please "
+"login</a> to analyze the status of your add-ons for %2$s."
+
+#: views/compatibility/dashboard.thtml:114
+#, fuzzy
+msgid "compatibility_developers_mdclogo_alt"
+msgstr "Mozilla Developer Center Logo"
+
+#: views/compatibility/developers.thtml:73
+#, fuzzy
+msgid "compatibility_developers_no_addons"
+msgstr "You do not have any add-ons hosted on Mozilla Add-ons."
+
+#: views/compatibility/dashboard.thtml:133
+#: views/compatibility/developers.thtml:55
+#, fuzzy
+msgid "compatibility_developers_results"
+msgstr "Add-on Status Check Results"
+
+#: views/compatibility/dashboard.thtml:137
+#, fuzzy
+msgid "compatibility_developers_retrieving"
+msgstr "Retrieving status of hosted add-ons..."
+
+#. %1$s is a number
+#. %2$s is an application name
+#. %3$s is a number.
+#. Full example: 50 Firefox users (10% of total)
+#: views/compatibility/developers.thtml:65
+#, fuzzy
+msgid "compatibility_developers_user_count"
+msgstr "%1$s %2$s users (%3$s&#37; of total)"
+
+#: views/compatibility/report.thtml:45
+#, fuzzy
+msgid "compatibility_report_detail_intro"
+msgstr ""
+"The add-ons below make up 95% of add-on usage known to Mozilla and are "
+"ordered by their usage size."
+
+#: views/compatibility/dashboard.thtml:94
+#, fuzzy
+msgid "compatibility_report_detailed_link"
+msgstr "View Detailed Report"
+
+#. %1$s and %2$s are numbers
+#. %3$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:65
+#, fuzzy
+msgid "compatibility_report_intro"
+msgstr ""
+"Of the %1$s add-ons that make up 95&#37; of add-on usage known to Mozilla, "
+"<b>%2$s&#37;</b> are currently considered compatible with the latest builds "
+"of %3$s."
+
+#: views/compatibility/dashboard.thtml:81
+#, fuzzy
+msgid "compatibility_report_legend_alpha"
+msgstr "Alpha Versions"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:81
+#, fuzzy
+msgid "compatibility_report_legend_alpha_description"
+msgstr "Add-ons compatible with an alpha version of %1$s"
+
+#: views/compatibility/dashboard.thtml:85
+#, fuzzy
+msgid "compatibility_report_legend_beta"
+msgstr "Beta Versions"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:85
+#, fuzzy
+msgid "compatibility_report_legend_beta_description"
+msgstr "Add-ons compatible with a beta version or release candidate of %1$s"
+
+#: views/compatibility/dashboard.thtml:89
+#, fuzzy
+msgid "compatibility_report_legend_latest"
+msgstr "Latest Version"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:89
+#, fuzzy
+msgid "compatibility_report_legend_latest_description"
+msgstr "Add-ons up-to-date with the latest builds of %1$s"
+
+#: views/compatibility/dashboard.thtml:77
+#, fuzzy
+msgid "compatibility_report_legend_other"
+msgstr "Other Versions"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:77
+#, fuzzy
+msgid "compatibility_report_legend_other_description"
+msgstr "Add-ons not compatible with any version of %1$s"
+
+#: views/compatibility/dashboard.thtml:62
+#, fuzzy
+msgid "compatibility_report_title"
+msgstr "Add-on Compatibility Report"
+
+#: views/compatibility/dashboard.thtml:54
+#: views/compatibility/dashboard.thtml:144 views/compatibility/users.thtml:42
+#, fuzzy
+msgid "compatibility_user_info"
+msgstr "Information for Add-on Users"
+
+#: views/compatibility/dashboard.thtml:52
+#, fuzzy
+msgid "compatibility_view_report"
+msgstr "View Compatibility Report"
+
+#. %s is a URL
+#: views/pages/credits.thtml:142
+#, php-format
+msgid "credits_contributing"
+msgstr "ê¸°ì—¬ìž ì •ë³´ë¥¼ ë” ë³´ì‹œë ¤ë©´ %sì„ ì°¸ê³ í•˜ì„¸ìš”."
+
+#: views/pages/credits.thtml:142
+msgid "credits_contributing_wikipage"
+msgstr "위키 페ì´ì§€"
+
+#: views/pages/credits.thtml:99
+msgid "credits_intro"
+msgstr ""
+"Mozilla 커뮤니티ì—서는 수년 ê°„ addons.mozilla.org 프로ì íŠ¸ì— 기여한 분들ì—"
+"게 ê°ì‚¬ë¥¼ 드립니다."
+
+#: views/pages/credits.thtml:103
+msgid "credits_section_developers"
+msgstr "개발ìž"
+
+#: views/pages/credits.thtml:115
+msgid "credits_section_editors"
+msgstr "편집ìž"
+
+#: views/pages/credits.thtml:109
+msgid "credits_section_localizers"
+msgstr "번역ìž"
+
+#: views/pages/credits.thtml:121
+msgid "credits_section_other_contributors"
+msgstr "기타 기여ìž"
+
+#: views/pages/credits.thtml:127
+msgid "credits_section_past_developers"
+msgstr "ì´ì „ 개발ìž"
+
+#: views/pages/credits.thtml:133
+msgid "credits_section_software"
+msgstr "소프트웨어 ë° ì´ë¯¸ì§€"
+
+#: views/pages/credits.thtml:136
+msgid "credits_software_famfamfam"
+msgstr ""
+"ì¼ë¶€ ì•„ì´ì½˜ ì •ë³´ <a href=\"http://www.famfamfam.com/lab/icons/silk/"
+"\">famfamfam Silk Icon Set</a> ë¼ì´ì„¼ìŠ¤ ì •ë³´ <a href=\"http://"
+"creativecommons.org/licenses/by/2.5/\">Creative Commons Attribution 2.5 ë¼ì´"
+"센스</a>."
+
+#: views/pages/credits.thtml:137
+#, fuzzy
+msgid "credits_software_timeplot"
+msgstr ""
+"Some pages use elements of <a href=\"http://www.simile-widgets.org/timeplot/"
+"\">Timeplot</a>, licensed under a <a href=\"http://simile.mit.edu/license."
+"html\">BSD License</a>."
+
+# date format string as used in PHP's strftime():
+# http://php.net/strftime
+#. date format string as used in PHP's strftime():
+#. http://php.net/strftime
+#: views/elements/collections_interactive_addon.thtml:85
+#: views/elements/amo2009/addon_version_detail.thtml:53
+#: views/elements/amo2009/homepage_addon.thtml:115
+#: views/elements/addon_version_detail.thtml:54
+#: views/elements/addon_listitem.thtml:124 views/elements/feature.thtml:106
+#: views/collections/detail.thtml:118 views/collections/edit.thtml:325
+#: views/users/info.thtml:76 views/editors/reviews_queue.thtml:57
+#: views/editors/reviews_queue.thtml:68 views/developers/dashboard.thtml:65
+#: views/developers/versions_edit.thtml:208 views/developers/versions.thtml:67
+#: views/search/rss/index.thtml:5 views/addons/rss/versions.thtml:42
+#: views/addons/display.thtml:104 views/addons/display.thtml:356
+#: views/addons/browse_thumbs.thtml:75 views/reviews/add.thtml:63
+#: views/reviews/display.thtml:74 views/reviews/display.thtml:160
+#: views/reviews/delete.thtml:54 controllers/statistics_controller.php:244
+#: controllers/collections_controller.php:1047
+msgid "date"
+msgstr "%x"
+
+# date and time format string (strftime)
+#. date and time format string (strftime)
+#. http://php.net/strftime
+#: views/elements/addon_version_detail.thtml:53
+#: views/developers/discuss.thtml:52 views/developers/discuss.thtml:62
+#: views/admin/addons_status.thtml:57
+msgid "datetime"
+msgstr "%x %X"
+
+#: views/elements/developers/actionbar.thtml:47
+msgid "devcp_actionbar_link_details"
+msgstr "ìƒì„¸ ì •ë³´"
+
+#: views/elements/developers/actionbar.thtml:42
+#: views/elements/developers/actionbar.thtml:50
+#: views/developers/dashboard.thtml:64
+msgid "devcp_actionbar_link_edit"
+msgstr "부가 기능 편집"
+
+#: views/elements/developers/actionbar.thtml:51
+msgid "devcp_actionbar_link_newversion"
+msgstr "새 버전 업로드"
+
+#: views/elements/developers/actionbar.thtml:44
+#: views/elements/developers/actionbar.thtml:49
+#: views/developers/dashboard.thtml:73
+msgid "devcp_actionbar_link_stats"
+msgstr "ì´ìš© 통계"
+
+#. %1$s is a filename, e.g. "foo.txt"
+#. %2$s is the extension, e.g. ".txt"
+#. %3$s is a list of valid extensions, like ".png, .jpg, .gif"
+#: controllers/developers_controller.php:1361
+#, fuzzy
+msgid "devcp_add_previews_extension_error"
+msgstr "File %1$s has an invalid extension (%2$s). Allowed extensions: %3$s"
+
+#. %s is the filename.
+#: controllers/developers_controller.php:1394
+#, fuzzy
+msgid "devcp_add_previews_save_error"
+msgstr "File %s could not be saved to the database. Please try again."
+
+#. %1$s is the preview ID number, %2$s is the filename.
+#: controllers/developers_controller.php:1389
+#, fuzzy
+msgid "devcp_add_previews_success_replace"
+msgstr "Preview %1$s was replaced with file %2$s successfully."
+
+#. %s is the filename.
+#: controllers/developers_controller.php:1391
+#, fuzzy
+msgid "devcp_add_previews_success_upload"
+msgstr "File %s was uploaded successfully. You can add a caption below."
+
+#: controllers/components/developers.php:1163
+msgid "devcp_additem_addontype_autodetect"
+msgstr "(ìžë™ íƒì§€)"
+
+#: views/elements/developers/additem.thtml:76
+msgid "devcp_additem_linktitle_opensin_newwindow"
+msgstr "새 창 열기"
+
+#: views/elements/developers/additem.thtml:41
+msgid "devcp_additem_sidebar_title"
+msgstr "부가 기능 전송"
+
+#: views/elements/developers/additem.thtml:53
+msgid "devcp_additem_step0_newlink"
+msgstr "ê°œë°œìž ì•½ê´€"
+
+#: views/elements/developers/additem.thtml:46
+msgid "devcp_additem_step1_link"
+msgstr "단계 1: 업로드"
+
+#: views/elements/developers/additem.thtml:47
+msgid "devcp_additem_step2_link"
+msgstr "단계 2: ìƒì„¸ ì •ë³´"
+
+#: views/elements/developers/additem.thtml:48
+msgid "devcp_additem_step3_link"
+msgstr "단계 3: 버전 정보"
+
+#: views/elements/developers/additem.thtml:49
+msgid "devcp_additem_step4_link"
+msgstr "단계 4: 지역화"
+
+#: views/elements/developers/additem.thtml:50
+msgid "devcp_additem_step5_link"
+msgstr "단계 5: 완료"
+
+#: views/elements/developers/additem.thtml:76
+msgid "devcp_additem_submissionhelp_link"
+msgstr "제출 ë„움ë§"
+
+#: controllers/previews_controller.php:168
+#: controllers/previews_controller.php:277
+msgid "devcp_addon_field_preview_caption_displaytitle"
+msgstr "정보 미리 보기"
+
+#: views/developers/addon_status.thtml:177
+#, fuzzy
+msgid "devcp_addon_status_action_activate"
+msgstr "Make Active"
+
+#: views/developers/addon_status.thtml:178
+#, fuzzy
+msgid "devcp_addon_status_action_activate_description"
+msgstr ""
+"Make your add-on active for it to show up in public listings and enable the "
+"update check service."
+
+#: views/developers/addon_status.thtml:135
+#, fuzzy
+msgid "devcp_addon_status_action_complete"
+msgstr "Complete Add-on"
+
+#: views/developers/addon_status.thtml:136
+#, fuzzy
+msgid "devcp_addon_status_action_complete_description"
+msgstr "Complete your add-on and move to the Sandbox"
+
+#: views/developers/addon_status.thtml:181
+#, fuzzy
+msgid "devcp_addon_status_action_deactivate"
+msgstr "Make Inactive"
+
+#: views/developers/addon_status.thtml:182
+#, fuzzy
+msgid "devcp_addon_status_action_deactivate_description"
+msgstr ""
+"Make your add-on inactive to hide it from all public listings and disable "
+"the update check service."
+
+#: views/developers/addon_status.thtml:143
+#, fuzzy
+msgid "devcp_addon_status_action_move"
+msgstr "Move to Sandbox"
+
+#: views/developers/addon_status.thtml:144
+#, fuzzy
+msgid "devcp_addon_status_action_move_description"
+msgstr "Move your add-on back to the Sandbox. This is reversible."
+
+#: views/developers/addon_status.thtml:139
+#, fuzzy
+msgid "devcp_addon_status_action_nominate"
+msgstr "Nominate for Public"
+
+#: views/developers/addon_status.thtml:140
+#, fuzzy
+msgid "devcp_addon_status_action_nominate_description"
+msgstr "Nominate your add-on to become Public"
+
+#: views/developers/addon_status.thtml:147
+#, fuzzy
+msgid "devcp_addon_status_action_public"
+msgstr "Make Public"
+
+#: views/developers/addon_status.thtml:148
+#, fuzzy
+msgid "devcp_addon_status_action_public_description"
+msgstr "Make your add-on Public again."
+
+#: views/developers/addon_status.thtml:169
+#, fuzzy
+msgid "devcp_addon_status_active"
+msgstr ""
+"Your add-on is <span class=\"inactive-0\">Active</span>. This means your add-"
+"on is showing up in all available listings appropriate for its status above."
+
+#: views/developers/addon_status.thtml:111
+#, fuzzy
+msgid "devcp_addon_status_completion_disabled"
+msgstr ""
+"Please fulfill the criteria above before you can complete your add-on and "
+"move it to the <span class=\"status-1\">Sandbox</span>."
+
+#: views/developers/addon_status.thtml:108
+#, fuzzy
+msgid "devcp_addon_status_completion_enabled"
+msgstr ""
+"You may now complete your add-on and move it to the <span class=\"status-1"
+"\">Sandbox</span> by clicking the button below."
+
+#: views/developers/addon_status.thtml:102
+#, fuzzy
+msgid "devcp_addon_status_criteria_category"
+msgstr "At least one category selected"
+
+#: views/developers/addon_status.thtml:101
+#, fuzzy
+msgid "devcp_addon_status_criteria_description"
+msgstr "Add-on Description required"
+
+#: views/developers/addon_status.thtml:99
+#, fuzzy
+msgid "devcp_addon_status_criteria_name"
+msgstr "Add-on Name required"
+
+#: views/developers/addon_status.thtml:120
+#, fuzzy
+msgid "devcp_addon_status_criteria_prerelease"
+msgstr "Add-on is not marked as pre-release."
+
+#: views/developers/addon_status.thtml:119
+#, fuzzy
+msgid "devcp_addon_status_criteria_preview"
+msgstr "At least one preview image required for extensions and themes."
+
+#: views/developers/addon_status.thtml:100
+#, fuzzy
+msgid "devcp_addon_status_criteria_summary"
+msgstr "Add-on Summary required"
+
+#. %s is the status in a span, e.g. "<span>_('Public')</span>".
+#: views/developers/addon_status.thtml:58
+#, fuzzy
+msgid "devcp_addon_status_header"
+msgstr "Add-on Status: %s"
+
+#: views/developers/addon_status.thtml:152
+#: views/developers/addon_status.thtml:173
+#, fuzzy
+msgid "devcp_addon_status_header_actions"
+msgstr "Available Actions"
+
+#: views/developers/addon_status.thtml:168
+#, fuzzy
+msgid "devcp_addon_status_header_active"
+msgstr "Active Status: <span class=\"inactive-0\">Active</span>"
+
+#: views/developers/addon_status.thtml:97
+#, fuzzy
+msgid "devcp_addon_status_header_criteria"
+msgstr "Add-on Completion Criteria"
+
+#: views/developers/addon_status.thtml:164
+#, fuzzy
+msgid "devcp_addon_status_header_inactive"
+msgstr "Active Status: <span class=\"inactive-1\">Inactive</span>"
+
+#: views/developers/addon_status.thtml:117
+#, fuzzy
+msgid "devcp_addon_status_header_nomination"
+msgstr "Public Nomination Criteria"
+
+#: views/developers/addon_status.thtml:190
+#, fuzzy
+msgid "devcp_addon_status_header_trusted"
+msgstr "Trusted Status: <span class=\"status-4\">Trusted</span>"
+
+#: views/developers/addon_status.thtml:165
+#, fuzzy
+msgid "devcp_addon_status_inactive"
+msgstr ""
+"Your add-on is <span class=\"inactive-1\">Inactive</span>. This means your "
+"add-on will not show up in any listing, regardless of its status above. "
+"Updates are <b>not</b> being provided to your add-on through the update "
+"check service."
+
+#: views/developers/addon_status.thtml:128
+#, fuzzy
+msgid "devcp_addon_status_nominate_disabled"
+msgstr ""
+"Please fulfill the criteria above before nominating your add-on to become "
+"<span class=\"status-4\">Public</span>."
+
+#: views/developers/addon_status.thtml:125
+#, fuzzy
+msgid "devcp_addon_status_nominate_enabled"
+msgstr ""
+"You may now nominate your add-on for <span class=\"status-4\">Public</span> "
+"by clicking the button below."
+
+#: views/developers/addon_status.thtml:64
+#, fuzzy
+msgid "devcp_addon_status_public"
+msgstr "Public"
+
+#: views/developers/addon_status.thtml:63
+#, fuzzy
+msgid "devcp_addon_status_sandbox"
+msgstr "Sandbox"
+
+#. %s is an email address.
+#: views/developers/addon_status.thtml:89
+#, fuzzy
+msgid "devcp_addon_status_switch_disabled"
+msgstr ""
+"Your add-on was <span class=\"status-5\">Disabled</span> by an administrator "
+"and cannot be used. If you have any questions, please e-mail %s."
+
+#: views/developers/addon_status.thtml:67
+#, fuzzy
+msgid "devcp_addon_status_switch_incomplete"
+msgstr ""
+"Your add-on is currently <span class=\"status-0\">Incomplete</span>. This "
+"means your add-on is not showing up on any portion of the site or update "
+"check service. You may come to this page to complete your add-on after it "
+"meets the criteria below for completion and transfer to the <span class="
+"\"status-1\">Sandbox</span>."
+
+#. %s is a number, perhaps 42.
+#: views/developers/addon_status.thtml:77
+#, fuzzy
+msgid "devcp_addon_status_switch_nominated"
+msgstr ""
+"Your add-on is currently nominated to become <span class=\"status-4"
+"\">Public</span> and is awaiting editor review. There are currently %s other "
+"add-ons in the nomination queue."
+
+#. %s is an email address.
+#: views/developers/addon_status.thtml:81
+#, fuzzy
+msgid "devcp_addon_status_switch_pending"
+msgstr ""
+"Your add-on is pending. This shouldn't have happened. Please e-mail %s with "
+"your add-on ID and state this error."
+
+#: views/developers/addon_status.thtml:85
+#, fuzzy
+msgid "devcp_addon_status_switch_public"
+msgstr ""
+"Your add-on is <span class=\"status-4\">Public</span>, which means it will "
+"show up in all listings and searches and can be downloaded without "
+"restriction. Updates are being provided to your add-on through the update "
+"check service."
+
+#: views/developers/addon_status.thtml:71
+#: views/developers/addon_status.thtml:75
+#, fuzzy
+msgid "devcp_addon_status_switch_sandbox"
+msgstr ""
+"Your add-on is in the <span class=\"status-1\">Sandbox</span>, which means "
+"it will show up in listings and searches, but users must log in to download "
+"it. Updates are <b>not</b> being provided to your add-on through the update "
+"check service."
+
+#. %s is the add-on name.
+#: views/developers/addon_status_nominate.thtml:43
+#: views/developers/addon_status_confirm.thtml:43
+#: views/developers/addon_status.thtml:43
+#, fuzzy
+msgid "devcp_addon_status_title"
+msgstr "%s Status"
+
+#: views/developers/addon_status.thtml:191
+#, fuzzy
+msgid "devcp_addon_status_trusted"
+msgstr ""
+"Your add-on is <span class=\"status-4\">Trusted</span>. This means you can "
+"submit updates to your add-on without editor review."
+
+#: views/developers/dashboard.thtml:68
+#, fuzzy
+msgid "devcp_dashboard_active"
+msgstr "Active"
+
+#. %1$s is the add-on type string
+#. %2$s is Inactive or Active in a <span>
+#. %3$s is the addon's public status (Public, In Sandbox, ...) in a <span>
+#: views/developers/dashboard.thtml:69
+#, fuzzy
+msgid "devcp_dashboard_addontype_status"
+msgstr "%1$s currenty %2$s and %3$s"
+
+#: views/developers/dashboard.thtml:67
+#, fuzzy
+msgid "devcp_dashboard_change_status"
+msgstr "Change Status"
+
+#. %s is the addons email address.
+#: views/developers/dashboard.thtml:99
+#, fuzzy
+msgid "devcp_dashboard_disabled_questions"
+msgstr ""
+"Your add-on was disabled by an administrator and cannot be used. If you "
+"have any questions, please email %s."
+
+#. %s is the (localized) add-on status string in a span, e.g. "Disabled"
+#: views/developers/dashboard.thtml:98
+#, fuzzy
+msgid "devcp_dashboard_disabled_status"
+msgstr "Add-on Status: %s"
+
+#: views/developers/dashboard.thtml:43
+#, fuzzy
+msgid "devcp_dashboard_header_main"
+msgstr "Developer Dashboard"
+
+#: views/developers/dashboard.thtml:110
+#, fuzzy
+msgid "devcp_dashboard_header_welcome"
+msgstr "Welcome to the Developer Dashboard"
+
+#: views/developers/dashboard.thtml:68
+#, fuzzy
+msgid "devcp_dashboard_inactive"
+msgstr "Inactive"
+
+#. %s is a date in the _('date') format
+#: views/developers/dashboard.thtml:65
+#, fuzzy
+msgid "devcp_dashboard_last_edited"
+msgstr "Last edited on %s"
+
+#: views/developers/dashboard.thtml:111
+#, fuzzy
+msgid "devcp_dashboard_learn"
+msgstr ""
+"You don't currently have any add-ons hosted on Mozilla Add-ons. To learn how "
+"the process works and submit your first add-on, click Get Started below."
+
+#: views/developers/dashboard.thtml:112
+#, fuzzy
+msgid "devcp_dashboard_start"
+msgstr "Get Started"
+
+#: views/developers/dashboard.thtml:82
+#, fuzzy
+msgid "devcp_dashboard_versions"
+msgstr "Versions and Files"
+
+#: views/developers/dashboard.thtml:91
+#, fuzzy
+msgid "devcp_dashboard_versions_new"
+msgstr "Upload a new version"
+
+#. %s is the preview ID number.
+#: controllers/developers_controller.php:1415
+#, fuzzy
+msgid "devcp_delete_previews_error"
+msgstr "Preview %s could not be deleted from the database. Please try again."
+
+#. %s is the preview ID number.
+#: controllers/developers_controller.php:1413
+#, fuzzy
+msgid "devcp_delete_previews_success"
+msgstr "Preview %s has been deleted successfully."
+
+#: controllers/developers_controller.php:1089
+#, fuzzy
+msgid "devcp_delete_version_priv_error"
+msgstr "You do not have privileges to delete versions or files."
+
+#. %1$s is the count of files, a number
+#. %2$s is a status string like _('Public') or _('Incomplete')
+#: controllers/components/amo.php:549
+#, fuzzy
+msgid "devcp_describe_version_status"
+msgid_plural "devcp_describe_version_status"
+msgstr[0] "%1$s %2$s file"
+msgstr[1] "%1$s %2$s files"
+
+#. %s is a version number. Example: 3.0
+#: views/developers/versions.thtml:65
+#, php-format
+msgid "devcp_details_version"
+msgstr "버전 %s"
+
+#: views/developers/discuss.thtml:68
+#, fuzzy
+msgid "devcp_discuss_addreply_header"
+msgstr "Add Reply"
+
+#: views/developers/discuss.thtml:57
+#, fuzzy
+msgid "devcp_discuss_allreplies_header"
+msgstr "Replies"
+
+#. notice when an error occurs saving a discussion reply
+#. %1 is the email address (linked) for the amo-editors list
+#: views/developers/discuss.thtml:70
+#, fuzzy
+msgid "devcp_discuss_error_notice"
+msgstr ""
+"There was an error saving your reply. Please contact %1$s about the issue."
+
+#. %1 is the add-on name, %2 is the add-on's version number currently being reviewed by an editor
+#: views/developers/discuss.thtml:46
+#, fuzzy
+msgid "devcp_discuss_intro"
+msgstr ""
+"A Mozilla Add-ons Editor requested further information from you regarding "
+"version %2$s of your add-on %1$s."
+
+#. %1 is the add-on name
+#: views/developers/discuss.thtml:43
+#, fuzzy
+msgid "devcp_discuss_pagetitle"
+msgstr "Provide More Information For the Add-on Review of %1$s"
+
+#. submit button text
+#: views/developers/discuss.thtml:79
+#, fuzzy
+msgid "devcp_discuss_submit_reply"
+msgstr "Submit Reply"
+
+#: views/developers/discuss.thtml:72
+#, fuzzy
+msgid "devcp_discuss_success_message"
+msgstr ""
+"Your reply was successfully saved. The other participants of the discussion "
+"will be notified by email."
+
+#. in an author/editor discussion about an add-on to be reviewed:
+#. %1 is the commenter's user name (linked).
+#. %2 is the full date the comment was made.
+#: views/developers/discuss.thtml:52 views/developers/discuss.thtml:62
+#, fuzzy
+msgid "devcp_discuss_writtenby"
+msgstr "written by %1$s on %2$s"
+
+#: views/developers/addon_edit_authors.thtml:72
+#: views/developers/addon_edit_authors.thtml:81
+#, fuzzy
+msgid "devcp_edit_authors_add_author"
+msgstr "Add New Author"
+
+#: views/developers/addon_edit_authors.thtml:96
+#, fuzzy
+msgid "devcp_edit_authors_add_author_button"
+msgstr "Add Author"
+
+#: views/developers/addon_edit_authors.thtml:83
+#, fuzzy
+msgid "devcp_edit_authors_add_email"
+msgstr "Author Account Email:"
+
+#: views/developers/addon_edit_authors.thtml:98
+#, fuzzy
+msgid "devcp_edit_authors_add_loading"
+msgstr "Checking account email..."
+
+#: views/developers/addon_edit_authors.thtml:70
+#, fuzzy
+msgid "devcp_edit_authors_click_save"
+msgstr "Click the Update Authors button below to save."
+
+#: views/developers/addon_edit_authors.thtml:58
+#, fuzzy
+msgid "devcp_edit_authors_header_current"
+msgstr "Current Authors"
+
+#: views/developers/addon_edit_authors.thtml:50
+#, fuzzy
+msgid "devcp_edit_authors_header_manage"
+msgstr "Manage Add-on Authors"
+
+#: views/developers/addon_edit_authors.thtml:93
+#, fuzzy
+msgid "devcp_edit_authors_label_add_listed"
+msgstr "List as author in pubilc display pages"
+
+#: views/developers/addon_edit_authors.thtml:89
+#, fuzzy
+msgid "devcp_edit_authors_label_developer"
+msgstr ""
+"<strong>Developer</strong> - Can manage all aspects of the add-on listing, "
+"except for adding and removing other authors."
+
+#: views/developers/addon_edit_authors.thtml:88
+#, fuzzy
+msgid "devcp_edit_authors_label_owner"
+msgstr ""
+"<strong>Owner</strong> - Can manage all aspects of the add-on listing, "
+"including adding and removing other authors."
+
+#: views/developers/addon_edit_authors.thtml:90
+#, fuzzy
+msgid "devcp_edit_authors_label_viewer"
+msgstr ""
+"<strong>Viewer</strong> - Can view add-on developer listing and statistics, "
+"but can't make any changes."
+
+#. Placeholder for the empty option in a <select>.
+#: views/developers/addon_edit_categories.thtml:69
+#, fuzzy
+msgid "devcp_edit_authors_option_empty"
+msgstr "----------------"
+
+#: views/developers/addon_edit_authors.thtml:86
+#, fuzzy
+msgid "devcp_edit_authors_select_role"
+msgstr "Select a role for the author:"
+
+#. Column name in a table.
+#: views/developers/addon_edit_authors.thtml:62
+#, fuzzy
+msgid "devcp_edit_authors_th_author"
+msgstr "Author"
+
+#. Column name in a table.
+#: views/developers/addon_edit_authors.thtml:64
+#, fuzzy
+msgid "devcp_edit_authors_th_listed"
+msgstr "Listed"
+
+#. Column name in a table.
+#: views/developers/addon_edit_authors.thtml:63
+#, fuzzy
+msgid "devcp_edit_authors_th_role"
+msgstr "Role"
+
+#: views/developers/addon_edit_authors.thtml:77
+#, fuzzy
+msgid "devcp_edit_authors_update_author"
+msgstr "Update authors"
+
+#: views/developers/addon_edit_categories.thtml:99
+#, fuzzy
+msgid "devcp_edit_categories_button_update"
+msgstr "Update Categories"
+
+#: views/developers/addon_edit_categories.thtml:88
+#, fuzzy
+msgid "devcp_edit_categories_does_not_fit"
+msgstr "My add-on doesn't fit into any available categories."
+
+#. %s is the application name (Firefox, Thunderbird).
+#: views/developers/addon_edit_categories.thtml:61
+#, fuzzy
+msgid "devcp_edit_categories_header_application"
+msgstr "%s Categories"
+
+#: views/developers/addon_edit_categories.thtml:49
+#, fuzzy
+msgid "devcp_edit_categories_header_manage"
+msgstr "Manage Add-on Categories"
+
+#: views/developers/addon_edit_categories.thtml:91
+#, fuzzy
+msgid "devcp_edit_categories_hover"
+msgstr "Hover over a category to see its description."
+
+#. %s is the category number (1, 2, 3).
+#: views/developers/addon_edit_categories.thtml:67
+#, fuzzy
+msgid "devcp_edit_categories_label_category_num"
+msgstr "Category %s"
+
+#: views/developers/addon_edit_categories.thtml:94
+#: views/developers/addon_edit_categories.thtml:103
+#, fuzzy
+msgid "devcp_edit_categories_none_available"
+msgstr "No categories are available for this add-on type and application."
+
+#: views/developers/addon_edit_categories.thtml:86
+#, fuzzy
+msgid "devcp_edit_categories_other"
+msgstr ""
+"Place your add-on into this category only if it does not fit into any other "
+"available categories."
+
+#. %s is the application name (Firefox, Thunderbird).
+#: views/developers/addon_edit_categories.thtml:63
+#, fuzzy
+msgid "devcp_edit_categories_select_application_categories"
+msgstr "Select up to three %s categories for your add-on"
+
+#: views/developers/addon_edit.thtml:47
+#, fuzzy
+msgid "devcp_edit_dd_manage_authors"
+msgstr "Add or remove users that can manage this add-on."
+
+#: views/developers/addon_edit.thtml:49
+#, fuzzy
+msgid "devcp_edit_dd_manage_categories"
+msgstr ""
+"Select the relevant categories for each application your add-on supports."
+
+#: views/developers/addon_edit.thtml:51
+#, fuzzy
+msgid "devcp_edit_dd_manage_description"
+msgstr ""
+"Add and modify translations for your add-on's summary, description, end-user "
+"license, and privacy policy."
+
+#: views/developers/addon_edit.thtml:53
+#, fuzzy
+msgid "devcp_edit_dd_manage_properties"
+msgstr "Change your add-on's name, homepage, icon, and other flags."
+
+#: views/developers/addon_edit_descriptions.thtml:116
+#, fuzzy
+msgid "devcp_edit_description_button_update"
+msgstr "Update Descriptions"
+
+#: views/developers/addon_edit_descriptions.thtml:115
+#, fuzzy
+msgid "devcp_edit_description_correct_error"
+msgstr "Please correct the errors above indicated in red."
+
+#: views/developers/addon_edit_descriptions.thtml:51
+#, fuzzy
+msgid "devcp_edit_descriptions_header"
+msgstr "Edit Add-on Descriptions"
+
+#: views/developers/addon_edit_descriptions.thtml:94
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_comments_description"
+msgstr ""
+"Any information end users may want to know that isn't necessarily applicable "
+"to the add-on summary or description. Common uses include listing known "
+"major bugs, information on how to report bugs, anticipated release date of a "
+"new version, etc."
+
+#: views/developers/addon_edit_descriptions.thtml:93
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_comments_name"
+msgstr "Developer Comments"
+
+#: views/developers/addon_edit_descriptions.thtml:86
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_description_description"
+msgstr ""
+"The description of your add-on is a longer explanation of features, "
+"functionality, and other relevant information. It is displayed under the "
+"summary on the add-on's display page."
+
+#: views/developers/addon_edit_descriptions.thtml:85
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_description_name"
+msgstr "Add-on Description"
+
+#: views/developers/addon_edit_descriptions.thtml:103
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_eula_description"
+msgstr ""
+"If your add-on has an End-User License Agreement (EULA), please enter its "
+"text below. If set below, users will be required to agree to this before "
+"installing your add-on. Please note that a EULA is not the same as a code "
+"license such as GPL or MPL."
+
+#: views/developers/addon_edit_descriptions.thtml:102
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_eula_name"
+msgstr "End-User License Agreement"
+
+#: views/developers/addon_edit_descriptions.thtml:112
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_privacy_description"
+msgstr ""
+"If your add-on has a privacy policy, enter its text here. Your add-on's "
+"display page will display a link to the policy."
+
+#: views/developers/addon_edit_descriptions.thtml:111
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_privacy_name"
+msgstr "Privacy Policy"
+
+#: views/developers/addon_edit_descriptions.thtml:78
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_summary_description"
+msgstr ""
+"The summary is a short explanation of your add-on's basic functionality that "
+"is displayed in search and browse listings, as well as at the top of your "
+"add-on's display page. <strong>Limit of 250 characters.</strong>"
+
+#: views/developers/addon_edit_descriptions.thtml:77
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_summary_name"
+msgstr "Add-on Summary"
+
+#: views/developers/addon_edit.thtml:46
+#, fuzzy
+msgid "devcp_edit_dt_manage_authors"
+msgstr "Manage Add-on Authors"
+
+#: views/developers/addon_edit.thtml:48
+#, fuzzy
+msgid "devcp_edit_dt_manage_categories"
+msgstr "Manage Add-on Categories"
+
+#: views/developers/addon_edit.thtml:50
+#, fuzzy
+msgid "devcp_edit_dt_manage_descriptions"
+msgstr "Manage Add-on Descriptions"
+
+#: views/developers/addon_edit.thtml:52
+#, fuzzy
+msgid "devcp_edit_dt_manage_properties"
+msgstr "Manage Add-on Properties"
+
+#: views/developers/addon_edit_properties.thtml:170
+msgid "devcp_edit_label_externalsoftware"
+msgstr "ì´ ë¶€ê°€ ê¸°ëŠ¥ì€ ì™¸ë¶€ í”„ë¡œê·¸ëž¨ì´ í•„ìš”í•©ë‹ˆë‹¤."
+
+#: views/developers/addon_edit_properties.thtml:205
+msgid "devcp_edit_label_locale_disambiguation"
+msgstr "부가 언어 정보"
+
+#: views/developers/addon_edit_properties.thtml:168
+msgid "devcp_edit_label_prerelease"
+msgstr "출시 전"
+
+#: views/developers/addon_edit_properties.thtml:169
+msgid "devcp_edit_label_sitespecific"
+msgstr "사ì´íŠ¸ 기반 부가 기능"
+
+#: views/developers/addon_edit_properties.thtml:202
+msgid "devcp_edit_label_target_locale"
+msgstr "기본 언어"
+
+#: views/developers/addon_edit_properties.thtml:212
+#, fuzzy
+msgid "devcp_edit_properties_button_update"
+msgstr "Update Properties"
+
+#: views/developers/addon_edit_properties.thtml:198
+#, fuzzy
+msgid "devcp_edit_properties_change_guid"
+msgstr "Only change if you understand all of the consequences."
+
+#: views/developers/addon_edit_properties.thtml:109
+#, fuzzy
+msgid "devcp_edit_properties_current_icon"
+msgstr "Current Icon"
+
+#: views/developers/addon_edit_properties.thtml:85
+#, fuzzy
+msgid "devcp_edit_properties_default_locale"
+msgstr ""
+"An add-on's default locale is the main locale in which translations must be "
+"present. If translations for your add-on's descriptions are unavailable in a "
+"user's selected language, they will fall back to this default locale."
+
+#: views/developers/addon_edit_properties.thtml:167
+#, fuzzy
+msgid "devcp_edit_properties_flags"
+msgstr "These flags are used to filter and classify add-ons."
+
+#: views/developers/addon_edit_properties.thtml:174
+#, fuzzy
+msgid "devcp_edit_properties_guid"
+msgstr ""
+"The GUID of your add-on is specified in its install.rdf and uniquely "
+"identifies it. You cannot change your GUID once it is listed on Mozilla Add-"
+"ons."
+
+#: views/developers/addon_edit_properties.thtml:53
+#, fuzzy
+msgid "devcp_edit_properties_header"
+msgstr "Edit Add-on Properties"
+
+#: views/developers/addon_edit_properties.thtml:186
+#, fuzzy
+msgid "devcp_edit_properties_header_addon_type"
+msgstr "Add-on Type"
+
+#: views/developers/addon_edit_properties.thtml:181
+#, fuzzy
+msgid "devcp_edit_properties_header_admin_settings"
+msgstr "Admin Settings"
+
+#: views/developers/addon_edit_properties.thtml:84
+#, fuzzy
+msgid "devcp_edit_properties_header_default_locale"
+msgstr "Default Locale"
+
+#: views/developers/addon_edit_properties.thtml:166
+#, fuzzy
+msgid "devcp_edit_properties_header_flags"
+msgstr "Add-on Flags"
+
+#: views/developers/addon_edit_properties.thtml:173
+#: views/developers/addon_edit_properties.thtml:197
+#, fuzzy
+msgid "devcp_edit_properties_header_guid"
+msgstr "Add-on GUID"
+
+#: views/developers/addon_edit_properties.thtml:104
+#, fuzzy
+msgid "devcp_edit_properties_header_icon"
+msgstr "Add-on Icon"
+
+#: views/developers/addon_edit_properties.thtml:159
+#, fuzzy
+msgid "devcp_edit_properties_header_other_settings"
+msgstr "Other Settings"
+
+#. A header on the admin page to toggle trusted status.
+#: views/developers/addon_edit_properties.thtml:182
+#, fuzzy
+msgid "devcp_edit_properties_header_trusted"
+msgstr "Trusted Add-on?"
+
+#: views/developers/addon_edit_properties.thtml:160
+#, fuzzy
+msgid "devcp_edit_properties_header_view_source"
+msgstr "View Source Online"
+
+#. %s is a comma-separated list of image extensions ".png, .jpg"
+#: views/developers/addon_edit_properties.thtml:106
+#, fuzzy
+msgid "devcp_edit_properties_icon"
+msgstr ""
+"The add-on icon is a small image that is displayed next to your add-on's "
+"name in browse and search results, display pages, and in the add-on "
+"installation dialog. The image will automatically be resized to 32 x 32 "
+"pixels. Please use one of the following image types: %s"
+
+#: views/developers/addon_edit_properties.thtml:171
+#, fuzzy
+msgid "devcp_edit_properties_label_binary"
+msgstr "This add-on contains binary components"
+
+#: views/developers/addon_edit_properties.thtml:185
+#, fuzzy
+msgid "devcp_edit_properties_label_not_trusted"
+msgstr "Not Trusted"
+
+#: views/developers/addon_edit_properties.thtml:184
+#, fuzzy
+msgid "devcp_edit_properties_label_trusted"
+msgstr "Trusted"
+
+#: views/developers/addon_edit_properties.thtml:110
+#, fuzzy
+msgid "devcp_edit_properties_new_icon"
+msgstr "New Icon"
+
+#: views/developers/addon_edit_properties.thtml:118
+#, fuzzy
+msgid "devcp_edit_properties_remove_icon"
+msgstr "Remove Icon"
+
+#: views/developers/addon_edit_properties.thtml:136
+#, fuzzy
+msgid "devcp_edit_properties_transbox_homepage_description"
+msgstr ""
+"If your add-on has another homepage, enter its address here. Adding other "
+"translations is not necessary unless your website is localized into other "
+"languages."
+
+#: views/developers/addon_edit_properties.thtml:135
+#, fuzzy
+msgid "devcp_edit_properties_transbox_homepage_name"
+msgstr "Add-on Homepage"
+
+#: views/developers/addon_edit_properties.thtml:79
+#, fuzzy
+msgid "devcp_edit_properties_transbox_name_description"
+msgstr "The name of your add-on is displayed everywhere your add-on is listed."
+
+#: views/developers/addon_edit_properties.thtml:78
+#, fuzzy
+msgid "devcp_edit_properties_transbox_name_name"
+msgstr "Add-on Name"
+
+#: views/developers/addon_edit_properties.thtml:145
+#, fuzzy
+msgid "devcp_edit_properties_transbox_supportemail_description"
+msgstr ""
+"If you have an email address for support inquiries, enter it here. Adding "
+"other translations is not necessary unless you have different email "
+"addresses for different languages."
+
+#: views/developers/addon_edit_properties.thtml:144
+#, fuzzy
+msgid "devcp_edit_properties_transbox_supportemail_name"
+msgstr "Support Email Address"
+
+#: views/developers/addon_edit_properties.thtml:154
+#, fuzzy
+msgid "devcp_edit_properties_transbox_supporturl_description"
+msgstr ""
+"If your add-on has a support website or forum, enter its address here. "
+"Adding other translations is not necessary unless your website is localized "
+"into other languages."
+
+#: views/developers/addon_edit_properties.thtml:153
+#, fuzzy
+msgid "devcp_edit_properties_transbox_supporturl_name"
+msgstr "Support Website"
+
+#: views/developers/addon_edit_properties.thtml:183
+#, fuzzy
+msgid "devcp_edit_properties_trusted"
+msgstr "Trusted add-ons can become public without Editor review."
+
+#. %s is href="..." and should stay in the <a> tag.
+#: views/developers/addon_edit_properties.thtml:119
+#, fuzzy
+msgid "devcp_edit_properties_undelete"
+msgstr "Icon will be deleted on save. <a %s>Cancel?</a>"
+
+#: views/developers/addon_edit_properties.thtml:161
+#, fuzzy
+msgid "devcp_edit_properties_view_source"
+msgstr ""
+"The source of your add-on files can be viewed online by any logged in user "
+"if you wish."
+
+#: views/developers/addon_edit_properties.thtml:162
+#, fuzzy
+msgid "devcp_edit_properties_view_source_allow"
+msgstr "Allow online source viewing"
+
+#: views/developers/addon_edit_properties.thtml:163
+#, fuzzy
+msgid "devcp_edit_properties_view_source_do_not_allow"
+msgstr "Do not allow online source viewing"
+
+#: views/elements/developers/editbox.thtml:46
+#, fuzzy
+msgid "devcp_editbox_authors"
+msgstr "Authors"
+
+#: views/elements/developers/editbox.thtml:47
+#, fuzzy
+msgid "devcp_editbox_categories"
+msgstr "Categories"
+
+#: views/elements/developers/editbox.thtml:52
+#, fuzzy
+msgid "devcp_editbox_change_status"
+msgstr "Change Status"
+
+#: views/elements/developers/editbox.thtml:48
+#, fuzzy
+msgid "devcp_editbox_descriptions"
+msgstr "Descriptions"
+
+#: views/elements/developers/editbox.thtml:43
+#, fuzzy
+msgid "devcp_editbox_edit_addon"
+msgstr "Edit Add-on"
+
+#: views/elements/developers/editbox.thtml:57
+#, fuzzy
+msgid "devcp_editbox_new_version"
+msgstr "New Version"
+
+#: views/elements/developers/editbox.thtml:49
+#, fuzzy
+msgid "devcp_editbox_properties"
+msgstr "Properties"
+
+#: views/elements/developers/editbox.thtml:60
+#, fuzzy
+msgid "devcp_editbox_screenshots"
+msgstr "Preview Screenshots"
+
+#: views/elements/developers/editbox.thtml:53
+#, fuzzy
+msgid "devcp_editbox_statistics_dashboard"
+msgstr "Statistics Dashboard"
+
+#: views/elements/developers/editbox.thtml:54
+#, fuzzy
+msgid "devcp_editbox_versions"
+msgstr "Versions and Files"
+
+#: views/elements/developers/editbox.thtml:42
+#, fuzzy
+msgid "devcp_editbox_view_listing"
+msgstr "View Listing"
+
+#: views/elements/developers/editorsmenu.thtml:59
+msgid "devcp_editorsqueue_featured"
+msgstr "추천 부가 기능"
+
+# %1 is the review count
+#. %1 is the review count
+#: views/elements/developers/editorsqueue.thtml:42
+#: views/elements/developers/editorsmenu.thtml:56
+#, php-format
+msgid "devcp_editorsqueue_moderatedreviews"
+msgid_plural "devcp_editorsqueue_moderatedreviews"
+msgstr[0] "í‰ê°€ 확ì¸"
+msgstr[1] "í‰ê°€ í™•ì¸ (%sê°œ)"
+
+# %1 is the nominated addons count
+#. %1 is the nominated addons count
+#: views/elements/developers/editorsqueue.thtml:44
+#: views/elements/developers/editorsmenu.thtml:58
+#, php-format
+msgid "devcp_editorsqueue_nominated"
+msgid_plural "devcp_editorsqueue_nominated"
+msgstr[0] "추천 부가 정보 (1개)"
+msgstr[1] "추천 부가 정보 (%s개)"
+
+# %1 is the update count
+#. %1 is the update count
+#: views/elements/developers/editorsqueue.thtml:43
+#: views/elements/developers/editorsmenu.thtml:57
+#, php-format
+msgid "devcp_editorsqueue_pendingupdates"
+msgid_plural "devcp_editorsqueue_pendingupdates"
+msgstr[0] "ì—…ë°ì´íŠ¸ 대기 (1ê°œ)"
+msgstr[1] "ì—…ë°ì´íŠ¸ 대기 갯수 (%sê°œ)"
+
+#: controllers/statistics_controller.php:147
+#: controllers/statistics_controller.php:361
+#: controllers/previews_controller.php:108
+#: controllers/previews_controller.php:211
+#: controllers/previews_controller.php:312
+msgid "devcp_error_addon_access_denied"
+msgstr "ì´ ë¶€ê°€ ê¸°ëŠ¥ì— ì ‘ê·¼í•  수 없습니다."
+
+#. %s is a complete URL with the text from devcp_error_appversion_reference_link_text
+#. in the <a> tag. This should be fixed.
+#: controllers/components/developers.php:591
+#, php-format
+msgid "devcp_error_appversion_reference_link"
+msgstr "참고 ìžë£ŒëŠ” %s를 보십시오."
+
+#. This is the link text in the <a> for devcp_error_appversion_reference_link. This
+#. should be fixed.
+#: controllers/components/developers.php:591
+msgid "devcp_error_appversion_reference_link_text"
+msgstr "현재 페ì´ì§€"
+
+#: views/developers/addon_edit_authors.thtml:76
+#, fuzzy
+msgid "devcp_error_empty_authors"
+msgstr "Your add-on must have at least one owner."
+
+#. %1$s is the name of the file
+#: controllers/components/developers.php:658
+#, fuzzy
+msgid "devcp_error_file_exists"
+msgstr ""
+"A version of that addon already exists. To replace it, you must delete the "
+"file %1$s first."
+
+#. %1$s is a file extension. Example: .exe
+#. %2$s is a comma separated list of extensions. Example: .xpi, .jar
+#: controllers/components/developers.php:355
+#, php-format
+msgid "devcp_error_file_extension"
+msgstr ""
+"ì´ íŒŒì¼ í™•ìž¥ìžëŠ”(%s)는 부가 ê¸°ëŠ¥ì— ì‚¬ìš©í•  수 없습니다. 아래 중 하나를 사용하"
+"세요: %s"
+
+#: controllers/components/developers.php:64
+msgid "devcp_error_five_categories"
+msgstr "5ê°œ ì´ìƒ 분류를 ì„ íƒí•  수 없습니다."
+
+#: controllers/components/developers.php:526
+msgid "devcp_error_guid_application"
+msgstr "ì´ ID는 다른 부가 기능ì—ì„œ ì´ë¯¸ 사용하고 있습니다."
+
+#: controllers/components/developers.php:337
+#: controllers/components/developers.php:389
+msgid "devcp_error_http_incomplete"
+msgstr "ì´ì „ 불완전"
+
+#: controllers/components/developers.php:335
+#: controllers/components/developers.php:336
+#: controllers/components/developers.php:387
+#: controllers/components/developers.php:388
+msgid "devcp_error_http_maxupload"
+msgstr "최대 업로드 íŒŒì¼ í¬ê¸° 초과"
+
+#: controllers/components/developers.php:338
+#: controllers/components/developers.php:390
+msgid "devcp_error_http_nofile"
+msgstr "업로드 파ì¼ì´ ì—†ìŒ"
+
+#. %1$s is a file extension. Example: .exe
+#. %2$s is a comma separated list of extensions. Example: .xpi, .jar
+#: controllers/components/developers.php:401
+#, php-format
+msgid "devcp_error_icon_extension"
+msgstr ""
+"ì´ íŒŒì¼ í™•ìž¥ìž(%s)는 ì•„ì´ì½˜ì— 사용할 수 없습니다. 아래 중 하나를 사용하세요: "
+"%s"
+
+#: controllers/developers_controller.php:504
+msgid "devcp_error_index_rdf_notfound"
+msgstr "install.rdf가 업습니다."
+
+#: controllers/components/developers.php:601
+msgid "devcp_error_install_manifest"
+msgstr "부가 기능 내 install.rdf가 없습니다:"
+
+#: controllers/developers_controller.php:1463
+msgid "devcp_error_invalid_addontype"
+msgstr "부가 기능 형ì‹ì„ ì„ íƒí•´ 주십시오."
+
+#. %$1s is a version. Example: 3.1.1
+#. %$2s is an add-on name.
+#: controllers/components/developers.php:569
+#: controllers/components/developers.php:581
+#, php-format
+msgid "devcp_error_invalid_appversion"
+msgstr "%sì€ %sì— ëŒ€í•œ 유효한 ë²„ì „ì´ ì•„ë‹™ë‹ˆë‹¤."
+
+#. %s is a string
+#: controllers/components/developers.php:521
+#, php-format
+msgid "devcp_error_invalid_guid"
+msgstr "부가 ê¸°ëŠ¥ì˜ IDê°€ 유효하지 않습니다: %s"
+
+#. %$1s is a version. Example: 3.1.1
+#. %$2s is an add-on name.
+#: controllers/components/developers.php:572
+#, php-format
+msgid "devcp_error_invalid_minversion"
+msgstr ""
+"%sì€ %sì— ëŒ€í•œ 유효한 ë²„ì „ì´ ì•„ë‹™ë‹ˆë‹¤: 최소 ë²„ì „ì€ *를 í¬í•¨í•  수 없습니다."
+
+#: controllers/components/developers.php:536
+msgid "devcp_error_invalid_version"
+msgstr ""
+"ì´ ë¶€ê°€ ê¸°ëŠ¥ì˜ ë²„ì „ì€ ìœ íš¨í•˜ì§€ 않습니다: </a><a href=\"http://developer."
+"mozilla.org/ko/docs/Toolkit_version_format\">버전 명세</a>를 참고하세요."
+
+#: controllers/components/developers.php:531
+msgid "devcp_error_invalid_version_spaces"
+msgstr ""
+"ì´ ë¶€ê°€ 기능 ë²„ì „ì€ ìœ íš¨í•˜ì§€ 않습니다: ë²„ì „ì— ê³µë°±ì„ í¬í•¨í•´ì„œëŠ” 안ë©ë‹ˆë‹¤."
+
+#. %s is an error message from the parser.
+#: controllers/components/developers.php:501
+#, php-format
+msgid "devcp_error_manifest_parse"
+msgstr "install.rdfì—ì„œ 정보를 ì¶”ì¶œí•˜ëŠ”ë° ì˜¤ë¥˜ê°€ ë°œìƒí–ˆìŠµë‹ˆë‹¤: %s"
+
+#: controllers/components/developers.php:373
+msgid "devcp_error_move_file"
+msgstr "ì´ë™í•  수 ì—†ìŒ"
+
+#. %s is the name of a file
+#: controllers/components/developers.php:650
+#: controllers/components/developers.php:662
+#: controllers/components/developers.php:667
+#: controllers/components/developers.php:727
+#: controllers/components/developers.php:738
+#: controllers/components/developers.php:743
+#, php-format
+msgid "devcp_error_moving_file"
+msgstr "%sì„ ì´ë™í•˜ëŠ” 중 오류가 ë°œìƒí–ˆìŠµë‹ˆë‹¤."
+
+#: controllers/components/developers.php:595
+msgid "devcp_error_mozilla_application"
+msgstr "ì ì–´ë„ 하나 ì´ìƒì˜ ì´ìš© 가능한 Mozilla 애플리케ì´ì…˜ì„ 설정해야 합니다."
+
+#: controllers/components/developers.php:516
+msgid "devcp_error_no_guid"
+msgstr "부가 ê¸°ëŠ¥ì˜ install.rdfì—ì„œ ID를 ì°¾ì„ ìˆ˜ 없습니다."
+
+#: controllers/components/developers.php:287
+msgid "devcp_error_no_platform"
+msgstr "플랫í¼ì„ ì„ íƒí•˜ì§€ ì•ŠìŒ"
+
+#: controllers/components/developers.php:59
+msgid "devcp_error_one_category"
+msgstr "하나 ì´ìƒì˜ 분류를 ì„ íƒí•˜ì„¸ìš”."
+
+#: controllers/components/developers.php:92
+msgid "devcp_error_one_user"
+msgstr "부가 기능 ê°œë°œìž ì •ë³´ë¥¼ 한명 ì´ìƒ 입력해야 합니다."
+
+#. %1$s is a file extension. Example: .exe
+#. %2$s is a comma separated list of extensions. Example: .xpi, .jar
+#: controllers/components/developers.php:1081
+#, php-format
+msgid "devcp_error_preview_extension"
+msgstr ""
+"ì´ íŒŒì¼ í™•ìž¥ìž (%s)는 미리 ë³´ê¸°ì— ì‚¬ìš©í•  수 없습니다. 아래 중 하나를 ì„ íƒí•˜ì„¸"
+"ìš”: %s"
+
+#: controllers/components/developers.php:511
+msgid "devcp_error_updatekey"
+msgstr ""
+"부가 기능ì—ì„œ updateKey를 사용할 수 없습니다. install.rdfì—ì„œ 삭제해 주십시"
+"오."
+
+#: controllers/components/developers.php:506
+msgid "devcp_error_updateurl"
+msgstr ""
+"부가 ê¸°ëŠ¥ì— ì™¸ë¶€ updateURLì„ ì‚¬ìš©í•´ì„œëŠ” 안ë©ë‹ˆë‹¤. install.rdfì—ì„œ 지운 후 다"
+"ì‹œ ì‹œë„í•´ 주세요."
+
+#: controllers/developers_controller.php:465
+#: controllers/components/developers.php:271
+msgid "devcp_error_upload_file"
+msgstr "파ì¼ì„ 업로드 í•´ 주십시오."
+
+#: views/developers/uploader.thtml:135
+#, fuzzy
+msgid "devcp_input_upload_file"
+msgstr "Upload File"
+
+#: views/pages/js_constants.js.thtml:89
+#, fuzzy
+msgid "devcp_js_a_cancel"
+msgstr "Cancel"
+
+#: views/pages/js_constants.js.thtml:90
+#, fuzzy
+msgid "devcp_js_add_email"
+msgstr "Please enter the account email of the author you wish to add."
+
+#. alt text for a down-arrow image.
+#: views/pages/js_constants.js.thtml:81
+#, fuzzy
+msgid "devcp_js_img_move_down"
+msgstr "Move Down"
+
+#. alt text for an up-arrow image.
+#: views/pages/js_constants.js.thtml:82
+#, fuzzy
+msgid "devcp_js_img_move_up"
+msgstr "Move Up"
+
+#: views/pages/js_constants.js.thtml:91
+#, fuzzy
+msgid "devcp_js_img_remove_compat"
+msgstr "Remove Application Compatibility"
+
+#: views/pages/js_constants.js.thtml:86
+#, fuzzy
+msgid "devcp_js_input_list_author"
+msgstr "List as author in public listings"
+
+#: views/pages/js_constants.js.thtml:92
+#, fuzzy
+msgid "devcp_js_license_select"
+msgstr "Please select a license."
+
+#: views/pages/js_constants.js.thtml:93
+#, fuzzy
+msgid "devcp_js_license_text"
+msgstr "Please enter text for your license."
+
+#. <option> text in a <select> for Author role in an add-on.
+#: views/pages/js_constants.js.thtml:84
+#, fuzzy
+msgid "devcp_js_option_developer"
+msgstr "Developer"
+
+#. <option> text in a <select> for Author role in an add-on.
+#: views/pages/js_constants.js.thtml:83
+#, fuzzy
+msgid "devcp_js_option_owner"
+msgstr "Owner"
+
+#. <option> text in a <select> for Author role in an add-on.
+#: views/pages/js_constants.js.thtml:85
+#, fuzzy
+msgid "devcp_js_option_viewer"
+msgstr "Viewer"
+
+#: views/pages/js_constants.js.thtml:88
+#, fuzzy
+msgid "devcp_js_remove_author"
+msgstr "Remove Author"
+
+#: views/pages/js_constants.js.thtml:87
+#, fuzzy
+msgid "devcp_js_sure_remove"
+msgstr "Are you <strong>sure</strong> you wish to remove this author?"
+
+#: views/pages/js_constants.js.thtml:77
+#, fuzzy
+msgid "devcp_js_upload_alert"
+msgstr "You must select a file to upload."
+
+#. %1$s is an addon id, like 32.
+#. %2$s is a version number, like 3.5.
+#: controllers/components/developers.php:1212
+#, fuzzy
+msgid "devcp_license_existing"
+msgstr "Custom license for add-on %1$s v%2$s"
+
+#: views/elements/developers/localebox.thtml:44
+msgid "devcp_localebox_header_localizedfields"
+msgstr "번역 항목"
+
+# %1 is the default locale
+#. %1 is the default locale
+#: views/elements/developers/localebox.thtml:48
+#, php-format
+msgid "devcp_localebox_intro"
+msgstr ""
+"ì´ íŽ˜ì´ì§€ ë‚´ 특정 í•­ëª©ë“¤ì€ ì‚¬ìš©ìžê°€ ìžì‹ ì˜ 언어로 ì ‘ì†í•  경우 ë²ˆì—­ëœ ìžë£Œë“¤"
+"ì´ ë³´ì´ê²Œ ë©ë‹ˆë‹¤. 부가 기능ì—ì„œ 제공할 언어별 소개 ë‚´ìš©ì„ íŽ¸ì§‘í•˜ì‹œê¸° ë°”ëžë‹ˆ"
+"다. 만약 해당 ì–¸ì–´ë¡œëœ ì†Œê°œ ìžë£Œê°€ 없는 경우 기본 언어 설정(%s)ì˜ ì†Œê°œ ë‚´ìš©"
+"ì´ ë‚˜íƒ€ë‚©ë‹ˆë‹¤."
+
+#: views/elements/developers/sidebar.thtml:68
+#: views/elements/developers/myaddons.thtml:75
+msgid "devcp_myaddons_admincp_link"
+msgstr "ê´€ë¦¬ìž ì œì–´íŒ"
+
+#: views/elements/developers/sidebar.thtml:65
+#: views/elements/developers/myaddons.thtml:72
+msgid "devcp_myaddons_editorcp_link"
+msgstr "íŽ¸ì§‘ìž ì œì–´íŒ"
+
+#: views/elements/developers/myaddons.thtml:52
+msgid "devcp_myaddons_link"
+msgstr "ë‚˜ì˜ ë¶€ê°€ 기능"
+
+#: views/elements/developers/sidebar.thtml:70
+#: views/elements/developers/myaddons.thtml:77
+msgid "devcp_myaddons_mainpage_link"
+msgstr "첫화면으로 ëŒì•„가기"
+
+#: views/elements/developers/sidebar.thtml:63
+#: views/elements/developers/myaddons.thtml:70
+msgid "devcp_myaddons_statistics_link"
+msgstr "통계 대시보드"
+
+#: views/elements/developers/sidebar.thtml:62
+#: views/elements/developers/myaddons.thtml:69
+msgid "devcp_myaddons_submitaddon_link"
+msgstr "부가 기능 제출"
+
+#: views/elements/developers/sidebar.thtml:48
+#: views/elements/developers/myaddons.thtml:67
+msgid "devcp_myaddons_title"
+msgstr "ê°œë°œìž ë„구"
+
+#. %1$s is an add-on ID, perhaps 167.
+#. %2$s is a URL.
+#: controllers/developers_controller.php:256
+#, fuzzy
+msgid "devcp_new_addon_error"
+msgstr ""
+"This add-on ID (%1$s) already exists in the database. If this is your add-"
+"on, you can <a href=\"%2$s\">upload a new version</a>."
+
+#: views/developers/addon_status_nominate.thtml:62
+#, fuzzy
+msgid "devcp_nominate_cancel"
+msgstr "Cancel and return"
+
+# %1 is the addon name
+#. %1 is the add-on name
+#: views/developers/addon_status_nominate.thtml:61
+#, php-format
+msgid "devcp_nominate_submit_nominate"
+msgstr "%s 추천"
+
+#: views/developers/addon_edit_properties.thtml:50
+#: views/developers/addon_status.thtml:49
+#: views/developers/versions_edit.thtml:50
+#, fuzzy
+msgid "devcp_notice_changes_error"
+msgstr ""
+"<span>One or more of your changes couldn't be saved.</span><br />Please look "
+"for the errors below. The rest of your changes were successfully saved."
+
+#: views/developers/addon_edit_authors.thtml:47
+#: views/developers/addon_edit_properties.thtml:47
+#: views/developers/addon_status.thtml:46
+#: views/developers/addon_edit_descriptions.thtml:47
+#: views/developers/versions_edit.thtml:47
+#: views/developers/addon_edit_categories.thtml:46
+#, fuzzy
+msgid "devcp_notice_changes_saved"
+msgstr ""
+"<span>Your changes have been saved.</span><br />Please note that some "
+"changes may take several hours to appear in all areas of the website."
+
+#: controllers/previews_controller.php:252
+msgid "devcp_notice_cleardefault"
+msgstr ""
+"현재 미리 보기 기본 ì„¤ì •ì„ ì œê±°í•˜ë©´ 다른 미리 보기 ê·¸ë¦¼ì´ ìžë™ì ìœ¼ë¡œ 기본 설"
+"ì • ë©ë‹ˆë‹¤."
+
+#: controllers/previews_controller.php:184
+#: controllers/previews_controller.php:251
+msgid "devcp_notice_makedefault"
+msgstr ""
+"현재 ê·¸ë¦¼ì„ ë¯¸ë¦¬ 보기 기본 설정으로 하면 ì›ëž˜ 미리 보기 ê·¸ë¦¼ì´ ìžë™ì ìœ¼ë¡œ 사"
+"ìš© 정지 ë©ë‹ˆë‹¤."
+
+#: views/developers/addon_edit_authors.thtml:70
+#, fuzzy
+msgid "devcp_notice_unsaved_changes"
+msgstr "You have unsaved changes."
+
+#: controllers/developers_controller.php:87
+#: controllers/developers_controller.php:97
+#: controllers/developers_controller.php:100
+#: controllers/previews_controller.php:67
+#: controllers/previews_controller.php:79
+#: controllers/previews_controller.php:82
+msgid "devcp_pagetitle"
+msgstr "ê°œë°œìž ì œì–´íŒ"
+
+#: controllers/previews_controller.php:103
+#: controllers/previews_controller.php:104
+msgid "devcp_preview_add_pagetitle"
+msgstr "미리 보기 추가"
+
+#: controllers/previews_controller.php:135
+msgid "devcp_preview_added_successfully"
+msgstr "미리 보기를 입력하였습니다."
+
+#: controllers/previews_controller.php:323
+msgid "devcp_preview_deleted_successfully"
+msgstr "미리 보기를 삭제하였습니다."
+
+#: controllers/previews_controller.php:194
+#: controllers/previews_controller.php:195
+msgid "devcp_preview_edit_pagetitle"
+msgstr "미리 보기 편집"
+
+#: controllers/previews_controller.php:237
+msgid "devcp_preview_updated_successfully"
+msgstr "미리 보기를 수정하였습니다."
+
+#: views/developers/previews.thtml:120
+#, fuzzy
+msgid "devcp_previews_a_another"
+msgstr "Add Another Preview"
+
+#: views/developers/previews.thtml:96
+#, fuzzy
+msgid "devcp_previews_a_delete"
+msgstr "Delete Preview"
+
+#: views/developers/previews.thtml:95
+#, fuzzy
+msgid "devcp_previews_a_replace"
+msgstr "Replace Preview"
+
+#: views/developers/previews.thtml:126
+#, fuzzy
+msgid "devcp_previews_a_update"
+msgstr "Update Previews"
+
+#: views/developers/previews.thtml:115 views/developers/previews.thtml:124
+#, fuzzy
+msgid "devcp_previews_add_new"
+msgstr "Add New Preview"
+
+#. %s is a list of file extensions, e.g. ".png, .gif"
+#: views/developers/previews.thtml:116
+#, fuzzy
+msgid "devcp_previews_add_select"
+msgstr ""
+"Select an image to upload below. Images larger than the maximum size of 700 "
+"pixels wide by 525 pixels tall will be resized. Allowed file types: %s"
+
+#: views/developers/previews.thtml:121
+#, fuzzy
+msgid "devcp_previews_click_below"
+msgstr "Click Update Previews below to upload."
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/previews.thtml:102
+#, fuzzy
+msgid "devcp_previews_click_update"
+msgstr ""
+"Click the Update Previews button below to save this image. (<a %s>Cancel?</"
+"a>)"
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/previews.thtml:107
+#, fuzzy
+msgid "devcp_previews_error_message"
+msgstr ""
+"This preview will be deleted when Update Previews is clicked below. (<a %"
+"s>Cancel?</a>)"
+
+#: views/previews/add.thtml:45
+msgid "devcp_previews_filetype_info"
+msgstr ""
+"현재 부가 기능 미리 보기 ê·¸ë¦¼ì„ PNG, JPG, GIF 형ì‹ìœ¼ë¡œ 700x525 픽셀 보다 í° "
+"ì´ë¯¸ì§€ë¡œ 올려 주시기 ë°”ëžë‹ˆë‹¤. ìžë™ìœ¼ë¡œ í¬ê¸°ê°€ ì¡°ì •ë©ë‹ˆë‹¤."
+
+#: views/previews/add.thtml:43
+msgid "devcp_previews_header_add"
+msgstr "미리 보기 추가"
+
+#: views/developers/previews.thtml:80
+#, fuzzy
+msgid "devcp_previews_header_caption"
+msgstr "Preview Caption"
+
+#: views/previews/edit.thtml:43
+msgid "devcp_previews_header_edit"
+msgstr "미리 보기 편집"
+
+#: views/developers/previews.thtml:93
+#, fuzzy
+msgid "devcp_previews_label_default"
+msgstr "Default Preview"
+
+#: views/previews/add.thtml:54
+msgid "devcp_previews_label_file"
+msgstr "미리 보기 파ì¼"
+
+#: views/previews/add.thtml:59 views/previews/edit.thtml:50
+msgid "devcp_previews_label_makedefault"
+msgstr "현재 ê·¸ë¦¼ì„ ê¸°ë³¸ 미리 보기로 설정"
+
+#: views/developers/previews.thtml:100
+#, fuzzy
+msgid "devcp_previews_label_new"
+msgstr "New image:"
+
+#: views/developers/previews.thtml:118
+#, fuzzy
+msgid "devcp_previews_label_upload"
+msgstr "Upload Preview: "
+
+#: views/developers/previews.thtml:50
+#, fuzzy
+msgid "devcp_previews_notice_error"
+msgstr "One or more of your new previews could not be saved."
+
+#: views/developers/previews.thtml:47
+#, fuzzy
+msgid "devcp_previews_notice_success"
+msgstr "Your previews have been updated successfully."
+
+#: views/developers/previews.thtml:59
+#, fuzzy
+msgid "devcp_previews_p_screenshots"
+msgstr ""
+"The preview screenshots for your add-on are shown below. You can make "
+"changes to captions or images below. The Default Preview is the preview that "
+"is displayed next to your add-on in search and browse listings."
+
+#: views/previews/edit.thtml:55
+msgid "devcp_previews_submit_delete"
+msgstr "미리 보기 삭제"
+
+#: views/previews/edit.thtml:55
+msgid "devcp_previews_submit_delete_confirm"
+msgstr "현재 미리 보기 ê·¸ë¦¼ì„ ì‚­ì œí•˜ì‹œê² ìŠµë‹ˆê¹Œ?"
+
+#: views/previews/edit.thtml:54
+msgid "devcp_previews_submit_edit"
+msgstr "미리 보기 편집"
+
+#: views/previews/add.thtml:63
+msgid "devcp_previews_submit_upload"
+msgstr "미리 보기 업로드"
+
+#: views/developers/previews.thtml:78
+#, fuzzy
+msgid "devcp_previews_thumbnail"
+msgstr "Thumbnail"
+
+#. %s is the add-on name.
+#: views/developers/previews.thtml:44
+#, fuzzy
+msgid "devcp_previews_title"
+msgstr "%s Preview Manager"
+
+#: views/developers/uploader.thtml:74
+msgid "devcp_review_agreement_please"
+msgstr "ê³„ì† í•˜ê¸° ì „ì— ì•„ëž˜ ê°œë°œìž ì•½ê´€ ì‚¬í•­ì„ ì½ì–´ë³´ì‹œê¸° ë°”ëžë‹ˆë‹¤."
+
+#: views/elements/developers/rolecheck.thtml:42
+#, fuzzy
+msgid "devcp_rolecheck_no_privs"
+msgstr ""
+"<span>You do not have sufficient privileges to make changes on this page.</"
+"span><br />Contact the Add-on Owner if you need to make changes."
+
+#: controllers/developers_controller.php:1315
+#, fuzzy
+msgid "devcp_several_hours"
+msgstr ""
+"Please note that some changes may take several hours to appear in all areas "
+"of the website."
+
+#: views/elements/developers/sidebar.thtml:52
+#, fuzzy
+msgid "devcp_sidebar_a_dashboard"
+msgstr "Dashboard"
+
+#. %s is a number
+#: views/elements/developers/statsbar.thtml:45
+#: views/developers/dashboard.thtml:79
+#, php-format
+msgid "devcp_statsbar_adu"
+msgstr "<em>%s</em> ì¼ì¼ 사용ìž"
+
+#. %s is a number
+#: views/elements/developers/statsbar.thtml:41
+#: views/developers/dashboard.thtml:75
+#, php-format
+msgid "devcp_statsbar_total_downloads"
+msgstr "<em>%s</em> ì´ ë‹¤ìš´ë¡œë“œ 횟수"
+
+#. %s is a number
+#: views/elements/developers/statsbar.thtml:43
+#: views/developers/dashboard.thtml:77
+#, php-format
+msgid "devcp_statsbar_weekly_downloads"
+msgstr "<em>%s</em> 주간 다운로드 호ㅣㅅ수"
+
+#: views/developers/addon_status_confirm.thtml:59
+#, fuzzy
+msgid "devcp_status_confirm_active"
+msgstr ""
+"Marking this add-on active will cause it to show up in public areas "
+"appropriate for its status, including search and browse listings. It will be "
+"downloadable from the website and could be returned in client update checks, "
+"depending on its status. You will be able to return here and disable it "
+"again at your convenience."
+
+#: views/developers/addon_status_confirm.thtml:59
+#, fuzzy
+msgid "devcp_status_confirm_active_sure"
+msgstr "Are you sure you wish to mark this add-on active?"
+
+#: views/developers/addon_status_confirm.thtml:50
+#, fuzzy
+msgid "devcp_status_confirm_header_sure"
+msgstr "Are you sure?"
+
+#: views/developers/addon_status_confirm.thtml:55
+#, fuzzy
+msgid "devcp_status_confirm_inactive"
+msgstr ""
+"Marking this add-on inactive will prevent it from showing up in any public "
+"areas, including search and browse listings. It will not be downloadable "
+"from the website and will not be returned in client update checks. You will "
+"be able to return here and re-enable it at your convenience."
+
+#: views/developers/addon_status_confirm.thtml:55
+#, fuzzy
+msgid "devcp_status_confirm_inactive_sure"
+msgstr "Are you sure you wish to mark this add-on inactive?'"
+
+#: views/developers/addon_status_confirm.thtml:74
+#, fuzzy
+msgid "devcp_status_confirm_no"
+msgstr "No, cancel"
+
+#: views/developers/addon_status_confirm.thtml:67
+#, fuzzy
+msgid "devcp_status_confirm_public"
+msgstr ""
+"Making this add-on public will make it available for anyone to download and "
+"will begin offering updates to existing users."
+
+#: views/developers/addon_status_confirm.thtml:67
+#, fuzzy
+msgid "devcp_status_confirm_public_sure"
+msgstr "Are you sure you wish to make this add-on public?"
+
+#: views/developers/addon_status_confirm.thtml:63
+#, fuzzy
+msgid "devcp_status_confirm_sandbox"
+msgstr ""
+"Moving this add-on back to the sandbox will require users to login before "
+"downloading and updates will no longer be offered to existing users. Because "
+"your add-on is currently public, you will be able to return here at any time "
+"to make it public again."
+
+#: views/developers/addon_status_confirm.thtml:63
+#, fuzzy
+msgid "devcp_status_confirm_sandbox_sure"
+msgstr "Are you sure you wish to move this add-on to the sandbox?"
+
+#: views/developers/addon_status_confirm.thtml:73
+#, fuzzy
+msgid "devcp_status_confirm_yes"
+msgstr "Yes, I'm Sure"
+
+#: views/developers/addon_status_nominate.thtml:46
+#, fuzzy
+msgid "devcp_status_nominate_error_notice"
+msgstr ""
+"<span>A nomination message is required.</span><br />Please fill in the text "
+"box with the requested information and try again."
+
+#: views/developers/addon_status_nominate.thtml:55
+#, fuzzy
+msgid "devcp_status_nominate_header"
+msgstr "Add-on Nomination"
+
+#: views/developers/dashboard.thtml:85
+msgid "devcp_summary_lastversion"
+msgstr "최신 버전:"
+
+#. %s is the add-on name.
+#: views/developers/addon_edit.thtml:43
+#: views/developers/addon_edit_authors.thtml:44
+#: views/developers/versions_delete.thtml:43
+#: views/developers/addon_edit_properties.thtml:44
+#: views/developers/addon_edit_descriptions.thtml:44
+#: views/developers/versions_edit.thtml:44
+#: views/developers/addon_edit_categories.thtml:43
+#: views/developers/versions.thtml:43
+#, fuzzy
+msgid "devcp_title_edit_addon"
+msgstr "Edit %s"
+
+#. title attribute for a javascript link that pops up a help dialog.
+#: views/elements/translationbox.thtml:68
+#, fuzzy
+msgid "devcp_transbox_a_title_help"
+msgstr "Help (does not leave page)"
+
+#: views/elements/translationbox.thtml:68
+#, fuzzy
+msgid "devcp_transbox_alt_help"
+msgstr "Help"
+
+#. %1$s is <span>17</span>, %2$s is 42.
+#: views/elements/translationbox.thtml:101
+#, fuzzy
+msgid "devcp_transbox_chars_used"
+msgstr "Characters used: %1$s / %2$s"
+
+#: views/elements/translationbox.thtml:132
+#, fuzzy
+msgid "devcp_transbox_delete_sure"
+msgstr "Are you sure you wish to delete this translation?"
+
+#. %s is a locale, like en-US.
+#: views/elements/translationbox.thtml:143
+#, fuzzy
+msgid "devcp_transbox_help_header_tabs"
+msgstr "What are these %s tabs?"
+
+#: views/elements/translationbox.thtml:145
+#, fuzzy
+msgid "devcp_transbox_help_header_what"
+msgstr "What if I don't have any translations?"
+
+#: views/elements/translationbox.thtml:147
+#, fuzzy
+msgid "devcp_transbox_help_hide"
+msgstr "Hide Help"
+
+#: views/elements/translationbox.thtml:146
+#, fuzzy
+msgid "devcp_transbox_help_if"
+msgstr ""
+"If a user browses the site and a translation isn't available in their own "
+"language, it will fall back to your add-on's Default Locale, specified in "
+"the Edit Add-on Properties area. If you don't have any translations, just "
+"enter what you can into your Default Locale, which should be a language you "
+"speak."
+
+#: views/elements/translationbox.thtml:144
+#, fuzzy
+msgid "devcp_transbox_help_transbox"
+msgstr ""
+"This is a <i>Translation Box</i>. It allows you to localize a specific field "
+"into any other languages for which you might have a translation. You can "
+"add, edit, and remove translations using the locale tabs."
+
+#: views/elements/translationbox.thtml:85
+#, fuzzy
+msgid "devcp_transbox_img_add_trans"
+msgstr "Add Translation"
+
+#: views/elements/translationbox.thtml:86
+#, fuzzy
+msgid "devcp_transbox_img_remove_trans"
+msgstr "Remove Translation"
+
+#: views/elements/translationbox.thtml:123
+#, fuzzy
+msgid "devcp_transbox_input_add_all"
+msgstr "Add Locale to All"
+
+#: views/elements/translationbox.thtml:122
+#, fuzzy
+msgid "devcp_transbox_input_add_locale"
+msgstr "Add Locale"
+
+#: views/elements/translationbox.thtml:124
+#: views/elements/translationbox.thtml:135
+#, fuzzy
+msgid "devcp_transbox_input_cancel"
+msgstr "Cancel"
+
+#: views/elements/translationbox.thtml:134
+#, fuzzy
+msgid "devcp_transbox_input_delete"
+msgstr "Delete It"
+
+#: views/elements/translationbox.thtml:113
+#, fuzzy
+msgid "devcp_transbox_select_locale"
+msgstr "Select the locale of the translation to add:"
+
+#. %1$s and %2$s are GUIDs.
+#: controllers/developers_controller.php:343
+#, fuzzy
+msgid "devcp_update_addon_guid_error"
+msgstr ""
+"The add-on GUID used in this file (%1$s) does not match the existing GUID "
+"for this add-on (%2$s)."
+
+#: controllers/developers_controller.php:334
+#, fuzzy
+msgid "devcp_update_addon_priv_error"
+msgstr "You do not have sufficient privileges to update this add-on."
+
+#. %1$s is a version number, %2$s is an add-on ID.
+#: controllers/developers_controller.php:399
+#, fuzzy
+msgid "devcp_update_addon_version_belong_error"
+msgstr "The specified version (%1$s) does not belong to this add-on (%2$s)."
+
+#. %1$s is a version number, maybe 1.1.
+#. %2$s is a URL.
+#: controllers/developers_controller.php:351
+#, fuzzy
+msgid "devcp_update_addon_version_exists_error"
+msgstr ""
+"The version number uploaded (%1$s) already exists for this add-on. If you "
+"are trying to add another file to this version, <a href=\"%2$s\">click here</"
+"a>."
+
+#. %1$s and %2$s are version numbers.
+#: controllers/developers_controller.php:405
+#, fuzzy
+msgid "devcp_update_addon_version_match_error"
+msgstr ""
+"The uploaded version number (%1$s) does not match the existing version "
+"number (%2$s)."
+
+#: views/developers/uploader.thtml:68
+#, fuzzy
+msgid "devcp_uploader_a_start"
+msgstr "Get Started"
+
+#: views/developers/uploader.thtml:137
+#, fuzzy
+msgid "devcp_uploader_ajax_loading"
+msgstr "Uploading file..."
+
+#: views/developers/uploader.thtml:82
+#, fuzzy
+msgid "devcp_uploader_button_agree"
+msgstr "Agree and continue"
+
+#: views/developers/uploader.thtml:157
+#, fuzzy
+msgid "devcp_uploader_button_edit"
+msgstr "Edit My Add-on"
+
+#: views/developers/uploader.thtml:158
+#, fuzzy
+msgid "devcp_uploader_button_later"
+msgstr "I'll complete my add-on later."
+
+#: views/developers/uploader.thtml:168
+#, fuzzy
+msgid "devcp_uploader_button_release"
+msgstr "Add Release Notes"
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/uploader.thtml:156
+#, fuzzy
+msgid "devcp_uploader_created_results"
+msgstr ""
+"<p>Your add-on listing has been successfully created. The basic information "
+"obtained from your uploaded file has been stored, but there's a lot more to "
+"your listing that can be customized.</p><p>Your add-on is currently marked "
+"as <strong>Incomplete</strong>. In order to complete your add-on, you'll "
+"need to make sure it has an accurate name, summary, and description, as well "
+"as at least one selected category. You can edit your add-on's information "
+"using the link below and check the status of your add-on at any time on the "
+"<a %s>status page</a>."
+
+#: views/developers/uploader.thtml:143
+#, fuzzy
+msgid "devcp_uploader_error_correct"
+msgstr "Please correct this problem and upload your file again."
+
+#. %1$s is a version number, %2$s is a status, e.g Public or Incomplete.
+#: views/developers/uploader.thtml:175
+#, fuzzy
+msgid "devcp_uploader_file_created"
+msgstr ""
+"Your new file has been added to version %1$s and is currently marked as %2$s."
+
+#: views/developers/uploader.thtml:154
+#, fuzzy
+msgid "devcp_uploader_header_created"
+msgstr "Add-on Created!"
+
+#: views/developers/uploader.thtml:141
+#, fuzzy
+msgid "devcp_uploader_header_error"
+msgstr "Oops! There seems to be a problem with this file..."
+
+#: views/developers/uploader.thtml:173
+#, fuzzy
+msgid "devcp_uploader_header_file_added"
+msgstr "File Added!"
+
+#: views/developers/uploader.thtml:66
+#, fuzzy
+msgid "devcp_uploader_header_how"
+msgstr "How does it all work?"
+
+#. %s is the version number, e.g. 3.2.
+#: views/developers/uploader.thtml:163
+#, fuzzy
+msgid "devcp_uploader_header_update_created"
+msgstr "Version %s Created"
+
+#: views/developers/uploader.thtml:117
+#, fuzzy
+msgid "devcp_uploader_header_upload"
+msgstr "Upload Your File"
+
+#: views/developers/uploader.thtml:67
+#, fuzzy
+msgid "devcp_uploader_how"
+msgstr ""
+"<p>Thanks for your interest in submitting your add-on to Mozilla Add-ons. "
+"Hosting your add-on on Mozilla Add-ons is the easiest way to handle "
+"distribution of your add-on. Here's what you'll get:</p><ul><li>Each add-on "
+"will have a public display page with information you provide, such as a "
+"brief summary of the add-on's functionality, an optional longer description, "
+"and a showcase of preview screenshots of your add-on.</li><li>Your add-on "
+"will appear in search and browse listings across the site, and even in the "
+"Add-ons Manager of Firefox 3.</li><li>We'll take care of hosting all of your "
+"downloads and providing automatic updates to users when you upload a new "
+"version.</li><li>You'll have access to a statistics dashboard with detailed "
+"information about your user base.</li></ul><p>Add-ons hosted on the site "
+"must be reviewed by a Mozilla Add-ons Editor before they will have all of "
+"the features listed above. If you're ready to start the process and have "
+"your add-on package ready for upload, just click on Get Started below!</p>"
+
+#: views/developers/uploader.thtml:125
+#, fuzzy
+msgid "devcp_uploader_label_platformtype"
+msgstr "Supported Platforms:"
+
+#: views/developers/uploader.thtml:124
+#, fuzzy
+msgid "devcp_uploader_label_upload_field"
+msgstr "Add-on File: "
+
+#: controllers/components/developers.php:1221
+#, fuzzy
+msgid "devcp_uploader_option_other"
+msgstr "Other"
+
+#. %1$s is a number, %2$s is href="..." and should stay in the <a> tag.
+#: views/developers/uploader.thtml:176
+#, fuzzy
+msgid "devcp_uploader_p_pending_file"
+msgstr ""
+"The new file will be available to the public as soon as an editor is able to "
+"review it. There are currently %1$s other add-ons in the queue. Want to be "
+"reviewed faster? Consider <a %2$s>becoming an editor</a>."
+
+#. %1$s is a number, %2$s is href="..." and should stay in the <a> tag.
+#: views/developers/uploader.thtml:166
+#, fuzzy
+msgid "devcp_uploader_p_pending_version"
+msgstr ""
+"The new version will be available to the public as soon as an editor is able "
+"to review it. There are currently %1$s other add-ons in the queue. Want to "
+"be reviewed faster? Consider <a %2$s>becoming an editor</a>."
+
+#. %s is a status, e.g Public or Incomplete.
+#: views/developers/uploader.thtml:165
+#, fuzzy
+msgid "devcp_uploader_p_update_created"
+msgstr "Your new version has been created and is currently marked as %s."
+
+#. %1$s is href="..." and should stay in the 'Versions and Files' <a> tag.
+#. %2$s is href="..." and should stay in the 'current status' <a> tag.
+#: views/developers/uploader.thtml:177
+#, fuzzy
+msgid "devcp_uploader_p_update_file"
+msgstr ""
+"View your new file in the <a %1$s>Versions and Files page</a>, check out "
+"your add-on's <a %2$s>current status</a>, or <b>add release notes</b> by "
+"clicking the button below (highly recommended)."
+
+#. %1$s is href="..." and should stay in the 'Versions and Files' <a> tag.
+#. %2$s is href="..." and should stay in the 'current status' <a> tag.
+#: views/developers/uploader.thtml:167
+#, fuzzy
+msgid "devcp_uploader_p_update_version"
+msgstr ""
+"View your new version in the <a %1$s>Versions and Files page</a>, check out "
+"your add-on's <a %2$s>current status</a>, or <b>add release notes</b> by "
+"clicking the button below (highly recommended)."
+
+#: views/developers/uploader.thtml:118
+#, fuzzy
+msgid "devcp_uploader_p_upload"
+msgstr ""
+"Upload your add-on file using the form below. If you have multiple, platform-"
+"specific files to upload, choose a single file and then upload the others "
+"using the Versions and Files Manager."
+
+#: views/developers/uploader.thtml:125
+#, fuzzy
+msgid "devcp_uploader_platformtype_all"
+msgstr "All"
+
+#: views/developers/uploader.thtml:126
+#, fuzzy
+msgid "devcp_uploader_platformtype_specific"
+msgstr "Specific:"
+
+#. Used as first item in a <select>.
+#: controllers/components/developers.php:1185
+#, fuzzy
+msgid "devcp_uploader_please_choose"
+msgstr "Please Choose..."
+
+#. %1$s is the add-on name, %2$s is the version number.
+#: views/developers/uploader.thtml:57
+#, fuzzy
+msgid "devcp_uploader_title_file"
+msgstr "Add File to %1$s %2$s"
+
+#: views/developers/uploader.thtml:50
+#, fuzzy
+msgid "devcp_uploader_title_submit"
+msgstr "Submit New Add-on"
+
+#. %s is the add-on name.
+#: views/developers/uploader.thtml:54
+#, fuzzy
+msgid "devcp_uploader_title_update"
+msgstr "Update %s"
+
+#. %s is a full <a> tag
+#: controllers/developers_controller.php:503
+#, php-format
+msgid "devcp_valid_app_reference"
+msgstr "아래 %s를 확ì¸í•˜ì„¸ìš”."
+
+#. This is the text in the <a> tag for devcp_valid_app_reference. This should be
+#. fixed.
+#: controllers/developers_controller.php:503
+msgid "devcp_valid_app_reference_linktext"
+msgstr "참고 정보"
+
+#: controllers/developers_controller.php:581
+#, fuzzy
+msgid "devcp_verify_author_error"
+msgstr "No account found for that email address."
+
+#: controllers/developers_controller.php:553
+#, fuzzy
+msgid "devcp_verify_search_engine_error"
+msgstr ""
+"Either the XML is invalid or required fields are missing. Please <a href="
+"\"https://developer.mozilla.org/en/Creating_OpenSearch_plugins_for_Firefox"
+"\">read the documentation</a>, verify your add-on, and try again."
+
+#: views/developers/versions.thtml:75
+#, fuzzy
+msgid "devcp_versions_a_cancel"
+msgstr "Cancel"
+
+#: views/developers/versions.thtml:79
+#, fuzzy
+msgid "devcp_versions_a_delete"
+msgstr "Delete Version"
+
+#: views/developers/versions.thtml:74
+#, fuzzy
+msgid "devcp_versions_a_empty"
+msgstr "Remove Empty Version"
+
+#: views/developers/versions.thtml:71
+#, fuzzy
+msgid "devcp_versions_a_remove"
+msgstr "Remove?"
+
+#: views/developers/versions.thtml:91
+#, fuzzy
+msgid "devcp_versions_add"
+msgstr "Add New Version"
+
+#: views/developers/versions_delete.thtml:58
+#, fuzzy
+msgid "devcp_versions_delete_a_cancel"
+msgstr "Cancel"
+
+#: views/developers/versions_delete.thtml:56
+#, fuzzy
+msgid "devcp_versions_delete_a_delete"
+msgstr "Delete Version"
+
+#. Followed by a list of reviews and files that will be removed.
+#: views/developers/versions_delete.thtml:50
+#, fuzzy
+msgid "devcp_versions_delete_also"
+msgstr "This will also delete:"
+
+#: views/developers/versions_delete.thtml:53
+#, fuzzy
+msgid "devcp_versions_delete_files"
+msgid_plural "devcp_versions_delete_files"
+msgstr[0] "%s file"
+msgstr[1] "%s files"
+
+#. %s is the version number.
+#: views/developers/versions_delete.thtml:48
+#, fuzzy
+msgid "devcp_versions_delete_header"
+msgstr "Delete Version %s?"
+
+#: views/developers/versions_delete.thtml:52
+#, fuzzy
+msgid "devcp_versions_delete_reviews"
+msgid_plural "devcp_versions_delete_reviews"
+msgstr[0] "%s review"
+msgstr[1] "%s reviews"
+
+#. %s is the version number.
+#: views/developers/versions_delete.thtml:49
+#, fuzzy
+msgid "devcp_versions_delete_sure"
+msgstr "Are you sure you want to permanently delete version %s?"
+
+#: views/developers/versions_edit.thtml:102
+#: views/developers/versions_edit.thtml:155
+#, fuzzy
+msgid "devcp_versions_edit_a_cancel"
+msgstr "Cancel"
+
+#: views/developers/versions_edit.thtml:101
+#, fuzzy
+msgid "devcp_versions_edit_a_delete"
+msgstr "Delete File"
+
+#: views/developers/versions_edit.thtml:165
+#, fuzzy
+msgid "devcp_versions_edit_a_new_app"
+msgstr "Add New Application"
+
+#: views/developers/versions_edit.thtml:154
+#, fuzzy
+msgid "devcp_versions_edit_a_remove_app"
+msgstr "Remove Application"
+
+#: views/developers/versions_edit.thtml:114
+#, fuzzy
+msgid "devcp_versions_edit_add"
+msgstr "Add New File"
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/versions_edit.thtml:121
+#, fuzzy
+msgid "devcp_versions_edit_adjust"
+msgstr ""
+"Adjusting application information here will allow users to install your add-"
+"on even if the install.rdf in the package indicates that the add-on is "
+"incompatible. <a %s>List of supported applications</a>"
+
+#: views/developers/versions_edit.thtml:153
+#, fuzzy
+msgid "devcp_versions_edit_compat_sure"
+msgstr ""
+"Are you <b>sure</b> you wish to remove compatibility with this application?"
+
+#: views/developers/versions_edit.thtml:100
+#, fuzzy
+msgid "devcp_versions_edit_delete_sure"
+msgstr "Are you <b>sure</b> you wish to permanently delete this file?"
+
+#: views/developers/versions_edit.thtml:203
+#, fuzzy
+msgid "devcp_versions_edit_header_approval"
+msgstr "Approval Information"
+
+#: views/developers/versions_edit.thtml:120
+#, fuzzy
+msgid "devcp_versions_edit_header_compat"
+msgstr "Compatible Applications"
+
+#: views/developers/versions_edit.thtml:74
+#, fuzzy
+msgid "devcp_versions_edit_header_file"
+msgstr "File Information"
+
+#: views/developers/versions_edit.thtml:189
+#, fuzzy
+msgid "devcp_versions_edit_header_license"
+msgstr "License"
+
+#. %s is the version number.
+#: views/developers/versions_edit.thtml:53
+#, fuzzy
+msgid "devcp_versions_edit_header_manage"
+msgstr "Manage Version %s"
+
+#: views/developers/versions_edit.thtml:212
+#, fuzzy
+msgid "devcp_versions_edit_header_notes"
+msgstr "Approval Notes"
+
+#: views/developers/versions_edit.thtml:98
+#, fuzzy
+msgid "devcp_versions_edit_img_delete"
+msgstr "Delete File"
+
+#. %1$s is the file id, e.g. 18723.
+#. %2$s is the platform name, e.g. ALL or Windows.
+#. %3$s is the _('date) created.
+#. %4$s is the status, e.g. "In Sandbox" or "Public".
+#. %5$s is the _('date') status was changed.
+#: views/developers/versions_edit.thtml:208
+#, fuzzy
+msgid "devcp_versions_edit_li_file"
+msgstr "File %1$s (%2$s) created on %3$s and changed to %4$s on %5$s"
+
+#: views/developers/versions_edit.thtml:190
+#, fuzzy
+msgid "devcp_versions_edit_license_description"
+msgstr ""
+"Please select the appropriate license for your add-on. This license "
+"specifies the rights you grant on your source code."
+
+#: views/developers/versions_edit.thtml:111
+#, fuzzy
+msgid "devcp_versions_edit_no_files"
+msgstr "No files found."
+
+#: views/developers/versions_edit.thtml:213
+#, fuzzy
+msgid "devcp_versions_edit_optional"
+msgstr "Optional information for the Editor that reviews this version."
+
+#: views/developers/versions_edit.thtml:151
+#, fuzzy
+msgid "devcp_versions_edit_remove_compat"
+msgstr "Remove Application Compatibility"
+
+#: views/developers/versions_edit.thtml:167
+#, fuzzy
+msgid "devcp_versions_edit_select_app"
+msgstr "Please Select an Application"
+
+#: views/developers/versions_edit.thtml:78
+#, fuzzy
+msgid "devcp_versions_edit_th_file"
+msgstr "File"
+
+#: views/developers/versions_edit.thtml:79
+#, fuzzy
+msgid "devcp_versions_edit_th_platform"
+msgstr "Platform"
+
+#: views/developers/versions_edit.thtml:80
+#, fuzzy
+msgid "devcp_versions_edit_th_size"
+msgstr "Size"
+
+#: views/developers/versions_edit.thtml:81
+#, fuzzy
+msgid "devcp_versions_edit_th_status"
+msgstr "Status"
+
+#: views/developers/versions_edit.thtml:183
+#, fuzzy
+msgid "devcp_versions_edit_transbox_releasenotes_description"
+msgstr ""
+"Information about changes in this release, new features, known bugs, and "
+"other useful information specific to this release/version. This information "
+"will also be available to users updating the add-on in the Firefox 3 Add-ons "
+"Manager interface."
+
+#: views/developers/versions_edit.thtml:182
+#, fuzzy
+msgid "devcp_versions_edit_transbox_releasenotes_name"
+msgstr "Release Notes"
+
+#: views/developers/versions_edit.thtml:164
+#, fuzzy
+msgid "devcp_versions_edit_unsaved_compat"
+msgstr ""
+"<strong>You have unsaved changes.</strong> Compatibility will not be deleted "
+"until you click Update Version below."
+
+#: views/developers/versions_edit.thtml:113
+#, fuzzy
+msgid "devcp_versions_edit_unsaved_files"
+msgstr ""
+"<strong>You have unsaved changes.</strong> Files will not be deleted until "
+"you click Update Version below."
+
+#: views/developers/versions_edit.thtml:218
+#, fuzzy
+msgid "devcp_versions_edit_update"
+msgstr "Update Versions"
+
+#: views/developers/versions.thtml:49
+#, fuzzy
+msgid "devcp_versions_header_manage"
+msgstr "Manage Versions and Files"
+
+#: views/developers/versions.thtml:87
+#, fuzzy
+msgid "devcp_versions_no_versions"
+msgstr "No versions."
+
+#. %s is a version number, base 10.
+#: views/developers/versions.thtml:46
+#, fuzzy
+msgid "devcp_versions_notice_success"
+msgstr "Version %s deleted successfully."
+
+#: views/developers/versions.thtml:73
+#, fuzzy
+msgid "devcp_versions_p_remove"
+msgstr ""
+"This version has no files associated with it and can be removed. Would you "
+"like to remove this version?"
+
+#: views/developers/versions.thtml:58
+#, fuzzy
+msgid "devcp_versions_th_created"
+msgstr "Created"
+
+#: views/developers/versions.thtml:57
+#, fuzzy
+msgid "devcp_versions_th_status"
+msgstr "Status"
+
+#: views/developers/versions.thtml:56
+#, fuzzy
+msgid "devcp_versions_th_version"
+msgstr "Version"
+
+#: controllers/downloads_controller.php:91
+msgid "downloads_disable_warning"
+msgstr "부가 ê¸°ëŠ¥ì„ ì‚¬ìš©í•  수 없습니다."
+
+#: controllers/components/editors.php:57
+#, fuzzy
+msgid "editor_review_error_addon_not_nominated"
+msgstr "This add-on has not been nominated."
+
+#: controllers/components/editors.php:213
+#, fuzzy
+msgid "editor_review_error_file_not_pending"
+msgstr "This file is not pending review."
+
+#. Actions are, for example: approving or rejecting
+#: controllers/components/editors.php:79
+#: controllers/components/editors.php:182
+#, fuzzy
+msgid "editor_review_error_no_action"
+msgstr "Please select a review action."
+
+#: controllers/components/editors.php:192
+#, fuzzy
+msgid "editor_review_error_no_applications"
+msgstr "Please enter the applications you tested."
+
+#. Comments are required when an editor approves or rejects an add-on.
+#: controllers/components/editors.php:84
+#: controllers/components/editors.php:187
+#, fuzzy
+msgid "editor_review_error_no_comments"
+msgstr "Please enter review comments."
+
+#: controllers/components/editors.php:161
+#, fuzzy
+msgid "editor_review_error_no_files"
+msgstr "Please select at least one file to review."
+
+#: controllers/components/editors.php:197
+#, fuzzy
+msgid "editor_review_error_no_operating_system"
+msgstr "Please enter the operating systems you tested."
+
+#: views/editors/logs.thtml:51
+msgid "editorcp_logs_button_filter"
+msgstr "í•„í„°"
+
+#: views/editors/logs.thtml:44
+msgid "editorcp_logs_filter_by"
+msgstr "í•„í„°(type/action)"
+
+#: views/editors/logs.thtml:42 controllers/editors_controller.php:964
+msgid "editorcp_logs_page_heading"
+msgstr "ì´ë²¤íŠ¸ 로그"
+
+#: views/elements/developers/editorsmenu.thtml:60
+msgid "editorcp_menu_eventlog_link"
+msgstr "ì´ë²¤íŠ¸ 로그"
+
+#: views/elements/developers/editorsmenu.thtml:62
+msgid "editorcp_menu_mainpage_link"
+msgstr "ë©”ì¸ìœ¼ë¡œ"
+
+#: views/elements/developers/editorsmenu.thtml:61
+msgid "editorcp_menu_reviewlog_link"
+msgstr "í‰ê°€ 로그"
+
+#: views/elements/developers/editorsmenu.thtml:55
+msgid "editorcp_menu_summary_link"
+msgstr "íŽ¸ì§‘ìž ìš”ì•½"
+
+#: views/elements/developers/editorsmenu.thtml:52
+msgid "editorcp_menu_title"
+msgstr "íŽ¸ì§‘ìž ë„구"
+
+#: views/editors/reviewlog.thtml:49
+msgid "editorcp_reviewlog_button_filter"
+msgstr "í•„í„°"
+
+#: views/editors/reviewlog.thtml:58
+msgid "editorcp_reviewlog_column_action"
+msgstr "ë™ìž‘"
+
+#: views/editors/reviewlog.thtml:56
+msgid "editorcp_reviewlog_column_addon"
+msgstr "부가 기능"
+
+#: views/editors/reviewlog.thtml:55
+msgid "editorcp_reviewlog_column_date"
+msgstr "날짜"
+
+#: views/editors/reviewlog.thtml:57
+msgid "editorcp_reviewlog_column_editor"
+msgstr "편집ìž"
+
+#: views/editors/reviewlog.thtml:94
+msgid "editorcp_reviewlog_comments_hide"
+msgstr "설명 숨기기"
+
+#: views/editors/reviewlog.thtml:93
+msgid "editorcp_reviewlog_comments_show"
+msgstr "설명 ë³´ì´ê¸°"
+
+#. %1$s and %2$s are full <input> tags for dates
+#: views/editors/reviewlog.thtml:45
+#, php-format
+msgid "editorcp_reviewlog_entries_between"
+msgstr "í‰ê°€ 보기 (%s ~ %s) "
+
+#: views/editors/reviewlog.thtml:104
+msgid "editorcp_reviewlog_none_found"
+msgstr "기간 ë‚´ ì œì¶œëœ í‰ê°€ í•­ëª©ì´ ì—†ìŠµë‹ˆë‹¤."
+
+#: views/editors/reviewlog.thtml:42
+msgid "editorcp_reviewlog_page_heading"
+msgstr "í‰ê°€ 로그"
+
+#: views/editors/summary.thtml:61
+msgid "editorcp_summary_monthreviews_heading"
+msgstr "월간 í‰ê°€"
+
+#: views/editors/summary.thtml:77
+msgid "editorcp_summary_neweditors_heading"
+msgstr "새 편집ìž"
+
+#: views/editors/summary.thtml:42
+msgid "editorcp_summary_page_heading"
+msgstr "íŽ¸ì§‘ìž ìš”ì•½ ì •ë³´"
+
+#: views/editors/summary.thtml:94
+msgid "editorcp_summary_recentactivity_heading"
+msgstr "최근 íŽ¸ì§‘ìž í™œë™ ë‚´ì—­"
+
+#: views/editors/summary.thtml:45
+msgid "editorcp_summary_totalreviews_heading"
+msgstr "ì´ í‰ê°€ 수"
+
+#: controllers/editors_controller.php:248
+#: controllers/editors_controller.php:249
+msgid "editors_addon_review_pagetitle"
+msgstr "부가 기능 í‰ê°€"
+
+#: controllers/editors_controller.php:349
+msgid "editors_error_js-formerror"
+msgstr "아래 í•­ëª©ì„ ëª¨ë‘ ì±„ì›Œ 주시기 ë°”ëžë‹ˆë‹¤:"
+
+#: controllers/editors_controller.php:350
+msgid "editors_error_review_one_file"
+msgstr "í‰ê°€í•  파ì¼ì„ 하나 ì´ìƒ ê³¨ë¼ ì£¼ì‹­ì‹œì˜¤."
+
+#: controllers/editors_controller.php:274
+msgid "editors_error_self_reviews_forbidden"
+msgstr "ìžì‹ ì˜ 부가 기능ì—는 í‰ê°€í•  수 없습니다."
+
+#: controllers/editors_controller.php:699
+msgid "editors_external_software"
+msgstr "외부 프로그램"
+
+#: views/editors/featured.thtml:120 views/editors/featured.thtml:121
+msgid "editors_featured_add_feature"
+msgstr "ìƒì„¸ 기능 추가"
+
+#: views/editors/featured.thtml:126
+msgid "editors_featured_add_feature_submit"
+msgstr "추가"
+
+#: views/editors/featured.thtml:49 controllers/editors_controller.php:832
+#: controllers/editors_controller.php:848
+msgid "editors_featured_addon_add_failure"
+msgstr "ìƒì„¸ 기능 추가를 í•  수 없습니다."
+
+#: controllers/editors_controller.php:851
+msgid "editors_featured_addon_add_success"
+msgstr "ìƒì„¸ 기능 추가를 완료했습니다."
+
+#: views/editors/featured.thtml:50 controllers/editors_controller.php:839
+#: controllers/editors_controller.php:868
+#: controllers/editors_controller.php:886
+msgid "editors_featured_addon_edit_failure"
+msgstr "ìƒì„¸ ê¸°ëŠ¥ì„ íŽ¸ì§‘í•  수 없습니다."
+
+#: views/editors/featured.thtml:51 controllers/editors_controller.php:888
+msgid "editors_featured_addon_edit_success"
+msgstr "ìƒì„¸ ê¸°ëŠ¥ì„ íŽ¸ì§‘í•˜ì˜€ìŠµë‹ˆë‹¤."
+
+#: views/editors/featured.thtml:53 controllers/editors_controller.php:861
+msgid "editors_featured_addon_invalid_locale"
+msgstr "하나 ì´ìƒì˜ ì–¸ì–´íŒ©ì´ ìœ íš¨í•˜ì§€ 않습니다."
+
+#: views/editors/featured.thtml:52 controllers/editors_controller.php:906
+msgid "editors_featured_addon_remove_failure"
+msgstr "ìƒì„¸ 기능를 지울 수 없습니다."
+
+#: controllers/editors_controller.php:901
+msgid "editors_featured_addon_remove_success"
+msgstr "ìƒì„¸ ê¸°ëŠ¥ì„ ì‚­ì œí•˜ì˜€ìŠµë‹ˆë‹¤."
+
+#: controllers/editors_controller.php:915
+#: controllers/editors_controller.php:917
+msgid "editors_featured_addons_pagetitle"
+msgstr "부가 기능 ìƒì„¸ ì •ë³´"
+
+#: views/editors/featured.thtml:54 views/editors/featured.thtml:107
+msgid "editors_featured_edit_feature_submit"
+msgstr "전송"
+
+#: views/editors/featured.thtml:90 views/editors/featured.thtml:91
+msgid "editors_featured_remove_feature"
+msgstr "ìƒì„¸ ê¸°ëŠ¥ì„ ì‚­ì œ"
+
+#: views/editors/queue.thtml:46
+msgid "editors_filter_queue"
+msgstr "필터 대기"
+
+#: views/editors/queue.thtml:182
+msgid "editors_helpful_links"
+msgstr "유용한 ë§í¬"
+
+#: views/editors/queue.thtml:182
+msgid "editors_link_guide"
+msgstr "편집 ê°€ì´ë“œ"
+
+#: views/editors/queue.thtml:182
+msgid "editors_link_policy"
+msgstr "부가 기능 정책"
+
+#: views/editors/queue.thtml:47
+msgid "editors_notice_filter_session"
+msgstr "ì´ í•„í„°ë“¤ì€ ì„¸ì…˜ì´ ìœ ì§€ë˜ëŠ” ë™ì•ˆ 사용할 수 있습니다."
+
+# %1 is the queue mode
+#. %1 is the queue mode
+#: views/editors/queue.thtml:177 views/admin/flagged_queue.thtml:89
+msgid "editors_notice_none_found"
+msgstr "í‰ê°€í•  부가 기능 갯수: %1 ê°œ"
+
+#: controllers/editors_controller.php:1040
+msgid "editors_one_day"
+msgstr "1ì¼"
+
+#: controllers/editors_controller.php:1048
+msgid "editors_one_hour"
+msgstr "1시간"
+
+#: controllers/editors_controller.php:1056
+msgid "editors_one_minute"
+msgstr "1분"
+
+#: controllers/editors_controller.php:64 controllers/editors_controller.php:73
+#: controllers/editors_controller.php:77
+msgid "editors_pagetitle"
+msgstr "íŽ¸ì§‘ìž ì œì–´íŒ"
+
+#. %s is a comma separated list of platforms. Example: Windows, OS X
+#: controllers/editors_controller.php:680
+#: controllers/editors_controller.php:683
+#, php-format
+msgid "editors_platform_x_only"
+msgstr "%s 만 지ì›"
+
+#: controllers/editors_controller.php:695
+msgid "editors_pre-release"
+msgstr "출시 전"
+
+# %1 is the app name
+#. %1 is the app name
+#: views/editors/queue.thtml:131
+#, php-format
+msgid "editors_queue_app_compatibility"
+msgstr "%s 호환성"
+
+#: views/editors/queue.thtml:51
+#, fuzzy
+msgid "editors_queue_filter_label_addon"
+msgstr "Add-on or Author Email"
+
+#: views/editors/queue.thtml:72
+#, fuzzy
+msgid "editors_queue_filter_label_addontypes"
+msgstr "Add-on Types"
+
+#: views/editors/queue.thtml:56
+#, fuzzy
+msgid "editors_queue_filter_label_application"
+msgstr "Application"
+
+#: views/editors/queue.thtml:61
+#, fuzzy
+msgid "editors_queue_filter_label_maxversion"
+msgstr "Max. Version"
+
+#: views/editors/queue.thtml:78
+#, fuzzy
+msgid "editors_queue_filter_label_platforms"
+msgstr "Platforms"
+
+#: views/editors/queue.thtml:66
+#, fuzzy
+msgid "editors_queue_filter_label_submissionage"
+msgstr "Age of Submission (days)"
+
+#. %1$s is a number
+#: views/editors/queue.thtml:90
+#, fuzzy
+msgid "editors_queue_filter_result_count"
+msgid_plural "editors_queue_filter_result_count"
+msgstr[0] "Results of your filtered search: <strong>%1$s</strong> Add-on"
+msgstr[1] "Results of your filtered search: <strong>%1$s</strong> Add-ons"
+
+#: views/editors/queue.thtml:84
+msgid "editors_queue_submit_clean"
+msgstr "제거"
+
+#: views/editors/queue.thtml:83
+msgid "editors_queue_submit_filter"
+msgstr "í•„í„°"
+
+#: controllers/editors_controller.php:133
+msgid "editors_queues_disabled"
+msgstr "현재 í‰ê°€ ìž‘ì—…ì´ ì •ì§€ ë˜ì—ˆìŠµë‹ˆë‹¤. 다시 í™•ì¸ ë°”ëžë‹ˆë‹¤."
+
+#: views/editors/review.thtml:149
+#, fuzzy
+msgid "editors_review_a_edit_item"
+msgstr "Edit Item"
+
+#: views/editors/review.thtml:146
+#, fuzzy
+msgid "editors_review_a_item_history"
+msgstr "Item History"
+
+#: views/editors/review.thtml:148
+#, fuzzy
+msgid "editors_review_a_item_homepage"
+msgstr "Item Homepage"
+
+#: views/editors/review.thtml:145
+#, fuzzy
+msgid "editors_review_a_item_overview"
+msgstr "Item Overview"
+
+#: views/editors/review.thtml:147
+#, fuzzy
+msgid "editors_review_a_previews"
+msgstr "Previews"
+
+#: controllers/editors_controller.php:345
+msgid "editors_review_action"
+msgstr "í‰ê°€ 하기"
+
+#: views/editors/review.thtml:159
+#, fuzzy
+msgid "editors_review_action_info"
+msgstr "Request More Information"
+
+#: views/editors/review.thtml:157
+msgid "editors_review_action_public"
+msgstr "공개 하기"
+
+#: views/editors/review.thtml:160
+msgid "editors_review_action_request_superreview"
+msgstr "ìƒìœ„ í‰ê°€ 요청"
+
+#: views/editors/review.thtml:158
+msgid "editors_review_action_sandbox"
+msgstr "Sandbox 유지"
+
+#: controllers/editors_controller.php:346
+msgid "editors_review_comments"
+msgstr "í‰ê°€ ì˜ê²¬"
+
+#: views/editors/review.thtml:182
+#, fuzzy
+msgid "editors_review_details_info_request"
+msgstr ""
+"Use this form to request more information from the author. They will receive "
+"an email and be able to answer here. You will be notified by email when they "
+"reply."
+
+#: views/editors/review.thtml:174
+msgid "editors_review_details_nominated_public"
+msgstr ""
+"부가 ê¸°ëŠ¥ì˜ ìµœì‹  ë²„ì „ì„ ì›¹ 사ì´íŠ¸ì™€ 공개하ë„ë¡ í•©ë‹ˆë‹¤. 향후 새 ë²„ì „ì€ ë‹¤ì‹œ "
+"Sandboxì—ì„œ 편집ìžì˜ í‰ê°€ë¥¼ 거치게 ë©ë‹ˆë‹¤."
+
+#: views/editors/review.thtml:177
+msgid "editors_review_details_nominated_sandbox"
+msgstr "부가 ê¸°ëŠ¥ì„ Sandboxì— ê³„ì† ìœ ì§€ 합니다."
+
+#: views/editors/review.thtml:166
+msgid "editors_review_details_pending_public"
+msgstr "부가 ê¸°ëŠ¥ì„ ê³µê°œ 웹 사ì´íŠ¸ì— 공개하ë„ë¡ í•©ë‹ˆë‹¤."
+
+#: views/editors/review.thtml:169
+msgid "editors_review_details_pending_sandbox"
+msgstr "ê³µê°œëœ ë¶€ê°€ ê¸°ëŠ¥ì„ Sandboxë¡œ 옮ê¹ë‹ˆë‹¤."
+
+#: views/editors/review.thtml:185
+msgid "editors_review_details_superreview"
+msgstr ""
+"ì´ ë¶€ê°€ 기능ì—ì„œ 보안, 저작권 ì´ìŠˆ 등과 ê°™ì€ ì—¼ë ¤ê°€ 있는 경우 관리ìžì—게 ìƒ"
+"위 í‰ê°€ë¥¼ 요청할 수 있습니다. 아래 í•­ëª©ì— ì˜ê²¬ì„ 입력하시면 개발ìžê°€ ì•„ë‹Œ ê´€"
+"리ìžì—게 전달 ë©ë‹ˆë‹¤."
+
+#: views/editors/review.thtml:134
+msgid "editors_review_file_diff_link"
+msgstr "공개 버전 비êµ"
+
+#: views/editors/review.thtml:131
+msgid "editors_review_file_viewcontents_link"
+msgstr "내용 보기"
+
+#: views/editors/review.thtml:65
+msgid "editors_review_header_authors"
+msgstr "개발ìž:"
+
+#: views/editors/review.thtml:79
+msgid "editors_review_header_categories"
+msgstr "분류:"
+
+#: views/editors/review.thtml:92
+msgid "editors_review_header_compatibility"
+msgstr "호환성:"
+
+#: views/editors/review.thtml:251
+msgid "editors_review_header_description"
+msgstr "설명"
+
+#: views/editors/review.thtml:275
+msgid "editors_review_header_devcomments"
+msgstr "ê°œë°œìž ì˜ê²¬"
+
+#: views/editors/review.thtml:263
+msgid "editors_review_header_eula"
+msgstr "EULA"
+
+#: views/editors/review.thtml:115
+msgid "editors_review_header_files"
+msgstr "파ì¼:"
+
+#: views/editors/review.thtml:284
+msgid "editors_review_header_itemhistory"
+msgstr "항목 기ë¡"
+
+#: views/editors/review.thtml:232
+msgid "editors_review_header_nominationmessage"
+msgstr "후보 ë“±ë¡ ë©”ì‹œì§€"
+
+#: views/editors/review.thtml:311
+msgid "editors_review_header_previews"
+msgstr "미리 보기"
+
+#: views/editors/review.thtml:269
+msgid "editors_review_header_privacy"
+msgstr "ê°œì¸ ì •ë³´ 보호 ì •ì±…"
+
+# %1 is the addon name and version
+#. %1 is the add-on name and version
+#: views/editors/review.thtml:56
+#, php-format
+msgid "editors_review_header_review"
+msgstr "%s í‰ê°€í•˜ê¸°"
+
+#: views/editors/review.thtml:239
+msgid "editors_review_header_reviewernotes"
+msgstr "í‰ê°€ìž ì£¼ì˜ ì‚¬í•­"
+
+#: views/editors/review.thtml:245
+msgid "editors_review_header_summary"
+msgstr "요약 정보"
+
+#: views/editors/review.thtml:257
+msgid "editors_review_header_versionnotes"
+msgstr "버전 노트"
+
+#. a noun: shown in an add-on's editor review history
+#: views/elements/developers/editors_review_history_item.thtml:80
+#, fuzzy
+msgid "editors_review_history_info_reply"
+msgstr "Reply"
+
+#: views/elements/developers/editors_review_history_item.thtml:78
+#, fuzzy
+msgid "editors_review_history_info_request"
+msgstr "Information Request"
+
+#: views/elements/developers/editors_review_history_item.thtml:62
+#: views/editors/reviewlog.thtml:77
+msgid "editors_review_history_nominated_adminreview"
+msgstr "í‰ê°€ 관리"
+
+#: views/elements/developers/editors_review_history_item.thtml:56
+#: views/editors/reviewlog.thtml:71
+msgid "editors_review_history_nominated_approved"
+msgstr "승ì¸/공개 추천"
+
+#: views/elements/developers/editors_review_history_item.thtml:59
+#: views/editors/reviewlog.thtml:74
+msgid "editors_review_history_nominated_denied"
+msgstr "ìŠ¹ì¸ ê±°ë¶€ 하기"
+
+#: views/editors/review.thtml:303
+msgid "editors_review_history_nonefound"
+msgstr "ì´ì „ í‰ê°€ ì‚¬í•­ì´ ì—†ìŠµë‹ˆë‹¤."
+
+#: views/elements/developers/editors_review_history_item.thtml:73
+#: views/editors/reviewlog.thtml:88
+msgid "editors_review_history_pending_adminreview"
+msgstr "í‰ê°€ 관리"
+
+#: views/elements/developers/editors_review_history_item.thtml:67
+#: views/editors/reviewlog.thtml:82
+msgid "editors_review_history_pending_approved"
+msgstr "승ì¸/공개"
+
+#: views/elements/developers/editors_review_history_item.thtml:70
+#: views/editors/reviewlog.thtml:85
+msgid "editors_review_history_pending_denied"
+msgstr "거부/Sandbox"
+
+#. link text in an add-on's editor review history, allowing to hide and show an information request's replies
+#. %1 is the number of replies
+#: views/elements/developers/editors_review_history_item.thtml:90
+#, fuzzy
+msgid "editors_review_history_show_hide_replies"
+msgid_plural "editors_review_history_show_hide_replies"
+msgstr[0] "Show/Hide Replies (%1$s)"
+msgstr[1] "Show/Hide Replies (%1$s)"
+
+#: views/editors/review.thtml:208
+msgid "editors_review_label_applications"
+msgstr "ì‘ìš© 프로그램:"
+
+#: views/editors/review.thtml:196
+msgid "editors_review_label_cannedresponse"
+msgstr "내부 ì‘답 ì„ íƒ:"
+
+#: views/editors/review.thtml:190
+msgid "editors_review_label_comments"
+msgstr "설명:"
+
+#: views/editors/review.thtml:204
+msgid "editors_review_label_operating_systems"
+msgstr "ìš´ì˜ ì²´ì œ:"
+
+#: views/editors/review.thtml:285 views/editors/review.thtml:312
+msgid "editors_review_link_pagetop"
+msgstr "위로"
+
+#: views/editors/review.thtml:141
+#, fuzzy
+msgid "editors_review_mulitple_notice"
+msgstr ""
+"Notice: Only review more than one file if you have tested EVERY file you "
+"select."
+
+#: views/editors/review.thtml:51
+#, fuzzy
+msgid "editors_review_next_link"
+msgstr "next &raquo;"
+
+#: views/editors/review.thtml:322
+msgid "editors_review_previews_notfound"
+msgstr "미리 보기가 없습니다."
+
+#: views/editors/review.thtml:50
+#, fuzzy
+msgid "editors_review_previous_link"
+msgstr "&laquo; prev"
+
+#: controllers/editors_controller.php:144
+#: controllers/editors_controller.php:146
+msgid "editors_review_queue_pagetitle"
+msgstr "í‰ê°€ 처리함"
+
+# %1 is the add-ons rank in the queue, %2 is the total queue length
+#. %1 is the add-ons rank in the queue, %2 is the total queue length
+#: views/editors/review.thtml:47
+#, fuzzy
+msgid "editors_review_rank_in_queue"
+msgstr "<strong># %1$s</strong> of %2$s in queue"
+
+#. %1 is the add-ons rank in the queue, %2 is the total queue length. Both numbers
+#: views/editors/review.thtml:45
+#, fuzzy
+msgid "editors_review_rank_in_queue_filtered"
+msgstr "<strong># %1$s</strong> of %2$s in queue (filtered)"
+
+#: views/editors/review.thtml:223
+msgid "editors_review_submit_process_action"
+msgstr "ë™ìž‘ 과정"
+
+#: views/editors/review.thtml:293
+msgid "editors_review_th_action"
+msgstr "ë™ìž‘"
+
+#: views/editors/review.thtml:294
+msgid "editors_review_th_comments"
+msgstr "설명"
+
+#: views/editors/review.thtml:291
+msgid "editors_review_th_date"
+msgstr "날짜"
+
+#: views/editors/review.thtml:292
+msgid "editors_review_th_reviewer"
+msgstr "í‰ê°€ìž"
+
+#: views/editors/review.thtml:290
+msgid "editors_review_th_version_file"
+msgstr "버전/파ì¼"
+
+#: views/editors/review.thtml:217
+#, fuzzy
+msgid "editors_review_update_notify_once"
+msgstr ""
+"Notify me the next time this add-on is updated. (Subsequent updates will not "
+"generate an email)"
+
+#: controllers/editors_controller.php:298
+msgid "editors_reviewed_successfully"
+msgstr "í‰ê°€ ìž‘ì—…ì„ ì§„í–‰ 합니다."
+
+#: views/editors/reviews_queue.thtml:106
+#, fuzzy
+msgid "editors_reviews_action_delete_review"
+msgstr "Delete review"
+
+#: views/editors/reviews_queue.thtml:104
+#, fuzzy
+msgid "editors_reviews_action_keep"
+msgstr "Remove flags; keep review"
+
+#: views/editors/reviews_queue.thtml:102
+msgid "editors_reviews_action_skip"
+msgstr "나중ì—"
+
+#: views/editors/reviews_queue.thtml:100
+msgid "editors_reviews_header_action"
+msgstr "처리"
+
+#: views/editors/reviews_queue.thtml:67
+msgid "editors_reviews_in_reply_to"
+msgstr "ì‘답 주소:"
+
+#: controllers/editors_controller.php:748
+msgid "editors_reviews_processed"
+msgstr "í‰ê°€ ë‚´ìš©ì´ ìž˜ 처리ë˜ì—ˆìŠµë‹ˆë‹¤."
+
+#: views/editors/reviews_queue.thtml:117
+msgid "editors_reviews_queue_empty"
+msgstr "현재 관리해야할 í‰ê°€ í•­ëª©ì´ ì—†ìŠµë‹ˆë‹¤."
+
+#: views/editors/reviews_queue.thtml:111
+msgid "editors_reviews_submit_process_reviews"
+msgstr "제출 과정 í‰ê°€"
+
+#: controllers/editors_controller.php:691
+msgid "editors_site_specific"
+msgstr "사ì´íŠ¸ 기반"
+
+#: controllers/editors_controller.php:348
+msgid "editors_tested_app"
+msgstr "테스트 완료 ì‘ìš© 프로그램"
+
+#: controllers/editors_controller.php:347
+msgid "editors_tested_os"
+msgstr "테스트 완료 ìš´ì˜ ì²´ì œ"
+
+#: views/editors/queue.thtml:151
+msgid "editors_th_additional_info"
+msgstr "기타 정보"
+
+#: views/editors/featured.thtml:63 views/editors/queue.thtml:109
+#: views/admin/flagged_queue.thtml:53
+msgid "editors_th_addon"
+msgstr "부가 기능"
+
+#: views/editors/queue.thtml:125
+msgid "editors_th_addontype"
+msgstr "형ì‹"
+
+#: views/editors/featured.thtml:64
+msgid "editors_th_locales"
+msgstr "언어를 제한 할까요?"
+
+#: views/editors/queue.thtml:148
+#, fuzzy
+msgid "editors_th_nomination_age"
+msgstr "Time in Queue"
+
+#: views/editors/queue.thtml:101 views/editors/queue.thtml:117
+#: views/editors/queue.thtml:144
+#, fuzzy
+msgid "editors_th_sort_ascending"
+msgstr "Ascending sort"
+
+#: views/editors/queue.thtml:105 views/editors/queue.thtml:121
+#: views/editors/queue.thtml:140
+#, fuzzy
+msgid "editors_th_sort_descending"
+msgstr "Descending sort"
+
+#. %s is a number
+#: controllers/editors_controller.php:1036
+#, php-format
+msgid "editors_x_days"
+msgstr "%sì¼"
+
+#. %s is a number
+#: controllers/editors_controller.php:1044
+#, php-format
+msgid "editors_x_hours"
+msgstr "%s시간"
+
+#. %s is a number
+#: controllers/editors_controller.php:1052
+#, php-format
+msgid "editors_x_minutes"
+msgstr "%s분"
+
+#: views/errors/error401.thtml:50 controllers/components/simple_acl.php:81
+#: controllers/components/simple_acl.php:82
+#: controllers/components/simple_acl.php:83 controllers/components/amo.php:607
+#: controllers/components/amo.php:608 controllers/components/amo.php:609
+#: controllers/reviews_controller.php:353
+#: controllers/reviews_controller.php:485
+#: controllers/collections_controller.php:438
+#: controllers/collections_controller.php:496
+#: controllers/collections_controller.php:504
+#: controllers/collections_controller.php:971
+#: controllers/collections_controller.php:1034
+#: controllers/collections_controller.php:1077
+msgid "error_access_denied"
+msgstr "ì´ í•­ëª©ì„ ì±„ì›Œì•¼ 합니다."
+
+#: views/errors/error401.thtml:52
+msgid "error_access_denied_message"
+msgstr "ì´ íŽ˜ì´ì§€ë¥¼ 보시려면 ê¶Œí•œì´ í•„ìš” 합니다."
+
+#: controllers/collections_controller.php:1039
+#, fuzzy
+msgid "error_addon_exists"
+msgstr "Add-on already exists!"
+
+#: controllers/developers_controller.php:200
+#: controllers/developers_controller.php:593
+#: controllers/developers_controller.php:1016
+#: controllers/developers_controller.php:1429
+#: controllers/downloads_controller.php:95
+#: controllers/downloads_controller.php:102
+#: controllers/downloads_controller.php:164
+#: controllers/statistics_controller.php:135
+#: controllers/previews_controller.php:115
+#: controllers/previews_controller.php:206
+#: controllers/previews_controller.php:307
+#: controllers/reviews_controller.php:77
+#: controllers/reviews_controller.php:240
+#: controllers/reviews_controller.php:332
+#: controllers/reviews_controller.php:340 controllers/api_controller.php:123
+#: controllers/api_controller.php:759 controllers/addons_controller.php:131
+#: controllers/addons_controller.php:197
+#: controllers/addons_controller.php:1407
+#: controllers/addons_controller.php:1465
+#: controllers/addons_controller.php:1469
+#: controllers/addons_controller.php:1503
+#: controllers/editors_controller.php:265
+#: controllers/collections_controller.php:1041
+#: controllers/collections_controller.php:1074
+msgid "error_addon_notfound"
+msgstr "검색 결과가 없습니다!"
+
+#: controllers/files_controller.php:83 controllers/files_controller.php:196
+msgid "error_addon_notviewable"
+msgstr "여기서 부가 ê¸°ëŠ¥ì„ ë³¼ 수 없습니다."
+
+#: controllers/reviews_controller.php:246
+msgid "error_addon_selfreview"
+msgstr "ìžê¸°ê°€ 만든 부가 ê¸°ëŠ¥ì— ë¦¬ë·°ë¥¼ 올릴 수 없습니다."
+
+#: controllers/addons_controller.php:970
+msgid "error_browse_no_addons"
+msgstr "분류 ë‚´ì— ë¶€ê°€ ê¸°ëŠ¥ì´ ì—†ìŠµë‹ˆë‹¤!"
+
+#: controllers/api_controller.php:424
+#, fuzzy
+msgid "error_collection_feed_notfound"
+msgstr "Add-on feed not found."
+
+#: views/users/register.thtml:65 views/users/edit.thtml:194
+msgid "error_email_invalid"
+msgstr "ì´ë©”ì¼ ì£¼ì†Œê°€ 유효하지 않습니다."
+
+#: views/users/pwreset.thtml:74 views/users/register.thtml:70
+#: views/users/register.thtml:80 views/users/register.thtml:86
+#: views/users/edit.thtml:105 views/users/edit.thtml:111
+#: views/users/edit.thtml:192 views/admin/users_edit.thtml:78
+#: views/admin/users_edit.thtml:83 views/reviews/add.thtml:80
+#: views/reviews/add.thtml:104
+msgid "error_field_required"
+msgstr "ì´ í•­ëª©ì„ ì±„ì›Œì•¼ 합니다."
+
+#: controllers/files_controller.php:75 controllers/files_controller.php:93
+#: controllers/files_controller.php:96 controllers/files_controller.php:163
+#: controllers/files_controller.php:176 controllers/files_controller.php:185
+#: controllers/files_controller.php:204 controllers/editors_controller.php:412
+msgid "error_file_notfound"
+msgstr "íŒŒì¼ ì—†ìŒ!"
+
+#. %s is a filename
+#: controllers/editors_controller.php:430
+#, php-format
+msgid "error_file_x_notfound"
+msgstr "íŒŒì¼ ì˜¤ë¥˜: %s는 존재하지 않습니다."
+
+#: views/collections/add.thtml:55 views/collections/edit.thtml:89
+#: views/users/register.thtml:54 views/users/edit.thtml:81
+#: views/reviews/add.thtml:70 controllers/groups_controller.php:80
+#: controllers/groups_controller.php:102
+msgid "error_formerrors"
+msgstr "ì´ ì–‘ì‹ì— 오류가 있습니다. 수정한 후 다시 제출하십시오."
+
+#: views/users/register.thtml:109
+msgid "error_invalid_captcha"
+msgstr "맞지 않습니다. 다시 해보세요!"
+
+#: views/users/register.thtml:100 views/users/edit.thtml:125
+#: views/admin/users_edit.thtml:101
+msgid "error_invalid_url"
+msgstr "ì´ë©”ì¼ ì£¼ì†Œê°€ 유효하지 않습니다."
+
+#. %s is a string representing what's missing. Example: file_id
+#: controllers/downloads_controller.php:65
+#: controllers/users_controller.php:185 controllers/users_controller.php:264
+#: controllers/users_controller.php:559 controllers/users_controller.php:653
+#: controllers/reviews_controller.php:71
+#: controllers/reviews_controller.php:234
+#: controllers/reviews_controller.php:325
+#: controllers/reviews_controller.php:473
+#: controllers/reviews_controller.php:475
+#: controllers/addons_controller.php:182
+#: controllers/addons_controller.php:1381
+#: controllers/addons_controller.php:1455
+#: controllers/collections_controller.php:266
+#: controllers/collections_controller.php:285
+#: controllers/collections_controller.php:346
+#: controllers/collections_controller.php:443
+#: controllers/collections_controller.php:482
+#: controllers/collections_controller.php:936
+#: controllers/collections_controller.php:959
+#: controllers/collections_controller.php:960
+#: controllers/collections_controller.php:975
+#: controllers/collections_controller.php:977
+#: controllers/collections_controller.php:994
+#: controllers/collections_controller.php:1003
+#: controllers/collections_controller.php:1016
+#: controllers/collections_controller.php:1017
+#: controllers/collections_controller.php:1024
+#: controllers/collections_controller.php:1070
+#: controllers/collections_controller.php:1090
+#, php-format
+msgid "error_missing_argument"
+msgstr "미지정 ì¸ìˆ˜: %s"
+
+#: controllers/components/amo.php:507 controllers/components/amo.php:532
+#, fuzzy
+msgid "error_no_files_in_addon"
+msgstr "No Files"
+
+#: controllers/previews_controller.php:200
+msgid "error_preview_notfound"
+msgstr "미리 보기 ì—†ìŒ!"
+
+#: views/addons/display.thtml:400 views/reviews/add.thtml:98
+msgid "error_review_rating_required"
+msgstr "별ì ì„ ì„ íƒí•˜ì…”야 합니다."
+
+#: controllers/users_controller.php:160
+msgid "error_user_already_confirmed"
+msgstr "ì´ ê³„ì •ì€ ì´ë¯¸ 확ì¸í•˜ì˜€ìŠµë‹ˆë‹¤."
+
+#: controllers/users_controller.php:202 controllers/users_controller.php:276
+#: controllers/users_controller.php:569 controllers/users_controller.php:581
+#: controllers/users_controller.php:587 controllers/users_controller.php:610
+#: controllers/users_controller.php:627
+msgid "error_user_badconfirmationcode"
+msgstr "유효하지 않는 í™•ì¸ ì½”ë“œ!"
+
+#: views/users/pwreset.thtml:79 views/users/register.thtml:75
+#: views/users/edit.thtml:183
+msgid "error_user_confirmpw_nomatch"
+msgstr "암호가 ì¼ì¹˜í•˜ì§€ 않습니다."
+
+#: views/users/register.thtml:65 views/users/edit.thtml:190
+#: controllers/users_controller.php:617
+msgid "error_user_email_notunique"
+msgstr "ì´ë©”ì¼ ì£¼ì†Œê°€ ì´ë¯¸ 다른 사용ìžì— ì˜í•´ 등ë¡ë˜ì–´ 있습니다."
+
+#: controllers/users_controller.php:596
+msgid "error_user_emailchange_expired"
+msgstr ""
+"ë©”ì¼ ì£¼ì†Œ ë³€ê²½ì´ ë§Œë£Œë˜ì—ˆìŠµë‹ˆë‹¤. ì‚¬ìš©ìž í”„ë¡œí•„ì—ì„œ ë©”ì¼ ì£¼ì†Œ ë³€ê²½ì„ ë‹¤ì‹œ 하시"
+"ê³  바로 ë³´ë‚´ 드리는 í™•ì¸ ë©”ì¼ì˜ ë§í¬ë¥¼ 다시 한번 눌러 주세요. "
+
+#: controllers/collections_controller.php:985
+#, fuzzy
+msgid "error_user_exists"
+msgstr ""
+"Users can only have one role at a time. Please remove the user from any "
+"existing roles before continuing."
+
+#: views/users/register.thtml:91 views/users/edit.thtml:116
+#: views/admin/users_edit.thtml:88
+msgid "error_user_nickname_notunique"
+msgstr "누군가가 ì´ë¯¸ ë‹‰ë„¤ìž„ì„ ì‚¬ìš©í•˜ê³  있습니다."
+
+#: views/users/pwreset.thtml:54 controllers/users_controller.php:191
+#: controllers/users_controller.php:270 controllers/users_controller.php:603
+#: controllers/users_controller.php:659
+#: controllers/collections_controller.php:988
+#: controllers/collections_controller.php:998
+msgid "error_user_notfound"
+msgstr "사용ìžê°€ 존재하지 않습니다!"
+
+#: views/users/activatefirst.thtml:47
+msgid "error_user_unconfirmed"
+msgstr "ë‹¹ì‹ ì˜ ê³„ì •ì„ í™•ì¸í•´ 주세요."
+
+#: views/users/login.thtml:67
+msgid "error_username_or_pw_wrong"
+msgstr "ìž˜ëª»ëœ ì‚¬ìš©ìž ì´ë¦„ì´ë‚˜ 암호입니다!"
+
+#: controllers/editors_controller.php:260
+msgid "error_version_notfound"
+msgstr "ë²„ì „ì„ ì°¾ì„ ìˆ˜ 없습니다."
+
+#: views/users/delete.thtml:125 views/users/edit.thtml:173
+msgid "error_wrong_password"
+msgstr "ìž˜ëª»ëœ ì•”í˜¸ìž…ë‹ˆë‹¤!"
+
+#: views/elements/amo2009/homepage_addon.thtml:122
+#: views/elements/feature.thtml:122
+msgid "feature_learnmore"
+msgstr "ìžì„¸ížˆ 보기"
+
+# %1 is the add-on name
+#. %1 is the add-on name
+#: views/elements/amo2009/homepage_addon.thtml:123
+#: views/elements/feature.thtml:123
+#, php-format
+msgid "feature_learnmore_about_addon"
+msgstr "%1$s ìžì„¸ížˆ 보기"
+
+#. %1$s is a number
+#: views/elements/amo2009/reviews.thtml:52
+#: views/elements/addon_listitem.thtml:112 views/elements/feature.thtml:99
+#: views/addons/browse_thumbs.thtml:86
+#, php-format
+msgid "feature_reviews"
+msgid_plural "feature_reviews"
+msgstr[0] "í‰ê°€ %1$sê°œ"
+msgstr[1] "í‰ê°€ %1$sê°œ"
+
+#: views/elements/amo2009/homepage_addon.thtml:127
+#: views/elements/feature.thtml:127
+msgid "feature_view_more_from_category"
+msgstr "ìžì„¸ížˆ 보기"
+
+#. This appears on a page that views the source of an add-on. This link will return
+#. the user to the add-on's main page
+#: views/files/browse.thtml:65
+#, fuzzy
+msgid "file_browser_link_addon"
+msgstr "Back to add-on"
+
+#. There is a list of directories and files on the page. Clicking this will show the
+#. contents of all the directories (normally you would click on each one to see the
+#. contents)
+#: views/files/browse.thtml:67
+#, fuzzy
+msgid "file_browser_link_expand_all"
+msgstr "Expand all"
+
+#. This appears on a page that views the source of an add-on. This link will return
+#. the user to the add-on's review page (it only appears if the add-on is being
+#. reviewed)
+#: views/files/browse.thtml:64
+#, fuzzy
+msgid "file_browser_link_review"
+msgstr "Back to review"
+
+#. The title of the page for viewing an add-on's source.
+#. %1$s is the name of the add-on
+#. %2$s is the name of the current application (e.g. Firefox or Thunderbird)
+#: views/files/browse.thtml:46
+#, fuzzy
+msgid "file_browser_title"
+msgstr "%1$s :: File Browser :: %2$s Add-ons"
+
+#. This appears on a page that views the source of an add-on. There is a list of
+#. directories and files on the page. Clicking this link will toggle between an
+#. expanded or a collapsed list. This string should be kept short.
+#: views/files/browse.thtml:68
+#, fuzzy
+msgid "file_browser_toggle_expand_collapse"
+msgstr "+/-"
+
+#. Link text for the AMO About page.
+#: views/elements/footer.thtml:72 views/layouts/amo2009.thtml:341
+#, fuzzy
+msgid "footer_a_about"
+msgstr "About"
+
+#. Link text to the AMO blog.
+#: views/elements/footer.thtml:74 views/layouts/amo2009.thtml:343
+#, fuzzy
+msgid "footer_a_blog"
+msgstr "Blog"
+
+#. Link text to the Frequently Asked Questions page.
+#: views/elements/footer.thtml:73 views/layouts/amo2009.thtml:342
+#, fuzzy
+msgid "footer_a_faq"
+msgstr "FAQ"
+
+#. Full text for the FAQ abbreviation.
+#: views/elements/footer.thtml:73 views/pages/collector_features.thtml:72
+#: views/layouts/amo2009.thtml:342
+#, fuzzy
+msgid "footer_abbr_faq"
+msgstr "Frequently Asked Questions"
+
+#: views/elements/footer.thtml:67 views/layouts/amo2009.thtml:336
+msgid "footer_all_rights_reserved"
+msgstr "모든 ê¶Œí•œì„ ì†Œìœ í•©ë‹ˆë‹¤."
+
+#: views/elements/footer.thtml:67 views/layouts/amo2009.thtml:336
+msgid "footer_copyright"
+msgstr "저작권"
+
+#: views/elements/footer.thtml:71 views/layouts/amo2009.thtml:340
+msgid "footer_credits"
+msgstr "ì •ë³´"
+
+#: views/elements/footer.thtml:76 views/layouts/amo2009.thtml:346
+msgid "footer_disclaimer"
+msgstr ""
+"Mozilla는 편ì˜ë¥¼ 위해 ì´ëŸ¬í•œ í”„ë¡œê·¸ëž¨ë“¤ì— ëŒ€í•œ ë§í¬ë¥¼ 제공하고 있지만, ì´ëŸ¬"
+"í•œ 프로그램들과 ê´€ë ¨ëœ ì •ë³´ì— ëŒ€í•˜ì—¬ ì–´ë– í•œ ì±…ìž„ë„ ì§€ì§€ 않습니다. í”„ë¡œê·¸ëž¨ì— "
+"대한 질문ì´ë‚˜ ì˜ê²¬ ë“±ì€ í•´ë‹¹ 프로그램 공급ìžì—게 전달하셔야 합니다."
+
+#: views/elements/footer.thtml:61 views/layouts/amo2009.thtml:332
+msgid "footer_lang_form_lang_submit_go"
+msgstr "ì´ë™"
+
+#: views/elements/footer.thtml:70 views/layouts/amo2009.thtml:339
+msgid "footer_legal_notices"
+msgstr "ë²•ì  ê³µì§€"
+
+# This is the lang code -- should be the same as the dir for this locale.
+#: views/elements/footer.thtml:50 views/layouts/amo2009.thtml:321
+msgid "footer_other_languages"
+msgstr "다른 언어:"
+
+#: views/elements/footer.thtml:69 views/layouts/amo2009.thtml:338
+msgid "footer_privacy_policy"
+msgstr "ê°œì¸ì •ë³´ 보호정책"
+
+#: models/addontype.php:79
+msgid "general_addontype_dict"
+msgstr "사전"
+
+# Plural in this context means many of the add-on type
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:100
+msgid "general_addontype_dict_plural"
+msgstr "사전"
+
+#: models/addontype.php:75
+msgid "general_addontype_extension"
+msgstr "확장 기능"
+
+# Plural in this context means many of the add-on type
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:98
+msgid "general_addontype_extension_plural"
+msgstr "확장 기능"
+
+#: models/addontype.php:85
+msgid "general_addontype_lpaddon"
+msgstr "언어팩(부가 기능)"
+
+# Plural in this context means many of the add-on type
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:103
+msgid "general_addontype_lpaddon_plural"
+msgstr "언어팩(부가기능)"
+
+#: models/addontype.php:83
+msgid "general_addontype_lpapp"
+msgstr "언어팩(프로그램)"
+
+# Plural in this context means many of the add-on type
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:102
+msgid "general_addontype_lpapp_plural"
+msgstr "언어팩(프로그램)"
+
+#: models/addontype.php:87
+msgid "general_addontype_plugin"
+msgstr "플러그ì¸"
+
+# Plural in this context means many of the add-on type
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:104
+msgid "general_addontype_plugin_plural"
+msgstr "플러그ì¸"
+
+#: models/addontype.php:81
+msgid "general_addontype_search"
+msgstr "검색 엔진"
+
+# Plural in this context means many of the add-on type
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:101
+msgid "general_addontype_search_plural"
+msgstr "검색 엔진"
+
+#: models/addontype.php:77
+msgid "general_addontype_theme"
+msgstr "테마"
+
+# Plural in this context means many of the add-on type
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:99
+msgid "general_addontype_theme_plural"
+msgstr "테마"
+
+#: config/language.php:367
+#, fuzzy
+msgid "general_languages_all_locales"
+msgstr "All Locales"
+
+#: views/layouts/amo2009.thtml:249
+#, fuzzy
+msgid "header_brand_name"
+msgstr "Mozilla"
+
+#. %1$s is the application name. Example: Firefox
+#: views/elements/header.thtml:111 views/elements/header.thtml:122
+#: views/layouts/amo2009.thtml:248
+#, php-format
+msgid "header_home_tooltip"
+msgstr "%1$s 홈페ì´ì§€ë¡œ ëŒì•„가기"
+
+#: views/elements/header.thtml:87
+msgid "header_main_firefox_header"
+msgstr "Firefox 부가 기능"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:218
+#, fuzzy
+msgid "header_main_firefox_header_with_logo"
+msgstr ""
+"Add-ons <em>for</em> <img alt=\"Firefox\" src=\"%1$s\" /> <strong>Firefox</"
+"strong>"
+
+#: views/elements/header.thtml:99
+msgid "header_main_header"
+msgstr "부가 기능"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:242
+#, fuzzy
+msgid "header_main_header_with_logo"
+msgstr "Add-ons <img alt=\"Add-ons\" src=\"%1$s\" />"
+
+#: views/elements/header.thtml:90
+msgid "header_main_seamonkey_header"
+msgstr "Seamonkey 부가 기능"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:224
+#, fuzzy
+msgid "header_main_seamonkey_header_with_logo"
+msgstr ""
+"Add-ons <em>for</em> <img alt=\"seamonkey\" src=\"%1$s\" /> "
+"<strong>SeaMonkey</strong>"
+
+#: views/elements/header.thtml:93
+msgid "header_main_sunbird_header"
+msgstr "Sunbird 부가 기능"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:230
+#, fuzzy
+msgid "header_main_sunbird_header_with_logo"
+msgstr ""
+"Add-ons <em>for</em> <img alt=\"sunbird\" src=\"%1$s\" /> <strong>Sunbird</"
+"strong>"
+
+#: views/elements/header.thtml:96
+msgid "header_main_thunderbird_header"
+msgstr "Thunderbird 부가 기능"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:236
+#, fuzzy
+msgid "header_main_thunderbird_header_with_logo"
+msgstr ""
+"Add-ons <em>for</em> <img alt=\"thunderbird\" src=\"%1$s\" /> "
+"<strong>Thunderbird</strong>"
+
+#: views/layouts/amo2009.thtml:205
+#, fuzzy
+msgid "header_navaccess_applications_menu"
+msgstr "Skip to other applications menu"
+
+#: views/layouts/amo2009.thtml:204
+#, fuzzy
+msgid "header_navaccess_categories_menu"
+msgstr "Skip to categories menu"
+
+#: views/layouts/amo2009.thtml:202
+#, fuzzy
+msgid "header_navaccess_main_content"
+msgstr "Skip to main content"
+
+#: views/layouts/amo2009.thtml:203
+#, fuzzy
+msgid "header_navaccess_search_form"
+msgstr "Skip to search form"
+
+#: views/elements/header.thtml:62
+msgid "header_navlink_addons"
+msgstr "부가 기능"
+
+#: views/elements/developers/sidebar.thtml:72
+#: views/elements/developers/myaddons.thtml:50 views/elements/header.thtml:159
+#: views/addons/display.thtml:378
+msgid "header_navlink_login"
+msgstr "로그ì¸"
+
+#: views/elements/header.thtml:156 views/layouts/amo2009.thtml:304
+msgid "header_navlink_logout"
+msgstr "로그아웃"
+
+#: views/elements/header.thtml:145 views/layouts/amo2009.thtml:303
+msgid "header_navlink_myaccount"
+msgstr "내 계정"
+
+#: views/elements/header.thtml:158
+msgid "header_navlink_register"
+msgstr "등ë¡"
+
+#. %1 is the URL to the registration page
+#. %2 is the URL to the login page
+#: views/layouts/amo2009.thtml:278
+#, fuzzy
+msgid "header_navlink_register_or_login"
+msgstr "<a href=\"%1$s\">Register</a> or <a href=\"%2$s\">Log in</a>"
+
+#: views/layouts/amo2009.thtml:285
+#, fuzzy
+msgid "header_navlink_tools"
+msgstr "Tools"
+
+#. %s is the add-on name
+#: views/elements/collections_interactive_addon.thtml:62
+#: views/elements/amo2009/homepage_addon.thtml:77
+#: views/elements/addon_discussionheader.thtml:62
+#: views/elements/addon_listitem.thtml:67 views/elements/feature.thtml:84
+#: views/addons/category_landing.thtml:87 views/addons/browse_thumbs.thtml:60
+#, php-format
+msgid "img_preview_of"
+msgstr "ì´ë¯¸ì§€ %s 미리 보기"
+
+# %1 is the login URL for the link tag
+#. %1 is the login URL for the link tag
+#. %2 is the link to an explanatory page.
+#: views/elements/amo2009/install.thtml:307 views/elements/install.thtml:255
+msgid "install_a_login_to_install"
+msgstr "부가 기능 설치 위해 <a href=\"%1$s\">로그ì¸</a>하기"
+
+#. %1 is the URL for the Experimental Add-ons section of the FAQ page
+#: views/elements/amo2009/install.thtml:283 views/elements/install.thtml:232
+#, fuzzy
+msgid "install_button_confirm_exp_install"
+msgstr ""
+"Let me install this experimental add-on. <a href=\"%1$s\">What's this?</a>"
+
+#. %1$s is the application name. Example: Firefox
+#. %2$s is an optional string used to specify a platform. Example: (Windows)
+#: views/elements/amo2009/install.thtml:128 views/elements/install.thtml:75
+#, php-format
+msgid "install_button_text"
+msgstr "%s %sì— ì¶”ê°€"
+
+# %1 is the add-on name, %2 is the app name
+#. %1 is the add-on name, %2 is the app name
+#: views/elements/amo2009/install.thtml:191
+#: views/elements/amo2009/install.thtml:206
+#: views/elements/amo2009/install.thtml:249
+#: views/elements/amo2009/install.thtml:298 views/elements/install.thtml:150
+#: views/elements/install.thtml:165 views/elements/install.thtml:202
+#: views/elements/install.thtml:246
+#, php-format
+msgid "install_button_title"
+msgstr "%1$s를 %2$sì— ì¶”ê°€"
+
+#. %1$s is the add-on name
+#: views/elements/amo2009/install.thtml:200 views/elements/install.thtml:159
+#, php-format
+msgid "install_download"
+msgstr "%1$s 다운로드"
+
+#: views/elements/amo2009/install.thtml:147 views/elements/install.thtml:94
+msgid "install_error_addon_not_found"
+msgstr "검색 결과가 없습니다!"
+
+#: views/addons/dictionaries.thtml:65
+msgid "langtools_a11y_tablesummary"
+msgstr "언어팩 ë° ë§žì¶¤ë²• 사전 목ë¡"
+
+#: views/addons/dictionaries.thtml:47
+msgid "langtools_download_dictionary"
+msgstr "맞춤법 사전 다운로드"
+
+#: views/addons/dictionaries.thtml:48
+msgid "langtools_download_langpack"
+msgstr "언어팩 다운로드"
+
+#: views/addons/dictionaries.thtml:63 controllers/components/amo.php:685
+#: controllers/addons_controller.php:1239
+msgid "langtools_header_dicts_and_langpacks"
+msgstr "맞춤법 사전 ë° ì–¸ì–´íŒ©"
+
+#: views/addons/dictionaries.thtml:44
+msgid "langtools_install_dictionary"
+msgstr "맞춤법 사전 설치"
+
+#: views/addons/dictionaries.thtml:45
+msgid "langtools_install_langpack"
+msgstr "언어팩 설치"
+
+#: views/addons/dictionaries.thtml:69
+msgid "langtools_tableheader_dictionary"
+msgstr "맞춤법 사전"
+
+#: views/addons/dictionaries.thtml:70
+msgid "langtools_tableheader_langpack"
+msgstr "언어팩"
+
+#: views/addons/dictionaries.thtml:68
+msgid "langtools_tableheader_language"
+msgstr "언어별"
+
+#: models/license.php:65
+#, fuzzy
+msgid "license_custom"
+msgstr "Custom License"
+
+#: config/bootstrap.php:303
+#, fuzzy
+msgid "licenses_bsd"
+msgstr "BSD License"
+
+#: config/bootstrap.php:298
+#, fuzzy
+msgid "licenses_gpl_2.0"
+msgstr "GNU General Public License, version 2.0"
+
+#: config/bootstrap.php:299
+#, fuzzy
+msgid "licenses_gpl_3.0"
+msgstr "GNU General Public License, version 3.0"
+
+#: config/bootstrap.php:300
+#, fuzzy
+msgid "licenses_lgpl_2.1"
+msgstr "GNU Lesser General Public License, version 2.1"
+
+#: config/bootstrap.php:301
+#, fuzzy
+msgid "licenses_lgpl_3.0"
+msgstr "GNU Lesser General Public License, version 3.0"
+
+#: config/bootstrap.php:302
+#, fuzzy
+msgid "licenses_mit"
+msgstr "MIT/X11 License"
+
+#: config/bootstrap.php:297
+#, fuzzy
+msgid "licenses_mpl_1.1"
+msgstr "Mozilla Public License, version 1.1"
+
+#: views/users/emailchange.thtml:51 views/users/delete.thtml:55
+#: views/users/delete.thtml:137 views/users/edit.thtml:74
+#: views/reviews/flag.thtml:54
+msgid "link_return_to_front_page"
+msgstr "첫화면으로 가려면 여기를 누르세요."
+
+#: views/elements/amo2009/addon_list_options.thtml:46
+#: views/elements/addon_list_options.thtml:46
+msgid "list_sortby_date"
+msgstr "날짜"
+
+#: views/elements/amo2009/addon_list_options.thtml:47
+#: views/elements/addon_list_options.thtml:47
+msgid "list_sortby_downloads"
+msgstr "다운로드 횟수"
+
+#: views/elements/amo2009/addon_list_options.thtml:45
+#: views/elements/addon_list_options.thtml:45
+msgid "list_sortby_name"
+msgstr "부가 기능명"
+
+#: views/elements/amo2009/addon_list_options.thtml:48
+#: views/elements/addon_list_options.thtml:48
+msgid "list_sortby_rating"
+msgstr "í‰ê°€"
+
+#: config/bootstrap.php:278
+#, fuzzy
+msgid "main_prettyname_fennec"
+msgstr "Fennec"
+
+#: config/bootstrap.php:274
+#, fuzzy
+msgid "main_prettyname_firefox"
+msgstr "Firefox"
+
+#: config/bootstrap.php:277
+#, fuzzy
+msgid "main_prettyname_seamonkey"
+msgstr "SeaMonkey"
+
+#: config/bootstrap.php:276
+#, fuzzy
+msgid "main_prettyname_sunbird"
+msgstr "Sunbird"
+
+#: config/bootstrap.php:275
+#, fuzzy
+msgid "main_prettyname_thunderbird"
+msgstr "Thunderbird"
+
+#: views/elements/addon_categories.thtml:52
+msgid "nav_category_dicts_langpacks"
+msgstr "언어팩 ë° ë§žì¶¤ë²• 사전 목ë¡"
+
+#: views/elements/addon_categories.thtml:55
+msgid "nav_category_themes"
+msgstr "테마"
+
+#: views/elements/app_chooser.thtml:47 views/layouts/amo2009.thtml:255
+msgid "other_apps_tooltip"
+msgstr "다른 í”„ë¡œê·¸ëž¨ì„ ìœ„í•œ 부가 기능 찾기"
+
+# In a user list: user 1, user 2, "others"
+#. In a user list: user 1, user 2, "others"
+#: views/helpers/addons_html.php:222
+msgid "other_users"
+msgstr "others"
+
+#: controllers/pages_controller.php:90
+#, fuzzy
+msgid "page_title_appversions"
+msgstr "Application Versions"
+
+#: controllers/pages_controller.php:115
+#, fuzzy
+msgid "page_title_collector"
+msgstr "Add-on Collector"
+
+#: controllers/pages_controller.php:117
+#, fuzzy
+msgid "page_title_collector_faq"
+msgstr "Add-on Collector FAQ"
+
+#: controllers/pages_controller.php:119
+#, fuzzy
+msgid "page_title_collector_features"
+msgstr "Add-on Collector Features"
+
+#: controllers/pages_controller.php:122
+#, fuzzy
+msgid "page_title_collector_firstrun"
+msgstr "Welcome to the Add-on Collector"
+
+#: controllers/pages_controller.php:92
+#, fuzzy
+msgid "page_title_credits"
+msgstr "Credits"
+
+#: controllers/pages_controller.php:113
+#, fuzzy
+msgid "page_title_developer_faq"
+msgstr "Developer FAQ"
+
+#: controllers/pages_controller.php:111
+#, fuzzy
+msgid "page_title_faq"
+msgstr "Frequently Asked Questions"
+
+#: controllers/pages_controller.php:94
+#, fuzzy
+msgid "page_title_fashionyourfirefox_faq"
+msgstr "Fashion your Firefox FAQ"
+
+#: controllers/pages_controller.php:101
+#, fuzzy
+msgid "page_title_policy"
+msgstr "Add-ons Policy"
+
+#: controllers/pages_controller.php:103
+#, fuzzy
+msgid "page_title_privacy"
+msgstr "Mozilla Privacy Policy"
+
+#: controllers/pages_controller.php:105
+#, fuzzy
+msgid "page_title_review_guide"
+msgstr "Review Guidelines"
+
+#: controllers/pages_controller.php:107
+#, fuzzy
+msgid "page_title_sandbox"
+msgstr "Sandbox Review System"
+
+#: controllers/pages_controller.php:109
+#, fuzzy
+msgid "page_title_submissionhelp"
+msgstr "Submission Help"
+
+#: views/pages/appversions.thtml:87
+#, fuzzy
+msgid "pages_appversions_guid"
+msgstr "GUID"
+
+#: views/pages/appversions.thtml:79 controllers/pages_controller.php:90
+msgid "pages_appversions_header"
+msgstr "유효 애플리케ì´ì…˜ 버전"
+
+#: views/pages/appversions.thtml:80
+msgid "pages_appversions_intro"
+msgstr ""
+"Mozilla 부가 기능 사ì´íŠ¸ì— ì œì¶œëœ ë¶€ê°€ ê¸°ëŠ¥ì€ ì•„ëž˜ ì‘ìš© 프로그램 중 하나를 지"
+"ì›í•˜ëŠ” install.rdf 파ì¼ì„ í¬í•¨í•´ì•¼ 합니다. 아래 버전만 사용 가능 합니다."
+
+#. %s is a full <a> tag
+#: views/pages/appversions.thtml:93
+#, php-format
+msgid "pages_appversions_required_files"
+msgstr ""
+"지ì›í•  ì‘ìš© í”„ë¡œê·¸ëž¨ì´ install.rdf를 요구하지 않으면 %sì˜ ìš”ì²­ 항목 중 하나"
+"는 추가하여야 합니다."
+
+#. this is the text inside of an <a> tag for pages_appversions_required_files. This
+#. should be fixed.
+#: views/pages/appversions.thtml:93
+msgid "pages_appversions_required_files_link"
+msgstr "여기"
+
+#: views/pages/appversions.thtml:88
+msgid "pages_appversions_versions"
+msgstr "버전"
+
+#: views/pages/policy.thtml:51
+msgid "pages_policy_sandbox_link"
+msgstr "Sandbox ì •ë³´ 페ì´ì§€"
+
+#: views/elements/pagination.thtml:53
+msgid "pagination_next_page"
+msgstr "다ìŒ"
+
+#: views/elements/pagination.thtml:52
+msgid "pagination_previous_page"
+msgstr "ì´ì „"
+
+#: views/elements/recaptcha.thtml:65
+msgid "recaptcha_enter_both_words"
+msgstr ""
+"<strong>ë‘ ê°œ 단어</strong>를 <strong>공백으로 분리</strong>í•´ì„œ 입력하세요."
+
+#: views/elements/recaptcha.thtml:83
+msgid "recaptcha_enter_here"
+msgstr "코드 입력:"
+
+#: views/elements/recaptcha.thtml:74
+#, fuzzy
+msgid "recaptcha_enter_whatyouhear"
+msgstr "Please type what you hear."
+
+# %1 is the link switching refreshing the captcha
+# %2 is the link switching to a text captcha
+#. %1 is the link switching refreshing the captcha
+#. %2 is the link switching to a text captcha
+#: views/elements/recaptcha.thtml:77
+#, fuzzy
+msgid "recaptcha_hardtohear_text"
+msgstr ""
+"If this is hard to understand, you can <a href=\"%1$s\">listen to something "
+"else</a> or <a href=\"%2$s\">switch back to text</a>."
+
+# %1 is the link switching refreshing the captcha
+# %2 is the link switching to an audio captcha
+#. %1 is the link switching refreshing the captcha
+#. %2 is the link switching to an audio captcha
+#: views/elements/recaptcha.thtml:68
+#, fuzzy
+msgid "recaptcha_hardtoread_text"
+msgstr ""
+"If this is hard to read, you can <a href=\"%1$s\">try different words</a> or "
+"<a href=\"%2$s\">listen to something</a> instead."
+
+#: views/users/register.thtml:105
+msgid "recaptcha_label"
+msgstr "스팸 차단용 기능"
+
+#: views/users/register.thtml:106
+msgid "recaptcha_whatsthis"
+msgstr "기능 소개"
+
+#: controllers/reviews_controller.php:559
+msgid "review_flag_error"
+msgstr "리뷰 올리기 실패!"
+
+#: models/reviews_moderation_flag.php:69
+#, fuzzy
+msgid "review_flag_reason_bug_support"
+msgstr "Misplaced bug report or support request"
+
+#: views/reviews/display.thtml:103 views/reviews/display.thtml:186
+#, fuzzy
+msgid "review_flag_reason_instructions"
+msgstr "Report this review (select a reason)"
+
+#: models/reviews_moderation_flag.php:67
+#, fuzzy
+msgid "review_flag_reason_language"
+msgstr "Inappropriate language/dialog"
+
+#: models/reviews_moderation_flag.php:71
+#, fuzzy
+msgid "review_flag_reason_other"
+msgstr "Other (please specify)"
+
+#: models/reviews_moderation_flag.php:65
+#, fuzzy
+msgid "review_flag_reason_spam"
+msgstr "Spam or otherwise non-review content"
+
+#: views/reviews/display.thtml:91 views/reviews/display.thtml:175
+#: controllers/reviews_controller.php:555
+msgid "review_flag_success"
+msgstr "ê°ì‚¬í•©ë‹ˆë‹¤. 리뷰가 편집ìžì—게 전달ë˜ì—ˆìŠµë‹ˆë‹¤."
+
+#: views/reviews/display.thtml:41
+msgid "review_flag_this"
+msgstr "리뷰 올리기"
+
+#: views/reviews/display.thtml:42
+msgid "review_flag_this_titletip"
+msgstr ""
+"현재 리뷰가 부ì ì ˆí•˜ê±°ë‚˜ 스팸입니까? 그렇다면 íŽ¸ì§‘ìž ë¦¬ë·° ìš”ì²­ì„ í•˜ì‹­ì‹œì˜¤."
+
+# %1 is the URL of the support section, %2 for the review guidelines
+#. %1 is the URL of the support section, %2 for the review guidelines
+#: views/reviews/add.thtml:53
+msgid "review_guidelines_short"
+msgstr ""
+"<p>ì£¼ì˜ ì‚¬í•­</p><ul><li>부가 ê¸°ëŠ¥ì„ ì“¸ 친구ì—게 ì¡°ì–¸ í•˜ë“¯ì´ ì ì–´ì£¼ì‹­ì‹œì˜¤. ì–´"
+"ë–¤ ê¸°ëŠ¥ì´ ì¢‹ì€ì§€ í˜¹ì€ ë‚˜ìœì§€ë¥¼ ìƒì„¸í•œ 기능 위주로 ì ì–´ 주시면 ë” ì¢‹ìŠµë‹ˆë‹¤. ë˜"
+"í•œ 사용하면 ë„ì›€ì´ ë˜ëŠ” 기능 ë° ë¶ˆíŽ¸í•œ ê¸°ëŠ¥ì„ í•¨ê»˜ ì ì–´ 주시고 \"멋지다!\" "
+"or \"나ì˜ë‹¤\" ê°™ì€ ì¼ë°˜ì ì¸ 단어 보다는 ì´ìœ ë¥¼ ì ì–´ 주십시오.</li><li>부가 기"
+"능 ì´ìš© 중 ë°œìƒí•œ 프로그램 버그를 ì—¬ê¸°ì— ì ì§€ 마시기 ë°”ëžë‹ˆë‹¤. 개발ìžì—게 ì—¬"
+"ëŸ¬ë¶„ì˜ ì´ë©”ì¼ ì£¼ì†Œê°€ 전달 ë˜ì§€ 않기 ë•Œë¬¸ì— ê²°ê³¼ë¥¼ ì–»ì„ ìˆ˜ 없습니다. <a href="
+"\"%1$s\">기술 지ì›</a> í•­ëª©ì„ ì°¾ì•„ ì§ì ‘ ì—°ë½í•´ 주십시오.</li><li>작성한 리뷰"
+"ì— ê°œì¸ ì •ë³´ë¥¼ 담거나 올바르지 않는 ë‚´ìš© ë° í…ŒìŠ¤íŠ¸ì„± ë‚´ìš©ì„ ë‹´ì§€ 마십시오.</"
+"li></ul><p>ë” ìƒì„¸í•œ 정보는 <a href=\"%2$s\">리뷰 ê°€ì´ë“œë¼ì¸</a>ì„ ì°¸ê³ í•˜ì‹œ"
+"기 ë°”ëžë‹ˆë‹¤. </p>"
+
+#. %1 is the add-on name
+#: views/reviews/flag.thtml:56 views/reviews/display.thtml:55
+#: views/reviews/review_added.thtml:50
+#, php-format
+msgid "reviews_header"
+msgstr "%sì— ëŒ€í•œ í‰ê°€"
+
+#: controllers/addons_controller.php:435
+msgid "rss_featuredaddons"
+msgstr "주요 부가 기능"
+
+#: controllers/addons_controller.php:432
+msgid "rss_newestaddons"
+msgstr "새 부가 기능"
+
+#: controllers/addons_controller.php:434
+#, fuzzy
+msgid "rss_popularaddons"
+msgstr "Popular Add-ons"
+
+#: controllers/addons_controller.php:433
+msgid "rss_updatedaddons"
+msgstr "최근 ì—…ë°ì´íŠ¸"
+
+#: views/elements/search_mini.thtml:70
+#, fuzzy
+msgid "search"
+msgstr "Search"
+
+#: views/search/collections.thtml:51
+#, fuzzy
+msgid "search_collections_header"
+msgstr "Collection Search Results"
+
+#: controllers/search_controller.php:297
+#, fuzzy
+msgid "search_collections_pagetitle"
+msgstr "Collection Search Results"
+
+#: controllers/search_controller.php:99
+msgid "search_disabled"
+msgstr "현재 검색 ê¸°ëŠ¥ì„ ì‚¬ìš©í•  수 없습니다. 다시 한번 ì‹œë„í•´ 주세요."
+
+#: views/elements/amo2009/search.thtml:188 views/elements/search.thtml:187
+#: views/elements/search_mini.thtml:54
+msgid "search_form_all_addons"
+msgstr "전체 부가 기능"
+
+#. This string is in the main category dropdown when searching
+#: views/elements/amo2009/search.thtml:204
+#, fuzzy
+msgid "search_form_all_collections"
+msgstr "all collections"
+
+#: views/elements/amo2009/search.thtml:184
+#: views/elements/amo2009/search.thtml:385
+#: views/elements/amo2009/search.thtml:408 views/elements/search.thtml:171
+#: views/elements/search.thtml:183 views/elements/search_mini.thtml:43
+#: views/elements/search_mini.thtml:49 views/layouts/mozilla.thtml:188
+msgid "search_form_default_text"
+msgstr "부가 기능 검색"
+
+#: views/elements/amo2009/search.thtml:184
+#: views/elements/amo2009/search.thtml:404
+#, fuzzy
+msgid "search_form_default_text_collections"
+msgstr "search for collections"
+
+#: views/elements/amo2009/search.thtml:206 views/elements/search.thtml:202
+msgid "search_form_submit_tooltip"
+msgstr "부가 기능 검색"
+
+#: views/elements/amo2009/search.thtml:184 views/elements/search.thtml:183
+#: views/elements/search_mini.thtml:49
+msgid "search_form_tooltip"
+msgstr "검색어 입력해주세요!"
+
+#: views/elements/amo2009/search.thtml:186 views/elements/search.thtml:185
+#: views/elements/search_mini.thtml:52
+msgid "search_form_within"
+msgstr "í¬í•¨"
+
+#: views/addons/searchengines.thtml:118
+msgid "search_landing_all_search_engines"
+msgstr "ì „ì²´ 검색 사ì´íŠ¸"
+
+#: views/addons/searchengines.thtml:114
+msgid "search_landing_browse_search_engines"
+msgstr "검색 사ì´íŠ¸ 보기"
+
+#: views/search/collections.thtml:58 views/search/index.thtml:59
+msgid "search_nothing_found"
+msgstr "검색 결과가 ì—†ìŒ."
+
+#: controllers/search_controller.php:185
+msgid "search_pagetitle"
+msgstr "부가 기능 검색"
+
+#: controllers/search_controller.php:242
+msgid "search_rss_description"
+msgstr "검색 결과 RSS 피드"
+
+#. %s is the terms the user is searching for (a string)
+#: controllers/search_controller.php:241
+#, php-format
+msgid "search_rss_results_for"
+msgstr "검색 결과: %s"
+
+#: views/elements/header.thtml:154 views/layouts/amo2009.thtml:296
+msgid "sidebar_navlink_admin_tools"
+msgstr "관리 ë„구"
+
+#: views/elements/header.thtml:146 views/layouts/amo2009.thtml:288
+msgid "sidebar_navlink_developer_tools"
+msgstr "개발 ë„구"
+
+#: views/elements/header.thtml:148 views/layouts/amo2009.thtml:290
+msgid "sidebar_navlink_editor_tools"
+msgstr "관리 ë„구"
+
+#: views/layouts/amo2009.thtml:302
+msgid "sidebar_navlink_welcome"
+msgstr "환ì˜í•©ë‹ˆë‹¤"
+
+#. %s is the user's name
+#: views/layouts/amo2009.thtml:302
+#, php-format
+msgid "sidebar_navlink_welcome_name"
+msgstr "환ì˜í•©ë‹ˆë‹¤, %s"
+
+#: views/elements/pitch.thtml:50 views/elements/pitch.thtml:55
+msgid "sidebar_pitch_dictionary"
+msgstr "맞춤법 사전"
+
+#: views/elements/pitch.thtml:72
+msgid "sidebar_pitch_featured_addons"
+msgstr "추천 항목"
+
+#: views/elements/pitch.thtml:61
+msgid "sidebar_pitch_looking_for"
+msgstr "찾기:"
+
+#: views/elements/pitch.thtml:70
+msgid "sidebar_pitch_newest_addons"
+msgstr "최신 항목"
+
+#: views/elements/pitch.thtml:49
+msgid "sidebar_pitch_search"
+msgstr "검색 플러그ì¸"
+
+#: views/elements/pitch.thtml:69
+msgid "sidebar_pitch_subscribe_to"
+msgstr "구ë…하기"
+
+#: views/elements/pitch.thtml:48 views/elements/pitch.thtml:54
+msgid "sidebar_pitch_theme"
+msgstr "테마"
+
+#: views/elements/pitch.thtml:71
+msgid "sidebar_pitch_updated_addons"
+msgstr "최근 ì—…ë°ì´íŠ¸ 항목"
+
+#. %1$s is a number
+#: views/helpers/localization.php:65 views/developers/versions_edit.thtml:95
+#: views/addons/dictionaries.thtml:92
+#, php-format
+msgid "size_kb"
+msgstr "%1$s KB"
+
+#: views/elements/amo2009/stars.thtml:57 views/elements/stars.thtml:63
+msgid "stars_not_yet_rated"
+msgstr "ì•„ì§ í‰ê°€ ì—†ìŒ"
+
+# %1 is the number of stars this add-on has
+#. %1 is the number of stars this add-on has
+#: views/elements/amo2009/stars.thtml:49 views/elements/stars.thtml:54
+#, php-format
+msgid "stars_rated_x_outof_5"
+msgstr "5ì  ì¤‘ %së¡œ í‰ê°€"
+
+#: views/statistics/addon.thtml:59
+msgid "statistics_addon_dashboard_link"
+msgstr "대시보드 홈페ì´ì§€"
+
+#: views/statistics/addon.thtml:58
+msgid "statistics_addon_developertools_link"
+msgstr "ê°œë°œìž ë„구"
+
+#: views/statistics/addon.thtml:53
+msgid "statistics_addon_switch"
+msgstr "부가 기능 전환"
+
+#. This is a date format.
+#. http://php.net/strftime
+#: views/statistics/rss/summary.thtml:54 views/statistics/addon.thtml:181
+msgid "statistics_date_shortmonth"
+msgstr "F jì¼"
+
+#. This is a date format.
+#. http://php.net/strftime
+#: views/statistics/rss/summary.thtml:40 views/statistics/addon.thtml:152
+msgid "statistics_date_shortmonthwithyear"
+msgstr "Yë…„ F jì¼"
+
+#. This is a date format.
+#. http://php.net/strftime
+#: views/statistics/rss/summary.thtml:41 views/statistics/rss/summary.thtml:48
+#: views/statistics/addon.thtml:161 views/statistics/addon.thtml:172
+msgid "statistics_date_weekdayshortmonth"
+msgstr "Y F j"
+
+#. %1$s is an add-on name and version. Example: Add-on 3.5
+#: controllers/components/stats.php:519
+#, php-format
+msgid "statistics_events_addon_created"
+msgstr "%1$s 만듬"
+
+#. %1$s is an application name and version. Example: Firefox 3.5
+#: controllers/components/stats.php:500
+#, php-format
+msgid "statistics_events_app_released"
+msgstr "%1$s 출시"
+
+#: views/statistics/addon.thtml:71
+msgid "statistics_help_close_link"
+msgstr "닫기"
+
+#: views/statistics/addon.thtml:60
+msgid "statistics_help_link"
+msgstr "ë„움ë§"
+
+#: views/statistics/index.thtml:83
+msgid "statistics_index_anotheraddon"
+msgstr "다른 부가 기능 ì„ íƒ"
+
+#: views/statistics/index.thtml:85
+msgid "statistics_index_anotheraddon_public"
+msgstr "통계가 제공ë˜ëŠ” 부가 기능 ì„ íƒ"
+
+#: views/statistics/index.thtml:71
+msgid "statistics_index_myaddons"
+msgstr "통계 조회할 ë‚´ 부가 기능 ì„ íƒ"
+
+#: views/statistics/index.thtml:89
+msgid "statistics_index_selectaddon"
+msgstr "통계 조회할 부가 기능 ì„ íƒ"
+
+#: views/statistics/index.thtml:91
+msgid "statistics_index_selectaddon_public"
+msgstr "통계가 ê³µê°œëœ ë¶€ê°€ 기능 ì„ íƒ"
+
+#: views/statistics/index.thtml:39
+msgid "statistics_index_title"
+msgstr "통계 대시보드"
+
+#: views/statistics/index.thtml:97
+msgid "statistics_index_view_button"
+msgstr "통계 보기"
+
+#: views/statistics/addon.thtml:222 controllers/statistics_controller.php:247
+#, fuzzy
+msgid "statistics_js_download_csv"
+msgstr "View this table in CSV format"
+
+#: controllers/statistics_controller.php:246
+msgid "statistics_js_dropdowns_none"
+msgstr "ì—†ìŒ"
+
+#: controllers/statistics_controller.php:245
+msgid "statistics_js_dropdowns_removeplot"
+msgstr "현재 통계 삭제"
+
+#: controllers/statistics_controller.php:248
+#, fuzzy
+msgid "statistics_js_groupby_selector_date"
+msgstr "Group by: Day"
+
+#: controllers/statistics_controller.php:251
+#, fuzzy
+msgid "statistics_js_groupby_selector_month"
+msgstr "Group by: Month"
+
+#: controllers/statistics_controller.php:249
+#, fuzzy
+msgid "statistics_js_groupby_selector_week"
+msgstr "Group by: Week"
+
+#: controllers/statistics_controller.php:250
+#, fuzzy
+msgid "statistics_js_groupby_selector_week_over_week"
+msgstr "Compare by: Week"
+
+#: controllers/statistics_controller.php:260
+msgid "statistics_js_plotselection_foundinrange"
+msgstr "조건 내 %s 조회"
+
+#: controllers/statistics_controller.php:270
+msgid "statistics_js_plotselection_options_addplot_name"
+msgstr "조건 추가"
+
+#: controllers/statistics_controller.php:271
+msgid "statistics_js_plotselection_options_addplot_tooltip"
+msgstr "현재 ê·¸ëž˜í”„ì— ë‹¤ë¥¸ ì¡°ê±´ 추가"
+
+#: controllers/statistics_controller.php:261
+msgid "statistics_js_plotselection_options_count_name_checked"
+msgstr "ì´ íšŸìˆ˜ 숨기기"
+
+#: controllers/statistics_controller.php:262
+msgid "statistics_js_plotselection_options_count_name_unchecked"
+msgstr "ì´ íšŸìˆ˜ ë³´ì´ê¸°"
+
+#: controllers/statistics_controller.php:263
+#, fuzzy
+msgid "statistics_js_plotselection_options_count_tooltip"
+msgstr "Plot the total count on this graph"
+
+#: controllers/statistics_controller.php:275
+msgid "statistics_js_plotselection_options_csv_name"
+msgstr "ë°ì´í„° 보기 (CSV)"
+
+#: controllers/statistics_controller.php:276
+msgid "statistics_js_plotselection_options_csv_tooltip"
+msgstr "쉼표 ë¶„ë¦¬ëœ ë°ì´í„° 형ì‹ìœ¼ë¡œ 보기"
+
+#: controllers/statistics_controller.php:267
+msgid "statistics_js_plotselection_options_events_addon_name_checked"
+msgstr "%s ì´ë²¤íŠ¸ 숨기기"
+
+#: controllers/statistics_controller.php:268
+msgid "statistics_js_plotselection_options_events_addon_name_unchecked"
+msgstr "%s ì´ë²¤íŠ¸ ë³´ì´ê¸°"
+
+#: controllers/statistics_controller.php:269
+msgid "statistics_js_plotselection_options_events_addon_tooltip"
+msgstr "범위 ë‚´ ì¶œì‹œì¼ í‘œì‹œ"
+
+#: controllers/statistics_controller.php:264
+msgid "statistics_js_plotselection_options_events_firefox_name_checked"
+msgstr "Firefox ì´ë²¤íŠ¸ 숨기기"
+
+#: controllers/statistics_controller.php:265
+msgid "statistics_js_plotselection_options_events_firefox_name_unchecked"
+msgstr "Firefox ì´ë²¤íŠ¸ ë³´ì´ê¸°"
+
+#: controllers/statistics_controller.php:266
+msgid "statistics_js_plotselection_options_events_firefox_tooltip"
+msgstr "범위 ë‚´ Firefox ì¶œì‹œì¼ í‘œì‹œ"
+
+#: controllers/statistics_controller.php:272
+msgid "statistics_js_plotselection_options_resize_name_checked"
+msgstr "그래프 닫기"
+
+#: controllers/statistics_controller.php:273
+msgid "statistics_js_plotselection_options_resize_name_unchecked"
+msgstr "그래프 확장"
+
+#: controllers/statistics_controller.php:274
+msgid "statistics_js_plotselection_options_resize_tooltip"
+msgstr "그래프 í¬ê¸° 변경"
+
+#: controllers/statistics_controller.php:254
+msgid "statistics_js_plotselection_selector_adu"
+msgstr "ì¼ì¼ ì‚¬ìš©ìž ìˆ˜"
+
+#: controllers/statistics_controller.php:256
+msgid "statistics_js_plotselection_selector_application"
+msgstr "프로그램"
+
+#: controllers/statistics_controller.php:259
+msgid "statistics_js_plotselection_selector_custom"
+msgstr "기타"
+
+#: controllers/statistics_controller.php:253
+msgid "statistics_js_plotselection_selector_downloads"
+msgstr "다운로드 횟수"
+
+#: controllers/statistics_controller.php:258
+msgid "statistics_js_plotselection_selector_os"
+msgstr "ìš´ì˜ ì²´ì œ"
+
+#: controllers/statistics_controller.php:257
+msgid "statistics_js_plotselection_selector_status"
+msgstr "부가 기능 ìƒíƒœ"
+
+#: controllers/statistics_controller.php:252
+msgid "statistics_js_plotselection_selector_summary"
+msgstr "요약 정보"
+
+#: controllers/statistics_controller.php:255
+msgid "statistics_js_plotselection_selector_version"
+msgstr "버전"
+
+#: controllers/components/stats.php:398
+msgid "statistics_longnames_application"
+msgstr "프로그램"
+
+#: controllers/components/stats.php:400
+msgid "statistics_longnames_os"
+msgstr "ìš´ì˜ ì²´ì œ"
+
+#: controllers/components/stats.php:399
+msgid "statistics_longnames_status"
+msgstr "부가 기능 ìƒíƒœ"
+
+#: controllers/components/stats.php:401
+msgid "statistics_longnames_unknown"
+msgstr "ì•Œ 수 ì—†ìŒ"
+
+#: controllers/components/stats.php:397
+msgid "statistics_longnames_version"
+msgstr "부가 기능 버전"
+
+#: views/statistics/addon.thtml:118
+msgid "statistics_notice_data_insufficient"
+msgstr "그래프로 í‘œì‹œí•˜ê¸°ì— ë°ì´í„°ì–‘ì´ ì ìŠµë‹ˆë‹¤. ë‚˜ì¤‘ì— ë‹¤ì‹œ 확ì¸í•´ 주십시오."
+
+#: views/statistics/addon.thtml:130
+msgid "statistics_notice_data_none"
+msgstr "부가 기능 통계 ì •ë³´ê°€ ì•„ì§ ì—†ìŠµë‹ˆë‹¤. ë©°ì¹  후 확ì¸í•´ 주십시오."
+
+#: views/statistics/addon.thtml:41
+msgid "statistics_notice_data_updating"
+msgstr ""
+"부가 기능 통계 ê¸°ëŠ¥ì€ ì—…ë°ì´íŠ¸ 중입니다. ìž‘ì—… 중 최근 ë°ì´í„°ëŠ” 정확지 ì•Šì„ "
+"수 있습니다. 몇 분 í›„ì— ë‹¤ì‹œ 확ì¸í•´ 주시기 ë°”ëžë‹ˆë‹¤. "
+
+#: views/statistics/addon.thtml:136
+msgid "statistics_notice_disabled"
+msgstr "통계 대시보드는 현재 사용할 수 없습니다. ë‚˜ì¤‘ì— ë‹¤ì‹œ 확ì¸í•´ 주십시오."
+
+#: views/statistics/addon.thtml:123
+msgid "statistics_notice_nojavascript"
+msgstr "통계 대시보드를 보려면 ìžë°”스í¬ë¦½íŠ¸ê°€ 켜져 있어야 합니다."
+
+#: views/statistics/addon.thtml:44
+msgid "statistics_notice_settings_updated"
+msgstr "ì„¤ì •ì´ ì—…ë°ì´íŠ¸ ë˜ì—ˆìŠµë‹ˆë‹¤!"
+
+#: controllers/statistics_controller.php:60
+#: controllers/statistics_controller.php:71
+#: controllers/statistics_controller.php:74
+#: controllers/statistics_controller.php:240
+msgid "statistics_pagetitle"
+msgstr "통계 대시보드"
+
+#: views/statistics/addon.thtml:99
+msgid "statistics_plot_legend_adu"
+msgstr "ì¼ê°„ 사용ìž"
+
+#: views/statistics/addon.thtml:95
+msgid "statistics_plot_legend_downloads"
+msgstr "ì¼ê°„ 다운로드"
+
+#: views/statistics/addon.thtml:107
+msgid "statistics_plot_options_zoomin_alt"
+msgstr "ìžì„¸ížˆ 보기"
+
+#: views/statistics/addon.thtml:106
+msgid "statistics_plot_options_zoomin_title"
+msgstr "한달로 보기"
+
+#: views/statistics/addon.thtml:110
+msgid "statistics_plot_options_zoomout_alt"
+msgstr "간략히 보기"
+
+#: views/statistics/addon.thtml:109
+msgid "statistics_plot_options_zoomout_title"
+msgstr "한달로 보기"
+
+#: controllers/statistics_controller.php:283
+#, php-format
+msgid "statistics_rss_description"
+msgstr "ì¼ê°„ 통계 요약: %1$s"
+
+#: views/statistics/rss/summary.thtml:68
+msgid "statistics_rss_title_fulldate"
+msgstr "Yë…„ F jì¼"
+
+#: views/statistics/rss/summary.thtml:68
+#, php-format
+msgid "statistics_rss_title_statsfordate"
+msgstr "통계 : %1$s"
+
+#: views/statistics/settings.thtml:49
+msgid "statistics_settings_access_description"
+msgstr ""
+"기본ì ìœ¼ë¡œ 개발ìžì™€ 관리ìžë§Œì´ 대시 ë³´ë“œì— ì ‘ì†í•  수 있으며 다른 사용ìžê°€ 부"
+"ê°€ 기능 정보를 ë” ë³´ë„ë¡ í•˜ë ¤ë©´ 아래 ì„¤ì •ì„ ë³€ê²½í•˜ì‹­ì‹œì˜¤."
+
+#: views/statistics/settings.thtml:48
+msgid "statistics_settings_access_heading"
+msgstr "대시보드 ì ‘ì† í—ˆê°€"
+
+#: views/statistics/settings.thtml:51
+msgid "statistics_settings_access_private"
+msgstr "비공개"
+
+#: views/statistics/settings.thtml:51
+msgid "statistics_settings_access_private_description"
+msgstr "ê°œë°œìž ë° ê´€ë¦¬ìžë§Œ ë³¼ 수 있ìŒ"
+
+#: views/statistics/settings.thtml:52
+msgid "statistics_settings_access_public"
+msgstr "공개"
+
+#: views/statistics/settings.thtml:52
+msgid "statistics_settings_access_public_description"
+msgstr "모든 사용ìžê°€ 통계를 볼수 있ìŒ"
+
+#: views/statistics/addon.thtml:251
+msgid "statistics_settings_change_link"
+msgstr "설정 변경"
+
+#: views/statistics/addon.thtml:253
+msgid "statistics_settings_confidential"
+msgstr "아래 정보는 신중하게 입력해 주십시오."
+
+#: views/statistics/addon.thtml:245
+msgid "statistics_settings_currently_private"
+msgstr "현재 대시보드는 <b>비공개 중</b>입니다."
+
+#: views/statistics/addon.thtml:241
+msgid "statistics_settings_currently_public"
+msgstr "현재 대시보드는 <b>공개 중</b>입니다."
+
+#: views/statistics/addon.thtml:246
+msgid "statistics_settings_locked_alt"
+msgstr "처리 중단ë¨"
+
+#: views/statistics/settings.thtml:57
+msgid "statistics_settings_return_link"
+msgstr "ëŒì•„가기"
+
+#: views/statistics/settings.thtml:56
+msgid "statistics_settings_save_button"
+msgstr "설정 저장"
+
+#: views/statistics/settings.thtml:46
+#, php-format
+msgid "statistics_settings_title"
+msgstr "%1$s 통계 설정"
+
+#: views/statistics/addon.thtml:242
+msgid "statistics_settings_unlocked_alt"
+msgstr "처리 중"
+
+#: controllers/components/stats.php:405
+msgid "statistics_shortnames_application"
+msgstr "프로그램"
+
+#: controllers/components/stats.php:407
+msgid "statistics_shortnames_os"
+msgstr "ìš´ì˜ì²´ì œ"
+
+#: controllers/components/stats.php:406
+msgid "statistics_shortnames_status"
+msgstr "ì´ë¦„"
+
+#: controllers/components/stats.php:408
+msgid "statistics_shortnames_unknown"
+msgstr "ì•Œ 수없ìŒ"
+
+#: controllers/components/stats.php:404
+msgid "statistics_shortnames_version"
+msgstr "버전"
+
+#: views/statistics/rss/summary.thtml:42 views/statistics/addon.thtml:192
+msgid "statistics_summary_downloads_average"
+msgstr "í‰ê·  ì¼ì¼ 다운로드 수"
+
+#: views/statistics/rss/summary.thtml:39
+msgid "statistics_summary_downloads_heading"
+msgstr "다운로드 통계"
+
+#: views/statistics/rss/summary.thtml:41 views/statistics/addon.thtml:171
+msgid "statistics_summary_downloads_lastcount"
+msgstr "어제 조회수"
+
+#: views/statistics/rss/summary.thtml:43 views/statistics/addon.thtml:199
+msgid "statistics_summary_downloads_lastweek"
+msgstr "최근 주간 다운로드 수"
+
+#: views/statistics/rss/summary.thtml:40 views/statistics/addon.thtml:151
+msgid "statistics_summary_downloads_total"
+msgstr "ì´ ë‹¤ìš´ë¡œë“œ 횟수"
+
+#: views/statistics/rss/summary.thtml:40 views/statistics/addon.thtml:152
+#, php-format
+msgid "statistics_summary_downloads_total_sincedate"
+msgstr "조회 시작ì¼: %1$s"
+
+#: views/statistics/rss/summary.thtml:50 views/statistics/rss/summary.thtml:56
+#: views/statistics/addon.thtml:163 views/statistics/addon.thtml:183
+msgid "statistics_summary_nodata"
+msgstr "ë°ì´í„°ê°€ ì—†ìŒ"
+
+#: views/statistics/rss/summary.thtml:60 views/statistics/addon.thtml:195
+msgid "statistics_summary_updatepings_average"
+msgstr "í‰ê·  ì¼ì¼ ì‚¬ìš©ìž í†µê³„"
+
+#: views/statistics/rss/summary.thtml:52 views/statistics/addon.thtml:177
+msgid "statistics_summary_updatepings_changefromprevious"
+msgstr "ì´ì „ 조회수 변경"
+
+#: views/statistics/rss/summary.thtml:54 views/statistics/addon.thtml:181
+#, php-format
+msgid "statistics_summary_updatepings_changefromprevious_ondate"
+msgstr "%1$s , 날짜: %2$s"
+
+#: views/statistics/rss/summary.thtml:45
+msgid "statistics_summary_updatepings_heading"
+msgstr "ì¼ì¼ ì‚¬ìš©ìž í†µê³„"
+
+#: views/statistics/rss/summary.thtml:46 views/statistics/addon.thtml:157
+msgid "statistics_summary_updatepings_total"
+msgstr "ì¼ì¼ ì‚¬ìš©ìž í†µê³„"
+
+#: views/statistics/rss/summary.thtml:48 views/statistics/addon.thtml:161
+#, php-format
+msgid "statistics_summary_updatepings_total_ondate"
+msgstr "날짜: %1$s"
+
+#: views/statistics/rss/summary.thtml:61 views/statistics/addon.thtml:203
+#, fuzzy
+msgid "statistics_summary_updatepings_weekly_average"
+msgstr "Average Daily Users this Week"
+
+#. %s is a percentage, like '+22.33%'. It sits next to another number, so
+#. the implied meaning is 'percentage change' from the previous stat point.
+#: views/statistics/rss/summary.thtml:62 views/statistics/addon.thtml:205
+#, fuzzy
+msgid "statistics_summary_updatepings_weekly_change"
+msgstr "%s from last week"
+
+#: views/statistics/addon.thtml:65 controllers/statistics_controller.php:184
+#: controllers/statistics_controller.php:282
+#, php-format
+msgid "statistics_title_addon_stats"
+msgstr "%1$s 통계"
+
+#: views/addons/themes_landing.thtml:113
+msgid "themes_landing_all_themes"
+msgstr "테마 전체 보기"
+
+#: views/addons/themes_landing.thtml:109
+msgid "themes_landing_browse_themes"
+msgstr "테마 검색"
+
+#: views/users/edit.thtml:185
+msgid "user_change_email"
+msgstr "ë©”ì¼ ì£¼ì†Œ 변경"
+
+#: views/users/edit.thtml:169
+msgid "user_change_password"
+msgstr "암호 바꾸기"
+
+#: views/users/edit.thtml:96
+#, fuzzy
+msgid "user_change_password_or_email"
+msgstr "Change Password or Email"
+
+#: controllers/users_controller.php:197
+msgid "user_confirmationcode_resent"
+msgstr "í™•ì¸ ì½”ë“œë¥¼ 보냈습니다!"
+
+# %1 is the email address, %2 is the URL of the user registration page
+#. %1 is the email address, %2 is the URL of the user registration page
+#: views/users/delete.thtml:51
+#, fuzzy
+msgid "user_del_account_deleted"
+msgstr ""
+"Your user account %1$s has been successfully deleted. If you want to come "
+"back some time, you can re-register on the <a href=\"%2$s\">user "
+"registration page</a>."
+
+#: views/users/delete.thtml:102
+#, fuzzy
+msgid "user_del_community_sad"
+msgstr "The Mozilla Add-ons community is sad to see you go."
+
+#: views/users/delete.thtml:123
+#, fuzzy
+msgid "user_del_confirm_password"
+msgstr "Confirm Password"
+
+#: views/users/delete.thtml:134
+#, fuzzy
+msgid "user_del_deletenow"
+msgstr "Delete my user account now"
+
+# %1 is the URL of the user's info page
+#. %1 is the URL of the user's info page
+#: views/users/delete.thtml:64
+#, fuzzy
+msgid "user_del_error_addons"
+msgstr ""
+"You cannot delete your account if you are listed as an <a href=\"%1$s"
+"\">author of any add-ons</a>. To delete your account, please have another "
+"person in your development group delete you from the list of authors for "
+"your add-ons. Afterwards you will be able to delete your account here."
+
+# %1 is a link to the amo-editors mailing list
+#. %1 is a link to the amo-editors mailing list
+#: views/users/delete.thtml:71
+#, fuzzy
+msgid "user_del_error_addons_more_questions"
+msgstr "If you have additional questions, please contact %1$s for assistance."
+
+#: views/users/delete.thtml:78
+#, fuzzy
+msgid "user_del_error_checkbox"
+msgstr ""
+"You need to check the box \"I understand...\" before we can delete your "
+"account."
+
+#: views/users/delete.thtml:84
+#, fuzzy
+msgid "user_del_error_password"
+msgstr "Please enter your password correctly in order to perform this step."
+
+# %1 is a link to the amo-admins mailing list
+#. %1 is a link to the amo-admins mailing list
+#: views/users/delete.thtml:91
+#, fuzzy
+msgid "user_del_error_unknown"
+msgstr ""
+"An unknown error occured deleting your account. Please contact %1$s with the "
+"issue and we will delete it for you. We apologize for the inconvenience."
+
+#: views/users/delete.thtml:110
+#, fuzzy
+msgid "user_del_header_confirm_deletion"
+msgstr "Confirm account deletion"
+
+# %1 is the user's email address
+#. %1 is the user's email address
+#: views/users/delete.thtml:100
+#, fuzzy
+msgid "user_del_header_delete_account"
+msgstr "Delete User Account %1$s"
+
+#: views/users/delete.thtml:50
+#, fuzzy
+msgid "user_del_header_farewell"
+msgstr "Farewell!"
+
+#: views/users/delete.thtml:115
+#, fuzzy
+msgid "user_del_nologin"
+msgstr "You will not be able to log into Mozilla Add-ons anymore."
+
+#: views/users/delete.thtml:112
+#, fuzzy
+msgid "user_del_permanently_removed_means"
+msgstr ""
+"By clicking \"delete\" your account is going to be <strong>permanently "
+"removed</strong>. That means:"
+
+#: views/users/delete.thtml:116
+#, fuzzy
+msgid "user_del_reviews_anonymized"
+msgstr ""
+"Your reviews and ratings will not be deleted, but they will no longer be "
+"associated with you."
+
+# %1 is a link to the amo-editors mailing list
+#. %1 is a link to the amo-editors mailing list
+#: views/users/delete.thtml:104
+#, fuzzy
+msgid "user_del_specific_problem_editors"
+msgstr ""
+"If you have a specific problem we may help you with, please do not delete "
+"your account now, but contact us at %1$s and we will do our best to assist "
+"you in solving it."
+
+#: views/users/delete.thtml:130
+#, fuzzy
+msgid "user_del_understand_permanent"
+msgstr "I understand that this step cannot be undone."
+
+#: views/helpers/addons_html.php:192
+#, fuzzy
+msgid "user_deleted_nickname"
+msgstr "Deleted User"
+
+# %1 is the new email address
+#. %1 is the new email address
+#: views/users/edit.thtml:71
+msgid "user_edit_confirm_email_sent"
+msgstr ""
+"ë©”ì¼ ë³€ê²½ 확ì¸ì„ 위해 %1$së¡œ í™•ì¸ ë©”ì¼ì„ 보냈습니다. 변경 ì‚¬í•­ì´ ì™„ë£Œ ë˜ë ¤ë©´ "
+"새로 변경한 ë©”ì¼ ì£¼ì†Œë¡œ 로그ì¸í•˜ì—¬ ë„ì°©í•œ ë©”ì¼ì˜ í™•ì¸ ë§í¬ë¥¼ í´ë¦­í•´ 주셔야 í•©"
+"니다."
+
+#: views/users/edit.thtml:201
+#, fuzzy
+msgid "user_edit_delete_user"
+msgstr "Delete user account"
+
+# This contains the email sent to users when they signed up for a new
+# account:
+# %1 is the confirmation URL, %2 is the current app
+#. This contains the email sent to users when they signed up for a new
+#. account:
+#. %1 is the confirmation URL, %2 is the current app
+#: views/users/email/confirm_plain.thtml:6
+#, php-format
+msgid "user_email_confirm_account_nopass"
+msgstr ""
+"%2$s 부가 기능 사ì´íŠ¸ì— 오신 ê²ƒì„ í™˜ì˜í•©ë‹ˆë‹¤.\n"
+"\n"
+"ìžì‹ ì˜ ê³„ì •ì„ ì‚¬ìš©í•˜ì‹œë ¤ë©´ 먼저 계정 활성화 ìž‘ì—…ì„ í•˜ì…”ì•¼ 합니다. ë‹¹ì‹ ì˜ ì´ë©”"
+"ì¼ ì£¼ì†Œë¡œ 보내진 ë©”ì¼ì— ë”°ë¼ ì¸ì¦ì„ 하시면 ë©ë‹ˆë‹¤. \n"
+"계정 활성화를 위해, ì´ë©”ì¼ì— 있는 ì¸ì¦ 주소를 í´ë¦­í•˜ì‹œê±°ë‚˜ 웹 브ë¼ìš°ì € 주소창"
+"ì— ë³µì‚¬í•´ì„œ 넣으신 후 방문하시면 ë©ë‹ˆë‹¤:\n"
+"\n"
+"%1$s\n"
+"\n"
+"계정 활성화가 완료 ë˜ë©´ 다시 한번 í™•ì¸ ë©”ì¼ì„ ë³´ë‚´ 드릴 것입니다.\n"
+"\n"
+"다시 한번 %2$s 부가 기능 사ì´íŠ¸ 등ë¡ì„ ê°ì‚¬ë“œë¦½ë‹ˆë‹¤.\n"
+"-- %2$s 부가 기능 웹 사ì´íŠ¸ ê´€ë¦¬ìž ë“œë¦¼"
+
+# %1 is the confirmation url, %2 is the application name
+#. %1 is the confirmation url, %2 is the application name
+#: views/users/email/emailchange_plain.thtml:5
+msgid "user_email_confirm_emailchange"
+msgstr ""
+"%2$s 부가 기능 관리 ë©”ì¼ ë³€ê²½\n"
+"\n"
+"새로운 ë©”ì¼ ì£¼ì†Œë¥¼ 확ì¸í•˜ë ¤ë©´ ì•„ëž˜ì˜ ë§í¬ë¥¼ í´ë¦­ 하시거나 복사하셔서 브ë¼ìš°"
+"ì € ì£¼ì†Œì°½ì— ë„£ì–´ 방문해 주셔야 합니다.:\n"
+"\n"
+"%1$s\n"
+"\n"
+"새 주소 ë³€ê²½ì„ í•˜ë ¤ë©´ 48시간 ì´ë‚´ì— í™•ì¸ ë§í¬ë¥¼ í´ë¦­í•˜ì…”야 합니다. 시간 ë‚´ ë³€"
+"ê²½ 완료를 하지 않으시면 ì´ ë©”ì¼ì€ 만료 ë©ë‹ˆë‹¤.\n"
+"\n"
+"ê°ì‚¬í•©ë‹ˆë‹¤!\n"
+"-- %2$s 부가 기능 관리ìž"
+
+#: controllers/users_controller.php:168
+#, php-format
+msgid "user_email_confirm_subject"
+msgstr "%s 부가 기능 사ì´íŠ¸ì— 가입해 주셔서 ê°ì‚¬í•©ë‹ˆë‹¤."
+
+# This is the password reset email
+# %1 is the pw reset URL
+#. This is the password reset email
+#. %1 is the pw reset URL, %2 is the application
+#: views/users/email/pwreset_plain.thtml:5
+#, php-format
+msgid "user_email_pwreset"
+msgstr ""
+"%2$s 부가 기능 암호 초기화\n"
+"\n"
+"부가 기능 사ì´íŠ¸ì˜ 암호 초기화 ìš”ì²­ì„ ë°›ì•˜ìŠµë‹ˆë‹¤.mozilla.org. 암호를 변경하"
+"기 위해 ì•„ëž˜ì˜ ë§í¬ë¥¼ í´ë¦­í•˜ê±°ë‚˜,웹 브ë¼ìš°ì € ì£¼ì†Œì°½ì— ë¶™ì—¬ë„£ê¸° 하십시오:\n"
+"\n"
+"%1$s\n"
+"\n"
+"만약 ì´ ì´ë©”ì¼ì´ 요청받지 ì•Šì€ ë©”ì¼ì´ë©´ 아무런 í–‰ë™ì„ ì•ˆí•˜ì…”ë„ ë©ë‹ˆë‹¤.\n"
+"\n"
+"ê°ì‚¬í•©ë‹ˆë‹¤,\n"
+"-- %2$s 부가 기능 관리ìž"
+
+#: controllers/users_controller.php:245
+#, php-format
+msgid "user_email_pwreset_subject"
+msgstr "%1$s 부가 기능 사ì´íŠ¸ 암호 초기화"
+
+#: views/users/emailchange.thtml:50
+msgid "user_emailchange_error"
+msgstr "오류!"
+
+# %1 is the application name
+#. %1 is the application name
+#: controllers/users_controller.php:533
+msgid "user_emailchange_subject"
+msgstr "%1$s 부가 기능 ìˆ˜ì •ì— ë©”ì¼ ì£¼ì†Œë¥¼ 확ì¸í•˜ì„¸ìš”."
+
+#: views/users/emailchange.thtml:48
+msgid "user_emailchange_success"
+msgstr "성공하였습니다!"
+
+# %1 is the new email address
+#. %1 is the new email address
+#: views/users/emailchange.thtml:49
+msgid "user_emailchange_successful_description"
+msgstr "ë©”ì¼ ì£¼ì†Œê°€ 변경ë˜ì—ˆìŠµë‹ˆë‹¤. 앞으로 ë¡œê·¸ì¸ ì‹œ %1$s를 ì´ìš©í•´ 주세요."
+
+#: views/users/edit.thtml:134 views/admin/users_edit.thtml:111
+#, fuzzy
+msgid "user_form_bio"
+msgstr "About me"
+
+#: views/users/edit.thtml:135 views/admin/users_edit.thtml:112
+#, fuzzy
+msgid "user_form_bio_description"
+msgstr ""
+"Introduce yourself to the community, if you like! This text will appear "
+"publicly on your user info page. Line breaks will be preserved, but no HTML "
+"is allowed."
+
+#: views/users/pwreset.thtml:77 views/users/register.thtml:73
+#: views/users/edit.thtml:181
+msgid "user_form_confirmpassword"
+msgstr "암호 확ì¸"
+
+#: views/users/edit.thtml:145
+#, fuzzy
+msgid "user_form_display_collections"
+msgstr "Display the collections I have created in my user profile"
+
+#: views/users/edit.thtml:149
+#, fuzzy
+msgid "user_form_display_collections_fav"
+msgstr "Display my favorite collections in my user profile"
+
+#: views/users/edit.thtml:86
+#, php-format
+msgid "user_form_editprofile"
+msgstr "%s ì‚¬ìš©ìž í”„ë¡œí•„ 편집"
+
+#: views/users/pwreset.thtml:52 views/users/login.thtml:81
+#: views/users/register.thtml:63 views/users/edit.thtml:187
+msgid "user_form_email"
+msgstr "ë©”ì¼ ì£¼ì†Œ"
+
+#: views/users/register.thtml:78 views/users/edit.thtml:103
+#: views/admin/users_edit.thtml:76
+msgid "user_form_firstname"
+msgstr "ì´ë¦„"
+
+#: views/users/register.thtml:94 views/users/edit.thtml:119
+#: views/admin/users_edit.thtml:91
+msgid "user_form_hideemail"
+msgstr "ì´ë©”ì¼ ì£¼ì†Œ ê°ì¶”기"
+
+#: views/users/register.thtml:98 views/users/edit.thtml:123
+#: views/admin/users_edit.thtml:99
+msgid "user_form_homepage"
+msgstr "웹사ì´íŠ¸ 주소"
+
+#: views/users/register.thtml:84 views/users/edit.thtml:109
+#: views/admin/users_edit.thtml:81
+msgid "user_form_lastname"
+msgstr "성"
+
+#: controllers/users_controller.php:333
+msgid "user_form_login"
+msgstr "ì‚¬ìš©ìž ë¡œê·¸ì¸"
+
+#: views/users/pwreset.thtml:72 views/users/edit.thtml:176
+msgid "user_form_newpassword"
+msgstr "새 암호"
+
+#: views/users/register.thtml:89 views/users/edit.thtml:114
+#: views/admin/users_edit.thtml:86
+msgid "user_form_nickname"
+msgstr "닉네임"
+
+#: views/users/edit.thtml:171
+msgid "user_form_oldpassword"
+msgstr "예전 암호"
+
+#: views/users/edit.thtml:97 views/users/edit.thtml:200
+#, fuzzy
+msgid "user_form_otheractions"
+msgstr "Other Actions"
+
+#: views/users/login.thtml:85 views/users/register.thtml:68
+msgid "user_form_password"
+msgstr "암호"
+
+#: controllers/users_controller.php:93
+msgid "user_form_registration"
+msgstr "새 ì‚¬ìš©ìž ë“±ë¡"
+
+#: views/users/login.thtml:90
+msgid "user_form_remember_me"
+msgstr "ì»´í“¨í„°ì— ì €ìž¥"
+
+#: views/admin/users_edit.thtml:95
+msgid "user_form_showsandbox"
+msgstr "Sandbox를 표시할까요?"
+
+#: views/users/edit.thtml:205
+msgid "user_form_submit_edit"
+msgstr "저장"
+
+#: views/users/login.thtml:93
+msgid "user_form_submit_login"
+msgstr "로그ì¸"
+
+#: views/users/register.thtml:113
+msgid "user_form_submit_register"
+msgstr "등ë¡"
+
+#: views/users/info.thtml:75
+#, php-format
+msgid "user_info_usersince"
+msgstr "%s 부가 기능 사용ìž"
+
+#: views/users/login.thtml:102
+msgid "user_login_register_link"
+msgstr "새 ì‚¬ìš©ìž ê³„ì • 만들기"
+
+#: views/users/edit.thtml:160
+#, fuzzy
+msgid "user_notifications_item_compat"
+msgstr "Add-on Compatibility (strongly recommended)"
+
+#: views/users/edit.thtml:161
+#, fuzzy
+msgid "user_notifications_item_events"
+msgstr "Upcoming events and contests"
+
+#: views/users/edit.thtml:156
+#, fuzzy
+msgid "user_notifications_none_available"
+msgstr "There are currently no notifications available for you to configure."
+
+#: views/users/edit.thtml:158
+#, fuzzy
+msgid "user_notifications_select_topics"
+msgstr ""
+"From time to time, Mozilla may send you email about upcoming releases and "
+"add-on events. Please select the topics you are interested in below:"
+
+#: views/users/edit.thtml:164
+#, fuzzy
+msgid "user_notifications_specific_contact"
+msgstr ""
+"Mozilla reserves the right to contact you individually about specific "
+"concerns with your hosted add-ons."
+
+#: controllers/users_controller.php:543
+msgid "user_profile_edit_error"
+msgstr "변경 내용 중 오류가 있습니다. 오류를 정정해 주세요."
+
+#: controllers/users_controller.php:540
+msgid "user_profile_saved"
+msgstr "í”„ë¡œí•„ì„ ë³€ê²½í•˜ì˜€ìŠµë‹ˆë‹¤."
+
+#: views/users/pwreset.thtml:65
+#, php-format
+msgid "user_pwreset_for_email"
+msgstr "%s를 위한 암호 초기화"
+
+#: controllers/users_controller.php:226
+msgid "user_pwreset_header"
+msgstr "암호 초기화"
+
+#: views/users/login.thtml:103
+msgid "user_pwreset_link"
+msgstr "암호를 잊으셨습니까?"
+
+#: controllers/users_controller.php:248
+msgid "user_pwreset_link_sent"
+msgstr "ë‹¹ì‹ ì˜ ì´ë©”ì¼ ì£¼ì†Œë¡œ 암호 초기화 ë§í¬ë¥¼ 보냈습니다."
+
+#: controllers/users_controller.php:304
+msgid "user_pwreset_okay"
+msgstr "암호를 성공ì ìœ¼ë¡œ 초기화 하였습니다."
+
+#: views/users/pwreset.thtml:82
+msgid "user_pwreset_submit_changepw"
+msgstr "암호 변경 ì ìš©"
+
+#: views/users/pwreset.thtml:57
+msgid "user_pwreset_submit_sendlink"
+msgstr "암호 초기화 ë§í¬ 보내기"
+
+#: views/users/register_complete.thtml:51
+#, php-format
+msgid "user_register_amo_link"
+msgstr "%s 부가 기능"
+
+#. %1 is the user's email address, %2 is the current app
+#: views/users/activatefirst.thtml:49
+#, php-format
+msgid "user_register_click_confirm_link"
+msgstr ""
+"%1$s ë©”ì¼ ì£¼ì†Œë¡œ ë‹¹ì‹ ì˜ ê³„ì •ì„ í™œì„±í™” í•  수 있는 ë§í¬ë¥¼ 보냈습니다.Mozilla 부"
+"ê°€ 기능 사ì´íŠ¸ì— ë¡œê·¸ì¸ í•˜ê¸° ì „ì— ê³„ì • 활성화를 해야 합니다."
+
+#. %1 is the user's email address
+#: views/users/register_complete.thtml:49
+#, php-format
+msgid "user_register_confirm_email_sent"
+msgstr ""
+"ì´ë©”ì¼ ì •ë³´ê°€ 정확한지 %1$së¡œ í™•ì¸ ë©”ì¼ì„ 보냈습니다.ë¡œê·¸ì¸ ì „ì— ì „ìžë©”ì¼ì„ "
+"확ì¸í•˜ê³  ì œê³µëœ ë§í¬ë¥¼ í´ë¦­í•´ê³„ì •ì„ ë¨¼ì € 활성화 시켜 주십시오."
+
+#: views/users/activatefirst.thtml:51
+msgid "user_register_confirmation_link_text"
+msgstr "í™•ì¸ ë©”ì‹œì§€ 재전송"
+
+#: views/users/register_complete.thtml:47
+msgid "user_register_congratulations"
+msgstr "축하합니다! 계정 등ë¡ì´ 완료 ë˜ì—ˆìŠµë‹ˆë‹¤."
+
+#: views/users/register.thtml:50
+#, fuzzy
+msgid "user_register_details"
+msgstr ""
+"<p>Registration on AMO is <strong>not required</strong> if you simply want "
+"to download and install public add-ons.</p><p>You only need to register if:</"
+"p><ul><li>You want to submit reviews for add-ons</li><li>You are an add-on "
+"developer and want to upload your add-on for hosting on AMO</li></ul><p>Upon "
+"successful registration, you will be sent a confirmation email to the "
+"address you provided. Please follow the instructions there to confirm your "
+"account.</p><p>If you like, you can read our <a href='%1$s' title='Legal "
+"Notices'>Legal Notices</a> and <a href='%2$s' title='Privacy Policy'>Privacy "
+"Policy</a>.</p>"
+
+#. %1 is the link to the "resend confirmation code" page
+#: views/users/activatefirst.thtml:51
+#, php-format
+msgid "user_register_resend_confirmation_link"
+msgstr "만약 í™•ì¸ ë©”ì¼ì„ 받지 못하셨다면 편지가 \"스팸 편지함\"ì— ìžˆëŠ” 지"
+
+#. %1 is the link to the Mozilla Add-ons front page
+#: views/users/register_complete.thtml:51
+#, php-format
+msgid "user_register_welcome"
+msgstr "등ë¡ì„ ê°ì‚¬í•˜ì˜¤ë©° %1$sì— ì˜¤ì‹ ê²ƒì„ í™˜ì˜í•©ë‹ˆë‹¤."
+
+#: views/users/register.thtml:49
+#, fuzzy
+msgid "user_register_welcome_header"
+msgstr "Welcome to addons.mozilla.org (AMO)!"
+
+#: views/users/register.thtml:81 views/users/edit.thtml:106
+#, fuzzy
+msgid "user_required_firstlast_or_nickname"
+msgstr "A first name, last name or nickname is required."
+
+#: views/users/edit.thtml:94 views/users/edit.thtml:142
+#, fuzzy
+msgid "user_tab_collections"
+msgstr "Collections"
+
+#: views/users/edit.thtml:95 views/users/edit.thtml:154
+#, fuzzy
+msgid "user_tab_notifications"
+msgstr "Notifications"
+
+#: views/users/edit.thtml:93 views/users/edit.thtml:101
+#, fuzzy
+msgid "user_tab_profile"
+msgstr "User Profile"
+
+#: controllers/users_controller.php:209
+msgid "user_verified_okay"
+msgstr "í™•ì¸ ì™„ë£Œ!"
+
+#: controllers/users_controller.php:723
+#, fuzzy
+msgid "users_delete_pagetitle"
+msgstr "Delete User Account"
+
+#: controllers/users_controller.php:414
+msgid "users_edit_pagetitle"
+msgstr "ì‚¬ìš©ìž ì •ë³´ 변경"
+
+#: views/users/info.thtml:71
+#, fuzzy
+msgid "users_info_aboutme"
+msgstr "About Me"
+
+#: views/users/info.thtml:96
+#, php-format
+msgid "users_info_addons_by_user"
+msgstr "부가 기능/ %1$s"
+
+#: views/users/info.thtml:51
+msgid "users_info_author_name"
+msgstr "ì´ë¦„"
+
+#: views/users/info.thtml:48
+msgid "users_info_author_profile"
+msgstr "ê°œë°œìž í”„ë¡œí•„"
+
+#. %s is the user name
+#: views/users/info.thtml:137
+#, fuzzy
+msgid "users_info_collections_by_user"
+msgstr "Collections by %s"
+
+#: views/users/info.thtml:66
+msgid "users_info_email"
+msgstr "ì´ë©”ì¼ ì£¼ì†Œ"
+
+#: views/users/info.thtml:155
+#, fuzzy
+msgid "users_info_fav_collections_by_user"
+msgstr "Favorite Collections"
+
+#: views/users/info.thtml:61
+msgid "users_info_homepage"
+msgstr "웹사ì´íŠ¸ 주소"
+
+#: views/users/info.thtml:56
+msgid "users_info_nickname"
+msgstr "닉네임"
+
+#: controllers/users_controller.php:707
+#, php-format
+msgid "users_info_pagetitle"
+msgstr "%1$s ì‚¬ìš©ìž ì •ë³´"
+
+# %1 is the user's name
+#. %1 is the user's name
+#: views/users/info.thtml:116
+#, fuzzy
+msgid "users_info_reviews_by_user"
+msgstr "Reviews by %s"
+
+#: controllers/users_controller.php:330 controllers/users_controller.php:332
+msgid "users_login_pagetitle"
+msgstr "ì‚¬ìš©ìž ë¡œê·¸ì¸"
+
+# %1 is the link to the sandbox/policy explanation page
+# This message is for a specific add-on not found
+#. %1 is the link to the sandbox/policy explanation page
+#. This message is for a specific add-on not found
+#: views/users/login.thtml:53
+#, php-format
+msgid "users_login_sandbox_display_warning"
+msgstr ""
+"현재 ì´ ë¶€ê°€ ê¸°ëŠ¥ì€ Sandboxì— ë“¤ì–´ 있습니다. Mozilla 부가 기능 사ì´íŠ¸ì— 계정"
+"ì´ ìžˆìœ¼ì‹œë©´ ë¡œê·¸ì¸ í›„ </a><a href=\"%1$s\">Sandbox 설명서</a>를 참고하세요."
+
+# %1 is the link to the sandbox/policy explanation page
+# This message is for any given sandbox-related page not found
+#. %1 is the link to the sandbox/policy explanation page
+#. This message is for any given sandbox-related page not found
+#: views/users/login.thtml:56
+#, php-format
+msgid "users_login_sandbox_page_warning"
+msgstr ""
+"현재 ì´ ë¶€ê°€ ê¸°ëŠ¥ì€ Sandboxì— ë“¤ì–´ 있습니다. Mozilla 부가 기능 사ì´íŠ¸ì— 계정"
+"ì´ ìžˆìœ¼ì‹œë©´ ë¡œê·¸ì¸ í›„ <a href=\"%1$s\">Sandbox 설명서</a>를 참고하세요."
+
+#: controllers/users_controller.php:223 controllers/users_controller.php:225
+msgid "users_pwreset_pagetitle"
+msgstr "ì‚¬ìš©ìž ì•”í˜¸ 초기화"
+
+#: controllers/users_controller.php:90 controllers/users_controller.php:92
+msgid "users_register_pagetitle"
+msgstr "새 ì‚¬ìš©ìž ë“±ë¡"
+
+#. %1$s is an addon name, like <a>Firebug</a>
+#. %2$s is a version number, like <a>1.2</a>
+#: views/versions/license.thtml:52
+#, fuzzy
+msgid "versions_license_header_source"
+msgstr "Source code license for %1$s %2$s"
+
+#: views/addons/category_landing.thtml:147
+#, fuzzy
+msgid "view_recently_added"
+msgstr "View all recently added"
+
+#: views/addons/category_landing.thtml:161
+#, fuzzy
+msgid "view_top_downloads"
+msgstr "View all top downloads"
+
+#: views/addons/category_landing.thtml:175
+#, fuzzy
+msgid "view_top_rated"
+msgstr "View all top rated"
+
+#, fuzzy
+#~ msgid "addon_slider_tooltip_next"
+#~ msgstr "Next Add-on"
+
+#, fuzzy
+#~ msgid "addon_slider_tooltip_previous"
+#~ msgstr "Previous Add-on"
+
+#~ msgid "addon_versions_getlatesttext"
+#~ msgstr "최신 버전 호환성: "
+
+#~ msgid "addons_display_version_history"
+#~ msgstr "모든 버전 ì •ë³´ 기ë¡"
+
+#~ msgid "addons_home_newest_header"
+#~ msgstr "최신 버전: "
+
+#~ msgid "addons_home_popular_header"
+#~ msgstr "ì¸ê¸° 부가 기능:"
+
+#~ msgid "addons_home_recommended_header"
+#~ msgstr "추천 부가 기능:"
+
+#~ msgid "addons_home_updated_header"
+#~ msgstr "최근 ì—…ë°ì´íŠ¸:"
+
+#~ msgid "addons_home_view_all"
+#~ msgstr "ëª¨ë‘ ë³´ê¸°"
+
+#~ msgid "category_extra_allrecommended"
+#~ msgstr "모든 추천 부가 기능 보기"
+
+#~ msgid "category_extra_highestrated"
+#~ msgstr "ë†’ì€ ì ìˆ˜ 순"
+
+#~ msgid "category_extra_lastupdated"
+#~ msgstr "최근 ì—…ë°ì´íŠ¸ 순"
+
+#~ msgid "category_extra_mostpopular"
+#~ msgstr "ì¸ê¸° 순"
+
+#, fuzzy
+#~ msgid "collections_detail_js_loading"
+#~ msgstr "Loading"
+
+#, fuzzy
+#~ msgid "collections_detail_more_info"
+#~ msgstr "Show More Info"
+
+#~ msgid "devcp_additem_firefox_notice"
+#~ msgstr ""
+#~ "현재 부가 기능 ë²„ì „ì€ Firefox %1$s와 호환ë˜ì§€ 않습니다. Mozillaì—서는 새 "
+#~ "Firefox ë²„ì „ì„ ì¶œì‹œí•˜ê³ ìž í•˜ë©° 부가 ê¸°ëŠ¥ì„ í˜¸í™˜ 가능한 새 버전ì—ì„œ 테스트 "
+#~ "하십시오. ìžì„¸í•œ ì‚¬í•­ì€ <a href=\"%2$s\">관련 ì •ë³´</a>ì—ì„œ ì–»ì„ ìˆ˜ 있습니"
+#~ "다. 본 ì£¼ì˜ ì‚¬í•­ì€ í˜„ìž¬ ë²„ì „ì„ addons.mozilla.orgì— ì „ì†¡í•˜ê¸° ì „ì— ì œê³µ í•©"
+#~ "니다."
+
+#~ msgid "devcp_addon_disabled_successfully"
+#~ msgstr "부가 기능 정지 ìƒíƒœ"
+
+#~ msgid "devcp_addon_edit_pagetitle"
+#~ msgstr "부가 기능 편집"
+
+#~ msgid "devcp_addon_enabled_successfully"
+#~ msgstr "부가 기능 ì´ìš© ìƒíƒœ"
+
+#~ msgid "devcp_addon_field_description_displaytitle"
+#~ msgstr "부가 기능 설명"
+
+#~ msgid "devcp_addon_field_eula_displaytitle"
+#~ msgstr "EULA"
+
+#~ msgid "devcp_addon_field_homepage_displaytitle"
+#~ msgstr "부가 기능 홈페ì´ì§€"
+
+#~ msgid "devcp_addon_field_name_displaytitle"
+#~ msgstr "부가 기능 ì´ë¦„"
+
+#~ msgid "devcp_addon_field_privacy_displaytitle"
+#~ msgstr "ê°œì¸ ì •ë³´ 보호 ì •ì±…"
+
+#~ msgid "devcp_addon_field_summary_displaytitle"
+#~ msgstr "부가 기능 요약"
+
+#~ msgid "devcp_addon_field_supportemail_displaytitle"
+#~ msgstr "ì´ë©”ì¼ ì£¼ì†Œ"
+
+#~ msgid "devcp_addon_field_supporturl_displaytitle"
+#~ msgstr "홈페ì´ì§€ 주소"
+
+#~ msgid "devcp_addon_field_versionnotes_displaytitle"
+#~ msgstr "버전 정보"
+
+#~ msgid "devcp_addon_nominate_pagetitle"
+#~ msgstr "부가 기능 추천하기"
+
+#~ msgid "devcp_addon_nominated_successfully"
+#~ msgstr "부가 기능 추천 완료"
+
+#, fuzzy
+#~ msgid "devcp_addon_status_criteria_review"
+#~ msgstr "Several user reviews of the add-on (may be external reviews)."
+
+# %1 is the addon edit link
+# %2 is the main dev CP link
+#~ msgid "devcp_addon_submission_makechanges"
+#~ msgstr ""
+#~ "제출한 부가 ê¸°ëŠ¥ì„ ìˆ˜ì • 하시려면 %1$s 페ì´ì§€ë¡œ 거거나 ê°œë°œìž ì œì–´íŒìœ¼ë¡œ ëŒ"
+#~ "어가려면%2$s 를 í´ë¦­í•˜ì„¸ìš”."
+
+#~ msgid "devcp_addon_submission_makechanges_devcp_link"
+#~ msgstr "여기"
+
+#~ msgid "devcp_addon_submission_makechanges_link"
+#~ msgstr "부가 기능 편집"
+
+#~ msgid "devcp_addon_submission_pending"
+#~ msgstr ""
+#~ "현재 ì´ ë²„ì „ì€ Mozilla 부가 기능 íŽ¸ì§‘ìž ë° í…ŒìŠ¤í„°ë¡œ 부터 í‰ê°€ë¥¼ 받기 위해 "
+#~ "Sandboxì— ìœ„ì¹˜í•˜ê³  있습니다. ê·¸ ë‹¤ìŒ ë‹¨ê³„ë¡œ 들어서면 ì´ë©”ì¼ì„ 받으시게 ë©"
+#~ "니다."
+
+# %1 is the link to the sandbox information page
+#~ msgid "devcp_addon_submission_sandbox_readmore"
+#~ msgstr "Sandbox í‰ê°€ ì²´ê³„ì— ëŒ€í•´ì„œëŠ” %s를 살펴 보세요."
+
+#~ msgid "devcp_addon_submission_sandbox_readmore_link"
+#~ msgstr "여기"
+
+# %1 is the "nominate" link
+#~ msgid "devcp_addon_submission_sandboxed"
+#~ msgstr ""
+#~ "ì´ ë²„ì „ì€ ê¸°ì¡´ 사용ìžë¥¼ 위해 Sandboxì— ìœ„ì¹˜í•´ 있습니다. 웹 사ì´íŠ¸ì— 공개하"
+#~ "시려면 %s를 눌러 í‰ê°€ ê³¼ì •ì„ ê±°ì¹˜ì‹œê¸° ë°”ëžë‹ˆë‹¤."
+
+#~ msgid "devcp_addon_submission_sandboxed_nominate_link"
+#~ msgstr "공개 추천"
+
+#~ msgid "devcp_addon_submission_success"
+#~ msgstr "부가 기능 ì œì¶œì„ ì™„ë£Œí•˜ì˜€ìŠµë‹ˆë‹¤."
+
+#~ msgid "devcp_addon_submission_trusted_public"
+#~ msgstr "본 부가 ê¸°ëŠ¥ì€ ì´ë¯¸ 신뢰ë˜ì–´ ìžë™ìœ¼ë¡œ 웹 사ì´íŠ¸ì— 공개 합니다."
+
+#~ msgid "devcp_addon_submit_pagetitle"
+#~ msgstr "부가 기능 제출"
+
+#~ msgid "devcp_addon_updated_successfully"
+#~ msgstr "부가 기능 정보 변경 완료"
+
+# %1 is the link to the preview upload page
+#~ msgid "devcp_addon_upload_preview"
+#~ msgstr "부가 ê¸°ëŠ¥ì— ëŒ€í•œ ê´€ì‹¬ì„ ë†’ížˆë ¤ë©´ %s를 하시면 ë„ì›€ì´ ë©ë‹ˆë‹¤."
+
+#~ msgid "devcp_addon_upload_preview_link"
+#~ msgstr "미리보기 업로드"
+
+# #1 is the author email
+#~ msgid "devcp_author_lookup_none_found"
+#~ msgstr "ê°œë°œìž ì—†ìŒ [%s]"
+
+#~ msgid "devcp_author_lookup_remove"
+#~ msgstr "제거"
+
+#~ msgid "devcp_button_cancel"
+#~ msgstr "취소"
+
+#~ msgid "devcp_button_cancel_confirm"
+#~ msgstr "현재 제출하신 ë‚´ìš©ì„ ì·¨ì†Œí•˜ì‹œê² ìŠµë‹ˆê¹Œ?"
+
+#~ msgid "devcp_button_next"
+#~ msgstr "다ìŒ"
+
+#~ msgid "devcp_change_addontype"
+#~ msgstr "부가 기능 í˜•ì‹ ë³€ê²½:"
+
+#~ msgid "devcp_comments_updated"
+#~ msgstr "ê°œë°œìž ì •ë³´ê°€ ì—…ë°ì´íŠ¸ ë˜ì—ˆìŠµë‹ˆë‹¤."
+
+#~ msgid "devcp_details_addpreview_link"
+#~ msgstr "미리 보기 추가"
+
+#~ msgid "devcp_details_author"
+#~ msgstr "개발ìž"
+
+#~ msgid "devcp_details_authors"
+#~ msgstr "복수 개발ìž"
+
+#~ msgid "devcp_details_authors_none"
+#~ msgstr "ì—†ìŒ"
+
+#~ msgid "devcp_details_categories"
+#~ msgstr "세부 분류"
+
+#~ msgid "devcp_details_category"
+#~ msgstr "세부 분류"
+
+#~ msgid "devcp_details_description"
+#~ msgstr "설명"
+
+#~ msgid "devcp_details_disabled"
+#~ msgstr "사용 안함"
+
+#~ msgid "devcp_details_guid"
+#~ msgstr "GUID"
+
+#~ msgid "devcp_details_header_details"
+#~ msgstr "ìƒì„¸ ì •ë³´"
+
+#~ msgid "devcp_details_header_devcomments"
+#~ msgstr "ê°œë°œìž ì •ë³´"
+
+#~ msgid "devcp_details_header_previews"
+#~ msgstr "미리 보기"
+
+#~ msgid "devcp_details_header_versions"
+#~ msgstr "버전"
+
+#~ msgid "devcp_details_homepage"
+#~ msgstr "홈페ì´ì§€"
+
+#~ msgid "devcp_details_homepage_none"
+#~ msgstr "ì—†ìŒ"
+
+#~ msgid "devcp_details_preview_nocaption"
+#~ msgstr "ì •ë³´ ì—†ìŒ"
+
+#~ msgid "devcp_details_previews_nonefound"
+#~ msgstr "미리 보기가 없습니다."
+
+#~ msgid "devcp_details_submit_update"
+#~ msgstr "ì—…ë°ì´íŠ¸"
+
+#~ msgid "devcp_details_supportemail"
+#~ msgstr "기술 ì§€ì› ì´ë©”ì¼ ì£¼ì†Œ"
+
+#~ msgid "devcp_details_supportemail_none"
+#~ msgstr "기술 지ì›ìš© ì´ë©”ì¼ ì£¼ì†Œê°€ 없습니다."
+
+#~ msgid "devcp_details_supporturl"
+#~ msgstr "기술 ì§€ì› í™ˆíŽ˜ì´ì§€"
+
+#~ msgid "devcp_details_supporturl_none"
+#~ msgstr "기술 지ì›ìš© 홈페ì´ì§€ê°€ 없습니다."
+
+#~ msgid "devcp_details_trusted"
+#~ msgstr "신뢰함"
+
+#~ msgid "devcp_details_versions_none_found"
+#~ msgstr "버전 정보가 없습니다."
+
+#~ msgid "devcp_disable_cancel"
+#~ msgstr "취소 ë° ëŒì•„가기"
+
+#~ msgid "devcp_disable_disable_button"
+#~ msgstr "ë™ì˜, 사용안함"
+
+#~ msgid "devcp_disable_disable_confirm"
+#~ msgstr "본 부가 ê¸°ëŠ¥ì„ ì‚¬ìš©í•˜ì§€ ì•ŠìŒ ìƒíƒœë¡œ 바꾸시겠습니까?"
+
+#~ msgid "devcp_disable_disable_description"
+#~ msgstr ""
+#~ "현재 부가 ê¸°ëŠ¥ì„ ì‚¬ìš© 안함으로 변경 하면 모든 ëª©ë¡ ë° ê²€ìƒ‰ì— ë‚˜íƒ€ë‚˜ì§€ 않습"
+#~ "니다. 본 웹 사ì´íŠ¸ì—ì„œ 다운로드 í•  수 없으며 ì—…ë°ì´íŠ¸ í™•ì¸ ìž‘ì—…ë„ ì§„í–‰ë˜"
+#~ "지 않습니다. 향후 다시 ì‚¬ìš©í•¨ì„ ì„¤ì •í•˜ë”ë¼ë„ 실제로 ì‚­ì œ ê°€ëŠ¥ì„±ì´ ìžˆìŠµë‹ˆ"
+#~ "다."
+
+#~ msgid "devcp_disable_disable_title"
+#~ msgstr "%s 사용 안함"
+
+#~ msgid "devcp_disable_enable_button"
+#~ msgstr "ë™ì˜, 사용함"
+
+#~ msgid "devcp_disable_enable_confirm"
+#~ msgstr "본 부가 ê¸°ëŠ¥ì„ ì‚¬ìš© ìƒíƒœë¡œ 바꾸시겠습니까?"
+
+#~ msgid "devcp_disable_enable_description"
+#~ msgstr ""
+#~ "부가 ê¸°ëŠ¥ì„ ì‚¬ìš©í•¨ìœ¼ë¡œ 변경하면 검색 ê²°ê³¼ ë° ëª©ë¡ì— 표시ë©ë‹ˆë‹¤. 웹 사ì´íŠ¸ "
+#~ "ë° ë²„ì „ ì—…ë°ì´íŠ¸ë¥¼ 통해 바로 다운로드 가능 합니다."
+
+#~ msgid "devcp_disable_enable_title"
+#~ msgstr "%s 사용 함"
+
+#~ msgid "devcp_edit_author_add"
+#~ msgstr "ê°œë°œìž ì¶”ê°€"
+
+#~ msgid "devcp_edit_author_email"
+#~ msgstr "ê°œë°œìž ì´ë©”ì¼ ì£¼ì†Œ"
+
+#~ msgid "devcp_edit_author_remove"
+#~ msgstr "제거"
+
+#~ msgid "devcp_edit_error_categories_unavailable"
+#~ msgstr "본 부가 기능 형ì‹ì—는 분류 í•­ëª©ì´ ì—†ìŠµë‹ˆë‹¤."
+
+#, fuzzy
+#~ msgid "devcp_edit_file_error_incomplete"
+#~ msgstr "Incomplete transfer"
+
+#, fuzzy
+#~ msgid "devcp_edit_file_error_no"
+#~ msgstr "No file uploaded"
+
+#, fuzzy
+#~ msgid "devcp_edit_file_error_size"
+#~ msgstr "Exceeds maximum upload size"
+
+#~ msgid "devcp_edit_header_authors"
+#~ msgstr "개발ìž"
+
+#~ msgid "devcp_edit_icon_add_link"
+#~ msgstr "ì•„ì´ì½˜ 추가"
+
+#~ msgid "devcp_edit_icon_change_link"
+#~ msgstr "ì•„ì´ì½˜ 변경"
+
+#~ msgid "devcp_edit_label_allow_viewsource"
+#~ msgstr "온ë¼ì¸ìœ¼ë¡œ 소스를 ë³¼ 수 있는 사용ìž"
+
+#~ msgid "devcp_edit_label_categories"
+#~ msgstr "분류"
+
+#~ msgid "devcp_edit_label_defaultlocale"
+#~ msgstr "기본 언어"
+
+#~ msgid "devcp_edit_label_icon_delete"
+#~ msgstr "현 ì•„ì´ì½˜ ì‚­ì œ"
+
+#~ msgid "devcp_edit_label_icon_new"
+#~ msgstr "새 ì•„ì´ì½˜ 파ì¼"
+
+#~ msgid "devcp_edit_label_info"
+#~ msgstr "ì•„ì´ì½˜"
+
+#~ msgid "devcp_edit_locale_disambiguation_explanation"
+#~ msgstr "부가 정보 (예, 지역명)"
+
+#~ msgid "devcp_edit_submit_update"
+#~ msgstr "ì—…ë°ì´íŠ¸"
+
+#~ msgid "devcp_edit_target_locale_explanation"
+#~ msgstr ""
+#~ "<a href=\"http://wiki.mozilla.org/L10n:Simple_locale_names\">언어별 코드</"
+#~ "a>, 예) 'en-US'"
+
+#~ msgid "devcp_editversion_checkedfiles_delete"
+#~ msgstr "ì²´í¬ëœ 파ì¼ì„ 삭제합니다."
+
+# %1 is the file name
+# %2 is the file size (150 KB)
+#~ msgid "devcp_editversion_filename_size"
+#~ msgstr "%1$s (%2$s)"
+
+#~ msgid "devcp_editversion_label_files"
+#~ msgstr "파ì¼"
+
+#~ msgid "devcp_editversion_label_targetapps"
+#~ msgstr "ì§€ì› ì‘ìš© 프로그램"
+
+#~ msgid "devcp_editversion_nofiles"
+#~ msgstr "파ì¼ì´ 없습니다."
+
+#~ msgid "devcp_editversion_reviewernotes"
+#~ msgstr "í‰ê°€ìž 노트"
+
+#~ msgid "devcp_editversion_submit_update"
+#~ msgstr "ì—…ë°ì´íŠ¸"
+
+#~ msgid "devcp_error_addon_field_summary_toolong"
+#~ msgstr ""
+#~ "ìš”ì•½ì€ ìµœëŒ€ 250ìž ì´ìƒ 사용할 수 없습니다.\n"
+#~ "(ë‚´ìš©: %s)"
+
+#~ msgid "devcp_error_addonname_not_unique"
+#~ msgstr ""
+#~ "부가 기능 ì´ë¦„ì´ ì´ë¯¸ 존재 합니다. ë‹¤ìŒ ì‚¬í•­ì„ í™•ì¸í•´ 보시기 ë°”ëžë‹ˆë‹¤. "
+#~ "<br /><li>GUID 확ì¸: 대부분 GUID와 부합하지 않는 ì—러가 나타납니다. </"
+#~ "li><li>ë°ì´í„°ë² ì´ìŠ¤ì— 중복 í•­ëª©ì´ ì—†ìŠµë‹ˆë‹¤. 그러면 ê·¸ í•­ëª©ì„ ì—…ë°ì´íŠ¸ 하"
+#~ "거나 삭제해야 만 합니다.</li>"
+
+#~ msgid "devcp_error_describe_changes"
+#~ msgstr "현재 부가 ê¸°ëŠ¥ì˜ ë³€ê²½ ì‚¬í•­ì„ ì ì–´ 주시기 ë°”ëžë‹ˆë‹¤."
+
+#~ msgid "devcp_error_file_guids_dont_match"
+#~ msgstr "GUID ê°’ì´ í˜¸ì¶œë˜ì§€ ì•ŠìŒ"
+
+#~ msgid "devcp_error_identical_version_exists"
+#~ msgstr "ì´ ë¶€ê°€ ê¸°ëŠ¥ì˜ í˜„ìž¬ 버전 (%s)ì€ ì´ë¯¸ 존재 합니다."
+
+#~ msgid "devcp_error_nominate_message"
+#~ msgstr "후부 ì¶”ì²œì„ ìœ„í•´ í•„ìš” í•­ëª©ì„ ì±„ì›Œ 주셔야 합니다."
+
+#~ msgid "devcp_error_nominate_no_prerelease"
+#~ msgstr "ì•„ì§ ì¶œì‹œí•˜ì§€ ì•Šì€ ë¶€ê°€ ê¸°ëŠ¥ì€ ì¶”ì²œí•  수 없습니다."
+
+#~ msgid "devcp_error_nominate_sandbox_only"
+#~ msgstr "Sandboxì—ì„œ 현재 부가 기능 공개를 추천할 수 있습니다."
+
+#~ msgid "devcp_error_saving"
+#~ msgstr "ë°ì´í„° 저장 중 오류가 ë°œìƒí–ˆìŠµë‹ˆë‹¤."
+
+#~ msgid "devcp_error_update_access_denied"
+#~ msgstr "ì´ ë¶€ê°€ ê¸°ëŠ¥ì„ ì—…ë°ì´íŠ¸í•  ê¶Œí•œì´ ì—†ìŠµë‹ˆë‹¤."
+
+#~ msgid "devcp_file_addanother"
+#~ msgstr "다른 í”Œëž«í¼ íŒŒì¼ ì¶”ê°€"
+
+#~ msgid "devcp_form_author_add"
+#~ msgstr "ê°œë°œìž ì¶”ê°€"
+
+#~ msgid "devcp_form_author_remove"
+#~ msgstr "제거"
+
+#~ msgid "devcp_form_categories_nextstep"
+#~ msgstr "새 부가 ê¸°ëŠ¥ì— ëŒ€í•œ 분류 형ì‹ì€ ë‹¤ìŒ ë‹¨ê³„ì—ì„œ 입력할 수 있습니다."
+
+#~ msgid "devcp_form_error_categories_unavailable"
+#~ msgstr "ì´ ë¶€ê°€ ê¸°ëŠ¥ì— ëŒ€í•œ 사용 가능한 분류가 없습니다."
+
+#~ msgid "devcp_form_error_description_notempty"
+#~ msgstr "부가 ê¸°ëŠ¥ì— ëŒ€í•œ ì„¤ëª…ì„ ìž…ë ¥í•˜ì„¸ìš”."
+
+#~ msgid "devcp_form_error_name_required"
+#~ msgstr "부가 기능 ì´ë¦„ì„ ìž…ë ¥í•˜ì„¸ìš”."
+
+#~ msgid "devcp_form_error_select_addontype"
+#~ msgstr "부가 ê¸°ëŠ¥ì— ëŒ€í•œ 형ì‹ì„ ì„ íƒí•˜ì„¸ìš”."
+
+#~ msgid "devcp_form_error_summary_notempty"
+#~ msgstr "부가 ê¸°ëŠ¥ì— ëŒ€í•œ 요약 정보를 입력하세요."
+
+#~ msgid "devcp_form_label_addonfile"
+#~ msgstr "부가 기능 파ì¼"
+
+#~ msgid "devcp_form_label_addonfile2"
+#~ msgstr "부가 기능 íŒŒì¼ 2"
+
+#~ msgid "devcp_form_label_addonfile3"
+#~ msgstr "부가 기능 íŒŒì¼ 3"
+
+#~ msgid "devcp_form_label_addontype"
+#~ msgstr "부가 기능 형ì‹"
+
+#~ msgid "devcp_form_label_allow_viewsource"
+#~ msgstr "사용ìžê°€ 소스 코드를 온ë¼ì¸ì—ì„œ 열람 가능"
+
+#~ msgid "devcp_form_label_author_email"
+#~ msgstr "ê°œë°œìž ì´ë©”ì¼ ì£¼ì†Œ"
+
+#~ msgid "devcp_form_label_authors"
+#~ msgstr "개발ìž"
+
+#~ msgid "devcp_form_label_categories"
+#~ msgstr "분류"
+
+#~ msgid "devcp_form_label_defaultlocale"
+#~ msgstr "기본 언어"
+
+#~ msgid "devcp_form_label_description"
+#~ msgstr "설명"
+
+#~ msgid "devcp_form_label_eula"
+#~ msgstr "ì¼ë°˜ ì‚¬ìš©ìž ì•½ê´€ (EULA)"
+
+#~ msgid "devcp_form_label_externalsoftware"
+#~ msgstr "ì´ ë¶€ê°€ ê¸°ëŠ¥ì€ ì™¸ë¶€ í”„ë¡œê·¸ëž¨ì´ í•„ìš”í•¨"
+
+#~ msgid "devcp_form_label_files"
+#~ msgstr "파ì¼"
+
+#~ msgid "devcp_form_label_homepage"
+#~ msgstr "홈페ì´ì§€"
+
+#~ msgid "devcp_form_label_iconfile"
+#~ msgstr "ì•„ì´ì½˜ 파ì¼"
+
+#~ msgid "devcp_form_label_name"
+#~ msgstr "ì´ë¦„"
+
+#~ msgid "devcp_form_label_platforms"
+#~ msgstr "ì§€ì› í”Œëž«í¼"
+
+#~ msgid "devcp_form_label_prerelease"
+#~ msgstr "미출시 ìƒíƒœ"
+
+#~ msgid "devcp_form_label_privacy"
+#~ msgstr "ê°œì¸ ì •ë³´ 보호 ì •ì±…"
+
+#~ msgid "devcp_form_label_sitespecific"
+#~ msgstr "웹 사ì´íŠ¸ 기반 부가 기능"
+
+#~ msgid "devcp_form_label_summary"
+#~ msgstr "요약"
+
+#~ msgid "devcp_form_label_supportemail"
+#~ msgstr "기술 ì§€ì› ì´ë©”ì¼ ì£¼ì†Œ"
+
+#~ msgid "devcp_form_label_supporturl"
+#~ msgstr "기술 ì§€ì› í™ˆíŽ˜ì´ì§€"
+
+#~ msgid "devcp_form_label_target_applications"
+#~ msgstr "ì§€ì› ì‘ìš© 프로그램"
+
+#~ msgid "devcp_form_label_version"
+#~ msgstr "버전"
+
+#~ msgid "devcp_form_label_versionnotes"
+#~ msgstr "버전 노트"
+
+#~ msgid "devcp_form_no_target_apps"
+#~ msgstr "ì—†ìŒ"
+
+#~ msgid "devcp_form_reviewernotes"
+#~ msgstr "í‰ê°€ìž 노트"
+
+#~ msgid "devcp_form_trustedaddon_destination"
+#~ msgstr "부가 ê¸°ëŠ¥ì´ ì‹ ë¢°ë˜ì—ˆìœ¼ë¯€ë¡œ 현재 버전 위치를 정하십시오:"
+
+#~ msgid "devcp_form_trustedaddon_destination_public"
+#~ msgstr "공개"
+
+#~ msgid "devcp_form_trustedaddon_destination_sandbox"
+#~ msgstr "Sandbox"
+
+#~ msgid "devcp_header_developer_agreement"
+#~ msgstr "ê°œë°œìž ì•½ê´€"
+
+#~ msgid "devcp_header_step1"
+#~ msgstr "단계 1"
+
+#~ msgid "devcp_header_step1_upload"
+#~ msgstr "íŒŒì¼ ì—…ë¡œë“œ"
+
+#~ msgid "devcp_header_step2"
+#~ msgstr "단계 2"
+
+#~ msgid "devcp_header_step2_addondetails"
+#~ msgstr "부가 기능 ìƒì„¸ ì •ë³´"
+
+#~ msgid "devcp_header_step3"
+#~ msgstr "단계 3"
+
+#~ msgid "devcp_header_step3_versiondetails"
+#~ msgstr "버전 ìƒì„¸ ì •ë³´"
+
+#~ msgid "devcp_header_step4"
+#~ msgstr "단계 4"
+
+#~ msgid "devcp_header_step4_localization"
+#~ msgstr "지역화"
+
+#~ msgid "devcp_header_step5"
+#~ msgstr "단계 5"
+
+#~ msgid "devcp_header_step5_success"
+#~ msgstr "완료"
+
+#~ msgid "devcp_index_header_myaddons"
+#~ msgstr "ë‚˜ì˜ ë¶€ê°€ 기능"
+
+#~ msgid "devcp_nominate_link_returnto_details"
+#~ msgstr "ìƒì„¸ ì •ë³´ë¡œ ëŒì•„가기"
+
+# %1 is the autodetected addon type
+#~ msgid "devcp_notice_autodetected_addontype"
+#~ msgstr "부가 기능 í˜•ì‹ ìžë™ ì¸ì‹: %s."
+
+# %1 is the default locale name (English (US))
+# %2 is the default locale code (en-US)
+# %3 is the current page locale name (Deutsch)
+# %4 is the current page locale code (de)
+#~ msgid "devcp_notice_different_defaultlocale"
+#~ msgstr ""
+#~ "현재 부가 ê¸°ëŠ¥ì˜ ê¸°ë³¸ 언어 설정(%1$s [%2$s])ì´ í˜„ìž¬ ì„ íƒí•œ ì‚¬ìš©ìž ì–¸ì–´ 설"
+#~ "ì • (%3$s [%4$s])ê³¼ 다릅니다. %1$sì—ì„œ 아래 í•­ëª©ì„ ëª¨ë‘ ì±„ì›Œì•¼ 합니다."
+
+#~ msgid "devcp_question_addontype_incorrect"
+#~ msgstr "형ì‹ì´ 맞지 않습니까?"
+
+#~ msgid "devcp_question_delete_file"
+#~ msgstr "ì´ íŒŒì¼ì„ 삭제하시겠습니까?"
+
+#~ msgid "devcp_skip_reviewing_addon_info"
+#~ msgstr "현재 부가 기능 정보 검토 건너 뛰기"
+
+#~ msgid "devcp_submissions_disabled"
+#~ msgstr ""
+#~ "현재 부가 기능 ë“±ë¡ ê¸°ëŠ¥ì´ ìž ì‹œ 정지ë˜ì—ˆìŠµë‹ˆë‹¤. 다ìŒì— ì‹œë„하시기 ë°”ëžë‹ˆ"
+#~ "다."
+
+#~ msgid "devcp_submit_accept_dev_agreement"
+#~ msgstr "ë™ì˜í•¨"
+
+#~ msgid "devcp_submit_decline_dev_agreement"
+#~ msgstr "ë™ì˜ 안함"
+
+#~ msgid "devcp_summary_admin_disabled"
+#~ msgstr "ì´ ë¶€ê°€ ê¸°ëŠ¥ì€ ê´€ë¦¬ìžì— ì˜í•´ 사용 정지 ë˜ì—ˆìŠµë‹ˆë‹¤."
+
+#~ msgid "devcp_summary_header_disabled"
+#~ msgstr "사용 정지ë¨"
+
+#~ msgid "devcp_summary_header_trusted"
+#~ msgstr "신뢰ë¨"
+
+# %1 is a link to the addon submit page
+#~ msgid "devcp_summary_noaddons_submit_one"
+#~ msgstr "등ë¡í•œ 부가 ê¸°ëŠ¥ì´ ì—†ìŠµë‹ˆë‹¤. 먼저 %sì„ í•˜ì„¸ìš”."
+
+#~ msgid "devcp_summary_noaddons_submit_one_link"
+#~ msgstr "부가 기능 등ë¡"
+
+# %1 is the link to the preview upload page
+#~ msgid "devcp_theme_upload_preview"
+#~ msgstr "í…Œë§ˆì— ëŒ€í•´ %s를 í™•ì¸ í•˜ì„¸ìš”."
+
+#~ msgid "devcp_theme_upload_preview_link"
+#~ msgstr "미리 보기 업로드"
+
+#~ msgid "devcp_version_edit_pagetitle"
+#~ msgstr "Edit Version"
+
+#~ msgid "devcp_version_updated_successfully"
+#~ msgstr "버전 ì—…ë°ì´íŠ¸ë¥¼ 완료 하였습니다."
+
+#~ msgid "editors_submissiontype_new"
+#~ msgstr "신규"
+
+#~ msgid "editors_submissiontype_updated"
+#~ msgstr "ì—…ë°ì´íŠ¸"
+
+#, fuzzy
+#~ msgid "editors_th_addon_age"
+#~ msgstr "Addon Age"
+
+#~ msgid "editors_th_addontypes"
+#~ msgstr "부가 기능 형ì‹"
+
+#~ msgid "editors_th_age"
+#~ msgstr "나ì´"
+
+#~ msgid "editors_th_applications"
+#~ msgstr "ì‘ìš© 프로그램"
+
+#~ msgid "editors_th_platforms"
+#~ msgstr "플랫í¼"
+
+#~ msgid "editors_th_submissiontypes"
+#~ msgstr "제출 형ì‹"
+
+#~ msgid "error_notice"
+#~ msgstr "오류 공지"
+
+#~ msgid "forum_save"
+#~ msgstr "저장"
+
+#, fuzzy
+#~ msgid "home"
+#~ msgstr "home"
+
+#~ msgid "nav_category_plugins"
+#~ msgstr "플러그ì¸"
+
+#, fuzzy
+#~ msgid "page_title_experimental_addons"
+#~ msgstr "Experimental Add-ons"
+
+#~ msgid "pages_experimental_addons_backbutton"
+#~ msgstr "ì•ž 페ì´ì§€ë¡œ"
+
+# %1 is page number, %2 is total page count
+#~ msgid "pagination_page_number_title"
+#~ msgstr "%2$s 중 %1$s"
+
+#~ msgid "search_matching_addons_number"
+#~ msgid_plural "search_matching_addons_number"
+#~ msgstr[0] "검색 결과: %s"
+#~ msgstr[1] "검색 결과: %s"
+
+#~ msgid "statistics_rss_icon_title"
+#~ msgstr "RSS 요약 정보"
diff --git a/site/app/locale/ko/images/sandbox-review.png b/site/app/locale/ko/images/sandbox-review.png
new file mode 100644
index 0000000..1e99aca
--- /dev/null
+++ b/site/app/locale/ko/images/sandbox-review.png
Binary files differ
diff --git a/site/app/locale/ko/pages/error404.thtml b/site/app/locale/ko/pages/error404.thtml
new file mode 100644
index 0000000..7358c1d
--- /dev/null
+++ b/site/app/locale/ko/pages/error404.thtml
@@ -0,0 +1,16 @@
+<h1>죄송합니다. 검색 결과를 ì°¾ì„ ìˆ˜ 없습니다.</h1>
+
+<p>요청하신 파ì¼ì´ë‚˜ 페ì´ì§€ë¥¼ ì´ ì›¹ 사ì´íŠ¸ì—ì„œ ì°¾ì„ ìˆ˜ 없습니다. ì„ íƒí•˜ì‹  페ì´ì§€ê°€ 오래ë˜ì—ˆê±°ë‚˜ 틀린 ì£¼ì†Œì¼ ê°€ëŠ¥ì„±ì´ ìžˆìŠµë‹ˆë‹¤.</p>
+
+<ul>
+<li>만약 주소를 ì§ì ‘ 입력한 경우, ì² ìžê°€ 맞는 지 í™•ì¸ í•´ 주십시오.</li>
+<li>만약 다른 웹 페ì´ì§€ì—ì„œ ë§í¬ë¥¼ ê±°ì³ ì˜¤ì…¨ë‹¤ë©´, <a href="mailto:webmaster@mozilla.com" title="Page Not Found on Mozilla.com">webmaster@mozilla.com</a>ì—게 알려 주십시오. ì–´ë–¤ 웹 페ì´ì§€ì—ì„œ ë§í¬ê°€ 있었는지 알려 주시면 고치는 ë° ìµœì„ ì„ ë‹¤í•˜ê² ìŠµë‹ˆë‹¤.</li>
+</ul>
+
+<p>ë˜ëŠ” 본 사ì´íŠ¸ì˜ 가장 ë§Žì´ ì ‘ì†í•˜ëŠ” 페ì´ì§€ë¡œ ì´ë™í•  수 있습니다.</p>
+
+<ul>
+<li><a href="%1$s">가장 선호하는 부가 기능 목ë¡</a>으로 ì´ë™í•˜ì‹œê² ìŠµë‹ˆê¹Œ?</li>
+<li><a href="%2$s">부가 기능 검색</a>으로 ì´ë™í•˜ì‹œê² ìŠµë‹ˆê¹Œ? <a href="%2$s">검색 페ì´ì§€</a>ì—ì„œ ì›í•˜ëŠ” 결과를 ì–»ì„ ìˆ˜ë„ ìžˆìŠµë‹ˆë‹¤.</li>
+<li><a href="%3$s">첫 화면</a>ì—ì„œ 시작 í•  수 있습니다.</li>
+</ul> \ No newline at end of file
diff --git a/site/app/locale/ko/pages/nomination.thtml b/site/app/locale/ko/pages/nomination.thtml
new file mode 100644
index 0000000..89a8918
--- /dev/null
+++ b/site/app/locale/ko/pages/nomination.thtml
@@ -0,0 +1,10 @@
+<p>Sandboxì— ìžˆëŠ” 부가 ê¸°ëŠ¥ì€ ì›¹ 사ì´íŠ¸ì— 공개하기 위해 추천 ìž‘ì—…ì„ ê±°ì³ì•¼ 합니다. 테스트 ì‚¬ìš©ìž ë° íŽ¸ì§‘ìžì˜ í‰ê°€ë¥¼ ê±°ì³ ë¶€ê°€ 기능 사ì´íŠ¸ì— 게재 ë˜ê¸° 위해서 아래 ì‚¬í•­ì„ ì¤€ìˆ˜í•´ 주시기 ë°”ëžë‹ˆë‹¤.</p>
+<ul>
+ <li>í…Œë§ˆì¸ ê²½ìš° 미리 보기 ê·¸ë¦¼ì€ í•„ìˆ˜ ì´ë©°, 다른 부가 기능ì—ì„œë„ ê°€ê¸‰ì  ì¶”ê°€í•˜ì‹œê¸° ë°”ëžë‹ˆë‹¤.</li>
+ <li>부가 ê¸°ëŠ¥ì€ Sandboxì—ì„œ ì‚¬ìš©ìž ì˜ê²¬ ë° í‰ê°€ê°€ 축ì ë˜ëŠ” ê¸°ê°„ì´ í•„ìš” 합니다. <b>í‰ê°€ëŠ” 공개를 위해 필수ì ì¸ 사항입니다.</b></li>
+ <li>공개 가능한 부가 ê¸°ëŠ¥ì€ Sandboxì— ìžˆì„ ë•Œ 보다 ë”ìš± ì¢‹ì€ ê¸°ëŠ¥ì„ ì¶”ê°€í•˜ì—¬ 웹 브ë¼ìš°ì € ì´ìš©ì— ë„ì›€ì´ ë˜ì–´ì•¼ 합니다.</li>
+ <li>공개 추천 í‰ê°€ ë°©ì‹ì€ <a href="%s">부가 기능 ì •ì±…</a>ì„ ì°¸ê³ í•˜ì‹œê¸° ë°”ëžë‹ˆë‹¤.</li>
+</ul>
+<p>ë§Œì¼ ë¶€ê°€ ê¸°ëŠ¥ì´ ìœ„ì˜ í‰ê°€ ë°©ì‹ì— 부합 하면 아래 í•­ëª©ì„ ì±„ì›Œ 추천하시기 ë°”ëžë‹ˆë‹¤. 추천 ìƒíƒœì— 대한 진행 ì‚¬í•­ì„ ì´ë©”ì¼ë¡œ 받아보실 수 있습니다.</p>
+
+<p>부가 ê¸°ëŠ¥ì´ ì¶”ì²œ ë˜ë ¤ë©´ 오류 ë° ê²½ê³  ì‚¬í•­ì„ í¬í•¨í•´ì„œ 어떻게 테스트 하는 지와 웹 사용ìžì—게 ì–´ë–¤ ì´ìµì´ 있는지를 ìžì„¸ížˆ 설명하셔야 합니다. ë˜ëŠ” 외부 ì‚¬ìš©ìž í‰ê°€ ë§í¬ë¥¼ ì œê³µí•˜ì…”ë„ ë©ë‹ˆë‹¤.</p>
diff --git a/site/app/locale/ko/pages/policy.thtml b/site/app/locale/ko/pages/policy.thtml
new file mode 100644
index 0000000..1d84555
--- /dev/null
+++ b/site/app/locale/ko/pages/policy.thtml
@@ -0,0 +1,118 @@
+<h1>부가 기능 정책</h1>
+
+<h2>샌드 박스란 무엇입니까?</h2>
+<p>%s를 참고하시기 ë°”ëžë‹ˆë‹¤.</p>
+
+<h2>샌드 ë°•ìŠ¤ì— ìžˆëŠ” 부가 ê¸°ëŠ¥ì€ ë¬´ì—‡ìž…ë‹ˆê¹Œ?</h2>
+<p>
+샌드 박스는 addons.mozilla.org (AMO)ì— ë“±ë¡ëœ 모든 부가 ê¸°ëŠ¥ì´ ìµœì´ˆë¡œ 등ë¡ë˜ëŠ” 장소입니다.ê³µê°œëœ ë¶€ê°€ ê¸°ëŠ¥ì˜ ìƒˆë¡œìš´ 버전ì´ë‚˜ ì•„ì§ ê³µê°œë˜ì–´ 있지 ì•Šì€ ë¶€ê°€ ê¸°ëŠ¥ì˜ ëª¨ë“  ë²„ì „ì´ ì œê³µë˜ê³  있습니다.새로운 부가 기능나 ê¸°ì¡´ì˜ ë¶€ê°€ ê¸°ëŠ¥ì˜ ì—…ë°ì´íŠ¸ ë²„ì „ì€ AMOì— ë“±ë¡ë˜ë©´ ìš°ì„  ì´ ìƒŒë“œ ë°•ìŠ¤ì— ë†“ì—¬ì§‘ë‹ˆë‹¤.</p>
+
+<p>
+ëŒ€ë¶€ë¶„ì˜ ë¶€ê°€ ê¸°ëŠ¥ì˜ íŠ¹ì • ë²„ì „ì€ í‰ê°€ë¥¼ 받아야 합니다. 공개 가능한 ìƒíƒœê°€ ë˜ë ¤ë©´ AMO ì— ê³µê°œê°€ 타당할지 검토를 ë°›ì€ í›„ì— ê³µê°œë©ë‹ˆë‹¤. 기타 부가 ê¸°ëŠ¥ì€ ìƒŒë“œ 박스ì—ì„œ 보류ë©ë‹ˆë‹¤. 샌드 박스를 참조하고 ê·¸ê³³ì˜ ë¶€ê°€ 기능를 진행하고 시험하려고 하는 사용ìžë§Œì´ ì´ìš©í•  수 있습니다.</p>
+
+<h2>부가 ê¸°ëŠ¥ì€ ì–´ë–»ê²Œ 공개ë©ë‹ˆê¹Œ?</h2>
+<p>
+부가 ê¸°ëŠ¥ì€ ìƒŒë“œ ë°•ìŠ¤ì— ìžˆëŠ” 부가 기능를 사용하고 테스트하려는 AMO 사용ìžì— ì˜í•œ í‰ê°€ë¥¼ 받습니다. 사용ìžê°€ 쓰는 í‰ê°€ëŠ” 부가 기능를 모든 Firefox 사용ìžì—게 ê³µê°œí•´ë„ ì¶©ë¶„ížˆ ë„ì›€ì´ ë˜ëŠ”지 제대로 만들어졌는지 ê¸°ëŠ¥ìƒ ë¬¸ì œê°€ 없는지 여부를 í™•ì¸ í•©ë‹ˆë‹¤. ì´ í‰ê°€ëŠ” AMO íŒ€ì— ì˜í•œ 다른 í‰ê°€ ë° ì¡°ì‚¬ì™€ 함께 공개를 위해서 새로운 기능 추가가 필요하지 ì•Šì€ì§€ í˜¹ì€ AMOì—ì„œ ê·¸ 부가 ê¸°ëŠ¥ì˜ ê³µê°œê°€ íƒ€ë‹¹í• ì§€ì˜ íŒë‹¨ 기준으로서 ì´ìš©ë©ë‹ˆë‹¤.</p>
+
+<h2>ìžì‹ ì˜ 부가 기능를 공개하려면 어떻게 하면 좋습니까?</h2>
+<p>
+ìžì‹ ì˜ 부가 ê¸°ëŠ¥ì´ ê³µê°œ 부가 ê¸°ëŠ¥ì˜ ì¡°ê±´ì„ ê°–ì¶”ì—ˆë‹¤ê³  ìƒê°í•˜ëŠ” 경우는 ê°œë°œìž ì œì–´íŒì—ì„œ 추천 ì‹ ì²­ì„ í•  수 있습니다.</p>
+
+<h2>공개를 위한 부가 기능 조건</h2>
+<p>AMOì—ì„œ 공개ë˜ëŠ” 부가 ê¸°ëŠ¥ì€ ì¶©ë¶„í•œ í’ˆì§ˆì„ ê°–ì¶”ì–´ 사용ìžì—게 유용하며 웹ì—ì„œ 훌륭한 ì²´í—˜ì„ ì œê³µí•˜ëŠ” 것ì´ì—¬ì•¼ 합니다. 우리는 공개 게재가 타당할지를 íŒë‹¨í•˜ê¸° 위해 아래 ì‚¬í•­ì„ ìš”êµ¬í•˜ê³  있습니다.</p>
+
+<h3>빠르게 ë¬¸ì œì— ëŒ€í•œ 대ì‘ì´ ê°€ëŠ¥í•œê°€?</h3>
+<p>
+우리는 ë§Žì€ Firefox 사용ìžì—게 향해서 부가 기능를 í™ë³´í•˜ë ¤ê³  하는 ê°œë°œìž ì—¬ëŸ¬ë¶„ì— ëŒ€í•´ì„œ ì œì¶œëœ ë¬¸ì œì— ì±…ìž„ì„ ê°€ì ¸ í•­ìƒ ìµœì‹ ì˜ ì—°ë½ì²˜ 정보를 제공하여 Firefox 제품 출시나 AMO ì •ì±…ì„ ë³€ê²½ í–ˆì„ ë•Œ 빠르고 ì‹ ì†í•˜ê²Œ 부가 ê¸°ëŠ¥ì„ ì—…ë°ì´íŠ¸ 해주기를 ë°”ë¼ê³  있습니다. ì´ê²ƒì€ ì˜ê²¬ìœ¼ë¡œ ê²Œìž¬ëœ ì§ˆë¬¸ì„ ëª¨ë‘ ë‹µí•˜ê±°ë‚˜ 버그를 수정해야 한다는 ê²ƒì€ ì•„ë‹™ë‹ˆë‹¤. 그러나 ë¬¸ì œì— ëŒ€í•´ì„œë„ ë¹ ë¥´ê²Œ 대ì‘í•´ 주기를 ë°”ëžë‹ˆë‹¤.</p>
+
+<h3>정확한 ì„¤ëª…ì„ ì œê³µí•˜ê³  있는가?</h3>
+
+<p>
+우리는 사용ìžê°€ 새로운 부가 기능를 시험할 ë•Œ 기대한 ê¸°ëŠ¥ì„ ì–»ì„ ìˆ˜ ìžˆì„ ê²ƒì¸ì§€ë¥¼ 가장 중요시 하고 있습니다. 부가 ê¸°ëŠ¥ì˜ ì„¤ëª…ì—는 ì–´ë– í•œ ê¸°ëŠ¥ì´ í¬í•¨ë˜ì–´ 있는지 어떻게 하면 활용할 수 있는지 설치 후 ë¬´ì—‡ì„ ê¸°ëŒ€í•  수 ìžˆëŠ”ì§€ì— ëŒ€í•´ ìƒì„¸ížˆ 기술 해야 합니다. 보다 ìžì„¸í•œ ì´ìš© ë°©ë²•ì— ê´€í•´ì„œëŠ” ì™¸ë¶€ì˜ ë¬¸ì„œì— ë§í¬í•´ë„ ìƒê´€í•˜ì§€ 않습니다만 ì„¤ëª…ë§Œìœ¼ë¡œë„ ê¸°ë³¸ì ì¸ 정보를 í¬í•¨í•˜ì—¬ ì–´ë– í•œ ê¸°ëŠ¥ì„ ì´ìš©í•  수 있는지 사용ìžì—게 올바르게 전달할 필요가 있습니다.</p>
+<p>
+ë˜ ë¶€ê°€ ê¸°ëŠ¥ì— ê¸°ëŠ¥ 추가나 변경 ì‚¬í•­ì´ ìžˆëŠ” 경우 ì´ì „ 버전 기ë¡(Change history)ì„ ì œê³µí•˜ëŠ” ê²ƒë„ ì¤‘ìš”í•©ë‹ˆë‹¤. ì´ë¯¸ 부가 기능를 설치한 사용ìžê°€ 새로운 ë²„ì „ì˜ ì‹ ê¸°ëŠ¥ì´ë‚˜ 개량ì ì„ ì•Œ 수 있ë„ë¡ í•´ 주시기 ë°”ëžë‹ˆë‹¤. ì—…ë°ì´íŠ¸ì— ì˜í•´ ì‚¬ìš©ì— ìžˆì–´ ì˜í–¥ì„ 줄만한 ì‚¬í•­ì´ ìžˆëŠ” 경우는 반드시 ê±°ê¸°ì— ê´€í•œ 변경ì ë„ 설명하여야 합니다. (현 ì‹œì ì—서는 웹 브ë¼ìš°ì €ë‚´ì—ì„œ 변경 사항 ë° ë²„ì „ 기ë¡ì„ 표시하는 ë°©ë²•ì€ ì—†ìŠµë‹ˆë‹¤ë§Œ 향후 ì´ ì ì— 대해서는 ìˆ˜ì •ì„ ì‹¤ì‹œí•  예정입니다. 버전 ì´ë ¥ì„ 제대로 제공하고 있으면, ì—…ë°ì´íŠ¸ ì „í›„ì— ì‚¬ìš©ìžì—게 있어서는 ë§Žì´ ë„ì›€ì´ ë©ë‹ˆë‹¤.)</p>
+
+<h3>ê°œì¸ ì •ë³´ 보호 ì •ì±… ë° ë³´ì•ˆì— ëŒ€í•œ ì‚¬í•­ì´ ëª¨ë‘ ëª…ê¸°ë˜ì–´ 있는가?</h3>
+<p>
+ê°œì¸ ì •ë³´ 보호 ë° ë³´ì•ˆì— ëŒ€í•´ 가장 올바르고 정확한 ì„¤ëª…ì´ ì–´ë–¤ 것ì¸ì§€ì— 대한 í•´ì„차가 존재합니다만 ì´ê²ƒì€ 우리로서는 구체ì ì¸ ì–¸ê¸‰ì„ í•´ì•¼ í•  가장 중요한 ì¼ì¤‘ 하나ë¼ê³  ìƒê° 합니다. 매우 편리하게 잘 만들어진 부가 ê¸°ëŠ¥ì€ ëŒ€ë¶€ë¶„ì˜ ê²½ìš° ì–´ë– í•œ 형태로 사용ìžì˜ ë°ì´í„°ë¥¼ 조작하고 있거나 í˜¹ì€ ìž˜ëª»ëœ ì‚¬ìš©ì„ í–ˆì„ ë•Œì— ë³´ì•ˆ ìƒ ë¬¸ì œì ì´ í‘œë©´í™”ë  ê°€ëŠ¥ì„±ì„ í¬í•¨í•˜ê³  있습니다. 그러한 경우 AMOì— ê³µê°œëŠ” 가능하지만 ì¼ë°˜ 사용ìžì—게 ì–´ë– í•œ ìœ„í—˜ì„ ìˆ˜ë°˜í•  ê°€ëŠ¥ì„±ì´ ìžˆëŠ”ì§€ ë˜ëŠ” ì‚¬ìš©ìž ìŠ¤ìŠ¤ë¡œ ìžì‹ ì´ 위험으로부터 보호할 ë°©ë²•ì„ ë¶„ëª…ížˆ 설명하여야 합니다.</p>
+
+<h3>충분한 테스트를 ê±°ì³ ì¤‘ëŒ€í•œ ê²°í•¨ì€ ì—†ëŠ”ê°€</h3>
+
+<p>
+우리는 부가 ê¸°ëŠ¥ì˜ ê³µê°œë¥¼ 검토할 ë•Œ 샌드 ë°•ìŠ¤ì— ìžˆëŠ” 부가 ê¸°ëŠ¥ì˜ í‰ê°€ê°€ 실제 테스트를 받아 등ë¡ëœ 것ì¸ì§€ë¥¼ ì˜ë¯¸í•˜ëŠ” 것으로 심ê°í•œ 문제나 웹 브ë¼ìš°ì €ì— 대한 ì•…ì˜í–¥ì´ 없는가ë¼ëŠ” ì ì„ 중요한 ì¡°ê±´ì˜ í•˜ë‚˜ë¡œì„œ ìƒê°í•˜ê³  있습니다. 부가 ê¸°ëŠ¥ì˜ ê¸°ëŠ¥ì„ í…ŒìŠ¤íŠ¸í•˜ê³  ìžˆì„ ë•Œ 중대한 ì„±ëŠ¥ìƒ ë¬¸ì œë‚˜ 충ëŒì— ë”°ë¼ ë¬¸ì œê°€ 빈번히 ë°œìƒí•œ 경우나 오류 ì •ë³´ì— ë‹¤ìˆ˜ì˜ ì˜¤ë¥˜ 메세지가 ì¶œë ¥ëœ ê²ƒì´ í‰ê°€ 담당ìžë¡œë¶€í„° ë³´ê³ ëœ ê²½ìš° 그러한 사항를 진지하게 파악해서 가능한 í•œ 문제를 í•´ê²°í•œ ë‹¤ìŒ ë‹¤ì‹œ 공개 ì‹ ì²­ì„ í•˜ì…”ì•¼ 합니다. 우리는 완벽한 최ì í™”와 모든 ë²„ê·¸ì˜ ìˆ˜ì •ì„ ìš”êµ¬í•˜ê³  있지는 않으며 문제ì ì— 대해서는 Firefox ìžì²´ë„ 계ì†ì ì¸ ê°œì„ ì„ í•´ 오고 있습니다.문제를 최소한으로 억제하기 위해 ìƒë‹¹í•œ ë…¸ë ¥ì„ ì§„í–‰í–ˆì§€ë§Œ 여전히 문제가 남아 있어 사용ìžì—게 ì˜í–¥ì„ 주는 경우ì—는 ê·¸ ë‚´ìš©ì„ ëª…ê¸°í•˜ì‹œê¸° ë°”ëžë‹ˆë‹¤.</p>
+
+<p>AMO 샌드 박스가 아니고 ìžì‚¬ 제공 ì„œë¹„ìŠ¤ì˜ ì‚¬ìš©ìž ê·¸ë£¹ì´ë‚˜ ì‚¬ë‚´ì˜ í’ˆì§ˆ ë³´ì¦ íŒ€ë“± ì™¸ë¶€ì˜ í”„ë¡œì„¸ìŠ¤ë¥¼ 통해서 테스트를 ì‹¤ì‹œí–ˆì„ ê²½ìš° 공개 ì‹ ì²­ ì‹œì— ê·¸ê²ƒì„ ì•Œë ¤ 주시기 ë°”ëžë‹ˆë‹¤. ì–´ëŠ ì •ë„ í…ŒìŠ¤íŠ¸ë¥¼ 했는지를 확실히 ìž…ì¦í•  수 있으면 부가 ê¸°ëŠ¥ì˜ ê³µê°œ í‰ê°€ì— 참고 ìžë£Œê°€ ë©ë‹ˆë‹¤.</p>
+
+<h3>개발ìžê°€ 사용ìžë¥¼ 보호하고 있는가?</h3>
+
+<p>부가 ê¸°ëŠ¥ì€ ë¶ˆí•„ìš”í•˜ê²Œ 사용ìžì˜ ê°œì¸ ì •ë³´ë¥¼ 침해하거나 사용ìžë¥¼ ì†ì´ë ¤ê³  하거나 ê¸°ëŠ¥ì„ ì€í 하려고 해서는 안ë©ë‹ˆë‹¤. ë˜ ì‚¬ìš©ìžëŠ” (í˜¹ì€ ì‚¬ìš©ìžê°€ 아니어ë„)
+때로 ì•…ì˜ì ì¸ ë‚´ìš©ì˜ ì˜ê²¬ì„ 제공하는 경우가 있고 ì´ë¥¼ 배제하기 위해 노력하고 있지만, ê°œë°œìž ìŠ¤ìŠ¤ë¡œ ì¼ë°˜ 사용ìžì—게 ë˜‘ê°™ì€ ëŒ€ì‘ì„ í•˜ì§€ ì•Šë„ë¡ í•´ 주시기 ë°”ëžë‹ˆë‹¤.</p>
+
+<h3>ì¼ë°˜ ëŒ€ì¤‘ì  ì‚¬ìš©ìžì—게 ë„ì›€ì´ ë  ê²ƒì¸ê°€?</h3>
+
+<p>Greasemonkey나 FireBug와 ê°™ì€ ì¸ê¸° 있는 부가 ê¸°ëŠ¥ì´ ë  í•„ìš”ëŠ” 없습니다만 ì ì–´ë„ 등ë¡í•œ 부가 ê¸°ëŠ¥ì´ ë‹¹ì‹ ì˜ íšŒì‚¬ ì§ì›ì´ë‚˜ ì†Œê·œëª¨ì˜ ì›¹ ì»¤ë®¤ë‹ˆí‹°ì˜ ë©¤ë²„ ë°–ì— ë„ì›€ì´ ë˜ì§€ 않는 듯한 경우 우리는 모든 Firefox 사용ìžì—게 공개하기ì—는 ì•„ì§ ì´ë¥´ë‹¤ê³  íŒë‹¨í•  것입니다.</p>
+
+<p>우리는 í•­ìƒ ì›¹ 사ì´íŠ¸ êµ¬ì„±ì„ ê°œì„ í•´ 부분ì ìœ¼ë¡œ 다른 부가 ê¸°ëŠ¥ì˜ ëª¨ë²”ì´ ë˜ëŠ” 한편 잠재ì ì¸ ì‚¬ìš©ìž í˜¹ì€ ì†Œê·œëª¨ ì»¤ë®¤ë‹ˆí‹°ë§Œì„ ëŒ€ìƒìœ¼ë¡œ 하고 있는 부가 기능를 어떻게 취급해야할 것ì¸ê°€ë¥¼ 모색하고 있습니다. ê°œë°œìž ì—¬ëŸ¬ë¶„ì´ ë¶€ê°€ 기능 분류와 기타 정보를 ì ì ˆížˆ 입력해 주시면 부가 ê¸°ëŠ¥ì— ì˜í•´ 가장 혜íƒì„ 받게 ë  ì‚¬ìš©ìžì—게 ì œê³µë  ìˆ˜ 있는 ë°©ë²•ì„ ì°¾ì•„ë‚¼ 수 있습니다.</p>
+
+<p>ì—¬ëŸ¬ë¶„ì˜ ë¶€ê°€ ê¸°ëŠ¥ì´ ì›¹ 사ì´íŠ¸ë¡œ ë¶ë§ˆí¬ 등 단순한 액세스 ë°©ë²•ì„ ì œê³µí•  만한 경우 AMOì—서는 공개하지 않습니다.다른 Mozilla 프로ì íŠ¸ 처럼 우리는 새로운 웹 애플리케ì´ì…˜ì´ë‚˜ 웹 서비스를 소중히 ìƒê°í•©ë‹ˆë‹¤ë§Œ Firefox 부가 ê¸°ëŠ¥ì€ ë³´ë‹¤ ì¢‹ì€ ë¸Œë¼ìš°ì§• ì²´í—˜ì„ ì‚¬ìš©ìžì—게 제공해 하며 AMOì— ë“±ë¡í•˜ì—¬ 단순한 ì‹ ê·œ 사ì´íŠ¸ë¥¼ í™ë³´ 하는 ê²ƒì€ ì›í•˜ëŠ” 바가 아닙니다. 부가 ê¸°ëŠ¥ì˜ ì„¤ëª…ì´ ì‚¬ìš©ìžì˜ 웹 브ë¼ìš°ì§• 사용 경험 í–¥ìƒì— 관한 ê²ƒì€ ì•„ë‹ˆê³  주로 ì„œë¹„ìŠ¤ì— ê´€í•œ ë‚´ìš©ì´ì—ˆì„ 경우 ê·¸ê²ƒì€ ì˜¬ë°”ë¥¸ ë°©í–¥ì´ë¼ê³  í•  수 ì—†ì„ ê²ƒìž…ë‹ˆë‹¤.</p>
+
+<h3>ìƒí‘œê¶Œì´ë‚˜ ì €ìž‘ê¶Œì˜ ì¹¨í•´ëŠ” 없는가?</h3>
+
+<p>ì œ 3ìžì˜ ìƒí‘œë‚˜ ì €ìž‘ê¶Œì„ ì¹¨í•´í•˜ê³  있는 부가 ê¸°ëŠ¥ì€ ê¶Œë¦¬ìžì—게서 문제가 없다고 ìƒê°ë˜ëŠ” 경우ì—ë„ ë“±ë¡í•  수 없습니다. ìƒí‘œê°€ ë˜ëŠ” 명칭ì´ë‚˜ 로고를 사용하는 허가를 얻지 ì•Šì€ ê²½ìš° ê·¸ 부가 ê¸°ëŠ¥ì„ AMOì— ë“±ë¡í•˜ëŠ” ê²ƒì€ ì—­ì‹œ 마찬가지 입니다. ì œ 3ìžê°€ ì €ìž‘ê¶Œì„ ë³´ìœ í•˜ëŠ” 소스 코드가 í¬í•¨ë˜ì–´ 있고 ê·¸ 부가 ê¸°ëŠ¥ì— ìžˆì–´ì„œì˜ ì‚¬ìš© 허가를 얻지 ì•Šì€ ê²½ìš°ë„ ë˜‘ê°™ì´ ë“±ë¡ì„ 거절합니다. (권리ìžë¡œë¶€í„° ìƒí‘œë‚˜ ì €ìž‘ë¬¼ì˜ ì‚¬ìš©ì— ê´€í•´ì„œ ì´ì˜ 제기가 ìžˆì—ˆì„ ê²½ìš° 전문가ì—게 ì‚­ì œ 요구 í‰ê°€ë¥¼ ì˜ë¢°í•´ì•¼ 하게 ë  ê°€ëŠ¥ì„±ì´ ë†’ê³  법ì ì¸ ë¶€ë¶„ì´ íŒë‹¨ë˜ë©´ 부가 ê¸°ëŠ¥ì„ ì‚­ì œí•˜ê²Œ ë©ë‹ˆë‹¤. ì´ê²ƒì€ 시간과 ìž¬ì •ì  ë¬¸ì œì—ì„œ 프로ì íŠ¸ ìžì›ì„ 낭비하게 ë˜ê¸° ë•Œë¬¸ì— ê°œë°œìžë“¤ì€ ì œ 3ìžì˜ 권리를 존중해 우리ì—게 ê³¼ë„í•œ ë¶€ë‹´ì„ ì£¼ì§€ ì•Šë„ë¡ í•´ì£¼ì‹œê¸° ë°”ëžë‹ˆë‹¤.)</p>
+
+<p>부가 ê¸°ëŠ¥ì˜ ì œëª©ì´ë‚˜ ê·¸ ì•ˆì— í¬í•¨ë˜ì–´ 있는 소스 코드 ë“±ì´ ì—¬ëŸ¬ 가지 ì´ìœ ë¡œ AMO 게재가 가능한가 í™•ì‹ ì„ ê°€ì§ˆ 수 없는 경우는 amo-editors@mozilla.orgì— í‰ê°€ë¥¼ ë°›ì„ ìˆ˜ 있습니다. ì£¼ì˜ ì‚¬í•­: ì´ ê·¸ë£¹ì€ ë²•ì ì¸ 권고를 하지 않습니다.ë˜í•œ, 우리가 ë‹¹ì‹ ì˜ ì´ìš© 형태를 허용 범위ë¼ê³  íŒë‹¨í–ˆì„ 경우ì—ë„ ê¶Œë¦¬ìžì˜ í´ë ˆìž„ì´ë‚˜ 전문가 ì¡°ì–¸ì— ë”°ë¥´ê³  재검토를 실시할 수 있습니다.</p>
+
+<p>다른 부가 ê¸°ëŠ¥ì— í¬í•¨ëœ 소스 ì½”ë“œì˜ ìž¬ì´ìš©ì— 관해 (예를 들면 오픈 소스 ë¼ì´ì„¼ìŠ¤ 등) 소스 코드 사용 허가가 개발ìžì— ì˜í•´ì„œ 명기ë˜ì–´ 있지 ì•Šì€ ê²½ìš° 사용 허가를 얻지 못했다고 ìƒê°í•˜ì‹œê¸° ë°”ëžë‹ˆë‹¤. ì´ ê²½ìš° 개발ìžì—게 ì—°ë½ì„ 하고 허가를 요구하는 ê²ƒì´ ì¢‹ì„ ê²ƒìž…ë‹ˆë‹¤. 부가 ê¸°ëŠ¥ì´ ì´ë¯¸ AMO ì— ë“±ë¡ë˜ì–´ 있기 ë•Œë¬¸ì— í˜¹ì€ ìž‘ìžë¡œë¶€í„° ë‹µì‹ ì´ ì—†ëŠ” ì‚¬ì •ì´ ìžˆì—ˆë‹¤ê³  í•´ë„ ìš°ë¦¬ëŠ” 당신ì—게 특별한 í—ˆë½ì„ í•  수 없습니다. (다시 ë§í•´ 우리는 법ì ì¸ ì¡°ì–¸ì„ ë“œë¦´ 수 없습니다. 어떻게 하면 ì´ ì‚¬ì´íŠ¸ì˜ ì •ì±…ì— ë”°ë¥¸ 부가 기능를 등ë¡í•  수 있는지 ì¼ë°˜ì ì¸ 범위ì—ì„œ 조언만 제공할 수 있습니다.)</p>
+
+<p>ìœ„ì˜ ì‚¬í•­ì€ã€ŒMozillaã€,「Firefoxã€, 「Thunderbirdã€ë“± Mozilla Foundationì˜ ìƒí‘œì—ë„ í•´ë‹¹ ë©ë‹ˆë‹¤. Mozillaì˜ ìƒí‘œ ì •ì±…ì€ ë¬´ë¶„ë³„í•œ ì´ìš©ì— 따른 í˜¼ëž€ì„ ë§‰ê³  ì œ 3ìžì— ì˜í•´ ìƒí‘œê°€ 뒤바뀌는 ê²ƒì„ ë§‰ê¸° 위해 법ì ì¸ 보호를 받습니다. ì´ëŸ¬í•œ ë³´í˜¸ì˜ í•„ìš”ì„±ì„ ê³ ë ¤í•´ 주셔서 Mozilla Foundationì˜ ê°€ìž¥ 귀중한 ìž¬ì‚°ì˜ ìœ ì§€ì— í˜‘ë ¥í•´ 주시기 ë°”ëžë‹ˆë‹¤.</p>
+
+<h2>공개 ì‹ ì²­ 후 ì–´ë–¤ ê³¼ì •ì„ ê±°ì¹©ë‹ˆê¹Œ?</h2>
+
+<p>공개 ì‹ ì²­ëœ ë¶€ê°€ ê¸°ëŠ¥ì€ AMOì˜ íŽ¸ì§‘íŒ€ì— ì˜í•´ ìƒê¸° ì¡°ê±´ì„ ê¸°ì¤€ìœ¼ë¡œ í‰ê°€ë©ë‹ˆë‹¤.공개가 가능하다고 íŒë‹¨ë˜ì—ˆì„ 경우는 í‰ê°€ ì¢…ë£Œí›„ì— ê³µê°œ 페ì´ì§€ì— 게재ë˜ê³  개발ìžì—게는 ë©”ì¼ë¡œ 알려드립니다.</p>
+
+<p>만약 AMO 공개가 타당하지 않다고 íŒë‹¨ë˜ì—ˆì„ 경우는 ê·¸ ì´ìœ ë¥¼ ì ì€ 통지가 보내지고 공개 ì‹ ì²­ì€ ì·¨ì†Œ ë©ë‹ˆë‹¤. ê·¸ ë©”ì¼ì— 쓰여진 문제ì ì„ 해결하고 나서 재차 í‰ê°€ë¥¼ ì˜ë¢°í•˜ê³  ì‹¶ì€ ê²½ìš°ëŠ” ìžì‹ ì˜ íŒë‹¨ì— ë”°ë¼ ìž¬ì‹ ì²­ì´ ê°€ëŠ¥í•©ë‹ˆë‹¤. ë§Œì¼ ë¶€ê°€ ê¸°ëŠ¥ì— ëŒ€í•œ ê°œì„ ì„ ì‹¤ì‹œí•˜ì§€ ì•Šê³  재차 ì‹ ì²­ì„ í•´ë„ ê·¸ ì‹ ì²­ì€ í˜¸ì˜ì ìœ¼ë¡œ ë³´ì´ì§€ 못하고 담당ìžì˜ ì¼ì„ 늘어나게 하기 ë•Œë¬¸ì— ì‹ ì¤‘í•˜ê²Œ ìž¬ì‹ ì²­ì„ í•˜ì‹œê¸° ë°”ëžë‹ˆë‹¤.</p>
+
+<h2>타ì¸ì˜ 부가 ê¸°ëŠ¥ì„ ê³µê°œ ì‹ ì²­í•  수 있습니까?</h2>
+
+<p>현재는 ê°œë°œìž ìŠ¤ìŠ¤ë¡œ 만든 부가 ê¸°ëŠ¥ë§Œì„ ì‹ ì²­í•  수 있ë„ë¡ í•˜ê³  있습니다. 우리는 ê°œë°œìž ì—¬ëŸ¬ë¶„ì´ ê³µê°œ 기회가 ì¦ê°€í•˜ëŠ” 것 보다 개발ìžì— ì˜í•œ ìž‘ì—… ë‚´ìš©ì´ ë¶€ê°€ ê¸°ëŠ¥ì— ì ì ˆížˆ ë°˜ì˜ë˜ê³  있는지를 확ì¸í•  수 있는 ê²ƒì´ ì¢‹ë‹¤ê³  ìƒê°í•©ë‹ˆë‹¤. 만약 ì–´ë–¤ 부가 ê¸°ëŠ¥ì˜ ê¸°ëŠ¥ì´ í›Œë¥­í•˜ê³  ìƒê¸°í•œ AMO ì •ì±…ì„ ìž˜ 따르고 ìžˆì„ ë¿ ì•„ë‹ˆë¼ 1억명 ì´ìƒì˜ Firefox와 웹 브ë¼ìš°ì € 사용ìžì—게 ë„ì›€ì´ ëœë‹¤ê³  ìƒê°í•˜ëŠ” 경우 개발ìžì—게 ì—°ë½í•˜ì…”ì„œ 부가 기능 등ë¡ì„ 권해 주시기 ë°”ëžë‹ˆë‹¤.
+</p>
+
+<h2>공개가 늦어지는 ê²ƒì´ ì´ìœ ê°€ 있습니까?</h2>
+
+<p>우리는 ê°œë°œìž í•œëª… í•œëª…ì„ ì‹«ì–´í•˜ê±°ë‚˜ 하지 않습니다. 우리는 부가 기능 ê°œë°œìž ì—¬ëŸ¬ë¶„ì„ ì†Œì¤‘ížˆ ìƒê°í•´ 만족ë„ê°€ 높아 지ë„ë¡ ê·¸ë¦¬ê³  사용ìžê°€ ê·¸ ì„±ê³¼ì— ì˜í•´ì„œ 혜íƒì„ 받게 ë˜ë„ë¡ ë…¸ë ¥í•˜ê³  있습니다. 그러나, 최종 게재ë˜ëŠ” 부가 ê¸°ëŠ¥ì˜ ì‹¬ì‚¬ì—는 ì‹ ì¤‘ì„ ìš”í•˜ê¸° ë•Œë¬¸ì— AMO 공개는 매우 중요하여 서둘러 진행시킬 수 없습니다. 우리는 í‰ê°€ 결과를 기다리는 ê²ƒì´ ë•Œì— ìŠ¤íŠ¸ë ˆìŠ¤ê°€ 쌓ì¸ë‹¤ëŠ” ê²ƒì„ ì´í•´í•˜ê³  있으며 대기 ì‹œê°„ì„ ê°€ëŠ¥í•œ í•œ 짧게 하기 ì›í•˜ê³  있습니다. 샌드 박스내ì—ì„œ 보다 ë§Žì€ ì‚¬ìš©ìžê°€ 꼼꼼하고 명확한 í‰ê°€ë¥¼ í•´ 주면 í‰ê°€ ê¸°ê°„ì´ ë” ë¹¨ë¦¬ 단축ë˜ë¯€ë¡œ 만약 샌드 ë°•ìŠ¤ì— í¥ë¯¸ê°€ 가는 부가 ê¸°ëŠ¥ì´ ìžˆìœ¼ë©´ ê¼­ í‰ê°€ì— 협력해 주시기 ë°”ëžë‹ˆë‹¤.</p>
+
+<h2>부가 ê¸°ëŠ¥ì— ì‹¬ê°í•œ 버그가 있어 바로 수정íŒì„ 공개하기 ì›í•©ë‹ˆë‹¤?</h2>
+
+<p>수정íŒì„ 즉시 공개할 필요가 있는 심ê°í•œ 버그(보안 ë° ì•ˆì •ì„±ê³¼ ê°™ì€ ì¤‘ëŒ€í•œ ê¸°ëŠ¥ìƒ ë¬¸ì œ)ê°€ 있는 경우 수정 ë²„ì „ì„ ë“±ë¡í•  ë•Œ 「í‰ê°€ 담당ìžì—게 ì—°ë½ ì‚¬í•­ã€ì„ 통해서 ê·¸ê²ƒì„ ì•Œë ¤ 주시기 ë°”ëžë‹ˆë‹¤. 물론 버전 ì´ë ¥ì—ë„ ê·¸ ë‚´ìš©ì„ ëª…ê¸°í•´ 주십시오. ë˜í•œ, 몇몇 기존 사용ìžì—게 í˜‘ë ¥ì„ ìš”ì²­í•˜ê³  샌드 박스내ì—ì„œ ì—…ë°ì´íŠ¸ 버전 테스트를 실시하여 ê·¸ 결과를 ìžì„¸í•˜ê²Œ ë³´ê³ í•´ 주는 ê²ƒë„ í•˜ë‚˜ì˜ ë°©ë²•ìž…ë‹ˆë‹¤. irc.mozilla.orgì˜ #addons 채ë„ì— ë“¤ì–´ê°€ë©´ 담당ìžì—게 ì§ì ‘ ìƒí™©ì„ 알릴 ìˆ˜ë„ ìžˆìŠµë‹ˆë‹¤ë§Œ ì´ ê²½ìš° 정중하게 요청해 주시기 ë°”ëžë‹ˆë‹¤.</p>
+
+<p>ë§ë¶™ì—¬ ê±°ì§“ëœ ì •ë³´ë¥¼ 제공하시면 안ë©ë‹ˆë‹¤. 우리는 ìš°ì„  순위가 ë†’ì€ ë³€ê²½ì‚¬í•­ì— ëŒ€í•´ì„œ 시급하게 í‰ê°€ë¥¼ 실시하고 있습니다만 ê·¸ ìž‘ì—…ì— ë•Œë¬¸ì— ì‹ ì²­ë°›ì€ ë‹¤ë¥¸ 부가 기능 ë° ì‹ ê·œ ë²„ì „ì„ í‰ê°€í•˜ëŠ” ì‹œê°„ì´ í•„ìš”í•˜ì—¬ ê°€ë” ìˆ˜ë©´ 시간ì´ë‚˜ ì¹œêµ¬Â·ê°€ì¡±ê³¼ì˜ ì‹œê°„ê¹Œì§€ë„ í¬ìƒí•´ì•¼ 하ë„ë¡ ã€Œí‰ê°€ 대기 순위ã€ë¥¼ ì´ìš©í•˜ë ¤ê³  하는 개발ìžë¥¼ 좋아하지 않습니다. ì´ëŸ¬í•œ ê³¼ì •ì„ ì´ìš©í•´ë„ 좋ì„지 ìžì‹ ì´ ì—†ì„ ë•ŒëŠ” irc.mozilla.org ì˜ #addons 채ë„ë¡œ ì¡°ì–¸ì„ ìš”ì²­í•˜ì‹œê¸° ë°”ëžë‹ˆë‹¤.</p>
+
+<h2>부당한 í‰ê°€ë¥¼ 받는 것 ê°™ì€ë° 어떻게 하면 좋ì„까요?</h2>
+
+<p>ë‹¹ì‹ ì˜ ë¶€ê°€ ê¸°ëŠ¥ì´ ë¶€ë‹¹í•˜ê²Œ í‰ê°€ë˜ì–´ ê·¸ ê²°ê³¼ 공개 ì‹ ì²­ì´ ì·¨ì†Œ ë˜ì—ˆë‹¤ê³  ìƒê°ë˜ëŠ” 경우는 amo-editors@mozilla.orgì— ë©”ì¼ì„ ë³´ë‚´ ì´ìœ ë¥¼ ìžì„¸í•˜ê²Œ 설명해 주시기 ë°”ëžë‹ˆë‹¤. 정중한 ë°©ì‹ìœ¼ë¡œ 논리ì ìœ¼ë¡œ 부가 ê¸°ëŠ¥ì´ ì–´ë–»ê²Œ 부당하게 í‰ê°€ë˜ì—ˆëŠ”지를 구체ì ìœ¼ë¡œ 설명해 주시기 ë°”ëžë‹ˆë‹¤.</p>
+
+<p>(공개 ì‹ ì²­ ê²°ê³¼ í†µì§€ì— ë¬¸ì œê°€ 쓰여져 있고 ìˆ˜ì •ì´ ëª¨ë‘ ì™„ë£Œí–ˆì„ ê²½ìš°ëŠ” í‰ê°€ ê²°ê³¼ì— í•­ì˜í•˜ëŠ” ê²ƒì´ ì•„ë‹ˆë¼ ê°œë°œìž ì œì–´íŒì„ 통해서 재 ì‹ ì²­ì„ í•´ 주시기 ë°”ëžë‹ˆë‹¤.)</p>
+
+<h2>ê³µê°œëœ ë¶€ê°€ ê¸°ëŠ¥ì´ ê°‘ìžê¸° 샌드 ë°•ìŠ¤ì— ë“¤ì–´ê°”ìŠµë‹ˆë‹¤.</h2>
+
+<p>부가 ê¸°ëŠ¥ì´ AMO 사ì´íŠ¸ì˜ 공개 ì¡°ê±´ì— ë§žì§€ 않게 ë˜ì—ˆì„ 경우 ê·¸ 부가 ê¸°ëŠ¥ì€ ìƒŒë“œ 박스로 ë˜ëŒë ¤ì§‘니다. ì´ëŸ¬í•œ 처리를 실시할 때는 ë²•ì  ì œí•œì´ ì—†ëŠ” í•œ 개발ìžì—게 ë©”ì¼ë¡œ 통지해 비공개가 ëœ ì´ìœ ë¥¼ 설명합니다.</p>
+
+<p>부가 ê¸°ëŠ¥ì˜ ê³µê°œì— ê´€í•´ì„œ 사ì´íŠ¸ì— 버그를 ì°¾ì•„ëƒˆì„ ê²½ìš°ëŠ” Bugzilla를 통해서 보고를 실시해 주세요.「addons.mozilla.orgã€ì œí’ˆì˜ 「Public Pagesã€í•­ëª©ì„ ì„ íƒí•˜ê³  가능한 í•œ ìžì„¸í•˜ê²Œ ìƒí™©ì„ 설명해 주시기 ë°”ëžë‹ˆë‹¤.</p>
+
+<h2>ìžì‹ ì˜ 부가 ê¸°ëŠ¥ì´ ã€Œì¶”ì²œ 부가 기능ã€ëª©ë¡ì— í¬í•¨ë  수 있나요?</h2>
+
+<p>개발한 부가 기능 부가 ê¸°ëŠ¥ì´ ë›°ì–´ë‚œ 사례가 ë˜ì–´ 확장성과 커스터마ì´ì¦ˆì„±ì´ ë›°ì–´ë‚œ 웹 브ë¼ìš°ì €ì¸ Firefoxì˜ ê°€ì¹˜ë¥¼ 실제로 ì¦ëª…하여 ì‚¬ìš©ì„ ì´‰ì§„í•  ë¿ë§Œ ì•„ë‹ˆë¼ ë›°ì–´ë‚œ ì‚¬ìš©ìž ì²´í—˜ì„ ì œê³µí•˜ëŠ” 경우 「추천 부가 기능ã€ëª©ë¡ì— 추가 검토를 ì˜ë¢°í•  수 있습니다. amo-editors@mozilla.orgì— ë©”ì¼ì„ ë³´ë‚´ ë‹¹ì‹ ì˜ ë¶€ê°€ ê¸°ëŠ¥ì˜ ìž¥ì ì„ 설명해 주시기 ë°”ëžë‹ˆë‹¤. </p>
+
+<p>
+ë©”ì¼ì—는 「ì ì–´ë„ã€ì•„래 í•­ëª©ì— ëŒ€í•œ 정보를 기술해 주세요.</p>
+<ul>
+
+<li>ì¼ë°˜ 사용ìžì˜ 웹 사용 경험ì„ì´ ì–¼ë§ˆë‚˜ í–¥ìƒí•´ 주는가?</li>
+<li>ì¼ë°˜ Firefox 사용ìžì—게 있어서 ê·¸ 부가 ê¸°ëŠ¥ì´ ì–¼ë§ˆë‚˜ ì í•©í•œê°€?</li>
+<li>부가 ê¸°ëŠ¥ì´ Mozilla 프로ì íŠ¸ì˜ 가치를 ì¦ëª…하고 사용ìžì—게 맞춤형 서비스 ë° ë³´ì•ˆ 기능 제공, ì›¹ì˜ ë³´íŽ¸ì ì¸ ì ‘ê·¼ì„ ìœ„í•œ 개방 표준 ë°ì´í„° í™œìš©ì´ ê°€ëŠ¥í•œê°€?</li>
+<li>부가 ê¸°ëŠ¥ì´ ë‹¤ë¥¸ ê°™ì€ ë¶€ê°€ 기능와 어떻게 다른 것ì¸ê°€?</li>
+<li>ì¼ë°˜ 사용ìžë‚˜ í‰ê°€ 담당ìž, 블로거, 우주비행사 í˜¹ì€ ê°€ì •ì˜ ì• ì™„ë™ë¬¼ë¡œë¶€í„° ì–´ë– í•œ ë°˜ì‘ì´ ìžˆì—ˆëŠ”ê°€?</li>
+</ul>
+
+<p>훌륭하게 만들어진 완벽한 부가 ê¸°ëŠ¥ë„ ã€Œì¶”ì²œ 부가 기능ã€ëª©ë¡ì— 게재ë˜ëŠ” ë³´ì¦ì€ 없으나 ì˜ë¢° ë©”ì¼ì— ì˜í•´ 완전한 정보를 제공하면 우리가 ê·¸ê²ƒì„ ìŠ¹ë‚™í•  수 ìžˆì„ ê°€ëŠ¥ì„±ë„ ë†’ì•„ì§‘ë‹ˆë‹¤. 즉 목ë¡ì€ Mozilla ìžì²´ ìž¬ëŸ‰ì— ì˜í•´ì„œ 제공 하는 것으로 ìš´ì˜ì— 있어 ì¼ë°˜ 사용ìžì˜ 웹 서핑 경험과 보호가 ë¬´ì—‡ë³´ë‹¤ë„ ì¤‘ì‹œë˜ëŠ” ê³³ 입니다.</p>
+
diff --git a/site/app/locale/ko/pages/sandbox.thtml b/site/app/locale/ko/pages/sandbox.thtml
new file mode 100644
index 0000000..9ba9a64
--- /dev/null
+++ b/site/app/locale/ko/pages/sandbox.thtml
@@ -0,0 +1,15 @@
+<h1>샌드 ë°•ìŠ¤ì˜ í‰ê°€ 시스템</h1>
+<h2>샌드 박스란</h2>
+<p>
+샌드 박스는 ê²½í—˜ì´ í’부한 사용ìžê°€ ì¼ë°˜ ê³µê°œì „ì˜ ë¶€ê°€ ê¸°ëŠ¥ì„ í…ŒìŠ¤íŠ¸í•˜ëŠ” 장소입니다. 샌드 박스 ì ‘ê·¼ì„ ìœ„í•´ì„œëŠ” 계정 설정ì—ì„œ ì ‘ê·¼ ì„¤ì •ì„ í•  수 있습니다.샌드 ë°•ìŠ¤ì— ìžˆëŠ” 부가 ê¸°ëŠ¥ì€ íŽ¸ì§‘ìžì— ì˜í•œ 테스트를 거치지 ì•Šê³  ë‹¹ì‹ ì˜ ì»´í“¨í„°ì— ì•…ì˜í–¥ì„ 미칠 우려가 있기 ë•Œë¬¸ì— ì„¤ì¹˜í•  경우 주ì˜ê°€ 필요합니다.</p>
+
+<h2>부가 기능 공개 방법</h2>
+
+<!-- To localize the flowchart image see http://wiki.mozilla.org/Update Remora_Sandbox_Flowchart -->
+<div style="text-align: center;">%s</div>
+<ol>
+<li><strong>부가 기능 등ë¡</strong> ê°œë°œìž ì œì–´íŒì—ì„œ 부가 ê¸°ëŠ¥ì„ ë“±ë¡í•˜ë©´ 곧바로 Mozilla Add-onsì˜ ã€ŒìƒŒë“œ 박스ã€íŽ˜ì´ì§€ì— 표시ë©ë‹ˆë‹¤.샌드 박스ì—서는 ê²½í—˜ì´ í’부한 사용ìžê°€ 테스트를 í•œ ë‹¤ìŒ í”¼ë“œë°±ì„ ì œê³µí•©ë‹ˆë‹¤. 샌드 박스 ì‚¬ìš©ì€ ê³„ì • 설정으로 í•  수 있습니다.</li>
+<li><strong>부가 기능 공개 ì‹ ì²­</strong> 개발ìžë¥¼ 위한 제어íŒì—ì„œ 부가 ê¸°ëŠ¥ì˜ ê³µê°œ ì‹ ì²­ì„ ìœ„í•œ ë§í¬ê°€ 있습니다.ì‹ ì²­ì„ í•˜ë©´ ë‹¹ì‹ ì˜ ë¶€ê°€ ê¸°ëŠ¥ì€ íŽ¸ì§‘ìžì˜ í‰ê°€ 대기 목ë¡ì— 추가ë©ë‹ˆë‹¤.</li>
+<li><strong>íŽ¸ì§‘ìž ë¶€ê°€ 기능 í‰ê°€</strong> Mozilla Add-onsì˜ íŽ¸ì§‘ìžê°€ ë‹¹ì‹ ì˜ ë¶€ê°€ ê¸°ëŠ¥ì„ ì„¤ì¹˜ 하고 올바르게 ë™ìž‘하는 지 ì—¬ë¶€ì— ëŒ€í•œ 테스트를 실시합니다.편집ìžëŠ” 샌드 박스 í…ŒìŠ¤í„°ì— ì˜í•œ í‰ê°€ë„ 참조합니다.</li>
+<li><strong>공개 여부 ê²°ì •</strong> 편집ìžëŠ” ë‹¹ì‹ ì˜ ë¶€ê°€ ê¸°ëŠ¥ì„ ê³µê°œ 페ì´ì§€ì— 제공할 것ì¸ì§€ 샌드 ë°•ìŠ¤ì— ê·¸ëŒ€ë¡œ 둘 것ì¸ì§€ë¥¼ 결정합니다. 공개가 보류ë˜ì—ˆì„ 경우, 편집ìžì˜ ì˜ê²¬ì— ë”°ë¼ì„œ ë³€ê²½ì„ ë”í•œ 후 공개 재 ì‹ ì²­ì„ í•  수 있습니다.공개 페ì´ì§€ì— 게재ë˜ì—ˆì„ 경우, 앞으로 등ë¡í•˜ëŠ” ë²„ì „ì€ íŽ¸ì§‘ìžì˜ í‰ê°€ë¥¼ 받아 공개 페ì´ì§€ì— ê²Œìž¬ë  ë•Œê¹Œì§€ 샌드 ë°•ìŠ¤ì— í‘œì‹œë©ë‹ˆë‹¤. í•œ 번 공개 페ì´ì§€ì— 게재ë˜ë©´ 재차 공개 ì‹ ì²­ì„ ì‹¤ì‹œí•  필요는 없고 ì´í›„ì˜ ë²„ì „ì€ ìžë™ì ìœ¼ë¡œ í‰ê°€ 대기 목ë¡ì— 추가ë©ë‹ˆë‹¤.</li>
+</ol>
diff --git a/site/app/locale/ko/pages/statistics_help.thtml b/site/app/locale/ko/pages/statistics_help.thtml
new file mode 100644
index 0000000..35d1675
--- /dev/null
+++ b/site/app/locale/ko/pages/statistics_help.thtml
@@ -0,0 +1,8 @@
+<h3>ë„움ë§</h3>
+<p>통계 대시보드는 ì—¬ëŸ¬ë¶„ì˜ ë¶€ê°€ ê¸°ëŠ¥ì— ëŒ€í•œ ì´ ì¡°íšŒ 수 ë° ë‹¤ìš´ë¡œë“œ 횟수를 제공해주고 있습니다.</p>
+
+<h4>다운로드 횟수</h4>
+<p>다운로드 횟스는 ë§¤ì¼ ì—…ë°ì´íŠ¸ ë˜ë©°, 최초 부가 기능 ë‹¤ìš´ë¡œë“œì¸ ê²½ìš°ì—만 ì¡°íšŒìˆ˜ì— í¬í•¨ë©ë‹ˆë‹¤.</p>
+
+<h4>ì´ ì¡°íšŒìˆ˜</h4>
+<p>본 웹 사ì´íŠ¸ì—ì„œ 다운로드 ëœ ë¶€ê°€ ê¸°ëŠ¥ì— ëŒ€í•œ 조회 수와 ì—…ë°ì´íŠ¸ í•­ëª©ì— ëŒ€í•œ 조회 수를 ëª¨ë‘ í¬í•¨í•©ë‹ˆë‹¤. ì¼ê°„ ì´ ì‚¬ìš©ìž(Active Daily Users)는 버전, ìš´ì˜ ì²´ì œ, ìƒíƒœ, 프로그램 등으로 제공ë©ë‹ˆë‹¤. ì´ ë°ì´í„°ëŠ” 수요ì¼ì— 매 주간 í•©ì‚° ê²°ê³¼ 입니다. </p> \ No newline at end of file
diff --git a/site/app/locale/ko/pages/submission_help.thtml b/site/app/locale/ko/pages/submission_help.thtml
new file mode 100644
index 0000000..40e4ebf
--- /dev/null
+++ b/site/app/locale/ko/pages/submission_help.thtml
@@ -0,0 +1,41 @@
+<h1>부가 기능 제출 과정 ë„움ë§</h1>
+
+<p><b>êµµì€ ê¸€ì”¨</b>ë¡œ í‘œê¸°ëœ í•­ëª©ì€ í•„ìˆ˜ìž…ë‹ˆë‹¤. 그외 í•­ëª©ì€ í•„ìˆ˜ëŠ” 아닙니다.</p>
+
+<h2 id="step1">단계 1: 업로드</h2>
+<ul class="submissionHelp">
+ <li><span class="required">부가 ê¸°ëŠ¥ì˜ ì¢…ë¥˜</span> - ì—…ë¡œë“œëœ íŒŒì¼ì— 근거해 ìžë™ì ìœ¼ë¡œ íŒë³„ë˜ê¸° ë•Œë¬¸ì— ë³€ê²½í•  필요는 없습니다.</li>
+
+ <li><span class="required">부가 기능 파ì¼</span> - install.rdf 파ì¼ì„ í¬í•¨í•œ 부가 ê¸°ëŠ¥ì˜ íŒ¨í‚¤ì§€ 파ì¼ì„ ì„ íƒí•©ë‹ˆë‹¤. 파ì¼ì´ 특정 플랫í¼ì—서만 ì´ìš©í•  수 있는 경우 플랫í¼ì„ ì„ íƒí•˜ê±°ë‚˜ 플랫í¼ë§ˆë‹¤ 파ì¼ì„ í•œ ë²ˆì— ì—…ë¡œë“œí•  수 있습니다.</li>
+ <li>ì•„ì´ì½˜ íŒŒì¼ - Mozilla Add-onsì˜ ì‚¬ì´íŠ¸ì—서는 부가 ê¸°ëŠ¥ì˜ íƒ€ì´í‹€ê³¼ 함께 표시ë˜ê³ , ì¼ë°˜ 사용ìžì—게 설치 후ì—는 부가 기능 ê´€ë¦¬ìž ì˜ì—­ì—ë„ í‘œì‹œë©ë‹ˆë‹¤.32x32 픽셀보다 í° ê²½ìš°ëŠ” 가로 세로 ë¹„ìœ¨ì„ ìœ ì§€í•œ 채로 ìžë™ìœ¼ë¡œ 리사ì´ì¦ˆ ë©ë‹ˆë‹¤.</li>
+ <li><span class="required">기본 언어 설정</span> - 부가 ê¸°ëŠ¥ì˜ ì£¼ìš” 언어설정 (언어+지역 설정)ì„ ì§€ì •í•©ë‹ˆë‹¤. 사용ìžê°€ ì„ íƒí•œ 언어 ì„¤ì •ì´ ë¶€ê°€ ê¸°ëŠ¥ì— í¬í•¨ë˜ì§€ ì•Šì€ ê²½ìš° ì„¤ì •ì„ ì´ìš©í•©ë‹ˆë‹¤.</li>
+ <li>등ë¡ëœ 부가 기능 ì •ë³´ í™•ì¸ - 기존 부가 ê¸°ëŠ¥ì„ ì—…ë°ì´íŠ¸í•˜ëŠ” 경우 ì´ í•­ëª©ì´ í‘œì‹œë©ë‹ˆë‹¤. ì´ í•­ëª©ì„ ì²´í¬ í•˜ë©´ 단계 2를 건너 ë›°ê³  단계 3ì˜ ë²„ì „ 정보를 입력하는 화면으로 ì´ë™í•©ë‹ˆë‹¤.</li>
+</ul>
+
+<h2 id="step2">단계 2: ìƒì„¸ ì •ë³´ ìž…ë ¥</h2>
+<ul class="submissionHelp">
+ <li><span class="required">ì´ë¦„</span> - 부가 ê¸°ëŠ¥ì˜ ì œëª©ì„ ê¸°ë³¸ 언어 ì„¤ì •ì— ë”°ë¼ ìž…ë ¥í•©ë‹ˆë‹¤.</li>
+ <li><span class="required">개발ìž</span> - 부가 ê¸°ëŠ¥ì˜ íŽ¸ì§‘ ê¶Œí•œì„ ê°€ì§€ê³  있는 모든 사용ìžë¡œ 부가 ê¸°ëŠ¥ì˜ ì œëª©ê³¼ 함께 표시ë©ë‹ˆë‹¤.</li>
+
+ <li><span class="required">분류</span> - 부가 ê¸°ëŠ¥ì— í•´ë‹¹í•˜ëŠ” 분류를 ì„ íƒí•©ë‹ˆë‹¤.</li>
+ <li>홈 페ì´ì§€ - 기본 언어 설정으로 설명하는 부가 ê¸°ëŠ¥ì˜ ì›¹ 사ì´íŠ¸ë¥¼ 입력합니다.</li>
+ <li><span class="required">요약 ì •ë³´</span> - 부가 ê¸°ëŠ¥ì˜ ê°œìš”ë¥¼ 기본 언어로 입력합니다. 250ìžê¹Œì§€ ìž…ë ¥ 가능합니다. 부가 ê¸°ëŠ¥ì˜ ê³µê°œ 페ì´ì§€ ë° ê²€ìƒ‰ ê²°ê³¼ì— í‘œì‹œë©ë‹ˆë‹¤.</li>
+ <li><span class="required">ìƒì„¸ 설명</span> - 부가 ê¸°ëŠ¥ì˜ ìƒì„¸ ì„¤ëª…ì„ ê¸°ë³¸ 언어로 입력합니다. 부가 기능 공개 페ì´ì§€ì˜ 요약 ì•„ëž˜ì— í‘œì‹œë©ë‹ˆë‹¤.</li>
+ <li>EULA - 사용ìžì—게 다운로드 ì „ì— ë™ì˜ë¥¼ 요구하는 최종 ì‚¬ìš©ìž ë¼ì´ì„¼ìŠ¤ ê³„ì•½ì„ ê¸°ë³¸ 언어로 입력합니다.</li>
+ <li>ê°œì¸ ì •ë³´ 보호 ì •ì±… - 부가 ê¸°ëŠ¥ì˜ ê°œì¸ ì •ë³´ 보호 ì •ì±…ì„ ê¸°ë³¸ 언어로 입력합니다. 최종 사용ìžì˜ ê°œì¸ ì •ë³´ 취급 ë°©ë²•ì— ëŒ€í•´ 설명해 주셔야 합니다. 부가 ê¸°ëŠ¥ì˜ ê³µê°œ 페ì´ì§€ì— 있는 설치 버튼과 함께 ë§í¬ê°€ 제공 ë©ë‹ˆë‹¤. ê°œì¸ ì •ë³´ 보호 ì •ì±…ì— ì–´ë– í•œ ì‚¬í•­ì„ ê¸°ìˆ í•´ì•¼ ë˜ëŠ”ì§€ì— ëŒ€í•œ ë‚´ìš©ì€ <a target=_top href='http://svn.mozilla.org/addons/trunk/site/app/locale/ko/pages/%s'>
+부가 기능 ì •ì±…</a>페ì´ì§€ë¥¼ 확ì¸í•´ 주십시오.</li>
+ <li>소스 코드 표시 허가- ì´ í•­ëª©ì— ì²´í¬í•˜ë©´ ì¼ë°˜ 사용ìžê°€ 사ì´íŠ¸ìƒì—ì„œ 부가 ê¸°ëŠ¥ì˜ ì†ŒìŠ¤ 코드를 ë³¼ 수 있게 ë©ë‹ˆë‹¤.</li>
+ <li>ì •ì‹ ì¶œì‹œ ì „ ì •ë³´ 제공 - ì´ í•­ëª©ì— ì²´í¬í•˜ë©´ 베타íŒì˜ 부가 ê¸°ëŠ¥ì¸ ê²ƒì´ ëª…ê¸°ë©ë‹ˆë‹¤. ì •ì‹ ì¶œì‹œ ì „ 부가 ê¸°ëŠ¥ì€ ìƒŒë“œ ë°•ìŠ¤ì— ë³´ë¥˜ë˜ì–´ ì´ ì„¤ì •ì— ë³€ê²½ ë  ë•Œê¹Œì§€ 공개 ì‹ ì²­ì„ í•  수 없습니다.</li>
+ <li>특정 사ì´íŠ¸ 부가 기능 - ì´ í•­ëª©ì„ ì²´í¬í•˜ë©° 특정 웹 사ì´íŠ¸ë¥¼ 위한 부가 ê¸°ëŠ¥ì¸ ê²ƒì´ ëª…ê¸°ë©ë‹ˆë‹¤. 예를 들면 특정 사ì´íŠ¸ì˜ ì™¸í˜•ì„ ë°”ê¾¸ê±°ë‚˜ 특정 사ì´íŠ¸ 컨í…츠를 표시하는 ê²ƒì´ í•´ë‹¹í•©ë‹ˆë‹¤. ì´ í•­ëª©ì€ íŽ¸ì§‘ìžì—게 참고 ì‚¬í•­ì´ ë˜ê³  향후 검색 ì¡°ê±´ìœ¼ë¡œë„ ì´ìš©í•  수 있게 ë  ì˜ˆì •ìž…ë‹ˆë‹¤.</li>
+ <li>외부 어플리케ì´ì…˜ì„ í•„ìš” 여부 - ì´ í•­ëª©ì„ ì²´í¬í•˜ë©´ 다른 어플리케ì´ì…˜ì„ ì´ìš©í•˜ëŠ” 부가 ê¸°ëŠ¥ì¸ ê²ƒì´ ëª…ê¸°ë©ë‹ˆë‹¤. ì´ í•­ëª©ì€ íŽ¸ì§‘ìžì—게 참고 ì‚¬í•­ì´ ë˜ê³  향후 검색 ì¡°ê±´ìœ¼ë¡œë„ ì´ìš©í•  수 있게 ë  ì˜ˆì •ìž…ë‹ˆë‹¤.</li>
+</ul>
+
+<h2 id="step3">단계 3: 버전 ìƒì„¸ ì •ë³´</h2>
+<ul class="submissionHelp">
+ <li><span class="required">버전 설명</span> - ë“±ë¡ ë²„ì „ì˜ ìš”ì•½ ì •ë³´ í˜¹ì€ ë³€ê²½ ì‚¬í•­ë“±ì„ ìž…ë ¥í•©ë‹ˆë‹¤.ì´ í•­ëª©ì€ ìƒˆë¡­ê²Œ 등ë¡ì„ 실시하는 경우는 ìž„ì˜ ì‚¬í•­ìž…ë‹ˆë‹¤ë§Œ ì—…ë°ì´íŠ¸ì¼ 경우는 필수입니다.</li>
+ <li>í‰ê°€ ë‹´ë‹¹ìž ìš”ì²­ 사항 - 부가 ê¸°ëŠ¥ì˜ í‰ê°€ë¥¼ 담당하는 편집ìžì— 정보를 전하는 비고란입니다. 테스트용 계정 정보나 특별한 주ì˜ì  ë“±ì„ ì—¬ê¸°ì— ìž…ë ¥í•©ë‹ˆë‹¤.</li>
+</ul>
+
+<h2 id="step4">단계 4: 지역화</h2>
+
+<p>현재 단계ì—ì„œ 입력한 í•­ëª©ì„ ê° ì–¸ì–´ë¡œ ë²ˆì—­ë³¸ì„ ì œê³µí•  수 있습니다. ê° ì–¸ì–´ë¥¼ ì„ íƒí•´ ë²ˆì—­ì„ ìž…ë ¥í•©ë‹ˆë‹¤.</p>
diff --git a/site/app/locale/merge-enus2all.sh b/site/app/locale/merge-enus2all.sh
new file mode 100755
index 0000000..82ad166
--- /dev/null
+++ b/site/app/locale/merge-enus2all.sh
@@ -0,0 +1,9 @@
+#!/bin/sh
+tempfoo=`basename $0`
+TMPFILE=`mktemp /tmp/${tempfoo}.XXXXXX` || exit 1
+
+for i in `find . -type f -name "messages.po" | grep -v en_US`; do
+ msgattrib --set-fuzzy en_US/LC_MESSAGES/messages.po | msgmerge -Ns "$i" - > $TMPFILE
+ cp "$TMPFILE" "$i"
+done
+rm "$TMPFILE"
diff --git a/site/app/locale/merge-po.sh b/site/app/locale/merge-po.sh
new file mode 100755
index 0000000..ea1c579
--- /dev/null
+++ b/site/app/locale/merge-po.sh
@@ -0,0 +1,22 @@
+#!/bin/bash
+
+# syntax:
+# merge-po.sh extracted.pot destination-dir/
+
+function usage() {
+ echo "syntax:"
+ echo "merge-po.sh extracted.pot destination-dir/"
+ exit 1
+}
+
+tempfoo=`basename $0`
+TMPFILE=`mktemp /tmp/${tempfoo}.XXXXXX` || exit 1
+
+# check if file and dir are there
+if [[ ($# -ne 2) || (! -f "$1") || (! -d "$2") ]]; then usage; fi
+
+for lang in `find $2 -type f -name "messages.po"`; do
+ sed 's/#\. /# developer_comment /' "$lang" | msgmerge --no-fuzzy-matching - $1 > $TMPFILE
+ sed 's/# developer_comment /#. /' "$TMPFILE" > "$lang"
+done
+rm "$TMPFILE"
diff --git a/site/app/locale/mn/LC_MESSAGES/messages.mo b/site/app/locale/mn/LC_MESSAGES/messages.mo
new file mode 100644
index 0000000..a8d691f
--- /dev/null
+++ b/site/app/locale/mn/LC_MESSAGES/messages.mo
Binary files differ
diff --git a/site/app/locale/mn/LC_MESSAGES/messages.po b/site/app/locale/mn/LC_MESSAGES/messages.po
new file mode 100644
index 0000000..d9d4ef2
--- /dev/null
+++ b/site/app/locale/mn/LC_MESSAGES/messages.po
@@ -0,0 +1,8732 @@
+# Remora Preliminary Language File
+# Copyright (C) 2006 Mozilla Corporation
+# This file is distributed under the same license as the REMORA package.
+# Wil Clouser <clouserw@mozilla.com>, 2006.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: REMORA 0.1\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2009-01-16 11:45-0800\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: Wil Clouser <clouserw@mozilla.com>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=n != 1;\n"
+
+#: views/addons/policy.thtml:98
+msgid "a_cancel_installation"
+msgstr "Суулгацыг цуцал"
+
+#. This is the text that appears on buttons to download add-ons.
+#. %$1s is an optional string that only appears if the add-on is only available for
+#. a certain platform. Examples: (Windows) or (Linux)
+#. Note that the parentheses are included in the string. :(
+#: views/elements/amo2009/install.thtml:126
+#: views/elements/amo2009/install.thtml:227
+#: views/elements/amo2009/install.thtml:257
+#: views/elements/amo2009/install.thtml:300
+#: views/elements/amo2009/install.thtml:312 views/elements/install.thtml:73
+#: views/elements/install.thtml:181 views/elements/install.thtml:205
+#: views/elements/install.thtml:248 views/elements/install.thtml:260
+#: views/addons/plugins.thtml:66 views/addons/plugins.thtml:76
+#: views/addons/plugins.thtml:86 views/addons/plugins.thtml:96
+#: views/addons/plugins.thtml:119
+#, php-format
+msgid "a_download"
+msgstr "%s-г одоо татаж ав"
+
+#: views/addons/policy.thtml:72
+msgid "a_eula_download"
+msgstr "Зөвшөөрөөд татаж ав"
+
+#: views/addons/policy.thtml:74
+msgid "a_eula_install"
+msgstr "Зөвшөөрөөд Ñуулга"
+
+#: views/elements/header.thtml:76 views/elements/header.thtml:82
+#: views/api/api_addon.thtml:55 views/api/collections_feed.thtml:75
+#: views/sharing_api/addon.thtml:64
+msgid "a_header_public"
+msgstr "Ðийтийн"
+
+#: views/elements/header.thtml:58 views/elements/header.thtml:75
+#: views/elements/header.thtml:80 views/api/api_addon.thtml:57
+#: views/api/collections_feed.thtml:77 views/sharing_api/addon.thtml:66
+msgid "a_header_sandbox"
+msgstr "Түр хайрцаг"
+
+#. %s is a date in the _('date') format
+#: views/elements/amo2009/homepage_addon.thtml:115
+#: views/elements/addon_listitem.thtml:122 views/elements/feature.thtml:106
+#: views/addons/display.thtml:104 views/addons/browse_thumbs.thtml:73
+msgid "addon_detail_last_updated"
+msgstr "%s шинÑчлÑгдÑÑн "
+
+#. %s is the version of the add-on. Example: 3.2a1
+#: views/elements/amo2009/addon_version_detail.thtml:51
+#: views/elements/addon_version_detail.thtml:51
+#, php-format
+msgid "addon_display_header_version"
+msgstr "Хувилбар %s"
+
+#: views/addons/browse_thumbs.thtml:80
+msgid "addon_downloads"
+msgstr "удаа татагдÑан"
+
+#: views/addons/display.thtml:147
+msgid "addon_downloads_total"
+msgstr "удаа нийтдÑÑ Ñ‚Ð°Ñ‚Ð°Ð³Ð´Ñан"
+
+#: views/elements/amo2009/homepage_addon.thtml:106
+#: views/elements/addon_listitem.thtml:115 views/elements/feature.thtml:101
+#: views/addons/category_landing.thtml:157 views/addons/display.thtml:146
+#: views/addons/browse_thumbs.thtml:80
+msgid "addon_downloads_weekly"
+msgstr "удаа долоо хоногт татагдÑан"
+
+#. %1 is the add-on count, %2 the category name
+#: views/addons/browse_thumbs.thtml:104 views/addons/browse.thtml:60
+#, php-format
+msgid "addon_list_category_totalcount"
+msgid_plural "addon_list_category_totalcount"
+msgstr[0] "%1$s \"%2$s\" нÑмÑгдÑл"
+msgstr[1] "%1$s \"%2$s\" нÑмÑгдлүүд"
+
+#: views/elements/amo2009/addon_list_options.thtml:103
+#: views/elements/pagination.thtml:67
+#: views/elements/addon_list_options.thtml:94
+msgid "addon_list_perpage"
+msgstr "-г нÑг хуудÑанд"
+
+#: views/elements/amo2009/addon_list_options.thtml:84
+#: views/elements/addon_list_options.thtml:98
+msgid "addon_list_sortby"
+msgstr "ЭрÑмбÑлÑлт:"
+
+#: views/helpers/addons_html.php:568 views/elements/amo2009/install.thtml:321
+#: views/elements/feature.thtml:89
+msgid "addon_listitem_flag_experimental"
+msgstr "туршилтын"
+
+#: views/helpers/addons_html.php:570
+msgid "addon_listitem_flag_recommended"
+msgstr "Ñанал болгогдÑон"
+
+#. %1 is the add-on name, %2 is the platform
+#: views/pages/js_constants.js.thtml:66
+msgid "addon_not_available_for_platform"
+msgstr "%1$s-н %2$s-д тохирÑон хувилбар байхгүй."
+
+#. %1 is the add-on name
+#: views/addons/policy.thtml:101 views/addons/previews.thtml:60
+#: views/addons/versions.thtml:130 views/reviews/flag.thtml:61
+#: views/reviews/add.thtml:114 views/reviews/display.thtml:216
+#: views/reviews/review_added.thtml:57
+#, php-format
+msgid "addon_review_a_back_to_addon_x"
+msgstr "%1$s-н хуудÑанд буцна..."
+
+#. %1 is the add-on name
+#: views/reviews/flag.thtml:60 views/reviews/add.thtml:113
+#: views/reviews/review_added.thtml:56
+#, php-format
+msgid "addon_review_a_back_to_reviews"
+msgstr "ҮнÑлгÑÑ Ð´Ò¯Ð³Ð½Ñлт хуудÑанд буцна..."
+
+#: views/reviews/add.thtml:85
+msgid "addon_review_add_rating_field"
+msgstr "ҮнÑлÑмж:"
+
+#: views/reviews/add.thtml:102
+msgid "addon_review_add_review_field"
+msgstr "ҮнÑлгÑÑ Ð´Ò¯Ð³Ð½Ñлт:"
+
+#: views/reviews/add.thtml:107
+msgid "addon_review_add_submit"
+msgstr "ҮнÑлгÑÑ Ð´Ò¯Ð³Ð½ÑлтÑÑ Ð¸Ð»Ð³ÑÑÑ…"
+
+#. %s is the name of the add-on
+#: views/reviews/add.thtml:51
+#, php-format
+msgid "addon_review_add_title"
+msgstr "%s-д дүгнÑлт өгөх"
+
+#: views/reviews/add.thtml:78
+msgid "addon_review_add_title_field"
+msgstr "Гарчиг/Товч мÑдÑÑлÑл:"
+
+#: views/reviews/display.thtml:77 views/reviews/display.thtml:161
+msgid "addon_review_admin_delete"
+msgstr "УÑтга"
+
+#: views/reviews/display.thtml:76
+msgid "addon_review_author_reply_link"
+msgstr "Хариулах"
+
+#: views/reviews/delete.thtml:62
+msgid "addon_review_confirm_delete"
+msgstr "Та ÑÐ½Ñ Ò¯Ð½ÑлгÑÑ Ð´Ò¯Ð³Ð½ÑлтÑÑ ÑƒÑтгахдаа итгÑлтÑй байна уу?"
+
+#: views/reviews/delete.thtml:63
+msgid "addon_review_confirm_no"
+msgstr "Үгүй"
+
+#: views/reviews/delete.thtml:64
+msgid "addon_review_confirm_yes"
+msgstr "Тийм"
+
+#: views/reviews/delete.thtml:48
+msgid "addon_review_delete_header"
+msgstr "ҮнÑлгÑÑ Ð´Ò¯Ð³Ð½Ñлтийг уÑтга"
+
+#: controllers/reviews_controller.php:449
+msgid "addon_review_deleted_successfully"
+msgstr "ДүгнÑлт амжилттай уÑтгагдлаа."
+
+#. %s is the name of the add-on
+#: views/reviews/add.thtml:51
+#, php-format
+msgid "addon_review_edit_title"
+msgstr "%s-н үнÑлгÑÑ Ð´Ò¯Ð³Ð½Ñлтийг заÑварла"
+
+#. %1 is the count of characters entered as notes for the review flag reason.
+#: controllers/reviews_controller.php:539
+#, fuzzy
+msgid "addon_review_flag_error_other_length"
+msgstr ""
+"Problem flagging review: Notes for flagged reviews are limited to between 10 "
+"and 100 characters; your character length was %1$s."
+
+#. Removing an extra comma
+#: views/reviews/review_added.thtml:53
+msgid "addon_review_in_moderation"
+msgstr ""
+"Ðнхаар: Таны үнÑлгÑÑ Ð´Ò¯Ð³Ð½Ñлт нийтийн хуудÑанд харуулагдахааÑаа өмнө "
+"зохиогчоор нь Ñ…Ñнагдах болно."
+
+#: views/reviews/add.thtml:57
+msgid "addon_review_in_reply_to"
+msgstr "ХөгжүүлÑгчид нь хариулах:"
+
+#. %1 is the review count, %2 is the nickname or full name of the user.
+#: views/reviews/display.thtml:131
+#, fuzzy, php-format
+msgid "addon_review_others_by_user"
+msgid_plural "addon_review_others_by_user"
+msgstr[0] "See %1$s previous review submitted by %2$s for this add-on."
+msgstr[1] "See %1$s previous reviews submitted by %2$s for this add-on."
+
+#. %1 is the add-on name
+#: controllers/reviews_controller.php:201
+#: controllers/reviews_controller.php:250
+#: controllers/reviews_controller.php:345
+#: controllers/reviews_controller.php:424
+#, php-format
+msgid "addon_review_pagetitle"
+msgstr "%s-д өгÑөн үнÑлгÑÑ Ð´Ò¯Ð³Ð½Ñлт"
+
+#. %1 is the user, %2 is the (localized) date
+#: views/reviews/display.thtml:160
+#, php-format
+msgid "addon_review_reply_on_x_by_y"
+msgstr "%1$s-р %2$s руу хариулах"
+
+#: views/reviews/display.thtml:157
+msgid "addon_review_reply_prefix"
+msgstr "ХөгжүүлÑгчийн хариулт:"
+
+#: views/reviews/review_added.thtml:51
+msgid "addon_review_saved_successfully"
+msgstr "Таны үнÑлгÑÑ Ð°Ð¼Ð¶Ð¸Ð»Ñ‚Ñ‚Ð°Ð¹ хадгалагдлаа. БаÑрлалаа!"
+
+#: views/addons/display.thtml:354 views/reviews/display.thtml:72
+msgid "addon_reviewed_by_u_on_d"
+msgstr "%2$s-ны өдөр %1$s-р"
+
+#. %1 is the user, %2 is the (localized) date, %3 is the rating
+#: views/editors/reviews_queue.thtml:57 views/editors/reviews_queue.thtml:68
+#: views/reviews/add.thtml:63 views/reviews/delete.thtml:54
+#, php-format
+msgid "addon_reviewed_on_x_rated_y"
+msgstr "%2$s-нд %1$s (үнÑлгÑÑ %3$s)"
+
+#: views/elements/amo2009/addon_version_detail.thtml:52
+#: views/elements/addon_version_detail.thtml:52
+#, fuzzy
+msgid "addon_version_permalink"
+msgstr "Permanent link to this version"
+
+#. %1 is the current Application name (e.g. Firefox)
+#. %2 is the Application's version number
+#: views/addons/versions.thtml:140
+#, fuzzy
+msgid "addon_versions_getlatestversion"
+msgstr "The most recent version compatible with %1$s %2$s"
+
+#: views/addons/display.thtml:447
+msgid "addons_author_addons_submit"
+msgstr "ИлгÑÑÑ…"
+
+#: views/elements/amo2009/homepage_addon.thtml:100
+#: views/elements/feature.thtml:95
+#, fuzzy
+msgid "addons_author_tooltip"
+msgstr "View Author's Profile"
+
+#. %1 is the name of the Application (eg. Firefox)
+#: controllers/addons_controller.php:1296
+#, fuzzy
+msgid "addons_browse_all_themes_title"
+msgstr "Browse all Themes :: %1$s Add-ons"
+
+#. %s is the name of the category
+#: controllers/addons_controller.php:1016
+#, php-format
+msgid "addons_browse_browse_category"
+msgstr "%s нÑмÑгдлүүд"
+
+#. %1 is the name of the theme category (eg. Modern)
+#. %2 is the name of the Application (eg. Firefox)
+#: controllers/addons_controller.php:664
+#, fuzzy
+msgid "addons_browse_categories_header_theme"
+msgstr "Browse %1$s Themes :: %2$s Add-ons"
+
+#: views/addons/display.thtml:249
+#, fuzzy
+msgid "addons_display_a_license_what"
+msgstr "What's this?"
+
+#: views/reviews/display.thtml:222
+msgid "addons_display_add_review"
+msgstr "ҮнÑлгÑÑ Ð´Ò¯Ð³Ð½Ñлт нÑм"
+
+#: views/addons/display.thtml:294
+msgid "addons_display_advanced_details"
+msgstr "ÐÑмÑлт мÑдÑÑлÑл"
+
+#: views/addons/display.thtml:98
+msgid "addons_display_categories"
+msgstr "Төрөл анги"
+
+#: views/addons/display.thtml:482
+#, fuzzy
+msgid "addons_display_collection_add"
+msgstr "Add to a collection:"
+
+#: views/addons/display.thtml:491
+#, fuzzy
+msgid "addons_display_collection_add_new"
+msgstr "New Collection..."
+
+#: views/addons/display.thtml:487
+#, fuzzy
+msgid "addons_display_collection_add_select_one"
+msgstr "Select a collection..."
+
+#: views/addons/display.thtml:493
+#, fuzzy
+msgid "addons_display_collection_add_submit"
+msgstr "Publish"
+
+#. %1$s is the add-on name
+#. %2$s is the collection name, linked to the collection's page
+#: views/pages/js_constants.js.thtml:103 views/addons/display.thtml:61
+#, fuzzy
+msgid "addons_display_collection_publish_success"
+msgstr "%1$s has been added to the %2$s collection."
+
+#: views/addons/display.thtml:483
+#, fuzzy
+msgid "addons_display_collection_whatsthis"
+msgstr "What's this?"
+
+#. %1$s is a number
+#: views/addons/display.thtml:473
+#, fuzzy
+msgid "addons_display_collections_more"
+msgid_plural "addons_display_collections_more"
+msgstr[0] "and %1$s more collection"
+msgstr[1] "and %1$s more collections"
+
+#: views/addons/display.thtml:403
+msgid "addons_display_detailed_review"
+msgstr "дÑлгÑÑ€Ñнгүй харуулалт"
+
+#: views/reviews/add.thtml:89 views/reviews/add.thtml:90
+msgid "addons_display_dont_like_it"
+msgstr "ТаалагдÑангүй"
+
+#: views/reviews/display.thtml:220
+msgid "addons_display_edit_review"
+msgstr "Тайлбараа заÑварлах"
+
+#: views/addons/display.thtml:132
+msgid "addons_display_has_privacy"
+msgstr ""
+"Ð­Ð½Ñ Ð½ÑмÑгдÑлд хувь хүнтÑй холбоотой мÑдÑÑллийг хамгаалах журам заагдÑан "
+"байна."
+
+#: views/reviews/add.thtml:87 views/reviews/add.thtml:88
+msgid "addons_display_hate_it"
+msgstr "ҮзÑн Ñдаж байна"
+
+#: views/addons/display.thtml:462
+#, fuzzy
+msgid "addons_display_header_collections"
+msgstr "Related Collections"
+
+#: views/addons/display.thtml:297
+msgid "addons_display_header_developer_comments"
+msgstr "Зохиогчийн тайлбар"
+
+#: views/addons/display.thtml:230
+msgid "addons_display_header_homepage"
+msgstr "Ð’Ñб хуудÑанд нь очих"
+
+#: views/addons/display.thtml:247 views/addons/versions.thtml:110
+#, fuzzy
+msgid "addons_display_header_license"
+msgstr "Source Code License"
+
+#: views/addons/display.thtml:337
+msgid "addons_display_header_reviews"
+msgstr "ҮнÑлгÑÑ Ð´Ò¯Ð³Ð½Ñлтүүд"
+
+#: views/addons/display.thtml:261
+msgid "addons_display_header_support"
+msgstr "ДÑмжлÑг"
+
+#: views/reviews/add.thtml:91 views/reviews/add.thtml:92
+msgid "addons_display_like_it"
+msgstr "Таалагдаж байна"
+
+#: views/addons/display.thtml:210
+msgid "addons_display_long_description"
+msgstr "Урт тайлбар"
+
+#: views/reviews/add.thtml:95 views/reviews/add.thtml:96
+msgid "addons_display_love_it"
+msgstr "Дурлахаар байна"
+
+#: views/addons/display.thtml:178
+msgid "addons_display_more_images"
+msgstr "ÐÑмÑлт зурагнууд"
+
+#: views/addons/display.thtml:465
+#, fuzzy
+msgid "addons_display_nocollections"
+msgstr "This add-on is not yet in any collections."
+
+#. %1$s is either an author's name or a comma separated list of authors. Using
+#. the list doesn't make sense in the English plural form so we ignore the
+#. variable.
+#: views/addons/display.thtml:436
+#, fuzzy
+msgid "addons_display_other_addons_by"
+msgid_plural "addons_display_other_addons_by"
+msgstr[0] "%1$s-н зохиоÑон буÑад нÑмÑгдлүүд"
+msgstr[1] "Other add-ons by these authors"
+
+#. %s is the name of the add-on and the add-on section. Example:
+#. Some Add-on :: Firefox Add-ons
+#. This should not be concatenated in the code and should be fixed.
+#: controllers/addons_controller.php:141 controllers/addons_controller.php:280
+#: controllers/addons_controller.php:1442
+#, php-format
+msgid "addons_display_pagetitle"
+msgstr "%s"
+
+#. %s is an email address
+#: views/addons/display.thtml:286
+#, php-format
+msgid "addons_display_paragraph_supportinfoemail"
+msgstr ""
+"Ð¥ÑÑ€Ñв та ÑÐ½Ñ Ó©Ñ€Ð³Ó©Ñ‚Ð³Ó©Ð»Ð¸Ð¹Ð³ дÑмжих Ñ…Ò¯ÑÑлтÑй бол %s Ñ…ÑƒÑƒÐ´Ð°Ñ Ñ€ÑƒÑƒ зорчино уу.Ð¥ÑÑ€Ñв "
+"та алдааны мÑдÑгдÑл байгаа бол түүнийгÑÑ ÑхлÑÑд хөгжүүлÑгчид нь мÑдÑгдÑÑ… нь "
+"илүү үр дүнтÑй байх болно. ХөгжүүлÑгч нь алдааны мÑдÑгдлийг шинжлÑхийн тулд "
+"нÑмÑлт мÑдÑÑлÑл шаардлагатай байдаг ÑƒÑ‡Ñ€Ð°Ð°Ñ ÑÐ½Ñ Ñ…ÑƒÑƒÐ´Ð°Ñ Ð½ÑŒ тийм үйлдÑлд "
+"тохиромжгүй билÑÑ.Таны Ñанал гомдлыг илгÑÑхдÑÑ Ð·Ð°Ñ…Ð¸Ð°Ð½Ñ‹ хаÑгийг тань "
+"хөгжүүлÑгч Ñ€Ò¯Ò¯ хамт илгÑÑдÑггүй ÑƒÑ‡Ñ€Ð°Ð°Ñ Ñ…Ó©Ð³Ð¶Ò¯Ò¯Ð»ÑгчÑÑÑ Ñ‚Ð°Ð½Ð´ уг алдаа дутагдал "
+"нь дараагийн хувилбарт заÑагдÑан ÑÑÑхийг мÑдÑÑлÑÑ… боломжгүй байх болно."
+
+#. %$1s is a URL
+#. %$2s is an email address
+#: views/addons/display.thtml:269
+#, php-format
+msgid "addons_display_paragraph_supportinfoemailurl"
+msgstr ""
+"Ð¥ÑÑ€Ñв та ÑÐ½Ñ Ó©Ñ€Ð³Ó©Ñ‚Ð³Ó©Ð»Ð¸Ð¹Ð³ дÑмжих Ñ…Ò¯ÑÑлтÑй бол %s ÑÑвÑл %s хуудÑанд зорчино уу."
+"Ð¥ÑÑ€Ñв та алдааны мÑдÑгдÑл байгаа бол түүнийгÑÑ ÑхлÑÑд хөгжүүлÑгчид нь "
+"мÑдÑгдÑÑ… нь илүү үр дүнтÑй байх болно. ХөгжүүлÑгч нь алдааны мÑдÑгдлийг "
+"шинжлÑхийн тулд нÑмÑлт мÑдÑÑлÑл шаардлагатай байдаг ÑƒÑ‡Ñ€Ð°Ð°Ñ ÑÐ½Ñ Ñ…ÑƒÑƒÐ´Ð°Ñ Ð½ÑŒ "
+"тийм үйлдÑлд тохиромжгүй билÑÑ.Таны Ñанал гомдлыг илгÑÑхдÑÑ Ð·Ð°Ñ…Ð¸Ð°Ð½Ñ‹ хаÑгийг "
+"тань хөгжүүлÑгч Ñ€Ò¯Ò¯ хамт илгÑÑдÑггүй ÑƒÑ‡Ñ€Ð°Ð°Ñ Ñ…Ó©Ð³Ð¶Ò¯Ò¯Ð»ÑгчÑÑÑ Ñ‚Ð°Ð½Ð´ уг алдаа "
+"дутагдал нь дараагийн хувилбарт заÑагдÑан ÑÑÑхийг мÑдÑÑлÑÑ… боломжгүй байх "
+"болно."
+
+#. %s is a URL
+#: views/addons/display.thtml:278
+#, php-format
+msgid "addons_display_paragraph_supportinfourl"
+msgstr ""
+"Ð¥ÑÑ€Ñв та ÑÐ½Ñ Ó©Ñ€Ð³Ó©Ñ‚Ð³Ó©Ð»Ð¸Ð¹Ð³ дÑмжих Ñ…Ò¯ÑÑлтÑй бол %s хуудÑанд зорчино уу.Ð¥ÑÑ€Ñв та "
+"алдааны мÑдÑгдÑл байгаа бол түүнийгÑÑ ÑхлÑÑд хөгжүүлÑгчид нь мÑдÑгдÑÑ… нь "
+"илүү үр дүнтÑй байх болно. ХөгжүүлÑгч нь алдааны мÑдÑгдлийг шинжлÑхийн тулд "
+"нÑмÑлт мÑдÑÑлÑл шаардлагатай байдаг ÑƒÑ‡Ñ€Ð°Ð°Ñ ÑÐ½Ñ Ñ…ÑƒÑƒÐ´Ð°Ñ Ð½ÑŒ тийм үйлдÑлд "
+"тохиромжгүй билÑÑ.Таны Ñанал гомдлыг илгÑÑхдÑÑ Ð·Ð°Ñ…Ð¸Ð°Ð½Ñ‹ хаÑгийг тань "
+"хөгжүүлÑгч Ñ€Ò¯Ò¯ хамт илгÑÑдÑггүй ÑƒÑ‡Ñ€Ð°Ð°Ñ Ñ…Ó©Ð³Ð¶Ò¯Ò¯Ð»ÑгчÑÑÑ Ñ‚Ð°Ð½Ð´ уг алдаа дутагдал "
+"нь дараагийн хувилбарт заÑагдÑан ÑÑÑхийг мÑдÑÑлÑÑ… боломжгүй байх болно."
+
+#: views/addons/display.thtml:383
+msgid "addons_display_rate_it"
+msgstr "ДүгнÑлт өгөх"
+
+#: views/reviews/add.thtml:93 views/reviews/add.thtml:94
+msgid "addons_display_really_like_it"
+msgstr "ҮнÑÑ…ÑÑÑ€ таалагдаж байна"
+
+#: views/addons/display.thtml:410
+msgid "addons_display_review_etiquette"
+msgstr ""
+"ҮнÑлгÑÑ Ð´Ò¯Ð³Ð½Ñлт өгөх Ñ…ÑÑÑгт алдааны мÑдÑÑлÑл илгÑÑхгүй байхыг Ñ…Ò¯Ñье. Бид "
+"таны захианы хаÑгийг хөгжүүлÑгчдÑд нь харуулдаггүй болохоор тантай холбоо "
+"барьж уг алдааг заÑахад тань туÑалж чадахгүй байх болов уу."
+
+#. %1 is the review guidelines link
+#: views/addons/display.thtml:417
+#, fuzzy
+msgid "addons_display_review_guidelines_link"
+msgstr "<a href=\"%s\">Review Guidelines</a>"
+
+#. %1 is the support section link
+#: views/addons/display.thtml:414
+msgid "addons_display_review_see_support"
+msgstr ""
+"<a href=\"%1$s\">ДÑмжлÑг туÑламжийн</a> Ñ…ÑÑÑгт уг нÑмÑгдÑлд тохирÑон "
+"туÑламжийг Ñ…Ð°Ð°Ð½Ð°Ð°Ñ Ð°Ð²Ñ‡ болохыг харна уу."
+
+#: views/addons/display.thtml:404
+msgid "addons_display_review_submit"
+msgstr "Хадгал"
+
+#: views/addons/display.thtml:430
+#, php-format
+msgid "addons_display_see_all_addons"
+msgstr "Бүх %1$s төрлийн нÑмÑгдлүүдийг харах"
+
+#. %1 is the number of reviews
+#: views/addons/display.thtml:364
+#, php-format
+msgid "addons_display_see_all_reviews"
+msgstr "Бүх үнÑлгÑÑг харах (%1$s)"
+
+#: views/addons/display.thtml:219
+msgid "addons_display_see_all_versions"
+msgstr "Бүх хувилбарыг нь харах"
+
+#: views/addons/display.thtml:321 views/addons/versions.thtml:117
+msgid "addons_display_view_source"
+msgstr "Эх бичлÑгийг нь харах"
+
+#: views/addons/display.thtml:324
+msgid "addons_display_view_stats"
+msgstr "Судалгааны үр дүнг харах"
+
+#: views/addons/display.thtml:376
+msgid "addons_display_what_do_you_think"
+msgstr "Та юу гÑж бодож байна?"
+
+#: views/elements/app_compatibility.thtml:49
+msgid "addons_display_workswith"
+msgstr "Ðжиллах хувилбар:"
+
+#: views/addons/home.thtml:112
+#, fuzzy
+msgid "addons_home_browse_new"
+msgstr "Just Added"
+
+#: views/addons/home.thtml:110
+#, fuzzy
+msgid "addons_home_browse_popular"
+msgstr "Popular"
+
+#: views/addons/home.thtml:108
+#, fuzzy
+msgid "addons_home_browse_recommended"
+msgstr "Recommended"
+
+#: views/addons/home.thtml:127 views/addons/home.thtml:134
+#: views/addons/home.thtml:141 views/addons/home.thtml:148
+#, fuzzy
+msgid "addons_home_browse_subscribe"
+msgstr "Subscribe"
+
+#: views/addons/home.thtml:101
+#, fuzzy
+msgid "addons_home_browse_title"
+msgstr "Browse Add-ons"
+
+#: views/addons/home.thtml:114
+#, fuzzy
+msgid "addons_home_browse_updated"
+msgstr "Updated"
+
+#: views/elements/amo2009/homepage_addon.thtml:100
+#: views/elements/addon_discussionheader.thtml:83
+#: views/elements/addon_listitem.thtml:109 views/elements/feature.thtml:95
+#: views/addons/category_landing.thtml:66 views/addons/policy.thtml:57
+#: views/addons/display.thtml:70 views/addons/home.thtml:178
+msgid "addons_home_by"
+msgstr "зохиогч"
+
+#: views/addons/home.thtml:169
+#, fuzzy
+msgid "addons_home_collection_popular_title"
+msgstr "Popular Collections"
+
+#: views/elements/amo2009/categories.thtml:69 views/addons/home.thtml:160
+#, fuzzy
+msgid "addons_home_collections"
+msgstr "Collections"
+
+#. %1$s is the count of addons in a collection
+#: views/elements/amo2009/collection_listing_item.thtml:51
+#: views/addons/home.thtml:185
+#, fuzzy
+msgid "addons_home_collections_addon_count"
+msgid_plural "addons_home_collections_addon_count"
+msgstr[0] "<strong>%1$s</strong> add-on"
+msgstr[1] "<strong>%1$s</strong> add-ons"
+
+#: views/addons/home.thtml:196
+#, fuzzy
+msgid "addons_home_collections_all"
+msgstr "View All Collections"
+
+#: views/addons/home.thtml:162
+#, fuzzy
+msgid "addons_home_collections_intro"
+msgstr ""
+"Collections are a way for you to categorize, mix, match and mingle add-ons. "
+"Subscribe to collections created by other users or create your own."
+
+#. %1$s is the count of subscribers for a collection
+#: views/elements/amo2009/collection_listing_item.thtml:58
+#: views/collections/detail.thtml:96 views/addons/home.thtml:189
+#, fuzzy
+msgid "addons_home_collections_subscribers"
+msgid_plural "addons_home_collections_subscribers"
+msgstr[0] "<strong>%1$s</strong> subscriber"
+msgstr[1] "<strong>%1$s</strong> subscribers"
+
+#: views/addons/searchengines.thtml:54 views/addons/themes_landing.thtml:49
+msgid "addons_home_feature_head"
+msgstr "Бидний Ñанал болголт"
+
+#: controllers/search_controller.php:218 controllers/addons_controller.php:176
+#: controllers/addons_controller.php:428 controllers/addons_controller.php:671
+#: controllers/addons_controller.php:871
+#: controllers/addons_controller.php:1103
+#: controllers/addons_controller.php:1242
+#: controllers/addons_controller.php:1298
+#, php-format
+msgid "addons_home_header_details"
+msgstr ""
+"ÐÑмÑгдлүүд нь %1$s-г өргөтгөж нÑмдÑг бөгөөд танд Ñ…Ò¯ÑÑл зорилгодоо тохируулж "
+"өөрчлөхөд тань туÑлана. Тухтай Ñайхан зорчиж %1$s-г өөрийн болгоорой."
+
+#. %1$s is the HTML collection name link.
+#: views/elements/amo2009/teaser_collections.thtml:107
+#, fuzzy
+msgid "addons_home_introduction_collection_link"
+msgstr "Like these? Find more add-ons in %1$s."
+
+#: views/elements/amo2009/teaser_collections.thtml:60
+#, fuzzy
+msgid "addons_home_introduction_extras"
+msgstr ""
+"<strong>Over 5000 free extras</strong> that let you customize and extend "
+"Firefox to meet your needs."
+
+#: views/elements/amo2009/teaser_collections.thtml:55
+#, fuzzy
+msgid "addons_home_introduction_header"
+msgstr "What are Add-ons?"
+
+#: views/elements/amo2009/teaser_collections.thtml:72
+#, fuzzy
+msgid "addons_home_introduction_install"
+msgstr ""
+"<strong>Easy to install</strong>, get notified when updates are available."
+
+#: views/elements/amo2009/teaser_collections.thtml:45
+#, fuzzy
+msgid "addons_home_introduction_name"
+msgstr "Introduction"
+
+#: views/elements/amo2009/teaser_collections.thtml:66
+#, fuzzy
+msgid "addons_home_introduction_themes"
+msgstr ""
+"Toolbars, themes and search providers that <strong>help you perform common "
+"tasks.</strong>"
+
+#: views/addons/home.thtml:161
+#, fuzzy
+msgid "addons_home_new_indicator"
+msgstr "NEW!"
+
+#: views/elements/app_chooser.thtml:48 views/layouts/amo2009.thtml:257
+msgid "addons_home_other_applications"
+msgstr "БуÑад програмууд"
+
+#. %1$s is the application the user is browsing. Examples: Thunderbird, Firefox,
+#. Sunbird
+#: views/pages/collector_faq.thtml:49 views/pages/collector_firstrun.thtml:42
+#: views/pages/collector.thtml:46 views/pages/collector_features.thtml:54
+#: controllers/developers_controller.php:87
+#: controllers/compatibility_controller.php:72
+#: controllers/components/simple_acl.php:81 controllers/components/amo.php:607
+#: controllers/statistics_controller.php:60
+#: controllers/statistics_controller.php:240
+#: controllers/previews_controller.php:67 controllers/users_controller.php:90
+#: controllers/users_controller.php:223 controllers/users_controller.php:330
+#: controllers/users_controller.php:414 controllers/users_controller.php:708
+#: controllers/users_controller.php:723 controllers/reviews_controller.php:204
+#: controllers/reviews_controller.php:251
+#: controllers/reviews_controller.php:346
+#: controllers/reviews_controller.php:425
+#: controllers/search_controller.php:185 controllers/search_controller.php:297
+#: controllers/search_controller.php:301 controllers/addons_controller.php:147
+#: controllers/addons_controller.php:280 controllers/addons_controller.php:370
+#: controllers/addons_controller.php:667 controllers/addons_controller.php:874
+#: controllers/addons_controller.php:1019
+#: controllers/addons_controller.php:1034
+#: controllers/addons_controller.php:1101
+#: controllers/addons_controller.php:1121
+#: controllers/addons_controller.php:1240
+#: controllers/addons_controller.php:1357
+#: controllers/addons_controller.php:1364
+#: controllers/addons_controller.php:1442
+#: controllers/addons_controller.php:1477
+#: controllers/addons_controller.php:1538
+#: controllers/addons_controller.php:1543
+#: controllers/editors_controller.php:64 controllers/pages_controller.php:132
+#: controllers/groups_controller.php:65 controllers/groups_controller.php:71
+#: controllers/groups_controller.php:89 controllers/groups_controller.php:111
+#: controllers/collections_controller.php:57
+#: controllers/collections_controller.php:121
+#: controllers/collections_controller.php:205
+#: controllers/collections_controller.php:365
+#: controllers/collections_controller.php:404
+#: controllers/collections_controller.php:466
+#: controllers/collections_controller.php:538
+#: controllers/collections_controller.php:828
+#: controllers/localizers_controller.php:72
+#, php-format
+msgid "addons_home_pagetitle"
+msgstr "%1$s нÑмÑгдлүүд"
+
+#. %1$s is the number of addons downloaded
+#: views/addons/home.thtml:57
+#, fuzzy, php-format
+msgid "addons_home_stats_downloaded"
+msgid_plural "addons_home_stats_downloaded"
+msgstr[0] "<strong>%1$s</strong> <span>add-on downloaded</span>"
+msgstr[1] "<strong>%1$s</strong> <span>add-ons downloaded</span>"
+
+#. %1$s is the number of addons in use
+#: views/addons/home.thtml:63
+#, fuzzy, php-format
+msgid "addons_home_stats_inuse"
+msgid_plural "addons_home_stats_inuse"
+msgstr[0] "<strong>%1$s</strong> <span>add-on in use</span>"
+msgstr[1] "<strong>%1$s</strong> <span>add-ons in use</span>"
+
+#: views/addons/home.thtml:136
+msgid "addons_home_view_all_newest_title"
+msgstr "ШинÑÑÑ€ Ò¯Ò¯ÑгÑгдÑÑн нÑмÑгдлүүдийг харах"
+
+#: views/addons/home.thtml:129
+msgid "addons_home_view_all_popular_title"
+msgstr "Бүх өргөн тархÑан нÑмÑгдлүүдийг харах"
+
+#: views/addons/home.thtml:150
+msgid "addons_home_view_all_recommended_title"
+msgstr "Бүх Ñанал болгоÑон өргөтгөлүүдийг харах"
+
+#: views/addons/home.thtml:143
+msgid "addons_home_view_all_updated_title"
+msgstr "СаÑхан шинÑчлÑгдÑÑн бүх нÑмÑгдлүүдийг харах"
+
+#: views/elements/amo2009/install.thtml:334 views/elements/install.thtml:112
+#, fuzzy
+msgid "addons_install_in_sunbird"
+msgstr ""
+"<ol><li>Click the link below to save the file.</li><li>In Mozilla Sunbird, "
+"open Add-ons from the Tools menu.</li><li>Click the Install button, and "
+"locate/select the file you downloaded and click \"OK\".</li></ol>"
+
+#: views/elements/amo2009/install.thtml:333 views/elements/install.thtml:111
+#, fuzzy
+msgid "addons_install_in_sunbird_title"
+msgstr "How to Install in Sunbird"
+
+#: views/elements/amo2009/install.thtml:331 views/elements/install.thtml:106
+msgid "addons_install_in_thunderbird"
+msgstr ""
+"<ol><li>Доорх Ñ…Ð¾Ð»Ð±Ð¾Ð¾Ñ Ð´ÑÑÑ€ хулганы баруун товчийг дарж \"ХолбогдÑон файлд "
+"нÑÑ€ өгч хадгал\" (Save Link as...) гÑж Ñонгоод дотоод диÑк рүүгÑÑ Ñ‚Ð°Ñ‚Ð°Ð¶ авна "
+"уу.</li><li>Mozilla Thunderbird дÑÑÑ€ Багаж цÑÑний ÐÑмÑгдлүүд цÑÑийг нÑÑнÑ.</"
+"li><li>Суулга товч дÑÑÑ€ дараад татаж авÑан файлынхаа Ð±Ð°Ð¹Ñ€ÑˆÐ»Ð°Ð°Ñ Ñ„Ð°Ð¹Ð»Ð°Ð° "
+"Ñонгоод \"OK\" дÑÑÑ€ дарна.</li></ol>"
+
+#: views/elements/amo2009/install.thtml:330 views/elements/install.thtml:105
+msgid "addons_install_in_thunderbird_title"
+msgstr "Thunderbird дÑÑÑ€ Ñ…ÑрхÑн Ñуулгах вÑ"
+
+#: views/elements/amo2009/addon_list_options.thtml:108
+#: views/elements/addon_list_options.thtml:105
+msgid "addons_options_show_experimental"
+msgstr "туршилтын нÑмÑгдлүүдийг харуулах"
+
+#: views/elements/amo2009/addon_list_options.thtml:113
+#: views/elements/addon_list_options.thtml:109
+msgid "addons_options_submit"
+msgstr "Харах"
+
+#: views/addons/plugins.thtml:63 views/addons/plugins.thtml:73
+#: views/addons/plugins.thtml:83 views/addons/plugins.thtml:93
+#: views/addons/plugins.thtml:103 views/addons/plugins.thtml:116
+#: views/addons/plugins.thtml:126
+msgid "addons_plugins_by"
+msgstr "Зохиогч"
+
+#: views/addons/plugins.thtml:107
+msgid "addons_plugins_for_linux"
+msgstr "Ð›Ð¸Ð½ÑƒÐºÑ Ð¼Ð°ÑˆÐ¸Ð½Ð´"
+
+#: views/addons/plugins.thtml:108 views/addons/plugins.thtml:131
+msgid "addons_plugins_for_macosx"
+msgstr "Mac OS X машинд"
+
+#: views/addons/plugins.thtml:106 views/addons/plugins.thtml:129
+#: views/addons/plugins.thtml:130
+msgid "addons_plugins_for_windows"
+msgstr "Windows машинд"
+
+#. %1$s is a URL
+#: views/addons/plugins.thtml:139
+#, php-format
+msgid "addons_plugins_looking_for_more"
+msgstr ""
+"Ð­Ð½Ñ Ñ…ÑƒÑƒÐ´Ñанд зөвхөн өргөн тархÑан болон байнга Ñ…ÑÑ€ÑглÑгддÑг плагинуудыг "
+"харуулÑан болно. БуÑад Мозилла хөтлөгчдөд зориулÑан плагинуудыг харахыг "
+"Ñ…Ò¯ÑвÑл %1$s хуудÑанд зорчино уу."
+
+#: views/addons/plugins.thtml:137
+msgid "addons_plugins_looking_for_plugin"
+msgstr "Таны хайж буй плагин Ñнд байхгүй байна уу?"
+
+#: views/addons/plugins.thtml:58
+msgid "addons_plugins_main_description"
+msgstr ""
+"Плагинууд нь таны хөтлөгч дÑÑÑ€ дуут дүрÑÑ‚Ñй файл үзÑÑ… ÑÑвÑл онцгой зургийн "
+"төрлийг харах зÑÑ€Ñг онцгой үйлдлүүдийг гүйцÑтгÑÑ…Ñд Ñ…ÑÑ€ÑглÑгддÑг. Плагин нь "
+"Ó©Ñ€Ð³Ó©Ñ‚Ð³Ó©Ð»Ó©Ó©Ñ Ð¾Ð´Ð¾Ð¾Ð³Ð¸Ð¹Ð½ байгаа үйлдлийг өөрчлөх юмуу нÑмдÑгÑÑÑ€ÑÑ Ð±Ð°Ð³Ð° зÑÑ€Ñг "
+"Ñлгардаг."
+
+#. %1$s is the application name. Example: Firefox, Thunderbird, Sunbird
+#: controllers/addons_controller.php:1122
+#, php-format
+msgid "addons_plugins_main_header"
+msgstr "%1$s-д зориулÑан ердийн плагинууд"
+
+#: controllers/components/amo.php:698 controllers/addons_controller.php:1121
+msgid "addons_plugins_pagetitle"
+msgstr "Плагинууд"
+
+#: views/addons/plugins.thtml:68 views/addons/plugins.thtml:78
+#: views/addons/plugins.thtml:88 views/addons/plugins.thtml:98
+#: views/addons/plugins.thtml:110 views/addons/plugins.thtml:121
+#: views/addons/plugins.thtml:133
+msgid "addons_plugins_support_documentation"
+msgstr "Заавар бичиг баримт: "
+
+#. %s is the name of the add-on
+#: views/addons/policy.thtml:61
+#, php-format
+msgid "addons_policy_eula_require"
+msgstr ""
+"%s Ñуулгацыг үргÑлжлүүлÑÑ…ÑÑÑÑÑ Ó©Ð¼Ð½Ó© Ð¥ÑÑ€ÑглÑÑ… лицензийг зөвшөөрÑөн ÑÑÑхийг "
+"мÑдÑÑ… шаардлагатай:"
+
+#. %1 is the add-on name
+#: controllers/addons_controller.php:1476
+#, php-format
+msgid "addons_previews_pagetitle"
+msgstr "%s-н үзүүлбÑÑ€"
+
+#: views/addons/category_landing.thtml:135
+#, fuzzy
+msgid "addons_recently_added"
+msgstr "Recently Added"
+
+#: views/addons/recommended.thtml:51 controllers/addons_controller.php:1365
+msgid "addons_recommended_introduction"
+msgstr ""
+"Маш олон нÑмÑгдлүүд боломжтой байгаа бөгөөд хүн болгонд тохирÑон зарим "
+"нÑмÑгдлүүд байдаг. Танд туÑлах зорилгоор байнга Ñ…ÑÑ€ÑглÑгддÑг болон өргөн "
+"тархÑан нÑмÑгдлүүдийг Ñнд жагÑаав. Таалан Ñоёрхоно уу!"
+
+#: controllers/addons_controller.php:1357
+#: controllers/addons_controller.php:1364
+msgid "addons_recommended_pagetitle"
+msgstr "Санал болгогдÑон нÑмÑгдлүүд"
+
+#: controllers/addons_controller.php:1360
+msgid "addons_recommended_title"
+msgstr "Санал болгогдÑон нÑмÑгдлүүд"
+
+#: views/addons/searchengines.thtml:136
+msgid "addons_searchengines_additional_resources"
+msgstr "ÐÑмÑлт ÑÑ… Ñурвалж"
+
+#. link text devmo
+#: views/addons/searchengines.thtml:141
+msgid "addons_searchengines_devmo_link"
+msgstr "Мозилаг хөгжүүлÑгчдийн төв"
+
+#: views/pages/js_constants.js.thtml:67
+msgid "addons_searchengines_error_mozilla_browser_required"
+msgstr ""
+"Уулчаарай, хайгч плагиныг Ñуулгахын тулд Мозила үндÑÑÑ‚Ñй (жишÑÑ Ð½ÑŒ Firefox) "
+"хөтлөгч Ñуулгах Ñ…ÑÑ€ÑгтÑй."
+
+#: views/addons/searchengines.thtml:49
+msgid "addons_searchengines_error_nojavascript"
+msgstr ""
+"Плагин Ñуулгахын тулд ЖааваÑрипт шаардлагатай байдаг бөгөөд та түүнийг "
+"хорьчихÑон юм шиг байна. Доорх хайгч плагинуудыг Ñуулгахын тулд "
+"жааваÑкриптийг зөвшөөрнө Ò¯Ò¯."
+
+#. %1 is "make your own" link
+#. %2 is MDC link
+#: views/addons/searchengines.thtml:139
+msgid "addons_searchengines_learn_howto"
+msgstr "Ð¥ÑрхÑн %2$s дÑÑÑ€ %1$s-н тухай Ñурах."
+
+#. link path to search plugins instructions, relative to devmo
+#: views/addons/searchengines.thtml:140
+msgid "addons_searchengines_makeyourown_href"
+msgstr "/en/docs/Creating_OpenSearch_plugins_for_Firefox"
+
+#. link text for "make your own" (opensearch engine)
+#: views/addons/searchengines.thtml:140
+msgid "addons_searchengines_makeyourown_link"
+msgstr "өөрийн болгох"
+
+#. %1 is the link to mycroft.mozdev.org
+#: views/addons/searchengines.thtml:138
+msgid "addons_searchengines_more"
+msgstr "%1$s дÑÑÑ€ буй буÑад хайгчдыг Ñонирхоно уу."
+
+#. link text to mycroft.mozdev.org
+#: views/addons/searchengines.thtml:138
+msgid "addons_searchengines_mycroft_link"
+msgstr "mycroft.mozdev.org"
+
+#: controllers/addons_controller.php:1100
+#: controllers/addons_controller.php:1110
+msgid "addons_searchengines_pagetitle"
+msgstr "Хайлт хийгчид"
+
+#: views/addons/searchengines.thtml:143
+msgid "addons_searchengines_thanks"
+msgstr ""
+"Firefox-н хайлт хийгчдÑд зориулж ажиллаÑан Mycroft Ñ‚Ó©Ñлийн хамт олонд онцгой "
+"талархал дÑвшүүлж байна."
+
+#: views/addons/display.thtml:154
+#, fuzzy
+msgid "addons_share_button_text"
+msgstr "Share this"
+
+#: controllers/addons_controller.php:89
+#, fuzzy
+msgid "addons_share_label_delicious"
+msgstr "Add to Delicious"
+
+#: controllers/addons_controller.php:77
+#, fuzzy
+msgid "addons_share_label_digg"
+msgstr "Digg this!"
+
+#: controllers/addons_controller.php:83
+#, fuzzy
+msgid "addons_share_label_facebook"
+msgstr "Post to Facebook"
+
+#: controllers/addons_controller.php:101
+#, fuzzy
+msgid "addons_share_label_friendfeed"
+msgstr "Share on FriendFeed"
+
+#: controllers/addons_controller.php:95
+#, fuzzy
+msgid "addons_share_label_myspace"
+msgstr "Post to MySpace"
+
+#: controllers/components/amo.php:201 controllers/components/amo.php:229
+#, fuzzy
+msgid "addons_status_disabled"
+msgstr "Disabled"
+
+#: controllers/components/amo.php:191 controllers/components/amo.php:224
+#, fuzzy
+msgid "addons_status_incomplete"
+msgstr "Incomplete Version"
+
+#: controllers/components/amo.php:197 controllers/components/amo.php:227
+#, fuzzy
+msgid "addons_status_nominated"
+msgstr "In Sandbox; Public Nomination"
+
+#: views/pages/js_constants.js.thtml:80 controllers/components/amo.php:195
+#: controllers/components/amo.php:226
+#, fuzzy
+msgid "addons_status_pending"
+msgstr "In Sandbox; Pending Review"
+
+#: views/pages/js_constants.js.thtml:78 controllers/components/amo.php:199
+#: controllers/components/amo.php:228
+#, fuzzy
+msgid "addons_status_public"
+msgstr "Public"
+
+#: views/pages/js_constants.js.thtml:79 controllers/components/amo.php:193
+#: controllers/components/amo.php:225
+#, fuzzy
+msgid "addons_status_sandbox"
+msgstr "In Sandbox"
+
+#: controllers/components/amo.php:203
+#, fuzzy
+msgid "addons_status_unknown"
+msgstr "Unknown"
+
+#: views/elements/amo2009/teaser_collections.thtml:91
+#: views/elements/amo2009/homepage_addon.thtml:99
+#: views/elements/feature.thtml:94
+#, fuzzy
+msgid "addons_title_tooltip"
+msgstr "Learn more about this add-on"
+
+#: views/addons/category_landing.thtml:151
+#, fuzzy
+msgid "addons_top_downloads"
+msgstr "Top Downloads"
+
+#: views/addons/category_landing.thtml:165
+#, fuzzy
+msgid "addons_top_rated"
+msgstr "Top Rated"
+
+#: views/addons/versions.thtml:62
+msgid "addons_versions_careful"
+msgstr "Хуучин Ñ…ÑƒÐ²Ð¸Ð»Ð±Ð°Ñ€Ð°Ð°Ñ Ð±Ð¾Ð»Ð³Ð¾Ð¾Ð¼Ð¶Ð¸Ð»"
+
+#: views/addons/versions.thtml:63
+msgid "addons_versions_careful_introduction"
+msgstr ""
+"ЭдгÑÑÑ€ хувилбар нь шалгах юмуу лавлагаа зориулалтаар харуулагдÑан болно. Та "
+"үргÑлж ÑˆÐ¸Ð½Ñ Ñ…ÑƒÐ²Ð¸Ð»Ð±Ð°Ñ€Ñ‹Ð³ нь илүүд тооцох Ñ…ÑÑ€ÑгтÑй."
+
+#: controllers/addons_controller.php:1549
+msgid "addons_versions_history"
+msgstr "Өөрчлөлтийн бүртгÑл агуулÑан хувилбарын түүх"
+
+#. %1$s is the add-on name
+#: controllers/addons_controller.php:1535
+#, php-format
+msgid "addons_versions_pagetitle"
+msgstr "%1$s хувилбарын түүх"
+
+#: controllers/groups_controller.php:71
+msgid "admin_group_add_pagetitle"
+msgstr "БүлÑг нÑм"
+
+#: controllers/groups_controller.php:111
+msgid "admin_group_delete_pagetitle"
+msgstr "БүлÑг уÑтга"
+
+#. %s is a number to identify the group
+#: controllers/groups_controller.php:117
+#, php-format
+msgid "admin_group_deleted"
+msgstr "%s гÑÑÑн таних нÑртÑй бүлÑг уÑтгагдлаа"
+
+#: controllers/groups_controller.php:89
+msgid "admin_group_edit_pagetitle"
+msgstr "БүлÑг заÑварла"
+
+#: controllers/groups_controller.php:92 controllers/groups_controller.php:113
+msgid "admin_group_error_invalid_id"
+msgstr "Бүлгийн буруу таних нÑÑ€ байна"
+
+#: controllers/groups_controller.php:65
+msgid "admin_group_pagetitle"
+msgstr "БүлÑг зохицуулагч"
+
+#: controllers/groups_controller.php:77 controllers/groups_controller.php:99
+msgid "admin_group_saved"
+msgstr "БүлÑг хадгалагдав"
+
+#: views/elements/amo2009/search.thtml:257 views/elements/search.thtml:239
+msgid "advanced_search_form"
+msgstr "ÐÑмÑлт"
+
+#: views/elements/amo2009/search.thtml:126 views/elements/search.thtml:125
+msgid "advanced_search_form_any_time"
+msgstr "бүх хугацаанд"
+
+#: views/elements/amo2009/search.thtml:97
+#: views/elements/amo2009/search.thtml:110 views/elements/search.thtml:96
+#: views/elements/search.thtml:109
+msgid "advanced_search_form_any_type"
+msgstr "бүх төрөлд"
+
+#: views/elements/amo2009/search.thtml:275 views/elements/search.thtml:254
+msgid "advanced_search_form_any_version"
+msgstr "бүх хувилбарт"
+
+#: views/elements/amo2009/search.thtml:217 views/elements/search.thtml:212
+msgid "advanced_search_form_application"
+msgstr "Програм"
+
+#: views/elements/amo2009/search.thtml:143 views/elements/search.thtml:142
+msgid "advanced_search_form_keyword_match"
+msgstr "Хайх үгтÑй тохирÑон"
+
+#: views/elements/amo2009/search.thtml:251 views/elements/search.thtml:225
+msgid "advanced_search_form_lastupdate"
+msgstr "Сүүлд шинÑчлÑгдÑÑн"
+
+#: views/elements/amo2009/search.thtml:145 views/elements/search.thtml:144
+msgid "advanced_search_form_name"
+msgstr "ÐÑÑ€"
+
+#: views/elements/amo2009/search.thtml:144 views/elements/search.thtml:143
+msgid "advanced_search_form_newest"
+msgstr "Хамгийн Ñүүлийн"
+
+#: views/elements/amo2009/search.thtml:130 views/elements/search.thtml:129
+msgid "advanced_search_form_past_3_months"
+msgstr "ӨнгөрÑөн 3 Ñард"
+
+#: views/elements/amo2009/search.thtml:131 views/elements/search.thtml:130
+msgid "advanced_search_form_past_6_months"
+msgstr "ӨнгөрÑөн 6 Ñард"
+
+#: views/elements/amo2009/search.thtml:127 views/elements/search.thtml:126
+msgid "advanced_search_form_past_day"
+msgstr "ӨнгөрÑөн өдөр"
+
+#: views/elements/amo2009/search.thtml:129 views/elements/search.thtml:128
+msgid "advanced_search_form_past_month"
+msgstr "ӨнгөрÑөн Ñар"
+
+#: views/elements/amo2009/search.thtml:128 views/elements/search.thtml:127
+msgid "advanced_search_form_past_week"
+msgstr "ӨнгөрÑөн долоо хоног"
+
+#: views/elements/amo2009/search.thtml:132 views/elements/search.thtml:131
+msgid "advanced_search_form_past_year"
+msgstr "ӨнгөрÑөн жил"
+
+#: views/elements/amo2009/search.thtml:239 views/elements/search.thtml:230
+msgid "advanced_search_form_perpage"
+msgstr "ÐÑг хуудÑанд"
+
+#: views/elements/amo2009/search.thtml:243 views/elements/search.thtml:224
+msgid "advanced_search_form_platform"
+msgstr "СиÑтемийн төрөл"
+
+#: views/elements/amo2009/search.thtml:147 views/elements/search.thtml:146
+msgid "advanced_search_form_popularity"
+msgstr "Олонд тархÑанаар нь"
+
+#: views/elements/amo2009/search.thtml:146 views/elements/search.thtml:145
+msgid "advanced_search_form_rating"
+msgstr "ҮнÑлгÑÑгÑÑÑ€ нь"
+
+#: views/elements/amo2009/search.thtml:247 views/elements/search.thtml:231
+msgid "advanced_search_form_sortby"
+msgstr "ЭрÑмбÑлÑлт"
+
+#: views/elements/amo2009/search.thtml:227 views/elements/search.thtml:216
+msgid "advanced_search_form_to"
+msgstr "-Ñ ÑхлÑÑд"
+
+#: views/elements/amo2009/search.thtml:257 views/elements/search.thtml:237
+#, fuzzy
+msgid "advanced_search_form_toggle_tooltip"
+msgstr "Toggle advanced search mode"
+
+#: views/elements/amo2009/search.thtml:235 views/elements/search.thtml:223
+msgid "advanced_search_form_type"
+msgstr "Төрөл"
+
+#: views/elements/amo2009/search.thtml:222 views/elements/search.thtml:214
+msgid "advanced_search_form_version"
+msgstr "хувилбар"
+
+#: views/elements/amo2009/pagination.thtml:42
+#, fuzzy
+msgid "amo2009_pagination_next_page"
+msgstr "Next"
+
+#: views/elements/amo2009/pagination.thtml:41
+#, fuzzy
+msgid "amo2009_pagination_previous_page"
+msgstr "Prev"
+
+#: views/pages/js_constants.js.thtml:96
+msgid "app_compat_ignore_check"
+msgstr "Хувилбар шалгахыг алгаÑ"
+
+#: views/pages/js_constants.js.thtml:72
+msgid "app_compat_older_firefox_only"
+msgstr "Ð­Ð½Ñ Ð½ÑмÑгдÑл нь Firefox-н хуучин хувилбарт зориулагдÑан"
+
+#. %1$s and %2$s are URLs
+#: views/pages/js_constants.js.thtml:74
+#, fuzzy
+msgid "app_compat_older_version_or_ignore_check"
+msgstr ""
+"You can <a href=\"%1$s\">try an older version</a> or <a href=\"#\" onclick="
+"\"%2$s\">ignore this check</a>"
+
+#. %1$s is a URL
+#: views/pages/js_constants.js.thtml:71
+msgid "app_compat_try_old_version"
+msgstr "<a href=\"%1$s\">хуучин хувилбард</a> ажиллаж магадгүй"
+
+#. %1$s is a URL
+#. %2$s is a version number. Example: 3.1
+#: views/pages/js_constants.js.thtml:73
+#, fuzzy
+msgid "app_compat_unreleased_version"
+msgstr ""
+"This add-on requires the not-yet released <a href=\"%1$s\">Firefox %2$s</a>"
+
+#: views/pages/js_constants.js.thtml:70
+msgid "app_compat_update_firefox"
+msgstr ""
+"<a href=\"http://getfirefox.com\">Firefox-г шинÑчлÑÑд</a> ÑÐ½Ñ Ð½ÑмÑгдлийг "
+"ашиглана уу"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#. %3$s is a status, like Public.
+#: controllers/components/audit.php:79
+#, fuzzy
+msgid "audit_addon_status"
+msgstr "%1$s changed the status of %2$s to %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:221
+#, fuzzy
+msgid "audit_admin_default"
+msgstr "%1$s committed unknown admin action %2$s to ID %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:153
+#, fuzzy
+msgid "audit_admin_feature_remove"
+msgstr "%1$s removed feature %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is an application, like Firefox.
+#: controllers/components/audit.php:92
+#, fuzzy
+msgid "audit_application_create"
+msgstr "%1$s created application %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is an application, like Firefox.
+#: controllers/components/audit.php:95
+#, fuzzy
+msgid "audit_application_edit"
+msgstr "%1$s edited application %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a version number, like 3.5.
+#. %3$s is an application, like Firefox.
+#: controllers/components/audit.php:105
+#, fuzzy
+msgid "audit_appversion_create"
+msgstr "%1$s created version %2$s for %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a version number, like 3.5.
+#. %3$s is an application, like Firefox.
+#: controllers/components/audit.php:108
+#, fuzzy
+msgid "audit_appversion_delete"
+msgstr "%1$s deleted version %2$s for %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a config field, like "awesomeness".
+#. %3$s is a config value, like "off".
+#. %4$s is a config value, like "on".
+#: controllers/components/audit.php:210
+#, fuzzy
+msgid "audit_config"
+msgstr "%1$s changed config '%2$s' from '%3$s' to '%4$s'"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:258
+#, fuzzy
+msgid "audit_editor_default"
+msgstr "%1$s committed unknown editor action %2$s to ID %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#: controllers/components/audit.php:236
+#, fuzzy
+msgid "audit_editor_feature_remove"
+msgstr "%1$s removed addon %2$s from feature list"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#: controllers/components/audit.php:231
+#, fuzzy
+msgid "audit_feature_add"
+msgstr "%1$s added addon %2$s to feature list"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:149
+#, fuzzy
+msgid "audit_feature_edit"
+msgstr "%1$s changed a feature for %2$s locale"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#: controllers/components/audit.php:241
+#, fuzzy
+msgid "audit_feature_locale_change"
+msgstr "%1$s changed locales for addon %2$s on feature list"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:83
+#, fuzzy
+msgid "audit_file_recalchash"
+msgstr "%1$s recalculated the hash for file %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>user name</a>
+#. %3$s is <a>group name</a>
+#: controllers/components/audit.php:182
+#, fuzzy
+msgid "audit_group_addmember"
+msgstr "%1$s added %2$s to group %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:313
+#, fuzzy
+msgid "audit_group_associated"
+msgstr "%1$s associated themselves with %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:162
+#, fuzzy
+msgid "audit_group_create"
+msgstr "%1s created group %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:170
+#, fuzzy
+msgid "audit_group_delete"
+msgstr "%1$s deleted group %2$s (ID %3$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:165
+#, fuzzy
+msgid "audit_group_edit"
+msgstr "%1$s edited group %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>user name</a>
+#. %3$s is <a>group name</a>
+#: controllers/components/audit.php:188
+#, fuzzy
+msgid "audit_group_removemember"
+msgstr "%1$s removed %2$s from group %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:280
+#, fuzzy
+msgid "audit_l10n_default"
+msgstr "%1$s committed unknown action %2$s for %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:295
+#, fuzzy
+msgid "audit_modify_locked_group"
+msgstr "%1$s attempted to modify locked group %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:299
+#, fuzzy
+msgid "audit_modify_other_locale"
+msgstr "%1$s attempted to modify translations in %2$s without permission"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a platform, like <a>Windows</a>
+#: controllers/components/audit.php:135
+#, fuzzy
+msgid "audit_platform_create"
+msgstr "%1$s created platform %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a platform, like <a>Windows</a>
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:143
+#, fuzzy
+msgid "audit_platform_delete"
+msgstr "%1$s deleted platform %2$s (ID %3$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a platform, like <a>Windows</a>
+#: controllers/components/audit.php:138
+#, fuzzy
+msgid "audit_platform_edit"
+msgstr "%1$s edited platform %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a part of the admin, like 'Site Config'
+#: controllers/components/audit.php:288
+#, fuzzy
+msgid "audit_reauthentication_failure"
+msgstr "%1$s failed to re-authenticate to access %2$s."
+
+#. %1$s is <a>user name</a>
+#. %2$s is the name of a canned response, like 'Ready for the public'
+#: controllers/components/audit.php:198
+#, fuzzy
+msgid "audit_response_create"
+msgstr "%1$s created response %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is the name of a canned response, like 'Ready for the public'
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:206
+#, fuzzy
+msgid "audit_response_delete"
+msgstr "%1$s deleted response %2$s (ID %3$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is the name of a canned response, like 'Ready for the public'
+#: controllers/components/audit.php:201
+#, fuzzy
+msgid "audit_response_edit"
+msgstr "%1$s edited response %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:245
+#, fuzzy
+msgid "audit_review_approve"
+msgstr "%1$s approved review %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:250 controllers/components/audit.php:253
+#, fuzzy
+msgid "audit_review_delete"
+msgstr "%1$s deleted review %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:303
+#, fuzzy
+msgid "audit_security_default"
+msgstr "%1$s committed unknown security action %2$s to ID %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a category name, like <a>Search Tools</a>
+#: controllers/components/audit.php:118
+#, fuzzy
+msgid "audit_tag_create"
+msgstr "%1$s created tag %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a category name, like <a>Search Tools</a>
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:126
+#, fuzzy
+msgid "audit_tag_delete"
+msgstr "%1$s deleted category %2$s (ID %3$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a category name, like <a>Search Tools</a>
+#: controllers/components/audit.php:121
+#, fuzzy
+msgid "audit_tag_edit"
+msgstr "%1$s edited category %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:266
+#, fuzzy
+msgid "audit_update_applications"
+msgstr "%1$s updated application translations for %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:277
+#, fuzzy
+msgid "audit_update_blog"
+msgstr "%1$s updated blog post translations for %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:274
+#, fuzzy
+msgid "audit_update_platforms"
+msgstr "%1$s updated platform translations for %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:270
+#, fuzzy
+msgid "audit_update_tags"
+msgstr "%1$s updated category translations for %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>user name</a>
+#: controllers/components/audit.php:217
+#, fuzzy
+msgid "audit_user_edit"
+msgstr "%1$s edited %2$s's user information"
+
+#: controllers/addons_controller.php:1012
+msgid "browse_addons_name"
+msgstr "ÐÑÑ€ÑÑÑ€ нь ÑÑ€ÑмбÑлж харах"
+
+#: controllers/addons_controller.php:1010
+msgid "browse_addons_newest"
+msgstr "ШинÑÑ…Ñн нÑмÑгдлүүд"
+
+#: controllers/addons_controller.php:1008
+msgid "browse_addons_popular"
+msgstr "Өргөн тархÑан нÑмÑгдлүүд"
+
+#: controllers/addons_controller.php:1011
+msgid "browse_addons_rated"
+msgstr "ҮнÑлгÑÑгÑÑÑ€ нь ÑÑ€ÑмбÑлж харах"
+
+#: controllers/addons_controller.php:1009
+msgid "browse_addons_updated"
+msgstr "СаÑхан шинÑчлÑгдÑÑн нÑмÑгдлүүд"
+
+#: views/elements/categories.thtml:73 views/elements/categories.thtml:82
+msgid "categories_current_title"
+msgstr "СонгогдÑон төрөл"
+
+#: views/elements/categories.thtml:50
+#: views/elements/amo2009/categories.thtml:43
+#: views/elements/amo2009/categories.thtml:45
+msgid "categories_header"
+msgstr "Төрөл анги"
+
+#: views/elements/categories.thtml:50
+#: views/elements/amo2009/categories.thtml:41
+msgid "categories_header_title"
+msgstr "Төрөл Ñонгох"
+
+#. %1$s is the category name
+#: views/addons/searchengines.thtml:129
+#, php-format
+msgid "category_extra_see_all"
+msgstr "%1$s Ñ‚Ó©Ñ€Ð»Ó©Ó©Ñ Ð±Ò¯Ð³Ð´Ð¸Ð¹Ð³ нь харуул"
+
+#. %1$s is a number.
+#: models/collection.php:130
+#, fuzzy
+msgid "collection_description_limit"
+msgstr "The description should be less than %1$s characters."
+
+#. %1$s is the name of the collection
+#: controllers/collections_controller.php:392
+#, fuzzy
+msgid "collection_detail_rss_title"
+msgstr "%s Collection"
+
+#: controllers/collections_controller.php:1065
+#, fuzzy
+msgid "collection_error_deleting_addon"
+msgstr "Error deleting add-on!"
+
+#: controllers/collections_controller.php:1051
+#, fuzzy
+msgid "collection_error_saving_addon"
+msgstr "Error saving add-on!"
+
+#: controllers/collections_controller.php:1080
+#, fuzzy
+msgid "collection_error_saving_comment"
+msgstr "Error saving comment!"
+
+#. %1$s is a number.
+#: models/collection.php:122
+#, fuzzy
+msgid "collection_name_limit"
+msgstr "The name should be less than %1$s characters."
+
+#: controllers/collections_controller.php:352
+#: controllers/collections_controller.php:487
+#, fuzzy
+msgid "collection_not_found"
+msgstr "Collection not found!"
+
+#. %1$s is the text on the "create collection" button
+#: views/collections/add.thtml:91
+#, fuzzy
+msgid "collections_add_formfield_addons_description"
+msgstr ""
+"If you already know which add-ons you want to add to your collection, just "
+"start typing their names below. If you'd rather wait and do this later, just "
+"click %1$s now."
+
+#: views/collections/add.thtml:90
+#, fuzzy
+msgid "collections_add_formfield_firstaddons"
+msgstr "Choose your first add-ons"
+
+#: views/collections/add.thtml:48
+#, fuzzy
+msgid "collections_add_header"
+msgstr "Create a Collection"
+
+#: views/collections/add.thtml:97
+#, fuzzy
+msgid "collections_add_header_selectedaddons"
+msgstr "Selected Add-ons"
+
+#: views/collections/add.thtml:50
+#, fuzzy
+msgid "collections_add_intro"
+msgstr ""
+"It's easy to create your own collection of add-ons by filling in a few "
+"fields below."
+
+#: views/collections/add.thtml:92 views/collections/add.thtml:103
+#, fuzzy
+msgid "collections_add_submit"
+msgstr "Create Collection"
+
+#: views/pages/collector_faq.thtml:50 views/pages/collector_firstrun.thtml:43
+#: views/pages/collector.thtml:47 views/pages/collector_features.thtml:55
+#: controllers/search_controller.php:302
+#: controllers/collections_controller.php:206
+#: controllers/collections_controller.php:405
+#: controllers/collections_controller.php:467
+#: controllers/collections_controller.php:539
+#, fuzzy
+msgid "collections_breadcrumb"
+msgstr "Collections"
+
+#: views/collections/detail.thtml:185
+#, fuzzy
+msgid "collections_detail_a_learn"
+msgstr "Learn More"
+
+#: views/elements/amo2009/collection_add_form.thtml:53
+#: views/elements/amo2009/collections_js_init.thtml:68
+#: views/pages/collector_firstrun.thtml:64
+#, fuzzy
+msgid "collections_detail_button_add"
+msgstr "Add to Favorites"
+
+#: views/elements/amo2009/collection_add_form.thtml:50
+#: views/elements/amo2009/collections_js_init.thtml:71
+#, fuzzy
+msgid "collections_detail_button_remove"
+msgstr "Remove from Favorites"
+
+#. %1$s is a URL.
+#. %2$s is a full <a href>.
+#: views/collections/detail.thtml:62
+#, fuzzy
+msgid "collections_detail_created_desc"
+msgstr ""
+"<p>You can view your new collection below. If you'd like to set a collection "
+"nickname, upload an icon, or change additional settings, please visit the <a "
+"href='%1$s'>Manage Collections</a> page.</p><p>Your collection can be "
+"accessed at this location: %2$s</p>"
+
+#: views/collections/detail.thtml:61
+#, fuzzy
+msgid "collections_detail_created_msg"
+msgstr "Your collection is now ready!"
+
+#: views/collections/detail.thtml:109
+#, fuzzy
+msgid "collections_detail_header_about"
+msgstr "About This Collection"
+
+#. %1$s is a number.
+#: views/collections/detail.thtml:126
+#, fuzzy
+msgid "collections_detail_header_count"
+msgid_plural "collections_detail_header_count"
+msgstr[0] "%1$s Add-on in this Collection"
+msgstr[1] "%1$s Add-ons in this Collection"
+
+#: views/collections/detail.thtml:113
+#, fuzzy
+msgid "collections_detail_info_created"
+msgstr "<strong>Created by:</strong> %1$s"
+
+#: views/collections/detail.thtml:117
+#, fuzzy
+msgid "collections_detail_info_updated"
+msgstr "<strong>Updated:</strong>"
+
+#: views/elements/amo2009/collections_js_init.thtml:62
+#, fuzzy
+msgid "collections_detail_js_adding"
+msgstr "Adding to Favorites&hellip;"
+
+#: views/elements/amo2009/collections_js_init.thtml:65
+#, fuzzy
+msgid "collections_detail_js_removing"
+msgstr "Removing Favorite&hellip;"
+
+#. %1$s is a URL
+#: views/collections/detail.thtml:90
+#, fuzzy
+msgid "collections_detail_login"
+msgstr "<a href=\"%1$s\">Log in</a> to add this collection to your favorites."
+
+#: views/collections/detail.thtml:104
+#, fuzzy
+msgid "collections_detail_manage"
+msgstr "Manage Collection"
+
+#: controllers/collections_controller.php:298
+#, fuzzy
+msgid "collections_detail_sort_date"
+msgstr "Date Added"
+
+#: controllers/collections_controller.php:299
+#, fuzzy
+msgid "collections_detail_sort_name"
+msgstr "Name"
+
+#: controllers/collections_controller.php:300
+#, fuzzy
+msgid "collections_detail_sort_popularity"
+msgstr "Popularity"
+
+#. %1$s is a number.
+#: views/collections/detail.thtml:166
+#, fuzzy
+msgid "collections_detail_weekly_downloads"
+msgid_plural "collections_detail_weekly_downloads"
+msgstr[0] "%1$s download this week"
+msgstr[1] "%1$s downloads this week"
+
+#: views/collections/edit.thtml:255
+#, fuzzy
+msgid "collections_edit_addons_delete_noscript"
+msgstr "Selected add-ons will be removed upon Save"
+
+#: views/collections/edit.thtml:247
+#, fuzzy
+msgid "collections_edit_addons_description"
+msgstr ""
+"To publish new add-ons to this collection, start typing their names below."
+
+#: views/collections/edit.thtml:248
+#, fuzzy
+msgid "collections_edit_addons_description_noscript"
+msgstr ""
+"To publish new add-ons to this collection, enter a comma-separated list of "
+"Add-on IDs below."
+
+#: views/collections/edit.thtml:247 views/collections/edit.thtml:248
+#, fuzzy
+msgid "collections_edit_addons_description_publish_detailspage"
+msgstr "You can also publish an add-on from its normal listing page."
+
+#. %1$s is the date the add-on was added to the collection
+#. %1$s is the name of the user who added the add-on to the collection
+#: views/collections/edit.thtml:260
+#, fuzzy
+msgid "collections_edit_addons_listitem_added"
+msgstr "Added %1$s by %2$s"
+
+#: views/collections/edit.thtml:263
+#, fuzzy
+msgid "collections_edit_addons_listitem_comment_add"
+msgstr "Add publisher comment"
+
+#: views/collections/edit.thtml:266
+#, fuzzy
+msgid "collections_edit_addons_listitem_comment_delete"
+msgstr "Delete publisher comment"
+
+#: views/collections/edit.thtml:265
+#, fuzzy
+msgid "collections_edit_addons_listitem_comment_edit"
+msgstr "Edit publisher comment"
+
+#: views/collections/edit.thtml:271
+#, fuzzy
+msgid "collections_edit_addons_listitem_comment_note"
+msgstr ""
+"Note: Comment will appear as though written by original publisher on the "
+"original publication date"
+
+#: views/collections/edit.thtml:270
+#, fuzzy
+msgid "collections_edit_addons_listitem_comment_submit"
+msgstr "Save Comment"
+
+#: views/collections/edit.thtml:261
+#, fuzzy
+msgid "collections_edit_addons_listitem_remove"
+msgstr "Remove"
+
+#: views/collections/edit.thtml:250
+#, fuzzy
+msgid "collections_edit_addons_submit"
+msgstr "Add to Collection"
+
+#: views/collections/edit.thtml:153
+#, fuzzy
+msgid "collections_edit_check_nickname"
+msgstr "Check Availability"
+
+#: views/collections/edit.thtml:299
+#, fuzzy
+msgid "collections_edit_confirm_deletecollection"
+msgstr "Yes, I would like to delete this collection."
+
+#. %1$s is the label of the edit form's submit button
+#: views/collections/edit.thtml:300
+#, fuzzy
+msgid "collections_edit_confirm_deletecollection_description"
+msgstr "Check the box, then click on \"%1$s\" to delete this collection."
+
+#. %1$s is the "delete" submit button text
+#. %2$s is the title of the "advanced" tab
+#: views/collections/edit.thtml:95
+#, fuzzy
+msgid "collections_edit_delete_upon_submit"
+msgstr ""
+"Upon clicking \"%1$s\" below, your collection will be deleted. If you do not "
+"want to delete your collection, uncheck the confirmation box in the \"%2$s\" "
+"tab and continue editing your collection. If you leave this page without "
+"saving, your collection will also not be deleted."
+
+#: views/collections/edit.thtml:94
+#, fuzzy
+msgid "collections_edit_delete_warning"
+msgstr "Your collection is about to be deleted!"
+
+#: views/collections/add.thtml:76 views/collections/edit.thtml:144
+#, fuzzy
+msgid "collections_edit_form_error_description"
+msgstr "You must provide a description of your collection."
+
+#: views/collections/edit.thtml:181
+#, fuzzy
+msgid "collections_edit_form_error_icon"
+msgstr "There was an error uploading your icon."
+
+#: views/collections/add.thtml:69 views/collections/edit.thtml:130
+#, fuzzy
+msgid "collections_edit_form_error_name"
+msgstr "You must give your collection a name."
+
+#: views/collections/edit.thtml:158
+#, fuzzy
+msgid "collections_edit_form_error_nickname"
+msgstr "If you choose a nickname, it must be unique."
+
+#: views/collections/add.thtml:93 views/collections/edit.thtml:249
+#, fuzzy
+msgid "collections_edit_formfield_addons"
+msgstr "Add-on name:"
+
+#: views/collections/edit.thtml:281
+#, fuzzy
+msgid "collections_edit_formfield_application"
+msgstr "Associated Application"
+
+#: views/collections/edit.thtml:282
+#, fuzzy
+msgid "collections_edit_formfield_application_description"
+msgstr "Select the application that your collection supports."
+
+#: views/collections/edit.thtml:288
+#, fuzzy
+msgid "collections_edit_formfield_collectiontype"
+msgstr "Collection Type"
+
+#: views/collections/edit.thtml:295
+#, fuzzy
+msgid "collections_edit_formfield_deletecollection"
+msgstr "Delete Collection"
+
+#: views/collections/edit.thtml:296
+#, fuzzy
+msgid "collections_edit_formfield_deletecollection_description"
+msgstr "Deleting your collection will permanently erase it."
+
+#: views/collections/add.thtml:73 views/collections/edit.thtml:140
+#, fuzzy
+msgid "collections_edit_formfield_description"
+msgstr "Collection Description"
+
+#: views/collections/add.thtml:74 views/collections/edit.thtml:141
+#, fuzzy
+msgid "collections_edit_formfield_description_description"
+msgstr "Briefly describe your collection and the kind of add-ons in it"
+
+#: views/collections/edit.thtml:162
+#, fuzzy
+msgid "collections_edit_formfield_icon"
+msgstr "Icon"
+
+#: views/collections/edit.thtml:163
+#, fuzzy
+msgid "collections_edit_formfield_icon_description"
+msgstr ""
+"You can upload a JPG, GIF or PNG icon that will be resized to 32x32 pixels."
+
+#: views/collections/add.thtml:80 views/collections/edit.thtml:189
+#, fuzzy
+msgid "collections_edit_formfield_listed"
+msgstr "Who can view your collection?"
+
+#: views/collections/add.thtml:81 views/collections/edit.thtml:190
+#, fuzzy
+msgid "collections_edit_formfield_listed_description"
+msgstr ""
+"By default, collections appear in the public Collection Directory and are "
+"discoverable by anyone. If you want to restrict your collection to be "
+"viewable only by people who are given a special link, choose that option "
+"below."
+
+#: views/collections/add.thtml:84 views/collections/edit.thtml:193
+#, fuzzy
+msgid "collections_edit_formfield_listed_false"
+msgstr "Only people I invite can view my collection"
+
+#: views/collections/add.thtml:83 views/collections/edit.thtml:192
+#, fuzzy
+msgid "collections_edit_formfield_listed_true"
+msgstr "Everyone can view my collection in the directory"
+
+#: views/collections/edit.thtml:223
+#, fuzzy
+msgid "collections_edit_formfield_managers"
+msgstr "Who can manage my collection?"
+
+#: views/collections/edit.thtml:224
+#, fuzzy
+msgid "collections_edit_formfield_managers_description"
+msgstr ""
+"These users can publish add-ons to your collection, manage all add-ons and "
+"settings, and grant other users permission."
+
+#: views/collections/add.thtml:66 views/collections/edit.thtml:126
+#, fuzzy
+msgid "collections_edit_formfield_name"
+msgstr "Collection Name"
+
+#: views/collections/add.thtml:67 views/collections/edit.thtml:127
+#, fuzzy
+msgid "collections_edit_formfield_name_description"
+msgstr ""
+"Give your collection a descriptive name, such as \"Dave's Favorite Travel "
+"Add-ons\""
+
+#: views/collections/edit.thtml:148
+#, fuzzy
+msgid "collections_edit_formfield_nickname"
+msgstr "Collection Nickname"
+
+#: views/collections/edit.thtml:149
+#, fuzzy
+msgid "collections_edit_formfield_nickname_description"
+msgstr "Optionally, give your collection a unique nickname for quick access:"
+
+#: views/collections/edit.thtml:201
+#, fuzzy
+msgid "collections_edit_formfield_publishers"
+msgstr "Who can publish add-ons to your collection?"
+
+#: views/collections/edit.thtml:202
+#, fuzzy
+msgid "collections_edit_formfield_publishers_description"
+msgstr ""
+"These users can publish add-ons to your collection and remove add-ons that "
+"they publish."
+
+#: views/collections/edit.thtml:210 views/collections/edit.thtml:232
+#, fuzzy
+msgid "collections_edit_formfield_users_add"
+msgstr "Enter the e-mail address of a Firefox Add-ons account:"
+
+#: views/collections/edit.thtml:216 views/collections/edit.thtml:238
+#, fuzzy
+msgid "collections_edit_formfield_users_delete_noscript"
+msgstr "Selected accounts will be removed upon Save"
+
+#: views/collections/edit.thtml:215 views/collections/edit.thtml:237
+#, fuzzy
+msgid "collections_edit_formfield_users_new_noscript"
+msgstr ""
+"Enter a comma-separated list of e-mail addresses of Firefox Add-ons accounts"
+
+#: views/collections/edit.thtml:204 views/collections/edit.thtml:226
+#, fuzzy
+msgid "collections_edit_formfield_users_onlyme"
+msgstr "Only me"
+
+#: views/collections/edit.thtml:205 views/collections/edit.thtml:227
+#, fuzzy
+msgid "collections_edit_formfield_users_otherusers"
+msgstr "Myself and these users:"
+
+#: views/collections/edit.thtml:211 views/collections/edit.thtml:233
+#, fuzzy
+msgid "collections_edit_formfield_users_submit"
+msgstr "Add"
+
+#. %1$s is the name of the collection
+#: views/collections/edit.thtml:68
+#, fuzzy
+msgid "collections_edit_header"
+msgstr "Manage %1$s"
+
+#: views/collections/edit.thtml:246
+#, fuzzy
+msgid "collections_edit_header_addons"
+msgstr "Manage Collection Contents"
+
+#: views/collections/edit.thtml:253 views/collections/edit.thtml:258
+#, fuzzy
+msgid "collections_edit_header_addons_current"
+msgstr "Current Add-ons:"
+
+#: views/collections/edit.thtml:279
+#, fuzzy
+msgid "collections_edit_header_advanced"
+msgstr "Advanced Settings"
+
+#: views/collections/edit.thtml:186
+#, fuzzy
+msgid "collections_edit_header_permissions"
+msgstr "Manage Collection Permissions"
+
+#: views/collections/edit.thtml:170
+#, fuzzy
+msgid "collections_edit_icon_cancel"
+msgstr "Cancel"
+
+#: views/collections/edit.thtml:174 views/collections/edit.thtml:179
+#, fuzzy
+msgid "collections_edit_icon_delete"
+msgstr "Delete Icon"
+
+#: views/collections/edit.thtml:178
+#, fuzzy
+msgid "collections_edit_icon_replace"
+msgstr "Replace Icon"
+
+#. %1$s is the label of the edit form's submit button
+#: views/collections/edit.thtml:169
+#, fuzzy
+msgid "collections_edit_icon_toberemoved"
+msgstr "Icon will be removed when \"%1$s\" is clicked below"
+
+#: views/collections/edit.thtml:155
+#, fuzzy
+msgid "collections_edit_nickname_available"
+msgstr "Nickname Available"
+
+#: controllers/collections_controller.php:943
+#, fuzzy
+msgid "collections_edit_nickname_error"
+msgstr ""
+"Your nickname contained invalid characters and was corrected. Please try "
+"again."
+
+#: views/collections/edit.thtml:156
+#, fuzzy
+msgid "collections_edit_nickname_taken"
+msgstr "Nickname Taken"
+
+#. This string is followed by a URL pointing to the collection's view page
+#: views/collections/edit.thtml:75
+#, fuzzy
+msgid "collections_edit_saved_nextstep"
+msgstr "Your collection can be accessed at this location:"
+
+#: views/collections/edit.thtml:74
+#, fuzzy
+msgid "collections_edit_saved_success"
+msgstr "Your collection was successfully saved!"
+
+#: views/collections/edit.thtml:169 views/collections/edit.thtml:300
+#: views/collections/edit.thtml:308 views/pages/js_constants.js.thtml:99
+#, fuzzy
+msgid "collections_edit_submit"
+msgstr "Update Collection"
+
+#: views/collections/edit.thtml:96 views/collections/edit.thtml:297
+#: views/pages/js_constants.js.thtml:100
+#, fuzzy
+msgid "collections_edit_submit_deletecollection"
+msgstr "Delete Collection"
+
+#: views/collections/edit.thtml:111
+#, fuzzy
+msgid "collections_edit_tabheader_addons"
+msgstr "Add-ons"
+
+#: views/collections/edit.thtml:97 views/collections/edit.thtml:113
+#, fuzzy
+msgid "collections_edit_tabheader_advanced"
+msgstr "Advanced"
+
+#: views/collections/edit.thtml:108
+#, fuzzy
+msgid "collections_edit_tabheader_details"
+msgstr "Name &amp; Details"
+
+#: views/collections/edit.thtml:109
+#, fuzzy
+msgid "collections_edit_tabheader_permissions"
+msgstr "Permissions"
+
+#: models/collection_promo.php:53
+#, fuzzy
+msgid "collections_family_tagline"
+msgstr "Add-ons can keep an eye on your kids and your calendar."
+
+#: models/collection_promo.php:53
+#, fuzzy
+msgid "collections_family_title"
+msgstr "Family Organizer"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:70
+#, fuzzy
+msgid "collections_index_a_check_out"
+msgstr "Check out Add-on Collector"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:52
+#, fuzzy
+msgid "collections_index_a_create"
+msgstr "Create a Collection"
+
+#: views/collections/detail.thtml:139 views/collections/listing.thtml:85
+#: views/search/collections.thtml:84
+#, fuzzy
+msgid "collections_index_button_go"
+msgstr "Go"
+
+#. %1$s is a URL.
+#: controllers/collections_controller.php:182
+#, fuzzy
+msgid "collections_index_filler_favorites"
+msgstr ""
+"<p><strong>You don't have any favorite collections yet.</strong></p> "
+"<p>Collections you mark as favorites can be quickly accessed from this page, "
+"and will appear in the <a href='%1$s'>Add-on Collector</a> if you've "
+"installed it.</p>"
+
+#. %1$s is a URL.
+#: controllers/collections_controller.php:167
+#, fuzzy
+msgid "collections_index_filler_mine"
+msgstr ""
+"<p>You haven't created any collections yet. Collections are easy to create "
+"and fill with your favorite add-ons. <a href='%1$s'>Try it out</a>!</p>"
+
+#: views/collections/listing.thtml:51
+#, fuzzy
+msgid "collections_index_header_collections"
+msgstr "Collections"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:60
+#, fuzzy
+msgid "collections_index_header_collector"
+msgstr "Add-on Collector"
+
+#. %1$s is a comma-separated list of author names
+#: views/elements/amo2009/collection_listing_item.thtml:84
+#: views/collections/detail.thtml:151
+#, fuzzy
+msgid "collections_index_header_created"
+msgstr "created by %1$s"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:47
+#, fuzzy
+msgid "collections_index_header_what"
+msgstr "What are Collections?"
+
+#: views/collections/detail.thtml:132 views/collections/listing.thtml:78
+#: views/search/collections.thtml:66
+#, fuzzy
+msgid "collections_index_label_sortby"
+msgstr "Sort by"
+
+#: controllers/collections_controller.php:130
+#, fuzzy
+msgid "collections_index_li_editors"
+msgstr "Editor's Picks"
+
+#: views/collections/subscribe.thtml:64
+#: controllers/collections_controller.php:140
+#, fuzzy
+msgid "collections_index_li_favorites"
+msgstr "My Favorites"
+
+#: controllers/collections_controller.php:138
+#, fuzzy
+msgid "collections_index_li_mine"
+msgstr "My Collections"
+
+#: controllers/collections_controller.php:132
+#, fuzzy
+msgid "collections_index_li_popular"
+msgstr "Popular"
+
+#: views/search/collections.thtml:74 controllers/collections_controller.php:81
+#, fuzzy
+msgid "collections_index_option_all"
+msgstr "Most popular all time"
+
+#: views/search/collections.thtml:72 controllers/collections_controller.php:78
+#, fuzzy
+msgid "collections_index_option_month"
+msgstr "Most popular this month"
+
+#: views/search/collections.thtml:76 controllers/collections_controller.php:84
+#, fuzzy
+msgid "collections_index_option_newest"
+msgstr "Newest"
+
+#: views/search/collections.thtml:70 controllers/collections_controller.php:75
+#, fuzzy
+msgid "collections_index_option_week"
+msgstr "Most popular this week"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:67
+#, fuzzy
+msgid "collections_index_p_collector"
+msgstr ""
+"There's a new way to manage and find favorite add-ons. Comment, share and "
+"sync collections, all from your browser"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:48
+#, fuzzy
+msgid "collections_index_p_what_are"
+msgstr "Collections are groups of related add-ons assembled for easy sharing."
+
+#. %s is a date in the _('date') format
+#: views/elements/collections_interactive_addon.thtml:85
+#, fuzzy, php-format
+msgid "collections_interactive_addon_added"
+msgstr "Added %s"
+
+#: models/collection_promo.php:55
+#, fuzzy
+msgid "collections_reference_tagline"
+msgstr "Add-ons can do better research online."
+
+#: models/collection_promo.php:55
+#, fuzzy
+msgid "collections_reference_title"
+msgstr "Reference Desk"
+
+#: models/collection_promo.php:52
+#, fuzzy
+msgid "collections_social_tagline"
+msgstr "Add-ons can manage your social network."
+
+#: models/collection_promo.php:52
+#, fuzzy
+msgid "collections_social_title"
+msgstr "Social Circuit"
+
+#: views/collections/subscribe.thtml:91
+#, fuzzy
+msgid "collections_subscribe_button_close"
+msgstr "Close"
+
+#: views/collections/subscribe.thtml:70
+#, fuzzy
+msgid "collections_subscribe_error"
+msgstr ""
+"An error occurred trying to add a favorite collection. Is this collection "
+"already a favorite?"
+
+#: views/collections/subscribe.thtml:96
+#, fuzzy
+msgid "collections_subscribe_label_bothersome"
+msgstr "Don't show me this message again."
+
+#. %1$s is the collection name
+#: views/collections/subscribe.thtml:60
+#, fuzzy
+msgid "collections_subscribe_success"
+msgstr "%1$s has been added to your favorite collections."
+
+#. %1$s is the link to the "My Favorites" tab on the main collections page
+#. %2$s is the localized title of the "My Favorites" tab
+#. %3$s is the link URL to the collector add-on
+#: views/collections/subscribe.thtml:62
+#, fuzzy
+msgid "collections_subscribe_success_desc"
+msgstr ""
+"You can now quickly find this collection from the <a href=\"%1$s\">%2$s</a> "
+"tab in the directory. For an even easier way to keep track of your favorite "
+"collections, try out our <a href=\"%3$s\">Add-on Collector</a> extension for "
+"Firefox."
+
+#: views/collections/listing.thtml:55
+#, fuzzy
+msgid "collections_success_delete"
+msgstr "The collection has been deleted."
+
+#: models/collection_promo.php:54
+#, fuzzy
+msgid "collections_travel_tagline"
+msgstr "Add-ons can turn you into a travel agent."
+
+#: models/collection_promo.php:54
+#, fuzzy
+msgid "collections_travel_title"
+msgstr "The Traveler's Pack"
+
+#. A collection of add-ons that is automatically built for a user. They are "automatically published" to this collection.
+#: controllers/collections_controller.php:581
+#, fuzzy
+msgid "collections_type_autopublisher"
+msgstr "Auto-publisher"
+
+#. A collection that has been chosen by an Editor as notable or exceptional
+#: controllers/collections_controller.php:582
+#, fuzzy
+msgid "collections_type_editorspick"
+msgstr "Editor's Pick"
+
+#: controllers/collections_controller.php:580
+#, fuzzy
+msgid "collections_type_normal"
+msgstr "Normal"
+
+#: views/collections/subscribe.thtml:84
+#, fuzzy
+msgid "collections_unsubscribe_error"
+msgstr ""
+"An error occurred trying to remove a favorite collection. Was this "
+"collection not a favorite?"
+
+#. %1$s is the collection name
+#: views/collections/subscribe.thtml:78
+#, fuzzy
+msgid "collections_unsubscribe_success"
+msgstr "%1$s has been removed from your favorite collections."
+
+#: models/collection_promo.php:56
+#, fuzzy
+msgid "collections_webdev_tagline"
+msgstr "Add-ons make it easier to build the perfect website."
+
+#: models/collection_promo.php:56
+#, fuzzy
+msgid "collections_webdev_title"
+msgstr "Web Developer's Toolbox"
+
+#: views/elements/amo2009/collections_sidebar_whatare.thtml:40
+#, fuzzy
+msgid "collections_whatare_header"
+msgstr "What are Collections?"
+
+#: views/elements/amo2009/collections_sidebar_whatare.thtml:45
+#, fuzzy
+msgid "collections_whatare_learnmore"
+msgstr "Read the FAQ"
+
+#: views/elements/amo2009/collections_sidebar_whatare.thtml:44
+#, fuzzy
+msgid "collections_whatare_text"
+msgstr ""
+"There’s a new way to manage and find favorite add-ons. Comment, share and "
+"sync collections, all from your browser."
+
+#: views/pages/collector_faq.thtml:61 views/pages/collector_features.thtml:67
+#, fuzzy
+msgid "collector_features_a_home"
+msgstr "Add-on Collector Home"
+
+#: views/elements/amo2009/collector_sidebar_download.thtml:46
+#, fuzzy
+msgid "collector_features_heading_download"
+msgstr "Download the Add-on Collector:"
+
+#: views/elements/amo2009/collector_sidebar_download.thtml:43
+#: views/pages/collector_firstrun.thtml:116 views/pages/collector.thtml:69
+#, fuzzy
+msgid "collector_features_img_logo"
+msgstr "Add-on Collector Logo"
+
+#: views/compatibility/dashboard.thtml:49
+#: controllers/compatibility_controller.php:72
+#, fuzzy
+msgid "compatibility_dashboard_center_header"
+msgstr "Add-on Compatibility Center"
+
+#. %1$s is the name of an application and a version. Example: Firefox 3.0
+#. %2$s is the name of an application. Example: Firefox
+#: views/compatibility/dashboard.thtml:50
+#, fuzzy
+msgid "compatibility_dashboard_intro"
+msgstr ""
+"Be prepared for the release of %1$s with the tools and information available "
+"for the %2$s Add-ons community found below."
+
+#: views/compatibility/dashboard.thtml:103
+#, fuzzy
+msgid "compatibility_dashboard_loading"
+msgstr "Loading data..."
+
+#: views/compatibility/dashboard.thtml:45
+#, fuzzy
+msgid "compatibility_dashboard_main_link"
+msgstr "Back to Main"
+
+#: views/compatibility/dashboard.thtml:100 views/compatibility/report.thtml:43
+#, fuzzy
+msgid "compatibility_dashboard_report"
+msgstr "Add-on Compatibility Report"
+
+#: views/compatibility/dashboard.thtml:53
+#: views/compatibility/dashboard.thtml:110
+#: views/compatibility/developers.thtml:43
+#, fuzzy
+msgid "compatibility_developer_info"
+msgstr "Information for Add-on Developers"
+
+#: views/compatibility/developers.thtml:66
+#, fuzzy
+msgid "compatibility_developers_adjust_maxversion"
+msgstr "Adjust maxVersion without uploading"
+
+#: views/compatibility/dashboard.thtml:124
+#, fuzzy
+msgid "compatibility_developers_check_status"
+msgstr "Check Status of My Add-ons"
+
+#. %1$s is a URL
+#. %2$s is an application and version. Example: Firefox 3.0
+#: views/compatibility/dashboard.thtml:126
+#, fuzzy
+msgid "compatibility_developers_login_first"
+msgstr ""
+"If you have add-ons hosted on Mozilla Add-ons, <a href=\"%1$s\">please "
+"login</a> to analyze the status of your add-ons for %2$s."
+
+#: views/compatibility/dashboard.thtml:114
+#, fuzzy
+msgid "compatibility_developers_mdclogo_alt"
+msgstr "Mozilla Developer Center Logo"
+
+#: views/compatibility/developers.thtml:73
+#, fuzzy
+msgid "compatibility_developers_no_addons"
+msgstr "You do not have any add-ons hosted on Mozilla Add-ons."
+
+#: views/compatibility/dashboard.thtml:133
+#: views/compatibility/developers.thtml:55
+#, fuzzy
+msgid "compatibility_developers_results"
+msgstr "Add-on Status Check Results"
+
+#: views/compatibility/dashboard.thtml:137
+#, fuzzy
+msgid "compatibility_developers_retrieving"
+msgstr "Retrieving status of hosted add-ons..."
+
+#. %1$s is a number
+#. %2$s is an application name
+#. %3$s is a number.
+#. Full example: 50 Firefox users (10% of total)
+#: views/compatibility/developers.thtml:65
+#, fuzzy
+msgid "compatibility_developers_user_count"
+msgstr "%1$s %2$s users (%3$s&#37; of total)"
+
+#: views/compatibility/report.thtml:45
+#, fuzzy
+msgid "compatibility_report_detail_intro"
+msgstr ""
+"The add-ons below make up 95% of add-on usage known to Mozilla and are "
+"ordered by their usage size."
+
+#: views/compatibility/dashboard.thtml:94
+#, fuzzy
+msgid "compatibility_report_detailed_link"
+msgstr "View Detailed Report"
+
+#. %1$s and %2$s are numbers
+#. %3$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:65
+#, fuzzy
+msgid "compatibility_report_intro"
+msgstr ""
+"Of the %1$s add-ons that make up 95&#37; of add-on usage known to Mozilla, "
+"<b>%2$s&#37;</b> are currently considered compatible with the latest builds "
+"of %3$s."
+
+#: views/compatibility/dashboard.thtml:81
+#, fuzzy
+msgid "compatibility_report_legend_alpha"
+msgstr "Alpha Versions"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:81
+#, fuzzy
+msgid "compatibility_report_legend_alpha_description"
+msgstr "Add-ons compatible with an alpha version of %1$s"
+
+#: views/compatibility/dashboard.thtml:85
+#, fuzzy
+msgid "compatibility_report_legend_beta"
+msgstr "Beta Versions"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:85
+#, fuzzy
+msgid "compatibility_report_legend_beta_description"
+msgstr "Add-ons compatible with a beta version or release candidate of %1$s"
+
+#: views/compatibility/dashboard.thtml:89
+#, fuzzy
+msgid "compatibility_report_legend_latest"
+msgstr "Latest Version"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:89
+#, fuzzy
+msgid "compatibility_report_legend_latest_description"
+msgstr "Add-ons up-to-date with the latest builds of %1$s"
+
+#: views/compatibility/dashboard.thtml:77
+#, fuzzy
+msgid "compatibility_report_legend_other"
+msgstr "Other Versions"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:77
+#, fuzzy
+msgid "compatibility_report_legend_other_description"
+msgstr "Add-ons not compatible with any version of %1$s"
+
+#: views/compatibility/dashboard.thtml:62
+#, fuzzy
+msgid "compatibility_report_title"
+msgstr "Add-on Compatibility Report"
+
+#: views/compatibility/dashboard.thtml:54
+#: views/compatibility/dashboard.thtml:144 views/compatibility/users.thtml:42
+#, fuzzy
+msgid "compatibility_user_info"
+msgstr "Information for Add-on Users"
+
+#: views/compatibility/dashboard.thtml:52
+#, fuzzy
+msgid "compatibility_view_report"
+msgstr "View Compatibility Report"
+
+#. %s is a URL
+#: views/pages/credits.thtml:142
+#, php-format
+msgid "credits_contributing"
+msgstr "Хамтрах талаарх мÑдÑÑллийг %s хуудаÑÐ½Ð°Ð°Ñ Ñ…Ð°Ñ€Ð½Ð° уу."
+
+#: views/pages/credits.thtml:142
+msgid "credits_contributing_wikipage"
+msgstr "wiki хуудаÑ"
+
+#: views/pages/credits.thtml:99
+msgid "credits_intro"
+msgstr ""
+"Mozilla addons.mozilla.org Ñ‚Ó©Ñөлд олон жил хаматрч туÑалÑан хүмүүÑд гүн "
+"талархлаа илÑрхийлж байна:"
+
+#: views/pages/credits.thtml:103
+msgid "credits_section_developers"
+msgstr "ХөгжүүлÑгчид"
+
+#: views/pages/credits.thtml:115
+msgid "credits_section_editors"
+msgstr "ЗаÑварлагчид"
+
+#: views/pages/credits.thtml:109
+msgid "credits_section_localizers"
+msgstr "Орчуулагчид"
+
+#: views/pages/credits.thtml:121
+msgid "credits_section_other_contributors"
+msgstr "БуÑад хамтран туÑлагчид"
+
+#: views/pages/credits.thtml:127
+msgid "credits_section_past_developers"
+msgstr "Хуучин хөгжүүлÑгчид"
+
+#: views/pages/credits.thtml:133
+msgid "credits_section_software"
+msgstr "Програм болон зурагнууд"
+
+#: views/pages/credits.thtml:136
+msgid "credits_software_famfamfam"
+msgstr ""
+"<a href=\"http://www.famfamfam.com/lab/icons/silk/\">famfamfam Silk Icon "
+"Set</a> хаÑÐ³Ð½Ð°Ð°Ñ Ñ…ÑÑ€ÑглÑгдÑÑн зарим зурагнууд <a href=\"http://"
+"creativecommons.org/licenses/by/2.5/\">Creative Commons Attribution 2.5 "
+"гÑÑÑн зохиогчийн Ñрх дор ашиглагдав</a>."
+
+#: views/pages/credits.thtml:137
+#, fuzzy
+msgid "credits_software_timeplot"
+msgstr ""
+"Some pages use elements of <a href=\"http://www.simile-widgets.org/timeplot/"
+"\">Timeplot</a>, licensed under a <a href=\"http://simile.mit.edu/license."
+"html\">BSD License</a>."
+
+#. date format string as used in PHP's strftime():
+#. http://php.net/strftime
+#: views/elements/collections_interactive_addon.thtml:85
+#: views/elements/amo2009/addon_version_detail.thtml:53
+#: views/elements/amo2009/homepage_addon.thtml:115
+#: views/elements/addon_version_detail.thtml:54
+#: views/elements/addon_listitem.thtml:124 views/elements/feature.thtml:106
+#: views/collections/detail.thtml:118 views/collections/edit.thtml:325
+#: views/users/info.thtml:76 views/editors/reviews_queue.thtml:57
+#: views/editors/reviews_queue.thtml:68 views/developers/dashboard.thtml:65
+#: views/developers/versions_edit.thtml:208 views/developers/versions.thtml:67
+#: views/search/rss/index.thtml:5 views/addons/rss/versions.thtml:42
+#: views/addons/display.thtml:104 views/addons/display.thtml:356
+#: views/addons/browse_thumbs.thtml:75 views/reviews/add.thtml:63
+#: views/reviews/display.thtml:74 views/reviews/display.thtml:160
+#: views/reviews/delete.thtml:54 controllers/statistics_controller.php:244
+#: controllers/collections_controller.php:1047
+msgid "date"
+msgstr "%Y оны %B %e "
+
+#. date and time format string (strftime)
+#. http://php.net/strftime
+#: views/elements/addon_version_detail.thtml:53
+#: views/developers/discuss.thtml:52 views/developers/discuss.thtml:62
+#: views/admin/addons_status.thtml:57
+msgid "datetime"
+msgstr "%Y оны %B %e, %I:%M %p"
+
+#: views/elements/developers/actionbar.thtml:47
+msgid "devcp_actionbar_link_details"
+msgstr "ДÑлгÑÑ€Ñнгүй мÑдÑÑлÑл"
+
+#: views/elements/developers/actionbar.thtml:42
+#: views/elements/developers/actionbar.thtml:50
+#: views/developers/dashboard.thtml:64
+msgid "devcp_actionbar_link_edit"
+msgstr "ÐÑмÑгдлийг заÑварла"
+
+#: views/elements/developers/actionbar.thtml:51
+msgid "devcp_actionbar_link_newversion"
+msgstr "Ð¨Ð¸Ð½Ñ Ñ…ÑƒÐ²Ð¸Ð»Ð±Ð°Ñ€Ñ‹Ð³ нийлүүлÑÑ…"
+
+#: views/elements/developers/actionbar.thtml:44
+#: views/elements/developers/actionbar.thtml:49
+#: views/developers/dashboard.thtml:73
+msgid "devcp_actionbar_link_stats"
+msgstr "Судалгааны Ñамбар"
+
+#. %1$s is a filename, e.g. "foo.txt"
+#. %2$s is the extension, e.g. ".txt"
+#. %3$s is a list of valid extensions, like ".png, .jpg, .gif"
+#: controllers/developers_controller.php:1361
+#, fuzzy
+msgid "devcp_add_previews_extension_error"
+msgstr "File %1$s has an invalid extension (%2$s). Allowed extensions: %3$s"
+
+#. %s is the filename.
+#: controllers/developers_controller.php:1394
+#, fuzzy
+msgid "devcp_add_previews_save_error"
+msgstr "File %s could not be saved to the database. Please try again."
+
+#. %1$s is the preview ID number, %2$s is the filename.
+#: controllers/developers_controller.php:1389
+#, fuzzy
+msgid "devcp_add_previews_success_replace"
+msgstr "Preview %1$s was replaced with file %2$s successfully."
+
+#. %s is the filename.
+#: controllers/developers_controller.php:1391
+#, fuzzy
+msgid "devcp_add_previews_success_upload"
+msgstr "File %s was uploaded successfully. You can add a caption below."
+
+#: controllers/components/developers.php:1163
+msgid "devcp_additem_addontype_autodetect"
+msgstr "(автоматаар тань)"
+
+#: views/elements/developers/additem.thtml:76
+msgid "devcp_additem_linktitle_opensin_newwindow"
+msgstr "Ð¨Ð¸Ð½Ñ Ñ†Ð¾Ð½Ñ…Ð¾Ð½Ð´ нÑÑгдÑнÑ"
+
+#: views/elements/developers/additem.thtml:41
+msgid "devcp_additem_sidebar_title"
+msgstr "ÐÑмÑгдÑл илгÑÑÑ…"
+
+#: views/elements/developers/additem.thtml:53
+msgid "devcp_additem_step0_newlink"
+msgstr "ХөгжүүлÑгчийн зөвшилцөө"
+
+#: views/elements/developers/additem.thtml:46
+msgid "devcp_additem_step1_link"
+msgstr "1-Ñ€ алхам: ДÑÑш хуулах"
+
+#: views/elements/developers/additem.thtml:47
+msgid "devcp_additem_step2_link"
+msgstr "2-Ñ€ алхам: ÐÑмÑгдлийн нарийн мÑдÑÑлÑл"
+
+#: views/elements/developers/additem.thtml:48
+msgid "devcp_additem_step3_link"
+msgstr "3-Ñ€ алхам: Хувилбарын нарийн мÑдÑÑлÑл"
+
+#: views/elements/developers/additem.thtml:49
+msgid "devcp_additem_step4_link"
+msgstr "4-Ñ€ алхам: Ðутагшуулах"
+
+#: views/elements/developers/additem.thtml:50
+msgid "devcp_additem_step5_link"
+msgstr "5-Ñ€ алхам: Ðмжилттай дууÑлаа"
+
+#: views/elements/developers/additem.thtml:76
+msgid "devcp_additem_submissionhelp_link"
+msgstr "ИлгÑÑÑ… туÑламж"
+
+#: controllers/previews_controller.php:168
+#: controllers/previews_controller.php:277
+msgid "devcp_addon_field_preview_caption_displaytitle"
+msgstr "ҮзүүлбÑрийн гарчиг"
+
+#: views/developers/addon_status.thtml:177
+#, fuzzy
+msgid "devcp_addon_status_action_activate"
+msgstr "Make Active"
+
+#: views/developers/addon_status.thtml:178
+#, fuzzy
+msgid "devcp_addon_status_action_activate_description"
+msgstr ""
+"Make your add-on active for it to show up in public listings and enable the "
+"update check service."
+
+#: views/developers/addon_status.thtml:135
+#, fuzzy
+msgid "devcp_addon_status_action_complete"
+msgstr "Complete Add-on"
+
+#: views/developers/addon_status.thtml:136
+#, fuzzy
+msgid "devcp_addon_status_action_complete_description"
+msgstr "Complete your add-on and move to the Sandbox"
+
+#: views/developers/addon_status.thtml:181
+#, fuzzy
+msgid "devcp_addon_status_action_deactivate"
+msgstr "Make Inactive"
+
+#: views/developers/addon_status.thtml:182
+#, fuzzy
+msgid "devcp_addon_status_action_deactivate_description"
+msgstr ""
+"Make your add-on inactive to hide it from all public listings and disable "
+"the update check service."
+
+#: views/developers/addon_status.thtml:143
+#, fuzzy
+msgid "devcp_addon_status_action_move"
+msgstr "Move to Sandbox"
+
+#: views/developers/addon_status.thtml:144
+#, fuzzy
+msgid "devcp_addon_status_action_move_description"
+msgstr "Move your add-on back to the Sandbox. This is reversible."
+
+#: views/developers/addon_status.thtml:139
+#, fuzzy
+msgid "devcp_addon_status_action_nominate"
+msgstr "Nominate for Public"
+
+#: views/developers/addon_status.thtml:140
+#, fuzzy
+msgid "devcp_addon_status_action_nominate_description"
+msgstr "Nominate your add-on to become Public"
+
+#: views/developers/addon_status.thtml:147
+#, fuzzy
+msgid "devcp_addon_status_action_public"
+msgstr "Make Public"
+
+#: views/developers/addon_status.thtml:148
+#, fuzzy
+msgid "devcp_addon_status_action_public_description"
+msgstr "Make your add-on Public again."
+
+#: views/developers/addon_status.thtml:169
+#, fuzzy
+msgid "devcp_addon_status_active"
+msgstr ""
+"Your add-on is <span class=\"inactive-0\">Active</span>. This means your add-"
+"on is showing up in all available listings appropriate for its status above."
+
+#: views/developers/addon_status.thtml:111
+#, fuzzy
+msgid "devcp_addon_status_completion_disabled"
+msgstr ""
+"Please fulfill the criteria above before you can complete your add-on and "
+"move it to the <span class=\"status-1\">Sandbox</span>."
+
+#: views/developers/addon_status.thtml:108
+#, fuzzy
+msgid "devcp_addon_status_completion_enabled"
+msgstr ""
+"You may now complete your add-on and move it to the <span class=\"status-1"
+"\">Sandbox</span> by clicking the button below."
+
+#: views/developers/addon_status.thtml:102
+#, fuzzy
+msgid "devcp_addon_status_criteria_category"
+msgstr "At least one category selected"
+
+#: views/developers/addon_status.thtml:101
+#, fuzzy
+msgid "devcp_addon_status_criteria_description"
+msgstr "Add-on Description required"
+
+#: views/developers/addon_status.thtml:99
+#, fuzzy
+msgid "devcp_addon_status_criteria_name"
+msgstr "Add-on Name required"
+
+#: views/developers/addon_status.thtml:120
+#, fuzzy
+msgid "devcp_addon_status_criteria_prerelease"
+msgstr "Add-on is not marked as pre-release."
+
+#: views/developers/addon_status.thtml:119
+#, fuzzy
+msgid "devcp_addon_status_criteria_preview"
+msgstr "At least one preview image required for extensions and themes."
+
+#: views/developers/addon_status.thtml:100
+#, fuzzy
+msgid "devcp_addon_status_criteria_summary"
+msgstr "Add-on Summary required"
+
+#. %s is the status in a span, e.g. "<span>_('Public')</span>".
+#: views/developers/addon_status.thtml:58
+#, fuzzy
+msgid "devcp_addon_status_header"
+msgstr "Add-on Status: %s"
+
+#: views/developers/addon_status.thtml:152
+#: views/developers/addon_status.thtml:173
+#, fuzzy
+msgid "devcp_addon_status_header_actions"
+msgstr "Available Actions"
+
+#: views/developers/addon_status.thtml:168
+#, fuzzy
+msgid "devcp_addon_status_header_active"
+msgstr "Active Status: <span class=\"inactive-0\">Active</span>"
+
+#: views/developers/addon_status.thtml:97
+#, fuzzy
+msgid "devcp_addon_status_header_criteria"
+msgstr "Add-on Completion Criteria"
+
+#: views/developers/addon_status.thtml:164
+#, fuzzy
+msgid "devcp_addon_status_header_inactive"
+msgstr "Active Status: <span class=\"inactive-1\">Inactive</span>"
+
+#: views/developers/addon_status.thtml:117
+#, fuzzy
+msgid "devcp_addon_status_header_nomination"
+msgstr "Public Nomination Criteria"
+
+#: views/developers/addon_status.thtml:190
+#, fuzzy
+msgid "devcp_addon_status_header_trusted"
+msgstr "Trusted Status: <span class=\"status-4\">Trusted</span>"
+
+#: views/developers/addon_status.thtml:165
+#, fuzzy
+msgid "devcp_addon_status_inactive"
+msgstr ""
+"Your add-on is <span class=\"inactive-1\">Inactive</span>. This means your "
+"add-on will not show up in any listing, regardless of its status above. "
+"Updates are <b>not</b> being provided to your add-on through the update "
+"check service."
+
+#: views/developers/addon_status.thtml:128
+#, fuzzy
+msgid "devcp_addon_status_nominate_disabled"
+msgstr ""
+"Please fulfill the criteria above before nominating your add-on to become "
+"<span class=\"status-4\">Public</span>."
+
+#: views/developers/addon_status.thtml:125
+#, fuzzy
+msgid "devcp_addon_status_nominate_enabled"
+msgstr ""
+"You may now nominate your add-on for <span class=\"status-4\">Public</span> "
+"by clicking the button below."
+
+#: views/developers/addon_status.thtml:64
+#, fuzzy
+msgid "devcp_addon_status_public"
+msgstr "Public"
+
+#: views/developers/addon_status.thtml:63
+#, fuzzy
+msgid "devcp_addon_status_sandbox"
+msgstr "Sandbox"
+
+#. %s is an email address.
+#: views/developers/addon_status.thtml:89
+#, fuzzy
+msgid "devcp_addon_status_switch_disabled"
+msgstr ""
+"Your add-on was <span class=\"status-5\">Disabled</span> by an administrator "
+"and cannot be used. If you have any questions, please e-mail %s."
+
+#: views/developers/addon_status.thtml:67
+#, fuzzy
+msgid "devcp_addon_status_switch_incomplete"
+msgstr ""
+"Your add-on is currently <span class=\"status-0\">Incomplete</span>. This "
+"means your add-on is not showing up on any portion of the site or update "
+"check service. You may come to this page to complete your add-on after it "
+"meets the criteria below for completion and transfer to the <span class="
+"\"status-1\">Sandbox</span>."
+
+#. %s is a number, perhaps 42.
+#: views/developers/addon_status.thtml:77
+#, fuzzy
+msgid "devcp_addon_status_switch_nominated"
+msgstr ""
+"Your add-on is currently nominated to become <span class=\"status-4"
+"\">Public</span> and is awaiting editor review. There are currently %s other "
+"add-ons in the nomination queue."
+
+#. %s is an email address.
+#: views/developers/addon_status.thtml:81
+#, fuzzy
+msgid "devcp_addon_status_switch_pending"
+msgstr ""
+"Your add-on is pending. This shouldn't have happened. Please e-mail %s with "
+"your add-on ID and state this error."
+
+#: views/developers/addon_status.thtml:85
+#, fuzzy
+msgid "devcp_addon_status_switch_public"
+msgstr ""
+"Your add-on is <span class=\"status-4\">Public</span>, which means it will "
+"show up in all listings and searches and can be downloaded without "
+"restriction. Updates are being provided to your add-on through the update "
+"check service."
+
+#: views/developers/addon_status.thtml:71
+#: views/developers/addon_status.thtml:75
+#, fuzzy
+msgid "devcp_addon_status_switch_sandbox"
+msgstr ""
+"Your add-on is in the <span class=\"status-1\">Sandbox</span>, which means "
+"it will show up in listings and searches, but users must log in to download "
+"it. Updates are <b>not</b> being provided to your add-on through the update "
+"check service."
+
+#. %s is the add-on name.
+#: views/developers/addon_status_nominate.thtml:43
+#: views/developers/addon_status_confirm.thtml:43
+#: views/developers/addon_status.thtml:43
+#, fuzzy
+msgid "devcp_addon_status_title"
+msgstr "%s Status"
+
+#: views/developers/addon_status.thtml:191
+#, fuzzy
+msgid "devcp_addon_status_trusted"
+msgstr ""
+"Your add-on is <span class=\"status-4\">Trusted</span>. This means you can "
+"submit updates to your add-on without editor review."
+
+#: views/developers/dashboard.thtml:68
+#, fuzzy
+msgid "devcp_dashboard_active"
+msgstr "Active"
+
+#. %1$s is the add-on type string
+#. %2$s is Inactive or Active in a <span>
+#. %3$s is the addon's public status (Public, In Sandbox, ...) in a <span>
+#: views/developers/dashboard.thtml:69
+#, fuzzy
+msgid "devcp_dashboard_addontype_status"
+msgstr "%1$s currenty %2$s and %3$s"
+
+#: views/developers/dashboard.thtml:67
+#, fuzzy
+msgid "devcp_dashboard_change_status"
+msgstr "Change Status"
+
+#. %s is the addons email address.
+#: views/developers/dashboard.thtml:99
+#, fuzzy
+msgid "devcp_dashboard_disabled_questions"
+msgstr ""
+"Your add-on was disabled by an administrator and cannot be used. If you "
+"have any questions, please email %s."
+
+#. %s is the (localized) add-on status string in a span, e.g. "Disabled"
+#: views/developers/dashboard.thtml:98
+#, fuzzy
+msgid "devcp_dashboard_disabled_status"
+msgstr "Add-on Status: %s"
+
+#: views/developers/dashboard.thtml:43
+#, fuzzy
+msgid "devcp_dashboard_header_main"
+msgstr "Developer Dashboard"
+
+#: views/developers/dashboard.thtml:110
+#, fuzzy
+msgid "devcp_dashboard_header_welcome"
+msgstr "Welcome to the Developer Dashboard"
+
+#: views/developers/dashboard.thtml:68
+#, fuzzy
+msgid "devcp_dashboard_inactive"
+msgstr "Inactive"
+
+#. %s is a date in the _('date') format
+#: views/developers/dashboard.thtml:65
+#, fuzzy
+msgid "devcp_dashboard_last_edited"
+msgstr "Last edited on %s"
+
+#: views/developers/dashboard.thtml:111
+#, fuzzy
+msgid "devcp_dashboard_learn"
+msgstr ""
+"You don't currently have any add-ons hosted on Mozilla Add-ons. To learn how "
+"the process works and submit your first add-on, click Get Started below."
+
+#: views/developers/dashboard.thtml:112
+#, fuzzy
+msgid "devcp_dashboard_start"
+msgstr "Get Started"
+
+#: views/developers/dashboard.thtml:82
+#, fuzzy
+msgid "devcp_dashboard_versions"
+msgstr "Versions and Files"
+
+#: views/developers/dashboard.thtml:91
+#, fuzzy
+msgid "devcp_dashboard_versions_new"
+msgstr "Upload a new version"
+
+#. %s is the preview ID number.
+#: controllers/developers_controller.php:1415
+#, fuzzy
+msgid "devcp_delete_previews_error"
+msgstr "Preview %s could not be deleted from the database. Please try again."
+
+#. %s is the preview ID number.
+#: controllers/developers_controller.php:1413
+#, fuzzy
+msgid "devcp_delete_previews_success"
+msgstr "Preview %s has been deleted successfully."
+
+#: controllers/developers_controller.php:1089
+#, fuzzy
+msgid "devcp_delete_version_priv_error"
+msgstr "You do not have privileges to delete versions or files."
+
+#. %1$s is the count of files, a number
+#. %2$s is a status string like _('Public') or _('Incomplete')
+#: controllers/components/amo.php:549
+#, fuzzy
+msgid "devcp_describe_version_status"
+msgid_plural "devcp_describe_version_status"
+msgstr[0] "%1$s %2$s file"
+msgstr[1] "%1$s %2$s files"
+
+#. %s is a version number. Example: 3.0
+#: views/developers/versions.thtml:65
+#, php-format
+msgid "devcp_details_version"
+msgstr "Хувилбар %s"
+
+#: views/developers/discuss.thtml:68
+#, fuzzy
+msgid "devcp_discuss_addreply_header"
+msgstr "Add Reply"
+
+#: views/developers/discuss.thtml:57
+#, fuzzy
+msgid "devcp_discuss_allreplies_header"
+msgstr "Replies"
+
+#. notice when an error occurs saving a discussion reply
+#. %1 is the email address (linked) for the amo-editors list
+#: views/developers/discuss.thtml:70
+#, fuzzy
+msgid "devcp_discuss_error_notice"
+msgstr ""
+"There was an error saving your reply. Please contact %1$s about the issue."
+
+#. %1 is the add-on name, %2 is the add-on's version number currently being reviewed by an editor
+#: views/developers/discuss.thtml:46
+#, fuzzy
+msgid "devcp_discuss_intro"
+msgstr ""
+"A Mozilla Add-ons Editor requested further information from you regarding "
+"version %2$s of your add-on %1$s."
+
+#. %1 is the add-on name
+#: views/developers/discuss.thtml:43
+#, fuzzy
+msgid "devcp_discuss_pagetitle"
+msgstr "Provide More Information For the Add-on Review of %1$s"
+
+#. submit button text
+#: views/developers/discuss.thtml:79
+#, fuzzy
+msgid "devcp_discuss_submit_reply"
+msgstr "Submit Reply"
+
+#: views/developers/discuss.thtml:72
+#, fuzzy
+msgid "devcp_discuss_success_message"
+msgstr ""
+"Your reply was successfully saved. The other participants of the discussion "
+"will be notified by email."
+
+#. in an author/editor discussion about an add-on to be reviewed:
+#. %1 is the commenter's user name (linked).
+#. %2 is the full date the comment was made.
+#: views/developers/discuss.thtml:52 views/developers/discuss.thtml:62
+#, fuzzy
+msgid "devcp_discuss_writtenby"
+msgstr "written by %1$s on %2$s"
+
+#: views/developers/addon_edit_authors.thtml:72
+#: views/developers/addon_edit_authors.thtml:81
+#, fuzzy
+msgid "devcp_edit_authors_add_author"
+msgstr "Add New Author"
+
+#: views/developers/addon_edit_authors.thtml:96
+#, fuzzy
+msgid "devcp_edit_authors_add_author_button"
+msgstr "Add Author"
+
+#: views/developers/addon_edit_authors.thtml:83
+#, fuzzy
+msgid "devcp_edit_authors_add_email"
+msgstr "Author Account Email:"
+
+#: views/developers/addon_edit_authors.thtml:98
+#, fuzzy
+msgid "devcp_edit_authors_add_loading"
+msgstr "Checking account email..."
+
+#: views/developers/addon_edit_authors.thtml:70
+#, fuzzy
+msgid "devcp_edit_authors_click_save"
+msgstr "Click the Update Authors button below to save."
+
+#: views/developers/addon_edit_authors.thtml:58
+#, fuzzy
+msgid "devcp_edit_authors_header_current"
+msgstr "Current Authors"
+
+#: views/developers/addon_edit_authors.thtml:50
+#, fuzzy
+msgid "devcp_edit_authors_header_manage"
+msgstr "Manage Add-on Authors"
+
+#: views/developers/addon_edit_authors.thtml:93
+#, fuzzy
+msgid "devcp_edit_authors_label_add_listed"
+msgstr "List as author in pubilc display pages"
+
+#: views/developers/addon_edit_authors.thtml:89
+#, fuzzy
+msgid "devcp_edit_authors_label_developer"
+msgstr ""
+"<strong>Developer</strong> - Can manage all aspects of the add-on listing, "
+"except for adding and removing other authors."
+
+#: views/developers/addon_edit_authors.thtml:88
+#, fuzzy
+msgid "devcp_edit_authors_label_owner"
+msgstr ""
+"<strong>Owner</strong> - Can manage all aspects of the add-on listing, "
+"including adding and removing other authors."
+
+#: views/developers/addon_edit_authors.thtml:90
+#, fuzzy
+msgid "devcp_edit_authors_label_viewer"
+msgstr ""
+"<strong>Viewer</strong> - Can view add-on developer listing and statistics, "
+"but can't make any changes."
+
+#. Placeholder for the empty option in a <select>.
+#: views/developers/addon_edit_categories.thtml:69
+#, fuzzy
+msgid "devcp_edit_authors_option_empty"
+msgstr "----------------"
+
+#: views/developers/addon_edit_authors.thtml:86
+#, fuzzy
+msgid "devcp_edit_authors_select_role"
+msgstr "Select a role for the author:"
+
+#. Column name in a table.
+#: views/developers/addon_edit_authors.thtml:62
+#, fuzzy
+msgid "devcp_edit_authors_th_author"
+msgstr "Author"
+
+#. Column name in a table.
+#: views/developers/addon_edit_authors.thtml:64
+#, fuzzy
+msgid "devcp_edit_authors_th_listed"
+msgstr "Listed"
+
+#. Column name in a table.
+#: views/developers/addon_edit_authors.thtml:63
+#, fuzzy
+msgid "devcp_edit_authors_th_role"
+msgstr "Role"
+
+#: views/developers/addon_edit_authors.thtml:77
+#, fuzzy
+msgid "devcp_edit_authors_update_author"
+msgstr "Update authors"
+
+#: views/developers/addon_edit_categories.thtml:99
+#, fuzzy
+msgid "devcp_edit_categories_button_update"
+msgstr "Update Categories"
+
+#: views/developers/addon_edit_categories.thtml:88
+#, fuzzy
+msgid "devcp_edit_categories_does_not_fit"
+msgstr "My add-on doesn't fit into any available categories."
+
+#. %s is the application name (Firefox, Thunderbird).
+#: views/developers/addon_edit_categories.thtml:61
+#, fuzzy
+msgid "devcp_edit_categories_header_application"
+msgstr "%s Categories"
+
+#: views/developers/addon_edit_categories.thtml:49
+#, fuzzy
+msgid "devcp_edit_categories_header_manage"
+msgstr "Manage Add-on Categories"
+
+#: views/developers/addon_edit_categories.thtml:91
+#, fuzzy
+msgid "devcp_edit_categories_hover"
+msgstr "Hover over a category to see its description."
+
+#. %s is the category number (1, 2, 3).
+#: views/developers/addon_edit_categories.thtml:67
+#, fuzzy
+msgid "devcp_edit_categories_label_category_num"
+msgstr "Category %s"
+
+#: views/developers/addon_edit_categories.thtml:94
+#: views/developers/addon_edit_categories.thtml:103
+#, fuzzy
+msgid "devcp_edit_categories_none_available"
+msgstr "No categories are available for this add-on type and application."
+
+#: views/developers/addon_edit_categories.thtml:86
+#, fuzzy
+msgid "devcp_edit_categories_other"
+msgstr ""
+"Place your add-on into this category only if it does not fit into any other "
+"available categories."
+
+#. %s is the application name (Firefox, Thunderbird).
+#: views/developers/addon_edit_categories.thtml:63
+#, fuzzy
+msgid "devcp_edit_categories_select_application_categories"
+msgstr "Select up to three %s categories for your add-on"
+
+#: views/developers/addon_edit.thtml:47
+#, fuzzy
+msgid "devcp_edit_dd_manage_authors"
+msgstr "Add or remove users that can manage this add-on."
+
+#: views/developers/addon_edit.thtml:49
+#, fuzzy
+msgid "devcp_edit_dd_manage_categories"
+msgstr ""
+"Select the relevant categories for each application your add-on supports."
+
+#: views/developers/addon_edit.thtml:51
+#, fuzzy
+msgid "devcp_edit_dd_manage_description"
+msgstr ""
+"Add and modify translations for your add-on's summary, description, end-user "
+"license, and privacy policy."
+
+#: views/developers/addon_edit.thtml:53
+#, fuzzy
+msgid "devcp_edit_dd_manage_properties"
+msgstr "Change your add-on's name, homepage, icon, and other flags."
+
+#: views/developers/addon_edit_descriptions.thtml:116
+#, fuzzy
+msgid "devcp_edit_description_button_update"
+msgstr "Update Descriptions"
+
+#: views/developers/addon_edit_descriptions.thtml:115
+#, fuzzy
+msgid "devcp_edit_description_correct_error"
+msgstr "Please correct the errors above indicated in red."
+
+#: views/developers/addon_edit_descriptions.thtml:51
+#, fuzzy
+msgid "devcp_edit_descriptions_header"
+msgstr "Edit Add-on Descriptions"
+
+#: views/developers/addon_edit_descriptions.thtml:94
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_comments_description"
+msgstr ""
+"Any information end users may want to know that isn't necessarily applicable "
+"to the add-on summary or description. Common uses include listing known "
+"major bugs, information on how to report bugs, anticipated release date of a "
+"new version, etc."
+
+#: views/developers/addon_edit_descriptions.thtml:93
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_comments_name"
+msgstr "Developer Comments"
+
+#: views/developers/addon_edit_descriptions.thtml:86
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_description_description"
+msgstr ""
+"The description of your add-on is a longer explanation of features, "
+"functionality, and other relevant information. It is displayed under the "
+"summary on the add-on's display page."
+
+#: views/developers/addon_edit_descriptions.thtml:85
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_description_name"
+msgstr "Add-on Description"
+
+#: views/developers/addon_edit_descriptions.thtml:103
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_eula_description"
+msgstr ""
+"If your add-on has an End-User License Agreement (EULA), please enter its "
+"text below. If set below, users will be required to agree to this before "
+"installing your add-on. Please note that a EULA is not the same as a code "
+"license such as GPL or MPL."
+
+#: views/developers/addon_edit_descriptions.thtml:102
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_eula_name"
+msgstr "End-User License Agreement"
+
+#: views/developers/addon_edit_descriptions.thtml:112
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_privacy_description"
+msgstr ""
+"If your add-on has a privacy policy, enter its text here. Your add-on's "
+"display page will display a link to the policy."
+
+#: views/developers/addon_edit_descriptions.thtml:111
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_privacy_name"
+msgstr "Privacy Policy"
+
+#: views/developers/addon_edit_descriptions.thtml:78
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_summary_description"
+msgstr ""
+"The summary is a short explanation of your add-on's basic functionality that "
+"is displayed in search and browse listings, as well as at the top of your "
+"add-on's display page. <strong>Limit of 250 characters.</strong>"
+
+#: views/developers/addon_edit_descriptions.thtml:77
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_summary_name"
+msgstr "Add-on Summary"
+
+#: views/developers/addon_edit.thtml:46
+#, fuzzy
+msgid "devcp_edit_dt_manage_authors"
+msgstr "Manage Add-on Authors"
+
+#: views/developers/addon_edit.thtml:48
+#, fuzzy
+msgid "devcp_edit_dt_manage_categories"
+msgstr "Manage Add-on Categories"
+
+#: views/developers/addon_edit.thtml:50
+#, fuzzy
+msgid "devcp_edit_dt_manage_descriptions"
+msgstr "Manage Add-on Descriptions"
+
+#: views/developers/addon_edit.thtml:52
+#, fuzzy
+msgid "devcp_edit_dt_manage_properties"
+msgstr "Manage Add-on Properties"
+
+#: views/developers/addon_edit_properties.thtml:170
+msgid "devcp_edit_label_externalsoftware"
+msgstr "Ð­Ð½Ñ Ð½ÑмÑгдÑл нь нÑмÑлт програм шаарддаг"
+
+#: views/developers/addon_edit_properties.thtml:205
+msgid "devcp_edit_label_locale_disambiguation"
+msgstr "Ð¥ÑÑ€ÑглÑÑ… Ñ…Ñлний нÑмÑлт мÑдÑÑлÑл"
+
+#: views/developers/addon_edit_properties.thtml:168
+msgid "devcp_edit_label_prerelease"
+msgstr "Ð­Ð½Ñ Ð½ÑŒ өмнөх хувилбар"
+
+#: views/developers/addon_edit_properties.thtml:169
+msgid "devcp_edit_label_sitespecific"
+msgstr "Ð­Ð½Ñ Ð½ÑŒ туÑгай хуудÑанд зориулÑан нÑмÑгдÑл"
+
+#: views/developers/addon_edit_properties.thtml:202
+msgid "devcp_edit_label_target_locale"
+msgstr "Ð¥ÑÑ€ÑглÑÑ… Ñ…Ñл"
+
+#: views/developers/addon_edit_properties.thtml:212
+#, fuzzy
+msgid "devcp_edit_properties_button_update"
+msgstr "Update Properties"
+
+#: views/developers/addon_edit_properties.thtml:198
+#, fuzzy
+msgid "devcp_edit_properties_change_guid"
+msgstr "Only change if you understand all of the consequences."
+
+#: views/developers/addon_edit_properties.thtml:109
+#, fuzzy
+msgid "devcp_edit_properties_current_icon"
+msgstr "Current Icon"
+
+#: views/developers/addon_edit_properties.thtml:85
+#, fuzzy
+msgid "devcp_edit_properties_default_locale"
+msgstr ""
+"An add-on's default locale is the main locale in which translations must be "
+"present. If translations for your add-on's descriptions are unavailable in a "
+"user's selected language, they will fall back to this default locale."
+
+#: views/developers/addon_edit_properties.thtml:167
+#, fuzzy
+msgid "devcp_edit_properties_flags"
+msgstr "These flags are used to filter and classify add-ons."
+
+#: views/developers/addon_edit_properties.thtml:174
+#, fuzzy
+msgid "devcp_edit_properties_guid"
+msgstr ""
+"The GUID of your add-on is specified in its install.rdf and uniquely "
+"identifies it. You cannot change your GUID once it is listed on Mozilla Add-"
+"ons."
+
+#: views/developers/addon_edit_properties.thtml:53
+#, fuzzy
+msgid "devcp_edit_properties_header"
+msgstr "Edit Add-on Properties"
+
+#: views/developers/addon_edit_properties.thtml:186
+#, fuzzy
+msgid "devcp_edit_properties_header_addon_type"
+msgstr "Add-on Type"
+
+#: views/developers/addon_edit_properties.thtml:181
+#, fuzzy
+msgid "devcp_edit_properties_header_admin_settings"
+msgstr "Admin Settings"
+
+#: views/developers/addon_edit_properties.thtml:84
+#, fuzzy
+msgid "devcp_edit_properties_header_default_locale"
+msgstr "Default Locale"
+
+#: views/developers/addon_edit_properties.thtml:166
+#, fuzzy
+msgid "devcp_edit_properties_header_flags"
+msgstr "Add-on Flags"
+
+#: views/developers/addon_edit_properties.thtml:173
+#: views/developers/addon_edit_properties.thtml:197
+#, fuzzy
+msgid "devcp_edit_properties_header_guid"
+msgstr "Add-on GUID"
+
+#: views/developers/addon_edit_properties.thtml:104
+#, fuzzy
+msgid "devcp_edit_properties_header_icon"
+msgstr "Add-on Icon"
+
+#: views/developers/addon_edit_properties.thtml:159
+#, fuzzy
+msgid "devcp_edit_properties_header_other_settings"
+msgstr "Other Settings"
+
+#. A header on the admin page to toggle trusted status.
+#: views/developers/addon_edit_properties.thtml:182
+#, fuzzy
+msgid "devcp_edit_properties_header_trusted"
+msgstr "Trusted Add-on?"
+
+#: views/developers/addon_edit_properties.thtml:160
+#, fuzzy
+msgid "devcp_edit_properties_header_view_source"
+msgstr "View Source Online"
+
+#. %s is a comma-separated list of image extensions ".png, .jpg"
+#: views/developers/addon_edit_properties.thtml:106
+#, fuzzy
+msgid "devcp_edit_properties_icon"
+msgstr ""
+"The add-on icon is a small image that is displayed next to your add-on's "
+"name in browse and search results, display pages, and in the add-on "
+"installation dialog. The image will automatically be resized to 32 x 32 "
+"pixels. Please use one of the following image types: %s"
+
+#: views/developers/addon_edit_properties.thtml:171
+#, fuzzy
+msgid "devcp_edit_properties_label_binary"
+msgstr "This add-on contains binary components"
+
+#: views/developers/addon_edit_properties.thtml:185
+#, fuzzy
+msgid "devcp_edit_properties_label_not_trusted"
+msgstr "Not Trusted"
+
+#: views/developers/addon_edit_properties.thtml:184
+#, fuzzy
+msgid "devcp_edit_properties_label_trusted"
+msgstr "Trusted"
+
+#: views/developers/addon_edit_properties.thtml:110
+#, fuzzy
+msgid "devcp_edit_properties_new_icon"
+msgstr "New Icon"
+
+#: views/developers/addon_edit_properties.thtml:118
+#, fuzzy
+msgid "devcp_edit_properties_remove_icon"
+msgstr "Remove Icon"
+
+#: views/developers/addon_edit_properties.thtml:136
+#, fuzzy
+msgid "devcp_edit_properties_transbox_homepage_description"
+msgstr ""
+"If your add-on has another homepage, enter its address here. Adding other "
+"translations is not necessary unless your website is localized into other "
+"languages."
+
+#: views/developers/addon_edit_properties.thtml:135
+#, fuzzy
+msgid "devcp_edit_properties_transbox_homepage_name"
+msgstr "Add-on Homepage"
+
+#: views/developers/addon_edit_properties.thtml:79
+#, fuzzy
+msgid "devcp_edit_properties_transbox_name_description"
+msgstr "The name of your add-on is displayed everywhere your add-on is listed."
+
+#: views/developers/addon_edit_properties.thtml:78
+#, fuzzy
+msgid "devcp_edit_properties_transbox_name_name"
+msgstr "Add-on Name"
+
+#: views/developers/addon_edit_properties.thtml:145
+#, fuzzy
+msgid "devcp_edit_properties_transbox_supportemail_description"
+msgstr ""
+"If you have an email address for support inquiries, enter it here. Adding "
+"other translations is not necessary unless you have different email "
+"addresses for different languages."
+
+#: views/developers/addon_edit_properties.thtml:144
+#, fuzzy
+msgid "devcp_edit_properties_transbox_supportemail_name"
+msgstr "Support Email Address"
+
+#: views/developers/addon_edit_properties.thtml:154
+#, fuzzy
+msgid "devcp_edit_properties_transbox_supporturl_description"
+msgstr ""
+"If your add-on has a support website or forum, enter its address here. "
+"Adding other translations is not necessary unless your website is localized "
+"into other languages."
+
+#: views/developers/addon_edit_properties.thtml:153
+#, fuzzy
+msgid "devcp_edit_properties_transbox_supporturl_name"
+msgstr "Support Website"
+
+#: views/developers/addon_edit_properties.thtml:183
+#, fuzzy
+msgid "devcp_edit_properties_trusted"
+msgstr "Trusted add-ons can become public without Editor review."
+
+#. %s is href="..." and should stay in the <a> tag.
+#: views/developers/addon_edit_properties.thtml:119
+#, fuzzy
+msgid "devcp_edit_properties_undelete"
+msgstr "Icon will be deleted on save. <a %s>Cancel?</a>"
+
+#: views/developers/addon_edit_properties.thtml:161
+#, fuzzy
+msgid "devcp_edit_properties_view_source"
+msgstr ""
+"The source of your add-on files can be viewed online by any logged in user "
+"if you wish."
+
+#: views/developers/addon_edit_properties.thtml:162
+#, fuzzy
+msgid "devcp_edit_properties_view_source_allow"
+msgstr "Allow online source viewing"
+
+#: views/developers/addon_edit_properties.thtml:163
+#, fuzzy
+msgid "devcp_edit_properties_view_source_do_not_allow"
+msgstr "Do not allow online source viewing"
+
+#: views/elements/developers/editbox.thtml:46
+#, fuzzy
+msgid "devcp_editbox_authors"
+msgstr "Authors"
+
+#: views/elements/developers/editbox.thtml:47
+#, fuzzy
+msgid "devcp_editbox_categories"
+msgstr "Categories"
+
+#: views/elements/developers/editbox.thtml:52
+#, fuzzy
+msgid "devcp_editbox_change_status"
+msgstr "Change Status"
+
+#: views/elements/developers/editbox.thtml:48
+#, fuzzy
+msgid "devcp_editbox_descriptions"
+msgstr "Descriptions"
+
+#: views/elements/developers/editbox.thtml:43
+#, fuzzy
+msgid "devcp_editbox_edit_addon"
+msgstr "Edit Add-on"
+
+#: views/elements/developers/editbox.thtml:57
+#, fuzzy
+msgid "devcp_editbox_new_version"
+msgstr "New Version"
+
+#: views/elements/developers/editbox.thtml:49
+#, fuzzy
+msgid "devcp_editbox_properties"
+msgstr "Properties"
+
+#: views/elements/developers/editbox.thtml:60
+#, fuzzy
+msgid "devcp_editbox_screenshots"
+msgstr "Preview Screenshots"
+
+#: views/elements/developers/editbox.thtml:53
+#, fuzzy
+msgid "devcp_editbox_statistics_dashboard"
+msgstr "Statistics Dashboard"
+
+#: views/elements/developers/editbox.thtml:54
+#, fuzzy
+msgid "devcp_editbox_versions"
+msgstr "Versions and Files"
+
+#: views/elements/developers/editbox.thtml:42
+#, fuzzy
+msgid "devcp_editbox_view_listing"
+msgstr "View Listing"
+
+#: views/elements/developers/editorsmenu.thtml:59
+msgid "devcp_editorsqueue_featured"
+msgstr "СайжирÑан нÑмÑгдлүүд"
+
+#. %1 is the review count
+#: views/elements/developers/editorsqueue.thtml:42
+#: views/elements/developers/editorsmenu.thtml:56
+#, php-format
+msgid "devcp_editorsqueue_moderatedreviews"
+msgid_plural "devcp_editorsqueue_moderatedreviews"
+msgstr[0] "Ð¥ÑнаÑан үнÑлгÑÑ Ð´Ò¯Ð³Ð½Ñлтүүд (%s)"
+msgstr[1] "Ð¥ÑнаÑан үнÑлгÑÑ Ð´Ò¯Ð³Ð½Ñлтүүд (%s)"
+
+#. %1 is the nominated addons count
+#: views/elements/developers/editorsqueue.thtml:44
+#: views/elements/developers/editorsmenu.thtml:58
+#, php-format
+msgid "devcp_editorsqueue_nominated"
+msgid_plural "devcp_editorsqueue_nominated"
+msgstr[0] "ÐÑÑ€ дÑвшигдÑÑн нÑмÑгдлүүд (%s)"
+msgstr[1] "ÐÑÑ€ дÑвшигдÑÑн нÑмÑгдлүүд (%s)"
+
+#. %1 is the update count
+#: views/elements/developers/editorsqueue.thtml:43
+#: views/elements/developers/editorsmenu.thtml:57
+#, php-format
+msgid "devcp_editorsqueue_pendingupdates"
+msgid_plural "devcp_editorsqueue_pendingupdates"
+msgstr[0] "ШинÑчлÑлийн Ñ…Ò¯ÑÑлт хүлÑÑж байна (%s)"
+msgstr[1] "ШинÑчлÑлийн Ñ…Ò¯ÑÑлт хүлÑÑж байн (%s)"
+
+#: controllers/statistics_controller.php:147
+#: controllers/statistics_controller.php:361
+#: controllers/previews_controller.php:108
+#: controllers/previews_controller.php:211
+#: controllers/previews_controller.php:312
+msgid "devcp_error_addon_access_denied"
+msgstr "Танд ÑÐ½Ñ Ð½ÑмÑгдÑлд хандах Ñрх байхгүй байна."
+
+#. %s is a complete URL with the text from devcp_error_appversion_reference_link_text
+#. in the <a> tag. This should be fixed.
+#: controllers/components/developers.php:591
+#, php-format
+msgid "devcp_error_appversion_reference_link"
+msgstr "%s хуудаÑÐ½Ð°Ð°Ñ Ð»Ð°Ð²Ð»Ð°Ð¶ харна уу."
+
+#. This is the link text in the <a> for devcp_error_appversion_reference_link. This
+#. should be fixed.
+#: controllers/components/developers.php:591
+msgid "devcp_error_appversion_reference_link_text"
+msgstr "ÑÐ½Ñ Ñ…ÑƒÑƒÐ´Ð°Ñ"
+
+#: views/developers/addon_edit_authors.thtml:76
+#, fuzzy
+msgid "devcp_error_empty_authors"
+msgstr "Your add-on must have at least one owner."
+
+#. %1$s is the name of the file
+#: controllers/components/developers.php:658
+#, fuzzy
+msgid "devcp_error_file_exists"
+msgstr ""
+"A version of that addon already exists. To replace it, you must delete the "
+"file %1$s first."
+
+#. %1$s is a file extension. Example: .exe
+#. %2$s is a comma separated list of extensions. Example: .xpi, .jar
+#: controllers/components/developers.php:355
+#, php-format
+msgid "devcp_error_file_extension"
+msgstr ""
+"Ийм файлын өргөтгөл (%s) нь ÑонгогдÑон нÑмÑгдлийн төрөлд зөвшөөрөгдөөгүй. Та "
+"дараах Ñ‚Ó©Ñ€Ð»Ó©Ó©Ñ Ð½Ñгийг нь Ñонгоно уу: %s"
+
+#: controllers/components/developers.php:64
+msgid "devcp_error_five_categories"
+msgstr "Ð¢Ð°Ð²Ð°Ð°Ñ Ð¸Ð»Ò¯Ò¯Ð³Ò¯Ð¹ төрөл Ñонгоно уу."
+
+#: controllers/components/developers.php:526
+msgid "devcp_error_guid_application"
+msgstr "Ð­Ð½Ñ Ð½ÑмÑгдлийн таних дугаар нь програмд өмнө нь ашиглагдÑан байна."
+
+#: controllers/components/developers.php:337
+#: controllers/components/developers.php:389
+msgid "devcp_error_http_incomplete"
+msgstr "БүрÑн дамжуулалт хийгдÑÑнгүй"
+
+#: controllers/components/developers.php:335
+#: controllers/components/developers.php:336
+#: controllers/components/developers.php:387
+#: controllers/components/developers.php:388
+msgid "devcp_error_http_maxupload"
+msgstr "ИлгÑÑÑ… дÑÑд Ñ…ÑмжÑÑнÑÑÑ Ñ…ÑÑ‚ÑÑ€ÑÑн"
+
+#: controllers/components/developers.php:338
+#: controllers/components/developers.php:390
+msgid "devcp_error_http_nofile"
+msgstr "Ямар ч файл илгÑÑгдÑÑнгүй"
+
+#. %1$s is a file extension. Example: .exe
+#. %2$s is a comma separated list of extensions. Example: .xpi, .jar
+#: controllers/components/developers.php:401
+#, php-format
+msgid "devcp_error_icon_extension"
+msgstr ""
+"Ийм файл өргөтгөл (%s) нь Ñ‚ÑмдÑгт зургийн төрөлд таарахгүй байна. Та дараах "
+"Ñ‚Ó©Ñ€Ð»Ó©Ó©Ñ Ð½Ñгийг нь Ñонгоно уу: %s"
+
+#: controllers/developers_controller.php:504
+msgid "devcp_error_index_rdf_notfound"
+msgstr "install.rdf файл байхгүй байна."
+
+#: controllers/components/developers.php:601
+msgid "devcp_error_install_manifest"
+msgstr "Дараах алдаанууд install.rdf файлд олдов:"
+
+#: controllers/developers_controller.php:1463
+msgid "devcp_error_invalid_addontype"
+msgstr "ÐÑмÑгдлийн зөв төрлийг Ñонгоно уу."
+
+#. %$1s is a version. Example: 3.1.1
+#. %$2s is an add-on name.
+#: controllers/components/developers.php:569
+#: controllers/components/developers.php:581
+#, php-format
+msgid "devcp_error_invalid_appversion"
+msgstr "%s нь %s-д тохирÑон зөв хувилбар биш байна"
+
+#. %s is a string
+#: controllers/components/developers.php:521
+#, php-format
+msgid "devcp_error_invalid_guid"
+msgstr "Ð­Ð½Ñ Ð½ÑмÑгдлийн таних дугаар нь зөв биш байна: %s"
+
+#. %$1s is a version. Example: 3.1.1
+#. %$2s is an add-on name.
+#: controllers/components/developers.php:572
+#, php-format
+msgid "devcp_error_invalid_minversion"
+msgstr ""
+"%s нь %s-д тохирÑон зөв хувилбар биш байна: бага хувилбарын дугаар * гÑÑÑн "
+"Ñ‚ÑмдÑгт агуулж болохгүй"
+
+#: controllers/components/developers.php:536
+msgid "devcp_error_invalid_version"
+msgstr ""
+"Ð­Ð½Ñ Ð½ÑмÑгдлийн хувилбар нь зөв биш байна: Та <a href=\"http://developer."
+"mozilla.org/en/docs/Toolkit_version_format\">хуудаÑÐ½Ð°Ð°Ñ </a> харна уу"
+
+#: controllers/components/developers.php:531
+msgid "devcp_error_invalid_version_spaces"
+msgstr ""
+"Ð­Ð½Ñ Ð½ÑмÑгдлийн хувилбар нь зөв биш байна: хувилбарын дугаар хооÑон зай "
+"агуулах Ñ‘Ñгүй."
+
+#. %s is an error message from the parser.
+#: controllers/components/developers.php:501
+#, php-format
+msgid "devcp_error_manifest_parse"
+msgstr "install.rdf файлыг уншиж байхад дараах алдаанууд гарав: %s"
+
+#: controllers/components/developers.php:373
+msgid "devcp_error_move_file"
+msgstr "Файлыг зөөж чадахгүй байна"
+
+#. %s is the name of a file
+#: controllers/components/developers.php:650
+#: controllers/components/developers.php:662
+#: controllers/components/developers.php:667
+#: controllers/components/developers.php:727
+#: controllers/components/developers.php:738
+#: controllers/components/developers.php:743
+#, php-format
+msgid "devcp_error_moving_file"
+msgstr "Ðлдаа гарÑан тул %s-г зөөж байна."
+
+#: controllers/components/developers.php:595
+msgid "devcp_error_mozilla_application"
+msgstr "Та Ñдаж Ñуулгах нÑг мозилла програмтай байх Ñ‘Ñтой."
+
+#: controllers/components/developers.php:516
+msgid "devcp_error_no_guid"
+msgstr ""
+"install.rdf файл дотор ÑÐ½Ñ Ð½ÑмÑгдÑлд зориулÑан таних дугаар байхгүй байна."
+
+#: controllers/components/developers.php:287
+msgid "devcp_error_no_platform"
+msgstr "Үйлдлийн ÑиÑтем Ñонгогдоогүй байна"
+
+#: controllers/components/developers.php:59
+msgid "devcp_error_one_category"
+msgstr "Ядаж нÑг төрөл Ñонгоно уу."
+
+#: controllers/components/developers.php:92
+msgid "devcp_error_one_user"
+msgstr "Ð­Ð½Ñ Ð½ÑмÑгдÑлд Ñдаж нÑг зохиогч байх Ñ‘Ñтой."
+
+#. %1$s is a file extension. Example: .exe
+#. %2$s is a comma separated list of extensions. Example: .xpi, .jar
+#: controllers/components/developers.php:1081
+#, php-format
+msgid "devcp_error_preview_extension"
+msgstr ""
+"Ийм файлын өргөтгөл (%s) нь харуулагдах боломжгүй байна. Дараах Ñ‚Ó©Ñ€Ð»Ó©Ó©Ñ "
+"нÑгийг Ñонгоно уу: %s"
+
+#: controllers/components/developers.php:511
+msgid "devcp_error_updatekey"
+msgstr ""
+"ÐÑмÑгдлүүд шинÑчлÑÑ… түлхүүр ашиглаж чадахгүй. Уг түлхүүр install.rdf Ñ„Ð°Ð¹Ð»Ð°Ð°Ñ "
+"уÑтгаад дахин оролдоно уу."
+
+#: controllers/components/developers.php:506
+msgid "devcp_error_updateurl"
+msgstr ""
+"ÐÑмÑгдлүүд нь гаднын шинÑчлÑÑ… хаÑг ашиглаж болохгүй. Та түүнийг install.rdf "
+"Ñ„Ð°Ð¹Ð»Ð°Ð°Ñ ÑƒÑтгаад дахин оролдоно уу."
+
+#: controllers/developers_controller.php:465
+#: controllers/components/developers.php:271
+msgid "devcp_error_upload_file"
+msgstr "Файлаа илгÑÑÐ½Ñ Ò¯Ò¯."
+
+#: views/developers/uploader.thtml:135
+#, fuzzy
+msgid "devcp_input_upload_file"
+msgstr "Upload File"
+
+#: views/pages/js_constants.js.thtml:89
+#, fuzzy
+msgid "devcp_js_a_cancel"
+msgstr "Cancel"
+
+#: views/pages/js_constants.js.thtml:90
+#, fuzzy
+msgid "devcp_js_add_email"
+msgstr "Please enter the account email of the author you wish to add."
+
+#. alt text for a down-arrow image.
+#: views/pages/js_constants.js.thtml:81
+#, fuzzy
+msgid "devcp_js_img_move_down"
+msgstr "Move Down"
+
+#. alt text for an up-arrow image.
+#: views/pages/js_constants.js.thtml:82
+#, fuzzy
+msgid "devcp_js_img_move_up"
+msgstr "Move Up"
+
+#: views/pages/js_constants.js.thtml:91
+#, fuzzy
+msgid "devcp_js_img_remove_compat"
+msgstr "Remove Application Compatibility"
+
+#: views/pages/js_constants.js.thtml:86
+#, fuzzy
+msgid "devcp_js_input_list_author"
+msgstr "List as author in public listings"
+
+#: views/pages/js_constants.js.thtml:92
+#, fuzzy
+msgid "devcp_js_license_select"
+msgstr "Please select a license."
+
+#: views/pages/js_constants.js.thtml:93
+#, fuzzy
+msgid "devcp_js_license_text"
+msgstr "Please enter text for your license."
+
+#. <option> text in a <select> for Author role in an add-on.
+#: views/pages/js_constants.js.thtml:84
+#, fuzzy
+msgid "devcp_js_option_developer"
+msgstr "Developer"
+
+#. <option> text in a <select> for Author role in an add-on.
+#: views/pages/js_constants.js.thtml:83
+#, fuzzy
+msgid "devcp_js_option_owner"
+msgstr "Owner"
+
+#. <option> text in a <select> for Author role in an add-on.
+#: views/pages/js_constants.js.thtml:85
+#, fuzzy
+msgid "devcp_js_option_viewer"
+msgstr "Viewer"
+
+#: views/pages/js_constants.js.thtml:88
+#, fuzzy
+msgid "devcp_js_remove_author"
+msgstr "Remove Author"
+
+#: views/pages/js_constants.js.thtml:87
+#, fuzzy
+msgid "devcp_js_sure_remove"
+msgstr "Are you <strong>sure</strong> you wish to remove this author?"
+
+#: views/pages/js_constants.js.thtml:77
+#, fuzzy
+msgid "devcp_js_upload_alert"
+msgstr "You must select a file to upload."
+
+#. %1$s is an addon id, like 32.
+#. %2$s is a version number, like 3.5.
+#: controllers/components/developers.php:1212
+#, fuzzy
+msgid "devcp_license_existing"
+msgstr "Custom license for add-on %1$s v%2$s"
+
+#: views/elements/developers/localebox.thtml:44
+msgid "devcp_localebox_header_localizedfields"
+msgstr "ОрчуулагдÑан талбарууд"
+
+#. %1 is the default locale
+#: views/elements/developers/localebox.thtml:48
+#, php-format
+msgid "devcp_localebox_intro"
+msgstr ""
+"Ð­Ð½Ñ Ñ…ÑƒÑƒÐ´Ð°Ñны зарим Ñ…ÑÑÑг нь Ñ…ÑÑ€ÑглÑгчийн ÑÑ… Ñ…ÑлÑÑÑ€ нь орчуулагдÑан байгаа. "
+"ÐÑмÑгдлийнхÑÑ Ð½Ð°Ñ€Ð¸Ð¹Ð½ мÑдÑÑллийг заÑварлахад Ñ…ÑÑ€ÑглÑгдÑÑ… Ñ…ÑлÑÑ Ñонгоно уу. "
+"Ð¥ÑÑ€Ñв орчуулагдаагүй байвал анхдагч Ñ…Ñл Ñ€Ò¯Ò¯ (%s) автоматаар шилжинÑ."
+
+#: views/elements/developers/sidebar.thtml:68
+#: views/elements/developers/myaddons.thtml:75
+msgid "devcp_myaddons_admincp_link"
+msgstr "Зохицуулагчийн Ñ…Ñнах Ñамбар"
+
+#: views/elements/developers/sidebar.thtml:65
+#: views/elements/developers/myaddons.thtml:72
+msgid "devcp_myaddons_editorcp_link"
+msgstr "ЗаÑварлагчийн Ñ…Ñнах Ñамбар"
+
+#: views/elements/developers/myaddons.thtml:52
+msgid "devcp_myaddons_link"
+msgstr "Миний нÑмÑгдлүүд"
+
+#: views/elements/developers/sidebar.thtml:70
+#: views/elements/developers/myaddons.thtml:77
+msgid "devcp_myaddons_mainpage_link"
+msgstr "ЭхлÑл хуудÑанд буцах"
+
+#: views/elements/developers/sidebar.thtml:63
+#: views/elements/developers/myaddons.thtml:70
+msgid "devcp_myaddons_statistics_link"
+msgstr "Судалгааны Ñамбар"
+
+#: views/elements/developers/sidebar.thtml:62
+#: views/elements/developers/myaddons.thtml:69
+msgid "devcp_myaddons_submitaddon_link"
+msgstr "ÐÑмÑгдÑл илгÑÑÑ…"
+
+#: views/elements/developers/sidebar.thtml:48
+#: views/elements/developers/myaddons.thtml:67
+msgid "devcp_myaddons_title"
+msgstr "Зохиогчид зориулÑан багажнууд"
+
+#. %1$s is an add-on ID, perhaps 167.
+#. %2$s is a URL.
+#: controllers/developers_controller.php:256
+#, fuzzy
+msgid "devcp_new_addon_error"
+msgstr ""
+"This add-on ID (%1$s) already exists in the database. If this is your add-"
+"on, you can <a href=\"%2$s\">upload a new version</a>."
+
+#: views/developers/addon_status_nominate.thtml:62
+#, fuzzy
+msgid "devcp_nominate_cancel"
+msgstr "Cancel and return"
+
+#. %1 is the add-on name
+#: views/developers/addon_status_nominate.thtml:61
+#, php-format
+msgid "devcp_nominate_submit_nominate"
+msgstr "%s-г нÑÑ€ дÑвшүүл"
+
+#: views/developers/addon_edit_properties.thtml:50
+#: views/developers/addon_status.thtml:49
+#: views/developers/versions_edit.thtml:50
+#, fuzzy
+msgid "devcp_notice_changes_error"
+msgstr ""
+"<span>One or more of your changes couldn't be saved.</span><br />Please look "
+"for the errors below. The rest of your changes were successfully saved."
+
+#: views/developers/addon_edit_authors.thtml:47
+#: views/developers/addon_edit_properties.thtml:47
+#: views/developers/addon_status.thtml:46
+#: views/developers/addon_edit_descriptions.thtml:47
+#: views/developers/versions_edit.thtml:47
+#: views/developers/addon_edit_categories.thtml:46
+#, fuzzy
+msgid "devcp_notice_changes_saved"
+msgstr ""
+"<span>Your changes have been saved.</span><br />Please note that some "
+"changes may take several hours to appear in all areas of the website."
+
+#: controllers/previews_controller.php:252
+msgid "devcp_notice_cleardefault"
+msgstr ""
+"Ð­Ð½Ñ Ð°Ð½Ñ…Ð´Ð°Ð³Ñ‡ үзүүлбÑрийг уÑтгаÑнаар Ó©Ó©Ñ€ үзүүлбÑрийг автоматаар анхдагч болгож "
+"Ñонгодог."
+
+#: controllers/previews_controller.php:184
+#: controllers/previews_controller.php:251
+msgid "devcp_notice_makedefault"
+msgstr ""
+"Ð­Ð½Ñ Ò¯Ð·Ò¯Ò¯Ð»Ð±Ñрийг анхдагч болгоÑноор одоогийн байгаа анхдагч үзүүлбÑрийг "
+"анхдагч төлөв байдлыг арилгадаг."
+
+#: views/developers/addon_edit_authors.thtml:70
+#, fuzzy
+msgid "devcp_notice_unsaved_changes"
+msgstr "You have unsaved changes."
+
+#: controllers/developers_controller.php:87
+#: controllers/developers_controller.php:97
+#: controllers/developers_controller.php:100
+#: controllers/previews_controller.php:67
+#: controllers/previews_controller.php:79
+#: controllers/previews_controller.php:82
+msgid "devcp_pagetitle"
+msgstr "ХөгжүүлÑгчийн Ñ…Ñнах Ñамбар"
+
+#: controllers/previews_controller.php:103
+#: controllers/previews_controller.php:104
+msgid "devcp_preview_add_pagetitle"
+msgstr "ҮзүүлбÑÑ€ нÑмÑÑ…"
+
+#: controllers/previews_controller.php:135
+msgid "devcp_preview_added_successfully"
+msgstr "ҮзүүлбÑÑ€ амжилттай нÑмÑгдлÑÑ."
+
+#: controllers/previews_controller.php:323
+msgid "devcp_preview_deleted_successfully"
+msgstr "ҮзүүлбÑÑ€ амжилттай уÑтгагдлаа."
+
+#: controllers/previews_controller.php:194
+#: controllers/previews_controller.php:195
+msgid "devcp_preview_edit_pagetitle"
+msgstr "ҮзүүлбÑрийг заÑварлах"
+
+#: controllers/previews_controller.php:237
+msgid "devcp_preview_updated_successfully"
+msgstr "ҮзүүлбÑÑ€ амжилттай шинÑчлÑгдлÑÑ."
+
+#: views/developers/previews.thtml:120
+#, fuzzy
+msgid "devcp_previews_a_another"
+msgstr "Add Another Preview"
+
+#: views/developers/previews.thtml:96
+#, fuzzy
+msgid "devcp_previews_a_delete"
+msgstr "Delete Preview"
+
+#: views/developers/previews.thtml:95
+#, fuzzy
+msgid "devcp_previews_a_replace"
+msgstr "Replace Preview"
+
+#: views/developers/previews.thtml:126
+#, fuzzy
+msgid "devcp_previews_a_update"
+msgstr "Update Previews"
+
+#: views/developers/previews.thtml:115 views/developers/previews.thtml:124
+#, fuzzy
+msgid "devcp_previews_add_new"
+msgstr "Add New Preview"
+
+#. %s is a list of file extensions, e.g. ".png, .gif"
+#: views/developers/previews.thtml:116
+#, fuzzy
+msgid "devcp_previews_add_select"
+msgstr ""
+"Select an image to upload below. Images larger than the maximum size of 700 "
+"pixels wide by 525 pixels tall will be resized. Allowed file types: %s"
+
+#: views/developers/previews.thtml:121
+#, fuzzy
+msgid "devcp_previews_click_below"
+msgstr "Click Update Previews below to upload."
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/previews.thtml:102
+#, fuzzy
+msgid "devcp_previews_click_update"
+msgstr ""
+"Click the Update Previews button below to save this image. (<a %s>Cancel?</"
+"a>)"
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/previews.thtml:107
+#, fuzzy
+msgid "devcp_previews_error_message"
+msgstr ""
+"This preview will be deleted when Update Previews is clicked below. (<a %"
+"s>Cancel?</a>)"
+
+#: views/previews/add.thtml:45
+msgid "devcp_previews_filetype_info"
+msgstr ""
+"Дараах Ñ…Ò¯ÑнÑгтийг ашиглан нÑмÑгдлийнхÑÑ Ð´ÑлгÑцийн агшны PNG, JPG, мөн GIF "
+"зургуудыг илгÑÑÐ½Ñ Ò¯Ò¯. Өргөн нь 700 цÑг мөн өндөр нь 525 цÑгÑÑÑ Ñ…ÑÑ‚ÑÑ€ÑÑн "
+"зурагнууд автоматаар багаÑгагдах болно."
+
+#: views/previews/add.thtml:43
+msgid "devcp_previews_header_add"
+msgstr "ҮзүүлбÑÑ€ нÑм"
+
+#: views/developers/previews.thtml:80
+#, fuzzy
+msgid "devcp_previews_header_caption"
+msgstr "Preview Caption"
+
+#: views/previews/edit.thtml:43
+msgid "devcp_previews_header_edit"
+msgstr "ҮзүүлбÑрийг заÑварла"
+
+#: views/developers/previews.thtml:93
+#, fuzzy
+msgid "devcp_previews_label_default"
+msgstr "Default Preview"
+
+#: views/previews/add.thtml:54
+msgid "devcp_previews_label_file"
+msgstr "Файлыг харуул"
+
+#: views/previews/add.thtml:59 views/previews/edit.thtml:50
+msgid "devcp_previews_label_makedefault"
+msgstr "Үүнийг анхдагч үзүүлбÑÑ€ болго"
+
+#: views/developers/previews.thtml:100
+#, fuzzy
+msgid "devcp_previews_label_new"
+msgstr "New image:"
+
+#: views/developers/previews.thtml:118
+#, fuzzy
+msgid "devcp_previews_label_upload"
+msgstr "Upload Preview: "
+
+#: views/developers/previews.thtml:50
+#, fuzzy
+msgid "devcp_previews_notice_error"
+msgstr "One or more of your new previews could not be saved."
+
+#: views/developers/previews.thtml:47
+#, fuzzy
+msgid "devcp_previews_notice_success"
+msgstr "Your previews have been updated successfully."
+
+#: views/developers/previews.thtml:59
+#, fuzzy
+msgid "devcp_previews_p_screenshots"
+msgstr ""
+"The preview screenshots for your add-on are shown below. You can make "
+"changes to captions or images below. The Default Preview is the preview that "
+"is displayed next to your add-on in search and browse listings."
+
+#: views/previews/edit.thtml:55
+msgid "devcp_previews_submit_delete"
+msgstr "ҮзүүлбÑрийг уÑтга"
+
+#: views/previews/edit.thtml:55
+msgid "devcp_previews_submit_delete_confirm"
+msgstr "Та ÑÐ½Ñ Ò¯Ð·Ò¯Ò¯Ò¯Ð»Ð±Ñрийг уÑтгахдаа итгÑлтÑй байна уу?"
+
+#: views/previews/edit.thtml:54
+msgid "devcp_previews_submit_edit"
+msgstr "ҮзүүлбÑрийг заÑварла"
+
+#: views/previews/add.thtml:63
+msgid "devcp_previews_submit_upload"
+msgstr "ҮзүүлбÑÑ€ илгÑÑÑ…"
+
+#: views/developers/previews.thtml:78
+#, fuzzy
+msgid "devcp_previews_thumbnail"
+msgstr "Thumbnail"
+
+#. %s is the add-on name.
+#: views/developers/previews.thtml:44
+#, fuzzy
+msgid "devcp_previews_title"
+msgstr "%s Preview Manager"
+
+#: views/developers/uploader.thtml:74
+msgid "devcp_review_agreement_please"
+msgstr ""
+"ГүйцÑтгÑÑ…ÑÑÑÑÑ Ó©Ð¼Ð½Ó© дараах хөгжүүлÑгчийн зөвшилцлийг уншиж дүгнÑлт Ñ…Ð¸Ð¹Ð½Ñ Ò¯Ò¯."
+
+#: views/elements/developers/rolecheck.thtml:42
+#, fuzzy
+msgid "devcp_rolecheck_no_privs"
+msgstr ""
+"<span>You do not have sufficient privileges to make changes on this page.</"
+"span><br />Contact the Add-on Owner if you need to make changes."
+
+#: controllers/developers_controller.php:1315
+#, fuzzy
+msgid "devcp_several_hours"
+msgstr ""
+"Please note that some changes may take several hours to appear in all areas "
+"of the website."
+
+#: views/elements/developers/sidebar.thtml:52
+#, fuzzy
+msgid "devcp_sidebar_a_dashboard"
+msgstr "Dashboard"
+
+#. %s is a number
+#: views/elements/developers/statsbar.thtml:45
+#: views/developers/dashboard.thtml:79
+#, php-format
+msgid "devcp_statsbar_adu"
+msgstr "<em>%s</em> өдөр тутмын идÑвхитÑй Ñ…ÑÑ€ÑглÑдÑг Ñ…ÑÑ€ÑглÑгчид"
+
+#. %s is a number
+#: views/elements/developers/statsbar.thtml:41
+#: views/developers/dashboard.thtml:75
+#, php-format
+msgid "devcp_statsbar_total_downloads"
+msgstr "<em>%s</em> удаа татаж авÑан"
+
+#. %s is a number
+#: views/elements/developers/statsbar.thtml:43
+#: views/developers/dashboard.thtml:77
+#, php-format
+msgid "devcp_statsbar_weekly_downloads"
+msgstr "<em>%s</em> удаа долоо хоногт татаж авÑан"
+
+#: views/developers/addon_status_confirm.thtml:59
+#, fuzzy
+msgid "devcp_status_confirm_active"
+msgstr ""
+"Marking this add-on active will cause it to show up in public areas "
+"appropriate for its status, including search and browse listings. It will be "
+"downloadable from the website and could be returned in client update checks, "
+"depending on its status. You will be able to return here and disable it "
+"again at your convenience."
+
+#: views/developers/addon_status_confirm.thtml:59
+#, fuzzy
+msgid "devcp_status_confirm_active_sure"
+msgstr "Are you sure you wish to mark this add-on active?"
+
+#: views/developers/addon_status_confirm.thtml:50
+#, fuzzy
+msgid "devcp_status_confirm_header_sure"
+msgstr "Are you sure?"
+
+#: views/developers/addon_status_confirm.thtml:55
+#, fuzzy
+msgid "devcp_status_confirm_inactive"
+msgstr ""
+"Marking this add-on inactive will prevent it from showing up in any public "
+"areas, including search and browse listings. It will not be downloadable "
+"from the website and will not be returned in client update checks. You will "
+"be able to return here and re-enable it at your convenience."
+
+#: views/developers/addon_status_confirm.thtml:55
+#, fuzzy
+msgid "devcp_status_confirm_inactive_sure"
+msgstr "Are you sure you wish to mark this add-on inactive?'"
+
+#: views/developers/addon_status_confirm.thtml:74
+#, fuzzy
+msgid "devcp_status_confirm_no"
+msgstr "No, cancel"
+
+#: views/developers/addon_status_confirm.thtml:67
+#, fuzzy
+msgid "devcp_status_confirm_public"
+msgstr ""
+"Making this add-on public will make it available for anyone to download and "
+"will begin offering updates to existing users."
+
+#: views/developers/addon_status_confirm.thtml:67
+#, fuzzy
+msgid "devcp_status_confirm_public_sure"
+msgstr "Are you sure you wish to make this add-on public?"
+
+#: views/developers/addon_status_confirm.thtml:63
+#, fuzzy
+msgid "devcp_status_confirm_sandbox"
+msgstr ""
+"Moving this add-on back to the sandbox will require users to login before "
+"downloading and updates will no longer be offered to existing users. Because "
+"your add-on is currently public, you will be able to return here at any time "
+"to make it public again."
+
+#: views/developers/addon_status_confirm.thtml:63
+#, fuzzy
+msgid "devcp_status_confirm_sandbox_sure"
+msgstr "Are you sure you wish to move this add-on to the sandbox?"
+
+#: views/developers/addon_status_confirm.thtml:73
+#, fuzzy
+msgid "devcp_status_confirm_yes"
+msgstr "Yes, I'm Sure"
+
+#: views/developers/addon_status_nominate.thtml:46
+#, fuzzy
+msgid "devcp_status_nominate_error_notice"
+msgstr ""
+"<span>A nomination message is required.</span><br />Please fill in the text "
+"box with the requested information and try again."
+
+#: views/developers/addon_status_nominate.thtml:55
+#, fuzzy
+msgid "devcp_status_nominate_header"
+msgstr "Add-on Nomination"
+
+#: views/developers/dashboard.thtml:85
+msgid "devcp_summary_lastversion"
+msgstr "Сүүлийн хувилбар:"
+
+#. %s is the add-on name.
+#: views/developers/addon_edit.thtml:43
+#: views/developers/addon_edit_authors.thtml:44
+#: views/developers/versions_delete.thtml:43
+#: views/developers/addon_edit_properties.thtml:44
+#: views/developers/addon_edit_descriptions.thtml:44
+#: views/developers/versions_edit.thtml:44
+#: views/developers/addon_edit_categories.thtml:43
+#: views/developers/versions.thtml:43
+#, fuzzy
+msgid "devcp_title_edit_addon"
+msgstr "Edit %s"
+
+#. title attribute for a javascript link that pops up a help dialog.
+#: views/elements/translationbox.thtml:68
+#, fuzzy
+msgid "devcp_transbox_a_title_help"
+msgstr "Help (does not leave page)"
+
+#: views/elements/translationbox.thtml:68
+#, fuzzy
+msgid "devcp_transbox_alt_help"
+msgstr "Help"
+
+#. %1$s is <span>17</span>, %2$s is 42.
+#: views/elements/translationbox.thtml:101
+#, fuzzy
+msgid "devcp_transbox_chars_used"
+msgstr "Characters used: %1$s / %2$s"
+
+#: views/elements/translationbox.thtml:132
+#, fuzzy
+msgid "devcp_transbox_delete_sure"
+msgstr "Are you sure you wish to delete this translation?"
+
+#. %s is a locale, like en-US.
+#: views/elements/translationbox.thtml:143
+#, fuzzy
+msgid "devcp_transbox_help_header_tabs"
+msgstr "What are these %s tabs?"
+
+#: views/elements/translationbox.thtml:145
+#, fuzzy
+msgid "devcp_transbox_help_header_what"
+msgstr "What if I don't have any translations?"
+
+#: views/elements/translationbox.thtml:147
+#, fuzzy
+msgid "devcp_transbox_help_hide"
+msgstr "Hide Help"
+
+#: views/elements/translationbox.thtml:146
+#, fuzzy
+msgid "devcp_transbox_help_if"
+msgstr ""
+"If a user browses the site and a translation isn't available in their own "
+"language, it will fall back to your add-on's Default Locale, specified in "
+"the Edit Add-on Properties area. If you don't have any translations, just "
+"enter what you can into your Default Locale, which should be a language you "
+"speak."
+
+#: views/elements/translationbox.thtml:144
+#, fuzzy
+msgid "devcp_transbox_help_transbox"
+msgstr ""
+"This is a <i>Translation Box</i>. It allows you to localize a specific field "
+"into any other languages for which you might have a translation. You can "
+"add, edit, and remove translations using the locale tabs."
+
+#: views/elements/translationbox.thtml:85
+#, fuzzy
+msgid "devcp_transbox_img_add_trans"
+msgstr "Add Translation"
+
+#: views/elements/translationbox.thtml:86
+#, fuzzy
+msgid "devcp_transbox_img_remove_trans"
+msgstr "Remove Translation"
+
+#: views/elements/translationbox.thtml:123
+#, fuzzy
+msgid "devcp_transbox_input_add_all"
+msgstr "Add Locale to All"
+
+#: views/elements/translationbox.thtml:122
+#, fuzzy
+msgid "devcp_transbox_input_add_locale"
+msgstr "Add Locale"
+
+#: views/elements/translationbox.thtml:124
+#: views/elements/translationbox.thtml:135
+#, fuzzy
+msgid "devcp_transbox_input_cancel"
+msgstr "Cancel"
+
+#: views/elements/translationbox.thtml:134
+#, fuzzy
+msgid "devcp_transbox_input_delete"
+msgstr "Delete It"
+
+#: views/elements/translationbox.thtml:113
+#, fuzzy
+msgid "devcp_transbox_select_locale"
+msgstr "Select the locale of the translation to add:"
+
+#. %1$s and %2$s are GUIDs.
+#: controllers/developers_controller.php:343
+#, fuzzy
+msgid "devcp_update_addon_guid_error"
+msgstr ""
+"The add-on GUID used in this file (%1$s) does not match the existing GUID "
+"for this add-on (%2$s)."
+
+#: controllers/developers_controller.php:334
+#, fuzzy
+msgid "devcp_update_addon_priv_error"
+msgstr "You do not have sufficient privileges to update this add-on."
+
+#. %1$s is a version number, %2$s is an add-on ID.
+#: controllers/developers_controller.php:399
+#, fuzzy
+msgid "devcp_update_addon_version_belong_error"
+msgstr "The specified version (%1$s) does not belong to this add-on (%2$s)."
+
+#. %1$s is a version number, maybe 1.1.
+#. %2$s is a URL.
+#: controllers/developers_controller.php:351
+#, fuzzy
+msgid "devcp_update_addon_version_exists_error"
+msgstr ""
+"The version number uploaded (%1$s) already exists for this add-on. If you "
+"are trying to add another file to this version, <a href=\"%2$s\">click here</"
+"a>."
+
+#. %1$s and %2$s are version numbers.
+#: controllers/developers_controller.php:405
+#, fuzzy
+msgid "devcp_update_addon_version_match_error"
+msgstr ""
+"The uploaded version number (%1$s) does not match the existing version "
+"number (%2$s)."
+
+#: views/developers/uploader.thtml:68
+#, fuzzy
+msgid "devcp_uploader_a_start"
+msgstr "Get Started"
+
+#: views/developers/uploader.thtml:137
+#, fuzzy
+msgid "devcp_uploader_ajax_loading"
+msgstr "Uploading file..."
+
+#: views/developers/uploader.thtml:82
+#, fuzzy
+msgid "devcp_uploader_button_agree"
+msgstr "Agree and continue"
+
+#: views/developers/uploader.thtml:157
+#, fuzzy
+msgid "devcp_uploader_button_edit"
+msgstr "Edit My Add-on"
+
+#: views/developers/uploader.thtml:158
+#, fuzzy
+msgid "devcp_uploader_button_later"
+msgstr "I'll complete my add-on later."
+
+#: views/developers/uploader.thtml:168
+#, fuzzy
+msgid "devcp_uploader_button_release"
+msgstr "Add Release Notes"
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/uploader.thtml:156
+#, fuzzy
+msgid "devcp_uploader_created_results"
+msgstr ""
+"<p>Your add-on listing has been successfully created. The basic information "
+"obtained from your uploaded file has been stored, but there's a lot more to "
+"your listing that can be customized.</p><p>Your add-on is currently marked "
+"as <strong>Incomplete</strong>. In order to complete your add-on, you'll "
+"need to make sure it has an accurate name, summary, and description, as well "
+"as at least one selected category. You can edit your add-on's information "
+"using the link below and check the status of your add-on at any time on the "
+"<a %s>status page</a>."
+
+#: views/developers/uploader.thtml:143
+#, fuzzy
+msgid "devcp_uploader_error_correct"
+msgstr "Please correct this problem and upload your file again."
+
+#. %1$s is a version number, %2$s is a status, e.g Public or Incomplete.
+#: views/developers/uploader.thtml:175
+#, fuzzy
+msgid "devcp_uploader_file_created"
+msgstr ""
+"Your new file has been added to version %1$s and is currently marked as %2$s."
+
+#: views/developers/uploader.thtml:154
+#, fuzzy
+msgid "devcp_uploader_header_created"
+msgstr "Add-on Created!"
+
+#: views/developers/uploader.thtml:141
+#, fuzzy
+msgid "devcp_uploader_header_error"
+msgstr "Oops! There seems to be a problem with this file..."
+
+#: views/developers/uploader.thtml:173
+#, fuzzy
+msgid "devcp_uploader_header_file_added"
+msgstr "File Added!"
+
+#: views/developers/uploader.thtml:66
+#, fuzzy
+msgid "devcp_uploader_header_how"
+msgstr "How does it all work?"
+
+#. %s is the version number, e.g. 3.2.
+#: views/developers/uploader.thtml:163
+#, fuzzy
+msgid "devcp_uploader_header_update_created"
+msgstr "Version %s Created"
+
+#: views/developers/uploader.thtml:117
+#, fuzzy
+msgid "devcp_uploader_header_upload"
+msgstr "Upload Your File"
+
+#: views/developers/uploader.thtml:67
+#, fuzzy
+msgid "devcp_uploader_how"
+msgstr ""
+"<p>Thanks for your interest in submitting your add-on to Mozilla Add-ons. "
+"Hosting your add-on on Mozilla Add-ons is the easiest way to handle "
+"distribution of your add-on. Here's what you'll get:</p><ul><li>Each add-on "
+"will have a public display page with information you provide, such as a "
+"brief summary of the add-on's functionality, an optional longer description, "
+"and a showcase of preview screenshots of your add-on.</li><li>Your add-on "
+"will appear in search and browse listings across the site, and even in the "
+"Add-ons Manager of Firefox 3.</li><li>We'll take care of hosting all of your "
+"downloads and providing automatic updates to users when you upload a new "
+"version.</li><li>You'll have access to a statistics dashboard with detailed "
+"information about your user base.</li></ul><p>Add-ons hosted on the site "
+"must be reviewed by a Mozilla Add-ons Editor before they will have all of "
+"the features listed above. If you're ready to start the process and have "
+"your add-on package ready for upload, just click on Get Started below!</p>"
+
+#: views/developers/uploader.thtml:125
+#, fuzzy
+msgid "devcp_uploader_label_platformtype"
+msgstr "Supported Platforms:"
+
+#: views/developers/uploader.thtml:124
+#, fuzzy
+msgid "devcp_uploader_label_upload_field"
+msgstr "Add-on File: "
+
+#: controllers/components/developers.php:1221
+#, fuzzy
+msgid "devcp_uploader_option_other"
+msgstr "Other"
+
+#. %1$s is a number, %2$s is href="..." and should stay in the <a> tag.
+#: views/developers/uploader.thtml:176
+#, fuzzy
+msgid "devcp_uploader_p_pending_file"
+msgstr ""
+"The new file will be available to the public as soon as an editor is able to "
+"review it. There are currently %1$s other add-ons in the queue. Want to be "
+"reviewed faster? Consider <a %2$s>becoming an editor</a>."
+
+#. %1$s is a number, %2$s is href="..." and should stay in the <a> tag.
+#: views/developers/uploader.thtml:166
+#, fuzzy
+msgid "devcp_uploader_p_pending_version"
+msgstr ""
+"The new version will be available to the public as soon as an editor is able "
+"to review it. There are currently %1$s other add-ons in the queue. Want to "
+"be reviewed faster? Consider <a %2$s>becoming an editor</a>."
+
+#. %s is a status, e.g Public or Incomplete.
+#: views/developers/uploader.thtml:165
+#, fuzzy
+msgid "devcp_uploader_p_update_created"
+msgstr "Your new version has been created and is currently marked as %s."
+
+#. %1$s is href="..." and should stay in the 'Versions and Files' <a> tag.
+#. %2$s is href="..." and should stay in the 'current status' <a> tag.
+#: views/developers/uploader.thtml:177
+#, fuzzy
+msgid "devcp_uploader_p_update_file"
+msgstr ""
+"View your new file in the <a %1$s>Versions and Files page</a>, check out "
+"your add-on's <a %2$s>current status</a>, or <b>add release notes</b> by "
+"clicking the button below (highly recommended)."
+
+#. %1$s is href="..." and should stay in the 'Versions and Files' <a> tag.
+#. %2$s is href="..." and should stay in the 'current status' <a> tag.
+#: views/developers/uploader.thtml:167
+#, fuzzy
+msgid "devcp_uploader_p_update_version"
+msgstr ""
+"View your new version in the <a %1$s>Versions and Files page</a>, check out "
+"your add-on's <a %2$s>current status</a>, or <b>add release notes</b> by "
+"clicking the button below (highly recommended)."
+
+#: views/developers/uploader.thtml:118
+#, fuzzy
+msgid "devcp_uploader_p_upload"
+msgstr ""
+"Upload your add-on file using the form below. If you have multiple, platform-"
+"specific files to upload, choose a single file and then upload the others "
+"using the Versions and Files Manager."
+
+#: views/developers/uploader.thtml:125
+#, fuzzy
+msgid "devcp_uploader_platformtype_all"
+msgstr "All"
+
+#: views/developers/uploader.thtml:126
+#, fuzzy
+msgid "devcp_uploader_platformtype_specific"
+msgstr "Specific:"
+
+#. Used as first item in a <select>.
+#: controllers/components/developers.php:1185
+#, fuzzy
+msgid "devcp_uploader_please_choose"
+msgstr "Please Choose..."
+
+#. %1$s is the add-on name, %2$s is the version number.
+#: views/developers/uploader.thtml:57
+#, fuzzy
+msgid "devcp_uploader_title_file"
+msgstr "Add File to %1$s %2$s"
+
+#: views/developers/uploader.thtml:50
+#, fuzzy
+msgid "devcp_uploader_title_submit"
+msgstr "Submit New Add-on"
+
+#. %s is the add-on name.
+#: views/developers/uploader.thtml:54
+#, fuzzy
+msgid "devcp_uploader_title_update"
+msgstr "Update %s"
+
+#. %s is a full <a> tag
+#: controllers/developers_controller.php:503
+#, php-format
+msgid "devcp_valid_app_reference"
+msgstr "Ð­Ð½Ñ %s нÑмÑлт зааврыг харна уу."
+
+#. This is the text in the <a> tag for devcp_valid_app_reference. This should be
+#. fixed.
+#: controllers/developers_controller.php:503
+msgid "devcp_valid_app_reference_linktext"
+msgstr "хуудаÑнааÑ"
+
+#: controllers/developers_controller.php:581
+#, fuzzy
+msgid "devcp_verify_author_error"
+msgstr "No account found for that email address."
+
+#: controllers/developers_controller.php:553
+#, fuzzy
+msgid "devcp_verify_search_engine_error"
+msgstr ""
+"Either the XML is invalid or required fields are missing. Please <a href="
+"\"https://developer.mozilla.org/en/Creating_OpenSearch_plugins_for_Firefox"
+"\">read the documentation</a>, verify your add-on, and try again."
+
+#: views/developers/versions.thtml:75
+#, fuzzy
+msgid "devcp_versions_a_cancel"
+msgstr "Cancel"
+
+#: views/developers/versions.thtml:79
+#, fuzzy
+msgid "devcp_versions_a_delete"
+msgstr "Delete Version"
+
+#: views/developers/versions.thtml:74
+#, fuzzy
+msgid "devcp_versions_a_empty"
+msgstr "Remove Empty Version"
+
+#: views/developers/versions.thtml:71
+#, fuzzy
+msgid "devcp_versions_a_remove"
+msgstr "Remove?"
+
+#: views/developers/versions.thtml:91
+#, fuzzy
+msgid "devcp_versions_add"
+msgstr "Add New Version"
+
+#: views/developers/versions_delete.thtml:58
+#, fuzzy
+msgid "devcp_versions_delete_a_cancel"
+msgstr "Cancel"
+
+#: views/developers/versions_delete.thtml:56
+#, fuzzy
+msgid "devcp_versions_delete_a_delete"
+msgstr "Delete Version"
+
+#. Followed by a list of reviews and files that will be removed.
+#: views/developers/versions_delete.thtml:50
+#, fuzzy
+msgid "devcp_versions_delete_also"
+msgstr "This will also delete:"
+
+#: views/developers/versions_delete.thtml:53
+#, fuzzy
+msgid "devcp_versions_delete_files"
+msgid_plural "devcp_versions_delete_files"
+msgstr[0] "%s file"
+msgstr[1] "%s files"
+
+#. %s is the version number.
+#: views/developers/versions_delete.thtml:48
+#, fuzzy
+msgid "devcp_versions_delete_header"
+msgstr "Delete Version %s?"
+
+#: views/developers/versions_delete.thtml:52
+#, fuzzy
+msgid "devcp_versions_delete_reviews"
+msgid_plural "devcp_versions_delete_reviews"
+msgstr[0] "%s review"
+msgstr[1] "%s reviews"
+
+#. %s is the version number.
+#: views/developers/versions_delete.thtml:49
+#, fuzzy
+msgid "devcp_versions_delete_sure"
+msgstr "Are you sure you want to permanently delete version %s?"
+
+#: views/developers/versions_edit.thtml:102
+#: views/developers/versions_edit.thtml:155
+#, fuzzy
+msgid "devcp_versions_edit_a_cancel"
+msgstr "Cancel"
+
+#: views/developers/versions_edit.thtml:101
+#, fuzzy
+msgid "devcp_versions_edit_a_delete"
+msgstr "Delete File"
+
+#: views/developers/versions_edit.thtml:165
+#, fuzzy
+msgid "devcp_versions_edit_a_new_app"
+msgstr "Add New Application"
+
+#: views/developers/versions_edit.thtml:154
+#, fuzzy
+msgid "devcp_versions_edit_a_remove_app"
+msgstr "Remove Application"
+
+#: views/developers/versions_edit.thtml:114
+#, fuzzy
+msgid "devcp_versions_edit_add"
+msgstr "Add New File"
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/versions_edit.thtml:121
+#, fuzzy
+msgid "devcp_versions_edit_adjust"
+msgstr ""
+"Adjusting application information here will allow users to install your add-"
+"on even if the install.rdf in the package indicates that the add-on is "
+"incompatible. <a %s>List of supported applications</a>"
+
+#: views/developers/versions_edit.thtml:153
+#, fuzzy
+msgid "devcp_versions_edit_compat_sure"
+msgstr ""
+"Are you <b>sure</b> you wish to remove compatibility with this application?"
+
+#: views/developers/versions_edit.thtml:100
+#, fuzzy
+msgid "devcp_versions_edit_delete_sure"
+msgstr "Are you <b>sure</b> you wish to permanently delete this file?"
+
+#: views/developers/versions_edit.thtml:203
+#, fuzzy
+msgid "devcp_versions_edit_header_approval"
+msgstr "Approval Information"
+
+#: views/developers/versions_edit.thtml:120
+#, fuzzy
+msgid "devcp_versions_edit_header_compat"
+msgstr "Compatible Applications"
+
+#: views/developers/versions_edit.thtml:74
+#, fuzzy
+msgid "devcp_versions_edit_header_file"
+msgstr "File Information"
+
+#: views/developers/versions_edit.thtml:189
+#, fuzzy
+msgid "devcp_versions_edit_header_license"
+msgstr "License"
+
+#. %s is the version number.
+#: views/developers/versions_edit.thtml:53
+#, fuzzy
+msgid "devcp_versions_edit_header_manage"
+msgstr "Manage Version %s"
+
+#: views/developers/versions_edit.thtml:212
+#, fuzzy
+msgid "devcp_versions_edit_header_notes"
+msgstr "Approval Notes"
+
+#: views/developers/versions_edit.thtml:98
+#, fuzzy
+msgid "devcp_versions_edit_img_delete"
+msgstr "Delete File"
+
+#. %1$s is the file id, e.g. 18723.
+#. %2$s is the platform name, e.g. ALL or Windows.
+#. %3$s is the _('date) created.
+#. %4$s is the status, e.g. "In Sandbox" or "Public".
+#. %5$s is the _('date') status was changed.
+#: views/developers/versions_edit.thtml:208
+#, fuzzy
+msgid "devcp_versions_edit_li_file"
+msgstr "File %1$s (%2$s) created on %3$s and changed to %4$s on %5$s"
+
+#: views/developers/versions_edit.thtml:190
+#, fuzzy
+msgid "devcp_versions_edit_license_description"
+msgstr ""
+"Please select the appropriate license for your add-on. This license "
+"specifies the rights you grant on your source code."
+
+#: views/developers/versions_edit.thtml:111
+#, fuzzy
+msgid "devcp_versions_edit_no_files"
+msgstr "No files found."
+
+#: views/developers/versions_edit.thtml:213
+#, fuzzy
+msgid "devcp_versions_edit_optional"
+msgstr "Optional information for the Editor that reviews this version."
+
+#: views/developers/versions_edit.thtml:151
+#, fuzzy
+msgid "devcp_versions_edit_remove_compat"
+msgstr "Remove Application Compatibility"
+
+#: views/developers/versions_edit.thtml:167
+#, fuzzy
+msgid "devcp_versions_edit_select_app"
+msgstr "Please Select an Application"
+
+#: views/developers/versions_edit.thtml:78
+#, fuzzy
+msgid "devcp_versions_edit_th_file"
+msgstr "File"
+
+#: views/developers/versions_edit.thtml:79
+#, fuzzy
+msgid "devcp_versions_edit_th_platform"
+msgstr "Platform"
+
+#: views/developers/versions_edit.thtml:80
+#, fuzzy
+msgid "devcp_versions_edit_th_size"
+msgstr "Size"
+
+#: views/developers/versions_edit.thtml:81
+#, fuzzy
+msgid "devcp_versions_edit_th_status"
+msgstr "Status"
+
+#: views/developers/versions_edit.thtml:183
+#, fuzzy
+msgid "devcp_versions_edit_transbox_releasenotes_description"
+msgstr ""
+"Information about changes in this release, new features, known bugs, and "
+"other useful information specific to this release/version. This information "
+"will also be available to users updating the add-on in the Firefox 3 Add-ons "
+"Manager interface."
+
+#: views/developers/versions_edit.thtml:182
+#, fuzzy
+msgid "devcp_versions_edit_transbox_releasenotes_name"
+msgstr "Release Notes"
+
+#: views/developers/versions_edit.thtml:164
+#, fuzzy
+msgid "devcp_versions_edit_unsaved_compat"
+msgstr ""
+"<strong>You have unsaved changes.</strong> Compatibility will not be deleted "
+"until you click Update Version below."
+
+#: views/developers/versions_edit.thtml:113
+#, fuzzy
+msgid "devcp_versions_edit_unsaved_files"
+msgstr ""
+"<strong>You have unsaved changes.</strong> Files will not be deleted until "
+"you click Update Version below."
+
+#: views/developers/versions_edit.thtml:218
+#, fuzzy
+msgid "devcp_versions_edit_update"
+msgstr "Update Versions"
+
+#: views/developers/versions.thtml:49
+#, fuzzy
+msgid "devcp_versions_header_manage"
+msgstr "Manage Versions and Files"
+
+#: views/developers/versions.thtml:87
+#, fuzzy
+msgid "devcp_versions_no_versions"
+msgstr "No versions."
+
+#. %s is a version number, base 10.
+#: views/developers/versions.thtml:46
+#, fuzzy
+msgid "devcp_versions_notice_success"
+msgstr "Version %s deleted successfully."
+
+#: views/developers/versions.thtml:73
+#, fuzzy
+msgid "devcp_versions_p_remove"
+msgstr ""
+"This version has no files associated with it and can be removed. Would you "
+"like to remove this version?"
+
+#: views/developers/versions.thtml:58
+#, fuzzy
+msgid "devcp_versions_th_created"
+msgstr "Created"
+
+#: views/developers/versions.thtml:57
+#, fuzzy
+msgid "devcp_versions_th_status"
+msgstr "Status"
+
+#: views/developers/versions.thtml:56
+#, fuzzy
+msgid "devcp_versions_th_version"
+msgstr "Version"
+
+#: controllers/downloads_controller.php:91
+msgid "downloads_disable_warning"
+msgstr "Ð­Ð½Ñ Ð½ÑмÑгдÑл хоригдÑон"
+
+#: controllers/components/editors.php:57
+#, fuzzy
+msgid "editor_review_error_addon_not_nominated"
+msgstr "This add-on has not been nominated."
+
+#: controllers/components/editors.php:213
+#, fuzzy
+msgid "editor_review_error_file_not_pending"
+msgstr "This file is not pending review."
+
+#. Actions are, for example: approving or rejecting
+#: controllers/components/editors.php:79
+#: controllers/components/editors.php:182
+#, fuzzy
+msgid "editor_review_error_no_action"
+msgstr "Please select a review action."
+
+#: controllers/components/editors.php:192
+#, fuzzy
+msgid "editor_review_error_no_applications"
+msgstr "Please enter the applications you tested."
+
+#. Comments are required when an editor approves or rejects an add-on.
+#: controllers/components/editors.php:84
+#: controllers/components/editors.php:187
+#, fuzzy
+msgid "editor_review_error_no_comments"
+msgstr "Please enter review comments."
+
+#: controllers/components/editors.php:161
+#, fuzzy
+msgid "editor_review_error_no_files"
+msgstr "Please select at least one file to review."
+
+#: controllers/components/editors.php:197
+#, fuzzy
+msgid "editor_review_error_no_operating_system"
+msgstr "Please enter the operating systems you tested."
+
+#: views/editors/logs.thtml:51
+msgid "editorcp_logs_button_filter"
+msgstr "Шүүлт"
+
+#: views/editors/logs.thtml:44
+msgid "editorcp_logs_filter_by"
+msgstr "Төрөл/ҮйлдлÑÑÑ€ нь шүүх"
+
+#: views/editors/logs.thtml:42 controllers/editors_controller.php:964
+msgid "editorcp_logs_page_heading"
+msgstr "Үйл Ñвдлын бүртгÑл бичлÑг"
+
+#: views/elements/developers/editorsmenu.thtml:60
+msgid "editorcp_menu_eventlog_link"
+msgstr "Үйл Ñвдлын бүртгÑл бичлÑг"
+
+#: views/elements/developers/editorsmenu.thtml:62
+msgid "editorcp_menu_mainpage_link"
+msgstr "ҮндÑÑн Ñ…ÑƒÑƒÐ´Ð°Ñ Ñ€ÑƒÑƒ буцах"
+
+#: views/elements/developers/editorsmenu.thtml:61
+msgid "editorcp_menu_reviewlog_link"
+msgstr "БүртгÑл бичлÑгийг харах"
+
+#: views/elements/developers/editorsmenu.thtml:55
+msgid "editorcp_menu_summary_link"
+msgstr "ЗаÑварлагчийн дүгнÑлт"
+
+#: views/elements/developers/editorsmenu.thtml:52
+msgid "editorcp_menu_title"
+msgstr "ЗаÑварлагчын багаж"
+
+#: views/editors/reviewlog.thtml:49
+msgid "editorcp_reviewlog_button_filter"
+msgstr "Шүүгч"
+
+#: views/editors/reviewlog.thtml:58
+msgid "editorcp_reviewlog_column_action"
+msgstr "ҮйлдÑл"
+
+#: views/editors/reviewlog.thtml:56
+msgid "editorcp_reviewlog_column_addon"
+msgstr "ÐÑмÑгдÑл"
+
+#: views/editors/reviewlog.thtml:55
+msgid "editorcp_reviewlog_column_date"
+msgstr "Огноо"
+
+#: views/editors/reviewlog.thtml:57
+msgid "editorcp_reviewlog_column_editor"
+msgstr "ЗаÑварлагч"
+
+#: views/editors/reviewlog.thtml:94
+msgid "editorcp_reviewlog_comments_hide"
+msgstr "СÑтгÑгдлийг нуу"
+
+#: views/editors/reviewlog.thtml:93
+msgid "editorcp_reviewlog_comments_show"
+msgstr "СÑтгÑгдлийг харуул"
+
+#. %1$s and %2$s are full <input> tags for dates
+#: views/editors/reviewlog.thtml:45
+#, php-format
+msgid "editorcp_reviewlog_entries_between"
+msgstr "%s-Ñ %s хүртÑлх оруулгыг харуул"
+
+#: views/editors/reviewlog.thtml:104
+msgid "editorcp_reviewlog_none_found"
+msgstr "Ð­Ð½Ñ Ñ…ÑƒÐ³Ð°Ñ†Ð°Ð°Ð½Ð´ Ñмар ч үнÑлгÑÑ Ð¾Ð»Ð´Ñонгүй."
+
+#: views/editors/reviewlog.thtml:42
+msgid "editorcp_reviewlog_page_heading"
+msgstr "Ð¥Ñнан шалгалтын бүртгÑл"
+
+#: views/editors/summary.thtml:61
+msgid "editorcp_summary_monthreviews_heading"
+msgstr "Сарын үнÑлгÑÑ"
+
+#: views/editors/summary.thtml:77
+msgid "editorcp_summary_neweditors_heading"
+msgstr "Ð¨Ð¸Ð½Ñ Ð·Ð°Ñварлагчид"
+
+#: views/editors/summary.thtml:42
+msgid "editorcp_summary_page_heading"
+msgstr "ЗаÑварлагчийн дүгнÑлт"
+
+#: views/editors/summary.thtml:94
+msgid "editorcp_summary_recentactivity_heading"
+msgstr "ЗаÑварлагчийн Ñүүлийн үеийн төлөв"
+
+#: views/editors/summary.thtml:45
+msgid "editorcp_summary_totalreviews_heading"
+msgstr "Ðийт үнÑлгÑÑ"
+
+#: controllers/editors_controller.php:248
+#: controllers/editors_controller.php:249
+msgid "editors_addon_review_pagetitle"
+msgstr "ÐÑмÑгдлийг үнÑлж дүгнÑÑ…"
+
+#: controllers/editors_controller.php:349
+msgid "editors_error_js-formerror"
+msgstr "Дараах талбаруудыг бөглөнө үү:"
+
+#: controllers/editors_controller.php:350
+msgid "editors_error_review_one_file"
+msgstr "Ядаж нÑг файлыг үнÑлж дүгнÑÑ…ÑÑÑ€ Ñонгоно уу."
+
+#: controllers/editors_controller.php:274
+msgid "editors_error_self_reviews_forbidden"
+msgstr "Ó¨Ó©Ñ€Ñдөө үнÑлж дүгнÑÑ… хориотой."
+
+#: controllers/editors_controller.php:699
+msgid "editors_external_software"
+msgstr "Гадаад програм"
+
+#: views/editors/featured.thtml:120 views/editors/featured.thtml:121
+msgid "editors_featured_add_feature"
+msgstr "Ð¨Ð¸Ð½Ñ Ñ‡Ð°Ð´Ð²Ð°Ñ€ нÑмÑÑ…"
+
+#: views/editors/featured.thtml:126
+msgid "editors_featured_add_feature_submit"
+msgstr "ÐÑм"
+
+#: views/editors/featured.thtml:49 controllers/editors_controller.php:832
+#: controllers/editors_controller.php:848
+msgid "editors_featured_addon_add_failure"
+msgstr "Чадвар нÑмÑÑ…Ñд алдаа гарав."
+
+#: controllers/editors_controller.php:851
+msgid "editors_featured_addon_add_success"
+msgstr "Чадварыг амжилттай нÑмÑв."
+
+#: views/editors/featured.thtml:50 controllers/editors_controller.php:839
+#: controllers/editors_controller.php:868
+#: controllers/editors_controller.php:886
+msgid "editors_featured_addon_edit_failure"
+msgstr "Чадварыг заÑварлахад алдаа гарав."
+
+#: views/editors/featured.thtml:51 controllers/editors_controller.php:888
+msgid "editors_featured_addon_edit_success"
+msgstr "Чадварыг амжилттай заÑварлав."
+
+#: views/editors/featured.thtml:53 controllers/editors_controller.php:861
+msgid "editors_featured_addon_invalid_locale"
+msgstr "ÐÑг юмуу ÑÑвÑл олон орон нутгийн тохиргоо буруу байна."
+
+#: views/editors/featured.thtml:52 controllers/editors_controller.php:906
+msgid "editors_featured_addon_remove_failure"
+msgstr "Чадварыг уÑтгахад алдаа гарав."
+
+#: controllers/editors_controller.php:901
+msgid "editors_featured_addon_remove_success"
+msgstr "Чадварыг амжилттай уÑтгав."
+
+#: controllers/editors_controller.php:915
+#: controllers/editors_controller.php:917
+msgid "editors_featured_addons_pagetitle"
+msgstr "Чадвараар хангагдÑан нÑмÑгдлүүд"
+
+#: views/editors/featured.thtml:54 views/editors/featured.thtml:107
+msgid "editors_featured_edit_feature_submit"
+msgstr "Очих"
+
+#: views/editors/featured.thtml:90 views/editors/featured.thtml:91
+msgid "editors_featured_remove_feature"
+msgstr "Чадварыг уÑтга"
+
+#: views/editors/queue.thtml:46
+msgid "editors_filter_queue"
+msgstr "Шүүлтүүрийн дараалал"
+
+#: views/editors/queue.thtml:182
+msgid "editors_helpful_links"
+msgstr "Ð¥ÑÑ€ÑгтÑй холбооÑууд"
+
+#: views/editors/queue.thtml:182
+msgid "editors_link_guide"
+msgstr "ЗаÑварлагчийн заавар"
+
+#: views/editors/queue.thtml:182
+msgid "editors_link_policy"
+msgstr "ÐÑмÑгдлийн журам"
+
+#: views/editors/queue.thtml:47
+msgid "editors_notice_filter_session"
+msgstr "ЭдгÑÑÑ€ шүүлтүүрүүд нь ÑÐ½Ñ Ñ…ÑÑÑгтÑÑ ÑÑвÑл арилгатал байрлах болно."
+
+#. %1 is the queue mode
+#: views/editors/queue.thtml:177 views/admin/flagged_queue.thtml:89
+msgid "editors_notice_none_found"
+msgstr "ДүгнÑлт хийгдÑÑ…ÑÑÑ€ %s доторх нÑмÑгдлүүд байхгүй байна."
+
+#: controllers/editors_controller.php:1040
+msgid "editors_one_day"
+msgstr "1 өдрийн"
+
+#: controllers/editors_controller.php:1048
+msgid "editors_one_hour"
+msgstr "1 цагийн"
+
+#: controllers/editors_controller.php:1056
+msgid "editors_one_minute"
+msgstr "1 минутын"
+
+#: controllers/editors_controller.php:64 controllers/editors_controller.php:73
+#: controllers/editors_controller.php:77
+msgid "editors_pagetitle"
+msgstr "ЗаÑварлагч Ñ…Ñнах Ñамбар"
+
+#. %s is a comma separated list of platforms. Example: Windows, OS X
+#: controllers/editors_controller.php:680
+#: controllers/editors_controller.php:683
+#, php-format
+msgid "editors_platform_x_only"
+msgstr "зөвхөн %s "
+
+#: controllers/editors_controller.php:695
+msgid "editors_pre-release"
+msgstr "УрьдчилÑан хувилбар"
+
+#. %1 is the app name
+#: views/editors/queue.thtml:131
+#, php-format
+msgid "editors_queue_app_compatibility"
+msgstr "%s-тай тохиромжтой"
+
+#: views/editors/queue.thtml:51
+#, fuzzy
+msgid "editors_queue_filter_label_addon"
+msgstr "Add-on or Author Email"
+
+#: views/editors/queue.thtml:72
+#, fuzzy
+msgid "editors_queue_filter_label_addontypes"
+msgstr "Add-on Types"
+
+#: views/editors/queue.thtml:56
+#, fuzzy
+msgid "editors_queue_filter_label_application"
+msgstr "Application"
+
+#: views/editors/queue.thtml:61
+#, fuzzy
+msgid "editors_queue_filter_label_maxversion"
+msgstr "Max. Version"
+
+#: views/editors/queue.thtml:78
+#, fuzzy
+msgid "editors_queue_filter_label_platforms"
+msgstr "Platforms"
+
+#: views/editors/queue.thtml:66
+#, fuzzy
+msgid "editors_queue_filter_label_submissionage"
+msgstr "Age of Submission (days)"
+
+#. %1$s is a number
+#: views/editors/queue.thtml:90
+#, fuzzy
+msgid "editors_queue_filter_result_count"
+msgid_plural "editors_queue_filter_result_count"
+msgstr[0] "Results of your filtered search: <strong>%1$s</strong> Add-on"
+msgstr[1] "Results of your filtered search: <strong>%1$s</strong> Add-ons"
+
+#: views/editors/queue.thtml:84
+msgid "editors_queue_submit_clean"
+msgstr "ЦÑвÑрхÑн"
+
+#: views/editors/queue.thtml:83
+msgid "editors_queue_submit_filter"
+msgstr "Шүүлтүүр"
+
+#: controllers/editors_controller.php:133
+msgid "editors_queues_disabled"
+msgstr "Одоогоор бүх үнÑлж дүгнÑÑ… дараалал хоригдÑон. Дараа дахин шалгана уу."
+
+#: views/editors/review.thtml:149
+#, fuzzy
+msgid "editors_review_a_edit_item"
+msgstr "Edit Item"
+
+#: views/editors/review.thtml:146
+#, fuzzy
+msgid "editors_review_a_item_history"
+msgstr "Item History"
+
+#: views/editors/review.thtml:148
+#, fuzzy
+msgid "editors_review_a_item_homepage"
+msgstr "Item Homepage"
+
+#: views/editors/review.thtml:145
+#, fuzzy
+msgid "editors_review_a_item_overview"
+msgstr "Item Overview"
+
+#: views/editors/review.thtml:147
+#, fuzzy
+msgid "editors_review_a_previews"
+msgstr "Previews"
+
+#: controllers/editors_controller.php:345
+msgid "editors_review_action"
+msgstr "ҮнÑлж дүгнÑÑ… Ñвц"
+
+#: views/editors/review.thtml:159
+#, fuzzy
+msgid "editors_review_action_info"
+msgstr "Request More Information"
+
+#: views/editors/review.thtml:157
+msgid "editors_review_action_public"
+msgstr "Ðийтийн Ñ…ÑƒÑƒÐ´Ð°Ñ Ñ€ÑƒÑƒ оруулах"
+
+#: views/editors/review.thtml:160
+msgid "editors_review_action_request_superreview"
+msgstr "Супер дүгнÑгчийн Ñ…Ò¯ÑÑлт"
+
+#: views/editors/review.thtml:158
+msgid "editors_review_action_sandbox"
+msgstr "Түр хайрцагт үлдÑÑÑ…"
+
+#: controllers/editors_controller.php:346
+msgid "editors_review_comments"
+msgstr "Тайлбарт үнÑлгÑÑ Ð´Ò¯Ð³Ð½Ñлт хийх"
+
+#: views/editors/review.thtml:182
+#, fuzzy
+msgid "editors_review_details_info_request"
+msgstr ""
+"Use this form to request more information from the author. They will receive "
+"an email and be able to answer here. You will be notified by email when they "
+"reply."
+
+#: views/editors/review.thtml:174
+msgid "editors_review_details_nominated_public"
+msgstr ""
+"Ð­Ð½Ñ Ð½ÑŒ нÑмÑгдÑл болон түүний хамгийн Ñүүлийн хувилбар ба файлуудыг олон "
+"нийтийн хуудÑанд Ñ‚ÑмдÑглÑдÑг. Дараагийн хувилбарууд нь завÑарлагчаар "
+"Ñ…Ñнагдах хүртÑл түр хайрцагт байрлах болно."
+
+#: views/editors/review.thtml:177
+msgid "editors_review_details_nominated_sandbox"
+msgstr "Ð­Ð½Ñ Ð½ÑŒ нÑмÑгдлийг түр хайрцагт үлдÑÑнÑ."
+
+#: views/editors/review.thtml:166
+msgid "editors_review_details_pending_public"
+msgstr ""
+"Ð­Ð½Ñ Ð½ÑŒ нийтийн түр байрлуулах хайрцагт буй нÑмÑгдлийн хувилбарыг нийтийн "
+"хуудÑанд харуулагдах Ñрх өгдөг."
+
+#: views/editors/review.thtml:169
+msgid "editors_review_details_pending_sandbox"
+msgstr ""
+"Ð­Ð½Ñ Ð½ÑŒ нийтийн түр байрлуулах хайрцагт буй нÑмÑгдлийн хувилбарыг түр "
+"хайрцагт үлдÑÑдÑг."
+
+#: views/editors/review.thtml:185
+msgid "editors_review_details_superreview"
+msgstr ""
+"Ð¥ÑÑ€Ñв та ÑÐ½Ñ Ð½ÑмÑгдлийн нууцлал юмуу ÑÑвÑл зохиогчийн ÑрхтÑй холбоотой "
+"зүйлүүд ÑÑвÑл админиÑтратор харах Ñ…ÑÑ€ÑгтÑй Ð·Ò¯Ð¹Ð»Ñ Ð±Ð°Ð¹Ð³Ð°Ð° гÑж бодож байгаа бол "
+"дараах талбарт бичÑÑÑ€Ñй. ТÑÑ€ нь зохиогч уруу биш админиÑтратор луу илгÑÑгдÑÑ… "
+"болно."
+
+#: views/editors/review.thtml:134
+#, fuzzy
+msgid "editors_review_file_diff_link"
+msgstr "Compare with public version"
+
+#: views/editors/review.thtml:131
+msgid "editors_review_file_viewcontents_link"
+msgstr "Бүрдлийг харах"
+
+#: views/editors/review.thtml:65
+msgid "editors_review_header_authors"
+msgstr "Зохиогч:"
+
+#: views/editors/review.thtml:79
+msgid "editors_review_header_categories"
+msgstr "Төрлүүд:"
+
+#: views/editors/review.thtml:92
+msgid "editors_review_header_compatibility"
+msgstr "Зохицох ÑиÑтемүүд:"
+
+#: views/editors/review.thtml:251
+msgid "editors_review_header_description"
+msgstr "Тодорхойлолт"
+
+#: views/editors/review.thtml:275
+msgid "editors_review_header_devcomments"
+msgstr "ХөгжүүлÑгчийн тайлбар"
+
+#: views/editors/review.thtml:263
+msgid "editors_review_header_eula"
+msgstr "EULA"
+
+#: views/editors/review.thtml:115
+msgid "editors_review_header_files"
+msgstr "Файлууд:"
+
+#: views/editors/review.thtml:284
+msgid "editors_review_header_itemhistory"
+msgstr "Түүх"
+
+#: views/editors/review.thtml:232
+msgid "editors_review_header_nominationmessage"
+msgstr "ÐÑÑ€ дÑвшүүлÑлтийн тодорхойлолт"
+
+#: views/editors/review.thtml:311
+msgid "editors_review_header_previews"
+msgstr "ҮзүүлбÑÑ€"
+
+#: views/editors/review.thtml:269
+msgid "editors_review_header_privacy"
+msgstr "Хувь хүнд холбогдох мÑдÑÑллийг хамгааалах журам"
+
+#. %1 is the add-on name and version
+#: views/editors/review.thtml:56
+#, php-format
+msgid "editors_review_header_review"
+msgstr "%s үнÑлгÑÑ Ð´Ò¯Ð³Ð½Ñлт хийх"
+
+#: views/editors/review.thtml:239
+msgid "editors_review_header_reviewernotes"
+msgstr "ҮнÑлÑгчдÑд зориулÑан Ñ‚ÑмдÑглÑл"
+
+#: views/editors/review.thtml:245
+msgid "editors_review_header_summary"
+msgstr "ÐÑгтгÑÑÑн мÑдÑÑлÑл"
+
+#: views/editors/review.thtml:257
+msgid "editors_review_header_versionnotes"
+msgstr "Хувилбарын Ñ‚ÑмдÑглÑл"
+
+#. a noun: shown in an add-on's editor review history
+#: views/elements/developers/editors_review_history_item.thtml:80
+#, fuzzy
+msgid "editors_review_history_info_reply"
+msgstr "Reply"
+
+#: views/elements/developers/editors_review_history_item.thtml:78
+#, fuzzy
+msgid "editors_review_history_info_request"
+msgstr "Information Request"
+
+#: views/elements/developers/editors_review_history_item.thtml:62
+#: views/editors/reviewlog.thtml:77
+msgid "editors_review_history_nominated_adminreview"
+msgstr "Зохицуулагчийн үнÑлгÑÑ"
+
+#: views/elements/developers/editors_review_history_item.thtml:56
+#: views/editors/reviewlog.thtml:71
+msgid "editors_review_history_nominated_approved"
+msgstr "ÐÑÑ€ дÑвшүүлÑлт зөвшөөрөгдÑөн/Ðийтийн хуудÑанд"
+
+#: views/elements/developers/editors_review_history_item.thtml:59
+#: views/editors/reviewlog.thtml:74
+msgid "editors_review_history_nominated_denied"
+msgstr "ÐÑÑ€ дÑвшүүлÑлт цуцлагдÑан/Түр хайрцагт"
+
+#: views/editors/review.thtml:303
+msgid "editors_review_history_nonefound"
+msgstr "Ямар ч өмнөх үнÑлгÑÑний оруулга олдÑонгүй."
+
+#: views/elements/developers/editors_review_history_item.thtml:73
+#: views/editors/reviewlog.thtml:88
+msgid "editors_review_history_pending_adminreview"
+msgstr "Зохицуулагчийн үнÑлгÑÑ"
+
+#: views/elements/developers/editors_review_history_item.thtml:67
+#: views/editors/reviewlog.thtml:82
+msgid "editors_review_history_pending_approved"
+msgstr "ЗөвшөөрөгдÑөн/Ðийтийн хуудÑанд"
+
+#: views/elements/developers/editors_review_history_item.thtml:70
+#: views/editors/reviewlog.thtml:85
+msgid "editors_review_history_pending_denied"
+msgstr "ЦуцлагдÑан/Түр хайрцагт"
+
+#. link text in an add-on's editor review history, allowing to hide and show an information request's replies
+#. %1 is the number of replies
+#: views/elements/developers/editors_review_history_item.thtml:90
+#, fuzzy
+msgid "editors_review_history_show_hide_replies"
+msgid_plural "editors_review_history_show_hide_replies"
+msgstr[0] "Show/Hide Replies (%1$s)"
+msgstr[1] "Show/Hide Replies (%1$s)"
+
+#: views/editors/review.thtml:208
+msgid "editors_review_label_applications"
+msgstr "Програмууд:"
+
+#: views/editors/review.thtml:196
+msgid "editors_review_label_cannedresponse"
+msgstr "ÑÑвÑл урьдчилан хадгалÑан хариулт Ñонгох:"
+
+#: views/editors/review.thtml:190
+msgid "editors_review_label_comments"
+msgstr "Тайлбар:"
+
+#: views/editors/review.thtml:204
+msgid "editors_review_label_operating_systems"
+msgstr "Үйлдлийн ÑиÑтемүүд:"
+
+#: views/editors/review.thtml:285 views/editors/review.thtml:312
+msgid "editors_review_link_pagetop"
+msgstr "ДÑÑд Ñ…ÑÑÑг Ñ€Ò¯Ò¯"
+
+#: views/editors/review.thtml:141
+#, fuzzy
+msgid "editors_review_mulitple_notice"
+msgstr ""
+"Notice: Only review more than one file if you have tested EVERY file you "
+"select."
+
+#: views/editors/review.thtml:51
+#, fuzzy
+msgid "editors_review_next_link"
+msgstr "next &raquo;"
+
+#: views/editors/review.thtml:322
+msgid "editors_review_previews_notfound"
+msgstr "ҮзүүлбÑÑ€ олдÑонгүй."
+
+#: views/editors/review.thtml:50
+#, fuzzy
+msgid "editors_review_previous_link"
+msgstr "&laquo; prev"
+
+#: controllers/editors_controller.php:144
+#: controllers/editors_controller.php:146
+msgid "editors_review_queue_pagetitle"
+msgstr "ҮнÑлгÑÑ Ð´Ò¯Ð³Ð½Ñлтийн дараалал"
+
+#. %1 is the add-ons rank in the queue, %2 is the total queue length
+#: views/editors/review.thtml:47
+#, fuzzy
+msgid "editors_review_rank_in_queue"
+msgstr "<strong># %1$s</strong> of %2$s in queue"
+
+#. %1 is the add-ons rank in the queue, %2 is the total queue length. Both numbers
+#: views/editors/review.thtml:45
+#, fuzzy
+msgid "editors_review_rank_in_queue_filtered"
+msgstr "<strong># %1$s</strong> of %2$s in queue (filtered)"
+
+#: views/editors/review.thtml:223
+msgid "editors_review_submit_process_action"
+msgstr "Үйлдлийн Ñвц"
+
+#: views/editors/review.thtml:293
+msgid "editors_review_th_action"
+msgstr "ҮйлдÑл"
+
+#: views/editors/review.thtml:294
+msgid "editors_review_th_comments"
+msgstr "Тайлбар"
+
+#: views/editors/review.thtml:291
+msgid "editors_review_th_date"
+msgstr "Огноо"
+
+#: views/editors/review.thtml:292
+msgid "editors_review_th_reviewer"
+msgstr "Ð¥Ñнаж дүгнÑÑÑн"
+
+#: views/editors/review.thtml:290
+msgid "editors_review_th_version_file"
+msgstr "Хувилбар/Файл"
+
+#: views/editors/review.thtml:217
+#, fuzzy
+msgid "editors_review_update_notify_once"
+msgstr ""
+"Notify me the next time this add-on is updated. (Subsequent updates will not "
+"generate an email)"
+
+#: controllers/editors_controller.php:298
+msgid "editors_reviewed_successfully"
+msgstr "Ð¥Ñнах дүгнÑлт амжилттай гүйцÑтгÑгдлÑÑ."
+
+#: views/editors/reviews_queue.thtml:106
+#, fuzzy
+msgid "editors_reviews_action_delete_review"
+msgstr "Delete review"
+
+#: views/editors/reviews_queue.thtml:104
+#, fuzzy
+msgid "editors_reviews_action_keep"
+msgstr "Remove flags; keep review"
+
+#: views/editors/reviews_queue.thtml:102
+msgid "editors_reviews_action_skip"
+msgstr "ÐлгаÑ"
+
+#: views/editors/reviews_queue.thtml:100
+msgid "editors_reviews_header_action"
+msgstr "ҮйлдÑл"
+
+#: views/editors/reviews_queue.thtml:67
+msgid "editors_reviews_in_reply_to"
+msgstr "Хариу:"
+
+#: controllers/editors_controller.php:748
+msgid "editors_reviews_processed"
+msgstr "Ð¥Ñналт дүгнÑлтүүд амжилттай гүйцÑтгÑгдлÑÑ!"
+
+#: views/editors/reviews_queue.thtml:117
+msgid "editors_reviews_queue_empty"
+msgstr "Ð¥Ñнаж дүгнÑÑ… ажил байхгүй байна."
+
+#: views/editors/reviews_queue.thtml:111
+msgid "editors_reviews_submit_process_reviews"
+msgstr "Ð¥Ñнаж дүгнÑлт хийх"
+
+#: controllers/editors_controller.php:691
+msgid "editors_site_specific"
+msgstr "ТуÑгай хуудÑанд зориулÑан"
+
+#: controllers/editors_controller.php:348
+msgid "editors_tested_app"
+msgstr "ШалгагдÑан програмууд"
+
+#: controllers/editors_controller.php:347
+msgid "editors_tested_os"
+msgstr "ШалгаÑан үйлдлийн ÑиÑтемүүд"
+
+#: views/editors/queue.thtml:151
+msgid "editors_th_additional_info"
+msgstr "ÐÑмÑлт мÑдÑÑлÑл"
+
+#: views/editors/featured.thtml:63 views/editors/queue.thtml:109
+#: views/admin/flagged_queue.thtml:53
+msgid "editors_th_addon"
+msgstr "ÐÑмÑгдÑл"
+
+#: views/editors/queue.thtml:125
+msgid "editors_th_addontype"
+msgstr "Төрөл"
+
+#: views/editors/featured.thtml:64
+msgid "editors_th_locales"
+msgstr "Орон нутагт нь Ñ…Ñзгаарлах уу?"
+
+#: views/editors/queue.thtml:148
+#, fuzzy
+msgid "editors_th_nomination_age"
+msgstr "Time in Queue"
+
+#: views/editors/queue.thtml:101 views/editors/queue.thtml:117
+#: views/editors/queue.thtml:144
+#, fuzzy
+msgid "editors_th_sort_ascending"
+msgstr "Ascending sort"
+
+#: views/editors/queue.thtml:105 views/editors/queue.thtml:121
+#: views/editors/queue.thtml:140
+#, fuzzy
+msgid "editors_th_sort_descending"
+msgstr "Descending sort"
+
+#. %s is a number
+#: controllers/editors_controller.php:1036
+#, php-format
+msgid "editors_x_days"
+msgstr "%s өдөр"
+
+#. %s is a number
+#: controllers/editors_controller.php:1044
+#, php-format
+msgid "editors_x_hours"
+msgstr "%s цаг"
+
+#. %s is a number
+#: controllers/editors_controller.php:1052
+#, php-format
+msgid "editors_x_minutes"
+msgstr "%s минут"
+
+#: views/errors/error401.thtml:50 controllers/components/simple_acl.php:81
+#: controllers/components/simple_acl.php:82
+#: controllers/components/simple_acl.php:83 controllers/components/amo.php:607
+#: controllers/components/amo.php:608 controllers/components/amo.php:609
+#: controllers/reviews_controller.php:353
+#: controllers/reviews_controller.php:485
+#: controllers/collections_controller.php:438
+#: controllers/collections_controller.php:496
+#: controllers/collections_controller.php:504
+#: controllers/collections_controller.php:971
+#: controllers/collections_controller.php:1034
+#: controllers/collections_controller.php:1077
+msgid "error_access_denied"
+msgstr "Хандах Ñрхгүй"
+
+#: views/errors/error401.thtml:52
+msgid "error_access_denied_message"
+msgstr "Танд ÑÐ½Ñ Ñ…ÑƒÑƒÐ´Ñыг үзÑÑ… Ñрх байхгүй байна."
+
+#: controllers/collections_controller.php:1039
+#, fuzzy
+msgid "error_addon_exists"
+msgstr "Add-on already exists!"
+
+#: controllers/developers_controller.php:200
+#: controllers/developers_controller.php:593
+#: controllers/developers_controller.php:1016
+#: controllers/developers_controller.php:1429
+#: controllers/downloads_controller.php:95
+#: controllers/downloads_controller.php:102
+#: controllers/downloads_controller.php:164
+#: controllers/statistics_controller.php:135
+#: controllers/previews_controller.php:115
+#: controllers/previews_controller.php:206
+#: controllers/previews_controller.php:307
+#: controllers/reviews_controller.php:77
+#: controllers/reviews_controller.php:240
+#: controllers/reviews_controller.php:332
+#: controllers/reviews_controller.php:340 controllers/api_controller.php:123
+#: controllers/api_controller.php:759 controllers/addons_controller.php:131
+#: controllers/addons_controller.php:197
+#: controllers/addons_controller.php:1407
+#: controllers/addons_controller.php:1465
+#: controllers/addons_controller.php:1469
+#: controllers/addons_controller.php:1503
+#: controllers/editors_controller.php:265
+#: controllers/collections_controller.php:1041
+#: controllers/collections_controller.php:1074
+msgid "error_addon_notfound"
+msgstr "ÐÑмÑгдÑл олдÑонгүй!"
+
+#: controllers/files_controller.php:83 controllers/files_controller.php:196
+msgid "error_addon_notviewable"
+msgstr "Ð­Ð½Ñ Ð½ÑмÑгдÑл Ñнд харуулагдах боломжгүй."
+
+#: controllers/reviews_controller.php:246
+#, fuzzy
+msgid "error_addon_selfreview"
+msgstr "You cannot review your own add-on."
+
+#: controllers/addons_controller.php:970
+msgid "error_browse_no_addons"
+msgstr "Ð­Ð½Ñ Ñ‚Ó©Ñ€Ó©Ð»Ð´ Ñмар ч нÑмÑгдÑл алга!"
+
+#: controllers/api_controller.php:424
+#, fuzzy
+msgid "error_collection_feed_notfound"
+msgstr "Add-on feed not found."
+
+#: views/users/register.thtml:65 views/users/edit.thtml:194
+msgid "error_email_invalid"
+msgstr "Ð­Ð½Ñ Ñ…Ò¯Ñ‡Ð¸Ð½Ñ‚Ñй захианы хаÑг биш байна."
+
+#: views/users/pwreset.thtml:74 views/users/register.thtml:70
+#: views/users/register.thtml:80 views/users/register.thtml:86
+#: views/users/edit.thtml:105 views/users/edit.thtml:111
+#: views/users/edit.thtml:192 views/admin/users_edit.thtml:78
+#: views/admin/users_edit.thtml:83 views/reviews/add.thtml:80
+#: views/reviews/add.thtml:104
+msgid "error_field_required"
+msgstr "Ð­Ð½Ñ Ñ‚Ð°Ð»Ð±Ð°Ñ€ хооÑон байх Ñ‘Ñгүй."
+
+#: controllers/files_controller.php:75 controllers/files_controller.php:93
+#: controllers/files_controller.php:96 controllers/files_controller.php:163
+#: controllers/files_controller.php:176 controllers/files_controller.php:185
+#: controllers/files_controller.php:204 controllers/editors_controller.php:412
+msgid "error_file_notfound"
+msgstr "Файл олдÑонгүй!"
+
+#. %s is a filename
+#: controllers/editors_controller.php:430
+#, php-format
+msgid "error_file_x_notfound"
+msgstr "Файлын алдаа: %s гÑж байхгүй байна."
+
+#: views/collections/add.thtml:55 views/collections/edit.thtml:89
+#: views/users/register.thtml:54 views/users/edit.thtml:81
+#: views/reviews/add.thtml:70 controllers/groups_controller.php:80
+#: controllers/groups_controller.php:102
+msgid "error_formerrors"
+msgstr "Ð­Ð½Ñ Ñ…Ò¯ÑнÑгтÑнд алдаа байна. ТÑдгÑÑрийг заÑаад дахин илгÑÑÐ½Ñ Ò¯Ò¯."
+
+#: views/users/register.thtml:109
+#, fuzzy
+msgid "error_invalid_captcha"
+msgstr "Invalid captcha, please try again!"
+
+#: views/users/register.thtml:100 views/users/edit.thtml:125
+#: views/admin/users_edit.thtml:101
+msgid "error_invalid_url"
+msgstr ""
+"Ð­Ð½Ñ Ñ…Ð°Ñг буруу Ñ…ÑлбÑршилтÑй байна. Зөв хаÑг http://example.com/my_page гÑÑÑн "
+"Ñ…ÑлбÑртÑй байдаг."
+
+#. %s is a string representing what's missing. Example: file_id
+#: controllers/downloads_controller.php:65
+#: controllers/users_controller.php:185 controllers/users_controller.php:264
+#: controllers/users_controller.php:559 controllers/users_controller.php:653
+#: controllers/reviews_controller.php:71
+#: controllers/reviews_controller.php:234
+#: controllers/reviews_controller.php:325
+#: controllers/reviews_controller.php:473
+#: controllers/reviews_controller.php:475
+#: controllers/addons_controller.php:182
+#: controllers/addons_controller.php:1381
+#: controllers/addons_controller.php:1455
+#: controllers/collections_controller.php:266
+#: controllers/collections_controller.php:285
+#: controllers/collections_controller.php:346
+#: controllers/collections_controller.php:443
+#: controllers/collections_controller.php:482
+#: controllers/collections_controller.php:936
+#: controllers/collections_controller.php:959
+#: controllers/collections_controller.php:960
+#: controllers/collections_controller.php:975
+#: controllers/collections_controller.php:977
+#: controllers/collections_controller.php:994
+#: controllers/collections_controller.php:1003
+#: controllers/collections_controller.php:1016
+#: controllers/collections_controller.php:1017
+#: controllers/collections_controller.php:1024
+#: controllers/collections_controller.php:1070
+#: controllers/collections_controller.php:1090
+#, php-format
+msgid "error_missing_argument"
+msgstr "Байхгүй байгаа аргументууд: %s"
+
+#: controllers/components/amo.php:507 controllers/components/amo.php:532
+#, fuzzy
+msgid "error_no_files_in_addon"
+msgstr "No Files"
+
+#: controllers/previews_controller.php:200
+msgid "error_preview_notfound"
+msgstr "ҮзүүлбÑÑ€ олдÑонгүй!"
+
+#: views/addons/display.thtml:400 views/reviews/add.thtml:98
+msgid "error_review_rating_required"
+msgstr "Та дүгнÑлт өгөхийг Ñонгох Ñ‘Ñтой."
+
+#: controllers/users_controller.php:160
+msgid "error_user_already_confirmed"
+msgstr "Ð­Ð½Ñ Ñ…ÑÑ€ÑглÑгчийн Ñрх өмнө нь батлагдÑан байна."
+
+#: controllers/users_controller.php:202 controllers/users_controller.php:276
+#: controllers/users_controller.php:569 controllers/users_controller.php:581
+#: controllers/users_controller.php:587 controllers/users_controller.php:610
+#: controllers/users_controller.php:627
+msgid "error_user_badconfirmationcode"
+msgstr "БүртгÑлийн буруу батлах код байна!"
+
+#: views/users/pwreset.thtml:79 views/users/register.thtml:75
+#: views/users/edit.thtml:183
+msgid "error_user_confirmpw_nomatch"
+msgstr "Ðууц үгнүүд ижил биш байна."
+
+#: views/users/register.thtml:65 views/users/edit.thtml:190
+#: controllers/users_controller.php:617
+msgid "error_user_email_notunique"
+msgstr "Ð­Ð½Ñ Ð·Ð°Ñ…Ð¸Ð°Ð½Ñ‹ хаÑг нь Ó©Ó©Ñ€ Ñ…ÑÑ€ÑглÑгчÑÑÑ€ өмнө нь бүртгÑгдÑÑн байна."
+
+#: controllers/users_controller.php:596
+msgid "error_user_emailchange_expired"
+msgstr ""
+"Захианы хаÑгаа Ñолих хугацаа тань Ñ…ÑÑ‚ÑÑ€ÑÑн байна. Ð¥ÑÑ€ÑглÑгчийн буланд очиж "
+"өөрийнхөө захианы хаÑгаа өөрчлөөд, батлах захиа ирÑнгүүт түүн дотор буй "
+"Ñ…Ð¾Ð»Ð±Ð¾Ð¾Ñ Ð´ÑÑÑ€ дарж баталгаажуулна уу."
+
+#: controllers/collections_controller.php:985
+#, fuzzy
+msgid "error_user_exists"
+msgstr ""
+"Users can only have one role at a time. Please remove the user from any "
+"existing roles before continuing."
+
+#: views/users/register.thtml:91 views/users/edit.thtml:116
+#: views/admin/users_edit.thtml:88
+msgid "error_user_nickname_notunique"
+msgstr "Ð­Ð½Ñ Ð½ÑÑ€ нь Ó©Ó©Ñ€ хүнÑÑÑ€ авагдÑан байна."
+
+#: views/users/pwreset.thtml:54 controllers/users_controller.php:191
+#: controllers/users_controller.php:270 controllers/users_controller.php:603
+#: controllers/users_controller.php:659
+#: controllers/collections_controller.php:988
+#: controllers/collections_controller.php:998
+msgid "error_user_notfound"
+msgstr "Ð¥ÑÑ€ÑглÑгч олдÑонгүй!"
+
+#: views/users/activatefirst.thtml:47
+msgid "error_user_unconfirmed"
+msgstr ""
+"Захиагаар хүлÑÑж авÑан батлах кодоор Ñ…ÑÑ€ÑглÑгчийн ÑрхÑÑ ÑхлÑÑд батлуулах "
+"Ñ‘Ñтой."
+
+#: views/users/login.thtml:67
+msgid "error_username_or_pw_wrong"
+msgstr "Ð¥ÑÑ€ÑглÑгчийн нÑÑ€ ÑÑвÑл нууц үг буруу байна!"
+
+#: controllers/editors_controller.php:260
+msgid "error_version_notfound"
+msgstr "Хувилбар олдÑонгүй!"
+
+#: views/users/delete.thtml:125 views/users/edit.thtml:173
+msgid "error_wrong_password"
+msgstr "Буруу нууц үг оруулÑан байна!"
+
+#: views/elements/amo2009/homepage_addon.thtml:122
+#: views/elements/feature.thtml:122
+msgid "feature_learnmore"
+msgstr "ÐÑмÑлт мÑдÑÑлÑл"
+
+#. %1 is the add-on name
+#: views/elements/amo2009/homepage_addon.thtml:123
+#: views/elements/feature.thtml:123
+#, php-format
+msgid "feature_learnmore_about_addon"
+msgstr "%1$s-н талаар нÑмж мÑдÑÑ…"
+
+#. %1$s is a number
+#: views/elements/amo2009/reviews.thtml:52
+#: views/elements/addon_listitem.thtml:112 views/elements/feature.thtml:99
+#: views/addons/browse_thumbs.thtml:86
+#, php-format
+msgid "feature_reviews"
+msgid_plural "feature_reviews"
+msgstr[0] "үнÑлгÑÑ"
+msgstr[1] "үнÑлгÑÑнүүд"
+
+#: views/elements/amo2009/homepage_addon.thtml:127
+#: views/elements/feature.thtml:127
+msgid "feature_view_more_from_category"
+msgstr "ДÑлгÑÑ€Ñнгүй харах"
+
+#. This appears on a page that views the source of an add-on. This link will return
+#. the user to the add-on's main page
+#: views/files/browse.thtml:65
+#, fuzzy
+msgid "file_browser_link_addon"
+msgstr "Back to add-on"
+
+#. There is a list of directories and files on the page. Clicking this will show the
+#. contents of all the directories (normally you would click on each one to see the
+#. contents)
+#: views/files/browse.thtml:67
+#, fuzzy
+msgid "file_browser_link_expand_all"
+msgstr "Expand all"
+
+#. This appears on a page that views the source of an add-on. This link will return
+#. the user to the add-on's review page (it only appears if the add-on is being
+#. reviewed)
+#: views/files/browse.thtml:64
+#, fuzzy
+msgid "file_browser_link_review"
+msgstr "Back to review"
+
+#. The title of the page for viewing an add-on's source.
+#. %1$s is the name of the add-on
+#. %2$s is the name of the current application (e.g. Firefox or Thunderbird)
+#: views/files/browse.thtml:46
+#, fuzzy
+msgid "file_browser_title"
+msgstr "%1$s :: File Browser :: %2$s Add-ons"
+
+#. This appears on a page that views the source of an add-on. There is a list of
+#. directories and files on the page. Clicking this link will toggle between an
+#. expanded or a collapsed list. This string should be kept short.
+#: views/files/browse.thtml:68
+#, fuzzy
+msgid "file_browser_toggle_expand_collapse"
+msgstr "+/-"
+
+#. Link text for the AMO About page.
+#: views/elements/footer.thtml:72 views/layouts/amo2009.thtml:341
+#, fuzzy
+msgid "footer_a_about"
+msgstr "About"
+
+#. Link text to the AMO blog.
+#: views/elements/footer.thtml:74 views/layouts/amo2009.thtml:343
+#, fuzzy
+msgid "footer_a_blog"
+msgstr "Blog"
+
+#. Link text to the Frequently Asked Questions page.
+#: views/elements/footer.thtml:73 views/layouts/amo2009.thtml:342
+#, fuzzy
+msgid "footer_a_faq"
+msgstr "FAQ"
+
+#. Full text for the FAQ abbreviation.
+#: views/elements/footer.thtml:73 views/pages/collector_features.thtml:72
+#: views/layouts/amo2009.thtml:342
+#, fuzzy
+msgid "footer_abbr_faq"
+msgstr "Frequently Asked Questions"
+
+#: views/elements/footer.thtml:67 views/layouts/amo2009.thtml:336
+msgid "footer_all_rights_reserved"
+msgstr "Бүх Ñрх хуулиар хамгаалагдÑан."
+
+#: views/elements/footer.thtml:67 views/layouts/amo2009.thtml:336
+msgid "footer_copyright"
+msgstr "Зохиогчийн Ñрх"
+
+#: views/elements/footer.thtml:71 views/layouts/amo2009.thtml:340
+msgid "footer_credits"
+msgstr "Зохиогчид"
+
+#: views/elements/footer.thtml:76 views/layouts/amo2009.thtml:346
+msgid "footer_disclaimer"
+msgstr ""
+"Мозила нь ÑдгÑÑÑ€ холбооÑыг танд туÑламж болгох зориулалтаар үзүүлж байгаа "
+"бөгөөд програмтай холбоотой Ñмар ч Ñурталчилгаа юмуу Ñмар нÑгÑн холбогдох "
+"мÑдÑÑллÑÑÑ€ хангаагүй болно. Програмтай холбоотой аÑуулт, гомдол Ñ…Ò¯ÑÑл байвал "
+"програм зохиогчид уруу нь илгÑÑÑ… Ñ…ÑÑ€ÑгтÑй."
+
+#: views/elements/footer.thtml:61 views/layouts/amo2009.thtml:332
+msgid "footer_lang_form_lang_submit_go"
+msgstr "Оч"
+
+#: views/elements/footer.thtml:70 views/layouts/amo2009.thtml:339
+msgid "footer_legal_notices"
+msgstr "Хуулийн анхааруулга"
+
+#: views/elements/footer.thtml:50 views/layouts/amo2009.thtml:321
+msgid "footer_other_languages"
+msgstr "БуÑад Ñ…Ñл дÑÑÑ€:"
+
+#: views/elements/footer.thtml:69 views/layouts/amo2009.thtml:338
+msgid "footer_privacy_policy"
+msgstr "Хувь хүнд холбогдолтой мÑдÑÑллийг хамгаалах журам"
+
+#: models/addontype.php:79
+msgid "general_addontype_dict"
+msgstr "Үгийн Ñан"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:100
+msgid "general_addontype_dict_plural"
+msgstr "Үгийн Ñангууд"
+
+#: models/addontype.php:75
+msgid "general_addontype_extension"
+msgstr "Өргөтгөл"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:98
+msgid "general_addontype_extension_plural"
+msgstr "Өргөтгөлүүд"
+
+#: models/addontype.php:85
+msgid "general_addontype_lpaddon"
+msgstr "Ð¥Ñлний багц (ÐÑмÑгдлийн)"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:103
+msgid "general_addontype_lpaddon_plural"
+msgstr "Ð¥Ñлний багцнууд (ÐÑмÑгдлийн)"
+
+#: models/addontype.php:83
+msgid "general_addontype_lpapp"
+msgstr "Ð¥Ñлний багц (Програмын)"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:102
+msgid "general_addontype_lpapp_plural"
+msgstr "Ð¥Ñлний багцнууд (Програмын)"
+
+#: models/addontype.php:87
+msgid "general_addontype_plugin"
+msgstr "Плагин"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:104
+msgid "general_addontype_plugin_plural"
+msgstr "Плагинууд"
+
+#: models/addontype.php:81
+msgid "general_addontype_search"
+msgstr "Ð’Ñбд хайгч"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:101
+msgid "general_addontype_search_plural"
+msgstr "Ð’Ñбд хайгчид"
+
+#: models/addontype.php:77
+msgid "general_addontype_theme"
+msgstr "Харуулах маÑг"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:99
+msgid "general_addontype_theme_plural"
+msgstr "Харуулах маÑгууд"
+
+#: config/language.php:367
+#, fuzzy
+msgid "general_languages_all_locales"
+msgstr "All Locales"
+
+#: views/layouts/amo2009.thtml:249
+#, fuzzy
+msgid "header_brand_name"
+msgstr "Mozilla"
+
+#. %1$s is the application name. Example: Firefox
+#: views/elements/header.thtml:111 views/elements/header.thtml:122
+#: views/layouts/amo2009.thtml:248
+#, php-format
+msgid "header_home_tooltip"
+msgstr "%1$s нÑмÑгдлийн Ñ…ÑƒÑƒÐ´Ð°Ñ Ñ€ÑƒÑƒ буцах"
+
+#: views/elements/header.thtml:87
+msgid "header_main_firefox_header"
+msgstr "Firefox нÑмÑгдлүүд"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:218
+#, fuzzy
+msgid "header_main_firefox_header_with_logo"
+msgstr ""
+"Add-ons <em>for</em> <img alt=\"Firefox\" src=\"%1$s\" /> <strong>Firefox</"
+"strong>"
+
+#: views/elements/header.thtml:99
+msgid "header_main_header"
+msgstr "ÐÑмÑгдлүүд"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:242
+#, fuzzy
+msgid "header_main_header_with_logo"
+msgstr "Add-ons <img alt=\"Add-ons\" src=\"%1$s\" />"
+
+#: views/elements/header.thtml:90
+msgid "header_main_seamonkey_header"
+msgstr "Seamonkey нÑмÑгдлүүд"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:224
+#, fuzzy
+msgid "header_main_seamonkey_header_with_logo"
+msgstr ""
+"Add-ons <em>for</em> <img alt=\"seamonkey\" src=\"%1$s\" /> "
+"<strong>SeaMonkey</strong>"
+
+#: views/elements/header.thtml:93
+msgid "header_main_sunbird_header"
+msgstr "Sunbird нÑмÑгдлүүд"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:230
+#, fuzzy
+msgid "header_main_sunbird_header_with_logo"
+msgstr ""
+"Add-ons <em>for</em> <img alt=\"sunbird\" src=\"%1$s\" /> <strong>Sunbird</"
+"strong>"
+
+#: views/elements/header.thtml:96
+msgid "header_main_thunderbird_header"
+msgstr "Thunderbird нÑмÑгдлүүд"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:236
+#, fuzzy
+msgid "header_main_thunderbird_header_with_logo"
+msgstr ""
+"Add-ons <em>for</em> <img alt=\"thunderbird\" src=\"%1$s\" /> "
+"<strong>Thunderbird</strong>"
+
+#: views/layouts/amo2009.thtml:205
+#, fuzzy
+msgid "header_navaccess_applications_menu"
+msgstr "Skip to other applications menu"
+
+#: views/layouts/amo2009.thtml:204
+#, fuzzy
+msgid "header_navaccess_categories_menu"
+msgstr "Skip to categories menu"
+
+#: views/layouts/amo2009.thtml:202
+#, fuzzy
+msgid "header_navaccess_main_content"
+msgstr "Skip to main content"
+
+#: views/layouts/amo2009.thtml:203
+#, fuzzy
+msgid "header_navaccess_search_form"
+msgstr "Skip to search form"
+
+#: views/elements/header.thtml:62
+msgid "header_navlink_addons"
+msgstr "ÐÑмÑгдлүүд"
+
+#: views/elements/developers/sidebar.thtml:72
+#: views/elements/developers/myaddons.thtml:50 views/elements/header.thtml:159
+#: views/addons/display.thtml:378
+msgid "header_navlink_login"
+msgstr "ÐÑвтрÑÑ…"
+
+#: views/elements/header.thtml:156 views/layouts/amo2009.thtml:304
+msgid "header_navlink_logout"
+msgstr "Гарах"
+
+#: views/elements/header.thtml:145 views/layouts/amo2009.thtml:303
+msgid "header_navlink_myaccount"
+msgstr "Миний бүртгÑл"
+
+#: views/elements/header.thtml:158
+msgid "header_navlink_register"
+msgstr "БүртгүүлÑÑ…"
+
+#. %1 is the URL to the registration page
+#. %2 is the URL to the login page
+#: views/layouts/amo2009.thtml:278
+#, fuzzy
+msgid "header_navlink_register_or_login"
+msgstr "<a href=\"%1$s\">Register</a> or <a href=\"%2$s\">Log in</a>"
+
+#: views/layouts/amo2009.thtml:285
+#, fuzzy
+msgid "header_navlink_tools"
+msgstr "Tools"
+
+#. %s is the add-on name
+#: views/elements/collections_interactive_addon.thtml:62
+#: views/elements/amo2009/homepage_addon.thtml:77
+#: views/elements/addon_discussionheader.thtml:62
+#: views/elements/addon_listitem.thtml:67 views/elements/feature.thtml:84
+#: views/addons/category_landing.thtml:87 views/addons/browse_thumbs.thtml:60
+#, php-format
+msgid "img_preview_of"
+msgstr "%s-н үзүүлбÑÑ€ зураг"
+
+#. %1 is the login URL for the link tag
+#. %2 is the link to an explanatory page.
+#: views/elements/amo2009/install.thtml:307 views/elements/install.thtml:255
+msgid "install_a_login_to_install"
+msgstr ""
+"Та ÑÐ½Ñ Ð½ÑмÑгдлийг Ñуулгахын тулд <a href=\"%1$s\">нÑвтрÑÑ…</a> үйлдÑл хийх "
+"Ñ…ÑÑ€ÑгтÑй"
+
+#. %1 is the URL for the Experimental Add-ons section of the FAQ page
+#: views/elements/amo2009/install.thtml:283 views/elements/install.thtml:232
+#, fuzzy
+msgid "install_button_confirm_exp_install"
+msgstr ""
+"Let me install this experimental add-on. <a href=\"%1$s\">What's this?</a>"
+
+#. %1$s is the application name. Example: Firefox
+#. %2$s is an optional string used to specify a platform. Example: (Windows)
+#: views/elements/amo2009/install.thtml:128 views/elements/install.thtml:75
+#, php-format
+msgid "install_button_text"
+msgstr "%s %s руу нÑм"
+
+#. %1 is the add-on name, %2 is the app name
+#: views/elements/amo2009/install.thtml:191
+#: views/elements/amo2009/install.thtml:206
+#: views/elements/amo2009/install.thtml:249
+#: views/elements/amo2009/install.thtml:298 views/elements/install.thtml:150
+#: views/elements/install.thtml:165 views/elements/install.thtml:202
+#: views/elements/install.thtml:246
+#, php-format
+msgid "install_button_title"
+msgstr "%1$s-г %2$s руу нÑм"
+
+#. %1$s is the add-on name
+#: views/elements/amo2009/install.thtml:200 views/elements/install.thtml:159
+#, php-format
+msgid "install_download"
+msgstr "%1$s-г татаж ав"
+
+#: views/elements/amo2009/install.thtml:147 views/elements/install.thtml:94
+msgid "install_error_addon_not_found"
+msgstr "Ð­Ð½Ñ Ð½ÑмÑгдÑл боломжгүй байна."
+
+#: views/addons/dictionaries.thtml:65
+msgid "langtools_a11y_tablesummary"
+msgstr "Ð¥Ñлний багц болон үгийн Ñангийн жагÑаалт."
+
+#: views/addons/dictionaries.thtml:47
+msgid "langtools_download_dictionary"
+msgstr "Үгийн Ñан татаж авах"
+
+#: views/addons/dictionaries.thtml:48
+msgid "langtools_download_langpack"
+msgstr "Ð¥Ñлний багц татаж авах"
+
+#: views/addons/dictionaries.thtml:63 controllers/components/amo.php:685
+#: controllers/addons_controller.php:1239
+msgid "langtools_header_dicts_and_langpacks"
+msgstr "Үгийн Ñан болон Ñ…Ñлний багц"
+
+#: views/addons/dictionaries.thtml:44
+msgid "langtools_install_dictionary"
+msgstr "Үгийн Ñанг Ñуулга"
+
+#: views/addons/dictionaries.thtml:45
+msgid "langtools_install_langpack"
+msgstr "Ð¥Ñлний багцыг Ñуулга"
+
+#: views/addons/dictionaries.thtml:69
+msgid "langtools_tableheader_dictionary"
+msgstr "Үгийн Ñан"
+
+#: views/addons/dictionaries.thtml:70
+msgid "langtools_tableheader_langpack"
+msgstr "Ð¥Ñлний багц"
+
+#: views/addons/dictionaries.thtml:68
+msgid "langtools_tableheader_language"
+msgstr "Ð¥Ñл"
+
+#: models/license.php:65
+#, fuzzy
+msgid "license_custom"
+msgstr "Custom License"
+
+#: config/bootstrap.php:303
+#, fuzzy
+msgid "licenses_bsd"
+msgstr "BSD License"
+
+#: config/bootstrap.php:298
+#, fuzzy
+msgid "licenses_gpl_2.0"
+msgstr "GNU General Public License, version 2.0"
+
+#: config/bootstrap.php:299
+#, fuzzy
+msgid "licenses_gpl_3.0"
+msgstr "GNU General Public License, version 3.0"
+
+#: config/bootstrap.php:300
+#, fuzzy
+msgid "licenses_lgpl_2.1"
+msgstr "GNU Lesser General Public License, version 2.1"
+
+#: config/bootstrap.php:301
+#, fuzzy
+msgid "licenses_lgpl_3.0"
+msgstr "GNU Lesser General Public License, version 3.0"
+
+#: config/bootstrap.php:302
+#, fuzzy
+msgid "licenses_mit"
+msgstr "MIT/X11 License"
+
+#: config/bootstrap.php:297
+#, fuzzy
+msgid "licenses_mpl_1.1"
+msgstr "Mozilla Public License, version 1.1"
+
+#: views/users/emailchange.thtml:51 views/users/delete.thtml:55
+#: views/users/delete.thtml:137 views/users/edit.thtml:74
+#: views/reviews/flag.thtml:54
+msgid "link_return_to_front_page"
+msgstr "Энд дарж ÑхлÑл Ñ…ÑƒÑƒÐ´Ð°Ñ Ñ€ÑƒÑƒ буцна уу."
+
+#: views/elements/amo2009/addon_list_options.thtml:46
+#: views/elements/addon_list_options.thtml:46
+msgid "list_sortby_date"
+msgstr "Огноо"
+
+#: views/elements/amo2009/addon_list_options.thtml:47
+#: views/elements/addon_list_options.thtml:47
+msgid "list_sortby_downloads"
+msgstr "Татаж авалт"
+
+#: views/elements/amo2009/addon_list_options.thtml:45
+#: views/elements/addon_list_options.thtml:45
+msgid "list_sortby_name"
+msgstr "ÐÑмÑгдлийн нÑÑ€"
+
+#: views/elements/amo2009/addon_list_options.thtml:48
+#: views/elements/addon_list_options.thtml:48
+msgid "list_sortby_rating"
+msgstr "ҮнÑлгÑÑ"
+
+#: config/bootstrap.php:278
+#, fuzzy
+msgid "main_prettyname_fennec"
+msgstr "Fennec"
+
+#: config/bootstrap.php:274
+msgid "main_prettyname_firefox"
+msgstr "Firefox"
+
+#: config/bootstrap.php:277
+msgid "main_prettyname_seamonkey"
+msgstr "SeaMonkey"
+
+#: config/bootstrap.php:276
+msgid "main_prettyname_sunbird"
+msgstr "Sunbird"
+
+#: config/bootstrap.php:275
+msgid "main_prettyname_thunderbird"
+msgstr "Thunderbird"
+
+#: views/elements/addon_categories.thtml:52
+msgid "nav_category_dicts_langpacks"
+msgstr "Үгийн Ñан болон Ñ…Ñлний багцнууд"
+
+#: views/elements/addon_categories.thtml:55
+msgid "nav_category_themes"
+msgstr "Харуулах маÑгууд"
+
+#: views/elements/app_chooser.thtml:47 views/layouts/amo2009.thtml:255
+#, fuzzy
+msgid "other_apps_tooltip"
+msgstr "Find add-ons for other applications"
+
+#. In a user list: user 1, user 2, "others"
+#: views/helpers/addons_html.php:222
+msgid "other_users"
+msgstr "буÑад"
+
+#: controllers/pages_controller.php:90
+#, fuzzy
+msgid "page_title_appversions"
+msgstr "Application Versions"
+
+#: controllers/pages_controller.php:115
+#, fuzzy
+msgid "page_title_collector"
+msgstr "Add-on Collector"
+
+#: controllers/pages_controller.php:117
+#, fuzzy
+msgid "page_title_collector_faq"
+msgstr "Add-on Collector FAQ"
+
+#: controllers/pages_controller.php:119
+#, fuzzy
+msgid "page_title_collector_features"
+msgstr "Add-on Collector Features"
+
+#: controllers/pages_controller.php:122
+#, fuzzy
+msgid "page_title_collector_firstrun"
+msgstr "Welcome to the Add-on Collector"
+
+#: controllers/pages_controller.php:92
+#, fuzzy
+msgid "page_title_credits"
+msgstr "Credits"
+
+#: controllers/pages_controller.php:113
+#, fuzzy
+msgid "page_title_developer_faq"
+msgstr "Developer FAQ"
+
+#: controllers/pages_controller.php:111
+#, fuzzy
+msgid "page_title_faq"
+msgstr "Frequently Asked Questions"
+
+#: controllers/pages_controller.php:94
+#, fuzzy
+msgid "page_title_fashionyourfirefox_faq"
+msgstr "Fashion your Firefox FAQ"
+
+#: controllers/pages_controller.php:101
+#, fuzzy
+msgid "page_title_policy"
+msgstr "Add-ons Policy"
+
+#: controllers/pages_controller.php:103
+#, fuzzy
+msgid "page_title_privacy"
+msgstr "Mozilla Privacy Policy"
+
+#: controllers/pages_controller.php:105
+#, fuzzy
+msgid "page_title_review_guide"
+msgstr "Review Guidelines"
+
+#: controllers/pages_controller.php:107
+#, fuzzy
+msgid "page_title_sandbox"
+msgstr "Sandbox Review System"
+
+#: controllers/pages_controller.php:109
+#, fuzzy
+msgid "page_title_submissionhelp"
+msgstr "Submission Help"
+
+#: views/pages/appversions.thtml:87
+msgid "pages_appversions_guid"
+msgstr "GUID"
+
+#: views/pages/appversions.thtml:79 controllers/pages_controller.php:90
+msgid "pages_appversions_header"
+msgstr "Програмын хүчинтÑй хувилбар"
+
+#: views/pages/appversions.thtml:80
+msgid "pages_appversions_intro"
+msgstr ""
+"Мозилагийн нÑмÑгдÑл Ñ€Ò¯Ò¯ илгÑÑгдÑж буй нÑмÑгдлүүд нь дараах програмуудын Ñдаж "
+"нÑгÑнд нь тохирох install.rdf файлтай байх Ñ‘Ñтой. Доорх харуулÑан хувилбарын "
+"жагÑаалт Ñ‚ÑдгÑÑÑ€ програмд тохиромжтой байна."
+
+#. %s is a full <a> tag
+#: views/pages/appversions.thtml:93
+#, php-format
+msgid "pages_appversions_required_files"
+msgstr ""
+"Ð¥ÑÑ€Ñв таны програмд install.rdf файл шаардлагаггүй бол, тийм байÑан ч гÑÑÑн "
+"та %s зааÑан шаардлагатай шинж чанаруудыг агуулÑан байх Ñ‘Ñтой."
+
+#. this is the text inside of an <a> tag for pages_appversions_required_files. This
+#. should be fixed.
+#: views/pages/appversions.thtml:93
+msgid "pages_appversions_required_files_link"
+msgstr "Ñнд"
+
+#: views/pages/appversions.thtml:88
+msgid "pages_appversions_versions"
+msgstr "Хувилбарууд"
+
+#: views/pages/policy.thtml:51
+msgid "pages_policy_sandbox_link"
+msgstr "Түр хайрцгийн мÑдÑÑллийн хуудаÑ"
+
+#: views/elements/pagination.thtml:53
+msgid "pagination_next_page"
+msgstr "дараах"
+
+#: views/elements/pagination.thtml:52
+msgid "pagination_previous_page"
+msgstr "өмнөх"
+
+#: views/elements/recaptcha.thtml:65
+#, fuzzy
+msgid "recaptcha_enter_both_words"
+msgstr ""
+"Please enter <strong>both words</strong> below, <strong>separated by a "
+"space</strong>."
+
+#: views/elements/recaptcha.thtml:83
+#, fuzzy
+msgid "recaptcha_enter_here"
+msgstr "Enter your answer here:"
+
+#: views/elements/recaptcha.thtml:74
+#, fuzzy
+msgid "recaptcha_enter_whatyouhear"
+msgstr "Please type what you hear."
+
+#. %1 is the link switching refreshing the captcha
+#. %2 is the link switching to a text captcha
+#: views/elements/recaptcha.thtml:77
+#, fuzzy
+msgid "recaptcha_hardtohear_text"
+msgstr ""
+"If this is hard to understand, you can <a href=\"%1$s\">listen to something "
+"else</a> or <a href=\"%2$s\">switch back to text</a>."
+
+#. %1 is the link switching refreshing the captcha
+#. %2 is the link switching to an audio captcha
+#: views/elements/recaptcha.thtml:68
+#, fuzzy
+msgid "recaptcha_hardtoread_text"
+msgstr ""
+"If this is hard to read, you can <a href=\"%1$s\">try different words</a> or "
+"<a href=\"%2$s\">listen to something</a> instead."
+
+#: views/users/register.thtml:105
+#, fuzzy
+msgid "recaptcha_label"
+msgstr "Are you human?"
+
+#: views/users/register.thtml:106
+#, fuzzy
+msgid "recaptcha_whatsthis"
+msgstr "What's this?"
+
+#: controllers/reviews_controller.php:559
+msgid "review_flag_error"
+msgstr "Ð­Ð½Ñ Ò¯Ð½ÑлгÑÑний Ñ‚ÑмдÑглÑлд алдаа гарлаа!"
+
+#: models/reviews_moderation_flag.php:69
+#, fuzzy
+msgid "review_flag_reason_bug_support"
+msgstr "Misplaced bug report or support request"
+
+#: views/reviews/display.thtml:103 views/reviews/display.thtml:186
+#, fuzzy
+msgid "review_flag_reason_instructions"
+msgstr "Report this review (select a reason)"
+
+#: models/reviews_moderation_flag.php:67
+#, fuzzy
+msgid "review_flag_reason_language"
+msgstr "Inappropriate language/dialog"
+
+#: models/reviews_moderation_flag.php:71
+#, fuzzy
+msgid "review_flag_reason_other"
+msgstr "Other (please specify)"
+
+#: models/reviews_moderation_flag.php:65
+#, fuzzy
+msgid "review_flag_reason_spam"
+msgstr "Spam or otherwise non-review content"
+
+#: views/reviews/display.thtml:91 views/reviews/display.thtml:175
+#: controllers/reviews_controller.php:555
+msgid "review_flag_success"
+msgstr ""
+"Танд баÑрлалаа, ÑÐ½Ñ Ò¯Ð½ÑлгÑÑ Ð½ÑŒ заÑварлагчаар зөвшөөрөгдөхөөр Ñ‚ÑмдÑглÑгдÑв."
+
+#: views/reviews/display.thtml:41
+msgid "review_flag_this"
+msgstr "Ð­Ð½Ñ Ò¯Ð½ÑлгÑÑг мÑдÑÑлÑÑ…"
+
+#: views/reviews/display.thtml:42
+msgid "review_flag_this_titletip"
+msgstr ""
+"Ð­Ð½Ñ Ò¯Ð½ÑлгÑÑ Ð½ÑŒ зөв биш, тодорхой биш, ÑÑвÑл дÑмий зүйл байна уу? Энд дарж "
+"заÑварлагчаар Ñ…Ñнуулахаар Ñ‚ÑмдÑглÑÐ½Ñ Ò¯Ò¯."
+
+#. %1 is the URL of the support section, %2 for the review guidelines
+#: views/reviews/add.thtml:53
+#, fuzzy
+msgid "review_guidelines_short"
+msgstr ""
+"<p>Keep these tips in mind:</p><ul><li>Write like you're telling a friend "
+"about your experience with the add-on. Give specifics and helpful details, "
+"such as what features you liked and/ordisliked, how easy to use it is, and "
+"any disadvantages it has. Avoid genericlanguage such as calling it \"Great"
+"\" or \"Bad\" unless you can give reasons whyyou believe this is so.</"
+"li><li>Please do not post bug reports in reviews. We do not make your email "
+"address available to add-on developers and they may need to contact you to "
+"help resolveyour issue. See the <a href=\"%1$s\">support section</a> to find "
+"out where to get assistance for this add-on.</li><li>Please keep reviews "
+"clean, avoid the use of improper language and do not post any personal "
+"information.</li></ul><p>Please read the <a href=\"%2$s\">Review Guidelines</"
+"a> for more detail about user add-on reviews.</p>"
+
+#. %1 is the add-on name
+#: views/reviews/flag.thtml:56 views/reviews/display.thtml:55
+#: views/reviews/review_added.thtml:50
+#, php-format
+msgid "reviews_header"
+msgstr "%s-н үнÑлгÑÑ Ð´Ò¯Ð³Ð½Ñлт"
+
+#: controllers/addons_controller.php:435
+msgid "rss_featuredaddons"
+msgstr "Онцгой шинж чанартай нÑмÑгдлүүд"
+
+#: controllers/addons_controller.php:432
+msgid "rss_newestaddons"
+msgstr "Ð¨Ð¸Ð½Ñ Ð½ÑмÑгдлүүд"
+
+#: controllers/addons_controller.php:434
+#, fuzzy
+msgid "rss_popularaddons"
+msgstr "Popular Add-ons"
+
+#: controllers/addons_controller.php:433
+msgid "rss_updatedaddons"
+msgstr "ШинÑчлÑгдÑÑн нÑмÑгдлүүд"
+
+#: views/elements/search_mini.thtml:70
+#, fuzzy
+msgid "search"
+msgstr "Search"
+
+#: views/search/collections.thtml:51
+#, fuzzy
+msgid "search_collections_header"
+msgstr "Collection Search Results"
+
+#: controllers/search_controller.php:297
+#, fuzzy
+msgid "search_collections_pagetitle"
+msgstr "Collection Search Results"
+
+#: controllers/search_controller.php:99
+msgid "search_disabled"
+msgstr "Хайлт хийх одоогоор боломжгүй. Дараа дахин оролдоно уу."
+
+#: views/elements/amo2009/search.thtml:188 views/elements/search.thtml:187
+#: views/elements/search_mini.thtml:54
+msgid "search_form_all_addons"
+msgstr "бүх нÑмÑгдлүүд"
+
+#. This string is in the main category dropdown when searching
+#: views/elements/amo2009/search.thtml:204
+#, fuzzy
+msgid "search_form_all_collections"
+msgstr "all collections"
+
+#: views/elements/amo2009/search.thtml:184
+#: views/elements/amo2009/search.thtml:385
+#: views/elements/amo2009/search.thtml:408 views/elements/search.thtml:171
+#: views/elements/search.thtml:183 views/elements/search_mini.thtml:43
+#: views/elements/search_mini.thtml:49 views/layouts/mozilla.thtml:188
+msgid "search_form_default_text"
+msgstr "нÑмÑгдÑл хайх"
+
+#: views/elements/amo2009/search.thtml:184
+#: views/elements/amo2009/search.thtml:404
+#, fuzzy
+msgid "search_form_default_text_collections"
+msgstr "search for collections"
+
+#: views/elements/amo2009/search.thtml:206 views/elements/search.thtml:202
+#, fuzzy
+msgid "search_form_submit_tooltip"
+msgstr "Search for add-ons"
+
+#: views/elements/amo2009/search.thtml:184 views/elements/search.thtml:183
+#: views/elements/search_mini.thtml:49
+#, fuzzy
+msgid "search_form_tooltip"
+msgstr "Click to enter search terms"
+
+#: views/elements/amo2009/search.thtml:186 views/elements/search.thtml:185
+#: views/elements/search_mini.thtml:52
+msgid "search_form_within"
+msgstr "хайх талбар"
+
+#: views/addons/searchengines.thtml:118
+msgid "search_landing_all_search_engines"
+msgstr "Бүх хайлт хийгчдÑд"
+
+#: views/addons/searchengines.thtml:114
+msgid "search_landing_browse_search_engines"
+msgstr "Хайлт хийгчдийг харуул"
+
+#: views/search/collections.thtml:58 views/search/index.thtml:59
+msgid "search_nothing_found"
+msgstr "Ямар ч үр дүн олдÑонгүй."
+
+#: controllers/search_controller.php:185
+msgid "search_pagetitle"
+msgstr "ÐÑмÑгдÑл хайх"
+
+#: controllers/search_controller.php:242
+msgid "search_rss_description"
+msgstr "Хайлтын үр дүнгийн товч мÑдÑÑ"
+
+#. %s is the terms the user is searching for (a string)
+#: controllers/search_controller.php:241
+#, php-format
+msgid "search_rss_results_for"
+msgstr "Хайлтын үр дүн: %s"
+
+#: views/elements/header.thtml:154 views/layouts/amo2009.thtml:296
+msgid "sidebar_navlink_admin_tools"
+msgstr "Зохицуулагчын Ñ…ÑÑ€ÑгÑÑл"
+
+#: views/elements/header.thtml:146 views/layouts/amo2009.thtml:288
+msgid "sidebar_navlink_developer_tools"
+msgstr "ХөгжүүлÑгчийн Ñ…ÑÑ€ÑгÑÑл"
+
+#: views/elements/header.thtml:148 views/layouts/amo2009.thtml:290
+msgid "sidebar_navlink_editor_tools"
+msgstr "ЗаÑварлагчийн Ñ…ÑÑ€ÑгÑÑл"
+
+#: views/layouts/amo2009.thtml:302
+msgid "sidebar_navlink_welcome"
+msgstr "Тавтай морилно уу"
+
+#. %s is the user's name
+#: views/layouts/amo2009.thtml:302
+#, php-format
+msgid "sidebar_navlink_welcome_name"
+msgstr "Тавтай морилно уу, %s-д"
+
+#: views/elements/pitch.thtml:50 views/elements/pitch.thtml:55
+msgid "sidebar_pitch_dictionary"
+msgstr "Үгийн Ñан"
+
+#: views/elements/pitch.thtml:72
+msgid "sidebar_pitch_featured_addons"
+msgstr "ДÑмжлÑгтÑй нÑмÑгдлүүд"
+
+#: views/elements/pitch.thtml:61
+msgid "sidebar_pitch_looking_for"
+msgstr "Миний хайж буй зүйл бол:"
+
+#: views/elements/pitch.thtml:70
+msgid "sidebar_pitch_newest_addons"
+msgstr "Ð¨Ð¸Ð½Ñ Ð½ÑмÑгдлүүд"
+
+#: views/elements/pitch.thtml:49
+msgid "sidebar_pitch_search"
+msgstr "Өргөтгөл хайх"
+
+#: views/elements/pitch.thtml:69
+msgid "sidebar_pitch_subscribe_to"
+msgstr "БүртгүүлÑÑ… "
+
+#: views/elements/pitch.thtml:48 views/elements/pitch.thtml:54
+msgid "sidebar_pitch_theme"
+msgstr "Харуулах маÑг"
+
+#: views/elements/pitch.thtml:71
+msgid "sidebar_pitch_updated_addons"
+msgstr "ШинÑчлÑгдÑÑн нÑмÑгдлүүд"
+
+#. %1$s is a number
+#: views/helpers/localization.php:65 views/developers/versions_edit.thtml:95
+#: views/addons/dictionaries.thtml:92
+#, php-format
+msgid "size_kb"
+msgstr "%1$s KБ"
+
+#: views/elements/amo2009/stars.thtml:57 views/elements/stars.thtml:63
+msgid "stars_not_yet_rated"
+msgstr "Одоогоор үнÑлгÑÑ Ð°Ð²Ð°Ð°Ð³Ò¯Ð¹"
+
+#. %1 is the number of stars this add-on has
+#: views/elements/amo2009/stars.thtml:49 views/elements/stars.thtml:54
+#, php-format
+msgid "stars_rated_x_outof_5"
+msgstr "Ð¢Ð°Ð²Ð°Ð°Ñ %s од авÑан"
+
+#: views/statistics/addon.thtml:59
+msgid "statistics_addon_dashboard_link"
+msgstr "ЭхлÑл Ñамбар"
+
+#: views/statistics/addon.thtml:58
+msgid "statistics_addon_developertools_link"
+msgstr "ХөгжүүлÑгчийн багаж"
+
+#: views/statistics/addon.thtml:53
+msgid "statistics_addon_switch"
+msgstr "ÐÑмÑгдÑлд ÑÑлгÑÑ…"
+
+#. This is a date format.
+#. http://php.net/strftime
+#: views/statistics/rss/summary.thtml:54 views/statistics/addon.thtml:181
+msgid "statistics_date_shortmonth"
+msgstr "M. j"
+
+#. This is a date format.
+#. http://php.net/strftime
+#: views/statistics/rss/summary.thtml:40 views/statistics/addon.thtml:152
+msgid "statistics_date_shortmonthwithyear"
+msgstr "Y. M. j"
+
+#. This is a date format.
+#. http://php.net/strftime
+#: views/statistics/rss/summary.thtml:41 views/statistics/rss/summary.thtml:48
+#: views/statistics/addon.thtml:161 views/statistics/addon.thtml:172
+msgid "statistics_date_weekdayshortmonth"
+msgstr "M. j, l дÑÑ… өдөр"
+
+#. %1$s is an add-on name and version. Example: Add-on 3.5
+#: controllers/components/stats.php:519
+#, php-format
+msgid "statistics_events_addon_created"
+msgstr "%1$s Ò¯Ò¯ÑгÑгдÑÑн"
+
+#. %1$s is an application name and version. Example: Firefox 3.5
+#: controllers/components/stats.php:500
+#, php-format
+msgid "statistics_events_app_released"
+msgstr "%1$s гаргаÑан"
+
+#: views/statistics/addon.thtml:71
+msgid "statistics_help_close_link"
+msgstr "Хаах"
+
+#: views/statistics/addon.thtml:60
+msgid "statistics_help_link"
+msgstr "ТуÑламж"
+
+#: views/statistics/index.thtml:83
+msgid "statistics_index_anotheraddon"
+msgstr "ÑÑвÑл Ó©Ó©Ñ€ нÑмÑгдÑл Ñонгох"
+
+#: views/statistics/index.thtml:85
+msgid "statistics_index_anotheraddon_public"
+msgstr "ÑÑвÑл нийтийн Ñудалгаатай нÑмÑгдÑл Ñонгох"
+
+#: views/statistics/index.thtml:71
+msgid "statistics_index_myaddons"
+msgstr "Судалгааг нь харахыг Ñ…Ò¯ÑÑÑн нÑмÑгдлÑÑ Ñонгоно уу"
+
+#: views/statistics/index.thtml:89
+msgid "statistics_index_selectaddon"
+msgstr "Судалгааг нь харахыг Ñ…Ò¯ÑÑÑн нÑмÑгдлÑÑ Ñонгоно уу"
+
+#: views/statistics/index.thtml:91
+msgid "statistics_index_selectaddon_public"
+msgstr "Ðийтийн Ñудалгаатай нÑмÑгдÑл Ñонгох"
+
+#: views/statistics/index.thtml:39
+msgid "statistics_index_title"
+msgstr "Судалгааны Ñамбар"
+
+#: views/statistics/index.thtml:97
+msgid "statistics_index_view_button"
+msgstr "Судалгааг харах"
+
+#: views/statistics/addon.thtml:222 controllers/statistics_controller.php:247
+#, fuzzy
+msgid "statistics_js_download_csv"
+msgstr "View this table in CSV format"
+
+#: controllers/statistics_controller.php:246
+msgid "statistics_js_dropdowns_none"
+msgstr "байхгүй"
+
+#: controllers/statistics_controller.php:245
+msgid "statistics_js_dropdowns_removeplot"
+msgstr "Ð­Ð½Ñ Ñ…Ð°Ñ€ÑƒÑƒÐ»Ð°Ð»Ñ‚Ñ‹Ð³ уÑтга"
+
+#: controllers/statistics_controller.php:248
+#, fuzzy
+msgid "statistics_js_groupby_selector_date"
+msgstr "Group by: Day"
+
+#: controllers/statistics_controller.php:251
+#, fuzzy
+msgid "statistics_js_groupby_selector_month"
+msgstr "Group by: Month"
+
+#: controllers/statistics_controller.php:249
+#, fuzzy
+msgid "statistics_js_groupby_selector_week"
+msgstr "Group by: Week"
+
+#: controllers/statistics_controller.php:250
+#, fuzzy
+msgid "statistics_js_groupby_selector_week_over_week"
+msgstr "Compare by: Week"
+
+#: controllers/statistics_controller.php:260
+msgid "statistics_js_plotselection_foundinrange"
+msgstr "%s Ñудалгаа олдов"
+
+#: controllers/statistics_controller.php:270
+msgid "statistics_js_plotselection_options_addplot_name"
+msgstr "Харуулалт нÑмÑÑ…"
+
+#: controllers/statistics_controller.php:271
+msgid "statistics_js_plotselection_options_addplot_tooltip"
+msgstr "Ð­Ð½Ñ Ð³Ñ€Ð°Ñ„Ð¸ÐºÑ‚ Ó©Ó©Ñ€ харуулалт нÑмÑÑ…"
+
+#: controllers/statistics_controller.php:261
+msgid "statistics_js_plotselection_options_count_name_checked"
+msgstr "Ðийт тоог нуу"
+
+#: controllers/statistics_controller.php:262
+msgid "statistics_js_plotselection_options_count_name_unchecked"
+msgstr "Ðийт тоог харуул"
+
+#: controllers/statistics_controller.php:263
+#, fuzzy
+msgid "statistics_js_plotselection_options_count_tooltip"
+msgstr "Plot the total count on this graph"
+
+#: controllers/statistics_controller.php:275
+msgid "statistics_js_plotselection_options_csv_name"
+msgstr "Өгөгдлийг харах (CSV)"
+
+#: controllers/statistics_controller.php:276
+msgid "statistics_js_plotselection_options_csv_tooltip"
+msgstr "Ð­Ð½Ñ Ó©Ð³Ó©Ð³Ð´Ð»Ð¸Ð¹Ð³ таÑлалаар туÑгаарлагдÑан Ñ…ÑлбÑÑ€ÑÑÑ€ авах"
+
+#: controllers/statistics_controller.php:267
+msgid "statistics_js_plotselection_options_events_addon_name_checked"
+msgstr "%s үйл Ñвцыг нуух"
+
+#: controllers/statistics_controller.php:268
+msgid "statistics_js_plotselection_options_events_addon_name_unchecked"
+msgstr "%s үйл Ñвцыг харуул"
+
+#: controllers/statistics_controller.php:269
+msgid "statistics_js_plotselection_options_events_addon_tooltip"
+msgstr "Харуулалт дÑÑÑ€ нÑмÑгдлийн гарÑан огноог дар"
+
+#: controllers/statistics_controller.php:264
+msgid "statistics_js_plotselection_options_events_firefox_name_checked"
+msgstr "Firefox үйл Ñвцыг нуу"
+
+#: controllers/statistics_controller.php:265
+msgid "statistics_js_plotselection_options_events_firefox_name_unchecked"
+msgstr "Firefox үйл Ñвцыг харуул"
+
+#: controllers/statistics_controller.php:266
+msgid "statistics_js_plotselection_options_events_firefox_tooltip"
+msgstr "Харуулалт дÑÑÑ€ Firefox гарÑан огнооог нуу"
+
+#: controllers/statistics_controller.php:272
+msgid "statistics_js_plotselection_options_resize_name_checked"
+msgstr "Графикийг хураа"
+
+#: controllers/statistics_controller.php:273
+msgid "statistics_js_plotselection_options_resize_name_unchecked"
+msgstr "Графикийг дÑлгÑ"
+
+#: controllers/statistics_controller.php:274
+msgid "statistics_js_plotselection_options_resize_tooltip"
+msgstr "Графикийн Ñ…ÑмжÑÑг өөрчил"
+
+#: controllers/statistics_controller.php:254
+msgid "statistics_js_plotselection_selector_adu"
+msgstr "Өдөржин Ñ…ÑÑ€ÑглÑдÑг идÑвхитÑй Ñ…ÑÑ€ÑглÑгчид"
+
+#: controllers/statistics_controller.php:256
+msgid "statistics_js_plotselection_selector_application"
+msgstr "Програмууд"
+
+#: controllers/statistics_controller.php:259
+msgid "statistics_js_plotselection_selector_custom"
+msgstr "БуÑад төрлийн"
+
+#: controllers/statistics_controller.php:253
+msgid "statistics_js_plotselection_selector_downloads"
+msgstr "Татаж авалт"
+
+#: controllers/statistics_controller.php:258
+msgid "statistics_js_plotselection_selector_os"
+msgstr "Үйлдлийн ÑиÑтем"
+
+#: controllers/statistics_controller.php:257
+msgid "statistics_js_plotselection_selector_status"
+msgstr "ÐÑмÑгдлийн төлөв байдал"
+
+#: controllers/statistics_controller.php:252
+msgid "statistics_js_plotselection_selector_summary"
+msgstr "ДүгнÑлт"
+
+#: controllers/statistics_controller.php:255
+msgid "statistics_js_plotselection_selector_version"
+msgstr "ÐÑмÑгдлийн хувилбар"
+
+#: controllers/components/stats.php:398
+msgid "statistics_longnames_application"
+msgstr "Програм"
+
+#: controllers/components/stats.php:400
+msgid "statistics_longnames_os"
+msgstr "Үйлдлийн ÑиÑтем"
+
+#: controllers/components/stats.php:399
+msgid "statistics_longnames_status"
+msgstr "ÐÑмÑгдлийн төлөв байдал"
+
+#: controllers/components/stats.php:401
+msgid "statistics_longnames_unknown"
+msgstr "Үл мÑдÑгдÑÑ…"
+
+#: controllers/components/stats.php:397
+msgid "statistics_longnames_version"
+msgstr "ÐÑмÑгдлийн хувилбар"
+
+#: views/statistics/addon.thtml:118
+msgid "statistics_notice_data_insufficient"
+msgstr ""
+"Ð­Ð½Ñ Ð³Ñ€Ð°Ñ„Ð¸ÐºÐ¸Ð¹Ð³ харуулах хангалттай өгөгдөл байхгүй байна. Сүүлд дахин шалгана "
+"уу."
+
+#: views/statistics/addon.thtml:130
+msgid "statistics_notice_data_none"
+msgstr ""
+"Таны нÑмÑгдÑлд зориулагдÑан өгөгдөл бидÑнд алга байна. Ð¥ÑдÑн өдрийн дараа та "
+"дахин шалгана уу."
+
+#: views/statistics/addon.thtml:41
+msgid "statistics_notice_data_updating"
+msgstr ""
+"ÐÑмÑгдлийн Ñудалгааны дүн одоогоор боловÑруулагдаж байна. Ð­Ð½Ñ Ð¼ÑдÑÑллийг "
+"боловÑруулж байх үед оруулÑан Ñүүлийн мÑдÑÑллүүд хамрагдахгүй байж магадгүй. "
+"Ð¥ÑдÑн минутын дараа ÑргÑж шалгана уу."
+
+#: views/statistics/addon.thtml:136
+msgid "statistics_notice_disabled"
+msgstr "Судалгааны Ñамбар одоогоор хоригдÑоно. Сүүлд дахин шалгана уу."
+
+#: views/statistics/addon.thtml:123
+msgid "statistics_notice_nojavascript"
+msgstr "Судалгааны Ñамбарт график харуулахын тулд ЖааваÑкрипт шаардлагатай."
+
+#: views/statistics/addon.thtml:44
+msgid "statistics_notice_settings_updated"
+msgstr "Таны тохиргоо шинÑчлÑгдÑÑн!"
+
+#: controllers/statistics_controller.php:60
+#: controllers/statistics_controller.php:71
+#: controllers/statistics_controller.php:74
+#: controllers/statistics_controller.php:240
+msgid "statistics_pagetitle"
+msgstr "Судалгааны Ñамбар"
+
+#: views/statistics/addon.thtml:99
+msgid "statistics_plot_legend_adu"
+msgstr "Өдөржин Ñ…ÑÑ€ÑглÑдÑг идÑвхитÑй Ñ…ÑÑ€ÑглÑгчид"
+
+#: views/statistics/addon.thtml:95
+msgid "statistics_plot_legend_downloads"
+msgstr "Өдрийн татаж авалт"
+
+#: views/statistics/addon.thtml:107
+msgid "statistics_plot_options_zoomin_alt"
+msgstr "Томруулж харуул"
+
+#: views/statistics/addon.thtml:106
+msgid "statistics_plot_options_zoomin_title"
+msgstr "ÐÑг Ñарын харуулалтыг томруул"
+
+#: views/statistics/addon.thtml:110
+msgid "statistics_plot_options_zoomout_alt"
+msgstr "БагаÑгаж харуул"
+
+#: views/statistics/addon.thtml:109
+msgid "statistics_plot_options_zoomout_title"
+msgstr "ÐÑг Ñарын харуулалтаар багаÑгаж харуул"
+
+#: controllers/statistics_controller.php:283
+#, php-format
+msgid "statistics_rss_description"
+msgstr "%1$s-н Ñудалгааны нÑг өдрийн үзүүлÑлт"
+
+#: views/statistics/rss/summary.thtml:68
+msgid "statistics_rss_title_fulldate"
+msgstr "Y, F, j, l"
+
+#: views/statistics/rss/summary.thtml:68
+#, php-format
+msgid "statistics_rss_title_statsfordate"
+msgstr "%1$s-н Ñудалгааны үзүүлÑлт"
+
+#: views/statistics/settings.thtml:49
+msgid "statistics_settings_access_description"
+msgstr ""
+"Ðнхдагч тохиргоогоор бол зөвхөн та болон Мозиллагийн Ñ…Ò¯Ð¼Ò¯Ò¯Ñ Ñ‚Ð°Ð½Ñ‹ Ñудалгааны "
+"Ñамбарт хандах боломжтой. Та ÑÐ½Ñ Ñудалгааг олон нийтÑд харуулахаар тохируулж "
+"Ð±Ð°Ñ Ð±Ð¾Ð»Ð½Ð¾."
+
+#: views/statistics/settings.thtml:48
+msgid "statistics_settings_access_heading"
+msgstr "Самбарт хандах тохируулга"
+
+#: views/statistics/settings.thtml:51
+msgid "statistics_settings_access_private"
+msgstr "Хувийн"
+
+#: views/statistics/settings.thtml:51
+msgid "statistics_settings_access_private_description"
+msgstr ""
+"Зөвхөн та болон Мозиллагийн Ñ…Ò¯Ð¼Ò¯Ò¯Ñ ÑÐ½Ñ Ð½ÑмÑгдлийн Ñудалгааны үр дүнг харна"
+
+#: views/statistics/settings.thtml:52
+msgid "statistics_settings_access_public"
+msgstr "Ðийтийн"
+
+#: views/statistics/settings.thtml:52
+msgid "statistics_settings_access_public_description"
+msgstr "Ð­Ð½Ñ Ð½ÑмÑгдлийн Ñудалгааны үр дүнг хүн болгон харна"
+
+#: views/statistics/addon.thtml:251
+msgid "statistics_settings_change_link"
+msgstr "Тохиргоог өөрчил"
+
+#: views/statistics/addon.thtml:253
+msgid "statistics_settings_confidential"
+msgstr "Ð­Ð½Ñ Ð¼ÑдÑÑллийг хувийн чухал гÑж тооцож хандана уу."
+
+#: views/statistics/addon.thtml:245
+msgid "statistics_settings_currently_private"
+msgstr "Ð­Ð½Ñ Ñамбар одоогоор <b>хувийн</b> гÑÑÑн тохируулгатай."
+
+#: views/statistics/addon.thtml:241
+msgid "statistics_settings_currently_public"
+msgstr "Ð­Ð½Ñ Ñамбар одоогоор <b>нийтийн</b> гÑÑÑн тохируулгатай."
+
+#: views/statistics/addon.thtml:246
+msgid "statistics_settings_locked_alt"
+msgstr "ТүгжигдÑÑн"
+
+#: views/statistics/settings.thtml:57
+msgid "statistics_settings_return_link"
+msgstr "Самбарт буцаж очих"
+
+#: views/statistics/settings.thtml:56
+msgid "statistics_settings_save_button"
+msgstr "Тохиргоог хадгал"
+
+#: views/statistics/settings.thtml:46
+#, php-format
+msgid "statistics_settings_title"
+msgstr "%1$s-н Ñудалгааны Ñамбарын тохиргоо"
+
+#: views/statistics/addon.thtml:242
+msgid "statistics_settings_unlocked_alt"
+msgstr "ТүгжигдÑÑгүй"
+
+#: controllers/components/stats.php:405
+msgid "statistics_shortnames_application"
+msgstr "Програм"
+
+#: controllers/components/stats.php:407
+msgid "statistics_shortnames_os"
+msgstr "ҮС"
+
+#: controllers/components/stats.php:406
+msgid "statistics_shortnames_status"
+msgstr "Суд"
+
+#: controllers/components/stats.php:408
+msgid "statistics_shortnames_unknown"
+msgstr "ҮМ"
+
+#: controllers/components/stats.php:404
+msgid "statistics_shortnames_version"
+msgstr "Хув"
+
+#: views/statistics/rss/summary.thtml:42 views/statistics/addon.thtml:192
+msgid "statistics_summary_downloads_average"
+msgstr "Өдрийн дундаж татаж авалт"
+
+#: views/statistics/rss/summary.thtml:39
+msgid "statistics_summary_downloads_heading"
+msgstr "Татаж авалт"
+
+#: views/statistics/rss/summary.thtml:41 views/statistics/addon.thtml:171
+msgid "statistics_summary_downloads_lastcount"
+msgstr "Сүүлийн өдрийн тоо"
+
+#: views/statistics/rss/summary.thtml:43 views/statistics/addon.thtml:199
+msgid "statistics_summary_downloads_lastweek"
+msgstr "Сүүлийн 7 хоногийн татаж авалт"
+
+#: views/statistics/rss/summary.thtml:40 views/statistics/addon.thtml:151
+msgid "statistics_summary_downloads_total"
+msgstr "Ðийт татаж авалт"
+
+#: views/statistics/rss/summary.thtml:40 views/statistics/addon.thtml:152
+#, php-format
+msgid "statistics_summary_downloads_total_sincedate"
+msgstr "%1$s-Ñ Ñ…Ð¾Ð¹ÑˆÑ…Ð¸"
+
+#: views/statistics/rss/summary.thtml:50 views/statistics/rss/summary.thtml:56
+#: views/statistics/addon.thtml:163 views/statistics/addon.thtml:183
+msgid "statistics_summary_nodata"
+msgstr "Өгөгдөл байхгүй"
+
+#: views/statistics/rss/summary.thtml:60 views/statistics/addon.thtml:195
+msgid "statistics_summary_updatepings_average"
+msgstr "Өдрийн идÑвхитÑй Ñ…ÑÑ€ÑглÑгчдийн дундаж"
+
+#: views/statistics/rss/summary.thtml:52 views/statistics/addon.thtml:177
+msgid "statistics_summary_updatepings_changefromprevious"
+msgstr "Өмнөх Ñ‚Ð¾Ð¾Ð½Ð¾Ð¾Ñ Ð³Ð°Ñ€Ñан өөрчлөлт"
+
+#: views/statistics/rss/summary.thtml:54 views/statistics/addon.thtml:181
+#, php-format
+msgid "statistics_summary_updatepings_changefromprevious_ondate"
+msgstr "%2$s-нд %1$s "
+
+#: views/statistics/rss/summary.thtml:45
+msgid "statistics_summary_updatepings_heading"
+msgstr "Өдрийн идÑвхитÑй Ñ…ÑÑ€ÑглÑгчид"
+
+#: views/statistics/rss/summary.thtml:46 views/statistics/addon.thtml:157
+msgid "statistics_summary_updatepings_total"
+msgstr "Өдрийн идÑвхитÑй Ñ…ÑÑ€ÑглÑгчид"
+
+#: views/statistics/rss/summary.thtml:48 views/statistics/addon.thtml:161
+#, php-format
+msgid "statistics_summary_updatepings_total_ondate"
+msgstr "%1$s-нд"
+
+#: views/statistics/rss/summary.thtml:61 views/statistics/addon.thtml:203
+#, fuzzy
+msgid "statistics_summary_updatepings_weekly_average"
+msgstr "Average Daily Users this Week"
+
+#. %s is a percentage, like '+22.33%'. It sits next to another number, so
+#. the implied meaning is 'percentage change' from the previous stat point.
+#: views/statistics/rss/summary.thtml:62 views/statistics/addon.thtml:205
+#, fuzzy
+msgid "statistics_summary_updatepings_weekly_change"
+msgstr "%s from last week"
+
+#: views/statistics/addon.thtml:65 controllers/statistics_controller.php:184
+#: controllers/statistics_controller.php:282
+#, php-format
+msgid "statistics_title_addon_stats"
+msgstr "%1$s Ñудалгаа"
+
+#: views/addons/themes_landing.thtml:113
+msgid "themes_landing_all_themes"
+msgstr "Бүх харуулах маÑг"
+
+#: views/addons/themes_landing.thtml:109
+msgid "themes_landing_browse_themes"
+msgstr "Харуулах маÑгуудыг харуул"
+
+#: views/users/edit.thtml:185
+msgid "user_change_email"
+msgstr "Захианы хаÑгаа өөрчлөх"
+
+#: views/users/edit.thtml:169
+msgid "user_change_password"
+msgstr "Ðууц үгÑÑ Ñолих"
+
+#: views/users/edit.thtml:96
+#, fuzzy
+msgid "user_change_password_or_email"
+msgstr "Change Password or Email"
+
+#: controllers/users_controller.php:197
+msgid "user_confirmationcode_resent"
+msgstr "Баталгаажуулах код дахин илгÑÑгдÑÑн!"
+
+#. %1 is the email address, %2 is the URL of the user registration page
+#: views/users/delete.thtml:51
+#, fuzzy
+msgid "user_del_account_deleted"
+msgstr ""
+"Your user account %1$s has been successfully deleted. If you want to come "
+"back some time, you can re-register on the <a href=\"%2$s\">user "
+"registration page</a>."
+
+#: views/users/delete.thtml:102
+#, fuzzy
+msgid "user_del_community_sad"
+msgstr "The Mozilla Add-ons community is sad to see you go."
+
+#: views/users/delete.thtml:123
+#, fuzzy
+msgid "user_del_confirm_password"
+msgstr "Confirm Password"
+
+#: views/users/delete.thtml:134
+#, fuzzy
+msgid "user_del_deletenow"
+msgstr "Delete my user account now"
+
+#. %1 is the URL of the user's info page
+#: views/users/delete.thtml:64
+#, fuzzy
+msgid "user_del_error_addons"
+msgstr ""
+"You cannot delete your account if you are listed as an <a href=\"%1$s"
+"\">author of any add-ons</a>. To delete your account, please have another "
+"person in your development group delete you from the list of authors for "
+"your add-ons. Afterwards you will be able to delete your account here."
+
+#. %1 is a link to the amo-editors mailing list
+#: views/users/delete.thtml:71
+#, fuzzy
+msgid "user_del_error_addons_more_questions"
+msgstr "If you have additional questions, please contact %1$s for assistance."
+
+#: views/users/delete.thtml:78
+#, fuzzy
+msgid "user_del_error_checkbox"
+msgstr ""
+"You need to check the box \"I understand...\" before we can delete your "
+"account."
+
+#: views/users/delete.thtml:84
+#, fuzzy
+msgid "user_del_error_password"
+msgstr "Please enter your password correctly in order to perform this step."
+
+#. %1 is a link to the amo-admins mailing list
+#: views/users/delete.thtml:91
+#, fuzzy
+msgid "user_del_error_unknown"
+msgstr ""
+"An unknown error occured deleting your account. Please contact %1$s with the "
+"issue and we will delete it for you. We apologize for the inconvenience."
+
+#: views/users/delete.thtml:110
+#, fuzzy
+msgid "user_del_header_confirm_deletion"
+msgstr "Confirm account deletion"
+
+#. %1 is the user's email address
+#: views/users/delete.thtml:100
+#, fuzzy
+msgid "user_del_header_delete_account"
+msgstr "Delete User Account %1$s"
+
+#: views/users/delete.thtml:50
+#, fuzzy
+msgid "user_del_header_farewell"
+msgstr "Farewell!"
+
+#: views/users/delete.thtml:115
+#, fuzzy
+msgid "user_del_nologin"
+msgstr "You will not be able to log into Mozilla Add-ons anymore."
+
+#: views/users/delete.thtml:112
+#, fuzzy
+msgid "user_del_permanently_removed_means"
+msgstr ""
+"By clicking \"delete\" your account is going to be <strong>permanently "
+"removed</strong>. That means:"
+
+#: views/users/delete.thtml:116
+#, fuzzy
+msgid "user_del_reviews_anonymized"
+msgstr ""
+"Your reviews and ratings will not be deleted, but they will no longer be "
+"associated with you."
+
+#. %1 is a link to the amo-editors mailing list
+#: views/users/delete.thtml:104
+#, fuzzy
+msgid "user_del_specific_problem_editors"
+msgstr ""
+"If you have a specific problem we may help you with, please do not delete "
+"your account now, but contact us at %1$s and we will do our best to assist "
+"you in solving it."
+
+#: views/users/delete.thtml:130
+#, fuzzy
+msgid "user_del_understand_permanent"
+msgstr "I understand that this step cannot be undone."
+
+#: views/helpers/addons_html.php:192
+#, fuzzy
+msgid "user_deleted_nickname"
+msgstr "Deleted User"
+
+#. %1 is the new email address
+#: views/users/edit.thtml:71
+msgid "user_edit_confirm_email_sent"
+msgstr ""
+"Таны ÑˆÐ¸Ð½Ñ Ð·Ð°Ñ…Ð¸Ð°Ð½Ñ‹ хаÑгийг баталгаажуулах захиа %1$s хаÑг руу илгÑÑгдÑв. "
+"Өөрчлөлтөө батлахын тулд ирÑÑн захиан дотор буй Ñ…Ð¾Ð»Ð±Ð¾Ð¾Ñ Ð´ÑÑÑ€ дарах "
+"шаардлагатай. ТÑÑ€ болтол та одоогийн захианы хаÑгаараа нÑвтÑÑ€ÑÑн байж болно."
+
+#: views/users/edit.thtml:201
+#, fuzzy
+msgid "user_edit_delete_user"
+msgstr "Delete user account"
+
+#. This contains the email sent to users when they signed up for a new
+#. account:
+#. %1 is the confirmation URL, %2 is the current app
+#: views/users/email/confirm_plain.thtml:6
+#, php-format
+msgid "user_email_confirm_account_nopass"
+msgstr ""
+"%2$s нÑмÑгдÑлд тавтай морилно уу.\n"
+"\n"
+"Ð¨Ð¸Ð½Ñ Ð±Ò¯Ñ€Ñ‚Ð³ÑлÑÑ Ñ…ÑÑ€ÑглÑхийн тулд та түүний идÑвхжүүлÑÑ… Ñ‘Ñтой - Ð­Ð½Ñ Ð½ÑŒ таны "
+"захианы хаÑг нь зөв бичигдÑÑн болон танд хамаарагддаг гÑж авч үздÑг.\n"
+"БүртгÑлÑÑ Ð¸Ð´ÑвхжүүлÑхийн тулд дараах Ñ…Ð¾Ð»Ð±Ð¾Ð¾Ñ Ð´ÑÑÑ€ дарах ÑÑвÑл уг холбооÑыг "
+"Ñанамжид хийгÑÑд хөтлөгчийнхөө хаÑг бичих талбар дÑÑÑ€ ÑанамжнааÑаа буулгаж "
+"орох Ñ…ÑÑ€ÑгтÑй:\n"
+"\n"
+"%1$s\n"
+"\n"
+"ÐÑгÑнт идÑвхжүүлÑний дараа ÑÐ½Ñ Ð·Ð°Ñ…Ð¸Ð°Ð³ уÑтгаж болно.\n"
+"\n"
+"%2$s нÑмÑгдлийнхÑнтÑй хамтарÑан танд баÑрлалаа\n"
+"-- %2$s нÑмÑгдлүүд"
+
+#. %1 is the confirmation url, %2 is the application name
+#: views/users/email/emailchange_plain.thtml:5
+msgid "user_email_confirm_emailchange"
+msgstr ""
+"Та %2$s нÑмÑгдÑл дÑÑрх захианы хаÑгаа өөрчлөх Ñ…Ò¯ÑÑлт тавьÑан байна.\n"
+"\n"
+"Ð¨Ð¸Ð½Ñ Ñ…Ð°Ñгаа баталгаажуулахын тулд доорх Ñ…Ð¾Ð»Ð±Ð¾Ð¾Ñ Ð´ÑÑÑ€ дарах, ÑÑвÑл уг Ñ…Ð¾Ð»Ð±Ð¾Ð¾Ñ "
+"хаÑгийг бүхлÑÑÑ€ нь хуулаад хөтлөгчийнхөө хаÑгийн Ñамбарт буулгах тавих "
+"Ñ…ÑÑ€ÑгтÑй:\n"
+"\n"
+"%1$s\n"
+"\n"
+"Танд ÑˆÐ¸Ð½Ñ Ñ…Ð°Ñгаа баталгаажуулахад 48 цагийн хугацаа бий. Ð¥ÑÑ€Ñв та өөрчлөхийг "
+"Ñ…Ò¯ÑÑхгүй болвол ÑÐ½Ñ Ð·Ð°Ñ…Ð¸Ð°Ð³ үл тоомÑорлож орхих Ñ…ÑÑ€ÑгтÑй.\n"
+"\n"
+"Танд баÑрлалаа!\n"
+"-- %2$s нÑмÑгдÑл хариуцÑан Ñ…ÑÑÑг"
+
+#: controllers/users_controller.php:168
+#, php-format
+msgid "user_email_confirm_subject"
+msgstr "%s нÑмÑгдлийнхÑнтÑй хамтарÑан танд баÑрлалаа"
+
+#. This is the password reset email
+#. %1 is the pw reset URL, %2 is the application
+#: views/users/email/pwreset_plain.thtml:5
+#, php-format
+msgid "user_email_pwreset"
+msgstr ""
+"%2$s нÑмÑгдлийн нууц үг Ñолилтt\n"
+"\n"
+"mozilla.org нÑмÑгдÑл дÑÑрх ÑÐ½Ñ Ð±Ò¯Ñ€Ñ‚Ð³Ñлийн нууц үгийг Ñолих Ñ…Ò¯ÑÑлтийг хүлÑÑж "
+"авÑан.Ð­Ð½Ñ Ð½ÑƒÑƒÑ† үгÑÑ Ñолихын тулд дараах Ñ…Ð¾Ð»Ð±Ð¾Ð¾Ñ Ð´ÑÑÑ€ дарах ÑÑвÑл Ñануулаад "
+"хөтлөгчийнхөө хаÑгийн Ñамбар дÑÑÑ€ буулгаж орох Ñ…ÑÑ€ÑгтÑй:\n"
+"\n"
+"%1$s\n"
+"\n"
+"Ð¥ÑÑ€Ñв та ийм захиаг Ñ…Ò¯ÑÑÑгүй бол Ñмар ч үйлдÑл хийх Ñ…ÑÑ€Ñггүй.\n"
+"\n"
+"БаÑрлалаа,\n"
+"-- %2$s нÑмÑгдлүүд"
+
+#: controllers/users_controller.php:245
+#, php-format
+msgid "user_email_pwreset_subject"
+msgstr "%s нÑмÑгдлийн нууц үгÑÑ Ó©Ó©Ñ€Ñ‡Ð»Ó©Ñ…"
+
+#: views/users/emailchange.thtml:50
+msgid "user_emailchange_error"
+msgstr "Ðлдаа!"
+
+#. %1 is the application name
+#: controllers/users_controller.php:533
+msgid "user_emailchange_subject"
+msgstr "Та %1$s нÑмÑгдÑл дÑÑрх захианы хаÑгийн өөрчлөлтөө батлана уу"
+
+#: views/users/emailchange.thtml:48
+msgid "user_emailchange_success"
+msgstr "Ðмжилттай!"
+
+#. %1 is the new email address
+#: views/users/emailchange.thtml:49
+msgid "user_emailchange_successful_description"
+msgstr ""
+"Таны захианы хаÑг амжилттай өөрчлөгдлөө. ÐžÐ´Ð¾Ð¾Ð½Ð¾Ð¾Ñ ÑхлÑн та %1$s хаÑгийг "
+"ашиглаж нÑвтрÑÑ… үйлдÑл хийгÑÑÑ€Ñй."
+
+#: views/users/edit.thtml:134 views/admin/users_edit.thtml:111
+#, fuzzy
+msgid "user_form_bio"
+msgstr "About me"
+
+#: views/users/edit.thtml:135 views/admin/users_edit.thtml:112
+#, fuzzy
+msgid "user_form_bio_description"
+msgstr ""
+"Introduce yourself to the community, if you like! This text will appear "
+"publicly on your user info page. Line breaks will be preserved, but no HTML "
+"is allowed."
+
+#: views/users/pwreset.thtml:77 views/users/register.thtml:73
+#: views/users/edit.thtml:181
+msgid "user_form_confirmpassword"
+msgstr "Ðууц үгийг дахин оруул"
+
+#: views/users/edit.thtml:145
+#, fuzzy
+msgid "user_form_display_collections"
+msgstr "Display the collections I have created in my user profile"
+
+#: views/users/edit.thtml:149
+#, fuzzy
+msgid "user_form_display_collections_fav"
+msgstr "Display my favorite collections in my user profile"
+
+#: views/users/edit.thtml:86
+#, php-format
+msgid "user_form_editprofile"
+msgstr "%s-н Ñ…ÑÑ€ÑглÑгчийн мÑдÑÑллийг заÑварла"
+
+#: views/users/pwreset.thtml:52 views/users/login.thtml:81
+#: views/users/register.thtml:63 views/users/edit.thtml:187
+msgid "user_form_email"
+msgstr "Захианы хаÑг"
+
+#: views/users/register.thtml:78 views/users/edit.thtml:103
+#: views/admin/users_edit.thtml:76
+msgid "user_form_firstname"
+msgstr "Овог нÑÑ€"
+
+#: views/users/register.thtml:94 views/users/edit.thtml:119
+#: views/admin/users_edit.thtml:91
+msgid "user_form_hideemail"
+msgstr "Захианы хаÑгийг нуу"
+
+#: views/users/register.thtml:98 views/users/edit.thtml:123
+#: views/admin/users_edit.thtml:99
+msgid "user_form_homepage"
+msgstr "Ð’Ñб хуудаÑны хаÑг"
+
+#: views/users/register.thtml:84 views/users/edit.thtml:109
+#: views/admin/users_edit.thtml:81
+msgid "user_form_lastname"
+msgstr "ÐÑÑ€"
+
+#: controllers/users_controller.php:333
+msgid "user_form_login"
+msgstr "Ð¥ÑÑ€ÑглÑгчийн нÑвтрÑлт"
+
+#: views/users/pwreset.thtml:72 views/users/edit.thtml:176
+msgid "user_form_newpassword"
+msgstr "Ð¨Ð¸Ð½Ñ Ð½ÑƒÑƒÑ† үг"
+
+#: views/users/register.thtml:89 views/users/edit.thtml:114
+#: views/admin/users_edit.thtml:86
+msgid "user_form_nickname"
+msgstr "Гоц нÑÑ€"
+
+#: views/users/edit.thtml:171
+msgid "user_form_oldpassword"
+msgstr "Хуучин нууц үг"
+
+#: views/users/edit.thtml:97 views/users/edit.thtml:200
+#, fuzzy
+msgid "user_form_otheractions"
+msgstr "Other Actions"
+
+#: views/users/login.thtml:85 views/users/register.thtml:68
+msgid "user_form_password"
+msgstr "Ðууц үг"
+
+#: controllers/users_controller.php:93
+msgid "user_form_registration"
+msgstr "Ð¨Ð¸Ð½Ñ Ñ…ÑÑ€ÑглÑгчийн бүртгÑл"
+
+#: views/users/login.thtml:90
+#, fuzzy
+msgid "user_form_remember_me"
+msgstr "Remember me on this computer"
+
+#: views/admin/users_edit.thtml:95
+msgid "user_form_showsandbox"
+msgstr "Түр хайрцгийг харуулах уу?"
+
+#: views/users/edit.thtml:205
+msgid "user_form_submit_edit"
+msgstr "Хадгал"
+
+#: views/users/login.thtml:93
+msgid "user_form_submit_login"
+msgstr "ÐÑвтрÑÑ…"
+
+#: views/users/register.thtml:113
+msgid "user_form_submit_register"
+msgstr "БүртгүүлÑÑ…"
+
+#: views/users/info.thtml:75
+#, php-format
+msgid "user_info_usersince"
+msgstr "%s нÑмÑгдлийн Ñ…ÑÑ€ÑглÑгчийн бүртгÑл"
+
+#: views/users/login.thtml:102
+msgid "user_login_register_link"
+msgstr "Ð¨Ð¸Ð½Ñ Ñ…ÑÑ€ÑглÑгчийн бүртгÑл Ò¯Ò¯ÑгÑÑ…"
+
+#: views/users/edit.thtml:160
+#, fuzzy
+msgid "user_notifications_item_compat"
+msgstr "Add-on Compatibility (strongly recommended)"
+
+#: views/users/edit.thtml:161
+#, fuzzy
+msgid "user_notifications_item_events"
+msgstr "Upcoming events and contests"
+
+#: views/users/edit.thtml:156
+#, fuzzy
+msgid "user_notifications_none_available"
+msgstr "There are currently no notifications available for you to configure."
+
+#: views/users/edit.thtml:158
+#, fuzzy
+msgid "user_notifications_select_topics"
+msgstr ""
+"From time to time, Mozilla may send you email about upcoming releases and "
+"add-on events. Please select the topics you are interested in below:"
+
+#: views/users/edit.thtml:164
+#, fuzzy
+msgid "user_notifications_specific_contact"
+msgstr ""
+"Mozilla reserves the right to contact you individually about specific "
+"concerns with your hosted add-ons."
+
+#: controllers/users_controller.php:543
+msgid "user_profile_edit_error"
+msgstr ""
+"Таны хийÑÑн өөрчлөлтөнд алдаа байв. ТÑд нарыг заÑаад дахин илгÑÑÐ½Ñ Ò¯Ò¯.."
+
+#: controllers/users_controller.php:540
+msgid "user_profile_saved"
+msgstr "ÐœÑдÑÑлÑл шинÑчлÑгдÑÑн."
+
+#: views/users/pwreset.thtml:65
+#, php-format
+msgid "user_pwreset_for_email"
+msgstr "%s-н нууц үгийг өөрчлөх"
+
+#: controllers/users_controller.php:226
+msgid "user_pwreset_header"
+msgstr "Ðууц үг өөрчлөх"
+
+#: views/users/login.thtml:103
+msgid "user_pwreset_link"
+msgstr "Ðууц үгÑÑ Ð¼Ð°Ñ€Ñ‚Ñан уу?"
+
+#: controllers/users_controller.php:248
+msgid "user_pwreset_link_sent"
+msgstr "Ðууц үгÑÑ Ó©Ó©Ñ€Ñ‡Ð»Ó©Ñ… Ñ…Ð¾Ð»Ð±Ð¾Ð¾Ñ Ñ…Ð°Ñг таны захиа руу илгÑÑгдлÑÑ."
+
+#: controllers/users_controller.php:304
+msgid "user_pwreset_okay"
+msgstr "Ðууц үг амжилттай өөрчлөгдлөө."
+
+#: views/users/pwreset.thtml:82
+msgid "user_pwreset_submit_changepw"
+msgstr "Ðууц үгийн өөрчлөлтийг илгÑÑ"
+
+#: views/users/pwreset.thtml:57
+msgid "user_pwreset_submit_sendlink"
+msgstr "Ðууц үг өөрчлөх Ñ…Ð¾Ð»Ð±Ð¾Ð¾Ñ Ð¸Ð»Ð³ÑÑÑ…"
+
+#: views/users/register_complete.thtml:51
+#, php-format
+msgid "user_register_amo_link"
+msgstr "%s нÑмÑгдÑл"
+
+#. %1 is the user's email address, %2 is the current app
+#: views/users/activatefirst.thtml:49
+#, php-format
+msgid "user_register_click_confirm_link"
+msgstr ""
+"Таны бүртгÑлийг идÑвхжүүлÑÑ… Ñ…Ð¾Ð»Ð±Ð¾Ð¾Ñ Ñ‚Ð°Ð½Ñ‹ захианы %1$s хаÑг руу илгÑÑгдÑÑн. %2"
+"$s нÑмÑгдÑл Ñ€Ò¯Ò¯ нÑвтрÑÑ…ÑÑÑÑÑ Ó©Ð¼Ð½Ó© Ñ‚ÑÑ€ Ñ…Ð¾Ð»Ð±Ð¾Ð¾Ñ Ð´ÑÑÑ€ дарах Ñ‘Ñтой."
+
+#. %1 is the user's email address
+#: views/users/register_complete.thtml:49
+#, php-format
+msgid "user_register_confirm_email_sent"
+msgstr ""
+"Таны %1$s гÑÑÑн захианы хаÑг руу баталгаажуулÑан захиаг илгÑÑÑÑн. ÐÑвтрÑлт "
+"хийхÑÑÑÑÑ Ó©Ð¼Ð½Ó© Захианд ÑвуулÑан баталгаажуулах Ñ…Ð¾Ð»Ð±Ð¾Ð¾Ñ Ð´ÑÑÑ€ дарж идÑвхжүүлÑÑ… "
+"шаардлагатай."
+
+#: views/users/activatefirst.thtml:51
+msgid "user_register_confirmation_link_text"
+msgstr "баталгаажуулÑан захиаг дахин илгÑÑж"
+
+#: views/users/register_complete.thtml:47
+msgid "user_register_congratulations"
+msgstr "БаÑÑ€ хүргÑе! Таны Ñ…ÑÑ€ÑглÑгчийн бүртгÑл амжилттай бүртгÑгдлÑÑ."
+
+#: views/users/register.thtml:50
+#, fuzzy
+msgid "user_register_details"
+msgstr ""
+"<p>Registration on AMO is <strong>not required</strong> if you simply want "
+"to download and install public add-ons.</p><p>You only need to register if:</"
+"p><ul><li>You want to submit reviews for add-ons</li><li>You are an add-on "
+"developer and want to upload your add-on for hosting on AMO</li></ul><p>Upon "
+"successful registration, you will be sent a confirmation email to the "
+"address you provided. Please follow the instructions there to confirm your "
+"account.</p><p>If you like, you can read our <a href='%1$s' title='Legal "
+"Notices'>Legal Notices</a> and <a href='%2$s' title='Privacy Policy'>Privacy "
+"Policy</a>.</p>"
+
+#. %1 is the link to the "resend confirmation code" page
+#: views/users/activatefirst.thtml:51
+#, php-format
+msgid "user_register_resend_confirmation_link"
+msgstr ""
+"Ð¥ÑÑ€Ñв та баталгаажуулÑан захиаг хүлÑÑж аваагүй бол таны захиа хүлÑÑн авагч "
+"тань Ñ‚ÑÑ€ захиаг \"Ñ‚ÑнÑмÑл захиа\" ÑÑвÑл \"хуурамч\" гÑж Ñ‚ÑмдÑглÑÑÑн байж "
+"магадгүй. Ð¥ÑÑ€Ñв танд Ñ…ÑÑ€ÑгтÑй бол дÑÑÑ€ өгүүлÑÑн захианы хаÑг руу бид %1$s "
+"болно."
+
+#. %1 is the link to the Mozilla Add-ons front page
+#: views/users/register_complete.thtml:51
+#, php-format
+msgid "user_register_welcome"
+msgstr "БүртгүүлÑÑнд тань баÑрлалаа. %1$s-д тавтай морилно уу!"
+
+#: views/users/register.thtml:49
+#, fuzzy
+msgid "user_register_welcome_header"
+msgstr "Welcome to addons.mozilla.org (AMO)!"
+
+#: views/users/register.thtml:81 views/users/edit.thtml:106
+#, fuzzy
+msgid "user_required_firstlast_or_nickname"
+msgstr "A first name, last name or nickname is required."
+
+#: views/users/edit.thtml:94 views/users/edit.thtml:142
+#, fuzzy
+msgid "user_tab_collections"
+msgstr "Collections"
+
+#: views/users/edit.thtml:95 views/users/edit.thtml:154
+#, fuzzy
+msgid "user_tab_notifications"
+msgstr "Notifications"
+
+#: views/users/edit.thtml:93 views/users/edit.thtml:101
+#, fuzzy
+msgid "user_tab_profile"
+msgstr "User Profile"
+
+#: controllers/users_controller.php:209
+msgid "user_verified_okay"
+msgstr "Ðмжилттай баталгаажÑан!"
+
+#: controllers/users_controller.php:723
+#, fuzzy
+msgid "users_delete_pagetitle"
+msgstr "Delete User Account"
+
+#: controllers/users_controller.php:414
+msgid "users_edit_pagetitle"
+msgstr "Ð¥ÑÑ€ÑглÑгчийн бүртгÑл заÑвар"
+
+#: views/users/info.thtml:71
+#, fuzzy
+msgid "users_info_aboutme"
+msgstr "About Me"
+
+#: views/users/info.thtml:96
+#, php-format
+msgid "users_info_addons_by_user"
+msgstr "%1$s-н зохиоÑон нÑмÑгдлүүд"
+
+#: views/users/info.thtml:51
+msgid "users_info_author_name"
+msgstr "ÐÑÑ€"
+
+#: views/users/info.thtml:48
+msgid "users_info_author_profile"
+msgstr "Ð¥ÑÑ€ÑглÑгчийн мÑдÑÑлÑл"
+
+#. %s is the user name
+#: views/users/info.thtml:137
+#, fuzzy
+msgid "users_info_collections_by_user"
+msgstr "Collections by %s"
+
+#: views/users/info.thtml:66
+msgid "users_info_email"
+msgstr "Захианы хаÑг"
+
+#: views/users/info.thtml:155
+#, fuzzy
+msgid "users_info_fav_collections_by_user"
+msgstr "Favorite Collections"
+
+#: views/users/info.thtml:61
+msgid "users_info_homepage"
+msgstr "Ð’Ñб хуудаÑ"
+
+#: views/users/info.thtml:56
+msgid "users_info_nickname"
+msgstr "Гоц нÑÑ€"
+
+#: controllers/users_controller.php:707
+#, php-format
+msgid "users_info_pagetitle"
+msgstr "%1$s Ñ…ÑÑ€ÑглÑгчийн мÑдÑÑлÑл"
+
+#. %1 is the user's name
+#: views/users/info.thtml:116
+#, fuzzy
+msgid "users_info_reviews_by_user"
+msgstr "Reviews by %s"
+
+#: controllers/users_controller.php:330 controllers/users_controller.php:332
+msgid "users_login_pagetitle"
+msgstr "Ð¥ÑÑ€ÑглÑгчийн нÑвтрÑлт"
+
+#. %1 is the link to the sandbox/policy explanation page
+#. This message is for a specific add-on not found
+#: views/users/login.thtml:53
+#, php-format
+msgid "users_login_sandbox_display_warning"
+msgstr ""
+"Таны хайж буй нÑмÑгдÑл тань түр хайрцагт олдлоо. Ð¥ÑÑ€Ñв танд Мозила "
+"нÑмÑгдлийн бүртгÑлд Ñрх байгаа бол нÑвтрÑлт хийх ÑÑвÑл түр хайрцагны талаар "
+"<a href=\"%1$s\">Ñудлах боломжтой.</a>"
+
+#. %1 is the link to the sandbox/policy explanation page
+#. This message is for any given sandbox-related page not found
+#: views/users/login.thtml:56
+#, php-format
+msgid "users_login_sandbox_page_warning"
+msgstr ""
+"Таны хайж буй Ñ…ÑƒÑƒÐ´Ð°Ñ Ñ‚Ð°Ð½ÑŒ түр хайрцагт олдлоо. Ð¥ÑÑ€Ñв танд Мозила нÑмÑгдлийн "
+"бүртгÑлд Ñрх байгаа бол нÑвтрÑлт хийх ÑÑвÑл түр хайрцагны талаар <a href=\"%1"
+"$s\">Ñудлах боломжтой.</a>"
+
+#: controllers/users_controller.php:223 controllers/users_controller.php:225
+msgid "users_pwreset_pagetitle"
+msgstr "Ðууц үг шинÑÑÑ€ оруулах"
+
+#: controllers/users_controller.php:90 controllers/users_controller.php:92
+msgid "users_register_pagetitle"
+msgstr "Ð¨Ð¸Ð½Ñ Ñ…ÑÑ€ÑглÑгчийн бүртгÑл"
+
+#. %1$s is an addon name, like <a>Firebug</a>
+#. %2$s is a version number, like <a>1.2</a>
+#: views/versions/license.thtml:52
+#, fuzzy
+msgid "versions_license_header_source"
+msgstr "Source code license for %1$s %2$s"
+
+#: views/addons/category_landing.thtml:147
+#, fuzzy
+msgid "view_recently_added"
+msgstr "View all recently added"
+
+#: views/addons/category_landing.thtml:161
+#, fuzzy
+msgid "view_top_downloads"
+msgstr "View all top downloads"
+
+#: views/addons/category_landing.thtml:175
+#, fuzzy
+msgid "view_top_rated"
+msgstr "View all top rated"
+
+#, fuzzy
+#~ msgid "addon_slider_tooltip_next"
+#~ msgstr "Next Add-on"
+
+#, fuzzy
+#~ msgid "addon_slider_tooltip_previous"
+#~ msgstr "Previous Add-on"
+
+#~ msgid "addon_versions_getlatesttext"
+#~ msgstr "Хамгийн Ñүүлийн тохирох хувилбар"
+
+#~ msgid "addons_display_version_history"
+#~ msgstr "Хувилбарын бүрÑн түүх"
+
+#~ msgid "addons_home_newest_header"
+#~ msgstr "ШинÑÑ…Ñн:"
+
+#~ msgid "addons_home_popular_header"
+#~ msgstr "Өргөн тархÑан нь:"
+
+#~ msgid "addons_home_recommended_header"
+#~ msgstr "Бидний Ñанал болголт:"
+
+#~ msgid "addons_home_updated_header"
+#~ msgstr "СаÑхан шинÑчлÑгдÑÑн:"
+
+#~ msgid "addons_home_view_all"
+#~ msgstr "Бүгдийг нь харах"
+
+#~ msgid "category_extra_allrecommended"
+#~ msgstr "Бүх Ñанал болгогдÑон нÑмÑдлүүдийг харах"
+
+#~ msgid "category_extra_highestrated"
+#~ msgstr "Их үнÑлÑгдÑÑн нь ÑÑ…Ñнд"
+
+#~ msgid "category_extra_lastupdated"
+#~ msgstr "Хамгийн Ñүүлд шинÑчлÑгдÑÑн нь ÑÑ…Ñнд"
+
+#~ msgid "category_extra_mostpopular"
+#~ msgstr "Хамгийн өргөн тархÑан нь ÑÑ…Ñнд"
+
+#, fuzzy
+#~ msgid "collections_detail_js_loading"
+#~ msgstr "Loading"
+
+#, fuzzy
+#~ msgid "collections_detail_more_info"
+#~ msgstr "Show More Info"
+
+#~ msgid "devcp_additem_firefox_notice"
+#~ msgstr ""
+#~ "Ð­Ð½Ñ Ð½ÑмÑгдлийн одоогийн хувилбар нь Firefox %1$s гÑÑÑн хувилбартай нь "
+#~ "тохирÑон гÑж мÑдÑгдÑхгүй байна. Firefox-н ÑˆÐ¸Ð½Ñ Ñ…ÑƒÐ²Ð¸Ð»Ð±Ð°Ñ€ удахгүй гарах гÑж "
+#~ "байна гÑж гÑж Мозилла тооцов. ÐÑмÑгдлÑÑ ÑˆÐ¸Ð½Ñ Ñ…ÑƒÐ²Ð¸Ð»Ð±Ð°Ñ€ дÑÑÑ€ туршаад "
+#~ "тохиромжийнх тухай мÑдÑÑллийг нь шинÑÑ‡Ð¸Ð»Ð½Ñ Ò¯Ò¯. Та ÑÐ½Ñ Ñ‚Ð°Ð»Ð°Ð°Ñ€Ñ… дÑлгÑÑ€Ñнгүй "
+#~ "мÑдÑÑллийг <a href=\"%2$s\">ÑндÑÑÑ</a> авах боломжтой. Ð­Ð½Ñ Ð½ÑŒ зөвхөн "
+#~ "Ñануулга болохоор та ÑÐ½Ñ Ñ…ÑƒÐ²Ð¸Ð»Ð±Ð°Ñ€Ð°Ð° илгÑÑÑ… үйлдлÑÑ Ò¯Ñ€Ð³ÑлжлүүлÑн гүйцÑтгÑж "
+#~ "болох юм."
+
+#~ msgid "devcp_addon_disabled_successfully"
+#~ msgstr "ÐÑмÑгдлÑл хорих амжилттай боллоо"
+
+#~ msgid "devcp_addon_edit_pagetitle"
+#~ msgstr "ÐÑмÑгдлийг заÑварла"
+
+#~ msgid "devcp_addon_enabled_successfully"
+#~ msgstr "ÐÑмÑгдлÑл зөвшөөрөх амжилттай боллоо"
+
+#~ msgid "devcp_addon_field_description_displaytitle"
+#~ msgstr "ÐÑмÑгдлийн тодорхойлолт"
+
+#~ msgid "devcp_addon_field_eula_displaytitle"
+#~ msgstr "EULA"
+
+#~ msgid "devcp_addon_field_homepage_displaytitle"
+#~ msgstr "ÐÑмÑгдлийн вÑб хуудаÑ"
+
+#~ msgid "devcp_addon_field_name_displaytitle"
+#~ msgstr "ÐÑмÑгдлийн нÑÑ€"
+
+#~ msgid "devcp_addon_field_privacy_displaytitle"
+#~ msgstr "Хувь хүнд холбоотой мÑдÑÑлÑл хамгаалах журам "
+
+#~ msgid "devcp_addon_field_summary_displaytitle"
+#~ msgstr "ÐÑмÑгдлийн ерөнхий тайлбар"
+
+#~ msgid "devcp_addon_field_supportemail_displaytitle"
+#~ msgstr "Лавлах захианы хаÑг"
+
+#~ msgid "devcp_addon_field_supporturl_displaytitle"
+#~ msgstr "Лавлах вÑб хуудаÑ"
+
+#~ msgid "devcp_addon_field_versionnotes_displaytitle"
+#~ msgstr "Хувилбарын Ñ‚ÑмдÑглÑгÑÑ"
+
+#~ msgid "devcp_addon_nominate_pagetitle"
+#~ msgstr "ÐÑÑ€ дÑвшигдÑÑн нÑмÑгдлүүд"
+
+#~ msgid "devcp_addon_nominated_successfully"
+#~ msgstr "ÐÑмÑгдлийн нÑÑ€ дÑвшүүлÑлт амжилттай боллоо!"
+
+#, fuzzy
+#~ msgid "devcp_addon_status_criteria_review"
+#~ msgstr "Several user reviews of the add-on (may be external reviews)."
+
+#~ msgid "devcp_addon_submission_makechanges"
+#~ msgstr ""
+#~ "%1$s хуудÑанд зорчиж илгÑÑмждÑÑ Ó©Ó©Ñ€Ñ‡Ð»Ó©Ð»Ñ‚ хийх ÑÑвÑл %2$s дÑÑÑ€ дарж "
+#~ "хөгжүүлÑгчийн үндÑÑн Ñамбарт буцна уу."
+
+#~ msgid "devcp_addon_submission_makechanges_devcp_link"
+#~ msgstr "Ñнд дарж"
+
+#~ msgid "devcp_addon_submission_makechanges_link"
+#~ msgstr "ÐÑмÑгдлийг заÑварла"
+
+#~ msgid "devcp_addon_submission_pending"
+#~ msgstr ""
+#~ "Ð­Ð½Ñ Ñ…ÑƒÐ²Ð¸Ð»Ð±Ð°Ñ€ нь Мозилагийн нÑмÑгдÑл заÑÐ²Ð°Ñ€Ð»Ð°Ð³Ð´Ð°Ð°Ñ Ò¯Ð½ÑлгÑÑ Ð´Ò¯Ð³Ð½Ñлт "
+#~ "хийлгÑÑ…ÑÑÑ€ түр хайрцганд байрлаÑан байгаа. ҮнÑлÑлт хийгдÑÑний дараа танд "
+#~ "захиагаар мÑдÑгдÑÑ… болно."
+
+#~ msgid "devcp_addon_submission_sandbox_readmore"
+#~ msgstr "Түр хайрцагт буй зүйлÑийн дүгнÑÑ… зарчмыг %s хуудаÑÐ½Ð°Ð°Ñ Ñ…Ð°Ñ€Ð½Ð° уу."
+
+#~ msgid "devcp_addon_submission_sandbox_readmore_link"
+#~ msgstr "ÑнÑ"
+
+#~ msgid "devcp_addon_submission_sandboxed"
+#~ msgstr ""
+#~ "Ð­Ð½Ñ Ñ…ÑƒÐ²Ð¸Ð»Ð±Ð°Ñ€ нь дадлага туршлагатай Ñ…ÑÑ€ÑглÑгчдÑÑÑ€ Ñ…ÑÑ€ÑглүүлÑхийн тулд түр "
+#~ "хайрцганд байрлуулагдÑан. Ðийтийн хуудÑанд харуулахын тулд та өөрийнхөө "
+#~ "нÑмÑгдлÑÑ %s Ñ…ÑÑ€ÑгтÑй бөгөөд үнÑлж дүгнÑÑ… Ñвцыг давж гарах Ñ…ÑÑ€ÑгтÑй."
+
+#~ msgid "devcp_addon_submission_sandboxed_nominate_link"
+#~ msgstr "нÑÑ€ дÑвшүүлÑÑ…"
+
+#~ msgid "devcp_addon_submission_success"
+#~ msgstr "Таны нÑмÑгдÑл илгÑÑлт амжилттай гүйцÑтгÑгдлÑÑ."
+
+#~ msgid "devcp_addon_submission_trusted_public"
+#~ msgstr ""
+#~ "Таны нÑмÑгдÑл итгÑгдÑÑн төрөлд багтдаг ÑƒÑ‡Ñ€Ð°Ð°Ñ ÑÐ½Ñ Ñ…ÑƒÐ²Ð¸Ð»Ð±Ð°Ñ€ нь автоматаар "
+#~ "нийтийн хуудÑанд орно."
+
+#~ msgid "devcp_addon_submit_pagetitle"
+#~ msgstr "ÐÑмÑгдлийг илгÑÑ"
+
+#~ msgid "devcp_addon_updated_successfully"
+#~ msgstr "ÐÑмÑгдÑл амжилттай шинÑчлÑгдлÑÑ"
+
+#~ msgid "devcp_addon_upload_preview"
+#~ msgstr "Та магадгүй %s хийж нÑмÑгдлийнхÑÑ Ñонирхлыг ихÑÑгÑж болох юм."
+
+#~ msgid "devcp_addon_upload_preview_link"
+#~ msgstr "үзүүлбÑÑ€ илгÑÑлт"
+
+#~ msgid "devcp_author_lookup_none_found"
+#~ msgstr "Зохиогч олдÑонгүй [%s]"
+
+#~ msgid "devcp_author_lookup_remove"
+#~ msgstr "УÑтга"
+
+#~ msgid "devcp_button_cancel"
+#~ msgstr "Цуцал"
+
+#~ msgid "devcp_button_cancel_confirm"
+#~ msgstr "Та илгÑÑлтÑÑ Ñ†ÑƒÑ†Ð»Ð°Ñ… гÑж буйдаа итгÑлтÑй байна уу?"
+
+#~ msgid "devcp_button_next"
+#~ msgstr "Дараах"
+
+#~ msgid "devcp_change_addontype"
+#~ msgstr "ÐÑмÑгдлийн төрөл өөрчлөх:"
+
+#~ msgid "devcp_comments_updated"
+#~ msgstr "ХөгжүүлÑгчийн тайлбар шинÑчлÑгдÑÑн."
+
+#~ msgid "devcp_details_addpreview_link"
+#~ msgstr "ҮзүүлбÑÑ€ нÑмÑÑ…"
+
+#~ msgid "devcp_details_author"
+#~ msgstr "Зохиогч"
+
+#~ msgid "devcp_details_authors"
+#~ msgstr "Зохиогч"
+
+#~ msgid "devcp_details_authors_none"
+#~ msgstr "Байхгүй"
+
+#~ msgid "devcp_details_categories"
+#~ msgstr "Төрлүүд"
+
+#~ msgid "devcp_details_category"
+#~ msgstr "Төрөл"
+
+#~ msgid "devcp_details_description"
+#~ msgstr "Тодорхойлолт"
+
+#~ msgid "devcp_details_disabled"
+#~ msgstr "ХоригдÑон"
+
+#~ msgid "devcp_details_guid"
+#~ msgstr "GUID"
+
+#~ msgid "devcp_details_header_details"
+#~ msgstr "Ðарийн мÑдÑÑлÑл"
+
+#~ msgid "devcp_details_header_devcomments"
+#~ msgstr "ХөгжүүлÑгчийн товч тайлбар"
+
+#~ msgid "devcp_details_header_previews"
+#~ msgstr "ҮзүүлбÑрүүд"
+
+#~ msgid "devcp_details_header_versions"
+#~ msgstr "Хувилбарууд"
+
+#~ msgid "devcp_details_homepage"
+#~ msgstr "Ð’Ñб хуудаÑ"
+
+#~ msgid "devcp_details_homepage_none"
+#~ msgstr "Байхгүй"
+
+#~ msgid "devcp_details_preview_nocaption"
+#~ msgstr "Гарчиггүй"
+
+#~ msgid "devcp_details_previews_nonefound"
+#~ msgstr "үзүүлбÑÑ€ олдÑонгүй."
+
+#~ msgid "devcp_details_submit_update"
+#~ msgstr "ШинÑчил"
+
+#~ msgid "devcp_details_supportemail"
+#~ msgstr "Лавлах захианы хаÑг"
+
+#~ msgid "devcp_details_supportemail_none"
+#~ msgstr "ХөгжүүлÑгчÑÑÑ Ñмар ч захианы хаÑг өгөгдөөгүй байна."
+
+#~ msgid "devcp_details_supporturl"
+#~ msgstr "Лавлах вÑб хуудаÑ"
+
+#~ msgid "devcp_details_supporturl_none"
+#~ msgstr "ХөгжүүлÑгчÑÑÑ Ñмар ч вÑб хуудаÑны хаÑг өгөгдөөгүй байна."
+
+#~ msgid "devcp_details_trusted"
+#~ msgstr "ИтгÑгдÑÑн"
+
+#~ msgid "devcp_details_versions_none_found"
+#~ msgstr "Хувилбар олдÑонгүй."
+
+#~ msgid "devcp_disable_cancel"
+#~ msgstr "Цуцлаад буцъÑ"
+
+#~ msgid "devcp_disable_disable_button"
+#~ msgstr "Тийм, үүнийг хорь"
+
+#~ msgid "devcp_disable_disable_confirm"
+#~ msgstr "Та ÑÐ½Ñ Ð½ÑмÑгдлийг хорих гÑж буйдаа итгÑлтÑй байна уу?"
+
+#~ msgid "devcp_disable_disable_description"
+#~ msgstr ""
+#~ "Ð­Ð½Ñ Ð½ÑмÑгдлийг хорьÑоноор хайх болон харуулах жагÑÐ°Ð°Ð»Ñ‚Ð½Ð°Ð°Ñ Ð½ÑƒÑƒÐ´Ð°Ð³. Мөн "
+#~ "ÑÐ½Ñ Ð½ÑŒ вÑб хуудаÑÐ½Ð°Ð°Ñ Ñ‚Ð°Ñ‚Ð°Ð¶ авагдахгүй бөгөөд Ñ…ÑÑ€ÑглÑгчÑÑÑ "
+#~ "шинÑчлÑгдÑхгүй. Уг нÑмÑгдÑл нь бараг уÑтгагдах бөгөөд Ñ…ÑÑ€Ñв та Ñ…Ò¯ÑвÑл ÑÐ½Ñ "
+#~ "хуудÑанд буцаж ирÑÑд хорих үйлдлийг цуцалж болно."
+
+#~ msgid "devcp_disable_disable_title"
+#~ msgstr "%s-г хорих"
+
+#~ msgid "devcp_disable_enable_button"
+#~ msgstr "Тийм, үүнийг зөвшөөр"
+
+#~ msgid "devcp_disable_enable_confirm"
+#~ msgstr "Та ÑÐ½Ñ Ð½ÑмÑгдлийг зөвшөөрөх гÑж буйдаа итгÑлтÑй байна уу?"
+
+#~ msgid "devcp_disable_enable_description"
+#~ msgstr ""
+#~ "Ð­Ð½Ñ Ð½ÑмÑгдлийг зөвшөөрÑөнөөр уг нÑмÑгдÑл нь хайх болон харуулах "
+#~ "жагÑаалтанд ÑргÑÑд харуулагдах болно. Мөн вÑб хуудаÑÐ½Ð°Ð°Ñ Ñ‚Ð°Ñ‚Ð°Ð¶ авагдах "
+#~ "болон Ñ…ÑÑ€ÑглÑгчÑÑÑ ÑˆÐ¸Ð½ÑчлÑгдÑÑ… боломжтой байх болно."
+
+#~ msgid "devcp_disable_enable_title"
+#~ msgstr "%s-г зөвшөөр"
+
+#~ msgid "devcp_edit_author_add"
+#~ msgstr "Зохиогч нÑмÑÑ…"
+
+#~ msgid "devcp_edit_author_email"
+#~ msgstr "Зохиогчийн захианы хаÑг"
+
+#~ msgid "devcp_edit_author_remove"
+#~ msgstr "УÑтга"
+
+#~ msgid "devcp_edit_error_categories_unavailable"
+#~ msgstr "Ð­Ð½Ñ Ð½ÑмÑгдлийн төрөлд таарÑан төрөл олдÑонгүй."
+
+#, fuzzy
+#~ msgid "devcp_edit_file_error_incomplete"
+#~ msgstr "Incomplete transfer"
+
+#, fuzzy
+#~ msgid "devcp_edit_file_error_no"
+#~ msgstr "No file uploaded"
+
+#, fuzzy
+#~ msgid "devcp_edit_file_error_size"
+#~ msgstr "Exceeds maximum upload size"
+
+#~ msgid "devcp_edit_header_authors"
+#~ msgstr "Зохиогчид"
+
+#~ msgid "devcp_edit_icon_add_link"
+#~ msgstr "ТÑмдÑг зураг нÑм"
+
+#~ msgid "devcp_edit_icon_change_link"
+#~ msgstr "ТÑмдÑг зургийг өөрчил"
+
+#~ msgid "devcp_edit_label_allow_viewsource"
+#~ msgstr "ИнтернÑÑ‚ÑÑÑ€ Ñ…ÑÑ€ÑглÑгчдÑд ÑÑ… бичлÑгийг нь харуулахыг зөвшөөр"
+
+#~ msgid "devcp_edit_label_categories"
+#~ msgstr "Төрлүүд"
+
+#~ msgid "devcp_edit_label_defaultlocale"
+#~ msgstr "Ðнхдагч нутагшил"
+
+#~ msgid "devcp_edit_label_icon_delete"
+#~ msgstr "Зөвхөн одоогийн Ñ‚ÑмдÑг зургийг арилга"
+
+#~ msgid "devcp_edit_label_icon_new"
+#~ msgstr "Ð¨Ð¸Ð½Ñ Ñ‚ÑмдÑг зураг файл"
+
+#~ msgid "devcp_edit_label_info"
+#~ msgstr "ТÑмдÑг зураг"
+
+#~ msgid "devcp_edit_locale_disambiguation_explanation"
+#~ msgstr "нÑмÑлт бичил мÑдÑÑлÑл (Ñ…ÑÑ€ÑглÑÑ… Ñ…Ñл гÑÑ… мÑÑ‚)"
+
+#~ msgid "devcp_edit_submit_update"
+#~ msgstr "ШинÑчил"
+
+#~ msgid "devcp_edit_target_locale_explanation"
+#~ msgstr ""
+#~ "<a href=\"http://wiki.mozilla.org/L10n:Simple_locale_names\">Ñ…ÑÑ€ÑглÑÑ… "
+#~ "Ñ…Ñлний нÑÑ€</a>, жишÑÑ Ð½ÑŒ 'en-US'"
+
+#~ msgid "devcp_editversion_checkedfiles_delete"
+#~ msgstr "ЧагталÑан файлууд уÑтгагдах болно."
+
+#~ msgid "devcp_editversion_filename_size"
+#~ msgstr "%1$s (%2$s)"
+
+#~ msgid "devcp_editversion_label_files"
+#~ msgstr "Файлууд"
+
+#~ msgid "devcp_editversion_label_targetapps"
+#~ msgstr "ЗориулÑан програм"
+
+#~ msgid "devcp_editversion_nofiles"
+#~ msgstr "Файл байхгүй."
+
+#~ msgid "devcp_editversion_reviewernotes"
+#~ msgstr "ҮнÑлÑл дүгнÑлт хийгчдÑд зориулÑан Ñ‚ÑмдÑглÑгÑÑ"
+
+#~ msgid "devcp_editversion_submit_update"
+#~ msgstr "ШинÑчил"
+
+#~ msgid "devcp_error_addon_field_summary_toolong"
+#~ msgstr ""
+#~ "Ерөнхий тайлбарын дÑÑд Ñ…ÑмжÑÑ Ð½ÑŒ 250 Ñ‚ÑмдÑгт.\n"
+#~ "(Та %s Ñ‚ÑмдÑгт бичÑÑн)"
+
+#~ msgid "devcp_error_addonname_not_unique"
+#~ msgstr ""
+#~ "Таны нÑмÑгдлийн нÑÑ€ өгөгдлийн бааз дотор өмнө оруулагдÑан байна. Та: <br /"
+#~ "><li>Таны GUIDs дугаар тохирч буй ÑÑÑхийг шалгана уу. Ð­Ð½Ñ Ð°Ð»Ð´Ð°Ð°Ð½Ñ‹ байнга "
+#~ "гардаг шалтгаан нь үл тохироогүй GUIDs-Ñ Ð±Ð¾Ð»Ñон байдаг.</li><li>Та "
+#~ "өгөгдлийн баазын оруулгах давхарлах Ñ…ÑÑ€Ñггүй. Ð¥ÑÑ€Ñв давхарлаÑан байгаа "
+#~ "бол Ñ‚ÑÑ€ оруулгаа шинÑчлÑÑ… ÑÑвÑл уÑтгаад дахин оролдох Ñ…ÑÑ€ÑгтÑй.</li>"
+
+#~ msgid "devcp_error_describe_changes"
+#~ msgstr "Ð­Ð½Ñ Ð½ÑмÑгдÑлд орÑон шинÑчлÑлийн өөрчлөлтийг тодорхойлно уу."
+
+#~ msgid "devcp_error_file_guids_dont_match"
+#~ msgstr "Бүх файлын GUIDs тохирÑонгүй"
+
+#~ msgid "devcp_error_identical_version_exists"
+#~ msgstr ""
+#~ "Ð­Ð½Ñ Ð½ÑмÑгдÑл болон үйлдлийн ÑиÑтемд тохирÑон ижил хувилбар (%s) өмнө нь "
+#~ "байна."
+
+#~ msgid "devcp_error_nominate_message"
+#~ msgstr "Та нÑÑ€ дÑвшүүлÑÑ…Ñд шаардагдах мÑдÑÑллүүдийг оруулах Ñ‘Ñтой."
+
+#~ msgid "devcp_error_nominate_no_prerelease"
+#~ msgstr "Та нÑмÑгдлийн урьдчилÑан хувилбарыг нÑÑ€ дÑвшүүлж болохгүй."
+
+#~ msgid "devcp_error_nominate_sandbox_only"
+#~ msgstr "Та зөвхөн түр хайрцганд байгаа нÑмÑгдлийг л нÑÑ€ дÑвшүүлж болно."
+
+#~ msgid "devcp_error_saving"
+#~ msgstr "Таны өгөгдлийг хадгалах үед алдаа гарлаа."
+
+#~ msgid "devcp_error_update_access_denied"
+#~ msgstr "Танд ÑÐ½Ñ Ð½ÑмÑгдлийг шинÑчлÑÑ… Ñрх байхгүй байна."
+
+#~ msgid "devcp_file_addanother"
+#~ msgstr "Ó¨Ó©Ñ€ үйлдлийн ÑиÑтемийн файл нÑмÑÑ…"
+
+#~ msgid "devcp_form_author_add"
+#~ msgstr "Зохиогч нÑмÑÑ…"
+
+#~ msgid "devcp_form_author_remove"
+#~ msgstr "УÑтга"
+
+#~ msgid "devcp_form_categories_nextstep"
+#~ msgstr "Таны ÑˆÐ¸Ð½Ñ Ð½ÑмÑгдлийн төрөл дараагийн алхамд боломжтой болдог."
+
+#~ msgid "devcp_form_error_categories_unavailable"
+#~ msgstr "Ð­Ð½Ñ Ð½ÑмÑгдлийн төрөлд тохирÑон төрөл байхгүй байна."
+
+#~ msgid "devcp_form_error_description_notempty"
+#~ msgstr "ÐÑмÑгдлийнхÑÑ Ñ‚Ð¾Ð´Ð¾Ñ€Ñ…Ð¾Ð¹Ð»Ð¾Ð»Ñ‚Ñ‹Ð³ оруулна уу."
+
+#~ msgid "devcp_form_error_name_required"
+#~ msgstr "ÐÑмÑгдлийнхÑÑ Ð½Ñрийг оруулна уу."
+
+#~ msgid "devcp_form_error_select_addontype"
+#~ msgstr "ИлгÑÑж байгаа нÑмÑгдлийнхÑÑ Ñ‚Ó©Ñ€Ð»Ð¸Ð¹Ð³ Ñонгоно уу."
+
+#~ msgid "devcp_form_error_summary_notempty"
+#~ msgstr "ÐÑмÑгдлийнхÑÑ ÐµÑ€Ó©Ð½Ñ…Ð¸Ð¹ тайлбарыг оруулна уу."
+
+#~ msgid "devcp_form_label_addonfile"
+#~ msgstr "ÐÑмÑгдÑл файл"
+
+#~ msgid "devcp_form_label_addonfile2"
+#~ msgstr "ÐÑмÑгдÑл файл 2"
+
+#~ msgid "devcp_form_label_addonfile3"
+#~ msgstr "ÐÑмÑгдÑл файл 3"
+
+#~ msgid "devcp_form_label_addontype"
+#~ msgstr "ÐÑмÑгдлийн төрөл"
+
+#~ msgid "devcp_form_label_allow_viewsource"
+#~ msgstr "Ð¥ÑÑ€ÑглÑгчдийн интернÑÑ‚ÑÑÑ€ ÑÑ… бичлÑгийг нь харахыг зөвшөөр"
+
+#~ msgid "devcp_form_label_author_email"
+#~ msgstr "Зохиогчийн захианы хаÑг"
+
+#~ msgid "devcp_form_label_authors"
+#~ msgstr "Зохиогчид"
+
+#~ msgid "devcp_form_label_categories"
+#~ msgstr "Төрлүүд"
+
+#~ msgid "devcp_form_label_defaultlocale"
+#~ msgstr "Ðнхдагч нутагшил"
+
+#~ msgid "devcp_form_label_description"
+#~ msgstr "Тодорхойлолт"
+
+#~ msgid "devcp_form_label_eula"
+#~ msgstr "Ð¥ÑÑ€ÑглÑгчийн лицензийн зөвшөөрөл (EULA)"
+
+#~ msgid "devcp_form_label_externalsoftware"
+#~ msgstr "Ð­Ð½Ñ Ð½ÑмÑгдÑл Ó©Ó©Ñ€ гадны програм шаарддаг юм байна"
+
+#~ msgid "devcp_form_label_files"
+#~ msgstr "Файлууд"
+
+#~ msgid "devcp_form_label_homepage"
+#~ msgstr "Ð’Ñб хуудаÑ"
+
+#~ msgid "devcp_form_label_iconfile"
+#~ msgstr "ТÑмдÑг зураг файл"
+
+#~ msgid "devcp_form_label_name"
+#~ msgstr "ÐÑÑ€"
+
+#~ msgid "devcp_form_label_platforms"
+#~ msgstr "ДÑмждÑг үйлдлийн ÑиÑтемүүд"
+
+#~ msgid "devcp_form_label_prerelease"
+#~ msgstr "Ð­Ð½Ñ Ð½ÑŒ урьдчилÑан хувилбар байна"
+
+#~ msgid "devcp_form_label_privacy"
+#~ msgstr "Хувь хүнд холбоотой мÑдÑÑллийг хамгаалах журам"
+
+#~ msgid "devcp_form_label_sitespecific"
+#~ msgstr "Ð­Ð½Ñ Ð½ÑŒ туÑгай хуудÑанд зориулÑан нÑмÑгдÑл байна"
+
+#~ msgid "devcp_form_label_summary"
+#~ msgstr "ÐÑгтгÑÑÑн мÑдÑÑлÑл"
+
+#~ msgid "devcp_form_label_supportemail"
+#~ msgstr "Лавлах захианы хаÑг"
+
+#~ msgid "devcp_form_label_supporturl"
+#~ msgstr "Лавлах вÑб хаÑг"
+
+#~ msgid "devcp_form_label_target_applications"
+#~ msgstr "ЗориулÑан програм"
+
+#~ msgid "devcp_form_label_version"
+#~ msgstr "Хувилбар"
+
+#~ msgid "devcp_form_label_versionnotes"
+#~ msgstr "Хувилбарын Ñ‚ÑмдÑглÑл"
+
+#~ msgid "devcp_form_no_target_apps"
+#~ msgstr "Байхгүй"
+
+#~ msgid "devcp_form_reviewernotes"
+#~ msgstr "ҮнÑлгÑÑ Ð´Ò¯Ð³Ð½ÑгчдÑд зориулÑан Ñ‚ÑмдÑглÑл"
+
+#~ msgid "devcp_form_trustedaddon_destination"
+#~ msgstr ""
+#~ "Таны нÑмÑгдÑл итгÑгдÑÑн жагÑаалтад багтдаг ÑƒÑ‡Ñ€Ð°Ð°Ñ Ñ…Ð°Ð°Ð½Ð° ÑÐ½Ñ Ñ…ÑƒÐ²Ð¸Ð»Ð±Ð°Ñ€ "
+#~ "очихыг Ñонгоно уу:"
+
+#~ msgid "devcp_form_trustedaddon_destination_public"
+#~ msgstr "Ðийтийн"
+
+#~ msgid "devcp_form_trustedaddon_destination_sandbox"
+#~ msgstr "Түр хайрцаг"
+
+#~ msgid "devcp_header_developer_agreement"
+#~ msgstr "ХөгжүүлÑгчийн зөвшилцөл"
+
+#~ msgid "devcp_header_step1"
+#~ msgstr "1-р алхам"
+
+#~ msgid "devcp_header_step1_upload"
+#~ msgstr "Файлаа илгÑÑÑ…"
+
+#~ msgid "devcp_header_step2"
+#~ msgstr "2-р алхам"
+
+#~ msgid "devcp_header_step2_addondetails"
+#~ msgstr "ÐÑмÑгдлийн нарийн мÑдÑÑлÑл бÑлдÑÑ…"
+
+#~ msgid "devcp_header_step3"
+#~ msgstr "3-р алхам"
+
+#~ msgid "devcp_header_step3_versiondetails"
+#~ msgstr "Хувилбарын нарийн мÑдÑÑллийг бÑлдÑÑ…"
+
+#~ msgid "devcp_header_step4"
+#~ msgstr "4-Р алхам"
+
+#~ msgid "devcp_header_step4_localization"
+#~ msgstr "Ðутагшуулах"
+
+#~ msgid "devcp_header_step5"
+#~ msgstr "5-р алхам"
+
+#~ msgid "devcp_header_step5_success"
+#~ msgstr "Ðмжилттай дууÑлаа"
+
+#~ msgid "devcp_index_header_myaddons"
+#~ msgstr "Миний нÑмÑгдлүүд"
+
+#~ msgid "devcp_nominate_link_returnto_details"
+#~ msgstr "ÐÑмÑгдлийн нарийн мÑдÑÑлÑл Ñ€Ò¯Ò¯ буцах"
+
+#~ msgid "devcp_notice_autodetected_addontype"
+#~ msgstr "Ðвтоматаар танигдÑан нÑмÑгдлийн төрөл: %s."
+
+#~ msgid "devcp_notice_different_defaultlocale"
+#~ msgstr ""
+#~ "Ð­Ð½Ñ Ð½ÑмÑгдлийн анхдагч нутагшил нь (%1$s [%2$s]) таны одоогийн ÑонгоÑон "
+#~ "Ð½ÑƒÑ‚Ð°Ð³ÑˆÐ»Ð°Ð°Ñ (%3$s [%4$s]) Ó©Ó©Ñ€ байна. Доорх талбарууд %1$s нутагшлаар "
+#~ "харуулагдах болно."
+
+#~ msgid "devcp_question_addontype_incorrect"
+#~ msgstr "Буруу юу?"
+
+#~ msgid "devcp_question_delete_file"
+#~ msgstr "Та ÑÐ½Ñ Ñ„Ð°Ð¹Ð»Ñ‹Ð³ уÑтгах гÑж буйдаа итгÑлтÑй байна уу?"
+
+#~ msgid "devcp_skip_reviewing_addon_info"
+#~ msgstr "Миний одоогийн нÑмÑгдлийн мÑдÑÑллийг шинÑчлÑÑ… үйлдлийг алгаÑ"
+
+#~ msgid "devcp_submissions_disabled"
+#~ msgstr ""
+#~ "ÐÑмÑгдÑл илгÑÑÑ… үйлдÑл одоогоор хоригдÑон. Ð¥ÑÑÑг хугацааны дараа ÑргÑж "
+#~ "шалгана уу."
+
+#~ msgid "devcp_submit_accept_dev_agreement"
+#~ msgstr "Би зөвшөөрнө"
+
+#~ msgid "devcp_submit_decline_dev_agreement"
+#~ msgstr "Би татгалзана"
+
+#~ msgid "devcp_summary_admin_disabled"
+#~ msgstr "Ð­Ð½Ñ Ð½ÑмÑгдÑл админиÑтратороор хоригдÑон байна."
+
+#~ msgid "devcp_summary_header_disabled"
+#~ msgstr "ХоригдÑон"
+
+#~ msgid "devcp_summary_header_trusted"
+#~ msgstr "ИтгÑгдÑÑн"
+
+#~ msgid "devcp_summary_noaddons_submit_one"
+#~ msgstr "Танд Ñмар ч нÑмÑгдÑл байхгүй байна. Та %s дарж нÑмÑгдÑл илгÑÑÐ½Ñ Ò¯Ò¯."
+
+#~ msgid "devcp_summary_noaddons_submit_one_link"
+#~ msgstr "Ñнд"
+
+#~ msgid "devcp_theme_upload_preview"
+#~ msgstr "Та өөрийнхөө маÑгт тохируулж %s шалгах Ñ…ÑÑ€ÑгтÑй."
+
+#~ msgid "devcp_theme_upload_preview_link"
+#~ msgstr "үзүүлбÑÑ€ нÑмж"
+
+#~ msgid "devcp_version_edit_pagetitle"
+#~ msgstr "Хувилбарыг заÑварла"
+
+#~ msgid "devcp_version_updated_successfully"
+#~ msgstr "Хувилбар амжилттай шинÑчлÑгдлÑÑ."
+
+#~ msgid "editors_submissiontype_new"
+#~ msgstr "ШинÑ"
+
+#~ msgid "editors_submissiontype_updated"
+#~ msgstr "ШинÑчлÑгдÑÑн"
+
+#, fuzzy
+#~ msgid "editors_th_addon_age"
+#~ msgstr "Addon Age"
+
+#~ msgid "editors_th_addontypes"
+#~ msgstr "ÐÑмÑгдлийн төрөл"
+
+#~ msgid "editors_th_age"
+#~ msgstr "ÐаÑ"
+
+#~ msgid "editors_th_applications"
+#~ msgstr "Програмууд"
+
+#~ msgid "editors_th_platforms"
+#~ msgstr "Үйлдлийн ÑиÑтем"
+
+#~ msgid "editors_th_submissiontypes"
+#~ msgstr "ИлгÑÑÑ… төрөл"
+
+#~ msgid "error_notice"
+#~ msgstr "ТÑмдÑглÑгÑÑ"
+
+#~ msgid "forum_save"
+#~ msgstr "Хадгал"
+
+#, fuzzy
+#~ msgid "home"
+#~ msgstr "home"
+
+#~ msgid "nav_category_plugins"
+#~ msgstr "Плагинууд"
+
+#, fuzzy
+#~ msgid "page_title_experimental_addons"
+#~ msgstr "Experimental Add-ons"
+
+#~ msgid "pages_experimental_addons_backbutton"
+#~ msgstr "Өмнөх хуудÑанд буцах"
+
+#~ msgid "pagination_page_number_title"
+#~ msgstr "Ðийт %2$s хуудаÑны %1$s дугаарх нь"
+
+#~ msgid "search_matching_addons_number"
+#~ msgid_plural "search_matching_addons_number"
+#~ msgstr[0] "%s тохирол"
+#~ msgstr[1] "%s тохирол"
+
+#~ msgid "statistics_rss_icon_title"
+#~ msgstr "ДүгнÑÑÑн өгөгдлийн RSS мÑдÑÑлÑлт"
diff --git a/site/app/locale/mn/images/sandbox-review.png b/site/app/locale/mn/images/sandbox-review.png
new file mode 100644
index 0000000..4322df9
--- /dev/null
+++ b/site/app/locale/mn/images/sandbox-review.png
Binary files differ
diff --git a/site/app/locale/mn/pages/error404.thtml b/site/app/locale/mn/pages/error404.thtml
new file mode 100644
index 0000000..69f2a63
--- /dev/null
+++ b/site/app/locale/mn/pages/error404.thtml
@@ -0,0 +1,16 @@
+<h1>Таны хайгаад байгаа зүйлийг харамÑалтай нь бид олÑонгүй.</h1>
+
+<p>Таны Ñ…Ò¯ÑÑÑн Ñ…ÑƒÑƒÐ´Ð°Ñ ÑÑвÑл файл нь бидний Ñ…ÑƒÑƒÐ´Ð°Ñ Ð´ÑƒÐ½Ð´Ð°Ð°Ñ Ð¾Ð»Ð´Ñонгүй. Магадгүй та хуучирÑан Ñ…Ð¾Ð»Ð±Ð¾Ð¾Ñ Ð´ÑÑÑ€ дарÑан юмуу ÑÑвÑл хаÑгийн талбар дÑÑÑ€ буруу хаÑг оруулÑан ч байж болох юм.</p>
+
+<ul>
+<li>Ð¥ÑÑ€Ñв та хаÑгийн талбар дÑÑÑ€ бичÑÑн бол зөв бичÑÑн ÑÑÑÑ…ÑÑ Ð´Ð°Ð²Ñ…Ð°Ñ€ шалгана уу.</li>
+<li>Ð¥ÑÑ€Ñв та Ó©Ó©Ñ€ нÑг хуудаÑÐ½Ð°Ð°Ñ Ñ…Ð¾Ð»Ð±Ð¾Ð¾Ñ Ð´ÑÑÑ€ дарж ирÑÑн бол <a href="mailto:webmaster@mozilla.com" title="Page Not Found on Mozilla.com">webmaster@mozilla.com</a> хаÑг руу илгÑÑж бидÑнд мÑдÑгдÑÐ½Ñ Ò¯Ò¯. Үүнд та Ñ…Ð°Ð°Ð½Ð°Ð°Ñ Ð¸Ñ€ÑÑн болон юу хайж байгаагаа тодорхойлж бичих Ñ…ÑÑ€ÑгтÑй. ТÑгÑнÑÑÑ€ бид нар чадах бүхнÑÑ Ñ…Ð¸Ð¹Ð¶ үүнийг заÑахыг хичÑÑÑ… болно.</li>
+</ul>
+
+<p>ЭÑвÑл та манай нийтÑд өргөн тархÑан хуудаÑны нÑгÑнд шилжиж болох юм.</p>
+
+<ul>
+<li>Та <a href="%1$s">өргөн тархÑан нÑмÑгдлийн жагÑаалт</a> хайÑан юм биш биз?</li>
+<li>Та <a href="%2$s">нÑмÑгдÑл хаймаар байна уу</a>? Магадгүй та <a href="%2$s">хайх хуудÑанд</a> очих, ÑÑвÑл доорх хайх талбарыг Ñ…ÑÑ€ÑглÑж болно.</li>
+<li>ЭÑвÑл та ерөөÑÓ©Ó© ÑхнÑÑÑ Ð½ÑŒ ÑхлÑе гÑж бодож байвал <a href="%3$s">нÑмÑгдлийн ÑхлÑл хуудÑанд </a> зорчиж болно.</li>
+</ul>
diff --git a/site/app/locale/mn/pages/nomination.thtml b/site/app/locale/mn/pages/nomination.thtml
new file mode 100644
index 0000000..54fa538
--- /dev/null
+++ b/site/app/locale/mn/pages/nomination.thtml
@@ -0,0 +1,8 @@
+<p>Түр хайрцагт байгаа нÑмÑгдÑл нь нийтийн хуудÑанд орохоор нÑÑ€ дÑвшүүлÑгдÑж болох бөгөөд заÑварлагчаар шалгагдаж дүгнÑгдÑÑний дараа олон нийтÑд ил тавигддаг. Ð­Ð½Ñ Ò¯Ðµ шатыг амжилттай давахын тулд дараах зүйлÑийг анхаарах Ñ…ÑÑ€ÑгтÑй:</p>
+<ul>
+ <li>БуÑад бүх нÑмÑгдлийн төрлүүдийн харуулах маÑгт шаардагддаг Ñ‚ÑмдÑгт зурагнууд нь их дÑмжлÑг авдаг. </li>
+ <li>ÐÑмÑгдÑл нь Ñ…ÑÑ€ÑглÑгчдÑÑÑ Ñ…Ð°Ð½Ð³Ð°Ð»Ñ‚Ñ‚Ð°Ð¹ Ñанал Ñ…Ò¯ÑÑлт шүүмжлÑл хүлÑÑж авахаар хугацаанд түр хайрцаг дотор байх шаардлагатай</li>
+ <li>Ðийтийн хуудÑанд буй нÑмÑгдÑл нь түр хайрцагт буй нÑмÑгдлÑÑÑ Ð´Ð°Ð²ÑƒÑƒ ÑрхтÑй байдаг</li>
+ <li>ÐÑÑ€ дÑвшÑÑн нÑмÑгдлийн шалгуурын талаар <a href="%s">ÐÑмÑгдлийн журам</a> хуудÑанд бичÑÑн байгаа.</li>
+</ul>
+<p>Ð¥ÑÑ€Ñв таны нÑмÑгдлүүд дÑÑрх шаардлагыг биелүүлÑÑн бол та доорх товчин дÑÑÑ€ дарж нÑмÑгдлÑÑ Ð½ÑÑ€ дÑвшүүлж болно. ÐÑÑ€ дÑвшүүлÑлтийн төлөв байдлын талаар танд захиагаар мÑдÑгдÑÑ… болно.</p>
diff --git a/site/app/locale/mn/pages/policy.thtml b/site/app/locale/mn/pages/policy.thtml
new file mode 100644
index 0000000..ac0f8b7
--- /dev/null
+++ b/site/app/locale/mn/pages/policy.thtml
@@ -0,0 +1,110 @@
+<h1>ÐÑмÑгдлийн журам</h1>
+
+<h2>Түр хайрцаг гÑж юу вÑ?</h2>
+<p>%s хуудаÑÐ½Ð°Ð°Ñ Ñ…Ð°Ñ€Ð½Ð° уу.</p>
+
+<h2>Ямар нÑмÑгдÑл түр хайрцагт байгаа вÑ?</h2>
+<p>Түр хайрцаг дотор ÐМО дÑÑÑ€ байлгах бүх нÑмÑгдлийн ÑхлÑл Ñ…ÑÑÑг юм. Энд нÑмÑгдлүүдийн ÑˆÐ¸Ð½Ñ Ñ…ÑƒÐ²Ð¸Ð»Ð±Ð°Ñ€ÑƒÑƒÐ´, мөн олон нийтийн Ñ…ÑƒÑƒÐ´Ð°Ñ ÑƒÑ€ÑƒÑƒ орж чадаагүй нÑмÑгдлүүд байдаг. Ð¥ÑÑ€Ñв ÑˆÐ¸Ð½Ñ Ð½ÑмÑгдÑл юмуу ÑÑвÑл өмнөх хувилбараа шинÑчлÑÑÑн нÑмÑгдÑл байгаад ÐМО руу илгÑÑгдÑж байгаа бол түр хайрцагт ÑхлÑÑд орно. </p>
+
+<p>Зөвхөн зарим нÑмÑгдлийн тодорхой хувилбарууд нь шалгаж дүгнÑгдÑÑ… Ñвцад олон нийтийн хуудÑанд орж болно гÑж тооцогдÑон тохиолдолд нийтийн хуудÑанд ордог. БуÑад нь тодорхойгүй хугацаагаар түр хайрцагтаа үлддÑг бөгөөд зөвхөн түр Ñ…Ð°Ð¹Ñ€Ñ†Ð°Ð³Ð½Ð°Ð°Ñ Ñуулгаж шалгах Ñ…Ò¯ÑÑлтÑй Ñ…ÑÑ€ÑглÑгчидÑд боломжтой байх болно. </p>
+
+<h2>ÐÑмÑгдÑл Ñ…ÑрхÑн олон нийтийн хуудÑанд ордог вÑ?</h2>
+
+<p>ÐÑмÑгдлүүд ÐМО-гий Ñ…ÑÑ€ÑглÑгчдÑÑÑ€ түр хайрцагт байх үед шалгуулж дүгнÑлт авдаг. Ийм үнÑлгÑÑ Ð´Ò¯Ð³Ð½Ñлт нь уг нÑмÑгдлийг Firefox-н Ñ…ÑÑ€ÑглÑгчдийн нÑмÑгдлийн хуудÑанд харуулагдахад тун их дөхөм болдог. ЭдгÑÑÑ€ үнÑлгÑÑ Ð´Ò¯Ð³Ð½Ñлт нь мөн ÐМО багийн гишүүдийн тухайн нÑмÑгдлийг олон нийтийн хуудÑанд оруулах уу ÑÑвÑл дахин нÑмÑлт заÑвар хийх Ñ…ÑÑ€ÑгтÑй юу, ÑÑвÑл уг нÑмÑгдлийг ÐМО гийн хуудÑан дÑÑÑ€ гаргаж Ñурталчлах шаардлага байгаа ÑÑÑÑ… зÑÑ€Ñг шийдÑл гаргахад тун их чухал үүрÑг гүйцÑтгÑдÑг. </p>
+
+<h2>Олон нийтийн хуудÑанд Ñаж нÑÑ€ дÑвшүүлÑÑ… вÑ?</h2>
+
+<p>Ð¥ÑÑ€Ñв таны нÑмÑгдÑл олон нийтийн нÑмÑгдÑлд тавигддаг шаардлагыг хангаÑан гÑж бодож байгаа бол түүнийгÑÑ Ñ‚Ð° хөгжүүлÑгчдийн Ñ…Ñналтын ÑÐ°Ð¼Ð±Ð°Ñ€Ð°Ð°Ñ Ð½ÑÑ€ дÑвшүүлÑÑ… Ñ…ÑÑ€ÑгтÑй.</p>
+
+<h2>Олон нийтийн нÑмÑгдÑлд Ñмар шаардлага тавигддаг вÑ?</h2>
+
+<p>ÐМО-н нийтийн хуудÑанд буй нÑмÑгдÑл нь өндөр чанарын байх Ñ‘Ñтой бөгөөд вÑб Ñ…ÑÑ€ÑглÑгчдийн Ñ…ÑÑ€ÑглÑÑг Ñайжруулахаар байх Ñ‘Ñтой. Бид нÑмÑгдлийг ÐМО-н нийтийн хуудÑанд оруулахааÑаа өмнө дараах Ð·Ò¯Ð¹Ð»Ñ Ñ…Ð°Ð½Ð³Ð°Ð³Ð´Ñан ÑÑÑхийг хардаг:</p>
+
+<h3>Та хариуцлага хүлÑÑÑ… чадвартай юу?</h3>
+
+<p>Бид тухайн нÑмÑгдлийг Firefox-н хуудÑанд оруулж олон нийтÑд харуулахыг Ñ…Ò¯ÑÑÑн Ð·Ð¾Ñ…Ð¸Ð¾Ð³Ñ‡Ð¾Ð¾Ñ Ð½ÑŒ уг нÑмÑгдÑлтÑй холбоотой алдааны мÑдÑÑллийг хариуцан даах, холбоо харьцаагаа бататгаж одоогийн Firefox-н хувилбартай нийцүүлÑн шинÑчилж арчлах мөн Ñ…ÑÑ€Ñв ÐМО-н нÑмÑгдлийн журам өөрчлөгдвөл түүнд зохицуулж арчлан торниулж байх хариуцлагыг шаарддаг. Ð­Ð½Ñ Ð½ÑŒ гÑхдÑÑ Ð½ÑмÑгдлийн Ñанал Ñ…Ò¯ÑÑлтÑд тавигдÑан аÑуулт болгонд хариулах юмуу ÑÑвÑл нÑмÑгдÑлд гарÑан програмынхаа цоорхой болгоныг нөхөх гÑÑÑн үг биш боловч ерөнхийдөө нÑмÑгдÑлтÑй холбоотой гол аÑуултуудад хариулж байхыг шаардана..</p>
+
+<h3>ÐÑмÑгдÑл цÑвÑрхÑн зөв тодорхойлогдож уу?</h3>
+
+<p>БидÑнд хамгийн чухал зүйл бол Ñ…ÑÑ€Ñв Ñ…ÑÑ€ÑглÑгч ÑˆÐ¸Ð½Ñ Ð½ÑмÑгдлийг туршаад Ñ…Ò¯ÑÑÑн зүйлд нь таарч байх билÑÑ. Та нÑмÑгдлÑÑ ÑŽÑƒ хийдгийг нь нарийвчилж тодорхойлж өгөх Ñ‘Ñтой бөгөөд Ñ…ÑÑ€ÑглÑгч Ñ…ÑÑ€ÑглÑÑнÑÑÑ€ Ñ…ÑрхÑн давуу талтай болох болон ÑуулгаÑны дараа Ñ…ÑÑ€ÑглÑгчийн Ñмар Ñ…Ò¯ÑÑлд таарах талаар тодорхойлж өгөх Ñ…ÑÑ€ÑгтÑй. Ó¨Ó©Ñ€ вÑб хуудÑанд буй нарийвчилÑан мÑдÑÑлÑл Ñ€Ò¯Ò¯ холбож өгÑөн байх нь зүгÑÑÑ€ бөгөөд гÑхдÑÑ Ñ…ÑÑ€ÑглÑгчид уг нÑмÑгдлийн ерөнхий тодорхойлолтыг авÑан байхаар тодорхойлолттой байх Ñ‘Ñтой бөгөөд Ñ…ÑÑ€ÑглÑгч нÑмÑлт Ñ…ÑƒÑƒÐ´Ð°Ñ ÑƒÑ€ÑƒÑƒ Ñвахаа Ó©Ó©Ñ€Ó©Ó© мÑдÑÑ…ÑÑÑ€ байх Ñ‘Ñтой.</p>
+
+<p>Мөн шинÑчлÑлд гарÑан өөрчлөлт болгонд тодорхой Ñ‚ÑмдÑглÑгÑÑÑ‚Ñй байх нь чухал. ИнгÑÑнÑÑÑ€ Ñ…ÑÑ€ÑглÑгчид ÑуулгахааÑаа өмнө уг нÑмÑгдÑлд гарÑан өөрчлөлтүүдийг харах боломжтой болох бөгөөд одоогийн ÑуулгаÑан Ñ…ÑƒÐ²Ð¸Ð»Ð±Ð°Ñ€Ð°Ð°Ñ Ð½ÑŒ юу нь өөрчлөгдөхийг мÑдÑж Ñуулгах ÑÑÑÑ…ÑÑ ÑˆÐ¸Ð¹Ð´ÑÑ…Ñд дөхөм үзүүлдÑг. (Одоогоор хөтлөгч дотор буй автомат шинÑчлÑгч дÑÑÑ€ ийм мÑдÑÑлÑл харуулагддаггүй бөгөөд бид үүнийг заÑах болно. Ð¥ÑÑ€Ñв та хувилбарын өөрчлөлтийн Ñ‚ÑмдÑглÑгÑÑг Ñайн хийдÑг бол үүнийг заÑагдÑан хойно зохицоход тань амархан байх болно.)</p>
+
+<h3>Хувь хүнд холбогдолтой мÑдÑÑллийг хадгалах журам болон нөхцлүүд тод заагдÑан уу?</h3>
+
+<p>Ð­Ð½Ñ Ñ…ÑÑÑг нь маш зөв тодорхой заагдÑан Ñ…ÑÑÑг байх Ñ‘Ñтой бөгөөд бид үүнийг зарим нÑгÑнд нь чухал Ñ…ÑÑÑг гÑдгийг мÑднÑ. Маш Ñайн зохиогдÑон олон нÑмÑгдлүүд нь Ñмар нÑгÑн Ñ…ÑлбÑÑ€ÑÑÑ€ Ñ…ÑÑ€ÑглÑгчийн өгөгдлийг өөрчлөх ÑÑвÑл зарим нь буруу ашиглагдвал нууцлалын аюулгүй байдлыг ÑвдÑÑ… нөхцөл гарч болзошгүй билÑÑ. Ийм нÑмÑгдлүүд нь олон нийтийн нÑмÑгдлийн хуудÑан дÑÑÑ€ байж болох боловч Ñ…ÑÑ€ÑглÑгчид учрах аюулгүйн болон мÑдÑÑллийн ÑÑ€Ñдлийг маш тодорхой зааж өгÑөн байх Ñ‘Ñтой бөгөөд Ñ…ÑрхÑн хамгаалах талаар мөн зааварлаÑан байх Ñ‘Ñтой.</p>
+
+<h3>ÐÑмÑгдÑл Ñайн шалгагдÑан бөгөөд Ñмар нÑгÑн алдаа дутагдалгүй юу?</h3>
+
+<p>Ðийтийн хуудÑанд орох гÑж буй нÑмÑдлÑÑÑ Ð±Ð¸Ð´ нарын шалгадаг нÑг чухал зүйл бол уг нÑмÑгдлийг түр хайрцагт байхад нь шалгаж дүгнÑÑÑн үнÑлгÑÑ Ð±Ó©Ð³Ó©Ó©Ð´ Ñмар нÑгÑн хүндрÑлийг хөтлөгчид учруулахгүй байх баталгаа юм. Ð¥ÑÑ€Ñв дүгнÑж шалгаÑан Ñ…Ò¯Ð¼Ò¯Ò¯Ñ Ð¶Ð¸ÑˆÑÑ Ð½ÑŒ гÑнÑтийн ÑвдрÑл, ÑÑвÑл алдааны цонх уруу шидÑгдÑÑ… алдаануу, гүйцÑтгÑлийн Ñмар нÑгÑн аÑуудал зÑргийг дурдÑан бол Ñ‚ÑдгÑÑрийг та тун анхааралтай хүлÑÑж аван заÑаад дахин нÑÑ€ дÑвшүүлÑÑ… Ñ…ÑÑ€ÑгтÑй. Бид мÑдÑÑÑж таныг Ñ‚Ó©Ð³Ñ ÑŽÐ¼ хийж Ñмар ч алдаагүй програм бичихийг шаардахгүй. ГÑхдÑÑ Ð±Ð¸Ð´ таныг гарах муу талуудыг багаÑгаж Ñүүлд Ñ…ÑÑ€ÑглÑгчдийг алмайруулахааргүй зүйл хийхийг Ñ…Ò¯ÑÑж байна.</p>
+
+<p>Ð¥ÑÑ€Ñв таны нÑмÑгдÑл ÐМО-н түр Ñ…Ð°Ð¹Ñ€Ñ†Ð°Ð³Ð½Ð°Ð°Ñ Ó©Ó©Ñ€ жишÑÑ Ð½ÑŒ бүлÑг Ñ…ÑÑ€ÑглÑгч, ÑÑвÑл албан байгууллага, үгүй бол туÑгай шалган Ñ…Ñнах хороогоор шалгагдÑан бол нÑÑ€ дÑвшүүлÑÑ… Ñ…ÑÑÑгтÑÑ Ñ‚Ð° дурдах Ñ…ÑÑ€ÑгтÑй. Ð­Ð½Ñ Ð½ÑŒ мÑдÑÑж бид нар Ñмар түвшинд шалгагдÑаныг харж хуудÑанд нÑмж болох шийдÑлд нөлөөлөх болно.</p>
+
+<h3>ÐÑмÑгдÑл болон нÑмÑгдÑл зохиогч хоёр Ñ…ÑÑ€ÑглÑгчдийг хүндÑтгÑж байна уу?</h3>
+
+<p>Таны програм Ñ…ÑÑ€ÑглÑгчийн мÑдÑÑлÑл руу дайрах, Ñ…ÑÑ€ÑглÑгчийг хуурах, ÑÑÑвл Ñ…ÑÑ€ÑглÑгчийг буруу үйлдÑл Ñ€Ò¯Ò¯ шахах зÑÑ€Ñг үйлдлүүд хийж болохгүй. Зарим Ñ…ÑÑ€ÑглÑгчид (ÑÑвÑл Ñ…ÑÑ€ÑглÑгч биш хүмүүÑ) Ñанал ÑÑтгÑгдлÑÑ Ð±Ò¯Ð´Ò¯Ò¯Ð»Ð³ÑÑÑ€ бичÑÑн байдаг бөгөөд бид Ñ‚ÑдгÑÑрийг аль болох шүүж зохиогчийг ийм бүдүүлÑг Ñ‚Ð°Ð¹Ð»Ð±Ð°Ñ€Ð°Ð°Ñ Ð±Ð¾Ð»Ð¶ урамгүй Ð±Ð¾Ð»Ð¾Ñ…Ð¾Ð¾Ñ ÑÑргийлж байдаг.</p>
+
+<h3>Уг нÑмÑгдÑл Firefox-н өргөн Ñ…ÑÑ€ÑглÑгчдÑд Ñ…ÑÑ€ÑгтÑй юу?</h3>
+
+<p>Таны нÑмÑгдÑл нь Greasemonkey ÑÑÑвл FireBug зÑÑ€Ñг нÑмÑгдлийн дараагийн шилдÑг нь байх алба үгүй. ГÑхдÑÑ Ñ…ÑÑ€Ñв уг нÑмÑгдÑл нь зөвхөн тодорхой бүлÑг хүмүүÑд зориулÑан юмуу ÑÑвÑл зөвхөн таны байгууллагад зориулÑан бол бид түүнийг нь харгалзаж Firefox-н нийтлÑг Ñ…ÑÑ€ÑглÑгчдийн өмнө харуулах ÑÑÑÑ…ÑÑ ÑˆÐ¸Ð¹Ð´ÑÑ… болно.</p>
+
+<p>Бид Ó©Ó©Ñрдийнхөө нÑмÑгдлийн хуудÑыг цөөхөн хүний хүчÑÑÑ€ аль болох Ñайхан харуулж Ñайжруулахыг хичÑÑж байгаа бөгөөд таны нÑмÑгдÑлдÑÑ Ð·Ó©Ð² зааж өгÑөн тодорхойлолтын ачаар Ñ‚ÑдгÑÑрийг ангилж зохицуулан Ñ…Ñнд Ñмар нÑмÑгдÑл харуулах Ñ‘Ñтой зÑÑ€Ñг шийдÑл хийхÑд тун дөхөм болдог. </p>
+
+<p>Ð¥ÑÑ€Ñв таны нÑмÑгдÑл зөвхөн цөөхөн хаÑгууд юмуу Ó©Ó©Ñ€ вÑб Ñ…ÑƒÑƒÐ´Ð°Ñ Ñ€ÑƒÑƒ зорчих Ñ…Ð¾Ð»Ð±Ð¾Ð¾Ñ Ð·Ñргийг хангаж байгаа бол бид нар түүнийг нийтийн хуудÑанд байх зүйл биш гÑж тоооцно. БуÑад мозилагийн Ñ‚Ó©Ñлүүд шиг бид нар ÑˆÐ¸Ð½Ñ Ð²Ñб үйлчилгÑÑнд дуртай бөгөөд Firefox-н нÑмÑгдлүүд нь вÑб хөтлөлтийг ÑайжруулÑан байх Ñ‘Ñтой Ð±Ð¾Ð»Ð¾Ñ…Ð¾Ð¾Ñ Ð²Ñб хуудаÑнуудыг Ñурталчлах Ñ‘Ñгүй билÑÑ. Ð¥ÑÑ€Ñв таны нÑмÑгдлийн тодорхойлолт нь вÑб хуудаÑны зорчилтыг Ñайжруулах биш харин вÑб Ñ…ÑƒÑƒÐ´Ð°Ñ Ñурталчлах тухай байвал та буруу газар үйлдÑж байна гÑÑÑн үг.</p>
+
+<h3>ÐÑмÑгдÑл чөлөөт ÑÑ… бичлÑгтÑй юу ÑÑвÑл зохиогчийн ÑрхтÑй юу?</h3>
+
+<p>Ð¥ÑдийгÑÑÑ€ таны нÑмÑгдлүүд Ñөрөг нөлөө үзүүлÑÑ…ÑÑргүй зохиогчийн Ñрх юмуу худалдааны ÑрхтÑй гÑж бодож байÑан ч маид нар Ñмар нÑгÑн худалдааны Ñрх болох зохиогчийн хууль Ñрх зүйтÑй орооцолдмооргүй байдаг. Ð¥ÑÑ€Ñв та зохиогчийнх нь Ñрх болон бүтÑÑгдÑхүүний нÑрийг ÑзÑмших Ñрхгүй бол уг нÑмÑгдлийг ÐМО руу илгÑÑÑний Ñ…ÑÑ€Ñггүй. Ð¥ÑÑ€Ñв та Ó©Ó©Ñ€ хүний зохиогчийн ÑрхтÑй бичлÑгийг өөрийнхөө нÑмÑгдÑлд зөвшөөрөлгүй нÑмÑÑн бол ÐМО руу илгÑÑгÑÑд Ð±Ð°Ñ Ñ…ÑÑ€Ñггүй. (Ð¥ÑÑ€Ñв Ñмар нÑгÑн хууль зүйд харшлах Ð·Ò¯Ð¹Ð»Ñ Ð¸Ð»ÑрвÑл шалгах Ñ…Ò¯Ð¼Ò¯Ò¯Ñ ÑƒÐ³ Ñ…ÑÑгийг таÑдаж авахыг Ñ‚Ð°Ð½Ð°Ð°Ñ Ñ…Ò¯ÑÑÑ… бөгөөд шаардлагатай бол уг нÑмÑгдлийг уÑтгах болно. Хууль зүйтÑй аÑуудлыг шийдÑÑ…Ñд зарцуулагддаг цаг болон мөнгө Ñ…ÑмнÑÑ… үүднÑÑÑ Ð¸Ð¹Ð¼ шуурхай арга Ñ…ÑмжÑÑг авч байгааг та ойлгоно буй заа.)</p>
+
+<p>Ð¥ÑÑ€Ñв та нÑмÑгдлийнхÑÑ Ð½Ñрийг тогтож чадаагүй юмуу Ñаж Ñ…ÑÑ€ÑглÑхийг нь тогтож шийдÑÑгүй бол нÑмÑгдлийн жагÑаалтанд оруулахааÑаа түдгÑлзÑÑ… Ñ…ÑÑ€ÑгтÑй бөгөөд amo-editors@mozilla.org хаÑг руу бичиж заавар туÑламж авах Ñ…ÑÑ€ÑгтÑй. ЧУХÐЛ: ЭдгÑÑÑ€ Ñ…Ò¯Ð¼Ò¯Ò¯Ñ Ð½ÑŒ хууль зүйн туÑламж өгдөггүй бөгөөд Ñ…ÑÑ€Ñв уг нÑмÑгдÑл хичнÑÑн хүлÑÑж авахуйц мÑÑ‚ байÑан ч Ñмар нÑгÑн хууль зүйн шийдÑл мÑдÑгдÑÑн үед бид Ñ‚ÑÑ€ ÑÑдвийг дахин хөндөх болно.</p>
+
+<p>ÐÑмÑгдÑлдÑÑ Ó©Ó©Ñ€ хүмүүÑийн бичлÑг Ñ…ÑÑ€ÑглÑхдÑÑ, Ñ…ÑÑ€Ñв зохиогч нь таныг өөрийнхөө бичлÑгт Ñ…ÑÑ€ÑглÑж болно гÑж тов тодорхой жишÑÑ Ð½ÑŒ нÑÑлттÑй ÑÑ… бичлÑг шиг зааж өгөөгүй бол та түүнийг Ñ…ÑÑ€ÑглÑж болохгүй гÑж авч үзÑÑ… Ñ…ÑÑ€ÑгтÑй. Та зохиогчтой нь холбоо барьж зөвшөөрөл авч болох боловч бид нарын зүгÑÑÑ Ð·Ó©Ð²Ñ…Ó©Ð½ ÐМО дÑÑÑ€ байрлуулах үндÑÑлÑлÑÑÑ€ юмуу ÑÑвÑл уг зохиолч таны аÑуултанд хариулаагүй зÑÑ€Ñгт Ñмар ч хууль зүйн туÑламж үзүүлÑхгүй. (Мөн дахин Ñануулахад бид Ñмар ч хууль зүйн зөвлөгөө өгдөггүй харин зөвхөн таны нÑмÑгдÑл ÑÐ½Ñ Ñ…ÑƒÑƒÐ´Ð°Ñны журамтай Ñ…ÑрхÑн зөрж байгааг л зөвлөж чадна.)</p>
+
+<p>Ð­Ð½Ñ Ð½Ó©Ñ…Ñ†Ó©Ð» Мозила Ñангийн худалдааны Ñрх, "Mozilla", "Firefox", мөн "Thunderbird" зÑÑ€Ñг бүтÑÑгдÑхүүнд мөн хамаарна. Мозилагийн худалдааны Ñрхийн журам нь Ñмар нÑгÑн үл ойлголцол болон хамгаалалтгүйгÑÑÑ Ð±Ð¾Ð»Ð¶ худалдааны Ñрх алдах зÑргÑÑÑ ÑÑргийлÑÑн журам болохоор бидний иймÑрхүү хамгаалалтыг хүндлÑн ойлгож Мозила Ñангийн журмыг баримтлана уу.</p>
+
+<h2>Ðамайг Ñмар нÑгÑн зүйлийг нÑÑ€ дÑвшүүлÑний дараа юу болдог вÑ?</h2>
+
+<p>Таны нÑмÑгдÑл нÑÑ€ дÑвшигдÑÑний дараа дÑÑрх зааÑан шалгууруудын дагуу ÐМО-н заÑварлагчид шалгаж дүгнÑдÑг. Таны нÑмÑгдÑл Ñ…ÑÑ€Ñв давж шалгагдлаа гÑж үзвÑл олон нийтийн Ñ…ÑƒÑƒÐ´Ð°Ñ Ñ€ÑƒÑƒ шилжүүлÑгддÑг бөгөөд танд мÑдÑгдÑÑн захиа илгÑÑÑ… болно.</p>
+
+<p>Ð¥ÑÑ€Ñв бид таны нÑмÑгдлийг ÐМО-н хуудÑанд тохирохооргүй юм байна гÑж үзвÑл Ñагаад гÑÑÑн үндÑÑлÑлийг зааÑан захиаг танд Ð±Ð°Ñ Ð¸Ð»Ð³ÑÑÑ… бөгөөд таны нÑмÑгдлийг нÑÑ€ дÑвшүүлÑÑ… Ð´Ð°Ñ€Ð°Ð°Ð»Ð»Ð°Ð°Ñ Ð°Ð²Ð´Ð°Ð³. Ð¥ÑÑ€Ñв та тухайн мÑдÑгдÑлд зааÑан зүйлÑийг заÑаж Ñнзлаад мөн Ñ…Ò¯ÑвÑл дахин нÑÑ€ дÑвшүүлж болно. Ямар нÑгÑн тодорхой өөрчлөлт хийгÑÑгүй байж дахин нÑÑ€ дÑвшүүлÑÑ… үйлдÑл нь бидÑнд хүндлÑгдÑхгүй бөгөөд иймÑрхүү хүндрÑлийг бид ноцтой авч үзÑÑ… болно.</p>
+
+<h2>Би Ó©Ó©Ñ€ хүний нÑмÑгдлийг нÑÑ€ дÑвшүүлж болох уу?</h2>
+
+<p>Одоогоор бид нÑмÑгдлийг зохиоÑон хүнÑÑÑ Ð½ÑŒ нÑÑ€ дÑвшүүлÑхийг аÑууж байгаа. ИнгÑÑнÑÑÑ€ бид уг нÑмÑгдлийг зохиоÑон хүн нь тухайн бүтÑÑгдÑхүүнийхÑÑ Ñ‡Ð°Ð½Ð°Ñ€Ñ‹Ð½ талаарх мÑдÑÑллÑÑ Ð¸Ð»Ò¯Ò¯ Ñайн авах болно гÑж боддог. Ð¥ÑÑ€Ñв та уг нÑмÑгдÑл маш Ñайн болÑон бөгөөд зохиогч нь захиагаар ÐМО-н журмыг дагаÑнаа мÑдÑгдÑж мөн Firefox болон түүний Ñ…ÑÑ€ÑглÑж буй олон зуун хүнд Ñ…ÑÑ€ÑгтÑй гÑж үзÑÑн бол зохиогчийн нÑмÑгдлÑÑ Ð½ÑÑ€ дÑвшүүлÑÑ…Ñд нь туÑлаж болох юм.</p>
+
+<h2>Миний нÑмÑгдÑл нÑÑ€ дÑвшүүлÑÑ… дараалалд маш удаан байж байна, та нар намайг үзÑн Ñдаад байгаа юм уу?</h2>
+
+<p>Бид таны Ñахан үзÑÑ… Ñдах билÑÑ. Бид нÑмÑгдÑл хөгжүүлÑгчдÑд хайртай бөгөөд Ñ‚Ñд нарыг аз жаргалтай үр бүтÑÑлтÑй байж Ñ‚Ñд нарын бүтÑÑгдÑхүүнийг Ñ…ÑÑ€ÑглÑгчид аÑтайхан Ñ…ÑÑ€ÑглÑж байхын тулд бид шаргуу ажиллацгааж байна. ÐМО дÑÑÑ€ нийтийн хуудÑанд байлгах нь маш Ñ…Ñнуур ажиллагаа бөгөөд зөвхөн хурдан гүйцÑтгÑÑ… гÑж бид Ñарч болдоггүй. ÐœÑдÑÑж таны нÑмÑгдлийг удаан байлгах нь уур хүргÑм гÑдгийг бид ойлгож байгаа бөгөөд аль болох хурдан шийдÑхийг хичÑÑж байдаг. Түр хайрцагт байхад нь шалгаж дүгнÑлт өгдөг Ñ…Ò¯Ð¼Ò¯Ò¯Ñ Ð±Ð¾Ð» тун Ñайн шалгадаг бөгөөд Ñ‚Ñд нарын дүгнÑлт тун Ñ…ÑÑ€ÑгтÑй байдаг болохоор Ñ…ÑÑ€Ñв та хурдаÑÐ³Ð°Ñ Ð³Ñж бодож байвал Ñ‚Ñд нарт туÑлаж шалгаж дүгнÑж байх Ñ…ÑÑ€ÑгтÑй.</p>
+
+<h2>Би нÑмÑгдлийнхÑÑ Ð±Ð¸Ñ‡Ð»Ñг дотор маш ноцтой алдаа олооод харчихлаа. ТүүнийгÑÑ Ð¼Ð°Ñˆ хурдан заÑах Ñ…ÑÑ€ÑгтÑй байна. Яавал дÑÑÑ€ вÑ?</h2>
+
+<p>Ð¥ÑÑ€Ñв Ñ‚ÑÑ€ нь үнÑÑ…ÑÑÑ€ ноцтой алдаа бол (нууцлалт, тогтворжилт, үндÑÑн гүйцÑтгÑлийн алдаа) түүнийг шинÑчлÑж хурдан заÑаад шиÑнчлÑлтÑÑ Ð¸Ð»Ð³ÑÑхдÑÑ "үнÑлгÑÑ Ð´Ò¯Ð³Ð½Ñлт өгөгчдөд зориулÑан Ñ‚ÑмдÑглÑгÑÑ" талбарт мөн мÑдÑÑж хувилбарын Ñ‚ÑмдÑглÑлдÑÑ Ñ‚ÑмдÑглÑж өгөх Ñ…ÑÑ€ÑгтÑй! Магадгүй та түр хайрцагт байхад нь шалгадаг хүмүүÑÑ‚Ñй холбоо барьж Ñ‚Ñд нараар үнÑлгÑÑ Ð´Ò¯Ð³Ð½Ñлт хийлгÑж алдаа оноог нь шалгуулж болох юм. Мөн irc.mozilla.org Ñервер дÑÑÑ€ буй #addons өрөөнд буй хүмүүÑÑ‚Ñй холбогдож нөхцөл байдлаа Ñрьж туÑламж Ñ…Ò¯ÑÑж болох болов Ñ…ÑÑ€Ñв ингÑÑ…ÑÑÑ€ бол Ñ‚ÑвчÑÑртÑй мөн ÑелдÑг байх Ñ…ÑÑ€ÑгтÑй.</p>
+
+<p>Уйлж унжих Ñ…ÑÑ€Ñггүй. Бид давуу ÑрхтÑй нÑмÑгдлүүд Ñ€Ò¯Ò¯ түргÑн очиж ажиллах боловч ийм үед биднÑÑÑ Ð¼Ð°Ñˆ олон цаг, нойр хоол болон гÑÑ€ бүлтÑйгÑÑ Ó©Ð½Ð³Ó©Ñ€Ò¯Ò¯Ð»ÑÑ… цагийг иддÑг болохоор "дарааллын урдуур орох" Ñ…Ò¯ÑÑлтÑй хүмүүÑд бид нар Ð±Ð°Ñ Ð½Ñг их дуртай биш. Ð¥ÑÑ€Ñв та иймÑрхүү замналаар ÑÐ²ÑŠÑ Ð³Ñж шийдÑÑ… юмуу бодож байгаа бол irc.mozilla.org Ñерверийн #addons өрөөнд буй Ñ…Ò¯Ð¼Ò¯Ò¯Ñ ÑˆÐ¸Ð¹Ð´ гаргахад тань туÑламж магадгүй.
+
+<h2>Миний нÑмÑгдлийг шударга Ð±ÑƒÑ Ð´Ò¯Ð³Ð½ÑÑÑн гÑж би бодож байна. Яавал дÑÑÑ€ вÑ?</h2>
+
+<p>Ð¥ÑÑ€Ñв таны нÑмÑгдлийг зөв биш дүгнÑÑнÑÑÑ Ð½Ð¸Ð¹Ñ‚Ð¸Ð¹Ð½ хуудÑанд орÑонгүй гÑж бодож байвал amo-editors@mozilla.org хаÑг руу шалтгаанаа илÑрхийлж захиа бичих Ñ…ÑÑ€ÑгтÑй. Захиандаа ÑелдÑг болон тов тодорхой бичиж таны нÑмÑгдÑл Ñ…ÑрхÑн буруу шүүгдÑÑн талаар онцгойлж тодорхойлох Ñ…ÑÑ€ÑгтÑй.</p>
+
+<p>(Ð¥ÑÑ€Ñв та захианд зааÑан *бүх* зүйлÑийг заÑÑан бол түүнийгÑÑ Ð´Ð°Ñ…Ð¸Ð½ үнÑлгÑÑ ÑˆÐ°Ð»Ð³ÑƒÑƒÑ€Ñ‚ оруулалгүйгÑÑÑ€ ХөгжүүлÑгчдийн Ñ…Ñналтын Ñамбарт мÑдÑгдÑÑний дараа шууд нÑÑ€ дÑвшүүлж болно)</p>
+
+<h2>Миний нÑмÑгдÑл урьд нь нийтийн байÑнаа одоо түр хайрцагт орчихÑон байх юм. Юу болÑон юм бол? </h2>
+
+<p>Ð¥ÑÑ€Ñв нÑмÑгдÑл нийтийн хуудÑанд байх шаардлагыг хангаж чадахаа больÑон бол бид түүнийг түр хайрцаг уруу зөөж магадгүй. Хууль Ñрх зүй дÑÑÑ€ÑÑ Ð¸Ð¹Ð¼ үйлдлийг хорьÑон болохоор бид танд захиагаар мÑдÑгдÑж Ñагаад ингÑÑ… болÑноо тайлбарлах болно.</p>
+
+<p>Та Ñ…ÑÑ€Ñв хуудÑанд алдаа олÑон бол Bugzilla; ашиглан "addons.mozilla.org" бүтÑÑгдÑхүүний нÑрийн дор "Public Pages" гÑÑÑн бүрдÑлтÑй алдааны мÑдÑÑлÑл хийж болох бөгөөд мÑдÑÑлÑлдÑÑ Ð¼Ð°Ñˆ дÑлгÑÑ€ÑнгүйгÑÑÑ€ бичих Ñ…ÑÑ€ÑгтÑй.</p>
+
+<h2>Миний нÑмÑгдÑл нийтийн хуудÑан дÑÑÑ€ байгаа бөгөөд хүмүүÑд их таалагдлаа. ҮүнийгÑÑ Ñаж би Ñанал болголтын жагÑаалтанд нÑмÑÑ… вÑ?</h2>
+
+<p>Ð¥ÑÑ€Ñв та өөрийнхөө нÑмÑгдлийг нÑмÑгдлүүдийн Ñор болÑнуудын нÑг гÑж итгÑж нÑмÑгдлийн Ñүр хүч болон мозилагийн вÑб Ñ…ÑÑ€ÑглÑгчдÑд тун их туÑтай зүйл болжÑÑ Ð³Ñж үзÑж байгаа бол нÑмÑгдлийн Ñанал болголтын хуудÑанд нÑмүүлÑÑ… Ñ…Ò¯ÑÑлт гаргаж болно. ИнгÑхийн тулд та amo-editors@mozilla.org хаÑг уруу захиа бичиж Ñагаах таны нÑмÑгдÑл тийм Ñүрхий Ð²Ñ Ð³ÑдгÑÑ Ñ‚Ð°Ð¹Ð»Ð±Ð°Ñ€Ð»Ð°Ñ… Ñ…ÑÑ€ÑгтÑй.</p>
+
+<p>Таны захиа <b>Ñдаж</b> дараах зүйлÑийг агуулÑан байх Ñ‘Ñтой:</p>
+<ul>
+<li>вÑб Ñ…ÑÑ€ÑглÑгчдийг Ñ…ÑрхÑн ÑайжруулÑан</li>
+<li>Firefox-н олон Ñ…ÑÑ€ÑглÑгчдийг Ñ…ÑрхÑн хамруулÑан</li>
+<li>таны нÑмÑгдÑл Мозила Ñ‚Ó©Ñлийн хүрÑÑнд Ñ…ÑрхÑн зохицож ÑлангуÑа Ñ…ÑÑ€ÑглÑгчдийн вÑб Ñ…ÑÑ€ÑглÑÑг Ñаадгүй Ñайжруулж нууцлал болон аюулгүй байдлыг дÑмжиж, вÑбийн төрөл бүрийн хандалтыг хангаж нÑÑлттÑй Ñтандарт болон өгөгдлийг Ñ…ÑрхÑн дÑмжÑÑн тухай</li>
+<li>буÑад ижил төрлийн нÑмÑгдлÑÑÑ Ñ…ÑрхÑн Ñлгарч байгаа (Ñайн болон муу талаараа)</li>
+<li>Ñ…ÑÑ€ÑглÑгчид Ñ…ÑрхÑн хүлÑÑж авÑан, үнÑлÑж дүгнÑÑÑн, ÑÑтгÑгдÑл бичÑÑн, ÑанÑрын ниÑÑгчид Ñ…ÑрхÑн Ñ…ÑÑ€ÑглÑÑÑн, ÑÑвÑл таны гÑрийн Ñ‚ÑжÑÑвÑл амьтдад Ñ…ÑрхÑн Ñайн муу нөлөөлÑөн зÑÑ€Ñг</li>
+</ul>
+
+<p>ХичнÑÑн Ñайн болÑон програм байÑан ч Ñайн мÑдÑÑллÑÑÑ€ хангаагүй юмуу бидÑнд Ñайн ойлгуулагдахаар биш бол Ñанал болголтын жагÑаалтанд орж чадахгүй. Уг жагÑаалтыг ÐœÐ¾Ð·Ð¸Ð»Ð°Ð³Ð°Ð°Ñ Ñ…ÑÑ€ÑглÑгчийн Ñ…ÑÑ€ÑглÑÑ Ð°ÑŽÑƒÐ»Ð³Ò¯Ð¹ байдлын тулд маш Ñ…Ñнуур шалгаж байдаг билÑÑ.</p>
diff --git a/site/app/locale/mn/pages/sandbox.thtml b/site/app/locale/mn/pages/sandbox.thtml
new file mode 100644
index 0000000..02a370c
--- /dev/null
+++ b/site/app/locale/mn/pages/sandbox.thtml
@@ -0,0 +1,13 @@
+<h1>Түр хайрцагт байлгах Ñвц</h1>
+<h2>Түр хайрцаг гÑж юу вÑ?</h2>
+<p>Түр хайрцаг гÑдÑг нь мÑргÑшÑÑн Ñ…ÑÑ€ÑглÑгчдийн Ó©Ó©Ñ€Ñдийнхөө нÑмÑгдлийг Ñнгийн Ñ…ÑÑ€ÑглÑÑнд оруулахааÑаа өмнө түр хайрцагт байлгаж нÑмÑгдÑлдÑÑ ÑˆÐ°Ð»Ð³Ð°Ð»Ñ‚ дүгнÑлт хийдÑг Ñ…ÑÑÑг юм. Түр хайрцаг уруу хандахын тулд та өөрийнхөө бүртгÑлд түр хайрцгийг зөвшөөрүүлÑÑн байх Ñ‘Ñтой. Ð¥ÑÑ€Ñв түр Ñ…Ð°Ð¹Ñ€Ñ†Ð°Ð³Ð½Ð°Ð°Ñ Ð½ÑмÑгдÑл Ñуулгахаар бол завÑарлагчаар шалгагдаж дүгнÑгдÑÑгүй нÑмÑгдÑл ÑƒÑ‡Ñ€Ð°Ð°Ñ Ñ‚Ð°Ð½Ñ‹ компьютерт ÑвдрÑл учруулах аюул буйг анхаарна уу.</p>
+
+<h2>Би нÑмÑгдлÑÑ Ð¾Ð»Ð¾Ð½ нийтийн хуудÑанд Ñаж оруулах вÑ?</h2>
+<!-- To localize the flowchart image, see http://wiki.mozilla.org/Update:Remora_Sandbox_Flowchart -->
+<div style="text-align: center;">%s</div>
+<ol>
+ <li><b>ÐÑмÑгдлÑÑ Ñ…Ó©Ð³Ð¶Ò¯Ò¯Ð»Ñгчдийн Ñ…Ñналтын Ñамбарт илгÑÑнÑ.</b> Таны илгÑÑÑÑн зүйл шууд мозилагийн нÑмÑгдлийн хажууд буй "Түр хайцраг" дотор харуулагдах бөгөөд ÑÐ½Ñ Ñ…ÑÑгийг мÑргÑшÑÑн Ñ…ÑÑ€ÑглÑгчид Ñ…ÑÑ€ÑглÑж шалгаад дүгнÑлт болон Ñанал Ñ…Ò¯ÑÑлт илгÑÑж байдаг юм. Түр хайрцгийг харахын тулд та бүртгÑлийнхÑÑ Ñ‚Ð¾Ñ…Ð¸Ñ€ÑƒÑƒÐ»Ð³Ñ‹Ð½ Ñ…ÑÑÑгт харуулна гÑж зөвшөөрүүлÑÑн байх Ñ…ÑÑ€ÑгтÑй. </li>
+ <li><b>ÐÑмÑгдлÑÑ Ð¾Ð»Ð¾Ð½ нийтийн хуудÑанд оруулахаар нÑÑ€ дÑвшүүлÑÑ….</b> ХөгжүүлÑгчдийн Ñ…Ñналтын Ñамбарт нÑмÑгдлÑÑ Ð½ÑÑ€ дÑвшүүлÑÑ… Ñ…Ð¾Ð»Ð±Ð¾Ð¾Ñ Ð±Ð°Ð¹Ð´Ð°Ð³. ÐÑÑ€ дÑвшигдÑÑний дараа таны нÑмÑгдÑл заÑварлагчдын нÑÑ€ дÑвшилтийн дараалалд харуулагдах болно. </li>
+ <li><b>ЗаÑварлагч таны нÑмÑгдÑлд үнÑлгÑÑ Ð´Ò¯Ð³Ð½Ñлт хийнÑ. </b> Мозилагийн нÑмÑгдлийн заÑварлагчид нь таны нÑмÑгдлийг Ñуулгаж үзÑÑд ажиллаж байгаа ÑÑÑхийг нь шалгана. ТÑдгÑÑÑ€ заÑварлагчид нь мөн түр хайрцагт байхад нь Ñ…ÑÑ€ÑглÑж шалгаÑан Ñ…ÑÑ€ÑглÑгчдийн үнÑлгÑÑ Ð´Ò¯Ð³Ð½Ñлтийг хардаг. </li>
+ <li><b>Таны нÑмÑгдÑл олон нийтийн Ñ…ÑƒÑƒÐ´Ð°Ñ ÑƒÑ€ÑƒÑƒ ÑÑвÑл түр хайрцагтаа буцаад орно.</b> ЗаÑварлагчид нь таны нÑмÑгдлийг нÑг бол олон нийтийн Ñ…ÑƒÑƒÐ´Ð°Ñ ÑƒÑ€ÑƒÑƒ оруулна ÑÑвÑл түр хайрцагт нь буцааж хийдÑг. Ð¥ÑÑ€Ñв түр хайрцагт буцаж орвол та заÑварлагчийн хийÑÑн тайлбарын дагуу заÑвар хийгÑÑд дахин нÑÑ€ дÑвшүүлж болно. Ð¥ÑÑ€Ñв олон нийтийн хуудÑанд орÑон бол цаашдаа таны нÑмÑгдлийн ирÑÑдүйн дараагийн хувилбарууд нь түр хайрцагт аль нÑг заÑварлагчаар Ñ…Ñнагдаад олон нийтийн хуудÑанд оруулагдах зарчмаар үргÑлжлÑÑ… болно. ÐÑгÑнт олон нийтийн хуудÑанд орÑон нÑмÑгдлийг та дахин нÑÑ€ дÑвшүүлÑÑ… шаардлагаггүй бөгөөд ирÑÑдүйн хувилбарууд нь автоматаар заÑварлагчдийн Ñ…Ñнах дараалалд нÑмÑгдÑж байна.</li>
+</ol>
diff --git a/site/app/locale/mn/pages/submission_help.thtml b/site/app/locale/mn/pages/submission_help.thtml
new file mode 100644
index 0000000..6d6c58b
--- /dev/null
+++ b/site/app/locale/mn/pages/submission_help.thtml
@@ -0,0 +1,35 @@
+<h1>ИлгÑÑÑ… заавар туÑламж</h1>
+Шаардлагатай талбарууд <b>зузаан</b> Ò¯ÑгÑÑÑ€ бичигдÑж Ñонгомол талбарууд нь <i>налуу</i> Ò¯ÑгÑÑÑ€ бичигдÑÑн байгаа.
+<h2 id="step1">1-Ñ€ алхам: ДÑÑш хуулах</h2>
+<ul class="submissionHelp">
+ <li><span class="required">ÐÑмÑгдлийн төрөл</span> - Ðнхдагч тохируулгаараа бол илгÑÑгдÑÑн нÑмÑгдлийн файлын төрлийг автоматаар таньдаг. Та ÑÐ½Ñ Ñ‚Ð°Ð»Ð±Ð°Ñ€Ñ‹Ð³ өөрчлөөд Ñ…ÑÑ€Ñггүй.</li>
+ <li><span class="required">ÐÑмÑгдлийн файл</span> - install.rdf гÑÑÑн файлыг оролцуулÑан, нÑмÑгдлийн багцалÑан файл. Ð¥ÑÑ€Ñв уг файл нь онцгой үйлдлийн ÑиÑтем дÑÑÑ€ ажилладаг бол тухайн үйлдлийн ÑиÑтемийг ÑонгоÑноор тухайн ÑиÑтемд тохирÑон нÑмÑгдÑл файлууд илгÑÑгдÑж болохоор Ñонголт Ò¯Ò¯ÑÑÑ… болно.</li>
+ <li><span class="optional">ТÑмдÑгт зураг</span> - Ð­Ð½Ñ Ñ‚ÑмдÑгт зураг файл нь нÑмÑгдлийн нÑрийн хажууд болон Ñуулгах цонхон дÑÑÑ€ мөн нÑрийн хажууд дүрÑлÑгддÑг.</li>
+ <li><span class="required">Ðнхдагч нутагшил</span> - ÐÑмÑгдлийн анхдагч нутагшил нь түүний гол нутагшил нь байдаг. Ð¥ÑÑ€Ñв Ñ…ÑÑ€ÑглÑгчийн ашиглаж байгаа нутагшил нь ÑÐ½Ñ Ð½ÑƒÑ‚Ð°Ð³ÑˆÐ»Ñ‹Ð½Ñ…Ñ‚Ð°Ð¹ зөрж байвал автоматаар ÑÐ½Ñ Ð°Ð½Ñ…Ð´Ð°Ð³Ñ‡ нутагшилд шилждÑг.</li>
+ <li><span class="optional">Миний одоогийн ÑÐ½Ñ Ð½ÑмÑгдлийн мÑдÑÑллийг харуулах Ñ…ÑÑгийг алгаÑ</span> - Ð¥ÑÑ€Ñв та өмнө нь байÑан нÑмÑгдлÑÑ ÑˆÐ¸Ð½Ñчилж байгаа бол ÑÐ½Ñ Ñ‚Ð°Ð»Ð±Ð°Ñ€ харуулагдана. Уг Ñонголтыг чагталÑнаар хувилбартай холбогдох мÑдÑÑллийг оруулдаг 3-Ñ€ алхам хийгдÑлгүй алгаÑагддаг.</li>
+</ul>
+
+<h2 id="step2">2-Ñ€ алхам: ÐÑмÑгдлийн нарийвчилÑан мÑдÑÑлÑл</h2>
+<ul class="submissionHelp">
+ <li><span class="required">ÐÑÑ€</span> - Ðнхдагч нутагшилтай байх үеийнх нь нÑÑ€.</li>
+ <li><span class="required">Зохиогч</span> - ÐÑмÑгдлийн харуулалтыг өөрчлөх ÑрхтÑй болон нÑмÑгдлийн харуулдаг хуудÑанд дÑÑÑ€ үзүүлдÑг зохиогчдын нÑÑ€.</li>
+ <li><span class="required">Төрөл</span> - ÐÑмÑгдлийн ашиглах төрөл.</li>
+ <li><span class="optional">Ð’Ñб хуудаÑ</span> - ÐÑмÑгдлийн өөрийнх нь вÑб хуудаÑ.</li>
+ <li><span class="required">Товч тайлбар</span> - Ðнхдагч нутагшил дÑÑрх тухайн нÑмÑгдлийн тухай товч тайлбар. Ð­Ð½Ñ Ñ‚Ð°Ð»Ð±Ð°Ñ€Ñ‚ оруулах Ñ‚Ñмдгийн дÑÑд Ñ…Ñзгаар нь 250 Ñ‚ÑмдÑгт бөгөөд нÑмÑгдлийн харуулах Ñ…ÑƒÑƒÐ´Ð°Ñ Ð±Ð¾Ð»Ð¾Ð½ хайх/зорчих хуудÑанд дÑÑÑ€ мөн харуулагдана.</li>
+ <li><span class="required">Тодорхойлолт</span> - ÐÑмÑгдлийн тухай дÑлгÑÑ€Ñнгүй тайлбар. Ð­Ð½Ñ Ð½ÑŒ нÑмÑгдлийг харуулдаг хуудÑанд товч тайлбарын дор харуулагддаг.</li>
+ <li><span class="optional">EULA</span> - Ð¥ÑÑ€ÑглÑгч Ñ…ÑÑ€ÑглÑÑ…ÑÑÑÑÑ Ó©Ð¼Ð½Ó© зөвшөөрөх Ñ‘Ñтой зөвшилцөл (End User License Agreement). Уг нÑмÑгдлийг татаж Ð°Ð²Ð°Ñ…Ð°Ð°Ñ Ó©Ð¼Ð½Ó© Ñ…ÑÑ€ÑглÑгчид үүнийг зөвшөөрÑөн байх Ñ‘Ñтой байдаг.</li>
+ <li><span class="optional">Хувь хүнд холбогдолтой мÑдÑÑллийг хамгаалах журамy</span> - ÐÑмÑгдÑлтÑй хамаатай хувь хүнтÑй холбогдолтой мÑдÑÑллийг хамгаалах журам. Уг журманд уг нÑмÑгдлийг Ñ…ÑÑ€ÑглÑÑ… хүний хувийн мÑдÑÑлÑлтÑй тухайн нÑмÑгдÑл Ñ…ÑрхÑн ажиллах болон Ñ…ÑÑ€ÑглÑÑ… талаар зааÑан байдаг. ТÑгÑÑд цааш нь нÑмÑгдлийг Ñуулгах товчтой Ñ…ÑƒÑƒÐ´Ð°Ñ Ñ€ÑƒÑƒ дамжуулах Ñ…Ð¾Ð»Ð±Ð¾Ð¾Ñ Ð°Ð³ÑƒÑƒÐ»Ñан байдаг. Таны нÑмÑгдлийн ÑÐ½Ñ Ð¶ÑƒÑ€Ð¼Ð°Ð½Ð´ юу байж болох ÑÑвÑл ер нь тийм журам оруулах оруулахгүй талаар дÑлгÑÑ€Ñнгүй мÑдÑÑлÑл <a href="%s">ÐÑмÑгдлийн журам</a> хуудÑанд бичигдÑÑн буй.</li>
+ <li><span class="optional">Ð¥ÑÑ€ÑглÑгчдийг интернÑÑ‚ÑÑÑ ÑÑ… бичлÑгийг нь харахыг зөвшөөрөр</span> - Ð­Ð½Ñ Ñ‡Ð°Ð³Ñ‚Ñ‹Ð³ чагталÑнаар Ñ…ÑÑ€ÑглÑгчид таны нÑмÑгдлийн ÑÑ… файлуудын бичлÑгийг интернÑÑ‚ дÑÑÑ€ шууд харах боломж өгдөг.</li>
+ <li><span class="optional">Ð­Ð½Ñ Ð±Ð¾Ð» урьдчилÑан хувилбар</span> - Ð­Ð½Ñ Ñ‡Ð°Ð³Ñ‚Ñ‹Ð³ чагталÑнаар уг нÑмÑгдлийг урьдчилÑан юмуу ÑÑвÑл бета хувилбар гÑж илÑрхийлдÑг. Ийм урьдчилÑан хувилбарууд нь олон нийтийн нÑмÑгдлийн хуудÑанд биш харин түр хайрцаг дотор уг чагтыг авах хүртÑл байрладаг..</li>
+ <li><span class="optional">Ð­Ð½Ñ Ð½ÑŒ туÑгай хуудаÑтай зориулÑан нÑмÑгдÑл</span> - Ð­Ð½Ñ Ñ‡Ð°Ð³Ñ‚Ñ‹Ð³ чагталÑнаар уг нÑмÑгдÑл нь Ñмар нÑгÑн туÑгай хуудаÑтай ажилладаг гÑдгийг илÑрхийлдÑг. ЖишÑÑлбÑл, уг нÑмÑгдÑл тодорхой нÑг хуудаÑны харуулалтыг өөрчлөх, ÑÑвÑл Ñ‚ÑÑ€ вÑб хуудаÑÐ½Ð°Ð°Ñ ÑŽÐ¼ хайх зÑÑ€Ñг байж болох юм. Ð­Ð½Ñ Ñ‚Ð°Ð»Ð±Ð°Ñ€ нь заÑварлагч нар болон интернÑÑ‚ÑÑÑ Ñ…Ð°Ð¹Ð¶ буй хайлтанд нөлөөлөхөд тун Ñ…ÑÑ€ÑгтÑй байдаг.</li>
+ <li><span class="optional">Ð­Ð½Ñ Ð½ÑмÑгдÑл нь нÑмÑлт програм шаарддаг</span> - Ð­Ð½Ñ Ñ‡Ð°Ð³Ñ‚Ñ‹Ð³ чагталÑнаар уг нÑмÑгдÑл нь нÑмÑлт програм шаардана гÑдгийг илÑрхийлдÑг. Ð­Ð½Ñ Ñ‚Ð°Ð»Ð±Ð°Ñ€ нь заÑварлагч нар болон интернÑÑ‚ÑÑÑ Ñ…Ð°Ð¹Ð¶ буй хайлтанд нөлөөлөхөд тун Ñ…ÑÑ€ÑгтÑй байдаг.</li>
+</ul>
+
+<h2 id="step3">Step 3: Хувилбарын нарийвчилÑан мÑдÑÑлÑл</h2>
+<ul class="submissionHelp">
+ <li><span class="required optional">Хувилбарын Ñ‚ÑмдÑглÑл</span> - Хувилбарт гарÑан өөрчлөлтүүд юмуу тухайн хувилбарын товч мÑдÑÑлÑл. Ð¥ÑÑ€Ñв анх удаагаа илгÑÑж байгаа бол ÑÐ½Ñ Ñ‚Ð°Ð»Ð±Ð°Ñ€Ñ‚ оруулах ÑÑÑÑ… нь таны Ñонголт бөгөөд Ñ…ÑÑ€Ñв шинÑчилж байгаа бол заавал оруулах шаардлагатай.</li>
+ <li><span class="optional">ҮнÑлгÑÑ Ð´Ò¯Ð³Ð½Ñлт өгөгчдөд зориулÑан Ñ‚ÑмдÑглÑгÑÑ</span> - Ð­Ð½Ñ Ñ‚Ð°Ð»Ð±Ð°Ñ€ нь тухайн нÑмÑгдлийг шалгаж үнÑлгÑÑ Ð´Ò¯Ð³Ð½Ñлт өгдөг заÑварлагчдад зориулÑан мÑдÑÑлÑл агуулж байдаг. Туршилтын бүртгÑл мÑдÑÑлÑл юмуу ÑÑвÑл онцгой Ñ‚ÑмдÑглÑл Ñнд байж болно.</li>
+</ul>
+
+<h2 id="step4">Step 4: Ðутагшуулах</h2>
+Ð­Ð½Ñ Ñ…ÑÑÑгт тухайн нÑмÑгдлийн дÑмждÑг Ñ…Ñлний орчуулгыг оруулах Ñ…ÑÑ€ÑгтÑй. Сонгох Ñ‚Ð°Ð»Ð±Ð°Ñ€Ð°Ð°Ñ Ñ…ÑлÑÑ Ñонгоод орчуулгыг нь оруулж өгдөг.
diff --git a/site/app/locale/nl/LC_MESSAGES/messages.mo b/site/app/locale/nl/LC_MESSAGES/messages.mo
new file mode 100644
index 0000000..1a333f7
--- /dev/null
+++ b/site/app/locale/nl/LC_MESSAGES/messages.mo
Binary files differ
diff --git a/site/app/locale/nl/LC_MESSAGES/messages.po b/site/app/locale/nl/LC_MESSAGES/messages.po
new file mode 100644
index 0000000..b4a2020
--- /dev/null
+++ b/site/app/locale/nl/LC_MESSAGES/messages.po
@@ -0,0 +1,7338 @@
+# Remora Preliminary Language File
+# Copyright (C) 2006 Mozilla Corporation
+# This file is distributed under the same license as the REMORA package.
+# Wil Clouser <clouserw@mozilla.com>, 2006.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: REMORA 0.1\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2009-01-16 11:45-0800\n"
+"PO-Revision-Date: 2009-06-04 19:53+0100\n"
+"Last-Translator: Mark Heijl <markh@babelzilla.org>\n"
+"Language-Team: DUTCH <LL@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=n != 1;\n"
+
+#: views/addons/policy.thtml:98
+msgid "a_cancel_installation"
+msgstr "Installatie afbreken"
+
+#. This is the text that appears on buttons to download add-ons.
+#. %$1s is an optional string that only appears if the add-on is only available for
+#. a certain platform. Examples: (Windows) or (Linux)
+#. Note that the parentheses are included in the string. :(
+#: views/elements/amo2009/install.thtml:126
+#: views/elements/amo2009/install.thtml:227
+#: views/elements/amo2009/install.thtml:257
+#: views/elements/amo2009/install.thtml:300
+#: views/elements/amo2009/install.thtml:312 views/elements/install.thtml:73
+#: views/elements/install.thtml:181 views/elements/install.thtml:205
+#: views/elements/install.thtml:248 views/elements/install.thtml:260
+#: views/addons/plugins.thtml:66 views/addons/plugins.thtml:76
+#: views/addons/plugins.thtml:86 views/addons/plugins.thtml:96
+#: views/addons/plugins.thtml:119
+#, php-format
+msgid "a_download"
+msgstr "Nu downloaden %s"
+
+#: views/addons/policy.thtml:72
+msgid "a_eula_download"
+msgstr "Accepteren en downloaden"
+
+#: views/addons/policy.thtml:74
+msgid "a_eula_install"
+msgstr "Accepteren en installeren"
+
+#: views/elements/header.thtml:76 views/elements/header.thtml:82
+#: views/api/api_addon.thtml:55 views/api/collections_feed.thtml:75
+#: views/sharing_api/addon.thtml:64
+msgid "a_header_public"
+msgstr "Publiek"
+
+#: views/elements/header.thtml:58 views/elements/header.thtml:75
+#: views/elements/header.thtml:80 views/api/api_addon.thtml:57
+#: views/api/collections_feed.thtml:77 views/sharing_api/addon.thtml:66
+msgid "a_header_sandbox"
+msgstr "Sandbox"
+
+#. %s is a date in the _('date') format
+#: views/elements/amo2009/homepage_addon.thtml:115
+#: views/elements/addon_listitem.thtml:122 views/elements/feature.thtml:106
+#: views/addons/display.thtml:104 views/addons/browse_thumbs.thtml:73
+msgid "addon_detail_last_updated"
+msgstr "Bijgewerkt op %s"
+
+#. %s is the version of the add-on. Example: 3.2a1
+#: views/elements/amo2009/addon_version_detail.thtml:51
+#: views/elements/addon_version_detail.thtml:51
+#, php-format
+msgid "addon_display_header_version"
+msgstr "Versie %s"
+
+#: views/addons/browse_thumbs.thtml:80
+msgid "addon_downloads"
+msgstr "downloads"
+
+#: views/addons/display.thtml:147
+msgid "addon_downloads_total"
+msgstr "downloads in totaal"
+
+#: views/elements/amo2009/homepage_addon.thtml:106
+#: views/elements/addon_listitem.thtml:115 views/elements/feature.thtml:101
+#: views/addons/category_landing.thtml:157 views/addons/display.thtml:146
+#: views/addons/browse_thumbs.thtml:80
+msgid "addon_downloads_weekly"
+msgstr "downloads per week"
+
+#. %1 is the add-on count, %2 the category name
+#: views/addons/browse_thumbs.thtml:104 views/addons/browse.thtml:60
+#, php-format
+msgid "addon_list_category_totalcount"
+msgid_plural "addon_list_category_totalcount"
+msgstr[0] "%1$s add-on"
+msgstr[1] "%1$s add-ons"
+
+#: views/elements/amo2009/addon_list_options.thtml:103
+#: views/elements/pagination.thtml:67
+#: views/elements/addon_list_options.thtml:94
+msgid "addon_list_perpage"
+msgstr "per pagina"
+
+#: views/elements/amo2009/addon_list_options.thtml:84
+#: views/elements/addon_list_options.thtml:98
+msgid "addon_list_sortby"
+msgstr "Sorteren op:"
+
+#: views/helpers/addons_html.php:568 views/elements/amo2009/install.thtml:321
+#: views/elements/feature.thtml:89
+msgid "addon_listitem_flag_experimental"
+msgstr "experimenteel"
+
+#: views/helpers/addons_html.php:570
+msgid "addon_listitem_flag_recommended"
+msgstr "aanbevolen"
+
+#. %1 is the add-on name, %2 is the platform
+#: views/pages/js_constants.js.thtml:66
+msgid "addon_not_available_for_platform"
+msgstr "%1$s is niet beschikbaar voor %2$s."
+
+#. %1 is the add-on name
+#: views/addons/policy.thtml:101 views/addons/previews.thtml:60
+#: views/addons/versions.thtml:130 views/reviews/flag.thtml:61
+#: views/reviews/add.thtml:114 views/reviews/display.thtml:216
+#: views/reviews/review_added.thtml:57
+#, php-format
+msgid "addon_review_a_back_to_addon_x"
+msgstr "Terug naar %1$s…"
+
+#. %1 is the add-on name
+#: views/reviews/flag.thtml:60 views/reviews/add.thtml:113
+#: views/reviews/review_added.thtml:56
+#, php-format
+msgid "addon_review_a_back_to_reviews"
+msgstr "Terug naar de beoordelingen…"
+
+#: views/reviews/add.thtml:85
+msgid "addon_review_add_rating_field"
+msgstr "Waardering:"
+
+#: views/reviews/add.thtml:102
+msgid "addon_review_add_review_field"
+msgstr "Beoordeling:"
+
+#: views/reviews/add.thtml:107
+msgid "addon_review_add_submit"
+msgstr "Uw beoordeling indienen"
+
+#. %s is the name of the add-on
+#: views/reviews/add.thtml:51
+#, php-format
+msgid "addon_review_add_title"
+msgstr "Beoordeling toevoegen voor %s"
+
+#: views/reviews/add.thtml:78
+msgid "addon_review_add_title_field"
+msgstr "Titel/Samenvatting:"
+
+#: views/reviews/display.thtml:77 views/reviews/display.thtml:161
+msgid "addon_review_admin_delete"
+msgstr "Verwijderen"
+
+#: views/reviews/display.thtml:76
+msgid "addon_review_author_reply_link"
+msgstr "Beantwoorden"
+
+#: views/reviews/delete.thtml:62
+msgid "addon_review_confirm_delete"
+msgstr "Weet u zeker dat u deze beoordeling wilt verwijderen?"
+
+#: views/reviews/delete.thtml:63
+msgid "addon_review_confirm_no"
+msgstr "Nee"
+
+#: views/reviews/delete.thtml:64
+msgid "addon_review_confirm_yes"
+msgstr "Ja"
+
+#: views/reviews/delete.thtml:48
+msgid "addon_review_delete_header"
+msgstr "Beoordeling verwijderen"
+
+#: controllers/reviews_controller.php:449
+msgid "addon_review_deleted_successfully"
+msgstr "Beoordeling succesvol verwijderd."
+
+#. %s is the name of the add-on
+#: views/reviews/add.thtml:51
+#, php-format
+msgid "addon_review_edit_title"
+msgstr "Beoordeling voor %s bewerken"
+
+#. %1 is the count of characters entered as notes for the review flag reason.
+#: controllers/reviews_controller.php:539
+msgid "addon_review_flag_error_other_length"
+msgstr ""
+"Probleem bij aanduiden van de beoordeling: Opmerkingen voor aangeduide "
+"beoordelingen zijn gelimiteerd tot tussen 10 en 100 karakters; het aantal "
+"karakters was %1$s."
+
+#. Removing an extra comma
+#: views/reviews/review_added.thtml:53
+msgid "addon_review_in_moderation"
+msgstr ""
+"Opmerking: voordat uw beoordeling op de publieke site verschijnt zal deze "
+"worden gescreend door een editor."
+
+#: views/reviews/add.thtml:57
+msgid "addon_review_in_reply_to"
+msgstr "Antwoord van de ontwikkelaar op:"
+
+#. %1 is the review count, %2 is the nickname or full name of the user.
+#: views/reviews/display.thtml:131
+#, php-format
+msgid "addon_review_others_by_user"
+msgid_plural "addon_review_others_by_user"
+msgstr[0] "Zie ook %1$s eerdere beoordeling door %2$s voor deze add-on."
+msgstr[1] "Zie ook %1$s eerdere beoordelingen door %2$s voor deze add-on."
+
+#. %1 is the add-on name
+#: controllers/reviews_controller.php:201
+#: controllers/reviews_controller.php:250
+#: controllers/reviews_controller.php:345
+#: controllers/reviews_controller.php:424
+#, php-format
+msgid "addon_review_pagetitle"
+msgstr "Beoordelingen voor %s"
+
+#. %1 is the user, %2 is the (localized) date
+#: views/reviews/display.thtml:160
+#, php-format
+msgid "addon_review_reply_on_x_by_y"
+msgstr "Antwoord van %1$s op %2$s"
+
+#: views/reviews/display.thtml:157
+msgid "addon_review_reply_prefix"
+msgstr "Antwoord ontwikkelaar:"
+
+#: views/reviews/review_added.thtml:51
+msgid "addon_review_saved_successfully"
+msgstr "Uw beoordeling is succesvol opgeslagen. Bedankt!"
+
+#: views/addons/display.thtml:354 views/reviews/display.thtml:72
+msgid "addon_reviewed_by_u_on_d"
+msgstr "door %1$s op %2$s"
+
+#. %1 is the user, %2 is the (localized) date, %3 is the rating
+#: views/editors/reviews_queue.thtml:57 views/editors/reviews_queue.thtml:68
+#: views/reviews/add.thtml:63 views/reviews/delete.thtml:54
+#, php-format
+msgid "addon_reviewed_on_x_rated_y"
+msgstr "door %1$s op %2$s (waardering %3$s)"
+
+#: views/elements/amo2009/addon_version_detail.thtml:52
+#: views/elements/addon_version_detail.thtml:52
+msgid "addon_version_permalink"
+msgstr "Permanente koppeling naar deze versie"
+
+#. %1 is the current Application name (e.g. Firefox)
+#. %2 is the Application's version number
+#: views/addons/versions.thtml:140
+msgid "addon_versions_getlatestversion"
+msgstr "De meest recente versie die compatibel is met %1$s %2$s"
+
+#: views/addons/display.thtml:447
+msgid "addons_author_addons_submit"
+msgstr "Indienen"
+
+#: views/elements/amo2009/homepage_addon.thtml:100
+#: views/elements/feature.thtml:95
+msgid "addons_author_tooltip"
+msgstr "Profiel van de schrijver bekijken"
+
+#. %1 is the name of the Application (eg. Firefox)
+#: controllers/addons_controller.php:1296
+msgid "addons_browse_all_themes_title"
+msgstr "Door alle thema’s bladeren :: %1$s Add-ons"
+
+#. %s is the name of the category
+#: controllers/addons_controller.php:1016
+#, php-format
+msgid "addons_browse_browse_category"
+msgstr "%s doorbladeren"
+
+#. %1 is the name of the theme category (eg. Modern)
+#. %2 is the name of the Application (eg. Firefox)
+#: controllers/addons_controller.php:664
+msgid "addons_browse_categories_header_theme"
+msgstr "Door alle thema’s in de categorie %1$s bladeren :: %2$s Add-ons"
+
+#: views/addons/display.thtml:249
+msgid "addons_display_a_license_what"
+msgstr "Wat is dit?"
+
+#: views/reviews/display.thtml:222
+msgid "addons_display_add_review"
+msgstr "Beoordeling toevoegen"
+
+#: views/addons/display.thtml:294
+msgid "addons_display_advanced_details"
+msgstr "Geavanceerde details"
+
+#: views/addons/display.thtml:98
+msgid "addons_display_categories"
+msgstr "Categorieën"
+
+#: views/addons/display.thtml:482
+msgid "addons_display_collection_add"
+msgstr "Aan een collectie toevoegen:"
+
+#: views/addons/display.thtml:491
+msgid "addons_display_collection_add_new"
+msgstr "Nieuwe collectie…"
+
+#: views/addons/display.thtml:487
+msgid "addons_display_collection_add_select_one"
+msgstr "Selecteer een collectie…"
+
+#: views/addons/display.thtml:493
+msgid "addons_display_collection_add_submit"
+msgstr "Publiceren"
+
+#. %1$s is the add-on name
+#. %2$s is the collection name, linked to the collection's page
+#: views/pages/js_constants.js.thtml:103 views/addons/display.thtml:61
+msgid "addons_display_collection_publish_success"
+msgstr "%1$s is toegevoegd aan de %2$s-collectie."
+
+#: views/addons/display.thtml:483
+msgid "addons_display_collection_whatsthis"
+msgstr "Wat is dit?"
+
+#. %1$s is a number
+#: views/addons/display.thtml:473
+msgid "addons_display_collections_more"
+msgid_plural "addons_display_collections_more"
+msgstr[0] "en nog %1$s collectie"
+msgstr[1] "en nog %1$s collecties"
+
+#: views/addons/display.thtml:403
+msgid "addons_display_detailed_review"
+msgstr "gedetailleerde beoordeling"
+
+#: views/reviews/add.thtml:89 views/reviews/add.thtml:90
+msgid "addons_display_dont_like_it"
+msgstr "Niet geweldig"
+
+#: views/reviews/display.thtml:220
+msgid "addons_display_edit_review"
+msgstr "Uw beoordeling bewerken"
+
+#: views/addons/display.thtml:132
+msgid "addons_display_has_privacy"
+msgstr "Deze add-on kent een privacybeleid."
+
+#: views/reviews/add.thtml:87 views/reviews/add.thtml:88
+msgid "addons_display_hate_it"
+msgstr "Verschrikkelijk"
+
+#: views/addons/display.thtml:462
+msgid "addons_display_header_collections"
+msgstr "Verwante collecties"
+
+#: views/addons/display.thtml:297
+msgid "addons_display_header_developer_comments"
+msgstr "Opmerkingen van de ontwikkelaar"
+
+#: views/addons/display.thtml:230
+msgid "addons_display_header_homepage"
+msgstr "Startpagina"
+
+#: views/addons/display.thtml:247 views/addons/versions.thtml:110
+msgid "addons_display_header_license"
+msgstr "Broncodelicentie"
+
+#: views/addons/display.thtml:337
+msgid "addons_display_header_reviews"
+msgstr "Beoordelingen"
+
+#: views/addons/display.thtml:261
+msgid "addons_display_header_support"
+msgstr "Ondersteuning"
+
+#: views/reviews/add.thtml:91 views/reviews/add.thtml:92
+msgid "addons_display_like_it"
+msgstr "Niet slecht"
+
+#: views/addons/display.thtml:210
+msgid "addons_display_long_description"
+msgstr "Uitgebreide beschrijving"
+
+#: views/reviews/add.thtml:95 views/reviews/add.thtml:96
+msgid "addons_display_love_it"
+msgstr "Geweldig"
+
+#: views/addons/display.thtml:178
+msgid "addons_display_more_images"
+msgstr "Meer afbeeldingen"
+
+#: views/addons/display.thtml:465
+msgid "addons_display_nocollections"
+msgstr "Deze add-on is nog niet in een collectie opgenomen."
+
+#. %1$s is either an author's name or a comma separated list of authors. Using
+#. the list doesn't make sense in the English plural form so we ignore the
+#. variable.
+#: views/addons/display.thtml:436
+msgid "addons_display_other_addons_by"
+msgid_plural "addons_display_other_addons_by"
+msgstr[0] "Andere add-ons door %1$s"
+msgstr[1] "Andere add-ons door deze schrijvers"
+
+#. %s is the name of the add-on and the add-on section. Example:
+#. Some Add-on :: Firefox Add-ons
+#. This should not be concatenated in the code and should be fixed.
+#: controllers/addons_controller.php:141 controllers/addons_controller.php:280
+#: controllers/addons_controller.php:1442
+#, php-format
+msgid "addons_display_pagetitle"
+msgstr "%s"
+
+#. %s is an email address
+#: views/addons/display.thtml:286
+#, php-format
+msgid "addons_display_paragraph_supportinfoemail"
+msgstr "De ontwikkelaar biedt ondersteuning voor deze add-on op %s."
+
+#. %$1s is a URL
+#. %$2s is an email address
+#: views/addons/display.thtml:269
+#, php-format
+msgid "addons_display_paragraph_supportinfoemailurl"
+msgstr ""
+"De ontwikkelaar biedt ondersteuning voor deze add-on op %s of u kunt een e-"
+"mailbericht sturen aan %s."
+
+#. %s is a URL
+#: views/addons/display.thtml:278
+#, php-format
+msgid "addons_display_paragraph_supportinfourl"
+msgstr "De ontwikkelaar biedt ondersteuning voor deze add-on op %s."
+
+#: views/addons/display.thtml:383
+msgid "addons_display_rate_it"
+msgstr "Waarderen"
+
+#: views/reviews/add.thtml:93 views/reviews/add.thtml:94
+msgid "addons_display_really_like_it"
+msgstr "Fantastisch"
+
+#: views/addons/display.thtml:410
+msgid "addons_display_review_etiquette"
+msgstr ""
+"Meld a.u.b. geen fouten in beoordelingen. We stellen uw e-mailadres niet "
+"beschikbaar aan ontwikkelaars van add-ons en ze willen mogelijk contact met "
+"u opnemen om te helpen bij het oplossen van uw probleem."
+
+#. %1 is the review guidelines link
+#: views/addons/display.thtml:417
+msgid "addons_display_review_guidelines_link"
+msgstr "<a href=\"%s\">Beoordelingsrichtlijnen</a>"
+
+#. %1 is the support section link
+#: views/addons/display.thtml:414
+msgid "addons_display_review_see_support"
+msgstr ""
+"Kijk in de <a href=\"%1$s\">ondersteuningssectie</a> voor het verkrijgen van "
+"ondersteuning voor deze add-on."
+
+#: views/addons/display.thtml:404
+msgid "addons_display_review_submit"
+msgstr "Opslaan"
+
+#: views/addons/display.thtml:430
+#, php-format
+msgid "addons_display_see_all_addons"
+msgstr "Alle %1$s add-ons bekijken"
+
+#. %1 is the number of reviews
+#: views/addons/display.thtml:364
+#, php-format
+msgid "addons_display_see_all_reviews"
+msgstr "Alle beoordelingen bekijken (%1$s)"
+
+#: views/addons/display.thtml:219
+msgid "addons_display_see_all_versions"
+msgstr "Alle versies bekijken"
+
+#: views/addons/display.thtml:321 views/addons/versions.thtml:117
+msgid "addons_display_view_source"
+msgstr "Bron bekijken"
+
+#: views/addons/display.thtml:324
+msgid "addons_display_view_stats"
+msgstr "Statistieken bekijken"
+
+#: views/addons/display.thtml:376
+msgid "addons_display_what_do_you_think"
+msgstr "Wat vindt u er van?"
+
+#: views/elements/app_compatibility.thtml:49
+msgid "addons_display_workswith"
+msgstr "Werkt met:"
+
+#: views/addons/home.thtml:112
+msgid "addons_home_browse_new"
+msgstr "Zojuist toegevoegd"
+
+#: views/addons/home.thtml:110
+msgid "addons_home_browse_popular"
+msgstr "Populair"
+
+#: views/addons/home.thtml:108
+msgid "addons_home_browse_recommended"
+msgstr "Aanbevolen"
+
+#: views/addons/home.thtml:127 views/addons/home.thtml:134
+#: views/addons/home.thtml:141 views/addons/home.thtml:148
+msgid "addons_home_browse_subscribe"
+msgstr "Abonneren"
+
+#: views/addons/home.thtml:101
+msgid "addons_home_browse_title"
+msgstr "Door add-ons bladeren"
+
+#: views/addons/home.thtml:114
+msgid "addons_home_browse_updated"
+msgstr "Bijgewerkt"
+
+#: views/elements/amo2009/homepage_addon.thtml:100
+#: views/elements/addon_discussionheader.thtml:83
+#: views/elements/addon_listitem.thtml:109 views/elements/feature.thtml:95
+#: views/addons/category_landing.thtml:66 views/addons/policy.thtml:57
+#: views/addons/display.thtml:70 views/addons/home.thtml:178
+msgid "addons_home_by"
+msgstr "door"
+
+#: views/addons/home.thtml:169
+msgid "addons_home_collection_popular_title"
+msgstr "Populaire collecties"
+
+#: views/elements/amo2009/categories.thtml:69 views/addons/home.thtml:160
+msgid "addons_home_collections"
+msgstr "Collecties"
+
+#. %1$s is the count of addons in a collection
+#: views/elements/amo2009/collection_listing_item.thtml:51
+#: views/addons/home.thtml:185
+msgid "addons_home_collections_addon_count"
+msgid_plural "addons_home_collections_addon_count"
+msgstr[0] "<strong>%1$s</strong> add-on"
+msgstr[1] "<strong>%1$s</strong> add-ons"
+
+#: views/addons/home.thtml:196
+msgid "addons_home_collections_all"
+msgstr "Alle collecties bekijken"
+
+#: views/addons/home.thtml:162
+msgid "addons_home_collections_intro"
+msgstr ""
+"Collecties zijn een manier om add-ons te categoriseren, mengen, matchen en "
+"husselen. Abonneer u op collecties die door andere gebruikers zijn "
+"aangemaakt of maak uw eigen collectie."
+
+#. %1$s is the count of subscribers for a collection
+#: views/elements/amo2009/collection_listing_item.thtml:58
+#: views/collections/detail.thtml:96 views/addons/home.thtml:189
+msgid "addons_home_collections_subscribers"
+msgid_plural "addons_home_collections_subscribers"
+msgstr[0] "<strong>%1$s</strong> abonnee"
+msgstr[1] "<strong>%1$s</strong> abonnees"
+
+#: views/addons/searchengines.thtml:54 views/addons/themes_landing.thtml:49
+msgid "addons_home_feature_head"
+msgstr "Wij bevelen aan:"
+
+#: controllers/search_controller.php:218 controllers/addons_controller.php:176
+#: controllers/addons_controller.php:428 controllers/addons_controller.php:671
+#: controllers/addons_controller.php:871
+#: controllers/addons_controller.php:1103
+#: controllers/addons_controller.php:1242
+#: controllers/addons_controller.php:1298
+#, php-format
+msgid "addons_home_header_details"
+msgstr ""
+"Add-ons breiden %1$s uit, waardoor u uw surfervaring kunt personaliseren. "
+"Neem eens een kijkje en kleed zelf %1$s aan."
+
+#. %1$s is the HTML collection name link.
+#: views/elements/amo2009/teaser_collections.thtml:107
+msgid "addons_home_introduction_collection_link"
+msgstr "Leuke add-ons? Vind er meer in %1$s."
+
+#: views/elements/amo2009/teaser_collections.thtml:60
+msgid "addons_home_introduction_extras"
+msgstr ""
+"<strong>Meer dan 5000 gratis extra’s</strong> waarmee u Firefox kunt "
+"aanpassen en uitbreiden naar uw wensen."
+
+#: views/elements/amo2009/teaser_collections.thtml:55
+msgid "addons_home_introduction_header"
+msgstr "Wat zijn add-ons?"
+
+#: views/elements/amo2009/teaser_collections.thtml:72
+msgid "addons_home_introduction_install"
+msgstr ""
+"<strong>Eenvoudig te installeren</strong> en bij te houden."
+
+#: views/elements/amo2009/teaser_collections.thtml:45
+msgid "addons_home_introduction_name"
+msgstr "Introductie"
+
+#: views/elements/amo2009/teaser_collections.thtml:66
+msgid "addons_home_introduction_themes"
+msgstr ""
+"Werkbalken, thema’s en zoekmachines die <strong>u helpen om uw dagelijkse "
+"taken uit te voeren.</strong>"
+
+#: views/addons/home.thtml:161
+msgid "addons_home_new_indicator"
+msgstr "NIEUW!"
+
+#: views/elements/app_chooser.thtml:48 views/layouts/amo2009.thtml:257
+msgid "addons_home_other_applications"
+msgstr "Overige toepassingen"
+
+#. %1$s is the application the user is browsing. Examples: Thunderbird, Firefox,
+#. Sunbird
+#: views/pages/collector_faq.thtml:49 views/pages/collector_firstrun.thtml:42
+#: views/pages/collector.thtml:46 views/pages/collector_features.thtml:54
+#: controllers/developers_controller.php:87
+#: controllers/compatibility_controller.php:72
+#: controllers/components/simple_acl.php:81 controllers/components/amo.php:607
+#: controllers/statistics_controller.php:60
+#: controllers/statistics_controller.php:240
+#: controllers/previews_controller.php:67 controllers/users_controller.php:90
+#: controllers/users_controller.php:223 controllers/users_controller.php:330
+#: controllers/users_controller.php:414 controllers/users_controller.php:708
+#: controllers/users_controller.php:723 controllers/reviews_controller.php:204
+#: controllers/reviews_controller.php:251
+#: controllers/reviews_controller.php:346
+#: controllers/reviews_controller.php:425
+#: controllers/search_controller.php:185 controllers/search_controller.php:297
+#: controllers/search_controller.php:301 controllers/addons_controller.php:147
+#: controllers/addons_controller.php:280 controllers/addons_controller.php:370
+#: controllers/addons_controller.php:667 controllers/addons_controller.php:874
+#: controllers/addons_controller.php:1019
+#: controllers/addons_controller.php:1034
+#: controllers/addons_controller.php:1101
+#: controllers/addons_controller.php:1121
+#: controllers/addons_controller.php:1240
+#: controllers/addons_controller.php:1357
+#: controllers/addons_controller.php:1364
+#: controllers/addons_controller.php:1442
+#: controllers/addons_controller.php:1477
+#: controllers/addons_controller.php:1538
+#: controllers/addons_controller.php:1543
+#: controllers/editors_controller.php:64 controllers/pages_controller.php:132
+#: controllers/groups_controller.php:65 controllers/groups_controller.php:71
+#: controllers/groups_controller.php:89 controllers/groups_controller.php:111
+#: controllers/collections_controller.php:57
+#: controllers/collections_controller.php:121
+#: controllers/collections_controller.php:205
+#: controllers/collections_controller.php:365
+#: controllers/collections_controller.php:404
+#: controllers/collections_controller.php:466
+#: controllers/collections_controller.php:538
+#: controllers/collections_controller.php:828
+#: controllers/localizers_controller.php:72
+#, php-format
+msgid "addons_home_pagetitle"
+msgstr "%1$s add-ons"
+
+#. %1$s is the number of addons downloaded
+#: views/addons/home.thtml:57
+#, php-format
+msgid "addons_home_stats_downloaded"
+msgid_plural "addons_home_stats_downloaded"
+msgstr[0] "<strong>%1$s</strong> <span>add-on gedownload</span>"
+msgstr[1] "<strong>%1$s</strong> <span>add-ons gedownload</span>"
+
+#. %1$s is the number of addons in use
+#: views/addons/home.thtml:63
+#, php-format
+msgid "addons_home_stats_inuse"
+msgid_plural "addons_home_stats_inuse"
+msgstr[0] "<strong>%1$s</strong> <span>add-on in gebruik</span>"
+msgstr[1] "<strong>%1$s</strong> <span>add-ons in gebruik</span>"
+
+#: views/addons/home.thtml:136
+msgid "addons_home_view_all_newest_title"
+msgstr "Alle nieuwe add-ons bekijken"
+
+#: views/addons/home.thtml:129
+msgid "addons_home_view_all_popular_title"
+msgstr "Alle populaire add-ons bekijken"
+
+#: views/addons/home.thtml:150
+msgid "addons_home_view_all_recommended_title"
+msgstr "Alle aanbevolen add-ons bekijken"
+
+#: views/addons/home.thtml:143
+msgid "addons_home_view_all_updated_title"
+msgstr "Alle onlangs bijgewerkte add-ons bekijken"
+
+#: views/elements/amo2009/install.thtml:334 views/elements/install.thtml:112
+msgid "addons_install_in_sunbird"
+msgstr ""
+"<ol><li>Klik op onderstaande koppeling om het bestand op te slaan.</"
+"li><li>OpenAdd-ons in het menu Extra in Mozilla Sunbird.</li><li>Klik op de "
+"knop Installeren, zoek/selecteer het gedownloade bestand en klik op “OKâ€.</"
+"li></ol>"
+
+#: views/elements/amo2009/install.thtml:333 views/elements/install.thtml:111
+msgid "addons_install_in_sunbird_title"
+msgstr "Hoe te installeren in Sunbird"
+
+#: views/elements/amo2009/install.thtml:331 views/elements/install.thtml:106
+msgid "addons_install_in_thunderbird"
+msgstr ""
+"<ol><li>Klik met de rechtermuisknop op de koppeling en kies “Koppeling "
+"opslaan als…†om het bestand te downloaden en op uw harde schijf op te slaan."
+"</li><li>Open Add-ons in het menu Extra in Mozilla Thunderbird.</li><li>Klik "
+"op de knop Installeren, en zoek/selecteer het gedownloade bestand en klik op "
+"“OKâ€.</li></ol>"
+
+#: views/elements/amo2009/install.thtml:330 views/elements/install.thtml:105
+msgid "addons_install_in_thunderbird_title"
+msgstr "Hoe te installeren in Thunderbird"
+
+#: views/elements/amo2009/addon_list_options.thtml:108
+#: views/elements/addon_list_options.thtml:105
+msgid "addons_options_show_experimental"
+msgstr "Experimentele add-ons weergeven"
+
+#: views/elements/amo2009/addon_list_options.thtml:113
+#: views/elements/addon_list_options.thtml:109
+msgid "addons_options_submit"
+msgstr "OK"
+
+#: views/addons/plugins.thtml:63 views/addons/plugins.thtml:73
+#: views/addons/plugins.thtml:83 views/addons/plugins.thtml:93
+#: views/addons/plugins.thtml:103 views/addons/plugins.thtml:116
+#: views/addons/plugins.thtml:126
+msgid "addons_plugins_by"
+msgstr "Door"
+
+#: views/addons/plugins.thtml:107
+msgid "addons_plugins_for_linux"
+msgstr "voor Linux"
+
+#: views/addons/plugins.thtml:108 views/addons/plugins.thtml:131
+msgid "addons_plugins_for_macosx"
+msgstr "voor Mac OS X"
+
+#: views/addons/plugins.thtml:106 views/addons/plugins.thtml:129
+#: views/addons/plugins.thtml:130
+msgid "addons_plugins_for_windows"
+msgstr "voor Windows"
+
+#. %1$s is a URL
+#: views/addons/plugins.thtml:139
+#, php-format
+msgid "addons_plugins_looking_for_more"
+msgstr ""
+"Deze pagina bevat slechts een paar meestgebruikte en meest populaire plug-"
+"ins. Bezoek voor meer informatie over overige voor browsers in de Mozilla-"
+"familie beschikbare plug-ins %1$s."
+
+#: views/addons/plugins.thtml:137
+msgid "addons_plugins_looking_for_plugin"
+msgstr "Op zoek naar een plug-in die niet in deze lijst staat?"
+
+#: views/addons/plugins.thtml:58
+msgid "addons_plugins_main_description"
+msgstr ""
+"Plug-ins helpen uw browser om specifieke functies uit te voeren, zoals het "
+"bekijken van speciale grafische opmaken of het afspelen van multimedia-"
+"bestanden. Plug-ins zijn anders dan extensies, die bestaande functionaliteit "
+"wijzigen of er iets aan toevoegen."
+
+#. %1$s is the application name. Example: Firefox, Thunderbird, Sunbird
+#: controllers/addons_controller.php:1122
+#, php-format
+msgid "addons_plugins_main_header"
+msgstr "Veelgebruikte plug-ins voor %1$s"
+
+#: controllers/components/amo.php:698 controllers/addons_controller.php:1121
+msgid "addons_plugins_pagetitle"
+msgstr "Plug-ins"
+
+#: views/addons/plugins.thtml:68 views/addons/plugins.thtml:78
+#: views/addons/plugins.thtml:88 views/addons/plugins.thtml:98
+#: views/addons/plugins.thtml:110 views/addons/plugins.thtml:121
+#: views/addons/plugins.thtml:133
+msgid "addons_plugins_support_documentation"
+msgstr "Ondersteunende documentatie: "
+
+#. %s is the name of the add-on
+#: views/addons/policy.thtml:61
+#, php-format
+msgid "addons_policy_eula_require"
+msgstr ""
+"%s vereist de acceptatie van de volgende gebruiksrechtovereenkomst (End User "
+"License Agreement) voordat u kunt doorgaan met installeren:"
+
+#. %1 is the add-on name
+#: controllers/addons_controller.php:1476
+#, php-format
+msgid "addons_previews_pagetitle"
+msgstr "Voorbeeldweergaven voor %s"
+
+#: views/addons/category_landing.thtml:135
+msgid "addons_recently_added"
+msgstr "Onlangs toegevoegd"
+
+#: views/addons/recommended.thtml:51 controllers/addons_controller.php:1365
+msgid "addons_recommended_introduction"
+msgstr ""
+"Met zo veel geweldige add-ons beschikbaar is er altijd wel iets voor "
+"iedereen. Om u op gang te helpen hebt u hier een lijst met een paar van de "
+"populairste. Veel plezier!"
+
+#: controllers/addons_controller.php:1357
+#: controllers/addons_controller.php:1364
+msgid "addons_recommended_pagetitle"
+msgstr "Aanbevolen add-ons"
+
+#: controllers/addons_controller.php:1360
+msgid "addons_recommended_title"
+msgstr "Aanbevolen add-ons"
+
+#: views/addons/searchengines.thtml:136
+msgid "addons_searchengines_additional_resources"
+msgstr "Aanvullende hulpbronnen"
+
+#. link text devmo
+#: views/addons/searchengines.thtml:141
+msgid "addons_searchengines_devmo_link"
+msgstr "Mozilla Ontwikkelingscentrum"
+
+#: views/pages/js_constants.js.thtml:67
+msgid "addons_searchengines_error_mozilla_browser_required"
+msgstr ""
+"Sorry, u hebt een op Mozilla gebaseerde browser (zoals Firefox) nodig om een "
+"zoekplug-in te installeren."
+
+#: views/addons/searchengines.thtml:49
+msgid "addons_searchengines_error_nojavascript"
+msgstr ""
+"JavaScript is nodig om plug-ins te installeren, maar het lijkt er op dat u "
+"dit hebt uitgeschakeld. Schakel a.u.b. JavaScript in voordat u één van "
+"onderstaande zoekplug-ins probeert te installeren."
+
+#. %1 is "make your own" link
+#. %2 is MDC link
+#: views/addons/searchengines.thtml:139
+msgid "addons_searchengines_learn_howto"
+msgstr "Leer hoe u uw %1$s kunt maken op het %2$s."
+
+#. link path to search plugins instructions, relative to devmo
+#: views/addons/searchengines.thtml:140
+msgid "addons_searchengines_makeyourown_href"
+msgstr "/en/docs/Creating_OpenSearch_plugins_for_Firefox"
+
+#. link text for "make your own" (opensearch engine)
+#: views/addons/searchengines.thtml:140
+msgid "addons_searchengines_makeyourown_link"
+msgstr "eigen zoekmachine"
+
+#. %1 is the link to mycroft.mozdev.org
+#: views/addons/searchengines.thtml:138
+msgid "addons_searchengines_more"
+msgstr "Blader door meer zoekmachines op %1$s"
+
+#. link text to mycroft.mozdev.org
+#: views/addons/searchengines.thtml:138
+msgid "addons_searchengines_mycroft_link"
+msgstr "mycroft.mozdev.org"
+
+#: controllers/addons_controller.php:1100
+#: controllers/addons_controller.php:1110
+msgid "addons_searchengines_pagetitle"
+msgstr "Zoekmachines"
+
+#: views/addons/searchengines.thtml:143
+msgid "addons_searchengines_thanks"
+msgstr ""
+"Een speciaal woord van dank aan het Mycroft Project voor hun werk aan "
+"Firefox-zoekmachines."
+
+#: views/addons/display.thtml:154
+msgid "addons_share_button_text"
+msgstr "Dit delen"
+
+#: controllers/addons_controller.php:89
+msgid "addons_share_label_delicious"
+msgstr "Aan Delicious toevoegen"
+
+#: controllers/addons_controller.php:77
+msgid "addons_share_label_digg"
+msgstr "Dit Diggen!"
+
+#: controllers/addons_controller.php:83
+msgid "addons_share_label_facebook"
+msgstr "Posten op Facebook"
+
+#: controllers/addons_controller.php:101
+msgid "addons_share_label_friendfeed"
+msgstr "Delen op FriendFeed"
+
+#: controllers/addons_controller.php:95
+msgid "addons_share_label_myspace"
+msgstr "Posten op MySpace"
+
+#: controllers/components/amo.php:201 controllers/components/amo.php:229
+msgid "addons_status_disabled"
+msgstr "Uitgeschakeld"
+
+#: controllers/components/amo.php:191 controllers/components/amo.php:224
+msgid "addons_status_incomplete"
+msgstr "Onvolledige versie"
+
+#: controllers/components/amo.php:197 controllers/components/amo.php:227
+msgid "addons_status_nominated"
+msgstr "In de sandbox; genomineerd voor publiek"
+
+#: views/pages/js_constants.js.thtml:80 controllers/components/amo.php:195
+#: controllers/components/amo.php:226
+msgid "addons_status_pending"
+msgstr "In de sandbox; wacht op beoordeling"
+
+#: views/pages/js_constants.js.thtml:78 controllers/components/amo.php:199
+#: controllers/components/amo.php:228
+msgid "addons_status_public"
+msgstr "Publiek"
+
+#: views/pages/js_constants.js.thtml:79 controllers/components/amo.php:193
+#: controllers/components/amo.php:225
+msgid "addons_status_sandbox"
+msgstr "In de sandbox"
+
+#: controllers/components/amo.php:203
+msgid "addons_status_unknown"
+msgstr "Onbekend"
+
+#: views/elements/amo2009/teaser_collections.thtml:91
+#: views/elements/amo2009/homepage_addon.thtml:99
+#: views/elements/feature.thtml:94
+msgid "addons_title_tooltip"
+msgstr "Meer over deze add-on"
+
+#: views/addons/category_landing.thtml:151
+msgid "addons_top_downloads"
+msgstr "Topdownloads"
+
+#: views/addons/category_landing.thtml:165
+msgid "addons_top_rated"
+msgstr "Best beoordeeld"
+
+#: views/addons/versions.thtml:62
+msgid "addons_versions_careful"
+msgstr "Pas op met oudere versies"
+
+#: views/addons/versions.thtml:63
+msgid "addons_versions_careful_introduction"
+msgstr ""
+"Deze versies worden als referentie en voor testdoeleinden weergegeven. U "
+"dient altijd de meest recente versie van een add-on te gebruiken."
+
+#: controllers/addons_controller.php:1549
+msgid "addons_versions_history"
+msgstr "Versiegeschiedenis met overzicht van wijzigingen"
+
+#. %1$s is the add-on name
+#: controllers/addons_controller.php:1535
+#, php-format
+msgid "addons_versions_pagetitle"
+msgstr "%1$s versiegeschiedenis"
+
+#: controllers/groups_controller.php:71
+msgid "admin_group_add_pagetitle"
+msgstr "Groep toevoegen"
+
+#: controllers/groups_controller.php:111
+msgid "admin_group_delete_pagetitle"
+msgstr "Groep verwijderen"
+
+#. %s is a number to identify the group
+#: controllers/groups_controller.php:117
+#, php-format
+msgid "admin_group_deleted"
+msgstr "De groep met id %s is verwijderd"
+
+#: controllers/groups_controller.php:89
+msgid "admin_group_edit_pagetitle"
+msgstr "Groep bewerken"
+
+#: controllers/groups_controller.php:92 controllers/groups_controller.php:113
+msgid "admin_group_error_invalid_id"
+msgstr "Ongeldige id voor groep"
+
+#: controllers/groups_controller.php:65
+msgid "admin_group_pagetitle"
+msgstr "Groepenbeheer"
+
+#: controllers/groups_controller.php:77 controllers/groups_controller.php:99
+msgid "admin_group_saved"
+msgstr "De groep is opgeslagen"
+
+#: views/elements/amo2009/search.thtml:257 views/elements/search.thtml:239
+msgid "advanced_search_form"
+msgstr "Geavanceerd"
+
+#: views/elements/amo2009/search.thtml:126 views/elements/search.thtml:125
+msgid "advanced_search_form_any_time"
+msgstr "Elke datum"
+
+#: views/elements/amo2009/search.thtml:97
+#: views/elements/amo2009/search.thtml:110 views/elements/search.thtml:96
+#: views/elements/search.thtml:109
+msgid "advanced_search_form_any_type"
+msgstr "Elk"
+
+#: views/elements/amo2009/search.thtml:275 views/elements/search.thtml:254
+msgid "advanced_search_form_any_version"
+msgstr "Elke"
+
+#: views/elements/amo2009/search.thtml:217 views/elements/search.thtml:212
+msgid "advanced_search_form_application"
+msgstr "Toepassing"
+
+#: views/elements/amo2009/search.thtml:143 views/elements/search.thtml:142
+msgid "advanced_search_form_keyword_match"
+msgstr "Sleutelwoordovereenkomst"
+
+#: views/elements/amo2009/search.thtml:251 views/elements/search.thtml:225
+msgid "advanced_search_form_lastupdate"
+msgstr "Laatst bijgewerkt"
+
+#: views/elements/amo2009/search.thtml:145 views/elements/search.thtml:144
+msgid "advanced_search_form_name"
+msgstr "Naam"
+
+#: views/elements/amo2009/search.thtml:144 views/elements/search.thtml:143
+msgid "advanced_search_form_newest"
+msgstr "Nieuwste"
+
+#: views/elements/amo2009/search.thtml:130 views/elements/search.thtml:129
+msgid "advanced_search_form_past_3_months"
+msgstr "Afgelopen 3 maanden"
+
+#: views/elements/amo2009/search.thtml:131 views/elements/search.thtml:130
+msgid "advanced_search_form_past_6_months"
+msgstr "Afgelopen 6 maanden"
+
+#: views/elements/amo2009/search.thtml:127 views/elements/search.thtml:126
+msgid "advanced_search_form_past_day"
+msgstr "Afgelopen etmaal"
+
+#: views/elements/amo2009/search.thtml:129 views/elements/search.thtml:128
+msgid "advanced_search_form_past_month"
+msgstr "Afgelopen maand"
+
+#: views/elements/amo2009/search.thtml:128 views/elements/search.thtml:127
+msgid "advanced_search_form_past_week"
+msgstr "Afgelopen week"
+
+#: views/elements/amo2009/search.thtml:132 views/elements/search.thtml:131
+msgid "advanced_search_form_past_year"
+msgstr "Afgelopen jaar"
+
+#: views/elements/amo2009/search.thtml:239 views/elements/search.thtml:230
+msgid "advanced_search_form_perpage"
+msgstr "Per pagina"
+
+#: views/elements/amo2009/search.thtml:243 views/elements/search.thtml:224
+msgid "advanced_search_form_platform"
+msgstr "Platform"
+
+#: views/elements/amo2009/search.thtml:147 views/elements/search.thtml:146
+msgid "advanced_search_form_popularity"
+msgstr "Populariteit"
+
+#: views/elements/amo2009/search.thtml:146 views/elements/search.thtml:145
+msgid "advanced_search_form_rating"
+msgstr "Waardering"
+
+#: views/elements/amo2009/search.thtml:247 views/elements/search.thtml:231
+msgid "advanced_search_form_sortby"
+msgstr "Sorteren op"
+
+#: views/elements/amo2009/search.thtml:227 views/elements/search.thtml:216
+msgid "advanced_search_form_to"
+msgstr "tot"
+
+#: views/elements/amo2009/search.thtml:257 views/elements/search.thtml:237
+msgid "advanced_search_form_toggle_tooltip"
+msgstr "Geavanceerd zoeken in-/uitklappen"
+
+#: views/elements/amo2009/search.thtml:235 views/elements/search.thtml:223
+msgid "advanced_search_form_type"
+msgstr "Type"
+
+#: views/elements/amo2009/search.thtml:222 views/elements/search.thtml:214
+msgid "advanced_search_form_version"
+msgstr "versie"
+
+#: views/elements/amo2009/pagination.thtml:42
+msgid "amo2009_pagination_next_page"
+msgstr "Volgende"
+
+#: views/elements/amo2009/pagination.thtml:41
+msgid "amo2009_pagination_previous_page"
+msgstr "Vorige"
+
+#: views/pages/js_constants.js.thtml:96
+msgid "app_compat_ignore_check"
+msgstr "Versiecontrole negeren"
+
+#: views/pages/js_constants.js.thtml:72
+msgid "app_compat_older_firefox_only"
+msgstr "Deze add-on is geschikt voor oudere versies van Firefox"
+
+#. %1$s and %2$s are URLs
+#: views/pages/js_constants.js.thtml:74
+msgid "app_compat_older_version_or_ignore_check"
+msgstr ""
+"U kunt een <a href=\"%1$s\">oudere versie proberen</a> of <a href=\"#\" "
+"onclick=\"%2$s\">deze controle negeren</a>"
+
+#. %1$s is a URL
+#: views/pages/js_constants.js.thtml:71
+msgid "app_compat_try_old_version"
+msgstr "Een <a href=\"%1$s\">oudere versie</a> werkt wellicht"
+
+#. %1$s is a URL
+#. %2$s is a version number. Example: 3.1
+#: views/pages/js_constants.js.thtml:73
+msgid "app_compat_unreleased_version"
+msgstr ""
+"Deze add-on vereist het nog niet vrijgegeven <a href=\"%1$s\">Firefox %2$s</"
+"a>"
+
+#: views/pages/js_constants.js.thtml:70
+msgid "app_compat_update_firefox"
+msgstr ""
+"<a href=\"http://getfirefox.com\">Werk Firefox bij</a> om deze add-on te "
+"gebruiken"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#. %3$s is a status, like Public.
+#: controllers/components/audit.php:79
+msgid "audit_addon_status"
+msgstr "%1$s heeft de status van %2$s naar %3$s gewijzigd"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:221
+msgid "audit_admin_default"
+msgstr "%1$s heeft een onbekende beheeractie %2$s uitgevoerd op ID %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:153
+msgid "audit_admin_feature_remove"
+msgstr "%1$s heeft functie %2$s verwijderd"
+
+#. %1$s is <a>user name</a>
+#. %2$s is an application, like Firefox.
+#: controllers/components/audit.php:92
+msgid "audit_application_create"
+msgstr "%1$s heeft toepassing %2$s aangemaakt"
+
+#. %1$s is <a>user name</a>
+#. %2$s is an application, like Firefox.
+#: controllers/components/audit.php:95
+msgid "audit_application_edit"
+msgstr "%1$s heeft toepassing %2$s bewerkt"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a version number, like 3.5.
+#. %3$s is an application, like Firefox.
+#: controllers/components/audit.php:105
+msgid "audit_appversion_create"
+msgstr "%1$s heeft versie %2$s voor %3$s gemaakt"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a version number, like 3.5.
+#. %3$s is an application, like Firefox.
+#: controllers/components/audit.php:108
+msgid "audit_appversion_delete"
+msgstr "%1$s heeft versie %2$s voor %3$s verwijderd"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a config field, like "awesomeness".
+#. %3$s is a config value, like "off".
+#. %4$s is a config value, like "on".
+#: controllers/components/audit.php:210
+msgid "audit_config"
+msgstr "%1$s heeft instelling ‘%2$s’ van ‘%3$s’ in ‘%4$s’ gewijzigd"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:258
+msgid "audit_editor_default"
+msgstr "%1$s heeft onbekende editoractie %2$s uitgevoerd op ID %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#: controllers/components/audit.php:236
+msgid "audit_editor_feature_remove"
+msgstr "%1$s heeft add-on %2$s verwijderd uit de lijst met aanbevolen add-ons"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#: controllers/components/audit.php:231
+msgid "audit_feature_add"
+msgstr "%1$s heeft add-on %2$s toegevoegd aan de lijst met aanbevolen add-ons"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:149
+msgid "audit_feature_edit"
+msgstr "%1$s heeft een functie gewijzigd voor de %2$s locale"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#: controllers/components/audit.php:241
+msgid "audit_feature_locale_change"
+msgstr ""
+"%1$s heeft de locales gewijzigd voor add-on %2$s op de lijst met aanbevolen "
+"add-ons"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:83
+msgid "audit_file_recalchash"
+msgstr "%1$s heeft de hash voor bestand %2$s opnieuw berekend"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>user name</a>
+#. %3$s is <a>group name</a>
+#: controllers/components/audit.php:182
+msgid "audit_group_addmember"
+msgstr "%1$s heeft %2$s toegevoegd aan groep %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:313
+msgid "audit_group_associated"
+msgstr "%1$s heeft zichzelf verbonden met %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:162
+msgid "audit_group_create"
+msgstr "%1s heeft groep %2$s aangemaakt"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:170
+msgid "audit_group_delete"
+msgstr "%1$s heeft groep %2$s (ID %3$s) verwijderd"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:165
+msgid "audit_group_edit"
+msgstr "%1$s heeft groep %2$s bewerkt"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>user name</a>
+#. %3$s is <a>group name</a>
+#: controllers/components/audit.php:188
+msgid "audit_group_removemember"
+msgstr "%1$s heeft %2$s verwijderd uit groep %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:280
+msgid "audit_l10n_default"
+msgstr "%1$s heeft een onbekende actie %2$s uitgevoerd op %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:295
+msgid "audit_modify_locked_group"
+msgstr "%1$s heeft geprobeerd de afgesloten groep %2$s te wijzigen"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:299
+msgid "audit_modify_other_locale"
+msgstr ""
+"%1$s heeft geprobeerd vertalingen in %2$s te wijzigen zonder toestemming"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a platform, like <a>Windows</a>
+#: controllers/components/audit.php:135
+msgid "audit_platform_create"
+msgstr "%1$s heeft besturingssysteem %2$s aangemaakt"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a platform, like <a>Windows</a>
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:143
+msgid "audit_platform_delete"
+msgstr "%1$s heeft besturingssysteem %2$s (ID %3$s) verwijderd"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a platform, like <a>Windows</a>
+#: controllers/components/audit.php:138
+msgid "audit_platform_edit"
+msgstr "%1$s heeft besturingssysteem %2$s bewerkt"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a part of the admin, like 'Site Config'
+#: controllers/components/audit.php:288
+msgid "audit_reauthentication_failure"
+msgstr ""
+"%1$s heeft zich niet opnieuw kunnen aanmelden om toegang te krijgen tot %2$s."
+
+#. %1$s is <a>user name</a>
+#. %2$s is the name of a canned response, like 'Ready for the public'
+#: controllers/components/audit.php:198
+msgid "audit_response_create"
+msgstr "%1$s heeft antwoord %2$s aangemaakt"
+
+#. %1$s is <a>user name</a>
+#. %2$s is the name of a canned response, like 'Ready for the public'
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:206
+msgid "audit_response_delete"
+msgstr "%1$s heeft antwoord %2$s (ID %3$s) verwijderd"
+
+#. %1$s is <a>user name</a>
+#. %2$s is the name of a canned response, like 'Ready for the public'
+#: controllers/components/audit.php:201
+msgid "audit_response_edit"
+msgstr "%1$s heeft antwoord %2$s bewerkt"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:245
+msgid "audit_review_approve"
+msgstr "%1$s heeft beoordeling %2$s goedgekeurd"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:250 controllers/components/audit.php:253
+msgid "audit_review_delete"
+msgstr "%1$s heeft beoordeling %2$s verwijderd"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:303
+msgid "audit_security_default"
+msgstr "%1$s heeft een onbekende beveiligingsactie %2$s uitgevoerd op ID %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a category name, like <a>Search Tools</a>
+#: controllers/components/audit.php:118
+msgid "audit_tag_create"
+msgstr "%1$s heeft label %2$s aangemaakt"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a category name, like <a>Search Tools</a>
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:126
+msgid "audit_tag_delete"
+msgstr "%1$s heeft categorie %2$s (ID %3$s) verwijderd"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a category name, like <a>Search Tools</a>
+#: controllers/components/audit.php:121
+msgid "audit_tag_edit"
+msgstr "%1$s heeft categorie %2$s bewerkt"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:266
+msgid "audit_update_applications"
+msgstr "%1$s heeft de toepassingsvertalingen voor %2$s bijgewerkt"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:277
+msgid "audit_update_blog"
+msgstr "%1$s heeft de blogpostvertalingen voor %2$s bijgewerkt"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:274
+msgid "audit_update_platforms"
+msgstr "%1$s heeft de besturingssysteemvertalingen voor %2$s bijgewerkt"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:270
+msgid "audit_update_tags"
+msgstr "%1$s heeft de categorievertalingen voor %2$s bijgewerkt"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>user name</a>
+#: controllers/components/audit.php:217
+msgid "audit_user_edit"
+msgstr "%1$s heeft de gebruikersinformatie van %2$s bewerkt"
+
+#: controllers/addons_controller.php:1012
+msgid "browse_addons_name"
+msgstr "Add-ons op naam"
+
+#: controllers/addons_controller.php:1010
+msgid "browse_addons_newest"
+msgstr "Nieuwste add-ons"
+
+#: controllers/addons_controller.php:1008
+msgid "browse_addons_popular"
+msgstr "Populaire add-ons"
+
+#: controllers/addons_controller.php:1011
+msgid "browse_addons_rated"
+msgstr "Add-ons op waardering"
+
+#: controllers/addons_controller.php:1009
+msgid "browse_addons_updated"
+msgstr "Onlangs bijgewerkte add-ons"
+
+#: views/elements/categories.thtml:73 views/elements/categories.thtml:82
+msgid "categories_current_title"
+msgstr "Huidige categorie"
+
+#: views/elements/categories.thtml:50
+#: views/elements/amo2009/categories.thtml:43
+#: views/elements/amo2009/categories.thtml:45
+msgid "categories_header"
+msgstr "Categorieën"
+
+#: views/elements/categories.thtml:50
+#: views/elements/amo2009/categories.thtml:41
+msgid "categories_header_title"
+msgstr "Kies een categorie"
+
+#. %1$s is the category name
+#: views/addons/searchengines.thtml:129
+#, php-format
+msgid "category_extra_see_all"
+msgstr "Alle %1$s bekijken"
+
+#. %1$s is a number.
+#: models/collection.php:130
+msgid "collection_description_limit"
+msgstr "De beschrijving dient minder dan %1$s karakters te bevatten."
+
+#. %1$s is the name of the collection
+#: controllers/collections_controller.php:392
+msgid "collection_detail_rss_title"
+msgstr "%s collectie"
+
+#: controllers/collections_controller.php:1065
+msgid "collection_error_deleting_addon"
+msgstr "Fout bij verwijderen add-on!"
+
+#: controllers/collections_controller.php:1051
+msgid "collection_error_saving_addon"
+msgstr "Fout bij opslaan add-on!"
+
+#: controllers/collections_controller.php:1080
+msgid "collection_error_saving_comment"
+msgstr "Fout bij opslaan opmerking!"
+
+#. %1$s is a number.
+#: models/collection.php:122
+msgid "collection_name_limit"
+msgstr "De naam dient minder dan %1$s karakters te bevatten."
+
+#: controllers/collections_controller.php:352
+#: controllers/collections_controller.php:487
+msgid "collection_not_found"
+msgstr "Collectie niet gevonden!"
+
+#. %1$s is the text on the "create collection" button
+#: views/collections/add.thtml:91
+msgid "collections_add_formfield_addons_description"
+msgstr ""
+"Als u al weet welke add-ons u aan uw collectie wilt toevoegen kunt u "
+"hieronder gewoon hun namen intypen. Als u liever wacht en dit later doet "
+"kunt u nu gewoon op %1$s klikken."
+
+#: views/collections/add.thtml:90
+msgid "collections_add_formfield_firstaddons"
+msgstr "Kies uw eerste add-ons"
+
+#: views/collections/add.thtml:48
+msgid "collections_add_header"
+msgstr "Maak een collectie"
+
+#: views/collections/add.thtml:97
+msgid "collections_add_header_selectedaddons"
+msgstr "Geselecteerde add-ons"
+
+#: views/collections/add.thtml:50
+msgid "collections_add_intro"
+msgstr ""
+"U kunt eenvoudig uw eigen add-oncollectie maken door hieronder een paar "
+"velden in te vullen."
+
+#: views/collections/add.thtml:92 views/collections/add.thtml:103
+msgid "collections_add_submit"
+msgstr "Collectie aanmaken"
+
+#: views/pages/collector_faq.thtml:50 views/pages/collector_firstrun.thtml:43
+#: views/pages/collector.thtml:47 views/pages/collector_features.thtml:55
+#: controllers/search_controller.php:302
+#: controllers/collections_controller.php:206
+#: controllers/collections_controller.php:405
+#: controllers/collections_controller.php:467
+#: controllers/collections_controller.php:539
+msgid "collections_breadcrumb"
+msgstr "Collecties"
+
+#: views/collections/detail.thtml:185
+msgid "collections_detail_a_learn"
+msgstr "Meer hierover"
+
+#: views/elements/amo2009/collection_add_form.thtml:53
+#: views/elements/amo2009/collections_js_init.thtml:68
+#: views/pages/collector_firstrun.thtml:64
+msgid "collections_detail_button_add"
+msgstr "Aan favorieten toevoegen"
+
+#: views/elements/amo2009/collection_add_form.thtml:50
+#: views/elements/amo2009/collections_js_init.thtml:71
+msgid "collections_detail_button_remove"
+msgstr "Uit favorieten verwijderen"
+
+#. %1$s is a URL.
+#. %2$s is a full <a href>.
+#: views/collections/detail.thtml:62
+msgid "collections_detail_created_desc"
+msgstr ""
+"<p>U kunt hieronder uw nieuwe collectie bekijken. als u een nickname voor de "
+"collectie wilt instellen, een pictogram wilt uploaden of aanvullende instellingen wilt wijzigen, bezoek dan de pagina <a "
+"href='%1$s'>Collecties beheren</a>.</p><p>Uw collectie is toegankelijk "
+"op deze locatie: %2$s</p>"
+
+#: views/collections/detail.thtml:61
+msgid "collections_detail_created_msg"
+msgstr "Uw collectie is nu klaar!"
+
+#: views/collections/detail.thtml:109
+msgid "collections_detail_header_about"
+msgstr "Over deze collectie"
+
+#. %1$s is a number.
+#: views/collections/detail.thtml:126
+msgid "collections_detail_header_count"
+msgid_plural "collections_detail_header_count"
+msgstr[0] "%1$s add-on in deze collectie"
+msgstr[1] "%1$s add-ons in deze collectie"
+
+#: views/collections/detail.thtml:113
+msgid "collections_detail_info_created"
+msgstr "<strong>Gemaakt door:</strong> %1$s"
+
+#: views/collections/detail.thtml:117
+msgid "collections_detail_info_updated"
+msgstr "<strong>Bijgewerkt:</strong>"
+
+#: views/elements/amo2009/collections_js_init.thtml:62
+msgid "collections_detail_js_adding"
+msgstr "Toevoegen aan Favorieten…"
+
+#: views/elements/amo2009/collections_js_init.thtml:65
+msgid "collections_detail_js_removing"
+msgstr "Favoriet verwijderen…"
+
+#. %1$s is a URL
+#: views/collections/detail.thtml:90
+msgid "collections_detail_login"
+msgstr "<a href=\"%1$s\">Meld u aan</a> om deze collectie aan uw favorieten toe te voegen."
+
+#: views/collections/detail.thtml:104
+msgid "collections_detail_manage"
+msgstr "Collectie beheren"
+
+#: controllers/collections_controller.php:298
+msgid "collections_detail_sort_date"
+msgstr "Datum toegevoegd"
+
+#: controllers/collections_controller.php:299
+msgid "collections_detail_sort_name"
+msgstr "Naam"
+
+#: controllers/collections_controller.php:300
+msgid "collections_detail_sort_popularity"
+msgstr "Populariteit"
+
+#. %1$s is a number.
+#: views/collections/detail.thtml:166
+msgid "collections_detail_weekly_downloads"
+msgid_plural "collections_detail_weekly_downloads"
+msgstr[0] "%1$s download deze week"
+msgstr[1] "%1$s downloads deze week"
+
+#: views/collections/edit.thtml:255
+msgid "collections_edit_addons_delete_noscript"
+msgstr "Geselecteerde add-ons worden verwijderd bij opslaan"
+
+#: views/collections/edit.thtml:247
+msgid "collections_edit_addons_description"
+msgstr ""
+"Type hieronder de namen van nieuwe add-ons om ze te publiceren naar deze "
+"collectie."
+
+#: views/collections/edit.thtml:248
+msgid "collections_edit_addons_description_noscript"
+msgstr ""
+"Voer hieronder een kommagescheiden lijst van add-on-ID’s in om ze te "
+"publiceren naar deze collectie."
+
+#: views/collections/edit.thtml:247 views/collections/edit.thtml:248
+msgid "collections_edit_addons_description_publish_detailspage"
+msgstr "U kunt een add-on ook publiceren vanaf de normale add-onpagina."
+
+#. %1$s is the date the add-on was added to the collection
+#. %1$s is the name of the user who added the add-on to the collection
+#: views/collections/edit.thtml:260
+msgid "collections_edit_addons_listitem_added"
+msgstr "Toegevoegd op %1$s door %2$s"
+
+#: views/collections/edit.thtml:263
+msgid "collections_edit_addons_listitem_comment_add"
+msgstr "Opmerking publicist toevoegen"
+
+#: views/collections/edit.thtml:266
+msgid "collections_edit_addons_listitem_comment_delete"
+msgstr "Opmerking publicist verwijderen"
+
+#: views/collections/edit.thtml:265
+msgid "collections_edit_addons_listitem_comment_edit"
+msgstr "Opmerking publicist bewerken"
+
+#: views/collections/edit.thtml:271
+msgid "collections_edit_addons_listitem_comment_note"
+msgstr ""
+"Noot: Opmerking wordt weergegeven als geschreven door oorspronkelijke "
+"publicist op de oorspronkelijke publicatiedatum"
+
+#: views/collections/edit.thtml:270
+msgid "collections_edit_addons_listitem_comment_submit"
+msgstr "Opmerking opslaan"
+
+#: views/collections/edit.thtml:261
+msgid "collections_edit_addons_listitem_remove"
+msgstr "Verwijderen"
+
+#: views/collections/edit.thtml:250
+msgid "collections_edit_addons_submit"
+msgstr "Aan collectie toevoegen"
+
+#: views/collections/edit.thtml:153
+msgid "collections_edit_check_nickname"
+msgstr "Beschikbaarheid controleren"
+
+#: views/collections/edit.thtml:299
+msgid "collections_edit_confirm_deletecollection"
+msgstr "Ja, ik wil deze collectie verwijderen."
+
+#. %1$s is the label of the edit form's submit button
+#: views/collections/edit.thtml:300
+msgid "collections_edit_confirm_deletecollection_description"
+msgstr ""
+"Vink het veld aan en klik op \"%1$s\" om deze collectie te verwijderen."
+
+#. %1$s is the "delete" submit button text
+#. %2$s is the title of the "advanced" tab
+#: views/collections/edit.thtml:95
+msgid "collections_edit_delete_upon_submit"
+msgstr ""
+"Na klikken op \"%1$s\" hieronder wordt uw collectie verwijderd. Als u uw "
+"collectie niet wilt verwijderen dient u het bevestigingsveld in het tabblad "
+"\"%2$s\" uit te vinken en door te gaan met bewerken van uw collectie. Als u "
+"deze pagina verlaat zonder op te slaan wordt uw collectie eveneens niet "
+"verwijderd."
+
+#: views/collections/edit.thtml:94
+msgid "collections_edit_delete_warning"
+msgstr "Uw collectie staat op het punt te worden verwijderd!"
+
+#: views/collections/add.thtml:76 views/collections/edit.thtml:144
+msgid "collections_edit_form_error_description"
+msgstr "U dient een beschrijving van uw collectie op te geven."
+
+#: views/collections/edit.thtml:181
+msgid "collections_edit_form_error_icon"
+msgstr "Er is een fout opgetreden bij het uploaden van uw pictogram."
+
+#: views/collections/add.thtml:69 views/collections/edit.thtml:130
+msgid "collections_edit_form_error_name"
+msgstr "U dient uw collectie een naam te geven."
+
+#: views/collections/edit.thtml:158
+msgid "collections_edit_form_error_nickname"
+msgstr "Als u een nickname kiest dient deze uniek te zijn."
+
+#: views/collections/add.thtml:93 views/collections/edit.thtml:249
+msgid "collections_edit_formfield_addons"
+msgstr "Add-onnaam:"
+
+#: views/collections/edit.thtml:281
+msgid "collections_edit_formfield_application"
+msgstr "Gekoppelde toepassing"
+
+#: views/collections/edit.thtml:282
+msgid "collections_edit_formfield_application_description"
+msgstr "Selecteer de toepassing die uw collectie ondersteunt."
+
+#: views/collections/edit.thtml:288
+msgid "collections_edit_formfield_collectiontype"
+msgstr "Collectietype"
+
+#: views/collections/edit.thtml:295
+msgid "collections_edit_formfield_deletecollection"
+msgstr "Collectie verwijderen"
+
+#: views/collections/edit.thtml:296
+msgid "collections_edit_formfield_deletecollection_description"
+msgstr "Verwijderen van uw collectie wist deze definitief."
+
+#: views/collections/add.thtml:73 views/collections/edit.thtml:140
+msgid "collections_edit_formfield_description"
+msgstr "Collectiebeschrijving"
+
+#: views/collections/add.thtml:74 views/collections/edit.thtml:141
+msgid "collections_edit_formfield_description_description"
+msgstr "Beschrijf uw collectie en het soort add-ons dat deze bevat kort"
+
+#: views/collections/edit.thtml:162
+msgid "collections_edit_formfield_icon"
+msgstr "Pictogram"
+
+#: views/collections/edit.thtml:163
+msgid "collections_edit_formfield_icon_description"
+msgstr ""
+"U kunt een JPG-, GIF- of PNG-pictogram uploaden dat wordt omgevormd tot "
+"32x32 pixels."
+
+#: views/collections/add.thtml:80 views/collections/edit.thtml:189
+msgid "collections_edit_formfield_listed"
+msgstr "Wie kan uw collectie bekijken?"
+
+#: views/collections/add.thtml:81 views/collections/edit.thtml:190
+msgid "collections_edit_formfield_listed_description"
+msgstr ""
+"Standaard verschijnen collecties in de publieke collectiemap en zijn ze door "
+"iedereen te bekijken. Als u bekijken van uw collectie wilt beperken tot "
+"personen door ze een speciale koppeling te geven dient u die optie hieronder "
+"aan te geven."
+
+#: views/collections/add.thtml:84 views/collections/edit.thtml:193
+msgid "collections_edit_formfield_listed_false"
+msgstr "Alleen personen die ik uitnodig kunnen mijn collectie bekijken"
+
+#: views/collections/add.thtml:83 views/collections/edit.thtml:192
+msgid "collections_edit_formfield_listed_true"
+msgstr "Iedereen kan mijn collectie in de map bekijken"
+
+#: views/collections/edit.thtml:223
+msgid "collections_edit_formfield_managers"
+msgstr "Wie kan mijn collectie beheren?"
+
+#: views/collections/edit.thtml:224
+msgid "collections_edit_formfield_managers_description"
+msgstr ""
+"Deze gebruikers kunnen add-ons naar uw collectie publiceren, alle add-ons en "
+"instellingen beheren en andere gebruikers toestemming verlenen hiertoe."
+
+#: views/collections/add.thtml:66 views/collections/edit.thtml:126
+msgid "collections_edit_formfield_name"
+msgstr "Collectienaam"
+
+#: views/collections/add.thtml:67 views/collections/edit.thtml:127
+msgid "collections_edit_formfield_name_description"
+msgstr ""
+"Geef uw collectie een beschrijvende naam, zoals “De favoriete reisadd-ons "
+"van Daveâ€"
+
+#: views/collections/edit.thtml:148
+msgid "collections_edit_formfield_nickname"
+msgstr "Collectienickname"
+
+#: views/collections/edit.thtml:149
+msgid "collections_edit_formfield_nickname_description"
+msgstr ""
+"Optioneel kunt u uw collectie een unieke nickname voor snelle toegang geven:"
+
+#: views/collections/edit.thtml:201
+msgid "collections_edit_formfield_publishers"
+msgstr "Wie kan add-ons naar uw collectie publiceren?"
+
+#: views/collections/edit.thtml:202
+msgid "collections_edit_formfield_publishers_description"
+msgstr ""
+"Deze gebruikers kunnen add-ons naar uw collectie publiceren en door hen "
+"gepubliceerde add-ons verwijderen."
+
+#: views/collections/edit.thtml:210 views/collections/edit.thtml:232
+msgid "collections_edit_formfield_users_add"
+msgstr "Voer het e-mailadres van een Firefox Add-onsaccount in:"
+
+#: views/collections/edit.thtml:216 views/collections/edit.thtml:238
+msgid "collections_edit_formfield_users_delete_noscript"
+msgstr "Geselecteerde accounts worden verwijderd bij opslaan"
+
+#: views/collections/edit.thtml:215 views/collections/edit.thtml:237
+msgid "collections_edit_formfield_users_new_noscript"
+msgstr ""
+"Voer een kommagescheiden lijst van e-mailadressen van Firefox Add-"
+"onsaccounts in"
+
+#: views/collections/edit.thtml:204 views/collections/edit.thtml:226
+msgid "collections_edit_formfield_users_onlyme"
+msgstr "Alleen ik"
+
+#: views/collections/edit.thtml:205 views/collections/edit.thtml:227
+msgid "collections_edit_formfield_users_otherusers"
+msgstr "Ikzelf en deze gebruikers:"
+
+#: views/collections/edit.thtml:211 views/collections/edit.thtml:233
+msgid "collections_edit_formfield_users_submit"
+msgstr "Toevoegen"
+
+#. %1$s is the name of the collection
+#: views/collections/edit.thtml:68
+msgid "collections_edit_header"
+msgstr "%1$s beheren"
+
+#: views/collections/edit.thtml:246
+msgid "collections_edit_header_addons"
+msgstr "Collectie-inhoud beheren"
+
+#: views/collections/edit.thtml:253 views/collections/edit.thtml:258
+msgid "collections_edit_header_addons_current"
+msgstr "Huidige add-ons:"
+
+#: views/collections/edit.thtml:279
+msgid "collections_edit_header_advanced"
+msgstr "Geavanceerde instellingen"
+
+#: views/collections/edit.thtml:186
+msgid "collections_edit_header_permissions"
+msgstr "Collectiepermissies beheren"
+
+#: views/collections/edit.thtml:170
+msgid "collections_edit_icon_cancel"
+msgstr "Annuleren"
+
+#: views/collections/edit.thtml:174 views/collections/edit.thtml:179
+msgid "collections_edit_icon_delete"
+msgstr "Pictogram verwijderen"
+
+#: views/collections/edit.thtml:178
+msgid "collections_edit_icon_replace"
+msgstr "Pictogram vervangen"
+
+#. %1$s is the label of the edit form's submit button
+#: views/collections/edit.thtml:169
+msgid "collections_edit_icon_toberemoved"
+msgstr ""
+"Het pictogram wordt verwijderd wanneer hieronder op “%1$s†wordt geklikt"
+
+#: views/collections/edit.thtml:155
+msgid "collections_edit_nickname_available"
+msgstr "Nickname beschikbaar"
+
+#: controllers/collections_controller.php:943
+msgid "collections_edit_nickname_error"
+msgstr ""
+"Uw nickname bevat ongeldige karakters en is gecorrigeerd. Probeer het a.u.b. "
+"opnieuw."
+
+#: views/collections/edit.thtml:156
+msgid "collections_edit_nickname_taken"
+msgstr "Nickname in gebruik"
+
+#. This string is followed by a URL pointing to the collection's view page
+#: views/collections/edit.thtml:75
+msgid "collections_edit_saved_nextstep"
+msgstr "Uw collectie is toegankelijk op deze lokatie:"
+
+#: views/collections/edit.thtml:74
+msgid "collections_edit_saved_success"
+msgstr "Uw collectie is succesvol opgeslagen!"
+
+#: views/collections/edit.thtml:169 views/collections/edit.thtml:300
+#: views/collections/edit.thtml:308 views/pages/js_constants.js.thtml:99
+msgid "collections_edit_submit"
+msgstr "Collectie bijwerken"
+
+#: views/collections/edit.thtml:96 views/collections/edit.thtml:297
+#: views/pages/js_constants.js.thtml:100
+msgid "collections_edit_submit_deletecollection"
+msgstr "Collectie verwijderen"
+
+#: views/collections/edit.thtml:111
+msgid "collections_edit_tabheader_addons"
+msgstr "Add-ons"
+
+#: views/collections/edit.thtml:97 views/collections/edit.thtml:113
+msgid "collections_edit_tabheader_advanced"
+msgstr "Geavanceerd"
+
+#: views/collections/edit.thtml:108
+msgid "collections_edit_tabheader_details"
+msgstr "Naam &amp; details"
+
+#: views/collections/edit.thtml:109
+msgid "collections_edit_tabheader_permissions"
+msgstr "Permissies"
+
+#: models/collection_promo.php:53
+msgid "collections_family_tagline"
+msgstr "Houd uw kinderen en uw agenda in de gaten."
+
+#: models/collection_promo.php:53
+msgid "collections_family_title"
+msgstr "Familie"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:70
+msgid "collections_index_a_check_out"
+msgstr "Probeer Add-on Collector"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:52
+msgid "collections_index_a_create"
+msgstr "Een collectie aanmaken"
+
+#: views/collections/detail.thtml:139 views/collections/listing.thtml:85
+#: views/search/collections.thtml:84
+msgid "collections_index_button_go"
+msgstr "Start"
+
+#. %1$s is a URL.
+#: controllers/collections_controller.php:182
+msgid "collections_index_filler_favorites"
+msgstr ""
+"<p><strong>U hebt nog geen favoriete collecties.</strong></p> "
+"<p>Collecties die u markeert als favorieten kunnen snel worden benaderd vanaf deze pagina "
+"en verschijnen in de <a href='%1$s'>Add-on Collector</a> als u die hebt "
+"geïnstalleerd.</p>"
+
+#. %1$s is a URL.
+#: controllers/collections_controller.php:167
+msgid "collections_index_filler_mine"
+msgstr ""
+"<p>U hebt nog geen collecties aangemaakt. Collecties zijn makkelijk aan te maken "
+"en te vullen met uw favoriete add-ons. <a href='%1$s'>Probeer het eens</a>!</p>"
+
+#: views/collections/listing.thtml:51
+msgid "collections_index_header_collections"
+msgstr "Collecties"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:60
+msgid "collections_index_header_collector"
+msgstr "Add-on Collector"
+
+#. %1$s is a comma-separated list of author names
+#: views/elements/amo2009/collection_listing_item.thtml:84
+#: views/collections/detail.thtml:151
+msgid "collections_index_header_created"
+msgstr "gemaakt door %1$s"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:47
+msgid "collections_index_header_what"
+msgstr "Wat zijn collecties?"
+
+#: views/collections/detail.thtml:132 views/collections/listing.thtml:78
+#: views/search/collections.thtml:66
+msgid "collections_index_label_sortby"
+msgstr "Sorteren op"
+
+#: controllers/collections_controller.php:130
+msgid "collections_index_li_editors"
+msgstr "Keuze van de editor"
+
+#: views/collections/subscribe.thtml:64
+#: controllers/collections_controller.php:140
+msgid "collections_index_li_favorites"
+msgstr "Mijn favorieten"
+
+#: controllers/collections_controller.php:138
+msgid "collections_index_li_mine"
+msgstr "Mijn collecties"
+
+#: controllers/collections_controller.php:132
+msgid "collections_index_li_popular"
+msgstr "Populair"
+
+#: views/search/collections.thtml:74 controllers/collections_controller.php:81
+msgid "collections_index_option_all"
+msgstr "Populairst aller tijden"
+
+#: views/search/collections.thtml:72 controllers/collections_controller.php:78
+msgid "collections_index_option_month"
+msgstr "Populairst deze maand"
+
+#: views/search/collections.thtml:76 controllers/collections_controller.php:84
+msgid "collections_index_option_newest"
+msgstr "Nieuwste"
+
+#: views/search/collections.thtml:70 controllers/collections_controller.php:75
+msgid "collections_index_option_week"
+msgstr "Populairst deze week"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:67
+msgid "collections_index_p_collector"
+msgstr ""
+"Er is een nieuwe manier om favoriete add-ons te zoeken en beheren. "
+"Becommentarieer, deel en synchroniseer collecties, helemaal vanuit uw browser"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:48
+msgid "collections_index_p_what_are"
+msgstr ""
+"Collecties zijn groepen verwante add-ons, verzameld om eenvoudig te delen."
+
+#. %s is a date in the _('date') format
+#: views/elements/collections_interactive_addon.thtml:85
+#, php-format
+msgid "collections_interactive_addon_added"
+msgstr "Toegevoegd op %s"
+
+#: models/collection_promo.php:55
+msgid "collections_reference_tagline"
+msgstr "Onderzoek alles online."
+
+#: models/collection_promo.php:55
+msgid "collections_reference_title"
+msgstr "Referentie"
+
+#: models/collection_promo.php:52
+msgid "collections_social_tagline"
+msgstr "Beheer uw sociale netwerk."
+
+#: models/collection_promo.php:52
+msgid "collections_social_title"
+msgstr "Sociaal"
+
+#: views/collections/subscribe.thtml:91
+msgid "collections_subscribe_button_close"
+msgstr "Sluiten"
+
+#: views/collections/subscribe.thtml:70
+msgid "collections_subscribe_error"
+msgstr ""
+"Er is een fout opgetreden bij het toevoegen van een collectie aan uw Favorieten. "
+"Is deze collectie al een favoriet?"
+
+#: views/collections/subscribe.thtml:96
+msgid "collections_subscribe_label_bothersome"
+msgstr "Dit bericht niet meer weergeven."
+
+#. %1$s is the collection name
+#: views/collections/subscribe.thtml:60
+msgid "collections_subscribe_success"
+msgstr "%1$s is toegevoegd aan uw favoriete collecties."
+
+#. %1$s is the link to the "My Favorites" tab on the main collections page
+#. %2$s is the localized title of the "My Favorites" tab
+#. %3$s is the link URL to the collector add-on
+#: views/collections/subscribe.thtml:62
+msgid "collections_subscribe_success_desc"
+msgstr ""
+"U kunt deze collectie nu snel vinden via het tabblad <a href=\"%1$s\">%2$s</a> "
+"in de map. Probeer onze <a href=\"%3$s\">Add-on Collector</a> extensie voor "
+"Firefox voor een nog eenvoudiger manier om uw favoriete collecties bij te houden."
+
+#: views/collections/listing.thtml:55
+msgid "collections_success_delete"
+msgstr "De collectie is verwijderd."
+
+#: models/collection_promo.php:54
+msgid "collections_travel_tagline"
+msgstr "Plan zakenreizen en onvergetelijke vakanties."
+
+#: models/collection_promo.php:54
+msgid "collections_travel_title"
+msgstr "Reizen"
+
+#. A collection of add-ons that is automatically built for a user. They are "automatically published" to this collection.
+#: controllers/collections_controller.php:581
+msgid "collections_type_autopublisher"
+msgstr "Autopublicatie"
+
+#. A collection that has been chosen by an Editor as notable or exceptional
+#: controllers/collections_controller.php:582
+msgid "collections_type_editorspick"
+msgstr "Keuze van de editor"
+
+#: controllers/collections_controller.php:580
+msgid "collections_type_normal"
+msgstr "Normaal"
+
+#: views/collections/subscribe.thtml:84
+msgid "collections_unsubscribe_error"
+msgstr ""
+"Er is een fout opgetreden bij verwijderen van een favoriete collectie. Was deze "
+"collectie geen favoriet?"
+
+#. %1$s is the collection name
+#: views/collections/subscribe.thtml:78
+msgid "collections_unsubscribe_success"
+msgstr "%1$s is verwijderd uit uw favoriete collecties."
+
+#: models/collection_promo.php:56
+msgid "collections_webdev_tagline"
+msgstr "Bouw de perfecte website."
+
+#: models/collection_promo.php:56
+msgid "collections_webdev_title"
+msgstr "Webontwikkeling"
+
+#: views/elements/amo2009/collections_sidebar_whatare.thtml:40
+msgid "collections_whatare_header"
+msgstr "Wat zijn collecties?"
+
+#: views/elements/amo2009/collections_sidebar_whatare.thtml:45
+msgid "collections_whatare_learnmore"
+msgstr "Lees de veelgestelde vragen"
+
+#: views/elements/amo2009/collections_sidebar_whatare.thtml:44
+msgid "collections_whatare_text"
+msgstr ""
+"Er is een nieuwe manier om favoriete add-ons te zoeken en beheren. "
+"Becommentarieer, deel en synchroniseer collecties, helemaal vanuit uw "
+"browser."
+
+#: views/pages/collector_faq.thtml:61 views/pages/collector_features.thtml:67
+msgid "collector_features_a_home"
+msgstr "Add-on Collector startpagina"
+
+#: views/elements/amo2009/collector_sidebar_download.thtml:46
+msgid "collector_features_heading_download"
+msgstr "Download Add-on Collector:"
+
+#: views/elements/amo2009/collector_sidebar_download.thtml:43
+#: views/pages/collector_firstrun.thtml:116 views/pages/collector.thtml:69
+msgid "collector_features_img_logo"
+msgstr "Add-on Collector Logo"
+
+#: views/compatibility/dashboard.thtml:49
+#: controllers/compatibility_controller.php:72
+msgid "compatibility_dashboard_center_header"
+msgstr "Add-oncompatibiliteitscentrum"
+
+#. %1$s is the name of an application and a version. Example: Firefox 3.0
+#. %2$s is the name of an application. Example: Firefox
+#: views/compatibility/dashboard.thtml:50
+msgid "compatibility_dashboard_intro"
+msgstr ""
+"Wees voorbereid op de release van %1$s met de onderstaande hulpmiddelen en "
+"informatie die beschikbaar zijn voor de %2$s Add-onsgemeenschap."
+
+#: views/compatibility/dashboard.thtml:103
+msgid "compatibility_dashboard_loading"
+msgstr "Gegevens worden geladen…"
+
+#: views/compatibility/dashboard.thtml:45
+msgid "compatibility_dashboard_main_link"
+msgstr "Terug naar hoofdscherm"
+
+#: views/compatibility/dashboard.thtml:100 views/compatibility/report.thtml:43
+msgid "compatibility_dashboard_report"
+msgstr "Add-on compatibiliteitsrapport"
+
+#: views/compatibility/dashboard.thtml:53
+#: views/compatibility/dashboard.thtml:110
+#: views/compatibility/developers.thtml:43
+msgid "compatibility_developer_info"
+msgstr "Informatie voor ontwikkelaars van add-ons"
+
+#: views/compatibility/developers.thtml:66
+msgid "compatibility_developers_adjust_maxversion"
+msgstr "De maxVersion aanpassen zonder uploaden"
+
+#: views/compatibility/dashboard.thtml:124
+msgid "compatibility_developers_check_status"
+msgstr "Status van Mijn Add-ons controleren"
+
+#. %1$s is a URL
+#. %2$s is an application and version. Example: Firefox 3.0
+#: views/compatibility/dashboard.thtml:126
+msgid "compatibility_developers_login_first"
+msgstr ""
+"Indien uw add-ons gehost worden op Mozilla Add-ons, <a href=\"%1$s\">log dan "
+"a.u.b. in</a> om de status van uw add-ons voor %2$s te analyseren."
+
+#: views/compatibility/dashboard.thtml:114
+msgid "compatibility_developers_mdclogo_alt"
+msgstr "Mozilla Ontwikkelaarscentrum-logo"
+
+#: views/compatibility/developers.thtml:73
+msgid "compatibility_developers_no_addons"
+msgstr "U hebt geen add-ons die gehost worden op Mozilla Add-ons."
+
+#: views/compatibility/dashboard.thtml:133
+#: views/compatibility/developers.thtml:55
+msgid "compatibility_developers_results"
+msgstr "Resultaten add-onstatuscontrole"
+
+#: views/compatibility/dashboard.thtml:137
+msgid "compatibility_developers_retrieving"
+msgstr "Status van gehoste add-ons wordt opgehaald…"
+
+#. %1$s is a number
+#. %2$s is an application name
+#. %3$s is a number.
+#. Full example: 50 Firefox users (10% of total)
+#: views/compatibility/developers.thtml:65
+msgid "compatibility_developers_user_count"
+msgstr "%1$s gebruikers van %2$s (%3$s&#37; van het totaal)"
+
+#: views/compatibility/report.thtml:45
+msgid "compatibility_report_detail_intro"
+msgstr ""
+"De onderstaande add-ons omvatten 95% van het bij Mozilla bekende add-"
+"ongebruik en zijn gerangschikt naar gebruiksomvang."
+
+#: views/compatibility/dashboard.thtml:94
+msgid "compatibility_report_detailed_link"
+msgstr "Gedetailleerd rapport bekijken"
+
+#. %1$s and %2$s are numbers
+#. %3$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:65
+msgid "compatibility_report_intro"
+msgstr ""
+"Van de %1$s add-ons die 95&#37; van het bij Mozilla bekende add-ongebruik "
+"omvatten wordt momenteel <b>%2$s&#37;</b> beschouwd als compatibel met de "
+"laatste builds van %3$s."
+
+#: views/compatibility/dashboard.thtml:81
+msgid "compatibility_report_legend_alpha"
+msgstr "Alfaversies"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:81
+msgid "compatibility_report_legend_alpha_description"
+msgstr "Add-ons die compatibel zijn met een alfaversie van %1$s"
+
+#: views/compatibility/dashboard.thtml:85
+msgid "compatibility_report_legend_beta"
+msgstr "Betaversies"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:85
+msgid "compatibility_report_legend_beta_description"
+msgstr ""
+"Add-ons die compatibel zijn met een betaversie of releasekandidaat van %1$s"
+
+#: views/compatibility/dashboard.thtml:89
+msgid "compatibility_report_legend_latest"
+msgstr "Laatste versie"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:89
+msgid "compatibility_report_legend_latest_description"
+msgstr "Add-ons die geschikt zijn voor de laatste builds van %1$s"
+
+#: views/compatibility/dashboard.thtml:77
+msgid "compatibility_report_legend_other"
+msgstr "Overige versies"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:77
+msgid "compatibility_report_legend_other_description"
+msgstr "Add-ons die niet compatibel zijn met enige versie van %1$s"
+
+#: views/compatibility/dashboard.thtml:62
+msgid "compatibility_report_title"
+msgstr "Add-oncompatibiliteitsrapport"
+
+#: views/compatibility/dashboard.thtml:54
+#: views/compatibility/dashboard.thtml:144 views/compatibility/users.thtml:42
+msgid "compatibility_user_info"
+msgstr "Informatie voor add-ongebruikers"
+
+#: views/compatibility/dashboard.thtml:52
+msgid "compatibility_view_report"
+msgstr "Compatibiliteitsrapport bekijken"
+
+#. %s is a URL
+#: views/pages/credits.thtml:142
+#, php-format
+msgid "credits_contributing"
+msgstr "Kijk voor informatie over het leveren van bijdragen op onze %s."
+
+#: views/pages/credits.thtml:142
+msgid "credits_contributing_wikipage"
+msgstr "Wiki-pagina"
+
+#: views/pages/credits.thtml:99
+msgid "credits_intro"
+msgstr ""
+"Mozilla wil de volgende personen bedanken voor hun bijdragen aan het addons."
+"mozilla.org project gedurende de afgelopen jaren:"
+
+#: views/pages/credits.thtml:103
+msgid "credits_section_developers"
+msgstr "Ontwikkelaars"
+
+#: views/pages/credits.thtml:115
+msgid "credits_section_editors"
+msgstr "Editors"
+
+#: views/pages/credits.thtml:109
+msgid "credits_section_localizers"
+msgstr "Vertalers"
+
+#: views/pages/credits.thtml:121
+msgid "credits_section_other_contributors"
+msgstr "Overige bijdragen"
+
+#: views/pages/credits.thtml:127
+msgid "credits_section_past_developers"
+msgstr "Vroegere ontwikkelaars"
+
+#: views/pages/credits.thtml:133
+msgid "credits_section_software"
+msgstr "Software en afbeeldingen"
+
+#: views/pages/credits.thtml:136
+msgid "credits_software_famfamfam"
+msgstr ""
+"Sommige gebruikte pictogrammen zijn afkomstig van de <a href=\"http://www."
+"famfamfam.com/lab/icons/silk/\">famfamfam Silk Icon Set</a>, die vallen "
+"onder een <a href=\"http://creativecommons.org/licenses/by/2.5/\">Creative "
+"Commons Attribution 2.5 licentie</a>."
+
+#: views/pages/credits.thtml:137
+msgid "credits_software_timeplot"
+msgstr ""
+"Sommige pagina’s gebruiken elementen van <a href=\"http://www.simile-widgets."
+"org/timeplot/\">Timeplot</a>, onder een <a href=\"http://simile.mit.edu/"
+"license.html\">BSD-licentie</a>."
+
+#. date format string as used in PHP's strftime():
+#. http://php.net/strftime
+#: views/elements/collections_interactive_addon.thtml:85
+#: views/elements/amo2009/addon_version_detail.thtml:53
+#: views/elements/amo2009/homepage_addon.thtml:115
+#: views/elements/addon_version_detail.thtml:54
+#: views/elements/addon_listitem.thtml:124 views/elements/feature.thtml:106
+#: views/collections/detail.thtml:118 views/collections/edit.thtml:325
+#: views/users/info.thtml:76 views/editors/reviews_queue.thtml:57
+#: views/editors/reviews_queue.thtml:68 views/developers/dashboard.thtml:65
+#: views/developers/versions_edit.thtml:208 views/developers/versions.thtml:67
+#: views/search/rss/index.thtml:5 views/addons/rss/versions.thtml:42
+#: views/addons/display.thtml:104 views/addons/display.thtml:356
+#: views/addons/browse_thumbs.thtml:75 views/reviews/add.thtml:63
+#: views/reviews/display.thtml:74 views/reviews/display.thtml:160
+#: views/reviews/delete.thtml:54 controllers/statistics_controller.php:244
+#: controllers/collections_controller.php:1047
+msgid "date"
+msgstr "%e %B %Y"
+
+#. date and time format string (strftime)
+#. http://php.net/strftime
+#: views/elements/addon_version_detail.thtml:53
+#: views/developers/discuss.thtml:52 views/developers/discuss.thtml:62
+#: views/admin/addons_status.thtml:57
+msgid "datetime"
+msgstr "%e %B %Y, %H:%M"
+
+#: views/elements/developers/actionbar.thtml:47
+msgid "devcp_actionbar_link_details"
+msgstr "Detailinformatie"
+
+#: views/elements/developers/actionbar.thtml:42
+#: views/elements/developers/actionbar.thtml:50
+#: views/developers/dashboard.thtml:64
+msgid "devcp_actionbar_link_edit"
+msgstr "Add-on bewerken"
+
+#: views/elements/developers/actionbar.thtml:51
+msgid "devcp_actionbar_link_newversion"
+msgstr "Nieuwe versie uploaden"
+
+#: views/elements/developers/actionbar.thtml:44
+#: views/elements/developers/actionbar.thtml:49
+#: views/developers/dashboard.thtml:73
+msgid "devcp_actionbar_link_stats"
+msgstr "Statistieken"
+
+#. %1$s is a filename, e.g. "foo.txt"
+#. %2$s is the extension, e.g. ".txt"
+#. %3$s is a list of valid extensions, like ".png, .jpg, .gif"
+#: controllers/developers_controller.php:1361
+msgid "devcp_add_previews_extension_error"
+msgstr ""
+"Bestand %1$s heeft een ongeldige extensie (%2$s). Toegestane extensies: %3$s"
+
+#. %s is the filename.
+#: controllers/developers_controller.php:1394
+msgid "devcp_add_previews_save_error"
+msgstr ""
+"Bestand %s kan niet worden opgeslagen in de database. Probeer het a.u.b. "
+"opnieuw."
+
+#. %1$s is the preview ID number, %2$s is the filename.
+#: controllers/developers_controller.php:1389
+msgid "devcp_add_previews_success_replace"
+msgstr "Voorbeeldweergave %1$s is succesvol vervangen door bestand %2$s."
+
+#. %s is the filename.
+#: controllers/developers_controller.php:1391
+msgid "devcp_add_previews_success_upload"
+msgstr ""
+"Bestand %s is succesvol ge-upload. U kunt hieronder een tekst toevoegen."
+
+#: controllers/components/developers.php:1163
+msgid "devcp_additem_addontype_autodetect"
+msgstr "(automatisch detecteren)"
+
+#: views/elements/developers/additem.thtml:76
+msgid "devcp_additem_linktitle_opensin_newwindow"
+msgstr "Opent in een nieuw venster"
+
+#: views/elements/developers/additem.thtml:41
+msgid "devcp_additem_sidebar_title"
+msgstr "Add-on indienen"
+
+#: views/elements/developers/additem.thtml:53
+msgid "devcp_additem_step0_newlink"
+msgstr "Ontwikkelaarsovereenkomst"
+
+#: views/elements/developers/additem.thtml:46
+msgid "devcp_additem_step1_link"
+msgstr "Stap 1: Uploaden"
+
+#: views/elements/developers/additem.thtml:47
+msgid "devcp_additem_step2_link"
+msgstr "Stap 2: Add-ondetails"
+
+#: views/elements/developers/additem.thtml:48
+msgid "devcp_additem_step3_link"
+msgstr "Stap 3: Versiedetails"
+
+#: views/elements/developers/additem.thtml:49
+msgid "devcp_additem_step4_link"
+msgstr "Stap 4: Localisatie"
+
+#: views/elements/developers/additem.thtml:50
+msgid "devcp_additem_step5_link"
+msgstr "Stap 5: Succes"
+
+#: views/elements/developers/additem.thtml:76
+msgid "devcp_additem_submissionhelp_link"
+msgstr "Hulp bij indienen"
+
+#: controllers/previews_controller.php:168
+#: controllers/previews_controller.php:277
+msgid "devcp_addon_field_preview_caption_displaytitle"
+msgstr "Titel van voorbeeldweergave"
+
+#: views/developers/addon_status.thtml:177
+msgid "devcp_addon_status_action_activate"
+msgstr "Actief maken"
+
+#: views/developers/addon_status.thtml:178
+msgid "devcp_addon_status_action_activate_description"
+msgstr ""
+"Maak uw add-on actief om deze in publieke lijsten weer te laten geven en de "
+"updatecontroledienst in te schakelen."
+
+#: views/developers/addon_status.thtml:135
+msgid "devcp_addon_status_action_complete"
+msgstr "Add-on afronden"
+
+#: views/developers/addon_status.thtml:136
+msgid "devcp_addon_status_action_complete_description"
+msgstr "Rond uw add-on af en ga naar de sandbox"
+
+#: views/developers/addon_status.thtml:181
+msgid "devcp_addon_status_action_deactivate"
+msgstr "Inactief maken"
+
+#: views/developers/addon_status.thtml:182
+msgid "devcp_addon_status_action_deactivate_description"
+msgstr ""
+"Maak uw add-on inactief om deze op alle publieke lijsten te verbergen en de "
+"updatecontroledienst uit te schakelen."
+
+#: views/developers/addon_status.thtml:143
+msgid "devcp_addon_status_action_move"
+msgstr "Naar de sandbox verplaatsen"
+
+#: views/developers/addon_status.thtml:144
+msgid "devcp_addon_status_action_move_description"
+msgstr "Plaats uw add-on terug in de sandbox. Dit kunt u terugdraaien."
+
+#: views/developers/addon_status.thtml:139
+msgid "devcp_addon_status_action_nominate"
+msgstr "Voor publicatie nomineren"
+
+#: views/developers/addon_status.thtml:140
+msgid "devcp_addon_status_action_nominate_description"
+msgstr "Nomineer uw add-on voor publicatie"
+
+#: views/developers/addon_status.thtml:147
+msgid "devcp_addon_status_action_public"
+msgstr "Publiek maken"
+
+#: views/developers/addon_status.thtml:148
+msgid "devcp_addon_status_action_public_description"
+msgstr "Maak uw add-on weer publiek."
+
+#: views/developers/addon_status.thtml:169
+msgid "devcp_addon_status_active"
+msgstr ""
+"Uw add-on is <span class=\"inactive-0\">actief</span>. Dit betekent dat uw "
+"add-on op alle beschikbare lijsten wordt getoond, passend bij bovenstaande "
+"status."
+
+#: views/developers/addon_status.thtml:111
+msgid "devcp_addon_status_completion_disabled"
+msgstr ""
+"U dient aan bovenstaande criteria te voldoen voordat u uw add-on kunt "
+"afronden en deze naar de <span class=\"status-1\"sandbox</span> kunt "
+"verplaatsen."
+
+#: views/developers/addon_status.thtml:108
+msgid "devcp_addon_status_completion_enabled"
+msgstr ""
+"U kunt nu uw add-on afronden en deze naar de <span class=\"status-1"
+"\">sandbox</span> verplaatsen door op onderstaande knop te klikken."
+
+#: views/developers/addon_status.thtml:102
+msgid "devcp_addon_status_criteria_category"
+msgstr "Ten minste één categorie geselecteerd"
+
+#: views/developers/addon_status.thtml:101
+msgid "devcp_addon_status_criteria_description"
+msgstr "Add-onbeschrijving vereist"
+
+#: views/developers/addon_status.thtml:99
+msgid "devcp_addon_status_criteria_name"
+msgstr "Add-onnaam vereist"
+
+#: views/developers/addon_status.thtml:120
+msgid "devcp_addon_status_criteria_prerelease"
+msgstr "Add-on is niet gemarkeerd als voorrelease."
+
+#: views/developers/addon_status.thtml:119
+msgid "devcp_addon_status_criteria_preview"
+msgstr "Ten minste één voorbeeldweergave is vereist voor extensies en thema’s."
+
+#: views/developers/addon_status.thtml:100
+msgid "devcp_addon_status_criteria_summary"
+msgstr "Add-onsamenvatting vereist"
+
+#. %s is the status in a span, e.g. "<span>_('Public')</span>".
+#: views/developers/addon_status.thtml:58
+msgid "devcp_addon_status_header"
+msgstr "Add-onstatus: %s"
+
+#: views/developers/addon_status.thtml:152
+#: views/developers/addon_status.thtml:173
+msgid "devcp_addon_status_header_actions"
+msgstr "Beschikbare acties"
+
+#: views/developers/addon_status.thtml:168
+msgid "devcp_addon_status_header_active"
+msgstr "Actiefstatus: <span class=\"inactive-0\">Actief</span>"
+
+#: views/developers/addon_status.thtml:97
+msgid "devcp_addon_status_header_criteria"
+msgstr "Add-on-afrondingscriteria"
+
+#: views/developers/addon_status.thtml:164
+msgid "devcp_addon_status_header_inactive"
+msgstr "Actiefstatus: <span class=\"inactive-1\">Inactief</span>"
+
+#: views/developers/addon_status.thtml:117
+msgid "devcp_addon_status_header_nomination"
+msgstr "Criteria voor publicatienominatie"
+
+#: views/developers/addon_status.thtml:190
+msgid "devcp_addon_status_header_trusted"
+msgstr "Vertrouwensstatus: <span class=\"status-4\">Vertrouwd</span>"
+
+#: views/developers/addon_status.thtml:165
+msgid "devcp_addon_status_inactive"
+msgstr ""
+"Uw add-on is <span class=\"inactive-1\">inactief</span>. Dit betekent dat uw "
+"add-on in geen enkele lijst wordt opgenomen, ongeacht de status hierboven. "
+"Updates worden <b>niet</b> voor uw add-on verstrekt middels de "
+"updatecontroledienst."
+
+#: views/developers/addon_status.thtml:128
+msgid "devcp_addon_status_nominate_disabled"
+msgstr ""
+"U dient aan bovenstaande criteria te voldoen voordat u uw add-on kunt "
+"nomineren voor <span class=\"status-4\">publicatie</span>."
+
+#: views/developers/addon_status.thtml:125
+msgid "devcp_addon_status_nominate_enabled"
+msgstr ""
+"U kunt nu uw add-on nomineren voor <span class=\"status-4\">publicatie</"
+"span> door op onderstaande knop te klikken."
+
+#: views/developers/addon_status.thtml:64
+msgid "devcp_addon_status_public"
+msgstr "Publiek"
+
+#: views/developers/addon_status.thtml:63
+msgid "devcp_addon_status_sandbox"
+msgstr "Sandbox"
+
+#. %s is an email address.
+#: views/developers/addon_status.thtml:89
+msgid "devcp_addon_status_switch_disabled"
+msgstr ""
+"Uw add-on is <span class=\"status-5\">uitgeschakeld</span> door een "
+"beheerder en kan niet worden gebruikt. Stuur indien u vragen hebt een e-"
+"mailbericht naar %s."
+
+#: views/developers/addon_status.thtml:67
+msgid "devcp_addon_status_switch_incomplete"
+msgstr ""
+"Uw add-on is momenteel <span class=\"status-0\">onvolledig</span>. Dit "
+"betekent dat uw add-on nergens op de site wordt weergegeven en dat de "
+"updatecontroledienst niet beschikbaar is. U kunt deze pagina bezoeken om uw "
+"add-on af te ronden als deze aan onderstaande criteria voldoet voor "
+"afronding en overdracht naar de <span class=\"status-1\">sandbox</span>."
+
+#. %s is a number, perhaps 42.
+#: views/developers/addon_status.thtml:77
+msgid "devcp_addon_status_switch_nominated"
+msgstr ""
+"Uw add-on is genomineerd voor <span class=\"status-4\">publicatie</span> en "
+"wacht op editorbeoordeling. Momenteel staan %s andere add-ons in de "
+"nominatiewachtrij."
+
+#. %s is an email address.
+#: views/developers/addon_status.thtml:81
+msgid "devcp_addon_status_switch_pending"
+msgstr ""
+"Uw add-on is in behandeling. Dit zou niet zo moeten zijn. Stuur a.u.b. een e-"
+"mailbericht naar %s met de ID van uw add-on en vermeld deze fout."
+
+#: views/developers/addon_status.thtml:85
+msgid "devcp_addon_status_switch_public"
+msgstr ""
+"Uw add-on is <span class=\"status-4\">publiek</span>, wat betekent dat deze "
+"in alle lijsten en zoekopdrachten wordt weergegeven en kan worden gedownload "
+"zonder restricties. Updates voor uw add-on worden verstrekt via de "
+"updatecontroledienst."
+
+#: views/developers/addon_status.thtml:71
+#: views/developers/addon_status.thtml:75
+msgid "devcp_addon_status_switch_sandbox"
+msgstr ""
+"Uw add-on bevindt zich in de <span class=\"status-1\">sandbox</span>, wat "
+"betekent dat deze wordt weergegeven in lijsten en zoekopdrachten, maar "
+"gebruikers dienen in te loggen om de add-on te downloaden. Updates worden "
+"<b>niet</b> verstrekt via de updatecontroledienst."
+
+#. %s is the add-on name.
+#: views/developers/addon_status_nominate.thtml:43
+#: views/developers/addon_status_confirm.thtml:43
+#: views/developers/addon_status.thtml:43
+msgid "devcp_addon_status_title"
+msgstr "Status van %s"
+
+#: views/developers/addon_status.thtml:191
+msgid "devcp_addon_status_trusted"
+msgstr ""
+"Uw add-on is <span class=\"status-4\">vertrouwd</span>. Dit betekent dat u "
+"updates voor uw add-on kunt indienen zonder editorbeoordeling."
+
+#: views/developers/dashboard.thtml:68
+msgid "devcp_dashboard_active"
+msgstr "Actief"
+
+#. %1$s is the add-on type string
+#. %2$s is Inactive or Active in a <span>
+#. %3$s is the addon's public status (Public, In Sandbox, ...) in a <span>
+#: views/developers/dashboard.thtml:69
+msgid "devcp_dashboard_addontype_status"
+msgstr "%1$s momenteel %2$s en %3$s"
+
+#: views/developers/dashboard.thtml:67
+msgid "devcp_dashboard_change_status"
+msgstr "Status wijzigen"
+
+#. %s is the addons email address.
+#: views/developers/dashboard.thtml:99
+msgid "devcp_dashboard_disabled_questions"
+msgstr ""
+"Uw add-on is uitgeschakeld door een beheerder en kan niet worden gebruikt. "
+"Stuur indien u vragen hebt een e-mailbericht aan %s."
+
+#. %s is the (localized) add-on status string in a span, e.g. "Disabled"
+#: views/developers/dashboard.thtml:98
+msgid "devcp_dashboard_disabled_status"
+msgstr "Add-onstatus: %s"
+
+#: views/developers/dashboard.thtml:43
+msgid "devcp_dashboard_header_main"
+msgstr "Ontwikkelaarsdashboard"
+
+#: views/developers/dashboard.thtml:110
+msgid "devcp_dashboard_header_welcome"
+msgstr "Welkom op het Ontwikkelaarsdashboard"
+
+#: views/developers/dashboard.thtml:68
+msgid "devcp_dashboard_inactive"
+msgstr "Inactief"
+
+#. %s is a date in the _('date') format
+#: views/developers/dashboard.thtml:65
+msgid "devcp_dashboard_last_edited"
+msgstr "Laatst bewerkt op %s"
+
+#: views/developers/dashboard.thtml:111
+msgid "devcp_dashboard_learn"
+msgstr ""
+"Er worden momenteel geen add-ons van u gehost op Mozilla Add-ons. Klik om te "
+"leren hoe het proces werkt en uw eerste add-on in te dienen hieronder op Nu "
+"Starten."
+
+#: views/developers/dashboard.thtml:112
+msgid "devcp_dashboard_start"
+msgstr "Nu Starten"
+
+#: views/developers/dashboard.thtml:82
+msgid "devcp_dashboard_versions"
+msgstr "Versies en bestanden"
+
+#: views/developers/dashboard.thtml:91
+msgid "devcp_dashboard_versions_new"
+msgstr "Een nieuwe versie uploaden"
+
+#. %s is the preview ID number.
+#: controllers/developers_controller.php:1415
+msgid "devcp_delete_previews_error"
+msgstr ""
+"Voorbeeldweergave %s kan niet worden verwijderd uit de database. Probeer het "
+"a.u.b. opnieuw."
+
+#. %s is the preview ID number.
+#: controllers/developers_controller.php:1413
+msgid "devcp_delete_previews_success"
+msgstr "Voorbeeldweergave %s is succesvol verwijderd."
+
+#: controllers/developers_controller.php:1089
+msgid "devcp_delete_version_priv_error"
+msgstr "U hebt geen rechten om versies of bestanden te verwijderen."
+
+#. %1$s is the count of files, a number
+#. %2$s is a status string like _('Public') or _('Incomplete')
+#: controllers/components/amo.php:549
+msgid "devcp_describe_version_status"
+msgid_plural "devcp_describe_version_status"
+msgstr[0] "%1$s ‘%2$s’ bestand"
+msgstr[1] "%1$s ‘%2$s’ bestanden"
+
+#. %s is a version number. Example: 3.0
+#: views/developers/versions.thtml:65
+#, php-format
+msgid "devcp_details_version"
+msgstr "Versie %s"
+
+#: views/developers/discuss.thtml:68
+msgid "devcp_discuss_addreply_header"
+msgstr "Antwoord toevoegen"
+
+#: views/developers/discuss.thtml:57
+msgid "devcp_discuss_allreplies_header"
+msgstr "Antwoorden"
+
+#. notice when an error occurs saving a discussion reply
+#. %1 is the email address (linked) for the amo-editors list
+#: views/developers/discuss.thtml:70
+msgid "devcp_discuss_error_notice"
+msgstr ""
+"Er is een fout opgetreden bij het opslaan van uw antwoord. Neem a.u.b. "
+"contact op met %1$s hierover."
+
+#. %1 is the add-on name, %2 is the add-on's version number currently being reviewed by an editor
+#: views/developers/discuss.thtml:46
+msgid "devcp_discuss_intro"
+msgstr ""
+"Een Mozilla Add-onseditor heeft meer informatie bij u aangevraagd met "
+"betrekking tot versie %2$s van uw add-on %1$s."
+
+#. %1 is the add-on name
+#: views/developers/discuss.thtml:43
+msgid "devcp_discuss_pagetitle"
+msgstr "Meer informatie geven voor de Add-onbeoordeling van %1$s"
+
+#. submit button text
+#: views/developers/discuss.thtml:79
+msgid "devcp_discuss_submit_reply"
+msgstr "Antwoord indienen"
+
+#: views/developers/discuss.thtml:72
+msgid "devcp_discuss_success_message"
+msgstr ""
+"Uw antwoord is succesvol opgeslagen. De overige deelnemers aan de discussie "
+"worden via e-mail geïnformeerd."
+
+#. in an author/editor discussion about an add-on to be reviewed:
+#. %1 is the commenter's user name (linked).
+#. %2 is the full date the comment was made.
+#: views/developers/discuss.thtml:52 views/developers/discuss.thtml:62
+msgid "devcp_discuss_writtenby"
+msgstr "geschreven door %1$s op %2$s"
+
+#: views/developers/addon_edit_authors.thtml:72
+#: views/developers/addon_edit_authors.thtml:81
+msgid "devcp_edit_authors_add_author"
+msgstr "Nieuwe schrijver toevoegen"
+
+#: views/developers/addon_edit_authors.thtml:96
+msgid "devcp_edit_authors_add_author_button"
+msgstr "Schrijver toevoegen"
+
+#: views/developers/addon_edit_authors.thtml:83
+msgid "devcp_edit_authors_add_email"
+msgstr "E-mailadres schrijversaccount:"
+
+#: views/developers/addon_edit_authors.thtml:98
+msgid "devcp_edit_authors_add_loading"
+msgstr "E-mailadres account controleren…"
+
+#: views/developers/addon_edit_authors.thtml:70
+msgid "devcp_edit_authors_click_save"
+msgstr "Klik hieronder op de knop Schrijvers bijwerken om op te slaan."
+
+#: views/developers/addon_edit_authors.thtml:58
+msgid "devcp_edit_authors_header_current"
+msgstr "Huidige schrijvers"
+
+#: views/developers/addon_edit_authors.thtml:50
+msgid "devcp_edit_authors_header_manage"
+msgstr "Add-onschrijvers beheren"
+
+#: views/developers/addon_edit_authors.thtml:93
+msgid "devcp_edit_authors_label_add_listed"
+msgstr "In schrijverslijst op publieke pagina’s openemen"
+
+#: views/developers/addon_edit_authors.thtml:89
+msgid "devcp_edit_authors_label_developer"
+msgstr ""
+"<strong>Ontwikkelaar</strong> - Kan alle aspecten van de add-onlijst "
+"beheren, behalve toevoegen en verwijderen van andere schrijvers."
+
+#: views/developers/addon_edit_authors.thtml:88
+msgid "devcp_edit_authors_label_owner"
+msgstr ""
+"<strong>Eigenaar</strong> - Kan alle aspecten van de add-onlijst beheren, "
+"inclusief toevoegen en verwijderen van andere schrijvers."
+
+#: views/developers/addon_edit_authors.thtml:90
+msgid "devcp_edit_authors_label_viewer"
+msgstr ""
+"<strong>Kijker</strong> - Kan add-on-ontwikkelaarslijst en statistieken "
+"bekijken, maar kan niets wijzigen."
+
+#. Placeholder for the empty option in a <select>.
+#: views/developers/addon_edit_categories.thtml:69
+msgid "devcp_edit_authors_option_empty"
+msgstr "----------------"
+
+#: views/developers/addon_edit_authors.thtml:86
+msgid "devcp_edit_authors_select_role"
+msgstr "Selecteer een rol voor de schrijver:"
+
+#. Column name in a table.
+#: views/developers/addon_edit_authors.thtml:62
+msgid "devcp_edit_authors_th_author"
+msgstr "Schrijver"
+
+#. Column name in a table.
+#: views/developers/addon_edit_authors.thtml:64
+msgid "devcp_edit_authors_th_listed"
+msgstr "In lijst"
+
+#. Column name in a table.
+#: views/developers/addon_edit_authors.thtml:63
+msgid "devcp_edit_authors_th_role"
+msgstr "Rol"
+
+#: views/developers/addon_edit_authors.thtml:77
+msgid "devcp_edit_authors_update_author"
+msgstr "Schrijvers bijwerken"
+
+#: views/developers/addon_edit_categories.thtml:99
+msgid "devcp_edit_categories_button_update"
+msgstr "Categorieën bijwerken"
+
+#: views/developers/addon_edit_categories.thtml:88
+msgid "devcp_edit_categories_does_not_fit"
+msgstr "Mijn add-on past in geen enkele beschikbare categorie."
+
+#. %s is the application name (Firefox, Thunderbird).
+#: views/developers/addon_edit_categories.thtml:61
+msgid "devcp_edit_categories_header_application"
+msgstr "%s-categorieën"
+
+#: views/developers/addon_edit_categories.thtml:49
+msgid "devcp_edit_categories_header_manage"
+msgstr "Add-oncategorieën beheren"
+
+#: views/developers/addon_edit_categories.thtml:91
+msgid "devcp_edit_categories_hover"
+msgstr "Beweeg uw muis over een categorie om de beschrijving te bekijken."
+
+#. %s is the category number (1, 2, 3).
+#: views/developers/addon_edit_categories.thtml:67
+msgid "devcp_edit_categories_label_category_num"
+msgstr "Categorie %s"
+
+#: views/developers/addon_edit_categories.thtml:94
+#: views/developers/addon_edit_categories.thtml:103
+msgid "devcp_edit_categories_none_available"
+msgstr ""
+"Er zijn geen categorieën beschikbaar voor dit add-ontype en deze toepassing."
+
+#: views/developers/addon_edit_categories.thtml:86
+msgid "devcp_edit_categories_other"
+msgstr ""
+"Plaats uw add-on alleen in deze categorie als deze in geen enkele andere "
+"beschikbare categorie past."
+
+#. %s is the application name (Firefox, Thunderbird).
+#: views/developers/addon_edit_categories.thtml:63
+msgid "devcp_edit_categories_select_application_categories"
+msgstr "Selecteer tot drie %s-categorieën voor uw add-on"
+
+#: views/developers/addon_edit.thtml:47
+msgid "devcp_edit_dd_manage_authors"
+msgstr "Voeg gebruikers doe deze add-on kunnen beheren toe of verwijder ze."
+
+#: views/developers/addon_edit.thtml:49
+msgid "devcp_edit_dd_manage_categories"
+msgstr ""
+"Selecteer de relevante categorieën voor elke toepassing die uw add-on "
+"ondersteunt."
+
+#: views/developers/addon_edit.thtml:51
+msgid "devcp_edit_dd_manage_description"
+msgstr ""
+"Voeg vertalingen toe en wijzig deze voor de samenvatting van uw add-on, "
+"beschrijving, gebruiksrechtovereenkomst en privacybeleid."
+
+#: views/developers/addon_edit.thtml:53
+msgid "devcp_edit_dd_manage_properties"
+msgstr ""
+"Wijzig de naam, de startpagina, het pictogram en andere labels van uw add-on."
+
+#: views/developers/addon_edit_descriptions.thtml:116
+msgid "devcp_edit_description_button_update"
+msgstr "Beschrijvingen bijwerken"
+
+#: views/developers/addon_edit_descriptions.thtml:115
+msgid "devcp_edit_description_correct_error"
+msgstr "Corrigeer a.u.b. de hierboven in rood aangeduide fouten."
+
+#: views/developers/addon_edit_descriptions.thtml:51
+msgid "devcp_edit_descriptions_header"
+msgstr "Add-onbeschrijvingen bewerken"
+
+#: views/developers/addon_edit_descriptions.thtml:94
+msgid "devcp_edit_descriptions_transbox_comments_description"
+msgstr ""
+"Alle informatie die mogelijk van belang is voor eindgebruikers en die niet "
+"noodzakelijkerwijs van toepassing is op de add-onsamenvatting of -"
+"beschrijving. Wordt vaak gebruikt voor opsommen van grote fouten, informatie "
+"over rapporteren van fouten, voorziene releasedatum of een nieuwe versie, "
+"etc."
+
+#: views/developers/addon_edit_descriptions.thtml:93
+msgid "devcp_edit_descriptions_transbox_comments_name"
+msgstr "Opmerkingen van de ontwikkelaar"
+
+#: views/developers/addon_edit_descriptions.thtml:86
+msgid "devcp_edit_descriptions_transbox_description_description"
+msgstr ""
+"De beschrijving van uw add-on is een langere uitleg van functies, werking en "
+"andere relevante informatie. Deze wordt weergegeven onder de samenvatting op "
+"de weergavepagina van de add-on."
+
+#: views/developers/addon_edit_descriptions.thtml:85
+msgid "devcp_edit_descriptions_transbox_description_name"
+msgstr "Add-onbeschrijving"
+
+#: views/developers/addon_edit_descriptions.thtml:103
+msgid "devcp_edit_descriptions_transbox_eula_description"
+msgstr ""
+"Indien uw add-on een gebruiksrechtovereenkomst (End-User License Agreement "
+"of EULA) heeft, voer dan hieronder de tekst in. Indien hieronder "
+"ingeschakeld zullen gebruikers hiermee moeten instemmen voordat ze uw add-on "
+"kunnen installer. Merk a.u.b. op dat een EULA niet hetzelfde is als een "
+"codelicentie zoals GPL of MPL."
+
+#: views/developers/addon_edit_descriptions.thtml:102
+msgid "devcp_edit_descriptions_transbox_eula_name"
+msgstr "Gebruiksrechtovereenkomst"
+
+#: views/developers/addon_edit_descriptions.thtml:112
+msgid "devcp_edit_descriptions_transbox_privacy_description"
+msgstr ""
+"Indien uw add-on een privacybeleid kent kunt u hier de tekst invoeren. De "
+"pagina van uw add-on zal een koppeling naar het beleid tonen."
+
+#: views/developers/addon_edit_descriptions.thtml:111
+msgid "devcp_edit_descriptions_transbox_privacy_name"
+msgstr "Privacybeleid"
+
+#: views/developers/addon_edit_descriptions.thtml:78
+msgid "devcp_edit_descriptions_transbox_summary_description"
+msgstr ""
+"De samenvatting is een korte uitleg van de basisfunctionaliteit van uw add-"
+"on die wordt weergegeven in zoek- en bladerlijsten en bovenaan de pagina van "
+"uw add-on. <strong>De lengte is maximaal 250 karakters.</strong>"
+
+#: views/developers/addon_edit_descriptions.thtml:77
+msgid "devcp_edit_descriptions_transbox_summary_name"
+msgstr "Add-onsamenvatting"
+
+#: views/developers/addon_edit.thtml:46
+msgid "devcp_edit_dt_manage_authors"
+msgstr "Add-onschrijvers beheren"
+
+#: views/developers/addon_edit.thtml:48
+msgid "devcp_edit_dt_manage_categories"
+msgstr "Add-oncategorieën beheren"
+
+#: views/developers/addon_edit.thtml:50
+msgid "devcp_edit_dt_manage_descriptions"
+msgstr "Add-onbeschrijvingen beheren"
+
+#: views/developers/addon_edit.thtml:52
+msgid "devcp_edit_dt_manage_properties"
+msgstr "Add-oneigenschappen beheren"
+
+#: views/developers/addon_edit_properties.thtml:170
+msgid "devcp_edit_label_externalsoftware"
+msgstr "Deze add-on vereist externe software"
+
+#: views/developers/addon_edit_properties.thtml:205
+msgid "devcp_edit_label_locale_disambiguation"
+msgstr "Aanvullende locale-informatie"
+
+#: views/developers/addon_edit_properties.thtml:168
+msgid "devcp_edit_label_prerelease"
+msgstr "Dit is een pre-release"
+
+#: views/developers/addon_edit_properties.thtml:169
+msgid "devcp_edit_label_sitespecific"
+msgstr "Dit is een site-specifieke add-on"
+
+#: views/developers/addon_edit_properties.thtml:202
+msgid "devcp_edit_label_target_locale"
+msgstr "Doellocale"
+
+#: views/developers/addon_edit_properties.thtml:212
+msgid "devcp_edit_properties_button_update"
+msgstr "Eigenschappen bijwerken"
+
+#: views/developers/addon_edit_properties.thtml:198
+msgid "devcp_edit_properties_change_guid"
+msgstr "Wijzig dit alleen als u alle gevolgen begrijpt."
+
+#: views/developers/addon_edit_properties.thtml:109
+msgid "devcp_edit_properties_current_icon"
+msgstr "Huidig pictogram"
+
+#: views/developers/addon_edit_properties.thtml:85
+msgid "devcp_edit_properties_default_locale"
+msgstr ""
+"De standaardlocale van een add-on is de hoofdlocale waarin vertalingen "
+"aanwezig moeten zijn. Indien vertalingen van de beschrijvingen van uw add-on "
+"niet beschikbaar zijn in de voorkeurstaal van de gebruiker wordt "
+"teruggevallen op deze standaardlocale."
+
+#: views/developers/addon_edit_properties.thtml:167
+msgid "devcp_edit_properties_flags"
+msgstr "Deze labels worden gebruikt om add-ons te filteren en in te delen."
+
+#: views/developers/addon_edit_properties.thtml:174
+msgid "devcp_edit_properties_guid"
+msgstr ""
+"De GUID van uw add-on wordt opgegeven in install.rdf en geeft een unieke "
+"identificatie. U kunt uw GUID niet wijzigen als deze eenmaal op Mozilla Add-"
+"ons in opgenomen."
+
+#: views/developers/addon_edit_properties.thtml:53
+msgid "devcp_edit_properties_header"
+msgstr "Add-oneigenschappen bewerken"
+
+#: views/developers/addon_edit_properties.thtml:186
+msgid "devcp_edit_properties_header_addon_type"
+msgstr "Add-ontype"
+
+#: views/developers/addon_edit_properties.thtml:181
+msgid "devcp_edit_properties_header_admin_settings"
+msgstr "Beheerinstellingen"
+
+#: views/developers/addon_edit_properties.thtml:84
+msgid "devcp_edit_properties_header_default_locale"
+msgstr "Standaardlocale"
+
+#: views/developers/addon_edit_properties.thtml:166
+msgid "devcp_edit_properties_header_flags"
+msgstr "Add-onlabels"
+
+#: views/developers/addon_edit_properties.thtml:173
+#: views/developers/addon_edit_properties.thtml:197
+msgid "devcp_edit_properties_header_guid"
+msgstr "Add-on-GUID"
+
+#: views/developers/addon_edit_properties.thtml:104
+msgid "devcp_edit_properties_header_icon"
+msgstr "Add-onpictogram"
+
+#: views/developers/addon_edit_properties.thtml:159
+msgid "devcp_edit_properties_header_other_settings"
+msgstr "Overige instellingen"
+
+#. A header on the admin page to toggle trusted status.
+#: views/developers/addon_edit_properties.thtml:182
+msgid "devcp_edit_properties_header_trusted"
+msgstr "Vertrouwde add-on?"
+
+#: views/developers/addon_edit_properties.thtml:160
+msgid "devcp_edit_properties_header_view_source"
+msgstr "Bron online bekijken"
+
+#. %s is a comma-separated list of image extensions ".png, .jpg"
+#: views/developers/addon_edit_properties.thtml:106
+msgid "devcp_edit_properties_icon"
+msgstr ""
+"Het add-onpictogram is een kleine afbeelding die naast de naam van uw add-on "
+"wordt weergegeven in blader- aen zoekresultaten, weergavepagina’s en in het "
+"installatievenster van uw add-on. De grootte van de afbeelding wordt "
+"automatisch omgezet naar 32 x 32 pixels. Gebruik a.u.b. één van de volgende "
+"afbeeldingstypes: %s"
+
+#: views/developers/addon_edit_properties.thtml:171
+msgid "devcp_edit_properties_label_binary"
+msgstr "Deze add-on bevat binaire componenten"
+
+#: views/developers/addon_edit_properties.thtml:185
+msgid "devcp_edit_properties_label_not_trusted"
+msgstr "Niet vertrouwd"
+
+#: views/developers/addon_edit_properties.thtml:184
+msgid "devcp_edit_properties_label_trusted"
+msgstr "Vertrouwd"
+
+#: views/developers/addon_edit_properties.thtml:110
+msgid "devcp_edit_properties_new_icon"
+msgstr "Nieuw pictogram"
+
+#: views/developers/addon_edit_properties.thtml:118
+msgid "devcp_edit_properties_remove_icon"
+msgstr "Pictogram verwijderen"
+
+#: views/developers/addon_edit_properties.thtml:136
+msgid "devcp_edit_properties_transbox_homepage_description"
+msgstr ""
+"Voer indien uw add-on een andere startpagina heefthier het adres in. Andere "
+"vertalingen toevoegen is niet nodig tenzij uw website is gelokaliseerd naar "
+"andere talen."
+
+#: views/developers/addon_edit_properties.thtml:135
+msgid "devcp_edit_properties_transbox_homepage_name"
+msgstr "Add-onstartpagina"
+
+#: views/developers/addon_edit_properties.thtml:79
+msgid "devcp_edit_properties_transbox_name_description"
+msgstr ""
+"De naam van uw add-on wordt overal weergegeven waar uw add-on op een lijst "
+"staat."
+
+#: views/developers/addon_edit_properties.thtml:78
+msgid "devcp_edit_properties_transbox_name_name"
+msgstr "Add-onnaam"
+
+#: views/developers/addon_edit_properties.thtml:145
+msgid "devcp_edit_properties_transbox_supportemail_description"
+msgstr ""
+"Indien u een e-mailadres voor ondersteuningsvragen hebt, kunt u dat hier "
+"invoeren. Toevoegen van andere vertalingen is niet nodig tenzij u "
+"verschillende e-mailadressen hebt voor verschillende talen."
+
+#: views/developers/addon_edit_properties.thtml:144
+msgid "devcp_edit_properties_transbox_supportemail_name"
+msgstr "E-mailadres voor ondersteuning"
+
+#: views/developers/addon_edit_properties.thtml:154
+msgid "devcp_edit_properties_transbox_supporturl_description"
+msgstr ""
+"Indien uw add-on een ondersteunende website of forum heeft kunt u het adres "
+"hier invoeren. Toevoegen van andere vertalingen is niet nodig tenzij uw "
+"website is vertaald in andere talen."
+
+#: views/developers/addon_edit_properties.thtml:153
+msgid "devcp_edit_properties_transbox_supporturl_name"
+msgstr "Ondersteuningswebsite"
+
+#: views/developers/addon_edit_properties.thtml:183
+msgid "devcp_edit_properties_trusted"
+msgstr ""
+"Vertrouwde add-ons kunnen publiek worden gemaakt zonder beoordeling door een "
+"editor."
+
+#. %s is href="..." and should stay in the <a> tag.
+#: views/developers/addon_edit_properties.thtml:119
+msgid "devcp_edit_properties_undelete"
+msgstr "Pictogram wordt verwijderd bij opslaan. <a %s>Annuleren?</a>"
+
+#: views/developers/addon_edit_properties.thtml:161
+msgid "devcp_edit_properties_view_source"
+msgstr ""
+"De bron van uw add-onbestanden kan online worden bekeken door elke ingelogde "
+"gebruiker als u dat wenst."
+
+#: views/developers/addon_edit_properties.thtml:162
+msgid "devcp_edit_properties_view_source_allow"
+msgstr "Online bron bekijken toestaan"
+
+#: views/developers/addon_edit_properties.thtml:163
+msgid "devcp_edit_properties_view_source_do_not_allow"
+msgstr "Online bron bekijken niet toestaan"
+
+#: views/elements/developers/editbox.thtml:46
+msgid "devcp_editbox_authors"
+msgstr "Schrijvers"
+
+#: views/elements/developers/editbox.thtml:47
+msgid "devcp_editbox_categories"
+msgstr "Categorieën"
+
+#: views/elements/developers/editbox.thtml:52
+msgid "devcp_editbox_change_status"
+msgstr "Status wijzigen"
+
+#: views/elements/developers/editbox.thtml:48
+msgid "devcp_editbox_descriptions"
+msgstr "Beschrijvingen"
+
+#: views/elements/developers/editbox.thtml:43
+msgid "devcp_editbox_edit_addon"
+msgstr "Add-on bewerken"
+
+#: views/elements/developers/editbox.thtml:57
+msgid "devcp_editbox_new_version"
+msgstr "Nieuwe versie"
+
+#: views/elements/developers/editbox.thtml:49
+msgid "devcp_editbox_properties"
+msgstr "Eigenschappen"
+
+#: views/elements/developers/editbox.thtml:60
+msgid "devcp_editbox_screenshots"
+msgstr "Voorbeeldweergaven"
+
+#: views/elements/developers/editbox.thtml:53
+msgid "devcp_editbox_statistics_dashboard"
+msgstr "Statistiekendashboard"
+
+#: views/elements/developers/editbox.thtml:54
+msgid "devcp_editbox_versions"
+msgstr "Versies en bestanden"
+
+#: views/elements/developers/editbox.thtml:42
+msgid "devcp_editbox_view_listing"
+msgstr "Lijst bekijken"
+
+#: views/elements/developers/editorsmenu.thtml:59
+msgid "devcp_editorsqueue_featured"
+msgstr "Aanbevolen add-ons"
+
+#. %1 is the review count
+#: views/elements/developers/editorsqueue.thtml:42
+#: views/elements/developers/editorsmenu.thtml:56
+#, php-format
+msgid "devcp_editorsqueue_moderatedreviews"
+msgid_plural "devcp_editorsqueue_moderatedreviews"
+msgstr[0] "Gescreende beoordeling (%s)"
+msgstr[1] "Gescreende beoordelingen (%s)"
+
+#. %1 is the nominated addons count
+#: views/elements/developers/editorsqueue.thtml:44
+#: views/elements/developers/editorsmenu.thtml:58
+#, php-format
+msgid "devcp_editorsqueue_nominated"
+msgid_plural "devcp_editorsqueue_nominated"
+msgstr[0] "Voorgedragen add-on (%s)"
+msgstr[1] "Voorgedragen add-ons (%s)"
+
+#. %1 is the update count
+#: views/elements/developers/editorsqueue.thtml:43
+#: views/elements/developers/editorsmenu.thtml:57
+#, php-format
+msgid "devcp_editorsqueue_pendingupdates"
+msgid_plural "devcp_editorsqueue_pendingupdates"
+msgstr[0] "Wachtende update (%s)"
+msgstr[1] "Wachtende updates (%s)"
+
+#: controllers/statistics_controller.php:147
+#: controllers/statistics_controller.php:361
+#: controllers/previews_controller.php:108
+#: controllers/previews_controller.php:211
+#: controllers/previews_controller.php:312
+msgid "devcp_error_addon_access_denied"
+msgstr "U hebt geen toegang tot die add-on."
+
+#. %s is a complete URL with the text from devcp_error_appversion_reference_link_text
+#. in the <a> tag. This should be fixed.
+#: controllers/components/developers.php:591
+#, php-format
+msgid "devcp_error_appversion_reference_link"
+msgstr "Lees a.u.b. %s als naslag."
+
+#. This is the link text in the <a> for devcp_error_appversion_reference_link. This
+#. should be fixed.
+#: controllers/components/developers.php:591
+msgid "devcp_error_appversion_reference_link_text"
+msgstr "deze pagina"
+
+#: views/developers/addon_edit_authors.thtml:76
+msgid "devcp_error_empty_authors"
+msgstr "Uw add-on dient ten minste één eigenaar te hebben."
+
+#. %1$s is the name of the file
+#: controllers/components/developers.php:658
+msgid "devcp_error_file_exists"
+msgstr ""
+"Er bestaat al een versie van die add-on. Om deze te vervangen dient u eerst "
+"het bestand %1$s te verwijderen."
+
+#. %1$s is a file extension. Example: .exe
+#. %2$s is a comma separated list of extensions. Example: .xpi, .jar
+#: controllers/components/developers.php:355
+#, php-format
+msgid "devcp_error_file_extension"
+msgstr ""
+"Die bestandsextensie (%s) is niet toegestaan voor het geselecteerde add-"
+"ontype. Gebruik a.u.b. één van de volgende: %s"
+
+#: controllers/components/developers.php:64
+msgid "devcp_error_five_categories"
+msgstr "Selecteer a.u.b. niet meer dan vijf categorieën."
+
+#: controllers/components/developers.php:526
+msgid "devcp_error_guid_application"
+msgstr "De ID van deze add-on wordt al gebruikt door een toepassing."
+
+#: controllers/components/developers.php:337
+#: controllers/components/developers.php:389
+msgid "devcp_error_http_incomplete"
+msgstr "Onvolledige overdracht"
+
+#: controllers/components/developers.php:335
+#: controllers/components/developers.php:336
+#: controllers/components/developers.php:387
+#: controllers/components/developers.php:388
+msgid "devcp_error_http_maxupload"
+msgstr "Groter dan de maximale uploadgrootte"
+
+#: controllers/components/developers.php:338
+#: controllers/components/developers.php:390
+msgid "devcp_error_http_nofile"
+msgstr "Geen bestand ge-upload"
+
+#. %1$s is a file extension. Example: .exe
+#. %2$s is a comma separated list of extensions. Example: .xpi, .jar
+#: controllers/components/developers.php:401
+#, php-format
+msgid "devcp_error_icon_extension"
+msgstr ""
+"Die bestandsextensie (%s) is niet toegestaan voor een pictogram. Gebruik a.u."
+"b. één van de volgende: %s"
+
+#: controllers/developers_controller.php:504
+msgid "devcp_error_index_rdf_notfound"
+msgstr "install.rdf ontbreekt."
+
+#: controllers/components/developers.php:601
+msgid "devcp_error_install_manifest"
+msgstr "De volgende fouten zijn aangetroffen in install.rdf:"
+
+#: controllers/developers_controller.php:1463
+msgid "devcp_error_invalid_addontype"
+msgstr "Selecteer a.u.b. een geldig add-ontype."
+
+#. %$1s is a version. Example: 3.1.1
+#. %$2s is an add-on name.
+#: controllers/components/developers.php:569
+#: controllers/components/developers.php:581
+#, php-format
+msgid "devcp_error_invalid_appversion"
+msgstr "%s is geen geldige versie voor %s"
+
+#. %s is a string
+#: controllers/components/developers.php:521
+#, php-format
+msgid "devcp_error_invalid_guid"
+msgstr "De ID van deze add-on is ongeldig: %s"
+
+#. %$1s is a version. Example: 3.1.1
+#. %$2s is an add-on name.
+#: controllers/components/developers.php:572
+#, php-format
+msgid "devcp_error_invalid_minversion"
+msgstr ""
+"%s is geen geldige versie voor %s: minimum versies kunnen geen * bevatten"
+
+#: controllers/components/developers.php:536
+msgid "devcp_error_invalid_version"
+msgstr ""
+"De versie van deze add-on is ongeldig: lees a.u.b. de <a href=\"http://"
+"developer.mozilla.org/en/docs/Toolkit_version_format\">specificatie</a>"
+
+#: controllers/components/developers.php:531
+msgid "devcp_error_invalid_version_spaces"
+msgstr ""
+"De versie van deze add-on is ongeldig: versies kunnen geen spaties bevatten."
+
+#. %s is an error message from the parser.
+#: controllers/components/developers.php:501
+#, php-format
+msgid "devcp_error_manifest_parse"
+msgstr "De volgende fout is opgetreden bij het ontleden van install.rdf: %s"
+
+#: controllers/components/developers.php:373
+msgid "devcp_error_move_file"
+msgstr "Bestand kon niet verplaatst worden"
+
+#. %s is the name of a file
+#: controllers/components/developers.php:650
+#: controllers/components/developers.php:662
+#: controllers/components/developers.php:667
+#: controllers/components/developers.php:727
+#: controllers/components/developers.php:738
+#: controllers/components/developers.php:743
+#, php-format
+msgid "devcp_error_moving_file"
+msgstr "Er is een fout opgetreden bij het verplaatsen van %s."
+
+#: controllers/components/developers.php:595
+msgid "devcp_error_mozilla_application"
+msgstr "U dient ten minste één geldige Mozilla-doeltoepassing te hebben."
+
+#: controllers/components/developers.php:516
+msgid "devcp_error_no_guid"
+msgstr "Er is geen ID voor deze add-on in install.rdf aangetroffen."
+
+#: controllers/components/developers.php:287
+msgid "devcp_error_no_platform"
+msgstr "Geen platform geselecteerd"
+
+#: controllers/components/developers.php:59
+msgid "devcp_error_one_category"
+msgstr "Selecteer a.u.b. ten minste één categorie."
+
+#: controllers/components/developers.php:92
+msgid "devcp_error_one_user"
+msgstr "Er dient ten minste één schrijver voor deze add-on te zijn."
+
+#. %1$s is a file extension. Example: .exe
+#. %2$s is a comma separated list of extensions. Example: .xpi, .jar
+#: controllers/components/developers.php:1081
+#, php-format
+msgid "devcp_error_preview_extension"
+msgstr ""
+"Die bestandsextensie (%s) is niet toegestaan voor een voorbeeldweergave. "
+"Gebruik a.u.b. één van de volgende: %s"
+
+#: controllers/components/developers.php:511
+msgid "devcp_error_updatekey"
+msgstr ""
+"Add-ons kunnen geen updateKey gebruiken. Verwijder deze a.u.b. uit install."
+"rdf en probeer het opnieuw."
+
+#: controllers/components/developers.php:506
+msgid "devcp_error_updateurl"
+msgstr ""
+"Add-ons kunnen geen externe update-URL gebruiken. Verwijder deze a.u.b. uit "
+"install.rdf en probeer het opnieuw."
+
+#: controllers/developers_controller.php:465
+#: controllers/components/developers.php:271
+msgid "devcp_error_upload_file"
+msgstr "Upload a.u.b. een bestand."
+
+#: views/developers/uploader.thtml:135
+msgid "devcp_input_upload_file"
+msgstr "Bestand uploaden"
+
+#: views/pages/js_constants.js.thtml:89
+msgid "devcp_js_a_cancel"
+msgstr "Annuleren"
+
+#: views/pages/js_constants.js.thtml:90
+msgid "devcp_js_add_email"
+msgstr ""
+"Voer a.u.b. het accounte-mailadres in van de schrijver die u wilt toevoegen."
+
+#. alt text for a down-arrow image.
+#: views/pages/js_constants.js.thtml:81
+msgid "devcp_js_img_move_down"
+msgstr "Omlaag"
+
+#. alt text for an up-arrow image.
+#: views/pages/js_constants.js.thtml:82
+msgid "devcp_js_img_move_up"
+msgstr "Omhoog"
+
+#: views/pages/js_constants.js.thtml:91
+msgid "devcp_js_img_remove_compat"
+msgstr "Toepassingscompatibiliteit verwijderen"
+
+#: views/pages/js_constants.js.thtml:86
+msgid "devcp_js_input_list_author"
+msgstr "Als schrijver vermelden in publieke lijsten"
+
+#: views/pages/js_constants.js.thtml:92
+msgid "devcp_js_license_select"
+msgstr "Selecteer a.u.b. een licentie."
+
+#: views/pages/js_constants.js.thtml:93
+msgid "devcp_js_license_text"
+msgstr "Voer a.u.b. tekst in voor uw licentie."
+
+#. <option> text in a <select> for Author role in an add-on.
+#: views/pages/js_constants.js.thtml:84
+msgid "devcp_js_option_developer"
+msgstr "Ontwikkelaar"
+
+#. <option> text in a <select> for Author role in an add-on.
+#: views/pages/js_constants.js.thtml:83
+msgid "devcp_js_option_owner"
+msgstr "Eigenaar"
+
+#. <option> text in a <select> for Author role in an add-on.
+#: views/pages/js_constants.js.thtml:85
+msgid "devcp_js_option_viewer"
+msgstr "Lezer"
+
+#: views/pages/js_constants.js.thtml:88
+msgid "devcp_js_remove_author"
+msgstr "Schrijver verwijderen"
+
+#: views/pages/js_constants.js.thtml:87
+msgid "devcp_js_sure_remove"
+msgstr "Weet u <strong>zeker</strong> dat u deze schrijver wilt verwijderen?"
+
+#: views/pages/js_constants.js.thtml:77
+msgid "devcp_js_upload_alert"
+msgstr "U dient een te uploaden bestand te selecteren."
+
+#. %1$s is an addon id, like 32.
+#. %2$s is a version number, like 3.5.
+#: controllers/components/developers.php:1212
+msgid "devcp_license_existing"
+msgstr "Aangepaste licentie voor add-on %1$s v%2$s"
+
+#: views/elements/developers/localebox.thtml:44
+msgid "devcp_localebox_header_localizedfields"
+msgstr "Gelocaliseerde velden"
+
+#. %1 is the default locale
+#: views/elements/developers/localebox.thtml:48
+#, php-format
+msgid "devcp_localebox_intro"
+msgstr ""
+"Sommige velden op deze pagina zijn gelocaliseerd zodat ze getoond worden in "
+"de taal van de eindgebruiker. Selecteer hieronder een locale om de details "
+"van uw add-on in die taal te bewerken. Als er voor een bepaalde locale geen "
+"vertaling beschikbaar is, wordt teruggevallen op de geselecteerde "
+"standaardlocale (%s)."
+
+#: views/elements/developers/sidebar.thtml:68
+#: views/elements/developers/myaddons.thtml:75
+msgid "devcp_myaddons_admincp_link"
+msgstr "Admin Controlevenster"
+
+#: views/elements/developers/sidebar.thtml:65
+#: views/elements/developers/myaddons.thtml:72
+msgid "devcp_myaddons_editorcp_link"
+msgstr "Editor Controlevenster"
+
+#: views/elements/developers/myaddons.thtml:52
+msgid "devcp_myaddons_link"
+msgstr "Mijn add-ons"
+
+#: views/elements/developers/sidebar.thtml:70
+#: views/elements/developers/myaddons.thtml:77
+msgid "devcp_myaddons_mainpage_link"
+msgstr "Terug naar hoofdvenster"
+
+#: views/elements/developers/sidebar.thtml:63
+#: views/elements/developers/myaddons.thtml:70
+msgid "devcp_myaddons_statistics_link"
+msgstr "Statistieken"
+
+#: views/elements/developers/sidebar.thtml:62
+#: views/elements/developers/myaddons.thtml:69
+msgid "devcp_myaddons_submitaddon_link"
+msgstr "Add-on indienen"
+
+#: views/elements/developers/sidebar.thtml:48
+#: views/elements/developers/myaddons.thtml:67
+msgid "devcp_myaddons_title"
+msgstr "Ontwikkelaarshulpmiddelen"
+
+#. %1$s is an add-on ID, perhaps 167.
+#. %2$s is a URL.
+#: controllers/developers_controller.php:256
+msgid "devcp_new_addon_error"
+msgstr ""
+"Een add-on met dit ID (%1$s) bestaat al in de database. Als dit uw add-on is "
+"kunt u <a href=\"%2$s\">een nieuwe versie uploaden</a>."
+
+#: views/developers/addon_status_nominate.thtml:62
+msgid "devcp_nominate_cancel"
+msgstr "Annuleren en terugkeren"
+
+#. %1 is the add-on name
+#: views/developers/addon_status_nominate.thtml:61
+#, php-format
+msgid "devcp_nominate_submit_nominate"
+msgstr "%s voordragen"
+
+#: views/developers/addon_edit_properties.thtml:50
+#: views/developers/addon_status.thtml:49
+#: views/developers/versions_edit.thtml:50
+msgid "devcp_notice_changes_error"
+msgstr ""
+"<span>Opslaan van één of meer van uw wijzigingen is mislukt.</span><br /"
+">Kijk a.u.b. naar onderstaande fouten. De rest van uw wijzigingen is "
+"succesvol opgeslagen."
+
+#: views/developers/addon_edit_authors.thtml:47
+#: views/developers/addon_edit_properties.thtml:47
+#: views/developers/addon_status.thtml:46
+#: views/developers/addon_edit_descriptions.thtml:47
+#: views/developers/versions_edit.thtml:47
+#: views/developers/addon_edit_categories.thtml:46
+msgid "devcp_notice_changes_saved"
+msgstr ""
+"<span>Uw wijzigingen zijn opgeslagen.</span><br />Merk a.u.b. op dat sommige "
+"wijzigingen mogelijk pas na enkele uren op alle delen van de website "
+"verschijnen."
+
+#: controllers/previews_controller.php:252
+msgid "devcp_notice_cleardefault"
+msgstr ""
+"Door dit als standaard voorbeeldweergave te verwijderen zal een andere "
+"voorbeeldweergave automatisch de standaard worden."
+
+#: controllers/previews_controller.php:184
+#: controllers/previews_controller.php:251
+msgid "devcp_notice_makedefault"
+msgstr ""
+"Door dit de standaardvoorbeeldweergave te maken zal de standaardstatus van "
+"de huidige standaardvoorbeeldweergave vervallen."
+
+#: views/developers/addon_edit_authors.thtml:70
+msgid "devcp_notice_unsaved_changes"
+msgstr "U hebt niet-opgeslagen wijzigingen."
+
+#: controllers/developers_controller.php:87
+#: controllers/developers_controller.php:97
+#: controllers/developers_controller.php:100
+#: controllers/previews_controller.php:67
+#: controllers/previews_controller.php:79
+#: controllers/previews_controller.php:82
+msgid "devcp_pagetitle"
+msgstr "Ontwikkelaarshulpmiddelen"
+
+#: controllers/previews_controller.php:103
+#: controllers/previews_controller.php:104
+msgid "devcp_preview_add_pagetitle"
+msgstr "Voorbeeldweergave toevoegen"
+
+#: controllers/previews_controller.php:135
+msgid "devcp_preview_added_successfully"
+msgstr "Voorbeeldweergave succesvol toegevoegd."
+
+#: controllers/previews_controller.php:323
+msgid "devcp_preview_deleted_successfully"
+msgstr "Voorbeeldweergave succesvol verwijderd."
+
+#: controllers/previews_controller.php:194
+#: controllers/previews_controller.php:195
+msgid "devcp_preview_edit_pagetitle"
+msgstr "Voorbeeldweergave bewerken"
+
+#: controllers/previews_controller.php:237
+msgid "devcp_preview_updated_successfully"
+msgstr "Voorbeeldweergave succesvol bijgewerkt."
+
+#: views/developers/previews.thtml:120
+msgid "devcp_previews_a_another"
+msgstr "Andere voorbeeldweergave toevoegen"
+
+#: views/developers/previews.thtml:96
+msgid "devcp_previews_a_delete"
+msgstr "Voorbeeldweergave verwijderen"
+
+#: views/developers/previews.thtml:95
+msgid "devcp_previews_a_replace"
+msgstr "Voorbeeldweergave vervangen"
+
+#: views/developers/previews.thtml:126
+msgid "devcp_previews_a_update"
+msgstr "Voorbeeldweergaven bijwerken"
+
+#: views/developers/previews.thtml:115 views/developers/previews.thtml:124
+msgid "devcp_previews_add_new"
+msgstr "Nieuwe voorbeeldweergave toevoegen"
+
+#. %s is a list of file extensions, e.g. ".png, .gif"
+#: views/developers/previews.thtml:116
+msgid "devcp_previews_add_select"
+msgstr ""
+"Selecteer hieronder een te uploaden afbeelding. Afbeeldingen die groter zijn "
+"dan de maximumgrootte van 700 pixels breed bij 525 pixels hoog worden "
+"verkleind. Toegestane bestandstypen: %s"
+
+#: views/developers/previews.thtml:121
+msgid "devcp_previews_click_below"
+msgstr "Klik hieronder op Voorbeeldweergaven bijwerken om te uploaden."
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/previews.thtml:102
+msgid "devcp_previews_click_update"
+msgstr ""
+"Klik hieronder op de knop Voorbeeldweergaven bijwerken om deze afbeelding op "
+"te slaan. (<a %s>Annuleren?</a>)"
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/previews.thtml:107
+msgid "devcp_previews_error_message"
+msgstr ""
+"Deze voorbeeldweergave wordt verwijderd wanneer hieronder op "
+"Voorbeeldweergaven bijwerken wordt geklikt. (<a %s>Annuleren?</a>)"
+
+#: views/previews/add.thtml:45
+msgid "devcp_previews_filetype_info"
+msgstr ""
+"Gebruik onderstaand formulier om een PNG, JPG of GIF screenshot van uw add-"
+"on te uploaden. Afbeeldingen die groter zijn dan 700 pixels breed en 525 "
+"pixels hoog worden automatisch verkleind."
+
+#: views/previews/add.thtml:43
+msgid "devcp_previews_header_add"
+msgstr "Voorbeeldweergave toevoegen"
+
+#: views/developers/previews.thtml:80
+msgid "devcp_previews_header_caption"
+msgstr "Tekst bij voorbeeldweergave"
+
+#: views/previews/edit.thtml:43
+msgid "devcp_previews_header_edit"
+msgstr "Voorbeeldweergave bewerken"
+
+#: views/developers/previews.thtml:93
+msgid "devcp_previews_label_default"
+msgstr "Standaardvoorbeeldweergave"
+
+#: views/previews/add.thtml:54
+msgid "devcp_previews_label_file"
+msgstr "Voorbeeldweergavebestand"
+
+#: views/previews/add.thtml:59 views/previews/edit.thtml:50
+msgid "devcp_previews_label_makedefault"
+msgstr "Van deze afbeelding de standaardvoorbeeldweergave maken"
+
+#: views/developers/previews.thtml:100
+msgid "devcp_previews_label_new"
+msgstr "Nieuwe afbeelding:"
+
+#: views/developers/previews.thtml:118
+msgid "devcp_previews_label_upload"
+msgstr "Voorbeeldweergave uploaden: "
+
+#: views/developers/previews.thtml:50
+msgid "devcp_previews_notice_error"
+msgstr "Opslaan van één of meer van uw nieuwe voorbeeldweergaven is mislukt."
+
+#: views/developers/previews.thtml:47
+msgid "devcp_previews_notice_success"
+msgstr "Uw voorbeeldweergaven zijn succesvol bijgewerkt."
+
+#: views/developers/previews.thtml:59
+msgid "devcp_previews_p_screenshots"
+msgstr ""
+"De voorbeeldweergaven voor uw add-on worden hieronder weergegeven. U kunt "
+"hieronder wijzigingen aan de tekst of de afbeeldingen. De "
+"Standaardvoorbeeldweergave is de afbeelding die naast uw add-on wordt "
+"weergegeven in zoek- en bladerlijsten."
+
+#: views/previews/edit.thtml:55
+msgid "devcp_previews_submit_delete"
+msgstr "Voorbeeldweergave verwijderen"
+
+#: views/previews/edit.thtml:55
+msgid "devcp_previews_submit_delete_confirm"
+msgstr "Weet u zeker dat u deze voorbeeldweergave wilt verwijderen?"
+
+#: views/previews/edit.thtml:54
+msgid "devcp_previews_submit_edit"
+msgstr "Voorbeeldweergave bewerken"
+
+#: views/previews/add.thtml:63
+msgid "devcp_previews_submit_upload"
+msgstr "Voorbeeldweergave uploaden"
+
+#: views/developers/previews.thtml:78
+msgid "devcp_previews_thumbnail"
+msgstr "Miniatuur"
+
+#. %s is the add-on name.
+#: views/developers/previews.thtml:44
+msgid "devcp_previews_title"
+msgstr "%s voorbeeldweergaven beheren"
+
+#: views/developers/uploader.thtml:74
+msgid "devcp_review_agreement_please"
+msgstr ""
+"Lees en accepteer a.u.b. de volgende Ontwikkelaarsovereenkomst voordat u "
+"verder gaat."
+
+#: views/elements/developers/rolecheck.thtml:42
+msgid "devcp_rolecheck_no_privs"
+msgstr ""
+"<span>U hebt onvoldoende rechten om deze pagina te wijzigen.</span><br /"
+">Neem contact op met de eigenaar van de add-on als u wijzigingen dient aan "
+"te brengen."
+
+#: controllers/developers_controller.php:1315
+msgid "devcp_several_hours"
+msgstr ""
+"Merk a.u.b. op dat sommige wijzigingen mogelijk pas na enkele uren op alle "
+"delen van de website worden getoond."
+
+#: views/elements/developers/sidebar.thtml:52
+msgid "devcp_sidebar_a_dashboard"
+msgstr "Dashboard"
+
+#. %s is a number
+#: views/elements/developers/statsbar.thtml:45
+#: views/developers/dashboard.thtml:79
+#, php-format
+msgid "devcp_statsbar_adu"
+msgstr "<em>%s</em> actieve dagelijkse gebruikers"
+
+#. %s is a number
+#: views/elements/developers/statsbar.thtml:41
+#: views/developers/dashboard.thtml:75
+#, php-format
+msgid "devcp_statsbar_total_downloads"
+msgstr "<em>%s</em> downloads in totaal"
+
+#. %s is a number
+#: views/elements/developers/statsbar.thtml:43
+#: views/developers/dashboard.thtml:77
+#, php-format
+msgid "devcp_statsbar_weekly_downloads"
+msgstr "<em>%s</em> downloads per week"
+
+#: views/developers/addon_status_confirm.thtml:59
+msgid "devcp_status_confirm_active"
+msgstr ""
+"Het als actief markeren van deze add-on zorgt ervoor dat deze in publieke "
+"gebieden passend bij de status wordt weergegeven, inclusief zoek- en "
+"bladerlijsten. Hij kan worden gedownload van de website en kan worden "
+"gesignaleerd in updatecontroles aan de clientzijde, afhankelijk van de "
+"status. U kunt hier terugkeren en de add-on naar uw goeddunken weer "
+"uitschakelen."
+
+#: views/developers/addon_status_confirm.thtml:59
+msgid "devcp_status_confirm_active_sure"
+msgstr "Weet u zeker dat u deze add-on als actief wilt markeren?"
+
+#: views/developers/addon_status_confirm.thtml:50
+msgid "devcp_status_confirm_header_sure"
+msgstr "Weet u dit zeker?"
+
+#: views/developers/addon_status_confirm.thtml:55
+msgid "devcp_status_confirm_inactive"
+msgstr ""
+"Het als inactief markeren van deze add-on zorgt ervoor dat deze in geen "
+"enkel publiek gebied wordt weergegeven, inclusief zoek- en bladerlijsten. "
+"Hij kan niet worden gedownload van de website en wordt niet gesignaleerd in "
+"updatecontroles aan de clientzijde. U kunt hier terugkeren en de add-on naar "
+"uw goeddunken weer inschakelen."
+
+#: views/developers/addon_status_confirm.thtml:55
+msgid "devcp_status_confirm_inactive_sure"
+msgstr "Weet u zeker dat u deze add-on als inactief wilt markeren?"
+
+#: views/developers/addon_status_confirm.thtml:74
+msgid "devcp_status_confirm_no"
+msgstr "Nee, annuleren"
+
+#: views/developers/addon_status_confirm.thtml:67
+msgid "devcp_status_confirm_public"
+msgstr ""
+"Door publiceren van deze add-on kan deze worden gedownload door iedereen en "
+"zullen updates worden aangeboden aan bestaande gebruikers."
+
+#: views/developers/addon_status_confirm.thtml:67
+msgid "devcp_status_confirm_public_sure"
+msgstr "Weet u zeker dat u deze add-on wilt publiceren?"
+
+#: views/developers/addon_status_confirm.thtml:63
+msgid "devcp_status_confirm_sandbox"
+msgstr ""
+"Door deze add-on terug te plaatsen in de sandbox dienen gebruikers in te "
+"loggen voordat ze kunnen downloaden en updates worden niet langer aangeboden "
+"aan bestaande gebruikers. Omdat uw add-on momenteel publiek is kunt u hier "
+"elk moment terugkeren om deze opnieuw te publiceren."
+
+#: views/developers/addon_status_confirm.thtml:63
+msgid "devcp_status_confirm_sandbox_sure"
+msgstr "Weet u zeker dat u deze add-on naar de sandbox wilt verplaatsen?"
+
+#: views/developers/addon_status_confirm.thtml:73
+msgid "devcp_status_confirm_yes"
+msgstr "Ja, dat weet ik zeker"
+
+#: views/developers/addon_status_nominate.thtml:46
+msgid "devcp_status_nominate_error_notice"
+msgstr ""
+"<span>Een nominatiebericht is vereist.</span><br />Vul a.u.b. het tekstveld "
+"met de gewenste informatie en probeer het opnieuw."
+
+#: views/developers/addon_status_nominate.thtml:55
+msgid "devcp_status_nominate_header"
+msgstr "Add-onnominatie"
+
+#: views/developers/dashboard.thtml:85
+msgid "devcp_summary_lastversion"
+msgstr "Laatste versie:"
+
+#. %s is the add-on name.
+#: views/developers/addon_edit.thtml:43
+#: views/developers/addon_edit_authors.thtml:44
+#: views/developers/versions_delete.thtml:43
+#: views/developers/addon_edit_properties.thtml:44
+#: views/developers/addon_edit_descriptions.thtml:44
+#: views/developers/versions_edit.thtml:44
+#: views/developers/addon_edit_categories.thtml:43
+#: views/developers/versions.thtml:43
+msgid "devcp_title_edit_addon"
+msgstr "%s bewerken"
+
+#. title attribute for a javascript link that pops up a help dialog.
+#: views/elements/translationbox.thtml:68
+msgid "devcp_transbox_a_title_help"
+msgstr "Hulp (op dezelfde pagina)"
+
+#: views/elements/translationbox.thtml:68
+msgid "devcp_transbox_alt_help"
+msgstr "Hulp"
+
+#. %1$s is <span>17</span>, %2$s is 42.
+#: views/elements/translationbox.thtml:101
+msgid "devcp_transbox_chars_used"
+msgstr "Gebruikte karakters: %1$s / %2$s"
+
+#: views/elements/translationbox.thtml:132
+msgid "devcp_transbox_delete_sure"
+msgstr "Weet u zeker dat u deze vertaling wilt verwijderen?"
+
+#. %s is a locale, like en-US.
+#: views/elements/translationbox.thtml:143
+msgid "devcp_transbox_help_header_tabs"
+msgstr "Wat betekenen deze tabbladen met %s?"
+
+#: views/elements/translationbox.thtml:145
+msgid "devcp_transbox_help_header_what"
+msgstr "Wat als ik geen vertalingen heb?"
+
+#: views/elements/translationbox.thtml:147
+msgid "devcp_transbox_help_hide"
+msgstr "Hulp verbergen"
+
+#: views/elements/translationbox.thtml:146
+msgid "devcp_transbox_help_if"
+msgstr ""
+"Als een gebruiker de site doorbladert en er is geen vertaling beschikbaar in "
+"de eigen taal wordt teruggevallen op de standaardlocale van uw add-on, zoals "
+"opgegeven in het gedeelte Add-oneigenschappen bewerken. Voer als u geen "
+"vertalingen heeft gewoon in wat u kan in de standaardlocale, wat de taal zou "
+"moeten zijn die u spreekt."
+
+#: views/elements/translationbox.thtml:144
+msgid "devcp_transbox_help_transbox"
+msgstr ""
+"Dit is een <i>vertaalveld</i>. Hiermee kunt u een specifiek veld localiseren "
+"naar elke andere taal waarvoor u een vertaling heeft. U kunt vertalingen "
+"toevoegen, bewerken en verwijderen met de localetabbladen."
+
+#: views/elements/translationbox.thtml:85
+msgid "devcp_transbox_img_add_trans"
+msgstr "Vertaling toevoegen"
+
+#: views/elements/translationbox.thtml:86
+msgid "devcp_transbox_img_remove_trans"
+msgstr "Vertaling verwijderen"
+
+#: views/elements/translationbox.thtml:123
+msgid "devcp_transbox_input_add_all"
+msgstr "Localeaan alles toevoegen"
+
+#: views/elements/translationbox.thtml:122
+msgid "devcp_transbox_input_add_locale"
+msgstr "Locale toevoegen"
+
+#: views/elements/translationbox.thtml:124
+#: views/elements/translationbox.thtml:135
+msgid "devcp_transbox_input_cancel"
+msgstr "Annuleren"
+
+#: views/elements/translationbox.thtml:134
+msgid "devcp_transbox_input_delete"
+msgstr "Verwijderen"
+
+#: views/elements/translationbox.thtml:113
+msgid "devcp_transbox_select_locale"
+msgstr "Selecteer de locale van de toe te voegen vertaling:"
+
+#. %1$s and %2$s are GUIDs.
+#: controllers/developers_controller.php:343
+msgid "devcp_update_addon_guid_error"
+msgstr ""
+"De GUID van de add-on in dit bestand (%1$s) komt niet overeen met de "
+"bestaande GUID voor deze add-on (%2$s)."
+
+#: controllers/developers_controller.php:334
+msgid "devcp_update_addon_priv_error"
+msgstr "U hebt onvoldoende rechten om deze add-on bij te werken."
+
+#. %1$s is a version number, %2$s is an add-on ID.
+#: controllers/developers_controller.php:399
+msgid "devcp_update_addon_version_belong_error"
+msgstr "De opgegeven versie (%1$s) hoort niet bij deze add-on (%2$s)."
+
+#. %1$s is a version number, maybe 1.1.
+#. %2$s is a URL.
+#: controllers/developers_controller.php:351
+msgid "devcp_update_addon_version_exists_error"
+msgstr ""
+"Het geüploade versienummer (%1$s) bestaat al voor deze add-on. Als u "
+"probeert een ander bestand toe te voegen aan deze versie, <a href=\"%2$s"
+"\">klik dan hier</a>."
+
+#. %1$s and %2$s are version numbers.
+#: controllers/developers_controller.php:405
+msgid "devcp_update_addon_version_match_error"
+msgstr ""
+"Het geüploade versienummer (%1$s) komt niet overeen met het bestaande "
+"versienummer (%2$s)."
+
+#: views/developers/uploader.thtml:68
+msgid "devcp_uploader_a_start"
+msgstr "Van start"
+
+#: views/developers/uploader.thtml:137
+msgid "devcp_uploader_ajax_loading"
+msgstr "Bestand uploaden…"
+
+#: views/developers/uploader.thtml:82
+msgid "devcp_uploader_button_agree"
+msgstr "Instemmen en doorgaan"
+
+#: views/developers/uploader.thtml:157
+msgid "devcp_uploader_button_edit"
+msgstr "Mijn add-on bewerken"
+
+#: views/developers/uploader.thtml:158
+msgid "devcp_uploader_button_later"
+msgstr "Ik rond mijn add-on later af."
+
+#: views/developers/uploader.thtml:168
+msgid "devcp_uploader_button_release"
+msgstr "Versieopmerkingen toevoegen"
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/uploader.thtml:156
+msgid "devcp_uploader_created_results"
+msgstr ""
+"<p>Uw add-onlijst is succesvol aangemaakt. De basisinformatie die is "
+"opgehaald uit het geüploade bestand is opgeslagen, maar er is nog meer aan "
+"uw lijstvermelding dat kan worden aangepast.</p><p>Uw add-on is momenteel "
+"gemarkeerd als <strong>Incompleet</strong>. Om uw add-on af te ronden dient "
+"u te zorgen voor een accurate naam, een samenvatting en een beschrijving, "
+"naast ten minste één geselecteerde categorie. U kunt de informatie van uw "
+"add-on bewerken via onderstaande koppeling en de status van uw add-on op elk "
+"moment controleren op de <a %s>statuspagina</a>."
+
+#: views/developers/uploader.thtml:143
+msgid "devcp_uploader_error_correct"
+msgstr "Corrigeer a.u.b. dit probleem en upload uw bestand opnieuw."
+
+#. %1$s is a version number, %2$s is a status, e.g Public or Incomplete.
+#: views/developers/uploader.thtml:175
+msgid "devcp_uploader_file_created"
+msgstr ""
+"Uw nieuwe bestand is toegevoegd aan versie %1$s en is momenteel gemarkeerd "
+"als %2$s."
+
+#: views/developers/uploader.thtml:154
+msgid "devcp_uploader_header_created"
+msgstr "Add-on aangemaakt!"
+
+#: views/developers/uploader.thtml:141
+msgid "devcp_uploader_header_error"
+msgstr "Oeps! Er lijkt een probleem te zijn met dit bestand…"
+
+#: views/developers/uploader.thtml:173
+msgid "devcp_uploader_header_file_added"
+msgstr "Bestand toegevoegd!"
+
+#: views/developers/uploader.thtml:66
+msgid "devcp_uploader_header_how"
+msgstr "Hoe werkt dit allemaal?"
+
+#. %s is the version number, e.g. 3.2.
+#: views/developers/uploader.thtml:163
+msgid "devcp_uploader_header_update_created"
+msgstr "Versie %s aangemaakt"
+
+#: views/developers/uploader.thtml:117
+msgid "devcp_uploader_header_upload"
+msgstr "Uw bestand uploaden"
+
+#: views/developers/uploader.thtml:67
+msgid "devcp_uploader_how"
+msgstr ""
+"<p>Bedankt voor uw belangstelling in indienen van uw add-on bij Mozilla Add-"
+"ons. Hosten van uw add-on bij Mozilla Add-ons is de eenvoudigste manier om "
+"voor distributie van uw add-on te zorgen. Dit is wat u krijgt:</"
+"p><ul><li>Elke add-on krijgt een publieke pagina met door u opgegeven "
+"informatie, zoals een korte samenvatting van de functionaliteit van de add-"
+"on, een optionele langere beschrijving, en voorbeeldweergaven van uw add-on."
+"</li><li>Uw add-on verschijnt in zoek- en bladerlijsten op de gehele site en "
+"zelfs in de Add-onbeheerder van Firefox 3.</li><li>Wij zorgen voor het "
+"hosten van al uw downloads en zorgen voor automatische updates voor "
+"gebruikers wanneer u een nieuwe versie uploadt.</li><li>U krijgt toegang tot "
+"een statistiekendashboard met gedetailleerde informatie over uw "
+"gebruikersgroep.</li></ul><p>Add-ons die op de site worden gehost moeten "
+"worden beoordeeld door een Mozilla Add-onseditor voordat ze alle "
+"bovenstaande functies ter beschikking krijgen. Als u klaar bent om het "
+"proces te starten en uw add-onpakket bij de hand heeft klik dan hieronder op "
+"Van start!</p>"
+
+#: views/developers/uploader.thtml:125
+msgid "devcp_uploader_label_platformtype"
+msgstr "Ondersteunde besturingssystemen:"
+
+#: views/developers/uploader.thtml:124
+msgid "devcp_uploader_label_upload_field"
+msgstr "Add-onbestand: "
+
+#: controllers/components/developers.php:1221
+msgid "devcp_uploader_option_other"
+msgstr "Overig"
+
+#. %1$s is a number, %2$s is href="..." and should stay in the <a> tag.
+#: views/developers/uploader.thtml:176
+msgid "devcp_uploader_p_pending_file"
+msgstr ""
+"Het nieuwe bestand wordt beschikbaar voor het publiek zodra een editor het "
+"heeft kunnen beoordelen. Momenteel wachten %1$s andere add-ons hierop. Wilt "
+"u een snellere beoordeling? Overweeg dan <a %2$s>ook een editor te worden</"
+"a>."
+
+#. %1$s is a number, %2$s is href="..." and should stay in the <a> tag.
+#: views/developers/uploader.thtml:166
+msgid "devcp_uploader_p_pending_version"
+msgstr ""
+"De nieuwe versie wordt beschikbaar voor het publiek zodra een editor het "
+"heeft kunnen beoordelen. Momenteel wachten %1$s andere add-ons hierop. Wilt "
+"u een snellere beoordeling? Overweeg dan <a %2$s>ook een editor te worden</"
+"a>."
+
+#. %s is a status, e.g Public or Incomplete.
+#: views/developers/uploader.thtml:165
+msgid "devcp_uploader_p_update_created"
+msgstr "Uw nieuwe versie is aangemaakt en is momenteel gemarkeerd als %s."
+
+#. %1$s is href="..." and should stay in the 'Versions and Files' <a> tag.
+#. %2$s is href="..." and should stay in the 'current status' <a> tag.
+#: views/developers/uploader.thtml:177
+msgid "devcp_uploader_p_update_file"
+msgstr ""
+"Bekijk uw nieuwe bestand op de <a %1$s>Versies en Bestandenpagina</a>, "
+"bekijk de <a %2$s>huidige status</a> van uw add-on, of <b>voeg "
+"versieopmerkingen toe</b> door op onderstaande knop te klikken (sterk "
+"aanbevolen)."
+
+#. %1$s is href="..." and should stay in the 'Versions and Files' <a> tag.
+#. %2$s is href="..." and should stay in the 'current status' <a> tag.
+#: views/developers/uploader.thtml:167
+msgid "devcp_uploader_p_update_version"
+msgstr ""
+"Bekijk uw nieuwe versie op de <a %1$s>Versies en Bestandenpagina</a>, bekijk "
+"yde <a %2$s>huidige status</a> van uw add-on, of <b>voeg versieopmerkingen "
+"toe</b> door op onderstaande knop te klikken (sterk aanbevolen)."
+
+#: views/developers/uploader.thtml:118
+msgid "devcp_uploader_p_upload"
+msgstr ""
+"Upload uw add-onbestand via onderstaand formulier. Indien u meerdere "
+"platform-specifieke bestanden wilt uploaden, kies dan een enkel bestand en "
+"upload vervolgens de overige via de Versies en Bestandenbeheerder."
+
+#: views/developers/uploader.thtml:125
+msgid "devcp_uploader_platformtype_all"
+msgstr "Alles"
+
+#: views/developers/uploader.thtml:126
+msgid "devcp_uploader_platformtype_specific"
+msgstr "Specifiek:"
+
+#. Used as first item in a <select>.
+#: controllers/components/developers.php:1185
+msgid "devcp_uploader_please_choose"
+msgstr "Kies a.u.b.…"
+
+#. %1$s is the add-on name, %2$s is the version number.
+#: views/developers/uploader.thtml:57
+msgid "devcp_uploader_title_file"
+msgstr "Bestand toevoegen aan %1$s %2$s"
+
+#: views/developers/uploader.thtml:50
+msgid "devcp_uploader_title_submit"
+msgstr "Nieuwe add-on indienen"
+
+#. %s is the add-on name.
+#: views/developers/uploader.thtml:54
+msgid "devcp_uploader_title_update"
+msgstr "%s bijwerken"
+
+#. %s is a full <a> tag
+#: controllers/developers_controller.php:503
+#, php-format
+msgid "devcp_valid_app_reference"
+msgstr "Lees a.u.b. %s als naslag."
+
+#. This is the text in the <a> tag for devcp_valid_app_reference. This should be
+#. fixed.
+#: controllers/developers_controller.php:503
+msgid "devcp_valid_app_reference_linktext"
+msgstr "deze pagina"
+
+#: controllers/developers_controller.php:581
+msgid "devcp_verify_author_error"
+msgstr "Geen account gevonden voor dat e-mailadres."
+
+#: controllers/developers_controller.php:553
+msgid "devcp_verify_search_engine_error"
+msgstr ""
+"De XML is ongeldig of vereiste velden zijn niet ingevuld. Lees a.u.b. <a "
+"href=\"https://developer.mozilla.org/en/"
+"Creating_OpenSearch_plugins_for_Firefox\">de documentatie</a>, controleer uw "
+"add-on, en probeer het opnieuw."
+
+#: views/developers/versions.thtml:75
+msgid "devcp_versions_a_cancel"
+msgstr "Annuleren"
+
+#: views/developers/versions.thtml:79
+msgid "devcp_versions_a_delete"
+msgstr "Versie verwijderen"
+
+#: views/developers/versions.thtml:74
+msgid "devcp_versions_a_empty"
+msgstr "Lege versie verwijderen"
+
+#: views/developers/versions.thtml:71
+msgid "devcp_versions_a_remove"
+msgstr "Verwijderen?"
+
+#: views/developers/versions.thtml:91
+msgid "devcp_versions_add"
+msgstr "Nieuwe versie toevoegen"
+
+#: views/developers/versions_delete.thtml:58
+msgid "devcp_versions_delete_a_cancel"
+msgstr "Annuleren"
+
+#: views/developers/versions_delete.thtml:56
+msgid "devcp_versions_delete_a_delete"
+msgstr "Versie verwijderen"
+
+#. Followed by a list of reviews and files that will be removed.
+#: views/developers/versions_delete.thtml:50
+msgid "devcp_versions_delete_also"
+msgstr "Dit verwijdert ook:"
+
+#: views/developers/versions_delete.thtml:53
+msgid "devcp_versions_delete_files"
+msgid_plural "devcp_versions_delete_files"
+msgstr[0] "%s bestand"
+msgstr[1] "%s bestanden"
+
+#. %s is the version number.
+#: views/developers/versions_delete.thtml:48
+msgid "devcp_versions_delete_header"
+msgstr "Versie %s verwijderen?"
+
+#: views/developers/versions_delete.thtml:52
+msgid "devcp_versions_delete_reviews"
+msgid_plural "devcp_versions_delete_reviews"
+msgstr[0] "%s beoordeling"
+msgstr[1] "%s beoordelingen"
+
+#. %s is the version number.
+#: views/developers/versions_delete.thtml:49
+msgid "devcp_versions_delete_sure"
+msgstr "Weet u zeker dat u versie %s permanent wilt verwijderen?"
+
+#: views/developers/versions_edit.thtml:102
+#: views/developers/versions_edit.thtml:155
+msgid "devcp_versions_edit_a_cancel"
+msgstr "Annuleren"
+
+#: views/developers/versions_edit.thtml:101
+msgid "devcp_versions_edit_a_delete"
+msgstr "Bestand verwijderen"
+
+#: views/developers/versions_edit.thtml:165
+msgid "devcp_versions_edit_a_new_app"
+msgstr "Nieuwe toepassing toevoegen"
+
+#: views/developers/versions_edit.thtml:154
+msgid "devcp_versions_edit_a_remove_app"
+msgstr "Toepassing verwijderen"
+
+#: views/developers/versions_edit.thtml:114
+msgid "devcp_versions_edit_add"
+msgstr "Nieuw bestand toevoegen"
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/versions_edit.thtml:121
+msgid "devcp_versions_edit_adjust"
+msgstr ""
+"Door hier aanpassen van toepassinginformatie kunnen gebruikers uw add-on "
+"installeren, zelfs als install.rdf in het pakket aangeeft dat de add-on niet "
+"compatibel is <a %s>Lijst van ondersteunde toepassingen</a>"
+
+#: views/developers/versions_edit.thtml:153
+msgid "devcp_versions_edit_compat_sure"
+msgstr ""
+"Weet u <b>zeker</b> dat u compatibiliteit met deze toepassing wilt "
+"verwijderen?"
+
+#: views/developers/versions_edit.thtml:100
+msgid "devcp_versions_edit_delete_sure"
+msgstr "Weet uu <b>zeker</b> dat u dit bestand permanent wilt verwijderen?"
+
+#: views/developers/versions_edit.thtml:203
+msgid "devcp_versions_edit_header_approval"
+msgstr "Goedkeuringsinformatie"
+
+#: views/developers/versions_edit.thtml:120
+msgid "devcp_versions_edit_header_compat"
+msgstr "Compatibele toepassingen"
+
+#: views/developers/versions_edit.thtml:74
+msgid "devcp_versions_edit_header_file"
+msgstr "Bestandsinformatie"
+
+#: views/developers/versions_edit.thtml:189
+msgid "devcp_versions_edit_header_license"
+msgstr "Licentie"
+
+#. %s is the version number.
+#: views/developers/versions_edit.thtml:53
+msgid "devcp_versions_edit_header_manage"
+msgstr "Versie %s beheren"
+
+#: views/developers/versions_edit.thtml:212
+msgid "devcp_versions_edit_header_notes"
+msgstr "Goedkeuringsopmerkingen"
+
+#: views/developers/versions_edit.thtml:98
+msgid "devcp_versions_edit_img_delete"
+msgstr "Bestand verwijderen"
+
+#. %1$s is the file id, e.g. 18723.
+#. %2$s is the platform name, e.g. ALL or Windows.
+#. %3$s is the _('date) created.
+#. %4$s is the status, e.g. "In Sandbox" or "Public".
+#. %5$s is the _('date') status was changed.
+#: views/developers/versions_edit.thtml:208
+msgid "devcp_versions_edit_li_file"
+msgstr "Bestand %1$s (%2$s) aangemaakt op %3$s en gewijzigd in %4$s op %5$s"
+
+#: views/developers/versions_edit.thtml:190
+msgid "devcp_versions_edit_license_description"
+msgstr ""
+"Selecteer a.u.b. de toepasselijke licentie voor uw add-on. Deze licentie "
+"specificeert de rechten die u verleent op uw broncode."
+
+#: views/developers/versions_edit.thtml:111
+msgid "devcp_versions_edit_no_files"
+msgstr "Geen bestanden gevonden."
+
+#: views/developers/versions_edit.thtml:213
+msgid "devcp_versions_edit_optional"
+msgstr "Optionele informatie voor de editor die deze versie beoordeelt."
+
+#: views/developers/versions_edit.thtml:151
+msgid "devcp_versions_edit_remove_compat"
+msgstr "Toepassingscompatibiliteit verwijderen"
+
+#: views/developers/versions_edit.thtml:167
+msgid "devcp_versions_edit_select_app"
+msgstr "Selecteer a.u.b. een toepassing"
+
+#: views/developers/versions_edit.thtml:78
+msgid "devcp_versions_edit_th_file"
+msgstr "Bestand"
+
+#: views/developers/versions_edit.thtml:79
+msgid "devcp_versions_edit_th_platform"
+msgstr "Platform"
+
+#: views/developers/versions_edit.thtml:80
+msgid "devcp_versions_edit_th_size"
+msgstr "Grootte"
+
+#: views/developers/versions_edit.thtml:81
+msgid "devcp_versions_edit_th_status"
+msgstr "Status"
+
+#: views/developers/versions_edit.thtml:183
+msgid "devcp_versions_edit_transbox_releasenotes_description"
+msgstr ""
+"Informatie over wijzigingen in deze uitgave, nieuwe functies, bekende fouten "
+"en overige nuttige informatie specifiek voor deze uitgave/versie. Deze "
+"informatie is ook beschikbaar voor gebruikers die de add-on bijwerken in de "
+"Firefox 3 Add-onbeheerder."
+
+#: views/developers/versions_edit.thtml:182
+msgid "devcp_versions_edit_transbox_releasenotes_name"
+msgstr "Versieopmerkingen"
+
+#: views/developers/versions_edit.thtml:164
+msgid "devcp_versions_edit_unsaved_compat"
+msgstr ""
+"<strong>U hebt nog niet-opgeslagen wijzigingen.</strong> Compatibiliteit "
+"wordt niet verwijderd totdat u hieronder op Versie bijwerken klikt."
+
+#: views/developers/versions_edit.thtml:113
+msgid "devcp_versions_edit_unsaved_files"
+msgstr ""
+"<strong>U hebt nog niet-opgeslagen wijzigingen.</strong> Bestanden worden "
+"niet verwijderd totdat u hieronder op Versie bijwerken klikt."
+
+#: views/developers/versions_edit.thtml:218
+msgid "devcp_versions_edit_update"
+msgstr "Versies bijwerken"
+
+#: views/developers/versions.thtml:49
+msgid "devcp_versions_header_manage"
+msgstr "Versies en Bestanden beheren"
+
+#: views/developers/versions.thtml:87
+msgid "devcp_versions_no_versions"
+msgstr "Geen versies."
+
+#. %s is a version number, base 10.
+#: views/developers/versions.thtml:46
+msgid "devcp_versions_notice_success"
+msgstr "Versie %s succesvol verwijderd."
+
+#: views/developers/versions.thtml:73
+msgid "devcp_versions_p_remove"
+msgstr ""
+"Deze versie heeft geen geassocieerde bestanden en kan worden verwijderd. "
+"Wilt u deze versie verwijderen?"
+
+#: views/developers/versions.thtml:58
+msgid "devcp_versions_th_created"
+msgstr "Aangemaakt"
+
+#: views/developers/versions.thtml:57
+msgid "devcp_versions_th_status"
+msgstr "Status"
+
+#: views/developers/versions.thtml:56
+msgid "devcp_versions_th_version"
+msgstr "Versie"
+
+#: controllers/downloads_controller.php:91
+msgid "downloads_disable_warning"
+msgstr "Deze add-on is uitgeschakeld"
+
+#: controllers/components/editors.php:57
+msgid "editor_review_error_addon_not_nominated"
+msgstr "Deze add-on is niet genomineerd."
+
+#: controllers/components/editors.php:213
+msgid "editor_review_error_file_not_pending"
+msgstr "Dit bestand wacht niet op beoordeling."
+
+#. Actions are, for example: approving or rejecting
+#: controllers/components/editors.php:79
+#: controllers/components/editors.php:182
+msgid "editor_review_error_no_action"
+msgstr "Selecteer a.u.b. een beoordelingsactie."
+
+#: controllers/components/editors.php:192
+msgid "editor_review_error_no_applications"
+msgstr "Voer a.u.b. de toepassingen in die u getest hebt."
+
+#. Comments are required when an editor approves or rejects an add-on.
+#: controllers/components/editors.php:84
+#: controllers/components/editors.php:187
+msgid "editor_review_error_no_comments"
+msgstr "Voer a.u.b. beoordelingsopmerkingen in."
+
+#: controllers/components/editors.php:161
+msgid "editor_review_error_no_files"
+msgstr "Selecteer a.u.b. ten minste één bestand om te beoordelen."
+
+#: controllers/components/editors.php:197
+msgid "editor_review_error_no_operating_system"
+msgstr "Selecteer a.u.b. de besturingssystemen die u getest hebt."
+
+#: views/editors/logs.thtml:51
+msgid "editorcp_logs_button_filter"
+msgstr "Filteren"
+
+#: views/editors/logs.thtml:44
+msgid "editorcp_logs_filter_by"
+msgstr "Filteren op type/actie"
+
+#: views/editors/logs.thtml:42 controllers/editors_controller.php:964
+msgid "editorcp_logs_page_heading"
+msgstr "Gebeurtenissenlogboek"
+
+#: views/elements/developers/editorsmenu.thtml:60
+msgid "editorcp_menu_eventlog_link"
+msgstr "Gebeurtenissenlogboek"
+
+#: views/elements/developers/editorsmenu.thtml:62
+msgid "editorcp_menu_mainpage_link"
+msgstr "Terug naar hoofdpagina"
+
+#: views/elements/developers/editorsmenu.thtml:61
+msgid "editorcp_menu_reviewlog_link"
+msgstr "Logboek beoordelen"
+
+#: views/elements/developers/editorsmenu.thtml:55
+msgid "editorcp_menu_summary_link"
+msgstr "Samenvatting van de editor"
+
+#: views/elements/developers/editorsmenu.thtml:52
+msgid "editorcp_menu_title"
+msgstr "Editorhulpmiddelen"
+
+#: views/editors/reviewlog.thtml:49
+msgid "editorcp_reviewlog_button_filter"
+msgstr "Filteren"
+
+#: views/editors/reviewlog.thtml:58
+msgid "editorcp_reviewlog_column_action"
+msgstr "Actie"
+
+#: views/editors/reviewlog.thtml:56
+msgid "editorcp_reviewlog_column_addon"
+msgstr "Add-on"
+
+#: views/editors/reviewlog.thtml:55
+msgid "editorcp_reviewlog_column_date"
+msgstr "Datum"
+
+#: views/editors/reviewlog.thtml:57
+msgid "editorcp_reviewlog_column_editor"
+msgstr "Editor"
+
+#: views/editors/reviewlog.thtml:94
+msgid "editorcp_reviewlog_comments_hide"
+msgstr "Opmerkingen verbergen"
+
+#: views/editors/reviewlog.thtml:93
+msgid "editorcp_reviewlog_comments_show"
+msgstr "Opmerkingen weergeven"
+
+#. %1$s and %2$s are full <input> tags for dates
+#: views/editors/reviewlog.thtml:45
+#, php-format
+msgid "editorcp_reviewlog_entries_between"
+msgstr "Ingaven tussen %s en %s bekijken"
+
+#: views/editors/reviewlog.thtml:104
+msgid "editorcp_reviewlog_none_found"
+msgstr "Geen beoordelingen gevonden in deze periode."
+
+#: views/editors/reviewlog.thtml:42
+msgid "editorcp_reviewlog_page_heading"
+msgstr "Logboek van beoordelingen"
+
+#: views/editors/summary.thtml:61
+msgid "editorcp_summary_monthreviews_heading"
+msgstr "Beoordelingen deze maand"
+
+#: views/editors/summary.thtml:77
+msgid "editorcp_summary_neweditors_heading"
+msgstr "Nieuwe editors"
+
+#: views/editors/summary.thtml:42
+msgid "editorcp_summary_page_heading"
+msgstr "Samenvatting van de editor"
+
+#: views/editors/summary.thtml:94
+msgid "editorcp_summary_recentactivity_heading"
+msgstr "Recente editor-activiteit"
+
+#: views/editors/summary.thtml:45
+msgid "editorcp_summary_totalreviews_heading"
+msgstr "Totaal aantal beoordelingen"
+
+#: controllers/editors_controller.php:248
+#: controllers/editors_controller.php:249
+msgid "editors_addon_review_pagetitle"
+msgstr "Add-on beoordelen"
+
+#: controllers/editors_controller.php:349
+msgid "editors_error_js-formerror"
+msgstr "Vul a.u.b. de volgende velden in:"
+
+#: controllers/editors_controller.php:350
+msgid "editors_error_review_one_file"
+msgstr "Selecteer a.u.b. ten minste één te beoordelen bestand."
+
+#: controllers/editors_controller.php:274
+msgid "editors_error_self_reviews_forbidden"
+msgstr "Zelfbeoordelingen zijn niet toegestaan."
+
+#: controllers/editors_controller.php:699
+msgid "editors_external_software"
+msgstr "Externe software"
+
+#: views/editors/featured.thtml:120 views/editors/featured.thtml:121
+msgid "editors_featured_add_feature"
+msgstr "Aanbeveling toevoegen"
+
+#: views/editors/featured.thtml:126
+msgid "editors_featured_add_feature_submit"
+msgstr "Toevoegen"
+
+#: views/editors/featured.thtml:49 controllers/editors_controller.php:832
+#: controllers/editors_controller.php:848
+msgid "editors_featured_addon_add_failure"
+msgstr "Toevoegen van aanbeveling mislukt."
+
+#: controllers/editors_controller.php:851
+msgid "editors_featured_addon_add_success"
+msgstr "Toevoegen van aanbeveling geslaagd."
+
+#: views/editors/featured.thtml:50 controllers/editors_controller.php:839
+#: controllers/editors_controller.php:868
+#: controllers/editors_controller.php:886
+msgid "editors_featured_addon_edit_failure"
+msgstr "Bewerken van aanbeveling mislukt."
+
+#: views/editors/featured.thtml:51 controllers/editors_controller.php:888
+msgid "editors_featured_addon_edit_success"
+msgstr "Bewerken van aanbeveling geslaagd."
+
+#: views/editors/featured.thtml:53 controllers/editors_controller.php:861
+msgid "editors_featured_addon_invalid_locale"
+msgstr "Eén of meer locales zijn ongeldig."
+
+#: views/editors/featured.thtml:52 controllers/editors_controller.php:906
+msgid "editors_featured_addon_remove_failure"
+msgstr "Verwijderen van aanbeveling mislukt."
+
+#: controllers/editors_controller.php:901
+msgid "editors_featured_addon_remove_success"
+msgstr "Verwijderen van aanbeveling gelukt."
+
+#: controllers/editors_controller.php:915
+#: controllers/editors_controller.php:917
+msgid "editors_featured_addons_pagetitle"
+msgstr "Aanbevolen add-ons"
+
+#: views/editors/featured.thtml:54 views/editors/featured.thtml:107
+msgid "editors_featured_edit_feature_submit"
+msgstr "OK"
+
+#: views/editors/featured.thtml:90 views/editors/featured.thtml:91
+msgid "editors_featured_remove_feature"
+msgstr "Aanbeveling verwijderen"
+
+#: views/editors/queue.thtml:46
+msgid "editors_filter_queue"
+msgstr "Filterrij"
+
+#: views/editors/queue.thtml:182
+msgid "editors_helpful_links"
+msgstr "Nuttige koppelingen"
+
+#: views/editors/queue.thtml:182
+msgid "editors_link_guide"
+msgstr "Handboek voor de editor"
+
+#: views/editors/queue.thtml:182
+msgid "editors_link_policy"
+msgstr "Add-onbeleid"
+
+#: views/editors/queue.thtml:47
+msgid "editors_notice_filter_session"
+msgstr ""
+"Deze filters zullen gedurende deze sessie toegepast blijven, tenzij ze "
+"worden gewist."
+
+#. %1 is the queue mode
+#: views/editors/queue.thtml:177 views/admin/flagged_queue.thtml:89
+msgid "editors_notice_none_found"
+msgstr "Er zijn momenteel geen add-ons uit %s te beoordelen."
+
+#: controllers/editors_controller.php:1040
+msgid "editors_one_day"
+msgstr "het laatste etmaal"
+
+#: controllers/editors_controller.php:1048
+msgid "editors_one_hour"
+msgstr "het laatste uur"
+
+#: controllers/editors_controller.php:1056
+msgid "editors_one_minute"
+msgstr "de laatste minuut"
+
+#: controllers/editors_controller.php:64 controllers/editors_controller.php:73
+#: controllers/editors_controller.php:77
+msgid "editors_pagetitle"
+msgstr "Editor controlevenster"
+
+#. %s is a comma separated list of platforms. Example: Windows, OS X
+#: controllers/editors_controller.php:680
+#: controllers/editors_controller.php:683
+#, php-format
+msgid "editors_platform_x_only"
+msgstr "Alleen %s"
+
+#: controllers/editors_controller.php:695
+msgid "editors_pre-release"
+msgstr "Pre-release"
+
+#. %1 is the app name
+#: views/editors/queue.thtml:131
+#, php-format
+msgid "editors_queue_app_compatibility"
+msgstr "%s compatibiliteit"
+
+#: views/editors/queue.thtml:51
+msgid "editors_queue_filter_label_addon"
+msgstr "Add-on of e-mailadres schrijver"
+
+#: views/editors/queue.thtml:72
+msgid "editors_queue_filter_label_addontypes"
+msgstr "Add-ontypes"
+
+#: views/editors/queue.thtml:56
+msgid "editors_queue_filter_label_application"
+msgstr "Toepassing"
+
+#: views/editors/queue.thtml:61
+msgid "editors_queue_filter_label_maxversion"
+msgstr "Max. versie"
+
+#: views/editors/queue.thtml:78
+msgid "editors_queue_filter_label_platforms"
+msgstr "Platforms"
+
+#: views/editors/queue.thtml:66
+msgid "editors_queue_filter_label_submissionage"
+msgstr "Leeftijd van indiening (dagen)"
+
+#. %1$s is a number
+#: views/editors/queue.thtml:90
+msgid "editors_queue_filter_result_count"
+msgid_plural "editors_queue_filter_result_count"
+msgstr[0] ""
+"Resultaten van uw gefilterde zoekopdracht: <strong>%1$s</strong> add-on"
+msgstr[1] ""
+"Resultaten van uw gefilterde zoekopdracht: <strong>%1$s</strong> add-ons"
+
+#: views/editors/queue.thtml:84
+msgid "editors_queue_submit_clean"
+msgstr "Wissen"
+
+#: views/editors/queue.thtml:83
+msgid "editors_queue_submit_filter"
+msgstr "Filteren"
+
+#: controllers/editors_controller.php:133
+msgid "editors_queues_disabled"
+msgstr ""
+"Alle beoordelingsrijen zijn momenteel uitgeschakeld. Probeer het later nog "
+"eens."
+
+#: views/editors/review.thtml:149
+msgid "editors_review_a_edit_item"
+msgstr "Onderdeel bewerken"
+
+#: views/editors/review.thtml:146
+msgid "editors_review_a_item_history"
+msgstr "Onderdeelgeschiedenis"
+
+#: views/editors/review.thtml:148
+msgid "editors_review_a_item_homepage"
+msgstr "Onderdeelstartpagina"
+
+#: views/editors/review.thtml:145
+msgid "editors_review_a_item_overview"
+msgstr "Itemoverzicht"
+
+#: views/editors/review.thtml:147
+msgid "editors_review_a_previews"
+msgstr "Voorbeeldweergaven"
+
+#: controllers/editors_controller.php:345
+msgid "editors_review_action"
+msgstr "Actie beoordelen"
+
+#: views/editors/review.thtml:159
+msgid "editors_review_action_info"
+msgstr "Meer informatie aanvragen"
+
+#: views/editors/review.thtml:157
+msgid "editors_review_action_public"
+msgstr "Naar publieke site doorzetten"
+
+#: views/editors/review.thtml:160
+msgid "editors_review_action_request_superreview"
+msgstr "Super-beoordeling aanvragen"
+
+#: views/editors/review.thtml:158
+msgid "editors_review_action_sandbox"
+msgstr "In sandbox houden"
+
+#: controllers/editors_controller.php:346
+msgid "editors_review_comments"
+msgstr "Opmerkingen beoordelen"
+
+#: views/editors/review.thtml:182
+msgid "editors_review_details_info_request"
+msgstr ""
+"Gebruik dit formulier om meer informatie aan de schrijver te vragen. Deze "
+"ontvangt een e-mailbericht en kan hier antwoorden. U krijgt een e-"
+"mailbericht wanneer de schrijver antwoordt."
+
+#: views/editors/review.thtml:174
+msgid "editors_review_details_nominated_public"
+msgstr ""
+"Dit zal de add-on en de meest recente versie en bestanden als publiek "
+"markeren. Toekomstige versies zullen in de sandbox worden geplaatst totdat "
+"ze zijn beoordeeld door een editor."
+
+#: views/editors/review.thtml:177
+msgid "editors_review_details_nominated_sandbox"
+msgstr "Dit zal de add-on in de sandbox houden."
+
+#: views/editors/review.thtml:166
+msgid "editors_review_details_pending_public"
+msgstr ""
+"Dit zorgt ervoor dat een versie in de sandbox van een publieke add-on op de "
+"publieke site verschijnt."
+
+#: views/editors/review.thtml:169
+msgid "editors_review_details_pending_sandbox"
+msgstr ""
+"Dit zorgt ervoor dat een versie in de sandbox van een publieke add-on in de "
+"sandbox blijft."
+
+#: views/editors/review.thtml:185
+msgid "editors_review_details_superreview"
+msgstr ""
+"Als u twijfels hebt bij de beveiliging van een add-on, vraagtekens over "
+"auteursrecht, of andere twijfels die door een beheerder moeten worden "
+"bekeken, vul dan uw opmerkingen in onderstaand veld in. Deze worden gestuurd "
+"naar de beheerders, niet naar de schrijver."
+
+#: views/editors/review.thtml:134
+msgid "editors_review_file_diff_link"
+msgstr "Vergelijken met publieke versie"
+
+#: views/editors/review.thtml:131
+msgid "editors_review_file_viewcontents_link"
+msgstr "Inhoud bekijken"
+
+#: views/editors/review.thtml:65
+msgid "editors_review_header_authors"
+msgstr "Schrijvers:"
+
+#: views/editors/review.thtml:79
+msgid "editors_review_header_categories"
+msgstr "Categorieën:"
+
+#: views/editors/review.thtml:92
+msgid "editors_review_header_compatibility"
+msgstr "Compatibiliteit:"
+
+#: views/editors/review.thtml:251
+msgid "editors_review_header_description"
+msgstr "Beschrijving"
+
+#: views/editors/review.thtml:275
+msgid "editors_review_header_devcomments"
+msgstr "Opmerkingen van de ontwikkelaar"
+
+#: views/editors/review.thtml:263
+msgid "editors_review_header_eula"
+msgstr "EULA"
+
+#: views/editors/review.thtml:115
+msgid "editors_review_header_files"
+msgstr "Bestanden:"
+
+#: views/editors/review.thtml:284
+msgid "editors_review_header_itemhistory"
+msgstr "Geschiedenis"
+
+#: views/editors/review.thtml:232
+msgid "editors_review_header_nominationmessage"
+msgstr "Voordrachtsbericht"
+
+#: views/editors/review.thtml:311
+msgid "editors_review_header_previews"
+msgstr "Voorbeeldweergave"
+
+#: views/editors/review.thtml:269
+msgid "editors_review_header_privacy"
+msgstr "Privacybeleid"
+
+#. %1 is the add-on name and version
+#: views/editors/review.thtml:56
+#, php-format
+msgid "editors_review_header_review"
+msgstr "Beoordeling %s"
+
+#: views/editors/review.thtml:239
+msgid "editors_review_header_reviewernotes"
+msgstr "Opmerkingen voor de beoordelaar"
+
+#: views/editors/review.thtml:245
+msgid "editors_review_header_summary"
+msgstr "Samenvatting"
+
+#: views/editors/review.thtml:257
+msgid "editors_review_header_versionnotes"
+msgstr "Versieopmerkingen"
+
+#. a noun: shown in an add-on's editor review history
+#: views/elements/developers/editors_review_history_item.thtml:80
+msgid "editors_review_history_info_reply"
+msgstr "Antwoord"
+
+#: views/elements/developers/editors_review_history_item.thtml:78
+msgid "editors_review_history_info_request"
+msgstr "Informatieaanvraag"
+
+#: views/elements/developers/editors_review_history_item.thtml:62
+#: views/editors/reviewlog.thtml:77
+msgid "editors_review_history_nominated_adminreview"
+msgstr "Beoordeling door beheerder"
+
+#: views/elements/developers/editors_review_history_item.thtml:56
+#: views/editors/reviewlog.thtml:71
+msgid "editors_review_history_nominated_approved"
+msgstr "Voordracht goedgekeurd/Publiek"
+
+#: views/elements/developers/editors_review_history_item.thtml:59
+#: views/editors/reviewlog.thtml:74
+msgid "editors_review_history_nominated_denied"
+msgstr "Voordracht afgewezen/Sandbox"
+
+#: views/editors/review.thtml:303
+msgid "editors_review_history_nonefound"
+msgstr "Er zijn geen voorgaande beoordelingsingaven gevonden."
+
+#: views/elements/developers/editors_review_history_item.thtml:73
+#: views/editors/reviewlog.thtml:88
+msgid "editors_review_history_pending_adminreview"
+msgstr "Beoordeling door beheerder"
+
+#: views/elements/developers/editors_review_history_item.thtml:67
+#: views/editors/reviewlog.thtml:82
+msgid "editors_review_history_pending_approved"
+msgstr "Goedgekeurd/Publiek"
+
+#: views/elements/developers/editors_review_history_item.thtml:70
+#: views/editors/reviewlog.thtml:85
+msgid "editors_review_history_pending_denied"
+msgstr "Afgewezen/Sandbox"
+
+#. link text in an add-on's editor review history, allowing to hide and show an information request's replies
+#. %1 is the number of replies
+#: views/elements/developers/editors_review_history_item.thtml:90
+msgid "editors_review_history_show_hide_replies"
+msgid_plural "editors_review_history_show_hide_replies"
+msgstr[0] "Antwoord weergeven/verbergen"
+msgstr[1] "Antwoorden (%1$s) weergeven/verbergen"
+
+#: views/editors/review.thtml:208
+msgid "editors_review_label_applications"
+msgstr "Toepassingen:"
+
+#: views/editors/review.thtml:196
+msgid "editors_review_label_cannedresponse"
+msgstr "of selecteer een voorgedefinieerd antwoord:"
+
+#: views/editors/review.thtml:190
+msgid "editors_review_label_comments"
+msgstr "Opmerkingen:"
+
+#: views/editors/review.thtml:204
+msgid "editors_review_label_operating_systems"
+msgstr "Besturingssystemen:"
+
+#: views/editors/review.thtml:285 views/editors/review.thtml:312
+msgid "editors_review_link_pagetop"
+msgstr "Bovenzijde"
+
+#: views/editors/review.thtml:141
+msgid "editors_review_mulitple_notice"
+msgstr ""
+"Noot: beoordeel slechts meerdere bestanden indien u ELK bestand dat u "
+"selecteert hebt getest."
+
+#: views/editors/review.thtml:51
+msgid "editors_review_next_link"
+msgstr "volgende &raquo;"
+
+#: views/editors/review.thtml:322
+msgid "editors_review_previews_notfound"
+msgstr "Geen voorbeeldweergaven gevonden."
+
+#: views/editors/review.thtml:50
+msgid "editors_review_previous_link"
+msgstr "&laquo; vorige"
+
+#: controllers/editors_controller.php:144
+#: controllers/editors_controller.php:146
+msgid "editors_review_queue_pagetitle"
+msgstr "Wachtrij van beoordelingen"
+
+#. %1 is the add-ons rank in the queue, %2 is the total queue length
+#: views/editors/review.thtml:47
+msgid "editors_review_rank_in_queue"
+msgstr "<strong>nr. %1$s</strong> van %2$s in wachtrij"
+
+#. %1 is the add-ons rank in the queue, %2 is the total queue length. Both numbers
+#: views/editors/review.thtml:45
+msgid "editors_review_rank_in_queue_filtered"
+msgstr "<strong># %1$s</strong> van %2$s in de wachtrij (gefilterd)"
+
+#: views/editors/review.thtml:223
+msgid "editors_review_submit_process_action"
+msgstr "Actie afhandelen"
+
+#: views/editors/review.thtml:293
+msgid "editors_review_th_action"
+msgstr "Actie"
+
+#: views/editors/review.thtml:294
+msgid "editors_review_th_comments"
+msgstr "Opmerkingen"
+
+#: views/editors/review.thtml:291
+msgid "editors_review_th_date"
+msgstr "Datum"
+
+#: views/editors/review.thtml:292
+msgid "editors_review_th_reviewer"
+msgstr "Beoordelaar"
+
+#: views/editors/review.thtml:290
+msgid "editors_review_th_version_file"
+msgstr "Versie/Bestand"
+
+#: views/editors/review.thtml:217
+msgid "editors_review_update_notify_once"
+msgstr ""
+"Geef mij de volgende keer dat deze add-on wordt bijgewerkt bericht. "
+"(Daaropvolgende updates zullen geen e-mailbericht aanmaken)"
+
+#: controllers/editors_controller.php:298
+msgid "editors_reviewed_successfully"
+msgstr "Beoordeling succesvol afgehandeld."
+
+#: views/editors/reviews_queue.thtml:106
+msgid "editors_reviews_action_delete_review"
+msgstr "Beoordeling verwijderen"
+
+#: views/editors/reviews_queue.thtml:104
+msgid "editors_reviews_action_keep"
+msgstr "Aanduidingen verwijderen; beoordeling behouden"
+
+#: views/editors/reviews_queue.thtml:102
+msgid "editors_reviews_action_skip"
+msgstr "Overslaan"
+
+#: views/editors/reviews_queue.thtml:100
+msgid "editors_reviews_header_action"
+msgstr "Actie"
+
+#: views/editors/reviews_queue.thtml:67
+msgid "editors_reviews_in_reply_to"
+msgstr "In antwoord op:"
+
+#: controllers/editors_controller.php:748
+msgid "editors_reviews_processed"
+msgstr "Beoordelingen succesvol afgehandeld!"
+
+#: views/editors/reviews_queue.thtml:117
+msgid "editors_reviews_queue_empty"
+msgstr "Er zijn momenteel geen te screenen beoordelingen."
+
+#: views/editors/reviews_queue.thtml:111
+msgid "editors_reviews_submit_process_reviews"
+msgstr "Beoordelingen afhandelen"
+
+#: controllers/editors_controller.php:691
+msgid "editors_site_specific"
+msgstr "Site-specifiek"
+
+#: controllers/editors_controller.php:348
+msgid "editors_tested_app"
+msgstr "Geteste toepassing"
+
+#: controllers/editors_controller.php:347
+msgid "editors_tested_os"
+msgstr "Geteste besturingssystemen"
+
+#: views/editors/queue.thtml:151
+msgid "editors_th_additional_info"
+msgstr "Aanvullende informatie"
+
+#: views/editors/featured.thtml:63 views/editors/queue.thtml:109
+#: views/admin/flagged_queue.thtml:53
+msgid "editors_th_addon"
+msgstr "Add-on"
+
+#: views/editors/queue.thtml:125
+msgid "editors_th_addontype"
+msgstr "Type"
+
+#: views/editors/featured.thtml:64
+msgid "editors_th_locales"
+msgstr "Beperken tot locales?"
+
+#: views/editors/queue.thtml:148
+msgid "editors_th_nomination_age"
+msgstr "Tijd in de wachtrij"
+
+#: views/editors/queue.thtml:101 views/editors/queue.thtml:117
+#: views/editors/queue.thtml:144
+msgid "editors_th_sort_ascending"
+msgstr "Oplopend gesorteerd"
+
+#: views/editors/queue.thtml:105 views/editors/queue.thtml:121
+#: views/editors/queue.thtml:140
+msgid "editors_th_sort_descending"
+msgstr "Aflopend gesorteerd"
+
+#. %s is a number
+#: controllers/editors_controller.php:1036
+#, php-format
+msgid "editors_x_days"
+msgstr "%s dagen"
+
+#. %s is a number
+#: controllers/editors_controller.php:1044
+#, php-format
+msgid "editors_x_hours"
+msgstr "%s uur"
+
+#. %s is a number
+#: controllers/editors_controller.php:1052
+#, php-format
+msgid "editors_x_minutes"
+msgstr "%s minuten"
+
+#: views/errors/error401.thtml:50 controllers/components/simple_acl.php:81
+#: controllers/components/simple_acl.php:82
+#: controllers/components/simple_acl.php:83 controllers/components/amo.php:607
+#: controllers/components/amo.php:608 controllers/components/amo.php:609
+#: controllers/reviews_controller.php:353
+#: controllers/reviews_controller.php:485
+#: controllers/collections_controller.php:438
+#: controllers/collections_controller.php:496
+#: controllers/collections_controller.php:504
+#: controllers/collections_controller.php:971
+#: controllers/collections_controller.php:1034
+#: controllers/collections_controller.php:1077
+msgid "error_access_denied"
+msgstr "Toegang geweigerd"
+
+#: views/errors/error401.thtml:52
+msgid "error_access_denied_message"
+msgstr "u hebt geen rechten om deze pagina te bekijken."
+
+#: controllers/collections_controller.php:1039
+msgid "error_addon_exists"
+msgstr "Add-on bestaat al!"
+
+#: controllers/developers_controller.php:200
+#: controllers/developers_controller.php:593
+#: controllers/developers_controller.php:1016
+#: controllers/developers_controller.php:1429
+#: controllers/downloads_controller.php:95
+#: controllers/downloads_controller.php:102
+#: controllers/downloads_controller.php:164
+#: controllers/statistics_controller.php:135
+#: controllers/previews_controller.php:115
+#: controllers/previews_controller.php:206
+#: controllers/previews_controller.php:307
+#: controllers/reviews_controller.php:77
+#: controllers/reviews_controller.php:240
+#: controllers/reviews_controller.php:332
+#: controllers/reviews_controller.php:340 controllers/api_controller.php:123
+#: controllers/api_controller.php:759 controllers/addons_controller.php:131
+#: controllers/addons_controller.php:197
+#: controllers/addons_controller.php:1407
+#: controllers/addons_controller.php:1465
+#: controllers/addons_controller.php:1469
+#: controllers/addons_controller.php:1503
+#: controllers/editors_controller.php:265
+#: controllers/collections_controller.php:1041
+#: controllers/collections_controller.php:1074
+msgid "error_addon_notfound"
+msgstr "Add-on niet gevonden!"
+
+#: controllers/files_controller.php:83 controllers/files_controller.php:196
+msgid "error_addon_notviewable"
+msgstr "Deze add-on kan hier niet worden bekeken."
+
+#: controllers/reviews_controller.php:246
+msgid "error_addon_selfreview"
+msgstr "U kunt uw eigen add-on niet beoordelen."
+
+#: controllers/addons_controller.php:970
+msgid "error_browse_no_addons"
+msgstr "Geen add-ons in deze categorie!"
+
+#: controllers/api_controller.php:424
+msgid "error_collection_feed_notfound"
+msgstr "Add-onfeed niet gevonden"
+
+#: views/users/register.thtml:65 views/users/edit.thtml:194
+msgid "error_email_invalid"
+msgstr "Dit is geen geldig e-mailadres."
+
+#: views/users/pwreset.thtml:74 views/users/register.thtml:70
+#: views/users/register.thtml:80 views/users/register.thtml:86
+#: views/users/edit.thtml:105 views/users/edit.thtml:111
+#: views/users/edit.thtml:192 views/admin/users_edit.thtml:78
+#: views/admin/users_edit.thtml:83 views/reviews/add.thtml:80
+#: views/reviews/add.thtml:104
+msgid "error_field_required"
+msgstr "Dit veld mag niet leeg zijn."
+
+#: controllers/files_controller.php:75 controllers/files_controller.php:93
+#: controllers/files_controller.php:96 controllers/files_controller.php:163
+#: controllers/files_controller.php:176 controllers/files_controller.php:185
+#: controllers/files_controller.php:204 controllers/editors_controller.php:412
+msgid "error_file_notfound"
+msgstr "Bestand niet gevonden!"
+
+#. %s is a filename
+#: controllers/editors_controller.php:430
+#, php-format
+msgid "error_file_x_notfound"
+msgstr "Bestandsfout: %s bestaat niet."
+
+#: views/collections/add.thtml:55 views/collections/edit.thtml:89
+#: views/users/register.thtml:54 views/users/edit.thtml:81
+#: views/reviews/add.thtml:70 controllers/groups_controller.php:80
+#: controllers/groups_controller.php:102
+msgid "error_formerrors"
+msgstr ""
+"Er staan fouten in dit formulier. Corrigeer ze a.u.b. en dien het formulier "
+"opnieuw in."
+
+#: views/users/register.thtml:109
+msgid "error_invalid_captcha"
+msgstr "Ongeldige captcha, probeer het a.u.b. opnieuw!"
+
+#: views/users/register.thtml:100 views/users/edit.thtml:125
+#: views/admin/users_edit.thtml:101
+msgid "error_invalid_url"
+msgstr ""
+"Deze URL heeft een ongeldige opmaak. Geldige URL’s lijken op http://"
+"voorbeeld.com/mijn_pagina."
+
+#. %s is a string representing what's missing. Example: file_id
+#: controllers/downloads_controller.php:65
+#: controllers/users_controller.php:185 controllers/users_controller.php:264
+#: controllers/users_controller.php:559 controllers/users_controller.php:653
+#: controllers/reviews_controller.php:71
+#: controllers/reviews_controller.php:234
+#: controllers/reviews_controller.php:325
+#: controllers/reviews_controller.php:473
+#: controllers/reviews_controller.php:475
+#: controllers/addons_controller.php:182
+#: controllers/addons_controller.php:1381
+#: controllers/addons_controller.php:1455
+#: controllers/collections_controller.php:266
+#: controllers/collections_controller.php:285
+#: controllers/collections_controller.php:346
+#: controllers/collections_controller.php:443
+#: controllers/collections_controller.php:482
+#: controllers/collections_controller.php:936
+#: controllers/collections_controller.php:959
+#: controllers/collections_controller.php:960
+#: controllers/collections_controller.php:975
+#: controllers/collections_controller.php:977
+#: controllers/collections_controller.php:994
+#: controllers/collections_controller.php:1003
+#: controllers/collections_controller.php:1016
+#: controllers/collections_controller.php:1017
+#: controllers/collections_controller.php:1024
+#: controllers/collections_controller.php:1070
+#: controllers/collections_controller.php:1090
+#, php-format
+msgid "error_missing_argument"
+msgstr "Ontbrekend argument: %s"
+
+#: controllers/components/amo.php:507 controllers/components/amo.php:532
+msgid "error_no_files_in_addon"
+msgstr "Geen bestanden"
+
+#: controllers/previews_controller.php:200
+msgid "error_preview_notfound"
+msgstr "Voorbeeldweergave niet gevonden!"
+
+#: views/addons/display.thtml:400 views/reviews/add.thtml:98
+msgid "error_review_rating_required"
+msgstr "U dient een waardering te selecteren."
+
+#: controllers/users_controller.php:160
+msgid "error_user_already_confirmed"
+msgstr "Deze gebruikersaccount is al bevestigd."
+
+#: controllers/users_controller.php:202 controllers/users_controller.php:276
+#: controllers/users_controller.php:569 controllers/users_controller.php:581
+#: controllers/users_controller.php:587 controllers/users_controller.php:610
+#: controllers/users_controller.php:627
+msgid "error_user_badconfirmationcode"
+msgstr "Ongeldige bevestigingscode!"
+
+#: views/users/pwreset.thtml:79 views/users/register.thtml:75
+#: views/users/edit.thtml:183
+msgid "error_user_confirmpw_nomatch"
+msgstr "De wachtwoorden komen niet overeen."
+
+#: views/users/register.thtml:65 views/users/edit.thtml:190
+#: controllers/users_controller.php:617
+msgid "error_user_email_notunique"
+msgstr "Dit e-mailadres is al in gebruik door een andere gebruiker."
+
+#: controllers/users_controller.php:596
+msgid "error_user_emailchange_expired"
+msgstr ""
+"De wijziging van het e-mailadres is verlopen. Wijzig a.u.b. uw e-mailadres "
+"opnieuw in uw gebruikersprofiel en klik op de koppeling in het "
+"bevestigingsbericht zodra u dat ontvangt."
+
+#: controllers/collections_controller.php:985
+msgid "error_user_exists"
+msgstr ""
+"Gebruikers kunnen slechts één rol tegelijk hebben. Verwijder a.u.b. de "
+"gebruiker uit reeds bestaande rollen voordat u verder gaat."
+
+#: views/users/register.thtml:91 views/users/edit.thtml:116
+#: views/admin/users_edit.thtml:88
+msgid "error_user_nickname_notunique"
+msgstr "Deze nickname is al in gebruik."
+
+#: views/users/pwreset.thtml:54 controllers/users_controller.php:191
+#: controllers/users_controller.php:270 controllers/users_controller.php:603
+#: controllers/users_controller.php:659
+#: controllers/collections_controller.php:988
+#: controllers/collections_controller.php:998
+msgid "error_user_notfound"
+msgstr "Gebruiker niet gevonden!"
+
+#: views/users/activatefirst.thtml:47
+msgid "error_user_unconfirmed"
+msgstr ""
+"Bevestig a.u.b. eerst uw gebruikersaccount met de code die u per e-mail hebt "
+"ontvangen."
+
+#: views/users/login.thtml:67
+msgid "error_username_or_pw_wrong"
+msgstr "Foutieve gebruikersnaam of wachtwoord!"
+
+#: controllers/editors_controller.php:260
+msgid "error_version_notfound"
+msgstr "Versie niet gevonden!"
+
+#: views/users/delete.thtml:125 views/users/edit.thtml:173
+msgid "error_wrong_password"
+msgstr "Foutief wachtwoord ingegeven!"
+
+#: views/elements/amo2009/homepage_addon.thtml:122
+#: views/elements/feature.thtml:122
+msgid "feature_learnmore"
+msgstr "Meer hierover"
+
+#. %1 is the add-on name
+#: views/elements/amo2009/homepage_addon.thtml:123
+#: views/elements/feature.thtml:123
+#, php-format
+msgid "feature_learnmore_about_addon"
+msgstr "Meer over %1$s"
+
+#. %1$s is a number
+#: views/elements/amo2009/reviews.thtml:52
+#: views/elements/addon_listitem.thtml:112 views/elements/feature.thtml:99
+#: views/addons/browse_thumbs.thtml:86
+#, php-format
+msgid "feature_reviews"
+msgid_plural "feature_reviews"
+msgstr[0] "%1$s beoordeling"
+msgstr[1] "%1$s beoordelingen"
+
+#: views/elements/amo2009/homepage_addon.thtml:127
+#: views/elements/feature.thtml:127
+msgid "feature_view_more_from_category"
+msgstr "Meer bekijken van"
+
+#. This appears on a page that views the source of an add-on. This link will return
+#. the user to the add-on's main page
+#: views/files/browse.thtml:65
+msgid "file_browser_link_addon"
+msgstr "Terug naar add-on"
+
+#. There is a list of directories and files on the page. Clicking this will show the
+#. contents of all the directories (normally you would click on each one to see the
+#. contents)
+#: views/files/browse.thtml:67
+msgid "file_browser_link_expand_all"
+msgstr "Alles uitklappen"
+
+#. This appears on a page that views the source of an add-on. This link will return
+#. the user to the add-on's review page (it only appears if the add-on is being
+#. reviewed)
+#: views/files/browse.thtml:64
+msgid "file_browser_link_review"
+msgstr "Terug naar beoordeling"
+
+#. The title of the page for viewing an add-on's source.
+#. %1$s is the name of the add-on
+#. %2$s is the name of the current application (e.g. Firefox or Thunderbird)
+#: views/files/browse.thtml:46
+msgid "file_browser_title"
+msgstr "%1$s :: Bestand zoeken :: %2$s Add-ons"
+
+#. This appears on a page that views the source of an add-on. There is a list of
+#. directories and files on the page. Clicking this link will toggle between an
+#. expanded or a collapsed list. This string should be kept short.
+#: views/files/browse.thtml:68
+msgid "file_browser_toggle_expand_collapse"
+msgstr "+/-"
+
+#. Link text for the AMO About page.
+#: views/elements/footer.thtml:72 views/layouts/amo2009.thtml:341
+msgid "footer_a_about"
+msgstr "Over"
+
+#. Link text to the AMO blog.
+#: views/elements/footer.thtml:74 views/layouts/amo2009.thtml:343
+msgid "footer_a_blog"
+msgstr "Blog"
+
+#. Link text to the Frequently Asked Questions page.
+#: views/elements/footer.thtml:73 views/layouts/amo2009.thtml:342
+msgid "footer_a_faq"
+msgstr "FAQ"
+
+#. Full text for the FAQ abbreviation.
+#: views/elements/footer.thtml:73 views/pages/collector_features.thtml:72
+#: views/layouts/amo2009.thtml:342
+msgid "footer_abbr_faq"
+msgstr "Veelgestelde vragen"
+
+#: views/elements/footer.thtml:67 views/layouts/amo2009.thtml:336
+msgid "footer_all_rights_reserved"
+msgstr "Alle rechten voorbehouden."
+
+#: views/elements/footer.thtml:67 views/layouts/amo2009.thtml:336
+msgid "footer_copyright"
+msgstr "Copyright"
+
+#: views/elements/footer.thtml:71 views/layouts/amo2009.thtml:340
+msgid "footer_credits"
+msgstr "Dankbetuiging"
+
+#: views/elements/footer.thtml:76 views/layouts/amo2009.thtml:346
+msgid "footer_disclaimer"
+msgstr ""
+"Mozilla verstrekt koppelingen naar deze toepassingen als service, en staat "
+"niet in voor de toepassingen of daaraan gerelateerde informatie. Vragen, "
+"klachten of claims met betrekking tot de toepassingen dienen gericht te "
+"worden aan de desbetreffende softwareverstrekker."
+
+#: views/elements/footer.thtml:61 views/layouts/amo2009.thtml:332
+msgid "footer_lang_form_lang_submit_go"
+msgstr "Indienen"
+
+#: views/elements/footer.thtml:70 views/layouts/amo2009.thtml:339
+msgid "footer_legal_notices"
+msgstr "Juridische opmerkingen"
+
+#: views/elements/footer.thtml:50 views/layouts/amo2009.thtml:321
+msgid "footer_other_languages"
+msgstr "Overige talen:"
+
+#: views/elements/footer.thtml:69 views/layouts/amo2009.thtml:338
+msgid "footer_privacy_policy"
+msgstr "Privacybeleid"
+
+#: models/addontype.php:79
+msgid "general_addontype_dict"
+msgstr "Woordenboek"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:100
+msgid "general_addontype_dict_plural"
+msgstr "Woordenboeken"
+
+#: models/addontype.php:75
+msgid "general_addontype_extension"
+msgstr "Extensie"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:98
+msgid "general_addontype_extension_plural"
+msgstr "Extensies"
+
+#: models/addontype.php:85
+msgid "general_addontype_lpaddon"
+msgstr "Taalpakket (Add-on)"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:103
+msgid "general_addontype_lpaddon_plural"
+msgstr "Taalpakketten (Add-on)"
+
+#: models/addontype.php:83
+msgid "general_addontype_lpapp"
+msgstr "Taalpakket (Toepassing)"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:102
+msgid "general_addontype_lpapp_plural"
+msgstr "Taalpakketten (Toepassing)"
+
+#: models/addontype.php:87
+msgid "general_addontype_plugin"
+msgstr "Plug-in"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:104
+msgid "general_addontype_plugin_plural"
+msgstr "Plug-ins"
+
+#: models/addontype.php:81
+msgid "general_addontype_search"
+msgstr "Zoekmachine"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:101
+msgid "general_addontype_search_plural"
+msgstr "Zoekmachines"
+
+#: models/addontype.php:77
+msgid "general_addontype_theme"
+msgstr "Thema"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:99
+msgid "general_addontype_theme_plural"
+msgstr "Thema's"
+
+#: config/language.php:367
+msgid "general_languages_all_locales"
+msgstr "Alle locales"
+
+#: views/layouts/amo2009.thtml:249
+msgid "header_brand_name"
+msgstr "Mozilla"
+
+#. %1$s is the application name. Example: Firefox
+#: views/elements/header.thtml:111 views/elements/header.thtml:122
+#: views/layouts/amo2009.thtml:248
+#, php-format
+msgid "header_home_tooltip"
+msgstr "Terug naar de %1$s Add-ons startpagina"
+
+#: views/elements/header.thtml:87
+msgid "header_main_firefox_header"
+msgstr "Firefox Add-ons"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:218
+msgid "header_main_firefox_header_with_logo"
+msgstr ""
+"Add-ons <em>voor</em> <img alt=\"Firefox\" src=\"%1$s\" /> <strong>Firefox</"
+"strong>"
+
+#: views/elements/header.thtml:99
+msgid "header_main_header"
+msgstr "Add-ons"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:242
+msgid "header_main_header_with_logo"
+msgstr "Add-ons <img alt=\"Add-ons\" src=\"%1$s\" />"
+
+#: views/elements/header.thtml:90
+msgid "header_main_seamonkey_header"
+msgstr "Seamonkey Add-ons"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:224
+msgid "header_main_seamonkey_header_with_logo"
+msgstr ""
+"Add-ons <em>voor</em> <img alt=\"seamonkey\" src=\"%1$s\" /> "
+"<strong>SeaMonkey</strong>"
+
+#: views/elements/header.thtml:93
+msgid "header_main_sunbird_header"
+msgstr "Sunbird Add-ons"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:230
+msgid "header_main_sunbird_header_with_logo"
+msgstr ""
+"Add-ons <em>voor</em> <img alt=\"sunbird\" src=\"%1$s\" /> <strong>Sunbird</"
+"strong>"
+
+#: views/elements/header.thtml:96
+msgid "header_main_thunderbird_header"
+msgstr "Thunderbird Add-ons"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:236
+msgid "header_main_thunderbird_header_with_logo"
+msgstr ""
+"Add-ons <em>voor</em> <img alt=\"thunderbird\" src=\"%1$s\" /> "
+"<strong>Thunderbird</strong>"
+
+#: views/layouts/amo2009.thtml:205
+msgid "header_navaccess_applications_menu"
+msgstr "Naar menu Overige toepassingen"
+
+#: views/layouts/amo2009.thtml:204
+msgid "header_navaccess_categories_menu"
+msgstr "Naar menu Categorieën"
+
+#: views/layouts/amo2009.thtml:202
+msgid "header_navaccess_main_content"
+msgstr "Naar hoofdinhoud"
+
+#: views/layouts/amo2009.thtml:203
+msgid "header_navaccess_search_form"
+msgstr "Naar zoekformulier"
+
+#: views/elements/header.thtml:62
+msgid "header_navlink_addons"
+msgstr "Add-ons"
+
+#: views/elements/developers/sidebar.thtml:72
+#: views/elements/developers/myaddons.thtml:50 views/elements/header.thtml:159
+#: views/addons/display.thtml:378
+msgid "header_navlink_login"
+msgstr "Inloggen"
+
+#: views/elements/header.thtml:156 views/layouts/amo2009.thtml:304
+msgid "header_navlink_logout"
+msgstr "Uitloggen"
+
+#: views/elements/header.thtml:145 views/layouts/amo2009.thtml:303
+msgid "header_navlink_myaccount"
+msgstr "Mijn account"
+
+#: views/elements/header.thtml:158
+msgid "header_navlink_register"
+msgstr "Registreren"
+
+#. %1 is the URL to the registration page
+#. %2 is the URL to the login page
+#: views/layouts/amo2009.thtml:278
+msgid "header_navlink_register_or_login"
+msgstr "<a href=\"%1$s\">Registreer</a> of <a href=\"%2$s\">meld u aan</a>"
+
+#: views/layouts/amo2009.thtml:285
+msgid "header_navlink_tools"
+msgstr "Hulpmiddelen"
+
+#. %s is the add-on name
+#: views/elements/collections_interactive_addon.thtml:62
+#: views/elements/amo2009/homepage_addon.thtml:77
+#: views/elements/addon_discussionheader.thtml:62
+#: views/elements/addon_listitem.thtml:67 views/elements/feature.thtml:84
+#: views/addons/category_landing.thtml:87 views/addons/browse_thumbs.thtml:60
+#, php-format
+msgid "img_preview_of"
+msgstr "Voorbeeldweergave van %s"
+
+#. %1 is the login URL for the link tag
+#. %2 is the link to an explanatory page.
+#: views/elements/amo2009/install.thtml:307 views/elements/install.thtml:255
+msgid "install_a_login_to_install"
+msgstr ""
+"<a href=\"%1$s\">Log in</a> om deze add-on te installeren. <a href=\"%2$s"
+"\">Waarom</a>?"
+
+#. %1 is the URL for the Experimental Add-ons section of the FAQ page
+#: views/elements/amo2009/install.thtml:283 views/elements/install.thtml:232
+msgid "install_button_confirm_exp_install"
+msgstr ""
+"Laat mij deze experimentele add-on installeren. <a href=\"%1$s\">Wat is dit?"
+"</a>"
+
+#. %1$s is the application name. Example: Firefox
+#. %2$s is an optional string used to specify a platform. Example: (Windows)
+#: views/elements/amo2009/install.thtml:128 views/elements/install.thtml:75
+#, php-format
+msgid "install_button_text"
+msgstr "Aan %1$s %2$s toevoegen"
+
+#. %1 is the add-on name, %2 is the app name
+#: views/elements/amo2009/install.thtml:191
+#: views/elements/amo2009/install.thtml:206
+#: views/elements/amo2009/install.thtml:249
+#: views/elements/amo2009/install.thtml:298 views/elements/install.thtml:150
+#: views/elements/install.thtml:165 views/elements/install.thtml:202
+#: views/elements/install.thtml:246
+#, php-format
+msgid "install_button_title"
+msgstr "%1$s toevoegen aan %2$s"
+
+#. %1$s is the add-on name
+#: views/elements/amo2009/install.thtml:200 views/elements/install.thtml:159
+#, php-format
+msgid "install_download"
+msgstr "%1$s downloaden"
+
+#: views/elements/amo2009/install.thtml:147 views/elements/install.thtml:94
+msgid "install_error_addon_not_found"
+msgstr "Deze add-on is niet beschikbaar."
+
+#: views/addons/dictionaries.thtml:65
+msgid "langtools_a11y_tablesummary"
+msgstr "Lijst van taalpakketten en woordenboeken."
+
+#: views/addons/dictionaries.thtml:47
+msgid "langtools_download_dictionary"
+msgstr "Woordenboek downloaden"
+
+#: views/addons/dictionaries.thtml:48
+msgid "langtools_download_langpack"
+msgstr "Taalpakket downloaden"
+
+#: views/addons/dictionaries.thtml:63 controllers/components/amo.php:685
+#: controllers/addons_controller.php:1239
+msgid "langtools_header_dicts_and_langpacks"
+msgstr "Woordenboeken & Taalpakketten"
+
+#: views/addons/dictionaries.thtml:44
+msgid "langtools_install_dictionary"
+msgstr "Woordenboek installeren"
+
+#: views/addons/dictionaries.thtml:45
+msgid "langtools_install_langpack"
+msgstr "Taalpakket installeren"
+
+#: views/addons/dictionaries.thtml:69
+msgid "langtools_tableheader_dictionary"
+msgstr "Woordenboek"
+
+#: views/addons/dictionaries.thtml:70
+msgid "langtools_tableheader_langpack"
+msgstr "Taalpakket"
+
+#: views/addons/dictionaries.thtml:68
+msgid "langtools_tableheader_language"
+msgstr "Taal"
+
+#: models/license.php:65
+msgid "license_custom"
+msgstr "Aangepaste licentie"
+
+#: config/bootstrap.php:303
+msgid "licenses_bsd"
+msgstr "BSD-licentie"
+
+#: config/bootstrap.php:298
+msgid "licenses_gpl_2.0"
+msgstr "GNU General Public License, versie 2.0"
+
+#: config/bootstrap.php:299
+msgid "licenses_gpl_3.0"
+msgstr "GNU General Public License, versie 3.0"
+
+#: config/bootstrap.php:300
+msgid "licenses_lgpl_2.1"
+msgstr "GNU Lesser General Public License, versie 2.1"
+
+#: config/bootstrap.php:301
+msgid "licenses_lgpl_3.0"
+msgstr "GNU Lesser General Public License, versie 3.0"
+
+#: config/bootstrap.php:302
+msgid "licenses_mit"
+msgstr "MIT/X11-licentie"
+
+#: config/bootstrap.php:297
+msgid "licenses_mpl_1.1"
+msgstr "Mozilla Public License, versie 1.1"
+
+#: views/users/emailchange.thtml:51 views/users/delete.thtml:55
+#: views/users/delete.thtml:137 views/users/edit.thtml:74
+#: views/reviews/flag.thtml:54
+msgid "link_return_to_front_page"
+msgstr "Klik hier om terug te keren naar de beginpagina."
+
+#: views/elements/amo2009/addon_list_options.thtml:46
+#: views/elements/addon_list_options.thtml:46
+msgid "list_sortby_date"
+msgstr "Datum"
+
+#: views/elements/amo2009/addon_list_options.thtml:47
+#: views/elements/addon_list_options.thtml:47
+msgid "list_sortby_downloads"
+msgstr "Aantal downloads"
+
+#: views/elements/amo2009/addon_list_options.thtml:45
+#: views/elements/addon_list_options.thtml:45
+msgid "list_sortby_name"
+msgstr "Add-onnaam"
+
+#: views/elements/amo2009/addon_list_options.thtml:48
+#: views/elements/addon_list_options.thtml:48
+msgid "list_sortby_rating"
+msgstr "Beoordeling"
+
+#: config/bootstrap.php:278
+msgid "main_prettyname_fennec"
+msgstr "Fennec"
+
+#: config/bootstrap.php:274
+msgid "main_prettyname_firefox"
+msgstr "Firefox"
+
+#: config/bootstrap.php:277
+msgid "main_prettyname_seamonkey"
+msgstr "SeaMonkey"
+
+#: config/bootstrap.php:276
+msgid "main_prettyname_sunbird"
+msgstr "Sunbird"
+
+#: config/bootstrap.php:275
+msgid "main_prettyname_thunderbird"
+msgstr "Thunderbird"
+
+#: views/elements/addon_categories.thtml:52
+msgid "nav_category_dicts_langpacks"
+msgstr "Woordenboeken & Taalpakketten"
+
+#: views/elements/addon_categories.thtml:55
+msgid "nav_category_themes"
+msgstr "Thema’s"
+
+#: views/elements/app_chooser.thtml:47 views/layouts/amo2009.thtml:255
+msgid "other_apps_tooltip"
+msgstr "Add-ons voor andere toepassingen zoeken"
+
+#. In a user list: user 1, user 2, "others"
+#: views/helpers/addons_html.php:222
+msgid "other_users"
+msgstr "overige"
+
+#: controllers/pages_controller.php:90
+msgid "page_title_appversions"
+msgstr "Toepassingsversies"
+
+#: controllers/pages_controller.php:115
+msgid "page_title_collector"
+msgstr "Add-on Collector"
+
+#: controllers/pages_controller.php:117
+msgid "page_title_collector_faq"
+msgstr "Veelgestelde vragen over Add-on Collector"
+
+#: controllers/pages_controller.php:119
+msgid "page_title_collector_features"
+msgstr "Add-on Collectorfuncties"
+
+#: controllers/pages_controller.php:122
+msgid "page_title_collector_firstrun"
+msgstr "Welkom bij de Add-on Collector"
+
+#: controllers/pages_controller.php:92
+msgid "page_title_credits"
+msgstr "Dankzegging"
+
+#: controllers/pages_controller.php:113
+msgid "page_title_developer_faq"
+msgstr "Veelgestelde vragen voor ontwikkelaars"
+
+#: controllers/pages_controller.php:111
+msgid "page_title_faq"
+msgstr "Veelgestelde vragen"
+
+#: controllers/pages_controller.php:94
+msgid "page_title_fashionyourfirefox_faq"
+msgstr "Veelgestelde vragen over Pas uw Firefox aan"
+
+#: controllers/pages_controller.php:101
+msgid "page_title_policy"
+msgstr "Add-onsbeleid"
+
+#: controllers/pages_controller.php:103
+msgid "page_title_privacy"
+msgstr "Mozilla privacybeleid"
+
+#: controllers/pages_controller.php:105
+msgid "page_title_review_guide"
+msgstr "Beoordelingsrichtlijnen"
+
+#: controllers/pages_controller.php:107
+msgid "page_title_sandbox"
+msgstr "Sandbox-beoordelingssysteem"
+
+#: controllers/pages_controller.php:109
+msgid "page_title_submissionhelp"
+msgstr "Hulp bij indienen"
+
+#: views/pages/appversions.thtml:87
+msgid "pages_appversions_guid"
+msgstr "GUID"
+
+#: views/pages/appversions.thtml:79 controllers/pages_controller.php:90
+msgid "pages_appversions_header"
+msgstr "Geldige toepassingsversies"
+
+#: views/pages/appversions.thtml:80
+msgid "pages_appversions_intro"
+msgstr ""
+"Add-ons die worden ingediend bij Mozilla Add-ons dienen een install.rdf "
+"bestand te bevatten met ten minste één van de onderstaande ondersteunde "
+"toepassingen. Alleen de hieronder genoemde versies zijn toegestaan voor deze "
+"toepassingen."
+
+#. %s is a full <a> tag
+#: views/pages/appversions.thtml:93
+#, php-format
+msgid "pages_appversions_required_files"
+msgstr ""
+"Als uw ondersteunde toepassing geen install.rdf bestand nodig heeft, dient u "
+"er nog altijd een op te geven met de %s aangeduide specificaties."
+
+#. this is the text inside of an <a> tag for pages_appversions_required_files. This
+#. should be fixed.
+#: views/pages/appversions.thtml:93
+msgid "pages_appversions_required_files_link"
+msgstr "hier"
+
+#: views/pages/appversions.thtml:88
+msgid "pages_appversions_versions"
+msgstr "Versies"
+
+#: views/pages/policy.thtml:51
+msgid "pages_policy_sandbox_link"
+msgstr "Sandbox-informatiepagina"
+
+#: views/elements/pagination.thtml:53
+msgid "pagination_next_page"
+msgstr "volgende"
+
+#: views/elements/pagination.thtml:52
+msgid "pagination_previous_page"
+msgstr "voorgaande"
+
+#: views/elements/recaptcha.thtml:65
+msgid "recaptcha_enter_both_words"
+msgstr ""
+"Voer a.u.b. <strong>beide woorden</strong> hieronder in, <strong>gescheiden "
+"door een spatie</strong>."
+
+#: views/elements/recaptcha.thtml:83
+msgid "recaptcha_enter_here"
+msgstr "Voer hier uw antwoord in:"
+
+#: views/elements/recaptcha.thtml:74
+msgid "recaptcha_enter_whatyouhear"
+msgstr "Type a.u.b. wat u hoort."
+
+#. %1 is the link switching refreshing the captcha
+#. %2 is the link switching to a text captcha
+#: views/elements/recaptcha.thtml:77
+msgid "recaptcha_hardtohear_text"
+msgstr ""
+"Indien dit moeilijk te verstaan is kunt u <a href=\"%1$s\">naar iets anders "
+"luisteren</a> of <a href=\"%2$s\">terugschakelen naar tekst</a>."
+
+#. %1 is the link switching refreshing the captcha
+#. %2 is the link switching to an audio captcha
+#: views/elements/recaptcha.thtml:68
+msgid "recaptcha_hardtoread_text"
+msgstr ""
+"Indien dit moeilijk te lezen is kunt u <a href=\"%1$s\">andere woorden "
+"proberen</a> of <a href=\"%2$s\">naar iets luisteren</a>."
+
+#: views/users/register.thtml:105
+msgid "recaptcha_label"
+msgstr "Bent u menselijk?"
+
+#: views/users/register.thtml:106
+msgid "recaptcha_whatsthis"
+msgstr "Wat is dit?"
+
+#: controllers/reviews_controller.php:559
+msgid "review_flag_error"
+msgstr "Fout bij aanduiden van deze beoordeling!"
+
+#: models/reviews_moderation_flag.php:69
+msgid "review_flag_reason_bug_support"
+msgstr "Misplaatst foutrapport of ondersteuningsverzoek"
+
+#: views/reviews/display.thtml:103 views/reviews/display.thtml:186
+msgid "review_flag_reason_instructions"
+msgstr "Deze beoordeling rapporteren (selecteer een reden)"
+
+#: models/reviews_moderation_flag.php:67
+msgid "review_flag_reason_language"
+msgstr "Ongepast taalgebruik"
+
+#: models/reviews_moderation_flag.php:71
+msgid "review_flag_reason_other"
+msgstr "Overig (specificeren)"
+
+#: models/reviews_moderation_flag.php:65
+msgid "review_flag_reason_spam"
+msgstr "Spam of andere tekst niet zijnde beoordeling"
+
+#: views/reviews/display.thtml:91 views/reviews/display.thtml:175
+#: controllers/reviews_controller.php:555
+msgid "review_flag_success"
+msgstr ""
+"Bedankt; deze beoordeling is aangeduid voor goedkeuring door een editor."
+
+#: views/reviews/display.thtml:41
+msgid "review_flag_this"
+msgstr "Deze beoordeling rapporteren"
+
+#: views/reviews/display.thtml:42
+msgid "review_flag_this_titletip"
+msgstr ""
+"Is deze beoordeling ongepast, inaccuraat of spam? Klik dan hier om deze aan "
+"te duiden voor beoordeling door een editor."
+
+#. %1 is the URL of the support section, %2 for the review guidelines
+#: views/reviews/add.thtml:53
+msgid "review_guidelines_short"
+msgstr ""
+"<p>Houd de volgende tips in gedachten:</p><ul><li>Schrijf alsof u een vriend "
+"vertelt over uw ervaring met de add-on. Geef specifieke en behulpzame "
+"details, zoals welke functies u goed en/of minder goed vond, hoe eenvoudig "
+"de extensie in gebruik is, en nadelen die eraan verbonden zijn. Vermijd "
+"algemene termen zoals het bestempelen als “Geweldig†of “Slecht†tenzij u "
+"redenen kunt opgeven voor die mening.</li><li>Post a.u.b. geen foutrapporten "
+"in beoordelingen. We maken uw e-mailadres niet bekend aan ontwikkelaars van "
+"add-ons en ze willen wellicht contact met u opnemen om te helpen bij het "
+"oplossen van uw probleem. Kijk in de <a href=\"%1$s\">ondersteuningssectie</"
+"a> om te ontdekken waar u ondersteuning kunt krijgen voor de add-on.</"
+"li><li>Houd beoordelingen a.u.b. netjes, vermijd incorrect taalgebruik en "
+"post geen persoonlijke informatie.</li></ul><p>Lees a.u.b. de <a href=\"%2$s"
+"\">Beoordelingsrichtlijnen</a> voor meer details over add-onbeoordelingen "
+"door gebruikers.</p>"
+
+#. %1 is the add-on name
+#: views/reviews/flag.thtml:56 views/reviews/display.thtml:55
+#: views/reviews/review_added.thtml:50
+#, php-format
+msgid "reviews_header"
+msgstr "Beoordelingen voor %1$s"
+
+#: controllers/addons_controller.php:435
+msgid "rss_featuredaddons"
+msgstr "Aanbevolen add-ons"
+
+#: controllers/addons_controller.php:432
+msgid "rss_newestaddons"
+msgstr "Nieuwste add-ons"
+
+#: controllers/addons_controller.php:434
+msgid "rss_popularaddons"
+msgstr "Populaire add-ons"
+
+#: controllers/addons_controller.php:433
+msgid "rss_updatedaddons"
+msgstr "Bijgewerkte add-ons"
+
+#: views/elements/search_mini.thtml:70
+msgid "search"
+msgstr "Zoeken"
+
+#: views/search/collections.thtml:51
+msgid "search_collections_header"
+msgstr "Collectie-zoekresultaten"
+
+#: controllers/search_controller.php:297
+msgid "search_collections_pagetitle"
+msgstr "Collectie-zoekresultaten"
+
+#: controllers/search_controller.php:99
+msgid "search_disabled"
+msgstr ""
+"De zoekfunctie is momenteel uitgeschakeld. Probeer het later a.u.b. nog eens."
+
+#: views/elements/amo2009/search.thtml:188 views/elements/search.thtml:187
+#: views/elements/search_mini.thtml:54
+msgid "search_form_all_addons"
+msgstr "alle add-ons"
+
+#. This string is in the main category dropdown when searching
+#: views/elements/amo2009/search.thtml:204
+msgid "search_form_all_collections"
+msgstr "alle collecties"
+
+#: views/elements/amo2009/search.thtml:184
+#: views/elements/amo2009/search.thtml:385
+#: views/elements/amo2009/search.thtml:408 views/elements/search.thtml:171
+#: views/elements/search.thtml:183 views/elements/search_mini.thtml:43
+#: views/elements/search_mini.thtml:49 views/layouts/mozilla.thtml:188
+msgid "search_form_default_text"
+msgstr "zoeken naar add-ons"
+
+#: views/elements/amo2009/search.thtml:184
+#: views/elements/amo2009/search.thtml:404
+msgid "search_form_default_text_collections"
+msgstr "zoeken naar collecties"
+
+#: views/elements/amo2009/search.thtml:206 views/elements/search.thtml:202
+msgid "search_form_submit_tooltip"
+msgstr "Naar add-ons zoeken"
+
+#: views/elements/amo2009/search.thtml:184 views/elements/search.thtml:183
+#: views/elements/search_mini.thtml:49
+msgid "search_form_tooltip"
+msgstr "Klik hier om zoekwoorden in te geven"
+
+#: views/elements/amo2009/search.thtml:186 views/elements/search.thtml:185
+#: views/elements/search_mini.thtml:52
+msgid "search_form_within"
+msgstr "binnen"
+
+#: views/addons/searchengines.thtml:118
+msgid "search_landing_all_search_engines"
+msgstr "Alle zoekmachines"
+
+#: views/addons/searchengines.thtml:114
+msgid "search_landing_browse_search_engines"
+msgstr "Door zoekmachines bladeren"
+
+#: views/search/collections.thtml:58 views/search/index.thtml:59
+msgid "search_nothing_found"
+msgstr "Geen resultaten gevonden."
+
+#: controllers/search_controller.php:185
+msgid "search_pagetitle"
+msgstr "Add-ons zoeken"
+
+#: controllers/search_controller.php:242
+msgid "search_rss_description"
+msgstr "Feed met zoekresultaten"
+
+#. %s is the terms the user is searching for (a string)
+#: controllers/search_controller.php:241
+#, php-format
+msgid "search_rss_results_for"
+msgstr "Zoekresultaten voor: %s"
+
+#: views/elements/header.thtml:154 views/layouts/amo2009.thtml:296
+msgid "sidebar_navlink_admin_tools"
+msgstr "Hulpmiddelen voor beheerders"
+
+#: views/elements/header.thtml:146 views/layouts/amo2009.thtml:288
+msgid "sidebar_navlink_developer_tools"
+msgstr "Ontwikkelaarshulpmiddelen"
+
+#: views/elements/header.thtml:148 views/layouts/amo2009.thtml:290
+msgid "sidebar_navlink_editor_tools"
+msgstr "Editorhulpmiddelen"
+
+#: views/layouts/amo2009.thtml:302
+msgid "sidebar_navlink_welcome"
+msgstr "Welkom"
+
+#. %s is the user's name
+#: views/layouts/amo2009.thtml:302
+#, php-format
+msgid "sidebar_navlink_welcome_name"
+msgstr "Welkom %s"
+
+#: views/elements/pitch.thtml:50 views/elements/pitch.thtml:55
+msgid "sidebar_pitch_dictionary"
+msgstr "Woordenboek"
+
+#: views/elements/pitch.thtml:72
+msgid "sidebar_pitch_featured_addons"
+msgstr "Aanbevolen add-ons"
+
+#: views/elements/pitch.thtml:61
+msgid "sidebar_pitch_looking_for"
+msgstr "Ik zoek een:"
+
+#: views/elements/pitch.thtml:70
+msgid "sidebar_pitch_newest_addons"
+msgstr "Nieuwste add-ons"
+
+#: views/elements/pitch.thtml:49
+msgid "sidebar_pitch_search"
+msgstr "Zoekplug-in"
+
+#: views/elements/pitch.thtml:69
+msgid "sidebar_pitch_subscribe_to"
+msgstr "Abonneren op"
+
+#: views/elements/pitch.thtml:48 views/elements/pitch.thtml:54
+msgid "sidebar_pitch_theme"
+msgstr "Thema"
+
+#: views/elements/pitch.thtml:71
+msgid "sidebar_pitch_updated_addons"
+msgstr "Bijgewerkte add-ons"
+
+#. %1$s is a number
+#: views/helpers/localization.php:65 views/developers/versions_edit.thtml:95
+#: views/addons/dictionaries.thtml:92
+#, php-format
+msgid "size_kb"
+msgstr "%1$s KB"
+
+#: views/elements/amo2009/stars.thtml:57 views/elements/stars.thtml:63
+msgid "stars_not_yet_rated"
+msgstr "Nog niet gewaardeerd"
+
+#. %1 is the number of stars this add-on has
+#: views/elements/amo2009/stars.thtml:49 views/elements/stars.thtml:54
+#, php-format
+msgid "stars_rated_x_outof_5"
+msgstr "Scoort %1$s van de 5 sterren"
+
+#: views/statistics/addon.thtml:59
+msgid "statistics_addon_dashboard_link"
+msgstr "Statistieken start"
+
+#: views/statistics/addon.thtml:58
+msgid "statistics_addon_developertools_link"
+msgstr "Ontwikkelaarshulpmiddelen"
+
+#: views/statistics/addon.thtml:53
+msgid "statistics_addon_switch"
+msgstr "Add-on wisselen"
+
+#. This is a date format.
+#. http://php.net/strftime
+#: views/statistics/rss/summary.thtml:54 views/statistics/addon.thtml:181
+msgid "statistics_date_shortmonth"
+msgstr "%e %b."
+
+#. This is a date format.
+#. http://php.net/strftime
+#: views/statistics/rss/summary.thtml:40 views/statistics/addon.thtml:152
+msgid "statistics_date_shortmonthwithyear"
+msgstr "%e %b. %Y"
+
+#. This is a date format.
+#. http://php.net/strftime
+#: views/statistics/rss/summary.thtml:41 views/statistics/rss/summary.thtml:48
+#: views/statistics/addon.thtml:161 views/statistics/addon.thtml:172
+msgid "statistics_date_weekdayshortmonth"
+msgstr "%A %e %b."
+
+#. %1$s is an add-on name and version. Example: Add-on 3.5
+#: controllers/components/stats.php:519
+#, php-format
+msgid "statistics_events_addon_created"
+msgstr "%1$s aangemaakt"
+
+#. %1$s is an application name and version. Example: Firefox 3.5
+#: controllers/components/stats.php:500
+#, php-format
+msgid "statistics_events_app_released"
+msgstr "%1$s vrijgegeven"
+
+#: views/statistics/addon.thtml:71
+msgid "statistics_help_close_link"
+msgstr "Sluiten"
+
+#: views/statistics/addon.thtml:60
+msgid "statistics_help_link"
+msgstr "Help"
+
+#: views/statistics/index.thtml:83
+msgid "statistics_index_anotheraddon"
+msgstr "of selecteer een andere add-on"
+
+#: views/statistics/index.thtml:85
+msgid "statistics_index_anotheraddon_public"
+msgstr "of selecteer een add-on met publieke statistieken"
+
+#: views/statistics/index.thtml:71
+msgid "statistics_index_myaddons"
+msgstr "Selecteer één van uw add-ons om de statistieken te bekijken"
+
+#: views/statistics/index.thtml:89
+msgid "statistics_index_selectaddon"
+msgstr "Selecteer een add-on om de statistieken te bekijken"
+
+#: views/statistics/index.thtml:91
+msgid "statistics_index_selectaddon_public"
+msgstr "Selecteer een add-on met publieke statistieken"
+
+#: views/statistics/index.thtml:39
+msgid "statistics_index_title"
+msgstr "Statistieken"
+
+#: views/statistics/index.thtml:97
+msgid "statistics_index_view_button"
+msgstr "Statistieken bekijken"
+
+#: views/statistics/addon.thtml:222 controllers/statistics_controller.php:247
+msgid "statistics_js_download_csv"
+msgstr "Deze tabel in CSV-opmaak bekijken"
+
+#: controllers/statistics_controller.php:246
+msgid "statistics_js_dropdowns_none"
+msgstr "geen"
+
+#: controllers/statistics_controller.php:245
+msgid "statistics_js_dropdowns_removeplot"
+msgstr "Deze graaf verwijderen"
+
+#: controllers/statistics_controller.php:248
+msgid "statistics_js_groupby_selector_date"
+msgstr "Groeperen op: Dag"
+
+#: controllers/statistics_controller.php:251
+msgid "statistics_js_groupby_selector_month"
+msgstr "Groeperen op: Maand"
+
+#: controllers/statistics_controller.php:249
+msgid "statistics_js_groupby_selector_week"
+msgstr "Groeperen op: Week"
+
+#: controllers/statistics_controller.php:250
+msgid "statistics_js_groupby_selector_week_over_week"
+msgstr "Vergelijken op: Week"
+
+#: controllers/statistics_controller.php:260
+msgid "statistics_js_plotselection_foundinrange"
+msgstr "%s gevonden in het bereik"
+
+#: controllers/statistics_controller.php:270
+msgid "statistics_js_plotselection_options_addplot_name"
+msgstr "Graaf toevoegen"
+
+#: controllers/statistics_controller.php:271
+msgid "statistics_js_plotselection_options_addplot_tooltip"
+msgstr "Nog een graaf aan deze grafiek toevoegen"
+
+#: controllers/statistics_controller.php:261
+msgid "statistics_js_plotselection_options_count_name_checked"
+msgstr "Totaalaantal verbergen"
+
+#: controllers/statistics_controller.php:262
+msgid "statistics_js_plotselection_options_count_name_unchecked"
+msgstr "Totaalaantal weergeven"
+
+#: controllers/statistics_controller.php:263
+msgid "statistics_js_plotselection_options_count_tooltip"
+msgstr "Geef het totaalaantal weer in deze grafiek"
+
+#: controllers/statistics_controller.php:275
+msgid "statistics_js_plotselection_options_csv_name"
+msgstr "Gegevens bekijken (CSV)"
+
+#: controllers/statistics_controller.php:276
+msgid "statistics_js_plotselection_options_csv_tooltip"
+msgstr "Een bestand met kommagescheiden waarden van deze gegevens ophalen"
+
+#: controllers/statistics_controller.php:267
+msgid "statistics_js_plotselection_options_events_addon_name_checked"
+msgstr "Gebeurtenissen van %s verbergen"
+
+#: controllers/statistics_controller.php:268
+msgid "statistics_js_plotselection_options_events_addon_name_unchecked"
+msgstr "gebeurtenissen van %s weergeven"
+
+#: controllers/statistics_controller.php:269
+msgid "statistics_js_plotselection_options_events_addon_tooltip"
+msgstr "Releasedata van add-on op de grafen weergeven"
+
+#: controllers/statistics_controller.php:264
+msgid "statistics_js_plotselection_options_events_firefox_name_checked"
+msgstr "Firefoxgebeurtenissen verbergen"
+
+#: controllers/statistics_controller.php:265
+msgid "statistics_js_plotselection_options_events_firefox_name_unchecked"
+msgstr "Firefoxgebeurtenissen weergeven"
+
+#: controllers/statistics_controller.php:266
+msgid "statistics_js_plotselection_options_events_firefox_tooltip"
+msgstr "Releasedata van Firefox op de grafen weergeven"
+
+#: controllers/statistics_controller.php:272
+msgid "statistics_js_plotselection_options_resize_name_checked"
+msgstr "Grafiek inklappen"
+
+#: controllers/statistics_controller.php:273
+msgid "statistics_js_plotselection_options_resize_name_unchecked"
+msgstr "Grafiek uitklappen"
+
+#: controllers/statistics_controller.php:274
+msgid "statistics_js_plotselection_options_resize_tooltip"
+msgstr "Grafiekgrootte aanpassen"
+
+#: controllers/statistics_controller.php:254
+msgid "statistics_js_plotselection_selector_adu"
+msgstr "Actieve dagelijkse gebruikers"
+
+#: controllers/statistics_controller.php:256
+msgid "statistics_js_plotselection_selector_application"
+msgstr "Toepassing"
+
+#: controllers/statistics_controller.php:259
+msgid "statistics_js_plotselection_selector_custom"
+msgstr "Aangepast"
+
+#: controllers/statistics_controller.php:253
+msgid "statistics_js_plotselection_selector_downloads"
+msgstr "Downloads"
+
+#: controllers/statistics_controller.php:258
+msgid "statistics_js_plotselection_selector_os"
+msgstr "Besturingssysteem"
+
+#: controllers/statistics_controller.php:257
+msgid "statistics_js_plotselection_selector_status"
+msgstr "Add-onstatus"
+
+#: controllers/statistics_controller.php:252
+msgid "statistics_js_plotselection_selector_summary"
+msgstr "Samenvatting"
+
+#: controllers/statistics_controller.php:255
+msgid "statistics_js_plotselection_selector_version"
+msgstr "Add-onversie"
+
+#: controllers/components/stats.php:398
+msgid "statistics_longnames_application"
+msgstr "Toepassing"
+
+#: controllers/components/stats.php:400
+msgid "statistics_longnames_os"
+msgstr "Besturingssysteem"
+
+#: controllers/components/stats.php:399
+msgid "statistics_longnames_status"
+msgstr "Add-onstatus"
+
+#: controllers/components/stats.php:401
+msgid "statistics_longnames_unknown"
+msgstr "Onbekend"
+
+#: controllers/components/stats.php:397
+msgid "statistics_longnames_version"
+msgstr "Add-onversie"
+
+#: views/statistics/addon.thtml:118
+msgid "statistics_notice_data_insufficient"
+msgstr ""
+"Er zijn nog onvoldoende gegevens om deze grafiek weer te geven. Probeer het "
+"later nog eens."
+
+#: views/statistics/addon.thtml:130
+msgid "statistics_notice_data_none"
+msgstr ""
+"We hebben nog geen gegevens voor uw add-on. Probeer het over een paar dagen "
+"nog eens."
+
+#: views/statistics/addon.thtml:41
+msgid "statistics_notice_data_updating"
+msgstr ""
+"Add-onstatistieken worden momenteel bijgewerkt. Recente gegevens kunnen "
+"onvolledig zijn terwijl onze scripts deze informatie bijwerken. Probeer het "
+"over een paar minuten nog eens."
+
+#: views/statistics/addon.thtml:136
+msgid "statistics_notice_disabled"
+msgstr ""
+"De Statistiekensectie is momenteel uitgeschakeld. Probeer het later nog eens."
+
+#: views/statistics/addon.thtml:123
+msgid "statistics_notice_nojavascript"
+msgstr "JavaScript is nodig om de statistische grafieken te bekijken."
+
+#: views/statistics/addon.thtml:44
+msgid "statistics_notice_settings_updated"
+msgstr "Uw instellingen zijn bijgewerkt!"
+
+#: controllers/statistics_controller.php:60
+#: controllers/statistics_controller.php:71
+#: controllers/statistics_controller.php:74
+#: controllers/statistics_controller.php:240
+msgid "statistics_pagetitle"
+msgstr "Statistieken"
+
+#: views/statistics/addon.thtml:99
+msgid "statistics_plot_legend_adu"
+msgstr "Actieve dagelijkse gebruikers"
+
+#: views/statistics/addon.thtml:95
+msgid "statistics_plot_legend_downloads"
+msgstr "Downloads per dag"
+
+#: views/statistics/addon.thtml:107
+msgid "statistics_plot_options_zoomin_alt"
+msgstr "Inzoomen"
+
+#: views/statistics/addon.thtml:106
+msgid "statistics_plot_options_zoomin_title"
+msgstr "Eén maand inzoomen"
+
+#: views/statistics/addon.thtml:110
+msgid "statistics_plot_options_zoomout_alt"
+msgstr "Uitzoomen"
+
+#: views/statistics/addon.thtml:109
+msgid "statistics_plot_options_zoomout_title"
+msgstr "Eén maand uitzoomen"
+
+#: controllers/statistics_controller.php:283
+#, php-format
+msgid "statistics_rss_description"
+msgstr "Dagsamenvatting van de statistieken voor %1$s"
+
+#: views/statistics/rss/summary.thtml:68
+msgid "statistics_rss_title_fulldate"
+msgstr "%A %e %B %Y"
+
+#: views/statistics/rss/summary.thtml:68
+#, php-format
+msgid "statistics_rss_title_statsfordate"
+msgstr "Statistieken voor %1$s"
+
+#: views/statistics/settings.thtml:49
+msgid "statistics_settings_access_description"
+msgstr ""
+"Standaard hebben alleen u en Mozilla toegang tot de informatie in deze "
+"sectie. U kunt dit voor het publiek openstellen zodat iedereen de gegevens "
+"van uw add-on kan zien."
+
+#: views/statistics/settings.thtml:48
+msgid "statistics_settings_access_heading"
+msgstr "Toegang"
+
+#: views/statistics/settings.thtml:51
+msgid "statistics_settings_access_private"
+msgstr "Persoonlijk"
+
+#: views/statistics/settings.thtml:51
+msgid "statistics_settings_access_private_description"
+msgstr "Alleen u en Mozilla kunnen de statistieken van deze add-on zien"
+
+#: views/statistics/settings.thtml:52
+msgid "statistics_settings_access_public"
+msgstr "Publiek"
+
+#: views/statistics/settings.thtml:52
+msgid "statistics_settings_access_public_description"
+msgstr "Iedereen kan de statistieken van deze add-on zien"
+
+#: views/statistics/addon.thtml:251
+msgid "statistics_settings_change_link"
+msgstr "Instellingen wijzigen"
+
+#: views/statistics/addon.thtml:253
+msgid "statistics_settings_confidential"
+msgstr "Deze informatie als vertrouwelijk behandelen."
+
+#: views/statistics/addon.thtml:245
+msgid "statistics_settings_currently_private"
+msgstr "Deze sectie is momenteel <b>persoonlijk</b>."
+
+#: views/statistics/addon.thtml:241
+msgid "statistics_settings_currently_public"
+msgstr "Deze sectie is momenteel <b>publiek</b>."
+
+#: views/statistics/addon.thtml:246
+msgid "statistics_settings_locked_alt"
+msgstr "Afgesloten"
+
+#: views/statistics/settings.thtml:57
+msgid "statistics_settings_return_link"
+msgstr "Terug naar Statistieken"
+
+#: views/statistics/settings.thtml:56
+msgid "statistics_settings_save_button"
+msgstr "Instellingen opslaan"
+
+#: views/statistics/settings.thtml:46
+#, php-format
+msgid "statistics_settings_title"
+msgstr "Instellingen van Statistieken voor %1$s"
+
+#: views/statistics/addon.thtml:242
+msgid "statistics_settings_unlocked_alt"
+msgstr "Onafgesloten"
+
+#: controllers/components/stats.php:405
+msgid "statistics_shortnames_application"
+msgstr "Toep"
+
+#: controllers/components/stats.php:407
+msgid "statistics_shortnames_os"
+msgstr "BS"
+
+#: controllers/components/stats.php:406
+msgid "statistics_shortnames_status"
+msgstr "St"
+
+#: controllers/components/stats.php:408
+msgid "statistics_shortnames_unknown"
+msgstr "Onb"
+
+#: controllers/components/stats.php:404
+msgid "statistics_shortnames_version"
+msgstr "Ver"
+
+#: views/statistics/rss/summary.thtml:42 views/statistics/addon.thtml:192
+msgid "statistics_summary_downloads_average"
+msgstr "Gemiddelde dagelijkse downloads"
+
+#: views/statistics/rss/summary.thtml:39
+msgid "statistics_summary_downloads_heading"
+msgstr "Downloads"
+
+#: views/statistics/rss/summary.thtml:41 views/statistics/addon.thtml:171
+msgid "statistics_summary_downloads_lastcount"
+msgstr "Aantal op laatste dag"
+
+#: views/statistics/rss/summary.thtml:43 views/statistics/addon.thtml:199
+msgid "statistics_summary_downloads_lastweek"
+msgstr "Downloads in de laatste 7 dagen"
+
+#: views/statistics/rss/summary.thtml:40 views/statistics/addon.thtml:151
+msgid "statistics_summary_downloads_total"
+msgstr "Totaal aantal downloads"
+
+#: views/statistics/rss/summary.thtml:40 views/statistics/addon.thtml:152
+#, php-format
+msgid "statistics_summary_downloads_total_sincedate"
+msgstr "Sinds %1$s"
+
+#: views/statistics/rss/summary.thtml:50 views/statistics/rss/summary.thtml:56
+#: views/statistics/addon.thtml:163 views/statistics/addon.thtml:183
+msgid "statistics_summary_nodata"
+msgstr "Nog geen gegevens"
+
+#: views/statistics/rss/summary.thtml:60 views/statistics/addon.thtml:195
+msgid "statistics_summary_updatepings_average"
+msgstr "Gemiddeld aantal dagelijkse actieve gebruikers"
+
+#: views/statistics/rss/summary.thtml:52 views/statistics/addon.thtml:177
+msgid "statistics_summary_updatepings_changefromprevious"
+msgstr "Wijziging t.o.v. vorige telling"
+
+#: views/statistics/rss/summary.thtml:54 views/statistics/addon.thtml:181
+#, php-format
+msgid "statistics_summary_updatepings_changefromprevious_ondate"
+msgstr "%1$s op %2$s"
+
+#: views/statistics/rss/summary.thtml:45
+msgid "statistics_summary_updatepings_heading"
+msgstr "Actieve dagelijkse gebruikers"
+
+#: views/statistics/rss/summary.thtml:46 views/statistics/addon.thtml:157
+msgid "statistics_summary_updatepings_total"
+msgstr "Actieve dagelijkse gebruikers"
+
+#: views/statistics/rss/summary.thtml:48 views/statistics/addon.thtml:161
+#, php-format
+msgid "statistics_summary_updatepings_total_ondate"
+msgstr "Op %1$s"
+
+#: views/statistics/rss/summary.thtml:61 views/statistics/addon.thtml:203
+msgid "statistics_summary_updatepings_weekly_average"
+msgstr "Gemiddeld aantal gebruikers deze week"
+
+#. %s is a percentage, like '+22.33%'. It sits next to another number, so
+#. the implied meaning is 'percentage change' from the previous stat point.
+#: views/statistics/rss/summary.thtml:62 views/statistics/addon.thtml:205
+msgid "statistics_summary_updatepings_weekly_change"
+msgstr "%s ten opzichte van vorige week"
+
+#: views/statistics/addon.thtml:65 controllers/statistics_controller.php:184
+#: controllers/statistics_controller.php:282
+#, php-format
+msgid "statistics_title_addon_stats"
+msgstr "%1$s statistieken"
+
+#: views/addons/themes_landing.thtml:113
+msgid "themes_landing_all_themes"
+msgstr "Alle thema’s"
+
+#: views/addons/themes_landing.thtml:109
+msgid "themes_landing_browse_themes"
+msgstr "Door thema’s bladeren"
+
+#: views/users/edit.thtml:185
+msgid "user_change_email"
+msgstr "E-mailadres wijzigen"
+
+#: views/users/edit.thtml:169
+msgid "user_change_password"
+msgstr "Wachtwoord wijzigen"
+
+#: views/users/edit.thtml:96
+msgid "user_change_password_or_email"
+msgstr "Wachtwoord of e-mailadres wijzigen"
+
+#: controllers/users_controller.php:197
+msgid "user_confirmationcode_resent"
+msgstr "De bevestigingscode is opnieuw verstuurd!"
+
+#. %1 is the email address, %2 is the URL of the user registration page
+#: views/users/delete.thtml:51
+msgid "user_del_account_deleted"
+msgstr ""
+"Uw gebruikersaccount %1$s is succesvol verwijderd. Als u ooit terug wilt "
+"komen kunt u zich opnieuw inschrijven op de <a href=\"%2$s\"> "
+"gebruikersregistratiepagina</a>."
+
+#: views/users/delete.thtml:102
+msgid "user_del_community_sad"
+msgstr "De Mozilla Add-onsgemeenschap vindt het jammer dat u vertrekt."
+
+#: views/users/delete.thtml:123
+msgid "user_del_confirm_password"
+msgstr "Wachtwoord bevestigen"
+
+#: views/users/delete.thtml:134
+msgid "user_del_deletenow"
+msgstr "Mijn gebruikersaccount nu verwijderen"
+
+#. %1 is the URL of the user's info page
+#: views/users/delete.thtml:64
+msgid "user_del_error_addons"
+msgstr ""
+"U kunt uw account niet verwijderen als u staat geregistreerd als een <a href="
+"\"%1$s\">schrijver van een add-on</a>. Om uw account te kunnen verwijderen "
+"dient een andere persoon in uw ontwikkelingsgroep u uit de lijst van "
+"schrijvers voor uw add-on(s) te verwijderen. Hierna kunt u hier uw account "
+"verwijderen."
+
+#. %1 is a link to the amo-editors mailing list
+#: views/users/delete.thtml:71
+msgid "user_del_error_addons_more_questions"
+msgstr ""
+"Als u aanvullende vragen heeft kunt u contact opnemen met %1$s voor hulp."
+
+#: views/users/delete.thtml:78
+msgid "user_del_error_checkbox"
+msgstr ""
+"U dient het veld “Ik begrijp…†aan te vinken voordat we uw account kunnen "
+"verwijderen."
+
+#: views/users/delete.thtml:84
+msgid "user_del_error_password"
+msgstr "Voer a.u.b. uw wachtwoord correct in om deze stap te zetten."
+
+#. %1 is a link to the amo-admins mailing list
+#: views/users/delete.thtml:91
+msgid "user_del_error_unknown"
+msgstr ""
+"Er is een onbekende fout opgetreden bij het verwijderen van uw account. Neem "
+"hierover a.u.b. contact op met %1$s en wij zullen uw account voor uw "
+"verwijderen. Excuses voor het ongemak."
+
+#: views/users/delete.thtml:110
+msgid "user_del_header_confirm_deletion"
+msgstr "Verwijdering gebruikersaccount bevestigen"
+
+#. %1 is the user's email address
+#: views/users/delete.thtml:100
+msgid "user_del_header_delete_account"
+msgstr "Gebruikersaccount %1$s verwijderen"
+
+#: views/users/delete.thtml:50
+msgid "user_del_header_farewell"
+msgstr "Vaarwel!"
+
+#: views/users/delete.thtml:115
+msgid "user_del_nologin"
+msgstr "U kunt vanaf nu niet meer op Mozilla Add-ons inloggen."
+
+#: views/users/delete.thtml:112
+msgid "user_del_permanently_removed_means"
+msgstr ""
+"Door op “Verwijderen†te klikken wordt uw account <strong>permanent "
+"verwijderd</strong>. Dat betekent:"
+
+#: views/users/delete.thtml:116
+msgid "user_del_reviews_anonymized"
+msgstr ""
+"Uw beoordelingen en waarderingen worden niet verwijderd, maar ze zullen niet "
+"langer aan uw account verbonden zijn."
+
+#. %1 is a link to the amo-editors mailing list
+#: views/users/delete.thtml:104
+msgid "user_del_specific_problem_editors"
+msgstr ""
+"Als u een specifiek probleem hebt waarmee we u kunnen helpen, verwijder dan "
+"niet nu uw account, maar neem contact met ons op via %1$s en we zullen ons "
+"best doen u te helpen het op te lossen."
+
+#: views/users/delete.thtml:130
+msgid "user_del_understand_permanent"
+msgstr "Ik begrijp dat deze stap niet ongedaan kan worden gemaakt."
+
+#: views/helpers/addons_html.php:192
+msgid "user_deleted_nickname"
+msgstr "Verwijderde gebruiker"
+
+#. %1 is the new email address
+#: views/users/edit.thtml:71
+msgid "user_edit_confirm_email_sent"
+msgstr ""
+"Er is een e-mailbericht verstuurd naar %1$s om uw nieuwe e-mailadres te "
+"bevestigen. Om de wijziging door te voeren dient u te klikken op de "
+"koppeling in dit e-mailbericht. Tot dat moment kunt u inloggen met uw "
+"huidige e-mailadres."
+
+#: views/users/edit.thtml:201
+msgid "user_edit_delete_user"
+msgstr "Gebruikersaccount verwijderen"
+
+#. This contains the email sent to users when they signed up for a new
+#. account:
+#. %1 is the confirmation URL, %2 is the current app
+#: views/users/email/confirm_plain.thtml:6
+#, php-format
+msgid "user_email_confirm_account_nopass"
+msgstr ""
+"Welkom bij %2$s add-ons.\n"
+"\n"
+"Voordat u uw nieuwe account kunt gebruiken moet u het activeren – dit "
+"bevestigt dat het gebruikte e-mailadres geldig is en van u is.\n"
+"Klik op onderstaande koppeling om uw account te activeren, of kopieer en "
+"plak de gehele koppeling in de locatiebalk van uw browser:\n"
+"\n"
+"%1$s\n"
+"\n"
+"Wanneer u uw account succesvol hebt geactiveerd kunt u dit e-mailbericht "
+"weggooien.\n"
+"\n"
+"Bedankt voor uw aanmelding bij %2$s Add-ons\n"
+"– %2$s Add-ons Team"
+
+#. %1 is the confirmation url, %2 is the application name
+#: views/users/email/emailchange_plain.thtml:5
+msgid "user_email_confirm_emailchange"
+msgstr ""
+"U hebt verzocht om wijziging van uw e-mailadres op %2$s Add-ons.\n"
+"\n"
+"Kik om het nieuwe adres te bevestigen a.u.b. op onderstaande koppeling of "
+"kopieer en plak de koppeling in uw lokatiebalk:\n"
+"\n"
+"%1$s\n"
+"\n"
+"U hebt 48 uur de tijd om het nieuwe adres te bevestigen. Als u het adres "
+"niet meer wilt wijzigen kunt u dit e-mailbericht gewoon negeren.\n"
+"\n"
+"Bedankt!\n"
+"– %2$s Add-ons Team"
+
+#: controllers/users_controller.php:168
+#, php-format
+msgid "user_email_confirm_subject"
+msgstr "Bedankt voor uw aanmelding bij %s Add-ons"
+
+#. This is the password reset email
+#. %1 is the pw reset URL, %2 is the application
+#: views/users/email/pwreset_plain.thtml:5
+#, php-format
+msgid "user_email_pwreset"
+msgstr ""
+"%2$s add-ons wachtwoordreset\n"
+"\n"
+"Er is een verzoek ontvangen om het wachtwoord voor deze account op AMO te "
+"resetten. Klik op de volgende koppeling om het wachtwoord te wijzigen, of "
+"plak deze in de locatiebalk van uw browser:\n"
+"\n"
+"%1$s\n"
+"\n"
+"Als u dit bericht niet hebt aangevraagd is verdere actie niet nodig.\n"
+"\n"
+"Bedankt,\n"
+"– %2$s Add-ons Team"
+
+#: controllers/users_controller.php:245
+#, php-format
+msgid "user_email_pwreset_subject"
+msgstr "Uw %s Add-ons-wachtwoord resetten"
+
+#: views/users/emailchange.thtml:50
+msgid "user_emailchange_error"
+msgstr "Fout!"
+
+#. %1 is the application name
+#: controllers/users_controller.php:533
+msgid "user_emailchange_subject"
+msgstr "Bevestig a.u.b. de wijziging van uw e-mailadres bij %1$s Add-ons"
+
+#: views/users/emailchange.thtml:48
+msgid "user_emailchange_success"
+msgstr "Succes!"
+
+#. %1 is the new email address
+#: views/users/emailchange.thtml:49
+msgid "user_emailchange_successful_description"
+msgstr ""
+"U e-mailadres is met succes gewijzigd. Gebruik vanaf nu a.u.b. %1$s om in te "
+"loggen."
+
+#: views/users/edit.thtml:134 views/admin/users_edit.thtml:111
+msgid "user_form_bio"
+msgstr "Over mij"
+
+#: views/users/edit.thtml:135 views/admin/users_edit.thtml:112
+msgid "user_form_bio_description"
+msgstr ""
+"Stel uzelf voor aan de gemeenschap indien u dat wilt! Deze tekst verschijnt "
+"openbaar op de uw gebruikersinformatiepagina. Regelonderbrekingen worden "
+"behouden, maar HTML is niet toegestaan."
+
+#: views/users/pwreset.thtml:77 views/users/register.thtml:73
+#: views/users/edit.thtml:181
+msgid "user_form_confirmpassword"
+msgstr "Wachtwoord bevestigen"
+
+#: views/users/edit.thtml:145
+msgid "user_form_display_collections"
+msgstr "De collecties die ik heb gemaakt in mijn gebruikersprofiel weergeven"
+
+#: views/users/edit.thtml:149
+msgid "user_form_display_collections_fav"
+msgstr "Mijn favoriete collecties in mijn gebruikersprofiel weergeven"
+
+#: views/users/edit.thtml:86
+#, php-format
+msgid "user_form_editprofile"
+msgstr "Gebruikersprofiel voor %s bewerken"
+
+#: views/users/pwreset.thtml:52 views/users/login.thtml:81
+#: views/users/register.thtml:63 views/users/edit.thtml:187
+msgid "user_form_email"
+msgstr "E-mailadres"
+
+#: views/users/register.thtml:78 views/users/edit.thtml:103
+#: views/admin/users_edit.thtml:76
+msgid "user_form_firstname"
+msgstr "Voornaam"
+
+#: views/users/register.thtml:94 views/users/edit.thtml:119
+#: views/admin/users_edit.thtml:91
+msgid "user_form_hideemail"
+msgstr "E-mailadres verbergen"
+
+#: views/users/register.thtml:98 views/users/edit.thtml:123
+#: views/admin/users_edit.thtml:99
+msgid "user_form_homepage"
+msgstr "Website-URL"
+
+#: views/users/register.thtml:84 views/users/edit.thtml:109
+#: views/admin/users_edit.thtml:81
+msgid "user_form_lastname"
+msgstr "Achternaam"
+
+#: controllers/users_controller.php:333
+msgid "user_form_login"
+msgstr "Inloggen"
+
+#: views/users/pwreset.thtml:72 views/users/edit.thtml:176
+msgid "user_form_newpassword"
+msgstr "Nieuw wachtwoord"
+
+#: views/users/register.thtml:89 views/users/edit.thtml:114
+#: views/admin/users_edit.thtml:86
+msgid "user_form_nickname"
+msgstr "Nickname"
+
+#: views/users/edit.thtml:171
+msgid "user_form_oldpassword"
+msgstr "Oud wachtwoord"
+
+#: views/users/edit.thtml:97 views/users/edit.thtml:200
+msgid "user_form_otheractions"
+msgstr "Overige acties"
+
+#: views/users/login.thtml:85 views/users/register.thtml:68
+msgid "user_form_password"
+msgstr "Wachtwoord"
+
+#: controllers/users_controller.php:93
+msgid "user_form_registration"
+msgstr "Nieuwe gebruikersregistratie"
+
+#: views/users/login.thtml:90
+msgid "user_form_remember_me"
+msgstr "Mij op deze computer onthouden"
+
+#: views/admin/users_edit.thtml:95
+msgid "user_form_showsandbox"
+msgstr "Sandbox weergeven?"
+
+#: views/users/edit.thtml:205
+msgid "user_form_submit_edit"
+msgstr "Opslaan"
+
+#: views/users/login.thtml:93
+msgid "user_form_submit_login"
+msgstr "Inloggen"
+
+#: views/users/register.thtml:113
+msgid "user_form_submit_register"
+msgstr "Registreren"
+
+#: views/users/info.thtml:75
+#, php-format
+msgid "user_info_usersince"
+msgstr "%s Add-ons-gebruiker sinds"
+
+#: views/users/login.thtml:102
+msgid "user_login_register_link"
+msgstr "Nieuwe gebruikersaccount aanmaken"
+
+#: views/users/edit.thtml:160
+msgid "user_notifications_item_compat"
+msgstr "Add-oncompatibiliteit (sterk aanbevolen)"
+
+#: views/users/edit.thtml:161
+msgid "user_notifications_item_events"
+msgstr "Verwachte evenementen en wedstrijden"
+
+#: views/users/edit.thtml:156
+msgid "user_notifications_none_available"
+msgstr "Er zijn momenteel geen in te stellen notificaties beschikbaar."
+
+#: views/users/edit.thtml:158
+msgid "user_notifications_select_topics"
+msgstr ""
+"Af en toe kan Mozilla u een e-mailbericht sturen over verwachte releases en "
+"add-onevenementen. Selecteer a.u.b. hieronder de onderwerpen waarin u bent "
+"geïnteresseerd:"
+
+#: views/users/edit.thtml:164
+msgid "user_notifications_specific_contact"
+msgstr ""
+"Mozilla behoudt zich het recht voor om individueel contact met u op te nemen "
+"over specifieke zorgen over uw add-ons die gehost worden."
+
+#: controllers/users_controller.php:543
+msgid "user_profile_edit_error"
+msgstr ""
+"Er zijn fouten opgetreden in de door u aangebrachte wijzigingen. Corrigeer "
+"ze a.u.b. en dien het formulier opnieuw in."
+
+#: controllers/users_controller.php:540
+msgid "user_profile_saved"
+msgstr "Profiel bijgewerkt."
+
+#: views/users/pwreset.thtml:65
+#, php-format
+msgid "user_pwreset_for_email"
+msgstr "wachtwoord gereset voor %s"
+
+#: controllers/users_controller.php:226
+msgid "user_pwreset_header"
+msgstr "Wachtwoordreset"
+
+#: views/users/login.thtml:103
+msgid "user_pwreset_link"
+msgstr "Wachtwoord vergeten?"
+
+#: controllers/users_controller.php:248
+msgid "user_pwreset_link_sent"
+msgstr ""
+"De koppeling om uw wachtwoord te resetten is naar uw e-mailadres verzonden."
+
+#: controllers/users_controller.php:304
+msgid "user_pwreset_okay"
+msgstr "Wachtwoord succesvol gereset."
+
+#: views/users/pwreset.thtml:82
+msgid "user_pwreset_submit_changepw"
+msgstr "Wijziging wachtwoord indienen"
+
+#: views/users/pwreset.thtml:57
+msgid "user_pwreset_submit_sendlink"
+msgstr "Koppeling voor wachtwoordreset toezenden"
+
+#: views/users/register_complete.thtml:51
+#, php-format
+msgid "user_register_amo_link"
+msgstr "%s Add-ons"
+
+#. %1 is the user's email address, %2 is the current app
+#: views/users/activatefirst.thtml:49
+#, php-format
+msgid "user_register_click_confirm_link"
+msgstr ""
+"Een koppeling om uw gebruikersaccount te activeren is per e-mail naar uw "
+"adres %1$s verzonden. U dient er op te klikken voordat u kunt inloggen op %2"
+"$s Add-ons."
+
+#. %1 is the user's email address
+#: views/users/register_complete.thtml:49
+#, php-format
+msgid "user_register_confirm_email_sent"
+msgstr ""
+"Er is een e-mail verzonden naar uw adres %1$s om uw account te bevestigen. "
+"Voordat u kunt inloggen dient u uw account te activeren door op de koppeling "
+"in deze e-mail te klikken."
+
+#: views/users/activatefirst.thtml:51
+msgid "user_register_confirmation_link_text"
+msgstr "bevestigingsbericht opnieuw verzenden"
+
+#: views/users/register_complete.thtml:47
+msgid "user_register_congratulations"
+msgstr "Gefeliciteerd! Uw gebruikersaccount is succesvol aangemaakt."
+
+#: views/users/register.thtml:50
+msgid "user_register_details"
+msgstr ""
+"<p>Registratie op AMO is <strong>niet vereist</strong> als u gewoon publieke "
+"add-ons wilt downloaden en installeren.</p><p>U hoeft zich alleen te "
+"registreren als:</p><ul><li>U beoordelingen voor add-ons wilt indienen</"
+"li><li>U een add-onontwikkelaar bent en uw add-on wilt uploaden voor hosting "
+"op AMO</li></ul><p>Na succesvolle registratie ontvangt u per e-mail een "
+"bevestiging op het door u opgegeven adres. Volg a.u.b. de instructies daarin "
+"om uw account te bevestigen.</p><p>Indien gewenst kunt u onze <a href='%1$s' "
+"title='Legal Notices'>Legal Notices</a> and <a href='%2$s' title='Privacy "
+"Policy'>Privacy Policy</a> (in het Engels) lezen.</p>"
+
+#. %1 is the link to the "resend confirmation code" page
+#: views/users/activatefirst.thtml:51
+#, php-format
+msgid "user_register_resend_confirmation_link"
+msgstr ""
+"Als u de bevestigingse-mail niet heeft ontvangen, controleer dan of uw e-"
+"mailservice deze niet als “junk mail†of “spam†heeft gemarkeerd. Als het "
+"nodig is, kunnen wij u het %1$s naar uw e-mailadres zoals hierboven vermeld."
+
+#. %1 is the link to the Mozilla Add-ons front page
+#: views/users/register_complete.thtml:51
+#, php-format
+msgid "user_register_welcome"
+msgstr "Bedankt voor uw registratie en welkom bij %1$s!"
+
+#: views/users/register.thtml:49
+msgid "user_register_welcome_header"
+msgstr "Welkom bij addons.mozilla.org (AMO)!"
+
+#: views/users/register.thtml:81 views/users/edit.thtml:106
+msgid "user_required_firstlast_or_nickname"
+msgstr "Een voornaam, achternaam of gebruikersnaam is vereist."
+
+#: views/users/edit.thtml:94 views/users/edit.thtml:142
+msgid "user_tab_collections"
+msgstr "Collecties"
+
+#: views/users/edit.thtml:95 views/users/edit.thtml:154
+msgid "user_tab_notifications"
+msgstr "Notificaties"
+
+#: views/users/edit.thtml:93 views/users/edit.thtml:101
+msgid "user_tab_profile"
+msgstr "Gebruikersprofiel"
+
+#: controllers/users_controller.php:209
+msgid "user_verified_okay"
+msgstr "Succesvol geverifieerd!"
+
+#: controllers/users_controller.php:723
+msgid "users_delete_pagetitle"
+msgstr "Gebruikersaccount verwijderen"
+
+#: controllers/users_controller.php:414
+msgid "users_edit_pagetitle"
+msgstr "Bewerken gebruikersaccount"
+
+#: views/users/info.thtml:71
+msgid "users_info_aboutme"
+msgstr "Over mij"
+
+#: views/users/info.thtml:96
+#, php-format
+msgid "users_info_addons_by_user"
+msgstr "Add-ons door %1$s"
+
+#: views/users/info.thtml:51
+msgid "users_info_author_name"
+msgstr "Naam"
+
+#: views/users/info.thtml:48
+msgid "users_info_author_profile"
+msgstr "Gebruikersprofiel"
+
+#. %s is the user name
+#: views/users/info.thtml:137
+msgid "users_info_collections_by_user"
+msgstr "Collecties van %s"
+
+#: views/users/info.thtml:66
+msgid "users_info_email"
+msgstr "E-mailadres"
+
+#: views/users/info.thtml:155
+msgid "users_info_fav_collections_by_user"
+msgstr "Favoriete collecties"
+
+#: views/users/info.thtml:61
+msgid "users_info_homepage"
+msgstr "Startpagina"
+
+#: views/users/info.thtml:56
+msgid "users_info_nickname"
+msgstr "Nickname"
+
+#: controllers/users_controller.php:707
+#, php-format
+msgid "users_info_pagetitle"
+msgstr "Gebruikersinformatie voor %1$s"
+
+#. %1 is the user's name
+#: views/users/info.thtml:116
+msgid "users_info_reviews_by_user"
+msgstr "Beoordelingen door %1$s"
+
+#: controllers/users_controller.php:330 controllers/users_controller.php:332
+msgid "users_login_pagetitle"
+msgstr "Inloggen"
+
+#. %1 is the link to the sandbox/policy explanation page
+#. This message is for a specific add-on not found
+#: views/users/login.thtml:53
+#, php-format
+msgid "users_login_sandbox_display_warning"
+msgstr ""
+"De door u gezochte add-on bevindt zich momenteel in de sandbox. Als u al een "
+"account op Mozilla Add-ons hebt, log dan a.u.b. in, of <a href=\"%1$s\">kom "
+"meer te weten over de sandbox.</a>"
+
+#. %1 is the link to the sandbox/policy explanation page
+#. This message is for any given sandbox-related page not found
+#: views/users/login.thtml:56
+#, php-format
+msgid "users_login_sandbox_page_warning"
+msgstr ""
+"De door u gezochte pagina is onderdeel van de sandbox. Als u al een account "
+"op Mozilla Add-ons hebt, log dan a.u.b. in, of <a href=\"%1$s\">kom meer te "
+"weten over de sandbox.</a>"
+
+#: controllers/users_controller.php:223 controllers/users_controller.php:225
+msgid "users_pwreset_pagetitle"
+msgstr "Resetten gebruikerswachtwoord"
+
+#: controllers/users_controller.php:90 controllers/users_controller.php:92
+msgid "users_register_pagetitle"
+msgstr "Nieuwe gebruikersregistratie"
+
+#. %1$s is an addon name, like <a>Firebug</a>
+#. %2$s is a version number, like <a>1.2</a>
+#: views/versions/license.thtml:52
+msgid "versions_license_header_source"
+msgstr "Broncodelicentie voor %1$s %2$s"
+
+#: views/addons/category_landing.thtml:147
+msgid "view_recently_added"
+msgstr "Alle onlangs toegevoegde bekijken"
+
+#: views/addons/category_landing.thtml:161
+msgid "view_top_downloads"
+msgstr "Alle topdownloads bekijken"
+
+#: views/addons/category_landing.thtml:175
+msgid "view_top_rated"
+msgstr "Alle best beoordeelde bekijken"
diff --git a/site/app/locale/nl/images/sandbox-review.png b/site/app/locale/nl/images/sandbox-review.png
new file mode 100644
index 0000000..d998145
--- /dev/null
+++ b/site/app/locale/nl/images/sandbox-review.png
Binary files differ
diff --git a/site/app/locale/nl/pages/about.thtml b/site/app/locale/nl/pages/about.thtml
new file mode 100644
index 0000000..3a69341
--- /dev/null
+++ b/site/app/locale/nl/pages/about.thtml
@@ -0,0 +1,47 @@
+<h2>Wat is addons.mozilla.org?</h2>
+<p>
+ addons.mozilla.org (AMO) is de officiële site van Mozilla voor add-ons voor Mozilla-toepassingen. Met add-ons kunt u nieuwe functies toevoegen aan Firefox, Thunderbird, SeaMonkey en Sunbird. Op AMO kunt u door duizenden add-ons bladeren en ze downloaden om zo de manier waarop u het internet gebruikt te veranderen.
+</p>
+
+<h2>Wie maakt deze add-ons?</h2>
+<p>
+ De duizenden add-onontwikkelaars variëren van individuele hobbyisten tot grote bedrijven. Alle publieke add-ons worden beoordeeld door een team van toegewijde vrijwilligers voordat ze worden vrijgegeven. Experimentele add-ons worden als zodanig gemarkeerd en zijn nog niet beoordeeld.
+</p>
+
+<h2>Hoe houd ik bij wat er gebeurt op AMO?</h2>
+<p>
+ Onze <a href="http://blog.mozilla.com/addons/">blog</a> wordt regelmatig bijgewerkt, en vaak worden berichten uit de algemene gemeenschap getoond. We hebben ook een <a href="https://addons.mozilla.org/newsletter">nieuwsbrief</a> die maandelijks wordt verstuurd.
+</p>
+
+<h2>Dat klinkt geweldig! Hoe kan ik bijdragen?</h2>
+<p>
+ Er zijn vele manieren om bij te dragen:
+</p>
+<ul>
+ <li>
+ <a href="https://wiki.mozilla.org/AMO:Editors/Applying">Word een editor</a>. Onze editors zijn AMO-fans met een technische achtergrond die add-ons beoordelen op codekwaliteit en stabiliteit.
+ </li>
+ <li>
+ <a href="http://developer.mozilla.org/">Maak uw eigen add-on</a>. AMO biedt gratis hosting en updatediensten en kan u helpen een groot publiek te bereiken.
+ </li>
+ <li>
+ Vertel het uw vrienden! <a href="http://spreadfirefox.com/">Verspreid Firefox</a> en laat mensen weten welke add-ons u gebruikt.
+ </li>
+ <li>
+ Meld fouten en oplossingen.
+ <a href="https://bugzilla.mozilla.org/buglist.cgi?quicksearch=addons">Bugzilla</a> bevat alle huidige fouten in AMO. U kunt daar nog niet ontdekte fouten melden of oplossingen aandragen.
+ </li>
+</ul>
+
+<h2>Ik heb een vraag.</h2>
+<p>
+ Een goed startpunt is onze pagina met
+ <a href="https://addons.mozilla.org/pages/faq"><abbr title="Frequently Asked Questions">veelgestelde vragen</abbr></a>. Als u daar het antwoord niet vindt kunt u de contactinformatie gebruiken onder aan deze pagina. Voor vragen over een specifieke add-on kunt u de contactinformatie op de pagina van de desbetreffende add-on gebruiken.
+</p>
+
+<h2>Neem contact met ons op</h2>
+<dl>
+ <dt>Via <abbr title="Internet Relay Chat">IRC</abbr>:</dt>
+ <dd><a href="irc://irc.mozilla.org/#addons">#addons</a> op irc.mozilla.org voor algemene vragen en vragen over beoordelingen</dd>
+ <dd><a href="irc://irc.mozilla.org/#amo">#amo</a> op irc.mozilla.org voor vragen over administratie of ontwikkeling</dd>
+</dl>
diff --git a/site/app/locale/nl/pages/collector_features.thtml b/site/app/locale/nl/pages/collector_features.thtml
new file mode 100644
index 0000000..c6aa3eb
--- /dev/null
+++ b/site/app/locale/nl/pages/collector_features.thtml
@@ -0,0 +1,27 @@
+<h2>Mozilla Firefox Add-on Collector</h2>
+<h4>Houd uw browseraanpassingen scherp.</h4>
+<h3>Extensiefuncties</h3>
+
+<p>
+ Add-on Collector houdt u verbonden met uw favoriete add-ons en collecties op verschillende manieren:
+</p>
+
+<dl>
+ <dt>Benader uw favoriete collecties vanuit Firefox</dt>
+ <dd>
+ Collecties die u markeert als favorieten in de <a href="%1$s">Collectiemap</a> verschijnen in een speciaal deel van de Add-onsbeheerder. Hierdoor kunt u bijblijven en de inhoud van elke collectie bekijken.
+ </dd>
+ <dt>Deel add-ons met het Publicatiemenu</dt>
+ <dd>
+ Elke add-on die u installeert wordt eenvoudig gedeeld met een vriend via e-mail of gepubliceerd naar één van uw collecties via een publicatiemenu.
+ </dd>
+ <dt>Ontvang notificaties</dt>
+ <dd>
+ Add-on Collector geeft u een bericht wanneer één van uw favoriete collecties een nieuw onderdeel bevat, en markeert dit zodat u het later kunt beoordelen.
+ </dd>
+
+ <dt>Publiceer automatisch uw geïnstalleerde add-ons naar een collectie</dt>
+ <dd>
+ Autopublicatiefunctionaliteit zorgt ervoor dat uw collectie continu wordt bijgewerkt met uw laatste add-ons, zodat uw vrienden die zich hebben geabonneerd up-to-date blijven.
+ </dd>
+</dl>
diff --git a/site/app/locale/nl/pages/compatibility_developer_tips.thtml b/site/app/locale/nl/pages/compatibility_developer_tips.thtml
new file mode 100644
index 0000000..a7bfef1
--- /dev/null
+++ b/site/app/locale/nl/pages/compatibility_developer_tips.thtml
@@ -0,0 +1,6 @@
+<ul class="tips">
+ <li>Informatie over bijwerken van uw add-ons naar %s kan worden gevonden in dit <a href="https://developer.mozilla.org/En/Updating_extensions_for_%s">artikel in het Mozilla Ontwikkelaarscentrum (Engelstalig)</a>.</li>
+ <li>Informatie over de algemene wijzigingen in %s kunnen worden gevonden in <a href="https://developer.mozilla.org/en/%s_for_developers">dit artikel (Engelstalig)</a>.</li>
+ <li>U kunt u abonneren op de <a href="https://addons.mozilla.org/newsletter">about:addons nieuwsbrief</a> en de <a href="http://blog.mozilla.com/addons/">Mozilla Add-onsblog</a> voor meer updates.</li>
+ <li>Als uw add-on geen codewijzigingen nodig heeft om compatibiliteit te claimen en op Mozilla Add-ons wordt gehost kunt u de compatibele maxVersion online wijzigen zonder een nieuw bestand te uploaden door naar de <a href="%s">Ontwikkelaarshulpmiddelen</a> te gaan of door de status hieronder te bekijken.</li>
+</ul> \ No newline at end of file
diff --git a/site/app/locale/nl/pages/compatibility_user_tips.thtml b/site/app/locale/nl/pages/compatibility_user_tips.thtml
new file mode 100644
index 0000000..17e3e72
--- /dev/null
+++ b/site/app/locale/nl/pages/compatibility_user_tips.thtml
@@ -0,0 +1,6 @@
+<ul class="tips">
+ <li>Terwijl veel add-ons de wijzigingen in %s zonder aanpassingen in de code kunnen ondersteunen, is voor andere mogelijk enig aanvullend werk door de schrijvers nodig om voor een soepele upgrade te kunnen zorgen. Wees a.u.b. geduldig terwijl dit gebeurt, aangezien veel ontwikkelaars hun add-ons vrijwillig bij wijze van hobby onderhouden.</li>
+ <li>Mozilla raadt het uitschakelen van de compatibiliteitscontrole af, aangezien dit tot serieuze problemen kan leiden bij het starten van %s en zelfs tot gegevensverlies als een extensie die niet compatibel is met een nieuwe versie van %s toch wordt gebruikt.</li>
+ <li>Als de extensie die u probeert te gebruiken niet compatibel is nadat %s is gelanceerd, kunt u wellicht de bijbehorende website of de startpagina van de schrijver bezoeken voor mogelijk nieuws over de update.</li>
+ <li>U kunt ook zoeken op de <a href="%s">%s Add-ons</a> website naar een add-on met vergelijkbare functionaliteit die wel %s ondersteunt.</li>
+</ul> \ No newline at end of file
diff --git a/site/app/locale/nl/pages/developer_faq.thtml b/site/app/locale/nl/pages/developer_faq.thtml
new file mode 100644
index 0000000..d130a57
--- /dev/null
+++ b/site/app/locale/nl/pages/developer_faq.thtml
@@ -0,0 +1,44 @@
+<h2>OVER OPENSOURCELICENTIES</h2>
+<p>
+ Wilt u meer informatie over de diverse opensourcelicenties? Weet u niet welke licentie u moet selecteren? Welke rechten geeft een specifieke licentie? Hoewel niets het volledig lezen van een licentie kan vervangen vindt u hieronder enkele sites die informatie bieden enkele van de belangrijkste opensourcelicenties en die u kunnen helpen bij het vinden van de onderlinge verschillen. Deze sites dienen uitsluitend voor uw gemak en als referentie voor persoonlijk gebruik. Deze informatie is geen juridisch advies en moet ook niet als zodanig worden beschouwd. Mozilla biedt geen garanties en is niet verantwoordelijk voor de inhoud van deze sites of uw vertrouwen daarin.
+</p>
+<dl>
+ <dt>
+ <a href="http://www.mozilla.org/MPL/">http://www.mozilla.org/MPL/</a>
+ </dt>
+ <dd>
+ In aanvulling op de volledige tekst van de Mozilla Public License (&#8220;MPL&#8221;) geeft dit ook een verkorte versie van de MPL en <abbr title="Frequently Asked Questions">veelgestelde vragen</abbr> om u te helpen als u code onder deze licentie wilt gebruiken of verspreiden.
+ </dd>
+ <dt>
+ <a href="http://developer.kde.org/documentation/licensing/licenses_summary.html">
+ http://developer.kde.org/documentation/licensing/licenses_summary.html
+ </a>
+ </dt>
+ <dd>
+ Een tabel met een samenvatting en vergelijking van hoe enkele van de belangrijkste opensourcelicenties omgaan met distributies, specifieke softwarekoppeling en herverspreiding van code met wijzigingen.
+ </dd>
+ <dt>
+ <a href="http://www.fsf.org/licensing/licenses/">
+ http://www.fsf.org/licensing/licenses/
+ </a>
+ </dt>
+ <dd>
+ Free Software Foundation biedt korte samenvattingen van de belangrijkste opensourcelicenties, inclusief de vraag of de licentie een licentie van gratis software is of een licentie voor kopiëren. Bevat ook een discussie over wat een licentie van gratis software is of een licentie voor kopiëren precies is (bijv. een licentie voor kopiëren is een algemene methode om een programma of ander werk gratis te maken en vereist dat alle aangepaste en uitgebreide versies van het programma ook gratis zijn.)
+ </dd>
+ <dt>
+ <a href="http://www.opensource.org/licenses/category">
+ http://www.opensource.org/licenses/category
+ </a>
+ </dt>
+ <dd>
+ Open Source Initiative biedt de voorwaarden van enkele van de belangrijkste opensourcelicenties.
+ </dd>
+ <dt>
+ <a href="http://en.wikipedia.org/wiki/Open_source_license">
+ http://en.wikipedia.org/wiki/Open_source_license
+ </a>
+ </dt>
+ <dd>
+ Wikipedia-discussie of BSD-achtige licenties.
+ </dd>
+</dl>
diff --git a/site/app/locale/nl/pages/error404.thtml b/site/app/locale/nl/pages/error404.thtml
new file mode 100644
index 0000000..016f14b
--- /dev/null
+++ b/site/app/locale/nl/pages/error404.thtml
@@ -0,0 +1,16 @@
+<h1>Het spijt ons, maar we kunnen niet vinden waar u naar zoekt.</h1>
+
+<p>De door u aangevraagde pagina of bestand is niet aangetroffen op onze site. Mogelijk hebt u op een verouderde koppeling geklikt, of het adres verkeerd ingetypt.</p>
+
+<ul>
+<li>Als u het adres hebt ingetypt, controleer dan de spelling nog eens.</li>
+<li>Als u een koppeling ergens vandaan hebt gevolgd, laat dit ons dan weten via <a href="mailto:webmaster@mozilla.com" title="Page Not Found on Mozilla.com">webmaster@mozilla.com</a>. Vertel ons waar u vandaan kwam en wat u zocht, en we zullen proberen het probleem op te lossen.</li>
+</ul>
+
+<p>Of u kunt gewoon naar wat populaire pagina’s op onze website springen.</p>
+
+<ul>
+<li>Bent u geïnteresseerd in een <a href="%1$s">lijst met populaire add-ons</a>?</li>
+<li>Wilt u naar <a href="%2$s">add-ons zoeken</a>? U kunt naar de <a href="%2$s">zoekpagina</a> gaan of gewoon bovenstaand zoekveld gebruiken.</li>
+<li>Als u liever opnieuw begint, ga dan gewoon naar de <a href="%3$s">add-ons startpagina</a>.</li>
+</ul>
diff --git a/site/app/locale/nl/pages/faq.thtml b/site/app/locale/nl/pages/faq.thtml
new file mode 100644
index 0000000..4aa37c4
--- /dev/null
+++ b/site/app/locale/nl/pages/faq.thtml
@@ -0,0 +1,65 @@
+<h1>Veelgestelde vragen</h1>
+
+<p>Deze veelgestelde vragen voor de <a href="http://addons.mozilla.org">AMO site</a> beschrijft een paar onderwerpen die momenteel niet zijn opgenomen op de Firefox-ondersteuningswebsite. De Ondersteuningswebsite bevat een introductie over <a href="http://support.mozilla.com/nl/kb/Firefox+aanpassen+met+add-ons">het aanpassen van Firefox met add-ons</a> en artikelen over:</p>
+
+<ul>
+ <li> Problemen oplossen bij <a href="http://support.mozilla.com/nl/kb/Unable+to+install+add-ons">installatie van add-ons</a>, <a href="http://support.mozilla.com/nl/kb/Troubleshooting+plugins">plug-ins</a> en <a href="http://support.mozilla.com/nl/kb/Troubleshooting+extensions+and+themes">algemene onderwerpen</a>.</li>
+ <li> <a href="http://support.mozilla.com/kb/Uninstalling+add-ons">Hoe u add-ons kunt deïnstalleren</a> en <a href="http://support.mozilla.com/kb/Cannot+uninstall+an+add-on">probleemoplossing bij deïnstallatie</a>.</li>
+ <li> <a href="http://support.mozilla.com/kb/Gray+bar+below+the+status+bar">Omgaan met problematische add-ons / Probleem van de grijze balk</a></li>
+</ul>
+
+<p></p>
+
+<h2>Vragen over add-ons</h2>
+<dl class="faq">
+<dt>Wat is een add-on?</dt>
+<dd>Met add-ons kunt u functies toevoegen die niet bij de standaardtoepassing horen. Thema’s wijzigen de weergave zonder de functionaliteit te wijzigen. Zoekplug-ins en Woordenboeken/Taalpakketten voegen extra zoekmachines en taalondersteuning toe. Extensies voegen uitgebreidere functies toe aan de browser; sommige voegen eenvoudige werkbalken toe terwijl andere een hele reeks aan nieuwe functies kunnen toevoegen.</dd>
+
+<dt>Zijn add-ons eenvoudig te installeren?</dt>
+<dd>Ja! Add-ons zijn heel eenvoudig te installeren. Ze zijn in het algemeen veel kleiner dan een normale toepassing en zijn snel te downloaden. Als een add-on u niet bevalt is deze net zo eenvoudig te verwijderen of uit te schakelen. Daarnaast zal Firefox u informeren als er een update beschikbaar is voor één van uw add-ons, waarna u kunt upgraden met één klik.</dd>
+
+<dt>Hoe beheer ik een add-on?</dt>
+<dd>Ga in Firefox naar “Add-ons†in het menu Extra om Thema’s en Extensies te beheren. Als uw extensie speciale opties kent kunt u deze zien in de sectie Extensies van het Add-onsvenster. Van daaruit kunt u ook add-ons uitschakelen en deïnstalleren. Woordenboeken worden geïnstalleerd als extensies. Zoekplug-ins kunnen worden beheerd in de Zoekbalk.</dd>
+
+<dt>Kunnen add-ons Firefox langzamer maken?</dt>
+<dd>In de meeste gevallen zorgen add-ons niet voor een merkbare vertraging van Firefox. Aangezien het toepassingen zijn kunnen sommige echter de prestaties van Firefox beïnvloeden, afhankelijk van uw systeeminstellingen. Als u vermoedt dat een add-on de manier waarop Firefox draait op uw machine beïnvloedt, probeer dan deze eens uit te schakelen.</dd>
+
+<dt>Waarom zou ik een add-on uitschakelen?</dt>
+<dd>Door uitschakelen van een add-on wordt deze niet geladen wanneer u Firefox start, maar de add-on of de instellingen worden niet verwijderd. Door de add-on weer in te schakelen wordt deze weer teruggebracht in de staat voordat u de add-on uitschakelde. Voor add-ons die u wilt uitzetten zonder verwijderen is uitschakelen dé manier.</dd>
+
+<dt>Hoe maak ik een back-up van alle add-ons en thema’s die ik heb geïnstalleerd?</dt>
+<dd>U kunt een back-up maken van uw profielmap waardoor u ook een back-up maakt van uw add-ons en thema’s. Een externe toepassing zoals MozBackup kan u hierbij helpen.</dd>
+</dl>
+
+<h2>Websitevragen</h2>
+<dl class="faq">
+<dt>Ik zie diverse add-ons met dezelfde mogelijkheden. Hoe beslis ik welke de beste is?</dt>
+<dd>In het algemeen kunt u kijken naar beoordelingen en aantal downloads en krijgt u daardoor al een aardig idee. Goede add-ons worden meestal meer gedownload dan slechte. Het kan echter ook makkelijk zijn om beide add-ons te installeren en daarna te beslissen welke u wilt gebruiken. Misschien wilt u ze beide wel!</dd>
+
+<dt>Ik zie een geweldige add-on maar er staat dat deze alleen compatibel is met Firefox 2.x. Kan ik deze toch in Firefox 3.x installeren?</dt>
+<dd>In het algemeen niet. Firefox 3.x heeft een aantal nieuwe functies en het overgrote deel van de add-onontwikkelaars heeft zijn add-ons bijgewerkt om 3.x te ondersteunen. Als de add-on alleen Firefox 2 ondersteunt zoek dan eens anar de titel van de add-on. In veel gevallen is er een nieuwe versie die Firefox 3 ondersteunt met dezelfde of een vergelijkbare titel.</dd>
+
+<dt>Ik heb een nieuw thema geïnstalleerd maar wil graag het standaardthema van Firefox weer terug. Hoe doe ik dat?</dt>
+<dd>Ga naar “Add-ons†in het menu Extra. Klik op de sectie “Thema’s†en daar kunt u het standaardthema selecteren, of elk ander thema dat u hebt geïnstalleerd.</dd>
+
+<dt>Moet ik als ik een probleem met een add-on heb contact opnemen met Mozilla?</dt>
+<dd>Add-ons, een paar uitzonderingen daargelaten, worden gemaakt door de gemeenschap en niet door Mozilla. Het beste wat u kunt doen is rechtstreeks met uw vraag contact opnemen met de ontwikkelaar. Om contactinformatie van een ontwikkelaar te vinden kunt u op diens naam in de bijregel op de pagina van de add-on klikken.</dd>
+
+<dt>Hoe worden add-ons beoordeeld?</dt>
+<dd>Publieke add-ons worden beoordeeld door ons toegewijde en getalenteerde team van editors. Zij beoordelen de code van alle publieke add-ons en testen deze ook om er zeker van te zijn dat deze goed worden beschreven.</dd>
+
+<dt>Ik heb bijgewerkt naar Firefox 3.5 maar mijn add-on werkt niet meer? Hoe kan dat?</dt>
+<dd>De meeste add-ons zijn nu compatibel met Firefox 3.5, en elke dag groeit hun aantal. Als uw add-on werkte op 3.0 maar niet op 3.1 bestaat de kans dat er al aan gewerkt wordt. Wanneer de add-on wordt bijgewerkt zal Firefox u hiervan een bericht geven.</dd>
+
+<dt id="experimental-addons">Wat zijn experimentele add-ons?</dt>
+ <p>Experimentele add-ons zijn nieuwere add-ons die nog niet door ons publieke beoordelingsproces zijn gegaan. Veel van deze add-ons zijn prototypes. Omdat ze nog niet zijn getest door ons team van editors zijn ze mogelijk alfa, beta of preproductie in kwaliteit, prestaties en functies.</p>
+ <p>U dient voorzichtig te zijn bij het installeren van experimentele add-ons, aangezien ze nog niet zijn getest door een editor en mogelijk uw computerconfiguratie kunnen beschadigen.</p>
+</dd>
+
+<dt id="recognizing-experimental-addons">Hoe herken ik een experimentele add-on wanneer ik deze op de site zie?</dt>
+<dd>Experimentele add-ons zijn gemarkeerd met een label “experimenteel†en tonen een waarschuwing wanneer u ze installeert.</dd>
+
+<dt>Wat zijn Aanbevolen add-ons?</dt>
+<dd>Het AMO-team beveelt een aantal add-ons aan die samen enkele van de beste add-ons vormen in termen van nut en ervaring. Deze Aanbevolen add-ons verschijnen op de pagina’s van de individuele categorieën. Enkele van deze add-ons worden ook op de startpagina van AMO weergegeven als Aanbevolen add-ons. Dit is geenszins een volledige lijst, en we werken de lijst maandelijks bij om zodoende onze gebruikers een verse set van add-ons te kunnen tonen. Wat zaken die we overwegen bij het aanbevelen van add-ons: kwaliteit, populariteit, uniciteit en of de add-on al door iemand is aanbevolen.</dd>
+
+</dl> \ No newline at end of file
diff --git a/site/app/locale/nl/pages/nomination.thtml b/site/app/locale/nl/pages/nomination.thtml
new file mode 100644
index 0000000..c91d7da
--- /dev/null
+++ b/site/app/locale/nl/pages/nomination.thtml
@@ -0,0 +1,10 @@
+<p>Een add-on die zich momenteel in de sandbox bevindt kan worden voorgedragen om op de publieke site te worden getoond en beschikbaar te worden gesteld aan alle gebruikers nadat deze is beoordeeld door een redacteur. Merk voor de beste resultaten het volgende op:</p>
+<ul>
+ <li>Voorbeeldweergaveafbeeldingen zijn vereist voor thema's en sterk aanbevolen voor alle overige add-ontypes.</li>
+ <li>De add-on dient zich lang genoeg in de sandbox te hebben bevonden om beoordelingen en terugkoppeling van gebruikers te hebben verzameld. <b>Beoordelingen zijn noodzakelijk om naar de publieke kant doorgezet te kunnen worden.</b></li>
+ <li>Voor publieke add-ons ligt de kwaliteitslat hoger dan voor add-ons in de sandbox en deze zouden het web moeten verbeteren.</li>
+ <li>De volledige voordrachtscriteria zijn beschikbaar in ons <a href="%s">Add-onbeleid</a>.</li>
+</ul>
+<p>Als uw add-on aan bovenstaande criteria voldoet, kunt u deze voordragen door het onderstaande veld in te vullen. U zult via e-mail bericht ontvangen over de status van uw voordracht.</p>
+
+<p>Beschrijf om uw add-on voor te dragen hoe deze is getest (en dat de add-on geen onnodige fouten en waarschuwingen bevat) en hoe deze van nut is voor het wereldwijde web. U kunt ook koppelingen naar externe beoordelingen van uw add-on opnemen.</p>
diff --git a/site/app/locale/nl/pages/policy.thtml b/site/app/locale/nl/pages/policy.thtml
new file mode 100644
index 0000000..7016e00
--- /dev/null
+++ b/site/app/locale/nl/pages/policy.thtml
@@ -0,0 +1,110 @@
+<h1>Add-onbeleid</h1>
+
+<h2>Wat is de sandbox?</h2>
+<p>Zie de %s.</p>
+
+<h2>Welke add-ons bevinden zich in de sandbox?</h2>
+<p>De sandbox is om te beginnen de plaats waarin alle add-ons die worden gehost op AMO worden geplaatst. Hij bevat nieuwe versies van publieke add-ons en alle versies van add-ons die nog niet naar de publieke kant zijn doorgezet. Wanneer een nieuwe add-on, of een update voor een bestaande add-on, wordt ingediend bij AMO, wordt deze in de sandbox geplaatst.</p>
+
+<p>Sommige add-ons, en hun specifieke versies, worden naar de publieke kant doorgezet nadat het beoordelingsproces heeft uitgewezen dat ze klaar en passend zijn voor publicatie. Andere add-ons blijven voor onbepaalde tijd in de sandbox, waar ze beschikbaar zijn voor gebruikers die ervoor kiezen door de lijst van add-ons in de sandbox te kunnen bladeren en te experimenteren met de daar aanwezige software.</p>
+
+<h2>Hoe worden add-ons publiek?</h2>
+
+<p>Add-ons worden beoordeeld door AMO-gebruikers die ervoor kiezen de sandbox te bekijken en daar aangetroffen pakketten te testen. De beoordelingen die AMO-gebruikers schrijven geven aan of een add-on voldoende nuttig is, goed genoeg is geschreven en voldoende gepolijst om gepresenteerd te worden aan alle gebruikers van Firefox. Deze beoordelingen, mogelijk in aanvulling tot andere beoordelingen en inspecties door het AMO-team, worden gebruikt om vast te stellen of een bepaalde add-on gepubliceerd kan worden, of er nog wat werk aan de polijsting nodig is voor een betere zichtbaarheid, of dat de add-on niet geschikt is voor publicatie op de AMO-site buiten de sandbox.</p>
+
+<h2>Hoe krijg ik mijn add-on gepromoveerd naar de publieke status?</h2>
+
+<p>Als u van mening bent dat uw add-on (en uw gedrag!) aan de criteria voor een publieke add-on voldoen, kunt u deze voordragen vanuit Ontwikkelaarshulpmiddelen.</p>
+
+<h2>Wat zijn de criteria voor publieke add-ons?</h2>
+
+<p>Een add-on die wordt gepubliceerd op AMO moet van hoge kwaliteit zijn en gebruikers een verbeterde webervaring bieden. Wij kijken naar de volgende zaken tijdens de besluitvorming of een add-on geschikt is voor de publieke kant van AMO:</p>
+
+<h3>Geeft u antwoord?</h3>
+
+<p>We verwachten dat een schrijver die zijn/haar add-on aan de vele gebruikers van Firefox aanbiedt reageert op probleemrapportages, zijn/haar contactinformatie onderhoudt en zijn/haar add-on zo spoedig mogelijk bijwerkt om bij te blijven bij nieuwe Firefox-releases en wijzigingen in het beleid van AMO. Dit betekent niet dat u dient te antwoorden op elke vraag die iemand stelt in de discussies, of dat u elke fout dient te repareren, maar we verwachten wel dat u reageert op zaken op een wijze die toepasselijk is voor de ernst van de aangelegenheid.</p>
+
+<h3>Is de add-on helder en duidelijk beschreven?</h3>
+
+<p>Het is voor ons zeer belangrijk dat gebruikers krijgen wat ze verwachten wanneer ze een nieuwe add-on uitproberen. Uw beschrijving dient details te geven over wat de add-on doet, hoe een gebruiker hier gebruik van kan maken, en wat de gebruiker mag verwachten als de add-on wordt geïnstalleerd. Koppelingen naar externe documenten voor gedetailleerde instructies zijn prima, maar de beschrijving zelf dient de basisprincipes te beschrijven en gebruikers het vertrouwen te geven dat ze weten wat ze krijgen.</p>
+
+<p>Het is ook belangrijk dat u versieopmerkingen over verbeteringen en wijzigingen bijhoudt wanneer dit relevantie heeft. Gebruikers zouden moeten kunnen zien wat er nieuw is in een add-on die ze eerder hebben geprobeerd, en moeten op de hoogte worden gebracht van wijzigingen die mogelijk gevolg hebben voor hun huidige gebruik van de add-on wanneer ze deze bijwerken. (Op dit moment zien gebruikers de versieopmerkingen niet wanneer ze bericht krijgen van een update binnen de browser, maar we werken er aan om dit op te lossen. Als u de versieopmerkingen ook bijhoudt, zullen uw gebruikers hiervan enorm profiteren voor- en nadat die oplossing er is.)</p>
+
+<h3>Zijn alle zaken die betrekking hebben op privacy en beveiliging duidelijk uitgelegd?</h3>
+
+<p>Dit is een aspect van een duidelijke en heldere beschrijving, maar van zo’n belang dat we vonden dat een speciale vermelding op zijn plaats is. Veel zeer nuttige en goed geschreven add-ons manipuleren op enigerlei wijze gebruikersgegevens, of kunnen beveiligingsrisico’s met zich meebrengen bij verkeerd gebruik; ze zijn welkom op de publieke kant van AMO, maar ze moeten aan gebruikers volledig duidelijk maken met welke risico’s ze te maken kunnen krijgen, en wat ze kunnen doen om zichzelf te beschermen.</p>
+
+<h3>Is de add-on goed getest, en zitten er geen duidelijke of ernstige fouten in?</h3>
+
+<p>Een belangrijk iets waar we naar kijken wanneer we overwegen een add-on te publiceren is of de beoordelingen in de sandbox aangeven dat de add-on grondig is getest, en dat er geen serieuze problemen of een negatieve invloed op de browser zijn. Als beoordelaars problemen als grote performance-issues, crashes, regelmatig terugkerende problemen bij het gebruik van de functionaliteit van de add-on, of spammen van berichten naar de foutconsole rapporteren, dient u deze rapporten ter harte te nemen en uw add-on opnieuw voor te dragen nadat u de problemen naar uw beste vermogen hebt geadresseerd. We verwachten geen ideale optimalisatie of een foutloze add-on -- Firefox zelf wordt constant verbeterd op dit vlak -- maar we willen wel dat u zich redelijkerwijs inspant om negatieve kanten te minimaliseren, en restpunten duidelijk te benoemen als gebruikers erdoor verrast kunnen worden.</p>
+
+<p>Als uw add-on buiten het AMO Sandboxproces is getest, zoals door een groep gebruikers van uw dienst of een eigen kwaliteitsteam, kunt u dat het beste aangeven in uw voordrachtbericht. Het helpt ons bij het vaststellen wat het niveau van de tests is geweest, en kan helpen uw add-on sneller op de site te krijgen.</p>
+
+<h3>Behandelen zowel de add-on als de schrijver de gebruiker met respect?</h3>
+
+<p>Uw software mag de gebruiker niet onnodig verstoren, proberen deze te misleiden, of enige activiteit proberen te verbergen voor de gebruiker. Gebruikers (of zelfs niet-gebruikers) zijn soms grof in hun commentaar, en hoewel we ons best doen om dergelijke berichten eruit te filteren als ze aan ons worden gerapporteerd verwachten we wel dat schrijvers vermijden zelf grof terug te slaan.</p>
+
+<h3>Is de add-on nuttig voor een voldoende grote groep gebruikers van Firefox?</h3>
+
+<p>Uw add-on hoeft niet de volgende Greasemonkey of FireBug te zijn, maar als deze alleen maar nuttig is voor personen binnen uw bedrijf of leden van een kleine webgemeenschap kan het zo zijn dat we vinden dat het (nog) niet gepast is te publiceren voor alle gebruikers van Firefox.</p>
+
+<p>Wij zijn constant op zoek naar manieren om de organisatie van de site te verbeteren, om zo add-ons beter onder te brengen die een voorbeeld vormen op andere wijzen, maar die zijn gericht op slechts een kleine gemeenschap van potentiële gebruikers. Het correct categoriseren en onderhouden van de metadata van uw add-on helpt ons uit te vinden hoe we meer van dergelijke add-ons kunnen presenteren aan de personen die er het meeste baat bij hebben.</p>
+
+<p>Als uw add-on alleen maar bladwijzers biedt of andere eenvoudige toegang tot uw site is deze waarschijnlijk niet geschikt voor de publieke kant van de site. Zoals de rest van het Mozilla project houden we van webtoepassingen en nieuwe webdiensten, maar Firefox add-ons dienen een verbeterde surfervaring voor de gebruiker te bieden en niet slechts een manier om een nieuwe site of dienst te promoten door vermelding op AMO. Als de beschrijving van uw add-on meer over de dienst gaat dan over de verbeteringen voor de surfervaring van de gebruiker zit u waarschijnlijk niet op het juiste spoor.</p>
+
+<h3>Is de add-on vrij van niet-toegestane handelsmerken of auteursrechten?</h3>
+
+<p>Hoewel u mogelijk geen kwade bedoelingen heeft voor de houder van een handelsmerk of de eigenaar van werk waarop auteursrecht rust, kunnen wij geen add-ons accepteren die inbreuk maken op handelsmerken of auteursrechten. Als u geen toestemming hebt voor het gebruik van naam of afbeelding onder handelsmerk, dien dan a.u.b. uw add-on niet in bij AMO. Als uw add-on code gebruikt waarop auteursrecht van iemand anders rust, en u hebt geen toestemming om dit te gebruiken in uw add-on, dien dan a.u.b. uw add-on niet in bij AMO. (Als de houder van een handelsmerk of auteursrecht bezwaar maakt tegen het gebruik van diens handelsmerk, zullen we hoogstwaarschijnlijk dit verzoek om verwijdering laten beoordelen door een jurist, en we zullen de add-on verwijderen als dit juridisch noodzakelijk blijkt. Dit is een duur proces in termen van hulpbronnen voor het project, inclusief tijd en geld, dus we vragen u om dit te respecteren en niet onnodig moeilijkheden te veroorzaken.)</p>
+
+<p>Als u niet zeker weet of de naam van uw add-on, of het gebruik van iets er in, publicatie op de site kan verhinderen, kunt u amo-editors@mozilla.org om hulp vragen. BELANGRIJK: Merk a.u.b. op dat deze groep geen juridisch advies kan verstrekken, en dat zelfs als wij vinden dat uw uw gebruik acceptabel is, we die beslissing in het licht van klachten van rechtelijke houders en advies van een jurist kunnen heroverwegen.</p>
+
+<p>In termen van hergebruik van broncode van andere add-ons, als de schrijver niet duidelijk heeft aangegeven dat u toestemming hebt diens code in uw eigen werk te gebruiken -- zoals het plaatsen ervan onder een open source licentie -- dan dient u aan te nemen dat u dat recht niet hebt. U kunt contact opnemen met de schrijver om die toestemming te verkrijgen, maar we kunnen u geen speciale rechten toekennen alleen op basis van het feit dat het op AMO is gepubliceerd, of omdat de schrijver niet antwoordt op uw verzoek. (En, nogmaals, wij kunnen geen juridisch advies geven, alleen maar advies over hoe uw add-on zich waarschijnlijk verhoudt tot het beleid van de site.)</p>
+
+<p>Dit is ook van toepassing op de handelsmerken van de Mozilla Foundation, inclusief “Mozillaâ€, “Firefoxâ€, en “Thunderbirdâ€. Het beleid van Mozilla op het gebruik van handelsmerken is geschreven om te beschermen tegen misvattingen, en voorkomt dat de handelsmerken omver worden geworpen vanwege gebrek aan bescherming; respecteer a.u.b. de noodzaak voor dergelijke bescherming, en help ons enkele van de meest waardevolle onderdelen van de Mozilla Foundation te behouden.</p>
+
+<h2>Wat gebeurt er nadat ik iets heb voorgedragen?</h2>
+
+<p>Wanneer uw add-on eenmaal is voorgedragen wordt deze geëvalueerd door een team van AMO Editors volgens bovenstaande criteria. Als de add-on rijp wordt geacht voor publicatie, zal deze worden doorgezet naar de publieke kant na evaluatie, en u zult hiervan bericht krijgen via e-mail.</p>
+
+<p>Als wij denken dat de add-on op dit moment niet geschikt is voor de publieke kant van AMO, ontvangt u een e-mailbericht waarin wordt aangegeven waarom, en uw voordracht zal worden verwijderd uit de wachtrij. Als en wanneer u denkt dat u de aandachtspunten die in dat bericht worden genoemd hebt geadresseerd, en u wilt dat de add-on opnieuw wordt beoordeeld, dan kunt u dat naar eigen believen doen. Herhaalde voordrachten zonder duidelijke verbeteringen in de add-on worden niet toegejuicht, dus wees hier terughoudend mee; u maakt meer kans ons boos te maken dan moe.</p>
+
+<h2>Kan ik de add-on van iemand anders voordragen?</h2>
+
+<p>Op dit moment vragen wij dat de schrijver van een add-on alleen eigen werk voordraagt voor publicatie. We willen zeker zijn dat de schrijver zich bewust is van de verhoogde belangstelling en dat ze vinden dat de add-on in de huidige vorm een goede afspiegeling is van de kwaliteit van hun werk. Als u denkt dat een add-on voldoende gepolijst is, dat de schrijver de letter geest van het AMO-beleid volgt, en dat het een aanwinst is voor Firefox, onze gebruikers, en het web in zijn algemeenheid dat de add-on beschikbaar wordt gesteld aan bijna honderd miljoen gebruikers over de gehele wereld, voel u dan vrij om de schrijver van de add-on te stimuleren om hun geesteskind voor te dragen.</p>
+
+<h2>Mijn add-on staat al een hele tijd in de voordrachtsrij, hebben jullie een hekel aan me?</h2>
+
+<p>We hebben geen hekel aan u. We houden van add-onontwikkelaars, en we doen ons best om ze gelukkig en productief te houden, zodat gebruikers over de hele wereld kunnen profiteren van hun werk. Maar publicatie op AMO heeft juist waarde omdat we nauwkeurig zijn met wat daar gepubliceerd wordt, dus we kunnen ons niet haasten alleen maar om het proces sneller te laten verlopen. We begrijpen dat het frustrerend kan zijn om op de evaluatie van uw add-on te wachten, en we doorlooptijd zo kort mogelijk houden. Hoe meer personen zorgvuldige en heldere beoordelingen van add-ons in de sandbox ingeven, hoe makkelijker het is om deze evaluaties uit te voeren, dus u kunt ook overwegen aan die kant mee te helpen als u dat zou willen.</p>
+
+<h2>Ik heb een ernstige fout in mijn add-on ontdekt, en ik wil de reparatie hiervan snel opvoeren. Wat moet ik doen?</h2>
+
+<p>Als er een ernstige fout (beveiliging, stabiliteit, groot functionaliteitsprobleem) in een add-on bestaat waarvoor u direct een update wilt uitgeven, dient u dat aan te geven in de “Beoordelaar-opmerkingen†bij het indienen van de update -- en ook in de versie-opmerkingen, natuurlijk! U kunt wellicht wat bestaande gebruikers van uw add-on vragen de update te testen en hun bevindingen in detail in de sandbox te rapporteren. Binnenwippen op #addons op irc.mozilla.org kan helpen mensen bewust te maken van de situatie, maar wees a.u.b. geduldig en beleefd als u dat doet.</p>
+
+<p>Sla niet nodeloos alarm. We proberen updates met een hoge prioriteit zo snel mogelijk te verwerken, maar het kost ons tijd om andere voorgedragen add-ons of versies te evalueren, en vaak kost het ons slaap of tijd met onze familie en vrienden, dus we hebben het niet zo op personen die van dit mechanisme proberen te profiteren om zo “voor te dringenâ€. Als u niet zeker bent of u deze route moet volgen, kan vragen op #addons op irc.mozilla.org wellicht helpen in die beslissing.
+
+<h2>Ik vind dat ik onjuist ben behandeld bij de evaluatie van mijn add-on. Wat moet ik doen?</h2>
+
+<p>Als u vindt dat uw add-on onjuist is geëvalueerd, en dat op onjuiste gronden de publieke status is geweigerd, kunt u een e-mail naar amo-editors@mozilla.org sturen met uw onderbouwing. Wees a.u.b. beleefd en helder in uw e-mail, en vergeet niet specifieke informatie te geven over hoe de add-on verkeerd is beoordeeld.</p>
+
+<p>(Als u *alle* opgenoemde problemen in uw e-mailbericht hebt opgelost, moet u niet in beroep gaan tegen de evaluatie, maar dient u de add-on voor te dragen voor herbeoordeling via Ontwikkelaarshulpmiddelen.)</p>
+
+<h2>Mijn add-on was gepubliceerd, en nu bevindt deze zich in de sandbox. Wat is er gebeurd? </h2>
+
+<p>Als een add-on niet meer aan de criteria voor de publieke kant van de site beantwoordt, kunnen we deze terugplaatsen in de sandbox. Tenzij juridische argumenten ons hierin tegenhouden, zullen we u via e-mail berichten als dit gebeurt, en de redenen ervoor aanduiden.</p>
+
+<p>Het is ook mogelijk dat u een fout in de site hebt gevonden, in geval waarvan u dit via Bugzilla moet rapporteren; gebruik “addons.mozilla.org†als product en “Publieke Pagina’s†als component voor uw rapport, en neem zo veel mogelijk details op.</p>
+
+<h2>Mijn add-on is publiek, en het lijkt erop dat deze erg populair is. Hoe kan ik op de lijst met aanbevolen add-ons komen?</h2>
+
+<p>Als u denkt dat uw add-on een lichtend voorbeeld is van de kracht van add-ons, dat deze de waarden van Mozilla voor het uitbreidbare en door gebruikers gecontroleerde web aantoont en uitbreidt, en dat deze een geweldige gebruikerservaring oplevert, dan kunt u vragen om te overwegen uw add-on toe te voegen aan de lijst met aanbevolen add-ons. Om dit te doen dient u een e-mail aan amo-editors@mozilla.org te sturen waarin u uitlegt waarom uw add-on zo geweldig is.</p>
+
+<p>Uw bericht dient <b>ten minste</b> informatie over deze zaken te bevatten:</p>
+<ul>
+<li>hoe de webervaring wordt verbeterd voor gebruikers</li>
+<li>hoe uw add-on geschikt is voor een groot deel van de gebruikers van Firefox</li>
+<li>hoe uw add-on de waarden van het Mozilla project aantoont en/of dient, in het bijzonder met betrekking tot het geven van controlemogelijkheden aan de gebruiker, bescherming van persoonsgegevens en beveiliging, algemene toegang tot het web, en open standaarden en gegevens</li>
+<li>hoe uw add-on afwijkt van andere vergelijkbare add-ons (zowel in positieve als in negatieve zin)</li>
+<li>welke reacties u hebt gekregen van gebruikers, beoordelaars, bloggers, astronauten, of uw huisdieren, zowel positief als negatief</li>
+</ul>
+
+<p>Hoe vollediger de informatie die u aandraagt in uw aanvraag, hoe waarschijnlijker het is dat wij het verzoek honoreren, hoewel zelfs een schitterend geschreven en breed inzetbare toepassing geen garantie is voor plaatsing op de lijst met aanbevolen extensies. Uiteindelijk moet die lijst worden -- en dat gebeurt ook -- onderhouden ter discretie van Mozilla, en gebruikerservaring en bescherming staan boven alle andere zaken.</p>
diff --git a/site/app/locale/nl/pages/reviewguide.thtml b/site/app/locale/nl/pages/reviewguide.thtml
new file mode 100644
index 0000000..a51c175
--- /dev/null
+++ b/site/app/locale/nl/pages/reviewguide.thtml
@@ -0,0 +1,66 @@
+<h1>Beoordelingsrichtlijnen</h1>
+<p>Add-onbeoordelingen zijn voor add-on-sitegebruikers een manier om hun mening te geven over de add-ons die ze hebben geïnstalleerd en gebruikt. Editors behouden zich het recht voor om beoordelingen die niet conform deze richtlijnen zijn opgesteld te weigeren of te verwijderen.</p>
+
+<div class="corner-box">
+ <h2>Enkele tips voor het schrijven van een goede beoordeling</h2>
+
+<h3><b>Doen:</b></h3>
+<ul>
+<li>Schrijf alsof u een vriend vertelt over uw ervaring met de add-on.</li>
+<li>Houd beoordelingen bondig en eenvoudig te begrijpen.</li>
+<li>Geef specifieke en behulpzame details. Bijvoorbeeld:
+<ul>
+ <li>Werkte de add-on als verwacht?</li>
+ <li>Welke functies vond u prettig en minder prettig?</li>
+ <li>Was de add-on nuttig?</li>
+ <li>Was de add-on eenvoudig in gebruik?</li>
+ <li>Blijft u deze add-on gebruiken?</li>
+</ul></li>
+
+<li>Lees uw beoordeling nog eens goed door voordat u deze indient om genante typ- of grammaticale fouten te voorkomen.</li>
+
+<li>Vermijd verwijzingen naar tijdelijke onderwerpen of zaken, aangezien beoordelingen geruime tijd op de site kunnen blijven staan.</li>
+</ul>
+
+<h3><b>Niet doen:</b></h3>
+<ul>
+<li>Simpele beoordelingen als “Geweldig!â€, “prachtigâ€, of “waardeloos†indienen zonder nadere toelichting.</li>
+<li>Fouten of problemen melden in beoordelingen. Gebruik hiervoor de beschikbare ondersteuningsopties voor de add-on.</li>
+<li>Schrijven van beoordelingen voor add-ons die u niet persoonlijk hebt gebruikt.</li>
+<li>Gebruik van lastering, sexueel getinte taal of taal die als haatdragend kan worden bestempeld.</li>
+<li>Opnemen van HTML, koppelingen naar malware, broncode of codegedeeltes. Beoordelingen zijn uitsluitend als tekst bedoeld.</li>
+<li>Foutieve verklaringen afleggen, add-onschrijvers kleineren of ze persoonlijk beledigen.</li>
+<li>Beoordelingen gebruiken als manier om ondersteuning te vragen voor een specifieke versie van Firefox (of een andere toepassing).</li>
+<li>Uw eigen e-mailadres, telefoonnummer, of andere persoonlijke details opnemen.</li>
+<li>Beoordelingen indienen voor een add-on die door u of uw organisatie is geschreven of wordt vertegenwoordigd.</li>
+</ul>
+</div>
+
+<div class="corner-box">
+ <h2>Richtlijnen voor waarderen van add-ons</h2>
+
+<p>Add-onwaarderingen dienen eerlijk te zijn en een goede indicatie van de kwaliteit en het nut te geven. Geef niet domweg 5 sterren als u de add-on waardeert of 1 ster als u deze niet waardeert. Consistente waardering is een belangrijk onderdeel van een beoordeling.</p>
+
+<ul>
+<li><b>5 sterren: Uitstekend.</b> Doet niet alleen wat het beweert, maar is duidelijk nuttiger dan vele andere add-ons. Deze add-on gaat u waarschijnlijk vaak gebruiken en is van harte aan te bevelen.</li>
+<li><b>4 sterren: Goed.</b> Nuttig en eenvoudig in gebruik, hoewel niet noodzakelijkerwijs bijzonder. Deze add-on is aan te bevelen maar is mogelijk voor sommigen nuttiger dan voor anderen.</li>
+<li><b>3 sterren: Acceptabel.</b> Kan wat designproblemen en/of wat ontbrekende functies hebben. Problemen zijn echter niet serieus genoeg om de add-on af te raden, en sommige gebruikers hebben er wellicht iets aan. Aanbevolen voor diegenen die de add-on nodig hebben en hem eens uit willen proberen.</li>
+<li><b>2 sterren: Matig.</b> Add-on is kwalitatief of qua bruikbaarheid onder de maat, of doet gewoon niet wat het beweert. U raadt gebruik van deze add-on af, opmerkend dat een enkeling er wellicht nog wat aan heeft.</li>
+<li><b>1 ster: Slecht.</b> De add-on werkt niet correct of is gewoon nutteloos. U kunt geen reden bedenken waarom iemand deze add-on zou willen gebruiken en raadt anderen aan deze add-on te mijden.</li>
+</ul>
+
+<p>Er is niets mis met het geven van een perfecte of een verschrikkelijke beoordeling aan een add-on, maar vertel wel hoe u tot deze waardering komt. De sterren betekenen niets als u ons niet vertelt waarom.</p>
+</div>
+
+<div class="corner-box">
+ <h2>Veelgestelde vragen over beoordelingen</h2>
+
+<h3>Hoe kan ik een problematische beoordeling rapporteren?</h3>
+<p>Rapporteer of markeer twijfelachtige beoordelingen door te klikken op “Deze beoordeling rapporteren†en de beoordeling zal nader worden bekeken. Editors zullen de beoordelingsrichtlijnen toepassen om te evalueren of de beoordeling moet worden verwijderd of teruggezet op de site.</p>
+
+<h3>Ik ben een add-onschrijver, kan ik reageren op beoordelingen?</h3>
+<p>Ja, add-onschrijvers kunnen eenmalig antwoorden op beoordelingen. Aanvullende discussie of opvolging dient plaats te vinden op een ondersteuningsforum of in een discussiegroep.</p>
+
+<h3>Ik ben een add-onschrijver, kan ik ongunstige beoordelingen of waarderingen verwijderen?</h3>
+<p>In het algemeen niet. Maar als de beoordeling niet volgens bovenstaande richtlijnen is opgesteld, kunt u klikken op “Deze beoordeling rapporteren†om een editor er nader naar te laten kijken. Als een beoordeling een klacht inhield die niet langer geldig is dankzij een nieuwe versie van uw add-on kunnen we overwegen de beoordeling te verwijderen. Stuur uw gedetailleerde verzoek naar amo-editors@mozilla.org.</p>
+</div> \ No newline at end of file
diff --git a/site/app/locale/nl/pages/sandbox.thtml b/site/app/locale/nl/pages/sandbox.thtml
new file mode 100644
index 0000000..97c7dd3
--- /dev/null
+++ b/site/app/locale/nl/pages/sandbox.thtml
@@ -0,0 +1,13 @@
+<h1>Sandbox Beoordelingssysteem</h1>
+<h2>Wat is de sandbox?</h2>
+<p>De sandbox is een gebied voor ervaren gebruikers om add-ons te testen voordat ze worden vrijgegeven voor algemeen gebruik. Om toegang te verkrijgen tot de sandbox dient u dit in te schakelen in uw accountinstellingen. U dient voorzichtig te zijn met het installeren van add-ons in de sandbox, aangezien ze nog niet zijn getest door een editor en mogelijk schade aan uw computer kunnen toebrengen.</p>
+
+<h2>Hoe krijg ik mijn add-on aan de publieke kant?</h2>
+<!-- To localize the flowchart image, see http://wiki.mozilla.org/Update:Remora_Sandbox_Flowchart -->
+<div style="text-align: center;">%s</div>
+<ol>
+ <li><b>Dien uw add-on in via Ontwikkelaarshulpmiddelen.</b> Uw add-on zal onmiddellijk verschijnen in de “Sandbox†van Mozilla Add-ons, waar ervaren gebruikers deze zullen testen en terugkoppeling zullen geven. Om de sandbox te kunnen zien dient u dit in te schakelen in uw accountinstellingen.</li>
+ <li><b>Draag uw add-on voor om publiek gemaakt te worden.</b> Vanuit Ontwikkelaarshulpmiddelen is er een koppeling om uw add-on voor te dragen. Na de voordracht zal uw add-on verschijnen in de Editor Voordrachtrij voor beoordeling.</li>
+ <li><b>Een editor beoordeelt uw add-on.</b> Een Mozilla Add-ons editor zal uw add-on installeren en testen of deze werkt. De editor zal ook naar beoordelingen kijken die sandboxtesters hebben ingegeven.</li>
+ <li><b>Uw add-on wordt naar de publieke kant doorgezet of blijft in de sandbox.</b> De editor zal ofwel uw add-on naar de publieke kant doorzetten of deze in de sandbox laten staan. Als de add-on in de sandbox blijft, kunt u deze opnieuw voordragen nadat u wijzigingen hebt aangebracht die de editor heeft voorgesteld in opmerkingen. Als de add-on wordt doorgezet naar de publieke kant, zullen toekomstige versies van uw add-on in de sandbox verschijnen totdat ze zijn beoordeeld door een editor en naar de publieke kant zijn doorgezet. Wanneer uw add-on eenmaal publiek is, is het niet nodig om deze weer voor te dragen - toekomstige versies worden automatisch in de wachtrij geplaatst voor beoordeling.</li>
+</ol> \ No newline at end of file
diff --git a/site/app/locale/nl/pages/statistics_help.thtml b/site/app/locale/nl/pages/statistics_help.thtml
new file mode 100644
index 0000000..d64cad2
--- /dev/null
+++ b/site/app/locale/nl/pages/statistics_help.thtml
@@ -0,0 +1,7 @@
+<h3>Help</h3>
+<p>De Statistieksectie geeft download- en updatepinggegevens weer die zijn verzameld voor uw add-on.</p>
+<h4>Downloads</h4>
+<p>Het aantal downloads wordt dagelijks bijgewerkt en bevat alleen eerste downloads van de add-on, geen updates.</p>
+
+<h4>Updatepings</h4>
+<p>Add-ons die worden gedownload van deze site controleren dagelijks op updates, en het totale aantal van deze updatepings staat bekend als Actieve dagelijkse gebruikers. Actieve dagelijkse gebruikers (ADG) kan worden opgesplitst naar add-onversie, besturingssysteem, add-onstatus en toepassing.</p> \ No newline at end of file
diff --git a/site/app/locale/nl/pages/submission_help.thtml b/site/app/locale/nl/pages/submission_help.thtml
new file mode 100644
index 0000000..a92b9b7
--- /dev/null
+++ b/site/app/locale/nl/pages/submission_help.thtml
@@ -0,0 +1,35 @@
+<h1>Hulp bij indienen</h1>
+verplichte velden zijn <b>vet</b> weergegeven. Optionele velden zijn <i>schuingedrukt</i>.
+<h2 id="step1">Stap 1: Uploaden</h2>
+<ul class="submissionHelp">
+ <li><span class="required">Add-ontype</span> - Het add-ontype zal standaard worden vastgesteld op basis van het ge-uploade bestand. Dit veld zou u niet moeten hoeven veranderen.</li>
+ <li><span class="required">Add-onbestand</span> - Het pakketbestand voor uw add-on, compleet met een install.rdf bestand. Als het bestand alleen maar werkt met een specifiek platform, kunt u door selectie van dat platform meerdere bestanden tegelijk uploaden.</li>
+ <li><span class="optional">Pictogrambestand</span> - Het pictogrambestand wordt naast de add-onnaam op de presentatiepagina getoond en wordt weergegeven tijdens installatie van de add-on. De grootte wordt automatisch naar 32x32 pixels gebracht, waarbij de hoogte:breedte verhouding in stand blijft.</li>
+ <li><span class="required">Standaardlocale</span> - De standaardlocale van een add-on is de hoofdlocale. Als de door een gebruiker toegepaste locale niet beschikbaar is voor de add-on zullen vertalingen terugvallen naar de standaardlocale.</li>
+ <li><span class="optional">Beoordelingen van mijn huidige add-oninformatie overslaan</span> - Als u een bestaande add-on bijwerkt, zal dit veld verschijnen. Door het veld aan te vinken slaat u stap 3 over waarin u versiespecifieke informatie kunt ingeven.</li>
+</ul>
+
+<h2 id="step2">Stap 2: Add-ondetails</h2>
+<ul class="submissionHelp">
+ <li><span class="required">Naam</span> - Naam van de add-on in de standaardlocale.</li>
+ <li><span class="required">Schrijvers</span> - Alle gebruikers die de rechten hebben om de lijstweergave van de add-on te wijzigen zullen als schrijvers worden weergegeven op de presentatiepagina.</li>
+ <li><span class="required">Categorieën</span> - Categorieën die van toepassing zijn op de add-on.</li>
+ <li><span class="optional">Homepage</span> - De website van de add-on in de standaardlocale.</li>
+ <li><span class="required">Samenvatting</span> - Een korte samenvatting van de add-on in de standaardlocale. Dit veld kent een maximum van 250 karakters, en zal verschijnen in de presentatiepagina van de add-on en in zoek-/bladerresultaten.</li>
+ <li><span class="required">Beschrijving</span> - Een beschrijving van de add-on in de standaardlocale. Deze zal verschijnen op de presentatiepagina van de add-on onder de samenvatting.</li>
+ <li><span class="optional">EULA</span> - De gebruiksrechtovereenkomst (End User License Agreement) die gebruikers moeten accepteren voordat ze de add-on downloaden, in de standaardlocale.</li>
+ <li><span class="optional">Privacybeleid</span> - Het privacybeleid dat behoort bij de add-on, in de standaardlocale. Het privacybeleid legt uit wat er gebeurt met de persoonlijke informatie van de eindgebruiker, en er wordt naar gekoppeld naast de installatieknop op de presentatiepagina van een add-on. Aanvullende informatie over wat in een Privacybeleid moet wordt opgenomen en of uw add-on er één nodig heeft is te vinden in het <a href="%s">Add-onbeleid</a>.</li>
+ <li><span class="optional">Gebruikers toestaan om de bronbestanden online te bekijken</span> - Door dit veld aan te vinken kunnen de bronbestanden van uw add-on online bekijken.</li>
+ <li><span class="optional">Dit is een pre-release</span> - Het aanvinken van dit veld geeft aan dat de add-on een pre-release of “beta†versie is. Pre-release add-ons moeten in de sandbox blijven en kunnen niet worden voorgedragen voor publicatie totdat deze markering is verwijderd.</li>
+ <li><span class="optional">Dit is een site-specifieke add-on</span> - Door dit veld aan te vinken geeft u aan dat de add-on specifiek voor een website is, zoals een add-on die het voorkomen van een bepaalde website wijzigt of inhoud van een specifieke website weergeeft. Dit veld is nuttig voor editors en kan worden gebruikt om toekomstige zoekopdrachten uit te filteren.</li>
+ <li><span class="optional">Deze add-on vereist externe software</span> - Dit veld geeft aan dat de add-on externe software nodig heeft. Dit veld is nuttig voor editors en kan worden gebruikt om toekomstige zoekopdrachten uit te filteren.</li>
+</ul>
+
+<h2 id="step3">Stap 3: Versiedetails</h2>
+<ul class="submissionHelp">
+ <li><span class="required optional">Versieopmerkingen</span> - Een samenvatting of lijst van veranderingen in deze versie. Dit is optioneel voor nieuw ingediende add-ons, maar een vereiste voor updates.</li>
+ <li><span class="optional">Opmerkingen voor de beoordelaar</span> - Dit veld wordt gebruikt om informatie door te geven aan editors die uw add-on zullen beoordelen. Testaccountinformatie and speciale opmerkingen moeten hier worden vermeld.</li>
+</ul>
+
+<h2 id="step4">Stap 4: Localisatie</h2>
+Dit is waar add-onvelden gelocaliseerd kunnen worden naar alle ondersteunde locales. Klik eenvoudigweg op een locale om vertalingen in te geven. \ No newline at end of file
diff --git a/site/app/locale/pl/LC_MESSAGES/messages.mo b/site/app/locale/pl/LC_MESSAGES/messages.mo
new file mode 100644
index 0000000..ee38b0f
--- /dev/null
+++ b/site/app/locale/pl/LC_MESSAGES/messages.mo
Binary files differ
diff --git a/site/app/locale/pl/LC_MESSAGES/messages.po b/site/app/locale/pl/LC_MESSAGES/messages.po
new file mode 100644
index 0000000..b13f6c3
--- /dev/null
+++ b/site/app/locale/pl/LC_MESSAGES/messages.po
@@ -0,0 +1,7084 @@
+# Language pl-PL translations for addons.mozilla.org package.
+# Copyright (C) 2009 THE addons.mozilla.org'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the addons.mozilla.org package.
+# Automatically generated, 2009.
+#
+# Zbigniew Braniecki <zbraniecki+amo@aviary.pl>, 2007.
+# Hubert Gajewski <hubert@hubertgajewski.com>, 2007.
+# Marek Stępień <mstepien@aviary.pl>, 2007.
+# Wojciech Szczęsny <wszczesny@aviary.pl>, 2008-2009.
+# Leszek Życzkowski <lzyczkowski@aviary.pl>, 2008-2009.
+msgid ""
+msgstr ""
+"Project-Id-Version: addons\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2009-01-16 11:45-0800\n"
+"PO-Revision-Date: 2009-06-05 23:56+0100\n"
+"Last-Translator: Wojciech Szczęsny <witia@aviary.pl>\n"
+"Language-Team: Polish <pl@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=3; plural=n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;X-Generator: KBabel 1.11.4\n"
+
+#: views/addons/policy.thtml:98
+msgid "a_cancel_installation"
+msgstr "Anuluj proces instalacji"
+
+#. This is the text that appears on buttons to download add-ons.
+#. %$1s is an optional string that only appears if the add-on is only available for
+#. a certain platform. Examples: (Windows) or (Linux)
+#. Note that the parentheses are included in the string. :(
+#: views/elements/amo2009/install.thtml:126
+#: views/elements/amo2009/install.thtml:227
+#: views/elements/amo2009/install.thtml:257
+#: views/elements/amo2009/install.thtml:300
+#: views/elements/amo2009/install.thtml:312
+#: views/elements/install.thtml:73
+#: views/elements/install.thtml:181
+#: views/elements/install.thtml:205
+#: views/elements/install.thtml:248
+#: views/elements/install.thtml:260
+#: views/addons/plugins.thtml:66
+#: views/addons/plugins.thtml:76
+#: views/addons/plugins.thtml:86
+#: views/addons/plugins.thtml:96
+#: views/addons/plugins.thtml:119
+#, php-format
+msgid "a_download"
+msgstr "Pobierz dodatek %s"
+
+#: views/addons/policy.thtml:72
+msgid "a_eula_download"
+msgstr "Akceptuj i pobierz"
+
+#: views/addons/policy.thtml:74
+msgid "a_eula_install"
+msgstr "Akceptuj i instaluj"
+
+#: views/elements/header.thtml:76
+#: views/elements/header.thtml:82
+#: views/api/api_addon.thtml:55
+#: views/api/collections_feed.thtml:75
+#: views/sharing_api/addon.thtml:64
+msgid "a_header_public"
+msgstr "Upubliczniony"
+
+#: views/elements/header.thtml:58
+#: views/elements/header.thtml:75
+#: views/elements/header.thtml:80
+#: views/api/api_addon.thtml:57
+#: views/api/collections_feed.thtml:77
+#: views/sharing_api/addon.thtml:66
+msgid "a_header_sandbox"
+msgstr "Piaskownica"
+
+#. %s is a date in the _('date') format
+#: views/elements/amo2009/homepage_addon.thtml:115
+#: views/elements/addon_listitem.thtml:122
+#: views/elements/feature.thtml:106
+#: views/addons/display.thtml:104
+#: views/addons/browse_thumbs.thtml:73
+msgid "addon_detail_last_updated"
+msgstr "Zaktualizowano %s"
+
+#. %s is the version of the add-on. Example: 3.2a1
+#: views/elements/amo2009/addon_version_detail.thtml:51
+#: views/elements/addon_version_detail.thtml:51
+#, php-format
+msgid "addon_display_header_version"
+msgstr "Wersja %s"
+
+#: views/addons/browse_thumbs.thtml:80
+msgid "addon_downloads"
+msgstr "pobrań"
+
+#: views/addons/display.thtml:147
+msgid "addon_downloads_total"
+msgstr "wszystkich pobrań"
+
+#: views/elements/amo2009/homepage_addon.thtml:106
+#: views/elements/addon_listitem.thtml:115
+#: views/elements/feature.thtml:101
+#: views/addons/category_landing.thtml:157
+#: views/addons/display.thtml:146
+#: views/addons/browse_thumbs.thtml:80
+msgid "addon_downloads_weekly"
+msgstr "pobrań tygodniowo"
+
+#. %1 is the add-on count, %2 the category name
+#: views/addons/browse_thumbs.thtml:104
+#: views/addons/browse.thtml:60
+#, php-format
+msgid "addon_list_category_totalcount"
+msgid_plural "addon_list_category_totalcount"
+msgstr[0] "%1$s dodatek"
+msgstr[1] "%1$s dodatki"
+msgstr[2] "%1$s dodatków"
+
+#: views/elements/amo2009/addon_list_options.thtml:103
+#: views/elements/pagination.thtml:67
+#: views/elements/addon_list_options.thtml:94
+msgid "addon_list_perpage"
+msgstr "na stronie"
+
+#: views/elements/amo2009/addon_list_options.thtml:84
+#: views/elements/addon_list_options.thtml:98
+msgid "addon_list_sortby"
+msgstr "Sortuj wg:"
+
+#: views/helpers/addons_html.php:568
+#: views/elements/amo2009/install.thtml:321
+#: views/elements/feature.thtml:89
+msgid "addon_listitem_flag_experimental"
+msgstr "eksperymentalny"
+
+#: views/helpers/addons_html.php:570
+msgid "addon_listitem_flag_recommended"
+msgstr "polecany"
+
+#. %1 is the add-on name, %2 is the platform
+#: views/pages/js_constants.js.thtml:66
+msgid "addon_not_available_for_platform"
+msgstr "Dodatek %1$s nie jest dostępny dla systemu %2$s."
+
+#. %1 is the add-on name
+#: views/addons/policy.thtml:101
+#: views/addons/previews.thtml:60
+#: views/addons/versions.thtml:130
+#: views/reviews/flag.thtml:61
+#: views/reviews/add.thtml:114
+#: views/reviews/display.thtml:216
+#: views/reviews/review_added.thtml:57
+#, php-format
+msgid "addon_review_a_back_to_addon_x"
+msgstr "Wróć do %1$s…"
+
+#. %1 is the add-on name
+#: views/reviews/flag.thtml:60
+#: views/reviews/add.thtml:113
+#: views/reviews/review_added.thtml:56
+#, php-format
+msgid "addon_review_a_back_to_reviews"
+msgstr "Wróć do recenzji…"
+
+#: views/reviews/add.thtml:85
+msgid "addon_review_add_rating_field"
+msgstr "Ocena:"
+
+#: views/reviews/add.thtml:102
+msgid "addon_review_add_review_field"
+msgstr "Recenzja:"
+
+#: views/reviews/add.thtml:107
+msgid "addon_review_add_submit"
+msgstr "Wyślij recenzję"
+
+#. %s is the name of the add-on
+#: views/reviews/add.thtml:51
+#, php-format
+msgid "addon_review_add_title"
+msgstr "Dodaj recenzjÄ™ dla: %s"
+
+#: views/reviews/add.thtml:78
+msgid "addon_review_add_title_field"
+msgstr "Tytuł/podsumowanie:"
+
+#: views/reviews/display.thtml:77
+#: views/reviews/display.thtml:161
+msgid "addon_review_admin_delete"
+msgstr "Usuń"
+
+#: views/reviews/display.thtml:76
+msgid "addon_review_author_reply_link"
+msgstr "Odpowiedz"
+
+#: views/reviews/delete.thtml:62
+msgid "addon_review_confirm_delete"
+msgstr "Czy na pewno chcesz usunąć tę recenzję?"
+
+#: views/reviews/delete.thtml:63
+msgid "addon_review_confirm_no"
+msgstr "Nie"
+
+#: views/reviews/delete.thtml:64
+msgid "addon_review_confirm_yes"
+msgstr "Tak"
+
+#: views/reviews/delete.thtml:48
+msgid "addon_review_delete_header"
+msgstr "Usuń recenzję"
+
+#: controllers/reviews_controller.php:449
+msgid "addon_review_deleted_successfully"
+msgstr "Recenzja została usunięta."
+
+#. %s is the name of the add-on
+#: views/reviews/add.thtml:51
+#, php-format
+msgid "addon_review_edit_title"
+msgstr "Edytuj recenzjÄ™ dla: %s"
+
+#. %1 is the count of characters entered as notes for the review flag reason.
+#: controllers/reviews_controller.php:539
+msgid "addon_review_flag_error_other_length"
+msgstr "Problem z oznaczaniem recenzji etykietą. Długość informacji dla oznaczonej etykietą recenzji powinna zawierać się pomiędzy 10 a 100 znakami. Wprowadzono %1$s znaków."
+
+#. Removing an extra comma
+#: views/reviews/review_added.thtml:53
+msgid "addon_review_in_moderation"
+msgstr "Uwaga: przed publikacjÄ… recenzja zostanie sprawdzona przez moderatora."
+
+#: views/reviews/add.thtml:57
+msgid "addon_review_in_reply_to"
+msgstr "Odpowiedź programisty na:"
+
+#. %1 is the review count, %2 is the nickname or full name of the user.
+#: views/reviews/display.thtml:131
+#, php-format
+msgid "addon_review_others_by_user"
+msgid_plural "addon_review_others_by_user"
+msgstr[0] "Zobacz poprzedniÄ… recenzjÄ™ tego dodatku wystawionÄ… przez %2$s."
+msgstr[1] "Zobacz %1$s poprzednie recenzje tego dodatku wystawione przez %2$s."
+msgstr[2] "Zobacz %1$s poprzednich recenzji tego dodatku wystawionych przez %2$s."
+
+#. %1 is the add-on name
+#: controllers/reviews_controller.php:201
+#: controllers/reviews_controller.php:250
+#: controllers/reviews_controller.php:345
+#: controllers/reviews_controller.php:424
+#, php-format
+msgid "addon_review_pagetitle"
+msgstr "Recenzje dla: %s"
+
+#. %1 is the user, %2 is the (localized) date
+#: views/reviews/display.thtml:160
+#, php-format
+msgid "addon_review_reply_on_x_by_y"
+msgstr "Odpowiedź użytkownika %1$s wysłana %2$s"
+
+#: views/reviews/display.thtml:157
+msgid "addon_review_reply_prefix"
+msgstr "Odpowiedź programisty:"
+
+#: views/reviews/review_added.thtml:51
+msgid "addon_review_saved_successfully"
+msgstr "Recenzja została zapisana. Dziękujemy!"
+
+#: views/addons/display.thtml:354
+#: views/reviews/display.thtml:72
+msgid "addon_reviewed_by_u_on_d"
+msgstr "dodana przez %1$s – %2$s"
+
+#. %1 is the user, %2 is the (localized) date, %3 is the rating
+#: views/editors/reviews_queue.thtml:57
+#: views/editors/reviews_queue.thtml:68
+#: views/reviews/add.thtml:63
+#: views/reviews/delete.thtml:54
+#, php-format
+msgid "addon_reviewed_on_x_rated_y"
+msgstr "przez użytkownika %1$s, dnia %2$s (oceniony na %3$s)"
+
+#: views/elements/amo2009/addon_version_detail.thtml:52
+#: views/elements/addon_version_detail.thtml:52
+msgid "addon_version_permalink"
+msgstr "Stały odnośnik do tej wersji"
+
+#. %1 is the current Application name (e.g. Firefox)
+#. %2 is the Application's version number
+#: views/addons/versions.thtml:140
+msgid "addon_versions_getlatestversion"
+msgstr "Najnowsza wersja kompatybilna z programem %1$s %2$s"
+
+#: views/addons/display.thtml:447
+msgid "addons_author_addons_submit"
+msgstr "Przejdź"
+
+#: views/elements/amo2009/homepage_addon.thtml:100
+#: views/elements/feature.thtml:95
+msgid "addons_author_tooltip"
+msgstr "Zobacz profil autora"
+
+#. %1 is the name of the Application (eg. Firefox)
+#: controllers/addons_controller.php:1296
+msgid "addons_browse_all_themes_title"
+msgstr "Przeglądaj wszystkie motywy :: %1$s – dodatki"
+
+#. %s is the name of the category
+#: controllers/addons_controller.php:1016
+#, php-format
+msgid "addons_browse_browse_category"
+msgstr "PrzeglÄ…dasz %s"
+
+#. %1 is the name of the theme category (eg. Modern)
+#. %2 is the name of the Application (eg. Firefox)
+#: controllers/addons_controller.php:664
+msgid "addons_browse_categories_header_theme"
+msgstr "Przeglądaj motywy z kategorii %1$s :: %2$s – dodatki"
+
+#: views/addons/display.thtml:249
+msgid "addons_display_a_license_what"
+msgstr "Co to jest?"
+
+#: views/reviews/display.thtml:222
+msgid "addons_display_add_review"
+msgstr "Dodaj recenzjÄ™"
+
+#: views/addons/display.thtml:294
+msgid "addons_display_advanced_details"
+msgstr "Informacje dodatkowe"
+
+#: views/addons/display.thtml:98
+msgid "addons_display_categories"
+msgstr "Kategorie"
+
+#: views/addons/display.thtml:482
+msgid "addons_display_collection_add"
+msgstr "Dodaj do kolekcji:"
+
+#: views/addons/display.thtml:491
+msgid "addons_display_collection_add_new"
+msgstr "Nowa kolekcja…"
+
+#: views/addons/display.thtml:487
+msgid "addons_display_collection_add_select_one"
+msgstr "Wybierz kolekcję…"
+
+#: views/addons/display.thtml:493
+msgid "addons_display_collection_add_submit"
+msgstr "Dodaj"
+
+#. %1$s is the add-on name
+#. %2$s is the collection name, linked to the collection's page
+#: views/pages/js_constants.js.thtml:103
+#: views/addons/display.thtml:61
+msgid "addons_display_collection_publish_success"
+msgstr "Dodatek %1$s został dodany do kolekcji %2$s."
+
+#: views/addons/display.thtml:483
+msgid "addons_display_collection_whatsthis"
+msgstr "Co to jest?"
+
+#. %1$s is a number
+#: views/addons/display.thtml:473
+msgid "addons_display_collections_more"
+msgid_plural "addons_display_collections_more"
+msgstr[0] "i %1$s kolekcja więcej"
+msgstr[1] "i %1$s kolekcje więcej"
+msgstr[2] "i %1$s kolekcji więcej"
+
+#: views/addons/display.thtml:403
+msgid "addons_display_detailed_review"
+msgstr "Szczegółowa recenzja"
+
+#: views/reviews/add.thtml:89
+#: views/reviews/add.thtml:90
+msgid "addons_display_dont_like_it"
+msgstr "Nie podoba mi siÄ™"
+
+#: views/reviews/display.thtml:220
+msgid "addons_display_edit_review"
+msgstr "Edytuj recenzjÄ™"
+
+#: views/addons/display.thtml:132
+msgid "addons_display_has_privacy"
+msgstr "To rozszerzenie posiada politykę prywatności."
+
+#: views/reviews/add.thtml:87
+#: views/reviews/add.thtml:88
+msgid "addons_display_hate_it"
+msgstr "Nie cierpiÄ™ go"
+
+#: views/addons/display.thtml:462
+msgid "addons_display_header_collections"
+msgstr "Pokrewne kolekcje"
+
+#: views/addons/display.thtml:297
+msgid "addons_display_header_developer_comments"
+msgstr "Komentarze autora"
+
+#: views/addons/display.thtml:230
+msgid "addons_display_header_homepage"
+msgstr "Strona domowa"
+
+#: views/addons/display.thtml:247
+#: views/addons/versions.thtml:110
+msgid "addons_display_header_license"
+msgstr "Licencja kodu źródłowego"
+
+#: views/addons/display.thtml:337
+msgid "addons_display_header_reviews"
+msgstr "Recenzje"
+
+#: views/addons/display.thtml:261
+msgid "addons_display_header_support"
+msgstr "Wsparcie techniczne"
+
+#: views/reviews/add.thtml:91
+#: views/reviews/add.thtml:92
+msgid "addons_display_like_it"
+msgstr "Podoba mi siÄ™"
+
+#: views/addons/display.thtml:210
+msgid "addons_display_long_description"
+msgstr "Szczegółowy opis"
+
+#: views/reviews/add.thtml:95
+#: views/reviews/add.thtml:96
+msgid "addons_display_love_it"
+msgstr "Uwielbiam go"
+
+#: views/addons/display.thtml:178
+msgid "addons_display_more_images"
+msgstr "Obrazki"
+
+#: views/addons/display.thtml:465
+msgid "addons_display_nocollections"
+msgstr "Tego dodatku nie ma jeszcze w żadnej kolekcji."
+
+#. %1$s is either an author's name or a comma separated list of authors. Using
+#. the list doesn't make sense in the English plural form so we ignore the
+#. variable.
+#: views/addons/display.thtml:436
+msgid "addons_display_other_addons_by"
+msgid_plural "addons_display_other_addons_by"
+msgstr[0] "Inne dodatki autorstwa %1$s"
+msgstr[1] "Inne dodatki tych autorów"
+msgstr[2] "Inne dodatki tych autorów"
+
+#. %s is the name of the add-on and the add-on section. Example:
+#. Some Add-on :: Firefox Add-ons
+#. This should not be concatenated in the code and should be fixed.
+#: controllers/addons_controller.php:141
+#: controllers/addons_controller.php:280
+#: controllers/addons_controller.php:1442
+#, php-format
+msgid "addons_display_pagetitle"
+msgstr "%s"
+
+#. %s is an email address
+#: views/addons/display.thtml:286
+#, php-format
+msgid "addons_display_paragraph_supportinfoemail"
+msgstr "Wsparcie techniczne dla tego rozszerzenia jest świadczone przez autora pod adresem %s"
+
+#. %$1s is a URL
+#. %$2s is an email address
+#: views/addons/display.thtml:269
+#, php-format
+msgid "addons_display_paragraph_supportinfoemailurl"
+msgstr "Wsparcie techniczne dla tego rozszerzenia jest świadczone przez autora na stronie %s lub przez wysłanie e-maila na adres %s"
+
+#. %s is a URL
+#: views/addons/display.thtml:278
+#, php-format
+msgid "addons_display_paragraph_supportinfourl"
+msgstr "Wsparcie techniczne dla tego rozszerzenia jest świadczone przez autora pod adresem %s "
+
+#: views/addons/display.thtml:383
+msgid "addons_display_rate_it"
+msgstr "Oceń dodatek"
+
+#: views/reviews/add.thtml:93
+#: views/reviews/add.thtml:94
+msgid "addons_display_really_like_it"
+msgstr "Bardzo mi siÄ™ podoba"
+
+#: views/addons/display.thtml:410
+msgid "addons_display_review_etiquette"
+msgstr "Prosimy nie zgłaszać błędów w recenzjach. Twój adres e-mail nie jest dostępny dla twórcy dodatku, a może on potrzebować kontaktu z Tobą, by rozwiązać problem."
+
+#. %1 is the review guidelines link
+#: views/addons/display.thtml:417
+msgid "addons_display_review_guidelines_link"
+msgstr "<a href=\"%s\">Wskazówki dla recenzentów</a>"
+
+#. %1 is the support section link
+#: views/addons/display.thtml:414
+msgid "addons_display_review_see_support"
+msgstr "Sprawdź w sekcji <a href=\"%1$s\">wsparcie techniczne</a>, gdzie można otrzymać pomoc dla rozszerzenia."
+
+#: views/addons/display.thtml:404
+msgid "addons_display_review_submit"
+msgstr "Zapisz"
+
+#: views/addons/display.thtml:430
+#, php-format
+msgid "addons_display_see_all_addons"
+msgstr "Wszystkie dodatki %1$s"
+
+#. %1 is the number of reviews
+#: views/addons/display.thtml:364
+#, php-format
+msgid "addons_display_see_all_reviews"
+msgstr "Zobacz wszystkie recenzje (%1$s)"
+
+#: views/addons/display.thtml:219
+msgid "addons_display_see_all_versions"
+msgstr "Zobacz wszystkie wersje"
+
+#: views/addons/display.thtml:321
+#: views/addons/versions.thtml:117
+msgid "addons_display_view_source"
+msgstr "Podgląd źródła"
+
+#: views/addons/display.thtml:324
+msgid "addons_display_view_stats"
+msgstr "Wyświetl statystyki"
+
+#: views/addons/display.thtml:376
+msgid "addons_display_what_do_you_think"
+msgstr "Co sÄ…dzisz o tym dodatku?"
+
+#: views/elements/app_compatibility.thtml:49
+msgid "addons_display_workswith"
+msgstr "Działa z:"
+
+#: views/addons/home.thtml:112
+msgid "addons_home_browse_new"
+msgstr "Najnowsze"
+
+#: views/addons/home.thtml:110
+msgid "addons_home_browse_popular"
+msgstr "Popularne"
+
+#: views/addons/home.thtml:108
+msgid "addons_home_browse_recommended"
+msgstr "Polecane"
+
+#: views/addons/home.thtml:127
+#: views/addons/home.thtml:134
+#: views/addons/home.thtml:141
+#: views/addons/home.thtml:148
+msgid "addons_home_browse_subscribe"
+msgstr "Subskrybuj"
+
+#: views/addons/home.thtml:101
+msgid "addons_home_browse_title"
+msgstr "Przejrzyj dodatki"
+
+#: views/addons/home.thtml:114
+msgid "addons_home_browse_updated"
+msgstr "Uaktualnione"
+
+#: views/elements/amo2009/homepage_addon.thtml:100
+#: views/elements/addon_discussionheader.thtml:83
+#: views/elements/addon_listitem.thtml:109
+#: views/elements/feature.thtml:95
+#: views/addons/category_landing.thtml:66
+#: views/addons/policy.thtml:57
+#: views/addons/display.thtml:70
+#: views/addons/home.thtml:178
+msgid "addons_home_by"
+msgstr "Autor: "
+
+#: views/addons/home.thtml:169
+msgid "addons_home_collection_popular_title"
+msgstr "Popularne kolekcje"
+
+#: views/elements/amo2009/categories.thtml:69
+#: views/addons/home.thtml:160
+msgid "addons_home_collections"
+msgstr "Kolekcje"
+
+#. %1$s is the count of addons in a collection
+#: views/elements/amo2009/collection_listing_item.thtml:51
+#: views/addons/home.thtml:185
+msgid "addons_home_collections_addon_count"
+msgid_plural "addons_home_collections_addon_count"
+msgstr[0] "<strong>%1$s</strong> dodatek"
+msgstr[1] "<strong>%1$s</strong> dodatki"
+msgstr[2] "<strong>%1$s</strong> dodatków"
+
+#: views/addons/home.thtml:196
+msgid "addons_home_collections_all"
+msgstr "Wszystkie kolekcje"
+
+#: views/addons/home.thtml:162
+msgid "addons_home_collections_intro"
+msgstr "Kolekcje są miejscem, gdzie można klasyfikować, miksować i dobierać dodatki. Subskrybuj kolekcje utworzone przez innych użytkowników lub utwórz własną."
+
+#. %1$s is the count of subscribers for a collection
+#: views/elements/amo2009/collection_listing_item.thtml:58
+#: views/collections/detail.thtml:96
+#: views/addons/home.thtml:189
+msgid "addons_home_collections_subscribers"
+msgid_plural "addons_home_collections_subscribers"
+msgstr[0] "<strong>%1$s</strong> subskrybent"
+msgstr[1] "<strong>%1$s</strong> subskrybentów"
+msgstr[2] "<strong>%1$s</strong> subskrybentów"
+
+#: views/addons/searchengines.thtml:54
+#: views/addons/themes_landing.thtml:49
+msgid "addons_home_feature_head"
+msgstr "Polecamy"
+
+#: controllers/search_controller.php:218
+#: controllers/addons_controller.php:176
+#: controllers/addons_controller.php:428
+#: controllers/addons_controller.php:671
+#: controllers/addons_controller.php:871
+#: controllers/addons_controller.php:1103
+#: controllers/addons_controller.php:1242
+#: controllers/addons_controller.php:1298
+#, php-format
+msgid "addons_home_header_details"
+msgstr "Dodatki rozszerzają możliwości programu %1$s, pozwalają dostosować go do swoich potrzeb. Rozejrzyj się wokół i rozbuduj program %1$s według własnego uznania."
+
+#. %1$s is the HTML collection name link.
+#: views/elements/amo2009/teaser_collections.thtml:107
+msgid "addons_home_introduction_collection_link"
+msgstr "Lubisz te dodatki? Poszukaj podobnych w kolekcji %1$s."
+
+#: views/elements/amo2009/teaser_collections.thtml:60
+msgid "addons_home_introduction_extras"
+msgstr "<strong>Ponad 5000 dodatków</strong>, które dostosowują Firefoksa do potrzeb użytkownika."
+
+#: views/elements/amo2009/teaser_collections.thtml:55
+msgid "addons_home_introduction_header"
+msgstr "Co to sÄ… dodatki?"
+
+#: views/elements/amo2009/teaser_collections.thtml:72
+msgid "addons_home_introduction_install"
+msgstr "<strong>Åatwe do zainstalowania</strong>, powiadamiajÄ… użytkownika, gdy jest dostÄ™pna ich aktualizacja."
+
+#: views/elements/amo2009/teaser_collections.thtml:45
+msgid "addons_home_introduction_name"
+msgstr "Wstęp"
+
+#: views/elements/amo2009/teaser_collections.thtml:66
+msgid "addons_home_introduction_themes"
+msgstr "Paski narzędzi, motywy i wyszukiwarki, które <strong>pomagają wykonać proste zadania.</strong>"
+
+#: views/addons/home.thtml:161
+msgid "addons_home_new_indicator"
+msgstr "Nowość!"
+
+#: views/elements/app_chooser.thtml:48
+#: views/layouts/amo2009.thtml:257
+msgid "addons_home_other_applications"
+msgstr "Inne programy"
+
+#. %1$s is the application the user is browsing. Examples: Thunderbird, Firefox,
+#. Sunbird
+#: views/pages/collector_faq.thtml:49
+#: views/pages/collector_firstrun.thtml:42
+#: views/pages/collector.thtml:46
+#: views/pages/collector_features.thtml:54
+#: controllers/developers_controller.php:87
+#: controllers/compatibility_controller.php:72
+#: controllers/components/simple_acl.php:81
+#: controllers/components/amo.php:607
+#: controllers/statistics_controller.php:60
+#: controllers/statistics_controller.php:240
+#: controllers/previews_controller.php:67
+#: controllers/users_controller.php:90
+#: controllers/users_controller.php:223
+#: controllers/users_controller.php:330
+#: controllers/users_controller.php:414
+#: controllers/users_controller.php:708
+#: controllers/users_controller.php:723
+#: controllers/reviews_controller.php:204
+#: controllers/reviews_controller.php:251
+#: controllers/reviews_controller.php:346
+#: controllers/reviews_controller.php:425
+#: controllers/search_controller.php:185
+#: controllers/search_controller.php:297
+#: controllers/search_controller.php:301
+#: controllers/addons_controller.php:147
+#: controllers/addons_controller.php:280
+#: controllers/addons_controller.php:370
+#: controllers/addons_controller.php:667
+#: controllers/addons_controller.php:874
+#: controllers/addons_controller.php:1019
+#: controllers/addons_controller.php:1034
+#: controllers/addons_controller.php:1101
+#: controllers/addons_controller.php:1121
+#: controllers/addons_controller.php:1240
+#: controllers/addons_controller.php:1357
+#: controllers/addons_controller.php:1364
+#: controllers/addons_controller.php:1442
+#: controllers/addons_controller.php:1477
+#: controllers/addons_controller.php:1538
+#: controllers/addons_controller.php:1543
+#: controllers/editors_controller.php:64
+#: controllers/pages_controller.php:132
+#: controllers/groups_controller.php:65
+#: controllers/groups_controller.php:71
+#: controllers/groups_controller.php:89
+#: controllers/groups_controller.php:111
+#: controllers/collections_controller.php:57
+#: controllers/collections_controller.php:121
+#: controllers/collections_controller.php:205
+#: controllers/collections_controller.php:365
+#: controllers/collections_controller.php:404
+#: controllers/collections_controller.php:466
+#: controllers/collections_controller.php:538
+#: controllers/collections_controller.php:828
+#: controllers/localizers_controller.php:72
+#, php-format
+msgid "addons_home_pagetitle"
+msgstr "Dodatki dla programu %1$s "
+
+#. %1$s is the number of addons downloaded
+#: views/addons/home.thtml:57
+#, php-format
+msgid "addons_home_stats_downloaded"
+msgid_plural "addons_home_stats_downloaded"
+msgstr[0] "<span>Dodatki pobrane:</span> <strong>%1$s</strong> "
+msgstr[1] "<span>Dodatki pobrane:</span> <strong>%1$s</strong> "
+msgstr[2] "<span>Dodatki pobrane:</span> <strong>%1$s</strong> "
+
+#. %1$s is the number of addons in use
+#: views/addons/home.thtml:63
+#, php-format
+msgid "addons_home_stats_inuse"
+msgid_plural "addons_home_stats_inuse"
+msgstr[0] "<span>Dodatki używane:</span> <strong>%1$s</strong>"
+msgstr[1] "<span>Dodatki używane:</span> <strong>%1$s</strong>"
+msgstr[2] "<span>Dodatki używane:</span> <strong>%1$s</strong>"
+
+#: views/addons/home.thtml:136
+msgid "addons_home_view_all_newest_title"
+msgstr "Wyświetl wszystkie"
+
+#: views/addons/home.thtml:129
+msgid "addons_home_view_all_popular_title"
+msgstr "Wyświetl wszystkie"
+
+#: views/addons/home.thtml:150
+msgid "addons_home_view_all_recommended_title"
+msgstr "Wyświetl wszystkie"
+
+#: views/addons/home.thtml:143
+msgid "addons_home_view_all_updated_title"
+msgstr "Wyświetl wszystkie"
+
+#: views/elements/amo2009/install.thtml:334
+#: views/elements/install.thtml:112
+msgid "addons_install_in_sunbird"
+msgstr "<ol><li>Kliknij poniższy odnoÅ›nik, by pobrać i zapisać plik.</li><li>W programie Mozilla Sunbird otwórz Dodatki z menu NarzÄ™dzia</li><li>NaciÅ›nij przycisk „Zainstalujâ€, znajdź i wybierz pobrany plik, i naciÅ›nij przycisk „OKâ€.</li></ol>"
+
+#: views/elements/amo2009/install.thtml:333
+#: views/elements/install.thtml:111
+msgid "addons_install_in_sunbird_title"
+msgstr "Instalacja w programie Sunbird"
+
+#: views/elements/amo2009/install.thtml:331
+#: views/elements/install.thtml:106
+msgid "addons_install_in_thunderbird"
+msgstr "<ol><li>Kliknij prawym przyciskiem myszy poniższy odnoÅ›nik i wybierz „Zapisz element docelowy jako…â€, by pobrać i zapisać ten plik na swoim twardym dysku.</li><li>W programie Mozilla Thunderbird otwórz Dodatki z menu NarzÄ™dzia.</li><li>NaciÅ›nij przycisk „Zainstaluj†i zlokalizuj/wybierz pobrany wczeÅ›niej plik, a nastÄ™pnie naciÅ›nij przycisk „OKâ€.</li></ol>"
+
+#: views/elements/amo2009/install.thtml:330
+#: views/elements/install.thtml:105
+msgid "addons_install_in_thunderbird_title"
+msgstr "Instalacja w Thunderbirdzie"
+
+#: views/elements/amo2009/addon_list_options.thtml:108
+#: views/elements/addon_list_options.thtml:105
+msgid "addons_options_show_experimental"
+msgstr "wyświetlaj dodatki eksperymentalne"
+
+#: views/elements/amo2009/addon_list_options.thtml:113
+#: views/elements/addon_list_options.thtml:109
+msgid "addons_options_submit"
+msgstr "Przejdź"
+
+#: views/addons/plugins.thtml:63
+#: views/addons/plugins.thtml:73
+#: views/addons/plugins.thtml:83
+#: views/addons/plugins.thtml:93
+#: views/addons/plugins.thtml:103
+#: views/addons/plugins.thtml:116
+#: views/addons/plugins.thtml:126
+msgid "addons_plugins_by"
+msgstr "Wydawca:"
+
+#: views/addons/plugins.thtml:107
+msgid "addons_plugins_for_linux"
+msgstr "dla Linuksa"
+
+#: views/addons/plugins.thtml:108
+#: views/addons/plugins.thtml:131
+msgid "addons_plugins_for_macosx"
+msgstr "dla Mac OS X"
+
+#: views/addons/plugins.thtml:106
+#: views/addons/plugins.thtml:129
+#: views/addons/plugins.thtml:130
+msgid "addons_plugins_for_windows"
+msgstr "dla Windows"
+
+#. %1$s is a URL
+#: views/addons/plugins.thtml:139
+#, php-format
+msgid "addons_plugins_looking_for_more"
+msgstr "Na tej stronie znajdują się jedynie najczęściej używane i najpopularniejsze wtyczki. Aby uzyskać więcej informacji o wtyczkach dostępnych dla przeglądarek opartych na Mozilli, odwiedź %1$s"
+
+#: views/addons/plugins.thtml:137
+msgid "addons_plugins_looking_for_plugin"
+msgstr "Szukasz wtyczki tutaj niewymienionej?"
+
+#: views/addons/plugins.thtml:58
+msgid "addons_plugins_main_description"
+msgstr "Wtyczki pomagają przeglądarce wykonywać pewne specyficzne funkcje, jak wyświetlanie specjalnych formatów graficznych lub odtwarzanie plików multimedialnych. Wtyczki nieco różnią się od rozszerzeń, które modyfikują lub dodają coś do istniejącej funkcjonalności."
+
+#. %1$s is the application name. Example: Firefox, Thunderbird, Sunbird
+#: controllers/addons_controller.php:1122
+#, php-format
+msgid "addons_plugins_main_header"
+msgstr "Często używane wtyczki dla programu %1$s"
+
+#: controllers/components/amo.php:698
+#: controllers/addons_controller.php:1121
+msgid "addons_plugins_pagetitle"
+msgstr "Wtyczki"
+
+#: views/addons/plugins.thtml:68
+#: views/addons/plugins.thtml:78
+#: views/addons/plugins.thtml:88
+#: views/addons/plugins.thtml:98
+#: views/addons/plugins.thtml:110
+#: views/addons/plugins.thtml:121
+#: views/addons/plugins.thtml:133
+msgid "addons_plugins_support_documentation"
+msgstr "Dokumentacja: "
+
+#. %s is the name of the add-on
+#: views/addons/policy.thtml:61
+#, php-format
+msgid "addons_policy_eula_require"
+msgstr "Przed kontynuowaniem instalacji %s wymaga zaakceptowania warunków poniższej licencji użytkownika (EULA)"
+
+#. %1 is the add-on name
+#: controllers/addons_controller.php:1476
+#, php-format
+msgid "addons_previews_pagetitle"
+msgstr "Obrazki dla: %s"
+
+#: views/addons/category_landing.thtml:135
+msgid "addons_recently_added"
+msgstr "Najnowsze"
+
+#: views/addons/recommended.thtml:51
+#: controllers/addons_controller.php:1365
+msgid "addons_recommended_introduction"
+msgstr "Wśród tylu wspaniałych dodatków znajdzie się coś dla każdego. Zacznij od wymienionych tutaj kilku najpopularniejszych. Dobrej zabawy!"
+
+#: controllers/addons_controller.php:1357
+#: controllers/addons_controller.php:1364
+msgid "addons_recommended_pagetitle"
+msgstr "Polecane dodatki"
+
+#: controllers/addons_controller.php:1360
+msgid "addons_recommended_title"
+msgstr "Polecane dodatki"
+
+#: views/addons/searchengines.thtml:136
+msgid "addons_searchengines_additional_resources"
+msgstr "Dodatkowe zasoby"
+
+#. link text devmo
+#: views/addons/searchengines.thtml:141
+msgid "addons_searchengines_devmo_link"
+msgstr "Mozilla Developer Center"
+
+#: views/pages/js_constants.js.thtml:67
+msgid "addons_searchengines_error_mozilla_browser_required"
+msgstr "Przepraszamy. Aby zainstalować wtyczkę wyszukiwarki, potrzebna jest przeglądarka oparta o Mozillę (tak jak np. Firefox)."
+
+#: views/addons/searchengines.thtml:49
+msgid "addons_searchengines_error_nojavascript"
+msgstr "Do instalacji wtyczek wymagany jest JavaScript, a wygląda na to, że jego obsługa jest wyłączona. Przed próbą instalacji jednej z poniższych wtyczek należy włączyć obsługę języka JavaScript."
+
+#. %1 is "make your own" link
+#. %2 is MDC link
+#: views/addons/searchengines.thtml:139
+msgid "addons_searchengines_learn_howto"
+msgstr "Dowiedz siÄ™, jak %1$s na stronie %2$s."
+
+#. link path to search plugins instructions, relative to devmo
+#: views/addons/searchengines.thtml:140
+msgid "addons_searchengines_makeyourown_href"
+msgstr "/pl/docs/Tworzenie_wtyczek_OpenSearch_dla_Firefoksa"
+
+#. link text for "make your own" (opensearch engine)
+#: views/addons/searchengines.thtml:140
+msgid "addons_searchengines_makeyourown_link"
+msgstr "stworzyć własną"
+
+#. %1 is the link to mycroft.mozdev.org
+#: views/addons/searchengines.thtml:138
+msgid "addons_searchengines_more"
+msgstr "Więcej wyszukiwarek znajdziesz na stronie %1$s"
+
+#. link text to mycroft.mozdev.org
+#: views/addons/searchengines.thtml:138
+msgid "addons_searchengines_mycroft_link"
+msgstr "mycroft.mozdev.org"
+
+#: controllers/addons_controller.php:1100
+#: controllers/addons_controller.php:1110
+msgid "addons_searchengines_pagetitle"
+msgstr "Wyszukiwarki"
+
+#: views/addons/searchengines.thtml:143
+msgid "addons_searchengines_thanks"
+msgstr "Specjalne podziękowania dla projektu Mycroft za ich pracę nad wyszukiwarkami do Firefoksa."
+
+#: views/addons/display.thtml:154
+msgid "addons_share_button_text"
+msgstr "Udostępnij"
+
+#: controllers/addons_controller.php:89
+msgid "addons_share_label_delicious"
+msgstr "Dodaj do Delicious"
+
+#: controllers/addons_controller.php:77
+msgid "addons_share_label_digg"
+msgstr "Opublikuj na Digg!"
+
+#: controllers/addons_controller.php:83
+msgid "addons_share_label_facebook"
+msgstr "Opublikuj na Facebook"
+
+#: controllers/addons_controller.php:101
+msgid "addons_share_label_friendfeed"
+msgstr "Udostępnij na FriendFeed"
+
+#: controllers/addons_controller.php:95
+msgid "addons_share_label_myspace"
+msgstr "Opublikuj na MySpace"
+
+#: controllers/components/amo.php:201
+#: controllers/components/amo.php:229
+msgid "addons_status_disabled"
+msgstr "wyłączony"
+
+#: controllers/components/amo.php:191
+#: controllers/components/amo.php:224
+msgid "addons_status_incomplete"
+msgstr "wersja niekompletna"
+
+#: controllers/components/amo.php:197
+#: controllers/components/amo.php:227
+msgid "addons_status_nominated"
+msgstr "w piaskownicy – nominowany do upublicznienia"
+
+#: views/pages/js_constants.js.thtml:80
+#: controllers/components/amo.php:195
+#: controllers/components/amo.php:226
+msgid "addons_status_pending"
+msgstr "w piaskownicy – w trakcie recenzowania"
+
+#: views/pages/js_constants.js.thtml:78
+#: controllers/components/amo.php:199
+#: controllers/components/amo.php:228
+msgid "addons_status_public"
+msgstr "upubliczniony"
+
+#: views/pages/js_constants.js.thtml:79
+#: controllers/components/amo.php:193
+#: controllers/components/amo.php:225
+msgid "addons_status_sandbox"
+msgstr "w piaskownicy"
+
+#: controllers/components/amo.php:203
+msgid "addons_status_unknown"
+msgstr "nieznany"
+
+#: views/elements/amo2009/teaser_collections.thtml:91
+#: views/elements/amo2009/homepage_addon.thtml:99
+#: views/elements/feature.thtml:94
+msgid "addons_title_tooltip"
+msgstr "Dowiedz się więcej o tym dodatku"
+
+#: views/addons/category_landing.thtml:151
+msgid "addons_top_downloads"
+msgstr "Najczęściej pobierane"
+
+#: views/addons/category_landing.thtml:165
+msgid "addons_top_rated"
+msgstr "Najwyżej oceniane"
+
+#: views/addons/versions.thtml:62
+msgid "addons_versions_careful"
+msgstr "Zachowaj ostrożność, gdy używasz starych wersji"
+
+#: views/addons/versions.thtml:63
+msgid "addons_versions_careful_introduction"
+msgstr "Wersje te są wyświetlane w celach informacyjnych i testowych. Używaj zawsze najnowszych wersji danego dodatku."
+
+#: controllers/addons_controller.php:1549
+msgid "addons_versions_history"
+msgstr "Historia wersji z informacjami o zmianach"
+
+#. %1$s is the add-on name
+#: controllers/addons_controller.php:1535
+#, php-format
+msgid "addons_versions_pagetitle"
+msgstr "%1$s – historia wersji"
+
+#: controllers/groups_controller.php:71
+msgid "admin_group_add_pagetitle"
+msgstr "Dodaj grupÄ™"
+
+#: controllers/groups_controller.php:111
+msgid "admin_group_delete_pagetitle"
+msgstr "Usuń grupę"
+
+#. %s is a number to identify the group
+#: controllers/groups_controller.php:117
+#, php-format
+msgid "admin_group_deleted"
+msgstr "Grupa o id %s została usunięta"
+
+#: controllers/groups_controller.php:89
+msgid "admin_group_edit_pagetitle"
+msgstr "Edytuj grupÄ™"
+
+#: controllers/groups_controller.php:92
+#: controllers/groups_controller.php:113
+msgid "admin_group_error_invalid_id"
+msgstr "Błędne id dla grupy"
+
+#: controllers/groups_controller.php:65
+msgid "admin_group_pagetitle"
+msgstr "Administracja grupÄ…"
+
+#: controllers/groups_controller.php:77
+#: controllers/groups_controller.php:99
+msgid "admin_group_saved"
+msgstr "Grupa została zapisana"
+
+#: views/elements/amo2009/search.thtml:257
+#: views/elements/search.thtml:239
+msgid "advanced_search_form"
+msgstr "Zaawansowane"
+
+#: views/elements/amo2009/search.thtml:126
+#: views/elements/search.thtml:125
+msgid "advanced_search_form_any_time"
+msgstr "Kiedykolwiek"
+
+#: views/elements/amo2009/search.thtml:97
+#: views/elements/amo2009/search.thtml:110
+#: views/elements/search.thtml:96
+#: views/elements/search.thtml:109
+msgid "advanced_search_form_any_type"
+msgstr "Każdy"
+
+#: views/elements/amo2009/search.thtml:275
+#: views/elements/search.thtml:254
+msgid "advanced_search_form_any_version"
+msgstr "Każda"
+
+#: views/elements/amo2009/search.thtml:217
+#: views/elements/search.thtml:212
+msgid "advanced_search_form_application"
+msgstr "Program"
+
+#: views/elements/amo2009/search.thtml:143
+#: views/elements/search.thtml:142
+msgid "advanced_search_form_keyword_match"
+msgstr "SÅ‚owa kluczowego"
+
+#: views/elements/amo2009/search.thtml:251
+#: views/elements/search.thtml:225
+msgid "advanced_search_form_lastupdate"
+msgstr "Uaktualniono"
+
+#: views/elements/amo2009/search.thtml:145
+#: views/elements/search.thtml:144
+msgid "advanced_search_form_name"
+msgstr "Nazwy"
+
+#: views/elements/amo2009/search.thtml:144
+#: views/elements/search.thtml:143
+msgid "advanced_search_form_newest"
+msgstr "Daty dodania"
+
+#: views/elements/amo2009/search.thtml:130
+#: views/elements/search.thtml:129
+msgid "advanced_search_form_past_3_months"
+msgstr "W ostatnich 3 miesiÄ…cach"
+
+#: views/elements/amo2009/search.thtml:131
+#: views/elements/search.thtml:130
+msgid "advanced_search_form_past_6_months"
+msgstr "W ostatnich 6 miesiÄ…cach"
+
+#: views/elements/amo2009/search.thtml:127
+#: views/elements/search.thtml:126
+msgid "advanced_search_form_past_day"
+msgstr "Dzisiaj"
+
+#: views/elements/amo2009/search.thtml:129
+#: views/elements/search.thtml:128
+msgid "advanced_search_form_past_month"
+msgstr "W ostatnim miesiÄ…cu"
+
+#: views/elements/amo2009/search.thtml:128
+#: views/elements/search.thtml:127
+msgid "advanced_search_form_past_week"
+msgstr "W ostatnim tygodniu"
+
+#: views/elements/amo2009/search.thtml:132
+#: views/elements/search.thtml:131
+msgid "advanced_search_form_past_year"
+msgstr "W ostatnim roku"
+
+#: views/elements/amo2009/search.thtml:239
+#: views/elements/search.thtml:230
+msgid "advanced_search_form_perpage"
+msgstr "Na stronie"
+
+#: views/elements/amo2009/search.thtml:243
+#: views/elements/search.thtml:224
+msgid "advanced_search_form_platform"
+msgstr "System"
+
+#: views/elements/amo2009/search.thtml:147
+#: views/elements/search.thtml:146
+msgid "advanced_search_form_popularity"
+msgstr "Liczby pobrań"
+
+#: views/elements/amo2009/search.thtml:146
+#: views/elements/search.thtml:145
+msgid "advanced_search_form_rating"
+msgstr "Oceny"
+
+#: views/elements/amo2009/search.thtml:247
+#: views/elements/search.thtml:231
+msgid "advanced_search_form_sortby"
+msgstr "Sortuj wg"
+
+#: views/elements/amo2009/search.thtml:227
+#: views/elements/search.thtml:216
+msgid "advanced_search_form_to"
+msgstr "do"
+
+#: views/elements/amo2009/search.thtml:257
+#: views/elements/search.thtml:237
+msgid "advanced_search_form_toggle_tooltip"
+msgstr "Pokaż/Ukryj panel wyszukiwania zaawansowanego"
+
+#: views/elements/amo2009/search.thtml:235
+#: views/elements/search.thtml:223
+msgid "advanced_search_form_type"
+msgstr "Typ"
+
+#: views/elements/amo2009/search.thtml:222
+#: views/elements/search.thtml:214
+msgid "advanced_search_form_version"
+msgstr "wersja"
+
+#: views/elements/amo2009/pagination.thtml:42
+msgid "amo2009_pagination_next_page"
+msgstr "Następna"
+
+#: views/elements/amo2009/pagination.thtml:41
+msgid "amo2009_pagination_previous_page"
+msgstr "Poprzednia"
+
+#: views/pages/js_constants.js.thtml:96
+msgid "app_compat_ignore_check"
+msgstr "Pomijaj sprawdzanie wersji"
+
+#: views/pages/js_constants.js.thtml:72
+msgid "app_compat_older_firefox_only"
+msgstr "To jest dodatek dla starszych wersji Firefoksa"
+
+#. %1$s and %2$s are URLs
+#: views/pages/js_constants.js.thtml:74
+msgid "app_compat_older_version_or_ignore_check"
+msgstr "Możesz <a href=\"%1$s\">wypróbować starszą wersję</a> lub <a href=\"#\" onclick=\"%2$s\">zignorować sprawdzanie</a>"
+
+#. %1$s is a URL
+#: views/pages/js_constants.js.thtml:71
+msgid "app_compat_try_old_version"
+msgstr "<a href=\"%1$s\">Starsza wersja</a> może zadziałać"
+
+#. %1$s is a URL
+#. %2$s is a version number. Example: 3.1
+#: views/pages/js_constants.js.thtml:73
+msgid "app_compat_unreleased_version"
+msgstr "Ten dodatek wymaga niewydanej jeszcze wersji programu <a href=\"%1$s\">Firefox %2$s</a>"
+
+#: views/pages/js_constants.js.thtml:70
+msgid "app_compat_update_firefox"
+msgstr "<a href=\"http://getfirefox.com\">Zaktualizuj Firefoksa</a>, aby używać tego dodatku"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#. %3$s is a status, like Public.
+#: controllers/components/audit.php:79
+msgid "audit_addon_status"
+msgstr "%1$s zmienił status %2$s na %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:221
+msgid "audit_admin_default"
+msgstr "%1$s przypisał nieznaną czynność administracyjną %2$s do ID %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:153
+msgid "audit_admin_feature_remove"
+msgstr "%1$s usunÄ…Å‚ element %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is an application, like Firefox.
+#: controllers/components/audit.php:92
+msgid "audit_application_create"
+msgstr "%1$s dodał program %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is an application, like Firefox.
+#: controllers/components/audit.php:95
+msgid "audit_application_edit"
+msgstr "%1$s edytował program %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a version number, like 3.5.
+#. %3$s is an application, like Firefox.
+#: controllers/components/audit.php:105
+msgid "audit_appversion_create"
+msgstr "%1$s utworzył wersję %2$s dla %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a version number, like 3.5.
+#. %3$s is an application, like Firefox.
+#: controllers/components/audit.php:108
+msgid "audit_appversion_delete"
+msgstr "%1$s usunÄ…Å‚ wersjÄ™ %2$s dla %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a config field, like "awesomeness".
+#. %3$s is a config value, like "off".
+#. %4$s is a config value, like "on".
+#: controllers/components/audit.php:210
+msgid "audit_config"
+msgstr "%1$s zmieniÅ‚ ustawienie „%2$s†z „%3$s†na „%4$sâ€"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:258
+msgid "audit_editor_default"
+msgstr "%1$s przypisał nieznaną czynność edytora %2$s do ID %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#: controllers/components/audit.php:236
+msgid "audit_editor_feature_remove"
+msgstr "%1$s usunÄ…Å‚ dodatek %2$s z listy polecanych"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#: controllers/components/audit.php:231
+msgid "audit_feature_add"
+msgstr "%1$s dodał dodatek %2$s do listy polecanych"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:149
+msgid "audit_feature_edit"
+msgstr "%1$s zmienił właściwość dla lokalizacji %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#: controllers/components/audit.php:241
+msgid "audit_feature_locale_change"
+msgstr "%1$s zmienił na liście polecanych lokalizację dla dodatku %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:83
+msgid "audit_file_recalchash"
+msgstr "%1$s skalkulował ponownie sumę kontrolną dla pliku %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>user name</a>
+#. %3$s is <a>group name</a>
+#: controllers/components/audit.php:182
+msgid "audit_group_addmember"
+msgstr "%1$s dodał %2$s do grupy %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:313
+msgid "audit_group_associated"
+msgstr "%1$s skojarzył siebie z %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:162
+msgid "audit_group_create"
+msgstr "%1s utworzył grupę %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:170
+msgid "audit_group_delete"
+msgstr "%1$s usunÄ…Å‚ grupÄ™ %2$s (ID %3$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:165
+msgid "audit_group_edit"
+msgstr "%1$s edytował grupę %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>user name</a>
+#. %3$s is <a>group name</a>
+#: controllers/components/audit.php:188
+msgid "audit_group_removemember"
+msgstr "%1$s usunÄ…Å‚ %2$s z grupy %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:280
+msgid "audit_l10n_default"
+msgstr "%1$s przypisał nieznaną czynność %2$s do %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:295
+msgid "audit_modify_locked_group"
+msgstr "%1$s próbował zmodyfikować zablokowaną grupę %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:299
+msgid "audit_modify_other_locale"
+msgstr "%1$s próbował bez uprawnień zmodyfikować tłumaczenie w %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a platform, like <a>Windows</a>
+#: controllers/components/audit.php:135
+msgid "audit_platform_create"
+msgstr "%1$s dodał system %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a platform, like <a>Windows</a>
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:143
+msgid "audit_platform_delete"
+msgstr "%1$s usunÄ…Å‚ system %2$s (ID %3$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a platform, like <a>Windows</a>
+#: controllers/components/audit.php:138
+msgid "audit_platform_edit"
+msgstr "%1$s edytował system %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a part of the admin, like 'Site Config'
+#: controllers/components/audit.php:288
+msgid "audit_reauthentication_failure"
+msgstr "%1$s nie uzyskał dostępu do %2$s."
+
+#. %1$s is <a>user name</a>
+#. %2$s is the name of a canned response, like 'Ready for the public'
+#: controllers/components/audit.php:198
+msgid "audit_response_create"
+msgstr "%1$s utworzył odpowiedź %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is the name of a canned response, like 'Ready for the public'
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:206
+msgid "audit_response_delete"
+msgstr "%1$s usunął odpowiedź %2$s (ID %3$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is the name of a canned response, like 'Ready for the public'
+#: controllers/components/audit.php:201
+msgid "audit_response_edit"
+msgstr "%1$s edytował odpowiedź %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:245
+msgid "audit_review_approve"
+msgstr "%1$s zaakceptował recenzję %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:250
+#: controllers/components/audit.php:253
+msgid "audit_review_delete"
+msgstr "%1$s usunÄ…Å‚ recenzjÄ™ %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:303
+msgid "audit_security_default"
+msgstr "%1$s przypisał nieznaną czynność z zakresu bezpieczeństwa %2$s do ID %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a category name, like <a>Search Tools</a>
+#: controllers/components/audit.php:118
+msgid "audit_tag_create"
+msgstr "%1$s utworzył etykietę %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a category name, like <a>Search Tools</a>
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:126
+msgid "audit_tag_delete"
+msgstr "%1$s usunÄ…Å‚ kategoriÄ™ %2$s (ID %3$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a category name, like <a>Search Tools</a>
+#: controllers/components/audit.php:121
+msgid "audit_tag_edit"
+msgstr "%1$s edytował kategorię %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:266
+msgid "audit_update_applications"
+msgstr "%1$s zaktualizował tłumaczenie dla %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:277
+msgid "audit_update_blog"
+msgstr "%1$s zaktualizował tłumaczenie posta na blogu dla %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:274
+msgid "audit_update_platforms"
+msgstr "%1$s zaktualizował tłumaczenie platformy dla %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:270
+msgid "audit_update_tags"
+msgstr "%1$s zaktualizował tłumaczenie kategorii dla %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>user name</a>
+#: controllers/components/audit.php:217
+msgid "audit_user_edit"
+msgstr "%1$s edytował informacje o %2$s"
+
+#: controllers/addons_controller.php:1012
+msgid "browse_addons_name"
+msgstr "Dodatki wg nazwy"
+
+#: controllers/addons_controller.php:1010
+msgid "browse_addons_newest"
+msgstr "Najnowsze dodatki"
+
+#: controllers/addons_controller.php:1008
+msgid "browse_addons_popular"
+msgstr "Popularne dodatki"
+
+#: controllers/addons_controller.php:1011
+msgid "browse_addons_rated"
+msgstr "Dodatki wg oceny"
+
+#: controllers/addons_controller.php:1009
+msgid "browse_addons_updated"
+msgstr "Ostatnio zaktualizowane dodatki"
+
+#: views/elements/categories.thtml:73
+#: views/elements/categories.thtml:82
+msgid "categories_current_title"
+msgstr "Bieżąca kategoria"
+
+#: views/elements/categories.thtml:50
+#: views/elements/amo2009/categories.thtml:43
+#: views/elements/amo2009/categories.thtml:45
+msgid "categories_header"
+msgstr "Kategorie"
+
+#: views/elements/categories.thtml:50
+#: views/elements/amo2009/categories.thtml:41
+msgid "categories_header_title"
+msgstr "Wybierz kategoriÄ™"
+
+#. %1$s is the category name
+#: views/addons/searchengines.thtml:129
+#, php-format
+msgid "category_extra_see_all"
+msgstr "Wszystkie z kategorii: %1$s"
+
+#. %1$s is a number.
+#: models/collection.php:130
+msgid "collection_description_limit"
+msgstr "Opis nie powinien zawierać więcej znaków niż %1$s."
+
+#. %1$s is the name of the collection
+#: controllers/collections_controller.php:392
+msgid "collection_detail_rss_title"
+msgstr "Kolekcja %s"
+
+#: controllers/collections_controller.php:1065
+msgid "collection_error_deleting_addon"
+msgstr "Wystąpił błąd podczas usuwania dodatku!"
+
+#: controllers/collections_controller.php:1051
+msgid "collection_error_saving_addon"
+msgstr "Wystąpił błąd podczas zapisywania dodatku!"
+
+#: controllers/collections_controller.php:1080
+msgid "collection_error_saving_comment"
+msgstr "Wystąpił błąd podczas zapisywania komentarza!"
+
+#. %1$s is a number.
+#: models/collection.php:122
+msgid "collection_name_limit"
+msgstr "Nazwa nie powinna zawierać więcej znaków niż %1$s."
+
+#: controllers/collections_controller.php:352
+#: controllers/collections_controller.php:487
+msgid "collection_not_found"
+msgstr "Nie znaleziono kolekcji!"
+
+#. %1$s is the text on the "create collection" button
+#: views/collections/add.thtml:91
+msgid "collections_add_formfield_addons_description"
+msgstr "Jeśli wiesz już, które dodatki chcesz umieścić w kolekcji, wprowadź ich nazwy poniżej. Jeśli chcesz to zrobić później, naciśnij przycisk %1$s."
+
+#: views/collections/add.thtml:90
+msgid "collections_add_formfield_firstaddons"
+msgstr "Wybierz pierwszy dodatek"
+
+#: views/collections/add.thtml:48
+msgid "collections_add_header"
+msgstr "Tworzenie kolekcji"
+
+#: views/collections/add.thtml:97
+msgid "collections_add_header_selectedaddons"
+msgstr "Wybrane dodatki"
+
+#: views/collections/add.thtml:50
+msgid "collections_add_intro"
+msgstr "Kolekcję dodatków można bardzo łatwo utworzyć wypełniając kilka znajdujących się poniżej pól."
+
+#: views/collections/add.thtml:92
+#: views/collections/add.thtml:103
+msgid "collections_add_submit"
+msgstr "Utwórz kolekcję"
+
+#: views/pages/collector_faq.thtml:50
+#: views/pages/collector_firstrun.thtml:43
+#: views/pages/collector.thtml:47
+#: views/pages/collector_features.thtml:55
+#: controllers/search_controller.php:302
+#: controllers/collections_controller.php:206
+#: controllers/collections_controller.php:405
+#: controllers/collections_controller.php:467
+#: controllers/collections_controller.php:539
+msgid "collections_breadcrumb"
+msgstr "Kolekcje"
+
+#: views/collections/detail.thtml:185
+msgid "collections_detail_a_learn"
+msgstr "Dowiedz się więcej"
+
+#: views/elements/amo2009/collection_add_form.thtml:53
+#: views/elements/amo2009/collections_js_init.thtml:68
+#: views/pages/collector_firstrun.thtml:64
+msgid "collections_detail_button_add"
+msgstr "Dodaj do ulubionych"
+
+#: views/elements/amo2009/collection_add_form.thtml:50
+#: views/elements/amo2009/collections_js_init.thtml:71
+msgid "collections_detail_button_remove"
+msgstr "Usuń z ulubionych"
+
+#. %1$s is a URL.
+#. %2$s is a full <a href>.
+#: views/collections/detail.thtml:62
+msgid "collections_detail_created_desc"
+msgstr "<p>Poniżej możesz zobaczyć nowo utworzoną kolekcję. Jeśli chcesz określić nick kolekcji, wysłać ikonę lub zmienić dodatkowe ustawienia – przejdź na stronę <a href='%1$s'>Zarządzaj kolekcją</a>.</p><p>Twoja kolekcja jest dostępna pod następującym adresem: %2$s</p>"
+
+#: views/collections/detail.thtml:61
+msgid "collections_detail_created_msg"
+msgstr "Twoja kolekcja została utworzona!"
+
+#: views/collections/detail.thtml:109
+msgid "collections_detail_header_about"
+msgstr "Informacje o kolekcji"
+
+#. %1$s is a number.
+#: views/collections/detail.thtml:126
+msgid "collections_detail_header_count"
+msgid_plural "collections_detail_header_count"
+msgstr[0] "W kolekcji znajduje siÄ™ %1$s dodatek"
+msgstr[1] "W kolekcji znajdujÄ… siÄ™ %1$s dodatki"
+msgstr[2] "W kolekcji znajduje się %1$s dodatków"
+
+#: views/collections/detail.thtml:113
+msgid "collections_detail_info_created"
+msgstr "<strong>Utworzona przez:</strong> %1$s"
+
+#: views/collections/detail.thtml:117
+msgid "collections_detail_info_updated"
+msgstr "<strong>Zaktualizowana:</strong>"
+
+#: views/elements/amo2009/collections_js_init.thtml:62
+msgid "collections_detail_js_adding"
+msgstr "Dodawanie do ulubionych&hellip;"
+
+#: views/elements/amo2009/collections_js_init.thtml:65
+msgid "collections_detail_js_removing"
+msgstr "Usuwanie z ulubionych&hellip;"
+
+#. %1$s is a URL
+#: views/collections/detail.thtml:90
+msgid "collections_detail_login"
+msgstr "<a href=\"%1$s\">Zaloguj się</a>, aby dodać tę kolekcje do swoich ulubionych."
+
+#: views/collections/detail.thtml:104
+msgid "collections_detail_manage"
+msgstr "ZarzÄ…dzaj kolekcjÄ…"
+
+#: controllers/collections_controller.php:298
+msgid "collections_detail_sort_date"
+msgstr "daty dodania"
+
+#: controllers/collections_controller.php:299
+msgid "collections_detail_sort_name"
+msgstr "nazwy"
+
+#: controllers/collections_controller.php:300
+msgid "collections_detail_sort_popularity"
+msgstr "popularności"
+
+#. %1$s is a number.
+#: views/collections/detail.thtml:166
+msgid "collections_detail_weekly_downloads"
+msgid_plural "collections_detail_weekly_downloads"
+msgstr[0] "%1$s pobranie w tym tygodniu"
+msgstr[1] "%1$s pobrania w tym tygodniu"
+msgstr[2] "%1$s pobrań w tym tygodniu"
+
+#: views/collections/edit.thtml:255
+msgid "collections_edit_addons_delete_noscript"
+msgstr "Zaznaczone dodatki zostaną usunięte po zapisaniu"
+
+#: views/collections/edit.thtml:247
+msgid "collections_edit_addons_description"
+msgstr "Aby dodać nowe dodatki do tej kolekcji, wprowadź ich nazwy poniżej."
+
+#: views/collections/edit.thtml:248
+msgid "collections_edit_addons_description_noscript"
+msgstr "Aby dodać nowe dodatki do tej kolekcji, wprowadź ich ID poniżej, oddzielając je przecinkami."
+
+#: views/collections/edit.thtml:247
+#: views/collections/edit.thtml:248
+msgid "collections_edit_addons_description_publish_detailspage"
+msgstr "Możesz również dodać dodatek do kolekcji bezpośrednio z jego strony."
+
+#. %1$s is the date the add-on was added to the collection
+#. %1$s is the name of the user who added the add-on to the collection
+#: views/collections/edit.thtml:260
+msgid "collections_edit_addons_listitem_added"
+msgstr "Dodano %1$s przez %2$s"
+
+#: views/collections/edit.thtml:263
+msgid "collections_edit_addons_listitem_comment_add"
+msgstr "Dodaj komentarz"
+
+#: views/collections/edit.thtml:266
+msgid "collections_edit_addons_listitem_comment_delete"
+msgstr "Usuń komentarz"
+
+#: views/collections/edit.thtml:265
+msgid "collections_edit_addons_listitem_comment_edit"
+msgstr "Edytuj komentarz"
+
+#: views/collections/edit.thtml:271
+msgid "collections_edit_addons_listitem_comment_note"
+msgstr "Informacja: Komentarz będzie wyświetlany w tak jakiej formie, w jakiej został napisany w momencie dodania"
+
+#: views/collections/edit.thtml:270
+msgid "collections_edit_addons_listitem_comment_submit"
+msgstr "Zapisz komentarz"
+
+#: views/collections/edit.thtml:261
+msgid "collections_edit_addons_listitem_remove"
+msgstr "Usuń"
+
+#: views/collections/edit.thtml:250
+msgid "collections_edit_addons_submit"
+msgstr "Dodaj do kolekcji"
+
+#: views/collections/edit.thtml:153
+msgid "collections_edit_check_nickname"
+msgstr "Sprawdź dostępność"
+
+#: views/collections/edit.thtml:299
+msgid "collections_edit_confirm_deletecollection"
+msgstr "Tak, chcę usunąć tę kolekcję."
+
+#. %1$s is the label of the edit form's submit button
+#: views/collections/edit.thtml:300
+msgid "collections_edit_confirm_deletecollection_description"
+msgstr "Zaznacz pole wyboru i naciÅ›nij przycisk „%1$sâ€, aby usunąć tÄ™ kolekcjÄ™."
+
+#. %1$s is the "delete" submit button text
+#. %2$s is the title of the "advanced" tab
+#: views/collections/edit.thtml:95
+msgid "collections_edit_delete_upon_submit"
+msgstr "Po naciÅ›niÄ™ciu przycisku „%1$sâ€, kolekcja zostanie usuniÄ™ta. JeÅ›li nie chcesz usunąć kolekcji, usuÅ„ zaznaczenie z pola potwierdzenia na karcie „%2$s†i kontynuuj edytowanie kolekcji. JeÅ›li opuÅ›cisz tÄ™ stronÄ™ bez zapisania, kolekcja nie zostanie usuniÄ™ta."
+
+#: views/collections/edit.thtml:94
+msgid "collections_edit_delete_warning"
+msgstr "Kolekcja zostanie usunięta!"
+
+#: views/collections/add.thtml:76
+#: views/collections/edit.thtml:144
+msgid "collections_edit_form_error_description"
+msgstr "Musisz dołączyć opis kolekcji"
+
+#: views/collections/edit.thtml:181
+msgid "collections_edit_form_error_icon"
+msgstr "Wystąpił błąd podczas wysyłania ikony"
+
+#: views/collections/add.thtml:69
+#: views/collections/edit.thtml:130
+msgid "collections_edit_form_error_name"
+msgstr "Musisz podać nazwę kolekcji"
+
+#: views/collections/edit.thtml:158
+msgid "collections_edit_form_error_nickname"
+msgstr "Jeśli został wybrany nick, musi być on unikatowy."
+
+#: views/collections/add.thtml:93
+#: views/collections/edit.thtml:249
+msgid "collections_edit_formfield_addons"
+msgstr "Nazwa dodatku:"
+
+#: views/collections/edit.thtml:281
+msgid "collections_edit_formfield_application"
+msgstr "PowiÄ…zany program"
+
+#: views/collections/edit.thtml:282
+msgid "collections_edit_formfield_application_description"
+msgstr "Wybierz program, z którym współpracuje Twoja kolekcja."
+
+#: views/collections/edit.thtml:288
+msgid "collections_edit_formfield_collectiontype"
+msgstr "Typ kolekcji"
+
+#: views/collections/edit.thtml:295
+msgid "collections_edit_formfield_deletecollection"
+msgstr "Usuwanie kolekcji"
+
+#: views/collections/edit.thtml:296
+msgid "collections_edit_formfield_deletecollection_description"
+msgstr "Usunięcie kolekcji spowoduje jej trwałe skasowanie."
+
+#: views/collections/add.thtml:73
+#: views/collections/edit.thtml:140
+msgid "collections_edit_formfield_description"
+msgstr "Opis kolekcji"
+
+#: views/collections/add.thtml:74
+#: views/collections/edit.thtml:141
+msgid "collections_edit_formfield_description_description"
+msgstr "Opisz krótko kolekcję i typ znajdujących się w niej dodatków"
+
+#: views/collections/edit.thtml:162
+msgid "collections_edit_formfield_icon"
+msgstr "Ikona"
+
+#: views/collections/edit.thtml:163
+msgid "collections_edit_formfield_icon_description"
+msgstr "Możesz wysłać ikonę w formacie JPG, GIF lub PNG. Zostanie ona przeskalowana do rozmiaru 32x32 px."
+
+#: views/collections/add.thtml:80
+#: views/collections/edit.thtml:189
+msgid "collections_edit_formfield_listed"
+msgstr "Kto może przeglądać tę kolekcję?"
+
+#: views/collections/add.thtml:81
+#: views/collections/edit.thtml:190
+msgid "collections_edit_formfield_listed_description"
+msgstr "Domyślnie kolekcja jest wyświetlana w Katalogu kolekcji i jest dostępna dla wszystkich. Jeśli chcesz ograniczyć przeglądanie kolekcji tylko do osób, które otrzymały specjalny odnośnik, zaznacz drugą opcję."
+
+#: views/collections/add.thtml:84
+#: views/collections/edit.thtml:193
+msgid "collections_edit_formfield_listed_false"
+msgstr "Tylko zaproszone przeze mnie osoby"
+
+#: views/collections/add.thtml:83
+#: views/collections/edit.thtml:192
+msgid "collections_edit_formfield_listed_true"
+msgstr "Wszyscy"
+
+#: views/collections/edit.thtml:223
+msgid "collections_edit_formfield_managers"
+msgstr "Kto może zarządzać tą kolekcją?"
+
+#: views/collections/edit.thtml:224
+msgid "collections_edit_formfield_managers_description"
+msgstr "Te osoby mogą dodawać dodatki do tej kolekcji, zarządzać wszystkimi dodatkami i ustawieniami oraz udzielać innym użytkownikom zezwoleń."
+
+#: views/collections/add.thtml:66
+#: views/collections/edit.thtml:126
+msgid "collections_edit_formfield_name"
+msgstr "Nazwa kolekcji"
+
+#: views/collections/add.thtml:67
+#: views/collections/edit.thtml:127
+msgid "collections_edit_formfield_name_description"
+msgstr "Nadaj kolekcji opisowÄ… nazwÄ™ np.: „Ulubione dodatki webmasterskie Leszkaâ€"
+
+#: views/collections/edit.thtml:148
+msgid "collections_edit_formfield_nickname"
+msgstr "Nick kolekcji"
+
+#: views/collections/edit.thtml:149
+msgid "collections_edit_formfield_nickname_description"
+msgstr "Opcjonalnie, aby mieć szybki dostęp do kolekcji, możesz dodać do niej unikatowy nick:"
+
+#: views/collections/edit.thtml:201
+msgid "collections_edit_formfield_publishers"
+msgstr "Kto może dodawać dodatki do tej kolekcji?"
+
+#: views/collections/edit.thtml:202
+msgid "collections_edit_formfield_publishers_description"
+msgstr "Poniższe osoby mogą dodawać dodatki do kolekcji i usuwać te, które dodali."
+
+#: views/collections/edit.thtml:210
+#: views/collections/edit.thtml:232
+msgid "collections_edit_formfield_users_add"
+msgstr "Wprowadź adres e-mail konta użytkownika na witrynie Dodatki dla Firefoksa"
+
+#: views/collections/edit.thtml:216
+#: views/collections/edit.thtml:238
+msgid "collections_edit_formfield_users_delete_noscript"
+msgstr "Zaznaczone konta zostaną usunięte po zapisaniu"
+
+#: views/collections/edit.thtml:215
+#: views/collections/edit.thtml:237
+msgid "collections_edit_formfield_users_new_noscript"
+msgstr "Wprowadź, oddzielane przecinkiem, adresy e-mail kont na witrynie Dodatki dla Firefoksa"
+
+#: views/collections/edit.thtml:204
+#: views/collections/edit.thtml:226
+msgid "collections_edit_formfield_users_onlyme"
+msgstr "Tylko ja"
+
+#: views/collections/edit.thtml:205
+#: views/collections/edit.thtml:227
+msgid "collections_edit_formfield_users_otherusers"
+msgstr "Ja i następujący użytkownicy:"
+
+#: views/collections/edit.thtml:211
+#: views/collections/edit.thtml:233
+msgid "collections_edit_formfield_users_submit"
+msgstr "Dodaj"
+
+#. %1$s is the name of the collection
+#: views/collections/edit.thtml:68
+msgid "collections_edit_header"
+msgstr "ZarzÄ…dzanie kolekcjÄ… %1$s"
+
+#: views/collections/edit.thtml:246
+msgid "collections_edit_header_addons"
+msgstr "Zarządzanie zawartością kolekcji"
+
+#: views/collections/edit.thtml:253
+#: views/collections/edit.thtml:258
+msgid "collections_edit_header_addons_current"
+msgstr "Dodatki w kolekcji:"
+
+#: views/collections/edit.thtml:279
+msgid "collections_edit_header_advanced"
+msgstr "Ustawienia zaawansowane"
+
+#: views/collections/edit.thtml:186
+msgid "collections_edit_header_permissions"
+msgstr "Zarządzanie udzielaniem uprawnień kolekcji"
+
+#: views/collections/edit.thtml:170
+msgid "collections_edit_icon_cancel"
+msgstr "Anuluj"
+
+#: views/collections/edit.thtml:174
+#: views/collections/edit.thtml:179
+msgid "collections_edit_icon_delete"
+msgstr "Usuń ikonę"
+
+#: views/collections/edit.thtml:178
+msgid "collections_edit_icon_replace"
+msgstr "Zmień ikonę"
+
+#. %1$s is the label of the edit form's submit button
+#: views/collections/edit.thtml:169
+msgid "collections_edit_icon_toberemoved"
+msgstr "Ikona zostanie usuniÄ™ta po naciÅ›niÄ™ciu przycisku „%1$sâ€"
+
+#: views/collections/edit.thtml:155
+msgid "collections_edit_nickname_available"
+msgstr "Dostępne nicki"
+
+#: controllers/collections_controller.php:943
+msgid "collections_edit_nickname_error"
+msgstr "Twój nick zawierał nieprawidłowe znaki i został poprawiony. Spróbuj ponownie."
+
+#: views/collections/edit.thtml:156
+msgid "collections_edit_nickname_taken"
+msgstr "Nick został zaakceptowany"
+
+#. This string is followed by a URL pointing to the collection's view page
+#: views/collections/edit.thtml:75
+msgid "collections_edit_saved_nextstep"
+msgstr "Twoja kolekcja może być dostępna pod tym adresem:"
+
+#: views/collections/edit.thtml:74
+msgid "collections_edit_saved_success"
+msgstr "Kolekcja została zapisana!"
+
+#: views/collections/edit.thtml:169
+#: views/collections/edit.thtml:300
+#: views/collections/edit.thtml:308
+#: views/pages/js_constants.js.thtml:99
+msgid "collections_edit_submit"
+msgstr "Aktualizuj kolekcjÄ™"
+
+#: views/collections/edit.thtml:96
+#: views/collections/edit.thtml:297
+#: views/pages/js_constants.js.thtml:100
+msgid "collections_edit_submit_deletecollection"
+msgstr "Usuń kolekcję"
+
+#: views/collections/edit.thtml:111
+msgid "collections_edit_tabheader_addons"
+msgstr "Dodatki"
+
+#: views/collections/edit.thtml:97
+#: views/collections/edit.thtml:113
+msgid "collections_edit_tabheader_advanced"
+msgstr "Zaawansowane"
+
+#: views/collections/edit.thtml:108
+msgid "collections_edit_tabheader_details"
+msgstr "Nazwa i szczegóły"
+
+#: views/collections/edit.thtml:109
+msgid "collections_edit_tabheader_permissions"
+msgstr "Uprawnienia"
+
+#: models/collection_promo.php:53
+msgid "collections_family_tagline"
+msgstr "Miej na oku swoje dzieci i kalendarz"
+
+#: models/collection_promo.php:53
+msgid "collections_family_title"
+msgstr "Rodzina"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:70
+msgid "collections_index_a_check_out"
+msgstr "Wypróbuj Kolekcjonera dodatków"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:52
+msgid "collections_index_a_create"
+msgstr "Utwórz kolekcję"
+
+#: views/collections/detail.thtml:139
+#: views/collections/listing.thtml:85
+#: views/search/collections.thtml:84
+msgid "collections_index_button_go"
+msgstr "Wykonaj"
+
+#. %1$s is a URL.
+#: controllers/collections_controller.php:182
+msgid "collections_index_filler_favorites"
+msgstr "<p><strong>Nie masz jeszcze żadnych ulubionych kolekcji.</strong></p> <p>Kolekcje oznaczone jako ulubione mogą być szybko dostępne z tej strony i będą wyświetlane w <a href='%1$s'>Kolekcjonerze dodatków</a>, jeśli masz go zainstalowanego.</p>"
+
+#. %1$s is a URL.
+#: controllers/collections_controller.php:167
+msgid "collections_index_filler_mine"
+msgstr "<p>Nie masz jeszcze utworzonej żadnej kolekcji. Kolekcje można łatwo tworzyć i uzupełniać ulubionymi dodatkami. <a href='%1$s'>Wypróbuj je</a>!</p>"
+
+#: views/collections/listing.thtml:51
+msgid "collections_index_header_collections"
+msgstr "Kolekcje"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:60
+msgid "collections_index_header_collector"
+msgstr "Kolekcjoner dodatków"
+
+#. %1$s is a comma-separated list of author names
+#: views/elements/amo2009/collection_listing_item.thtml:84
+#: views/collections/detail.thtml:151
+msgid "collections_index_header_created"
+msgstr "autor: %1$s"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:47
+msgid "collections_index_header_what"
+msgstr "Co to sÄ… kolekcje?"
+
+#: views/collections/detail.thtml:132
+#: views/collections/listing.thtml:78
+#: views/search/collections.thtml:66
+msgid "collections_index_label_sortby"
+msgstr "Sortuj wg"
+
+#: controllers/collections_controller.php:130
+msgid "collections_index_li_editors"
+msgstr "Kolekcje AMO"
+
+#: views/collections/subscribe.thtml:64
+#: controllers/collections_controller.php:140
+msgid "collections_index_li_favorites"
+msgstr "Moje ulubione"
+
+#: controllers/collections_controller.php:138
+msgid "collections_index_li_mine"
+msgstr "Moje kolekcje"
+
+#: controllers/collections_controller.php:132
+msgid "collections_index_li_popular"
+msgstr "Popularne"
+
+#: views/search/collections.thtml:74
+#: controllers/collections_controller.php:81
+msgid "collections_index_option_all"
+msgstr "Najpopularniejsze"
+
+#: views/search/collections.thtml:72
+#: controllers/collections_controller.php:78
+msgid "collections_index_option_month"
+msgstr "Najpopularniejsze w tym miesiÄ…cu"
+
+#: views/search/collections.thtml:76
+#: controllers/collections_controller.php:84
+msgid "collections_index_option_newest"
+msgstr "Najnowsze"
+
+#: views/search/collections.thtml:70
+#: controllers/collections_controller.php:75
+msgid "collections_index_option_week"
+msgstr "Najpopularniejsze w tym tygodniu"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:67
+msgid "collections_index_p_collector"
+msgstr "To jest nowy sposób szukania i zarządzania ulubionymi dodatkami. Komentuj, udostępniaj i synchronizuj kolekcje – wszystko z poziomu Twojej przeglądarki"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:48
+msgid "collections_index_p_what_are"
+msgstr "Kolekcje są grupami podobnych dodatków zgromadzonych razem, aby ułatwić ich udostępnianie."
+
+#. %s is a date in the _('date') format
+#: views/elements/collections_interactive_addon.thtml:85
+#, php-format
+msgid "collections_interactive_addon_added"
+msgstr "Dodano %s"
+
+#: models/collection_promo.php:55
+msgid "collections_reference_tagline"
+msgstr "Eksploruj Internet"
+
+#: models/collection_promo.php:55
+msgid "collections_reference_title"
+msgstr "Podręczne"
+
+#: models/collection_promo.php:52
+msgid "collections_social_tagline"
+msgstr "Zarządzaj swoimi sieciami społecznościowymi"
+
+#: models/collection_promo.php:52
+msgid "collections_social_title"
+msgstr "Społeczności"
+
+#: views/collections/subscribe.thtml:91
+msgid "collections_subscribe_button_close"
+msgstr "Zamknij"
+
+#: views/collections/subscribe.thtml:70
+msgid "collections_subscribe_error"
+msgstr "Podczas próby dodania ulubionej kolekcji wystąpił błąd. Czy ta kolekcja nie jest już w Twoich ulubionych?"
+
+#: views/collections/subscribe.thtml:96
+msgid "collections_subscribe_label_bothersome"
+msgstr "Nie wyświetlaj tej wiadomości ponownie."
+
+#. %1$s is the collection name
+#: views/collections/subscribe.thtml:60
+msgid "collections_subscribe_success"
+msgstr "Kolekcja %1$s została dodana do zbioru Twoich ulubionych kolekcji."
+
+#. %1$s is the link to the "My Favorites" tab on the main collections page
+#. %2$s is the localized title of the "My Favorites" tab
+#. %3$s is the link URL to the collector add-on
+#: views/collections/subscribe.thtml:62
+msgid "collections_subscribe_success_desc"
+msgstr "Teraz możesz szybko znaleźć tę kolekcję na karcie <a href=\"%1$s\">%2$s</a>. Aby jeszcze łatwiej śledzić swoje ulubione kolekcje, wypróbuj rozszerzenie dla Firefoksa o nazwie <a href=\"%3$s\">Kolekcjoner dodatków</a>."
+
+#: views/collections/listing.thtml:55
+msgid "collections_success_delete"
+msgstr "Kolekcja została usunięta"
+
+#: models/collection_promo.php:54
+msgid "collections_travel_tagline"
+msgstr "Zaplanuj podróż służbową i niezapomniane wakacje"
+
+#: models/collection_promo.php:54
+msgid "collections_travel_title"
+msgstr "Podróże"
+
+#. A collection of add-ons that is automatically built for a user. They are "automatically published" to this collection.
+#: controllers/collections_controller.php:581
+msgid "collections_type_autopublisher"
+msgstr "Autokolekcja"
+
+#. A collection that has been chosen by an Editor as notable or exceptional
+#: controllers/collections_controller.php:582
+msgid "collections_type_editorspick"
+msgstr "Kolekcja AMO"
+
+#: controllers/collections_controller.php:580
+msgid "collections_type_normal"
+msgstr "Normalna"
+
+#: views/collections/subscribe.thtml:84
+msgid "collections_unsubscribe_error"
+msgstr "Podczas próby usunięcia ulubionej kolekcji wystąpił błąd. To nie była ulubiona kolekcja?"
+
+#. %1$s is the collection name
+#: views/collections/subscribe.thtml:78
+msgid "collections_unsubscribe_success"
+msgstr "Kolekcja %1$s została usunięta ze zbioru Twoich ulubionych kolekcji."
+
+#: models/collection_promo.php:56
+msgid "collections_webdev_tagline"
+msgstr "Zbuduj doskonałą stronę internetową"
+
+#: models/collection_promo.php:56
+msgid "collections_webdev_title"
+msgstr "Webmaster"
+
+#: views/elements/amo2009/collections_sidebar_whatare.thtml:40
+msgid "collections_whatare_header"
+msgstr "Co to sÄ… kolekcje?"
+
+#: views/elements/amo2009/collections_sidebar_whatare.thtml:45
+msgid "collections_whatare_learnmore"
+msgstr "Przeczytaj FAQ"
+
+#: views/elements/amo2009/collections_sidebar_whatare.thtml:44
+msgid "collections_whatare_text"
+msgstr "To jest nowy sposób szukania dodatków i zarządzania ulubionymi dodatkami. Komentuj, udostępniaj i synchronizuj kolekcje – wszystko z poziomu Twojej przeglądarki."
+
+#: views/pages/collector_faq.thtml:61
+#: views/pages/collector_features.thtml:67
+msgid "collector_features_a_home"
+msgstr "Strona domowa Kolekcjonera dodatków"
+
+#: views/elements/amo2009/collector_sidebar_download.thtml:46
+msgid "collector_features_heading_download"
+msgstr "Pobierz Kolekcjonera dodatków:"
+
+#: views/elements/amo2009/collector_sidebar_download.thtml:43
+#: views/pages/collector_firstrun.thtml:116
+#: views/pages/collector.thtml:69
+msgid "collector_features_img_logo"
+msgstr "Logo Kolekcjonera dodatków"
+
+#: views/compatibility/dashboard.thtml:49
+#: controllers/compatibility_controller.php:72
+msgid "compatibility_dashboard_center_header"
+msgstr "Centrum kompatybilności dodatków"
+
+#. %1$s is the name of an application and a version. Example: Firefox 3.0
+#. %2$s is the name of an application. Example: Firefox
+#: views/compatibility/dashboard.thtml:50
+msgid "compatibility_dashboard_intro"
+msgstr "Przygotuj się na wydanie wersji %1$s korzystając z dostępnych poniżej dla społeczności „%2$s – dodatki†narzędzi oraz informacji."
+
+#: views/compatibility/dashboard.thtml:103
+msgid "compatibility_dashboard_loading"
+msgstr "Wczytywanie danych…"
+
+#: views/compatibility/dashboard.thtml:45
+msgid "compatibility_dashboard_main_link"
+msgstr "Strona główna"
+
+#: views/compatibility/dashboard.thtml:100
+#: views/compatibility/report.thtml:43
+msgid "compatibility_dashboard_report"
+msgstr "Informacje o kompatybilności dodatków"
+
+#: views/compatibility/dashboard.thtml:53
+#: views/compatibility/dashboard.thtml:110
+#: views/compatibility/developers.thtml:43
+msgid "compatibility_developer_info"
+msgstr "Informacje dla twórców dodatków"
+
+#: views/compatibility/developers.thtml:66
+msgid "compatibility_developers_adjust_maxversion"
+msgstr "Zmień maxVersion bez ponownego wysyłania dodatku"
+
+#: views/compatibility/dashboard.thtml:124
+msgid "compatibility_developers_check_status"
+msgstr "Sprawdź status swoich dodatków"
+
+#. %1$s is a URL
+#. %2$s is an application and version. Example: Firefox 3.0
+#: views/compatibility/dashboard.thtml:126
+msgid "compatibility_developers_login_first"
+msgstr "Jeśli masz dodatki utrzymywane na witrynie Mozilla Add-ons, <a href=\"%1$s\">zaloguj się</a>, by sprawdzić zgodność swoich dodatków z programem %2$s."
+
+#: views/compatibility/dashboard.thtml:114
+msgid "compatibility_developers_mdclogo_alt"
+msgstr "Logo Mozilla Developer Center"
+
+#: views/compatibility/developers.thtml:73
+msgid "compatibility_developers_no_addons"
+msgstr "Nie masz dodatków utrzymywanych na witrynie Mozilla Add-ons."
+
+#: views/compatibility/dashboard.thtml:133
+#: views/compatibility/developers.thtml:55
+msgid "compatibility_developers_results"
+msgstr "Wyniki sprawdzania statusu dodatków"
+
+#: views/compatibility/dashboard.thtml:137
+msgid "compatibility_developers_retrieving"
+msgstr "Pobieranie informacji o statusie dodatków…"
+
+#. %1$s is a number
+#. %2$s is an application name
+#. %3$s is a number.
+#. Full example: 50 Firefox users (10% of total)
+#: views/compatibility/developers.thtml:65
+msgid "compatibility_developers_user_count"
+msgstr "%1$s użytkowników %2$s (%3$s&#37; wszystkich)"
+
+#: views/compatibility/report.thtml:45
+msgid "compatibility_report_detail_intro"
+msgstr "Poniższe dodatki stanowią 95% znanego Mozilli poziomu użycia dodatków i są wyświetlone w kolejności zależnej od tego poziomu."
+
+#: views/compatibility/dashboard.thtml:94
+msgid "compatibility_report_detailed_link"
+msgstr "Zobacz szczegółowe informacje"
+
+#. %1$s and %2$s are numbers
+#. %3$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:65
+msgid "compatibility_report_intro"
+msgstr "Z %1$s dodatków, które stanowią 95&#37; znanego Mozilli poziomu użycia dodatków, <b>%2$s&#37;</b> uważa się za kompatybilne z najnowszymi wersjami %3$s."
+
+#: views/compatibility/dashboard.thtml:81
+msgid "compatibility_report_legend_alpha"
+msgstr "Wersje alfa"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:81
+msgid "compatibility_report_legend_alpha_description"
+msgstr "Dodatki kompatybilne z wersjÄ… alfa programu %1$s"
+
+#: views/compatibility/dashboard.thtml:85
+msgid "compatibility_report_legend_beta"
+msgstr "Wersje beta"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:85
+msgid "compatibility_report_legend_beta_description"
+msgstr "Dodatki kompatybilne z wersjÄ… beta lub wydaniem kandydackim programu %1$s"
+
+#: views/compatibility/dashboard.thtml:89
+msgid "compatibility_report_legend_latest"
+msgstr "Najnowsza wersja"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:89
+msgid "compatibility_report_legend_latest_description"
+msgstr "Dodatki kompatybilne z najnowszÄ… wersjÄ… programu %1$s"
+
+#: views/compatibility/dashboard.thtml:77
+msgid "compatibility_report_legend_other"
+msgstr "Inne wersje"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:77
+msgid "compatibility_report_legend_other_description"
+msgstr "Dodatki niekompatybilne z żadną wersją programu %1$s"
+
+#: views/compatibility/dashboard.thtml:62
+msgid "compatibility_report_title"
+msgstr "Informacje o kompatybilności dodatków"
+
+#: views/compatibility/dashboard.thtml:54
+#: views/compatibility/dashboard.thtml:144
+#: views/compatibility/users.thtml:42
+msgid "compatibility_user_info"
+msgstr "Informacje dla użytkowników dodatków"
+
+#: views/compatibility/dashboard.thtml:52
+msgid "compatibility_view_report"
+msgstr "Informacje o kompatybilności dodatków"
+
+#. %s is a URL
+#: views/pages/credits.thtml:142
+#, php-format
+msgid "credits_contributing"
+msgstr "Informacje na temat współpracy można znaleźć na %s."
+
+#: views/pages/credits.thtml:142
+msgid "credits_contributing_wikipage"
+msgstr "stronie wiki"
+
+#: views/pages/credits.thtml:99
+msgid "credits_intro"
+msgstr "Mozilla chciałaby podziękować następującym osobom za ich wkład w projekt addons.mozilla.org:"
+
+#: views/pages/credits.thtml:103
+msgid "credits_section_developers"
+msgstr "Programiści"
+
+#: views/pages/credits.thtml:115
+msgid "credits_section_editors"
+msgstr "Edytorzy"
+
+#: views/pages/credits.thtml:109
+msgid "credits_section_localizers"
+msgstr "Lokalizatorzy"
+
+#: views/pages/credits.thtml:121
+msgid "credits_section_other_contributors"
+msgstr "Pozostali współtwórcy"
+
+#: views/pages/credits.thtml:127
+msgid "credits_section_past_developers"
+msgstr "Poprzedni programiści"
+
+#: views/pages/credits.thtml:133
+msgid "credits_section_software"
+msgstr "Oprogramowanie i grafika"
+
+#: views/pages/credits.thtml:136
+msgid "credits_software_famfamfam"
+msgstr "Niektóre użyte ikony pochodzą z zestawu <a href=\"http://www.famfamfam.com/lab/icons/silk/\">famfamfam Silk Icon</a>, udostępnianego na licencji <a href=\"http://creativecommons.org/licenses/by/2.5/\">Creative Commons Attribution 2.5 License</a>."
+
+#: views/pages/credits.thtml:137
+msgid "credits_software_timeplot"
+msgstr "Część stron używa elementów widgetu <a href=\"http://www.simile-widgets.org/timeplot/\">Timeplot</a> wydanego na licencji <a href=\"http://simile.mit.edu/license.html\">BSD</a>."
+
+#. date format string as used in PHP's strftime():
+#. http://php.net/strftime
+#: views/elements/collections_interactive_addon.thtml:85
+#: views/elements/amo2009/addon_version_detail.thtml:53
+#: views/elements/amo2009/homepage_addon.thtml:115
+#: views/elements/addon_version_detail.thtml:54
+#: views/elements/addon_listitem.thtml:124
+#: views/elements/feature.thtml:106
+#: views/collections/detail.thtml:118
+#: views/collections/edit.thtml:325
+#: views/users/info.thtml:76
+#: views/editors/reviews_queue.thtml:57
+#: views/editors/reviews_queue.thtml:68
+#: views/developers/dashboard.thtml:65
+#: views/developers/versions_edit.thtml:208
+#: views/developers/versions.thtml:67
+#: views/search/rss/index.thtml:5
+#: views/addons/rss/versions.thtml:42
+#: views/addons/display.thtml:104
+#: views/addons/display.thtml:356
+#: views/addons/browse_thumbs.thtml:75
+#: views/reviews/add.thtml:63
+#: views/reviews/display.thtml:74
+#: views/reviews/display.thtml:160
+#: views/reviews/delete.thtml:54
+#: controllers/statistics_controller.php:244
+#: controllers/collections_controller.php:1047
+msgid "date"
+msgstr "%e %b %Y"
+
+#. date and time format string (strftime)
+#. http://php.net/strftime
+#: views/elements/addon_version_detail.thtml:53
+#: views/developers/discuss.thtml:52
+#: views/developers/discuss.thtml:62
+#: views/admin/addons_status.thtml:57
+msgid "datetime"
+msgstr "%e %b %Y, %H:%M"
+
+#: views/elements/developers/actionbar.thtml:47
+msgid "devcp_actionbar_link_details"
+msgstr "Szczegóły"
+
+#: views/elements/developers/actionbar.thtml:42
+#: views/elements/developers/actionbar.thtml:50
+#: views/developers/dashboard.thtml:64
+msgid "devcp_actionbar_link_edit"
+msgstr "Edytuj dodatek"
+
+#: views/elements/developers/actionbar.thtml:51
+msgid "devcp_actionbar_link_newversion"
+msgstr "Prześlij nową wersję"
+
+#: views/elements/developers/actionbar.thtml:44
+#: views/elements/developers/actionbar.thtml:49
+#: views/developers/dashboard.thtml:73
+msgid "devcp_actionbar_link_stats"
+msgstr "Panel statystyk"
+
+#. %1$s is a filename, e.g. "foo.txt"
+#. %2$s is the extension, e.g. ".txt"
+#. %3$s is a list of valid extensions, like ".png, .jpg, .gif"
+#: controllers/developers_controller.php:1361
+msgid "devcp_add_previews_extension_error"
+msgstr "Plik %1$s ma nieprawidłowe rozszerzenie (%2$s). Dozwolone rozszerzenia: %3$s"
+
+#. %s is the filename.
+#: controllers/developers_controller.php:1394
+msgid "devcp_add_previews_save_error"
+msgstr "Plik %s nie został zapisany w bazie danych. Proszę spróbować ponownie."
+
+#. %1$s is the preview ID number, %2$s is the filename.
+#: controllers/developers_controller.php:1389
+msgid "devcp_add_previews_success_replace"
+msgstr "Obrazek o numerze %1$s został zamieniony plikiem %2$s."
+
+#. %s is the filename.
+#: controllers/developers_controller.php:1391
+msgid "devcp_add_previews_success_upload"
+msgstr "Plik %s został wysłany. Poniżej możesz dodać opis."
+
+#: controllers/components/developers.php:1163
+msgid "devcp_additem_addontype_autodetect"
+msgstr "(wykryj automatycznie)"
+
+#: views/elements/developers/additem.thtml:76
+msgid "devcp_additem_linktitle_opensin_newwindow"
+msgstr "Otwiera w nowym oknie"
+
+#: views/elements/developers/additem.thtml:41
+msgid "devcp_additem_sidebar_title"
+msgstr "Wyślij dodatek"
+
+#: views/elements/developers/additem.thtml:53
+msgid "devcp_additem_step0_newlink"
+msgstr "Umowa programisty"
+
+#: views/elements/developers/additem.thtml:46
+msgid "devcp_additem_step1_link"
+msgstr "Krok 1: Wysyłanie pliku"
+
+#: views/elements/developers/additem.thtml:47
+msgid "devcp_additem_step2_link"
+msgstr "Krok 2: Szczegóły dodatku"
+
+#: views/elements/developers/additem.thtml:48
+msgid "devcp_additem_step3_link"
+msgstr "Krok 3: Szczegóły wersji"
+
+#: views/elements/developers/additem.thtml:49
+msgid "devcp_additem_step4_link"
+msgstr "Krok 4: Lokalizacja"
+
+#: views/elements/developers/additem.thtml:50
+msgid "devcp_additem_step5_link"
+msgstr "Krok 5: Koniec"
+
+#: views/elements/developers/additem.thtml:76
+msgid "devcp_additem_submissionhelp_link"
+msgstr "Pomoc w wysłaniu"
+
+#: controllers/previews_controller.php:168
+#: controllers/previews_controller.php:277
+msgid "devcp_addon_field_preview_caption_displaytitle"
+msgstr "Opis obrazka podglÄ…du"
+
+#: views/developers/addon_status.thtml:177
+msgid "devcp_addon_status_action_activate"
+msgstr "Uaktywnij"
+
+#: views/developers/addon_status.thtml:178
+msgid "devcp_addon_status_action_activate_description"
+msgstr "Ta operacja spowoduje, że dodatek stanie się aktywny. Będzie wyświetlany w ogólnodostępnych wykazach i dostępny dla usługi sprawdzania aktualizacji."
+
+#: views/developers/addon_status.thtml:135
+msgid "devcp_addon_status_action_complete"
+msgstr "Zakończ"
+
+#: views/developers/addon_status.thtml:136
+msgid "devcp_addon_status_action_complete_description"
+msgstr "Kończy proces dodawania dodatku i przenosi go do piaskownicy"
+
+#: views/developers/addon_status.thtml:181
+msgid "devcp_addon_status_action_deactivate"
+msgstr "Dezaktywuj"
+
+#: views/developers/addon_status.thtml:182
+msgid "devcp_addon_status_action_deactivate_description"
+msgstr "Ta operacja spowoduje dezaktywację dodatku. Nie będzie on wyświetlany w ogólnodostępnych wykazach i nie będzie dostępny dla usługi sprawdzania aktualizacji."
+
+#: views/developers/addon_status.thtml:143
+msgid "devcp_addon_status_action_move"
+msgstr "PrzenieÅ› do piaskownicy"
+
+#: views/developers/addon_status.thtml:144
+msgid "devcp_addon_status_action_move_description"
+msgstr "Ta operacja spowoduje przeniesienie dodatku do piaskownicy. Operację tę można odwrócić."
+
+#: views/developers/addon_status.thtml:139
+msgid "devcp_addon_status_action_nominate"
+msgstr "Nominuj"
+
+#: views/developers/addon_status.thtml:140
+msgid "devcp_addon_status_action_nominate_description"
+msgstr "Ta operacja spowoduje nominowanie dodatku do upublicznienia"
+
+#: views/developers/addon_status.thtml:147
+msgid "devcp_addon_status_action_public"
+msgstr "Upublicznij"
+
+#: views/developers/addon_status.thtml:148
+msgid "devcp_addon_status_action_public_description"
+msgstr "Ta operacja spowoduje ponowne upublicznienie dodatku."
+
+#: views/developers/addon_status.thtml:169
+msgid "devcp_addon_status_active"
+msgstr "Dodatek jest <span class=\"inactive-0\">aktywny</span>. Oznacza to, że Twój dodatek jest wyświetlany we wszystkich dostępnych wykazach – odpowiednio do swojego statusu."
+
+#: views/developers/addon_status.thtml:111
+msgid "devcp_addon_status_completion_disabled"
+msgstr "Aby ukończyć dodatek i przenieść go do <span class=\"status-1\">piaskownicy</span>, muszą być spełnione powyższe kryteria."
+
+#: views/developers/addon_status.thtml:108
+msgid "devcp_addon_status_completion_enabled"
+msgstr "Teraz możesz zakoÅ„czyć swój dodatek i przenieść go do <span class=\"status-1\">piaskownicy</span> naciskajÄ…c przycisk „ZakoÅ„czâ€."
+
+#: views/developers/addon_status.thtml:102
+msgid "devcp_addon_status_criteria_category"
+msgstr "Musi być określona co najmniej jedna kategoria"
+
+#: views/developers/addon_status.thtml:101
+msgid "devcp_addon_status_criteria_description"
+msgstr "Dodatek musi mieć opis"
+
+#: views/developers/addon_status.thtml:99
+msgid "devcp_addon_status_criteria_name"
+msgstr "Dodatek musi mieć nazwę"
+
+#: views/developers/addon_status.thtml:120
+msgid "devcp_addon_status_criteria_prerelease"
+msgstr "Dodatek nie może być oznaczony jako wydanie wstępne."
+
+#: views/developers/addon_status.thtml:119
+msgid "devcp_addon_status_criteria_preview"
+msgstr "Wymagany jest co najmniej jeden obrazek podglądu dla rozszerzeń i motywów."
+
+#: views/developers/addon_status.thtml:100
+msgid "devcp_addon_status_criteria_summary"
+msgstr "Dodatek musi mieć podsumowanie"
+
+#. %s is the status in a span, e.g. "<span>_('Public')</span>".
+#: views/developers/addon_status.thtml:58
+msgid "devcp_addon_status_header"
+msgstr "Status dodatku: %s"
+
+#: views/developers/addon_status.thtml:152
+#: views/developers/addon_status.thtml:173
+msgid "devcp_addon_status_header_actions"
+msgstr "Dostępne czynności"
+
+#: views/developers/addon_status.thtml:168
+msgid "devcp_addon_status_header_active"
+msgstr "Status aktywności: <span class=\"inactive-0\">Aktywny</span>"
+
+#: views/developers/addon_status.thtml:97
+msgid "devcp_addon_status_header_criteria"
+msgstr "Kryteria kompletacji dodatku"
+
+#: views/developers/addon_status.thtml:164
+msgid "devcp_addon_status_header_inactive"
+msgstr "Status aktywności: <span class=\"inactive-1\">Nieaktywny</span>"
+
+#: views/developers/addon_status.thtml:117
+msgid "devcp_addon_status_header_nomination"
+msgstr "Kryteria nominacji do upublicznienia"
+
+#: views/developers/addon_status.thtml:190
+msgid "devcp_addon_status_header_trusted"
+msgstr "Status zaufania: <span class=\"status-4\">Zaufany</span>"
+
+#: views/developers/addon_status.thtml:165
+msgid "devcp_addon_status_inactive"
+msgstr "Dodatek jest <span class=\"inactive-1\">nieaktywny</span>. Oznacza to, że Twój dodatek nie jest wyświetlany w żadnym wykazie – niezależnie od swojego statusu. Aktualizacje <b>nie</b> są udostępniane przez usługę aktualizacji."
+
+#: views/developers/addon_status.thtml:128
+msgid "devcp_addon_status_nominate_disabled"
+msgstr "Przed nominacją dodatku do <span class=\"status-4\">upublicznienia</span> muszą być spełnione powyższe kryteria."
+
+#: views/developers/addon_status.thtml:125
+msgid "devcp_addon_status_nominate_enabled"
+msgstr "Teraz naciskając przycisk „Nominuj†możesz nominować dodatek do <span class=\"status-4\">upublicznienia</span>."
+
+#: views/developers/addon_status.thtml:64
+msgid "devcp_addon_status_public"
+msgstr "Upubliczniony"
+
+#: views/developers/addon_status.thtml:63
+msgid "devcp_addon_status_sandbox"
+msgstr "Piaskownica"
+
+#. %s is an email address.
+#: views/developers/addon_status.thtml:89
+msgid "devcp_addon_status_switch_disabled"
+msgstr "Dodatek został <span class=\"status-5\">wyłączony</span> przez administratora i nie może być używany. Jeśli masz jakieś pytania, wyślij e-mail na adres %s."
+
+#: views/developers/addon_status.thtml:67
+msgid "devcp_addon_status_switch_incomplete"
+msgstr "Dodatek jest <span class=\"status-0\">niekompletny</span>. Oznacza to, że Twój dodatek nie jest wyświetlany w żadnej części witryny ani nie jest dostępny dla usługi aktualizacji. Możesz powrócić do tej strony, aby zakończyć kompletację dodatku i wysłać go do <span class=\"status-1\">piaskownicy</span> po spełnieniu poniższych kryteriów kompletacji dodatku."
+
+#. %s is a number, perhaps 42.
+#: views/developers/addon_status.thtml:77
+msgid "devcp_addon_status_switch_nominated"
+msgstr "Dodatek jest nominowany do <span class=\"status-4\">upublicznienia</span> i oczekuje na recenzję edytora. Liczba innych dodatków oczekujących w kolejce do recenzji: %s."
+
+#. %s is an email address.
+#: views/developers/addon_status.thtml:81
+msgid "devcp_addon_status_switch_pending"
+msgstr "Dodatek ciągle oczekuje na recenzję. Nie powinno się to zdarzyć. Wyślij wiadomość do %s zawierającą ID dodatku i stan tego błędu."
+
+#: views/developers/addon_status.thtml:85
+msgid "devcp_addon_status_switch_public"
+msgstr "Dodatek jest <span class=\"status-4\">upubliczniony</span>, co oznacza, że będzie on widoczny we wszystkich wykazach i wynikach wyszukiwania i może być pobierany bez żadnych ograniczeń. Aktualizacje dodatku są dostępne przez usługę sprawdzania aktualizacji."
+
+#: views/developers/addon_status.thtml:71
+#: views/developers/addon_status.thtml:75
+msgid "devcp_addon_status_switch_sandbox"
+msgstr "Dodatek jest w <span class=\"status-1\">piaskownicy</span>, co oznacza, że będzie on widoczny we wszystkich wykazach i wynikach wyszukiwania, ale, aby go pobrać, użytkownicy muszą się zalogować. Aktualizacje dodatku <b>nie</b> są dostępne przez usługę sprawdzania aktualizacji."
+
+#. %s is the add-on name.
+#: views/developers/addon_status_nominate.thtml:43
+#: views/developers/addon_status_confirm.thtml:43
+#: views/developers/addon_status.thtml:43
+msgid "devcp_addon_status_title"
+msgstr "Status %s"
+
+#: views/developers/addon_status.thtml:191
+msgid "devcp_addon_status_trusted"
+msgstr "Dodatek ma status <span class=\"status-4\">zaufanego</span> dodatku. Oznacza to, że możesz wysyłać aktualizacje tego dodatku bez recenzowania przez edytora."
+
+#: views/developers/dashboard.thtml:68
+msgid "devcp_dashboard_active"
+msgstr "Aktywny"
+
+#. %1$s is the add-on type string
+#. %2$s is Inactive or Active in a <span>
+#. %3$s is the addon's public status (Public, In Sandbox, ...) in a <span>
+#: views/developers/dashboard.thtml:69
+msgid "devcp_dashboard_addontype_status"
+msgstr "Kategoria: %1$s, Status: %2$s i %3$s"
+
+#: views/developers/dashboard.thtml:67
+msgid "devcp_dashboard_change_status"
+msgstr "Zmień status"
+
+#. %s is the addons email address.
+#: views/developers/dashboard.thtml:99
+msgid "devcp_dashboard_disabled_questions"
+msgstr "Dodatek został wyłączony przez administratora i nie może być używany. Jeśli masz jakieś pytania, wyślij e-mail na adres %s."
+
+#. %s is the (localized) add-on status string in a span, e.g. "Disabled"
+#: views/developers/dashboard.thtml:98
+msgid "devcp_dashboard_disabled_status"
+msgstr "Status dodatku: %s"
+
+#: views/developers/dashboard.thtml:43
+msgid "devcp_dashboard_header_main"
+msgstr "Panel programisty"
+
+#: views/developers/dashboard.thtml:110
+msgid "devcp_dashboard_header_welcome"
+msgstr "Witamy w Panelu programisty"
+
+#: views/developers/dashboard.thtml:68
+msgid "devcp_dashboard_inactive"
+msgstr "Nieaktywny"
+
+#. %s is a date in the _('date') format
+#: views/developers/dashboard.thtml:65
+msgid "devcp_dashboard_last_edited"
+msgstr "Ostatnio edytowany %s"
+
+#: views/developers/dashboard.thtml:111
+msgid "devcp_dashboard_learn"
+msgstr "Aktualnie nie masz żadnego dodatku przechowywanego na witrynie Mozilla Add-ons. Aby dowiedzieć siÄ™, jak ta technologia dziaÅ‚a i wysÅ‚ać swój pierwszy dodatek, kliknij „Zaczynamy!â€."
+
+#: views/developers/dashboard.thtml:112
+msgid "devcp_dashboard_start"
+msgstr "Zaczynamy!"
+
+#: views/developers/dashboard.thtml:82
+msgid "devcp_dashboard_versions"
+msgstr "Wersje i pliki"
+
+#: views/developers/dashboard.thtml:91
+msgid "devcp_dashboard_versions_new"
+msgstr "Wyślij nową wersję"
+
+#. %s is the preview ID number.
+#: controllers/developers_controller.php:1415
+msgid "devcp_delete_previews_error"
+msgstr "Nie można usunąć z bazy danych obrazka podglądu %s. Proszę spróbować ponownie."
+
+#. %s is the preview ID number.
+#: controllers/developers_controller.php:1413
+msgid "devcp_delete_previews_success"
+msgstr "Obrazek o numerze %s został usunięty."
+
+#: controllers/developers_controller.php:1089
+msgid "devcp_delete_version_priv_error"
+msgstr "Nie masz uprawnień do usuwania wersji lub plików."
+
+#. %1$s is the count of files, a number
+#. %2$s is a status string like _('Public') or _('Incomplete')
+#: controllers/components/amo.php:549
+msgid "devcp_describe_version_status"
+msgid_plural "devcp_describe_version_status"
+msgstr[0] "%1$s plik o statusie %2$s"
+msgstr[1] "%1$s pliki o statusie %2$s"
+msgstr[2] "%1$s plików o statusie %2$s"
+
+#. %s is a version number. Example: 3.0
+#: views/developers/versions.thtml:65
+#, php-format
+msgid "devcp_details_version"
+msgstr "Wersja %s"
+
+#: views/developers/discuss.thtml:68
+msgid "devcp_discuss_addreply_header"
+msgstr "Dodaj odpowiedź"
+
+#: views/developers/discuss.thtml:57
+msgid "devcp_discuss_allreplies_header"
+msgstr "Odpowiedzi"
+
+#. notice when an error occurs saving a discussion reply
+#. %1 is the email address (linked) for the amo-editors list
+#: views/developers/discuss.thtml:70
+msgid "devcp_discuss_error_notice"
+msgstr "W trakcie zapisywania Twojej odpowiedzi wystąpił błąd. W sprawie tego problemu proszę skontaktować się z %1$s."
+
+#. %1 is the add-on name, %2 is the add-on's version number currently being reviewed by an editor
+#: views/developers/discuss.thtml:46
+msgid "devcp_discuss_intro"
+msgstr "Edytor dodatku poprosił o dodatkowe informacje dotyczące wersji %2$s dodatku %1$s."
+
+#. %1 is the add-on name
+#: views/developers/discuss.thtml:43
+msgid "devcp_discuss_pagetitle"
+msgstr "Podaj więcej informacji dla recenzji dodatku %1$s"
+
+#. submit button text
+#: views/developers/discuss.thtml:79
+msgid "devcp_discuss_submit_reply"
+msgstr "Wyślij odpowiedź"
+
+#: views/developers/discuss.thtml:72
+msgid "devcp_discuss_success_message"
+msgstr "Odpowiedź została zapisana. Uczestnicy dyskusji zostaną powiadomieni za pomocą wiadomości e-mail."
+
+#. in an author/editor discussion about an add-on to be reviewed:
+#. %1 is the commenter's user name (linked).
+#. %2 is the full date the comment was made.
+#: views/developers/discuss.thtml:52
+#: views/developers/discuss.thtml:62
+msgid "devcp_discuss_writtenby"
+msgstr "napisana przez %1$s w dniu %2$s"
+
+#: views/developers/addon_edit_authors.thtml:72
+#: views/developers/addon_edit_authors.thtml:81
+msgid "devcp_edit_authors_add_author"
+msgstr "Dodaj kolejnego autora"
+
+#: views/developers/addon_edit_authors.thtml:96
+msgid "devcp_edit_authors_add_author_button"
+msgstr "Dodaj"
+
+#: views/developers/addon_edit_authors.thtml:83
+msgid "devcp_edit_authors_add_email"
+msgstr "Adres e-mail autora:"
+
+#: views/developers/addon_edit_authors.thtml:98
+msgid "devcp_edit_authors_add_loading"
+msgstr "Sprawdzanie konta e-mail…"
+
+#: views/developers/addon_edit_authors.thtml:70
+msgid "devcp_edit_authors_click_save"
+msgstr "Aby je zapisać, naciÅ›nij przycisk „Aktualizujâ€."
+
+#: views/developers/addon_edit_authors.thtml:58
+msgid "devcp_edit_authors_header_current"
+msgstr "Obecni autorzy"
+
+#: views/developers/addon_edit_authors.thtml:50
+msgid "devcp_edit_authors_header_manage"
+msgstr "ZarzÄ…dzanie autorami dodatku"
+
+#: views/developers/addon_edit_authors.thtml:93
+msgid "devcp_edit_authors_label_add_listed"
+msgstr "Wyświetlaj jako autora na ogólnodostępnych stronach"
+
+#: views/developers/addon_edit_authors.thtml:89
+msgid "devcp_edit_authors_label_developer"
+msgstr "<strong>Programista</strong> - Może zarządzać wszystkimi parametrami dodatku z wyjątkiem dodawania i usuwania innych autorów."
+
+#: views/developers/addon_edit_authors.thtml:88
+msgid "devcp_edit_authors_label_owner"
+msgstr "<strong>Właściciel</strong> - Może zarządzać wszystkimi parametrami dodatku, włącznie z dodawaniem i usuwaniem innych autorów."
+
+#: views/developers/addon_edit_authors.thtml:90
+msgid "devcp_edit_authors_label_viewer"
+msgstr "<strong>Obserwator</strong> - Może oglądać strony programisty i statystyki, ale nie może wykonywać żadnych zmian."
+
+#. Placeholder for the empty option in a <select>.
+#: views/developers/addon_edit_categories.thtml:69
+msgid "devcp_edit_authors_option_empty"
+msgstr "----------------"
+
+#: views/developers/addon_edit_authors.thtml:86
+msgid "devcp_edit_authors_select_role"
+msgstr "Wybierz funkcjÄ™ dla autora:"
+
+#. Column name in a table.
+#: views/developers/addon_edit_authors.thtml:62
+msgid "devcp_edit_authors_th_author"
+msgstr "Autor"
+
+#. Column name in a table.
+#: views/developers/addon_edit_authors.thtml:64
+msgid "devcp_edit_authors_th_listed"
+msgstr "Wyświetlanie"
+
+#. Column name in a table.
+#: views/developers/addon_edit_authors.thtml:63
+msgid "devcp_edit_authors_th_role"
+msgstr "Funkcja"
+
+#: views/developers/addon_edit_authors.thtml:77
+msgid "devcp_edit_authors_update_author"
+msgstr "Aktualizuj"
+
+#: views/developers/addon_edit_categories.thtml:99
+msgid "devcp_edit_categories_button_update"
+msgstr "Aktualizuj"
+
+#: views/developers/addon_edit_categories.thtml:88
+msgid "devcp_edit_categories_does_not_fit"
+msgstr "Dodatek nie pasuje do żadnej dostępnej kategorii."
+
+#. %s is the application name (Firefox, Thunderbird).
+#: views/developers/addon_edit_categories.thtml:61
+msgid "devcp_edit_categories_header_application"
+msgstr "Kategorie programu %s"
+
+#: views/developers/addon_edit_categories.thtml:49
+msgid "devcp_edit_categories_header_manage"
+msgstr "ZarzÄ…dzanie kategoriami dodatku"
+
+#: views/developers/addon_edit_categories.thtml:91
+msgid "devcp_edit_categories_hover"
+msgstr "Aby zobaczyć opis kategorii, umieść kursor myszy nad jej nazwą."
+
+#. %s is the category number (1, 2, 3).
+#: views/developers/addon_edit_categories.thtml:67
+msgid "devcp_edit_categories_label_category_num"
+msgstr "Kategoria %s"
+
+#: views/developers/addon_edit_categories.thtml:94
+#: views/developers/addon_edit_categories.thtml:103
+msgid "devcp_edit_categories_none_available"
+msgstr "Dla tego typu dodatku i programu nie są dostępne żadne kategorie."
+
+#: views/developers/addon_edit_categories.thtml:86
+msgid "devcp_edit_categories_other"
+msgstr "Umieść dodatek w tej kategorii, tylko jeśli nie można skojarzyć go z żadną inną dostępną kategorią."
+
+#. %s is the application name (Firefox, Thunderbird).
+#: views/developers/addon_edit_categories.thtml:63
+msgid "devcp_edit_categories_select_application_categories"
+msgstr "Zaznacz maksymalnie trzy kategorie, do jakich można zaliczyć dodatek współpracujący z programem %s"
+
+#: views/developers/addon_edit.thtml:47
+msgid "devcp_edit_dd_manage_authors"
+msgstr "Dodaj lub usuń użytkowników, którzy mogą zarządzać tym dodatkiem."
+
+#: views/developers/addon_edit.thtml:49
+msgid "devcp_edit_dd_manage_categories"
+msgstr "Wybierz właściwe kategorie dla każdego programu, z jakim współpracuje dodatek."
+
+#: views/developers/addon_edit.thtml:51
+msgid "devcp_edit_dd_manage_description"
+msgstr "Dodaj i modyfikuj podsumowanie dodatku, opis, licencję użytkownika i politykę prywatności."
+
+#: views/developers/addon_edit.thtml:53
+msgid "devcp_edit_dd_manage_properties"
+msgstr "Zmień nazwę dodatku, stronę domową, ikonę i inne etykiety."
+
+#: views/developers/addon_edit_descriptions.thtml:116
+msgid "devcp_edit_description_button_update"
+msgstr "Aktualizuj"
+
+#: views/developers/addon_edit_descriptions.thtml:115
+msgid "devcp_edit_description_correct_error"
+msgstr "Napraw błędy wyszczególnione poniżej czerwonym kolorem."
+
+#: views/developers/addon_edit_descriptions.thtml:51
+msgid "devcp_edit_descriptions_header"
+msgstr "Edytowanie opisów dodatku"
+
+#: views/developers/addon_edit_descriptions.thtml:94
+msgid "devcp_edit_descriptions_transbox_comments_description"
+msgstr "Różne informacje, jakie użytkownicy chcą znać, nie są właściwe do zamieszczania w podsumowaniu czy opisie – można podać je tutaj. Komentarzy zazwyczaj używa się do załączenia wykazu znanych błędów, informacji jak zgłaszać błędy, podania przypuszczalnej daty wydania nowej wersji itp."
+
+#: views/developers/addon_edit_descriptions.thtml:93
+msgid "devcp_edit_descriptions_transbox_comments_name"
+msgstr "Komentarze autora"
+
+#: views/developers/addon_edit_descriptions.thtml:86
+msgid "devcp_edit_descriptions_transbox_description_description"
+msgstr "Opis dodatku jest obszerniejszym opisem funkcji, zastosowania i innych istotnych danych. Jest on wyświetlany na stronie dodatku poniżej podsumowania."
+
+#: views/developers/addon_edit_descriptions.thtml:85
+msgid "devcp_edit_descriptions_transbox_description_name"
+msgstr "Opis dodatku"
+
+#: views/developers/addon_edit_descriptions.thtml:103
+msgid "devcp_edit_descriptions_transbox_eula_description"
+msgstr "Jeśli dodatek ma Licencję użytkownika (EULA), wprowadź jej treść tutaj. Przed zainstalowaniem dodatku użytkownicy będą musieli zaakceptować postanowienia licencji. Zwróć uwagę na to, że EULA nie jest tym samym, co licencje stosowane dla kodu np. GPL lub MPL."
+
+#: views/developers/addon_edit_descriptions.thtml:102
+msgid "devcp_edit_descriptions_transbox_eula_name"
+msgstr "Licencja użytkownika"
+
+#: views/developers/addon_edit_descriptions.thtml:112
+msgid "devcp_edit_descriptions_transbox_privacy_description"
+msgstr "Jeśli dodatek ma politykę prywatności, wprowadź jej treść tutaj. Na stronie dodatku będzie wyświetlany odnośnik do niej."
+
+#: views/developers/addon_edit_descriptions.thtml:111
+msgid "devcp_edit_descriptions_transbox_privacy_name"
+msgstr "Polityka prywatności"
+
+#: views/developers/addon_edit_descriptions.thtml:78
+msgid "devcp_edit_descriptions_transbox_summary_description"
+msgstr "Podsumowanie jest krótkim opisem podstawowych funkcji dodatku. Jest ono wyświetlane w wykazach przeglądania i wyników szukania dodatków, a także na górze strony dodatku. Długość podsumowania limitowana jest do <strong>250 znaków</strong>."
+
+#: views/developers/addon_edit_descriptions.thtml:77
+msgid "devcp_edit_descriptions_transbox_summary_name"
+msgstr "Podsumowanie dodatku"
+
+#: views/developers/addon_edit.thtml:46
+msgid "devcp_edit_dt_manage_authors"
+msgstr "ZarzÄ…dzanie autorami dodatku"
+
+#: views/developers/addon_edit.thtml:48
+msgid "devcp_edit_dt_manage_categories"
+msgstr "ZarzÄ…dzanie kategoriami dodatku"
+
+#: views/developers/addon_edit.thtml:50
+msgid "devcp_edit_dt_manage_descriptions"
+msgstr "ZarzÄ…dzanie opisami dodatku"
+
+#: views/developers/addon_edit.thtml:52
+msgid "devcp_edit_dt_manage_properties"
+msgstr "Zarządzanie właściwościami dodatku"
+
+#: views/developers/addon_edit_properties.thtml:170
+msgid "devcp_edit_label_externalsoftware"
+msgstr "Dodatek wymaga zewnętrznego oprogramowania"
+
+#: views/developers/addon_edit_properties.thtml:205
+msgid "devcp_edit_label_locale_disambiguation"
+msgstr "Dodatkowe informacje o lokalizacji"
+
+#: views/developers/addon_edit_properties.thtml:168
+msgid "devcp_edit_label_prerelease"
+msgstr "To jest wydanie wstępne"
+
+#: views/developers/addon_edit_properties.thtml:169
+msgid "devcp_edit_label_sitespecific"
+msgstr "Dodatek właściwy konkretnej stronie"
+
+#: views/developers/addon_edit_properties.thtml:202
+msgid "devcp_edit_label_target_locale"
+msgstr "Docelowa lokalizacja"
+
+#: views/developers/addon_edit_properties.thtml:212
+msgid "devcp_edit_properties_button_update"
+msgstr "Aktualizuj"
+
+#: views/developers/addon_edit_properties.thtml:198
+msgid "devcp_edit_properties_change_guid"
+msgstr "Zmień, tylko jeśli zdajesz sobie sprawę ze wszystkich konsekwencji tej zmiany."
+
+#: views/developers/addon_edit_properties.thtml:109
+msgid "devcp_edit_properties_current_icon"
+msgstr "Aktualna ikona"
+
+#: views/developers/addon_edit_properties.thtml:85
+msgid "devcp_edit_properties_default_locale"
+msgstr "Domyślne ustawienie regionalne dodatku to podstawowy język, którego tłumaczenie musi być obecne. Jeśli w wybranym przez użytkownika języku tłumaczenie opisów dodatku jest niedostępne, opisy zostaną wyświetlone w domyślnej lokalizacji."
+
+#: views/developers/addon_edit_properties.thtml:167
+msgid "devcp_edit_properties_flags"
+msgstr "Te etykiety są używane do filtrowania i klasyfikowania dodatków."
+
+#: views/developers/addon_edit_properties.thtml:174
+msgid "devcp_edit_properties_guid"
+msgstr "Identyfikator GUID dodatku jest określony w jego pliku install.rdf i jest unikatowym identyfikatorem tego dodatku. Po opublikowaniu dodatku na witrynie Mozilla Add-ons nie można zmieniać tego identyfikatora."
+
+#: views/developers/addon_edit_properties.thtml:53
+msgid "devcp_edit_properties_header"
+msgstr "Edycja właściwości dodatku"
+
+#: views/developers/addon_edit_properties.thtml:186
+msgid "devcp_edit_properties_header_addon_type"
+msgstr "Typ dodatku"
+
+#: views/developers/addon_edit_properties.thtml:181
+msgid "devcp_edit_properties_header_admin_settings"
+msgstr "Ustawienia administratora"
+
+#: views/developers/addon_edit_properties.thtml:84
+msgid "devcp_edit_properties_header_default_locale"
+msgstr "Domyślny język"
+
+#: views/developers/addon_edit_properties.thtml:166
+msgid "devcp_edit_properties_header_flags"
+msgstr "Etykiety dodatku"
+
+#: views/developers/addon_edit_properties.thtml:173
+#: views/developers/addon_edit_properties.thtml:197
+msgid "devcp_edit_properties_header_guid"
+msgstr "Identyfikator GUID dodatku"
+
+#: views/developers/addon_edit_properties.thtml:104
+msgid "devcp_edit_properties_header_icon"
+msgstr "Ikona dodatku"
+
+#: views/developers/addon_edit_properties.thtml:159
+msgid "devcp_edit_properties_header_other_settings"
+msgstr "Inne ustawienia"
+
+#. A header on the admin page to toggle trusted status.
+#: views/developers/addon_edit_properties.thtml:182
+msgid "devcp_edit_properties_header_trusted"
+msgstr "To jest zaufany dodatek?"
+
+#: views/developers/addon_edit_properties.thtml:160
+msgid "devcp_edit_properties_header_view_source"
+msgstr "Przeglądanie źródeł w trybie online"
+
+#. %s is a comma-separated list of image extensions ".png, .jpg"
+#: views/developers/addon_edit_properties.thtml:106
+msgid "devcp_edit_properties_icon"
+msgstr "Ikona dodatku to mały obrazek wyświetlany obok nazwy dodatku w wykazach przeglądania i wyników szukania, wyświetlanych stronach i w oknie dialogowym instalacji dodatku. Obrazek zostanie automatycznie przeskalowany do wymiarów 32 x 32 piksele. Użyj jednego z następujących typów obrazków: %s."
+
+#: views/developers/addon_edit_properties.thtml:171
+msgid "devcp_edit_properties_label_binary"
+msgstr "Dodatek zawiera komponenty binarne"
+
+#: views/developers/addon_edit_properties.thtml:185
+msgid "devcp_edit_properties_label_not_trusted"
+msgstr "Niezaufany"
+
+#: views/developers/addon_edit_properties.thtml:184
+msgid "devcp_edit_properties_label_trusted"
+msgstr "Zaufany"
+
+#: views/developers/addon_edit_properties.thtml:110
+msgid "devcp_edit_properties_new_icon"
+msgstr "Nowa ikona"
+
+#: views/developers/addon_edit_properties.thtml:118
+msgid "devcp_edit_properties_remove_icon"
+msgstr "Usuń ikonę"
+
+#: views/developers/addon_edit_properties.thtml:136
+msgid "devcp_edit_properties_transbox_homepage_description"
+msgstr "Jeśli dodatek ma inną stronę domową niż na Mozilla Add-ons, wprowadź jej adres tutaj. Dodając tłumaczenia dodatku, nie ma konieczności lokalizowania witryny na inne języki."
+
+#: views/developers/addon_edit_properties.thtml:135
+msgid "devcp_edit_properties_transbox_homepage_name"
+msgstr "Strona domowa dodatku"
+
+#: views/developers/addon_edit_properties.thtml:79
+msgid "devcp_edit_properties_transbox_name_description"
+msgstr "Nazwa dodatku jest wyświetlana we wszystkich wykazach, w których znajduje się dodatek."
+
+#: views/developers/addon_edit_properties.thtml:78
+msgid "devcp_edit_properties_transbox_name_name"
+msgstr "Nazwa dodatku"
+
+#: views/developers/addon_edit_properties.thtml:145
+msgid "devcp_edit_properties_transbox_supportemail_description"
+msgstr "Jeśli masz adres e-mail, na który użytkownicy mogą kierować zapytania i prośby o pomoc, wprowadź go tutaj. Dodając tłumaczenia, nie ma konieczności posiadania adresów e-mail dla różnych języków."
+
+#: views/developers/addon_edit_properties.thtml:144
+msgid "devcp_edit_properties_transbox_supportemail_name"
+msgstr "Adres e-mail wsparcia"
+
+#: views/developers/addon_edit_properties.thtml:154
+msgid "devcp_edit_properties_transbox_supporturl_description"
+msgstr "Jeśli dodatek ma witrynę lub forum pomocy, wprowadź ich adresy tutaj. Dodając tłumaczenia, nie ma konieczności, aby witryna była zlokalizowana na inne języki."
+
+#: views/developers/addon_edit_properties.thtml:153
+msgid "devcp_edit_properties_transbox_supporturl_name"
+msgstr "Witryna wsparcia"
+
+#: views/developers/addon_edit_properties.thtml:183
+msgid "devcp_edit_properties_trusted"
+msgstr "Zaufane dodatki mogą być upubliczniane bez recenzji edytora."
+
+#. %s is href="..." and should stay in the <a> tag.
+#: views/developers/addon_edit_properties.thtml:119
+msgid "devcp_edit_properties_undelete"
+msgstr "Ikona zostanie usunięta podczas aktualizacji. <a %s>Anuluj</a>"
+
+#: views/developers/addon_edit_properties.thtml:161
+msgid "devcp_edit_properties_view_source"
+msgstr "Jeśli sobie tego życzysz, źródło plików Twojego dodatku może być oglądane w trybie online przez każdego zalogowanego użytkownika."
+
+#: views/developers/addon_edit_properties.thtml:162
+msgid "devcp_edit_properties_view_source_allow"
+msgstr "Zezwalaj na przeglądanie źródła w trybie online"
+
+#: views/developers/addon_edit_properties.thtml:163
+msgid "devcp_edit_properties_view_source_do_not_allow"
+msgstr "Nie zezwalaj na przeglądanie źródła w trybie online"
+
+#: views/elements/developers/editbox.thtml:46
+msgid "devcp_editbox_authors"
+msgstr "Autorzy"
+
+#: views/elements/developers/editbox.thtml:47
+msgid "devcp_editbox_categories"
+msgstr "Kategorie"
+
+#: views/elements/developers/editbox.thtml:52
+msgid "devcp_editbox_change_status"
+msgstr "Zmień status"
+
+#: views/elements/developers/editbox.thtml:48
+msgid "devcp_editbox_descriptions"
+msgstr "Opisy"
+
+#: views/elements/developers/editbox.thtml:43
+msgid "devcp_editbox_edit_addon"
+msgstr "Edytuj dodatek"
+
+#: views/elements/developers/editbox.thtml:57
+msgid "devcp_editbox_new_version"
+msgstr "Nowa wersja"
+
+#: views/elements/developers/editbox.thtml:49
+msgid "devcp_editbox_properties"
+msgstr "Właściwości"
+
+#: views/elements/developers/editbox.thtml:60
+msgid "devcp_editbox_screenshots"
+msgstr "Obrazki"
+
+#: views/elements/developers/editbox.thtml:53
+msgid "devcp_editbox_statistics_dashboard"
+msgstr "Panel statystyk"
+
+#: views/elements/developers/editbox.thtml:54
+msgid "devcp_editbox_versions"
+msgstr "Wersje i pliki"
+
+#: views/elements/developers/editbox.thtml:42
+msgid "devcp_editbox_view_listing"
+msgstr "Strona dodatku"
+
+#: views/elements/developers/editorsmenu.thtml:59
+msgid "devcp_editorsqueue_featured"
+msgstr "Polecane dodatki"
+
+#. %1 is the review count
+#: views/elements/developers/editorsqueue.thtml:42
+#: views/elements/developers/editorsmenu.thtml:56
+#, php-format
+msgid "devcp_editorsqueue_moderatedreviews"
+msgid_plural "devcp_editorsqueue_moderatedreviews"
+msgstr[0] "Recenzje moderowane (%s)"
+msgstr[1] "Recenzje moderowane (%s)"
+msgstr[2] "Recenzje moderowane (%s)"
+
+#. %1 is the nominated addons count
+#: views/elements/developers/editorsqueue.thtml:44
+#: views/elements/developers/editorsmenu.thtml:58
+#, php-format
+msgid "devcp_editorsqueue_nominated"
+msgid_plural "devcp_editorsqueue_nominated"
+msgstr[0] "Dodatki nominowane (%s)"
+msgstr[1] "Dodatki nominowane (%s)"
+msgstr[2] "Dodatki nominowane (%s)"
+
+#. %1 is the update count
+#: views/elements/developers/editorsqueue.thtml:43
+#: views/elements/developers/editorsmenu.thtml:57
+#, php-format
+msgid "devcp_editorsqueue_pendingupdates"
+msgid_plural "devcp_editorsqueue_pendingupdates"
+msgstr[0] "OczekujÄ…ce aktualizacje (%s)"
+msgstr[1] "OczekujÄ…ce aktualizacje (%s)"
+msgstr[2] "OczekujÄ…ce aktualizacje (%s)"
+
+#: controllers/statistics_controller.php:147
+#: controllers/statistics_controller.php:361
+#: controllers/previews_controller.php:108
+#: controllers/previews_controller.php:211
+#: controllers/previews_controller.php:312
+msgid "devcp_error_addon_access_denied"
+msgstr "Nie masz dostępu do tego dodatku."
+
+#. %s is a complete URL with the text from devcp_error_appversion_reference_link_text
+#. in the <a> tag. This should be fixed.
+#: controllers/components/developers.php:591
+#, php-format
+msgid "devcp_error_appversion_reference_link"
+msgstr "Więcej informacji można znaleźć na %s."
+
+#. This is the link text in the <a> for devcp_error_appversion_reference_link. This
+#. should be fixed.
+#: controllers/components/developers.php:591
+msgid "devcp_error_appversion_reference_link_text"
+msgstr "tej stronie"
+
+#: views/developers/addon_edit_authors.thtml:76
+msgid "devcp_error_empty_authors"
+msgstr "Dodatek musi mieć przynajmniej jednego właściciela."
+
+#. %1$s is the name of the file
+#: controllers/components/developers.php:658
+msgid "devcp_error_file_exists"
+msgstr "Ta wersja dodatku już istnieje. Aby dokonać zamiany, musisz najpierw usunąć plik %1$s."
+
+#. %1$s is a file extension. Example: .exe
+#. %2$s is a comma separated list of extensions. Example: .xpi, .jar
+#: controllers/components/developers.php:355
+#, php-format
+msgid "devcp_error_file_extension"
+msgstr "To rozszerzenie pliku (%1$s) nie jest dozwolone dla wybranego typu dodatku. Prosimy skorzystać z jednego z tych: %2$s"
+
+#: controllers/components/developers.php:64
+msgid "devcp_error_five_categories"
+msgstr "Wybierz nie więcej niż pięć kategorii."
+
+#: controllers/components/developers.php:526
+msgid "devcp_error_guid_application"
+msgstr "Identyfikator tego dodatku (ID) jest już używany przez inny dodatek."
+
+#: controllers/components/developers.php:337
+#: controllers/components/developers.php:389
+msgid "devcp_error_http_incomplete"
+msgstr "Transfer niekompletny"
+
+#: controllers/components/developers.php:335
+#: controllers/components/developers.php:336
+#: controllers/components/developers.php:387
+#: controllers/components/developers.php:388
+msgid "devcp_error_http_maxupload"
+msgstr "Został przekroczony maksymalny rozmiar wysyłanego pliku."
+
+#: controllers/components/developers.php:338
+#: controllers/components/developers.php:390
+msgid "devcp_error_http_nofile"
+msgstr "Nie wysłano żadnego pliku"
+
+#. %1$s is a file extension. Example: .exe
+#. %2$s is a comma separated list of extensions. Example: .xpi, .jar
+#: controllers/components/developers.php:401
+#, php-format
+msgid "devcp_error_icon_extension"
+msgstr "To rozszerzenie pliku (%1$s) nie jest dozwolone dla ikony. Prosimy skorzystać z jednego z tych: %2$s"
+
+#: controllers/developers_controller.php:504
+msgid "devcp_error_index_rdf_notfound"
+msgstr "Brak pliku install.rdf."
+
+#: controllers/components/developers.php:601
+msgid "devcp_error_install_manifest"
+msgstr "W pliku install.rdf zostały znalezione następujące błędy:"
+
+#: controllers/developers_controller.php:1463
+msgid "devcp_error_invalid_addontype"
+msgstr ""
+
+#. %$1s is a version. Example: 3.1.1
+#. %$2s is an add-on name.
+#: controllers/components/developers.php:569
+#: controllers/components/developers.php:581
+#, php-format
+msgid "devcp_error_invalid_appversion"
+msgstr "%1$s nie jest prawidłową wersją dla %2$s"
+
+#. %s is a string
+#: controllers/components/developers.php:521
+#, php-format
+msgid "devcp_error_invalid_guid"
+msgstr "Identyfikator (ID) dla tego dodatku jest nieprawidłowy: %s"
+
+#. %$1s is a version. Example: 3.1.1
+#. %$2s is an add-on name.
+#: controllers/components/developers.php:572
+#, php-format
+msgid "devcp_error_invalid_minversion"
+msgstr "%1$s nie jest prawidłową wersją dla programu %2$s: wersja minimalna nie może zawierać *"
+
+#: controllers/components/developers.php:536
+msgid "devcp_error_invalid_version"
+msgstr "Wersja tego dodatku jest nieprawidłowa: zobacz <a href=\"http://developer.mozilla.org/en/docs/Toolkit_version_format\">specyfikację</a> (w języku angielskim)"
+
+#: controllers/components/developers.php:531
+msgid "devcp_error_invalid_version_spaces"
+msgstr "Wersja tego dodatku jest nieprawidłowa: wersje nie mogą zawierać spacji."
+
+#. %s is an error message from the parser.
+#: controllers/components/developers.php:501
+#, php-format
+msgid "devcp_error_manifest_parse"
+msgstr "Podczas przetwarzania pliku install.rdf został znaleziony błąd: %s"
+
+#: controllers/components/developers.php:373
+msgid "devcp_error_move_file"
+msgstr "Nie można przenieść pliku"
+
+#. %s is the name of a file
+#: controllers/components/developers.php:650
+#: controllers/components/developers.php:662
+#: controllers/components/developers.php:667
+#: controllers/components/developers.php:727
+#: controllers/components/developers.php:738
+#: controllers/components/developers.php:743
+#, php-format
+msgid "devcp_error_moving_file"
+msgstr "Podczas przenoszenia pliku %s wystąpił błąd."
+
+#: controllers/components/developers.php:595
+msgid "devcp_error_mozilla_application"
+msgstr "Należy określić przynajmniej jeden poprawny program docelowy Mozilli."
+
+#: controllers/components/developers.php:516
+msgid "devcp_error_no_guid"
+msgstr "W pliku install.rdf nie znaleziono identyfikatora (ID) tego dodatku."
+
+#: controllers/components/developers.php:287
+msgid "devcp_error_no_platform"
+msgstr "Nie wybrano systemu"
+
+#: controllers/components/developers.php:59
+msgid "devcp_error_one_category"
+msgstr "Należy wybrać przynajmniej jedną kategorię."
+
+#: controllers/components/developers.php:92
+msgid "devcp_error_one_user"
+msgstr "Dodatek musi mieć określonego przynajmniej jednego autora."
+
+#. %1$s is a file extension. Example: .exe
+#. %2$s is a comma separated list of extensions. Example: .xpi, .jar
+#: controllers/components/developers.php:1081
+#, php-format
+msgid "devcp_error_preview_extension"
+msgstr "Nie można wybrać tego rozszerzenia pliku (%1$s) dla pliku obrazka. Wybierz jedno z poniższych: %2$s"
+
+#: controllers/components/developers.php:511
+msgid "devcp_error_updatekey"
+msgstr "Dodatki nie mogą używać elementu updateKey. Należy usunąć go z install.rdf i spróbować ponownie."
+
+#: controllers/components/developers.php:506
+msgid "devcp_error_updateurl"
+msgstr "Dodatki nie mogą używać zewnętrznych adresów aktualizacji. Usuń go z pliku install.rdf i spróbuj ponownie."
+
+#: controllers/developers_controller.php:465
+#: controllers/components/developers.php:271
+msgid "devcp_error_upload_file"
+msgstr "Proszę wysłać plik."
+
+#: views/developers/uploader.thtml:135
+msgid "devcp_input_upload_file"
+msgstr "Wyślij plik"
+
+#: views/pages/js_constants.js.thtml:89
+msgid "devcp_js_a_cancel"
+msgstr "Anuluj"
+
+#: views/pages/js_constants.js.thtml:90
+msgid "devcp_js_add_email"
+msgstr "Wprowadź konto e-mail autora, którego chcesz dodać."
+
+#. alt text for a down-arrow image.
+#: views/pages/js_constants.js.thtml:81
+msgid "devcp_js_img_move_down"
+msgstr "Przenieś w dół"
+
+#. alt text for an up-arrow image.
+#: views/pages/js_constants.js.thtml:82
+msgid "devcp_js_img_move_up"
+msgstr "Przenieś w górę"
+
+#: views/pages/js_constants.js.thtml:91
+msgid "devcp_js_img_remove_compat"
+msgstr "Usuń kompatybilność z programem"
+
+#: views/pages/js_constants.js.thtml:86
+msgid "devcp_js_input_list_author"
+msgstr "Wyświetlaj jako autora na ogólnodostępnych wykazach"
+
+#: views/pages/js_constants.js.thtml:92
+msgid "devcp_js_license_select"
+msgstr "Wybierz licencjÄ™."
+
+#: views/pages/js_constants.js.thtml:93
+msgid "devcp_js_license_text"
+msgstr "Wprowadź tekst swojej licencji."
+
+#. <option> text in a <select> for Author role in an add-on.
+#: views/pages/js_constants.js.thtml:84
+msgid "devcp_js_option_developer"
+msgstr "Programista"
+
+#. <option> text in a <select> for Author role in an add-on.
+#: views/pages/js_constants.js.thtml:83
+msgid "devcp_js_option_owner"
+msgstr "Właściciel"
+
+#. <option> text in a <select> for Author role in an add-on.
+#: views/pages/js_constants.js.thtml:85
+msgid "devcp_js_option_viewer"
+msgstr "Obserwator"
+
+#: views/pages/js_constants.js.thtml:88
+msgid "devcp_js_remove_author"
+msgstr "Usuń autora"
+
+#: views/pages/js_constants.js.thtml:87
+msgid "devcp_js_sure_remove"
+msgstr "Czy <strong>na pewno</strong> chcesz usunąć tego autora?"
+
+#: views/pages/js_constants.js.thtml:77
+msgid "devcp_js_upload_alert"
+msgstr "Musisz wybrać plik do wysłania."
+
+#. %1$s is an addon id, like 32.
+#. %2$s is a version number, like 3.5.
+#: controllers/components/developers.php:1212
+msgid "devcp_license_existing"
+msgstr "Licencja autora dodatku %1$s %2$s"
+
+#: views/elements/developers/localebox.thtml:44
+msgid "devcp_localebox_header_localizedfields"
+msgstr "Pola lokalizowane"
+
+#. %1 is the default locale
+#: views/elements/developers/localebox.thtml:48
+#, php-format
+msgid "devcp_localebox_intro"
+msgstr "Niektóre pola na tej stronie są lokalizowane, by wyświetlały się w ojczystym języku użytkowników końcowych. Wybierz poniżej lokalizację, by edytować szczegóły swojego dodatku w danym języku. Jeśli tłumaczenie dla danej lokalizacji nie jest dostępne, zostanie przywrócony wybór domyślnej lokalizacji (%s)."
+
+#: views/elements/developers/sidebar.thtml:68
+#: views/elements/developers/myaddons.thtml:75
+msgid "devcp_myaddons_admincp_link"
+msgstr "Panel kontrolny administratora"
+
+#: views/elements/developers/sidebar.thtml:65
+#: views/elements/developers/myaddons.thtml:72
+msgid "devcp_myaddons_editorcp_link"
+msgstr "Panel kontrolny edytora"
+
+#: views/elements/developers/myaddons.thtml:52
+msgid "devcp_myaddons_link"
+msgstr "Moje dodatki"
+
+#: views/elements/developers/sidebar.thtml:70
+#: views/elements/developers/myaddons.thtml:77
+msgid "devcp_myaddons_mainpage_link"
+msgstr "Strona główna"
+
+#: views/elements/developers/sidebar.thtml:63
+#: views/elements/developers/myaddons.thtml:70
+msgid "devcp_myaddons_statistics_link"
+msgstr "Panel statystyk"
+
+#: views/elements/developers/sidebar.thtml:62
+#: views/elements/developers/myaddons.thtml:69
+msgid "devcp_myaddons_submitaddon_link"
+msgstr "Wyślij dodatek"
+
+#: views/elements/developers/sidebar.thtml:48
+#: views/elements/developers/myaddons.thtml:67
+msgid "devcp_myaddons_title"
+msgstr "Narzędzia programisty"
+
+#. %1$s is an add-on ID, perhaps 167.
+#. %2$s is a URL.
+#: controllers/developers_controller.php:256
+msgid "devcp_new_addon_error"
+msgstr "Identyfikator tego dodatku (%1$s) już występuje w bazie danych. Jeśli jest to Twój dodatek, możesz <a href=\"%2$s\">wysłać nową wersję</a>."
+
+#: views/developers/addon_status_nominate.thtml:62
+msgid "devcp_nominate_cancel"
+msgstr "Wróć do poprzedniej strony"
+
+#. %1 is the add-on name
+#: views/developers/addon_status_nominate.thtml:61
+#, php-format
+msgid "devcp_nominate_submit_nominate"
+msgstr "Nominuj %s"
+
+#: views/developers/addon_edit_properties.thtml:50
+#: views/developers/addon_status.thtml:49
+#: views/developers/versions_edit.thtml:50
+msgid "devcp_notice_changes_error"
+msgstr "<span>Część zmian nie została zapisana.</span><br />Sprawdź poniżej błędy, jakie wystąpiły. Pozostałe zmiany zostały zapisane."
+
+#: views/developers/addon_edit_authors.thtml:47
+#: views/developers/addon_edit_properties.thtml:47
+#: views/developers/addon_status.thtml:46
+#: views/developers/addon_edit_descriptions.thtml:47
+#: views/developers/versions_edit.thtml:47
+#: views/developers/addon_edit_categories.thtml:46
+msgid "devcp_notice_changes_saved"
+msgstr "<span>Zmiany zostały zapisane.</span><br />Niektóre zmiany mogą być widoczne we wszystkich częściach witryny dopiero po kilku godzinach."
+
+#: controllers/previews_controller.php:252
+msgid "devcp_notice_cleardefault"
+msgstr "Usunięcie tego obrazka podglądu, ustawionego jako domyślny, spowoduje, że inny obrazek zostanie automatycznie ustawiony jako domyślny obrazek podglądu."
+
+#: controllers/previews_controller.php:184
+#: controllers/previews_controller.php:251
+msgid "devcp_notice_makedefault"
+msgstr "Ustawienie tego obrazka jako domyślnego obrazka podglądu spowoduje, że obecny domyślny obrazek podglądu straci swój status."
+
+#: views/developers/addon_edit_authors.thtml:70
+msgid "devcp_notice_unsaved_changes"
+msgstr "SÄ… niezapisane zmiany. "
+
+#: controllers/developers_controller.php:87
+#: controllers/developers_controller.php:97
+#: controllers/developers_controller.php:100
+#: controllers/previews_controller.php:67
+#: controllers/previews_controller.php:79
+#: controllers/previews_controller.php:82
+msgid "devcp_pagetitle"
+msgstr "Panel kontrolny programisty"
+
+#: controllers/previews_controller.php:103
+#: controllers/previews_controller.php:104
+msgid "devcp_preview_add_pagetitle"
+msgstr "Dodawanie obrazka podglÄ…du"
+
+#: controllers/previews_controller.php:135
+msgid "devcp_preview_added_successfully"
+msgstr "Obrazek podglądu został dodany."
+
+#: controllers/previews_controller.php:323
+msgid "devcp_preview_deleted_successfully"
+msgstr "Obrazek podglądu został usunięty."
+
+#: controllers/previews_controller.php:194
+#: controllers/previews_controller.php:195
+msgid "devcp_preview_edit_pagetitle"
+msgstr "Edycja obrazka podglÄ…du"
+
+#: controllers/previews_controller.php:237
+msgid "devcp_preview_updated_successfully"
+msgstr "Obrazek podglądu został zaktualizowany."
+
+#: views/developers/previews.thtml:120
+msgid "devcp_previews_a_another"
+msgstr "Dodaj kolejny obrazek"
+
+#: views/developers/previews.thtml:96
+msgid "devcp_previews_a_delete"
+msgstr "Usuń"
+
+#: views/developers/previews.thtml:95
+msgid "devcp_previews_a_replace"
+msgstr "Zamień"
+
+#: views/developers/previews.thtml:126
+msgid "devcp_previews_a_update"
+msgstr "Aktualizuj"
+
+#: views/developers/previews.thtml:115
+#: views/developers/previews.thtml:124
+msgid "devcp_previews_add_new"
+msgstr "Dodaj obrazek"
+
+#. %s is a list of file extensions, e.g. ".png, .gif"
+#: views/developers/previews.thtml:116
+msgid "devcp_previews_add_select"
+msgstr "Wybierz obrazek do wysłania. Obrazki o rozmiarze większym niż 700 x 525 pikseli zostaną przeskalowane. Dozwolone typy plików: %s"
+
+#: views/developers/previews.thtml:121
+msgid "devcp_previews_click_below"
+msgstr "Aby wysÅ‚ać obrazek, naciÅ›nij przycisk „Aktualizujâ€."
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/previews.thtml:102
+msgid "devcp_previews_click_update"
+msgstr "Aby zapisać ten obrazek, naciÅ›nij na dole przycisk „Aktualizujâ€. (<a %s>Anulować?</a>)"
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/previews.thtml:107
+msgid "devcp_previews_error_message"
+msgstr "Ten obrazek zostanie usuniÄ™ty po naciÅ›niÄ™ciu na dole przycisku „Aktualizujâ€. (<a %s>Anulować?</a>)"
+
+#: views/previews/add.thtml:45
+msgid "devcp_previews_filetype_info"
+msgstr "Użyj poniższego formularza, by wysłać obrazek podglądu swojego dodatku w formacie PNG, JPG lub GIF. Obrazki, mające rozmiary większe niż: 700 x 525 pikseli zostaną automatycznie przeskalowane."
+
+#: views/previews/add.thtml:43
+msgid "devcp_previews_header_add"
+msgstr "Dodaj obrazek"
+
+#: views/developers/previews.thtml:80
+msgid "devcp_previews_header_caption"
+msgstr "Opis obrazka"
+
+#: views/previews/edit.thtml:43
+msgid "devcp_previews_header_edit"
+msgstr "Edytuj obrazek"
+
+#: views/developers/previews.thtml:93
+msgid "devcp_previews_label_default"
+msgstr "Domyślny obrazek"
+
+#: views/previews/add.thtml:54
+msgid "devcp_previews_label_file"
+msgstr "Plik obrazka"
+
+#: views/previews/add.thtml:59
+#: views/previews/edit.thtml:50
+msgid "devcp_previews_label_makedefault"
+msgstr "Ustaw ten obrazek jako domyślny obrazek podglądu"
+
+#: views/developers/previews.thtml:100
+msgid "devcp_previews_label_new"
+msgstr "Nowy obrazek:"
+
+#: views/developers/previews.thtml:118
+msgid "devcp_previews_label_upload"
+msgstr "Wyślij obrazek: "
+
+#: views/developers/previews.thtml:50
+msgid "devcp_previews_notice_error"
+msgstr "Nie można zapisać części nowych obrazków podglądu."
+
+#: views/developers/previews.thtml:47
+msgid "devcp_previews_notice_success"
+msgstr "Obrazki zostały zaktualizowane."
+
+#: views/developers/previews.thtml:59
+msgid "devcp_previews_p_screenshots"
+msgstr "Obrazki podglądu dla tego dodatku są wyświetlone poniżej. Możesz dokonać zmian w opisach lub zmienić obrazki. Domyślny obrazek podglądu to obrazek prezentujący dodatek wyświetlany w wykazach przeglądania i wyników szukania dodatków."
+
+#: views/previews/edit.thtml:55
+msgid "devcp_previews_submit_delete"
+msgstr "Usuń obrazek"
+
+#: views/previews/edit.thtml:55
+msgid "devcp_previews_submit_delete_confirm"
+msgstr "Czy na pewno usunąć ten obrazek?"
+
+#: views/previews/edit.thtml:54
+msgid "devcp_previews_submit_edit"
+msgstr "Edytuj obrazek"
+
+#: views/previews/add.thtml:63
+msgid "devcp_previews_submit_upload"
+msgstr "Wyślij"
+
+#: views/developers/previews.thtml:78
+msgid "devcp_previews_thumbnail"
+msgstr "Miniaturka"
+
+#. %s is the add-on name.
+#: views/developers/previews.thtml:44
+msgid "devcp_previews_title"
+msgstr "Menedżer obrazków podglądu dodatku %s"
+
+#: views/developers/uploader.thtml:74
+msgid "devcp_review_agreement_please"
+msgstr "Najpierw musisz zapoznać się i zaakceptować następującą Umowę programisty."
+
+#: views/elements/developers/rolecheck.thtml:42
+msgid "devcp_rolecheck_no_privs"
+msgstr "<span>Nie masz odpowiednich uprawnień do wykonania zmian na tej stronie.</span><br />Jeśli chcesz dokonać zmian, skontaktuj się z właścicielem dodatku."
+
+#: controllers/developers_controller.php:1315
+msgid "devcp_several_hours"
+msgstr "Niektóre zmiany mogą być widoczne we wszystkich częściach witryny dopiero po kilku godzinach."
+
+#: views/elements/developers/sidebar.thtml:52
+msgid "devcp_sidebar_a_dashboard"
+msgstr "Panel programisty"
+
+#. %s is a number
+#: views/elements/developers/statsbar.thtml:45
+#: views/developers/dashboard.thtml:79
+#, php-format
+msgid "devcp_statsbar_adu"
+msgstr "<em>%s</em> aktywnych dziennych użytkowników"
+
+#. %s is a number
+#: views/elements/developers/statsbar.thtml:41
+#: views/developers/dashboard.thtml:75
+#, php-format
+msgid "devcp_statsbar_total_downloads"
+msgstr "Liczba wszystkich pobrań: <em>%s</em>"
+
+#. %s is a number
+#: views/elements/developers/statsbar.thtml:43
+#: views/developers/dashboard.thtml:77
+#, php-format
+msgid "devcp_statsbar_weekly_downloads"
+msgstr "Tygodniowa liczba pobrań <em>%s</em>"
+
+#: views/developers/addon_status_confirm.thtml:59
+msgid "devcp_status_confirm_active"
+msgstr "Oznaczenie tego dodatku jako aktywny spowoduje wyświetlenie go w ogólnodostępnej części witryny w miejscu odpowiednim dla jego statusu włącznie z wykazami przeglądania i wyników wyszukiwania. Będzie można go pobierać i będzie dostępny dla aplikacji sprawdzającej aktualizacje. Z tego miejsca będzie można ponownie go wyłączyć."
+
+#: views/developers/addon_status_confirm.thtml:59
+msgid "devcp_status_confirm_active_sure"
+msgstr "Czy na pewno chcesz oznaczyć ten dodatek jako aktywny?"
+
+#: views/developers/addon_status_confirm.thtml:50
+msgid "devcp_status_confirm_header_sure"
+msgstr "Czy na pewno chcesz to zrobić?"
+
+#: views/developers/addon_status_confirm.thtml:55
+msgid "devcp_status_confirm_inactive"
+msgstr "Oznaczenie tego dodatku jako nieaktywny spowoduje, że nie będzie on wyświetlany w ogólnodostępnej części witryny włącznie z wykazami przeglądania i wyników wyszukiwania. Nie będzie można go pobierać i mie będzie dostępny dla aplikacji sprawdzającej aktualizacje. Z tego miejsca będzie można ponownie go włączyć."
+
+#: views/developers/addon_status_confirm.thtml:55
+msgid "devcp_status_confirm_inactive_sure"
+msgstr "Czy na pewno chcesz oznaczyć ten dodatek jako nieaktywny?"
+
+#: views/developers/addon_status_confirm.thtml:74
+msgid "devcp_status_confirm_no"
+msgstr "Nie, anuluj"
+
+#: views/developers/addon_status_confirm.thtml:67
+msgid "devcp_status_confirm_public"
+msgstr "Upublicznienie tego dodatku spowoduje, że każdy będzie mógł go pobrać i użytkownikom będą oferowane jego aktualizacje."
+
+#: views/developers/addon_status_confirm.thtml:67
+msgid "devcp_status_confirm_public_sure"
+msgstr "Czy na pewno chcesz upublicznić ten dodatek?"
+
+#: views/developers/addon_status_confirm.thtml:63
+msgid "devcp_status_confirm_sandbox"
+msgstr "Przeniesienie tego dodatku do piaskownicy spowoduje, że użytkownicy chcÄ…cy go pobrać, bÄ™dÄ… najpierw musieli siÄ™ zalogować i nie bÄ™dÄ… oferowane jego aktualizacje. Ponieważ obecnie Twój dodatek ma status „Upublicznionyâ€, w każdej chwili bÄ™dzie można go ponownie upublicznić."
+
+#: views/developers/addon_status_confirm.thtml:63
+msgid "devcp_status_confirm_sandbox_sure"
+msgstr "Czy na pewno chcesz przenieść ten dodatek do piaskownicy?"
+
+#: views/developers/addon_status_confirm.thtml:73
+msgid "devcp_status_confirm_yes"
+msgstr "Tak, chcÄ™"
+
+#: views/developers/addon_status_nominate.thtml:46
+msgid "devcp_status_nominate_error_notice"
+msgstr "<span>Informacje o nominacji są wymagane.</span><br />Wprowadź do pola tekstowego żądane informacje i spróbuj ponownie."
+
+#: views/developers/addon_status_nominate.thtml:55
+msgid "devcp_status_nominate_header"
+msgstr "Nominowanie dodatku"
+
+#: views/developers/dashboard.thtml:85
+msgid "devcp_summary_lastversion"
+msgstr "Najnowsza wersja:"
+
+#. %s is the add-on name.
+#: views/developers/addon_edit.thtml:43
+#: views/developers/addon_edit_authors.thtml:44
+#: views/developers/versions_delete.thtml:43
+#: views/developers/addon_edit_properties.thtml:44
+#: views/developers/addon_edit_descriptions.thtml:44
+#: views/developers/versions_edit.thtml:44
+#: views/developers/addon_edit_categories.thtml:43
+#: views/developers/versions.thtml:43
+msgid "devcp_title_edit_addon"
+msgstr "Edycja %s"
+
+#. title attribute for a javascript link that pops up a help dialog.
+#: views/elements/translationbox.thtml:68
+msgid "devcp_transbox_a_title_help"
+msgstr "Pomoc (wyświetlana na stronie)"
+
+#: views/elements/translationbox.thtml:68
+msgid "devcp_transbox_alt_help"
+msgstr "Pomoc"
+
+#. %1$s is <span>17</span>, %2$s is 42.
+#: views/elements/translationbox.thtml:101
+msgid "devcp_transbox_chars_used"
+msgstr "Użyte znaki: %1$s / %2$s"
+
+#: views/elements/translationbox.thtml:132
+msgid "devcp_transbox_delete_sure"
+msgstr "Czy na pewno chcesz usunąć to tłumaczenie?"
+
+#. %s is a locale, like en-US.
+#: views/elements/translationbox.thtml:143
+msgid "devcp_transbox_help_header_tabs"
+msgstr "Co to są karty „%s�"
+
+#: views/elements/translationbox.thtml:145
+msgid "devcp_transbox_help_header_what"
+msgstr "A co, jeśli nie mam żadnego tłumaczenia?"
+
+#: views/elements/translationbox.thtml:147
+msgid "devcp_transbox_help_hide"
+msgstr "Ukryj pomoc"
+
+#: views/elements/translationbox.thtml:146
+msgid "devcp_transbox_help_if"
+msgstr "Jeśli użytkownik przegląda witrynę, a tłumaczenie w jego języku jest niedostępne, opisy dodatku zostaną wyświetlone w domyślnym języku dodatku, określonym na stronie edycji właściwości dodatku. Jeśli nie masz żadnego tłumaczenia, do pola domyślnego języka wprowadź identyfikator języka jakim się posługujesz."
+
+#: views/elements/translationbox.thtml:144
+msgid "devcp_transbox_help_transbox"
+msgstr "Są to karty polskiego ustawienia regionalnego znajdujące się w <i>Panelu tłumaczeń</i>. W panelu tym można zlokalizować określone pola w innych językach, dla których masz tłumaczenie. Możesz dodawać, edytować i usuwać tłumaczenia używając kart ustawień regionalnych."
+
+#: views/elements/translationbox.thtml:85
+msgid "devcp_transbox_img_add_trans"
+msgstr "Dodaj tłumaczenie"
+
+#: views/elements/translationbox.thtml:86
+msgid "devcp_transbox_img_remove_trans"
+msgstr "Usuń tłumaczenie"
+
+#: views/elements/translationbox.thtml:123
+msgid "devcp_transbox_input_add_all"
+msgstr "Dodaj do wszystkich"
+
+#: views/elements/translationbox.thtml:122
+msgid "devcp_transbox_input_add_locale"
+msgstr "Dodaj"
+
+#: views/elements/translationbox.thtml:124
+#: views/elements/translationbox.thtml:135
+msgid "devcp_transbox_input_cancel"
+msgstr "Anuluj"
+
+#: views/elements/translationbox.thtml:134
+msgid "devcp_transbox_input_delete"
+msgstr "Usuń"
+
+#: views/elements/translationbox.thtml:113
+msgid "devcp_transbox_select_locale"
+msgstr "Wybierz identyfikator języka tłumaczenia:"
+
+#. %1$s and %2$s are GUIDs.
+#: controllers/developers_controller.php:343
+msgid "devcp_update_addon_guid_error"
+msgstr "Identyfikator dodatku GUID użyty w tym pliku (%1$s) nie zgadza się z istniejącym GUID dla tego dodatku (%2$s)."
+
+#: controllers/developers_controller.php:334
+msgid "devcp_update_addon_priv_error"
+msgstr "Nie masz odpowiednich uprawnień do aktualizacji tego dodatku."
+
+#. %1$s is a version number, %2$s is an add-on ID.
+#: controllers/developers_controller.php:399
+msgid "devcp_update_addon_version_belong_error"
+msgstr "Podana wersja (%1$s) nie jest wersjÄ… tego dodatku (%2$s)."
+
+#. %1$s is a version number, maybe 1.1.
+#. %2$s is a URL.
+#: controllers/developers_controller.php:351
+msgid "devcp_update_addon_version_exists_error"
+msgstr "Wersja dodatku o takim numerze (%1$s) już istnieje. Jeśli próbujesz dodać inny plik tej wersji, <a href=\"%2$s\">kliknij tutaj</a>."
+
+#. %1$s and %2$s are version numbers.
+#: controllers/developers_controller.php:405
+msgid "devcp_update_addon_version_match_error"
+msgstr "Wysłany numer wersji (%1$s) nie zgadza się z istniejącym numerem wersji (%2$s)."
+
+#: views/developers/uploader.thtml:68
+msgid "devcp_uploader_a_start"
+msgstr "Zaczynamy!"
+
+#: views/developers/uploader.thtml:137
+msgid "devcp_uploader_ajax_loading"
+msgstr "Wysyłanie pliku…"
+
+#: views/developers/uploader.thtml:82
+msgid "devcp_uploader_button_agree"
+msgstr "Dalej"
+
+#: views/developers/uploader.thtml:157
+msgid "devcp_uploader_button_edit"
+msgstr "Edytuj dodatek"
+
+#: views/developers/uploader.thtml:158
+msgid "devcp_uploader_button_later"
+msgstr "Skompletuję dodatek później."
+
+#: views/developers/uploader.thtml:168
+msgid "devcp_uploader_button_release"
+msgstr "Dodaj informacje o wydaniu"
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/uploader.thtml:156
+msgid "devcp_uploader_created_results"
+msgstr "<p>Strona Twojego dodatku została utworzona. Podstawowe informacje zostały uzyskane z wysłanego na nasz serwer pliku, ale można na stronie dodatku umieścić wiele innych informacji.</p><p>Dodatek jest obecnie oznaczony jako <strong>niekompletny</strong>. Aby ukończyć proces umieszczania dodatku, musisz upewnić się, że ma on właściwą nazwę, podsumowanie i opis, a także oznaczoną co najmniej jedną kategorię. Możesz edytować informacje o swoim dodatku, używając odnośnika znajdującego się poniżej, a na <a %s>stronie statusu</a>, w dowolnym czasie, sprawdzić jego aktualny status."
+
+#: views/developers/uploader.thtml:143
+msgid "devcp_uploader_error_correct"
+msgstr "Usuń ten problem i wyślij plik ponownie."
+
+#. %1$s is a version number, %2$s is a status, e.g Public or Incomplete.
+#: views/developers/uploader.thtml:175
+msgid "devcp_uploader_file_created"
+msgstr "Nowy plik wersji %1$s został dodany i jest obecnie oznaczony jako %2$s."
+
+#: views/developers/uploader.thtml:154
+msgid "devcp_uploader_header_created"
+msgstr "Dodatek został utworzony!"
+
+#: views/developers/uploader.thtml:141
+msgid "devcp_uploader_header_error"
+msgstr "Uups! Wygląda na to, że wystąpił problem z tym plikiem…"
+
+#: views/developers/uploader.thtml:173
+msgid "devcp_uploader_header_file_added"
+msgstr "Plik został dodany!"
+
+#: views/developers/uploader.thtml:66
+msgid "devcp_uploader_header_how"
+msgstr "Jak to wszystko funkcjonuje?"
+
+#. %s is the version number, e.g. 3.2.
+#: views/developers/uploader.thtml:163
+msgid "devcp_uploader_header_update_created"
+msgstr "Wersja %s została utworzona"
+
+#: views/developers/uploader.thtml:117
+msgid "devcp_uploader_header_upload"
+msgstr "Wyślij plik"
+
+#: views/developers/uploader.thtml:67
+msgid "devcp_uploader_how"
+msgstr "<p>Dziękujemy za zainteresowanie i umieszczenie swojego dodatku na witrynie Mozilla Add-ons. Przechowywanie dodatków na witrynie Mozilla Add-ons jest najłatwiejszą formą dystrybucji dodatków. Co możesz od nas otrzymać:</p><ul><li>Każdy dodatek będzie miał swoją ogólnodostępną stronę z informacjami dostarczonymi przez Ciebie, takimi jak: zwięzły opis funkcji dodatku, opcjonalny dłuższy opis i prezentację podglądu obrazków dodatku.</li><li>Dodatek będzie wyświetlany na stronach przeglądania i wyników szukania witryny, a także w menedżerze dodatków Firefoksa 3.</li><li>Będziemy także opiekowali się obsługą wszystkich pobrań dodatku i dostarczali użytkownikom automatyczne aktualizacje po opublikowaniu przez Ciebie nowej wersji.</li><li>Będziesz mieć dostęp do panelu statystyk zawierającego szczegółowe informacje o bazie swoich użytkowników.</li></ul><p>Zanim wszystkie wymienione powyżej funkcje będą dostępne, dodatki utrzymywane na witrynie muszą przejść proces recenzji wykonywany przez edytorów Mozilla Add-ons. Jeśli jesteś gotowy do rozpoczęcia i masz przygotowany do wysłania pakiet swojego rozszerzenia, wystarczy nacisnąć przycisk: Zaczynamy!</p>"
+
+#: views/developers/uploader.thtml:125
+msgid "devcp_uploader_label_platformtype"
+msgstr "Obsługiwane systemy:"
+
+#: views/developers/uploader.thtml:124
+msgid "devcp_uploader_label_upload_field"
+msgstr "Plik dodatku: "
+
+#: controllers/components/developers.php:1221
+msgid "devcp_uploader_option_other"
+msgstr "Inna"
+
+#. %1$s is a number, %2$s is href="..." and should stay in the <a> tag.
+#: views/developers/uploader.thtml:176
+msgid "devcp_uploader_p_pending_file"
+msgstr "Nowy plik będzie możliwy do upublicznienia tak szybko, jak tylko edytor będzie w stanie dokonać jego recenzji. Aktualnie w kolejce do wykonania recenzji oczekuje %1$s innych dodatków. Chcesz, aby został szybciej zrecenzowany? Zastanów się, czy nie zostać <a %2$s>edytorem</a>."
+
+#. %1$s is a number, %2$s is href="..." and should stay in the <a> tag.
+#: views/developers/uploader.thtml:166
+msgid "devcp_uploader_p_pending_version"
+msgstr "Nowa wersja będzie możliwa do upublicznienia tak szybko, jak tylko edytor będzie w stanie dokonać jej recenzji. Aktualnie w kolejce do wykonania recenzji oczekuje %1$s innych dodatków. Chcesz, aby została zrecenzowana szybciej? Zastanów się, czy nie zostać <a %2$s>edytorem</a>."
+
+#. %s is a status, e.g Public or Incomplete.
+#: views/developers/uploader.thtml:165
+msgid "devcp_uploader_p_update_created"
+msgstr "Nowa wersja została utworzona i jest obecnie oznaczona jako %s."
+
+#. %1$s is href="..." and should stay in the 'Versions and Files' <a> tag.
+#. %2$s is href="..." and should stay in the 'current status' <a> tag.
+#: views/developers/uploader.thtml:177
+msgid "devcp_uploader_p_update_file"
+msgstr "Zobacz swój nowy plik na stronie <a %1$s>Wersje i pliki</a>, sprawdź <a %2$s>obecny status</a> swojego dodatku lub <b>dodaj informacje o wydaniu</b> naciskając poniższy przycisk (zalecane)."
+
+#. %1$s is href="..." and should stay in the 'Versions and Files' <a> tag.
+#. %2$s is href="..." and should stay in the 'current status' <a> tag.
+#: views/developers/uploader.thtml:167
+msgid "devcp_uploader_p_update_version"
+msgstr "Obejrzyj dane nowej wersji na stronie <a %1$s>Wersje i pliki</a>, sprawdź <a %2$s>obecny status</a> swojego dodatku lub <b>dodaj informacje o wydaniu</b> naciskając poniższy przycisk (zalecane)."
+
+#: views/developers/uploader.thtml:118
+msgid "devcp_uploader_p_upload"
+msgstr "Wyślij plik dodatku, używając poniższego formularza. Jeśli masz do wysłania kilka, właściwych dla danego systemu operacyjnego plików wybierz jeden plik i następnie wyślij pozostałe pliki, używając menedżera wersji i plików."
+
+#: views/developers/uploader.thtml:125
+msgid "devcp_uploader_platformtype_all"
+msgstr "Wszystkie"
+
+#: views/developers/uploader.thtml:126
+msgid "devcp_uploader_platformtype_specific"
+msgstr "Określone:"
+
+#. Used as first item in a <select>.
+#: controllers/components/developers.php:1185
+msgid "devcp_uploader_please_choose"
+msgstr "Wybierz…"
+
+#. %1$s is the add-on name, %2$s is the version number.
+#: views/developers/uploader.thtml:57
+msgid "devcp_uploader_title_file"
+msgstr "Dodawanie pliku do %1$s %2$s"
+
+#: views/developers/uploader.thtml:50
+msgid "devcp_uploader_title_submit"
+msgstr "Wysyłanie nowego dodatku"
+
+#. %s is the add-on name.
+#: views/developers/uploader.thtml:54
+msgid "devcp_uploader_title_update"
+msgstr "Aktualizacja %s"
+
+#. %s is a full <a> tag
+#: controllers/developers_controller.php:503
+#, php-format
+msgid "devcp_valid_app_reference"
+msgstr "Więcej informacji można znaleźć na %s."
+
+#. This is the text in the <a> tag for devcp_valid_app_reference. This should be
+#. fixed.
+#: controllers/developers_controller.php:503
+msgid "devcp_valid_app_reference_linktext"
+msgstr "tej stronie"
+
+#: controllers/developers_controller.php:581
+msgid "devcp_verify_author_error"
+msgstr "Nie znaleziono konta skojarzonego z tym adresem e-mail."
+
+#: controllers/developers_controller.php:553
+msgid "devcp_verify_search_engine_error"
+msgstr "Kod XML ma nieprawidłową strukturę lub nie wypełniono wymaganych pól. Proszę zapoznać się z <a href=\"https://developer.mozilla.org/en/Creating_OpenSearch_plugins_for_Firefox\">dokumentacją</a>, zweryfikować dodatek i spróbować ponownie."
+
+#: views/developers/versions.thtml:75
+msgid "devcp_versions_a_cancel"
+msgstr "Anuluj"
+
+#: views/developers/versions.thtml:79
+msgid "devcp_versions_a_delete"
+msgstr "Usuń wersję"
+
+#: views/developers/versions.thtml:74
+msgid "devcp_versions_a_empty"
+msgstr "Usuń pustą wersję"
+
+#: views/developers/versions.thtml:71
+msgid "devcp_versions_a_remove"
+msgstr "Czy na pewno usunąć?"
+
+#: views/developers/versions.thtml:91
+msgid "devcp_versions_add"
+msgstr "Dodaj nowÄ… wersjÄ™"
+
+#: views/developers/versions_delete.thtml:58
+msgid "devcp_versions_delete_a_cancel"
+msgstr "Anuluj"
+
+#: views/developers/versions_delete.thtml:56
+msgid "devcp_versions_delete_a_delete"
+msgstr "Usuń"
+
+#. Followed by a list of reviews and files that will be removed.
+#: views/developers/versions_delete.thtml:50
+msgid "devcp_versions_delete_also"
+msgstr "Usunięcie tej wersji spowoduje również usunięcie:"
+
+#: views/developers/versions_delete.thtml:53
+msgid "devcp_versions_delete_files"
+msgid_plural "devcp_versions_delete_files"
+msgstr[0] "%s plik"
+msgstr[1] "%s pliki"
+msgstr[2] "%s plików"
+
+#. %s is the version number.
+#: views/developers/versions_delete.thtml:48
+msgid "devcp_versions_delete_header"
+msgstr "Usunąć wersję %s?"
+
+#: views/developers/versions_delete.thtml:52
+msgid "devcp_versions_delete_reviews"
+msgid_plural "devcp_versions_delete_reviews"
+msgstr[0] "%s recenzja"
+msgstr[1] "%s recenzje"
+msgstr[2] "%s recenzji"
+
+#. %s is the version number.
+#: views/developers/versions_delete.thtml:49
+msgid "devcp_versions_delete_sure"
+msgstr "Czy na pewno chcesz trwale usunąć wersję %s?"
+
+#: views/developers/versions_edit.thtml:102
+#: views/developers/versions_edit.thtml:155
+msgid "devcp_versions_edit_a_cancel"
+msgstr "Anuluj"
+
+#: views/developers/versions_edit.thtml:101
+msgid "devcp_versions_edit_a_delete"
+msgstr "Usuń plik"
+
+#: views/developers/versions_edit.thtml:165
+msgid "devcp_versions_edit_a_new_app"
+msgstr "Dodaj program"
+
+#: views/developers/versions_edit.thtml:154
+msgid "devcp_versions_edit_a_remove_app"
+msgstr "Usuń"
+
+#: views/developers/versions_edit.thtml:114
+msgid "devcp_versions_edit_add"
+msgstr "Wyślij nowy plik"
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/versions_edit.thtml:121
+msgid "devcp_versions_edit_adjust"
+msgstr "Ustawione tutaj informacje dotyczące programu i wersji, pozwolą użytkownikom zainstalować Twój dodatek, nawet jeśli dane zawarte w pliku install.rdf wskazują, że jest on niekompatybilny. <a %s>Wykaz obsługiwanych programów i wersji</a>."
+
+#: views/developers/versions_edit.thtml:153
+msgid "devcp_versions_edit_compat_sure"
+msgstr "Czy <b>na pewno</b> chcesz usunąć kompatybilność z tym programem?"
+
+#: views/developers/versions_edit.thtml:100
+msgid "devcp_versions_edit_delete_sure"
+msgstr "Czy <b>na pewno</b> chcesz trwale usunąć ten plik?"
+
+#: views/developers/versions_edit.thtml:203
+msgid "devcp_versions_edit_header_approval"
+msgstr "Informacje rejestracyjne"
+
+#: views/developers/versions_edit.thtml:120
+msgid "devcp_versions_edit_header_compat"
+msgstr "Kompatybilne programy"
+
+#: views/developers/versions_edit.thtml:74
+msgid "devcp_versions_edit_header_file"
+msgstr "Informacja o pliku"
+
+#: views/developers/versions_edit.thtml:189
+msgid "devcp_versions_edit_header_license"
+msgstr "Licencja"
+
+#. %s is the version number.
+#: views/developers/versions_edit.thtml:53
+msgid "devcp_versions_edit_header_manage"
+msgstr "ZarzÄ…dzanie wersjÄ… %s"
+
+#: views/developers/versions_edit.thtml:212
+msgid "devcp_versions_edit_header_notes"
+msgstr "Uwagi dla edytora"
+
+#: views/developers/versions_edit.thtml:98
+msgid "devcp_versions_edit_img_delete"
+msgstr "Usuń plik"
+
+#. %1$s is the file id, e.g. 18723.
+#. %2$s is the platform name, e.g. ALL or Windows.
+#. %3$s is the _('date) created.
+#. %4$s is the status, e.g. "In Sandbox" or "Public".
+#. %5$s is the _('date') status was changed.
+#: views/developers/versions_edit.thtml:208
+msgid "devcp_versions_edit_li_file"
+msgstr "Numer pliku: %1$s; System: (%2$s); Utworzono: %3$s; Status określono na %4$s %5$s"
+
+#: views/developers/versions_edit.thtml:190
+msgid "devcp_versions_edit_license_description"
+msgstr "Proszę wybrać odpowiednią licencję dla swojego dodatku. Ta licencja określa prawa do kodu źródłowego, które przekazujesz."
+
+#: views/developers/versions_edit.thtml:111
+msgid "devcp_versions_edit_no_files"
+msgstr "Nie znaleziono plików."
+
+#: views/developers/versions_edit.thtml:213
+msgid "devcp_versions_edit_optional"
+msgstr "Opcjonalna informacja dla edytora recenzujÄ…cego tÄ™ wersjÄ™."
+
+#: views/developers/versions_edit.thtml:151
+msgid "devcp_versions_edit_remove_compat"
+msgstr "Usuń program"
+
+#: views/developers/versions_edit.thtml:167
+msgid "devcp_versions_edit_select_app"
+msgstr "Wybierz program"
+
+#: views/developers/versions_edit.thtml:78
+msgid "devcp_versions_edit_th_file"
+msgstr "Plik"
+
+#: views/developers/versions_edit.thtml:79
+msgid "devcp_versions_edit_th_platform"
+msgstr "System"
+
+#: views/developers/versions_edit.thtml:80
+msgid "devcp_versions_edit_th_size"
+msgstr "Rozmiar"
+
+#: views/developers/versions_edit.thtml:81
+msgid "devcp_versions_edit_th_status"
+msgstr "Status"
+
+#: views/developers/versions_edit.thtml:183
+msgid "devcp_versions_edit_transbox_releasenotes_description"
+msgstr "Informacje o zmianach w tym wydaniu, nowe funkcje, znane błędy i inne użyteczne informacje właściwe dla tego wydania/wersji. Informacje te będą również dostępne dla użytkowników aktualizujących dodatek z poziomu menedżera dodatków Firefoksa 3."
+
+#: views/developers/versions_edit.thtml:182
+msgid "devcp_versions_edit_transbox_releasenotes_name"
+msgstr "Informacje o wydaniu"
+
+#: views/developers/versions_edit.thtml:164
+msgid "devcp_versions_edit_unsaved_compat"
+msgstr "<strong>SÄ… niezapisane zmiany.</strong> Kompatybilność nie zostanie usuniÄ™ta do czasu naciÅ›niÄ™cia na dole strony przycisku „Aktualizujâ€."
+
+#: views/developers/versions_edit.thtml:113
+msgid "devcp_versions_edit_unsaved_files"
+msgstr "<strong>SÄ… niezapisane zmiany.</strong> Pliki nie zostanÄ… usuniÄ™te do czasu naciÅ›niÄ™cia na dole strony przycisku „Aktualizujâ€."
+
+#: views/developers/versions_edit.thtml:218
+msgid "devcp_versions_edit_update"
+msgstr "Aktualizuj"
+
+#: views/developers/versions.thtml:49
+msgid "devcp_versions_header_manage"
+msgstr "ZarzÄ…dzanie wersjami i plikami"
+
+#: views/developers/versions.thtml:87
+msgid "devcp_versions_no_versions"
+msgstr "Nie ma żadnej wersji"
+
+#. %s is a version number, base 10.
+#: views/developers/versions.thtml:46
+msgid "devcp_versions_notice_success"
+msgstr "Wersja %s została usunięta."
+
+#: views/developers/versions.thtml:73
+msgid "devcp_versions_p_remove"
+msgstr "Ta wersja nie ma skojarzonych plików i może zostać usunięta. Czy chcesz usunąć tę wersję?"
+
+#: views/developers/versions.thtml:58
+msgid "devcp_versions_th_created"
+msgstr "Data utworzenia"
+
+#: views/developers/versions.thtml:57
+msgid "devcp_versions_th_status"
+msgstr "Status"
+
+#: views/developers/versions.thtml:56
+msgid "devcp_versions_th_version"
+msgstr "Wersja"
+
+#: controllers/downloads_controller.php:91
+msgid "downloads_disable_warning"
+msgstr "Ten dodatek został wyłączony"
+
+#: controllers/components/editors.php:57
+msgid "editor_review_error_addon_not_nominated"
+msgstr "Ten dodatek nie został jeszcze nominowany."
+
+#: controllers/components/editors.php:213
+msgid "editor_review_error_file_not_pending"
+msgstr "Ten plik nie oczekuje na recenzjÄ™."
+
+#. Actions are, for example: approving or rejecting
+#: controllers/components/editors.php:79
+#: controllers/components/editors.php:182
+msgid "editor_review_error_no_action"
+msgstr "Nie określono czynności. Wybierz ją."
+
+#: controllers/components/editors.php:192
+msgid "editor_review_error_no_applications"
+msgstr "Podaj nazwy testowanych programów."
+
+#. Comments are required when an editor approves or rejects an add-on.
+#: controllers/components/editors.php:84
+#: controllers/components/editors.php:187
+msgid "editor_review_error_no_comments"
+msgstr "Napisz komentarze recenzji."
+
+#: controllers/components/editors.php:161
+msgid "editor_review_error_no_files"
+msgstr "Wybierz co najmniej jeden plik do zrecenzowania."
+
+#: controllers/components/editors.php:197
+msgid "editor_review_error_no_operating_system"
+msgstr "Podaj nazwy testowanych systemów operacyjnych."
+
+#: views/editors/logs.thtml:51
+msgid "editorcp_logs_button_filter"
+msgstr "Filtruj"
+
+#: views/editors/logs.thtml:44
+msgid "editorcp_logs_filter_by"
+msgstr "Filtruj wg typu/czynności"
+
+#: views/editors/logs.thtml:42
+#: controllers/editors_controller.php:964
+msgid "editorcp_logs_page_heading"
+msgstr "Dziennik zdarzeń"
+
+#: views/elements/developers/editorsmenu.thtml:60
+msgid "editorcp_menu_eventlog_link"
+msgstr "Dziennik zdarzeń"
+
+#: views/elements/developers/editorsmenu.thtml:62
+msgid "editorcp_menu_mainpage_link"
+msgstr "Wróć do strony głównej"
+
+#: views/elements/developers/editorsmenu.thtml:61
+msgid "editorcp_menu_reviewlog_link"
+msgstr "PrzeglÄ…daj zdarzenia"
+
+#: views/elements/developers/editorsmenu.thtml:55
+msgid "editorcp_menu_summary_link"
+msgstr "Przegląd edytorów"
+
+#: views/elements/developers/editorsmenu.thtml:52
+msgid "editorcp_menu_title"
+msgstr "Narzędzia edytora"
+
+#: views/editors/reviewlog.thtml:49
+msgid "editorcp_reviewlog_button_filter"
+msgstr "Filtruj"
+
+#: views/editors/reviewlog.thtml:58
+msgid "editorcp_reviewlog_column_action"
+msgstr "Czynność"
+
+#: views/editors/reviewlog.thtml:56
+msgid "editorcp_reviewlog_column_addon"
+msgstr "Dodatek"
+
+#: views/editors/reviewlog.thtml:55
+msgid "editorcp_reviewlog_column_date"
+msgstr "Data"
+
+#: views/editors/reviewlog.thtml:57
+msgid "editorcp_reviewlog_column_editor"
+msgstr "Edytor"
+
+#: views/editors/reviewlog.thtml:94
+msgid "editorcp_reviewlog_comments_hide"
+msgstr "Ukryj komentarze"
+
+#: views/editors/reviewlog.thtml:93
+msgid "editorcp_reviewlog_comments_show"
+msgstr "Wyświetl komentarze"
+
+#. %1$s and %2$s are full <input> tags for dates
+#: views/editors/reviewlog.thtml:45
+#, php-format
+msgid "editorcp_reviewlog_entries_between"
+msgstr "Wyświetl wpisy między %1$s i %2$s"
+
+#: views/editors/reviewlog.thtml:104
+msgid "editorcp_reviewlog_none_found"
+msgstr "Brak recenzji dla tego okresu."
+
+#: views/editors/reviewlog.thtml:42
+msgid "editorcp_reviewlog_page_heading"
+msgstr "Dziennik recenzji"
+
+#: views/editors/summary.thtml:61
+msgid "editorcp_summary_monthreviews_heading"
+msgstr "Oceny miesięczne"
+
+#: views/editors/summary.thtml:77
+msgid "editorcp_summary_neweditors_heading"
+msgstr "Nowi edytorzy"
+
+#: views/editors/summary.thtml:42
+msgid "editorcp_summary_page_heading"
+msgstr "Podsumowanie edytora"
+
+#: views/editors/summary.thtml:94
+msgid "editorcp_summary_recentactivity_heading"
+msgstr "Ostatnie czynności edytorów"
+
+#: views/editors/summary.thtml:45
+msgid "editorcp_summary_totalreviews_heading"
+msgstr "Liczba recenzji"
+
+#: controllers/editors_controller.php:248
+#: controllers/editors_controller.php:249
+msgid "editors_addon_review_pagetitle"
+msgstr "Recenzja dodatku"
+
+#: controllers/editors_controller.php:349
+msgid "editors_error_js-formerror"
+msgstr "Uzupełnij następujące pola:"
+
+#: controllers/editors_controller.php:350
+msgid "editors_error_review_one_file"
+msgstr "Wybierz przynajmniej jeden plik do recenzji."
+
+#: controllers/editors_controller.php:274
+msgid "editors_error_self_reviews_forbidden"
+msgstr "Recenzowanie własnych dodatków jest zabronione."
+
+#: controllers/editors_controller.php:699
+msgid "editors_external_software"
+msgstr "Zewnętrzne oprogramowanie"
+
+#: views/editors/featured.thtml:120
+#: views/editors/featured.thtml:121
+msgid "editors_featured_add_feature"
+msgstr "Dodaj element"
+
+#: views/editors/featured.thtml:126
+msgid "editors_featured_add_feature_submit"
+msgstr "Dodaj"
+
+#: views/editors/featured.thtml:49
+#: controllers/editors_controller.php:832
+#: controllers/editors_controller.php:848
+msgid "editors_featured_addon_add_failure"
+msgstr "Nie udało się dodać elementu."
+
+#: controllers/editors_controller.php:851
+msgid "editors_featured_addon_add_success"
+msgstr "Element został dodany."
+
+#: views/editors/featured.thtml:50
+#: controllers/editors_controller.php:839
+#: controllers/editors_controller.php:868
+#: controllers/editors_controller.php:886
+msgid "editors_featured_addon_edit_failure"
+msgstr "Nie udało się edytować elementu."
+
+#: views/editors/featured.thtml:51
+#: controllers/editors_controller.php:888
+msgid "editors_featured_addon_edit_success"
+msgstr "Edycja elementu zakończona powodzeniem."
+
+#: views/editors/featured.thtml:53
+#: controllers/editors_controller.php:861
+msgid "editors_featured_addon_invalid_locale"
+msgstr "Przynajmniej jedna lokalizacja jest nieprawidłowa"
+
+#: views/editors/featured.thtml:52
+#: controllers/editors_controller.php:906
+msgid "editors_featured_addon_remove_failure"
+msgstr "Nie udało się usunąć elementu."
+
+#: controllers/editors_controller.php:901
+msgid "editors_featured_addon_remove_success"
+msgstr "Element został usunięty."
+
+#: controllers/editors_controller.php:915
+#: controllers/editors_controller.php:917
+msgid "editors_featured_addons_pagetitle"
+msgstr "Polecane dodatki"
+
+#: views/editors/featured.thtml:54
+#: views/editors/featured.thtml:107
+msgid "editors_featured_edit_feature_submit"
+msgstr "Wykonaj"
+
+#: views/editors/featured.thtml:90
+#: views/editors/featured.thtml:91
+msgid "editors_featured_remove_feature"
+msgstr "Usuń element"
+
+#: views/editors/queue.thtml:46
+msgid "editors_filter_queue"
+msgstr "Filtrowanie kolejki"
+
+#: views/editors/queue.thtml:182
+msgid "editors_helpful_links"
+msgstr "Pomocne odnośniki"
+
+#: views/editors/queue.thtml:182
+msgid "editors_link_guide"
+msgstr "Poradnik edytora"
+
+#: views/editors/queue.thtml:182
+msgid "editors_link_policy"
+msgstr "Polityka dodatków"
+
+#: views/editors/queue.thtml:47
+msgid "editors_notice_filter_session"
+msgstr "Te filtry pozostanÄ… aktywne na czas trwania sesji lub do wyczyszczenia."
+
+#. %1 is the queue mode
+#: views/editors/queue.thtml:177
+#: views/admin/flagged_queue.thtml:89
+msgid "editors_notice_none_found"
+msgstr "Aktualnie nie ma dodatków tego typu do recenzji."
+
+#: controllers/editors_controller.php:1040
+msgid "editors_one_day"
+msgstr "1 dzień"
+
+#: controllers/editors_controller.php:1048
+msgid "editors_one_hour"
+msgstr "1 godzina"
+
+#: controllers/editors_controller.php:1056
+msgid "editors_one_minute"
+msgstr "1 minuta"
+
+#: controllers/editors_controller.php:64
+#: controllers/editors_controller.php:73
+#: controllers/editors_controller.php:77
+msgid "editors_pagetitle"
+msgstr "Panel kontrolny edytora"
+
+#. %s is a comma separated list of platforms. Example: Windows, OS X
+#: controllers/editors_controller.php:680
+#: controllers/editors_controller.php:683
+#, php-format
+msgid "editors_platform_x_only"
+msgstr "Tylko %s"
+
+#: controllers/editors_controller.php:695
+msgid "editors_pre-release"
+msgstr "Wydanie wstępne"
+
+#. %1 is the app name
+#: views/editors/queue.thtml:131
+#, php-format
+msgid "editors_queue_app_compatibility"
+msgstr "Kompatybilny z %s"
+
+#: views/editors/queue.thtml:51
+msgid "editors_queue_filter_label_addon"
+msgstr "Dodatek lub adres e-mail autora"
+
+#: views/editors/queue.thtml:72
+msgid "editors_queue_filter_label_addontypes"
+msgstr "Typ dodatku"
+
+#: views/editors/queue.thtml:56
+msgid "editors_queue_filter_label_application"
+msgstr "Program"
+
+#: views/editors/queue.thtml:61
+msgid "editors_queue_filter_label_maxversion"
+msgstr "Maksymalna wersja"
+
+#: views/editors/queue.thtml:78
+msgid "editors_queue_filter_label_platforms"
+msgstr "Systemy"
+
+#: views/editors/queue.thtml:66
+msgid "editors_queue_filter_label_submissionage"
+msgstr "Czas oczekiwania (dni)"
+
+#. %1$s is a number
+#: views/editors/queue.thtml:90
+msgid "editors_queue_filter_result_count"
+msgid_plural "editors_queue_filter_result_count"
+msgstr[0] "Wynik wyszukiwania: <strong>%1$s</strong> dodatek"
+msgstr[1] "Wynik wyszukiwania: <strong>%1$s</strong> dodatki"
+msgstr[2] "Wynik wyszukiwania: <strong>%1$s</strong> dodatków"
+
+#: views/editors/queue.thtml:84
+msgid "editors_queue_submit_clean"
+msgstr "Wyczyść"
+
+#: views/editors/queue.thtml:83
+msgid "editors_queue_submit_filter"
+msgstr "Filtruj"
+
+#: controllers/editors_controller.php:133
+msgid "editors_queues_disabled"
+msgstr "Wszystkie kolejki recenzji są aktualnie wyłączone. Spróbuj ponownie później"
+
+#: views/editors/review.thtml:149
+msgid "editors_review_a_edit_item"
+msgstr "Edytuj dodatek"
+
+#: views/editors/review.thtml:146
+msgid "editors_review_a_item_history"
+msgstr "Historia dodatku"
+
+#: views/editors/review.thtml:148
+msgid "editors_review_a_item_homepage"
+msgstr "Strona dodatku"
+
+#: views/editors/review.thtml:145
+msgid "editors_review_a_item_overview"
+msgstr "PrzeglÄ…d dodatku"
+
+#: views/editors/review.thtml:147
+msgid "editors_review_a_previews"
+msgstr "Obrazki"
+
+#: controllers/editors_controller.php:345
+msgid "editors_review_action"
+msgstr "Czynność recenzji"
+
+#: views/editors/review.thtml:159
+msgid "editors_review_action_info"
+msgstr "PoproÅ› o dodatkowe informacje"
+
+#: views/editors/review.thtml:157
+msgid "editors_review_action_public"
+msgstr "Publikuj"
+
+#: views/editors/review.thtml:160
+msgid "editors_review_action_request_superreview"
+msgstr "PoproÅ› o Super-Review"
+
+#: views/editors/review.thtml:158
+msgid "editors_review_action_sandbox"
+msgstr "Pozostaw w piaskownicy"
+
+#: controllers/editors_controller.php:346
+msgid "editors_review_comments"
+msgstr "Komentarze do recenzji"
+
+#: views/editors/review.thtml:182
+msgid "editors_review_details_info_request"
+msgstr "Użyj tego formularza do wysłania prośby do autora o dodatkowe informacje. Autor za pomocą wiadomości e-mail zostanie powiadomiony i będzie mógł udzielić odpowiedzi. Gdy nadejdzie odpowiedź, otrzymasz powiadomienie."
+
+#: views/editors/review.thtml:174
+msgid "editors_review_details_nominated_public"
+msgstr "To działanie spowoduje, że dodatek i jego ostatnia wersja zostaną oznaczone jako ogólnodostępne. Nowe wersje będą trafiały do piaskownicy i czekały na recenzję edytora."
+
+#: views/editors/review.thtml:177
+msgid "editors_review_details_nominated_sandbox"
+msgstr "To działanie spowoduje, że dodatek pozostanie w piaskownicy."
+
+#: views/editors/review.thtml:166
+msgid "editors_review_details_pending_public"
+msgstr "To działanie spowoduje zatwierdzenie nowej wersji upublicznionego dodatku znajdującej się w piaskownicy i zezwoli na jej wyświetlenie na stronie ogólnodostępnej."
+
+#: views/editors/review.thtml:169
+msgid "editors_review_details_pending_sandbox"
+msgstr "To działanie spowoduje, że wersja upublicznionego dodatku znajdująca się w piaskownicy nadal w niej pozostanie."
+
+#: views/editors/review.thtml:185
+msgid "editors_review_details_superreview"
+msgstr "Jeśli masz jakieś zastrzeżenia do bezpieczeństwa tego dodatku, kwestii licencyjnych lub innych, na które powinien spojrzeć administrator, wpisz swoje uwagi do pola poniżej. Zostaną one przekazane tylko administratorowi."
+
+#: views/editors/review.thtml:134
+msgid "editors_review_file_diff_link"
+msgstr "Porównaj z wersją upublicznioną"
+
+#: views/editors/review.thtml:131
+msgid "editors_review_file_viewcontents_link"
+msgstr "Wyświetl zawartość"
+
+#: views/editors/review.thtml:65
+msgid "editors_review_header_authors"
+msgstr "Autorzy:"
+
+#: views/editors/review.thtml:79
+msgid "editors_review_header_categories"
+msgstr "Kategorie:"
+
+#: views/editors/review.thtml:92
+msgid "editors_review_header_compatibility"
+msgstr "Kompatybilność:"
+
+#: views/editors/review.thtml:251
+msgid "editors_review_header_description"
+msgstr "Opis"
+
+#: views/editors/review.thtml:275
+msgid "editors_review_header_devcomments"
+msgstr "Komentarze autora"
+
+#: views/editors/review.thtml:263
+msgid "editors_review_header_eula"
+msgstr "EULA"
+
+#: views/editors/review.thtml:115
+msgid "editors_review_header_files"
+msgstr "Pliki:"
+
+#: views/editors/review.thtml:284
+msgid "editors_review_header_itemhistory"
+msgstr "Historia dodatku"
+
+#: views/editors/review.thtml:232
+msgid "editors_review_header_nominationmessage"
+msgstr "Informacje o nominacji"
+
+#: views/editors/review.thtml:311
+msgid "editors_review_header_previews"
+msgstr "Obrazki"
+
+#: views/editors/review.thtml:269
+msgid "editors_review_header_privacy"
+msgstr "Polityka prywatności"
+
+#. %1 is the add-on name and version
+#: views/editors/review.thtml:56
+#, php-format
+msgid "editors_review_header_review"
+msgstr "Recenzja %s"
+
+#: views/editors/review.thtml:239
+msgid "editors_review_header_reviewernotes"
+msgstr "Informacje dla edytora"
+
+#: views/editors/review.thtml:245
+msgid "editors_review_header_summary"
+msgstr "Podsumowanie"
+
+#: views/editors/review.thtml:257
+msgid "editors_review_header_versionnotes"
+msgstr "Informacje o wersji"
+
+#. a noun: shown in an add-on's editor review history
+#: views/elements/developers/editors_review_history_item.thtml:80
+msgid "editors_review_history_info_reply"
+msgstr "Odpowiedź"
+
+#: views/elements/developers/editors_review_history_item.thtml:78
+msgid "editors_review_history_info_request"
+msgstr "Prośba o dodatkowe informacje"
+
+#: views/elements/developers/editors_review_history_item.thtml:62
+#: views/editors/reviewlog.thtml:77
+msgid "editors_review_history_nominated_adminreview"
+msgstr "ZarzÄ…dzanie recenzjÄ…"
+
+#: views/elements/developers/editors_review_history_item.thtml:56
+#: views/editors/reviewlog.thtml:71
+msgid "editors_review_history_nominated_approved"
+msgstr "Nominacja zatwierdzona/Upubliczniony"
+
+#: views/elements/developers/editors_review_history_item.thtml:59
+#: views/editors/reviewlog.thtml:74
+msgid "editors_review_history_nominated_denied"
+msgstr "Odmowa nominacji/Piaskownica"
+
+#: views/editors/review.thtml:303
+msgid "editors_review_history_nonefound"
+msgstr "Brak wcześniejszych recenzji."
+
+#: views/elements/developers/editors_review_history_item.thtml:73
+#: views/editors/reviewlog.thtml:88
+msgid "editors_review_history_pending_adminreview"
+msgstr "ZarzÄ…dzanie recenzjÄ…"
+
+#: views/elements/developers/editors_review_history_item.thtml:67
+#: views/editors/reviewlog.thtml:82
+msgid "editors_review_history_pending_approved"
+msgstr "Zatwierdzony/Upubliczniony"
+
+#: views/elements/developers/editors_review_history_item.thtml:70
+#: views/editors/reviewlog.thtml:85
+msgid "editors_review_history_pending_denied"
+msgstr "Odmowa/Piaskownica"
+
+#. link text in an add-on's editor review history, allowing to hide and show an information request's replies
+#. %1 is the number of replies
+#: views/elements/developers/editors_review_history_item.thtml:90
+msgid "editors_review_history_show_hide_replies"
+msgid_plural "editors_review_history_show_hide_replies"
+msgstr[0] "Wyświetl/ukryj odpowiedź (%1$s)"
+msgstr[1] "Wyświetl/ukryj odpowiedzi (%1$s)"
+msgstr[2] "Wyświetl/ukryj odpowiedzi (%1$s)"
+
+#: views/editors/review.thtml:208
+msgid "editors_review_label_applications"
+msgstr "Programy:"
+
+#: views/editors/review.thtml:196
+msgid "editors_review_label_cannedresponse"
+msgstr "lub wybierz gotową odpowiedź:"
+
+#: views/editors/review.thtml:190
+msgid "editors_review_label_comments"
+msgstr "Komentarze:"
+
+#: views/editors/review.thtml:204
+msgid "editors_review_label_operating_systems"
+msgstr "Systemy operacyjne:"
+
+#: views/editors/review.thtml:285
+#: views/editors/review.thtml:312
+msgid "editors_review_link_pagetop"
+msgstr "Do góry"
+
+#: views/editors/review.thtml:141
+msgid "editors_review_mulitple_notice"
+msgstr "Informacja: Recenzuj więcej plików, tylko jeśli masz testować wszystkie zaznaczone pliki."
+
+#: views/editors/review.thtml:51
+msgid "editors_review_next_link"
+msgstr "następny &raquo;"
+
+#: views/editors/review.thtml:322
+msgid "editors_review_previews_notfound"
+msgstr "Nie znaleziono obrazków."
+
+#: views/editors/review.thtml:50
+msgid "editors_review_previous_link"
+msgstr "&laquo; poprzedni"
+
+#: controllers/editors_controller.php:144
+#: controllers/editors_controller.php:146
+msgid "editors_review_queue_pagetitle"
+msgstr "Kolejka recenzji"
+
+#. %1 is the add-ons rank in the queue, %2 is the total queue length
+#: views/editors/review.thtml:47
+msgid "editors_review_rank_in_queue"
+msgstr "<strong># %1$s</strong> z %2$s w kolejce "
+
+#. %1 is the add-ons rank in the queue, %2 is the total queue length. Both numbers
+#: views/editors/review.thtml:45
+msgid "editors_review_rank_in_queue_filtered"
+msgstr "Dodatki w kolejce: <strong># %1$s</strong> z %2$s"
+
+#: views/editors/review.thtml:223
+msgid "editors_review_submit_process_action"
+msgstr "Wykonaj"
+
+#: views/editors/review.thtml:293
+msgid "editors_review_th_action"
+msgstr "Czynność"
+
+#: views/editors/review.thtml:294
+msgid "editors_review_th_comments"
+msgstr "Komentarze"
+
+#: views/editors/review.thtml:291
+msgid "editors_review_th_date"
+msgstr "Data"
+
+#: views/editors/review.thtml:292
+msgid "editors_review_th_reviewer"
+msgstr "Edytor"
+
+#: views/editors/review.thtml:290
+msgid "editors_review_th_version_file"
+msgstr "Wersja/plik"
+
+#: views/editors/review.thtml:217
+msgid "editors_review_update_notify_once"
+msgstr "Powiadom mnie, gdy ten dodatek zostanie zaktualizowany. (Kolejne aktualizacje nie będą generowały wiadomości e-mail)"
+
+#: controllers/editors_controller.php:298
+msgid "editors_reviewed_successfully"
+msgstr "Proces recenzji został pomyślnie zakończony."
+
+#: views/editors/reviews_queue.thtml:106
+msgid "editors_reviews_action_delete_review"
+msgstr "Usuń recenzję"
+
+#: views/editors/reviews_queue.thtml:104
+msgid "editors_reviews_action_keep"
+msgstr "Usuń etykiety, zachowaj recenzję"
+
+#: views/editors/reviews_queue.thtml:102
+msgid "editors_reviews_action_skip"
+msgstr "Pomiń"
+
+#: views/editors/reviews_queue.thtml:100
+msgid "editors_reviews_header_action"
+msgstr "Czynność"
+
+#: views/editors/reviews_queue.thtml:67
+msgid "editors_reviews_in_reply_to"
+msgstr "W odpowiedzi na:"
+
+#: controllers/editors_controller.php:748
+msgid "editors_reviews_processed"
+msgstr "Recenzje zostały wysłane!"
+
+#: views/editors/reviews_queue.thtml:117
+msgid "editors_reviews_queue_empty"
+msgstr "Brak recenzji do moderacji."
+
+#: views/editors/reviews_queue.thtml:111
+msgid "editors_reviews_submit_process_reviews"
+msgstr "Wyślij recenzje"
+
+#: controllers/editors_controller.php:691
+msgid "editors_site_specific"
+msgstr "Przeznaczony dla danej strony"
+
+#: controllers/editors_controller.php:348
+msgid "editors_tested_app"
+msgstr "Testowany program"
+
+#: controllers/editors_controller.php:347
+msgid "editors_tested_os"
+msgstr "Testowane systemy operacyjne"
+
+#: views/editors/queue.thtml:151
+msgid "editors_th_additional_info"
+msgstr "Informacje dodatkowe"
+
+#: views/editors/featured.thtml:63
+#: views/editors/queue.thtml:109
+#: views/admin/flagged_queue.thtml:53
+msgid "editors_th_addon"
+msgstr "Dodatek"
+
+#: views/editors/queue.thtml:125
+msgid "editors_th_addontype"
+msgstr "Typ"
+
+#: views/editors/featured.thtml:64
+msgid "editors_th_locales"
+msgstr "Ogranicz do lokalizacji"
+
+#: views/editors/queue.thtml:148
+msgid "editors_th_nomination_age"
+msgstr "Czas oczekiwania"
+
+#: views/editors/queue.thtml:101
+#: views/editors/queue.thtml:117
+#: views/editors/queue.thtml:144
+msgid "editors_th_sort_ascending"
+msgstr "Sortuj rosnÄ…co"
+
+#: views/editors/queue.thtml:105
+#: views/editors/queue.thtml:121
+#: views/editors/queue.thtml:140
+msgid "editors_th_sort_descending"
+msgstr "Sortuj malejÄ…co"
+
+#. %s is a number
+#: controllers/editors_controller.php:1036
+#, php-format
+msgid "editors_x_days"
+msgstr "%s dni"
+
+#. %s is a number
+#: controllers/editors_controller.php:1044
+#, php-format
+msgid "editors_x_hours"
+msgstr "%s godzin"
+
+#. %s is a number
+#: controllers/editors_controller.php:1052
+#, php-format
+msgid "editors_x_minutes"
+msgstr "%s min"
+
+#: views/errors/error401.thtml:50
+#: controllers/components/simple_acl.php:81
+#: controllers/components/simple_acl.php:82
+#: controllers/components/simple_acl.php:83
+#: controllers/components/amo.php:607
+#: controllers/components/amo.php:608
+#: controllers/components/amo.php:609
+#: controllers/reviews_controller.php:353
+#: controllers/reviews_controller.php:485
+#: controllers/collections_controller.php:438
+#: controllers/collections_controller.php:496
+#: controllers/collections_controller.php:504
+#: controllers/collections_controller.php:971
+#: controllers/collections_controller.php:1034
+#: controllers/collections_controller.php:1077
+msgid "error_access_denied"
+msgstr "Brak dostępu"
+
+#: views/errors/error401.thtml:52
+msgid "error_access_denied_message"
+msgstr "Nie masz uprawnień do przeglądania tej strony."
+
+#: controllers/collections_controller.php:1039
+msgid "error_addon_exists"
+msgstr "Ten dodatek już istnieje!"
+
+#: controllers/developers_controller.php:200
+#: controllers/developers_controller.php:593
+#: controllers/developers_controller.php:1016
+#: controllers/developers_controller.php:1429
+#: controllers/downloads_controller.php:95
+#: controllers/downloads_controller.php:102
+#: controllers/downloads_controller.php:164
+#: controllers/statistics_controller.php:135
+#: controllers/previews_controller.php:115
+#: controllers/previews_controller.php:206
+#: controllers/previews_controller.php:307
+#: controllers/reviews_controller.php:77
+#: controllers/reviews_controller.php:240
+#: controllers/reviews_controller.php:332
+#: controllers/reviews_controller.php:340
+#: controllers/api_controller.php:123
+#: controllers/api_controller.php:759
+#: controllers/addons_controller.php:131
+#: controllers/addons_controller.php:197
+#: controllers/addons_controller.php:1407
+#: controllers/addons_controller.php:1465
+#: controllers/addons_controller.php:1469
+#: controllers/addons_controller.php:1503
+#: controllers/editors_controller.php:265
+#: controllers/collections_controller.php:1041
+#: controllers/collections_controller.php:1074
+msgid "error_addon_notfound"
+msgstr "Nie znaleziono dodatku!"
+
+#: controllers/files_controller.php:83
+#: controllers/files_controller.php:196
+msgid "error_addon_notviewable"
+msgstr "Ten dodatek nie może zostać pokazany tutaj."
+
+#: controllers/reviews_controller.php:246
+msgid "error_addon_selfreview"
+msgstr "Nie możesz recenzować własnego dodatku."
+
+#: controllers/addons_controller.php:970
+msgid "error_browse_no_addons"
+msgstr "W tej kategorii nie ma żadnych dodatków!"
+
+#: controllers/api_controller.php:424
+msgid "error_collection_feed_notfound"
+msgstr "Nie znaleziono kanału RSS dodatku"
+
+#: views/users/register.thtml:65
+#: views/users/edit.thtml:194
+msgid "error_email_invalid"
+msgstr "Podany e-mail jest niepoprawny."
+
+#: views/users/pwreset.thtml:74
+#: views/users/register.thtml:70
+#: views/users/register.thtml:80
+#: views/users/register.thtml:86
+#: views/users/edit.thtml:105
+#: views/users/edit.thtml:111
+#: views/users/edit.thtml:192
+#: views/admin/users_edit.thtml:78
+#: views/admin/users_edit.thtml:83
+#: views/reviews/add.thtml:80
+#: views/reviews/add.thtml:104
+msgid "error_field_required"
+msgstr "To pole nie może być puste."
+
+#: controllers/files_controller.php:75
+#: controllers/files_controller.php:93
+#: controllers/files_controller.php:96
+#: controllers/files_controller.php:163
+#: controllers/files_controller.php:176
+#: controllers/files_controller.php:185
+#: controllers/files_controller.php:204
+#: controllers/editors_controller.php:412
+msgid "error_file_notfound"
+msgstr "Nie znaleziono pliku!"
+
+#. %s is a filename
+#: controllers/editors_controller.php:430
+#, php-format
+msgid "error_file_x_notfound"
+msgstr "BÅ‚Ä…d pliku: %s nie istnieje."
+
+#: views/collections/add.thtml:55
+#: views/collections/edit.thtml:89
+#: views/users/register.thtml:54
+#: views/users/edit.thtml:81
+#: views/reviews/add.thtml:70
+#: controllers/groups_controller.php:80
+#: controllers/groups_controller.php:102
+msgid "error_formerrors"
+msgstr "Znaleziono błędy w formularzu. Popraw je i wyślij ponownie."
+
+#: views/users/register.thtml:109
+msgid "error_invalid_captcha"
+msgstr "Nieprawidłowy kod captcha, proszę spróbować ponownie!"
+
+#: views/users/register.thtml:100
+#: views/users/edit.thtml:125
+#: views/admin/users_edit.thtml:101
+msgid "error_invalid_url"
+msgstr "Ten adres URL ma nieprawidłowy format. Poprawny adres URL wygląda jak: http://example.com/moja_strona."
+
+#. %s is a string representing what's missing. Example: file_id
+#: controllers/downloads_controller.php:65
+#: controllers/users_controller.php:185
+#: controllers/users_controller.php:264
+#: controllers/users_controller.php:559
+#: controllers/users_controller.php:653
+#: controllers/reviews_controller.php:71
+#: controllers/reviews_controller.php:234
+#: controllers/reviews_controller.php:325
+#: controllers/reviews_controller.php:473
+#: controllers/reviews_controller.php:475
+#: controllers/addons_controller.php:182
+#: controllers/addons_controller.php:1381
+#: controllers/addons_controller.php:1455
+#: controllers/collections_controller.php:266
+#: controllers/collections_controller.php:285
+#: controllers/collections_controller.php:346
+#: controllers/collections_controller.php:443
+#: controllers/collections_controller.php:482
+#: controllers/collections_controller.php:936
+#: controllers/collections_controller.php:959
+#: controllers/collections_controller.php:960
+#: controllers/collections_controller.php:975
+#: controllers/collections_controller.php:977
+#: controllers/collections_controller.php:994
+#: controllers/collections_controller.php:1003
+#: controllers/collections_controller.php:1016
+#: controllers/collections_controller.php:1017
+#: controllers/collections_controller.php:1024
+#: controllers/collections_controller.php:1070
+#: controllers/collections_controller.php:1090
+#, php-format
+msgid "error_missing_argument"
+msgstr "BrakujÄ…cy argument: %s"
+
+#: controllers/components/amo.php:507
+#: controllers/components/amo.php:532
+msgid "error_no_files_in_addon"
+msgstr "Brak plików"
+
+#: controllers/previews_controller.php:200
+msgid "error_preview_notfound"
+msgstr "Nie znaleziono podglÄ…du!"
+
+#: views/addons/display.thtml:400
+#: views/reviews/add.thtml:98
+msgid "error_review_rating_required"
+msgstr "Musisz wybrać ocenę."
+
+#: controllers/users_controller.php:160
+msgid "error_user_already_confirmed"
+msgstr "To konto użytkownika zostało już potwierdzone."
+
+#: controllers/users_controller.php:202
+#: controllers/users_controller.php:276
+#: controllers/users_controller.php:569
+#: controllers/users_controller.php:581
+#: controllers/users_controller.php:587
+#: controllers/users_controller.php:610
+#: controllers/users_controller.php:627
+msgid "error_user_badconfirmationcode"
+msgstr "Kod potwierdzający jest nieprawidłowy!"
+
+#: views/users/pwreset.thtml:79
+#: views/users/register.thtml:75
+#: views/users/edit.thtml:183
+msgid "error_user_confirmpw_nomatch"
+msgstr "Podane hasła nie pasują do siebie."
+
+#: views/users/register.thtml:65
+#: views/users/edit.thtml:190
+#: controllers/users_controller.php:617
+msgid "error_user_email_notunique"
+msgstr "Ten adres e-mail jest już używany przez innego użytkownika."
+
+#: controllers/users_controller.php:596
+msgid "error_user_emailchange_expired"
+msgstr "Prośba o zmianę e-maila straciła ważność. Proszę ponownie zmienić adres e-mail w profilu użytkownika i kliknąć odnośnik w e-mailu potwierdzającym zaraz po otrzymaniu listu."
+
+#: controllers/collections_controller.php:985
+msgid "error_user_exists"
+msgstr "Użytkownicy mogą mieć tylko jedną funkcję. Zanim przejdziesz dalej, usuń użytkownika z wszystkich funkcji."
+
+#: views/users/register.thtml:91
+#: views/users/edit.thtml:116
+#: views/admin/users_edit.thtml:88
+msgid "error_user_nickname_notunique"
+msgstr "Ten nick jest już używany."
+
+#: views/users/pwreset.thtml:54
+#: controllers/users_controller.php:191
+#: controllers/users_controller.php:270
+#: controllers/users_controller.php:603
+#: controllers/users_controller.php:659
+#: controllers/collections_controller.php:988
+#: controllers/collections_controller.php:998
+msgid "error_user_notfound"
+msgstr "Nie znaleziono użytkownika!"
+
+#: views/users/activatefirst.thtml:47
+msgid "error_user_unconfirmed"
+msgstr "Należy potwierdzić założenie swojego konta, używając kodu otrzymanego e-mailem."
+
+#: views/users/login.thtml:67
+msgid "error_username_or_pw_wrong"
+msgstr "Nieprawidłowa nazwa użytkownika lub hasło!"
+
+#: controllers/editors_controller.php:260
+msgid "error_version_notfound"
+msgstr "Nie znaleziono wersji!"
+
+#: views/users/delete.thtml:125
+#: views/users/edit.thtml:173
+msgid "error_wrong_password"
+msgstr "Wprowadzono złe hasło!"
+
+#: views/elements/amo2009/homepage_addon.thtml:122
+#: views/elements/feature.thtml:122
+msgid "feature_learnmore"
+msgstr "Dowiedz się więcej"
+
+#. %1 is the add-on name
+#: views/elements/amo2009/homepage_addon.thtml:123
+#: views/elements/feature.thtml:123
+#, php-format
+msgid "feature_learnmore_about_addon"
+msgstr "Więcej o dodatku %1$s"
+
+#. %1$s is a number
+#: views/elements/amo2009/reviews.thtml:52
+#: views/elements/addon_listitem.thtml:112
+#: views/elements/feature.thtml:99
+#: views/addons/browse_thumbs.thtml:86
+#, php-format
+msgid "feature_reviews"
+msgid_plural "feature_reviews"
+msgstr[0] "%1$s recenzja"
+msgstr[1] "%1$s recenzje"
+msgstr[2] "%1$s recenzji"
+
+#: views/elements/amo2009/homepage_addon.thtml:127
+#: views/elements/feature.thtml:127
+msgid "feature_view_more_from_category"
+msgstr "Więcej z kategorii "
+
+#. This appears on a page that views the source of an add-on. This link will return
+#. the user to the add-on's main page
+#: views/files/browse.thtml:65
+msgid "file_browser_link_addon"
+msgstr "Wróć do dodatku"
+
+#. There is a list of directories and files on the page. Clicking this will show the
+#. contents of all the directories (normally you would click on each one to see the
+#. contents)
+#: views/files/browse.thtml:67
+msgid "file_browser_link_expand_all"
+msgstr "Pokaż wszystkie"
+
+#. This appears on a page that views the source of an add-on. This link will return
+#. the user to the add-on's review page (it only appears if the add-on is being
+#. reviewed)
+#: views/files/browse.thtml:64
+msgid "file_browser_link_review"
+msgstr "Wróć do recenzji"
+
+#. The title of the page for viewing an add-on's source.
+#. %1$s is the name of the add-on
+#. %2$s is the name of the current application (e.g. Firefox or Thunderbird)
+#: views/files/browse.thtml:46
+msgid "file_browser_title"
+msgstr "%1$s :: Przeglądanie pliku :: %2$s – dodatki"
+
+#. This appears on a page that views the source of an add-on. There is a list of
+#. directories and files on the page. Clicking this link will toggle between an
+#. expanded or a collapsed list. This string should be kept short.
+#: views/files/browse.thtml:68
+msgid "file_browser_toggle_expand_collapse"
+msgstr "+/-"
+
+#. Link text for the AMO About page.
+#: views/elements/footer.thtml:72
+#: views/layouts/amo2009.thtml:341
+msgid "footer_a_about"
+msgstr "Informacje o AMO"
+
+#. Link text to the AMO blog.
+#: views/elements/footer.thtml:74
+#: views/layouts/amo2009.thtml:343
+msgid "footer_a_blog"
+msgstr "Blog"
+
+#. Link text to the Frequently Asked Questions page.
+#: views/elements/footer.thtml:73
+#: views/layouts/amo2009.thtml:342
+msgid "footer_a_faq"
+msgstr "FAQ"
+
+#. Full text for the FAQ abbreviation.
+#: views/elements/footer.thtml:73
+#: views/pages/collector_features.thtml:72
+#: views/layouts/amo2009.thtml:342
+msgid "footer_abbr_faq"
+msgstr "Często zadawane pytania"
+
+#: views/elements/footer.thtml:67
+#: views/layouts/amo2009.thtml:336
+msgid "footer_all_rights_reserved"
+msgstr "Wszelkie prawa zastrzeżone."
+
+#: views/elements/footer.thtml:67
+#: views/layouts/amo2009.thtml:336
+msgid "footer_copyright"
+msgstr "Copyright"
+
+#: views/elements/footer.thtml:71
+#: views/layouts/amo2009.thtml:340
+msgid "footer_credits"
+msgstr "Twórcy"
+
+#: views/elements/footer.thtml:76
+#: views/layouts/amo2009.thtml:346
+msgid "footer_disclaimer"
+msgstr "Mozilla umieszcza odnośniki do tych programów grzecznościowo. Prosimy nie kierować do nas uwag i zażaleń dotyczących ich działania. Wszelkie pytania, reklamacje i roszczenia dotyczące tych aplikacji należy kierować do ich twórców."
+
+#: views/elements/footer.thtml:61
+#: views/layouts/amo2009.thtml:332
+msgid "footer_lang_form_lang_submit_go"
+msgstr "Idź"
+
+#: views/elements/footer.thtml:70
+#: views/layouts/amo2009.thtml:339
+msgid "footer_legal_notices"
+msgstr "Informacje prawne"
+
+#: views/elements/footer.thtml:50
+#: views/layouts/amo2009.thtml:321
+msgid "footer_other_languages"
+msgstr "Inne języki:"
+
+#: views/elements/footer.thtml:69
+#: views/layouts/amo2009.thtml:338
+msgid "footer_privacy_policy"
+msgstr "Polityka prywatności"
+
+#: models/addontype.php:79
+msgid "general_addontype_dict"
+msgstr "SÅ‚ownik"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:100
+msgid "general_addontype_dict_plural"
+msgstr "SÅ‚owniki"
+
+#: models/addontype.php:75
+msgid "general_addontype_extension"
+msgstr "Rozszerzenie"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:98
+msgid "general_addontype_extension_plural"
+msgstr "Rozszerzenia"
+
+#: models/addontype.php:85
+msgid "general_addontype_lpaddon"
+msgstr "Pakiet językowy (dodatek)"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:103
+msgid "general_addontype_lpaddon_plural"
+msgstr "Pakiety językowe (dodatek)"
+
+#: models/addontype.php:83
+msgid "general_addontype_lpapp"
+msgstr "Pakiet językowy (program)"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:102
+msgid "general_addontype_lpapp_plural"
+msgstr "Pakiety językowe (program)"
+
+#: models/addontype.php:87
+msgid "general_addontype_plugin"
+msgstr "Wtyczka"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:104
+msgid "general_addontype_plugin_plural"
+msgstr "Wtyczki"
+
+#: models/addontype.php:81
+msgid "general_addontype_search"
+msgstr "Wyszukiwarka"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:101
+msgid "general_addontype_search_plural"
+msgstr "Wyszukiwarki"
+
+#: models/addontype.php:77
+msgid "general_addontype_theme"
+msgstr "Motyw"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:99
+msgid "general_addontype_theme_plural"
+msgstr "Motywy"
+
+#: config/language.php:367
+msgid "general_languages_all_locales"
+msgstr "Wszystkie lokalizacje"
+
+#: views/layouts/amo2009.thtml:249
+msgid "header_brand_name"
+msgstr "Mozilla"
+
+#. %1$s is the application name. Example: Firefox
+#: views/elements/header.thtml:111
+#: views/elements/header.thtml:122
+#: views/layouts/amo2009.thtml:248
+#, php-format
+msgid "header_home_tooltip"
+msgstr "Wróć do głównej strony %1$s – dodatki"
+
+#: views/elements/header.thtml:87
+msgid "header_main_firefox_header"
+msgstr "Dodatki dla Firefoksa"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:218
+msgid "header_main_firefox_header_with_logo"
+msgstr "Dodatki <em>dla</em> <img alt=\"Firefox\" src=\"%1$s\" /> <strong>Firefoksa</strong>"
+
+#: views/elements/header.thtml:99
+msgid "header_main_header"
+msgstr "Dodatki"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:242
+msgid "header_main_header_with_logo"
+msgstr "Dodatki <img alt=\"Add-ons\" src=\"%1$s\" />"
+
+#: views/elements/header.thtml:90
+msgid "header_main_seamonkey_header"
+msgstr "Seamonkey – dodatki"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:224
+msgid "header_main_seamonkey_header_with_logo"
+msgstr "Dodatki <em>dla</em> <img alt=\"Seamonkey\" src=\"%1$s\" /> <strong>Seamonkey</strong>"
+
+#: views/elements/header.thtml:93
+msgid "header_main_sunbird_header"
+msgstr "Sunbird – dodatki"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:230
+msgid "header_main_sunbird_header_with_logo"
+msgstr "Dodatki <em>dla</em> <img alt=\"Sunbird\" src=\"%1$s\" /> <strong>Sunbirda</strong>"
+
+#: views/elements/header.thtml:96
+msgid "header_main_thunderbird_header"
+msgstr "Thunderbird – dodatki"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:236
+msgid "header_main_thunderbird_header_with_logo"
+msgstr "Dodatki <em>dla</em> <img alt=\"Thunderbird\" src=\"%1$s\" /> <strong>Thunderbirda</strong>"
+
+#: views/layouts/amo2009.thtml:205
+msgid "header_navaccess_applications_menu"
+msgstr "Przejdź do menu innych programów"
+
+#: views/layouts/amo2009.thtml:204
+msgid "header_navaccess_categories_menu"
+msgstr "Przejdź do menu kategorii"
+
+#: views/layouts/amo2009.thtml:202
+msgid "header_navaccess_main_content"
+msgstr "Przejdź do głównej zawartości"
+
+#: views/layouts/amo2009.thtml:203
+msgid "header_navaccess_search_form"
+msgstr "Przejdź do formularza wyszukiwania"
+
+#: views/elements/header.thtml:62
+msgid "header_navlink_addons"
+msgstr "Dodatki"
+
+#: views/elements/developers/sidebar.thtml:72
+#: views/elements/developers/myaddons.thtml:50
+#: views/elements/header.thtml:159
+#: views/addons/display.thtml:378
+msgid "header_navlink_login"
+msgstr "Zaloguj siÄ™"
+
+#: views/elements/header.thtml:156
+#: views/layouts/amo2009.thtml:304
+msgid "header_navlink_logout"
+msgstr "Wyloguj siÄ™"
+
+#: views/elements/header.thtml:145
+#: views/layouts/amo2009.thtml:303
+msgid "header_navlink_myaccount"
+msgstr "Moje konto"
+
+#: views/elements/header.thtml:158
+msgid "header_navlink_register"
+msgstr "Zarejestruj siÄ™"
+
+#. %1 is the URL to the registration page
+#. %2 is the URL to the login page
+#: views/layouts/amo2009.thtml:278
+msgid "header_navlink_register_or_login"
+msgstr "<a href=\"%1$s\">Zarejestruj siÄ™</a> lub <a href=\"%2$s\">Zaloguj siÄ™</a>"
+
+#: views/layouts/amo2009.thtml:285
+msgid "header_navlink_tools"
+msgstr "Narzędzia"
+
+#. %s is the add-on name
+#: views/elements/collections_interactive_addon.thtml:62
+#: views/elements/amo2009/homepage_addon.thtml:77
+#: views/elements/addon_discussionheader.thtml:62
+#: views/elements/addon_listitem.thtml:67
+#: views/elements/feature.thtml:84
+#: views/addons/category_landing.thtml:87
+#: views/addons/browse_thumbs.thtml:60
+#, php-format
+msgid "img_preview_of"
+msgstr "Obrazek podglÄ…du dodatku %s"
+
+#. %1 is the login URL for the link tag
+#. %2 is the link to an explanatory page.
+#: views/elements/amo2009/install.thtml:307
+#: views/elements/install.thtml:255
+msgid "install_a_login_to_install"
+msgstr "<a href=\"%1$s\">Zaloguj się</a>, aby zainstalować ten dodatek. <a href=\"%2$s\">Dlaczego</a>?"
+
+#. %1 is the URL for the Experimental Add-ons section of the FAQ page
+#: views/elements/amo2009/install.thtml:283
+#: views/elements/install.thtml:232
+msgid "install_button_confirm_exp_install"
+msgstr "Instaluj ten eksperymentalny dodatek. <a href=\"%1$s\">Co to jest?</a>"
+
+#. %1$s is the application name. Example: Firefox
+#. %2$s is an optional string used to specify a platform. Example: (Windows)
+#: views/elements/amo2009/install.thtml:128
+#: views/elements/install.thtml:75
+#, php-format
+msgid "install_button_text"
+msgstr "Dodaj do programu %1$s %2$s"
+
+#. %1 is the add-on name, %2 is the app name
+#: views/elements/amo2009/install.thtml:191
+#: views/elements/amo2009/install.thtml:206
+#: views/elements/amo2009/install.thtml:249
+#: views/elements/amo2009/install.thtml:298
+#: views/elements/install.thtml:150
+#: views/elements/install.thtml:165
+#: views/elements/install.thtml:202
+#: views/elements/install.thtml:246
+#, php-format
+msgid "install_button_title"
+msgstr "Dodaj dodatek %1$s do programu %2$s"
+
+#. %1$s is the add-on name
+#: views/elements/amo2009/install.thtml:200
+#: views/elements/install.thtml:159
+#, php-format
+msgid "install_download"
+msgstr "Pobierz dodatek %1$s"
+
+#: views/elements/amo2009/install.thtml:147
+#: views/elements/install.thtml:94
+msgid "install_error_addon_not_found"
+msgstr "Ten dodatek nie jest dostępny."
+
+#: views/addons/dictionaries.thtml:65
+msgid "langtools_a11y_tablesummary"
+msgstr "Lista pakietów językowych i słowników."
+
+#: views/addons/dictionaries.thtml:47
+msgid "langtools_download_dictionary"
+msgstr "Pobierz słownik"
+
+#: views/addons/dictionaries.thtml:48
+msgid "langtools_download_langpack"
+msgstr "Pobierz pakiet językowy"
+
+#: views/addons/dictionaries.thtml:63
+#: controllers/components/amo.php:685
+#: controllers/addons_controller.php:1239
+msgid "langtools_header_dicts_and_langpacks"
+msgstr "Słowniki i pakiety językowe"
+
+#: views/addons/dictionaries.thtml:44
+msgid "langtools_install_dictionary"
+msgstr "Zainstaluj słownik"
+
+#: views/addons/dictionaries.thtml:45
+msgid "langtools_install_langpack"
+msgstr "Zainstaluj pakiet językowy"
+
+#: views/addons/dictionaries.thtml:69
+msgid "langtools_tableheader_dictionary"
+msgstr "SÅ‚ownik"
+
+#: views/addons/dictionaries.thtml:70
+msgid "langtools_tableheader_langpack"
+msgstr "Pakiet językowy"
+
+#: views/addons/dictionaries.thtml:68
+msgid "langtools_tableheader_language"
+msgstr "Język"
+
+#: models/license.php:65
+msgid "license_custom"
+msgstr "WÅ‚asna licencja"
+
+#: config/bootstrap.php:303
+msgid "licenses_bsd"
+msgstr "Licencja BSD"
+
+#: config/bootstrap.php:298
+msgid "licenses_gpl_2.0"
+msgstr "Licencja GNU General Public Licence, wersja 2.0"
+
+#: config/bootstrap.php:299
+msgid "licenses_gpl_3.0"
+msgstr "Licencja GNU General Public Licence, wersja 3.0"
+
+#: config/bootstrap.php:300
+msgid "licenses_lgpl_2.1"
+msgstr "Licencja GNU Lesser General Public License, wersja 2.1"
+
+#: config/bootstrap.php:301
+msgid "licenses_lgpl_3.0"
+msgstr "Licencja GNU Lesser General Public License, wersja 3.0"
+
+#: config/bootstrap.php:302
+msgid "licenses_mit"
+msgstr "Licencja MIT/X11"
+
+#: config/bootstrap.php:297
+msgid "licenses_mpl_1.1"
+msgstr "Licencja Mozilla Public License, wersja 1.1"
+
+#: views/users/emailchange.thtml:51
+#: views/users/delete.thtml:55
+#: views/users/delete.thtml:137
+#: views/users/edit.thtml:74
+#: views/reviews/flag.thtml:54
+msgid "link_return_to_front_page"
+msgstr "Kliknij tutaj, by wrócić na stronę główną."
+
+#: views/elements/amo2009/addon_list_options.thtml:46
+#: views/elements/addon_list_options.thtml:46
+msgid "list_sortby_date"
+msgstr "Daty"
+
+#: views/elements/amo2009/addon_list_options.thtml:47
+#: views/elements/addon_list_options.thtml:47
+msgid "list_sortby_downloads"
+msgstr "Pobrań"
+
+#: views/elements/amo2009/addon_list_options.thtml:45
+#: views/elements/addon_list_options.thtml:45
+msgid "list_sortby_name"
+msgstr "Nazwy"
+
+#: views/elements/amo2009/addon_list_options.thtml:48
+#: views/elements/addon_list_options.thtml:48
+msgid "list_sortby_rating"
+msgstr "Oceny"
+
+#: config/bootstrap.php:278
+msgid "main_prettyname_fennec"
+msgstr "Fennec"
+
+#: config/bootstrap.php:274
+msgid "main_prettyname_firefox"
+msgstr "Firefox"
+
+#: config/bootstrap.php:277
+msgid "main_prettyname_seamonkey"
+msgstr "SeaMonkey"
+
+#: config/bootstrap.php:276
+msgid "main_prettyname_sunbird"
+msgstr "Sunbird"
+
+#: config/bootstrap.php:275
+msgid "main_prettyname_thunderbird"
+msgstr "Thunderbird"
+
+#: views/elements/addon_categories.thtml:52
+msgid "nav_category_dicts_langpacks"
+msgstr "Słowniki i pakiety językowe"
+
+#: views/elements/addon_categories.thtml:55
+msgid "nav_category_themes"
+msgstr "Motywy"
+
+#: views/elements/app_chooser.thtml:47
+#: views/layouts/amo2009.thtml:255
+msgid "other_apps_tooltip"
+msgstr "Znajdź dodatki dla innych programów"
+
+#. In a user list: user 1, user 2, "others"
+#: views/helpers/addons_html.php:222
+msgid "other_users"
+msgstr "inni"
+
+#: controllers/pages_controller.php:90
+msgid "page_title_appversions"
+msgstr "Wersje programu"
+
+#: controllers/pages_controller.php:115
+msgid "page_title_collector"
+msgstr "Kolekcjoner dodatków"
+
+#: controllers/pages_controller.php:117
+msgid "page_title_collector_faq"
+msgstr "Kolekcjoner dodatków – FAQ"
+
+#: controllers/pages_controller.php:119
+msgid "page_title_collector_features"
+msgstr "Funkcje Kolekcjonera dodatków"
+
+#: controllers/pages_controller.php:122
+msgid "page_title_collector_firstrun"
+msgstr "Zapraszamy do Kolekcjonera dodatków"
+
+#: controllers/pages_controller.php:92
+msgid "page_title_credits"
+msgstr "Podziękowania"
+
+#: controllers/pages_controller.php:113
+msgid "page_title_developer_faq"
+msgstr "FAQ programisty"
+
+#: controllers/pages_controller.php:111
+msgid "page_title_faq"
+msgstr "Często zadawane pytania"
+
+#: controllers/pages_controller.php:94
+msgid "page_title_fashionyourfirefox_faq"
+msgstr "Dostosuj swojego Firefoksa – FAQ"
+
+#: controllers/pages_controller.php:101
+msgid "page_title_policy"
+msgstr "Polityka dodatków"
+
+#: controllers/pages_controller.php:103
+msgid "page_title_privacy"
+msgstr "Polityka prywatności Mozilli"
+
+#: controllers/pages_controller.php:105
+msgid "page_title_review_guide"
+msgstr "Informacje o recenzjach"
+
+#: controllers/pages_controller.php:107
+msgid "page_title_sandbox"
+msgstr "System recenzji piaskownicy"
+
+#: controllers/pages_controller.php:109
+msgid "page_title_submissionhelp"
+msgstr "Wysyłanie dodatków – pomoc"
+
+#: views/pages/appversions.thtml:87
+msgid "pages_appversions_guid"
+msgstr "GUID"
+
+#: views/pages/appversions.thtml:79
+#: controllers/pages_controller.php:90
+msgid "pages_appversions_header"
+msgstr "Poprawne wersje programu"
+
+#: views/pages/appversions.thtml:80
+msgid "pages_appversions_intro"
+msgstr "Dodatki wysłane do Mozilla Add-ons muszą zawierać plik install.rdf, w którym musi być zadeklarowane wsparcie dla przynajmniej jednego z poniższych programów. Tylko wersje wymienione poniżej są dozwolone."
+
+#. %s is a full <a> tag
+#: views/pages/appversions.thtml:93
+#, php-format
+msgid "pages_appversions_required_files"
+msgstr "Nawet jeśli program, w którym ma pracować dany dodatek, nie wymaga pliku install.rdf, należy utworzyć go wg opisu na %s i dołączyć do dodatku."
+
+#. this is the text inside of an <a> tag for pages_appversions_required_files. This
+#. should be fixed.
+#: views/pages/appversions.thtml:93
+msgid "pages_appversions_required_files_link"
+msgstr "tej stronie"
+
+#: views/pages/appversions.thtml:88
+msgid "pages_appversions_versions"
+msgstr "Wersje"
+
+#: views/pages/policy.thtml:51
+msgid "pages_policy_sandbox_link"
+msgstr "Strona informacyjna piaskownicy"
+
+#: views/elements/pagination.thtml:53
+msgid "pagination_next_page"
+msgstr "następna"
+
+#: views/elements/pagination.thtml:52
+msgid "pagination_previous_page"
+msgstr "poprzednia"
+
+#: views/elements/recaptcha.thtml:65
+msgid "recaptcha_enter_both_words"
+msgstr "Wprowadź <strong>oba słowa</strong> poniżej, <strong>oddzielając je spacją</strong>."
+
+#: views/elements/recaptcha.thtml:83
+msgid "recaptcha_enter_here"
+msgstr "Wprowadź tutaj swoją odpowiedź:"
+
+#: views/elements/recaptcha.thtml:74
+msgid "recaptcha_enter_whatyouhear"
+msgstr "Wpisz to, co słyszysz."
+
+#. %1 is the link switching refreshing the captcha
+#. %2 is the link switching to a text captcha
+#: views/elements/recaptcha.thtml:77
+msgid "recaptcha_hardtohear_text"
+msgstr "Jeśli jest to trudne do zrozumienia, <a href=\"%1$s\">posłuchaj</a> czegoś innego lub <a href=\"%2$s\">wróć do formy tekstowej</a>."
+
+#. %1 is the link switching refreshing the captcha
+#. %2 is the link switching to an audio captcha
+#: views/elements/recaptcha.thtml:68
+msgid "recaptcha_hardtoread_text"
+msgstr "Jeśli tekst jest nieczytelny, spróbuj <a href=\"%1$s\">innych słów</a> lub zamiast tego <a href=\"%2$s\">posłuchaj</a> nagrania dźwiękowego."
+
+#: views/users/register.thtml:105
+msgid "recaptcha_label"
+msgstr "Czy jesteś człowiekiem?"
+
+#: views/users/register.thtml:106
+msgid "recaptcha_whatsthis"
+msgstr "Co to jest?"
+
+#: controllers/reviews_controller.php:559
+msgid "review_flag_error"
+msgstr "Podczas oznaczania recenzji etykietą wystąpił błąd!"
+
+#: models/reviews_moderation_flag.php:69
+msgid "review_flag_reason_bug_support"
+msgstr "Niewłaściwie umieszczona prośba o pomoc lub raport o błędzie"
+
+#: views/reviews/display.thtml:103
+#: views/reviews/display.thtml:186
+msgid "review_flag_reason_instructions"
+msgstr "Zgłoś tę recenzję (wybierz powód)"
+
+#: models/reviews_moderation_flag.php:67
+msgid "review_flag_reason_language"
+msgstr "Niewłaściwy język/dialog"
+
+#: models/reviews_moderation_flag.php:71
+msgid "review_flag_reason_other"
+msgstr "Inny (proszę określić)"
+
+#: models/reviews_moderation_flag.php:65
+msgid "review_flag_reason_spam"
+msgstr "Spam lub niecenzuralna treść"
+
+#: views/reviews/display.thtml:91
+#: views/reviews/display.thtml:175
+#: controllers/reviews_controller.php:555
+msgid "review_flag_success"
+msgstr "Dziękujemy. Recenzja została oznaczona etykietą w celu zatwierdzenia jej przez edytora."
+
+#: views/reviews/display.thtml:41
+msgid "review_flag_this"
+msgstr "Zgłoś tę recenzję"
+
+#: views/reviews/display.thtml:42
+msgid "review_flag_this_titletip"
+msgstr "Jeśli ta recenzja jest niewłaściwa lub stanowi spam, kliknij tutaj, by zgłosić ją do oceny przez edytora."
+
+#. %1 is the URL of the support section, %2 for the review guidelines
+#: views/reviews/add.thtml:53
+msgid "review_guidelines_short"
+msgstr "<p>PamiÄ™taj o poniższych wskazówkach:</p><ul><li>Pisz tak, jakbyÅ› mówiÅ‚ przyjacielowi o swoich doÅ›wiadczeniach z dodatkiem. Podawaj charakterystyczne i przydatne szczegóły, takie jak opcje, które ci siÄ™ podobajÄ… lub których nie lubisz, czy Å‚atwo siÄ™ ich używa, a także, czy majÄ… jakieÅ› wady. Unikaj ogólnikowych okreÅ›leÅ„ w rodzaju „Świetnyâ€, czy „ZÅ‚yâ€, chyba że masz dla nich wÅ‚aÅ›ciwe uzasadnienie.</li><li>Nie zgÅ‚aszaj bÅ‚Ä™dów w recenzjach. Twórcy dodatków nie majÄ… dostÄ™pu do twojego adresu e-mail, a mogÄ… potrzebować kontaktu z tobÄ…, by uzyskać dodatkowe informacje pomocne w rozwiÄ…zaniu twojego problemu. Sprawdź w sekcji <a href=\"%1$s\">wsparcie techniczne</a>, gdzie można otrzymać pomoc zwiÄ…zanÄ… z tym dodatkiem.</li><li>Staraj siÄ™, by recenzja byÅ‚a jasna, unikaj używania niewÅ‚aÅ›ciwego jÄ™zyka i nie dodawaj żadnych prywatnych informacji.</li></ul><p>Przeczytaj <a href=\"%2$s\">wskazówki dla recenzentów</a>, by dowiedzieć siÄ™ wiÄ™cej, jak pisać recenzje dodatków.</p>"
+
+#. %1 is the add-on name
+#: views/reviews/flag.thtml:56
+#: views/reviews/display.thtml:55
+#: views/reviews/review_added.thtml:50
+#, php-format
+msgid "reviews_header"
+msgstr "Recenzje dla: %s"
+
+#: controllers/addons_controller.php:435
+msgid "rss_featuredaddons"
+msgstr "Polecane dodatki"
+
+#: controllers/addons_controller.php:432
+msgid "rss_newestaddons"
+msgstr "Najnowsze dodatki"
+
+#: controllers/addons_controller.php:434
+msgid "rss_popularaddons"
+msgstr "Popularne dodatki"
+
+#: controllers/addons_controller.php:433
+msgid "rss_updatedaddons"
+msgstr "Zaktualizowane dodatki"
+
+#: views/elements/search_mini.thtml:70
+msgid "search"
+msgstr "Szukaj"
+
+#: views/search/collections.thtml:51
+msgid "search_collections_header"
+msgstr "Wyniki szukania kolekcji"
+
+#: controllers/search_controller.php:297
+msgid "search_collections_pagetitle"
+msgstr "Wyniki szukania kolekcji"
+
+#: controllers/search_controller.php:99
+msgid "search_disabled"
+msgstr "Wyszukiwanie jest obecnie zablokowane. Prosimy spróbować później."
+
+#: views/elements/amo2009/search.thtml:188
+#: views/elements/search.thtml:187
+#: views/elements/search_mini.thtml:54
+msgid "search_form_all_addons"
+msgstr "wszystkich dodatków"
+
+#. This string is in the main category dropdown when searching
+#: views/elements/amo2009/search.thtml:204
+msgid "search_form_all_collections"
+msgstr "wszystkich kolekcji"
+
+#: views/elements/amo2009/search.thtml:184
+#: views/elements/amo2009/search.thtml:385
+#: views/elements/amo2009/search.thtml:408
+#: views/elements/search.thtml:171
+#: views/elements/search.thtml:183
+#: views/elements/search_mini.thtml:43
+#: views/elements/search_mini.thtml:49
+#: views/layouts/mozilla.thtml:188
+msgid "search_form_default_text"
+msgstr "szukaj dodatków"
+
+#: views/elements/amo2009/search.thtml:184
+#: views/elements/amo2009/search.thtml:404
+msgid "search_form_default_text_collections"
+msgstr "szukaj kolekcji"
+
+#: views/elements/amo2009/search.thtml:206
+#: views/elements/search.thtml:202
+msgid "search_form_submit_tooltip"
+msgstr "Szukaj dodatków"
+
+#: views/elements/amo2009/search.thtml:184
+#: views/elements/search.thtml:183
+#: views/elements/search_mini.thtml:49
+msgid "search_form_tooltip"
+msgstr "Kliknij, by wprowadzić słowa do wyszukania"
+
+#: views/elements/amo2009/search.thtml:186
+#: views/elements/search.thtml:185
+#: views/elements/search_mini.thtml:52
+msgid "search_form_within"
+msgstr "wśród"
+
+#: views/addons/searchengines.thtml:118
+msgid "search_landing_all_search_engines"
+msgstr "Wszystkie wyszukiwarki"
+
+#: views/addons/searchengines.thtml:114
+msgid "search_landing_browse_search_engines"
+msgstr "PrzeglÄ…daj wyszukiwarki"
+
+#: views/search/collections.thtml:58
+#: views/search/index.thtml:59
+msgid "search_nothing_found"
+msgstr "Nie znaleziono."
+
+#: controllers/search_controller.php:185
+msgid "search_pagetitle"
+msgstr "Szukaj dodatków"
+
+#: controllers/search_controller.php:242
+msgid "search_rss_description"
+msgstr "Wyniki szukania kanałów"
+
+#. %s is the terms the user is searching for (a string)
+#: controllers/search_controller.php:241
+#, php-format
+msgid "search_rss_results_for"
+msgstr "Wyniki wyszukiwania dla: %s"
+
+#: views/elements/header.thtml:154
+#: views/layouts/amo2009.thtml:296
+msgid "sidebar_navlink_admin_tools"
+msgstr "Narzędzia administratora"
+
+#: views/elements/header.thtml:146
+#: views/layouts/amo2009.thtml:288
+msgid "sidebar_navlink_developer_tools"
+msgstr "Narzędzia programisty"
+
+#: views/elements/header.thtml:148
+#: views/layouts/amo2009.thtml:290
+msgid "sidebar_navlink_editor_tools"
+msgstr "Narzędzia edytora"
+
+#: views/layouts/amo2009.thtml:302
+msgid "sidebar_navlink_welcome"
+msgstr "Witamy"
+
+#. %s is the user's name
+#: views/layouts/amo2009.thtml:302
+#, php-format
+msgid "sidebar_navlink_welcome_name"
+msgstr "Witaj, %s"
+
+#: views/elements/pitch.thtml:50
+#: views/elements/pitch.thtml:55
+msgid "sidebar_pitch_dictionary"
+msgstr "słownika"
+
+#: views/elements/pitch.thtml:72
+msgid "sidebar_pitch_featured_addons"
+msgstr "Polecane"
+
+#: views/elements/pitch.thtml:61
+msgid "sidebar_pitch_looking_for"
+msgstr "PoszukujÄ™:"
+
+#: views/elements/pitch.thtml:70
+msgid "sidebar_pitch_newest_addons"
+msgstr "Najnowsze"
+
+#: views/elements/pitch.thtml:49
+msgid "sidebar_pitch_search"
+msgstr "wtyczki wyszukiwarki"
+
+#: views/elements/pitch.thtml:69
+msgid "sidebar_pitch_subscribe_to"
+msgstr "Subskrybuj kanał"
+
+#: views/elements/pitch.thtml:48
+#: views/elements/pitch.thtml:54
+msgid "sidebar_pitch_theme"
+msgstr "motywu"
+
+#: views/elements/pitch.thtml:71
+msgid "sidebar_pitch_updated_addons"
+msgstr "Ostatnio zaktualizowane"
+
+#. %1$s is a number
+#: views/helpers/localization.php:65
+#: views/developers/versions_edit.thtml:95
+#: views/addons/dictionaries.thtml:92
+#, php-format
+msgid "size_kb"
+msgstr "%1$s KB"
+
+#: views/elements/amo2009/stars.thtml:57
+#: views/elements/stars.thtml:63
+msgid "stars_not_yet_rated"
+msgstr "Nieoceniony"
+
+#. %1 is the number of stars this add-on has
+#: views/elements/amo2009/stars.thtml:49
+#: views/elements/stars.thtml:54
+#, php-format
+msgid "stars_rated_x_outof_5"
+msgstr "Oceniony jako %s/5"
+
+#: views/statistics/addon.thtml:59
+msgid "statistics_addon_dashboard_link"
+msgstr "Strona główna panelu"
+
+#: views/statistics/addon.thtml:58
+msgid "statistics_addon_developertools_link"
+msgstr "Narzędzia programisty"
+
+#: views/statistics/addon.thtml:53
+msgid "statistics_addon_switch"
+msgstr "Zmień dodatek"
+
+#. This is a date format.
+#. http://php.net/strftime
+#: views/statistics/rss/summary.thtml:54
+#: views/statistics/addon.thtml:181
+msgid "statistics_date_shortmonth"
+msgstr "%d.%m."
+
+#. This is a date format.
+#. http://php.net/strftime
+#: views/statistics/rss/summary.thtml:40
+#: views/statistics/addon.thtml:152
+msgid "statistics_date_shortmonthwithyear"
+msgstr "%d.%m.%Y"
+
+#. This is a date format.
+#. http://php.net/strftime
+#: views/statistics/rss/summary.thtml:41
+#: views/statistics/rss/summary.thtml:48
+#: views/statistics/addon.thtml:161
+#: views/statistics/addon.thtml:172
+msgid "statistics_date_weekdayshortmonth"
+msgstr "%A, %d.%m."
+
+#. %1$s is an add-on name and version. Example: Add-on 3.5
+#: controllers/components/stats.php:519
+#, php-format
+msgid "statistics_events_addon_created"
+msgstr "Dodatek %1$s został utworzony"
+
+#. %1$s is an application name and version. Example: Firefox 3.5
+#: controllers/components/stats.php:500
+#, php-format
+msgid "statistics_events_app_released"
+msgstr "Dodatek %1$s został wydany"
+
+#: views/statistics/addon.thtml:71
+msgid "statistics_help_close_link"
+msgstr "Zamknij"
+
+#: views/statistics/addon.thtml:60
+msgid "statistics_help_link"
+msgstr "Pomoc"
+
+#: views/statistics/index.thtml:83
+msgid "statistics_index_anotheraddon"
+msgstr "albo wybierz inny dodatek"
+
+#: views/statistics/index.thtml:85
+msgid "statistics_index_anotheraddon_public"
+msgstr "albo wybierz dodatek z upublicznionymi statystykami"
+
+#: views/statistics/index.thtml:71
+msgid "statistics_index_myaddons"
+msgstr "Wybierz jeden z dodatków, by wyświetlić jego statystyki"
+
+#: views/statistics/index.thtml:89
+msgid "statistics_index_selectaddon"
+msgstr "Wybierz dodatek, by wyświetlić jego statystyki"
+
+#: views/statistics/index.thtml:91
+msgid "statistics_index_selectaddon_public"
+msgstr "Wybierz dodatek z upublicznionymi statystykami"
+
+#: views/statistics/index.thtml:39
+msgid "statistics_index_title"
+msgstr "Panel statystyk"
+
+#: views/statistics/index.thtml:97
+msgid "statistics_index_view_button"
+msgstr "Wyświetl statystyki"
+
+#: views/statistics/addon.thtml:222
+#: controllers/statistics_controller.php:247
+msgid "statistics_js_download_csv"
+msgstr "Pokaż tę tabelę w formacie CSV"
+
+#: controllers/statistics_controller.php:246
+msgid "statistics_js_dropdowns_none"
+msgstr "brak"
+
+#: controllers/statistics_controller.php:245
+msgid "statistics_js_dropdowns_removeplot"
+msgstr "Usuń ten wykres"
+
+#: controllers/statistics_controller.php:248
+msgid "statistics_js_groupby_selector_date"
+msgstr "Grupuj wg: dni"
+
+#: controllers/statistics_controller.php:251
+msgid "statistics_js_groupby_selector_month"
+msgstr "Grupuj wg: miesięcy"
+
+#: controllers/statistics_controller.php:249
+msgid "statistics_js_groupby_selector_week"
+msgstr "Grupuj wg: tygodni"
+
+#: controllers/statistics_controller.php:250
+msgid "statistics_js_groupby_selector_week_over_week"
+msgstr "Porównaj wg: tygodni"
+
+#: controllers/statistics_controller.php:260
+msgid "statistics_js_plotselection_foundinrange"
+msgstr "Odnaleziono w zakresie: %s"
+
+#: controllers/statistics_controller.php:270
+msgid "statistics_js_plotselection_options_addplot_name"
+msgstr "Dodaj wykres"
+
+#: controllers/statistics_controller.php:271
+msgid "statistics_js_plotselection_options_addplot_tooltip"
+msgstr "Dodaje kolejny wykres do tego grafu"
+
+#: controllers/statistics_controller.php:261
+msgid "statistics_js_plotselection_options_count_name_checked"
+msgstr "Ukryj sumaryczny wykres"
+
+#: controllers/statistics_controller.php:262
+msgid "statistics_js_plotselection_options_count_name_unchecked"
+msgstr "Wyświetl sumaryczny wykres"
+
+#: controllers/statistics_controller.php:263
+msgid "statistics_js_plotselection_options_count_tooltip"
+msgstr "Nanosi na graf sumaryczny wykres"
+
+#: controllers/statistics_controller.php:275
+msgid "statistics_js_plotselection_options_csv_name"
+msgstr "Wyświetl dane (CSV)"
+
+#: controllers/statistics_controller.php:276
+msgid "statistics_js_plotselection_options_csv_tooltip"
+msgstr "Wyświetla plik z tymi danymi w formacie CSV"
+
+#: controllers/statistics_controller.php:267
+msgid "statistics_js_plotselection_options_events_addon_name_checked"
+msgstr "Ukryj wydania %s"
+
+#: controllers/statistics_controller.php:268
+msgid "statistics_js_plotselection_options_events_addon_name_unchecked"
+msgstr "Wyświetl wydania %s"
+
+#: controllers/statistics_controller.php:269
+msgid "statistics_js_plotselection_options_events_addon_tooltip"
+msgstr "Pokazuje/ukrywa na wykresach daty wydań dodatku"
+
+#: controllers/statistics_controller.php:264
+msgid "statistics_js_plotselection_options_events_firefox_name_checked"
+msgstr "Ukryj wydania Firefoksa"
+
+#: controllers/statistics_controller.php:265
+msgid "statistics_js_plotselection_options_events_firefox_name_unchecked"
+msgstr "Wyświetl wydania Firefoksa"
+
+#: controllers/statistics_controller.php:266
+msgid "statistics_js_plotselection_options_events_firefox_tooltip"
+msgstr "Pokazuje/ukrywa na wykresach daty wydań Firefoksa"
+
+#: controllers/statistics_controller.php:272
+msgid "statistics_js_plotselection_options_resize_name_checked"
+msgstr "Pomniejsz graf"
+
+#: controllers/statistics_controller.php:273
+msgid "statistics_js_plotselection_options_resize_name_unchecked"
+msgstr "Powiększ graf"
+
+#: controllers/statistics_controller.php:274
+msgid "statistics_js_plotselection_options_resize_tooltip"
+msgstr "Zmienia rozmiar grafu"
+
+#: controllers/statistics_controller.php:254
+msgid "statistics_js_plotselection_selector_adu"
+msgstr "Aktywni dzienni użytkownicy"
+
+#: controllers/statistics_controller.php:256
+msgid "statistics_js_plotselection_selector_application"
+msgstr "Program"
+
+#: controllers/statistics_controller.php:259
+msgid "statistics_js_plotselection_selector_custom"
+msgstr "WÅ‚asne"
+
+#: controllers/statistics_controller.php:253
+msgid "statistics_js_plotselection_selector_downloads"
+msgstr "Liczba pobrań"
+
+#: controllers/statistics_controller.php:258
+msgid "statistics_js_plotselection_selector_os"
+msgstr "System operacyjny"
+
+#: controllers/statistics_controller.php:257
+msgid "statistics_js_plotselection_selector_status"
+msgstr "Status dodatku"
+
+#: controllers/statistics_controller.php:252
+msgid "statistics_js_plotselection_selector_summary"
+msgstr "Podsumowanie"
+
+#: controllers/statistics_controller.php:255
+msgid "statistics_js_plotselection_selector_version"
+msgstr "Wersja dodatku"
+
+#: controllers/components/stats.php:398
+msgid "statistics_longnames_application"
+msgstr "Program"
+
+#: controllers/components/stats.php:400
+msgid "statistics_longnames_os"
+msgstr "System operacyjny"
+
+#: controllers/components/stats.php:399
+msgid "statistics_longnames_status"
+msgstr "Status dodatku"
+
+#: controllers/components/stats.php:401
+msgid "statistics_longnames_unknown"
+msgstr "Nieznany"
+
+#: controllers/components/stats.php:397
+msgid "statistics_longnames_version"
+msgstr "Wersja dodatku"
+
+#: views/statistics/addon.thtml:118
+msgid "statistics_notice_data_insufficient"
+msgstr "Nie ma jeszcze odpowiedniej ilości danych, aby wyświetlić ten graf. Prosimy spróbować ponownie później."
+
+#: views/statistics/addon.thtml:130
+msgid "statistics_notice_data_none"
+msgstr "Brak danych dla tego dodatku. Prosimy spróbować ponownie za kilka dni."
+
+#: views/statistics/addon.thtml:41
+msgid "statistics_notice_data_updating"
+msgstr "Statystyki dodatków są obecnie aktualizowane. Najnowsze dane mogą być niekompletne podczas procesu ich aktualizacji. Prosimy spróbować ponownie za kilka minut."
+
+#: views/statistics/addon.thtml:136
+msgid "statistics_notice_disabled"
+msgstr "Panel statystyk jest obecnie wyłączony. Prosimy spróbować ponownie później."
+
+#: views/statistics/addon.thtml:123
+msgid "statistics_notice_nojavascript"
+msgstr "Do wyświetlenia wykresów w panelu statystyk konieczne jest włączenie obsługi JavaScriptu."
+
+#: views/statistics/addon.thtml:44
+msgid "statistics_notice_settings_updated"
+msgstr "Twoje ustawienia zostały zaktualizowane!"
+
+#: controllers/statistics_controller.php:60
+#: controllers/statistics_controller.php:71
+#: controllers/statistics_controller.php:74
+#: controllers/statistics_controller.php:240
+msgid "statistics_pagetitle"
+msgstr "Panel statystyk"
+
+#: views/statistics/addon.thtml:99
+msgid "statistics_plot_legend_adu"
+msgstr "Aktywni dzienni użytkownicy"
+
+#: views/statistics/addon.thtml:95
+msgid "statistics_plot_legend_downloads"
+msgstr "Dzienna liczba pobrań"
+
+#: views/statistics/addon.thtml:107
+msgid "statistics_plot_options_zoomin_alt"
+msgstr "Powiększ"
+
+#: views/statistics/addon.thtml:106
+msgid "statistics_plot_options_zoomin_title"
+msgstr "Powiększ o jeden miesiąc"
+
+#: views/statistics/addon.thtml:110
+msgid "statistics_plot_options_zoomout_alt"
+msgstr "Pomniejsz"
+
+#: views/statistics/addon.thtml:109
+msgid "statistics_plot_options_zoomout_title"
+msgstr "Pomniejsz o jeden miesiÄ…c"
+
+#: controllers/statistics_controller.php:283
+#, php-format
+msgid "statistics_rss_description"
+msgstr "Dzienne podsumowanie statystyk dla dodatku %1$s"
+
+#: views/statistics/rss/summary.thtml:68
+msgid "statistics_rss_title_fulldate"
+msgstr "%A, %d.%m.%Y"
+
+#: views/statistics/rss/summary.thtml:68
+#, php-format
+msgid "statistics_rss_title_statsfordate"
+msgstr "Statystyki dla %1$s"
+
+#: views/statistics/settings.thtml:49
+msgid "statistics_settings_access_description"
+msgstr "DomyÅ›lnie tylko Ty i Mozilla macie dostÄ™p do informacji w tym panelu. Można otworzyć ten panel dla wszystkich, zmieniajÄ…c jego status na „Upublicznionyâ€."
+
+#: views/statistics/settings.thtml:48
+msgid "statistics_settings_access_heading"
+msgstr "Dostęp do panelu"
+
+#: views/statistics/settings.thtml:51
+msgid "statistics_settings_access_private"
+msgstr "Prywatny"
+
+#: views/statistics/settings.thtml:51
+msgid "statistics_settings_access_private_description"
+msgstr "Tylko Ty i Mozilla możecie przeglądać statystyki tego dodatku"
+
+#: views/statistics/settings.thtml:52
+msgid "statistics_settings_access_public"
+msgstr "Ogólnodostępny"
+
+#: views/statistics/settings.thtml:52
+msgid "statistics_settings_access_public_description"
+msgstr "Każdy może przeglądać statystyki tego dodatku"
+
+#: views/statistics/addon.thtml:251
+msgid "statistics_settings_change_link"
+msgstr "Zmień ustawienia"
+
+#: views/statistics/addon.thtml:253
+msgid "statistics_settings_confidential"
+msgstr "Informacje te należy traktować jako poufne."
+
+#: views/statistics/addon.thtml:245
+msgid "statistics_settings_currently_private"
+msgstr "Panel jest obecnie <b>prywatny</b>."
+
+#: views/statistics/addon.thtml:241
+msgid "statistics_settings_currently_public"
+msgstr "Panel jest obecnie <b>ogólnodostępny</b>."
+
+#: views/statistics/addon.thtml:246
+msgid "statistics_settings_locked_alt"
+msgstr "Zablokowany"
+
+#: views/statistics/settings.thtml:57
+msgid "statistics_settings_return_link"
+msgstr "Powrót do panelu"
+
+#: views/statistics/settings.thtml:56
+msgid "statistics_settings_save_button"
+msgstr "Zapisz ustawienia"
+
+#: views/statistics/settings.thtml:46
+#, php-format
+msgid "statistics_settings_title"
+msgstr "Ustawienia panelu statystyk dla %1$s"
+
+#: views/statistics/addon.thtml:242
+msgid "statistics_settings_unlocked_alt"
+msgstr "Odblokowany"
+
+#: controllers/components/stats.php:405
+msgid "statistics_shortnames_application"
+msgstr "Prg"
+
+#: controllers/components/stats.php:407
+msgid "statistics_shortnames_os"
+msgstr "SO"
+
+#: controllers/components/stats.php:406
+msgid "statistics_shortnames_status"
+msgstr "St"
+
+#: controllers/components/stats.php:408
+msgid "statistics_shortnames_unknown"
+msgstr "nn."
+
+#: controllers/components/stats.php:404
+msgid "statistics_shortnames_version"
+msgstr "Wer"
+
+#: views/statistics/rss/summary.thtml:42
+#: views/statistics/addon.thtml:192
+msgid "statistics_summary_downloads_average"
+msgstr "Średnia dzienna liczba pobrań"
+
+#: views/statistics/rss/summary.thtml:39
+msgid "statistics_summary_downloads_heading"
+msgstr "Pobrania"
+
+#: views/statistics/rss/summary.thtml:41
+#: views/statistics/addon.thtml:171
+msgid "statistics_summary_downloads_lastcount"
+msgstr "Suma z ostatniego dnia"
+
+#: views/statistics/rss/summary.thtml:43
+#: views/statistics/addon.thtml:199
+msgid "statistics_summary_downloads_lastweek"
+msgstr "Pobrania w ciÄ…gu ostatnich 7 dni"
+
+#: views/statistics/rss/summary.thtml:40
+#: views/statistics/addon.thtml:151
+msgid "statistics_summary_downloads_total"
+msgstr "Całkowita liczba pobrań"
+
+#: views/statistics/rss/summary.thtml:40
+#: views/statistics/addon.thtml:152
+#, php-format
+msgid "statistics_summary_downloads_total_sincedate"
+msgstr "Od %1$s"
+
+#: views/statistics/rss/summary.thtml:50
+#: views/statistics/rss/summary.thtml:56
+#: views/statistics/addon.thtml:163
+#: views/statistics/addon.thtml:183
+msgid "statistics_summary_nodata"
+msgstr "Brak danych jak dotÄ…d"
+
+#: views/statistics/rss/summary.thtml:60
+#: views/statistics/addon.thtml:195
+msgid "statistics_summary_updatepings_average"
+msgstr "Średnia dzienna liczba aktywnych użytkowników"
+
+#: views/statistics/rss/summary.thtml:52
+#: views/statistics/addon.thtml:177
+msgid "statistics_summary_updatepings_changefromprevious"
+msgstr "Zmiana od poprzedniego wyniku"
+
+#: views/statistics/rss/summary.thtml:54
+#: views/statistics/addon.thtml:181
+#, php-format
+msgid "statistics_summary_updatepings_changefromprevious_ondate"
+msgstr "%1$s – %2$s"
+
+#: views/statistics/rss/summary.thtml:45
+msgid "statistics_summary_updatepings_heading"
+msgstr "Aktywni dzienni użytkownicy"
+
+#: views/statistics/rss/summary.thtml:46
+#: views/statistics/addon.thtml:157
+msgid "statistics_summary_updatepings_total"
+msgstr "Aktywni dzienni użytkownicy"
+
+#: views/statistics/rss/summary.thtml:48
+#: views/statistics/addon.thtml:161
+#, php-format
+msgid "statistics_summary_updatepings_total_ondate"
+msgstr "Dnia %1$s"
+
+#: views/statistics/rss/summary.thtml:61
+#: views/statistics/addon.thtml:203
+msgid "statistics_summary_updatepings_weekly_average"
+msgstr "Średnia dzienna liczba użytkowników w tym tygodniu"
+
+#. %s is a percentage, like '+22.33%'. It sits next to another number, so
+#. the implied meaning is 'percentage change' from the previous stat point.
+#: views/statistics/rss/summary.thtml:62
+#: views/statistics/addon.thtml:205
+msgid "statistics_summary_updatepings_weekly_change"
+msgstr "%s od ostatniego tygodnia"
+
+#: views/statistics/addon.thtml:65
+#: controllers/statistics_controller.php:184
+#: controllers/statistics_controller.php:282
+#, php-format
+msgid "statistics_title_addon_stats"
+msgstr "%1$s – statystyki"
+
+#: views/addons/themes_landing.thtml:113
+msgid "themes_landing_all_themes"
+msgstr "Wszystkie motywy"
+
+#: views/addons/themes_landing.thtml:109
+msgid "themes_landing_browse_themes"
+msgstr "PrzeglÄ…daj motywy"
+
+#: views/users/edit.thtml:185
+msgid "user_change_email"
+msgstr "Zmień adres e-mail"
+
+#: views/users/edit.thtml:169
+msgid "user_change_password"
+msgstr "Zmień hasło"
+
+#: views/users/edit.thtml:96
+msgid "user_change_password_or_email"
+msgstr "Zmień hasło lub adres e-mail"
+
+#: controllers/users_controller.php:197
+msgid "user_confirmationcode_resent"
+msgstr "Kod potwierdzający został wysłany ponownie!"
+
+#. %1 is the email address, %2 is the URL of the user registration page
+#: views/users/delete.thtml:51
+msgid "user_del_account_deleted"
+msgstr "Twoje konto %1$s zostało usunięte. Jeśli kiedykolwiek zapragniesz powrócić do nas, zarejestruj się ponownie na <a href=\"%2$s\">stronie rejestracji użytkownika</a>."
+
+#: views/users/delete.thtml:102
+msgid "user_del_community_sad"
+msgstr "Społeczność Mozilla Add-ons smuci się, że nas opuszczasz."
+
+#: views/users/delete.thtml:123
+msgid "user_del_confirm_password"
+msgstr "Potwierdź hasło"
+
+#: views/users/delete.thtml:134
+msgid "user_del_deletenow"
+msgstr "Usuń moje konto"
+
+#. %1 is the URL of the user's info page
+#: views/users/delete.thtml:64
+msgid "user_del_error_addons"
+msgstr "Nie możesz usunąć swojego konta, jeśli jesteś <a href=\"%1$s\">twórcą jakiegoś dodatku</a>. Aby usunąć swoje konto, poproś inną osobę z listy autorów tego dodatku, by usunęła Cię z tej listy, następnie wróć tutaj, aby usunąć swoje konto."
+
+#. %1 is a link to the amo-editors mailing list
+#: views/users/delete.thtml:71
+msgid "user_del_error_addons_more_questions"
+msgstr "Jeśli masz dodatkowe pytania, skontaktuj się z %1$s, by uzyskać pomoc."
+
+#: views/users/delete.thtml:78
+msgid "user_del_error_checkbox"
+msgstr "Przed usuniÄ™ciem konta należy zaznaczyć pole „ZdajÄ™ sobie sprawę…â€."
+
+#: views/users/delete.thtml:84
+msgid "user_del_error_password"
+msgstr "Proszę wprowadzić poprawnie hasło, aby wykonać ten krok."
+
+#. %1 is a link to the amo-admins mailing list
+#: views/users/delete.thtml:91
+msgid "user_del_error_unknown"
+msgstr "W celu usunięcia błędu, proszę skontaktować się z %1$s."
+
+#: views/users/delete.thtml:110
+msgid "user_del_header_confirm_deletion"
+msgstr "Potwierdź usunięcie konta"
+
+#. %1 is the user's email address
+#: views/users/delete.thtml:100
+msgid "user_del_header_delete_account"
+msgstr "Usuwanie konta %1$s"
+
+#: views/users/delete.thtml:50
+msgid "user_del_header_farewell"
+msgstr "Do widzenia!"
+
+#: views/users/delete.thtml:115
+msgid "user_del_nologin"
+msgstr "Nie będziesz mieć możliwości zalogowania się na Mozilla Add-ons."
+
+#: views/users/delete.thtml:112
+msgid "user_del_permanently_removed_means"
+msgstr "Po naciśnięciu przycisku „Usuń moje konto†Twoje konto zostanie <strong>trwale usunięte</strong>. Oznacza to, że:"
+
+#: views/users/delete.thtml:116
+msgid "user_del_reviews_anonymized"
+msgstr "Twoje recenzje i oceny nie zostaną usunięte, ale nie będą dłużej z Tobą powiązane."
+
+#. %1 is a link to the amo-editors mailing list
+#: views/users/delete.thtml:104
+msgid "user_del_specific_problem_editors"
+msgstr "Jeśli masz szczególny problem, możemy Ci pomóc. Prosimy – nie usuwaj teraz swojego konta, ale skontaktuj się z nami poprzez %1$s, a zrobimy wszystko, aby pomóc Ci w jego rozwiązaniu."
+
+#: views/users/delete.thtml:130
+msgid "user_del_understand_permanent"
+msgstr "Zdaję sobie sprawę, że ten krok nie może być cofnięty."
+
+#: views/helpers/addons_html.php:192
+msgid "user_deleted_nickname"
+msgstr "Konto użytkownika zostało usunięte"
+
+#. %1 is the new email address
+#: views/users/edit.thtml:71
+msgid "user_edit_confirm_email_sent"
+msgstr "List z potwierdzeniem nowego adresu e-mail został wysłany na %1$s. Aby zmiana zaczęła obowiązywać, należy kliknąć odnośnik przesłany w tym e-mailu. Póki to nie nastąpi, można logować się przy użyciu dotychczasowego adresu e-mail."
+
+#: views/users/edit.thtml:201
+msgid "user_edit_delete_user"
+msgstr "Usuwanie konta użytkownika"
+
+#. This contains the email sent to users when they signed up for a new
+#. account:
+#. %1 is the confirmation URL, %2 is the current app
+#: views/users/email/confirm_plain.thtml:6
+#, php-format
+msgid "user_email_confirm_account_nopass"
+msgstr ""
+"Witaj w %2$s – dodatki.\n"
+"\n"
+"Zanim zaczniesz używać swojego nowego konta, musisz je aktywować. Aktywacja potwierdza, że adres e-mail podany przez Ciebie podczas rejestracji jest poprawny i stanowi Twoją własność.\n"
+"Aby aktywować swoje konto, kliknij odnośnik poniżej lub skopiuj i wklej cały adres do paska adresu swojej przeglądarki:\n"
+"\n"
+"%1$s\n"
+"\n"
+"Po aktywacji konta można usunąć tę wiadomość.\n"
+"\n"
+"Dziękujemy za przyłączenie się do %2$s – dodatki\n"
+"— Zespół %2$s – dodatki"
+
+#. %1 is the confirmation url, %2 is the application name
+#: views/users/email/emailchange_plain.thtml:5
+msgid "user_email_confirm_emailchange"
+msgstr ""
+"Poprosiłeś o zmianę adresu e-mail na %2$s – dodatki.\n"
+"\n"
+"Aby potwierdzić nowy adres, proszę kliknąć poniższy odnośnik lub skopiować i wkleić cały adres do paska adresu przeglądarki:\n"
+"\n"
+"%1$s\n"
+"\n"
+"Nowy adres należy potwierdzić w ciągu 48 godzin. Jeśli jednak nie chcesz zmieniać adresu, wystarczy po prostu zignorować ten e-mail.\n"
+"\n"
+"Dziękujemy!\n"
+"— Zespół %2$s – dodatki"
+
+#: controllers/users_controller.php:168
+#, php-format
+msgid "user_email_confirm_subject"
+msgstr "Dziękujemy za dołączenie do %s – dodatki"
+
+#. This is the password reset email
+#. %1 is the pw reset URL, %2 is the application
+#: views/users/email/pwreset_plain.thtml:5
+#, php-format
+msgid "user_email_pwreset"
+msgstr ""
+"%2$s – dodatki — Resetowanie hasła\n"
+"\n"
+"Otrzymaliśmy prośbę o zresetowanie hasła dla tego konta na addons.mozilla.org. Aby zmienić hasło, kliknij odnośnik poniżej lub skopiuj i wklej cały adres do paska adresu swojej przeglądarki:\n"
+"\n"
+"%1$s\n"
+"\n"
+"Jeśli z Twojej strony nie było prośby o zresetowanie hasła, nie ma potrzeby podejmowania jakiegokolwiek działania.\n"
+"\n"
+"Dziękujemy,\n"
+"— Zespoł %2$s – dodatki"
+
+#: controllers/users_controller.php:245
+#, php-format
+msgid "user_email_pwreset_subject"
+msgstr "Zresetuj swoje hasło do %s – dodatki"
+
+#: views/users/emailchange.thtml:50
+msgid "user_emailchange_error"
+msgstr "BÅ‚Ä…d!"
+
+#. %1 is the application name
+#: controllers/users_controller.php:533
+msgid "user_emailchange_subject"
+msgstr "Proszę potwierdzić zmianę adresu e-mail w %1$s – dodatki"
+
+#: views/users/emailchange.thtml:48
+msgid "user_emailchange_success"
+msgstr "Zmiana została dokonana!"
+
+#. %1 is the new email address
+#: views/users/emailchange.thtml:49
+msgid "user_emailchange_successful_description"
+msgstr "Twój adres e-mail został zmieniony. Od teraz do logowania proszę używać %1$s."
+
+#: views/users/edit.thtml:134
+#: views/admin/users_edit.thtml:111
+msgid "user_form_bio"
+msgstr "O mnie"
+
+#: views/users/edit.thtml:135
+#: views/admin/users_edit.thtml:112
+msgid "user_form_bio_description"
+msgstr "Przedstaw siÄ™ spoÅ‚ecznoÅ›ci – jeÅ›li chcesz! Ten tekst bÄ™dzie wyÅ›wietlany na Twojej ogólnodostÄ™pnej stronie. Åamanie wierszy zostanie zachowane, ale kod HTML jest niedozwolony."
+
+#: views/users/pwreset.thtml:77
+#: views/users/register.thtml:73
+#: views/users/edit.thtml:181
+msgid "user_form_confirmpassword"
+msgstr "Potwierdź hasło"
+
+#: views/users/edit.thtml:145
+msgid "user_form_display_collections"
+msgstr "Wyświetlaj w profilu utworzone przeze mnie kolekcje"
+
+#: views/users/edit.thtml:149
+msgid "user_form_display_collections_fav"
+msgstr "Wyświetlaj w profilu moje ulubione kolekcje"
+
+#: views/users/edit.thtml:86
+#, php-format
+msgid "user_form_editprofile"
+msgstr "Edytowanie profilu użytkownika: %s"
+
+#: views/users/pwreset.thtml:52
+#: views/users/login.thtml:81
+#: views/users/register.thtml:63
+#: views/users/edit.thtml:187
+msgid "user_form_email"
+msgstr "Adres e-mail"
+
+#: views/users/register.thtml:78
+#: views/users/edit.thtml:103
+#: views/admin/users_edit.thtml:76
+msgid "user_form_firstname"
+msgstr "ImiÄ™"
+
+#: views/users/register.thtml:94
+#: views/users/edit.thtml:119
+#: views/admin/users_edit.thtml:91
+msgid "user_form_hideemail"
+msgstr "Ukryj adres e-mail"
+
+#: views/users/register.thtml:98
+#: views/users/edit.thtml:123
+#: views/admin/users_edit.thtml:99
+msgid "user_form_homepage"
+msgstr "Strona internetowa"
+
+#: views/users/register.thtml:84
+#: views/users/edit.thtml:109
+#: views/admin/users_edit.thtml:81
+msgid "user_form_lastname"
+msgstr "Nazwisko"
+
+#: controllers/users_controller.php:333
+msgid "user_form_login"
+msgstr "Nazwa użytkownika"
+
+#: views/users/pwreset.thtml:72
+#: views/users/edit.thtml:176
+msgid "user_form_newpassword"
+msgstr "Nowe hasło"
+
+#: views/users/register.thtml:89
+#: views/users/edit.thtml:114
+#: views/admin/users_edit.thtml:86
+msgid "user_form_nickname"
+msgstr "Nick"
+
+#: views/users/edit.thtml:171
+msgid "user_form_oldpassword"
+msgstr "Stare hasło"
+
+#: views/users/edit.thtml:97
+#: views/users/edit.thtml:200
+msgid "user_form_otheractions"
+msgstr "Inne możliwości"
+
+#: views/users/login.thtml:85
+#: views/users/register.thtml:68
+msgid "user_form_password"
+msgstr "Hasło"
+
+#: controllers/users_controller.php:93
+msgid "user_form_registration"
+msgstr "Rejestracja nowego użytkownika"
+
+#: views/users/login.thtml:90
+msgid "user_form_remember_me"
+msgstr "Zapamiętaj mnie na tym komputerze"
+
+#: views/admin/users_edit.thtml:95
+msgid "user_form_showsandbox"
+msgstr "Pokazać „Piaskownicę�"
+
+#: views/users/edit.thtml:205
+msgid "user_form_submit_edit"
+msgstr "Zapisz"
+
+#: views/users/login.thtml:93
+msgid "user_form_submit_login"
+msgstr "Zaloguj siÄ™"
+
+#: views/users/register.thtml:113
+msgid "user_form_submit_register"
+msgstr "Zarejestruj siÄ™"
+
+#: views/users/info.thtml:75
+#, php-format
+msgid "user_info_usersince"
+msgstr "Użytkownik %s – dodatki od:"
+
+#: views/users/login.thtml:102
+msgid "user_login_register_link"
+msgstr "Utwórz nowe konto"
+
+#: views/users/edit.thtml:160
+msgid "user_notifications_item_compat"
+msgstr "Kompatybilność dodatku (zalecane)"
+
+#: views/users/edit.thtml:161
+msgid "user_notifications_item_events"
+msgstr "Najbliższe wydarzenia i konkursy"
+
+#: views/users/edit.thtml:156
+msgid "user_notifications_none_available"
+msgstr "Obecnie nie ma żadnych powiadomień odpowiadających Twojej konfiguracji."
+
+#: views/users/edit.thtml:158
+msgid "user_notifications_select_topics"
+msgstr "Od czasu do czasu Mozilla może wysyłać do Ciebie e-mail z informacjami o nadchodzących wydaniach i wydarzeniach związanych z dodatkami. Wybierz interesujące Cię zagadnienia:"
+
+#: views/users/edit.thtml:164
+msgid "user_notifications_specific_contact"
+msgstr "Mozilla zastrzega sobie prawo do bezpośredniego kontaktu z Tobą w szczegółowych sprawach dotyczących Twoich dodatków."
+
+#: controllers/users_controller.php:543
+msgid "user_profile_edit_error"
+msgstr "Wprowadzone zmiany zawierają błędy. Należy je poprawić i wysłać ponownie."
+
+#: controllers/users_controller.php:540
+msgid "user_profile_saved"
+msgstr "Profil został zaktualizowany."
+
+#: views/users/pwreset.thtml:65
+#, php-format
+msgid "user_pwreset_for_email"
+msgstr "Resetowanie hasła dla konta: %s"
+
+#: controllers/users_controller.php:226
+msgid "user_pwreset_header"
+msgstr "Resetowanie hasła"
+
+#: views/users/login.thtml:103
+msgid "user_pwreset_link"
+msgstr "Nie pamiętasz hasła?"
+
+#: controllers/users_controller.php:248
+msgid "user_pwreset_link_sent"
+msgstr "Dane potrzebne do zresetowania hasła zostały wysłany e-mailem."
+
+#: controllers/users_controller.php:304
+msgid "user_pwreset_okay"
+msgstr "Hasło zostało zresetowane."
+
+#: views/users/pwreset.thtml:82
+msgid "user_pwreset_submit_changepw"
+msgstr "Zmień hasło"
+
+#: views/users/pwreset.thtml:57
+msgid "user_pwreset_submit_sendlink"
+msgstr "Zresetuj moje hasło"
+
+#: views/users/register_complete.thtml:51
+#, php-format
+msgid "user_register_amo_link"
+msgstr "%s – dodatki"
+
+#. %1 is the user's email address, %2 is the current app
+#: views/users/activatefirst.thtml:49
+#, php-format
+msgid "user_register_click_confirm_link"
+msgstr "Odnośnik aktywujący konto został wysłany e-mailem na adres %1$s. Należy kliknąć go przed pierwszym logowaniem do %2$s – dodatki."
+
+#. %1 is the user's email address
+#: views/users/register_complete.thtml:49
+#, php-format
+msgid "user_register_confirm_email_sent"
+msgstr "Na Twój adres e-mail %1$s została wysłana wiadomość zawierająca dane do aktywacji konta. Aby móc się zalogować, należy dokonać jego aktywacji klikając odnośnik znajdujący się w wiadomości."
+
+#: views/users/activatefirst.thtml:51
+msgid "user_register_confirmation_link_text"
+msgstr "ponowne przesłanie kodu potwierdzającego"
+
+#: views/users/register_complete.thtml:47
+msgid "user_register_congratulations"
+msgstr "Gratulujemy! Twoje konto zostało utworzone."
+
+#: views/users/register.thtml:50
+msgid "user_register_details"
+msgstr "<p>Rejestracja na witrynie AMO <strong>nie jest wymagana</strong>, jeśli chcesz tylko pobierać i instalować dodatki znajdujące się w ogólnodostępnej części witryny.</p><p>Musisz zarejestrować się jeśli:</p><ul><li>Chcesz recenzować dodatki</li><li>Jesteś autorem dodatku i chcesz umieścić go na witrynie AMO</li></ul><p>Po zarejestrowaniu, na podany podczas rejestracji adres e-mail otrzymasz wiadomość z danymi do potwierdzenia konta. Aby potwierdzić swoje konto, postępuj zgodnie z zawartymi w tej wiadomości instrukcjami.</p><p>Jeśli chcesz możesz zapoznać się z naszymi <a href='%1$s' title='Informacje prawne'>informacjami prawnymi</a> oraz <a href='%2$s' title='Polityka prywatności'>polityką prywatności</a>.</p>"
+
+#. %1 is the link to the "resend confirmation code" page
+#: views/users/activatefirst.thtml:51
+#, php-format
+msgid "user_register_resend_confirmation_link"
+msgstr "JeÅ›li w Twojej skrzynce odbiorczej nie ma wiadomoÅ›ci z danymi do potwierdzenia konta, upewnij siÄ™, czy nie zostaÅ‚a ona oznaczona jako niechciana lub „spamâ€. W razie potrzeby możesz poprosić o %1$s na podany wyżej adres."
+
+#. %1 is the link to the Mozilla Add-ons front page
+#: views/users/register_complete.thtml:51
+#, php-format
+msgid "user_register_welcome"
+msgstr "Dziękujemy za zarejestrowanie się i witamy w serwisie %1$s!"
+
+#: views/users/register.thtml:49
+msgid "user_register_welcome_header"
+msgstr "Witaj na addons.mozilla.org (AMO)!"
+
+#: views/users/register.thtml:81
+#: views/users/edit.thtml:106
+msgid "user_required_firstlast_or_nickname"
+msgstr "Wymagane jest imiÄ™, nazwisko lub pseudonim."
+
+#: views/users/edit.thtml:94
+#: views/users/edit.thtml:142
+msgid "user_tab_collections"
+msgstr "Kolekcje"
+
+#: views/users/edit.thtml:95
+#: views/users/edit.thtml:154
+msgid "user_tab_notifications"
+msgstr "Powiadomienia"
+
+#: views/users/edit.thtml:93
+#: views/users/edit.thtml:101
+msgid "user_tab_profile"
+msgstr "Profil użytkownika"
+
+#: controllers/users_controller.php:209
+msgid "user_verified_okay"
+msgstr "Konto zostało pomyślnie zweryfikowane!"
+
+#: controllers/users_controller.php:723
+msgid "users_delete_pagetitle"
+msgstr "Usuwanie konta użytkownika"
+
+#: controllers/users_controller.php:414
+msgid "users_edit_pagetitle"
+msgstr "Edytowanie konta użytkownika"
+
+#: views/users/info.thtml:71
+msgid "users_info_aboutme"
+msgstr "O mnie"
+
+#: views/users/info.thtml:96
+#, php-format
+msgid "users_info_addons_by_user"
+msgstr "Dodatki autorstwa: %1$s"
+
+#: views/users/info.thtml:51
+msgid "users_info_author_name"
+msgstr "ImiÄ™ i nazwisko"
+
+#: views/users/info.thtml:48
+msgid "users_info_author_profile"
+msgstr "Profil autora"
+
+#. %s is the user name
+#: views/users/info.thtml:137
+msgid "users_info_collections_by_user"
+msgstr "Kolekcje utworzone przez %s"
+
+#: views/users/info.thtml:66
+msgid "users_info_email"
+msgstr "Adres e-mail"
+
+#: views/users/info.thtml:155
+msgid "users_info_fav_collections_by_user"
+msgstr "Ulubione kolekcje"
+
+#: views/users/info.thtml:61
+msgid "users_info_homepage"
+msgstr "Strona domowa"
+
+#: views/users/info.thtml:56
+msgid "users_info_nickname"
+msgstr "Nick"
+
+#: controllers/users_controller.php:707
+#, php-format
+msgid "users_info_pagetitle"
+msgstr "Informacje o użytkowniku %1$s"
+
+#. %1 is the user's name
+#: views/users/info.thtml:116
+msgid "users_info_reviews_by_user"
+msgstr "Recenzje autorstwa: %s"
+
+#: controllers/users_controller.php:330
+#: controllers/users_controller.php:332
+msgid "users_login_pagetitle"
+msgstr "Nazwa użytkownika"
+
+#. %1 is the link to the sandbox/policy explanation page
+#. This message is for a specific add-on not found
+#: views/users/login.thtml:53
+#, php-format
+msgid "users_login_sandbox_display_warning"
+msgstr "Dodatek, którego szukasz, jest aktualnie w piaskownicy. Jeśli posiadasz już konto w Mozilla Add-ons, zaloguj się, lub <a href=\"%1$s\">dowiedz się więcej o piaskownicy.</a>"
+
+#. %1 is the link to the sandbox/policy explanation page
+#. This message is for any given sandbox-related page not found
+#: views/users/login.thtml:56
+#, php-format
+msgid "users_login_sandbox_page_warning"
+msgstr "Strona, której szukasz, jest częścią piaskownicy. Jeśli posiadasz już konto w Mozilla Add-ons, zaloguj się, lub <a href=\"%1$s\">dowiedz się więcej o piaskownicy.</a>"
+
+#: controllers/users_controller.php:223
+#: controllers/users_controller.php:225
+msgid "users_pwreset_pagetitle"
+msgstr "Resetowanie hasła użytkownika"
+
+#: controllers/users_controller.php:90
+#: controllers/users_controller.php:92
+msgid "users_register_pagetitle"
+msgstr "Rejestracja nowego użytkownika"
+
+#. %1$s is an addon name, like <a>Firebug</a>
+#. %2$s is a version number, like <a>1.2</a>
+#: views/versions/license.thtml:52
+msgid "versions_license_header_source"
+msgstr "Licencja kodu źródłowego dla %1$s %2$s"
+
+#: views/addons/category_landing.thtml:147
+msgid "view_recently_added"
+msgstr "Pokaż wszystkie ostatnio dodane"
+
+#: views/addons/category_landing.thtml:161
+msgid "view_top_downloads"
+msgstr "Pokaż wszystkie najczęściej pobierane"
+
+#: views/addons/category_landing.thtml:175
+msgid "view_top_rated"
+msgstr "Pokaż wszystkie najwyżej oceniane"
+
diff --git a/site/app/locale/pl/images/sandbox-review.png b/site/app/locale/pl/images/sandbox-review.png
new file mode 100644
index 0000000..4e4afbf
--- /dev/null
+++ b/site/app/locale/pl/images/sandbox-review.png
Binary files differ
diff --git a/site/app/locale/pl/pages/about.thtml b/site/app/locale/pl/pages/about.thtml
new file mode 100644
index 0000000..df7f41d
--- /dev/null
+++ b/site/app/locale/pl/pages/about.thtml
@@ -0,0 +1,63 @@
+<h2>Co to jest addons.mozilla.org?</h2>
+<p>
+ addons.mozilla.org (AMO) jest oficjalnÄ… witrynÄ… Mozilli gromadzÄ…cÄ… dodatki do
+ programów Mozilli. Dodatki umożliwiają dodanie nowych funkcji do Firefoksa,
+ Thunderbirda, SeaMonkey czy Sunbirda. Na witrynie AMO można przeglądać, pobrać i
+ zainstalować tysiące dodatków umożliwiających zmianę sposobu używania Internetu.
+</p>
+
+<h2>Kto tworzy te dodatki?</h2>
+<p>
+ Tysiące twórców dodatków, poczynając od hobbystów po wielkie korporacje. Wszystkie
+ ogólnodostępne dodatki, przed ich upublicznieniem, są sprawdzane przez zespół
+ wolontariuszy. Dodatki eksperymentalne sÄ… oznaczone i sÄ… jeszcze niesprawdzone.
+</p>
+
+<h2>Jak uzyskać bieżące informacje o tym, co się dzieje na AMO?</h2>
+<p>
+ Nasz <a href="http://blog.mozilla.com/addons/">blog</a> jest regularnie aktualizowany
+ i często zamieszczamy na nim posty naszej społeczności. Mamy także wydawany co miesiąc
+ <a href="https://addons.mozilla.org/newsletter">biuletyn</a>.
+</p>
+
+<h2>Wspaniale! Jak można zaangażować się w działalność AMO?</h2>
+<p>
+ Można to zrobić na wiele sposobów:
+</p>
+<ul>
+ <li>
+ <a href="https://wiki.mozilla.org/AMO:Editors/Applying">Zostań edytorem</a>.
+ Nasi edytorzy to fani AMO posiadający wiedzę techniczną na poziomie umożliwiającym
+ sprawdzanie poprawności kodu i stabilności dodatków.
+ </li>
+ <li>
+ <a href="http://developer.mozilla.org/">Stwórz własny dodatek</a>. AMO
+ zapewnia darmowe przechowywanie i aktualizacje dodatków, a także może pomóc osiągnąć
+ dużą liczbę użytkowników danego dodatku.
+ </li>
+ <li>
+ Poinformuj swoich znajomych! <a href="http://spreadfirefox.com/">Promuj Firefoksa</a>
+ i powiedz wszystkim, jakich dodatków używasz.
+ </li>
+ <li>
+ Informuj o błędach i sugeruj poprawki.
+ Na <a href="https://bugzilla.mozilla.org/buglist.cgi?quicksearch=addons">Bugzilli</a>
+ znajdują się wszystkie aktualne błędy AMO. Możesz zamieścić tam informację o odkrytym
+ błędzie bądź stworzoną przez Ciebie poprawkę.
+ </li>
+</ul>
+
+<h2>Mam pytanie</h2>
+<p>
+ Dobrym miejscem do poszukania odpowiedzi jest dział
+ <a href="https://addons.mozilla.org/pages/faq"><abbr title="Często zadawane pytania">FAQ</abbr></a>. Jeśli
+ nie możesz znaleźć tam odpowiedzi, użyj informacji kontaktowych znajdujących się na dole tej strony. Jeśli
+ masz pytania dotyczÄ…ce konkretnego dodatku, skorzystaj z informacji kontaktowych znajdujÄ…cych siÄ™ na stronie tego dodatku.
+</p>
+
+<h2>Kontakt z nami</h2>
+<dl>
+ <dt>Za pomocÄ… <abbr title="Internet Relay Chat">IRC-a</abbr> na kanale:</dt>
+ <dd><a href="irc://irc.mozilla.org/#addons">#addons</a> w sieci irc.mozilla.org – w kwestiach ogólnych i recenzji dodatków</dd>
+ <dd><a href="irc://irc.mozilla.org/#amo">#amo</a> w sieci irc.mozilla.org – w kwestiach administracyjnych lub zagadnień związanych z tworzeniem dodatków</dd>
+</dl>
diff --git a/site/app/locale/pl/pages/collector.thtml b/site/app/locale/pl/pages/collector.thtml
new file mode 100644
index 0000000..d9491a5
--- /dev/null
+++ b/site/app/locale/pl/pages/collector.thtml
@@ -0,0 +1,47 @@
+<h2>Mozilla Firefox – Kolekcjoner dodatków</h2>
+
+<p class="intro">Dostosuj swoją przeglądarkę za pomocą najnowocześniejszego narzędzia.</p>
+
+<div class="primary">
+ <p>Poznaj więcej najlepszych dodatków i organizuj swoje ulubione dodatki w łatwe do zarządzania kolekcje. Subskrybuj je, aby zobaczyć, jak kolekcje, które podziwiasz, rozrastają się i zwiększa się liczba wielbicieli, gdy zarządzasz i aktualizujesz swoje kolekcje.</p>
+</div>
+
+<div class="secondary">
+ <div class="highlight">
+ <h4>Pobierz Kolekcjonera dodatków:</h4>
+ %1$s
+ </div><!-- /.highlight -->
+</div>
+
+<div class="column-wrapper article-wrapper">
+
+ <div class="column first">
+ <div class="article">
+ <h3>Polecane kolekcje</h3>
+ <p>Subskrybuj kolekcję dodatków i odbieraj powiadomienia, gdy pojawią się w niej nowe dodatki. Jeśli tworzysz kolekcję, jest tam miejsce, aby napisać, dlaczego lubisz dany dodatek i przekazać kilka uwag o jego funkcjach.</p>
+
+ </div>
+ </div>
+
+ <div class="column">
+ <div class="article">
+ <h3>Udostępniaj dodatki</h3>
+ <p>Powiadom znajomych o dobrych dodatkach. NaciÅ›nij przycisk „WyÅ›lij doâ€, a otrzymajÄ… oni wiadomość o dodatkach w gotowej do natychmiastowego użycia formie.</p>
+ </div>
+
+ </div>
+
+
+ <div class="column">
+ <div class="article">
+ <h3>Synchronizacja ze wszystkimi źródłami</h3>
+ <p>Za pomocą funkcji automatycznych kolekcji powiadamiaj o nowych kolekcjach dodatków i dostarczaj odnośniki, które pozwalają mieć bieżące informacje o kolekcji. Funkcja ta synchronizuje urządzenia i dostarcza wszystkim Twoim przeglądarkom Twoje najnowsze kolekcje.</p>
+ </div>
+ </div>
+
+</div><!-- /.column-wrapper .article-wrapper -->
+
+<ul class="further-navigation">
+ <li><a href="%2$s">Funkcje Kolekcjonera dodatków</a></li>
+ <li><a href="%3$s">Często zadawane pytania</a></li>
+</ul>
diff --git a/site/app/locale/pl/pages/collector_faq.thtml b/site/app/locale/pl/pages/collector_faq.thtml
new file mode 100644
index 0000000..fa7fedf
--- /dev/null
+++ b/site/app/locale/pl/pages/collector_faq.thtml
@@ -0,0 +1,24 @@
+<h1>Kolekcjoner dodatków – często zadawane pytania (FAQ)</h1>
+
+<dl class="faq">
+<dt>Co to sÄ… kolekcje?</dt>
+<dd>Kolekcje są grupami podobnych dodatków zgromadzonych razem, aby ułatwić ich udostępnianie.</dd>
+
+<dt>Co to jest Kolekcjoner dodatków?</dt>
+<dd>Kolekcjoner dodatków jest rozszerzeniem dla Firefoksa, które umożliwia łatwą aktualizację ulubionych kolekcji.</dd>
+
+<dt>Co jest potrzebne, aby używać Kolekcjonera dodatków?</dt>
+<dd>Trzeba mieć <a href="%s">konto na witrynie Mozilla Add-ons</a> i najnowszą wersję <a href="http://www.getfirefox.com">Firefoksa</a>.</dd>
+
+<dt>W jaki sposób można subskrybować kolekcję?</dt>
+<dd>Kolekcję można subskrybować zaznaczając ją jako ulubioną w <a href="%s">Katalogu kolekcji</a>. Ulubione kolekcje będą wyświetlane jako subskrypcje w Menedżerze dodatków Firefoksa.</dd>
+
+<dt>W jaki sposób można synchronizować dodatki pomiędzy komputerami używając Kolekcjonera dodatków?</dt>
+<dd>Wystarczy włączyć opcję autokolekcji w jednym komputerze i na górze listy subskrypcji na wszystkich komputerach, które mają zainstalowanego Kolekcjonera dodatków, będzie wyświetlana automatycznie tworzona kolekcja. Będzie można zobaczyć dodatki zainstalowane na każdym komputerze, które mają włączoną opcję autokolekcji.</dd>
+
+<dt>Czy projekt Weave z Mozilla Labs już może synchronizować dodatki?</dt>
+<dd>Weave planuje w przyszłości dołączyć synchronizację dodatków pomiędzy profilami i urządzeniami. Synchronizacja w Kolekcjonerze dodatków działa trochę inaczej. Dane zawarte w automatycznych kolekcjach nie są kodowane i są przeznaczone do udostępniania innym osobom w formie kolekcji. Dodatki mogą być współdzielone pomiędzy profilami przy użyciu wielu kolekcji.</dd>
+
+<dt>Gdzie można przekazać swoją opinię lub zgłosić błąd?</dt>
+<dd>Jeśli znajdziesz błąd lub chcesz przekazać propozycję nowej funkcji, zrób to za pośrednictwem Bugzilli używając <a href="https://bugzilla.mozilla.org/enter_bug.cgi?component=Bandwagon&amp;product=addons.mozilla.org">tego formularza</a>. Jeśli chcesz przekazać ogólną opinię, zrób to na naszej <a href="http://groups.google.com/group/mozilla.dev.amo">grupie dyskusyjnej</a>.</dd>
+</dl>
diff --git a/site/app/locale/pl/pages/collector_firstrun.thtml b/site/app/locale/pl/pages/collector_firstrun.thtml
new file mode 100644
index 0000000..d6c7be6
--- /dev/null
+++ b/site/app/locale/pl/pages/collector_firstrun.thtml
@@ -0,0 +1,38 @@
+<div>
+ <h2>Witamy!</h2>
+ <p class="intro">Rozszerzenie Kolekcjoner dodatków zostało dodane do Firefoksa. Za chwilę będzie można rozpocząć tworzenie, zarządzanie, udostępnianie i odbieranie kolekcji dodatków.</p>
+</div>
+
+ <div class="primary">
+ <h3>Aby zacząć używać rozszerzenie:</h3>
+ <ol class="numbered">
+ <li>
+ <h4 class="step"></h4>
+ Z menu <strong>Narzędzia</strong>, znajdującego się na pasku narzędzi Firefoksa, wybierz <strong>Dodatki</strong>.
+ </li>
+ <li>
+ <h4 class="step"></h4>
+ Za pośrednictwem karty Subskrypcje zaloguj się do swojego konta na witrynie Mozilla Add-ons.
+ </li>
+ <li>
+ <h4 class="step"></h4>
+ Po lewej stronie zobaczysz listę swoich kolekcji. Kliknij dowolną kolekcję, aby zobaczyć jej zawartość. Aby zarządzać tą kolekcją lub wysłać ją znajomemu za pomocą e-maila, kliknij <strong>Dodaj do programu Firefox</strong> lub <strong>Wyślij do</strong>.
+ </li>
+ </ol>
+ <p>Czy jesteś zagorzałym łowcą dodatków, czy kimś, kto używa dodatków tylko po to, aby usprawnić przeglądanie Internetu, Kolekcjoner dodatków jest po to, aby Ci to ułatwić. Aby uzyskać więcej informacji o funkcjach rozszerzenia i zapoznać się z często zadawanymi pytaniami i odpowiedziami na nie, przejdź na <a href="%1$s">stronę funkcji</a> i <a href="%2$s">FAQ</a>.</p>
+ </div><!-- / .primary -->
+
+ <div class="secondary">
+ <div class="highlight">
+ <h4>Rozpocznij z tymi kolekcjami</h4>
+
+ <ul>
+ %3$s
+ </ul>
+
+ <ul class="further-navigation">
+ <li><a href="%4$s" class="more-info">Zobacz więcej kolekcji</a></li>
+ </ul>
+ </div><!-- /. highlight -->
+ </div><!-- /. secondary-->
+
diff --git a/site/app/locale/pl/pages/compatibility_developer_tips.thtml b/site/app/locale/pl/pages/compatibility_developer_tips.thtml
new file mode 100644
index 0000000..f3be420
--- /dev/null
+++ b/site/app/locale/pl/pages/compatibility_developer_tips.thtml
@@ -0,0 +1,6 @@
+<ul class="tips">
+ <li>Informacje o tym, jak zaktualizować swój dodatek do programu %s możesz znaleźć w tym <a href="https://developer.mozilla.org/En/Updating_extensions_for_%s">artykule</a>.</li>
+ <li>Ogólne informacje o zmianach w programie %s znajdziesz w tym <a href="https://developer.mozilla.org/en/%s_for_developers">artykule</a>.</li>
+ <li>Aby mieć bieżące informacje o zmianach, możesz subskrybować <a href="https://addons.mozilla.org/newsletter">biuletyn</a> about:addons i <a href="http://blog.mozilla.com/addons/">blog</a> Mozilla Add-ons.</li>
+ <li>Jeśli Twój dodatek jest przechowywany na witrynie Mozilla Add-ons i nie wymaga zmian kodu, aby zachować kompatybilność, a wymaga tylko podwyższenia wersji (maxVersion), możesz to zrobić bez wysyłania nowego pliku, przechodząc do sekcji <a href="%s">Narzędzia programisty</a> lub poniżej przejrzeć jego status.</li>
+</ul>
diff --git a/site/app/locale/pl/pages/compatibility_user_tips.thtml b/site/app/locale/pl/pages/compatibility_user_tips.thtml
new file mode 100644
index 0000000..e607fde
--- /dev/null
+++ b/site/app/locale/pl/pages/compatibility_user_tips.thtml
@@ -0,0 +1,6 @@
+<ul class="tips">
+ <li>Wiele dodatków obsługuje zmiany w programie %s bez modyfikacji kodu, ale wiele wymaga dodatkowej pracy autorów, aby zapewnić bezproblemową aktualizację. W tym czasie prosimy o zachowanie cierpliwości, ponieważ większość twórców dodatków robi to społecznie, traktując to jako swoje hobby.</li>
+ <li>Mozilla nie zaleca wyłączania sprawdzania kompatybilności dodatków, ponieważ może to spowodować poważne problemy z uruchomieniem programu %s, a nawet utratę danych, jeśli zostanie wymuszone działanie rozszerzenia niekompatybilnego z nową wersją programu %s.</li>
+ <li>Jeśli po uruchomieniu programu %s dotychczas używane rozszerzenie jest teraz niekompatybilne, możesz spróbować sprawdzić na jego stronie domowej lub stronie autora, czy nie ma informacji dotyczących aktualizacji rozszerzenia.</li>
+ <li>Możesz także na witrynie <a href="%s">%s – dodatki</a> poszukać dodatku o podobnym działaniu, który działa z programem %s.</li>
+</ul>
diff --git a/site/app/locale/pl/pages/developer_faq.thtml b/site/app/locale/pl/pages/developer_faq.thtml
new file mode 100644
index 0000000..7186259
--- /dev/null
+++ b/site/app/locale/pl/pages/developer_faq.thtml
@@ -0,0 +1,226 @@
+<h1>Tworzenie dodatków – FAQ</h1>
+
+<h2>Tworzenie dodatku</h2>
+<dl>
+<dt>Jak można stworzyć dodatek?</dt>
+<dd>
+<p>Mozilla udostępnia dokumentację dotyczącą budowy dodatków na stronach Mozilla Developer Center (MDC). Przewodnik <a href="https://developer.mozilla.org/En/Building_an_Extension">Tworzenie rozszerzenia</a> wyjaśnia, jak stworzyć środowisko pracy i dodatek.</p>
+<p>Inne źródła informacji:</p>
+<ul>
+<li><a href="https://developer.mozilla.org/En/Firefox_addons_dev_guide">Podręcznik twórcy dodatków do Firefoksa</a></li>
+<li><a href="http://blog.mozilla.com/addons/2009/01/28/how-to-develop-a-firefox-extension/">Artykuł Roberta Nymana "Jak stworzyć rozszerzenie do Firefoksa"</a></li>
+<li><a href="http://blog.mozilla.com/addons/2009/03/18/video-tutorial-extensions-bootcamp-zero-to-hello-world-in-45-minutes/">Wideo-przewodnik Myka Meleza "Video Tutorial - Extensions Bootcamp: Zero to „Hello World†in 45 Minutes"</a></li>
+</ul>
+</dd>
+
+<dt>Jakie narzędzia są potrzebne, aby stworzyć dodatek?</dt>
+<dd>
+<p>Aby stworzyć dodatek, trzeba mieć zainstalowany program Mozilli, do którego dodatek będzie tworzony, i edytor kodu według uznania twórcy. Dodatki mogą być tworzone dla wszystkich programów Mozilli, ale są przede wszystkim przeznaczone dla:</p>
+<ul>
+<li><a href="http://www.mozilla.com/en-US/firefox/">Firefoksa</a></li>
+<li><a href="http://www.mozillamessaging.com/en-US/thunderbird/">Thunderbirda</a></li>
+<li><a href="http://www.seamonkey-project.org/">SeaMonkey</a></li>
+<li><a href="http://www.mozilla.org/projects/calendar/sunbird/">Sunbirda</a></li>
+</ul>
+<p>Popularne edytory kodu:</p>
+<ul>
+<li><a href="http://www.activestate.com/komodo_edit/">Komodo Edit</a></li>
+<li><a href="http://macromates.com/">TextMate</a></li>
+<li><a href="http://notepad-plus.sourceforge.net/uk/site.htm">Notepad++</a></li>
+<li><a href="http://www.eclipse.org/">Eclipse IDE</a></li>
+</ul>
+<p>Więcej na temat środowiska pracy twórcy dodatków można dowiedzieć się z artykułu <a href="https://developer.mozilla.org/en/Setting_up_extension_development_environment">Określanie środowiska pracy twórcy rozszerzeń</a>, zamieszczonego w MDC.</p>
+</dd>
+
+<dt>Gdzie można znaleźć dokumentację na temat tworzenia dodatków?</dt>
+<dd>Cała dokumentacja Mozilli na temat tworzenia dodatków, włącznie z przewodnikami i interfejsem programowania aplikacji (API – Application Programming Interface), znajduje się na stronach <a href="https://developer.mozilla.org/En">Mozilla Developer Center</a>.</dd>
+
+<dt>Co to jest plik „.xpi�</dt>
+<dd>Rozszerzenia sÄ… spakowane i dystrybuowane w plikach lub paczkach ZIP z rozszerzeniem pliku XPI (wymawianym „zippyâ€).</dd>
+
+<dt>Co to jest XUL?</dt>
+<dd>XUL – rozszerzalny język interfejsu użytkownika (XML User Interface Language) – jest bazującym na języku XML (eXtensible Markup Language) językiem Mozilli, umożliwiającym budowanie bogatych w funkcje programów działających na wielu platformach systemowych. Język ten umożliwia tworzenie różnych elementów interfejsu, takich jak przyciski, menu, paski narzędzi, drzewa itp. Elementy te mogą być używane do tworzenia dodatków modyfikujących interfejs programu, dla którego są tworzone.</dd>
+
+<dt>Co to jest plik „install.rdf†i do czego jest używany?</dt>
+<dd>Plik ten, zwany <a href="https://developer.mozilla.org/en/Install_Manifests">manifestem instalacji</a>, jest używany przez aplikacje XUL, których instalację nadzoruje Menedżer dodatków, do określenia informacji o sposobie instalacji dodatku. Zawiera on metadane identyfikujące dodatek, informacje o twórcach, stronie domowej dodatku, z jakimi programami i wersjami tych programów jest kompatybilny, jak powinien być aktualizowany itp. Jest on w formacie RDF/XML.</dd>
+
+<dt>Co oznacza „maxVersion�</dt>
+<dd>Ten parametr określa maksymalną wersję programu, z którą dodatek współpracuje. Nie należy określać wersji wyższej niż najnowsza, dostępna wersja programu!</dd>
+
+<dt>Czy dodatek może zawierać komponenty binarne?</dt>
+<dd>Tak. Można zastosować <a href="https://developer.mozilla.org/en/XPCOM"> komponenty XPCOM Mozilli</a>. Komponenty XPCOM są używane i zaimplementowane w językach JavaScript, Java, Python oprócz C++.</dd>
+
+<dt>Czy do budowy dodatków można używać bibliotek JavaScript, takich jak jQuery, MooTools?</dt>
+<dd>Tak, jest to możliwe, ale niektóre funkcjonalności, oferowane przez te biblioteki, są dostępne poprzez XPCOM, XUL i JS 1.8. Niemniej autorzy powinni zachować ostrożność, jeśli biblioteki modyfikują podstawowe prototypy obiektów (String.prototype, Date.prototype itp.) lub definiują globalne funkcje (np. funkcję $). Mogą one powodować konflikty z innymi dodatkami – w szczególności, gdy dodatki używają różnych wersji bibliotek. Używając tych bibliotek, autorzy dodatków muszą zachować szczególną ostrożność. Mozilla nie dostarcza dokumentacji dotyczącej używania tych bibliotek do budowy dodatków.</dd>
+
+<dt>Jak można wykonać testy dodatku?</dt>
+<dd>Szczegółowe dane dotyczące testowania dodatków są zawarte w sekcjach <a href="https://developer.mozilla.org/en/Building_an_Extension#Test">Testowanie</a> i <a href="https://developer.mozilla.org/en/Building_an_Extension#Debugging_Extensions">Wykrywanie i usuwanie usterek</a> przewodnika <a href="https://developer.mozilla.org/en/Building_an_Extension">Tworzenie rozszerzenia</a>.</dd>
+
+<dt>Jak można wykonać test kompatybilności z najnowszą wersją programu?</dt>
+<dd>Aby zapewnić kompatybilność dodatku z najnowszÄ… wersjÄ… programu, należy zawsze przeprowadzać testy z najnowszÄ… wersjÄ… oprogramowania. W tym celu należy pobrać i zainstalować dostÄ™pne aktualizacje i dopiero wówczas sprawdzić, czy dodatek dziaÅ‚a poprawnie. Najlepiej jest zastosować procedurÄ™ okreÅ›lonÄ… w przewodniku <a href="https://developer.mozilla.org/en/Building_an_Extension">Tworzenie rozszerzenia</a> w sekcji <a href="https://developer.mozilla.org/en/Building_an_Extension#Test">Testowanie</a>. CzÄ™sto najnowsza wersja programu, z którym współpracuje dodatek, może być wydaniem „betaâ€. Ponieważ te wydania czÄ™sto poddawane sÄ… zmianom architektury, zmiany te mogÄ… mieć wpÅ‚yw na funkcjonowanie dodatku. Autor dodatku powinien bacznie Å›ledzić proces tworzenia nowej wersji programu i dostosować do niej swój dodatek, aby użytkownicy dodatku nie byli negatywnie zaskoczeni po wydaniu nowej wersji programu.</dd>
+
+<dt>Co to jest testowanie wycieków pamięci?</dt>
+<dd>Wycieki pamięci są typowymi błędami w kodzie źródłowym użytym do budowy programu, które pochłaniają pamięć systemową bez prawidłowego jej zwalniania po zakończeniu programu. Test wycieków pozwala ustalić, która część kodu powoduje wycieki pamięci. Ta <a href="https://wiki.mozilla.org/Performance:Leak_Tools">publikacja</a> jest dobrym przewodnikiem, aby znaleźć narzędzia i sposób, który pomoże przeprowadzić testy wycieków pamięci. Na stronach Mozilla wiki znajduje się świetny artykuł na temat, jak <a href="https://wiki.mozilla.org/QA:Home_Page:Firefox_3.0_TestPlan:Leaks:LeakTesting-How-To">testować wycieki pamięci w Firefoksie</a>.</dd>
+
+<dt>Czy dodatek może zawierać wiele wersji językowych?</dt>
+<dd>Tak. Dokładne dane, jak zlokalizować dodatek, znajdują się w przewodniku <a href="https://developer.mozilla.org/en/Building_an_Extension#Localization">Tworzenie rozszerzenia</a>, a także na stronie <a href="https://developer.mozilla.org/en/Localization">Mozilla Developer Center Localization</a>. Także projekt <a href="http://www.babelzilla.org/">BabelZilla</a> jest świetnym źródłem wiedzy o lokalizacji i wolontariacie pomagającym tłumaczyć dodatki.</dd>
+</dl>
+
+<h2>Źródła pomocy</h2>
+<dl>
+<dt>Potrzebuję porady przy tworzeniu dodatku. Gdzie mogę znaleźć pomoc?</dt>
+<dd><p>Mozilla oferuje twórcom rozszerzeń następujące opcje pomocy:</p>
+<ul>
+<li>irc://irc.mozilla.org/
+ <ul>
+ <li>#extdev (pomoc w zakresie tworzenia dodatków)</li>
+ <li>#amo (pomoc w zakresie przechowywania dodatków na witrynie AMO)</li>
+ </ul>
+</li>
+<li><a href="https://lists.mozilla.org/listinfo/dev-extensions">Lista mailingowa</a></li>
+<li><a href="news://news.mozilla.org/mozilla.dev.extensions">Grupy dyskusyjne</a></li>
+<li><a href="http://groups.google.com/group/mozilla.dev.extensions">Grupy dyskusyjne Google</a></li>
+</ul>
+</dd>
+
+<dt>Czy Mozilla oferuje usługi tworzenia dodatków?</dt>
+<dd>Nie.</dd>
+
+<dt>Czy są twórcy, którzy mogą stworzyć dla mnie dodatek?</dt>
+<dd>Tak. Można znaleźć takich twórców za pośrednictwem listy <a href="http://www.mozilla.org/community/developer-forums.html#projectwide-forums">mozilla.jobs</a>, forum <a href="http://forums.mozillazine.org/">mozillaZine</a> lub <a href="http://consultants.mozdev.org/">MozDev</a>. Mozilla nie rekomenduje żadnych twórców.</dd>
+</dl>
+
+<h2>Wsparcie dla dodatków</h2>
+<dl>
+<dt>Czy mogę przechowywać i udostępniać swój dodatek?</dt>
+<dd>Tak. Wielu twórców wybiera ten sposób, jednakże przechowywanie dodatku na witrynie Mozilli AMO (<a href="https://addons.mozilla.org">https://addons.mozilla.org</a>) pozwala go lepiej wyeksponować, ponieważ odwiedza ją bardzo dużo osób. Witryna <a href="http://mozdev.org/">mozdev.org</a> oferuje darmowe przechowywanie projektów dodatków i programów Mozilli, dostarczając ich autorom narzędzi i pomocy w zarządzaniu kodem źródłowym, system kontroli wersji, śledzenia błędów i dokumentację.</dd>
+
+<dt>Czy Mozilla może przechowywać mój dodatek?</dt>
+<dd>Tak. Można przechowywać dodatek na witrynie Mozilli AMO (<a href="https://addons.mozilla.org">https://addons.mozilla.org</a>).</dd>
+
+<dt>Co to jest AMO?</dt>
+<dd>AMO (<a href="https://addons.mozilla.org">https://addons.mozilla.org</a>) jest inkubatorem, który pomaga autorom tworzyć, dystrybuować i wspierać fantastyczne produkty tworzone przez Mozillę. Udostępnia narzędzia i infrastrukturę niezbędną do zarządzania, przechowywania i eksponowania dodatków ogromnej rzeszy użytkowników programów Mozilli.</dd>
+
+<dt>Czy moje dane udostępnione Mozilli są bezpieczne?</dt>
+<dd>Tak. Nasza <a href="https://addons.mozilla.org/en-US/firefox/pages/privacy">Polityka prywatności</a> określa, w jaki sposób Mozilla zarządza powierzonymi jej informacjami.</dd>
+
+<dt>Co to są „Narzędzia programisty†istniejące na witrynie AMO?</dt>
+<dd>Panel „Narzędzi programisty†jest miejscem, gdzie znajdują się narzędzia do zarządzania dodatkami autora. Znajdują się tam funkcje niezbędne do wysłania dodatków na AMO, zarządzania informacjami o dodatku i statystyki recenzji.</dd>
+
+<dt>Czy Mozilla ma określone warunki, jakie powinien spełniać wysyłany dodatek?</dt>
+<dd>Tak. <a href="https://addons.mozilla.org/en-US/firefox/pages/policy">Polityka dodatków</a> Mozilli określa te warunki. Warunki te mogą być zmieniane bez powiadamiania. Ponadto zespół edytorów AMO stosuje <a href="https://wiki.mozilla.org/AMO:Editors/ReviewingGuide">Instrukcję recenzji</a>, aby sprawdzić i zapewnić, że dodatek spełnia określone warunki funkcjonalności i bezpieczeństwa.</dd>
+
+<dt>Jak można wysłać dodatek do zrecenzowania?</dt>
+<dd>Panel narzędzi programisty umożliwia wysyłanie dodatków na AMO i kierowanie ich do recenzji. Aby wysłać dodatek, trzeba być zarejestrowanym użytkownikiem AMO. Przed skierowaniem dodatku do recenzji, należy zapoznać się z <a href="https://wiki.mozilla.org/AMO:Editors/ReviewingGuide">Instrukcją recenzji</a>, aby upewnić się, że dodatek spełnia wytyczne stosowane przez edytorów do oceny dodatków.</dd>
+
+<dt>Jaki system operacyjny wybrać dla dodatku?</dt>
+<dd>Należy wybrać system operacyjny, na którym dodatek pracuje prawidłowo.</dd>
+
+<dt>Jaką kategorię dodatku wybrać?</dt>
+<dd>Wybór kategorii dodatku jest zależny od typu odbiorcy, do jakiego jest skierowany i funkcji dodatku. JeÅ›li nie masz pewnoÅ›ci, do jakiej kategorii przypisać dodatek, wybierz „Różneâ€. Zespół AMO może zmienić kategoriÄ™ dodatku, jeÅ›li uzna, że lepiej pasuje inna kategoria.</dd>
+
+<dt>Co oznacza „nominowanie†dodatku?</dt>
+<dd>Nominowane dodatki, to nowe dodatki, które za pomocą Narzędzi programisty zostały nominowane przez autora do upublicznienia.</dd>
+
+<dt>Czy można określić rodzaj licencji na używanie dodatku?</dt>
+<dd>Tak. Podczas wysyłania dodatku można określić umowę licencyjną. Można także po dodaniu dodatku, z poziomu panelu narzędzi programisty, dodać lub zaktualizować umowę licencyjną.</dd>
+
+<dt>Czy można dołączyć do dodatku własną politykę prywatności?</dt>
+<dd>Tak. Podczas wysyłania dodatku można określić politykę prywatności. Można także po dodaniu dodatku, z poziomu panelu narzędzi programisty, dodać lub zaktualizować politykę prywatności.</dd>
+</dl>
+
+<h2>Proces recenzji dodatków</h2>
+<dl>
+<dt>Dlaczego dodatek musi przejść proces recenzji?</dt>
+<dd>Wszystkie wysłane dodatki, zarówno nowe, jak i zaktualizowane, są recenzowane, aby zapewnić użytkownikom programów Mozilli stabilne i bezpieczne używanie jej produktów. Wszystkie wysłane dodatki są recenzowane z zastosowaniem wytycznych zawartych w <a href="https://wiki.mozilla.org/AMO:Editors/ReviewingGuide">Instrukcji recenzji</a>.</dd>
+
+<dt>Kto recenzuje dodatki?</dt>
+<dd>Dodatki są recenzowane przez edytorów AMO – grupę utalentowanych twórców, którzy na ochotnika pomagają Mozilli, recenzując dodatki, aby zapewnić użytkownikom programów Mozilli stabilne i bezpieczne używanie jej produktów. Kontaktując się z edytorem, zachowaj grzeczność, cierpliwość i szacunek, ponieważ pracują oni ciężko, aby zapewnić prawidłową konfigurację dodatków i sprawdzić, czy spełniają one kryteria zawarte w <a href="https://wiki.mozilla.org/AMO:Editors/ReviewingGuide">Instrukcji recenzji</a>.</dd>
+
+<dt>Co to jest „piaskownica�</dt>
+<dd>Pełne wyjaśnienie, czym jest <a href="https://addons.mozilla.org/en-US/firefox/pages/sandbox">piaskownica AMO</a>, znajduje się <a href="https://addons.mozilla.org/en-US/firefox/pages/sandbox">tutaj</a>.</dd>
+
+<dt>Dlaczego dodatek jest oznaczony jako „eksperymentalny�</dt>
+<dd>Nowe i nominowane dodatki są oznaczone jako „eksperymentalne†do czasu zakończenia procesu recenzowania przez edytorów. Takie oznaczenie zapewnia, że użytkownicy przed zainstalowaniem dodatku są świadomi statusu tego dodatku, który oznacza, że dodatek nie przeszedł jeszcze pełnego procesu recenzji.</dd>
+
+<dt>Jakie kryteria sÄ… stosowane podczas recenzji dodatku?</dt>
+<dd>Zanim dodatek zostanie upubliczniony na AMO, musi przejść proces testowania dodatku przez zespół edytorów, który przebiega zgodnie z kryteriami określonymi w <a href="https://wiki.mozilla.org/AMO:Editors/ReviewingGuide">Instrukcji recenzji</a>. Bardzo ważne jest, aby autorzy dodatku zapoznali się z tymi kryteriami przed skierowaniem dodatku do recenzji i upewnili się, że ich dodatek je spełnia – w znacznym stopniu przyspieszy to proces recenzji.</dd>
+
+<dt>Jak długo trwa proces recenzji dodatku?</dt>
+<dd><p>Nie można określić przybliżonego czasu oczekiwania na recenzję. Wiele czynników ma wpływ na ten czas:</p>
+<ul>
+<li>liczba dodatków skierowanych do recenzji</li>
+<li>stopień skomplikowania kodu dodatku</li>
+<li>liczba ujawnionych problemów</li>
+</ul>
+<p>Właśnie dlatego tak ważne jest, aby autor zapoznał się z <a href="https://wiki.mozilla.org/AMO:Editors/ReviewingGuide">Instrukcją recenzji</a>, by upewnić się, że dodatek jest skonfigurowany zgodnie z oczekiwaniami. Zaleca się także zapoznać z wpisem na blogu <a href="http://blog.mozilla.com/addons/2009/01/14/successfully-getting-your-addon-reviewed/">Successfully Getting your Addon Reviewed</a>, który dostarcza świetnych informacji na temat, jak bezproblemowo przejść przez proces recenzji.</p></dd>
+</dl>
+
+<h2>ZarzÄ…dzanie dodatkiem</h2>
+<dl>
+<dt>Czy można sprawdzić, ile razy dodatek był pobierany?</dt>
+<dd>Panel statystyk znajdujący się w Panelu narzędzi programisty dostarcza informacje, które mogą pomóc określić, ile razy dany dodatek został pobrany od czasu umieszczenia go na witrynie AMO.</dd>
+
+<dt>Czy można sprawdzić, ilu aktywnych użytkowników korzysta z dodatku?</dt>
+<dd>Panel statystyk znajdujący się w Panelu narzędzi programisty dostarcza informacje, które mogą pomóc określić, ilu użytkowników aktywnie używa danego dodatku od czasu umieszczenia go na witrynie AMO.</dd>
+
+<dt>W jaki sposób można wysłać aktualizację dodatku?</dt>
+<dd>Aktualizację dodatku można wysłać z poziomu panelu narzędzi programisty, wybierając opcję „Wyślij nową wersję†i wysłać na AMO nowy plik .xpi dodatku.</dd>
+
+<dt>Czy aktualizacja musi być recenzowana przez edytorów?</dt>
+<dd>To zależy… JeÅ›li np. zostaje zmieniony tylko opis dodatku lub zaktualizowany parametr „maxVersionâ€, aby zapewnić kompatybilność z aktualizacjÄ… programu Mozilli, dodatek nie musi być ponownie recenzowany. JeÅ›li jednak zostaÅ‚ wysÅ‚any nowy zaktualizowany plik, aktualizacja dodatku musi być sprawdzona przez edytora.</dd>
+</dl>
+
+<h2>Status „Polecaneâ€</h2>
+<dl>
+<dt>Co to sÄ… polecane listy?</dt>
+<dd>Polecane listy są ważnym elementem eksponowania odwiedzającym witrynę AMO użytecznych i fascynujących dodatków za pomocą małych, aktywnych list. Pozwala to nam polecać dodatki, które tworzą wyjątkowe lub interesujące ulepszenia programów Mozilli i zwiększają zainteresowanie tysiącami dodatków przechowywanych na AMO. Listy są podzielone na dwie kategorie: Polecane i Polecane kategorie. Formatka jest wyświetlana na stronie głównej AMO i zazwyczaj zawiera 40 polecanych dodatków. Dalej znajduję się listy dodatków polecanych w poszczególnych kategoriach. Jedyną różnicą pomiędzy tymi dwoma listami jest to, że dodatki polecane w kategoriach nie są polecane na stronie głównej. Poza tym na obu listach są dostępne informacje o autorach i ich osiągnięciach.</dd>
+
+<dt>Co to sÄ… polecane dodatki?</dt>
+<dd>Główna strona AMO, tak samo, jak główna strona każdej kategorii, zawiera trzy okienka, które są używane do wyświetlania zestawu polecanych dodatków. Nazwy tych dodatków są pobierane odpowiednio z listy polecanych dodatków i list polecanych dodatków w każdej kategorii. Dodatki te podlegają okresowej rotacji, tak jak opisano to w artykule <a href="https://wiki.mozilla.org/AMO:Editors/Featured_and_Recommended#Featured_Add-Ons">Polecane dodatki – FAQ</a>. Działanie to ma na celu wyeksponowanie polecanych dodatków użytkownikom. Aby zapobiec utracie atrakcyjności, polecane dodatki są regularnie zmieniane.</dd>
+
+<dt>W jaki sposób dodatek może być wyświetlany jako polecany?</dt>
+<dd>Następujący <a href="http://blog.mozilla.com/addons/2009/03/10/the-hows-whys-of-the-amo-recommended-rotation/">wpis na blogu</a> opisuje proces, według którego listy polecanych dodatków są zarządzane.</dd>
+
+<dt>Czy można zapłacić za to, aby dodatek był wyświetlany na liście polecanych dodatków?</dt>
+<dd>Nie.</dd>
+
+<dt>Dlaczego dodatek nie jest już wyświetlany jako polecany?</dt>
+<dd>Następujący <a href="http://blog.mozilla.com/addons/2009/03/10/the-hows-whys-of-the-amo-recommended-rotation/">wpis na blogu</a> opisuje proces, według którego listy polecanych dodatków są zarządzane.</dd>
+</dl>
+
+<h2>Recenzje użytkowników</h2>
+<dl>
+<dt>Jak można odpowiedzieć użytkownikowi, który wystawił dodatkowi negatywną recenzję?</dt>
+<dd><p>Autorzy dodatków mogą odpowiadać na każdą recenzję wystawioną ich dodatkom tak długo, jak są zalogowani na AMO. Ponadto każdy użytkownik może oznaczyć recenzję jako:</p>
+<ul>
+<li>spam lub niecenzuralna treść</li>
+<li>niewłaściwy język/dialogg</li>
+<li>niewłaściwie umieszczona prośba o pomoc lub raport o błędzie</li>
+<li>inny (wyświetla okienko z prośbą o podanie informacji)</li>
+</ul>
+
+<p>Obecnie AMO nie ma mechanizmu do bezpośredniej komunikacji z recenzentem, ale funkcja ta jest badana i rozważana do wprowadzenia jej w przyszłości.</p>
+</dd>
+
+<dt>Czy można prosić, aby negatywna recenzja została usunięta?</dt>
+<dd>Nie. Nie usuwamy z dodatków negatywnych recenzji, nawet jeśli są one nieprawdziwe.</dd>
+
+<dt>Czy można prosić, aby nieścisła recenzja została usunięta?</dt>
+<dd>Jeśli autor skontaktuje się z nami i poprosi o usunięcie nieprawdziwej lub nieścisłej recenzji, sprawdzimy wpis i rozważymy jego usunięcie.</dd>
+</dl>
+
+<h2>Publikacje dotyczące licencji otwartego dostępu do kodu źródłowego</h2>
+<p>Potrzebujesz więcej informacji o licencjach otwartego dostępu do kodu źródłowego programu? Nie wiesz, którą licencję wybrać? Jakich praw udziela dana licencja? Choć nic nie zastąpi zapoznania się z pełnymi postanowieniami licencji, poniżej znajduje się kilka adresów witryn, na których znajdują się informacje o kluczowych licencjach otwartego dostępu do kodu źródłowego, które mogą pomóc poznać różnice pomiędzy nimi. Te witryny stanowią jedynie pomoc i służą jako punkt odniesienia. Zasoby te nie są źródłem porad prawnych ani też nie powinny być używane jako równoważnik takich porad. Mozilla nie gwarantuje ani nie odpowiada za treść znajdującą się na tych witrynach, ani za zaufanie do znajdujących się tam treści, jakim obdarza je czytelnik.</p>
+<dl>
+<dt><a href="http://www.mozilla.org/MPL/">http://www.mozilla.org/MPL/</a></dt>
+<dd>Osobom, które chcą używać i dystrybuować kod na licencji Mozilla Public License (&#8222;MPL&#8221;), witryna ta, oprócz pełnego tekstu licencji, dostarcza wersję MPL z komentarzami i odpowiedzi na często zadawane pytania <abbr title="Frequently Asked Questions">FAQ</abbr>.</dd>
+<dt><a href="http://developer.kde.org/documentation/licensing/licenses_summary.html">http://developer.kde.org/documentation/licensing/licenses_summary.html</a></dt>
+<dd>Na tej witrynie znajduje się tabela podsumowująca i porównująca, jak niektóre kluczowe licencje otwartego dostępu do kodu źródłowego odnoszą się do dystrybucji, odwołań do oprogramowania o kodzie zamkniętym i redystrybucji zmienionego kodu.</dd>
+<dt><a href="http://www.fsf.org/licensing/licenses/">http://www.fsf.org/licensing/licenses/</a></dt>
+<dd>Fundacja Wolnego Oprogramowania (Free Software Foundation) udostępnia krótkie podsumowania kluczowych licencji otwartego dostępu do kodu źródłowego łącznie z tym, czy licencja zalicza się do licencji wolnego oprogramowania, czy jest to licencja niewprowadzająca ograniczeń praw autorskich. Zawiera także dyskusję o tym, co stanowi licencję otwartego dostępu do kodu źródłowego, a co licencję bez ograniczeń praw autorskich – Copyleft (np. czy licencja Copyleft jest ogólną metodą wytworzenia programu lub innego utworu jako wolnego i czy wymaga, aby wszystkie zmodyfikowane i rozbudowane wersje były także wolne od ograniczeń).</dd>
+<dt><a href="http://www.opensource.org/licenses/category">http://www.opensource.org/licenses/category</a></dt>
+<dd>Inicjatywa Otwartego Kodu Źródłowego (Open Source Initiative) udostępnia pełne teksty niektórych kluczowych licencji otwartego dostępu do kodu źródłowego programu.</dd>
+<dt><a href="http://en.wikipedia.org/wiki/Open_source_license">http://en.wikipedia.org/wiki/Open_source_license</a></dt>
+<dd>Dyskusja na Wikipedii o licencjach Open Source Definition (OSD).</dd>
+</dl>
diff --git a/site/app/locale/pl/pages/error404.thtml b/site/app/locale/pl/pages/error404.thtml
new file mode 100644
index 0000000..9855a3b
--- /dev/null
+++ b/site/app/locale/pl/pages/error404.thtml
@@ -0,0 +1,16 @@
+<h1>Przepraszamy, ale nie możemy znaleźć szukanego elementu.</h1>
+
+<p>Żądana strona lub plik nie zostały znalezione na tej witrynie. Możliwe, że został kliknęty nieaktualny odnośnik lub adres został niepoprawnie wprowadzony.</p>
+
+<ul>
+<li>Jeśli adres strony był wprowadzany, proszę dokładnie sprawdzić pisownię.</li>
+<li>Jeśli informacja ta została wyświetlona po kliknięciu odnośnika na jakiejś stronie, prosimy o wysłanie wiadomości do <a href="mailto:webmaster@mozilla.com" title="Page Not Found on Mozilla.com">webmaster@mozilla.com</a> zawierającej informacje, na jakiej stronie nastąpiło kliknięcie i jakie informacje były szukane, a my zrobimy wszystko, by to naprawić.</li>
+</ul>
+
+<p>Można również przejść do którejś z popularnych stron na naszej witrynie.</p>
+
+<ul>
+<li>Interesuje cię <a href="%1$s">spis polecanych dodatków</a>?</li>
+<li>Chcesz <a href="%2$s">poszukać dodatków</a>? Przejdź do <a href="%2$s">strony wyszukiwania</a> lub użyj pola wyszukiwania znajdującego się powyżej.</li>
+<li>Jeśli chcesz zacząć od początku, przejdź do <a href="%3$s">strony głównej dodatków</a>.</li>
+</ul>
diff --git a/site/app/locale/pl/pages/nomination.thtml b/site/app/locale/pl/pages/nomination.thtml
new file mode 100644
index 0000000..5a3d64d
--- /dev/null
+++ b/site/app/locale/pl/pages/nomination.thtml
@@ -0,0 +1,10 @@
+<p>Dodatek, który aktualnie znajduje się w piaskownicy, może być nominowany do upublicznienia i dostępny dla wszystkich użytkowników po poddaniu go ocenie przez edytora. Aby osiągnąć pożądany efekt - publikację dodatku, proszę zapoznać się z poniższymi uwagami:</p>
+<ul>
+ <li>Obrazki poglądowe są wymagane dla motywów i wysoce rekomendowane dla wszystkich innych typów dodatków.</li>
+ <li>Dodatek powinien spędzić wystarczającą ilość czasu w piaskownicy, by zgromadzić opinie i oceny użytkowników. <b>Opinie te są konieczne, aby dodatek mógł być upubliczniony.</b></li>
+ <li>Dodatki dostępne publicznie muszą mieć wyższy poziom jakości niż przebywające w piaskownicy i powinny uatrakcyjniać korzystanie z Internetu.</li>
+ <li>Wszystkie kryteria nominacji są dostępne w naszej <a href="%s">Polityce dodatków.</a></li>
+</ul>
+<p>Jeśli dodatek spełnia powyższe kryteria, można go nominować, naciskając przycisk znajdujący się poniżej. Informacja o statusie nominacji zostanie wysłana e-mailem.</p>
+
+<p>Aby nominować dodatek, proszę opisać, jak był testowany (opis powinien zawierać zapewnienie, że jest on wolny od błędów) i w jaki sposób rozszerza możliwości korzystania z Internetu. Można także dołączyć odnośnik do zewnętrznych opinii o dodatku.</p>
diff --git a/site/app/locale/pl/pages/policy.thtml b/site/app/locale/pl/pages/policy.thtml
new file mode 100644
index 0000000..da5e065
--- /dev/null
+++ b/site/app/locale/pl/pages/policy.thtml
@@ -0,0 +1,229 @@
+<html><head></head><body><h1>Polityka dodatków</h1>
+
+<h2>Czym jest piaskownica?</h2>
+<p>Odpowiedź można znaleźć w dokumencie %s.</p>
+
+<h2>Jakie dodatki znajdujÄ… siÄ™ w piaskownicy?</h2>
+<p>Od piaskownicy zaczynają wszelkie dodatki udostępniane w AMO.
+Znaleźć w niej można nowe wersje publicznych dodatków, jak też
+wszystkie wersje dodatków, które nie zostały jeszcze upublicznione.
+Kiedy nowy dodatek lub aktualizacja istniejącego są wysyłane do AMO,
+umieszczane sÄ… one w piaskownicy.</p>
+
+<p>Niektóre dodatki i ich odpowiednie wersje są upubliczniane po tym,
+jak w wyniku procesu recenzowania zostanÄ… oznaczone jako odpowiednie do
+upublicznienia. Inne dodatki pozostanÄ… w piaskownicy na czas
+nieokreślony; będą tam dostępne dla użytkowników chcących przeglądać
+spis piaskownicy i eksperymentować z oprogramowaniem tam udostępnionym.</p>
+
+<h2>W jaki sposób dodatki są upubliczniane?</h2>
+
+<p>Dodatki są recenzowane przez użytkowników AMO, którzy chcą
+przeglądać piaskownicę i testować pakiety znajdujące się w niej.
+Recenzje napisane przez użytkowników AMO pozwolą określić, czy dany
+dodatek jest dostatecznie użyteczny, prawidłowo napisany i ma
+odpowiednią jakość, by zaprezentować go wszystkim użytkownikom
+Firefoksa. Recenzje te, jak też inne recenzje i inne testy dokonywane
+przez zespół AMO, pomagają określić, czy dany dodatek powinien zostać
+upubliczniony, czy wymaga jeszcze dalszych prac albo czy nie powinien
+być udostępniany na stronie AMO poza piaskownicą.</p>
+
+<h2>W jaki sposób mój dodatek może uzyskać status publiczny?</h2>
+
+<p>Jeśli uważasz, że Twój dodatek (i Twoje zachowanie!) spełnia
+wszystkie kryteria, możesz go nominować z poziomu narzędzi programisty.</p>
+
+<h2>Jakie są kryteria dla upublicznionych dodatków?</h2>
+
+<p>Upubliczniony dodatek musi mieć wysoką jakość i ulepszać
+sposób korzystania z sieci. Przy określaniu, czy dany dodatek powinien
+zostać upubliczniony w AMO, bierzemy pod uwagę następujące kryteria:</p>
+
+<h3>Czy zamierzasz zarządzać swoim dodatkiem?</h3>
+
+<p>Oczekujemy, że autor który prezentuje swoje dodatki użytkownikom
+Firefoksa, jest w stanie odpowiadać na raporty o problemach, zarządzać
+swoim dodatkiem i aktualizować go, aby był zgodny z aktualnym wydaniem Firefoksa i
+zmianami w polityce AMO. Nie oznacza to, że musisz odpowiadać na każde
+pytanie, które ktoś zada na grupie dyskusyjnej, ani, że musisz poprawiać
+każdy zgłoszony błąd, ale oczekujemy od Ciebie, komunikacji i reakcji na
+problemy zgodnie z ich wagą i zagrożeniem jakie stwarzają dla użytkowników.</p>
+
+<h3>Czy dodatek jest jasno i dokładnie opisany?</h3>
+
+<p>Niezwykle ważne jest dla nas, aby użytkownicy dostali zawsze to czego oczekują
+kiedy decydują się zainstalować nowy dodatek. Opis dodatku powinien szczegółowo opisywać
+co dany dodatek robi, jak użytkownik ma z niego korzystać i czego powinien się
+spodziewać po zainstalowaniu go. Nie mamy nic przeciwko, aby w opisie
+znalazły się odnośniki do zewnętrznych instrukcji, ale sam opis musi
+zawierać podstawowe informacje i zapewniać użytkownikom wiedzę, co dostają
+wraz z instalacjÄ… danego dodatku.</p>
+
+<p>Jest także ważne, by aktualizować informacje o wydaniach zgodnie ze
+zmianami i poprawkami jakie wprowadzasz do swojego dodatku. Użytkownicy, którzy
+w przeszłości wypróbowali dany dodatek powinni mieć możliwość zobaczenia,
+co nowego się w nim znalazło i powinni mieć świadomość jak zmiany mogą wpływać na ich sposób
+korzystania z niego. (W tym momencie użytkownicy nie widzą notatek do wydania
+podczas aktualizacji, ale mamy w planie to poprawić. Użytkownicy skorzystają z tego,
+że będziesz zarządzać notatkami do wydania, zarówno teraz jak i po dodaniu notatek do okna aktualizacji).</p>
+
+<h3>Czy wszystkie uwagi dotyczące bezpieczeństwa i prywatności zostały wymienione?</h3>
+
+<p>Jest to element jasnego i poprawnego opisu, ale na tyle ważny, że uznaliśmy iż
+zasługuje na osobny punkt. Wiele bardzo wygodnych i dobrze napisanych dodatków
+manipuluje w jakiejś formie danymi użytkownika albo może wprowadzać ryzyko bezpieczeństwa,
+jeśli będą źle wykorzystywane; takie dodatki mogą znaleźć się w publicznej części AMO,
+ale muszą bardzo dokładnie opisywać użytkownikom ryzyko, jakie wprowadzają oraz informacje
+o tym, jak mogą się przed tym ryzykiem zabezpieczyć.</p>
+
+<h3>Czy dodatek został przetestowany i masz pewność, że nie zawiera oczywistych i poważnych błędów?</h3>
+
+<p>Jednym z istotnych aspektów, na które patrzymy podczas rozpatrywania, czy dodatek
+nadaje się dla użytkowników to kwestia testowania. Sprawdzamy, czy recenzje z piaskownicy
+wskazują, że dodatek przeszedł gruntowne testy i nie posiada poważnych błędów i nie wpływa
+negatywnie na działanie przeglądarki. Jeżeli recenzenci zgłaszają problemy takie jak
+poważne problemy z wydajnością, stabilnością, powtarzające się problemy z używaniem
+funkcji dostarczanych przez dodatek lub zalew informacji w konsoli błędów, autor
+dodatku powinien wziąć je sobie do serca i nominować dodatek ponownie, po poprawieniu
+tych błędów. Nie oczekujemy od nikogo absolutnej optymalizacji, ani uzyskania produktu bez
+jakichkolwiek błędów -- sam Firefox jest cały czas poprawiany -- ale chcemy, aby autor
+poświecił rozsądną ilość czasu i energii, aby zminimalizować potencjalne problemy i
+jasno opisał przypadki, kiedy użytkownicy mogą zostać zaskoczeni tymi, których poprawić się jeszcze
+nie udało.</p>
+
+<p>Jeżeli dodatek był testowany poza procesem piaskownicy AMO,
+jak na przykład przez grupę użytkowników Twojej usługi albo wewnętrzny zespół kontroli jakości,
+powinno to być jasno zaznaczone w wiadomości z nominacją. Znacząco ułatwia
+nam to ustalenie jaki zakres był testów i pomoże przejść przez proces zatwierdzania dodatku.</p>
+
+<h3>Czy dodatek i autor dodatku traktują użytkownika z szacunkiem?</h3>
+
+<p>Oprogramowanie nie powinno niepotrzebnie przeszkadzać użytkownikowi, próbować
+go oszukać, albo ukrywać swoje działania przed nim. Użytkownicy (lub nawet nie-użytkownicy)
+są czasem niekulturalni w swoich komentarzach i mimo, że robimy co w naszej mocy, by odfiltrować takie osoby, oczekujemy od autorów, że powstrzymają się przed reagowaniem na tym samym poziomie.</p>
+
+<h3>Czy dodatek jest przydatny dla odpowiednio dużej grupy użytkowników Firefoksa?</h3>
+
+<p>Dodatek nie musi być następnym Greasemonkey czy FireBugiem, ale jeśli jest przydatny tylko
+dla ludzi w Twojej firmie albo członków jakiejś małej społeczności sieciowej, możemy uznać, że
+nie nadaje się do prezentowania wszystkim użytkownikom Firefoksa.</p>
+
+<p>Cały czas szukamy dróg, które pozwolą nam poprawić stronę w taki sposób, aby
+lepiej rozmieszczać dodatki, które są przydatne w konkretnych przypadkach, ale są przydatne
+tylko dla małej społeczności potencjalnych użytkowników. Prawidłowa
+kategoryzacja i zarządzanie metadanymi dodatku pomoże nam zorientować się,
+jak możemy poukładać tego typu dodatki, aby były widoczne dla osób, które
+najprawdopodobniej będą chciały z nich skorzystać.</p>
+
+<p>Jeżeli dodatek dostarcza zakładki, lub inne ułatwienia dostępu do Twojej
+strony, najprawdopodobniej nie jest to odpowiedni dodatek dla publicznie dostępnej
+części serwisu. Tak jak reszta projektu Mozilla, uwielbiamy aplikacje sieciowe i
+nowe usługi sieciowe, ale dodatki Firefoksa powinny podnosić jakość korzystania z sieci, a nie
+być metodą promocji nowej strony czy serwisu poprzez AMO. Jeżeli opis
+dodatku dotyczy głównie serwisu, a nie usprawnień jakie ten dodatek dostarcza, prawdopodobnie jesteś na niewłaściwej drodze.</p>
+
+<h3>Czy dodatek jest wolny od praw autorskich i nielicencjonowanych znaków handlowych?</h3>
+
+<p>Chociaż możesz nie chcieć w żaden sposób zaszkodzić właścicielowi znaków handlowych lub
+autorowi posiadającemu prawa autorskie, nie możemy publikować żadnych dodatków
+które mogą wchodzić w konflikt z prawem. Jeżeli nie masz zezwoleń na używanie zastrzeżonej nazwy lub grafiki, prosimy, nie wysyłaj swojego dodatku do AMO.
+Jeżeli dodatek zawiera kod, który jest chroniony prawem autorskim przez kogoś innego,
+i nie posiadasz licencji na użycie go w dodatku, prosimy, nie wysyłaj swojego dodatku do AMO.
+(Jeżeli właściciel praw będzie miał zastrzeżenia co do wykorzystania jego własności, bardzo prawdopodobne, że jego zgłoszenie będzie musiało być rozpatrzone przez prawnika i - jeśli będzie to prawnie konieczne - usuniemy dany dodatek. Taki proces jest kosztowny, zarówno w zakresie czasu jak i pieniędzy, więc prosimy, szanuj to i nie dodawaj nam niepotrzebnej pracy).</p>
+
+<p>Jeżeli nie masz pewności czy nazwa dodatku lub jakiś jego element, uniemożliwi mu
+pojawienie się na tej stronie, możesz poprosić o poradę na amo-editors@mozilla.org. WAŻNE: Zwróć uwagę, że ta grupa nie ma możliwości udzielenia porady prawnej i nawet jeśli będziemy czuli,
+że sposób w jaki korzystasz z czyjejś pracy jest legalny, możemy później zmienić naszą
+decyzję w świetle zgłoszeń ze strony właścicieli praw autorskich lub zaleceń prawnych.</p>
+
+<p>W przypadku ponownego wykorzystania źródeł innego dodatku, jeżeli autor
+nie zaznaczył jasno, że można użyć jego kodu w swojej pracy -- na przykład poprzez
+licencjonowanie go na otwartej licencji -- wówczas należy założyć, że nie posiadasz praw
+do tego. Możesz skontaktować się z autorem i poprosić o zezwolenie, ale nie możemy
+dać Ci żadnych specjalnych praw tylko dlatego, że jest on na AMO lub ponieważ autor
+nie odpowiedział na prośbę. (I ponownie - nie możemy udzielić Ci żadnego wsparcia
+prawnego, jedynie radę na temat, jak twój dodatek ma się do reguł tej strony).</p>
+
+<p>Te prawa dotyczą także znaków handlowych Mozilli Foundation, włączając w to znaki takie jak "Mozilla", "Firefox" i "Thunderbird". Polityka ochrony znaków handlowych Mozilli jest tak skonstruowana, aby chronić użytkowników przed pomyłkami i chronić znaki handlowe przed ich złym wykorzystaniem; prosimy, uszanuj taką potrzebę ochrony i pomóż nam ochronić jedne z ważniejszych rzeczy które udało nam się stworzyć w Mozilli Foundation.</p>
+
+<h2>Co siÄ™ dzieje po tym, jak coÅ› nominujÄ™?</h2>
+
+<p>Kiedy dodatek zostanie nominowany, jest on oceniany przez zespół redaktorów AMO, zgodnie z kryteriami opisanymi powyżej. Jeśli dodatek wygląda na gotowy do publicznej prezentacji, zostanie on przeniesiony na stronę publiczną po jego ocenieniu. Otrzymasz wówczas powiadomienie.</p>
+
+<p>Jeśli uznamy, że ten dodatek nie nadaje się do publikacji na AMO, otrzymasz powiadomienie e-mailem z wyszczególnieniem powodów, a nominacja zostanie usunięta z kolejki. Kiedy uznasz, że elementy, które znalazły się w powiadomieniu są już poprawione i zechcesz, aby dodatek został oceniony ponownie, możesz wysłać go do nas jeszcze raz.
+Powtórzone nominacje bez znaczących usprawnień w dodatku nie są mile widziane, więc prosimy, zastanów się przed ponownym wysłaniem, czy na pewno poprawiłeś to, na co zwróciliśmy uwagę; w przeciwnym wypadku prędzej nas zdenerwujesz niż uprosisz.</p>
+
+<h2>Czy mogę nominować cudzy dodatek?</h2>
+
+<p>W tym momencie, prosimy autorów dodatków, aby sami nominowali swoje dodatki do publikacji.
+Chcemy mieć pewność, że autor nie ma nic przeciwko wystawieniu jego dodatku dla większego grona odbiorców w obecnej formie i uważa swój dodatek za wystarczająco na to gotowy. Jeśli uważasz, że dany dodatek jest na to gotowy i jego autor postępuje zgodnie z literą i duchem reguł AMO oraz że ten dodatek usprawnia działanie Firefoksa, jest przydatny dla jego użytkowników i warto wystawić go dla blisko stu milionów użytkowników sieci na świecie, zachęć autora dodatku, aby sam go nominował.</p>
+
+<h2>Mój dodatek został nominowany do kolejki dawno temu, dlaczego mnie tak bardzo nie lubicie?</h2>
+
+<p>Tu nie chodzi o to, że kogoś nie lubimy. Uwielbiamy wszystkich programistów
+dodatków i ciężko pracujemy, by byli zadowoleni i czuli się pożyteczni, po to, aby
+użytkownicy na całym świecie mogli korzystać z ich pracy. Ale to co znajduje się na publicznie
+dostępnej stronie AMO ma swoją wartość właśnie dlatego, że dbamy o to, co się tutaj umieszcza,
+więc nie chcemy pędzić, byle tylko zrobić to szybciej. Zdajemy sobie sprawę z tego, że
+oczekiwanie, aż dodatek zostanie oceniony, może być frustrujące i chcemy utrzymać czas
+wykonania tej pracy na tak krótkim poziomie, jak to tylko możliwe.
+Im więcej ludzi wysyła dokładne i jasne recenzje dodatków w piaskownicy, tym
+łatwiejsze jest dokonywanie tych ocen, dlatego prosimy przemyśleć
+udzielenie nam pomocy na tej stronie.
+</p>
+
+<h2>W moim dodatku został znaleziony poważny błąd i chcę szybko przesłać poprawkę. Co należy zrobić?</h2>
+
+<p>Jeśli to poważny błąd (bezpieczeństwo, stabilność, problem z główną
+funkcjonalnością) w dodatku, dla którego potrzebujesz dostarczyć aktualizację niezwłocznie,
+należy zasygnalizować to w "uwagach dla recenzenta", przy wysyłaniu
+aktualizacji (oczywiście taka informacja powinna znaleźć się również w uwagach o wersji).
+Można także zwerbować któregoś z dostępnych użytkowników, by przetestował aktualizację
+dodatku i zdał szczegółową relację w piaskownicy. Wejście na kanał #addons na
+irc.mozilla.org może pomóc ludziom zorientowanym w temacie, ale prosimy o cierpliwość
+i uprzejmość.</p>
+
+<p>Prosimy, nie podnoś fałszywego alarmu. Spróbujemy przenieść to do aktualizacji
+o wysokim priorytecie, ale ocenienie innych nominowanych dodatków
+lub wersji zajmuje nam trochę czasu i często odbywa się to kosztem snu
+lub czasu przeznaczonego dla naszych rodzin i przyjaciół, więc nie akceptujemy zachowania
+ludzi, którzy próbują wykorzystać ten mechanizm, jako okazję do "wepchnięcia
+się do kolejki". Jeśli nie masz pewności, czy należy wykorzystać tę drogę,
+zapytaj na #addons na irc.mozilla.org, może to pomoże podjąć decyzję.
+</p>
+
+<h2>Uważam, że zostałem potraktowany niesprawiedliwie podczas oceniania mojego dodatku. Co powinienem zrobić?</h2>
+
+<p>Jeśli wierzysz, że dodatek został nieprawidłowo oceniony i że
+nie został udostępniony w wyniku pomyłki, wyślij e-mail na adres
+amo-editors@mozilla.org z dokładnym opisem swojego rozumowania.
+E-mail powinien być spokojny, grzeczny i jasno prezentować Twoje stanowisko oraz zawierać szczegóły, dotyczące błędów w ocenie dodatku.</p>
+
+<p>(Jeśli *wszystkie* elementy wymienione jako problemy zostały poprawione, nie należy wnioskować o ocenę, tylko ponownie nominować dodatek do rozpatrzenia z poziomu narzędzi programisty).</p>
+
+<h2>Mój dodatek był dostępny publicznie, a teraz jest tylko w piaskownicy. Co się stało?</h2>
+
+<p>Jeśli dodatek nie spełnia kryteriów wymaganych do bycia publicznie dostępnym, możemy przenieść
+go z powrotem do piaskownicy. Jeśli tylko nie zostanie nam to prawnie zabronione, poinformujemy Cię o tym e-mailem i podamy powody takiego postępowania.</p>
+
+<p>Jest także możliwe, że dostrzegasz błąd na tej stronie. W takim przypadku
+należy go zgłosić przy użyciu Bugzilli; w swoim raporcie użyj produktu "addons.mozilla.org"
+i komponentu "Public Pages" oraz podaj tyle szczegółów, ile to możliwe.</p>
+
+<h2>Mój dodatek jest upubliczniony i ludzie go uwielbiają. Jak mogę dostać się na listę polecanych dodatków?</h2>
+
+<p>Jeśli wierzysz, że dodatek jest błyszczącym przykładem potęgi dodatków, który
+demonstruje i szerzy wartości Mozilli, dotyczące rozszerzalnego i kontrolowanego przez użytkowników Internetu, i podnosi wygodę korzystania z sieci, możesz poprosić o rozpatrzenie dodania go do listy polecanych dodatków. Aby to zrobić, należy wysłać e-mail na adres
+amo-editors@mozilla.org, tłumacząc dlaczego dodatek jest wspaniały.</p>
+
+<p>E-mail powinien zawierać <b>przynajmniej</b> informacje na następujące tematy:</p>
+<ul>
+<li>jak poprawia się wygoda korzystania z sieci dla użytkowników,</li>
+<li>na ile dodatek nadaje się dla większej grupy użytkowników Firefoksa,</li>
+<li>w jaki sposób dodatek prezentuje i służy wartościom projektu Mozilla, ze szczególnym uwzględnieniem dawania większej kontroli nad siecią użytkownikowi, ochrony jego prywatności i bezpieczeństwa, uniwersalnego dostępu do sieci, otwartych standardów i danych,</li>
+<li>jak dodatek różni się od innych, podobnych dodatków (w jaki sposób jest lepszy, a w jaki gorszy od nich),</li>
+<li>z jaką reakcją dodatek spotkał się ze strony użytkowników, redaktorów, blogerów, astronautów i Twoich zwierzątek domowych - opisz zarówno reakcje pozytywne jak i negatywne</li>
+</ul>
+
+<p>Im bardziej kompletne będzie zgłoszenie, tym większa jest szansa, że umieścimy dodatek na liście. Jednakże, nawet błyskotliwie napisana i wyczerpująco zgłoszone podanie nie jest gwarancją umieszczenia dodatku na liście polecanych. Lista musi być -- i jest -- utrzymywana przez Mozillę zgodnie z naszymi wartościami i przekonaniami, zatem wygoda i ochrona użytkownika jest ważniejsza niż cokolwiek innego.</p>
+</body></html> \ No newline at end of file
diff --git a/site/app/locale/pl/pages/sandbox.thtml b/site/app/locale/pl/pages/sandbox.thtml
new file mode 100644
index 0000000..cc5aedb
--- /dev/null
+++ b/site/app/locale/pl/pages/sandbox.thtml
@@ -0,0 +1,13 @@
+<h1>Piaskownica &ndash; system ocen</h1>
+<h2>Czym jest piaskownica?</h2>
+<p>Piaskownica jest strefą dla zaawansowanych użytkowników, miejscem do testowania i oceny dodatków przed ich upublicznieniem. Aby uzyskać dostęp do piaskownicy, należy założyć na witrynie AMO konto i się zalogować. Należy zachować ostrożność instalując dodatki z piaskownicy. Nie zostały one przetestowane przez edytorów i mogą uszkodzić komputer instalującego.</p>
+
+<h2>Jaka jest droga dodatku do upublicznienia?</h2>
+<!-- To localize the flowchart image, see http://wiki.mozilla.org/Update:Remora_Sandbox_Flowchart -->
+<div style="text-align: center;">%s</div>
+<ol>
+ <li><b>Wysłanie dodatku na AMO.</b> Za pomocą narzędzi programisty należy wysłać dodatek na witrynę AMO. Dodatek ten natychmiast pojawi się w piaskownicy, na stronie Mozilla Add-ons, gdzie doświadczeni użytkownicy wykonają testy i wystawią swoją recenzję.</li>
+ <li><b>Nominowanie dodatku do upublicznienia.</b> W narzędziach programisty znajduje się odnośnik do nominowania dodatku. Po nominowaniu dodatku pojawi się on w kolejce do oceny.</li>
+ <li><b>Ocena przez edytora.</b> Edytor Mozilla Add-ons zainstaluje dodatek i sprawdzi jego działanie. Edytor zapozna się również z recenzjami wystawionymi przez testerów piaskownicy.</li>
+ <li><b>Upublicznienie lub zatrzymanie w piaskownicy.</b> Edytor upublicznia dodatek lub pozostawia go w piaskownicy. Jeśli zostanie zatrzymany w piaskownicy, można nominować go ponownie po wprowadzeniu zmian zasugerowanych przez edytora w komentarzach. Jeśli zostanie upubliczniony, to nowe wersje dodatku będą pojawiać się w piaskownicy do momentu ich ocenienia przez edytora i upublicznienia. Raz upublicznionego dodatku nie ma potrzeby nominować ponownie - nowe wersje automatycznie znajdą się w kolejce oczekujących na ocenę.</li>
+</ol>
diff --git a/site/app/locale/pl/pages/statistics_help.thtml b/site/app/locale/pl/pages/statistics_help.thtml
new file mode 100644
index 0000000..cb20f4d
--- /dev/null
+++ b/site/app/locale/pl/pages/statistics_help.thtml
@@ -0,0 +1,7 @@
+<h3>Pomoc</h3>
+<p>W Panelu statystyk wyświetlane są zgromadzone dane o liczbie pobrań i sprawdzeń dostępności aktualizacji Twojego dodatku.</p>
+<h4>Pobrania</h4>
+<p>Liczba pobrań jest aktualizowana codziennie i zawiera tylko liczbę pobrań dodatku dokonanych po raz pierwszy - nie zawiera liczby pobrań aktualizacji.</p>
+
+<h4>Sprawdzenia dostępności aktualizacji</h4>
+<p>Dodatki pobrane z tej witryny sprawdzajÄ… dostÄ™pność aktualizacji raz dziennie i caÅ‚kowita liczba tych sprawdzeÅ„ jest okreÅ›lana jako „Aktywni dzienni użytkownicyâ€. Statystyki te (ADU) można podzielić wedÅ‚ug: wersji dodatku, programu, statusu dodatku oraz systemu operacyjnego. Te dane sÄ… obecnie zapisywane jednego dnia każdego tygodnia - w Å›rodÄ™.</p>
diff --git a/site/app/locale/pl/pages/submission_help.thtml b/site/app/locale/pl/pages/submission_help.thtml
new file mode 100644
index 0000000..c8238c5
--- /dev/null
+++ b/site/app/locale/pl/pages/submission_help.thtml
@@ -0,0 +1,35 @@
+<h1>Wysyłanie dodatków &ndash; pomoc</h1>
+Pola wymagane sÄ… <b>pogrubione</b>. Pola opcjonalne sÄ… <i>napisane kursywÄ…</i>.
+<h2 id="step1">Krok 1: Wyślij</h2>
+<ul class="submissionHelp">
+ <li><span class="required">Typ dodatku</span> - domyślnie typ dodatku zostanie automatycznie rozpoznany na podstawie wysłanego pliku. Nie należy zmieniać tego pola.</li>
+ <li><span class="required">Plik dodatku</span> - spakowany plik dodatku, zawierający plik install.rdf. Jeśli plik działa tylko na specyficznej platformie, należy wybrać tę platformę, pozwoli to wysłać wiele plików za jednym razem.</li>
+ <li><span class="optional">Plik ikony</span> - plik ikony jest wyświetlany tuż obok nazwy dodatku (na jego stronie) i pokazuje się w oknie instalacji dodatków. Ikona zostanie automatycznie przeskalowana do rozmiaru 32x32 piksele, z zachowaniem właściwych proporcji.</li>
+ <li><span class="required">Domyślna lokalizacja</span> - domyślna lokalizacja (tłumaczenie) dodatku jest jego główną lokalizacją. Jeśli lokalizacja wybrana przez użytkownika jest dla dodatku niedostępna, wybór zostanie cofnięty do domyślnej lokalizacji.</li>
+ <li><span class="optional">Pomijanie przeglądania informacji już dostępnego dodatku</span> - jeśli uaktualniamy dostępny już dodatek, to pole powinno być zaznaczone. Zaznaczenie tego pola spowoduje pominięcie kroku trzeciego, gdzie musisz wprowadzać informacje dotyczące wersji.</li>
+</ul>
+
+<h2 id="step2">Krok 2: Szczegóły dodatku</h2>
+<ul class="submissionHelp">
+ <li><span class="required">Nazwa</span> - nazwa dodatku w domyślnej lokalizacji.</li>
+ <li><span class="required">Autorzy</span> - wszyscy użytkownicy, którzy mają prawa do modyfikacji wymienionego dodatku i którzy będą umieszczeni na wyświetlanej stronie jako autorzy.</li>
+ <li><span class="required">Kategorie</span> - kategorie odpowiednie dla tego dodatku.</li>
+ <li><span class="optional">Strona domowa</span> - witryna dodatku w domyślnej lokalizacji.</li>
+ <li><span class="required">Podsumowanie</span> - krótkie podsumowanie dodatku w domyślnej lokalizacji. Maksymalnie 250 znaków.</li>
+ <li><span class="required">Opis</span> - opis dodatku, w domyślnej lokalizacji.</li>
+ <li><span class="optional">EULA</span> - warunki licencji użytkownika końcowego (ang. <i>The End User License Agreement</i>), które użytkownicy będą musieli zaakceptować przed pobraniem dodatku, napisane w domyślnej lokalizacji</li>
+ <li><span class="optional">Polityka prywatności</span> - polityka prywatności dodatku, w domyślnej lokalizacji.</li>
+ <li><span class="optional">Pozwalaj użytkownikom na oglądanie online kodu źródłowego plików</span> - Zaznaczając to pole pozwalamy użytkownikom przeglądać online kod źródłowy plików dodatku.</li>
+ <li><span class="optional">To jest pre-release</span> - zaznaczenie tego pola będzie sygnalizowało, że dodatek to pre-release (wydanie następujące bezpośrednio przez wydaniem ostatecznym) lub wersja &quot;beta&quot;.</li>
+ <li><span class="optional">To jest dodatek specyficzny dla wybranej strony</span> - zaznaczenie tego pola będzie sygnalizowało, że dodatek jest specjalnie przeznaczony dla pojedynczej witryny.</li>
+ <li><span class="optional">Ten dodatek wymaga zewnętrznego oprogramowania</span> - zaznaczenie tego pola będzie sygnalizowało, że dodatek wymaga zewnętrznego oprogramowania.</li>
+</ul>
+
+<h2 id="step3">Krok 3: Szczegóły wersji</h2>
+<ul class="submissionHelp">
+ <li><span class="required optional">Uwagi dotyczące wersji</span> - podsumowanie lub lista zmian w tej wersji. To jest opcjonalne przy wysyłaniu nowych dodatków, ale wymagane dla uaktualnień.</li>
+ <li><span class="optional">Uwagi dla oceniającego</span> - to pole jest używane do przekazania informacji dla redaktorów, którzy będą oceniali dodatek. Informacje o koncie testowym i specjalne notatki powinny się tutaj znaleźć właśnie tutaj.</li>
+</ul>
+
+<h2 id="step4">Krok 4: Lokalizacja</h2>
+To jest miejsce, gdzie należy podać w jakim zakresie dodatki mogą być na wszystkie wspierane lokalizacje. Po prostu kliknij na lokalizację, by wprowadzić tłumaczenia. \ No newline at end of file
diff --git a/site/app/locale/pt_BR/LC_MESSAGES/messages.mo b/site/app/locale/pt_BR/LC_MESSAGES/messages.mo
new file mode 100644
index 0000000..956331b
--- /dev/null
+++ b/site/app/locale/pt_BR/LC_MESSAGES/messages.mo
Binary files differ
diff --git a/site/app/locale/pt_BR/LC_MESSAGES/messages.po b/site/app/locale/pt_BR/LC_MESSAGES/messages.po
new file mode 100644
index 0000000..a9c748b
--- /dev/null
+++ b/site/app/locale/pt_BR/LC_MESSAGES/messages.po
@@ -0,0 +1,8216 @@
+# Remor Preliminary Language File
+# Copyright (C) 2006 Mozilla Corporation
+# This file is distributed under the same license as the REMORA package.
+# Wil Clouser <clouserw@mozilla.com>, 2006.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: REMORA 0.1\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2009-01-16 11:45-0800\n"
+"PO-Revision-Date: 2008-08-23 HO:MI+ZONE\n"
+"Last-Translator: Filipe Grillo <filipe.grillo@gmail.com> Vinicius Fuentes "
+"<vinibaggio@gmail.com> Marcio Galli <taboca@gmail.com> Gloria Edini "
+"<gedini@taboca.com> \n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=n != 1;\n"
+
+#: views/addons/policy.thtml:98
+msgid "a_cancel_installation"
+msgstr "Cancelar Instalação"
+
+#. This is the text that appears on buttons to download add-ons.
+#. %$1s is an optional string that only appears if the add-on is only available for
+#. a certain platform. Examples: (Windows) or (Linux)
+#. Note that the parentheses are included in the string. :(
+#: views/elements/amo2009/install.thtml:126
+#: views/elements/amo2009/install.thtml:227
+#: views/elements/amo2009/install.thtml:257
+#: views/elements/amo2009/install.thtml:300
+#: views/elements/amo2009/install.thtml:312 views/elements/install.thtml:73
+#: views/elements/install.thtml:181 views/elements/install.thtml:205
+#: views/elements/install.thtml:248 views/elements/install.thtml:260
+#: views/addons/plugins.thtml:66 views/addons/plugins.thtml:76
+#: views/addons/plugins.thtml:86 views/addons/plugins.thtml:96
+#: views/addons/plugins.thtml:119
+#, php-format
+msgid "a_download"
+msgstr "Baixar agora %s"
+
+#: views/addons/policy.thtml:72
+msgid "a_eula_download"
+msgstr "Aceitar e Baixar"
+
+#: views/addons/policy.thtml:74
+msgid "a_eula_install"
+msgstr "Aceitar e Instalar"
+
+#: views/elements/header.thtml:76 views/elements/header.thtml:82
+#: views/api/api_addon.thtml:55 views/api/collections_feed.thtml:75
+#: views/sharing_api/addon.thtml:64
+msgid "a_header_public"
+msgstr "Público"
+
+#: views/elements/header.thtml:58 views/elements/header.thtml:75
+#: views/elements/header.thtml:80 views/api/api_addon.thtml:57
+#: views/api/collections_feed.thtml:77 views/sharing_api/addon.thtml:66
+msgid "a_header_sandbox"
+msgstr "Sandbox"
+
+#. %s is a date in the _('date') format
+#: views/elements/amo2009/homepage_addon.thtml:115
+#: views/elements/addon_listitem.thtml:122 views/elements/feature.thtml:106
+#: views/addons/display.thtml:104 views/addons/browse_thumbs.thtml:73
+msgid "addon_detail_last_updated"
+msgstr "Atualizado em %s"
+
+#. %s is the version of the add-on. Example: 3.2a1
+#: views/elements/amo2009/addon_version_detail.thtml:51
+#: views/elements/addon_version_detail.thtml:51
+#, php-format
+msgid "addon_display_header_version"
+msgstr "Versão %s"
+
+#: views/addons/browse_thumbs.thtml:80
+msgid "addon_downloads"
+msgstr "downloads"
+
+#: views/addons/display.thtml:147
+msgid "addon_downloads_total"
+msgstr "total de downloads"
+
+#: views/elements/amo2009/homepage_addon.thtml:106
+#: views/elements/addon_listitem.thtml:115 views/elements/feature.thtml:101
+#: views/addons/category_landing.thtml:157 views/addons/display.thtml:146
+#: views/addons/browse_thumbs.thtml:80
+msgid "addon_downloads_weekly"
+msgstr "downloads semanais"
+
+#. %1 is the add-on count, %2 the category name
+#: views/addons/browse_thumbs.thtml:104 views/addons/browse.thtml:60
+#, php-format
+msgid "addon_list_category_totalcount"
+msgid_plural "addon_list_category_totalcount"
+msgstr[0] "%1$s Complemento"
+msgstr[1] "%1$s Complementos"
+
+#: views/elements/amo2009/addon_list_options.thtml:103
+#: views/elements/pagination.thtml:67
+#: views/elements/addon_list_options.thtml:94
+msgid "addon_list_perpage"
+msgstr "por página"
+
+#: views/elements/amo2009/addon_list_options.thtml:84
+#: views/elements/addon_list_options.thtml:98
+msgid "addon_list_sortby"
+msgstr "Ordenar por:"
+
+#: views/helpers/addons_html.php:568 views/elements/amo2009/install.thtml:321
+#: views/elements/feature.thtml:89
+msgid "addon_listitem_flag_experimental"
+msgstr "experimental"
+
+#: views/helpers/addons_html.php:570
+msgid "addon_listitem_flag_recommended"
+msgstr "recomendado"
+
+#. %1 is the add-on name, %2 is the platform
+#: views/pages/js_constants.js.thtml:66
+msgid "addon_not_available_for_platform"
+msgstr "%1$s não está disponível para %2$s."
+
+#. %1 is the add-on name
+#: views/addons/policy.thtml:101 views/addons/previews.thtml:60
+#: views/addons/versions.thtml:130 views/reviews/flag.thtml:61
+#: views/reviews/add.thtml:114 views/reviews/display.thtml:216
+#: views/reviews/review_added.thtml:57
+#, php-format
+msgid "addon_review_a_back_to_addon_x"
+msgstr "Voltar à %1$s..."
+
+#. %1 is the add-on name
+#: views/reviews/flag.thtml:60 views/reviews/add.thtml:113
+#: views/reviews/review_added.thtml:56
+#, php-format
+msgid "addon_review_a_back_to_reviews"
+msgstr "Voltar às revisões..."
+
+#: views/reviews/add.thtml:85
+msgid "addon_review_add_rating_field"
+msgstr "Nota:"
+
+#: views/reviews/add.thtml:102
+msgid "addon_review_add_review_field"
+msgstr "Revisão:"
+
+#: views/reviews/add.thtml:107
+msgid "addon_review_add_submit"
+msgstr "Enviar sua revisão"
+
+#. %s is the name of the add-on
+#: views/reviews/add.thtml:51
+#, php-format
+msgid "addon_review_add_title"
+msgstr "Adicionar revisão para %s"
+
+#: views/reviews/add.thtml:78
+msgid "addon_review_add_title_field"
+msgstr "Título/Sumário:"
+
+#: views/reviews/display.thtml:77 views/reviews/display.thtml:161
+msgid "addon_review_admin_delete"
+msgstr "Remover"
+
+#: views/reviews/display.thtml:76
+msgid "addon_review_author_reply_link"
+msgstr "Responder"
+
+#: views/reviews/delete.thtml:62
+msgid "addon_review_confirm_delete"
+msgstr "Você tem certeza de que quer remover esta revisão?"
+
+#: views/reviews/delete.thtml:63
+msgid "addon_review_confirm_no"
+msgstr "Não"
+
+#: views/reviews/delete.thtml:64
+msgid "addon_review_confirm_yes"
+msgstr "Sim"
+
+#: views/reviews/delete.thtml:48
+msgid "addon_review_delete_header"
+msgstr "Remover Revisão"
+
+#: controllers/reviews_controller.php:449
+msgid "addon_review_deleted_successfully"
+msgstr "Revisão removida com sucesso."
+
+#. %s is the name of the add-on
+#: views/reviews/add.thtml:51
+#, php-format
+msgid "addon_review_edit_title"
+msgstr "Editar revisão para %s"
+
+#. %1 is the count of characters entered as notes for the review flag reason.
+#: controllers/reviews_controller.php:539
+msgid "addon_review_flag_error_other_length"
+msgstr ""
+"Problema no reportar da revisão: Estas notas são limitadas de 10 a 100 "
+"caracteres; Sua contagem de caracteres foi de %1$s."
+
+#. Removing an extra comma
+#: views/reviews/review_added.thtml:53
+msgid "addon_review_in_moderation"
+msgstr ""
+"Observação: Antes que sua revisão apareça publicamente, ela será avaliada "
+"por um editor."
+
+#: views/reviews/add.thtml:57
+msgid "addon_review_in_reply_to"
+msgstr "Resposta do desenvolvedor para:"
+
+#. %1 is the review count, %2 is the nickname or full name of the user.
+#: views/reviews/display.thtml:131
+#, php-format
+msgid "addon_review_others_by_user"
+msgid_plural "addon_review_others_by_user"
+msgstr[0] "Veja %1$s revisão anterior enviada por %2$s para este Complemento."
+msgstr[1] ""
+"Veja %1$s revisões anteriores enviadas por %2$s para este Complemento."
+
+#. %1 is the add-on name
+#: controllers/reviews_controller.php:201
+#: controllers/reviews_controller.php:250
+#: controllers/reviews_controller.php:345
+#: controllers/reviews_controller.php:424
+#, php-format
+msgid "addon_review_pagetitle"
+msgstr "Revisões para %s"
+
+#. %1 is the user, %2 is the (localized) date
+#: views/reviews/display.thtml:160
+#, php-format
+msgid "addon_review_reply_on_x_by_y"
+msgstr "Resposta por %1$s em %2$s"
+
+#: views/reviews/display.thtml:157
+msgid "addon_review_reply_prefix"
+msgstr "Resposta do desenvolvedor:"
+
+#: views/reviews/review_added.thtml:51
+msgid "addon_review_saved_successfully"
+msgstr "Sua revisão foi salva com sucesso. Obrigado!"
+
+#: views/addons/display.thtml:354 views/reviews/display.thtml:72
+msgid "addon_reviewed_by_u_on_d"
+msgstr "por %1$s em %2$s"
+
+#. %1 is the user, %2 is the (localized) date, %3 is the rating
+#: views/editors/reviews_queue.thtml:57 views/editors/reviews_queue.thtml:68
+#: views/reviews/add.thtml:63 views/reviews/delete.thtml:54
+#, php-format
+msgid "addon_reviewed_on_x_rated_y"
+msgstr "por %1$s em %2$s (deu nota %3$s)"
+
+#: views/elements/amo2009/addon_version_detail.thtml:52
+#: views/elements/addon_version_detail.thtml:52
+msgid "addon_version_permalink"
+msgstr "A versão mais recente compatível com"
+
+#. %1 is the current Application name (e.g. Firefox)
+#. %2 is the Application's version number
+#: views/addons/versions.thtml:140
+msgid "addon_versions_getlatestversion"
+msgstr "A versão mais recente compatível com %1$s %2$s"
+
+#: views/addons/display.thtml:447
+msgid "addons_author_addons_submit"
+msgstr "Ir"
+
+#: views/elements/amo2009/homepage_addon.thtml:100
+#: views/elements/feature.thtml:95
+msgid "addons_author_tooltip"
+msgstr "Ver o perfil do autor"
+
+#. %1 is the name of the Application (eg. Firefox)
+#: controllers/addons_controller.php:1296
+msgid "addons_browse_all_themes_title"
+msgstr "Navegar em todos os Temas :: %1$s Complementos "
+
+#. %s is the name of the category
+#: controllers/addons_controller.php:1016
+#, php-format
+msgid "addons_browse_browse_category"
+msgstr "Navegar por %s"
+
+#. %1 is the name of the theme category (eg. Modern)
+#. %2 is the name of the Application (eg. Firefox)
+#: controllers/addons_controller.php:664
+msgid "addons_browse_categories_header_theme"
+msgstr "Navegar em Temas %1$s :: Complementos %2$s"
+
+#: views/addons/display.thtml:249
+msgid "addons_display_a_license_what"
+msgstr "O que é isto?"
+
+#: views/reviews/display.thtml:222
+msgid "addons_display_add_review"
+msgstr "Adicionar uma revisão"
+
+#: views/addons/display.thtml:294
+msgid "addons_display_advanced_details"
+msgstr "Detalhes avançados"
+
+#: views/addons/display.thtml:98
+msgid "addons_display_categories"
+msgstr "Categorias"
+
+#: views/addons/display.thtml:482
+#, fuzzy
+msgid "addons_display_collection_add"
+msgstr "Add to a collection:"
+
+#: views/addons/display.thtml:491
+#, fuzzy
+msgid "addons_display_collection_add_new"
+msgstr "New Collection..."
+
+#: views/addons/display.thtml:487
+#, fuzzy
+msgid "addons_display_collection_add_select_one"
+msgstr "Select a collection..."
+
+#: views/addons/display.thtml:493
+#, fuzzy
+msgid "addons_display_collection_add_submit"
+msgstr "Publish"
+
+#. %1$s is the add-on name
+#. %2$s is the collection name, linked to the collection's page
+#: views/pages/js_constants.js.thtml:103 views/addons/display.thtml:61
+#, fuzzy
+msgid "addons_display_collection_publish_success"
+msgstr "%1$s has been added to the %2$s collection."
+
+#: views/addons/display.thtml:483
+#, fuzzy
+msgid "addons_display_collection_whatsthis"
+msgstr "What's this?"
+
+#. %1$s is a number
+#: views/addons/display.thtml:473
+#, fuzzy
+msgid "addons_display_collections_more"
+msgid_plural "addons_display_collections_more"
+msgstr[0] "and %1$s more collection"
+msgstr[1] "and %1$s more collections"
+
+#: views/addons/display.thtml:403
+msgid "addons_display_detailed_review"
+msgstr "revisão detalhada"
+
+#: views/reviews/add.thtml:89 views/reviews/add.thtml:90
+msgid "addons_display_dont_like_it"
+msgstr "Não gosto"
+
+#: views/reviews/display.thtml:220
+msgid "addons_display_edit_review"
+msgstr "Editar sua revisão"
+
+#: views/addons/display.thtml:132
+msgid "addons_display_has_privacy"
+msgstr "Este Complemento tem uma política de privacidade."
+
+#: views/reviews/add.thtml:87 views/reviews/add.thtml:88
+msgid "addons_display_hate_it"
+msgstr "Odeio"
+
+#: views/addons/display.thtml:462
+#, fuzzy
+msgid "addons_display_header_collections"
+msgstr "Related Collections"
+
+#: views/addons/display.thtml:297
+msgid "addons_display_header_developer_comments"
+msgstr "Comentário do(s) desenvolvedor(es)"
+
+#: views/addons/display.thtml:230
+msgid "addons_display_header_homepage"
+msgstr "Página na Web"
+
+#: views/addons/display.thtml:247 views/addons/versions.thtml:110
+msgid "addons_display_header_license"
+msgstr "Source Code License"
+
+#: views/addons/display.thtml:337
+msgid "addons_display_header_reviews"
+msgstr "Revisões"
+
+#: views/addons/display.thtml:261
+msgid "addons_display_header_support"
+msgstr "Suporte"
+
+#: views/reviews/add.thtml:91 views/reviews/add.thtml:92
+msgid "addons_display_like_it"
+msgstr "Gosto"
+
+#: views/addons/display.thtml:210
+msgid "addons_display_long_description"
+msgstr "Descrição longa"
+
+#: views/reviews/add.thtml:95 views/reviews/add.thtml:96
+msgid "addons_display_love_it"
+msgstr "Adoro"
+
+#: views/addons/display.thtml:178
+msgid "addons_display_more_images"
+msgstr "Mais imagens"
+
+#: views/addons/display.thtml:465
+#, fuzzy
+msgid "addons_display_nocollections"
+msgstr "This add-on is not yet in any collections."
+
+#. %1$s is either an author's name or a comma separated list of authors. Using
+#. the list doesn't make sense in the English plural form so we ignore the
+#. variable.
+#: views/addons/display.thtml:436
+msgid "addons_display_other_addons_by"
+msgid_plural "addons_display_other_addons_by"
+msgstr[0] "Outros Complementos de %1$s"
+msgstr[1] "Outros Complementos destes autores"
+
+#. %s is the name of the add-on and the add-on section. Example:
+#. Some Add-on :: Firefox Add-ons
+#. This should not be concatenated in the code and should be fixed.
+#: controllers/addons_controller.php:141 controllers/addons_controller.php:280
+#: controllers/addons_controller.php:1442
+#, php-format
+msgid "addons_display_pagetitle"
+msgstr "%s"
+
+#. %s is an email address
+#: views/addons/display.thtml:286
+#, php-format
+msgid "addons_display_paragraph_supportinfoemail"
+msgstr ""
+"Suporte para este Complemento está disponível em %s. Se você tem um bug, "
+"relate-o, pode ser melhor enviá-lo para o desenvolvedor para que ele possa "
+"acompanhar com você. Revisões não são o melhor lugar para se colocar relatos "
+"de bugs, e o desenvolvedor pode pedir vários detalhes para que consiga "
+"recriar o bug. Uma vez que não tornamos seu email disponível para "
+"desenvolvedores quando você envia uma revisão, eles não poderão entrar em "
+"contato com você para pedir mais detalhes ou avisá-lo se o bug já foi "
+"arrumado em uma versão que será lançada."
+
+#. %$1s is a URL
+#. %$2s is an email address
+#: views/addons/display.thtml:269
+#, php-format
+msgid "addons_display_paragraph_supportinfoemailurl"
+msgstr ""
+"Suporte para este Complemento está disponível em %s ou %s. Se você tem um "
+"bug, relate-o, pode ser melhor enviá-lo para o desenvolvedor para que ele "
+"possa acompanhar com você. Revisões não são o melhor lugar para se colocar "
+"relatos de bugs, e o desenvolvedor pode pedir vários detalhes para que "
+"consiga recriar o bug. Uma vez que não tornamos seu email disponível para "
+"desenvolvedores quando você envia uma revisão, eles não poderão entrar em "
+"contato com você para pedir mais detalhes ou avisá-lo se o bug já foi "
+"arrumado em uma versão que será lançada."
+
+#. %s is a URL
+#: views/addons/display.thtml:278
+#, php-format
+msgid "addons_display_paragraph_supportinfourl"
+msgstr ""
+"Suporte para este Complemento está disponível em %s. Se você tem um bug, "
+"relate-o, pode ser melhor enviá-lo para o desenvolvedor para que ele possa "
+"acompanhar com você. Revisões não são o melhor lugar para se colocar relatos "
+"de bugs, e o desenvolvedor pode pedir vários detalhes para que consiga "
+"recriar o bug. Uma vez que não tornamos seu email disponível para "
+"desenvolvedores quando você envia uma revisão, eles não poderão entrar em "
+"contato com você para pedir mais detalhes ou avisá-lo se o bug já foi "
+"arrumado em uma versão que será lançada."
+
+#: views/addons/display.thtml:383
+msgid "addons_display_rate_it"
+msgstr "Avalie"
+
+#: views/reviews/add.thtml:93 views/reviews/add.thtml:94
+msgid "addons_display_really_like_it"
+msgstr "Gosto muito"
+
+#: views/addons/display.thtml:410
+msgid "addons_display_review_etiquette"
+msgstr ""
+"Por favor, não envie avisos de bugs nas revisões. Nós não tornamos seu "
+"endereço de e-mail disponível para os desenvolvedores dos Complementos e "
+"eles podem precisar entrar em contato para ajudar a resolver o problema."
+
+#. %1 is the review guidelines link
+#: views/addons/display.thtml:417
+msgid "addons_display_review_guidelines_link"
+msgstr "<a href=\"%s\">Guia para revisões</a>"
+
+#. %1 is the support section link
+#: views/addons/display.thtml:414
+msgid "addons_display_review_see_support"
+msgstr ""
+"Veja a <a href=\"%1$s\">seção de suporte</a> para descobrir onde conseguir "
+"ajuda para este Complemento."
+
+#: views/addons/display.thtml:404
+msgid "addons_display_review_submit"
+msgstr "Salvar"
+
+#: views/addons/display.thtml:430
+#, php-format
+msgid "addons_display_see_all_addons"
+msgstr "Ver todos os Complementos em %1$s"
+
+#. %1 is the number of reviews
+#: views/addons/display.thtml:364
+#, php-format
+msgid "addons_display_see_all_reviews"
+msgstr "Ver todas as discussões (%1$s)"
+
+#: views/addons/display.thtml:219
+msgid "addons_display_see_all_versions"
+msgstr "Ver todas as versões"
+
+#: views/addons/display.thtml:321 views/addons/versions.thtml:117
+msgid "addons_display_view_source"
+msgstr "Ver o código-fonte"
+
+#: views/addons/display.thtml:324
+msgid "addons_display_view_stats"
+msgstr "Ver as estatísticas"
+
+#: views/addons/display.thtml:376
+msgid "addons_display_what_do_you_think"
+msgstr "O que você acha?"
+
+#: views/elements/app_compatibility.thtml:49
+msgid "addons_display_workswith"
+msgstr "Funciona em:"
+
+#: views/addons/home.thtml:112
+#, fuzzy
+msgid "addons_home_browse_new"
+msgstr "Just Added"
+
+#: views/addons/home.thtml:110
+#, fuzzy
+msgid "addons_home_browse_popular"
+msgstr "Popular"
+
+#: views/addons/home.thtml:108
+#, fuzzy
+msgid "addons_home_browse_recommended"
+msgstr "Recommended"
+
+#: views/addons/home.thtml:127 views/addons/home.thtml:134
+#: views/addons/home.thtml:141 views/addons/home.thtml:148
+#, fuzzy
+msgid "addons_home_browse_subscribe"
+msgstr "Subscribe"
+
+#: views/addons/home.thtml:101
+#, fuzzy
+msgid "addons_home_browse_title"
+msgstr "Browse Add-ons"
+
+#: views/addons/home.thtml:114
+#, fuzzy
+msgid "addons_home_browse_updated"
+msgstr "Updated"
+
+#: views/elements/amo2009/homepage_addon.thtml:100
+#: views/elements/addon_discussionheader.thtml:83
+#: views/elements/addon_listitem.thtml:109 views/elements/feature.thtml:95
+#: views/addons/category_landing.thtml:66 views/addons/policy.thtml:57
+#: views/addons/display.thtml:70 views/addons/home.thtml:178
+msgid "addons_home_by"
+msgstr "por"
+
+#: views/addons/home.thtml:169
+#, fuzzy
+msgid "addons_home_collection_popular_title"
+msgstr "Popular Collections"
+
+#: views/elements/amo2009/categories.thtml:69 views/addons/home.thtml:160
+#, fuzzy
+msgid "addons_home_collections"
+msgstr "Collections"
+
+#. %1$s is the count of addons in a collection
+#: views/elements/amo2009/collection_listing_item.thtml:51
+#: views/addons/home.thtml:185
+#, fuzzy
+msgid "addons_home_collections_addon_count"
+msgid_plural "addons_home_collections_addon_count"
+msgstr[0] "<strong>%1$s</strong> add-on"
+msgstr[1] "<strong>%1$s</strong> add-ons"
+
+#: views/addons/home.thtml:196
+#, fuzzy
+msgid "addons_home_collections_all"
+msgstr "View All Collections"
+
+#: views/addons/home.thtml:162
+#, fuzzy
+msgid "addons_home_collections_intro"
+msgstr ""
+"Collections are a way for you to categorize, mix, match and mingle add-ons. "
+"Subscribe to collections created by other users or create your own."
+
+#. %1$s is the count of subscribers for a collection
+#: views/elements/amo2009/collection_listing_item.thtml:58
+#: views/collections/detail.thtml:96 views/addons/home.thtml:189
+#, fuzzy
+msgid "addons_home_collections_subscribers"
+msgid_plural "addons_home_collections_subscribers"
+msgstr[0] "<strong>%1$s</strong> subscriber"
+msgstr[1] "<strong>%1$s</strong> subscribers"
+
+#: views/addons/searchengines.thtml:54 views/addons/themes_landing.thtml:49
+msgid "addons_home_feature_head"
+msgstr "Recomendamos"
+
+#: controllers/search_controller.php:218 controllers/addons_controller.php:176
+#: controllers/addons_controller.php:428 controllers/addons_controller.php:671
+#: controllers/addons_controller.php:871
+#: controllers/addons_controller.php:1103
+#: controllers/addons_controller.php:1242
+#: controllers/addons_controller.php:1298
+#, php-format
+msgid "addons_home_header_details"
+msgstr ""
+"O Mozilla Add-ons oferece Complementos que ampliam o %1$s, personalizando a "
+"maneira de como você navega. Dê uma olhada e torne seu %1$s único."
+
+#. %1$s is the HTML collection name link.
+#: views/elements/amo2009/teaser_collections.thtml:107
+#, fuzzy
+msgid "addons_home_introduction_collection_link"
+msgstr "Like these? Find more add-ons in %1$s."
+
+#: views/elements/amo2009/teaser_collections.thtml:60
+#, fuzzy
+msgid "addons_home_introduction_extras"
+msgstr ""
+"<strong>Over 5000 free extras</strong> that let you customize and extend "
+"Firefox to meet your needs."
+
+#: views/elements/amo2009/teaser_collections.thtml:55
+#, fuzzy
+msgid "addons_home_introduction_header"
+msgstr "What are Add-ons?"
+
+#: views/elements/amo2009/teaser_collections.thtml:72
+#, fuzzy
+msgid "addons_home_introduction_install"
+msgstr ""
+"<strong>Easy to install</strong>, get notified when updates are available."
+
+#: views/elements/amo2009/teaser_collections.thtml:45
+#, fuzzy
+msgid "addons_home_introduction_name"
+msgstr "Introduction"
+
+#: views/elements/amo2009/teaser_collections.thtml:66
+#, fuzzy
+msgid "addons_home_introduction_themes"
+msgstr ""
+"Toolbars, themes and search providers that <strong>help you perform common "
+"tasks.</strong>"
+
+#: views/addons/home.thtml:161
+#, fuzzy
+msgid "addons_home_new_indicator"
+msgstr "NEW!"
+
+#: views/elements/app_chooser.thtml:48 views/layouts/amo2009.thtml:257
+msgid "addons_home_other_applications"
+msgstr "Outras aplicações"
+
+#. %1$s is the application the user is browsing. Examples: Thunderbird, Firefox,
+#. Sunbird
+#: views/pages/collector_faq.thtml:49 views/pages/collector_firstrun.thtml:42
+#: views/pages/collector.thtml:46 views/pages/collector_features.thtml:54
+#: controllers/developers_controller.php:87
+#: controllers/compatibility_controller.php:72
+#: controllers/components/simple_acl.php:81 controllers/components/amo.php:607
+#: controllers/statistics_controller.php:60
+#: controllers/statistics_controller.php:240
+#: controllers/previews_controller.php:67 controllers/users_controller.php:90
+#: controllers/users_controller.php:223 controllers/users_controller.php:330
+#: controllers/users_controller.php:414 controllers/users_controller.php:708
+#: controllers/users_controller.php:723 controllers/reviews_controller.php:204
+#: controllers/reviews_controller.php:251
+#: controllers/reviews_controller.php:346
+#: controllers/reviews_controller.php:425
+#: controllers/search_controller.php:185 controllers/search_controller.php:297
+#: controllers/search_controller.php:301 controllers/addons_controller.php:147
+#: controllers/addons_controller.php:280 controllers/addons_controller.php:370
+#: controllers/addons_controller.php:667 controllers/addons_controller.php:874
+#: controllers/addons_controller.php:1019
+#: controllers/addons_controller.php:1034
+#: controllers/addons_controller.php:1101
+#: controllers/addons_controller.php:1121
+#: controllers/addons_controller.php:1240
+#: controllers/addons_controller.php:1357
+#: controllers/addons_controller.php:1364
+#: controllers/addons_controller.php:1442
+#: controllers/addons_controller.php:1477
+#: controllers/addons_controller.php:1538
+#: controllers/addons_controller.php:1543
+#: controllers/editors_controller.php:64 controllers/pages_controller.php:132
+#: controllers/groups_controller.php:65 controllers/groups_controller.php:71
+#: controllers/groups_controller.php:89 controllers/groups_controller.php:111
+#: controllers/collections_controller.php:57
+#: controllers/collections_controller.php:121
+#: controllers/collections_controller.php:205
+#: controllers/collections_controller.php:365
+#: controllers/collections_controller.php:404
+#: controllers/collections_controller.php:466
+#: controllers/collections_controller.php:538
+#: controllers/collections_controller.php:828
+#: controllers/localizers_controller.php:72
+#, php-format
+msgid "addons_home_pagetitle"
+msgstr "Complementos para o %1$s"
+
+#. %1$s is the number of addons downloaded
+#: views/addons/home.thtml:57
+#, fuzzy, php-format
+msgid "addons_home_stats_downloaded"
+msgid_plural "addons_home_stats_downloaded"
+msgstr[0] "<strong>%1$s</strong> <span>add-on downloaded</span>"
+msgstr[1] "<strong>%1$s</strong> <span>add-ons downloaded</span>"
+
+#. %1$s is the number of addons in use
+#: views/addons/home.thtml:63
+#, fuzzy, php-format
+msgid "addons_home_stats_inuse"
+msgid_plural "addons_home_stats_inuse"
+msgstr[0] "<strong>%1$s</strong> <span>add-on in use</span>"
+msgstr[1] "<strong>%1$s</strong> <span>add-ons in use</span>"
+
+#: views/addons/home.thtml:136
+msgid "addons_home_view_all_newest_title"
+msgstr "Ver todos os Complementos criados recentemente"
+
+#: views/addons/home.thtml:129
+msgid "addons_home_view_all_popular_title"
+msgstr "Ver todos os Complementos populares"
+
+#: views/addons/home.thtml:150
+msgid "addons_home_view_all_recommended_title"
+msgstr "Ver todos os Complementos recomendados"
+
+#: views/addons/home.thtml:143
+msgid "addons_home_view_all_updated_title"
+msgstr "Ver todos os Complementos atualizados recentemente"
+
+#: views/elements/amo2009/install.thtml:334 views/elements/install.thtml:112
+msgid "addons_install_in_sunbird"
+msgstr ""
+"<ol><li>Clique no link abaixo para salvar o arquivo.</li><li>No Mozilla "
+"Sunbird, abra os Complementos do Menu de Ferramentas.</li><li>Clique no "
+"botão de Instalação, localize/selecione o arquivo que você fez download "
+"depois clique \"OK\".</li></ol>"
+
+#: views/elements/amo2009/install.thtml:333 views/elements/install.thtml:111
+msgid "addons_install_in_sunbird_title"
+msgstr "Como instalar no Sunbird"
+
+#: views/elements/amo2009/install.thtml:331 views/elements/install.thtml:106
+msgid "addons_install_in_thunderbird"
+msgstr ""
+"<ol><li>Clique com o botão direito no link abaixo e clique em \"Salvar link "
+"como...\" para salvar o arquivo em seu computador.</li><li>No Mozilla "
+"Thunderbird, procure por Complementos no menu Ferramentas.</li><li>Clique no "
+"botão instalar ..., selecione o arquivo que você baixou e clique \"abrir\".</"
+"li></ol>"
+
+#: views/elements/amo2009/install.thtml:330 views/elements/install.thtml:105
+msgid "addons_install_in_thunderbird_title"
+msgstr "Como instalar no Thunderbird"
+
+#: views/elements/amo2009/addon_list_options.thtml:108
+#: views/elements/addon_list_options.thtml:105
+msgid "addons_options_show_experimental"
+msgstr "mostrar Complementos experimentais"
+
+#: views/elements/amo2009/addon_list_options.thtml:113
+#: views/elements/addon_list_options.thtml:109
+msgid "addons_options_submit"
+msgstr "Ir"
+
+#: views/addons/plugins.thtml:63 views/addons/plugins.thtml:73
+#: views/addons/plugins.thtml:83 views/addons/plugins.thtml:93
+#: views/addons/plugins.thtml:103 views/addons/plugins.thtml:116
+#: views/addons/plugins.thtml:126
+msgid "addons_plugins_by"
+msgstr "por"
+
+#: views/addons/plugins.thtml:107
+msgid "addons_plugins_for_linux"
+msgstr "para Linux"
+
+#: views/addons/plugins.thtml:108 views/addons/plugins.thtml:131
+msgid "addons_plugins_for_macosx"
+msgstr "para Mac OS X"
+
+#: views/addons/plugins.thtml:106 views/addons/plugins.thtml:129
+#: views/addons/plugins.thtml:130
+msgid "addons_plugins_for_windows"
+msgstr "para Windows"
+
+#. %1$s is a URL
+#: views/addons/plugins.thtml:139
+#, php-format
+msgid "addons_plugins_looking_for_more"
+msgstr ""
+"Esta página lista apenas alguns plugins mais comuns e mais populares. Para "
+"mais informações sobre outros plugins disponíveis para navegadores baseados "
+"no Mozilla, visite %1$s"
+
+#: views/addons/plugins.thtml:137
+msgid "addons_plugins_looking_for_plugin"
+msgstr "Procurando por um plugin não listado aqui?"
+
+#: views/addons/plugins.thtml:58
+msgid "addons_plugins_main_description"
+msgstr ""
+"Plugins ajudam seu navegador a realizar tarefas específicas, como ver "
+"formatos especiais de imagens ou tocar arquivos multimídia. Plugins são um "
+"pouco diferente de Complementos, que incrementam ou modificam "
+"funcionalidades já existentes."
+
+#. %1$s is the application name. Example: Firefox, Thunderbird, Sunbird
+#: controllers/addons_controller.php:1122
+#, php-format
+msgid "addons_plugins_main_header"
+msgstr "Plugins para %1$s"
+
+#: controllers/components/amo.php:698 controllers/addons_controller.php:1121
+msgid "addons_plugins_pagetitle"
+msgstr "Plugins"
+
+#: views/addons/plugins.thtml:68 views/addons/plugins.thtml:78
+#: views/addons/plugins.thtml:88 views/addons/plugins.thtml:98
+#: views/addons/plugins.thtml:110 views/addons/plugins.thtml:121
+#: views/addons/plugins.thtml:133
+msgid "addons_plugins_support_documentation"
+msgstr "Documentação de suporte: "
+
+#. %s is the name of the add-on
+#: views/addons/policy.thtml:61
+#, php-format
+msgid "addons_policy_eula_require"
+msgstr ""
+"%s necessita que você aceite o seguinte termo de aceitação do usuário antes "
+"que a instalação possa prosseguir:"
+
+#. %1 is the add-on name
+#: controllers/addons_controller.php:1476
+#, php-format
+msgid "addons_previews_pagetitle"
+msgstr "Visualização para %s"
+
+#: views/addons/category_landing.thtml:135
+msgid "addons_recently_added"
+msgstr "Adicionados Recentemente"
+
+#: views/addons/recommended.thtml:51 controllers/addons_controller.php:1365
+msgid "addons_recommended_introduction"
+msgstr ""
+"Com tantos Complementos disponíveis, há alguma coisa para cada um. Para "
+"começar a conhecê-los, segue abaixo uma lista dos Complementos mais "
+"populares. Divirta-se!"
+
+#: controllers/addons_controller.php:1357
+#: controllers/addons_controller.php:1364
+msgid "addons_recommended_pagetitle"
+msgstr "Complementos recomendados"
+
+#: controllers/addons_controller.php:1360
+msgid "addons_recommended_title"
+msgstr "Complementos recomendados"
+
+#: views/addons/searchengines.thtml:136
+msgid "addons_searchengines_additional_resources"
+msgstr "Recursos adicionais"
+
+#. link text devmo
+#: views/addons/searchengines.thtml:141
+msgid "addons_searchengines_devmo_link"
+msgstr "Centro do Desenvolvedor Mozilla"
+
+#: views/pages/js_constants.js.thtml:67
+msgid "addons_searchengines_error_mozilla_browser_required"
+msgstr ""
+"Desculpe-nos, mas você precisa de um navegador baseado no Mozilla (como o "
+"Firefox) para instalar um mecanismo de pesquisa. "
+
+#: views/addons/searchengines.thtml:49
+msgid "addons_searchengines_error_nojavascript"
+msgstr ""
+"É necessário ter JavaScript ativado para instalar plugins, mas parece que "
+"você o desativou. Por favor, ative-o antes de tentar instalar qualquer um "
+"dos mecanismos de pesquisa abaixo."
+
+#. %1 is "make your own" link
+#. %2 is MDC link
+#: views/addons/searchengines.thtml:139
+msgid "addons_searchengines_learn_howto"
+msgstr "Aprenda como %1$s no %2$s."
+
+#. link path to search plugins instructions, relative to devmo
+#: views/addons/searchengines.thtml:140
+msgid "addons_searchengines_makeyourown_href"
+msgstr "/en/docs/Creating_OpenSearch_plugins_for_Firefox"
+
+#. link text for "make your own" (opensearch engine)
+#: views/addons/searchengines.thtml:140
+msgid "addons_searchengines_makeyourown_link"
+msgstr "criar o seu"
+
+#. %1 is the link to mycroft.mozdev.org
+#: views/addons/searchengines.thtml:138
+msgid "addons_searchengines_more"
+msgstr "Navegue por mais mecanismos de pesquisa em %1$s"
+
+#. link text to mycroft.mozdev.org
+#: views/addons/searchengines.thtml:138
+msgid "addons_searchengines_mycroft_link"
+msgstr "mycroft.mozdev.org"
+
+#: controllers/addons_controller.php:1100
+#: controllers/addons_controller.php:1110
+msgid "addons_searchengines_pagetitle"
+msgstr "Mecanismos de pesquisa"
+
+#: views/addons/searchengines.thtml:143
+msgid "addons_searchengines_thanks"
+msgstr ""
+"Agradecimentos especiais ao projeto Mycroft pelo seu trabalho nos mecanismos "
+"de pesquisa do Firefox."
+
+#: views/addons/display.thtml:154
+msgid "addons_share_button_text"
+msgstr "Compartilhar este"
+
+#: controllers/addons_controller.php:89
+msgid "addons_share_label_delicious"
+msgstr "Adicionar ao Delicious"
+
+#: controllers/addons_controller.php:77
+msgid "addons_share_label_digg"
+msgstr "Enviar ao Digg!"
+
+#: controllers/addons_controller.php:83
+msgid "addons_share_label_facebook"
+msgstr "Compartilhar no Facebook"
+
+#: controllers/addons_controller.php:101
+msgid "addons_share_label_friendfeed"
+msgstr "Compartilhar no FriendFeed"
+
+#: controllers/addons_controller.php:95
+msgid "addons_share_label_myspace"
+msgstr "Compartilhar no MySpace"
+
+#: controllers/components/amo.php:201 controllers/components/amo.php:229
+msgid "addons_status_disabled"
+msgstr "Desabilitado"
+
+#: controllers/components/amo.php:191 controllers/components/amo.php:224
+msgid "addons_status_incomplete"
+msgstr "Versão Incompleta"
+
+#: controllers/components/amo.php:197 controllers/components/amo.php:227
+msgid "addons_status_nominated"
+msgstr "Na Sandbox; Nominado para Publicação"
+
+#: views/pages/js_constants.js.thtml:80 controllers/components/amo.php:195
+#: controllers/components/amo.php:226
+msgid "addons_status_pending"
+msgstr "Na Sandbox; Com revisão pendente"
+
+#: views/pages/js_constants.js.thtml:78 controllers/components/amo.php:199
+#: controllers/components/amo.php:228
+msgid "addons_status_public"
+msgstr "Público"
+
+#: views/pages/js_constants.js.thtml:79 controllers/components/amo.php:193
+#: controllers/components/amo.php:225
+msgid "addons_status_sandbox"
+msgstr "Na Sandbox"
+
+#: controllers/components/amo.php:203
+msgid "addons_status_unknown"
+msgstr "Desconhecido"
+
+#: views/elements/amo2009/teaser_collections.thtml:91
+#: views/elements/amo2009/homepage_addon.thtml:99
+#: views/elements/feature.thtml:94
+msgid "addons_title_tooltip"
+msgstr "Saiba mais sobre este Complemento"
+
+#: views/addons/category_landing.thtml:151
+msgid "addons_top_downloads"
+msgstr "Mais Baixados"
+
+#: views/addons/category_landing.thtml:165
+msgid "addons_top_rated"
+msgstr "Mais Votados"
+
+#: views/addons/versions.thtml:62
+msgid "addons_versions_careful"
+msgstr "Tome cuidado com versões antigas"
+
+#: views/addons/versions.thtml:63
+msgid "addons_versions_careful_introduction"
+msgstr ""
+"Estas versões são exibidas para referência e teste. Você deve sempre usar as "
+"versões mais novas para um Complemento."
+
+#: controllers/addons_controller.php:1549
+msgid "addons_versions_history"
+msgstr "Histórico de versões com changelogs."
+
+#. %1$s is the add-on name
+#: controllers/addons_controller.php:1535
+#, php-format
+msgid "addons_versions_pagetitle"
+msgstr "Histórico de versões do %1$s"
+
+#: controllers/groups_controller.php:71
+msgid "admin_group_add_pagetitle"
+msgstr "Adicionar grupo"
+
+#: controllers/groups_controller.php:111
+msgid "admin_group_delete_pagetitle"
+msgstr "Remover grupo"
+
+#. %s is a number to identify the group
+#: controllers/groups_controller.php:117
+#, php-format
+msgid "admin_group_deleted"
+msgstr "O grupo com id %s foi removido"
+
+#: controllers/groups_controller.php:89
+msgid "admin_group_edit_pagetitle"
+msgstr "Editar grupo"
+
+#: controllers/groups_controller.php:92 controllers/groups_controller.php:113
+msgid "admin_group_error_invalid_id"
+msgstr "Id inválido para grupo"
+
+#: controllers/groups_controller.php:65
+msgid "admin_group_pagetitle"
+msgstr "Admin do grupo"
+
+#: controllers/groups_controller.php:77 controllers/groups_controller.php:99
+msgid "admin_group_saved"
+msgstr "O grupo foi salvo"
+
+#: views/elements/amo2009/search.thtml:257 views/elements/search.thtml:239
+msgid "advanced_search_form"
+msgstr "Busca avançada"
+
+#: views/elements/amo2009/search.thtml:126 views/elements/search.thtml:125
+msgid "advanced_search_form_any_time"
+msgstr "Qualquer data"
+
+#: views/elements/amo2009/search.thtml:97
+#: views/elements/amo2009/search.thtml:110 views/elements/search.thtml:96
+#: views/elements/search.thtml:109
+msgid "advanced_search_form_any_type"
+msgstr "Todos"
+
+#: views/elements/amo2009/search.thtml:275 views/elements/search.thtml:254
+msgid "advanced_search_form_any_version"
+msgstr "Todas"
+
+#: views/elements/amo2009/search.thtml:217 views/elements/search.thtml:212
+msgid "advanced_search_form_application"
+msgstr "Aplicação"
+
+#: views/elements/amo2009/search.thtml:143 views/elements/search.thtml:142
+msgid "advanced_search_form_keyword_match"
+msgstr "Coincidência por palavra"
+
+#: views/elements/amo2009/search.thtml:251 views/elements/search.thtml:225
+msgid "advanced_search_form_lastupdate"
+msgstr "Última atualização"
+
+#: views/elements/amo2009/search.thtml:145 views/elements/search.thtml:144
+msgid "advanced_search_form_name"
+msgstr "Nome"
+
+#: views/elements/amo2009/search.thtml:144 views/elements/search.thtml:143
+msgid "advanced_search_form_newest"
+msgstr "Mais novos"
+
+#: views/elements/amo2009/search.thtml:130 views/elements/search.thtml:129
+msgid "advanced_search_form_past_3_months"
+msgstr "Últimos 3 meses"
+
+#: views/elements/amo2009/search.thtml:131 views/elements/search.thtml:130
+msgid "advanced_search_form_past_6_months"
+msgstr "Últimos 6 meses"
+
+#: views/elements/amo2009/search.thtml:127 views/elements/search.thtml:126
+msgid "advanced_search_form_past_day"
+msgstr "Dia anterior"
+
+#: views/elements/amo2009/search.thtml:129 views/elements/search.thtml:128
+msgid "advanced_search_form_past_month"
+msgstr "Último mês"
+
+#: views/elements/amo2009/search.thtml:128 views/elements/search.thtml:127
+msgid "advanced_search_form_past_week"
+msgstr "Semana passada"
+
+#: views/elements/amo2009/search.thtml:132 views/elements/search.thtml:131
+msgid "advanced_search_form_past_year"
+msgstr "Último ano"
+
+#: views/elements/amo2009/search.thtml:239 views/elements/search.thtml:230
+msgid "advanced_search_form_perpage"
+msgstr "Por página"
+
+#: views/elements/amo2009/search.thtml:243 views/elements/search.thtml:224
+msgid "advanced_search_form_platform"
+msgstr "Plataforma"
+
+#: views/elements/amo2009/search.thtml:147 views/elements/search.thtml:146
+msgid "advanced_search_form_popularity"
+msgstr "Popularidade"
+
+#: views/elements/amo2009/search.thtml:146 views/elements/search.thtml:145
+msgid "advanced_search_form_rating"
+msgstr "Avaliação"
+
+#: views/elements/amo2009/search.thtml:247 views/elements/search.thtml:231
+msgid "advanced_search_form_sortby"
+msgstr "Ordenar por"
+
+#: views/elements/amo2009/search.thtml:227 views/elements/search.thtml:216
+msgid "advanced_search_form_to"
+msgstr "até"
+
+#: views/elements/amo2009/search.thtml:257 views/elements/search.thtml:237
+msgid "advanced_search_form_toggle_tooltip"
+msgstr "Mostrar o modo de busca avançada"
+
+#: views/elements/amo2009/search.thtml:235 views/elements/search.thtml:223
+msgid "advanced_search_form_type"
+msgstr "Tipo"
+
+#: views/elements/amo2009/search.thtml:222 views/elements/search.thtml:214
+msgid "advanced_search_form_version"
+msgstr "versão"
+
+#: views/elements/amo2009/pagination.thtml:42
+#, fuzzy
+msgid "amo2009_pagination_next_page"
+msgstr "Next"
+
+#: views/elements/amo2009/pagination.thtml:41
+#, fuzzy
+msgid "amo2009_pagination_previous_page"
+msgstr "Prev"
+
+#: views/pages/js_constants.js.thtml:96
+msgid "app_compat_ignore_check"
+msgstr "Ignorar verificação de versão"
+
+#: views/pages/js_constants.js.thtml:72
+msgid "app_compat_older_firefox_only"
+msgstr "Este Complemento é para versões mais antigas do Firefox"
+
+#. %1$s and %2$s are URLs
+#: views/pages/js_constants.js.thtml:74
+msgid "app_compat_older_version_or_ignore_check"
+msgstr ""
+"Voçê pode <a href=\"%1$s\">tentar uma versão anterior</a> ou <a href=\"#\" "
+"onclick=\"%2$s\">ignorar esta checagem</a>"
+
+#. %1$s is a URL
+#: views/pages/js_constants.js.thtml:71
+msgid "app_compat_try_old_version"
+msgstr "Uma <a href=\"%1$s\">versão mais antiga</a> pode funcionar"
+
+#. %1$s is a URL
+#. %2$s is a version number. Example: 3.1
+#: views/pages/js_constants.js.thtml:73
+msgid "app_compat_unreleased_version"
+msgstr ""
+"Este Complemento depende do <a href=\"%1$s\">Firefox %2$s</a> que ainda não "
+"foi lançado"
+
+#: views/pages/js_constants.js.thtml:70
+msgid "app_compat_update_firefox"
+msgstr ""
+"<a href=\"http://getfirefox.com\">Atualize o Firefox</a> para utilizar este "
+"Complemento"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#. %3$s is a status, like Public.
+#: controllers/components/audit.php:79
+msgid "audit_addon_status"
+msgstr "%1$s mudou o status de %2$s para %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:221
+msgid "audit_admin_default"
+msgstr "%1$s definiu ação de admin %2$s para ID %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:153
+msgid "audit_admin_feature_remove"
+msgstr "%1$s removeu recurso %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is an application, like Firefox.
+#: controllers/components/audit.php:92
+msgid "audit_application_create"
+msgstr "%1$s criou aplicação %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is an application, like Firefox.
+#: controllers/components/audit.php:95
+msgid "audit_application_edit"
+msgstr "%1$s editou aplicação %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a version number, like 3.5.
+#. %3$s is an application, like Firefox.
+#: controllers/components/audit.php:105
+msgid "audit_appversion_create"
+msgstr "%1$s criou versão %2$s para %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a version number, like 3.5.
+#. %3$s is an application, like Firefox.
+#: controllers/components/audit.php:108
+msgid "audit_appversion_delete"
+msgstr "%1$s removeu versão %2$s para %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a config field, like "awesomeness".
+#. %3$s is a config value, like "off".
+#. %4$s is a config value, like "on".
+#: controllers/components/audit.php:210
+msgid "audit_config"
+msgstr "%1$s mudou configuração '%2$s' de '%3$s' para '%4$s'"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:258
+msgid "audit_editor_default"
+msgstr "%1$s definiu ação de editor desconhecida %2$s para ID %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#: controllers/components/audit.php:236
+msgid "audit_editor_feature_remove"
+msgstr "%1$s removeu Complemento %2$s da lista de recomendados"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#: controllers/components/audit.php:231
+msgid "audit_feature_add"
+msgstr "%1$s adicionou o Complemento %2$s para a lista de recomendados"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:149
+msgid "audit_feature_edit"
+msgstr "%1$s mudou um recurso para o locale %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#: controllers/components/audit.php:241
+msgid "audit_feature_locale_change"
+msgstr "%1$s mudou locales do Complemento %2$s na lista de recomendados"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:83
+msgid "audit_file_recalchash"
+msgstr "%1$s recalculou a hash para arquivo %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>user name</a>
+#. %3$s is <a>group name</a>
+#: controllers/components/audit.php:182
+msgid "audit_group_addmember"
+msgstr "%1$s adicionou %2$s ao grupo %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:313
+msgid "audit_group_associated"
+msgstr "%1$s se associou ao grupo %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:162
+msgid "audit_group_create"
+msgstr "%1s criou grupo %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:170
+msgid "audit_group_delete"
+msgstr "%1$s apagou grupo %2$s (ID %3$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:165
+msgid "audit_group_edit"
+msgstr "%1$s editou grupo %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>user name</a>
+#. %3$s is <a>group name</a>
+#: controllers/components/audit.php:188
+msgid "audit_group_removemember"
+msgstr "%1$s removeu %2$s do grupo %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:280
+msgid "audit_l10n_default"
+msgstr "%1$s definiu ação desconhecida %2$s para %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:295
+msgid "audit_modify_locked_group"
+msgstr "%1$s tentou modificar grupo bloqueado %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:299
+msgid "audit_modify_other_locale"
+msgstr "%1$s tentou modificar traduções em %2$s sem permissão"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a platform, like <a>Windows</a>
+#: controllers/components/audit.php:135
+msgid "audit_platform_create"
+msgstr "%1$s criou plataforma %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a platform, like <a>Windows</a>
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:143
+msgid "audit_platform_delete"
+msgstr "%1$s apagou plataforma %2$s (ID %3$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a platform, like <a>Windows</a>
+#: controllers/components/audit.php:138
+msgid "audit_platform_edit"
+msgstr "%1$s editou plataforma %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a part of the admin, like 'Site Config'
+#: controllers/components/audit.php:288
+msgid "audit_reauthentication_failure"
+msgstr "%1$s failed to re-authenticate to access %2$s."
+
+#. %1$s is <a>user name</a>
+#. %2$s is the name of a canned response, like 'Ready for the public'
+#: controllers/components/audit.php:198
+msgid "audit_response_create"
+msgstr "%1$s created response %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is the name of a canned response, like 'Ready for the public'
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:206
+msgid "audit_response_delete"
+msgstr "%1$s deleted response %2$s (ID %3$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is the name of a canned response, like 'Ready for the public'
+#: controllers/components/audit.php:201
+msgid "audit_response_edit"
+msgstr "%1$s edited response %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:245
+msgid "audit_review_approve"
+msgstr "%1$s approved review %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:250 controllers/components/audit.php:253
+msgid "audit_review_delete"
+msgstr "%1$s deleted review %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:303
+msgid "audit_security_default"
+msgstr "%1$s committed unknown security action %2$s to ID %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a category name, like <a>Search Tools</a>
+#: controllers/components/audit.php:118
+msgid "audit_tag_create"
+msgstr "%1$s created tag %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a category name, like <a>Search Tools</a>
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:126
+msgid "audit_tag_delete"
+msgstr "%1$s deleted category %2$s (ID %3$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a category name, like <a>Search Tools</a>
+#: controllers/components/audit.php:121
+msgid "audit_tag_edit"
+msgstr "%1$s edited category %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:266
+msgid "audit_update_applications"
+msgstr "%1$s updated application translations for %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:277
+msgid "audit_update_blog"
+msgstr "%1$s updated blog post translations for %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:274
+msgid "audit_update_platforms"
+msgstr "%1$s updated platform translations for %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:270
+msgid "audit_update_tags"
+msgstr "%1$s updated category translations for %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>user name</a>
+#: controllers/components/audit.php:217
+msgid "audit_user_edit"
+msgstr "%1$s edited %2$s's user information"
+
+#: controllers/addons_controller.php:1012
+msgid "browse_addons_name"
+msgstr "Complementos por nome"
+
+#: controllers/addons_controller.php:1010
+msgid "browse_addons_newest"
+msgstr "Complementos mais novos"
+
+#: controllers/addons_controller.php:1008
+msgid "browse_addons_popular"
+msgstr "Complementos populares"
+
+#: controllers/addons_controller.php:1011
+msgid "browse_addons_rated"
+msgstr "Complementos por avaliação"
+
+#: controllers/addons_controller.php:1009
+msgid "browse_addons_updated"
+msgstr "Complementos atualizados recentemente"
+
+#: views/elements/categories.thtml:73 views/elements/categories.thtml:82
+msgid "categories_current_title"
+msgstr "Categoria atual"
+
+#: views/elements/categories.thtml:50
+#: views/elements/amo2009/categories.thtml:43
+#: views/elements/amo2009/categories.thtml:45
+msgid "categories_header"
+msgstr "Categorias"
+
+#: views/elements/categories.thtml:50
+#: views/elements/amo2009/categories.thtml:41
+msgid "categories_header_title"
+msgstr "Escolha a categoria"
+
+#. %1$s is the category name
+#: views/addons/searchengines.thtml:129
+#, php-format
+msgid "category_extra_see_all"
+msgstr "Ver todos em %1$s"
+
+#. %1$s is a number.
+#: models/collection.php:130
+#, fuzzy
+msgid "collection_description_limit"
+msgstr "The description should be less than %1$s characters."
+
+#. %1$s is the name of the collection
+#: controllers/collections_controller.php:392
+#, fuzzy
+msgid "collection_detail_rss_title"
+msgstr "%s Collection"
+
+#: controllers/collections_controller.php:1065
+#, fuzzy
+msgid "collection_error_deleting_addon"
+msgstr "Error deleting add-on!"
+
+#: controllers/collections_controller.php:1051
+#, fuzzy
+msgid "collection_error_saving_addon"
+msgstr "Error saving add-on!"
+
+#: controllers/collections_controller.php:1080
+#, fuzzy
+msgid "collection_error_saving_comment"
+msgstr "Error saving comment!"
+
+#. %1$s is a number.
+#: models/collection.php:122
+#, fuzzy
+msgid "collection_name_limit"
+msgstr "The name should be less than %1$s characters."
+
+#: controllers/collections_controller.php:352
+#: controllers/collections_controller.php:487
+msgid "collection_not_found"
+msgstr "Coleção não encontrada!"
+
+#. %1$s is the text on the "create collection" button
+#: views/collections/add.thtml:91
+#, fuzzy
+msgid "collections_add_formfield_addons_description"
+msgstr ""
+"If you already know which add-ons you want to add to your collection, just "
+"start typing their names below. If you'd rather wait and do this later, just "
+"click %1$s now."
+
+#: views/collections/add.thtml:90
+#, fuzzy
+msgid "collections_add_formfield_firstaddons"
+msgstr "Choose your first add-ons"
+
+#: views/collections/add.thtml:48
+#, fuzzy
+msgid "collections_add_header"
+msgstr "Create a Collection"
+
+#: views/collections/add.thtml:97
+#, fuzzy
+msgid "collections_add_header_selectedaddons"
+msgstr "Selected Add-ons"
+
+#: views/collections/add.thtml:50
+#, fuzzy
+msgid "collections_add_intro"
+msgstr ""
+"It's easy to create your own collection of add-ons by filling in a few "
+"fields below."
+
+#: views/collections/add.thtml:92 views/collections/add.thtml:103
+#, fuzzy
+msgid "collections_add_submit"
+msgstr "Create Collection"
+
+#: views/pages/collector_faq.thtml:50 views/pages/collector_firstrun.thtml:43
+#: views/pages/collector.thtml:47 views/pages/collector_features.thtml:55
+#: controllers/search_controller.php:302
+#: controllers/collections_controller.php:206
+#: controllers/collections_controller.php:405
+#: controllers/collections_controller.php:467
+#: controllers/collections_controller.php:539
+#, fuzzy
+msgid "collections_breadcrumb"
+msgstr "Collections"
+
+#: views/collections/detail.thtml:185
+#, fuzzy
+msgid "collections_detail_a_learn"
+msgstr "Learn More"
+
+#: views/elements/amo2009/collection_add_form.thtml:53
+#: views/elements/amo2009/collections_js_init.thtml:68
+#: views/pages/collector_firstrun.thtml:64
+#, fuzzy
+msgid "collections_detail_button_add"
+msgstr "Add to Favorites"
+
+#: views/elements/amo2009/collection_add_form.thtml:50
+#: views/elements/amo2009/collections_js_init.thtml:71
+#, fuzzy
+msgid "collections_detail_button_remove"
+msgstr "Remove from Favorites"
+
+#. %1$s is a URL.
+#. %2$s is a full <a href>.
+#: views/collections/detail.thtml:62
+#, fuzzy
+msgid "collections_detail_created_desc"
+msgstr ""
+"<p>You can view your new collection below. If you'd like to set a collection "
+"nickname, upload an icon, or change additional settings, please visit the <a "
+"href='%1$s'>Manage Collections</a> page.</p><p>Your collection can be "
+"accessed at this location: %2$s</p>"
+
+#: views/collections/detail.thtml:61
+#, fuzzy
+msgid "collections_detail_created_msg"
+msgstr "Your collection is now ready!"
+
+#: views/collections/detail.thtml:109
+#, fuzzy
+msgid "collections_detail_header_about"
+msgstr "About This Collection"
+
+#. %1$s is a number.
+#: views/collections/detail.thtml:126
+#, fuzzy
+msgid "collections_detail_header_count"
+msgid_plural "collections_detail_header_count"
+msgstr[0] "%1$s Add-on in this Collection"
+msgstr[1] "%1$s Add-ons in this Collection"
+
+#: views/collections/detail.thtml:113
+#, fuzzy
+msgid "collections_detail_info_created"
+msgstr "<strong>Created by:</strong> %1$s"
+
+#: views/collections/detail.thtml:117
+#, fuzzy
+msgid "collections_detail_info_updated"
+msgstr "<strong>Updated:</strong>"
+
+#: views/elements/amo2009/collections_js_init.thtml:62
+#, fuzzy
+msgid "collections_detail_js_adding"
+msgstr "Adding to Favorites&hellip;"
+
+#: views/elements/amo2009/collections_js_init.thtml:65
+#, fuzzy
+msgid "collections_detail_js_removing"
+msgstr "Removing Favorite&hellip;"
+
+#. %1$s is a URL
+#: views/collections/detail.thtml:90
+#, fuzzy
+msgid "collections_detail_login"
+msgstr "<a href=\"%1$s\">Log in</a> to add this collection to your favorites."
+
+#: views/collections/detail.thtml:104
+#, fuzzy
+msgid "collections_detail_manage"
+msgstr "Manage Collection"
+
+#: controllers/collections_controller.php:298
+#, fuzzy
+msgid "collections_detail_sort_date"
+msgstr "Date Added"
+
+#: controllers/collections_controller.php:299
+#, fuzzy
+msgid "collections_detail_sort_name"
+msgstr "Name"
+
+#: controllers/collections_controller.php:300
+#, fuzzy
+msgid "collections_detail_sort_popularity"
+msgstr "Popularity"
+
+#. %1$s is a number.
+#: views/collections/detail.thtml:166
+#, fuzzy
+msgid "collections_detail_weekly_downloads"
+msgid_plural "collections_detail_weekly_downloads"
+msgstr[0] "%1$s download this week"
+msgstr[1] "%1$s downloads this week"
+
+#: views/collections/edit.thtml:255
+#, fuzzy
+msgid "collections_edit_addons_delete_noscript"
+msgstr "Selected add-ons will be removed upon Save"
+
+#: views/collections/edit.thtml:247
+#, fuzzy
+msgid "collections_edit_addons_description"
+msgstr ""
+"To publish new add-ons to this collection, start typing their names below."
+
+#: views/collections/edit.thtml:248
+#, fuzzy
+msgid "collections_edit_addons_description_noscript"
+msgstr ""
+"To publish new add-ons to this collection, enter a comma-separated list of "
+"Add-on IDs below."
+
+#: views/collections/edit.thtml:247 views/collections/edit.thtml:248
+#, fuzzy
+msgid "collections_edit_addons_description_publish_detailspage"
+msgstr "You can also publish an add-on from its normal listing page."
+
+#. %1$s is the date the add-on was added to the collection
+#. %1$s is the name of the user who added the add-on to the collection
+#: views/collections/edit.thtml:260
+#, fuzzy
+msgid "collections_edit_addons_listitem_added"
+msgstr "Added %1$s by %2$s"
+
+#: views/collections/edit.thtml:263
+#, fuzzy
+msgid "collections_edit_addons_listitem_comment_add"
+msgstr "Add publisher comment"
+
+#: views/collections/edit.thtml:266
+#, fuzzy
+msgid "collections_edit_addons_listitem_comment_delete"
+msgstr "Delete publisher comment"
+
+#: views/collections/edit.thtml:265
+#, fuzzy
+msgid "collections_edit_addons_listitem_comment_edit"
+msgstr "Edit publisher comment"
+
+#: views/collections/edit.thtml:271
+#, fuzzy
+msgid "collections_edit_addons_listitem_comment_note"
+msgstr ""
+"Note: Comment will appear as though written by original publisher on the "
+"original publication date"
+
+#: views/collections/edit.thtml:270
+#, fuzzy
+msgid "collections_edit_addons_listitem_comment_submit"
+msgstr "Save Comment"
+
+#: views/collections/edit.thtml:261
+#, fuzzy
+msgid "collections_edit_addons_listitem_remove"
+msgstr "Remove"
+
+#: views/collections/edit.thtml:250
+#, fuzzy
+msgid "collections_edit_addons_submit"
+msgstr "Add to Collection"
+
+#: views/collections/edit.thtml:153
+#, fuzzy
+msgid "collections_edit_check_nickname"
+msgstr "Check Availability"
+
+#: views/collections/edit.thtml:299
+#, fuzzy
+msgid "collections_edit_confirm_deletecollection"
+msgstr "Yes, I would like to delete this collection."
+
+#. %1$s is the label of the edit form's submit button
+#: views/collections/edit.thtml:300
+#, fuzzy
+msgid "collections_edit_confirm_deletecollection_description"
+msgstr "Check the box, then click on \"%1$s\" to delete this collection."
+
+#. %1$s is the "delete" submit button text
+#. %2$s is the title of the "advanced" tab
+#: views/collections/edit.thtml:95
+#, fuzzy
+msgid "collections_edit_delete_upon_submit"
+msgstr ""
+"Upon clicking \"%1$s\" below, your collection will be deleted. If you do not "
+"want to delete your collection, uncheck the confirmation box in the \"%2$s\" "
+"tab and continue editing your collection. If you leave this page without "
+"saving, your collection will also not be deleted."
+
+#: views/collections/edit.thtml:94
+#, fuzzy
+msgid "collections_edit_delete_warning"
+msgstr "Your collection is about to be deleted!"
+
+#: views/collections/add.thtml:76 views/collections/edit.thtml:144
+#, fuzzy
+msgid "collections_edit_form_error_description"
+msgstr "You must provide a description of your collection."
+
+#: views/collections/edit.thtml:181
+#, fuzzy
+msgid "collections_edit_form_error_icon"
+msgstr "There was an error uploading your icon."
+
+#: views/collections/add.thtml:69 views/collections/edit.thtml:130
+#, fuzzy
+msgid "collections_edit_form_error_name"
+msgstr "You must give your collection a name."
+
+#: views/collections/edit.thtml:158
+#, fuzzy
+msgid "collections_edit_form_error_nickname"
+msgstr "If you choose a nickname, it must be unique."
+
+#: views/collections/add.thtml:93 views/collections/edit.thtml:249
+#, fuzzy
+msgid "collections_edit_formfield_addons"
+msgstr "Add-on name:"
+
+#: views/collections/edit.thtml:281
+#, fuzzy
+msgid "collections_edit_formfield_application"
+msgstr "Associated Application"
+
+#: views/collections/edit.thtml:282
+#, fuzzy
+msgid "collections_edit_formfield_application_description"
+msgstr "Select the application that your collection supports."
+
+#: views/collections/edit.thtml:288
+#, fuzzy
+msgid "collections_edit_formfield_collectiontype"
+msgstr "Collection Type"
+
+#: views/collections/edit.thtml:295
+#, fuzzy
+msgid "collections_edit_formfield_deletecollection"
+msgstr "Delete Collection"
+
+#: views/collections/edit.thtml:296
+#, fuzzy
+msgid "collections_edit_formfield_deletecollection_description"
+msgstr "Deleting your collection will permanently erase it."
+
+#: views/collections/add.thtml:73 views/collections/edit.thtml:140
+#, fuzzy
+msgid "collections_edit_formfield_description"
+msgstr "Collection Description"
+
+#: views/collections/add.thtml:74 views/collections/edit.thtml:141
+#, fuzzy
+msgid "collections_edit_formfield_description_description"
+msgstr "Briefly describe your collection and the kind of add-ons in it"
+
+#: views/collections/edit.thtml:162
+#, fuzzy
+msgid "collections_edit_formfield_icon"
+msgstr "Icon"
+
+#: views/collections/edit.thtml:163
+#, fuzzy
+msgid "collections_edit_formfield_icon_description"
+msgstr ""
+"You can upload a JPG, GIF or PNG icon that will be resized to 32x32 pixels."
+
+#: views/collections/add.thtml:80 views/collections/edit.thtml:189
+#, fuzzy
+msgid "collections_edit_formfield_listed"
+msgstr "Who can view your collection?"
+
+#: views/collections/add.thtml:81 views/collections/edit.thtml:190
+#, fuzzy
+msgid "collections_edit_formfield_listed_description"
+msgstr ""
+"By default, collections appear in the public Collection Directory and are "
+"discoverable by anyone. If you want to restrict your collection to be "
+"viewable only by people who are given a special link, choose that option "
+"below."
+
+#: views/collections/add.thtml:84 views/collections/edit.thtml:193
+#, fuzzy
+msgid "collections_edit_formfield_listed_false"
+msgstr "Only people I invite can view my collection"
+
+#: views/collections/add.thtml:83 views/collections/edit.thtml:192
+#, fuzzy
+msgid "collections_edit_formfield_listed_true"
+msgstr "Everyone can view my collection in the directory"
+
+#: views/collections/edit.thtml:223
+#, fuzzy
+msgid "collections_edit_formfield_managers"
+msgstr "Who can manage my collection?"
+
+#: views/collections/edit.thtml:224
+#, fuzzy
+msgid "collections_edit_formfield_managers_description"
+msgstr ""
+"These users can publish add-ons to your collection, manage all add-ons and "
+"settings, and grant other users permission."
+
+#: views/collections/add.thtml:66 views/collections/edit.thtml:126
+#, fuzzy
+msgid "collections_edit_formfield_name"
+msgstr "Collection Name"
+
+#: views/collections/add.thtml:67 views/collections/edit.thtml:127
+#, fuzzy
+msgid "collections_edit_formfield_name_description"
+msgstr ""
+"Give your collection a descriptive name, such as \"Dave's Favorite Travel "
+"Add-ons\""
+
+#: views/collections/edit.thtml:148
+#, fuzzy
+msgid "collections_edit_formfield_nickname"
+msgstr "Collection Nickname"
+
+#: views/collections/edit.thtml:149
+#, fuzzy
+msgid "collections_edit_formfield_nickname_description"
+msgstr "Optionally, give your collection a unique nickname for quick access:"
+
+#: views/collections/edit.thtml:201
+#, fuzzy
+msgid "collections_edit_formfield_publishers"
+msgstr "Who can publish add-ons to your collection?"
+
+#: views/collections/edit.thtml:202
+#, fuzzy
+msgid "collections_edit_formfield_publishers_description"
+msgstr ""
+"These users can publish add-ons to your collection and remove add-ons that "
+"they publish."
+
+#: views/collections/edit.thtml:210 views/collections/edit.thtml:232
+#, fuzzy
+msgid "collections_edit_formfield_users_add"
+msgstr "Enter the e-mail address of a Firefox Add-ons account:"
+
+#: views/collections/edit.thtml:216 views/collections/edit.thtml:238
+#, fuzzy
+msgid "collections_edit_formfield_users_delete_noscript"
+msgstr "Selected accounts will be removed upon Save"
+
+#: views/collections/edit.thtml:215 views/collections/edit.thtml:237
+#, fuzzy
+msgid "collections_edit_formfield_users_new_noscript"
+msgstr ""
+"Enter a comma-separated list of e-mail addresses of Firefox Add-ons accounts"
+
+#: views/collections/edit.thtml:204 views/collections/edit.thtml:226
+#, fuzzy
+msgid "collections_edit_formfield_users_onlyme"
+msgstr "Only me"
+
+#: views/collections/edit.thtml:205 views/collections/edit.thtml:227
+#, fuzzy
+msgid "collections_edit_formfield_users_otherusers"
+msgstr "Myself and these users:"
+
+#: views/collections/edit.thtml:211 views/collections/edit.thtml:233
+#, fuzzy
+msgid "collections_edit_formfield_users_submit"
+msgstr "Add"
+
+#. %1$s is the name of the collection
+#: views/collections/edit.thtml:68
+#, fuzzy
+msgid "collections_edit_header"
+msgstr "Manage %1$s"
+
+#: views/collections/edit.thtml:246
+#, fuzzy
+msgid "collections_edit_header_addons"
+msgstr "Manage Collection Contents"
+
+#: views/collections/edit.thtml:253 views/collections/edit.thtml:258
+#, fuzzy
+msgid "collections_edit_header_addons_current"
+msgstr "Current Add-ons:"
+
+#: views/collections/edit.thtml:279
+#, fuzzy
+msgid "collections_edit_header_advanced"
+msgstr "Advanced Settings"
+
+#: views/collections/edit.thtml:186
+#, fuzzy
+msgid "collections_edit_header_permissions"
+msgstr "Manage Collection Permissions"
+
+#: views/collections/edit.thtml:170
+#, fuzzy
+msgid "collections_edit_icon_cancel"
+msgstr "Cancel"
+
+#: views/collections/edit.thtml:174 views/collections/edit.thtml:179
+#, fuzzy
+msgid "collections_edit_icon_delete"
+msgstr "Delete Icon"
+
+#: views/collections/edit.thtml:178
+#, fuzzy
+msgid "collections_edit_icon_replace"
+msgstr "Replace Icon"
+
+#. %1$s is the label of the edit form's submit button
+#: views/collections/edit.thtml:169
+#, fuzzy
+msgid "collections_edit_icon_toberemoved"
+msgstr "Icon will be removed when \"%1$s\" is clicked below"
+
+#: views/collections/edit.thtml:155
+#, fuzzy
+msgid "collections_edit_nickname_available"
+msgstr "Nickname Available"
+
+#: controllers/collections_controller.php:943
+#, fuzzy
+msgid "collections_edit_nickname_error"
+msgstr ""
+"Your nickname contained invalid characters and was corrected. Please try "
+"again."
+
+#: views/collections/edit.thtml:156
+#, fuzzy
+msgid "collections_edit_nickname_taken"
+msgstr "Nickname Taken"
+
+#. This string is followed by a URL pointing to the collection's view page
+#: views/collections/edit.thtml:75
+#, fuzzy
+msgid "collections_edit_saved_nextstep"
+msgstr "Your collection can be accessed at this location:"
+
+#: views/collections/edit.thtml:74
+#, fuzzy
+msgid "collections_edit_saved_success"
+msgstr "Your collection was successfully saved!"
+
+#: views/collections/edit.thtml:169 views/collections/edit.thtml:300
+#: views/collections/edit.thtml:308 views/pages/js_constants.js.thtml:99
+#, fuzzy
+msgid "collections_edit_submit"
+msgstr "Update Collection"
+
+#: views/collections/edit.thtml:96 views/collections/edit.thtml:297
+#: views/pages/js_constants.js.thtml:100
+#, fuzzy
+msgid "collections_edit_submit_deletecollection"
+msgstr "Delete Collection"
+
+#: views/collections/edit.thtml:111
+#, fuzzy
+msgid "collections_edit_tabheader_addons"
+msgstr "Add-ons"
+
+#: views/collections/edit.thtml:97 views/collections/edit.thtml:113
+#, fuzzy
+msgid "collections_edit_tabheader_advanced"
+msgstr "Advanced"
+
+#: views/collections/edit.thtml:108
+#, fuzzy
+msgid "collections_edit_tabheader_details"
+msgstr "Name &amp; Details"
+
+#: views/collections/edit.thtml:109
+#, fuzzy
+msgid "collections_edit_tabheader_permissions"
+msgstr "Permissions"
+
+#: models/collection_promo.php:53
+#, fuzzy
+msgid "collections_family_tagline"
+msgstr "Add-ons can keep an eye on your kids and your calendar."
+
+#: models/collection_promo.php:53
+#, fuzzy
+msgid "collections_family_title"
+msgstr "Family Organizer"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:70
+#, fuzzy
+msgid "collections_index_a_check_out"
+msgstr "Check out Add-on Collector"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:52
+#, fuzzy
+msgid "collections_index_a_create"
+msgstr "Create a Collection"
+
+#: views/collections/detail.thtml:139 views/collections/listing.thtml:85
+#: views/search/collections.thtml:84
+#, fuzzy
+msgid "collections_index_button_go"
+msgstr "Go"
+
+#. %1$s is a URL.
+#: controllers/collections_controller.php:182
+#, fuzzy
+msgid "collections_index_filler_favorites"
+msgstr ""
+"<p><strong>You don't have any favorite collections yet.</strong></p> "
+"<p>Collections you mark as favorites can be quickly accessed from this page, "
+"and will appear in the <a href='%1$s'>Add-on Collector</a> if you've "
+"installed it.</p>"
+
+#. %1$s is a URL.
+#: controllers/collections_controller.php:167
+#, fuzzy
+msgid "collections_index_filler_mine"
+msgstr ""
+"<p>You haven't created any collections yet. Collections are easy to create "
+"and fill with your favorite add-ons. <a href='%1$s'>Try it out</a>!</p>"
+
+#: views/collections/listing.thtml:51
+#, fuzzy
+msgid "collections_index_header_collections"
+msgstr "Collections"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:60
+#, fuzzy
+msgid "collections_index_header_collector"
+msgstr "Add-on Collector"
+
+#. %1$s is a comma-separated list of author names
+#: views/elements/amo2009/collection_listing_item.thtml:84
+#: views/collections/detail.thtml:151
+#, fuzzy
+msgid "collections_index_header_created"
+msgstr "created by %1$s"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:47
+#, fuzzy
+msgid "collections_index_header_what"
+msgstr "What are Collections?"
+
+#: views/collections/detail.thtml:132 views/collections/listing.thtml:78
+#: views/search/collections.thtml:66
+#, fuzzy
+msgid "collections_index_label_sortby"
+msgstr "Sort by"
+
+#: controllers/collections_controller.php:130
+#, fuzzy
+msgid "collections_index_li_editors"
+msgstr "Editor's Picks"
+
+#: views/collections/subscribe.thtml:64
+#: controllers/collections_controller.php:140
+#, fuzzy
+msgid "collections_index_li_favorites"
+msgstr "My Favorites"
+
+#: controllers/collections_controller.php:138
+#, fuzzy
+msgid "collections_index_li_mine"
+msgstr "My Collections"
+
+#: controllers/collections_controller.php:132
+#, fuzzy
+msgid "collections_index_li_popular"
+msgstr "Popular"
+
+#: views/search/collections.thtml:74 controllers/collections_controller.php:81
+#, fuzzy
+msgid "collections_index_option_all"
+msgstr "Most popular all time"
+
+#: views/search/collections.thtml:72 controllers/collections_controller.php:78
+#, fuzzy
+msgid "collections_index_option_month"
+msgstr "Most popular this month"
+
+#: views/search/collections.thtml:76 controllers/collections_controller.php:84
+#, fuzzy
+msgid "collections_index_option_newest"
+msgstr "Newest"
+
+#: views/search/collections.thtml:70 controllers/collections_controller.php:75
+#, fuzzy
+msgid "collections_index_option_week"
+msgstr "Most popular this week"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:67
+#, fuzzy
+msgid "collections_index_p_collector"
+msgstr ""
+"There's a new way to manage and find favorite add-ons. Comment, share and "
+"sync collections, all from your browser"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:48
+#, fuzzy
+msgid "collections_index_p_what_are"
+msgstr "Collections are groups of related add-ons assembled for easy sharing."
+
+#. %s is a date in the _('date') format
+#: views/elements/collections_interactive_addon.thtml:85
+#, php-format
+msgid "collections_interactive_addon_added"
+msgstr "Adicionado %s"
+
+#: models/collection_promo.php:55
+#, fuzzy
+msgid "collections_reference_tagline"
+msgstr "Add-ons can do better research online."
+
+#: models/collection_promo.php:55
+#, fuzzy
+msgid "collections_reference_title"
+msgstr "Reference Desk"
+
+#: models/collection_promo.php:52
+#, fuzzy
+msgid "collections_social_tagline"
+msgstr "Add-ons can manage your social network."
+
+#: models/collection_promo.php:52
+#, fuzzy
+msgid "collections_social_title"
+msgstr "Social Circuit"
+
+#: views/collections/subscribe.thtml:91
+#, fuzzy
+msgid "collections_subscribe_button_close"
+msgstr "Close"
+
+#: views/collections/subscribe.thtml:70
+#, fuzzy
+msgid "collections_subscribe_error"
+msgstr ""
+"An error occurred trying to add a favorite collection. Is this collection "
+"already a favorite?"
+
+#: views/collections/subscribe.thtml:96
+#, fuzzy
+msgid "collections_subscribe_label_bothersome"
+msgstr "Don't show me this message again."
+
+#. %1$s is the collection name
+#: views/collections/subscribe.thtml:60
+#, fuzzy
+msgid "collections_subscribe_success"
+msgstr "%1$s has been added to your favorite collections."
+
+#. %1$s is the link to the "My Favorites" tab on the main collections page
+#. %2$s is the localized title of the "My Favorites" tab
+#. %3$s is the link URL to the collector add-on
+#: views/collections/subscribe.thtml:62
+#, fuzzy
+msgid "collections_subscribe_success_desc"
+msgstr ""
+"You can now quickly find this collection from the <a href=\"%1$s\">%2$s</a> "
+"tab in the directory. For an even easier way to keep track of your favorite "
+"collections, try out our <a href=\"%3$s\">Add-on Collector</a> extension for "
+"Firefox."
+
+#: views/collections/listing.thtml:55
+#, fuzzy
+msgid "collections_success_delete"
+msgstr "The collection has been deleted."
+
+#: models/collection_promo.php:54
+#, fuzzy
+msgid "collections_travel_tagline"
+msgstr "Add-ons can turn you into a travel agent."
+
+#: models/collection_promo.php:54
+#, fuzzy
+msgid "collections_travel_title"
+msgstr "The Traveler's Pack"
+
+#. A collection of add-ons that is automatically built for a user. They are "automatically published" to this collection.
+#: controllers/collections_controller.php:581
+#, fuzzy
+msgid "collections_type_autopublisher"
+msgstr "Auto-publisher"
+
+#. A collection that has been chosen by an Editor as notable or exceptional
+#: controllers/collections_controller.php:582
+#, fuzzy
+msgid "collections_type_editorspick"
+msgstr "Editor's Pick"
+
+#: controllers/collections_controller.php:580
+#, fuzzy
+msgid "collections_type_normal"
+msgstr "Normal"
+
+#: views/collections/subscribe.thtml:84
+#, fuzzy
+msgid "collections_unsubscribe_error"
+msgstr ""
+"An error occurred trying to remove a favorite collection. Was this "
+"collection not a favorite?"
+
+#. %1$s is the collection name
+#: views/collections/subscribe.thtml:78
+#, fuzzy
+msgid "collections_unsubscribe_success"
+msgstr "%1$s has been removed from your favorite collections."
+
+#: models/collection_promo.php:56
+#, fuzzy
+msgid "collections_webdev_tagline"
+msgstr "Add-ons make it easier to build the perfect website."
+
+#: models/collection_promo.php:56
+#, fuzzy
+msgid "collections_webdev_title"
+msgstr "Web Developer's Toolbox"
+
+#: views/elements/amo2009/collections_sidebar_whatare.thtml:40
+#, fuzzy
+msgid "collections_whatare_header"
+msgstr "What are Collections?"
+
+#: views/elements/amo2009/collections_sidebar_whatare.thtml:45
+#, fuzzy
+msgid "collections_whatare_learnmore"
+msgstr "Read the FAQ"
+
+#: views/elements/amo2009/collections_sidebar_whatare.thtml:44
+#, fuzzy
+msgid "collections_whatare_text"
+msgstr ""
+"There’s a new way to manage and find favorite add-ons. Comment, share and "
+"sync collections, all from your browser."
+
+#: views/pages/collector_faq.thtml:61 views/pages/collector_features.thtml:67
+#, fuzzy
+msgid "collector_features_a_home"
+msgstr "Add-on Collector Home"
+
+#: views/elements/amo2009/collector_sidebar_download.thtml:46
+#, fuzzy
+msgid "collector_features_heading_download"
+msgstr "Download the Add-on Collector:"
+
+#: views/elements/amo2009/collector_sidebar_download.thtml:43
+#: views/pages/collector_firstrun.thtml:116 views/pages/collector.thtml:69
+#, fuzzy
+msgid "collector_features_img_logo"
+msgstr "Add-on Collector Logo"
+
+#: views/compatibility/dashboard.thtml:49
+#: controllers/compatibility_controller.php:72
+msgid "compatibility_dashboard_center_header"
+msgstr "Central de Compatibilidade de Complementos"
+
+#. %1$s is the name of an application and a version. Example: Firefox 3.0
+#. %2$s is the name of an application. Example: Firefox
+#: views/compatibility/dashboard.thtml:50
+msgid "compatibility_dashboard_intro"
+msgstr ""
+"Prepare-se para o lançamento do %1$s com ferramentas e informações "
+"disponíveis para a comunidade de Complementos do %2$s."
+
+#: views/compatibility/dashboard.thtml:103
+msgid "compatibility_dashboard_loading"
+msgstr "Carregando dados..."
+
+#: views/compatibility/dashboard.thtml:45
+msgid "compatibility_dashboard_main_link"
+msgstr "Voltar para principal"
+
+#: views/compatibility/dashboard.thtml:100 views/compatibility/report.thtml:43
+msgid "compatibility_dashboard_report"
+msgstr "Relatório de compatibilidade dos Complementos "
+
+#: views/compatibility/dashboard.thtml:53
+#: views/compatibility/dashboard.thtml:110
+#: views/compatibility/developers.thtml:43
+msgid "compatibility_developer_info"
+msgstr "Informações para Desenvolvedores de Complementos"
+
+#: views/compatibility/developers.thtml:66
+msgid "compatibility_developers_adjust_maxversion"
+msgstr "Ajuste maxVersion sem fazer upload"
+
+#: views/compatibility/dashboard.thtml:124
+msgid "compatibility_developers_check_status"
+msgstr "Checar status de meus Complementos"
+
+#. %1$s is a URL
+#. %2$s is an application and version. Example: Firefox 3.0
+#: views/compatibility/dashboard.thtml:126
+msgid "compatibility_developers_login_first"
+msgstr ""
+"Se você tem Complementos mantidos no Mozilla Add-ons, <a href=\"%1$s\">por "
+"favor faça login</a> para analisar o status de seus Complementos para o %2$s."
+
+#: views/compatibility/dashboard.thtml:114
+msgid "compatibility_developers_mdclogo_alt"
+msgstr "Logotipo do Mozilla Developer Center"
+
+#: views/compatibility/developers.thtml:73
+msgid "compatibility_developers_no_addons"
+msgstr "Você não possui Complementos mantidos no Mozilla Add-ons."
+
+#: views/compatibility/dashboard.thtml:133
+#: views/compatibility/developers.thtml:55
+msgid "compatibility_developers_results"
+msgstr "Resultados da Checagem de Status dos Complementos"
+
+#: views/compatibility/dashboard.thtml:137
+msgid "compatibility_developers_retrieving"
+msgstr "Buscando status dos Complementos armazenados ..."
+
+#. %1$s is a number
+#. %2$s is an application name
+#. %3$s is a number.
+#. Full example: 50 Firefox users (10% of total)
+#: views/compatibility/developers.thtml:65
+msgid "compatibility_developers_user_count"
+msgstr "%1$s %2$s usuários (%3$s&#37; do total)"
+
+#: views/compatibility/report.thtml:45
+msgid "compatibility_report_detail_intro"
+msgstr ""
+"Os Complementos abaixo representam 95% da utilização de Complementos que o "
+"Mozilla tem conhecimento e estão ordenados por uso."
+
+#: views/compatibility/dashboard.thtml:94
+msgid "compatibility_report_detailed_link"
+msgstr "Ver relatório detalhado"
+
+#. %1$s and %2$s are numbers
+#. %3$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:65
+msgid "compatibility_report_intro"
+msgstr ""
+"Dos Complementos do %1$s que representam 95&#37; da utilização de "
+"Complementos que Mozilla tem conhecimento, <b>%2$s&#37;</b> são atualmente "
+"considerados compatíveis com as últimas versões do %3$s."
+
+#: views/compatibility/dashboard.thtml:81
+msgid "compatibility_report_legend_alpha"
+msgstr "Versões Alpha"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:81
+msgid "compatibility_report_legend_alpha_description"
+msgstr "Complementos compatíveis com uma versão alpha do %1$s"
+
+#: views/compatibility/dashboard.thtml:85
+msgid "compatibility_report_legend_beta"
+msgstr "Versões Beta"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:85
+msgid "compatibility_report_legend_beta_description"
+msgstr "Complementos compatíveis com uma versão beta ou candidata do %1$s"
+
+#: views/compatibility/dashboard.thtml:89
+msgid "compatibility_report_legend_latest"
+msgstr "Última versão"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:89
+msgid "compatibility_report_legend_latest_description"
+msgstr "Complementos atualizados com a última versão do %1$s"
+
+#: views/compatibility/dashboard.thtml:77
+msgid "compatibility_report_legend_other"
+msgstr "Outras versões"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:77
+msgid "compatibility_report_legend_other_description"
+msgstr "Complementos não compatíveis com quaisquer versões do %1$s"
+
+#: views/compatibility/dashboard.thtml:62
+msgid "compatibility_report_title"
+msgstr "Relatório de Compatibilidade de Complementos"
+
+#: views/compatibility/dashboard.thtml:54
+#: views/compatibility/dashboard.thtml:144 views/compatibility/users.thtml:42
+msgid "compatibility_user_info"
+msgstr "Informações para Usuários de Complementos"
+
+#: views/compatibility/dashboard.thtml:52
+msgid "compatibility_view_report"
+msgstr "Ver Relatório de Compatibilidade"
+
+#. %s is a URL
+#: views/pages/credits.thtml:142
+#, php-format
+msgid "credits_contributing"
+msgstr "Para saber como contribuir, veja o nosso %s."
+
+#: views/pages/credits.thtml:142
+msgid "credits_contributing_wikipage"
+msgstr "wiki page"
+
+#: views/pages/credits.thtml:99
+msgid "credits_intro"
+msgstr ""
+"A Mozilla gostaria de agradecer as seguintes pessoas pela sua contribuição "
+"para o projeto addons.mozilla.org através dos anos:"
+
+#: views/pages/credits.thtml:103
+msgid "credits_section_developers"
+msgstr "Desenvolvedores"
+
+#: views/pages/credits.thtml:115
+msgid "credits_section_editors"
+msgstr "Editores"
+
+#: views/pages/credits.thtml:109
+msgid "credits_section_localizers"
+msgstr "Tradutores"
+
+#: views/pages/credits.thtml:121
+msgid "credits_section_other_contributors"
+msgstr "Outros colaboradores"
+
+#: views/pages/credits.thtml:127
+msgid "credits_section_past_developers"
+msgstr "Desenvolvedores anteriores"
+
+#: views/pages/credits.thtml:133
+msgid "credits_section_software"
+msgstr "Software e Imagens"
+
+#: views/pages/credits.thtml:136
+msgid "credits_software_famfamfam"
+msgstr ""
+"Alguns ícones usados são do <a href=\"http://www.famfamfam.com/lab/icons/"
+"silk/\">Conjunto de ícones do famfamfam Silk</a>, lincenciados sob a licença "
+"<a href=\"http://creativecommons.org/licenses/by/2.5/\">Creative Commons "
+"Attribution 2.5 </a>."
+
+#: views/pages/credits.thtml:137
+msgid "credits_software_timeplot"
+msgstr ""
+"Some pages use elements of <a href=\"http://www.simile-widgets.org/timeplot/"
+"\">Timeplot</a>, licensed under a <a href=\"http://simile.mit.edu/license."
+"html\">BSD License</a>."
+
+#. date format string as used in PHP's strftime():
+#. http://php.net/strftime
+#: views/elements/collections_interactive_addon.thtml:85
+#: views/elements/amo2009/addon_version_detail.thtml:53
+#: views/elements/amo2009/homepage_addon.thtml:115
+#: views/elements/addon_version_detail.thtml:54
+#: views/elements/addon_listitem.thtml:124 views/elements/feature.thtml:106
+#: views/collections/detail.thtml:118 views/collections/edit.thtml:325
+#: views/users/info.thtml:76 views/editors/reviews_queue.thtml:57
+#: views/editors/reviews_queue.thtml:68 views/developers/dashboard.thtml:65
+#: views/developers/versions_edit.thtml:208 views/developers/versions.thtml:67
+#: views/search/rss/index.thtml:5 views/addons/rss/versions.thtml:42
+#: views/addons/display.thtml:104 views/addons/display.thtml:356
+#: views/addons/browse_thumbs.thtml:75 views/reviews/add.thtml:63
+#: views/reviews/display.thtml:74 views/reviews/display.thtml:160
+#: views/reviews/delete.thtml:54 controllers/statistics_controller.php:244
+#: controllers/collections_controller.php:1047
+msgid "date"
+msgstr "%e de %B de %Y"
+
+#. date and time format string (strftime)
+#. http://php.net/strftime
+#: views/elements/addon_version_detail.thtml:53
+#: views/developers/discuss.thtml:52 views/developers/discuss.thtml:62
+#: views/admin/addons_status.thtml:57
+msgid "datetime"
+msgstr "%e de %B de %Y às %I:%M %p"
+
+#: views/elements/developers/actionbar.thtml:47
+msgid "devcp_actionbar_link_details"
+msgstr "Informações detalhadas"
+
+#: views/elements/developers/actionbar.thtml:42
+#: views/elements/developers/actionbar.thtml:50
+#: views/developers/dashboard.thtml:64
+msgid "devcp_actionbar_link_edit"
+msgstr "Editar o Complemento"
+
+#: views/elements/developers/actionbar.thtml:51
+msgid "devcp_actionbar_link_newversion"
+msgstr "Enviar nova versão"
+
+#: views/elements/developers/actionbar.thtml:44
+#: views/elements/developers/actionbar.thtml:49
+#: views/developers/dashboard.thtml:73
+msgid "devcp_actionbar_link_stats"
+msgstr "Painel de estatística"
+
+#. %1$s is a filename, e.g. "foo.txt"
+#. %2$s is the extension, e.g. ".txt"
+#. %3$s is a list of valid extensions, like ".png, .jpg, .gif"
+#: controllers/developers_controller.php:1361
+msgid "devcp_add_previews_extension_error"
+msgstr "File %1$s has an invalid extension (%2$s). Allowed extensions: %3$s"
+
+#. %s is the filename.
+#: controllers/developers_controller.php:1394
+msgid "devcp_add_previews_save_error"
+msgstr "File %s could not be saved to the database. Please try again."
+
+#. %1$s is the preview ID number, %2$s is the filename.
+#: controllers/developers_controller.php:1389
+msgid "devcp_add_previews_success_replace"
+msgstr "Preview %1$s was replaced with file %2$s successfully."
+
+#. %s is the filename.
+#: controllers/developers_controller.php:1391
+msgid "devcp_add_previews_success_upload"
+msgstr "File %s was uploaded successfully. You can add a caption below."
+
+#: controllers/components/developers.php:1163
+msgid "devcp_additem_addontype_autodetect"
+msgstr "(autodetectar)"
+
+#: views/elements/developers/additem.thtml:76
+msgid "devcp_additem_linktitle_opensin_newwindow"
+msgstr "Abrir em nova janela"
+
+#: views/elements/developers/additem.thtml:41
+msgid "devcp_additem_sidebar_title"
+msgstr "Enviar Complemento"
+
+#: views/elements/developers/additem.thtml:53
+msgid "devcp_additem_step0_newlink"
+msgstr "Acordo com desenvolvedor"
+
+#: views/elements/developers/additem.thtml:46
+msgid "devcp_additem_step1_link"
+msgstr "Passo 1: Enviar"
+
+#: views/elements/developers/additem.thtml:47
+msgid "devcp_additem_step2_link"
+msgstr "Passo 2: Detalhes do Complemento"
+
+#: views/elements/developers/additem.thtml:48
+msgid "devcp_additem_step3_link"
+msgstr "Passo 3: Detalhes da versão"
+
+#: views/elements/developers/additem.thtml:49
+msgid "devcp_additem_step4_link"
+msgstr "Passo 4: Tradução"
+
+#: views/elements/developers/additem.thtml:50
+msgid "devcp_additem_step5_link"
+msgstr "Passo 5: Sucesso"
+
+#: views/elements/developers/additem.thtml:76
+msgid "devcp_additem_submissionhelp_link"
+msgstr "Ajuda para enviar"
+
+#: controllers/previews_controller.php:168
+#: controllers/previews_controller.php:277
+msgid "devcp_addon_field_preview_caption_displaytitle"
+msgstr "Rótulo para visualização"
+
+#: views/developers/addon_status.thtml:177
+msgid "devcp_addon_status_action_activate"
+msgstr "Deixar Ativo"
+
+#: views/developers/addon_status.thtml:178
+msgid "devcp_addon_status_action_activate_description"
+msgstr ""
+"Deixar seu Complemento ativo para que apareça em listagens públicas e "
+"permita o serviço de checagem de atualizações."
+
+#: views/developers/addon_status.thtml:135
+msgid "devcp_addon_status_action_complete"
+msgstr "Completar Complemento"
+
+#: views/developers/addon_status.thtml:136
+msgid "devcp_addon_status_action_complete_description"
+msgstr "Completar seu Complemento e colocá-lo no Sandbox"
+
+#: views/developers/addon_status.thtml:181
+msgid "devcp_addon_status_action_deactivate"
+msgstr "Deixar Inativo"
+
+#: views/developers/addon_status.thtml:182
+msgid "devcp_addon_status_action_deactivate_description"
+msgstr ""
+"Deixar seu Complemento inativo para que fique escondido de todas as "
+"listagens públicas e desabilitar o serviço de checagem de atualizações."
+
+#: views/developers/addon_status.thtml:143
+msgid "devcp_addon_status_action_move"
+msgstr "Deixar no Sandbox"
+
+#: views/developers/addon_status.thtml:144
+msgid "devcp_addon_status_action_move_description"
+msgstr "Colocar o seu Complemento novamente no Sandbox. Isto é reversível."
+
+#: views/developers/addon_status.thtml:139
+msgid "devcp_addon_status_action_nominate"
+msgstr "Nomear para o público"
+
+#: views/developers/addon_status.thtml:140
+msgid "devcp_addon_status_action_nominate_description"
+msgstr "Nomear seu Complemento para se tornar público"
+
+#: views/developers/addon_status.thtml:147
+msgid "devcp_addon_status_action_public"
+msgstr "Deixar Público"
+
+#: views/developers/addon_status.thtml:148
+msgid "devcp_addon_status_action_public_description"
+msgstr "Tornar seu Complemento Público novamente."
+
+#: views/developers/addon_status.thtml:169
+msgid "devcp_addon_status_active"
+msgstr ""
+"Seu Complemento está <span class=\"inactive-0\">Ativo</span>. Isto significa "
+"que seu Complemento está aparecendo em todas as listagens públicas que são "
+"apropriadas para o status acima."
+
+#: views/developers/addon_status.thtml:111
+msgid "devcp_addon_status_completion_disabled"
+msgstr ""
+"Por favor preencha os critérios acima antes de completar seu Complemento e "
+"colocá-lo no <span class=\"status-1\">Sandbox</span>."
+
+#: views/developers/addon_status.thtml:108
+msgid "devcp_addon_status_completion_enabled"
+msgstr ""
+"Agora você poderá completar seu Complemento e colocá-lo no <span class="
+"\"status-1\">Sandbox</span> clicando no botão abaixo."
+
+#: views/developers/addon_status.thtml:102
+msgid "devcp_addon_status_criteria_category"
+msgstr "Pelo menos uma categoria selecionada"
+
+#: views/developers/addon_status.thtml:101
+msgid "devcp_addon_status_criteria_description"
+msgstr "Descrição do Complemento é obrigatória"
+
+#: views/developers/addon_status.thtml:99
+msgid "devcp_addon_status_criteria_name"
+msgstr "Nome do Complemento é obrigatório"
+
+#: views/developers/addon_status.thtml:120
+msgid "devcp_addon_status_criteria_prerelease"
+msgstr "Complemento não encontra-se marcado como pré-lançamento."
+
+#: views/developers/addon_status.thtml:119
+msgid "devcp_addon_status_criteria_preview"
+msgstr ""
+"Pelo menos uma ou mais imagens de Screenshot são obrigatórias para extensões "
+"e temas."
+
+#: views/developers/addon_status.thtml:100
+msgid "devcp_addon_status_criteria_summary"
+msgstr "Sumário do Complemento é obrigatório"
+
+#. %s is the status in a span, e.g. "<span>_('Public')</span>".
+#: views/developers/addon_status.thtml:58
+msgid "devcp_addon_status_header"
+msgstr "Status do Complemento: %s"
+
+#: views/developers/addon_status.thtml:152
+#: views/developers/addon_status.thtml:173
+msgid "devcp_addon_status_header_actions"
+msgstr "Ações permitidas"
+
+#: views/developers/addon_status.thtml:168
+msgid "devcp_addon_status_header_active"
+msgstr "Status de disponibilidade: <span class=\"inactive-0\">Ativo</span>"
+
+#: views/developers/addon_status.thtml:97
+msgid "devcp_addon_status_header_criteria"
+msgstr "Critério de Completude do Complemento"
+
+#: views/developers/addon_status.thtml:164
+msgid "devcp_addon_status_header_inactive"
+msgstr "Status de disponibilidade: <span class=\"inactive-1\">Inativo</span>"
+
+#: views/developers/addon_status.thtml:117
+msgid "devcp_addon_status_header_nomination"
+msgstr "Critério para Nomeação Pública"
+
+#: views/developers/addon_status.thtml:190
+msgid "devcp_addon_status_header_trusted"
+msgstr "Status de Reconhecimento: <span class=\"status-4\">Reconhecido</span>"
+
+#: views/developers/addon_status.thtml:165
+msgid "devcp_addon_status_inactive"
+msgstr ""
+"Seu Complemento está <span class=\"inactive-1\">Inativo</span>. O que "
+"significa que seu Complemento não irá aparecer nas listagens, independente "
+"do status acima. Atualizações <b>não</b> serão fornecidas ao seu Complemento "
+"através do serviço de checagem de atualizações."
+
+#: views/developers/addon_status.thtml:128
+msgid "devcp_addon_status_nominate_disabled"
+msgstr ""
+"Por favor preencha os critérios acima antes de nomear seu Complemento para "
+"se tornar <span class=\"status-4\">Público</span>."
+
+#: views/developers/addon_status.thtml:125
+msgid "devcp_addon_status_nominate_enabled"
+msgstr ""
+"Agora você pode nomear seu Complemento como <span class=\"status-4"
+"\">Público</span> ao clicar no botão abaixo."
+
+#: views/developers/addon_status.thtml:64
+msgid "devcp_addon_status_public"
+msgstr "Público"
+
+#: views/developers/addon_status.thtml:63
+msgid "devcp_addon_status_sandbox"
+msgstr "Sandbox"
+
+#. %s is an email address.
+#: views/developers/addon_status.thtml:89
+msgid "devcp_addon_status_switch_disabled"
+msgstr ""
+"Seu Complemento encontra-se <span class=\"status-5\">Desabilitado</span> por "
+"um administrador e não pode ser utilizado. Se você tem dúvidas por favor "
+"envie email para %s."
+
+#: views/developers/addon_status.thtml:67
+msgid "devcp_addon_status_switch_incomplete"
+msgstr ""
+"Seu Complemento está <span class=\"status-0\">Incompleto</span>. Isto "
+"significa que seu Complemento não está aparecendo em quaisquer áreas do site "
+"ou no serviço de checagem de atualizações. Você poderá voltar a esta página "
+"para completar seu Complemento depois que ele se enquadrar nos requisitos "
+"abaixo para que o mesmo possa ficar completo e ser transferido para o <span "
+"class=\"status-1\">Sandbox</span>."
+
+#. %s is a number, perhaps 42.
+#: views/developers/addon_status.thtml:77
+msgid "devcp_addon_status_switch_nominated"
+msgstr ""
+"Seu Complemento está nomeado para se tornar <span class=\"status-4"
+"\">Público</span> e encontra-se esperando uma revisão de editores. Existem "
+"atualimente %s outros Complementos na fila."
+
+#. %s is an email address.
+#: views/developers/addon_status.thtml:81
+msgid "devcp_addon_status_switch_pending"
+msgstr ""
+"Seu Complemento encontra-se pendende. Isto não deve acontecer. Por favor "
+"envie e-mail para %s colocando o ID do seu Complemento e esta mensagem de "
+"erro."
+
+#: views/developers/addon_status.thtml:85
+msgid "devcp_addon_status_switch_public"
+msgstr ""
+"Seu Complemento está <span class=\"status-4\">Público</span>, o que "
+"significa que irá aparecer em todas as listagens e buscas, e poderá ser "
+"baixado sem restrições. Atualizações estarão em funcionamento para seu "
+"Complemento através do serviço de checagem de atualizações."
+
+#: views/developers/addon_status.thtml:71
+#: views/developers/addon_status.thtml:75
+msgid "devcp_addon_status_switch_sandbox"
+msgstr ""
+"Seu Complemento está no <span class=\"status-1\">Sandbox</span>, o que "
+"significa que será apresentado em listagens e buscas, mas usuários deverão "
+"aceitá-lo como experimental antes da instalação. Atualizações <b>não</b> "
+"são oferecidas para o seu Complemento através do serviço de checagem de "
+"atualizações."
+
+#. %s is the add-on name.
+#: views/developers/addon_status_nominate.thtml:43
+#: views/developers/addon_status_confirm.thtml:43
+#: views/developers/addon_status.thtml:43
+msgid "devcp_addon_status_title"
+msgstr "Status do %s"
+
+#: views/developers/addon_status.thtml:191
+msgid "devcp_addon_status_trusted"
+msgstr ""
+"Seu Complemento é <span class=\"status-4\">Reconhecido</span>. Isto "
+"significa que você pode enviar atualizações para seu Complemento, sem que "
+"sejam necessárias revisões por editores."
+
+#: views/developers/dashboard.thtml:68
+msgid "devcp_dashboard_active"
+msgstr "Ativo"
+
+#. %1$s is the add-on type string
+#. %2$s is Inactive or Active in a <span>
+#. %3$s is the addon's public status (Public, In Sandbox, ...) in a <span>
+#: views/developers/dashboard.thtml:69
+msgid "devcp_dashboard_addontype_status"
+msgstr "%1$s currenty %2$s and %3$s"
+
+#: views/developers/dashboard.thtml:67
+msgid "devcp_dashboard_change_status"
+msgstr "Change Status"
+
+#. %s is the addons email address.
+#: views/developers/dashboard.thtml:99
+msgid "devcp_dashboard_disabled_questions"
+msgstr ""
+"Your add-on was disabled by an administrator and cannot be used. If you "
+"have any questions, please email %s."
+
+#. %s is the (localized) add-on status string in a span, e.g. "Disabled"
+#: views/developers/dashboard.thtml:98
+msgid "devcp_dashboard_disabled_status"
+msgstr "Add-on Status: %s"
+
+#: views/developers/dashboard.thtml:43
+msgid "devcp_dashboard_header_main"
+msgstr "Developer Dashboard"
+
+#: views/developers/dashboard.thtml:110
+msgid "devcp_dashboard_header_welcome"
+msgstr "Welcome to the Developer Dashboard"
+
+#: views/developers/dashboard.thtml:68
+msgid "devcp_dashboard_inactive"
+msgstr "Inactive"
+
+#. %s is a date in the _('date') format
+#: views/developers/dashboard.thtml:65
+msgid "devcp_dashboard_last_edited"
+msgstr "Last edited on %s"
+
+#: views/developers/dashboard.thtml:111
+msgid "devcp_dashboard_learn"
+msgstr ""
+"You don't currently have any add-ons hosted on Mozilla Add-ons. To learn how "
+"the process works and submit your first add-on, click Get Started below."
+
+#: views/developers/dashboard.thtml:112
+msgid "devcp_dashboard_start"
+msgstr "Get Started"
+
+#: views/developers/dashboard.thtml:82
+msgid "devcp_dashboard_versions"
+msgstr "Versions and Files"
+
+#: views/developers/dashboard.thtml:91
+msgid "devcp_dashboard_versions_new"
+msgstr "Upload a new version"
+
+#. %s is the preview ID number.
+#: controllers/developers_controller.php:1415
+msgid "devcp_delete_previews_error"
+msgstr "Preview %s could not be deleted from the database. Please try again."
+
+#. %s is the preview ID number.
+#: controllers/developers_controller.php:1413
+msgid "devcp_delete_previews_success"
+msgstr "Preview %s has been deleted successfully."
+
+#: controllers/developers_controller.php:1089
+msgid "devcp_delete_version_priv_error"
+msgstr "You do not have privileges to delete versions or files."
+
+#. %1$s is the count of files, a number
+#. %2$s is a status string like _('Public') or _('Incomplete')
+#: controllers/components/amo.php:549
+msgid "devcp_describe_version_status"
+msgid_plural "devcp_describe_version_status"
+msgstr[0] "%1$s %2$s file"
+msgstr[1] "%1$s %2$s files"
+
+#. %s is a version number. Example: 3.0
+#: views/developers/versions.thtml:65
+#, php-format
+msgid "devcp_details_version"
+msgstr "Versão %s"
+
+#: views/developers/discuss.thtml:68
+msgid "devcp_discuss_addreply_header"
+msgstr "Adicionar Resposta"
+
+#: views/developers/discuss.thtml:57
+msgid "devcp_discuss_allreplies_header"
+msgstr "Respostas"
+
+#. notice when an error occurs saving a discussion reply
+#. %1 is the email address (linked) for the amo-editors list
+#: views/developers/discuss.thtml:70
+msgid "devcp_discuss_error_notice"
+msgstr ""
+"Erro ao salvar sua resposta. Entre em contato com %1$s sobre este problema."
+
+#. %1 is the add-on name, %2 is the add-on's version number currently being reviewed by an editor
+#: views/developers/discuss.thtml:46
+msgid "devcp_discuss_intro"
+msgstr ""
+"Um Editor do Mozilla Add-ons pediu maiores informações de você referente a "
+"versão %2$s do seu Complemento %1$s."
+
+#. %1 is the add-on name
+#: views/developers/discuss.thtml:43
+msgid "devcp_discuss_pagetitle"
+msgstr "Fornecer maiores informações para a revisão de Complemento de %1$s"
+
+#. submit button text
+#: views/developers/discuss.thtml:79
+msgid "devcp_discuss_submit_reply"
+msgstr "Enviar Resposta"
+
+#: views/developers/discuss.thtml:72
+msgid "devcp_discuss_success_message"
+msgstr ""
+"Sua resposta foi arquivada com sucesso. Os outros participantes da discussão "
+"serão notificados via e-mail."
+
+#. in an author/editor discussion about an add-on to be reviewed:
+#. %1 is the commenter's user name (linked).
+#. %2 is the full date the comment was made.
+#: views/developers/discuss.thtml:52 views/developers/discuss.thtml:62
+msgid "devcp_discuss_writtenby"
+msgstr "escrito por %1$s em %2$s"
+
+#: views/developers/addon_edit_authors.thtml:72
+#: views/developers/addon_edit_authors.thtml:81
+msgid "devcp_edit_authors_add_author"
+msgstr "Adicionar novo autor"
+
+#: views/developers/addon_edit_authors.thtml:96
+msgid "devcp_edit_authors_add_author_button"
+msgstr "Adicionar Autor"
+
+#: views/developers/addon_edit_authors.thtml:83
+msgid "devcp_edit_authors_add_email"
+msgstr "Conta de Email de Autor:"
+
+#: views/developers/addon_edit_authors.thtml:98
+msgid "devcp_edit_authors_add_loading"
+msgstr "Checando conta de email..."
+
+#: views/developers/addon_edit_authors.thtml:70
+msgid "devcp_edit_authors_click_save"
+msgstr "Para salvar clique no botão Atualizar Autores abaixo."
+
+#: views/developers/addon_edit_authors.thtml:58
+msgid "devcp_edit_authors_header_current"
+msgstr "Autores Existentes"
+
+#: views/developers/addon_edit_authors.thtml:50
+msgid "devcp_edit_authors_header_manage"
+msgstr "Gerenciar Autores de Complementos"
+
+#: views/developers/addon_edit_authors.thtml:93
+msgid "devcp_edit_authors_label_add_listed"
+msgstr "Listar como autor em páginas públicas"
+
+#: views/developers/addon_edit_authors.thtml:89
+msgid "devcp_edit_authors_label_developer"
+msgstr ""
+"<strong>Desenvolvedor</strong> - Pode gerenciar todos os aspectos da "
+"listagem de Complementos, exceto adicionar ou remover autores."
+
+#: views/developers/addon_edit_authors.thtml:88
+msgid "devcp_edit_authors_label_owner"
+msgstr ""
+"<strong>Proprietário</strong> - Pode gerenciar todos os aspectos da listagem "
+"de Complementos, includindo adicionar ou remover autores."
+
+#: views/developers/addon_edit_authors.thtml:90
+msgid "devcp_edit_authors_label_viewer"
+msgstr ""
+"<strong>Visualizador</strong> - Podem olhar listagem de Complementos e "
+"estatísticas, mas não podem fazer mudanças."
+
+#. Placeholder for the empty option in a <select>.
+#: views/developers/addon_edit_categories.thtml:69
+msgid "devcp_edit_authors_option_empty"
+msgstr "----------------"
+
+#: views/developers/addon_edit_authors.thtml:86
+msgid "devcp_edit_authors_select_role"
+msgstr "Selecione um papel para o autor:"
+
+#. Column name in a table.
+#: views/developers/addon_edit_authors.thtml:62
+msgid "devcp_edit_authors_th_author"
+msgstr "Autor"
+
+#. Column name in a table.
+#: views/developers/addon_edit_authors.thtml:64
+msgid "devcp_edit_authors_th_listed"
+msgstr "Listado"
+
+#. Column name in a table.
+#: views/developers/addon_edit_authors.thtml:63
+msgid "devcp_edit_authors_th_role"
+msgstr "Papel"
+
+#: views/developers/addon_edit_authors.thtml:77
+msgid "devcp_edit_authors_update_author"
+msgstr "Atualizar autores"
+
+#: views/developers/addon_edit_categories.thtml:99
+msgid "devcp_edit_categories_button_update"
+msgstr "Atualizar Categorias"
+
+#: views/developers/addon_edit_categories.thtml:88
+msgid "devcp_edit_categories_does_not_fit"
+msgstr "Meu Complemento não se enquadra em nenhuma das categorias."
+
+#. %s is the application name (Firefox, Thunderbird).
+#: views/developers/addon_edit_categories.thtml:61
+msgid "devcp_edit_categories_header_application"
+msgstr "%s Categorias"
+
+#: views/developers/addon_edit_categories.thtml:49
+msgid "devcp_edit_categories_header_manage"
+msgstr "Gerenciar Categorias de Complementos"
+
+#: views/developers/addon_edit_categories.thtml:91
+msgid "devcp_edit_categories_hover"
+msgstr "Visite as categorias para ver a descrição."
+
+#. %s is the category number (1, 2, 3).
+#: views/developers/addon_edit_categories.thtml:67
+msgid "devcp_edit_categories_label_category_num"
+msgstr "Categoria %s"
+
+#: views/developers/addon_edit_categories.thtml:94
+#: views/developers/addon_edit_categories.thtml:103
+msgid "devcp_edit_categories_none_available"
+msgstr ""
+"Nenhuma das categorias estão disponíveis para este tipo de Complemento e "
+"aplicação."
+
+#: views/developers/addon_edit_categories.thtml:86
+msgid "devcp_edit_categories_other"
+msgstr ""
+"Coloque o seu Complemento nesta categoria somente se ele não se enquadrar "
+"nas outras categorias disponíveis."
+
+#. %s is the application name (Firefox, Thunderbird).
+#: views/developers/addon_edit_categories.thtml:63
+msgid "devcp_edit_categories_select_application_categories"
+msgstr "Selecione até três categorias do %s para seu Complemento"
+
+#: views/developers/addon_edit.thtml:47
+msgid "devcp_edit_dd_manage_authors"
+msgstr "Adicionar ou remover usuários que podem gerenciar este Complemento."
+
+#: views/developers/addon_edit.thtml:49
+msgid "devcp_edit_dd_manage_categories"
+msgstr ""
+"Selecionar as categorias relevantes para cada uma das aplicações que o seu "
+"Complemento suporta."
+
+#: views/developers/addon_edit.thtml:51
+msgid "devcp_edit_dd_manage_description"
+msgstr ""
+"Adicionar ou modificar traduções para seu Complemento referentes ao sumário, "
+"descrições, acordo de utilização para usuários e política de privacidade."
+
+#: views/developers/addon_edit.thtml:53
+msgid "devcp_edit_dd_manage_properties"
+msgstr ""
+"Mudar dados do Complemento como nome, página home, ícone, e outros atributos."
+
+#: views/developers/addon_edit_descriptions.thtml:116
+msgid "devcp_edit_description_button_update"
+msgstr "Atualizar Descrições"
+
+#: views/developers/addon_edit_descriptions.thtml:115
+msgid "devcp_edit_description_correct_error"
+msgstr "Por favor corrija os erros indicado em vermelho acima."
+
+#: views/developers/addon_edit_descriptions.thtml:51
+msgid "devcp_edit_descriptions_header"
+msgstr "Editar Descrições do Complemento"
+
+#: views/developers/addon_edit_descriptions.thtml:94
+msgid "devcp_edit_descriptions_transbox_comments_description"
+msgstr ""
+"Quaisquer informações que usuários podem estar interessados em saber que não "
+"necessariamente se aplicam ao sumário ou descrição do Complemento. Casos "
+"comuns incluem listagem de bugs conhecidos, informações sobre como relatar "
+"bugs, datas das próximas versões, etc."
+
+#: views/developers/addon_edit_descriptions.thtml:93
+msgid "devcp_edit_descriptions_transbox_comments_name"
+msgstr "Comentários do Desenvolvedor"
+
+#: views/developers/addon_edit_descriptions.thtml:86
+msgid "devcp_edit_descriptions_transbox_description_description"
+msgstr ""
+"A descrição do seu Complemento trata-se de uma descrição longa dos recursos, "
+"funcionalidade, e outras informações relevantes. Esta informação será "
+"apresentada abaixo do sumário na página de apresentação do Complemento."
+
+#: views/developers/addon_edit_descriptions.thtml:85
+msgid "devcp_edit_descriptions_transbox_description_name"
+msgstr "Descrição do Complemento"
+
+#: views/developers/addon_edit_descriptions.thtml:103
+msgid "devcp_edit_descriptions_transbox_eula_description"
+msgstr ""
+"Se o seu Complemento tem um acordo de utilização para usuários, por favor "
+"entre com o texto abaixo. Se colocado o texto baixo, usuários serão "
+"obrigados a aceitar antes de instalar seu Complemento. Por favor entenda que "
+"um acordo de utilização não é a mesma coisa que licença de código como GPL "
+"ou MPL."
+
+#: views/developers/addon_edit_descriptions.thtml:102
+msgid "devcp_edit_descriptions_transbox_eula_name"
+msgstr "Acordo de Utilização de Software"
+
+#: views/developers/addon_edit_descriptions.thtml:112
+msgid "devcp_edit_descriptions_transbox_privacy_description"
+msgstr ""
+"If your add-on has a privacy policy, enter its text here. Your add-on's "
+"display page will display a link to the policy."
+
+#: views/developers/addon_edit_descriptions.thtml:111
+msgid "devcp_edit_descriptions_transbox_privacy_name"
+msgstr "Política de Privacidade"
+
+#: views/developers/addon_edit_descriptions.thtml:78
+msgid "devcp_edit_descriptions_transbox_summary_description"
+msgstr ""
+"O sumário é uma descrição breve do seu Complemento sobre a funcionalidade "
+"básica e que será apresentada nos resultados da busca e nas listagens, assim "
+"como no topo da página de apresentação do seu Complemento <strong>Limite de "
+"250 caracteres.</strong>"
+
+#: views/developers/addon_edit_descriptions.thtml:77
+msgid "devcp_edit_descriptions_transbox_summary_name"
+msgstr "Sumário do Complemento"
+
+#: views/developers/addon_edit.thtml:46
+msgid "devcp_edit_dt_manage_authors"
+msgstr "Gerenciar Autores do Complemento"
+
+#: views/developers/addon_edit.thtml:48
+msgid "devcp_edit_dt_manage_categories"
+msgstr "Gerenciar Categorias do Complemento"
+
+#: views/developers/addon_edit.thtml:50
+msgid "devcp_edit_dt_manage_descriptions"
+msgstr "Gerenciar Descrições do Complemento"
+
+#: views/developers/addon_edit.thtml:52
+msgid "devcp_edit_dt_manage_properties"
+msgstr "Gerenciar Propriedades do Complemento"
+
+#: views/developers/addon_edit_properties.thtml:170
+msgid "devcp_edit_label_externalsoftware"
+msgstr "Este Complemento necessita de software externo"
+
+#: views/developers/addon_edit_properties.thtml:205
+msgid "devcp_edit_label_locale_disambiguation"
+msgstr "Mais informações sobre o idioma"
+
+#: views/developers/addon_edit_properties.thtml:168
+msgid "devcp_edit_label_prerelease"
+msgstr "Esta é uma pré-distribuição"
+
+#: views/developers/addon_edit_properties.thtml:169
+msgid "devcp_edit_label_sitespecific"
+msgstr "Este é um Complemento específico para um site"
+
+#: views/developers/addon_edit_properties.thtml:202
+msgid "devcp_edit_label_target_locale"
+msgstr "Idioma alvo"
+
+#: views/developers/addon_edit_properties.thtml:212
+msgid "devcp_edit_properties_button_update"
+msgstr "Atualizar propriedades"
+
+#: views/developers/addon_edit_properties.thtml:198
+msgid "devcp_edit_properties_change_guid"
+msgstr "Somente mudar se você entende as possíveis consequências."
+
+#: views/developers/addon_edit_properties.thtml:109
+msgid "devcp_edit_properties_current_icon"
+msgstr "Ãcone registrado"
+
+#: views/developers/addon_edit_properties.thtml:85
+msgid "devcp_edit_properties_default_locale"
+msgstr ""
+"A tradução padrão de um Complemento é a tradução principal base para outras "
+"traduções presentes. Se traduções para o seu Complemento não encontram-se "
+"disponíveis em certos tipos de idiomas dos usuários, a tradução padrão será "
+"apresentada."
+
+#: views/developers/addon_edit_properties.thtml:167
+msgid "devcp_edit_properties_flags"
+msgstr ""
+"Estas propriedades são utilizadas para filtrar e classificar Complementos."
+
+#: views/developers/addon_edit_properties.thtml:174
+msgid "devcp_edit_properties_guid"
+msgstr ""
+"O GUID do seu Complemento é especificado no install.rdf o indentifica "
+"unicamente. Você não podem mudar o GUID uma vez que for listado no Mozilla "
+"Add-ons."
+
+#: views/developers/addon_edit_properties.thtml:53
+msgid "devcp_edit_properties_header"
+msgstr "Editar Propriedades do Complemento"
+
+#: views/developers/addon_edit_properties.thtml:186
+msgid "devcp_edit_properties_header_addon_type"
+msgstr "Tipo de Complemento"
+
+#: views/developers/addon_edit_properties.thtml:181
+msgid "devcp_edit_properties_header_admin_settings"
+msgstr "Configurações do Adminstrador"
+
+#: views/developers/addon_edit_properties.thtml:84
+msgid "devcp_edit_properties_header_default_locale"
+msgstr "Tradução padrão"
+
+#: views/developers/addon_edit_properties.thtml:166
+msgid "devcp_edit_properties_header_flags"
+msgstr "Propriedades do Complemento"
+
+#: views/developers/addon_edit_properties.thtml:173
+#: views/developers/addon_edit_properties.thtml:197
+msgid "devcp_edit_properties_header_guid"
+msgstr "GUID do Complemento"
+
+#: views/developers/addon_edit_properties.thtml:104
+msgid "devcp_edit_properties_header_icon"
+msgstr "Ãcone do Complemento"
+
+#: views/developers/addon_edit_properties.thtml:159
+msgid "devcp_edit_properties_header_other_settings"
+msgstr "Outras configurações"
+
+#. A header on the admin page to toggle trusted status.
+#: views/developers/addon_edit_properties.thtml:182
+msgid "devcp_edit_properties_header_trusted"
+msgstr "Complemento certificado?"
+
+#: views/developers/addon_edit_properties.thtml:160
+msgid "devcp_edit_properties_header_view_source"
+msgstr "Ver código fonte online"
+
+#. %s is a comma-separated list of image extensions ".png, .jpg"
+#: views/developers/addon_edit_properties.thtml:106
+msgid "devcp_edit_properties_icon"
+msgstr ""
+"O ícone do Complemento trata-se de uma imagem pequena que é apresentada "
+"próxima ao nome do seu Complemento nas páginas de resultado e navegação, "
+"páginas de apresentação, e também na tela de instalação do Complemento. A "
+"imagem será automaticamente redimensionada para 32 x 32 pixels. Por favor "
+"escolha um dos tipos de imagem abaixo: %s"
+
+#: views/developers/addon_edit_properties.thtml:171
+msgid "devcp_edit_properties_label_binary"
+msgstr "Este Complemento contém componentes binários"
+
+#: views/developers/addon_edit_properties.thtml:185
+msgid "devcp_edit_properties_label_not_trusted"
+msgstr "Não Certificado"
+
+#: views/developers/addon_edit_properties.thtml:184
+msgid "devcp_edit_properties_label_trusted"
+msgstr "Certificado"
+
+#: views/developers/addon_edit_properties.thtml:110
+msgid "devcp_edit_properties_new_icon"
+msgstr "Novo Ãcone"
+
+#: views/developers/addon_edit_properties.thtml:118
+msgid "devcp_edit_properties_remove_icon"
+msgstr "Remover Ãcone"
+
+#: views/developers/addon_edit_properties.thtml:136
+msgid "devcp_edit_properties_transbox_homepage_description"
+msgstr ""
+"Se o seu Complemento tem outra página home, entre com o endereço aqui. "
+"Adicionar outras traduções não é necessário ao menos que o seu site exista "
+"em em vários idiomas."
+
+#: views/developers/addon_edit_properties.thtml:135
+msgid "devcp_edit_properties_transbox_homepage_name"
+msgstr "Página home do Complemento"
+
+#: views/developers/addon_edit_properties.thtml:79
+msgid "devcp_edit_properties_transbox_name_description"
+msgstr ""
+"O nome do seu Complemento será apresentado em todos os locais onde seu "
+"Complemento é listado."
+
+#: views/developers/addon_edit_properties.thtml:78
+msgid "devcp_edit_properties_transbox_name_name"
+msgstr "Nome do Complemento"
+
+#: views/developers/addon_edit_properties.thtml:145
+msgid "devcp_edit_properties_transbox_supportemail_description"
+msgstr ""
+"Se você tem um endereço de email para pedidos de suporte, entre com ele "
+"aqui. O cadastrode outras traduções não é necessário ao menos que você tem "
+"múltiplos endereços de email referentes a múltiplos idiomas."
+
+#: views/developers/addon_edit_properties.thtml:144
+msgid "devcp_edit_properties_transbox_supportemail_name"
+msgstr "Endereço de Email para Suporte"
+
+#: views/developers/addon_edit_properties.thtml:154
+msgid "devcp_edit_properties_transbox_supporturl_description"
+msgstr ""
+"Se o seu Complemento tem um site de suporte ou forum, entre o endereço aqui. "
+"Cadastrar outras traduções não é necessário ao menos que seu site encontra-"
+"se traduzido em outros idiomas."
+
+#: views/developers/addon_edit_properties.thtml:153
+msgid "devcp_edit_properties_transbox_supporturl_name"
+msgstr "Website de Suporte"
+
+#: views/developers/addon_edit_properties.thtml:183
+msgid "devcp_edit_properties_trusted"
+msgstr ""
+"Complementos certificados podem se tornar públicos sem revisão por Editores."
+
+#. %s is href="..." and should stay in the <a> tag.
+#: views/developers/addon_edit_properties.thtml:119
+msgid "devcp_edit_properties_undelete"
+msgstr "Ãcone será removido ao salvar. <a %s>Cancelar?</a>"
+
+#: views/developers/addon_edit_properties.thtml:161
+msgid "devcp_edit_properties_view_source"
+msgstr ""
+"O código fonte do seu Complemento pode ser visualizado online por qualquer "
+"usuário logado se você desejar."
+
+#: views/developers/addon_edit_properties.thtml:162
+msgid "devcp_edit_properties_view_source_allow"
+msgstr "Permitir visualização online do código fonte"
+
+#: views/developers/addon_edit_properties.thtml:163
+msgid "devcp_edit_properties_view_source_do_not_allow"
+msgstr "Não permitir a visualização online do código fonte"
+
+#: views/elements/developers/editbox.thtml:46
+msgid "devcp_editbox_authors"
+msgstr "Autores"
+
+#: views/elements/developers/editbox.thtml:47
+msgid "devcp_editbox_categories"
+msgstr "Categorias"
+
+#: views/elements/developers/editbox.thtml:52
+msgid "devcp_editbox_change_status"
+msgstr "Mudar Status"
+
+#: views/elements/developers/editbox.thtml:48
+msgid "devcp_editbox_descriptions"
+msgstr "Descrições"
+
+#: views/elements/developers/editbox.thtml:43
+msgid "devcp_editbox_edit_addon"
+msgstr "Editar Complemento"
+
+#: views/elements/developers/editbox.thtml:57
+msgid "devcp_editbox_new_version"
+msgstr "Nova versão"
+
+#: views/elements/developers/editbox.thtml:49
+msgid "devcp_editbox_properties"
+msgstr "Propriedades"
+
+#: views/elements/developers/editbox.thtml:60
+msgid "devcp_editbox_screenshots"
+msgstr "Screenshots de Demonstração"
+
+#: views/elements/developers/editbox.thtml:53
+msgid "devcp_editbox_statistics_dashboard"
+msgstr "Quadro de Estatísticas"
+
+#: views/elements/developers/editbox.thtml:54
+msgid "devcp_editbox_versions"
+msgstr "Versões e Arquivos"
+
+#: views/elements/developers/editbox.thtml:42
+msgid "devcp_editbox_view_listing"
+msgstr "Ver listagem"
+
+#: views/elements/developers/editorsmenu.thtml:59
+msgid "devcp_editorsqueue_featured"
+msgstr "Complementos em destaque"
+
+#. %1 is the review count
+#: views/elements/developers/editorsqueue.thtml:42
+#: views/elements/developers/editorsmenu.thtml:56
+#, php-format
+msgid "devcp_editorsqueue_moderatedreviews"
+msgid_plural "devcp_editorsqueue_moderatedreviews"
+msgstr[0] "Revisões avaliadas (%s)"
+msgstr[1] "Revisões avaliadas (%s)"
+
+#. %1 is the nominated addons count
+#: views/elements/developers/editorsqueue.thtml:44
+#: views/elements/developers/editorsmenu.thtml:58
+#, php-format
+msgid "devcp_editorsqueue_nominated"
+msgid_plural "devcp_editorsqueue_nominated"
+msgstr[0] "Complementos indicados (%s)"
+msgstr[1] "Complementos indicados (%s)"
+
+#. %1 is the update count
+#: views/elements/developers/editorsqueue.thtml:43
+#: views/elements/developers/editorsmenu.thtml:57
+#, php-format
+msgid "devcp_editorsqueue_pendingupdates"
+msgid_plural "devcp_editorsqueue_pendingupdates"
+msgstr[0] "Atualizações pendentes (%s)"
+msgstr[1] "Atualizações pendentes (%s)"
+
+#: controllers/statistics_controller.php:147
+#: controllers/statistics_controller.php:361
+#: controllers/previews_controller.php:108
+#: controllers/previews_controller.php:211
+#: controllers/previews_controller.php:312
+msgid "devcp_error_addon_access_denied"
+msgstr "Você não tem acesso a este Complemento."
+
+#. %s is a complete URL with the text from devcp_error_appversion_reference_link_text
+#. in the <a> tag. This should be fixed.
+#: controllers/components/developers.php:591
+#, php-format
+msgid "devcp_error_appversion_reference_link"
+msgstr "Por favor, veja %s para referência."
+
+#. This is the link text in the <a> for devcp_error_appversion_reference_link. This
+#. should be fixed.
+#: controllers/components/developers.php:591
+msgid "devcp_error_appversion_reference_link_text"
+msgstr "esta página"
+
+#: views/developers/addon_edit_authors.thtml:76
+msgid "devcp_error_empty_authors"
+msgstr "Seu Complemento precisa ter o menos um proprietário."
+
+#. %1$s is the name of the file
+#: controllers/components/developers.php:658
+msgid "devcp_error_file_exists"
+msgstr ""
+"Uma versão deste Complemento já existe. Para trocar você deverá remover o "
+"arquivo %1$s primeiramente."
+
+#. %1$s is a file extension. Example: .exe
+#. %2$s is a comma separated list of extensions. Example: .xpi, .jar
+#: controllers/components/developers.php:355
+#, php-format
+msgid "devcp_error_file_extension"
+msgstr ""
+"Esta extensão de arquivo (%s) não é permitida para o tipo de Complemento "
+"selecionada. Por favor, selecione um dos seguintes: %s"
+
+#: controllers/components/developers.php:64
+msgid "devcp_error_five_categories"
+msgstr "Por favor, escolha no máximo cinco categorias."
+
+#: controllers/components/developers.php:526
+msgid "devcp_error_guid_application"
+msgstr "A ID deste Complemento já foi usada por outra aplicação."
+
+#: controllers/components/developers.php:337
+#: controllers/components/developers.php:389
+msgid "devcp_error_http_incomplete"
+msgstr "Transferência incompleta"
+
+#: controllers/components/developers.php:335
+#: controllers/components/developers.php:336
+#: controllers/components/developers.php:387
+#: controllers/components/developers.php:388
+msgid "devcp_error_http_maxupload"
+msgstr "Excede o valor máximo para envio"
+
+#: controllers/components/developers.php:338
+#: controllers/components/developers.php:390
+msgid "devcp_error_http_nofile"
+msgstr "Nenhum arquivo enviado"
+
+#. %1$s is a file extension. Example: .exe
+#. %2$s is a comma separated list of extensions. Example: .xpi, .jar
+#: controllers/components/developers.php:401
+#, php-format
+msgid "devcp_error_icon_extension"
+msgstr ""
+"Esta extensão de arquivo (%s) não é permitida para um ícone. Por favor, "
+"selecione um dos seguintes: %s"
+
+#: controllers/developers_controller.php:504
+msgid "devcp_error_index_rdf_notfound"
+msgstr "Arquivo install.rdf ausente."
+
+#: controllers/components/developers.php:601
+msgid "devcp_error_install_manifest"
+msgstr "Os seguintes erros foram encontrados em install.rdf:"
+
+#: controllers/developers_controller.php:1463
+msgid "devcp_error_invalid_addontype"
+msgstr "Por favor, selecione um tipo válido de Complemento."
+
+#. %$1s is a version. Example: 3.1.1
+#. %$2s is an add-on name.
+#: controllers/components/developers.php:569
+#: controllers/components/developers.php:581
+#, php-format
+msgid "devcp_error_invalid_appversion"
+msgstr "%s não é uma versão válida para %s"
+
+#. %s is a string
+#: controllers/components/developers.php:521
+#, php-format
+msgid "devcp_error_invalid_guid"
+msgstr "A ID deste Complemento não é válida: %s"
+
+#. %$1s is a version. Example: 3.1.1
+#. %$2s is an add-on name.
+#: controllers/components/developers.php:572
+#, php-format
+msgid "devcp_error_invalid_minversion"
+msgstr "%s não é uma versão válida para %s: versões mínimas não podem conter *"
+
+#: controllers/components/developers.php:536
+msgid "devcp_error_invalid_version"
+msgstr ""
+"A versão deste Complemento é inválida: Por favor, veja as <a href=\"http://"
+"developer.mozilla.org/en/docs/Toolkit_version_format\">especificações</a>"
+
+#: controllers/components/developers.php:531
+msgid "devcp_error_invalid_version_spaces"
+msgstr ""
+"A versão deste Complemento é inválida: versões não podem conter espaços."
+
+#. %s is an error message from the parser.
+#: controllers/components/developers.php:501
+#, php-format
+msgid "devcp_error_manifest_parse"
+msgstr "O seguinte erro ocorreu na leitura de install.rdf: %s"
+
+#: controllers/components/developers.php:373
+msgid "devcp_error_move_file"
+msgstr "Não foi possível mover arquivo"
+
+#. %s is the name of a file
+#: controllers/components/developers.php:650
+#: controllers/components/developers.php:662
+#: controllers/components/developers.php:667
+#: controllers/components/developers.php:727
+#: controllers/components/developers.php:738
+#: controllers/components/developers.php:743
+#, php-format
+msgid "devcp_error_moving_file"
+msgstr "Foi encontrado um erro ao mover %s."
+
+#: controllers/components/developers.php:595
+msgid "devcp_error_mozilla_application"
+msgstr "Você precisa selecionar pelo menos uma aplicação Mozilla."
+
+#: controllers/components/developers.php:516
+msgid "devcp_error_no_guid"
+msgstr "Nenhuma ID foi encontrada para este Complemento em install.rdf."
+
+#: controllers/components/developers.php:287
+msgid "devcp_error_no_platform"
+msgstr "Nenhuma plataforma selecionada"
+
+#: controllers/components/developers.php:59
+msgid "devcp_error_one_category"
+msgstr "Por favor, escolha ao menos uma categoria."
+
+#: controllers/components/developers.php:92
+msgid "devcp_error_one_user"
+msgstr "Deve haver pelo menos um autor para este Complemento."
+
+#. %1$s is a file extension. Example: .exe
+#. %2$s is a comma separated list of extensions. Example: .xpi, .jar
+#: controllers/components/developers.php:1081
+#, php-format
+msgid "devcp_error_preview_extension"
+msgstr ""
+"Esta extensão de arquivo (%s) não é permitida para uma pré-distribuição. Por "
+"favor, use uma das seguintes: %s"
+
+#: controllers/components/developers.php:511
+msgid "devcp_error_updatekey"
+msgstr ""
+"Complementos não podem usar uma chave de atualização. Por favor, remova isto "
+"do install.rdf e tente novamente."
+
+#: controllers/components/developers.php:506
+msgid "devcp_error_updateurl"
+msgstr ""
+"Complementos não podem usar um endereço de atualização externo. Por favor, "
+"remova isto do install.rdf e tente novamente."
+
+#: controllers/developers_controller.php:465
+#: controllers/components/developers.php:271
+msgid "devcp_error_upload_file"
+msgstr "Por favor, envie um arquivo."
+
+#: views/developers/uploader.thtml:135
+msgid "devcp_input_upload_file"
+msgstr "Enviar Arquivo"
+
+#: views/pages/js_constants.js.thtml:89
+msgid "devcp_js_a_cancel"
+msgstr "Cancelar"
+
+#: views/pages/js_constants.js.thtml:90
+msgid "devcp_js_add_email"
+msgstr ""
+"Por favor entre com o endereço de email do autor que você desenha adicionar."
+
+#. alt text for a down-arrow image.
+#: views/pages/js_constants.js.thtml:81
+msgid "devcp_js_img_move_down"
+msgstr "Mover para baixo"
+
+#. alt text for an up-arrow image.
+#: views/pages/js_constants.js.thtml:82
+msgid "devcp_js_img_move_up"
+msgstr "Mover para cima"
+
+#: views/pages/js_constants.js.thtml:91
+msgid "devcp_js_img_remove_compat"
+msgstr "Remover Compatibilidade de Aplicação"
+
+#: views/pages/js_constants.js.thtml:86
+msgid "devcp_js_input_list_author"
+msgstr "Listar como autor em listagens públicas"
+
+#: views/pages/js_constants.js.thtml:92
+msgid "devcp_js_license_select"
+msgstr "Please select a license."
+
+#: views/pages/js_constants.js.thtml:93
+msgid "devcp_js_license_text"
+msgstr "Please enter text for your license."
+
+#. <option> text in a <select> for Author role in an add-on.
+#: views/pages/js_constants.js.thtml:84
+msgid "devcp_js_option_developer"
+msgstr "Desenvolvedor"
+
+#. <option> text in a <select> for Author role in an add-on.
+#: views/pages/js_constants.js.thtml:83
+msgid "devcp_js_option_owner"
+msgstr "Proprietário"
+
+#. <option> text in a <select> for Author role in an add-on.
+#: views/pages/js_constants.js.thtml:85
+msgid "devcp_js_option_viewer"
+msgstr "Visualizador"
+
+#: views/pages/js_constants.js.thtml:88
+msgid "devcp_js_remove_author"
+msgstr "Remover autor"
+
+#: views/pages/js_constants.js.thtml:87
+msgid "devcp_js_sure_remove"
+msgstr "Você está <strong>certo</strong> que deseja remover este autor?"
+
+#: views/pages/js_constants.js.thtml:77
+msgid "devcp_js_upload_alert"
+msgstr "Você tem que selecionar um arquivo para enviar."
+
+#. %1$s is an addon id, like 32.
+#. %2$s is a version number, like 3.5.
+#: controllers/components/developers.php:1212
+msgid "devcp_license_existing"
+msgstr "Custom license for add-on %1$s v%2$s"
+
+#: views/elements/developers/localebox.thtml:44
+msgid "devcp_localebox_header_localizedfields"
+msgstr "Campos traduzidos"
+
+#. %1 is the default locale
+#: views/elements/developers/localebox.thtml:48
+#, php-format
+msgid "devcp_localebox_intro"
+msgstr ""
+"Alguns campos desta página estão traduzidos para aparecer no idioma nativo "
+"do usuário final. Selecione sua localização abaixo para editar os detalhes "
+"de seu Complemento neste idioma. Se não existir tradução para um determinado "
+"idioma, ele será mostrado com o idioma padrão selecionado (%s)."
+
+#: views/elements/developers/sidebar.thtml:68
+#: views/elements/developers/myaddons.thtml:75
+msgid "devcp_myaddons_admincp_link"
+msgstr "Painel de controle do administrador"
+
+#: views/elements/developers/sidebar.thtml:65
+#: views/elements/developers/myaddons.thtml:72
+msgid "devcp_myaddons_editorcp_link"
+msgstr "Painel de controle do editor"
+
+#: views/elements/developers/myaddons.thtml:52
+msgid "devcp_myaddons_link"
+msgstr "Meus Complementos"
+
+#: views/elements/developers/sidebar.thtml:70
+#: views/elements/developers/myaddons.thtml:77
+msgid "devcp_myaddons_mainpage_link"
+msgstr "Voltar para página principal"
+
+#: views/elements/developers/sidebar.thtml:63
+#: views/elements/developers/myaddons.thtml:70
+msgid "devcp_myaddons_statistics_link"
+msgstr "Painel de estatísticas"
+
+#: views/elements/developers/sidebar.thtml:62
+#: views/elements/developers/myaddons.thtml:69
+msgid "devcp_myaddons_submitaddon_link"
+msgstr "Enviar um Complemento"
+
+#: views/elements/developers/sidebar.thtml:48
+#: views/elements/developers/myaddons.thtml:67
+msgid "devcp_myaddons_title"
+msgstr "Ferramentas do desenvolvedor"
+
+#. %1$s is an add-on ID, perhaps 167.
+#. %2$s is a URL.
+#: controllers/developers_controller.php:256
+msgid "devcp_new_addon_error"
+msgstr ""
+"Este ID (%1$s) de Complemento já existe no banco de dados. Se este é o seu "
+"Complemento, você poderá <a href=\"%2$s\">enviar uma nova versão</a>."
+
+#: views/developers/addon_status_nominate.thtml:62
+msgid "devcp_nominate_cancel"
+msgstr "Cancelar e voltar"
+
+#. %1 is the add-on name
+#: views/developers/addon_status_nominate.thtml:61
+#, php-format
+msgid "devcp_nominate_submit_nominate"
+msgstr "Indicar %s"
+
+#: views/developers/addon_edit_properties.thtml:50
+#: views/developers/addon_status.thtml:49
+#: views/developers/versions_edit.thtml:50
+msgid "devcp_notice_changes_error"
+msgstr ""
+"<span>Uma ou mais mudanças feitas não podem ser gravadas.</span><br />Por "
+"favor verifique pelos erros abaixo. As outras mudanças foram gravadas com "
+"sucesso."
+
+#: views/developers/addon_edit_authors.thtml:47
+#: views/developers/addon_edit_properties.thtml:47
+#: views/developers/addon_status.thtml:46
+#: views/developers/addon_edit_descriptions.thtml:47
+#: views/developers/versions_edit.thtml:47
+#: views/developers/addon_edit_categories.thtml:46
+msgid "devcp_notice_changes_saved"
+msgstr ""
+"<span>Suas mudanças foram arquivadas.</span><br />Por favor entenda que "
+"algumas mudanças podem levar algumas horas para aparecer em todas as áreas "
+"do site."
+
+#: controllers/previews_controller.php:252
+msgid "devcp_notice_cleardefault"
+msgstr ""
+"Remover esta visualização padrão fará com que outra visualização se torne "
+"automaticamente a visualização padrão."
+
+#: controllers/previews_controller.php:184
+#: controllers/previews_controller.php:251
+msgid "devcp_notice_makedefault"
+msgstr ""
+"Tornar esta visualização padrão irá remover o status da visualização padrão "
+"atual."
+
+#: views/developers/addon_edit_authors.thtml:70
+msgid "devcp_notice_unsaved_changes"
+msgstr "Você tem mudanças não gravadas."
+
+#: controllers/developers_controller.php:87
+#: controllers/developers_controller.php:97
+#: controllers/developers_controller.php:100
+#: controllers/previews_controller.php:67
+#: controllers/previews_controller.php:79
+#: controllers/previews_controller.php:82
+msgid "devcp_pagetitle"
+msgstr "Painel de controle do desenvolvedor"
+
+#: controllers/previews_controller.php:103
+#: controllers/previews_controller.php:104
+msgid "devcp_preview_add_pagetitle"
+msgstr "Adicionar visualização"
+
+#: controllers/previews_controller.php:135
+msgid "devcp_preview_added_successfully"
+msgstr "Visualização adicionada com sucesso."
+
+#: controllers/previews_controller.php:323
+msgid "devcp_preview_deleted_successfully"
+msgstr "Visualização excluída com sucesso."
+
+#: controllers/previews_controller.php:194
+#: controllers/previews_controller.php:195
+msgid "devcp_preview_edit_pagetitle"
+msgstr "Editar visualização"
+
+#: controllers/previews_controller.php:237
+msgid "devcp_preview_updated_successfully"
+msgstr "Visualização atualizada com sucesso."
+
+#: views/developers/previews.thtml:120
+msgid "devcp_previews_a_another"
+msgstr "Adicionar outro Screenshot"
+
+#: views/developers/previews.thtml:96
+msgid "devcp_previews_a_delete"
+msgstr "Remover screenshot"
+
+#: views/developers/previews.thtml:95
+msgid "devcp_previews_a_replace"
+msgstr "Alterar Screenshot"
+
+#: views/developers/previews.thtml:126
+msgid "devcp_previews_a_update"
+msgstr "Atualizar Screenshots"
+
+#: views/developers/previews.thtml:115 views/developers/previews.thtml:124
+msgid "devcp_previews_add_new"
+msgstr "Adicionar um novo Screenshot"
+
+#. %s is a list of file extensions, e.g. ".png, .gif"
+#: views/developers/previews.thtml:116
+msgid "devcp_previews_add_select"
+msgstr ""
+"Selecione uma imagem para enviar abaixo. Imagens que são maiores do que o "
+"tamanho de 700 pixels de largura por 525 pixels de altura serão "
+"redimensionadas. Tipos de arquivos permitidos: %s"
+
+#: views/developers/previews.thtml:121
+msgid "devcp_previews_click_below"
+msgstr "Clicar abaixo em Atualizar Screenshots para enviar."
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/previews.thtml:102
+msgid "devcp_previews_click_update"
+msgstr ""
+"Clicar o botão de Atualizar Screenshots abaixo para gravar esta imagem. (<a %"
+"s>Cancelar?</a>)"
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/previews.thtml:107
+msgid "devcp_previews_error_message"
+msgstr ""
+"Este Screenshot será removido quando o botão Atualizar Screenshots for "
+"clicado abaixo. (<a %s>Cancelar?</a>)"
+
+#: views/previews/add.thtml:45
+msgid "devcp_previews_filetype_info"
+msgstr ""
+"Use o formulário abaixo para carregar um screenshot PNG, JPG ou GIF para seu "
+"Complemento. Imagens maiores que 700 pixels de largura e 525 pixels de "
+"altura serão redimensionadas automaticamente."
+
+#: views/previews/add.thtml:43
+msgid "devcp_previews_header_add"
+msgstr "Adicionar visualização"
+
+#: views/developers/previews.thtml:80
+msgid "devcp_previews_header_caption"
+msgstr "Sub-títulos do Screenshot"
+
+#: views/previews/edit.thtml:43
+msgid "devcp_previews_header_edit"
+msgstr "Editar visualização"
+
+#: views/developers/previews.thtml:93
+msgid "devcp_previews_label_default"
+msgstr "Screenshot Padrão"
+
+#: views/previews/add.thtml:54
+msgid "devcp_previews_label_file"
+msgstr "Arquivo de visualização"
+
+#: views/previews/add.thtml:59 views/previews/edit.thtml:50
+msgid "devcp_previews_label_makedefault"
+msgstr "Tornar esta a imagem de visualização padrão"
+
+#: views/developers/previews.thtml:100
+msgid "devcp_previews_label_new"
+msgstr "Nova imagem:"
+
+#: views/developers/previews.thtml:118
+msgid "devcp_previews_label_upload"
+msgstr "Enviar Screenshot: "
+
+#: views/developers/previews.thtml:50
+msgid "devcp_previews_notice_error"
+msgstr "Um ou mais Screenshots não foram gravados."
+
+#: views/developers/previews.thtml:47
+msgid "devcp_previews_notice_success"
+msgstr "Seus Screenshots foram gravados com sucesso."
+
+#: views/developers/previews.thtml:59
+msgid "devcp_previews_p_screenshots"
+msgstr ""
+"Os Screenshots de Demonstração do seu Complemento estão mostrados abaixo. "
+"Você poderá fazer mudanças para os sub-títulos ou imagens abaixo. O "
+"Screenshot padrão é o screenshot que será apresentado próximo ao deu "
+"Complemento nos resultados da busca e nas listagens."
+
+#: views/previews/edit.thtml:55
+msgid "devcp_previews_submit_delete"
+msgstr "Excluír visualização"
+
+#: views/previews/edit.thtml:55
+msgid "devcp_previews_submit_delete_confirm"
+msgstr "Tem certeza de que deseja excluír esta visualização?"
+
+#: views/previews/edit.thtml:54
+msgid "devcp_previews_submit_edit"
+msgstr "Editar visualização"
+
+#: views/previews/add.thtml:63
+msgid "devcp_previews_submit_upload"
+msgstr "Carregar visualização"
+
+#: views/developers/previews.thtml:78
+msgid "devcp_previews_thumbnail"
+msgstr "Thumbnail"
+
+#. %s is the add-on name.
+#: views/developers/previews.thtml:44
+msgid "devcp_previews_title"
+msgstr "%s Preview Manager"
+
+#: views/developers/uploader.thtml:74
+msgid "devcp_review_agreement_please"
+msgstr ""
+"Por favor, revise e aceite os seguintes termos do desenvolvedor antes de "
+"prosseguir."
+
+#: views/elements/developers/rolecheck.thtml:42
+msgid "devcp_rolecheck_no_privs"
+msgstr ""
+"<span>Você não tem privilégios suficientes para fazer mudanças nesta página."
+"</span><br />Entre em contato com o Proprietário do Complemento caso precise "
+"fazer mudanças."
+
+#: controllers/developers_controller.php:1315
+msgid "devcp_several_hours"
+msgstr ""
+"Por favor entenda que algumas mudanças podem levar algumas horas para "
+"aparecer em todas as áreas do site."
+
+#: views/elements/developers/sidebar.thtml:52
+msgid "devcp_sidebar_a_dashboard"
+msgstr "Quadro"
+
+#. %s is a number
+#: views/elements/developers/statsbar.thtml:45
+#: views/developers/dashboard.thtml:79
+#, php-format
+msgid "devcp_statsbar_adu"
+msgstr "<em>%s</em> Usuários ativos por dia"
+
+#. %s is a number
+#: views/elements/developers/statsbar.thtml:41
+#: views/developers/dashboard.thtml:75
+#, php-format
+msgid "devcp_statsbar_total_downloads"
+msgstr "<em>%s</em> total de downloads"
+
+#. %s is a number
+#: views/elements/developers/statsbar.thtml:43
+#: views/developers/dashboard.thtml:77
+#, php-format
+msgid "devcp_statsbar_weekly_downloads"
+msgstr "<em>%s</em> downloads semanais"
+
+#: views/developers/addon_status_confirm.thtml:59
+msgid "devcp_status_confirm_active"
+msgstr ""
+"Ao marcar este Complemento como ativo ele será apresentado em todas as áreas "
+"públicas, incluindo resultados de busca e listagens de navegação. Ele estará "
+"disponível para para downloads a partir do site e poderá ser automaticamente "
+"transferido nas checagens de atualização dependendo do estado. Você poderá "
+"voltar aqui e desabilitar novamente quando lhe for conveniente."
+
+#: views/developers/addon_status_confirm.thtml:59
+msgid "devcp_status_confirm_active_sure"
+msgstr "Você tem certeza que quer marcar este Complemento como Ativo?"
+
+#: views/developers/addon_status_confirm.thtml:50
+msgid "devcp_status_confirm_header_sure"
+msgstr "Você tem certeza?"
+
+#: views/developers/addon_status_confirm.thtml:55
+msgid "devcp_status_confirm_inactive"
+msgstr ""
+"Marking this add-on inactive will prevent it from showing up in any public "
+"areas, including search and browse listings. It will not be downloadable "
+"from the website and will not be returned in client update checks. You will "
+"be able to return here and re-enable it at your convenience."
+
+#: views/developers/addon_status_confirm.thtml:55
+msgid "devcp_status_confirm_inactive_sure"
+msgstr "Are you sure you wish to mark this add-on inactive?'"
+
+#: views/developers/addon_status_confirm.thtml:74
+msgid "devcp_status_confirm_no"
+msgstr "No, cancel"
+
+#: views/developers/addon_status_confirm.thtml:67
+msgid "devcp_status_confirm_public"
+msgstr ""
+"Making this add-on public will make it available for anyone to download and "
+"will begin offering updates to existing users."
+
+#: views/developers/addon_status_confirm.thtml:67
+msgid "devcp_status_confirm_public_sure"
+msgstr "Are you sure you wish to make this add-on public?"
+
+#: views/developers/addon_status_confirm.thtml:63
+msgid "devcp_status_confirm_sandbox"
+msgstr ""
+"Moving this add-on back to the sandbox will require users to login before "
+"downloading and updates will no longer be offered to existing users. Because "
+"your add-on is currently public, you will be able to return here at any time "
+"to make it public again."
+
+#: views/developers/addon_status_confirm.thtml:63
+msgid "devcp_status_confirm_sandbox_sure"
+msgstr "Are you sure you wish to move this add-on to the sandbox?"
+
+#: views/developers/addon_status_confirm.thtml:73
+msgid "devcp_status_confirm_yes"
+msgstr "Yes, I'm Sure"
+
+#: views/developers/addon_status_nominate.thtml:46
+msgid "devcp_status_nominate_error_notice"
+msgstr ""
+"<span>A nomination message is required.</span><br />Please fill in the text "
+"box with the requested information and try again."
+
+#: views/developers/addon_status_nominate.thtml:55
+msgid "devcp_status_nominate_header"
+msgstr "Add-on Nomination"
+
+#: views/developers/dashboard.thtml:85
+msgid "devcp_summary_lastversion"
+msgstr "Última versão:"
+
+#. %s is the add-on name.
+#: views/developers/addon_edit.thtml:43
+#: views/developers/addon_edit_authors.thtml:44
+#: views/developers/versions_delete.thtml:43
+#: views/developers/addon_edit_properties.thtml:44
+#: views/developers/addon_edit_descriptions.thtml:44
+#: views/developers/versions_edit.thtml:44
+#: views/developers/addon_edit_categories.thtml:43
+#: views/developers/versions.thtml:43
+msgid "devcp_title_edit_addon"
+msgstr "Editar %s"
+
+#. title attribute for a javascript link that pops up a help dialog.
+#: views/elements/translationbox.thtml:68
+msgid "devcp_transbox_a_title_help"
+msgstr "Ajuda (não sairá da página)"
+
+#: views/elements/translationbox.thtml:68
+msgid "devcp_transbox_alt_help"
+msgstr "Ajuda"
+
+#. %1$s is <span>17</span>, %2$s is 42.
+#: views/elements/translationbox.thtml:101
+msgid "devcp_transbox_chars_used"
+msgstr "Caracteres utilizados: %1$s / %2$s"
+
+#: views/elements/translationbox.thtml:132
+msgid "devcp_transbox_delete_sure"
+msgstr "Você está certo que desejar remover esta tradução?"
+
+#. %s is a locale, like en-US.
+#: views/elements/translationbox.thtml:143
+msgid "devcp_transbox_help_header_tabs"
+msgstr "O que são estas abas %s ?"
+
+#: views/elements/translationbox.thtml:145
+msgid "devcp_transbox_help_header_what"
+msgstr "E se eu não tenho outras traduções?"
+
+#: views/elements/translationbox.thtml:147
+msgid "devcp_transbox_help_hide"
+msgstr "Esconder ajuda"
+
+#: views/elements/translationbox.thtml:146
+msgid "devcp_transbox_help_if"
+msgstr ""
+"Se um usuário navegar o site e uma tradução não está disponível no idioma "
+"dele,o sistema irá apresentar o idioma padrão, que encontra-se especificado "
+"na área de Edição de Propriedades do Complemento. Se você não tem outras "
+"traduções, simplesmente coloque o que você conseguir na tradução padrão, que "
+"deverá ser o idioma que você fala."
+
+#: views/elements/translationbox.thtml:144
+msgid "devcp_transbox_help_transbox"
+msgstr ""
+"Este é um <i>Campo de Tradução</i>. Ele permite que você possa traduzir um "
+"campo específico para outros idiomas no qual você tem traduções. Vocé poderá "
+"adicionar, editar, e remover traduções utilizando as abas de tradução."
+
+#: views/elements/translationbox.thtml:85
+msgid "devcp_transbox_img_add_trans"
+msgstr "Adicionar Tradução"
+
+#: views/elements/translationbox.thtml:86
+msgid "devcp_transbox_img_remove_trans"
+msgstr "Remover Tradução"
+
+#: views/elements/translationbox.thtml:123
+msgid "devcp_transbox_input_add_all"
+msgstr "Adicionar Idiomas para Todos"
+
+#: views/elements/translationbox.thtml:122
+msgid "devcp_transbox_input_add_locale"
+msgstr "Adicionar Idiomas"
+
+#: views/elements/translationbox.thtml:124
+#: views/elements/translationbox.thtml:135
+msgid "devcp_transbox_input_cancel"
+msgstr "Cancelar"
+
+#: views/elements/translationbox.thtml:134
+msgid "devcp_transbox_input_delete"
+msgstr "Remover isto"
+
+#: views/elements/translationbox.thtml:113
+msgid "devcp_transbox_select_locale"
+msgstr "Selecionar o idioma para a tradução a ser adicionada:"
+
+#. %1$s and %2$s are GUIDs.
+#: controllers/developers_controller.php:343
+msgid "devcp_update_addon_guid_error"
+msgstr ""
+"O GUID do Complemento utilizado neste arquivo (%1$s) não bate com o GUID "
+"existente para este Complemento (%2$s)."
+
+#: controllers/developers_controller.php:334
+msgid "devcp_update_addon_priv_error"
+msgstr "Você não tem privilégios suficientes para atualizar este Complemento."
+
+#. %1$s is a version number, %2$s is an add-on ID.
+#: controllers/developers_controller.php:399
+msgid "devcp_update_addon_version_belong_error"
+msgstr "A versão especificada (%1$s) não pertence ao Complemento (%2$s)."
+
+#. %1$s is a version number, maybe 1.1.
+#. %2$s is a URL.
+#: controllers/developers_controller.php:351
+msgid "devcp_update_addon_version_exists_error"
+msgstr ""
+"O número da versão enviada (%1$s) já existe para este Complemento. Se você "
+"está tentando adicionar outro arquivo nesta versão, <a href=\"%2$s\">clique "
+"aqui</a>."
+
+#. %1$s and %2$s are version numbers.
+#: controllers/developers_controller.php:405
+msgid "devcp_update_addon_version_match_error"
+msgstr ""
+"A versão enviada de número (%1$s) não bate com a versão existente de número "
+"(%2$s)."
+
+#: views/developers/uploader.thtml:68
+msgid "devcp_uploader_a_start"
+msgstr "Iniciar"
+
+#: views/developers/uploader.thtml:137
+msgid "devcp_uploader_ajax_loading"
+msgstr "Enviando arquivo..."
+
+#: views/developers/uploader.thtml:82
+msgid "devcp_uploader_button_agree"
+msgstr "Agree and continue"
+
+#: views/developers/uploader.thtml:157
+msgid "devcp_uploader_button_edit"
+msgstr "Editar meu Complemento"
+
+#: views/developers/uploader.thtml:158
+msgid "devcp_uploader_button_later"
+msgstr "Vou completar meu Complemento depois."
+
+#: views/developers/uploader.thtml:168
+msgid "devcp_uploader_button_release"
+msgstr "Adicionar notas de versão"
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/uploader.thtml:156
+msgid "devcp_uploader_created_results"
+msgstr ""
+"<p>Your add-on listing has been successfully created. The basic information "
+"obtained from your uploaded file has been stored, but there's a lot more to "
+"your listing that can be customized.</p><p>Your add-on is currently marked "
+"as <strong>Incomplete</strong>. In order to complete your add-on, you'll "
+"need to make sure it has an accurate name, summary, and description, as well "
+"as at least one selected category. You can edit your add-on's information "
+"using the link below and check the status of your add-on at any time on the "
+"<a %s>status page</a>."
+
+#: views/developers/uploader.thtml:143
+msgid "devcp_uploader_error_correct"
+msgstr "Please correct this problem and upload your file again."
+
+#. %1$s is a version number, %2$s is a status, e.g Public or Incomplete.
+#: views/developers/uploader.thtml:175
+msgid "devcp_uploader_file_created"
+msgstr ""
+"Your new file has been added to version %1$s and is currently marked as %2$s."
+
+#: views/developers/uploader.thtml:154
+msgid "devcp_uploader_header_created"
+msgstr "Add-on Created!"
+
+#: views/developers/uploader.thtml:141
+msgid "devcp_uploader_header_error"
+msgstr "Oops! There seems to be a problem with this file..."
+
+#: views/developers/uploader.thtml:173
+msgid "devcp_uploader_header_file_added"
+msgstr "File Added!"
+
+#: views/developers/uploader.thtml:66
+msgid "devcp_uploader_header_how"
+msgstr "How does it all work?"
+
+#. %s is the version number, e.g. 3.2.
+#: views/developers/uploader.thtml:163
+msgid "devcp_uploader_header_update_created"
+msgstr "Version %s Created"
+
+#: views/developers/uploader.thtml:117
+msgid "devcp_uploader_header_upload"
+msgstr "Upload Your File"
+
+#: views/developers/uploader.thtml:67
+msgid "devcp_uploader_how"
+msgstr ""
+"<p>Thanks for your interest in submitting your add-on to Mozilla Add-ons. "
+"Hosting your add-on on Mozilla Add-ons is the easiest way to handle "
+"distribution of your add-on. Here's what you'll get:</p><ul><li>Each add-on "
+"will have a public display page with information you provide, such as a "
+"brief summary of the add-on's functionality, an optional longer description, "
+"and a showcase of preview screenshots of your add-on.</li><li>Your add-on "
+"will appear in search and browse listings across the site, and even in the "
+"Add-ons Manager of Firefox 3.</li><li>We'll take care of hosting all of your "
+"downloads and providing automatic updates to users when you upload a new "
+"version.</li><li>You'll have access to a statistics dashboard with detailed "
+"information about your user base.</li></ul><p>Add-ons hosted on the site "
+"must be reviewed by a Mozilla Add-ons Editor before they will have all of "
+"the features listed above. If you're ready to start the process and have "
+"your add-on package ready for upload, just click on Get Started below!</p>"
+
+#: views/developers/uploader.thtml:125
+msgid "devcp_uploader_label_platformtype"
+msgstr "Supported Platforms:"
+
+#: views/developers/uploader.thtml:124
+msgid "devcp_uploader_label_upload_field"
+msgstr "Add-on File: "
+
+#: controllers/components/developers.php:1221
+msgid "devcp_uploader_option_other"
+msgstr "Other"
+
+#. %1$s is a number, %2$s is href="..." and should stay in the <a> tag.
+#: views/developers/uploader.thtml:176
+msgid "devcp_uploader_p_pending_file"
+msgstr ""
+"The new file will be available to the public as soon as an editor is able to "
+"review it. There are currently %1$s other add-ons in the queue. Want to be "
+"reviewed faster? Consider <a %2$s>becoming an editor</a>."
+
+#. %1$s is a number, %2$s is href="..." and should stay in the <a> tag.
+#: views/developers/uploader.thtml:166
+msgid "devcp_uploader_p_pending_version"
+msgstr ""
+"The new version will be available to the public as soon as an editor is able "
+"to review it. There are currently %1$s other add-ons in the queue. Want to "
+"be reviewed faster? Consider <a %2$s>becoming an editor</a>."
+
+#. %s is a status, e.g Public or Incomplete.
+#: views/developers/uploader.thtml:165
+msgid "devcp_uploader_p_update_created"
+msgstr "Your new version has been created and is currently marked as %s."
+
+#. %1$s is href="..." and should stay in the 'Versions and Files' <a> tag.
+#. %2$s is href="..." and should stay in the 'current status' <a> tag.
+#: views/developers/uploader.thtml:177
+msgid "devcp_uploader_p_update_file"
+msgstr ""
+"View your new file in the <a %1$s>Versions and Files page</a>, check out "
+"your add-on's <a %2$s>current status</a>, or <b>add release notes</b> by "
+"clicking the button below (highly recommended)."
+
+#. %1$s is href="..." and should stay in the 'Versions and Files' <a> tag.
+#. %2$s is href="..." and should stay in the 'current status' <a> tag.
+#: views/developers/uploader.thtml:167
+msgid "devcp_uploader_p_update_version"
+msgstr ""
+"View your new version in the <a %1$s>Versions and Files page</a>, check out "
+"your add-on's <a %2$s>current status</a>, or <b>add release notes</b> by "
+"clicking the button below (highly recommended)."
+
+#: views/developers/uploader.thtml:118
+msgid "devcp_uploader_p_upload"
+msgstr ""
+"Upload your add-on file using the form below. If you have multiple, platform-"
+"specific files to upload, choose a single file and then upload the others "
+"using the Versions and Files Manager."
+
+#: views/developers/uploader.thtml:125
+msgid "devcp_uploader_platformtype_all"
+msgstr "All"
+
+#: views/developers/uploader.thtml:126
+msgid "devcp_uploader_platformtype_specific"
+msgstr "Specific:"
+
+#. Used as first item in a <select>.
+#: controllers/components/developers.php:1185
+msgid "devcp_uploader_please_choose"
+msgstr "Please Choose..."
+
+#. %1$s is the add-on name, %2$s is the version number.
+#: views/developers/uploader.thtml:57
+msgid "devcp_uploader_title_file"
+msgstr "Adicionar arquivo ao %1$s %2$s"
+
+#: views/developers/uploader.thtml:50
+msgid "devcp_uploader_title_submit"
+msgstr "Enviar novo Complemento"
+
+#. %s is the add-on name.
+#: views/developers/uploader.thtml:54
+msgid "devcp_uploader_title_update"
+msgstr "Atualizar %s"
+
+#. %s is a full <a> tag
+#: controllers/developers_controller.php:503
+#, php-format
+msgid "devcp_valid_app_reference"
+msgstr "Por favor, veja %s para referência."
+
+#. This is the text in the <a> tag for devcp_valid_app_reference. This should be
+#. fixed.
+#: controllers/developers_controller.php:503
+msgid "devcp_valid_app_reference_linktext"
+msgstr "esta página"
+
+#: controllers/developers_controller.php:581
+msgid "devcp_verify_author_error"
+msgstr "Conta não encontrada para o endereço de email informado."
+
+#: controllers/developers_controller.php:553
+msgid "devcp_verify_search_engine_error"
+msgstr ""
+"Either the XML is invalid or required fields are missing. Please <a href="
+"\"https://developer.mozilla.org/en/Creating_OpenSearch_plugins_for_Firefox"
+"\">read the documentation</a>, verify your add-on, and try again."
+
+#: views/developers/versions.thtml:75
+msgid "devcp_versions_a_cancel"
+msgstr "Cancelar"
+
+#: views/developers/versions.thtml:79
+msgid "devcp_versions_a_delete"
+msgstr "Remover Versão"
+
+#: views/developers/versions.thtml:74
+msgid "devcp_versions_a_empty"
+msgstr "Remover Versão Nula"
+
+#: views/developers/versions.thtml:71
+msgid "devcp_versions_a_remove"
+msgstr "Remover?"
+
+#: views/developers/versions.thtml:91
+msgid "devcp_versions_add"
+msgstr "Adicionar Nova Versão"
+
+#: views/developers/versions_delete.thtml:58
+msgid "devcp_versions_delete_a_cancel"
+msgstr "Cancelar"
+
+#: views/developers/versions_delete.thtml:56
+msgid "devcp_versions_delete_a_delete"
+msgstr "Remover Versão"
+
+#. Followed by a list of reviews and files that will be removed.
+#: views/developers/versions_delete.thtml:50
+msgid "devcp_versions_delete_also"
+msgstr "Também serão removidos:"
+
+#: views/developers/versions_delete.thtml:53
+msgid "devcp_versions_delete_files"
+msgid_plural "devcp_versions_delete_files"
+msgstr[0] "%s arquivo"
+msgstr[1] "%s arquivos"
+
+#. %s is the version number.
+#: views/developers/versions_delete.thtml:48
+msgid "devcp_versions_delete_header"
+msgstr "Remover Versão %s?"
+
+#: views/developers/versions_delete.thtml:52
+msgid "devcp_versions_delete_reviews"
+msgid_plural "devcp_versions_delete_reviews"
+msgstr[0] "%s revisão"
+msgstr[1] "%s revisões"
+
+#. %s is the version number.
+#: views/developers/versions_delete.thtml:49
+msgid "devcp_versions_delete_sure"
+msgstr "Você tem certeza que quer permanentemente remover a versão %s?"
+
+#: views/developers/versions_edit.thtml:102
+#: views/developers/versions_edit.thtml:155
+msgid "devcp_versions_edit_a_cancel"
+msgstr "Cancelar"
+
+#: views/developers/versions_edit.thtml:101
+msgid "devcp_versions_edit_a_delete"
+msgstr "Remover Arquivo"
+
+#: views/developers/versions_edit.thtml:165
+msgid "devcp_versions_edit_a_new_app"
+msgstr "Adicionar nova aplicação"
+
+#: views/developers/versions_edit.thtml:154
+msgid "devcp_versions_edit_a_remove_app"
+msgstr "Remover Aplicação"
+
+#: views/developers/versions_edit.thtml:114
+msgid "devcp_versions_edit_add"
+msgstr "Adicionar Novo Arquivo"
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/versions_edit.thtml:121
+msgid "devcp_versions_edit_adjust"
+msgstr ""
+"Ajustando informações da aplicação irá permitir que usuários instalem seu "
+"Complementomesmo que o install.rdf do pacote indique que o Complemento é "
+"incompatível.<a %s>Veja lista de aplicações suportadas</a>"
+
+#: views/developers/versions_edit.thtml:153
+msgid "devcp_versions_edit_compat_sure"
+msgstr ""
+"Você tem <b>certeza</b> que quer remover a compatibilidade para esta "
+"aplicação?"
+
+#: views/developers/versions_edit.thtml:100
+msgid "devcp_versions_edit_delete_sure"
+msgstr "Você tem <b>certeza</b> que quer remover este arquivo permanentemente?"
+
+#: views/developers/versions_edit.thtml:203
+msgid "devcp_versions_edit_header_approval"
+msgstr "Informações da Aprovação"
+
+#: views/developers/versions_edit.thtml:120
+msgid "devcp_versions_edit_header_compat"
+msgstr "Aplicações compatíveis"
+
+#: views/developers/versions_edit.thtml:74
+msgid "devcp_versions_edit_header_file"
+msgstr "Informações de Arquivo"
+
+#: views/developers/versions_edit.thtml:189
+msgid "devcp_versions_edit_header_license"
+msgstr "License"
+
+#. %s is the version number.
+#: views/developers/versions_edit.thtml:53
+msgid "devcp_versions_edit_header_manage"
+msgstr "Gerenciar Versão %s"
+
+#: views/developers/versions_edit.thtml:212
+msgid "devcp_versions_edit_header_notes"
+msgstr "Notas da Aprovação"
+
+#: views/developers/versions_edit.thtml:98
+msgid "devcp_versions_edit_img_delete"
+msgstr "Remover Arquivo"
+
+#. %1$s is the file id, e.g. 18723.
+#. %2$s is the platform name, e.g. ALL or Windows.
+#. %3$s is the _('date) created.
+#. %4$s is the status, e.g. "In Sandbox" or "Public".
+#. %5$s is the _('date') status was changed.
+#: views/developers/versions_edit.thtml:208
+msgid "devcp_versions_edit_li_file"
+msgstr "Arquivo %1$s (%2$s) criado em %3$s e alterado para %4$s em %5$s"
+
+#: views/developers/versions_edit.thtml:190
+msgid "devcp_versions_edit_license_description"
+msgstr ""
+"Please select the appropriate license for your add-on. This license "
+"specifies the rights you grant on your source code."
+
+#: views/developers/versions_edit.thtml:111
+msgid "devcp_versions_edit_no_files"
+msgstr "Arquivos não encontrados."
+
+#: views/developers/versions_edit.thtml:213
+msgid "devcp_versions_edit_optional"
+msgstr "Informações opcionais para o Editor que irá revisar esta versão."
+
+#: views/developers/versions_edit.thtml:151
+msgid "devcp_versions_edit_remove_compat"
+msgstr "Remover Compatibilidade de Aplicação"
+
+#: views/developers/versions_edit.thtml:167
+msgid "devcp_versions_edit_select_app"
+msgstr "Por favor selecione uma aplicação"
+
+#: views/developers/versions_edit.thtml:78
+msgid "devcp_versions_edit_th_file"
+msgstr "Arquivo"
+
+#: views/developers/versions_edit.thtml:79
+msgid "devcp_versions_edit_th_platform"
+msgstr "Plataforma"
+
+#: views/developers/versions_edit.thtml:80
+msgid "devcp_versions_edit_th_size"
+msgstr "Tamanho"
+
+#: views/developers/versions_edit.thtml:81
+msgid "devcp_versions_edit_th_status"
+msgstr "Estado"
+
+#: views/developers/versions_edit.thtml:183
+msgid "devcp_versions_edit_transbox_releasenotes_description"
+msgstr ""
+"Informações sobre mudanças neste lançamento, novos recursos, bugs "
+"conhecidos, e outras informações úteis relacionadas com esta versão/"
+"lançamento. Estas informações estarão disponíveis para usuários que "
+"atualizarem os Complementos utilizando a tela de gerenciamento de "
+"Complementos do Firefox 3."
+
+#: views/developers/versions_edit.thtml:182
+msgid "devcp_versions_edit_transbox_releasenotes_name"
+msgstr "Notas da Versão"
+
+#: views/developers/versions_edit.thtml:164
+msgid "devcp_versions_edit_unsaved_compat"
+msgstr ""
+"<strong>Você tem mudanças não arquivadas.</strong> A compatibilidade não "
+"será removida até que você clique em Atualizar Versão abaixo."
+
+#: views/developers/versions_edit.thtml:113
+msgid "devcp_versions_edit_unsaved_files"
+msgstr ""
+"<strong>Você tem mudanças não arquivadas.</strong> Arquivos não serão "
+"removidos até que você clique em Atualizar Versão abaixo."
+
+#: views/developers/versions_edit.thtml:218
+msgid "devcp_versions_edit_update"
+msgstr "Atualizar Versões"
+
+#: views/developers/versions.thtml:49
+msgid "devcp_versions_header_manage"
+msgstr "Gerenciar Versões e Arquivos"
+
+#: views/developers/versions.thtml:87
+msgid "devcp_versions_no_versions"
+msgstr "Sem versões."
+
+#. %s is a version number, base 10.
+#: views/developers/versions.thtml:46
+msgid "devcp_versions_notice_success"
+msgstr "Versão %s removida com sucesso."
+
+#: views/developers/versions.thtml:73
+msgid "devcp_versions_p_remove"
+msgstr ""
+"Esta versão não tem arquivos associados com ela e pode ser removida. Você "
+"deseja remover esta versão?"
+
+#: views/developers/versions.thtml:58
+msgid "devcp_versions_th_created"
+msgstr "Criado"
+
+#: views/developers/versions.thtml:57
+msgid "devcp_versions_th_status"
+msgstr "Status"
+
+#: views/developers/versions.thtml:56
+msgid "devcp_versions_th_version"
+msgstr "Versão"
+
+#: controllers/downloads_controller.php:91
+msgid "downloads_disable_warning"
+msgstr "Este Complemento está desativado"
+
+#: controllers/components/editors.php:57
+msgid "editor_review_error_addon_not_nominated"
+msgstr "Este Complemento não foi nomeado."
+
+#: controllers/components/editors.php:213
+msgid "editor_review_error_file_not_pending"
+msgstr "Este arquivo não está com revisão pendente."
+
+#. Actions are, for example: approving or rejecting
+#: controllers/components/editors.php:79
+#: controllers/components/editors.php:182
+msgid "editor_review_error_no_action"
+msgstr "Por favor selecione uma ação de revisão."
+
+#: controllers/components/editors.php:192
+msgid "editor_review_error_no_applications"
+msgstr "Por favor entre com as aplicações que você testou."
+
+#. Comments are required when an editor approves or rejects an add-on.
+#: controllers/components/editors.php:84
+#: controllers/components/editors.php:187
+msgid "editor_review_error_no_comments"
+msgstr "Por favor entre com os comentários da revisão."
+
+#: controllers/components/editors.php:161
+msgid "editor_review_error_no_files"
+msgstr "Por favor selecione ao menos um arquivo para revisar."
+
+#: controllers/components/editors.php:197
+msgid "editor_review_error_no_operating_system"
+msgstr "Por favor entre com o sistema operacional que você testou."
+
+#: views/editors/logs.thtml:51
+msgid "editorcp_logs_button_filter"
+msgstr "Filtrar"
+
+#: views/editors/logs.thtml:44
+msgid "editorcp_logs_filter_by"
+msgstr "Filtrar por tipo/ação"
+
+#: views/editors/logs.thtml:42 controllers/editors_controller.php:964
+msgid "editorcp_logs_page_heading"
+msgstr "Log de eventos"
+
+#: views/elements/developers/editorsmenu.thtml:60
+msgid "editorcp_menu_eventlog_link"
+msgstr "Log de eventos"
+
+#: views/elements/developers/editorsmenu.thtml:62
+msgid "editorcp_menu_mainpage_link"
+msgstr "Voltar para principal"
+
+#: views/elements/developers/editorsmenu.thtml:61
+msgid "editorcp_menu_reviewlog_link"
+msgstr "Log de revisões"
+
+#: views/elements/developers/editorsmenu.thtml:55
+msgid "editorcp_menu_summary_link"
+msgstr "Sumário do editor"
+
+#: views/elements/developers/editorsmenu.thtml:52
+msgid "editorcp_menu_title"
+msgstr "Ferramentas do editor"
+
+#: views/editors/reviewlog.thtml:49
+msgid "editorcp_reviewlog_button_filter"
+msgstr "Filtrar"
+
+#: views/editors/reviewlog.thtml:58
+msgid "editorcp_reviewlog_column_action"
+msgstr "Ação"
+
+#: views/editors/reviewlog.thtml:56
+msgid "editorcp_reviewlog_column_addon"
+msgstr "Complemento"
+
+#: views/editors/reviewlog.thtml:55
+msgid "editorcp_reviewlog_column_date"
+msgstr "Data"
+
+#: views/editors/reviewlog.thtml:57
+msgid "editorcp_reviewlog_column_editor"
+msgstr "Editor"
+
+#: views/editors/reviewlog.thtml:94
+msgid "editorcp_reviewlog_comments_hide"
+msgstr "Ocultar comentários"
+
+#: views/editors/reviewlog.thtml:93
+msgid "editorcp_reviewlog_comments_show"
+msgstr "Mostrar comentários"
+
+#. %1$s and %2$s are full <input> tags for dates
+#: views/editors/reviewlog.thtml:45
+#, php-format
+msgid "editorcp_reviewlog_entries_between"
+msgstr "Ver as entradas entre %s e %s"
+
+#: views/editors/reviewlog.thtml:104
+msgid "editorcp_reviewlog_none_found"
+msgstr "Não foram encontradas revisões para este período."
+
+#: views/editors/reviewlog.thtml:42
+msgid "editorcp_reviewlog_page_heading"
+msgstr "Log da revisão"
+
+#: views/editors/summary.thtml:61
+msgid "editorcp_summary_monthreviews_heading"
+msgstr "Revisões mensais"
+
+#: views/editors/summary.thtml:77
+msgid "editorcp_summary_neweditors_heading"
+msgstr "Novos editores"
+
+#: views/editors/summary.thtml:42
+msgid "editorcp_summary_page_heading"
+msgstr "Sumário do editor"
+
+#: views/editors/summary.thtml:94
+msgid "editorcp_summary_recentactivity_heading"
+msgstr "Atividades recentes dos editores"
+
+#: views/editors/summary.thtml:45
+msgid "editorcp_summary_totalreviews_heading"
+msgstr "Total de revisões"
+
+#: controllers/editors_controller.php:248
+#: controllers/editors_controller.php:249
+msgid "editors_addon_review_pagetitle"
+msgstr "Revisar Complemento"
+
+#: controllers/editors_controller.php:349
+msgid "editors_error_js-formerror"
+msgstr "Por favor, preencha os seguintes campos:"
+
+#: controllers/editors_controller.php:350
+msgid "editors_error_review_one_file"
+msgstr "Por favor, selecione pelo menos um arquivo para revisar."
+
+#: controllers/editors_controller.php:274
+msgid "editors_error_self_reviews_forbidden"
+msgstr "Não é permitido revisar seus próprios Complementos."
+
+#: controllers/editors_controller.php:699
+msgid "editors_external_software"
+msgstr "Software externo"
+
+#: views/editors/featured.thtml:120 views/editors/featured.thtml:121
+msgid "editors_featured_add_feature"
+msgstr "Adicionar característica"
+
+#: views/editors/featured.thtml:126
+msgid "editors_featured_add_feature_submit"
+msgstr "Adicionar"
+
+#: views/editors/featured.thtml:49 controllers/editors_controller.php:832
+#: controllers/editors_controller.php:848
+msgid "editors_featured_addon_add_failure"
+msgstr "Falha ao adicionar característica."
+
+#: controllers/editors_controller.php:851
+msgid "editors_featured_addon_add_success"
+msgstr "Característica adicionada com sucesso."
+
+#: views/editors/featured.thtml:50 controllers/editors_controller.php:839
+#: controllers/editors_controller.php:868
+#: controllers/editors_controller.php:886
+msgid "editors_featured_addon_edit_failure"
+msgstr "Falha ao editar a característica."
+
+#: views/editors/featured.thtml:51 controllers/editors_controller.php:888
+msgid "editors_featured_addon_edit_success"
+msgstr "Característica editada com sucesso."
+
+#: views/editors/featured.thtml:53 controllers/editors_controller.php:861
+msgid "editors_featured_addon_invalid_locale"
+msgstr "Um ou mais idiomas são invalidos."
+
+#: views/editors/featured.thtml:52 controllers/editors_controller.php:906
+msgid "editors_featured_addon_remove_failure"
+msgstr "Falha ao remover a característica."
+
+#: controllers/editors_controller.php:901
+msgid "editors_featured_addon_remove_success"
+msgstr "Característica removida com sucesso."
+
+#: controllers/editors_controller.php:915
+#: controllers/editors_controller.php:917
+msgid "editors_featured_addons_pagetitle"
+msgstr "Complementos em destaque"
+
+#: views/editors/featured.thtml:54 views/editors/featured.thtml:107
+msgid "editors_featured_edit_feature_submit"
+msgstr "Ir"
+
+#: views/editors/featured.thtml:90 views/editors/featured.thtml:91
+msgid "editors_featured_remove_feature"
+msgstr "Remover característica"
+
+#: views/editors/queue.thtml:46
+msgid "editors_filter_queue"
+msgstr "Fila de filtros"
+
+#: views/editors/queue.thtml:182
+msgid "editors_helpful_links"
+msgstr "Endereços úteis"
+
+#: views/editors/queue.thtml:182
+msgid "editors_link_guide"
+msgstr "Guia do editor"
+
+#: views/editors/queue.thtml:182
+msgid "editors_link_policy"
+msgstr "Políticas de Uso dos Complemento"
+
+#: views/editors/queue.thtml:47
+msgid "editors_notice_filter_session"
+msgstr ""
+"Estes filtros irão permanecer para esta sessão ou até que sejam removidos."
+
+#. %1 is the queue mode
+#: views/editors/queue.thtml:177 views/admin/flagged_queue.thtml:89
+msgid "editors_notice_none_found"
+msgstr "Não existem Complementos %s para revisar."
+
+#: controllers/editors_controller.php:1040
+msgid "editors_one_day"
+msgstr "1 Dia"
+
+#: controllers/editors_controller.php:1048
+msgid "editors_one_hour"
+msgstr "1 hora"
+
+#: controllers/editors_controller.php:1056
+msgid "editors_one_minute"
+msgstr "1 minuto"
+
+#: controllers/editors_controller.php:64 controllers/editors_controller.php:73
+#: controllers/editors_controller.php:77
+msgid "editors_pagetitle"
+msgstr "Painel de controle do editor"
+
+#. %s is a comma separated list of platforms. Example: Windows, OS X
+#: controllers/editors_controller.php:680
+#: controllers/editors_controller.php:683
+#, php-format
+msgid "editors_platform_x_only"
+msgstr "apenas %s"
+
+#: controllers/editors_controller.php:695
+msgid "editors_pre-release"
+msgstr "Pré-distribuição"
+
+#. %1 is the app name
+#: views/editors/queue.thtml:131
+#, php-format
+msgid "editors_queue_app_compatibility"
+msgstr "Compatibilidade de %s"
+
+#: views/editors/queue.thtml:51
+#, fuzzy
+msgid "editors_queue_filter_label_addon"
+msgstr "Add-on or Author Email"
+
+#: views/editors/queue.thtml:72
+#, fuzzy
+msgid "editors_queue_filter_label_addontypes"
+msgstr "Add-on Types"
+
+#: views/editors/queue.thtml:56
+#, fuzzy
+msgid "editors_queue_filter_label_application"
+msgstr "Application"
+
+#: views/editors/queue.thtml:61
+#, fuzzy
+msgid "editors_queue_filter_label_maxversion"
+msgstr "Max. Version"
+
+#: views/editors/queue.thtml:78
+#, fuzzy
+msgid "editors_queue_filter_label_platforms"
+msgstr "Platforms"
+
+#: views/editors/queue.thtml:66
+#, fuzzy
+msgid "editors_queue_filter_label_submissionage"
+msgstr "Age of Submission (days)"
+
+#. %1$s is a number
+#: views/editors/queue.thtml:90
+#, fuzzy
+msgid "editors_queue_filter_result_count"
+msgid_plural "editors_queue_filter_result_count"
+msgstr[0] "Results of your filtered search: <strong>%1$s</strong> Add-on"
+msgstr[1] "Results of your filtered search: <strong>%1$s</strong> Add-ons"
+
+#: views/editors/queue.thtml:84
+msgid "editors_queue_submit_clean"
+msgstr "Limpar"
+
+#: views/editors/queue.thtml:83
+msgid "editors_queue_submit_filter"
+msgstr "Filtrar"
+
+#: controllers/editors_controller.php:133
+msgid "editors_queues_disabled"
+msgstr ""
+"Todas as filas de revisão estão desabilitadas. Verifique novamente mais "
+"tarde."
+
+#: views/editors/review.thtml:149
+msgid "editors_review_a_edit_item"
+msgstr "Edit Item"
+
+#: views/editors/review.thtml:146
+msgid "editors_review_a_item_history"
+msgstr "Item History"
+
+#: views/editors/review.thtml:148
+msgid "editors_review_a_item_homepage"
+msgstr "Item Homepage"
+
+#: views/editors/review.thtml:145
+msgid "editors_review_a_item_overview"
+msgstr "Item Overview"
+
+#: views/editors/review.thtml:147
+msgid "editors_review_a_previews"
+msgstr "Previews"
+
+#: controllers/editors_controller.php:345
+msgid "editors_review_action"
+msgstr "Ação de revisão"
+
+#: views/editors/review.thtml:159
+msgid "editors_review_action_info"
+msgstr "Request More Information"
+
+#: views/editors/review.thtml:157
+msgid "editors_review_action_public"
+msgstr "Publicar"
+
+#: views/editors/review.thtml:160
+msgid "editors_review_action_request_superreview"
+msgstr "Requisitar super-revisão"
+
+#: views/editors/review.thtml:158
+msgid "editors_review_action_sandbox"
+msgstr "Manter na sandbox"
+
+#: controllers/editors_controller.php:346
+msgid "editors_review_comments"
+msgstr "Comentários da revisão"
+
+#: views/editors/review.thtml:182
+msgid "editors_review_details_info_request"
+msgstr ""
+"Utilize este formulário para pedir mais informações para o autor(es). Eles "
+"irão receber um email e assim poderão responder aqui. Você será notificado "
+"por email quando for respondido."
+
+#: views/editors/review.thtml:174
+msgid "editors_review_details_nominated_public"
+msgstr ""
+"Isto irá tornar o Complemento, sua versão e arquivos mais recentes, "
+"públicos. Versões futuras irão para a sandbox até que sejam revistas por um "
+"editor."
+
+#: views/editors/review.thtml:177
+msgid "editors_review_details_nominated_sandbox"
+msgstr "Isto irá manter o Complemento na sandbox."
+
+#: views/editors/review.thtml:166
+msgid "editors_review_details_pending_public"
+msgstr ""
+"Isto irá aprovar a versão sandbox de um Complemento para que ele apareça na "
+"parte pública."
+
+#: views/editors/review.thtml:169
+msgid "editors_review_details_pending_sandbox"
+msgstr ""
+"Isto irá fazer com que a versão sandbox de um Complemento público permaneça "
+"na sandbox."
+
+#: views/editors/review.thtml:185
+msgid "editors_review_details_superreview"
+msgstr ""
+"Se você possui dúvidas sobre a segurança, questões de copyright ou outras "
+"dúvidas sobre este Complemento que um administrador deveria observar, entre "
+"com seus comentários na área abaixo. Eles serão enviados para "
+"administradores, não para o autor."
+
+#: views/editors/review.thtml:134
+msgid "editors_review_file_diff_link"
+msgstr "Comparar com a versão pública"
+
+#: views/editors/review.thtml:131
+msgid "editors_review_file_viewcontents_link"
+msgstr "Visualizar conteúdo"
+
+#: views/editors/review.thtml:65
+msgid "editors_review_header_authors"
+msgstr "Autores:"
+
+#: views/editors/review.thtml:79
+msgid "editors_review_header_categories"
+msgstr "Categorias:"
+
+#: views/editors/review.thtml:92
+msgid "editors_review_header_compatibility"
+msgstr "Compatibilidade:"
+
+#: views/editors/review.thtml:251
+msgid "editors_review_header_description"
+msgstr "Descrição"
+
+#: views/editors/review.thtml:275
+msgid "editors_review_header_devcomments"
+msgstr "Comentários do desenvolvedor"
+
+#: views/editors/review.thtml:263
+msgid "editors_review_header_eula"
+msgstr "EULA ( Termo de Utilização )"
+
+#: views/editors/review.thtml:115
+msgid "editors_review_header_files"
+msgstr "Arquivos:"
+
+#: views/editors/review.thtml:284
+msgid "editors_review_header_itemhistory"
+msgstr "Histórico do item"
+
+#: views/editors/review.thtml:232
+msgid "editors_review_header_nominationmessage"
+msgstr "Mensagem de indicação"
+
+#: views/editors/review.thtml:311
+msgid "editors_review_header_previews"
+msgstr "Visualizações"
+
+#: views/editors/review.thtml:269
+msgid "editors_review_header_privacy"
+msgstr "Políticas de privacidade"
+
+#. %1 is the add-on name and version
+#: views/editors/review.thtml:56
+#, php-format
+msgid "editors_review_header_review"
+msgstr "Revisão %s"
+
+#: views/editors/review.thtml:239
+msgid "editors_review_header_reviewernotes"
+msgstr "Notas para o revisor"
+
+#: views/editors/review.thtml:245
+msgid "editors_review_header_summary"
+msgstr "Sumário"
+
+#: views/editors/review.thtml:257
+msgid "editors_review_header_versionnotes"
+msgstr "Notas da versão"
+
+#. a noun: shown in an add-on's editor review history
+#: views/elements/developers/editors_review_history_item.thtml:80
+msgid "editors_review_history_info_reply"
+msgstr "Resposta"
+
+#: views/elements/developers/editors_review_history_item.thtml:78
+msgid "editors_review_history_info_request"
+msgstr "Pedido de Informações"
+
+#: views/elements/developers/editors_review_history_item.thtml:62
+#: views/editors/reviewlog.thtml:77
+msgid "editors_review_history_nominated_adminreview"
+msgstr "Revisão do administrador"
+
+#: views/elements/developers/editors_review_history_item.thtml:56
+#: views/editors/reviewlog.thtml:71
+msgid "editors_review_history_nominated_approved"
+msgstr "Indicação aprovada/publicada"
+
+#: views/elements/developers/editors_review_history_item.thtml:59
+#: views/editors/reviewlog.thtml:74
+msgid "editors_review_history_nominated_denied"
+msgstr "Indicação negada/sandboxed"
+
+#: views/editors/review.thtml:303
+msgid "editors_review_history_nonefound"
+msgstr "Não foram encontradas entradas de revisões anteriores."
+
+#: views/elements/developers/editors_review_history_item.thtml:73
+#: views/editors/reviewlog.thtml:88
+msgid "editors_review_history_pending_adminreview"
+msgstr "Revisão do administrador"
+
+#: views/elements/developers/editors_review_history_item.thtml:67
+#: views/editors/reviewlog.thtml:82
+msgid "editors_review_history_pending_approved"
+msgstr "aprovado/público"
+
+#: views/elements/developers/editors_review_history_item.thtml:70
+#: views/editors/reviewlog.thtml:85
+msgid "editors_review_history_pending_denied"
+msgstr "negado/sandbox"
+
+#. link text in an add-on's editor review history, allowing to hide and show an information request's replies
+#. %1 is the number of replies
+#: views/elements/developers/editors_review_history_item.thtml:90
+msgid "editors_review_history_show_hide_replies"
+msgid_plural "editors_review_history_show_hide_replies"
+msgstr[0] "Mostrar/Esconder Respostas (%1$s)"
+msgstr[1] "Mostrar/Esconder Respostas (%1$s)"
+
+#: views/editors/review.thtml:208
+msgid "editors_review_label_applications"
+msgstr "aplicações:"
+
+#: views/editors/review.thtml:196
+msgid "editors_review_label_cannedresponse"
+msgstr "ou selecione uma resposta prévia:"
+
+#: views/editors/review.thtml:190
+msgid "editors_review_label_comments"
+msgstr "comentários:"
+
+#: views/editors/review.thtml:204
+msgid "editors_review_label_operating_systems"
+msgstr "Sistemas operacionais:"
+
+#: views/editors/review.thtml:285 views/editors/review.thtml:312
+msgid "editors_review_link_pagetop"
+msgstr "Topo"
+
+#: views/editors/review.thtml:141
+msgid "editors_review_mulitple_notice"
+msgstr ""
+"Notice: Only review more than one file if you have tested EVERY file you "
+"select."
+
+#: views/editors/review.thtml:51
+msgid "editors_review_next_link"
+msgstr "next &raquo;"
+
+#: views/editors/review.thtml:322
+msgid "editors_review_previews_notfound"
+msgstr "Não foram encontradas visualizações."
+
+#: views/editors/review.thtml:50
+msgid "editors_review_previous_link"
+msgstr "&laquo; prev"
+
+#: controllers/editors_controller.php:144
+#: controllers/editors_controller.php:146
+msgid "editors_review_queue_pagetitle"
+msgstr "Fila de revisões"
+
+#. %1 is the add-ons rank in the queue, %2 is the total queue length
+#: views/editors/review.thtml:47
+msgid "editors_review_rank_in_queue"
+msgstr "<strong># %1$s</strong> de %2$s na fila"
+
+#. %1 is the add-ons rank in the queue, %2 is the total queue length. Both numbers
+#: views/editors/review.thtml:45
+#, fuzzy
+msgid "editors_review_rank_in_queue_filtered"
+msgstr "<strong># %1$s</strong> of %2$s in queue (filtered)"
+
+#: views/editors/review.thtml:223
+msgid "editors_review_submit_process_action"
+msgstr "Ações para o processo"
+
+#: views/editors/review.thtml:293
+msgid "editors_review_th_action"
+msgstr "Ação"
+
+#: views/editors/review.thtml:294
+msgid "editors_review_th_comments"
+msgstr "Comentários"
+
+#: views/editors/review.thtml:291
+msgid "editors_review_th_date"
+msgstr "Data"
+
+#: views/editors/review.thtml:292
+msgid "editors_review_th_reviewer"
+msgstr "Revisor"
+
+#: views/editors/review.thtml:290
+msgid "editors_review_th_version_file"
+msgstr "versão/arquivo"
+
+#: views/editors/review.thtml:217
+msgid "editors_review_update_notify_once"
+msgstr ""
+"Me notifique a próxima vez que este Complemento for atualizado. (Para as "
+"atualizações seguintes não será notificado)"
+
+#: controllers/editors_controller.php:298
+msgid "editors_reviewed_successfully"
+msgstr "Revisão processada com sucesso."
+
+#: views/editors/reviews_queue.thtml:106
+msgid "editors_reviews_action_delete_review"
+msgstr "Remover revisão"
+
+#: views/editors/reviews_queue.thtml:104
+msgid "editors_reviews_action_keep"
+msgstr "Remover atributos; manter revisão"
+
+#: views/editors/reviews_queue.thtml:102
+msgid "editors_reviews_action_skip"
+msgstr "Pular"
+
+#: views/editors/reviews_queue.thtml:100
+msgid "editors_reviews_header_action"
+msgstr "Ação"
+
+#: views/editors/reviews_queue.thtml:67
+msgid "editors_reviews_in_reply_to"
+msgstr "Em resposta a:"
+
+#: controllers/editors_controller.php:748
+msgid "editors_reviews_processed"
+msgstr "Revisões processadas com sucesso!"
+
+#: views/editors/reviews_queue.thtml:117
+msgid "editors_reviews_queue_empty"
+msgstr "Não existem revisões para serem avaliadas."
+
+#: views/editors/reviews_queue.thtml:111
+msgid "editors_reviews_submit_process_reviews"
+msgstr "Revisões para o processo"
+
+#: controllers/editors_controller.php:691
+msgid "editors_site_specific"
+msgstr "Sites específicos"
+
+#: controllers/editors_controller.php:348
+msgid "editors_tested_app"
+msgstr "Aplicação testada"
+
+#: controllers/editors_controller.php:347
+msgid "editors_tested_os"
+msgstr "Sistemas operacionais testados"
+
+#: views/editors/queue.thtml:151
+msgid "editors_th_additional_info"
+msgstr "Informações adicionais"
+
+#: views/editors/featured.thtml:63 views/editors/queue.thtml:109
+#: views/admin/flagged_queue.thtml:53
+msgid "editors_th_addon"
+msgstr "Complemento"
+
+#: views/editors/queue.thtml:125
+msgid "editors_th_addontype"
+msgstr "Tipo"
+
+#: views/editors/featured.thtml:64
+msgid "editors_th_locales"
+msgstr "Restringir idiomas?"
+
+#: views/editors/queue.thtml:148
+msgid "editors_th_nomination_age"
+msgstr "Tempo na Fila"
+
+#: views/editors/queue.thtml:101 views/editors/queue.thtml:117
+#: views/editors/queue.thtml:144
+#, fuzzy
+msgid "editors_th_sort_ascending"
+msgstr "Ascending sort"
+
+#: views/editors/queue.thtml:105 views/editors/queue.thtml:121
+#: views/editors/queue.thtml:140
+#, fuzzy
+msgid "editors_th_sort_descending"
+msgstr "Descending sort"
+
+#. %s is a number
+#: controllers/editors_controller.php:1036
+#, php-format
+msgid "editors_x_days"
+msgstr "%s dias"
+
+#. %s is a number
+#: controllers/editors_controller.php:1044
+#, php-format
+msgid "editors_x_hours"
+msgstr "%s horas"
+
+#. %s is a number
+#: controllers/editors_controller.php:1052
+#, php-format
+msgid "editors_x_minutes"
+msgstr "%s minutos"
+
+#: views/errors/error401.thtml:50 controllers/components/simple_acl.php:81
+#: controllers/components/simple_acl.php:82
+#: controllers/components/simple_acl.php:83 controllers/components/amo.php:607
+#: controllers/components/amo.php:608 controllers/components/amo.php:609
+#: controllers/reviews_controller.php:353
+#: controllers/reviews_controller.php:485
+#: controllers/collections_controller.php:438
+#: controllers/collections_controller.php:496
+#: controllers/collections_controller.php:504
+#: controllers/collections_controller.php:971
+#: controllers/collections_controller.php:1034
+#: controllers/collections_controller.php:1077
+msgid "error_access_denied"
+msgstr "Acesso negado"
+
+#: views/errors/error401.thtml:52
+msgid "error_access_denied_message"
+msgstr "Você não tem autorização para ver esta página."
+
+#: controllers/collections_controller.php:1039
+#, fuzzy
+msgid "error_addon_exists"
+msgstr "Add-on already exists!"
+
+#: controllers/developers_controller.php:200
+#: controllers/developers_controller.php:593
+#: controllers/developers_controller.php:1016
+#: controllers/developers_controller.php:1429
+#: controllers/downloads_controller.php:95
+#: controllers/downloads_controller.php:102
+#: controllers/downloads_controller.php:164
+#: controllers/statistics_controller.php:135
+#: controllers/previews_controller.php:115
+#: controllers/previews_controller.php:206
+#: controllers/previews_controller.php:307
+#: controllers/reviews_controller.php:77
+#: controllers/reviews_controller.php:240
+#: controllers/reviews_controller.php:332
+#: controllers/reviews_controller.php:340 controllers/api_controller.php:123
+#: controllers/api_controller.php:759 controllers/addons_controller.php:131
+#: controllers/addons_controller.php:197
+#: controllers/addons_controller.php:1407
+#: controllers/addons_controller.php:1465
+#: controllers/addons_controller.php:1469
+#: controllers/addons_controller.php:1503
+#: controllers/editors_controller.php:265
+#: controllers/collections_controller.php:1041
+#: controllers/collections_controller.php:1074
+msgid "error_addon_notfound"
+msgstr "Complemento não encontrado!"
+
+#: controllers/files_controller.php:83 controllers/files_controller.php:196
+msgid "error_addon_notviewable"
+msgstr "Este Complemento não pode ser visualizado aqui."
+
+#: controllers/reviews_controller.php:246
+msgid "error_addon_selfreview"
+msgstr "Você não pode revisar seu próprio Complemento."
+
+#: controllers/addons_controller.php:970
+msgid "error_browse_no_addons"
+msgstr "Não existem Complementos nesta categoria!"
+
+#: controllers/api_controller.php:424
+msgid "error_collection_feed_notfound"
+msgstr "Add-on feed not found."
+
+#: views/users/register.thtml:65 views/users/edit.thtml:194
+msgid "error_email_invalid"
+msgstr "Este não é um endereço de email válido."
+
+#: views/users/pwreset.thtml:74 views/users/register.thtml:70
+#: views/users/register.thtml:80 views/users/register.thtml:86
+#: views/users/edit.thtml:105 views/users/edit.thtml:111
+#: views/users/edit.thtml:192 views/admin/users_edit.thtml:78
+#: views/admin/users_edit.thtml:83 views/reviews/add.thtml:80
+#: views/reviews/add.thtml:104
+msgid "error_field_required"
+msgstr "Este campo não pode ser vazio."
+
+#: controllers/files_controller.php:75 controllers/files_controller.php:93
+#: controllers/files_controller.php:96 controllers/files_controller.php:163
+#: controllers/files_controller.php:176 controllers/files_controller.php:185
+#: controllers/files_controller.php:204 controllers/editors_controller.php:412
+msgid "error_file_notfound"
+msgstr "Arquivo não encontrado!"
+
+#. %s is a filename
+#: controllers/editors_controller.php:430
+#, php-format
+msgid "error_file_x_notfound"
+msgstr "Erro de arquivo: %s não existe."
+
+#: views/collections/add.thtml:55 views/collections/edit.thtml:89
+#: views/users/register.thtml:54 views/users/edit.thtml:81
+#: views/reviews/add.thtml:70 controllers/groups_controller.php:80
+#: controllers/groups_controller.php:102
+msgid "error_formerrors"
+msgstr "Existem erros neste formulário. Favor corrigi-los e reenviar."
+
+#: views/users/register.thtml:109
+msgid "error_invalid_captcha"
+msgstr "As letras não conferem. Tente novamente!"
+
+#: views/users/register.thtml:100 views/users/edit.thtml:125
+#: views/admin/users_edit.thtml:101
+msgid "error_invalid_url"
+msgstr ""
+"Este endereço tem um formato inválido. Endereços válidos são do tipo http://"
+"example.com/minha_página."
+
+#. %s is a string representing what's missing. Example: file_id
+#: controllers/downloads_controller.php:65
+#: controllers/users_controller.php:185 controllers/users_controller.php:264
+#: controllers/users_controller.php:559 controllers/users_controller.php:653
+#: controllers/reviews_controller.php:71
+#: controllers/reviews_controller.php:234
+#: controllers/reviews_controller.php:325
+#: controllers/reviews_controller.php:473
+#: controllers/reviews_controller.php:475
+#: controllers/addons_controller.php:182
+#: controllers/addons_controller.php:1381
+#: controllers/addons_controller.php:1455
+#: controllers/collections_controller.php:266
+#: controllers/collections_controller.php:285
+#: controllers/collections_controller.php:346
+#: controllers/collections_controller.php:443
+#: controllers/collections_controller.php:482
+#: controllers/collections_controller.php:936
+#: controllers/collections_controller.php:959
+#: controllers/collections_controller.php:960
+#: controllers/collections_controller.php:975
+#: controllers/collections_controller.php:977
+#: controllers/collections_controller.php:994
+#: controllers/collections_controller.php:1003
+#: controllers/collections_controller.php:1016
+#: controllers/collections_controller.php:1017
+#: controllers/collections_controller.php:1024
+#: controllers/collections_controller.php:1070
+#: controllers/collections_controller.php:1090
+#, php-format
+msgid "error_missing_argument"
+msgstr "Argumento não existente: %s"
+
+#: controllers/components/amo.php:507 controllers/components/amo.php:532
+msgid "error_no_files_in_addon"
+msgstr "Sem arquivos"
+
+#: controllers/previews_controller.php:200
+msgid "error_preview_notfound"
+msgstr "Visualização não encontrada!"
+
+#: views/addons/display.thtml:400 views/reviews/add.thtml:98
+msgid "error_review_rating_required"
+msgstr "Você precisa selecionar uma nota."
+
+#: controllers/users_controller.php:160
+msgid "error_user_already_confirmed"
+msgstr "Esta conta de usuário já está confirmada."
+
+#: controllers/users_controller.php:202 controllers/users_controller.php:276
+#: controllers/users_controller.php:569 controllers/users_controller.php:581
+#: controllers/users_controller.php:587 controllers/users_controller.php:610
+#: controllers/users_controller.php:627
+msgid "error_user_badconfirmationcode"
+msgstr "Código de confirmação inválido!"
+
+#: views/users/pwreset.thtml:79 views/users/register.thtml:75
+#: views/users/edit.thtml:183
+msgid "error_user_confirmpw_nomatch"
+msgstr "As senhas não conferem."
+
+#: views/users/register.thtml:65 views/users/edit.thtml:190
+#: controllers/users_controller.php:617
+msgid "error_user_email_notunique"
+msgstr "Este email já foi utilizado por outro usuário."
+
+#: controllers/users_controller.php:596
+msgid "error_user_emailchange_expired"
+msgstr ""
+"A troca de e-mail expirou. Por favor troque seu e-email novamente em seu "
+"cadastro e clique no link do e-email de confirmação assim que recebê-lo "
+
+#: controllers/collections_controller.php:985
+#, fuzzy
+msgid "error_user_exists"
+msgstr ""
+"Users can only have one role at a time. Please remove the user from any "
+"existing roles before continuing."
+
+#: views/users/register.thtml:91 views/users/edit.thtml:116
+#: views/admin/users_edit.thtml:88
+msgid "error_user_nickname_notunique"
+msgstr "Este apelido já foi utilizado."
+
+#: views/users/pwreset.thtml:54 controllers/users_controller.php:191
+#: controllers/users_controller.php:270 controllers/users_controller.php:603
+#: controllers/users_controller.php:659
+#: controllers/collections_controller.php:988
+#: controllers/collections_controller.php:998
+msgid "error_user_notfound"
+msgstr "Usuário não encontrado!"
+
+#: views/users/activatefirst.thtml:47
+msgid "error_user_unconfirmed"
+msgstr ""
+"Por favor, confirme sua conta de usuário com o código enviado via email."
+
+#: views/users/login.thtml:67
+msgid "error_username_or_pw_wrong"
+msgstr "Usuário ou senha incorretos!"
+
+#: controllers/editors_controller.php:260
+msgid "error_version_notfound"
+msgstr "Versão não encontrada!"
+
+#: views/users/delete.thtml:125 views/users/edit.thtml:173
+msgid "error_wrong_password"
+msgstr "Senha digitada inválida!"
+
+#: views/elements/amo2009/homepage_addon.thtml:122
+#: views/elements/feature.thtml:122
+msgid "feature_learnmore"
+msgstr "Saiba mais"
+
+#. %1 is the add-on name
+#: views/elements/amo2009/homepage_addon.thtml:123
+#: views/elements/feature.thtml:123
+#, php-format
+msgid "feature_learnmore_about_addon"
+msgstr "Saiba mais sobre %1$s"
+
+#. %1$s is a number
+#: views/elements/amo2009/reviews.thtml:52
+#: views/elements/addon_listitem.thtml:112 views/elements/feature.thtml:99
+#: views/addons/browse_thumbs.thtml:86
+#, php-format
+msgid "feature_reviews"
+msgid_plural "feature_reviews"
+msgstr[0] "revisões"
+msgstr[1] "revisões"
+
+#: views/elements/amo2009/homepage_addon.thtml:127
+#: views/elements/feature.thtml:127
+msgid "feature_view_more_from_category"
+msgstr "Ver mais de"
+
+#. This appears on a page that views the source of an add-on. This link will return
+#. the user to the add-on's main page
+#: views/files/browse.thtml:65
+msgid "file_browser_link_addon"
+msgstr "Voltar para Complemento"
+
+#. There is a list of directories and files on the page. Clicking this will show the
+#. contents of all the directories (normally you would click on each one to see the
+#. contents)
+#: views/files/browse.thtml:67
+msgid "file_browser_link_expand_all"
+msgstr "Expandir tudo"
+
+#. This appears on a page that views the source of an add-on. This link will return
+#. the user to the add-on's review page (it only appears if the add-on is being
+#. reviewed)
+#: views/files/browse.thtml:64
+msgid "file_browser_link_review"
+msgstr "Voltar para Revisão"
+
+#. The title of the page for viewing an add-on's source.
+#. %1$s is the name of the add-on
+#. %2$s is the name of the current application (e.g. Firefox or Thunderbird)
+#: views/files/browse.thtml:46
+msgid "file_browser_title"
+msgstr "%1$s :: Navegador de Arquivos :: Complementos %2$s"
+
+#. This appears on a page that views the source of an add-on. There is a list of
+#. directories and files on the page. Clicking this link will toggle between an
+#. expanded or a collapsed list. This string should be kept short.
+#: views/files/browse.thtml:68
+msgid "file_browser_toggle_expand_collapse"
+msgstr "+/-"
+
+#. Link text for the AMO About page.
+#: views/elements/footer.thtml:72 views/layouts/amo2009.thtml:341
+msgid "footer_a_about"
+msgstr "Sobre"
+
+#. Link text to the AMO blog.
+#: views/elements/footer.thtml:74 views/layouts/amo2009.thtml:343
+msgid "footer_a_blog"
+msgstr "Blog"
+
+#. Link text to the Frequently Asked Questions page.
+#: views/elements/footer.thtml:73 views/layouts/amo2009.thtml:342
+msgid "footer_a_faq"
+msgstr "FAQ"
+
+#. Full text for the FAQ abbreviation.
+#: views/elements/footer.thtml:73 views/pages/collector_features.thtml:72
+#: views/layouts/amo2009.thtml:342
+msgid "footer_abbr_faq"
+msgstr "Perguntas mais Frequentes"
+
+#: views/elements/footer.thtml:67 views/layouts/amo2009.thtml:336
+msgid "footer_all_rights_reserved"
+msgstr "Todos os direitos reservados."
+
+#: views/elements/footer.thtml:67 views/layouts/amo2009.thtml:336
+msgid "footer_copyright"
+msgstr "Copyright"
+
+#: views/elements/footer.thtml:71 views/layouts/amo2009.thtml:340
+msgid "footer_credits"
+msgstr "Créditos"
+
+#: views/elements/footer.thtml:76 views/layouts/amo2009.thtml:346
+msgid "footer_disclaimer"
+msgstr ""
+"Mozilla oferece links para estas aplicações como um serviço de cortesia, e "
+"não se responsabiliza sobre as aplicações ou quaisquer informações "
+"relacionadas a estas. Perguntas ou reclamações com relação a estas "
+"aplicações devem ser direcionadas aos devidos autores dos programas."
+
+#: views/elements/footer.thtml:61 views/layouts/amo2009.thtml:332
+msgid "footer_lang_form_lang_submit_go"
+msgstr "Enviar"
+
+#: views/elements/footer.thtml:70 views/layouts/amo2009.thtml:339
+msgid "footer_legal_notices"
+msgstr "Termos legais"
+
+#: views/elements/footer.thtml:50 views/layouts/amo2009.thtml:321
+msgid "footer_other_languages"
+msgstr "Outros idiomas:"
+
+#: views/elements/footer.thtml:69 views/layouts/amo2009.thtml:338
+msgid "footer_privacy_policy"
+msgstr "Política de privacidade"
+
+#: models/addontype.php:79
+msgid "general_addontype_dict"
+msgstr "Dicionário"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:100
+msgid "general_addontype_dict_plural"
+msgstr "Dicionários"
+
+#: models/addontype.php:75
+msgid "general_addontype_extension"
+msgstr "Extensão"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:98
+msgid "general_addontype_extension_plural"
+msgstr "Extensões"
+
+#: models/addontype.php:85
+msgid "general_addontype_lpaddon"
+msgstr "Pacote de idioma (Complemento)"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:103
+msgid "general_addontype_lpaddon_plural"
+msgstr "Pacotes de idiomas (Complemento)"
+
+#: models/addontype.php:83
+msgid "general_addontype_lpapp"
+msgstr "Pacote de idioma (Aplicação)"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:102
+msgid "general_addontype_lpapp_plural"
+msgstr "Pacotes de idiomas (Aplicação)"
+
+#: models/addontype.php:87
+msgid "general_addontype_plugin"
+msgstr "Plugin"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:104
+msgid "general_addontype_plugin_plural"
+msgstr "Plugins"
+
+#: models/addontype.php:81
+msgid "general_addontype_search"
+msgstr "Mecanismo de pesquisa"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:101
+msgid "general_addontype_search_plural"
+msgstr "Mecanismos de pesquisa"
+
+#: models/addontype.php:77
+msgid "general_addontype_theme"
+msgstr "Tema"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:99
+msgid "general_addontype_theme_plural"
+msgstr "Temas"
+
+#: config/language.php:367
+#, fuzzy
+msgid "general_languages_all_locales"
+msgstr "All Locales"
+
+#: views/layouts/amo2009.thtml:249
+#, fuzzy
+msgid "header_brand_name"
+msgstr "Mozilla"
+
+#. %1$s is the application name. Example: Firefox
+#: views/elements/header.thtml:111 views/elements/header.thtml:122
+#: views/layouts/amo2009.thtml:248
+#, php-format
+msgid "header_home_tooltip"
+msgstr "Voltar para a página de início de Complementos para %1$s"
+
+#: views/elements/header.thtml:87
+msgid "header_main_firefox_header"
+msgstr "Complementos para o Firefox"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:218
+#, fuzzy
+msgid "header_main_firefox_header_with_logo"
+msgstr ""
+"Add-ons <em>for</em> <img alt=\"Firefox\" src=\"%1$s\" /> <strong>Firefox</"
+"strong>"
+
+#: views/elements/header.thtml:99
+msgid "header_main_header"
+msgstr "Complementos"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:242
+#, fuzzy
+msgid "header_main_header_with_logo"
+msgstr "Add-ons <img alt=\"Add-ons\" src=\"%1$s\" />"
+
+#: views/elements/header.thtml:90
+msgid "header_main_seamonkey_header"
+msgstr "Complementos para o Seamonkey"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:224
+#, fuzzy
+msgid "header_main_seamonkey_header_with_logo"
+msgstr ""
+"Add-ons <em>for</em> <img alt=\"seamonkey\" src=\"%1$s\" /> "
+"<strong>SeaMonkey</strong>"
+
+#: views/elements/header.thtml:93
+msgid "header_main_sunbird_header"
+msgstr "Complementos para o Sunbird"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:230
+#, fuzzy
+msgid "header_main_sunbird_header_with_logo"
+msgstr ""
+"Add-ons <em>for</em> <img alt=\"sunbird\" src=\"%1$s\" /> <strong>Sunbird</"
+"strong>"
+
+#: views/elements/header.thtml:96
+msgid "header_main_thunderbird_header"
+msgstr "Complementos para o Thunderbird"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:236
+#, fuzzy
+msgid "header_main_thunderbird_header_with_logo"
+msgstr ""
+"Add-ons <em>for</em> <img alt=\"thunderbird\" src=\"%1$s\" /> "
+"<strong>Thunderbird</strong>"
+
+#: views/layouts/amo2009.thtml:205
+#, fuzzy
+msgid "header_navaccess_applications_menu"
+msgstr "Skip to other applications menu"
+
+#: views/layouts/amo2009.thtml:204
+#, fuzzy
+msgid "header_navaccess_categories_menu"
+msgstr "Skip to categories menu"
+
+#: views/layouts/amo2009.thtml:202
+#, fuzzy
+msgid "header_navaccess_main_content"
+msgstr "Skip to main content"
+
+#: views/layouts/amo2009.thtml:203
+#, fuzzy
+msgid "header_navaccess_search_form"
+msgstr "Skip to search form"
+
+#: views/elements/header.thtml:62
+msgid "header_navlink_addons"
+msgstr "Complementos"
+
+#: views/elements/developers/sidebar.thtml:72
+#: views/elements/developers/myaddons.thtml:50 views/elements/header.thtml:159
+#: views/addons/display.thtml:378
+msgid "header_navlink_login"
+msgstr "Acessar"
+
+#: views/elements/header.thtml:156 views/layouts/amo2009.thtml:304
+msgid "header_navlink_logout"
+msgstr "Sair"
+
+#: views/elements/header.thtml:145 views/layouts/amo2009.thtml:303
+msgid "header_navlink_myaccount"
+msgstr "Minha conta"
+
+#: views/elements/header.thtml:158
+msgid "header_navlink_register"
+msgstr "Registrar"
+
+#. %1 is the URL to the registration page
+#. %2 is the URL to the login page
+#: views/layouts/amo2009.thtml:278
+#, fuzzy
+msgid "header_navlink_register_or_login"
+msgstr "<a href=\"%1$s\">Register</a> or <a href=\"%2$s\">Log in</a>"
+
+#: views/layouts/amo2009.thtml:285
+#, fuzzy
+msgid "header_navlink_tools"
+msgstr "Tools"
+
+#. %s is the add-on name
+#: views/elements/collections_interactive_addon.thtml:62
+#: views/elements/amo2009/homepage_addon.thtml:77
+#: views/elements/addon_discussionheader.thtml:62
+#: views/elements/addon_listitem.thtml:67 views/elements/feature.thtml:84
+#: views/addons/category_landing.thtml:87 views/addons/browse_thumbs.thtml:60
+#, php-format
+msgid "img_preview_of"
+msgstr "Imagem de visualização de %s"
+
+#. %1 is the login URL for the link tag
+#. %2 is the link to an explanatory page.
+#: views/elements/amo2009/install.thtml:307 views/elements/install.thtml:255
+msgid "install_a_login_to_install"
+msgstr "<a href=\"%1$s\">Iniciar sessão</a> para instalar este Complemento"
+
+#. %1 is the URL for the Experimental Add-ons section of the FAQ page
+#: views/elements/amo2009/install.thtml:283 views/elements/install.thtml:232
+msgid "install_button_confirm_exp_install"
+msgstr ""
+"Permita-me instalar este Complemento experimental. <a href=\"%1$s\">Saiba "
+"mais</a>"
+
+#. %1$s is the application name. Example: Firefox
+#. %2$s is an optional string used to specify a platform. Example: (Windows)
+#: views/elements/amo2009/install.thtml:128 views/elements/install.thtml:75
+#, php-format
+msgid "install_button_text"
+msgstr "Adicionar a %s %s"
+
+#. %1 is the add-on name, %2 is the app name
+#: views/elements/amo2009/install.thtml:191
+#: views/elements/amo2009/install.thtml:206
+#: views/elements/amo2009/install.thtml:249
+#: views/elements/amo2009/install.thtml:298 views/elements/install.thtml:150
+#: views/elements/install.thtml:165 views/elements/install.thtml:202
+#: views/elements/install.thtml:246
+#, php-format
+msgid "install_button_title"
+msgstr "Adicionar %1$s a %2$s"
+
+#. %1$s is the add-on name
+#: views/elements/amo2009/install.thtml:200 views/elements/install.thtml:159
+#, php-format
+msgid "install_download"
+msgstr "Baixar %1$s"
+
+#: views/elements/amo2009/install.thtml:147 views/elements/install.thtml:94
+msgid "install_error_addon_not_found"
+msgstr "Este Complemento não está disponível."
+
+#: views/addons/dictionaries.thtml:65
+msgid "langtools_a11y_tablesummary"
+msgstr "Lista de pacotes de idiomas e dicionários."
+
+#: views/addons/dictionaries.thtml:47
+msgid "langtools_download_dictionary"
+msgstr "Baixar dicionário"
+
+#: views/addons/dictionaries.thtml:48
+msgid "langtools_download_langpack"
+msgstr "Baixar pacote de idioma"
+
+#: views/addons/dictionaries.thtml:63 controllers/components/amo.php:685
+#: controllers/addons_controller.php:1239
+msgid "langtools_header_dicts_and_langpacks"
+msgstr "Dicionários e pacotes de idiomas"
+
+#: views/addons/dictionaries.thtml:44
+msgid "langtools_install_dictionary"
+msgstr "Instalar dicionário"
+
+#: views/addons/dictionaries.thtml:45
+msgid "langtools_install_langpack"
+msgstr "Instalar pacote de idiomas"
+
+#: views/addons/dictionaries.thtml:69
+msgid "langtools_tableheader_dictionary"
+msgstr "Dicionário"
+
+#: views/addons/dictionaries.thtml:70
+msgid "langtools_tableheader_langpack"
+msgstr "Pacote de idioma"
+
+#: views/addons/dictionaries.thtml:68
+msgid "langtools_tableheader_language"
+msgstr "Idioma"
+
+#: models/license.php:65
+msgid "license_custom"
+msgstr "Custom License"
+
+#: config/bootstrap.php:303
+msgid "licenses_bsd"
+msgstr "BSD License"
+
+#: config/bootstrap.php:298
+msgid "licenses_gpl_2.0"
+msgstr "GNU General Public License, version 2.0"
+
+#: config/bootstrap.php:299
+msgid "licenses_gpl_3.0"
+msgstr "GNU General Public License, version 3.0"
+
+#: config/bootstrap.php:300
+msgid "licenses_lgpl_2.1"
+msgstr "GNU Lesser General Public License, version 2.1"
+
+#: config/bootstrap.php:301
+msgid "licenses_lgpl_3.0"
+msgstr "GNU Lesser General Public License, version 3.0"
+
+#: config/bootstrap.php:302
+msgid "licenses_mit"
+msgstr "MIT/X11 License"
+
+#: config/bootstrap.php:297
+msgid "licenses_mpl_1.1"
+msgstr "Mozilla Public License, version 1.1"
+
+#: views/users/emailchange.thtml:51 views/users/delete.thtml:55
+#: views/users/delete.thtml:137 views/users/edit.thtml:74
+#: views/reviews/flag.thtml:54
+msgid "link_return_to_front_page"
+msgstr "Clique aqui para voltar à página inicial."
+
+#: views/elements/amo2009/addon_list_options.thtml:46
+#: views/elements/addon_list_options.thtml:46
+msgid "list_sortby_date"
+msgstr "Data"
+
+#: views/elements/amo2009/addon_list_options.thtml:47
+#: views/elements/addon_list_options.thtml:47
+msgid "list_sortby_downloads"
+msgstr "Downloads"
+
+#: views/elements/amo2009/addon_list_options.thtml:45
+#: views/elements/addon_list_options.thtml:45
+msgid "list_sortby_name"
+msgstr "Nome do Complemento"
+
+#: views/elements/amo2009/addon_list_options.thtml:48
+#: views/elements/addon_list_options.thtml:48
+msgid "list_sortby_rating"
+msgstr "Pontuação"
+
+#: config/bootstrap.php:278
+msgid "main_prettyname_fennec"
+msgstr "Fennec"
+
+#: config/bootstrap.php:274
+msgid "main_prettyname_firefox"
+msgstr "Firefox"
+
+#: config/bootstrap.php:277
+msgid "main_prettyname_seamonkey"
+msgstr "SeaMonkey"
+
+#: config/bootstrap.php:276
+msgid "main_prettyname_sunbird"
+msgstr "Sunbird"
+
+#: config/bootstrap.php:275
+msgid "main_prettyname_thunderbird"
+msgstr "Thunderbird"
+
+#: views/elements/addon_categories.thtml:52
+msgid "nav_category_dicts_langpacks"
+msgstr "Dicionários e pacotes de idiomas"
+
+#: views/elements/addon_categories.thtml:55
+msgid "nav_category_themes"
+msgstr "Temas"
+
+#: views/elements/app_chooser.thtml:47 views/layouts/amo2009.thtml:255
+msgid "other_apps_tooltip"
+msgstr "Encontre Complementos para outras aplicações"
+
+#. In a user list: user 1, user 2, "others"
+#: views/helpers/addons_html.php:222
+msgid "other_users"
+msgstr "outros"
+
+#: controllers/pages_controller.php:90
+msgid "page_title_appversions"
+msgstr "Versões da Aplicação"
+
+#: controllers/pages_controller.php:115
+#, fuzzy
+msgid "page_title_collector"
+msgstr "Add-on Collector"
+
+#: controllers/pages_controller.php:117
+#, fuzzy
+msgid "page_title_collector_faq"
+msgstr "Add-on Collector FAQ"
+
+#: controllers/pages_controller.php:119
+#, fuzzy
+msgid "page_title_collector_features"
+msgstr "Add-on Collector Features"
+
+#: controllers/pages_controller.php:122
+#, fuzzy
+msgid "page_title_collector_firstrun"
+msgstr "Welcome to the Add-on Collector"
+
+#: controllers/pages_controller.php:92
+msgid "page_title_credits"
+msgstr "Créditos"
+
+#: controllers/pages_controller.php:113
+msgid "page_title_developer_faq"
+msgstr "Developer FAQ"
+
+#: controllers/pages_controller.php:111
+msgid "page_title_faq"
+msgstr "Perguntas Frequentes"
+
+#: controllers/pages_controller.php:94
+msgid "page_title_fashionyourfirefox_faq"
+msgstr "FAQ do Fashion Your Firefox"
+
+#: controllers/pages_controller.php:101
+msgid "page_title_policy"
+msgstr "Política de Uso dos Complementos"
+
+#: controllers/pages_controller.php:103
+msgid "page_title_privacy"
+msgstr "Política de Privacidade Mozilla"
+
+#: controllers/pages_controller.php:105
+msgid "page_title_review_guide"
+msgstr "Regras gerais para Revisores"
+
+#: controllers/pages_controller.php:107
+msgid "page_title_sandbox"
+msgstr "Sistema de Revisão da Sandbox"
+
+#: controllers/pages_controller.php:109
+msgid "page_title_submissionhelp"
+msgstr "Ajuda com Envio"
+
+#: views/pages/appversions.thtml:87
+msgid "pages_appversions_guid"
+msgstr "GUID"
+
+#: views/pages/appversions.thtml:79 controllers/pages_controller.php:90
+msgid "pages_appversions_header"
+msgstr "Versões de aplicação válidas"
+
+#: views/pages/appversions.thtml:80
+msgid "pages_appversions_intro"
+msgstr ""
+"Complementos enviados ao Mozilla Add-ons precisam incluir o arquivo install."
+"rdf com pelo menos uma das aplicações abaixo. Somente as versões listadas "
+"são suportadas para estas aplicações."
+
+#. %s is a full <a> tag
+#: views/pages/appversions.thtml:93
+#, php-format
+msgid "pages_appversions_required_files"
+msgstr ""
+"Se sua aplicação não necessita do arquivo install.rdf, você deverá incluir "
+"devido aos requisitos pelas propriedades especificadas %s."
+
+#. this is the text inside of an <a> tag for pages_appversions_required_files. This
+#. should be fixed.
+#: views/pages/appversions.thtml:93
+msgid "pages_appversions_required_files_link"
+msgstr "aqui"
+
+#: views/pages/appversions.thtml:88
+msgid "pages_appversions_versions"
+msgstr "Versões"
+
+#: views/pages/policy.thtml:51
+msgid "pages_policy_sandbox_link"
+msgstr "Página de informação da sandbox"
+
+#: views/elements/pagination.thtml:53
+msgid "pagination_next_page"
+msgstr "próximo"
+
+#: views/elements/pagination.thtml:52
+msgid "pagination_previous_page"
+msgstr "anterior"
+
+#: views/elements/recaptcha.thtml:65
+msgid "recaptcha_enter_both_words"
+msgstr ""
+"Insira <strong>ambas as palavras</strong> abaixo, <strong>separadas por um "
+"espaço </strong>."
+
+#: views/elements/recaptcha.thtml:83
+msgid "recaptcha_enter_here"
+msgstr "Insira sua resposta aqui:"
+
+#: views/elements/recaptcha.thtml:74
+msgid "recaptcha_enter_whatyouhear"
+msgstr "Por favor digite o que você ouve."
+
+#. %1 is the link switching refreshing the captcha
+#. %2 is the link switching to a text captcha
+#: views/elements/recaptcha.thtml:77
+msgid "recaptcha_hardtohear_text"
+msgstr ""
+"Se isto for difícil de entender, você poderá <a href=\"%1$s\">ouvir outra "
+"coisa</a> ou <a href=\"%2$s\">colocar texto novamente</a>."
+
+#. %1 is the link switching refreshing the captcha
+#. %2 is the link switching to an audio captcha
+#: views/elements/recaptcha.thtml:68
+msgid "recaptcha_hardtoread_text"
+msgstr ""
+"Se isto for difícil de se ler, você poderá <a href=\"%1$s\">tentar palavras "
+"diferentes</a> ou <a href=\"%2$s\">ouvir algo</a>."
+
+#: views/users/register.thtml:105
+msgid "recaptcha_label"
+msgstr "Você é humano?"
+
+#: views/users/register.thtml:106
+msgid "recaptcha_whatsthis"
+msgstr "O que é isso?"
+
+#: controllers/reviews_controller.php:559
+msgid "review_flag_error"
+msgstr "Erro ao marcar esta revisão!"
+
+#: models/reviews_moderation_flag.php:69
+msgid "review_flag_reason_bug_support"
+msgstr "Pedido de suporte ou relato de Bug inválivo"
+
+#: views/reviews/display.thtml:103 views/reviews/display.thtml:186
+msgid "review_flag_reason_instructions"
+msgstr "Relatar esta revisão (selecione uma razão)"
+
+#: models/reviews_moderation_flag.php:67
+msgid "review_flag_reason_language"
+msgstr "Linguajar inapropriado"
+
+#: models/reviews_moderation_flag.php:71
+msgid "review_flag_reason_other"
+msgstr "Outros ( especificar )"
+
+#: models/reviews_moderation_flag.php:65
+msgid "review_flag_reason_spam"
+msgstr "Spam ou conteúdo que não é uma revisão"
+
+#: views/reviews/display.thtml:91 views/reviews/display.thtml:175
+#: controllers/reviews_controller.php:555
+msgid "review_flag_success"
+msgstr "Obrigado; esta revisão foi marcada para aprovação de um editor."
+
+#: views/reviews/display.thtml:41
+msgid "review_flag_this"
+msgstr "Enviar esta revisão"
+
+#: views/reviews/display.thtml:42
+msgid "review_flag_this_titletip"
+msgstr ""
+"Esta revisão é inapropriada, incorreta ou spam? Clique aqui para marcá-la "
+"para revisão de um editor."
+
+#. %1 is the URL of the support section, %2 for the review guidelines
+#: views/reviews/add.thtml:53
+msgid "review_guidelines_short"
+msgstr ""
+"<p>Mantenhas essas dicas em mente::</p><ul><li>Escreva como se tivesse "
+"falando para um amigo sobre sua experiência com o Complemento. Dê detalhes "
+"específicos e úteis, tais como quais características você gostou ou não, "
+"quão fácil é utilizá-lo, e quaisquer desvantagens que ele possua. Evite "
+"usar termos genéricos como dizer \"Ótimo\" ou \"Ruim\" a menos que você "
+"possa dar as razões pelas quais você acha isso.</li><li>Por favor, não "
+"reporte bugs nas revisões. Nós não deixamos seu endereço de e-mail "
+"disponível para os desenvolvedores do Complemento e eles podem precisar "
+"entrar em contato com você para que ajude a resolver seu problema. Veja a <a "
+"href=\"%1$s\">seção de suporte</a> para encontrar onde obter ajuda para este "
+"Complemento.</li><li>Por favor, deixe suas revisões claras, evite o uso de "
+"linguagem imprópria e não escreva nenhuma informação pessoal. </li></"
+"ul><p>Leia as <a href=\"%2$s\">Dicas de revisão</a> para maiores detalhes "
+"sobre revisões de Complementos.</p>"
+
+#. %1 is the add-on name
+#: views/reviews/flag.thtml:56 views/reviews/display.thtml:55
+#: views/reviews/review_added.thtml:50
+#, php-format
+msgid "reviews_header"
+msgstr "Revisões para %s"
+
+#: controllers/addons_controller.php:435
+msgid "rss_featuredaddons"
+msgstr "Complementos selecionados"
+
+#: controllers/addons_controller.php:432
+msgid "rss_newestaddons"
+msgstr "Complementos mais novos"
+
+#: controllers/addons_controller.php:434
+#, fuzzy
+msgid "rss_popularaddons"
+msgstr "Popular Add-ons"
+
+#: controllers/addons_controller.php:433
+msgid "rss_updatedaddons"
+msgstr "Atualizar Complementos"
+
+#: views/elements/search_mini.thtml:70
+msgid "search"
+msgstr "Search"
+
+#: views/search/collections.thtml:51
+#, fuzzy
+msgid "search_collections_header"
+msgstr "Collection Search Results"
+
+#: controllers/search_controller.php:297
+#, fuzzy
+msgid "search_collections_pagetitle"
+msgstr "Collection Search Results"
+
+#: controllers/search_controller.php:99
+msgid "search_disabled"
+msgstr ""
+"A busca está temporariamente fora do ar. Por favor, tente novamente mais "
+"tarde."
+
+#: views/elements/amo2009/search.thtml:188 views/elements/search.thtml:187
+#: views/elements/search_mini.thtml:54
+msgid "search_form_all_addons"
+msgstr "todos os Complementos"
+
+#. This string is in the main category dropdown when searching
+#: views/elements/amo2009/search.thtml:204
+#, fuzzy
+msgid "search_form_all_collections"
+msgstr "all collections"
+
+#: views/elements/amo2009/search.thtml:184
+#: views/elements/amo2009/search.thtml:385
+#: views/elements/amo2009/search.thtml:408 views/elements/search.thtml:171
+#: views/elements/search.thtml:183 views/elements/search_mini.thtml:43
+#: views/elements/search_mini.thtml:49 views/layouts/mozilla.thtml:188
+msgid "search_form_default_text"
+msgstr "buscar por Complementos"
+
+#: views/elements/amo2009/search.thtml:184
+#: views/elements/amo2009/search.thtml:404
+#, fuzzy
+msgid "search_form_default_text_collections"
+msgstr "search for collections"
+
+#: views/elements/amo2009/search.thtml:206 views/elements/search.thtml:202
+msgid "search_form_submit_tooltip"
+msgstr "Pesquisar por Complementos"
+
+#: views/elements/amo2009/search.thtml:184 views/elements/search.thtml:183
+#: views/elements/search_mini.thtml:49
+msgid "search_form_tooltip"
+msgstr "Clique para inserir os termos da pesquisa"
+
+#: views/elements/amo2009/search.thtml:186 views/elements/search.thtml:185
+#: views/elements/search_mini.thtml:52
+msgid "search_form_within"
+msgstr "dentro de"
+
+#: views/addons/searchengines.thtml:118
+msgid "search_landing_all_search_engines"
+msgstr "Todos os mecanismos de pesquisa"
+
+#: views/addons/searchengines.thtml:114
+msgid "search_landing_browse_search_engines"
+msgstr "Ver mecanismos de pesquisa"
+
+#: views/search/collections.thtml:58 views/search/index.thtml:59
+msgid "search_nothing_found"
+msgstr "Nenhum resultado encontrado."
+
+#: controllers/search_controller.php:185
+msgid "search_pagetitle"
+msgstr "Procure por Complementos"
+
+#: controllers/search_controller.php:242
+msgid "search_rss_description"
+msgstr "Feed dos resultados de procura"
+
+#. %s is the terms the user is searching for (a string)
+#: controllers/search_controller.php:241
+#, php-format
+msgid "search_rss_results_for"
+msgstr "Resultados da procura: %s"
+
+#: views/elements/header.thtml:154 views/layouts/amo2009.thtml:296
+msgid "sidebar_navlink_admin_tools"
+msgstr "Ferramentas administrativas"
+
+#: views/elements/header.thtml:146 views/layouts/amo2009.thtml:288
+msgid "sidebar_navlink_developer_tools"
+msgstr "Ferramentas do desenvolvedor"
+
+#: views/elements/header.thtml:148 views/layouts/amo2009.thtml:290
+msgid "sidebar_navlink_editor_tools"
+msgstr "Ferramentas de edição"
+
+#: views/layouts/amo2009.thtml:302
+msgid "sidebar_navlink_welcome"
+msgstr "Bem vindo"
+
+#. %s is the user's name
+#: views/layouts/amo2009.thtml:302
+#, php-format
+msgid "sidebar_navlink_welcome_name"
+msgstr "Bem vindo, %s"
+
+#: views/elements/pitch.thtml:50 views/elements/pitch.thtml:55
+msgid "sidebar_pitch_dictionary"
+msgstr "Dicionário"
+
+#: views/elements/pitch.thtml:72
+msgid "sidebar_pitch_featured_addons"
+msgstr "Complementos em destaque"
+
+#: views/elements/pitch.thtml:61
+msgid "sidebar_pitch_looking_for"
+msgstr "Estou procurando por:"
+
+#: views/elements/pitch.thtml:70
+msgid "sidebar_pitch_newest_addons"
+msgstr "Complementos mais recentes"
+
+#: views/elements/pitch.thtml:49
+msgid "sidebar_pitch_search"
+msgstr "Mecanismo de pesquisa"
+
+#: views/elements/pitch.thtml:69
+msgid "sidebar_pitch_subscribe_to"
+msgstr "Inscrever-se em"
+
+#: views/elements/pitch.thtml:48 views/elements/pitch.thtml:54
+msgid "sidebar_pitch_theme"
+msgstr "Tema"
+
+#: views/elements/pitch.thtml:71
+msgid "sidebar_pitch_updated_addons"
+msgstr "Complementos atualizados"
+
+#. %1$s is a number
+#: views/helpers/localization.php:65 views/developers/versions_edit.thtml:95
+#: views/addons/dictionaries.thtml:92
+#, php-format
+msgid "size_kb"
+msgstr "%1$s KB"
+
+#: views/elements/amo2009/stars.thtml:57 views/elements/stars.thtml:63
+msgid "stars_not_yet_rated"
+msgstr "Sem pontuação"
+
+#. %1 is the number of stars this add-on has
+#: views/elements/amo2009/stars.thtml:49 views/elements/stars.thtml:54
+#, php-format
+msgid "stars_rated_x_outof_5"
+msgstr "Pontuação: %s de 5 estrelas"
+
+#: views/statistics/addon.thtml:59
+msgid "statistics_addon_dashboard_link"
+msgstr "Página de início do painel de controle"
+
+#: views/statistics/addon.thtml:58
+msgid "statistics_addon_developertools_link"
+msgstr "Ferramentas do desenvolvedor"
+
+#: views/statistics/addon.thtml:53
+msgid "statistics_addon_switch"
+msgstr "Trocar Complemento"
+
+#. This is a date format.
+#. http://php.net/strftime
+#: views/statistics/rss/summary.thtml:54 views/statistics/addon.thtml:181
+msgid "statistics_date_shortmonth"
+msgstr "%e de %b"
+
+#. This is a date format.
+#. http://php.net/strftime
+#: views/statistics/rss/summary.thtml:40 views/statistics/addon.thtml:152
+msgid "statistics_date_shortmonthwithyear"
+msgstr "%e de %b, %Y"
+
+#. This is a date format.
+#. http://php.net/strftime
+#: views/statistics/rss/summary.thtml:41 views/statistics/rss/summary.thtml:48
+#: views/statistics/addon.thtml:161 views/statistics/addon.thtml:172
+msgid "statistics_date_weekdayshortmonth"
+msgstr "%A, %e de %b"
+
+#. %1$s is an add-on name and version. Example: Add-on 3.5
+#: controllers/components/stats.php:519
+#, php-format
+msgid "statistics_events_addon_created"
+msgstr "%1$s criado"
+
+#. %1$s is an application name and version. Example: Firefox 3.5
+#: controllers/components/stats.php:500
+#, php-format
+msgid "statistics_events_app_released"
+msgstr "%1$s publicado"
+
+#: views/statistics/addon.thtml:71
+msgid "statistics_help_close_link"
+msgstr "Fechar"
+
+#: views/statistics/addon.thtml:60
+msgid "statistics_help_link"
+msgstr "Ajuda"
+
+#: views/statistics/index.thtml:83
+msgid "statistics_index_anotheraddon"
+msgstr "ou, selecione outro Complemento"
+
+#: views/statistics/index.thtml:85
+msgid "statistics_index_anotheraddon_public"
+msgstr "ou, selecione um Complemento com estatísticas públicas"
+
+#: views/statistics/index.thtml:71
+msgid "statistics_index_myaddons"
+msgstr "Selecione um de seus Complementos para ver suas estatísticas"
+
+#: views/statistics/index.thtml:89
+msgid "statistics_index_selectaddon"
+msgstr "Selecione um Complemento para ver suas estatísticas"
+
+#: views/statistics/index.thtml:91
+msgid "statistics_index_selectaddon_public"
+msgstr "Selecione um Complemento com estatísticas públicas"
+
+#: views/statistics/index.thtml:39
+msgid "statistics_index_title"
+msgstr "Painel de estatísticas"
+
+#: views/statistics/index.thtml:97
+msgid "statistics_index_view_button"
+msgstr "Ver estatísticas"
+
+#: views/statistics/addon.thtml:222 controllers/statistics_controller.php:247
+msgid "statistics_js_download_csv"
+msgstr "Visualizar esta tabela em formato CSV"
+
+#: controllers/statistics_controller.php:246
+msgid "statistics_js_dropdowns_none"
+msgstr "nenhum"
+
+#: controllers/statistics_controller.php:245
+msgid "statistics_js_dropdowns_removeplot"
+msgstr "Remover este parâmetro"
+
+#: controllers/statistics_controller.php:248
+msgid "statistics_js_groupby_selector_date"
+msgstr "Agrupar por: Dia"
+
+#: controllers/statistics_controller.php:251
+msgid "statistics_js_groupby_selector_month"
+msgstr "Agrupar por: Mês"
+
+#: controllers/statistics_controller.php:249
+msgid "statistics_js_groupby_selector_week"
+msgstr "Agrupar por: Semana"
+
+#: controllers/statistics_controller.php:250
+msgid "statistics_js_groupby_selector_week_over_week"
+msgstr "Compare by: Week"
+
+#: controllers/statistics_controller.php:260
+msgid "statistics_js_plotselection_foundinrange"
+msgstr "%s encontrado"
+
+#: controllers/statistics_controller.php:270
+msgid "statistics_js_plotselection_options_addplot_name"
+msgstr "Adicionar parâmetro"
+
+#: controllers/statistics_controller.php:271
+msgid "statistics_js_plotselection_options_addplot_tooltip"
+msgstr "Adicionar outro parâmetro a este gráfico"
+
+#: controllers/statistics_controller.php:261
+msgid "statistics_js_plotselection_options_count_name_checked"
+msgstr "Ocultar a contagem total"
+
+#: controllers/statistics_controller.php:262
+msgid "statistics_js_plotselection_options_count_name_unchecked"
+msgstr "Mostrar a contagem total"
+
+#: controllers/statistics_controller.php:263
+msgid "statistics_js_plotselection_options_count_tooltip"
+msgstr "Colocar a contagem total neste gráfico"
+
+#: controllers/statistics_controller.php:275
+msgid "statistics_js_plotselection_options_csv_name"
+msgstr "Ver dados (CSV)"
+
+#: controllers/statistics_controller.php:276
+msgid "statistics_js_plotselection_options_csv_tooltip"
+msgstr "Obter um arquivo 'Comma Separated Values' destes dados"
+
+#: controllers/statistics_controller.php:267
+msgid "statistics_js_plotselection_options_events_addon_name_checked"
+msgstr "Ocultar %s eventos"
+
+#: controllers/statistics_controller.php:268
+msgid "statistics_js_plotselection_options_events_addon_name_unchecked"
+msgstr "Mostrar %s eventos"
+
+#: controllers/statistics_controller.php:269
+msgid "statistics_js_plotselection_options_events_addon_tooltip"
+msgstr "Sobrepor as datas de publicação dos Complementos nos gráficos"
+
+#: controllers/statistics_controller.php:264
+msgid "statistics_js_plotselection_options_events_firefox_name_checked"
+msgstr "Ocultar eventos do Firefox"
+
+#: controllers/statistics_controller.php:265
+msgid "statistics_js_plotselection_options_events_firefox_name_unchecked"
+msgstr "Mostrar eventos do Firefox"
+
+#: controllers/statistics_controller.php:266
+msgid "statistics_js_plotselection_options_events_firefox_tooltip"
+msgstr "Sobreper datas de publicação do Firefox nos gráficos"
+
+#: controllers/statistics_controller.php:272
+msgid "statistics_js_plotselection_options_resize_name_checked"
+msgstr "Encolher gráfico"
+
+#: controllers/statistics_controller.php:273
+msgid "statistics_js_plotselection_options_resize_name_unchecked"
+msgstr "Expandir gráfico"
+
+#: controllers/statistics_controller.php:274
+msgid "statistics_js_plotselection_options_resize_tooltip"
+msgstr "Redimensionar o gráfico"
+
+#: controllers/statistics_controller.php:254
+msgid "statistics_js_plotselection_selector_adu"
+msgstr "Usuários ativos diariamente"
+
+#: controllers/statistics_controller.php:256
+msgid "statistics_js_plotselection_selector_application"
+msgstr "Aplicação"
+
+#: controllers/statistics_controller.php:259
+msgid "statistics_js_plotselection_selector_custom"
+msgstr "Personalizado"
+
+#: controllers/statistics_controller.php:253
+msgid "statistics_js_plotselection_selector_downloads"
+msgstr "Downloads"
+
+#: controllers/statistics_controller.php:258
+msgid "statistics_js_plotselection_selector_os"
+msgstr "Sistema operacional"
+
+#: controllers/statistics_controller.php:257
+msgid "statistics_js_plotselection_selector_status"
+msgstr "Estado do Complemento"
+
+#: controllers/statistics_controller.php:252
+msgid "statistics_js_plotselection_selector_summary"
+msgstr "Sumário"
+
+#: controllers/statistics_controller.php:255
+msgid "statistics_js_plotselection_selector_version"
+msgstr "Versão do Complemento"
+
+#: controllers/components/stats.php:398
+msgid "statistics_longnames_application"
+msgstr "Aplicação"
+
+#: controllers/components/stats.php:400
+msgid "statistics_longnames_os"
+msgstr "Sistema operacional"
+
+#: controllers/components/stats.php:399
+msgid "statistics_longnames_status"
+msgstr "Estado do Complemento"
+
+#: controllers/components/stats.php:401
+msgid "statistics_longnames_unknown"
+msgstr "Desconhecido"
+
+#: controllers/components/stats.php:397
+msgid "statistics_longnames_version"
+msgstr "Versão do Complemento"
+
+#: views/statistics/addon.thtml:118
+msgid "statistics_notice_data_insufficient"
+msgstr ""
+"Não existem dados suficientes para exibir este gráfico. Por favor, verifique "
+"novamente mais tarde."
+
+#: views/statistics/addon.thtml:130
+msgid "statistics_notice_data_none"
+msgstr ""
+"Nós não temos nenhum dado para seu Complemento ainda. Por favor, verifique "
+"novamente dentro de alguns dias."
+
+#: views/statistics/addon.thtml:41
+msgid "statistics_notice_data_updating"
+msgstr ""
+"Estatísticas do Complemento estão em processo de atualização. Dados recentes "
+"podem estar incompletos enquatno nossos scripts trabalham para atualizar a "
+"informação. Por favor, verifique novamente dentro de alguns minutos."
+
+#: views/statistics/addon.thtml:136
+msgid "statistics_notice_disabled"
+msgstr ""
+"O painel de estatísticas está desativado no momento. Por favor, verifique "
+"novamente mais tarde."
+
+#: views/statistics/addon.thtml:123
+msgid "statistics_notice_nojavascript"
+msgstr ""
+"É necessário JavaScript para ver os gráficos do painel de estatísticas."
+
+#: views/statistics/addon.thtml:44
+msgid "statistics_notice_settings_updated"
+msgstr "Suas configurações foram atualizadas!"
+
+#: controllers/statistics_controller.php:60
+#: controllers/statistics_controller.php:71
+#: controllers/statistics_controller.php:74
+#: controllers/statistics_controller.php:240
+msgid "statistics_pagetitle"
+msgstr "Painel de estatísticas"
+
+#: views/statistics/addon.thtml:99
+msgid "statistics_plot_legend_adu"
+msgstr "Usuários ativos diariamente"
+
+#: views/statistics/addon.thtml:95
+msgid "statistics_plot_legend_downloads"
+msgstr "Downloads diários"
+
+#: views/statistics/addon.thtml:107
+msgid "statistics_plot_options_zoomin_alt"
+msgstr "Aproximar"
+
+#: views/statistics/addon.thtml:106
+msgid "statistics_plot_options_zoomin_title"
+msgstr "Aproximar para um mês"
+
+#: views/statistics/addon.thtml:110
+msgid "statistics_plot_options_zoomout_alt"
+msgstr "Afastar"
+
+#: views/statistics/addon.thtml:109
+msgid "statistics_plot_options_zoomout_title"
+msgstr "Afastar um mês"
+
+#: controllers/statistics_controller.php:283
+#, php-format
+msgid "statistics_rss_description"
+msgstr "Resumo diários das estatísticas de %1$s"
+
+#: views/statistics/rss/summary.thtml:68
+msgid "statistics_rss_title_fulldate"
+msgstr "%A, %e de %B de %Y"
+
+#: views/statistics/rss/summary.thtml:68
+#, php-format
+msgid "statistics_rss_title_statsfordate"
+msgstr "Estatísticas para %1$s"
+
+#: views/statistics/settings.thtml:49
+msgid "statistics_settings_access_description"
+msgstr ""
+"Por padrão, apenas você e a Mozilla podem ter acesso às informações em seu "
+"painel. Você pode abrí-lo ao público para que todos possam ver os dados de "
+"seu Complemento."
+
+#: views/statistics/settings.thtml:48
+msgid "statistics_settings_access_heading"
+msgstr "Acesso ao painel"
+
+#: views/statistics/settings.thtml:51
+msgid "statistics_settings_access_private"
+msgstr "Privado"
+
+#: views/statistics/settings.thtml:51
+msgid "statistics_settings_access_private_description"
+msgstr "Somente você e a Mozilla podem ver as estatísticas deste Complementos"
+
+#: views/statistics/settings.thtml:52
+msgid "statistics_settings_access_public"
+msgstr "Público"
+
+#: views/statistics/settings.thtml:52
+msgid "statistics_settings_access_public_description"
+msgstr "Todos podem ver as estatísticas deste compelento"
+
+#: views/statistics/addon.thtml:251
+msgid "statistics_settings_change_link"
+msgstr "Alterar as configurações"
+
+#: views/statistics/addon.thtml:253
+msgid "statistics_settings_confidential"
+msgstr "Por favor, trate essas informações como confidenciais."
+
+#: views/statistics/addon.thtml:245
+msgid "statistics_settings_currently_private"
+msgstr "Este painel é atualmente <b>privado</b>."
+
+#: views/statistics/addon.thtml:241
+msgid "statistics_settings_currently_public"
+msgstr "Este painel é atualmente <b>público</b>."
+
+#: views/statistics/addon.thtml:246
+msgid "statistics_settings_locked_alt"
+msgstr "Bloqueado"
+
+#: views/statistics/settings.thtml:57
+msgid "statistics_settings_return_link"
+msgstr "Voltar ao painel"
+
+#: views/statistics/settings.thtml:56
+msgid "statistics_settings_save_button"
+msgstr "Salvar configurações"
+
+#: views/statistics/settings.thtml:46
+#, php-format
+msgid "statistics_settings_title"
+msgstr "Configurações do painel de estatísticas de %1$s"
+
+#: views/statistics/addon.thtml:242
+msgid "statistics_settings_unlocked_alt"
+msgstr "Desbloqueado"
+
+#: controllers/components/stats.php:405
+msgid "statistics_shortnames_application"
+msgstr "App."
+
+#: controllers/components/stats.php:407
+msgid "statistics_shortnames_os"
+msgstr "SO"
+
+#: controllers/components/stats.php:406
+msgid "statistics_shortnames_status"
+msgstr "Est."
+
+#: controllers/components/stats.php:408
+msgid "statistics_shortnames_unknown"
+msgstr "Desc."
+
+#: controllers/components/stats.php:404
+msgid "statistics_shortnames_version"
+msgstr "Ver."
+
+#: views/statistics/rss/summary.thtml:42 views/statistics/addon.thtml:192
+msgid "statistics_summary_downloads_average"
+msgstr "Média de downloads diários"
+
+#: views/statistics/rss/summary.thtml:39
+msgid "statistics_summary_downloads_heading"
+msgstr "Downloads"
+
+#: views/statistics/rss/summary.thtml:41 views/statistics/addon.thtml:171
+msgid "statistics_summary_downloads_lastcount"
+msgstr "Contagem do último dia"
+
+#: views/statistics/rss/summary.thtml:43 views/statistics/addon.thtml:199
+msgid "statistics_summary_downloads_lastweek"
+msgstr "Downloads nos últimos 7 dias"
+
+#: views/statistics/rss/summary.thtml:40 views/statistics/addon.thtml:151
+msgid "statistics_summary_downloads_total"
+msgstr "Total de downloads"
+
+#: views/statistics/rss/summary.thtml:40 views/statistics/addon.thtml:152
+#, php-format
+msgid "statistics_summary_downloads_total_sincedate"
+msgstr "Desde %1$s"
+
+#: views/statistics/rss/summary.thtml:50 views/statistics/rss/summary.thtml:56
+#: views/statistics/addon.thtml:163 views/statistics/addon.thtml:183
+msgid "statistics_summary_nodata"
+msgstr "Sem dados até o momento"
+
+#: views/statistics/rss/summary.thtml:60 views/statistics/addon.thtml:195
+msgid "statistics_summary_updatepings_average"
+msgstr "Média de usuários ativos por dia"
+
+#: views/statistics/rss/summary.thtml:52 views/statistics/addon.thtml:177
+msgid "statistics_summary_updatepings_changefromprevious"
+msgstr "Alteração desde última contagem"
+
+#: views/statistics/rss/summary.thtml:54 views/statistics/addon.thtml:181
+#, php-format
+msgid "statistics_summary_updatepings_changefromprevious_ondate"
+msgstr "%1$s em %2$s"
+
+#: views/statistics/rss/summary.thtml:45
+msgid "statistics_summary_updatepings_heading"
+msgstr "Usuários ativos por dia"
+
+#: views/statistics/rss/summary.thtml:46 views/statistics/addon.thtml:157
+msgid "statistics_summary_updatepings_total"
+msgstr "Usuários ativos por dia"
+
+#: views/statistics/rss/summary.thtml:48 views/statistics/addon.thtml:161
+#, php-format
+msgid "statistics_summary_updatepings_total_ondate"
+msgstr "Em %1$s"
+
+#: views/statistics/rss/summary.thtml:61 views/statistics/addon.thtml:203
+msgid "statistics_summary_updatepings_weekly_average"
+msgstr "Average Daily Users this Week"
+
+#. %s is a percentage, like '+22.33%'. It sits next to another number, so
+#. the implied meaning is 'percentage change' from the previous stat point.
+#: views/statistics/rss/summary.thtml:62 views/statistics/addon.thtml:205
+msgid "statistics_summary_updatepings_weekly_change"
+msgstr "%s from last week"
+
+#: views/statistics/addon.thtml:65 controllers/statistics_controller.php:184
+#: controllers/statistics_controller.php:282
+#, php-format
+msgid "statistics_title_addon_stats"
+msgstr "Estatísticas para %1$s"
+
+#: views/addons/themes_landing.thtml:113
+msgid "themes_landing_all_themes"
+msgstr "Todos os temas"
+
+#: views/addons/themes_landing.thtml:109
+msgid "themes_landing_browse_themes"
+msgstr "Ver temas"
+
+#: views/users/edit.thtml:185
+msgid "user_change_email"
+msgstr "Trocar endereço de e-mail"
+
+#: views/users/edit.thtml:169
+msgid "user_change_password"
+msgstr "Mudar senha"
+
+#: views/users/edit.thtml:96
+#, fuzzy
+msgid "user_change_password_or_email"
+msgstr "Change Password or Email"
+
+#: controllers/users_controller.php:197
+msgid "user_confirmationcode_resent"
+msgstr "O código de confirmação foi enviado!"
+
+#. %1 is the email address, %2 is the URL of the user registration page
+#: views/users/delete.thtml:51
+msgid "user_del_account_deleted"
+msgstr ""
+"Sua conta de usuário %1$s foi deletada com sucesso. Se você tiver interesse "
+"em voltar, você poderá registrar-se novamente na <a href=\"%2$s\">Página de "
+"registro</a>."
+
+#: views/users/delete.thtml:102
+msgid "user_del_community_sad"
+msgstr "A comunidade de Mozilla Add-ons ficará triste em saber que vai."
+
+#: views/users/delete.thtml:123
+msgid "user_del_confirm_password"
+msgstr "Confirme senha"
+
+#: views/users/delete.thtml:134
+msgid "user_del_deletenow"
+msgstr "Delete minha conta de usuário agora"
+
+#. %1 is the URL of the user's info page
+#: views/users/delete.thtml:64
+msgid "user_del_error_addons"
+msgstr ""
+"Você não pode deletar sua conta se estiver listado como um <a href=\"%1$s"
+"\">autor de Complementos</a>. Para deletar sua conta, por favor coloque "
+"outra pessoa no grupo de desenvolvimento e tire seu nome da lista de autores "
+"para seus Complementos. Somente depois disso, você poderá deletar sua conta "
+"aqui."
+
+#. %1 is a link to the amo-editors mailing list
+#: views/users/delete.thtml:71
+msgid "user_del_error_addons_more_questions"
+msgstr ""
+"Se você tem outras perguntas, por favor entre em contato com %1$s para obter "
+"assistência."
+
+#: views/users/delete.thtml:78
+msgid "user_del_error_checkbox"
+msgstr ""
+"Você precisa marcar a caixa \"Eu Concordo...\" antes de deletar sua conta."
+
+#: views/users/delete.thtml:84
+msgid "user_del_error_password"
+msgstr "Por favor entre com sua senha corretamente para completar este passo."
+
+#. %1 is a link to the amo-admins mailing list
+#: views/users/delete.thtml:91
+msgid "user_del_error_unknown"
+msgstr ""
+"Um erro desconhecido ocorreu na tentativa de deletar sua conta. Por favor "
+"entre em contato %1$s com o problema e nós vamos deletar para você. Pedimos "
+"desculpas pelo transtorno."
+
+#: views/users/delete.thtml:110
+msgid "user_del_header_confirm_deletion"
+msgstr "Confirme Deletar de Conta"
+
+#. %1 is the user's email address
+#: views/users/delete.thtml:100
+msgid "user_del_header_delete_account"
+msgstr "Deletar conta de usuário %1$s"
+
+#: views/users/delete.thtml:50
+msgid "user_del_header_farewell"
+msgstr "Despedida!"
+
+#: views/users/delete.thtml:115
+msgid "user_del_nologin"
+msgstr "Você não poderá acessar o Mozilla Add-ons novamente."
+
+#: views/users/delete.thtml:112
+msgid "user_del_permanently_removed_means"
+msgstr ""
+"Ao clicar \"deletar\" sua conta será <strong>permanentemente removida</"
+"strong>. Ou seja:"
+
+#: views/users/delete.thtml:116
+msgid "user_del_reviews_anonymized"
+msgstr ""
+"Suas revisões ou notas não serão apagadas, mas elas não serão mais "
+"associadas com seu usuário."
+
+#. %1 is a link to the amo-editors mailing list
+#: views/users/delete.thtml:104
+msgid "user_del_specific_problem_editors"
+msgstr ""
+"Se você tem um problema específico que podemos lhe ajudar, por favor não "
+"delete sua conta agora, mas entre em contato conosco em %1$s e faremos o "
+"melhor para ajudá-lo a resolver o problema."
+
+#: views/users/delete.thtml:130
+msgid "user_del_understand_permanent"
+msgstr "Eu entendo que este passo não tem volta."
+
+#: views/helpers/addons_html.php:192
+msgid "user_deleted_nickname"
+msgstr "Usuário deletado"
+
+#. %1 is the new email address
+#: views/users/edit.thtml:71
+msgid "user_edit_confirm_email_sent"
+msgstr ""
+"Foi enviado um e-mail para %1$s para confirmar seu novo endereço de e-mail. "
+"Para que a mudança tenha efeito, você precisa clicar no link fornecido neste "
+"e-mail. Até lá, você pode continuar acessando com seu endereço de e-mail "
+"atual."
+
+#: views/users/edit.thtml:201
+msgid "user_edit_delete_user"
+msgstr "Apagar conta de usuário"
+
+#. This contains the email sent to users when they signed up for a new
+#. account:
+#. %1 is the confirmation URL, %2 is the current app
+#: views/users/email/confirm_plain.thtml:6
+#, php-format
+msgid "user_email_confirm_account_nopass"
+msgstr ""
+"Bem-vindo ao %2$s Add-ons.\n"
+"\n"
+"Antes de utilizar o Add-ons você precisa ativar sua conta para garantir que "
+"o email é válido e pertence a você.\n"
+"Para ativar sua conta, clique no endereço abaixo ou copie o endereço "
+"inteiramente na barra de endereço do seu navegador:\n"
+"\n"
+"%1$s\n"
+"\n"
+"Uma vez que você ativar então poderá desconsiderar este email.\n"
+"\n"
+"Obrigado por participar do %2$s Add-ons\n"
+"-- Pessoal do %2$s Add-ons"
+
+#. %1 is the confirmation url, %2 is the application name
+#: views/users/email/emailchange_plain.thtml:5
+msgid "user_email_confirm_emailchange"
+msgstr ""
+"Você requisitou uma troca de endereço de e-mail no %2$s Add-ons.\n"
+"\n"
+"Para confirmar o novo endereço, clique no link abaixo ou copie e cole o "
+"link todo na barra de endereços do seu navegador:\n"
+"\n"
+"%1$s\n"
+"\n"
+"Você tem 48 horas para confirmar seu novo endereço. Se você não deseja mais "
+"mudar o endereço, você pode apenas ignorar este e-mail.\n"
+"\n"
+"Obrigado!\n"
+"-- Equipe do %2$s Add-ons"
+
+#: controllers/users_controller.php:168
+#, php-format
+msgid "user_email_confirm_subject"
+msgstr "Obrigado por participar do %s Add-ons"
+
+#. This is the password reset email
+#. %1 is the pw reset URL, %2 is the application
+#: views/users/email/pwreset_plain.thtml:5
+#, php-format
+msgid "user_email_pwreset"
+msgstr ""
+"%2$s Add-ons - Resetar senha\n"
+"\n"
+"Um pedido de resetar senha foi recebido para a conta de usuário no Add-ons."
+"mozilla.org. Para mudar a senha clique no endereço abaixo, ou copie o mesmo "
+"na barra de endereço do seu navegador:\n"
+"\n"
+"%1$s\n"
+"\n"
+"Se não foi você que fez este pedido, não existe necessidade de ações.\n"
+"\n"
+"Valeu,\n"
+"-- Pessoal do %2$s Add-ons"
+
+#: controllers/users_controller.php:245
+#, php-format
+msgid "user_email_pwreset_subject"
+msgstr "Resetar sua senha do %s Add-ons"
+
+#: views/users/emailchange.thtml:50
+msgid "user_emailchange_error"
+msgstr "Erro!"
+
+#. %1 is the application name
+#: controllers/users_controller.php:533
+msgid "user_emailchange_subject"
+msgstr "Por favor, confirme a troca de endereço de e-mail no %1$s Add-ons"
+
+#: views/users/emailchange.thtml:48
+msgid "user_emailchange_success"
+msgstr "Successo!"
+
+#. %1 is the new email address
+#: views/users/emailchange.thtml:49
+msgid "user_emailchange_successful_description"
+msgstr ""
+"Seu endereço de e-mail foi alterado com sucesso. De agora em diante, por "
+"favor, use %1$s para fazer log-in no site"
+
+#: views/users/edit.thtml:134 views/admin/users_edit.thtml:111
+msgid "user_form_bio"
+msgstr "About me"
+
+#: views/users/edit.thtml:135 views/admin/users_edit.thtml:112
+msgid "user_form_bio_description"
+msgstr ""
+"Introduce yourself to the community, if you like! This text will appear "
+"publicly on your user info page. Line breaks will be preserved, but no HTML "
+"is allowed."
+
+#: views/users/pwreset.thtml:77 views/users/register.thtml:73
+#: views/users/edit.thtml:181
+msgid "user_form_confirmpassword"
+msgstr "Confirme a senha"
+
+#: views/users/edit.thtml:145
+#, fuzzy
+msgid "user_form_display_collections"
+msgstr "Display the collections I have created in my user profile"
+
+#: views/users/edit.thtml:149
+#, fuzzy
+msgid "user_form_display_collections_fav"
+msgstr "Display my favorite collections in my user profile"
+
+#: views/users/edit.thtml:86
+#, php-format
+msgid "user_form_editprofile"
+msgstr "Editar perfil de usuário para %s"
+
+#: views/users/pwreset.thtml:52 views/users/login.thtml:81
+#: views/users/register.thtml:63 views/users/edit.thtml:187
+msgid "user_form_email"
+msgstr "Endereço de email"
+
+#: views/users/register.thtml:78 views/users/edit.thtml:103
+#: views/admin/users_edit.thtml:76
+msgid "user_form_firstname"
+msgstr "Nome"
+
+#: views/users/register.thtml:94 views/users/edit.thtml:119
+#: views/admin/users_edit.thtml:91
+msgid "user_form_hideemail"
+msgstr "Não mostrar endereço de email"
+
+#: views/users/register.thtml:98 views/users/edit.thtml:123
+#: views/admin/users_edit.thtml:99
+msgid "user_form_homepage"
+msgstr "Endereço URL"
+
+#: views/users/register.thtml:84 views/users/edit.thtml:109
+#: views/admin/users_edit.thtml:81
+msgid "user_form_lastname"
+msgstr "Sobrenome"
+
+#: controllers/users_controller.php:333
+msgid "user_form_login"
+msgstr "Login de usuário"
+
+#: views/users/pwreset.thtml:72 views/users/edit.thtml:176
+msgid "user_form_newpassword"
+msgstr "Nova senha"
+
+#: views/users/register.thtml:89 views/users/edit.thtml:114
+#: views/admin/users_edit.thtml:86
+msgid "user_form_nickname"
+msgstr "Apelido"
+
+#: views/users/edit.thtml:171
+msgid "user_form_oldpassword"
+msgstr "Senha antiga"
+
+#: views/users/edit.thtml:97 views/users/edit.thtml:200
+msgid "user_form_otheractions"
+msgstr "Outras ações"
+
+#: views/users/login.thtml:85 views/users/register.thtml:68
+msgid "user_form_password"
+msgstr "Senha"
+
+#: controllers/users_controller.php:93
+msgid "user_form_registration"
+msgstr "Novo registro de usuário"
+
+#: views/users/login.thtml:90
+msgid "user_form_remember_me"
+msgstr "Lembrar de mim neste computador"
+
+#: views/admin/users_edit.thtml:95
+msgid "user_form_showsandbox"
+msgstr "Mostrar sandbox?"
+
+#: views/users/edit.thtml:205
+msgid "user_form_submit_edit"
+msgstr "Salvar"
+
+#: views/users/login.thtml:93
+msgid "user_form_submit_login"
+msgstr "Login"
+
+#: views/users/register.thtml:113
+msgid "user_form_submit_register"
+msgstr "Registrar"
+
+#: views/users/info.thtml:75
+#, php-format
+msgid "user_info_usersince"
+msgstr "%s Complementos - usuário desde"
+
+#: views/users/login.thtml:102
+msgid "user_login_register_link"
+msgstr "Criar uma nova conta de usuário"
+
+#: views/users/edit.thtml:160
+msgid "user_notifications_item_compat"
+msgstr "Compatibilidade do Complemento (fortemente recomendado)"
+
+#: views/users/edit.thtml:161
+msgid "user_notifications_item_events"
+msgstr "Concursos e eventos"
+
+#: views/users/edit.thtml:156
+msgid "user_notifications_none_available"
+msgstr ""
+"No momento não exitem notificações disponíveis para que você precise "
+"configurar."
+
+#: views/users/edit.thtml:158
+msgid "user_notifications_select_topics"
+msgstr ""
+"De tempos em tempos, Mozilla poderá lhe enviar emails sobre os lançamentos "
+"futuros e eventos relacionados com Complementos. Por favor selecione os "
+"tópicos que você tem interesse abaixo:"
+
+#: views/users/edit.thtml:164
+msgid "user_notifications_specific_contact"
+msgstr ""
+"Mozilla reserva o direito de entrar em contato com você individualmente com "
+"possíveis questões sobre os Complementos armazenados."
+
+#: controllers/users_controller.php:543
+msgid "user_profile_edit_error"
+msgstr ""
+"Existem erros nas mudanças que você fez. Por favor, corrigir e enviar "
+"novamente."
+
+#: controllers/users_controller.php:540
+msgid "user_profile_saved"
+msgstr "Perfil atualizado."
+
+#: views/users/pwreset.thtml:65
+#, php-format
+msgid "user_pwreset_for_email"
+msgstr "Resetar senha para %s"
+
+#: controllers/users_controller.php:226
+msgid "user_pwreset_header"
+msgstr "Resetar senha"
+
+#: views/users/login.thtml:103
+msgid "user_pwreset_link"
+msgstr "Esqueceu sua senha?"
+
+#: controllers/users_controller.php:248
+msgid "user_pwreset_link_sent"
+msgstr "O endereço para resetar a senha foi enviado para seu email."
+
+#: controllers/users_controller.php:304
+msgid "user_pwreset_okay"
+msgstr "Senha resetada com sucesso."
+
+#: views/users/pwreset.thtml:82
+msgid "user_pwreset_submit_changepw"
+msgstr "Enviar mudança de senha"
+
+#: views/users/pwreset.thtml:57
+msgid "user_pwreset_submit_sendlink"
+msgstr "Enviar endereço para resetar senha"
+
+#: views/users/register_complete.thtml:51
+#, php-format
+msgid "user_register_amo_link"
+msgstr "%s Complementos"
+
+#. %1 is the user's email address, %2 is the current app
+#: views/users/activatefirst.thtml:49
+#, php-format
+msgid "user_register_click_confirm_link"
+msgstr ""
+"Um endereço para ativar sua conta de usuário foi enviado ao email %1$s. Você "
+"deverá clicar no endereço antes de acessar o %2$s Add-ons."
+
+#. %1 is the user's email address
+#: views/users/register_complete.thtml:49
+#, php-format
+msgid "user_register_confirm_email_sent"
+msgstr ""
+"Um email foi enviado para o endereço %1$s para que a conta seja confirmada. "
+"Antes de fazer login, você deverá ativar sua conta clicando no link que "
+"encontrará no email."
+
+#: views/users/activatefirst.thtml:51
+msgid "user_register_confirmation_link_text"
+msgstr "envie novamente o email de confirmação"
+
+#: views/users/register_complete.thtml:47
+msgid "user_register_congratulations"
+msgstr "Parabéns! Sua conta foi criada com sucesso."
+
+#: views/users/register.thtml:50
+msgid "user_register_details"
+msgstr ""
+"<p>Registro no AMO <strong>não é obrigatório</strong> se você simplesmente "
+"quer baixar e instalar Complementos públicos.</p><p>Você só precisa se "
+"registrar caso:</p><ul><li>Você quiser enviar revisões para Complementos</"
+"li><li>Você é um desenvolvedor de Complementos e desejar enviar seus "
+"Complementos para serem mantidos no AMO</li></ul><p>Após o registro com "
+"sucesso, você receberá um email de confirmação para o endereço que você "
+"cadastrou. Por favor siga as instruções enviadas para confirmar sua conta.</"
+"p><p>Se você deseja, você poderá ler nossas <a href='%1$s' title='Notas de "
+"conteúdo legal Notices'>Notas de Conteúdo Legal</a> e <a href='%2$s' "
+"title='Política de Privacidade'>Política de Privacidade</a>.</p>"
+
+#. %1 is the link to the "resend confirmation code" page
+#: views/users/activatefirst.thtml:51
+#, php-format
+msgid "user_register_resend_confirmation_link"
+msgstr ""
+"Se você não recebeu o email de confirmação, certifique-se de que seu serviço "
+"de email não colocou a mensagem na \"lixeira\" ou \"spam\". Se precisar, "
+"podemos %1$s utilizando o email acima."
+
+#. %1 is the link to the Mozilla Add-ons front page
+#: views/users/register_complete.thtml:51
+#, php-format
+msgid "user_register_welcome"
+msgstr "Obrigado por se registrar e bem-vindo ao %1$s!"
+
+#: views/users/register.thtml:49
+msgid "user_register_welcome_header"
+msgstr "Bem-vindo ao addons.mozilla.org (AMO)!"
+
+#: views/users/register.thtml:81 views/users/edit.thtml:106
+msgid "user_required_firstlast_or_nickname"
+msgstr "O primeiro nome, último nome, ou apelido deve ser adicionado."
+
+#: views/users/edit.thtml:94 views/users/edit.thtml:142
+#, fuzzy
+msgid "user_tab_collections"
+msgstr "Collections"
+
+#: views/users/edit.thtml:95 views/users/edit.thtml:154
+msgid "user_tab_notifications"
+msgstr "Notificações"
+
+#: views/users/edit.thtml:93 views/users/edit.thtml:101
+msgid "user_tab_profile"
+msgstr "Profile do Usuário"
+
+#: controllers/users_controller.php:209
+msgid "user_verified_okay"
+msgstr "Verificado com sucesso!"
+
+#: controllers/users_controller.php:723
+msgid "users_delete_pagetitle"
+msgstr "Apagar conta de usuário"
+
+#: controllers/users_controller.php:414
+msgid "users_edit_pagetitle"
+msgstr "Editando conta de usuário"
+
+#: views/users/info.thtml:71
+msgid "users_info_aboutme"
+msgstr "About Me"
+
+#: views/users/info.thtml:96
+#, php-format
+msgid "users_info_addons_by_user"
+msgstr "Complementos de %1$s"
+
+#: views/users/info.thtml:51
+msgid "users_info_author_name"
+msgstr "Nome"
+
+#: views/users/info.thtml:48
+msgid "users_info_author_profile"
+msgstr "Perfil do usuário"
+
+#. %s is the user name
+#: views/users/info.thtml:137
+#, fuzzy
+msgid "users_info_collections_by_user"
+msgstr "Collections by %s"
+
+#: views/users/info.thtml:66
+msgid "users_info_email"
+msgstr "Endereço de email"
+
+#: views/users/info.thtml:155
+#, fuzzy
+msgid "users_info_fav_collections_by_user"
+msgstr "Favorite Collections"
+
+#: views/users/info.thtml:61
+msgid "users_info_homepage"
+msgstr "Página inicial"
+
+#: views/users/info.thtml:56
+msgid "users_info_nickname"
+msgstr "Apelido"
+
+#: controllers/users_controller.php:707
+#, php-format
+msgid "users_info_pagetitle"
+msgstr "Informação de usuário para %1$s"
+
+#. %1 is the user's name
+#: views/users/info.thtml:116
+msgid "users_info_reviews_by_user"
+msgstr "Revisões por %s"
+
+#: controllers/users_controller.php:330 controllers/users_controller.php:332
+msgid "users_login_pagetitle"
+msgstr "Login do usuário"
+
+#. %1 is the link to the sandbox/policy explanation page
+#. This message is for a specific add-on not found
+#: views/users/login.thtml:53
+#, php-format
+msgid "users_login_sandbox_display_warning"
+msgstr ""
+"O Complemento que você está procurando encontra-se na sandbox. Se você já "
+"tem uma conta no Mozilla Add-ons, faça login, ou <a href=\"%1$s\">leia mais "
+"sobre a sandbox.</a>"
+
+#. %1 is the link to the sandbox/policy explanation page
+#. This message is for any given sandbox-related page not found
+#: views/users/login.thtml:56
+#, php-format
+msgid "users_login_sandbox_page_warning"
+msgstr ""
+"A página que você está procurando encontra-se na sandbox. Se você já tem uma "
+"conta no Mozilla Add-ons, faça login, ou <a href=\"%1$s\">leia mais sobre a "
+"sandbox.</a>"
+
+#: controllers/users_controller.php:223 controllers/users_controller.php:225
+msgid "users_pwreset_pagetitle"
+msgstr "Resetar senha de usuário"
+
+#: controllers/users_controller.php:90 controllers/users_controller.php:92
+msgid "users_register_pagetitle"
+msgstr "Registro de novo usuário"
+
+#. %1$s is an addon name, like <a>Firebug</a>
+#. %2$s is a version number, like <a>1.2</a>
+#: views/versions/license.thtml:52
+msgid "versions_license_header_source"
+msgstr "Source code license for %1$s %2$s"
+
+#: views/addons/category_landing.thtml:147
+msgid "view_recently_added"
+msgstr "View all recently added"
+
+#: views/addons/category_landing.thtml:161
+msgid "view_top_downloads"
+msgstr "View all top downloads"
+
+#: views/addons/category_landing.thtml:175
+msgid "view_top_rated"
+msgstr "View all top rated"
+
+#~ msgid "addon_slider_tooltip_next"
+#~ msgstr "Próximo Complemento"
+
+#~ msgid "addon_slider_tooltip_previous"
+#~ msgstr "Complemento Anterior"
+
+#~ msgid "addon_versions_getlatesttext"
+#~ msgstr "A versão mais recente compatível com"
+
+#~ msgid "addons_display_version_history"
+#~ msgstr "Histórico completo de versões"
+
+#~ msgid "addons_home_newest_header"
+#~ msgstr "Mais novos:"
+
+#~ msgid "addons_home_popular_header"
+#~ msgstr "Mais populares:"
+
+#~ msgid "addons_home_recommended_header"
+#~ msgstr "Nós recomendamos:"
+
+#~ msgid "addons_home_updated_header"
+#~ msgstr "Atualizados recentemente:"
+
+#~ msgid "addons_home_view_all"
+#~ msgstr "Ver todos"
+
+#~ msgid "category_extra_allrecommended"
+#~ msgstr "Ver todos os Complementos recomendados"
+
+#~ msgid "category_extra_highestrated"
+#~ msgstr "Melhor avaliados primeiro"
+
+#~ msgid "category_extra_lastupdated"
+#~ msgstr "Atualizados mais recentemente primeiro"
+
+#~ msgid "category_extra_mostpopular"
+#~ msgstr "Mais populares primeiro"
+
+#, fuzzy
+#~ msgid "collections_detail_js_loading"
+#~ msgstr "Loading"
+
+#, fuzzy
+#~ msgid "collections_detail_more_info"
+#~ msgstr "Show More Info"
+
+#~ msgid "devcp_additem_firefox_notice"
+#~ msgstr ""
+#~ "Esta versão de seu Complemento não se diz compatível com o Firefox %1$s. "
+#~ "Mozilla espera que a próxima versão do Firefox seja lançada em breve, "
+#~ "então por favor teste seu Complemento na nova versão a atualize as "
+#~ "informações de compatibilidade. Você pode encontrar mais informações "
+#~ "sobre isso <a href=\"%2$s\">aqui</a>. Isto é apenas um lembrete e você "
+#~ "pode continuar a enviar esta versão para o Add-ons.mozilla.org."
+
+#~ msgid "devcp_addon_disabled_successfully"
+#~ msgstr "Complemento desativado com sucesso"
+
+#~ msgid "devcp_addon_edit_pagetitle"
+#~ msgstr "Editar Complemento"
+
+#~ msgid "devcp_addon_enabled_successfully"
+#~ msgstr "Complemento ativado com sucesso"
+
+#~ msgid "devcp_addon_field_description_displaytitle"
+#~ msgstr "Descrição do Complemento"
+
+#~ msgid "devcp_addon_field_eula_displaytitle"
+#~ msgstr "EULA"
+
+#~ msgid "devcp_addon_field_homepage_displaytitle"
+#~ msgstr "Página do Complemento"
+
+#~ msgid "devcp_addon_field_name_displaytitle"
+#~ msgstr "Nome do Complemento"
+
+#~ msgid "devcp_addon_field_privacy_displaytitle"
+#~ msgstr "Política de privacidade"
+
+#~ msgid "devcp_addon_field_summary_displaytitle"
+#~ msgstr "Sumário do Complemento"
+
+#~ msgid "devcp_addon_field_supportemail_displaytitle"
+#~ msgstr "Email para suporte"
+
+#~ msgid "devcp_addon_field_supporturl_displaytitle"
+#~ msgstr "URL para suporte"
+
+#~ msgid "devcp_addon_field_versionnotes_displaytitle"
+#~ msgstr "Notas da versão"
+
+#~ msgid "devcp_addon_nominate_pagetitle"
+#~ msgstr "Indicar Complemento"
+
+#~ msgid "devcp_addon_nominated_successfully"
+#~ msgstr "Complemento indicado com sucesso!"
+
+#~ msgid "devcp_addon_status_criteria_review"
+#~ msgstr ""
+#~ "Várias revisões por usuários do Complemento (servem revisões externas)."
+
+#~ msgid "devcp_addon_submission_makechanges"
+#~ msgstr ""
+#~ "Visite a página %1$s para alterar a sua submissão, ou %2$s para retornar "
+#~ "ao painel de controle do desenvolvedor."
+
+#~ msgid "devcp_addon_submission_makechanges_devcp_link"
+#~ msgstr "clique aqui"
+
+#~ msgid "devcp_addon_submission_makechanges_link"
+#~ msgstr "Editar Complemento"
+
+#~ msgid "devcp_addon_submission_pending"
+#~ msgstr ""
+#~ "Esta versão foi colocada na sandbox enquanto espera por revisão pelos "
+#~ "testadores da sandbox e por um editor de Complementos da Mozilla. Você "
+#~ "será notificado por email quando alguma ação for tomada."
+
+#~ msgid "devcp_addon_submission_sandbox_readmore"
+#~ msgstr ""
+#~ "Você pode ler mais sobre o sistema de revisões da sandbox clicando %s."
+
+#~ msgid "devcp_addon_submission_sandbox_readmore_link"
+#~ msgstr "aqui"
+
+#~ msgid "devcp_addon_submission_sandboxed"
+#~ msgstr ""
+#~ "Esta versão foi colocada na sandbox para o uso de usuários experientes. "
+#~ "Para que ela seja exibida no site público, você precisa %s seu "
+#~ "Complemento para que seja submetida a um processo de revisão."
+
+#~ msgid "devcp_addon_submission_sandboxed_nominate_link"
+#~ msgstr "indicar"
+
+#~ msgid "devcp_addon_submission_success"
+#~ msgstr "O envio de seu Complemento foi finalizado com sucesso."
+
+#~ msgid "devcp_addon_submission_trusted_public"
+#~ msgstr ""
+#~ "Devido ao fato de que seu Complemento é confiável, esta versão já foi "
+#~ "automaticamente aprovada para a área pública do site."
+
+#~ msgid "devcp_addon_submit_pagetitle"
+#~ msgstr "Enviar Complemento"
+
+#~ msgid "devcp_addon_updated_successfully"
+#~ msgstr "Complemento atualizado com sucesso"
+
+#~ msgid "devcp_addon_upload_preview"
+#~ msgstr "Você pode %s para tentar aumentar o interesse em seu Complemento."
+
+#~ msgid "devcp_addon_upload_preview_link"
+#~ msgstr "escrever uma revisão"
+
+#~ msgid "devcp_author_lookup_none_found"
+#~ msgstr "Autor não encontrado [%s]"
+
+#~ msgid "devcp_author_lookup_remove"
+#~ msgstr "Remover"
+
+#~ msgid "devcp_button_cancel"
+#~ msgstr "Cancelar"
+
+#~ msgid "devcp_button_cancel_confirm"
+#~ msgstr "Você tem certeza de que quer cancelar sua submissão?"
+
+#~ msgid "devcp_button_next"
+#~ msgstr "Próximo"
+
+#~ msgid "devcp_change_addontype"
+#~ msgstr "Mudar tipo do Complemento:"
+
+#~ msgid "devcp_comments_updated"
+#~ msgstr "Os comentários dos desenvolvedores foram atualizados."
+
+#~ msgid "devcp_details_addpreview_link"
+#~ msgstr "Adicionar visualização"
+
+#~ msgid "devcp_details_author"
+#~ msgstr "Autor"
+
+#~ msgid "devcp_details_authors"
+#~ msgstr "Autores"
+
+#~ msgid "devcp_details_authors_none"
+#~ msgstr "Nenhum"
+
+#~ msgid "devcp_details_categories"
+#~ msgstr "Categorias"
+
+#~ msgid "devcp_details_category"
+#~ msgstr "Categoria"
+
+#~ msgid "devcp_details_description"
+#~ msgstr "Descrição"
+
+#~ msgid "devcp_details_disabled"
+#~ msgstr "Desativado"
+
+#~ msgid "devcp_details_guid"
+#~ msgstr "GUID"
+
+#~ msgid "devcp_details_header_details"
+#~ msgstr "Detalhes"
+
+#~ msgid "devcp_details_header_devcomments"
+#~ msgstr "Comentários dos desenvolvedores"
+
+#~ msgid "devcp_details_header_previews"
+#~ msgstr "Visualizações"
+
+#~ msgid "devcp_details_header_versions"
+#~ msgstr "Versões"
+
+#~ msgid "devcp_details_homepage"
+#~ msgstr "Página inicial"
+
+#~ msgid "devcp_details_homepage_none"
+#~ msgstr "Nenhum"
+
+#~ msgid "devcp_details_preview_nocaption"
+#~ msgstr "Sem rótulo"
+
+#~ msgid "devcp_details_previews_nonefound"
+#~ msgstr "Nenhuma visualização encontrada."
+
+#~ msgid "devcp_details_submit_update"
+#~ msgstr "Atualizar"
+
+#~ msgid "devcp_details_supportemail"
+#~ msgstr "Email para suporte"
+
+#~ msgid "devcp_details_supportemail_none"
+#~ msgstr "O desenvolvedor não forneceu um email para suporte."
+
+#~ msgid "devcp_details_supporturl"
+#~ msgstr "URL para suporte"
+
+#~ msgid "devcp_details_supporturl_none"
+#~ msgstr "O desenvolvedor não forneceu uma URL para suporte."
+
+#~ msgid "devcp_details_trusted"
+#~ msgstr "Confiável"
+
+#~ msgid "devcp_details_versions_none_found"
+#~ msgstr "Nenhuma versão encontrada."
+
+#~ msgid "devcp_disable_cancel"
+#~ msgstr "Cancelar e voltar"
+
+#~ msgid "devcp_disable_disable_button"
+#~ msgstr "Sim, desativar"
+
+#~ msgid "devcp_disable_disable_confirm"
+#~ msgstr "Tem certeza que deseja desativar este Complemento?"
+
+#~ msgid "devcp_disable_disable_description"
+#~ msgstr ""
+#~ "Desativar este Complemento irá ocultá-lo de buscas e listagens. Não será "
+#~ "possível fazer download dele pelo site e não serão enviados avisos nas "
+#~ "verificações de atualização dos clientes. O Complemento será deletado "
+#~ "efetivamente. No entanto você poderá voltar aqui e reativá-lo quando "
+#~ "desejar."
+
+#~ msgid "devcp_disable_disable_title"
+#~ msgstr "Desativar %s"
+
+#~ msgid "devcp_disable_enable_button"
+#~ msgstr "Sim, ativar"
+
+#~ msgid "devcp_disable_enable_confirm"
+#~ msgstr "Tem certeza que deseja ativar este Complemento?"
+
+#~ msgid "devcp_disable_enable_description"
+#~ msgstr ""
+#~ "Ao ativar este Complemento fará com quem ele apareça novamente nas buscas "
+#~ "e listagens. Usuários poderão fazer download dele tanto pelo site quanto "
+#~ "pelas verificações de atualização dos clientes."
+
+#~ msgid "devcp_disable_enable_title"
+#~ msgstr "Ativar %s"
+
+#~ msgid "devcp_edit_author_add"
+#~ msgstr "Adicionar autor"
+
+#~ msgid "devcp_edit_author_email"
+#~ msgstr "Endereço de email do autor: "
+
+#~ msgid "devcp_edit_author_remove"
+#~ msgstr "Remover"
+
+#~ msgid "devcp_edit_error_categories_unavailable"
+#~ msgstr "Nenhuma categoria disponível para o tipo deste Complemento."
+
+#~ msgid "devcp_edit_file_error_incomplete"
+#~ msgstr "Transferência incompleta"
+
+#~ msgid "devcp_edit_file_error_no"
+#~ msgstr "Arquivo não enviado"
+
+#~ msgid "devcp_edit_file_error_size"
+#~ msgstr "Ultrapassou o máximo do tamanho de upload"
+
+#~ msgid "devcp_edit_header_authors"
+#~ msgstr "Autores"
+
+#~ msgid "devcp_edit_icon_add_link"
+#~ msgstr "Adicionar ícone"
+
+#~ msgid "devcp_edit_icon_change_link"
+#~ msgstr "Alterar ícone"
+
+#~ msgid "devcp_edit_label_allow_viewsource"
+#~ msgstr "Permitir que usuários vejam os códigos-fonte online"
+
+#~ msgid "devcp_edit_label_categories"
+#~ msgstr "Categorias"
+
+#~ msgid "devcp_edit_label_defaultlocale"
+#~ msgstr "Idioma padrão"
+
+#~ msgid "devcp_edit_label_icon_delete"
+#~ msgstr "Apenas limpar o ícone existente"
+
+#~ msgid "devcp_edit_label_icon_new"
+#~ msgstr "Novo arquivo de ícone"
+
+#~ msgid "devcp_edit_label_info"
+#~ msgstr "ícone"
+
+#~ msgid "devcp_edit_locale_disambiguation_explanation"
+#~ msgstr "Informação adicional breve (tal como nome de dialeto local)"
+
+#~ msgid "devcp_edit_submit_update"
+#~ msgstr "Atualizar"
+
+#~ msgid "devcp_edit_target_locale_explanation"
+#~ msgstr "<a href=\"http://wiki.mozilla.org/L10n:pt-BR\">pt-BR</a>"
+
+#~ msgid "devcp_editversion_checkedfiles_delete"
+#~ msgstr "Os arquivos selecionados serão deletados."
+
+#~ msgid "devcp_editversion_filename_size"
+#~ msgstr "%1$s (%2$s)"
+
+#~ msgid "devcp_editversion_label_files"
+#~ msgstr "Arquivos"
+
+#~ msgid "devcp_editversion_label_targetapps"
+#~ msgstr "Aplicações alvo"
+
+#~ msgid "devcp_editversion_nofiles"
+#~ msgstr "Sem arquivos."
+
+#~ msgid "devcp_editversion_reviewernotes"
+#~ msgstr "Notas para o revisor"
+
+#~ msgid "devcp_editversion_submit_update"
+#~ msgstr "Atualizar"
+
+#~ msgid "devcp_error_addon_field_summary_toolong"
+#~ msgstr ""
+#~ "Sumários podem conter no máximo 250 caracteres.\n"
+#~ "(Você digitou %s)"
+
+#~ msgid "devcp_error_addonname_not_unique"
+#~ msgstr ""
+#~ "O nome do seu Complemento já existe na base de dados. Assegure-se de que: "
+#~ "<br /><li>seus GUIDs conferem. As causas mais comuns deste erro são GUIDs "
+#~ "diferentes.</li><li>Você não possui entradas duplicadas na base de dados. "
+#~ "Se tiver, você deve atualizar ou deletar esta entrada e tentar novamente."
+#~ "</li>"
+
+#~ msgid "devcp_error_describe_changes"
+#~ msgstr ""
+#~ "Por favor, descreva as mudanças realizadas na atualização deste "
+#~ "Complemento."
+
+#~ msgid "devcp_error_file_guids_dont_match"
+#~ msgstr "As GUIDs não são as mesmas em todos os arquivos"
+
+#~ msgid "devcp_error_identical_version_exists"
+#~ msgstr ""
+#~ "Uma versão idêntica (%s) já existe para este Complemento e plataforma."
+
+#~ msgid "devcp_error_nominate_message"
+#~ msgstr "Você precisa fornecer os detalhes necessários para indicação."
+
+#~ msgid "devcp_error_nominate_no_prerelease"
+#~ msgstr "Você não pode indicar uma pré-distribuição de um Complemento."
+
+#~ msgid "devcp_error_nominate_sandbox_only"
+#~ msgstr "Você só pode indicar Complementos que estejam na SandBox."
+
+#~ msgid "devcp_error_saving"
+#~ msgstr "Ocorreu um erro enquanto tentávamos salvar seus dados."
+
+#~ msgid "devcp_error_update_access_denied"
+#~ msgstr "Você não tem permissão para atualizar este Complemento."
+
+#~ msgid "devcp_file_addanother"
+#~ msgstr "Adicionar outro arquivo de plataforma"
+
+#~ msgid "devcp_form_author_add"
+#~ msgstr "Adicionar autor"
+
+#~ msgid "devcp_form_author_remove"
+#~ msgstr "Remover"
+
+#~ msgid "devcp_form_categories_nextstep"
+#~ msgstr ""
+#~ "No próximo passo você poderá escolher categorias para seu novo "
+#~ "Complemento."
+
+#~ msgid "devcp_form_error_categories_unavailable"
+#~ msgstr "Não existem categorias disponíveis para este tipo de Complemento."
+
+#~ msgid "devcp_form_error_description_notempty"
+#~ msgstr "Por favor, insira uma descrição para seu Complemento."
+
+#~ msgid "devcp_form_error_name_required"
+#~ msgstr "Por favor, insira o nome do seu Complemento."
+
+#~ msgid "devcp_form_error_select_addontype"
+#~ msgstr "Por favor, selecione o tipo do Complemento que está enviando."
+
+#~ msgid "devcp_form_error_summary_notempty"
+#~ msgstr "Por favor, insira um sumário do seu Complemento."
+
+#~ msgid "devcp_form_label_addonfile"
+#~ msgstr "Arquivo do Complemento"
+
+#~ msgid "devcp_form_label_addonfile2"
+#~ msgstr "Arquivo 2 do Complemento"
+
+#~ msgid "devcp_form_label_addonfile3"
+#~ msgstr "Arquivo 3 do Complemento"
+
+#~ msgid "devcp_form_label_addontype"
+#~ msgstr "Tipo do Complemento"
+
+#~ msgid "devcp_form_label_allow_viewsource"
+#~ msgstr "Permitir que usuários vejam os códigos-fonte online"
+
+#~ msgid "devcp_form_label_author_email"
+#~ msgstr "Email do autor"
+
+#~ msgid "devcp_form_label_authors"
+#~ msgstr "autores"
+
+#~ msgid "devcp_form_label_categories"
+#~ msgstr "Categorias"
+
+#~ msgid "devcp_form_label_defaultlocale"
+#~ msgstr "Idioma padrão"
+
+#~ msgid "devcp_form_label_description"
+#~ msgstr "Descrição"
+
+#~ msgid "devcp_form_label_eula"
+#~ msgstr "Termo de aceitação do usuário (EULA)"
+
+#~ msgid "devcp_form_label_externalsoftware"
+#~ msgstr "Este Complemento requer um software externo"
+
+#~ msgid "devcp_form_label_files"
+#~ msgstr "Arquivos"
+
+#~ msgid "devcp_form_label_homepage"
+#~ msgstr "Página inicial"
+
+#~ msgid "devcp_form_label_iconfile"
+#~ msgstr "Arquivo de ícone"
+
+#~ msgid "devcp_form_label_name"
+#~ msgstr "Nome"
+
+#~ msgid "devcp_form_label_platforms"
+#~ msgstr "Plataformas suportadas"
+
+#~ msgid "devcp_form_label_prerelease"
+#~ msgstr "Esta é uma pré-distribuição"
+
+#~ msgid "devcp_form_label_privacy"
+#~ msgstr "Políticas de privacidade"
+
+#~ msgid "devcp_form_label_sitespecific"
+#~ msgstr "Este é um Complemento para um site específico"
+
+#~ msgid "devcp_form_label_summary"
+#~ msgstr "Sumário"
+
+#~ msgid "devcp_form_label_supportemail"
+#~ msgstr "Email para suporte"
+
+#~ msgid "devcp_form_label_supporturl"
+#~ msgstr "URL para suporte"
+
+#~ msgid "devcp_form_label_target_applications"
+#~ msgstr "Aplicações alvo"
+
+#~ msgid "devcp_form_label_version"
+#~ msgstr "Versão"
+
+#~ msgid "devcp_form_label_versionnotes"
+#~ msgstr "Notas da versão"
+
+#~ msgid "devcp_form_no_target_apps"
+#~ msgstr "Nenhum"
+
+#~ msgid "devcp_form_reviewernotes"
+#~ msgstr "Notas para os revisores"
+
+#~ msgid "devcp_form_trustedaddon_destination"
+#~ msgstr ""
+#~ "Por seu Complemento ser confiável, descreva para onde esta versão deve "
+#~ "seguir:"
+
+#~ msgid "devcp_form_trustedaddon_destination_public"
+#~ msgstr "Público"
+
+#~ msgid "devcp_form_trustedaddon_destination_sandbox"
+#~ msgstr "Sandbox"
+
+#~ msgid "devcp_header_developer_agreement"
+#~ msgstr "Acordo do desenvolvedor"
+
+#~ msgid "devcp_header_step1"
+#~ msgstr "Passo 1"
+
+#~ msgid "devcp_header_step1_upload"
+#~ msgstr "Carregar um arquivo"
+
+#~ msgid "devcp_header_step2"
+#~ msgstr "Passo 2"
+
+#~ msgid "devcp_header_step2_addondetails"
+#~ msgstr "Detalhes do Complemento"
+
+#~ msgid "devcp_header_step3"
+#~ msgstr "Passo 3"
+
+#~ msgid "devcp_header_step3_versiondetails"
+#~ msgstr "Detalhes da versão"
+
+#~ msgid "devcp_header_step4"
+#~ msgstr "Passo 4"
+
+#~ msgid "devcp_header_step4_localization"
+#~ msgstr "Localização"
+
+#~ msgid "devcp_header_step5"
+#~ msgstr "Passo 5"
+
+#~ msgid "devcp_header_step5_success"
+#~ msgstr "Sucesso"
+
+#~ msgid "devcp_index_header_myaddons"
+#~ msgstr "Meus Complementos"
+
+#~ msgid "devcp_nominate_link_returnto_details"
+#~ msgstr "Voltar para os detalhes do Complemento"
+
+#~ msgid "devcp_notice_autodetected_addontype"
+#~ msgstr "Tipo do Complemento detectado automaticamente: %s."
+
+#~ msgid "devcp_notice_different_defaultlocale"
+#~ msgstr ""
+#~ "A localidade padrão deste Complemento (%1$s [%2$s]) é diferente da sua "
+#~ "localidade atual (%3$s [%4$s]). Os campos abaixo devem ser preenchidos em "
+#~ "%1$s."
+
+#~ msgid "devcp_question_addontype_incorrect"
+#~ msgstr "Incorreto?"
+
+#~ msgid "devcp_question_delete_file"
+#~ msgstr "Tem certeza de que deseja excluír este arquivo?"
+
+#~ msgid "devcp_skip_reviewing_addon_info"
+#~ msgstr "Pular a atualização das informações do Complemento"
+
+#~ msgid "devcp_submissions_disabled"
+#~ msgstr ""
+#~ "Submissões de Complementos estão desabilitadas no momento. Por favor, "
+#~ "tente novamente mais tarde."
+
+#~ msgid "devcp_submit_accept_dev_agreement"
+#~ msgstr "Eu aceito"
+
+#~ msgid "devcp_submit_decline_dev_agreement"
+#~ msgstr "Não aceito"
+
+#~ msgid "devcp_summary_admin_disabled"
+#~ msgstr "Este Complemento foi desativado por um administrador."
+
+#~ msgid "devcp_summary_header_disabled"
+#~ msgstr "Desabilitado"
+
+#~ msgid "devcp_summary_header_trusted"
+#~ msgstr "Confiável"
+
+#~ msgid "devcp_summary_noaddons_submit_one"
+#~ msgstr "Você não possui nenhum Complemento. Clique %s para enviar um."
+
+#~ msgid "devcp_summary_noaddons_submit_one_link"
+#~ msgstr "aqui"
+
+#~ msgid "devcp_theme_upload_preview"
+#~ msgstr "Assegure-se de %s para seu tema."
+
+#~ msgid "devcp_theme_upload_preview_link"
+#~ msgstr "carregar uma visualização"
+
+#~ msgid "devcp_version_edit_pagetitle"
+#~ msgstr "Editar versão"
+
+#~ msgid "devcp_version_updated_successfully"
+#~ msgstr "Versão atualizada com sucesso."
+
+#~ msgid "editors_submissiontype_new"
+#~ msgstr "Novo"
+
+#~ msgid "editors_submissiontype_updated"
+#~ msgstr "Atualizado"
+
+#~ msgid "editors_th_addon_age"
+#~ msgstr "Idade do Complemento"
+
+#~ msgid "editors_th_addontypes"
+#~ msgstr "Tipos de Complementos"
+
+#~ msgid "editors_th_age"
+#~ msgstr "Idade"
+
+#~ msgid "editors_th_applications"
+#~ msgstr "Aplicações"
+
+#~ msgid "editors_th_platforms"
+#~ msgstr "Plataformas"
+
+#~ msgid "editors_th_submissiontypes"
+#~ msgstr "Tipos de submissão"
+
+#~ msgid "error_notice"
+#~ msgstr "Aviso"
+
+#~ msgid "forum_save"
+#~ msgstr "salvar"
+
+#~ msgid "home"
+#~ msgstr "home"
+
+#~ msgid "nav_category_plugins"
+#~ msgstr "Plugins"
+
+#~ msgid "page_title_experimental_addons"
+#~ msgstr "Complementos Experimentais"
+
+#~ msgid "pages_experimental_addons_backbutton"
+#~ msgstr "Voltar para a página anterior"
+
+#~ msgid "pagination_page_number_title"
+#~ msgstr "Esta é a página %1$s de %2$s"
+
+#~ msgid "search_matching_addons_number"
+#~ msgid_plural "search_matching_addons_number"
+#~ msgstr[0] "%s Complemento encontrado"
+#~ msgstr[1] "%s Complementos encontrados"
+
+#~ msgid "statistics_rss_icon_title"
+#~ msgstr "RSS feed do resumo dos dados"
diff --git a/site/app/locale/pt_BR/images/sandbox-review.png b/site/app/locale/pt_BR/images/sandbox-review.png
new file mode 100644
index 0000000..607aa7c
--- /dev/null
+++ b/site/app/locale/pt_BR/images/sandbox-review.png
Binary files differ
diff --git a/site/app/locale/pt_BR/pages/error404.thtml b/site/app/locale/pt_BR/pages/error404.thtml
new file mode 100644
index 0000000..205ce55
--- /dev/null
+++ b/site/app/locale/pt_BR/pages/error404.thtml
@@ -0,0 +1,17 @@
+<h1>Desculpe, não foi possível encontrar o que está procurando.</h1>
+
+<p>A página ou arquivo requisitado não foi encontrado em nosso site. É possível que você tenha clicado em um link desatualizado ou digitado um endereço incorreto.</p>
+
+<ul>
+<li>Se você digitou o endereço, por favor verifique novamente o que foi digitado.</li>
+<li>Se você seguiu algum link, por favor nos avise em <a href="mailto:webmaster@mozilla.com" title="Page Not Found on Mozilla.com">webmaster@mozilla.com</a>. Descreva de que página você veio e o que estava procurando, e faremos o possível para solucionar o problema.</li>
+
+</ul>
+
+<p>Ou você pode querer ir para algumas das páginas mais populares em nosso site.</p>
+
+<ul>
+<li>Você está interessado em uma <a href="%1$s">lista de complementos mais populares</a>?</li>
+<li>Você quer <a href="%2$s">buscar complementos</a>? Você pode ir para a <a href="%2$s">página de busca</a> ou usar o campo de busca abaixo.</li>
+<li>Se você preferir começar novamente, vá para a <a href="%3$s">página inicial de complementos</a>.</li>
+</ul>
diff --git a/site/app/locale/pt_BR/pages/nomination.thtml b/site/app/locale/pt_BR/pages/nomination.thtml
new file mode 100644
index 0000000..d95367c
--- /dev/null
+++ b/site/app/locale/pt_BR/pages/nomination.thtml
@@ -0,0 +1,10 @@
+<p>Um complemento que está atualmente no sandbox pode ser indicado para fazer parte do site público e, assim, disponível para todos o usuários, após ser submetido a uma revisão por um editor. Para melhores resultados, note o seguinte:</p>
+<ul>
+ <li>Imagens para pré-visualização são necessárias para temas e altamente recomendadas para todos os outros tipos de complementos.</li>
+ <li>O complemento deve permanecer tempo suficente no sandbox para acumular revisões e feedback dos usuários. <b>Revisões são necessárias para se tornar público.</b></li>
+ <li>Complementos públicos possuem qualidade maior do que os que estão no sandbox e devem tornar a web melhor.</li>
+ <li>Os critérios completos para indicação estão disponíveis nas <a href="%s">Políticas do Add-ons</a>.</li>
+</ul>
+<p>Se seu complemento atender aos critérios acima, você poderá indicá-lo completando o campo abaixo. Você será notificado via e-mail sobre o andamento da sua indicação.</p>
+
+<p>Para indicar seu complemento, por favor descreva como ele foi testado ( incluindo se ele está livre de erros e warnings ) e como ele pode ser útil para a web como um todo. Você também pode incluir links para revisões externas de seu complemento.</p>
diff --git a/site/app/locale/pt_BR/pages/policy.thtml b/site/app/locale/pt_BR/pages/policy.thtml
new file mode 100644
index 0000000..e1d0729
--- /dev/null
+++ b/site/app/locale/pt_BR/pages/policy.thtml
@@ -0,0 +1,113 @@
+<h1>Política dos Complementos</h1>
+
+<h2>O que tem no Sandbox?</h2>
+<p>Veja %s.</p>
+
+<h2>Quais complemementos estão no sandbox?</h2>
+<p>O sandbox é onde todos os complementos são mantidos no AMO inicialmente. Ele contém novas versões de complementos públicos, assim como todas as versões dos complementos que não são públicos. Quando um novo complemento, ou uma atualização de um complemento existente, é enviado ao AMO, é armanezado no sandbox.</p>
+
+<p>Alguns complementos, e suas específicas versões, tornam-se públicos assim que o processo de revisão indica que estão prontos e apropriados para visilibilidade pública. Outros complementos vão permanecer no sandbox indefinidamente, onde estarão disponíveis aos usuários que escolherem navegar a lista do sandbox e experimentar os softwares contidos.</p>
+
+<h2>Como tornar os complementos públicos?</h2>
+
+<p>Complementos são revisados por usuários do AMO que decidem olhar no sandbox e testar os pacotes que lá se encontram. As revisões que usuários do AMO escrevem irão indicar se o complemento é suficientemente útil, bem escritos e bem acabados para serem expostos à frente de todos os usuários do Firefox. Estas revisões, possivelmente em conjunto com outras revisões e inspeções do time AMO, serão utilizadas para determinar se um dado complemento deve se tornar público, ou se precisa de mais atualizações para uma visibilidade maior, ou se não é apropriado para promoção no site AMO fora do sandbox. </p>
+
+<h2>Como faço para ter meu Complemento promovido publicamente?</h2>
+
+<p>Se você acredita que seu complemento (e o comportamento do mesmo) se encaixam nos critérios de um complemento público, você poderá nominá-lo através do painel de controle do desenvolvedor. </p>
+
+<h2>Quais são os critérios para um complemento ser público?</h2>
+
+<p>Um complemento que se torna público no AMO deverá ter alta qualidade e oferecer aos usuários uma melhor experiência na Web. Nós observamos os itens abaixo para decidir quando um complemento é apropriado para o público no AMO: </p>
+
+<h3>Você é responsável?</h3>
+
+<p>Nós esperamos que um autor que promove seus complementos para os muitos usuários do Firefox, seja responsável pelos problemas reportados, mantenha suas informações de contato e atualize seus complementos afim de mantê-los atualizados com versões do Firefox e possíveis mudanças na política do AMO. Isso não implica que você deve responder todas as questões que usuários enviam nas discussões, ou que seja necessário consertar todos os bugs, mas nós esperamos que você responda de maneira apropriada, dado a importância das questões. </p>
+
+<h3>O complemento possui uma descrição clara e precisa?</h3>
+
+<p>É da mais alta importância para nós que os usuários recebam aquilo que eles esperam ao instalar um novo complemento. Sua descrição deverá prover os detalhes sobre o que o complemento faz, como o usuário pode obter vantagem com ele e o que o usuário deverá esperar quando o instalar. Links para documentos externos com instruções detalhadas são permitidos, mas a descrição em si deverá cobrir o básico e permitir que usuários fiquem confiantes em saber o que eles estarão obtendo.</p>
+
+<p>Também é importante que você mantenha as notas de versão apropriadamente à medida que você melhora e modifca seu complemento. Usuários devem estar aptos a perceber o que existe de novo em um complemento que eles instalaram anteriormente, e devem poder entender as mudanças que poderão afetar a utilização do complemento assim que eles atualizarem. Exatamente agora os usuários não podem ver as notas da versão quando eles recebem uma notificação de atualização no Browser, mas nós estaremos arrumando isto. Se você mantiver as notas da versão, seus usuários poderão se beneficiar antes e depois deste trabalho ser completado ).</p>
+
+<h3>No que diz respeito a privacidade e segurança, os aspectos estão claramente escritos?</h3>
+
+<p>Este é um dos aspectos da descrição clara e precisa, mas é de tal importância que nós sentimos que merece ser mencionado a parte. Muitos dos complementos mais úteis e bem escritos tratam com manipulação de algum tipo de dados do usuário, ou podem apresentar perigo de segurança se utilizados incorretamente; esses são bem-vindos na área pública do AMO, mas deve-se colocar claramente aos usuários os devidos riscos que podem ser encontrados e o que os eles podem fazer para se protegerem. </p>
+
+<h3>O complemento tem sido bem testado, e encontra-se livre de defeitos sérios e óbvios?</h3>
+
+<p>Uma coisa importante que nós procuramos quando estudamos um complemento para acesso público é se suas revisões no sandbox indicam que ele foi testado minuciosamente e que ele não tem problemas sérios ou incompatibilidade no browser. Se revisores relatam problemas tais como performance, crashes, problemas constantes ao usar as funções do complemento ou spam de mensagens para o console erros, você deveria considerar profundamente esses relatos, e reindicar seu complemento depois de conduzir as considerações do melhor modo que puder. Não estamos esperando de você otimizaçao perfeita ou que tenha zero bugs – mesmo o Firefox permanece em constante melhorias nesta area – mas nós queremos que você mantenha razoáveis esforços para minimizar aspectos negativos e elimine de vez os casos, que se ficarem remanecentes podem surpreender os usuários.
+</p>
+
+<p>Se o seu complemento foi testado fora do processo do sandbox no AMO, como por exemplo por um grupo de usuários de seu serviço ou um time de qualidade interno, você deverá indicar isso, no campo de comentários, no processo de indicação. Isso certamente nos ajuda a entender qual o nível de teste que foi realizado e poderá ajudar seu complemento aparecer no site público. </p>
+
+<h3>O complemento assim como o autor do complemento, tratam o usuário respeitosamente?</h3>
+
+<p>Seu software não deveria intrometer-se desnecessariamente no usuário, tentar enganá-lo ou esconder dele algumas de suas atividades. Os usuários (ou mesmo não-usuários) são às vezes rudes em seus comentários. Enquanto nós vamos dar o melhor de nós para filtrar estes comentários, nós esperamos que os autores vitem retaliação com rudeza igual a eles. </p>
+
+<h3>O complemento é útil para uma porção grande dos usuários Firefox? </h3>
+
+<p>Seu complemento não precisa ser o popular como o Greasemonkey ou FireBug, mas se ele é somente útil para pessoas na sua empresa ou uma comunidade pequena, nós sentimos que ele não é apropriado ainda para ser colocado na frente de todos os usuários do Firefox.</p>
+
+<p>Nós estamos constantemente procurando maneiras de melhorar a organização do site para melhor acomodar complementos exemplares em outros modelos e que são intencionados para comunidades pequenas de usuários. A manutenção e categorização correta dos meta-dados do seu complemento estará nos ajudando a entender como poderemos trabalhar melhor esses tipos de complementos para as pessoas que provavelmente se beneficiarão deles. </p>
+
+<p>Se o seu complemento somente provê links para outros pontos de acesso no seu Web site, será considerado não apropriado para a parte pública do site. Como o resto do projeto Mozilla, nós adoramos aplicações Web e novos serviços Web, mas os Complementos do Firefox devem oferecer uma experiência de navegação melhor para o usuário e não servir apenas como uma maneira de promover um novo site ou serviço via listagem no AMO. Se a descrição do seu complemento é praticamente sobre o serviço e não sobre as melhorias que faz para o usuário na experiência de navegação, você provavelmente não está seguindo a trilha correta. </p>
+
+<h3>Seu complemento encontra-se livre de direito autoral e marcas não licenciadas?</h3>
+
+<p>Mesmo que você não tenha interesse em prejudicar o dono de uma marca, ou o possuidor de um direito autoral, nós não podemos prover acesso para complementos que infringem o direito autoral ou registro de marcas. Se você não tem permissão para usar uma marca ou nome previamente registrado, por favor não envie seu complemento ao AMO. Se o seu complemento inclui código que tem direitos autorais de outros e não encontra-se devidamente licenciado para usá-lo no seu complemento, por favor, não envie seu complemento ao AMO. (Se o proprietário de uma marca ou de direitos autorais apresentar queixas sobre a utilização de uma marca, nós iremos provavelmente ter o pedido de remoção revisado por um conselho e iremos remover o complemento se for legalmente necessário. Este é um processo caro em termos de recursos de projeto, includindo tempo e custos. Então, nós pedimos a você que tenha respeito e não cause dificuldades desnecessárias). </p>
+
+<p>Se você não está certo do nome do seu complemento ou o uso de algo dentro dele, deverá impedir que ele seja listado, você pode solicitar ajuda para amo-editors@mozilla.org. IMPORTANTE: Por favor, note que este grupo não está apto para oferecer conselho legal e mesmo que consideramos que o uso é aceitável, nós reservamos o direito de revisitar decisões, em vista de pedidos vindos por donos de direitos ou conselho de carater legal ou jurídico. </p>
+
+<p>Em termos de reutilização do código fonte de outros complementos, se um autor não colocou claramente que você tem permissão de utilização do código fonte no seu trabalho -- como por exemplo ter colocado o código fonte dentro de uma licença livre -- então você deve assumir que você não tem o direito da utilização. Você pode entrar em contado com o autor para procurar uma permissão, mas nós não estaremos atribuindo a você nenhum direito especial somente porque seu complemento foi colocado no AMO, ou devido ao fato de que o autor não respondeu seu pedido. (E mais uma vez, nós não oferecemos conselho legal, mas, apenas conselhos de como os complementos podem se interagir com as políticas do site). </p>
+
+<p>Estas notas se aplicam aos trademarks, e/ou direitos autorais da Mozilla Foundation, includindo "Mozilla", "Firefox" e "Thunderbird". A política do Mozilla, quanto ao uso de marcas, é feita para criar proteção contra confusão, e evitar que as marcas sejam prejudicadas devido a falta de proteção. Por favor, respeite a necessidade dessa exigência e nos ajude a preservar alguns dos valores mais importantes da Mozilla Foundation. </p>
+
+<h2>O que acontece depois que eu indico um complemento? </h2>
+
+<p>Uma vez que seu complemento foi indicado, este será avaliado por um time de editores do AMO de acordo com os critérios descritos anteriormente. Se o mesmo estiver devidamente pronto para visibilidade ao público, será então publicado, desde que já tenha sido avaliado, e você receberá um e-mail de notificação. </p>
+
+<p>Se nós sentirmos que o seu complemento não está apropriado para ser publicado no site AMO neste momento, você irá receber um e-mail de notificação indicando o porquê, e seu pedido de indicação será removido da fila. Se, e quando você sentir, que os problemas foram resolvidos na notificação e quiser ser avaliado de novo, você poderá re-indicar o complemento. Indicações repetidas sem conteúdo e melhorias no complemento não serão avaliadas positivamente, assim, recomenda-se exercitar o bom senso; [[[you are more likely to anger us than to wear us down.]]]</p>
+
+<h2>Eu posso indicar um complemento de outros?</h2>
+
+<p>No momento, nós pedimos que o autor do complemento indique os seus próprios trabalhos para publicação. Nós queremos ter certeza de que o autor sinta-se à vontade com o aumento da exposição e que sinta que o estado atual do seu complemento reflete a qualidade do seu trabalho. Se você acredita que um complemento está bem acabado, que o autor desistiu ou interrompeu devido aos termos e espírito das políticas do AMO, e que estaria beneficiando o Firefox, nossos usuários, e a web em geral ao ser colocado na frente de uma alta quantidade de usuários ao redor do mundo, encoraja o autor do complemento para que ele o indique. </p>
+
+
+<h2>Meu complemento está na fila de indicados há longo tempo. Vocês me odeiam? </h2>
+
+<p>Não. Nós gostamos de desenvolvedores de complementos e trabalhamos bastante para que eles sejam felizes e produtivos, para que usuários de todo o mundo possam se beneficiar com os trabalhos deles. Mas os artigos publicados no site AMO tem um valor precioso, nós damos muita importância para o que vai para lá. Assim, não podemos apressar, somente para que as coisas andem mais rápido. Sabemos que pode ser frustrante a espera até que seu complemento seja avaliado, e também nós queremos que o tempo de aprovação seja o mais breve possível. Quanto mais pessoas colocarem revisões claras e cuidadosas para os complementos no sandbox, mais fácil se torna o desenrolar dessas avaliações, assim você pode considerar ajudar neste aspecto se houver interesse. </p>
+
+<h2>Eu encontrei um bug sério no meu complemento, e eu realmente quero arrumar rapidamente. O que eu devo fazer? </h2>
+
+<p>Se existe um bug sério (segurança, estabilidade, problema de funcionalidade maior) para um complemento no qual você precisa de ter uma atualização rápida, você deverá indicar isso nas notas para o revisor no momento que enviar uma atualização -- assim como nas notas da versão, obviamente! Você pode também listar alguns usuários atuais do seu complemento para testar a atualização e reportar seus resultados em detalhes no sandbox. Aparecendo no canal #addons no irc.mozilla.org pode facilitar às pessoas o conhecimento da situação, mas tenha paciência e seja respeitoso se o fizer. </p>
+
+<p>Por favor não se desespere. Nós tentamos trabalhar rapidamente nas atualizações de alta prioridade, mas temos que avaliar outros complementos indicados ou versões e, frequentemente, isso custa-nos horas de sono ou o tempo de estarmos com nossas familias e amigos, assim nós não apreciamos pessoas que tentam se avantajar deste mecanismo para "furar a fila". Se você não está certo se deve seguir este caminho, o #addons no irc.mozilla.org poderá ajudá-lo a decidir. </p>
+
+<h2>Eu acho que eu fui tratado injustamente na avaliação do meu complemento. O que faço?</h2>
+
+<p>Se você acredita que seu complemento foi incorretamente avaliado, e que foi negado o estado público como um erro, você deve enviar um e-mail para amo-editors@mozilla.org com os detalhes da sua justificativa. Por favor, seja respeitoso e claro no seu e-mail, e esteja certo de ter dados sobre os motivos pelos quais o seu complemento foi avaliado incorretamente. </p>
+
+<p>(Se você arrumou *todas* as coisas que foram listadas como problemas no e-mail de notificação do revisor, você não deve apelar para a avaliação, mas deveria, ao invés disso, re-indicar o complemento para consideração através do Painel de Controle do Desenvolvedor).</p>
+
+<h2>Meu complemento costumava ser público, e agora existe somente no sandbox. O que aconteceu? </h2>
+
+<p>Se um complemento não mais mantém os critérios de estar no site público, nós poderemos movê-lo de volta ao sandbox. Exceto o caso de estarmos impedidos legalmente de fazê-lo, nós iremos informar via e-mail quando isto acontece e indicaremos as razões para tal. </p>
+
+<p>É também possível que você tenha encontrado um bug no site. Neste caso você deverá reportar o bug via Bugzilla; usar o "addons.mozilla.org" na seleção produto, o componente "Public Pages" e reportar o máximo de detalhe que você conseguir. </p>
+
+<h2>Meu complemento é público, e parece que as pessoas o adoram. Como faço para ficar na lista de complementos recomendados? </h2>
+
+<p>Se você acredita que seu complemento é um exemplo brilhante do poder dos complementos, que demonstra e enriquece o valores do Mozilla no contexto de extensão e personalização da web, e que ele oferece uma rica experiência ao usuário, você pode pedir para que seja adicionado à lista de complementos recomendados. Para fazer isto, você deve enviar um e-mail para amo-editors@mozilla.org explicando porque seu complemento é ótimo. </p>
+
+<p>Seu e-mail deve incluir <b>ao menos</b> as informações abaixo:</p>
+<ul>
+<li>Como a experiência da Web foi melhorada aos usuários</li>
+<li>Porque o seu complemento é apropriado para ser colocado à frente de grande quantidade de usuários Firefox?</li>
+
+<li>Como seu complemento demonstra e/ou serve para os valores do projeto Mozilla, especialmente com respeito a questão de oferecer controle ao usuário, proteção da privacidade e segurança, acesso universal a web e abrir padrões e dados.</li>
+<li>Como seu complemento se diferencia de outros complementos similares (nos aspectos comparativos entre melhor e pior.)</li>
+<li>Qual reação você observou dos usuários, revisores, blogadores, astronautas, ou seus animais de estimação, aspectos positivos e negativos</li>
+</ul>
+
+<p>Quanto mais completa for a informação que você colocar no seu pedido, maior será a probabilidade de avaliação e aprovação, no entanto até uma aplicação perfeitamente escrita e bem testada não implica em garantia que seja colocada na lista de recomendados. No final, a lista deve -- e é -- mantida sob discrição do Mozilla e acima de tudo, experiência e proteção do usuário. </p>
diff --git a/site/app/locale/pt_BR/pages/sandbox.thtml b/site/app/locale/pt_BR/pages/sandbox.thtml
new file mode 100644
index 0000000..458481f
--- /dev/null
+++ b/site/app/locale/pt_BR/pages/sandbox.thtml
@@ -0,0 +1,13 @@
+<h1>Sistema de revisão do Sandbox</h1>
+<h2>O que é o sandbox?</h2>
+<p> Sandbox é uma área para usuários avançados testarem seus complementos antes que eles sejam revisados para uso geral. Para acessar o sandbox, você deve habilitá-lo nas configurações de sua conta. Deve-se tomar cuidado ao instalar complementos do sandbox, pois eles ainda não foram testados por um editor e podem danificar seu computador.</p>
+
+<h2>Como eu faço para meu complemento ir para parte pública do site?</h2>
+<!-- To localize the flowchart image, see http://wiki.mozilla.org/Update:Remora_Sandbox_Flowchart -->
+<div style="text-align: center;">%s</div>
+<ol>
+ <li><b>Envie seu complemento ao Painel de Controle do Desenvolvedor.</b> Seu item vai aparecer imediatamente no sandbox do Mozilla Add-ons, onde usuários experientes irão testá-lo e prover feedback. Para ver o sandbox, você precisa habilitá-lo nas configurações de sua conta.</li>
+ <li><b>Indicar seu complemento para torná-lo público.</b> No Painel de Controle do Desenvolvedor existe um link para indicar seu complemento. Após indicado, seu complemento irá aparecer na fila para ser revisado por um Editor.</li>
+ <li><b>Um editor revisa seu complemento.</b> Um editor do Mozilla Add-ons irá instalar seu complemento e testá-lo para ver seu funcionamento. O editor também irá olhar as revisões feitas pelos testadores do sandbox.</li>
+ <li><b>Seu complemento se torna público ou é mantido no sandbox.</b> O editor irá tornar seu complemento público ou mantê-lo no sandbox. Se ele for mantido no sandbox, você pode indicá-lo novamente após fazer as modificações que o editor sugeriu em seus comentários. Se for publicado, as futuras versões do seu complemento irão aparecer no sandbox até que sejam revisadas por um editor e publicadas. Uma vez publicado, não há necessidade de indicar um complemento novamente - versões futuras irão automaticamente para fila de revisão.</li>
+</ol>
diff --git a/site/app/locale/pt_BR/pages/statistics_help.thtml b/site/app/locale/pt_BR/pages/statistics_help.thtml
new file mode 100644
index 0000000..fa3d9a7
--- /dev/null
+++ b/site/app/locale/pt_BR/pages/statistics_help.thtml
@@ -0,0 +1,7 @@
+<h3>Ajuda</h3>
+<p>O painel de estatísticas mostra informações sobre download e atualizações coletadas para seu complemento.</p>
+<h4>Downloads</h4>
+<p>Contagens de downloads são atualizadas diariamente e incluem apenas o download dos complementos originais, e não atualizações.</p>
+
+<h4>Update Pings</h4>
+<p>Complementos baixados deste site verificarão por atualizações uma vez ao dia, e o número total dessas atualizações é conhecido como Usuários ativos diariamente. Usuários ativos diariamente podem ser separados por versão do complemento, sistema operacional, estado do complemento, e aplicação. Esses dados são gravados para um dia em cada semana, nas quartas-feiras.</p>
diff --git a/site/app/locale/pt_BR/pages/submission_help.thtml b/site/app/locale/pt_BR/pages/submission_help.thtml
new file mode 100644
index 0000000..e50a687
--- /dev/null
+++ b/site/app/locale/pt_BR/pages/submission_help.thtml
@@ -0,0 +1,69 @@
+<h1>Ajuda para Submissão</h1>
+
+Os campos obrigatórios estão em <b>negrito</b>. Campos opicionais estão em <i>itálico</i>.
+
+<h2 id="step1">Passo 1: Envio de Arquivos</h2>
+
+<ul class="submissionHelp">
+
+ <li><span class="required">Tipo do Complemento</span> - Por padrão, o tipo do complemento será determinado automaticamente baseado no arquivo enviado. Você não deveria ter que mudar este campo.</li>
+
+ <li><span class="required">Arquivo do Complemento</span> - O pacote de arquivos de seu complemento, completo com um arquivo install.rdf. Se o arquivo só funcionar com uma plataforma específica, selecionar a plataforma é um meio de enviar múltiplos arquivos de uma só vez.</li>
+
+ <li><span class="optional">Arquivo de Ãcone</span> - O arquivo de ícone é mostrado próximo ao nome do complemento em sua página de exibição e também mostrado na mensagem de instalação do complemento. Ele será redimensionado automaticamente para 32x32 pixels, mantendo a proporção.</li>
+
+ <li><span class="required">Idioma Padrão</span> - O idioma padrão de um complemento é seu idioma principal. Se o idioma seleciona pelo usuárionão estiver disponível em seu complemento, será utilizado o idioma padrão.</li>
+
+ <li><span class="optional">Não revisar as informações do complemento atual</span> - Este campo irá aparecer se você estiver atualizado um complemento já existente. Marcando a caixa de seleção irá pular para o Passo 3, onde você pode inserir informações específicas da versão.</li>
+
+</ul>
+
+
+
+<h2 id="step2">Passo 2: Detalhes do Complemento</h2>
+
+<ul class="submissionHelp">
+
+ <li><span class="required">Nome</span> - Nome do complemento no idioma padrão.</li>
+
+ <li><span class="required">Autores</span> - Todos os usuários que tem acesso a modificar o cadastro do complemento e serão listados como autores na página do complemento.</li>
+
+ <li><span class="required">Categorias</span> - Categorias nas quais este complemento se encaixa.</li>
+
+ <li><span class="optional">Homepage</span> - O website do complemento em seu idioma padrão.</li>
+
+ <li><span class="required">Sumário</span> - Um breve sumário do complemento em seu idioma padrão. Este campo possui um limite de 250 caractéres e aparecerá na página do complemento, assim como nos resultados de busca/navegação.</li>
+
+ <li><span class="required">Descrição</span> - Uma descrição do complemento em seu idioma padrão. Isto irá aparecer na página do complemento abaixo do sumário.</li>
+
+ <li><span class="optional">EULA</span> - Os Termos de Aceitação do Usuário (EULA) que deverão ser aceitos pelo usuário antes do download, no idioma padrão.</li>
+
+ <li><span class="optional">Políticas de Privacidade</span> - As políticas de privacidade do complemento, no idioma padrão. Políticas de privacidade servem para explicar o que é feito com as informações pessoais do usuário e serão mostradas próximas ao botão Instalar na página do complemento. Mais informações sobre o que deve ser incluído nas políticas de privacidade e quando seu complemento precisa de uma, estão disponíveis em <a href="%s">Politicas dos Complementos</a>.</li>
+
+ <li><span class="optional">Permitir que os usuários vejam os arquivos fonte online</span> - Ao marcar esta caixa você autoriza os usuário a navegar pelos códigos fonte de seu complemento online.</li>
+
+ <li><span class="optional">Este é um pré lançamento</span> - Marcar esta caixa indica que seu complemento é um pré lançamento ou versão "beta". Complementos que são pré lançamentos deverão permanecer no sandbox e não poderão ser indicados para serem públicos até que este estado seja removido.</li>
+
+ <li><span class="optional">Este é um complemento para um site específico</span> - Marcar essa caixa indica que o complemento é específico para um único website, como um complemento que altera o visual de algum website ou exibe conteúdo de um website específico. Este campo é útil para editores e pode ser utilizado, no futuro, para filtrar buscas.</li>
+
+ <li><span class="optional">Este complemento requer algum software externo</span> - Marcar essa caixa indica que o complemento requer algum software externo. Este campo é útil para editores e pode ser utilizado, no futuro, para filtrar buscas.</li>
+
+</ul>
+
+
+
+<h2 id="step3">Passo 3: Detalhes da versão</h2>
+
+<ul class="submissionHelp">
+
+ <li><span class="required optional">Notas da Versão</span> - Um sumário ou uma lista das mudanças contidas nessa versão. Isso é opcional para novas submissões, mas é requerido para atualizações.</li>
+
+ <li><span class="optional">Notas para o revisor</span> - Este campo é utilizado para se comunicar com os editores quer irão revisar seu complemento. Contas para teste e detalhes especiais devem aparecer aqui.</li>
+
+</ul>
+
+
+
+<h2 id="step4">Step 4: Tradução</h2>
+
+Aqui é onde os campos do complmeneto podem ser traduzidos para todos os idiomas suportados. Basta clicar em um idioma para inserir as traduções.
diff --git a/site/app/locale/pt_PT/LC_MESSAGES/messages.mo b/site/app/locale/pt_PT/LC_MESSAGES/messages.mo
new file mode 100644
index 0000000..b32bd37
--- /dev/null
+++ b/site/app/locale/pt_PT/LC_MESSAGES/messages.mo
Binary files differ
diff --git a/site/app/locale/pt_PT/LC_MESSAGES/messages.po b/site/app/locale/pt_PT/LC_MESSAGES/messages.po
new file mode 100644
index 0000000..8aaea7e
--- /dev/null
+++ b/site/app/locale/pt_PT/LC_MESSAGES/messages.po
@@ -0,0 +1,7995 @@
+msgid ""
+msgstr ""
+"Project-Id-Version: \n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2009-01-16 11:45-0800\n"
+"PO-Revision-Date: \n"
+"Last-Translator: Carlos Simão <lloco73@gmail.com>\n"
+"Language-Team: pt-PT <portuguese european>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+"X-Poedit-Language: Portuguese\n"
+"X-Poedit-Country: PORTUGAL\n"
+
+#: views/addons/policy.thtml:98
+msgid "a_cancel_installation"
+msgstr "Cancelar Instalação"
+
+#. This is the text that appears on buttons to download add-ons.
+#. %$1s is an optional string that only appears if the add-on is only available for
+#. a certain platform. Examples: (Windows) or (Linux)
+#. Note that the parentheses are included in the string. :(
+#: views/elements/amo2009/install.thtml:126
+#: views/elements/amo2009/install.thtml:227
+#: views/elements/amo2009/install.thtml:257
+#: views/elements/amo2009/install.thtml:300
+#: views/elements/amo2009/install.thtml:312 views/elements/install.thtml:73
+#: views/elements/install.thtml:181 views/elements/install.thtml:205
+#: views/elements/install.thtml:248 views/elements/install.thtml:260
+#: views/addons/plugins.thtml:66 views/addons/plugins.thtml:76
+#: views/addons/plugins.thtml:86 views/addons/plugins.thtml:96
+#: views/addons/plugins.thtml:119
+#, php-format
+msgid "a_download"
+msgstr "Transferir Agora %s"
+
+#: views/addons/policy.thtml:72
+msgid "a_eula_download"
+msgstr "Aceitar e Transferir"
+
+#: views/addons/policy.thtml:74
+msgid "a_eula_install"
+msgstr "Aceitar e Instalar"
+
+#: views/elements/header.thtml:76 views/elements/header.thtml:82
+#: views/api/api_addon.thtml:55 views/api/collections_feed.thtml:75
+#: views/sharing_api/addon.thtml:64
+msgid "a_header_public"
+msgstr "Público"
+
+#: views/elements/header.thtml:58 views/elements/header.thtml:75
+#: views/elements/header.thtml:80 views/api/api_addon.thtml:57
+#: views/api/collections_feed.thtml:77 views/sharing_api/addon.thtml:66
+msgid "a_header_sandbox"
+msgstr "Sandbox"
+
+#. %s is a date in the _('date') format
+#: views/elements/amo2009/homepage_addon.thtml:115
+#: views/elements/addon_listitem.thtml:122 views/elements/feature.thtml:106
+#: views/addons/display.thtml:104 views/addons/browse_thumbs.thtml:73
+msgid "addon_detail_last_updated"
+msgstr "Actualizado %s"
+
+#. %s is the version of the add-on. Example: 3.2a1
+#: views/elements/amo2009/addon_version_detail.thtml:51
+#: views/elements/addon_version_detail.thtml:51
+#, php-format
+msgid "addon_display_header_version"
+msgstr "Versão %s"
+
+#: views/addons/browse_thumbs.thtml:80
+msgid "addon_downloads"
+msgstr "transferências"
+
+#: views/addons/display.thtml:147
+msgid "addon_downloads_total"
+msgstr "Transferências totais"
+
+#: views/elements/amo2009/homepage_addon.thtml:106
+#: views/elements/addon_listitem.thtml:115 views/elements/feature.thtml:101
+#: views/addons/category_landing.thtml:157 views/addons/display.thtml:146
+#: views/addons/browse_thumbs.thtml:80
+msgid "addon_downloads_weekly"
+msgstr "Transferências semanais"
+
+#. %1 is the add-on count, %2 the category name
+#: views/addons/browse_thumbs.thtml:104 views/addons/browse.thtml:60
+#, php-format
+msgid "addon_list_category_totalcount"
+msgid_plural "addon_list_category_totalcount"
+msgstr[0] "%1$s extra "
+msgstr[1] "%1$s extras"
+
+#: views/elements/amo2009/addon_list_options.thtml:103
+#: views/elements/pagination.thtml:67
+#: views/elements/addon_list_options.thtml:94
+msgid "addon_list_perpage"
+msgstr "por página"
+
+#: views/elements/amo2009/addon_list_options.thtml:84
+#: views/elements/addon_list_options.thtml:98
+msgid "addon_list_sortby"
+msgstr "Ordenar por:"
+
+#: views/helpers/addons_html.php:568 views/elements/amo2009/install.thtml:321
+#: views/elements/feature.thtml:89
+msgid "addon_listitem_flag_experimental"
+msgstr "em teste"
+
+#: views/helpers/addons_html.php:570
+msgid "addon_listitem_flag_recommended"
+msgstr "recomendado"
+
+#. %1 is the add-on name, %2 is the platform
+#: views/pages/js_constants.js.thtml:66
+msgid "addon_not_available_for_platform"
+msgstr "%1$s não está disponível para %2$s."
+
+#. %1 is the add-on name
+#: views/addons/policy.thtml:101 views/addons/previews.thtml:60
+#: views/addons/versions.thtml:130 views/reviews/flag.thtml:61
+#: views/reviews/add.thtml:114 views/reviews/display.thtml:216
+#: views/reviews/review_added.thtml:57
+#, php-format
+msgid "addon_review_a_back_to_addon_x"
+msgstr "Voltar a %1$s..."
+
+#. %1 is the add-on name
+#: views/reviews/flag.thtml:60 views/reviews/add.thtml:113
+#: views/reviews/review_added.thtml:56
+#, php-format
+msgid "addon_review_a_back_to_reviews"
+msgstr "Voltar aos comentários..."
+
+#: views/reviews/add.thtml:85
+msgid "addon_review_add_rating_field"
+msgstr "Classificação:"
+
+#: views/reviews/add.thtml:102
+msgid "addon_review_add_review_field"
+msgstr "Comentário:"
+
+#: views/reviews/add.thtml:107
+msgid "addon_review_add_submit"
+msgstr "Submeter o seu comentário"
+
+#. %s is the name of the add-on
+#: views/reviews/add.thtml:51
+#, php-format
+msgid "addon_review_add_title"
+msgstr "Adicionar um comentário a %s"
+
+#: views/reviews/add.thtml:78
+msgid "addon_review_add_title_field"
+msgstr "Título/Sumário:"
+
+#: views/reviews/display.thtml:77 views/reviews/display.thtml:161
+msgid "addon_review_admin_delete"
+msgstr "Apagar"
+
+#: views/reviews/display.thtml:76
+msgid "addon_review_author_reply_link"
+msgstr "Responder"
+
+#: views/reviews/delete.thtml:62
+msgid "addon_review_confirm_delete"
+msgstr "Tem a certeza que deseja eliminar este comentário?"
+
+#: views/reviews/delete.thtml:63
+msgid "addon_review_confirm_no"
+msgstr "Não"
+
+#: views/reviews/delete.thtml:64
+msgid "addon_review_confirm_yes"
+msgstr "Sim"
+
+#: views/reviews/delete.thtml:48
+msgid "addon_review_delete_header"
+msgstr "Eliminar comentário"
+
+#: controllers/reviews_controller.php:449
+msgid "addon_review_deleted_successfully"
+msgstr "Comentário eliminado com sucesso."
+
+#. %s is the name of the add-on
+#: views/reviews/add.thtml:51
+#, php-format
+msgid "addon_review_edit_title"
+msgstr "Editar comentário para %s"
+
+#. %1 is the count of characters entered as notes for the review flag reason.
+#: controllers/reviews_controller.php:539
+msgid "addon_review_flag_error_other_length"
+msgstr ""
+"Problema ao indicar comentário: Notas para indicações de comentários estão "
+"limitadas de 10 e 100 caracteres: a sua palavra tinha %1$s."
+
+#. Removing an extra comma
+#: views/reviews/review_added.thtml:53
+msgid "addon_review_in_moderation"
+msgstr ""
+"Nota: Antes do seu comentário ser apresentado, será moderado por um editor."
+
+#: views/reviews/add.thtml:57
+msgid "addon_review_in_reply_to"
+msgstr "O Desenvolvedor responde para:"
+
+#. %1 is the review count, %2 is the nickname or full name of the user.
+#: views/reviews/display.thtml:131
+#, php-format
+msgid "addon_review_others_by_user"
+msgid_plural "addon_review_others_by_user"
+msgstr[0] "Veja o comentário anterior do %1$s submetido por %2$s ."
+msgstr[1] ""
+"Veja os %1$s comentários anteriores submetidos por %2$s para este extra."
+
+#. %1 is the add-on name
+#: controllers/reviews_controller.php:201
+#: controllers/reviews_controller.php:250
+#: controllers/reviews_controller.php:345
+#: controllers/reviews_controller.php:424
+#, php-format
+msgid "addon_review_pagetitle"
+msgstr "Avaliações para %s"
+
+#. %1 is the user, %2 is the (localized) date
+#: views/reviews/display.thtml:160
+#, php-format
+msgid "addon_review_reply_on_x_by_y"
+msgstr "Respondido por %1$s em %2$s"
+
+#: views/reviews/display.thtml:157
+msgid "addon_review_reply_prefix"
+msgstr "Resposta do Desenvolvedor:"
+
+#: views/reviews/review_added.thtml:51
+msgid "addon_review_saved_successfully"
+msgstr "O seu comentário foi guardado com sucesso. Obrigado!"
+
+#: views/addons/display.thtml:354 views/reviews/display.thtml:72
+msgid "addon_reviewed_by_u_on_d"
+msgstr "por %1$s em %2$"
+
+#. %1 is the user, %2 is the (localized) date, %3 is the rating
+#: views/editors/reviews_queue.thtml:57 views/editors/reviews_queue.thtml:68
+#: views/reviews/add.thtml:63 views/reviews/delete.thtml:54
+#, php-format
+msgid "addon_reviewed_on_x_rated_y"
+msgstr "por %1$s em %2$s (Classificação de %3$s)"
+
+#: views/elements/amo2009/addon_version_detail.thtml:52
+#: views/elements/addon_version_detail.thtml:52
+msgid "addon_version_permalink"
+msgstr "Ligação permanebte para esta versão"
+
+#. %1 is the current Application name (e.g. Firefox)
+#. %2 is the Application's version number
+#: views/addons/versions.thtml:140
+msgid "addon_versions_getlatestversion"
+msgstr "A versão mais recente compatível com o %1$s %2$s"
+
+#: views/addons/display.thtml:447
+msgid "addons_author_addons_submit"
+msgstr "Ir"
+
+#: views/elements/amo2009/homepage_addon.thtml:100
+#: views/elements/feature.thtml:95
+msgid "addons_author_tooltip"
+msgstr "Ver perfil do autor"
+
+#. %1 is the name of the Application (eg. Firefox)
+#: controllers/addons_controller.php:1296
+msgid "addons_browse_all_themes_title"
+msgstr "Navegar em todos os temas :: Extras do %1$s"
+
+#. %s is the name of the category
+#: controllers/addons_controller.php:1016
+#, php-format
+msgid "addons_browse_browse_category"
+msgstr "Explorar %s"
+
+#. %1 is the name of the theme category (eg. Modern)
+#. %2 is the name of the Application (eg. Firefox)
+#: controllers/addons_controller.php:664
+msgid "addons_browse_categories_header_theme"
+msgstr "Navegar nos temas do %1$s :: Extras do %2$s"
+
+#: views/addons/display.thtml:249
+msgid "addons_display_a_license_what"
+msgstr "O que é isto?"
+
+#: views/reviews/display.thtml:222
+msgid "addons_display_add_review"
+msgstr "Adicionar comentário"
+
+#: views/addons/display.thtml:294
+msgid "addons_display_advanced_details"
+msgstr "Detalhes avançados"
+
+#: views/addons/display.thtml:98
+msgid "addons_display_categories"
+msgstr "Categorias"
+
+#: views/addons/display.thtml:482
+msgid "addons_display_collection_add"
+msgstr "Adicionar a uma colecção:"
+
+#: views/addons/display.thtml:491
+msgid "addons_display_collection_add_new"
+msgstr "Nova colecção..."
+
+#: views/addons/display.thtml:487
+msgid "addons_display_collection_add_select_one"
+msgstr "Seleccione uma colecção..."
+
+#: views/addons/display.thtml:493
+msgid "addons_display_collection_add_submit"
+msgstr "Publicar"
+
+#. %1$s is the add-on name
+#. %2$s is the collection name, linked to the collection's page
+#: views/pages/js_constants.js.thtml:103 views/addons/display.thtml:61
+msgid "addons_display_collection_publish_success"
+msgstr "%1$s foi adicionado à colecção de %2$s."
+
+#: views/addons/display.thtml:483
+msgid "addons_display_collection_whatsthis"
+msgstr "O que é isto?"
+
+#. %1$s is a number
+#: views/addons/display.thtml:473
+msgid "addons_display_collections_more"
+msgid_plural "addons_display_collections_more"
+msgstr[0] "e mais %1$s colecção"
+msgstr[1] "e mais %1$s colecções"
+
+#: views/addons/display.thtml:403
+msgid "addons_display_detailed_review"
+msgstr "comentário detalhado"
+
+#: views/reviews/add.thtml:89 views/reviews/add.thtml:90
+msgid "addons_display_dont_like_it"
+msgstr "Não gostei"
+
+#: views/reviews/display.thtml:220
+msgid "addons_display_edit_review"
+msgstr "Editar o seu comentário"
+
+#: views/addons/display.thtml:132
+msgid "addons_display_has_privacy"
+msgstr "Este extra tem uma política de privacidade."
+
+#: views/reviews/add.thtml:87 views/reviews/add.thtml:88
+msgid "addons_display_hate_it"
+msgstr "Odiei"
+
+#: views/addons/display.thtml:462
+msgid "addons_display_header_collections"
+msgstr "Colecções relacionadas"
+
+#: views/addons/display.thtml:297
+msgid "addons_display_header_developer_comments"
+msgstr "Comentários do desenvolvedor"
+
+#: views/addons/display.thtml:230
+msgid "addons_display_header_homepage"
+msgstr "Página Inicial"
+
+#: views/addons/display.thtml:247 views/addons/versions.thtml:110
+msgid "addons_display_header_license"
+msgstr "Licença do código fonte"
+
+#: views/addons/display.thtml:337
+msgid "addons_display_header_reviews"
+msgstr "Comentários"
+
+#: views/addons/display.thtml:261
+msgid "addons_display_header_support"
+msgstr "Suporte"
+
+#: views/reviews/add.thtml:91 views/reviews/add.thtml:92
+msgid "addons_display_like_it"
+msgstr "Gostei"
+
+#: views/addons/display.thtml:210
+msgid "addons_display_long_description"
+msgstr "descrição Longa"
+
+#: views/reviews/add.thtml:95 views/reviews/add.thtml:96
+msgid "addons_display_love_it"
+msgstr "Adorei"
+
+#: views/addons/display.thtml:178
+msgid "addons_display_more_images"
+msgstr "Mais Imagens"
+
+#: views/addons/display.thtml:465
+msgid "addons_display_nocollections"
+msgstr "Este extra ainda não está em nenhuma colecção."
+
+#. %1$s is either an author's name or a comma separated list of authors. Using
+#. the list doesn't make sense in the English plural form so we ignore the
+#. variable.
+#: views/addons/display.thtml:436
+msgid "addons_display_other_addons_by"
+msgid_plural "addons_display_other_addons_by"
+msgstr[0] "Outros extras de %1$s"
+msgstr[1] "Outros extras destes autores"
+
+#. %s is the name of the add-on and the add-on section. Example:
+#. Some Add-on :: Firefox Add-ons
+#. This should not be concatenated in the code and should be fixed.
+#: controllers/addons_controller.php:141 controllers/addons_controller.php:280
+#: controllers/addons_controller.php:1442
+#, php-format
+msgid "addons_display_pagetitle"
+msgstr "%s"
+
+#. %s is an email address
+#: views/addons/display.thtml:286
+#, php-format
+msgid "addons_display_paragraph_supportinfoemail"
+msgstr "O suporte para este extra e fornecido pelo desenvolvedor em %s"
+
+#. %$1s is a URL
+#. %$2s is an email address
+#: views/addons/display.thtml:269
+#, php-format
+msgid "addons_display_paragraph_supportinfoemailurl"
+msgstr ""
+"O Suporte para esta extensão é fornecido pelo desenvolvedor em %s ou "
+"enviandouma mensagem de correio electrónico para %s"
+
+#. %s is a URL
+#: views/addons/display.thtml:278
+#, php-format
+msgid "addons_display_paragraph_supportinfourl"
+msgstr "O suporte para este extra e fornecido pelo desenvolvedor em %s"
+
+#: views/addons/display.thtml:383
+msgid "addons_display_rate_it"
+msgstr "Avalie"
+
+#: views/reviews/add.thtml:93 views/reviews/add.thtml:94
+msgid "addons_display_really_like_it"
+msgstr "Gostei mesmo"
+
+#: views/addons/display.thtml:410
+msgid "addons_display_review_etiquette"
+msgstr ""
+"Por favor não coloque relatos de erro nos comentários. Nós não "
+"disponibilizamos o seu endereço de correio ao desenvolvedor do extra e ele "
+"poderá ter que o contactar para resolver o problema."
+
+#. %1 is the review guidelines link
+#: views/addons/display.thtml:417
+msgid "addons_display_review_guidelines_link"
+msgstr "<a href=\"%s\">Guia sobre comentários</a>"
+
+#. %1 is the support section link
+#: views/addons/display.thtml:414
+msgid "addons_display_review_see_support"
+msgstr ""
+"Veja a <a href=\"%1$s\">secção de suporte</a> para saber onde obter ajuda "
+"sobre este extra."
+
+#: views/addons/display.thtml:404
+msgid "addons_display_review_submit"
+msgstr "Guardar"
+
+#: views/addons/display.thtml:430
+#, php-format
+msgid "addons_display_see_all_addons"
+msgstr "Ver todos os Extras de %1$s"
+
+#. %1 is the number of reviews
+#: views/addons/display.thtml:364
+#, php-format
+msgid "addons_display_see_all_reviews"
+msgstr "Ver todas as avaliações (%1$s)"
+
+#: views/addons/display.thtml:219
+msgid "addons_display_see_all_versions"
+msgstr "Ver todas a Versões"
+
+#: views/addons/display.thtml:321 views/addons/versions.thtml:117
+msgid "addons_display_view_source"
+msgstr "Ver a fonte"
+
+#: views/addons/display.thtml:324
+msgid "addons_display_view_stats"
+msgstr "Ver estatísticas"
+
+#: views/addons/display.thtml:376
+msgid "addons_display_what_do_you_think"
+msgstr "O que acha?"
+
+#: views/elements/app_compatibility.thtml:49
+msgid "addons_display_workswith"
+msgstr "Funciona com:"
+
+#: views/addons/home.thtml:112
+msgid "addons_home_browse_new"
+msgstr "Adicionado recentemente"
+
+#: views/addons/home.thtml:110
+msgid "addons_home_browse_popular"
+msgstr "Popular"
+
+#: views/addons/home.thtml:108
+msgid "addons_home_browse_recommended"
+msgstr "Recomendado"
+
+#: views/addons/home.thtml:127 views/addons/home.thtml:134
+#: views/addons/home.thtml:141 views/addons/home.thtml:148
+msgid "addons_home_browse_subscribe"
+msgstr "Subscrever"
+
+#: views/addons/home.thtml:101
+msgid "addons_home_browse_title"
+msgstr "Navegar nos extras"
+
+#: views/addons/home.thtml:114
+msgid "addons_home_browse_updated"
+msgstr "Actualizado"
+
+#: views/elements/amo2009/homepage_addon.thtml:100
+#: views/elements/addon_discussionheader.thtml:83
+#: views/elements/addon_listitem.thtml:109 views/elements/feature.thtml:95
+#: views/addons/category_landing.thtml:66 views/addons/policy.thtml:57
+#: views/addons/display.thtml:70 views/addons/home.thtml:178
+msgid "addons_home_by"
+msgstr "por"
+
+#: views/addons/home.thtml:169
+msgid "addons_home_collection_popular_title"
+msgstr "Colecções populares"
+
+#: views/elements/amo2009/categories.thtml:69 views/addons/home.thtml:160
+msgid "addons_home_collections"
+msgstr "Colecções"
+
+#. %1$s is the count of addons in a collection
+#: views/elements/amo2009/collection_listing_item.thtml:51
+#: views/addons/home.thtml:185
+msgid "addons_home_collections_addon_count"
+msgid_plural "addons_home_collections_addon_count"
+msgstr[0] "<strong>%1$s</strong> extra"
+msgstr[1] "<strong>%1$s</strong> add-ons"
+
+#: views/addons/home.thtml:196
+msgid "addons_home_collections_all"
+msgstr "Ver todas as colecções"
+
+#: views/addons/home.thtml:162
+#, fuzzy
+msgid "addons_home_collections_intro"
+msgstr ""
+"Collections are a way for you to categorize, mix, match and mingle add-ons. "
+"Subscribe to collections created by other users or create your own."
+
+#. %1$s is the count of subscribers for a collection
+#: views/elements/amo2009/collection_listing_item.thtml:58
+#: views/collections/detail.thtml:96 views/addons/home.thtml:189
+msgid "addons_home_collections_subscribers"
+msgid_plural "addons_home_collections_subscribers"
+msgstr[0] "<strong>%1$s</strong> subscritor"
+msgstr[1] "<strong>%1$s</strong> subscritores"
+
+#: views/addons/searchengines.thtml:54 views/addons/themes_landing.thtml:49
+msgid "addons_home_feature_head"
+msgstr "Nós recomendamos"
+
+#: controllers/search_controller.php:218 controllers/addons_controller.php:176
+#: controllers/addons_controller.php:428 controllers/addons_controller.php:671
+#: controllers/addons_controller.php:871
+#: controllers/addons_controller.php:1103
+#: controllers/addons_controller.php:1242
+#: controllers/addons_controller.php:1298
+#, php-format
+msgid "addons_home_header_details"
+msgstr ""
+"Os extras melhoram o %1$s, deixando-o personalizar a sua experiência de "
+"navegação. Dê uma vista de olhos e faça o seu %1$s."
+
+#. %1$s is the HTML collection name link.
+#: views/elements/amo2009/teaser_collections.thtml:107
+msgid "addons_home_introduction_collection_link"
+msgstr "Gostou? Encontre mais extras em %1$s."
+
+#: views/elements/amo2009/teaser_collections.thtml:60
+msgid "addons_home_introduction_extras"
+msgstr ""
+"<strong>Mais de 5000 extras grátis</strong> que lhe permitem personalizar o "
+"Firefox para ir de encontro às suas necessidades."
+
+#: views/elements/amo2009/teaser_collections.thtml:55
+msgid "addons_home_introduction_header"
+msgstr "O que são extras?"
+
+#: views/elements/amo2009/teaser_collections.thtml:72
+msgid "addons_home_introduction_install"
+msgstr ""
+"<strong>Fácil de instalar</strong>, seja notificado quando forem "
+"disponibilizadas actualizações."
+
+#: views/elements/amo2009/teaser_collections.thtml:45
+msgid "addons_home_introduction_name"
+msgstr "Introdução"
+
+#: views/elements/amo2009/teaser_collections.thtml:66
+#, fuzzy
+msgid "addons_home_introduction_themes"
+msgstr ""
+"Toolbars, themes and search providers that <strong>help you perform common "
+"tasks.</strong>"
+
+#: views/addons/home.thtml:161
+msgid "addons_home_new_indicator"
+msgstr "NOVO!"
+
+#: views/elements/app_chooser.thtml:48 views/layouts/amo2009.thtml:257
+msgid "addons_home_other_applications"
+msgstr "Outras Aplicações"
+
+#. %1$s is the application the user is browsing. Examples: Thunderbird, Firefox,
+#. Sunbird
+#: views/pages/collector_faq.thtml:49 views/pages/collector_firstrun.thtml:42
+#: views/pages/collector.thtml:46 views/pages/collector_features.thtml:54
+#: controllers/developers_controller.php:87
+#: controllers/compatibility_controller.php:72
+#: controllers/components/simple_acl.php:81 controllers/components/amo.php:607
+#: controllers/statistics_controller.php:60
+#: controllers/statistics_controller.php:240
+#: controllers/previews_controller.php:67 controllers/users_controller.php:90
+#: controllers/users_controller.php:223 controllers/users_controller.php:330
+#: controllers/users_controller.php:414 controllers/users_controller.php:708
+#: controllers/users_controller.php:723 controllers/reviews_controller.php:204
+#: controllers/reviews_controller.php:251
+#: controllers/reviews_controller.php:346
+#: controllers/reviews_controller.php:425
+#: controllers/search_controller.php:185 controllers/search_controller.php:297
+#: controllers/search_controller.php:301 controllers/addons_controller.php:147
+#: controllers/addons_controller.php:280 controllers/addons_controller.php:370
+#: controllers/addons_controller.php:667 controllers/addons_controller.php:874
+#: controllers/addons_controller.php:1019
+#: controllers/addons_controller.php:1034
+#: controllers/addons_controller.php:1101
+#: controllers/addons_controller.php:1121
+#: controllers/addons_controller.php:1240
+#: controllers/addons_controller.php:1357
+#: controllers/addons_controller.php:1364
+#: controllers/addons_controller.php:1442
+#: controllers/addons_controller.php:1477
+#: controllers/addons_controller.php:1538
+#: controllers/addons_controller.php:1543
+#: controllers/editors_controller.php:64 controllers/pages_controller.php:132
+#: controllers/groups_controller.php:65 controllers/groups_controller.php:71
+#: controllers/groups_controller.php:89 controllers/groups_controller.php:111
+#: controllers/collections_controller.php:57
+#: controllers/collections_controller.php:121
+#: controllers/collections_controller.php:205
+#: controllers/collections_controller.php:365
+#: controllers/collections_controller.php:404
+#: controllers/collections_controller.php:466
+#: controllers/collections_controller.php:538
+#: controllers/collections_controller.php:828
+#: controllers/localizers_controller.php:72
+#, php-format
+msgid "addons_home_pagetitle"
+msgstr "Extras do %1$s "
+
+#. %1$s is the number of addons downloaded
+#: views/addons/home.thtml:57
+#, php-format
+msgid "addons_home_stats_downloaded"
+msgid_plural "addons_home_stats_downloaded"
+msgstr[0] "<strong>%1$s</strong> <span>extra transferido</span>"
+msgstr[1] "<strong>%1$s</strong> <span>extras transferidos</span>"
+
+#. %1$s is the number of addons in use
+#: views/addons/home.thtml:63
+#, php-format
+msgid "addons_home_stats_inuse"
+msgid_plural "addons_home_stats_inuse"
+msgstr[0] "<strong>%1$s</strong> <span>extra em uso</span>"
+msgstr[1] "<strong>%1$s</strong> <span>extra em uso</span>"
+
+#: views/addons/home.thtml:136
+msgid "addons_home_view_all_newest_title"
+msgstr "Ver todos os extras recentes"
+
+#: views/addons/home.thtml:129
+msgid "addons_home_view_all_popular_title"
+msgstr "Ver todos os extras populares"
+
+#: views/addons/home.thtml:150
+msgid "addons_home_view_all_recommended_title"
+msgstr "Ver todos os extras recomendados"
+
+#: views/addons/home.thtml:143
+msgid "addons_home_view_all_updated_title"
+msgstr "Ver todos os extras actualizados recentemente"
+
+#: views/elements/amo2009/install.thtml:334 views/elements/install.thtml:112
+msgid "addons_install_in_sunbird"
+msgstr ""
+"<ol><li>Clique na ligação abaixo para guardar o ficheiro.</li><li>No Mozilla "
+"Sunbird, abrir os extras a partir do menu ferramentas.</li><li>Clique no "
+"botão instalar e localize/seleccione o ficheiro que transferiu e clique \"OK"
+"\".</li></ol>"
+
+#: views/elements/amo2009/install.thtml:333 views/elements/install.thtml:111
+msgid "addons_install_in_sunbird_title"
+msgstr "Como instalar no Sunbird"
+
+#: views/elements/amo2009/install.thtml:331 views/elements/install.thtml:106
+msgid "addons_install_in_thunderbird"
+msgstr ""
+"<ol><li>Clique com o botão direito do rato na ligação abaixo e escolha "
+"\"Guardar ligação como...\" para transferir e guardar o ficheiro no seu "
+"disco rígido.</li><li>No Mozilla Thunderbird, abra Extras a partir do menu "
+"Ferramentas.</li><li>Clique no botão Instalar, localize/seleccione o "
+"ficheiro que transferiu e depois clique em \"OK\".</li></ol>"
+
+#: views/elements/amo2009/install.thtml:330 views/elements/install.thtml:105
+msgid "addons_install_in_thunderbird_title"
+msgstr "Como instalar no Thunderbird"
+
+#: views/elements/amo2009/addon_list_options.thtml:108
+#: views/elements/addon_list_options.thtml:105
+msgid "addons_options_show_experimental"
+msgstr "mostrar extras em teste"
+
+#: views/elements/amo2009/addon_list_options.thtml:113
+#: views/elements/addon_list_options.thtml:109
+msgid "addons_options_submit"
+msgstr "Ir"
+
+#: views/addons/plugins.thtml:63 views/addons/plugins.thtml:73
+#: views/addons/plugins.thtml:83 views/addons/plugins.thtml:93
+#: views/addons/plugins.thtml:103 views/addons/plugins.thtml:116
+#: views/addons/plugins.thtml:126
+msgid "addons_plugins_by"
+msgstr "Por"
+
+#: views/addons/plugins.thtml:107
+msgid "addons_plugins_for_linux"
+msgstr "para Linux"
+
+#: views/addons/plugins.thtml:108 views/addons/plugins.thtml:131
+msgid "addons_plugins_for_macosx"
+msgstr "para Mac OS X"
+
+#: views/addons/plugins.thtml:106 views/addons/plugins.thtml:129
+#: views/addons/plugins.thtml:130
+msgid "addons_plugins_for_windows"
+msgstr "para Windows"
+
+#. %1$s is a URL
+#: views/addons/plugins.thtml:139
+#, php-format
+msgid "addons_plugins_looking_for_more"
+msgstr ""
+"Esta lista apresenta apenas alguns dos mais comuns e populares plugins. Para "
+"mais informação sobre os plugins disponíveis para os Navegadores baseados no "
+"Mozilla, visite %1$s"
+
+#: views/addons/plugins.thtml:137
+msgid "addons_plugins_looking_for_plugin"
+msgstr "Procura um plugin que não está aqui?"
+
+#: views/addons/plugins.thtml:58
+msgid "addons_plugins_main_description"
+msgstr ""
+"Os Plugins ajudam o seu navegador a efectuar funções específicas como, por "
+"exemplo, ver formatos de gráficos especiais ou tocar ficheiros multimédia. "
+"Os Plugins são ligeiramente diferentes das extensões, que modificam ou "
+"adicionam funcionalidades existentes."
+
+#. %1$s is the application name. Example: Firefox, Thunderbird, Sunbird
+#: controllers/addons_controller.php:1122
+#, php-format
+msgid "addons_plugins_main_header"
+msgstr "Plugins Comuns para o %1$s"
+
+#: controllers/components/amo.php:698 controllers/addons_controller.php:1121
+msgid "addons_plugins_pagetitle"
+msgstr "Plugins"
+
+#: views/addons/plugins.thtml:68 views/addons/plugins.thtml:78
+#: views/addons/plugins.thtml:88 views/addons/plugins.thtml:98
+#: views/addons/plugins.thtml:110 views/addons/plugins.thtml:121
+#: views/addons/plugins.thtml:133
+msgid "addons_plugins_support_documentation"
+msgstr "Documentação de Suporte: "
+
+#. %s is the name of the add-on
+#: views/addons/policy.thtml:61
+#, php-format
+msgid "addons_policy_eula_require"
+msgstr ""
+"O %s necessita que aceite o seguinte Acordo de Licença para o Utilizador "
+"Final antes da instalação poder continuar:"
+
+#. %1 is the add-on name
+#: controllers/addons_controller.php:1476
+#, php-format
+msgid "addons_previews_pagetitle"
+msgstr "Pré-visualizações para %s"
+
+#: views/addons/category_landing.thtml:135
+msgid "addons_recently_added"
+msgstr "Adicionado recentemente"
+
+#: views/addons/recommended.thtml:51 controllers/addons_controller.php:1365
+msgid "addons_recommended_introduction"
+msgstr ""
+"Com tantos extras disponíveis, existe algo para toda a gente. Para começar, "
+"aqui está uma lista dos mais populares. Aprecie-os!"
+
+#: controllers/addons_controller.php:1357
+#: controllers/addons_controller.php:1364
+msgid "addons_recommended_pagetitle"
+msgstr "Extras Recomendados"
+
+#: controllers/addons_controller.php:1360
+msgid "addons_recommended_title"
+msgstr "Extras Recomendados"
+
+#: views/addons/searchengines.thtml:136
+msgid "addons_searchengines_additional_resources"
+msgstr "Recursos adicionais"
+
+#. link text devmo
+#: views/addons/searchengines.thtml:141
+msgid "addons_searchengines_devmo_link"
+msgstr "Centro de desenvolvimento da Mozilla"
+
+#: views/pages/js_constants.js.thtml:67
+msgid "addons_searchengines_error_mozilla_browser_required"
+msgstr ""
+"Desculpe, precisa de um navegador baseado no Mozilla (como o Firefox) para "
+"instalar um plugin de pesquisa."
+
+#: views/addons/searchengines.thtml:49
+msgid "addons_searchengines_error_nojavascript"
+msgstr ""
+"O JavaScript é necessário para instalar plugins, mas parece que o tem "
+"desactivado. Por favor active o JavaScript antes de tentar instalar qualquer "
+"dos plugins procurados abaixo."
+
+#. %1 is "make your own" link
+#. %2 is MDC link
+#: views/addons/searchengines.thtml:139
+msgid "addons_searchengines_learn_howto"
+msgstr "Saiba como %1$s em %2$s."
+
+#. link path to search plugins instructions, relative to devmo
+#: views/addons/searchengines.thtml:140
+msgid "addons_searchengines_makeyourown_href"
+msgstr "/en/docs/Creating_OpenSearch_plugins_for_Firefox"
+
+#. link text for "make your own" (opensearch engine)
+#: views/addons/searchengines.thtml:140
+msgid "addons_searchengines_makeyourown_link"
+msgstr "como fazer o seu"
+
+#. %1 is the link to mycroft.mozdev.org
+#: views/addons/searchengines.thtml:138
+msgid "addons_searchengines_more"
+msgstr "Navegar muitos mais motores de pesquisa em %1$s"
+
+#. link text to mycroft.mozdev.org
+#: views/addons/searchengines.thtml:138
+msgid "addons_searchengines_mycroft_link"
+msgstr "mycroft.mozdev.org"
+
+#: controllers/addons_controller.php:1100
+#: controllers/addons_controller.php:1110
+msgid "addons_searchengines_pagetitle"
+msgstr "Motores de Pesquisa"
+
+#: views/addons/searchengines.thtml:143
+msgid "addons_searchengines_thanks"
+msgstr ""
+"Um obrigado especial ao Mycroft Projectpelo seu trabalho nos Motores de "
+"Pesquisa do Firefox."
+
+#: views/addons/display.thtml:154
+msgid "addons_share_button_text"
+msgstr "Partilhar isto"
+
+#: controllers/addons_controller.php:89
+msgid "addons_share_label_delicious"
+msgstr "Adicionar ao Delicious"
+
+#: controllers/addons_controller.php:77
+msgid "addons_share_label_digg"
+msgstr "Digg this!"
+
+#: controllers/addons_controller.php:83
+msgid "addons_share_label_facebook"
+msgstr "Postar no Facebook"
+
+#: controllers/addons_controller.php:101
+msgid "addons_share_label_friendfeed"
+msgstr "partilhar na fonte do amigo"
+
+#: controllers/addons_controller.php:95
+msgid "addons_share_label_myspace"
+msgstr "Postar no MySpace"
+
+#: controllers/components/amo.php:201 controllers/components/amo.php:229
+msgid "addons_status_disabled"
+msgstr "Desactivado"
+
+#: controllers/components/amo.php:191 controllers/components/amo.php:224
+msgid "addons_status_incomplete"
+msgstr "Versão incompleta"
+
+#: controllers/components/amo.php:197 controllers/components/amo.php:227
+msgid "addons_status_nominated"
+msgstr "No Sandbox; Nomeação pública"
+
+#: views/pages/js_constants.js.thtml:80 controllers/components/amo.php:195
+#: controllers/components/amo.php:226
+msgid "addons_status_pending"
+msgstr "No Sandbox; A aguardar comentário"
+
+#: views/pages/js_constants.js.thtml:78 controllers/components/amo.php:199
+#: controllers/components/amo.php:228
+msgid "addons_status_public"
+msgstr "Público"
+
+#: views/pages/js_constants.js.thtml:79 controllers/components/amo.php:193
+#: controllers/components/amo.php:225
+msgid "addons_status_sandbox"
+msgstr "No Sandbox"
+
+#: controllers/components/amo.php:203
+msgid "addons_status_unknown"
+msgstr "Desconhecido"
+
+#: views/elements/amo2009/teaser_collections.thtml:91
+#: views/elements/amo2009/homepage_addon.thtml:99
+#: views/elements/feature.thtml:94
+msgid "addons_title_tooltip"
+msgstr "Saiba mais sobre este extra"
+
+#: views/addons/category_landing.thtml:151
+msgid "addons_top_downloads"
+msgstr "Top de trasnferências"
+
+#: views/addons/category_landing.thtml:165
+msgid "addons_top_rated"
+msgstr "Top de avaliações"
+
+#: views/addons/versions.thtml:62
+msgid "addons_versions_careful"
+msgstr "Tenha Cuidado Com Versões Antigas"
+
+#: views/addons/versions.thtml:63
+msgid "addons_versions_careful_introduction"
+msgstr ""
+"Estas versões são apresentadas apenas como referência ou para testes. Deverá "
+"Sempre utilizar a última versão do extra."
+
+#: controllers/addons_controller.php:1549
+msgid "addons_versions_history"
+msgstr "Histórico da Versão com Registo de alterações"
+
+#. %1$s is the add-on name
+#: controllers/addons_controller.php:1535
+#, php-format
+msgid "addons_versions_pagetitle"
+msgstr "%1$s Histórico da Versão"
+
+#: controllers/groups_controller.php:71
+msgid "admin_group_add_pagetitle"
+msgstr "Adicionar Grupo"
+
+#: controllers/groups_controller.php:111
+msgid "admin_group_delete_pagetitle"
+msgstr "Apagar Grupo"
+
+#. %s is a number to identify the group
+#: controllers/groups_controller.php:117
+#, php-format
+msgid "admin_group_deleted"
+msgstr "O Grupo com o id %s foi eliminado"
+
+#: controllers/groups_controller.php:89
+msgid "admin_group_edit_pagetitle"
+msgstr "Editar Grupo"
+
+#: controllers/groups_controller.php:92 controllers/groups_controller.php:113
+msgid "admin_group_error_invalid_id"
+msgstr "ID inválido para o Grupo"
+
+#: controllers/groups_controller.php:65
+msgid "admin_group_pagetitle"
+msgstr "Admin do Grupo"
+
+#: controllers/groups_controller.php:77 controllers/groups_controller.php:99
+msgid "admin_group_saved"
+msgstr "O Grupo foi guardado"
+
+#: views/elements/amo2009/search.thtml:257 views/elements/search.thtml:239
+msgid "advanced_search_form"
+msgstr "Avançado"
+
+#: views/elements/amo2009/search.thtml:126 views/elements/search.thtml:125
+msgid "advanced_search_form_any_time"
+msgstr "Em todas as datas"
+
+#: views/elements/amo2009/search.thtml:97
+#: views/elements/amo2009/search.thtml:110 views/elements/search.thtml:96
+#: views/elements/search.thtml:109
+msgid "advanced_search_form_any_type"
+msgstr "Qualquer"
+
+#: views/elements/amo2009/search.thtml:275 views/elements/search.thtml:254
+msgid "advanced_search_form_any_version"
+msgstr "qualquer"
+
+#: views/elements/amo2009/search.thtml:217 views/elements/search.thtml:212
+msgid "advanced_search_form_application"
+msgstr "Aplicação"
+
+#: views/elements/amo2009/search.thtml:143 views/elements/search.thtml:142
+msgid "advanced_search_form_keyword_match"
+msgstr "Correspondência da palavra chave"
+
+#: views/elements/amo2009/search.thtml:251 views/elements/search.thtml:225
+msgid "advanced_search_form_lastupdate"
+msgstr "Última actualização"
+
+#: views/elements/amo2009/search.thtml:145 views/elements/search.thtml:144
+msgid "advanced_search_form_name"
+msgstr "Nome"
+
+#: views/elements/amo2009/search.thtml:144 views/elements/search.thtml:143
+msgid "advanced_search_form_newest"
+msgstr "Mais recentes"
+
+#: views/elements/amo2009/search.thtml:130 views/elements/search.thtml:129
+msgid "advanced_search_form_past_3_months"
+msgstr "Últimos 3 meses"
+
+#: views/elements/amo2009/search.thtml:131 views/elements/search.thtml:130
+msgid "advanced_search_form_past_6_months"
+msgstr "Últimos 6 meses"
+
+#: views/elements/amo2009/search.thtml:127 views/elements/search.thtml:126
+msgid "advanced_search_form_past_day"
+msgstr "Ontem"
+
+#: views/elements/amo2009/search.thtml:129 views/elements/search.thtml:128
+msgid "advanced_search_form_past_month"
+msgstr "Mês passado"
+
+#: views/elements/amo2009/search.thtml:128 views/elements/search.thtml:127
+msgid "advanced_search_form_past_week"
+msgstr "Semana passada"
+
+#: views/elements/amo2009/search.thtml:132 views/elements/search.thtml:131
+msgid "advanced_search_form_past_year"
+msgstr "Ano passado"
+
+#: views/elements/amo2009/search.thtml:239 views/elements/search.thtml:230
+msgid "advanced_search_form_perpage"
+msgstr "Por Página"
+
+#: views/elements/amo2009/search.thtml:243 views/elements/search.thtml:224
+msgid "advanced_search_form_platform"
+msgstr "Platforma"
+
+#: views/elements/amo2009/search.thtml:147 views/elements/search.thtml:146
+msgid "advanced_search_form_popularity"
+msgstr "Popularidade"
+
+#: views/elements/amo2009/search.thtml:146 views/elements/search.thtml:145
+msgid "advanced_search_form_rating"
+msgstr "Avaliação"
+
+#: views/elements/amo2009/search.thtml:247 views/elements/search.thtml:231
+msgid "advanced_search_form_sortby"
+msgstr "Ordenar por"
+
+#: views/elements/amo2009/search.thtml:227 views/elements/search.thtml:216
+msgid "advanced_search_form_to"
+msgstr "até"
+
+#: views/elements/amo2009/search.thtml:257 views/elements/search.thtml:237
+msgid "advanced_search_form_toggle_tooltip"
+msgstr "Mudar para modo de pesquisa avançada"
+
+#: views/elements/amo2009/search.thtml:235 views/elements/search.thtml:223
+msgid "advanced_search_form_type"
+msgstr "Tipo"
+
+#: views/elements/amo2009/search.thtml:222 views/elements/search.thtml:214
+msgid "advanced_search_form_version"
+msgstr "versão"
+
+#: views/elements/amo2009/pagination.thtml:42
+msgid "amo2009_pagination_next_page"
+msgstr "Seguinte"
+
+#: views/elements/amo2009/pagination.thtml:41
+msgid "amo2009_pagination_previous_page"
+msgstr "Anterior"
+
+#: views/pages/js_constants.js.thtml:96
+msgid "app_compat_ignore_check"
+msgstr "Ignorar a verificação da versão"
+
+#: views/pages/js_constants.js.thtml:72
+msgid "app_compat_older_firefox_only"
+msgstr "Este extra é para versões antigas do Firefox"
+
+#. %1$s and %2$s are URLs
+#: views/pages/js_constants.js.thtml:74
+msgid "app_compat_older_version_or_ignore_check"
+msgstr ""
+"Pode <a href=\"%1$s\">experimentar uma versão antiga</a> ou <a href=\"#\" "
+"onclick=\"%2$s\">ignorar esta verificação</a>"
+
+#. %1$s is a URL
+#: views/pages/js_constants.js.thtml:71
+msgid "app_compat_try_old_version"
+msgstr "Uma <a href=\"%1$s\">versão antiga</a> poderá funcionar"
+
+#. %1$s is a URL
+#. %2$s is a version number. Example: 3.1
+#: views/pages/js_constants.js.thtml:73
+msgid "app_compat_unreleased_version"
+msgstr ""
+"Esta versão necessita do ainida não lançado <a href=\"%1$s\">Firefox %2$s</a>"
+
+#: views/pages/js_constants.js.thtml:70
+msgid "app_compat_update_firefox"
+msgstr ""
+"<a href=\"http://getfirefox.com\">Actualize o Firefox</a> para utilizar este "
+"extra"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#. %3$s is a status, like Public.
+#: controllers/components/audit.php:79
+msgid "audit_addon_status"
+msgstr "%1$s alterou o estado de %2$s para %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:221
+msgid "audit_admin_default"
+msgstr "%1$s committed acção administrativa desconhecida %2$s para o ID %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:153
+msgid "audit_admin_feature_remove"
+msgstr "%1$s removeu a função %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is an application, like Firefox.
+#: controllers/components/audit.php:92
+msgid "audit_application_create"
+msgstr "%1$s criou a aplicação %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is an application, like Firefox.
+#: controllers/components/audit.php:95
+msgid "audit_application_edit"
+msgstr "%1$s editou a aplicação %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a version number, like 3.5.
+#. %3$s is an application, like Firefox.
+#: controllers/components/audit.php:105
+msgid "audit_appversion_create"
+msgstr "%1$s criou a versão %2$s para %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a version number, like 3.5.
+#. %3$s is an application, like Firefox.
+#: controllers/components/audit.php:108
+msgid "audit_appversion_delete"
+msgstr "%1$s eliminou a versão %2$s para %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a config field, like "awesomeness".
+#. %3$s is a config value, like "off".
+#. %4$s is a config value, like "on".
+#: controllers/components/audit.php:210
+msgid "audit_config"
+msgstr "%1$s alterou o config '%2$s' de'%3$s' para '%4$s'"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:258
+msgid "audit_editor_default"
+msgstr "%1$s committed acção de editor desconhecida %2$s para o ID %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#: controllers/components/audit.php:236
+msgid "audit_editor_feature_remove"
+msgstr "%1$s removeu o extra %2$s da lista"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#: controllers/components/audit.php:231
+msgid "audit_feature_add"
+msgstr "%1$s adicionou o extra %2$s à lista"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:149
+msgid "audit_feature_edit"
+msgstr "%1$s alterou uma funcionalidade para o idioma %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#: controllers/components/audit.php:241
+msgid "audit_feature_locale_change"
+msgstr "%1$s alterou idiomas para o extra %2$s na lista"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:83
+msgid "audit_file_recalchash"
+msgstr "%1$s recalculou a hash para o ficheiro %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>user name</a>
+#. %3$s is <a>group name</a>
+#: controllers/components/audit.php:182
+msgid "audit_group_addmember"
+msgstr "%1$s adicionou %2$s ao grupo %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:313
+msgid "audit_group_associated"
+msgstr "%1$s associou-se a %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:162
+msgid "audit_group_create"
+msgstr "%1s criou o grupo %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:170
+msgid "audit_group_delete"
+msgstr "%1$s eliminou o grupo %2$s (ID %3$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:165
+msgid "audit_group_edit"
+msgstr "%1$s editou o grupo %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>user name</a>
+#. %3$s is <a>group name</a>
+#: controllers/components/audit.php:188
+msgid "audit_group_removemember"
+msgstr "%1$s removeu %2$s do grupo %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:280
+msgid "audit_l10n_default"
+msgstr "%1$s committed acção desconhecida %2$s para %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:295
+msgid "audit_modify_locked_group"
+msgstr "%1$s tentou modificar o grupo fechado %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:299
+msgid "audit_modify_other_locale"
+msgstr "%1$s tentou modificartraduções em %2$s sem permissão"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a platform, like <a>Windows</a>
+#: controllers/components/audit.php:135
+msgid "audit_platform_create"
+msgstr "%1$s criou a plataforma %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a platform, like <a>Windows</a>
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:143
+msgid "audit_platform_delete"
+msgstr "%1$s eliminou a plataforma %2$s (ID %3$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a platform, like <a>Windows</a>
+#: controllers/components/audit.php:138
+msgid "audit_platform_edit"
+msgstr "%1$s editou a plataforma %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a part of the admin, like 'Site Config'
+#: controllers/components/audit.php:288
+msgid "audit_reauthentication_failure"
+msgstr "%1$s falhou a re-autenticação para aceder a %2$s."
+
+#. %1$s is <a>user name</a>
+#. %2$s is the name of a canned response, like 'Ready for the public'
+#: controllers/components/audit.php:198
+msgid "audit_response_create"
+msgstr "%1$s criou a resposta %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is the name of a canned response, like 'Ready for the public'
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:206
+msgid "audit_response_delete"
+msgstr "%1$s eliminou a resposta %2$s (ID %3$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is the name of a canned response, like 'Ready for the public'
+#: controllers/components/audit.php:201
+msgid "audit_response_edit"
+msgstr "%1$s editou a resposta %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:245
+msgid "audit_review_approve"
+msgstr "%1$s aprovou o comentário %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:250 controllers/components/audit.php:253
+msgid "audit_review_delete"
+msgstr "%1$s eliminou o comentário %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:303
+msgid "audit_security_default"
+msgstr "%1$s committed acção de segurança desconhecido %2$s para o ID %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a category name, like <a>Search Tools</a>
+#: controllers/components/audit.php:118
+msgid "audit_tag_create"
+msgstr "%1$s criou a etiqueta %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a category name, like <a>Search Tools</a>
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:126
+msgid "audit_tag_delete"
+msgstr "%1$s eliminou a categoria %2$s (ID %3$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a category name, like <a>Search Tools</a>
+#: controllers/components/audit.php:121
+msgid "audit_tag_edit"
+msgstr "%1$s editou a categoria %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:266
+msgid "audit_update_applications"
+msgstr "%1$s actualizou a aplicação de transferências para %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:277
+msgid "audit_update_blog"
+msgstr "%1$s actualizou as traduções do tópico do blog para %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:274
+msgid "audit_update_platforms"
+msgstr "%1$s actualizou as traduções da plataforma para %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:270
+msgid "audit_update_tags"
+msgstr "%1$s actualizou a categoria de traduções para %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>user name</a>
+#: controllers/components/audit.php:217
+msgid "audit_user_edit"
+msgstr "%1$s editou a informação do utilizador %2$s"
+
+#: controllers/addons_controller.php:1012
+msgid "browse_addons_name"
+msgstr "Extras por nome"
+
+#: controllers/addons_controller.php:1010
+msgid "browse_addons_newest"
+msgstr "Extras mais recentes"
+
+#: controllers/addons_controller.php:1008
+msgid "browse_addons_popular"
+msgstr "Extras populares"
+
+#: controllers/addons_controller.php:1011
+msgid "browse_addons_rated"
+msgstr "Extras por avaliação"
+
+#: controllers/addons_controller.php:1009
+msgid "browse_addons_updated"
+msgstr "Extras actualizados recentemente"
+
+#: views/elements/categories.thtml:73 views/elements/categories.thtml:82
+msgid "categories_current_title"
+msgstr "Categoria Actual"
+
+#: views/elements/categories.thtml:50
+#: views/elements/amo2009/categories.thtml:43
+#: views/elements/amo2009/categories.thtml:45
+msgid "categories_header"
+msgstr "Categorias"
+
+#: views/elements/categories.thtml:50
+#: views/elements/amo2009/categories.thtml:41
+msgid "categories_header_title"
+msgstr "Escolha uma categoria"
+
+#. %1$s is the category name
+#: views/addons/searchengines.thtml:129
+#, php-format
+msgid "category_extra_see_all"
+msgstr "Ver todos %1$s"
+
+#. %1$s is a number.
+#: models/collection.php:130
+msgid "collection_description_limit"
+msgstr "A descrição tem de ter menos de %1$s caracteres."
+
+#. %1$s is the name of the collection
+#: controllers/collections_controller.php:392
+#, fuzzy
+msgid "collection_detail_rss_title"
+msgstr "%s Collection"
+
+#: controllers/collections_controller.php:1065
+msgid "collection_error_deleting_addon"
+msgstr "Erro ao eliminar extra!"
+
+#: controllers/collections_controller.php:1051
+msgid "collection_error_saving_addon"
+msgstr "Erro ao guardar extra!"
+
+#: controllers/collections_controller.php:1080
+msgid "collection_error_saving_comment"
+msgstr "Erro ao guardar comentário!"
+
+#. %1$s is a number.
+#: models/collection.php:122
+msgid "collection_name_limit"
+msgstr "O nome tem de ter menos de %1$s caracteres."
+
+#: controllers/collections_controller.php:352
+#: controllers/collections_controller.php:487
+msgid "collection_not_found"
+msgstr "Coleção não encontrada!"
+
+#. %1$s is the text on the "create collection" button
+#: views/collections/add.thtml:91
+#, fuzzy
+msgid "collections_add_formfield_addons_description"
+msgstr ""
+"If you already know which add-ons you want to add to your collection, just "
+"start typing their names below. If you'd rather wait and do this later, just "
+"click %1$s now."
+
+#: views/collections/add.thtml:90
+msgid "collections_add_formfield_firstaddons"
+msgstr "Escolha os seus primeiros extras"
+
+#: views/collections/add.thtml:48
+msgid "collections_add_header"
+msgstr "Criar uma colecção"
+
+#: views/collections/add.thtml:97
+msgid "collections_add_header_selectedaddons"
+msgstr "Extras seleccionados"
+
+#: views/collections/add.thtml:50
+msgid "collections_add_intro"
+msgstr ""
+"É fácil criar a sua própria colecção de extras preenchendo os campos abaixo."
+
+#: views/collections/add.thtml:92 views/collections/add.thtml:103
+msgid "collections_add_submit"
+msgstr "Criar colecção"
+
+#: views/pages/collector_faq.thtml:50 views/pages/collector_firstrun.thtml:43
+#: views/pages/collector.thtml:47 views/pages/collector_features.thtml:55
+#: controllers/search_controller.php:302
+#: controllers/collections_controller.php:206
+#: controllers/collections_controller.php:405
+#: controllers/collections_controller.php:467
+#: controllers/collections_controller.php:539
+msgid "collections_breadcrumb"
+msgstr "Colecções"
+
+#: views/collections/detail.thtml:185
+msgid "collections_detail_a_learn"
+msgstr "Sabaer mais"
+
+#: views/elements/amo2009/collection_add_form.thtml:53
+#: views/elements/amo2009/collections_js_init.thtml:68
+#: views/pages/collector_firstrun.thtml:64
+msgid "collections_detail_button_add"
+msgstr "Adicionar aos favoritos"
+
+#: views/elements/amo2009/collection_add_form.thtml:50
+#: views/elements/amo2009/collections_js_init.thtml:71
+msgid "collections_detail_button_remove"
+msgstr "Remover do favoritos"
+
+#. %1$s is a URL.
+#. %2$s is a full <a href>.
+#: views/collections/detail.thtml:62
+#, fuzzy
+msgid "collections_detail_created_desc"
+msgstr ""
+"<p>You can view your new collection below. If you'd like to set a collection "
+"nickname, upload an icon, or change additional settings, please visit the <a "
+"href='%1$s'>Manage Collections</a> page.</p><p>Your collection can be "
+"accessed at this location: %2$s</p>"
+
+#: views/collections/detail.thtml:61
+#, fuzzy
+msgid "collections_detail_created_msg"
+msgstr "Your collection is now ready!"
+
+#: views/collections/detail.thtml:109
+msgid "collections_detail_header_about"
+msgstr "Sobre esta colecção"
+
+#. %1$s is a number.
+#: views/collections/detail.thtml:126
+msgid "collections_detail_header_count"
+msgid_plural "collections_detail_header_count"
+msgstr[0] "%1$s extra nesta colecção"
+msgstr[1] "%1$s extras nesta colecção"
+
+#: views/collections/detail.thtml:113
+msgid "collections_detail_info_created"
+msgstr "<strong>Criado por:</strong> %1$s"
+
+#: views/collections/detail.thtml:117
+msgid "collections_detail_info_updated"
+msgstr "<strong>Actualizado:</strong>"
+
+#: views/elements/amo2009/collections_js_init.thtml:62
+#, fuzzy
+msgid "collections_detail_js_adding"
+msgstr "Adding to Favorites&hellip;"
+
+#: views/elements/amo2009/collections_js_init.thtml:65
+#, fuzzy
+msgid "collections_detail_js_removing"
+msgstr "Removing Favorite&hellip;"
+
+#. %1$s is a URL
+#: views/collections/detail.thtml:90
+#, fuzzy
+msgid "collections_detail_login"
+msgstr "<a href=\"%1$s\">Log in</a> to add this collection to your favorites."
+
+#: views/collections/detail.thtml:104
+#, fuzzy
+msgid "collections_detail_manage"
+msgstr "Manage Collection"
+
+#: controllers/collections_controller.php:298
+msgid "collections_detail_sort_date"
+msgstr "Adicionado em"
+
+#: controllers/collections_controller.php:299
+msgid "collections_detail_sort_name"
+msgstr "Nome"
+
+#: controllers/collections_controller.php:300
+msgid "collections_detail_sort_popularity"
+msgstr "Popularidade"
+
+#. %1$s is a number.
+#: views/collections/detail.thtml:166
+msgid "collections_detail_weekly_downloads"
+msgid_plural "collections_detail_weekly_downloads"
+msgstr[0] "%1$s transferência esta semana"
+msgstr[1] "%1$s transferências esta semana"
+
+#: views/collections/edit.thtml:255
+msgid "collections_edit_addons_delete_noscript"
+msgstr "Os extras seleccionados serão eliminados ao guardar"
+
+#: views/collections/edit.thtml:247
+msgid "collections_edit_addons_description"
+msgstr ""
+"Para publicar novos extras nesta colecção, comece por escrever os nomes "
+"deles abaixo."
+
+#: views/collections/edit.thtml:248
+msgid "collections_edit_addons_description_noscript"
+msgstr ""
+"To publish new add-ons to this collection, enter a comma-separated list of "
+"Add-on IDs below.Para publicar novos extras"
+
+#: views/collections/edit.thtml:247 views/collections/edit.thtml:248
+msgid "collections_edit_addons_description_publish_detailspage"
+msgstr "Pode publicar um extra a partir da págin de listagem normal."
+
+#. %1$s is the date the add-on was added to the collection
+#. %1$s is the name of the user who added the add-on to the collection
+#: views/collections/edit.thtml:260
+msgid "collections_edit_addons_listitem_added"
+msgstr "Adicionado %1$s por %2$s"
+
+#: views/collections/edit.thtml:263
+msgid "collections_edit_addons_listitem_comment_add"
+msgstr "Adicionar comentário do editor"
+
+#: views/collections/edit.thtml:266
+msgid "collections_edit_addons_listitem_comment_delete"
+msgstr "Eliminar comentário do editor"
+
+#: views/collections/edit.thtml:265
+msgid "collections_edit_addons_listitem_comment_edit"
+msgstr "Editar comentário do editor"
+
+#: views/collections/edit.thtml:271
+#, fuzzy
+msgid "collections_edit_addons_listitem_comment_note"
+msgstr ""
+"Note: Comment will appear as though written by original publisher on the "
+"original publication date"
+
+#: views/collections/edit.thtml:270
+msgid "collections_edit_addons_listitem_comment_submit"
+msgstr "Guardar comentário"
+
+#: views/collections/edit.thtml:261
+msgid "collections_edit_addons_listitem_remove"
+msgstr "Remover"
+
+#: views/collections/edit.thtml:250
+msgid "collections_edit_addons_submit"
+msgstr "Adicionar à colecção"
+
+#: views/collections/edit.thtml:153
+msgid "collections_edit_check_nickname"
+msgstr "Verificar disponibilidade"
+
+#: views/collections/edit.thtml:299
+msgid "collections_edit_confirm_deletecollection"
+msgstr "Sim, quero eliminar esta colecção."
+
+#. %1$s is the label of the edit form's submit button
+#: views/collections/edit.thtml:300
+msgid "collections_edit_confirm_deletecollection_description"
+msgstr ""
+"Seleccione a caixa, e depois clique em \"%1$s\" para eliminar esta colecção."
+
+#. %1$s is the "delete" submit button text
+#. %2$s is the title of the "advanced" tab
+#: views/collections/edit.thtml:95
+#, fuzzy
+msgid "collections_edit_delete_upon_submit"
+msgstr ""
+"Upon clicking \"%1$s\" below, your collection will be deleted. If you do not "
+"want to delete your collection, uncheck the confirmation box in the \"%2$s\" "
+"tab and continue editing your collection. If you leave this page without "
+"saving, your collection will also not be deleted."
+
+#: views/collections/edit.thtml:94
+msgid "collections_edit_delete_warning"
+msgstr "A sua colecção está prestes a ser eliminada!"
+
+#: views/collections/add.thtml:76 views/collections/edit.thtml:144
+msgid "collections_edit_form_error_description"
+msgstr "Tem de fornecer uma descrição para a sua colecção."
+
+#: views/collections/edit.thtml:181
+msgid "collections_edit_form_error_icon"
+msgstr "Hove um erro ao carregar o seu ícone."
+
+#: views/collections/add.thtml:69 views/collections/edit.thtml:130
+msgid "collections_edit_form_error_name"
+msgstr "Tem de dar um nome à sua colecção."
+
+#: views/collections/edit.thtml:158
+msgid "collections_edit_form_error_nickname"
+msgstr "Se escolher uma alcunha , tem de ser única."
+
+#: views/collections/add.thtml:93 views/collections/edit.thtml:249
+msgid "collections_edit_formfield_addons"
+msgstr "Nome do extra:"
+
+#: views/collections/edit.thtml:281
+msgid "collections_edit_formfield_application"
+msgstr "Aplicação associada"
+
+#: views/collections/edit.thtml:282
+msgid "collections_edit_formfield_application_description"
+msgstr "Seleccione a aplicação que a sua colecção suporta."
+
+#: views/collections/edit.thtml:288
+#, fuzzy
+msgid "collections_edit_formfield_collectiontype"
+msgstr "Collection Type"
+
+#: views/collections/edit.thtml:295
+msgid "collections_edit_formfield_deletecollection"
+msgstr "Eliminar colecção"
+
+#: views/collections/edit.thtml:296
+msgid "collections_edit_formfield_deletecollection_description"
+msgstr "Eliminar a sua colecção será apagada definitivamente."
+
+#: views/collections/add.thtml:73 views/collections/edit.thtml:140
+msgid "collections_edit_formfield_description"
+msgstr "Descrição da colecção"
+
+#: views/collections/add.thtml:74 views/collections/edit.thtml:141
+msgid "collections_edit_formfield_description_description"
+msgstr "Descreva sucintamente a sua colecção e o tipo de extras que contém"
+
+#: views/collections/edit.thtml:162
+msgid "collections_edit_formfield_icon"
+msgstr "Ãcone"
+
+#: views/collections/edit.thtml:163
+msgid "collections_edit_formfield_icon_description"
+msgstr ""
+"Pode carregar um ícone JPG, GIF ou PNG que será redimensionado para 32x32 "
+"pixéis."
+
+#: views/collections/add.thtml:80 views/collections/edit.thtml:189
+msgid "collections_edit_formfield_listed"
+msgstr "Quem pode ver a sua colecção?"
+
+#: views/collections/add.thtml:81 views/collections/edit.thtml:190
+msgid "collections_edit_formfield_listed_description"
+msgstr ""
+"por pré-definição, as colecções aparecem na directoria de colecções pública "
+"e são descobertas por qualquer um. se quer restringir a sua colecção para "
+"poder apenas ser vista por pessoas a que deu uma ligação especial escolha a "
+"opção abaixo."
+
+#: views/collections/add.thtml:84 views/collections/edit.thtml:193
+msgid "collections_edit_formfield_listed_false"
+msgstr "Apenas pessoas que convido podem ver a minha colecção"
+
+#: views/collections/add.thtml:83 views/collections/edit.thtml:192
+msgid "collections_edit_formfield_listed_true"
+msgstr "Todos podem ver a minha colecção na directoria"
+
+#: views/collections/edit.thtml:223
+msgid "collections_edit_formfield_managers"
+msgstr "Quem pode gerir a minha colecção?"
+
+#: views/collections/edit.thtml:224
+msgid "collections_edit_formfield_managers_description"
+msgstr ""
+"Estes utilizadores podem publicar extras na sua colecção, gerir todos os "
+"extras e definições e dar permissão a outros."
+
+#: views/collections/add.thtml:66 views/collections/edit.thtml:126
+msgid "collections_edit_formfield_name"
+msgstr "O pacote do viajante"
+
+#: views/collections/add.thtml:67 views/collections/edit.thtml:127
+msgid "collections_edit_formfield_name_description"
+msgstr ""
+"Dê à sua colecção um nome que a descreva, tipo \"Extras de viagens favoritos "
+"do David\""
+
+#: views/collections/edit.thtml:148
+msgid "collections_edit_formfield_nickname"
+msgstr "Alcunha da colecção"
+
+#: views/collections/edit.thtml:149
+msgid "collections_edit_formfield_nickname_description"
+msgstr "Em opção, dê à sua colecção uma alcunha para acesso rápido:"
+
+#: views/collections/edit.thtml:201
+msgid "collections_edit_formfield_publishers"
+msgstr "Quem é que pode publicar extras na sua colecção?"
+
+#: views/collections/edit.thtml:202
+msgid "collections_edit_formfield_publishers_description"
+msgstr ""
+"Os utilizadores podem publicar extras á sua colecção e remover extras que "
+"eles publicam:"
+
+#: views/collections/edit.thtml:210 views/collections/edit.thtml:232
+msgid "collections_edit_formfield_users_add"
+msgstr ""
+"Escreva o endereço de correio electrónico de uma conta dos extras do Firefox:"
+
+#: views/collections/edit.thtml:216 views/collections/edit.thtml:238
+msgid "collections_edit_formfield_users_delete_noscript"
+msgstr "As contas seleccionadas serão removidas ao guardar"
+
+#: views/collections/edit.thtml:215 views/collections/edit.thtml:237
+msgid "collections_edit_formfield_users_new_noscript"
+msgstr ""
+"Escreva uma lista de correio electrónico separada por vírgulas de contas dos "
+"extras do Firefox"
+
+#: views/collections/edit.thtml:204 views/collections/edit.thtml:226
+msgid "collections_edit_formfield_users_onlyme"
+msgstr "Apenas eu"
+
+#: views/collections/edit.thtml:205 views/collections/edit.thtml:227
+msgid "collections_edit_formfield_users_otherusers"
+msgstr "Eu e estes utilizadores:"
+
+#: views/collections/edit.thtml:211 views/collections/edit.thtml:233
+msgid "collections_edit_formfield_users_submit"
+msgstr "Adicionar"
+
+#. %1$s is the name of the collection
+#: views/collections/edit.thtml:68
+msgid "collections_edit_header"
+msgstr "Gerir %1$s"
+
+#: views/collections/edit.thtml:246
+msgid "collections_edit_header_addons"
+msgstr "Gerir conteúdo da colecção"
+
+#: views/collections/edit.thtml:253 views/collections/edit.thtml:258
+msgid "collections_edit_header_addons_current"
+msgstr "Extras actuais:"
+
+#: views/collections/edit.thtml:279
+msgid "collections_edit_header_advanced"
+msgstr "Definições avançadas"
+
+#: views/collections/edit.thtml:186
+msgid "collections_edit_header_permissions"
+msgstr "Gerir permissões da colecção"
+
+#: views/collections/edit.thtml:170
+msgid "collections_edit_icon_cancel"
+msgstr "Cancelar"
+
+#: views/collections/edit.thtml:174 views/collections/edit.thtml:179
+msgid "collections_edit_icon_delete"
+msgstr "Eliminar ícone"
+
+#: views/collections/edit.thtml:178
+msgid "collections_edit_icon_replace"
+msgstr "Substituir ícone"
+
+#. %1$s is the label of the edit form's submit button
+#: views/collections/edit.thtml:169
+msgid "collections_edit_icon_toberemoved"
+msgstr "O ícone será removido quando \"%1$s\" for clicado abaixo"
+
+#: views/collections/edit.thtml:155
+msgid "collections_edit_nickname_available"
+msgstr "Alcunha disponível"
+
+#: controllers/collections_controller.php:943
+msgid "collections_edit_nickname_error"
+msgstr ""
+"A sua alcunha tinha caracteres inválidos e foi corrigida. Tente novamente."
+
+#: views/collections/edit.thtml:156
+msgid "collections_edit_nickname_taken"
+msgstr "Alcunha já utilizada"
+
+#. This string is followed by a URL pointing to the collection's view page
+#: views/collections/edit.thtml:75
+msgid "collections_edit_saved_nextstep"
+msgstr "A sua colecção foi acedida neste local:"
+
+#: views/collections/edit.thtml:74
+msgid "collections_edit_saved_success"
+msgstr "A sua colecção foi guardada com sucesso!"
+
+#: views/collections/edit.thtml:169 views/collections/edit.thtml:300
+#: views/collections/edit.thtml:308 views/pages/js_constants.js.thtml:99
+msgid "collections_edit_submit"
+msgstr "Actualizar colecção"
+
+#: views/collections/edit.thtml:96 views/collections/edit.thtml:297
+#: views/pages/js_constants.js.thtml:100
+msgid "collections_edit_submit_deletecollection"
+msgstr "Eliminar colecção"
+
+#: views/collections/edit.thtml:111
+msgid "collections_edit_tabheader_addons"
+msgstr "Extras"
+
+#: views/collections/edit.thtml:97 views/collections/edit.thtml:113
+msgid "collections_edit_tabheader_advanced"
+msgstr "Avançado"
+
+#: views/collections/edit.thtml:108
+msgid "collections_edit_tabheader_details"
+msgstr "Nome &amp; Detalhes"
+
+#: views/collections/edit.thtml:109
+msgid "collections_edit_tabheader_permissions"
+msgstr "Permissões"
+
+#: models/collection_promo.php:53
+msgid "collections_family_tagline"
+msgstr "Os extras podem vigiar os seus filhos e o seu calendário."
+
+#: models/collection_promo.php:53
+msgid "collections_family_title"
+msgstr "Organizador Familiar"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:70
+msgid "collections_index_a_check_out"
+msgstr "Check out do coleccionador de extras"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:52
+msgid "collections_index_a_create"
+msgstr "Criar uma colecção"
+
+#: views/collections/detail.thtml:139 views/collections/listing.thtml:85
+#: views/search/collections.thtml:84
+msgid "collections_index_button_go"
+msgstr "Ir"
+
+#. %1$s is a URL.
+#: controllers/collections_controller.php:182
+#, fuzzy
+msgid "collections_index_filler_favorites"
+msgstr ""
+"<p><strong>You don't have any favorite collections yet.</strong></p> "
+"<p>Collections you mark as favorites can be quickly accessed from this page, "
+"and will appear in the <a href='%1$s'>Add-on Collector</a> if you've "
+"installed it.</p>"
+
+#. %1$s is a URL.
+#: controllers/collections_controller.php:167
+#, fuzzy
+msgid "collections_index_filler_mine"
+msgstr ""
+"<p>You haven't created any collections yet. Collections are easy to create "
+"and fill with your favorite add-ons. <a href='%1$s'>Try it out</a>!</p>"
+
+#: views/collections/listing.thtml:51
+msgid "collections_index_header_collections"
+msgstr "Colecções"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:60
+msgid "collections_index_header_collector"
+msgstr "Coleccionador de extras"
+
+#. %1$s is a comma-separated list of author names
+#: views/elements/amo2009/collection_listing_item.thtml:84
+#: views/collections/detail.thtml:151
+msgid "collections_index_header_created"
+msgstr "criado por %1$s"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:47
+msgid "collections_index_header_what"
+msgstr "O que são colecções?"
+
+#: views/collections/detail.thtml:132 views/collections/listing.thtml:78
+#: views/search/collections.thtml:66
+msgid "collections_index_label_sortby"
+msgstr "Ordenar por"
+
+#: controllers/collections_controller.php:130
+msgid "collections_index_li_editors"
+msgstr "Editor's Picks"
+
+#: views/collections/subscribe.thtml:64
+#: controllers/collections_controller.php:140
+msgid "collections_index_li_favorites"
+msgstr "Os meus favoritos"
+
+#: controllers/collections_controller.php:138
+msgid "collections_index_li_mine"
+msgstr "As minhas colecções"
+
+#: controllers/collections_controller.php:132
+msgid "collections_index_li_popular"
+msgstr "Popular"
+
+#: views/search/collections.thtml:74 controllers/collections_controller.php:81
+msgid "collections_index_option_all"
+msgstr "Mais populares de sempre"
+
+#: views/search/collections.thtml:72 controllers/collections_controller.php:78
+msgid "collections_index_option_month"
+msgstr "Mais populares este mês"
+
+#: views/search/collections.thtml:76 controllers/collections_controller.php:84
+#, fuzzy
+msgid "collections_index_option_newest"
+msgstr "Newest"
+
+#: views/search/collections.thtml:70 controllers/collections_controller.php:75
+msgid "collections_index_option_week"
+msgstr "Mais populares esta semana"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:67
+msgid "collections_index_p_collector"
+msgstr ""
+"Existe uma nova maneira de encontrar e gerir os extras favoritoss. Comente, "
+"partilhe e sincronize colecções tudo isto a partir do seu navegador."
+
+#: views/elements/amo2009/collector_info_secondary.thtml:48
+msgid "collections_index_p_what_are"
+msgstr ""
+"As colecções são grupos de extras relacionados que são agregados para uma "
+"partilha fácil."
+
+#. %s is a date in the _('date') format
+#: views/elements/collections_interactive_addon.thtml:85
+#, php-format
+msgid "collections_interactive_addon_added"
+msgstr "Adicionado %s"
+
+#: models/collection_promo.php:55
+msgid "collections_reference_tagline"
+msgstr "Os extras podem fazer uma melhor pesquisa quando ligados."
+
+#: models/collection_promo.php:55
+msgid "collections_reference_title"
+msgstr "Balcão de referência"
+
+#: models/collection_promo.php:52
+msgid "collections_social_tagline"
+msgstr "Os extras podem ferir a sua rede social."
+
+#: models/collection_promo.php:52
+msgid "collections_social_title"
+msgstr "Circuito social"
+
+#: views/collections/subscribe.thtml:91
+#, fuzzy
+msgid "collections_subscribe_button_close"
+msgstr "Close"
+
+#: views/collections/subscribe.thtml:70
+#, fuzzy
+msgid "collections_subscribe_error"
+msgstr ""
+"An error occurred trying to add a favorite collection. Is this collection "
+"already a favorite?"
+
+#: views/collections/subscribe.thtml:96
+#, fuzzy
+msgid "collections_subscribe_label_bothersome"
+msgstr "Don't show me this message again."
+
+#. %1$s is the collection name
+#: views/collections/subscribe.thtml:60
+#, fuzzy
+msgid "collections_subscribe_success"
+msgstr "%1$s has been added to your favorite collections."
+
+#. %1$s is the link to the "My Favorites" tab on the main collections page
+#. %2$s is the localized title of the "My Favorites" tab
+#. %3$s is the link URL to the collector add-on
+#: views/collections/subscribe.thtml:62
+#, fuzzy
+msgid "collections_subscribe_success_desc"
+msgstr ""
+"You can now quickly find this collection from the <a href=\"%1$s\">%2$s</a> "
+"tab in the directory. For an even easier way to keep track of your favorite "
+"collections, try out our <a href=\"%3$s\">Add-on Collector</a> extension for "
+"Firefox."
+
+#: views/collections/listing.thtml:55
+msgid "collections_success_delete"
+msgstr "A colecção foi eliminada."
+
+#: models/collection_promo.php:54
+msgid "collections_travel_tagline"
+msgstr "Os extras podem torná-lo num agente de viagens."
+
+#: models/collection_promo.php:54
+msgid "collections_travel_title"
+msgstr "O pacote do viajante"
+
+#. A collection of add-ons that is automatically built for a user. They are "automatically published" to this collection.
+#: controllers/collections_controller.php:581
+#, fuzzy
+msgid "collections_type_autopublisher"
+msgstr "Auto-publisher"
+
+#. A collection that has been chosen by an Editor as notable or exceptional
+#: controllers/collections_controller.php:582
+#, fuzzy
+msgid "collections_type_editorspick"
+msgstr "Editor's Pick"
+
+#: controllers/collections_controller.php:580
+#, fuzzy
+msgid "collections_type_normal"
+msgstr "Normal"
+
+#: views/collections/subscribe.thtml:84
+#, fuzzy
+msgid "collections_unsubscribe_error"
+msgstr ""
+"An error occurred trying to remove a favorite collection. Was this "
+"collection not a favorite?"
+
+#. %1$s is the collection name
+#: views/collections/subscribe.thtml:78
+#, fuzzy
+msgid "collections_unsubscribe_success"
+msgstr "%1$s has been removed from your favorite collections."
+
+#: models/collection_promo.php:56
+msgid "collections_webdev_tagline"
+msgstr "Os extras tornam mais fácil a consrução do sítio web perfeito."
+
+#: models/collection_promo.php:56
+msgid "collections_webdev_title"
+msgstr "Caixa de ferramenta do desenvolvedor web"
+
+#: views/elements/amo2009/collections_sidebar_whatare.thtml:40
+msgid "collections_whatare_header"
+msgstr "O que são colecções?"
+
+#: views/elements/amo2009/collections_sidebar_whatare.thtml:45
+msgid "collections_whatare_learnmore"
+msgstr "Ler a FAQ"
+
+#: views/elements/amo2009/collections_sidebar_whatare.thtml:44
+msgid "collections_whatare_text"
+msgstr ""
+"Existe uma nova maneira de encontrar e gerir os extras favoritoss. Comente, "
+"partilhe e sincronize colecções tudo isto a partir do seu navegador."
+
+#: views/pages/collector_faq.thtml:61 views/pages/collector_features.thtml:67
+msgid "collector_features_a_home"
+msgstr "Página inicial do coleccionador de extras"
+
+#: views/elements/amo2009/collector_sidebar_download.thtml:46
+msgid "collector_features_heading_download"
+msgstr "Transferir o coleccionador de extras:"
+
+#: views/elements/amo2009/collector_sidebar_download.thtml:43
+#: views/pages/collector_firstrun.thtml:116 views/pages/collector.thtml:69
+msgid "collector_features_img_logo"
+msgstr "Logo do coleccionador de extras"
+
+#: views/compatibility/dashboard.thtml:49
+#: controllers/compatibility_controller.php:72
+msgid "compatibility_dashboard_center_header"
+msgstr "Centro de compatibilidade dos extras"
+
+#. %1$s is the name of an application and a version. Example: Firefox 3.0
+#. %2$s is the name of an application. Example: Firefox
+#: views/compatibility/dashboard.thtml:50
+msgid "compatibility_dashboard_intro"
+msgstr ""
+"Esteja preparado para o lançamento do %1$s com as ferramentas e informação "
+"disponível para a comunidade dos extras do %2$s abaixo."
+
+#: views/compatibility/dashboard.thtml:103
+msgid "compatibility_dashboard_loading"
+msgstr "A carregar dados..."
+
+#: views/compatibility/dashboard.thtml:45
+msgid "compatibility_dashboard_main_link"
+msgstr "Voltar ao início"
+
+#: views/compatibility/dashboard.thtml:100 views/compatibility/report.thtml:43
+msgid "compatibility_dashboard_report"
+msgstr "Relatório de compatibilidade do extra"
+
+#: views/compatibility/dashboard.thtml:53
+#: views/compatibility/dashboard.thtml:110
+#: views/compatibility/developers.thtml:43
+msgid "compatibility_developer_info"
+msgstr "Informação para desenvolvedores de extras"
+
+#: views/compatibility/developers.thtml:66
+msgid "compatibility_developers_adjust_maxversion"
+msgstr "Ajustar a maxVersion sem carregar"
+
+#: views/compatibility/dashboard.thtml:124
+msgid "compatibility_developers_check_status"
+msgstr "Verificar estado dos meus extras"
+
+#. %1$s is a URL
+#. %2$s is an application and version. Example: Firefox 3.0
+#: views/compatibility/dashboard.thtml:126
+msgid "compatibility_developers_login_first"
+msgstr ""
+"Se tiver extras hospedados nos extras da Mozilla, <a href=\"%1$s\">inície "
+"sessão</a> para analisar o estado dos seus extras para %2$s."
+
+#: views/compatibility/dashboard.thtml:114
+msgid "compatibility_developers_mdclogo_alt"
+msgstr "Logo do Centro de Desenvolvimento Mozilla"
+
+#: views/compatibility/developers.thtml:73
+msgid "compatibility_developers_no_addons"
+msgstr "Não tem extras hospedados nos extras da Mozilla."
+
+#: views/compatibility/dashboard.thtml:133
+#: views/compatibility/developers.thtml:55
+msgid "compatibility_developers_results"
+msgstr "Resultados da verificação do estado dos extras"
+
+#: views/compatibility/dashboard.thtml:137
+msgid "compatibility_developers_retrieving"
+msgstr "A obter dados sobre o estado dos extras hospedados..."
+
+#. %1$s is a number
+#. %2$s is an application name
+#. %3$s is a number.
+#. Full example: 50 Firefox users (10% of total)
+#: views/compatibility/developers.thtml:65
+msgid "compatibility_developers_user_count"
+msgstr "%1$s %2$s utilizadores (%3$s&#37; no total)"
+
+#: views/compatibility/report.thtml:45
+msgid "compatibility_report_detail_intro"
+msgstr ""
+"Os extras abaixo têm 95% de uso conhecido pela Mozilla e são ordenados pelo "
+"seu tamanho de utilização."
+
+#: views/compatibility/dashboard.thtml:94
+msgid "compatibility_report_detailed_link"
+msgstr "Ver relatório detalhado"
+
+#. %1$s and %2$s are numbers
+#. %3$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:65
+msgid "compatibility_report_intro"
+msgstr ""
+" %1$s extras que tenham 95&#37; de uso do extra conhecido pela Mozilla, <b>%2"
+"$s&#37;</b> são considerados compatíveis com as últimas versões do %3$s."
+
+#: views/compatibility/dashboard.thtml:81
+msgid "compatibility_report_legend_alpha"
+msgstr "Versões Alpha "
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:81
+msgid "compatibility_report_legend_alpha_description"
+msgstr "Extras compatíveis com uma versão alpha do %1$s"
+
+#: views/compatibility/dashboard.thtml:85
+msgid "compatibility_report_legend_beta"
+msgstr "Versões Beta"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:85
+msgid "compatibility_report_legend_beta_description"
+msgstr "Extras compatíveis com uma versão beta ou release candidate do %1$s"
+
+#: views/compatibility/dashboard.thtml:89
+msgid "compatibility_report_legend_latest"
+msgstr "Última versão"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:89
+msgid "compatibility_report_legend_latest_description"
+msgstr "Extras actualizados com a última versão do %1$s"
+
+#: views/compatibility/dashboard.thtml:77
+msgid "compatibility_report_legend_other"
+msgstr "Outras versões"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:77
+msgid "compatibility_report_legend_other_description"
+msgstr "Extras não compatíveis com nenhuma versão do %1$s"
+
+#: views/compatibility/dashboard.thtml:62
+msgid "compatibility_report_title"
+msgstr "Relatório de compatibilidade do extra"
+
+#: views/compatibility/dashboard.thtml:54
+#: views/compatibility/dashboard.thtml:144 views/compatibility/users.thtml:42
+msgid "compatibility_user_info"
+msgstr "Informação para os utilizadores dos extras"
+
+#: views/compatibility/dashboard.thtml:52
+msgid "compatibility_view_report"
+msgstr "Ver relatório de compatibilidade"
+
+#. %s is a URL
+#: views/pages/credits.thtml:142
+#, php-format
+msgid "credits_contributing"
+msgstr "Para informação sobre como contribuir, veja a nossa %s."
+
+#: views/pages/credits.thtml:142
+msgid "credits_contributing_wikipage"
+msgstr "página wiki"
+
+#: views/pages/credits.thtml:99
+msgid "credits_intro"
+msgstr ""
+"A Mozilla gostaria de agradecer às seguintes pessoas pela sua contribuição "
+"no projecto addons.mozilla.org ao longo dos anos:"
+
+#: views/pages/credits.thtml:103
+msgid "credits_section_developers"
+msgstr "Desenvolvedores"
+
+#: views/pages/credits.thtml:115
+msgid "credits_section_editors"
+msgstr "Editores"
+
+#: views/pages/credits.thtml:109
+msgid "credits_section_localizers"
+msgstr "Tradutores"
+
+#: views/pages/credits.thtml:121
+msgid "credits_section_other_contributors"
+msgstr "Outros Colaboradores"
+
+#: views/pages/credits.thtml:127
+msgid "credits_section_past_developers"
+msgstr "Antigos Desenvolvedores"
+
+#: views/pages/credits.thtml:133
+msgid "credits_section_software"
+msgstr "Software e Imagens"
+
+#: views/pages/credits.thtml:136
+msgid "credits_software_famfamfam"
+msgstr ""
+"Alguns ícones utilizados são da <a href=\"http://www.famfamfam.com/lab/icons/"
+"silk/\">famfamfam Silk Icon Set</a>, licenciados sobre <a href=\"http://"
+"creativecommons.org/licenses/by/2.5/\">Creative Commons Attribution 2.5 "
+"License</a>."
+
+#: views/pages/credits.thtml:137
+msgid "credits_software_timeplot"
+msgstr ""
+"Algumas páginas usam elementos do <a href=\"http://www.simile-widgets.org/"
+"timeplot/\">Timeplot</a>, liceciado sobre a <a href=\"http://simile.mit.edu/"
+"license.html\">Licença BSD</a>."
+
+#. date format string as used in PHP's strftime():
+#. http://php.net/strftime
+#: views/elements/collections_interactive_addon.thtml:85
+#: views/elements/amo2009/addon_version_detail.thtml:53
+#: views/elements/amo2009/homepage_addon.thtml:115
+#: views/elements/addon_version_detail.thtml:54
+#: views/elements/addon_listitem.thtml:124 views/elements/feature.thtml:106
+#: views/collections/detail.thtml:118 views/collections/edit.thtml:325
+#: views/users/info.thtml:76 views/editors/reviews_queue.thtml:57
+#: views/editors/reviews_queue.thtml:68 views/developers/dashboard.thtml:65
+#: views/developers/versions_edit.thtml:208 views/developers/versions.thtml:67
+#: views/search/rss/index.thtml:5 views/addons/rss/versions.thtml:42
+#: views/addons/display.thtml:104 views/addons/display.thtml:356
+#: views/addons/browse_thumbs.thtml:75 views/reviews/add.thtml:63
+#: views/reviews/display.thtml:74 views/reviews/display.thtml:160
+#: views/reviews/delete.thtml:54 controllers/statistics_controller.php:244
+#: controllers/collections_controller.php:1047
+msgid "date"
+msgstr "%B %e, %Y"
+
+#. date and time format string (strftime)
+#. http://php.net/strftime
+#: views/elements/addon_version_detail.thtml:53
+#: views/developers/discuss.thtml:52 views/developers/discuss.thtml:62
+#: views/admin/addons_status.thtml:57
+msgid "datetime"
+msgstr "%B %e, %Y, %I:%M %p"
+
+#: views/elements/developers/actionbar.thtml:47
+msgid "devcp_actionbar_link_details"
+msgstr "Info Detalhada"
+
+#: views/elements/developers/actionbar.thtml:42
+#: views/elements/developers/actionbar.thtml:50
+#: views/developers/dashboard.thtml:64
+msgid "devcp_actionbar_link_edit"
+msgstr "Editar Extra"
+
+#: views/elements/developers/actionbar.thtml:51
+msgid "devcp_actionbar_link_newversion"
+msgstr "Carregar Nova Versão"
+
+#: views/elements/developers/actionbar.thtml:44
+#: views/elements/developers/actionbar.thtml:49
+#: views/developers/dashboard.thtml:73
+msgid "devcp_actionbar_link_stats"
+msgstr "Painel de Estatísticas"
+
+#. %1$s is a filename, e.g. "foo.txt"
+#. %2$s is the extension, e.g. ".txt"
+#. %3$s is a list of valid extensions, like ".png, .jpg, .gif"
+#: controllers/developers_controller.php:1361
+msgid "devcp_add_previews_extension_error"
+msgstr ""
+"O ficheiro %1$s tem uma extensão inválida (%2$s). Extensões permitidas: %3$s"
+
+#. %s is the filename.
+#: controllers/developers_controller.php:1394
+msgid "devcp_add_previews_save_error"
+msgstr "O ficheiro %s não pode ser guardado na base de dados. Tente novamente."
+
+#. %1$s is the preview ID number, %2$s is the filename.
+#: controllers/developers_controller.php:1389
+msgid "devcp_add_previews_success_replace"
+msgstr ""
+"A pré-visualização %1$s foi substituída pelo ficheiro %2$s com sucesso."
+
+#. %s is the filename.
+#: controllers/developers_controller.php:1391
+msgid "devcp_add_previews_success_upload"
+msgstr ""
+"O ficheiro %s foi carregado com sucesso. Abaixo pode adicionar uma captura."
+
+#: controllers/components/developers.php:1163
+msgid "devcp_additem_addontype_autodetect"
+msgstr "(auto-detectar)"
+
+#: views/elements/developers/additem.thtml:76
+msgid "devcp_additem_linktitle_opensin_newwindow"
+msgstr "Abre numa nova janela"
+
+#: views/elements/developers/additem.thtml:41
+msgid "devcp_additem_sidebar_title"
+msgstr "Submeter Extra"
+
+#: views/elements/developers/additem.thtml:53
+msgid "devcp_additem_step0_newlink"
+msgstr "Acordo do Desenvolvedor"
+
+#: views/elements/developers/additem.thtml:46
+msgid "devcp_additem_step1_link"
+msgstr "Passo 1: Carregar"
+
+#: views/elements/developers/additem.thtml:47
+msgid "devcp_additem_step2_link"
+msgstr "Passo 2: Detalhes do Extra"
+
+#: views/elements/developers/additem.thtml:48
+msgid "devcp_additem_step3_link"
+msgstr "Passo 3: Detalhes da Versão"
+
+#: views/elements/developers/additem.thtml:49
+msgid "devcp_additem_step4_link"
+msgstr "Passo 4: Tradução"
+
+#: views/elements/developers/additem.thtml:50
+msgid "devcp_additem_step5_link"
+msgstr "Passo 5: Sucesso"
+
+#: views/elements/developers/additem.thtml:76
+msgid "devcp_additem_submissionhelp_link"
+msgstr "Ajuda da Submissão"
+
+#: controllers/previews_controller.php:168
+#: controllers/previews_controller.php:277
+msgid "devcp_addon_field_preview_caption_displaytitle"
+msgstr "Captura da Pré-visualização"
+
+#: views/developers/addon_status.thtml:177
+msgid "devcp_addon_status_action_activate"
+msgstr "Tornar activo"
+
+#: views/developers/addon_status.thtml:178
+msgid "devcp_addon_status_action_activate_description"
+msgstr ""
+"Tornar o seu extra activo para ser mostrado nas listas públicas e activar o "
+"serviço de verificação de actualizações."
+
+#: views/developers/addon_status.thtml:135
+msgid "devcp_addon_status_action_complete"
+msgstr "Completar extra"
+
+#: views/developers/addon_status.thtml:136
+msgid "devcp_addon_status_action_complete_description"
+msgstr "Completar o seu extra e movê-lo para o Sandbox"
+
+#: views/developers/addon_status.thtml:181
+msgid "devcp_addon_status_action_deactivate"
+msgstr "Tornar inactivo"
+
+#: views/developers/addon_status.thtml:182
+msgid "devcp_addon_status_action_deactivate_description"
+msgstr ""
+"Tornar o seu extra inactivo para ser ocultado das listas públicas e "
+"desactivar o serviço de verificação de actualizações."
+
+#: views/developers/addon_status.thtml:143
+msgid "devcp_addon_status_action_move"
+msgstr "Mover para oSandbox"
+
+#: views/developers/addon_status.thtml:144
+msgid "devcp_addon_status_action_move_description"
+msgstr "Mover o seu extra de novo para o Sandbox. Isto é reversível."
+
+#: views/developers/addon_status.thtml:139
+msgid "devcp_addon_status_action_nominate"
+msgstr "Nomear par público"
+
+#: views/developers/addon_status.thtml:140
+msgid "devcp_addon_status_action_nominate_description"
+msgstr "Nomear o seu extra para se tornar público"
+
+#: views/developers/addon_status.thtml:147
+msgid "devcp_addon_status_action_public"
+msgstr "Tornar público"
+
+#: views/developers/addon_status.thtml:148
+msgid "devcp_addon_status_action_public_description"
+msgstr "Tornar extra público de novo."
+
+#: views/developers/addon_status.thtml:169
+msgid "devcp_addon_status_active"
+msgstr ""
+"O seu extra está <span class=\"inactive-0\">Activo</span>. Isto significa "
+"que o seu extra está a ser apresentado em todas as listagens disponíveis "
+"para o estado acima."
+
+#: views/developers/addon_status.thtml:111
+msgid "devcp_addon_status_completion_disabled"
+msgstr ""
+"Preencha os critérios acima antes de terminar o seu extra e movê-lo para o "
+"<span class=\"status-1\">Sandbox</span>."
+
+#: views/developers/addon_status.thtml:108
+msgid "devcp_addon_status_completion_enabled"
+msgstr ""
+"Agora já pode terminar o seu extra e mov~e-lo para o <span class=\"status-1"
+"\">Sandbox</span>clicando no botão abaixo."
+
+#: views/developers/addon_status.thtml:102
+msgid "devcp_addon_status_criteria_category"
+msgstr "Pelo menos uma categoria seleccionada"
+
+#: views/developers/addon_status.thtml:101
+msgid "devcp_addon_status_criteria_description"
+msgstr "Necessária descrição do extra "
+
+#: views/developers/addon_status.thtml:99
+msgid "devcp_addon_status_criteria_name"
+msgstr "Necessário nome do extra"
+
+#: views/developers/addon_status.thtml:120
+msgid "devcp_addon_status_criteria_prerelease"
+msgstr "O extra não está marcado como pré-lançamento."
+
+#: views/developers/addon_status.thtml:119
+msgid "devcp_addon_status_criteria_preview"
+msgstr ""
+"É necessário pelo menos uma imagem de pré-visualização para extensões e "
+"temas."
+
+#: views/developers/addon_status.thtml:100
+msgid "devcp_addon_status_criteria_summary"
+msgstr "Necessário sumário do extra"
+
+#. %s is the status in a span, e.g. "<span>_('Public')</span>".
+#: views/developers/addon_status.thtml:58
+msgid "devcp_addon_status_header"
+msgstr "Estado do extra: %s"
+
+#: views/developers/addon_status.thtml:152
+#: views/developers/addon_status.thtml:173
+msgid "devcp_addon_status_header_actions"
+msgstr "Acções disponíveis"
+
+#: views/developers/addon_status.thtml:168
+msgid "devcp_addon_status_header_active"
+msgstr "Estado actual: <span class=\"inactive-0\">Activo</span>"
+
+#: views/developers/addon_status.thtml:97
+msgid "devcp_addon_status_header_criteria"
+msgstr "Critério de finalização do extra"
+
+#: views/developers/addon_status.thtml:164
+msgid "devcp_addon_status_header_inactive"
+msgstr "Estado actual: <span class=\"inactive-1\">Inactivo</span>"
+
+#: views/developers/addon_status.thtml:117
+msgid "devcp_addon_status_header_nomination"
+msgstr "Critério de nomeação pública"
+
+#: views/developers/addon_status.thtml:190
+msgid "devcp_addon_status_header_trusted"
+msgstr "Estado de confiança: <span class=\"status-4\">De confiança</span>"
+
+#: views/developers/addon_status.thtml:165
+msgid "devcp_addon_status_inactive"
+msgstr ""
+"O seu extra está <span class=\"inactive-1\">Inactivo</span>. Isto significa "
+"que o seu extra não está a ser mostrado em nenhuma listagem, apesar do "
+"estado indicado. As actualizações <b>não</b> estão a ser efectuadas através "
+"do serviço de verificação de actualizações."
+
+#: views/developers/addon_status.thtml:128
+msgid "devcp_addon_status_nominate_disabled"
+msgstr ""
+"Preencha os critérios acima para nomear o seu extra e torná-lo <span class="
+"\"status-4\">Público</span>."
+
+#: views/developers/addon_status.thtml:125
+msgid "devcp_addon_status_nominate_enabled"
+msgstr ""
+"Agora pode nomear o seu extra para <span class=\"status-4\">Público</span> "
+"clicando no botão abaixo."
+
+#: views/developers/addon_status.thtml:64
+msgid "devcp_addon_status_public"
+msgstr "Público"
+
+#: views/developers/addon_status.thtml:63
+msgid "devcp_addon_status_sandbox"
+msgstr "Sandbox"
+
+#. %s is an email address.
+#: views/developers/addon_status.thtml:89
+msgid "devcp_addon_status_switch_disabled"
+msgstr ""
+"O seu extra foi <span class=\"status-5\">Disactivado</span> por um "
+"admministrador e não pode ser usado. Se tiver questões envie uma mensagem de "
+"correio paral %s."
+
+#: views/developers/addon_status.thtml:67
+msgid "devcp_addon_status_switch_incomplete"
+msgstr ""
+"O seu extra está <span class=\"status-0\">Incompleto</span>. Isto significa "
+"que o seu extra não está a ser mostrado em nenhum local do sítio ou através "
+"do serviço de actulizações. Pode vir para esta página para terminar o seu "
+"extra após ele corrsponder aos critérios mostrados abaixo para finalização e "
+"transferência para o <span class=\"status-1\">Sandbox</span>."
+
+#. %s is a number, perhaps 42.
+#: views/developers/addon_status.thtml:77
+msgid "devcp_addon_status_switch_nominated"
+msgstr ""
+"O seu extra está nomeado para se tornar <span class=\"status-4\">Público</"
+"span> e aguarda uma revisão de um editor. Existem actualmente %s outros "
+"extras em espera."
+
+#. %s is an email address.
+#: views/developers/addon_status.thtml:81
+msgid "devcp_addon_status_switch_pending"
+msgstr ""
+"O seu extra está em fila de espera. isto não deveria ter acontecido. Envie "
+"uma mensagem de correio para %s com o Id do extra e o seu estado de erro."
+
+#: views/developers/addon_status.thtml:85
+msgid "devcp_addon_status_switch_public"
+msgstr ""
+"O seu extra é <span class=\"status-4\">Público</span>, o que significa que "
+"será apresentado em todas as listagens e pesquisas e pode ser transferido "
+"sem restrições. As actualizações são fornecidas através do serviço de "
+"actualizações."
+
+#: views/developers/addon_status.thtml:71
+#: views/developers/addon_status.thtml:75
+msgid "devcp_addon_status_switch_sandbox"
+msgstr ""
+"O seu extra está no <span class=\"status-1\">Sandbox</span>, o que significa "
+"que está nas listagens e nas pesquisas mas os utilizadores têm de iniciar "
+"sessão para o transferir. As actualizações <b>não</b> não são fornecidas ao "
+"seu extra através do serviço de verificação de actualizações."
+
+#. %s is the add-on name.
+#: views/developers/addon_status_nominate.thtml:43
+#: views/developers/addon_status_confirm.thtml:43
+#: views/developers/addon_status.thtml:43
+msgid "devcp_addon_status_title"
+msgstr "Estado do %s"
+
+#: views/developers/addon_status.thtml:191
+msgid "devcp_addon_status_trusted"
+msgstr ""
+"O seu extra é de <span class=\"status-4\">Confiança</span>. Isto significa "
+"que pode submeter actualizações do seu extra sem revisão de um editor."
+
+#: views/developers/dashboard.thtml:68
+msgid "devcp_dashboard_active"
+msgstr "Activo"
+
+#. %1$s is the add-on type string
+#. %2$s is Inactive or Active in a <span>
+#. %3$s is the addon's public status (Public, In Sandbox, ...) in a <span>
+#: views/developers/dashboard.thtml:69
+msgid "devcp_dashboard_addontype_status"
+msgstr "%1$s actualmente %2$s e %3$s"
+
+#: views/developers/dashboard.thtml:67
+msgid "devcp_dashboard_change_status"
+msgstr "Alterar estado"
+
+#. %s is the addons email address.
+#: views/developers/dashboard.thtml:99
+msgid "devcp_dashboard_disabled_questions"
+msgstr ""
+"O seu extra foi desactivado por um administrador e não pode ser usado. Se "
+"tiver questões envie uma mensagem de correio paral %s."
+
+#. %s is the (localized) add-on status string in a span, e.g. "Disabled"
+#: views/developers/dashboard.thtml:98
+msgid "devcp_dashboard_disabled_status"
+msgstr "Estado do extra: %s"
+
+#: views/developers/dashboard.thtml:43
+msgid "devcp_dashboard_header_main"
+msgstr "Quadro do desenvolvedor"
+
+#: views/developers/dashboard.thtml:110
+msgid "devcp_dashboard_header_welcome"
+msgstr "Bem vindo ao quadro do desenvolvedor"
+
+#: views/developers/dashboard.thtml:68
+msgid "devcp_dashboard_inactive"
+msgstr "Inactivo"
+
+#. %s is a date in the _('date') format
+#: views/developers/dashboard.thtml:65
+msgid "devcp_dashboard_last_edited"
+msgstr "Última edição em %s"
+
+#: views/developers/dashboard.thtml:111
+msgid "devcp_dashboard_learn"
+msgstr ""
+"De momento não tem nenhum extra alojado nos extras da Mozilla. Para saber "
+"como funciona o processo e submeter o seu primeiro extra, clique em Começar."
+
+#: views/developers/dashboard.thtml:112
+msgid "devcp_dashboard_start"
+msgstr "Começar"
+
+#: views/developers/dashboard.thtml:82
+msgid "devcp_dashboard_versions"
+msgstr "Versões e ficheiros"
+
+#: views/developers/dashboard.thtml:91
+msgid "devcp_dashboard_versions_new"
+msgstr "Carregar uma nova versão"
+
+#. %s is the preview ID number.
+#: controllers/developers_controller.php:1415
+msgid "devcp_delete_previews_error"
+msgstr ""
+"A pré-visualização %s não pode ser eliminada da base de dados. Tente "
+"novamente."
+
+#. %s is the preview ID number.
+#: controllers/developers_controller.php:1413
+msgid "devcp_delete_previews_success"
+msgstr "A pré-visualização %s foi eliminada com sucesso."
+
+#: controllers/developers_controller.php:1089
+msgid "devcp_delete_version_priv_error"
+msgstr "Não tem previlégios para eliminar versões e ficheiros."
+
+#. %1$s is the count of files, a number
+#. %2$s is a status string like _('Public') or _('Incomplete')
+#: controllers/components/amo.php:549
+msgid "devcp_describe_version_status"
+msgid_plural "devcp_describe_version_status"
+msgstr[0] "%1$s %2$s ficheiro"
+msgstr[1] "%1$s %2$s ficheiros"
+
+#. %s is a version number. Example: 3.0
+#: views/developers/versions.thtml:65
+#, php-format
+msgid "devcp_details_version"
+msgstr "Versão %s"
+
+#: views/developers/discuss.thtml:68
+msgid "devcp_discuss_addreply_header"
+msgstr "Adicionar resposta"
+
+#: views/developers/discuss.thtml:57
+msgid "devcp_discuss_allreplies_header"
+msgstr "Respostas"
+
+#. notice when an error occurs saving a discussion reply
+#. %1 is the email address (linked) for the amo-editors list
+#: views/developers/discuss.thtml:70
+msgid "devcp_discuss_error_notice"
+msgstr ""
+"Houve um erro ao guardar a sua respostay. Contacte %1$s sobre este problema."
+
+#. %1 is the add-on name, %2 is the add-on's version number currently being reviewed by an editor
+#: views/developers/discuss.thtml:46
+msgid "devcp_discuss_intro"
+msgstr ""
+"Um editor de extras da Mozilla pediu-lhe mais informação sobre a versão %2$s "
+"do seu extra %1$s."
+
+#. %1 is the add-on name
+#: views/developers/discuss.thtml:43
+msgid "devcp_discuss_pagetitle"
+msgstr "Fornecer mais informação sobre o comentário %1$s do extra."
+
+#. submit button text
+#: views/developers/discuss.thtml:79
+msgid "devcp_discuss_submit_reply"
+msgstr "Submeter resposta"
+
+#: views/developers/discuss.thtml:72
+msgid "devcp_discuss_success_message"
+msgstr ""
+"A sua resposta foi guardada com sucesso. Os outros participantes na serão "
+"notificados por correio electrónicol."
+
+#. in an author/editor discussion about an add-on to be reviewed:
+#. %1 is the commenter's user name (linked).
+#. %2 is the full date the comment was made.
+#: views/developers/discuss.thtml:52 views/developers/discuss.thtml:62
+msgid "devcp_discuss_writtenby"
+msgstr "escrito por %1$s em %2$s"
+
+#: views/developers/addon_edit_authors.thtml:72
+#: views/developers/addon_edit_authors.thtml:81
+msgid "devcp_edit_authors_add_author"
+msgstr "Adicionar novo autor"
+
+#: views/developers/addon_edit_authors.thtml:96
+msgid "devcp_edit_authors_add_author_button"
+msgstr "Adicionar autor"
+
+#: views/developers/addon_edit_authors.thtml:83
+msgid "devcp_edit_authors_add_email"
+msgstr "Conta de correio do autor:"
+
+#: views/developers/addon_edit_authors.thtml:98
+msgid "devcp_edit_authors_add_loading"
+msgstr "A verificar a conta de correio..."
+
+#: views/developers/addon_edit_authors.thtml:70
+msgid "devcp_edit_authors_click_save"
+msgstr "Clique no botão de actualização de autores em baixo para guardar."
+
+#: views/developers/addon_edit_authors.thtml:58
+msgid "devcp_edit_authors_header_current"
+msgstr "Autores actuais"
+
+#: views/developers/addon_edit_authors.thtml:50
+msgid "devcp_edit_authors_header_manage"
+msgstr "Gerir autores dos extras"
+
+#: views/developers/addon_edit_authors.thtml:93
+msgid "devcp_edit_authors_label_add_listed"
+msgstr "Listar como autor nas páginas de apresentação públicas"
+
+#: views/developers/addon_edit_authors.thtml:89
+msgid "devcp_edit_authors_label_developer"
+msgstr ""
+"<strong>Desenvolvedorr</strong> - Pode gerir todos os aspectos da listagem "
+"do extra, excluindo adicionar e remover outros autores."
+
+#: views/developers/addon_edit_authors.thtml:88
+msgid "devcp_edit_authors_label_owner"
+msgstr ""
+"<strong>Dono</strong> - Pode gerir todos os aspectos da listagem do extra, "
+"incluindo adicionar e remover outros autores."
+
+#: views/developers/addon_edit_authors.thtml:90
+msgid "devcp_edit_authors_label_viewer"
+msgstr ""
+"<strong>Visitante</strong> - Pode ver a listagem e estatísticas do "
+"desenvolvedor, mas não pode efectuar nenhuma alteração."
+
+#. Placeholder for the empty option in a <select>.
+#: views/developers/addon_edit_categories.thtml:69
+msgid "devcp_edit_authors_option_empty"
+msgstr "------------------"
+
+#: views/developers/addon_edit_authors.thtml:86
+msgid "devcp_edit_authors_select_role"
+msgstr "Seleccione um papel para o autor:"
+
+#. Column name in a table.
+#: views/developers/addon_edit_authors.thtml:62
+msgid "devcp_edit_authors_th_author"
+msgstr "Autor"
+
+#. Column name in a table.
+#: views/developers/addon_edit_authors.thtml:64
+msgid "devcp_edit_authors_th_listed"
+msgstr "Listado"
+
+#. Column name in a table.
+#: views/developers/addon_edit_authors.thtml:63
+msgid "devcp_edit_authors_th_role"
+msgstr "Papel"
+
+#: views/developers/addon_edit_authors.thtml:77
+msgid "devcp_edit_authors_update_author"
+msgstr "Actualizar autores"
+
+#: views/developers/addon_edit_categories.thtml:99
+msgid "devcp_edit_categories_button_update"
+msgstr "Actualizar categorias"
+
+#: views/developers/addon_edit_categories.thtml:88
+msgid "devcp_edit_categories_does_not_fit"
+msgstr "O meu extra não se adequa a nenhuma das categorias existentes.."
+
+#. %s is the application name (Firefox, Thunderbird).
+#: views/developers/addon_edit_categories.thtml:61
+msgid "devcp_edit_categories_header_application"
+msgstr "%s Categorias"
+
+#: views/developers/addon_edit_categories.thtml:49
+msgid "devcp_edit_categories_header_manage"
+msgstr "Gerir categorias dos extras"
+
+#: views/developers/addon_edit_categories.thtml:91
+msgid "devcp_edit_categories_hover"
+msgstr "Passe por cima de uma categoria para ver a sua descrição."
+
+#. %s is the category number (1, 2, 3).
+#: views/developers/addon_edit_categories.thtml:67
+msgid "devcp_edit_categories_label_category_num"
+msgstr "Categoria %s"
+
+#: views/developers/addon_edit_categories.thtml:94
+#: views/developers/addon_edit_categories.thtml:103
+msgid "devcp_edit_categories_none_available"
+msgstr ""
+"Não existem categorias disponíveis para este tipo de extra e aplicação."
+
+#: views/developers/addon_edit_categories.thtml:86
+msgid "devcp_edit_categories_other"
+msgstr ""
+"Coloque o seu extra nesta categoria se ele não se enquadrar em nenhuma das "
+"caregorias disponíveis."
+
+#. %s is the application name (Firefox, Thunderbird).
+#: views/developers/addon_edit_categories.thtml:63
+msgid "devcp_edit_categories_select_application_categories"
+msgstr "Seleccione até três %s categorias para o seu extra."
+
+#: views/developers/addon_edit.thtml:47
+msgid "devcp_edit_dd_manage_authors"
+msgstr "Adicionar ou remover utilizadores que podem gerir este extra."
+
+#: views/developers/addon_edit.thtml:49
+msgid "devcp_edit_dd_manage_categories"
+msgstr ""
+"Seleccione as categorias relevantes para cada aplicação que o seu extra "
+"suporta."
+
+#: views/developers/addon_edit.thtml:51
+msgid "devcp_edit_dd_manage_description"
+msgstr ""
+"Adicione e modifique traduções para o sumário do seu extra, descrição, "
+"licença de utilizador e política de privacidade."
+
+#: views/developers/addon_edit.thtml:53
+msgid "devcp_edit_dd_manage_properties"
+msgstr "Altere o nome do seu extra, página inicial, ícone e outras etiquetas."
+
+#: views/developers/addon_edit_descriptions.thtml:116
+msgid "devcp_edit_description_button_update"
+msgstr "Actualizar descrições"
+
+#: views/developers/addon_edit_descriptions.thtml:115
+msgid "devcp_edit_description_correct_error"
+msgstr "Corriga os erros acima indicados a vermelho."
+
+#: views/developers/addon_edit_descriptions.thtml:51
+msgid "devcp_edit_descriptions_header"
+msgstr "Editar descrições dos extras"
+
+#: views/developers/addon_edit_descriptions.thtml:94
+msgid "devcp_edit_descriptions_transbox_comments_description"
+msgstr ""
+"Qualquer informação que os utilizadores queiram saber mas que não é "
+"necessária no sumário ou descrição do extra. Usos comuns são a listagem dos "
+"erros conhecidos, informação como reportar erros data antecipada de "
+"lançamento, etc."
+
+#: views/developers/addon_edit_descriptions.thtml:93
+msgid "devcp_edit_descriptions_transbox_comments_name"
+msgstr "Comentários do desenvolvedor"
+
+#: views/developers/addon_edit_descriptions.thtml:86
+msgid "devcp_edit_descriptions_transbox_description_description"
+msgstr ""
+"A descrição do seu extra é uma explicação sobre as funcionalidades, funções "
+"e outra informação importante. É apresentada no sumário da página do seu "
+"extra."
+
+#: views/developers/addon_edit_descriptions.thtml:85
+msgid "devcp_edit_descriptions_transbox_description_name"
+msgstr "Descrição do extra"
+
+#: views/developers/addon_edit_descriptions.thtml:103
+msgid "devcp_edit_descriptions_transbox_eula_description"
+msgstr ""
+"Se o seu extra tiver um Acordo de Licença de Utilizador Final (ALUF), "
+"escreva-o nesta caixa. Se for escrito, os utilizadores terão de aceitá-lo "
+"antes de instalar o extra. Tenha em atenção que o ALUF não é o mesmo que "
+"código de licença tipo GPL ou MPL."
+
+#: views/developers/addon_edit_descriptions.thtml:102
+msgid "devcp_edit_descriptions_transbox_eula_name"
+msgstr "Acordo de licença de utilizador final"
+
+#: views/developers/addon_edit_descriptions.thtml:112
+msgid "devcp_edit_descriptions_transbox_privacy_description"
+msgstr ""
+"Se o seu extra tiver uma política de privacidade, escreva o texto aqui. A "
+"página de apresentação do seu extra irá mostrar uma ligação para a política "
+"de privacidade."
+
+#: views/developers/addon_edit_descriptions.thtml:111
+msgid "devcp_edit_descriptions_transbox_privacy_name"
+msgstr "Política de privacidade"
+
+#: views/developers/addon_edit_descriptions.thtml:78
+msgid "devcp_edit_descriptions_transbox_summary_description"
+msgstr ""
+"O sumário é uma pequena explicação das funcionalidades básicas do seu extra "
+"e é apresentado nas listagens de pesquisa e navegação, assim como no topo da "
+"página do seu extra. <strong>Limite de 250 caractéres.</strong>"
+
+#: views/developers/addon_edit_descriptions.thtml:77
+msgid "devcp_edit_descriptions_transbox_summary_name"
+msgstr "Sumário do extra"
+
+#: views/developers/addon_edit.thtml:46
+msgid "devcp_edit_dt_manage_authors"
+msgstr "Gerir autores dos extras"
+
+#: views/developers/addon_edit.thtml:48
+msgid "devcp_edit_dt_manage_categories"
+msgstr "Gerir categorias dos extras"
+
+#: views/developers/addon_edit.thtml:50
+msgid "devcp_edit_dt_manage_descriptions"
+msgstr "Gerir descrições dos extras"
+
+#: views/developers/addon_edit.thtml:52
+msgid "devcp_edit_dt_manage_properties"
+msgstr "Gerir propriedades dos extras"
+
+#: views/developers/addon_edit_properties.thtml:170
+msgid "devcp_edit_label_externalsoftware"
+msgstr "Este extra necessita de software externo"
+
+#: views/developers/addon_edit_properties.thtml:205
+msgid "devcp_edit_label_locale_disambiguation"
+msgstr "Info adicional do Idioma"
+
+#: views/developers/addon_edit_properties.thtml:168
+msgid "devcp_edit_label_prerelease"
+msgstr "Isto é um pré-lançamento"
+
+#: views/developers/addon_edit_properties.thtml:169
+msgid "devcp_edit_label_sitespecific"
+msgstr "Isto é um extra de um sítio específico"
+
+#: views/developers/addon_edit_properties.thtml:202
+msgid "devcp_edit_label_target_locale"
+msgstr "Idioma de destino"
+
+#: views/developers/addon_edit_properties.thtml:212
+msgid "devcp_edit_properties_button_update"
+msgstr "Actualizar propriedades"
+
+#: views/developers/addon_edit_properties.thtml:198
+msgid "devcp_edit_properties_change_guid"
+msgstr "Altere apenas se compreender todas as consequencias."
+
+#: views/developers/addon_edit_properties.thtml:109
+msgid "devcp_edit_properties_current_icon"
+msgstr "Ãcone actual"
+
+#: views/developers/addon_edit_properties.thtml:85
+msgid "devcp_edit_properties_default_locale"
+msgstr ""
+"O idioma pré-definido de um extra é o idioma a partir dos quais as traduções "
+"deverão ser feitas. Se não tiverem disponíveis traduções do seu extra no "
+"idioma do utilizador, eles irão ver o idioma pré-definido."
+
+#: views/developers/addon_edit_properties.thtml:167
+msgid "devcp_edit_properties_flags"
+msgstr "Estas etiquetas são usadas para filtrar e classificar extras."
+
+#: views/developers/addon_edit_properties.thtml:174
+msgid "devcp_edit_properties_guid"
+msgstr ""
+"O GUID do seu extra é especificado no install.rdf e identifica-o unicamente. "
+"Não pode alterar o seu GUID assim que for listado nos extras da Mozilla."
+
+#: views/developers/addon_edit_properties.thtml:53
+msgid "devcp_edit_properties_header"
+msgstr "Editar propriedades do extra"
+
+#: views/developers/addon_edit_properties.thtml:186
+msgid "devcp_edit_properties_header_addon_type"
+msgstr "Tipo de extra"
+
+#: views/developers/addon_edit_properties.thtml:181
+msgid "devcp_edit_properties_header_admin_settings"
+msgstr "Definições de admin"
+
+#: views/developers/addon_edit_properties.thtml:84
+msgid "devcp_edit_properties_header_default_locale"
+msgstr "Idioma por defeito"
+
+#: views/developers/addon_edit_properties.thtml:166
+msgid "devcp_edit_properties_header_flags"
+msgstr "Etiquetas do extra"
+
+#: views/developers/addon_edit_properties.thtml:173
+#: views/developers/addon_edit_properties.thtml:197
+msgid "devcp_edit_properties_header_guid"
+msgstr "GUID do extra"
+
+#: views/developers/addon_edit_properties.thtml:104
+msgid "devcp_edit_properties_header_icon"
+msgstr "Ãcone do extra"
+
+#: views/developers/addon_edit_properties.thtml:159
+msgid "devcp_edit_properties_header_other_settings"
+msgstr "Outras definições"
+
+#. A header on the admin page to toggle trusted status.
+#: views/developers/addon_edit_properties.thtml:182
+msgid "devcp_edit_properties_header_trusted"
+msgstr "Extra de confiança?"
+
+#: views/developers/addon_edit_properties.thtml:160
+msgid "devcp_edit_properties_header_view_source"
+msgstr "Ver fonte "
+
+#. %s is a comma-separated list of image extensions ".png, .jpg"
+#: views/developers/addon_edit_properties.thtml:106
+msgid "devcp_edit_properties_icon"
+msgstr ""
+"O ícone do extra é uma pequena imagem que é mostrada ao lado do nome do seu "
+"extra nos resultados de pesquisa e navegação,páginas de apresentação, e no "
+"diálogo de instalação do extra. A imagem será redimensionada automaticamente "
+"para 32 x 32 pixéis. Utilize um dos seguintes tipos de imagem: %s"
+
+#: views/developers/addon_edit_properties.thtml:171
+msgid "devcp_edit_properties_label_binary"
+msgstr "Este extra contém componentes binários"
+
+#: views/developers/addon_edit_properties.thtml:185
+msgid "devcp_edit_properties_label_not_trusted"
+msgstr "Não é de confiança"
+
+#: views/developers/addon_edit_properties.thtml:184
+msgid "devcp_edit_properties_label_trusted"
+msgstr "De confiança"
+
+#: views/developers/addon_edit_properties.thtml:110
+msgid "devcp_edit_properties_new_icon"
+msgstr "Novo ícone"
+
+#: views/developers/addon_edit_properties.thtml:118
+msgid "devcp_edit_properties_remove_icon"
+msgstr "Remover ícone"
+
+#: views/developers/addon_edit_properties.thtml:136
+msgid "devcp_edit_properties_transbox_homepage_description"
+msgstr ""
+"Se o seu extra tiver outra página inicial, escreva o seu endereço aqui. "
+"Adicionar outras traduções não é necessário a menos que o seu sítio web "
+"esteja traduzido noutros idiomas."
+
+#: views/developers/addon_edit_properties.thtml:135
+msgid "devcp_edit_properties_transbox_homepage_name"
+msgstr "Página inicial do extra"
+
+#: views/developers/addon_edit_properties.thtml:79
+msgid "devcp_edit_properties_transbox_name_description"
+msgstr ""
+"O nome do seu extra é apresentado em todos os lados onde estiver listado."
+
+#: views/developers/addon_edit_properties.thtml:78
+msgid "devcp_edit_properties_transbox_name_name"
+msgstr "Nome do extra"
+
+#: views/developers/addon_edit_properties.thtml:145
+msgid "devcp_edit_properties_transbox_supportemail_description"
+msgstr ""
+"Se tiver um endereço de correio electrónico para pedidos de suportel, "
+"escreva o seu endereço aqui. Adicionar outras traduções não é necessário a "
+"menos que o seu sítio web esteja traduzido noutros idiomas."
+
+#: views/developers/addon_edit_properties.thtml:144
+msgid "devcp_edit_properties_transbox_supportemail_name"
+msgstr "Endereço de correio de suporte"
+
+#: views/developers/addon_edit_properties.thtml:154
+msgid "devcp_edit_properties_transbox_supporturl_description"
+msgstr ""
+"Se o seu extra tiver uma página de suporte ou um fórum, escreva o seu "
+"endereço aqui. Adicionar outras traduções não é necessário a menos que o seu "
+"sítio web esteja traduzido noutros idiomas."
+
+#: views/developers/addon_edit_properties.thtml:153
+msgid "devcp_edit_properties_transbox_supporturl_name"
+msgstr "Sítio web de suporte"
+
+#: views/developers/addon_edit_properties.thtml:183
+msgid "devcp_edit_properties_trusted"
+msgstr ""
+"Extras de confiança poderõ tornar-se públicos sem uma revisão do Editor."
+
+#. %s is href="..." and should stay in the <a> tag.
+#: views/developers/addon_edit_properties.thtml:119
+msgid "devcp_edit_properties_undelete"
+msgstr "O ícone será eliminado ao guardar. <a %s>Cancelar?</a>"
+
+#: views/developers/addon_edit_properties.thtml:161
+msgid "devcp_edit_properties_view_source"
+msgstr ""
+"O ficheiros fonte do seu extra podem ser vistos se assim o quiser, por "
+"qualquer utilizador que esteja ligado."
+
+#: views/developers/addon_edit_properties.thtml:162
+msgid "devcp_edit_properties_view_source_allow"
+msgstr "Permitir visualização da fonte quando ligado"
+
+#: views/developers/addon_edit_properties.thtml:163
+msgid "devcp_edit_properties_view_source_do_not_allow"
+msgstr "Não permitir visualização da fonte quando ligado"
+
+#: views/elements/developers/editbox.thtml:46
+msgid "devcp_editbox_authors"
+msgstr "Autores"
+
+#: views/elements/developers/editbox.thtml:47
+msgid "devcp_editbox_categories"
+msgstr "Categorias"
+
+#: views/elements/developers/editbox.thtml:52
+msgid "devcp_editbox_change_status"
+msgstr "Alterar estado"
+
+#: views/elements/developers/editbox.thtml:48
+msgid "devcp_editbox_descriptions"
+msgstr "Descrições"
+
+#: views/elements/developers/editbox.thtml:43
+msgid "devcp_editbox_edit_addon"
+msgstr "Editar extra"
+
+#: views/elements/developers/editbox.thtml:57
+msgid "devcp_editbox_new_version"
+msgstr "Nova versão"
+
+#: views/elements/developers/editbox.thtml:49
+msgid "devcp_editbox_properties"
+msgstr "Propriedades"
+
+#: views/elements/developers/editbox.thtml:60
+msgid "devcp_editbox_screenshots"
+msgstr "Pré-visualizar imagens"
+
+#: views/elements/developers/editbox.thtml:53
+msgid "devcp_editbox_statistics_dashboard"
+msgstr "Quadro de estatísticas"
+
+#: views/elements/developers/editbox.thtml:54
+msgid "devcp_editbox_versions"
+msgstr "Versões e ficheiros"
+
+#: views/elements/developers/editbox.thtml:42
+msgid "devcp_editbox_view_listing"
+msgstr "Ver listagem"
+
+#: views/elements/developers/editorsmenu.thtml:59
+msgid "devcp_editorsqueue_featured"
+msgstr "Extras"
+
+#. %1 is the review count
+#: views/elements/developers/editorsqueue.thtml:42
+#: views/elements/developers/editorsmenu.thtml:56
+#, php-format
+msgid "devcp_editorsqueue_moderatedreviews"
+msgid_plural "devcp_editorsqueue_moderatedreviews"
+msgstr[0] "Avaliações Moderadas (%s)"
+msgstr[1] "Avaliações Moderadas (%s)"
+
+#. %1 is the nominated addons count
+#: views/elements/developers/editorsqueue.thtml:44
+#: views/elements/developers/editorsmenu.thtml:58
+#, php-format
+msgid "devcp_editorsqueue_nominated"
+msgid_plural "devcp_editorsqueue_nominated"
+msgstr[0] "Extras Nomeados (%s)"
+msgstr[1] "Extras Nomeados (%s)"
+
+#. %1 is the update count
+#: views/elements/developers/editorsqueue.thtml:43
+#: views/elements/developers/editorsmenu.thtml:57
+#, php-format
+msgid "devcp_editorsqueue_pendingupdates"
+msgid_plural "devcp_editorsqueue_pendingupdates"
+msgstr[0] "Actualizações Pendentes (%s)"
+msgstr[1] "Actualizações Pendentes (%s)"
+
+#: controllers/statistics_controller.php:147
+#: controllers/statistics_controller.php:361
+#: controllers/previews_controller.php:108
+#: controllers/previews_controller.php:211
+#: controllers/previews_controller.php:312
+msgid "devcp_error_addon_access_denied"
+msgstr "Não tem acesso a esse extra."
+
+#. %s is a complete URL with the text from devcp_error_appversion_reference_link_text
+#. in the <a> tag. This should be fixed.
+#: controllers/components/developers.php:591
+#, php-format
+msgid "devcp_error_appversion_reference_link"
+msgstr "Para referência veja %s."
+
+#. This is the link text in the <a> for devcp_error_appversion_reference_link. This
+#. should be fixed.
+#: controllers/components/developers.php:591
+msgid "devcp_error_appversion_reference_link_text"
+msgstr "esta página"
+
+#: views/developers/addon_edit_authors.thtml:76
+msgid "devcp_error_empty_authors"
+msgstr "O seu extra tem de ter pelo menos um dono."
+
+#. %1$s is the name of the file
+#: controllers/components/developers.php:658
+msgid "devcp_error_file_exists"
+msgstr ""
+"Já existe uma versão deste extra. Para o substituir , tem de eliminar "
+"primeiro o ficheiro %1$s."
+
+#. %1$s is a file extension. Example: .exe
+#. %2$s is a comma separated list of extensions. Example: .xpi, .jar
+#: controllers/components/developers.php:355
+#, php-format
+msgid "devcp_error_file_extension"
+msgstr ""
+"A extensão do ficheiro (%s) não é permitida para o tipo de extra "
+"seleccionado. Por favor utilize um dos seguintes: %s"
+
+#: controllers/components/developers.php:64
+msgid "devcp_error_five_categories"
+msgstr "Por favor seleccione até 5 categorias."
+
+#: controllers/components/developers.php:526
+msgid "devcp_error_guid_application"
+msgstr "O ID desta aplicação já está a ser usado por uma aplicação."
+
+#: controllers/components/developers.php:337
+#: controllers/components/developers.php:389
+msgid "devcp_error_http_incomplete"
+msgstr "Transferência Incompleta"
+
+#: controllers/components/developers.php:335
+#: controllers/components/developers.php:336
+#: controllers/components/developers.php:387
+#: controllers/components/developers.php:388
+msgid "devcp_error_http_maxupload"
+msgstr "Excede o tamanho máximo permitido"
+
+#: controllers/components/developers.php:338
+#: controllers/components/developers.php:390
+msgid "devcp_error_http_nofile"
+msgstr "Nenhum ficheiro carregado"
+
+#. %1$s is a file extension. Example: .exe
+#. %2$s is a comma separated list of extensions. Example: .xpi, .jar
+#: controllers/components/developers.php:401
+#, php-format
+msgid "devcp_error_icon_extension"
+msgstr ""
+"A extensão do ficheiro (%s) não é permitida para um ícone. Utilize um dos "
+"seguintes: %s"
+
+#: controllers/developers_controller.php:504
+msgid "devcp_error_index_rdf_notfound"
+msgstr "Não está presente nenhum install.rdf."
+
+#: controllers/components/developers.php:601
+msgid "devcp_error_install_manifest"
+msgstr "Os seguintes erros foram encontrados no install.rdf:"
+
+#: controllers/developers_controller.php:1463
+msgid "devcp_error_invalid_addontype"
+msgstr "Por favor seleccione um tipo válido de extra."
+
+#. %$1s is a version. Example: 3.1.1
+#. %$2s is an add-on name.
+#: controllers/components/developers.php:569
+#: controllers/components/developers.php:581
+#, php-format
+msgid "devcp_error_invalid_appversion"
+msgstr "%s não é uma versão válida para %s"
+
+#. %s is a string
+#: controllers/components/developers.php:521
+#, php-format
+msgid "devcp_error_invalid_guid"
+msgstr "O ID deste extra é inválido: %s"
+
+#. %$1s is a version. Example: 3.1.1
+#. %$2s is an add-on name.
+#: controllers/components/developers.php:572
+#, php-format
+msgid "devcp_error_invalid_minversion"
+msgstr ""
+"%s não é uma versão válida parar %s: o mínimo das versões não pode conter *"
+
+#: controllers/components/developers.php:536
+msgid "devcp_error_invalid_version"
+msgstr ""
+"A versão deste extra é inválida: Por favor veja a <a href=\"http://developer."
+"mozilla.org/en/docs/Toolkit_version_format\">especificação</a>"
+
+#: controllers/components/developers.php:531
+msgid "devcp_error_invalid_version_spaces"
+msgstr "A versão deste extra é inválida: as versões não podem conter espaços."
+
+#. %s is an error message from the parser.
+#: controllers/components/developers.php:501
+#, php-format
+msgid "devcp_error_manifest_parse"
+msgstr "O seguinte erro ocorreu a fazer parsing a install.rdf: %s"
+
+#: controllers/components/developers.php:373
+msgid "devcp_error_move_file"
+msgstr "Não foi possível mover o ficheiro"
+
+#. %s is the name of a file
+#: controllers/components/developers.php:650
+#: controllers/components/developers.php:662
+#: controllers/components/developers.php:667
+#: controllers/components/developers.php:727
+#: controllers/components/developers.php:738
+#: controllers/components/developers.php:743
+#, php-format
+msgid "devcp_error_moving_file"
+msgstr "Ocorreu um erro ao mover %s."
+
+#: controllers/components/developers.php:595
+msgid "devcp_error_mozilla_application"
+msgstr "Tem de ter pelo menos uma aplicação válida da Mozilla."
+
+#: controllers/components/developers.php:516
+msgid "devcp_error_no_guid"
+msgstr "Não foi encontrado nenhum ID para este extra no install.rdf."
+
+#: controllers/components/developers.php:287
+msgid "devcp_error_no_platform"
+msgstr "Nenhuma plataforma seleccionada"
+
+#: controllers/components/developers.php:59
+msgid "devcp_error_one_category"
+msgstr "Seleccione pelo menos uma categoria."
+
+#: controllers/components/developers.php:92
+msgid "devcp_error_one_user"
+msgstr "Tem de haver pelo menos um autor para este extra."
+
+#. %1$s is a file extension. Example: .exe
+#. %2$s is a comma separated list of extensions. Example: .xpi, .jar
+#: controllers/components/developers.php:1081
+#, php-format
+msgid "devcp_error_preview_extension"
+msgstr ""
+"Essa extensão de ficheiro (%s) não é permitida para pré-visualização. "
+"Utilize um dos seguintes: %s"
+
+#: controllers/components/developers.php:511
+msgid "devcp_error_updatekey"
+msgstr ""
+"Os extras não podem utilizar uma chave de actualização. Por favor remova-a "
+"de install.rdf e tente novamente."
+
+#: controllers/components/developers.php:506
+msgid "devcp_error_updateurl"
+msgstr ""
+"Os extras não podem utilizar um URL de actualização externo. Por favor "
+"remova-o do install.rdf e tente novamente."
+
+#: controllers/developers_controller.php:465
+#: controllers/components/developers.php:271
+msgid "devcp_error_upload_file"
+msgstr "Por favor carregue um ficheiro."
+
+#: views/developers/uploader.thtml:135
+msgid "devcp_input_upload_file"
+msgstr "Carregar ficheiro"
+
+#: views/pages/js_constants.js.thtml:89
+msgid "devcp_js_a_cancel"
+msgstr "Cancelar"
+
+#: views/pages/js_constants.js.thtml:90
+msgid "devcp_js_add_email"
+msgstr "Escreva a conta de correio electrónico do autor que deseja adicionar."
+
+#. alt text for a down-arrow image.
+#: views/pages/js_constants.js.thtml:81
+msgid "devcp_js_img_move_down"
+msgstr "Mover para baixo"
+
+#. alt text for an up-arrow image.
+#: views/pages/js_constants.js.thtml:82
+msgid "devcp_js_img_move_up"
+msgstr "Mover para cima"
+
+#: views/pages/js_constants.js.thtml:91
+msgid "devcp_js_img_remove_compat"
+msgstr "Remover compatibilidade da aplicação"
+
+#: views/pages/js_constants.js.thtml:86
+msgid "devcp_js_input_list_author"
+msgstr "Listar como autor nas listagens públicas"
+
+#: views/pages/js_constants.js.thtml:92
+msgid "devcp_js_license_select"
+msgstr "Seleccione uma licença."
+
+#: views/pages/js_constants.js.thtml:93
+msgid "devcp_js_license_text"
+msgstr "Escreva o texto para a sua licença"
+
+#. <option> text in a <select> for Author role in an add-on.
+#: views/pages/js_constants.js.thtml:84
+msgid "devcp_js_option_developer"
+msgstr "Desenvolvedor"
+
+#. <option> text in a <select> for Author role in an add-on.
+#: views/pages/js_constants.js.thtml:83
+msgid "devcp_js_option_owner"
+msgstr "Dono"
+
+#. <option> text in a <select> for Author role in an add-on.
+#: views/pages/js_constants.js.thtml:85
+msgid "devcp_js_option_viewer"
+msgstr "Visualizador"
+
+#: views/pages/js_constants.js.thtml:88
+msgid "devcp_js_remove_author"
+msgstr "Remover Autor"
+
+#: views/pages/js_constants.js.thtml:87
+msgid "devcp_js_sure_remove"
+msgstr "Tem a <strong>certeza</strong> que deseja remover este extra?"
+
+#: views/pages/js_constants.js.thtml:77
+msgid "devcp_js_upload_alert"
+msgstr "Tem de seleccionar um ficheiro para carregar."
+
+#. %1$s is an addon id, like 32.
+#. %2$s is a version number, like 3.5.
+#: controllers/components/developers.php:1212
+msgid "devcp_license_existing"
+msgstr "Licença personalizada para o extra %1$s v%2$s"
+
+#: views/elements/developers/localebox.thtml:44
+msgid "devcp_localebox_header_localizedfields"
+msgstr "Campos Traduzidos"
+
+#. %1 is the default locale
+#: views/elements/developers/localebox.thtml:48
+#, php-format
+msgid "devcp_localebox_intro"
+msgstr ""
+"Alguns dos campos desta página estão traduzidos para aparecer no idioma do "
+"utilizador final. Seleccione um idioma para editar os detalhes do seu extra "
+"no idioma pretendido. Se não estiver disponível uma tradução, irá ser "
+"remetida para o idioma pré-definido (%s)."
+
+#: views/elements/developers/sidebar.thtml:68
+#: views/elements/developers/myaddons.thtml:75
+msgid "devcp_myaddons_admincp_link"
+msgstr "Painel de Controlo do Admin"
+
+#: views/elements/developers/sidebar.thtml:65
+#: views/elements/developers/myaddons.thtml:72
+msgid "devcp_myaddons_editorcp_link"
+msgstr "Painel de Controlo do Editor"
+
+#: views/elements/developers/myaddons.thtml:52
+msgid "devcp_myaddons_link"
+msgstr "Os meus Extras"
+
+#: views/elements/developers/sidebar.thtml:70
+#: views/elements/developers/myaddons.thtml:77
+msgid "devcp_myaddons_mainpage_link"
+msgstr "Voltar ao Início"
+
+#: views/elements/developers/sidebar.thtml:63
+#: views/elements/developers/myaddons.thtml:70
+msgid "devcp_myaddons_statistics_link"
+msgstr "Painel de Estatísticas"
+
+#: views/elements/developers/sidebar.thtml:62
+#: views/elements/developers/myaddons.thtml:69
+msgid "devcp_myaddons_submitaddon_link"
+msgstr "Submeter Extra"
+
+#: views/elements/developers/sidebar.thtml:48
+#: views/elements/developers/myaddons.thtml:67
+msgid "devcp_myaddons_title"
+msgstr "Ferramentas do Developer"
+
+#. %1$s is an add-on ID, perhaps 167.
+#. %2$s is a URL.
+#: controllers/developers_controller.php:256
+msgid "devcp_new_addon_error"
+msgstr ""
+"O ID deste extra (%1$s) já existe na base de dados. Se o extra for seu, pode "
+"<a href=\"%2$s\">carregar uma nova versão</a>."
+
+#: views/developers/addon_status_nominate.thtml:62
+msgid "devcp_nominate_cancel"
+msgstr "Cancelar e voltar"
+
+#. %1 is the add-on name
+#: views/developers/addon_status_nominate.thtml:61
+#, php-format
+msgid "devcp_nominate_submit_nominate"
+msgstr "Nomear %s"
+
+#: views/developers/addon_edit_properties.thtml:50
+#: views/developers/addon_status.thtml:49
+#: views/developers/versions_edit.thtml:50
+msgid "devcp_notice_changes_error"
+msgstr ""
+"<span>Uma ou mais das suas alterações não pode ser guardada.</span><br /"
+">Veja os erros abaixo. O resto das suas alterações foi guardado com sucesso."
+
+#: views/developers/addon_edit_authors.thtml:47
+#: views/developers/addon_edit_properties.thtml:47
+#: views/developers/addon_status.thtml:46
+#: views/developers/addon_edit_descriptions.thtml:47
+#: views/developers/versions_edit.thtml:47
+#: views/developers/addon_edit_categories.thtml:46
+msgid "devcp_notice_changes_saved"
+msgstr ""
+"<span>As suas alterações foram guardadas.</span><br />Tenha em atenção que "
+"algumas alterações poderão demorar várias horas a aparecer em determinadas "
+"áreas do sítio web."
+
+#: controllers/previews_controller.php:252
+msgid "devcp_notice_cleardefault"
+msgstr ""
+"Remover esta como pré-visualização por defeito irá fazer com que outra pré-"
+"visualização se torne automaticamente na pré-visualização por defeito."
+
+#: controllers/previews_controller.php:184
+#: controllers/previews_controller.php:251
+msgid "devcp_notice_makedefault"
+msgstr ""
+"Tornar esta a pré-visualização por defeito irá alterar o estado da pré-"
+"visualização actual."
+
+#: views/developers/addon_edit_authors.thtml:70
+msgid "devcp_notice_unsaved_changes"
+msgstr "Tem alterações não guardadas."
+
+#: controllers/developers_controller.php:87
+#: controllers/developers_controller.php:97
+#: controllers/developers_controller.php:100
+#: controllers/previews_controller.php:67
+#: controllers/previews_controller.php:79
+#: controllers/previews_controller.php:82
+msgid "devcp_pagetitle"
+msgstr "Painel de Controlo do Developer"
+
+#: controllers/previews_controller.php:103
+#: controllers/previews_controller.php:104
+msgid "devcp_preview_add_pagetitle"
+msgstr "Adicionar Pré-visualização"
+
+#: controllers/previews_controller.php:135
+msgid "devcp_preview_added_successfully"
+msgstr "Pré-visualização adicionada com sucesso."
+
+#: controllers/previews_controller.php:323
+msgid "devcp_preview_deleted_successfully"
+msgstr "Pré-visualização eliminada com sucesso."
+
+#: controllers/previews_controller.php:194
+#: controllers/previews_controller.php:195
+msgid "devcp_preview_edit_pagetitle"
+msgstr "Editar Pré-visualização"
+
+#: controllers/previews_controller.php:237
+msgid "devcp_preview_updated_successfully"
+msgstr "Pré-visualização actualizada com sucesso."
+
+#: views/developers/previews.thtml:120
+msgid "devcp_previews_a_another"
+msgstr "Adicionar outra pré-visualização"
+
+#: views/developers/previews.thtml:96
+msgid "devcp_previews_a_delete"
+msgstr "Eliminar pré-visualização"
+
+#: views/developers/previews.thtml:95
+msgid "devcp_previews_a_replace"
+msgstr "Substituir pré-visualização"
+
+#: views/developers/previews.thtml:126
+msgid "devcp_previews_a_update"
+msgstr "Actualizar pré-visualizações"
+
+#: views/developers/previews.thtml:115 views/developers/previews.thtml:124
+msgid "devcp_previews_add_new"
+msgstr "Adicionar nova pré-visualização"
+
+#. %s is a list of file extensions, e.g. ".png, .gif"
+#: views/developers/previews.thtml:116
+msgid "devcp_previews_add_select"
+msgstr ""
+"Seleccione a imagem a carregar abaixo. Imagens maiores que 700 pixéis de "
+"largura e 525 de altura serão redimensionados. Os ficheiros permitidos são: %"
+"s"
+
+#: views/developers/previews.thtml:121
+msgid "devcp_previews_click_below"
+msgstr "Clique em actualizar pré-visualizações abaixo para carregar."
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/previews.thtml:102
+msgid "devcp_previews_click_update"
+msgstr ""
+"Clique no botão de actualização de pré-visualizações abaixo para guardar "
+"esta imagem. (<a %s>Cancelar?</a>)"
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/previews.thtml:107
+msgid "devcp_previews_error_message"
+msgstr ""
+"Esta pré-visualização será eliminada quando actualizar pré-visualizações for "
+"clicado. (<a %s>Cancelar?</a>)"
+
+#: views/previews/add.thtml:45
+msgid "devcp_previews_filetype_info"
+msgstr ""
+"Utilize o formulário abaixo para carregar screeshots em PNG, JPG, ou GIF so "
+"seu extra. Imagens maiores que 700 pixéis de largura e 525 pixéis de altura "
+"serão automaticamente redimensionadas."
+
+#: views/previews/add.thtml:43
+msgid "devcp_previews_header_add"
+msgstr "Adicionar Pré-visualização"
+
+#: views/developers/previews.thtml:80
+msgid "devcp_previews_header_caption"
+msgstr "Pré-visualizar captura"
+
+#: views/previews/edit.thtml:43
+msgid "devcp_previews_header_edit"
+msgstr "Editar Pré-visualização"
+
+#: views/developers/previews.thtml:93
+msgid "devcp_previews_label_default"
+msgstr "Pré-visualização pré-definida"
+
+#: views/previews/add.thtml:54
+msgid "devcp_previews_label_file"
+msgstr "Pré-visualizar Ficheiro"
+
+#: views/previews/add.thtml:59 views/previews/edit.thtml:50
+msgid "devcp_previews_label_makedefault"
+msgstr "Tornar esta imagem a pré-definida"
+
+#: views/developers/previews.thtml:100
+msgid "devcp_previews_label_new"
+msgstr "Nova imagem:"
+
+#: views/developers/previews.thtml:118
+msgid "devcp_previews_label_upload"
+msgstr "Carregar pré-visualização: "
+
+#: views/developers/previews.thtml:50
+msgid "devcp_previews_notice_error"
+msgstr "Uma ou mais das suas novas pré-visualizações não pode ser guardada."
+
+#: views/developers/previews.thtml:47
+msgid "devcp_previews_notice_success"
+msgstr "As suas pré-visualizações foram actualizadas com sucesso."
+
+#: views/developers/previews.thtml:59
+msgid "devcp_previews_p_screenshots"
+msgstr ""
+"As miniaturas das pré-visualizações do seu extra são mostradas abaixo.A pré-"
+"visualização por defeito é a que é apresentada ao lado do seu extra nas "
+"listagens de pesquisa e navegação."
+
+#: views/previews/edit.thtml:55
+msgid "devcp_previews_submit_delete"
+msgstr "Eliminar Pré-visualização"
+
+#: views/previews/edit.thtml:55
+msgid "devcp_previews_submit_delete_confirm"
+msgstr "Tem a certeza que deseja eliminar esta pré-visualização?"
+
+#: views/previews/edit.thtml:54
+msgid "devcp_previews_submit_edit"
+msgstr "Editar Pré-visualização"
+
+#: views/previews/add.thtml:63
+msgid "devcp_previews_submit_upload"
+msgstr "Carregar Pré-visualização"
+
+#: views/developers/previews.thtml:78
+msgid "devcp_previews_thumbnail"
+msgstr "Miniatura"
+
+#. %s is the add-on name.
+#: views/developers/previews.thtml:44
+msgid "devcp_previews_title"
+msgstr "%s gestor de pré-visualizações"
+
+#: views/developers/uploader.thtml:74
+msgid "devcp_review_agreement_please"
+msgstr ""
+"Por favor reveja e aceite o seguinte Acordo do Desenvolvedor antes de "
+"continuar."
+
+#: views/elements/developers/rolecheck.thtml:42
+msgid "devcp_rolecheck_no_privs"
+msgstr ""
+"<span>Não tem previlégios suficientes para fazer alterações nesta página.</"
+"span><br />Contacte o dono do extra se necessitar de fazer alterações."
+
+#: controllers/developers_controller.php:1315
+msgid "devcp_several_hours"
+msgstr ""
+"Tenha em atenção que algumas alterações poderão durar algumas horas para "
+"aparecer em algumas áreas do sítios web."
+
+#: views/elements/developers/sidebar.thtml:52
+msgid "devcp_sidebar_a_dashboard"
+msgstr "Quadro"
+
+#. %s is a number
+#: views/elements/developers/statsbar.thtml:45
+#: views/developers/dashboard.thtml:79
+#, php-format
+msgid "devcp_statsbar_adu"
+msgstr "<em>%s</em> Utilizadores diários Activos"
+
+#. %s is a number
+#: views/elements/developers/statsbar.thtml:41
+#: views/developers/dashboard.thtml:75
+#, php-format
+msgid "devcp_statsbar_total_downloads"
+msgstr "<em>%s</em> Transferências no total"
+
+#. %s is a number
+#: views/elements/developers/statsbar.thtml:43
+#: views/developers/dashboard.thtml:77
+#, php-format
+msgid "devcp_statsbar_weekly_downloads"
+msgstr "<em>%s</em> Transferências Semanais"
+
+#: views/developers/addon_status_confirm.thtml:59
+msgid "devcp_status_confirm_active"
+msgstr ""
+"Macar este extra como activo irá fazer com que seja apresentado nas áres "
+"públicas apropriadas para o seu estado, incluindo listagens de pesquisa e "
+"navegação. Será transferível do sítio web e terá verificações de estado das "
+"actualizações, dependendo do seu estado. Poderá voltar aqui e desactivá-lo "
+"de novo."
+
+#: views/developers/addon_status_confirm.thtml:59
+msgid "devcp_status_confirm_active_sure"
+msgstr "Tem a certeza que deseja marcar este extra como activo?"
+
+#: views/developers/addon_status_confirm.thtml:50
+msgid "devcp_status_confirm_header_sure"
+msgstr "Tem a certeza?"
+
+#: views/developers/addon_status_confirm.thtml:55
+msgid "devcp_status_confirm_inactive"
+msgstr ""
+"Tornar este extra inactivo irá prevenir que seja apresentado em áreas "
+"públicas, incluindo listagens de pesquisa e navegação. Não irá ser "
+"transferível do sítio web e não será indicado nas verificações de "
+"actualização do cliente. Poderá voltar aqui e reactivá-lo novamente."
+
+#: views/developers/addon_status_confirm.thtml:55
+msgid "devcp_status_confirm_inactive_sure"
+msgstr "Tem a certeza que deseja marcar este extra como inactivo?'"
+
+#: views/developers/addon_status_confirm.thtml:74
+msgid "devcp_status_confirm_no"
+msgstr "Não, cancelar"
+
+#: views/developers/addon_status_confirm.thtml:67
+msgid "devcp_status_confirm_public"
+msgstr ""
+"Tornar este extra público irá torná-lo disponível para todos transferirem e "
+"começarão a ser fornecidas actualizações aos seus utilizadores."
+
+#: views/developers/addon_status_confirm.thtml:67
+msgid "devcp_status_confirm_public_sure"
+msgstr "Tem a certeza que deseja tornar este extra público?"
+
+#: views/developers/addon_status_confirm.thtml:63
+msgid "devcp_status_confirm_sandbox"
+msgstr ""
+"Mover este extra de novo para o sandbox irá necessitar que o utilizador "
+"inicie sessão antes de transferir e as actualizações não serão oferecidas "
+"aos utilizadores actuais. Como o seu extra é público, pode voltar aqui e "
+"torná-lo novamente público."
+
+#: views/developers/addon_status_confirm.thtml:63
+msgid "devcp_status_confirm_sandbox_sure"
+msgstr "Tem a certeza que deseja mover este extra para o sandbox?"
+
+#: views/developers/addon_status_confirm.thtml:73
+msgid "devcp_status_confirm_yes"
+msgstr "Sim, tenho a certeza"
+
+#: views/developers/addon_status_nominate.thtml:46
+msgid "devcp_status_nominate_error_notice"
+msgstr ""
+"<span>É necessária uma mensagem de nomeação.</span><br />Preencha a caixa de "
+"texto com a informação pedida e volte a tentar."
+
+#: views/developers/addon_status_nominate.thtml:55
+msgid "devcp_status_nominate_header"
+msgstr "Nomeação do extra"
+
+#: views/developers/dashboard.thtml:85
+msgid "devcp_summary_lastversion"
+msgstr "Última Versão:"
+
+#. %s is the add-on name.
+#: views/developers/addon_edit.thtml:43
+#: views/developers/addon_edit_authors.thtml:44
+#: views/developers/versions_delete.thtml:43
+#: views/developers/addon_edit_properties.thtml:44
+#: views/developers/addon_edit_descriptions.thtml:44
+#: views/developers/versions_edit.thtml:44
+#: views/developers/addon_edit_categories.thtml:43
+#: views/developers/versions.thtml:43
+msgid "devcp_title_edit_addon"
+msgstr "Editar %s"
+
+#. title attribute for a javascript link that pops up a help dialog.
+#: views/elements/translationbox.thtml:68
+msgid "devcp_transbox_a_title_help"
+msgstr "Ajuda (não sai da página)"
+
+#: views/elements/translationbox.thtml:68
+msgid "devcp_transbox_alt_help"
+msgstr "Ajuda"
+
+#. %1$s is <span>17</span>, %2$s is 42.
+#: views/elements/translationbox.thtml:101
+msgid "devcp_transbox_chars_used"
+msgstr "Caracteres usados: %1$s / %2$s"
+
+#: views/elements/translationbox.thtml:132
+msgid "devcp_transbox_delete_sure"
+msgstr "Tem a certeza que deseja eliminar esta tradução?"
+
+#. %s is a locale, like en-US.
+#: views/elements/translationbox.thtml:143
+msgid "devcp_transbox_help_header_tabs"
+msgstr "O que são estes %s separadores?"
+
+#: views/elements/translationbox.thtml:145
+msgid "devcp_transbox_help_header_what"
+msgstr "E se eu não tiver nenhuma tradução?"
+
+#: views/elements/translationbox.thtml:147
+msgid "devcp_transbox_help_hide"
+msgstr "Ocultar ajuda"
+
+#: views/elements/translationbox.thtml:146
+msgid "devcp_transbox_help_if"
+msgstr ""
+"Se um utilizador ao navegar no sítio não tiver uma tradução no seu idioma "
+"disponível, irá ser redireccionado para o idioma pré-definido do seu extra, "
+"especificado na área Editar propriedades do extra. Se não tiver nenhuma "
+"tradução, escreva o que puder no seu idioma pré-definido , que deverá ser o "
+"idioma em que fala."
+
+#: views/elements/translationbox.thtml:144
+msgid "devcp_transbox_help_transbox"
+msgstr ""
+"Isto é uma <i>Caixa de tradução</i>.Permite-lhe traduzir um campo específico "
+"para outros idiomas para os quais tenha uma tradução. Pode adicionar, editar "
+"e remover traduções usando os separadores de idioma."
+
+#: views/elements/translationbox.thtml:85
+msgid "devcp_transbox_img_add_trans"
+msgstr "Adicionar tradução"
+
+#: views/elements/translationbox.thtml:86
+msgid "devcp_transbox_img_remove_trans"
+msgstr "Remover tradução"
+
+#: views/elements/translationbox.thtml:123
+msgid "devcp_transbox_input_add_all"
+msgstr "Adicionar idioma a todos"
+
+#: views/elements/translationbox.thtml:122
+msgid "devcp_transbox_input_add_locale"
+msgstr "Adicionar idioma"
+
+#: views/elements/translationbox.thtml:124
+#: views/elements/translationbox.thtml:135
+msgid "devcp_transbox_input_cancel"
+msgstr "Cancelar"
+
+#: views/elements/translationbox.thtml:134
+msgid "devcp_transbox_input_delete"
+msgstr "Eliminar"
+
+#: views/elements/translationbox.thtml:113
+msgid "devcp_transbox_select_locale"
+msgstr "Seleccione o idioma da tradução a adicionar:"
+
+#. %1$s and %2$s are GUIDs.
+#: controllers/developers_controller.php:343
+msgid "devcp_update_addon_guid_error"
+msgstr ""
+"O GUID do extra usado neste ficheiro (%1$s) não é igual ao GUID existente "
+"para este extra (%2$s)."
+
+#: controllers/developers_controller.php:334
+msgid "devcp_update_addon_priv_error"
+msgstr "Não tem previlégios suficientes para actualizar este extra."
+
+#. %1$s is a version number, %2$s is an add-on ID.
+#: controllers/developers_controller.php:399
+msgid "devcp_update_addon_version_belong_error"
+msgstr "A versão especificada (%1$s) não pertence a este extra (%2$s)."
+
+#. %1$s is a version number, maybe 1.1.
+#. %2$s is a URL.
+#: controllers/developers_controller.php:351
+msgid "devcp_update_addon_version_exists_error"
+msgstr ""
+"O número da versão carregada (%1$s) já existe para este extra. Se está a "
+"tentar adicionar outro ficheiro a esta versão, <a href=\"%2$s\">clique aqui</"
+"a>."
+
+#. %1$s and %2$s are version numbers.
+#: controllers/developers_controller.php:405
+msgid "devcp_update_addon_version_match_error"
+msgstr ""
+"O número da versão carregada (%1$s) não é igual à versão existente (%2$s)."
+
+#: views/developers/uploader.thtml:68
+msgid "devcp_uploader_a_start"
+msgstr "Começar"
+
+#: views/developers/uploader.thtml:137
+msgid "devcp_uploader_ajax_loading"
+msgstr "A carregar ficheiro..."
+
+#: views/developers/uploader.thtml:82
+msgid "devcp_uploader_button_agree"
+msgstr " "
+
+#: views/developers/uploader.thtml:157
+msgid "devcp_uploader_button_edit"
+msgstr "Editar o meu extra"
+
+#: views/developers/uploader.thtml:158
+msgid "devcp_uploader_button_later"
+msgstr "Termino o meu extra mais tarde."
+
+#: views/developers/uploader.thtml:168
+msgid "devcp_uploader_button_release"
+msgstr "Adicionar notas de lançamento"
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/uploader.thtml:156
+msgid "devcp_uploader_created_results"
+msgstr ""
+"<p>A lista do seu extra foi carregada com sucesso. A informação básica "
+"obtida do ficheiro que carregou foi guardada, mas existe muito mais na sua "
+"listagem que pode ser personalizado.</p><p>O seu extra actualmente está "
+"marcado como <strong>Imcompleto</strong>. Para poder completar o seu extra, "
+"tem de ter a certeza que tem um nome correcto, sumário e descrição assim "
+"como, pelo menos, uma categoria seleccionada. Pode editar a informação do "
+"seu extra usando a ligação abaixo e verificar o estado do seu extra a "
+"qualquer momento na <a %s>página de estado</a>."
+
+#: views/developers/uploader.thtml:143
+msgid "devcp_uploader_error_correct"
+msgstr "Corrija este problema e carregue o seu ficheiro de novo."
+
+#. %1$s is a version number, %2$s is a status, e.g Public or Incomplete.
+#: views/developers/uploader.thtml:175
+msgid "devcp_uploader_file_created"
+msgstr ""
+"O seu novo ficheiro foi adicionado à versão %1$s e está marcado como %2$s."
+
+#: views/developers/uploader.thtml:154
+msgid "devcp_uploader_header_created"
+msgstr "Extra criado!"
+
+#: views/developers/uploader.thtml:141
+msgid "devcp_uploader_header_error"
+msgstr "Oops! parece que existe um problema com este ficheiro..."
+
+#: views/developers/uploader.thtml:173
+msgid "devcp_uploader_header_file_added"
+msgstr "Ficheiro adicionado!"
+
+#: views/developers/uploader.thtml:66
+msgid "devcp_uploader_header_how"
+msgstr "Como é que tudo isto funciona?"
+
+#. %s is the version number, e.g. 3.2.
+#: views/developers/uploader.thtml:163
+msgid "devcp_uploader_header_update_created"
+msgstr "Versão %s criada"
+
+#: views/developers/uploader.thtml:117
+msgid "devcp_uploader_header_upload"
+msgstr "Carregar o seu ficheiro"
+
+#: views/developers/uploader.thtml:67
+msgid "devcp_uploader_how"
+msgstr ""
+"<p>Obrigado pelo interesse em submeter o seu extra nos Extras da Mozilla. "
+"Hospedar o seu extra nos Extras da Mozilla é a maneira mais fácil para "
+"distribuir o seu extra. Eis o que obtém:</p><ul><li>Cada extra tem uma "
+"página de apresentação pública que mostra a informação que forneceu, tal "
+"como, um breve sumário da funcionalidade do extra, uma descrição mais longa "
+"como opção e uma pre-visualização de imagens do extra.</li><li>O seu extra "
+"irá aparecer nas listagem de pesquisa e navegação por todo o sítio e até no "
+"gestor de extras do Firefox 3.</li><li>Nós cuidamos da hospedagem de todas "
+"as suas transferências e fornecemos actualizações automáticas aos "
+"utilizadores quando carregar uma nova versão.</li><li>Irá ter acesso a um "
+"quadro de estatísticas com informação detalhada sobre a base de utilizadores."
+"</li></ul><p>Extras hospedados no sítio têm de ser revistos por Editor dos "
+"Extras da Mozilla antes de todas as suas funcionalidades serem listadas "
+"acima. Se estiver pronto para iniciar o processo e tiver o pacote do seu "
+"extra pronto para ser carregado clique em Iniciar!</p>"
+
+#: views/developers/uploader.thtml:125
+msgid "devcp_uploader_label_platformtype"
+msgstr "Plataformas suportadas:"
+
+#: views/developers/uploader.thtml:124
+msgid "devcp_uploader_label_upload_field"
+msgstr "Ficheiro do extra: "
+
+#: controllers/components/developers.php:1221
+msgid "devcp_uploader_option_other"
+msgstr "Outro"
+
+#. %1$s is a number, %2$s is href="..." and should stay in the <a> tag.
+#: views/developers/uploader.thtml:176
+msgid "devcp_uploader_p_pending_file"
+msgstr ""
+"O novo ficheiro será tornado público assim que um editor o puder rever. "
+"Actualmente existem %1$s outros extras em espera. Deseja ser revisto mais "
+"rapidamente? Considere <a %2$s>tornar-se um editor</a>."
+
+#. %1$s is a number, %2$s is href="..." and should stay in the <a> tag.
+#: views/developers/uploader.thtml:166
+msgid "devcp_uploader_p_pending_version"
+msgstr ""
+"A nova versão será tornada públiao assim que um editor o puder rever. "
+"Actualmente existem %1$s outros extras em espera. Deseja ser revisto mais "
+"rapidamente? Considere <a %2$s>tornar-se um editor</a>."
+
+#. %s is a status, e.g Public or Incomplete.
+#: views/developers/uploader.thtml:165
+msgid "devcp_uploader_p_update_created"
+msgstr "A sua nova versão foi criada e está marcada como %s."
+
+#. %1$s is href="..." and should stay in the 'Versions and Files' <a> tag.
+#. %2$s is href="..." and should stay in the 'current status' <a> tag.
+#: views/developers/uploader.thtml:177
+msgid "devcp_uploader_p_update_file"
+msgstr ""
+"Veja o seu novo ficheiro na <a %1$s>página de versões e ficheiros</a>, "
+"verifique o <a %2$s>estado actual</a> do seu extra, ou <b>adicione notas de "
+"lançamento</b> clicando no botão abixo (altamente recomendado)."
+
+#. %1$s is href="..." and should stay in the 'Versions and Files' <a> tag.
+#. %2$s is href="..." and should stay in the 'current status' <a> tag.
+#: views/developers/uploader.thtml:167
+msgid "devcp_uploader_p_update_version"
+msgstr ""
+"Veja a sua nova versão na <a %1$s>página de versões e ficheiros</a>, "
+"verifique o <a %2$s>estado actual</a> do seu extra, ou <b>adicione notas de "
+"lançamento</b>clicando no botão abaixo (altamente recomendado)."
+
+#: views/developers/uploader.thtml:118
+msgid "devcp_uploader_p_upload"
+msgstr ""
+"Carregue o seu ficheiro do extra usando o formulário abaixo. Se tiver "
+"múltiplos ficheiros específicos para determinadas plataformas para carregar, "
+"escolha um único ficheiro e depois carregue os restantes usando o gestor de "
+"ficheiros e versões."
+
+#: views/developers/uploader.thtml:125
+msgid "devcp_uploader_platformtype_all"
+msgstr "Todas"
+
+#: views/developers/uploader.thtml:126
+msgid "devcp_uploader_platformtype_specific"
+msgstr "Específico:"
+
+#. Used as first item in a <select>.
+#: controllers/components/developers.php:1185
+msgid "devcp_uploader_please_choose"
+msgstr "Por favor, escolha..."
+
+#. %1$s is the add-on name, %2$s is the version number.
+#: views/developers/uploader.thtml:57
+msgid "devcp_uploader_title_file"
+msgstr "Adicionar ficheiro a %1$s %2$s"
+
+#: views/developers/uploader.thtml:50
+msgid "devcp_uploader_title_submit"
+msgstr "Submeter novo extra"
+
+#. %s is the add-on name.
+#: views/developers/uploader.thtml:54
+msgid "devcp_uploader_title_update"
+msgstr "Actualizar %s"
+
+#. %s is a full <a> tag
+#: controllers/developers_controller.php:503
+#, php-format
+msgid "devcp_valid_app_reference"
+msgstr "Para referência veja %s."
+
+#. This is the text in the <a> tag for devcp_valid_app_reference. This should be
+#. fixed.
+#: controllers/developers_controller.php:503
+msgid "devcp_valid_app_reference_linktext"
+msgstr "esta página"
+
+#: controllers/developers_controller.php:581
+msgid "devcp_verify_author_error"
+msgstr "Nenhuma conta encontrada para este endereço de correio."
+
+#: controllers/developers_controller.php:553
+msgid "devcp_verify_search_engine_error"
+msgstr ""
+"Ou o XMLé inválido ou os campos necessários estão em falta. Por favor <a "
+"href=\"https://developer.mozilla.org/en/"
+"Creating_OpenSearch_plugins_for_Firefox\">leia a documentação</a>, verifique "
+"o seu extra e tente novamente."
+
+#: views/developers/versions.thtml:75
+msgid "devcp_versions_a_cancel"
+msgstr "Cancelar"
+
+#: views/developers/versions.thtml:79
+msgid "devcp_versions_a_delete"
+msgstr "Eliminar versão"
+
+#: views/developers/versions.thtml:74
+msgid "devcp_versions_a_empty"
+msgstr "Remover versão vazia"
+
+#: views/developers/versions.thtml:71
+msgid "devcp_versions_a_remove"
+msgstr "Remover?"
+
+#: views/developers/versions.thtml:91
+msgid "devcp_versions_add"
+msgstr "Adicionar nova versão"
+
+#: views/developers/versions_delete.thtml:58
+msgid "devcp_versions_delete_a_cancel"
+msgstr "Cancelar"
+
+#: views/developers/versions_delete.thtml:56
+msgid "devcp_versions_delete_a_delete"
+msgstr "Eliminar versão"
+
+#. Followed by a list of reviews and files that will be removed.
+#: views/developers/versions_delete.thtml:50
+msgid "devcp_versions_delete_also"
+msgstr "Isto também elimina:"
+
+#: views/developers/versions_delete.thtml:53
+msgid "devcp_versions_delete_files"
+msgid_plural "devcp_versions_delete_files"
+msgstr[0] "%s ficheiro"
+msgstr[1] "%s ficheiros"
+
+#. %s is the version number.
+#: views/developers/versions_delete.thtml:48
+msgid "devcp_versions_delete_header"
+msgstr "Eliminar versão %s?"
+
+#: views/developers/versions_delete.thtml:52
+msgid "devcp_versions_delete_reviews"
+msgid_plural "devcp_versions_delete_reviews"
+msgstr[0] "%s comentário"
+msgstr[1] "%s comentários"
+
+#. %s is the version number.
+#: views/developers/versions_delete.thtml:49
+msgid "devcp_versions_delete_sure"
+msgstr "Tem a certeza que deseja eliminar permanentemente a versão %s?"
+
+#: views/developers/versions_edit.thtml:102
+#: views/developers/versions_edit.thtml:155
+msgid "devcp_versions_edit_a_cancel"
+msgstr "Cancelar"
+
+#: views/developers/versions_edit.thtml:101
+msgid "devcp_versions_edit_a_delete"
+msgstr "Eliminar ficheiro"
+
+#: views/developers/versions_edit.thtml:165
+msgid "devcp_versions_edit_a_new_app"
+msgstr "Adicionar nova aplicação"
+
+#: views/developers/versions_edit.thtml:154
+msgid "devcp_versions_edit_a_remove_app"
+msgstr "Remover aplicação"
+
+#: views/developers/versions_edit.thtml:114
+msgid "devcp_versions_edit_add"
+msgstr "Adicionar novo ficheiro"
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/versions_edit.thtml:121
+msgid "devcp_versions_edit_adjust"
+msgstr ""
+"Ajustar aqui a informação da aplicação permite a todos os utilizadores "
+"instalar o seu extra mesmo que o install.rdf indique que o extra é "
+"imcompatível. <a %s>Lista de aplicações suportadas</a>"
+
+#: views/developers/versions_edit.thtml:153
+msgid "devcp_versions_edit_compat_sure"
+msgstr ""
+"Tem a <b>certeza</b> que deseja remover a compatibilidade com esta aplicação?"
+
+#: views/developers/versions_edit.thtml:100
+msgid "devcp_versions_edit_delete_sure"
+msgstr ""
+"Tem a <b>certeza</b> que deseja eliminar permanentemente este ficheiro?"
+
+#: views/developers/versions_edit.thtml:203
+msgid "devcp_versions_edit_header_approval"
+msgstr "Informação sobre a aprovação"
+
+#: views/developers/versions_edit.thtml:120
+msgid "devcp_versions_edit_header_compat"
+msgstr "Aplicações compatíveis"
+
+#: views/developers/versions_edit.thtml:74
+msgid "devcp_versions_edit_header_file"
+msgstr "Informação do ficheiro"
+
+#: views/developers/versions_edit.thtml:189
+msgid "devcp_versions_edit_header_license"
+msgstr "Licença"
+
+#. %s is the version number.
+#: views/developers/versions_edit.thtml:53
+msgid "devcp_versions_edit_header_manage"
+msgstr "gerir versão %s"
+
+#: views/developers/versions_edit.thtml:212
+msgid "devcp_versions_edit_header_notes"
+msgstr "Notas de aprovação"
+
+#: views/developers/versions_edit.thtml:98
+msgid "devcp_versions_edit_img_delete"
+msgstr "Eliminar ficheiro"
+
+#. %1$s is the file id, e.g. 18723.
+#. %2$s is the platform name, e.g. ALL or Windows.
+#. %3$s is the _('date) created.
+#. %4$s is the status, e.g. "In Sandbox" or "Public".
+#. %5$s is the _('date') status was changed.
+#: views/developers/versions_edit.thtml:208
+msgid "devcp_versions_edit_li_file"
+msgstr "Ficheiro %1$s (%2$s) criado em %3$s e alterado para %4$s a %5$s"
+
+#: views/developers/versions_edit.thtml:190
+msgid "devcp_versions_edit_license_description"
+msgstr ""
+"Seleccione a licença apropriada para o seu extra. Esta licença especifíca os "
+"direitos que dá ao seu código fonte."
+
+#: views/developers/versions_edit.thtml:111
+msgid "devcp_versions_edit_no_files"
+msgstr "Não foram encontrados ficheiros."
+
+#: views/developers/versions_edit.thtml:213
+msgid "devcp_versions_edit_optional"
+msgstr "Informação opcional para o Editor que revê esta versão."
+
+#: views/developers/versions_edit.thtml:151
+msgid "devcp_versions_edit_remove_compat"
+msgstr "Remover compatibilidade da aplicação"
+
+#: views/developers/versions_edit.thtml:167
+msgid "devcp_versions_edit_select_app"
+msgstr "seleccione uma aplicação"
+
+#: views/developers/versions_edit.thtml:78
+msgid "devcp_versions_edit_th_file"
+msgstr "Ficheiro"
+
+#: views/developers/versions_edit.thtml:79
+msgid "devcp_versions_edit_th_platform"
+msgstr "Plataforma"
+
+#: views/developers/versions_edit.thtml:80
+msgid "devcp_versions_edit_th_size"
+msgstr "Tamanho"
+
+#: views/developers/versions_edit.thtml:81
+msgid "devcp_versions_edit_th_status"
+msgstr "Estado"
+
+#: views/developers/versions_edit.thtml:183
+msgid "devcp_versions_edit_transbox_releasenotes_description"
+msgstr ""
+"Informação sobre alterações nesta versão, novas funcionalidades, problemas "
+"conhecidos e outra informação útil específica a esta versão. Esta informação "
+"estará disponível para os utilizadores que actualizem o extra na interface "
+"de gestão de extras do Firefox 3."
+
+#: views/developers/versions_edit.thtml:182
+msgid "devcp_versions_edit_transbox_releasenotes_name"
+msgstr "Notas de lançamento"
+
+#: views/developers/versions_edit.thtml:164
+msgid "devcp_versions_edit_unsaved_compat"
+msgstr ""
+"<strong>Tem alterações não guardadas.</strong> A compatibilidade não será "
+"eliminada até que clique em actualizar versão."
+
+#: views/developers/versions_edit.thtml:113
+msgid "devcp_versions_edit_unsaved_files"
+msgstr ""
+"<strong>Tem alterações não guardadas.</strong> Os ficheiros não serão "
+"eliminados até que clique em actualizar versão."
+
+#: views/developers/versions_edit.thtml:218
+msgid "devcp_versions_edit_update"
+msgstr "Actualizar versões"
+
+#: views/developers/versions.thtml:49
+msgid "devcp_versions_header_manage"
+msgstr "Gerir versões e ficheiros"
+
+#: views/developers/versions.thtml:87
+msgid "devcp_versions_no_versions"
+msgstr "Sem versões."
+
+#. %s is a version number, base 10.
+#: views/developers/versions.thtml:46
+msgid "devcp_versions_notice_success"
+msgstr "Versão %s eliminada com sucesso."
+
+#: views/developers/versions.thtml:73
+msgid "devcp_versions_p_remove"
+msgstr ""
+"Esta versão não tem ficheiros associados e pode ser removida. Deseja remover "
+"esta versão?"
+
+#: views/developers/versions.thtml:58
+msgid "devcp_versions_th_created"
+msgstr "Criado"
+
+#: views/developers/versions.thtml:57
+msgid "devcp_versions_th_status"
+msgstr "Estado"
+
+#: views/developers/versions.thtml:56
+msgid "devcp_versions_th_version"
+msgstr "Versão"
+
+#: controllers/downloads_controller.php:91
+msgid "downloads_disable_warning"
+msgstr "Este extra está desactivado"
+
+#: controllers/components/editors.php:57
+msgid "editor_review_error_addon_not_nominated"
+msgstr "Este extra não foi nomeado"
+
+#: controllers/components/editors.php:213
+msgid "editor_review_error_file_not_pending"
+msgstr "O ficheiro não está à espera de revisão."
+
+#. Actions are, for example: approving or rejecting
+#: controllers/components/editors.php:79
+#: controllers/components/editors.php:182
+msgid "editor_review_error_no_action"
+msgstr "Por favor seleccione uma acção para a revisão"
+
+#: controllers/components/editors.php:192
+msgid "editor_review_error_no_applications"
+msgstr "Por favor escreva as aplicações que testou."
+
+#. Comments are required when an editor approves or rejects an add-on.
+#: controllers/components/editors.php:84
+#: controllers/components/editors.php:187
+msgid "editor_review_error_no_comments"
+msgstr "Por favor escreva o comentário da revisão"
+
+#: controllers/components/editors.php:161
+msgid "editor_review_error_no_files"
+msgstr "Por favor seleccione pelo menos um comentário."
+
+#: controllers/components/editors.php:197
+msgid "editor_review_error_no_operating_system"
+msgstr "Por favor escreva os sistemas operativos que testou."
+
+#: views/editors/logs.thtml:51
+msgid "editorcp_logs_button_filter"
+msgstr "Filtro"
+
+#: views/editors/logs.thtml:44
+msgid "editorcp_logs_filter_by"
+msgstr "Filtrar por tipo/acção"
+
+#: views/editors/logs.thtml:42 controllers/editors_controller.php:964
+msgid "editorcp_logs_page_heading"
+msgstr "Registo de Eventos"
+
+#: views/elements/developers/editorsmenu.thtml:60
+msgid "editorcp_menu_eventlog_link"
+msgstr "Registo de Eventos"
+
+#: views/elements/developers/editorsmenu.thtml:62
+msgid "editorcp_menu_mainpage_link"
+msgstr "Voltar ao Início"
+
+#: views/elements/developers/editorsmenu.thtml:61
+msgid "editorcp_menu_reviewlog_link"
+msgstr "Registo do comentário"
+
+#: views/elements/developers/editorsmenu.thtml:55
+msgid "editorcp_menu_summary_link"
+msgstr "Sumário do Editor"
+
+#: views/elements/developers/editorsmenu.thtml:52
+msgid "editorcp_menu_title"
+msgstr "Ferramentas do Editor"
+
+#: views/editors/reviewlog.thtml:49
+msgid "editorcp_reviewlog_button_filter"
+msgstr "Filtro"
+
+#: views/editors/reviewlog.thtml:58
+msgid "editorcp_reviewlog_column_action"
+msgstr "Acção"
+
+#: views/editors/reviewlog.thtml:56
+msgid "editorcp_reviewlog_column_addon"
+msgstr "Extra"
+
+#: views/editors/reviewlog.thtml:55
+msgid "editorcp_reviewlog_column_date"
+msgstr "Data"
+
+#: views/editors/reviewlog.thtml:57
+msgid "editorcp_reviewlog_column_editor"
+msgstr "Editor"
+
+#: views/editors/reviewlog.thtml:94
+msgid "editorcp_reviewlog_comments_hide"
+msgstr "Ocultar Comentários"
+
+#: views/editors/reviewlog.thtml:93
+msgid "editorcp_reviewlog_comments_show"
+msgstr "Mostrar Comentários"
+
+#. %1$s and %2$s are full <input> tags for dates
+#: views/editors/reviewlog.thtml:45
+#, php-format
+msgid "editorcp_reviewlog_entries_between"
+msgstr "Ver entradas entre %s e %s"
+
+#: views/editors/reviewlog.thtml:104
+msgid "editorcp_reviewlog_none_found"
+msgstr "Nenhum comentário encontrado para este período."
+
+#: views/editors/reviewlog.thtml:42
+msgid "editorcp_reviewlog_page_heading"
+msgstr "Registo do comentário"
+
+#: views/editors/summary.thtml:61
+msgid "editorcp_summary_monthreviews_heading"
+msgstr "Avaliações Mensais"
+
+#: views/editors/summary.thtml:77
+msgid "editorcp_summary_neweditors_heading"
+msgstr "Novos Editores"
+
+#: views/editors/summary.thtml:42
+msgid "editorcp_summary_page_heading"
+msgstr "Sumário do Editor"
+
+#: views/editors/summary.thtml:94
+msgid "editorcp_summary_recentactivity_heading"
+msgstr "Actividade Recente do Editor"
+
+#: views/editors/summary.thtml:45
+msgid "editorcp_summary_totalreviews_heading"
+msgstr "Total de comentários"
+
+#: controllers/editors_controller.php:248
+#: controllers/editors_controller.php:249
+msgid "editors_addon_review_pagetitle"
+msgstr "Avaliar Extra"
+
+#: controllers/editors_controller.php:349
+msgid "editors_error_js-formerror"
+msgstr "Por favor complete os seguintes campos:"
+
+#: controllers/editors_controller.php:350
+msgid "editors_error_review_one_file"
+msgstr "Seleccione pelo menos um ficheiro para rever."
+
+#: controllers/editors_controller.php:274
+msgid "editors_error_self_reviews_forbidden"
+msgstr "Comentários próprios não são permitidos."
+
+#: controllers/editors_controller.php:699
+msgid "editors_external_software"
+msgstr "Software Externo"
+
+#: views/editors/featured.thtml:120 views/editors/featured.thtml:121
+msgid "editors_featured_add_feature"
+msgstr "Adicionar funcionalidade"
+
+#: views/editors/featured.thtml:126
+msgid "editors_featured_add_feature_submit"
+msgstr "Adicionar"
+
+#: views/editors/featured.thtml:49 controllers/editors_controller.php:832
+#: controllers/editors_controller.php:848
+msgid "editors_featured_addon_add_failure"
+msgstr "Adicionar funcionalidade falhou."
+
+#: controllers/editors_controller.php:851
+msgid "editors_featured_addon_add_success"
+msgstr "Funcionalidade adicionada com sucesso."
+
+#: views/editors/featured.thtml:50 controllers/editors_controller.php:839
+#: controllers/editors_controller.php:868
+#: controllers/editors_controller.php:886
+msgid "editors_featured_addon_edit_failure"
+msgstr "A edição da funcionalidade falhou."
+
+#: views/editors/featured.thtml:51 controllers/editors_controller.php:888
+msgid "editors_featured_addon_edit_success"
+msgstr "Edição da funcionalidade feita com sucesso."
+
+#: views/editors/featured.thtml:53 controllers/editors_controller.php:861
+msgid "editors_featured_addon_invalid_locale"
+msgstr "Uma ou mais traduções são inválidas."
+
+#: views/editors/featured.thtml:52 controllers/editors_controller.php:906
+msgid "editors_featured_addon_remove_failure"
+msgstr "A eliminação da funcionalidade falhou."
+
+#: controllers/editors_controller.php:901
+msgid "editors_featured_addon_remove_success"
+msgstr "Eliminação da funcionalidade feita com sucesso."
+
+#: controllers/editors_controller.php:915
+#: controllers/editors_controller.php:917
+msgid "editors_featured_addons_pagetitle"
+msgstr "Funcionalidades do Extra"
+
+#: views/editors/featured.thtml:54 views/editors/featured.thtml:107
+msgid "editors_featured_edit_feature_submit"
+msgstr "Ir"
+
+#: views/editors/featured.thtml:90 views/editors/featured.thtml:91
+msgid "editors_featured_remove_feature"
+msgstr "Eliminar funcionalidade"
+
+#: views/editors/queue.thtml:46
+msgid "editors_filter_queue"
+msgstr "Filtro de Espera"
+
+#: views/editors/queue.thtml:182
+msgid "editors_helpful_links"
+msgstr "Ligações de Interesse"
+
+#: views/editors/queue.thtml:182
+msgid "editors_link_guide"
+msgstr "Guia dos Editores"
+
+#: views/editors/queue.thtml:182
+msgid "editors_link_policy"
+msgstr "Política dos Extras"
+
+#: views/editors/queue.thtml:47
+msgid "editors_notice_filter_session"
+msgstr "Estes filtros irão manter-se durante esta sessão ou até serem limpos."
+
+#. %1 is the queue mode
+#: views/editors/queue.thtml:177 views/admin/flagged_queue.thtml:89
+msgid "editors_notice_none_found"
+msgstr "De momento não existem nenhuns %s extras para rever."
+
+#: controllers/editors_controller.php:1040
+msgid "editors_one_day"
+msgstr "1 dia"
+
+#: controllers/editors_controller.php:1048
+msgid "editors_one_hour"
+msgstr "1 hora"
+
+#: controllers/editors_controller.php:1056
+msgid "editors_one_minute"
+msgstr "1 minuto"
+
+#: controllers/editors_controller.php:64 controllers/editors_controller.php:73
+#: controllers/editors_controller.php:77
+msgid "editors_pagetitle"
+msgstr "Painel de controlo do Editor"
+
+#. %s is a comma separated list of platforms. Example: Windows, OS X
+#: controllers/editors_controller.php:680
+#: controllers/editors_controller.php:683
+#, php-format
+msgid "editors_platform_x_only"
+msgstr "apenas %s"
+
+#: controllers/editors_controller.php:695
+msgid "editors_pre-release"
+msgstr "Pré-lançamento"
+
+#. %1 is the app name
+#: views/editors/queue.thtml:131
+#, php-format
+msgid "editors_queue_app_compatibility"
+msgstr "%s Compatibilidade"
+
+#: views/editors/queue.thtml:51
+msgid "editors_queue_filter_label_addon"
+msgstr "Extra ou correio electrónico do autor"
+
+#: views/editors/queue.thtml:72
+msgid "editors_queue_filter_label_addontypes"
+msgstr "Tipos de extra"
+
+#: views/editors/queue.thtml:56
+msgid "editors_queue_filter_label_application"
+msgstr "Aplicação"
+
+#: views/editors/queue.thtml:61
+msgid "editors_queue_filter_label_maxversion"
+msgstr "Versão máx."
+
+#: views/editors/queue.thtml:78
+msgid "editors_queue_filter_label_platforms"
+msgstr "Plataformas"
+
+#: views/editors/queue.thtml:66
+msgid "editors_queue_filter_label_submissionage"
+msgstr "Idade da submissão (dias)"
+
+#. %1$s is a number
+#: views/editors/queue.thtml:90
+msgid "editors_queue_filter_result_count"
+msgid_plural "editors_queue_filter_result_count"
+msgstr[0] "Resultados da sua pesquisa com filtros: <strong>%1$s</strong> extra"
+msgstr[1] ""
+"Resultados da sua pesquisa com filtros: <strong>%1$s</strong> extras"
+
+#: views/editors/queue.thtml:84
+msgid "editors_queue_submit_clean"
+msgstr "Limpar"
+
+#: views/editors/queue.thtml:83
+msgid "editors_queue_submit_filter"
+msgstr "Filtro"
+
+#: controllers/editors_controller.php:133
+msgid "editors_queues_disabled"
+msgstr ""
+"Todas os comentários em espera estão actualmente desactivados. Volte a "
+"tentar mais tarde."
+
+#: views/editors/review.thtml:149
+msgid "editors_review_a_edit_item"
+msgstr "Editar item"
+
+#: views/editors/review.thtml:146
+msgid "editors_review_a_item_history"
+msgstr "Histórico do item"
+
+#: views/editors/review.thtml:148
+msgid "editors_review_a_item_homepage"
+msgstr "Página inicial do item"
+
+#: views/editors/review.thtml:145
+msgid "editors_review_a_item_overview"
+msgstr "Visualizar item"
+
+#: views/editors/review.thtml:147
+msgid "editors_review_a_previews"
+msgstr "Pré-visualizações"
+
+#: controllers/editors_controller.php:345
+msgid "editors_review_action"
+msgstr "Acção do comentário"
+
+#: views/editors/review.thtml:159
+msgid "editors_review_action_info"
+msgstr "Pedir mais informação"
+
+#: views/editors/review.thtml:157
+msgid "editors_review_action_public"
+msgstr "Tornar Público"
+
+#: views/editors/review.thtml:160
+msgid "editors_review_action_request_superreview"
+msgstr "Pedir Super-comentário"
+
+#: views/editors/review.thtml:158
+msgid "editors_review_action_sandbox"
+msgstr "Manter no Sandbox"
+
+#: controllers/editors_controller.php:346
+msgid "editors_review_comments"
+msgstr "Comentários da avaliação"
+
+#: views/editors/review.thtml:182
+msgid "editors_review_details_info_request"
+msgstr ""
+"Utilize este formulário para pedir mais informação ao autor. Ele receberá "
+"uma mensagem de correio electrónico e poderá responder aqui.Quando "
+"responderem será notificado por correio electrónico."
+
+#: views/editors/review.thtml:174
+msgid "editors_review_details_nominated_public"
+msgstr ""
+"Isto irá marcar o extra e a sua versão e ficheiros mais recentes como "
+"pública. Versões futuras irão para o sandbox até serem revistas por um "
+"editor."
+
+#: views/editors/review.thtml:177
+msgid "editors_review_details_nominated_sandbox"
+msgstr "Isto irá manter o extra no sandbox."
+
+#: views/editors/review.thtml:166
+msgid "editors_review_details_pending_public"
+msgstr ""
+"Isto irá aprovar uma versão que está no sandbox de uma versão de um extra "
+"público a aparecer no lado público."
+
+#: views/editors/review.thtml:169
+msgid "editors_review_details_pending_sandbox"
+msgstr ""
+"Isto irá causar que uma versão que está no sandbox de uma versão pública de "
+"um extra seja mantida no sandbox."
+
+#: views/editors/review.thtml:185
+msgid "editors_review_details_superreview"
+msgstr ""
+"Se tiver dúvidas sobre a segurança deste extra, problemas de copyright, ou "
+"outras dúvidas que um administrador deverá ver, escreva os seus comentários "
+"na área abaixo. Serão enviadas aos administradores, mas não ao autor."
+
+#: views/editors/review.thtml:134
+msgid "editors_review_file_diff_link"
+msgstr "Comparar com a versão pública"
+
+#: views/editors/review.thtml:131
+msgid "editors_review_file_viewcontents_link"
+msgstr "Ver Conteúdo"
+
+#: views/editors/review.thtml:65
+msgid "editors_review_header_authors"
+msgstr "Autores:"
+
+#: views/editors/review.thtml:79
+msgid "editors_review_header_categories"
+msgstr "Categorias:"
+
+#: views/editors/review.thtml:92
+msgid "editors_review_header_compatibility"
+msgstr "Compatibilidade:"
+
+#: views/editors/review.thtml:251
+msgid "editors_review_header_description"
+msgstr "Descrição"
+
+#: views/editors/review.thtml:275
+msgid "editors_review_header_devcomments"
+msgstr "Comentários do Developer"
+
+#: views/editors/review.thtml:263
+msgid "editors_review_header_eula"
+msgstr "ALUF"
+
+#: views/editors/review.thtml:115
+msgid "editors_review_header_files"
+msgstr "Ficheiros:"
+
+#: views/editors/review.thtml:284
+msgid "editors_review_header_itemhistory"
+msgstr "Histórico do Item"
+
+#: views/editors/review.thtml:232
+msgid "editors_review_header_nominationmessage"
+msgstr "Mensagem de Nomeação"
+
+#: views/editors/review.thtml:311
+msgid "editors_review_header_previews"
+msgstr "Pré-visualizações"
+
+#: views/editors/review.thtml:269
+msgid "editors_review_header_privacy"
+msgstr "Política de Privacidade"
+
+#. %1 is the add-on name and version
+#: views/editors/review.thtml:56
+#, php-format
+msgid "editors_review_header_review"
+msgstr "Avaliar %s"
+
+#: views/editors/review.thtml:239
+msgid "editors_review_header_reviewernotes"
+msgstr "Notas para o avaliador"
+
+#: views/editors/review.thtml:245
+msgid "editors_review_header_summary"
+msgstr "Sumário"
+
+#: views/editors/review.thtml:257
+msgid "editors_review_header_versionnotes"
+msgstr "Notas da Versão"
+
+#. a noun: shown in an add-on's editor review history
+#: views/elements/developers/editors_review_history_item.thtml:80
+msgid "editors_review_history_info_reply"
+msgstr "Responder"
+
+#: views/elements/developers/editors_review_history_item.thtml:78
+msgid "editors_review_history_info_request"
+msgstr "Pedido de informação"
+
+#: views/elements/developers/editors_review_history_item.thtml:62
+#: views/editors/reviewlog.thtml:77
+msgid "editors_review_history_nominated_adminreview"
+msgstr "Comentário do Admin"
+
+#: views/elements/developers/editors_review_history_item.thtml:56
+#: views/editors/reviewlog.thtml:71
+msgid "editors_review_history_nominated_approved"
+msgstr "Nomeação Aprovada/Pública"
+
+#: views/elements/developers/editors_review_history_item.thtml:59
+#: views/editors/reviewlog.thtml:74
+msgid "editors_review_history_nominated_denied"
+msgstr "Nomeação Negada/Sandbox"
+
+#: views/editors/review.thtml:303
+msgid "editors_review_history_nonefound"
+msgstr "Não foi encontrada nenhum comentário anterior."
+
+#: views/elements/developers/editors_review_history_item.thtml:73
+#: views/editors/reviewlog.thtml:88
+msgid "editors_review_history_pending_adminreview"
+msgstr "Comentário do Admin"
+
+#: views/elements/developers/editors_review_history_item.thtml:67
+#: views/editors/reviewlog.thtml:82
+msgid "editors_review_history_pending_approved"
+msgstr "Aprovado/Público"
+
+#: views/elements/developers/editors_review_history_item.thtml:70
+#: views/editors/reviewlog.thtml:85
+msgid "editors_review_history_pending_denied"
+msgstr "Negado/Sandbox"
+
+#. link text in an add-on's editor review history, allowing to hide and show an information request's replies
+#. %1 is the number of replies
+#: views/elements/developers/editors_review_history_item.thtml:90
+msgid "editors_review_history_show_hide_replies"
+msgid_plural "editors_review_history_show_hide_replies"
+msgstr[0] "Mostrar/Ocultar respostas (%1$s)"
+msgstr[1] "Mostrar/Ocultar respostas (%1$s)"
+
+#: views/editors/review.thtml:208
+msgid "editors_review_label_applications"
+msgstr "Aplicações:"
+
+#: views/editors/review.thtml:196
+msgid "editors_review_label_cannedresponse"
+msgstr "ou seleccione uma resposta:"
+
+#: views/editors/review.thtml:190
+msgid "editors_review_label_comments"
+msgstr "Comentários:"
+
+#: views/editors/review.thtml:204
+msgid "editors_review_label_operating_systems"
+msgstr "Sistemas Operativos:"
+
+#: views/editors/review.thtml:285 views/editors/review.thtml:312
+msgid "editors_review_link_pagetop"
+msgstr "Topo"
+
+#: views/editors/review.thtml:141
+msgid "editors_review_mulitple_notice"
+msgstr ""
+"Nota: Reveja mais do que um ficheiro apenas se testou TODOS os ficheiros "
+"que seleccionou."
+
+#: views/editors/review.thtml:51
+msgid "editors_review_next_link"
+msgstr "segu &raquo;"
+
+#: views/editors/review.thtml:322
+msgid "editors_review_previews_notfound"
+msgstr "Nenhuma pré-visualização encontrada."
+
+#: views/editors/review.thtml:50
+msgid "editors_review_previous_link"
+msgstr "&laquo; ante"
+
+#: controllers/editors_controller.php:144
+#: controllers/editors_controller.php:146
+msgid "editors_review_queue_pagetitle"
+msgstr "Comentário em espera"
+
+#. %1 is the add-ons rank in the queue, %2 is the total queue length
+#: views/editors/review.thtml:47
+msgid "editors_review_rank_in_queue"
+msgstr "<strong># %1$s</strong> de %2$s em espera"
+
+#. %1 is the add-ons rank in the queue, %2 is the total queue length. Both numbers
+#: views/editors/review.thtml:45
+msgid "editors_review_rank_in_queue_filtered"
+msgstr "<strong># %1$s</strong> de %2$s em espera (filtrado)"
+
+#: views/editors/review.thtml:223
+msgid "editors_review_submit_process_action"
+msgstr "Acção do Processo"
+
+#: views/editors/review.thtml:293
+msgid "editors_review_th_action"
+msgstr "Acção"
+
+#: views/editors/review.thtml:294
+msgid "editors_review_th_comments"
+msgstr "Comentários"
+
+#: views/editors/review.thtml:291
+msgid "editors_review_th_date"
+msgstr "Data"
+
+#: views/editors/review.thtml:292
+msgid "editors_review_th_reviewer"
+msgstr "Revisor"
+
+#: views/editors/review.thtml:290
+msgid "editors_review_th_version_file"
+msgstr "Versão/Ficheiro"
+
+#: views/editors/review.thtml:217
+msgid "editors_review_update_notify_once"
+msgstr ""
+"Notificar-me da próxima vez que o extra for actualizado. (As actualizações "
+"seguintes não irõ gerar uma mensagem de correio)"
+
+#: controllers/editors_controller.php:298
+msgid "editors_reviewed_successfully"
+msgstr "Comentário processado com sucesso."
+
+#: views/editors/reviews_queue.thtml:106
+msgid "editors_reviews_action_delete_review"
+msgstr "Eliminar comentário"
+
+#: views/editors/reviews_queue.thtml:104
+msgid "editors_reviews_action_keep"
+msgstr "Remover etiquetas; manter comentário"
+
+#: views/editors/reviews_queue.thtml:102
+msgid "editors_reviews_action_skip"
+msgstr "Saltar"
+
+#: views/editors/reviews_queue.thtml:100
+msgid "editors_reviews_header_action"
+msgstr "Acção"
+
+#: views/editors/reviews_queue.thtml:67
+msgid "editors_reviews_in_reply_to"
+msgstr "Em resposta a:"
+
+#: controllers/editors_controller.php:748
+msgid "editors_reviews_processed"
+msgstr "Comentários processados com sucesso!"
+
+#: views/editors/reviews_queue.thtml:117
+msgid "editors_reviews_queue_empty"
+msgstr "De momento não existem comentários para serem moderados."
+
+#: views/editors/reviews_queue.thtml:111
+msgid "editors_reviews_submit_process_reviews"
+msgstr "Processo de comnetários"
+
+#: controllers/editors_controller.php:691
+msgid "editors_site_specific"
+msgstr "Específico de um Sítio"
+
+#: controllers/editors_controller.php:348
+msgid "editors_tested_app"
+msgstr "Aplicação Testada"
+
+#: controllers/editors_controller.php:347
+msgid "editors_tested_os"
+msgstr "Sistemas Operativos Testados"
+
+#: views/editors/queue.thtml:151
+msgid "editors_th_additional_info"
+msgstr "Informação Adicional"
+
+#: views/editors/featured.thtml:63 views/editors/queue.thtml:109
+#: views/admin/flagged_queue.thtml:53
+msgid "editors_th_addon"
+msgstr "Extra"
+
+#: views/editors/queue.thtml:125
+msgid "editors_th_addontype"
+msgstr "Tipo"
+
+#: views/editors/featured.thtml:64
+msgid "editors_th_locales"
+msgstr "Restringir para os locales?"
+
+#: views/editors/queue.thtml:148
+msgid "editors_th_nomination_age"
+msgstr "Tempo de espera"
+
+#: views/editors/queue.thtml:101 views/editors/queue.thtml:117
+#: views/editors/queue.thtml:144
+msgid "editors_th_sort_ascending"
+msgstr "Ordem ascendente"
+
+#: views/editors/queue.thtml:105 views/editors/queue.thtml:121
+#: views/editors/queue.thtml:140
+msgid "editors_th_sort_descending"
+msgstr "Ordem descendente"
+
+#. %s is a number
+#: controllers/editors_controller.php:1036
+#, php-format
+msgid "editors_x_days"
+msgstr "%s dias"
+
+#. %s is a number
+#: controllers/editors_controller.php:1044
+#, php-format
+msgid "editors_x_hours"
+msgstr "%s horas"
+
+#. %s is a number
+#: controllers/editors_controller.php:1052
+#, php-format
+msgid "editors_x_minutes"
+msgstr "%s minutos"
+
+#: views/errors/error401.thtml:50 controllers/components/simple_acl.php:81
+#: controllers/components/simple_acl.php:82
+#: controllers/components/simple_acl.php:83 controllers/components/amo.php:607
+#: controllers/components/amo.php:608 controllers/components/amo.php:609
+#: controllers/reviews_controller.php:353
+#: controllers/reviews_controller.php:485
+#: controllers/collections_controller.php:438
+#: controllers/collections_controller.php:496
+#: controllers/collections_controller.php:504
+#: controllers/collections_controller.php:971
+#: controllers/collections_controller.php:1034
+#: controllers/collections_controller.php:1077
+msgid "error_access_denied"
+msgstr "Acesso Negado"
+
+#: views/errors/error401.thtml:52
+msgid "error_access_denied_message"
+msgstr "Não está autorizado a ver esta página."
+
+#: controllers/collections_controller.php:1039
+msgid "error_addon_exists"
+msgstr "O extra já existe!"
+
+#: controllers/developers_controller.php:200
+#: controllers/developers_controller.php:593
+#: controllers/developers_controller.php:1016
+#: controllers/developers_controller.php:1429
+#: controllers/downloads_controller.php:95
+#: controllers/downloads_controller.php:102
+#: controllers/downloads_controller.php:164
+#: controllers/statistics_controller.php:135
+#: controllers/previews_controller.php:115
+#: controllers/previews_controller.php:206
+#: controllers/previews_controller.php:307
+#: controllers/reviews_controller.php:77
+#: controllers/reviews_controller.php:240
+#: controllers/reviews_controller.php:332
+#: controllers/reviews_controller.php:340 controllers/api_controller.php:123
+#: controllers/api_controller.php:759 controllers/addons_controller.php:131
+#: controllers/addons_controller.php:197
+#: controllers/addons_controller.php:1407
+#: controllers/addons_controller.php:1465
+#: controllers/addons_controller.php:1469
+#: controllers/addons_controller.php:1503
+#: controllers/editors_controller.php:265
+#: controllers/collections_controller.php:1041
+#: controllers/collections_controller.php:1074
+msgid "error_addon_notfound"
+msgstr "Extra não encontrado!"
+
+#: controllers/files_controller.php:83 controllers/files_controller.php:196
+msgid "error_addon_notviewable"
+msgstr "Este extra não é visível aqui."
+
+#: controllers/reviews_controller.php:246
+msgid "error_addon_selfreview"
+msgstr "Não pode rever o seu próprio extra."
+
+#: controllers/addons_controller.php:970
+msgid "error_browse_no_addons"
+msgstr "Nenhum Extra nesta categoria!"
+
+#: controllers/api_controller.php:424
+msgid "error_collection_feed_notfound"
+msgstr " "
+
+#: views/users/register.thtml:65 views/users/edit.thtml:194
+msgid "error_email_invalid"
+msgstr "Não é um endereço de correio electrónico válido."
+
+#: views/users/pwreset.thtml:74 views/users/register.thtml:70
+#: views/users/register.thtml:80 views/users/register.thtml:86
+#: views/users/edit.thtml:105 views/users/edit.thtml:111
+#: views/users/edit.thtml:192 views/admin/users_edit.thtml:78
+#: views/admin/users_edit.thtml:83 views/reviews/add.thtml:80
+#: views/reviews/add.thtml:104
+msgid "error_field_required"
+msgstr "Este campo não pode estar vazio."
+
+#: controllers/files_controller.php:75 controllers/files_controller.php:93
+#: controllers/files_controller.php:96 controllers/files_controller.php:163
+#: controllers/files_controller.php:176 controllers/files_controller.php:185
+#: controllers/files_controller.php:204 controllers/editors_controller.php:412
+msgid "error_file_notfound"
+msgstr "Ficheiro não encontrado!"
+
+#. %s is a filename
+#: controllers/editors_controller.php:430
+#, php-format
+msgid "error_file_x_notfound"
+msgstr "Erro no ficheiro: %s não existe."
+
+#: views/collections/add.thtml:55 views/collections/edit.thtml:89
+#: views/users/register.thtml:54 views/users/edit.thtml:81
+#: views/reviews/add.thtml:70 controllers/groups_controller.php:80
+#: controllers/groups_controller.php:102
+msgid "error_formerrors"
+msgstr "Existem erros neste formulário. Corriga-os e volte a submete-los."
+
+#: views/users/register.thtml:109
+msgid "error_invalid_captcha"
+msgstr "Captcha inválido, tente novamente!"
+
+#: views/users/register.thtml:100 views/users/edit.thtml:125
+#: views/admin/users_edit.thtml:101
+msgid "error_invalid_url"
+msgstr ""
+"Este URL tem um formato inválido. URLs válidos são do tipo http://example."
+"com/my_page."
+
+#. %s is a string representing what's missing. Example: file_id
+#: controllers/downloads_controller.php:65
+#: controllers/users_controller.php:185 controllers/users_controller.php:264
+#: controllers/users_controller.php:559 controllers/users_controller.php:653
+#: controllers/reviews_controller.php:71
+#: controllers/reviews_controller.php:234
+#: controllers/reviews_controller.php:325
+#: controllers/reviews_controller.php:473
+#: controllers/reviews_controller.php:475
+#: controllers/addons_controller.php:182
+#: controllers/addons_controller.php:1381
+#: controllers/addons_controller.php:1455
+#: controllers/collections_controller.php:266
+#: controllers/collections_controller.php:285
+#: controllers/collections_controller.php:346
+#: controllers/collections_controller.php:443
+#: controllers/collections_controller.php:482
+#: controllers/collections_controller.php:936
+#: controllers/collections_controller.php:959
+#: controllers/collections_controller.php:960
+#: controllers/collections_controller.php:975
+#: controllers/collections_controller.php:977
+#: controllers/collections_controller.php:994
+#: controllers/collections_controller.php:1003
+#: controllers/collections_controller.php:1016
+#: controllers/collections_controller.php:1017
+#: controllers/collections_controller.php:1024
+#: controllers/collections_controller.php:1070
+#: controllers/collections_controller.php:1090
+#, php-format
+msgid "error_missing_argument"
+msgstr "Argumento em falta: %s"
+
+#: controllers/components/amo.php:507 controllers/components/amo.php:532
+msgid "error_no_files_in_addon"
+msgstr "Sem ficheiros"
+
+#: controllers/previews_controller.php:200
+msgid "error_preview_notfound"
+msgstr "Pré-visualização não encontrada!"
+
+#: views/addons/display.thtml:400 views/reviews/add.thtml:98
+msgid "error_review_rating_required"
+msgstr "Tem de seleccionar uma avaliação"
+
+#: controllers/users_controller.php:160
+msgid "error_user_already_confirmed"
+msgstr "Esta conta de utilizador já está confirmada."
+
+#: controllers/users_controller.php:202 controllers/users_controller.php:276
+#: controllers/users_controller.php:569 controllers/users_controller.php:581
+#: controllers/users_controller.php:587 controllers/users_controller.php:610
+#: controllers/users_controller.php:627
+msgid "error_user_badconfirmationcode"
+msgstr "Código de confirmação inválido!"
+
+#: views/users/pwreset.thtml:79 views/users/register.thtml:75
+#: views/users/edit.thtml:183
+msgid "error_user_confirmpw_nomatch"
+msgstr "As senhas não coincidem."
+
+#: views/users/register.thtml:65 views/users/edit.thtml:190
+#: controllers/users_controller.php:617
+msgid "error_user_email_notunique"
+msgstr "Este endereço de correio já existe."
+
+#: controllers/users_controller.php:596
+msgid "error_user_emailchange_expired"
+msgstr ""
+"A alteração do correio electrónico expirou. Por favor altere o seu endereço "
+"de correio electrónico de novo no seu perfil de utilizador e clique na "
+"ligação que aparece no correio electrónico de confirmaçãoque irá receber "
+"dentro de instantes."
+
+#: controllers/collections_controller.php:985
+msgid "error_user_exists"
+msgstr ""
+"Os utilizadores apenas podem ter um papel de cada vez. Remova o utilizador "
+"de todos os papéis existentes antes de continuar."
+
+#: views/users/register.thtml:91 views/users/edit.thtml:116
+#: views/admin/users_edit.thtml:88
+msgid "error_user_nickname_notunique"
+msgstr "Esta alcunha já existe."
+
+#: views/users/pwreset.thtml:54 controllers/users_controller.php:191
+#: controllers/users_controller.php:270 controllers/users_controller.php:603
+#: controllers/users_controller.php:659
+#: controllers/collections_controller.php:988
+#: controllers/collections_controller.php:998
+msgid "error_user_notfound"
+msgstr "Utilizador não encontrado!"
+
+#: views/users/activatefirst.thtml:47
+msgid "error_user_unconfirmed"
+msgstr ""
+"Confirme primeiro a sua conta com o código que recebeu por correio "
+"electrónico."
+
+#: views/users/login.thtml:67
+msgid "error_username_or_pw_wrong"
+msgstr "Nome de utilizador ou senha errados!"
+
+#: controllers/editors_controller.php:260
+msgid "error_version_notfound"
+msgstr "Versão não encontrada!"
+
+#: views/users/delete.thtml:125 views/users/edit.thtml:173
+msgid "error_wrong_password"
+msgstr "Senha errada introduzida!"
+
+#: views/elements/amo2009/homepage_addon.thtml:122
+#: views/elements/feature.thtml:122
+msgid "feature_learnmore"
+msgstr "Saber mais"
+
+#. %1 is the add-on name
+#: views/elements/amo2009/homepage_addon.thtml:123
+#: views/elements/feature.thtml:123
+#, php-format
+msgid "feature_learnmore_about_addon"
+msgstr "Saber mais sobre %1$s"
+
+#. %1$s is a number
+#: views/elements/amo2009/reviews.thtml:52
+#: views/elements/addon_listitem.thtml:112 views/elements/feature.thtml:99
+#: views/addons/browse_thumbs.thtml:86
+#, php-format
+msgid "feature_reviews"
+msgid_plural "feature_reviews"
+msgstr[0] "%1$s comentário"
+msgstr[1] "%1$s comentários"
+
+#: views/elements/amo2009/homepage_addon.thtml:127
+#: views/elements/feature.thtml:127
+msgid "feature_view_more_from_category"
+msgstr "Ver mais de"
+
+#. This appears on a page that views the source of an add-on. This link will return
+#. the user to the add-on's main page
+#: views/files/browse.thtml:65
+msgid "file_browser_link_addon"
+msgstr "Voltar ao extra"
+
+#. There is a list of directories and files on the page. Clicking this will show the
+#. contents of all the directories (normally you would click on each one to see the
+#. contents)
+#: views/files/browse.thtml:67
+msgid "file_browser_link_expand_all"
+msgstr "Expandir tudo"
+
+#. This appears on a page that views the source of an add-on. This link will return
+#. the user to the add-on's review page (it only appears if the add-on is being
+#. reviewed)
+#: views/files/browse.thtml:64
+msgid "file_browser_link_review"
+msgstr "Retroceder para o comentário"
+
+#. The title of the page for viewing an add-on's source.
+#. %1$s is the name of the add-on
+#. %2$s is the name of the current application (e.g. Firefox or Thunderbird)
+#: views/files/browse.thtml:46
+msgid "file_browser_title"
+msgstr "%1$s :: Explorador de ficheiro :: %2$s Extras"
+
+#. This appears on a page that views the source of an add-on. There is a list of
+#. directories and files on the page. Clicking this link will toggle between an
+#. expanded or a collapsed list. This string should be kept short.
+#: views/files/browse.thtml:68
+msgid "file_browser_toggle_expand_collapse"
+msgstr "+/-"
+
+#. Link text for the AMO About page.
+#: views/elements/footer.thtml:72 views/layouts/amo2009.thtml:341
+msgid "footer_a_about"
+msgstr "Sobre"
+
+#. Link text to the AMO blog.
+#: views/elements/footer.thtml:74 views/layouts/amo2009.thtml:343
+msgid "footer_a_blog"
+msgstr "Blog"
+
+#. Link text to the Frequently Asked Questions page.
+#: views/elements/footer.thtml:73 views/layouts/amo2009.thtml:342
+msgid "footer_a_faq"
+msgstr "FAQ"
+
+#. Full text for the FAQ abbreviation.
+#: views/elements/footer.thtml:73 views/pages/collector_features.thtml:72
+#: views/layouts/amo2009.thtml:342
+msgid "footer_abbr_faq"
+msgstr "Perguntas frequentes"
+
+#: views/elements/footer.thtml:67 views/layouts/amo2009.thtml:336
+msgid "footer_all_rights_reserved"
+msgstr "Todos os direitos reservados."
+
+#: views/elements/footer.thtml:67 views/layouts/amo2009.thtml:336
+msgid "footer_copyright"
+msgstr "Copyright"
+
+#: views/elements/footer.thtml:71 views/layouts/amo2009.thtml:340
+msgid "footer_credits"
+msgstr "Créditos"
+
+#: views/elements/footer.thtml:76 views/layouts/amo2009.thtml:346
+msgid "footer_disclaimer"
+msgstr ""
+"A Mozilla está a fornecer, por cortesia, ligações para estas aplicações, e "
+"não faz nenhuma representação relativamente a essas aplicações ou qualquer "
+"informação aí indicada. Quaisquer questões, queixas ou outro sobre esta "
+"aplicação têm de ser direccionadas ao fabricante do software apropriado."
+
+#: views/elements/footer.thtml:61 views/layouts/amo2009.thtml:332
+msgid "footer_lang_form_lang_submit_go"
+msgstr "Ir"
+
+#: views/elements/footer.thtml:70 views/layouts/amo2009.thtml:339
+msgid "footer_legal_notices"
+msgstr "Informações Legais"
+
+#: views/elements/footer.thtml:50 views/layouts/amo2009.thtml:321
+msgid "footer_other_languages"
+msgstr "Outros Idiomas:"
+
+#: views/elements/footer.thtml:69 views/layouts/amo2009.thtml:338
+msgid "footer_privacy_policy"
+msgstr "Política de privacidade"
+
+#: models/addontype.php:79
+msgid "general_addontype_dict"
+msgstr "Dicionário"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:100
+msgid "general_addontype_dict_plural"
+msgstr "Dicionários"
+
+#: models/addontype.php:75
+msgid "general_addontype_extension"
+msgstr "Extensão"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:98
+msgid "general_addontype_extension_plural"
+msgstr "Extensões"
+
+#: models/addontype.php:85
+msgid "general_addontype_lpaddon"
+msgstr "Pacote de Idioma (Extra)"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:103
+msgid "general_addontype_lpaddon_plural"
+msgstr "Pacotes de Idioma (Extras)"
+
+#: models/addontype.php:83
+msgid "general_addontype_lpapp"
+msgstr "Pacote de Idioma (Aplicação)"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:102
+msgid "general_addontype_lpapp_plural"
+msgstr "Pacotes de Idioma (Aplicações)"
+
+#: models/addontype.php:87
+msgid "general_addontype_plugin"
+msgstr "Plugin"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:104
+msgid "general_addontype_plugin_plural"
+msgstr "Plugins"
+
+#: models/addontype.php:81
+msgid "general_addontype_search"
+msgstr "Motor de Pesquisa"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:101
+msgid "general_addontype_search_plural"
+msgstr "Motores de Pesquisa"
+
+#: models/addontype.php:77
+msgid "general_addontype_theme"
+msgstr "Tema"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:99
+msgid "general_addontype_theme_plural"
+msgstr "Temas"
+
+#: config/language.php:367
+msgid "general_languages_all_locales"
+msgstr "Todos os idiomas"
+
+#: views/layouts/amo2009.thtml:249
+msgid "header_brand_name"
+msgstr "Mozilla"
+
+#. %1$s is the application name. Example: Firefox
+#: views/elements/header.thtml:111 views/elements/header.thtml:122
+#: views/layouts/amo2009.thtml:248
+#, php-format
+msgid "header_home_tooltip"
+msgstr "Voltar à página inicial dos extras do %1$s"
+
+#: views/elements/header.thtml:87
+msgid "header_main_firefox_header"
+msgstr "Extras do Firefox"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:218
+#, fuzzy
+msgid "header_main_firefox_header_with_logo"
+msgstr ""
+"Add-ons <em>for</em> <img alt=\"Firefox\" src=\"%1$s\" /> <strong>Firefox</"
+"strong>"
+
+#: views/elements/header.thtml:99
+msgid "header_main_header"
+msgstr "Extras"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:242
+#, fuzzy
+msgid "header_main_header_with_logo"
+msgstr "Add-ons <img alt=\"Add-ons\" src=\"%1$s\" />"
+
+#: views/elements/header.thtml:90
+msgid "header_main_seamonkey_header"
+msgstr "Extras do Seamonkey"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:224
+#, fuzzy
+msgid "header_main_seamonkey_header_with_logo"
+msgstr ""
+"Add-ons <em>for</em> <img alt=\"seamonkey\" src=\"%1$s\" /> "
+"<strong>SeaMonkey</strong>"
+
+#: views/elements/header.thtml:93
+msgid "header_main_sunbird_header"
+msgstr "Extras do Sunbird"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:230
+#, fuzzy
+msgid "header_main_sunbird_header_with_logo"
+msgstr ""
+"Add-ons <em>for</em> <img alt=\"sunbird\" src=\"%1$s\" /> <strong>Sunbird</"
+"strong>"
+
+#: views/elements/header.thtml:96
+msgid "header_main_thunderbird_header"
+msgstr "Extras do Thunderbird"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:236
+#, fuzzy
+msgid "header_main_thunderbird_header_with_logo"
+msgstr ""
+"Add-ons <em>for</em> <img alt=\"thunderbird\" src=\"%1$s\" /> "
+"<strong>Thunderbird</strong>"
+
+#: views/layouts/amo2009.thtml:205
+msgid "header_navaccess_applications_menu"
+msgstr "Saltar para o menu de outras aplicações"
+
+#: views/layouts/amo2009.thtml:204
+msgid "header_navaccess_categories_menu"
+msgstr "Saltar para o menu de categorias"
+
+#: views/layouts/amo2009.thtml:202
+msgid "header_navaccess_main_content"
+msgstr "Saltar para o conteúdo principal"
+
+#: views/layouts/amo2009.thtml:203
+msgid "header_navaccess_search_form"
+msgstr "Saltar para o formulário de pesquisa"
+
+#: views/elements/header.thtml:62
+msgid "header_navlink_addons"
+msgstr "Extras"
+
+#: views/elements/developers/sidebar.thtml:72
+#: views/elements/developers/myaddons.thtml:50 views/elements/header.thtml:159
+#: views/addons/display.thtml:378
+msgid "header_navlink_login"
+msgstr "Entrar"
+
+#: views/elements/header.thtml:156 views/layouts/amo2009.thtml:304
+msgid "header_navlink_logout"
+msgstr "Sair"
+
+#: views/elements/header.thtml:145 views/layouts/amo2009.thtml:303
+msgid "header_navlink_myaccount"
+msgstr "A Minha Conta"
+
+#: views/elements/header.thtml:158
+msgid "header_navlink_register"
+msgstr "Registar"
+
+#. %1 is the URL to the registration page
+#. %2 is the URL to the login page
+#: views/layouts/amo2009.thtml:278
+msgid "header_navlink_register_or_login"
+msgstr "<a href=\"%1$s\">Registe-se</a> ou <a href=\"%2$s\">Inicie sessão</a>"
+
+#: views/layouts/amo2009.thtml:285
+msgid "header_navlink_tools"
+msgstr "Ferramentas"
+
+#. %s is the add-on name
+#: views/elements/collections_interactive_addon.thtml:62
+#: views/elements/amo2009/homepage_addon.thtml:77
+#: views/elements/addon_discussionheader.thtml:62
+#: views/elements/addon_listitem.thtml:67 views/elements/feature.thtml:84
+#: views/addons/category_landing.thtml:87 views/addons/browse_thumbs.thtml:60
+#, php-format
+msgid "img_preview_of"
+msgstr "Pré-visualizar imagem do %s"
+
+#. %1 is the login URL for the link tag
+#. %2 is the link to an explanatory page.
+#: views/elements/amo2009/install.thtml:307 views/elements/install.thtml:255
+msgid "install_a_login_to_install"
+msgstr ""
+"<a href=\"%1$s\">Entrar</a> para instalar este extra experimental. <a href="
+"\"%2$s\">Porquê</a>?"
+
+#. %1 is the URL for the Experimental Add-ons section of the FAQ page
+#: views/elements/amo2009/install.thtml:283 views/elements/install.thtml:232
+msgid "install_button_confirm_exp_install"
+msgstr ""
+"Deixem-me instalar este extra experimental. <a href=\"%1$s\">O que é isto?</"
+"a>"
+
+#. %1$s is the application name. Example: Firefox
+#. %2$s is an optional string used to specify a platform. Example: (Windows)
+#: views/elements/amo2009/install.thtml:128 views/elements/install.thtml:75
+#, php-format
+msgid "install_button_text"
+msgstr "Adicionar ao %s %s"
+
+#. %1 is the add-on name, %2 is the app name
+#: views/elements/amo2009/install.thtml:191
+#: views/elements/amo2009/install.thtml:206
+#: views/elements/amo2009/install.thtml:249
+#: views/elements/amo2009/install.thtml:298 views/elements/install.thtml:150
+#: views/elements/install.thtml:165 views/elements/install.thtml:202
+#: views/elements/install.thtml:246
+#, php-format
+msgid "install_button_title"
+msgstr "Adicionar %1$s a %2$s"
+
+#. %1$s is the add-on name
+#: views/elements/amo2009/install.thtml:200 views/elements/install.thtml:159
+#, php-format
+msgid "install_download"
+msgstr "Transferir %1$s"
+
+#: views/elements/amo2009/install.thtml:147 views/elements/install.thtml:94
+msgid "install_error_addon_not_found"
+msgstr "Este extra não está disponível."
+
+#: views/addons/dictionaries.thtml:65
+msgid "langtools_a11y_tablesummary"
+msgstr "Lista de pacotes de idioma e dicionários"
+
+#: views/addons/dictionaries.thtml:47
+msgid "langtools_download_dictionary"
+msgstr "Transferir Dicionário"
+
+#: views/addons/dictionaries.thtml:48
+msgid "langtools_download_langpack"
+msgstr "Transferir Pacote de Idioma"
+
+#: views/addons/dictionaries.thtml:63 controllers/components/amo.php:685
+#: controllers/addons_controller.php:1239
+msgid "langtools_header_dicts_and_langpacks"
+msgstr "Dicionários & Pacotes de Idioma"
+
+#: views/addons/dictionaries.thtml:44
+msgid "langtools_install_dictionary"
+msgstr "Instalar Dicionário"
+
+#: views/addons/dictionaries.thtml:45
+msgid "langtools_install_langpack"
+msgstr "Instalar Pacote de Idioma"
+
+#: views/addons/dictionaries.thtml:69
+msgid "langtools_tableheader_dictionary"
+msgstr "Dicionário"
+
+#: views/addons/dictionaries.thtml:70
+msgid "langtools_tableheader_langpack"
+msgstr "Pacote de Idioma"
+
+#: views/addons/dictionaries.thtml:68
+msgid "langtools_tableheader_language"
+msgstr "Idioma"
+
+#: models/license.php:65
+msgid "license_custom"
+msgstr "Licença personalizada"
+
+#: config/bootstrap.php:303
+msgid "licenses_bsd"
+msgstr "Licença BSD"
+
+#: config/bootstrap.php:298
+msgid "licenses_gpl_2.0"
+msgstr "GNU General Public License, versão 2.0"
+
+#: config/bootstrap.php:299
+msgid "licenses_gpl_3.0"
+msgstr "GNU General Public License, versão 3.0"
+
+#: config/bootstrap.php:300
+msgid "licenses_lgpl_2.1"
+msgstr "GNU Lesser General Public License, versão 2.1"
+
+#: config/bootstrap.php:301
+msgid "licenses_lgpl_3.0"
+msgstr "GNU Lesser General Public License, versão 3.0"
+
+#: config/bootstrap.php:302
+msgid "licenses_mit"
+msgstr "Licença MIT/X11"
+
+#: config/bootstrap.php:297
+msgid "licenses_mpl_1.1"
+msgstr "Mozilla Public License, versão 1.1"
+
+#: views/users/emailchange.thtml:51 views/users/delete.thtml:55
+#: views/users/delete.thtml:137 views/users/edit.thtml:74
+#: views/reviews/flag.thtml:54
+msgid "link_return_to_front_page"
+msgstr "Clique aqui para voltar à página inicial."
+
+#: views/elements/amo2009/addon_list_options.thtml:46
+#: views/elements/addon_list_options.thtml:46
+msgid "list_sortby_date"
+msgstr "Data"
+
+#: views/elements/amo2009/addon_list_options.thtml:47
+#: views/elements/addon_list_options.thtml:47
+msgid "list_sortby_downloads"
+msgstr "Transferências"
+
+#: views/elements/amo2009/addon_list_options.thtml:45
+#: views/elements/addon_list_options.thtml:45
+msgid "list_sortby_name"
+msgstr "Nome"
+
+#: views/elements/amo2009/addon_list_options.thtml:48
+#: views/elements/addon_list_options.thtml:48
+msgid "list_sortby_rating"
+msgstr "Avaliação"
+
+#: config/bootstrap.php:278
+msgid "main_prettyname_fennec"
+msgstr "Fennec "
+
+#: config/bootstrap.php:274
+msgid "main_prettyname_firefox"
+msgstr "Firefox"
+
+#: config/bootstrap.php:277
+msgid "main_prettyname_seamonkey"
+msgstr "SeaMonkey"
+
+#: config/bootstrap.php:276
+msgid "main_prettyname_sunbird"
+msgstr "Sunbird"
+
+#: config/bootstrap.php:275
+msgid "main_prettyname_thunderbird"
+msgstr "Thunderbird"
+
+#: views/elements/addon_categories.thtml:52
+msgid "nav_category_dicts_langpacks"
+msgstr "Dicionários e Pacotes de Idiomas"
+
+#: views/elements/addon_categories.thtml:55
+msgid "nav_category_themes"
+msgstr "Temas"
+
+#: views/elements/app_chooser.thtml:47 views/layouts/amo2009.thtml:255
+msgid "other_apps_tooltip"
+msgstr "Procure extras para outras aplicações"
+
+#. In a user list: user 1, user 2, "others"
+#: views/helpers/addons_html.php:222
+msgid "other_users"
+msgstr "outros"
+
+#: controllers/pages_controller.php:90
+msgid "page_title_appversions"
+msgstr "Versões da aplicação"
+
+#: controllers/pages_controller.php:115
+msgid "page_title_collector"
+msgstr "Coleccionador de extras"
+
+#: controllers/pages_controller.php:117
+msgid "page_title_collector_faq"
+msgstr "Perguntas frequentes do coleccionador de extras"
+
+#: controllers/pages_controller.php:119
+msgid "page_title_collector_features"
+msgstr "Funcionalidades do coleccionador de extras"
+
+#: controllers/pages_controller.php:122
+#, fuzzy
+msgid "page_title_collector_firstrun"
+msgstr "Welcome to the Add-on Collector"
+
+#: controllers/pages_controller.php:92
+msgid "page_title_credits"
+msgstr "Créditos"
+
+#: controllers/pages_controller.php:113
+msgid "page_title_developer_faq"
+msgstr "FAQ do Desenvolvedor"
+
+#: controllers/pages_controller.php:111
+msgid "page_title_faq"
+msgstr "Perguntas frequentes"
+
+#: controllers/pages_controller.php:94
+msgid "page_title_fashionyourfirefox_faq"
+msgstr "FAQ personalize o seu Firefox "
+
+#: controllers/pages_controller.php:101
+msgid "page_title_policy"
+msgstr "Política dos extras"
+
+#: controllers/pages_controller.php:103
+msgid "page_title_privacy"
+msgstr "Política de privacidade da Mozilla"
+
+#: controllers/pages_controller.php:105
+msgid "page_title_review_guide"
+msgstr "Guia sobre comentários"
+
+#: controllers/pages_controller.php:107
+msgid "page_title_sandbox"
+msgstr "Sistema avaliação Sandbox"
+
+#: controllers/pages_controller.php:109
+msgid "page_title_submissionhelp"
+msgstr "Ajuda sobre submissões"
+
+#: views/pages/appversions.thtml:87
+msgid "pages_appversions_guid"
+msgstr "GUID"
+
+#: views/pages/appversions.thtml:79 controllers/pages_controller.php:90
+msgid "pages_appversions_header"
+msgstr "Versões Válidas da Aplicação"
+
+#: views/pages/appversions.thtml:80
+msgid "pages_appversions_intro"
+msgstr ""
+"Extras submetidos nos Extras da Mozilla têm de ter um ficheiro install.rdf "
+"com pelo menos uma aplicação suportada. Apenas as versões listadas abaixo "
+"são permitidas para essas aplicações."
+
+#. %s is a full <a> tag
+#: views/pages/appversions.thtml:93
+#, php-format
+msgid "pages_appversions_required_files"
+msgstr ""
+"Se a sua aplicação suportada não necessitar de um ficheiro install.rdf file, "
+"tem de incluir pelo menos um com as propriedades necessárias especificadas %"
+"s."
+
+#. this is the text inside of an <a> tag for pages_appversions_required_files. This
+#. should be fixed.
+#: views/pages/appversions.thtml:93
+msgid "pages_appversions_required_files_link"
+msgstr "aqui"
+
+#: views/pages/appversions.thtml:88
+msgid "pages_appversions_versions"
+msgstr "Versões"
+
+#: views/pages/policy.thtml:51
+msgid "pages_policy_sandbox_link"
+msgstr "Página de Informação do Sandbox"
+
+#: views/elements/pagination.thtml:53
+msgid "pagination_next_page"
+msgstr "seguinte"
+
+#: views/elements/pagination.thtml:52
+msgid "pagination_previous_page"
+msgstr "anterior"
+
+#: views/elements/recaptcha.thtml:65
+msgid "recaptcha_enter_both_words"
+msgstr ""
+"Por favor escreva <strong>ambas as palavras</strong> indicadas abaixo, "
+"<strong>separadas por um espaço</strong>."
+
+#: views/elements/recaptcha.thtml:83
+msgid "recaptcha_enter_here"
+msgstr "Escreva a sua resposta aqui:"
+
+#: views/elements/recaptcha.thtml:74
+msgid "recaptcha_enter_whatyouhear"
+msgstr "Escreva o que ouve."
+
+#. %1 is the link switching refreshing the captcha
+#. %2 is the link switching to a text captcha
+#: views/elements/recaptcha.thtml:77
+msgid "recaptcha_hardtohear_text"
+msgstr ""
+"Se for difícil de ouvir, pode <a href=\"%1$s\">ouvir algo diferente</a> ou "
+"<a href=\"%2$s\">mudar novamente para texto</a>."
+
+#. %1 is the link switching refreshing the captcha
+#. %2 is the link switching to an audio captcha
+#: views/elements/recaptcha.thtml:68
+msgid "recaptcha_hardtoread_text"
+msgstr ""
+"Se for difícil de ler, pode <a href=\"%1$s\">pode tentar outras letras</a> "
+"ou em alternativa <a href=\"%2$s\">ouvir algo</a>."
+
+#: views/users/register.thtml:105
+msgid "recaptcha_label"
+msgstr "Você é humano?"
+
+#: views/users/register.thtml:106
+msgid "recaptcha_whatsthis"
+msgstr "O que é isto?"
+
+#: controllers/reviews_controller.php:559
+msgid "review_flag_error"
+msgstr "Erro ao marcar este comentário"
+
+#: models/reviews_moderation_flag.php:69
+msgid "review_flag_reason_bug_support"
+msgstr "Relatório de erro mal colocado ou pedido de ajuda"
+
+#: views/reviews/display.thtml:103 views/reviews/display.thtml:186
+msgid "review_flag_reason_instructions"
+msgstr "Reportar este comentário (seleccione uma razão)"
+
+#: models/reviews_moderation_flag.php:67
+msgid "review_flag_reason_language"
+msgstr "Idioma/diálogo inapropriado"
+
+#: models/reviews_moderation_flag.php:71
+msgid "review_flag_reason_other"
+msgstr "Outro (por favor rspecífique)"
+
+#: models/reviews_moderation_flag.php:65
+msgid "review_flag_reason_spam"
+msgstr "Spam ou caso contrário conteúdo não revisto"
+
+#: views/reviews/display.thtml:91 views/reviews/display.thtml:175
+#: controllers/reviews_controller.php:555
+msgid "review_flag_success"
+msgstr "Obrigado;este avaliação foi marcada para aprovação do editor."
+
+#: views/reviews/display.thtml:41
+msgid "review_flag_this"
+msgstr "Reportar esta avaliação"
+
+#: views/reviews/display.thtml:42
+msgid "review_flag_this_titletip"
+msgstr ""
+"Este comentário é inapropriado, inadequado ou é spam? Clique aqui para enviá-"
+"la ao editor para revisão."
+
+#. %1 is the URL of the support section, %2 for the review guidelines
+#: views/reviews/add.thtml:53
+msgid "review_guidelines_short"
+msgstr ""
+"<p>Tenha isto em mente:</p><ul><li>Escreva como se tivesse a dizer a um "
+"amigo a sua experiência com este extra. Dê detalhes específicos e de ajuda,"
+"tais como que funcionalidades gostou ou desgostou, a facilidade de o "
+"utilizar, e qualquer desvantagem que tenha. Evite comentários genéricos tipo"
+"\"espetaculart\" ou \"Mau\" a não ser que dê razões para o poder dizer.</"
+"li><li>Por favor não coloque relatórios de erro nos comentários. Nós não "
+"fornecemos o seu endereço de correio ao desenvolvedor do extra e ele pode "
+"ter que o contactar para o ajudar a resolver o seu problema. Veja a <a href="
+"\"%1$s\">secção de ajuda</a>para encontrar ajuda para este extra.</"
+"li><li>Mantenha os comentários limpos, evite usar linguagem imprópria e não "
+"coloque nenhuma informação pessoal.</li></ul><p>Veja o <a href=\"%2$s\">Guia "
+"sobre comentários</a> para mais detalhes sobre comentários feitos por "
+"utilizadores.</p>"
+
+#. %1 is the add-on name
+#: views/reviews/flag.thtml:56 views/reviews/display.thtml:55
+#: views/reviews/review_added.thtml:50
+#, php-format
+msgid "reviews_header"
+msgstr "Comentários para %s"
+
+#: controllers/addons_controller.php:435
+msgid "rss_featuredaddons"
+msgstr "Extras"
+
+#: controllers/addons_controller.php:432
+msgid "rss_newestaddons"
+msgstr "Novos Extras"
+
+#: controllers/addons_controller.php:434
+msgid "rss_popularaddons"
+msgstr "Extras populares"
+
+#: controllers/addons_controller.php:433
+msgid "rss_updatedaddons"
+msgstr "Extras actualizados"
+
+#: views/elements/search_mini.thtml:70
+msgid "search"
+msgstr "Pesquisar"
+
+#: views/search/collections.thtml:51
+#, fuzzy
+msgid "search_collections_header"
+msgstr "Collection Search Results"
+
+#: controllers/search_controller.php:297
+#, fuzzy
+msgid "search_collections_pagetitle"
+msgstr "Collection Search Results"
+
+#: controllers/search_controller.php:99
+msgid "search_disabled"
+msgstr "A procura de momento está desactivada. Volte a tentar mais tarde."
+
+#: views/elements/amo2009/search.thtml:188 views/elements/search.thtml:187
+#: views/elements/search_mini.thtml:54
+msgid "search_form_all_addons"
+msgstr "todos os extras"
+
+#. This string is in the main category dropdown when searching
+#: views/elements/amo2009/search.thtml:204
+#, fuzzy
+msgid "search_form_all_collections"
+msgstr "all collections"
+
+#: views/elements/amo2009/search.thtml:184
+#: views/elements/amo2009/search.thtml:385
+#: views/elements/amo2009/search.thtml:408 views/elements/search.thtml:171
+#: views/elements/search.thtml:183 views/elements/search_mini.thtml:43
+#: views/elements/search_mini.thtml:49 views/layouts/mozilla.thtml:188
+msgid "search_form_default_text"
+msgstr "Procurar extras"
+
+#: views/elements/amo2009/search.thtml:184
+#: views/elements/amo2009/search.thtml:404
+#, fuzzy
+msgid "search_form_default_text_collections"
+msgstr "search for collections"
+
+#: views/elements/amo2009/search.thtml:206 views/elements/search.thtml:202
+msgid "search_form_submit_tooltip"
+msgstr "Pesquisar extras"
+
+#: views/elements/amo2009/search.thtml:184 views/elements/search.thtml:183
+#: views/elements/search_mini.thtml:49
+msgid "search_form_tooltip"
+msgstr "Clique para escrever os termos de pesquisa"
+
+#: views/elements/amo2009/search.thtml:186 views/elements/search.thtml:185
+#: views/elements/search_mini.thtml:52
+msgid "search_form_within"
+msgstr "em"
+
+#: views/addons/searchengines.thtml:118
+msgid "search_landing_all_search_engines"
+msgstr "Todos os Motores de Pesquisa"
+
+#: views/addons/searchengines.thtml:114
+msgid "search_landing_browse_search_engines"
+msgstr "Explorar Motores de Pesquisa"
+
+#: views/search/collections.thtml:58 views/search/index.thtml:59
+msgid "search_nothing_found"
+msgstr "Nenhum resultado encontrado."
+
+#: controllers/search_controller.php:185
+msgid "search_pagetitle"
+msgstr "Procurar Extras"
+
+#: controllers/search_controller.php:242
+msgid "search_rss_description"
+msgstr "Resultados da procura de fontes"
+
+#. %s is the terms the user is searching for (a string)
+#: controllers/search_controller.php:241
+#, php-format
+msgid "search_rss_results_for"
+msgstr "Procurar resultados para: %s"
+
+#: views/elements/header.thtml:154 views/layouts/amo2009.thtml:296
+msgid "sidebar_navlink_admin_tools"
+msgstr "Ferramentas do Admin"
+
+#: views/elements/header.thtml:146 views/layouts/amo2009.thtml:288
+msgid "sidebar_navlink_developer_tools"
+msgstr "Ferramentas do Desenvolvedor"
+
+#: views/elements/header.thtml:148 views/layouts/amo2009.thtml:290
+msgid "sidebar_navlink_editor_tools"
+msgstr "Ferramentas do Editor"
+
+#: views/layouts/amo2009.thtml:302
+msgid "sidebar_navlink_welcome"
+msgstr "Bem-Vindo"
+
+#. %s is the user's name
+#: views/layouts/amo2009.thtml:302
+#, php-format
+msgid "sidebar_navlink_welcome_name"
+msgstr "Bem-Vindo, %s"
+
+#: views/elements/pitch.thtml:50 views/elements/pitch.thtml:55
+msgid "sidebar_pitch_dictionary"
+msgstr "Dicionário"
+
+#: views/elements/pitch.thtml:72
+msgid "sidebar_pitch_featured_addons"
+msgstr "Extras"
+
+#: views/elements/pitch.thtml:61
+msgid "sidebar_pitch_looking_for"
+msgstr "Estou a procurar um:"
+
+#: views/elements/pitch.thtml:70
+msgid "sidebar_pitch_newest_addons"
+msgstr "Extras recentes"
+
+#: views/elements/pitch.thtml:49
+msgid "sidebar_pitch_search"
+msgstr "Plugin de Pesquisa"
+
+#: views/elements/pitch.thtml:69
+msgid "sidebar_pitch_subscribe_to"
+msgstr "Subscrever a"
+
+#: views/elements/pitch.thtml:48 views/elements/pitch.thtml:54
+msgid "sidebar_pitch_theme"
+msgstr "Tema"
+
+#: views/elements/pitch.thtml:71
+msgid "sidebar_pitch_updated_addons"
+msgstr "Extras actualizados"
+
+#. %1$s is a number
+#: views/helpers/localization.php:65 views/developers/versions_edit.thtml:95
+#: views/addons/dictionaries.thtml:92
+#, php-format
+msgid "size_kb"
+msgstr "%1$s&nbsp;KB"
+
+#: views/elements/amo2009/stars.thtml:57 views/elements/stars.thtml:63
+msgid "stars_not_yet_rated"
+msgstr "Ainda sem avaliação"
+
+#. %1 is the number of stars this add-on has
+#: views/elements/amo2009/stars.thtml:49 views/elements/stars.thtml:54
+#, php-format
+msgid "stars_rated_x_outof_5"
+msgstr "Avaliado com %s de 5 estrelas"
+
+#: views/statistics/addon.thtml:59
+msgid "statistics_addon_dashboard_link"
+msgstr "Início do Painel"
+
+#: views/statistics/addon.thtml:58
+msgid "statistics_addon_developertools_link"
+msgstr "Ferramentas do Developer"
+
+#: views/statistics/addon.thtml:53
+msgid "statistics_addon_switch"
+msgstr "Mudar Extra"
+
+#. This is a date format.
+#. http://php.net/strftime
+#: views/statistics/rss/summary.thtml:54 views/statistics/addon.thtml:181
+msgid "statistics_date_shortmonth"
+msgstr "%b. %e"
+
+#. This is a date format.
+#. http://php.net/strftime
+#: views/statistics/rss/summary.thtml:40 views/statistics/addon.thtml:152
+msgid "statistics_date_shortmonthwithyear"
+msgstr "%b. %e, %Y"
+
+#. This is a date format.
+#. http://php.net/strftime
+#: views/statistics/rss/summary.thtml:41 views/statistics/rss/summary.thtml:48
+#: views/statistics/addon.thtml:161 views/statistics/addon.thtml:172
+msgid "statistics_date_weekdayshortmonth"
+msgstr "%A, %b. %e"
+
+#. %1$s is an add-on name and version. Example: Add-on 3.5
+#: controllers/components/stats.php:519
+#, php-format
+msgid "statistics_events_addon_created"
+msgstr "%1$s criado"
+
+#. %1$s is an application name and version. Example: Firefox 3.5
+#: controllers/components/stats.php:500
+#, php-format
+msgid "statistics_events_app_released"
+msgstr "%1$s lançado"
+
+#: views/statistics/addon.thtml:71
+msgid "statistics_help_close_link"
+msgstr "Fechar"
+
+#: views/statistics/addon.thtml:60
+msgid "statistics_help_link"
+msgstr "Ajuda"
+
+#: views/statistics/index.thtml:83
+msgid "statistics_index_anotheraddon"
+msgstr "ou, seleccione outro extra"
+
+#: views/statistics/index.thtml:85
+msgid "statistics_index_anotheraddon_public"
+msgstr "ou, seleccione um extra com estatísticas públicas"
+
+#: views/statistics/index.thtml:71
+msgid "statistics_index_myaddons"
+msgstr "Seleccione um dos seus extra para ver as suas estatísticas"
+
+#: views/statistics/index.thtml:89
+msgid "statistics_index_selectaddon"
+msgstr "Seleccione um extra para ver as suas estatísticas"
+
+#: views/statistics/index.thtml:91
+msgid "statistics_index_selectaddon_public"
+msgstr "Seleccione um extra com estatísticas públicas"
+
+#: views/statistics/index.thtml:39
+msgid "statistics_index_title"
+msgstr "Quadro de Estatísticas"
+
+#: views/statistics/index.thtml:97
+msgid "statistics_index_view_button"
+msgstr "Ver Estatísticas"
+
+#: views/statistics/addon.thtml:222 controllers/statistics_controller.php:247
+msgid "statistics_js_download_csv"
+msgstr "Ver esta tabela no formato CSV"
+
+#: controllers/statistics_controller.php:246
+msgid "statistics_js_dropdowns_none"
+msgstr "nenhum"
+
+#: controllers/statistics_controller.php:245
+msgid "statistics_js_dropdowns_removeplot"
+msgstr "Remover esta parcela"
+
+#: controllers/statistics_controller.php:248
+msgid "statistics_js_groupby_selector_date"
+msgstr "Agrupar por: Dia"
+
+#: controllers/statistics_controller.php:251
+msgid "statistics_js_groupby_selector_month"
+msgstr "Agrupar por: Mês"
+
+#: controllers/statistics_controller.php:249
+msgid "statistics_js_groupby_selector_week"
+msgstr "Agrupar por: Semana"
+
+#: controllers/statistics_controller.php:250
+msgid "statistics_js_groupby_selector_week_over_week"
+msgstr "Comparar por: Semana"
+
+#: controllers/statistics_controller.php:260
+msgid "statistics_js_plotselection_foundinrange"
+msgstr "%s encontrados no intervalo"
+
+#: controllers/statistics_controller.php:270
+msgid "statistics_js_plotselection_options_addplot_name"
+msgstr "Adicionar parcela"
+
+#: controllers/statistics_controller.php:271
+msgid "statistics_js_plotselection_options_addplot_tooltip"
+msgstr "Adicionar outra parcela a este gráfico"
+
+#: controllers/statistics_controller.php:261
+msgid "statistics_js_plotselection_options_count_name_checked"
+msgstr "Esconder contador total"
+
+#: controllers/statistics_controller.php:262
+msgid "statistics_js_plotselection_options_count_name_unchecked"
+msgstr "Mostrar contador total"
+
+#: controllers/statistics_controller.php:263
+msgid "statistics_js_plotselection_options_count_tooltip"
+msgstr "Mostrar o contador total neste gráfico"
+
+#: controllers/statistics_controller.php:275
+msgid "statistics_js_plotselection_options_csv_name"
+msgstr "Ver Dados (CSV)"
+
+#: controllers/statistics_controller.php:276
+msgid "statistics_js_plotselection_options_csv_tooltip"
+msgstr "Obter ficheiro com valores separados por Vírgulas para estes dados"
+
+#: controllers/statistics_controller.php:267
+msgid "statistics_js_plotselection_options_events_addon_name_checked"
+msgstr "Ocultar %s Eventos"
+
+#: controllers/statistics_controller.php:268
+msgid "statistics_js_plotselection_options_events_addon_name_unchecked"
+msgstr "Mostrar %s Eventos"
+
+#: controllers/statistics_controller.php:269
+msgid "statistics_js_plotselection_options_events_addon_tooltip"
+msgstr "Sobrepor as datas de lançamento do extra nas parcelas"
+
+#: controllers/statistics_controller.php:264
+msgid "statistics_js_plotselection_options_events_firefox_name_checked"
+msgstr "Ocultar Eventos do Firefox"
+
+#: controllers/statistics_controller.php:265
+msgid "statistics_js_plotselection_options_events_firefox_name_unchecked"
+msgstr "Mostrar os Eventos do Firefox"
+
+#: controllers/statistics_controller.php:266
+msgid "statistics_js_plotselection_options_events_firefox_tooltip"
+msgstr "Sobrepor as datas de lançamento do Firefox nas parcelas"
+
+#: controllers/statistics_controller.php:272
+msgid "statistics_js_plotselection_options_resize_name_checked"
+msgstr "Colapsar Gráfico"
+
+#: controllers/statistics_controller.php:273
+msgid "statistics_js_plotselection_options_resize_name_unchecked"
+msgstr "Expandir Gráfico"
+
+#: controllers/statistics_controller.php:274
+msgid "statistics_js_plotselection_options_resize_tooltip"
+msgstr "Redimensionar Gráfico"
+
+#: controllers/statistics_controller.php:254
+msgid "statistics_js_plotselection_selector_adu"
+msgstr "Utilizadores Activos Diários"
+
+#: controllers/statistics_controller.php:256
+msgid "statistics_js_plotselection_selector_application"
+msgstr "Aplicação"
+
+#: controllers/statistics_controller.php:259
+msgid "statistics_js_plotselection_selector_custom"
+msgstr "Personalizar"
+
+#: controllers/statistics_controller.php:253
+msgid "statistics_js_plotselection_selector_downloads"
+msgstr "Transferências"
+
+#: controllers/statistics_controller.php:258
+msgid "statistics_js_plotselection_selector_os"
+msgstr "Sistema Operativo"
+
+#: controllers/statistics_controller.php:257
+msgid "statistics_js_plotselection_selector_status"
+msgstr "Estado do Extra"
+
+#: controllers/statistics_controller.php:252
+msgid "statistics_js_plotselection_selector_summary"
+msgstr "Sumário"
+
+#: controllers/statistics_controller.php:255
+msgid "statistics_js_plotselection_selector_version"
+msgstr "Versão do Extra"
+
+#: controllers/components/stats.php:398
+msgid "statistics_longnames_application"
+msgstr "Aplicação"
+
+#: controllers/components/stats.php:400
+msgid "statistics_longnames_os"
+msgstr "Sistema Operativo"
+
+#: controllers/components/stats.php:399
+msgid "statistics_longnames_status"
+msgstr "Estado do Extra"
+
+#: controllers/components/stats.php:401
+msgid "statistics_longnames_unknown"
+msgstr "Desconhecido"
+
+#: controllers/components/stats.php:397
+msgid "statistics_longnames_version"
+msgstr "Versão do Extra"
+
+#: views/statistics/addon.thtml:118
+msgid "statistics_notice_data_insufficient"
+msgstr ""
+"Ainda não existem dados suficientes para este gráfico. Tente mais tarde."
+
+#: views/statistics/addon.thtml:130
+msgid "statistics_notice_data_none"
+msgstr ""
+"Ainda não temos nenhuns dados para o seu extra. Tente mais tarde daqui a "
+"alguns dias."
+
+#: views/statistics/addon.thtml:41
+msgid "statistics_notice_data_updating"
+msgstr ""
+"As estatísticas do extra estão a ser actualizadas. Dados recentes podem "
+"estar incompletos pois os nossos scripts para actualizar a informação. Tente "
+"daqui a alguns minutos."
+
+#: views/statistics/addon.thtml:136
+msgid "statistics_notice_disabled"
+msgstr ""
+"O Painel de Estatísticas de momento está desactivado. Tente mais tarde."
+
+#: views/statistics/addon.thtml:123
+msgid "statistics_notice_nojavascript"
+msgstr "O JavaScript é necessário para ver o gráfico das estatísticas."
+
+#: views/statistics/addon.thtml:44
+msgid "statistics_notice_settings_updated"
+msgstr "As suas definições foram actualizadas!"
+
+#: controllers/statistics_controller.php:60
+#: controllers/statistics_controller.php:71
+#: controllers/statistics_controller.php:74
+#: controllers/statistics_controller.php:240
+msgid "statistics_pagetitle"
+msgstr "Estatísticas"
+
+#: views/statistics/addon.thtml:99
+msgid "statistics_plot_legend_adu"
+msgstr "Utilizadores Diários activos"
+
+#: views/statistics/addon.thtml:95
+msgid "statistics_plot_legend_downloads"
+msgstr "Transferências Diárias"
+
+#: views/statistics/addon.thtml:107
+msgid "statistics_plot_options_zoomin_alt"
+msgstr "Aumentar"
+
+#: views/statistics/addon.thtml:106
+msgid "statistics_plot_options_zoomin_title"
+msgstr "Aumentar um mês"
+
+#: views/statistics/addon.thtml:110
+msgid "statistics_plot_options_zoomout_alt"
+msgstr "Diminuir"
+
+#: views/statistics/addon.thtml:109
+msgid "statistics_plot_options_zoomout_title"
+msgstr "Diminuir um mês"
+
+#: controllers/statistics_controller.php:283
+#, php-format
+msgid "statistics_rss_description"
+msgstr "Sumário de estatísticas Diário para %1$s"
+
+#: views/statistics/rss/summary.thtml:68
+msgid "statistics_rss_title_fulldate"
+msgstr "%A, %B %e, %Y"
+
+#: views/statistics/rss/summary.thtml:68
+#, php-format
+msgid "statistics_rss_title_statsfordate"
+msgstr "Estatísticas para %1$s"
+
+#: views/statistics/settings.thtml:49
+msgid "statistics_settings_access_description"
+msgstr ""
+"Por defeito,apenas você e a Mozilla podem aceder à informação do seu "
+"dashboard. Pode abrir isto ao público para que todos possam ver os dados "
+"relativos ao seu extra."
+
+#: views/statistics/settings.thtml:48
+msgid "statistics_settings_access_heading"
+msgstr "Acesso ao Dashboard"
+
+#: views/statistics/settings.thtml:51
+msgid "statistics_settings_access_private"
+msgstr "Privado"
+
+#: views/statistics/settings.thtml:51
+msgid "statistics_settings_access_private_description"
+msgstr "Apenas você e a Mozilla podem ver as estatísticas deste extra"
+
+#: views/statistics/settings.thtml:52
+msgid "statistics_settings_access_public"
+msgstr "Público"
+
+#: views/statistics/settings.thtml:52
+msgid "statistics_settings_access_public_description"
+msgstr "Todos podem ver as estatísticas deste extra"
+
+#: views/statistics/addon.thtml:251
+msgid "statistics_settings_change_link"
+msgstr "Mudar definições"
+
+#: views/statistics/addon.thtml:253
+msgid "statistics_settings_confidential"
+msgstr "Por favor trate esta informação como confidencial."
+
+#: views/statistics/addon.thtml:245
+msgid "statistics_settings_currently_private"
+msgstr "Este painel actualmente é <b>privado</b>."
+
+#: views/statistics/addon.thtml:241
+msgid "statistics_settings_currently_public"
+msgstr "Estepainel actualmente é <b>público</b>."
+
+#: views/statistics/addon.thtml:246
+msgid "statistics_settings_locked_alt"
+msgstr "Bloqueado"
+
+#: views/statistics/settings.thtml:57
+msgid "statistics_settings_return_link"
+msgstr "Voltar ao Painel"
+
+#: views/statistics/settings.thtml:56
+msgid "statistics_settings_save_button"
+msgstr "Guardar Definições"
+
+#: views/statistics/settings.thtml:46
+#, php-format
+msgid "statistics_settings_title"
+msgstr "Definições do Painel de estatisticas para %1$s"
+
+#: views/statistics/addon.thtml:242
+msgid "statistics_settings_unlocked_alt"
+msgstr "Desbloqueado"
+
+#: controllers/components/stats.php:405
+msgid "statistics_shortnames_application"
+msgstr "Ap"
+
+#: controllers/components/stats.php:407
+msgid "statistics_shortnames_os"
+msgstr "SO"
+
+#: controllers/components/stats.php:406
+msgid "statistics_shortnames_status"
+msgstr "Es"
+
+#: controllers/components/stats.php:408
+msgid "statistics_shortnames_unknown"
+msgstr "Desc"
+
+#: controllers/components/stats.php:404
+msgid "statistics_shortnames_version"
+msgstr "Ver."
+
+#: views/statistics/rss/summary.thtml:42 views/statistics/addon.thtml:192
+msgid "statistics_summary_downloads_average"
+msgstr "Média de Transferências Diárias"
+
+#: views/statistics/rss/summary.thtml:39
+msgid "statistics_summary_downloads_heading"
+msgstr "Transferências"
+
+#: views/statistics/rss/summary.thtml:41 views/statistics/addon.thtml:171
+msgid "statistics_summary_downloads_lastcount"
+msgstr "Última contagem do Dia"
+
+#: views/statistics/rss/summary.thtml:43 views/statistics/addon.thtml:199
+msgid "statistics_summary_downloads_lastweek"
+msgstr "Transferências nos últimos 7 dias"
+
+#: views/statistics/rss/summary.thtml:40 views/statistics/addon.thtml:151
+msgid "statistics_summary_downloads_total"
+msgstr "Transferências Totais"
+
+#: views/statistics/rss/summary.thtml:40 views/statistics/addon.thtml:152
+#, php-format
+msgid "statistics_summary_downloads_total_sincedate"
+msgstr "Desde %1$s"
+
+#: views/statistics/rss/summary.thtml:50 views/statistics/rss/summary.thtml:56
+#: views/statistics/addon.thtml:163 views/statistics/addon.thtml:183
+msgid "statistics_summary_nodata"
+msgstr "Ainda sem dados"
+
+#: views/statistics/rss/summary.thtml:60 views/statistics/addon.thtml:195
+msgid "statistics_summary_updatepings_average"
+msgstr "Média de Utilizadores Activos Diáriamente"
+
+#: views/statistics/rss/summary.thtml:52 views/statistics/addon.thtml:177
+msgid "statistics_summary_updatepings_changefromprevious"
+msgstr "Alterações desde a última contagem"
+
+#: views/statistics/rss/summary.thtml:54 views/statistics/addon.thtml:181
+#, php-format
+msgid "statistics_summary_updatepings_changefromprevious_ondate"
+msgstr "%1$s em %2$s"
+
+#: views/statistics/rss/summary.thtml:45
+msgid "statistics_summary_updatepings_heading"
+msgstr "Utilizadores Activos Diáriamente"
+
+#: views/statistics/rss/summary.thtml:46 views/statistics/addon.thtml:157
+msgid "statistics_summary_updatepings_total"
+msgstr "Utilizadores Activos Diáriamente"
+
+#: views/statistics/rss/summary.thtml:48 views/statistics/addon.thtml:161
+#, php-format
+msgid "statistics_summary_updatepings_total_ondate"
+msgstr "Em %1$s"
+
+#: views/statistics/rss/summary.thtml:61 views/statistics/addon.thtml:203
+msgid "statistics_summary_updatepings_weekly_average"
+msgstr "Média de utilizadores diários esta semana"
+
+#. %s is a percentage, like '+22.33%'. It sits next to another number, so
+#. the implied meaning is 'percentage change' from the previous stat point.
+#: views/statistics/rss/summary.thtml:62 views/statistics/addon.thtml:205
+msgid "statistics_summary_updatepings_weekly_change"
+msgstr "%s da última semana"
+
+#: views/statistics/addon.thtml:65 controllers/statistics_controller.php:184
+#: controllers/statistics_controller.php:282
+#, php-format
+msgid "statistics_title_addon_stats"
+msgstr "%1$s Estatisticas"
+
+#: views/addons/themes_landing.thtml:113
+msgid "themes_landing_all_themes"
+msgstr "Todos os Temas"
+
+#: views/addons/themes_landing.thtml:109
+msgid "themes_landing_browse_themes"
+msgstr "Explorar Temas"
+
+#: views/users/edit.thtml:185
+msgid "user_change_email"
+msgstr "Alterar endereço de correio"
+
+#: views/users/edit.thtml:169
+msgid "user_change_password"
+msgstr "Alterar senha"
+
+#: views/users/edit.thtml:96
+msgid "user_change_password_or_email"
+msgstr "Alterar senha ou correio electrónico"
+
+#: controllers/users_controller.php:197
+msgid "user_confirmationcode_resent"
+msgstr "O código de confirmação foi reenviado!"
+
+#. %1 is the email address, %2 is the URL of the user registration page
+#: views/users/delete.thtml:51
+msgid "user_del_account_deleted"
+msgstr ""
+"A sua conta de utilizador %1$s foi eliminada com sucesso. Se desejar voltar "
+"mais tarde, pode voltar a registar-se na <a href=\"%2$s\">página de registo "
+"de utilizador</a>."
+
+#: views/users/delete.thtml:102
+msgid "user_del_community_sad"
+msgstr "A comunidade dos Extras da Mozilla está triste por vê-lo partir."
+
+#: views/users/delete.thtml:123
+msgid "user_del_confirm_password"
+msgstr "Confirmar Senha"
+
+#: views/users/delete.thtml:134
+msgid "user_del_deletenow"
+msgstr "Eliminar agora a minha conta de utilizador"
+
+#. %1 is the URL of the user's info page
+#: views/users/delete.thtml:64
+msgid "user_del_error_addons"
+msgstr ""
+"Não pode eliminar a sua conta se estiver incrito como <a href=\"%1$s\">autor "
+"de qualquer extra</a>. Para eliminar a sua conta, arranje outra pessoa no "
+"seu grupo de desenvolvimento para o eliminar da lista de autores dos seus "
+"extras. Depois já aqui poderá eliminar a sua conta."
+
+#. %1 is a link to the amo-editors mailing list
+#: views/users/delete.thtml:71
+msgid "user_del_error_addons_more_questions"
+msgstr "Se tiver perguntas, por favor contacte %1$s para assistência."
+
+#: views/users/delete.thtml:78
+msgid "user_del_error_checkbox"
+msgstr ""
+"Tem de seleccionar a caixa \"Eu compreendo...\" antes de eliminar a sua "
+"conta."
+
+#: views/users/delete.thtml:84
+msgid "user_del_error_password"
+msgstr "Introduza a sua senha correctamente para efectuar este passo."
+
+#. %1 is a link to the amo-admins mailing list
+#: views/users/delete.thtml:91
+msgid "user_del_error_unknown"
+msgstr ""
+"Ocorreu um erro desconhecido ao eliminar a sua conta. por favor contacte %1"
+"$s com o problema e nós eliminaremos a sua conta. pedimos desculpa pela "
+"incoveniência."
+
+#: views/users/delete.thtml:110
+msgid "user_del_header_confirm_deletion"
+msgstr "Confirmar eliminação da conta"
+
+#. %1 is the user's email address
+#: views/users/delete.thtml:100
+msgid "user_del_header_delete_account"
+msgstr "Eliminar a conta de utilizador %1$s"
+
+#: views/users/delete.thtml:50
+msgid "user_del_header_farewell"
+msgstr "Adeus!"
+
+#: views/users/delete.thtml:115
+msgid "user_del_nologin"
+msgstr "Não poderá entrar mais nos Extras da Mozilla."
+
+#: views/users/delete.thtml:112
+msgid "user_del_permanently_removed_means"
+msgstr ""
+"Ao clicar \"eliminar\" a sua conta irá ser <strong>permanentemente "
+"eliminada</strong>. isto significa:"
+
+#: views/users/delete.thtml:116
+msgid "user_del_reviews_anonymized"
+msgstr ""
+"Os seus comentários e avaliações não serão eliminadas, mas não serão "
+"associadas a si."
+
+#. %1 is a link to the amo-editors mailing list
+#: views/users/delete.thtml:104
+msgid "user_del_specific_problem_editors"
+msgstr ""
+"Se tiver um problema específico nós podemos ajudar, por favor não elimine "
+"agora a sua conta, contacte-nos em %1$s e faremos o nosso melhor para ajudá-"
+"loa resolver."
+
+#: views/users/delete.thtml:130
+msgid "user_del_understand_permanent"
+msgstr "Eu compreendo que este passo não pode ser anulado."
+
+#: views/helpers/addons_html.php:192
+msgid "user_deleted_nickname"
+msgstr "Eliminar utilizador"
+
+#. %1 is the new email address
+#: views/users/edit.thtml:71
+msgid "user_edit_confirm_email_sent"
+msgstr ""
+"Uma mensagem de correio electrónico foi enviada para %1$s para confirmar o "
+"seu novo endereço. Para que a alteração seja realizada, tem que clicar na "
+"ligação fornecida nesta mensagem. Até lá pode continuar a entrar com o seu "
+"correio electrónico actual."
+
+#: views/users/edit.thtml:201
+msgid "user_edit_delete_user"
+msgstr "Eliminar conta de utilizador"
+
+#. This contains the email sent to users when they signed up for a new
+#. account:
+#. %1 is the confirmation URL, %2 is the current app
+#: views/users/email/confirm_plain.thtml:6
+#, php-format
+msgid "user_email_confirm_account_nopass"
+msgstr ""
+"Bem-Vindo aos Extras do %2$s .\n"
+"\n"
+"Antes de poder utilizar a sua nova conta, tem de a activar - isto assegura "
+"que o endereço de correio utilizado é válido e pertence a si.\n"
+"Para activar a sua conta, clique na ligação abaixo ou copie e cole tudo na "
+"barra de endereço do seu navegador:\n"
+"\n"
+"%1$s\n"
+"\n"
+"Uma vez activada a sua conta com sucesso, pode apagar esta mensagem de "
+"correio.\n"
+"\n"
+"Obrigado por se juntar aos Extras do %2$s\n"
+"-- A equipa dos Extras do %2$s"
+
+#. %1 is the confirmation url, %2 is the application name
+#: views/users/email/emailchange_plain.thtml:5
+msgid "user_email_confirm_emailchange"
+msgstr ""
+"Pediu uma alteração no endereço de correio electrónico dos Extras do %2$s.\n"
+"\n"
+"De maneira a confirmar o seu novo endereço, clique na ligação abaixo ou "
+"copie tudo e cole na barra do seu navegador:\n"
+"\n"
+"%1$s\n"
+"\n"
+"Tem 48 horas para confirmar o seu novo endereço de correio. Se já não "
+"desejar alterar o seu endereço de correio, pode ignorar esta mensageml.\n"
+"\n"
+"Obrigado!\n"
+"-- A equipa dos Extras do %2$s"
+
+#: controllers/users_controller.php:168
+#, php-format
+msgid "user_email_confirm_subject"
+msgstr "Obrigado por se juntar aos Extras do %s"
+
+#. This is the password reset email
+#. %1 is the pw reset URL, %2 is the application
+#: views/users/email/pwreset_plain.thtml:5
+#, php-format
+msgid "user_email_pwreset"
+msgstr ""
+"Limpar a senha dos Extras do %2$s\n"
+"\n"
+"Foi recebido um pedido para limpar a senha desta conta em addons.mozilla."
+"org. Para alterar a senha clique na seguinte ligação, ou cole-a na barra de "
+"endereço do seu navegador:\n"
+"\n"
+"%1$s\n"
+"\n"
+"Se não pediu esta mensagem de correio electrónico não precisa de fazer mais "
+"nada.\n"
+"\n"
+"Obrigado,\n"
+"-- A equipa dos Extras do %2$s"
+
+#: controllers/users_controller.php:245
+#, php-format
+msgid "user_email_pwreset_subject"
+msgstr "Re-inicie a sua senha dos Extras %s"
+
+#: views/users/emailchange.thtml:50
+msgid "user_emailchange_error"
+msgstr "Erro!"
+
+#. %1 is the application name
+#: controllers/users_controller.php:533
+msgid "user_emailchange_subject"
+msgstr ""
+"Por favor confirme a alteração do seu endereço de correio electrónico em "
+"Extras do %1$s"
+
+#: views/users/emailchange.thtml:48
+msgid "user_emailchange_success"
+msgstr "Successo!"
+
+#. %1 is the new email address
+#: views/users/emailchange.thtml:49
+msgid "user_emailchange_successful_description"
+msgstr ""
+"O seu endereço de correio electrónico foi alterado com sucesso. A partir de "
+"agora, utilize %1$s para entrar."
+
+#: views/users/edit.thtml:134 views/admin/users_edit.thtml:111
+msgid "user_form_bio"
+msgstr "Sobre mim"
+
+#: views/users/edit.thtml:135 views/admin/users_edit.thtml:112
+msgid "user_form_bio_description"
+msgstr ""
+"Apresente-se à comunidade, se desejar! Este texto irá aparecer publicamente "
+"na sua info.Quebras de linha serão mantidas, mas HTML não é permitido."
+
+#: views/users/pwreset.thtml:77 views/users/register.thtml:73
+#: views/users/edit.thtml:181
+msgid "user_form_confirmpassword"
+msgstr "Confirmar senha"
+
+#: views/users/edit.thtml:145
+msgid "user_form_display_collections"
+msgstr "Mostrar as colecções que criei no meu perfil de utilizador"
+
+#: views/users/edit.thtml:149
+msgid "user_form_display_collections_fav"
+msgstr "Mostrar as minhas colecções favoritas no meu perfil de utilizador"
+
+#: views/users/edit.thtml:86
+#, php-format
+msgid "user_form_editprofile"
+msgstr "Editar perfil do utilizador %s"
+
+#: views/users/pwreset.thtml:52 views/users/login.thtml:81
+#: views/users/register.thtml:63 views/users/edit.thtml:187
+msgid "user_form_email"
+msgstr "Endereço de Correio "
+
+#: views/users/register.thtml:78 views/users/edit.thtml:103
+#: views/admin/users_edit.thtml:76
+msgid "user_form_firstname"
+msgstr "Primeiro nome"
+
+#: views/users/register.thtml:94 views/users/edit.thtml:119
+#: views/admin/users_edit.thtml:91
+msgid "user_form_hideemail"
+msgstr "Ocultar endereço de correio"
+
+#: views/users/register.thtml:98 views/users/edit.thtml:123
+#: views/admin/users_edit.thtml:99
+msgid "user_form_homepage"
+msgstr "URL do Sítio Web"
+
+#: views/users/register.thtml:84 views/users/edit.thtml:109
+#: views/admin/users_edit.thtml:81
+msgid "user_form_lastname"
+msgstr "último nome"
+
+#: controllers/users_controller.php:333
+msgid "user_form_login"
+msgstr "Login do Utilizador"
+
+#: views/users/pwreset.thtml:72 views/users/edit.thtml:176
+msgid "user_form_newpassword"
+msgstr "Nova senha"
+
+#: views/users/register.thtml:89 views/users/edit.thtml:114
+#: views/admin/users_edit.thtml:86
+msgid "user_form_nickname"
+msgstr "Alcunha"
+
+#: views/users/edit.thtml:171
+msgid "user_form_oldpassword"
+msgstr "Senha antiga"
+
+#: views/users/edit.thtml:97 views/users/edit.thtml:200
+msgid "user_form_otheractions"
+msgstr "Outras acções"
+
+#: views/users/login.thtml:85 views/users/register.thtml:68
+msgid "user_form_password"
+msgstr "Senha"
+
+#: controllers/users_controller.php:93
+msgid "user_form_registration"
+msgstr "Novo Registo de Utilizador"
+
+#: views/users/login.thtml:90
+msgid "user_form_remember_me"
+msgstr "Lembrar-me neste computador"
+
+#: views/admin/users_edit.thtml:95
+msgid "user_form_showsandbox"
+msgstr "Mostrar sandbox?"
+
+#: views/users/edit.thtml:205
+msgid "user_form_submit_edit"
+msgstr "Guardar"
+
+#: views/users/login.thtml:93
+msgid "user_form_submit_login"
+msgstr "Entrar"
+
+#: views/users/register.thtml:113
+msgid "user_form_submit_register"
+msgstr "Registar"
+
+#: views/users/info.thtml:75
+#, php-format
+msgid "user_info_usersince"
+msgstr "%s utilizador dos Extras desde"
+
+#: views/users/login.thtml:102
+msgid "user_login_register_link"
+msgstr "Criar uma nova conta de utilizador"
+
+#: views/users/edit.thtml:160
+msgid "user_notifications_item_compat"
+msgstr "Compatibilidade do extra (fortemente recomendado)"
+
+#: views/users/edit.thtml:161
+msgid "user_notifications_item_events"
+msgstr "Próximos eventos e concursos"
+
+#: views/users/edit.thtml:156
+msgid "user_notifications_none_available"
+msgstr "De momento não existem notificações disponíveis para configurar."
+
+#: views/users/edit.thtml:158
+msgid "user_notifications_select_topics"
+msgstr ""
+"De vez em quando a Mozilla poderá enviar-lhe uma mensagem de correio sobre "
+"os próximos lançamentos e eventos de extras. Seleccione os tópicos que lhe "
+"interessam abaixo:"
+
+#: views/users/edit.thtml:164
+msgid "user_notifications_specific_contact"
+msgstr ""
+"A Mozilla reserva o direito de o cntactar individualmente sobre preocupações "
+"específicas sobre os extras hospedados."
+
+#: controllers/users_controller.php:543
+msgid "user_profile_edit_error"
+msgstr ""
+"Houve erros nas alterações que efectuou. Corrija-os e volte a submeter."
+
+#: controllers/users_controller.php:540
+msgid "user_profile_saved"
+msgstr "Perfil actualizado."
+
+#: views/users/pwreset.thtml:65
+#, php-format
+msgid "user_pwreset_for_email"
+msgstr "Reiniciar para %s"
+
+#: controllers/users_controller.php:226
+msgid "user_pwreset_header"
+msgstr "Reiniciar Senha"
+
+#: views/users/login.thtml:103
+msgid "user_pwreset_link"
+msgstr "Esqueceu a sua senha?"
+
+#: controllers/users_controller.php:248
+msgid "user_pwreset_link_sent"
+msgstr ""
+"A ligação para reiniciar a sua senha foi enviada para o seu endereço de "
+"correio electrónico."
+
+#: controllers/users_controller.php:304
+msgid "user_pwreset_okay"
+msgstr "Senha reiniciada com sucesso."
+
+#: views/users/pwreset.thtml:82
+msgid "user_pwreset_submit_changepw"
+msgstr "Submeter alteração de senha"
+
+#: views/users/pwreset.thtml:57
+msgid "user_pwreset_submit_sendlink"
+msgstr "Enviar ligação para reiniciar senha"
+
+#: views/users/register_complete.thtml:51
+#, php-format
+msgid "user_register_amo_link"
+msgstr "%s Extras"
+
+#. %1 is the user's email address, %2 is the current app
+#: views/users/activatefirst.thtml:49
+#, php-format
+msgid "user_register_click_confirm_link"
+msgstr ""
+"Foi enviada para a sua conta de correio %1$s uma ligação para activar a sua "
+"conta de utilizador. Tem de a ver antes de poder entrar nos Extras do %2$s."
+
+#. %1 is the user's email address
+#: views/users/register_complete.thtml:49
+#, php-format
+msgid "user_register_confirm_email_sent"
+msgstr ""
+"Foi enviada uma mensagem de correio electrónico a %1$s para confirmar a sua "
+"conta. Antes de poder entrar, tem de activar a sua conta clicando na ligação "
+"fornecida nesta mensagem de correio electrónico."
+
+#: views/users/activatefirst.thtml:51
+msgid "user_register_confirmation_link_text"
+msgstr "re-enviar a mensagem de confirmação"
+
+#: views/users/register_complete.thtml:47
+msgid "user_register_congratulations"
+msgstr "Parabéns! A sua conta de utilizador foi criada com sucesso."
+
+#: views/users/register.thtml:50
+msgid "user_register_details"
+msgstr ""
+"<p>O registo no AMO não <strong>é necessário</strong> se apenas quiser "
+"transferir e instalar extras públicos.</p><p>Apenas necessita de se registar "
+"se:</p><ul><li>Deseja submeter comentários para os extras</li><li>For um "
+"desenvolvedor de extras e desejar carregar o extra para o AMO</li></"
+"ul><p>Após registar-se com sucesso, ser-lhe-á enviado uma mensagem de "
+"correio de confirmação para o endereço que forneceu. Siga as instruções lá "
+"contidas para confirmar a sua conta.</p><p>Se quiser pode ler as nossas <a "
+"href='%1$s' title=Legal Notices'>Notícias Legais</a> e a <a href='%2$s' "
+"title='Privacy Policy'>Política de Privacidade</a>.</p>"
+
+#. %1 is the link to the "resend confirmation code" page
+#: views/users/activatefirst.thtml:51
+#, php-format
+msgid "user_register_resend_confirmation_link"
+msgstr ""
+"Se não recebeu o correio electrónico de confirmação, verifique se o seu "
+"serviço de correio não o marcou como \"lixo electrónico\" ou \"spam\". Se "
+"necessitar, pode-nos pedir para %1$s para o endereço de correio electrónico "
+"acima mencionado."
+
+#. %1 is the link to the Mozilla Add-ons front page
+#: views/users/register_complete.thtml:51
+#, php-format
+msgid "user_register_welcome"
+msgstr "Obrigado por se registar e bem-vindo a %1$s!"
+
+#: views/users/register.thtml:49
+msgid "user_register_welcome_header"
+msgstr "Bem vindo a addons.mozilla.org (AMO)!"
+
+#: views/users/register.thtml:81 views/users/edit.thtml:106
+msgid "user_required_firstlast_or_nickname"
+msgstr "É necessário o primeiro nome, último nome ou uma alcunha."
+
+#: views/users/edit.thtml:94 views/users/edit.thtml:142
+msgid "user_tab_collections"
+msgstr "Colecções"
+
+#: views/users/edit.thtml:95 views/users/edit.thtml:154
+msgid "user_tab_notifications"
+msgstr "Notificações"
+
+#: views/users/edit.thtml:93 views/users/edit.thtml:101
+msgid "user_tab_profile"
+msgstr "Perfil do utilizador"
+
+#: controllers/users_controller.php:209
+msgid "user_verified_okay"
+msgstr "Verificado com Sucesso!"
+
+#: controllers/users_controller.php:723
+msgid "users_delete_pagetitle"
+msgstr "Eliminar conta de utilizador"
+
+#: controllers/users_controller.php:414
+msgid "users_edit_pagetitle"
+msgstr "Editar Conta do Utilizador"
+
+#: views/users/info.thtml:71
+msgid "users_info_aboutme"
+msgstr "Sobre mim"
+
+#: views/users/info.thtml:96
+#, php-format
+msgid "users_info_addons_by_user"
+msgstr "Extras por %1$s"
+
+#: views/users/info.thtml:51
+msgid "users_info_author_name"
+msgstr "Nome"
+
+#: views/users/info.thtml:48
+msgid "users_info_author_profile"
+msgstr "Perfil de Utilizador"
+
+#. %s is the user name
+#: views/users/info.thtml:137
+msgid "users_info_collections_by_user"
+msgstr "Colecções por %s"
+
+#: views/users/info.thtml:66
+msgid "users_info_email"
+msgstr "Endereço de Correio Electrónico"
+
+#: views/users/info.thtml:155
+msgid "users_info_fav_collections_by_user"
+msgstr "Colecções preferidas"
+
+#: views/users/info.thtml:61
+msgid "users_info_homepage"
+msgstr "Página Inicial"
+
+#: views/users/info.thtml:56
+msgid "users_info_nickname"
+msgstr "Alcunha"
+
+#: controllers/users_controller.php:707
+#, php-format
+msgid "users_info_pagetitle"
+msgstr "Info do utilizador para %1$s"
+
+#. %1 is the user's name
+#: views/users/info.thtml:116
+msgid "users_info_reviews_by_user"
+msgstr "Comentário de %s"
+
+#: controllers/users_controller.php:330 controllers/users_controller.php:332
+msgid "users_login_pagetitle"
+msgstr "Início de sessão do utilizador"
+
+#. %1 is the link to the sandbox/policy explanation page
+#. This message is for a specific add-on not found
+#: views/users/login.thtml:53
+#, php-format
+msgid "users_login_sandbox_display_warning"
+msgstr ""
+"O extra que está à procura está actualmente no sandbox. Se já tiver uma "
+"conta em Mozilla Add-ons, por favor entre, ou <a href=\"%1$s\">saiba mais "
+"sobre o sandbox.</a>"
+
+#. %1 is the link to the sandbox/policy explanation page
+#. This message is for any given sandbox-related page not found
+#: views/users/login.thtml:56
+#, php-format
+msgid "users_login_sandbox_page_warning"
+msgstr ""
+"A página que está à procura faz parte do sandbox. Se já tiver uma conta em "
+"Mozilla Add-ons, por favor entre, ou <a href=\"%1$s\">saiba mais sobre o "
+"sandbox.</a>"
+
+#: controllers/users_controller.php:223 controllers/users_controller.php:225
+msgid "users_pwreset_pagetitle"
+msgstr "Reiniciar Senha do Utilizador"
+
+#: controllers/users_controller.php:90 controllers/users_controller.php:92
+msgid "users_register_pagetitle"
+msgstr "Registo de Novo Utilizador"
+
+#. %1$s is an addon name, like <a>Firebug</a>
+#. %2$s is a version number, like <a>1.2</a>
+#: views/versions/license.thtml:52
+msgid "versions_license_header_source"
+msgstr "Licença do código fonte para %1$s %2$s"
+
+#: views/addons/category_landing.thtml:147
+msgid "view_recently_added"
+msgstr "Ver todas as adições recentes"
+
+#: views/addons/category_landing.thtml:161
+msgid "view_top_downloads"
+msgstr "Ver o top de transferências"
+
+#: views/addons/category_landing.thtml:175
+msgid "view_top_rated"
+msgstr "Ver o top de avaliações"
+
+#~ msgid "addon_slider_tooltip_next"
+#~ msgstr "Extra seguinte"
+
+#~ msgid "addon_slider_tooltip_previous"
+#~ msgstr "Extra anterior"
+
+#~ msgid "addon_versions_getlatesttext"
+#~ msgstr "A versão mais recente compatível com"
+
+#~ msgid "addons_display_version_history"
+#~ msgstr "Histórico Completo da Versão"
+
+#~ msgid "addons_home_newest_header"
+#~ msgstr "Mais Recentes:"
+
+#~ msgid "addons_home_popular_header"
+#~ msgstr "Mais Populares:"
+
+#~ msgid "addons_home_recommended_header"
+#~ msgstr "Nós Recomendamos:"
+
+#~ msgid "addons_home_updated_header"
+#~ msgstr "Actualizados recentemente:"
+
+#~ msgid "addons_home_view_all"
+#~ msgstr "Ver Todos"
+
+#~ msgid "category_extra_allrecommended"
+#~ msgstr "Ver todos os extras recomendados"
+
+#~ msgid "category_extra_highestrated"
+#~ msgstr "Avaliação mais Alta Primeiro"
+
+#~ msgid "category_extra_lastupdated"
+#~ msgstr "Os mais Recentemente Actualizados Primeiro"
+
+#~ msgid "category_extra_mostpopular"
+#~ msgstr "Os mais Populares Primeiro"
+
+#~ msgid "collections_detail_js_loading"
+#~ msgstr "A carregar"
+
+#~ msgid "collections_detail_more_info"
+#~ msgstr "Mostrar mais info"
+
+#~ msgid "devcp_additem_firefox_notice"
+#~ msgstr ""
+#~ "Esta versão do seu extra não tem compatibilidade com o Firefox %1$s. A "
+#~ "Mozilla está a contar com o lançamento da próxima versão do Firefox para "
+#~ "breve, por isso teste o seu extra na nova versão e actualize a informação "
+#~ "sobre a compatibilidade. Pode saber mais <a href=\"%2$s\">aqui</a>. Isto "
+#~ "é apenas uma informação e pode continuar a submeter esta versão em addons."
+#~ "mozilla.org."
+
+#~ msgid "devcp_addon_disabled_successfully"
+#~ msgstr "Extra desactivado com sucesso"
+
+#~ msgid "devcp_addon_edit_pagetitle"
+#~ msgstr "Editar Extra"
+
+#~ msgid "devcp_addon_enabled_successfully"
+#~ msgstr "Extra activado com sucesso"
+
+#~ msgid "devcp_addon_field_description_displaytitle"
+#~ msgstr "Descrição do Extra"
+
+#~ msgid "devcp_addon_field_eula_displaytitle"
+#~ msgstr "ALUF"
+
+#~ msgid "devcp_addon_field_homepage_displaytitle"
+#~ msgstr "Página inicial do Extra"
+
+#~ msgid "devcp_addon_field_name_displaytitle"
+#~ msgstr "Nome do Extra"
+
+#~ msgid "devcp_addon_field_privacy_displaytitle"
+#~ msgstr "Política de Privacidade"
+
+#~ msgid "devcp_addon_field_summary_displaytitle"
+#~ msgstr "Sumário do Extra"
+
+#~ msgid "devcp_addon_field_supportemail_displaytitle"
+#~ msgstr "Correio Electrónico de Suporte"
+
+#~ msgid "devcp_addon_field_supporturl_displaytitle"
+#~ msgstr "URL de Suporte"
+
+#~ msgid "devcp_addon_field_versionnotes_displaytitle"
+#~ msgstr "Notas da Versão"
+
+#~ msgid "devcp_addon_nominate_pagetitle"
+#~ msgstr "Nomear Extra"
+
+#~ msgid "devcp_addon_nominated_successfully"
+#~ msgstr "Extra nomeado com sucesso!"
+
+#~ msgid "devcp_addon_status_criteria_review"
+#~ msgstr ""
+#~ "Vários comentários de utilizadores do extra (poderão ser comentários "
+#~ "externos)."
+
+#~ msgid "devcp_addon_submission_makechanges"
+#~ msgstr ""
+#~ "Visite a página do %1$s para fazer alterações à sua submissão, ou %2$s "
+#~ "para voltar ao Painel de Controlo do Desenvolvedor."
+
+#~ msgid "devcp_addon_submission_makechanges_devcp_link"
+#~ msgstr "clique aqui"
+
+#~ msgid "devcp_addon_submission_makechanges_link"
+#~ msgstr "Editar extra"
+
+#~ msgid "devcp_addon_submission_pending"
+#~ msgstr ""
+#~ "Esta versão foi colocada no sandbox enquanto aguarda avaliações dos "
+#~ "sandbox testers e do editor de extras da Mozilla. Será notificado por "
+#~ "correio "
+
+#~ msgid "devcp_addon_submission_sandbox_readmore"
+#~ msgstr "Pode ler mais sobre o Sistema de comentários do Sandbox em %s."
+
+#~ msgid "devcp_addon_submission_sandbox_readmore_link"
+#~ msgstr "aqui"
+
+#~ msgid "devcp_addon_submission_sandboxed"
+#~ msgstr ""
+#~ "Esta versão foi colocada no sandbox para ser utilizada por utilizadores "
+#~ "experientes. De maneira a poder ser apresentado no sítio público, tem de %"
+#~ "s o seu extra e iniciar um processo de avaliação."
+
+#~ msgid "devcp_addon_submission_sandboxed_nominate_link"
+#~ msgstr "nomear"
+
+#~ msgid "devcp_addon_submission_success"
+#~ msgstr "A submissão do seu extra foi efectuada com sucesso."
+
+#~ msgid "devcp_addon_submission_trusted_public"
+#~ msgstr ""
+#~ "Como o seu extra é de cofiança, esta versão foi automaticamente aprovada "
+#~ "para a área pública."
+
+#~ msgid "devcp_addon_submit_pagetitle"
+#~ msgstr "Submeter Extra"
+
+#~ msgid "devcp_addon_updated_successfully"
+#~ msgstr "Extra actualizado com sucesso"
+
+#~ msgid "devcp_addon_upload_preview"
+#~ msgstr "Pode desejar que %s para aumentar o interesse no seu extra."
+
+#~ msgid "devcp_addon_upload_preview_link"
+#~ msgstr "carregar um comentário"
+
+#~ msgid "devcp_author_lookup_none_found"
+#~ msgstr "Nenhum autor encontrado [%s]"
+
+#~ msgid "devcp_author_lookup_remove"
+#~ msgstr "Eliminar"
+
+#~ msgid "devcp_button_cancel"
+#~ msgstr "Cancelar"
+
+#~ msgid "devcp_button_cancel_confirm"
+#~ msgstr "Tem a certeza que deseja cancelar a sua submissão?"
+
+#~ msgid "devcp_button_next"
+#~ msgstr "Seguinte"
+
+#~ msgid "devcp_change_addontype"
+#~ msgstr "Mudar o tipo de extra:"
+
+#~ msgid "devcp_comments_updated"
+#~ msgstr "Comentário actualizado do Developer."
+
+#~ msgid "devcp_details_addpreview_link"
+#~ msgstr "Adicionar pré-visualização"
+
+#~ msgid "devcp_details_author"
+#~ msgstr "Autor"
+
+#~ msgid "devcp_details_authors"
+#~ msgstr "Autores"
+
+#~ msgid "devcp_details_authors_none"
+#~ msgstr "Nenhum"
+
+#~ msgid "devcp_details_categories"
+#~ msgstr "Categorias"
+
+#~ msgid "devcp_details_category"
+#~ msgstr "Categoria"
+
+#~ msgid "devcp_details_description"
+#~ msgstr "Descrição"
+
+#~ msgid "devcp_details_disabled"
+#~ msgstr "Desactivado"
+
+#~ msgid "devcp_details_guid"
+#~ msgstr "GUID"
+
+#~ msgid "devcp_details_header_details"
+#~ msgstr "Detalhes"
+
+#~ msgid "devcp_details_header_devcomments"
+#~ msgstr "Comentários do Developer"
+
+#~ msgid "devcp_details_header_previews"
+#~ msgstr "Pré-visualizações"
+
+#~ msgid "devcp_details_header_versions"
+#~ msgstr "Versões"
+
+#~ msgid "devcp_details_homepage"
+#~ msgstr "Página Inicial"
+
+#~ msgid "devcp_details_homepage_none"
+#~ msgstr "Nenhuma"
+
+#~ msgid "devcp_details_preview_nocaption"
+#~ msgstr "Nenhuma captura"
+
+#~ msgid "devcp_details_previews_nonefound"
+#~ msgstr "Nenhuma pré-visualização encontrada."
+
+#~ msgid "devcp_details_submit_update"
+#~ msgstr "Actualizar"
+
+#~ msgid "devcp_details_supportemail"
+#~ msgstr "Correio Electrónico de Suporte"
+
+#~ msgid "devcp_details_supportemail_none"
+#~ msgstr "Nenhum correio electrónico de suporte fornecido pelo desenvolvedor"
+
+#~ msgid "devcp_details_supporturl"
+#~ msgstr "URL de Suporte"
+
+#~ msgid "devcp_details_supporturl_none"
+#~ msgstr "Nenhum url de suporte fornecido pelo desenvolvedor."
+
+#~ msgid "devcp_details_trusted"
+#~ msgstr "De Confiança"
+
+#~ msgid "devcp_details_versions_none_found"
+#~ msgstr "Nenhuma versão encontrada."
+
+#~ msgid "devcp_disable_cancel"
+#~ msgstr "Cancelar e retroceder"
+
+#~ msgid "devcp_disable_disable_button"
+#~ msgstr "Sim, desactive-o"
+
+#~ msgid "devcp_disable_disable_confirm"
+#~ msgstr "Tem a certeza que deseja desactivar este extra?"
+
+#~ msgid "devcp_disable_disable_description"
+#~ msgstr ""
+#~ "Desactivar este extra irá ocultá-lo das pesquisas e das listagens. Não "
+#~ "poderá ser transferido do sítio web e não terá verificações de "
+#~ "actualização através do cliente . O estra será eliminado efectivamente, "
+#~ "embora possa voltar para aqui e ser novamente activado quando lhe convier."
+
+#~ msgid "devcp_disable_disable_title"
+#~ msgstr "Desactivar %s"
+
+#~ msgid "devcp_disable_enable_button"
+#~ msgstr "Sim, activar"
+
+#~ msgid "devcp_disable_enable_confirm"
+#~ msgstr "Tem a certeza que deseja activar este extra?"
+
+#~ msgid "devcp_disable_enable_description"
+#~ msgstr ""
+#~ "Activar este extra irá fazer com que mais uma vez ele apareça nas listas "
+#~ "de pesquisas. Poderá ser transferido a partir do sítio web assim como das "
+#~ "verificações de actualizações do cliente."
+
+#~ msgid "devcp_disable_enable_title"
+#~ msgstr "Activar %s"
+
+#~ msgid "devcp_edit_author_add"
+#~ msgstr "Adicionar Autor"
+
+#~ msgid "devcp_edit_author_email"
+#~ msgstr "Endereço de Correio Electrónico do Autor"
+
+#~ msgid "devcp_edit_author_remove"
+#~ msgstr "eliminar"
+
+#~ msgid "devcp_edit_error_categories_unavailable"
+#~ msgstr "Nenhuma categoria disponível para este tipo de extra."
+
+#~ msgid "devcp_edit_file_error_incomplete"
+#~ msgstr "Transferência incompleta"
+
+#~ msgid "devcp_edit_file_error_no"
+#~ msgstr "Nenhum ficheiro carregado"
+
+#~ msgid "devcp_edit_file_error_size"
+#~ msgstr "Excede o tamanho máximo de carregamento"
+
+#~ msgid "devcp_edit_header_authors"
+#~ msgstr "Autores"
+
+#~ msgid "devcp_edit_icon_add_link"
+#~ msgstr "Adicionar Ãcone"
+
+#~ msgid "devcp_edit_icon_change_link"
+#~ msgstr "Mudar Ãcone"
+
+#~ msgid "devcp_edit_label_allow_viewsource"
+#~ msgstr "Permitir que os utilizadores vejam online os ficheiros fonte"
+
+#~ msgid "devcp_edit_label_categories"
+#~ msgstr "Categorias"
+
+#~ msgid "devcp_edit_label_defaultlocale"
+#~ msgstr "Idioma Pré-definido"
+
+#~ msgid "devcp_edit_label_icon_delete"
+#~ msgstr "Limpar apenas o ícone existente"
+
+#~ msgid "devcp_edit_label_icon_new"
+#~ msgstr "Novo Ficheiro de Ãcone"
+
+#~ msgid "devcp_edit_label_info"
+#~ msgstr "Ãcone"
+
+#~ msgid "devcp_edit_locale_disambiguation_explanation"
+#~ msgstr ""
+#~ "pequena info adicional (como por exemplo um nome num dialecto local)"
+
+#~ msgid "devcp_edit_submit_update"
+#~ msgstr "Actualizar"
+
+#~ msgid "devcp_edit_target_locale_explanation"
+#~ msgstr ""
+#~ "<a href=\"http://wiki.mozilla.org/L10n:Simple_locale_names\">nome do "
+#~ "idioma simples</a>, tal como 'en-US'"
+
+#~ msgid "devcp_editversion_checkedfiles_delete"
+#~ msgstr "Os ficheiros seleccionados serão eliminados."
+
+#~ msgid "devcp_editversion_filename_size"
+#~ msgstr "%1$s (%2$s)"
+
+#~ msgid "devcp_editversion_label_files"
+#~ msgstr "Ficheiros"
+
+#~ msgid "devcp_editversion_label_targetapps"
+#~ msgstr "Destino das Aplicações"
+
+#~ msgid "devcp_editversion_nofiles"
+#~ msgstr "Nenhuns Ficheiros."
+
+#~ msgid "devcp_editversion_reviewernotes"
+#~ msgstr "Notas para o Avaliador"
+
+#~ msgid "devcp_editversion_submit_update"
+#~ msgstr "Actualizar"
+
+#~ msgid "devcp_error_addon_field_summary_toolong"
+#~ msgstr ""
+#~ "Os sumários estão limitados a um máximo de 250 caracteres.\n"
+#~ "(Você escreveu %s)"
+
+#~ msgid "devcp_error_addonname_not_unique"
+#~ msgstr ""
+#~ "O nome para o seu extra já existe na base de dados. Verifique por favor "
+#~ "que o: <br /><li>Seu GUIDs é igual. A causa mais comum para este erro é "
+#~ "GUIDs diferentes.</li><li>Não tem de duplicar a entrada na base de dados. "
+#~ "Se o fizer, deverá actualizar a entrada ou eliminaá-la e tentar novamente."
+#~ "</li>"
+
+#~ msgid "devcp_error_describe_changes"
+#~ msgstr "Descreva as alterações feitas a esta actualização do extra."
+
+#~ msgid "devcp_error_file_guids_dont_match"
+#~ msgstr "Nem todos os ficheiros de GUIDs são iguais"
+
+#~ msgid "devcp_error_identical_version_exists"
+#~ msgstr "Já existe uma versão idêntica (%s) para este extra e plataforma."
+
+#~ msgid "devcp_error_nominate_message"
+#~ msgstr "Tem de fornecer os seguintes detalhes para nomeação."
+
+#~ msgid "devcp_error_nominate_no_prerelease"
+#~ msgstr "Não pode nomear um extra de pré-lançamento."
+
+#~ msgid "devcp_error_nominate_sandbox_only"
+#~ msgstr "Apenas pode nomear extras que estejam no sandbox."
+
+#~ msgid "devcp_error_saving"
+#~ msgstr "Ocorreu um erro ao tentar guardar os seus dados."
+
+#~ msgid "devcp_error_update_access_denied"
+#~ msgstr "Não tem autorização para actualizar este extra."
+
+#~ msgid "devcp_file_addanother"
+#~ msgstr "Adicione Outro Ficheiro de Plataforma"
+
+#~ msgid "devcp_form_author_add"
+#~ msgstr "Adicionar Autor"
+
+#~ msgid "devcp_form_author_remove"
+#~ msgstr "Eliminar"
+
+#~ msgid "devcp_form_categories_nextstep"
+#~ msgstr ""
+#~ "Categorias para o seu novo extra estarão disponíveis no passo seguinte."
+
+#~ msgid "devcp_form_error_categories_unavailable"
+#~ msgstr "Nenhuma categoria disponível para este tipo de extra."
+
+#~ msgid "devcp_form_error_description_notempty"
+#~ msgstr "Escreva uma descrição do seu extra."
+
+#~ msgid "devcp_form_error_name_required"
+#~ msgstr "Escreva o nome do seu extra."
+
+#~ msgid "devcp_form_error_select_addontype"
+#~ msgstr "Seleccione o tipo de extra que está a submeter."
+
+#~ msgid "devcp_form_error_summary_notempty"
+#~ msgstr "Escreva um sumário para o seu extra."
+
+#~ msgid "devcp_form_label_addonfile"
+#~ msgstr "Ficheiro do Extra"
+
+#~ msgid "devcp_form_label_addonfile2"
+#~ msgstr "Ficheiro do Extra 2"
+
+#~ msgid "devcp_form_label_addonfile3"
+#~ msgstr "Ficheiro do Extra 3"
+
+#~ msgid "devcp_form_label_addontype"
+#~ msgstr "Tipo do Extra"
+
+#~ msgid "devcp_form_label_allow_viewsource"
+#~ msgstr "Permitir que os utilizadores vejam os ficheiros fonte online"
+
+#~ msgid "devcp_form_label_author_email"
+#~ msgstr "Endereço de Correio Electrónico do Autor"
+
+#~ msgid "devcp_form_label_authors"
+#~ msgstr "Autores"
+
+#~ msgid "devcp_form_label_categories"
+#~ msgstr "Categorias"
+
+#~ msgid "devcp_form_label_defaultlocale"
+#~ msgstr "Idioma Pré-definido"
+
+#~ msgid "devcp_form_label_description"
+#~ msgstr "Descrição"
+
+#~ msgid "devcp_form_label_eula"
+#~ msgstr "Licença de Utilizador Final (ALUF)"
+
+#~ msgid "devcp_form_label_externalsoftware"
+#~ msgstr "Este Extra necessiata de software externo"
+
+#~ msgid "devcp_form_label_files"
+#~ msgstr "Ficheiros"
+
+#~ msgid "devcp_form_label_homepage"
+#~ msgstr "Página Inicial"
+
+#~ msgid "devcp_form_label_iconfile"
+#~ msgstr "Ficheiro do Ãcone"
+
+#~ msgid "devcp_form_label_name"
+#~ msgstr "Nome"
+
+#~ msgid "devcp_form_label_platforms"
+#~ msgstr "Plataformas Suportadas"
+
+#~ msgid "devcp_form_label_prerelease"
+#~ msgstr "Isto é um pré-lançamento"
+
+#~ msgid "devcp_form_label_privacy"
+#~ msgstr "Política de Privacidade"
+
+#~ msgid "devcp_form_label_sitespecific"
+#~ msgstr "Isto é um extra específico de um sítio"
+
+#~ msgid "devcp_form_label_summary"
+#~ msgstr "Sumário"
+
+#~ msgid "devcp_form_label_supportemail"
+#~ msgstr "Correio Electrónico de Suporte"
+
+#~ msgid "devcp_form_label_supporturl"
+#~ msgstr "URL de Suporte"
+
+#~ msgid "devcp_form_label_target_applications"
+#~ msgstr "Aplicações de Destino"
+
+#~ msgid "devcp_form_label_version"
+#~ msgstr "Versão"
+
+#~ msgid "devcp_form_label_versionnotes"
+#~ msgstr "Notas da Versão"
+
+#~ msgid "devcp_form_no_target_apps"
+#~ msgstr "Nenhuma"
+
+#~ msgid "devcp_form_reviewernotes"
+#~ msgstr "Notas para o Avaliador"
+
+#~ msgid "devcp_form_trustedaddon_destination"
+#~ msgstr ""
+#~ "Porque o seu extra é de confiança, escolha para onde esta versão deve ir:"
+
+#~ msgid "devcp_form_trustedaddon_destination_public"
+#~ msgstr "Público"
+
+#~ msgid "devcp_form_trustedaddon_destination_sandbox"
+#~ msgstr "Sandbox"
+
+#~ msgid "devcp_header_developer_agreement"
+#~ msgstr "Acordo do Desenvolvedor"
+
+#~ msgid "devcp_header_step1"
+#~ msgstr "Passo 1"
+
+#~ msgid "devcp_header_step1_upload"
+#~ msgstr "Carregar Ficheiro"
+
+#~ msgid "devcp_header_step2"
+#~ msgstr "Passo 2"
+
+#~ msgid "devcp_header_step2_addondetails"
+#~ msgstr "Detalhes do Extra"
+
+#~ msgid "devcp_header_step3"
+#~ msgstr "Passo 3"
+
+#~ msgid "devcp_header_step3_versiondetails"
+#~ msgstr "Detalhes da Versão"
+
+#~ msgid "devcp_header_step4"
+#~ msgstr "Passo 4"
+
+#~ msgid "devcp_header_step4_localization"
+#~ msgstr "Tradução"
+
+#~ msgid "devcp_header_step5"
+#~ msgstr "Passo 5"
+
+#~ msgid "devcp_header_step5_success"
+#~ msgstr "Sucesso"
+
+#~ msgid "devcp_index_header_myaddons"
+#~ msgstr "Os meus Extras"
+
+#~ msgid "devcp_nominate_link_returnto_details"
+#~ msgstr "Voltar aos detalhes do extra"
+
+#~ msgid "devcp_notice_autodetected_addontype"
+#~ msgstr "Tipo de extra detectado automaticamente: %s."
+
+#~ msgid "devcp_notice_different_defaultlocale"
+#~ msgstr ""
+#~ "O idioma por defeito deste extra (%1$s [%2$s]) é diferente do idioma "
+#~ "actualmente seleccionado (%3$s [%4$s]). Os campos abaixo deverão ser "
+#~ "completados em %1$s."
+
+#~ msgid "devcp_question_addontype_incorrect"
+#~ msgstr "Incorrecto?"
+
+#~ msgid "devcp_question_delete_file"
+#~ msgstr "Tem a certeza que deseja eliminar este ficheiro?"
+
+#~ msgid "devcp_skip_reviewing_addon_info"
+#~ msgstr "Saltar a actualização da informação actual do meu extra"
+
+#~ msgid "devcp_submissions_disabled"
+#~ msgstr ""
+#~ "As submissões de Extras estão desactivadas de momento. Por favor volte a "
+#~ "mais tarde."
+
+#~ msgid "devcp_submit_accept_dev_agreement"
+#~ msgstr "Eu Aceito"
+
+#~ msgid "devcp_submit_decline_dev_agreement"
+#~ msgstr "Eu Recuso"
+
+#~ msgid "devcp_summary_admin_disabled"
+#~ msgstr "Este extra foi desactivado por um administrador."
+
+#~ msgid "devcp_summary_header_disabled"
+#~ msgstr "Desactivado"
+
+#~ msgid "devcp_summary_header_trusted"
+#~ msgstr "De Confiança"
+
+#~ msgid "devcp_summary_noaddons_submit_one"
+#~ msgstr "Não tem nenhum extra. Clique %s para submeter um."
+
+#~ msgid "devcp_summary_noaddons_submit_one_link"
+#~ msgstr "aqui"
+
+#~ msgid "devcp_theme_upload_preview"
+#~ msgstr "tenha a certeza de %s para o seu tema."
+
+#~ msgid "devcp_theme_upload_preview_link"
+#~ msgstr "carregar uma pré-visualização"
+
+#~ msgid "devcp_version_edit_pagetitle"
+#~ msgstr "Editar Versão"
+
+#~ msgid "devcp_version_updated_successfully"
+#~ msgstr "Versão actualizada com sucesso."
+
+#~ msgid "editors_submissiontype_new"
+#~ msgstr "Novo"
+
+#~ msgid "editors_submissiontype_updated"
+#~ msgstr "Actualizado"
+
+#~ msgid "editors_th_addon_age"
+#~ msgstr "Idade do extra"
+
+#~ msgid "editors_th_addontypes"
+#~ msgstr "Tipos de Extra"
+
+#~ msgid "editors_th_age"
+#~ msgstr "Idade"
+
+#~ msgid "editors_th_applications"
+#~ msgstr "Aplicações"
+
+#~ msgid "editors_th_platforms"
+#~ msgstr "Plataformas"
+
+#~ msgid "editors_th_submissiontypes"
+#~ msgstr "Tipos de Submissão"
+
+#~ msgid "error_notice"
+#~ msgstr "Notícia"
+
+#~ msgid "forum_save"
+#~ msgstr "Guardar"
+
+#~ msgid "home"
+#~ msgstr "início"
+
+#~ msgid "nav_category_plugins"
+#~ msgstr "Plugins"
+
+#~ msgid "page_title_experimental_addons"
+#~ msgstr "Extras experimentais"
+
+#~ msgid "pages_experimental_addons_backbutton"
+#~ msgstr "Voltar à pagina anterior"
+
+#~ msgid "pagination_page_number_title"
+#~ msgstr "Esta é a página %1$s de %2$s"
+
+#~ msgid "search_matching_addons_number"
+#~ msgid_plural "search_matching_addons_number"
+#~ msgstr[0] "%s extra corresponde"
+#~ msgstr[1] "%s extras correspondem"
+
+#~ msgid "statistics_rss_icon_title"
+#~ msgstr "Fonte RSS para os dados do sumário"
diff --git a/site/app/locale/pt_PT/images/sandbox-review.png b/site/app/locale/pt_PT/images/sandbox-review.png
new file mode 100644
index 0000000..3a0eef1
--- /dev/null
+++ b/site/app/locale/pt_PT/images/sandbox-review.png
Binary files differ
diff --git a/site/app/locale/pt_PT/pages/error404.thtml b/site/app/locale/pt_PT/pages/error404.thtml
new file mode 100644
index 0000000..7b864dc
--- /dev/null
+++ b/site/app/locale/pt_PT/pages/error404.thtml
@@ -0,0 +1,16 @@
+<h1>Pedimos desculpa, mas não encontrámos o que procurava.</h1>
+
+<p>A página ou ficheiro não foi encontrado no nosso sítio. É possível que tenha clicado numa ligação antiga, ou escreveu o endereço incorrectamente.</p>
+
+<ul>
+<li>Se escreveu um endereço, por favor verifique se o escreveu correctamente.</li>
+<li>Se seguiu uma ligação, por favor informe-nos em <a href="mailto:webmaster@mozilla.com" title="Página não encontrada em Mozilla.com">webmaster@mozilla.com</a>. Diga-nos de onde veio e o que estava à procura, e faremos o nosso melhor para o reparar.</li>
+</ul>
+
+<p>Ou pode ir para algumas das páginas populares do nosso sítio web.</p>
+
+<ul>
+<li>Está interessado numa <a href="%1$s">lista de extras populares</a>?</li>
+<li>Deseja <a href="%2$s">procurar extras</a>? Pode ir à <a href="%2$s">página de procura</a> ou então utilize o campo abixo.</li>
+<li>Se deseja começar do início, vá à <a href="%3$s">página inicial dos extras</a>.</li>
+</ul>
diff --git a/site/app/locale/pt_PT/pages/extension_features.thtml b/site/app/locale/pt_PT/pages/extension_features.thtml
new file mode 100644
index 0000000..1043991
--- /dev/null
+++ b/site/app/locale/pt_PT/pages/extension_features.thtml
@@ -0,0 +1,30 @@
+<p>
+ O coleccionador de extras mantêm-o ligado aos seus extras favoritos e
+ colecções de diferentes maneiras:
+</p>
+
+<dl>
+ <dt>Aceda ás suas colecções preferidas através do Firefox</dt>
+ <dd>
+ Colecções que marque como favoritas na
+ <a href="%1$s">Directoria de colecções</a> aparecem numa parte especial do
+ gestor de extras. Poderá manter-se actualizado e ver os conteúdos de cada
+ colecção.
+ </dd>
+ <dt>Partilhe extras com o menu publicar</dt>
+ <dd>
+ Each add-on you install is easily shared with a friend via e-mail or
+ published to one of your collections through a publishing menu.
+ </dd>
+ <dt>Receba notificações</dt>
+ <dd>
+ Collector will alert you when one of your favorite collections has a new
+ item, and mark it for you to review later.
+ </dd>
+
+ <dt>Automatically publish your installed add-ons to a collection</dt>
+ <dd>
+ Auto-publisher functionality keeps your collection continuously updated with
+ your latest add-ons, keeping your friends who subscribe up-to-date.
+ </dd>
+</dl>
diff --git a/site/app/locale/pt_PT/pages/nomination.thtml b/site/app/locale/pt_PT/pages/nomination.thtml
new file mode 100644
index 0000000..4945495
--- /dev/null
+++ b/site/app/locale/pt_PT/pages/nomination.thtml
@@ -0,0 +1,10 @@
+<p>Um extra actualmente no sandbox pode ser nomeado a fazer parte do sítio público e ser disponibilizado a todos os utilizadores após ser revisto por um editor. Para os melhores resultados, tenha atenção ao seguinte:</p>
+<ul>
+ <li>Imagens de pré-visualização são necessárias para temas e altamente recomendadas para todos os outros tipos de extras.</li>
+ <li>O extra deverá ter estado o tempo suficiente no sandbox para acumular avaliações e feedback dos utilizadores. <b>As avaliações terão de ser tornadas públicas.</b></li>
+ <li>Os extras públicos têm uma maior qualidade do que os extras no sandbox e devem melhorar a web.</li>
+ <li>Os critérios de nomeação estão disponíveis em <a href="%s">Política dos Extras</a>.</li>
+</ul>
+<p>Se o seu extra tiver os critérios acima referidos, pode nomeá-lo completando o campo abaixo. Será notificado por correio electrónico sobre o estado da sua nomeação.</p>
+
+<p>Para nomear o seu extra, descreva por favor como foi testado (incluindo que está livre de erros e avisos) e como é útil para a web. Pode também incluir ligações para análises externas sobre o seu extra.</p>
diff --git a/site/app/locale/pt_PT/pages/policy.thtml b/site/app/locale/pt_PT/pages/policy.thtml
new file mode 100644
index 0000000..bc87b8f
--- /dev/null
+++ b/site/app/locale/pt_PT/pages/policy.thtml
@@ -0,0 +1,112 @@
+<h1>Política dos Extras</h1>
+
+<h2>O que é o sandbox?</h2>
+<p>Veja %s.</p>
+
+<h2>Que extras estão no sandbox?</h2>
+<p>O sandbox é para onde todos os extras que são hospedados pela AMO vão de inicialmente. It contains new versions of public add-ons, as well as all versions for add-ons that are not made public. When a new add-on, or an update to an existing add-on, is submitted to AMO, it is placed in the sandbox.</p>
+
+<p>Alguns extras, e as suas versões específicas, são tornados públicos após o proceso de revisão indicar que estão prontos e são apropriados para uso público. Outros extras manter-se-ão indefinidamente no sandbox, onde estão disponíveis para os utilizadores que escolheram navegar através da lista do sandbox e experimentar o software que lá se encontra.</p>
+
+<h2>Como é que os extras se tornam públicos?</h2>
+
+<p>Add-ons are reviewed by AMO users who opt into viewing the sandbox and testing the packages found there. The reviews that AMO users write will indicate whether an add-on is sufficiently useful, well-written and polished to be put in front of all of Firefox's users. These reviews, possibly in addition to other reviews and inspections by the AMO team, are used to determine whether a given add-on should be made public, whether it needs more work to be polished for wider visibility, or whether it's not suitable for promotion on the AMO site outside of the sandbox.</p>
+
+<h2>Como consigo que o meu extra seja promovido ao estado de público?</h2>
+
+<p>Se acredita que o seu extra (assim como o seu comportamento!) cumprem os critérios para um extra público, pode nomeá-lo a partir do painel de controlo do developer.</p>
+
+<h2>Qual é o critério para extras públicos?</h2>
+
+<p>An add-on that's made public on AMO should be of high quality, and give users an improved web experience. We look for the following things when deciding whether an add-on is appropriate for the public side of AMO:</p>
+
+<h3>Você é Responsável?</h3>
+
+<p>We expect that an author who is promoting their add-on to Firefox's many users is responsive to problem reports, maintains their contact information, and updates their add-on promptly to keep current with Firefox releases and changes in AMO policies. This doesn't mean that you have to reply to every question that someone posts in the discussions, or that you even need to fix every bug, but we do expect that you will respond to issues in a manner that's appropriate to the severity of the issue in question.</p>
+
+<h3>O extra está descrito correctamente e facilmente?</h3>
+
+<p>It's of the utmost importance to us that users get what they expect when they try a new add-on. Your description should provide details about what the add-on does, how a user should take advantage of it, and what the user should expect when they install it. Links to external docs for detailed instructions are fine, but the description itself should cover the basics and leave users confident that they know what they'll get.</p>
+
+<p>Also, it is important that you maintain version notes appropriately as you improve and change your add-on. Users should be able to see what's new in an add-on they may have tried previously, and should be made aware of changes that might affect their current use of the add-on when they update. (Right now, users don't see the version notes when they're prompted for an update within the browser, but we'll work to fix that. If you maintain the version notes well, your users will benefit greatly before and after that work is complete.)</p>
+
+<h3>Foram tomadas todas as medidas de segurança e privacidade?</h3>
+
+<p>This is an aspect of a clear and accurate description, but such an important one that we feel it deserves specific mention. Many very useful and well-written add-ons manipulate some form of user data, or can present security hazards if misused; they are welcome on the public portion of AMO, but they must make it very clear to users what risks they might encounter, and what they can do to protect themselves.</p>
+
+<h3>O extra foi bem testado está livre de defeitos sérios ou óbvios?</h3>
+
+<p>One important thing that we look for when considering an add-on for public access is whether its sandbox reviews indicate that it has received thorough testing, and that it doesn't have serious problems or negative impacts on the browser. If reviewers report problems such as major performance issues, crashes, frequent problems using the functions of the add-on, or spamming of messages to the error console, you should take those reports to heart, and re-nominate your add-on after you've addressed them as best you can. We don't expect you to perfectly optimize or have zero bugs -- Firefox itself undergoes constant improvement in these areas -- but we do want you to take reasonable efforts to minimize downsides, and to clearly call out cases where users may be surprised by those that remain.</p>
+
+<p>If your add-on has been tested outside of the AMO Sandbox process, such as by a group of users of your service or an in-house QA team, you should indicate that in your nomination message. It certainly helps us establish what the level of testing has been, and can help get your add-on up on the site.</p>
+
+<h3>O extra assim como o seu autor tratam o utilizador com respeito?</h3>
+
+<p>Your software should not intrude on the user unnecessarily, try to trick the user, or conceal any of its activities from the user. Users (or even non-users) are sometimes rude in their comments, and while we will do our best to filter those out as they're reported to us, we do expect that authors will avoid retaliating with rudeness of their own.</p>
+
+<h3>Is the add-on useful to an appropriately wide portion of Firefox's users?</h3>
+
+<p>Your add-on doesn't need to be the next Greasemonkey or FireBug, but if it is only useful to people at your company or who are part of a small web community, we may feel that it's not yet appropriate to put it in front of all of Firefox's users.</p>
+
+<p>We are constantly looking at ways to improve the organization of the site to better accommodate add-ons that are exemplary in other ways, but are aimed at only a small community of potential users. Correctly categorizing and maintaining the metadata of your add-on will help us figure out how we can surface more of those sorts of add-ons to people who are most likely to benefit from them.</p>
+
+<p>If your add-on just provides bookmarks or other simple access points to your site, it's probably not
+appropriate for the public part of the site. Like the rest of the Mozilla project, we love web applications and
+new web services, but Firefox add-ons should provide an improved browsing experience for the user and not just be a way to promote a new site or service through an AMO listing. If the description for your add-on is mostly about the service rather than the improvements it makes to the user's browser experience, you're probably not on the right track.</p>
+
+<h3>O extra está livre de marcas registadas ou de direitos de cópia?</h3>
+
+<p>Though you may mean no harm to the holder of a trademark, or the owner of a copyrighted work, we can't host add-ons that infringe on trademarks or copyrights. If you don't have permission to use a trademarked name or image, please do not submit your add-on to AMO. If your add-on includes code that is copyrighted by someone else, and is not licensed to you to use in your add-on, please do not submit your add-on to AMO. (If the holder of a trademark or copyright objects to the use of their trademark, we will very likely have to have the request for removal reviewed by counsel, and we will remove the add-on if it's deemed legally necessary. This is an expensive process in terms of the project's resources, including time and money, so we ask you to be respectful and not cause us undue difficulty.)</p>
+
+<p>If you're not sure if the name of your add-on, or use of something within it, will prevent it from being listed on the site, you can ask amo-editors@mozilla.org for guidance. IMPORTANT: Please note that this group is not able to provide legal advice, and that even if we feel that your usage is acceptable, we may revisit that decision in light of complaints from rights-holders and advice from legal counsel.</p>
+
+<p>In terms of reuse of source code from other add-ons, if the author has not clearly stated that you are permitted to use her code in your own work -- such as by placing it under an open source license -- then you should assume that you do not have the right to do so. You can contact the author to seek such permission, but we can't provide you with any special rights to it just because it's been on AMO, or because the author isn't responding to your request. (And, again, we can't provide legal advice, just advice about how your add-on is likely to interact with the policies of the site.)</p>
+
+<p>This applies to the Mozilla Foundation's trademarks as well, including "Mozilla", "Firefox", and "Thunderbird". The Mozilla policy on trademark use is designed to protect against confusion, and prevent the trademarks from being overturned due to lack of protection; please respect the need for such protection, and help us preserve some of the most valuable assets of the Mozilla Foundation.</p>
+
+<h2>O que acontece depois de EU nomear algo?</h2>
+
+<p>Once your add-on has been nominated, it is evaluated by a team of AMO Editors according to the criteria described above. If it is deemed ready for public display, it will be pushed to the public side once it has been evaluated, and you will receive an email notification.</p>
+
+<p>If we feel that the add-on isn't appropriate for the public side of AMO at this time, you'll receive an email notification indicating why, and your nomination will be removed from the queue. If and when you feel that you've addressed the concerns expressed in that notification, and you want to be evaluated again, you can do so at your discretion. Repeated nominations without meaningful improvements in the add-on are not looked upon with favour, so please do exercise discretion; you are more likely to anger us than to wear us down.</p>
+
+<h2>Posso nomear os extras de outra pessoa?</h2>
+
+<p>Currently, we ask that an add-on's author nominate their own work for publication. We want to make sure that the author is comfortable with the increased exposure and that feel the add-on in its current state appropriately reflects the quality of their work. If you believe that an add-on is polished, that the author is abiding by the letter and spirit of the AMO policies, and that it would benefit Firefox, our users, and the web in general to have it made available to nearly a hundred million users around the world, you should feel free to encourage the author of the add-on to nominate their creation.</p>
+
+<h2>O meu extra esteve muito tempo em espera após nomeação, será que não gostam de mim?</h2>
+
+<p>Nós não o odiamos. Adoramos developers de extras, e trabalhamos árduamente para os tornar productivos e satisfeitos, para que utilizadores por todo o mundo beneficiem do seu trabalho. Mas estar no lado público da AMO tem valor precisamente porque nós temos cuidado com o que para lá vai, por isso não podemos acelerar apenas para o tornar mais rápido. Nós sabemos que pode ser frustante esperar até que o seu extra seja avaliado, e desejamos que o espaço de tempo seja o mais curto possível. Quantas mais pessoas fornecerem revisões detalhadas e claras de extras no sandbox, mais fácil e fazer essas avaliações, por isso pode considerar em ajudar nesse campo se estiver interessado.</p>
+
+<h2>Encontrei um grande problema no meu extra e quero resolvê-lo o mais rápidamente possível. O que posso fazer?</h2>
+
+<p>If there is a serious bug (security, stability, major functionality problem) in an add-on for which you need to get an update out promptly, you should indicate that in the "reviewer notes" when submitting the update -- as well as in the version notes, obviously! You may also want to enlist some existing users of your add-on to test the update and report their results in detail in the sandbox. Popping into #addons on irc.mozilla.org can help make people aware of the situation, but please be patient and polite if you do so.</p>
+
+<p>Por favor não chore. We try to jump quickly on high-priority updates, but it costs us time evaluating other nominated add-ons or versions, and often it costs us sleep or time with our families and friends, so we take a dim view of people who try to take advantage of this mechanism to "jump the queue". If you're not sure whether you should go this route, asking on #addons on irc.mozilla.org may well help you decide.
+
+<h2>Penso que fui tratado incorrectamente na avaliação do meu extra. O que posso fazer?</h2>
+
+<p>If you believe that your add-on was incorrectly evaluated, and that it was denied public status in error, you should send an email to amo-editors@mozilla.org with the details of your reasoning. Please be polite and clear in your email, and make sure that you have specifics about how the add-on was misjudged.</p>
+
+<p>(If you have fixed *all* the things that were listed as problems in your notification mail, you shouldn't appeal the evaluation, but should instead re-nominate for consideration through the Developer Control Panel.)</p>
+
+<h2>O meu extra era público mas agora está no sandbox. O que aconteceu? </h2>
+
+<p>If an add-on no longer meets the criteria for being on the public side of the site, we may move it back to the sandbox. Unless we are legally prevented from doing so, we will notify you by email when that happens, and indicate the reasons for doing so.</p>
+
+<p>It's also possible that you've found a bug in the site, in which case you should report it via Bugzilla; use the "addons.mozilla.org" product and the "Public Pages" component for your report, and include as much detail as you can.</p>
+
+<h2>O meu extra é público e parece que as pessoas o adoram. Como posso entras na lista dos extras recomendados?</h2>
+
+<p>If you believe that your add-on is a shining example of the power of add-ons, that it demonstrates and furthers Mozilla's values for the extensible and user-controlled web, and that it provides a great user experience, you can ask to have it considered for addition to the list of recommended add-ons. To do this, you should send an email to amo-editors@mozilla.org explaining why your add-on is great.</p>
+
+<p>O seu correio deve incluir <b>pelo menos</b> informação sobre o seguinte:</p>
+<ul>
+<li>como é que a experiência na web é aumentada para os utilizadores</li>
+<li>como é que o seu extra é apropriado para a grande parte dos utilizadores do Firefox</li>
+<li>como é que o seu extra demonstra e/ou serve os valores do projecto Mozilla, especialmente no que respeita a colocar o utilizador com, protecção da privacidade e segurança, acesso universal à web, dados e standards abertos</li>
+<li>como é que o seu extra é diferente de extras parecidos (na medida em que ambos são bons e maus)</li>
+<li>qual a reacção que observou dos utilizadores, revisores, bloggers, astronautas e até dos seus animais de estimação, tanto positivas como negativas</li>
+</ul>
+
+<p>Quanto mais completa for a informação fornecida no seu pedido mais facilmete o poderemos garantir, ainda que uma fantástica e bem escrita aplicação não é garantia de colocação na lista dos recomendados. Por último , a lista tem de ser -- e é -- mantida á disposição da Mozilla, e a protecção e experiência do utilizador tem de estar acima de tudo o resto.</p>
diff --git a/site/app/locale/pt_PT/pages/sandbox.thtml b/site/app/locale/pt_PT/pages/sandbox.thtml
new file mode 100644
index 0000000..2bc71c1
--- /dev/null
+++ b/site/app/locale/pt_PT/pages/sandbox.thtml
@@ -0,0 +1,13 @@
+<h1>Sistema de Avaliação Sandbox</h1>
+<h2>O que é o sandbox?</h2>
+<p>O sandbox é uma área para os utilizadores avançados testarem os Extras antes de serem revistos para uso geral. Para poder aceder ao sandbox, tem de o activar nas definições da sua conta. é preciso ter cuidado ao instalar extras do sandbox, pois eles não foram testados por um editor e poderão causar problemas ao seu computador.</p>
+
+<h2>Como posso fazer com que o meu extra esteja no lado público?</h2>
+<!-- To localize the flowchart image, see http://wiki.mozilla.org/Update:Remora_Sandbox_Flowchart -->
+<div style="text-align: center;">%s</div>
+<ol>
+ <li><b>Submeta o seu extra no Painel de Controlo de Desenvolvimento.</b> O seu item irá aparecer imediatamente no "Sandbox" dos Extras da Mozilla, onde utilizadores experientes o irão avaliar e dar feedback. Para poder ver o sandbox, terá que o activar nas definições da sua conta.</li>
+ <li><b>Nomeie o seu extra para ser público.</b> A partir do Painel de Controlo de Desenvolvimento, existe uma ligação para nomear o seu extra. Após nomeação, o seu extra irá aparecer no Editor Nomination Queue para revisão.</li>
+ <li><b>Um editor faz a avaliação ao seu extra.</b> Um editor de Extras da Mozilla irá instalar o seu extra e verificará se funciona. O editor irá também ver as avaliações dadas no sandbox.</li>
+ <li><b>O seu extra é tornado público ou é retido no sandbox.</b> O editor irá tornar o seu extra público ou rete-lo-á no sandbox. Se retido no sandbox, poderá nomeá-lo de novo após efectuar as alterações sugeridas pelo editor nos comentários. Se tornados públicos, as futuras versões do seu extra irão aparecer no sandbox até serem revistas por um editor e tornadas públicas. Uma vez o extra público, não é necessário voltar a nomeá-lo - as versões futuras ficarão automaticamente em espera para revisão.</li>
+</ol> \ No newline at end of file
diff --git a/site/app/locale/pt_PT/pages/submission_help.thtml b/site/app/locale/pt_PT/pages/submission_help.thtml
new file mode 100644
index 0000000..ab4b9d9
--- /dev/null
+++ b/site/app/locale/pt_PT/pages/submission_help.thtml
@@ -0,0 +1,35 @@
+<h1>Ajuda da Submissão</h1>
+Os campos obrigatórios são <b>bold</b>. Os campos opcionais são <i>italicized</i>.
+<h2 id="step1">Passo 1: Carregar</h2>
+<ul class="submissionHelp">
+ <li><span class="required">Tipo de Extra</span> - Por defeito, o tipo de extra será automaticamente detectado baseado no tipo de ficheiro carregado. Não tem que alterar este campo.</li>
+ <li><span class="required">Ficheiro do Extra</span> - O pacote de ficheiros do seu extra, completo com um ficheiro install.rdf. Se o ficheiro apenas funciona com uma plataforma específica, seleccionar essa plataforma irá permitir que os ficheiros sejam carregados imediatamente.</li>
+ <li><span class="optional">Ãcone do Ficheiro</span> - O ficheiro do ícone é apresentado perto do nome do extra na sua página de apresentação e é mostrado no diálogo da instalação do extra. Será redimensionado auomaticamente para 32x32 pixéis, mantendo a aparência.</li>
+ <li><span class="required">Idioma pré-definido</span> - O idioma por defeito do extra é o idioma principal. Se o idioma seleccionado por um utilizador não estiver disponível, as traduções irão indicar para o idioma pré-definido.</li>
+ <li><span class="optional">Saltar o teste à informação do meu extra</span> - Se estiver a actualizar um extra existente, este campo irá aparecer. Seleccionar a caixa irá fazer saltar o passo 3 onde pode escrever a informação específica da versão.</li>
+</ul>
+
+<h2 id="step2">Passo 2: Detalhes do Extra</h2>
+<ul class="submissionHelp">
+ <li><span class="required">Nome</span> - Nome do extra no idioma pré-definido.</li>
+ <li><span class="required">Autor</span> - Todos os utilizadores que têm acesso a modificar a lista do extra e que serão apresentados como autores na página de apresentação.</li>
+ <li><span class="required">Categorias</span> - Categorias aplicáveis ao extra.</li>
+ <li><span class="optional">Página inicial</span> - O sítio web do extra no idioma pré-definido.</li>
+ <li><span class="required">Sumário</span> - Um resumo rápido do extra no idioma pré-definido. Este campo tem um máximo de 250 caracteres, e irá ser apresentado na página do extra, assim como nos resultados de procura/navegação.</li>
+ <li><span class="required">Descrição</span> - Uma descrição do extra no idioma pré-definido. Isto irá aparecer na página de apresentação do extra por baixo do sumário.</li>
+ <li><span class="optional">EULA</span> - The End User License Agreement that users will be required to accept before downloading, no idioma pré-definido.</li>
+ <li><span class="optional">Política de Privacidade</span> - A Política de Privacidade do extra, no idioma pré-definido. A política de Privacidade explica o que é feito com a informação do utilizador final, e estará ligada a seguir ao botão instalar na página de apresentação de um extra. Está disponível em <a href="%s">Política do Extra</a> informação adicional sobre o que deverá estar incluído na Política de Privacidade e se o seu extra precisa de um ou não.</li>
+ <li><span class="optional">Permitir que os utilizadores vejam os ficheiros fonte online</span> - Seleccionar esta caixa permite ao utilizadores explorar os ficheiros fonte do seu extra online.</li>
+ <li><span class="optional">Isto é um pré-lançamento</span> - Seleccionar esta caixa indica que o extra é um pré-lançamento ou uma versão "beta". Extras de pré-lançamento têm de permanecer no sandbox e não podem ser nomeados para o público até que a etiqueta seja removida.</li>
+ <li><span class="optional">Isto é um extra específico de um sítio</span> - Seleccionar esta caixa indica que o extra é específico a um sítio web, tal como um extra que altera a aparência do sítio web ou apresenta conteúdo específico de um sítio web. Este campo é importatnte para os editores e pode ser utilizado para filtrar pesquisas no futuro.</li>
+ <li><span class="optional">Este extra necessita de software externo</span> - Seleccionar esta caixa indica que o extra necessita de software externo. Este campo é importatnte para os editores e pode ser utilizado para filtrar pesquisas no futuro.</li>
+</ul>
+
+<h2 id="step3">Passo 3: Detalhes da Versão</h2>
+<ul class="submissionHelp">
+ <li><span class="required optional">Notas da versão</span> - Um sumário da lista de alterações nesta versão. Isto é opcional para novas submissões, mas necessário para actualizações.</li>
+ <li><span class="optional">Notas ao Revisor</span> - Este campo é utilizado para comunicar informação aos editores que irão rever o seu extra. Informação sobre testes e notas especiais deverão aqui ficar.</li>
+</ul>
+
+<h2 id="step4">Passo 4: Tradução</h2>
+Aqui é onde os campos do extra poderão ser traduzidos para todos os idiomas suportados. Clique num idioma para introduzir as traduções. \ No newline at end of file
diff --git a/site/app/locale/ro/LC_MESSAGES/messages.mo b/site/app/locale/ro/LC_MESSAGES/messages.mo
new file mode 100644
index 0000000..cdb206e
--- /dev/null
+++ b/site/app/locale/ro/LC_MESSAGES/messages.mo
Binary files differ
diff --git a/site/app/locale/ro/LC_MESSAGES/messages.po b/site/app/locale/ro/LC_MESSAGES/messages.po
new file mode 100644
index 0000000..3cc01ac
--- /dev/null
+++ b/site/app/locale/ro/LC_MESSAGES/messages.po
@@ -0,0 +1,7037 @@
+msgid ""
+msgstr ""
+"Project-Id-Version: addons.mozilla.org\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2009-01-16 11:45-0800\n"
+"PO-Revision-Date: 2009-06-08 12:10+0300\n"
+"Last-Translator: alexxed <alexxed@gmail.com>\n"
+"Language-Team: Romanian <LL@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=3; plural=n==1 ? 0 : (n==0 || (n%100 > 0 && n%100 < "
+"20)) ? 1 : 2;\n"
+"X-Generator: Narro 0.9.4 on http://tradu.softwareliber.ro\n"
+
+#: views/addons/policy.thtml:98
+msgid "a_cancel_installation"
+msgstr "Anulează instalarea"
+
+#. This is the text that appears on buttons to download add-ons.
+#. %$1s is an optional string that only appears if the add-on is only available for
+#. a certain platform. Examples: (Windows) or (Linux)
+#. Note that the parentheses are included in the string. :(
+#: views/elements/amo2009/install.thtml:126
+#: views/elements/amo2009/install.thtml:227
+#: views/elements/amo2009/install.thtml:257
+#: views/elements/amo2009/install.thtml:300
+#: views/elements/amo2009/install.thtml:312 views/elements/install.thtml:73
+#: views/elements/install.thtml:181 views/elements/install.thtml:205
+#: views/elements/install.thtml:248 views/elements/install.thtml:260
+#: views/addons/plugins.thtml:66 views/addons/plugins.thtml:76
+#: views/addons/plugins.thtml:86 views/addons/plugins.thtml:96
+#: views/addons/plugins.thtml:119
+#, php-format
+msgid "a_download"
+msgstr "Descarcă acum %s"
+
+#: views/addons/policy.thtml:72
+msgid "a_eula_download"
+msgstr "Acceptă și descarcă"
+
+#: views/addons/policy.thtml:74
+msgid "a_eula_install"
+msgstr "Accept, instalează"
+
+#: views/elements/header.thtml:76 views/elements/header.thtml:82
+#: views/api/api_addon.thtml:55 views/api/collections_feed.thtml:75
+#: views/sharing_api/addon.thtml:64
+msgid "a_header_public"
+msgstr "Public"
+
+#: views/elements/header.thtml:58 views/elements/header.thtml:75
+#: views/elements/header.thtml:80 views/api/api_addon.thtml:57
+#: views/api/collections_feed.thtml:77 views/sharing_api/addon.thtml:66
+msgid "a_header_sandbox"
+msgstr "Cutia cu nisip"
+
+#. %s is a date in the _('date') format
+#: views/elements/amo2009/homepage_addon.thtml:115
+#: views/elements/addon_listitem.thtml:122 views/elements/feature.thtml:106
+#: views/addons/display.thtml:104 views/addons/browse_thumbs.thtml:73
+msgid "addon_detail_last_updated"
+msgstr "Actualizat în %s"
+
+#. %s is the version of the add-on. Example: 3.2a1
+#: views/elements/amo2009/addon_version_detail.thtml:51
+#: views/elements/addon_version_detail.thtml:51
+#, php-format
+msgid "addon_display_header_version"
+msgstr "Versiunea %s"
+
+#: views/addons/browse_thumbs.thtml:80
+msgid "addon_downloads"
+msgstr "descărcări"
+
+#: views/addons/display.thtml:147
+msgid "addon_downloads_total"
+msgstr "descărcări în total"
+
+#: views/elements/amo2009/homepage_addon.thtml:106
+#: views/elements/addon_listitem.thtml:115 views/elements/feature.thtml:101
+#: views/addons/category_landing.thtml:157 views/addons/display.thtml:146
+#: views/addons/browse_thumbs.thtml:80
+msgid "addon_downloads_weekly"
+msgstr "descărcări pe săptămână"
+
+#. %1 is the add-on count, %2 the category name
+#: views/addons/browse_thumbs.thtml:104 views/addons/browse.thtml:60
+#, php-format
+msgid "addon_list_category_totalcount"
+msgid_plural "addon_list_category_totalcount"
+msgstr[0] "%1$s supliment"
+msgstr[1] "%1$s suplimente"
+msgstr[2] "%1$s de suplimente"
+
+#: views/elements/amo2009/addon_list_options.thtml:103
+#: views/elements/pagination.thtml:67
+#: views/elements/addon_list_options.thtml:94
+msgid "addon_list_perpage"
+msgstr "per pagină"
+
+#: views/elements/amo2009/addon_list_options.thtml:84
+#: views/elements/addon_list_options.thtml:98
+msgid "addon_list_sortby"
+msgstr "Sortează după:"
+
+#: views/helpers/addons_html.php:568 views/elements/amo2009/install.thtml:321
+#: views/elements/feature.thtml:89
+msgid "addon_listitem_flag_experimental"
+msgstr "experimental"
+
+#: views/helpers/addons_html.php:570
+msgid "addon_listitem_flag_recommended"
+msgstr "recomandat"
+
+#. %1 is the add-on name, %2 is the platform
+#: views/pages/js_constants.js.thtml:66
+msgid "addon_not_available_for_platform"
+msgstr "%1$s nu este disponibil pentru %2$s."
+
+#. %1 is the add-on name
+#: views/addons/policy.thtml:101 views/addons/previews.thtml:60
+#: views/addons/versions.thtml:130 views/reviews/flag.thtml:61
+#: views/reviews/add.thtml:114 views/reviews/display.thtml:216
+#: views/reviews/review_added.thtml:57
+#, php-format
+msgid "addon_review_a_back_to_addon_x"
+msgstr "ÃŽnapoi la %1$s..."
+
+#. %1 is the add-on name
+#: views/reviews/flag.thtml:60 views/reviews/add.thtml:113
+#: views/reviews/review_added.thtml:56
+#, php-format
+msgid "addon_review_a_back_to_reviews"
+msgstr "ÃŽnapoi la recenzii..."
+
+#: views/reviews/add.thtml:85
+msgid "addon_review_add_rating_field"
+msgstr "Notă de apreciere:"
+
+#: views/reviews/add.thtml:102
+msgid "addon_review_add_review_field"
+msgstr "Recenzie:"
+
+#: views/reviews/add.thtml:107
+msgid "addon_review_add_submit"
+msgstr "Trimite recenzia"
+
+#. %s is the name of the add-on
+#: views/reviews/add.thtml:51
+#, php-format
+msgid "addon_review_add_title"
+msgstr "Adăugare recenzie pentru %s"
+
+#: views/reviews/add.thtml:78
+msgid "addon_review_add_title_field"
+msgstr "Titlu/Sumar:"
+
+#: views/reviews/display.thtml:77 views/reviews/display.thtml:161
+msgid "addon_review_admin_delete"
+msgstr "Șterge"
+
+#: views/reviews/display.thtml:76
+msgid "addon_review_author_reply_link"
+msgstr "Răspunde"
+
+#: views/reviews/delete.thtml:62
+msgid "addon_review_confirm_delete"
+msgstr "Sigur doriți să ștergeți această recenzie?"
+
+#: views/reviews/delete.thtml:63
+msgid "addon_review_confirm_no"
+msgstr "Nu"
+
+#: views/reviews/delete.thtml:64
+msgid "addon_review_confirm_yes"
+msgstr "Da"
+
+#: views/reviews/delete.thtml:48
+msgid "addon_review_delete_header"
+msgstr "Ștergere recenzie"
+
+#: controllers/reviews_controller.php:449
+msgid "addon_review_deleted_successfully"
+msgstr "Recenzia a fost ștearsă cu succes."
+
+#. %s is the name of the add-on
+#: views/reviews/add.thtml:51
+#, php-format
+msgid "addon_review_edit_title"
+msgstr "Editare recenzie pentru %s"
+
+#. %1 is the count of characters entered as notes for the review flag reason.
+#: controllers/reviews_controller.php:539
+msgid "addon_review_flag_error_other_length"
+msgstr ""
+"Eroare la marcarea recenziei: Notele pentru recenzii sunt limitate la minim "
+"10 și maxim 100 de caractere; numărul de caractere din nota dumneavoastră "
+"este %1$s."
+
+#. Removing an extra comma
+#: views/reviews/review_added.thtml:53
+msgid "addon_review_in_moderation"
+msgstr ""
+"Notați vă rugăm: Înainte ca recenzia dumneavoastră să apară pe saitul public, "
+"ea va fi moderată de un editor."
+
+#: views/reviews/add.thtml:57
+msgid "addon_review_in_reply_to"
+msgstr "Răspunsul dezvoltatorului către:"
+
+#. %1 is the review count, %2 is the nickname or full name of the user.
+#: views/reviews/display.thtml:131
+#, php-format
+msgid "addon_review_others_by_user"
+msgid_plural "addon_review_others_by_user"
+msgstr[0] ""
+"Vedeți și %1$s recenzie anterioară făcută de %2$s pentru acest supliment."
+msgstr[1] ""
+"Vedeți și %1$s recenzii anterioare făcută de %2$s pentru acest supliment."
+msgstr[2] ""
+"Vedeți și %1$s recenzii anterioare făcută de %2$s pentru acest supliment."
+
+#. %1 is the add-on name
+#: controllers/reviews_controller.php:201
+#: controllers/reviews_controller.php:250
+#: controllers/reviews_controller.php:345
+#: controllers/reviews_controller.php:424
+#, php-format
+msgid "addon_review_pagetitle"
+msgstr "Recenzii pentru %s"
+
+#. %1 is the user, %2 is the (localized) date
+#: views/reviews/display.thtml:160
+#, php-format
+msgid "addon_review_reply_on_x_by_y"
+msgstr "%1$s a răspuns în %2$s"
+
+#: views/reviews/display.thtml:157
+msgid "addon_review_reply_prefix"
+msgstr "Răspunsul dezvoltatorului: "
+
+#: views/reviews/review_added.thtml:51
+msgid "addon_review_saved_successfully"
+msgstr "Recenzia dumneavoastră a fost salvată cu succes. Mulțumim!"
+
+#: views/addons/display.thtml:354 views/reviews/display.thtml:72
+msgid "addon_reviewed_by_u_on_d"
+msgstr "de %1$s în %2$s"
+
+#. %1 is the user, %2 is the (localized) date, %3 is the rating
+#: views/editors/reviews_queue.thtml:57 views/editors/reviews_queue.thtml:68
+#: views/reviews/add.thtml:63 views/reviews/delete.thtml:54
+#, php-format
+msgid "addon_reviewed_on_x_rated_y"
+msgstr "de %1$s în %2$s (notat cu %3$s)"
+
+#: views/elements/amo2009/addon_version_detail.thtml:52
+#: views/elements/addon_version_detail.thtml:52
+msgid "addon_version_permalink"
+msgstr "Legătură permanentă la această versiune"
+
+#. %1 is the current Application name (e.g. Firefox)
+#. %2 is the Application's version number
+#: views/addons/versions.thtml:140
+msgid "addon_versions_getlatestversion"
+msgstr "Cea mai recentă versiune compatibilă cu %1$s %2$s"
+
+#: views/addons/display.thtml:447
+msgid "addons_author_addons_submit"
+msgstr "Du-te"
+
+#: views/elements/amo2009/homepage_addon.thtml:100
+#: views/elements/feature.thtml:95
+msgid "addons_author_tooltip"
+msgstr "Vezi profilul autorului"
+
+#. %1 is the name of the Application (eg. Firefox)
+#: controllers/addons_controller.php:1296
+msgid "addons_browse_all_themes_title"
+msgstr "Răsfoiți toate temele :: Suplimente %1$s"
+
+#. %s is the name of the category
+#: controllers/addons_controller.php:1016
+#, php-format
+msgid "addons_browse_browse_category"
+msgstr "Uitați-vă la %s"
+
+#. %1 is the name of the theme category (eg. Modern)
+#. %2 is the name of the Application (eg. Firefox)
+#: controllers/addons_controller.php:664
+msgid "addons_browse_categories_header_theme"
+msgstr "Răsfoiți %1$s teme :: Suplimente %2$s"
+
+#: views/addons/display.thtml:249
+msgid "addons_display_a_license_what"
+msgstr "Ce e asta?"
+
+#: views/reviews/display.thtml:222
+msgid "addons_display_add_review"
+msgstr "Scrieți o recenzie"
+
+#: views/addons/display.thtml:294
+msgid "addons_display_advanced_details"
+msgstr "Mai multe detalii"
+
+#: views/addons/display.thtml:98
+msgid "addons_display_categories"
+msgstr "Categorii"
+
+#: views/addons/display.thtml:482
+msgid "addons_display_collection_add"
+msgstr "Adaugă la o colecție:"
+
+#: views/addons/display.thtml:491
+msgid "addons_display_collection_add_new"
+msgstr "Colecție nouă..."
+
+#: views/addons/display.thtml:487
+msgid "addons_display_collection_add_select_one"
+msgstr "Selectați o colecție..."
+
+#: views/addons/display.thtml:493
+msgid "addons_display_collection_add_submit"
+msgstr "Publică"
+
+#. %1$s is the add-on name
+#. %2$s is the collection name, linked to the collection's page
+#: views/pages/js_constants.js.thtml:103 views/addons/display.thtml:61
+msgid "addons_display_collection_publish_success"
+msgstr "%1$s a fost adăugat la colecția %2$s."
+
+#: views/addons/display.thtml:483
+msgid "addons_display_collection_whatsthis"
+msgstr "Ce e asta?"
+
+#. %1$s is a number
+#: views/addons/display.thtml:473
+msgid "addons_display_collections_more"
+msgid_plural "addons_display_collections_more"
+msgstr[0] "și încă %1$s colecție"
+msgstr[1] "și încă %1$s colecții"
+msgstr[2] "și încă %1$s de colecții"
+
+#: views/addons/display.thtml:403
+msgid "addons_display_detailed_review"
+msgstr "recenzie detaliată"
+
+#: views/reviews/add.thtml:89 views/reviews/add.thtml:90
+msgid "addons_display_dont_like_it"
+msgstr "Nu-mi place"
+
+#: views/reviews/display.thtml:220
+msgid "addons_display_edit_review"
+msgstr "Editați-vă recenzia"
+
+#: views/addons/display.thtml:132
+msgid "addons_display_has_privacy"
+msgstr "Acest supliment are o politică de confidențialitate."
+
+#: views/reviews/add.thtml:87 views/reviews/add.thtml:88
+msgid "addons_display_hate_it"
+msgstr "Groaznic"
+
+#: views/addons/display.thtml:462
+msgid "addons_display_header_collections"
+msgstr "Colecții asemănătoare"
+
+#: views/addons/display.thtml:297
+msgid "addons_display_header_developer_comments"
+msgstr "Comentariile dezvoltatorului"
+
+#: views/addons/display.thtml:230
+msgid "addons_display_header_homepage"
+msgstr "Pagina suplimentului"
+
+#: views/addons/display.thtml:247 views/addons/versions.thtml:110
+msgid "addons_display_header_license"
+msgstr ""
+
+#: views/addons/display.thtml:337
+msgid "addons_display_header_reviews"
+msgstr "Recenzii"
+
+#: views/addons/display.thtml:261
+msgid "addons_display_header_support"
+msgstr "Suport"
+
+#: views/reviews/add.thtml:91 views/reviews/add.thtml:92
+msgid "addons_display_like_it"
+msgstr "ÃŽmi place"
+
+#: views/addons/display.thtml:210
+msgid "addons_display_long_description"
+msgstr "Descriere lungă"
+
+#: views/reviews/add.thtml:95 views/reviews/add.thtml:96
+msgid "addons_display_love_it"
+msgstr "Nu pot trăi fără"
+
+#: views/addons/display.thtml:178
+msgid "addons_display_more_images"
+msgstr "Mai multe imagini"
+
+#: views/addons/display.thtml:465
+msgid "addons_display_nocollections"
+msgstr "Acest supliment nu este încă în nicio colecție."
+
+#. %1$s is either an author's name or a comma separated list of authors. Using
+#. the list doesn't make sense in the English plural form so we ignore the
+#. variable.
+#: views/addons/display.thtml:436
+msgid "addons_display_other_addons_by"
+msgid_plural "addons_display_other_addons_by"
+msgstr[0] "Alte suplimente create de %1$s"
+msgstr[1] "Alte suplimente de acești autori"
+msgstr[2] "Alte suplimente de acești autori"
+
+#. %s is the name of the add-on and the add-on section. Example:
+#. Some Add-on :: Firefox Add-ons
+#. This should not be concatenated in the code and should be fixed.
+#: controllers/addons_controller.php:141 controllers/addons_controller.php:280
+#: controllers/addons_controller.php:1442
+#, php-format
+msgid "addons_display_pagetitle"
+msgstr "%s"
+
+#. %s is an email address
+#: views/addons/display.thtml:286
+#, php-format
+msgid "addons_display_paragraph_supportinfoemail"
+msgstr ""
+"Găsiți asistență pentru această extensie la %s.Dacă vreți să raportați un "
+"defect, ar fi cel mai bine dacă l-ați raporta dezvoltatorului pentru ca să "
+"poată fi tratat imediat. Recenziile nu sunt locul potrivit pentru rapoarte "
+"detaliate de defecte și dezvoltatorul v-ar putea cere date suplimentare "
+"pentru a remedia defectul. Pentru că noi nu furnizăm adresa dumneavoastră de "
+"email dezvoltatorului când scrieți o recenzie, nu veți putea fi contactat(ă) "
+"pentru a vi se cere mai multe detalii sau pentru a fi anunțat(ă) că defectul "
+"a fost reparat într-o versiune mai nouă."
+
+#. %$1s is a URL
+#. %$2s is an email address
+#: views/addons/display.thtml:269
+#, php-format
+msgid "addons_display_paragraph_supportinfoemailurl"
+msgstr ""
+"Găsiți asistență pentru această extensie la %s sau la %s.Dacă vreți să "
+"raportați un defect, ar fi cel mai bine dacă l-ați raporta dezvoltatorului "
+"pentru ca să poată fi tratat imediat. Recenziile nu sunt locul potrivit "
+"pentru rapoarte detaliate de defecte și dezvoltatorul v-ar putea cere date "
+"suplimentare pentru a remedia defectul. Pentru că noi nu furnizăm adresa "
+"dumneavoastră de email dezvoltatorului când scrieți o recenzie, nu veți putea "
+"fi contactat(ă) pentru a vi se cere mai multe detalii sau pentru a fi anunțat"
+"(ă) că defectul a fost reparat într-o versiune mai nouă."
+
+#. %s is a URL
+#: views/addons/display.thtml:278
+#, php-format
+msgid "addons_display_paragraph_supportinfourl"
+msgstr ""
+"Găsiți asistență pentru această extensie la %s.Dacă vreți să raportați un "
+"defect, ar fi cel mai bine dacă l-ați raporta dezvoltatorului pentru ca să "
+"poată fi tratat imediat. Recenziile nu sunt locul potrivit pentru rapoarte "
+"detaliate de defecte și dezvoltatorul v-ar putea cere date suplimentare "
+"pentru a remedia defectul. Pentru că noi nu furnizăm adresa dumneavoastră de "
+"email dezvoltatorului când scrieți o recenzie, nu veți putea fi contactat(ă) "
+"pentru a vi se cere mai multe detalii sau pentru a fi anunțat(ă) că defectul "
+"a fost reparat într-o versiune mai nouă."
+
+#: views/addons/display.thtml:383
+msgid "addons_display_rate_it"
+msgstr "Apreciere"
+
+#: views/reviews/add.thtml:93 views/reviews/add.thtml:94
+msgid "addons_display_really_like_it"
+msgstr "ÃŽmi place foarte mult"
+
+#: views/addons/display.thtml:410
+msgid "addons_display_review_etiquette"
+msgstr ""
+"Vă rugăm să nu postați defecte în recenzii. Dezvoltatorii nu văd adresa "
+"dumneavoastră de email și nu vă pot contacta pentru a vă cere detalii."
+
+#. %1 is the review guidelines link
+#: views/addons/display.thtml:417
+msgid "addons_display_review_guidelines_link"
+msgstr "<a href=\"%s\">Scurt ghid pentru recenzii</a>"
+
+#. %1 is the support section link
+#: views/addons/display.thtml:414
+msgid "addons_display_review_see_support"
+msgstr ""
+"Vedeți <a href=\"%1$s\">secțiunea de suport</a> pentru a afla de unde puteți "
+"obține asistență pentru acest supliment."
+
+#: views/addons/display.thtml:404
+msgid "addons_display_review_submit"
+msgstr "Salvează"
+
+#: views/addons/display.thtml:430
+#, php-format
+msgid "addons_display_see_all_addons"
+msgstr "Toată categoria %1$s"
+
+#. %1 is the number of reviews
+#: views/addons/display.thtml:364
+#, php-format
+msgid "addons_display_see_all_reviews"
+msgstr "Toate recenziile (%1$s)"
+
+#: views/addons/display.thtml:219
+msgid "addons_display_see_all_versions"
+msgstr "Vezi toate versiunile"
+
+#: views/addons/display.thtml:321 views/addons/versions.thtml:117
+msgid "addons_display_view_source"
+msgstr "Arată sursa"
+
+#: views/addons/display.thtml:324
+msgid "addons_display_view_stats"
+msgstr "Arată statisticile"
+
+#: views/addons/display.thtml:376
+msgid "addons_display_what_do_you_think"
+msgstr "Ce părere aveți?"
+
+#: views/elements/app_compatibility.thtml:49
+msgid "addons_display_workswith"
+msgstr "Funcționează cu:"
+
+#: views/addons/home.thtml:112
+msgid "addons_home_browse_new"
+msgstr ""
+
+#: views/addons/home.thtml:110
+msgid "addons_home_browse_popular"
+msgstr "Popular"
+
+#: views/addons/home.thtml:108
+msgid "addons_home_browse_recommended"
+msgstr "Recomandat"
+
+#: views/addons/home.thtml:127 views/addons/home.thtml:134
+#: views/addons/home.thtml:141 views/addons/home.thtml:148
+msgid "addons_home_browse_subscribe"
+msgstr "Abonare"
+
+#: views/addons/home.thtml:101
+msgid "addons_home_browse_title"
+msgstr ""
+
+#: views/addons/home.thtml:114
+msgid "addons_home_browse_updated"
+msgstr "Actualizat"
+
+#: views/elements/amo2009/homepage_addon.thtml:100
+#: views/elements/addon_discussionheader.thtml:83
+#: views/elements/addon_listitem.thtml:109 views/elements/feature.thtml:95
+#: views/addons/category_landing.thtml:66 views/addons/policy.thtml:57
+#: views/addons/display.thtml:70 views/addons/home.thtml:178
+msgid "addons_home_by"
+msgstr "de"
+
+#: views/addons/home.thtml:169
+msgid "addons_home_collection_popular_title"
+msgstr "Colecții populare"
+
+#: views/elements/amo2009/categories.thtml:69 views/addons/home.thtml:160
+msgid "addons_home_collections"
+msgstr "Colecții"
+
+#. %1$s is the count of addons in a collection
+#: views/elements/amo2009/collection_listing_item.thtml:51
+#: views/addons/home.thtml:185
+msgid "addons_home_collections_addon_count"
+msgid_plural "addons_home_collections_addon_count"
+msgstr[0] "<strong>%1$s</strong> supliment"
+msgstr[1] "<strong>%1$s</strong> suplimente"
+msgstr[2] "<strong>%1$s</strong> de suplimente"
+
+#: views/addons/home.thtml:196
+msgid "addons_home_collections_all"
+msgstr "Vezi toate colecțiile"
+
+#: views/addons/home.thtml:162
+msgid "addons_home_collections_intro"
+msgstr ""
+"Colecțiile sunt un mod de a categorisi, amesteca și potrivi suplimente. "
+"Abonați-vă la colecțiile create de alți utilizatori sau creați propria "
+"colecție."
+
+#. %1$s is the count of subscribers for a collection
+#: views/elements/amo2009/collection_listing_item.thtml:58
+#: views/collections/detail.thtml:96 views/addons/home.thtml:189
+msgid "addons_home_collections_subscribers"
+msgid_plural "addons_home_collections_subscribers"
+msgstr[0] "<strong>%1$s</strong> abonat"
+msgstr[1] "<strong>%1$s</strong> abonați"
+msgstr[2] "<strong>%1$s</strong> de abonați"
+
+#: views/addons/searchengines.thtml:54 views/addons/themes_landing.thtml:49
+msgid "addons_home_feature_head"
+msgstr "Vă recomandăm"
+
+#: controllers/search_controller.php:218 controllers/addons_controller.php:176
+#: controllers/addons_controller.php:428 controllers/addons_controller.php:671
+#: controllers/addons_controller.php:871 controllers/addons_controller.php:1103
+#: controllers/addons_controller.php:1242
+#: controllers/addons_controller.php:1298
+#, php-format
+msgid "addons_home_header_details"
+msgstr ""
+"Suplimentele extind %1$s, permițându-vă să personalizați experiența "
+"dumneavoastră pe web. Uitați-vă pe aici și alegeți ceva pentru a face un %1"
+"$s al dumneavoastră."
+
+#. %1$s is the HTML collection name link.
+#: views/elements/amo2009/teaser_collections.thtml:107
+msgid "addons_home_introduction_collection_link"
+msgstr "Ca acestea? Găsiți suplimente asemănătoare în colecția %1$s."
+
+#: views/elements/amo2009/teaser_collections.thtml:60
+msgid "addons_home_introduction_extras"
+msgstr ""
+
+#: views/elements/amo2009/teaser_collections.thtml:55
+msgid "addons_home_introduction_header"
+msgstr ""
+
+#: views/elements/amo2009/teaser_collections.thtml:72
+msgid "addons_home_introduction_install"
+msgstr ""
+
+#: views/elements/amo2009/teaser_collections.thtml:45
+msgid "addons_home_introduction_name"
+msgstr "Introducere"
+
+#: views/elements/amo2009/teaser_collections.thtml:66
+msgid "addons_home_introduction_themes"
+msgstr ""
+
+#: views/addons/home.thtml:161
+msgid "addons_home_new_indicator"
+msgstr ""
+
+#: views/elements/app_chooser.thtml:48 views/layouts/amo2009.thtml:257
+msgid "addons_home_other_applications"
+msgstr "Alte aplicații"
+
+#. %1$s is the application the user is browsing. Examples: Thunderbird, Firefox,
+#. Sunbird
+#: views/pages/collector_faq.thtml:49 views/pages/collector_firstrun.thtml:42
+#: views/pages/collector.thtml:46 views/pages/collector_features.thtml:54
+#: controllers/developers_controller.php:87
+#: controllers/compatibility_controller.php:72
+#: controllers/components/simple_acl.php:81 controllers/components/amo.php:607
+#: controllers/statistics_controller.php:60
+#: controllers/statistics_controller.php:240
+#: controllers/previews_controller.php:67 controllers/users_controller.php:90
+#: controllers/users_controller.php:223 controllers/users_controller.php:330
+#: controllers/users_controller.php:414 controllers/users_controller.php:708
+#: controllers/users_controller.php:723 controllers/reviews_controller.php:204
+#: controllers/reviews_controller.php:251
+#: controllers/reviews_controller.php:346
+#: controllers/reviews_controller.php:425 controllers/search_controller.php:185
+#: controllers/search_controller.php:297 controllers/search_controller.php:301
+#: controllers/addons_controller.php:147 controllers/addons_controller.php:280
+#: controllers/addons_controller.php:370 controllers/addons_controller.php:667
+#: controllers/addons_controller.php:874 controllers/addons_controller.php:1019
+#: controllers/addons_controller.php:1034
+#: controllers/addons_controller.php:1101
+#: controllers/addons_controller.php:1121
+#: controllers/addons_controller.php:1240
+#: controllers/addons_controller.php:1357
+#: controllers/addons_controller.php:1364
+#: controllers/addons_controller.php:1442
+#: controllers/addons_controller.php:1477
+#: controllers/addons_controller.php:1538
+#: controllers/addons_controller.php:1543 controllers/editors_controller.php:64
+#: controllers/pages_controller.php:132 controllers/groups_controller.php:65
+#: controllers/groups_controller.php:71 controllers/groups_controller.php:89
+#: controllers/groups_controller.php:111
+#: controllers/collections_controller.php:57
+#: controllers/collections_controller.php:121
+#: controllers/collections_controller.php:205
+#: controllers/collections_controller.php:365
+#: controllers/collections_controller.php:404
+#: controllers/collections_controller.php:466
+#: controllers/collections_controller.php:538
+#: controllers/collections_controller.php:828
+#: controllers/localizers_controller.php:72
+#, php-format
+msgid "addons_home_pagetitle"
+msgstr "Suplimente %1$s"
+
+#. %1$s is the number of addons downloaded
+#: views/addons/home.thtml:57
+#, php-format
+msgid "addons_home_stats_downloaded"
+msgid_plural "addons_home_stats_downloaded"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+
+#. %1$s is the number of addons in use
+#: views/addons/home.thtml:63
+#, php-format
+msgid "addons_home_stats_inuse"
+msgid_plural "addons_home_stats_inuse"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+
+#: views/addons/home.thtml:136
+msgid "addons_home_view_all_newest_title"
+msgstr "Vezi toate suplimentele nou create"
+
+#: views/addons/home.thtml:129
+msgid "addons_home_view_all_popular_title"
+msgstr "Toate suplimentele populare"
+
+#: views/addons/home.thtml:150
+msgid "addons_home_view_all_recommended_title"
+msgstr "Toate suplimentele recomandate"
+
+#: views/addons/home.thtml:143
+msgid "addons_home_view_all_updated_title"
+msgstr "Vezi toate suplimentele actualizate recent"
+
+#: views/elements/amo2009/install.thtml:334 views/elements/install.thtml:112
+msgid "addons_install_in_sunbird"
+msgstr ""
+"<ol><li>Clic pe legătura de mai jos pentru a salva fișierul.</li><li>În "
+"Mozilla Sunbird, deschideți fereastra Suplimente din meniul Unelte.</"
+"li><li>Clic pe butonul Instalare, localizați/selectați fișierul descărcat și "
+"apoi apăsaÈ›i „OKâ€.</li></ol>"
+
+#: views/elements/amo2009/install.thtml:333 views/elements/install.thtml:111
+msgid "addons_install_in_sunbird_title"
+msgstr "Cum se instalează în Sunbird"
+
+#: views/elements/amo2009/install.thtml:331 views/elements/install.thtml:106
+msgid "addons_install_in_thunderbird"
+msgstr ""
+"<ol><li>Clic dreapta pe legătura de mai jos și alegeți „Salvează legătura "
+"ca...†(Save link as...) pentru a descărca și salva fișierul pe discul "
+"dumneavoastră.</li><li>În Mozilla Thunderbird, selectați Suplimente (Add-ons) "
+"din meniul Unelte (Tools).</li><li>Clicați pe butonul Instalează și "
+"localizaÈ›i/selectaÈ›i fiÈ™ierul pe care l-aÈ›i descărcat după care apăsaÈ›i „OKâ€."
+"</li></ol>"
+
+#: views/elements/amo2009/install.thtml:330 views/elements/install.thtml:105
+msgid "addons_install_in_thunderbird_title"
+msgstr "Cum se instalează în Thunderbird"
+
+#: views/elements/amo2009/addon_list_options.thtml:108
+#: views/elements/addon_list_options.thtml:105
+msgid "addons_options_show_experimental"
+msgstr "arată suplimentele experimentale"
+
+#: views/elements/amo2009/addon_list_options.thtml:113
+#: views/elements/addon_list_options.thtml:109
+msgid "addons_options_submit"
+msgstr "Du-te"
+
+#: views/addons/plugins.thtml:63 views/addons/plugins.thtml:73
+#: views/addons/plugins.thtml:83 views/addons/plugins.thtml:93
+#: views/addons/plugins.thtml:103 views/addons/plugins.thtml:116
+#: views/addons/plugins.thtml:126
+msgid "addons_plugins_by"
+msgstr "De"
+
+#: views/addons/plugins.thtml:107
+msgid "addons_plugins_for_linux"
+msgstr "pentru Linux"
+
+#: views/addons/plugins.thtml:108 views/addons/plugins.thtml:131
+msgid "addons_plugins_for_macosx"
+msgstr "pentru Mac OS X"
+
+#: views/addons/plugins.thtml:106 views/addons/plugins.thtml:129
+#: views/addons/plugins.thtml:130
+msgid "addons_plugins_for_windows"
+msgstr "pentru Windows"
+
+#. %1$s is a URL
+#: views/addons/plugins.thtml:139
+#, php-format
+msgid "addons_plugins_looking_for_more"
+msgstr ""
+"Această pagină conține informații doar despre cele mai folosite plugin-uri. "
+"Pentru mai multe informații despre alte plugin-uri disponibile pentru "
+"navigatoare bazate pe Mozilla, vizitați %1$s (în engleză)"
+
+#: views/addons/plugins.thtml:137
+msgid "addons_plugins_looking_for_plugin"
+msgstr "Nu găsiți un plugin în această listă?"
+
+#: views/addons/plugins.thtml:58
+msgid "addons_plugins_main_description"
+msgstr ""
+"Plugin-urile ajută navigatorul dumneavoastră să efectueze funcții specifice "
+"cum ar fi vizualizarea unor formate grafice speciale sau redarea fișierelor "
+"multimedia. Plugin-urile sunt ușor diferite de extensii, care modifică sau "
+"adaugă la o funcționalitate existentă deja."
+
+#. %1$s is the application name. Example: Firefox, Thunderbird, Sunbird
+#: controllers/addons_controller.php:1122
+#, php-format
+msgid "addons_plugins_main_header"
+msgstr "Plugin-uri des folosite pentru %1$s"
+
+#: controllers/components/amo.php:698 controllers/addons_controller.php:1121
+msgid "addons_plugins_pagetitle"
+msgstr "Plugin-uri"
+
+#: views/addons/plugins.thtml:68 views/addons/plugins.thtml:78
+#: views/addons/plugins.thtml:88 views/addons/plugins.thtml:98
+#: views/addons/plugins.thtml:110 views/addons/plugins.thtml:121
+#: views/addons/plugins.thtml:133
+msgid "addons_plugins_support_documentation"
+msgstr "Suport prin documentație: "
+
+#. %s is the name of the add-on
+#: views/addons/policy.thtml:61
+#, php-format
+msgid "addons_policy_eula_require"
+msgstr ""
+"%s necesită acordul dumneavoastră pentru licența de folosire (EULA) înainte "
+"ca instalarea să poată continua:"
+
+#. %1 is the add-on name
+#: controllers/addons_controller.php:1476
+#, php-format
+msgid "addons_previews_pagetitle"
+msgstr "Avanpremiere pentru %s"
+
+#: views/addons/category_landing.thtml:135
+msgid "addons_recently_added"
+msgstr ""
+
+#: views/addons/recommended.thtml:51 controllers/addons_controller.php:1365
+msgid "addons_recommended_introduction"
+msgstr ""
+"Între atâtea suplimente grozave disponibile, există ceva pentru oricine. Ca "
+"să începeți imediat, v-am pregătit o listă cu câteva dintre cele mai "
+"populare. Bucurați-vă de ele!"
+
+#: controllers/addons_controller.php:1357
+#: controllers/addons_controller.php:1364
+msgid "addons_recommended_pagetitle"
+msgstr "Suplimente recomandate"
+
+#: controllers/addons_controller.php:1360
+msgid "addons_recommended_title"
+msgstr "Suplimente recomandate"
+
+#: views/addons/searchengines.thtml:136
+msgid "addons_searchengines_additional_resources"
+msgstr "Resurse adiționale"
+
+#. link text devmo
+#: views/addons/searchengines.thtml:141
+msgid "addons_searchengines_devmo_link"
+msgstr "Centrul dezvoltatorilor Mozilla"
+
+#: views/pages/js_constants.js.thtml:67
+msgid "addons_searchengines_error_mozilla_browser_required"
+msgstr ""
+"Ne pare rău, aveți nevoie de un navigator bazat pe Mozilla (cum ar fi "
+"Firefox) pentru a instala un plugin pentru căutare."
+
+#: views/addons/searchengines.thtml:49
+msgid "addons_searchengines_error_nojavascript"
+msgstr ""
+"JavaScript este necesar pentru a instala plugin-uri, dar se pare că îl aveți "
+"dezactivat. Vă rugăm activați JavaScript înainte de a încerca să instalați "
+"oricare dintre plugin-urile pentru căutare de mai jos."
+
+#. %1 is "make your own" link
+#. %2 is MDC link
+#: views/addons/searchengines.thtml:139
+msgid "addons_searchengines_learn_howto"
+msgstr "Învățați să %1$s la %2$s."
+
+#. link path to search plugins instructions, relative to devmo
+#: views/addons/searchengines.thtml:140
+msgid "addons_searchengines_makeyourown_href"
+msgstr "/en/docs/Creating__OpenSearch_plugins_for_Firefox"
+
+#. link text for "make your own" (opensearch engine)
+#: views/addons/searchengines.thtml:140
+msgid "addons_searchengines_makeyourown_link"
+msgstr "faceți voi unul"
+
+#. %1 is the link to mycroft.mozdev.org
+#: views/addons/searchengines.thtml:138
+msgid "addons_searchengines_more"
+msgstr "Puteți găsi mai multe motoare de căutare la %1$s"
+
+#. link text to mycroft.mozdev.org
+#: views/addons/searchengines.thtml:138
+msgid "addons_searchengines_mycroft_link"
+msgstr "mycroft.mozdev.org"
+
+#: controllers/addons_controller.php:1100
+#: controllers/addons_controller.php:1110
+msgid "addons_searchengines_pagetitle"
+msgstr "Motoare de căutare"
+
+#: views/addons/searchengines.thtml:143
+msgid "addons_searchengines_thanks"
+msgstr ""
+"Mulțumiri speciale proiectului Mycroft pentru munca lor la motoarele de "
+"căutare Firefox."
+
+#: views/addons/display.thtml:154
+msgid "addons_share_button_text"
+msgstr "Împărtășește"
+
+#: controllers/addons_controller.php:89
+msgid "addons_share_label_delicious"
+msgstr "Adaugă la Delicious"
+
+#: controllers/addons_controller.php:77
+msgid "addons_share_label_digg"
+msgstr "Evaluează pe Digg!"
+
+#: controllers/addons_controller.php:83
+msgid "addons_share_label_facebook"
+msgstr "Postează în Facebook"
+
+#: controllers/addons_controller.php:101
+msgid "addons_share_label_friendfeed"
+msgstr "Împărtășește pe FriendFeed"
+
+#: controllers/addons_controller.php:95
+msgid "addons_share_label_myspace"
+msgstr "Postează în MySpace"
+
+#: controllers/components/amo.php:201 controllers/components/amo.php:229
+msgid "addons_status_disabled"
+msgstr "Dezactivat"
+
+#: controllers/components/amo.php:191 controllers/components/amo.php:224
+msgid "addons_status_incomplete"
+msgstr "Versiune incompletă"
+
+#: controllers/components/amo.php:197 controllers/components/amo.php:227
+msgid "addons_status_nominated"
+msgstr "În cutia cu nisip; Nominalizare publică"
+
+#: views/pages/js_constants.js.thtml:80 controllers/components/amo.php:195
+#: controllers/components/amo.php:226
+msgid "addons_status_pending"
+msgstr "În cutia cu nisip; Așteaptă recenzia"
+
+#: views/pages/js_constants.js.thtml:78 controllers/components/amo.php:199
+#: controllers/components/amo.php:228
+msgid "addons_status_public"
+msgstr "Public"
+
+#: views/pages/js_constants.js.thtml:79 controllers/components/amo.php:193
+#: controllers/components/amo.php:225
+msgid "addons_status_sandbox"
+msgstr "ÃŽn cutia cu nisip"
+
+#: controllers/components/amo.php:203
+msgid "addons_status_unknown"
+msgstr "Necunoscut"
+
+#: views/elements/amo2009/teaser_collections.thtml:91
+#: views/elements/amo2009/homepage_addon.thtml:99
+#: views/elements/feature.thtml:94
+msgid "addons_title_tooltip"
+msgstr "Află mai multe despre acest supliment"
+
+#: views/addons/category_landing.thtml:151
+msgid "addons_top_downloads"
+msgstr ""
+
+#: views/addons/category_landing.thtml:165
+msgid "addons_top_rated"
+msgstr ""
+
+#: views/addons/versions.thtml:62
+msgid "addons_versions_careful"
+msgstr "Fiți precaut(ă) cu vechile versiuni"
+
+#: views/addons/versions.thtml:63
+msgid "addons_versions_careful_introduction"
+msgstr ""
+"Aceste versiuni sunt afișate pentru referință și pentru a fi testate. Ar "
+"trebui să folosiți întotdeauna ultima versiune a unui supliment."
+
+#: controllers/addons_controller.php:1549
+msgid "addons_versions_history"
+msgstr "Istoria versiunilor și a modificărilor"
+
+#. %1$s is the add-on name
+#: controllers/addons_controller.php:1535
+#, php-format
+msgid "addons_versions_pagetitle"
+msgstr "Istoricul versiunilor %1$s"
+
+#: controllers/groups_controller.php:71
+msgid "admin_group_add_pagetitle"
+msgstr "Adăugare grup"
+
+#: controllers/groups_controller.php:111
+msgid "admin_group_delete_pagetitle"
+msgstr "Ștergere grup"
+
+#. %s is a number to identify the group
+#: controllers/groups_controller.php:117
+#, php-format
+msgid "admin_group_deleted"
+msgstr "Grupul %s a fost șters"
+
+#: controllers/groups_controller.php:89
+msgid "admin_group_edit_pagetitle"
+msgstr "Editare grup"
+
+#: controllers/groups_controller.php:92 controllers/groups_controller.php:113
+msgid "admin_group_error_invalid_id"
+msgstr "Id·invalid·pentru·grup"
+
+#: controllers/groups_controller.php:65
+msgid "admin_group_pagetitle"
+msgstr "Administrare grup"
+
+#: controllers/groups_controller.php:77 controllers/groups_controller.php:99
+msgid "admin_group_saved"
+msgstr "Grupul a fost salvat"
+
+#: views/elements/amo2009/search.thtml:257 views/elements/search.thtml:239
+msgid "advanced_search_form"
+msgstr "Avansat"
+
+#: views/elements/amo2009/search.thtml:126 views/elements/search.thtml:125
+msgid "advanced_search_form_any_time"
+msgstr "Oricând"
+
+#: views/elements/amo2009/search.thtml:97
+#: views/elements/amo2009/search.thtml:110 views/elements/search.thtml:96
+#: views/elements/search.thtml:109
+msgid "advanced_search_form_any_type"
+msgstr "Oricare"
+
+#: views/elements/amo2009/search.thtml:275 views/elements/search.thtml:254
+msgid "advanced_search_form_any_version"
+msgstr "Oricare"
+
+#: views/elements/amo2009/search.thtml:217 views/elements/search.thtml:212
+msgid "advanced_search_form_application"
+msgstr "Aplicație"
+
+#: views/elements/amo2009/search.thtml:143 views/elements/search.thtml:142
+msgid "advanced_search_form_keyword_match"
+msgstr "Potrivire cuvinte cheie"
+
+#: views/elements/amo2009/search.thtml:251 views/elements/search.thtml:225
+msgid "advanced_search_form_lastupdate"
+msgstr "Ultima actualizare"
+
+#: views/elements/amo2009/search.thtml:145 views/elements/search.thtml:144
+msgid "advanced_search_form_name"
+msgstr "Nume"
+
+#: views/elements/amo2009/search.thtml:144 views/elements/search.thtml:143
+msgid "advanced_search_form_newest"
+msgstr "Cel mai nou"
+
+#: views/elements/amo2009/search.thtml:130 views/elements/search.thtml:129
+msgid "advanced_search_form_past_3_months"
+msgstr "Ultimele 3 luni"
+
+#: views/elements/amo2009/search.thtml:131 views/elements/search.thtml:130
+msgid "advanced_search_form_past_6_months"
+msgstr "Ultimele 6 luni"
+
+#: views/elements/amo2009/search.thtml:127 views/elements/search.thtml:126
+msgid "advanced_search_form_past_day"
+msgstr "Ieri"
+
+#: views/elements/amo2009/search.thtml:129 views/elements/search.thtml:128
+msgid "advanced_search_form_past_month"
+msgstr "Luna trecută"
+
+#: views/elements/amo2009/search.thtml:128 views/elements/search.thtml:127
+msgid "advanced_search_form_past_week"
+msgstr "Săptămâna trecută"
+
+#: views/elements/amo2009/search.thtml:132 views/elements/search.thtml:131
+msgid "advanced_search_form_past_year"
+msgstr "Anul trecut"
+
+#: views/elements/amo2009/search.thtml:239 views/elements/search.thtml:230
+msgid "advanced_search_form_perpage"
+msgstr "Pe pagină"
+
+#: views/elements/amo2009/search.thtml:243 views/elements/search.thtml:224
+msgid "advanced_search_form_platform"
+msgstr "Platformă"
+
+#: views/elements/amo2009/search.thtml:147 views/elements/search.thtml:146
+msgid "advanced_search_form_popularity"
+msgstr "Popularitate"
+
+#: views/elements/amo2009/search.thtml:146 views/elements/search.thtml:145
+msgid "advanced_search_form_rating"
+msgstr "Evaluare"
+
+#: views/elements/amo2009/search.thtml:247 views/elements/search.thtml:231
+msgid "advanced_search_form_sortby"
+msgstr "Sortează după"
+
+#: views/elements/amo2009/search.thtml:227 views/elements/search.thtml:216
+msgid "advanced_search_form_to"
+msgstr "până la"
+
+#: views/elements/amo2009/search.thtml:257 views/elements/search.thtml:237
+msgid "advanced_search_form_toggle_tooltip"
+msgstr "Comută la căutarea avansată"
+
+#: views/elements/amo2009/search.thtml:235 views/elements/search.thtml:223
+msgid "advanced_search_form_type"
+msgstr "Tip"
+
+#: views/elements/amo2009/search.thtml:222 views/elements/search.thtml:214
+msgid "advanced_search_form_version"
+msgstr "de la versiunea"
+
+#: views/elements/amo2009/pagination.thtml:42
+msgid "amo2009_pagination_next_page"
+msgstr "ÃŽnainte"
+
+#: views/elements/amo2009/pagination.thtml:41
+msgid "amo2009_pagination_previous_page"
+msgstr "ÃŽnapoi"
+
+#: views/pages/js_constants.js.thtml:96
+msgid "app_compat_ignore_check"
+msgstr "Ignoră verificarea versiunii"
+
+#: views/pages/js_constants.js.thtml:72
+msgid "app_compat_older_firefox_only"
+msgstr "Numai pentru versiuni vechi de Firefox"
+
+#. %1$s and %2$s are URLs
+#: views/pages/js_constants.js.thtml:74
+msgid "app_compat_older_version_or_ignore_check"
+msgstr ""
+"Puteți <a href=\"%1$s\">încerca o versiune mai veche</a> sau <a href=\"#\" "
+"onclick=\"%2$s\">puteți ignora această verificare</a>"
+
+#. %1$s is a URL
+#: views/pages/js_constants.js.thtml:71
+msgid "app_compat_try_old_version"
+msgstr "S-ar putea să meargă <a href=\"%1$s\">o versiune mai veche</a>"
+
+#. %1$s is a URL
+#. %2$s is a version number. Example: 3.1
+#: views/pages/js_constants.js.thtml:73
+msgid "app_compat_unreleased_version"
+msgstr ""
+"Acest supliment are nevoie <a href=\"%1$s\">Firefox %2$s</a> care nu e încă "
+"lansat"
+
+#: views/pages/js_constants.js.thtml:70
+msgid "app_compat_update_firefox"
+msgstr ""
+"<a href=\"http://getfirefox.com\">Actualizați Firefox</a> pentru a folosi "
+"acest supliment"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#. %3$s is a status, like Public.
+#: controllers/components/audit.php:79
+msgid "audit_addon_status"
+msgstr ""
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:221
+msgid "audit_admin_default"
+msgstr ""
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:153
+msgid "audit_admin_feature_remove"
+msgstr ""
+
+#. %1$s is <a>user name</a>
+#. %2$s is an application, like Firefox.
+#: controllers/components/audit.php:92
+msgid "audit_application_create"
+msgstr ""
+
+#. %1$s is <a>user name</a>
+#. %2$s is an application, like Firefox.
+#: controllers/components/audit.php:95
+msgid "audit_application_edit"
+msgstr ""
+
+#. %1$s is <a>user name</a>
+#. %2$s is a version number, like 3.5.
+#. %3$s is an application, like Firefox.
+#: controllers/components/audit.php:105
+msgid "audit_appversion_create"
+msgstr ""
+
+#. %1$s is <a>user name</a>
+#. %2$s is a version number, like 3.5.
+#. %3$s is an application, like Firefox.
+#: controllers/components/audit.php:108
+msgid "audit_appversion_delete"
+msgstr ""
+
+#. %1$s is <a>user name</a>
+#. %2$s is a config field, like "awesomeness".
+#. %3$s is a config value, like "off".
+#. %4$s is a config value, like "on".
+#: controllers/components/audit.php:210
+msgid "audit_config"
+msgstr ""
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:258
+msgid "audit_editor_default"
+msgstr ""
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#: controllers/components/audit.php:236
+msgid "audit_editor_feature_remove"
+msgstr ""
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#: controllers/components/audit.php:231
+msgid "audit_feature_add"
+msgstr ""
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:149
+msgid "audit_feature_edit"
+msgstr ""
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#: controllers/components/audit.php:241
+msgid "audit_feature_locale_change"
+msgstr ""
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:83
+msgid "audit_file_recalchash"
+msgstr ""
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>user name</a>
+#. %3$s is <a>group name</a>
+#: controllers/components/audit.php:182
+msgid "audit_group_addmember"
+msgstr ""
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:313
+msgid "audit_group_associated"
+msgstr ""
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:162
+msgid "audit_group_create"
+msgstr ""
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:170
+msgid "audit_group_delete"
+msgstr ""
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:165
+msgid "audit_group_edit"
+msgstr ""
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>user name</a>
+#. %3$s is <a>group name</a>
+#: controllers/components/audit.php:188
+msgid "audit_group_removemember"
+msgstr ""
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:280
+msgid "audit_l10n_default"
+msgstr ""
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:295
+msgid "audit_modify_locked_group"
+msgstr ""
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:299
+msgid "audit_modify_other_locale"
+msgstr ""
+
+#. %1$s is <a>user name</a>
+#. %2$s is a platform, like <a>Windows</a>
+#: controllers/components/audit.php:135
+msgid "audit_platform_create"
+msgstr ""
+
+#. %1$s is <a>user name</a>
+#. %2$s is a platform, like <a>Windows</a>
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:143
+msgid "audit_platform_delete"
+msgstr ""
+
+#. %1$s is <a>user name</a>
+#. %2$s is a platform, like <a>Windows</a>
+#: controllers/components/audit.php:138
+msgid "audit_platform_edit"
+msgstr ""
+
+#. %1$s is <a>user name</a>
+#. %2$s is a part of the admin, like 'Site Config'
+#: controllers/components/audit.php:288
+msgid "audit_reauthentication_failure"
+msgstr ""
+
+#. %1$s is <a>user name</a>
+#. %2$s is the name of a canned response, like 'Ready for the public'
+#: controllers/components/audit.php:198
+msgid "audit_response_create"
+msgstr ""
+
+#. %1$s is <a>user name</a>
+#. %2$s is the name of a canned response, like 'Ready for the public'
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:206
+msgid "audit_response_delete"
+msgstr ""
+
+#. %1$s is <a>user name</a>
+#. %2$s is the name of a canned response, like 'Ready for the public'
+#: controllers/components/audit.php:201
+msgid "audit_response_edit"
+msgstr ""
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:245
+msgid "audit_review_approve"
+msgstr ""
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:250 controllers/components/audit.php:253
+msgid "audit_review_delete"
+msgstr ""
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:303
+msgid "audit_security_default"
+msgstr ""
+
+#. %1$s is <a>user name</a>
+#. %2$s is a category name, like <a>Search Tools</a>
+#: controllers/components/audit.php:118
+msgid "audit_tag_create"
+msgstr ""
+
+#. %1$s is <a>user name</a>
+#. %2$s is a category name, like <a>Search Tools</a>
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:126
+msgid "audit_tag_delete"
+msgstr ""
+
+#. %1$s is <a>user name</a>
+#. %2$s is a category name, like <a>Search Tools</a>
+#: controllers/components/audit.php:121
+msgid "audit_tag_edit"
+msgstr ""
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:266
+msgid "audit_update_applications"
+msgstr ""
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:277
+msgid "audit_update_blog"
+msgstr ""
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:274
+msgid "audit_update_platforms"
+msgstr ""
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:270
+msgid "audit_update_tags"
+msgstr ""
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>user name</a>
+#: controllers/components/audit.php:217
+msgid "audit_user_edit"
+msgstr ""
+
+#: controllers/addons_controller.php:1012
+msgid "browse_addons_name"
+msgstr "Suplimente după nume"
+
+#: controllers/addons_controller.php:1010
+msgid "browse_addons_newest"
+msgstr "Cele mai noi suplimente"
+
+#: controllers/addons_controller.php:1008
+msgid "browse_addons_popular"
+msgstr "Suplimente populare"
+
+#: controllers/addons_controller.php:1011
+msgid "browse_addons_rated"
+msgstr "Suplimente după evaluare"
+
+#: controllers/addons_controller.php:1009
+msgid "browse_addons_updated"
+msgstr "Suplimente actualizate recent"
+
+#: views/elements/categories.thtml:73 views/elements/categories.thtml:82
+msgid "categories_current_title"
+msgstr "Categoria curentă"
+
+#: views/elements/categories.thtml:50
+#: views/elements/amo2009/categories.thtml:43
+#: views/elements/amo2009/categories.thtml:45
+msgid "categories_header"
+msgstr "Categorii"
+
+#: views/elements/categories.thtml:50
+#: views/elements/amo2009/categories.thtml:41
+msgid "categories_header_title"
+msgstr "Alegeți o categorie"
+
+#. %1$s is the category name
+#: views/addons/searchengines.thtml:129
+#, php-format
+msgid "category_extra_see_all"
+msgstr "Toate de tipul %1$s"
+
+#. %1$s is a number.
+#: models/collection.php:130
+msgid "collection_description_limit"
+msgstr "Descrierea ar trebui să aibă mai puțin de %1$s caractere."
+
+#. %1$s is the name of the collection
+#: controllers/collections_controller.php:392
+msgid "collection_detail_rss_title"
+msgstr "Colecția %s"
+
+#: controllers/collections_controller.php:1065
+msgid "collection_error_deleting_addon"
+msgstr "Eroare la ștergerea suplimentului!"
+
+#: controllers/collections_controller.php:1051
+msgid "collection_error_saving_addon"
+msgstr "Eroare la salvarea suplimentului!"
+
+#: controllers/collections_controller.php:1080
+msgid "collection_error_saving_comment"
+msgstr "Eroare la salvarea comentariului!"
+
+#. %1$s is a number.
+#: models/collection.php:122
+msgid "collection_name_limit"
+msgstr "Numele ar trebui să aibă mai puțin de %1$s caractere."
+
+#: controllers/collections_controller.php:352
+#: controllers/collections_controller.php:487
+msgid "collection_not_found"
+msgstr "Colecție negăsită!"
+
+#. %1$s is the text on the "create collection" button
+#: views/collections/add.thtml:91
+msgid "collections_add_formfield_addons_description"
+msgstr ""
+
+#: views/collections/add.thtml:90
+msgid "collections_add_formfield_firstaddons"
+msgstr "Alegeți primele suplimente"
+
+#: views/collections/add.thtml:48
+msgid "collections_add_header"
+msgstr "Creați o colecție"
+
+#: views/collections/add.thtml:97
+msgid "collections_add_header_selectedaddons"
+msgstr "Suplimente selectate"
+
+#: views/collections/add.thtml:50
+msgid "collections_add_intro"
+msgstr ""
+
+#: views/collections/add.thtml:92 views/collections/add.thtml:103
+msgid "collections_add_submit"
+msgstr ""
+
+#: views/pages/collector_faq.thtml:50 views/pages/collector_firstrun.thtml:43
+#: views/pages/collector.thtml:47 views/pages/collector_features.thtml:55
+#: controllers/search_controller.php:302
+#: controllers/collections_controller.php:206
+#: controllers/collections_controller.php:405
+#: controllers/collections_controller.php:467
+#: controllers/collections_controller.php:539
+msgid "collections_breadcrumb"
+msgstr "Colecții"
+
+#: views/collections/detail.thtml:185
+msgid "collections_detail_a_learn"
+msgstr "Află mai multe"
+
+#: views/elements/amo2009/collection_add_form.thtml:53
+#: views/elements/amo2009/collections_js_init.thtml:68
+#: views/pages/collector_firstrun.thtml:64
+msgid "collections_detail_button_add"
+msgstr "Adaugă la favorite"
+
+#: views/elements/amo2009/collection_add_form.thtml:50
+#: views/elements/amo2009/collections_js_init.thtml:71
+msgid "collections_detail_button_remove"
+msgstr "Elimină din favorite"
+
+#. %1$s is a URL.
+#. %2$s is a full <a href>.
+#: views/collections/detail.thtml:62
+msgid "collections_detail_created_desc"
+msgstr ""
+
+#: views/collections/detail.thtml:61
+msgid "collections_detail_created_msg"
+msgstr ""
+
+#: views/collections/detail.thtml:109
+msgid "collections_detail_header_about"
+msgstr ""
+
+#. %1$s is a number.
+#: views/collections/detail.thtml:126
+msgid "collections_detail_header_count"
+msgid_plural "collections_detail_header_count"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+
+#: views/collections/detail.thtml:113
+msgid "collections_detail_info_created"
+msgstr ""
+
+#: views/collections/detail.thtml:117
+msgid "collections_detail_info_updated"
+msgstr ""
+
+#: views/elements/amo2009/collections_js_init.thtml:62
+msgid "collections_detail_js_adding"
+msgstr ""
+
+#: views/elements/amo2009/collections_js_init.thtml:65
+msgid "collections_detail_js_removing"
+msgstr ""
+
+#. %1$s is a URL
+#: views/collections/detail.thtml:90
+msgid "collections_detail_login"
+msgstr ""
+
+#: views/collections/detail.thtml:104
+msgid "collections_detail_manage"
+msgstr ""
+
+#: controllers/collections_controller.php:298
+msgid "collections_detail_sort_date"
+msgstr ""
+
+#: controllers/collections_controller.php:299
+msgid "collections_detail_sort_name"
+msgstr "Nume"
+
+#: controllers/collections_controller.php:300
+msgid "collections_detail_sort_popularity"
+msgstr "Popularitate"
+
+#. %1$s is a number.
+#: views/collections/detail.thtml:166
+msgid "collections_detail_weekly_downloads"
+msgid_plural "collections_detail_weekly_downloads"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+
+#: views/collections/edit.thtml:255
+msgid "collections_edit_addons_delete_noscript"
+msgstr ""
+
+#: views/collections/edit.thtml:247
+msgid "collections_edit_addons_description"
+msgstr ""
+
+#: views/collections/edit.thtml:248
+msgid "collections_edit_addons_description_noscript"
+msgstr ""
+
+#: views/collections/edit.thtml:247 views/collections/edit.thtml:248
+msgid "collections_edit_addons_description_publish_detailspage"
+msgstr ""
+
+#. %1$s is the date the add-on was added to the collection
+#. %1$s is the name of the user who added the add-on to the collection
+#: views/collections/edit.thtml:260
+msgid "collections_edit_addons_listitem_added"
+msgstr ""
+
+#: views/collections/edit.thtml:263
+msgid "collections_edit_addons_listitem_comment_add"
+msgstr ""
+
+#: views/collections/edit.thtml:266
+msgid "collections_edit_addons_listitem_comment_delete"
+msgstr ""
+
+#: views/collections/edit.thtml:265
+msgid "collections_edit_addons_listitem_comment_edit"
+msgstr ""
+
+#: views/collections/edit.thtml:271
+msgid "collections_edit_addons_listitem_comment_note"
+msgstr ""
+
+#: views/collections/edit.thtml:270
+msgid "collections_edit_addons_listitem_comment_submit"
+msgstr ""
+
+#: views/collections/edit.thtml:261
+msgid "collections_edit_addons_listitem_remove"
+msgstr "Elimină"
+
+#: views/collections/edit.thtml:250
+msgid "collections_edit_addons_submit"
+msgstr ""
+
+#: views/collections/edit.thtml:153
+msgid "collections_edit_check_nickname"
+msgstr ""
+
+#: views/collections/edit.thtml:299
+msgid "collections_edit_confirm_deletecollection"
+msgstr ""
+
+#. %1$s is the label of the edit form's submit button
+#: views/collections/edit.thtml:300
+msgid "collections_edit_confirm_deletecollection_description"
+msgstr ""
+
+#. %1$s is the "delete" submit button text
+#. %2$s is the title of the "advanced" tab
+#: views/collections/edit.thtml:95
+msgid "collections_edit_delete_upon_submit"
+msgstr ""
+
+#: views/collections/edit.thtml:94
+msgid "collections_edit_delete_warning"
+msgstr ""
+
+#: views/collections/add.thtml:76 views/collections/edit.thtml:144
+msgid "collections_edit_form_error_description"
+msgstr ""
+
+#: views/collections/edit.thtml:181
+msgid "collections_edit_form_error_icon"
+msgstr ""
+
+#: views/collections/add.thtml:69 views/collections/edit.thtml:130
+msgid "collections_edit_form_error_name"
+msgstr ""
+
+#: views/collections/edit.thtml:158
+msgid "collections_edit_form_error_nickname"
+msgstr ""
+
+#: views/collections/add.thtml:93 views/collections/edit.thtml:249
+msgid "collections_edit_formfield_addons"
+msgstr ""
+
+#: views/collections/edit.thtml:281
+msgid "collections_edit_formfield_application"
+msgstr ""
+
+#: views/collections/edit.thtml:282
+msgid "collections_edit_formfield_application_description"
+msgstr ""
+
+#: views/collections/edit.thtml:288
+msgid "collections_edit_formfield_collectiontype"
+msgstr ""
+
+#: views/collections/edit.thtml:295
+msgid "collections_edit_formfield_deletecollection"
+msgstr ""
+
+#: views/collections/edit.thtml:296
+msgid "collections_edit_formfield_deletecollection_description"
+msgstr ""
+
+#: views/collections/add.thtml:73 views/collections/edit.thtml:140
+msgid "collections_edit_formfield_description"
+msgstr ""
+
+#: views/collections/add.thtml:74 views/collections/edit.thtml:141
+msgid "collections_edit_formfield_description_description"
+msgstr ""
+
+#: views/collections/edit.thtml:162
+msgid "collections_edit_formfield_icon"
+msgstr "Iconiță"
+
+#: views/collections/edit.thtml:163
+msgid "collections_edit_formfield_icon_description"
+msgstr ""
+
+#: views/collections/add.thtml:80 views/collections/edit.thtml:189
+msgid "collections_edit_formfield_listed"
+msgstr ""
+
+#: views/collections/add.thtml:81 views/collections/edit.thtml:190
+msgid "collections_edit_formfield_listed_description"
+msgstr ""
+
+#: views/collections/add.thtml:84 views/collections/edit.thtml:193
+msgid "collections_edit_formfield_listed_false"
+msgstr ""
+
+#: views/collections/add.thtml:83 views/collections/edit.thtml:192
+msgid "collections_edit_formfield_listed_true"
+msgstr ""
+
+#: views/collections/edit.thtml:223
+msgid "collections_edit_formfield_managers"
+msgstr ""
+
+#: views/collections/edit.thtml:224
+msgid "collections_edit_formfield_managers_description"
+msgstr ""
+
+#: views/collections/add.thtml:66 views/collections/edit.thtml:126
+msgid "collections_edit_formfield_name"
+msgstr ""
+
+#: views/collections/add.thtml:67 views/collections/edit.thtml:127
+msgid "collections_edit_formfield_name_description"
+msgstr ""
+
+#: views/collections/edit.thtml:148
+msgid "collections_edit_formfield_nickname"
+msgstr ""
+
+#: views/collections/edit.thtml:149
+msgid "collections_edit_formfield_nickname_description"
+msgstr ""
+
+#: views/collections/edit.thtml:201
+msgid "collections_edit_formfield_publishers"
+msgstr ""
+
+#: views/collections/edit.thtml:202
+msgid "collections_edit_formfield_publishers_description"
+msgstr ""
+
+#: views/collections/edit.thtml:210 views/collections/edit.thtml:232
+msgid "collections_edit_formfield_users_add"
+msgstr ""
+
+#: views/collections/edit.thtml:216 views/collections/edit.thtml:238
+msgid "collections_edit_formfield_users_delete_noscript"
+msgstr ""
+
+#: views/collections/edit.thtml:215 views/collections/edit.thtml:237
+msgid "collections_edit_formfield_users_new_noscript"
+msgstr ""
+
+#: views/collections/edit.thtml:204 views/collections/edit.thtml:226
+msgid "collections_edit_formfield_users_onlyme"
+msgstr "Doar eu"
+
+#: views/collections/edit.thtml:205 views/collections/edit.thtml:227
+msgid "collections_edit_formfield_users_otherusers"
+msgstr "Eu și utilizatorii:"
+
+#: views/collections/edit.thtml:211 views/collections/edit.thtml:233
+msgid "collections_edit_formfield_users_submit"
+msgstr "Adaugă"
+
+#. %1$s is the name of the collection
+#: views/collections/edit.thtml:68
+msgid "collections_edit_header"
+msgstr "Gestionează %1$s"
+
+#: views/collections/edit.thtml:246
+msgid "collections_edit_header_addons"
+msgstr "Gestionează conținutul colecției"
+
+#: views/collections/edit.thtml:253 views/collections/edit.thtml:258
+msgid "collections_edit_header_addons_current"
+msgstr "Suplimentele curente:"
+
+#: views/collections/edit.thtml:279
+msgid "collections_edit_header_advanced"
+msgstr "Setări avansate"
+
+#: views/collections/edit.thtml:186
+msgid "collections_edit_header_permissions"
+msgstr "Gestionează permisiunile asupra colecției"
+
+#: views/collections/edit.thtml:170
+msgid "collections_edit_icon_cancel"
+msgstr "Renunță"
+
+#: views/collections/edit.thtml:174 views/collections/edit.thtml:179
+msgid "collections_edit_icon_delete"
+msgstr "Șterge iconița"
+
+#: views/collections/edit.thtml:178
+msgid "collections_edit_icon_replace"
+msgstr "Înlocuiește iconița"
+
+#. %1$s is the label of the edit form's submit button
+#: views/collections/edit.thtml:169
+msgid "collections_edit_icon_toberemoved"
+msgstr "Iconița va fi eliminată după ce faceți clic pe „%1$s†de mai jos"
+
+#: views/collections/edit.thtml:155
+msgid "collections_edit_nickname_available"
+msgstr "Pseudonim disponibil"
+
+#: controllers/collections_controller.php:943
+msgid "collections_edit_nickname_error"
+msgstr ""
+
+#: views/collections/edit.thtml:156
+msgid "collections_edit_nickname_taken"
+msgstr ""
+
+#. This string is followed by a URL pointing to the collection's view page
+#: views/collections/edit.thtml:75
+msgid "collections_edit_saved_nextstep"
+msgstr ""
+
+#: views/collections/edit.thtml:74
+msgid "collections_edit_saved_success"
+msgstr ""
+
+#: views/collections/edit.thtml:169 views/collections/edit.thtml:300
+#: views/collections/edit.thtml:308 views/pages/js_constants.js.thtml:99
+msgid "collections_edit_submit"
+msgstr ""
+
+#: views/collections/edit.thtml:96 views/collections/edit.thtml:297
+#: views/pages/js_constants.js.thtml:100
+msgid "collections_edit_submit_deletecollection"
+msgstr ""
+
+#: views/collections/edit.thtml:111
+msgid "collections_edit_tabheader_addons"
+msgstr "Suplimente"
+
+#: views/collections/edit.thtml:97 views/collections/edit.thtml:113
+msgid "collections_edit_tabheader_advanced"
+msgstr "Avansat"
+
+#: views/collections/edit.thtml:108
+msgid "collections_edit_tabheader_details"
+msgstr ""
+
+#: views/collections/edit.thtml:109
+msgid "collections_edit_tabheader_permissions"
+msgstr "Permisiuni"
+
+#: models/collection_promo.php:53
+msgid "collections_family_tagline"
+msgstr ""
+
+#: models/collection_promo.php:53
+msgid "collections_family_title"
+msgstr "Familie"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:70
+msgid "collections_index_a_check_out"
+msgstr ""
+
+#: views/elements/amo2009/collector_info_secondary.thtml:52
+msgid "collections_index_a_create"
+msgstr "Creați o colecție"
+
+#: views/collections/detail.thtml:139 views/collections/listing.thtml:85
+#: views/search/collections.thtml:84
+msgid "collections_index_button_go"
+msgstr "Du-te"
+
+#. %1$s is a URL.
+#: controllers/collections_controller.php:182
+msgid "collections_index_filler_favorites"
+msgstr ""
+
+#. %1$s is a URL.
+#: controllers/collections_controller.php:167
+msgid "collections_index_filler_mine"
+msgstr ""
+
+#: views/collections/listing.thtml:51
+msgid "collections_index_header_collections"
+msgstr "Colecții"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:60
+msgid "collections_index_header_collector"
+msgstr ""
+
+#. %1$s is a comma-separated list of author names
+#: views/elements/amo2009/collection_listing_item.thtml:84
+#: views/collections/detail.thtml:151
+msgid "collections_index_header_created"
+msgstr ""
+
+#: views/elements/amo2009/collector_info_secondary.thtml:47
+msgid "collections_index_header_what"
+msgstr ""
+
+#: views/collections/detail.thtml:132 views/collections/listing.thtml:78
+#: views/search/collections.thtml:66
+msgid "collections_index_label_sortby"
+msgstr "Sortează după"
+
+#: controllers/collections_controller.php:130
+msgid "collections_index_li_editors"
+msgstr ""
+
+#: views/collections/subscribe.thtml:64
+#: controllers/collections_controller.php:140
+msgid "collections_index_li_favorites"
+msgstr "Favoritele mele"
+
+#: controllers/collections_controller.php:138
+msgid "collections_index_li_mine"
+msgstr "Colecțiile mele"
+
+#: controllers/collections_controller.php:132
+msgid "collections_index_li_popular"
+msgstr "Popular"
+
+#: views/search/collections.thtml:74 controllers/collections_controller.php:81
+msgid "collections_index_option_all"
+msgstr "Cele mai populare per total"
+
+#: views/search/collections.thtml:72 controllers/collections_controller.php:78
+msgid "collections_index_option_month"
+msgstr "Cele mai populare de luna asta"
+
+#: views/search/collections.thtml:76 controllers/collections_controller.php:84
+msgid "collections_index_option_newest"
+msgstr "Cel mai nou"
+
+#: views/search/collections.thtml:70 controllers/collections_controller.php:75
+msgid "collections_index_option_week"
+msgstr "Cele mai populare în săptămâna asta"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:67
+msgid "collections_index_p_collector"
+msgstr ""
+
+#: views/elements/amo2009/collector_info_secondary.thtml:48
+msgid "collections_index_p_what_are"
+msgstr ""
+
+#. %s is a date in the _('date') format
+#: views/elements/collections_interactive_addon.thtml:85
+#, php-format
+msgid "collections_interactive_addon_added"
+msgstr "Adăugat %s"
+
+#: models/collection_promo.php:55
+msgid "collections_reference_tagline"
+msgstr ""
+
+#: models/collection_promo.php:55
+msgid "collections_reference_title"
+msgstr "Referință"
+
+#: models/collection_promo.php:52
+msgid "collections_social_tagline"
+msgstr ""
+
+#: models/collection_promo.php:52
+msgid "collections_social_title"
+msgstr ""
+
+#: views/collections/subscribe.thtml:91
+msgid "collections_subscribe_button_close"
+msgstr "ÃŽnchide"
+
+#: views/collections/subscribe.thtml:70
+msgid "collections_subscribe_error"
+msgstr ""
+
+#: views/collections/subscribe.thtml:96
+msgid "collections_subscribe_label_bothersome"
+msgstr ""
+
+#. %1$s is the collection name
+#: views/collections/subscribe.thtml:60
+msgid "collections_subscribe_success"
+msgstr ""
+
+#. %1$s is the link to the "My Favorites" tab on the main collections page
+#. %2$s is the localized title of the "My Favorites" tab
+#. %3$s is the link URL to the collector add-on
+#: views/collections/subscribe.thtml:62
+msgid "collections_subscribe_success_desc"
+msgstr ""
+
+#: views/collections/listing.thtml:55
+msgid "collections_success_delete"
+msgstr ""
+
+#: models/collection_promo.php:54
+msgid "collections_travel_tagline"
+msgstr ""
+
+#: models/collection_promo.php:54
+msgid "collections_travel_title"
+msgstr "Călătorie"
+
+#. A collection of add-ons that is automatically built for a user. They are "automatically published" to this collection.
+#: controllers/collections_controller.php:581
+msgid "collections_type_autopublisher"
+msgstr ""
+
+#. A collection that has been chosen by an Editor as notable or exceptional
+#: controllers/collections_controller.php:582
+msgid "collections_type_editorspick"
+msgstr ""
+
+#: controllers/collections_controller.php:580
+msgid "collections_type_normal"
+msgstr "Normal"
+
+#: views/collections/subscribe.thtml:84
+msgid "collections_unsubscribe_error"
+msgstr ""
+
+#. %1$s is the collection name
+#: views/collections/subscribe.thtml:78
+msgid "collections_unsubscribe_success"
+msgstr ""
+
+#: models/collection_promo.php:56
+msgid "collections_webdev_tagline"
+msgstr ""
+
+#: models/collection_promo.php:56
+msgid "collections_webdev_title"
+msgstr "Dezvoltare web"
+
+#: views/elements/amo2009/collections_sidebar_whatare.thtml:40
+msgid "collections_whatare_header"
+msgstr ""
+
+#: views/elements/amo2009/collections_sidebar_whatare.thtml:45
+msgid "collections_whatare_learnmore"
+msgstr ""
+
+#: views/elements/amo2009/collections_sidebar_whatare.thtml:44
+msgid "collections_whatare_text"
+msgstr ""
+
+#: views/pages/collector_faq.thtml:61 views/pages/collector_features.thtml:67
+msgid "collector_features_a_home"
+msgstr ""
+
+#: views/elements/amo2009/collector_sidebar_download.thtml:46
+msgid "collector_features_heading_download"
+msgstr ""
+
+#: views/elements/amo2009/collector_sidebar_download.thtml:43
+#: views/pages/collector_firstrun.thtml:116 views/pages/collector.thtml:69
+msgid "collector_features_img_logo"
+msgstr ""
+
+#: views/compatibility/dashboard.thtml:49
+#: controllers/compatibility_controller.php:72
+msgid "compatibility_dashboard_center_header"
+msgstr "Centrul de compatibilitate a suplimentelor"
+
+#. %1$s is the name of an application and a version. Example: Firefox 3.0
+#. %2$s is the name of an application. Example: Firefox
+#: views/compatibility/dashboard.thtml:50
+msgid "compatibility_dashboard_intro"
+msgstr ""
+
+#: views/compatibility/dashboard.thtml:103
+msgid "compatibility_dashboard_loading"
+msgstr "Se încarcă datele..."
+
+#: views/compatibility/dashboard.thtml:45
+msgid "compatibility_dashboard_main_link"
+msgstr "Înapoi la pagina principală"
+
+#: views/compatibility/dashboard.thtml:100 views/compatibility/report.thtml:43
+msgid "compatibility_dashboard_report"
+msgstr "Raport de compatibilitate al suplimentului"
+
+#: views/compatibility/dashboard.thtml:53
+#: views/compatibility/dashboard.thtml:110
+#: views/compatibility/developers.thtml:43
+msgid "compatibility_developer_info"
+msgstr "Informații pentru dezvoltatorii de suplimente"
+
+#: views/compatibility/developers.thtml:66
+msgid "compatibility_developers_adjust_maxversion"
+msgstr "Ajustare parametru maxVersion fără încărcare"
+
+#: views/compatibility/dashboard.thtml:124
+msgid "compatibility_developers_check_status"
+msgstr "Verifică starea suplimentelor mele"
+
+#. %1$s is a URL
+#. %2$s is an application and version. Example: Firefox 3.0
+#: views/compatibility/dashboard.thtml:126
+msgid "compatibility_developers_login_first"
+msgstr ""
+"Dacă aveți suplimente găzduite pe Mozilla Add-ons, <a href=\"%1$s\">vă rugăm "
+"să vă autentificați</a> pentru a analiza starea suplimentelor dumneavoastră "
+"pentru %2$s."
+
+#: views/compatibility/dashboard.thtml:114
+msgid "compatibility_developers_mdclogo_alt"
+msgstr "Sigla Mozilla Developer Center"
+
+#: views/compatibility/developers.thtml:73
+msgid "compatibility_developers_no_addons"
+msgstr "Nu aveți nici un supliment găzduit de Mozilla Add-ons."
+
+#: views/compatibility/dashboard.thtml:133
+#: views/compatibility/developers.thtml:55
+msgid "compatibility_developers_results"
+msgstr "Rezultatele verificării stării suplimentelor"
+
+#: views/compatibility/dashboard.thtml:137
+msgid "compatibility_developers_retrieving"
+msgstr "Se obține starea suplimentelor găzduite..."
+
+#. %1$s is a number
+#. %2$s is an application name
+#. %3$s is a number.
+#. Full example: 50 Firefox users (10% of total)
+#: views/compatibility/developers.thtml:65
+msgid "compatibility_developers_user_count"
+msgstr "%1$s utilizează %2$s (%3$s&#37; din total)"
+
+#: views/compatibility/report.thtml:45
+msgid "compatibility_report_detail_intro"
+msgstr ""
+"Suplimentele de mai jos au o rată de utilizare cunoscută de Mozilla ca 95% și "
+"sunt ordonate după utilizarea lor."
+
+#: views/compatibility/dashboard.thtml:94
+msgid "compatibility_report_detailed_link"
+msgstr "Arată raportul detaliat"
+
+#. %1$s and %2$s are numbers
+#. %3$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:65
+msgid "compatibility_report_intro"
+msgstr ""
+"Din cele %1$s suplimente care însumează o frecvență de utilizare cunoscută de "
+"Mozilla ca fiind de 95&#37;, <b>%2$s&#37;</b> sunt în prezent considerate "
+"compatibile cu ultimele versiuni de %3$s."
+
+#: views/compatibility/dashboard.thtml:81
+msgid "compatibility_report_legend_alpha"
+msgstr "Versiuni alfa"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:81
+msgid "compatibility_report_legend_alpha_description"
+msgstr "Suplimente compatibile cu o versiune alfa de %1$s"
+
+#: views/compatibility/dashboard.thtml:85
+msgid "compatibility_report_legend_beta"
+msgstr "Versiuni beta"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:85
+msgid "compatibility_report_legend_beta_description"
+msgstr ""
+"Suplimente compatibile cu o versiune beta sau cu un candidat pentru lansarea %"
+"1$s"
+
+#: views/compatibility/dashboard.thtml:89
+msgid "compatibility_report_legend_latest"
+msgstr "Ultima versiune"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:89
+msgid "compatibility_report_legend_latest_description"
+msgstr "Suplimente compatibile cu cele mai recente compilări de %1$s"
+
+#: views/compatibility/dashboard.thtml:77
+msgid "compatibility_report_legend_other"
+msgstr "Alte versiuni"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:77
+msgid "compatibility_report_legend_other_description"
+msgstr "Suplimente incompatibile cu orice versiune de %1$s"
+
+#: views/compatibility/dashboard.thtml:62
+msgid "compatibility_report_title"
+msgstr "Raport de compatibilitate al suplimentului"
+
+#: views/compatibility/dashboard.thtml:54
+#: views/compatibility/dashboard.thtml:144 views/compatibility/users.thtml:42
+msgid "compatibility_user_info"
+msgstr "Informații pentru utilizatorii de suplimente"
+
+#: views/compatibility/dashboard.thtml:52
+msgid "compatibility_view_report"
+msgstr "Arată raportul de compatibilitate"
+
+#. %s is a URL
+#: views/pages/credits.thtml:142
+#, php-format
+msgid "credits_contributing"
+msgstr "Pentru informații despre contribuție, vedeți %s."
+
+#: views/pages/credits.thtml:142
+msgid "credits_contributing_wikipage"
+msgstr "pagina de wiki"
+
+#: views/pages/credits.thtml:99
+msgid "credits_intro"
+msgstr ""
+"Mozilla ar dori să mulțumească următoarelor persoane pentru contribuțiile lor "
+"la proiectul addons.mozilla.org de-a lungul anilor:"
+
+#: views/pages/credits.thtml:103
+msgid "credits_section_developers"
+msgstr "Dezvoltatori"
+
+#: views/pages/credits.thtml:115
+msgid "credits_section_editors"
+msgstr "Editori"
+
+#: views/pages/credits.thtml:109
+msgid "credits_section_localizers"
+msgstr "Traducători"
+
+#: views/pages/credits.thtml:121
+msgid "credits_section_other_contributors"
+msgstr "Alți colaboratori"
+
+#: views/pages/credits.thtml:127
+msgid "credits_section_past_developers"
+msgstr "Foști dezvoltatori"
+
+#: views/pages/credits.thtml:133
+msgid "credits_section_software"
+msgstr "Software și imagini"
+
+#: views/pages/credits.thtml:136
+msgid "credits_software_famfamfam"
+msgstr ""
+"Unele iconițe folosite provin din <a href=\"http://www.famfamfam.com/lab/"
+"icons/silk/\">famfamfam Silk Icon Set</a>, licențiat sub <a href=\"http://"
+"creativecommons.org/licenses/by/2.5/\">Creative Commons Attribution 2.5 "
+"License</a>."
+
+#: views/pages/credits.thtml:137
+msgid "credits_software_timeplot"
+msgstr ""
+"Unele pagini folosesc componente <a href=\"http://www.simile-widgets.org/"
+"timeplot/\">Timeplot</a>, aflate sub <a href=\"http://simile.mit.edu/license."
+"html\">Licență BSD</a>."
+
+#. date format string as used in PHP's strftime():
+#. http://php.net/strftime
+#: views/elements/collections_interactive_addon.thtml:85
+#: views/elements/amo2009/addon_version_detail.thtml:53
+#: views/elements/amo2009/homepage_addon.thtml:115
+#: views/elements/addon_version_detail.thtml:54
+#: views/elements/addon_listitem.thtml:124 views/elements/feature.thtml:106
+#: views/collections/detail.thtml:118 views/collections/edit.thtml:325
+#: views/users/info.thtml:76 views/editors/reviews_queue.thtml:57
+#: views/editors/reviews_queue.thtml:68 views/developers/dashboard.thtml:65
+#: views/developers/versions_edit.thtml:208 views/developers/versions.thtml:67
+#: views/search/rss/index.thtml:5 views/addons/rss/versions.thtml:42
+#: views/addons/display.thtml:104 views/addons/display.thtml:356
+#: views/addons/browse_thumbs.thtml:75 views/reviews/add.thtml:63
+#: views/reviews/display.thtml:74 views/reviews/display.thtml:160
+#: views/reviews/delete.thtml:54 controllers/statistics_controller.php:244
+#: controllers/collections_controller.php:1047
+msgid "date"
+msgstr "%e %B %Y"
+
+#. date and time format string (strftime)
+#. http://php.net/strftime
+#: views/elements/addon_version_detail.thtml:53
+#: views/developers/discuss.thtml:52 views/developers/discuss.thtml:62
+#: views/admin/addons_status.thtml:57
+msgid "datetime"
+msgstr "%e %B %Y, %k:%M"
+
+#: views/elements/developers/actionbar.thtml:47
+msgid "devcp_actionbar_link_details"
+msgstr "Informații detaliate"
+
+#: views/elements/developers/actionbar.thtml:42
+#: views/elements/developers/actionbar.thtml:50
+#: views/developers/dashboard.thtml:64
+msgid "devcp_actionbar_link_edit"
+msgstr "Editează suplimentul"
+
+#: views/elements/developers/actionbar.thtml:51
+msgid "devcp_actionbar_link_newversion"
+msgstr "Încarcă o versiune nouă"
+
+#: views/elements/developers/actionbar.thtml:44
+#: views/elements/developers/actionbar.thtml:49
+#: views/developers/dashboard.thtml:73
+msgid "devcp_actionbar_link_stats"
+msgstr "Tabolul de bord al statisticilor"
+
+#. %1$s is a filename, e.g. "foo.txt"
+#. %2$s is the extension, e.g. ".txt"
+#. %3$s is a list of valid extensions, like ".png, .jpg, .gif"
+#: controllers/developers_controller.php:1361
+msgid "devcp_add_previews_extension_error"
+msgstr "Fișierul %1$s are o extensie nevalidă (%2$s). Extensii permise: %3$s"
+
+#. %s is the filename.
+#: controllers/developers_controller.php:1394
+msgid "devcp_add_previews_save_error"
+msgstr ""
+"Fișierul %s nu poate fi salvat în baza de date. Vă rugăm să încercați din nou."
+
+#. %1$s is the preview ID number, %2$s is the filename.
+#: controllers/developers_controller.php:1389
+msgid "devcp_add_previews_success_replace"
+msgstr "Previzualizarea %1$s a fost înlocuită cu succes de fișierul %2$s ."
+
+#. %s is the filename.
+#: controllers/developers_controller.php:1391
+msgid "devcp_add_previews_success_upload"
+msgstr ""
+"Fișierul %s a fost încărcat cu succes. Puteți adăuga o explicație dedesubt."
+
+#: controllers/components/developers.php:1163
+msgid "devcp_additem_addontype_autodetect"
+msgstr "(detectare automată)"
+
+#: views/elements/developers/additem.thtml:76
+msgid "devcp_additem_linktitle_opensin_newwindow"
+msgstr "Se deschide într-o fereastră nouă"
+
+#: views/elements/developers/additem.thtml:41
+msgid "devcp_additem_sidebar_title"
+msgstr "Trimite un supliment"
+
+#: views/elements/developers/additem.thtml:53
+msgid "devcp_additem_step0_newlink"
+msgstr "Acord cu dezvoltatorul"
+
+#: views/elements/developers/additem.thtml:46
+msgid "devcp_additem_step1_link"
+msgstr "Pasul 1: Încărcare"
+
+#: views/elements/developers/additem.thtml:47
+msgid "devcp_additem_step2_link"
+msgstr "Pasul 2: Detalii supliment"
+
+#: views/elements/developers/additem.thtml:48
+msgid "devcp_additem_step3_link"
+msgstr "Pasul 3: Detalii versiune"
+
+#: views/elements/developers/additem.thtml:49
+msgid "devcp_additem_step4_link"
+msgstr "Pasul 4: Localizare"
+
+#: views/elements/developers/additem.thtml:50
+msgid "devcp_additem_step5_link"
+msgstr "Pasul 5: Succes"
+
+#: views/elements/developers/additem.thtml:76
+msgid "devcp_additem_submissionhelp_link"
+msgstr "Ajutor pentru trimiterea suplimentelor"
+
+#: controllers/previews_controller.php:168
+#: controllers/previews_controller.php:277
+msgid "devcp_addon_field_preview_caption_displaytitle"
+msgstr "Titlu avanpremieră"
+
+#: views/developers/addon_status.thtml:177
+msgid "devcp_addon_status_action_activate"
+msgstr "Activați"
+
+#: views/developers/addon_status.thtml:178
+msgid "devcp_addon_status_action_activate_description"
+msgstr ""
+"Activați suplimentul dvs. pentru a fi afișat în listele publice și pentru a "
+"permite verificarea actualizărilor."
+
+#: views/developers/addon_status.thtml:135
+msgid "devcp_addon_status_action_complete"
+msgstr ""
+
+#: views/developers/addon_status.thtml:136
+msgid "devcp_addon_status_action_complete_description"
+msgstr ""
+
+#: views/developers/addon_status.thtml:181
+msgid "devcp_addon_status_action_deactivate"
+msgstr "Dezactivați"
+
+#: views/developers/addon_status.thtml:182
+msgid "devcp_addon_status_action_deactivate_description"
+msgstr ""
+"Dezactivați suplimentul dvs. pentru a nu mai fi afișat în listele publice și "
+"pentru a întrerupe verificările de actualizare."
+
+#: views/developers/addon_status.thtml:143
+msgid "devcp_addon_status_action_move"
+msgstr "Mută în cutia cu nisip"
+
+#: views/developers/addon_status.thtml:144
+msgid "devcp_addon_status_action_move_description"
+msgstr ""
+"Mutați suplimentul înapoi în cutia cu nisip. Procedura este reversibilă."
+
+#: views/developers/addon_status.thtml:139
+msgid "devcp_addon_status_action_nominate"
+msgstr "Nominalizare pentru public"
+
+#: views/developers/addon_status.thtml:140
+msgid "devcp_addon_status_action_nominate_description"
+msgstr "Nominalizați suplimentul pentru a deveni public"
+
+#: views/developers/addon_status.thtml:147
+msgid "devcp_addon_status_action_public"
+msgstr "Faceți-l public"
+
+#: views/developers/addon_status.thtml:148
+msgid "devcp_addon_status_action_public_description"
+msgstr "Faceți suplimentul public din nou."
+
+#: views/developers/addon_status.thtml:169
+msgid "devcp_addon_status_active"
+msgstr ""
+"Suplimentul este <span class=\"inactive-0\">activ</span>. Aceasta înseamnă că "
+"suplimentul va fi afișat în toate listele corespunzătoare stării sale de mai "
+"sus."
+
+#: views/developers/addon_status.thtml:111
+msgid "devcp_addon_status_completion_disabled"
+msgstr ""
+"Vă rugăm să îndepliniți criteriile de mai sus înainte de a finaliza "
+"suplimentul și a-l muta în <span class=\"status-1\">cutia cu nisip</span>."
+
+#: views/developers/addon_status.thtml:108
+msgid "devcp_addon_status_completion_enabled"
+msgstr ""
+"Acum puteți să vă finalizați suplimentul și să îl mutați în <span class="
+"\"status-1\">cutia cu nisip</span> apăsând butonul de mai jos."
+
+#: views/developers/addon_status.thtml:102
+msgid "devcp_addon_status_criteria_category"
+msgstr "S-a selectat cel puțin o categorie"
+
+#: views/developers/addon_status.thtml:101
+msgid "devcp_addon_status_criteria_description"
+msgstr "Descrierea suplimentului este obligatorie"
+
+#: views/developers/addon_status.thtml:99
+msgid "devcp_addon_status_criteria_name"
+msgstr "Numele suplimentului este obligatoriu"
+
+#: views/developers/addon_status.thtml:120
+msgid "devcp_addon_status_criteria_prerelease"
+msgstr ""
+
+#: views/developers/addon_status.thtml:119
+msgid "devcp_addon_status_criteria_preview"
+msgstr ""
+
+#: views/developers/addon_status.thtml:100
+msgid "devcp_addon_status_criteria_summary"
+msgstr ""
+
+#. %s is the status in a span, e.g. "<span>_('Public')</span>".
+#: views/developers/addon_status.thtml:58
+msgid "devcp_addon_status_header"
+msgstr ""
+
+#: views/developers/addon_status.thtml:152
+#: views/developers/addon_status.thtml:173
+msgid "devcp_addon_status_header_actions"
+msgstr "Acțiuni disponibile"
+
+#: views/developers/addon_status.thtml:168
+msgid "devcp_addon_status_header_active"
+msgstr ""
+
+#: views/developers/addon_status.thtml:97
+msgid "devcp_addon_status_header_criteria"
+msgstr "Criteriile de completare a suplimentului"
+
+#: views/developers/addon_status.thtml:164
+msgid "devcp_addon_status_header_inactive"
+msgstr "Stare: <span class=\"inactiv-1\">inactiv</span>"
+
+#: views/developers/addon_status.thtml:117
+msgid "devcp_addon_status_header_nomination"
+msgstr "Criteriile de nominalizare publică"
+
+#: views/developers/addon_status.thtml:190
+msgid "devcp_addon_status_header_trusted"
+msgstr "Stare de încredere: <span class=\"stare-4\">de încredere</span>"
+
+#: views/developers/addon_status.thtml:165
+msgid "devcp_addon_status_inactive"
+msgstr ""
+"Suplimentul este <span class=\"inactiv-1\">inactiv</span>. Asta înseamnă că "
+"suplimentul nu va apărea în nicio listă, indiferent de starea sa dinainte. "
+"Actualizările <b>nu</b> sunt furnizate suplimentului prin serviciul de "
+"verificare al actualizărilor."
+
+#: views/developers/addon_status.thtml:128
+msgid "devcp_addon_status_nominate_disabled"
+msgstr ""
+
+#: views/developers/addon_status.thtml:125
+msgid "devcp_addon_status_nominate_enabled"
+msgstr ""
+
+#: views/developers/addon_status.thtml:64
+msgid "devcp_addon_status_public"
+msgstr "Public"
+
+#: views/developers/addon_status.thtml:63
+msgid "devcp_addon_status_sandbox"
+msgstr "Cutia cu nisip"
+
+#. %s is an email address.
+#: views/developers/addon_status.thtml:89
+msgid "devcp_addon_status_switch_disabled"
+msgstr ""
+
+#: views/developers/addon_status.thtml:67
+msgid "devcp_addon_status_switch_incomplete"
+msgstr ""
+
+#. %s is a number, perhaps 42.
+#: views/developers/addon_status.thtml:77
+msgid "devcp_addon_status_switch_nominated"
+msgstr ""
+
+#. %s is an email address.
+#: views/developers/addon_status.thtml:81
+msgid "devcp_addon_status_switch_pending"
+msgstr ""
+
+#: views/developers/addon_status.thtml:85
+msgid "devcp_addon_status_switch_public"
+msgstr ""
+
+#: views/developers/addon_status.thtml:71
+#: views/developers/addon_status.thtml:75
+msgid "devcp_addon_status_switch_sandbox"
+msgstr ""
+
+#. %s is the add-on name.
+#: views/developers/addon_status_nominate.thtml:43
+#: views/developers/addon_status_confirm.thtml:43
+#: views/developers/addon_status.thtml:43
+msgid "devcp_addon_status_title"
+msgstr ""
+
+#: views/developers/addon_status.thtml:191
+msgid "devcp_addon_status_trusted"
+msgstr ""
+
+#: views/developers/dashboard.thtml:68
+msgid "devcp_dashboard_active"
+msgstr "Activ"
+
+#. %1$s is the add-on type string
+#. %2$s is Inactive or Active in a <span>
+#. %3$s is the addon's public status (Public, In Sandbox, ...) in a <span>
+#: views/developers/dashboard.thtml:69
+msgid "devcp_dashboard_addontype_status"
+msgstr "%1$s actualmente %2$s și %3$s"
+
+#: views/developers/dashboard.thtml:67
+msgid "devcp_dashboard_change_status"
+msgstr "Schimbă starea"
+
+#. %s is the addons email address.
+#: views/developers/dashboard.thtml:99
+msgid "devcp_dashboard_disabled_questions"
+msgstr ""
+
+#. %s is the (localized) add-on status string in a span, e.g. "Disabled"
+#: views/developers/dashboard.thtml:98
+msgid "devcp_dashboard_disabled_status"
+msgstr ""
+
+#: views/developers/dashboard.thtml:43
+msgid "devcp_dashboard_header_main"
+msgstr ""
+
+#: views/developers/dashboard.thtml:110
+msgid "devcp_dashboard_header_welcome"
+msgstr ""
+
+#: views/developers/dashboard.thtml:68
+msgid "devcp_dashboard_inactive"
+msgstr "Inactiv"
+
+#. %s is a date in the _('date') format
+#: views/developers/dashboard.thtml:65
+msgid "devcp_dashboard_last_edited"
+msgstr ""
+
+#: views/developers/dashboard.thtml:111
+msgid "devcp_dashboard_learn"
+msgstr ""
+
+#: views/developers/dashboard.thtml:112
+msgid "devcp_dashboard_start"
+msgstr ""
+
+#: views/developers/dashboard.thtml:82
+msgid "devcp_dashboard_versions"
+msgstr ""
+
+#: views/developers/dashboard.thtml:91
+msgid "devcp_dashboard_versions_new"
+msgstr ""
+
+#. %s is the preview ID number.
+#: controllers/developers_controller.php:1415
+msgid "devcp_delete_previews_error"
+msgstr ""
+
+#. %s is the preview ID number.
+#: controllers/developers_controller.php:1413
+msgid "devcp_delete_previews_success"
+msgstr ""
+
+#: controllers/developers_controller.php:1089
+msgid "devcp_delete_version_priv_error"
+msgstr ""
+
+#. %1$s is the count of files, a number
+#. %2$s is a status string like _('Public') or _('Incomplete')
+#: controllers/components/amo.php:549
+msgid "devcp_describe_version_status"
+msgid_plural "devcp_describe_version_status"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+
+#. %s is a version number. Example: 3.0
+#: views/developers/versions.thtml:65
+#, php-format
+msgid "devcp_details_version"
+msgstr "Versiunea %s"
+
+#: views/developers/discuss.thtml:68
+msgid "devcp_discuss_addreply_header"
+msgstr ""
+
+#: views/developers/discuss.thtml:57
+msgid "devcp_discuss_allreplies_header"
+msgstr ""
+
+#. notice when an error occurs saving a discussion reply
+#. %1 is the email address (linked) for the amo-editors list
+#: views/developers/discuss.thtml:70
+msgid "devcp_discuss_error_notice"
+msgstr ""
+
+#. %1 is the add-on name, %2 is the add-on's version number currently being reviewed by an editor
+#: views/developers/discuss.thtml:46
+msgid "devcp_discuss_intro"
+msgstr ""
+
+#. %1 is the add-on name
+#: views/developers/discuss.thtml:43
+msgid "devcp_discuss_pagetitle"
+msgstr ""
+
+#. submit button text
+#: views/developers/discuss.thtml:79
+msgid "devcp_discuss_submit_reply"
+msgstr "Trimite răspuns"
+
+#: views/developers/discuss.thtml:72
+msgid "devcp_discuss_success_message"
+msgstr ""
+
+#. in an author/editor discussion about an add-on to be reviewed:
+#. %1 is the commenter's user name (linked).
+#. %2 is the full date the comment was made.
+#: views/developers/discuss.thtml:52 views/developers/discuss.thtml:62
+msgid "devcp_discuss_writtenby"
+msgstr ""
+
+#: views/developers/addon_edit_authors.thtml:72
+#: views/developers/addon_edit_authors.thtml:81
+msgid "devcp_edit_authors_add_author"
+msgstr "Adaugă un autor nou"
+
+#: views/developers/addon_edit_authors.thtml:96
+msgid "devcp_edit_authors_add_author_button"
+msgstr "Adaugă un autor"
+
+#: views/developers/addon_edit_authors.thtml:83
+msgid "devcp_edit_authors_add_email"
+msgstr ""
+
+#: views/developers/addon_edit_authors.thtml:98
+msgid "devcp_edit_authors_add_loading"
+msgstr ""
+
+#: views/developers/addon_edit_authors.thtml:70
+msgid "devcp_edit_authors_click_save"
+msgstr ""
+
+#: views/developers/addon_edit_authors.thtml:58
+msgid "devcp_edit_authors_header_current"
+msgstr ""
+
+#: views/developers/addon_edit_authors.thtml:50
+msgid "devcp_edit_authors_header_manage"
+msgstr ""
+
+#: views/developers/addon_edit_authors.thtml:93
+msgid "devcp_edit_authors_label_add_listed"
+msgstr ""
+
+#: views/developers/addon_edit_authors.thtml:89
+msgid "devcp_edit_authors_label_developer"
+msgstr ""
+
+#: views/developers/addon_edit_authors.thtml:88
+msgid "devcp_edit_authors_label_owner"
+msgstr ""
+
+#: views/developers/addon_edit_authors.thtml:90
+msgid "devcp_edit_authors_label_viewer"
+msgstr ""
+
+#. Placeholder for the empty option in a <select>.
+#: views/developers/addon_edit_categories.thtml:69
+msgid "devcp_edit_authors_option_empty"
+msgstr ""
+
+#: views/developers/addon_edit_authors.thtml:86
+msgid "devcp_edit_authors_select_role"
+msgstr ""
+
+#. Column name in a table.
+#: views/developers/addon_edit_authors.thtml:62
+msgid "devcp_edit_authors_th_author"
+msgstr "Autor"
+
+#. Column name in a table.
+#: views/developers/addon_edit_authors.thtml:64
+msgid "devcp_edit_authors_th_listed"
+msgstr ""
+
+#. Column name in a table.
+#: views/developers/addon_edit_authors.thtml:63
+msgid "devcp_edit_authors_th_role"
+msgstr "Rol"
+
+#: views/developers/addon_edit_authors.thtml:77
+msgid "devcp_edit_authors_update_author"
+msgstr ""
+
+#: views/developers/addon_edit_categories.thtml:99
+msgid "devcp_edit_categories_button_update"
+msgstr ""
+
+#: views/developers/addon_edit_categories.thtml:88
+msgid "devcp_edit_categories_does_not_fit"
+msgstr ""
+
+#. %s is the application name (Firefox, Thunderbird).
+#: views/developers/addon_edit_categories.thtml:61
+msgid "devcp_edit_categories_header_application"
+msgstr ""
+
+#: views/developers/addon_edit_categories.thtml:49
+msgid "devcp_edit_categories_header_manage"
+msgstr ""
+
+#: views/developers/addon_edit_categories.thtml:91
+msgid "devcp_edit_categories_hover"
+msgstr ""
+
+#. %s is the category number (1, 2, 3).
+#: views/developers/addon_edit_categories.thtml:67
+msgid "devcp_edit_categories_label_category_num"
+msgstr ""
+
+#: views/developers/addon_edit_categories.thtml:94
+#: views/developers/addon_edit_categories.thtml:103
+msgid "devcp_edit_categories_none_available"
+msgstr ""
+
+#: views/developers/addon_edit_categories.thtml:86
+msgid "devcp_edit_categories_other"
+msgstr ""
+
+#. %s is the application name (Firefox, Thunderbird).
+#: views/developers/addon_edit_categories.thtml:63
+msgid "devcp_edit_categories_select_application_categories"
+msgstr ""
+
+#: views/developers/addon_edit.thtml:47
+msgid "devcp_edit_dd_manage_authors"
+msgstr ""
+
+#: views/developers/addon_edit.thtml:49
+msgid "devcp_edit_dd_manage_categories"
+msgstr ""
+
+#: views/developers/addon_edit.thtml:51
+msgid "devcp_edit_dd_manage_description"
+msgstr ""
+
+#: views/developers/addon_edit.thtml:53
+msgid "devcp_edit_dd_manage_properties"
+msgstr ""
+
+#: views/developers/addon_edit_descriptions.thtml:116
+msgid "devcp_edit_description_button_update"
+msgstr ""
+
+#: views/developers/addon_edit_descriptions.thtml:115
+msgid "devcp_edit_description_correct_error"
+msgstr ""
+
+#: views/developers/addon_edit_descriptions.thtml:51
+msgid "devcp_edit_descriptions_header"
+msgstr ""
+
+#: views/developers/addon_edit_descriptions.thtml:94
+msgid "devcp_edit_descriptions_transbox_comments_description"
+msgstr ""
+
+#: views/developers/addon_edit_descriptions.thtml:93
+msgid "devcp_edit_descriptions_transbox_comments_name"
+msgstr "Comentariile dezvoltatorului"
+
+#: views/developers/addon_edit_descriptions.thtml:86
+msgid "devcp_edit_descriptions_transbox_description_description"
+msgstr ""
+
+#: views/developers/addon_edit_descriptions.thtml:85
+msgid "devcp_edit_descriptions_transbox_description_name"
+msgstr "Descriere supliment"
+
+#: views/developers/addon_edit_descriptions.thtml:103
+msgid "devcp_edit_descriptions_transbox_eula_description"
+msgstr ""
+
+#: views/developers/addon_edit_descriptions.thtml:102
+msgid "devcp_edit_descriptions_transbox_eula_name"
+msgstr "Acord de licențiere cu utilizatorul"
+
+#: views/developers/addon_edit_descriptions.thtml:112
+msgid "devcp_edit_descriptions_transbox_privacy_description"
+msgstr ""
+
+#: views/developers/addon_edit_descriptions.thtml:111
+msgid "devcp_edit_descriptions_transbox_privacy_name"
+msgstr "Politică de confidențialitate"
+
+#: views/developers/addon_edit_descriptions.thtml:78
+msgid "devcp_edit_descriptions_transbox_summary_description"
+msgstr ""
+
+#: views/developers/addon_edit_descriptions.thtml:77
+msgid "devcp_edit_descriptions_transbox_summary_name"
+msgstr "Descriere sumară pentru supliment"
+
+#: views/developers/addon_edit.thtml:46
+msgid "devcp_edit_dt_manage_authors"
+msgstr ""
+
+#: views/developers/addon_edit.thtml:48
+msgid "devcp_edit_dt_manage_categories"
+msgstr ""
+
+#: views/developers/addon_edit.thtml:50
+msgid "devcp_edit_dt_manage_descriptions"
+msgstr ""
+
+#: views/developers/addon_edit.thtml:52
+msgid "devcp_edit_dt_manage_properties"
+msgstr ""
+
+#: views/developers/addon_edit_properties.thtml:170
+msgid "devcp_edit_label_externalsoftware"
+msgstr "Acest supliment necesită alte programe"
+
+#: views/developers/addon_edit_properties.thtml:205
+msgid "devcp_edit_label_locale_disambiguation"
+msgstr "Alte informații despre localizare"
+
+#: views/developers/addon_edit_properties.thtml:168
+msgid "devcp_edit_label_prerelease"
+msgstr "Aceasta este o ediție preliminară"
+
+#: views/developers/addon_edit_properties.thtml:169
+msgid "devcp_edit_label_sitespecific"
+msgstr "Acesta este un supliment pentru un sait anume"
+
+#: views/developers/addon_edit_properties.thtml:202
+msgid "devcp_edit_label_target_locale"
+msgstr "Localizarea țintă"
+
+#: views/developers/addon_edit_properties.thtml:212
+msgid "devcp_edit_properties_button_update"
+msgstr ""
+
+#: views/developers/addon_edit_properties.thtml:198
+msgid "devcp_edit_properties_change_guid"
+msgstr ""
+
+#: views/developers/addon_edit_properties.thtml:109
+msgid "devcp_edit_properties_current_icon"
+msgstr ""
+
+#: views/developers/addon_edit_properties.thtml:85
+msgid "devcp_edit_properties_default_locale"
+msgstr ""
+
+#: views/developers/addon_edit_properties.thtml:167
+msgid "devcp_edit_properties_flags"
+msgstr ""
+
+#: views/developers/addon_edit_properties.thtml:174
+msgid "devcp_edit_properties_guid"
+msgstr ""
+
+#: views/developers/addon_edit_properties.thtml:53
+msgid "devcp_edit_properties_header"
+msgstr ""
+
+#: views/developers/addon_edit_properties.thtml:186
+msgid "devcp_edit_properties_header_addon_type"
+msgstr "Tip de supliment"
+
+#: views/developers/addon_edit_properties.thtml:181
+msgid "devcp_edit_properties_header_admin_settings"
+msgstr "Setări administrative"
+
+#: views/developers/addon_edit_properties.thtml:84
+msgid "devcp_edit_properties_header_default_locale"
+msgstr "Limba implicită"
+
+#: views/developers/addon_edit_properties.thtml:166
+msgid "devcp_edit_properties_header_flags"
+msgstr ""
+
+#: views/developers/addon_edit_properties.thtml:173
+#: views/developers/addon_edit_properties.thtml:197
+msgid "devcp_edit_properties_header_guid"
+msgstr ""
+
+#: views/developers/addon_edit_properties.thtml:104
+msgid "devcp_edit_properties_header_icon"
+msgstr ""
+
+#: views/developers/addon_edit_properties.thtml:159
+msgid "devcp_edit_properties_header_other_settings"
+msgstr "Alte setări"
+
+#. A header on the admin page to toggle trusted status.
+#: views/developers/addon_edit_properties.thtml:182
+msgid "devcp_edit_properties_header_trusted"
+msgstr ""
+
+#: views/developers/addon_edit_properties.thtml:160
+msgid "devcp_edit_properties_header_view_source"
+msgstr ""
+
+#. %s is a comma-separated list of image extensions ".png, .jpg"
+#: views/developers/addon_edit_properties.thtml:106
+msgid "devcp_edit_properties_icon"
+msgstr ""
+
+#: views/developers/addon_edit_properties.thtml:171
+msgid "devcp_edit_properties_label_binary"
+msgstr ""
+
+#: views/developers/addon_edit_properties.thtml:185
+msgid "devcp_edit_properties_label_not_trusted"
+msgstr "Necreditat"
+
+#: views/developers/addon_edit_properties.thtml:184
+msgid "devcp_edit_properties_label_trusted"
+msgstr "De încredere"
+
+#: views/developers/addon_edit_properties.thtml:110
+msgid "devcp_edit_properties_new_icon"
+msgstr ""
+
+#: views/developers/addon_edit_properties.thtml:118
+msgid "devcp_edit_properties_remove_icon"
+msgstr ""
+
+#: views/developers/addon_edit_properties.thtml:136
+msgid "devcp_edit_properties_transbox_homepage_description"
+msgstr ""
+
+#: views/developers/addon_edit_properties.thtml:135
+msgid "devcp_edit_properties_transbox_homepage_name"
+msgstr "Pagina de start a suplimentului"
+
+#: views/developers/addon_edit_properties.thtml:79
+msgid "devcp_edit_properties_transbox_name_description"
+msgstr ""
+
+#: views/developers/addon_edit_properties.thtml:78
+msgid "devcp_edit_properties_transbox_name_name"
+msgstr "Nume supliment"
+
+#: views/developers/addon_edit_properties.thtml:145
+msgid "devcp_edit_properties_transbox_supportemail_description"
+msgstr ""
+
+#: views/developers/addon_edit_properties.thtml:144
+msgid "devcp_edit_properties_transbox_supportemail_name"
+msgstr ""
+
+#: views/developers/addon_edit_properties.thtml:154
+msgid "devcp_edit_properties_transbox_supporturl_description"
+msgstr ""
+
+#: views/developers/addon_edit_properties.thtml:153
+msgid "devcp_edit_properties_transbox_supporturl_name"
+msgstr ""
+
+#: views/developers/addon_edit_properties.thtml:183
+msgid "devcp_edit_properties_trusted"
+msgstr ""
+
+#. %s is href="..." and should stay in the <a> tag.
+#: views/developers/addon_edit_properties.thtml:119
+msgid "devcp_edit_properties_undelete"
+msgstr ""
+
+#: views/developers/addon_edit_properties.thtml:161
+msgid "devcp_edit_properties_view_source"
+msgstr ""
+
+#: views/developers/addon_edit_properties.thtml:162
+msgid "devcp_edit_properties_view_source_allow"
+msgstr ""
+
+#: views/developers/addon_edit_properties.thtml:163
+msgid "devcp_edit_properties_view_source_do_not_allow"
+msgstr ""
+
+#: views/elements/developers/editbox.thtml:46
+msgid "devcp_editbox_authors"
+msgstr "Autori"
+
+#: views/elements/developers/editbox.thtml:47
+msgid "devcp_editbox_categories"
+msgstr "Categorii"
+
+#: views/elements/developers/editbox.thtml:52
+msgid "devcp_editbox_change_status"
+msgstr "Schimbă starea"
+
+#: views/elements/developers/editbox.thtml:48
+msgid "devcp_editbox_descriptions"
+msgstr ""
+
+#: views/elements/developers/editbox.thtml:43
+msgid "devcp_editbox_edit_addon"
+msgstr "Editează suplimentul"
+
+#: views/elements/developers/editbox.thtml:57
+msgid "devcp_editbox_new_version"
+msgstr "Versiune nouă"
+
+#: views/elements/developers/editbox.thtml:49
+msgid "devcp_editbox_properties"
+msgstr "Proprietăți"
+
+#: views/elements/developers/editbox.thtml:60
+msgid "devcp_editbox_screenshots"
+msgstr ""
+
+#: views/elements/developers/editbox.thtml:53
+msgid "devcp_editbox_statistics_dashboard"
+msgstr "Statistici - Tablou de bord"
+
+#: views/elements/developers/editbox.thtml:54
+msgid "devcp_editbox_versions"
+msgstr ""
+
+#: views/elements/developers/editbox.thtml:42
+msgid "devcp_editbox_view_listing"
+msgstr ""
+
+#: views/elements/developers/editorsmenu.thtml:59
+msgid "devcp_editorsqueue_featured"
+msgstr "Suplimente excepționale"
+
+#. %1 is the review count
+#: views/elements/developers/editorsqueue.thtml:42
+#: views/elements/developers/editorsmenu.thtml:56
+#, php-format
+msgid "devcp_editorsqueue_moderatedreviews"
+msgid_plural "devcp_editorsqueue_moderatedreviews"
+msgstr[0] "O recenzie moderată"
+msgstr[1] "Recenzii moderate (%s)"
+msgstr[2] "Recenzii moderate (%s)"
+
+#. %1 is the nominated addons count
+#: views/elements/developers/editorsqueue.thtml:44
+#: views/elements/developers/editorsmenu.thtml:58
+#, php-format
+msgid "devcp_editorsqueue_nominated"
+msgid_plural "devcp_editorsqueue_nominated"
+msgstr[0] "Un supliment nominalizat"
+msgstr[1] "Suplimente nominalizate (%s)"
+msgstr[2] "Suplimente nominalizate (%s)"
+
+#. %1 is the update count
+#: views/elements/developers/editorsqueue.thtml:43
+#: views/elements/developers/editorsmenu.thtml:57
+#, php-format
+msgid "devcp_editorsqueue_pendingupdates"
+msgid_plural "devcp_editorsqueue_pendingupdates"
+msgstr[0] "O actualizare în așteptare"
+msgstr[1] "Actualizări în așteptare (%s)"
+msgstr[2] "Actualizări în așteptare (%s)"
+
+#: controllers/statistics_controller.php:147
+#: controllers/statistics_controller.php:361
+#: controllers/previews_controller.php:108
+#: controllers/previews_controller.php:211
+#: controllers/previews_controller.php:312
+msgid "devcp_error_addon_access_denied"
+msgstr "Nu aveți acces la supliment."
+
+#. %s is a complete URL with the text from devcp_error_appversion_reference_link_text
+#. in the <a> tag. This should be fixed.
+#: controllers/components/developers.php:591
+#, php-format
+msgid "devcp_error_appversion_reference_link"
+msgstr "Consultați %s pentru referință."
+
+#. This is the link text in the <a> for devcp_error_appversion_reference_link. This
+#. should be fixed.
+#: controllers/components/developers.php:591
+msgid "devcp_error_appversion_reference_link_text"
+msgstr "această pagină"
+
+#: views/developers/addon_edit_authors.thtml:76
+msgid "devcp_error_empty_authors"
+msgstr ""
+
+#. %1$s is the name of the file
+#: controllers/components/developers.php:658
+msgid "devcp_error_file_exists"
+msgstr ""
+
+#. %1$s is a file extension. Example: .exe
+#. %2$s is a comma separated list of extensions. Example: .xpi, .jar
+#: controllers/components/developers.php:355
+#, php-format
+msgid "devcp_error_file_extension"
+msgstr ""
+"Extensia de fișier (%s) nu este permisă pentru tipul de supliment ales. Vă "
+"rugăm folosiți una din următoarele: %s"
+
+#: controllers/components/developers.php:64
+msgid "devcp_error_five_categories"
+msgstr "Vă rugăm nu selectați mai mult de 5 categorii."
+
+#: controllers/components/developers.php:526
+msgid "devcp_error_guid_application"
+msgstr "ID-ul acestui supliment este deja folosit de o aplicație."
+
+#: controllers/components/developers.php:337
+#: controllers/components/developers.php:389
+msgid "devcp_error_http_incomplete"
+msgstr "Transfer incomplet"
+
+#: controllers/components/developers.php:335
+#: controllers/components/developers.php:336
+#: controllers/components/developers.php:387
+#: controllers/components/developers.php:388
+msgid "devcp_error_http_maxupload"
+msgstr "Depășește mărimea maximă admisă pentru încărcări"
+
+#: controllers/components/developers.php:338
+#: controllers/components/developers.php:390
+msgid "devcp_error_http_nofile"
+msgstr "Niciun fișier încărcat"
+
+#. %1$s is a file extension. Example: .exe
+#. %2$s is a comma separated list of extensions. Example: .xpi, .jar
+#: controllers/components/developers.php:401
+#, php-format
+msgid "devcp_error_icon_extension"
+msgstr ""
+"Această extensie de fișier (%s) nu este admisă pentru o iconiță. Vă rugăm "
+"folosiți una din următoarele: %s"
+
+#: controllers/developers_controller.php:504
+msgid "devcp_error_index_rdf_notfound"
+msgstr "Lipsește install.rdf."
+
+#: controllers/components/developers.php:601
+msgid "devcp_error_install_manifest"
+msgstr "Au fost găsite următoarele erori în install.rdf:"
+
+#: controllers/developers_controller.php:1463
+msgid "devcp_error_invalid_addontype"
+msgstr ""
+
+#. %$1s is a version. Example: 3.1.1
+#. %$2s is an add-on name.
+#: controllers/components/developers.php:569
+#: controllers/components/developers.php:581
+#, php-format
+msgid "devcp_error_invalid_appversion"
+msgstr "%s nu este o versiune validă pentru %s"
+
+#. %s is a string
+#: controllers/components/developers.php:521
+#, php-format
+msgid "devcp_error_invalid_guid"
+msgstr "ID-ul acestui supliment este invalid: %s"
+
+#. %$1s is a version. Example: 3.1.1
+#. %$2s is an add-on name.
+#: controllers/components/developers.php:572
+#, php-format
+msgid "devcp_error_invalid_minversion"
+msgstr ""
+"%s nu este o versiune validă pentru %s: minimul versiunii nu poate conține *"
+
+#: controllers/components/developers.php:536
+msgid "devcp_error_invalid_version"
+msgstr ""
+"Versiunea acestui supliment este invalidă: vă rugăm vedeți <a href=\"http://"
+"developer.mozilla.org/en/docs/Toolkit_version_format\">specificațiile</a>"
+
+#: controllers/components/developers.php:531
+msgid "devcp_error_invalid_version_spaces"
+msgstr ""
+"Versiunea acestui supliment este invalidă: versiunile nu pot conține spații."
+
+#. %s is an error message from the parser.
+#: controllers/components/developers.php:501
+#, php-format
+msgid "devcp_error_manifest_parse"
+msgstr "A apărut următoarea eroare la analiza install.rdf: %s"
+
+#: controllers/components/developers.php:373
+msgid "devcp_error_move_file"
+msgstr "Nu se poate muta fișierul"
+
+#. %s is the name of a file
+#: controllers/components/developers.php:650
+#: controllers/components/developers.php:662
+#: controllers/components/developers.php:667
+#: controllers/components/developers.php:727
+#: controllers/components/developers.php:738
+#: controllers/components/developers.php:743
+#, php-format
+msgid "devcp_error_moving_file"
+msgstr "A apărut o eroare la mutarea %s."
+
+#: controllers/components/developers.php:595
+msgid "devcp_error_mozilla_application"
+msgstr "Trebuie să aveți cel puțin o aplicație Mozilla țintă validă."
+
+#: controllers/components/developers.php:516
+msgid "devcp_error_no_guid"
+msgstr "Nu s-a găsit niciun ID pentru acest supliment în install.rdf."
+
+#: controllers/components/developers.php:287
+msgid "devcp_error_no_platform"
+msgstr "Nicio platformă selectată"
+
+#: controllers/components/developers.php:59
+msgid "devcp_error_one_category"
+msgstr "Vă rugăm selectați cel puțin o categorie."
+
+#: controllers/components/developers.php:92
+msgid "devcp_error_one_user"
+msgstr "Trebuie să fie cel puțin un autor pentru acest supliment."
+
+#. %1$s is a file extension. Example: .exe
+#. %2$s is a comma separated list of extensions. Example: .xpi, .jar
+#: controllers/components/developers.php:1081
+#, php-format
+msgid "devcp_error_preview_extension"
+msgstr ""
+"Această extensie de fișier (%s) nu este permisă pentru o avanpremieră. Vă "
+"rugăm folosiți una din următoarele: %s"
+
+#: controllers/components/developers.php:511
+msgid "devcp_error_updatekey"
+msgstr ""
+"Suplimentele nu pot folosi updateKey. Vă rugăm să ștergeți cheia din install."
+"rdf și să încercați din nou."
+
+#: controllers/components/developers.php:506
+msgid "devcp_error_updateurl"
+msgstr ""
+"Suplimentele nu pot folosi o adresă externă pentru actualizare (updateURL). "
+"Vă rugăm ștergeți această declarație din install.rdf și încercați din nou."
+
+#: controllers/developers_controller.php:465
+#: controllers/components/developers.php:271
+msgid "devcp_error_upload_file"
+msgstr "Vă rugăm încărcați un fișier."
+
+#: views/developers/uploader.thtml:135
+msgid "devcp_input_upload_file"
+msgstr "Încărcare fișier"
+
+#: views/pages/js_constants.js.thtml:89
+msgid "devcp_js_a_cancel"
+msgstr "Renunță"
+
+#: views/pages/js_constants.js.thtml:90
+msgid "devcp_js_add_email"
+msgstr ""
+
+#. alt text for a down-arrow image.
+#: views/pages/js_constants.js.thtml:81
+msgid "devcp_js_img_move_down"
+msgstr "Mută în jos"
+
+#. alt text for an up-arrow image.
+#: views/pages/js_constants.js.thtml:82
+msgid "devcp_js_img_move_up"
+msgstr "Mută în sus"
+
+#: views/pages/js_constants.js.thtml:91
+msgid "devcp_js_img_remove_compat"
+msgstr ""
+
+#: views/pages/js_constants.js.thtml:86
+msgid "devcp_js_input_list_author"
+msgstr ""
+
+#: views/pages/js_constants.js.thtml:92
+msgid "devcp_js_license_select"
+msgstr ""
+
+#: views/pages/js_constants.js.thtml:93
+msgid "devcp_js_license_text"
+msgstr ""
+
+#. <option> text in a <select> for Author role in an add-on.
+#: views/pages/js_constants.js.thtml:84
+msgid "devcp_js_option_developer"
+msgstr ""
+
+#. <option> text in a <select> for Author role in an add-on.
+#: views/pages/js_constants.js.thtml:83
+msgid "devcp_js_option_owner"
+msgstr "Proprietar"
+
+#. <option> text in a <select> for Author role in an add-on.
+#: views/pages/js_constants.js.thtml:85
+msgid "devcp_js_option_viewer"
+msgstr "Vizualizator"
+
+#: views/pages/js_constants.js.thtml:88
+msgid "devcp_js_remove_author"
+msgstr ""
+
+#: views/pages/js_constants.js.thtml:87
+msgid "devcp_js_sure_remove"
+msgstr ""
+
+#: views/pages/js_constants.js.thtml:77
+msgid "devcp_js_upload_alert"
+msgstr ""
+
+#. %1$s is an addon id, like 32.
+#. %2$s is a version number, like 3.5.
+#: controllers/components/developers.php:1212
+msgid "devcp_license_existing"
+msgstr ""
+
+#: views/elements/developers/localebox.thtml:44
+msgid "devcp_localebox_header_localizedfields"
+msgstr "Câmpuri localizate"
+
+#. %1 is the default locale
+#: views/elements/developers/localebox.thtml:48
+#, php-format
+msgid "devcp_localebox_intro"
+msgstr ""
+"Unele câmpuri de pe această pagină sunt localizate pentru a fi afișate în "
+"limba nativă a utilizatorilor. Alegeți o limbă mai jos pentru a edita "
+"detaliile suplimentului în acea limbă. Dacă traducerea într-o limbă nu este "
+"disponbilă, se va afișa descrierea în limba implicită (%s)."
+
+#: views/elements/developers/sidebar.thtml:68
+#: views/elements/developers/myaddons.thtml:75
+msgid "devcp_myaddons_admincp_link"
+msgstr "Panoul de control al administratorului"
+
+#: views/elements/developers/sidebar.thtml:65
+#: views/elements/developers/myaddons.thtml:72
+msgid "devcp_myaddons_editorcp_link"
+msgstr "Panoul de control al editorului"
+
+#: views/elements/developers/myaddons.thtml:52
+msgid "devcp_myaddons_link"
+msgstr "Suplimentele mele"
+
+#: views/elements/developers/sidebar.thtml:70
+#: views/elements/developers/myaddons.thtml:77
+msgid "devcp_myaddons_mainpage_link"
+msgstr "Înapoi la pagina principală"
+
+#: views/elements/developers/sidebar.thtml:63
+#: views/elements/developers/myaddons.thtml:70
+msgid "devcp_myaddons_statistics_link"
+msgstr "Statistici - Tablou de bord"
+
+#: views/elements/developers/sidebar.thtml:62
+#: views/elements/developers/myaddons.thtml:69
+msgid "devcp_myaddons_submitaddon_link"
+msgstr "Trimite supliment"
+
+#: views/elements/developers/sidebar.thtml:48
+#: views/elements/developers/myaddons.thtml:67
+msgid "devcp_myaddons_title"
+msgstr "Unelte pentru dezvoltatori"
+
+#. %1$s is an add-on ID, perhaps 167.
+#. %2$s is a URL.
+#: controllers/developers_controller.php:256
+msgid "devcp_new_addon_error"
+msgstr ""
+
+#: views/developers/addon_status_nominate.thtml:62
+msgid "devcp_nominate_cancel"
+msgstr ""
+
+#. %1 is the add-on name
+#: views/developers/addon_status_nominate.thtml:61
+#, php-format
+msgid "devcp_nominate_submit_nominate"
+msgstr "Nominalizează %s"
+
+#: views/developers/addon_edit_properties.thtml:50
+#: views/developers/addon_status.thtml:49
+#: views/developers/versions_edit.thtml:50
+msgid "devcp_notice_changes_error"
+msgstr ""
+
+#: views/developers/addon_edit_authors.thtml:47
+#: views/developers/addon_edit_properties.thtml:47
+#: views/developers/addon_status.thtml:46
+#: views/developers/addon_edit_descriptions.thtml:47
+#: views/developers/versions_edit.thtml:47
+#: views/developers/addon_edit_categories.thtml:46
+msgid "devcp_notice_changes_saved"
+msgstr ""
+
+#: controllers/previews_controller.php:252
+msgid "devcp_notice_cleardefault"
+msgstr ""
+"Dacă această avanpremieră nu va mai fi cea implicită, atunci o altă "
+"avanpremieră va deveni automat cea implicită."
+
+#: controllers/previews_controller.php:184
+#: controllers/previews_controller.php:251
+msgid "devcp_notice_makedefault"
+msgstr ""
+"Dacă faceți această avanpremieră cea implicită, o altă avanpremieră își va "
+"pierde proprietatea de a fi implicită."
+
+#: views/developers/addon_edit_authors.thtml:70
+msgid "devcp_notice_unsaved_changes"
+msgstr ""
+
+#: controllers/developers_controller.php:87
+#: controllers/developers_controller.php:97
+#: controllers/developers_controller.php:100
+#: controllers/previews_controller.php:67
+#: controllers/previews_controller.php:79
+#: controllers/previews_controller.php:82
+msgid "devcp_pagetitle"
+msgstr "Panoul de control al dezvoltatorului"
+
+#: controllers/previews_controller.php:103
+#: controllers/previews_controller.php:104
+msgid "devcp_preview_add_pagetitle"
+msgstr "Adaugă avanpremieră"
+
+#: controllers/previews_controller.php:135
+msgid "devcp_preview_added_successfully"
+msgstr "Imaginea de avanpremieră a fost adăugată cu succes."
+
+#: controllers/previews_controller.php:323
+msgid "devcp_preview_deleted_successfully"
+msgstr "Imaginea de avanpremieră a fost ștearsă cu succes."
+
+#: controllers/previews_controller.php:194
+#: controllers/previews_controller.php:195
+msgid "devcp_preview_edit_pagetitle"
+msgstr "Editează avanpremieră"
+
+#: controllers/previews_controller.php:237
+msgid "devcp_preview_updated_successfully"
+msgstr "Avanpremieră actualizată cu succes."
+
+#: views/developers/previews.thtml:120
+msgid "devcp_previews_a_another"
+msgstr ""
+
+#: views/developers/previews.thtml:96
+msgid "devcp_previews_a_delete"
+msgstr "Șterge avanpriemiera"
+
+#: views/developers/previews.thtml:95
+msgid "devcp_previews_a_replace"
+msgstr ""
+
+#: views/developers/previews.thtml:126
+msgid "devcp_previews_a_update"
+msgstr ""
+
+#: views/developers/previews.thtml:115 views/developers/previews.thtml:124
+msgid "devcp_previews_add_new"
+msgstr ""
+
+#. %s is a list of file extensions, e.g. ".png, .gif"
+#: views/developers/previews.thtml:116
+msgid "devcp_previews_add_select"
+msgstr ""
+
+#: views/developers/previews.thtml:121
+msgid "devcp_previews_click_below"
+msgstr ""
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/previews.thtml:102
+msgid "devcp_previews_click_update"
+msgstr ""
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/previews.thtml:107
+msgid "devcp_previews_error_message"
+msgstr ""
+
+#: views/previews/add.thtml:45
+msgid "devcp_previews_filetype_info"
+msgstr ""
+"Folosiți formularul de mai jos pentru a încărca o captură de ecran a "
+"suplimentului în format PNG, JPG sau GIF. Imaginile mai mari de 700 pixeli în "
+"lățime și 525 pixeli în înălțime vor fi automat redimensionate."
+
+#: views/previews/add.thtml:43
+msgid "devcp_previews_header_add"
+msgstr "Adaugă avanpremieră"
+
+#: views/developers/previews.thtml:80
+msgid "devcp_previews_header_caption"
+msgstr "Titlu avanpremieră"
+
+#: views/previews/edit.thtml:43
+msgid "devcp_previews_header_edit"
+msgstr "Editează avanpremieră"
+
+#: views/developers/previews.thtml:93
+msgid "devcp_previews_label_default"
+msgstr ""
+
+#: views/previews/add.thtml:54
+msgid "devcp_previews_label_file"
+msgstr "Fișier avanpremieră"
+
+#: views/previews/add.thtml:59 views/previews/edit.thtml:50
+msgid "devcp_previews_label_makedefault"
+msgstr "Această imagine de avanpremieră este cea implicită"
+
+#: views/developers/previews.thtml:100
+msgid "devcp_previews_label_new"
+msgstr ""
+
+#: views/developers/previews.thtml:118
+msgid "devcp_previews_label_upload"
+msgstr ""
+
+#: views/developers/previews.thtml:50
+msgid "devcp_previews_notice_error"
+msgstr ""
+
+#: views/developers/previews.thtml:47
+msgid "devcp_previews_notice_success"
+msgstr ""
+
+#: views/developers/previews.thtml:59
+msgid "devcp_previews_p_screenshots"
+msgstr ""
+
+#: views/previews/edit.thtml:55
+msgid "devcp_previews_submit_delete"
+msgstr "Șterge avanpriemiera"
+
+#: views/previews/edit.thtml:55
+msgid "devcp_previews_submit_delete_confirm"
+msgstr "Sigur doriți să ștergeți această avanpremieră?"
+
+#: views/previews/edit.thtml:54
+msgid "devcp_previews_submit_edit"
+msgstr "Editează avanpremieră"
+
+#: views/previews/add.thtml:63
+msgid "devcp_previews_submit_upload"
+msgstr "Încarcă o avanpremieră"
+
+#: views/developers/previews.thtml:78
+msgid "devcp_previews_thumbnail"
+msgstr "Miniatură"
+
+#. %s is the add-on name.
+#: views/developers/previews.thtml:44
+msgid "devcp_previews_title"
+msgstr ""
+
+#: views/developers/uploader.thtml:74
+msgid "devcp_review_agreement_please"
+msgstr ""
+"Va rugăm revizuiți și acceptați termenii acordului cu dezvoltatorul înainte "
+"de a continua."
+
+#: views/elements/developers/rolecheck.thtml:42
+msgid "devcp_rolecheck_no_privs"
+msgstr ""
+
+#: controllers/developers_controller.php:1315
+msgid "devcp_several_hours"
+msgstr ""
+
+#: views/elements/developers/sidebar.thtml:52
+msgid "devcp_sidebar_a_dashboard"
+msgstr "Tablou de bord"
+
+#. %s is a number
+#: views/elements/developers/statsbar.thtml:45
+#: views/developers/dashboard.thtml:79
+#, php-format
+msgid "devcp_statsbar_adu"
+msgstr "<em>%s</em> utilizatori activi zilnic"
+
+#. %s is a number
+#: views/elements/developers/statsbar.thtml:41
+#: views/developers/dashboard.thtml:75
+#, php-format
+msgid "devcp_statsbar_total_downloads"
+msgstr "<em>%s</em> descărcări în total"
+
+#. %s is a number
+#: views/elements/developers/statsbar.thtml:43
+#: views/developers/dashboard.thtml:77
+#, php-format
+msgid "devcp_statsbar_weekly_downloads"
+msgstr "<em>%s</em> descărcări pe săptămână"
+
+#: views/developers/addon_status_confirm.thtml:59
+msgid "devcp_status_confirm_active"
+msgstr ""
+
+#: views/developers/addon_status_confirm.thtml:59
+msgid "devcp_status_confirm_active_sure"
+msgstr ""
+
+#: views/developers/addon_status_confirm.thtml:50
+msgid "devcp_status_confirm_header_sure"
+msgstr "Sigur doriți asta?"
+
+#: views/developers/addon_status_confirm.thtml:55
+msgid "devcp_status_confirm_inactive"
+msgstr ""
+
+#: views/developers/addon_status_confirm.thtml:55
+msgid "devcp_status_confirm_inactive_sure"
+msgstr ""
+
+#: views/developers/addon_status_confirm.thtml:74
+msgid "devcp_status_confirm_no"
+msgstr ""
+
+#: views/developers/addon_status_confirm.thtml:67
+msgid "devcp_status_confirm_public"
+msgstr ""
+
+#: views/developers/addon_status_confirm.thtml:67
+msgid "devcp_status_confirm_public_sure"
+msgstr ""
+
+#: views/developers/addon_status_confirm.thtml:63
+msgid "devcp_status_confirm_sandbox"
+msgstr ""
+
+#: views/developers/addon_status_confirm.thtml:63
+msgid "devcp_status_confirm_sandbox_sure"
+msgstr ""
+
+#: views/developers/addon_status_confirm.thtml:73
+msgid "devcp_status_confirm_yes"
+msgstr ""
+
+#: views/developers/addon_status_nominate.thtml:46
+msgid "devcp_status_nominate_error_notice"
+msgstr ""
+
+#: views/developers/addon_status_nominate.thtml:55
+msgid "devcp_status_nominate_header"
+msgstr ""
+
+#: views/developers/dashboard.thtml:85
+msgid "devcp_summary_lastversion"
+msgstr "Ultima versiune:"
+
+#. %s is the add-on name.
+#: views/developers/addon_edit.thtml:43
+#: views/developers/addon_edit_authors.thtml:44
+#: views/developers/versions_delete.thtml:43
+#: views/developers/addon_edit_properties.thtml:44
+#: views/developers/addon_edit_descriptions.thtml:44
+#: views/developers/versions_edit.thtml:44
+#: views/developers/addon_edit_categories.thtml:43
+#: views/developers/versions.thtml:43
+msgid "devcp_title_edit_addon"
+msgstr ""
+
+#. title attribute for a javascript link that pops up a help dialog.
+#: views/elements/translationbox.thtml:68
+msgid "devcp_transbox_a_title_help"
+msgstr ""
+
+#: views/elements/translationbox.thtml:68
+msgid "devcp_transbox_alt_help"
+msgstr "Ajutor"
+
+#. %1$s is <span>17</span>, %2$s is 42.
+#: views/elements/translationbox.thtml:101
+msgid "devcp_transbox_chars_used"
+msgstr ""
+
+#: views/elements/translationbox.thtml:132
+msgid "devcp_transbox_delete_sure"
+msgstr ""
+
+#. %s is a locale, like en-US.
+#: views/elements/translationbox.thtml:143
+msgid "devcp_transbox_help_header_tabs"
+msgstr ""
+
+#: views/elements/translationbox.thtml:145
+msgid "devcp_transbox_help_header_what"
+msgstr ""
+
+#: views/elements/translationbox.thtml:147
+msgid "devcp_transbox_help_hide"
+msgstr ""
+
+#: views/elements/translationbox.thtml:146
+msgid "devcp_transbox_help_if"
+msgstr ""
+
+#: views/elements/translationbox.thtml:144
+msgid "devcp_transbox_help_transbox"
+msgstr ""
+
+#: views/elements/translationbox.thtml:85
+msgid "devcp_transbox_img_add_trans"
+msgstr ""
+
+#: views/elements/translationbox.thtml:86
+msgid "devcp_transbox_img_remove_trans"
+msgstr ""
+
+#: views/elements/translationbox.thtml:123
+msgid "devcp_transbox_input_add_all"
+msgstr ""
+
+#: views/elements/translationbox.thtml:122
+msgid "devcp_transbox_input_add_locale"
+msgstr ""
+
+#: views/elements/translationbox.thtml:124
+#: views/elements/translationbox.thtml:135
+msgid "devcp_transbox_input_cancel"
+msgstr "Renunță"
+
+#: views/elements/translationbox.thtml:134
+msgid "devcp_transbox_input_delete"
+msgstr ""
+
+#: views/elements/translationbox.thtml:113
+msgid "devcp_transbox_select_locale"
+msgstr ""
+
+#. %1$s and %2$s are GUIDs.
+#: controllers/developers_controller.php:343
+msgid "devcp_update_addon_guid_error"
+msgstr ""
+
+#: controllers/developers_controller.php:334
+msgid "devcp_update_addon_priv_error"
+msgstr ""
+
+#. %1$s is a version number, %2$s is an add-on ID.
+#: controllers/developers_controller.php:399
+msgid "devcp_update_addon_version_belong_error"
+msgstr ""
+
+#. %1$s is a version number, maybe 1.1.
+#. %2$s is a URL.
+#: controllers/developers_controller.php:351
+msgid "devcp_update_addon_version_exists_error"
+msgstr ""
+
+#. %1$s and %2$s are version numbers.
+#: controllers/developers_controller.php:405
+msgid "devcp_update_addon_version_match_error"
+msgstr ""
+
+#: views/developers/uploader.thtml:68
+msgid "devcp_uploader_a_start"
+msgstr ""
+
+#: views/developers/uploader.thtml:137
+msgid "devcp_uploader_ajax_loading"
+msgstr ""
+
+#: views/developers/uploader.thtml:82
+msgid "devcp_uploader_button_agree"
+msgstr ""
+
+#: views/developers/uploader.thtml:157
+msgid "devcp_uploader_button_edit"
+msgstr ""
+
+#: views/developers/uploader.thtml:158
+msgid "devcp_uploader_button_later"
+msgstr ""
+
+#: views/developers/uploader.thtml:168
+msgid "devcp_uploader_button_release"
+msgstr ""
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/uploader.thtml:156
+msgid "devcp_uploader_created_results"
+msgstr ""
+
+#: views/developers/uploader.thtml:143
+msgid "devcp_uploader_error_correct"
+msgstr ""
+
+#. %1$s is a version number, %2$s is a status, e.g Public or Incomplete.
+#: views/developers/uploader.thtml:175
+msgid "devcp_uploader_file_created"
+msgstr ""
+
+#: views/developers/uploader.thtml:154
+msgid "devcp_uploader_header_created"
+msgstr ""
+
+#: views/developers/uploader.thtml:141
+msgid "devcp_uploader_header_error"
+msgstr ""
+
+#: views/developers/uploader.thtml:173
+msgid "devcp_uploader_header_file_added"
+msgstr ""
+
+#: views/developers/uploader.thtml:66
+msgid "devcp_uploader_header_how"
+msgstr ""
+
+#. %s is the version number, e.g. 3.2.
+#: views/developers/uploader.thtml:163
+msgid "devcp_uploader_header_update_created"
+msgstr ""
+
+#: views/developers/uploader.thtml:117
+msgid "devcp_uploader_header_upload"
+msgstr ""
+
+#: views/developers/uploader.thtml:67
+msgid "devcp_uploader_how"
+msgstr ""
+
+#: views/developers/uploader.thtml:125
+msgid "devcp_uploader_label_platformtype"
+msgstr ""
+
+#: views/developers/uploader.thtml:124
+msgid "devcp_uploader_label_upload_field"
+msgstr ""
+
+#: controllers/components/developers.php:1221
+msgid "devcp_uploader_option_other"
+msgstr "Alta"
+
+#. %1$s is a number, %2$s is href="..." and should stay in the <a> tag.
+#: views/developers/uploader.thtml:176
+msgid "devcp_uploader_p_pending_file"
+msgstr ""
+
+#. %1$s is a number, %2$s is href="..." and should stay in the <a> tag.
+#: views/developers/uploader.thtml:166
+msgid "devcp_uploader_p_pending_version"
+msgstr ""
+
+#. %s is a status, e.g Public or Incomplete.
+#: views/developers/uploader.thtml:165
+msgid "devcp_uploader_p_update_created"
+msgstr ""
+
+#. %1$s is href="..." and should stay in the 'Versions and Files' <a> tag.
+#. %2$s is href="..." and should stay in the 'current status' <a> tag.
+#: views/developers/uploader.thtml:177
+msgid "devcp_uploader_p_update_file"
+msgstr ""
+
+#. %1$s is href="..." and should stay in the 'Versions and Files' <a> tag.
+#. %2$s is href="..." and should stay in the 'current status' <a> tag.
+#: views/developers/uploader.thtml:167
+msgid "devcp_uploader_p_update_version"
+msgstr ""
+
+#: views/developers/uploader.thtml:118
+msgid "devcp_uploader_p_upload"
+msgstr ""
+
+#: views/developers/uploader.thtml:125
+msgid "devcp_uploader_platformtype_all"
+msgstr "Toate"
+
+#: views/developers/uploader.thtml:126
+msgid "devcp_uploader_platformtype_specific"
+msgstr ""
+
+#. Used as first item in a <select>.
+#: controllers/components/developers.php:1185
+msgid "devcp_uploader_please_choose"
+msgstr ""
+
+#. %1$s is the add-on name, %2$s is the version number.
+#: views/developers/uploader.thtml:57
+msgid "devcp_uploader_title_file"
+msgstr ""
+
+#: views/developers/uploader.thtml:50
+msgid "devcp_uploader_title_submit"
+msgstr ""
+
+#. %s is the add-on name.
+#: views/developers/uploader.thtml:54
+msgid "devcp_uploader_title_update"
+msgstr ""
+
+#. %s is a full <a> tag
+#: controllers/developers_controller.php:503
+#, php-format
+msgid "devcp_valid_app_reference"
+msgstr "Vedeți %s pentru referință."
+
+#. This is the text in the <a> tag for devcp_valid_app_reference. This should be
+#. fixed.
+#: controllers/developers_controller.php:503
+msgid "devcp_valid_app_reference_linktext"
+msgstr "această pagină"
+
+#: controllers/developers_controller.php:581
+msgid "devcp_verify_author_error"
+msgstr ""
+
+#: controllers/developers_controller.php:553
+msgid "devcp_verify_search_engine_error"
+msgstr ""
+
+#: views/developers/versions.thtml:75
+msgid "devcp_versions_a_cancel"
+msgstr "Renunță"
+
+#: views/developers/versions.thtml:79
+msgid "devcp_versions_a_delete"
+msgstr ""
+
+#: views/developers/versions.thtml:74
+msgid "devcp_versions_a_empty"
+msgstr ""
+
+#: views/developers/versions.thtml:71
+msgid "devcp_versions_a_remove"
+msgstr ""
+
+#: views/developers/versions.thtml:91
+msgid "devcp_versions_add"
+msgstr ""
+
+#: views/developers/versions_delete.thtml:58
+msgid "devcp_versions_delete_a_cancel"
+msgstr "Renunță"
+
+#: views/developers/versions_delete.thtml:56
+msgid "devcp_versions_delete_a_delete"
+msgstr ""
+
+#. Followed by a list of reviews and files that will be removed.
+#: views/developers/versions_delete.thtml:50
+msgid "devcp_versions_delete_also"
+msgstr ""
+
+#: views/developers/versions_delete.thtml:53
+msgid "devcp_versions_delete_files"
+msgid_plural "devcp_versions_delete_files"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+
+#. %s is the version number.
+#: views/developers/versions_delete.thtml:48
+msgid "devcp_versions_delete_header"
+msgstr ""
+
+#: views/developers/versions_delete.thtml:52
+msgid "devcp_versions_delete_reviews"
+msgid_plural "devcp_versions_delete_reviews"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+
+#. %s is the version number.
+#: views/developers/versions_delete.thtml:49
+msgid "devcp_versions_delete_sure"
+msgstr ""
+
+#: views/developers/versions_edit.thtml:102
+#: views/developers/versions_edit.thtml:155
+msgid "devcp_versions_edit_a_cancel"
+msgstr "Renunță"
+
+#: views/developers/versions_edit.thtml:101
+msgid "devcp_versions_edit_a_delete"
+msgstr "Șterge fișierul"
+
+#: views/developers/versions_edit.thtml:165
+msgid "devcp_versions_edit_a_new_app"
+msgstr ""
+
+#: views/developers/versions_edit.thtml:154
+msgid "devcp_versions_edit_a_remove_app"
+msgstr ""
+
+#: views/developers/versions_edit.thtml:114
+msgid "devcp_versions_edit_add"
+msgstr ""
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/versions_edit.thtml:121
+msgid "devcp_versions_edit_adjust"
+msgstr ""
+
+#: views/developers/versions_edit.thtml:153
+msgid "devcp_versions_edit_compat_sure"
+msgstr ""
+
+#: views/developers/versions_edit.thtml:100
+msgid "devcp_versions_edit_delete_sure"
+msgstr ""
+
+#: views/developers/versions_edit.thtml:203
+msgid "devcp_versions_edit_header_approval"
+msgstr ""
+
+#: views/developers/versions_edit.thtml:120
+msgid "devcp_versions_edit_header_compat"
+msgstr ""
+
+#: views/developers/versions_edit.thtml:74
+msgid "devcp_versions_edit_header_file"
+msgstr ""
+
+#: views/developers/versions_edit.thtml:189
+msgid "devcp_versions_edit_header_license"
+msgstr "Licență"
+
+#. %s is the version number.
+#: views/developers/versions_edit.thtml:53
+msgid "devcp_versions_edit_header_manage"
+msgstr ""
+
+#: views/developers/versions_edit.thtml:212
+msgid "devcp_versions_edit_header_notes"
+msgstr ""
+
+#: views/developers/versions_edit.thtml:98
+msgid "devcp_versions_edit_img_delete"
+msgstr "Șterge fișierul"
+
+#. %1$s is the file id, e.g. 18723.
+#. %2$s is the platform name, e.g. ALL or Windows.
+#. %3$s is the _('date) created.
+#. %4$s is the status, e.g. "In Sandbox" or "Public".
+#. %5$s is the _('date') status was changed.
+#: views/developers/versions_edit.thtml:208
+msgid "devcp_versions_edit_li_file"
+msgstr ""
+
+#: views/developers/versions_edit.thtml:190
+msgid "devcp_versions_edit_license_description"
+msgstr ""
+
+#: views/developers/versions_edit.thtml:111
+msgid "devcp_versions_edit_no_files"
+msgstr ""
+
+#: views/developers/versions_edit.thtml:213
+msgid "devcp_versions_edit_optional"
+msgstr ""
+
+#: views/developers/versions_edit.thtml:151
+msgid "devcp_versions_edit_remove_compat"
+msgstr ""
+
+#: views/developers/versions_edit.thtml:167
+msgid "devcp_versions_edit_select_app"
+msgstr ""
+
+#: views/developers/versions_edit.thtml:78
+msgid "devcp_versions_edit_th_file"
+msgstr "Fișier"
+
+#: views/developers/versions_edit.thtml:79
+msgid "devcp_versions_edit_th_platform"
+msgstr "Platformă"
+
+#: views/developers/versions_edit.thtml:80
+msgid "devcp_versions_edit_th_size"
+msgstr "Mărime"
+
+#: views/developers/versions_edit.thtml:81
+msgid "devcp_versions_edit_th_status"
+msgstr "Stare"
+
+#: views/developers/versions_edit.thtml:183
+msgid "devcp_versions_edit_transbox_releasenotes_description"
+msgstr ""
+
+#: views/developers/versions_edit.thtml:182
+msgid "devcp_versions_edit_transbox_releasenotes_name"
+msgstr "Note asupra ediției"
+
+#: views/developers/versions_edit.thtml:164
+msgid "devcp_versions_edit_unsaved_compat"
+msgstr ""
+
+#: views/developers/versions_edit.thtml:113
+msgid "devcp_versions_edit_unsaved_files"
+msgstr ""
+
+#: views/developers/versions_edit.thtml:218
+msgid "devcp_versions_edit_update"
+msgstr ""
+
+#: views/developers/versions.thtml:49
+msgid "devcp_versions_header_manage"
+msgstr ""
+
+#: views/developers/versions.thtml:87
+msgid "devcp_versions_no_versions"
+msgstr ""
+
+#. %s is a version number, base 10.
+#: views/developers/versions.thtml:46
+msgid "devcp_versions_notice_success"
+msgstr ""
+
+#: views/developers/versions.thtml:73
+msgid "devcp_versions_p_remove"
+msgstr ""
+
+#: views/developers/versions.thtml:58
+msgid "devcp_versions_th_created"
+msgstr "Creat"
+
+#: views/developers/versions.thtml:57
+msgid "devcp_versions_th_status"
+msgstr "Stare"
+
+#: views/developers/versions.thtml:56
+msgid "devcp_versions_th_version"
+msgstr "Versiune"
+
+#: controllers/downloads_controller.php:91
+msgid "downloads_disable_warning"
+msgstr "Acest supliment este dezactivat"
+
+#: controllers/components/editors.php:57
+msgid "editor_review_error_addon_not_nominated"
+msgstr ""
+
+#: controllers/components/editors.php:213
+msgid "editor_review_error_file_not_pending"
+msgstr ""
+
+#. Actions are, for example: approving or rejecting
+#: controllers/components/editors.php:79 controllers/components/editors.php:182
+msgid "editor_review_error_no_action"
+msgstr ""
+
+#: controllers/components/editors.php:192
+msgid "editor_review_error_no_applications"
+msgstr ""
+
+#. Comments are required when an editor approves or rejects an add-on.
+#: controllers/components/editors.php:84 controllers/components/editors.php:187
+msgid "editor_review_error_no_comments"
+msgstr ""
+
+#: controllers/components/editors.php:161
+msgid "editor_review_error_no_files"
+msgstr "Vă rugăm selectați cel puțin un fișier pentru recenziat."
+
+#: controllers/components/editors.php:197
+msgid "editor_review_error_no_operating_system"
+msgstr ""
+
+#: views/editors/logs.thtml:51
+msgid "editorcp_logs_button_filter"
+msgstr "Filtrează"
+
+#: views/editors/logs.thtml:44
+msgid "editorcp_logs_filter_by"
+msgstr "Filtrează după tip/acțiune"
+
+#: views/editors/logs.thtml:42 controllers/editors_controller.php:964
+msgid "editorcp_logs_page_heading"
+msgstr "Jurnal de evenimente"
+
+#: views/elements/developers/editorsmenu.thtml:60
+msgid "editorcp_menu_eventlog_link"
+msgstr "Jurnal de evenimente"
+
+#: views/elements/developers/editorsmenu.thtml:62
+msgid "editorcp_menu_mainpage_link"
+msgstr "Înapoi la început"
+
+#: views/elements/developers/editorsmenu.thtml:61
+msgid "editorcp_menu_reviewlog_link"
+msgstr "Jurnalul recenziilor"
+
+#: views/elements/developers/editorsmenu.thtml:55
+msgid "editorcp_menu_summary_link"
+msgstr "Sumar pentru editor"
+
+#: views/elements/developers/editorsmenu.thtml:52
+msgid "editorcp_menu_title"
+msgstr "Unelte pentru editori"
+
+#: views/editors/reviewlog.thtml:49
+msgid "editorcp_reviewlog_button_filter"
+msgstr "Filtrează"
+
+#: views/editors/reviewlog.thtml:58
+msgid "editorcp_reviewlog_column_action"
+msgstr "Acțiune"
+
+#: views/editors/reviewlog.thtml:56
+msgid "editorcp_reviewlog_column_addon"
+msgstr "Supliment"
+
+#: views/editors/reviewlog.thtml:55
+msgid "editorcp_reviewlog_column_date"
+msgstr "Dată"
+
+#: views/editors/reviewlog.thtml:57
+msgid "editorcp_reviewlog_column_editor"
+msgstr "Editor"
+
+#: views/editors/reviewlog.thtml:94
+msgid "editorcp_reviewlog_comments_hide"
+msgstr "Ascunde comentariile"
+
+#: views/editors/reviewlog.thtml:93
+msgid "editorcp_reviewlog_comments_show"
+msgstr "Arată comentariile"
+
+#. %1$s and %2$s are full <input> tags for dates
+#: views/editors/reviewlog.thtml:45
+#, php-format
+msgid "editorcp_reviewlog_entries_between"
+msgstr "Vezi intrările de la %s la %s"
+
+#: views/editors/reviewlog.thtml:104
+msgid "editorcp_reviewlog_none_found"
+msgstr "Nu sunt recenzii în această perioadă."
+
+#: views/editors/reviewlog.thtml:42
+msgid "editorcp_reviewlog_page_heading"
+msgstr "Jurnalul recenziilor"
+
+#: views/editors/summary.thtml:61
+msgid "editorcp_summary_monthreviews_heading"
+msgstr "Recenziile lunii"
+
+#: views/editors/summary.thtml:77
+msgid "editorcp_summary_neweditors_heading"
+msgstr "Editori noi"
+
+#: views/editors/summary.thtml:42
+msgid "editorcp_summary_page_heading"
+msgstr "Sumar pentru editori"
+
+#: views/editors/summary.thtml:94
+msgid "editorcp_summary_recentactivity_heading"
+msgstr "Activitatea recentă a editorilor"
+
+#: views/editors/summary.thtml:45
+msgid "editorcp_summary_totalreviews_heading"
+msgstr "Total recenzii"
+
+#: controllers/editors_controller.php:248
+#: controllers/editors_controller.php:249
+msgid "editors_addon_review_pagetitle"
+msgstr "Recenzie supliment"
+
+#: controllers/editors_controller.php:349
+msgid "editors_error_js-formerror"
+msgstr "Vă rugăm completați următoarele câmpuri:"
+
+#: controllers/editors_controller.php:350
+msgid "editors_error_review_one_file"
+msgstr "Vă rugăm selectați cel puțin un fișier pentru recenziat."
+
+#: controllers/editors_controller.php:274
+msgid "editors_error_self_reviews_forbidden"
+msgstr "Nu sunt permise recenzii pentru suplimentele dumneavoastră."
+
+#: controllers/editors_controller.php:699
+msgid "editors_external_software"
+msgstr "Programe externe"
+
+#: views/editors/featured.thtml:120 views/editors/featured.thtml:121
+msgid "editors_featured_add_feature"
+msgstr "Adaugă favorit"
+
+#: views/editors/featured.thtml:126
+msgid "editors_featured_add_feature_submit"
+msgstr "Adaugă"
+
+#: views/editors/featured.thtml:49 controllers/editors_controller.php:832
+#: controllers/editors_controller.php:848
+msgid "editors_featured_addon_add_failure"
+msgstr "Eșec la adăugarea favoritului."
+
+#: controllers/editors_controller.php:851
+msgid "editors_featured_addon_add_success"
+msgstr "Favorit adăugat cu succes."
+
+#: views/editors/featured.thtml:50 controllers/editors_controller.php:839
+#: controllers/editors_controller.php:868
+#: controllers/editors_controller.php:886
+msgid "editors_featured_addon_edit_failure"
+msgstr "Eșec la editarea favoritului."
+
+#: views/editors/featured.thtml:51 controllers/editors_controller.php:888
+msgid "editors_featured_addon_edit_success"
+msgstr "Favorit editat cu succes."
+
+#: views/editors/featured.thtml:53 controllers/editors_controller.php:861
+msgid "editors_featured_addon_invalid_locale"
+msgstr "Una sau mai multe localizări sunt invalide."
+
+#: views/editors/featured.thtml:52 controllers/editors_controller.php:906
+msgid "editors_featured_addon_remove_failure"
+msgstr "Eșec la eliminarea favoritului."
+
+#: controllers/editors_controller.php:901
+msgid "editors_featured_addon_remove_success"
+msgstr "Favorit eliminat cu succes."
+
+#: controllers/editors_controller.php:915
+#: controllers/editors_controller.php:917
+msgid "editors_featured_addons_pagetitle"
+msgstr "Suplimente excepționale"
+
+#: views/editors/featured.thtml:54 views/editors/featured.thtml:107
+msgid "editors_featured_edit_feature_submit"
+msgstr "Du-te"
+
+#: views/editors/featured.thtml:90 views/editors/featured.thtml:91
+msgid "editors_featured_remove_feature"
+msgstr "Elimină favorit"
+
+#: views/editors/queue.thtml:46
+msgid "editors_filter_queue"
+msgstr "Filtre coadă"
+
+#: views/editors/queue.thtml:182
+msgid "editors_helpful_links"
+msgstr "Legături spre ajutor"
+
+#: views/editors/queue.thtml:182
+msgid "editors_link_guide"
+msgstr "Ghidul editorului"
+
+#: views/editors/queue.thtml:182
+msgid "editors_link_policy"
+msgstr "Politică suplimente"
+
+#: views/editors/queue.thtml:47
+msgid "editors_notice_filter_session"
+msgstr ""
+"Aceste filtre vor rămâne aici pentru această sesiune sau până sunt curățate."
+
+#. %1 is the queue mode
+#: views/editors/queue.thtml:177 views/admin/flagged_queue.thtml:89
+msgid "editors_notice_none_found"
+msgstr "Nu sunt suplimente %s de recenziat."
+
+#: controllers/editors_controller.php:1040
+msgid "editors_one_day"
+msgstr "1 zi"
+
+#: controllers/editors_controller.php:1048
+msgid "editors_one_hour"
+msgstr "1 oră"
+
+#: controllers/editors_controller.php:1056
+msgid "editors_one_minute"
+msgstr "1 minut"
+
+#: controllers/editors_controller.php:64 controllers/editors_controller.php:73
+#: controllers/editors_controller.php:77
+msgid "editors_pagetitle"
+msgstr "Panoul de control al editorului"
+
+#. %s is a comma separated list of platforms. Example: Windows, OS X
+#: controllers/editors_controller.php:680
+#: controllers/editors_controller.php:683
+#, php-format
+msgid "editors_platform_x_only"
+msgstr "numai %s"
+
+#: controllers/editors_controller.php:695
+msgid "editors_pre-release"
+msgstr "Ediție preliminară"
+
+#. %1 is the app name
+#: views/editors/queue.thtml:131
+#, php-format
+msgid "editors_queue_app_compatibility"
+msgstr "Compatibilitate cu %s"
+
+#: views/editors/queue.thtml:51
+msgid "editors_queue_filter_label_addon"
+msgstr ""
+
+#: views/editors/queue.thtml:72
+msgid "editors_queue_filter_label_addontypes"
+msgstr "Tipuri de suplimente"
+
+#: views/editors/queue.thtml:56
+msgid "editors_queue_filter_label_application"
+msgstr "Aplicație"
+
+#: views/editors/queue.thtml:61
+msgid "editors_queue_filter_label_maxversion"
+msgstr ""
+
+#: views/editors/queue.thtml:78
+msgid "editors_queue_filter_label_platforms"
+msgstr "Platforme"
+
+#: views/editors/queue.thtml:66
+msgid "editors_queue_filter_label_submissionage"
+msgstr ""
+
+#. %1$s is a number
+#: views/editors/queue.thtml:90
+msgid "editors_queue_filter_result_count"
+msgid_plural "editors_queue_filter_result_count"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+
+#: views/editors/queue.thtml:84
+msgid "editors_queue_submit_clean"
+msgstr "Curăță"
+
+#: views/editors/queue.thtml:83
+msgid "editors_queue_submit_filter"
+msgstr "Filtrează"
+
+#: controllers/editors_controller.php:133
+msgid "editors_queues_disabled"
+msgstr ""
+"Cozile de recenzie sunt dezactivate. Vă rugăm încercați din nou mai târziu."
+
+#: views/editors/review.thtml:149
+msgid "editors_review_a_edit_item"
+msgstr "Editează elementul"
+
+#: views/editors/review.thtml:146
+msgid "editors_review_a_item_history"
+msgstr "Istoricul elementului"
+
+#: views/editors/review.thtml:148
+msgid "editors_review_a_item_homepage"
+msgstr ""
+
+#: views/editors/review.thtml:145
+msgid "editors_review_a_item_overview"
+msgstr ""
+
+#: views/editors/review.thtml:147
+msgid "editors_review_a_previews"
+msgstr "Previzualizări"
+
+#: controllers/editors_controller.php:345
+msgid "editors_review_action"
+msgstr "Acțiune de recenzent"
+
+#: views/editors/review.thtml:159
+msgid "editors_review_action_info"
+msgstr ""
+
+#: views/editors/review.thtml:157
+msgid "editors_review_action_public"
+msgstr "Trimite spre public"
+
+#: views/editors/review.thtml:160
+msgid "editors_review_action_request_superreview"
+msgstr "Cere o supra-recenzie"
+
+#: views/editors/review.thtml:158
+msgid "editors_review_action_sandbox"
+msgstr "Reține în cutia cu nisip"
+
+#: controllers/editors_controller.php:346
+msgid "editors_review_comments"
+msgstr "Comentarii recenzent"
+
+#: views/editors/review.thtml:182
+msgid "editors_review_details_info_request"
+msgstr ""
+
+#: views/editors/review.thtml:174
+msgid "editors_review_details_nominated_public"
+msgstr ""
+"Aceasta va marca cea mai recentă versiune a suplimentului și fișierele lui ca "
+"publice. Versiunile viitoare vor sta în cutia cu nisip până când sunt "
+"recenziate de un editor."
+
+#: views/editors/review.thtml:177
+msgid "editors_review_details_nominated_sandbox"
+msgstr "Aceasta va reține suplimentul în cutia cu nisip."
+
+#: views/editors/review.thtml:166
+msgid "editors_review_details_pending_public"
+msgstr ""
+"Aceasta va aproba apariția pe saitul public a unei versiuni de supliment "
+"public din cutia cu nisip."
+
+#: views/editors/review.thtml:169
+msgid "editors_review_details_pending_sandbox"
+msgstr ""
+"Aceasta va face ca versiunea din cutia cu nisip a suplimentului public să "
+"rămână în cutia cu nisip."
+
+#: views/editors/review.thtml:185
+msgid "editors_review_details_superreview"
+msgstr ""
+"Dacă vă preocupă securitatea acestui supliment, probleme legate de drepturi "
+"de autor sau alte probleme pe care un administrator ar trebui să se uite, "
+"introduceți comentariile dumneavoastră în zona de mai jos. Ele vor fi trimise "
+"administratorilor, nu autorului."
+
+#: views/editors/review.thtml:134
+msgid "editors_review_file_diff_link"
+msgstr "Compară cu versiunea publică"
+
+#: views/editors/review.thtml:131
+msgid "editors_review_file_viewcontents_link"
+msgstr "Vezi conținutul"
+
+#: views/editors/review.thtml:65
+msgid "editors_review_header_authors"
+msgstr "Autori:"
+
+#: views/editors/review.thtml:79
+msgid "editors_review_header_categories"
+msgstr "Categorii:"
+
+#: views/editors/review.thtml:92
+msgid "editors_review_header_compatibility"
+msgstr "Compatibilitate:"
+
+#: views/editors/review.thtml:251
+msgid "editors_review_header_description"
+msgstr "Descriere"
+
+#: views/editors/review.thtml:275
+msgid "editors_review_header_devcomments"
+msgstr "Comentariile dezvoltatorului"
+
+#: views/editors/review.thtml:263
+msgid "editors_review_header_eula"
+msgstr "EULA"
+
+#: views/editors/review.thtml:115
+msgid "editors_review_header_files"
+msgstr "Fișiere:"
+
+#: views/editors/review.thtml:284
+msgid "editors_review_header_itemhistory"
+msgstr "Istoricul elementului"
+
+#: views/editors/review.thtml:232
+msgid "editors_review_header_nominationmessage"
+msgstr "Mesaj de nominalizare"
+
+#: views/editors/review.thtml:311
+msgid "editors_review_header_previews"
+msgstr "Avanpremiere"
+
+#: views/editors/review.thtml:269
+msgid "editors_review_header_privacy"
+msgstr "Politică de confidențialitate"
+
+#. %1 is the add-on name and version
+#: views/editors/review.thtml:56
+#, php-format
+msgid "editors_review_header_review"
+msgstr "Recenzie %s"
+
+#: views/editors/review.thtml:239
+msgid "editors_review_header_reviewernotes"
+msgstr "Note către recenzent"
+
+#: views/editors/review.thtml:245
+msgid "editors_review_header_summary"
+msgstr "Descriere sumară"
+
+#: views/editors/review.thtml:257
+msgid "editors_review_header_versionnotes"
+msgstr "Note versiune"
+
+#. a noun: shown in an add-on's editor review history
+#: views/elements/developers/editors_review_history_item.thtml:80
+msgid "editors_review_history_info_reply"
+msgstr "Răspunde"
+
+#: views/elements/developers/editors_review_history_item.thtml:78
+msgid "editors_review_history_info_request"
+msgstr ""
+
+#: views/elements/developers/editors_review_history_item.thtml:62
+#: views/editors/reviewlog.thtml:77
+msgid "editors_review_history_nominated_adminreview"
+msgstr "Recenzie administrator"
+
+#: views/elements/developers/editors_review_history_item.thtml:56
+#: views/editors/reviewlog.thtml:71
+msgid "editors_review_history_nominated_approved"
+msgstr "Nominalizare acordată/Public"
+
+#: views/elements/developers/editors_review_history_item.thtml:59
+#: views/editors/reviewlog.thtml:74
+msgid "editors_review_history_nominated_denied"
+msgstr "Nominalizare respinsă/Cutia cu nisip"
+
+#: views/editors/review.thtml:303
+msgid "editors_review_history_nonefound"
+msgstr "Nu s-au găsit recenzii anterioare."
+
+#: views/elements/developers/editors_review_history_item.thtml:73
+#: views/editors/reviewlog.thtml:88
+msgid "editors_review_history_pending_adminreview"
+msgstr "Recenzie administrator"
+
+#: views/elements/developers/editors_review_history_item.thtml:67
+#: views/editors/reviewlog.thtml:82
+msgid "editors_review_history_pending_approved"
+msgstr "Aprobat/Public"
+
+#: views/elements/developers/editors_review_history_item.thtml:70
+#: views/editors/reviewlog.thtml:85
+msgid "editors_review_history_pending_denied"
+msgstr "Respins/Cutia cu nisip"
+
+#. link text in an add-on's editor review history, allowing to hide and show an information request's replies
+#. %1 is the number of replies
+#: views/elements/developers/editors_review_history_item.thtml:90
+msgid "editors_review_history_show_hide_replies"
+msgid_plural "editors_review_history_show_hide_replies"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+
+#: views/editors/review.thtml:208
+msgid "editors_review_label_applications"
+msgstr "Aplicații:"
+
+#: views/editors/review.thtml:196
+msgid "editors_review_label_cannedresponse"
+msgstr "sau alegeți un răspuns salvat:"
+
+#: views/editors/review.thtml:190
+msgid "editors_review_label_comments"
+msgstr "Comentarii:"
+
+#: views/editors/review.thtml:204
+msgid "editors_review_label_operating_systems"
+msgstr "Sisteme de operare:"
+
+#: views/editors/review.thtml:285 views/editors/review.thtml:312
+msgid "editors_review_link_pagetop"
+msgstr "Sus"
+
+#: views/editors/review.thtml:141
+msgid "editors_review_mulitple_notice"
+msgstr ""
+
+#: views/editors/review.thtml:51
+msgid "editors_review_next_link"
+msgstr "înainte &raquo;"
+
+#: views/editors/review.thtml:322
+msgid "editors_review_previews_notfound"
+msgstr "Nu s-a găsit nicio avanpremieră."
+
+#: views/editors/review.thtml:50
+msgid "editors_review_previous_link"
+msgstr "&laquo; înapoi"
+
+#: controllers/editors_controller.php:144
+#: controllers/editors_controller.php:146
+msgid "editors_review_queue_pagetitle"
+msgstr "Coada recenziilor"
+
+#. %1 is the add-ons rank in the queue, %2 is the total queue length
+#: views/editors/review.thtml:47
+msgid "editors_review_rank_in_queue"
+msgstr "<strong># %1$s</strong> din %2$s care sunt în coadă"
+
+#. %1 is the add-ons rank in the queue, %2 is the total queue length. Both numbers
+#: views/editors/review.thtml:45
+msgid "editors_review_rank_in_queue_filtered"
+msgstr ""
+
+#: views/editors/review.thtml:223
+msgid "editors_review_submit_process_action"
+msgstr "Procesează acțiunea"
+
+#: views/editors/review.thtml:293
+msgid "editors_review_th_action"
+msgstr "Acțiune"
+
+#: views/editors/review.thtml:294
+msgid "editors_review_th_comments"
+msgstr "Comentarii"
+
+#: views/editors/review.thtml:291
+msgid "editors_review_th_date"
+msgstr "Dată"
+
+#: views/editors/review.thtml:292
+msgid "editors_review_th_reviewer"
+msgstr "Recenzent"
+
+#: views/editors/review.thtml:290
+msgid "editors_review_th_version_file"
+msgstr "Versiune/Fișier"
+
+#: views/editors/review.thtml:217
+msgid "editors_review_update_notify_once"
+msgstr ""
+
+#: controllers/editors_controller.php:298
+msgid "editors_reviewed_successfully"
+msgstr "Recenzie procesată cu succes."
+
+#: views/editors/reviews_queue.thtml:106
+msgid "editors_reviews_action_delete_review"
+msgstr "Șterge recenzia"
+
+#: views/editors/reviews_queue.thtml:104
+msgid "editors_reviews_action_keep"
+msgstr "Șterge marcajul; păstrează recenzia"
+
+#: views/editors/reviews_queue.thtml:102
+msgid "editors_reviews_action_skip"
+msgstr "Sări"
+
+#: views/editors/reviews_queue.thtml:100
+msgid "editors_reviews_header_action"
+msgstr "Acțiune"
+
+#: views/editors/reviews_queue.thtml:67
+msgid "editors_reviews_in_reply_to"
+msgstr "Răspuns pentru:"
+
+#: controllers/editors_controller.php:748
+msgid "editors_reviews_processed"
+msgstr "Recenziile au fost procesate cu succes!"
+
+#: views/editors/reviews_queue.thtml:117
+msgid "editors_reviews_queue_empty"
+msgstr "Nu sunt recenzii de făcut."
+
+#: views/editors/reviews_queue.thtml:111
+msgid "editors_reviews_submit_process_reviews"
+msgstr "Procesează recenzii"
+
+#: controllers/editors_controller.php:691
+msgid "editors_site_specific"
+msgstr "Sait specific"
+
+#: controllers/editors_controller.php:348
+msgid "editors_tested_app"
+msgstr "Aplicație testată"
+
+#: controllers/editors_controller.php:347
+msgid "editors_tested_os"
+msgstr "Sisteme de operare testate"
+
+#: views/editors/queue.thtml:151
+msgid "editors_th_additional_info"
+msgstr "Informații adiționale"
+
+#: views/editors/featured.thtml:63 views/editors/queue.thtml:109
+#: views/admin/flagged_queue.thtml:53
+msgid "editors_th_addon"
+msgstr "Supliment"
+
+#: views/editors/queue.thtml:125
+msgid "editors_th_addontype"
+msgstr "Tip"
+
+#: views/editors/featured.thtml:64
+msgid "editors_th_locales"
+msgstr "Restricție la localizări?"
+
+#: views/editors/queue.thtml:148
+msgid "editors_th_nomination_age"
+msgstr ""
+
+#: views/editors/queue.thtml:101 views/editors/queue.thtml:117
+#: views/editors/queue.thtml:144
+msgid "editors_th_sort_ascending"
+msgstr ""
+
+#: views/editors/queue.thtml:105 views/editors/queue.thtml:121
+#: views/editors/queue.thtml:140
+msgid "editors_th_sort_descending"
+msgstr ""
+
+#. %s is a number
+#: controllers/editors_controller.php:1036
+#, php-format
+msgid "editors_x_days"
+msgstr "%s zile"
+
+#. %s is a number
+#: controllers/editors_controller.php:1044
+#, php-format
+msgid "editors_x_hours"
+msgstr "%s ore"
+
+#. %s is a number
+#: controllers/editors_controller.php:1052
+#, php-format
+msgid "editors_x_minutes"
+msgstr "%s minute"
+
+#: views/errors/error401.thtml:50 controllers/components/simple_acl.php:81
+#: controllers/components/simple_acl.php:82
+#: controllers/components/simple_acl.php:83 controllers/components/amo.php:607
+#: controllers/components/amo.php:608 controllers/components/amo.php:609
+#: controllers/reviews_controller.php:353
+#: controllers/reviews_controller.php:485
+#: controllers/collections_controller.php:438
+#: controllers/collections_controller.php:496
+#: controllers/collections_controller.php:504
+#: controllers/collections_controller.php:971
+#: controllers/collections_controller.php:1034
+#: controllers/collections_controller.php:1077
+msgid "error_access_denied"
+msgstr "Acces interzis"
+
+#: views/errors/error401.thtml:52
+msgid "error_access_denied_message"
+msgstr "Nu sunteți autorizat(ă) să vedeți această pagină."
+
+#: controllers/collections_controller.php:1039
+msgid "error_addon_exists"
+msgstr ""
+
+#: controllers/developers_controller.php:200
+#: controllers/developers_controller.php:593
+#: controllers/developers_controller.php:1016
+#: controllers/developers_controller.php:1429
+#: controllers/downloads_controller.php:95
+#: controllers/downloads_controller.php:102
+#: controllers/downloads_controller.php:164
+#: controllers/statistics_controller.php:135
+#: controllers/previews_controller.php:115
+#: controllers/previews_controller.php:206
+#: controllers/previews_controller.php:307
+#: controllers/reviews_controller.php:77 controllers/reviews_controller.php:240
+#: controllers/reviews_controller.php:332
+#: controllers/reviews_controller.php:340 controllers/api_controller.php:123
+#: controllers/api_controller.php:759 controllers/addons_controller.php:131
+#: controllers/addons_controller.php:197 controllers/addons_controller.php:1407
+#: controllers/addons_controller.php:1465
+#: controllers/addons_controller.php:1469
+#: controllers/addons_controller.php:1503
+#: controllers/editors_controller.php:265
+#: controllers/collections_controller.php:1041
+#: controllers/collections_controller.php:1074
+msgid "error_addon_notfound"
+msgstr "Supliment negăsit"
+
+#: controllers/files_controller.php:83 controllers/files_controller.php:196
+msgid "error_addon_notviewable"
+msgstr "Suplimentul nu poate fi văzut aici."
+
+#: controllers/reviews_controller.php:246
+msgid "error_addon_selfreview"
+msgstr "Nu puteți recenzia propriul supliment."
+
+#: controllers/addons_controller.php:970
+msgid "error_browse_no_addons"
+msgstr "Niciun supliment în această categorie!"
+
+#: controllers/api_controller.php:424
+msgid "error_collection_feed_notfound"
+msgstr "Nu s-a găsit fluxul suplimentelor."
+
+#: views/users/register.thtml:65 views/users/edit.thtml:194
+msgid "error_email_invalid"
+msgstr "Aceasta nu este o adresă vaildă de email."
+
+#: views/users/pwreset.thtml:74 views/users/register.thtml:70
+#: views/users/register.thtml:80 views/users/register.thtml:86
+#: views/users/edit.thtml:105 views/users/edit.thtml:111
+#: views/users/edit.thtml:192 views/admin/users_edit.thtml:78
+#: views/admin/users_edit.thtml:83 views/reviews/add.thtml:80
+#: views/reviews/add.thtml:104
+msgid "error_field_required"
+msgstr "Acest câmp nu poate fi lăsat necompletat."
+
+#: controllers/files_controller.php:75 controllers/files_controller.php:93
+#: controllers/files_controller.php:96 controllers/files_controller.php:163
+#: controllers/files_controller.php:176 controllers/files_controller.php:185
+#: controllers/files_controller.php:204 controllers/editors_controller.php:412
+msgid "error_file_notfound"
+msgstr "Fișier negăsit!"
+
+#. %s is a filename
+#: controllers/editors_controller.php:430
+#, php-format
+msgid "error_file_x_notfound"
+msgstr "Eroare în fișier: nu·există %s."
+
+#: views/collections/add.thtml:55 views/collections/edit.thtml:89
+#: views/users/register.thtml:54 views/users/edit.thtml:81
+#: views/reviews/add.thtml:70 controllers/groups_controller.php:80
+#: controllers/groups_controller.php:102
+msgid "error_formerrors"
+msgstr ""
+"Sunt erori în acest formular. Vă rugăm corectați-le și trimiteți-l din nou."
+
+#: views/users/register.thtml:109
+msgid "error_invalid_captcha"
+msgstr "Captcha invalid, vă rugăm încercați din nou!"
+
+#: views/users/register.thtml:100 views/users/edit.thtml:125
+#: views/admin/users_edit.thtml:101
+msgid "error_invalid_url"
+msgstr ""
+"Acest URL are un format invalid. URL-urile valide arată ca http://exemplu.com/"
+"paginamea."
+
+#. %s is a string representing what's missing. Example: file_id
+#: controllers/downloads_controller.php:65 controllers/users_controller.php:185
+#: controllers/users_controller.php:264 controllers/users_controller.php:559
+#: controllers/users_controller.php:653 controllers/reviews_controller.php:71
+#: controllers/reviews_controller.php:234
+#: controllers/reviews_controller.php:325
+#: controllers/reviews_controller.php:473
+#: controllers/reviews_controller.php:475 controllers/addons_controller.php:182
+#: controllers/addons_controller.php:1381
+#: controllers/addons_controller.php:1455
+#: controllers/collections_controller.php:266
+#: controllers/collections_controller.php:285
+#: controllers/collections_controller.php:346
+#: controllers/collections_controller.php:443
+#: controllers/collections_controller.php:482
+#: controllers/collections_controller.php:936
+#: controllers/collections_controller.php:959
+#: controllers/collections_controller.php:960
+#: controllers/collections_controller.php:975
+#: controllers/collections_controller.php:977
+#: controllers/collections_controller.php:994
+#: controllers/collections_controller.php:1003
+#: controllers/collections_controller.php:1016
+#: controllers/collections_controller.php:1017
+#: controllers/collections_controller.php:1024
+#: controllers/collections_controller.php:1070
+#: controllers/collections_controller.php:1090
+#, php-format
+msgid "error_missing_argument"
+msgstr "Argument lipsă: %s"
+
+#: controllers/components/amo.php:507 controllers/components/amo.php:532
+msgid "error_no_files_in_addon"
+msgstr "Nu există fișiere"
+
+#: controllers/previews_controller.php:200
+msgid "error_preview_notfound"
+msgstr "Avanpremieră negăsită!"
+
+#: views/addons/display.thtml:400 views/reviews/add.thtml:98
+msgid "error_review_rating_required"
+msgstr "Trebuie să selectați o evaluare."
+
+#: controllers/users_controller.php:160
+msgid "error_user_already_confirmed"
+msgstr "Acest cont de utilizator este deja confirmat."
+
+#: controllers/users_controller.php:202 controllers/users_controller.php:276
+#: controllers/users_controller.php:569 controllers/users_controller.php:581
+#: controllers/users_controller.php:587 controllers/users_controller.php:610
+#: controllers/users_controller.php:627
+msgid "error_user_badconfirmationcode"
+msgstr "Cod de confirmare invalid!"
+
+#: views/users/pwreset.thtml:79 views/users/register.thtml:75
+#: views/users/edit.thtml:183
+msgid "error_user_confirmpw_nomatch"
+msgstr "Parolele nu se potrivesc."
+
+#: views/users/register.thtml:65 views/users/edit.thtml:190
+#: controllers/users_controller.php:617
+msgid "error_user_email_notunique"
+msgstr "Această adresă de email este luată deja de un alt utilizators."
+
+#: controllers/users_controller.php:596
+msgid "error_user_emailchange_expired"
+msgstr ""
+"Cererea de schimbare a emailului a expirat. Vă rugăm să vă schimbați adresa "
+"de email din nou în profilul de utilizator și odată ce primiți mesajul de "
+"confirmare, urmați legătura din el pentru a activa noua adresa de email."
+
+#: controllers/collections_controller.php:985
+msgid "error_user_exists"
+msgstr ""
+
+#: views/users/register.thtml:91 views/users/edit.thtml:116
+#: views/admin/users_edit.thtml:88
+msgid "error_user_nickname_notunique"
+msgstr "Porecla este deja luată."
+
+#: views/users/pwreset.thtml:54 controllers/users_controller.php:191
+#: controllers/users_controller.php:270 controllers/users_controller.php:603
+#: controllers/users_controller.php:659
+#: controllers/collections_controller.php:988
+#: controllers/collections_controller.php:998
+msgid "error_user_notfound"
+msgstr "Utilizator inexistent!"
+
+#: views/users/activatefirst.thtml:47
+msgid "error_user_unconfirmed"
+msgstr ""
+"Vă rugăm confirmați contul dumneavoastră cu codul pe care l-ați primit prin e-"
+"mail."
+
+#: views/users/login.thtml:67
+msgid "error_username_or_pw_wrong"
+msgstr "Ați greșit utilizatorul sau parola!"
+
+#: controllers/editors_controller.php:260
+msgid "error_version_notfound"
+msgstr "Nu s-a găsit versiunea!"
+
+#: views/users/delete.thtml:125 views/users/edit.thtml:173
+msgid "error_wrong_password"
+msgstr "Ați introdus o parolă greșită!"
+
+#: views/elements/amo2009/homepage_addon.thtml:122
+#: views/elements/feature.thtml:122
+msgid "feature_learnmore"
+msgstr "Continuare"
+
+#. %1 is the add-on name
+#: views/elements/amo2009/homepage_addon.thtml:123
+#: views/elements/feature.thtml:123
+#, php-format
+msgid "feature_learnmore_about_addon"
+msgstr "Află mai multe despre %1$s"
+
+#. %1$s is a number
+#: views/elements/amo2009/reviews.thtml:52
+#: views/elements/addon_listitem.thtml:112 views/elements/feature.thtml:99
+#: views/addons/browse_thumbs.thtml:86
+#, php-format
+msgid "feature_reviews"
+msgid_plural "feature_reviews"
+msgstr[0] "%1$s recenzie"
+msgstr[1] "%1$s recenzii"
+msgstr[2] "%1$s de recenzii"
+
+#: views/elements/amo2009/homepage_addon.thtml:127
+#: views/elements/feature.thtml:127
+msgid "feature_view_more_from_category"
+msgstr "Mai multe din"
+
+#. This appears on a page that views the source of an add-on. This link will return
+#. the user to the add-on's main page
+#: views/files/browse.thtml:65
+msgid "file_browser_link_addon"
+msgstr ""
+
+#. There is a list of directories and files on the page. Clicking this will show the
+#. contents of all the directories (normally you would click on each one to see the
+#. contents)
+#: views/files/browse.thtml:67
+msgid "file_browser_link_expand_all"
+msgstr "Extinde tot"
+
+#. This appears on a page that views the source of an add-on. This link will return
+#. the user to the add-on's review page (it only appears if the add-on is being
+#. reviewed)
+#: views/files/browse.thtml:64
+msgid "file_browser_link_review"
+msgstr ""
+
+#. The title of the page for viewing an add-on's source.
+#. %1$s is the name of the add-on
+#. %2$s is the name of the current application (e.g. Firefox or Thunderbird)
+#: views/files/browse.thtml:46
+msgid "file_browser_title"
+msgstr ""
+
+#. This appears on a page that views the source of an add-on. There is a list of
+#. directories and files on the page. Clicking this link will toggle between an
+#. expanded or a collapsed list. This string should be kept short.
+#: views/files/browse.thtml:68
+msgid "file_browser_toggle_expand_collapse"
+msgstr ""
+
+#. Link text for the AMO About page.
+#: views/elements/footer.thtml:72 views/layouts/amo2009.thtml:341
+msgid "footer_a_about"
+msgstr "Despre"
+
+#. Link text to the AMO blog.
+#: views/elements/footer.thtml:74 views/layouts/amo2009.thtml:343
+msgid "footer_a_blog"
+msgstr "Blog"
+
+#. Link text to the Frequently Asked Questions page.
+#: views/elements/footer.thtml:73 views/layouts/amo2009.thtml:342
+msgid "footer_a_faq"
+msgstr "Întrebări frecvente"
+
+#. Full text for the FAQ abbreviation.
+#: views/elements/footer.thtml:73 views/pages/collector_features.thtml:72
+#: views/layouts/amo2009.thtml:342
+msgid "footer_abbr_faq"
+msgstr "Cele mai întâlnite întrebări"
+
+#: views/elements/footer.thtml:67 views/layouts/amo2009.thtml:336
+msgid "footer_all_rights_reserved"
+msgstr "Toate drepturile rezervate."
+
+#: views/elements/footer.thtml:67 views/layouts/amo2009.thtml:336
+msgid "footer_copyright"
+msgstr "Drepturi de autor"
+
+#: views/elements/footer.thtml:71 views/layouts/amo2009.thtml:340
+msgid "footer_credits"
+msgstr "Merite"
+
+#: views/elements/footer.thtml:76 views/layouts/amo2009.thtml:346
+msgid "footer_disclaimer"
+msgstr ""
+"Mozilla furnizează legături către aceste aplicații ca o favoare și nu "
+"reprezintă persoanele care furnizează aplicațiile sau alte informații legate "
+"de ele. Orice întrebări, plângeri sau revendicări legate de aplicații trebuie "
+"să fie îndreptate către furnizorul aplicației."
+
+#: views/elements/footer.thtml:61 views/layouts/amo2009.thtml:332
+msgid "footer_lang_form_lang_submit_go"
+msgstr "Du-te"
+
+#: views/elements/footer.thtml:70 views/layouts/amo2009.thtml:339
+msgid "footer_legal_notices"
+msgstr "Mențiuni legale"
+
+#: views/elements/footer.thtml:50 views/layouts/amo2009.thtml:321
+msgid "footer_other_languages"
+msgstr "Alte limbi:"
+
+#: views/elements/footer.thtml:69 views/layouts/amo2009.thtml:338
+msgid "footer_privacy_policy"
+msgstr "Politică de confidențialitate"
+
+#: models/addontype.php:79
+msgid "general_addontype_dict"
+msgstr "Dicționar"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:100
+msgid "general_addontype_dict_plural"
+msgstr "Dicționare"
+
+#: models/addontype.php:75
+msgid "general_addontype_extension"
+msgstr "Extensie"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:98
+msgid "general_addontype_extension_plural"
+msgstr "Extensii"
+
+#: models/addontype.php:85
+msgid "general_addontype_lpaddon"
+msgstr "Pachet de limbă (Supliment)"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:103
+msgid "general_addontype_lpaddon_plural"
+msgstr "Pachete de limbă (Supliment)"
+
+#: models/addontype.php:83
+msgid "general_addontype_lpapp"
+msgstr "Pachet de limbă (Aplicație)"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:102
+msgid "general_addontype_lpapp_plural"
+msgstr "Pachete de limbă (Aplicație)"
+
+#: models/addontype.php:87
+msgid "general_addontype_plugin"
+msgstr "Modul"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:104
+msgid "general_addontype_plugin_plural"
+msgstr "Module"
+
+#: models/addontype.php:81
+msgid "general_addontype_search"
+msgstr "Motor de căutare"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:101
+msgid "general_addontype_search_plural"
+msgstr "Motoare de căutare"
+
+#: models/addontype.php:77
+msgid "general_addontype_theme"
+msgstr "Temă"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:99
+msgid "general_addontype_theme_plural"
+msgstr "Teme"
+
+#: config/language.php:367
+msgid "general_languages_all_locales"
+msgstr ""
+
+#: views/layouts/amo2009.thtml:249
+msgid "header_brand_name"
+msgstr "Mozilla"
+
+#. %1$s is the application name. Example: Firefox
+#: views/elements/header.thtml:111 views/elements/header.thtml:122
+#: views/layouts/amo2009.thtml:248
+#, php-format
+msgid "header_home_tooltip"
+msgstr "ÃŽnapoi la Suplimente %1$s"
+
+#: views/elements/header.thtml:87
+msgid "header_main_firefox_header"
+msgstr "Suplimente Firefox"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:218
+msgid "header_main_firefox_header_with_logo"
+msgstr ""
+
+#: views/elements/header.thtml:99
+msgid "header_main_header"
+msgstr "Suplimente"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:242
+msgid "header_main_header_with_logo"
+msgstr ""
+
+#: views/elements/header.thtml:90
+msgid "header_main_seamonkey_header"
+msgstr "Suplimente Seamonkey"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:224
+msgid "header_main_seamonkey_header_with_logo"
+msgstr ""
+
+#: views/elements/header.thtml:93
+msgid "header_main_sunbird_header"
+msgstr "Suplimente Sunbird"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:230
+msgid "header_main_sunbird_header_with_logo"
+msgstr ""
+
+#: views/elements/header.thtml:96
+msgid "header_main_thunderbird_header"
+msgstr "Suplimente Thunderbird"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:236
+msgid "header_main_thunderbird_header_with_logo"
+msgstr ""
+
+#: views/layouts/amo2009.thtml:205
+msgid "header_navaccess_applications_menu"
+msgstr ""
+
+#: views/layouts/amo2009.thtml:204
+msgid "header_navaccess_categories_menu"
+msgstr ""
+
+#: views/layouts/amo2009.thtml:202
+msgid "header_navaccess_main_content"
+msgstr ""
+
+#: views/layouts/amo2009.thtml:203
+msgid "header_navaccess_search_form"
+msgstr ""
+
+#: views/elements/header.thtml:62
+msgid "header_navlink_addons"
+msgstr "Suplimente"
+
+#: views/elements/developers/sidebar.thtml:72
+#: views/elements/developers/myaddons.thtml:50 views/elements/header.thtml:159
+#: views/addons/display.thtml:378
+msgid "header_navlink_login"
+msgstr "Autentificare"
+
+#: views/elements/header.thtml:156 views/layouts/amo2009.thtml:304
+msgid "header_navlink_logout"
+msgstr "Ieșire"
+
+#: views/elements/header.thtml:145 views/layouts/amo2009.thtml:303
+msgid "header_navlink_myaccount"
+msgstr "Contul meu"
+
+#: views/elements/header.thtml:158
+msgid "header_navlink_register"
+msgstr "ÃŽnregistrare"
+
+#. %1 is the URL to the registration page
+#. %2 is the URL to the login page
+#: views/layouts/amo2009.thtml:278
+msgid "header_navlink_register_or_login"
+msgstr ""
+
+#: views/layouts/amo2009.thtml:285
+msgid "header_navlink_tools"
+msgstr "Unelte"
+
+#. %s is the add-on name
+#: views/elements/collections_interactive_addon.thtml:62
+#: views/elements/amo2009/homepage_addon.thtml:77
+#: views/elements/addon_discussionheader.thtml:62
+#: views/elements/addon_listitem.thtml:67 views/elements/feature.thtml:84
+#: views/addons/category_landing.thtml:87 views/addons/browse_thumbs.thtml:60
+#, php-format
+msgid "img_preview_of"
+msgstr "Avanpremieră pentru %s"
+
+#. %1 is the login URL for the link tag
+#. %2 is the link to an explanatory page.
+#: views/elements/amo2009/install.thtml:307 views/elements/install.thtml:255
+msgid "install_a_login_to_install"
+msgstr "<a href=\"%1$s\">Autentificați-vă</a> pentru a instala acest supliment"
+
+#. %1 is the URL for the Experimental Add-ons section of the FAQ page
+#: views/elements/amo2009/install.thtml:283 views/elements/install.thtml:232
+msgid "install_button_confirm_exp_install"
+msgstr ""
+
+#. %1$s is the application name. Example: Firefox
+#. %2$s is an optional string used to specify a platform. Example: (Windows)
+#: views/elements/amo2009/install.thtml:128 views/elements/install.thtml:75
+#, php-format
+msgid "install_button_text"
+msgstr "Adaugă la %s %s"
+
+#. %1 is the add-on name, %2 is the app name
+#: views/elements/amo2009/install.thtml:191
+#: views/elements/amo2009/install.thtml:206
+#: views/elements/amo2009/install.thtml:249
+#: views/elements/amo2009/install.thtml:298 views/elements/install.thtml:150
+#: views/elements/install.thtml:165 views/elements/install.thtml:202
+#: views/elements/install.thtml:246
+#, php-format
+msgid "install_button_title"
+msgstr "Adaugă %1$s la %2$s"
+
+#. %1$s is the add-on name
+#: views/elements/amo2009/install.thtml:200 views/elements/install.thtml:159
+#, php-format
+msgid "install_download"
+msgstr "Descarcă %1$s"
+
+#: views/elements/amo2009/install.thtml:147 views/elements/install.thtml:94
+msgid "install_error_addon_not_found"
+msgstr "Acest supliment nu este disponibil."
+
+#: views/addons/dictionaries.thtml:65
+msgid "langtools_a11y_tablesummary"
+msgstr "Lista de pachete de limbi și dicționare."
+
+#: views/addons/dictionaries.thtml:47
+msgid "langtools_download_dictionary"
+msgstr "Descarcă dicționarul"
+
+#: views/addons/dictionaries.thtml:48
+msgid "langtools_download_langpack"
+msgstr "Descarcă pachetul de limbă"
+
+#: views/addons/dictionaries.thtml:63 controllers/components/amo.php:685
+#: controllers/addons_controller.php:1239
+msgid "langtools_header_dicts_and_langpacks"
+msgstr "Dicționare și pachete de limbă"
+
+#: views/addons/dictionaries.thtml:44
+msgid "langtools_install_dictionary"
+msgstr "Instalează dicționarul"
+
+#: views/addons/dictionaries.thtml:45
+msgid "langtools_install_langpack"
+msgstr "Instalează pachetul de limbă"
+
+#: views/addons/dictionaries.thtml:69
+msgid "langtools_tableheader_dictionary"
+msgstr "Dicționar"
+
+#: views/addons/dictionaries.thtml:70
+msgid "langtools_tableheader_langpack"
+msgstr "Pachet de limbă"
+
+#: views/addons/dictionaries.thtml:68
+msgid "langtools_tableheader_language"
+msgstr "Limbă"
+
+#: models/license.php:65
+msgid "license_custom"
+msgstr ""
+
+#: config/bootstrap.php:303
+msgid "licenses_bsd"
+msgstr ""
+
+#: config/bootstrap.php:298
+msgid "licenses_gpl_2.0"
+msgstr ""
+
+#: config/bootstrap.php:299
+msgid "licenses_gpl_3.0"
+msgstr ""
+
+#: config/bootstrap.php:300
+msgid "licenses_lgpl_2.1"
+msgstr ""
+
+#: config/bootstrap.php:301
+msgid "licenses_lgpl_3.0"
+msgstr ""
+
+#: config/bootstrap.php:302
+msgid "licenses_mit"
+msgstr ""
+
+#: config/bootstrap.php:297
+msgid "licenses_mpl_1.1"
+msgstr ""
+
+#: views/users/emailchange.thtml:51 views/users/delete.thtml:55
+#: views/users/delete.thtml:137 views/users/edit.thtml:74
+#: views/reviews/flag.thtml:54
+msgid "link_return_to_front_page"
+msgstr "Clic aici pentru a merge la pagina principală."
+
+#: views/elements/amo2009/addon_list_options.thtml:46
+#: views/elements/addon_list_options.thtml:46
+msgid "list_sortby_date"
+msgstr "Dată"
+
+#: views/elements/amo2009/addon_list_options.thtml:47
+#: views/elements/addon_list_options.thtml:47
+msgid "list_sortby_downloads"
+msgstr "Descărcări"
+
+#: views/elements/amo2009/addon_list_options.thtml:45
+#: views/elements/addon_list_options.thtml:45
+msgid "list_sortby_name"
+msgstr "Nume supliment"
+
+#: views/elements/amo2009/addon_list_options.thtml:48
+#: views/elements/addon_list_options.thtml:48
+msgid "list_sortby_rating"
+msgstr "Evaluare"
+
+#: config/bootstrap.php:278
+msgid "main_prettyname_fennec"
+msgstr "Fennec"
+
+#: config/bootstrap.php:274
+msgid "main_prettyname_firefox"
+msgstr "Firefox"
+
+#: config/bootstrap.php:277
+msgid "main_prettyname_seamonkey"
+msgstr "Seamonkey"
+
+#: config/bootstrap.php:276
+msgid "main_prettyname_sunbird"
+msgstr "Sunbird"
+
+#: config/bootstrap.php:275
+msgid "main_prettyname_thunderbird"
+msgstr "Thunderbird"
+
+#: views/elements/addon_categories.thtml:52
+msgid "nav_category_dicts_langpacks"
+msgstr "Dicționare și pachete de limbă"
+
+#: views/elements/addon_categories.thtml:55
+msgid "nav_category_themes"
+msgstr "Teme"
+
+#: views/elements/app_chooser.thtml:47 views/layouts/amo2009.thtml:255
+msgid "other_apps_tooltip"
+msgstr "Găsește suplimente pentru alte aplicații"
+
+#. In a user list: user 1, user 2, "others"
+#: views/helpers/addons_html.php:222
+msgid "other_users"
+msgstr "alții"
+
+#: controllers/pages_controller.php:90
+msgid "page_title_appversions"
+msgstr "Versiuni de aplicație"
+
+#: controllers/pages_controller.php:115
+msgid "page_title_collector"
+msgstr ""
+
+#: controllers/pages_controller.php:117
+msgid "page_title_collector_faq"
+msgstr ""
+
+#: controllers/pages_controller.php:119
+msgid "page_title_collector_features"
+msgstr ""
+
+#: controllers/pages_controller.php:122
+msgid "page_title_collector_firstrun"
+msgstr ""
+
+#: controllers/pages_controller.php:92
+msgid "page_title_credits"
+msgstr "Merite"
+
+#: controllers/pages_controller.php:113
+msgid "page_title_developer_faq"
+msgstr ""
+
+#: controllers/pages_controller.php:111
+msgid "page_title_faq"
+msgstr "Cele mai întâlnite întrebări"
+
+#: controllers/pages_controller.php:94
+msgid "page_title_fashionyourfirefox_faq"
+msgstr "ÃŽntrebări frecvente pentru „Fashion your Firefoxâ€"
+
+#: controllers/pages_controller.php:101
+msgid "page_title_policy"
+msgstr "Politica suplimentelor"
+
+#: controllers/pages_controller.php:103
+msgid "page_title_privacy"
+msgstr "Politica de confidențialitate Mozilla"
+
+#: controllers/pages_controller.php:105
+msgid "page_title_review_guide"
+msgstr "Ghid pentru recenzii"
+
+#: controllers/pages_controller.php:107
+msgid "page_title_sandbox"
+msgstr "Sistemul de recenzie prin cutia cu nisip"
+
+#: controllers/pages_controller.php:109
+msgid "page_title_submissionhelp"
+msgstr "Ajutor pentru trimiterea suplimentelor"
+
+#: views/pages/appversions.thtml:87
+msgid "pages_appversions_guid"
+msgstr "GUID"
+
+#: views/pages/appversions.thtml:79 controllers/pages_controller.php:90
+msgid "pages_appversions_header"
+msgstr "Versiuni valide de aplicație"
+
+#: views/pages/appversions.thtml:80
+msgid "pages_appversions_intro"
+msgstr ""
+"Suplimentele trimise către Suplimente Mozilla trebuie să aibă un "
+"fișierinstall.rdf cu cel puțin una din aplicațiile suportate de mai jos. "
+"Numai versiunile afișate mai jos sunt permise pentru aceste aplicații."
+
+#. %s is a full <a> tag
+#: views/pages/appversions.thtml:93
+#, php-format
+msgid "pages_appversions_required_files"
+msgstr ""
+"Dacă aplicația suportată de supliment nu necesită un fișier install.rdf, "
+"totuși trebuie să includeți unul cu proprietățile specificate în %s."
+
+#. this is the text inside of an <a> tag for pages_appversions_required_files. This
+#. should be fixed.
+#: views/pages/appversions.thtml:93
+msgid "pages_appversions_required_files_link"
+msgstr "aici"
+
+#: views/pages/appversions.thtml:88
+msgid "pages_appversions_versions"
+msgstr "Versiuni"
+
+#: views/pages/policy.thtml:51
+msgid "pages_policy_sandbox_link"
+msgstr "Pagina cu informații despre cutia cu nisip"
+
+#: views/elements/pagination.thtml:53
+msgid "pagination_next_page"
+msgstr "următoarea"
+
+#: views/elements/pagination.thtml:52
+msgid "pagination_previous_page"
+msgstr "precedenta"
+
+#: views/elements/recaptcha.thtml:65
+msgid "recaptcha_enter_both_words"
+msgstr ""
+"Vă rugăm să introduceți <strong>ambele cuvinte</strong> mai jos, "
+"<strong>separate de un spațiu</strong>."
+
+#: views/elements/recaptcha.thtml:83
+msgid "recaptcha_enter_here"
+msgstr "Introduceți răspunsul dumneavoastră aici:"
+
+#: views/elements/recaptcha.thtml:74
+msgid "recaptcha_enter_whatyouhear"
+msgstr "Vă rugăm să tastați ceea ce auziți."
+
+#. %1 is the link switching refreshing the captcha
+#. %2 is the link switching to a text captcha
+#: views/elements/recaptcha.thtml:77
+msgid "recaptcha_hardtohear_text"
+msgstr ""
+"Dacă este dificil de înțeles, puteți să <a href=\"%1$s\">ascultați altceva</"
+"a> sau să <a href=\"%2$s\">comutați înapoi la text</a>."
+
+#. %1 is the link switching refreshing the captcha
+#. %2 is the link switching to an audio captcha
+#: views/elements/recaptcha.thtml:68
+msgid "recaptcha_hardtoread_text"
+msgstr ""
+"Dacă este dificil de citit, puteți să <a href=\"%1$s\">încercați alte "
+"cuvinte</a> sau să <a href=\"%2$s\">ascultați ceva</a>."
+
+#: views/users/register.thtml:105
+msgid "recaptcha_label"
+msgstr "Sunteți om?"
+
+#: views/users/register.thtml:106
+msgid "recaptcha_whatsthis"
+msgstr "Ce e asta?"
+
+#: controllers/reviews_controller.php:559
+msgid "review_flag_error"
+msgstr "Eroare la marcarea acestei recenzii!"
+
+#: models/reviews_moderation_flag.php:69
+msgid "review_flag_reason_bug_support"
+msgstr "Raport de defect sau cerere de asistență amplasate greșit"
+
+#: views/reviews/display.thtml:103 views/reviews/display.thtml:186
+msgid "review_flag_reason_instructions"
+msgstr "Raportează această recenzie (alegeți un motiv)"
+
+#: models/reviews_moderation_flag.php:67
+msgid "review_flag_reason_language"
+msgstr "Limbaj necorespunzător"
+
+#: models/reviews_moderation_flag.php:71
+msgid "review_flag_reason_other"
+msgstr "Altele (vă rugăm să specificați)"
+
+#: models/reviews_moderation_flag.php:65
+msgid "review_flag_reason_spam"
+msgstr "Spam sau alt conținut care nu e o recenzie"
+
+#: views/reviews/display.thtml:91 views/reviews/display.thtml:175
+#: controllers/reviews_controller.php:555
+msgid "review_flag_success"
+msgstr ""
+"Vă mulțumim; recenzia a fost marcată pentru aprobare de către un editor."
+
+#: views/reviews/display.thtml:41
+msgid "review_flag_this"
+msgstr "Raportează această recenzie"
+
+#: views/reviews/display.thtml:42
+msgid "review_flag_this_titletip"
+msgstr ""
+"Este această recenzie nepotrivită, inexactă sau spam? Clic aici pentru a o "
+"marca pentru a fi recenziată de către un editor."
+
+#. %1 is the URL of the support section, %2 for the review guidelines
+#: views/reviews/add.thtml:53
+msgid "review_guidelines_short"
+msgstr ""
+"<p>Keep these tips in mind:</p><ul><li>Write like you're telling a friend "
+"about your experience with the add-on. Give specifics and helpful details, "
+"such as what features you liked and/ordisliked, how easy to use it is, and "
+"any disadvantages it has. Avoid genericlanguage such as calling it \"Great\" "
+"or \"Bad\" unless you can give reasons whyyou believe this is so.</"
+"li><li>Please do not post bug reports in reviews. We do not make your email "
+"address available to add-on developers and they may need to contact you to "
+"help resolveyour issue. See the <a href=\"%1$s\">support section</a> to find "
+"out where to get assistance for this add-on.</li><li>Please keep reviews "
+"clean, avoid the use of improper language and do not post any personal "
+"information.</li></ul><p>Please read the <a href=\"%2$s\">Review Guidelines</"
+"a> for more detail about user add-on reviews.</p>"
+
+#. %1 is the add-on name
+#: views/reviews/flag.thtml:56 views/reviews/display.thtml:55
+#: views/reviews/review_added.thtml:50
+#, php-format
+msgid "reviews_header"
+msgstr "Recenzii pentru %s"
+
+#: controllers/addons_controller.php:435
+msgid "rss_featuredaddons"
+msgstr "Suplimente excepționale"
+
+#: controllers/addons_controller.php:432
+msgid "rss_newestaddons"
+msgstr "Cele mai noi suplimente"
+
+#: controllers/addons_controller.php:434
+msgid "rss_popularaddons"
+msgstr "Suplimente populare"
+
+#: controllers/addons_controller.php:433
+msgid "rss_updatedaddons"
+msgstr "Suplimente actualizate"
+
+#: views/elements/search_mini.thtml:70
+msgid "search"
+msgstr "Caută"
+
+#: views/search/collections.thtml:51
+msgid "search_collections_header"
+msgstr ""
+
+#: controllers/search_controller.php:297
+msgid "search_collections_pagetitle"
+msgstr ""
+
+#: controllers/search_controller.php:99
+msgid "search_disabled"
+msgstr ""
+"Căutarea este actualmente dezactivată. Vă rugăm să încercați din nou mai "
+"târziu."
+
+#: views/elements/amo2009/search.thtml:188 views/elements/search.thtml:187
+#: views/elements/search_mini.thtml:54
+msgid "search_form_all_addons"
+msgstr "toate suplimentele"
+
+#. This string is in the main category dropdown when searching
+#: views/elements/amo2009/search.thtml:204
+msgid "search_form_all_collections"
+msgstr ""
+
+#: views/elements/amo2009/search.thtml:184
+#: views/elements/amo2009/search.thtml:385
+#: views/elements/amo2009/search.thtml:408 views/elements/search.thtml:171
+#: views/elements/search.thtml:183 views/elements/search_mini.thtml:43
+#: views/elements/search_mini.thtml:49 views/layouts/mozilla.thtml:188
+msgid "search_form_default_text"
+msgstr "caută"
+
+#: views/elements/amo2009/search.thtml:184
+#: views/elements/amo2009/search.thtml:404
+msgid "search_form_default_text_collections"
+msgstr ""
+
+#: views/elements/amo2009/search.thtml:206 views/elements/search.thtml:202
+msgid "search_form_submit_tooltip"
+msgstr "Caută suplimente"
+
+#: views/elements/amo2009/search.thtml:184 views/elements/search.thtml:183
+#: views/elements/search_mini.thtml:49
+msgid "search_form_tooltip"
+msgstr "Clic pentru a introduce termeni de căutare"
+
+#: views/elements/amo2009/search.thtml:186 views/elements/search.thtml:185
+#: views/elements/search_mini.thtml:52
+msgid "search_form_within"
+msgstr "în"
+
+#: views/addons/searchengines.thtml:118
+msgid "search_landing_all_search_engines"
+msgstr "Toate motoarele de căutare"
+
+#: views/addons/searchengines.thtml:114
+msgid "search_landing_browse_search_engines"
+msgstr "Răsfoiți motoarele de căutare"
+
+#: views/search/collections.thtml:58 views/search/index.thtml:59
+msgid "search_nothing_found"
+msgstr "Niciun rezultat găsit."
+
+#: controllers/search_controller.php:185
+msgid "search_pagetitle"
+msgstr "Căutare suplimente"
+
+#: controllers/search_controller.php:242
+msgid "search_rss_description"
+msgstr "Flux cu rezultatele căutării"
+
+#. %s is the terms the user is searching for (a string)
+#: controllers/search_controller.php:241
+#, php-format
+msgid "search_rss_results_for"
+msgstr "Rezultatele căutării după: %s"
+
+#: views/elements/header.thtml:154 views/layouts/amo2009.thtml:296
+msgid "sidebar_navlink_admin_tools"
+msgstr "Unelte pentru admin"
+
+#: views/elements/header.thtml:146 views/layouts/amo2009.thtml:288
+msgid "sidebar_navlink_developer_tools"
+msgstr "Unelte pentru dezvoltatori"
+
+#: views/elements/header.thtml:148 views/layouts/amo2009.thtml:290
+msgid "sidebar_navlink_editor_tools"
+msgstr "Unelte pentru editori"
+
+#: views/layouts/amo2009.thtml:302
+msgid "sidebar_navlink_welcome"
+msgstr "Bun venit"
+
+#. %s is the user's name
+#: views/layouts/amo2009.thtml:302
+#, php-format
+msgid "sidebar_navlink_welcome_name"
+msgstr "Bun venit, %s"
+
+#: views/elements/pitch.thtml:50 views/elements/pitch.thtml:55
+msgid "sidebar_pitch_dictionary"
+msgstr "Un dicționar"
+
+#: views/elements/pitch.thtml:72
+msgid "sidebar_pitch_featured_addons"
+msgstr "Suplimente excepționale"
+
+#: views/elements/pitch.thtml:61
+msgid "sidebar_pitch_looking_for"
+msgstr "Căutați:"
+
+#: views/elements/pitch.thtml:70
+msgid "sidebar_pitch_newest_addons"
+msgstr "Cele mai noi suplimente"
+
+#: views/elements/pitch.thtml:49
+msgid "sidebar_pitch_search"
+msgstr "Un motor de căutare"
+
+#: views/elements/pitch.thtml:69
+msgid "sidebar_pitch_subscribe_to"
+msgstr "Abonează-mă la"
+
+#: views/elements/pitch.thtml:48 views/elements/pitch.thtml:54
+msgid "sidebar_pitch_theme"
+msgstr "O temă"
+
+#: views/elements/pitch.thtml:71
+msgid "sidebar_pitch_updated_addons"
+msgstr "Suplimente actualizate"
+
+#. %1$s is a number
+#: views/helpers/localization.php:65 views/developers/versions_edit.thtml:95
+#: views/addons/dictionaries.thtml:92
+#, php-format
+msgid "size_kb"
+msgstr "%1$s KO"
+
+#: views/elements/amo2009/stars.thtml:57 views/elements/stars.thtml:63
+msgid "stars_not_yet_rated"
+msgstr "Neevaluat încă"
+
+#. %1 is the number of stars this add-on has
+#: views/elements/amo2009/stars.thtml:49 views/elements/stars.thtml:54
+#, php-format
+msgid "stars_rated_x_outof_5"
+msgstr "Evaluat la %s stele din 5"
+
+#: views/statistics/addon.thtml:59
+msgid "statistics_addon_dashboard_link"
+msgstr "Tabloul de bord"
+
+#: views/statistics/addon.thtml:58
+msgid "statistics_addon_developertools_link"
+msgstr "Unelte pentru dezvoltatori"
+
+#: views/statistics/addon.thtml:53
+msgid "statistics_addon_switch"
+msgstr "Schimbă suplimentul"
+
+#. This is a date format.
+#. http://php.net/strftime
+#: views/statistics/rss/summary.thtml:54 views/statistics/addon.thtml:181
+msgid "statistics_date_shortmonth"
+msgstr "Bun venit, %s"
+
+#. This is a date format.
+#. http://php.net/strftime
+#: views/statistics/rss/summary.thtml:40 views/statistics/addon.thtml:152
+msgid "statistics_date_shortmonthwithyear"
+msgstr "%e %b %Y"
+
+#. This is a date format.
+#. http://php.net/strftime
+#: views/statistics/rss/summary.thtml:41 views/statistics/rss/summary.thtml:48
+#: views/statistics/addon.thtml:161 views/statistics/addon.thtml:172
+msgid "statistics_date_weekdayshortmonth"
+msgstr "%A, %e %b"
+
+#. %1$s is an add-on name and version. Example: Add-on 3.5
+#: controllers/components/stats.php:519
+#, php-format
+msgid "statistics_events_addon_created"
+msgstr "S-a creat %1$s"
+
+#. %1$s is an application name and version. Example: Firefox 3.5
+#: controllers/components/stats.php:500
+#, php-format
+msgid "statistics_events_app_released"
+msgstr "S-a lansat %1$s"
+
+#: views/statistics/addon.thtml:71
+msgid "statistics_help_close_link"
+msgstr "ÃŽnchide"
+
+#: views/statistics/addon.thtml:60
+msgid "statistics_help_link"
+msgstr "Ajutor"
+
+#: views/statistics/index.thtml:83
+msgid "statistics_index_anotheraddon"
+msgstr "sau, selectați alt supliment"
+
+#: views/statistics/index.thtml:85
+msgid "statistics_index_anotheraddon_public"
+msgstr "sau, selectați un supliment cu statistici publice"
+
+#: views/statistics/index.thtml:71
+msgid "statistics_index_myaddons"
+msgstr "Selectați un supliment pentru a-i vedea statisticile"
+
+#: views/statistics/index.thtml:89
+msgid "statistics_index_selectaddon"
+msgstr "Alegeți un supliment pentru a-i vedea statisticile"
+
+#: views/statistics/index.thtml:91
+msgid "statistics_index_selectaddon_public"
+msgstr "Alegeți un supliment cu statistici publice"
+
+#: views/statistics/index.thtml:39
+msgid "statistics_index_title"
+msgstr "Statistici - Tablou de bord"
+
+#: views/statistics/index.thtml:97
+msgid "statistics_index_view_button"
+msgstr "Afișează statisticile"
+
+#: views/statistics/addon.thtml:222 controllers/statistics_controller.php:247
+msgid "statistics_js_download_csv"
+msgstr "Vezi acest tabel în format CSV"
+
+#: controllers/statistics_controller.php:246
+msgid "statistics_js_dropdowns_none"
+msgstr "niciunul"
+
+#: controllers/statistics_controller.php:245
+msgid "statistics_js_dropdowns_removeplot"
+msgstr "Șterge acest grafic"
+
+#: controllers/statistics_controller.php:248
+msgid "statistics_js_groupby_selector_date"
+msgstr "Grupare după: zi"
+
+#: controllers/statistics_controller.php:251
+msgid "statistics_js_groupby_selector_month"
+msgstr "Grupare după: lună"
+
+#: controllers/statistics_controller.php:249
+msgid "statistics_js_groupby_selector_week"
+msgstr "Grupare după: săptămână"
+
+#: controllers/statistics_controller.php:250
+msgid "statistics_js_groupby_selector_week_over_week"
+msgstr ""
+
+#: controllers/statistics_controller.php:260
+msgid "statistics_js_plotselection_foundinrange"
+msgstr "%s găsite în plajă"
+
+#: controllers/statistics_controller.php:270
+msgid "statistics_js_plotselection_options_addplot_name"
+msgstr "Adaugă grafic"
+
+#: controllers/statistics_controller.php:271
+msgid "statistics_js_plotselection_options_addplot_tooltip"
+msgstr "Adaugă un alt grafic"
+
+#: controllers/statistics_controller.php:261
+msgid "statistics_js_plotselection_options_count_name_checked"
+msgstr "Ascunde totalul"
+
+#: controllers/statistics_controller.php:262
+msgid "statistics_js_plotselection_options_count_name_unchecked"
+msgstr "Arată totalul"
+
+#: controllers/statistics_controller.php:263
+msgid "statistics_js_plotselection_options_count_tooltip"
+msgstr "Desenează totalul pe acest grafic"
+
+#: controllers/statistics_controller.php:275
+msgid "statistics_js_plotselection_options_csv_name"
+msgstr "Afișează datele (CSV)"
+
+#: controllers/statistics_controller.php:276
+msgid "statistics_js_plotselection_options_csv_tooltip"
+msgstr "Descarcă un fișier cu aceste date separate prin virgule (CSV)"
+
+#: controllers/statistics_controller.php:267
+msgid "statistics_js_plotselection_options_events_addon_name_checked"
+msgstr "Ascunde evenimentele %s"
+
+#: controllers/statistics_controller.php:268
+msgid "statistics_js_plotselection_options_events_addon_name_unchecked"
+msgstr "Arată evenimentele %s"
+
+#: controllers/statistics_controller.php:269
+msgid "statistics_js_plotselection_options_events_addon_tooltip"
+msgstr "Arată datele de lansare pe grafic"
+
+#: controllers/statistics_controller.php:264
+msgid "statistics_js_plotselection_options_events_firefox_name_checked"
+msgstr "Ascunde evenimentele Firefox"
+
+#: controllers/statistics_controller.php:265
+msgid "statistics_js_plotselection_options_events_firefox_name_unchecked"
+msgstr "Arată evenimentele Firefox"
+
+#: controllers/statistics_controller.php:266
+msgid "statistics_js_plotselection_options_events_firefox_tooltip"
+msgstr "Arată datele de lansare ale Firefox pe grafic"
+
+#: controllers/statistics_controller.php:272
+msgid "statistics_js_plotselection_options_resize_name_checked"
+msgstr "Pliază graficul"
+
+#: controllers/statistics_controller.php:273
+msgid "statistics_js_plotselection_options_resize_name_unchecked"
+msgstr "Expandează graficul"
+
+#: controllers/statistics_controller.php:274
+msgid "statistics_js_plotselection_options_resize_tooltip"
+msgstr "Redimensionează graficul"
+
+#: controllers/statistics_controller.php:254
+msgid "statistics_js_plotselection_selector_adu"
+msgstr "Utilizatori activi zilnic"
+
+#: controllers/statistics_controller.php:256
+msgid "statistics_js_plotselection_selector_application"
+msgstr "Aplicație"
+
+#: controllers/statistics_controller.php:259
+msgid "statistics_js_plotselection_selector_custom"
+msgstr "Personalizat"
+
+#: controllers/statistics_controller.php:253
+msgid "statistics_js_plotselection_selector_downloads"
+msgstr "Descărcări"
+
+#: controllers/statistics_controller.php:258
+msgid "statistics_js_plotselection_selector_os"
+msgstr "Sistem de operare"
+
+#: controllers/statistics_controller.php:257
+msgid "statistics_js_plotselection_selector_status"
+msgstr "Stare supliment"
+
+#: controllers/statistics_controller.php:252
+msgid "statistics_js_plotselection_selector_summary"
+msgstr "Sumar"
+
+#: controllers/statistics_controller.php:255
+msgid "statistics_js_plotselection_selector_version"
+msgstr "Versiune supliment"
+
+#: controllers/components/stats.php:398
+msgid "statistics_longnames_application"
+msgstr "Aplicație"
+
+#: controllers/components/stats.php:400
+msgid "statistics_longnames_os"
+msgstr "Sistem de operare"
+
+#: controllers/components/stats.php:399
+msgid "statistics_longnames_status"
+msgstr "Stare supliment"
+
+#: controllers/components/stats.php:401
+msgid "statistics_longnames_unknown"
+msgstr "Necunoscut"
+
+#: controllers/components/stats.php:397
+msgid "statistics_longnames_version"
+msgstr "Versiune supliment"
+
+#: views/statistics/addon.thtml:118
+msgid "statistics_notice_data_insufficient"
+msgstr ""
+"Nu sunt date suficiente pentru a afișa acest grafic. Vă rugăm să încercați "
+"mai târziu."
+
+#: views/statistics/addon.thtml:130
+msgid "statistics_notice_data_none"
+msgstr "Nu s-au adunat încă date pentru supliment. Reveniți în câteva zile."
+
+#: views/statistics/addon.thtml:41
+msgid "statistics_notice_data_updating"
+msgstr ""
+"Statisticile suplimentului sunt în curs de prelucrare. Datele recente ar "
+"putea fi incomplete datorită faptului că scripturile noastre lucrează la "
+"actualizarea acestor informații. Vă rugăm să reveniți în câteva minute."
+
+#: views/statistics/addon.thtml:136
+msgid "statistics_notice_disabled"
+msgstr ""
+"Tabloul de bord pentru statistici este dezactivat acum. Vă rugăm să încercați "
+"mai târziu."
+
+#: views/statistics/addon.thtml:123
+msgid "statistics_notice_nojavascript"
+msgstr "E nevoie de JavaScript pentru a vedea statisticile."
+
+#: views/statistics/addon.thtml:44
+msgid "statistics_notice_settings_updated"
+msgstr "Setările dumneavoastră au fost actualizate!"
+
+#: controllers/statistics_controller.php:60
+#: controllers/statistics_controller.php:71
+#: controllers/statistics_controller.php:74
+#: controllers/statistics_controller.php:240
+msgid "statistics_pagetitle"
+msgstr "Statistici - Tablou de bord"
+
+#: views/statistics/addon.thtml:99
+msgid "statistics_plot_legend_adu"
+msgstr "Utilizatori activi zilnic"
+
+#: views/statistics/addon.thtml:95
+msgid "statistics_plot_legend_downloads"
+msgstr "Descărcări zilnice"
+
+#: views/statistics/addon.thtml:107
+msgid "statistics_plot_options_zoomin_alt"
+msgstr "Mărește"
+
+#: views/statistics/addon.thtml:106
+msgid "statistics_plot_options_zoomin_title"
+msgstr "Mărește cu o lună"
+
+#: views/statistics/addon.thtml:110
+msgid "statistics_plot_options_zoomout_alt"
+msgstr "Micșorează"
+
+#: views/statistics/addon.thtml:109
+msgid "statistics_plot_options_zoomout_title"
+msgstr "Micșorează cu o lună"
+
+#: controllers/statistics_controller.php:283
+#, php-format
+msgid "statistics_rss_description"
+msgstr "Sumar zilnic al statisticilor pentru %1$s"
+
+#: views/statistics/rss/summary.thtml:68
+msgid "statistics_rss_title_fulldate"
+msgstr "%A, %e %B %Y"
+
+#: views/statistics/rss/summary.thtml:68
+#, php-format
+msgid "statistics_rss_title_statsfordate"
+msgstr "Statistici pentru %1$s"
+
+#: views/statistics/settings.thtml:49
+msgid "statistics_settings_access_description"
+msgstr ""
+"Implicit, doar dumneavoastră și Mozilla puteți accesa informațiile prezente "
+"în tabloul de bord. Puteți permite și publicului larg acest lucru pentru ca "
+"oricine să poată vedea statisticile suplimentului."
+
+#: views/statistics/settings.thtml:48
+msgid "statistics_settings_access_heading"
+msgstr "Acces la tabloul de bord"
+
+#: views/statistics/settings.thtml:51
+msgid "statistics_settings_access_private"
+msgstr "Privat"
+
+#: views/statistics/settings.thtml:51
+msgid "statistics_settings_access_private_description"
+msgstr "Numai dumneavoastră și Mozilla puteți vedea statisticile suplimentului"
+
+#: views/statistics/settings.thtml:52
+msgid "statistics_settings_access_public"
+msgstr "Public"
+
+#: views/statistics/settings.thtml:52
+msgid "statistics_settings_access_public_description"
+msgstr "Oricine poate vedea statisticile acestui supliment"
+
+#: views/statistics/addon.thtml:251
+msgid "statistics_settings_change_link"
+msgstr "Schimbă setările"
+
+#: views/statistics/addon.thtml:253
+msgid "statistics_settings_confidential"
+msgstr "Vă rugăm să tratați această informație ca fiind confidențială."
+
+#: views/statistics/addon.thtml:245
+msgid "statistics_settings_currently_private"
+msgstr "Acest tablou de bord este acum <b>privat</b>."
+
+#: views/statistics/addon.thtml:241
+msgid "statistics_settings_currently_public"
+msgstr "Acest tablou de bord este acum <b>public</b>."
+
+#: views/statistics/addon.thtml:246
+msgid "statistics_settings_locked_alt"
+msgstr "Blocat"
+
+#: views/statistics/settings.thtml:57
+msgid "statistics_settings_return_link"
+msgstr "ÃŽnapoi la tabloul de bord"
+
+#: views/statistics/settings.thtml:56
+msgid "statistics_settings_save_button"
+msgstr "Salvează setările"
+
+#: views/statistics/settings.thtml:46
+#, php-format
+msgid "statistics_settings_title"
+msgstr "Statistici - Setările tabloului de bord pentru %1$s"
+
+#: views/statistics/addon.thtml:242
+msgid "statistics_settings_unlocked_alt"
+msgstr "Deblocat"
+
+#: controllers/components/stats.php:405
+msgid "statistics_shortnames_application"
+msgstr "Ap"
+
+#: controllers/components/stats.php:407
+msgid "statistics_shortnames_os"
+msgstr "SO"
+
+#: controllers/components/stats.php:406
+msgid "statistics_shortnames_status"
+msgstr "St"
+
+#: controllers/components/stats.php:408
+msgid "statistics_shortnames_unknown"
+msgstr "Nec"
+
+#: controllers/components/stats.php:404
+msgid "statistics_shortnames_version"
+msgstr "Ver"
+
+#: views/statistics/rss/summary.thtml:42 views/statistics/addon.thtml:192
+msgid "statistics_summary_downloads_average"
+msgstr "Descărcări în medie pe zi"
+
+#: views/statistics/rss/summary.thtml:39
+msgid "statistics_summary_downloads_heading"
+msgstr "Descărcări"
+
+#: views/statistics/rss/summary.thtml:41 views/statistics/addon.thtml:171
+msgid "statistics_summary_downloads_lastcount"
+msgstr "Numărătoarea din ultima zi"
+
+#: views/statistics/rss/summary.thtml:43 views/statistics/addon.thtml:199
+msgid "statistics_summary_downloads_lastweek"
+msgstr "Descărcări în ultimele 7 zile"
+
+#: views/statistics/rss/summary.thtml:40 views/statistics/addon.thtml:151
+msgid "statistics_summary_downloads_total"
+msgstr "Descărcări în total"
+
+#: views/statistics/rss/summary.thtml:40 views/statistics/addon.thtml:152
+#, php-format
+msgid "statistics_summary_downloads_total_sincedate"
+msgstr "Din %1$s"
+
+#: views/statistics/rss/summary.thtml:50 views/statistics/rss/summary.thtml:56
+#: views/statistics/addon.thtml:163 views/statistics/addon.thtml:183
+msgid "statistics_summary_nodata"
+msgstr "Încă nu sunt date"
+
+#: views/statistics/rss/summary.thtml:60 views/statistics/addon.thtml:195
+msgid "statistics_summary_updatepings_average"
+msgstr "Media utilizatorilor activi zilnic"
+
+#: views/statistics/rss/summary.thtml:52 views/statistics/addon.thtml:177
+msgid "statistics_summary_updatepings_changefromprevious"
+msgstr "Schimbare de la numărătoarea precedentă"
+
+#: views/statistics/rss/summary.thtml:54 views/statistics/addon.thtml:181
+#, php-format
+msgid "statistics_summary_updatepings_changefromprevious_ondate"
+msgstr "%1$s în %2$s"
+
+#: views/statistics/rss/summary.thtml:45
+msgid "statistics_summary_updatepings_heading"
+msgstr "Utilizatori activi zilnic"
+
+#: views/statistics/rss/summary.thtml:46 views/statistics/addon.thtml:157
+msgid "statistics_summary_updatepings_total"
+msgstr "Utilizatori activi zilnic"
+
+#: views/statistics/rss/summary.thtml:48 views/statistics/addon.thtml:161
+#, php-format
+msgid "statistics_summary_updatepings_total_ondate"
+msgstr "ÃŽn %1$s"
+
+#: views/statistics/rss/summary.thtml:61 views/statistics/addon.thtml:203
+msgid "statistics_summary_updatepings_weekly_average"
+msgstr ""
+
+#. %s is a percentage, like '+22.33%'. It sits next to another number, so
+#. the implied meaning is 'percentage change' from the previous stat point.
+#: views/statistics/rss/summary.thtml:62 views/statistics/addon.thtml:205
+msgid "statistics_summary_updatepings_weekly_change"
+msgstr ""
+
+#: views/statistics/addon.thtml:65 controllers/statistics_controller.php:184
+#: controllers/statistics_controller.php:282
+#, php-format
+msgid "statistics_title_addon_stats"
+msgstr "Statistici pentru %1$s"
+
+#: views/addons/themes_landing.thtml:113
+msgid "themes_landing_all_themes"
+msgstr "Toate temele"
+
+#: views/addons/themes_landing.thtml:109
+msgid "themes_landing_browse_themes"
+msgstr "Răsfoiți temele"
+
+#: views/users/edit.thtml:185
+msgid "user_change_email"
+msgstr "Schimbă adresa de email"
+
+#: views/users/edit.thtml:169
+msgid "user_change_password"
+msgstr "Schimbare parolă"
+
+#: views/users/edit.thtml:96
+msgid "user_change_password_or_email"
+msgstr ""
+
+#: controllers/users_controller.php:197
+msgid "user_confirmationcode_resent"
+msgstr "Codul de confirmare a fost trimis din nou!"
+
+#. %1 is the email address, %2 is the URL of the user registration page
+#: views/users/delete.thtml:51
+msgid "user_del_account_deleted"
+msgstr ""
+"Contul dumneavoastră de utilizator %1$s a fost șters cu succes. Dacă doriți "
+"să reveniți ulterior, vizitați <a href=\"%2$s\">pagina de înregistrare</a>."
+
+#: views/users/delete.thtml:102
+msgid "user_del_community_sad"
+msgstr "Comunitatea Suplimente Mozilla e tristă că vă vede plecând."
+
+#: views/users/delete.thtml:123
+msgid "user_del_confirm_password"
+msgstr "Confirmați parola"
+
+#: views/users/delete.thtml:134
+msgid "user_del_deletenow"
+msgstr "Șterge contul meu acum"
+
+#. %1 is the URL of the user's info page
+#: views/users/delete.thtml:64
+msgid "user_del_error_addons"
+msgstr ""
+"Nu puteți să vă ștergeți contul de utilizator dacă sunteți afișat ca <a href="
+"\"%1$s\">autor al vreunui supliment</a>. Pentru a vă șterge contul, vă rugăm "
+"să desemnați o altă persoană din grupul dumneavoastră de dezvoltatori să vă "
+"înlăture din lista de autori a suplimentelor dumneavoastră, după care veți "
+"putea să vă ștergeți contul."
+
+#. %1 is a link to the amo-editors mailing list
+#: views/users/delete.thtml:71
+msgid "user_del_error_addons_more_questions"
+msgstr ""
+"Dacă aveți și alte întrebări, vă rugăm să contactați %1$s pentru asistență."
+
+#: views/users/delete.thtml:78
+msgid "user_del_error_checkbox"
+msgstr "Trebuie să bifați căsuța „Înțeleg că...†înainte de a vă șterge contul."
+
+#: views/users/delete.thtml:84
+msgid "user_del_error_password"
+msgstr "Vă rugăm să introduceți parola corect pentru a trece peste acest pas."
+
+#. %1 is a link to the amo-admins mailing list
+#: views/users/delete.thtml:91
+msgid "user_del_error_unknown"
+msgstr ""
+"A intervenit o eroare necunoscută în timpul ștergerii contului. Vă rugăm să "
+"contactați %1$s în legătură cu această problemă și vă vom șterge noi contul. "
+"Ne cerem scuze pentru dificultățile create."
+
+#: views/users/delete.thtml:110
+msgid "user_del_header_confirm_deletion"
+msgstr "Confirmați ștergerea contului"
+
+#. %1 is the user's email address
+#: views/users/delete.thtml:100
+msgid "user_del_header_delete_account"
+msgstr "Ștergere cont de utilizator %1$s"
+
+#: views/users/delete.thtml:50
+msgid "user_del_header_farewell"
+msgstr "La revedere!"
+
+#: views/users/delete.thtml:115
+msgid "user_del_nologin"
+msgstr "De acum nu vă veți mai putea autentifica în Mozilla Add-ons."
+
+#: views/users/delete.thtml:112
+msgid "user_del_permanently_removed_means"
+msgstr ""
+"Prin clic pe „ștergereâ€, contul dumneavoastră va fi <strong>È™ters permanent</"
+"strong>. Asta înseamnă că:"
+
+#: views/users/delete.thtml:116
+msgid "user_del_reviews_anonymized"
+msgstr ""
+"Recenziile și evaluările nu vor fi șterse, dar nu vor mai fi asociate cu "
+"dumneavoastră."
+
+#. %1 is a link to the amo-editors mailing list
+#: views/users/delete.thtml:104
+msgid "user_del_specific_problem_editors"
+msgstr ""
+"Dacă aveți o problemă cu care vă putem ajuta, vă rugăm să nu vă ștergeți "
+"contul acum. Contactați-ne la %1$s și vom face tot posibilul să vă sprijinim "
+"în rezolvarea problemei."
+
+#: views/users/delete.thtml:130
+msgid "user_del_understand_permanent"
+msgstr "Înțeleg că acest pas nu are cale de întoarcere."
+
+#: views/helpers/addons_html.php:192
+msgid "user_deleted_nickname"
+msgstr "Utilizator șters"
+
+#. %1 is the new email address
+#: views/users/edit.thtml:71
+msgid "user_edit_confirm_email_sent"
+msgstr ""
+"S-a trimis un email la %1$s, pentru a confirma noua dumneavoastră adresă de "
+"email. Pentru ca modificarea să aibă efect, trebuie să urmați legătura "
+"furnizată în email. Până atunci, puteți să vă autentificați cu adresa de "
+"email curentă."
+
+#: views/users/edit.thtml:201
+msgid "user_edit_delete_user"
+msgstr "Șterge contul de utilizator"
+
+#. This contains the email sent to users when they signed up for a new
+#. account:
+#. %1 is the confirmation URL, %2 is the current app
+#: views/users/email/confirm_plain.thtml:6
+#, php-format
+msgid "user_email_confirm_account_nopass"
+msgstr ""
+"Bun venit pe Suplimente %2$s.\n"
+"\n"
+"Înainte de a putea folosi noul dumneavoastră cont, trebuie să-l activați - "
+"acest lucru certifică faptul că adresa dumneavoastră de email este validă și "
+"vă aparține.\n"
+"Pentru a vă activa contul, clicați legătura de mai jos sau copiați și lipiți "
+"întreaga chestie în bara de adrese a navigatorului dumneavoastră:\n"
+"\n"
+"%1$s\n"
+"\n"
+"Odată ce ați activat cu succes contul dumneavoastră, puteți arunca acest "
+"mesaj.\n"
+"\n"
+"Vă mulțumim pentru înscrierea pe Suplimente %2$s\n"
+"-- Echipa Suplimente %2$s"
+
+#. %1 is the confirmation url, %2 is the application name
+#: views/users/email/emailchange_plain.thtml:5
+msgid "user_email_confirm_emailchange"
+msgstr ""
+"AÈ›i făcut o cerere de schimbare a adresei de email pentru „Suplimente %2$sâ€.\n"
+"\n"
+"Pentru a confirma noua adresă, vă rugăm să urmați legătura de mai jos cu un "
+"clic sau să o copiați și să o lipiți în bara de adrese a programului de "
+"navigare pe internet:\n"
+"\n"
+"%1$s\n"
+"\n"
+"Aveți 48 de ore pentru a confirma noua adresă. Dacă nu mai doriți să vă "
+"schimbați adresa, puteți pur și simplu să ignorați acest mesaj.\n"
+"\n"
+"Vă mulțumim!\n"
+"-- Echipa „Suplimente %2$sâ€"
+
+#: controllers/users_controller.php:168
+#, php-format
+msgid "user_email_confirm_subject"
+msgstr "Vă mulțumim pentru înscrierea pe Suplimente %s"
+
+#. This is the password reset email
+#. %1 is the pw reset URL, %2 is the application
+#: views/users/email/pwreset_plain.thtml:5
+#, php-format
+msgid "user_email_pwreset"
+msgstr ""
+"Suplimente %2$s - Resetare parolă\n"
+"\n"
+"Am primit o cerere de resetare a parolei pentru acest cont de pe addons."
+"mozilla.org. Pentru a schimba parola, vă rugăm clicați pe următoarea "
+"legătură, sau lipiți-o în bara de adrese a navigatorului dumneavoastră:\n"
+"\n"
+"%1$s\n"
+"\n"
+"Dacă nu ați făcut o astfel de cerere nu este nevoie să faceți nimic.\n"
+"\n"
+"Vă mulțumim,\n"
+"-- Echipa Suplimente %2$s"
+
+#: controllers/users_controller.php:245
+#, php-format
+msgid "user_email_pwreset_subject"
+msgstr "Resetați-vă parola dumneavoastră pe Suplimente %s"
+
+#: views/users/emailchange.thtml:50
+msgid "user_emailchange_error"
+msgstr "Eroare!"
+
+#. %1 is the application name
+#: controllers/users_controller.php:533
+msgid "user_emailchange_subject"
+msgstr ""
+"Vă rugăm să confirmaÈ›i schimbarea adresei de email pentru „Suplimente %1$sâ€"
+
+#: views/users/emailchange.thtml:48
+msgid "user_emailchange_success"
+msgstr "Succes!"
+
+#. %1 is the new email address
+#: views/users/emailchange.thtml:49
+msgid "user_emailchange_successful_description"
+msgstr ""
+"Adresa dumneavoastră de email a fost schimbată cu succes. De acum înainte, vă "
+"rugăm să folosiți %1$s pentru a vă autentifica."
+
+#: views/users/edit.thtml:134 views/admin/users_edit.thtml:111
+msgid "user_form_bio"
+msgstr ""
+
+#: views/users/edit.thtml:135 views/admin/users_edit.thtml:112
+msgid "user_form_bio_description"
+msgstr ""
+
+#: views/users/pwreset.thtml:77 views/users/register.thtml:73
+#: views/users/edit.thtml:181
+msgid "user_form_confirmpassword"
+msgstr "Confirmare parolă"
+
+#: views/users/edit.thtml:145
+msgid "user_form_display_collections"
+msgstr ""
+
+#: views/users/edit.thtml:149
+msgid "user_form_display_collections_fav"
+msgstr ""
+
+#: views/users/edit.thtml:86
+#, php-format
+msgid "user_form_editprofile"
+msgstr "Editare profil utilizator pentru %s"
+
+#: views/users/pwreset.thtml:52 views/users/login.thtml:81
+#: views/users/register.thtml:63 views/users/edit.thtml:187
+msgid "user_form_email"
+msgstr "Adresă email"
+
+#: views/users/register.thtml:78 views/users/edit.thtml:103
+#: views/admin/users_edit.thtml:76
+msgid "user_form_firstname"
+msgstr "Prenume"
+
+#: views/users/register.thtml:94 views/users/edit.thtml:119
+#: views/admin/users_edit.thtml:91
+msgid "user_form_hideemail"
+msgstr "Ascunde adresa de email"
+
+#: views/users/register.thtml:98 views/users/edit.thtml:123
+#: views/admin/users_edit.thtml:99
+msgid "user_form_homepage"
+msgstr "URL sait web"
+
+#: views/users/register.thtml:84 views/users/edit.thtml:109
+#: views/admin/users_edit.thtml:81
+msgid "user_form_lastname"
+msgstr "Nume"
+
+#: controllers/users_controller.php:333
+msgid "user_form_login"
+msgstr "Autentificare utilizator"
+
+#: views/users/pwreset.thtml:72 views/users/edit.thtml:176
+msgid "user_form_newpassword"
+msgstr "Parolă nouă"
+
+#: views/users/register.thtml:89 views/users/edit.thtml:114
+#: views/admin/users_edit.thtml:86
+msgid "user_form_nickname"
+msgstr "Pseudonim"
+
+#: views/users/edit.thtml:171
+msgid "user_form_oldpassword"
+msgstr "Parolă veche"
+
+#: views/users/edit.thtml:97 views/users/edit.thtml:200
+msgid "user_form_otheractions"
+msgstr "Alte acțiuni"
+
+#: views/users/login.thtml:85 views/users/register.thtml:68
+msgid "user_form_password"
+msgstr "Parolă"
+
+#: controllers/users_controller.php:93
+msgid "user_form_registration"
+msgstr "ÃŽnregistrare utilizator nou"
+
+#: views/users/login.thtml:90
+msgid "user_form_remember_me"
+msgstr "Ține-mă minte pe acest calculator"
+
+#: views/admin/users_edit.thtml:95
+msgid "user_form_showsandbox"
+msgstr "Arată cutia cu nisip?"
+
+#: views/users/edit.thtml:205
+msgid "user_form_submit_edit"
+msgstr "Salvează"
+
+#: views/users/login.thtml:93
+msgid "user_form_submit_login"
+msgstr "Autentificare"
+
+#: views/users/register.thtml:113
+msgid "user_form_submit_register"
+msgstr "ÃŽnregistrare"
+
+#: views/users/info.thtml:75
+#, php-format
+msgid "user_info_usersince"
+msgstr "Utilizator Suplimente %s din"
+
+#: views/users/login.thtml:102
+msgid "user_login_register_link"
+msgstr "Creează un nou cont de utilizator"
+
+#: views/users/edit.thtml:160
+msgid "user_notifications_item_compat"
+msgstr "Compatibilitate supliment (recomandat cu tărie)"
+
+#: views/users/edit.thtml:161
+msgid "user_notifications_item_events"
+msgstr "Evenimente viitoare și concursuri"
+
+#: views/users/edit.thtml:156
+msgid "user_notifications_none_available"
+msgstr "Actualmente nu sunt notificări disponibile pentru a fi configurate."
+
+#: views/users/edit.thtml:158
+msgid "user_notifications_select_topics"
+msgstr ""
+"Din când în când, Mozilla vă poate trimite câte un email despre ediții noi și "
+"evenimente legate de suplimente. Vă rugăm să selectați subiectele de care "
+"sunteți interesat mai jos:"
+
+#: views/users/edit.thtml:164
+msgid "user_notifications_specific_contact"
+msgstr ""
+"Mozilla își rezervă dreptul de a vă contacta individual despre probleme "
+"specifice legate de suplimentele găzduite de dumneavoastră."
+
+#: controllers/users_controller.php:543
+msgid "user_profile_edit_error"
+msgstr ""
+"Sunt erori în schimbările pe care le-ați făcut. Vă rugăm corectați-le și "
+"trimiteți din nou. "
+
+#: controllers/users_controller.php:540
+msgid "user_profile_saved"
+msgstr "Profil actualizat."
+
+#: views/users/pwreset.thtml:65
+#, php-format
+msgid "user_pwreset_for_email"
+msgstr "Resetare parolă pentru %s"
+
+#: controllers/users_controller.php:226
+msgid "user_pwreset_header"
+msgstr "Resetare parolă"
+
+#: views/users/login.thtml:103
+msgid "user_pwreset_link"
+msgstr "Ați uitat parola?"
+
+#: controllers/users_controller.php:248
+msgid "user_pwreset_link_sent"
+msgstr ""
+"Legătura de resetare a parolei a fost trimisă pe adresa dumneavoastră de "
+"email."
+
+#: controllers/users_controller.php:304
+msgid "user_pwreset_okay"
+msgstr "Parolă resetată cu succes."
+
+#: views/users/pwreset.thtml:82
+msgid "user_pwreset_submit_changepw"
+msgstr "Trimite schimbarea de parolă"
+
+#: views/users/pwreset.thtml:57
+msgid "user_pwreset_submit_sendlink"
+msgstr "Trimite legătura de resetare a parolei"
+
+#: views/users/register_complete.thtml:51
+#, php-format
+msgid "user_register_amo_link"
+msgstr "Suplimente %s"
+
+#. %1 is the user's email address, %2 is the current app
+#: views/users/activatefirst.thtml:49
+#, php-format
+msgid "user_register_click_confirm_link"
+msgstr ""
+"O legătură pentru a activa contul dumneavoastră a fost trimisă pe adresa "
+"dumneavoastră de e-mail %1$s. Trebuie să o urmați înainte de a vă autentifica "
+"în Suplimente %2$s."
+
+#. %1 is the user's email address
+#: views/users/register_complete.thtml:49
+#, php-format
+msgid "user_register_confirm_email_sent"
+msgstr ""
+"Un email a fost trimis pe adresa %1$s pentru a confirma contul dumneavoastră. "
+"Înainte să vă puteți autentifica, trebuie să confirmați contul dumneavoastră "
+"clicând pe legătura din acest email."
+
+#: views/users/activatefirst.thtml:51
+msgid "user_register_confirmation_link_text"
+msgstr "retrimite mesajul de confirmare"
+
+#: views/users/register_complete.thtml:47
+msgid "user_register_congratulations"
+msgstr "Felicitări! Contul dumneavoastră a fost creat cu succes."
+
+#: views/users/register.thtml:50
+msgid "user_register_details"
+msgstr ""
+
+#. %1 is the link to the "resend confirmation code" page
+#: views/users/activatefirst.thtml:51
+#, php-format
+msgid "user_register_resend_confirmation_link"
+msgstr ""
+"Dacă nu ați primit un email de confirmare, asigurați-vă că serviciul "
+"dumneavoastră de e-mail nu a marcat mesajul ca „junkâ€, „bulkâ€, „spam†sau "
+"„corespondență nesolicitatăâ€. Dacă aveÈ›i nevoie, vă putem %1$s pe adresa de "
+"email menționată mai sus."
+
+#. %1 is the link to the Mozilla Add-ons front page
+#: views/users/register_complete.thtml:51
+#, php-format
+msgid "user_register_welcome"
+msgstr "Vă mulțumim pentru înregistrare și vă urăm bun venit în %1$s!"
+
+#: views/users/register.thtml:49
+msgid "user_register_welcome_header"
+msgstr ""
+
+#: views/users/register.thtml:81 views/users/edit.thtml:106
+msgid "user_required_firstlast_or_nickname"
+msgstr "E necesar un prenume, nume sau un pseudonim."
+
+#: views/users/edit.thtml:94 views/users/edit.thtml:142
+msgid "user_tab_collections"
+msgstr "Colecții"
+
+#: views/users/edit.thtml:95 views/users/edit.thtml:154
+msgid "user_tab_notifications"
+msgstr "Notificări"
+
+#: views/users/edit.thtml:93 views/users/edit.thtml:101
+msgid "user_tab_profile"
+msgstr "Profil autor"
+
+#: controllers/users_controller.php:209
+msgid "user_verified_okay"
+msgstr "Verificat cu succes!"
+
+#: controllers/users_controller.php:723
+msgid "users_delete_pagetitle"
+msgstr "Ștergere cont de utilizator"
+
+#: controllers/users_controller.php:414
+msgid "users_edit_pagetitle"
+msgstr "Editare cont utilizator"
+
+#: views/users/info.thtml:71
+msgid "users_info_aboutme"
+msgstr "Despre mine"
+
+#: views/users/info.thtml:96
+#, php-format
+msgid "users_info_addons_by_user"
+msgstr "Suplimente create de %1$s"
+
+#: views/users/info.thtml:51
+msgid "users_info_author_name"
+msgstr "Nume"
+
+#: views/users/info.thtml:48
+msgid "users_info_author_profile"
+msgstr "Profil autor"
+
+#. %s is the user name
+#: views/users/info.thtml:137
+msgid "users_info_collections_by_user"
+msgstr ""
+
+#: views/users/info.thtml:66
+msgid "users_info_email"
+msgstr "Adresă email"
+
+#: views/users/info.thtml:155
+msgid "users_info_fav_collections_by_user"
+msgstr ""
+
+#: views/users/info.thtml:61
+msgid "users_info_homepage"
+msgstr "Pagina personală"
+
+#: views/users/info.thtml:56
+msgid "users_info_nickname"
+msgstr "Pseudonim"
+
+#: controllers/users_controller.php:707
+#, php-format
+msgid "users_info_pagetitle"
+msgstr "Info utilizator pentru %1$s"
+
+#. %1 is the user's name
+#: views/users/info.thtml:116
+msgid "users_info_reviews_by_user"
+msgstr "Recenzii făcute de %s"
+
+#: controllers/users_controller.php:330 controllers/users_controller.php:332
+msgid "users_login_pagetitle"
+msgstr "Autentificare utilizator"
+
+#. %1 is the link to the sandbox/policy explanation page
+#. This message is for a specific add-on not found
+#: views/users/login.thtml:53
+#, php-format
+msgid "users_login_sandbox_display_warning"
+msgstr ""
+"Suplimentul la care vă uitați se află actualmente în cutia cu nisip. Dacă "
+"aveți deja un cont pe Suplimente Mozilla, vă rugăm autentificați-vă, sau "
+"<a·href=\"%1$s\">aflați mai multe despre cutia cu nisip.</a>"
+
+#. %1 is the link to the sandbox/policy explanation page
+#. This message is for any given sandbox-related page not found
+#: views/users/login.thtml:56
+#, php-format
+msgid "users_login_sandbox_page_warning"
+msgstr ""
+"Pagina la care vă uitați este parte a cutiei cu nisip. Dacă aveți deja un "
+"cont pe Suplimente Mozilla, vă rugăm autentificați-vă sau <a·href=\"%1$s"
+"\">aflați mai multe despre cutia cu nisip.</a>"
+
+#: controllers/users_controller.php:223 controllers/users_controller.php:225
+msgid "users_pwreset_pagetitle"
+msgstr "Resetare parolă utilizator"
+
+#: controllers/users_controller.php:90 controllers/users_controller.php:92
+msgid "users_register_pagetitle"
+msgstr "ÃŽnregistrare utilizator nou"
+
+#. %1$s is an addon name, like <a>Firebug</a>
+#. %2$s is a version number, like <a>1.2</a>
+#: views/versions/license.thtml:52
+msgid "versions_license_header_source"
+msgstr ""
+
+#: views/addons/category_landing.thtml:147
+msgid "view_recently_added"
+msgstr "Vezi toate cele adăugate recent"
+
+#: views/addons/category_landing.thtml:161
+msgid "view_top_downloads"
+msgstr "Vezi cele mai descărcate"
+
+#: views/addons/category_landing.thtml:175
+msgid "view_top_rated"
+msgstr "Vezi cele mai apreciate"
diff --git a/site/app/locale/ro/images/sandbox-review.png b/site/app/locale/ro/images/sandbox-review.png
new file mode 100644
index 0000000..6a6834b
--- /dev/null
+++ b/site/app/locale/ro/images/sandbox-review.png
Binary files differ
diff --git a/site/app/locale/ro/pages/error404.thtml b/site/app/locale/ro/pages/error404.thtml
new file mode 100644
index 0000000..f30e8e6
--- /dev/null
+++ b/site/app/locale/ro/pages/error404.thtml
@@ -0,0 +1,16 @@
+<h1>Ne pare rău, dar nu putem găsi ceea ce căutaţi.</h1>
+
+<p>Pagina sau fişierul cerut nu a fost găsit pe saitul nostru. E posibil să fi clicat pe o legătură veche sau să fi tastat o adresă incorectă.</p>
+
+<ul>
+<li>Dacă aţi introdus o adresă, vă rugăm verificaţi corectitudinea ei.</li>
+<li>Dacă aţi urmat o legătură de undeva, vă rugăm spuneţi-ne la <a href="mailto:webmaster@mozilla.com" title="Page Not Found on Mozilla.com">webmaster@mozilla.com</a>. Spuneţi-ne de unde aţi venit şi ce căutaţi, iar noi vom face tot posibilul să remediem problema.</li>
+</ul>
+
+<p>Sau puteţi sări peste acest incident şi să vă uitaţi peste cele mai populare pagini ale saitului nostru.</p>
+
+<ul>
+<li>Sunteţi interesat(ă) de o <a href="%1$s">listă a celor mai populare suplimente</a>?</li>
+<li>Doriţi să <a href="%2$s">căutaţi suplimente</a>? Puteţi merge la <a href="%2$s">pagina de căutare</a> sau puteţi folosi câmpul de căutare de mai jos.</li>
+<li>Dacă preferaţi să o luaţi de la început, mergeţi la <a href="%3$s">prima pagină a suplimentelor</a>.</li>
+</ul>
diff --git a/site/app/locale/ro/pages/nomination.thtml b/site/app/locale/ro/pages/nomination.thtml
new file mode 100644
index 0000000..0623ef9
--- /dev/null
+++ b/site/app/locale/ro/pages/nomination.thtml
@@ -0,0 +1,8 @@
+<p>Un supliment aflat în cutia cu nisip poate fi nominalizat să fie parte a saitului public şi disponibil tuturor utilizatorilor după revizuirea de către un editor. Pentru cele mai bune rezultate, vă rugăm notaţi următoarele:</p>
+<ul>
+ <li>Imaginile de avanpremieră sunt necesare pentru teme şi recomandate cu tărie pentru toate celelalte tipuri de suplimente</li>
+ <li>Suplimentul ar trebui să fi petrecut suficient timp în cutia de nisip pentru a acumula recenzii şi păreri de la utilizatori</li>
+ <li>Suplimentele publice au o calitate mai mare decât cele din cutia cu nisip şi ar trebui să îmbunătăţească web-ul</li>
+ <li>Criteriile pentru nominalizare sunt disponibile în <a href="%s">Politica suplimentelor</a></li>
+</ul>
+<p>Dacă suplimentul dumneavoastră îndeplineşte criteriile de mai sus, puteţi să-l nominalizaţi clicând butonul de mai jos. Veţi fi anunţat prin email despre starea nominalizării.</p>
diff --git a/site/app/locale/ro/pages/sandbox.thtml b/site/app/locale/ro/pages/sandbox.thtml
new file mode 100644
index 0000000..d8d3e2f
--- /dev/null
+++ b/site/app/locale/ro/pages/sandbox.thtml
@@ -0,0 +1,13 @@
+<h1>Sistemul de revizuire prin cutia cu nisip</h1>
+<h2>Ce este cutia cu nisip?</h2>
+<p>Cutia cu nisip este o zonă pentru utilizatorii avansaţi în care pot testa suplimentele înainte de a fi revizuite pentru uz general. Pentru a accesa cutia cu nisip, trebuie să o activaţi în setările contului dumneavoastră. Precauţia ar trebui folosită când instalaţi suplimente din cutia cu nisip, deoarece ele nu au fost testate de un editor şi ar putea face rău calculatorului dumneavoastră.</p>
+
+<h2>Cum îmi pun suplimentul pe saitul public?</h2>
+<!-- To localize the flowchart image, see http://wiki.mozilla.org/Update:Remora_Sandbox_Flowchart -->
+<div style="text-align: center;">%s</div>
+<ol>
+ <li><b>Trimiteţi suplimentul dumneavoastră din panoul de control al dezvoltatorului.</b> El va apărea imediat în partea „cutiei cu nisip†a Suplimentelor Mozilla, unde utilizatori experimentaţi o vor testa şi vă vor spune părerile lor. Pentru a vedea cutia cu nisip, va trebui să o activaţi în setările contului dumneavoastră.</li>
+ <li><b>Nominalizaţi suplimentul dumneavoastră pentru a deveni public.</b> În panoul de control al dezvoltatorului veţi găsi o legătură pentru a nominaliza suplimentul dumneavoastră. După ce este nominalizat, suplimentul va fi pus la coadă pentru revizuire de către un editor.</li>
+ <li><b>Un editor revizuieşte suplimentul dumneavoastră.</b> Un editor Suplimente Mozilla va instala suplimentul şi îi va testa funcţionalitatea. Editorul se va uita de asemenea şi peste recenziile scrise de utilizatorii cutiei cu nisip care au testat suplimentul.</li>
+ <li><b>Suplimentul va fi făcut public sau reţinut în cutia cu nisip.</b> Editorul va face suplimentul public sau îl va reţine în cutia cu nisip. Dacă este reţinut în cutia cu nisip, îl puteţi nominaliza din nou după ce faceţi schimbările pe care editorul le sugerează în comentarii. Dacă e făcut public, viitoarele versiuni ale suplimentului vor apărea în cutia cu nisip până când vor fi revizuite de un editor şi făcute publice. Odată ce suplimentul este public, nu mai e nevoie să îl nominalizaţi din nou - versiunile viitoare vor merge automat în coada pentru revizuire.</li>
+</ol> \ No newline at end of file
diff --git a/site/app/locale/ro/pages/submission_help.thtml b/site/app/locale/ro/pages/submission_help.thtml
new file mode 100644
index 0000000..4ee8623
--- /dev/null
+++ b/site/app/locale/ro/pages/submission_help.thtml
@@ -0,0 +1,35 @@
+<h1>Ajutor pentru trimiterea suplimentelor</h1>
+Câmpurile necesare sunt <b>îngroşate</b>. Câmpurile opţionale au numele scris <i>înclinat</i>.
+<h2 id="step1">Pasul 1: Încărcare</h2>
+<ul class="submissionHelp">
+ <li><span class="required">Tip supliment</span> - Implicit, tipul suplimentului va fi determinat automat pe baza fişierului încărcat. Nu ar trebui să schimbaţi acest câmp.</li>
+ <li><span class="required">Fişier supliment</span> - Pachetul de fişiere care conţine suplimentul, completat cu un fişier install.rdf. Dacă fişierul merge numai cu o platformă, selectarea platformei vă va oferi posibilitatea să încărcaţi mai multe fişiere deodată.</li>
+ <li><span class="optional">Fişier iconiţă</span> - Fişierul care conţine iconiţa este afişat lângă numele suplimentului pe pagina sa şi este afişat în dialogul de instalare. Va fi redimensionat automat la 32x32 pixeli, cu păstrarea aspectului.</li>
+ <li><span class="required">Limba implicită</span> - Limba implicită a suplimentului este limba sa principală. Dacă traducerea în limba selectată de un utilizator nu este disponibilă pentru supliment, va fi afişat textul în limba implicită.</li>
+ <li><span class="optional">Sări peste recenzierea informaţiilor suplimentului</span> - Acest câmp va fi vizibil doar dacă actualizaţi un supliment. Bifând această opţiune veţi sări peste pasul 3 unde puteţi introduce informaţii specifice versiunii.</li>
+</ul>
+
+<h2 id="step2">Pasul 2: Detalii supliment</h2>
+<ul class="submissionHelp">
+ <li><span class="required">Nume</span> - Numele suplimentului în limba implicită.</li>
+ <li><span class="required">Autori</span> - Toţi utilizatorii care au acces la modificarea datelor suplimentului şi care vor fi enumeraţi în pagina suplimentului.</li>
+ <li><span class="required">Categorii</span> - Categorii aplicabile suplimentului.</li>
+ <li><span class="optional">Pagina de start</span> - Saitul suplimentului pentru limba implicită.</li>
+ <li><span class="required">Descriere sumară</span> - O scurtă descriere a suplimentului în limba implicită. Maxim 250 caractere.</li>
+ <li><span class="required">Descriere</span> - O descriere a suplimentului în limba implicită.</li>
+ <li><span class="optional">EULA</span> - Acordul de licenţă cu utilizatorul, în limba implicită, care va trebui acceptat de utilizatori înainte de a descărca.</li>
+ <li><span class="optional">Politică de confidenţialitate</span> - Politica de confidenţialitate a suplimentului, în limba implicită.</li>
+ <li><span class="optional">Permite utilizatorilor să vadă sursa fişierelor</span> - Dacă bifaţi această opţiune, utilizatorilor li se va permite să răsfoiască fişierele sursă ale suplimentului dumneavoastră.</li>
+ <li><span class="optional">Aceasta este o ediÅ£ie preliminară</span> - Bifând această opÅ£iune veÅ£i indica că suplimentul este o ediÅ£ie preliminară sau o versiune „betaâ€.</li>
+ <li><span class="optional">Acesta este un supliment pentru un sait anume</span> - Bifând această opţiune veţi indica că suplimentul este specific unui singur sait.</li>
+ <li><span class="optional">Acest supliment necesită alte programe</span> - Bifând această opţiune veţi indica că suplimentul are nevoie de alt program pentru a funcţiona în aplicaţia pentru care este făcut.</li>
+</ul>
+
+<h2 id="step3">Pasul 3: Detalii versiune</h2>
+<ul class="submissionHelp">
+ <li><span class="required optional">Note versiune</span> - Un sumar sau o listă de schimbări în această versiune. Acesta este opţional pentru trimiterile noi, dar obligatoriu pentru actualizări.</li>
+ <li><span class="optional">Note către recenzent</span> - Acest câmp este folosit pentru comunicarea de informaţii către editorii care vor recenzia suplimentul dumneavoastră. Informaţii despre cont de test şi note speciale ar trebui să fie lăsate aici.</li>
+</ul>
+
+<h2 id="step4">Pasul 4: Localizare</h2>
+Aici e locul unde câmpurile suplimentului pot fi localizate în toate limbile suportate. Trebuie doar să apăsaţi pe simbolul unei limbi pentru a introduce traducerile.
diff --git a/site/app/locale/ru/LC_MESSAGES/messages.mo b/site/app/locale/ru/LC_MESSAGES/messages.mo
new file mode 100644
index 0000000..4afe5cb
--- /dev/null
+++ b/site/app/locale/ru/LC_MESSAGES/messages.mo
Binary files differ
diff --git a/site/app/locale/ru/LC_MESSAGES/messages.po b/site/app/locale/ru/LC_MESSAGES/messages.po
new file mode 100644
index 0000000..f8fd533
--- /dev/null
+++ b/site/app/locale/ru/LC_MESSAGES/messages.po
@@ -0,0 +1,8139 @@
+# translation of messages.po to Russian
+# Remora Preliminary Language File
+# Copyright (C) 2006 Mozilla Corporation
+# This file is distributed under the same license as the REMORA package.
+# Wil Clouser <clouserw@mozilla.com>, 2006.
+# Merlyel <merlyell@gmail.com>, 2007.
+# Alexander Slovesnik <unghost@mozilla-russia.org>, 2008-2009.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: REMORA 0.1\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2009-01-16 11:45-0800\n"
+"PO-Revision-Date: 2009-06-05 00:59+0300\n"
+"Last-Translator: Alexander Slovesnik <unghost@mozilla-russia.org>\n"
+"Language-Team: Russian <ru@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%"
+"10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
+
+#: views/addons/policy.thtml:98
+msgid "a_cancel_installation"
+msgstr "Отменить уÑтановку"
+
+#. This is the text that appears on buttons to download add-ons.
+#. %$1s is an optional string that only appears if the add-on is only available for
+#. a certain platform. Examples: (Windows) or (Linux)
+#. Note that the parentheses are included in the string. :(
+#: views/elements/amo2009/install.thtml:126
+#: views/elements/amo2009/install.thtml:227
+#: views/elements/amo2009/install.thtml:257
+#: views/elements/amo2009/install.thtml:300
+#: views/elements/amo2009/install.thtml:312 views/elements/install.thtml:73
+#: views/elements/install.thtml:181 views/elements/install.thtml:205
+#: views/elements/install.thtml:248 views/elements/install.thtml:260
+#: views/addons/plugins.thtml:66 views/addons/plugins.thtml:76
+#: views/addons/plugins.thtml:86 views/addons/plugins.thtml:96
+#: views/addons/plugins.thtml:119
+#, php-format
+msgid "a_download"
+msgstr "Загрузить %s"
+
+#: views/addons/policy.thtml:72
+msgid "a_eula_download"
+msgstr "ПринÑÑ‚ÑŒ и загрузить"
+
+#: views/addons/policy.thtml:74
+msgid "a_eula_install"
+msgstr "ПринÑÑ‚ÑŒ и уÑтановить"
+
+#: views/elements/header.thtml:76 views/elements/header.thtml:82
+#: views/api/api_addon.thtml:55 views/api/collections_feed.thtml:75
+#: views/sharing_api/addon.thtml:64
+msgid "a_header_public"
+msgstr "Публичные"
+
+#: views/elements/header.thtml:58 views/elements/header.thtml:75
+#: views/elements/header.thtml:80 views/api/api_addon.thtml:57
+#: views/api/collections_feed.thtml:77 views/sharing_api/addon.thtml:66
+msgid "a_header_sandbox"
+msgstr "«ПеÑочница»"
+
+#. %s is a date in the _('date') format
+#: views/elements/amo2009/homepage_addon.thtml:115
+#: views/elements/addon_listitem.thtml:122 views/elements/feature.thtml:106
+#: views/addons/display.thtml:104 views/addons/browse_thumbs.thtml:73
+msgid "addon_detail_last_updated"
+msgstr "Обновлено %s"
+
+#. %s is the version of the add-on. Example: 3.2a1
+#: views/elements/amo2009/addon_version_detail.thtml:51
+#: views/elements/addon_version_detail.thtml:51
+#, php-format
+msgid "addon_display_header_version"
+msgstr "ВерÑÐ¸Ñ %s"
+
+#: views/addons/browse_thumbs.thtml:80
+msgid "addon_downloads"
+msgstr "загрузки"
+
+#: views/addons/display.thtml:147
+msgid "addon_downloads_total"
+msgstr "загрузок вÑего"
+
+#: views/elements/amo2009/homepage_addon.thtml:106
+#: views/elements/addon_listitem.thtml:115 views/elements/feature.thtml:101
+#: views/addons/category_landing.thtml:157 views/addons/display.thtml:146
+#: views/addons/browse_thumbs.thtml:80
+msgid "addon_downloads_weekly"
+msgstr "загрузок еженедельно"
+
+# %1 is the add-on count, %2 the category name
+#. %1 is the add-on count, %2 the category name
+#: views/addons/browse_thumbs.thtml:104 views/addons/browse.thtml:60
+#, php-format
+msgid "addon_list_category_totalcount"
+msgid_plural "addon_list_category_totalcount"
+msgstr[0] "%1$s дополнение"
+msgstr[1] "%1$s дополнениÑ"
+msgstr[2] "%1$s дополнений"
+
+#: views/elements/amo2009/addon_list_options.thtml:103
+#: views/elements/pagination.thtml:67
+#: views/elements/addon_list_options.thtml:94
+msgid "addon_list_perpage"
+msgstr "на Ñтраницу"
+
+#: views/elements/amo2009/addon_list_options.thtml:84
+#: views/elements/addon_list_options.thtml:98
+msgid "addon_list_sortby"
+msgstr "Сортировать по:"
+
+#: views/helpers/addons_html.php:568 views/elements/amo2009/install.thtml:321
+#: views/elements/feature.thtml:89
+msgid "addon_listitem_flag_experimental"
+msgstr "ÑкÑпериментальные"
+
+#: views/helpers/addons_html.php:570
+msgid "addon_listitem_flag_recommended"
+msgstr "рекомендуемые"
+
+# %1 is the addon name, %2 is the platform
+#. %1 is the add-on name, %2 is the platform
+#: views/pages/js_constants.js.thtml:66
+msgid "addon_not_available_for_platform"
+msgstr "%1$s недоÑтупен Ð´Ð»Ñ Ð¿Ð»Ð°Ñ‚Ñ„Ð¾Ñ€Ð¼Ñ‹ %2$s."
+
+# %1 is the addon name
+#. %1 is the add-on name
+#: views/addons/policy.thtml:101 views/addons/previews.thtml:60
+#: views/addons/versions.thtml:130 views/reviews/flag.thtml:61
+#: views/reviews/add.thtml:114 views/reviews/display.thtml:216
+#: views/reviews/review_added.thtml:57
+#, php-format
+msgid "addon_review_a_back_to_addon_x"
+msgstr "ВернутьÑÑ Ðº %1$s..."
+
+# %1 is the addon name
+#. %1 is the add-on name
+#: views/reviews/flag.thtml:60 views/reviews/add.thtml:113
+#: views/reviews/review_added.thtml:56
+#, php-format
+msgid "addon_review_a_back_to_reviews"
+msgstr "ВернутьÑÑ Ðº отзывам..."
+
+#: views/reviews/add.thtml:85
+msgid "addon_review_add_rating_field"
+msgstr "Рейтинг:"
+
+#: views/reviews/add.thtml:102
+msgid "addon_review_add_review_field"
+msgstr "Отзыв:"
+
+#: views/reviews/add.thtml:107
+msgid "addon_review_add_submit"
+msgstr "Отправить ваш отзыв"
+
+#. %s is the name of the add-on
+#: views/reviews/add.thtml:51
+#, php-format
+msgid "addon_review_add_title"
+msgstr "Добавление отзыва о %s"
+
+#: views/reviews/add.thtml:78
+msgid "addon_review_add_title_field"
+msgstr "Заголовок:"
+
+#: views/reviews/display.thtml:77 views/reviews/display.thtml:161
+msgid "addon_review_admin_delete"
+msgstr "Удалить"
+
+#: views/reviews/display.thtml:76
+msgid "addon_review_author_reply_link"
+msgstr "Ответить"
+
+#: views/reviews/delete.thtml:62
+msgid "addon_review_confirm_delete"
+msgstr "Ð’Ñ‹ дейÑтвительно хотите удалить Ñтот отзыв?"
+
+#: views/reviews/delete.thtml:63
+msgid "addon_review_confirm_no"
+msgstr "Ðет"
+
+#: views/reviews/delete.thtml:64
+msgid "addon_review_confirm_yes"
+msgstr "Да"
+
+#: views/reviews/delete.thtml:48
+msgid "addon_review_delete_header"
+msgstr "Удалить отзыв"
+
+#: controllers/reviews_controller.php:449
+msgid "addon_review_deleted_successfully"
+msgstr "Отзыв уÑпешно удалён."
+
+#. %s is the name of the add-on
+#: views/reviews/add.thtml:51
+#, php-format
+msgid "addon_review_edit_title"
+msgstr "Редактировать отзыв на %s"
+
+# %1 is the count of characters entered as notes for the review flag reason.
+#. %1 is the count of characters entered as notes for the review flag reason.
+#: controllers/reviews_controller.php:539
+msgid "addon_review_flag_error_other_length"
+msgstr ""
+"При пометке Ñтого отзыва произошла проблема: поле Ð¿Ñ€Ð¸Ð¼ÐµÑ‡Ð°Ð½Ð¸Ñ Ð´Ð»Ñ Ð¿Ð¾Ð¼ÐµÑ‡ÐµÐ½Ð½Ñ‹Ñ… "
+"отзывов вмещает от 10 до 100 Ñимволов; вы ввели %1$s Ñимвола(ов)."
+
+#. Removing an extra comma
+#: views/reviews/review_added.thtml:53
+msgid "addon_review_in_moderation"
+msgstr "Примечание: перед публикацией ваш отзыв будет проверен рецензентом."
+
+#: views/reviews/add.thtml:57
+msgid "addon_review_in_reply_to"
+msgstr "Ответ разработчика на:"
+
+# %1 is the review count, %2 is the nickname or full name of the user.
+#. %1 is the review count, %2 is the nickname or full name of the user.
+#: views/reviews/display.thtml:131
+#, php-format
+msgid "addon_review_others_by_user"
+msgid_plural "addon_review_others_by_user"
+msgstr[0] "ПроÑмотреть %1$s предыдущий отзыв о дополнении, оÑтавленный %2$s."
+msgstr[1] "ПроÑмотреть %1$s предыдущих отзыва о дополнении, оÑтавленных %2$s."
+msgstr[2] "ПроÑмотреть %1$s предыдущих отзывов о дополнении, оÑтавленных %2$s."
+
+# %1 is the addon name
+#. %1 is the add-on name
+#: controllers/reviews_controller.php:201
+#: controllers/reviews_controller.php:250
+#: controllers/reviews_controller.php:345
+#: controllers/reviews_controller.php:424
+#, php-format
+msgid "addon_review_pagetitle"
+msgstr "Отзывы о %s"
+
+# %1 is the user, %2 is the (localized) date
+#. %1 is the user, %2 is the (localized) date
+#: views/reviews/display.thtml:160
+#, php-format
+msgid "addon_review_reply_on_x_by_y"
+msgstr "Ответ от %1$s оÑтавлен %2$s"
+
+#: views/reviews/display.thtml:157
+msgid "addon_review_reply_prefix"
+msgstr "Ответ разработчика:"
+
+#: views/reviews/review_added.thtml:51
+msgid "addon_review_saved_successfully"
+msgstr "Ваш отзыв уÑпешно добавлен. СпаÑибо!"
+
+#: views/addons/display.thtml:354 views/reviews/display.thtml:72
+msgid "addon_reviewed_by_u_on_d"
+msgstr "от %1$s оÑтавлен %2$s"
+
+# %1 is the user, %2 is the (localized) date, %3 is the rating
+#. %1 is the user, %2 is the (localized) date, %3 is the rating
+#: views/editors/reviews_queue.thtml:57 views/editors/reviews_queue.thtml:68
+#: views/reviews/add.thtml:63 views/reviews/delete.thtml:54
+#, php-format
+msgid "addon_reviewed_on_x_rated_y"
+msgstr "Отзыв от %1$s оÑтавлен %2$s (оценка %3$s)"
+
+#: views/elements/amo2009/addon_version_detail.thtml:52
+#: views/elements/addon_version_detail.thtml:52
+msgid "addon_version_permalink"
+msgstr "ПоÑтоÑÐ½Ð½Ð°Ñ ÑÑылка на Ñту верÑию"
+
+# %1 is the current Application name (e.g. Firefox)
+# %2 is the Application's version number
+#. %1 is the current Application name (e.g. Firefox)
+#. %2 is the Application's version number
+#: views/addons/versions.thtml:140
+msgid "addon_versions_getlatestversion"
+msgstr "ПоÑледнÑÑ Ð²ÐµÑ€ÑиÑ, ÑовмеÑÑ‚Ð¸Ð¼Ð°Ñ Ñ %1$s %2$s"
+
+#: views/addons/display.thtml:447
+msgid "addons_author_addons_submit"
+msgstr "Перейти"
+
+#: views/elements/amo2009/homepage_addon.thtml:100
+#: views/elements/feature.thtml:95
+msgid "addons_author_tooltip"
+msgstr "ПроÑмотреть профиль автора"
+
+# %1 is the name of the Application (eg. Firefox)
+#. %1 is the name of the Application (eg. Firefox)
+#: controllers/addons_controller.php:1296
+msgid "addons_browse_all_themes_title"
+msgstr "Обзор вÑех тем :: Ð”Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ %1$s"
+
+#. %s is the name of the category
+#: controllers/addons_controller.php:1016
+#, php-format
+msgid "addons_browse_browse_category"
+msgstr "Обзор категории %s"
+
+# %1 is the name of the theme category (eg. Modern)
+# %2 is the name of the Application (eg. Firefox)
+#. %1 is the name of the theme category (eg. Modern)
+#. %2 is the name of the Application (eg. Firefox)
+#: controllers/addons_controller.php:664
+msgid "addons_browse_categories_header_theme"
+msgstr "Обзор тем в категории %1$s :: Ð”Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ %2$s"
+
+#: views/addons/display.thtml:249
+msgid "addons_display_a_license_what"
+msgstr "Что Ñто?"
+
+#: views/reviews/display.thtml:222
+msgid "addons_display_add_review"
+msgstr "Добавить отзыв"
+
+#: views/addons/display.thtml:294
+msgid "addons_display_advanced_details"
+msgstr "Дополнительные детали"
+
+#: views/addons/display.thtml:98
+msgid "addons_display_categories"
+msgstr "Категории"
+
+#: views/addons/display.thtml:482
+msgid "addons_display_collection_add"
+msgstr "Добавить в подборку:"
+
+#: views/addons/display.thtml:491
+msgid "addons_display_collection_add_new"
+msgstr "ÐÐ¾Ð²Ð°Ñ Ð¿Ð¾Ð´Ð±Ð¾Ñ€ÐºÐ°..."
+
+#: views/addons/display.thtml:487
+msgid "addons_display_collection_add_select_one"
+msgstr "Выбрать подборку..."
+
+#: views/addons/display.thtml:493
+msgid "addons_display_collection_add_submit"
+msgstr "Опубликовать"
+
+#. %1$s is the add-on name
+#. %2$s is the collection name, linked to the collection's page
+#: views/pages/js_constants.js.thtml:103 views/addons/display.thtml:61
+msgid "addons_display_collection_publish_success"
+msgstr "%1$s было добавлено в подборку %2$s."
+
+#: views/addons/display.thtml:483
+msgid "addons_display_collection_whatsthis"
+msgstr "Что Ñто?"
+
+#. %1$s is a number
+#: views/addons/display.thtml:473
+msgid "addons_display_collections_more"
+msgid_plural "addons_display_collections_more"
+msgstr[0] "и ещё %1$s подборка"
+msgstr[1] "и ещё %1$s подборки"
+msgstr[2] "и ещё %1$s подборок"
+
+#: views/addons/display.thtml:403
+msgid "addons_display_detailed_review"
+msgstr "подробный отзыв"
+
+#: views/reviews/add.thtml:89 views/reviews/add.thtml:90
+msgid "addons_display_dont_like_it"
+msgstr "Ðе нравитÑÑ"
+
+#: views/reviews/display.thtml:220
+msgid "addons_display_edit_review"
+msgstr "Редактировать ваш отзыв"
+
+#: views/addons/display.thtml:132
+msgid "addons_display_has_privacy"
+msgstr "У данного Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ ÐµÑÑ‚ÑŒ ÑобÑÑ‚Ð²ÐµÐ½Ð½Ð°Ñ Ð¿Ð¾Ð»Ð¸Ñ‚Ð¸ÐºÐ° конфиденциальноÑти."
+
+#: views/reviews/add.thtml:87 views/reviews/add.thtml:88
+msgid "addons_display_hate_it"
+msgstr "Ðенавижу"
+
+#: views/addons/display.thtml:462
+msgid "addons_display_header_collections"
+msgstr "Похожие подборки"
+
+#: views/addons/display.thtml:297
+msgid "addons_display_header_developer_comments"
+msgstr "Комментарии разработчика"
+
+#: views/addons/display.thtml:230
+msgid "addons_display_header_homepage"
+msgstr "ДомашнÑÑ Ñтраница"
+
+#: views/addons/display.thtml:247 views/addons/versions.thtml:110
+msgid "addons_display_header_license"
+msgstr "Ð›Ð¸Ñ†ÐµÐ½Ð·Ð¸Ñ Ð¸Ñходного кода"
+
+#: views/addons/display.thtml:337
+msgid "addons_display_header_reviews"
+msgstr "Отзывы"
+
+#: views/addons/display.thtml:261
+msgid "addons_display_header_support"
+msgstr "Поддержка"
+
+#: views/reviews/add.thtml:91 views/reviews/add.thtml:92
+msgid "addons_display_like_it"
+msgstr "ÐравитÑÑ"
+
+#: views/addons/display.thtml:210
+msgid "addons_display_long_description"
+msgstr "Подробное опиÑание"
+
+#: views/reviews/add.thtml:95 views/reviews/add.thtml:96
+msgid "addons_display_love_it"
+msgstr "Обожаю"
+
+#: views/addons/display.thtml:178
+msgid "addons_display_more_images"
+msgstr "Другие изображениÑ"
+
+#: views/addons/display.thtml:465
+msgid "addons_display_nocollections"
+msgstr "Это дополнение не входит пока ни в одну подборку."
+
+# %1$s is either an author's name or a comma separated list of authors. Using
+# the list doesn't make sense in the English plural form so we ignore the
+# variable.
+#. %1$s is either an author's name or a comma separated list of authors. Using
+#. the list doesn't make sense in the English plural form so we ignore the
+#. variable.
+#: views/addons/display.thtml:436
+msgid "addons_display_other_addons_by"
+msgid_plural "addons_display_other_addons_by"
+msgstr[0] "Другие Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ñозданные %1$s"
+msgstr[1] "Другие Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ñозданные Ñтими авторами"
+
+#. %s is the name of the add-on and the add-on section. Example:
+#. Some Add-on :: Firefox Add-ons
+#. This should not be concatenated in the code and should be fixed.
+#: controllers/addons_controller.php:141 controllers/addons_controller.php:280
+#: controllers/addons_controller.php:1442
+#, php-format
+msgid "addons_display_pagetitle"
+msgstr "%s"
+
+#. %s is an email address
+#: views/addons/display.thtml:286
+#, php-format
+msgid "addons_display_paragraph_supportinfoemail"
+msgstr ""
+"Поддержка Ñтого Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð¾ÑущеÑтвлÑетÑÑ Ñ€Ð°Ð·Ñ€Ð°Ð±Ð¾Ñ‚Ñ‡Ð¸ÐºÐ¾Ð¼ по адреÑу "
+"Ñлектронной почты %s."
+
+#. %$1s is a URL
+#. %$2s is an email address
+#: views/addons/display.thtml:269
+#, php-format
+msgid "addons_display_paragraph_supportinfoemailurl"
+msgstr ""
+"Поддержка Ñтого Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð¾ÑущеÑтвлÑетÑÑ Ñ€Ð°Ð·Ñ€Ð°Ð±Ð¾Ñ‚Ñ‡Ð¸ÐºÐ¾Ð¼ по адреÑу %s или %s."
+
+#. %s is a URL
+#: views/addons/display.thtml:278
+#, php-format
+msgid "addons_display_paragraph_supportinfourl"
+msgstr "Поддержка Ñтого Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð¾ÑущеÑтвлÑетÑÑ Ñ€Ð°Ð·Ñ€Ð°Ð±Ð¾Ñ‚Ñ‡Ð¸ÐºÐ¾Ð¼ по адреÑу %s."
+
+#: views/addons/display.thtml:383
+msgid "addons_display_rate_it"
+msgstr "Оценить"
+
+#: views/reviews/add.thtml:93 views/reviews/add.thtml:94
+msgid "addons_display_really_like_it"
+msgstr "Очень нравитÑÑ"
+
+#: views/addons/display.thtml:410
+msgid "addons_display_review_etiquette"
+msgstr ""
+"ПожалуйÑта не оÑтавлÑйте в отзывах ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ Ð¾Ð± ошибках. Мы не Ñообщаем ваш "
+"почтовый Ð°Ð´Ñ€ÐµÑ Ñ€Ð°Ð·Ñ€Ð°Ð±Ð¾Ñ‚Ñ‡Ð¸ÐºÐ°Ð¼ дополнений, а им может потребоватьÑÑ ÑвÑзатьÑÑ "
+"Ñ Ð²Ð°Ð¼Ð¸, чтобы помочь решить вашу проблему."
+
+# %1 is the review guidelines link
+#. %1 is the review guidelines link
+#: views/addons/display.thtml:417
+msgid "addons_display_review_guidelines_link"
+msgstr "<a href=\"%s\">Советы по оÑтавлению отзывов</a>"
+
+# %1 is the support section link
+#. %1 is the support section link
+#: views/addons/display.thtml:414
+msgid "addons_display_review_see_support"
+msgstr ""
+"Ð”Ð»Ñ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ñ Ñведений о том, как получить помощь по работе Ñ Ñтим "
+"дополнением, обратитеÑÑŒ в <a href=\"%1$s\">раздел поддержки</a>."
+
+#: views/addons/display.thtml:404
+msgid "addons_display_review_submit"
+msgstr "Сохранить"
+
+#: views/addons/display.thtml:430
+#, php-format
+msgid "addons_display_see_all_addons"
+msgstr "ПроÑмотреть вÑе Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð² %1$s"
+
+# %1 is the number of reviews
+#. %1 is the number of reviews
+#: views/addons/display.thtml:364
+#, php-format
+msgid "addons_display_see_all_reviews"
+msgstr "ПроÑмотреть вÑе отзывы (%1$s)"
+
+#: views/addons/display.thtml:219
+msgid "addons_display_see_all_versions"
+msgstr "Отобразить вÑе верÑии"
+
+#: views/addons/display.thtml:321 views/addons/versions.thtml:117
+msgid "addons_display_view_source"
+msgstr "ПроÑмотреть иÑходный текÑÑ‚"
+
+#: views/addons/display.thtml:324
+msgid "addons_display_view_stats"
+msgstr "ПроÑмотреть ÑтатиÑтику"
+
+#: views/addons/display.thtml:376
+msgid "addons_display_what_do_you_think"
+msgstr "Что вы думаете?"
+
+#: views/elements/app_compatibility.thtml:49
+msgid "addons_display_workswith"
+msgstr "СовмеÑтимоÑÑ‚ÑŒ:"
+
+#: views/addons/home.thtml:112
+msgid "addons_home_browse_new"
+msgstr "Только что добавлено"
+
+#: views/addons/home.thtml:110
+msgid "addons_home_browse_popular"
+msgstr "ПопулÑрное"
+
+#: views/addons/home.thtml:108
+msgid "addons_home_browse_recommended"
+msgstr "Рекомендуемое"
+
+#: views/addons/home.thtml:127 views/addons/home.thtml:134
+#: views/addons/home.thtml:141 views/addons/home.thtml:148
+msgid "addons_home_browse_subscribe"
+msgstr "ПодпиÑатьÑÑ"
+
+#: views/addons/home.thtml:101
+msgid "addons_home_browse_title"
+msgstr "Обзор дополнений"
+
+#: views/addons/home.thtml:114
+msgid "addons_home_browse_updated"
+msgstr "Обновлённые"
+
+#: views/elements/amo2009/homepage_addon.thtml:100
+#: views/elements/addon_discussionheader.thtml:83
+#: views/elements/addon_listitem.thtml:109 views/elements/feature.thtml:95
+#: views/addons/category_landing.thtml:66 views/addons/policy.thtml:57
+#: views/addons/display.thtml:70 views/addons/home.thtml:178
+msgid "addons_home_by"
+msgstr "автор"
+
+#: views/addons/home.thtml:169
+msgid "addons_home_collection_popular_title"
+msgstr "ПопулÑрные подборки"
+
+#: views/elements/amo2009/categories.thtml:69 views/addons/home.thtml:160
+msgid "addons_home_collections"
+msgstr "Подборки"
+
+#. %1$s is the count of addons in a collection
+#: views/elements/amo2009/collection_listing_item.thtml:51
+#: views/addons/home.thtml:185
+msgid "addons_home_collections_addon_count"
+msgid_plural "addons_home_collections_addon_count"
+msgstr[0] "<strong>%1$s</strong> дополнение"
+msgstr[1] "<strong>%1$s</strong> дополнениÑ"
+msgstr[2] "<strong>%1$s</strong> дополнений"
+
+#: views/addons/home.thtml:196
+msgid "addons_home_collections_all"
+msgstr "ПроÑмотр вÑех подборок"
+
+#: views/addons/home.thtml:162
+msgid "addons_home_collections_intro"
+msgstr ""
+"Подборки ÑвлÑÑŽÑ‚ÑÑ ÑпоÑобом категоризации, ÑÐ¼ÐµÑˆÐ¸Ð²Ð°Ð½Ð¸Ñ Ð¸ ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ ÐºÐ¾Ð»Ð»ÐµÐºÑ†Ð¸Ð¹ "
+"дополнений. ПодпишитеÑÑŒ на подборки, Ñозданные другими пользователÑми, или "
+"Ñоздайте Ñвои ÑобÑтвенные."
+
+#. %1$s is the count of subscribers for a collection
+#: views/elements/amo2009/collection_listing_item.thtml:58
+#: views/collections/detail.thtml:96 views/addons/home.thtml:189
+msgid "addons_home_collections_subscribers"
+msgid_plural "addons_home_collections_subscribers"
+msgstr[0] "<strong>%1$s</strong> подпиÑчик"
+msgstr[1] "<strong>%1$s</strong> подпиÑчика"
+msgstr[2] "<strong>%1$s</strong> подпиÑчиков"
+
+#: views/addons/searchengines.thtml:54 views/addons/themes_landing.thtml:49
+msgid "addons_home_feature_head"
+msgstr "Мы рекомендуем"
+
+#: controllers/search_controller.php:218 controllers/addons_controller.php:176
+#: controllers/addons_controller.php:428 controllers/addons_controller.php:671
+#: controllers/addons_controller.php:871
+#: controllers/addons_controller.php:1103
+#: controllers/addons_controller.php:1242
+#: controllers/addons_controller.php:1298
+#, php-format
+msgid "addons_home_header_details"
+msgstr ""
+"Ð”Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ñ€Ð°ÑширÑÑŽÑ‚ возможноÑти %1$s, шаг за шагом Ð¿Ñ€Ð¸Ð±Ð»Ð¸Ð¶Ð°Ñ Ð¸Ñ… к "
+"идеальным. ОглÑнитеÑÑŒ вокруг и Ñделайте %1$s таким, каким вы Ñтого хотите."
+
+#. %1$s is the HTML collection name link.
+#: views/elements/amo2009/teaser_collections.thtml:107
+msgid "addons_home_introduction_collection_link"
+msgstr "ПонравилиÑÑŒ? Рв %1$s можно найти ещё."
+
+#: views/elements/amo2009/teaser_collections.thtml:60
+msgid "addons_home_introduction_extras"
+msgstr ""
+"<strong>Более 5000 беÑплатных дополнений</strong>, которые позволÑÑ‚ вам "
+"наÑтроить Firefox под Ñвои нужды, безгранично раÑширÑÑ ÐµÐ³Ð¾ функциональноÑÑ‚ÑŒ."
+
+#: views/elements/amo2009/teaser_collections.thtml:55
+msgid "addons_home_introduction_header"
+msgstr "Что такое дополнениÑ?"
+
+#: views/elements/amo2009/teaser_collections.thtml:72
+msgid "addons_home_introduction_install"
+msgstr ""
+"<strong>Легкие в уÑтановке</strong>, они также уведомлÑÑŽÑ‚ Ð²Ð°Ñ Ð² Ñлучае "
+"поÑÐ²Ð»ÐµÐ½Ð¸Ñ Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ð¹."
+
+#: views/elements/amo2009/teaser_collections.thtml:45
+msgid "addons_home_introduction_name"
+msgstr "Введение"
+
+#: views/elements/amo2009/teaser_collections.thtml:66
+msgid "addons_home_introduction_themes"
+msgstr ""
+"Панели инÑтрументов, темы и плагины Ð´Ð»Ñ Ð¿Ð¾Ð¸Ñковых движков <strong>помогут "
+"вам выполнÑÑ‚ÑŒ повÑедневные задачи.</strong>"
+
+#: views/addons/home.thtml:161
+msgid "addons_home_new_indicator"
+msgstr "ÐОВИÐКÐ!"
+
+#: views/elements/app_chooser.thtml:48 views/layouts/amo2009.thtml:257
+msgid "addons_home_other_applications"
+msgstr "Другие приложениÑ"
+
+#. %1$s is the application the user is browsing. Examples: Thunderbird, Firefox,
+#. Sunbird
+#: views/pages/collector_faq.thtml:49 views/pages/collector_firstrun.thtml:42
+#: views/pages/collector.thtml:46 views/pages/collector_features.thtml:54
+#: controllers/developers_controller.php:87
+#: controllers/compatibility_controller.php:72
+#: controllers/components/simple_acl.php:81 controllers/components/amo.php:607
+#: controllers/statistics_controller.php:60
+#: controllers/statistics_controller.php:240
+#: controllers/previews_controller.php:67 controllers/users_controller.php:90
+#: controllers/users_controller.php:223 controllers/users_controller.php:330
+#: controllers/users_controller.php:414 controllers/users_controller.php:708
+#: controllers/users_controller.php:723 controllers/reviews_controller.php:204
+#: controllers/reviews_controller.php:251
+#: controllers/reviews_controller.php:346
+#: controllers/reviews_controller.php:425
+#: controllers/search_controller.php:185 controllers/search_controller.php:297
+#: controllers/search_controller.php:301 controllers/addons_controller.php:147
+#: controllers/addons_controller.php:280 controllers/addons_controller.php:370
+#: controllers/addons_controller.php:667 controllers/addons_controller.php:874
+#: controllers/addons_controller.php:1019
+#: controllers/addons_controller.php:1034
+#: controllers/addons_controller.php:1101
+#: controllers/addons_controller.php:1121
+#: controllers/addons_controller.php:1240
+#: controllers/addons_controller.php:1357
+#: controllers/addons_controller.php:1364
+#: controllers/addons_controller.php:1442
+#: controllers/addons_controller.php:1477
+#: controllers/addons_controller.php:1538
+#: controllers/addons_controller.php:1543
+#: controllers/editors_controller.php:64 controllers/pages_controller.php:132
+#: controllers/groups_controller.php:65 controllers/groups_controller.php:71
+#: controllers/groups_controller.php:89 controllers/groups_controller.php:111
+#: controllers/collections_controller.php:57
+#: controllers/collections_controller.php:121
+#: controllers/collections_controller.php:205
+#: controllers/collections_controller.php:365
+#: controllers/collections_controller.php:404
+#: controllers/collections_controller.php:466
+#: controllers/collections_controller.php:538
+#: controllers/collections_controller.php:828
+#: controllers/localizers_controller.php:72
+#, php-format
+msgid "addons_home_pagetitle"
+msgstr "Ð”Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ %1$s"
+
+#. %1$s is the number of addons downloaded
+#: views/addons/home.thtml:57
+#, php-format
+msgid "addons_home_stats_downloaded"
+msgid_plural "addons_home_stats_downloaded"
+msgstr[0] "<strong>%1$s</strong> <span>дополнение загружено</span>"
+msgstr[1] "<strong>%1$s</strong> <span>Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð·Ð°Ð³Ñ€ÑƒÐ¶ÐµÐ½Ð¾</span>"
+msgstr[2] "<strong>%1$s</strong> <span>дополнений загружено</span>"
+
+#. %1$s is the number of addons in use
+#: views/addons/home.thtml:63
+#, php-format
+msgid "addons_home_stats_inuse"
+msgid_plural "addons_home_stats_inuse"
+msgstr[0] "<strong>%1$s</strong> <span>дополнение иÑпользуетÑÑ</span>"
+msgstr[1] "<strong>%1$s</strong> <span>Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð¸ÑпользуетÑÑ</span>"
+msgstr[2] "<strong>%1$s</strong> <span>дополнений иÑпользуетÑÑ</span>"
+
+#: views/addons/home.thtml:136
+msgid "addons_home_view_all_newest_title"
+msgstr "ПроÑмотреть вÑе новые дополнениÑ"
+
+#: views/addons/home.thtml:129
+msgid "addons_home_view_all_popular_title"
+msgstr "ПроÑмотреть вÑе популÑрные дополнениÑ"
+
+#: views/addons/home.thtml:150
+msgid "addons_home_view_all_recommended_title"
+msgstr "ПроÑмотреть вÑе рекомендуемые дополнениÑ"
+
+#: views/addons/home.thtml:143
+msgid "addons_home_view_all_updated_title"
+msgstr "ПроÑмотреть вÑе недавно обновлённые дополнениÑ"
+
+#: views/elements/amo2009/install.thtml:334 views/elements/install.thtml:112
+msgid "addons_install_in_sunbird"
+msgstr ""
+"<ol><li>Ðажмите правой кнопкой мыши на ÑÑылке и выберите «Сохранить ÑÑылку "
+"как…» Ð´Ð»Ñ Ñ‚Ð¾Ð³Ð¾, чтобы Ñохранить файл на жёÑтком диÑке.</li><li>Ð’ Mozilla "
+"Sunbird, откройте окно менеджера дополнений через меню «ИнÑтрументы|"
+"ДополнениÑ».</li><li>Ðажмите кнопку «УÑтановить…», найдите и выберите файл, "
+"который вы Ñкачали и нажмите «OK».</li></ol>"
+
+#: views/elements/amo2009/install.thtml:333 views/elements/install.thtml:111
+msgid "addons_install_in_sunbird_title"
+msgstr "Как уÑтановить Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð² Sunbird"
+
+#: views/elements/amo2009/install.thtml:331 views/elements/install.thtml:106
+msgid "addons_install_in_thunderbird"
+msgstr ""
+"<ol><li>Ðажмите правой кнопкой мыши на ÑÑылке и выберите «Сохранить ÑÑылку "
+"как…» Ð´Ð»Ñ Ñ‚Ð¾Ð³Ð¾, чтобы Ñохранить файл на жёÑтком диÑке.</li><li>Ð’ Mozilla "
+"Thunderbird откройте окно менеджера дополнений через меню «ИнÑтрументы|"
+"ДополнениÑ».</li><li>Ðажмите кнопку «УÑтановить…», найдите и выберите файл, "
+"который вы Ñкачали и нажмите «OK».</li></ol>"
+
+#: views/elements/amo2009/install.thtml:330 views/elements/install.thtml:105
+msgid "addons_install_in_thunderbird_title"
+msgstr "Как уÑтановить Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð² Thunderbird"
+
+#: views/elements/amo2009/addon_list_options.thtml:108
+#: views/elements/addon_list_options.thtml:105
+msgid "addons_options_show_experimental"
+msgstr "показать ÑкÑпериментальные дополнениÑ"
+
+#: views/elements/amo2009/addon_list_options.thtml:113
+#: views/elements/addon_list_options.thtml:109
+msgid "addons_options_submit"
+msgstr "Перейти"
+
+#: views/addons/plugins.thtml:63 views/addons/plugins.thtml:73
+#: views/addons/plugins.thtml:83 views/addons/plugins.thtml:93
+#: views/addons/plugins.thtml:103 views/addons/plugins.thtml:116
+#: views/addons/plugins.thtml:126
+msgid "addons_plugins_by"
+msgstr "От"
+
+#: views/addons/plugins.thtml:107
+msgid "addons_plugins_for_linux"
+msgstr "Ð´Ð»Ñ Linux"
+
+#: views/addons/plugins.thtml:108 views/addons/plugins.thtml:131
+msgid "addons_plugins_for_macosx"
+msgstr "Ð´Ð»Ñ Mac OS X"
+
+#: views/addons/plugins.thtml:106 views/addons/plugins.thtml:129
+#: views/addons/plugins.thtml:130
+msgid "addons_plugins_for_windows"
+msgstr "Ð´Ð»Ñ Windows"
+
+#. %1$s is a URL
+#: views/addons/plugins.thtml:139
+#, php-format
+msgid "addons_plugins_looking_for_more"
+msgstr ""
+"Ðа Ñтой Ñтранице перечиÑлены только наиболее раÑпроÑтранённые и популÑрные "
+"плагины. Более подробную информацию о других плагинах Ð´Ð»Ñ Ð¿Ñ€Ð¾Ð´ÑƒÐºÑ‚Ð¾Ð² "
+"ÑемейÑтва Mozilla можно найти на Ñайте %1$s"
+
+#: views/addons/plugins.thtml:137
+msgid "addons_plugins_looking_for_plugin"
+msgstr "Ðужен плагин, которого здеÑÑŒ нет?"
+
+#: views/addons/plugins.thtml:58
+msgid "addons_plugins_main_description"
+msgstr ""
+"Плагины помогают вашему браузеру выполнÑÑ‚ÑŒ Ñпецифичные функции, такие как "
+"проÑмотр графичеÑких файлов в Ñпециальных форматах или проигрывание "
+"мультимедиа файлов. Плагины Ñлегка отличаютÑÑ Ð¾Ñ‚ раÑширений, которые "
+"изменÑÑŽÑ‚ или раÑширÑÑŽÑ‚ ÑущеÑтвующую функциональноÑÑ‚ÑŒ."
+
+#. %1$s is the application name. Example: Firefox, Thunderbird, Sunbird
+#: controllers/addons_controller.php:1122
+#, php-format
+msgid "addons_plugins_main_header"
+msgstr "ПопулÑрные плагины Ð´Ð»Ñ %1$s"
+
+#: controllers/components/amo.php:698 controllers/addons_controller.php:1121
+msgid "addons_plugins_pagetitle"
+msgstr "Плагины"
+
+#: views/addons/plugins.thtml:68 views/addons/plugins.thtml:78
+#: views/addons/plugins.thtml:88 views/addons/plugins.thtml:98
+#: views/addons/plugins.thtml:110 views/addons/plugins.thtml:121
+#: views/addons/plugins.thtml:133
+msgid "addons_plugins_support_documentation"
+msgstr "ДокументациÑ:"
+
+#. %s is the name of the add-on
+#: views/addons/policy.thtml:61
+#, php-format
+msgid "addons_policy_eula_require"
+msgstr ""
+"Перед началом уÑтановки %s необходимо принÑÑ‚ÑŒ лицензионное Ñоглашение "
+"конечного пользователÑ:"
+
+# %1 is the addon name
+#. %1 is the add-on name
+#: controllers/addons_controller.php:1476
+#, php-format
+msgid "addons_previews_pagetitle"
+msgstr "ИллюÑтрации Ð´Ð»Ñ %s"
+
+#: views/addons/category_landing.thtml:135
+msgid "addons_recently_added"
+msgstr "Ðедавно добавленные"
+
+#: views/addons/recommended.thtml:51 controllers/addons_controller.php:1365
+msgid "addons_recommended_introduction"
+msgstr ""
+"Среди громадного количеÑтва доÑтупных дополнений найдётÑÑ Ñ‡Ñ‚Ð¾-нибудь "
+"полезное Ð´Ð»Ñ ÐºÐ°Ð¶Ð´Ð¾Ð³Ð¾. Ð”Ð»Ñ Ð½Ð°Ñ‡Ð°Ð»Ð°, мы Ñобрали здеÑÑŒ ÑпиÑок некоторых Ñамых "
+"популÑрных дополнений. Удачи!"
+
+#: controllers/addons_controller.php:1357
+#: controllers/addons_controller.php:1364
+msgid "addons_recommended_pagetitle"
+msgstr "Рекомендуемые дополнениÑ"
+
+#: controllers/addons_controller.php:1360
+msgid "addons_recommended_title"
+msgstr "Рекомендуемые дополнениÑ"
+
+#: views/addons/searchengines.thtml:136
+msgid "addons_searchengines_additional_resources"
+msgstr "Дополнительные реÑурÑÑ‹"
+
+# link text devmo
+#. link text devmo
+#: views/addons/searchengines.thtml:141
+msgid "addons_searchengines_devmo_link"
+msgstr "Центр разработки Mozilla"
+
+#: views/pages/js_constants.js.thtml:67
+msgid "addons_searchengines_error_mozilla_browser_required"
+msgstr ""
+"Извините, Ð´Ð»Ñ ÑƒÑтановки поиÑкового плагина вам нужен браузер из ÑемейÑтва "
+"Mozilla (например, Firefox)."
+
+#: views/addons/searchengines.thtml:49
+msgid "addons_searchengines_error_nojavascript"
+msgstr ""
+"Ð”Ð»Ñ ÑƒÑтановки плагинов требуетÑÑ JavaScript, но, похоже, вы отключили его. "
+"Включите JavaScript перед попыткой уÑтановки любого из поиÑковых плагинов, "
+"указанных ниже."
+
+# %1 is "make your own" link
+# %2 is MDC link
+#. %1 is "make your own" link
+#. %2 is MDC link
+#: views/addons/searchengines.thtml:139
+msgid "addons_searchengines_learn_howto"
+msgstr "Ð’Ñ‹ можете прочитать о том как %1$s на Ñайте %2$s."
+
+# link path to search plugins instructions, relative to devmo
+#. link path to search plugins instructions, relative to devmo
+#: views/addons/searchengines.thtml:140
+msgid "addons_searchengines_makeyourown_href"
+msgstr "/en/docs/Creating_OpenSearch_plugins_for_Firefox"
+
+# link text for "make your own" (opensearch engine)
+#. link text for "make your own" (opensearch engine)
+#: views/addons/searchengines.thtml:140
+msgid "addons_searchengines_makeyourown_link"
+msgstr "Ñделать Ñвой ÑобÑтвенный поиÑковый плагин"
+
+# %1 is the link to mycroft.mozdev.org
+#. %1 is the link to mycroft.mozdev.org
+#: views/addons/searchengines.thtml:138
+msgid "addons_searchengines_more"
+msgstr "Ð’Ñ‹ можете найти другие поиÑковые плагины на Ñайте %1$s"
+
+# link text to mycroft.mozdev.org
+#. link text to mycroft.mozdev.org
+#: views/addons/searchengines.thtml:138
+msgid "addons_searchengines_mycroft_link"
+msgstr "mycroft.mozdev.org"
+
+#: controllers/addons_controller.php:1100
+#: controllers/addons_controller.php:1110
+msgid "addons_searchengines_pagetitle"
+msgstr "ПоиÑковые плагины"
+
+#: views/addons/searchengines.thtml:143
+msgid "addons_searchengines_thanks"
+msgstr ""
+"Мы выражаем оÑобую благодарноÑÑ‚ÑŒ проекту Mycroft за их работу над поиÑковыми "
+"плагинами Ð´Ð»Ñ Firefox."
+
+#: views/addons/display.thtml:154
+msgid "addons_share_button_text"
+msgstr "ПоделитьÑÑ Ñтим"
+
+#: controllers/addons_controller.php:89
+msgid "addons_share_label_delicious"
+msgstr "Добавить в Delicious"
+
+#: controllers/addons_controller.php:77
+msgid "addons_share_label_digg"
+msgstr "Ðа Digg!"
+
+#: controllers/addons_controller.php:83
+msgid "addons_share_label_facebook"
+msgstr "ÐапиÑать в Facebook"
+
+#: controllers/addons_controller.php:101
+msgid "addons_share_label_friendfeed"
+msgstr "ПоделитьÑÑ Ð½Ð° FriendFeed"
+
+#: controllers/addons_controller.php:95
+msgid "addons_share_label_myspace"
+msgstr "ÐапиÑать в MySpace"
+
+#: controllers/components/amo.php:201 controllers/components/amo.php:229
+msgid "addons_status_disabled"
+msgstr "Отключено"
+
+#: controllers/components/amo.php:191 controllers/components/amo.php:224
+msgid "addons_status_incomplete"
+msgstr "ÐÐµÐ¿Ð¾Ð»Ð½Ð°Ñ Ð²ÐµÑ€ÑиÑ"
+
+#: controllers/components/amo.php:197 controllers/components/amo.php:227
+msgid "addons_status_nominated"
+msgstr "Ð’ «пеÑочнице»; Ðоминировано на общий доÑтуп"
+
+#: views/pages/js_constants.js.thtml:80 controllers/components/amo.php:195
+#: controllers/components/amo.php:226
+msgid "addons_status_pending"
+msgstr "Ð’ «пеÑочнице»; Ожидает рецензии"
+
+#: views/pages/js_constants.js.thtml:78 controllers/components/amo.php:199
+#: controllers/components/amo.php:228
+msgid "addons_status_public"
+msgstr "Ð’ общем доÑтупе"
+
+#: views/pages/js_constants.js.thtml:79 controllers/components/amo.php:193
+#: controllers/components/amo.php:225
+msgid "addons_status_sandbox"
+msgstr "Ð’ «пеÑочнице»"
+
+#: controllers/components/amo.php:203
+msgid "addons_status_unknown"
+msgstr "Ð¡Ñ‚Ð°Ñ‚ÑƒÑ Ð½ÐµÐ¸Ð·Ð²ÐµÑтен"
+
+#: views/elements/amo2009/teaser_collections.thtml:91
+#: views/elements/amo2009/homepage_addon.thtml:99
+#: views/elements/feature.thtml:94
+msgid "addons_title_tooltip"
+msgstr "Подробнее об Ñтом дополнении"
+
+#: views/addons/category_landing.thtml:151
+msgid "addons_top_downloads"
+msgstr "Лидеры загрузок"
+
+#: views/addons/category_landing.thtml:165
+msgid "addons_top_rated"
+msgstr "Лидеры рейтинга"
+
+#: views/addons/versions.thtml:62
+msgid "addons_versions_careful"
+msgstr "Будьте оÑторожны Ñо Ñтарыми верÑиÑми"
+
+#: views/addons/versions.thtml:63
+msgid "addons_versions_careful_introduction"
+msgstr ""
+"Эти верÑии отображаютÑÑ Ñ‚Ð¾Ð»ÑŒÐºÐ¾ Ð´Ð»Ñ ÑÐ²ÐµÐ´ÐµÐ½Ð¸Ñ Ð¸ в целÑÑ… теÑтированиÑ. Вам "
+"Ñледует вÑегда иÑпользовать поÑледнюю верÑию дополнениÑ."
+
+#: controllers/addons_controller.php:1549
+msgid "addons_versions_history"
+msgstr "ИÑÑ‚Ð¾Ñ€Ð¸Ñ Ð²ÐµÑ€Ñий Ñо ÑпиÑком изменений"
+
+#. %1$s is the add-on name
+#: controllers/addons_controller.php:1535
+#, php-format
+msgid "addons_versions_pagetitle"
+msgstr "ИÑÑ‚Ð¾Ñ€Ð¸Ñ Ð²ÐµÑ€Ñий %1$s"
+
+#: controllers/groups_controller.php:71
+msgid "admin_group_add_pagetitle"
+msgstr "Добавить группу"
+
+#: controllers/groups_controller.php:111
+msgid "admin_group_delete_pagetitle"
+msgstr "Удалить группу"
+
+#. %s is a number to identify the group
+#: controllers/groups_controller.php:117
+#, php-format
+msgid "admin_group_deleted"
+msgstr "Группа Ñ Ð¸Ð´ÐµÐ½Ñ‚Ð¸Ñ„Ð¸ÐºÐ°Ñ‚Ð¾Ñ€Ð¾Ð¼ %s была удалена"
+
+#: controllers/groups_controller.php:89
+msgid "admin_group_edit_pagetitle"
+msgstr "Изменить группу"
+
+#: controllers/groups_controller.php:92 controllers/groups_controller.php:113
+msgid "admin_group_error_invalid_id"
+msgstr "Ðеправильный идентификатор группы"
+
+#: controllers/groups_controller.php:65
+msgid "admin_group_pagetitle"
+msgstr "ÐдминиÑтратор группы"
+
+#: controllers/groups_controller.php:77 controllers/groups_controller.php:99
+msgid "admin_group_saved"
+msgstr "Группа Ñохранена"
+
+#: views/elements/amo2009/search.thtml:257 views/elements/search.thtml:239
+msgid "advanced_search_form"
+msgstr "Дополнительно"
+
+#: views/elements/amo2009/search.thtml:126 views/elements/search.thtml:125
+msgid "advanced_search_form_any_time"
+msgstr "Ð’ любое времÑ"
+
+#: views/elements/amo2009/search.thtml:97
+#: views/elements/amo2009/search.thtml:110 views/elements/search.thtml:96
+#: views/elements/search.thtml:109
+msgid "advanced_search_form_any_type"
+msgstr "Любой"
+
+#: views/elements/amo2009/search.thtml:275 views/elements/search.thtml:254
+msgid "advanced_search_form_any_version"
+msgstr "любаÑ"
+
+#: views/elements/amo2009/search.thtml:217 views/elements/search.thtml:212
+msgid "advanced_search_form_application"
+msgstr "Приложение"
+
+#: views/elements/amo2009/search.thtml:143 views/elements/search.thtml:142
+msgid "advanced_search_form_keyword_match"
+msgstr "Ключевым Ñловам"
+
+#: views/elements/amo2009/search.thtml:251 views/elements/search.thtml:225
+msgid "advanced_search_form_lastupdate"
+msgstr "Были обновлены"
+
+#: views/elements/amo2009/search.thtml:145 views/elements/search.thtml:144
+msgid "advanced_search_form_name"
+msgstr "Имени"
+
+#: views/elements/amo2009/search.thtml:144 views/elements/search.thtml:143
+msgid "advanced_search_form_newest"
+msgstr "Ðовизне"
+
+#: views/elements/amo2009/search.thtml:130 views/elements/search.thtml:129
+msgid "advanced_search_form_past_3_months"
+msgstr "Ð’ поÑледние 3 меÑÑца"
+
+#: views/elements/amo2009/search.thtml:131 views/elements/search.thtml:130
+msgid "advanced_search_form_past_6_months"
+msgstr "Ð’ поÑледние 6 меÑÑцев"
+
+#: views/elements/amo2009/search.thtml:127 views/elements/search.thtml:126
+msgid "advanced_search_form_past_day"
+msgstr "Вчера"
+
+#: views/elements/amo2009/search.thtml:129 views/elements/search.thtml:128
+msgid "advanced_search_form_past_month"
+msgstr "Ð’ поÑледний меÑÑц"
+
+#: views/elements/amo2009/search.thtml:128 views/elements/search.thtml:127
+msgid "advanced_search_form_past_week"
+msgstr "Ð’ поÑледнюю неделю"
+
+#: views/elements/amo2009/search.thtml:132 views/elements/search.thtml:131
+msgid "advanced_search_form_past_year"
+msgstr "Ð’ поÑледний год"
+
+#: views/elements/amo2009/search.thtml:239 views/elements/search.thtml:230
+msgid "advanced_search_form_perpage"
+msgstr "Дополнений на Ñтранице"
+
+#: views/elements/amo2009/search.thtml:243 views/elements/search.thtml:224
+msgid "advanced_search_form_platform"
+msgstr "Платформа"
+
+#: views/elements/amo2009/search.thtml:147 views/elements/search.thtml:146
+msgid "advanced_search_form_popularity"
+msgstr "ПопулÑрноÑти"
+
+#: views/elements/amo2009/search.thtml:146 views/elements/search.thtml:145
+msgid "advanced_search_form_rating"
+msgstr "Рейтингу"
+
+#: views/elements/amo2009/search.thtml:247 views/elements/search.thtml:231
+msgid "advanced_search_form_sortby"
+msgstr "Сортировать по"
+
+#: views/elements/amo2009/search.thtml:227 views/elements/search.thtml:216
+msgid "advanced_search_form_to"
+msgstr "по"
+
+#: views/elements/amo2009/search.thtml:257 views/elements/search.thtml:237
+msgid "advanced_search_form_toggle_tooltip"
+msgstr "Включить продвинутый режим поиÑка"
+
+#: views/elements/amo2009/search.thtml:235 views/elements/search.thtml:223
+msgid "advanced_search_form_type"
+msgstr "Тип"
+
+#: views/elements/amo2009/search.thtml:222 views/elements/search.thtml:214
+msgid "advanced_search_form_version"
+msgstr "верÑÐ¸Ñ Ñ"
+
+#: views/elements/amo2009/pagination.thtml:42
+msgid "amo2009_pagination_next_page"
+msgstr "След."
+
+#: views/elements/amo2009/pagination.thtml:41
+msgid "amo2009_pagination_previous_page"
+msgstr "Пред."
+
+#: views/pages/js_constants.js.thtml:96
+msgid "app_compat_ignore_check"
+msgstr "Игнорировать проверку верÑии"
+
+#: views/pages/js_constants.js.thtml:72
+msgid "app_compat_older_firefox_only"
+msgstr "Это раÑширение работает Ñо Ñтарыми верÑиÑми Firefox"
+
+#. %1$s and %2$s are URLs
+#: views/pages/js_constants.js.thtml:74
+msgid "app_compat_older_version_or_ignore_check"
+msgstr ""
+"Ð’Ñ‹ можете <a href=\"%1$s\">попробовать иÑпользовать Ñтарую верÑию</a> или <a "
+"href=\"#\" onclick=\"%2$s\">проигнорировать Ñту проверку</a>"
+
+#. %1$s is a URL
+#: views/pages/js_constants.js.thtml:71
+msgid "app_compat_try_old_version"
+msgstr "Возможно будет работать <a href=\"%1$s\">ÑÑ‚Ð°Ñ€Ð°Ñ Ð²ÐµÑ€ÑиÑ</a>"
+
+#. %1$s is a URL
+#. %2$s is a version number. Example: 3.1
+#: views/pages/js_constants.js.thtml:73
+msgid "app_compat_unreleased_version"
+msgstr ""
+"Это раÑширение работает в ещё не выпущенной верÑии <a href=\"%1$s\">Firefox %"
+"2$s</a>"
+
+#: views/pages/js_constants.js.thtml:70
+msgid "app_compat_update_firefox"
+msgstr ""
+"Ð”Ð»Ñ Ð¸ÑÐ¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ Ñтого Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ <a href=\"http://getfirefox.com"
+"\">Обновите Firefox</a>"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#. %3$s is a status, like Public.
+#: controllers/components/audit.php:79
+msgid "audit_addon_status"
+msgstr "%1$s изменил ÑÑ‚Ð°Ñ‚ÑƒÑ %2$s на %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:221
+msgid "audit_admin_default"
+msgstr "%1$s произвёл неизвеÑтное админиÑтративное дейÑтвие %2$s Ñ ID %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:153
+msgid "audit_admin_feature_remove"
+msgstr "%1$s удалил возможноÑÑ‚ÑŒ %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is an application, like Firefox.
+#: controllers/components/audit.php:92
+msgid "audit_application_create"
+msgstr "%1$s Ñоздал приложение %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is an application, like Firefox.
+#: controllers/components/audit.php:95
+msgid "audit_application_edit"
+msgstr "%1$s отредактировал приложение %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a version number, like 3.5.
+#. %3$s is an application, like Firefox.
+#: controllers/components/audit.php:105
+msgid "audit_appversion_create"
+msgstr "%1$s Ñоздал верÑию %2$s Ð´Ð»Ñ %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a version number, like 3.5.
+#. %3$s is an application, like Firefox.
+#: controllers/components/audit.php:108
+msgid "audit_appversion_delete"
+msgstr "%1$s удалил верÑию %2$s Ð´Ð»Ñ %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a config field, like "awesomeness".
+#. %3$s is a config value, like "off".
+#. %4$s is a config value, like "on".
+#: controllers/components/audit.php:210
+msgid "audit_config"
+msgstr "%1$s изменил поле конфигурации '%2$s' Ñ '%3$s' на '%4$s'"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:258
+msgid "audit_editor_default"
+msgstr "%1$s произвёл неизвеÑтное редакторÑкое дейÑтвие %2$s Ñ ID %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#: controllers/components/audit.php:236
+msgid "audit_editor_feature_remove"
+msgstr "%1$s удалил дополнение %2$s из ÑпиÑка избранных"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#: controllers/components/audit.php:231
+msgid "audit_feature_add"
+msgstr "%1$s добавил дополнение %2$s в ÑпиÑок избранных"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:149
+msgid "audit_feature_edit"
+msgstr "%1$s изменил возможноÑÑ‚ÑŒ Ð´Ð»Ñ Ð»Ð¾ÐºÐ°Ð»Ð¸Ð·Ð°Ñ†Ð¸Ð¸ %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#: controllers/components/audit.php:241
+msgid "audit_feature_locale_change"
+msgstr "%1$s изменил локализации Ð´Ð»Ñ Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ %2$s в ÑпиÑке избранных"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:83
+msgid "audit_file_recalchash"
+msgstr "%1$s переÑчитал Ñ…Ñш Ð´Ð»Ñ Ñ„Ð°Ð¹Ð»Ð° %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>user name</a>
+#. %3$s is <a>group name</a>
+#: controllers/components/audit.php:182
+msgid "audit_group_addmember"
+msgstr "%1$s добавил %2$s в группу %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:313
+msgid "audit_group_associated"
+msgstr "%1$s ÑвÑзал ÑÐµÐ±Ñ Ñ %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:162
+msgid "audit_group_create"
+msgstr "%1s Ñоздал группу %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:170
+msgid "audit_group_delete"
+msgstr "%1$s удалил группу %2$s (ID %3$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:165
+msgid "audit_group_edit"
+msgstr "%1$s отредактировал группу %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>user name</a>
+#. %3$s is <a>group name</a>
+#: controllers/components/audit.php:188
+msgid "audit_group_removemember"
+msgstr "%1$s удалил %2$s из группы %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:280
+msgid "audit_l10n_default"
+msgstr "%1$s произвёл неизвеÑтное дейÑтвие %2$s, ID %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:295
+msgid "audit_modify_locked_group"
+msgstr "%1$s попыталÑÑ Ð¸Ð·Ð¼ÐµÐ½Ð¸Ñ‚ÑŒ заблокированную группу %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:299
+msgid "audit_modify_other_locale"
+msgstr "%1$s попыталÑÑ Ð¸Ð·Ð¼ÐµÐ½Ð¸Ñ‚ÑŒ переводы в %2$s без разрешениÑ"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a platform, like <a>Windows</a>
+#: controllers/components/audit.php:135
+msgid "audit_platform_create"
+msgstr "%1$s Ñоздал платформу %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a platform, like <a>Windows</a>
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:143
+msgid "audit_platform_delete"
+msgstr "%1$s удалил платформу %2$s (ID %3$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a platform, like <a>Windows</a>
+#: controllers/components/audit.php:138
+msgid "audit_platform_edit"
+msgstr "%1$s отредактировал платформу %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a part of the admin, like 'Site Config'
+#: controllers/components/audit.php:288
+msgid "audit_reauthentication_failure"
+msgstr "%1$s не удалоÑÑŒ произвеÑти повторный вход Ð´Ð»Ñ Ð´Ð¾Ñтупа к %2$s."
+
+#. %1$s is <a>user name</a>
+#. %2$s is the name of a canned response, like 'Ready for the public'
+#: controllers/components/audit.php:198
+msgid "audit_response_create"
+msgstr "%1$s Ñоздал ответ %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is the name of a canned response, like 'Ready for the public'
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:206
+msgid "audit_response_delete"
+msgstr "%1$s удалил ответ %2$s (ID %3$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is the name of a canned response, like 'Ready for the public'
+#: controllers/components/audit.php:201
+msgid "audit_response_edit"
+msgstr "%1$s отредактировал ответ %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:245
+msgid "audit_review_approve"
+msgstr "%1$s одобрил отзыв %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:250 controllers/components/audit.php:253
+msgid "audit_review_delete"
+msgstr "%1$s удалил отзыв %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:303
+msgid "audit_security_default"
+msgstr ""
+"%1$s произвёл неизвеÑтное дейÑтвие в ÑиÑтеме безопаÑноÑти %2$s Ñ ID %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a category name, like <a>Search Tools</a>
+#: controllers/components/audit.php:118
+msgid "audit_tag_create"
+msgstr "%1$s Ñоздал метку %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a category name, like <a>Search Tools</a>
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:126
+msgid "audit_tag_delete"
+msgstr "%1$s удалил категорию %2$s (ID %3$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a category name, like <a>Search Tools</a>
+#: controllers/components/audit.php:121
+msgid "audit_tag_edit"
+msgstr "%1$s отредактировал категорию %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:266
+msgid "audit_update_applications"
+msgstr "%1$s обновил переводы Ð¿Ñ€Ð¸Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ Ð´Ð»Ñ %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:277
+msgid "audit_update_blog"
+msgstr "%1$s обновил переводы поÑта в блоге Ð´Ð»Ñ %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:274
+msgid "audit_update_platforms"
+msgstr "%1$s обновил переводы платформы Ð´Ð»Ñ %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:270
+msgid "audit_update_tags"
+msgstr "%1$s обновил переводы категории Ð´Ð»Ñ %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>user name</a>
+#: controllers/components/audit.php:217
+msgid "audit_user_edit"
+msgstr "%1$s отредактировал информацию Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ %2$s"
+
+#: controllers/addons_controller.php:1012
+msgid "browse_addons_name"
+msgstr "Сортировать Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð¿Ð¾ имени"
+
+#: controllers/addons_controller.php:1010
+msgid "browse_addons_newest"
+msgstr "Ðовейшие дополнениÑ"
+
+#: controllers/addons_controller.php:1008
+msgid "browse_addons_popular"
+msgstr "ПопулÑрные дополнениÑ"
+
+#: controllers/addons_controller.php:1011
+msgid "browse_addons_rated"
+msgstr "Сортировать Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð¿Ð¾ рейтингу"
+
+#: controllers/addons_controller.php:1009
+msgid "browse_addons_updated"
+msgstr "Ðедавно обновлённые дополнениÑ"
+
+#: views/elements/categories.thtml:73 views/elements/categories.thtml:82
+msgid "categories_current_title"
+msgstr "Ð¢ÐµÐºÑƒÑ‰Ð°Ñ ÐºÐ°Ñ‚ÐµÐ³Ð¾Ñ€Ð¸Ñ"
+
+#: views/elements/categories.thtml:50
+#: views/elements/amo2009/categories.thtml:43
+#: views/elements/amo2009/categories.thtml:45
+msgid "categories_header"
+msgstr "Категории"
+
+#: views/elements/categories.thtml:50
+#: views/elements/amo2009/categories.thtml:41
+msgid "categories_header_title"
+msgstr "Выбрать категорию"
+
+# %1 is the category name
+#. %1$s is the category name
+#: views/addons/searchengines.thtml:129
+#, php-format
+msgid "category_extra_see_all"
+msgstr "ПроÑмотреть вÑÑŽ категорию %1$s"
+
+#. %1$s is a number.
+#: models/collection.php:130
+msgid "collection_description_limit"
+msgstr "ОпиÑание не может быть короче %1$s Ñимволов."
+
+#. %1$s is the name of the collection
+#: controllers/collections_controller.php:392
+msgid "collection_detail_rss_title"
+msgstr "Подборка %s"
+
+#: controllers/collections_controller.php:1065
+msgid "collection_error_deleting_addon"
+msgstr "Ошибка ÑƒÐ´Ð°Ð»ÐµÐ½Ð¸Ñ Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ!"
+
+#: controllers/collections_controller.php:1051
+msgid "collection_error_saving_addon"
+msgstr "Ошибка ÑохранениÑ!"
+
+#: controllers/collections_controller.php:1080
+msgid "collection_error_saving_comment"
+msgstr "Ошибка ÑÐ¾Ñ…Ñ€Ð°Ð½ÐµÐ½Ð¸Ñ ÐºÐ¾Ð¼Ð¼ÐµÐ½Ñ‚Ð°Ñ€Ð¸Ñ!"
+
+#. %1$s is a number.
+#: models/collection.php:122
+msgid "collection_name_limit"
+msgstr "Ð˜Ð¼Ñ Ð´Ð¾Ð»Ð¶Ð½Ð¾ быть короче %1$s Ñимволов."
+
+#: controllers/collections_controller.php:352
+#: controllers/collections_controller.php:487
+msgid "collection_not_found"
+msgstr "ÐšÐ¾Ð»Ð»ÐµÐºÑ†Ð¸Ñ Ð½Ðµ найдена!"
+
+#. %1$s is the text on the "create collection" button
+#: views/collections/add.thtml:91
+msgid "collections_add_formfield_addons_description"
+msgstr ""
+"ЕÑли вы уже знаете, какие Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð²Ñ‹ хотите добавить к Ñвоей подборке, "
+"проÑто начните набирать их имена в раÑположенном ниже поле. ЕÑли вы хотите "
+"подождать и Ñделать Ñто позже, щёлкните ÑÐµÐ¹Ñ‡Ð°Ñ Ð¿Ð¾ кнопке %1$s."
+
+#: views/collections/add.thtml:90
+msgid "collections_add_formfield_firstaddons"
+msgstr "Выберите ваши первые дополнениÑ"
+
+#: views/collections/add.thtml:48
+msgid "collections_add_header"
+msgstr "Создайте подборку"
+
+#: views/collections/add.thtml:97
+msgid "collections_add_header_selectedaddons"
+msgstr "Выбранные дополнениÑ"
+
+#: views/collections/add.thtml:50
+msgid "collections_add_intro"
+msgstr ""
+"Ð’Ñ‹ можете легко Ñоздать Ñвою ÑобÑтвенную подборку, заполнив неÑколько "
+"раÑположенных ниже полей."
+
+#: views/collections/add.thtml:92 views/collections/add.thtml:103
+msgid "collections_add_submit"
+msgstr "Создать подборку"
+
+#: views/pages/collector_faq.thtml:50 views/pages/collector_firstrun.thtml:43
+#: views/pages/collector.thtml:47 views/pages/collector_features.thtml:55
+#: controllers/search_controller.php:302
+#: controllers/collections_controller.php:206
+#: controllers/collections_controller.php:405
+#: controllers/collections_controller.php:467
+#: controllers/collections_controller.php:539
+msgid "collections_breadcrumb"
+msgstr "Подборки"
+
+#: views/collections/detail.thtml:185
+msgid "collections_detail_a_learn"
+msgstr "Подробнее"
+
+#: views/elements/amo2009/collection_add_form.thtml:53
+#: views/elements/amo2009/collections_js_init.thtml:68
+#: views/pages/collector_firstrun.thtml:64
+msgid "collections_detail_button_add"
+msgstr "Добавить в избранное"
+
+#: views/elements/amo2009/collection_add_form.thtml:50
+#: views/elements/amo2009/collections_js_init.thtml:71
+msgid "collections_detail_button_remove"
+msgstr "Удалить из избранного"
+
+#. %1$s is a URL.
+#. %2$s is a full <a href>.
+#: views/collections/detail.thtml:62
+msgid "collections_detail_created_desc"
+msgstr ""
+"<p>Чтобы поÑмотреть на вашу подборку, поÑмотрите вниз. ЕÑли вы хотите "
+"уÑтановить Ð´Ð»Ñ Ð¿Ð¾Ð´Ð±Ð¾Ñ€ÐºÐ¸ пÑевдоним, загрузить значок или изменить "
+"дополнительные наÑтройки, поÑетите Ñтраницу <a href='%1$s'>Управление "
+"подборками</a>.</p><p>Ваша подборка может быть открыта по Ñледующему "
+"адреÑу: %2$s</p>"
+
+#: views/collections/detail.thtml:61
+msgid "collections_detail_created_msg"
+msgstr "Ваша подборка готова!"
+
+#: views/collections/detail.thtml:109
+msgid "collections_detail_header_about"
+msgstr "Об Ñтой подборке"
+
+#. %1$s is a number.
+#: views/collections/detail.thtml:126
+msgid "collections_detail_header_count"
+msgid_plural "collections_detail_header_count"
+msgstr[0] "%1$s дополнение в Ñтой подборке"
+msgstr[1] "%1$s Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð² Ñтой подборке"
+msgstr[2] "%1$s дополнений в Ñтой подборке"
+
+#: views/collections/detail.thtml:113
+msgid "collections_detail_info_created"
+msgstr "<strong>Создано:</strong> %1$s"
+
+#: views/collections/detail.thtml:117
+msgid "collections_detail_info_updated"
+msgstr "<strong>Обновлено:</strong>"
+
+#: views/elements/amo2009/collections_js_init.thtml:62
+msgid "collections_detail_js_adding"
+msgstr "ДобавлÑÑŽ в Избранное&hellip;"
+
+#: views/elements/amo2009/collections_js_init.thtml:65
+msgid "collections_detail_js_removing"
+msgstr "УдалÑÑŽ из Избранного&hellip;"
+
+#. %1$s is a URL
+#: views/collections/detail.thtml:90
+msgid "collections_detail_login"
+msgstr "<a href=\"%1$s\">ЗарегиÑтрируйтеÑÑŒ</a> чтобы добавить Ñту подборку к "
+"Ñебе в Избранное."
+
+#: views/collections/detail.thtml:104
+msgid "collections_detail_manage"
+msgstr "Управление подборкой"
+
+#: controllers/collections_controller.php:298
+msgid "collections_detail_sort_date"
+msgstr "Дата добавлениÑ"
+
+#: controllers/collections_controller.php:299
+msgid "collections_detail_sort_name"
+msgstr "ИмÑ"
+
+#: controllers/collections_controller.php:300
+msgid "collections_detail_sort_popularity"
+msgstr "ПопулÑрноÑÑ‚ÑŒ"
+
+#. %1$s is a number.
+#: views/collections/detail.thtml:166
+msgid "collections_detail_weekly_downloads"
+msgid_plural "collections_detail_weekly_downloads"
+msgstr[0] "%1$s загрузка на Ñтой неделе"
+msgstr[1] "%1$s загрузки на Ñтой неделе"
+msgstr[2] "%1$s загрузок на Ñтой неделе"
+
+#: views/collections/edit.thtml:255
+msgid "collections_edit_addons_delete_noscript"
+msgstr "Выделенные Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð±ÑƒÐ´ÑƒÑ‚ удалены при нажатии кнопки Сохранить"
+
+#: views/collections/edit.thtml:247
+msgid "collections_edit_addons_description"
+msgstr ""
+"Чтобы добавить в Ñту подборку новые дополнениÑ, начните набирать их имена в "
+"раÑположенное ниже поле."
+
+#: views/collections/edit.thtml:248
+msgid "collections_edit_addons_description_noscript"
+msgstr ""
+"Чтобы добавить в Ñту подборку новые дополнениÑ, введите в раÑположенное ниже "
+"поле ÑпиÑок их ID, разделённый запÑтыми."
+
+#: views/collections/edit.thtml:247 views/collections/edit.thtml:248
+msgid "collections_edit_addons_description_publish_detailspage"
+msgstr "Ð’Ñ‹ также можете опубликовать дополнение прÑмо Ñ ÐµÐ³Ð¾ обычной Ñтраницы."
+
+#. %1$s is the date the add-on was added to the collection
+#. %1$s is the name of the user who added the add-on to the collection
+#: views/collections/edit.thtml:260
+msgid "collections_edit_addons_listitem_added"
+msgstr "Добавлено %1$s пользователем %2$s"
+
+#: views/collections/edit.thtml:263
+msgid "collections_edit_addons_listitem_comment_add"
+msgstr "Добавить комментарий опубликовавшего"
+
+#: views/collections/edit.thtml:266
+msgid "collections_edit_addons_listitem_comment_delete"
+msgstr "Удалить комментарий опубликовавшего"
+
+#: views/collections/edit.thtml:265
+msgid "collections_edit_addons_listitem_comment_edit"
+msgstr "Редактировать комментарий опубликовавшего"
+
+#: views/collections/edit.thtml:271
+msgid "collections_edit_addons_listitem_comment_note"
+msgstr ""
+"Примечание: Комментарий поÑвитÑÑ Ñ‚Ð°ÐºÐ¸Ð¼, как будто его напиÑал первоначальный "
+"автор Ñ Ð´Ð°Ñ‚Ð¾Ð¹ первоначальной публикации"
+
+#: views/collections/edit.thtml:270
+msgid "collections_edit_addons_listitem_comment_submit"
+msgstr "Сохранить комментарий"
+
+#: views/collections/edit.thtml:261
+msgid "collections_edit_addons_listitem_remove"
+msgstr "Удалить"
+
+#: views/collections/edit.thtml:250
+msgid "collections_edit_addons_submit"
+msgstr "Добавить в подборку"
+
+#: views/collections/edit.thtml:153
+msgid "collections_edit_check_nickname"
+msgstr "Проверить доÑтупноÑÑ‚ÑŒ"
+
+#: views/collections/edit.thtml:299
+msgid "collections_edit_confirm_deletecollection"
+msgstr "Да, Ñ Ñ…Ð¾Ñ‡Ñƒ удалить Ñту подборку."
+
+#. %1$s is the label of the edit form's submit button
+#: views/collections/edit.thtml:300
+msgid "collections_edit_confirm_deletecollection_description"
+msgstr ""
+"УÑтановите флажок, затем щёлкните по \"%1$s\" чтобы удалить Ñту подборку."
+
+#. %1$s is the "delete" submit button text
+#. %2$s is the title of the "advanced" tab
+#: views/collections/edit.thtml:95
+msgid "collections_edit_delete_upon_submit"
+msgstr ""
+"При нажатии раÑположенной ниже кнопки \"%1$s\" ваша подборка будет удалёна. "
+"ЕÑли вы не хотите ÑÐµÐ¹Ñ‡Ð°Ñ ÑƒÐ´Ð°Ð»ÑÑ‚ÑŒ вашу подборку, Ñнимите флажок в поле "
+"Ð¿Ð¾Ð´Ñ‚Ð²ÐµÑ€Ð¶Ð´ÐµÐ½Ð¸Ñ Ð²Ð¾ вкладке \"%2$s\" и продолжите редактировать Ñвою подборку. "
+"ЕÑли вы оÑтавите Ñту Ñтраницу и не Ñохраните её, ваша подборка также не "
+"будет удалёна."
+
+#: views/collections/edit.thtml:94
+msgid "collections_edit_delete_warning"
+msgstr "Ваша подборка ÑÐµÐ¹Ñ‡Ð°Ñ Ð±ÑƒÐ´ÐµÑ‚ удалёна!"
+
+#: views/collections/add.thtml:76 views/collections/edit.thtml:144
+msgid "collections_edit_form_error_description"
+msgstr "Ð’Ñ‹ должны дать опиÑание Ð´Ð»Ñ Ð²Ð°ÑˆÐµÐ¹ подборки."
+
+#: views/collections/edit.thtml:181
+msgid "collections_edit_form_error_icon"
+msgstr "При загрузке вашего значка произошла ошибка."
+
+#: views/collections/add.thtml:69 views/collections/edit.thtml:130
+msgid "collections_edit_form_error_name"
+msgstr "Ð’Ñ‹ должны дать Ð¸Ð¼Ñ Ð²Ð°ÑˆÐµÐ¹ подборке."
+
+#: views/collections/edit.thtml:158
+msgid "collections_edit_form_error_nickname"
+msgstr "ЕÑли вы выбираете ник, он должен быть уникальным."
+
+#: views/collections/add.thtml:93 views/collections/edit.thtml:249
+msgid "collections_edit_formfield_addons"
+msgstr "Ð˜Ð¼Ñ Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ:"
+
+#: views/collections/edit.thtml:281
+msgid "collections_edit_formfield_application"
+msgstr "СвÑзанное приложение"
+
+#: views/collections/edit.thtml:282
+msgid "collections_edit_formfield_application_description"
+msgstr "Выберите приложение, которое поддерживает вашу подборку."
+
+#: views/collections/edit.thtml:288
+msgid "collections_edit_formfield_collectiontype"
+msgstr "Тип подборки"
+
+#: views/collections/edit.thtml:295
+msgid "collections_edit_formfield_deletecollection"
+msgstr "Удалить подборку"
+
+#: views/collections/edit.thtml:296
+msgid "collections_edit_formfield_deletecollection_description"
+msgstr "При удалении вашей подборки она будет безвозвратно утерÑна."
+
+#: views/collections/add.thtml:73 views/collections/edit.thtml:140
+msgid "collections_edit_formfield_description"
+msgstr "ОпиÑание подборки"
+
+#: views/collections/add.thtml:74 views/collections/edit.thtml:141
+msgid "collections_edit_formfield_description_description"
+msgstr ""
+"Дайте краткое опиÑание вашей подборки и вида находÑщихÑÑ Ð² нём дополнений"
+
+#: views/collections/edit.thtml:162
+msgid "collections_edit_formfield_icon"
+msgstr "Значок"
+
+#: views/collections/edit.thtml:163
+msgid "collections_edit_formfield_icon_description"
+msgstr ""
+"Вы можете загрузить значок в форматах JPG, GIF или PNG, который будет "
+"приведён к размеру 32x32 пикÑелÑ."
+
+#: views/collections/add.thtml:80 views/collections/edit.thtml:189
+msgid "collections_edit_formfield_listed"
+msgstr "Кто может проÑматривать вашу подборку?"
+
+#: views/collections/add.thtml:81 views/collections/edit.thtml:190
+msgid "collections_edit_formfield_listed_description"
+msgstr ""
+"По умолчанию, подборка поÑвитÑÑ Ð² каталоге публичных подборок и будет "
+"доÑтупна Ð´Ð»Ñ Ð¿ÑƒÐ±Ð»Ð¸Ñ‡Ð½Ð¾Ð³Ð¾ проÑмотра. ЕÑли вы хотите, чтобы вашу подборку "
+"проÑматривали только те люди, которым была отправлена ÑÐ¿ÐµÑ†Ð¸Ð°Ð»ÑŒÐ½Ð°Ñ ÑÑылка, "
+"выберите раÑположенную ниже опцию."
+
+#: views/collections/add.thtml:84 views/collections/edit.thtml:193
+msgid "collections_edit_formfield_listed_false"
+msgstr "Только те, кого Ñ Ð¿Ñ€Ð¸Ð³Ð»Ð°ÑˆÑƒ, могут проÑматривать мою подборку"
+
+#: views/collections/add.thtml:83 views/collections/edit.thtml:192
+msgid "collections_edit_formfield_listed_true"
+msgstr "Любой человек может проÑматривать мою подборку в каталоге"
+
+#: views/collections/edit.thtml:223
+msgid "collections_edit_formfield_managers"
+msgstr "Кто может управлÑÑ‚ÑŒ моей подборкой?"
+
+#: views/collections/edit.thtml:224
+msgid "collections_edit_formfield_managers_description"
+msgstr ""
+"Данные пользователи могут добавлÑÑ‚ÑŒ Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð² вашу подборку, управлÑÑ‚ÑŒ "
+"вÑеми дополнениÑми и наÑтройками, и давать Ñ€Ð°Ð·Ñ€ÐµÑˆÐµÐ½Ð¸Ñ Ð´Ñ€ÑƒÐ³Ð¸Ð¼ пользователÑм."
+
+#: views/collections/add.thtml:66 views/collections/edit.thtml:126
+msgid "collections_edit_formfield_name"
+msgstr "Ð˜Ð¼Ñ Ð¿Ð¾Ð´Ð±Ð¾Ñ€ÐºÐ¸"
+
+#: views/collections/add.thtml:67 views/collections/edit.thtml:127
+msgid "collections_edit_formfield_name_description"
+msgstr ""
+"Дайте Ñвоей подборке наглÑдное опиÑание, например \"Полезные Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð´Ð»Ñ "
+"поездки в командировку от ВаÑи\""
+
+#: views/collections/edit.thtml:148
+msgid "collections_edit_formfield_nickname"
+msgstr "ПÑевдоним подборки"
+
+#: views/collections/edit.thtml:149
+msgid "collections_edit_formfield_nickname_description"
+msgstr ""
+"При желании, вы можете дать подборке уникальный пÑевдоним Ð´Ð»Ñ Ð±Ñ‹Ñтрого "
+"доÑтупа:"
+
+#: views/collections/edit.thtml:201
+msgid "collections_edit_formfield_publishers"
+msgstr "Кто может добавлÑÑ‚ÑŒ Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð² вашу подборку?"
+
+#: views/collections/edit.thtml:202
+msgid "collections_edit_formfield_publishers_description"
+msgstr ""
+"Данные пользователи могут добавлÑÑ‚ÑŒ Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð² вашу подборку и удалÑÑ‚ÑŒ "
+"Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ ÐºÐ¾Ñ‚Ð¾Ñ€Ñ‹Ðµ они добавили."
+
+#: views/collections/edit.thtml:210 views/collections/edit.thtml:232
+msgid "collections_edit_formfield_users_add"
+msgstr "Введите Ð°Ð´Ñ€ÐµÑ Ñл. почты учётной запиÑи Ñайта дополнений Firefox:"
+
+#: views/collections/edit.thtml:216 views/collections/edit.thtml:238
+msgid "collections_edit_formfield_users_delete_noscript"
+msgstr "Выбранные учётные запиÑи будут удалены при нажатии кнопки Сохранить"
+
+#: views/collections/edit.thtml:215 views/collections/edit.thtml:237
+msgid "collections_edit_formfield_users_new_noscript"
+msgstr ""
+"Введите разделённый запÑтыми ÑпиÑок адреÑов Ñл. почты учётных запиÑей Ñайта "
+"дополнений Firefox"
+
+#: views/collections/edit.thtml:204 views/collections/edit.thtml:226
+msgid "collections_edit_formfield_users_onlyme"
+msgstr "Только Ñ"
+
+#: views/collections/edit.thtml:205 views/collections/edit.thtml:227
+msgid "collections_edit_formfield_users_otherusers"
+msgstr "Я и Ñти пользователи:"
+
+#: views/collections/edit.thtml:211 views/collections/edit.thtml:233
+msgid "collections_edit_formfield_users_submit"
+msgstr "Добавить"
+
+#. %1$s is the name of the collection
+#: views/collections/edit.thtml:68
+msgid "collections_edit_header"
+msgstr "УправлÑÑ‚ÑŒ %1$s"
+
+#: views/collections/edit.thtml:246
+msgid "collections_edit_header_addons"
+msgstr "УправлÑÑ‚ÑŒ Ñодержимым подборки"
+
+#: views/collections/edit.thtml:253 views/collections/edit.thtml:258
+msgid "collections_edit_header_addons_current"
+msgstr "Текущие дополнениÑ:"
+
+#: views/collections/edit.thtml:279
+msgid "collections_edit_header_advanced"
+msgstr "Дополнительные наÑтройки"
+
+#: views/collections/edit.thtml:186
+msgid "collections_edit_header_permissions"
+msgstr "Управление разрешениÑми подборки"
+
+#: views/collections/edit.thtml:170
+msgid "collections_edit_icon_cancel"
+msgstr "Отмена"
+
+#: views/collections/edit.thtml:174 views/collections/edit.thtml:179
+msgid "collections_edit_icon_delete"
+msgstr "Удалить значок"
+
+#: views/collections/edit.thtml:178
+msgid "collections_edit_icon_replace"
+msgstr "Заменить значок"
+
+#. %1$s is the label of the edit form's submit button
+#: views/collections/edit.thtml:169
+msgid "collections_edit_icon_toberemoved"
+msgstr "Значок будет удалён поÑле Ð½Ð°Ð¶Ð°Ñ‚Ð¸Ñ Ñ€Ð°Ñположенной ниже кнопки \"%1$s\""
+
+#: views/collections/edit.thtml:155
+msgid "collections_edit_nickname_available"
+msgstr "ПÑевдоним доÑтупен"
+
+#: controllers/collections_controller.php:943
+msgid "collections_edit_nickname_error"
+msgstr ""
+"Ваш пÑевдоним Ñодержал недопуÑтимые Ñимволы и был иÑправлен. ПожалуйÑта, "
+"попробуйте ещё раз."
+
+#: views/collections/edit.thtml:156
+msgid "collections_edit_nickname_taken"
+msgstr "ПÑевдоним занÑÑ‚"
+
+#. This string is followed by a URL pointing to the collection's view page
+#: views/collections/edit.thtml:75
+msgid "collections_edit_saved_nextstep"
+msgstr "К вашей подборке можно получить доÑтуп по Ñледующему адреÑу:"
+
+#: views/collections/edit.thtml:74
+msgid "collections_edit_saved_success"
+msgstr "Ваша подборка была уÑпешно Ñохранёна!"
+
+#: views/collections/edit.thtml:169 views/collections/edit.thtml:300
+#: views/collections/edit.thtml:308 views/pages/js_constants.js.thtml:99
+msgid "collections_edit_submit"
+msgstr "Обновить подборку"
+
+#: views/collections/edit.thtml:96 views/collections/edit.thtml:297
+#: views/pages/js_constants.js.thtml:100
+msgid "collections_edit_submit_deletecollection"
+msgstr "Удалить подборку"
+
+#: views/collections/edit.thtml:111
+msgid "collections_edit_tabheader_addons"
+msgstr "ДополнениÑ"
+
+#: views/collections/edit.thtml:97 views/collections/edit.thtml:113
+msgid "collections_edit_tabheader_advanced"
+msgstr "Дополнительно"
+
+#: views/collections/edit.thtml:108
+msgid "collections_edit_tabheader_details"
+msgstr "Ð˜Ð¼Ñ Ð¸ подробноÑти"
+
+#: views/collections/edit.thtml:109
+msgid "collections_edit_tabheader_permissions"
+msgstr "РазрешениÑ"
+
+#: models/collection_promo.php:53
+msgid "collections_family_tagline"
+msgstr ""
+"ДополнениÑ, которые могут приÑматривать за вашими детьми и вашим раÑпиÑанием."
+
+#: models/collection_promo.php:53
+msgid "collections_family_title"
+msgstr "Ð¡ÐµÐ¼ÐµÐ¹Ð½Ð°Ñ Ð¶Ð¸Ð·Ð½ÑŒ"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:70
+msgid "collections_index_a_check_out"
+msgstr "ВзглÑните в Ñобиратель дополнений"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:52
+msgid "collections_index_a_create"
+msgstr "Создать подборку"
+
+#: views/collections/detail.thtml:139 views/collections/listing.thtml:85
+#: views/search/collections.thtml:84
+msgid "collections_index_button_go"
+msgstr "Перейти"
+
+#. %1$s is a URL.
+#: controllers/collections_controller.php:182
+msgid "collections_index_filler_favorites"
+msgstr ""
+"<p><strong>У Ð²Ð°Ñ Ð¿Ð¾ÐºÐ° нет ни одной избранной подборки.</strong></p> <p>С Ñтой "
+"Ñтраницы можно быÑтро открыть избранные вами подборки. Они также поÑвÑÑ‚ÑÑ "
+"в <a href='%1$s'>Собирателе дополнений</a>, еÑли вы его уÑтановили.</p>"
+
+#. %1$s is a URL.
+#: controllers/collections_controller.php:167
+msgid "collections_index_filler_mine"
+msgstr ""
+"<p>Ð’Ñ‹ пока не Ñоздали ни одной подборки. Ð’Ñ‹ можете легко Ñоздать подборки и "
+"заполнить их Ñвоими любимыми дополнениÑми. <a href='%1$s'>Попробуйте</a>!</p>"
+
+#: views/collections/listing.thtml:51
+msgid "collections_index_header_collections"
+msgstr "Подборки"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:60
+msgid "collections_index_header_collector"
+msgstr "Собиратель дополнений"
+
+#. %1$s is a comma-separated list of author names
+#: views/elements/amo2009/collection_listing_item.thtml:84
+#: views/collections/detail.thtml:151
+msgid "collections_index_header_created"
+msgstr "Ñоздан %1$s"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:47
+msgid "collections_index_header_what"
+msgstr "Что такое подборки?"
+
+#: views/collections/detail.thtml:132 views/collections/listing.thtml:78
+#: views/search/collections.thtml:66
+msgid "collections_index_label_sortby"
+msgstr "Сортировать по"
+
+#: controllers/collections_controller.php:130
+msgid "collections_index_li_editors"
+msgstr "Выбор редакторов"
+
+#: views/collections/subscribe.thtml:64
+#: controllers/collections_controller.php:140
+msgid "collections_index_li_favorites"
+msgstr "Мои любимые"
+
+#: controllers/collections_controller.php:138
+msgid "collections_index_li_mine"
+msgstr "Мои подборки"
+
+#: controllers/collections_controller.php:132
+msgid "collections_index_li_popular"
+msgstr "ПопулÑрные"
+
+#: views/search/collections.thtml:74 controllers/collections_controller.php:81
+msgid "collections_index_option_all"
+msgstr "Самые популÑрные за вÑÑ‘ времÑ"
+
+#: views/search/collections.thtml:72 controllers/collections_controller.php:78
+msgid "collections_index_option_month"
+msgstr "Самые популÑрные за Ñтот меÑÑц"
+
+#: views/search/collections.thtml:76 controllers/collections_controller.php:84
+msgid "collections_index_option_newest"
+msgstr "Ðовейшие"
+
+#: views/search/collections.thtml:70 controllers/collections_controller.php:75
+msgid "collections_index_option_week"
+msgstr "Самые популÑрные за Ñту неделю"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:67
+msgid "collections_index_p_collector"
+msgstr ""
+"Это новый ÑпоÑоб ÑƒÐ¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ð¸ поиÑка любимых дополнений. Ð’Ñ‹ можете "
+"поделитьÑÑ Ð¿Ð¾Ð´Ð±Ð¾Ñ€ÐºÐ°Ð¼Ð¸, Ñинхронизировать их и оÑтавлÑÑ‚ÑŒ к ним комментарии "
+"прÑмо из вашего браузера"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:48
+msgid "collections_index_p_what_are"
+msgstr "Подборки Ñто группы дополнений, которыми можно легко поделитьÑÑ."
+
+#. %s is a date in the _('date') format
+#: views/elements/collections_interactive_addon.thtml:85
+#, php-format
+msgid "collections_interactive_addon_added"
+msgstr "Добавлено %s"
+
+#: models/collection_promo.php:55
+msgid "collections_reference_tagline"
+msgstr "ДополнениÑ, которые помогут вам в онлайновых иÑÑледованиÑÑ…."
+
+#: models/collection_promo.php:55
+msgid "collections_reference_title"
+msgstr "СправочнаÑ"
+
+#: models/collection_promo.php:52
+msgid "collections_social_tagline"
+msgstr "Ð”Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð´Ð»Ñ ÑƒÐ¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ð²Ð°ÑˆÐ¸Ð¼Ð¸ Ñоциальными ÑетÑми."
+
+#: models/collection_promo.php:52
+msgid "collections_social_title"
+msgstr "Социальный круг"
+
+#: views/collections/subscribe.thtml:91
+msgid "collections_subscribe_button_close"
+msgstr "Закрыть"
+
+#: views/collections/subscribe.thtml:70
+msgid "collections_subscribe_error"
+msgstr ""
+"При попытке Ð´Ð¾Ð±Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ð¿Ð¾Ð´Ð±Ð¾Ñ€ÐºÐ¸ в избранные произошла ошибка. Может быть Ñта "
+"подборка уже в избранных?"
+
+#: views/collections/subscribe.thtml:96
+msgid "collections_subscribe_label_bothersome"
+msgstr "Больше не показывать мне Ñто Ñообщение."
+
+#. %1$s is the collection name
+#: views/collections/subscribe.thtml:60
+msgid "collections_subscribe_success"
+msgstr "%1$s была добавлена в ваши избранные подборки."
+
+#. %1$s is the link to the "My Favorites" tab on the main collections page
+#. %2$s is the localized title of the "My Favorites" tab
+#. %3$s is the link URL to the collector add-on
+#: views/collections/subscribe.thtml:62
+msgid "collections_subscribe_success_desc"
+msgstr ""
+"Ð’Ñ‹ можете быÑтро найти Ñту подборку через вкладку <a href=\"%1$s\">%2$s</a> "
+"в каталоге. Ð”Ð»Ñ ÐµÑ‰Ñ‘ более проÑтого ÑƒÐ¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ð²Ð°ÑˆÐ¸Ð¼Ð¸ избранными подборками, "
+"попробуйте наше раÑширение Ð´Ð»Ñ Firefox <a href=\"%3$s\">Собиратель "
+"дополнений</a>."
+
+#: views/collections/listing.thtml:55
+msgid "collections_success_delete"
+msgstr "Подборка была удалёна."
+
+#: models/collection_promo.php:54
+msgid "collections_travel_tagline"
+msgstr "ДополнениÑ, которые помогут вам в ваших путешеÑтвиÑÑ…."
+
+#: models/collection_promo.php:54
+msgid "collections_travel_title"
+msgstr "Ðабор путешеÑтвенника"
+
+#. A collection of add-ons that is automatically built for a user. They are "automatically published" to this collection.
+#: controllers/collections_controller.php:581
+msgid "collections_type_autopublisher"
+msgstr "Ðвто-публикатор"
+
+#. A collection that has been chosen by an Editor as notable or exceptional
+#: controllers/collections_controller.php:582
+msgid "collections_type_editorspick"
+msgstr "Выбор редакции"
+
+#: controllers/collections_controller.php:580
+msgid "collections_type_normal"
+msgstr "ÐормальнаÑ"
+
+#: views/collections/subscribe.thtml:84
+msgid "collections_unsubscribe_error"
+msgstr ""
+"При попытке ÑƒÐ´Ð°Ð»ÐµÐ½Ð¸Ñ Ð¿Ð¾Ð´Ð±Ð¾Ñ€ÐºÐ¸ из избранного произошла ошибка. Может быть Ñта "
+"подборка не была в избранном?"
+
+#. %1$s is the collection name
+#: views/collections/subscribe.thtml:78
+msgid "collections_unsubscribe_success"
+msgstr "%1$s была удалена из ваших избранных подборок."
+
+#: models/collection_promo.php:56
+msgid "collections_webdev_tagline"
+msgstr "ДополнениÑ, которые облегчат вам Ñоздание идеальных веб-Ñайтов."
+
+#: models/collection_promo.php:56
+msgid "collections_webdev_title"
+msgstr "Ðабор инÑтрументов веб-разработчика"
+
+#: views/elements/amo2009/collections_sidebar_whatare.thtml:40
+msgid "collections_whatare_header"
+msgstr "Что такое подборки?"
+
+#: views/elements/amo2009/collections_sidebar_whatare.thtml:45
+msgid "collections_whatare_learnmore"
+msgstr "Прочтите FAQ"
+
+#: views/elements/amo2009/collections_sidebar_whatare.thtml:44
+msgid "collections_whatare_text"
+msgstr ""
+"Это новый ÑпоÑоб ÑƒÐ¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ð¸ поиÑка любимых дополнений. Ð’Ñ‹ можете "
+"поделитьÑÑ Ð¿Ð¾Ð´Ð±Ð¾Ñ€ÐºÐ°Ð¼Ð¸, Ñинхронизировать их и оÑтавлÑÑ‚ÑŒ к ним комментарии "
+"прÑмо из вашего браузера"
+
+#: views/pages/collector_faq.thtml:61 views/pages/collector_features.thtml:67
+msgid "collector_features_a_home"
+msgstr "ДомашнÑÑ Ñтраница ÑÐ¾Ð±Ð¸Ñ€Ð°Ñ‚ÐµÐ»Ñ Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ð¹"
+
+#: views/elements/amo2009/collector_sidebar_download.thtml:46
+msgid "collector_features_heading_download"
+msgstr "Загрузите Ñобиратель дополнений:"
+
+#: views/elements/amo2009/collector_sidebar_download.thtml:43
+#: views/pages/collector_firstrun.thtml:116 views/pages/collector.thtml:69
+msgid "collector_features_img_logo"
+msgstr "Логотип ÑÐ¾Ð±Ð¸Ñ€Ð°Ñ‚ÐµÐ»Ñ Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ð¹"
+
+#: views/compatibility/dashboard.thtml:49
+#: controllers/compatibility_controller.php:72
+msgid "compatibility_dashboard_center_header"
+msgstr "Центр ÑовмеÑтимоÑти дополнений"
+
+#. %1$s is the name of an application and a version. Example: Firefox 3.0
+#. %2$s is the name of an application. Example: Firefox
+#: views/compatibility/dashboard.thtml:50
+msgid "compatibility_dashboard_intro"
+msgstr ""
+"Будьте готовы к выходу %1$s, иÑÐ¿Ð¾Ð»ÑŒÐ·ÑƒÑ Ð½Ð¸Ð¶ÐµÑледующие инÑтрументы и "
+"информацию, доÑтупную Ð´Ð»Ñ ÑообщеÑтва разработчиков дополнений %2$s."
+
+#: views/compatibility/dashboard.thtml:103
+msgid "compatibility_dashboard_loading"
+msgstr "Загрузка данных..."
+
+#: views/compatibility/dashboard.thtml:45
+msgid "compatibility_dashboard_main_link"
+msgstr "ВернутьÑÑ Ð½Ð° главную"
+
+#: views/compatibility/dashboard.thtml:100 views/compatibility/report.thtml:43
+msgid "compatibility_dashboard_report"
+msgstr "Отчёт о ÑовмеÑтимоÑти дополнений"
+
+#: views/compatibility/dashboard.thtml:53
+#: views/compatibility/dashboard.thtml:110
+#: views/compatibility/developers.thtml:43
+msgid "compatibility_developer_info"
+msgstr "Ð˜Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð´Ð»Ñ Ñ€Ð°Ð·Ñ€Ð°Ð±Ð¾Ñ‚Ñ‡Ð¸ÐºÐ¾Ð² дополнений"
+
+#: views/compatibility/developers.thtml:66
+msgid "compatibility_developers_adjust_maxversion"
+msgstr "Изменить maxVersion без загрузки"
+
+#: views/compatibility/dashboard.thtml:124
+msgid "compatibility_developers_check_status"
+msgstr "Проверить ÑÑ‚Ð°Ñ‚ÑƒÑ Ð¼Ð¾Ð¸Ñ… дополнений"
+
+#. %1$s is a URL
+#. %2$s is an application and version. Example: Firefox 3.0
+#: views/compatibility/dashboard.thtml:126
+msgid "compatibility_developers_login_first"
+msgstr ""
+"ЕÑли вы размещали Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð½Ð° Ñайте дополнений Mozilla, <a href=\"%1$s\"> "
+"пожалуйÑта войдите</a> и проанализируйте ÑÑ‚Ð°Ñ‚ÑƒÑ Ð²Ð°ÑˆÐ¸Ñ… дополнений Ð´Ð»Ñ %2$s."
+
+#: views/compatibility/dashboard.thtml:114
+msgid "compatibility_developers_mdclogo_alt"
+msgstr "Логотип Центра Разработки Mozilla"
+
+#: views/compatibility/developers.thtml:73
+msgid "compatibility_developers_no_addons"
+msgstr "Ð’Ñ‹ не размеÑтили ни одного Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð½Ð° Ñайте дополнений Mozilla."
+
+#: views/compatibility/dashboard.thtml:133
+#: views/compatibility/developers.thtml:55
+msgid "compatibility_developers_results"
+msgstr "Результаты проверки ÑтатуÑа дополнений"
+
+#: views/compatibility/dashboard.thtml:137
+msgid "compatibility_developers_retrieving"
+msgstr "Получение ÑтатуÑа размещённых дополнений..."
+
+#. %1$s is a number
+#. %2$s is an application name
+#. %3$s is a number.
+#. Full example: 50 Firefox users (10% of total)
+#: views/compatibility/developers.thtml:65
+msgid "compatibility_developers_user_count"
+msgstr "%1$s %2$s пользователей (%3$s&#37; от общего кол-ва)"
+
+#: views/compatibility/report.thtml:45
+msgid "compatibility_report_detail_intro"
+msgstr ""
+"По ÑведениÑм Mozilla, Ð´Ð¾Ð»Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»ÐµÐ¹ перечиÑленных ниже дополнений "
+"ÑоÑтавлÑет 95% от общего чиÑла пользователей дополнений. Данные Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ "
+"отÑортированы по количеÑтву иÑпользующих их пользователей."
+
+#: views/compatibility/dashboard.thtml:94
+msgid "compatibility_report_detailed_link"
+msgstr "ПроÑмотреть подробный отчёт"
+
+#. %1$s and %2$s are numbers
+#. %3$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:65
+msgid "compatibility_report_intro"
+msgstr ""
+"Из %1$s дополнений, иÑпользуемых 95&#37; пользователей дополнений, <b>%2"
+"$s&#37;</b> ÑчитаютÑÑ Ð² данный момент ÑовмеÑтимыми Ñ Ð¿Ð¾Ñледними Ñборками %3"
+"$s."
+
+#: views/compatibility/dashboard.thtml:81
+msgid "compatibility_report_legend_alpha"
+msgstr "Ðльфа-верÑии"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:81
+msgid "compatibility_report_legend_alpha_description"
+msgstr "ДополнениÑ, ÑовмеÑтимые Ñ Ð°Ð»ÑŒÑ„Ð°-верÑией %1$s"
+
+#: views/compatibility/dashboard.thtml:85
+msgid "compatibility_report_legend_beta"
+msgstr "Бета-верÑии"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:85
+msgid "compatibility_report_legend_beta_description"
+msgstr "ДополнениÑ, ÑовмеÑтимые Ñ Ð±ÐµÑ‚Ð°-верÑией или релиз-кандидатом %1$s"
+
+#: views/compatibility/dashboard.thtml:89
+msgid "compatibility_report_legend_latest"
+msgstr "ПоÑледнÑÑ Ð²ÐµÑ€ÑиÑ"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:89
+msgid "compatibility_report_legend_latest_description"
+msgstr "ДополнениÑ, ÑовмеÑтимые Ñ Ð¿Ð¾Ñледними Ñборками %1$s"
+
+#: views/compatibility/dashboard.thtml:77
+msgid "compatibility_report_legend_other"
+msgstr "Другие верÑии"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:77
+msgid "compatibility_report_legend_other_description"
+msgstr "ДополнениÑ, не ÑовмеÑтимые ни Ñ ÐºÐ°ÐºÐ¾Ð¹ верÑией %1$s"
+
+#: views/compatibility/dashboard.thtml:62
+msgid "compatibility_report_title"
+msgstr "Отчёт о ÑовмеÑтимоÑти дополнений"
+
+#: views/compatibility/dashboard.thtml:54
+#: views/compatibility/dashboard.thtml:144 views/compatibility/users.thtml:42
+msgid "compatibility_user_info"
+msgstr "Ð˜Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð´Ð»Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»ÐµÐ¹ дополнений"
+
+#: views/compatibility/dashboard.thtml:52
+msgid "compatibility_view_report"
+msgstr "ПроÑмотр отчёта о ÑовмеÑтимоÑти"
+
+#. %s is a URL
+#: views/pages/credits.thtml:142
+#, php-format
+msgid "credits_contributing"
+msgstr ""
+"Ð”Ð»Ñ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ñ Ð´Ð¾Ð¿Ð¾Ð»Ð½Ð¸Ñ‚ÐµÐ»ÑŒÐ½Ð¾Ð¹ информации отноÑительно ÑодейÑтвиÑ, пожалуйÑта "
+"Ñм. нашу %s."
+
+#: views/pages/credits.thtml:142
+msgid "credits_contributing_wikipage"
+msgstr "Ñтраничку Wiki"
+
+#: views/pages/credits.thtml:99
+msgid "credits_intro"
+msgstr ""
+"Mozilla хотела бы поблагодарить Ñледующих людей за их ÑодейÑтвие проекту "
+"addons.mozilla.org в течение вÑех Ñтих лет:"
+
+#: views/pages/credits.thtml:103
+msgid "credits_section_developers"
+msgstr "Разработчики"
+
+#: views/pages/credits.thtml:115
+msgid "credits_section_editors"
+msgstr "Редакторы"
+
+#: views/pages/credits.thtml:109
+msgid "credits_section_localizers"
+msgstr "Локализаторы"
+
+#: views/pages/credits.thtml:121
+msgid "credits_section_other_contributors"
+msgstr "Другие учаÑтники"
+
+#: views/pages/credits.thtml:127
+msgid "credits_section_past_developers"
+msgstr "Прошлые разработчики"
+
+#: views/pages/credits.thtml:133
+msgid "credits_section_software"
+msgstr "ПО и изображениÑ"
+
+#: views/pages/credits.thtml:136
+msgid "credits_software_famfamfam"
+msgstr ""
+"Ðекоторые иÑпользованные значки входÑÑ‚ в <a href=\"http://www.famfamfam.com/"
+"lab/icons/silk/\">набор иконок famfamfam Silk</a>, лицензированный на "
+"уÑловиÑÑ… <a href=\"http://creativecommons.org/licenses/by/2.5/\">Creative "
+"Commons Attribution 2.5 License</a>."
+
+#: views/pages/credits.thtml:137
+msgid "credits_software_timeplot"
+msgstr ""
+"Ðекоторые Ñтраницы иÑпользуют Ñлементы <a href=\"http://www.simile-widgets."
+"org/timeplot/\">Timeplot</a>, лицензированного на уÑловиÑÑ… <a href=\"http://"
+"simile.mit.edu/license.html\">BSD License</a>."
+
+# date format string as used in PHP's strftime():
+# http://php.net/strftime
+#. date format string as used in PHP's strftime():
+#. http://php.net/strftime
+#: views/elements/collections_interactive_addon.thtml:85
+#: views/elements/amo2009/addon_version_detail.thtml:53
+#: views/elements/amo2009/homepage_addon.thtml:115
+#: views/elements/addon_version_detail.thtml:54
+#: views/elements/addon_listitem.thtml:124 views/elements/feature.thtml:106
+#: views/collections/detail.thtml:118 views/collections/edit.thtml:325
+#: views/users/info.thtml:76 views/editors/reviews_queue.thtml:57
+#: views/editors/reviews_queue.thtml:68 views/developers/dashboard.thtml:65
+#: views/developers/versions_edit.thtml:208 views/developers/versions.thtml:67
+#: views/search/rss/index.thtml:5 views/addons/rss/versions.thtml:42
+#: views/addons/display.thtml:104 views/addons/display.thtml:356
+#: views/addons/browse_thumbs.thtml:75 views/reviews/add.thtml:63
+#: views/reviews/display.thtml:74 views/reviews/display.thtml:160
+#: views/reviews/delete.thtml:54 controllers/statistics_controller.php:244
+#: controllers/collections_controller.php:1047
+msgid "date"
+msgstr "%e %B %Y"
+
+# date and time format string (strftime)
+#. date and time format string (strftime)
+#. http://php.net/strftime
+#: views/elements/addon_version_detail.thtml:53
+#: views/developers/discuss.thtml:52 views/developers/discuss.thtml:62
+#: views/admin/addons_status.thtml:57
+msgid "datetime"
+msgstr "%e %B %Y, %H:%M"
+
+#: views/elements/developers/actionbar.thtml:47
+msgid "devcp_actionbar_link_details"
+msgstr "Подробнее"
+
+#: views/elements/developers/actionbar.thtml:42
+#: views/elements/developers/actionbar.thtml:50
+#: views/developers/dashboard.thtml:64
+msgid "devcp_actionbar_link_edit"
+msgstr "Редактировать дополнение"
+
+#: views/elements/developers/actionbar.thtml:51
+msgid "devcp_actionbar_link_newversion"
+msgstr "Загрузить новую верÑию"
+
+#: views/elements/developers/actionbar.thtml:44
+#: views/elements/developers/actionbar.thtml:49
+#: views/developers/dashboard.thtml:73
+msgid "devcp_actionbar_link_stats"
+msgstr "Панель ÑтатиÑтики"
+
+#. %1$s is a filename, e.g. "foo.txt"
+#. %2$s is the extension, e.g. ".txt"
+#. %3$s is a list of valid extensions, like ".png, .jpg, .gif"
+#: controllers/developers_controller.php:1361
+msgid "devcp_add_previews_extension_error"
+msgstr ""
+"Файл %1$s имеет неверное раÑширение (%2$s). ДопуÑтимые раÑширениÑ: %3$s"
+
+#. %s is the filename.
+#: controllers/developers_controller.php:1394
+msgid "devcp_add_previews_save_error"
+msgstr ""
+"Файл %s не удалоÑÑŒ Ñохранить в базу данных. ПожалуйÑта, попробуйте Ñнова."
+
+#. %1$s is the preview ID number, %2$s is the filename.
+#: controllers/developers_controller.php:1389
+msgid "devcp_add_previews_success_replace"
+msgstr "ПредпроÑмотр %1$s был уÑпешно заменён файлом %2$s."
+
+#. %s is the filename.
+#: controllers/developers_controller.php:1391
+msgid "devcp_add_previews_success_upload"
+msgstr "Файл %s был уÑпешно загружен. Ð’Ñ‹ можете добавить к нему опиÑание."
+
+#: controllers/components/developers.php:1163
+msgid "devcp_additem_addontype_autodetect"
+msgstr "ÐвтоматичеÑкое определение"
+
+#: views/elements/developers/additem.thtml:76
+msgid "devcp_additem_linktitle_opensin_newwindow"
+msgstr "Открыть в новом окне"
+
+#: views/elements/developers/additem.thtml:41
+msgid "devcp_additem_sidebar_title"
+msgstr "Отправить дополнение"
+
+#: views/elements/developers/additem.thtml:53
+msgid "devcp_additem_step0_newlink"
+msgstr "Соглашение разработчика"
+
+#: views/elements/developers/additem.thtml:46
+msgid "devcp_additem_step1_link"
+msgstr "Шаг 1: Загрузка на Ñервер"
+
+#: views/elements/developers/additem.thtml:47
+msgid "devcp_additem_step2_link"
+msgstr "Шаг 2: Ð˜Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¾ дополнении"
+
+#: views/elements/developers/additem.thtml:48
+msgid "devcp_additem_step3_link"
+msgstr "Шаг 3: Ð˜Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¾ новой верÑии"
+
+#: views/elements/developers/additem.thtml:49
+msgid "devcp_additem_step4_link"
+msgstr "Шаг 4: Переводы на другие Ñзыки"
+
+#: views/elements/developers/additem.thtml:50
+msgid "devcp_additem_step5_link"
+msgstr "Шаг 5: Завершение"
+
+#: views/elements/developers/additem.thtml:76
+msgid "devcp_additem_submissionhelp_link"
+msgstr "Помощь по публикации"
+
+#: controllers/previews_controller.php:168
+#: controllers/previews_controller.php:277
+msgid "devcp_addon_field_preview_caption_displaytitle"
+msgstr "ПодпиÑÑŒ к Ñкриншоту"
+
+#: views/developers/addon_status.thtml:177
+msgid "devcp_addon_status_action_activate"
+msgstr "Сделать активным"
+
+#: views/developers/addon_status.thtml:178
+msgid "devcp_addon_status_action_activate_description"
+msgstr ""
+"Делает ваше дополнение активным, чтобы отобразить его в публичных ÑпиÑках и "
+"включить Ñлужбу проверки обновлений."
+
+#: views/developers/addon_status.thtml:135
+msgid "devcp_addon_status_action_complete"
+msgstr "Закончить оформление"
+
+#: views/developers/addon_status.thtml:136
+msgid "devcp_addon_status_action_complete_description"
+msgstr "Закончить оформление вашего Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð¸ перемеÑтить его в пеÑочницу"
+
+#: views/developers/addon_status.thtml:181
+msgid "devcp_addon_status_action_deactivate"
+msgstr "Сделать неактивным"
+
+#: views/developers/addon_status.thtml:182
+msgid "devcp_addon_status_action_deactivate_description"
+msgstr ""
+"Делает ваше дополнение неактивным, чтобы убрать его из вÑех публичных "
+"ÑпиÑков и отключить Ñлужбу проверки обновлений."
+
+#: views/developers/addon_status.thtml:143
+msgid "devcp_addon_status_action_move"
+msgstr "ПеремеÑтить в пеÑочницу"
+
+#: views/developers/addon_status.thtml:144
+msgid "devcp_addon_status_action_move_description"
+msgstr "Перемещает ваше дополнение назад в ПеÑочницу. Это обратимое дейÑтвие."
+
+#: views/developers/addon_status.thtml:139
+msgid "devcp_addon_status_action_nominate"
+msgstr "Ðоминировать на публичный доÑтуп"
+
+#: views/developers/addon_status.thtml:140
+msgid "devcp_addon_status_action_nominate_description"
+msgstr "Ðоминирует ваше дополнение на публичный доÑтуп"
+
+#: views/developers/addon_status.thtml:147
+msgid "devcp_addon_status_action_public"
+msgstr "Сделать публичным"
+
+#: views/developers/addon_status.thtml:148
+msgid "devcp_addon_status_action_public_description"
+msgstr "Снова делает ваше дополнение публичным."
+
+#: views/developers/addon_status.thtml:169
+msgid "devcp_addon_status_active"
+msgstr ""
+"Ваше дополнение ÑвлÑетÑÑ <span class=\"inactive-0\">Ðктивным</span>. Это "
+"значит, что ваше дополнение поÑвлÑетÑÑ Ð²Ð¾ вÑех доÑтупных перечнÑÑ… "
+"дополнений, подходÑщих Ð´Ð»Ñ ÑƒÐºÐ°Ð·Ð°Ð½Ð½Ð¾Ð³Ð¾ выше ÑтатуÑа."
+
+#: views/developers/addon_status.thtml:111
+msgid "devcp_addon_status_completion_disabled"
+msgstr ""
+"Ð”Ð»Ñ Ð·Ð°Ð²ÐµÑ€ÑˆÐµÐ½Ð¸Ñ Ð¾Ñ„Ð¾Ñ€Ð¼Ð»ÐµÐ½Ð¸Ñ Ð²Ð°ÑˆÐµÐ³Ð¾ Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð¸ Ð¿ÐµÑ€ÐµÐ¼ÐµÑ‰ÐµÐ½Ð¸Ñ ÐµÐ³Ð¾ в <span class="
+"\"status-1\">ПеÑочницу</span> выполните указанные выше уÑловиÑ."
+
+#: views/developers/addon_status.thtml:108
+msgid "devcp_addon_status_completion_enabled"
+msgstr ""
+"Теперь вы можете завершить оформление вашего Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð¸ перемеÑтить его в "
+"<span class=\"status-1\">ПеÑочницу</span>, нажав раÑположенную ниже кнопку."
+
+#: views/developers/addon_status.thtml:102
+msgid "devcp_addon_status_criteria_category"
+msgstr "Выбрана по меньшей мере одна категориÑ"
+
+#: views/developers/addon_status.thtml:101
+msgid "devcp_addon_status_criteria_description"
+msgstr "ТребуетÑÑ Ð¾Ð¿Ð¸Ñание дополнениÑ"
+
+#: views/developers/addon_status.thtml:99
+msgid "devcp_addon_status_criteria_name"
+msgstr "ТребуетÑÑ Ð¸Ð¼Ñ Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ"
+
+#: views/developers/addon_status.thtml:120
+msgid "devcp_addon_status_criteria_prerelease"
+msgstr "Дополнение не помечено как пререлиз."
+
+#: views/developers/addon_status.thtml:119
+msgid "devcp_addon_status_criteria_preview"
+msgstr "Ð”Ð»Ñ Ñ€Ð°Ñширений и тем требуетÑÑ Ð¿Ð¾ меньшей мере один Ñкриншот."
+
+#: views/developers/addon_status.thtml:100
+msgid "devcp_addon_status_criteria_summary"
+msgstr "ТребуетÑÑ Ð¾Ð¿Ð¸Ñание дополнениÑ"
+
+#. %s is the status in a span, e.g. "<span>_('Public')</span>".
+#: views/developers/addon_status.thtml:58
+msgid "devcp_addon_status_header"
+msgstr "Ð¡Ñ‚Ð°Ñ‚ÑƒÑ Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ: %s"
+
+#: views/developers/addon_status.thtml:152
+#: views/developers/addon_status.thtml:173
+msgid "devcp_addon_status_header_actions"
+msgstr "ДоÑтупные дейÑтвиÑ"
+
+#: views/developers/addon_status.thtml:168
+msgid "devcp_addon_status_header_active"
+msgstr "Ðктивный ÑтатуÑ: <span class=\"inactive-0\">Ðктивный</span>"
+
+#: views/developers/addon_status.thtml:97
+msgid "devcp_addon_status_header_criteria"
+msgstr "Критерий Ð¾Ñ„Ð¾Ñ€Ð¼Ð»ÐµÐ½Ð¸Ñ Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ"
+
+#: views/developers/addon_status.thtml:164
+msgid "devcp_addon_status_header_inactive"
+msgstr "Ðктивный ÑтатуÑ: <span class=\"inactive-1\">Ðеактивный</span>"
+
+#: views/developers/addon_status.thtml:117
+msgid "devcp_addon_status_header_nomination"
+msgstr "Критерий номинации на публичный доÑтуп"
+
+#: views/developers/addon_status.thtml:190
+msgid "devcp_addon_status_header_trusted"
+msgstr "Доверенный ÑтатуÑ: <span class=\"status-4\">Доверенный</span>"
+
+#: views/developers/addon_status.thtml:165
+msgid "devcp_addon_status_inactive"
+msgstr ""
+"Ваше дополнение ÑвлÑетÑÑ <span class=\"inactive-1\">Ðеактивным</span>. Это "
+"значит, что ваше дополнение не поÑвитÑÑ Ð½Ð¸ в одном из перечней дополнений, "
+"незавиÑимо от указанного выше ÑтатуÑа. ÐžÐ±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ð´Ð»Ñ Ð²Ð°ÑˆÐµÐ³Ð¾ Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ "
+"через Ñлужбу проверки обновлений предоÑтавлÑÑ‚ÑŒÑÑ <b>не</b> будут."
+
+#: views/developers/addon_status.thtml:128
+msgid "devcp_addon_status_nominate_disabled"
+msgstr ""
+"ПожалуйÑта, выполните вышеуказанные критерии перед номинированием вашего "
+"Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð½Ð° <span class=\"status-4\">Публичный доÑтуп</span>."
+
+#: views/developers/addon_status.thtml:125
+msgid "devcp_addon_status_nominate_enabled"
+msgstr ""
+"Вы можете номинировать ваше дополнение на <span class=\"status-4\">Публичный "
+"доÑтуп</span> щёлкнув по раÑположенной ниже кнопке."
+
+#: views/developers/addon_status.thtml:64
+msgid "devcp_addon_status_public"
+msgstr "Публичное"
+
+#: views/developers/addon_status.thtml:63
+msgid "devcp_addon_status_sandbox"
+msgstr "ПеÑочница"
+
+#. %s is an email address.
+#: views/developers/addon_status.thtml:89
+msgid "devcp_addon_status_switch_disabled"
+msgstr ""
+"Ваше дополнение было <span class=\"status-5\">Отключено</span> "
+"админиÑтратором и не может быть иÑпользовано. ЕÑли у Ð²Ð°Ñ Ð²Ð¾Ð·Ð½Ð¸ÐºÐ»Ð¸ вопроÑÑ‹, "
+"вы можете ÑвÑзатьÑÑ Ñ Ð½Ð¸Ð¼ по адреÑу %s."
+
+#: views/developers/addon_status.thtml:67
+msgid "devcp_addon_status_switch_incomplete"
+msgstr ""
+"Ваше дополнение ÑвлÑетÑÑ <span class=\"status-0\">Ðезавершённым</span>. Это "
+"значит, что ваше дополнение не поÑвлÑетÑÑ Ð½Ð¸ на Ñайте, ни в Ñлужбе проверки "
+"обновлений. Ð’Ñ‹ можете вернутьÑÑ Ðº Ñтой Ñтранице, чтобы завершить оформление "
+"вашего дополнениÑ, поÑле того, как оно Ñтанет ÑоответÑтвовать указанным ниже "
+"уÑловиÑм, и перенеÑти его в <span class=\"status-1\">ПеÑочницу</span>."
+
+#. %s is a number, perhaps 42.
+#: views/developers/addon_status.thtml:77
+msgid "devcp_addon_status_switch_nominated"
+msgstr ""
+"Ð’ данное Ð²Ñ€ÐµÐ¼Ñ Ð²Ð°ÑˆÐµ дополнение номинировано на <span class=\"status-4\"> "
+"Публичный доÑтуп</span> и ждёт рецензии от редактора. Ð’ очереди на номинацию "
+"в данный момент Ñтоит %s других дополнений."
+
+#. %s is an email address.
+#: views/developers/addon_status.thtml:81
+msgid "devcp_addon_status_switch_pending"
+msgstr ""
+"Ваше дополнение находитÑÑ Ð² ÑоÑтоÑнии ожиданиÑ. Этого не должно ÑлучитьÑÑ. "
+"ПожалуйÑта, отправьте пиÑьмо по адреÑу %s, указав ID вашего Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð¸ Ñту "
+"ошибку."
+
+#: views/developers/addon_status.thtml:85
+msgid "devcp_addon_status_switch_public"
+msgstr ""
+"Ваше дополнение ÑвлÑетÑÑ <span class=\"status-4\">Публичным</span>. Это "
+"значит, что оно поÑвитÑÑ Ð²Ð¾ вÑех перечнÑÑ… и результатах поиÑка и может быть "
+"загружено без ограничениÑ. ÐžÐ±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ð´Ð»Ñ Ð²Ð°ÑˆÐµÐ³Ð¾ Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð±ÑƒÐ´ÑƒÑ‚ обеÑпечены "
+"через Ñлужбу проверки обновлений."
+
+#: views/developers/addon_status.thtml:71
+#: views/developers/addon_status.thtml:75
+msgid "devcp_addon_status_switch_sandbox"
+msgstr ""
+"Ваше дополнение находитÑÑ Ð² <span class=\"status-1\">ПеÑочнице</span>. Это "
+"значит, что оно поÑвитÑÑ Ð² перечнÑÑ… и результатах поиÑка, но Ð´Ð»Ñ ÐµÐ³Ð¾ "
+"загрузки пользователÑм будет нужно зарегиÑтрироватьÑÑ Ð½Ð° Ñайте. ÐžÐ±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ "
+"Ð´Ð»Ñ Ð²Ð°ÑˆÐµÐ³Ð¾ Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ñ‡ÐµÑ€ÐµÐ· Ñлужбу проверки обновлений предоÑтавлÑÑ‚ÑŒÑÑ "
+"<b>не</b> будут."
+
+#. %s is the add-on name.
+#: views/developers/addon_status_nominate.thtml:43
+#: views/developers/addon_status_confirm.thtml:43
+#: views/developers/addon_status.thtml:43
+msgid "devcp_addon_status_title"
+msgstr "Ð¡Ñ‚Ð°Ñ‚ÑƒÑ %s"
+
+#: views/developers/addon_status.thtml:191
+msgid "devcp_addon_status_trusted"
+msgstr ""
+"Ваше дополнение ÑвлÑетÑÑ <span class=\"status-4\">Доверенным</span>. Это "
+"значит, что Ð´Ð»Ñ Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ð²Ð°ÑˆÐµÐ³Ð¾ Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð½ÐµÑ‚ необходимоÑти получать "
+"отзыв от редактора."
+
+#: views/developers/dashboard.thtml:68
+msgid "devcp_dashboard_active"
+msgstr "Ðктивное"
+
+#. %1$s is the add-on type string
+#. %2$s is Inactive or Active in a <span>
+#. %3$s is the addon's public status (Public, In Sandbox, ...) in a <span>
+#: views/developers/dashboard.thtml:69
+msgid "devcp_dashboard_addontype_status"
+msgstr "%1$s в данный момент ÑвлÑетÑÑ %2$s и %3$s"
+
+#: views/developers/dashboard.thtml:67
+msgid "devcp_dashboard_change_status"
+msgstr "Изменить ÑтатуÑ"
+
+#. %s is the addons email address.
+#: views/developers/dashboard.thtml:99
+msgid "devcp_dashboard_disabled_questions"
+msgstr ""
+"Ваше дополнение было отключено админиÑтратором и не может быть иÑпользовано. "
+"ЕÑли у Ð²Ð°Ñ Ð²Ð¾Ð·Ð½Ð¸ÐºÐ»Ð¸ вопроÑÑ‹, вы можете ÑвÑзатьÑÑ Ñ Ð½Ð¸Ð¼ по адреÑу %s."
+
+#. %s is the (localized) add-on status string in a span, e.g. "Disabled"
+#: views/developers/dashboard.thtml:98
+msgid "devcp_dashboard_disabled_status"
+msgstr "Ð¡Ñ‚Ð°Ñ‚ÑƒÑ Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ: %s"
+
+#: views/developers/dashboard.thtml:43
+msgid "devcp_dashboard_header_main"
+msgstr "Панель ÑƒÐ¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ñ€Ð°Ð·Ñ€Ð°Ð±Ð¾Ñ‚Ñ‡Ð¸ÐºÐ°"
+
+#: views/developers/dashboard.thtml:110
+msgid "devcp_dashboard_header_welcome"
+msgstr "Добро пожаловать в панель ÑƒÐ¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ñ€Ð°Ð·Ñ€Ð°Ð±Ð¾Ñ‚Ñ‡Ð¸ÐºÐ°"
+
+#: views/developers/dashboard.thtml:68
+msgid "devcp_dashboard_inactive"
+msgstr "Ðеактивное"
+
+#. %s is a date in the _('date') format
+#: views/developers/dashboard.thtml:65
+msgid "devcp_dashboard_last_edited"
+msgstr "Дата поÑледней правки: %s"
+
+#: views/developers/dashboard.thtml:111
+msgid "devcp_dashboard_learn"
+msgstr ""
+"Ðа текущий момент вы не размещали никаких дополнений на Ñайте дополнений "
+"Mozilla. Чтобы узнать о процеÑÑе Ñ€Ð°Ð·Ð¼ÐµÑ‰ÐµÐ½Ð¸Ñ Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ð¹ и размеÑтить Ñвое "
+"первое дополнение, нажмите «Ðачать»."
+
+#: views/developers/dashboard.thtml:112
+msgid "devcp_dashboard_start"
+msgstr "Ðачать"
+
+#: views/developers/dashboard.thtml:82
+msgid "devcp_dashboard_versions"
+msgstr "ВерÑии и файлы"
+
+#: views/developers/dashboard.thtml:91
+msgid "devcp_dashboard_versions_new"
+msgstr "Загрузить новую верÑию"
+
+#. %s is the preview ID number.
+#: controllers/developers_controller.php:1415
+msgid "devcp_delete_previews_error"
+msgstr ""
+"Скриншот %s не получилоÑÑŒ удалить из базы данных. ПожалуйÑта, попробуйте "
+"Ñнова."
+
+#. %s is the preview ID number.
+#: controllers/developers_controller.php:1413
+msgid "devcp_delete_previews_success"
+msgstr "Скриншот %s был уÑпешно удалён."
+
+#: controllers/developers_controller.php:1089
+msgid "devcp_delete_version_priv_error"
+msgstr "У Ð²Ð°Ñ Ð½ÐµÑ‚ прав на удаление верÑий или файлов."
+
+#. %1$s is the count of files, a number
+#. %2$s is a status string like _('Public') or _('Incomplete')
+#: controllers/components/amo.php:549
+msgid "devcp_describe_version_status"
+msgid_plural "devcp_describe_version_status"
+msgstr[0] "%1$s %2$s файл"
+msgstr[1] "%1$s %2$s файла"
+msgstr[2] "%1$s %2$s файлов"
+
+#. %s is a version number. Example: 3.0
+#: views/developers/versions.thtml:65
+#, php-format
+msgid "devcp_details_version"
+msgstr "ВерÑÐ¸Ñ %s"
+
+#: views/developers/discuss.thtml:68
+msgid "devcp_discuss_addreply_header"
+msgstr "Добавить ответ"
+
+#: views/developers/discuss.thtml:57
+msgid "devcp_discuss_allreplies_header"
+msgstr "Ответы"
+
+#. notice when an error occurs saving a discussion reply
+#. %1 is the email address (linked) for the amo-editors list
+#: views/developers/discuss.thtml:70
+msgid "devcp_discuss_error_notice"
+msgstr ""
+"При отправке вашего ответа произошла ошибка. ПожалуйÑта, ÑвÑжитеÑÑŒ Ñ %1$s и "
+"опишите проблему."
+
+#. %1 is the add-on name, %2 is the add-on's version number currently being reviewed by an editor
+#: views/developers/discuss.thtml:46
+msgid "devcp_discuss_intro"
+msgstr ""
+"Редактор Ñайта дополнений Mozilla запроÑил у Ð²Ð°Ñ Ð´Ð¾Ð¿Ð¾Ð»Ð½Ð¸Ñ‚ÐµÐ»ÑŒÐ½ÑƒÑŽ информацию о "
+"верÑии %2$s вашего Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ %1$s."
+
+#. %1 is the add-on name
+#: views/developers/discuss.thtml:43
+msgid "devcp_discuss_pagetitle"
+msgstr ""
+"ВвеÑти дополнительную информацию Ð´Ð»Ñ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ñ Ñ€ÐµÑ†ÐµÐ½Ð·Ð¸Ð¸ на дополнение %1$s"
+
+#. submit button text
+#: views/developers/discuss.thtml:79
+msgid "devcp_discuss_submit_reply"
+msgstr "Отправить ответ"
+
+#: views/developers/discuss.thtml:72
+msgid "devcp_discuss_success_message"
+msgstr ""
+"Ваш ответ был уÑпешно Ñохранён. Другие учаÑтники диÑкуÑÑии будут уведомлены "
+"по Ñлектронной почте."
+
+#. in an author/editor discussion about an add-on to be reviewed:
+#. %1 is the commenter's user name (linked).
+#. %2 is the full date the comment was made.
+#: views/developers/discuss.thtml:52 views/developers/discuss.thtml:62
+msgid "devcp_discuss_writtenby"
+msgstr "%1$s напиÑал %2$s"
+
+#: views/developers/addon_edit_authors.thtml:72
+#: views/developers/addon_edit_authors.thtml:81
+msgid "devcp_edit_authors_add_author"
+msgstr "Добавить нового автора"
+
+#: views/developers/addon_edit_authors.thtml:96
+msgid "devcp_edit_authors_add_author_button"
+msgstr "Добавить автора"
+
+#: views/developers/addon_edit_authors.thtml:83
+msgid "devcp_edit_authors_add_email"
+msgstr "ÐÐ´Ñ€ÐµÑ ÑƒÑ‡Ñ‘Ñ‚Ð½Ð¾Ð¹ запиÑи автора:"
+
+#: views/developers/addon_edit_authors.thtml:98
+msgid "devcp_edit_authors_add_loading"
+msgstr "Проверка адреÑа учётной запиÑи..."
+
+#: views/developers/addon_edit_authors.thtml:70
+msgid "devcp_edit_authors_click_save"
+msgstr "Ð”Ð»Ñ ÑÐ¾Ñ…Ñ€Ð°Ð½ÐµÐ½Ð¸Ñ Ñ‰Ñ‘Ð»ÐºÐ½Ð¸Ñ‚Ðµ по раÑположенной ниже кнопке Обновить авторов."
+
+#: views/developers/addon_edit_authors.thtml:58
+msgid "devcp_edit_authors_header_current"
+msgstr "Текущие авторы"
+
+#: views/developers/addon_edit_authors.thtml:50
+msgid "devcp_edit_authors_header_manage"
+msgstr "Управление авторами дополнениÑ"
+
+#: views/developers/addon_edit_authors.thtml:93
+msgid "devcp_edit_authors_label_add_listed"
+msgstr "Отобразить как автора на публичной Ñтранице"
+
+#: views/developers/addon_edit_authors.thtml:89
+msgid "devcp_edit_authors_label_developer"
+msgstr ""
+"<strong>Разработчик</strong> - может управлÑÑ‚ÑŒ вÑеми аÑпектами Ð¾Ñ‚Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ "
+"дополнениÑ, кроме Ð´Ð¾Ð±Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ð¸ ÑƒÐ´Ð°Ð»ÐµÐ½Ð¸Ñ Ð´Ñ€ÑƒÐ³Ð¸Ñ… авторов."
+
+#: views/developers/addon_edit_authors.thtml:88
+msgid "devcp_edit_authors_label_owner"
+msgstr ""
+"<strong>Владелец</strong> - может управлÑÑ‚ÑŒ вÑеми аÑпектами Ð¾Ñ‚Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ "
+"дополнениÑ, в том чиÑле добавлÑÑ‚ÑŒ и удалÑÑ‚ÑŒ других авторов."
+
+#: views/developers/addon_edit_authors.thtml:90
+msgid "devcp_edit_authors_label_viewer"
+msgstr ""
+"<strong>Зритель</strong> - может проÑматривать ÑпиÑок разработчиков и "
+"ÑтатиÑтику дополнениÑ, но не может производить никаких изменений."
+
+#. Placeholder for the empty option in a <select>.
+#: views/developers/addon_edit_categories.thtml:69
+msgid "devcp_edit_authors_option_empty"
+msgstr "----------------"
+
+#: views/developers/addon_edit_authors.thtml:86
+msgid "devcp_edit_authors_select_role"
+msgstr "Выберите роль Ð´Ð»Ñ Ð°Ð²Ñ‚Ð¾Ñ€Ð°:"
+
+#. Column name in a table.
+#: views/developers/addon_edit_authors.thtml:62
+msgid "devcp_edit_authors_th_author"
+msgstr "Ðвтор"
+
+#. Column name in a table.
+#: views/developers/addon_edit_authors.thtml:64
+msgid "devcp_edit_authors_th_listed"
+msgstr "Ð’ ÑпиÑке"
+
+#. Column name in a table.
+#: views/developers/addon_edit_authors.thtml:63
+msgid "devcp_edit_authors_th_role"
+msgstr "Роль"
+
+#: views/developers/addon_edit_authors.thtml:77
+msgid "devcp_edit_authors_update_author"
+msgstr "Обновить авторов"
+
+#: views/developers/addon_edit_categories.thtml:99
+msgid "devcp_edit_categories_button_update"
+msgstr "Обновить категории"
+
+#: views/developers/addon_edit_categories.thtml:88
+msgid "devcp_edit_categories_does_not_fit"
+msgstr "Моё дополнение не подходит под какие-либо категории."
+
+#. %s is the application name (Firefox, Thunderbird).
+#: views/developers/addon_edit_categories.thtml:61
+msgid "devcp_edit_categories_header_application"
+msgstr "Категории %s"
+
+#: views/developers/addon_edit_categories.thtml:49
+msgid "devcp_edit_categories_header_manage"
+msgstr "Управление категориÑми дополнениÑ"
+
+#: views/developers/addon_edit_categories.thtml:91
+msgid "devcp_edit_categories_hover"
+msgstr "Ðаведите курÑор мыши на категорию, чтобы поÑмотреть её опиÑание."
+
+#. %s is the category number (1, 2, 3).
+#: views/developers/addon_edit_categories.thtml:67
+msgid "devcp_edit_categories_label_category_num"
+msgstr "ÐšÐ°Ñ‚ÐµÐ³Ð¾Ñ€Ð¸Ñ %s"
+
+#: views/developers/addon_edit_categories.thtml:94
+#: views/developers/addon_edit_categories.thtml:103
+msgid "devcp_edit_categories_none_available"
+msgstr "Ð”Ð»Ñ Ñтого типа Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð¸ Ð¿Ñ€Ð¸Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ Ð½ÐµÐ´Ð¾Ñтупна ни одна категориÑ."
+
+#: views/developers/addon_edit_categories.thtml:86
+msgid "devcp_edit_categories_other"
+msgstr ""
+"ПомеÑтите ваше дополнение в Ñту категорию только еÑли оно не подходит под "
+"любую другую категорию."
+
+#. %s is the application name (Firefox, Thunderbird).
+#: views/developers/addon_edit_categories.thtml:63
+msgid "devcp_edit_categories_select_application_categories"
+msgstr "Выберите Ð´Ð»Ñ Ð²Ð°ÑˆÐµÐ³Ð¾ Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð½Ðµ более трёх категорий %s"
+
+#: views/developers/addon_edit.thtml:47
+msgid "devcp_edit_dd_manage_authors"
+msgstr ""
+"ДобавлÑйте или удалÑйте пользователей, которые могут управлÑÑ‚ÑŒ Ñтим "
+"дополнением."
+
+#: views/developers/addon_edit.thtml:49
+msgid "devcp_edit_dd_manage_categories"
+msgstr ""
+"Выберите подходÑщие категории Ð´Ð»Ñ ÐºÐ°Ð¶Ð´Ð¾Ð³Ð¾ приложениÑ, которое поддерживает "
+"ваше дополнение."
+
+#: views/developers/addon_edit.thtml:51
+msgid "devcp_edit_dd_manage_description"
+msgstr ""
+"ДобавлÑйте и изменÑйте переводы Ð´Ð»Ñ Ñводки, опиÑаниÑ, лицензии и политики "
+"приватноÑти вашего дополнениÑ."
+
+#: views/developers/addon_edit.thtml:53
+msgid "devcp_edit_dd_manage_properties"
+msgstr ""
+"Измените имÑ, домашнюю Ñтраницу, значок и другие флаги вашего дополнениÑ."
+
+#: views/developers/addon_edit_descriptions.thtml:116
+msgid "devcp_edit_description_button_update"
+msgstr "Обновить опиÑаниÑ"
+
+#: views/developers/addon_edit_descriptions.thtml:115
+msgid "devcp_edit_description_correct_error"
+msgstr "ПожалуйÑта иÑправьте ошибки, отмеченные краÑным."
+
+#: views/developers/addon_edit_descriptions.thtml:51
+msgid "devcp_edit_descriptions_header"
+msgstr "Редактировать опиÑÐ°Ð½Ð¸Ñ Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ"
+
+#: views/developers/addon_edit_descriptions.thtml:94
+msgid "devcp_edit_descriptions_transbox_comments_description"
+msgstr ""
+"Ð›ÑŽÐ±Ð°Ñ Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ, которую возможно захотÑÑ‚ узнать конечные пользователи, но "
+"которой не меÑто в Ñводке или опиÑании дополнениÑ. Обычно иÑпользуетÑÑ Ð´Ð»Ñ "
+"Ñведений о Ñерьёзных ошибках, о том как Ñообщать об ошибках, предполагаемой "
+"дате выпуÑка новой верÑии и Ñ‚.д.."
+
+#: views/developers/addon_edit_descriptions.thtml:93
+msgid "devcp_edit_descriptions_transbox_comments_name"
+msgstr "Комментарии разработчика"
+
+#: views/developers/addon_edit_descriptions.thtml:86
+msgid "devcp_edit_descriptions_transbox_description_description"
+msgstr ""
+"Подробное опиÑание Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ - Ñто более полное объÑÑнение его функций, "
+"оÑобенноÑтей и Ð´Ñ€ÑƒÐ³Ð°Ñ Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ. Оно отображаетÑÑ Ð¿Ð¾Ð´ кратким опиÑанием на "
+"Ñтранице дополнениÑ."
+
+#: views/developers/addon_edit_descriptions.thtml:85
+msgid "devcp_edit_descriptions_transbox_description_name"
+msgstr "ОпиÑание дополнениÑ"
+
+#: views/developers/addon_edit_descriptions.thtml:103
+msgid "devcp_edit_descriptions_transbox_eula_description"
+msgstr ""
+"ЕÑли у вашего Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ ÐµÑÑ‚ÑŒ лицензионное Ñоглашение конечного "
+"пользователÑ, пожалуйÑта, введите его текÑÑ‚ в поле ниже. Ð’ Ñлучае его "
+"наличиÑпользователи должны будут ÑоглаÑитьÑÑ Ñ Ð½Ð¸Ð¼ перед уÑтановкой "
+"дополнениÑ. Учтите, что лицензионное Ñоглашение Ñто не то же Ñамое, что "
+"Ð»Ð¸Ñ†ÐµÐ½Ð·Ð¸Ñ Ð½Ð° иÑходный код (например, GPL или MPL)."
+
+#: views/developers/addon_edit_descriptions.thtml:102
+msgid "devcp_edit_descriptions_transbox_eula_name"
+msgstr "Лицензионное Ñоглашение конечного пользователÑ"
+
+#: views/developers/addon_edit_descriptions.thtml:112
+msgid "devcp_edit_descriptions_transbox_privacy_description"
+msgstr ""
+"ЕÑли у вашего Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ ÐµÑÑ‚ÑŒ политика приватноÑти, введите Ñюда её текÑÑ‚."
+"СÑылка на неё будет отображена на Ñтранице дополнениÑ."
+
+#: views/developers/addon_edit_descriptions.thtml:111
+msgid "devcp_edit_descriptions_transbox_privacy_name"
+msgstr "Политика приватноÑти"
+
+#: views/developers/addon_edit_descriptions.thtml:78
+msgid "devcp_edit_descriptions_transbox_summary_description"
+msgstr ""
+"Сводка - Ñто краткое опиÑание базовых функций вашего дополнениÑ, ÐºÐ¾Ñ‚Ð¾Ñ€Ð°Ñ "
+"отображаетÑÑ Ð¿Ñ€Ð¸ поиÑке и проÑмотре перечней дополнений, а также в верхней "
+"чаÑти Ñтраницы вашего дополнениÑ. <strong>Длина до 250 Ñимволов.</strong>"
+
+#: views/developers/addon_edit_descriptions.thtml:77
+msgid "devcp_edit_descriptions_transbox_summary_name"
+msgstr "Сводка дополнениÑ"
+
+#: views/developers/addon_edit.thtml:46
+msgid "devcp_edit_dt_manage_authors"
+msgstr "Управление авторами дополнениÑ"
+
+#: views/developers/addon_edit.thtml:48
+msgid "devcp_edit_dt_manage_categories"
+msgstr "Управление категориÑми дополнениÑ"
+
+#: views/developers/addon_edit.thtml:50
+msgid "devcp_edit_dt_manage_descriptions"
+msgstr "Управление опиÑаниÑми дополнениÑ"
+
+#: views/developers/addon_edit.thtml:52
+msgid "devcp_edit_dt_manage_properties"
+msgstr "Управление ÑвойÑтвами дополнениÑ"
+
+#: views/developers/addon_edit_properties.thtml:170
+msgid "devcp_edit_label_externalsoftware"
+msgstr "Это дополнение требует Ñтороннего программного обеÑпечениÑ"
+
+#: views/developers/addon_edit_properties.thtml:205
+msgid "devcp_edit_label_locale_disambiguation"
+msgstr "Ð”Ð¾Ð¿Ð¾Ð»Ð½Ð¸Ñ‚ÐµÐ»ÑŒÐ½Ð°Ñ Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¾ локали"
+
+#: views/developers/addon_edit_properties.thtml:168
+msgid "devcp_edit_label_prerelease"
+msgstr "Предварительный выпуÑк"
+
+#: views/developers/addon_edit_properties.thtml:169
+msgid "devcp_edit_label_sitespecific"
+msgstr "Дополнение Ð´Ð»Ñ Ð¾Ð¿Ñ€ÐµÐ´ÐµÐ»Ñ‘Ð½Ð½Ð¾Ð³Ð¾ Ñайта"
+
+#: views/developers/addon_edit_properties.thtml:202
+msgid "devcp_edit_label_target_locale"
+msgstr "Ð£ÐºÐ°Ð·Ð°Ð½Ð½Ð°Ñ Ð»Ð¾ÐºÐ°Ð»ÑŒ"
+
+#: views/developers/addon_edit_properties.thtml:212
+msgid "devcp_edit_properties_button_update"
+msgstr "Обновить ÑвойÑтва"
+
+#: views/developers/addon_edit_properties.thtml:198
+msgid "devcp_edit_properties_change_guid"
+msgstr "ИзменÑйте только в том Ñлучае, еÑли вы понимаете вÑе поÑледÑтвиÑ."
+
+#: views/developers/addon_edit_properties.thtml:109
+msgid "devcp_edit_properties_current_icon"
+msgstr "Текущий значок"
+
+#: views/developers/addon_edit_properties.thtml:85
+msgid "devcp_edit_properties_default_locale"
+msgstr ""
+"Локализацией Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð¿Ð¾ умолчанию ÑвлÑетÑÑ Ð³Ð»Ð°Ð²Ð½Ð°Ñ Ð»Ð¾ÐºÐ°Ð»Ð¸Ð·Ð°Ñ†Ð¸ÐµÐ¹, в "
+"которой должен приÑутÑтвовать перевод. ЕÑли перевод опиÑÐ°Ð½Ð¸Ñ Ð²Ð°ÑˆÐµÐ³Ð¾ "
+"Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð½Ðµ ÑущеÑтвует на Ñзыке, выбранном пользователем, отображаетÑÑ "
+"опиÑание на Ñзыке локализации по умолчанию."
+
+#: views/developers/addon_edit_properties.thtml:167
+msgid "devcp_edit_properties_flags"
+msgstr "Эти флаги иÑпользуютÑÑ Ð´Ð»Ñ Ñ„Ð¸Ð»ÑŒÑ‚Ñ€Ð°Ñ†Ð¸Ð¸ и клаÑÑификации дополнений."
+
+#: views/developers/addon_edit_properties.thtml:174
+msgid "devcp_edit_properties_guid"
+msgstr ""
+"GUID вашего Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ ÑƒÐºÐ°Ð·Ð°Ð½ в его файле install.rdf и Ñлужит Ð´Ð»Ñ ÐµÐ³Ð¾ "
+"уникальной идентификации. Ð’Ñ‹ не Ñможете Ñменить Ñвой GUID поÑле того, как он "
+"добавлен на Ñайт дополнений Mozilla."
+
+#: views/developers/addon_edit_properties.thtml:53
+msgid "devcp_edit_properties_header"
+msgstr "Редактировать ÑвойÑтва дополнениÑ"
+
+#: views/developers/addon_edit_properties.thtml:186
+msgid "devcp_edit_properties_header_addon_type"
+msgstr "Тип дополнениÑ"
+
+#: views/developers/addon_edit_properties.thtml:181
+msgid "devcp_edit_properties_header_admin_settings"
+msgstr "ÐаÑтройки админиÑтратора"
+
+#: views/developers/addon_edit_properties.thtml:84
+msgid "devcp_edit_properties_header_default_locale"
+msgstr "Локаль по умолчанию"
+
+#: views/developers/addon_edit_properties.thtml:166
+msgid "devcp_edit_properties_header_flags"
+msgstr "Флаги дополнениÑ"
+
+#: views/developers/addon_edit_properties.thtml:173
+#: views/developers/addon_edit_properties.thtml:197
+msgid "devcp_edit_properties_header_guid"
+msgstr "GUID дополнениÑ"
+
+#: views/developers/addon_edit_properties.thtml:104
+msgid "devcp_edit_properties_header_icon"
+msgstr "Значок дополнениÑ"
+
+#: views/developers/addon_edit_properties.thtml:159
+msgid "devcp_edit_properties_header_other_settings"
+msgstr "Другие наÑтройки"
+
+#. A header on the admin page to toggle trusted status.
+#: views/developers/addon_edit_properties.thtml:182
+msgid "devcp_edit_properties_header_trusted"
+msgstr "Доверенное дополнение?"
+
+#: views/developers/addon_edit_properties.thtml:160
+msgid "devcp_edit_properties_header_view_source"
+msgstr "ПроÑмотреть иÑходник в онлайне"
+
+#. %s is a comma-separated list of image extensions ".png, .jpg"
+#: views/developers/addon_edit_properties.thtml:106
+msgid "devcp_edit_properties_icon"
+msgstr ""
+"Значком Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ ÑвлÑетÑÑ Ð¼Ð°Ð»ÐµÐ½ÑŒÐºÐ¾Ðµ изображение, которое отображаетÑÑ "
+"Ñ€Ñдом Ñ Ð¸Ð¼ÐµÐ½ÐµÐ¼ вашего Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð¿Ñ€Ð¸ обзоре дополнений, их поиÑке, "
+"отображении Ñтраниц и в диалоговом окне уÑтановки дополнениÑ. Изображение "
+"автоматичеÑки маÑштабируетÑÑ Ð´Ð¾ размера 32 x 32 пикÑелÑ. ПожалуйÑта, "
+"иÑпользуйте один из Ñледующих форматов изображений: %s"
+
+#: views/developers/addon_edit_properties.thtml:171
+msgid "devcp_edit_properties_label_binary"
+msgstr "Это дополнение Ñодержит бинарные компоненты"
+
+#: views/developers/addon_edit_properties.thtml:185
+msgid "devcp_edit_properties_label_not_trusted"
+msgstr "Ðе доверенное"
+
+#: views/developers/addon_edit_properties.thtml:184
+msgid "devcp_edit_properties_label_trusted"
+msgstr "Доверенное"
+
+#: views/developers/addon_edit_properties.thtml:110
+msgid "devcp_edit_properties_new_icon"
+msgstr "Ðовый значок Icon"
+
+#: views/developers/addon_edit_properties.thtml:118
+msgid "devcp_edit_properties_remove_icon"
+msgstr "Удалить значок"
+
+#: views/developers/addon_edit_properties.thtml:136
+msgid "devcp_edit_properties_transbox_homepage_description"
+msgstr ""
+"ЕÑли ваше дополнение имеет другую домашнюю Ñтраницу, введите здеÑÑŒ её адреÑ. "
+"ДобавлÑÑ‚ÑŒ другие переводы не обÑзательно, еÑли только ваш Ñайт не "
+"локализован на другие Ñзыки."
+
+#: views/developers/addon_edit_properties.thtml:135
+msgid "devcp_edit_properties_transbox_homepage_name"
+msgstr "ДомашнÑÑ Ñтраница дополнениÑ"
+
+#: views/developers/addon_edit_properties.thtml:79
+msgid "devcp_edit_properties_transbox_name_description"
+msgstr "Ð˜Ð¼Ñ Ð²Ð°ÑˆÐµÐ³Ð¾ Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð¾Ñ‚Ð¾Ð±Ñ€Ð°Ð¶Ð°ÐµÐ¼Ð¾Ðµ везде, где видно ваше дополнение."
+
+#: views/developers/addon_edit_properties.thtml:78
+msgid "devcp_edit_properties_transbox_name_name"
+msgstr "Ð˜Ð¼Ñ Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ"
+
+#: views/developers/addon_edit_properties.thtml:145
+msgid "devcp_edit_properties_transbox_supportemail_description"
+msgstr ""
+"ЕÑли у Ð²Ð°Ñ ÐµÑÑ‚ÑŒ Ð°Ð´Ñ€ÐµÑ Ñл. почты Ð´Ð»Ñ Ð¿Ð¾Ð´Ð´ÐµÑ€Ð¶ÐºÐ¸ пользователей, введите его "
+"здеÑÑŒ. ДобавлÑÑ‚ÑŒ другие переводы не обÑзательно, еÑли только у Ð²Ð°Ñ Ð½ÐµÑ‚ "
+"разных адреÑов Ñл. почты Ð´Ð»Ñ Ñ€Ð°Ð·Ð½Ñ‹Ñ… Ñзыков."
+
+#: views/developers/addon_edit_properties.thtml:144
+msgid "devcp_edit_properties_transbox_supportemail_name"
+msgstr "ÐÐ´Ñ€ÐµÑ Ñл. почты поддержки"
+
+#: views/developers/addon_edit_properties.thtml:154
+msgid "devcp_edit_properties_transbox_supporturl_description"
+msgstr ""
+"ЕÑли у вашего Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ ÐµÑÑ‚ÑŒ Ñайт или форум поддержки, введите его Ð°Ð´Ñ€ÐµÑ "
+"здеÑÑŒ. ДобавлÑÑ‚ÑŒ другие переводы не обÑзательно, еÑли только ваш Ñайт не "
+"локализован на другие Ñзыки."
+
+#: views/developers/addon_edit_properties.thtml:153
+msgid "devcp_edit_properties_transbox_supporturl_name"
+msgstr "Веб-Ñайт поддержки"
+
+#: views/developers/addon_edit_properties.thtml:183
+msgid "devcp_edit_properties_trusted"
+msgstr ""
+"Доверенные Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð¼Ð¾Ð³ÑƒÑ‚ ÑтановитьÑÑ Ð¿ÑƒÐ±Ð»Ð¸Ñ‡Ð½Ñ‹Ð¼Ð¸ без Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ñ Ð¾Ñ‚Ð·Ñ‹Ð²Ð° "
+"редактора."
+
+#. %s is href="..." and should stay in the <a> tag.
+#: views/developers/addon_edit_properties.thtml:119
+msgid "devcp_edit_properties_undelete"
+msgstr "Значок будет удалён при Ñохранении. <a %s>Отменить?</a>"
+
+#: views/developers/addon_edit_properties.thtml:161
+msgid "devcp_edit_properties_view_source"
+msgstr ""
+"ЕÑли вы хотите, вы можете разрешить проÑмотр иÑходного текÑта файлов вашего "
+"Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð»ÑŽÐ±Ñ‹Ð¼ зарегиÑтрированным пользователем."
+
+#: views/developers/addon_edit_properties.thtml:162
+msgid "devcp_edit_properties_view_source_allow"
+msgstr "Разрешить онлайновый проÑмотр иÑходного кода"
+
+#: views/developers/addon_edit_properties.thtml:163
+msgid "devcp_edit_properties_view_source_do_not_allow"
+msgstr "Ðе разрешать онлайновый проÑмотр иÑходного кода"
+
+#: views/elements/developers/editbox.thtml:46
+msgid "devcp_editbox_authors"
+msgstr "Ðвторы"
+
+#: views/elements/developers/editbox.thtml:47
+msgid "devcp_editbox_categories"
+msgstr "Категории"
+
+#: views/elements/developers/editbox.thtml:52
+msgid "devcp_editbox_change_status"
+msgstr "Изменить ÑтатуÑ"
+
+#: views/elements/developers/editbox.thtml:48
+msgid "devcp_editbox_descriptions"
+msgstr "ОпиÑаниÑ"
+
+#: views/elements/developers/editbox.thtml:43
+msgid "devcp_editbox_edit_addon"
+msgstr "Редактировать дополнение"
+
+#: views/elements/developers/editbox.thtml:57
+msgid "devcp_editbox_new_version"
+msgstr "ÐÐ¾Ð²Ð°Ñ Ð²ÐµÑ€ÑиÑ"
+
+#: views/elements/developers/editbox.thtml:49
+msgid "devcp_editbox_properties"
+msgstr "СвойÑтва"
+
+#: views/elements/developers/editbox.thtml:60
+msgid "devcp_editbox_screenshots"
+msgstr "Скриншоты предпроÑмотра"
+
+#: views/elements/developers/editbox.thtml:53
+msgid "devcp_editbox_statistics_dashboard"
+msgstr "Панель ÑтатиÑтики"
+
+#: views/elements/developers/editbox.thtml:54
+msgid "devcp_editbox_versions"
+msgstr "ВерÑии и файлы"
+
+#: views/elements/developers/editbox.thtml:42
+msgid "devcp_editbox_view_listing"
+msgstr "ПроÑмотреть ÑпиÑок"
+
+#: views/elements/developers/editorsmenu.thtml:59
+msgid "devcp_editorsqueue_featured"
+msgstr "ПоÑвившиеÑÑ Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ"
+
+# %1 is the review count
+#. %1 is the review count
+#: views/elements/developers/editorsqueue.thtml:42
+#: views/elements/developers/editorsmenu.thtml:56
+#, php-format
+msgid "devcp_editorsqueue_moderatedreviews"
+msgid_plural "devcp_editorsqueue_moderatedreviews"
+msgstr[0] "ÐœÐ¾Ð´ÐµÑ€Ð¸Ñ€ÑƒÐµÐ¼Ð°Ñ Ñ€ÐµÑ†ÐµÐ½Ð·Ð¸Ñ (%s)"
+msgstr[1] "Модерируемых рецензий (%s)"
+msgstr[2] "Модерируемых рецензий (%s)"
+
+# %1 is the nominated addons count
+#. %1 is the nominated addons count
+#: views/elements/developers/editorsqueue.thtml:44
+#: views/elements/developers/editorsmenu.thtml:58
+#, php-format
+msgid "devcp_editorsqueue_nominated"
+msgid_plural "devcp_editorsqueue_nominated"
+msgstr[0] "Ðоминированное дополнение (%s)"
+msgstr[1] "Ðоминированных дополнений (%s)"
+msgstr[2] "Ðоминированных дополнений (%s)"
+
+# %1 is the update count
+#. %1 is the update count
+#: views/elements/developers/editorsqueue.thtml:43
+#: views/elements/developers/editorsmenu.thtml:57
+#, php-format
+msgid "devcp_editorsqueue_pendingupdates"
+msgid_plural "devcp_editorsqueue_pendingupdates"
+msgstr[0] "РаÑÑматриваемое обновление (%s)"
+msgstr[1] "РаÑÑматриваемых обновлений (%s)"
+msgstr[2] "РаÑÑматриваемых обновлений (%s)"
+
+#: controllers/statistics_controller.php:147
+#: controllers/statistics_controller.php:361
+#: controllers/previews_controller.php:108
+#: controllers/previews_controller.php:211
+#: controllers/previews_controller.php:312
+msgid "devcp_error_addon_access_denied"
+msgstr "Ð’Ñ‹ не имеете доÑтупа к Ñтому дополнению"
+
+#. %s is a complete URL with the text from devcp_error_appversion_reference_link_text
+#. in the <a> tag. This should be fixed.
+#: controllers/components/developers.php:591
+#, php-format
+msgid "devcp_error_appversion_reference_link"
+msgstr "Ð”Ð»Ñ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ñ Ñправочной информации поÑетите %s."
+
+#. This is the link text in the <a> for devcp_error_appversion_reference_link. This
+#. should be fixed.
+#: controllers/components/developers.php:591
+msgid "devcp_error_appversion_reference_link_text"
+msgstr "Ñту Ñтраницу"
+
+#: views/developers/addon_edit_authors.thtml:76
+msgid "devcp_error_empty_authors"
+msgstr "Ваше дополнение должно иметь по меньшей мере одного владельца."
+
+#. %1$s is the name of the file
+#: controllers/components/developers.php:658
+msgid "devcp_error_file_exists"
+msgstr ""
+"ВерÑÐ¸Ñ Ñтого Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ ÑƒÐ¶Ðµ ÑущеÑтвует. Чтобы его заменить, вначале вы "
+"должны удалить файл %1$s."
+
+#. %1$s is a file extension. Example: .exe
+#. %2$s is a comma separated list of extensions. Example: .xpi, .jar
+#: controllers/components/developers.php:355
+#, php-format
+msgid "devcp_error_file_extension"
+msgstr ""
+"Указанное раÑширение файла (%s) недопуÑтимо Ð´Ð»Ñ Ð´Ð°Ð½Ð½Ð¾Ð³Ð¾ типа дополнениÑ. "
+"ПожалуйÑта, иÑпользуйте одно из Ñледующих: %s"
+
+#: controllers/components/developers.php:64
+msgid "devcp_error_five_categories"
+msgstr "ПожалуйÑта, выберите не более пÑти категорий."
+
+#: controllers/components/developers.php:526
+msgid "devcp_error_guid_application"
+msgstr "ID данного Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ ÑƒÐ¶Ðµ иÑпользуетÑÑ Ð¿Ñ€Ð¸Ð»Ð¾Ð¶ÐµÐ½Ð¸ÐµÐ¼."
+
+#: controllers/components/developers.php:337
+#: controllers/components/developers.php:389
+msgid "devcp_error_http_incomplete"
+msgstr "ÐÐµÐ·Ð°Ð²ÐµÑ€ÑˆÐµÐ½Ð½Ð°Ñ Ð¿ÐµÑ€ÐµÐ´Ð°Ñ‡Ð°"
+
+#: controllers/components/developers.php:335
+#: controllers/components/developers.php:336
+#: controllers/components/developers.php:387
+#: controllers/components/developers.php:388
+msgid "devcp_error_http_maxupload"
+msgstr "Размер Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð¿Ñ€ÐµÐ²Ñ‹ÑˆÐ°ÐµÑ‚ макÑимальный"
+
+#: controllers/components/developers.php:338
+#: controllers/components/developers.php:390
+msgid "devcp_error_http_nofile"
+msgstr "Файл не был загружен"
+
+#. %1$s is a file extension. Example: .exe
+#. %2$s is a comma separated list of extensions. Example: .xpi, .jar
+#: controllers/components/developers.php:401
+#, php-format
+msgid "devcp_error_icon_extension"
+msgstr ""
+"Указанное раÑширение файла (%s) недопуÑтимо Ð´Ð»Ñ Ð·Ð½Ð°Ñ‡ÐºÐ°. ПожалуйÑта, "
+"иÑпользуйте одно из Ñледующих: %s"
+
+#: controllers/developers_controller.php:504
+msgid "devcp_error_index_rdf_notfound"
+msgstr "ОтÑутÑтвует файл install.rdf."
+
+#: controllers/components/developers.php:601
+msgid "devcp_error_install_manifest"
+msgstr "Ð’ install.rdf обнаружены Ñледующие ошибки:"
+
+#: controllers/developers_controller.php:1463
+msgid "devcp_error_invalid_addontype"
+msgstr "Выберите правильный тип дополнениÑ."
+
+#. %$1s is a version. Example: 3.1.1
+#. %$2s is an add-on name.
+#: controllers/components/developers.php:569
+#: controllers/components/developers.php:581
+#, php-format
+msgid "devcp_error_invalid_appversion"
+msgstr "ВерÑÐ¸Ñ %s не ÑвлÑетÑÑ Ð´ÐµÐ¹Ñтвительной Ð´Ð»Ñ %s"
+
+#. %s is a string
+#: controllers/components/developers.php:521
+#, php-format
+msgid "devcp_error_invalid_guid"
+msgstr "Ð”Ð»Ñ Ð´Ð°Ð½Ð½Ð¾Ð³Ð¾ Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ ÑƒÐºÐ°Ð·Ð°Ð½ недейÑтвительный ID: %s"
+
+#. %$1s is a version. Example: 3.1.1
+#. %$2s is an add-on name.
+#: controllers/components/developers.php:572
+#, php-format
+msgid "devcp_error_invalid_minversion"
+msgstr ""
+"ВерÑÐ¸Ñ %s не ÑвлÑетÑÑ Ð´ÐµÐ¹Ñтвительной Ð´Ð»Ñ %s: Ð¼Ð¸Ð½Ð¸Ð¼Ð°Ð»ÑŒÐ½Ð°Ñ Ð²ÐµÑ€ÑÐ¸Ñ Ð½Ðµ может "
+"Ñодержать *"
+
+#: controllers/components/developers.php:536
+msgid "devcp_error_invalid_version"
+msgstr ""
+"Указана недопуÑÑ‚Ð¸Ð¼Ð°Ñ Ð²ÐµÑ€ÑÐ¸Ñ Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ: пожалуйÑта, ÑверьтеÑÑŒ Ñо <a href="
+"\"http://developer.mozilla.org/en/docs/Toolkit_version_format"
+"\">Ñпецификацией</a>"
+
+#: controllers/components/developers.php:531
+msgid "devcp_error_invalid_version_spaces"
+msgstr ""
+"Указана недопуÑÑ‚Ð¸Ð¼Ð°Ñ Ð²ÐµÑ€ÑÐ¸Ñ Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ: в верÑии не могут ÑодержатьÑÑ "
+"пробелы."
+
+#. %s is an error message from the parser.
+#: controllers/components/developers.php:501
+#, php-format
+msgid "devcp_error_manifest_parse"
+msgstr "Во Ð²Ñ€ÐµÐ¼Ñ Ð¾Ð±Ñ€Ð°Ð±Ð¾Ñ‚ÐºÐ¸ файла install.rdf произошла ÑÐ»ÐµÐ´ÑƒÑŽÑ‰Ð°Ñ Ð¾ÑˆÐ¸Ð±ÐºÐ°: %s"
+
+#: controllers/components/developers.php:373
+msgid "devcp_error_move_file"
+msgstr "Ðевозможно перемеÑтить файл."
+
+#. %s is the name of a file
+#: controllers/components/developers.php:650
+#: controllers/components/developers.php:662
+#: controllers/components/developers.php:667
+#: controllers/components/developers.php:727
+#: controllers/components/developers.php:738
+#: controllers/components/developers.php:743
+#, php-format
+msgid "devcp_error_moving_file"
+msgstr "При перемещении %s возникла ошибка."
+
+#: controllers/components/developers.php:595
+msgid "devcp_error_mozilla_application"
+msgstr "Должно быть указано по крайней мере одно доÑтупное приложение Mozilla."
+
+#: controllers/components/developers.php:516
+msgid "devcp_error_no_guid"
+msgstr "Ð’ файле install.rdf не найдено ID Ð´Ð»Ñ Ð´Ð°Ð½Ð½Ð¾Ð³Ð¾ дополнениÑ."
+
+#: controllers/components/developers.php:287
+msgid "devcp_error_no_platform"
+msgstr "Платформа не выбрана."
+
+#: controllers/components/developers.php:59
+msgid "devcp_error_one_category"
+msgstr "ПожалуйÑта, выберите Ñ…Ð¾Ñ‚Ñ Ð±Ñ‹ одну категорию."
+
+#: controllers/components/developers.php:92
+msgid "devcp_error_one_user"
+msgstr "Должен быть Ñ…Ð¾Ñ‚Ñ Ð±Ñ‹ один автор дополнениÑ."
+
+#. %1$s is a file extension. Example: .exe
+#. %2$s is a comma separated list of extensions. Example: .xpi, .jar
+#: controllers/components/developers.php:1081
+#, php-format
+msgid "devcp_error_preview_extension"
+msgstr ""
+"Указанное раÑширение файла (%s) недопуÑтимо Ð´Ð»Ñ Ñкриншотов. ПожалуйÑта, "
+"иÑпользуйте одно из Ñледующих: %s"
+
+#: controllers/components/developers.php:511
+msgid "devcp_error_updatekey"
+msgstr ""
+"Дополнение не может иÑпользовать updateKey. ПожалуйÑта, удалите Ñтот "
+"параметр из install.rdf и попробуйте Ñнова."
+
+#: controllers/components/developers.php:506
+msgid "devcp_error_updateurl"
+msgstr ""
+"Ð”Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð½Ðµ могут иÑпользовать внешнюю ÑÑылку Ð´Ð»Ñ updateURL. ПожалуйÑта, "
+"удалите данную ÑÑылку из файла install.rdf и повторите попытку Ñнова."
+
+#: controllers/developers_controller.php:465
+#: controllers/components/developers.php:271
+msgid "devcp_error_upload_file"
+msgstr "ПожалуйÑта, загрузите файл."
+
+#: views/developers/uploader.thtml:135
+msgid "devcp_input_upload_file"
+msgstr "Загрузить файл"
+
+#: views/pages/js_constants.js.thtml:89
+msgid "devcp_js_a_cancel"
+msgstr "Отмена"
+
+#: views/pages/js_constants.js.thtml:90
+msgid "devcp_js_add_email"
+msgstr ""
+"ПожалуйÑта, введите Ð°Ð´Ñ€ÐµÑ Ñлектронной почты учётной запиÑи автора, которого "
+"вы хотите добавить."
+
+#. alt text for a down-arrow image.
+#: views/pages/js_constants.js.thtml:81
+msgid "devcp_js_img_move_down"
+msgstr "Вниз"
+
+#. alt text for an up-arrow image.
+#: views/pages/js_constants.js.thtml:82
+msgid "devcp_js_img_move_up"
+msgstr "Вверх"
+
+#: views/pages/js_constants.js.thtml:91
+msgid "devcp_js_img_remove_compat"
+msgstr "Удалить ÑовмеÑтимоÑÑ‚ÑŒ Ñ Ð¿Ñ€Ð¸Ð»Ð¾Ð¶ÐµÐ½Ð¸ÐµÐ¼"
+
+#: views/pages/js_constants.js.thtml:86
+msgid "devcp_js_input_list_author"
+msgstr "Показать как автора в публичных ÑпиÑках"
+
+#: views/pages/js_constants.js.thtml:92
+msgid "devcp_js_license_select"
+msgstr "ПожалуйÑта, выберите лицензию."
+
+#: views/pages/js_constants.js.thtml:93
+msgid "devcp_js_license_text"
+msgstr "ПожалуйÑта, введите текÑÑ‚ вашей лицензии."
+
+#. <option> text in a <select> for Author role in an add-on.
+#: views/pages/js_constants.js.thtml:84
+msgid "devcp_js_option_developer"
+msgstr "Разработчик"
+
+#. <option> text in a <select> for Author role in an add-on.
+#: views/pages/js_constants.js.thtml:83
+msgid "devcp_js_option_owner"
+msgstr "Владелец"
+
+#. <option> text in a <select> for Author role in an add-on.
+#: views/pages/js_constants.js.thtml:85
+msgid "devcp_js_option_viewer"
+msgstr "Ðаблюдатель"
+
+#: views/pages/js_constants.js.thtml:88
+msgid "devcp_js_remove_author"
+msgstr "Удалить автора"
+
+#: views/pages/js_constants.js.thtml:87
+msgid "devcp_js_sure_remove"
+msgstr "Ð’Ñ‹ <strong>уверены</strong>, что хотите удалить Ñтого автора?"
+
+#: views/pages/js_constants.js.thtml:77
+msgid "devcp_js_upload_alert"
+msgstr "Ð’Ñ‹ должны выбрать файл Ð´Ð»Ñ Ð·Ð°Ð³Ñ€ÑƒÐ·ÐºÐ¸."
+
+#. %1$s is an addon id, like 32.
+#. %2$s is a version number, like 3.5.
+#: controllers/components/developers.php:1212
+msgid "devcp_license_existing"
+msgstr "Ð¡Ð²Ð¾Ñ Ð»Ð¸Ñ†ÐµÐ½Ð·Ð¸Ñ Ð´Ð»Ñ Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ %1$s v%2$s"
+
+#: views/elements/developers/localebox.thtml:44
+msgid "devcp_localebox_header_localizedfields"
+msgstr "Переведенные полÑ"
+
+# %1 is the default locale
+#. %1 is the default locale
+#: views/elements/developers/localebox.thtml:48
+#, php-format
+msgid "devcp_localebox_intro"
+msgstr ""
+"Ðекоторые из полей на Ñтой Ñтранице локализованы Ð´Ð»Ñ Ð¿Ñ€ÐµÐ´ÑÑ‚Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ð½Ð° родном "
+"Ñзыке конечного пользователÑ. Выберите локаль ниже Ð´Ð»Ñ Ñ€ÐµÐ´Ð°ÐºÑ‚Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ "
+"Ñведений о вашем дополнении на Ñтом Ñзыке. ЕÑли перевод Ð´Ð»Ñ Ñтого Ñзыка "
+"будет недоÑтупен, то будет иÑпользоватьÑÑ Ñзык по умолчанию (%s)."
+
+#: views/elements/developers/sidebar.thtml:68
+#: views/elements/developers/myaddons.thtml:75
+msgid "devcp_myaddons_admincp_link"
+msgstr "Панель ÑƒÐ¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ð°Ð´Ð¼Ð¸Ð½Ð¸Ñтратора"
+
+#: views/elements/developers/sidebar.thtml:65
+#: views/elements/developers/myaddons.thtml:72
+msgid "devcp_myaddons_editorcp_link"
+msgstr "Панель ÑƒÐ¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ñ€ÐµÐ´Ð°ÐºÑ‚Ð¾Ñ€Ð°"
+
+#: views/elements/developers/myaddons.thtml:52
+msgid "devcp_myaddons_link"
+msgstr "Мои дополнениÑ"
+
+#: views/elements/developers/sidebar.thtml:70
+#: views/elements/developers/myaddons.thtml:77
+msgid "devcp_myaddons_mainpage_link"
+msgstr "ВернутьÑÑ Ð½Ð° главную"
+
+#: views/elements/developers/sidebar.thtml:63
+#: views/elements/developers/myaddons.thtml:70
+msgid "devcp_myaddons_statistics_link"
+msgstr "Панель ÑтатиÑтики"
+
+#: views/elements/developers/sidebar.thtml:62
+#: views/elements/developers/myaddons.thtml:69
+msgid "devcp_myaddons_submitaddon_link"
+msgstr "ÐŸÑƒÐ±Ð»Ð¸ÐºÐ°Ñ†Ð¸Ñ Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ"
+
+#: views/elements/developers/sidebar.thtml:48
+#: views/elements/developers/myaddons.thtml:67
+msgid "devcp_myaddons_title"
+msgstr "ИнÑтрументы разработчика"
+
+#. %1$s is an add-on ID, perhaps 167.
+#. %2$s is a URL.
+#: controllers/developers_controller.php:256
+msgid "devcp_new_addon_error"
+msgstr ""
+"Это дополнение ID (%1$s) уже ÑущеÑтвует в базе данных. ЕÑли Ñто ваше "
+"дополнение, вы можете <a href=\"%2$s\">загрузить новую верÑию</a>."
+
+#: views/developers/addon_status_nominate.thtml:62
+msgid "devcp_nominate_cancel"
+msgstr "Отменить и вернутьÑÑ"
+
+# %1 is the addon name
+#. %1 is the add-on name
+#: views/developers/addon_status_nominate.thtml:61
+#, php-format
+msgid "devcp_nominate_submit_nominate"
+msgstr "Ðоминировать %s"
+
+#: views/developers/addon_edit_properties.thtml:50
+#: views/developers/addon_status.thtml:49
+#: views/developers/versions_edit.thtml:50
+msgid "devcp_notice_changes_error"
+msgstr ""
+"<span>Одно или неÑколько из Ñделанных вами изменений не могут быть "
+"Ñохранены. </span><br />ПожалуйÑта, взглÑните на приведённые ниже ошибки. "
+"ОÑÑ‚Ð°Ð»ÑŒÐ½Ð°Ñ Ñ‡Ð°ÑÑ‚ÑŒ Ñделанных вами изменений была уÑпешно Ñохранена."
+
+#: views/developers/addon_edit_authors.thtml:47
+#: views/developers/addon_edit_properties.thtml:47
+#: views/developers/addon_status.thtml:46
+#: views/developers/addon_edit_descriptions.thtml:47
+#: views/developers/versions_edit.thtml:47
+#: views/developers/addon_edit_categories.thtml:46
+msgid "devcp_notice_changes_saved"
+msgstr ""
+"<span>Ваши Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð±Ñ‹Ð»Ð¸ Ñохранены.</span><br />ПожалуйÑта, обратите "
+"внимание, что Ð´Ð»Ñ Ð¿Ð¾ÑÐ²Ð»ÐµÐ½Ð¸Ñ Ð½ÐµÐºÐ¾Ñ‚Ð¾Ñ€Ñ‹Ñ… изменений во вÑех чаÑÑ‚ÑÑ… веб-Ñайта "
+"может потребоватьÑÑ Ð½ÐµÑколько чаÑов."
+
+#: controllers/previews_controller.php:252
+msgid "devcp_notice_cleardefault"
+msgstr ""
+"Удаление Ñтого, назначенного по умолчанию Ñкриншота, приведёт к "
+"автоматичеÑкому назначению ÑтатуÑа «по умолчанию» другому Ñкриншоту."
+
+#: controllers/previews_controller.php:184
+#: controllers/previews_controller.php:251
+msgid "devcp_notice_makedefault"
+msgstr ""
+"Ðазначение Ñтому Ñкриншоту ÑтатуÑа «по умолчанию» приведёт к удалению Ñтого "
+"ÑтатуÑа у текущего назначенного по умолчанию Ñкриншота."
+
+#: views/developers/addon_edit_authors.thtml:70
+msgid "devcp_notice_unsaved_changes"
+msgstr "У Ð²Ð°Ñ ÐµÑÑ‚ÑŒ неÑохранённые изменениÑ."
+
+#: controllers/developers_controller.php:87
+#: controllers/developers_controller.php:97
+#: controllers/developers_controller.php:100
+#: controllers/previews_controller.php:67
+#: controllers/previews_controller.php:79
+#: controllers/previews_controller.php:82
+msgid "devcp_pagetitle"
+msgstr "Панель ÑƒÐ¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ñ€Ð°Ð·Ñ€Ð°Ð±Ð¾Ñ‚Ñ‡Ð¸ÐºÐ°"
+
+#: controllers/previews_controller.php:103
+#: controllers/previews_controller.php:104
+msgid "devcp_preview_add_pagetitle"
+msgstr "Добавить Ñкриншот"
+
+#: controllers/previews_controller.php:135
+msgid "devcp_preview_added_successfully"
+msgstr "ИллюÑÑ‚Ñ€Ð°Ñ†Ð¸Ñ ÑƒÑпешно добавлена."
+
+#: controllers/previews_controller.php:323
+msgid "devcp_preview_deleted_successfully"
+msgstr "ИллюÑÑ‚Ñ€Ð°Ñ†Ð¸Ñ ÑƒÑпешно удалена."
+
+#: controllers/previews_controller.php:194
+#: controllers/previews_controller.php:195
+msgid "devcp_preview_edit_pagetitle"
+msgstr "Изменить Ñкриншот"
+
+#: controllers/previews_controller.php:237
+msgid "devcp_preview_updated_successfully"
+msgstr "ИллюÑÑ‚Ñ€Ð°Ñ†Ð¸Ñ ÑƒÑпешно обновлена."
+
+#: views/developers/previews.thtml:120
+msgid "devcp_previews_a_another"
+msgstr "Добавить другой Ñкриншот"
+
+#: views/developers/previews.thtml:96
+msgid "devcp_previews_a_delete"
+msgstr "Удалить Ñкриншот"
+
+#: views/developers/previews.thtml:95
+msgid "devcp_previews_a_replace"
+msgstr "Заменить Ñкриншот"
+
+#: views/developers/previews.thtml:126
+msgid "devcp_previews_a_update"
+msgstr "Обновить Ñкриншоты"
+
+#: views/developers/previews.thtml:115 views/developers/previews.thtml:124
+msgid "devcp_previews_add_new"
+msgstr "Добавить новый Ñкриншот"
+
+#. %s is a list of file extensions, e.g. ".png, .gif"
+#: views/developers/previews.thtml:116
+msgid "devcp_previews_add_select"
+msgstr ""
+"Выберите ниже изображение Ð´Ð»Ñ Ð·Ð°Ð³Ñ€ÑƒÐ·ÐºÐ¸. Ð˜Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ Ð¿Ñ€ÐµÐ²Ñ‹ÑˆÐ°ÑŽÑ‰Ð¸Ðµ по ширине "
+"700 пикÑелей, а по выÑоте 525 пикÑелей будут автоматичеÑки отмаÑштабированы."
+"Разрешённые типы файлов: %s"
+
+#: views/developers/previews.thtml:121
+msgid "devcp_previews_click_below"
+msgstr "Ð”Ð»Ñ Ð·Ð°Ð³Ñ€ÑƒÐ·ÐºÐ¸ щёлкните по кнопке Обновить Ñкриншоты."
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/previews.thtml:102
+msgid "devcp_previews_click_update"
+msgstr ""
+"Ð”Ð»Ñ ÑÐ¾Ñ…Ñ€Ð°Ð½ÐµÐ½Ð¸Ñ Ñтого Ð¸Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ Ñ‰Ñ‘Ð»ÐºÐ½Ð¸Ñ‚Ðµ по кнопке Обновить Ñкриншоты. (<a %"
+"s>Отмена?</a>)"
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/previews.thtml:107
+msgid "devcp_previews_error_message"
+msgstr ""
+"Этот Ñкриншот будет удалён при нажатии кнопки Обновить Ñкриншоты. (<a %"
+"s>Отмена?</a>)"
+
+#: views/previews/add.thtml:45
+msgid "devcp_previews_filetype_info"
+msgstr ""
+"ИÑпользуйте раÑположенную ниже форму Ð´Ð»Ñ Ð·Ð°Ð³Ñ€ÑƒÐ·ÐºÐ¸ PNG, JPG или GIF "
+"Ñкриншотов вашего дополнениÑ. Ð˜Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ Ð¿Ñ€ÐµÐ²Ñ‹ÑˆÐ°ÑŽÑ‰Ð¸Ðµ по ширине 700 "
+"пикÑелей, а по выÑоте 525 пикÑелей будут автоматичеÑки отмаÑштабированы."
+
+#: views/previews/add.thtml:43
+msgid "devcp_previews_header_add"
+msgstr "Добавить Ñкриншот"
+
+#: views/developers/previews.thtml:80
+msgid "devcp_previews_header_caption"
+msgstr "ПодпиÑÑŒ под Ñкриншотом"
+
+#: views/previews/edit.thtml:43
+msgid "devcp_previews_header_edit"
+msgstr "Изменить Ñкриншот"
+
+#: views/developers/previews.thtml:93
+msgid "devcp_previews_label_default"
+msgstr "ИллюÑÑ‚Ñ€Ð°Ñ†Ð¸Ñ Ð¿Ð¾ умолчанию"
+
+#: views/previews/add.thtml:54
+msgid "devcp_previews_label_file"
+msgstr "Файл Ñкриншота"
+
+#: views/previews/add.thtml:59 views/previews/edit.thtml:50
+msgid "devcp_previews_label_makedefault"
+msgstr "Сделать Ñтот Ñкриншот изображением по умолчанию"
+
+#: views/developers/previews.thtml:100
+msgid "devcp_previews_label_new"
+msgstr "Ðовое изображение:"
+
+#: views/developers/previews.thtml:118
+msgid "devcp_previews_label_upload"
+msgstr "Загрузить изображение: "
+
+#: views/developers/previews.thtml:50
+msgid "devcp_previews_notice_error"
+msgstr "Один или неÑколько из ваших новых Ñкриншотов не могут быть Ñохранены."
+
+#: views/developers/previews.thtml:47
+msgid "devcp_previews_notice_success"
+msgstr "Ваши Ñкриншоты были уÑпешно обновлены."
+
+#: views/developers/previews.thtml:59
+msgid "devcp_previews_p_screenshots"
+msgstr ""
+"Скриншоты вашего Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð¿Ð¾ÐºÐ°Ð·Ð°Ð½Ñ‹ ниже. Ð’Ñ‹ можете изменить Ñти Ñкриншоты "
+"или подпиÑи к ним. Скриншотом по умолчанию ÑвлÑетÑÑ Ñкриншот, отображающийÑÑ "
+"Ñ€Ñдом Ñ Ð²Ð°ÑˆÐ¸Ð¼ дополнением при поиÑке или в ÑпиÑках дополнений."
+
+#: views/previews/edit.thtml:55
+msgid "devcp_previews_submit_delete"
+msgstr "Удалить Ñкриншот"
+
+#: views/previews/edit.thtml:55
+msgid "devcp_previews_submit_delete_confirm"
+msgstr "Ð’Ñ‹ уверены, что хотите удалить Ñтот Ñкриншот?"
+
+#: views/previews/edit.thtml:54
+msgid "devcp_previews_submit_edit"
+msgstr "Изменить Ñкриншот"
+
+#: views/previews/add.thtml:63
+msgid "devcp_previews_submit_upload"
+msgstr "Загрузить Ñкриншот"
+
+#: views/developers/previews.thtml:78
+msgid "devcp_previews_thumbnail"
+msgstr "Превьюшка"
+
+#. %s is the add-on name.
+#: views/developers/previews.thtml:44
+msgid "devcp_previews_title"
+msgstr "Менеджер Ñкриншотов к %s"
+
+#: views/developers/uploader.thtml:74
+msgid "devcp_review_agreement_please"
+msgstr ""
+"Перед продолжением необходимо проÑмотреть и принÑÑ‚ÑŒ Ñледующее Ñоглашение "
+"разработчика."
+
+#: views/elements/developers/rolecheck.thtml:42
+msgid "devcp_rolecheck_no_privs"
+msgstr ""
+"<span>У Ð²Ð°Ñ Ð½ÐµÐ´Ð¾Ñтаточно прав Ð´Ð»Ñ Ð²Ð½ÐµÑÐµÐ½Ð¸Ñ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ð¹ на Ñтой Ñтранице.</"
+"span><br />ЕÑли вам нужно внеÑти изменениÑ, ÑвÑжитеÑÑŒ Ñ Ð²Ð»Ð°Ð´ÐµÐ»ÑŒÑ†ÐµÐ¼ "
+"дополнениÑ."
+
+#: controllers/developers_controller.php:1315
+msgid "devcp_several_hours"
+msgstr ""
+"ПожалуйÑта, обратите внимание, что Ð´Ð»Ñ Ð¿Ð¾ÑÐ²Ð»ÐµÐ½Ð¸Ñ Ð½ÐµÐºÐ¾Ñ‚Ð¾Ñ€Ñ‹Ñ… изменений во вÑех "
+"чаÑÑ‚ÑÑ… веб-Ñайта может потребоватьÑÑ Ð½ÐµÑколько чаÑов."
+
+#: views/elements/developers/sidebar.thtml:52
+msgid "devcp_sidebar_a_dashboard"
+msgstr "Панель"
+
+#. %s is a number
+#: views/elements/developers/statsbar.thtml:45
+#: views/developers/dashboard.thtml:79
+#, php-format
+msgid "devcp_statsbar_adu"
+msgstr "<em>%s</em> активных ежедневных пользователей"
+
+#. %s is a number
+#: views/elements/developers/statsbar.thtml:41
+#: views/developers/dashboard.thtml:75
+#, php-format
+msgid "devcp_statsbar_total_downloads"
+msgstr "<em>%s</em> из общего кол-ва загрузок"
+
+#. %s is a number
+#: views/elements/developers/statsbar.thtml:43
+#: views/developers/dashboard.thtml:77
+#, php-format
+msgid "devcp_statsbar_weekly_downloads"
+msgstr "<em>%s</em> из еженедельного кол-ва загрузок"
+
+#: views/developers/addon_status_confirm.thtml:59
+msgid "devcp_status_confirm_active"
+msgstr ""
+"ЕÑли вы отметите ваше дополнение как активное, то оно поÑвитÑÑ Ð² публичной "
+"чаÑти Ñайта, подходÑщей Ð´Ð»Ñ ÐµÐ³Ð¾ ÑтатуÑа, Ð²ÐºÐ»ÑŽÑ‡Ð°Ñ Ñ€ÐµÐ·ÑƒÐ»ÑŒÑ‚Ð°Ñ‚Ñ‹ поиÑка и "
+"перечни дополнений. Его можно будет загрузить Ñ Ñайта и оно будет "
+"предлагатьÑÑ Ð¿Ñ€Ð¸ проверке обновлений. Ð’ Ñлучае необходимоÑти вы Ñможете "
+"вернутьÑÑ Ñюда и отключить ваше дополнение Ñнова ."
+
+#: views/developers/addon_status_confirm.thtml:59
+msgid "devcp_status_confirm_active_sure"
+msgstr "Ð’Ñ‹ уверены, что хотите пометить Ñто дополнение как активное?"
+
+#: views/developers/addon_status_confirm.thtml:50
+msgid "devcp_status_confirm_header_sure"
+msgstr "Вы уверены?"
+
+#: views/developers/addon_status_confirm.thtml:55
+msgid "devcp_status_confirm_inactive"
+msgstr ""
+"ЕÑли вы отметите ваше дополнение как неактивное, то оно не будет "
+"отображатьÑÑ Ð² публичной чаÑти Ñайта, Ð²ÐºÐ»ÑŽÑ‡Ð°Ñ Ñ€ÐµÐ·ÑƒÐ»ÑŒÑ‚Ð°Ñ‚Ñ‹ поиÑка и перечни "
+"дополнений. Его Ð½ÐµÐ»ÑŒÐ·Ñ Ð±ÑƒÐ´ÐµÑ‚ загрузить Ñ Ñайта или при проверке обновлений. "
+"Ð’ Ñлучае необходимоÑти вы Ñможете вернутьÑÑ Ñюда и включить ваше дополнение "
+"Ñнова."
+
+#: views/developers/addon_status_confirm.thtml:55
+msgid "devcp_status_confirm_inactive_sure"
+msgstr "Ð’Ñ‹ уверены, что хотите пометить Ñто дополнение как неактивное?'"
+
+#: views/developers/addon_status_confirm.thtml:74
+msgid "devcp_status_confirm_no"
+msgstr "Ðет, отменить"
+
+#: views/developers/addon_status_confirm.thtml:67
+msgid "devcp_status_confirm_public"
+msgstr ""
+"ЕÑли вы Ñделаете Ñто дополнение публичным, любой пользователь Ñможет "
+"загрузить Ñто дополнение и оно Ñтанет предлагатьÑÑ Ð² качеÑтве Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ "
+"ÑущеÑтвующим пользователÑм."
+
+#: views/developers/addon_status_confirm.thtml:67
+msgid "devcp_status_confirm_public_sure"
+msgstr "Ð’Ñ‹ уверены, что хотите Ñделать Ñто дополнение публичным?"
+
+#: views/developers/addon_status_confirm.thtml:63
+msgid "devcp_status_confirm_sandbox"
+msgstr ""
+"ЕÑли вы перемеÑтите Ñто дополнение назад в пеÑочницу, то Ð´Ð»Ñ Ñ‚Ð¾Ð³Ð¾, чтобы "
+"загрузить дополнение, пользователÑм будет нужно зарегиÑтрироватьÑÑ Ð½Ð° Ñайте, "
+"и оно больше не будет предлагатьÑÑ Ð² качеÑтве Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ ÑущеÑтвующим "
+"пользователÑм. Так как ваше дополнение в данное Ð²Ñ€ÐµÐ¼Ñ ÑвлÑетÑÑ Ð¿ÑƒÐ±Ð»Ð¸Ñ‡Ð½Ñ‹Ð¼, вы "
+"можете в любое Ð²Ñ€ÐµÐ¼Ñ Ð²ÐµÑ€Ð½ÑƒÑ‚ÑŒÑÑ Ñюда и Ñнова Ñделать его публичным."
+
+#: views/developers/addon_status_confirm.thtml:63
+msgid "devcp_status_confirm_sandbox_sure"
+msgstr "Ð’Ñ‹ уверены, что хотите перемеÑтить Ñто дополнение в пеÑочницу?"
+
+#: views/developers/addon_status_confirm.thtml:73
+msgid "devcp_status_confirm_yes"
+msgstr "Да, Ñ ÑƒÐ²ÐµÑ€ÐµÐ½"
+
+#: views/developers/addon_status_nominate.thtml:46
+msgid "devcp_status_nominate_error_notice"
+msgstr ""
+"<span>Ð”Ð»Ñ Ð½Ð¾Ð¼Ð¸Ð½Ð°Ñ†Ð¸Ð¸ требуетÑÑ Ñообщение.</span><br />ПожалуйÑта, введите в "
+"текÑтовое поле требуемую информацию и попробуйте Ñнова."
+
+#: views/developers/addon_status_nominate.thtml:55
+msgid "devcp_status_nominate_header"
+msgstr "ÐÐ¾Ð¼Ð¸Ð½Ð°Ñ†Ð¸Ñ Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ"
+
+#: views/developers/dashboard.thtml:85
+msgid "devcp_summary_lastversion"
+msgstr "ПоÑледнÑÑ Ð²ÐµÑ€ÑиÑ:"
+
+#. %s is the add-on name.
+#: views/developers/addon_edit.thtml:43
+#: views/developers/addon_edit_authors.thtml:44
+#: views/developers/versions_delete.thtml:43
+#: views/developers/addon_edit_properties.thtml:44
+#: views/developers/addon_edit_descriptions.thtml:44
+#: views/developers/versions_edit.thtml:44
+#: views/developers/addon_edit_categories.thtml:43
+#: views/developers/versions.thtml:43
+msgid "devcp_title_edit_addon"
+msgstr "Редактировать %s"
+
+#. title attribute for a javascript link that pops up a help dialog.
+#: views/elements/translationbox.thtml:68
+msgid "devcp_transbox_a_title_help"
+msgstr "Справка (без ухода Ñо Ñтраницы)"
+
+#: views/elements/translationbox.thtml:68
+msgid "devcp_transbox_alt_help"
+msgstr "Справка"
+
+#. %1$s is <span>17</span>, %2$s is 42.
+#: views/elements/translationbox.thtml:101
+msgid "devcp_transbox_chars_used"
+msgstr "ИÑпользовано Ñимволов: %1$s / %2$s"
+
+#: views/elements/translationbox.thtml:132
+msgid "devcp_transbox_delete_sure"
+msgstr "Ð’Ñ‹ уверены, что хотите удалить Ñтот перевод?"
+
+#. %s is a locale, like en-US.
+#: views/elements/translationbox.thtml:143
+msgid "devcp_transbox_help_header_tabs"
+msgstr "Что Ñто за вкладки Ñ %s?"
+
+#: views/elements/translationbox.thtml:145
+msgid "devcp_transbox_help_header_what"
+msgstr "Что, еÑли у Ð¼ÐµÐ½Ñ Ð½ÐµÑ‚ ни одного перевода?"
+
+#: views/elements/translationbox.thtml:147
+msgid "devcp_transbox_help_hide"
+msgstr "Скрыть Ñправку"
+
+#: views/elements/translationbox.thtml:146
+msgid "devcp_transbox_help_if"
+msgstr ""
+"ЕÑли пользователь открыл Ñтраницу Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð¸ перевод Ñтраницы Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ "
+"на его Ñзыке отÑутÑтвует, Ñтраница будет отображена на Ñзыке вашей Локализации "
+"по умолчанию, указанной в облаÑти Ñ€ÐµÐ´Ð°ÐºÑ‚Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ ÑвойÑтв дополнениÑ. ЕÑли у Ð²Ð°Ñ "
+"нет ни одного перевода, проÑто укажите что можете в Локализации по умолчанию, "
+"ÐºÐ¾Ñ‚Ð¾Ñ€Ð°Ñ Ð´Ð¾Ð»Ð¶Ð½Ð° быть Ñзыком, на котором вы говорите."
+
+#: views/elements/translationbox.thtml:144
+msgid "devcp_transbox_help_transbox"
+msgstr ""
+"Это <i>поле Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÐ²Ð¾Ð´Ð°</i>. С его помощью вы можете локализовать на другие "
+"Ñзыки Ñпецифичное поле, Ð´Ð»Ñ ÐºÐ¾Ñ‚Ð¾Ñ€Ð¾Ð³Ð¾ у Ð²Ð°Ñ Ð¼Ð¾Ð¶ÐµÑ‚ быть перевод. Ð’Ñ‹ можете "
+"добавлÑÑ‚ÑŒ, редактировать и удалÑÑ‚ÑŒ переводы, иÑÐ¿Ð¾Ð»ÑŒÐ·ÑƒÑ Ð²ÐºÐ»Ð°Ð´ÐºÐ¸ локалей."
+
+#: views/elements/translationbox.thtml:85
+msgid "devcp_transbox_img_add_trans"
+msgstr "Добавить перевод"
+
+#: views/elements/translationbox.thtml:86
+msgid "devcp_transbox_img_remove_trans"
+msgstr "Удалить перевод"
+
+#: views/elements/translationbox.thtml:123
+msgid "devcp_transbox_input_add_all"
+msgstr "Добавить локаль во вÑе"
+
+#: views/elements/translationbox.thtml:122
+msgid "devcp_transbox_input_add_locale"
+msgstr "Добавить локаль"
+
+#: views/elements/translationbox.thtml:124
+#: views/elements/translationbox.thtml:135
+msgid "devcp_transbox_input_cancel"
+msgstr "Отмена"
+
+#: views/elements/translationbox.thtml:134
+msgid "devcp_transbox_input_delete"
+msgstr "Удалить её"
+
+#: views/elements/translationbox.thtml:113
+msgid "devcp_transbox_select_locale"
+msgstr "Выберите Ð´Ð»Ñ Ð´Ð¾Ð±Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ð»Ð¾ÐºÐ°Ð»ÑŒ перевода:"
+
+#. %1$s and %2$s are GUIDs.
+#: controllers/developers_controller.php:343
+msgid "devcp_update_addon_guid_error"
+msgstr ""
+"GUID дополнениÑ, иÑпользуемый в Ñтом файле, (%1$s) не ÑоответÑтвует "
+"ÑущеÑтвующему GUID Ð´Ð»Ñ Ñтого Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ (%2$s)."
+
+#: controllers/developers_controller.php:334
+msgid "devcp_update_addon_priv_error"
+msgstr "У Ð²Ð°Ñ Ð½ÐµÐ´Ð¾Ñтаточно привилегий Ð´Ð»Ñ Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ñтого дополнениÑ."
+
+#. %1$s is a version number, %2$s is an add-on ID.
+#: controllers/developers_controller.php:399
+msgid "devcp_update_addon_version_belong_error"
+msgstr "Ð£ÐºÐ°Ð·Ð°Ð½Ð°Ñ Ð²ÐµÑ€ÑÐ¸Ñ (%1$s) не принадлежит Ñтому дополнению (%2$s)."
+
+#. %1$s is a version number, maybe 1.1.
+#. %2$s is a URL.
+#: controllers/developers_controller.php:351
+msgid "devcp_update_addon_version_exists_error"
+msgstr ""
+"Ðомер загруженной верÑии (%1$s) Ð´Ð»Ñ Ñтого Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ ÑƒÐ¶Ðµ ÑущеÑтвует. ЕÑли вы "
+"пытаетеÑÑŒ добавить к Ñтой верÑии ещё один файл, <a href=\"%2$s\">щёлкните "
+"здеÑÑŒ</a>."
+
+#. %1$s and %2$s are version numbers.
+#: controllers/developers_controller.php:405
+msgid "devcp_update_addon_version_match_error"
+msgstr ""
+"Загруженный номер верÑии (%1$s) не ÑоответÑтвует ÑущеÑтвующему номеру верÑии "
+"(%2$s)."
+
+#: views/developers/uploader.thtml:68
+msgid "devcp_uploader_a_start"
+msgstr "начать"
+
+#: views/developers/uploader.thtml:137
+msgid "devcp_uploader_ajax_loading"
+msgstr "Загрузка файла..."
+
+#: views/developers/uploader.thtml:82
+msgid "devcp_uploader_button_agree"
+msgstr "СоглаÑитьÑÑ Ð¸ продолжить"
+
+#: views/developers/uploader.thtml:157
+msgid "devcp_uploader_button_edit"
+msgstr "Редактировать моё дополнение"
+
+#: views/developers/uploader.thtml:158
+msgid "devcp_uploader_button_later"
+msgstr "Я оформлю моё дополнение позже."
+
+#: views/developers/uploader.thtml:168
+msgid "devcp_uploader_button_release"
+msgstr "Добавить Ð¿Ñ€Ð¸Ð¼ÐµÑ‡Ð°Ð½Ð¸Ñ Ðº выпуÑку"
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/uploader.thtml:156
+msgid "devcp_uploader_created_results"
+msgstr ""
+"<p>СпиÑок ваших дополнений был уÑпешно Ñоздан. Ð‘Ð°Ð·Ð¾Ð²Ð°Ñ Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ, Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð½Ð°Ñ "
+"из вашего загруженного файла, была Ñохранена. Ð’Ñ‹ можете наÑтроить Ð´Ð»Ñ Ð²Ð°ÑˆÐµÐ³Ð¾ "
+"ÑпиÑка множеÑтво дополнительных параметров.</p><p>Ваше дополнение помечено как "
+"<strong>Ðезавершенное</strong>. Чтобы закончить оформление вашего дополнениÑ, "
+"вам нужно убедитьÑÑ, что указано корректное имÑ, Ñводка и опиÑание и что "
+"выбрана по меньшей мере одна категориÑ. Ð’Ñ‹ можете отредактировать информацию "
+"о вашем дополнении, иÑÐ¿Ð¾Ð»ÑŒÐ·ÑƒÑ ÑƒÐºÐ°Ð·Ð°Ð½Ð½ÑƒÑŽ ниже ÑÑылку, и проверить ÑÑ‚Ð°Ñ‚ÑƒÑ Ð²Ð°ÑˆÐµÐ³Ð¾ "
+"Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð² любое Ð²Ñ€ÐµÐ¼Ñ Ð½Ð° <a %s>Ñтранице ÑтатуÑа</a>."
+
+#: views/developers/uploader.thtml:143
+msgid "devcp_uploader_error_correct"
+msgstr "ПожалуйÑта, уÑтраните Ñту проблему и Ñнова загрузите ваше файл."
+
+#. %1$s is a version number, %2$s is a status, e.g Public or Incomplete.
+#: views/developers/uploader.thtml:175
+msgid "devcp_uploader_file_created"
+msgstr ""
+"Ваш новый файл был добавлен в верÑию %1$s и в данный момент помечен как %2$s."
+
+#: views/developers/uploader.thtml:154
+msgid "devcp_uploader_header_created"
+msgstr "Дополнение Ñоздано!"
+
+#: views/developers/uploader.thtml:141
+msgid "devcp_uploader_header_error"
+msgstr "Ой! КажетÑÑ Ñ Ñтим файлом еÑÑ‚ÑŒ проблема..."
+
+#: views/developers/uploader.thtml:173
+msgid "devcp_uploader_header_file_added"
+msgstr "Файл добавлен!"
+
+#: views/developers/uploader.thtml:66
+msgid "devcp_uploader_header_how"
+msgstr "Как вÑÑ‘ Ñто работает?"
+
+#. %s is the version number, e.g. 3.2.
+#: views/developers/uploader.thtml:163
+msgid "devcp_uploader_header_update_created"
+msgstr "Создана верÑÐ¸Ñ %s"
+
+#: views/developers/uploader.thtml:117
+msgid "devcp_uploader_header_upload"
+msgstr "Загрузить ваш файл"
+
+#: views/developers/uploader.thtml:67
+msgid "devcp_uploader_how"
+msgstr ""
+"<p>СпаÑибо за то, что проÑвили Ð¸Ð½Ñ‚ÐµÑ€ÐµÑ Ðº отправке вашего Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð½Ð° Ñайт "
+"дополнений Mozilla. Размещение вашего Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð½Ð° Ñайте дополнений Mozilla - "
+"Ñто Ñамый легкий ÑпоÑоб раÑпроÑÑ‚Ñ€Ð°Ð½ÐµÐ½Ð¸Ñ Ð²Ð°ÑˆÐµÐ³Ð¾ дополнениÑ. Вот что вы "
+"получите:</p><ul><li>Каждое дополнение имеет Ñвою Ñтраницу, открытую Ð´Ð»Ñ "
+"публичного доÑтупа, Ñ Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸ÐµÐ¹, которую вам необходимо предоÑтавить, такую "
+"как: ÐºÑ€Ð°Ñ‚ÐºÐ°Ñ Ñводка функций дополнениÑ, более длинное опиÑание (опционально) "
+"и набор Ñкриншотов вашего дополнениÑ.</li><li>Ваше дополнение поÑвитÑÑ Ð² "
+"поиÑке дополнений и перечнÑÑ… дополнений на Ñайте, и даже в менеджере "
+"дополнений Firefox 3.</li><li>Мы позаботимÑÑ Ð¾ хоÑтинге загружаемых "
+"пользователÑми файлов и обеÑпечим автоматичеÑкие Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ð´Ð»Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»ÐµÐ¹, "
+"когда вы загрузите новую верÑию.</li><li>Ð’Ñ‹ получите доÑтуп к панели "
+"ÑтатиÑтики Ñ Ð¿Ð¾Ð´Ñ€Ð¾Ð±Ð½Ð¾Ð¹ информацией о вашей пользовательÑкой "
+"базе.</li></ul><p>ДополнениÑ, размещаемые на Ñтом Ñайте, должны получить "
+"положительный отзыв от редактора дополнений Mozilla перед тем, как они "
+"получат вÑе перечиÑленные выше преимущеÑтва. ЕÑли вы готовы начать Ñто процеÑÑ "
+"и ваше дополнение готово Ð´Ð»Ñ Ð·Ð°Ð³Ñ€ÑƒÐ·ÐºÐ¸, проÑто щёлкните по ÑÑылке Ðачать!</p>"
+
+#: views/developers/uploader.thtml:125
+msgid "devcp_uploader_label_platformtype"
+msgstr "Поддерживаемые платформы:"
+
+#: views/developers/uploader.thtml:124
+msgid "devcp_uploader_label_upload_field"
+msgstr "Файл дополнениÑ: "
+
+#: controllers/components/developers.php:1221
+msgid "devcp_uploader_option_other"
+msgstr "Другое"
+
+#. %1$s is a number, %2$s is href="..." and should stay in the <a> tag.
+#: views/developers/uploader.thtml:176
+msgid "devcp_uploader_p_pending_file"
+msgstr ""
+"Ðовый файл Ñтанет доÑтупен в публичном доÑтупе, как только его раÑÑмотрит "
+"редактор. Ð’ данный момент в очереди на раÑÑмотрение Ñтоит %1$s других "
+"дополнений. Хотите уÑкорить процеÑÑ Ñ€Ð°ÑÑмотрениÑ? Подумайте, не хотите ли вы "
+"<a %2$s>Ñтать редактором</a>."
+
+#. %1$s is a number, %2$s is href="..." and should stay in the <a> tag.
+#: views/developers/uploader.thtml:166
+msgid "devcp_uploader_p_pending_version"
+msgstr ""
+"ÐÐ¾Ð²Ð°Ñ Ð²ÐµÑ€ÑÐ¸Ñ Ñтанет доÑтупна в публичном доÑтупе, как только её раÑÑмотрит "
+"редактор. Ð’ данный момент в очереди на раÑÑмотрение Ñтоит %1$s других "
+"дополнений. Хотите уÑкорить процеÑÑ Ñ€Ð°ÑÑмотрениÑ? Подумайте, не хотите ли вы "
+"<a %2$s>Ñтать редактором</a>."
+
+#. %s is a status, e.g Public or Incomplete.
+#: views/developers/uploader.thtml:165
+msgid "devcp_uploader_p_update_created"
+msgstr "ÐÐ¾Ð²Ð°Ñ Ð²ÐµÑ€ÑÐ¸Ñ ÑƒÑпешно Ñоздана и в данный момент помечена как %s."
+
+#. %1$s is href="..." and should stay in the 'Versions and Files' <a> tag.
+#. %2$s is href="..." and should stay in the 'current status' <a> tag.
+#: views/developers/uploader.thtml:177
+msgid "devcp_uploader_p_update_file"
+msgstr ""
+"ПроÑмотрите Ñвой новый файл на <a %1$s>Ñтранице ВерÑии и Файлы</a>, "
+"проверьте <a %2$s>текущий ÑтатуÑ</a> вашего дополнениÑ, или <b>добавьте "
+"Ð¿Ñ€Ð¸Ð¼ÐµÑ‡Ð°Ð½Ð¸Ñ Ðº выпуÑку</b> щёлкнув раÑположенную ниже кнопку (наÑтоÑтельно "
+"рекомендуетÑÑ)."
+
+#. %1$s is href="..." and should stay in the 'Versions and Files' <a> tag.
+#. %2$s is href="..." and should stay in the 'current status' <a> tag.
+#: views/developers/uploader.thtml:167
+msgid "devcp_uploader_p_update_version"
+msgstr ""
+"ПроÑмотрите Ñвою новую верÑию на <a %1$s>Ñтранице ВерÑии и Файлы</a>, "
+"проверьте <a %2$s>текущий ÑтатуÑ</a> вашего дополнениÑ, или <b>добавьте "
+"Ð¿Ñ€Ð¸Ð¼ÐµÑ‡Ð°Ð½Ð¸Ñ Ðº выпуÑку</b> щёлкнув раÑположенную ниже кнопку (наÑтоÑтельно "
+"рекомендуетÑÑ)."
+
+#: views/developers/uploader.thtml:118
+msgid "devcp_uploader_p_upload"
+msgstr ""
+"Загрузите файл вашего дополнениÑ, иÑÐ¿Ð¾Ð»ÑŒÐ·ÑƒÑ Ñ€Ð°Ñположенную ниже форму. ЕÑли у "
+"Ð²Ð°Ñ Ð¸Ð¼ÐµÐµÑ‚ÑÑ Ð´Ð»Ñ Ð·Ð°Ð³Ñ€ÑƒÐ·ÐºÐ¸ неÑколько файлов, Ñпецифичных Ð´Ð»Ñ Ð¾Ð¿ÐµÑ€Ð°Ñ†Ð¸Ð¾Ð½Ð½Ð¾Ð¹ "
+"ÑиÑтемы, выберите один файл и затем загрузите оÑтальные, иÑÐ¿Ð¾Ð»ÑŒÐ·ÑƒÑ Ð¼ÐµÐ½ÐµÐ´Ð¶ÐµÑ€ "
+"ВерÑий и Файлов."
+
+#: views/developers/uploader.thtml:125
+msgid "devcp_uploader_platformtype_all"
+msgstr "Ð’Ñе"
+
+#: views/developers/uploader.thtml:126
+msgid "devcp_uploader_platformtype_specific"
+msgstr "Специфичные:"
+
+#. Used as first item in a <select>.
+#: controllers/components/developers.php:1185
+msgid "devcp_uploader_please_choose"
+msgstr "ПожалуйÑта, выберите..."
+
+#. %1$s is the add-on name, %2$s is the version number.
+#: views/developers/uploader.thtml:57
+msgid "devcp_uploader_title_file"
+msgstr "Добавить файл в %1$s %2$s"
+
+#: views/developers/uploader.thtml:50
+msgid "devcp_uploader_title_submit"
+msgstr "Загрузить новое дополнение"
+
+#. %s is the add-on name.
+#: views/developers/uploader.thtml:54
+msgid "devcp_uploader_title_update"
+msgstr "Обновить %s"
+
+#. %s is a full <a> tag
+#: controllers/developers_controller.php:503
+#, php-format
+msgid "devcp_valid_app_reference"
+msgstr "Ð”Ð»Ñ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ñ Ñправочной информации поÑетите %s."
+
+#. This is the text in the <a> tag for devcp_valid_app_reference. This should be
+#. fixed.
+#: controllers/developers_controller.php:503
+msgid "devcp_valid_app_reference_linktext"
+msgstr "Ñту Ñтраницу"
+
+#: controllers/developers_controller.php:581
+msgid "devcp_verify_author_error"
+msgstr "Ð”Ð»Ñ Ñтого адреÑа Ñл. почты учётной запиÑи не найдено."
+
+#: controllers/developers_controller.php:553
+msgid "devcp_verify_search_engine_error"
+msgstr ""
+"Либо отÑутÑтвуют требуемые полÑ, либо имеетÑÑ Ð¾ÑˆÐ¸Ð±ÐºÐ° в XML. ПожалуйÑта <a "
+"href=\"https://developer.mozilla.org/en/"
+"Creating_OpenSearch_plugins_for_Firefox\">прочтите документацию</a>, "
+"проверьте ваше дополнение, и попробуйте Ñнова."
+
+#: views/developers/versions.thtml:75
+msgid "devcp_versions_a_cancel"
+msgstr "Отмена"
+
+#: views/developers/versions.thtml:79
+msgid "devcp_versions_a_delete"
+msgstr "Удалить верÑию"
+
+#: views/developers/versions.thtml:74
+msgid "devcp_versions_a_empty"
+msgstr "Удалить пуÑтую верÑию"
+
+#: views/developers/versions.thtml:71
+msgid "devcp_versions_a_remove"
+msgstr "Удалить?"
+
+#: views/developers/versions.thtml:91
+msgid "devcp_versions_add"
+msgstr "Добавить новую верÑию"
+
+#: views/developers/versions_delete.thtml:58
+msgid "devcp_versions_delete_a_cancel"
+msgstr "Отмена"
+
+#: views/developers/versions_delete.thtml:56
+msgid "devcp_versions_delete_a_delete"
+msgstr "Удалить верÑию"
+
+#. Followed by a list of reviews and files that will be removed.
+#: views/developers/versions_delete.thtml:50
+msgid "devcp_versions_delete_also"
+msgstr "Это также удалит:"
+
+#: views/developers/versions_delete.thtml:53
+msgid "devcp_versions_delete_files"
+msgid_plural "devcp_versions_delete_files"
+msgstr[0] "%s файл"
+msgstr[1] "%s файла"
+msgstr[2] "%s файлов"
+
+#. %s is the version number.
+#: views/developers/versions_delete.thtml:48
+msgid "devcp_versions_delete_header"
+msgstr "Удалить верÑию %s?"
+
+#: views/developers/versions_delete.thtml:52
+msgid "devcp_versions_delete_reviews"
+msgid_plural "devcp_versions_delete_reviews"
+msgstr[0] "%s отзыв"
+msgstr[1] "%s отзыва"
+msgstr[2] "%s отзывов"
+
+#. %s is the version number.
+#: views/developers/versions_delete.thtml:49
+msgid "devcp_versions_delete_sure"
+msgstr "Ð’Ñ‹ уверены, что хотите навÑегда удалить верÑию %s?"
+
+#: views/developers/versions_edit.thtml:102
+#: views/developers/versions_edit.thtml:155
+msgid "devcp_versions_edit_a_cancel"
+msgstr "Отмена"
+
+#: views/developers/versions_edit.thtml:101
+msgid "devcp_versions_edit_a_delete"
+msgstr "Удалить файл"
+
+#: views/developers/versions_edit.thtml:165
+msgid "devcp_versions_edit_a_new_app"
+msgstr "Добавить новое приложение"
+
+#: views/developers/versions_edit.thtml:154
+msgid "devcp_versions_edit_a_remove_app"
+msgstr "Удалить приложение"
+
+#: views/developers/versions_edit.thtml:114
+msgid "devcp_versions_edit_add"
+msgstr "Добавить новый файл"
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/versions_edit.thtml:121
+msgid "devcp_versions_edit_adjust"
+msgstr ""
+"ÐаÑтройка здеÑÑŒ информации о приложении позволит пользователÑм уÑтановить "
+"ваше дополнение даже еÑли файл install.rdf в пакете указывает, что "
+"дополнение неÑовмеÑтимо. <a %s>СпиÑок поддерживаемых приложений</a>"
+
+#: views/developers/versions_edit.thtml:153
+msgid "devcp_versions_edit_compat_sure"
+msgstr "Ð’Ñ‹ <b>уверены</b> что хотите удалить ÑовмеÑтимоÑÑ‚ÑŒ Ñ Ñтим приложением?"
+
+#: views/developers/versions_edit.thtml:100
+msgid "devcp_versions_edit_delete_sure"
+msgstr "Ð’Ñ‹ <b>уверены</b> что хотите навÑегда удалить Ñтот файл?"
+
+#: views/developers/versions_edit.thtml:203
+msgid "devcp_versions_edit_header_approval"
+msgstr "Ð˜Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¾Ð´Ð¾Ð±Ñ€ÐµÐ½Ð¸Ñ"
+
+#: views/developers/versions_edit.thtml:120
+msgid "devcp_versions_edit_header_compat"
+msgstr "СовмеÑтимые приложениÑ"
+
+#: views/developers/versions_edit.thtml:74
+msgid "devcp_versions_edit_header_file"
+msgstr "Ð˜Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¾ файле"
+
+#: views/developers/versions_edit.thtml:189
+msgid "devcp_versions_edit_header_license"
+msgstr "ЛицензиÑ"
+
+#. %s is the version number.
+#: views/developers/versions_edit.thtml:53
+msgid "devcp_versions_edit_header_manage"
+msgstr "Управление верÑией %s"
+
+#: views/developers/versions_edit.thtml:212
+msgid "devcp_versions_edit_header_notes"
+msgstr "ÐŸÑ€Ð¸Ð¼ÐµÑ‡Ð°Ð½Ð¸Ñ Ð¾Ð´Ð¾Ð±Ñ€ÐµÐ½Ð¸Ñ"
+
+#: views/developers/versions_edit.thtml:98
+msgid "devcp_versions_edit_img_delete"
+msgstr "Удалить файл"
+
+#. %1$s is the file id, e.g. 18723.
+#. %2$s is the platform name, e.g. ALL or Windows.
+#. %3$s is the _('date) created.
+#. %4$s is the status, e.g. "In Sandbox" or "Public".
+#. %5$s is the _('date') status was changed.
+#: views/developers/versions_edit.thtml:208
+msgid "devcp_versions_edit_li_file"
+msgstr "Файл %1$s (%2$s) Ñоздан %3$s и перенеÑён в %4$s %5$s"
+
+#: views/developers/versions_edit.thtml:190
+msgid "devcp_versions_edit_license_description"
+msgstr ""
+"ПожалуйÑта, выберите Ð´Ð»Ñ Ð²Ð°ÑˆÐµÐ³Ð¾ Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð¿Ð¾Ð´Ñ…Ð¾Ð´Ñщую лицензию. Эта Ð»Ð¸Ñ†ÐµÐ½Ð·Ð¸Ñ "
+"указывает права на ваш иÑходный код, которые вы предоÑтавлÑете."
+
+#: views/developers/versions_edit.thtml:111
+msgid "devcp_versions_edit_no_files"
+msgstr "Файлов не найдено."
+
+#: views/developers/versions_edit.thtml:213
+msgid "devcp_versions_edit_optional"
+msgstr ""
+"Ð”Ð¾Ð¿Ð¾Ð»Ð½Ð¸Ñ‚ÐµÐ»ÑŒÐ½Ð°Ñ Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð´Ð»Ñ Ñ€ÐµÐ´Ð°ÐºÑ‚Ð¾Ñ€Ð°, который будет пиÑать отзыв на Ñту "
+"верÑию."
+
+#: views/developers/versions_edit.thtml:151
+msgid "devcp_versions_edit_remove_compat"
+msgstr "Удалить ÑовмеÑтимоÑÑ‚ÑŒ приложениÑ"
+
+#: views/developers/versions_edit.thtml:167
+msgid "devcp_versions_edit_select_app"
+msgstr "ПожалуйÑта, выберите приложение"
+
+#: views/developers/versions_edit.thtml:78
+msgid "devcp_versions_edit_th_file"
+msgstr "Файл"
+
+#: views/developers/versions_edit.thtml:79
+msgid "devcp_versions_edit_th_platform"
+msgstr "Платформа"
+
+#: views/developers/versions_edit.thtml:80
+msgid "devcp_versions_edit_th_size"
+msgstr "Размер"
+
+#: views/developers/versions_edit.thtml:81
+msgid "devcp_versions_edit_th_status"
+msgstr "СтатуÑ"
+
+#: views/developers/versions_edit.thtml:183
+msgid "devcp_versions_edit_transbox_releasenotes_description"
+msgstr ""
+"Ð˜Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¾Ð± изменениÑÑ… в Ñтом выпуÑке, новых возможноÑÑ‚ÑÑ…, извеÑтных "
+"ошибках. и Ð´Ñ€ÑƒÐ³Ð°Ñ Ð¿Ð¾Ð»ÐµÐ·Ð½Ð°Ñ Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ, ÑÐ¿ÐµÑ†Ð¸Ñ„Ð¸Ñ‡Ð½Ð°Ñ Ð´Ð»Ñ Ñтого выпуÑка/верÑии. "
+"Эта Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð±ÑƒÐ´ÐµÑ‚ также доÑтупна Ð´Ð»Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»ÐµÐ¹, обновлÑющих Ñто "
+"дополнение, в менеджере дополнений Firefox 3."
+
+#: views/developers/versions_edit.thtml:182
+msgid "devcp_versions_edit_transbox_releasenotes_name"
+msgstr "ÐŸÑ€Ð¸Ð¼ÐµÑ‡Ð°Ð½Ð¸Ñ Ðº выпуÑку"
+
+#: views/developers/versions_edit.thtml:164
+msgid "devcp_versions_edit_unsaved_compat"
+msgstr ""
+"<strong>У Ð²Ð°Ñ Ð¸Ð¼ÐµÑŽÑ‚ÑÑ Ð½ÐµÑохранённые изменениÑ.</strong> СовмеÑтимоÑÑ‚ÑŒ не "
+"будет удалена, пока вы не щёлкните по кнопке Обновить верÑию."
+
+#: views/developers/versions_edit.thtml:113
+msgid "devcp_versions_edit_unsaved_files"
+msgstr ""
+"<strong>У Ð²Ð°Ñ Ð¸Ð¼ÐµÑŽÑ‚ÑÑ Ð½ÐµÑохранённые изменениÑ.</strong> Файлы не будут "
+"удалены, пока вы не щёлкните по кнопке Обновить верÑию."
+
+#: views/developers/versions_edit.thtml:218
+msgid "devcp_versions_edit_update"
+msgstr "Обновить верÑии"
+
+#: views/developers/versions.thtml:49
+msgid "devcp_versions_header_manage"
+msgstr "Управление верÑиÑми и файлами"
+
+#: views/developers/versions.thtml:87
+msgid "devcp_versions_no_versions"
+msgstr "ВерÑий нет."
+
+#. %s is a version number, base 10.
+#: views/developers/versions.thtml:46
+msgid "devcp_versions_notice_success"
+msgstr "ВерÑÐ¸Ñ %s уÑпешно удалена."
+
+#: views/developers/versions.thtml:73
+msgid "devcp_versions_p_remove"
+msgstr ""
+"Эта верÑÐ¸Ñ Ð½Ðµ имеет ÑвÑзанных Ñ Ð½ÐµÑŽ файлоов и может быть удалена. Ð’Ñ‹ хотите "
+"удалить Ñту верÑию?"
+
+#: views/developers/versions.thtml:58
+msgid "devcp_versions_th_created"
+msgstr "Создано"
+
+#: views/developers/versions.thtml:57
+msgid "devcp_versions_th_status"
+msgstr "СтатуÑ"
+
+#: views/developers/versions.thtml:56
+msgid "devcp_versions_th_version"
+msgstr "ВерÑиÑ"
+
+#: controllers/downloads_controller.php:91
+msgid "downloads_disable_warning"
+msgstr "Дополнение заблокировано"
+
+#: controllers/components/editors.php:57
+msgid "editor_review_error_addon_not_nominated"
+msgstr "Это дополнение не было номинировано."
+
+#: controllers/components/editors.php:213
+msgid "editor_review_error_file_not_pending"
+msgstr "Этот файл не ожидает Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ñ Ð¾Ñ‚Ð·Ñ‹Ð²Ð°."
+
+#. Actions are, for example: approving or rejecting
+#: controllers/components/editors.php:79
+#: controllers/components/editors.php:182
+msgid "editor_review_error_no_action"
+msgstr "ПожалуйÑта, выберите рецензию."
+
+#: controllers/components/editors.php:192
+msgid "editor_review_error_no_applications"
+msgstr "ПожалуйÑта, выберите протеÑтированные вами приложениÑ."
+
+#. Comments are required when an editor approves or rejects an add-on.
+#: controllers/components/editors.php:84
+#: controllers/components/editors.php:187
+msgid "editor_review_error_no_comments"
+msgstr "ПожалуйÑта, введите комментарии к рецензии."
+
+#: controllers/components/editors.php:161
+msgid "editor_review_error_no_files"
+msgstr "ПожалуйÑта, выберите по крайней мере один файл Ð´Ð»Ñ Ñ€ÐµÑ†ÐµÐ½Ð·Ð¸Ð¸."
+
+#: controllers/components/editors.php:197
+msgid "editor_review_error_no_operating_system"
+msgstr "ПожалуйÑта, выберите протеÑтированные вами операционные ÑиÑтемы."
+
+#: views/editors/logs.thtml:51
+msgid "editorcp_logs_button_filter"
+msgstr "Фильтр"
+
+#: views/editors/logs.thtml:44
+msgid "editorcp_logs_filter_by"
+msgstr "Фильтр по типу/дейÑтвию"
+
+#: views/editors/logs.thtml:42 controllers/editors_controller.php:964
+msgid "editorcp_logs_page_heading"
+msgstr "Журнал Ñобытий"
+
+#: views/elements/developers/editorsmenu.thtml:60
+msgid "editorcp_menu_eventlog_link"
+msgstr "Журнал Ñобытий"
+
+#: views/elements/developers/editorsmenu.thtml:62
+msgid "editorcp_menu_mainpage_link"
+msgstr "ВернутьÑÑ Ð½Ð° главную"
+
+#: views/elements/developers/editorsmenu.thtml:61
+msgid "editorcp_menu_reviewlog_link"
+msgstr "Журнал рецензий"
+
+#: views/elements/developers/editorsmenu.thtml:55
+msgid "editorcp_menu_summary_link"
+msgstr "Ð˜Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¾ редакторах"
+
+#: views/elements/developers/editorsmenu.thtml:52
+msgid "editorcp_menu_title"
+msgstr "ИнÑтрументы разработчика"
+
+#: views/editors/reviewlog.thtml:49
+msgid "editorcp_reviewlog_button_filter"
+msgstr "Фильтр"
+
+#: views/editors/reviewlog.thtml:58
+msgid "editorcp_reviewlog_column_action"
+msgstr "ДейÑтвие"
+
+#: views/editors/reviewlog.thtml:56
+msgid "editorcp_reviewlog_column_addon"
+msgstr "Дополнение"
+
+#: views/editors/reviewlog.thtml:55
+msgid "editorcp_reviewlog_column_date"
+msgstr "Дата"
+
+#: views/editors/reviewlog.thtml:57
+msgid "editorcp_reviewlog_column_editor"
+msgstr "Редактор"
+
+#: views/editors/reviewlog.thtml:94
+msgid "editorcp_reviewlog_comments_hide"
+msgstr "Скрыть комментарии"
+
+#: views/editors/reviewlog.thtml:93
+msgid "editorcp_reviewlog_comments_show"
+msgstr "Показать комментарии"
+
+#. %1$s and %2$s are full <input> tags for dates
+#: views/editors/reviewlog.thtml:45
+#, php-format
+msgid "editorcp_reviewlog_entries_between"
+msgstr "ПроÑмотреть запиÑи между %s и %s"
+
+#: views/editors/reviewlog.thtml:104
+msgid "editorcp_reviewlog_none_found"
+msgstr "Отзывы за данный период не найдены."
+
+#: views/editors/reviewlog.thtml:42
+msgid "editorcp_reviewlog_page_heading"
+msgstr "Журнал рецензий"
+
+#: views/editors/summary.thtml:61
+msgid "editorcp_summary_monthreviews_heading"
+msgstr "Отзывы меÑÑца"
+
+#: views/editors/summary.thtml:77
+msgid "editorcp_summary_neweditors_heading"
+msgstr "Ðовые редакторы"
+
+#: views/editors/summary.thtml:42
+msgid "editorcp_summary_page_heading"
+msgstr "Ð˜Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¾ редакторах"
+
+#: views/editors/summary.thtml:94
+msgid "editorcp_summary_recentactivity_heading"
+msgstr "ПоÑледние дейÑÑ‚Ð²Ð¸Ñ Ñ€ÐµÐ´Ð°ÐºÑ‚Ð¾Ñ€Ð°"
+
+#: views/editors/summary.thtml:45
+msgid "editorcp_summary_totalreviews_heading"
+msgstr "Ð’Ñего отзывов"
+
+#: controllers/editors_controller.php:248
+#: controllers/editors_controller.php:249
+msgid "editors_addon_review_pagetitle"
+msgstr "Рецензирование дополнениÑ"
+
+#: controllers/editors_controller.php:349
+msgid "editors_error_js-formerror"
+msgstr "Заполните Ñледующие полÑ:"
+
+#: controllers/editors_controller.php:350
+msgid "editors_error_review_one_file"
+msgstr "Выберите по крайней мере один файл Ð´Ð»Ñ Ñ€ÐµÑ†ÐµÐ½Ð·Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ."
+
+#: controllers/editors_controller.php:274
+msgid "editors_error_self_reviews_forbidden"
+msgstr "Саморецензирование недопуÑтимо."
+
+#: controllers/editors_controller.php:699
+msgid "editors_external_software"
+msgstr "Дополнительное программное обеÑпечение"
+
+#: views/editors/featured.thtml:120 views/editors/featured.thtml:121
+msgid "editors_featured_add_feature"
+msgstr "Добавить избранное"
+
+#: views/editors/featured.thtml:126
+msgid "editors_featured_add_feature_submit"
+msgstr "Добавить"
+
+#: views/editors/featured.thtml:49 controllers/editors_controller.php:832
+#: controllers/editors_controller.php:848
+msgid "editors_featured_addon_add_failure"
+msgstr "Ðе удалоÑÑŒ добавить избранное."
+
+#: controllers/editors_controller.php:851
+msgid "editors_featured_addon_add_success"
+msgstr "Избранное уÑпешно добавлено."
+
+#: views/editors/featured.thtml:50 controllers/editors_controller.php:839
+#: controllers/editors_controller.php:868
+#: controllers/editors_controller.php:886
+msgid "editors_featured_addon_edit_failure"
+msgstr "Ðе удалоÑÑŒ отредактировать избранное."
+
+#: views/editors/featured.thtml:51 controllers/editors_controller.php:888
+msgid "editors_featured_addon_edit_success"
+msgstr "Избранное уÑпешно отредактировано."
+
+#: views/editors/featured.thtml:53 controllers/editors_controller.php:861
+msgid "editors_featured_addon_invalid_locale"
+msgstr "Одна или неÑколько локалей некорректны."
+
+#: views/editors/featured.thtml:52 controllers/editors_controller.php:906
+msgid "editors_featured_addon_remove_failure"
+msgstr "Ðе удалоÑÑŒ удалить избранное."
+
+#: controllers/editors_controller.php:901
+msgid "editors_featured_addon_remove_success"
+msgstr "Избранное уÑпешно удалено."
+
+#: controllers/editors_controller.php:915
+#: controllers/editors_controller.php:917
+msgid "editors_featured_addons_pagetitle"
+msgstr "Избранные дополнениÑ"
+
+#: views/editors/featured.thtml:54 views/editors/featured.thtml:107
+msgid "editors_featured_edit_feature_submit"
+msgstr "ПоÑлать"
+
+#: views/editors/featured.thtml:90 views/editors/featured.thtml:91
+msgid "editors_featured_remove_feature"
+msgstr "Удалить избранное"
+
+#: views/editors/queue.thtml:46
+msgid "editors_filter_queue"
+msgstr "Фильтр очереди"
+
+#: views/editors/queue.thtml:182
+msgid "editors_helpful_links"
+msgstr "Полезные ÑÑылки"
+
+#: views/editors/queue.thtml:182
+msgid "editors_link_guide"
+msgstr "Политика раÑпроÑÑ‚Ñ€Ð°Ð½ÐµÐ½Ð¸Ñ Ð¸ иÑÐ¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ð¹"
+
+#: views/editors/queue.thtml:182
+msgid "editors_link_policy"
+msgstr "РуководÑтво редактора"
+
+#: views/editors/queue.thtml:47
+msgid "editors_notice_filter_session"
+msgstr ""
+"Эти фильтры будут дейÑтвовать до конца ÑеанÑа или пока не будут удалены."
+
+# %1 is the queue mode
+#. %1 is the queue mode
+#: views/editors/queue.thtml:177 views/admin/flagged_queue.thtml:89
+msgid "editors_notice_none_found"
+msgstr "Ð’ наÑтоÑщее Ð²Ñ€ÐµÐ¼Ñ Ð½ÐµÑ‚ дополнений данного типа Ð´Ð»Ñ Ñ€ÐµÑ†ÐµÐ½Ð·Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ."
+
+#: controllers/editors_controller.php:1040
+msgid "editors_one_day"
+msgstr "1 день"
+
+#: controllers/editors_controller.php:1048
+msgid "editors_one_hour"
+msgstr "1 чаÑ"
+
+#: controllers/editors_controller.php:1056
+msgid "editors_one_minute"
+msgstr "1 минута"
+
+#: controllers/editors_controller.php:64 controllers/editors_controller.php:73
+#: controllers/editors_controller.php:77
+msgid "editors_pagetitle"
+msgstr "Панель ÑƒÐ¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ñ€ÐµÑ†ÐµÐ½Ð·ÐµÐ½Ñ‚Ð°"
+
+#. %s is a comma separated list of platforms. Example: Windows, OS X
+#: controllers/editors_controller.php:680
+#: controllers/editors_controller.php:683
+#, php-format
+msgid "editors_platform_x_only"
+msgstr "Только Ð´Ð»Ñ %s"
+
+#: controllers/editors_controller.php:695
+msgid "editors_pre-release"
+msgstr "Предварительный выпуÑк"
+
+# %1 is the app name
+#. %1 is the app name
+#: views/editors/queue.thtml:131
+#, php-format
+msgid "editors_queue_app_compatibility"
+msgstr "СовмеÑтимо Ñ %s"
+
+#: views/editors/queue.thtml:51
+msgid "editors_queue_filter_label_addon"
+msgstr "Дополнение или Ð°Ð´Ñ€ÐµÑ Ñл. почты автора"
+
+#: views/editors/queue.thtml:72
+msgid "editors_queue_filter_label_addontypes"
+msgstr "Типы дополнений"
+
+#: views/editors/queue.thtml:56
+msgid "editors_queue_filter_label_application"
+msgstr "Приложение"
+
+#: views/editors/queue.thtml:61
+msgid "editors_queue_filter_label_maxversion"
+msgstr "МакÑ. верÑиÑ"
+
+#: views/editors/queue.thtml:78
+msgid "editors_queue_filter_label_platforms"
+msgstr "Платформы"
+
+#: views/editors/queue.thtml:66
+msgid "editors_queue_filter_label_submissionage"
+msgstr "Кол-во дней Ñ Ð¼Ð¾Ð¼ÐµÐ½Ñ‚Ð° предÑтавлениÑ"
+
+#. %1$s is a number
+#: views/editors/queue.thtml:90
+msgid "editors_queue_filter_result_count"
+msgid_plural "editors_queue_filter_result_count"
+msgstr[0] "Результаты поиÑка Ñ Ñ„Ð¸Ð»ÑŒÑ‚Ñ€Ð¾Ð¼: <strong>%1$s</strong> дополнение"
+msgstr[1] "Результаты поиÑка Ñ Ñ„Ð¸Ð»ÑŒÑ‚Ñ€Ð¾Ð¼: <strong>%1$s</strong> дополнениÑ"
+msgstr[2] "Результаты поиÑка Ñ Ñ„Ð¸Ð»ÑŒÑ‚Ñ€Ð¾Ð¼: <strong>%1$s</strong> дополнений"
+
+#: views/editors/queue.thtml:84
+msgid "editors_queue_submit_clean"
+msgstr "ОчиÑтить"
+
+#: views/editors/queue.thtml:83
+msgid "editors_queue_submit_filter"
+msgstr "Фильтр"
+
+#: controllers/editors_controller.php:133
+msgid "editors_queues_disabled"
+msgstr ""
+"Ð’ наÑтоÑщее Ð²Ñ€ÐµÐ¼Ñ Ð²Ñе очереди рецензий заблокированы. Попробуйте вернутьÑÑ Ð¸ "
+"проверить позднее."
+
+#: views/editors/review.thtml:149
+msgid "editors_review_a_edit_item"
+msgstr "Правка объекта"
+
+#: views/editors/review.thtml:146
+msgid "editors_review_a_item_history"
+msgstr "ИÑÑ‚Ð¾Ñ€Ð¸Ñ Ð¾Ð±ÑŠÐµÐºÑ‚Ð°"
+
+#: views/editors/review.thtml:148
+msgid "editors_review_a_item_homepage"
+msgstr "ДомашнÑÑ Ñтраница объекта"
+
+#: views/editors/review.thtml:145
+msgid "editors_review_a_item_overview"
+msgstr "Обзор объекта"
+
+#: views/editors/review.thtml:147
+msgid "editors_review_a_previews"
+msgstr "Скриншоты"
+
+#: controllers/editors_controller.php:345
+msgid "editors_review_action"
+msgstr "Рецензировать"
+
+#: views/editors/review.thtml:159
+msgid "editors_review_action_info"
+msgstr "ЗапроÑить дополнительную информацию"
+
+#: views/editors/review.thtml:157
+msgid "editors_review_action_public"
+msgstr "ПомеÑтить в общий доÑтуп"
+
+#: views/editors/review.thtml:160
+msgid "editors_review_action_request_superreview"
+msgstr "Ð—Ð°Ð¿Ñ€Ð¾Ñ Ñуперрецензии"
+
+#: views/editors/review.thtml:158
+msgid "editors_review_action_sandbox"
+msgstr "Вернуть в «пеÑочницу»"
+
+#: controllers/editors_controller.php:346
+msgid "editors_review_comments"
+msgstr "ПроÑмотреть комментарии"
+
+#: views/editors/review.thtml:182
+msgid "editors_review_details_info_request"
+msgstr ""
+"ИÑпользуйте Ñту форму, чтобы запроÑить у авторов более подробную информацию. "
+"Они получат пиÑьмо по Ñлектронной почте и Ñмогут тут ответить. Когда они "
+"ответÑÑ‚, Ð²Ð°Ñ ÑƒÐ²ÐµÐ´Ð¾Ð¼ÑÑ‚ по Ñлектронной почте."
+
+#: views/editors/review.thtml:174
+msgid "editors_review_details_nominated_public"
+msgstr ""
+"Отметить дополнение и его предыдущие верÑии и файлы как общедоÑтупные. "
+"Будущие верÑии будут попадать в «пеÑочницу», пока они не будут "
+"отрецензированы редактором."
+
+#: views/editors/review.thtml:177
+msgid "editors_review_details_nominated_sandbox"
+msgstr "ОÑтавить дополнение в «пеÑочнице»."
+
+#: views/editors/review.thtml:166
+msgid "editors_review_details_pending_public"
+msgstr ""
+"Одобрить данную верÑию Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð¸Ð· «пеÑочницы» Ð´Ð»Ñ Ñ€Ð°Ð·Ð¼ÐµÑ‰ÐµÐ½Ð¸Ñ Ð² общем "
+"доÑтупе."
+
+#: views/editors/review.thtml:169
+msgid "editors_review_details_pending_sandbox"
+msgstr "ОÑтавить данную верÑию общедоÑтупного Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð² «пеÑочнице»."
+
+#: views/editors/review.thtml:185
+msgid "editors_review_details_superreview"
+msgstr ""
+"ЕÑли у Ð²Ð°Ñ ÐµÑÑ‚ÑŒ опаÑÐµÐ½Ð¸Ñ Ð½Ð°Ñчет безопаÑноÑти Ñтого дополнениÑ, проблем Ñ "
+"авторÑкими правами или других проблем, требующих Ð¸Ð·ÑƒÑ‡ÐµÐ½Ð¸Ñ Ð°Ð´Ð¼Ð¸Ð½Ð¸Ñтратором, "
+"введите ваши комментарии в поле раÑположенное ниже. Они будут отоÑланы "
+"админиÑтраторам, а не автору."
+
+#: views/editors/review.thtml:134
+msgid "editors_review_file_diff_link"
+msgstr "Сравнить Ñ Ð¿ÑƒÐ±Ð»Ð¸Ñ‡Ð½Ð¾Ð¹ верÑией"
+
+#: views/editors/review.thtml:131
+msgid "editors_review_file_viewcontents_link"
+msgstr "ПроÑмотр Ñодержимого"
+
+#: views/editors/review.thtml:65
+msgid "editors_review_header_authors"
+msgstr "Ðвторы:"
+
+#: views/editors/review.thtml:79
+msgid "editors_review_header_categories"
+msgstr "Категории:"
+
+#: views/editors/review.thtml:92
+msgid "editors_review_header_compatibility"
+msgstr "СовмеÑтимо Ñ:"
+
+#: views/editors/review.thtml:251
+msgid "editors_review_header_description"
+msgstr "ОпиÑание"
+
+#: views/editors/review.thtml:275
+msgid "editors_review_header_devcomments"
+msgstr "Комментарии разработчика"
+
+#: views/editors/review.thtml:263
+msgid "editors_review_header_eula"
+msgstr "Лицензионное Ñоглашение конечного Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ (EULA)"
+
+#: views/editors/review.thtml:115
+msgid "editors_review_header_files"
+msgstr "Файлы:"
+
+#: views/editors/review.thtml:284
+msgid "editors_review_header_itemhistory"
+msgstr "ИÑÑ‚Ð¾Ñ€Ð¸Ñ Ñообщений"
+
+#: views/editors/review.thtml:232
+msgid "editors_review_header_nominationmessage"
+msgstr "Сообщение о номинации"
+
+#: views/editors/review.thtml:311
+msgid "editors_review_header_previews"
+msgstr "ИллюÑтрации"
+
+#: views/editors/review.thtml:269
+msgid "editors_review_header_privacy"
+msgstr "Политика конфиденциальноÑти"
+
+# %1 is the addon name and version
+#. %1 is the add-on name and version
+#: views/editors/review.thtml:56
+#, php-format
+msgid "editors_review_header_review"
+msgstr "Рецензирование %s"
+
+#: views/editors/review.thtml:239
+msgid "editors_review_header_reviewernotes"
+msgstr "Заметки рецензенту"
+
+#: views/editors/review.thtml:245
+msgid "editors_review_header_summary"
+msgstr "ÐннотациÑ"
+
+#: views/editors/review.thtml:257
+msgid "editors_review_header_versionnotes"
+msgstr "ÐŸÑ€Ð¸Ð¼ÐµÑ‡Ð°Ð½Ð¸Ñ Ðº верÑии"
+
+#. a noun: shown in an add-on's editor review history
+#: views/elements/developers/editors_review_history_item.thtml:80
+msgid "editors_review_history_info_reply"
+msgstr "Ответ"
+
+#: views/elements/developers/editors_review_history_item.thtml:78
+msgid "editors_review_history_info_request"
+msgstr "Ð—Ð°Ð¿Ñ€Ð¾Ñ Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ð¸"
+
+#: views/elements/developers/editors_review_history_item.thtml:62
+#: views/editors/reviewlog.thtml:77
+msgid "editors_review_history_nominated_adminreview"
+msgstr "Ð ÐµÑ†ÐµÐ½Ð·Ð¸Ñ Ð°Ð´Ð¼Ð¸Ð½Ð¸Ñтратора"
+
+#: views/elements/developers/editors_review_history_item.thtml:56
+#: views/editors/reviewlog.thtml:71
+msgid "editors_review_history_nominated_approved"
+msgstr "ÐÐ¾Ð¼Ð¸Ð½Ð°Ñ†Ð¸Ñ Ð¾Ð´Ð¾Ð±Ñ€ÐµÐ½Ð°/Ð’ общий доÑтуп"
+
+#: views/elements/developers/editors_review_history_item.thtml:59
+#: views/editors/reviewlog.thtml:74
+msgid "editors_review_history_nominated_denied"
+msgstr "ÐÐ¾Ð¼Ð¸Ð½Ð°Ñ†Ð¸Ñ Ð¾Ñ‚ÐºÐ»Ð¾Ð½ÐµÐ½Ð°/Ð’ «пеÑочницу»"
+
+#: views/editors/review.thtml:303
+msgid "editors_review_history_nonefound"
+msgstr "Ðе найдено ни одной предыдущей рецензии."
+
+#: views/elements/developers/editors_review_history_item.thtml:73
+#: views/editors/reviewlog.thtml:88
+msgid "editors_review_history_pending_adminreview"
+msgstr "Ð ÐµÑ†ÐµÐ½Ð·Ð¸Ñ Ð°Ð´Ð¼Ð¸Ð½Ð¸Ñтратора"
+
+#: views/elements/developers/editors_review_history_item.thtml:67
+#: views/editors/reviewlog.thtml:82
+msgid "editors_review_history_pending_approved"
+msgstr "Одобрить/Ð’ общий доÑтуп"
+
+#: views/elements/developers/editors_review_history_item.thtml:70
+#: views/editors/reviewlog.thtml:85
+msgid "editors_review_history_pending_denied"
+msgstr "Отклонить/Ð’ «пеÑочницу»"
+
+#. link text in an add-on's editor review history, allowing to hide and show an information request's replies
+#. %1 is the number of replies
+#: views/elements/developers/editors_review_history_item.thtml:90
+msgid "editors_review_history_show_hide_replies"
+msgid_plural "editors_review_history_show_hide_replies"
+msgstr[0] "Показать/Скрыть ответы (%1$s)"
+msgstr[1] "Показать/Скрыть ответы (%1$s)"
+
+#: views/editors/review.thtml:208
+msgid "editors_review_label_applications"
+msgstr "ПриложениÑ:"
+
+#: views/editors/review.thtml:196
+msgid "editors_review_label_cannedresponse"
+msgstr "или выберите ответ из Ñтандартных:"
+
+#: views/editors/review.thtml:190
+msgid "editors_review_label_comments"
+msgstr "Комментарии:"
+
+#: views/editors/review.thtml:204
+msgid "editors_review_label_operating_systems"
+msgstr "Операционные ÑиÑтемы:"
+
+#: views/editors/review.thtml:285 views/editors/review.thtml:312
+msgid "editors_review_link_pagetop"
+msgstr "Ðаверх"
+
+#: views/editors/review.thtml:141
+msgid "editors_review_mulitple_notice"
+msgstr ""
+"Примечание: Рецензируйте более одного файла только в Ñлучае еÑли вы "
+"протеÑтировали КÐЖДЫЙ выбранный вами файл."
+
+#: views/editors/review.thtml:51
+msgid "editors_review_next_link"
+msgstr "Ñлед. &raquo;"
+
+#: views/editors/review.thtml:322
+msgid "editors_review_previews_notfound"
+msgstr "Рецензии не найдены."
+
+#: views/editors/review.thtml:50
+msgid "editors_review_previous_link"
+msgstr "&laquo; пред."
+
+#: controllers/editors_controller.php:144
+#: controllers/editors_controller.php:146
+msgid "editors_review_queue_pagetitle"
+msgstr "Очередь рецензий"
+
+# %1 is the add-ons rank in the queue, %2 is the total queue length
+#. %1 is the add-ons rank in the queue, %2 is the total queue length
+#: views/editors/review.thtml:47
+msgid "editors_review_rank_in_queue"
+msgstr "<strong># %1$s-й</strong> из %2$s в очереди"
+
+#. %1 is the add-ons rank in the queue, %2 is the total queue length. Both numbers
+#: views/editors/review.thtml:45
+msgid "editors_review_rank_in_queue_filtered"
+msgstr "<strong># %1$-й</strong> из %2$s в очереди (Ñ Ñ„Ð¸Ð»ÑŒÑ‚Ñ€Ð¾Ð¼)"
+
+#: views/editors/review.thtml:223
+msgid "editors_review_submit_process_action"
+msgstr "Ход дейÑтвиÑ"
+
+#: views/editors/review.thtml:293
+msgid "editors_review_th_action"
+msgstr "ДейÑтвие"
+
+#: views/editors/review.thtml:294
+msgid "editors_review_th_comments"
+msgstr "Комментарии"
+
+#: views/editors/review.thtml:291
+msgid "editors_review_th_date"
+msgstr "Дата"
+
+#: views/editors/review.thtml:292
+msgid "editors_review_th_reviewer"
+msgstr "Рецензент"
+
+#: views/editors/review.thtml:290
+msgid "editors_review_th_version_file"
+msgstr "ВерÑиÑ/Файл"
+
+#: views/editors/review.thtml:217
+msgid "editors_review_update_notify_once"
+msgstr ""
+"ПоÑлать мне уведомление при Ñледующем обновлении Ñтого дополнениÑ. "
+"(ÐеÑколько обновлений подрÑд приведут к поÑылке только одного пиÑьма)"
+
+#: controllers/editors_controller.php:298
+msgid "editors_reviewed_successfully"
+msgstr "Ð ÐµÑ†ÐµÐ½Ð·Ð¸Ñ ÑƒÑпешно обработана."
+
+#: views/editors/reviews_queue.thtml:106
+msgid "editors_reviews_action_delete_review"
+msgstr "Удалить рецензию"
+
+#: views/editors/reviews_queue.thtml:104
+msgid "editors_reviews_action_keep"
+msgstr "Удалить флаги; Ñохранить рецензию"
+
+#: views/editors/reviews_queue.thtml:102
+msgid "editors_reviews_action_skip"
+msgstr "ПропуÑтить"
+
+#: views/editors/reviews_queue.thtml:100
+msgid "editors_reviews_header_action"
+msgstr "ДейÑтвие"
+
+#: views/editors/reviews_queue.thtml:67
+msgid "editors_reviews_in_reply_to"
+msgstr "В ответ на:"
+
+#: controllers/editors_controller.php:748
+msgid "editors_reviews_processed"
+msgstr "Рецензии уÑпешно обработаны!"
+
+#: views/editors/reviews_queue.thtml:117
+msgid "editors_reviews_queue_empty"
+msgstr "Ð’ наÑтоÑщее Ð²Ñ€ÐµÐ¼Ñ Ð½ÐµÑ‚ рецензий Ð´Ð»Ñ Ð¼Ð¾Ð´ÐµÑ€Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ."
+
+#: views/editors/reviews_queue.thtml:111
+msgid "editors_reviews_submit_process_reviews"
+msgstr "Обработать рецензии"
+
+#: controllers/editors_controller.php:691
+msgid "editors_site_specific"
+msgstr "Ð”Ð»Ñ Ð¾Ð¿Ñ€ÐµÐ´ÐµÐ»Ñ‘Ð½Ð½Ð¾Ð³Ð¾ Ñайта"
+
+#: controllers/editors_controller.php:348
+msgid "editors_tested_app"
+msgstr "Проверенные приложениÑ"
+
+#: controllers/editors_controller.php:347
+msgid "editors_tested_os"
+msgstr "Проверенные операционные ÑиÑтемы"
+
+#: views/editors/queue.thtml:151
+msgid "editors_th_additional_info"
+msgstr "Ð”Ð¾Ð¿Ð¾Ð»Ð½Ð¸Ñ‚ÐµÐ»ÑŒÐ½Ð°Ñ Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ"
+
+#: views/editors/featured.thtml:63 views/editors/queue.thtml:109
+#: views/admin/flagged_queue.thtml:53
+msgid "editors_th_addon"
+msgstr "Дополнение"
+
+#: views/editors/queue.thtml:125
+msgid "editors_th_addontype"
+msgstr "Тип"
+
+#: views/editors/featured.thtml:64
+msgid "editors_th_locales"
+msgstr "Ограничить Ð´Ð»Ñ Ð»Ð¾ÐºÐ°Ð»ÐµÐ¹?"
+
+#: views/editors/queue.thtml:148
+msgid "editors_th_nomination_age"
+msgstr "Ð’Ñ€ÐµÐ¼Ñ Ð² очереди"
+
+#: views/editors/queue.thtml:101 views/editors/queue.thtml:117
+#: views/editors/queue.thtml:144
+msgid "editors_th_sort_ascending"
+msgstr "Сортировка по возраÑтанию"
+
+#: views/editors/queue.thtml:105 views/editors/queue.thtml:121
+#: views/editors/queue.thtml:140
+msgid "editors_th_sort_descending"
+msgstr "Сортировка по убыванию"
+
+#. %s is a number
+#: controllers/editors_controller.php:1036
+#, php-format
+msgid "editors_x_days"
+msgstr "%s днÑ(ей)"
+
+#. %s is a number
+#: controllers/editors_controller.php:1044
+#, php-format
+msgid "editors_x_hours"
+msgstr "%s чаÑа(ов)"
+
+#. %s is a number
+#: controllers/editors_controller.php:1052
+#, php-format
+msgid "editors_x_minutes"
+msgstr "%s минут(ы)"
+
+#: views/errors/error401.thtml:50 controllers/components/simple_acl.php:81
+#: controllers/components/simple_acl.php:82
+#: controllers/components/simple_acl.php:83 controllers/components/amo.php:607
+#: controllers/components/amo.php:608 controllers/components/amo.php:609
+#: controllers/reviews_controller.php:353
+#: controllers/reviews_controller.php:485
+#: controllers/collections_controller.php:438
+#: controllers/collections_controller.php:496
+#: controllers/collections_controller.php:504
+#: controllers/collections_controller.php:971
+#: controllers/collections_controller.php:1034
+#: controllers/collections_controller.php:1077
+msgid "error_access_denied"
+msgstr "Ð’ доÑтупе отказано"
+
+#: views/errors/error401.thtml:52
+msgid "error_access_denied_message"
+msgstr "У Ð²Ð°Ñ Ð½ÐµÐ´Ð¾Ñтаточно прав Ð´Ð»Ñ Ð¿Ñ€Ð¾Ñмотра Ñтой Ñтраницы."
+
+#: controllers/collections_controller.php:1039
+msgid "error_addon_exists"
+msgstr "Дополнение уже ÑущеÑтвует!"
+
+#: controllers/developers_controller.php:200
+#: controllers/developers_controller.php:593
+#: controllers/developers_controller.php:1016
+#: controllers/developers_controller.php:1429
+#: controllers/downloads_controller.php:95
+#: controllers/downloads_controller.php:102
+#: controllers/downloads_controller.php:164
+#: controllers/statistics_controller.php:135
+#: controllers/previews_controller.php:115
+#: controllers/previews_controller.php:206
+#: controllers/previews_controller.php:307
+#: controllers/reviews_controller.php:77
+#: controllers/reviews_controller.php:240
+#: controllers/reviews_controller.php:332
+#: controllers/reviews_controller.php:340 controllers/api_controller.php:123
+#: controllers/api_controller.php:759 controllers/addons_controller.php:131
+#: controllers/addons_controller.php:197
+#: controllers/addons_controller.php:1407
+#: controllers/addons_controller.php:1465
+#: controllers/addons_controller.php:1469
+#: controllers/addons_controller.php:1503
+#: controllers/editors_controller.php:265
+#: controllers/collections_controller.php:1041
+#: controllers/collections_controller.php:1074
+msgid "error_addon_notfound"
+msgstr "Дополнение не найдено!"
+
+#: controllers/files_controller.php:83 controllers/files_controller.php:196
+msgid "error_addon_notviewable"
+msgstr "Дополнение Ð½ÐµÐ»ÑŒÐ·Ñ Ð¿Ñ€Ð¾Ñмотреть через Ð¸Ð½Ñ‚ÐµÑ€Ñ„ÐµÐ¹Ñ ÐМО."
+
+#: controllers/reviews_controller.php:246
+msgid "error_addon_selfreview"
+msgstr "Ð’Ñ‹ не можете дать отзыв на Ñвоё ÑобÑтвенное дополнение."
+
+#: controllers/addons_controller.php:970
+msgid "error_browse_no_addons"
+msgstr "Ð’ Ñтой категории Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð¾Ñ‚ÑутÑтвуют!"
+
+#: controllers/api_controller.php:424
+msgid "error_collection_feed_notfound"
+msgstr "Лента новоÑтей Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð½Ðµ найдена."
+
+#: views/users/register.thtml:65 views/users/edit.thtml:194
+msgid "error_email_invalid"
+msgstr "Это неправильный Ð°Ð´Ñ€ÐµÑ Ñлектронной почты."
+
+#: views/users/pwreset.thtml:74 views/users/register.thtml:70
+#: views/users/register.thtml:80 views/users/register.thtml:86
+#: views/users/edit.thtml:105 views/users/edit.thtml:111
+#: views/users/edit.thtml:192 views/admin/users_edit.thtml:78
+#: views/admin/users_edit.thtml:83 views/reviews/add.thtml:80
+#: views/reviews/add.thtml:104
+msgid "error_field_required"
+msgstr "Это поле не может быть пуÑтым."
+
+#: controllers/files_controller.php:75 controllers/files_controller.php:93
+#: controllers/files_controller.php:96 controllers/files_controller.php:163
+#: controllers/files_controller.php:176 controllers/files_controller.php:185
+#: controllers/files_controller.php:204 controllers/editors_controller.php:412
+msgid "error_file_notfound"
+msgstr "Файл не найден!"
+
+#. %s is a filename
+#: controllers/editors_controller.php:430
+#, php-format
+msgid "error_file_x_notfound"
+msgstr "Ошибка: файл %s не ÑущеÑтвует."
+
+#: views/collections/add.thtml:55 views/collections/edit.thtml:89
+#: views/users/register.thtml:54 views/users/edit.thtml:81
+#: views/reviews/add.thtml:70 controllers/groups_controller.php:80
+#: controllers/groups_controller.php:102
+msgid "error_formerrors"
+msgstr "Ð’ Ñтой форме имеютÑÑ Ð¾ÑˆÐ¸Ð±ÐºÐ¸. ИÑправьте их и повторите попытку."
+
+#: views/users/register.thtml:109
+msgid "error_invalid_captcha"
+msgstr "Введённый текÑÑ‚ неверен, пожалуйÑта попробуйте Ñнова!"
+
+#: views/users/register.thtml:100 views/users/edit.thtml:125
+#: views/admin/users_edit.thtml:101
+msgid "error_invalid_url"
+msgstr ""
+"Этот URL имеет неверный формат. Правильные URL имеют вид http://example.com/"
+"my_page."
+
+#. %s is a string representing what's missing. Example: file_id
+#: controllers/downloads_controller.php:65
+#: controllers/users_controller.php:185 controllers/users_controller.php:264
+#: controllers/users_controller.php:559 controllers/users_controller.php:653
+#: controllers/reviews_controller.php:71
+#: controllers/reviews_controller.php:234
+#: controllers/reviews_controller.php:325
+#: controllers/reviews_controller.php:473
+#: controllers/reviews_controller.php:475
+#: controllers/addons_controller.php:182
+#: controllers/addons_controller.php:1381
+#: controllers/addons_controller.php:1455
+#: controllers/collections_controller.php:266
+#: controllers/collections_controller.php:285
+#: controllers/collections_controller.php:346
+#: controllers/collections_controller.php:443
+#: controllers/collections_controller.php:482
+#: controllers/collections_controller.php:936
+#: controllers/collections_controller.php:959
+#: controllers/collections_controller.php:960
+#: controllers/collections_controller.php:975
+#: controllers/collections_controller.php:977
+#: controllers/collections_controller.php:994
+#: controllers/collections_controller.php:1003
+#: controllers/collections_controller.php:1016
+#: controllers/collections_controller.php:1017
+#: controllers/collections_controller.php:1024
+#: controllers/collections_controller.php:1070
+#: controllers/collections_controller.php:1090
+#, php-format
+msgid "error_missing_argument"
+msgstr "ОтÑутÑтвует аргумент: %s"
+
+#: controllers/components/amo.php:507 controllers/components/amo.php:532
+msgid "error_no_files_in_addon"
+msgstr "Файлы отÑутÑтвуют"
+
+#: controllers/previews_controller.php:200
+msgid "error_preview_notfound"
+msgstr "ИллюÑÑ‚Ñ€Ð°Ñ†Ð¸Ñ Ð½Ðµ найдена!"
+
+#: views/addons/display.thtml:400 views/reviews/add.thtml:98
+msgid "error_review_rating_required"
+msgstr "Вы должны выбрать рейтинг."
+
+#: controllers/users_controller.php:160
+msgid "error_user_already_confirmed"
+msgstr "РегиÑÑ‚Ñ€Ð°Ñ†Ð¸Ñ ÑƒÑ‡Ñ‘Ñ‚Ð½Ð¾Ð¹ запиÑи Ñтого Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ ÑƒÐ¶Ðµ была подтверждена."
+
+#: controllers/users_controller.php:202 controllers/users_controller.php:276
+#: controllers/users_controller.php:569 controllers/users_controller.php:581
+#: controllers/users_controller.php:587 controllers/users_controller.php:610
+#: controllers/users_controller.php:627
+msgid "error_user_badconfirmationcode"
+msgstr "Ðеверный код подтверждениÑ!"
+
+#: views/users/pwreset.thtml:79 views/users/register.thtml:75
+#: views/users/edit.thtml:183
+msgid "error_user_confirmpw_nomatch"
+msgstr "Пароли не Ñовпадают."
+
+#: views/users/register.thtml:65 views/users/edit.thtml:190
+#: controllers/users_controller.php:617
+msgid "error_user_email_notunique"
+msgstr ""
+"Данный Ð°Ð´Ñ€ÐµÑ Ñлектронной почты уже зарегиÑтрирован другим пользователем."
+
+#: controllers/users_controller.php:596
+msgid "error_user_emailchange_expired"
+msgstr ""
+"ВремÑ, отведённое на Ñмену адреÑа Ñлектронной почты, иÑтекло. ПожалуйÑта "
+"Ñнова Ñмените Ñвой Ð°Ð´Ñ€ÐµÑ Ñлектронной почты в профиле Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ð¸ щёлкните "
+"по ÑÑылке в подтверждающем пиÑьме, как только вы его получите."
+
+#: controllers/collections_controller.php:985
+msgid "error_user_exists"
+msgstr ""
+"Пользователь может иметь только одну роль. ПожалуйÑта, перед продолжением, "
+"уберите у Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ð»ÑŽÐ±Ñ‹Ðµ роли."
+
+#: views/users/register.thtml:91 views/users/edit.thtml:116
+#: views/admin/users_edit.thtml:88
+msgid "error_user_nickname_notunique"
+msgstr "Такой ник уже ÑущеÑтвует."
+
+#: views/users/pwreset.thtml:54 controllers/users_controller.php:191
+#: controllers/users_controller.php:270 controllers/users_controller.php:603
+#: controllers/users_controller.php:659
+#: controllers/collections_controller.php:988
+#: controllers/collections_controller.php:998
+msgid "error_user_notfound"
+msgstr "Пользователь не найден!"
+
+#: views/users/activatefirst.thtml:47
+msgid "error_user_unconfirmed"
+msgstr ""
+"Сначала требуетÑÑ Ð²Ñ‹Ð¿Ð¾Ð»Ð½Ð¸Ñ‚ÑŒ активацию учётной запиÑи при помощи кода, "
+"полученного по Ñлектронной почте."
+
+#: views/users/login.thtml:67
+msgid "error_username_or_pw_wrong"
+msgstr "Ðеверный логин или пароль!"
+
+#: controllers/editors_controller.php:260
+msgid "error_version_notfound"
+msgstr "ВерÑÐ¸Ñ Ð½Ðµ найдена!"
+
+#: views/users/delete.thtml:125 views/users/edit.thtml:173
+msgid "error_wrong_password"
+msgstr "Введён неверный пароль!"
+
+#: views/elements/amo2009/homepage_addon.thtml:122
+#: views/elements/feature.thtml:122
+msgid "feature_learnmore"
+msgstr "Узнать больше"
+
+# %1 is the add-on name
+#. %1 is the add-on name
+#: views/elements/amo2009/homepage_addon.thtml:123
+#: views/elements/feature.thtml:123
+#, php-format
+msgid "feature_learnmore_about_addon"
+msgstr "Узнать больше о %1$s"
+
+#. %1$s is a number
+#: views/elements/amo2009/reviews.thtml:52
+#: views/elements/addon_listitem.thtml:112 views/elements/feature.thtml:99
+#: views/addons/browse_thumbs.thtml:86
+#, php-format
+msgid "feature_reviews"
+msgid_plural "feature_reviews"
+msgstr[0] "%1$s отзыв"
+msgstr[1] "%1$s отзыва"
+msgstr[2] "%1$s отзывов"
+
+#: views/elements/amo2009/homepage_addon.thtml:127
+#: views/elements/feature.thtml:127
+msgid "feature_view_more_from_category"
+msgstr "ПроÑмотреть другие из"
+
+#. This appears on a page that views the source of an add-on. This link will return
+#. the user to the add-on's main page
+#: views/files/browse.thtml:65
+msgid "file_browser_link_addon"
+msgstr "Ðазад к дополнению"
+
+#. There is a list of directories and files on the page. Clicking this will show the
+#. contents of all the directories (normally you would click on each one to see the
+#. contents)
+#: views/files/browse.thtml:67
+msgid "file_browser_link_expand_all"
+msgstr "Развернуть вÑÑ‘"
+
+#. This appears on a page that views the source of an add-on. This link will return
+#. the user to the add-on's review page (it only appears if the add-on is being
+#. reviewed)
+#: views/files/browse.thtml:64
+msgid "file_browser_link_review"
+msgstr "Ðазад к рецензии"
+
+#. The title of the page for viewing an add-on's source.
+#. %1$s is the name of the add-on
+#. %2$s is the name of the current application (e.g. Firefox or Thunderbird)
+#: views/files/browse.thtml:46
+msgid "file_browser_title"
+msgstr "%1$s :: Обозреватель файлов :: Ð”Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ %2$s"
+
+#. This appears on a page that views the source of an add-on. There is a list of
+#. directories and files on the page. Clicking this link will toggle between an
+#. expanded or a collapsed list. This string should be kept short.
+#: views/files/browse.thtml:68
+msgid "file_browser_toggle_expand_collapse"
+msgstr "+/-"
+
+#. Link text for the AMO About page.
+#: views/elements/footer.thtml:72 views/layouts/amo2009.thtml:341
+msgid "footer_a_about"
+msgstr "О Ñайте"
+
+#. Link text to the AMO blog.
+#: views/elements/footer.thtml:74 views/layouts/amo2009.thtml:343
+msgid "footer_a_blog"
+msgstr "Блог"
+
+#. Link text to the Frequently Asked Questions page.
+#: views/elements/footer.thtml:73 views/layouts/amo2009.thtml:342
+msgid "footer_a_faq"
+msgstr "FAQ"
+
+#. Full text for the FAQ abbreviation.
+#: views/elements/footer.thtml:73 views/pages/collector_features.thtml:72
+#: views/layouts/amo2009.thtml:342
+msgid "footer_abbr_faq"
+msgstr "ЧаÑто задаваемые вопроÑÑ‹"
+
+#: views/elements/footer.thtml:67 views/layouts/amo2009.thtml:336
+msgid "footer_all_rights_reserved"
+msgstr "Ð’Ñе права защищены."
+
+#: views/elements/footer.thtml:67 views/layouts/amo2009.thtml:336
+msgid "footer_copyright"
+msgstr "Copyright"
+
+#: views/elements/footer.thtml:71 views/layouts/amo2009.thtml:340
+msgid "footer_credits"
+msgstr "Ð¡Ð²ÐµÐ´ÐµÐ½Ð¸Ñ Ð¾Ð± авторах"
+
+#: views/elements/footer.thtml:76 views/layouts/amo2009.thtml:346
+msgid "footer_disclaimer"
+msgstr ""
+"Mozilla любезно обеÑпечивает ÑÑылки на Ñти Ð¿Ñ€Ð¸Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ Ð¸ не предоÑтавлÑет "
+"никаких Ñведений отноÑительно приложений или любой информации, ÑвÑзанной Ñ "
+"ними. Любые вопроÑÑ‹, жалобы или Ñ‚Ñ€ÐµÐ±Ð¾Ð²Ð°Ð½Ð¸Ñ Ð¾Ñ‚Ð½Ð¾Ñительно приложений должны "
+"направлÑÑ‚ÑŒÑÑ ÑоответÑтвующему производителю программного обеÑпечениÑ."
+
+#: views/elements/footer.thtml:61 views/layouts/amo2009.thtml:332
+msgid "footer_lang_form_lang_submit_go"
+msgstr "Перейти"
+
+#: views/elements/footer.thtml:70 views/layouts/amo2009.thtml:339
+msgid "footer_legal_notices"
+msgstr "Правовое обеÑпечение"
+
+#: views/elements/footer.thtml:50 views/layouts/amo2009.thtml:321
+msgid "footer_other_languages"
+msgstr "Другие Ñзыки:"
+
+#: views/elements/footer.thtml:69 views/layouts/amo2009.thtml:338
+msgid "footer_privacy_policy"
+msgstr "Политика конфиденциальноÑти"
+
+#: models/addontype.php:79
+msgid "general_addontype_dict"
+msgstr "Словарь"
+
+# Plural in this context means many of the add-on type
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:100
+msgid "general_addontype_dict_plural"
+msgstr "Словари"
+
+#: models/addontype.php:75
+msgid "general_addontype_extension"
+msgstr "РаÑширение"
+
+# Plural in this context means many of the add-on type
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:98
+msgid "general_addontype_extension_plural"
+msgstr "РаÑширениÑ"
+
+#: models/addontype.php:85
+msgid "general_addontype_lpaddon"
+msgstr "Ð›Ð¾ÐºÐ°Ð»Ð¸Ð·Ð°Ñ†Ð¸Ñ (ДополнениÑ)"
+
+# Plural in this context means many of the add-on type
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:103
+msgid "general_addontype_lpaddon_plural"
+msgstr "Локализации (Дополнений)"
+
+#: models/addontype.php:83
+msgid "general_addontype_lpapp"
+msgstr "Ð›Ð¾ÐºÐ°Ð»Ð¸Ð·Ð°Ñ†Ð¸Ñ (ПриложениÑ)"
+
+# Plural in this context means many of the add-on type
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:102
+msgid "general_addontype_lpapp_plural"
+msgstr "Локализации (Приложений)"
+
+#: models/addontype.php:87
+msgid "general_addontype_plugin"
+msgstr "Плагин"
+
+# Plural in this context means many of the add-on type
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:104
+msgid "general_addontype_plugin_plural"
+msgstr "Плагины"
+
+#: models/addontype.php:81
+msgid "general_addontype_search"
+msgstr "ПоиÑковый движок"
+
+# Plural in this context means many of the add-on type
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:101
+msgid "general_addontype_search_plural"
+msgstr "ПоиÑковые движки"
+
+#: models/addontype.php:77
+msgid "general_addontype_theme"
+msgstr "Тема"
+
+# Plural in this context means many of the add-on type
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:99
+msgid "general_addontype_theme_plural"
+msgstr "Темы"
+
+#: config/language.php:367
+msgid "general_languages_all_locales"
+msgstr "Ð’Ñе локализации"
+
+#: views/layouts/amo2009.thtml:249
+msgid "header_brand_name"
+msgstr "Mozilla"
+
+#. %1$s is the application name. Example: Firefox
+#: views/elements/header.thtml:111 views/elements/header.thtml:122
+#: views/layouts/amo2009.thtml:248
+#, php-format
+msgid "header_home_tooltip"
+msgstr "ВозвратитьÑÑ Ð½Ð° домашнюю Ñтраницу дополнений %1$s"
+
+#: views/elements/header.thtml:87
+msgid "header_main_firefox_header"
+msgstr "Ð”Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Firefox"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:218
+msgid "header_main_firefox_header_with_logo"
+msgstr ""
+"Ð”Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ <em>длÑ</em> <img alt=\"Firefox\" src=\"%1$s\" /> <strong>Firefox</"
+"strong>"
+
+#: views/elements/header.thtml:99
+msgid "header_main_header"
+msgstr "ДополнениÑ"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:242
+msgid "header_main_header_with_logo"
+msgstr "Ð”Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ <img alt=\"ДополнениÑ\" src=\"%1$s\" />"
+
+#: views/elements/header.thtml:90
+msgid "header_main_seamonkey_header"
+msgstr "Ð”Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ SeaMonkey"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:224
+msgid "header_main_seamonkey_header_with_logo"
+msgstr ""
+"Ð”Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ <em>длÑ</em> <img alt=\"seamonkey\" src=\"%1$s\" /> "
+"<strong>SeaMonkey</strong>"
+
+#: views/elements/header.thtml:93
+msgid "header_main_sunbird_header"
+msgstr "Ð”Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Sunbird"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:230
+msgid "header_main_sunbird_header_with_logo"
+msgstr ""
+"Ð”Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ <em>длÑ</em> <img alt=\"sunbird\" src=\"%1$s\" /> <strong>Sunbird</"
+"strong>"
+
+#: views/elements/header.thtml:96
+msgid "header_main_thunderbird_header"
+msgstr "Ð”Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Thunderbird"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:236
+msgid "header_main_thunderbird_header_with_logo"
+msgstr ""
+"Ð”Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ <em>длÑ</em> <img alt=\"thunderbird\" src=\"%1$s\" /> "
+"<strong>Thunderbird</strong>"
+
+#: views/layouts/amo2009.thtml:205
+msgid "header_navaccess_applications_menu"
+msgstr "Перейти к меню других приложений"
+
+#: views/layouts/amo2009.thtml:204
+msgid "header_navaccess_categories_menu"
+msgstr "Перейти к меню категорий"
+
+#: views/layouts/amo2009.thtml:202
+msgid "header_navaccess_main_content"
+msgstr "Перейти к главному Ñодержимому"
+
+#: views/layouts/amo2009.thtml:203
+msgid "header_navaccess_search_form"
+msgstr "Перейти к форме поиÑка"
+
+#: views/elements/header.thtml:62
+msgid "header_navlink_addons"
+msgstr "ДополнениÑ"
+
+#: views/elements/developers/sidebar.thtml:72
+#: views/elements/developers/myaddons.thtml:50 views/elements/header.thtml:159
+#: views/addons/display.thtml:378
+msgid "header_navlink_login"
+msgstr "Войти"
+
+#: views/elements/header.thtml:156 views/layouts/amo2009.thtml:304
+msgid "header_navlink_logout"
+msgstr "Выйти"
+
+#: views/elements/header.thtml:145 views/layouts/amo2009.thtml:303
+msgid "header_navlink_myaccount"
+msgstr "ÐœÐ¾Ñ ÑƒÑ‡Ñ‘Ñ‚Ð½Ð°Ñ Ð·Ð°Ð¿Ð¸ÑÑŒ"
+
+#: views/elements/header.thtml:158
+msgid "header_navlink_register"
+msgstr "РегиÑтрациÑ"
+
+#. %1 is the URL to the registration page
+#. %2 is the URL to the login page
+#: views/layouts/amo2009.thtml:278
+msgid "header_navlink_register_or_login"
+msgstr ""
+"<a href=\"%1$s\">ЗарегиÑтрируйтеÑÑŒ</a> или <a href=\"%2$s\">Войдите</a>"
+
+#: views/layouts/amo2009.thtml:285
+msgid "header_navlink_tools"
+msgstr "ИнÑтрументы"
+
+#. %s is the add-on name
+#: views/elements/collections_interactive_addon.thtml:62
+#: views/elements/amo2009/homepage_addon.thtml:77
+#: views/elements/addon_discussionheader.thtml:62
+#: views/elements/addon_listitem.thtml:67 views/elements/feature.thtml:84
+#: views/addons/category_landing.thtml:87 views/addons/browse_thumbs.thtml:60
+#, php-format
+msgid "img_preview_of"
+msgstr "Предварительный проÑмотр %s"
+
+# %1 is the login URL for the link tag
+# %2 is the link to an explanatory page.
+#. %1 is the login URL for the link tag
+#. %2 is the link to an explanatory page.
+#: views/elements/amo2009/install.thtml:307 views/elements/install.thtml:255
+msgid "install_a_login_to_install"
+msgstr ""
+"<a href=\"%1$s\">ЗарегиÑтрируйтеÑÑŒ</a>, чтобы уÑтановить Ñто "
+"ÑкÑпериментальное дополнение. <a href=\"%2$s\">Ðо почему</a>?"
+
+#. %1 is the URL for the Experimental Add-ons section of the FAQ page
+#: views/elements/amo2009/install.thtml:283 views/elements/install.thtml:232
+msgid "install_button_confirm_exp_install"
+msgstr ""
+"Дайте мне уÑтановить Ñто ÑкÑпериментальное дополнение. <a href=\"%1$s\">Что "
+"Ñто?</a>"
+
+#. %1$s is the application name. Example: Firefox
+#. %2$s is an optional string used to specify a platform. Example: (Windows)
+#: views/elements/amo2009/install.thtml:128 views/elements/install.thtml:75
+#, php-format
+msgid "install_button_text"
+msgstr "Добавить в %s %s"
+
+# %1 is the add-on name, %2 is the app name
+#. %1 is the add-on name, %2 is the app name
+#: views/elements/amo2009/install.thtml:191
+#: views/elements/amo2009/install.thtml:206
+#: views/elements/amo2009/install.thtml:249
+#: views/elements/amo2009/install.thtml:298 views/elements/install.thtml:150
+#: views/elements/install.thtml:165 views/elements/install.thtml:202
+#: views/elements/install.thtml:246
+#, php-format
+msgid "install_button_title"
+msgstr "Добавить %1$s в %2$s"
+
+#. %1$s is the add-on name
+#: views/elements/amo2009/install.thtml:200 views/elements/install.thtml:159
+#, php-format
+msgid "install_download"
+msgstr "Загрузить %1$s"
+
+#: views/elements/amo2009/install.thtml:147 views/elements/install.thtml:94
+msgid "install_error_addon_not_found"
+msgstr "Дополнение недоÑтупно."
+
+#: views/addons/dictionaries.thtml:65
+msgid "langtools_a11y_tablesummary"
+msgstr "СпиÑок локализаций и Ñловарей"
+
+#: views/addons/dictionaries.thtml:47
+msgid "langtools_download_dictionary"
+msgstr "Загрузить Ñловарь"
+
+#: views/addons/dictionaries.thtml:48
+msgid "langtools_download_langpack"
+msgstr "Загрузить локализацию"
+
+#: views/addons/dictionaries.thtml:63 controllers/components/amo.php:685
+#: controllers/addons_controller.php:1239
+msgid "langtools_header_dicts_and_langpacks"
+msgstr "Словари и локализации"
+
+#: views/addons/dictionaries.thtml:44
+msgid "langtools_install_dictionary"
+msgstr "УÑтановить Ñловарь"
+
+#: views/addons/dictionaries.thtml:45
+msgid "langtools_install_langpack"
+msgstr "УÑтановить локализацию"
+
+#: views/addons/dictionaries.thtml:69
+msgid "langtools_tableheader_dictionary"
+msgstr "Словарь"
+
+#: views/addons/dictionaries.thtml:70
+msgid "langtools_tableheader_langpack"
+msgstr "ЛокализациÑ"
+
+#: views/addons/dictionaries.thtml:68
+msgid "langtools_tableheader_language"
+msgstr "Язык"
+
+#: models/license.php:65
+msgid "license_custom"
+msgstr "Ð¡Ð²Ð¾Ñ Ð»Ð¸Ñ†ÐµÐ½Ð·Ð¸Ñ"
+
+#: config/bootstrap.php:303
+msgid "licenses_bsd"
+msgstr "Ð›Ð¸Ñ†ÐµÐ½Ð·Ð¸Ñ BSD"
+
+#: config/bootstrap.php:298
+msgid "licenses_gpl_2.0"
+msgstr "Ð›Ð¸Ñ†ÐµÐ½Ð·Ð¸Ñ GNU General Public License, верÑÐ¸Ñ 2.0"
+
+#: config/bootstrap.php:299
+msgid "licenses_gpl_3.0"
+msgstr "Ð›Ð¸Ñ†ÐµÐ½Ð·Ð¸Ñ GNU General Public License, верÑÐ¸Ñ 3.0"
+
+#: config/bootstrap.php:300
+msgid "licenses_lgpl_2.1"
+msgstr "Ð›Ð¸Ñ†ÐµÐ½Ð·Ð¸Ñ GNU Lesser General Public License, верÑÐ¸Ñ 2.1"
+
+#: config/bootstrap.php:301
+msgid "licenses_lgpl_3.0"
+msgstr "Ð›Ð¸Ñ†ÐµÐ½Ð·Ð¸Ñ GNU Lesser General Public License, верÑÐ¸Ñ 3.0"
+
+#: config/bootstrap.php:302
+msgid "licenses_mit"
+msgstr "Ð›Ð¸Ñ†ÐµÐ½Ð·Ð¸Ñ MIT/X11 License"
+
+#: config/bootstrap.php:297
+msgid "licenses_mpl_1.1"
+msgstr "Ð›Ð¸Ñ†ÐµÐ½Ð·Ð¸Ñ Mozilla Public License, верÑÐ¸Ñ 1.1"
+
+#: views/users/emailchange.thtml:51 views/users/delete.thtml:55
+#: views/users/delete.thtml:137 views/users/edit.thtml:74
+#: views/reviews/flag.thtml:54
+msgid "link_return_to_front_page"
+msgstr "Ð”Ð»Ñ Ð²Ð¾Ð·Ð²Ñ€Ð°Ñ‚Ð° на первую Ñтраницу щёлкните здеÑÑŒ."
+
+#: views/elements/amo2009/addon_list_options.thtml:46
+#: views/elements/addon_list_options.thtml:46
+msgid "list_sortby_date"
+msgstr "дате"
+
+#: views/elements/amo2009/addon_list_options.thtml:47
+#: views/elements/addon_list_options.thtml:47
+msgid "list_sortby_downloads"
+msgstr "загрузкам"
+
+#: views/elements/amo2009/addon_list_options.thtml:45
+#: views/elements/addon_list_options.thtml:45
+msgid "list_sortby_name"
+msgstr "названию"
+
+#: views/elements/amo2009/addon_list_options.thtml:48
+#: views/elements/addon_list_options.thtml:48
+msgid "list_sortby_rating"
+msgstr "рейтингу"
+
+#: config/bootstrap.php:278
+msgid "main_prettyname_fennec"
+msgstr "Fennec"
+
+#: config/bootstrap.php:274
+msgid "main_prettyname_firefox"
+msgstr "Firefox"
+
+#: config/bootstrap.php:277
+msgid "main_prettyname_seamonkey"
+msgstr "SeaMonkey"
+
+#: config/bootstrap.php:276
+msgid "main_prettyname_sunbird"
+msgstr "Sunbird"
+
+#: config/bootstrap.php:275
+msgid "main_prettyname_thunderbird"
+msgstr "Thunderbird"
+
+#: views/elements/addon_categories.thtml:52
+msgid "nav_category_dicts_langpacks"
+msgstr "Словари и локализации"
+
+#: views/elements/addon_categories.thtml:55
+msgid "nav_category_themes"
+msgstr "Темы"
+
+#: views/elements/app_chooser.thtml:47 views/layouts/amo2009.thtml:255
+msgid "other_apps_tooltip"
+msgstr "Ðайти Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð´Ð»Ñ Ð´Ñ€ÑƒÐ³Ð¸Ñ… приложений"
+
+# In a user list: user 1, user 2, "others"
+#. In a user list: user 1, user 2, "others"
+#: views/helpers/addons_html.php:222
+msgid "other_users"
+msgstr "другие"
+
+#: controllers/pages_controller.php:90
+msgid "page_title_appversions"
+msgstr "ВерÑии приложениÑ"
+
+#: controllers/pages_controller.php:115
+msgid "page_title_collector"
+msgstr "Собиратель дополнений"
+
+#: controllers/pages_controller.php:117
+msgid "page_title_collector_faq"
+msgstr "FAQ ÑÐ¾Ð±Ð¸Ñ€Ð°Ñ‚ÐµÐ»Ñ Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ð¹"
+
+#: controllers/pages_controller.php:119
+msgid "page_title_collector_features"
+msgstr "ВозможноÑти ÑÐ¾Ð±Ð¸Ñ€Ð°Ñ‚ÐµÐ»Ñ Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ð¹"
+
+#: controllers/pages_controller.php:122
+msgid "page_title_collector_firstrun"
+msgstr "Добро пожаловать в Ñобиратель дополнений"
+
+#: controllers/pages_controller.php:92
+msgid "page_title_credits"
+msgstr "БлагодарноÑти"
+
+#: controllers/pages_controller.php:113
+msgid "page_title_developer_faq"
+msgstr "FAQ Ð´Ð»Ñ Ñ€Ð°Ð·Ñ€Ð°Ð±Ð¾Ñ‚Ñ‡Ð¸ÐºÐ°"
+
+#: controllers/pages_controller.php:111
+msgid "page_title_faq"
+msgstr "ЧаÑто задаваемые вопроÑÑ‹"
+
+#: controllers/pages_controller.php:94
+msgid "page_title_fashionyourfirefox_faq"
+msgstr "FAQ Ñайта «Прокачай Ñвой Firefox»"
+
+#: controllers/pages_controller.php:101
+msgid "page_title_policy"
+msgstr "Политика дополнений"
+
+#: controllers/pages_controller.php:103
+msgid "page_title_privacy"
+msgstr "Политика приватноÑти Mozilla"
+
+#: controllers/pages_controller.php:105
+msgid "page_title_review_guide"
+msgstr "Чем Ñледует руководÑтвоватьÑÑ Ð¿Ñ€Ð¸ ÑоÑтавлении рецензии"
+
+#: controllers/pages_controller.php:107
+msgid "page_title_sandbox"
+msgstr "СиÑтема Ñ€ÐµÑ†ÐµÐ½Ð·Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Â«Ð¿ÐµÑочницы»"
+
+#: controllers/pages_controller.php:109
+msgid "page_title_submissionhelp"
+msgstr "Помощь при отправке"
+
+#: views/pages/appversions.thtml:87
+msgid "pages_appversions_guid"
+msgstr "GUID"
+
+#: views/pages/appversions.thtml:79 controllers/pages_controller.php:90
+msgid "pages_appversions_header"
+msgstr "ДоÑтупные верÑии приложений"
+
+#: views/pages/appversions.thtml:80
+msgid "pages_appversions_intro"
+msgstr ""
+"ДополнениÑ, отправлÑемые на Mozilla Add-ons, должны Ñодержать файл install."
+"rdf. Причём в Ñтом файле должна приÑутÑтвовать запиÑÑŒ Ñ…Ð¾Ñ‚Ñ Ð±Ñ‹ об одном из "
+"приложений, перечиÑленных ниже. ДопуÑкаютÑÑ Ñ‚Ð¾Ð»ÑŒÐºÐ¾ перечиÑленные верÑии."
+
+#. %s is a full <a> tag
+#: views/pages/appversions.thtml:93
+#, php-format
+msgid "pages_appversions_required_files"
+msgstr ""
+"Даже еÑли приложению, в которое уÑтанавливаетÑÑ Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ðµ, не требуетÑÑ "
+"файл install.rdf, он вÑÑ‘ равно должен приÑутÑтвовать Ñ ÑƒÐºÐ°Ð·Ð°Ð½Ð¸ÐµÐ¼ требуемых "
+"ÑвойÑтв (как указано %s)."
+
+#. this is the text inside of an <a> tag for pages_appversions_required_files. This
+#. should be fixed.
+#: views/pages/appversions.thtml:93
+msgid "pages_appversions_required_files_link"
+msgstr "здеÑÑŒ"
+
+#: views/pages/appversions.thtml:88
+msgid "pages_appversions_versions"
+msgstr "ВерÑии"
+
+#: views/pages/policy.thtml:51
+msgid "pages_policy_sandbox_link"
+msgstr "Ñтраницу информации «пеÑочницы»"
+
+#: views/elements/pagination.thtml:53
+msgid "pagination_next_page"
+msgstr "ÑледующаÑ"
+
+#: views/elements/pagination.thtml:52
+msgid "pagination_previous_page"
+msgstr "предыдущаÑ"
+
+#: views/elements/recaptcha.thtml:65
+msgid "recaptcha_enter_both_words"
+msgstr ""
+"ПожалуйÑта введите <strong>оба Ñлова</strong> в раÑположенное ниже поле, "
+"<strong>разделив их пробелом</strong>."
+
+#: views/elements/recaptcha.thtml:83
+msgid "recaptcha_enter_here"
+msgstr "Введите здеÑÑŒ Ñвой ответ:"
+
+#: views/elements/recaptcha.thtml:74
+msgid "recaptcha_enter_whatyouhear"
+msgstr "ПожалуйÑта наберите то, что вы Ñлышите."
+
+# %1 is the link switching refreshing the captcha
+# %2 is the link switching to a text captcha
+#. %1 is the link switching refreshing the captcha
+#. %2 is the link switching to a text captcha
+#: views/elements/recaptcha.thtml:77
+msgid "recaptcha_hardtohear_text"
+msgstr ""
+"ЕÑли Ñто трудно Ð´Ð»Ñ Ð¿Ð¾Ð½Ð¸Ð¼Ð°Ð½Ð¸Ñ, вы можете <a href=\"%1$s\">проÑлушать что-"
+"либо ещё</a> или <a href=\"%2$s\">вернутьÑÑ Ðº вводу текÑта</a>."
+
+# %1 is the link switching refreshing the captcha
+# %2 is the link switching to an audio captcha
+#. %1 is the link switching refreshing the captcha
+#. %2 is the link switching to an audio captcha
+#: views/elements/recaptcha.thtml:68
+msgid "recaptcha_hardtoread_text"
+msgstr ""
+"ЕÑли Ñто трудно Ð´Ð»Ñ Ð¿Ñ€Ð¾Ñ‡Ñ‚ÐµÐ½Ð¸Ñ, вы можете <a href=\"%1$s\">попробовать "
+"прочеÑÑ‚ÑŒ другие Ñлова</a> или <a href=\"%2$s\">проÑлушать что-либо</a> "
+"вмеÑто чтениÑ."
+
+#: views/users/register.thtml:105
+msgid "recaptcha_label"
+msgstr "Вы человек?"
+
+#: views/users/register.thtml:106
+msgid "recaptcha_whatsthis"
+msgstr "Что Ñто?"
+
+#: controllers/reviews_controller.php:559
+msgid "review_flag_error"
+msgstr "Ошибка при пометке Ñтого отзыва!"
+
+#: models/reviews_moderation_flag.php:69
+msgid "review_flag_reason_bug_support"
+msgstr ""
+"Отправленное не по назначению Ñообщение об ошибке или проÑьба оказать "
+"поддержку"
+
+#: views/reviews/display.thtml:103 views/reviews/display.thtml:186
+msgid "review_flag_reason_instructions"
+msgstr "Сообщите от Ñтом отзыве (выберите причину)"
+
+#: models/reviews_moderation_flag.php:67
+msgid "review_flag_reason_language"
+msgstr "Ðеприемлемые выражениÑ/перебранка"
+
+#: models/reviews_moderation_flag.php:71
+msgid "review_flag_reason_other"
+msgstr "Ð”Ñ€ÑƒÐ³Ð°Ñ (пожалуйÑта укажите)"
+
+#: models/reviews_moderation_flag.php:65
+msgid "review_flag_reason_spam"
+msgstr "Спам или другое неÑоответÑтвующее Ñодержимое"
+
+#: views/reviews/display.thtml:91 views/reviews/display.thtml:175
+#: controllers/reviews_controller.php:555
+msgid "review_flag_success"
+msgstr "СпаÑибо; Ñтот отзыв помечен и будет раÑÑмотрен редактором."
+
+#: views/reviews/display.thtml:41
+msgid "review_flag_this"
+msgstr "Сообщить об Ñтом отзыве"
+
+#: views/reviews/display.thtml:42
+msgid "review_flag_this_titletip"
+msgstr ""
+"ЕÑли вы думаете, что Ñтот отзыв неумеÑтен, некорректен или ÑвлÑетÑÑ Ñпамом, "
+"щёлкните здеÑÑŒ, чтобы отправить его на раÑÑмотрение редактору."
+
+# %1 is the URL of the support section, %2 for the review guidelines
+#. %1 is the URL of the support section, %2 for the review guidelines
+#: views/reviews/add.thtml:53
+msgid "review_guidelines_short"
+msgstr ""
+"<p>ÐеÑколько Ñоветов, к которым Ñтоит приÑлушатьÑÑ:</p><ul><li>Пишите отзыв "
+"так, как будто вы раÑÑказываете другу о Ñвоей работе Ñ Ñтим дополнением. "
+"Подробно опишите ваш опыт работы Ñ Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸ÐµÐ¼ и ваши Ð¿Ð¾Ð¶ÐµÐ»Ð°Ð½Ð¸Ñ â€” какие "
+"возможноÑти Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð²Ð°Ð¼ понравилиÑÑŒ или не понравилиÑÑŒ, наÑколько легко "
+"им пользоватьÑÑ, какие в нём имеютÑÑ Ð½ÐµÐ´Ð¾Ñтатки. Избегайте общих фраз вроде "
+"«Круто» или «ОтÑтой», еÑли вы не можете привеÑти причины, почему вы так "
+"Ñчитаете.</li><li>ПожалуйÑта, не оÑтавлÑйте в отзывах ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ Ð¾Ð± ошибках. "
+"Мы не Ñообщаем ваш почтовый Ð°Ð´Ñ€ÐµÑ Ñ€Ð°Ð·Ñ€Ð°Ð±Ð¾Ñ‚Ñ‡Ð¸ÐºÐ°Ð¼ дополнений, а им может "
+"потребоватьÑÑ ÑвÑзатьÑÑ Ñ Ð²Ð°Ð¼Ð¸, чтобы помочь решить вашу проблему. Ð”Ð»Ñ "
+"Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ñ Ñведений о том, где можно получить помощь по работе Ñ Ñтим "
+"дополнением, обратитеÑÑŒ в <a href=\"%1$s\">раздел поддержки</a>.</li><li> "
+"ПожалуйÑта, не заÑорÑйте отзывы ненужной информацией, не иÑпользуйте "
+"неприличные Ð²Ñ‹Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ Ð¸ не оÑтавлÑйте какую-либо перÑональную информацию. </"
+"li></ul><p>Ð”Ð»Ñ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ñ Ð±Ð¾Ð»ÐµÐµ подробной информации об отзывах "
+"пользователей о дополнениÑÑ…, пожалуйÑта прочтите <a href=\"%2$s\">Советы по "
+"оÑтавлению отзывов</a>.</p>"
+
+#. %1 is the add-on name
+#: views/reviews/flag.thtml:56 views/reviews/display.thtml:55
+#: views/reviews/review_added.thtml:50
+#, php-format
+msgid "reviews_header"
+msgstr "Отзывы о %s"
+
+#: controllers/addons_controller.php:435
+msgid "rss_featuredaddons"
+msgstr "ПопулÑрные дополнениÑ"
+
+#: controllers/addons_controller.php:432
+msgid "rss_newestaddons"
+msgstr "Ðовейшие дополнениÑ"
+
+#: controllers/addons_controller.php:434
+msgid "rss_popularaddons"
+msgstr "ПопулÑрные дополнениÑ"
+
+#: controllers/addons_controller.php:433
+msgid "rss_updatedaddons"
+msgstr "Обновлённые дополнениÑ"
+
+#: views/elements/search_mini.thtml:70
+msgid "search"
+msgstr "ПоиÑк"
+
+#: views/search/collections.thtml:51
+msgid "search_collections_header"
+msgstr "Результаты поиÑка набора"
+
+#: controllers/search_controller.php:297
+msgid "search_collections_pagetitle"
+msgstr "Результаты поиÑка набора"
+
+#: controllers/search_controller.php:99
+msgid "search_disabled"
+msgstr "Ð’ данный момент поиÑк отключен. ПожалуйÑта, попробуйте позже."
+
+#: views/elements/amo2009/search.thtml:188 views/elements/search.thtml:187
+#: views/elements/search_mini.thtml:54
+msgid "search_form_all_addons"
+msgstr "Ð’Ñех дополнений"
+
+#. This string is in the main category dropdown when searching
+#: views/elements/amo2009/search.thtml:204
+msgid "search_form_all_collections"
+msgstr "вÑе наборы"
+
+#: views/elements/amo2009/search.thtml:184
+#: views/elements/amo2009/search.thtml:385
+#: views/elements/amo2009/search.thtml:408 views/elements/search.thtml:171
+#: views/elements/search.thtml:183 views/elements/search_mini.thtml:43
+#: views/elements/search_mini.thtml:49 views/layouts/mozilla.thtml:188
+msgid "search_form_default_text"
+msgstr "поиÑк дополнений"
+
+#: views/elements/amo2009/search.thtml:184
+#: views/elements/amo2009/search.thtml:404
+msgid "search_form_default_text_collections"
+msgstr "поиÑк наборов"
+
+#: views/elements/amo2009/search.thtml:206 views/elements/search.thtml:202
+msgid "search_form_submit_tooltip"
+msgstr "ПоиÑк дополнений"
+
+#: views/elements/amo2009/search.thtml:184 views/elements/search.thtml:183
+#: views/elements/search_mini.thtml:49
+msgid "search_form_tooltip"
+msgstr "Щёлкните, чтобы ввеÑти Ð·Ð°Ð¿Ñ€Ð¾Ñ Ð½Ð° поиÑк"
+
+#: views/elements/amo2009/search.thtml:186 views/elements/search.thtml:185
+#: views/elements/search_mini.thtml:52
+msgid "search_form_within"
+msgstr "Ñреди"
+
+#: views/addons/searchengines.thtml:118
+msgid "search_landing_all_search_engines"
+msgstr "Ð’Ñе поиÑковые плагины"
+
+#: views/addons/searchengines.thtml:114
+msgid "search_landing_browse_search_engines"
+msgstr "Обзор поиÑковых плагинов"
+
+#: views/search/collections.thtml:58 views/search/index.thtml:59
+msgid "search_nothing_found"
+msgstr "ПоиÑк не дал результатов."
+
+#: controllers/search_controller.php:185
+msgid "search_pagetitle"
+msgstr "ПоиÑк дополнений"
+
+#: controllers/search_controller.php:242
+msgid "search_rss_description"
+msgstr "Выдача результатов поиÑка"
+
+#. %s is the terms the user is searching for (a string)
+#: controllers/search_controller.php:241
+#, php-format
+msgid "search_rss_results_for"
+msgstr "Результаты поиÑка: %s"
+
+#: views/elements/header.thtml:154 views/layouts/amo2009.thtml:296
+msgid "sidebar_navlink_admin_tools"
+msgstr "ИнÑтрументы Ð´Ð»Ñ Ð°Ð´Ð¼Ð¸Ð½Ð¸ÑтрированиÑ"
+
+#: views/elements/header.thtml:146 views/layouts/amo2009.thtml:288
+msgid "sidebar_navlink_developer_tools"
+msgstr "ИнÑтрументы разработчика"
+
+#: views/elements/header.thtml:148 views/layouts/amo2009.thtml:290
+msgid "sidebar_navlink_editor_tools"
+msgstr "ИнÑтрументы Ð´Ð»Ñ Ñ€ÐµÐ´Ð°ÐºÑ‚Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ"
+
+#: views/layouts/amo2009.thtml:302
+msgid "sidebar_navlink_welcome"
+msgstr "Добро пожаловать"
+
+#. %s is the user's name
+#: views/layouts/amo2009.thtml:302
+#, php-format
+msgid "sidebar_navlink_welcome_name"
+msgstr "Добро пожаловать, %s"
+
+#: views/elements/pitch.thtml:50 views/elements/pitch.thtml:55
+msgid "sidebar_pitch_dictionary"
+msgstr "Словарь"
+
+#: views/elements/pitch.thtml:72
+msgid "sidebar_pitch_featured_addons"
+msgstr "Избранные дополнениÑ"
+
+#: views/elements/pitch.thtml:61
+msgid "sidebar_pitch_looking_for"
+msgstr "Я ищу:"
+
+#: views/elements/pitch.thtml:70
+msgid "sidebar_pitch_newest_addons"
+msgstr "Ðовейшие дополнениÑ"
+
+#: views/elements/pitch.thtml:49
+msgid "sidebar_pitch_search"
+msgstr "ПоиÑковый плагин"
+
+#: views/elements/pitch.thtml:69
+msgid "sidebar_pitch_subscribe_to"
+msgstr "ПодпиÑатьÑÑ Ð½Ð°"
+
+#: views/elements/pitch.thtml:48 views/elements/pitch.thtml:54
+msgid "sidebar_pitch_theme"
+msgstr "Тему"
+
+#: views/elements/pitch.thtml:71
+msgid "sidebar_pitch_updated_addons"
+msgstr "Обновлённые дополнениÑ"
+
+#. %1$s is a number
+#: views/helpers/localization.php:65 views/developers/versions_edit.thtml:95
+#: views/addons/dictionaries.thtml:92
+#, php-format
+msgid "size_kb"
+msgstr "%1$s КБ"
+
+#: views/elements/amo2009/stars.thtml:57 views/elements/stars.thtml:63
+msgid "stars_not_yet_rated"
+msgstr "Пока не оценено"
+
+# %1 is the number of stars this add-on has
+#. %1 is the number of stars this add-on has
+#: views/elements/amo2009/stars.thtml:49 views/elements/stars.thtml:54
+#, php-format
+msgid "stars_rated_x_outof_5"
+msgstr "Оценка %s из 5 звёзд"
+
+#: views/statistics/addon.thtml:59
+msgid "statistics_addon_dashboard_link"
+msgstr "ÐÐ°Ñ‡Ð°Ð»ÑŒÐ½Ð°Ñ Ñтраница панели"
+
+#: views/statistics/addon.thtml:58
+msgid "statistics_addon_developertools_link"
+msgstr "ИнÑтрументы разработчика"
+
+#: views/statistics/addon.thtml:53
+msgid "statistics_addon_switch"
+msgstr "Сменить дополнение"
+
+#. This is a date format.
+#. http://php.net/strftime
+#: views/statistics/rss/summary.thtml:54 views/statistics/addon.thtml:181
+msgid "statistics_date_shortmonth"
+msgstr "%d.%m."
+
+#. This is a date format.
+#. http://php.net/strftime
+#: views/statistics/rss/summary.thtml:40 views/statistics/addon.thtml:152
+msgid "statistics_date_shortmonthwithyear"
+msgstr "%d.%m.%Y"
+
+#. This is a date format.
+#. http://php.net/strftime
+#: views/statistics/rss/summary.thtml:41 views/statistics/rss/summary.thtml:48
+#: views/statistics/addon.thtml:161 views/statistics/addon.thtml:172
+msgid "statistics_date_weekdayshortmonth"
+msgstr "%A, %d.%m."
+
+#. %1$s is an add-on name and version. Example: Add-on 3.5
+#: controllers/components/stats.php:519
+#, php-format
+msgid "statistics_events_addon_created"
+msgstr "%1$s Ñоздано"
+
+#. %1$s is an application name and version. Example: Firefox 3.5
+#: controllers/components/stats.php:500
+#, php-format
+msgid "statistics_events_app_released"
+msgstr "%1$s выпущено"
+
+#: views/statistics/addon.thtml:71
+msgid "statistics_help_close_link"
+msgstr "Закрыть"
+
+#: views/statistics/addon.thtml:60
+msgid "statistics_help_link"
+msgstr "Справка"
+
+#: views/statistics/index.thtml:83
+msgid "statistics_index_anotheraddon"
+msgstr "или выберите другое дополнение"
+
+#: views/statistics/index.thtml:85
+msgid "statistics_index_anotheraddon_public"
+msgstr "или выберите дополнение Ñ Ð¿ÑƒÐ±Ð»Ð¸Ñ‡Ð½Ð¾Ð¹ ÑтатиÑтикой"
+
+#: views/statistics/index.thtml:71
+msgid "statistics_index_myaddons"
+msgstr "Выберите одно из ваших дополнений Ð´Ð»Ñ Ð¿Ñ€Ð¾Ñмотра его ÑтатиÑтики"
+
+#: views/statistics/index.thtml:89
+msgid "statistics_index_selectaddon"
+msgstr "Выберите дополнение Ð´Ð»Ñ Ð¿Ñ€Ð¾Ñмотра его ÑтатиÑтики"
+
+#: views/statistics/index.thtml:91
+msgid "statistics_index_selectaddon_public"
+msgstr "Выберите дополнение Ñ Ð¿ÑƒÐ±Ð»Ð¸Ñ‡Ð½Ð¾Ð¹ ÑтатиÑтикой"
+
+#: views/statistics/index.thtml:39
+msgid "statistics_index_title"
+msgstr "Панель ÑтатиÑтики"
+
+#: views/statistics/index.thtml:97
+msgid "statistics_index_view_button"
+msgstr "ПроÑмотреть ÑтатиÑтику"
+
+#: views/statistics/addon.thtml:222 controllers/statistics_controller.php:247
+msgid "statistics_js_download_csv"
+msgstr "ПроÑмотреть Ñту таблицу в формате CSV"
+
+#: controllers/statistics_controller.php:246
+msgid "statistics_js_dropdowns_none"
+msgstr "нет"
+
+#: controllers/statistics_controller.php:245
+msgid "statistics_js_dropdowns_removeplot"
+msgstr "Удалить Ñту диаграмму"
+
+#: controllers/statistics_controller.php:248
+msgid "statistics_js_groupby_selector_date"
+msgstr "Группировать по: Дню"
+
+#: controllers/statistics_controller.php:251
+msgid "statistics_js_groupby_selector_month"
+msgstr "Группировать по: МеÑÑцу"
+
+#: controllers/statistics_controller.php:249
+msgid "statistics_js_groupby_selector_week"
+msgstr "Группировать по: Ðеделе"
+
+#: controllers/statistics_controller.php:250
+msgid "statistics_js_groupby_selector_week_over_week"
+msgstr "Сравнить по: Ðеделе"
+
+#: controllers/statistics_controller.php:260
+msgid "statistics_js_plotselection_foundinrange"
+msgstr "В диапазоне найдено %s штук"
+
+#: controllers/statistics_controller.php:270
+msgid "statistics_js_plotselection_options_addplot_name"
+msgstr "Добавить график"
+
+#: controllers/statistics_controller.php:271
+msgid "statistics_js_plotselection_options_addplot_tooltip"
+msgstr "Добавить ещё один график к Ñтой диаграмме"
+
+#: controllers/statistics_controller.php:261
+msgid "statistics_js_plotselection_options_count_name_checked"
+msgstr "Скрыть общее кол-во"
+
+#: controllers/statistics_controller.php:262
+msgid "statistics_js_plotselection_options_count_name_unchecked"
+msgstr "Показать общее кол-во"
+
+#: controllers/statistics_controller.php:263
+msgid "statistics_js_plotselection_options_count_tooltip"
+msgstr "ÐанеÑти общее кол-во на Ñту диаграмму"
+
+#: controllers/statistics_controller.php:275
+msgid "statistics_js_plotselection_options_csv_name"
+msgstr "ПроÑмотр данных (CSV)"
+
+#: controllers/statistics_controller.php:276
+msgid "statistics_js_plotselection_options_csv_tooltip"
+msgstr "Получить файл Ñ Ñ€Ð°Ð·Ð´ÐµÐ»Ñ‘Ð½Ð½Ñ‹Ð¼Ð¸ запÑтыми данными (CSV)"
+
+#: controllers/statistics_controller.php:267
+msgid "statistics_js_plotselection_options_events_addon_name_checked"
+msgstr "Скрыть %s Ñобытий"
+
+#: controllers/statistics_controller.php:268
+msgid "statistics_js_plotselection_options_events_addon_name_unchecked"
+msgstr "Показать %s Ñобытий"
+
+#: controllers/statistics_controller.php:269
+msgid "statistics_js_plotselection_options_events_addon_tooltip"
+msgstr "ÐанеÑти даты релизов Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð½Ð° графики"
+
+#: controllers/statistics_controller.php:264
+msgid "statistics_js_plotselection_options_events_firefox_name_checked"
+msgstr "Скрыть ÑÐ¾Ð±Ñ‹Ñ‚Ð¸Ñ Firefox"
+
+#: controllers/statistics_controller.php:265
+msgid "statistics_js_plotselection_options_events_firefox_name_unchecked"
+msgstr "Показать ÑÐ¾Ð±Ñ‹Ñ‚Ð¸Ñ Firefox"
+
+#: controllers/statistics_controller.php:266
+msgid "statistics_js_plotselection_options_events_firefox_tooltip"
+msgstr "ÐанеÑти даты релизов Firefox на графики"
+
+#: controllers/statistics_controller.php:272
+msgid "statistics_js_plotselection_options_resize_name_checked"
+msgstr "Свернуть диаграмму"
+
+#: controllers/statistics_controller.php:273
+msgid "statistics_js_plotselection_options_resize_name_unchecked"
+msgstr "Развернуть диаграмму"
+
+#: controllers/statistics_controller.php:274
+msgid "statistics_js_plotselection_options_resize_tooltip"
+msgstr "Изменить размер диаграммы"
+
+#: controllers/statistics_controller.php:254
+msgid "statistics_js_plotselection_selector_adu"
+msgstr "Ðктивных ежедневных пользователей"
+
+#: controllers/statistics_controller.php:256
+msgid "statistics_js_plotselection_selector_application"
+msgstr "Приложение"
+
+#: controllers/statistics_controller.php:259
+msgid "statistics_js_plotselection_selector_custom"
+msgstr "ÐаÑтроить"
+
+#: controllers/statistics_controller.php:253
+msgid "statistics_js_plotselection_selector_downloads"
+msgstr "Загрузки"
+
+#: controllers/statistics_controller.php:258
+msgid "statistics_js_plotselection_selector_os"
+msgstr "ÐžÐ¿ÐµÑ€Ð°Ñ†Ð¸Ð¾Ð½Ð½Ð°Ñ ÑиÑтема"
+
+#: controllers/statistics_controller.php:257
+msgid "statistics_js_plotselection_selector_status"
+msgstr "Ð¡Ñ‚Ð°Ñ‚ÑƒÑ Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ"
+
+#: controllers/statistics_controller.php:252
+msgid "statistics_js_plotselection_selector_summary"
+msgstr "Сводка"
+
+#: controllers/statistics_controller.php:255
+msgid "statistics_js_plotselection_selector_version"
+msgstr "ВерÑÐ¸Ñ Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ"
+
+#: controllers/components/stats.php:398
+msgid "statistics_longnames_application"
+msgstr "Приложение"
+
+#: controllers/components/stats.php:400
+msgid "statistics_longnames_os"
+msgstr "ÐžÐ¿ÐµÑ€Ð°Ñ†Ð¸Ð¾Ð½Ð½Ð°Ñ ÑиÑтема"
+
+#: controllers/components/stats.php:399
+msgid "statistics_longnames_status"
+msgstr "Ð¡Ñ‚Ð°Ñ‚ÑƒÑ Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ"
+
+#: controllers/components/stats.php:401
+msgid "statistics_longnames_unknown"
+msgstr "ÐеизвеÑтно"
+
+#: controllers/components/stats.php:397
+msgid "statistics_longnames_version"
+msgstr "ВерÑÐ¸Ñ Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ"
+
+#: views/statistics/addon.thtml:118
+msgid "statistics_notice_data_insufficient"
+msgstr ""
+"Ð”Ð»Ñ Ð¾Ñ‚Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ Ñтой диаграммы пока ещё не хватает данных. ПожалуйÑта "
+"вернитеÑÑŒ попозже. "
+
+#: views/statistics/addon.thtml:130
+msgid "statistics_notice_data_none"
+msgstr ""
+"У Ð½Ð°Ñ Ð¿Ð¾ÐºÐ° нет никаких данных Ð´Ð»Ñ Ð²Ð°ÑˆÐµÐ³Ð¾ дополнениÑ. ПожалуйÑта вернитеÑÑŒ "
+"через неÑколько дней. "
+
+#: views/statistics/addon.thtml:41
+msgid "statistics_notice_data_updating"
+msgstr ""
+"Ð’ данный момент идёт процеÑÑ Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ ÑтатиÑтики дополнений. ПоÑледние "
+"данные могут быть неполны, так как наши Ñкрипты обновлÑÑŽÑ‚ Ñту информацию. "
+"ПожалуйÑта вернитеÑÑŒ через неÑколько минут. "
+
+#: views/statistics/addon.thtml:136
+msgid "statistics_notice_disabled"
+msgstr ""
+"Панель ÑтатиÑтики в данное Ð²Ñ€ÐµÐ¼Ñ Ð¾Ñ‚ÐºÐ»ÑŽÑ‡ÐµÐ½Ð°. ПожалуйÑта вернитеÑÑŒ попозже. "
+
+#: views/statistics/addon.thtml:123
+msgid "statistics_notice_nojavascript"
+msgstr "Ð”Ð»Ñ Ð¿Ñ€Ð¾Ñмотра диаграмм панели ÑтатиÑтики требуетÑÑ JavaScript."
+
+#: views/statistics/addon.thtml:44
+msgid "statistics_notice_settings_updated"
+msgstr "Ваши наÑтройки были обновлены!"
+
+#: controllers/statistics_controller.php:60
+#: controllers/statistics_controller.php:71
+#: controllers/statistics_controller.php:74
+#: controllers/statistics_controller.php:240
+msgid "statistics_pagetitle"
+msgstr "Панель ÑтатиÑтики"
+
+#: views/statistics/addon.thtml:99
+msgid "statistics_plot_legend_adu"
+msgstr "Ðктивных пользователей в день"
+
+#: views/statistics/addon.thtml:95
+msgid "statistics_plot_legend_downloads"
+msgstr "Загрузок в день"
+
+#: views/statistics/addon.thtml:107
+msgid "statistics_plot_options_zoomin_alt"
+msgstr "Скрыть"
+
+#: views/statistics/addon.thtml:106
+msgid "statistics_plot_options_zoomin_title"
+msgstr "Скрыть один меÑÑц"
+
+#: views/statistics/addon.thtml:110
+msgid "statistics_plot_options_zoomout_alt"
+msgstr "Показать"
+
+#: views/statistics/addon.thtml:109
+msgid "statistics_plot_options_zoomout_title"
+msgstr "Показать ещё один меÑÑц"
+
+#: controllers/statistics_controller.php:283
+#, php-format
+msgid "statistics_rss_description"
+msgstr "Ð•Ð¶ÐµÐ´Ð½ÐµÐ²Ð½Ð°Ñ Ñводка ÑтатиÑтики Ð´Ð»Ñ %1$s"
+
+#: views/statistics/rss/summary.thtml:68
+msgid "statistics_rss_title_fulldate"
+msgstr "%A, %d.%m.%Y"
+
+#: views/statistics/rss/summary.thtml:68
+#, php-format
+msgid "statistics_rss_title_statsfordate"
+msgstr "СтатиÑтика Ð´Ð»Ñ %1$s"
+
+#: views/statistics/settings.thtml:49
+msgid "statistics_settings_access_description"
+msgstr ""
+"По умолчанию, только вы и Mozilla имеют доÑтуп к информации на вашей панели. "
+"Ð’Ñ‹ можете открыть её Ð´Ð»Ñ Ð¿ÑƒÐ±Ð»Ð¸ÐºÐ¸, чтобы любой мог видеть данные по вашему "
+"дополнению."
+
+#: views/statistics/settings.thtml:48
+msgid "statistics_settings_access_heading"
+msgstr "ДоÑтуп к панели"
+
+#: views/statistics/settings.thtml:51
+msgid "statistics_settings_access_private"
+msgstr "Приватный"
+
+#: views/statistics/settings.thtml:51
+msgid "statistics_settings_access_private_description"
+msgstr "Только вы и Mozilla могут проÑматривать ÑтатиÑтику Ñтого Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ "
+
+#: views/statistics/settings.thtml:52
+msgid "statistics_settings_access_public"
+msgstr "Публичный"
+
+#: views/statistics/settings.thtml:52
+msgid "statistics_settings_access_public_description"
+msgstr "Любой может проÑматривать ÑтатиÑтику Ñтого дополнениÑ"
+
+#: views/statistics/addon.thtml:251
+msgid "statistics_settings_change_link"
+msgstr "Изменить наÑтройки"
+
+#: views/statistics/addon.thtml:253
+msgid "statistics_settings_confidential"
+msgstr "ПожалуйÑта обращайтеÑÑŒ Ñ Ñтой информацией как Ñ ÐºÐ¾Ð½Ñ„Ð¸Ð´ÐµÐ½Ñ†Ð¸Ð°Ð»ÑŒÐ½Ð¾Ð¹."
+
+#: views/statistics/addon.thtml:245
+msgid "statistics_settings_currently_private"
+msgstr "Эта панель в данный момент <b>приватнаÑ</b>."
+
+#: views/statistics/addon.thtml:241
+msgid "statistics_settings_currently_public"
+msgstr "Эта панель в данный момент <b>публичнаÑ</b>."
+
+#: views/statistics/addon.thtml:246
+msgid "statistics_settings_locked_alt"
+msgstr "Заблокированы"
+
+#: views/statistics/settings.thtml:57
+msgid "statistics_settings_return_link"
+msgstr "ВозвратитьÑÑ Ð½Ð° панель"
+
+#: views/statistics/settings.thtml:56
+msgid "statistics_settings_save_button"
+msgstr "Сохранить наÑтройки"
+
+#: views/statistics/settings.thtml:46
+#, php-format
+msgid "statistics_settings_title"
+msgstr "ÐаÑтройки панели ÑтатиÑтики Ð´Ð»Ñ %1$s"
+
+#: views/statistics/addon.thtml:242
+msgid "statistics_settings_unlocked_alt"
+msgstr "Ðезаблокированы"
+
+#: controllers/components/stats.php:405
+msgid "statistics_shortnames_application"
+msgstr "Прил."
+
+#: controllers/components/stats.php:407
+msgid "statistics_shortnames_os"
+msgstr "ОС"
+
+#: controllers/components/stats.php:406
+msgid "statistics_shortnames_status"
+msgstr "Стат."
+
+#: controllers/components/stats.php:408
+msgid "statistics_shortnames_unknown"
+msgstr "Ðеизв."
+
+#: controllers/components/stats.php:404
+msgid "statistics_shortnames_version"
+msgstr "Вер."
+
+#: views/statistics/rss/summary.thtml:42 views/statistics/addon.thtml:192
+msgid "statistics_summary_downloads_average"
+msgstr "Среднее кол-во загрузок за день"
+
+#: views/statistics/rss/summary.thtml:39
+msgid "statistics_summary_downloads_heading"
+msgstr "Загрузки"
+
+#: views/statistics/rss/summary.thtml:41 views/statistics/addon.thtml:171
+msgid "statistics_summary_downloads_lastcount"
+msgstr "Загрузок за поÑледний день"
+
+#: views/statistics/rss/summary.thtml:43 views/statistics/addon.thtml:199
+msgid "statistics_summary_downloads_lastweek"
+msgstr "Загрузок за поÑледние 7 дней"
+
+#: views/statistics/rss/summary.thtml:40 views/statistics/addon.thtml:151
+msgid "statistics_summary_downloads_total"
+msgstr "Ð’Ñего загрузок"
+
+#: views/statistics/rss/summary.thtml:40 views/statistics/addon.thtml:152
+#, php-format
+msgid "statistics_summary_downloads_total_sincedate"
+msgstr "С %1$s"
+
+#: views/statistics/rss/summary.thtml:50 views/statistics/rss/summary.thtml:56
+#: views/statistics/addon.thtml:163 views/statistics/addon.thtml:183
+msgid "statistics_summary_nodata"
+msgstr "Данных ещё нет"
+
+#: views/statistics/rss/summary.thtml:60 views/statistics/addon.thtml:195
+msgid "statistics_summary_updatepings_average"
+msgstr "Среднее кол-во активных пользователей за день"
+
+#: views/statistics/rss/summary.thtml:52 views/statistics/addon.thtml:177
+msgid "statistics_summary_updatepings_changefromprevious"
+msgstr "Изменение от предыдущего кол-ва"
+
+#: views/statistics/rss/summary.thtml:54 views/statistics/addon.thtml:181
+#, php-format
+msgid "statistics_summary_updatepings_changefromprevious_ondate"
+msgstr "%1$s в %2$s"
+
+#: views/statistics/rss/summary.thtml:45
+msgid "statistics_summary_updatepings_heading"
+msgstr "Ðктивных пользователей в день"
+
+#: views/statistics/rss/summary.thtml:46 views/statistics/addon.thtml:157
+msgid "statistics_summary_updatepings_total"
+msgstr "Ðктивных пользователей в день"
+
+#: views/statistics/rss/summary.thtml:48 views/statistics/addon.thtml:161
+#, php-format
+msgid "statistics_summary_updatepings_total_ondate"
+msgstr "Ðа %1$s"
+
+#: views/statistics/rss/summary.thtml:61 views/statistics/addon.thtml:203
+msgid "statistics_summary_updatepings_weekly_average"
+msgstr "Среднее кол-во активных ежедневных пользователей за Ñту неделю"
+
+#. %s is a percentage, like '+22.33%'. It sits next to another number, so
+#. the implied meaning is 'percentage change' from the previous stat point.
+#: views/statistics/rss/summary.thtml:62 views/statistics/addon.thtml:205
+msgid "statistics_summary_updatepings_weekly_change"
+msgstr "%s Ñ Ð¿Ñ€Ð¾ÑˆÐ»Ð¾Ð¹ недели"
+
+#: views/statistics/addon.thtml:65 controllers/statistics_controller.php:184
+#: controllers/statistics_controller.php:282
+#, php-format
+msgid "statistics_title_addon_stats"
+msgstr "СтатиÑтика %1$s"
+
+#: views/addons/themes_landing.thtml:113
+msgid "themes_landing_all_themes"
+msgstr "Ð’Ñе темы"
+
+#: views/addons/themes_landing.thtml:109
+msgid "themes_landing_browse_themes"
+msgstr "Обзор тем"
+
+#: views/users/edit.thtml:185
+msgid "user_change_email"
+msgstr "Сменить Ð°Ð´Ñ€ÐµÑ Ñлектронной почты"
+
+#: views/users/edit.thtml:169
+msgid "user_change_password"
+msgstr "Сменить пароль"
+
+#: views/users/edit.thtml:96
+msgid "user_change_password_or_email"
+msgstr "Сменить пароль или Ð°Ð´Ñ€ÐµÑ Ñлектронной почты"
+
+#: controllers/users_controller.php:197
+msgid "user_confirmationcode_resent"
+msgstr "Код Ð¿Ð¾Ð´Ñ‚Ð²ÐµÑ€Ð¶Ð´ÐµÐ½Ð¸Ñ Ð±Ñ‹Ð» отправлен повторно!"
+
+# %1 is the email address, %2 is the URL of the user registration page
+#. %1 is the email address, %2 is the URL of the user registration page
+#: views/users/delete.thtml:51
+msgid "user_del_account_deleted"
+msgstr ""
+"Ваша ÑƒÑ‡Ñ‘Ñ‚Ð½Ð°Ñ Ð·Ð°Ð¿Ð¸ÑÑŒ %1$s была уÑпешно удалена. ЕÑли вы захотите вернутьÑÑ, "
+"вы можете зарегиÑтрироватьÑÑ Ñнова на <a href=\"%2$s\">Ñтранице региÑтрации</"
+"a>."
+
+#: views/users/delete.thtml:102
+msgid "user_del_community_sad"
+msgstr "Мы опечалены тем, что вы уходите."
+
+#: views/users/delete.thtml:123
+msgid "user_del_confirm_password"
+msgstr "Подтвердите пароль"
+
+#: views/users/delete.thtml:134
+msgid "user_del_deletenow"
+msgstr "Удалить мою учётную запиÑÑŒ"
+
+# %1 is the URL of the user's info page
+#. %1 is the URL of the user's info page
+#: views/users/delete.thtml:64
+msgid "user_del_error_addons"
+msgstr ""
+"Ð’Ñ‹ не можете удалить Ñвою учётную запиÑÑŒ, еÑли вы указаны в качеÑтве <a href="
+"\"%1$s\">автора какого-либо дополнениÑ</a>. Чтобы удалить Ñвою учётную "
+"запиÑÑŒ, попроÑите другого разработчика Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ ÑƒÐ´Ð°Ð»Ð¸Ñ‚ÑŒ Ð²Ð°Ñ Ð¸Ð· ÑпиÑка "
+"авторов ваших дополнений. ПоÑле Ñтого вы Ñможете удалить Ñвою учётную запиÑÑŒ."
+
+# %1 is a link to the amo-editors mailing list
+#. %1 is a link to the amo-editors mailing list
+#: views/users/delete.thtml:71
+msgid "user_del_error_addons_more_questions"
+msgstr "ЕÑли у Ð²Ð°Ñ Ð¸Ð¼ÐµÑŽÑ‚ÑÑ Ð´Ð¾Ð¿Ð¾Ð»Ð½Ð¸Ñ‚ÐµÐ»ÑŒÐ½Ñ‹Ðµ вопроÑÑ‹, обратитеÑÑŒ в %1$s."
+
+#: views/users/delete.thtml:78
+msgid "user_del_error_checkbox"
+msgstr ""
+"Ð”Ð»Ñ ÑƒÐ´Ð°Ð»ÐµÐ½Ð¸Ñ ÑƒÑ‡Ñ‘Ñ‚Ð½Ð¾Ð¹ запиÑи необходимо уÑтановить флажок \"Я понимаю...\"."
+
+#: views/users/delete.thtml:84
+msgid "user_del_error_password"
+msgstr "Ð”Ð»Ñ Ð²Ñ‹Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ñтого шага введите правильный пароль."
+
+# %1 is a link to the amo-admins mailing list
+#. %1 is a link to the amo-admins mailing list
+#: views/users/delete.thtml:91
+msgid "user_del_error_unknown"
+msgstr ""
+"При удалении вашей учётной запиÑи произошла неизвеÑÑ‚Ð½Ð°Ñ Ð¾ÑˆÐ¸Ð±ÐºÐ°. Ð”Ð»Ñ "
+"Ñ€Ð°Ð·Ñ€ÐµÑˆÐµÐ½Ð¸Ñ Ñтой проблемы ÑвÑжитеÑÑŒ Ñ %1$s и мы удалим Ñту учётную запиÑÑŒ. "
+"ПриноÑим Ñвои Ð¸Ð·Ð²Ð¸Ð½ÐµÐ½Ð¸Ñ Ð·Ð° причинённые неудобÑтва."
+
+#: views/users/delete.thtml:110
+msgid "user_del_header_confirm_deletion"
+msgstr "Подтверждение ÑƒÐ´Ð°Ð»ÐµÐ½Ð¸Ñ ÑƒÑ‡Ñ‘Ñ‚Ð½Ð¾Ð¹ запиÑи"
+
+# %1 is the user's email address
+#. %1 is the user's email address
+#: views/users/delete.thtml:100
+msgid "user_del_header_delete_account"
+msgstr "Удаление учётной запиÑи %1$s"
+
+#: views/users/delete.thtml:50
+msgid "user_del_header_farewell"
+msgstr "Прощайте!"
+
+#: views/users/delete.thtml:115
+msgid "user_del_nologin"
+msgstr "Ð’Ñ‹ больше не Ñможете зарегиÑтрироватьÑÑ Ð½Ð° Ñайте Mozilla Addons."
+
+#: views/users/delete.thtml:112
+msgid "user_del_permanently_removed_means"
+msgstr ""
+"При нажатии кнопки \"удалить\" ваша ÑƒÑ‡Ñ‘Ñ‚Ð½Ð°Ñ Ð·Ð°Ð¿Ð¸ÑÑŒ будет <strong>навÑегда "
+"удалена</strong>. Это значит:"
+
+#: views/users/delete.thtml:116
+msgid "user_del_reviews_anonymized"
+msgstr ""
+"Ваши отзывы и рейтинги не будут удалены, но они больше не будут Ñ Ð²Ð°Ð¼Ð¸ "
+"ÑвÑзаны."
+
+# %1 is a link to the amo-editors mailing list
+#. %1 is a link to the amo-editors mailing list
+#: views/users/delete.thtml:104
+msgid "user_del_specific_problem_editors"
+msgstr ""
+"ЕÑли у Ð²Ð°Ñ Ð¸Ð¼ÐµÐµÑ‚ÑÑ ÑÐ¿ÐµÑ†Ð¸Ñ„Ð¸Ñ‡Ð½Ð°Ñ Ð¿Ñ€Ð¾Ð±Ð»ÐµÐ¼Ð°, Ñ ÐºÐ¾Ñ‚Ð¾Ñ€Ð¾Ð¹ мы можем помочь, "
+"пожалуйÑта не удалÑйте Ñвою учётную запиÑÑŒ. СвÑжитеÑÑŒ Ñ Ð½Ð°Ð¼Ð¸ по адреÑу %1$s "
+"и мы приложим вÑе уÑÐ¸Ð»Ð¸Ñ Ð¿Ð¾ решению Ñтой проблемы."
+
+#: views/users/delete.thtml:130
+msgid "user_del_understand_permanent"
+msgstr "Я понимаю, что Ñтот шаг не может быть отменён."
+
+#: views/helpers/addons_html.php:192
+msgid "user_deleted_nickname"
+msgstr "Удалённый пользователь"
+
+# %1 is the new email address
+#. %1 is the new email address
+#: views/users/edit.thtml:71
+msgid "user_edit_confirm_email_sent"
+msgstr ""
+"Ð”Ð»Ñ Ð¿Ð¾Ð´Ñ‚Ð²ÐµÑ€Ð¶Ð´ÐµÐ½Ð¸Ñ Ð²Ð°ÑˆÐµÐ³Ð¾ нового адреÑа Ñлектронной почты на Ð°Ð´Ñ€ÐµÑ %1$s было "
+"отправлено пиÑьмо. Ð”Ð»Ñ Ñмены почтового адреÑа, вам необходимо щёлкнуть по "
+"ÑÑылке, указанной в Ñтом пиÑьме. До Ñтих пор, вы можете входить, иÑÐ¿Ð¾Ð»ÑŒÐ·ÑƒÑ "
+"ваш текущий Ð°Ð´Ñ€ÐµÑ Ñлектронной почты."
+
+#: views/users/edit.thtml:201
+msgid "user_edit_delete_user"
+msgstr "Удалить учётную запиÑÑŒ"
+
+# This contains the email sent to users when they signed up for a new
+# account:
+# %1 is the confirmation URL, %2 is the current app
+#. This contains the email sent to users when they signed up for a new
+#. account:
+#. %1 is the confirmation URL, %2 is the current app
+#: views/users/email/confirm_plain.thtml:6
+#, php-format
+msgid "user_email_confirm_account_nopass"
+msgstr ""
+"Добро пожаловать на %2$s Add-ons.\n"
+"\n"
+"Перед иÑпользованием учётной запиÑи необходимо её активировать — Ñто "
+"ÑвлÑетÑÑ Ð³Ð°Ñ€Ð°Ð½Ñ‚Ð¸ÐµÐ¹, что указанный при региÑтрации Ð°Ð´Ñ€ÐµÑ Ñлектронной почты "
+"правильный и дейÑтвительно принадлежит вам.\n"
+"Чтобы активировать учётную запиÑÑŒ, щёлкните по ÑÑылке, указанной ниже, или "
+"Ñкопируйте и вÑтавьте её в Ñтроку адреÑа браузера:\n"
+"\n"
+"%1$s\n"
+"\n"
+"ПоÑле активации учётной запиÑи, вы можете Ñтереть Ñто Ñообщение.\n"
+"\n"
+"СпаÑибо за региÑтрацию на %2$s Add-ons\n"
+"-- ÐдминиÑÑ‚Ñ€Ð°Ñ†Ð¸Ñ %2$s Add-ons"
+
+# %1 is the confirmation url, %2 is the application name
+#. %1 is the confirmation url, %2 is the application name
+#: views/users/email/emailchange_plain.thtml:5
+msgid "user_email_confirm_emailchange"
+msgstr ""
+"Ð’Ñ‹ запроÑили Ñмену Ñвоего адреÑа Ñлектронной почты на %2$s Add-ons.\n"
+"\n"
+"Ð”Ð»Ñ Ð¿Ð¾Ð´Ñ‚Ð²ÐµÑ€Ð¶Ð´ÐµÐ½Ð¸Ñ Ð½Ð¾Ð²Ð¾Ð³Ð¾ адреÑа, пожалуйÑта щёлкните по раÑположенной ниже "
+"ÑÑылке или Ñкопируйте и вÑтавьте её целиком в панель адреÑа вашего "
+"браузера:\n"
+"\n"
+"%1$s\n"
+"\n"
+"Ð”Ð»Ñ Ð¿Ð¾Ð´Ñ‚Ð²ÐµÑ€Ð¶Ð´ÐµÐ½Ð¸Ñ Ð½Ð¾Ð²Ð¾Ð³Ð¾ адреÑа у Ð²Ð°Ñ Ð¸Ð¼ÐµÐµÑ‚ÑÑ 48 чаÑов. ЕÑли вы больше не "
+"хотите изменÑÑ‚ÑŒ адреÑ, проÑто проигнорируйте Ñто пиÑьмо.\n"
+"\n"
+"СпаÑибо!\n"
+"-- ÐдминиÑÑ‚Ñ€Ð°Ñ†Ð¸Ñ %2$s Add-ons"
+
+#: controllers/users_controller.php:168
+#, php-format
+msgid "user_email_confirm_subject"
+msgstr "Благодарим за региÑтрацию на %s Add-ons"
+
+# This is the password reset email
+# %1 is the pw reset URL, %2 is the application
+#. This is the password reset email
+#. %1 is the pw reset URL, %2 is the application
+#: views/users/email/pwreset_plain.thtml:5
+#, php-format
+msgid "user_email_pwreset"
+msgstr ""
+"Ð¡Ð±Ñ€Ð¾Ñ Ð¿Ð°Ñ€Ð¾Ð»Ñ Ð½Ð° %2$s Add-ons\n"
+"\n"
+"Был получен Ð·Ð°Ð¿Ñ€Ð¾Ñ Ð½Ð° ÑÐ±Ñ€Ð¾Ñ Ð¿Ð°Ñ€Ð¾Ð»Ñ Ð´Ð»Ñ Ñтой учётной запиÑи на addons.mozilla."
+"org. Чтобы изменить пароль щёлкните по ÑÑылке, указанной ниже, или "
+"Ñкопируйте и вÑтавьте её в Ñтроку адреÑа браузера:\n"
+"\n"
+"%1$s\n"
+"\n"
+"ЕÑли вы не делали Ñтого запроÑа, проÑто проигнорируйте Ñто Ñообщение.\n"
+"\n"
+"СпаÑибо,\n"
+"-- ÐдминиÑÑ‚Ñ€Ð°Ñ†Ð¸Ñ %2$s Add-ons"
+
+#: controllers/users_controller.php:245
+#, php-format
+msgid "user_email_pwreset_subject"
+msgstr "СброÑить пароль Ð´Ð»Ñ Ð²Ñ…Ð¾Ð´Ð° на %s Add-ons"
+
+#: views/users/emailchange.thtml:50
+msgid "user_emailchange_error"
+msgstr "Ошибка!"
+
+# %1 is the application name
+#. %1 is the application name
+#: controllers/users_controller.php:533
+msgid "user_emailchange_subject"
+msgstr ""
+"ПожалуйÑта, подтвердите изменение Ñвоего адреÑа Ñлектронной почты на %1$s "
+"Add-ons"
+
+#: views/users/emailchange.thtml:48
+msgid "user_emailchange_success"
+msgstr "УÑпех!"
+
+# %1 is the new email address
+#. %1 is the new email address
+#: views/users/emailchange.thtml:49
+msgid "user_emailchange_successful_description"
+msgstr ""
+"Ваш Ð°Ð´Ñ€ÐµÑ Ñлектронной почты был уÑпешно изменён. С Ñтих пор Ð´Ð»Ñ Ð²Ñ…Ð¾Ð´Ð° "
+"пожалуйÑта иÑпользуйте Ð°Ð´Ñ€ÐµÑ %1$s."
+
+#: views/users/edit.thtml:134 views/admin/users_edit.thtml:111
+msgid "user_form_bio"
+msgstr "О мне"
+
+#: views/users/edit.thtml:135 views/admin/users_edit.thtml:112
+msgid "user_form_bio_description"
+msgstr ""
+"ЕÑли хотите, предÑтавьтеÑÑŒ ÑообщеÑтву! Этот текÑÑ‚ поÑвитÑÑ Ð² публичном "
+"доÑтупе на вашей Ñтранице Ñ Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸ÐµÐ¹ о пользователе. ПереноÑÑ‹ Ñтрок будут "
+"Ñохранены, но иÑпользование HTML не разрешено."
+
+#: views/users/pwreset.thtml:77 views/users/register.thtml:73
+#: views/users/edit.thtml:181
+msgid "user_form_confirmpassword"
+msgstr "Подтвердить пароль"
+
+#: views/users/edit.thtml:145
+msgid "user_form_display_collections"
+msgstr "Отобразить Ñозданные мной подборки в моем профиле"
+
+#: views/users/edit.thtml:149
+msgid "user_form_display_collections_fav"
+msgstr "Отобразить мои любимые подборки в моем профиле"
+
+#: views/users/edit.thtml:86
+#, php-format
+msgid "user_form_editprofile"
+msgstr "Редактировать профиль %s"
+
+#: views/users/pwreset.thtml:52 views/users/login.thtml:81
+#: views/users/register.thtml:63 views/users/edit.thtml:187
+msgid "user_form_email"
+msgstr "ÐÐ´Ñ€ÐµÑ Ñл. почты"
+
+#: views/users/register.thtml:78 views/users/edit.thtml:103
+#: views/admin/users_edit.thtml:76
+msgid "user_form_firstname"
+msgstr "ИмÑ"
+
+#: views/users/register.thtml:94 views/users/edit.thtml:119
+#: views/admin/users_edit.thtml:91
+msgid "user_form_hideemail"
+msgstr "Скрывать Ð°Ð´Ñ€ÐµÑ Ñл. почты "
+
+#: views/users/register.thtml:98 views/users/edit.thtml:123
+#: views/admin/users_edit.thtml:99
+msgid "user_form_homepage"
+msgstr "URL веб-Ñайта"
+
+#: views/users/register.thtml:84 views/users/edit.thtml:109
+#: views/admin/users_edit.thtml:81
+msgid "user_form_lastname"
+msgstr "ФамилиÑ"
+
+#: controllers/users_controller.php:333
+msgid "user_form_login"
+msgstr "Вход в ÑиÑтему"
+
+#: views/users/pwreset.thtml:72 views/users/edit.thtml:176
+msgid "user_form_newpassword"
+msgstr "Ðовый пароль"
+
+#: views/users/register.thtml:89 views/users/edit.thtml:114
+#: views/admin/users_edit.thtml:86
+msgid "user_form_nickname"
+msgstr "Ðик"
+
+#: views/users/edit.thtml:171
+msgid "user_form_oldpassword"
+msgstr "Старый пароль"
+
+#: views/users/edit.thtml:97 views/users/edit.thtml:200
+msgid "user_form_otheractions"
+msgstr "Другие дейÑтвиÑ"
+
+#: views/users/login.thtml:85 views/users/register.thtml:68
+msgid "user_form_password"
+msgstr "Пароль"
+
+#: controllers/users_controller.php:93
+msgid "user_form_registration"
+msgstr "РегиÑÑ‚Ñ€Ð°Ñ†Ð¸Ñ Ð½Ð¾Ð²Ð¾Ð³Ð¾ пользователÑ"
+
+#: views/users/login.thtml:90
+msgid "user_form_remember_me"
+msgstr "Запомнить Ð¼ÐµÐ½Ñ Ð½Ð° Ñтом компьютере"
+
+#: views/admin/users_edit.thtml:95
+msgid "user_form_showsandbox"
+msgstr "Показать «пеÑочницу»?"
+
+#: views/users/edit.thtml:205
+msgid "user_form_submit_edit"
+msgstr "Сохранить"
+
+#: views/users/login.thtml:93
+msgid "user_form_submit_login"
+msgstr "Войти"
+
+#: views/users/register.thtml:113
+msgid "user_form_submit_register"
+msgstr "РегиÑтрациÑ"
+
+#: views/users/info.thtml:75
+#, php-format
+msgid "user_info_usersince"
+msgstr "Пользователь Mozilla Add-ons Ñ"
+
+#: views/users/login.thtml:102
+msgid "user_login_register_link"
+msgstr "Создать новую учётную запиÑÑŒ"
+
+#: views/users/edit.thtml:160
+msgid "user_notifications_item_compat"
+msgstr "СовмеÑтимоÑÑ‚ÑŒ дополнений (наÑтоÑтельно рекомендуем Ð´Ð»Ñ Ð¿Ð¾Ð´Ð¿Ð¸Ñки)"
+
+#: views/users/edit.thtml:161
+msgid "user_notifications_item_events"
+msgstr "ПредÑтоÑщие ÑÐ¾Ð±Ñ‹Ñ‚Ð¸Ñ Ð¸ конкурÑÑ‹"
+
+#: views/users/edit.thtml:156
+msgid "user_notifications_none_available"
+msgstr "Ð’ данное Ð²Ñ€ÐµÐ¼Ñ Ñƒ Ð²Ð°Ñ Ð½ÐµÑ‚ уведомлений, которые можно наÑтроить."
+
+#: views/users/edit.thtml:158
+msgid "user_notifications_select_topics"
+msgstr ""
+"Ð’Ñ€ÐµÐ¼Ñ Ð¾Ñ‚ времени Mozilla может поÑылать вам пиÑьма Ñ Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸ÐµÐ¹ о выходÑщих "
+"в Ñкором времени верÑиÑÑ… приложений и ÑобытиÑÑ…, каÑающихÑÑ Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ð¹. "
+"ПожалуйÑта, выберите темы, в которых вы заинтереÑованы:"
+
+#: views/users/edit.thtml:164
+msgid "user_notifications_specific_contact"
+msgstr ""
+"Mozilla оÑтавлÑет за Ñобой право ÑвÑзатьÑÑ Ñ Ð²Ð°Ð¼Ð¸ лично, в Ñлучае, еÑли "
+"возникнут вопроÑÑ‹ по размещенным вами дополнениÑм."
+
+#: controllers/users_controller.php:543
+msgid "user_profile_edit_error"
+msgstr ""
+"Ð’ изменениÑÑ…, которые вы Ñделали, имеютÑÑ Ð¾ÑˆÐ¸Ð±ÐºÐ¸. ИÑправьте их и отправьте "
+"данные заново…"
+
+#: controllers/users_controller.php:540
+msgid "user_profile_saved"
+msgstr "Профиль обновлён."
+
+#: views/users/pwreset.thtml:65
+#, php-format
+msgid "user_pwreset_for_email"
+msgstr "Ð¡Ð±Ñ€Ð¾Ñ Ð¿Ð°Ñ€Ð¾Ð»Ñ Ð´Ð»Ñ %s"
+
+#: controllers/users_controller.php:226
+msgid "user_pwreset_header"
+msgstr "Ð¡Ð±Ñ€Ð¾Ñ Ð¿Ð°Ñ€Ð¾Ð»Ñ"
+
+#: views/users/login.thtml:103
+msgid "user_pwreset_link"
+msgstr "Забыли пароль?"
+
+#: controllers/users_controller.php:248
+msgid "user_pwreset_link_sent"
+msgstr ""
+"СÑылка Ð´Ð»Ñ ÑброÑа Ð¿Ð°Ñ€Ð¾Ð»Ñ Ð±Ñ‹Ð»Ð° отправлена на Ð°Ð´Ñ€ÐµÑ Ð²Ð°ÑˆÐµÐ¹ Ñлектронной почты."
+
+#: controllers/users_controller.php:304
+msgid "user_pwreset_okay"
+msgstr "Пароль уÑпешно Ñброшен."
+
+#: views/users/pwreset.thtml:82
+msgid "user_pwreset_submit_changepw"
+msgstr "Отправить изменённый пароль"
+
+#: views/users/pwreset.thtml:57
+msgid "user_pwreset_submit_sendlink"
+msgstr "Отправить ÑÑылку Ð´Ð»Ñ ÑброÑа паролÑ"
+
+#: views/users/register_complete.thtml:51
+#, php-format
+msgid "user_register_amo_link"
+msgstr "Ð”Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð´Ð»Ñ %s"
+
+# %1 is the user's email address, %2 is the current app
+#. %1 is the user's email address, %2 is the current app
+#: views/users/activatefirst.thtml:49
+#, php-format
+msgid "user_register_click_confirm_link"
+msgstr ""
+"СÑылка Ð´Ð»Ñ Ð°ÐºÑ‚Ð¸Ð²Ð°Ñ†Ð¸Ð¸ данной учётной запиÑи была отправлена на указанный "
+"Ð°Ð´Ñ€ÐµÑ Ñлектронной почты — %1$s. Прежде чем войти на %2$s Add-ons потребуетÑÑ "
+"активировать её, Ð¿Ñ€Ð¾Ð¹Ð´Ñ Ð¿Ð¾ ÑÑылке, указанной в пиÑьме."
+
+# %1 is the user's email address
+#. %1 is the user's email address
+#: views/users/register_complete.thtml:49
+#, php-format
+msgid "user_register_confirm_email_sent"
+msgstr ""
+"Ð”Ð»Ñ Ð¿Ð¾Ð´Ñ‚Ð²ÐµÑ€Ð¶Ð´ÐµÐ½Ð¸Ñ ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ ÑƒÑ‡Ñ‘Ñ‚Ð½Ð¾Ð¹ запиÑи по адреÑу %1$s было отправлено "
+"пиÑьмо. Перед тем как войти, вы должны активировать учётную запиÑÑŒ, щёлкнув "
+"по ÑÑылке, находÑщейÑÑ Ð² Ñтом пиÑьме."
+
+#: views/users/activatefirst.thtml:51
+msgid "user_register_confirmation_link_text"
+msgstr "отправить Ñообщение Ð´Ð»Ñ Ð¿Ð¾Ð´Ñ‚Ð²ÐµÑ€Ð¶Ð´ÐµÐ½Ð¸Ñ Ð·Ð°Ð½Ð¾Ð²Ð¾"
+
+#: views/users/register_complete.thtml:47
+msgid "user_register_congratulations"
+msgstr "ПоздравлÑем! Ваша ÑƒÑ‡Ñ‘Ñ‚Ð½Ð°Ñ Ð·Ð°Ð¿Ð¸ÑÑŒ уÑпешно Ñоздана."
+
+#: views/users/register.thtml:50
+msgid "user_register_details"
+msgstr ""
+"<p>РегиÑÑ‚Ñ€Ð°Ñ†Ð¸Ñ Ð½Ð° AMO <strong>не требуетÑÑ</strong> еÑли вы хотите проÑто "
+"загрузить и уÑтановить публичные дополнениÑ.</p><p>Вам нужно "
+"зарегиÑтрироватьÑÑ Ñ‚Ð¾Ð»ÑŒÐºÐ¾ еÑли:</p><ul><li>Ð’Ñ‹ хотите ÑоÑтавлÑÑ‚ÑŒ рецензии на "
+"дополнениÑ</li><li>Ð’Ñ‹ ÑвлÑетеÑÑŒ разработчиком Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð¸ хотите загрузить "
+"ваше дополнение Ð´Ð»Ñ Ñ€Ð°Ð·Ð¼ÐµÑ‰ÐµÐ½Ð¸Ñ Ð½Ð° AMO</li></ul><p>По завершении уÑпешной "
+"региÑтрации по указанному вами адреÑу Ñлектронной почты вам будет отправлено "
+"пиÑьмо Ð´Ð»Ñ Ð¿Ð¾Ð´Ñ‚Ð²ÐµÑ€Ð¶Ð´ÐµÐ½Ð¸Ñ Ñ€ÐµÐ³Ð¸Ñтрации. Ð”Ð»Ñ Ð¿Ð¾Ð´Ñ‚Ð²ÐµÑ€Ð¶Ð´ÐµÐ½Ð¸Ñ Ñ€ÐµÐ³Ð¸Ñтрации вашей "
+"учётной запиÑи, пожалуйÑта, Ñледуйте инÑтрукциÑм в Ñтом пиÑьме.</p><p>ЕÑли "
+"желате, вы можете прочеÑÑ‚ÑŒ наше <a href='%1$s' title='Правовое "
+"обеÑпечение'>Правовое обеÑпечение</a> и <a href='%2$s' title='Политика "
+"приватноÑти'>Политику приватноÑти</a>.</p>"
+
+# %1 is the link to the "resend confirmation code" page
+#. %1 is the link to the "resend confirmation code" page
+#: views/users/activatefirst.thtml:51
+#, php-format
+msgid "user_register_resend_confirmation_link"
+msgstr ""
+"ЕÑли вы не получили пиÑьмо Ð´Ð»Ñ Ð¿Ð¾Ð´Ñ‚Ð²ÐµÑ€Ð¶Ð´ÐµÐ½Ð¸Ñ, убедитеÑÑŒ что ваш почтовый "
+"ÑÐµÑ€Ð²Ð¸Ñ Ð½Ðµ пометил его как «Ñпам». При необходимоÑти вы можете %1$s на ваш "
+"почтовый адреÑ, упомÑнутый выше."
+
+# %1 is the link to the Mozilla Add-ons front page
+#. %1 is the link to the Mozilla Add-ons front page
+#: views/users/register_complete.thtml:51
+#, php-format
+msgid "user_register_welcome"
+msgstr "СпаÑибо за региÑтрацию! Добро пожаловать на %1$s!"
+
+#: views/users/register.thtml:49
+msgid "user_register_welcome_header"
+msgstr "Добро пожаловать на addons.mozilla.org (AMO)!"
+
+#: views/users/register.thtml:81 views/users/edit.thtml:106
+msgid "user_required_firstlast_or_nickname"
+msgstr "ТребуетÑÑ Ð¸Ð¼Ñ, Ñ„Ð°Ð¼Ð¸Ð»Ð¸Ñ Ð¸Ð»Ð¸ ник."
+
+#: views/users/edit.thtml:94 views/users/edit.thtml:142
+msgid "user_tab_collections"
+msgstr "Подборки"
+
+#: views/users/edit.thtml:95 views/users/edit.thtml:154
+msgid "user_tab_notifications"
+msgstr "УведомлениÑ"
+
+#: views/users/edit.thtml:93 views/users/edit.thtml:101
+msgid "user_tab_profile"
+msgstr "Профиль пользователÑ"
+
+#: controllers/users_controller.php:209
+msgid "user_verified_okay"
+msgstr "Проверка уÑпешно завершена!"
+
+#: controllers/users_controller.php:723
+msgid "users_delete_pagetitle"
+msgstr "Удаление учётной запиÑи"
+
+#: controllers/users_controller.php:414
+msgid "users_edit_pagetitle"
+msgstr "Изменение наÑтроек учётной запиÑи пользователÑ"
+
+#: views/users/info.thtml:71
+msgid "users_info_aboutme"
+msgstr "О мне"
+
+#: views/users/info.thtml:96
+#, php-format
+msgid "users_info_addons_by_user"
+msgstr "ДополнениÑ, Ñозданные %1$s:"
+
+#: views/users/info.thtml:51
+msgid "users_info_author_name"
+msgstr "ИмÑ"
+
+#: views/users/info.thtml:48
+msgid "users_info_author_profile"
+msgstr "Профиль пользователÑ"
+
+#. %s is the user name
+#: views/users/info.thtml:137
+msgid "users_info_collections_by_user"
+msgstr "Подборки от %s"
+
+#: views/users/info.thtml:66
+msgid "users_info_email"
+msgstr "ÐÐ´Ñ€ÐµÑ Ñлектронной почты"
+
+#: views/users/info.thtml:155
+msgid "users_info_fav_collections_by_user"
+msgstr "Любимые подборки"
+
+#: views/users/info.thtml:61
+msgid "users_info_homepage"
+msgstr "ДомашнÑÑ Ñтраница"
+
+#: views/users/info.thtml:56
+msgid "users_info_nickname"
+msgstr "Ðик"
+
+#: controllers/users_controller.php:707
+#, php-format
+msgid "users_info_pagetitle"
+msgstr "Ð˜Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¾ пользователе %1$s"
+
+# %1 is the user's name
+#. %1 is the user's name
+#: views/users/info.thtml:116
+msgid "users_info_reviews_by_user"
+msgstr "Отзывы от %s"
+
+#: controllers/users_controller.php:330 controllers/users_controller.php:332
+msgid "users_login_pagetitle"
+msgstr "Вход Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ð² ÑиÑтему"
+
+# %1 is the link to the sandbox/policy explanation page
+# This message is for a specific add-on not found
+#. %1 is the link to the sandbox/policy explanation page
+#. This message is for a specific add-on not found
+#: views/users/login.thtml:53
+#, php-format
+msgid "users_login_sandbox_display_warning"
+msgstr ""
+"Дополнение, которое вы ищете, находитÑÑ Ð² данный момент в «пеÑочнице». ЕÑли "
+"у Ð²Ð°Ñ ÑƒÐ¶Ðµ еÑÑ‚ÑŒ ÑƒÑ‡Ñ‘Ñ‚Ð½Ð°Ñ Ð·Ð°Ð¿Ð¸ÑÑŒ на Mozilla Add-ons, пожалуйÑта войдите в "
+"ÑиÑтему или <a href=\"%1$s\">почитайте больше о «пеÑочнице»</a>."
+
+# %1 is the link to the sandbox/policy explanation page
+# This message is for any given sandbox-related page not found
+#. %1 is the link to the sandbox/policy explanation page
+#. This message is for any given sandbox-related page not found
+#: views/users/login.thtml:56
+#, php-format
+msgid "users_login_sandbox_page_warning"
+msgstr ""
+"Страница, которую вы ищете, ÑвлÑетÑÑ Ñ‡Ð°Ñтью «пеÑочницы». ЕÑли у Ð²Ð°Ñ ÑƒÐ¶Ðµ еÑÑ‚ÑŒ "
+"ÑƒÑ‡Ñ‘Ñ‚Ð½Ð°Ñ Ð·Ð°Ð¿Ð¸ÑÑŒ на Mozilla Add-ons, пожалуйÑта войдите в ÑиÑтему или <a href="
+"\"%1$s\">почитайте больше о «пеÑочнице»</a>."
+
+#: controllers/users_controller.php:223 controllers/users_controller.php:225
+msgid "users_pwreset_pagetitle"
+msgstr "Ð¡Ð±Ñ€Ð¾Ñ Ð¿Ð°Ñ€Ð¾Ð»Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ"
+
+#: controllers/users_controller.php:90 controllers/users_controller.php:92
+msgid "users_register_pagetitle"
+msgstr "РегиÑÑ‚Ñ€Ð°Ñ†Ð¸Ñ Ð½Ð¾Ð²Ð¾Ð³Ð¾ пользователÑ"
+
+#. %1$s is an addon name, like <a>Firebug</a>
+#. %2$s is a version number, like <a>1.2</a>
+#: views/versions/license.thtml:52
+msgid "versions_license_header_source"
+msgstr "Ð›Ð¸Ñ†ÐµÐ½Ð·Ð¸Ñ Ð½Ð° иÑходный код Ð´Ð»Ñ %1$s %2$s"
+
+#: views/addons/category_landing.thtml:147
+msgid "view_recently_added"
+msgstr "ПроÑмотреть по дате добавлениÑ"
+
+#: views/addons/category_landing.thtml:161
+msgid "view_top_downloads"
+msgstr "ПроÑмотреть по кол-ву загрузок"
+
+#: views/addons/category_landing.thtml:175
+msgid "view_top_rated"
+msgstr "ПроÑмотреть по рейтингу"
+
+#~ msgid "addon_slider_tooltip_next"
+#~ msgstr "Следующее дополнение"
+
+#~ msgid "addon_slider_tooltip_previous"
+#~ msgstr "Предыдущее дополнение"
+
+#~ msgid "addon_versions_getlatesttext"
+#~ msgstr "Ð¡Ð°Ð¼Ð°Ñ Ð¿Ð¾ÑледнÑÑ Ð²ÐµÑ€ÑÐ¸Ñ ÑовмеÑтима Ñ"
+
+#~ msgid "addons_display_version_history"
+#~ msgstr "ÐŸÐ¾Ð»Ð½Ð°Ñ Ð¸ÑÑ‚Ð¾Ñ€Ð¸Ñ Ð²ÐµÑ€Ñий"
+
+#~ msgid "addons_home_newest_header"
+#~ msgstr "Ðовейшие:"
+
+#~ msgid "addons_home_popular_header"
+#~ msgstr "Ðаиболее популÑрные:"
+
+#~ msgid "addons_home_recommended_header"
+#~ msgstr "Мы рекомендуем:"
+
+#~ msgid "addons_home_updated_header"
+#~ msgstr "Ðедавно обновлённые:"
+
+#~ msgid "addons_home_view_all"
+#~ msgstr "ПроÑмотреть вÑе"
+
+#~ msgid "category_extra_allrecommended"
+#~ msgstr "ПроÑмотреть вÑе рекомендуемые дополнениÑ"
+
+#~ msgid "category_extra_highestrated"
+#~ msgstr "По рейтингу"
+
+#~ msgid "category_extra_lastupdated"
+#~ msgstr "По дате поÑледнего обновлениÑ"
+
+#~ msgid "category_extra_mostpopular"
+#~ msgstr "По популÑрноÑти"
+
+#~ msgid "collections_detail_js_loading"
+#~ msgstr "ЗагружаетÑÑ"
+
+#~ msgid "collections_detail_more_info"
+#~ msgstr "Подробнее"
+
+#~ msgid "devcp_additem_firefox_notice"
+#~ msgstr ""
+#~ "Ð”Ð°Ð½Ð½Ð°Ñ Ð²ÐµÑ€ÑÐ¸Ñ Ð²Ð°ÑˆÐµÐ³Ð¾ Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð½Ðµ отмечена как ÑовмеÑÑ‚Ð¸Ð¼Ð°Ñ Ñ Firefox %1"
+#~ "$s. Mozilla ÑобираетÑÑ Ð² Ñкором времени выпуÑтить Ñледующую верÑию "
+#~ "Firefox, поÑтому пожалуйÑта протеÑтируйте ваше дополнение в новой верÑии "
+#~ "и обновите информацию о ÑовмеÑтимоÑти. Более Ð¿Ð¾Ð´Ñ€Ð¾Ð±Ð½Ð°Ñ Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ "
+#~ "доÑтупна по <a href=\"%2$s\">Ñтому адреÑу</a>. Это вÑего лишь уведомление "
+#~ "и вы можете продолжать выкладывать Ñту верÑию на addons.mozilla.org."
+
+#~ msgid "devcp_addon_disabled_successfully"
+#~ msgstr "Дополнение уÑпешно заблокировано"
+
+#~ msgid "devcp_addon_edit_pagetitle"
+#~ msgstr "Изменить дополнение"
+
+#~ msgid "devcp_addon_enabled_successfully"
+#~ msgstr "Дополнение уÑпешно разблокировано"
+
+#~ msgid "devcp_addon_field_description_displaytitle"
+#~ msgstr "ОпиÑание дополнениÑ"
+
+#~ msgid "devcp_addon_field_eula_displaytitle"
+#~ msgstr "Лицензионное Ñоглашение (EULA)"
+
+#~ msgid "devcp_addon_field_homepage_displaytitle"
+#~ msgstr "ДомашнÑÑ Ñтраница дополнениÑ"
+
+#~ msgid "devcp_addon_field_name_displaytitle"
+#~ msgstr "Ðазвание дополнениÑ"
+
+#~ msgid "devcp_addon_field_privacy_displaytitle"
+#~ msgstr "Политика конфиденциальноÑти"
+
+#~ msgid "devcp_addon_field_summary_displaytitle"
+#~ msgstr "ÐšÑ€Ð°Ñ‚ÐºÐ°Ñ Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¾ дополнении"
+
+#~ msgid "devcp_addon_field_supportemail_displaytitle"
+#~ msgstr "ÐÐ´Ñ€ÐµÑ Ñл. почты поддержки"
+
+#~ msgid "devcp_addon_field_supporturl_displaytitle"
+#~ msgstr "URL поддержки"
+
+#~ msgid "devcp_addon_field_versionnotes_displaytitle"
+#~ msgstr "ÐŸÑ€Ð¸Ð¼ÐµÑ‡Ð°Ð½Ð¸Ñ Ðº верÑии"
+
+#~ msgid "devcp_addon_nominate_pagetitle"
+#~ msgstr "Ðоминировать дополнение"
+
+#~ msgid "devcp_addon_nominated_successfully"
+#~ msgstr "Дополнение уÑпешно номинировано!"
+
+#~ msgid "devcp_addon_status_criteria_review"
+#~ msgstr ""
+#~ "ÐеÑколько отзывов пользователей об Ñтом дополнении (могут быть внешние "
+#~ "отзывы)."
+
+# %1 is the addon edit link
+# %2 is the main dev CP link
+#~ msgid "devcp_addon_submission_makechanges"
+#~ msgstr ""
+#~ "ПоÑетите Ñтраницу %1$s, чтобы Ñделать Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð² вашей публикации или %2"
+#~ "$s, чтобы вернутьÑÑ Ð² панель ÑƒÐ¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ñ€Ð°Ð·Ñ€Ð°Ð±Ð¾Ñ‚Ñ‡Ð¸ÐºÐ°."
+
+#~ msgid "devcp_addon_submission_makechanges_devcp_link"
+#~ msgstr "щёлкните здеÑÑŒ"
+
+#~ msgid "devcp_addon_submission_makechanges_link"
+#~ msgstr "Изменить дополнение"
+
+#~ msgid "devcp_addon_submission_pending"
+#~ msgstr ""
+#~ "Эта верÑÐ¸Ñ Ð±Ñ‹Ð»Ð° помещена в «пеÑочницу», в ожидании проверки теÑтерами и "
+#~ "редактором Mozilla Add-on. О предпринÑÑ‚Ñ‹Ñ… дейÑтвиÑÑ… вы будете уведомлены "
+#~ "по Ñлектронной почте."
+
+# %1 is the link to the sandbox information page
+#~ msgid "devcp_addon_submission_sandbox_readmore"
+#~ msgstr ""
+#~ "Дополнительную информацию о ÑиÑтеме Ñ€ÐµÑ†ÐµÐ½Ð·Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Â«Ð¿ÐµÑочница» вы можете "
+#~ "получить %s."
+
+#~ msgid "devcp_addon_submission_sandbox_readmore_link"
+#~ msgstr "здеÑÑŒ"
+
+# %1 is the "nominate" link
+#~ msgid "devcp_addon_submission_sandboxed"
+#~ msgstr ""
+#~ "Эта верÑÐ¸Ñ Ð±Ñ‹Ð»Ð° помещена в «пеÑочницу» Ð´Ð»Ñ Ð¸ÑÐ¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ Ð¾Ð¿Ñ‹Ñ‚Ð½Ñ‹Ð¼Ð¸ "
+#~ "пользователÑми. Ð”Ð»Ñ Ñ‚Ð¾Ð³Ð¾, чтобы показать её на общедоÑтупном Ñайте, вы "
+#~ "должны %s ваше дополнение и пройти через процеÑÑ Ñ€ÐµÑ†ÐµÐ½Ð·Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ."
+
+#~ msgid "devcp_addon_submission_sandboxed_nominate_link"
+#~ msgstr "номинировать"
+
+#~ msgid "devcp_addon_submission_success"
+#~ msgstr "ÐŸÑƒÐ±Ð»Ð¸ÐºÐ°Ñ†Ð¸Ñ Ð²Ð°ÑˆÐµÐ³Ð¾ Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð±Ñ‹Ð»Ð° уÑпешно завершена."
+
+#~ msgid "devcp_addon_submission_trusted_public"
+#~ msgstr ""
+#~ "ПоÑкольку вашему дополнению доверÑÑŽÑ‚, Ñта верÑÐ¸Ñ Ð±Ñ‹Ð»Ð° автоматичеÑки "
+#~ "одобрена Ð´Ð»Ñ Ð¾Ð±Ñ‰ÐµÐ´Ð¾Ñтупной чаÑти Ñайта."
+
+#~ msgid "devcp_addon_submit_pagetitle"
+#~ msgstr "ÐŸÑƒÐ±Ð»Ð¸ÐºÐ°Ñ†Ð¸Ñ Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ"
+
+#~ msgid "devcp_addon_updated_successfully"
+#~ msgstr "Дополнение уÑпешно обновлено"
+
+# %1 is the link to the preview upload page
+#~ msgid "devcp_addon_upload_preview"
+#~ msgstr "Ð’Ñ‹ можете увеличить Ð¸Ð½Ñ‚ÐµÑ€ÐµÑ Ðº вашему дополнению, %s."
+
+#~ msgid "devcp_addon_upload_preview_link"
+#~ msgstr "загрузив иллюÑтрации"
+
+# #1 is the author email
+#~ msgid "devcp_author_lookup_none_found"
+#~ msgstr "Ðвтор не найден [%s]"
+
+#~ msgid "devcp_author_lookup_remove"
+#~ msgstr "ПеремеÑтить/удалить"
+
+#~ msgid "devcp_button_cancel"
+#~ msgstr "Отменить"
+
+#~ msgid "devcp_button_cancel_confirm"
+#~ msgstr "Вы уверены, что хотите отменить публикацию?"
+
+#~ msgid "devcp_button_next"
+#~ msgstr "Далее"
+
+#~ msgid "devcp_change_addontype"
+#~ msgstr "Изменить тип дополнениÑ:"
+
+#~ msgid "devcp_comments_updated"
+#~ msgstr "Комментарии разработчика обновлены."
+
+#~ msgid "devcp_details_addpreview_link"
+#~ msgstr "Добавить иллюÑтрацию"
+
+#~ msgid "devcp_details_author"
+#~ msgstr "Ðвтор"
+
+#~ msgid "devcp_details_authors"
+#~ msgstr "Ðвторы"
+
+#~ msgid "devcp_details_authors_none"
+#~ msgstr "Ðет"
+
+#~ msgid "devcp_details_categories"
+#~ msgstr "КатегориÑ"
+
+#~ msgid "devcp_details_category"
+#~ msgstr "Категории"
+
+#~ msgid "devcp_details_description"
+#~ msgstr "ОпиÑание"
+
+#~ msgid "devcp_details_disabled"
+#~ msgstr "Заблокировано"
+
+#~ msgid "devcp_details_guid"
+#~ msgstr "GUID"
+
+#~ msgid "devcp_details_header_details"
+#~ msgstr "СведениÑ"
+
+#~ msgid "devcp_details_header_devcomments"
+#~ msgstr "Комментарии разработчика"
+
+#~ msgid "devcp_details_header_previews"
+#~ msgstr "ИллюÑтрации"
+
+#~ msgid "devcp_details_header_versions"
+#~ msgstr "ВерÑии"
+
+#~ msgid "devcp_details_homepage"
+#~ msgstr "ДомашнÑÑ Ñтраница"
+
+#~ msgid "devcp_details_homepage_none"
+#~ msgstr "Ðет"
+
+#~ msgid "devcp_details_preview_nocaption"
+#~ msgstr "Ðет подпиÑи"
+
+#~ msgid "devcp_details_previews_nonefound"
+#~ msgstr "ИллюÑтрации не найдены."
+
+#~ msgid "devcp_details_submit_update"
+#~ msgstr "Обновить"
+
+#~ msgid "devcp_details_supportemail"
+#~ msgstr "ÐÐ´Ñ€ÐµÑ Ñл. почты поддержки"
+
+#~ msgid "devcp_details_supportemail_none"
+#~ msgstr "Разработчик не указал Ð°Ð´Ñ€ÐµÑ Ñл. почты поддержки."
+
+#~ msgid "devcp_details_supporturl"
+#~ msgstr "URL поддержки"
+
+#~ msgid "devcp_details_supporturl_none"
+#~ msgstr "Разработчик не указал url поддержки."
+
+#~ msgid "devcp_details_trusted"
+#~ msgstr "ДоверÑÑ‚ÑŒ"
+
+#~ msgid "devcp_details_versions_none_found"
+#~ msgstr "ВерÑии не найдены."
+
+#~ msgid "devcp_disable_cancel"
+#~ msgstr "Отменить и вернутьÑÑ Ð½Ð°Ð·Ð°Ð´"
+
+#~ msgid "devcp_disable_disable_button"
+#~ msgstr "Да, отключить его"
+
+#~ msgid "devcp_disable_disable_confirm"
+#~ msgstr "Ð’Ñ‹ уверены, что хотите отключить Ñто дополнение?"
+
+#~ msgid "devcp_disable_disable_description"
+#~ msgstr ""
+#~ "Отключение Ñтого Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð¿Ñ€Ð¸Ð²ÐµÐ´Ñ‘Ñ‚ к Ñкрытию его из ÑпиÑка дополнений и "
+#~ "результатов поиÑка. Его Ð½ÐµÐ»ÑŒÐ·Ñ Ð±ÑƒÐ´ÐµÑ‚ загрузить Ñ Ð²ÐµÐ±-Ñайта и оно не будет "
+#~ "предложено клиенту при проверке обновлениÑ. С точки Ð·Ñ€ÐµÐ½Ð¸Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»ÐµÐ¹ "
+#~ "дополнение будет удалено, Ñ…Ð¾Ñ‚Ñ Ð²Ñ‹ Ñможете в дальнейшем вернутьÑÑ Ñюда и "
+#~ "при желании Ñнова его включить."
+
+#~ msgid "devcp_disable_disable_title"
+#~ msgstr "Отключить %s"
+
+#~ msgid "devcp_disable_enable_button"
+#~ msgstr "Да, включить его"
+
+#~ msgid "devcp_disable_enable_confirm"
+#~ msgstr "Ð’Ñ‹ уверены, что хотите включить Ñто дополнение?"
+
+#~ msgid "devcp_disable_enable_description"
+#~ msgstr ""
+#~ "Включение Ñтого Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð¿Ñ€Ð¸Ð²ÐµÐ´Ñ‘Ñ‚ к тому, что оно Ñнова поÑвитÑÑ Ð² "
+#~ "ÑпиÑке дополнений и результатах поиÑка. Его можно будет загрузить Ñ Ð²ÐµÐ±-"
+#~ "Ñайта и оно будет предложено клиенту при проверке обновлений."
+
+#~ msgid "devcp_disable_enable_title"
+#~ msgstr "Включить %s"
+
+#~ msgid "devcp_edit_author_add"
+#~ msgstr "Добавить автора"
+
+#~ msgid "devcp_edit_author_email"
+#~ msgstr "ÐдреÑа Ñл. почты авторов"
+
+#~ msgid "devcp_edit_author_remove"
+#~ msgstr "ПеремеÑтить/удалить"
+
+#~ msgid "devcp_edit_error_categories_unavailable"
+#~ msgstr "Ð”Ð»Ñ Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ð¹ Ñтого типа нет доÑтупных категорий."
+
+#, fuzzy
+#~ msgid "devcp_edit_file_error_incomplete"
+#~ msgstr "Incomplete transfer"
+
+#, fuzzy
+#~ msgid "devcp_edit_file_error_no"
+#~ msgstr "No file uploaded"
+
+#, fuzzy
+#~ msgid "devcp_edit_file_error_size"
+#~ msgstr "Exceeds maximum upload size"
+
+#~ msgid "devcp_edit_header_authors"
+#~ msgstr "Ðвторы"
+
+#~ msgid "devcp_edit_icon_add_link"
+#~ msgstr "Добавить значок"
+
+#~ msgid "devcp_edit_icon_change_link"
+#~ msgstr "Изменить значок"
+
+#~ msgid "devcp_edit_label_allow_viewsource"
+#~ msgstr "Позволить пользователÑм проÑматривать иÑходные файлы онлайн."
+
+#~ msgid "devcp_edit_label_categories"
+#~ msgstr "Категории"
+
+#~ msgid "devcp_edit_label_defaultlocale"
+#~ msgstr "Язык по умолчанию"
+
+#~ msgid "devcp_edit_label_icon_delete"
+#~ msgstr "Удалить ÑущеÑтвующий значок"
+
+#~ msgid "devcp_edit_label_icon_new"
+#~ msgstr "Ðовый файл значка"
+
+#~ msgid "devcp_edit_label_info"
+#~ msgstr "Значок"
+
+#~ msgid "devcp_edit_locale_disambiguation_explanation"
+#~ msgstr "ÐšÑ€Ð°Ñ‚ÐºÐ°Ñ Ð´Ð¾Ð¿Ð¾Ð»Ð½Ð¸Ñ‚ÐµÐ»ÑŒÐ½Ð°Ñ Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ (Ñ‚Ð°ÐºÐ°Ñ ÐºÐ°Ðº Ð¸Ð¼Ñ Ð¼ÐµÑтного диалекта)"
+
+#~ msgid "devcp_edit_submit_update"
+#~ msgstr "Обновить"
+
+#~ msgid "devcp_edit_target_locale_explanation"
+#~ msgstr ""
+#~ "<a href=\"http://wiki.mozilla.org/L10n:Simple_locale_names\">проÑтое Ð¸Ð¼Ñ "
+#~ "локали</a>, например 'en-US'"
+
+#~ msgid "devcp_editversion_checkedfiles_delete"
+#~ msgstr "Отмеченные файлы будут удалены."
+
+# %1 is the file name
+# %2 is the file size (150 KB)
+#~ msgid "devcp_editversion_filename_size"
+#~ msgstr "%1$s (%2$s)"
+
+#~ msgid "devcp_editversion_label_files"
+#~ msgstr "Файлы"
+
+#~ msgid "devcp_editversion_label_targetapps"
+#~ msgstr "Приложение"
+
+#~ msgid "devcp_editversion_nofiles"
+#~ msgstr "Ðет файлов."
+
+#~ msgid "devcp_editversion_reviewernotes"
+#~ msgstr "Заметки рецензенту"
+
+#~ msgid "devcp_editversion_submit_update"
+#~ msgstr "Обновить"
+
+#~ msgid "devcp_error_addon_field_summary_toolong"
+#~ msgstr ""
+#~ "ÐÐ½Ð½Ð¾Ñ‚Ð°Ñ†Ð¸Ñ Ð¾Ð³Ñ€Ð°Ð½Ð¸Ñ‡ÐµÐ½Ð° макÑимум 250 Ñимволами.\n"
+#~ "(Вы ввели %s)"
+
+#~ msgid "devcp_error_addonname_not_unique"
+#~ msgstr ""
+#~ "Такое дополнение уже ÑущеÑтвует в базе данных. УдоÑтоверьтеÑÑŒ, что:<br /"
+#~ "><li>GUID указан верно. Ð¡Ð°Ð¼Ð°Ñ Ñ€Ð°ÑпроÑÑ‚Ñ€Ð°Ð½Ñ‘Ð½Ð½Ð°Ñ Ð¿Ñ€Ð¸Ñ‡Ð¸Ð½Ð° Ð´Ð»Ñ Ñтой ошибки — "
+#~ "неверный GUID.</li><li>Ð’ базе нет дублирующей запиÑи. ЕÑли Ñ‚Ð°ÐºÐ°Ñ Ð·Ð°Ð¿Ð¸ÑÑŒ "
+#~ "приÑутÑтвует, необходимо обновить её или удалить и попытатьÑÑ Ñнова.</li>"
+
+#~ msgid "devcp_error_describe_changes"
+#~ msgstr "Опишите изменениÑ, Ñделанные в Ñтом обновлении."
+
+#~ msgid "devcp_error_file_guids_dont_match"
+#~ msgstr "Ðе вÑе GUIDÑ‹ в файле подходÑÑ‚"
+
+#~ msgid "devcp_error_identical_version_exists"
+#~ msgstr ""
+#~ "Ð”Ð»Ñ Ñтого Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð¸ платформы уже ÑущеÑтвует Ð¸Ð´ÐµÐ½Ñ‚Ð¸Ñ‡Ð½Ð°Ñ Ð²ÐµÑ€ÑÐ¸Ñ (%s)."
+
+#~ msgid "devcp_error_nominate_message"
+#~ msgstr "Ð”Ð»Ñ Ð½Ð¾Ð¼Ð¸Ð½Ð°Ñ†Ð¸Ð¸ вы должны ввеÑти требуемые данные."
+
+#~ msgid "devcp_error_nominate_no_prerelease"
+#~ msgstr "Ðевозможно номинировать предварительный выпуÑк."
+
+#~ msgid "devcp_error_nominate_sandbox_only"
+#~ msgstr "Ð’Ñ‹ можете номинировать только Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð½Ð°Ñ…Ð¾Ð´ÑщиеÑÑ Ð² «пеÑочнице»."
+
+#~ msgid "devcp_error_saving"
+#~ msgstr "При попытке ÑÐ¾Ñ…Ñ€Ð°Ð½ÐµÐ½Ð¸Ñ Ð²Ð°ÑˆÐ¸Ñ… данных произошла ошибка."
+
+#~ msgid "devcp_error_update_access_denied"
+#~ msgstr "Ð’Ñ‹ не имеете прав Ð´Ð»Ñ Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ñтого дополнениÑ."
+
+#~ msgid "devcp_file_addanother"
+#~ msgstr "Добавить файл Ð´Ð»Ñ Ð´Ñ€ÑƒÐ³Ð¾Ð¹ платформы"
+
+#~ msgid "devcp_form_author_add"
+#~ msgstr "Добавить автора"
+
+#~ msgid "devcp_form_author_remove"
+#~ msgstr "ПеремеÑтить/удалить"
+
+#~ msgid "devcp_form_categories_nextstep"
+#~ msgstr ""
+#~ "Категории Ð´Ð»Ñ Ð½Ð¾Ð²Ð¾Ð³Ð¾ типа дополнений будут доÑтупны на Ñледующем шаге."
+
+#~ msgid "devcp_form_error_categories_unavailable"
+#~ msgstr "Ð”Ð»Ñ Ñтого типа дополнений нет доÑтупных категорий."
+
+#~ msgid "devcp_form_error_description_notempty"
+#~ msgstr "Введите опиÑание вашего дополнениÑ."
+
+#~ msgid "devcp_form_error_name_required"
+#~ msgstr "Введите название вашего дополнениÑ."
+
+#~ msgid "devcp_form_error_select_addontype"
+#~ msgstr "Выберите тип дополнениÑ, которое вы публикуете."
+
+#~ msgid "devcp_form_error_summary_notempty"
+#~ msgstr "Введите аннотацию Ð´Ð»Ñ Ð²Ð°ÑˆÐµÐ³Ð¾ дополнениÑ."
+
+#~ msgid "devcp_form_label_addonfile"
+#~ msgstr "Файл дополнениÑ"
+
+#~ msgid "devcp_form_label_addonfile2"
+#~ msgstr "Второй файл дополнениÑ"
+
+#~ msgid "devcp_form_label_addonfile3"
+#~ msgstr "Третий файл дополнениÑ"
+
+#~ msgid "devcp_form_label_addontype"
+#~ msgstr "Тип дополнениÑ"
+
+#~ msgid "devcp_form_label_allow_viewsource"
+#~ msgstr "Разрешить пользователÑм проÑматривать иÑходный код"
+
+#~ msgid "devcp_form_label_author_email"
+#~ msgstr "ÐÐ´Ñ€ÐµÑ Ñл. почты автора"
+
+#~ msgid "devcp_form_label_authors"
+#~ msgstr "Ðвторы"
+
+#~ msgid "devcp_form_label_categories"
+#~ msgstr "Категории"
+
+#~ msgid "devcp_form_label_defaultlocale"
+#~ msgstr "Язык по умолчанию"
+
+#~ msgid "devcp_form_label_description"
+#~ msgstr "ОпиÑание"
+
+#~ msgid "devcp_form_label_eula"
+#~ msgstr "Лицензионное Ñоглашение (EULA)"
+
+#~ msgid "devcp_form_label_externalsoftware"
+#~ msgstr "Дополнительное программное обеÑпечение"
+
+#~ msgid "devcp_form_label_files"
+#~ msgstr "Файлы дополнениÑ"
+
+#~ msgid "devcp_form_label_homepage"
+#~ msgstr "ДомашнÑÑ Ñтраница"
+
+#~ msgid "devcp_form_label_iconfile"
+#~ msgstr "Файл значка"
+
+#~ msgid "devcp_form_label_name"
+#~ msgstr "Ðазвание"
+
+#~ msgid "devcp_form_label_platforms"
+#~ msgstr "Поддерживаемые платформы"
+
+#~ msgid "devcp_form_label_prerelease"
+#~ msgstr "Предварительный выпуÑк"
+
+#~ msgid "devcp_form_label_privacy"
+#~ msgstr "Политика конфиденциальноÑти"
+
+#~ msgid "devcp_form_label_sitespecific"
+#~ msgstr "Дополнение Ð´Ð»Ñ Ð¾Ð¿Ñ€ÐµÐ´ÐµÐ»Ñ‘Ð½Ð½Ð¾Ð³Ð¾ Ñайта"
+
+#~ msgid "devcp_form_label_summary"
+#~ msgstr "ÐннотациÑ"
+
+#~ msgid "devcp_form_label_supportemail"
+#~ msgstr "ÐÐ´Ñ€ÐµÑ Ñл. почты поддержки"
+
+#~ msgid "devcp_form_label_supporturl"
+#~ msgstr "URL поддержки"
+
+#~ msgid "devcp_form_label_target_applications"
+#~ msgstr "Приложение"
+
+#~ msgid "devcp_form_label_version"
+#~ msgstr "ВерÑиÑ"
+
+#~ msgid "devcp_form_label_versionnotes"
+#~ msgstr "Ð˜Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¾ верÑии"
+
+#~ msgid "devcp_form_no_target_apps"
+#~ msgstr "Ðет"
+
+#~ msgid "devcp_form_reviewernotes"
+#~ msgstr "Заметки рецензенту"
+
+#~ msgid "devcp_form_trustedaddon_destination"
+#~ msgstr ""
+#~ "ПоÑкольку вашему дополнению доверÑÑŽÑ‚, выберите, куда помеÑтить Ñту верÑию:"
+
+#~ msgid "devcp_form_trustedaddon_destination_public"
+#~ msgstr "Ð’ общий доÑтуп"
+
+#~ msgid "devcp_form_trustedaddon_destination_sandbox"
+#~ msgstr "Ð’ «пеÑочницу»"
+
+#~ msgid "devcp_header_developer_agreement"
+#~ msgstr "Соглашение разработчика"
+
+#~ msgid "devcp_header_step1"
+#~ msgstr "Шаг 1"
+
+#~ msgid "devcp_header_step1_upload"
+#~ msgstr "Загрузка на Ñервер"
+
+#~ msgid "devcp_header_step2"
+#~ msgstr "Шаг 2"
+
+#~ msgid "devcp_header_step2_addondetails"
+#~ msgstr "Ð˜Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¾ дополнении"
+
+#~ msgid "devcp_header_step3"
+#~ msgstr "Шаг 3"
+
+#~ msgid "devcp_header_step3_versiondetails"
+#~ msgstr "Ð˜Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¾ новой верÑии"
+
+#~ msgid "devcp_header_step4"
+#~ msgstr "Шаг 4"
+
+#~ msgid "devcp_header_step4_localization"
+#~ msgstr "Переводы на другие Ñзыки"
+
+#~ msgid "devcp_header_step5"
+#~ msgstr "Шаг 5"
+
+#~ msgid "devcp_header_step5_success"
+#~ msgstr "Завершение"
+
+#~ msgid "devcp_index_header_myaddons"
+#~ msgstr "Мои дополнениÑ"
+
+#~ msgid "devcp_nominate_link_returnto_details"
+#~ msgstr "ВернутьÑÑ Ðº ÑведениÑм о дополнении"
+
+# %1 is the autodetected addon type
+#~ msgid "devcp_notice_autodetected_addontype"
+#~ msgstr "ÐвтоматичеÑки определённый тип дополнениÑ: %s."
+
+# %1 is the default locale name (English (US))
+# %2 is the default locale code (en-US)
+# %3 is the current page locale name (Deutsch)
+# %4 is the current page locale code (de)
+#~ msgid "devcp_notice_different_defaultlocale"
+#~ msgstr ""
+#~ "Язык по умолчанию Ð´Ð»Ñ Ñтого Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ (%1$s [%2$s]) отличаетÑÑ Ð¾Ñ‚ "
+#~ "выбранного вами Ñзыка (%3$s [%4$s]). ÐŸÐ¾Ð»Ñ Ñ€Ð°Ñположенные ниже должны быть "
+#~ "заполнены на %1$s."
+
+#~ msgid "devcp_question_addontype_incorrect"
+#~ msgstr "Ðе ÑоответÑтвует?"
+
+#~ msgid "devcp_question_delete_file"
+#~ msgstr "Ð’Ñ‹ уверены, что хотите удалить Ñтот файл?"
+
+#~ msgid "devcp_skip_reviewing_addon_info"
+#~ msgstr "ПропуÑтить обновление текущей информации о дополнении"
+
+#~ msgid "devcp_submissions_disabled"
+#~ msgstr ""
+#~ "Ð’ наÑтоÑщее Ð²Ñ€ÐµÐ¼Ñ Ð¿ÑƒÐ±Ð»Ð¸ÐºÐ°Ñ†Ð¸Ñ Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ð¹ заблокирована. Попробуйте "
+#~ "вернутьÑÑ Ð¸ попробовать позднее."
+
+#~ msgid "devcp_submit_accept_dev_agreement"
+#~ msgstr "ПринÑÑ‚ÑŒ"
+
+#~ msgid "devcp_submit_decline_dev_agreement"
+#~ msgstr "Отклонить"
+
+#~ msgid "devcp_summary_admin_disabled"
+#~ msgstr "Это дополнение было заблокировано админиÑтратором."
+
+#~ msgid "devcp_summary_header_disabled"
+#~ msgstr "Заблокировано"
+
+#~ msgid "devcp_summary_header_trusted"
+#~ msgstr "ДоверÑÑ‚ÑŒ"
+
+# %1 is a link to the addon submit page
+#~ msgid "devcp_summary_noaddons_submit_one"
+#~ msgstr "У Ð²Ð°Ñ Ð½ÐµÑ‚ дополнений. Щёлкните %s Ð´Ð»Ñ Ð¿ÑƒÐ±Ð»Ð¸ÐºÐ°Ñ†Ð¸Ð¸."
+
+#~ msgid "devcp_summary_noaddons_submit_one_link"
+#~ msgstr "здеÑÑŒ"
+
+# %1 is the link to the preview upload page
+#~ msgid "devcp_theme_upload_preview"
+#~ msgstr "УбедитеÑÑŒ, что %s Ð´Ð»Ñ Ð²Ð°ÑˆÐµÐ¹ темы."
+
+#~ msgid "devcp_theme_upload_preview_link"
+#~ msgstr "загрузили иллюÑтрацию"
+
+#~ msgid "devcp_version_edit_pagetitle"
+#~ msgstr "Изменить верÑию"
+
+#~ msgid "devcp_version_updated_successfully"
+#~ msgstr "ВерÑÐ¸Ñ Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð° уÑпешно."
+
+#~ msgid "editors_submissiontype_new"
+#~ msgstr "Ðовое"
+
+#~ msgid "editors_submissiontype_updated"
+#~ msgstr "Обновлено"
+
+#, fuzzy
+#~ msgid "editors_th_addon_age"
+#~ msgstr "Addon Age"
+
+#~ msgid "editors_th_addontypes"
+#~ msgstr "Типы дополнений"
+
+#~ msgid "editors_th_age"
+#~ msgstr "ВозраÑÑ‚"
+
+#~ msgid "editors_th_applications"
+#~ msgstr "ПриложениÑ"
+
+#~ msgid "editors_th_platforms"
+#~ msgstr "Платформы"
+
+#~ msgid "editors_th_submissiontypes"
+#~ msgstr "Типы публикации"
+
+#~ msgid "error_notice"
+#~ msgstr "Предупреждение"
+
+#~ msgid "forum_save"
+#~ msgstr "Сохранить"
+
+#~ msgid "home"
+#~ msgstr "домой"
+
+#~ msgid "nav_category_plugins"
+#~ msgstr "Плагины"
+
+#~ msgid "page_title_experimental_addons"
+#~ msgstr "ЭкÑпериментальные дополнениÑ"
+
+#~ msgid "pages_experimental_addons_backbutton"
+#~ msgstr "ВернутьÑÑ Ð½Ð° предыдущую Ñтраницу"
+
+# %1 is page number, %2 is total page count
+#, fuzzy
+#~ msgid "pagination_page_number_title"
+#~ msgstr "Страница %1$s из %2$s"
+
+#~ msgid "search_matching_addons_number"
+#~ msgid_plural "search_matching_addons_number"
+#~ msgstr[0] "%s подходÑщее дополнение"
+#~ msgstr[1] "%s подходÑщих дополнениÑ"
+#~ msgstr[2] "%s подходÑщих дополнений"
+
+#~ msgid "statistics_rss_icon_title"
+#~ msgstr "RSS-канал Ñводки данных"
diff --git a/site/app/locale/ru/images/sandbox-review.png b/site/app/locale/ru/images/sandbox-review.png
new file mode 100644
index 0000000..01c5421
--- /dev/null
+++ b/site/app/locale/ru/images/sandbox-review.png
Binary files differ
diff --git a/site/app/locale/ru/pages/about.thtml b/site/app/locale/ru/pages/about.thtml
new file mode 100644
index 0000000..8379288
--- /dev/null
+++ b/site/app/locale/ru/pages/about.thtml
@@ -0,0 +1,67 @@
+<h2>Что такое addons.mozilla.org?</h2>
+<p>
+ addons.mozilla.org (AMO) Ñто официальный Ñайт проекта Mozilla на котором
+ размещены Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð´Ð»Ñ Ð¿Ñ€Ð¸Ð»Ð¾Ð¶ÐµÐ½Ð¸Ð¹ Mozilla. Ð”Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð¿Ð¾Ð·Ð²Ð¾Ð»ÑÑŽÑ‚ Вам добавлÑÑ‚ÑŒ
+ новые возможноÑти в Firefox, Thunderbird, SeaMonkey и Sunbird. Ðа AMO Ð’Ñ‹ можете
+ найти и уÑтановить Ñ‚Ñ‹ÑÑчи различных дополнений, которые помогут Вам при
+ пользовании Интернет.
+</p>
+
+<h2>Кто Ñоздает дополнениÑ?</h2>
+<p>
+ ТыÑÑчи разработчиков дополнений - от одиночек-любителей до крупных
+ корпораций. Ð’Ñе публичные Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð¿ÐµÑ€ÐµÐ´ их официальным релизом проходÑÑ‚
+ проверку Ñпециализированным штатом добровольцев. Ð’Ñе дополнениÑ, которые
+ находÑÑ‚ÑÑ Ð½Ð° Ñтадии теÑтированиÑ, отмечены как ÑкÑпериментальные и не были
+ официально одобрены.
+</p>
+
+<h2>Как Ñ Ð¼Ð¾Ð³Ñƒ узнать что проиÑходит на AMO?</h2>
+<p>
+ Ðаш <a href="http://blog.mozilla.com/addons/">блог</a> поÑтоÑнно обновлÑетÑÑ Ð¸
+ на нем чаÑто размещаютÑÑ ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ Ð¾Ñ‚ оÑновного ÑообщеÑтва AMO. Также Ð’Ñ‹
+ можете подпиÑатьÑÑ Ð½Ð° ежемеÑÑчную <a href="https://addons.mozilla.org/newsletter">
+ раÑÑылку</a> новоÑтей.
+</p>
+
+<h2>Чем Ñ Ð¼Ð¾Ð³Ñƒ помочь AMO?</h2>
+<p>
+ ЕÑÑ‚ÑŒ неÑколько вариантов:
+</p>
+<ul>
+ <li>
+ <a href="https://wiki.mozilla.org/AMO:Editors/Applying">Стать редактором</a>.
+ Ðаши редакторы - Ñто техничеÑки грамотные поклонники AMO, которые проверÑÑŽÑ‚
+ Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð½Ð° качеÑтво кода и ÑтабильноÑÑ‚ÑŒ работы.
+ </li>
+ <li>
+ <a href="http://developer.mozilla.org/">Создать Ñвое дополнение</a>. AMO
+ предоÑтавлÑет беÑплатные уÑлуги Ñ€Ð°Ð·Ð¼ÐµÑ‰ÐµÐ½Ð¸Ñ Ð²Ð°ÑˆÐ¸Ñ… дополнений и ÑÐµÑ€Ð²Ð¸Ñ Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ
+ и может обеÑпечить Вашему дополнению большую аудиторию пользователей.
+ </li>
+ <li>
+ РаÑÑказать Ñвоим друзьÑм. <a href="http://spreadfirefox.com/">РаÑпроÑтранÑйте Firefox</a>,
+ и пуÑÑ‚ÑŒ люди знают какими дополнениÑми Ð’Ñ‹ пользуетеÑÑŒ.
+ </li>
+ <li>
+ Сообщать об ошибках и иÑправлÑÑ‚ÑŒ их. Ð’ ÑиÑтеме <a href="https://bugzilla.mozilla.org/buglist.cgi?quicksearch=addons">Bugzilla</a>
+ ÑодержатьÑÑ Ð²Ñе текущие ошибки дополнений AMO. Ð’Ñ‹ можете отправить отчет о новой
+ ошибке или решение ÑущеÑтвующей проблемы.
+ </li>
+</ul>
+
+<h2>У Ð¼ÐµÐ½Ñ ÐµÑÑ‚ÑŒ вопроÑ.</h2>
+<p>
+ Вы можете найти ответ в нашем
+ <a href="https://addons.mozilla.org/pages/faq"><abbr title="Frequently Asked Questions">FAQ</abbr></a>.
+ ЕÑли Ð’Ñ‹ не нашли ответа на Ваш вопроÑ, то можете ÑвÑзатьÑÑ Ñ Ð½Ð°Ð¼Ð¸ - контактнаÑ
+ Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¿Ñ€ÐµÐ´Ñтавлена внизу данной Ñтраницы. Ð”Ð»Ñ Ð²Ð¾Ð¿Ñ€Ð¾Ñов по конкретному
+ дополнению иÑпользуйте контактную информацию Ñо Ñтраницы Ñтого дополнениÑ.
+</p>
+
+<h2>СвÑзатьÑÑ Ñ Ð½Ð°Ð¼Ð¸.</h2>
+<dl>
+ <dt><abbr title="Internet Relay Chat">IRC</abbr>-чат:</dt>
+ <dd><a href="irc://irc.mozilla.org/#addons">#addons</a> на irc.mozilla.org Ð´Ð»Ñ Ð¾Ð±Ñ‰Ð¸Ñ… вопроÑов и вопроÑов теÑтированиÑ</dd>
+ <dd><a href="irc://irc.mozilla.org/#amo">#amo</a> on irc.mozilla.org Ð´Ð»Ñ Ð²Ð¾Ð¿Ñ€Ð¾Ñов админиÑÑ‚Ñ€Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ð¸ вопроÑов по разработке</dd>
+</dl>
diff --git a/site/app/locale/ru/pages/error404.thtml b/site/app/locale/ru/pages/error404.thtml
new file mode 100644
index 0000000..30d66b7
--- /dev/null
+++ b/site/app/locale/ru/pages/error404.thtml
@@ -0,0 +1,16 @@
+<h1>Извините, но то, что вы ищете, не может быть найдено.</h1>
+
+<p>Ð—Ð°Ð¿Ñ€Ð¾ÑˆÐµÐ½Ð½Ð°Ñ Ð²Ð°Ð¼Ð¸ Ñтраница или файл на нашем Ñайте не найдены. Возможно ÑÑылка, по которой вы щёлкнули, уÑтарела, или вы ошиблиÑÑŒ при вводе адреÑа.</p>
+
+<ul>
+<li>ЕÑли вы набрали Ð°Ð´Ñ€ÐµÑ Ð²Ñ€ÑƒÑ‡Ð½ÑƒÑŽ, проверьте верно ли вы его ввели.</li>
+<li>ЕÑли вы попали Ñюда, щёлкнув где-либо по ÑÑылке, Ñообщите нам об Ñтом по адреÑу <a href="mailto:webmaster@mozilla.com" title="Page Not Found on Mozilla.com">webmaster@mozilla.com</a>. Ðапишите нам (на английÑком Ñзыке) как вы Ñюда попали и что иÑкали, и мы Ñделаем вÑÑ‘ что возможно, чтобы Ñто иÑправить.</li>
+</ul>
+
+<p>Или же вы можете перейти отÑюда на некоторые из популÑрных Ñтраниц нашего веб-Ñайта.</p>
+
+<ul>
+<li>Хотите поÑмотреть <a href="%1$s">ÑпиÑок популÑрных дополнений</a>?</li>
+<li>Рможет вы хотите <a href="%2$s">найти дополнение</a>? Ð’Ñ‹ можете перейти на <a href="%2$s">Ñтраницу поиÑка</a> или проÑто иÑпользовать раÑположенное ниже поле Ð´Ð»Ñ Ð¿Ð¾Ð¸Ñка.</li>
+<li>ЕÑли же вы хотите начать Ñ Ñамого начала, вы можете перейти на <a href="%3$s">главную Ñтраницу Ñайта дополнений</a>.</li>
+</ul>
diff --git a/site/app/locale/ru/pages/nomination.thtml b/site/app/locale/ru/pages/nomination.thtml
new file mode 100644
index 0000000..2c1f19f
--- /dev/null
+++ b/site/app/locale/ru/pages/nomination.thtml
@@ -0,0 +1,9 @@
+<p>Дополнение, которое находитÑÑ Ð² «пеÑочнице», может быть номинировано на предоÑтавление его в общий доÑтуп поÑле раÑÑÐ¼Ð¾Ñ‚Ñ€ÐµÐ½Ð¸Ñ ÐµÐ³Ð¾ редактором. Ð”Ð»Ñ Ð´Ð¾ÑÑ‚Ð¸Ð¶ÐµÐ½Ð¸Ñ Ð½Ð°Ð¸Ð»ÑƒÑ‡ÑˆÐ¸Ñ… результатов, пожалуйÑта, обратите внимание на Ñледующее:</p>
+<ul>
+ <li>Ð”Ð»Ñ Ñ‚ÐµÐ¼ Ð¾Ñ„Ð¾Ñ€Ð¼Ð»ÐµÐ½Ð¸Ñ Ð½ÐµÐ¾Ð±Ñ…Ð¾Ð´Ð¸Ð¼Ð¾ загрузить иллюÑтрации; Ð´Ð»Ñ Ð´Ñ€ÑƒÐ³Ð¸Ñ… типов дополнений иллюÑтрации наÑтоÑтельно рекомендуютÑÑ.</li>
+ <li>Дополнение должно провеÑти доÑтаточно времени в «пеÑочнице», чтобы получить некоторое количеÑтво рецензий и отзывов от пользователей. Рецензии должны пройти модерацию.</li>
+ <li>Ð¢Ñ€ÐµÐ±Ð¾Ð²Ð°Ð½Ð¸Ñ Ðº качеÑтву общедоÑтупных дополнений выше, чем к качеÑтву дополнений в «пеÑочнице». ОбщедоÑтупные Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð´Ð¾Ð»Ð¶Ð½Ñ‹ улучшать работу пользователей в Ñети.</li>
+ <li>Полный ÑпиÑок критериев Ð½Ð¾Ð¼Ð¸Ð½Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ð¼Ð¾Ð¶Ð½Ð¾ поÑмотреть в <a href="%s">Политике раÑпроÑÑ‚Ñ€Ð°Ð½ÐµÐ½Ð¸Ñ Ð¸ иÑÐ¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ð¹</a>.</li>
+</ul>
+<p>ЕÑли ваше дополнение удовлетворÑет вышеуказанным требованиÑм, вы можете номинировать его Ñ Ð¿Ð¾Ð¼Ð¾Ñ‰ÑŒÑŽ кнопки, раÑположенной ниже. Об изменении ÑоÑтоÑÐ½Ð¸Ñ Ð²Ð°ÑˆÐµÐ³Ð¾ запроÑа вы будете оповещены по Ñлектронной почте.</p>
+<p>Чтобы номинировать Ваше дополнение, пожалуйÑта, опишите результаты его теÑÑ‚Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ (Ð²ÐºÐ»ÑŽÑ‡Ð°Ñ Ð½Ð°Ð»Ð¸Ñ‡Ð¸Ðµ или отÑутÑтвие ошибок и предупреждений) и его полезноÑÑ‚ÑŒ Ð´Ð»Ñ Ð±Ð¾Ð»ÐµÐµ широкой аудитории пользователей. Также Ð’Ñ‹ можете привеÑти ÑÑылки на рецензии Ñ Ð´Ñ€ÑƒÐ³Ð¸Ñ… Ñайтов.</p>
diff --git a/site/app/locale/ru/pages/sandbox.thtml b/site/app/locale/ru/pages/sandbox.thtml
new file mode 100644
index 0000000..f41806b
--- /dev/null
+++ b/site/app/locale/ru/pages/sandbox.thtml
@@ -0,0 +1,13 @@
+<h1>«ПеÑочница»</h1>
+<h2>Ð”Ð»Ñ Ñ‡ÐµÐ³Ð¾ нужна «пеÑочница»?</h2>
+<p>«ПеÑочница» (ÑиÑтема Ñ€ÐµÑ†ÐµÐ½Ð·Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ð¹) — Ñто раздел Ð´Ð»Ñ Ð¾Ð¿Ñ‹Ñ‚Ð½Ñ‹Ñ… пользователей, в котором они могут Ñкачать и затем протеÑтировать Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð¿ÐµÑ€ÐµÐ´ предоÑтавлением их в общий доÑтуп. Чтобы получить доÑтуп к «пеÑочнице», вам необходимо разрешить её в наÑтройках вашей учётной запиÑи. Ðеобходимо проÑвлÑÑ‚ÑŒ оÑторожноÑÑ‚ÑŒ при уÑтановке дополнений из «пеÑочницы», так как они не были проверены редакторами и могут нанеÑти вред вашему компьютеру.</p>
+
+<h2>Каким образом Ñделать дополнение общедоÑтупным?</h2>
+<!-- To localize the flowchart image, see http://wiki.mozilla.org/Update:Remora_Sandbox_Flowchart -->
+<div style="text-align: center;">%s</div>
+<ol>
+ <li><b>Загрузите дополнение на Ñайт, иÑÐ¿Ð¾Ð»ÑŒÐ·ÑƒÑ Ð¿Ð°Ð½ÐµÐ»ÑŒ ÑƒÐ¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ñ€Ð°Ð·Ñ€Ð°Ð±Ð¾Ñ‚Ñ‡Ð¸ÐºÐ°.</b> Ðа первом Ñтапе дополнение Ñразу же поÑвитÑÑ Ð² «пеÑочнице» Ñайта Addons.Mozilla.org, где квалифицированные пользователи (выÑтупающие в качеÑтве теÑтеров) Ñмогут его протеÑтировать и оÑтавить отзывы о работе и Ð¿Ñ€ÐµÐ´Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ Ð¿Ð¾ улучшению. Чтобы получить доÑтуп к «пеÑочнице» вам потребуетÑÑ Ð²ÐºÐ»ÑŽÑ‡Ð¸Ñ‚ÑŒ её отображение в наÑтройках учётной запиÑи. </li>
+ <li><b>Ðоминируйте дополнение на публикацию.</b> Одна из возможноÑтей панели ÑƒÐ¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ñ€Ð°Ð·Ñ€Ð°Ð±Ð¾Ñ‚Ñ‡Ð¸ÐºÐ° — Ð½Ð¾Ð¼Ð¸Ð½Ð°Ñ†Ð¸Ñ Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð½Ð° публикацию в общий доÑтуп. ПоÑле Ñтого дополнение поÑтупит на раÑÑмотрение к редакторам. </li>
+ <li><b>Проверка Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ñ€ÐµÐ´Ð°ÐºÑ‚Ð¾Ñ€Ð¾Ð¼.</b> Редактор Addons.Mozilla.org уÑтановит дополнение Ð´Ð»Ñ Ñ‚ÐµÑÑ‚Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ ÐµÐ³Ð¾ работы. Кроме того он ознакомитÑÑ Ñ Ð¾Ñ‚Ð·Ñ‹Ð²Ð°Ð¼Ð¸ по работе и функциональноÑти дополнениÑ, оÑтавленными теÑтерами. </li>
+ <li><b>ÐŸÑƒÐ±Ð»Ð¸ÐºÐ°Ñ†Ð¸Ñ Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ, либо его «удержание» в «пеÑочнице».</b> Редактор либо Ñделает дополнение общедоÑтупным, либо оÑтавит в «пеÑочнице». Во втором Ñлучае вы можете предÑтавить дополнение на повторную публикацию поÑле внеÑÐµÐ½Ð¸Ñ Ð¿Ñ€ÐµÐ´Ð»Ð¾Ð¶ÐµÐ½Ð½Ñ‹Ñ… рецензентом доработок. ПоÑле публикации Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð¸Ñчезнет необходимоÑÑ‚ÑŒ выÑтавлÑÑ‚ÑŒ его на публикацию — будущие верÑии будут автоматичеÑки помещатьÑÑ Ð² очередь на раÑÑмотрение. </li>
+</ol>
diff --git a/site/app/locale/ru/pages/submission_help.thtml b/site/app/locale/ru/pages/submission_help.thtml
new file mode 100644
index 0000000..2325144
--- /dev/null
+++ b/site/app/locale/ru/pages/submission_help.thtml
@@ -0,0 +1,35 @@
+<h1>Помощь по публикации дополнениÑ</h1>
+ОбÑзательные Ð´Ð»Ñ Ð·Ð°Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð¿Ð¾Ð»Ñ Ð²Ñ‹Ð´ÐµÐ»ÐµÐ½Ñ‹ <b>полужирным шрифтом<b>, необÑзательные — <i>курÑивом</i>.
+<h2 id="step1">Шаг первый: Загрузка на Ñервер</h2>
+<ul class="submissionHelp">
+ <li><span class="required">Тип дополнениÑ</span> — по умолчанию тип Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð°Ð²Ñ‚Ð¾Ð¼Ð°Ñ‚Ð¸Ñ‡ÐµÑки определÑетÑÑ Ð¿Ñ€Ð¸ загрузке. Обычно вам не придётÑÑ Ð¸Ð·Ð¼ÐµÐ½ÑÑ‚ÑŒ Ñто поле.</li>
+ <li><span class="required">Файл дополнениÑ</span> — упакованный файл вашего дополнениÑ, Ñодержащий файл «install.rdf». ЕÑли ÑущеÑтвуют отдельные верÑии Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð´Ð»Ñ Ñ€Ð°Ð·Ð½Ñ‹Ñ… платформ, то указание конкретной платформы позволит выбрать файлы Ð´Ð»Ñ ÐºÐ°Ð¶Ð´Ð¾Ð¹ из них.</li>
+ <li><span class="optional">Файл значка</span> — значок показываетÑÑ Ñ€Ñдом Ñ Ð½Ð°Ð·Ð²Ð°Ð½Ð¸ÐµÐ¼ Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð½Ð° его Ñтранице и в диалоге уÑтановки. Изображение будет автоматичеÑки отмаÑштабировано до 32Ñ…32 (в пикÑелÑÑ…), Ñ Ñохранением ÑÐ¾Ð¾Ñ‚Ð½Ð¾ÑˆÐµÐ½Ð¸Ñ Ñторон.</li>
+ <li><span class="required">Язык по умолчанию</span> — Ñто оÑновной Ñзык дополнениÑ. Он будет иÑпользоватьÑÑ, еÑли перевод на выбранный пользователем Ñзык недоÑтупен.</li>
+ <li><span class="optional">ПропуÑтить обновление текущей информации о дополнении</span> — Ñто поле поÑвитÑÑ, еÑли выполнÑетÑÑ Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ðµ ÑущеÑтвующего дополнениÑ. Отметив Ñто поле, вы Ñможете Ñразу перейти к третьему Ñтапу и ввеÑти информацию о новой верÑии.</li>
+</ul>
+
+<h2 id="step2">Шаг второй: Ð˜Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¾ дополнении</h2>
+<ul class="submissionHelp">
+ <li><span class="required">Ðазвание</span> — название вашего Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð½Ð° Ñзыке по умолчанию;</li>
+ <li><span class="required">Ðвторы</span> — пользователи, у которых еÑÑ‚ÑŒ доÑтуп к изменению/модификации кода Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ (они будут перечиÑлены на Ñтранице дополнениÑ);</li>
+ <li><span class="required">Категории</span> — категории дополнениÑ;</li>
+ <li><span class="optional">ДомашнÑÑ Ñтраница</span> — Ñайт Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð½Ð° Ñзыке по умолчанию;</li>
+ <li><span class="required">ÐннотациÑ</span> — краткое опиÑание Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð½Ð° Ñзыке по умолчанию. МакÑимум 250 Ñимволов. Этот текÑÑ‚ будет показыватьÑÑ Ð½Ð° Ñтранице Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð¸ в результатах поиÑка.</li>
+ <li><span class="required">ОпиÑание</span> — подробное опиÑание Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð½Ð° Ñзыке по умолчанию. Данный текÑÑ‚ будет показыватьÑÑ Ð½Ð° Ñтранице Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð¿Ð¾Ð´ аннотацией</li>
+ <li><span class="optional">Лицензионное Ñоглашение (EULA)</span> — «Лицензионное Ñоглашение конечного пользователÑ» на Ñзыке по умолчанию, которое необходимо принÑÑ‚ÑŒ перед загрузкой дополнениÑ.</li>
+ <li><span class="optional">Политика конфиденциальноÑти</span> — политика конфиденциальноÑти Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð½Ð° Ñзыке по умолчанию. Политика конфиденциальноÑти объÑÑнÑет, что проиÑходит Ñ Ð»Ð¸Ñ‡Ð½Ñ‹Ð¼Ð¸ данными пользователÑ. СÑылка на политику конфиденциальноÑти будет размещатьÑÑ Ñ€Ñдом Ñ ÐºÐ½Ð¾Ð¿ÐºÐ¾Ð¹ уÑтановки на Ñтранице дополнениÑ. Ð˜Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¾ том, что должно быть включено в политику конфиденциальноÑти, и о том, необходима ли политика конфиденциальноÑти вашему дополнению, доÑтупна на Ñтранице <a href="%s">Политике раÑпроÑÑ‚Ñ€Ð°Ð½ÐµÐ½Ð¸Ñ Ð¸ иÑÐ¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ð¹</a>.</li>
+ <li><span class="optional">Разрешить пользователÑм проÑматривать иÑходный код</span> — означает, что проÑмотр иÑходного кода Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð±ÑƒÐ´ÐµÑ‚ доÑтупен вÑем пользователÑм через Ð¸Ð½Ñ‚ÐµÑ€Ñ„ÐµÐ¹Ñ AMO. </li>
+ <li><span class="optional">Предварительный выпуÑк</span> — означает, что Ñто Ð¿Ñ€ÐµÐ´Ð²Ð°Ñ€Ð¸Ñ‚ÐµÐ»ÑŒÐ½Ð°Ñ Ð¸Ð»Ð¸ «бета»-верÑÐ¸Ñ Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ. Такие верÑии Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð´Ð¾Ð»Ð¶Ð½Ñ‹ оÑтаватьÑÑ Ð² «пеÑочнице», они не могут быть номинированы Ð´Ð»Ñ Ð¿Ð¾ÐºÐ°Ð·Ð° на общедоÑтупном веб-Ñайте.</li>
+ <li><span class="optional">Дополнение Ð´Ð»Ñ Ð¾Ð¿Ñ€ÐµÐ´ÐµÐ»Ñ‘Ð½Ð½Ð¾Ð³Ð¾ Ñайта</span> — означает что, дополнение предназначено Ð´Ð»Ñ Ñ€Ð°Ð±Ð¾Ñ‚Ñ‹ на одном определённом веб-Ñайте. К таким дополнениÑм отноÑÑÑ‚ÑÑ, например, такие, которые изменÑÑŽÑ‚ внешний вид определённого веб-Ñайта или показывают данные Ñ Ð´Ñ€ÑƒÐ³Ð¾Ð³Ð¾ веб-Ñайта. Данный параметр полезен редакторам, кроме того в будущем он может иÑпользоватьÑÑ ÐºÐ°Ðº критерий Ð´Ð»Ñ Ð¿Ð¾Ð¸Ñка.</li>
+ <li><span class="optional">Дополнительное программное обеÑпечение</span> — означает, что дополнению Ð´Ð»Ñ Ð²Ñ‹Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ñвоих функций требуетÑÑ Ñтороннее программное обеÑпечение.</li>
+</ul>
+
+<h2 id="step3">Шаг третий: Ð˜Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¾ новой верÑии</h2>
+<ul class="submissionHelp">
+ <li><span class="required optional">Ð˜Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¾ верÑии</span> — ÐºÑ€Ð°Ñ‚ÐºÐ°Ñ Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¾ новой верÑии или ÑпиÑок изменений. Данное поле обÑзательно должно быть заполнено только при обновлении дополнениÑ.</li>
+ <li><span class="optional">Заметки рецензенту</span> — данное поле иÑпользуетÑÑ Ð°Ð²Ñ‚Ð¾Ñ€Ð¾Ð¼ Ð´Ð»Ñ Ð¾Ð±Ð¼ÐµÐ½Ð° информацией Ñ Ñ€ÐµÑ†ÐµÐ½Ð·ÐµÐ½Ñ‚Ð°Ð¼Ð¸, которые будут раÑÑматривать дополнение. Ð’ Ñтом поле Ñледует указывать Ð¿Ñ€Ð¸Ð¼ÐµÑ‡Ð°Ð½Ð¸Ñ Ð¸, например, информацию о теÑтовой учётной запиÑи.</li>
+</ul>
+
+<h2 id="step4">Шаг четвёртый: Переводы на другие Ñзыки</h2>
+Данные Ð¿Ð¾Ð»Ñ Ð¿Ñ€ÐµÐ´Ð½Ð°Ð·Ð½Ð°Ñ‡ÐµÐ½Ñ‹ Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÐ²Ð¾Ð´Ð° Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð½Ð° вÑе поддерживаемые Ñзыки. ПроÑто нажмите на нужный Ñзык и введите перевод.
diff --git a/site/app/locale/sk/LC_MESSAGES/messages.mo b/site/app/locale/sk/LC_MESSAGES/messages.mo
new file mode 100644
index 0000000..5988c67
--- /dev/null
+++ b/site/app/locale/sk/LC_MESSAGES/messages.mo
Binary files differ
diff --git a/site/app/locale/sk/LC_MESSAGES/messages.po b/site/app/locale/sk/LC_MESSAGES/messages.po
new file mode 100644
index 0000000..2cdd67e
--- /dev/null
+++ b/site/app/locale/sk/LC_MESSAGES/messages.po
@@ -0,0 +1,7258 @@
+# Copyright (C) 2006 Mozilla Corporation
+# This file is distributed under the same license as the REMORA package.
+# Wil Clouser <clouserw@mozilla.com>, 2006.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: REMORA 0.1\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2009-01-16 11:45-0800\n"
+"PO-Revision-Date: 2009-06-04 11:56+0100\n"
+"Last-Translator: wladow <info@wladow.sk>\n"
+"Language-Team: SLOVAK <l10n@mozilla.sk>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=3; plural=n==1 ? 0 : n>=2 && n<=4 ? 1 : 2\n"
+
+#: views/addons/policy.thtml:98
+msgid "a_cancel_installation"
+msgstr "Zrušiť inštaláciu"
+
+#. This is the text that appears on buttons to download add-ons.
+#. %$1s is an optional string that only appears if the add-on is only available for
+#. a certain platform. Examples: (Windows) or (Linux)
+#. Note that the parentheses are included in the string. :(
+#: views/elements/amo2009/install.thtml:126
+#: views/elements/amo2009/install.thtml:227
+#: views/elements/amo2009/install.thtml:257
+#: views/elements/amo2009/install.thtml:300
+#: views/elements/amo2009/install.thtml:312
+#: views/elements/install.thtml:73
+#: views/elements/install.thtml:181
+#: views/elements/install.thtml:205
+#: views/elements/install.thtml:248
+#: views/elements/install.thtml:260
+#: views/addons/plugins.thtml:66
+#: views/addons/plugins.thtml:76
+#: views/addons/plugins.thtml:86
+#: views/addons/plugins.thtml:96
+#: views/addons/plugins.thtml:119
+#, php-format
+msgid "a_download"
+msgstr "Prevziať %s"
+
+#: views/addons/policy.thtml:72
+msgid "a_eula_download"
+msgstr "Prijať a prevziať"
+
+#: views/addons/policy.thtml:74
+msgid "a_eula_install"
+msgstr "Prijať a nainštalovať"
+
+#: views/elements/header.thtml:76
+#: views/elements/header.thtml:82
+#: views/api/api_addon.thtml:55
+#: views/api/collections_feed.thtml:75
+#: views/sharing_api/addon.thtml:64
+msgid "a_header_public"
+msgstr "Verejné"
+
+#: views/elements/header.thtml:58
+#: views/elements/header.thtml:75
+#: views/elements/header.thtml:80
+#: views/api/api_addon.thtml:57
+#: views/api/collections_feed.thtml:77
+#: views/sharing_api/addon.thtml:66
+msgid "a_header_sandbox"
+msgstr "Sandbox"
+
+#. %s is a date in the _('date') format
+#: views/elements/amo2009/homepage_addon.thtml:115
+#: views/elements/addon_listitem.thtml:122
+#: views/elements/feature.thtml:106
+#: views/addons/display.thtml:104
+#: views/addons/browse_thumbs.thtml:73
+msgid "addon_detail_last_updated"
+msgstr "Aktualizované: %s"
+
+#. %s is the version of the add-on. Example: 3.2a1
+#: views/elements/amo2009/addon_version_detail.thtml:51
+#: views/elements/addon_version_detail.thtml:51
+#, php-format
+msgid "addon_display_header_version"
+msgstr "Verzia %s"
+
+#: views/addons/browse_thumbs.thtml:80
+msgid "addon_downloads"
+msgstr "prevzatí"
+
+#: views/addons/display.thtml:147
+msgid "addon_downloads_total"
+msgstr "prevzatí spolu"
+
+#: views/elements/amo2009/homepage_addon.thtml:106
+#: views/elements/addon_listitem.thtml:115
+#: views/elements/feature.thtml:101
+#: views/addons/category_landing.thtml:157
+#: views/addons/display.thtml:146
+#: views/addons/browse_thumbs.thtml:80
+msgid "addon_downloads_weekly"
+msgstr "prevzatí za týždeň"
+
+# %1 is the add-on count, %2 the category name
+#. %1 is the add-on count, %2 the category name
+#: views/addons/browse_thumbs.thtml:104
+#: views/addons/browse.thtml:60
+#, php-format
+msgid "addon_list_category_totalcount"
+msgid_plural "addon_list_category_totalcount"
+msgstr[0] "%1$s doplnok"
+msgstr[1] "%1$s doplnky"
+msgstr[2] "%1$s doplnkov"
+
+#: views/elements/amo2009/addon_list_options.thtml:103
+#: views/elements/pagination.thtml:67
+#: views/elements/addon_list_options.thtml:94
+msgid "addon_list_perpage"
+msgstr "na stránku"
+
+#: views/elements/amo2009/addon_list_options.thtml:84
+#: views/elements/addon_list_options.thtml:98
+msgid "addon_list_sortby"
+msgstr "Zoradiť podľa:"
+
+#: views/helpers/addons_html.php:568
+#: views/elements/amo2009/install.thtml:321
+#: views/elements/feature.thtml:89
+msgid "addon_listitem_flag_experimental"
+msgstr "experimentálne"
+
+#: views/helpers/addons_html.php:570
+msgid "addon_listitem_flag_recommended"
+msgstr "odporúÄané"
+
+# %1 is the addon name, %2 is the platform
+#. %1 is the add-on name, %2 is the platform
+#: views/pages/js_constants.js.thtml:66
+msgid "addon_not_available_for_platform"
+msgstr "Doplnok %1$s nie je pre platformu %2$s k dispozícii"
+
+# %1 is the addon name
+#. %1 is the add-on name
+#: views/addons/policy.thtml:101
+#: views/addons/previews.thtml:60
+#: views/addons/versions.thtml:130
+#: views/reviews/flag.thtml:61
+#: views/reviews/add.thtml:114
+#: views/reviews/display.thtml:216
+#: views/reviews/review_added.thtml:57
+#, php-format
+msgid "addon_review_a_back_to_addon_x"
+msgstr "Späť na %1$s…"
+
+# %1 is the addon name
+#. %1 is the add-on name
+#: views/reviews/flag.thtml:60
+#: views/reviews/add.thtml:113
+#: views/reviews/review_added.thtml:56
+#, php-format
+msgid "addon_review_a_back_to_reviews"
+msgstr "Späť na recenzie…"
+
+#: views/reviews/add.thtml:85
+msgid "addon_review_add_rating_field"
+msgstr "Hodnotenie:"
+
+#: views/reviews/add.thtml:102
+msgid "addon_review_add_review_field"
+msgstr "Recenzia:"
+
+#: views/reviews/add.thtml:107
+msgid "addon_review_add_submit"
+msgstr "Odoslať recenziu"
+
+#. %s is the name of the add-on
+#: views/reviews/add.thtml:51
+#, php-format
+msgid "addon_review_add_title"
+msgstr "Pridať recenziu doplnku %s"
+
+#: views/reviews/add.thtml:78
+msgid "addon_review_add_title_field"
+msgstr "Názov/Súhrn:"
+
+#: views/reviews/display.thtml:77
+#: views/reviews/display.thtml:161
+msgid "addon_review_admin_delete"
+msgstr "Odstrániť"
+
+#: views/reviews/display.thtml:76
+msgid "addon_review_author_reply_link"
+msgstr "Odpovedať"
+
+#: views/reviews/delete.thtml:62
+msgid "addon_review_confirm_delete"
+msgstr "Naozaj chcete odstrániť túto recenziu?"
+
+#: views/reviews/delete.thtml:63
+msgid "addon_review_confirm_no"
+msgstr "Nie"
+
+#: views/reviews/delete.thtml:64
+msgid "addon_review_confirm_yes"
+msgstr "Ãno"
+
+#: views/reviews/delete.thtml:48
+msgid "addon_review_delete_header"
+msgstr "Odstrániť recenziu"
+
+#: controllers/reviews_controller.php:449
+msgid "addon_review_deleted_successfully"
+msgstr "Recenzia úspešne odstránená."
+
+#. %s is the name of the add-on
+#: views/reviews/add.thtml:51
+#, php-format
+msgid "addon_review_edit_title"
+msgstr "Upraviť recenziu doplnku %s"
+
+# %1 is the count of characters entered as notes for the review flag reason.
+#. %1 is the count of characters entered as notes for the review flag reason.
+#: controllers/reviews_controller.php:539
+msgid "addon_review_flag_error_other_length"
+msgstr "Problém pri nahlásení recenzie: poznámky k nahláseným recenziám sú obmedzené na 10 až 100 znakov. Vaša poznámka obsahuje %1$s znakov."
+
+#. Removing an extra comma
+#: views/reviews/review_added.thtml:53
+msgid "addon_review_in_moderation"
+msgstr "Nezabudnite: pred publikovaním na verejnej stránke bude recenzia moderovaná editorom."
+
+#: views/reviews/add.thtml:57
+msgid "addon_review_in_reply_to"
+msgstr "OdpoveÄ vývojára na:"
+
+# %1 is the review count, %2 is the nickname or full name of the user.
+#. %1 is the review count, %2 is the nickname or full name of the user.
+#: views/reviews/display.thtml:131
+#, php-format
+msgid "addon_review_others_by_user"
+msgid_plural "addon_review_others_by_user"
+msgstr[0] "Pozrite si ÄalÅ¡iu %1$s recenziu používateľa %2$s k tomuto doplnku."
+msgstr[1] "Pozrite si ÄalÅ¡ie %1$s recenzie používateľa %2$s k tomuto doplnku."
+msgstr[2] "Pozrite si Äalších %1$s recenzií používateľa %2$s k tomuto doplnku."
+
+# %1 is the addon name
+#. %1 is the add-on name
+#: controllers/reviews_controller.php:201
+#: controllers/reviews_controller.php:250
+#: controllers/reviews_controller.php:345
+#: controllers/reviews_controller.php:424
+#, php-format
+msgid "addon_review_pagetitle"
+msgstr "Recenzie doplnku %s"
+
+# %1 is the user, %2 is the (localized) date
+#. %1 is the user, %2 is the (localized) date
+#: views/reviews/display.thtml:160
+#, php-format
+msgid "addon_review_reply_on_x_by_y"
+msgstr "OdpoveÄ od %1$s na %2$s"
+
+#: views/reviews/display.thtml:157
+msgid "addon_review_reply_prefix"
+msgstr "OdpoveÄ vývojára:"
+
+#: views/reviews/review_added.thtml:51
+msgid "addon_review_saved_successfully"
+msgstr "Recenzia úspešne uložená. Ďakujeme!"
+
+#: views/addons/display.thtml:354
+#: views/reviews/display.thtml:72
+msgid "addon_reviewed_by_u_on_d"
+msgstr "%1$s dňa %2$s"
+
+# %1 is the user, %2 is the (localized) date, %3 is the rating
+#. %1 is the user, %2 is the (localized) date, %3 is the rating
+#: views/editors/reviews_queue.thtml:57
+#: views/editors/reviews_queue.thtml:68
+#: views/reviews/add.thtml:63
+#: views/reviews/delete.thtml:54
+#, php-format
+msgid "addon_reviewed_on_x_rated_y"
+msgstr "%1$s dňa %2$s (hodnotenie: %3$s)"
+
+#: views/elements/amo2009/addon_version_detail.thtml:52
+#: views/elements/addon_version_detail.thtml:52
+msgid "addon_version_permalink"
+msgstr "Permanentný odkaz na túto verziu"
+
+# %1 is the current Application name (e.g. Firefox)
+# %2 is the Application's version number
+#. %1 is the current Application name (e.g. Firefox)
+#. %2 is the Application's version number
+#: views/addons/versions.thtml:140
+msgid "addon_versions_getlatestversion"
+msgstr "Posledná verzia kompatibilná s %1$s %2$s"
+
+#: views/addons/display.thtml:447
+msgid "addons_author_addons_submit"
+msgstr "Prejsť"
+
+#: views/elements/amo2009/homepage_addon.thtml:100
+#: views/elements/feature.thtml:95
+msgid "addons_author_tooltip"
+msgstr "Zobraziť profil autora"
+
+# %1 is the name of the Application (eg. Firefox)
+#. %1 is the name of the Application (eg. Firefox)
+#: controllers/addons_controller.php:1296
+msgid "addons_browse_all_themes_title"
+msgstr "Prehľadávať všetky témy :: Doplnky pre %1$s"
+
+#. %s is the name of the category
+#: controllers/addons_controller.php:1016
+#, php-format
+msgid "addons_browse_browse_category"
+msgstr "Prehľadávať %s"
+
+# %1 is the name of the theme category (eg. Modern)
+# %2 is the name of the Application (eg. Firefox)
+#. %1 is the name of the theme category (eg. Modern)
+#. %2 is the name of the Application (eg. Firefox)
+#: controllers/addons_controller.php:664
+msgid "addons_browse_categories_header_theme"
+msgstr "Prehľadávať témy z kategórie %1$s :: Doplnky pre %2$s"
+
+#: views/addons/display.thtml:249
+msgid "addons_display_a_license_what"
+msgstr "ÄŒo je toto?"
+
+#: views/reviews/display.thtml:222
+msgid "addons_display_add_review"
+msgstr "Pridať recenziu"
+
+#: views/addons/display.thtml:294
+msgid "addons_display_advanced_details"
+msgstr "Ďalšie podrobnosti"
+
+#: views/addons/display.thtml:98
+msgid "addons_display_categories"
+msgstr "Kategórie"
+
+#: views/addons/display.thtml:482
+msgid "addons_display_collection_add"
+msgstr "Pridať do kolekcie:"
+
+#: views/addons/display.thtml:491
+msgid "addons_display_collection_add_new"
+msgstr "Nová kolekcia..."
+
+#: views/addons/display.thtml:487
+msgid "addons_display_collection_add_select_one"
+msgstr "Zvoľte kolekciu..."
+
+#: views/addons/display.thtml:493
+msgid "addons_display_collection_add_submit"
+msgstr "Publikovať"
+
+#. %1$s is the add-on name
+#. %2$s is the collection name, linked to the collection's page
+#: views/pages/js_constants.js.thtml:103
+#: views/addons/display.thtml:61
+msgid "addons_display_collection_publish_success"
+msgstr "Doplnok %1$s bol pridaný do kolekcie %2$s."
+
+#: views/addons/display.thtml:483
+msgid "addons_display_collection_whatsthis"
+msgstr "ÄŒo je toto?"
+
+#. %1$s is a number
+#: views/addons/display.thtml:473
+msgid "addons_display_collections_more"
+msgid_plural "addons_display_collections_more"
+msgstr[0] "a ÄalÅ¡ia kolekcia"
+msgstr[1] "a ÄalÅ¡ie %1$s kolekcie"
+msgstr[2] "a Äalších %1$s kolekcií"
+
+#: views/addons/display.thtml:403
+msgid "addons_display_detailed_review"
+msgstr "podrobná recenzia"
+
+#: views/reviews/add.thtml:89
+#: views/reviews/add.thtml:90
+msgid "addons_display_dont_like_it"
+msgstr "NepáÄi sa"
+
+#: views/reviews/display.thtml:220
+msgid "addons_display_edit_review"
+msgstr "Upraviť recenziu"
+
+#: views/addons/display.thtml:132
+msgid "addons_display_has_privacy"
+msgstr "Doplnok obsahuje zásady ochrany súkromia"
+
+#: views/reviews/add.thtml:87
+#: views/reviews/add.thtml:88
+msgid "addons_display_hate_it"
+msgstr "Neznášaný"
+
+#: views/addons/display.thtml:462
+msgid "addons_display_header_collections"
+msgstr "Príbuzné kolekcie"
+
+#: views/addons/display.thtml:297
+msgid "addons_display_header_developer_comments"
+msgstr "Komentáre vývojára"
+
+#: views/addons/display.thtml:230
+msgid "addons_display_header_homepage"
+msgstr "Domovská stránka"
+
+#: views/addons/display.thtml:247
+#: views/addons/versions.thtml:110
+msgid "addons_display_header_license"
+msgstr "Licencia pre zdrojový kód"
+
+#: views/addons/display.thtml:337
+msgid "addons_display_header_reviews"
+msgstr "Recenzie"
+
+#: views/addons/display.thtml:261
+msgid "addons_display_header_support"
+msgstr "Podpora"
+
+#: views/reviews/add.thtml:91
+#: views/reviews/add.thtml:92
+msgid "addons_display_like_it"
+msgstr "PáÄi sa"
+
+#: views/addons/display.thtml:210
+msgid "addons_display_long_description"
+msgstr "Dlhý popis"
+
+#: views/reviews/add.thtml:95
+#: views/reviews/add.thtml:96
+msgid "addons_display_love_it"
+msgstr "Obľúbený"
+
+#: views/addons/display.thtml:178
+msgid "addons_display_more_images"
+msgstr "Ďalšie obrázky"
+
+#: views/addons/display.thtml:465
+msgid "addons_display_nocollections"
+msgstr "Tento doplnok sa zatiaľ nenachádza v žiadnej kolekcii."
+
+# %1$s is either an author's name or a comma separated list of authors. Using
+# the list doesn't make sense in the English plural form so we ignore the
+# variable.
+#. %1$s is either an author's name or a comma separated list of authors. Using
+#. the list doesn't make sense in the English plural form so we ignore the
+#. variable.
+#: views/addons/display.thtml:436
+msgid "addons_display_other_addons_by"
+msgid_plural "addons_display_other_addons_by"
+msgstr[0] "Ďalšie doplnky od %1$s"
+msgstr[1] "Ďalšie doplnky od týchto autorov"
+msgstr[2] "Ďalšie doplnky od týchto autorov"
+
+#. %s is the name of the add-on and the add-on section. Example:
+#. Some Add-on :: Firefox Add-ons
+#. This should not be concatenated in the code and should be fixed.
+#: controllers/addons_controller.php:141
+#: controllers/addons_controller.php:280
+#: controllers/addons_controller.php:1442
+#, php-format
+msgid "addons_display_pagetitle"
+msgstr "%s"
+
+#. %s is an email address
+#: views/addons/display.thtml:286
+#, php-format
+msgid "addons_display_paragraph_supportinfoemail"
+msgstr "Podporu pre tento doplnok poskytuje autor na e-mailovej adrese %s."
+
+#. %$1s is a URL
+#. %$2s is an email address
+#: views/addons/display.thtml:269
+#, php-format
+msgid "addons_display_paragraph_supportinfoemailurl"
+msgstr "Podporu pre tento doplnok poskytuje autor na adresách %$1s alebo %$2s."
+
+#. %s is a URL
+#: views/addons/display.thtml:278
+#, php-format
+msgid "addons_display_paragraph_supportinfourl"
+msgstr "Podporu pre tento doplnok poskytuje autor na adrese %s."
+
+#: views/addons/display.thtml:383
+msgid "addons_display_rate_it"
+msgstr "Hodnotenie"
+
+#: views/reviews/add.thtml:93
+#: views/reviews/add.thtml:94
+msgid "addons_display_really_like_it"
+msgstr "Naozaj pekný"
+
+#: views/addons/display.thtml:410
+msgid "addons_display_review_etiquette"
+msgstr "Prosím, do recenzií nepíšte záznamy o chybách. Nesprístupňujeme vašu e-mailovú adresu autorom rozšírení a tí vás môžu chcieť kontaktovať, aby ste im pomohli opraviť chyby."
+
+# %1 is the review guidelines link
+#. %1 is the review guidelines link
+#: views/addons/display.thtml:417
+msgid "addons_display_review_guidelines_link"
+msgstr "<a href=\"%s\">Pravidlá pre pridávanie recenzií</a>"
+
+# %1 is the support section link
+#. %1 is the support section link
+#: views/addons/display.thtml:414
+msgid "addons_display_review_see_support"
+msgstr "Informácie o asistencii k tomuto doplnku nájdete v <a href=\"%1$s\">sekcii podpory</a>."
+
+#: views/addons/display.thtml:404
+msgid "addons_display_review_submit"
+msgstr "Uložiť"
+
+#: views/addons/display.thtml:430
+#, php-format
+msgid "addons_display_see_all_addons"
+msgstr "Zobraziť všetky doplnky z kategórie %1$s"
+
+# %1 is the number of reviews
+#. %1 is the number of reviews
+#: views/addons/display.thtml:364
+#, php-format
+msgid "addons_display_see_all_reviews"
+msgstr "Zobraziť všetky recenzie (%1$s)"
+
+#: views/addons/display.thtml:219
+msgid "addons_display_see_all_versions"
+msgstr "Zobraziť všetky verzie"
+
+#: views/addons/display.thtml:321
+#: views/addons/versions.thtml:117
+msgid "addons_display_view_source"
+msgstr "Zobraziť zdroj"
+
+#: views/addons/display.thtml:324
+msgid "addons_display_view_stats"
+msgstr "Zobraziť štatistiku"
+
+#: views/addons/display.thtml:376
+msgid "addons_display_what_do_you_think"
+msgstr "Čo si myslíte?"
+
+#: views/elements/app_compatibility.thtml:49
+msgid "addons_display_workswith"
+msgstr "UrÄené pre:"
+
+#: views/addons/home.thtml:112
+msgid "addons_home_browse_new"
+msgstr "Nedávno pridané"
+
+#: views/addons/home.thtml:110
+msgid "addons_home_browse_popular"
+msgstr "Populárne"
+
+#: views/addons/home.thtml:108
+msgid "addons_home_browse_recommended"
+msgstr "OdporúÄané"
+
+#: views/addons/home.thtml:127
+#: views/addons/home.thtml:134
+#: views/addons/home.thtml:141
+#: views/addons/home.thtml:148
+msgid "addons_home_browse_subscribe"
+msgstr "Odoberať"
+
+#: views/addons/home.thtml:101
+msgid "addons_home_browse_title"
+msgstr "Prehľadávanie doplnkov"
+
+#: views/addons/home.thtml:114
+msgid "addons_home_browse_updated"
+msgstr "Aktualizované"
+
+#: views/elements/amo2009/homepage_addon.thtml:100
+#: views/elements/addon_discussionheader.thtml:83
+#: views/elements/addon_listitem.thtml:109
+#: views/elements/feature.thtml:95
+#: views/addons/category_landing.thtml:66
+#: views/addons/policy.thtml:57
+#: views/addons/display.thtml:70
+#: views/addons/home.thtml:178
+msgid "addons_home_by"
+msgstr "Autor:"
+
+#: views/addons/home.thtml:169
+msgid "addons_home_collection_popular_title"
+msgstr "Populárne kolekcie"
+
+#: views/elements/amo2009/categories.thtml:69
+#: views/addons/home.thtml:160
+msgid "addons_home_collections"
+msgstr "Kolekcie"
+
+#. %1$s is the count of addons in a collection
+#: views/elements/amo2009/collection_listing_item.thtml:51
+#: views/addons/home.thtml:185
+msgid "addons_home_collections_addon_count"
+msgid_plural "addons_home_collections_addon_count"
+msgstr[0] "<strong>%1$s</strong> doplnok"
+msgstr[1] "<strong>%1$s</strong> doplnky"
+msgstr[2] "<strong>%1$s</strong> doplnkov"
+
+#: views/addons/home.thtml:196
+msgid "addons_home_collections_all"
+msgstr "Zobraziť všetky kolekcie"
+
+#: views/addons/home.thtml:162
+msgid "addons_home_collections_intro"
+msgstr "Kolekcie sú spôsob, ako môžete kategorizovať, triediť, miešať, zoskupovať a spájať doplnky. Prihláste sa k odberu kolekcie vytvorenej niekým iným alebo si vytvorte svoju vlastnú."
+
+#. %1$s is the count of subscribers for a collection
+#: views/elements/amo2009/collection_listing_item.thtml:58
+#: views/collections/detail.thtml:96
+#: views/addons/home.thtml:189
+msgid "addons_home_collections_subscribers"
+msgid_plural "addons_home_collections_subscribers"
+msgstr[0] "<strong>%1$s</strong> odberateľ"
+msgstr[1] "<strong>%1$s</strong> odberatelia"
+msgstr[2] "<strong>%1$s</strong> odberateľov"
+
+#: views/addons/searchengines.thtml:54
+#: views/addons/themes_landing.thtml:49
+msgid "addons_home_feature_head"
+msgstr "OdporúÄame"
+
+#: controllers/search_controller.php:218
+#: controllers/addons_controller.php:176
+#: controllers/addons_controller.php:428
+#: controllers/addons_controller.php:671
+#: controllers/addons_controller.php:871
+#: controllers/addons_controller.php:1103
+#: controllers/addons_controller.php:1242
+#: controllers/addons_controller.php:1298
+#, php-format
+msgid "addons_home_header_details"
+msgstr "Doplnky rozširujú %1$s a umožňujú ho prispôsobiť. Poobzerajte sa tu a prispôsobte si %1$s podľa svojich potrieb."
+
+#. %1$s is the HTML collection name link.
+#: views/elements/amo2009/teaser_collections.thtml:107
+msgid "addons_home_introduction_collection_link"
+msgstr "Ako tieto? Ďalšie doplnky nájdete v kolekcii %1$s."
+
+#: views/elements/amo2009/teaser_collections.thtml:60
+msgid "addons_home_introduction_extras"
+msgstr "<strong>Viac ako 5000 doplnkov</strong>, pomocou ktorých si môžete prispôsobiť a rozšíriť Firefox podľa vašich predstáv."
+
+#: views/elements/amo2009/teaser_collections.thtml:55
+msgid "addons_home_introduction_header"
+msgstr "Čo sú doplnky?"
+
+#: views/elements/amo2009/teaser_collections.thtml:72
+msgid "addons_home_introduction_install"
+msgstr "<strong>Jednoduchá inštalácia</strong> a aktualizácia."
+
+#: views/elements/amo2009/teaser_collections.thtml:45
+msgid "addons_home_introduction_name"
+msgstr "Úvod"
+
+#: views/elements/amo2009/teaser_collections.thtml:66
+msgid "addons_home_introduction_themes"
+msgstr "Panely s nástrojmi, témy a poskytovatelia vyhľadávania, ktorí <strong>vám pomáhajú vykonávať bežné úlohy.</strong>"
+
+#: views/addons/home.thtml:161
+msgid "addons_home_new_indicator"
+msgstr "NOVÉ!"
+
+#: views/elements/app_chooser.thtml:48
+#: views/layouts/amo2009.thtml:257
+msgid "addons_home_other_applications"
+msgstr "Ďalšie programy"
+
+#. %1$s is the application the user is browsing. Examples: Thunderbird, Firefox,
+#. Sunbird
+#: views/pages/collector_faq.thtml:49
+#: views/pages/collector_firstrun.thtml:42
+#: views/pages/collector.thtml:46
+#: views/pages/collector_features.thtml:54
+#: controllers/developers_controller.php:87
+#: controllers/compatibility_controller.php:72
+#: controllers/components/simple_acl.php:81
+#: controllers/components/amo.php:607
+#: controllers/statistics_controller.php:60
+#: controllers/statistics_controller.php:240
+#: controllers/previews_controller.php:67
+#: controllers/users_controller.php:90
+#: controllers/users_controller.php:223
+#: controllers/users_controller.php:330
+#: controllers/users_controller.php:414
+#: controllers/users_controller.php:708
+#: controllers/users_controller.php:723
+#: controllers/reviews_controller.php:204
+#: controllers/reviews_controller.php:251
+#: controllers/reviews_controller.php:346
+#: controllers/reviews_controller.php:425
+#: controllers/search_controller.php:185
+#: controllers/search_controller.php:297
+#: controllers/search_controller.php:301
+#: controllers/addons_controller.php:147
+#: controllers/addons_controller.php:280
+#: controllers/addons_controller.php:370
+#: controllers/addons_controller.php:667
+#: controllers/addons_controller.php:874
+#: controllers/addons_controller.php:1019
+#: controllers/addons_controller.php:1034
+#: controllers/addons_controller.php:1101
+#: controllers/addons_controller.php:1121
+#: controllers/addons_controller.php:1240
+#: controllers/addons_controller.php:1357
+#: controllers/addons_controller.php:1364
+#: controllers/addons_controller.php:1442
+#: controllers/addons_controller.php:1477
+#: controllers/addons_controller.php:1538
+#: controllers/addons_controller.php:1543
+#: controllers/editors_controller.php:64
+#: controllers/pages_controller.php:132
+#: controllers/groups_controller.php:65
+#: controllers/groups_controller.php:71
+#: controllers/groups_controller.php:89
+#: controllers/groups_controller.php:111
+#: controllers/collections_controller.php:57
+#: controllers/collections_controller.php:121
+#: controllers/collections_controller.php:205
+#: controllers/collections_controller.php:365
+#: controllers/collections_controller.php:404
+#: controllers/collections_controller.php:466
+#: controllers/collections_controller.php:538
+#: controllers/collections_controller.php:828
+#: controllers/localizers_controller.php:72
+#, php-format
+msgid "addons_home_pagetitle"
+msgstr "%1$s Add-ons"
+
+#. %1$s is the number of addons downloaded
+#: views/addons/home.thtml:57
+#, php-format
+msgid "addons_home_stats_downloaded"
+msgid_plural "addons_home_stats_downloaded"
+msgstr[0] "<strong>%1$s</strong> <span>prevzatý doplnok</span>"
+msgstr[1] "<strong>%1$s</strong> <span>prevzaté doplnky</span>"
+msgstr[2] "<strong>%1$s</strong> <span>prevzatých doplnkov</span>"
+
+#. %1$s is the number of addons in use
+#: views/addons/home.thtml:63
+#, php-format
+msgid "addons_home_stats_inuse"
+msgid_plural "addons_home_stats_inuse"
+msgstr[0] "<strong>%1$s</strong> <span>používaný doplnok</span>"
+msgstr[1] "<strong>%1$s</strong> <span>používané doplnky</span>"
+msgstr[2] "<strong>%1$s</strong> <span>používaných doplnkov</span>"
+
+#: views/addons/home.thtml:136
+msgid "addons_home_view_all_newest_title"
+msgstr "Zobraziť všetky naposledy pridané doplnky"
+
+#: views/addons/home.thtml:129
+msgid "addons_home_view_all_popular_title"
+msgstr "Zobraziť všetky obľúbené doplnky"
+
+#: views/addons/home.thtml:150
+msgid "addons_home_view_all_recommended_title"
+msgstr "ZobraziÅ¥ vÅ¡etky odporúÄané doplnky"
+
+#: views/addons/home.thtml:143
+msgid "addons_home_view_all_updated_title"
+msgstr "Zobraziť všetky naposledy aktualizované doplnky"
+
+#: views/elements/amo2009/install.thtml:334
+#: views/elements/install.thtml:112
+msgid "addons_install_in_sunbird"
+msgstr "<ol><li>Prevezmite súbor a uložte ho na pevný disk.</li><li>V programe Mozilla Sunbird pomocou ponuky Nástroje otvorte Doplnky.</li><li>Kliknite na tlaÄidlo NainÅ¡talovaÅ¥, vyhľadajte/vyberte prevzatý súbor a kliknite na tlaÄidlo \"OK\".</li></ol>"
+
+#: views/elements/amo2009/install.thtml:333
+#: views/elements/install.thtml:111
+msgid "addons_install_in_sunbird_title"
+msgstr "Ako nainštalovať do Sunbirdu"
+
+#: views/elements/amo2009/install.thtml:331
+#: views/elements/install.thtml:106
+msgid "addons_install_in_thunderbird"
+msgstr "<ol><li>Prevezmite súbor a uložte ho na pevný disk.</li><li>V programe Mozilla Thunderbird pomocou ponuky Nástroje otvorte Doplnky.</li><li>Kliknite na tlaÄidlo NainÅ¡talovaÅ¥, vyhľadajte/vyberte prevzatý súbor a kliknite na tlaÄidlo \"OK\".</li></ol>"
+
+#: views/elements/amo2009/install.thtml:330
+#: views/elements/install.thtml:105
+msgid "addons_install_in_thunderbird_title"
+msgstr "Ako nainštalovať do Thunderbirdu"
+
+#: views/elements/amo2009/addon_list_options.thtml:108
+#: views/elements/addon_list_options.thtml:105
+msgid "addons_options_show_experimental"
+msgstr "Zobraziť experimentálne doplnky"
+
+#: views/elements/amo2009/addon_list_options.thtml:113
+#: views/elements/addon_list_options.thtml:109
+msgid "addons_options_submit"
+msgstr "Prejsť"
+
+#: views/addons/plugins.thtml:63
+#: views/addons/plugins.thtml:73
+#: views/addons/plugins.thtml:83
+#: views/addons/plugins.thtml:93
+#: views/addons/plugins.thtml:103
+#: views/addons/plugins.thtml:116
+#: views/addons/plugins.thtml:126
+msgid "addons_plugins_by"
+msgstr "Od"
+
+#: views/addons/plugins.thtml:107
+msgid "addons_plugins_for_linux"
+msgstr "pre Linux"
+
+#: views/addons/plugins.thtml:108
+#: views/addons/plugins.thtml:131
+msgid "addons_plugins_for_macosx"
+msgstr "pre Mac OS X"
+
+#: views/addons/plugins.thtml:106
+#: views/addons/plugins.thtml:129
+#: views/addons/plugins.thtml:130
+msgid "addons_plugins_for_windows"
+msgstr "pre Windows"
+
+#. %1$s is a URL
+#: views/addons/plugins.thtml:139
+#, php-format
+msgid "addons_plugins_looking_for_more"
+msgstr "Na tejto stránke sú uvedené len najpoužívanejÅ¡ie a najobľúbenejÅ¡ie zásuvné moduly. ÄŽalÅ¡ie informácie o ostatných zásuvných moduloch, ktoré sú k dispozícii pre prehliadaÄe založené na Mozille, nájdete na stránke %1$s."
+
+#: views/addons/plugins.thtml:137
+msgid "addons_plugins_looking_for_plugin"
+msgstr "Hľadáte zásuvný modul, ktorý tu nie je uvedený?"
+
+#: views/addons/plugins.thtml:58
+msgid "addons_plugins_main_description"
+msgstr "Zásuvné moduly pomáhajú prehliadaÄu vykonávaÅ¥ Å¡peciálne funkcie, napríklad zobrazovaÅ¥ Å¡peciálne grafické formáty alebo prehrávaÅ¥ multimediálne súbory. Zásuvné moduly sa trochu líšia od rozšírení, ktoré upravujú existujúce funkcie alebo pridávajú nové."
+
+#. %1$s is the application name. Example: Firefox, Thunderbird, Sunbird
+#: controllers/addons_controller.php:1122
+#, php-format
+msgid "addons_plugins_main_header"
+msgstr "Najpoužívanejšie zásuvné moduly pre %1$s"
+
+#: controllers/components/amo.php:698
+#: controllers/addons_controller.php:1121
+msgid "addons_plugins_pagetitle"
+msgstr "Zásuvné moduly"
+
+#: views/addons/plugins.thtml:68
+#: views/addons/plugins.thtml:78
+#: views/addons/plugins.thtml:88
+#: views/addons/plugins.thtml:98
+#: views/addons/plugins.thtml:110
+#: views/addons/plugins.thtml:121
+#: views/addons/plugins.thtml:133
+msgid "addons_plugins_support_documentation"
+msgstr "Dokumentácia podpory: "
+
+#. %s is the name of the add-on
+#: views/addons/policy.thtml:61
+#, php-format
+msgid "addons_policy_eula_require"
+msgstr "%s vyžaduje, aby ste pred pokraÄovaním v inÅ¡talácii prijali podmienky nasledujúcej LicenÄnej zmluvy koncového používateľa:"
+
+# %1 is the addon name
+#. %1 is the add-on name
+#: controllers/addons_controller.php:1476
+#, php-format
+msgid "addons_previews_pagetitle"
+msgstr "Ukážky pre %s"
+
+#: views/addons/category_landing.thtml:135
+msgid "addons_recently_added"
+msgstr "Naposledy pridané"
+
+#: views/addons/recommended.thtml:51
+#: controllers/addons_controller.php:1365
+msgid "addons_recommended_introduction"
+msgstr "K dispozícii sú tisíce doplnkov, pre každého sa tu nieÄo nájde. Na úvod uvádzame niektoré obľúbené. Príjemnú zábavu!"
+
+#: controllers/addons_controller.php:1357
+#: controllers/addons_controller.php:1364
+msgid "addons_recommended_pagetitle"
+msgstr "OdporúÄané doplnky"
+
+#: controllers/addons_controller.php:1360
+msgid "addons_recommended_title"
+msgstr "OdporúÄané doplnky"
+
+#: views/addons/searchengines.thtml:136
+msgid "addons_searchengines_additional_resources"
+msgstr "Ďalšie zdroje"
+
+# link text devmo
+#. link text devmo
+#: views/addons/searchengines.thtml:141
+msgid "addons_searchengines_devmo_link"
+msgstr "Vývojárske centrum Mozilla"
+
+#: views/pages/js_constants.js.thtml:67
+msgid "addons_searchengines_error_mozilla_browser_required"
+msgstr "PrepáÄte, ak chcete nainÅ¡talovaÅ¥ vyhľadávací modul, musíte maÅ¥ prehliadaÄ založený na Mozille (napríklad Firefox)."
+
+#: views/addons/searchengines.thtml:49
+msgid "addons_searchengines_error_nojavascript"
+msgstr "Na inštaláciu vyhľadávacích modulov je potrebný JavaScript, ale zdá sa, že ho máte zakázaný. Pred inštaláciou dole uvedených vyhľadávacích modulov povoľte JavaScript."
+
+# %1 is "make your own" link
+# %2 is MDC link
+#. %1 is "make your own" link
+#. %2 is MDC link
+#: views/addons/searchengines.thtml:139
+msgid "addons_searchengines_learn_howto"
+msgstr "NauÄte sa %1$s, na stránke %2$s."
+
+# link path to search plugins instructions, relative to devmo
+#. link path to search plugins instructions, relative to devmo
+#: views/addons/searchengines.thtml:140
+msgid "addons_searchengines_makeyourown_href"
+msgstr "/en/docs/Creating_OpenSearch_plugins_for_Firefox"
+
+# link text for "make your own" (opensearch engine)
+#. link text for "make your own" (opensearch engine)
+#: views/addons/searchengines.thtml:140
+msgid "addons_searchengines_makeyourown_link"
+msgstr "vytvoriť svoj vlastný"
+
+# %1 is the link to mycroft.mozdev.org
+#. %1 is the link to mycroft.mozdev.org
+#: views/addons/searchengines.thtml:138
+msgid "addons_searchengines_more"
+msgstr "Ďalšie vyhľadávacie moduly nájdete na stránke %1$s."
+
+# link text to mycroft.mozdev.org
+#. link text to mycroft.mozdev.org
+#: views/addons/searchengines.thtml:138
+msgid "addons_searchengines_mycroft_link"
+msgstr "mycroft.mozdev.org"
+
+#: controllers/addons_controller.php:1100
+#: controllers/addons_controller.php:1110
+msgid "addons_searchengines_pagetitle"
+msgstr "Vyhľadávacie moduly"
+
+#: views/addons/searchengines.thtml:143
+msgid "addons_searchengines_thanks"
+msgstr "Zvláštne poÄakovanie patrí projektu Mycroft za ich prácu na vyhľadávacích moduloch pre Firefox."
+
+#: views/addons/display.thtml:154
+msgid "addons_share_button_text"
+msgstr "Zdieľať"
+
+#: controllers/addons_controller.php:89
+msgid "addons_share_label_delicious"
+msgstr "Pridať do Delicious"
+
+#: controllers/addons_controller.php:77
+msgid "addons_share_label_digg"
+msgstr "Digg this!"
+
+#: controllers/addons_controller.php:83
+msgid "addons_share_label_facebook"
+msgstr "Odoslať na Facebook"
+
+#: controllers/addons_controller.php:101
+msgid "addons_share_label_friendfeed"
+msgstr "Zdieľať na FriendFeed"
+
+#: controllers/addons_controller.php:95
+msgid "addons_share_label_myspace"
+msgstr "Odoslať na MySpace"
+
+#: controllers/components/amo.php:201
+#: controllers/components/amo.php:229
+msgid "addons_status_disabled"
+msgstr "zakázaný"
+
+#: controllers/components/amo.php:191
+#: controllers/components/amo.php:224
+msgid "addons_status_incomplete"
+msgstr "nekompletná verzia"
+
+#: controllers/components/amo.php:197
+#: controllers/components/amo.php:227
+msgid "addons_status_nominated"
+msgstr "v sandboxe, nominovaný na uverejnenie"
+
+#: views/pages/js_constants.js.thtml:80
+#: controllers/components/amo.php:195
+#: controllers/components/amo.php:226
+msgid "addons_status_pending"
+msgstr "v sandboxe, Äakajúci na kontrolu"
+
+#: views/pages/js_constants.js.thtml:78
+#: controllers/components/amo.php:199
+#: controllers/components/amo.php:228
+msgid "addons_status_public"
+msgstr "uverejnený"
+
+#: views/pages/js_constants.js.thtml:79
+#: controllers/components/amo.php:193
+#: controllers/components/amo.php:225
+msgid "addons_status_sandbox"
+msgstr "v sandboxe"
+
+#: controllers/components/amo.php:203
+msgid "addons_status_unknown"
+msgstr "neznámy"
+
+#: views/elements/amo2009/teaser_collections.thtml:91
+#: views/elements/amo2009/homepage_addon.thtml:99
+#: views/elements/feature.thtml:94
+msgid "addons_title_tooltip"
+msgstr "Viac informácií o tomto doplnku"
+
+#: views/addons/category_landing.thtml:151
+msgid "addons_top_downloads"
+msgstr "NajÄastejÅ¡ie preberané"
+
+#: views/addons/category_landing.thtml:165
+msgid "addons_top_rated"
+msgstr "Najlepšie hodnotené"
+
+#: views/addons/versions.thtml:62
+msgid "addons_versions_careful"
+msgstr "Opatrne pri starých verziách"
+
+#: views/addons/versions.thtml:63
+msgid "addons_versions_careful_introduction"
+msgstr "Tieto verzie sú zobrazené len ako odkazy na testovacie úÄely. Vždy by ste mali používaÅ¥ najnovÅ¡iu verziu doplnku."
+
+#: controllers/addons_controller.php:1549
+msgid "addons_versions_history"
+msgstr "História verzií s denníkmi zmien"
+
+#. %1$s is the add-on name
+#: controllers/addons_controller.php:1535
+#, php-format
+msgid "addons_versions_pagetitle"
+msgstr "História verzií %1$s"
+
+#: controllers/groups_controller.php:71
+msgid "admin_group_add_pagetitle"
+msgstr "Pridať skupinu"
+
+#: controllers/groups_controller.php:111
+msgid "admin_group_delete_pagetitle"
+msgstr "Odstrániť skupinu"
+
+#. %s is a number to identify the group
+#: controllers/groups_controller.php:117
+#, php-format
+msgid "admin_group_deleted"
+msgstr "Skupina s identifikáciou %s bola odstránená"
+
+#: controllers/groups_controller.php:89
+msgid "admin_group_edit_pagetitle"
+msgstr "Upraviť skupinu"
+
+#: controllers/groups_controller.php:92
+#: controllers/groups_controller.php:113
+msgid "admin_group_error_invalid_id"
+msgstr "Neplatná identifikácia skupiny"
+
+#: controllers/groups_controller.php:65
+msgid "admin_group_pagetitle"
+msgstr "Administrácia skupiny"
+
+#: controllers/groups_controller.php:77
+#: controllers/groups_controller.php:99
+msgid "admin_group_saved"
+msgstr "Skupina bola uložená"
+
+#: views/elements/amo2009/search.thtml:257
+#: views/elements/search.thtml:239
+msgid "advanced_search_form"
+msgstr "Rozšírené"
+
+#: views/elements/amo2009/search.thtml:126
+#: views/elements/search.thtml:125
+msgid "advanced_search_form_any_time"
+msgstr "Nezáleží"
+
+#: views/elements/amo2009/search.thtml:97
+#: views/elements/amo2009/search.thtml:110
+#: views/elements/search.thtml:96
+#: views/elements/search.thtml:109
+msgid "advanced_search_form_any_type"
+msgstr "Nezáleží"
+
+#: views/elements/amo2009/search.thtml:275
+#: views/elements/search.thtml:254
+msgid "advanced_search_form_any_version"
+msgstr "Nezáleží"
+
+#: views/elements/amo2009/search.thtml:217
+#: views/elements/search.thtml:212
+msgid "advanced_search_form_application"
+msgstr "Aplikácia"
+
+#: views/elements/amo2009/search.thtml:143
+#: views/elements/search.thtml:142
+msgid "advanced_search_form_keyword_match"
+msgstr "Zhoda kľúÄových slov"
+
+#: views/elements/amo2009/search.thtml:251
+#: views/elements/search.thtml:225
+msgid "advanced_search_form_lastupdate"
+msgstr "Aktualizované"
+
+#: views/elements/amo2009/search.thtml:145
+#: views/elements/search.thtml:144
+msgid "advanced_search_form_name"
+msgstr "Meno"
+
+#: views/elements/amo2009/search.thtml:144
+#: views/elements/search.thtml:143
+msgid "advanced_search_form_newest"
+msgstr "Najnovšie"
+
+#: views/elements/amo2009/search.thtml:130
+#: views/elements/search.thtml:129
+msgid "advanced_search_form_past_3_months"
+msgstr "V posledných 3 mesiacoch"
+
+#: views/elements/amo2009/search.thtml:131
+#: views/elements/search.thtml:130
+msgid "advanced_search_form_past_6_months"
+msgstr "V posledných 6 mesiacoch"
+
+#: views/elements/amo2009/search.thtml:127
+#: views/elements/search.thtml:126
+msgid "advanced_search_form_past_day"
+msgstr "Za posledných 24 hodín"
+
+#: views/elements/amo2009/search.thtml:129
+#: views/elements/search.thtml:128
+msgid "advanced_search_form_past_month"
+msgstr "Za posledný mesiac"
+
+#: views/elements/amo2009/search.thtml:128
+#: views/elements/search.thtml:127
+msgid "advanced_search_form_past_week"
+msgstr "Za posledných 7 dní"
+
+#: views/elements/amo2009/search.thtml:132
+#: views/elements/search.thtml:131
+msgid "advanced_search_form_past_year"
+msgstr "Za posledný rok"
+
+#: views/elements/amo2009/search.thtml:239
+#: views/elements/search.thtml:230
+msgid "advanced_search_form_perpage"
+msgstr "Doplnkov na stránku"
+
+#: views/elements/amo2009/search.thtml:243
+#: views/elements/search.thtml:224
+msgid "advanced_search_form_platform"
+msgstr "Platforma"
+
+#: views/elements/amo2009/search.thtml:147
+#: views/elements/search.thtml:146
+msgid "advanced_search_form_popularity"
+msgstr "Popularita"
+
+#: views/elements/amo2009/search.thtml:146
+#: views/elements/search.thtml:145
+msgid "advanced_search_form_rating"
+msgstr "Hodnotenie"
+
+#: views/elements/amo2009/search.thtml:247
+#: views/elements/search.thtml:231
+msgid "advanced_search_form_sortby"
+msgstr "Usporiadať podľa"
+
+#: views/elements/amo2009/search.thtml:227
+#: views/elements/search.thtml:216
+msgid "advanced_search_form_to"
+msgstr "až"
+
+#: views/elements/amo2009/search.thtml:257
+#: views/elements/search.thtml:237
+msgid "advanced_search_form_toggle_tooltip"
+msgstr "Prepnúť rozšírený režim vyhľadávania"
+
+#: views/elements/amo2009/search.thtml:235
+#: views/elements/search.thtml:223
+msgid "advanced_search_form_type"
+msgstr "Typ"
+
+#: views/elements/amo2009/search.thtml:222
+#: views/elements/search.thtml:214
+msgid "advanced_search_form_version"
+msgstr "verzia"
+
+#: views/elements/amo2009/pagination.thtml:42
+msgid "amo2009_pagination_next_page"
+msgstr "Ďalšia"
+
+#: views/elements/amo2009/pagination.thtml:41
+msgid "amo2009_pagination_previous_page"
+msgstr "Predchádzajúca"
+
+#: views/pages/js_constants.js.thtml:96
+msgid "app_compat_ignore_check"
+msgstr "Ignorovať kontrolu verzie"
+
+#: views/pages/js_constants.js.thtml:72
+msgid "app_compat_older_firefox_only"
+msgstr "Tento doplnok je urÄený pre starÅ¡ie verzie Firefoxu"
+
+#. %1$s and %2$s are URLs
+#: views/pages/js_constants.js.thtml:74
+msgid "app_compat_older_version_or_ignore_check"
+msgstr "Môžete skúsiť <a href=\"%1$s\">staršiu verziu</a> alebo <a href=\"#\" onclick=\"%2$s\">ignorovať túto kontrolu</a>."
+
+#. %1$s is a URL
+#: views/pages/js_constants.js.thtml:71
+msgid "app_compat_try_old_version"
+msgstr "<a href=\"%1$s\">Staršia verzia</a> by mohla fungovať"
+
+#. %1$s is a URL
+#. %2$s is a version number. Example: 3.1
+#: views/pages/js_constants.js.thtml:73
+msgid "app_compat_unreleased_version"
+msgstr "Tento doplnok vyžaduje zatiaľ neuvoľnený <a href=\"%1$s\">Firefox %2$s</a>"
+
+#: views/pages/js_constants.js.thtml:70
+msgid "app_compat_update_firefox"
+msgstr "Aby ste mohli používať tento doplnok, musíte <a href=\"http://getfirefox.com\">aktualizovať Firefox</a>"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#. %3$s is a status, like Public.
+#: controllers/components/audit.php:79
+msgid "audit_addon_status"
+msgstr "Používateľ %1$s zmenil stav doplnku %2$s na %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:221
+msgid "audit_admin_default"
+msgstr "Používateľ %1$s vykonal neznámu akciu administrátora '%2$s' pre ID %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:153
+msgid "audit_admin_feature_remove"
+msgstr "Používateľ %1$s odstránil funkciu %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is an application, like Firefox.
+#: controllers/components/audit.php:92
+msgid "audit_application_create"
+msgstr "Používateľ %1$s vytvoril aplikáciu %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is an application, like Firefox.
+#: controllers/components/audit.php:95
+msgid "audit_application_edit"
+msgstr "Používateľ %1$s upravil aplikáciu %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a version number, like 3.5.
+#. %3$s is an application, like Firefox.
+#: controllers/components/audit.php:105
+msgid "audit_appversion_create"
+msgstr "Používateľ %1$s vytvoril verziu %2$s pre %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a version number, like 3.5.
+#. %3$s is an application, like Firefox.
+#: controllers/components/audit.php:108
+msgid "audit_appversion_delete"
+msgstr "Používateľ %1$s odstránil verziu %2$s pre %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a config field, like "awesomeness".
+#. %3$s is a config value, like "off".
+#. %4$s is a config value, like "on".
+#: controllers/components/audit.php:210
+msgid "audit_config"
+msgstr "Používateľ %1$s zmenil konfiguráciu '%2$s' z '%3$s' na '%4$s'"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:258
+msgid "audit_editor_default"
+msgstr "Používateľ %1$s vykonal neznámu akciu editora '%2$s' pre ID %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#: controllers/components/audit.php:236
+msgid "audit_editor_feature_remove"
+msgstr "Používateľ %1$s odstránil doplnok %2$s zo zoznamu odporúÄaných"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#: controllers/components/audit.php:231
+msgid "audit_feature_add"
+msgstr "Používateľ %1$s pridal doplnok %2$s do zoznamu odporúÄaných"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:149
+msgid "audit_feature_edit"
+msgstr "Používateľ %1$s zmenil zoznam odporúÄaných doplnkov pre lokalizáciu %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#: controllers/components/audit.php:241
+msgid "audit_feature_locale_change"
+msgstr "Používateľ %1$s zmenil lokalizácie pre doplnok %2$s na zozname odporúÄaných"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:83
+msgid "audit_file_recalchash"
+msgstr "Používateľ %1$s obnovil hash pre súbor %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>user name</a>
+#. %3$s is <a>group name</a>
+#: controllers/components/audit.php:182
+msgid "audit_group_addmember"
+msgstr "Používateľ %1$s pridal používateľa %2$s do skupiny %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:313
+msgid "audit_group_associated"
+msgstr "Používateľ %1$s sa priradil do skupiny %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:162
+msgid "audit_group_create"
+msgstr "Používateľ %1s vytvoril skupinu %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:170
+msgid "audit_group_delete"
+msgstr "Používateľ %1$s odstránil skupinu %2$s (ID %3$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:165
+msgid "audit_group_edit"
+msgstr "Používateľ %1$s upravil skupinu %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>user name</a>
+#. %3$s is <a>group name</a>
+#: controllers/components/audit.php:188
+msgid "audit_group_removemember"
+msgstr "Používateľ %1$s odstránil používateľa %2$s zo skupiny %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:280
+msgid "audit_l10n_default"
+msgstr "Používateľ %1$s vykonal neznámu akciu '%2$s' pre %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:295
+msgid "audit_modify_locked_group"
+msgstr "Používateľ %1$s sa pokúsil upraviť uzamknutú skupinu %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:299
+msgid "audit_modify_other_locale"
+msgstr "Používateľ %1$s sa pokúsil bez povolenia upraviť preklady pre lokalizáciu %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a platform, like <a>Windows</a>
+#: controllers/components/audit.php:135
+msgid "audit_platform_create"
+msgstr "Používateľ %1$s vytvoril platformu %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a platform, like <a>Windows</a>
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:143
+msgid "audit_platform_delete"
+msgstr "Používateľ %1$s odstránil platformu %2$s (ID %3$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a platform, like <a>Windows</a>
+#: controllers/components/audit.php:138
+msgid "audit_platform_edit"
+msgstr "Používateľ %1$s upravil platformu %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a part of the admin, like 'Site Config'
+#: controllers/components/audit.php:288
+msgid "audit_reauthentication_failure"
+msgstr "Používateľovi %1$s sa nepodarilo autentifikovať sa na prístup k %2$s."
+
+#. %1$s is <a>user name</a>
+#. %2$s is the name of a canned response, like 'Ready for the public'
+#: controllers/components/audit.php:198
+msgid "audit_response_create"
+msgstr "Používateľ %1$s vytvoril odpoveÄ %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is the name of a canned response, like 'Ready for the public'
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:206
+msgid "audit_response_delete"
+msgstr "Používateľ %1$s odstránil odpoveÄ %2$s (ID %3$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is the name of a canned response, like 'Ready for the public'
+#: controllers/components/audit.php:201
+msgid "audit_response_edit"
+msgstr "Používateľ %1$s upravil odpoveÄ %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:245
+msgid "audit_review_approve"
+msgstr "Používateľ %1$s odsúhlasil recenziu %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:250
+#: controllers/components/audit.php:253
+msgid "audit_review_delete"
+msgstr "Používateľ %1$s odstránil recenziu %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:303
+msgid "audit_security_default"
+msgstr "Používateľ %1$s vykonal neznámu akciu zabezpeÄenia '%2$s' pre ID %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a category name, like <a>Search Tools</a>
+#: controllers/components/audit.php:118
+msgid "audit_tag_create"
+msgstr "Používateľ %1$s vytvoril kategóriu %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a category name, like <a>Search Tools</a>
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:126
+msgid "audit_tag_delete"
+msgstr "Používateľ %1$s odstránil kategóriu %2$s (ID %3$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a category name, like <a>Search Tools</a>
+#: controllers/components/audit.php:121
+msgid "audit_tag_edit"
+msgstr "Používateľ %1$s upravil kategóriu %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:266
+msgid "audit_update_applications"
+msgstr "Používateľ %1$s aktualizoval preklady aplikácií (%2$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:277
+msgid "audit_update_blog"
+msgstr "Používateľ %1$s aktualizoval preklady príspevkov blogu (%2$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:274
+msgid "audit_update_platforms"
+msgstr "Používateľ %1$s aktualizoval preklady platforiem (%2$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:270
+msgid "audit_update_tags"
+msgstr "Používateľ %1$s aktualizoval preklady kategórií (%2$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>user name</a>
+#: controllers/components/audit.php:217
+msgid "audit_user_edit"
+msgstr "Používateľ %1$s upravil informácie o používateľovi %2$s"
+
+#: controllers/addons_controller.php:1012
+msgid "browse_addons_name"
+msgstr "Doplnky podľa názvu"
+
+#: controllers/addons_controller.php:1010
+msgid "browse_addons_newest"
+msgstr "Najnovšie doplnky"
+
+#: controllers/addons_controller.php:1008
+msgid "browse_addons_popular"
+msgstr "Populárne doplnky"
+
+#: controllers/addons_controller.php:1011
+msgid "browse_addons_rated"
+msgstr "Doplnky podľa hodnotenia"
+
+#: controllers/addons_controller.php:1009
+msgid "browse_addons_updated"
+msgstr "Naposledy aktualizované doplnky"
+
+#: views/elements/categories.thtml:73
+#: views/elements/categories.thtml:82
+msgid "categories_current_title"
+msgstr "Aktuálna kategória"
+
+#: views/elements/categories.thtml:50
+#: views/elements/amo2009/categories.thtml:43
+#: views/elements/amo2009/categories.thtml:45
+msgid "categories_header"
+msgstr "Kategórie"
+
+#: views/elements/categories.thtml:50
+#: views/elements/amo2009/categories.thtml:41
+msgid "categories_header_title"
+msgstr "Výber kategórie"
+
+# %1 is the category name
+#. %1$s is the category name
+#: views/addons/searchengines.thtml:129
+#, php-format
+msgid "category_extra_see_all"
+msgstr "Zobraziť všetky %1$s"
+
+#. %1$s is a number.
+#: models/collection.php:130
+msgid "collection_description_limit"
+msgstr "Popis by mal obsahovať maximálne %1$s znakov."
+
+#. %1$s is the name of the collection
+#: controllers/collections_controller.php:392
+msgid "collection_detail_rss_title"
+msgstr "Kolekcia %s"
+
+#: controllers/collections_controller.php:1065
+msgid "collection_error_deleting_addon"
+msgstr "Chyba pri odstraňovaní doplnku!"
+
+#: controllers/collections_controller.php:1051
+msgid "collection_error_saving_addon"
+msgstr "Chyba pri ukladaní doplnku!"
+
+#: controllers/collections_controller.php:1080
+msgid "collection_error_saving_comment"
+msgstr "Chyba pri ukladaní komentára!"
+
+#. %1$s is a number.
+#: models/collection.php:122
+msgid "collection_name_limit"
+msgstr "Názov musí obsahovať menej ako %1$s znakov."
+
+#: controllers/collections_controller.php:352
+#: controllers/collections_controller.php:487
+msgid "collection_not_found"
+msgstr "Kolekcia nebola nájdená!"
+
+#. %1$s is the text on the "create collection" button
+#: views/collections/add.thtml:91
+msgid "collections_add_formfield_addons_description"
+msgstr "Ak už viete, ktoré doplnky chcete pridaÅ¥ do vaÅ¡ej kolekcie, zaÄnite písaÅ¥ ich názvy. Ak chcete radÅ¡ej poÄkaÅ¥ a urobiÅ¥ neskôr, kliknite na %1$s."
+
+#: views/collections/add.thtml:90
+msgid "collections_add_formfield_firstaddons"
+msgstr "Vyberte si vaše prvé doplnky"
+
+#: views/collections/add.thtml:48
+msgid "collections_add_header"
+msgstr "Vytvorenie kolekcie"
+
+#: views/collections/add.thtml:97
+msgid "collections_add_header_selectedaddons"
+msgstr "OznaÄené doplnky"
+
+#: views/collections/add.thtml:50
+msgid "collections_add_intro"
+msgstr "Kolekciu vytvoríte jednoducho vyplnením niekoľkých políÄok uvedených nižšie."
+
+#: views/collections/add.thtml:92
+#: views/collections/add.thtml:103
+msgid "collections_add_submit"
+msgstr "Vytvoriť kolekciu"
+
+#: views/pages/collector_faq.thtml:50
+#: views/pages/collector_firstrun.thtml:43
+#: views/pages/collector.thtml:47
+#: views/pages/collector_features.thtml:55
+#: controllers/search_controller.php:302
+#: controllers/collections_controller.php:206
+#: controllers/collections_controller.php:405
+#: controllers/collections_controller.php:467
+#: controllers/collections_controller.php:539
+msgid "collections_breadcrumb"
+msgstr "Kolekcie"
+
+#: views/collections/detail.thtml:185
+msgid "collections_detail_a_learn"
+msgstr "Ďalšie informácie"
+
+#: views/elements/amo2009/collection_add_form.thtml:53
+#: views/elements/amo2009/collections_js_init.thtml:68
+#: views/pages/collector_firstrun.thtml:64
+msgid "collections_detail_button_add"
+msgstr "Pridať medzi Obľúbené"
+
+#: views/elements/amo2009/collection_add_form.thtml:50
+#: views/elements/amo2009/collections_js_init.thtml:71
+msgid "collections_detail_button_remove"
+msgstr "Odstrániť z Obľúbených"
+
+#. %1$s is a URL.
+#. %2$s is a full <a href>.
+#: views/collections/detail.thtml:62
+msgid "collections_detail_created_desc"
+msgstr "<p>Nižšie môžete zobraziÅ¥ vaÅ¡u kolekciu. Ak chcete nastaviÅ¥ prezývku kolekcie, odoslaÅ¥ jej ikonu alebo zmeniÅ¥ niektoré ÄalÅ¡ie nastavenia, navÅ¡tívte stránku <a href='%1$s'>správy kolekcií</a>.</p><p>VaÅ¡a kolekcia je dostupná na adrese: %2$s</p>"
+
+#: views/collections/detail.thtml:61
+msgid "collections_detail_created_msg"
+msgstr "Vaša kolekcia je pripravená!"
+
+#: views/collections/detail.thtml:109
+msgid "collections_detail_header_about"
+msgstr "O tejto kolekcii"
+
+#. %1$s is a number.
+#: views/collections/detail.thtml:126
+msgid "collections_detail_header_count"
+msgid_plural "collections_detail_header_count"
+msgstr[0] "%1$s doplnok v tejto kolekcii"
+msgstr[1] "%1$s doplnky v tejto kolekcii"
+msgstr[2] "%1$s doplnkov v tejto kolekcii"
+
+#: views/collections/detail.thtml:113
+msgid "collections_detail_info_created"
+msgstr "<strong>Autor:</strong> %1$s"
+
+#: views/collections/detail.thtml:117
+msgid "collections_detail_info_updated"
+msgstr "<strong>Aktualizovaná:</strong>"
+
+#: views/elements/amo2009/collections_js_init.thtml:62
+msgid "collections_detail_js_adding"
+msgstr "Pridávanie medzi Obľúbené&hellip;"
+
+#: views/elements/amo2009/collections_js_init.thtml:65
+msgid "collections_detail_js_removing"
+msgstr "Odstraňovanie z Obľúbených&hellip;"
+
+#. %1$s is a URL
+#: views/collections/detail.thtml:90
+msgid "collections_detail_login"
+msgstr "Ak chcete túto kolekciu pridať medzi Obľúbené, musíte sa <a href=\"%1$s\">prihlásiť</a>."
+
+#: views/collections/detail.thtml:104
+msgid "collections_detail_manage"
+msgstr "Správa kolekcie"
+
+#: controllers/collections_controller.php:298
+msgid "collections_detail_sort_date"
+msgstr "dátumu pridania"
+
+#: controllers/collections_controller.php:299
+msgid "collections_detail_sort_name"
+msgstr "názvu"
+
+#: controllers/collections_controller.php:300
+msgid "collections_detail_sort_popularity"
+msgstr "popularity"
+
+#. %1$s is a number.
+#: views/collections/detail.thtml:166
+msgid "collections_detail_weekly_downloads"
+msgid_plural "collections_detail_weekly_downloads"
+msgstr[0] "%1$s prevzatie tento týždeň"
+msgstr[1] "%1$s prevzatia tento týždeň"
+msgstr[2] "%1$s prevzatí tento týždeň"
+
+#: views/collections/edit.thtml:255
+msgid "collections_edit_addons_delete_noscript"
+msgstr "OznaÄené doplnky budú odstránené v okamihu uloženia"
+
+#: views/collections/edit.thtml:247
+msgid "collections_edit_addons_description"
+msgstr "Ak chcete publikovaÅ¥ nové doplnky do tejto kolekcie, zaÄnite zadaním ich názvov sem."
+
+#: views/collections/edit.thtml:248
+msgid "collections_edit_addons_description_noscript"
+msgstr "Ak chcete publikovaÅ¥ nové doplnky do tejto kolekcie, zadajte Äiarkou oddelený zoznam ich identifikátorov (ID)."
+
+#: views/collections/edit.thtml:247
+#: views/collections/edit.thtml:248
+msgid "collections_edit_addons_description_publish_detailspage"
+msgstr "Doplnok môžete pridať do kolekcie aj na jeho stránke."
+
+#. %1$s is the date the add-on was added to the collection
+#. %1$s is the name of the user who added the add-on to the collection
+#: views/collections/edit.thtml:260
+msgid "collections_edit_addons_listitem_added"
+msgstr "Pridané dňa %1$s používateľom %2$s"
+
+#: views/collections/edit.thtml:263
+msgid "collections_edit_addons_listitem_comment_add"
+msgstr "Pridať komentár autora"
+
+#: views/collections/edit.thtml:266
+msgid "collections_edit_addons_listitem_comment_delete"
+msgstr "Odstrániť komentár autora"
+
+#: views/collections/edit.thtml:265
+msgid "collections_edit_addons_listitem_comment_edit"
+msgstr "Upraviť komentár autora"
+
+#: views/collections/edit.thtml:271
+msgid "collections_edit_addons_listitem_comment_note"
+msgstr "Poznámka: komentár sa objaví ako ten napísaný pôvodným autorom s pôvodným dátumom pridania"
+
+#: views/collections/edit.thtml:270
+msgid "collections_edit_addons_listitem_comment_submit"
+msgstr "Uložiť komentár"
+
+#: views/collections/edit.thtml:261
+msgid "collections_edit_addons_listitem_remove"
+msgstr "Odstrániť"
+
+#: views/collections/edit.thtml:250
+msgid "collections_edit_addons_submit"
+msgstr "Pridať do kolekcie"
+
+#: views/collections/edit.thtml:153
+msgid "collections_edit_check_nickname"
+msgstr "Skontrolovať dostupnosť"
+
+#: views/collections/edit.thtml:299
+msgid "collections_edit_confirm_deletecollection"
+msgstr "Ãno, chcem odstrániÅ¥ túto kolekciu."
+
+#. %1$s is the label of the edit form's submit button
+#: views/collections/edit.thtml:300
+msgid "collections_edit_confirm_deletecollection_description"
+msgstr "Skontrolujte políÄko a kliknite na \"%1$s\", Äím odstránite túto kolekciu."
+
+#. %1$s is the "delete" submit button text
+#. %2$s is the title of the "advanced" tab
+#: views/collections/edit.thtml:95
+msgid "collections_edit_delete_upon_submit"
+msgstr "Po kliknutí na \"%1$s\" bude vaÅ¡a kolekcia odstránená. Ak nechcete odstrániÅ¥ vaÅ¡u kolekciu, zruÅ¡te oznaÄenie potvrdzovacieho políÄka na karte \"%2$s\" a pokraÄujte v úpravách vaÅ¡ej kolekcie. Ak opustíte túto stránku bez uloženia zmien, vaÅ¡a kolekcia nebude odstránená."
+
+#: views/collections/edit.thtml:94
+msgid "collections_edit_delete_warning"
+msgstr "Vaša kolekcia bude odstránená!"
+
+#: views/collections/add.thtml:76
+#: views/collections/edit.thtml:144
+msgid "collections_edit_form_error_description"
+msgstr "Musíte zadať popis vašej kolekcie."
+
+#: views/collections/edit.thtml:181
+msgid "collections_edit_form_error_icon"
+msgstr "Pri odosielaní ikony sa vyskytol problém."
+
+#: views/collections/add.thtml:69
+#: views/collections/edit.thtml:130
+msgid "collections_edit_form_error_name"
+msgstr "Musíte zadať názov kolekcie."
+
+#: views/collections/edit.thtml:158
+msgid "collections_edit_form_error_nickname"
+msgstr "Prezývka musí byť unikátna."
+
+#: views/collections/add.thtml:93
+#: views/collections/edit.thtml:249
+msgid "collections_edit_formfield_addons"
+msgstr "Názov doplnku"
+
+#: views/collections/edit.thtml:281
+msgid "collections_edit_formfield_application"
+msgstr "Priradená aplikácia"
+
+#: views/collections/edit.thtml:282
+msgid "collections_edit_formfield_application_description"
+msgstr "Zvoľte aplikácie, ktoré vaša kolekcia podporuje."
+
+#: views/collections/edit.thtml:288
+msgid "collections_edit_formfield_collectiontype"
+msgstr "Typ kolekcie"
+
+#: views/collections/edit.thtml:295
+msgid "collections_edit_formfield_deletecollection"
+msgstr "Odstrániť kolekcie"
+
+#: views/collections/edit.thtml:296
+msgid "collections_edit_formfield_deletecollection_description"
+msgstr "Odstránením kolekcie ju nenávratne vymažete."
+
+#: views/collections/add.thtml:73
+#: views/collections/edit.thtml:140
+msgid "collections_edit_formfield_description"
+msgstr "Popis kolekcie"
+
+#: views/collections/add.thtml:74
+#: views/collections/edit.thtml:141
+msgid "collections_edit_formfield_description_description"
+msgstr "StruÄne popíšte vaÅ¡u kolekciu a typ doplnkov v nej"
+
+#: views/collections/edit.thtml:162
+msgid "collections_edit_formfield_icon"
+msgstr "Ikona"
+
+#: views/collections/edit.thtml:163
+msgid "collections_edit_formfield_icon_description"
+msgstr "Môžete odoslať ikonu vo formáte JPG, GIF alebo PNG, táto bude upravená na veľkosť 32x32 bodov."
+
+#: views/collections/add.thtml:80
+#: views/collections/edit.thtml:189
+msgid "collections_edit_formfield_listed"
+msgstr "Kto môže zobraziť vašu kolekciu?"
+
+#: views/collections/add.thtml:81
+#: views/collections/edit.thtml:190
+msgid "collections_edit_formfield_listed_description"
+msgstr "Predvolene sa kolekcie zobrazujú vo verejnom prieÄinku Kolekcie, takže sú dostupné vÅ¡etkým. Ak chcete obmedziÅ¥ zobrazenie vaÅ¡ich doplnkov len pre urÄitých ľudí, zvoľte túto voľbu nižšie."
+
+#: views/collections/add.thtml:84
+#: views/collections/edit.thtml:193
+msgid "collections_edit_formfield_listed_false"
+msgstr "Len ľudia, ktorých pozvem"
+
+#: views/collections/add.thtml:83
+#: views/collections/edit.thtml:192
+msgid "collections_edit_formfield_listed_true"
+msgstr "Ktokoľvek"
+
+#: views/collections/edit.thtml:223
+msgid "collections_edit_formfield_managers"
+msgstr "Kto môže spravovať moju kolekciu?"
+
+#: views/collections/edit.thtml:224
+msgid "collections_edit_formfield_managers_description"
+msgstr "Títo používatelia môžu publikovaÅ¥ doplnky do vaÅ¡ej kolekcie, spravovaÅ¥ vÅ¡etky doplnky a nastavenia, a umožniÅ¥ to aj Äalším používateľom."
+
+#: views/collections/add.thtml:66
+#: views/collections/edit.thtml:126
+msgid "collections_edit_formfield_name"
+msgstr "Názov kolekcie"
+
+#: views/collections/add.thtml:67
+#: views/collections/edit.thtml:127
+msgid "collections_edit_formfield_name_description"
+msgstr "Zadajte popisný názov kolekcie, napr. \"Michalove obľúbené doplnky pre záložky\""
+
+#: views/collections/edit.thtml:148
+msgid "collections_edit_formfield_nickname"
+msgstr "Prezývka kolekcie"
+
+#: views/collections/edit.thtml:149
+msgid "collections_edit_formfield_nickname_description"
+msgstr "Voliteľne môžete zadať unikátny názov kolekcie:"
+
+#: views/collections/edit.thtml:201
+msgid "collections_edit_formfield_publishers"
+msgstr "Kto môže publikovať doplnky do vašej kolekcie?"
+
+#: views/collections/edit.thtml:202
+msgid "collections_edit_formfield_publishers_description"
+msgstr "Títo používatelia môžu publikovať doplnky do vašej kolekcie a takisto ich odstrániť."
+
+#: views/collections/edit.thtml:210
+#: views/collections/edit.thtml:232
+msgid "collections_edit_formfield_users_add"
+msgstr "Zadajte e-mailovú adresu úÄtu na Firefox Add-ons:"
+
+#: views/collections/edit.thtml:216
+#: views/collections/edit.thtml:238
+msgid "collections_edit_formfield_users_delete_noscript"
+msgstr "OznaÄené úÄty budú odstránené pri uložení"
+
+#: views/collections/edit.thtml:215
+#: views/collections/edit.thtml:237
+msgid "collections_edit_formfield_users_new_noscript"
+msgstr "Zadajte Äiarkami oddelený zoznam e-mailových adries úÄtov na Firefox Add-ons"
+
+#: views/collections/edit.thtml:204
+#: views/collections/edit.thtml:226
+msgid "collections_edit_formfield_users_onlyme"
+msgstr "Len ja"
+
+#: views/collections/edit.thtml:205
+#: views/collections/edit.thtml:227
+msgid "collections_edit_formfield_users_otherusers"
+msgstr "Ja a títo používatelia:"
+
+#: views/collections/edit.thtml:211
+#: views/collections/edit.thtml:233
+msgid "collections_edit_formfield_users_submit"
+msgstr "Pridať"
+
+#. %1$s is the name of the collection
+#: views/collections/edit.thtml:68
+msgid "collections_edit_header"
+msgstr "Spravovať kolekciu %1$s"
+
+#: views/collections/edit.thtml:246
+msgid "collections_edit_header_addons"
+msgstr "Spravovať obsah kolekcie"
+
+#: views/collections/edit.thtml:253
+#: views/collections/edit.thtml:258
+msgid "collections_edit_header_addons_current"
+msgstr "Aktuálne doplnky:"
+
+#: views/collections/edit.thtml:279
+msgid "collections_edit_header_advanced"
+msgstr "Rozšírené nastavenia"
+
+#: views/collections/edit.thtml:186
+msgid "collections_edit_header_permissions"
+msgstr "Správa oprávnení pre kolekciu"
+
+#: views/collections/edit.thtml:170
+msgid "collections_edit_icon_cancel"
+msgstr "Zrušiť"
+
+#: views/collections/edit.thtml:174
+#: views/collections/edit.thtml:179
+msgid "collections_edit_icon_delete"
+msgstr "Odstrániť ikonu"
+
+#: views/collections/edit.thtml:178
+msgid "collections_edit_icon_replace"
+msgstr "Nahradiť ikonu"
+
+#. %1$s is the label of the edit form's submit button
+#: views/collections/edit.thtml:169
+msgid "collections_edit_icon_toberemoved"
+msgstr "Ikona bude odstránená pri kliknutí na \"%1$s\""
+
+#: views/collections/edit.thtml:155
+msgid "collections_edit_nickname_available"
+msgstr "Prezývka dostupná"
+
+#: controllers/collections_controller.php:943
+msgid "collections_edit_nickname_error"
+msgstr "Vaša prezývka obsahovala neplatné znaky a bola opravená. Skúste to znova."
+
+#: views/collections/edit.thtml:156
+msgid "collections_edit_nickname_taken"
+msgstr "Prezývka už existuje"
+
+#. This string is followed by a URL pointing to the collection's view page
+#: views/collections/edit.thtml:75
+msgid "collections_edit_saved_nextstep"
+msgstr "Vaša kolekcia je dostupná na:"
+
+#: views/collections/edit.thtml:74
+msgid "collections_edit_saved_success"
+msgstr "Vaša kolekcia bola úspešne uložená!"
+
+#: views/collections/edit.thtml:169
+#: views/collections/edit.thtml:300
+#: views/collections/edit.thtml:308
+#: views/pages/js_constants.js.thtml:99
+msgid "collections_edit_submit"
+msgstr "Aktualizovať kolekciu"
+
+#: views/collections/edit.thtml:96
+#: views/collections/edit.thtml:297
+#: views/pages/js_constants.js.thtml:100
+msgid "collections_edit_submit_deletecollection"
+msgstr "Odstrániť kolekciu"
+
+#: views/collections/edit.thtml:111
+msgid "collections_edit_tabheader_addons"
+msgstr "Doplnky"
+
+#: views/collections/edit.thtml:97
+#: views/collections/edit.thtml:113
+msgid "collections_edit_tabheader_advanced"
+msgstr "Rozšírené"
+
+#: views/collections/edit.thtml:108
+msgid "collections_edit_tabheader_details"
+msgstr "Názov a podrobnosti"
+
+#: views/collections/edit.thtml:109
+msgid "collections_edit_tabheader_permissions"
+msgstr "Oprávnenia"
+
+#: models/collection_promo.php:53
+msgid "collections_family_tagline"
+msgstr "Dozerajte na vaše deti a kalendár."
+
+#: models/collection_promo.php:53
+msgid "collections_family_title"
+msgstr "Rodina"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:70
+msgid "collections_index_a_check_out"
+msgstr "Pozrite si Add-on Collector"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:52
+msgid "collections_index_a_create"
+msgstr "Vytvorenie kolekcie"
+
+#: views/collections/detail.thtml:139
+#: views/collections/listing.thtml:85
+#: views/search/collections.thtml:84
+msgid "collections_index_button_go"
+msgstr "Prejsť"
+
+#. %1$s is a URL.
+#: controllers/collections_controller.php:182
+msgid "collections_index_filler_favorites"
+msgstr "<p><strong>Zatiaľ nemáte žiadne obľúbené kolekcie.</strong></p> <p>Ku kolekciám, ktoré oznaÄíte ako Obľúbené, môžete pristupovaÅ¥ z tejto stránky a objavia sa aj v rozšírení <a href='%1$s'>Add-on Collector</a>, ak ho máte nainÅ¡talované.</p>"
+
+#. %1$s is a URL.
+#: controllers/collections_controller.php:167
+msgid "collections_index_filler_mine"
+msgstr "<p>Zatiaľ ste nevytvorili žiadne kolekcie. Kolekcie sú jednoduchým spôsobom ako vytvoriť a spravovať vaše obľúbené doplnky. <a href='%1$s'>Vyskúšajte si to</a>!</p>"
+
+#: views/collections/listing.thtml:51
+msgid "collections_index_header_collections"
+msgstr "Kolekcie"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:60
+msgid "collections_index_header_collector"
+msgstr "Rozšírenie Add-on Collector"
+
+#. %1$s is a comma-separated list of author names
+#: views/elements/amo2009/collection_listing_item.thtml:84
+#: views/collections/detail.thtml:151
+msgid "collections_index_header_created"
+msgstr "autor %1$s"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:47
+msgid "collections_index_header_what"
+msgstr "Čo sú kolekcie?"
+
+#: views/collections/detail.thtml:132
+#: views/collections/listing.thtml:78
+#: views/search/collections.thtml:66
+msgid "collections_index_label_sortby"
+msgstr "Usporiadať podľa"
+
+#: controllers/collections_controller.php:130
+msgid "collections_index_li_editors"
+msgstr "Výber editorov"
+
+#: views/collections/subscribe.thtml:64
+#: controllers/collections_controller.php:140
+msgid "collections_index_li_favorites"
+msgstr "Moje obľúbené"
+
+#: controllers/collections_controller.php:138
+msgid "collections_index_li_mine"
+msgstr "Moje kolekcie"
+
+#: controllers/collections_controller.php:132
+msgid "collections_index_li_popular"
+msgstr "Populárne"
+
+#: views/search/collections.thtml:74
+#: controllers/collections_controller.php:81
+msgid "collections_index_option_all"
+msgstr "najpopulárnejÅ¡ie za celý Äas"
+
+#: views/search/collections.thtml:72
+#: controllers/collections_controller.php:78
+msgid "collections_index_option_month"
+msgstr "najpopulárnejšie tento mesiac"
+
+#: views/search/collections.thtml:76
+#: controllers/collections_controller.php:84
+msgid "collections_index_option_newest"
+msgstr "najnovšie"
+
+#: views/search/collections.thtml:70
+#: controllers/collections_controller.php:75
+msgid "collections_index_option_week"
+msgstr "najpopulárnejšie za tento týždeň"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:67
+msgid "collections_index_p_collector"
+msgstr "Existuje nový spôsob správy a vyhľadávania obľúbených doplnkov. Komentujte, zdieľajte a synchronizujte kolekcie, vÅ¡etko priamo z vášho prehliadaÄa"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:48
+msgid "collections_index_p_what_are"
+msgstr "Kolekcie sú skupiny príbuzných doplnkov vytvorené pre jednoduché zdieľanie."
+
+#. %s is a date in the _('date') format
+#: views/elements/collections_interactive_addon.thtml:85
+#, php-format
+msgid "collections_interactive_addon_added"
+msgstr "Pridané %s"
+
+#: models/collection_promo.php:55
+msgid "collections_reference_tagline"
+msgstr "Skúmajte hociÄo online."
+
+#: models/collection_promo.php:55
+msgid "collections_reference_title"
+msgstr "Referencie"
+
+#: models/collection_promo.php:52
+msgid "collections_social_tagline"
+msgstr "Spravujte vašu sociálnu sieť."
+
+#: models/collection_promo.php:52
+msgid "collections_social_title"
+msgstr "Sociálne"
+
+#: views/collections/subscribe.thtml:91
+msgid "collections_subscribe_button_close"
+msgstr "Zavrieť"
+
+#: views/collections/subscribe.thtml:70
+msgid "collections_subscribe_error"
+msgstr "Pri pokuse o pridanie kolekcie medzi Obľúbené sa vyskytla chyba. Nenachádza sa už táto kolekcia medzi vašimi obľúbenými kolekciami?"
+
+#: views/collections/subscribe.thtml:96
+msgid "collections_subscribe_label_bothersome"
+msgstr "Túto správu viac nezobrazovať."
+
+#. %1$s is the collection name
+#: views/collections/subscribe.thtml:60
+msgid "collections_subscribe_success"
+msgstr "Kolekcia %1$s bola pridaná medzi vaše obľúbené kolekcie."
+
+#. %1$s is the link to the "My Favorites" tab on the main collections page
+#. %2$s is the localized title of the "My Favorites" tab
+#. %3$s is the link URL to the collector add-on
+#: views/collections/subscribe.thtml:62
+msgid "collections_subscribe_success_desc"
+msgstr "Túto kolekciu teraz rýchlo nájdete na karte <a href=\"%1$s\">%2$s</a> v prieÄinku kolekcií. Na jednoduchÅ¡iu správu vaÅ¡ich obľúbených kolekcií odporúÄame rozšírenie pre Firefox s názvom <a href=\"%3$s\">Add-on Collector</a>."
+
+#: views/collections/listing.thtml:55
+msgid "collections_success_delete"
+msgstr "Kolekcia bola odstránená."
+
+#: models/collection_promo.php:54
+msgid "collections_travel_tagline"
+msgstr "Naplánujte si obchodné cesty a nezabudnuteľné dovolenky."
+
+#: models/collection_promo.php:54
+msgid "collections_travel_title"
+msgstr "Cestovanie"
+
+#. A collection of add-ons that is automatically built for a user. They are "automatically published" to this collection.
+#: controllers/collections_controller.php:581
+msgid "collections_type_autopublisher"
+msgstr "Automaticky publikované"
+
+#. A collection that has been chosen by an Editor as notable or exceptional
+#: controllers/collections_controller.php:582
+msgid "collections_type_editorspick"
+msgstr "Výber editora"
+
+#: controllers/collections_controller.php:580
+msgid "collections_type_normal"
+msgstr "Normálne"
+
+#: views/collections/subscribe.thtml:84
+msgid "collections_unsubscribe_error"
+msgstr "Pri pokuse o odstránenie obľúbenej kolekcie sa vyskytla chyba. Nachádzala sa táto kolekcia medzi Obľúbenými?"
+
+#. %1$s is the collection name
+#: views/collections/subscribe.thtml:78
+msgid "collections_unsubscribe_success"
+msgstr "Kolekcia %1$s bola odstránená z vašich obľúbených kolekcií."
+
+#: models/collection_promo.php:56
+msgid "collections_webdev_tagline"
+msgstr "Vytvorte perfektnú stránku."
+
+#: models/collection_promo.php:56
+msgid "collections_webdev_title"
+msgstr "Vývoj webu"
+
+#: views/elements/amo2009/collections_sidebar_whatare.thtml:40
+msgid "collections_whatare_header"
+msgstr "Čo sú kolekcie?"
+
+#: views/elements/amo2009/collections_sidebar_whatare.thtml:45
+msgid "collections_whatare_learnmore"
+msgstr "Často kladené otázky"
+
+#: views/elements/amo2009/collections_sidebar_whatare.thtml:44
+msgid "collections_whatare_text"
+msgstr "Existuje nový spôsob správy a vyhľadávania obľúbených doplnkov. Komentujte, zdieľajte a synchronizujte kolekcie, vÅ¡etko priamo z vášho prehliadaÄa."
+
+#: views/pages/collector_faq.thtml:61
+#: views/pages/collector_features.thtml:67
+msgid "collector_features_a_home"
+msgstr "Domovská stránka rozšírenia Add-on Collector"
+
+#: views/elements/amo2009/collector_sidebar_download.thtml:46
+msgid "collector_features_heading_download"
+msgstr "Prevziať Add-on Collector:"
+
+#: views/elements/amo2009/collector_sidebar_download.thtml:43
+#: views/pages/collector_firstrun.thtml:116
+#: views/pages/collector.thtml:69
+msgid "collector_features_img_logo"
+msgstr "Logo rozšírenia Add-on Collector"
+
+#: views/compatibility/dashboard.thtml:49
+#: controllers/compatibility_controller.php:72
+msgid "compatibility_dashboard_center_header"
+msgstr "Centrum kompatibility doplnku"
+
+#. %1$s is the name of an application and a version. Example: Firefox 3.0
+#. %2$s is the name of an application. Example: Firefox
+#: views/compatibility/dashboard.thtml:50
+msgid "compatibility_dashboard_intro"
+msgstr "BuÄte pripravený na novú verziu aplikácie %1$s pomocou nástrojov a informácií, ktoré sú pre komunitu %2$s Add-ons dostupné nižšie."
+
+#: views/compatibility/dashboard.thtml:103
+msgid "compatibility_dashboard_loading"
+msgstr "NaÄítavajú sa údaje…"
+
+#: views/compatibility/dashboard.thtml:45
+msgid "compatibility_dashboard_main_link"
+msgstr "Naspäť na hlavnú stránku"
+
+#: views/compatibility/dashboard.thtml:100
+#: views/compatibility/report.thtml:43
+msgid "compatibility_dashboard_report"
+msgstr "Správa o kompatibilite doplnkov"
+
+#: views/compatibility/dashboard.thtml:53
+#: views/compatibility/dashboard.thtml:110
+#: views/compatibility/developers.thtml:43
+msgid "compatibility_developer_info"
+msgstr "Informácie pre vývojárov doplnkov"
+
+#: views/compatibility/developers.thtml:66
+msgid "compatibility_developers_adjust_maxversion"
+msgstr "Zvýšiť hodnotu maxVersion bez odoslania novej verzie"
+
+#: views/compatibility/dashboard.thtml:124
+msgid "compatibility_developers_check_status"
+msgstr "Skontrolovať stav mojich doplnkov"
+
+#. %1$s is a URL
+#. %2$s is an application and version. Example: Firefox 3.0
+#: views/compatibility/dashboard.thtml:126
+msgid "compatibility_developers_login_first"
+msgstr "Ak máte na Mozilla Add-ons umiestnené svoje doplnky, <a href=\"%1$s\">prihláste sa</a> a pozrite si stav svojich doplnkov pre %2$s."
+
+#: views/compatibility/dashboard.thtml:114
+msgid "compatibility_developers_mdclogo_alt"
+msgstr "Logo Vývojárske centrum Mozilly"
+
+#: views/compatibility/developers.thtml:73
+msgid "compatibility_developers_no_addons"
+msgstr "Na Mozilla Add-ons nemáte umiestnené žiadne doplnky."
+
+#: views/compatibility/dashboard.thtml:133
+#: views/compatibility/developers.thtml:55
+msgid "compatibility_developers_results"
+msgstr "Výsledky kontroly stavu doplnku"
+
+#: views/compatibility/dashboard.thtml:137
+msgid "compatibility_developers_retrieving"
+msgstr "Zisťuje sa stav vašich doplnkov…"
+
+#. %1$s is a number
+#. %2$s is an application name
+#. %3$s is a number.
+#. Full example: 50 Firefox users (10% of total)
+#: views/compatibility/developers.thtml:65
+msgid "compatibility_developers_user_count"
+msgstr "%1$s používateľov v aplikácii %2$s (%3$s&#37; zo všetkých)"
+
+#: views/compatibility/report.thtml:45
+msgid "compatibility_report_detail_intro"
+msgstr "Doplnky uvedené nižšie tvoria podľa údajov Mozilly 95% všetkých používaných doplnkov, usporiadané sú podľa používanosti."
+
+#: views/compatibility/dashboard.thtml:94
+msgid "compatibility_report_detailed_link"
+msgstr "Zobraziť podrobnú správu"
+
+#. %1$s and %2$s are numbers
+#. %3$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:65
+msgid "compatibility_report_intro"
+msgstr "Z %1$s doplnkov, ktoré podľa údajov Mozilly tvoria 95&#37; všetkých používaných doplnkov, je <b>%2$s&#37;</b> kompatibilných s najnovšími zostaveniami aplikácie %3$s."
+
+#: views/compatibility/dashboard.thtml:81
+msgid "compatibility_report_legend_alpha"
+msgstr "Verzie alpha"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:81
+msgid "compatibility_report_legend_alpha_description"
+msgstr "Doplnky kompatibilné s verziou alpha aplikácie %1$s"
+
+#: views/compatibility/dashboard.thtml:85
+msgid "compatibility_report_legend_beta"
+msgstr "Verzia beta"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:85
+msgid "compatibility_report_legend_beta_description"
+msgstr "Doplnky kompatibilné s verziou beta/RC aplikácie %1$s"
+
+#: views/compatibility/dashboard.thtml:89
+msgid "compatibility_report_legend_latest"
+msgstr "Najnovšia verzia"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:89
+msgid "compatibility_report_legend_latest_description"
+msgstr "Doplnky kompatibilné s najnovšou verziou aplikácie %1$s"
+
+#: views/compatibility/dashboard.thtml:77
+msgid "compatibility_report_legend_other"
+msgstr "Iné verzie"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:77
+msgid "compatibility_report_legend_other_description"
+msgstr "Doplnok nie je kompatibilný zo žiadnou verziou aplikácie %1$s"
+
+#: views/compatibility/dashboard.thtml:62
+msgid "compatibility_report_title"
+msgstr "Správa o kompatibilite doplnkov"
+
+#: views/compatibility/dashboard.thtml:54
+#: views/compatibility/dashboard.thtml:144
+#: views/compatibility/users.thtml:42
+msgid "compatibility_user_info"
+msgstr "Informácie pre používateľov doplnkov"
+
+#: views/compatibility/dashboard.thtml:52
+msgid "compatibility_view_report"
+msgstr "Zobraziť správu o kompatibilite"
+
+#. %s is a URL
+#: views/pages/credits.thtml:142
+#, php-format
+msgid "credits_contributing"
+msgstr "Informácie o prispievateľoch nájdete na našej %s."
+
+#: views/pages/credits.thtml:142
+msgid "credits_contributing_wikipage"
+msgstr "stránke Wiki"
+
+#: views/pages/credits.thtml:99
+msgid "credits_intro"
+msgstr "Mozilla Äakuje nasledujúcim ľuÄom za ich prácu na projekte addons.mozilla.org:"
+
+#: views/pages/credits.thtml:103
+msgid "credits_section_developers"
+msgstr "Vývojári"
+
+#: views/pages/credits.thtml:115
+msgid "credits_section_editors"
+msgstr "Editori"
+
+#: views/pages/credits.thtml:109
+msgid "credits_section_localizers"
+msgstr "Lokalizátori"
+
+#: views/pages/credits.thtml:121
+msgid "credits_section_other_contributors"
+msgstr "Ostatní prispievatelia"
+
+#: views/pages/credits.thtml:127
+msgid "credits_section_past_developers"
+msgstr "Najnovší vývojári"
+
+#: views/pages/credits.thtml:133
+msgid "credits_section_software"
+msgstr "Softvér a obrázky"
+
+#: views/pages/credits.thtml:136
+msgid "credits_software_famfamfam"
+msgstr "Niektoré použité ikony pochádzajú zo <a href=\"http://www.famfamfam.com/lab/icons/silk/\">sady ikon famfamfam Silk</a>, uvoľnené sú pod licenciou <a href=\"http://creativecommons.org/licenses/by/2.5/\">Creative Commons Attribution 2.5</a>."
+
+#: views/pages/credits.thtml:137
+msgid "credits_software_timeplot"
+msgstr "Niektoré podstránky používajú prvky <a href=\"http://www.simile-widgets.org/timeplot/\">Timeplot</a> uvádzané pod licenciou <a href=\"http://simile.mit.edu/license.html\">BSD License</a>."
+
+# date format string as used in PHP's strftime():
+# http://php.net/strftime
+#. date format string as used in PHP's strftime():
+#. http://php.net/strftime
+#: views/elements/collections_interactive_addon.thtml:85
+#: views/elements/amo2009/addon_version_detail.thtml:53
+#: views/elements/amo2009/homepage_addon.thtml:115
+#: views/elements/addon_version_detail.thtml:54
+#: views/elements/addon_listitem.thtml:124
+#: views/elements/feature.thtml:106
+#: views/collections/detail.thtml:118
+#: views/collections/edit.thtml:325
+#: views/users/info.thtml:76
+#: views/editors/reviews_queue.thtml:57
+#: views/editors/reviews_queue.thtml:68
+#: views/developers/dashboard.thtml:65
+#: views/developers/versions_edit.thtml:208
+#: views/developers/versions.thtml:67
+#: views/search/rss/index.thtml:5
+#: views/addons/rss/versions.thtml:42
+#: views/addons/display.thtml:104
+#: views/addons/display.thtml:356
+#: views/addons/browse_thumbs.thtml:75
+#: views/reviews/add.thtml:63
+#: views/reviews/display.thtml:74
+#: views/reviews/display.thtml:160
+#: views/reviews/delete.thtml:54
+#: controllers/statistics_controller.php:244
+#: controllers/collections_controller.php:1047
+msgid "date"
+msgstr "%e. %B %Y"
+
+# date and time format string (strftime)
+#. date and time format string (strftime)
+#. http://php.net/strftime
+#: views/elements/addon_version_detail.thtml:53
+#: views/developers/discuss.thtml:52
+#: views/developers/discuss.thtml:62
+#: views/admin/addons_status.thtml:57
+msgid "datetime"
+msgstr "%e. %B %Y, %H:%M"
+
+#: views/elements/developers/actionbar.thtml:47
+msgid "devcp_actionbar_link_details"
+msgstr "Podrobné informácie"
+
+#: views/elements/developers/actionbar.thtml:42
+#: views/elements/developers/actionbar.thtml:50
+#: views/developers/dashboard.thtml:64
+msgid "devcp_actionbar_link_edit"
+msgstr "Upraviť doplnok"
+
+#: views/elements/developers/actionbar.thtml:51
+msgid "devcp_actionbar_link_newversion"
+msgstr "Odoslať novú verziu"
+
+#: views/elements/developers/actionbar.thtml:44
+#: views/elements/developers/actionbar.thtml:49
+#: views/developers/dashboard.thtml:73
+msgid "devcp_actionbar_link_stats"
+msgstr "Å tatistika"
+
+#. %1$s is a filename, e.g. "foo.txt"
+#. %2$s is the extension, e.g. ".txt"
+#. %3$s is a list of valid extensions, like ".png, .jpg, .gif"
+#: controllers/developers_controller.php:1361
+msgid "devcp_add_previews_extension_error"
+msgstr "Súbor %1$s má neplatnú koncovku (%2$s). Povolené koncovky: %3$s"
+
+#. %s is the filename.
+#: controllers/developers_controller.php:1394
+msgid "devcp_add_previews_save_error"
+msgstr "Súbor %s nemohol byť uložený do databázy. Skúste to znova."
+
+#. %1$s is the preview ID number, %2$s is the filename.
+#: controllers/developers_controller.php:1389
+msgid "devcp_add_previews_success_replace"
+msgstr "Ukážka %1$s bola úspešne nahradená súborom %2$s."
+
+#. %s is the filename.
+#: controllers/developers_controller.php:1391
+msgid "devcp_add_previews_success_upload"
+msgstr "Súbor %s bol úspešne odoslaný. Môžete zadať jeho popis."
+
+#: controllers/components/developers.php:1163
+msgid "devcp_additem_addontype_autodetect"
+msgstr "(zistiť automaticky)"
+
+#: views/elements/developers/additem.thtml:76
+msgid "devcp_additem_linktitle_opensin_newwindow"
+msgstr "Otvára v novom okne"
+
+#: views/elements/developers/additem.thtml:41
+msgid "devcp_additem_sidebar_title"
+msgstr "Odoslať doplnok"
+
+#: views/elements/developers/additem.thtml:53
+msgid "devcp_additem_step0_newlink"
+msgstr "Vývojárska zmluva"
+
+#: views/elements/developers/additem.thtml:46
+msgid "devcp_additem_step1_link"
+msgstr "1. krok: Odoslanie"
+
+#: views/elements/developers/additem.thtml:47
+msgid "devcp_additem_step2_link"
+msgstr "2. krok: Podrobnosti doplnku"
+
+#: views/elements/developers/additem.thtml:48
+msgid "devcp_additem_step3_link"
+msgstr "3. krok: Podrobnosti verzie"
+
+#: views/elements/developers/additem.thtml:49
+msgid "devcp_additem_step4_link"
+msgstr "4. krok: Lokalizácia"
+
+#: views/elements/developers/additem.thtml:50
+msgid "devcp_additem_step5_link"
+msgstr "5. krok: Úspešné"
+
+#: views/elements/developers/additem.thtml:76
+msgid "devcp_additem_submissionhelp_link"
+msgstr "Pomocník k odoslaniu"
+
+#: controllers/previews_controller.php:168
+#: controllers/previews_controller.php:277
+msgid "devcp_addon_field_preview_caption_displaytitle"
+msgstr "Nadpis ukážky"
+
+#: views/developers/addon_status.thtml:177
+msgid "devcp_addon_status_action_activate"
+msgstr "Aktivovať"
+
+#: views/developers/addon_status.thtml:178
+msgid "devcp_addon_status_action_activate_description"
+msgstr "Nastavením doplnku ako aktívny ho sprístupníte vo všetkých verejne dostupných zoznamoch a povolíte poskytovanie aktualizácií."
+
+#: views/developers/addon_status.thtml:135
+msgid "devcp_addon_status_action_complete"
+msgstr "DokonÄiÅ¥ doplnok"
+
+#: views/developers/addon_status.thtml:136
+msgid "devcp_addon_status_action_complete_description"
+msgstr "DokonÄite váš doplnok a presuňte ho do Sandboxu"
+
+#: views/developers/addon_status.thtml:181
+msgid "devcp_addon_status_action_deactivate"
+msgstr "Nastaviť ako neaktívny"
+
+#: views/developers/addon_status.thtml:182
+msgid "devcp_addon_status_action_deactivate_description"
+msgstr "Nastavením doplnku ako neaktívny ho skryjete zo všetkých verejne dostupných zoznamov a zastavíte poskytovanie aktualizácií."
+
+#: views/developers/addon_status.thtml:143
+msgid "devcp_addon_status_action_move"
+msgstr "Presunúť do Sandboxu"
+
+#: views/developers/addon_status.thtml:144
+msgid "devcp_addon_status_action_move_description"
+msgstr "Presunie váš doplnok späť do Sandboxu. Akciu je možné vrátiť späť."
+
+#: views/developers/addon_status.thtml:139
+msgid "devcp_addon_status_action_nominate"
+msgstr "Nominovať na verejný"
+
+#: views/developers/addon_status.thtml:140
+msgid "devcp_addon_status_action_nominate_description"
+msgstr "Nominovať doplnok na uverejnenie"
+
+#: views/developers/addon_status.thtml:147
+msgid "devcp_addon_status_action_public"
+msgstr "Uverejniť"
+
+#: views/developers/addon_status.thtml:148
+msgid "devcp_addon_status_action_public_description"
+msgstr "Nastaví váš doplnok ako verejný."
+
+#: views/developers/addon_status.thtml:169
+msgid "devcp_addon_status_active"
+msgstr "Váš doplnok je <span class=\"inactive-0\">aktívny</span>. To znamená, že doplnok sa zobrazuje vo všetkých verejne dostupných zoznamoch."
+
+#: views/developers/addon_status.thtml:111
+msgid "devcp_addon_status_completion_disabled"
+msgstr "Pred dokonÄením doplnku a jeho presunutím do <span class=\"status-1\">Sandboxu</span> musíte splniÅ¥ vyÅ¡Å¡ie uvedené kritériá."
+
+#: views/developers/addon_status.thtml:108
+msgid "devcp_addon_status_completion_enabled"
+msgstr "Teraz môžete dokonÄiÅ¥ váš doplnok a presunúť ho do <span class=\"status-1\">Sandboxu</span> kliknutím na nižšie uvedené tlaÄidlo."
+
+#: views/developers/addon_status.thtml:102
+msgid "devcp_addon_status_criteria_category"
+msgstr "Zvoľte aspoň jednu kategóriu"
+
+#: views/developers/addon_status.thtml:101
+msgid "devcp_addon_status_criteria_description"
+msgstr "Vyžadovaný popis doplnku"
+
+#: views/developers/addon_status.thtml:99
+msgid "devcp_addon_status_criteria_name"
+msgstr "Vyžadovaný názov doplnku"
+
+#: views/developers/addon_status.thtml:120
+msgid "devcp_addon_status_criteria_prerelease"
+msgstr "Doplnok nie je oznaÄený ako pred-vydanie."
+
+#: views/developers/addon_status.thtml:119
+msgid "devcp_addon_status_criteria_preview"
+msgstr "Pre rozšírenia a témy sa vyžaduje aspoň jeden obrázok s ukážkou."
+
+#: views/developers/addon_status.thtml:100
+msgid "devcp_addon_status_criteria_summary"
+msgstr "Vyžadovaný súhrn doplnku"
+
+#. %s is the status in a span, e.g. "<span>_('Public')</span>".
+#: views/developers/addon_status.thtml:58
+msgid "devcp_addon_status_header"
+msgstr "Stav doplnku: %s"
+
+#: views/developers/addon_status.thtml:152
+#: views/developers/addon_status.thtml:173
+msgid "devcp_addon_status_header_actions"
+msgstr "Dostupné akcie"
+
+#: views/developers/addon_status.thtml:168
+msgid "devcp_addon_status_header_active"
+msgstr "Stav aktivovania: <span class=\"inactive-0\">aktívny</span>"
+
+#: views/developers/addon_status.thtml:97
+msgid "devcp_addon_status_header_criteria"
+msgstr "Kritéria pre dokonÄenie doplnku"
+
+#: views/developers/addon_status.thtml:164
+msgid "devcp_addon_status_header_inactive"
+msgstr "Stav aktivovania: <span class=\"inactive-1\">neaktívny</span>"
+
+#: views/developers/addon_status.thtml:117
+msgid "devcp_addon_status_header_nomination"
+msgstr "Kritériá pre nomináciu doplnku na verejný"
+
+#: views/developers/addon_status.thtml:190
+msgid "devcp_addon_status_header_trusted"
+msgstr "Dôveryhodnosť: <span class=\"status-4\">dôveryhodný</span>"
+
+#: views/developers/addon_status.thtml:165
+msgid "devcp_addon_status_inactive"
+msgstr "Váš doplnok je <span class=\"inactive-1\">neaktívny</span>. To znamená, že sa neobjavuje v žiadnom dostupnom zozname a to nezávisle na svojom stave. Aktualizácie <b>nie sú</b> prostredníctvom aktualizaÄnej služby poskytované."
+
+#: views/developers/addon_status.thtml:128
+msgid "devcp_addon_status_nominate_disabled"
+msgstr "Pred nominovaním doplnku na <span class=\"status-4\">verejný</span> musíte splniť vyššie uvedené kritériá."
+
+#: views/developers/addon_status.thtml:125
+msgid "devcp_addon_status_nominate_enabled"
+msgstr "Teraz môžete nominovaÅ¥ váš doplnok na <span class=\"status-4\">verejný</span> kliknutím na nižšie uvedené tlaÄidlo."
+
+#: views/developers/addon_status.thtml:64
+msgid "devcp_addon_status_public"
+msgstr "Verejné"
+
+#: views/developers/addon_status.thtml:63
+msgid "devcp_addon_status_sandbox"
+msgstr "Sandbox"
+
+#. %s is an email address.
+#: views/developers/addon_status.thtml:89
+msgid "devcp_addon_status_switch_disabled"
+msgstr "Váš doplnok bol správcom <span class=\"status-5\">zakázaný</span> a nemôže byť používaný. Ak máte otázky, kontaktujte nás na e-mailovej adrese %s."
+
+#: views/developers/addon_status.thtml:67
+msgid "devcp_addon_status_switch_incomplete"
+msgstr "Váš doplnok je momentálne <span class=\"status-0\">nekompletný</span>. To znamená, že sa nezobrazuje v žiadnej Äasti stránky a nie sú preň poskytované aktualizácie. Váš doplnok môžete dokonÄiÅ¥ na tejto stránke, keÄ splní kritériá pre dokonÄenie a presun do <span class=\"status-1\">Sandboxu</span>."
+
+#. %s is a number, perhaps 42.
+#: views/developers/addon_status.thtml:77
+msgid "devcp_addon_status_switch_nominated"
+msgstr "Váš doplnok je nominovaný na <span class=\"status-4\">verejný</span> doplnok a Äaká na kontrolu editorom. Vo fronte momentálne Äaká niekoľko Äalších doplnkov (celkom %s)."
+
+#. %s is an email address.
+#: views/developers/addon_status.thtml:81
+msgid "devcp_addon_status_switch_pending"
+msgstr "Váš doplnok je momentálne Äakajúci. Toto by sa nemalo staÅ¥. Prosím, poÅ¡lite e-mailovú správu na adresu %s a uveÄte ID doplnku a túto chybu."
+
+#: views/developers/addon_status.thtml:85
+msgid "devcp_addon_status_switch_public"
+msgstr "Váš doplnok je <span class=\"status-4\">verejný</span>, Äo znamená, že sa zobrazuje vo vÅ¡etkých zoznamoch a výsledkoch vyhľadávania a používatelia ho môžu bez obmedzenia preberaÅ¥. Cez aktualizaÄný mechanizmus sú poskytované aktualizácie doplnku."
+
+#: views/developers/addon_status.thtml:71
+#: views/developers/addon_status.thtml:75
+msgid "devcp_addon_status_switch_sandbox"
+msgstr "Váš doplnok sa nachádza v <span class=\"status-1\">Sandboxe</span>, Äo znamená, že sa zobrazuje vo vÅ¡etkých zoznamoch a výsledkoch vyhľadávania, ale používatelia sa musia prihlásiÅ¥, ak ho chcú prevziaÅ¥ a nainÅ¡talovaÅ¥. Cez aktualizaÄný mechanizmus <b>nie sú</b> poskytované aktualizácie doplnku."
+
+#. %s is the add-on name.
+#: views/developers/addon_status_nominate.thtml:43
+#: views/developers/addon_status_confirm.thtml:43
+#: views/developers/addon_status.thtml:43
+msgid "devcp_addon_status_title"
+msgstr "Stav doplnku %s"
+
+#: views/developers/addon_status.thtml:191
+msgid "devcp_addon_status_trusted"
+msgstr "Váš doplnok je <span class=\"status-4\">dôveryhodný</span>. To znamená, že môžete odosielať nové verzie bez toho, aby ich musel skontrolovať editor."
+
+#: views/developers/dashboard.thtml:68
+msgid "devcp_dashboard_active"
+msgstr "aktívny"
+
+#. %1$s is the add-on type string
+#. %2$s is Inactive or Active in a <span>
+#. %3$s is the addon's public status (Public, In Sandbox, ...) in a <span>
+#: views/developers/dashboard.thtml:69
+msgid "devcp_dashboard_addontype_status"
+msgstr "Typ doplnku: %1$s, stav doplnku: %2$s a %3$s"
+
+#: views/developers/dashboard.thtml:67
+msgid "devcp_dashboard_change_status"
+msgstr "Zmeniť stav"
+
+#. %s is the addons email address.
+#: views/developers/dashboard.thtml:99
+msgid "devcp_dashboard_disabled_questions"
+msgstr "Váš doplnok bol správcom zakázaný a nemôže byť používaný. Ak máte otázky, pošlite e-mailovú správu na adresu %s."
+
+#. %s is the (localized) add-on status string in a span, e.g. "Disabled"
+#: views/developers/dashboard.thtml:98
+msgid "devcp_dashboard_disabled_status"
+msgstr "Stav doplnku: %s"
+
+#: views/developers/dashboard.thtml:43
+msgid "devcp_dashboard_header_main"
+msgstr "Ovládací panel vývojára"
+
+#: views/developers/dashboard.thtml:110
+msgid "devcp_dashboard_header_welcome"
+msgstr "Víta vás Ovládací panel vývojára"
+
+#: views/developers/dashboard.thtml:68
+msgid "devcp_dashboard_inactive"
+msgstr "neaktívny"
+
+#. %s is a date in the _('date') format
+#: views/developers/dashboard.thtml:65
+msgid "devcp_dashboard_last_edited"
+msgstr "Posledná úprava: %s"
+
+#: views/developers/dashboard.thtml:111
+msgid "devcp_dashboard_learn"
+msgstr "Momentálne nemáte na serveri Mozilla Add-ons umiestnené žiadne vlastné doplnky. Ak chcete vedieÅ¥, ako tak urobiÅ¥, kliknite na tlaÄidlo ZaÄíname."
+
+#: views/developers/dashboard.thtml:112
+msgid "devcp_dashboard_start"
+msgstr "ZaÄíname"
+
+#: views/developers/dashboard.thtml:82
+msgid "devcp_dashboard_versions"
+msgstr "Verzia a súbory"
+
+#: views/developers/dashboard.thtml:91
+msgid "devcp_dashboard_versions_new"
+msgstr "Odoslať novú verziu"
+
+#. %s is the preview ID number.
+#: controllers/developers_controller.php:1415
+msgid "devcp_delete_previews_error"
+msgstr "Ukážka %s nemohla byť odstránená z databázy. Skúste to znova."
+
+#. %s is the preview ID number.
+#: controllers/developers_controller.php:1413
+msgid "devcp_delete_previews_success"
+msgstr "Ukážka %s bola úspešne odstránená."
+
+#: controllers/developers_controller.php:1089
+msgid "devcp_delete_version_priv_error"
+msgstr "Nemáte oprávnenie na odstránenie súborov alebo verzií."
+
+#. %1$s is the count of files, a number
+#. %2$s is a status string like _('Public') or _('Incomplete')
+#: controllers/components/amo.php:549
+msgid "devcp_describe_version_status"
+msgid_plural "devcp_describe_version_status"
+msgstr[0] "%1$s %2$s súbor"
+msgstr[1] "%1$s %2$s súbory"
+msgstr[2] "%1$s %2$s súborov"
+
+#. %s is a version number. Example: 3.0
+#: views/developers/versions.thtml:65
+#, php-format
+msgid "devcp_details_version"
+msgstr "Verzia %s"
+
+#: views/developers/discuss.thtml:68
+msgid "devcp_discuss_addreply_header"
+msgstr "PridaÅ¥ odpoveÄ"
+
+#: views/developers/discuss.thtml:57
+msgid "devcp_discuss_allreplies_header"
+msgstr "Odpovede"
+
+#. notice when an error occurs saving a discussion reply
+#. %1 is the email address (linked) for the amo-editors list
+#: views/developers/discuss.thtml:70
+msgid "devcp_discuss_error_notice"
+msgstr "Pri ukladaní vašej odpovede sa vyskytla chyba. Prosím, kontaktujte %1$s."
+
+#. %1 is the add-on name, %2 is the add-on's version number currently being reviewed by an editor
+#: views/developers/discuss.thtml:46
+msgid "devcp_discuss_intro"
+msgstr "Editor Mozilla Add-ons vyžaduje dodatoÄné informácie k verzii %2$s vášho doplnku %1$s."
+
+#. %1 is the add-on name
+#: views/developers/discuss.thtml:43
+msgid "devcp_discuss_pagetitle"
+msgstr "Poskytnúť viac informácií pre recenziu doplnku %1$s"
+
+#. submit button text
+#: views/developers/discuss.thtml:79
+msgid "devcp_discuss_submit_reply"
+msgstr "OdoslaÅ¥ odpoveÄ"
+
+#: views/developers/discuss.thtml:72
+msgid "devcp_discuss_success_message"
+msgstr "VaÅ¡a odpoveÄ bola úspeÅ¡ne uložená. Ostatní úÄastníci diskusie budú upozornení e-mailovou správou."
+
+#. in an author/editor discussion about an add-on to be reviewed:
+#. %1 is the commenter's user name (linked).
+#. %2 is the full date the comment was made.
+#: views/developers/discuss.thtml:52
+#: views/developers/discuss.thtml:62
+msgid "devcp_discuss_writtenby"
+msgstr "napísal %1$s dňa %2$s"
+
+#: views/developers/addon_edit_authors.thtml:72
+#: views/developers/addon_edit_authors.thtml:81
+msgid "devcp_edit_authors_add_author"
+msgstr "Pridať nového autora"
+
+#: views/developers/addon_edit_authors.thtml:96
+msgid "devcp_edit_authors_add_author_button"
+msgstr "Pridať autora"
+
+#: views/developers/addon_edit_authors.thtml:83
+msgid "devcp_edit_authors_add_email"
+msgstr "E-mailová adresa úÄtu autora:"
+
+#: views/developers/addon_edit_authors.thtml:98
+msgid "devcp_edit_authors_add_loading"
+msgstr "Kontroluje sa e-mailová adresu úÄtu…"
+
+#: views/developers/addon_edit_authors.thtml:70
+msgid "devcp_edit_authors_click_save"
+msgstr "Zmeny uložíte kliknutím na tlaÄidlo AktualizovaÅ¥ autorov."
+
+#: views/developers/addon_edit_authors.thtml:58
+msgid "devcp_edit_authors_header_current"
+msgstr "Aktuálni autori"
+
+#: views/developers/addon_edit_authors.thtml:50
+msgid "devcp_edit_authors_header_manage"
+msgstr "Správa autorov doplnku"
+
+#: views/developers/addon_edit_authors.thtml:93
+msgid "devcp_edit_authors_label_add_listed"
+msgstr "Uviesť ako autora na verejne dostupných stránkach"
+
+#: views/developers/addon_edit_authors.thtml:89
+msgid "devcp_edit_authors_label_developer"
+msgstr "<strong>Vývojár</strong> - môže vykonávať všetky úkony, okrem pridávania a odstraňovania iných autorov."
+
+#: views/developers/addon_edit_authors.thtml:88
+msgid "devcp_edit_authors_label_owner"
+msgstr "<strong>Vlastník</strong> - môže vykonávať všetky úkony, vrátane pridávania a odstraňovania iných autorov."
+
+#: views/developers/addon_edit_authors.thtml:90
+msgid "devcp_edit_authors_label_viewer"
+msgstr "<strong>Divák</strong> - môže zobrazovať všetky údaje o doplnku, ale nemôže meniť žiadne údaje."
+
+#. Placeholder for the empty option in a <select>.
+#: views/developers/addon_edit_categories.thtml:69
+msgid "devcp_edit_authors_option_empty"
+msgstr "----------------"
+
+#: views/developers/addon_edit_authors.thtml:86
+msgid "devcp_edit_authors_select_role"
+msgstr "Zvoľte funkciu autora:"
+
+#. Column name in a table.
+#: views/developers/addon_edit_authors.thtml:62
+msgid "devcp_edit_authors_th_author"
+msgstr "Autor"
+
+#. Column name in a table.
+#: views/developers/addon_edit_authors.thtml:64
+msgid "devcp_edit_authors_th_listed"
+msgstr "V zozname"
+
+#. Column name in a table.
+#: views/developers/addon_edit_authors.thtml:63
+msgid "devcp_edit_authors_th_role"
+msgstr "Funkcia"
+
+#: views/developers/addon_edit_authors.thtml:77
+msgid "devcp_edit_authors_update_author"
+msgstr "Aktualizovať autorov"
+
+#: views/developers/addon_edit_categories.thtml:99
+msgid "devcp_edit_categories_button_update"
+msgstr "Aktualizovať kategórie"
+
+#: views/developers/addon_edit_categories.thtml:88
+msgid "devcp_edit_categories_does_not_fit"
+msgstr "Môj doplnok nespadá ani do jednej z uvedených kategórií."
+
+#. %s is the application name (Firefox, Thunderbird).
+#: views/developers/addon_edit_categories.thtml:61
+msgid "devcp_edit_categories_header_application"
+msgstr "Kategórie pre %s"
+
+#: views/developers/addon_edit_categories.thtml:49
+msgid "devcp_edit_categories_header_manage"
+msgstr "Správa kategórií doplnku"
+
+#: views/developers/addon_edit_categories.thtml:91
+msgid "devcp_edit_categories_hover"
+msgstr "Presunutím myši na názov kategórie sa zobrazí jej popis."
+
+#. %s is the category number (1, 2, 3).
+#: views/developers/addon_edit_categories.thtml:67
+msgid "devcp_edit_categories_label_category_num"
+msgstr "Kategória %s"
+
+#: views/developers/addon_edit_categories.thtml:94
+#: views/developers/addon_edit_categories.thtml:103
+msgid "devcp_edit_categories_none_available"
+msgstr "Pre tento typ doplnku a túto aplikáciu nie sú dostupné žiadne kategórie."
+
+#: views/developers/addon_edit_categories.thtml:86
+msgid "devcp_edit_categories_other"
+msgstr "Do tejto kategórie umiestnite doplnok len v prípade, že nespadá ani do jednej z dostupných kategórií."
+
+#. %s is the application name (Firefox, Thunderbird).
+#: views/developers/addon_edit_categories.thtml:63
+msgid "devcp_edit_categories_select_application_categories"
+msgstr "Môžete zvoliť až 3 kategórie doplnku pre %s"
+
+#: views/developers/addon_edit.thtml:47
+msgid "devcp_edit_dd_manage_authors"
+msgstr "Umožňuje pridať alebo odstrániť používateľov, ktorí môžu spravovať tento doplnok."
+
+#: views/developers/addon_edit.thtml:49
+msgid "devcp_edit_dd_manage_categories"
+msgstr "Umožňuje zvoliť relevantné kategórie doplnku pre každú aplikáciu."
+
+#: views/developers/addon_edit.thtml:51
+msgid "devcp_edit_dd_manage_description"
+msgstr "Umožňuje pridať a meniť preklady súhrnu doplnku, jeho popisu, zmluvy s koncovým používateľom a zásad ochrany súkromia."
+
+#: views/developers/addon_edit.thtml:53
+msgid "devcp_edit_dd_manage_properties"
+msgstr "Umožňuje zmeniÅ¥ názov doplnku, domovskú stránku, ikonu a ÄalÅ¡ie vlastnosti."
+
+#: views/developers/addon_edit_descriptions.thtml:116
+msgid "devcp_edit_description_button_update"
+msgstr "Aktualizovať popisy"
+
+#: views/developers/addon_edit_descriptions.thtml:115
+msgid "devcp_edit_description_correct_error"
+msgstr "Prosím, opravte chyby oznaÄené Äervenou farbou."
+
+#: views/developers/addon_edit_descriptions.thtml:51
+msgid "devcp_edit_descriptions_header"
+msgstr "Úprava popisov doplnku"
+
+#: views/developers/addon_edit_descriptions.thtml:94
+msgid "devcp_edit_descriptions_transbox_comments_description"
+msgstr "DodatoÄné informácie, ktoré by mali používatelia doplnku vedieÅ¥, ale nie je potrebné ich uvádzaÅ¥ v súhrne alebo popise doplnku. Bežne sa tu uvádzajú známe problémy, informácie o spôsobe nahlasovania nájdených chýb, predpokladaný dátum sprístupnenia novej verzie atÄ."
+
+#: views/developers/addon_edit_descriptions.thtml:93
+msgid "devcp_edit_descriptions_transbox_comments_name"
+msgstr "Poznámky vývojára"
+
+#: views/developers/addon_edit_descriptions.thtml:86
+msgid "devcp_edit_descriptions_transbox_description_description"
+msgstr "Popis doplnku slúži na hlbÅ¡ie popísanie vlastností Äi funkcionality doplnku a poskytnutie Äalších potrebných informácií. Na stránke doplnku sa zobrazuje pod súhrnom."
+
+#: views/developers/addon_edit_descriptions.thtml:85
+msgid "devcp_edit_descriptions_transbox_description_name"
+msgstr "Popis doplnku"
+
+#: views/developers/addon_edit_descriptions.thtml:103
+msgid "devcp_edit_descriptions_transbox_eula_description"
+msgstr "Ak váš doplnok využíva LicenÄnú zmluvu s koncovým používateľom (EULA), tu by ste mali zadaÅ¥ jej text. Podľa nastavenia používatelia ju budú musieÅ¥ pred inÅ¡taláciou doplnku odsúhlasiÅ¥. Pamätajte, že EULA nie je totožná s licenciou, pod ktorou sa vydáva zdrojový kód (GPL Äi MPL)."
+
+#: views/developers/addon_edit_descriptions.thtml:102
+msgid "devcp_edit_descriptions_transbox_eula_name"
+msgstr "LicenÄná zmluva s koncovým používateľom"
+
+#: views/developers/addon_edit_descriptions.thtml:112
+msgid "devcp_edit_descriptions_transbox_privacy_description"
+msgstr "Ak váš doplnok používa Zásady ochrany súkromia, zadajte ich tu. Na stránke doplnku sa objaví odkaz na tieto zásady."
+
+#: views/developers/addon_edit_descriptions.thtml:111
+msgid "devcp_edit_descriptions_transbox_privacy_name"
+msgstr "Zásady ochrany súkromia"
+
+#: views/developers/addon_edit_descriptions.thtml:78
+msgid "devcp_edit_descriptions_transbox_summary_description"
+msgstr "Súhrn je krátky popis základnej funkcionality doplnku, ktorá sa zobrazuje v zoznamoch doplnkov a vo vyhľadávaní, ako aj v hornej Äasti stránky doplnku. <strong>Je možné zadaÅ¥ maximálne 250 znakov.</strong>"
+
+#: views/developers/addon_edit_descriptions.thtml:77
+msgid "devcp_edit_descriptions_transbox_summary_name"
+msgstr "Súhrn doplnku"
+
+#: views/developers/addon_edit.thtml:46
+msgid "devcp_edit_dt_manage_authors"
+msgstr "Správa autorov doplnku"
+
+#: views/developers/addon_edit.thtml:48
+msgid "devcp_edit_dt_manage_categories"
+msgstr "Správa kategórií doplnku"
+
+#: views/developers/addon_edit.thtml:50
+msgid "devcp_edit_dt_manage_descriptions"
+msgstr "Správa popisov doplnku"
+
+#: views/developers/addon_edit.thtml:52
+msgid "devcp_edit_dt_manage_properties"
+msgstr "Správa vlastností doplnku"
+
+#: views/developers/addon_edit_properties.thtml:170
+msgid "devcp_edit_label_externalsoftware"
+msgstr "Tento doplnok vyžaduje externý softvér"
+
+#: views/developers/addon_edit_properties.thtml:205
+msgid "devcp_edit_label_locale_disambiguation"
+msgstr "Ďalšie informácie o lokalizácii"
+
+#: views/developers/addon_edit_properties.thtml:168
+msgid "devcp_edit_label_prerelease"
+msgstr "Toto je vývojová verzia"
+
+#: views/developers/addon_edit_properties.thtml:169
+msgid "devcp_edit_label_sitespecific"
+msgstr "Tento doplnok je urÄený pre Å¡pecifickú stránku"
+
+#: views/developers/addon_edit_properties.thtml:202
+msgid "devcp_edit_label_target_locale"
+msgstr "Cieľová lokalizácia"
+
+#: views/developers/addon_edit_properties.thtml:212
+msgid "devcp_edit_properties_button_update"
+msgstr "Aktualizovať vlastnosti"
+
+#: views/developers/addon_edit_properties.thtml:198
+msgid "devcp_edit_properties_change_guid"
+msgstr "Meňte len v prípade, že rozumiete všetkým dôsledkom."
+
+#: views/developers/addon_edit_properties.thtml:109
+msgid "devcp_edit_properties_current_icon"
+msgstr "Aktuálna ikona"
+
+#: views/developers/addon_edit_properties.thtml:85
+msgid "devcp_edit_properties_default_locale"
+msgstr "Predvolený jazyk doplnku je hlavný jazyk, pre ktorý musí byť dostupná lokalizácia. Ak pre váš doplnok nie sú dostupné popisné texty v jazyku používateľa, ktorý si prehliada stránku doplnku, tieto sa zobrazia v predvolenom jazyku."
+
+#: views/developers/addon_edit_properties.thtml:167
+msgid "devcp_edit_properties_flags"
+msgstr "Pomocou týchto oznaÄení je možné filtrovaÅ¥ a triediÅ¥ doplnky."
+
+#: views/developers/addon_edit_properties.thtml:174
+msgid "devcp_edit_properties_guid"
+msgstr "Unikátny identifikátor GUID vášho doplnku je urÄený v súbore install.rdf a jednoznaÄne identifikuje doplnok. Po pridaní doplnku do zoznamu na Mozilla Add-ons nie je možné identifikátor zmeniÅ¥."
+
+#: views/developers/addon_edit_properties.thtml:53
+msgid "devcp_edit_properties_header"
+msgstr "Úprava vlastností doplnku"
+
+#: views/developers/addon_edit_properties.thtml:186
+msgid "devcp_edit_properties_header_addon_type"
+msgstr "Typ doplnku"
+
+#: views/developers/addon_edit_properties.thtml:181
+msgid "devcp_edit_properties_header_admin_settings"
+msgstr "Nastavenia administrátora"
+
+#: views/developers/addon_edit_properties.thtml:84
+msgid "devcp_edit_properties_header_default_locale"
+msgstr "Predvolený jazyk"
+
+#: views/developers/addon_edit_properties.thtml:166
+msgid "devcp_edit_properties_header_flags"
+msgstr "OznaÄenie doplnku"
+
+#: views/developers/addon_edit_properties.thtml:173
+#: views/developers/addon_edit_properties.thtml:197
+msgid "devcp_edit_properties_header_guid"
+msgstr "GUID doplnku"
+
+#: views/developers/addon_edit_properties.thtml:104
+msgid "devcp_edit_properties_header_icon"
+msgstr "Ikona doplnku"
+
+#: views/developers/addon_edit_properties.thtml:159
+msgid "devcp_edit_properties_header_other_settings"
+msgstr "Ďalšie nastavenia"
+
+#. A header on the admin page to toggle trusted status.
+#: views/developers/addon_edit_properties.thtml:182
+msgid "devcp_edit_properties_header_trusted"
+msgstr "Dôveryhodný doplnok?"
+
+#: views/developers/addon_edit_properties.thtml:160
+msgid "devcp_edit_properties_header_view_source"
+msgstr "Zobraziť zdrojový kód online"
+
+#. %s is a comma-separated list of image extensions ".png, .jpg"
+#: views/developers/addon_edit_properties.thtml:106
+msgid "devcp_edit_properties_icon"
+msgstr "Ikona doplnku je malý obrázok, ktorý je pri prehliadaní stránky doplnku, vo výsledkoch vyhľadávania a pri inštalácii doplnku zobrazený vedľa názvu doplnku. Obrázok bude automaticky nastavený na veľkosť 32 x 32 bodov. Môžete použiť jeden z nasledujúcich typov obrázkov: %s"
+
+#: views/developers/addon_edit_properties.thtml:171
+msgid "devcp_edit_properties_label_binary"
+msgstr "Tento doplnok obsahuje binárne súÄasti"
+
+#: views/developers/addon_edit_properties.thtml:185
+msgid "devcp_edit_properties_label_not_trusted"
+msgstr "Nedôveryhodný"
+
+#: views/developers/addon_edit_properties.thtml:184
+msgid "devcp_edit_properties_label_trusted"
+msgstr "Dôveryhodný"
+
+#: views/developers/addon_edit_properties.thtml:110
+msgid "devcp_edit_properties_new_icon"
+msgstr "Nová ikona"
+
+#: views/developers/addon_edit_properties.thtml:118
+msgid "devcp_edit_properties_remove_icon"
+msgstr "Odstrániť ikonu"
+
+#: views/developers/addon_edit_properties.thtml:136
+msgid "devcp_edit_properties_transbox_homepage_description"
+msgstr "Ak má váš doplnok domovskú stránku, zadajte ju tu. Pokiaľ domovská stránka nie je lokalizovaná do viacerých jazykov, pridávanie Äalších jazykov nie je potrebné."
+
+#: views/developers/addon_edit_properties.thtml:135
+msgid "devcp_edit_properties_transbox_homepage_name"
+msgstr "Domovská stránka doplnku"
+
+#: views/developers/addon_edit_properties.thtml:79
+msgid "devcp_edit_properties_transbox_name_description"
+msgstr "Názov doplnku sa používa vo všetkých zoznamoch a stránkach, kde sa váš doplnok vyskytuje."
+
+#: views/developers/addon_edit_properties.thtml:78
+msgid "devcp_edit_properties_transbox_name_name"
+msgstr "Názov doplnku"
+
+#: views/developers/addon_edit_properties.thtml:145
+msgid "devcp_edit_properties_transbox_supportemail_description"
+msgstr "Ak poskytujete technickú podporu prostredníctvom e-mailu, zadajte sem vaÅ¡u adresu. Pokiaľ pre iné jazyky nepoužívate inú e-mailovú adresu, pridávanie Äalších jazykov nie je potrebné."
+
+#: views/developers/addon_edit_properties.thtml:144
+msgid "devcp_edit_properties_transbox_supportemail_name"
+msgstr "Technická podpora prostredníctvom e-mailu"
+
+#: views/developers/addon_edit_properties.thtml:154
+msgid "devcp_edit_properties_transbox_supporturl_description"
+msgstr "Ak má váš doplnok stránku technickej podpory alebo fórum, zadajte tu potrebnú adresu. Pokiaľ stránka nie je lokalizovaná do viacerých jazykov, pridávanie Äalších jazykov nie je potrebné."
+
+#: views/developers/addon_edit_properties.thtml:153
+msgid "devcp_edit_properties_transbox_supporturl_name"
+msgstr "Technická podpora"
+
+#: views/developers/addon_edit_properties.thtml:183
+msgid "devcp_edit_properties_trusted"
+msgstr "Dôveryhodné doplnky sa môžu stať verejnými bez kontroly editorom."
+
+#. %s is href="..." and should stay in the <a> tag.
+#: views/developers/addon_edit_properties.thtml:119
+msgid "devcp_edit_properties_undelete"
+msgstr "Ikona bude pri uložení odstránená. <a %s>Zrušiť?</a>"
+
+#: views/developers/addon_edit_properties.thtml:161
+msgid "devcp_edit_properties_view_source"
+msgstr "Ak chcete, zdrojový kód súborov vášho doplnku si môže prezrieť online každý prihlásený používateľ."
+
+#: views/developers/addon_edit_properties.thtml:162
+msgid "devcp_edit_properties_view_source_allow"
+msgstr "Umožniť zobrazenie zdrojového kódu online"
+
+#: views/developers/addon_edit_properties.thtml:163
+msgid "devcp_edit_properties_view_source_do_not_allow"
+msgstr "Nezobrazovať zdrojový kód online"
+
+#: views/elements/developers/editbox.thtml:46
+msgid "devcp_editbox_authors"
+msgstr "Autori"
+
+#: views/elements/developers/editbox.thtml:47
+msgid "devcp_editbox_categories"
+msgstr "Kategórie"
+
+#: views/elements/developers/editbox.thtml:52
+msgid "devcp_editbox_change_status"
+msgstr "Zmeniť stav"
+
+#: views/elements/developers/editbox.thtml:48
+msgid "devcp_editbox_descriptions"
+msgstr "Popisy"
+
+#: views/elements/developers/editbox.thtml:43
+msgid "devcp_editbox_edit_addon"
+msgstr "Upraviť doplnok"
+
+#: views/elements/developers/editbox.thtml:57
+msgid "devcp_editbox_new_version"
+msgstr "Nová verzia"
+
+#: views/elements/developers/editbox.thtml:49
+msgid "devcp_editbox_properties"
+msgstr "Vlastnosti"
+
+#: views/elements/developers/editbox.thtml:60
+msgid "devcp_editbox_screenshots"
+msgstr "Obrázky s ukážkami"
+
+#: views/elements/developers/editbox.thtml:53
+msgid "devcp_editbox_statistics_dashboard"
+msgstr "Å tatistika"
+
+#: views/elements/developers/editbox.thtml:54
+msgid "devcp_editbox_versions"
+msgstr "Verzie a súbory"
+
+#: views/elements/developers/editbox.thtml:42
+msgid "devcp_editbox_view_listing"
+msgstr "Zobraziť doplnok"
+
+#: views/elements/developers/editorsmenu.thtml:59
+msgid "devcp_editorsqueue_featured"
+msgstr "OdporúÄané doplnky"
+
+# %1 is the review count
+#. %1 is the review count
+#: views/elements/developers/editorsqueue.thtml:42
+#: views/elements/developers/editorsmenu.thtml:56
+#, php-format
+msgid "devcp_editorsqueue_moderatedreviews"
+msgid_plural "devcp_editorsqueue_moderatedreviews"
+msgstr[0] "Moderované recenzie (%s)"
+msgstr[1] "Moderované recenzie (%s)"
+msgstr[2] "Moderované recenzie (%s)"
+
+# %1 is the nominated addons count
+#. %1 is the nominated addons count
+#: views/elements/developers/editorsqueue.thtml:44
+#: views/elements/developers/editorsmenu.thtml:58
+#, php-format
+msgid "devcp_editorsqueue_nominated"
+msgid_plural "devcp_editorsqueue_nominated"
+msgstr[0] "Nominované doplnky (%s)"
+msgstr[1] "Nominované doplnky (%s)"
+msgstr[2] "Nominované doplnky (%s)"
+
+# %1 is the update count
+#. %1 is the update count
+#: views/elements/developers/editorsqueue.thtml:43
+#: views/elements/developers/editorsmenu.thtml:57
+#, php-format
+msgid "devcp_editorsqueue_pendingupdates"
+msgid_plural "devcp_editorsqueue_pendingupdates"
+msgstr[0] "Nevybavené aktualizácie (%s)"
+msgstr[1] "Nevybavené aktualizácie (%s)"
+msgstr[2] "Nevybavené aktualizácie (%s)"
+
+#: controllers/statistics_controller.php:147
+#: controllers/statistics_controller.php:361
+#: controllers/previews_controller.php:108
+#: controllers/previews_controller.php:211
+#: controllers/previews_controller.php:312
+msgid "devcp_error_addon_access_denied"
+msgstr "Nemáte prístup k tomuto doplnku."
+
+#. %s is a complete URL with the text from devcp_error_appversion_reference_link_text
+#. in the <a> tag. This should be fixed.
+#: controllers/components/developers.php:591
+#, php-format
+msgid "devcp_error_appversion_reference_link"
+msgstr "Pozrite informácie na %s."
+
+#. This is the link text in the <a> for devcp_error_appversion_reference_link. This
+#. should be fixed.
+#: controllers/components/developers.php:591
+msgid "devcp_error_appversion_reference_link_text"
+msgstr "tejto stránke"
+
+#: views/developers/addon_edit_authors.thtml:76
+msgid "devcp_error_empty_authors"
+msgstr "Váš doplnok musí mať aspoň jedného vlastníka."
+
+#. %1$s is the name of the file
+#: controllers/components/developers.php:658
+msgid "devcp_error_file_exists"
+msgstr "Táto verzia doplnku už existuje. Ak ju chcete nahradiť, musíte najskôr odstrániť súbor %1$s."
+
+#. %1$s is a file extension. Example: .exe
+#. %2$s is a comma separated list of extensions. Example: .xpi, .jar
+#: controllers/components/developers.php:355
+#, php-format
+msgid "devcp_error_file_extension"
+msgstr "Táto prípona súboru (%1$s) nie je pre vybraný typ doplnku povolená. Použite jednu z nasledujúcich: %2$s"
+
+#: controllers/components/developers.php:64
+msgid "devcp_error_five_categories"
+msgstr "Vyberte najviac päť kategórií."
+
+#: controllers/components/developers.php:526
+msgid "devcp_error_guid_application"
+msgstr "ID tohto doplnku už používa iná aplikácia."
+
+#: controllers/components/developers.php:337
+#: controllers/components/developers.php:389
+msgid "devcp_error_http_incomplete"
+msgstr "Neúplný prenos"
+
+#: controllers/components/developers.php:335
+#: controllers/components/developers.php:336
+#: controllers/components/developers.php:387
+#: controllers/components/developers.php:388
+msgid "devcp_error_http_maxupload"
+msgstr "Presahuje maximálnu veľkosť pre odoslanie"
+
+#: controllers/components/developers.php:338
+#: controllers/components/developers.php:390
+msgid "devcp_error_http_nofile"
+msgstr "Nie je odoslaný žiadny súbor"
+
+#. %1$s is a file extension. Example: .exe
+#. %2$s is a comma separated list of extensions. Example: .xpi, .jar
+#: controllers/components/developers.php:401
+#, php-format
+msgid "devcp_error_icon_extension"
+msgstr "Táto prípona súboru (%1$s) nie je pre ikonu povolená. Použite jednu z nasledujúcich: %2$s."
+
+#: controllers/developers_controller.php:504
+msgid "devcp_error_index_rdf_notfound"
+msgstr "Chýba súbor install.rdf."
+
+#: controllers/components/developers.php:601
+msgid "devcp_error_install_manifest"
+msgstr "V súbore install.rdf sa našli nasledujúce chyby:"
+
+#: controllers/developers_controller.php:1463
+msgid "devcp_error_invalid_addontype"
+msgstr ""
+
+#. %$1s is a version. Example: 3.1.1
+#. %$2s is an add-on name.
+#: controllers/components/developers.php:569
+#: controllers/components/developers.php:581
+#, php-format
+msgid "devcp_error_invalid_appversion"
+msgstr "%$1s nie platná verzia doplnku %$2s."
+
+#. %s is a string
+#: controllers/components/developers.php:521
+#, php-format
+msgid "devcp_error_invalid_guid"
+msgstr "ID doplnku je neplatné: %s"
+
+#. %$1s is a version. Example: 3.1.1
+#. %$2s is an add-on name.
+#: controllers/components/developers.php:572
+#, php-format
+msgid "devcp_error_invalid_minversion"
+msgstr "%$1s nie je platná verzia %$2s: minimálna verzia nemôže obsahovať znak *."
+
+#: controllers/components/developers.php:536
+msgid "devcp_error_invalid_version"
+msgstr "Verzia tohto doplnku je neplatná: pozrite <a href=\"http://developer.mozilla.org/en/docs/Toolkit_version_format\">špecifikáciu</a>."
+
+#: controllers/components/developers.php:531
+msgid "devcp_error_invalid_version_spaces"
+msgstr "Verzia tohto doplnku je neplatná: verzie nemôžu obsahovať medzery."
+
+#. %s is an error message from the parser.
+#: controllers/components/developers.php:501
+#, php-format
+msgid "devcp_error_manifest_parse"
+msgstr "PoÄas analýzy súboru install.rdf doÅ¡lo k nasledujúcej chybe: %s"
+
+#: controllers/components/developers.php:373
+msgid "devcp_error_move_file"
+msgstr "Súbor nemožno presunúť"
+
+#. %s is the name of a file
+#: controllers/components/developers.php:650
+#: controllers/components/developers.php:662
+#: controllers/components/developers.php:667
+#: controllers/components/developers.php:727
+#: controllers/components/developers.php:738
+#: controllers/components/developers.php:743
+#, php-format
+msgid "devcp_error_moving_file"
+msgstr "Pri presúvaní súboru %s sa vyskytla chyba."
+
+#: controllers/components/developers.php:595
+msgid "devcp_error_mozilla_application"
+msgstr "Musíte mať aspoň jednu platnú cieľovú aplikáciu od Mozilly."
+
+#: controllers/components/developers.php:516
+msgid "devcp_error_no_guid"
+msgstr "V súbore install.rdf nemožno nájsť ID tohto doplnku."
+
+#: controllers/components/developers.php:287
+msgid "devcp_error_no_platform"
+msgstr "Nie je vybraná žiadna platforma"
+
+#: controllers/components/developers.php:59
+msgid "devcp_error_one_category"
+msgstr "Vyberte aspoň jednu kategóriu."
+
+#: controllers/components/developers.php:92
+msgid "devcp_error_one_user"
+msgstr "Doplnok musí mať aspoň jedného autora."
+
+#. %1$s is a file extension. Example: .exe
+#. %2$s is a comma separated list of extensions. Example: .xpi, .jar
+#: controllers/components/developers.php:1081
+#, php-format
+msgid "devcp_error_preview_extension"
+msgstr "Táto prípona súboru (%1$s) nie je pre ukážku povolená. Použite jednu z nasledujúcich: %2$s"
+
+#: controllers/components/developers.php:511
+msgid "devcp_error_updatekey"
+msgstr "Doplnok nemôže používať updateKey. Odstráňte ho zo súboru install.rdf a skúste to znova."
+
+#: controllers/components/developers.php:506
+msgid "devcp_error_updateurl"
+msgstr "Doplnky nemôžu používať externú adresu aktualizácie. Odstráňte ju zo súboru install.rdf a skúste to znova."
+
+#: controllers/developers_controller.php:465
+#: controllers/components/developers.php:271
+msgid "devcp_error_upload_file"
+msgstr "Odošlite súbor."
+
+#: views/developers/uploader.thtml:135
+msgid "devcp_input_upload_file"
+msgstr "Odoslať súbor"
+
+#: views/pages/js_constants.js.thtml:89
+msgid "devcp_js_a_cancel"
+msgstr "Zrušiť"
+
+#: views/pages/js_constants.js.thtml:90
+msgid "devcp_js_add_email"
+msgstr "Prosím, zadajte e-mailovú adresu úÄtu autora, ktorého chcete pridaÅ¥."
+
+#. alt text for a down-arrow image.
+#: views/pages/js_constants.js.thtml:81
+msgid "devcp_js_img_move_down"
+msgstr "Posunúť nadol"
+
+#. alt text for an up-arrow image.
+#: views/pages/js_constants.js.thtml:82
+msgid "devcp_js_img_move_up"
+msgstr "Posunúť nahor"
+
+#: views/pages/js_constants.js.thtml:91
+msgid "devcp_js_img_remove_compat"
+msgstr "Odstrániť kompatibilitu aplikácie"
+
+#: views/pages/js_constants.js.thtml:86
+msgid "devcp_js_input_list_author"
+msgstr "Zobraziť ako autora na verejne dostupných stránkach"
+
+#: views/pages/js_constants.js.thtml:92
+msgid "devcp_js_license_select"
+msgstr "Prosím, zvoľte licenciu."
+
+#: views/pages/js_constants.js.thtml:93
+msgid "devcp_js_license_text"
+msgstr "Prosím, zadajte text licencie."
+
+#. <option> text in a <select> for Author role in an add-on.
+#: views/pages/js_constants.js.thtml:84
+msgid "devcp_js_option_developer"
+msgstr "Vývojár"
+
+#. <option> text in a <select> for Author role in an add-on.
+#: views/pages/js_constants.js.thtml:83
+msgid "devcp_js_option_owner"
+msgstr "Vlastník"
+
+#. <option> text in a <select> for Author role in an add-on.
+#: views/pages/js_constants.js.thtml:85
+msgid "devcp_js_option_viewer"
+msgstr "Divák"
+
+#: views/pages/js_constants.js.thtml:88
+msgid "devcp_js_remove_author"
+msgstr "Odstrániť autora"
+
+#: views/pages/js_constants.js.thtml:87
+msgid "devcp_js_sure_remove"
+msgstr "<strong>Naozaj</strong> chcete odstrániť tohto autora?"
+
+#: views/pages/js_constants.js.thtml:77
+msgid "devcp_js_upload_alert"
+msgstr "Musíte zvoliť súbor, ktorý chcete odoslať."
+
+#. %1$s is an addon id, like 32.
+#. %2$s is a version number, like 3.5.
+#: controllers/components/developers.php:1212
+msgid "devcp_license_existing"
+msgstr "Vlastná licencia pre doplnok %1$s v%2$s"
+
+#: views/elements/developers/localebox.thtml:44
+msgid "devcp_localebox_header_localizedfields"
+msgstr "Lokalizované polia"
+
+# %1 is the default locale
+#. %1 is the default locale
+#: views/elements/developers/localebox.thtml:48
+#, php-format
+msgid "devcp_localebox_intro"
+msgstr "Niektoré polia na tejto stránke sú lokalizované, takže sa objavia v rodnom jazyku používateľa. Vyberte dole jazyk, ak chcete upraviť podrobnosti o doplnku v tomto jazyku. Ak preklad pre jazyk nie je k dispozícii, vráti sa do predvoleného jazyka (%s)."
+
+#: views/elements/developers/sidebar.thtml:68
+#: views/elements/developers/myaddons.thtml:75
+msgid "devcp_myaddons_admincp_link"
+msgstr "Nástroje správcu"
+
+#: views/elements/developers/sidebar.thtml:65
+#: views/elements/developers/myaddons.thtml:72
+msgid "devcp_myaddons_editorcp_link"
+msgstr "Nástroje editora"
+
+#: views/elements/developers/myaddons.thtml:52
+msgid "devcp_myaddons_link"
+msgstr "Moje doplnky"
+
+#: views/elements/developers/sidebar.thtml:70
+#: views/elements/developers/myaddons.thtml:77
+msgid "devcp_myaddons_mainpage_link"
+msgstr "Späť na hlavnú stránku"
+
+#: views/elements/developers/sidebar.thtml:63
+#: views/elements/developers/myaddons.thtml:70
+msgid "devcp_myaddons_statistics_link"
+msgstr "Å tatistika"
+
+#: views/elements/developers/sidebar.thtml:62
+#: views/elements/developers/myaddons.thtml:69
+msgid "devcp_myaddons_submitaddon_link"
+msgstr "Odoslať doplnok"
+
+#: views/elements/developers/sidebar.thtml:48
+#: views/elements/developers/myaddons.thtml:67
+msgid "devcp_myaddons_title"
+msgstr "Nástroje vývojára"
+
+#. %1$s is an add-on ID, perhaps 167.
+#. %2$s is a URL.
+#: controllers/developers_controller.php:256
+msgid "devcp_new_addon_error"
+msgstr "Doplnok s týmto ID (%1$s) už v databáze existuje. Ak je to váš doplnok, môžete <a href=\"%2$s\">odoslať jeho novú verziu</a>."
+
+#: views/developers/addon_status_nominate.thtml:62
+msgid "devcp_nominate_cancel"
+msgstr "Zrušiť a návrat"
+
+# %1 is the addon name
+#. %1 is the add-on name
+#: views/developers/addon_status_nominate.thtml:61
+#, php-format
+msgid "devcp_nominate_submit_nominate"
+msgstr "Nominovať %s"
+
+#: views/developers/addon_edit_properties.thtml:50
+#: views/developers/addon_status.thtml:49
+#: views/developers/versions_edit.thtml:50
+msgid "devcp_notice_changes_error"
+msgstr "<span>Jedna alebo viacero zmien nemohlo byť uložených.</span><br />Prosím, pozrite nižšie uvedené chyby. Ostatné zmeny boli úspešne uložené."
+
+#: views/developers/addon_edit_authors.thtml:47
+#: views/developers/addon_edit_properties.thtml:47
+#: views/developers/addon_status.thtml:46
+#: views/developers/addon_edit_descriptions.thtml:47
+#: views/developers/versions_edit.thtml:47
+#: views/developers/addon_edit_categories.thtml:46
+msgid "devcp_notice_changes_saved"
+msgstr "<span>VaÅ¡e zmeny boli uložené.</span><br />Pamätajte, že niektorým zmenám môže trvaÅ¥ niekoľko hodín, kým sa prejavia vo vÅ¡etkých Äastiach stránky."
+
+#: controllers/previews_controller.php:252
+msgid "devcp_notice_cleardefault"
+msgstr "ZruÅ¡enie predvolenia spôsobí, že predvolenou ukážkou sa automaticky stane ÄalÅ¡ia ukážka."
+
+#: controllers/previews_controller.php:184
+#: controllers/previews_controller.php:251
+msgid "devcp_notice_makedefault"
+msgstr "Predvolenie ukážky zruší predvolenie aktuálnej ukážky."
+
+#: views/developers/addon_edit_authors.thtml:70
+msgid "devcp_notice_unsaved_changes"
+msgstr "Zmeny zatiaľ neboli uložené. "
+
+#: controllers/developers_controller.php:87
+#: controllers/developers_controller.php:97
+#: controllers/developers_controller.php:100
+#: controllers/previews_controller.php:67
+#: controllers/previews_controller.php:79
+#: controllers/previews_controller.php:82
+msgid "devcp_pagetitle"
+msgstr "Nástroje vývojára"
+
+#: controllers/previews_controller.php:103
+#: controllers/previews_controller.php:104
+msgid "devcp_preview_add_pagetitle"
+msgstr "Pridať ukážku"
+
+#: controllers/previews_controller.php:135
+msgid "devcp_preview_added_successfully"
+msgstr "Ukážka úspešne pridaná."
+
+#: controllers/previews_controller.php:323
+msgid "devcp_preview_deleted_successfully"
+msgstr "Ukážka úspešne odstránená."
+
+#: controllers/previews_controller.php:194
+#: controllers/previews_controller.php:195
+msgid "devcp_preview_edit_pagetitle"
+msgstr "Upraviť ukážku"
+
+#: controllers/previews_controller.php:237
+msgid "devcp_preview_updated_successfully"
+msgstr "Ukážka úspešne aktualizovaná."
+
+#: views/developers/previews.thtml:120
+msgid "devcp_previews_a_another"
+msgstr "PridaÅ¥ ÄalÅ¡iu ukážku"
+
+#: views/developers/previews.thtml:96
+msgid "devcp_previews_a_delete"
+msgstr "Odstrániť ukážku"
+
+#: views/developers/previews.thtml:95
+msgid "devcp_previews_a_replace"
+msgstr "Nahradiť ukážku"
+
+#: views/developers/previews.thtml:126
+msgid "devcp_previews_a_update"
+msgstr "Aktualizovať ukážky"
+
+#: views/developers/previews.thtml:115
+#: views/developers/previews.thtml:124
+msgid "devcp_previews_add_new"
+msgstr "Pridanie novej ukážky"
+
+#. %s is a list of file extensions, e.g. ".png, .gif"
+#: views/developers/previews.thtml:116
+msgid "devcp_previews_add_select"
+msgstr "Zvoľte obrázok, ktorý chcete odoslaÅ¥. VeľkosÅ¥ obrázkov väÄších ako 700 bodov na šírku a 525 bodov na výšku bude upravená. Povolené typy súborov: %s"
+
+#: views/developers/previews.thtml:121
+msgid "devcp_previews_click_below"
+msgstr "Kliknutím na tlaÄidlo AktualizovaÅ¥ ukážky odoÅ¡lete súbory."
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/previews.thtml:102
+msgid "devcp_previews_click_update"
+msgstr "Kliknutím na tlaÄidlo AktualizovaÅ¥ ukážky uložíte tento obrázok. (<a %s>ZruÅ¡iÅ¥?</a>)"
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/previews.thtml:107
+msgid "devcp_previews_error_message"
+msgstr "Táto ukážka bude odstránená po kliknutí na tlaÄidlo AktualizovaÅ¥ ukážky. (<a %s>ZruÅ¡iÅ¥?</a>)"
+
+#: views/previews/add.thtml:45
+msgid "devcp_previews_filetype_info"
+msgstr "Na odoslanie snímky svojho doplnku vo formáte PNG, JPG alebo GIF použite dole uvedený formulár. Veľkosť obrázkov širších ako 700 bodov a vyšších ako 525 bodov bude automaticky zmenená."
+
+#: views/previews/add.thtml:43
+msgid "devcp_previews_header_add"
+msgstr "Pridať ukážku"
+
+#: views/developers/previews.thtml:80
+msgid "devcp_previews_header_caption"
+msgstr "Popis ukážky"
+
+#: views/previews/edit.thtml:43
+msgid "devcp_previews_header_edit"
+msgstr "Upraviť ukážku"
+
+#: views/developers/previews.thtml:93
+msgid "devcp_previews_label_default"
+msgstr "Predvolená ukážka"
+
+#: views/previews/add.thtml:54
+msgid "devcp_previews_label_file"
+msgstr "Súbor ukážky"
+
+#: views/previews/add.thtml:59
+#: views/previews/edit.thtml:50
+msgid "devcp_previews_label_makedefault"
+msgstr "Predvoliť ako obrázok ukážky"
+
+#: views/developers/previews.thtml:100
+msgid "devcp_previews_label_new"
+msgstr "Nový obrázok:"
+
+#: views/developers/previews.thtml:118
+msgid "devcp_previews_label_upload"
+msgstr "Odoslať ukážku: "
+
+#: views/developers/previews.thtml:50
+msgid "devcp_previews_notice_error"
+msgstr "Jedna alebo viaceré ukážky nemohlo byť uložených."
+
+#: views/developers/previews.thtml:47
+msgid "devcp_previews_notice_success"
+msgstr "Ukážky boli úspešne aktualizované."
+
+#: views/developers/previews.thtml:59
+msgid "devcp_previews_p_screenshots"
+msgstr "Obrázky ukážok vášho doplnku sú zobrazené nižšie. Nižšie môžete takisto zmeniť ich menovky alebo aj jednotlivé obrázky. Predvolená ukážka je obrázok, ktorý sa zobrazuje vedľa názvu doplnku v zoznamoch a výsledkoch vyhľadávania."
+
+#: views/previews/edit.thtml:55
+msgid "devcp_previews_submit_delete"
+msgstr "Odstrániť ukážku"
+
+#: views/previews/edit.thtml:55
+msgid "devcp_previews_submit_delete_confirm"
+msgstr "Naozaj chcete odstrániť túto ukážku?"
+
+#: views/previews/edit.thtml:54
+msgid "devcp_previews_submit_edit"
+msgstr "Upraviť ukážku"
+
+#: views/previews/add.thtml:63
+msgid "devcp_previews_submit_upload"
+msgstr "Odoslať ukážku"
+
+#: views/developers/previews.thtml:78
+msgid "devcp_previews_thumbnail"
+msgstr "Miniatúra"
+
+#. %s is the add-on name.
+#: views/developers/previews.thtml:44
+msgid "devcp_previews_title"
+msgstr "Správca ukážok doplnku %s"
+
+#: views/developers/uploader.thtml:74
+msgid "devcp_review_agreement_please"
+msgstr "Pred pokraÄovaním si preÄítajte a prijmite nasledujúcu Vývojársku zmluvu."
+
+#: views/elements/developers/rolecheck.thtml:42
+msgid "devcp_rolecheck_no_privs"
+msgstr "<span>Nemáte dostatoÄné oprávnenia na vykonanie zmien na tejto stránke.</span><br />Ak potrebujete vykonaÅ¥ nejaké zmeny, kontaktujte vlastníka doplnku."
+
+#: controllers/developers_controller.php:1315
+msgid "devcp_several_hours"
+msgstr "Pamätajte, že niektorým zmenám môže trvaÅ¥ niekoľko hodín, kým sa objavia vo vÅ¡etkých Äastiach stránky."
+
+#: views/elements/developers/sidebar.thtml:52
+msgid "devcp_sidebar_a_dashboard"
+msgstr "Ovládací panel"
+
+#. %s is a number
+#: views/elements/developers/statsbar.thtml:45
+#: views/developers/dashboard.thtml:79
+#, php-format
+msgid "devcp_statsbar_adu"
+msgstr "Aktívni denní používatelia: <em>%s</em>"
+
+#. %s is a number
+#: views/elements/developers/statsbar.thtml:41
+#: views/developers/dashboard.thtml:75
+#, php-format
+msgid "devcp_statsbar_total_downloads"
+msgstr "Prevzatí celkom: <em>%s</em>"
+
+#. %s is a number
+#: views/elements/developers/statsbar.thtml:43
+#: views/developers/dashboard.thtml:77
+#, php-format
+msgid "devcp_statsbar_weekly_downloads"
+msgstr "Prevzatí za týždeň: <em>%s</em>"
+
+#: views/developers/addon_status_confirm.thtml:59
+msgid "devcp_status_confirm_active"
+msgstr "OznaÄenie tohto doplnku ako aktívny spôsobí, že doplnok bude zobrazený vo verejne dostupných zoznamoch, vrátane výsledkov vyhľadávania a zoznamu doplnkov. Bude ho možné prevziaÅ¥ z webovej stránky a dostupné budú aj jeho aktualizácie. Ak budete chcieÅ¥, môžete sa sem vrátiÅ¥ a opätovne ho deaktivovaÅ¥."
+
+#: views/developers/addon_status_confirm.thtml:59
+msgid "devcp_status_confirm_active_sure"
+msgstr "Naozaj chcete oznaÄiÅ¥ tento doplnok ako aktívny?"
+
+#: views/developers/addon_status_confirm.thtml:50
+msgid "devcp_status_confirm_header_sure"
+msgstr "Ste si istý?"
+
+#: views/developers/addon_status_confirm.thtml:55
+msgid "devcp_status_confirm_inactive"
+msgstr "OznaÄenie tohto doplnku ako neaktívny spôsobí, že doplnok nebude zobrazený vo verejne dostupných zoznamoch, vrátane výsledkov vyhľadávania a zoznamu doplnkov. Nebude ho možné prevziaÅ¥ z webovej stránky a nebudú dostupné ani jeho aktualizácie. Ak budete chcieÅ¥, môžete sa sem vrátiÅ¥ a opätovne ho aktivovaÅ¥."
+
+#: views/developers/addon_status_confirm.thtml:55
+msgid "devcp_status_confirm_inactive_sure"
+msgstr "Naozaj chcete oznaÄiÅ¥ tento doplnok ako neaktívny?"
+
+#: views/developers/addon_status_confirm.thtml:74
+msgid "devcp_status_confirm_no"
+msgstr "Nie, zrušiť"
+
+#: views/developers/addon_status_confirm.thtml:67
+msgid "devcp_status_confirm_public"
+msgstr "OznaÄením tohto doplnku ako verejný ho sprístupníte vÅ¡etkým používateľom, bude ho možné prevziaÅ¥ zo stránky a takisto bude dostupný cez aktualizaÄný mechanizmus."
+
+#: views/developers/addon_status_confirm.thtml:67
+msgid "devcp_status_confirm_public_sure"
+msgstr "Naozaj chcete nastaviť tento doplnok ako verejný?"
+
+#: views/developers/addon_status_confirm.thtml:63
+msgid "devcp_status_confirm_sandbox"
+msgstr "Presunutie doplnku späť do Sandboxu spôsobí, že používatelia sa budú musieť prihlásiť, ak si budú chcieť túto verziu nainštalovať. Existujúcim používateľom nebude ponúknutá aktualizácia na túto verziu. Pretože váš doplnok je aktuálne uverejnený, budete ho môcť nastaviť ako verejný kedykoľvek sa rozhodnete."
+
+#: views/developers/addon_status_confirm.thtml:63
+msgid "devcp_status_confirm_sandbox_sure"
+msgstr "Naozaj chcete presunúť tento doplnok do sandboxu?"
+
+#: views/developers/addon_status_confirm.thtml:73
+msgid "devcp_status_confirm_yes"
+msgstr "Ãno, urÄite"
+
+#: views/developers/addon_status_nominate.thtml:46
+msgid "devcp_status_nominate_error_notice"
+msgstr "<span>Vyžadovaná je správa pre nomináciu.</span><br />Prosím, vyplňte textové pole požadovanými informáciami a skúste to znova."
+
+#: views/developers/addon_status_nominate.thtml:55
+msgid "devcp_status_nominate_header"
+msgstr "Nominovanie doplnku"
+
+#: views/developers/dashboard.thtml:85
+msgid "devcp_summary_lastversion"
+msgstr "Najnovšia verzia:"
+
+#. %s is the add-on name.
+#: views/developers/addon_edit.thtml:43
+#: views/developers/addon_edit_authors.thtml:44
+#: views/developers/versions_delete.thtml:43
+#: views/developers/addon_edit_properties.thtml:44
+#: views/developers/addon_edit_descriptions.thtml:44
+#: views/developers/versions_edit.thtml:44
+#: views/developers/addon_edit_categories.thtml:43
+#: views/developers/versions.thtml:43
+msgid "devcp_title_edit_addon"
+msgstr "Úprava doplnku %s"
+
+#. title attribute for a javascript link that pops up a help dialog.
+#: views/elements/translationbox.thtml:68
+msgid "devcp_transbox_a_title_help"
+msgstr "Pomocník (neopustíte túto stránku)"
+
+#: views/elements/translationbox.thtml:68
+msgid "devcp_transbox_alt_help"
+msgstr "Pomocník"
+
+#. %1$s is <span>17</span>, %2$s is 42.
+#: views/elements/translationbox.thtml:101
+msgid "devcp_transbox_chars_used"
+msgstr "PoÄet využitých znakov: %1$s / %2$s"
+
+#: views/elements/translationbox.thtml:132
+msgid "devcp_transbox_delete_sure"
+msgstr "Naozaj chcete odstrániť tento preklad?"
+
+#. %s is a locale, like en-US.
+#: views/elements/translationbox.thtml:143
+msgid "devcp_transbox_help_header_tabs"
+msgstr "Čo sú karty pomenované '%s'?"
+
+#: views/elements/translationbox.thtml:145
+msgid "devcp_transbox_help_header_what"
+msgstr "Čo ak neposkytnem žiadne preklady?"
+
+#: views/elements/translationbox.thtml:147
+msgid "devcp_transbox_help_hide"
+msgstr "Skryť pomocníka"
+
+#: views/elements/translationbox.thtml:146
+msgid "devcp_transbox_help_if"
+msgstr "Ak používateľ prehliada stránku doplnku a táto nie je dostupná v jeho jazyku, bude zobrazená v jazyku, ktorý urÄí autor doplnku v nastavení Predvolený jazyk v sekcii UpraviÅ¥ doplnok - Vlastnosti. Ak neposkytujete preklad do žiadneho jazyka, jednoducho zvoľte ako predvolený jazyk ten, ktorým hovoríte vy."
+
+#: views/elements/translationbox.thtml:144
+msgid "devcp_transbox_help_transbox"
+msgstr "Toto je <i>LokalizaÄné pole</i>. Umožňuje preložiÅ¥ informaÄné texty o doplnku do rôznych jazykov. Jednotlivé preklady môžete pridávaÅ¥, upravovaÅ¥ a odstraňovaÅ¥ pomocou kariet jednotlivých jazykov."
+
+#: views/elements/translationbox.thtml:85
+msgid "devcp_transbox_img_add_trans"
+msgstr "Pridať preklad"
+
+#: views/elements/translationbox.thtml:86
+msgid "devcp_transbox_img_remove_trans"
+msgstr "Odstrániť preklad"
+
+#: views/elements/translationbox.thtml:123
+msgid "devcp_transbox_input_add_all"
+msgstr "Pridať jazyk do všetkých polí"
+
+#: views/elements/translationbox.thtml:122
+msgid "devcp_transbox_input_add_locale"
+msgstr "Pridať jazyk"
+
+#: views/elements/translationbox.thtml:124
+#: views/elements/translationbox.thtml:135
+msgid "devcp_transbox_input_cancel"
+msgstr "Zrušiť"
+
+#: views/elements/translationbox.thtml:134
+msgid "devcp_transbox_input_delete"
+msgstr "Odstrániť"
+
+#: views/elements/translationbox.thtml:113
+msgid "devcp_transbox_select_locale"
+msgstr "Zvoľte jazyk, ktorý chcete pridať:"
+
+#. %1$s and %2$s are GUIDs.
+#: controllers/developers_controller.php:343
+msgid "devcp_update_addon_guid_error"
+msgstr "Identifikátor GUID použitý v tomto súbore (%1$s) nezodpovedá existujúcemu GUID tohto doplnku (%2$s)."
+
+#: controllers/developers_controller.php:334
+msgid "devcp_update_addon_priv_error"
+msgstr "Nemáte dostatoÄné oprávnenia na aktualizovanie tohto doplnku."
+
+#. %1$s is a version number, %2$s is an add-on ID.
+#: controllers/developers_controller.php:399
+msgid "devcp_update_addon_version_belong_error"
+msgstr "Zvolená verzia (%1$s) nepatrí k tomuto doplnku (%2$s)."
+
+#. %1$s is a version number, maybe 1.1.
+#. %2$s is a URL.
+#: controllers/developers_controller.php:351
+msgid "devcp_update_addon_version_exists_error"
+msgstr "Číslo odosielanej verzie (%1$s) už pre tento prvok existuje. Ak sa pokúšate pre túto verziu pridaÅ¥ Äalší súbor, <a href=\"%2$s\">kliknite sem</a>."
+
+#. %1$s and %2$s are version numbers.
+#: controllers/developers_controller.php:405
+msgid "devcp_update_addon_version_match_error"
+msgstr "Číslo odosielanej verzie (%1$s) sa nezhoduje s existujúcim Äíslom verzie (%2$s)."
+
+#: views/developers/uploader.thtml:68
+msgid "devcp_uploader_a_start"
+msgstr "ZaÄíname"
+
+#: views/developers/uploader.thtml:137
+msgid "devcp_uploader_ajax_loading"
+msgstr "Odosiela sa súbor…"
+
+#: views/developers/uploader.thtml:82
+msgid "devcp_uploader_button_agree"
+msgstr "SúhlasiÅ¥ a pokraÄovaÅ¥"
+
+#: views/developers/uploader.thtml:157
+msgid "devcp_uploader_button_edit"
+msgstr "Upraviť môj doplnok"
+
+#: views/developers/uploader.thtml:158
+msgid "devcp_uploader_button_later"
+msgstr "Môj doplnok dokonÄím neskôr."
+
+#: views/developers/uploader.thtml:168
+msgid "devcp_uploader_button_release"
+msgstr "Pridať Poznámky k vydaniu"
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/uploader.thtml:156
+msgid "devcp_uploader_created_results"
+msgstr "<p>Stránka vášho doplnku bola vytvorená. Základné údaje získané z vášho doplnku boli uložené v databáze, sami vÅ¡ak môžete uviesÅ¥ oveľa viac údajov a nastavení.</p><p>Váš doplnok je momentálne oznaÄený ako <strong>nekompletný</strong>. Ak ho chcete dokonÄiÅ¥, musíte sa uistiÅ¥, že má správne vyplnený názov, súhrn a popis, ako aj zvolenú aspoň jednu kategóriu, do ktorej patrí. Informácie o doplnku môžete zmeniÅ¥ kliknutím na nižšie uvedený odkaz, stav doplnku si môžete vždy skontrolovaÅ¥ na stránke <a %s>Stav doplnku</a>."
+
+#: views/developers/uploader.thtml:143
+msgid "devcp_uploader_error_correct"
+msgstr "Prosím, opravte tento problém a odošlite súbor znova."
+
+#. %1$s is a version number, %2$s is a status, e.g Public or Incomplete.
+#: views/developers/uploader.thtml:175
+msgid "devcp_uploader_file_created"
+msgstr "Váš nový súbor bol pridaný k verzii %1$s a je aktuálne oznaÄený ako %2$s."
+
+#: views/developers/uploader.thtml:154
+msgid "devcp_uploader_header_created"
+msgstr "Doplnok vytvorený!"
+
+#: views/developers/uploader.thtml:141
+msgid "devcp_uploader_header_error"
+msgstr "Oops! S týmto súborom sa vyskytol nejaký problém…"
+
+#: views/developers/uploader.thtml:173
+msgid "devcp_uploader_header_file_added"
+msgstr "Súbor pridaný!"
+
+#: views/developers/uploader.thtml:66
+msgid "devcp_uploader_header_how"
+msgstr "Ako to funguje?"
+
+#. %s is the version number, e.g. 3.2.
+#: views/developers/uploader.thtml:163
+msgid "devcp_uploader_header_update_created"
+msgstr "Verzia %s vytvorená"
+
+#: views/developers/uploader.thtml:117
+msgid "devcp_uploader_header_upload"
+msgstr "Odoslanie nového súboru"
+
+#: views/developers/uploader.thtml:67
+msgid "devcp_uploader_how"
+msgstr "<p>ÄŽakujeme, že ste sa rozhodli odoslaÅ¥ váš doplnok do databázy servera Mozilla Add-ons. Umiestnenie doplnku na serveroch Mozilla Add-ons je najjednoduchší spôsob distribúcie vášho doplnku. Odoslaním doplnku získavate:</p><ul><li>Každý doplnok má svoju vlastnú verejnú stránku s informáciami, ktoré sami poskytnete, ako krátky opis funkcionality doplnku, voliteľný dlhší popis a obrázky s ukážkami doplnku.</li><li>Váš doplnok sa zobrazí v zoznamoch a výsledkoch vyhľadávania na stránke Mozilla Addons a takisto v Správcovi doplnkov prehliadaÄa Firefox 3.</li><li>ZabezpeÄíme hosting pre vÅ¡etky vaÅ¡e súbory a keÄ sprístupníte novú verziu, poskytneme aktualizácie existujúcim používateľom doplnku.</li><li>Umožníme vám prístup k detailným Å¡tatistikám používanosti vášho doplnku.</li></ul><p>VÅ¡etky doplnky umiestnené na serveroch Mozilla Add-ons musia byÅ¥ pred získaním vÅ¡etkých spomenutých výhod skontrolované editorom. Ak chcete pokraÄovaÅ¥ a máte svoj doplnok pripravený na odoslanie, jednoducho kliknite na tlaÄidlo ZaÄíname!</p>"
+
+#: views/developers/uploader.thtml:125
+msgid "devcp_uploader_label_platformtype"
+msgstr "Podporované platformy:"
+
+#: views/developers/uploader.thtml:124
+msgid "devcp_uploader_label_upload_field"
+msgstr "Súbor doplnku: "
+
+#: controllers/components/developers.php:1221
+msgid "devcp_uploader_option_other"
+msgstr "Iné"
+
+#. %1$s is a number, %2$s is href="..." and should stay in the <a> tag.
+#: views/developers/uploader.thtml:176
+msgid "devcp_uploader_p_pending_file"
+msgstr "Nový súbor bude verejne dostupný po kontrole editorom. Vo fronte Äaká na kontrolu niekoľko doplnkov súborov (celkom %1$s). Chcete urýchliÅ¥ kontrolu? <a %2$s>Staňte sa editorom</a>."
+
+#. %1$s is a number, %2$s is href="..." and should stay in the <a> tag.
+#: views/developers/uploader.thtml:166
+msgid "devcp_uploader_p_pending_version"
+msgstr "Nová verzia bude verejne dostupná po kontrole editorom. Vo fronte Äaká na kontrolu niekoľko doplnkov (celkom %1$s). Chcete urýchliÅ¥ kontrolu? <a %2$s>Staňte sa editorom</a>."
+
+#. %s is a status, e.g Public or Incomplete.
+#: views/developers/uploader.thtml:165
+msgid "devcp_uploader_p_update_created"
+msgstr "Nová verzia bola úspeÅ¡ne vytvorená a doplnok tejto verzie je oznaÄený ako %s."
+
+#. %1$s is href="..." and should stay in the 'Versions and Files' <a> tag.
+#. %2$s is href="..." and should stay in the 'current status' <a> tag.
+#: views/developers/uploader.thtml:177
+msgid "devcp_uploader_p_update_file"
+msgstr "Nový súbor nájdete v sekcii <a %1$s>Verzie s súbory</a>, skontrolujte jeho <a %2$s>aktuálny stav</a>, prípadne kliknutím na nižšie uvedené tlaÄidlo <b>pridajte poznámky k vydaniu</b> (odporúÄané)."
+
+#. %1$s is href="..." and should stay in the 'Versions and Files' <a> tag.
+#. %2$s is href="..." and should stay in the 'current status' <a> tag.
+#: views/developers/uploader.thtml:167
+msgid "devcp_uploader_p_update_version"
+msgstr "Novú verziu nájdete v sekcii <a %1$s>Verzie s súbory</a>, skontrolujte jeho <a %2$s>aktuálny stav</a>, prípadne kliknutím na nižšie uvedené tlaÄidlo <b>pridajte poznámky k vydaniu</b> (odporúÄané)."
+
+#: views/developers/uploader.thtml:118
+msgid "devcp_uploader_p_upload"
+msgstr "Súbor doplnku odošlite pomocou tohto formulára. Ak máte niekoľko rôznych súborov pre rôzne platformy, zvoľte jeden súbor a následne odošlite ostatné pomocou Správcu verzií a súborov."
+
+#: views/developers/uploader.thtml:125
+msgid "devcp_uploader_platformtype_all"
+msgstr "VÅ¡etky"
+
+#: views/developers/uploader.thtml:126
+msgid "devcp_uploader_platformtype_specific"
+msgstr "Špecifická:"
+
+#. Used as first item in a <select>.
+#: controllers/components/developers.php:1185
+msgid "devcp_uploader_please_choose"
+msgstr "Zvoľte..."
+
+#. %1$s is the add-on name, %2$s is the version number.
+#: views/developers/uploader.thtml:57
+msgid "devcp_uploader_title_file"
+msgstr "Pridať súbor k %1$s %2$s"
+
+#: views/developers/uploader.thtml:50
+msgid "devcp_uploader_title_submit"
+msgstr "Odoslanie nového doplnku"
+
+#. %s is the add-on name.
+#: views/developers/uploader.thtml:54
+msgid "devcp_uploader_title_update"
+msgstr "Aktualizácia doplnku %s"
+
+#. %s is a full <a> tag
+#: controllers/developers_controller.php:503
+#, php-format
+msgid "devcp_valid_app_reference"
+msgstr "Pozrite %s."
+
+#. This is the text in the <a> tag for devcp_valid_app_reference. This should be
+#. fixed.
+#: controllers/developers_controller.php:503
+msgid "devcp_valid_app_reference_linktext"
+msgstr "túto stránku"
+
+#: controllers/developers_controller.php:581
+msgid "devcp_verify_author_error"
+msgstr "Pre zadanú e-mailovú adresu nebol nájdený žiadny úÄet."
+
+#: controllers/developers_controller.php:553
+msgid "devcp_verify_search_engine_error"
+msgstr "Súbor XML je buÄ neplatný alebo chýbajú požadované polia. Prosím, <a href=\"https://developer.mozilla.org/en/Creating_OpenSearch_plugins_for_Firefox\">preÄítajte si dokumentáciu</a>, overte váš add-on a skúste to znova."
+
+#: views/developers/versions.thtml:75
+msgid "devcp_versions_a_cancel"
+msgstr "Zrušiť"
+
+#: views/developers/versions.thtml:79
+msgid "devcp_versions_a_delete"
+msgstr "Odstrániť verziu"
+
+#: views/developers/versions.thtml:74
+msgid "devcp_versions_a_empty"
+msgstr "Odstrániť prázdnu verziu"
+
+#: views/developers/versions.thtml:71
+msgid "devcp_versions_a_remove"
+msgstr "Odstrániť?"
+
+#: views/developers/versions.thtml:91
+msgid "devcp_versions_add"
+msgstr "Pridať novú verziu"
+
+#: views/developers/versions_delete.thtml:58
+msgid "devcp_versions_delete_a_cancel"
+msgstr "Zrušiť"
+
+#: views/developers/versions_delete.thtml:56
+msgid "devcp_versions_delete_a_delete"
+msgstr "Odstrániť verziu"
+
+#. Followed by a list of reviews and files that will be removed.
+#: views/developers/versions_delete.thtml:50
+msgid "devcp_versions_delete_also"
+msgstr "Týmto odstránite tiež:"
+
+#: views/developers/versions_delete.thtml:53
+msgid "devcp_versions_delete_files"
+msgid_plural "devcp_versions_delete_files"
+msgstr[0] "%s súbor"
+msgstr[1] "%s súbory"
+msgstr[2] "%s súborov"
+
+#. %s is the version number.
+#: views/developers/versions_delete.thtml:48
+msgid "devcp_versions_delete_header"
+msgstr "Odstrániť verziu %s?"
+
+#: views/developers/versions_delete.thtml:52
+msgid "devcp_versions_delete_reviews"
+msgid_plural "devcp_versions_delete_reviews"
+msgstr[0] "%s recenziu"
+msgstr[1] "%s recenzie"
+msgstr[2] "%s recenzií"
+
+#. %s is the version number.
+#: views/developers/versions_delete.thtml:49
+msgid "devcp_versions_delete_sure"
+msgstr "Naozaj chcete natrvalo odstrániť verziu %s?"
+
+#: views/developers/versions_edit.thtml:102
+#: views/developers/versions_edit.thtml:155
+msgid "devcp_versions_edit_a_cancel"
+msgstr "Zrušiť"
+
+#: views/developers/versions_edit.thtml:101
+msgid "devcp_versions_edit_a_delete"
+msgstr "Odstrániť súbor"
+
+#: views/developers/versions_edit.thtml:165
+msgid "devcp_versions_edit_a_new_app"
+msgstr "Pridať novú aplikáciu"
+
+#: views/developers/versions_edit.thtml:154
+msgid "devcp_versions_edit_a_remove_app"
+msgstr "Odstrániť aplikáciu"
+
+#: views/developers/versions_edit.thtml:114
+msgid "devcp_versions_edit_add"
+msgstr "Pridať novú verziu"
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/versions_edit.thtml:121
+msgid "devcp_versions_edit_adjust"
+msgstr "Upravenie údajov o kompatibilných verziách umožní používateľom nainštalovať vaše rozšírenie aj v prípade, ak nie je v súbore install.rdf uvedená kompatibilita s danou verziou programu. <a %s>Zoznam podporovaných aplikácií</a>."
+
+#: views/developers/versions_edit.thtml:153
+msgid "devcp_versions_edit_compat_sure"
+msgstr "<b>Naozaj</b> chcete odstrániť kompatibilitu s touto aplikáciou?"
+
+#: views/developers/versions_edit.thtml:100
+msgid "devcp_versions_edit_delete_sure"
+msgstr "<b>Naozaj</b> chcete natrvalo odstrániť tento súbor?"
+
+#: views/developers/versions_edit.thtml:203
+msgid "devcp_versions_edit_header_approval"
+msgstr "Informácie o schválení doplnku"
+
+#: views/developers/versions_edit.thtml:120
+msgid "devcp_versions_edit_header_compat"
+msgstr "Kompatibilné aplikácie"
+
+#: views/developers/versions_edit.thtml:74
+msgid "devcp_versions_edit_header_file"
+msgstr "Informácie o súbore"
+
+#: views/developers/versions_edit.thtml:189
+msgid "devcp_versions_edit_header_license"
+msgstr "Licencia"
+
+#. %s is the version number.
+#: views/developers/versions_edit.thtml:53
+msgid "devcp_versions_edit_header_manage"
+msgstr "Správa verzie %s"
+
+#: views/developers/versions_edit.thtml:212
+msgid "devcp_versions_edit_header_notes"
+msgstr "Poznámky k schváleniu doplnku"
+
+#: views/developers/versions_edit.thtml:98
+msgid "devcp_versions_edit_img_delete"
+msgstr "Odstrániť súbor"
+
+#. %1$s is the file id, e.g. 18723.
+#. %2$s is the platform name, e.g. ALL or Windows.
+#. %3$s is the _('date) created.
+#. %4$s is the status, e.g. "In Sandbox" or "Public".
+#. %5$s is the _('date') status was changed.
+#: views/developers/versions_edit.thtml:208
+msgid "devcp_versions_edit_li_file"
+msgstr "Súbor %1$s (%2$s) vytvorený dňa %3$s, stav '%4$s' nastavený dňa %5$s"
+
+#: views/developers/versions_edit.thtml:190
+msgid "devcp_versions_edit_license_description"
+msgstr "Zvoľte vhodnú licenciu pre váš doplnok. Táto licencia urÄuje práva, ktoré urÄujete pre zdrojový kód."
+
+#: views/developers/versions_edit.thtml:111
+msgid "devcp_versions_edit_no_files"
+msgstr "Neboli nájdené žiadne súbory."
+
+#: views/developers/versions_edit.thtml:213
+msgid "devcp_versions_edit_optional"
+msgstr "Voliteľné informácie pre editora, ktorý bude kontrolovať túto verziu."
+
+#: views/developers/versions_edit.thtml:151
+msgid "devcp_versions_edit_remove_compat"
+msgstr "Odstrániť kompatibilitu s aplikáciou"
+
+#: views/developers/versions_edit.thtml:167
+msgid "devcp_versions_edit_select_app"
+msgstr "Zvoľte aplikáciu"
+
+#: views/developers/versions_edit.thtml:78
+msgid "devcp_versions_edit_th_file"
+msgstr "Súbor"
+
+#: views/developers/versions_edit.thtml:79
+msgid "devcp_versions_edit_th_platform"
+msgstr "Platforma"
+
+#: views/developers/versions_edit.thtml:80
+msgid "devcp_versions_edit_th_size"
+msgstr "Veľkosť"
+
+#: views/developers/versions_edit.thtml:81
+msgid "devcp_versions_edit_th_status"
+msgstr "Stav"
+
+#: views/developers/versions_edit.thtml:183
+msgid "devcp_versions_edit_transbox_releasenotes_description"
+msgstr "Informácie o zmenách v tejto verzii, nové funkcie, známe chyby a ÄalÅ¡ie informácie Å¡pecifické pre túto verziu. Tieto informácie budú dostupné používateľom pri aktualizovaní verzie v Správcovi doplnkov Firefoxu 3."
+
+#: views/developers/versions_edit.thtml:182
+msgid "devcp_versions_edit_transbox_releasenotes_name"
+msgstr "Poznámky k vydaniu"
+
+#: views/developers/versions_edit.thtml:164
+msgid "devcp_versions_edit_unsaved_compat"
+msgstr "<strong>Zmeny zatiaľ neboli uložené.</strong> Kompatibilita bude odstránená až po kliknutí na tlaÄidlo AktualizovaÅ¥ verzie."
+
+#: views/developers/versions_edit.thtml:113
+msgid "devcp_versions_edit_unsaved_files"
+msgstr "<strong>Zmeny zatiaľ neboli uložené.</strong> Súbory budú odstránené až po kliknutí na tlaÄidlo AktualizovaÅ¥ verzie."
+
+#: views/developers/versions_edit.thtml:218
+msgid "devcp_versions_edit_update"
+msgstr "Aktualizovať verzie"
+
+#: views/developers/versions.thtml:49
+msgid "devcp_versions_header_manage"
+msgstr "Správa verzií a súborov"
+
+#: views/developers/versions.thtml:87
+msgid "devcp_versions_no_versions"
+msgstr "Žiadne verzie."
+
+#. %s is a version number, base 10.
+#: views/developers/versions.thtml:46
+msgid "devcp_versions_notice_success"
+msgstr "Verzia %s bola úspešne odstránená."
+
+#: views/developers/versions.thtml:73
+msgid "devcp_versions_p_remove"
+msgstr "Táto verzia nemá priradené žiadne súbory a môže byť odstránená. Chcete ju odstrániť?"
+
+#: views/developers/versions.thtml:58
+msgid "devcp_versions_th_created"
+msgstr "Vytvorená"
+
+#: views/developers/versions.thtml:57
+msgid "devcp_versions_th_status"
+msgstr "Stav"
+
+#: views/developers/versions.thtml:56
+msgid "devcp_versions_th_version"
+msgstr "Verzia"
+
+#: controllers/downloads_controller.php:91
+msgid "downloads_disable_warning"
+msgstr "Tento doplnok je zakázaný"
+
+#: controllers/components/editors.php:57
+msgid "editor_review_error_addon_not_nominated"
+msgstr "Tento doplnok ešte nebol nominovaný."
+
+#: controllers/components/editors.php:213
+msgid "editor_review_error_file_not_pending"
+msgstr "Tento súbor neÄaká na kontrolu."
+
+#. Actions are, for example: approving or rejecting
+#: controllers/components/editors.php:79
+#: controllers/components/editors.php:182
+msgid "editor_review_error_no_action"
+msgstr "Prosím, zvoľte akciu kontroly."
+
+#: controllers/components/editors.php:192
+msgid "editor_review_error_no_applications"
+msgstr "Prosím, zadajte aplikáciu, s ktorou ste testovali."
+
+#. Comments are required when an editor approves or rejects an add-on.
+#: controllers/components/editors.php:84
+#: controllers/components/editors.php:187
+msgid "editor_review_error_no_comments"
+msgstr "Prosím, zadajte komentáre ku kontrole."
+
+#: controllers/components/editors.php:161
+msgid "editor_review_error_no_files"
+msgstr "Prosím, vyberte aspoň jeden súbor na kontrolu."
+
+#: controllers/components/editors.php:197
+msgid "editor_review_error_no_operating_system"
+msgstr "Prosím, zadajte operaÄný systém, pod ktorým prebehla kontrola."
+
+#: views/editors/logs.thtml:51
+msgid "editorcp_logs_button_filter"
+msgstr "Filtrovať"
+
+#: views/editors/logs.thtml:44
+msgid "editorcp_logs_filter_by"
+msgstr "Filter podľa typu/úkonu"
+
+#: views/editors/logs.thtml:42
+#: controllers/editors_controller.php:964
+msgid "editorcp_logs_page_heading"
+msgstr "Denník udalostí"
+
+#: views/elements/developers/editorsmenu.thtml:60
+msgid "editorcp_menu_eventlog_link"
+msgstr "Denník udalostí"
+
+#: views/elements/developers/editorsmenu.thtml:62
+msgid "editorcp_menu_mainpage_link"
+msgstr "Späť na úvodnú stránku"
+
+#: views/elements/developers/editorsmenu.thtml:61
+msgid "editorcp_menu_reviewlog_link"
+msgstr "Denník recenzií"
+
+#: views/elements/developers/editorsmenu.thtml:55
+msgid "editorcp_menu_summary_link"
+msgstr "Súhrn editora"
+
+#: views/elements/developers/editorsmenu.thtml:52
+msgid "editorcp_menu_title"
+msgstr "Nástroje editora"
+
+#: views/editors/reviewlog.thtml:49
+msgid "editorcp_reviewlog_button_filter"
+msgstr "Filtrovať"
+
+#: views/editors/reviewlog.thtml:58
+msgid "editorcp_reviewlog_column_action"
+msgstr "Úkon"
+
+#: views/editors/reviewlog.thtml:56
+msgid "editorcp_reviewlog_column_addon"
+msgstr "Doplnok"
+
+#: views/editors/reviewlog.thtml:55
+msgid "editorcp_reviewlog_column_date"
+msgstr "Dátum"
+
+#: views/editors/reviewlog.thtml:57
+msgid "editorcp_reviewlog_column_editor"
+msgstr "Editor"
+
+#: views/editors/reviewlog.thtml:94
+msgid "editorcp_reviewlog_comments_hide"
+msgstr "Skryť komentáre"
+
+#: views/editors/reviewlog.thtml:93
+msgid "editorcp_reviewlog_comments_show"
+msgstr "Zobraziť komentáre"
+
+#. %1$s and %2$s are full <input> tags for dates
+#: views/editors/reviewlog.thtml:45
+#, php-format
+msgid "editorcp_reviewlog_entries_between"
+msgstr "Zobraziť položky od %1$s do %2$s"
+
+#: views/editors/reviewlog.thtml:104
+msgid "editorcp_reviewlog_none_found"
+msgstr "V tomto období nie sú žiadne recenzie."
+
+#: views/editors/reviewlog.thtml:42
+msgid "editorcp_reviewlog_page_heading"
+msgstr "Denník recenzií"
+
+#: views/editors/summary.thtml:61
+msgid "editorcp_summary_monthreviews_heading"
+msgstr "MesaÄné recenzie"
+
+#: views/editors/summary.thtml:77
+msgid "editorcp_summary_neweditors_heading"
+msgstr "Noví editori"
+
+#: views/editors/summary.thtml:42
+msgid "editorcp_summary_page_heading"
+msgstr "Súhrn editora"
+
+#: views/editors/summary.thtml:94
+msgid "editorcp_summary_recentactivity_heading"
+msgstr "Ostatná aktivita editora"
+
+#: views/editors/summary.thtml:45
+msgid "editorcp_summary_totalreviews_heading"
+msgstr "Recenzie celkom"
+
+#: controllers/editors_controller.php:248
+#: controllers/editors_controller.php:249
+msgid "editors_addon_review_pagetitle"
+msgstr "Recenzia doplnku"
+
+#: controllers/editors_controller.php:349
+msgid "editors_error_js-formerror"
+msgstr "Vyplňte nasledujúce polia:"
+
+#: controllers/editors_controller.php:350
+msgid "editors_error_review_one_file"
+msgstr "Vyberte aspoň jeden súbor na recenziu."
+
+#: controllers/editors_controller.php:274
+msgid "editors_error_self_reviews_forbidden"
+msgstr "Recenzie samým sebou nie sú dovolené."
+
+#: controllers/editors_controller.php:699
+msgid "editors_external_software"
+msgstr "Externý softvér"
+
+#: views/editors/featured.thtml:120
+#: views/editors/featured.thtml:121
+msgid "editors_featured_add_feature"
+msgstr "PridaÅ¥ medzi odporúÄané"
+
+#: views/editors/featured.thtml:126
+msgid "editors_featured_add_feature_submit"
+msgstr "Pridať"
+
+#: views/editors/featured.thtml:49
+#: controllers/editors_controller.php:832
+#: controllers/editors_controller.php:848
+msgid "editors_featured_addon_add_failure"
+msgstr "Nepodarilo sa pridaÅ¥ medzi odporúÄané."
+
+#: controllers/editors_controller.php:851
+msgid "editors_featured_addon_add_success"
+msgstr "ÚspeÅ¡ne pridané medzi odporúÄané."
+
+#: views/editors/featured.thtml:50
+#: controllers/editors_controller.php:839
+#: controllers/editors_controller.php:868
+#: controllers/editors_controller.php:886
+msgid "editors_featured_addon_edit_failure"
+msgstr "Nepodarilo sa upraviť."
+
+#: views/editors/featured.thtml:51
+#: controllers/editors_controller.php:888
+msgid "editors_featured_addon_edit_success"
+msgstr "Úspešne upravené."
+
+#: views/editors/featured.thtml:53
+#: controllers/editors_controller.php:861
+msgid "editors_featured_addon_invalid_locale"
+msgstr "Jeden alebo niekoľko jazykov je neplatných."
+
+#: views/editors/featured.thtml:52
+#: controllers/editors_controller.php:906
+msgid "editors_featured_addon_remove_failure"
+msgstr "Nepodarilo sa odstrániť."
+
+#: controllers/editors_controller.php:901
+msgid "editors_featured_addon_remove_success"
+msgstr "Úspešne odstránené."
+
+#: controllers/editors_controller.php:915
+#: controllers/editors_controller.php:917
+msgid "editors_featured_addons_pagetitle"
+msgstr "OdporúÄané doplnky"
+
+#: views/editors/featured.thtml:54
+#: views/editors/featured.thtml:107
+msgid "editors_featured_edit_feature_submit"
+msgstr "Prejsť"
+
+#: views/editors/featured.thtml:90
+#: views/editors/featured.thtml:91
+msgid "editors_featured_remove_feature"
+msgstr "OdstrániÅ¥ z odporúÄaných"
+
+#: views/editors/queue.thtml:46
+msgid "editors_filter_queue"
+msgstr "Filter frontu"
+
+#: views/editors/queue.thtml:182
+msgid "editors_helpful_links"
+msgstr "UžitoÄné odkazy"
+
+#: views/editors/queue.thtml:182
+msgid "editors_link_guide"
+msgstr "PríruÄka editora"
+
+#: views/editors/queue.thtml:182
+msgid "editors_link_policy"
+msgstr "Zásady ochrany súkromia doplnku"
+
+#: views/editors/queue.thtml:47
+msgid "editors_notice_filter_session"
+msgstr "Tieto filtre zostanú platné poÄas celej relácie alebo kým nebudú vymazané."
+
+# %1 is the queue mode
+#. %1 is the queue mode
+#: views/editors/queue.thtml:177
+#: views/admin/flagged_queue.thtml:89
+msgid "editors_notice_none_found"
+msgstr "Momentálne nie je na recenziu žiadny doplnok tohto typu."
+
+#: controllers/editors_controller.php:1040
+msgid "editors_one_day"
+msgstr "1 deň"
+
+#: controllers/editors_controller.php:1048
+msgid "editors_one_hour"
+msgstr "1 hod."
+
+#: controllers/editors_controller.php:1056
+msgid "editors_one_minute"
+msgstr "1 min."
+
+#: controllers/editors_controller.php:64
+#: controllers/editors_controller.php:73
+#: controllers/editors_controller.php:77
+msgid "editors_pagetitle"
+msgstr "Nástroje editora"
+
+#. %s is a comma separated list of platforms. Example: Windows, OS X
+#: controllers/editors_controller.php:680
+#: controllers/editors_controller.php:683
+#, php-format
+msgid "editors_platform_x_only"
+msgstr "len %s"
+
+#: controllers/editors_controller.php:695
+msgid "editors_pre-release"
+msgstr "Vývojová verzia"
+
+# %1 is the app name
+#. %1 is the app name
+#: views/editors/queue.thtml:131
+#, php-format
+msgid "editors_queue_app_compatibility"
+msgstr "Kompatibilita s programom %s"
+
+#: views/editors/queue.thtml:51
+msgid "editors_queue_filter_label_addon"
+msgstr "Doplnok alebo e-mail autora"
+
+#: views/editors/queue.thtml:72
+msgid "editors_queue_filter_label_addontypes"
+msgstr "Typy doplnku"
+
+#: views/editors/queue.thtml:56
+msgid "editors_queue_filter_label_application"
+msgstr "Aplikácia"
+
+#: views/editors/queue.thtml:61
+msgid "editors_queue_filter_label_maxversion"
+msgstr "Max. verzia"
+
+#: views/editors/queue.thtml:78
+msgid "editors_queue_filter_label_platforms"
+msgstr "Platformy"
+
+#: views/editors/queue.thtml:66
+msgid "editors_queue_filter_label_submissionage"
+msgstr "Doba od odoslania (dni)"
+
+#. %1$s is a number
+#: views/editors/queue.thtml:90
+msgid "editors_queue_filter_result_count"
+msgid_plural "editors_queue_filter_result_count"
+msgstr[0] "Výsledky filtrovaného vyhľadávania: <strong>%1$s</strong> doplnok"
+msgstr[1] "Výsledky filtrovaného vyhľadávania: <strong>%1$s</strong> doplnky"
+msgstr[2] "Výsledky filtrovaného vyhľadávania: <strong>%1$s</strong> doplnkov"
+
+#: views/editors/queue.thtml:84
+msgid "editors_queue_submit_clean"
+msgstr "Vymazať"
+
+#: views/editors/queue.thtml:83
+msgid "editors_queue_submit_filter"
+msgstr "Filtrovať"
+
+#: controllers/editors_controller.php:133
+msgid "editors_queues_disabled"
+msgstr "Všetky fronty recenzií sú momentálne zakázané. Skúste neskôr."
+
+#: views/editors/review.thtml:149
+msgid "editors_review_a_edit_item"
+msgstr "Upraviť položku"
+
+#: views/editors/review.thtml:146
+msgid "editors_review_a_item_history"
+msgstr "História položky"
+
+#: views/editors/review.thtml:148
+msgid "editors_review_a_item_homepage"
+msgstr "Domovská stránka položky"
+
+#: views/editors/review.thtml:145
+msgid "editors_review_a_item_overview"
+msgstr "Prehľad položky"
+
+#: views/editors/review.thtml:147
+msgid "editors_review_a_previews"
+msgstr "Ukážky"
+
+#: controllers/editors_controller.php:345
+msgid "editors_review_action"
+msgstr "Úkon recenzie"
+
+#: views/editors/review.thtml:159
+msgid "editors_review_action_info"
+msgstr "VyžiadaÅ¥ dodatoÄné informácie"
+
+#: views/editors/review.thtml:157
+msgid "editors_review_action_public"
+msgstr "Schváliť pre verejnosť"
+
+#: views/editors/review.thtml:160
+msgid "editors_review_action_request_superreview"
+msgstr "Požadovať super-recenziu"
+
+#: views/editors/review.thtml:158
+msgid "editors_review_action_sandbox"
+msgstr "Nechať v Sandboxe"
+
+#: controllers/editors_controller.php:346
+msgid "editors_review_comments"
+msgstr "Komentáre recenzie"
+
+#: views/editors/review.thtml:182
+msgid "editors_review_details_info_request"
+msgstr "Použite tento formulár na vyžiadanie dodatoÄných informácií od autora doplnku, ktorý obdrží e-mailovú správu a bude môcÅ¥ tu odpovedaÅ¥. Pri jeho odpovedi budete upozornený e-mailovou správou."
+
+#: views/editors/review.thtml:174
+msgid "editors_review_details_nominated_public"
+msgstr "Tým oznaÄíte doplnok a jeho najnovÅ¡iu verziu a súbory ako verejné. Budúce verzie prejdú do Sandboxu, kým sa nepodrobia recenzii editorom."
+
+#: views/editors/review.thtml:177
+msgid "editors_review_details_nominated_sandbox"
+msgstr "Týmto ponecháte doplnok v Sandboxe."
+
+#: views/editors/review.thtml:166
+msgid "editors_review_details_pending_public"
+msgstr "Tým schválite verziu zo Sandboxu nominovanú na uverejnenie, aby sa objavila na verejnej stránke. "
+
+#: views/editors/review.thtml:169
+msgid "editors_review_details_pending_sandbox"
+msgstr "Tým urÄíte, že verejný doplnok zo Sandboxu má v ňom zostaÅ¥."
+
+#: views/editors/review.thtml:185
+msgid "editors_review_details_superreview"
+msgstr "Ak máte pochybnosti o bezpeÄnosti tohto doplnku, problémoch s autorskými právami alebo iné, na ktoré by sa mal pozrieÅ¥ správca, zadajte do dole uvedenej Äasti svoje komentáre. Budú odoslané správcom, nie autorovi."
+
+#: views/editors/review.thtml:134
+msgid "editors_review_file_diff_link"
+msgstr "Porovnať s verejnou verziou"
+
+#: views/editors/review.thtml:131
+msgid "editors_review_file_viewcontents_link"
+msgstr "Zobraziť obsah"
+
+#: views/editors/review.thtml:65
+msgid "editors_review_header_authors"
+msgstr "Autori:"
+
+#: views/editors/review.thtml:79
+msgid "editors_review_header_categories"
+msgstr "Kategórie:"
+
+#: views/editors/review.thtml:92
+msgid "editors_review_header_compatibility"
+msgstr "Kompatibilita:"
+
+#: views/editors/review.thtml:251
+msgid "editors_review_header_description"
+msgstr "Popis"
+
+#: views/editors/review.thtml:275
+msgid "editors_review_header_devcomments"
+msgstr "Komentáre vývojára"
+
+#: views/editors/review.thtml:263
+msgid "editors_review_header_eula"
+msgstr "LicenÄná zmluva"
+
+#: views/editors/review.thtml:115
+msgid "editors_review_header_files"
+msgstr "Súbory:"
+
+#: views/editors/review.thtml:284
+msgid "editors_review_header_itemhistory"
+msgstr "História položky"
+
+#: views/editors/review.thtml:232
+msgid "editors_review_header_nominationmessage"
+msgstr "NominaÄná správa"
+
+#: views/editors/review.thtml:311
+msgid "editors_review_header_previews"
+msgstr "Ukážky"
+
+#: views/editors/review.thtml:269
+msgid "editors_review_header_privacy"
+msgstr "Zásady ochrany súkromia"
+
+# %1 is the addon name and version
+#. %1 is the add-on name and version
+#: views/editors/review.thtml:56
+#, php-format
+msgid "editors_review_header_review"
+msgstr "Recenzia doplnku %s"
+
+#: views/editors/review.thtml:239
+msgid "editors_review_header_reviewernotes"
+msgstr "Poznámky pre recenzenta"
+
+#: views/editors/review.thtml:245
+msgid "editors_review_header_summary"
+msgstr "Súhrn"
+
+#: views/editors/review.thtml:257
+msgid "editors_review_header_versionnotes"
+msgstr "Poznámky k verzii"
+
+#. a noun: shown in an add-on's editor review history
+#: views/elements/developers/editors_review_history_item.thtml:80
+msgid "editors_review_history_info_reply"
+msgstr "OdpoveÄ"
+
+#: views/elements/developers/editors_review_history_item.thtml:78
+msgid "editors_review_history_info_request"
+msgstr "Žiadosť o informácie"
+
+#: views/elements/developers/editors_review_history_item.thtml:62
+#: views/editors/reviewlog.thtml:77
+msgid "editors_review_history_nominated_adminreview"
+msgstr "Recenzia správcu"
+
+#: views/elements/developers/editors_review_history_item.thtml:56
+#: views/editors/reviewlog.thtml:71
+msgid "editors_review_history_nominated_approved"
+msgstr "Nominácia schválená/Verejné"
+
+#: views/elements/developers/editors_review_history_item.thtml:59
+#: views/editors/reviewlog.thtml:74
+msgid "editors_review_history_nominated_denied"
+msgstr "Nominácia zamietnutá/Sandbox"
+
+#: views/editors/review.thtml:303
+msgid "editors_review_history_nonefound"
+msgstr "Nenašli sa žiadne predchádzajúce recenzie."
+
+#: views/elements/developers/editors_review_history_item.thtml:73
+#: views/editors/reviewlog.thtml:88
+msgid "editors_review_history_pending_adminreview"
+msgstr "Recenzia správcu"
+
+#: views/elements/developers/editors_review_history_item.thtml:67
+#: views/editors/reviewlog.thtml:82
+msgid "editors_review_history_pending_approved"
+msgstr "Schválené/Verejné"
+
+#: views/elements/developers/editors_review_history_item.thtml:70
+#: views/editors/reviewlog.thtml:85
+msgid "editors_review_history_pending_denied"
+msgstr "Zamietnuté/Sandbox"
+
+#. link text in an add-on's editor review history, allowing to hide and show an information request's replies
+#. %1 is the number of replies
+#: views/elements/developers/editors_review_history_item.thtml:90
+msgid "editors_review_history_show_hide_replies"
+msgid_plural "editors_review_history_show_hide_replies"
+msgstr[0] "ZobraziÅ¥/skryÅ¥ odpoveÄ"
+msgstr[1] "Zobraziť/skryť %1$s odpovede"
+msgstr[2] "Zobraziť/skryť %1$s odpovedí"
+
+#: views/editors/review.thtml:208
+msgid "editors_review_label_applications"
+msgstr "Aplikácie:"
+
+#: views/editors/review.thtml:196
+msgid "editors_review_label_cannedresponse"
+msgstr "alebo vyberte pripravenú odpoveÄ:"
+
+#: views/editors/review.thtml:190
+msgid "editors_review_label_comments"
+msgstr "Komentáre:"
+
+#: views/editors/review.thtml:204
+msgid "editors_review_label_operating_systems"
+msgstr "OperaÄné systémy:"
+
+#: views/editors/review.thtml:285
+#: views/editors/review.thtml:312
+msgid "editors_review_link_pagetop"
+msgstr "Navrch"
+
+#: views/editors/review.thtml:141
+msgid "editors_review_mulitple_notice"
+msgstr "Poznámka: recenziu pre viac súborov píšte len pre vtedy, ak ste testovali KAŽDà zvolený súbor."
+
+#: views/editors/review.thtml:51
+msgid "editors_review_next_link"
+msgstr "Äalší &raquo;"
+
+#: views/editors/review.thtml:322
+msgid "editors_review_previews_notfound"
+msgstr "Žiadne ukážky sa nenašli."
+
+#: views/editors/review.thtml:50
+msgid "editors_review_previous_link"
+msgstr "&laquo; predchádzajúci"
+
+#: controllers/editors_controller.php:144
+#: controllers/editors_controller.php:146
+msgid "editors_review_queue_pagetitle"
+msgstr "Front recenzií"
+
+# %1 is the add-ons rank in the queue, %2 is the total queue length
+#. %1 is the add-ons rank in the queue, %2 is the total queue length
+#: views/editors/review.thtml:47
+msgid "editors_review_rank_in_queue"
+msgstr "<strong>Ä. %1$s</strong> z %2$s vo fronte"
+
+#. %1 is the add-ons rank in the queue, %2 is the total queue length. Both numbers
+#: views/editors/review.thtml:45
+msgid "editors_review_rank_in_queue_filtered"
+msgstr "<strong># %1$s</strong> z %2$s vo fronte (filtrované)"
+
+#: views/editors/review.thtml:223
+msgid "editors_review_submit_process_action"
+msgstr "Spracovať úkon"
+
+#: views/editors/review.thtml:293
+msgid "editors_review_th_action"
+msgstr "Úkon"
+
+#: views/editors/review.thtml:294
+msgid "editors_review_th_comments"
+msgstr "Komentáre"
+
+#: views/editors/review.thtml:291
+msgid "editors_review_th_date"
+msgstr "Dátum"
+
+#: views/editors/review.thtml:292
+msgid "editors_review_th_reviewer"
+msgstr "Recenzent"
+
+#: views/editors/review.thtml:290
+msgid "editors_review_th_version_file"
+msgstr "Verzia/Súbor"
+
+#: views/editors/review.thtml:217
+msgid "editors_review_update_notify_once"
+msgstr "Upozorniť ma pri nasledujúcej aktualizácii tohto doplnku. (Ďalšie aktualizácie nevygenerujú e-mailovú správu)"
+
+#: controllers/editors_controller.php:298
+msgid "editors_reviewed_successfully"
+msgstr "Recenzia úspešne spracovaná."
+
+#: views/editors/reviews_queue.thtml:106
+msgid "editors_reviews_action_delete_review"
+msgstr "Odstrániť recenziu"
+
+#: views/editors/reviews_queue.thtml:104
+msgid "editors_reviews_action_keep"
+msgstr "Odstrániť nahlásenie; ponechať recenziu"
+
+#: views/editors/reviews_queue.thtml:102
+msgid "editors_reviews_action_skip"
+msgstr "PreskoÄiÅ¥"
+
+#: views/editors/reviews_queue.thtml:100
+msgid "editors_reviews_header_action"
+msgstr "Úkon"
+
+#: views/editors/reviews_queue.thtml:67
+msgid "editors_reviews_in_reply_to"
+msgstr "V odpovedi na:"
+
+#: controllers/editors_controller.php:748
+msgid "editors_reviews_processed"
+msgstr "Recenzie úspešne spracované!"
+
+#: views/editors/reviews_queue.thtml:117
+msgid "editors_reviews_queue_empty"
+msgstr "V moderovaní nie sú momentálne žiadne recenzie."
+
+#: views/editors/reviews_queue.thtml:111
+msgid "editors_reviews_submit_process_reviews"
+msgstr "Spracovať recenzie"
+
+#: controllers/editors_controller.php:691
+msgid "editors_site_specific"
+msgstr "Pre špecifickú stránku"
+
+#: controllers/editors_controller.php:348
+msgid "editors_tested_app"
+msgstr "Testované aplikácie"
+
+#: controllers/editors_controller.php:347
+msgid "editors_tested_os"
+msgstr "Testované operaÄné systémy"
+
+#: views/editors/queue.thtml:151
+msgid "editors_th_additional_info"
+msgstr "Ďalšie informácie"
+
+#: views/editors/featured.thtml:63
+#: views/editors/queue.thtml:109
+#: views/admin/flagged_queue.thtml:53
+msgid "editors_th_addon"
+msgstr "Doplnok"
+
+#: views/editors/queue.thtml:125
+msgid "editors_th_addontype"
+msgstr "Typ"
+
+#: views/editors/featured.thtml:64
+msgid "editors_th_locales"
+msgstr "Obmedziť na jazyky?"
+
+#: views/editors/queue.thtml:148
+msgid "editors_th_nomination_age"
+msgstr "Doba vo fronte"
+
+#: views/editors/queue.thtml:101
+#: views/editors/queue.thtml:117
+#: views/editors/queue.thtml:144
+msgid "editors_th_sort_ascending"
+msgstr "Vzostupné zoradenie"
+
+#: views/editors/queue.thtml:105
+#: views/editors/queue.thtml:121
+#: views/editors/queue.thtml:140
+msgid "editors_th_sort_descending"
+msgstr "Zostupné zoradenie"
+
+#. %s is a number
+#: controllers/editors_controller.php:1036
+#, php-format
+msgid "editors_x_days"
+msgstr "%s dní"
+
+#. %s is a number
+#: controllers/editors_controller.php:1044
+#, php-format
+msgid "editors_x_hours"
+msgstr "%s hod."
+
+#. %s is a number
+#: controllers/editors_controller.php:1052
+#, php-format
+msgid "editors_x_minutes"
+msgstr "%s min."
+
+#: views/errors/error401.thtml:50
+#: controllers/components/simple_acl.php:81
+#: controllers/components/simple_acl.php:82
+#: controllers/components/simple_acl.php:83
+#: controllers/components/amo.php:607
+#: controllers/components/amo.php:608
+#: controllers/components/amo.php:609
+#: controllers/reviews_controller.php:353
+#: controllers/reviews_controller.php:485
+#: controllers/collections_controller.php:438
+#: controllers/collections_controller.php:496
+#: controllers/collections_controller.php:504
+#: controllers/collections_controller.php:971
+#: controllers/collections_controller.php:1034
+#: controllers/collections_controller.php:1077
+msgid "error_access_denied"
+msgstr "Prístup odmietnutý"
+
+#: views/errors/error401.thtml:52
+msgid "error_access_denied_message"
+msgstr "Na zobrazenie tejto stránky nemáte oprávnenie."
+
+#: controllers/collections_controller.php:1039
+msgid "error_addon_exists"
+msgstr "Doplnok už existuje!"
+
+#: controllers/developers_controller.php:200
+#: controllers/developers_controller.php:593
+#: controllers/developers_controller.php:1016
+#: controllers/developers_controller.php:1429
+#: controllers/downloads_controller.php:95
+#: controllers/downloads_controller.php:102
+#: controllers/downloads_controller.php:164
+#: controllers/statistics_controller.php:135
+#: controllers/previews_controller.php:115
+#: controllers/previews_controller.php:206
+#: controllers/previews_controller.php:307
+#: controllers/reviews_controller.php:77
+#: controllers/reviews_controller.php:240
+#: controllers/reviews_controller.php:332
+#: controllers/reviews_controller.php:340
+#: controllers/api_controller.php:123
+#: controllers/api_controller.php:759
+#: controllers/addons_controller.php:131
+#: controllers/addons_controller.php:197
+#: controllers/addons_controller.php:1407
+#: controllers/addons_controller.php:1465
+#: controllers/addons_controller.php:1469
+#: controllers/addons_controller.php:1503
+#: controllers/editors_controller.php:265
+#: controllers/collections_controller.php:1041
+#: controllers/collections_controller.php:1074
+msgid "error_addon_notfound"
+msgstr "Doplnok sa nenašiel!"
+
+#: controllers/files_controller.php:83
+#: controllers/files_controller.php:196
+msgid "error_addon_notviewable"
+msgstr "Tento doplnok tu nemožno zobraziť."
+
+#: controllers/reviews_controller.php:246
+msgid "error_addon_selfreview"
+msgstr "Nemôžete recenzovať vlastný doplnok."
+
+#: controllers/addons_controller.php:970
+msgid "error_browse_no_addons"
+msgstr "V kategórii nie sú žiadne doplnky!"
+
+#: controllers/api_controller.php:424
+msgid "error_collection_feed_notfound"
+msgstr "Kanál RSS pre doplnok nebol nájdený."
+
+#: views/users/register.thtml:65
+#: views/users/edit.thtml:194
+msgid "error_email_invalid"
+msgstr "Toto nie je platná e-mailová adresa."
+
+#: views/users/pwreset.thtml:74
+#: views/users/register.thtml:70
+#: views/users/register.thtml:80
+#: views/users/register.thtml:86
+#: views/users/edit.thtml:105
+#: views/users/edit.thtml:111
+#: views/users/edit.thtml:192
+#: views/admin/users_edit.thtml:78
+#: views/admin/users_edit.thtml:83
+#: views/reviews/add.thtml:80
+#: views/reviews/add.thtml:104
+msgid "error_field_required"
+msgstr "Toto pole nesmie byť prázdne."
+
+#: controllers/files_controller.php:75
+#: controllers/files_controller.php:93
+#: controllers/files_controller.php:96
+#: controllers/files_controller.php:163
+#: controllers/files_controller.php:176
+#: controllers/files_controller.php:185
+#: controllers/files_controller.php:204
+#: controllers/editors_controller.php:412
+msgid "error_file_notfound"
+msgstr "Súbor sa nenašiel!"
+
+#. %s is a filename
+#: controllers/editors_controller.php:430
+#, php-format
+msgid "error_file_x_notfound"
+msgstr "Chyba: súbor %s neexistuje."
+
+#: views/collections/add.thtml:55
+#: views/collections/edit.thtml:89
+#: views/users/register.thtml:54
+#: views/users/edit.thtml:81
+#: views/reviews/add.thtml:70
+#: controllers/groups_controller.php:80
+#: controllers/groups_controller.php:102
+msgid "error_formerrors"
+msgstr "V tomto formulári sú chyby. Opravte ich a odošlite znova."
+
+#: views/users/register.thtml:109
+msgid "error_invalid_captcha"
+msgstr "Nesprávny kód, skúste to znova!"
+
+#: views/users/register.thtml:100
+#: views/users/edit.thtml:125
+#: views/admin/users_edit.thtml:101
+msgid "error_invalid_url"
+msgstr "URL má neplatný formát. Platná adresa vyzerá takto: http://priklad.com/moja_stranka."
+
+#. %s is a string representing what's missing. Example: file_id
+#: controllers/downloads_controller.php:65
+#: controllers/users_controller.php:185
+#: controllers/users_controller.php:264
+#: controllers/users_controller.php:559
+#: controllers/users_controller.php:653
+#: controllers/reviews_controller.php:71
+#: controllers/reviews_controller.php:234
+#: controllers/reviews_controller.php:325
+#: controllers/reviews_controller.php:473
+#: controllers/reviews_controller.php:475
+#: controllers/addons_controller.php:182
+#: controllers/addons_controller.php:1381
+#: controllers/addons_controller.php:1455
+#: controllers/collections_controller.php:266
+#: controllers/collections_controller.php:285
+#: controllers/collections_controller.php:346
+#: controllers/collections_controller.php:443
+#: controllers/collections_controller.php:482
+#: controllers/collections_controller.php:936
+#: controllers/collections_controller.php:959
+#: controllers/collections_controller.php:960
+#: controllers/collections_controller.php:975
+#: controllers/collections_controller.php:977
+#: controllers/collections_controller.php:994
+#: controllers/collections_controller.php:1003
+#: controllers/collections_controller.php:1016
+#: controllers/collections_controller.php:1017
+#: controllers/collections_controller.php:1024
+#: controllers/collections_controller.php:1070
+#: controllers/collections_controller.php:1090
+#, php-format
+msgid "error_missing_argument"
+msgstr "Chýba parameter: %s"
+
+#: controllers/components/amo.php:507
+#: controllers/components/amo.php:532
+msgid "error_no_files_in_addon"
+msgstr "bez súborov"
+
+#: controllers/previews_controller.php:200
+msgid "error_preview_notfound"
+msgstr "Ukážka sa nenašla!"
+
+#: views/addons/display.thtml:400
+#: views/reviews/add.thtml:98
+msgid "error_review_rating_required"
+msgstr "Musíte zvoliť hodnotenie."
+
+#: controllers/users_controller.php:160
+msgid "error_user_already_confirmed"
+msgstr "Tento používateľský úÄet už je potvrdený."
+
+#: controllers/users_controller.php:202
+#: controllers/users_controller.php:276
+#: controllers/users_controller.php:569
+#: controllers/users_controller.php:581
+#: controllers/users_controller.php:587
+#: controllers/users_controller.php:610
+#: controllers/users_controller.php:627
+msgid "error_user_badconfirmationcode"
+msgstr "Neplatný potvrdzovací kód!"
+
+#: views/users/pwreset.thtml:79
+#: views/users/register.thtml:75
+#: views/users/edit.thtml:183
+msgid "error_user_confirmpw_nomatch"
+msgstr "Heslá sa nezhodujú."
+
+#: views/users/register.thtml:65
+#: views/users/edit.thtml:190
+#: controllers/users_controller.php:617
+msgid "error_user_email_notunique"
+msgstr "Táto e-mailová adresa už je obsadená iným používateľom."
+
+#: controllers/users_controller.php:596
+msgid "error_user_emailchange_expired"
+msgstr "Časový interval na zmenu adresy vypršal. Ak chcete zmeniť svoju adresu, urobte tak znova vo vašom používateľskom profile a po prijatí overovacej e-mailovej správy kliknite na odkaz nachádzajúci sa v nej."
+
+#: controllers/collections_controller.php:985
+msgid "error_user_exists"
+msgstr "Používateľ môže maÅ¥ v jednom Äase priradenú len jednu rolu. Pred pokraÄovaním odstráňte existujúce role používateľa."
+
+#: views/users/register.thtml:91
+#: views/users/edit.thtml:116
+#: views/admin/users_edit.thtml:88
+msgid "error_user_nickname_notunique"
+msgstr "Táto prezývka už je obsadená."
+
+#: views/users/pwreset.thtml:54
+#: controllers/users_controller.php:191
+#: controllers/users_controller.php:270
+#: controllers/users_controller.php:603
+#: controllers/users_controller.php:659
+#: controllers/collections_controller.php:988
+#: controllers/collections_controller.php:998
+msgid "error_user_notfound"
+msgstr "Používateľ sa nenašiel!"
+
+#: views/users/activatefirst.thtml:47
+msgid "error_user_unconfirmed"
+msgstr "Najprv potvrÄte svoj používateľský úÄet kódom, ktorý ste dostali e-mailom."
+
+#: views/users/login.thtml:67
+msgid "error_username_or_pw_wrong"
+msgstr "Nesprávne meno používateľa alebo heslo!"
+
+#: controllers/editors_controller.php:260
+msgid "error_version_notfound"
+msgstr "Verzia sa nenašla!"
+
+#: views/users/delete.thtml:125
+#: views/users/edit.thtml:173
+msgid "error_wrong_password"
+msgstr "Zadané nesprávne heslo!"
+
+#: views/elements/amo2009/homepage_addon.thtml:122
+#: views/elements/feature.thtml:122
+msgid "feature_learnmore"
+msgstr "Viac informácií"
+
+# %1 is the add-on name
+#. %1 is the add-on name
+#: views/elements/amo2009/homepage_addon.thtml:123
+#: views/elements/feature.thtml:123
+#, php-format
+msgid "feature_learnmore_about_addon"
+msgstr "Viac informácií o %1$s"
+
+#. %1$s is a number
+#: views/elements/amo2009/reviews.thtml:52
+#: views/elements/addon_listitem.thtml:112
+#: views/elements/feature.thtml:99
+#: views/addons/browse_thumbs.thtml:86
+#, php-format
+msgid "feature_reviews"
+msgid_plural "feature_reviews"
+msgstr[0] "%1$s recenzia"
+msgstr[1] "%1$s recenzie"
+msgstr[2] "%1$s recenzií"
+
+#: views/elements/amo2009/homepage_addon.thtml:127
+#: views/elements/feature.thtml:127
+msgid "feature_view_more_from_category"
+msgstr "ZobraziÅ¥ ÄalÅ¡ie z kategórie "
+
+#. This appears on a page that views the source of an add-on. This link will return
+#. the user to the add-on's main page
+#: views/files/browse.thtml:65
+msgid "file_browser_link_addon"
+msgstr "Späť na doplnok"
+
+#. There is a list of directories and files on the page. Clicking this will show the
+#. contents of all the directories (normally you would click on each one to see the
+#. contents)
+#: views/files/browse.thtml:67
+msgid "file_browser_link_expand_all"
+msgstr "Rozbaliť všetko"
+
+#. This appears on a page that views the source of an add-on. This link will return
+#. the user to the add-on's review page (it only appears if the add-on is being
+#. reviewed)
+#: views/files/browse.thtml:64
+msgid "file_browser_link_review"
+msgstr "Späť na recenziu"
+
+#. The title of the page for viewing an add-on's source.
+#. %1$s is the name of the add-on
+#. %2$s is the name of the current application (e.g. Firefox or Thunderbird)
+#: views/files/browse.thtml:46
+msgid "file_browser_title"
+msgstr "%1$s :: PrehliadaÄ súborov :: %2$s Add-ons"
+
+#. This appears on a page that views the source of an add-on. There is a list of
+#. directories and files on the page. Clicking this link will toggle between an
+#. expanded or a collapsed list. This string should be kept short.
+#: views/files/browse.thtml:68
+msgid "file_browser_toggle_expand_collapse"
+msgstr "+/-"
+
+#. Link text for the AMO About page.
+#: views/elements/footer.thtml:72
+#: views/layouts/amo2009.thtml:341
+msgid "footer_a_about"
+msgstr "ÄŒo je"
+
+#. Link text to the AMO blog.
+#: views/elements/footer.thtml:74
+#: views/layouts/amo2009.thtml:343
+msgid "footer_a_blog"
+msgstr "Blog"
+
+#. Link text to the Frequently Asked Questions page.
+#: views/elements/footer.thtml:73
+#: views/layouts/amo2009.thtml:342
+msgid "footer_a_faq"
+msgstr "FAQ"
+
+#. Full text for the FAQ abbreviation.
+#: views/elements/footer.thtml:73
+#: views/pages/collector_features.thtml:72
+#: views/layouts/amo2009.thtml:342
+msgid "footer_abbr_faq"
+msgstr "Často kladené otázky"
+
+#: views/elements/footer.thtml:67
+#: views/layouts/amo2009.thtml:336
+msgid "footer_all_rights_reserved"
+msgstr "Všetky práva vyhradené."
+
+#: views/elements/footer.thtml:67
+#: views/layouts/amo2009.thtml:336
+msgid "footer_copyright"
+msgstr "Copyright"
+
+#: views/elements/footer.thtml:71
+#: views/layouts/amo2009.thtml:340
+msgid "footer_credits"
+msgstr "Tvorcovia"
+
+#: views/elements/footer.thtml:76
+#: views/layouts/amo2009.thtml:346
+msgid "footer_disclaimer"
+msgstr "Mozilla poskytuje odkazy na tieto programy ako láskavosť. Nezastupuje autorov týchto aplikácií ani neposkytuje žiadne informácie, ktoré sa ich týkajú. Všetky otázky, sťažnosti alebo požiadavky týkajúce sa aplikácií treba adresovať príslušnému vydavateľovi softvéru."
+
+#: views/elements/footer.thtml:61
+#: views/layouts/amo2009.thtml:332
+msgid "footer_lang_form_lang_submit_go"
+msgstr "Prejsť"
+
+#: views/elements/footer.thtml:70
+#: views/layouts/amo2009.thtml:339
+msgid "footer_legal_notices"
+msgstr "Právne informácie"
+
+#: views/elements/footer.thtml:50
+#: views/layouts/amo2009.thtml:321
+msgid "footer_other_languages"
+msgstr "Ďalšie jazyky:"
+
+#: views/elements/footer.thtml:69
+#: views/layouts/amo2009.thtml:338
+msgid "footer_privacy_policy"
+msgstr "Zásady ochrany súkromia"
+
+#: models/addontype.php:79
+msgid "general_addontype_dict"
+msgstr "Slovník"
+
+# Plural in this context means many of the add-on type
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:100
+msgid "general_addontype_dict_plural"
+msgstr "Slovníky"
+
+#: models/addontype.php:75
+msgid "general_addontype_extension"
+msgstr "Rozšírenie"
+
+# Plural in this context means many of the add-on type
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:98
+msgid "general_addontype_extension_plural"
+msgstr "Rozšírenia"
+
+#: models/addontype.php:85
+msgid "general_addontype_lpaddon"
+msgstr "Jazykový balík (doplnok)"
+
+# Plural in this context means many of the add-on type
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:103
+msgid "general_addontype_lpaddon_plural"
+msgstr "Jazykové balíky (doplnok)"
+
+#: models/addontype.php:83
+msgid "general_addontype_lpapp"
+msgstr "Jazykový balík (aplikácia)"
+
+# Plural in this context means many of the add-on type
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:102
+msgid "general_addontype_lpapp_plural"
+msgstr "Jazykové balíky (aplikácia)"
+
+#: models/addontype.php:87
+msgid "general_addontype_plugin"
+msgstr "Zásuvný modul"
+
+# Plural in this context means many of the add-on type
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:104
+msgid "general_addontype_plugin_plural"
+msgstr "Zásuvné moduly"
+
+#: models/addontype.php:81
+msgid "general_addontype_search"
+msgstr "Vyhľadávací modul"
+
+# Plural in this context means many of the add-on type
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:101
+msgid "general_addontype_search_plural"
+msgstr "Vyhľadávacie moduly"
+
+#: models/addontype.php:77
+msgid "general_addontype_theme"
+msgstr "Téma"
+
+# Plural in this context means many of the add-on type
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:99
+msgid "general_addontype_theme_plural"
+msgstr "Témy"
+
+#: config/language.php:367
+msgid "general_languages_all_locales"
+msgstr "Všetky lokalizácie"
+
+#: views/layouts/amo2009.thtml:249
+msgid "header_brand_name"
+msgstr "Mozilla"
+
+#. %1$s is the application name. Example: Firefox
+#: views/elements/header.thtml:111
+#: views/elements/header.thtml:122
+#: views/layouts/amo2009.thtml:248
+#, php-format
+msgid "header_home_tooltip"
+msgstr "Návrat na úvodnú stránku %1$s Add-ons"
+
+#: views/elements/header.thtml:87
+msgid "header_main_firefox_header"
+msgstr "Firefox Add-ons"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:218
+msgid "header_main_firefox_header_with_logo"
+msgstr "Doplnky <em>pre</em> <img alt=\"Firefox\" src=\"%1$s\" /> <strong>Firefox</strong>"
+
+#: views/elements/header.thtml:99
+msgid "header_main_header"
+msgstr "Doplnky"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:242
+msgid "header_main_header_with_logo"
+msgstr "Doplnky <img alt=\"Doplnky\" src=\"%1$s\" />"
+
+#: views/elements/header.thtml:90
+msgid "header_main_seamonkey_header"
+msgstr "SeaMonkey Add-ons"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:224
+msgid "header_main_seamonkey_header_with_logo"
+msgstr "Doplnky <em>pre</em> <img alt=\"seamonkey\" src=\"%1$s\" /> <strong>SeaMonkey</strong>"
+
+#: views/elements/header.thtml:93
+msgid "header_main_sunbird_header"
+msgstr "Sunbird Add-ons"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:230
+msgid "header_main_sunbird_header_with_logo"
+msgstr "Doplnky <em>pre</em> <img alt=\"sunbird\" src=\"%1$s\" /> <strong>Sunbird</strong>"
+
+#: views/elements/header.thtml:96
+msgid "header_main_thunderbird_header"
+msgstr "Thunderbird Add-ons"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:236
+msgid "header_main_thunderbird_header_with_logo"
+msgstr "Doplnky <em>pre</em> <img alt=\"thunderbird\" src=\"%1$s\" /> <strong>Thunderbird</strong>"
+
+#: views/layouts/amo2009.thtml:205
+msgid "header_navaccess_applications_menu"
+msgstr "Prejsť do ponuky Ďalšie aplikácie"
+
+#: views/layouts/amo2009.thtml:204
+msgid "header_navaccess_categories_menu"
+msgstr "Prejsť do ponuky kategórie"
+
+#: views/layouts/amo2009.thtml:202
+msgid "header_navaccess_main_content"
+msgstr "Prejsť na hlavný obsah"
+
+#: views/layouts/amo2009.thtml:203
+msgid "header_navaccess_search_form"
+msgstr "Prejsť na vyhľadávací formulár"
+
+#: views/elements/header.thtml:62
+msgid "header_navlink_addons"
+msgstr "Doplnky"
+
+#: views/elements/developers/sidebar.thtml:72
+#: views/elements/developers/myaddons.thtml:50
+#: views/elements/header.thtml:159
+#: views/addons/display.thtml:378
+msgid "header_navlink_login"
+msgstr "Prihlásenie"
+
+#: views/elements/header.thtml:156
+#: views/layouts/amo2009.thtml:304
+msgid "header_navlink_logout"
+msgstr "Odhlásiť sa"
+
+#: views/elements/header.thtml:145
+#: views/layouts/amo2009.thtml:303
+msgid "header_navlink_myaccount"
+msgstr "Môj úÄet"
+
+#: views/elements/header.thtml:158
+msgid "header_navlink_register"
+msgstr "Registrácia"
+
+#. %1 is the URL to the registration page
+#. %2 is the URL to the login page
+#: views/layouts/amo2009.thtml:278
+msgid "header_navlink_register_or_login"
+msgstr "<a href=\"%1$s\">Zaregistrujte</a> alebo <a href=\"%2$s\">prihláste sa</a>"
+
+#: views/layouts/amo2009.thtml:285
+msgid "header_navlink_tools"
+msgstr "Nástroje"
+
+#. %s is the add-on name
+#: views/elements/collections_interactive_addon.thtml:62
+#: views/elements/amo2009/homepage_addon.thtml:77
+#: views/elements/addon_discussionheader.thtml:62
+#: views/elements/addon_listitem.thtml:67
+#: views/elements/feature.thtml:84
+#: views/addons/category_landing.thtml:87
+#: views/addons/browse_thumbs.thtml:60
+#, php-format
+msgid "img_preview_of"
+msgstr "Obrázok ukážky doplnku %s"
+
+# %1 is the login URL for the link tag
+#. %1 is the login URL for the link tag
+#. %2 is the link to an explanatory page.
+#: views/elements/amo2009/install.thtml:307
+#: views/elements/install.thtml:255
+msgid "install_a_login_to_install"
+msgstr "Na inÅ¡taláciu tohto doplnku sa musíte <a href=\"%1$s\">prihlásiÅ¥</a>. <a href=\"%2$s\">PreÄo</a>?"
+
+#. %1 is the URL for the Experimental Add-ons section of the FAQ page
+#: views/elements/amo2009/install.thtml:283
+#: views/elements/install.thtml:232
+msgid "install_button_confirm_exp_install"
+msgstr "Umožniť mi nainštalovať experimentálny doplnok. <a href=\"%1$s\">Čo to je?</a>"
+
+#. %1$s is the application name. Example: Firefox
+#. %2$s is an optional string used to specify a platform. Example: (Windows)
+#: views/elements/amo2009/install.thtml:128
+#: views/elements/install.thtml:75
+#, php-format
+msgid "install_button_text"
+msgstr "Pridať do programu %1$s %2$s"
+
+# %1 is the add-on name, %2 is the app name
+#. %1 is the add-on name, %2 is the app name
+#: views/elements/amo2009/install.thtml:191
+#: views/elements/amo2009/install.thtml:206
+#: views/elements/amo2009/install.thtml:249
+#: views/elements/amo2009/install.thtml:298
+#: views/elements/install.thtml:150
+#: views/elements/install.thtml:165
+#: views/elements/install.thtml:202
+#: views/elements/install.thtml:246
+#, php-format
+msgid "install_button_title"
+msgstr "Pridať %1$s do programu %2$s"
+
+#. %1$s is the add-on name
+#: views/elements/amo2009/install.thtml:200
+#: views/elements/install.thtml:159
+#, php-format
+msgid "install_download"
+msgstr "Prevziať %1$s"
+
+#: views/elements/amo2009/install.thtml:147
+#: views/elements/install.thtml:94
+msgid "install_error_addon_not_found"
+msgstr "Tento doplnok nie je k dispozícii"
+
+#: views/addons/dictionaries.thtml:65
+msgid "langtools_a11y_tablesummary"
+msgstr "Zoznam jazykových balíkov a slovníkov."
+
+#: views/addons/dictionaries.thtml:47
+msgid "langtools_download_dictionary"
+msgstr "Prevziať slovník"
+
+#: views/addons/dictionaries.thtml:48
+msgid "langtools_download_langpack"
+msgstr "Prevziať jazykový balík"
+
+#: views/addons/dictionaries.thtml:63
+#: controllers/components/amo.php:685
+#: controllers/addons_controller.php:1239
+msgid "langtools_header_dicts_and_langpacks"
+msgstr "Slovníky/Jazykové balíky"
+
+#: views/addons/dictionaries.thtml:44
+msgid "langtools_install_dictionary"
+msgstr "Nainštalovať slovník"
+
+#: views/addons/dictionaries.thtml:45
+msgid "langtools_install_langpack"
+msgstr "Nainštalovať jazykový balík"
+
+#: views/addons/dictionaries.thtml:69
+msgid "langtools_tableheader_dictionary"
+msgstr "Slovník"
+
+#: views/addons/dictionaries.thtml:70
+msgid "langtools_tableheader_langpack"
+msgstr "Jazykový balík"
+
+#: views/addons/dictionaries.thtml:68
+msgid "langtools_tableheader_language"
+msgstr "Jazyk"
+
+#: models/license.php:65
+msgid "license_custom"
+msgstr "Vlastná licencia"
+
+#: config/bootstrap.php:303
+msgid "licenses_bsd"
+msgstr "Licencia BSD"
+
+#: config/bootstrap.php:298
+msgid "licenses_gpl_2.0"
+msgstr "GNU General Public License, verzia 2.0"
+
+#: config/bootstrap.php:299
+msgid "licenses_gpl_3.0"
+msgstr "GNU General Public License, verzia 3.0"
+
+#: config/bootstrap.php:300
+msgid "licenses_lgpl_2.1"
+msgstr "GNU Lesser General Public License, verzia 2.1"
+
+#: config/bootstrap.php:301
+msgid "licenses_lgpl_3.0"
+msgstr "GNU Lesser General Public License, verzia 3.0"
+
+#: config/bootstrap.php:302
+msgid "licenses_mit"
+msgstr "Licencia MIT/X11"
+
+#: config/bootstrap.php:297
+msgid "licenses_mpl_1.1"
+msgstr "Mozilla Public License, verzia 1.1"
+
+#: views/users/emailchange.thtml:51
+#: views/users/delete.thtml:55
+#: views/users/delete.thtml:137
+#: views/users/edit.thtml:74
+#: views/reviews/flag.thtml:54
+msgid "link_return_to_front_page"
+msgstr "Kliknutím sem sa vrátite na hlavnú stránku."
+
+#: views/elements/amo2009/addon_list_options.thtml:46
+#: views/elements/addon_list_options.thtml:46
+msgid "list_sortby_date"
+msgstr "Dátum"
+
+#: views/elements/amo2009/addon_list_options.thtml:47
+#: views/elements/addon_list_options.thtml:47
+msgid "list_sortby_downloads"
+msgstr "Prevzatia"
+
+#: views/elements/amo2009/addon_list_options.thtml:45
+#: views/elements/addon_list_options.thtml:45
+msgid "list_sortby_name"
+msgstr "Názov"
+
+#: views/elements/amo2009/addon_list_options.thtml:48
+#: views/elements/addon_list_options.thtml:48
+msgid "list_sortby_rating"
+msgstr "Hodnotenie"
+
+#: config/bootstrap.php:278
+msgid "main_prettyname_fennec"
+msgstr "Fennec"
+
+#: config/bootstrap.php:274
+msgid "main_prettyname_firefox"
+msgstr "Firefox"
+
+#: config/bootstrap.php:277
+msgid "main_prettyname_seamonkey"
+msgstr "SeaMonkey"
+
+#: config/bootstrap.php:276
+msgid "main_prettyname_sunbird"
+msgstr "Sunbird"
+
+#: config/bootstrap.php:275
+msgid "main_prettyname_thunderbird"
+msgstr "Thunderbird"
+
+#: views/elements/addon_categories.thtml:52
+msgid "nav_category_dicts_langpacks"
+msgstr "Slovníky a jazykové balíky"
+
+#: views/elements/addon_categories.thtml:55
+msgid "nav_category_themes"
+msgstr "Témy"
+
+#: views/elements/app_chooser.thtml:47
+#: views/layouts/amo2009.thtml:255
+msgid "other_apps_tooltip"
+msgstr "Hľadať doplnky pre iné aplikácie"
+
+# In a user list: user 1, user 2, "others"
+#. In a user list: user 1, user 2, "others"
+#: views/helpers/addons_html.php:222
+msgid "other_users"
+msgstr "a Äalší"
+
+#: controllers/pages_controller.php:90
+msgid "page_title_appversions"
+msgstr "Verzie aplikácie"
+
+#: controllers/pages_controller.php:115
+msgid "page_title_collector"
+msgstr "Kolekcia doplnkov"
+
+#: controllers/pages_controller.php:117
+msgid "page_title_collector_faq"
+msgstr "FAQ pre kolekcie doplnkov"
+
+#: controllers/pages_controller.php:119
+msgid "page_title_collector_features"
+msgstr "Funkcie pre kolekcie doplnkov"
+
+#: controllers/pages_controller.php:122
+msgid "page_title_collector_firstrun"
+msgstr "Víta vás rozšírenie Add-on Collector"
+
+#: controllers/pages_controller.php:92
+msgid "page_title_credits"
+msgstr "Tvorcovia"
+
+#: controllers/pages_controller.php:113
+msgid "page_title_developer_faq"
+msgstr "Často kladené otázky vývojárov"
+
+#: controllers/pages_controller.php:111
+msgid "page_title_faq"
+msgstr "Často kladené otázky"
+
+#: controllers/pages_controller.php:94
+msgid "page_title_fashionyourfirefox_faq"
+msgstr "ÄŒasto kladené otázky pre ObleÄte svoj Firefox"
+
+#: controllers/pages_controller.php:101
+msgid "page_title_policy"
+msgstr "Zásady stránky Add-ons"
+
+#: controllers/pages_controller.php:103
+msgid "page_title_privacy"
+msgstr "Zásady ochrany súkromia Mozilla"
+
+#: controllers/pages_controller.php:105
+msgid "page_title_review_guide"
+msgstr "Sprievodca systémom kontroly"
+
+#: controllers/pages_controller.php:107
+msgid "page_title_sandbox"
+msgstr "Systém kontroly v Sandboxe"
+
+#: controllers/pages_controller.php:109
+msgid "page_title_submissionhelp"
+msgstr "Pomocník k odoslaniu"
+
+#: views/pages/appversions.thtml:87
+msgid "pages_appversions_guid"
+msgstr "Identifikátor GUID"
+
+#: views/pages/appversions.thtml:79
+#: controllers/pages_controller.php:90
+msgid "pages_appversions_header"
+msgstr "Platné verzie aplikácie"
+
+#: views/pages/appversions.thtml:80
+msgid "pages_appversions_intro"
+msgstr "Doplnky odoslané na Mozilla Add-ons musia obsahovať súbor install.rdf aspoň s jednou z dole podporovaných aplikácií. Pre tieto aplikácie sú podporované len dole uvedené verzie."
+
+#. %s is a full <a> tag
+#: views/pages/appversions.thtml:93
+#, php-format
+msgid "pages_appversions_required_files"
+msgstr "Ak podporovaná aplikácia nevyžaduje súbor install.rdf, musí obsahovaÅ¥ súbor s požadovanými vlastnosÅ¥ami (ako je urÄené %s)."
+
+#. this is the text inside of an <a> tag for pages_appversions_required_files. This
+#. should be fixed.
+#: views/pages/appversions.thtml:93
+msgid "pages_appversions_required_files_link"
+msgstr "tu"
+
+#: views/pages/appversions.thtml:88
+msgid "pages_appversions_versions"
+msgstr "Verzie"
+
+#: views/pages/policy.thtml:51
+msgid "pages_policy_sandbox_link"
+msgstr "stránku s informáciami o Sandboxe"
+
+#: views/elements/pagination.thtml:53
+msgid "pagination_next_page"
+msgstr "nasledujúce"
+
+#: views/elements/pagination.thtml:52
+msgid "pagination_previous_page"
+msgstr "predchádzajúce"
+
+#: views/elements/recaptcha.thtml:65
+msgid "recaptcha_enter_both_words"
+msgstr "Nižšie zadajte <strong>obidve slová oddelené medzerou</strong>."
+
+#: views/elements/recaptcha.thtml:83
+msgid "recaptcha_enter_here"
+msgstr "Zadajte vaÅ¡u odpoveÄ:"
+
+#: views/elements/recaptcha.thtml:74
+msgid "recaptcha_enter_whatyouhear"
+msgstr "Prosím, zadajte vypoÄutý text."
+
+# %1 is the link switching refreshing the captcha
+# %2 is the link switching to a text captcha
+#. %1 is the link switching refreshing the captcha
+#. %2 is the link switching to a text captcha
+#: views/elements/recaptcha.thtml:77
+msgid "recaptcha_hardtohear_text"
+msgstr "Ak toto je Å¥ažko zrozumiteľné, môžete <a href=\"%1$s\">si vypoÄuÅ¥ nieÄo iné</a> alebo <a href=\"%2$s\">prepnite naspäť na text</a>."
+
+# %1 is the link switching refreshing the captcha
+# %2 is the link switching to an audio captcha
+#. %1 is the link switching refreshing the captcha
+#. %2 is the link switching to an audio captcha
+#: views/elements/recaptcha.thtml:68
+msgid "recaptcha_hardtoread_text"
+msgstr "Ak je to Å¥ažko Äitateľné, môžete skúsiÅ¥ <a href=\"%1$s\">iné slová</a> alebo si namiesto toho <a href=\"%2$s\">nieÄo vypoÄujte</a>."
+
+#: views/users/register.thtml:105
+msgid "recaptcha_label"
+msgstr "Ste Älovek?"
+
+#: views/users/register.thtml:106
+msgid "recaptcha_whatsthis"
+msgstr "ÄŒo je toto?"
+
+#: controllers/reviews_controller.php:559
+msgid "review_flag_error"
+msgstr "Chyba pri nahlásení tejto recenzie!"
+
+#: models/reviews_moderation_flag.php:69
+msgid "review_flag_reason_bug_support"
+msgstr "Nevhodne umiestnená správa o chybe alebo žiadosť o podporu"
+
+#: views/reviews/display.thtml:103
+#: views/reviews/display.thtml:186
+msgid "review_flag_reason_instructions"
+msgstr "Nahlásiť túto recenziu (vyberte dôvod)"
+
+#: models/reviews_moderation_flag.php:67
+msgid "review_flag_reason_language"
+msgstr "Nevhodný jazyk/dialóg"
+
+#: models/reviews_moderation_flag.php:71
+msgid "review_flag_reason_other"
+msgstr "Iný (popíšte)"
+
+#: models/reviews_moderation_flag.php:65
+msgid "review_flag_reason_spam"
+msgstr "Spam alebo iný neschválený obsah"
+
+#: views/reviews/display.thtml:91
+#: views/reviews/display.thtml:175
+#: controllers/reviews_controller.php:555
+msgid "review_flag_success"
+msgstr "ÄŽakujeme; táto recenzia bola oznaÄená na schválenie editorom."
+
+#: views/reviews/display.thtml:41
+msgid "review_flag_this"
+msgstr "Nahlásiť túto recenziu"
+
+#: views/reviews/display.thtml:42
+msgid "review_flag_this_titletip"
+msgstr "Je táto recenzia nevhodná, nepresná alebo spam? Kliknutím sem ju oznaÄíte na schválenie editorom."
+
+# %1 is the URL of the support section, %2 for the review guidelines
+#. %1 is the URL of the support section, %2 for the review guidelines
+#: views/reviews/add.thtml:53
+msgid "review_guidelines_short"
+msgstr "<p>Pamätajte na tieto tipy:</p><ul><li>Píšte, akoby ste rozprávali svojmu priateľovi o svojich zážitkoch s týmto doplnkom. UveÄte Å¡pecifické a užitoÄné detaily, ako napríklad funkcie, ktoré sa vám páÄia Äi nepáÄia, ako jednoduché je jeho používanie a takisto aké má nevýhody. Vyhýbajte sa vÅ¡eobecným frázam typu \"Je to super\" alebo \"Je hrozné\" v prípade, že to neviete/nechcete doložiÅ¥ skúsenosÅ¥ami a faktami.</li><li>Do recenzií nepíšte hlásenia o chybách. VaÅ¡a e-mailová adresa nie je viditeľná ani pre vývojárov doplnku a tí vás môžu chcieÅ¥ po takom hlásení kontaktovaÅ¥. Ak chcete pomôcÅ¥ získaÅ¥ podporu k doplnku, pozrite si <a href=\"%1$s\">sekciu podpory</a>.</li><li>Recenzie píšte jasne, vyhýbajte sa nesluÅ¡ným frázam a nezadávajte do nich žiadne osobné informácie.</li></ul><p>PodrobnejÅ¡ie informácie o recenziách si preÄítajte v <a href=\"%2$s\">pravidlách pre pridávanie recenzií</a>.</p>"
+
+#. %1 is the add-on name
+#: views/reviews/flag.thtml:56
+#: views/reviews/display.thtml:55
+#: views/reviews/review_added.thtml:50
+#, php-format
+msgid "reviews_header"
+msgstr "Recenzie doplnku %s"
+
+#: controllers/addons_controller.php:435
+msgid "rss_featuredaddons"
+msgstr "OdporúÄané doplnky"
+
+#: controllers/addons_controller.php:432
+msgid "rss_newestaddons"
+msgstr "Najnovšie doplnky"
+
+#: controllers/addons_controller.php:434
+msgid "rss_popularaddons"
+msgstr "Populárne doplnky"
+
+#: controllers/addons_controller.php:433
+msgid "rss_updatedaddons"
+msgstr "Aktualizované doplnky"
+
+#: views/elements/search_mini.thtml:70
+msgid "search"
+msgstr "Hľadať"
+
+#: views/search/collections.thtml:51
+msgid "search_collections_header"
+msgstr "Výsledky vyhľadávania v kolekciách"
+
+#: controllers/search_controller.php:297
+msgid "search_collections_pagetitle"
+msgstr "Výsledky vyhľadávania v kolekciách"
+
+#: controllers/search_controller.php:99
+msgid "search_disabled"
+msgstr "Vyhľadávanie je momentálne zakázané. Skúste neskôr znova."
+
+#: views/elements/amo2009/search.thtml:188
+#: views/elements/search.thtml:187
+#: views/elements/search_mini.thtml:54
+msgid "search_form_all_addons"
+msgstr "všetky doplnky"
+
+#. This string is in the main category dropdown when searching
+#: views/elements/amo2009/search.thtml:204
+msgid "search_form_all_collections"
+msgstr "všetky kolekcie"
+
+#: views/elements/amo2009/search.thtml:184
+#: views/elements/amo2009/search.thtml:385
+#: views/elements/amo2009/search.thtml:408
+#: views/elements/search.thtml:171
+#: views/elements/search.thtml:183
+#: views/elements/search_mini.thtml:43
+#: views/elements/search_mini.thtml:49
+#: views/layouts/mozilla.thtml:188
+msgid "search_form_default_text"
+msgstr "hľadaný doplnok"
+
+#: views/elements/amo2009/search.thtml:184
+#: views/elements/amo2009/search.thtml:404
+msgid "search_form_default_text_collections"
+msgstr "hľadať v kolekciách"
+
+#: views/elements/amo2009/search.thtml:206
+#: views/elements/search.thtml:202
+msgid "search_form_submit_tooltip"
+msgstr "Hľadať doplnky"
+
+#: views/elements/amo2009/search.thtml:184
+#: views/elements/search.thtml:183
+#: views/elements/search_mini.thtml:49
+msgid "search_form_tooltip"
+msgstr "Kliknutím pridáte hľadané slová"
+
+#: views/elements/amo2009/search.thtml:186
+#: views/elements/search.thtml:185
+#: views/elements/search_mini.thtml:52
+msgid "search_form_within"
+msgstr "kde"
+
+#: views/addons/searchengines.thtml:118
+msgid "search_landing_all_search_engines"
+msgstr "Všetky vyhľadávacie moduly"
+
+#: views/addons/searchengines.thtml:114
+msgid "search_landing_browse_search_engines"
+msgstr "Prehľadávať všetky vyhľadávacie moduly"
+
+#: views/search/collections.thtml:58
+#: views/search/index.thtml:59
+msgid "search_nothing_found"
+msgstr "Žiadne výsledky sa nenašli."
+
+#: controllers/search_controller.php:185
+msgid "search_pagetitle"
+msgstr "Hľadať doplnky"
+
+#: controllers/search_controller.php:242
+msgid "search_rss_description"
+msgstr "Kanál výsledkov hľadania"
+
+#. %s is the terms the user is searching for (a string)
+#: controllers/search_controller.php:241
+#, php-format
+msgid "search_rss_results_for"
+msgstr "Výsledky hľadania pre: %s"
+
+#: views/elements/header.thtml:154
+#: views/layouts/amo2009.thtml:296
+msgid "sidebar_navlink_admin_tools"
+msgstr "Nástroje správcu"
+
+#: views/elements/header.thtml:146
+#: views/layouts/amo2009.thtml:288
+msgid "sidebar_navlink_developer_tools"
+msgstr "Nástroje vývojára"
+
+#: views/elements/header.thtml:148
+#: views/layouts/amo2009.thtml:290
+msgid "sidebar_navlink_editor_tools"
+msgstr "Nástroje editora"
+
+#: views/layouts/amo2009.thtml:302
+msgid "sidebar_navlink_welcome"
+msgstr "Vitajte"
+
+#. %s is the user's name
+#: views/layouts/amo2009.thtml:302
+#, php-format
+msgid "sidebar_navlink_welcome_name"
+msgstr "Vitajte, %s"
+
+#: views/elements/pitch.thtml:50
+#: views/elements/pitch.thtml:55
+msgid "sidebar_pitch_dictionary"
+msgstr "Slovník"
+
+#: views/elements/pitch.thtml:72
+msgid "sidebar_pitch_featured_addons"
+msgstr "OdporúÄané doplnky"
+
+#: views/elements/pitch.thtml:61
+msgid "sidebar_pitch_looking_for"
+msgstr "Hľadám:"
+
+#: views/elements/pitch.thtml:70
+msgid "sidebar_pitch_newest_addons"
+msgstr "Najnovšie doplnky"
+
+#: views/elements/pitch.thtml:49
+msgid "sidebar_pitch_search"
+msgstr "Zásuvný modul"
+
+#: views/elements/pitch.thtml:69
+msgid "sidebar_pitch_subscribe_to"
+msgstr "Prihlásiť sa k odberu:"
+
+#: views/elements/pitch.thtml:48
+#: views/elements/pitch.thtml:54
+msgid "sidebar_pitch_theme"
+msgstr "Tému"
+
+#: views/elements/pitch.thtml:71
+msgid "sidebar_pitch_updated_addons"
+msgstr "Aktualizované doplnky"
+
+#. %1$s is a number
+#: views/helpers/localization.php:65
+#: views/developers/versions_edit.thtml:95
+#: views/addons/dictionaries.thtml:92
+#, php-format
+msgid "size_kb"
+msgstr "%1$s kB"
+
+#: views/elements/amo2009/stars.thtml:57
+#: views/elements/stars.thtml:63
+msgid "stars_not_yet_rated"
+msgstr "Nehodnotené"
+
+# %1 is the number of stars this add-on has
+#. %1 is the number of stars this add-on has
+#: views/elements/amo2009/stars.thtml:49
+#: views/elements/stars.thtml:54
+#, php-format
+msgid "stars_rated_x_outof_5"
+msgstr "Hodnotenie: %s z 5 hviezdiÄiek"
+
+#: views/statistics/addon.thtml:59
+msgid "statistics_addon_dashboard_link"
+msgstr "Å tatistika"
+
+#: views/statistics/addon.thtml:58
+msgid "statistics_addon_developertools_link"
+msgstr "Nástroje vývojára"
+
+#: views/statistics/addon.thtml:53
+msgid "statistics_addon_switch"
+msgstr "Prepnúť doplnok"
+
+#. This is a date format.
+#. http://php.net/strftime
+#: views/statistics/rss/summary.thtml:54
+#: views/statistics/addon.thtml:181
+msgid "statistics_date_shortmonth"
+msgstr "%e. %B"
+
+#. This is a date format.
+#. http://php.net/strftime
+#: views/statistics/rss/summary.thtml:40
+#: views/statistics/addon.thtml:152
+msgid "statistics_date_shortmonthwithyear"
+msgstr "%e. %B %Y"
+
+#. This is a date format.
+#. http://php.net/strftime
+#: views/statistics/rss/summary.thtml:41
+#: views/statistics/rss/summary.thtml:48
+#: views/statistics/addon.thtml:161
+#: views/statistics/addon.thtml:172
+msgid "statistics_date_weekdayshortmonth"
+msgstr "%A, %e. %B"
+
+#. %1$s is an add-on name and version. Example: Add-on 3.5
+#: controllers/components/stats.php:519
+#, php-format
+msgid "statistics_events_addon_created"
+msgstr "vytvorené: %1$s"
+
+#. %1$s is an application name and version. Example: Firefox 3.5
+#: controllers/components/stats.php:500
+#, php-format
+msgid "statistics_events_app_released"
+msgstr "vydané: %1$s"
+
+#: views/statistics/addon.thtml:71
+msgid "statistics_help_close_link"
+msgstr "Zavrieť"
+
+#: views/statistics/addon.thtml:60
+msgid "statistics_help_link"
+msgstr "Pomocník"
+
+#: views/statistics/index.thtml:83
+msgid "statistics_index_anotheraddon"
+msgstr "alebo vyberte iný doplnok"
+
+#: views/statistics/index.thtml:85
+msgid "statistics_index_anotheraddon_public"
+msgstr "alebo vyberte doplnok s verejnou Å¡tatistikou"
+
+#: views/statistics/index.thtml:71
+msgid "statistics_index_myaddons"
+msgstr "Vyberte jeden zo svojich doplnkov, ktorého štatistiku zobraziť"
+
+#: views/statistics/index.thtml:89
+msgid "statistics_index_selectaddon"
+msgstr "Vyberte doplnok, ktorého štatistiku zobraziť"
+
+#: views/statistics/index.thtml:91
+msgid "statistics_index_selectaddon_public"
+msgstr "Vyberte doplnok s verejnou Å¡tatistikou"
+
+#: views/statistics/index.thtml:39
+msgid "statistics_index_title"
+msgstr "Å tatistika"
+
+#: views/statistics/index.thtml:97
+msgid "statistics_index_view_button"
+msgstr "Zobraziť štatistiku"
+
+#: views/statistics/addon.thtml:222
+#: controllers/statistics_controller.php:247
+msgid "statistics_js_download_csv"
+msgstr "Zobraziť túto tabuľku vo formáte CSV"
+
+#: controllers/statistics_controller.php:246
+msgid "statistics_js_dropdowns_none"
+msgstr "žiadne"
+
+#: controllers/statistics_controller.php:245
+msgid "statistics_js_dropdowns_removeplot"
+msgstr "Odstrániť tento diagram"
+
+#: controllers/statistics_controller.php:248
+msgid "statistics_js_groupby_selector_date"
+msgstr "Zoskupiť podľa: deň"
+
+#: controllers/statistics_controller.php:251
+msgid "statistics_js_groupby_selector_month"
+msgstr "Zoskupiť podľa: mesiac"
+
+#: controllers/statistics_controller.php:249
+msgid "statistics_js_groupby_selector_week"
+msgstr "Zoskupiť podľa: týždeň"
+
+#: controllers/statistics_controller.php:250
+msgid "statistics_js_groupby_selector_week_over_week"
+msgstr "Porovnať podľa týždňov"
+
+#: controllers/statistics_controller.php:260
+msgid "statistics_js_plotselection_foundinrange"
+msgstr "nájdené v rozsahu: %s"
+
+#: controllers/statistics_controller.php:270
+msgid "statistics_js_plotselection_options_addplot_name"
+msgstr "Pridať diagram"
+
+#: controllers/statistics_controller.php:271
+msgid "statistics_js_plotselection_options_addplot_tooltip"
+msgstr "PridaÅ¥ Äalší diagram do tohto grafu"
+
+#: controllers/statistics_controller.php:261
+msgid "statistics_js_plotselection_options_count_name_checked"
+msgstr "SkryÅ¥ celkový poÄet"
+
+#: controllers/statistics_controller.php:262
+msgid "statistics_js_plotselection_options_count_name_unchecked"
+msgstr "ZobraziÅ¥ celkový poÄet"
+
+#: controllers/statistics_controller.php:263
+msgid "statistics_js_plotselection_options_count_tooltip"
+msgstr "ZakresliÅ¥ celkový poÄet do tohto grafu"
+
+#: controllers/statistics_controller.php:275
+msgid "statistics_js_plotselection_options_csv_name"
+msgstr "Zobraziť údaje (CSV)"
+
+#: controllers/statistics_controller.php:276
+msgid "statistics_js_plotselection_options_csv_tooltip"
+msgstr "ZískaÅ¥ súbor údajov oddelených Äiarkami"
+
+#: controllers/statistics_controller.php:267
+msgid "statistics_js_plotselection_options_events_addon_name_checked"
+msgstr "Skryť udalosti: %s"
+
+#: controllers/statistics_controller.php:268
+msgid "statistics_js_plotselection_options_events_addon_name_unchecked"
+msgstr "Zobraziť udalosti: %s"
+
+#: controllers/statistics_controller.php:269
+msgid "statistics_js_plotselection_options_events_addon_tooltip"
+msgstr "VyznaÄiÅ¥ na diagramoch dátumy vydania"
+
+#: controllers/statistics_controller.php:264
+msgid "statistics_js_plotselection_options_events_firefox_name_checked"
+msgstr "Skryť udalosti Firefoxu"
+
+#: controllers/statistics_controller.php:265
+msgid "statistics_js_plotselection_options_events_firefox_name_unchecked"
+msgstr "Zobraziť udalosti Firefoxu"
+
+#: controllers/statistics_controller.php:266
+msgid "statistics_js_plotselection_options_events_firefox_tooltip"
+msgstr "VyznaÄiÅ¥ na diagramoch dátumy vydania Firefoxu"
+
+#: controllers/statistics_controller.php:272
+msgid "statistics_js_plotselection_options_resize_name_checked"
+msgstr "Zbaliť graf"
+
+#: controllers/statistics_controller.php:273
+msgid "statistics_js_plotselection_options_resize_name_unchecked"
+msgstr "Rozbaliť graf"
+
+#: controllers/statistics_controller.php:274
+msgid "statistics_js_plotselection_options_resize_tooltip"
+msgstr "Zmeniť veľkosť grafu"
+
+#: controllers/statistics_controller.php:254
+msgid "statistics_js_plotselection_selector_adu"
+msgstr "Aktívni denní používatelia"
+
+#: controllers/statistics_controller.php:256
+msgid "statistics_js_plotselection_selector_application"
+msgstr "Aplikácia"
+
+#: controllers/statistics_controller.php:259
+msgid "statistics_js_plotselection_selector_custom"
+msgstr "Vlastné"
+
+#: controllers/statistics_controller.php:253
+msgid "statistics_js_plotselection_selector_downloads"
+msgstr "Prevzatia"
+
+#: controllers/statistics_controller.php:258
+msgid "statistics_js_plotselection_selector_os"
+msgstr "OperaÄný systém"
+
+#: controllers/statistics_controller.php:257
+msgid "statistics_js_plotselection_selector_status"
+msgstr "Stav doplnku"
+
+#: controllers/statistics_controller.php:252
+msgid "statistics_js_plotselection_selector_summary"
+msgstr "Súhrn"
+
+#: controllers/statistics_controller.php:255
+msgid "statistics_js_plotselection_selector_version"
+msgstr "Verzia doplnku"
+
+#: controllers/components/stats.php:398
+msgid "statistics_longnames_application"
+msgstr "Aplikácia"
+
+#: controllers/components/stats.php:400
+msgid "statistics_longnames_os"
+msgstr "OperaÄný systém"
+
+#: controllers/components/stats.php:399
+msgid "statistics_longnames_status"
+msgstr "Stav doplnku"
+
+#: controllers/components/stats.php:401
+msgid "statistics_longnames_unknown"
+msgstr "Neznáme"
+
+#: controllers/components/stats.php:397
+msgid "statistics_longnames_version"
+msgstr "Verzia doplnku"
+
+#: views/statistics/addon.thtml:118
+msgid "statistics_notice_data_insufficient"
+msgstr "Nedostatok údajov na zobrazenie grafu. Skontrolujte neskôr."
+
+#: views/statistics/addon.thtml:130
+msgid "statistics_notice_data_none"
+msgstr "Pre doplnok zatiaľ nie sú žiadne údaje. Skontrolujte o niekoľko dní."
+
+#: views/statistics/addon.thtml:41
+msgid "statistics_notice_data_updating"
+msgstr "Štatistika doplnku sa práve aktualizuje. Najnovšie údaje nemusia byť úplné, pretože naše skripty práve údaje aktualizujú. Skontrolujte o niekoľko minút."
+
+#: views/statistics/addon.thtml:136
+msgid "statistics_notice_disabled"
+msgstr "Štatistika je práve deaktivovaná. Skontrolujte neskôr."
+
+#: views/statistics/addon.thtml:123
+msgid "statistics_notice_nojavascript"
+msgstr "Na zobrazenie grafov štatistiky je potrebný JavaScript."
+
+#: views/statistics/addon.thtml:44
+msgid "statistics_notice_settings_updated"
+msgstr "Nastavenie bolo aktualizované!"
+
+#: controllers/statistics_controller.php:60
+#: controllers/statistics_controller.php:71
+#: controllers/statistics_controller.php:74
+#: controllers/statistics_controller.php:240
+msgid "statistics_pagetitle"
+msgstr "Å tatistika"
+
+#: views/statistics/addon.thtml:99
+msgid "statistics_plot_legend_adu"
+msgstr "Aktívni denní používatelia"
+
+#: views/statistics/addon.thtml:95
+msgid "statistics_plot_legend_downloads"
+msgstr "Denne prevzatí"
+
+#: views/statistics/addon.thtml:107
+msgid "statistics_plot_options_zoomin_alt"
+msgstr "ZväÄÅ¡iÅ¥"
+
+#: views/statistics/addon.thtml:106
+msgid "statistics_plot_options_zoomin_title"
+msgstr "ZväÄÅ¡iÅ¥ jeden mesiac"
+
+#: views/statistics/addon.thtml:110
+msgid "statistics_plot_options_zoomout_alt"
+msgstr "Zmenšiť"
+
+#: views/statistics/addon.thtml:109
+msgid "statistics_plot_options_zoomout_title"
+msgstr "Zmenšiť jeden mesiac"
+
+#: controllers/statistics_controller.php:283
+#, php-format
+msgid "statistics_rss_description"
+msgstr "Denné súhrn štatistiky pre %1$s"
+
+#: views/statistics/rss/summary.thtml:68
+msgid "statistics_rss_title_fulldate"
+msgstr "%A, %B %e, %Y"
+
+#: views/statistics/rss/summary.thtml:68
+#, php-format
+msgid "statistics_rss_title_statsfordate"
+msgstr "Å tatistika pre %1$s"
+
+#: views/statistics/settings.thtml:49
+msgid "statistics_settings_access_description"
+msgstr "V predvolenom nastavení má prístup k štatistike len Mozilla a vy. Môžete ju sprístupniť verejnosti, takže každý bude môcť prezerať údaje o doplnku."
+
+#: views/statistics/settings.thtml:48
+msgid "statistics_settings_access_heading"
+msgstr "Prístup k štatistike"
+
+#: views/statistics/settings.thtml:51
+msgid "statistics_settings_access_private"
+msgstr "Súkromná"
+
+#: views/statistics/settings.thtml:51
+msgid "statistics_settings_access_private_description"
+msgstr "Štatistiku môže prezerať len Mozilla a vy"
+
+#: views/statistics/settings.thtml:52
+msgid "statistics_settings_access_public"
+msgstr "Verejná"
+
+#: views/statistics/settings.thtml:52
+msgid "statistics_settings_access_public_description"
+msgstr "Štatistiku doplnku môže prezerať každý"
+
+#: views/statistics/addon.thtml:251
+msgid "statistics_settings_change_link"
+msgstr "Zmeniť nastavenie"
+
+#: views/statistics/addon.thtml:253
+msgid "statistics_settings_confidential"
+msgstr "Považujte tieto údaje za dôverné."
+
+#: views/statistics/addon.thtml:245
+msgid "statistics_settings_currently_private"
+msgstr "Táto štatistika je momentálne <b>súkromná</b>"
+
+#: views/statistics/addon.thtml:241
+msgid "statistics_settings_currently_public"
+msgstr "Táto štatistika je momentálne <b>verejná</b>"
+
+#: views/statistics/addon.thtml:246
+msgid "statistics_settings_locked_alt"
+msgstr "Zablokované"
+
+#: views/statistics/settings.thtml:57
+msgid "statistics_settings_return_link"
+msgstr "Návrat na štatistiku"
+
+#: views/statistics/settings.thtml:56
+msgid "statistics_settings_save_button"
+msgstr "Uložiť nastavenie"
+
+#: views/statistics/settings.thtml:46
+#, php-format
+msgid "statistics_settings_title"
+msgstr "Nastavenie Å¡tatistiky pre %1$s"
+
+#: views/statistics/addon.thtml:242
+msgid "statistics_settings_unlocked_alt"
+msgstr "Odblokované"
+
+#: controllers/components/stats.php:405
+msgid "statistics_shortnames_application"
+msgstr "Apl."
+
+#: controllers/components/stats.php:407
+msgid "statistics_shortnames_os"
+msgstr "OS"
+
+#: controllers/components/stats.php:406
+msgid "statistics_shortnames_status"
+msgstr "St"
+
+#: controllers/components/stats.php:408
+msgid "statistics_shortnames_unknown"
+msgstr "Nez."
+
+#: controllers/components/stats.php:404
+msgid "statistics_shortnames_version"
+msgstr "Ver."
+
+#: views/statistics/rss/summary.thtml:42
+#: views/statistics/addon.thtml:192
+msgid "statistics_summary_downloads_average"
+msgstr "Priemer prevzatí denne"
+
+#: views/statistics/rss/summary.thtml:39
+msgid "statistics_summary_downloads_heading"
+msgstr "Prevzatia"
+
+#: views/statistics/rss/summary.thtml:41
+#: views/statistics/addon.thtml:171
+msgid "statistics_summary_downloads_lastcount"
+msgstr "Prevzatí za posledný deň"
+
+#: views/statistics/rss/summary.thtml:43
+#: views/statistics/addon.thtml:199
+msgid "statistics_summary_downloads_lastweek"
+msgstr "Prevzatí sa posledných 7 dní"
+
+#: views/statistics/rss/summary.thtml:40
+#: views/statistics/addon.thtml:151
+msgid "statistics_summary_downloads_total"
+msgstr "Prevzatí celkom"
+
+#: views/statistics/rss/summary.thtml:40
+#: views/statistics/addon.thtml:152
+#, php-format
+msgid "statistics_summary_downloads_total_sincedate"
+msgstr "Od %1$s"
+
+#: views/statistics/rss/summary.thtml:50
+#: views/statistics/rss/summary.thtml:56
+#: views/statistics/addon.thtml:163
+#: views/statistics/addon.thtml:183
+msgid "statistics_summary_nodata"
+msgstr "Zatiaľ žiadne údaje"
+
+#: views/statistics/rss/summary.thtml:60
+#: views/statistics/addon.thtml:195
+msgid "statistics_summary_updatepings_average"
+msgstr "Denní aktívni používatelia priemerne"
+
+#: views/statistics/rss/summary.thtml:52
+#: views/statistics/addon.thtml:177
+msgid "statistics_summary_updatepings_changefromprevious"
+msgstr "Zmena od posledného poÄtu"
+
+#: views/statistics/rss/summary.thtml:54
+#: views/statistics/addon.thtml:181
+#, php-format
+msgid "statistics_summary_updatepings_changefromprevious_ondate"
+msgstr "%1$s dňa: %2$s"
+
+#: views/statistics/rss/summary.thtml:45
+msgid "statistics_summary_updatepings_heading"
+msgstr "Aktívni denní používatelia"
+
+#: views/statistics/rss/summary.thtml:46
+#: views/statistics/addon.thtml:157
+msgid "statistics_summary_updatepings_total"
+msgstr "Aktívni denní používatelia"
+
+#: views/statistics/rss/summary.thtml:48
+#: views/statistics/addon.thtml:161
+#, php-format
+msgid "statistics_summary_updatepings_total_ondate"
+msgstr "%1$s"
+
+#: views/statistics/rss/summary.thtml:61
+#: views/statistics/addon.thtml:203
+msgid "statistics_summary_updatepings_weekly_average"
+msgstr "Priemerný týždenný poÄet denných používateľov"
+
+#. %s is a percentage, like '+22.33%'. It sits next to another number, so
+#. the implied meaning is 'percentage change' from the previous stat point.
+#: views/statistics/rss/summary.thtml:62
+#: views/statistics/addon.thtml:205
+msgid "statistics_summary_updatepings_weekly_change"
+msgstr "%s oproti minulému týždňu"
+
+#: views/statistics/addon.thtml:65
+#: controllers/statistics_controller.php:184
+#: controllers/statistics_controller.php:282
+#, php-format
+msgid "statistics_title_addon_stats"
+msgstr "Å tatistika doplnku %1$s"
+
+#: views/addons/themes_landing.thtml:113
+msgid "themes_landing_all_themes"
+msgstr "Všetky témy"
+
+#: views/addons/themes_landing.thtml:109
+msgid "themes_landing_browse_themes"
+msgstr "Prehľadávať témy"
+
+#: views/users/edit.thtml:185
+msgid "user_change_email"
+msgstr "Zmeniť e-mailovú adresu"
+
+#: views/users/edit.thtml:169
+msgid "user_change_password"
+msgstr "Zmeniť heslo"
+
+#: views/users/edit.thtml:96
+msgid "user_change_password_or_email"
+msgstr "Zmena hesla alebo e-mailu"
+
+#: controllers/users_controller.php:197
+msgid "user_confirmationcode_resent"
+msgstr "Potvrdzovací kód znova odoslaný!"
+
+# %1 is the email address, %2 is the URL of the user registration page
+#. %1 is the email address, %2 is the URL of the user registration page
+#: views/users/delete.thtml:51
+msgid "user_del_account_deleted"
+msgstr "Používateľský úÄet %1$s bol úspeÅ¡ne odstránený. Ak sa rozhodnete vrátiÅ¥, môžete sa znova zaregistrovaÅ¥ na stránke <a href=\"%2$s\">registrácie používateľov</a>."
+
+#: views/users/delete.thtml:102
+msgid "user_del_community_sad"
+msgstr "Komunita Mozilla Add-ons je smutná z toho, že odchádzate."
+
+#: views/users/delete.thtml:123
+msgid "user_del_confirm_password"
+msgstr "Potvrdenie hesla"
+
+#: views/users/delete.thtml:134
+msgid "user_del_deletenow"
+msgstr "OdstrániÅ¥ môj úÄet"
+
+# %1 is the URL of the user's info page
+#. %1 is the URL of the user's info page
+#: views/users/delete.thtml:64
+msgid "user_del_error_addons"
+msgstr "Váš úÄet nemôžete odstrániÅ¥, ak ste uvedený ako <a href=\"%1$s\">autor niektorého z doplnkov</a>. Ak chcete tento úÄet odstrániÅ¥, musí najskôr niekto zo skupiny autorov vaÅ¡ich doplnkov odstrániÅ¥ váš úÄet zo zoznamu autorov týchto rozšírení. Následne môžete na tomto mieste váš úÄet odstrániÅ¥."
+
+# %1 is a link to the amo-editors mailing list
+#. %1 is a link to the amo-editors mailing list
+#: views/users/delete.thtml:71
+msgid "user_del_error_addons_more_questions"
+msgstr "Ak máte ÄalÅ¡ie otázky, kontaktujte nás na adrese %1$s."
+
+#: views/users/delete.thtml:78
+msgid "user_del_error_checkbox"
+msgstr "Pred odstránením úÄtu musíte oznaÄiÅ¥ pole \"Chápem, že…\"."
+
+#: views/users/delete.thtml:84
+msgid "user_del_error_password"
+msgstr "Na vykonanie tohto kroku musíte správne zadať vaše heslo."
+
+# %1 is a link to the amo-admins mailing list
+#. %1 is a link to the amo-admins mailing list
+#: views/users/delete.thtml:91
+msgid "user_del_error_unknown"
+msgstr "Pri odstraňovaní tohto úÄtu sa vyskytla neznáma chyba. Prosím, kontaktujte %1$s so žiadosÅ¥ou o odstránenie úÄtu a my to vykonáme. Ospravedlňujeme sa za túto nepríjemnosÅ¥."
+
+#: views/users/delete.thtml:110
+msgid "user_del_header_confirm_deletion"
+msgstr "Potvrdenie odstránenia úÄtu"
+
+# %1 is the user's email address
+#. %1 is the user's email address
+#: views/users/delete.thtml:100
+msgid "user_del_header_delete_account"
+msgstr "Odstránenie používateľského úÄtu %1$s"
+
+#: views/users/delete.thtml:50
+msgid "user_del_header_farewell"
+msgstr "Zbohom!"
+
+#: views/users/delete.thtml:115
+msgid "user_del_nologin"
+msgstr "Už sa nebudete môcť prihlásiť na stránkach Mozilla Add-ons."
+
+#: views/users/delete.thtml:112
+msgid "user_del_permanently_removed_means"
+msgstr "Po kliknutí na \"odstrániÅ¥\" bude tento úÄet <strong>nenávratne odstránený</strong>. To znamená, že:"
+
+#: views/users/delete.thtml:116
+msgid "user_del_reviews_anonymized"
+msgstr "VaÅ¡e recenzie a hodnotenia nebudú odstránené, ale už nebudú priradené tomuto úÄtu."
+
+# %1 is a link to the amo-editors mailing list
+#. %1 is a link to the amo-editors mailing list
+#: views/users/delete.thtml:104
+msgid "user_del_specific_problem_editors"
+msgstr "Ak máte nejaký problém, s ktorým by sme vám mohli pomôcÅ¥, neodstraňujte zatiaľ váš úÄet, ale kontaktujte nás na adrese %1$s a my urobíme vÅ¡etko preto, aby sme daný problém vyrieÅ¡ili."
+
+#: views/users/delete.thtml:130
+msgid "user_del_understand_permanent"
+msgstr "Chápem, že tento krok nie je možné vrátiť späť."
+
+#: views/helpers/addons_html.php:192
+msgid "user_deleted_nickname"
+msgstr "Odstránený používateľ"
+
+# %1 is the new email address
+#. %1 is the new email address
+#: views/users/edit.thtml:71
+msgid "user_edit_confirm_email_sent"
+msgstr "Na adresu %1$s bola odoslaná overovacia e-mailová správa. Aby bola táto zmena úspešne vykonaná, musíte kliknúť na odkaz nachádzajúci sa v tejto správe. Dovtedy sa môžete prihlasovať použitím aktuálne používanej e-mailovej adresy."
+
+#: views/users/edit.thtml:201
+msgid "user_edit_delete_user"
+msgstr "OdstrániÅ¥ používateľský úÄet"
+
+# This contains the email sent to users when they signed up for a new
+# account:
+# %1 is the confirmation URL, %2 is the current app
+#. This contains the email sent to users when they signed up for a new
+#. account:
+#. %1 is the confirmation URL, %2 is the current app
+#: views/users/email/confirm_plain.thtml:6
+#, php-format
+msgid "user_email_confirm_account_nopass"
+msgstr ""
+"Vitajte na %2$s Add-ons.\n"
+"\n"
+"Najprv je potrebné nový úÄet aktivovaÅ¥. Tým spolu skontrolujeme platnosÅ¥ použitej e-mailovej adresy.\n"
+"Ak chcete aktivovaÅ¥ úÄet, kliknite na dole uvedený odkaz alebo ho skopírujte a prilepte v prehliadaÄi do panela adresy:\n"
+"\n"
+"%1$s\n"
+"\n"
+"Po úspeÅ¡nom aktivovaní úÄtu môžete tento e-mail zahodiÅ¥.\n"
+"\n"
+"Ďakujeme, že ste sa pripojili k %2$s Add-ons.\n"
+"-- Tím %2$s Add-ons"
+
+# %1 is the confirmation url, %2 is the application name
+#. %1 is the confirmation url, %2 is the application name
+#: views/users/email/emailchange_plain.thtml:5
+msgid "user_email_confirm_emailchange"
+msgstr ""
+"Požiadali ste o zmenu e-mailovej adresy vášho úÄtu na %2$s Add-ons.\n"
+"\n"
+"Ak chcete túto zmenu potvrdiÅ¥, kliknite na odkaz uvedený nižšie alebo skopírujte adresu a zadajte ju do webového prehliadaÄa:\n"
+"\n"
+"%1$s\n"
+"\n"
+"Na potvrdenie novej e-mailovej adresy máte 48 hodín. Ak ju nechcete zmeniť, ignorujte túto správu.\n"
+"\n"
+"ÄŽakujeme!\n"
+"-- Tím %2$s Add-ons"
+
+#: controllers/users_controller.php:168
+#, php-format
+msgid "user_email_confirm_subject"
+msgstr "Ďakujeme, že ste sa pripojili k %s Add-ons"
+
+# This is the password reset email
+# %1 is the pw reset URL, %2 is the application
+#. This is the password reset email
+#. %1 is the pw reset URL, %2 is the application
+#: views/users/email/pwreset_plain.thtml:5
+#, php-format
+msgid "user_email_pwreset"
+msgstr ""
+"Vynulovanie hesla pre %2$s Add-ons\n"
+"\n"
+"Bola prijatá žiadosÅ¥ o vynulovanie hesla pre tento úÄet na stránke addons.mozilla.org. Ak chcete zmeniÅ¥ heslo, kliknite na nasledujúci odkaz, alebo ho zadajte v prehliadaÄi do panela adresy:\n"
+"\n"
+"%1$s\n"
+"\n"
+"Ak ste žiadosť nepodali, nie je potrebná žiadna akcia.\n"
+"\n"
+"ÄŽakujeme,\n"
+"-- Tím %2$s Add-ons"
+
+#: controllers/users_controller.php:245
+#, php-format
+msgid "user_email_pwreset_subject"
+msgstr "Vynulovanie hesla pre %s Add-ons"
+
+#: views/users/emailchange.thtml:50
+msgid "user_emailchange_error"
+msgstr "Chyba!"
+
+# %1 is the application name
+#. %1 is the application name
+#: controllers/users_controller.php:533
+msgid "user_emailchange_subject"
+msgstr "Prosím, potvrÄte zmenu vaÅ¡ej e-mailovej adresy konta na %1$s Add-ons"
+
+#: views/users/emailchange.thtml:48
+msgid "user_emailchange_success"
+msgstr "Zmena úspešná!"
+
+# %1 is the new email address
+#. %1 is the new email address
+#: views/users/emailchange.thtml:49
+msgid "user_emailchange_successful_description"
+msgstr "Vaša e-mailová adresa bola úspešne zmenená. Odteraz sa prihlasujte použitím adresy %1$s."
+
+#: views/users/edit.thtml:134
+#: views/admin/users_edit.thtml:111
+msgid "user_form_bio"
+msgstr "O mne"
+
+#: views/users/edit.thtml:135
+#: views/admin/users_edit.thtml:112
+msgid "user_form_bio_description"
+msgstr "Predstavte sa komunite, ak chcete! Tento text sa objaví na informaÄnej stránke o Vás. Zlomy riadkov budú zachované, kód HTML nie je povolený."
+
+#: views/users/pwreset.thtml:77
+#: views/users/register.thtml:73
+#: views/users/edit.thtml:181
+msgid "user_form_confirmpassword"
+msgstr "Potvrdiť heslo"
+
+#: views/users/edit.thtml:145
+msgid "user_form_display_collections"
+msgstr "Zobraziť kolekcie, ktoré som vytvoril v mojom používateľskom profile"
+
+#: views/users/edit.thtml:149
+msgid "user_form_display_collections_fav"
+msgstr "Zobraziť obľúbené kolekcie v mojom používateľskom profile"
+
+#: views/users/edit.thtml:86
+#, php-format
+msgid "user_form_editprofile"
+msgstr "Upraviť profil používateľa pre %s"
+
+#: views/users/pwreset.thtml:52
+#: views/users/login.thtml:81
+#: views/users/register.thtml:63
+#: views/users/edit.thtml:187
+msgid "user_form_email"
+msgstr "E-mailová adresa"
+
+#: views/users/register.thtml:78
+#: views/users/edit.thtml:103
+#: views/admin/users_edit.thtml:76
+msgid "user_form_firstname"
+msgstr "Krstné meno"
+
+#: views/users/register.thtml:94
+#: views/users/edit.thtml:119
+#: views/admin/users_edit.thtml:91
+msgid "user_form_hideemail"
+msgstr "Skryť e-mailovú adresu"
+
+#: views/users/register.thtml:98
+#: views/users/edit.thtml:123
+#: views/admin/users_edit.thtml:99
+msgid "user_form_homepage"
+msgstr "Adresa webovej stránky"
+
+#: views/users/register.thtml:84
+#: views/users/edit.thtml:109
+#: views/admin/users_edit.thtml:81
+msgid "user_form_lastname"
+msgstr "Priezvisko"
+
+#: controllers/users_controller.php:333
+msgid "user_form_login"
+msgstr "Prihlásenie používateľa"
+
+#: views/users/pwreset.thtml:72
+#: views/users/edit.thtml:176
+msgid "user_form_newpassword"
+msgstr "Nové heslo"
+
+#: views/users/register.thtml:89
+#: views/users/edit.thtml:114
+#: views/admin/users_edit.thtml:86
+msgid "user_form_nickname"
+msgstr "Prezývka"
+
+#: views/users/edit.thtml:171
+msgid "user_form_oldpassword"
+msgstr "Staré heslo"
+
+#: views/users/edit.thtml:97
+#: views/users/edit.thtml:200
+msgid "user_form_otheractions"
+msgstr "Ďalšie akcie"
+
+#: views/users/login.thtml:85
+#: views/users/register.thtml:68
+msgid "user_form_password"
+msgstr "Heslo"
+
+#: controllers/users_controller.php:93
+msgid "user_form_registration"
+msgstr "Registrácia nového používateľa"
+
+#: views/users/login.thtml:90
+msgid "user_form_remember_me"
+msgstr "ZapamätaÅ¥ si ma na tomto poÄítaÄi"
+
+#: views/admin/users_edit.thtml:95
+msgid "user_form_showsandbox"
+msgstr "Zobraziť Sandbox?"
+
+#: views/users/edit.thtml:205
+msgid "user_form_submit_edit"
+msgstr "Uložiť"
+
+#: views/users/login.thtml:93
+msgid "user_form_submit_login"
+msgstr "Prihlásiť"
+
+#: views/users/register.thtml:113
+msgid "user_form_submit_register"
+msgstr "Zaregistrovať"
+
+#: views/users/info.thtml:75
+#, php-format
+msgid "user_info_usersince"
+msgstr "Používateľ %s Add-ons od:"
+
+#: views/users/login.thtml:102
+msgid "user_login_register_link"
+msgstr "VytvoriÅ¥ nový úÄet"
+
+#: views/users/edit.thtml:160
+msgid "user_notifications_item_compat"
+msgstr "Kompatibilita doplnku (dôrazne odporúÄané)"
+
+#: views/users/edit.thtml:161
+msgid "user_notifications_item_events"
+msgstr "Nadchádzajúce udalosti a súťaže"
+
+#: views/users/edit.thtml:156
+msgid "user_notifications_none_available"
+msgstr "Momentálne nie sú dostupné žiadne notifikácie, ktoré môžete nastavovať."
+
+#: views/users/edit.thtml:158
+msgid "user_notifications_select_topics"
+msgstr "Z Äasu na Äas Vám Mozilla môže odoslaÅ¥ e-mailovú správu s informáciou o nadchádzajúcich vydaniach alebo udalostí. Prosím, zvoľte si oblasti, ktoré Vás zaujímajú:"
+
+#: views/users/edit.thtml:164
+msgid "user_notifications_specific_contact"
+msgstr "Mozilla si vyhradzuje právo individuálne Vás kontaktovať ohľadne špecifických záležitostí vašich doplnkov hostovaných Mozillou."
+
+#: controllers/users_controller.php:543
+msgid "user_profile_edit_error"
+msgstr "V zmenách, ktoré ste urobili, sú chyby. Opravte ich a odošlite znova."
+
+#: controllers/users_controller.php:540
+msgid "user_profile_saved"
+msgstr "Profil aktualizovaný."
+
+#: views/users/pwreset.thtml:65
+#, php-format
+msgid "user_pwreset_for_email"
+msgstr "Vynulovanie hesla pre %s"
+
+#: controllers/users_controller.php:226
+msgid "user_pwreset_header"
+msgstr "Vynulovanie hesla"
+
+#: views/users/login.thtml:103
+msgid "user_pwreset_link"
+msgstr "Zabudli ste heslo?"
+
+#: controllers/users_controller.php:248
+msgid "user_pwreset_link_sent"
+msgstr "Odkaz na vynulovanie hesla bol odoslaný na vašu e-mailovú adresu."
+
+#: controllers/users_controller.php:304
+msgid "user_pwreset_okay"
+msgstr "Heslo úspešne vynulované."
+
+#: views/users/pwreset.thtml:82
+msgid "user_pwreset_submit_changepw"
+msgstr "Odoslať zmenu hesla"
+
+#: views/users/pwreset.thtml:57
+msgid "user_pwreset_submit_sendlink"
+msgstr "Odoslať vynulovanie hesla"
+
+#: views/users/register_complete.thtml:51
+#, php-format
+msgid "user_register_amo_link"
+msgstr "%s Add-ons"
+
+# %1 is the user's email address, %2 is the current app
+#. %1 is the user's email address, %2 is the current app
+#: views/users/activatefirst.thtml:49
+#, php-format
+msgid "user_register_click_confirm_link"
+msgstr "Odkaz na aktivovanie používateľského úÄtu bol odoslaný e-mailom na adresu %1$s. Pred prihlásením na %2$s Add-ons je potrebné na tento odkaz kliknúť."
+
+# %1 is the user's email address
+#. %1 is the user's email address
+#: views/users/register_complete.thtml:49
+#, php-format
+msgid "user_register_confirm_email_sent"
+msgstr "Na adresu %1$s bol odoslaný e-mail, ktorým potvrdíte svoj úÄet. Pred tým, než sa budete môcÅ¥ prihlásiÅ¥, je potrebné aktivovaÅ¥ úÄet kliknutím na odkaz, ktorý sa nachádza v tejto e-mailovej správe."
+
+#: views/users/activatefirst.thtml:51
+msgid "user_register_confirmation_link_text"
+msgstr "znova odoslať potvrdzovaciu správu"
+
+#: views/users/register_complete.thtml:47
+msgid "user_register_congratulations"
+msgstr "Blahoželáme! Váš úÄet používateľa bol úspeÅ¡ne vytvorený."
+
+#: views/users/register.thtml:50
+msgid "user_register_details"
+msgstr "<p>Registrácia stránke AMO <strong>nie je vyžadovaná</strong>, ak chcete preberaÅ¥ a inÅ¡talovaÅ¥ verejné doplnky.</p><p>ZaregistrovaÅ¥ sa musíte len v prípade, že:</p><ul><li>chcete odoslaÅ¥ recenziu na nejaký doplnok</li><li>ste vývojárom doplnkov a chcete váš doplnok umiestniÅ¥ na stránke AMO</li></ul><p>Po úspeÅ¡nej registrácii obdržíte na zadanú adresu potvrdzovaciu e-mailovú správu. ÚÄet potvrdíte nasledovaním krokov popísaných v tejto správe.</p><p>Ak chcete, môžete si preÄítaÅ¥ <a href='%1$s' title='Právne informácie'>Právne informácie</a> a <a href='%2$s' title='Zásady ochrany súkromia'>Zásady ochrany súkromia</a>.</p>"
+
+# %1 is the link to the "resend confirmation code" page
+#. %1 is the link to the "resend confirmation code" page
+#: views/users/activatefirst.thtml:51
+#, php-format
+msgid "user_register_resend_confirmation_link"
+msgstr "Ak ste nedostali potvrdzovací e-mail, skontrolujte svoju e-mailovú službu, Äi neoznaÄila správu ako \"spam\". V prípade potreby môžete %1$s na e-mailovú adresu uvedenú vyÅ¡Å¡ie."
+
+# %1 is the link to the Mozilla Add-ons front page
+#. %1 is the link to the Mozilla Add-ons front page
+#: views/users/register_complete.thtml:51
+#, php-format
+msgid "user_register_welcome"
+msgstr "Ďakujeme za registráciu a vítame vás na %1$s!"
+
+#: views/users/register.thtml:49
+msgid "user_register_welcome_header"
+msgstr "Víta vás addons.mozilla.org (AMO)!"
+
+#: views/users/register.thtml:81
+#: views/users/edit.thtml:106
+msgid "user_required_firstlast_or_nickname"
+msgstr "Vyžaduje sa meno, priezvisko alebo prezývka."
+
+#: views/users/edit.thtml:94
+#: views/users/edit.thtml:142
+msgid "user_tab_collections"
+msgstr "Kolekcie"
+
+#: views/users/edit.thtml:95
+#: views/users/edit.thtml:154
+msgid "user_tab_notifications"
+msgstr "Upozornenia"
+
+#: views/users/edit.thtml:93
+#: views/users/edit.thtml:101
+msgid "user_tab_profile"
+msgstr "Profil používateľa"
+
+#: controllers/users_controller.php:209
+msgid "user_verified_okay"
+msgstr "Úspešne overené!"
+
+#: controllers/users_controller.php:723
+msgid "users_delete_pagetitle"
+msgstr "OdstrániÅ¥ používateľský úÄet"
+
+#: controllers/users_controller.php:414
+msgid "users_edit_pagetitle"
+msgstr "Úprava používateľského úÄtu"
+
+#: views/users/info.thtml:71
+msgid "users_info_aboutme"
+msgstr "O mne"
+
+#: views/users/info.thtml:96
+#, php-format
+msgid "users_info_addons_by_user"
+msgstr "Doplnky od autora %1$s"
+
+#: views/users/info.thtml:51
+msgid "users_info_author_name"
+msgstr "Meno"
+
+#: views/users/info.thtml:48
+msgid "users_info_author_profile"
+msgstr "Profil autora"
+
+#. %s is the user name
+#: views/users/info.thtml:137
+msgid "users_info_collections_by_user"
+msgstr "Kolekcie autora %s"
+
+#: views/users/info.thtml:66
+msgid "users_info_email"
+msgstr "E-mailová adresa"
+
+#: views/users/info.thtml:155
+msgid "users_info_fav_collections_by_user"
+msgstr "Obľúbené kolekcie"
+
+#: views/users/info.thtml:61
+msgid "users_info_homepage"
+msgstr "Domovská stránka"
+
+#: views/users/info.thtml:56
+msgid "users_info_nickname"
+msgstr "Prezývka"
+
+#: controllers/users_controller.php:707
+#, php-format
+msgid "users_info_pagetitle"
+msgstr "Informácie o používateľovi %1$s"
+
+# %1 is the user's name
+#. %1 is the user's name
+#: views/users/info.thtml:116
+msgid "users_info_reviews_by_user"
+msgstr "Recenzie používateľa %s"
+
+#: controllers/users_controller.php:330
+#: controllers/users_controller.php:332
+msgid "users_login_pagetitle"
+msgstr "Prihlásenie používateľa"
+
+# %1 is the link to the sandbox/policy explanation page
+# This message is for a specific add-on not found
+#. %1 is the link to the sandbox/policy explanation page
+#. This message is for a specific add-on not found
+#: views/users/login.thtml:53
+#, php-format
+msgid "users_login_sandbox_display_warning"
+msgstr "Doplnok, ktorý hľadáte, je momentálne v Sandboxe. Ak máte úÄet na Mozilla Add-ons, prihláste sa alebo si <a href=\"%1$s\">preÄítajte o Sandboxe</a> ÄalÅ¡ie informácie."
+
+# %1 is the link to the sandbox/policy explanation page
+# This message is for any given sandbox-related page not found
+#. %1 is the link to the sandbox/policy explanation page
+#. This message is for any given sandbox-related page not found
+#: views/users/login.thtml:56
+#, php-format
+msgid "users_login_sandbox_page_warning"
+msgstr "Stránka, ktorú hľadáte, je súÄasÅ¥ou Sandboxu. Ak máte úÄet na Mozilla Add-ons, prihláste sa alebo si <a href=\"%1$s\">preÄítajte o Sandboxe</a> ÄalÅ¡ie informácie."
+
+#: controllers/users_controller.php:223
+#: controllers/users_controller.php:225
+msgid "users_pwreset_pagetitle"
+msgstr "Vynulovanie používateľského hesla"
+
+#: controllers/users_controller.php:90
+#: controllers/users_controller.php:92
+msgid "users_register_pagetitle"
+msgstr "Registrácia nového používateľa"
+
+#. %1$s is an addon name, like <a>Firebug</a>
+#. %2$s is a version number, like <a>1.2</a>
+#: views/versions/license.thtml:52
+msgid "versions_license_header_source"
+msgstr "Licencia pre zdrojový kód doplnku %1$s %2$s"
+
+#: views/addons/category_landing.thtml:147
+msgid "view_recently_added"
+msgstr "Zobraziť všetky naposledy pridané"
+
+#: views/addons/category_landing.thtml:161
+msgid "view_top_downloads"
+msgstr "ZobraziÅ¥ vÅ¡etky najÄastejÅ¡ie preberané"
+
+#: views/addons/category_landing.thtml:175
+msgid "view_top_rated"
+msgstr "Zobraziť všetky najlepšie hodnotené"
+
+#~ msgid "addon_slider_tooltip_next"
+#~ msgstr "Ďalší doplnok"
+#~ msgid "addon_slider_tooltip_previous"
+#~ msgstr "Predchádzajúci doplnok"
+#~ msgid "addon_versions_getlatesttext"
+#~ msgstr "Posledná verzia je kompatibilná s aplikáciou"
+#~ msgid "addons_display_version_history"
+#~ msgstr "Úplná história verzií"
+#~ msgid "addons_home_newest_header"
+#~ msgstr "Najnovšie:"
+#~ msgid "addons_home_popular_header"
+#~ msgstr "Najobľúbenejšie:"
+#~ msgid "addons_home_recommended_header"
+#~ msgstr "OdporúÄame:"
+#~ msgid "addons_home_updated_header"
+#~ msgstr "Naposledy aktualizované:"
+#~ msgid "addons_home_view_all"
+#~ msgstr "Zobraziť všetky"
+#~ msgid "category_extra_allrecommended"
+#~ msgstr "ZobraziÅ¥ vÅ¡etky odporúÄané doplnky"
+#~ msgid "category_extra_highestrated"
+#~ msgstr "Najprv najvyššie hodnotené"
+#~ msgid "category_extra_lastupdated"
+#~ msgstr "Najprv naposledy aktualizované"
+#~ msgid "category_extra_mostpopular"
+#~ msgstr "Najprv najobľúbenejšie"
+#~ msgid "collections_detail_js_loading"
+#~ msgstr "NaÄítava sa"
+#~ msgid "collections_detail_more_info"
+#~ msgstr "ZobraziÅ¥ ÄalÅ¡ie informácie"
+#~ msgid "devcp_additem_firefox_notice"
+#~ msgstr ""
+#~ "Táto verzia doplnku nie je kompatibilná s Firefoxom %s. Mozilla "
+#~ "predpokladá, že nasledujúca verzia Firefoxu bude Äoskoro vydaná. "
+#~ "Otestujte preto svoj doplnok v novej verzii a aktualizujte údaj o "
+#~ "kompatibilite. Ďalšie informácie nájdete na <a href=\"%s\">tejto stránke</"
+#~ "a>. Toto je len oznámenie, môžete pokraÄovaÅ¥ v odosielaní tejto verzie na "
+#~ "addons.mozilla.org."
+#~ msgid "devcp_addon_disabled_successfully"
+#~ msgstr "Doplnok úspešne zakázaný"
+#~ msgid "devcp_addon_edit_pagetitle"
+#~ msgstr "Upraviť doplnok"
+#~ msgid "devcp_addon_enabled_successfully"
+#~ msgstr "Doplnok úspešne povolený"
+#~ msgid "devcp_addon_field_description_displaytitle"
+#~ msgstr "Popis doplnku"
+#~ msgid "devcp_addon_field_eula_displaytitle"
+#~ msgstr "LicenÄná zmluva"
+#~ msgid "devcp_addon_field_homepage_displaytitle"
+#~ msgstr "Domovská stránka doplnku"
+#~ msgid "devcp_addon_field_name_displaytitle"
+#~ msgstr "Názov doplnku"
+#~ msgid "devcp_addon_field_privacy_displaytitle"
+#~ msgstr "Zásady ochrany súkromia"
+#~ msgid "devcp_addon_field_summary_displaytitle"
+#~ msgstr "Súhrn doplnku"
+#~ msgid "devcp_addon_field_supportemail_displaytitle"
+#~ msgstr "E-mail na podporu"
+#~ msgid "devcp_addon_field_supporturl_displaytitle"
+#~ msgstr "Adresa URL na podporu"
+#~ msgid "devcp_addon_field_versionnotes_displaytitle"
+#~ msgstr "Poznámky k verziám"
+#~ msgid "devcp_addon_nominate_pagetitle"
+#~ msgstr "Nominovať doplnok"
+#~ msgid "devcp_addon_nominated_successfully"
+#~ msgstr "Doplnok úspešne nominovaný!"
+#~ msgid "devcp_addon_status_criteria_review"
+#~ msgstr "Niekoľko recenzií doplnku (môžu byť externé recenzie)."
+#~ msgid "devcp_submit_accept_dev_agreement"
+#~ msgstr "Súhlasím"
+#~ msgid "devcp_submit_decline_dev_agreement"
+#~ msgstr "Nesúhlasím"
+#~ msgid "editors_submissiontype_new"
+#~ msgstr "Nové"
+#~ msgid "editors_submissiontype_updated"
+#~ msgstr "Aktualizované"
+#~ msgid "editors_th_addon_age"
+#~ msgstr "Vek doplnku"
+#~ msgid "editors_th_addontypes"
+#~ msgstr "Typy doplnkov"
+#~ msgid "editors_th_applications"
+#~ msgstr "Aplikácie"
+#~ msgid "editors_th_platforms"
+#~ msgstr "Platformy"
+#~ msgid "editors_th_submissiontypes"
+#~ msgstr "Typy odoslania"
+#~ msgid "forum_save"
+#~ msgstr "Uložiť"
+#~ msgid "home"
+#~ msgstr "domov"
+#~ msgid "nav_category_plugins"
+#~ msgstr "Zásuvné moduly"
+#~ msgid "search_matching_addons_number"
+#~ msgid_plural "search_matching_addons_number"
+#~ msgstr[0] "%s zodpovedajúci doplnok"
+#~ msgstr[1] "%s zodpovedajúce doplnky"
+#~ msgstr[2] "%s zodpovedajúcich doplnkov"
+
diff --git a/site/app/locale/sk/images/sandbox-review.png b/site/app/locale/sk/images/sandbox-review.png
new file mode 100644
index 0000000..d2d6921
--- /dev/null
+++ b/site/app/locale/sk/images/sandbox-review.png
Binary files differ
diff --git a/site/app/locale/sk/pages/collector.thtml b/site/app/locale/sk/pages/collector.thtml
new file mode 100644
index 0000000..f28f4d3
--- /dev/null
+++ b/site/app/locale/sk/pages/collector.thtml
@@ -0,0 +1,47 @@
+<h2>Rozšírenie Add-on Collector pre Mozilla Firefox</h2>
+
+<p class="intro">Majte vždy najlepÅ¡ie prispôsobený prehliadaÄ</p>
+
+<div class="primary">
+ <p>Objavte najlepšie a organizujte obľúbené doplnky v jednoducho spravovateľných kolekciách. Odoberajte ich a obdivujte, ako vaše obľúbené kolekcie rastú a ako vaše kolekcie ich fanúšikovia aktualizujú.</p>
+</div>
+
+<div class="secondary">
+ <div class="highlight">
+ <h4>Prevezmite si rozšírenie Add-on Collector:</h4>
+ %1$s
+ </div><!-- /.highlight -->
+</div>
+
+<div class="column-wrapper article-wrapper">
+
+ <div class="column first">
+ <div class="article">
+ <h3>OdporúÄané kolekcie</h3>
+ <p>Odoberajte kolekcie doplnkov a dostávajte upozornenia pri ich aktualizácii. Ak vytvárate kolekciu, môžete informovaÅ¥, preÄo pridávate konkrétny doplnok, Äi poskytnúť iné informácie.</p>
+
+ </div>
+ </div>
+
+ <div class="column">
+ <div class="article">
+ <h3>Zdieľanie doplnkov</h3>
+ <p>Povedzte známym o vaÅ¡ich objavoch. Zvoľte voľbu “PublikovaÅ¥ do†a známi dostanú informáciu o nových doplnkoch, ktoré si budú môcÅ¥ hneÄ aj nainÅ¡talovaÅ¥.</p>
+ </div>
+
+ </div>
+
+
+ <div class="column">
+ <div class="article">
+ <h3>Synchronizácia</h3>
+ <p>Oznamujte nové kolekcie doplnkov a poskytujte odkazy, ktoré vÄaka funkcii Automatické publikovanie zostanú vždy aktuálne. Synchronizujte zariadenia a majte tak vo vÅ¡etkých prehliadaÄoch vaÅ¡u obľúbenú kolekciu doplnkov.</p>
+ </div>
+ </div>
+
+</div><!-- /.column-wrapper .article-wrapper -->
+
+<ul class="further-navigation">
+ <li><a href="%2$s">Funkcie rozšírenia Add-on Collector</a></li>
+ <li><a href="%3$s">Často kladené otázky</a></li>
+</ul>
diff --git a/site/app/locale/sk/pages/collector_faq.thtml b/site/app/locale/sk/pages/collector_faq.thtml
new file mode 100644
index 0000000..1f052b2
--- /dev/null
+++ b/site/app/locale/sk/pages/collector_faq.thtml
@@ -0,0 +1,24 @@
+<h2>Často kladené otázky pre Add-on Collector</h2>
+
+<dl class="faq">
+<dt>Čo sú to kolekcie?</dt>
+<dd>Kolekcie sú skupiny podobných doplnkov zoskupených za úÄelom jednoduchého zdieľania.</dd>
+
+<dt>Čo je rozšírenie Add-on Collector?</dt>
+<dd>Add-on Collector je rozšírenie pre Firefox, ktoré umožňuje jednoduchú synchronizáciu s vašimi obľúbenými kolekciami.</dd>
+
+<dt>Čo potrebujem, aby som mohol rozšírenie Add-on Collector používať?</dt>
+<dd>Potrebujete maÅ¥ <a href="%s">úÄet na Mozilla Add-ons</a> a poslednú verziu <a href="http://www.getfirefox.com">Firefoxu</a>.</dd>
+
+<dt>Ako môžem odoberať kolekciu?</dt>
+<dd>Kolekciu môžete odoberaÅ¥ jej oznaÄením ako obľúbená v <a href="%s">prieÄinku Kolekcie</a>. VaÅ¡e obľúbené kolekcie sa zobrazia ako odoberané v Správcovi doplnkov.</dd>
+
+<dt>Ako môžem pomocou rozšírenia Add-on Collector synchronizovaÅ¥ moje doplnky medzi poÄítaÄmi?</dt>
+<dd>PostaÄí si na jednom poÄítaÄi nastaviÅ¥ automatické publikovanie a nové doplnky sa vám zobrazia navrchu zoznamu na odoberanie na vÅ¡etkých poÄítaÄoch, kde máte rozšírenie Add-on Collector nainÅ¡talované. Potom budete môcÅ¥ vidieÅ¥ nainÅ¡talované doplnky na každom poÄítaÄi, ktorý má nastavené automatické publikovanie.</dd>
+
+<dt>Nie je Weave od Mozilla Labs spôsob, ako môžem synchronizovať svoje doplnky?</dt>
+<dd>Weave plánuje do budúcna podporu synchronizácie doplnkov medzi profilmi a zariadeniami. Synchronizácia rozšírenia Add-on Collector funguje trochu odlišne. Automaticky publikované údaje nie sú šifrované a sú prispôsobené na zdieľanie medzi priateľmi vo forme kolekcie. Doplnky je možné zdieľať medzi profilmi pomocou viacerých kolekcií.</dd>
+
+<dt>Kde sa môžem k rozšíreniu vyjadriÅ¥ Äi nahlásiÅ¥ chybu?</dt>
+<dd>Ak nájdete chybu alebo chcete zaslať pripomienku, vyplňte v Bugzille <a href="https://bugzilla.mozilla.org/enter_bug.cgi?component=Bandwagon&amp;product=addons.mozilla.org">tento formulár</a>. Ak chcete poslať všeobecnú reakciu, pridajte ju do <a href="http://groups.google.com/group/mozilla.dev.amo">našej diskusnej skupiny</a>.</dd>
+</dl>
diff --git a/site/app/locale/sk/pages/collector_features.thtml b/site/app/locale/sk/pages/collector_features.thtml
new file mode 100644
index 0000000..6018ad4
--- /dev/null
+++ b/site/app/locale/sk/pages/collector_features.thtml
@@ -0,0 +1,33 @@
+<h2>Rozšírenie Add-on Collector pre Mozilla Firefox</h2>
+<h4>Majte vždy najlepÅ¡ie prispôsobený prehliadaÄ.</h4>
+<h3>Funkcie rozšírenia</h3>
+<p>
+ Rozšírenie Add-on Collector vám umožňuje jednoduchý prístup k vašim obľúbeným doplnkom
+ a kolekciám a to hneÄ niekoľkými spôsobmi:
+</p>
+
+<dl>
+ <dt>Prístup k obľúbeným kolekciám z Firefoxu</dt>
+ <dd>
+ Kolekcie, ktoré oznaÄíte v
+ <a href="%1$s">prieÄinku Kolekcie</a> ako obľúbené, sa objavia v oddelenej sekcii
+ Správcu doplnkov. Budete tak môcť vidieť aktualizovaný obsah každej kolekcie.
+ </dd>
+ <dt>Zdieľanie doplnkov pomocou publikovania</dt>
+ <dd>
+ Každý doplnok, ktorý si nainštalujete, je možné jednoducho zdieľať s kamarátmi pomocou e-mailu
+ Äi publikovaÅ¥ ho do jednej z vaÅ¡ich kolekcií pomocou ponuky urÄenej na publikovanie.
+ </dd>
+ <dt>Prijímanie upozornení</dt>
+ <dd>
+ Rozšírenie vás upozorní, keÄ sa v nejakej z vaÅ¡ich obľúbených kolekcií objaví
+ nová položka a oznaÄí ju, aby ste si ju mohli neskôr prezrieÅ¥.
+ </dd>
+
+ <dt>Automatické publikovanie vašich nainštalovaných doplnkov do kolekcie</dt>
+ <dd>
+ Funkcia automatického publikovania umožní pravidelnú synchronizáciu vašej kolekcie
+ s doplnkami, ktoré máte nainštalované. Kamaráti, ktorí vašu kolekciu odoberajú,
+ budú na aktuálny stav kolekcie vždy upozornení.
+ </dd>
+</dl>
diff --git a/site/app/locale/sk/pages/collector_firstrun.thtml b/site/app/locale/sk/pages/collector_firstrun.thtml
new file mode 100644
index 0000000..9124cf9
--- /dev/null
+++ b/site/app/locale/sk/pages/collector_firstrun.thtml
@@ -0,0 +1,38 @@
+<div>
+ <h2>Vítame vás</h2>
+ <p class="intro">Rozšírenie Add-on Collector bolo nainÅ¡talované do vaÅ¡ej kópie prehliadaÄa Firefox. Už ste takmer pripravení zaÄaÅ¥ vytváraÅ¥, spravovaÅ¥, zdieľaÅ¥ a prijímaÅ¥ kolekcie doplnkov..</p>
+</div>
+
+ <div class="primary">
+ <h3>Ak chcete zaÄaÅ¥ používaÅ¥ Firefox Add-on Collector</h3>
+ <ol class="numbered">
+ <li>
+ <h4 class="step">1</h4>
+ Kliknite na ponuku Nástroje v hlavnej ponuke Firefoxu a kliknite na položku “Doplnkyâ€.
+ </li>
+ <li>
+ <h4 class="step">2</h4>
+ Na paneli Odbery sa prihláste pomocou podobne ako na sa prihlasujete na stránke Mozilla Addons.
+ </li>
+ <li>
+ <h4 class="step">3</h4>
+ Na ľavej strane sa vám zobrazí zoznam vÅ¡etkých vaÅ¡ich kolekcií. Ak chcete zobraziÅ¥ obsah kolekcie, kliknite na ňu. Ak chcete spravovaÅ¥ alebo zdieľaÅ¥ vaÅ¡u kolekciu, kliknite na tlaÄidlá "PridaÅ¥ do programu Firefox" Äi "PublikovaÅ¥ do".
+ </li>
+ </ol>
+ <p>Je jedno, Äi ste dychtivý lovec doplnkov alebo niekto, kto používa doplnky na zlepÅ¡enie zážitkov z prehliadania webu, rozšírenie Add-on Collector je tu preto, aby vám pomohlo. Ak chcete viac informácií o možnostiach rozšírenia Add-on Collector alebo hľadáte Äasto kladené otázky, pozrite si <a href="%1$s">stránku o funkciách</a> a <a href="%2$s">ÄŒasto kladené otázky pre Add-on Collector</a>.</p>
+ </div><!-- / .primary -->
+
+ <div class="secondary">
+ <div class="highlight">
+ <h4>ZaÄnite s týmito kolekciami</h4>
+
+ <ul>
+ %3$s
+ </ul>
+
+ <ul class="further-navigation">
+ <li><a href="%4$s" class="more-info">Zobraziť všetky kolekcie</a></li>
+ </ul>
+ </div><!-- /. highlight -->
+ </div><!-- /. secondary-->
+
diff --git a/site/app/locale/sk/pages/error404.thtml b/site/app/locale/sk/pages/error404.thtml
new file mode 100644
index 0000000..e03155c
--- /dev/null
+++ b/site/app/locale/sk/pages/error404.thtml
@@ -0,0 +1,16 @@
+<h1>PrepáÄte, nie je možné nájsÅ¥, Äo ste hľadali.</h1>
+
+<p>Stránka alebo súbor, ktorý požadujete, sa na&nbsp;našej stránke nenašli. Je možné, že ste klikli na&nbsp;neplatný odkaz, alebo ste nesprávne zadali adresu.</p>
+
+<ul>
+<li>Ak ste adresu zadávali, skontrolujte dvakrát správnosť.</li>
+<li>Ak ste niekde klikli na&nbsp;odkaz, dajte nám vedieÅ¥ na&nbsp;adresu <a href="mailto:webmaster@mozilla.com" title="Page Not Found on Mozilla.com">webmaster@mozilla.com</a>. Oznámte nám, odkiaľ ste priÅ¡li a&nbsp;Äo ste hľadali. Urobíme vÅ¡etko pre&nbsp;nápravu.</li>
+</ul>
+
+<p>Prípadne prejdite na&nbsp;niektorú z&nbsp;obľúbených stránok na&nbsp;našom webe.</p>
+
+<ul>
+<li>Zaujíma vás <a href="%1$s">zoznam odporúÄaných doplnkov</a>?</li>
+<li>Chcete <a href="%2$s">hľadať doplnok</a>? Môžete prejsť na&nbsp;<a href="%2$s">stránku vyhľadávania</a>, alebo jednoducho použite hore uvedené vyhľadávacie pole.</li>
+<li>Ak chcete ísÅ¥ na&nbsp;zaÄiatok, prejdite na&nbsp;<a href="%3$s">úvodnú stránku doplnkov</a>.</li>
+</ul>
diff --git a/site/app/locale/sk/pages/nomination.thtml b/site/app/locale/sk/pages/nomination.thtml
new file mode 100644
index 0000000..df58367
--- /dev/null
+++ b/site/app/locale/sk/pages/nomination.thtml
@@ -0,0 +1,10 @@
+<p>Ľubovoľný doplnok, ktorý sa práve nachádza v&nbsp;Sandboxe, môže byť nominovaný na&nbsp;verejnú stránku, kde bude po&nbsp;recenzii editorom k&nbsp;dispozícii všetkým používateľom. Ak chcete dosiahnuť najlepšie výsledky, nezabudnite na&nbsp;nasledujúce:</p>
+<ul>
+ <li>Obrázkové ukážky sú povinné pri&nbsp;témach a&nbsp;dôrazne odporúÄané pri&nbsp;vÅ¡etkých ostatných typoch doplnkov.</li>
+ <li>Doplnok by mal byÅ¥ v&nbsp;Sandboxe dostatoÄne dlhú dobu, aby sa zozbierali recenzie a&nbsp;ohlasy od&nbsp;používateľov. <b>Ak sa má staÅ¥ doplnok verejným, recenzie sú nevyhnutné.</b></li>
+ <li>Verejné doplnky majú vyššiu kvalitu než doplnky v&nbsp;Sandboxe a&nbsp;mali by web zlepšovať.</li>
+ <li>Úplné kritériá nominácie nájdete v&nbsp;<a href="%s">Zásadách stránky Add-ons</a>.</li>
+</ul>
+<p>Ak váš doplnok spĺňa vyššie uvedené podmienky, môžete ho nominovať vyplnením dole uvedeného formulára. Stav nominácie bude oznámený e-mailom.</p>
+
+<p>Pri&nbsp;nominácii svojho doplnku opíšte, ako bol testovaný (uveÄte aj to, Äi to bolo bez&nbsp;chýb a&nbsp;upozornení) a&nbsp;ako je užitoÄný pre&nbsp;web. Môžete uviesÅ¥ aj externé odkazy na&nbsp;recenzie svojho doplnku.</p> \ No newline at end of file
diff --git a/site/app/locale/sk/pages/policy.thtml b/site/app/locale/sk/pages/policy.thtml
new file mode 100644
index 0000000..4f39fb9
--- /dev/null
+++ b/site/app/locale/sk/pages/policy.thtml
@@ -0,0 +1,110 @@
+<h1>Zásady stránky Add-ons</h1>
+
+<h2>ÄŒo je Sandbox?</h2>
+<p>Pozrite <a href="/sk/firefox/pages/sandbox" >stránku s&nbsp;informáciami o Sandboxe</a>.</p>
+
+<h2>Čo sú doplnky v&nbsp;Sandboxe?</h2>
+<p>Sandbox je úvodné umiestnenie doplnkov na&nbsp;stránke AMO. Obsahuje nové verzie verejne prístupných doplnkov ako aj všetky verzie doplnkov, ktoré zatiaľ neboli publikované. Ak je na&nbsp;stránku AMO odoslaný nový doplnok alebo aktualizácia existujúceho doplnku, sú umiestnené najprv do&nbsp;Sandboxu.</p>
+
+<p>Niektoré doplnky alebo ich urÄité verzie sú sprístupnené verejne až po&nbsp;procese recenzie, ktorá ich oznaÄí za&nbsp;pripravené a&nbsp;vhodné na&nbsp;verejné zobrazenie. Ostatné doplnky zostávajú na&nbsp;neurÄito v&nbsp;Sandboxe, kde sú prístupné používateľom, ktorí majú zvolenú možnosÅ¥ prehľadávaÅ¥ zoznam doplnkov v&nbsp;Sandboxe a&nbsp;experimentujú so&nbsp;softvérom.</p>
+
+<h2>Ako sa doplnok stane verejným?</h2>
+
+<p>Doplnky sú recenzované používateľmi stránky AMO, ktorí majú zvolenú možnosÅ¥ zobrazenia Sandboxu, v&nbsp;ktorom môžu balíky testovaÅ¥. Recenzie napísané používateľmi stránky AMO signalizujú, Äi je doplnok dostatoÄne užitoÄný, dobre napísaný a&nbsp;vypracovaný, aby mohol byÅ¥ predložený používateľom Firefoxu. Tieto recenzie sa spolu s&nbsp;ostatnými prehliadkami a&nbsp;kontrolami vykonanými tímom stránky AMO používajú za&nbsp;úÄelom urÄenia, Äi má byÅ¥ daný doplnok verejný, Äi má byÅ¥ eÅ¡te dôkladnejÅ¡ie prepracovaný alebo Äi nie je vhodný na&nbsp;prezentáciu na&nbsp;stránke AMO mimo Sandboxu.</p>
+
+<h2>Ako dosiahnuť verejný stav doplnku?</h2>
+
+<p>Ak si myslíte, že váš doplnok (a&nbsp;jeho správanie) spĺňa kritériá verejného doplnku, môžete ho pomocou panela Nástroje vývojára nominovať.</p>
+
+<h2>Aké sú kritériá na&nbsp;verejné doplnky?</h2>
+
+<p>Doplnok uverejnený na&nbsp;stránke AMO má maÅ¥ vysokú kvalitu a&nbsp;poskytovaÅ¥ používateľom vylepÅ¡ené využívanie webu. Pri rozhodovaní, Äi je doplnok vhodný na&nbsp;publikovanie na&nbsp;stránke AMO, berieme do&nbsp;úvahy tieto kritériá:</p>
+
+<h3>Ste prístupní reakciám?</h3>
+
+<p>OÄakávame, že autor prezentujúci svoj doplnok veľkému poÄtu používateľov Firefoxu reaguje na&nbsp;hlásenie problémov, udržiava aktuálne kontaktné údaje a&nbsp;bez prieÅ¥ahov aktualizuje svoj doplnok vzhľadom na&nbsp;aktualizácie Firefoxu a&nbsp;zmeny zásad používaných na&nbsp;stránke AMO. To neznamená, že musíte odpovedaÅ¥ na&nbsp;každú otázku, ktorú niekto položí v&nbsp;diskusiách ani nie je potrebné opravovaÅ¥ každú chybu v&nbsp;doplnku. OÄakávame ale, že budete reagovaÅ¥ na&nbsp;problémy spôsobom zodpovedajúcim závažnosti problému nastolenému v&nbsp;otázke.</p>
+
+<h3>Je doplnok jasne a&nbsp;presne opísaný?</h3>
+
+<p>Pre&nbsp;nás je maximálne dôležité, aby nový doplnok poskytol používateľom to, Äo od neho oÄakávali. Popis doplnku musí poskytovaÅ¥ podrobnosti o&nbsp;tom, Äo doplnok robí, ako môžu používatelia využiÅ¥ jeho výhody a&nbsp;Äo môže používateľ oÄakávaÅ¥, keÄ si doplnok nainÅ¡taluje. Odkazy na&nbsp;externé dokumenty s&nbsp;podrobnými pokynmi sú vítané, ale popis samotný musí obsahovaÅ¥ základné informácie a&nbsp;nenechaÅ¥ používateľov na&nbsp;pochybách v&nbsp;tom, Äo vÄaka nemu získajú.</p>
+
+<p>Dôležité je aj spolu s&nbsp;vylepÅ¡ovaním a&nbsp;zmenami svojho doplnku udržiavaÅ¥ aktuálne poznámky k&nbsp;verziám. Používatelia musia vidieÅ¥, Äo je nové oproti doplnku, ktorý mali vyskúšaný predtým, a&nbsp;musia byÅ¥ oboznámení so&nbsp;zmenami, ktoré môžu maÅ¥ po&nbsp;aktualizácii vplyv na&nbsp;súÄasné používanie doplnku. (V&nbsp;súÄasnosti používatelia nevidia poznámky k&nbsp;verziám pri&nbsp;výzve na&nbsp;aktualizáciu doplnku vo&nbsp;Firefoxe, ale pracujeme na&nbsp;rieÅ¡ení. Ak udržiavate poznámky k&nbsp;verziám aktuálne, používateľom budú viac jasné výhody prinášané aktualizáciou.)</p>
+
+<h3>Sú jasne vysvetlené vÅ¡etky otázky týkajúce sa bezpeÄnosti a&nbsp;súkromia?</h3>
+
+<p>Ide o&nbsp;jeden z aspektov jasného a presného popisu, ale je taký dôležitý, že považujeme za&nbsp;potrebné ho zvlášť zdôrazniÅ¥. Mnohé veľmi užitoÄné a&nbsp;dobre napísané doplnky spracovávajú niektoré z&nbsp;foriem používateľských údajov, alebo môžu pri&nbsp;nesprávnom zaobchádzaní predstavovaÅ¥ bezpeÄnostné riziká. Tieto doplnky sú vo&nbsp;verejnej Äasti stránky AMO vítané, ale používateľom musí byÅ¥ jasné, že riziko existuje a&nbsp;ako sa majú sami pred&nbsp;ním chrániÅ¥.</p>
+
+<h3>Bol doplnok dobre otestovaný a&nbsp;neobsahuje žiadne zvyÄajné alebo vážne chyby?</h3>
+
+<p>Pri&nbsp;posudzovaní, Äi je doplnok vhodný na&nbsp;publikovanie, prihliadame na&nbsp;to, Äo naznaÄujú recenzie z&nbsp;testovania v&nbsp;Sandboxe, a&nbsp;Äi sa vo&nbsp;Firefoxe nevyskytli žiadne vážne problémy alebo negatívne dopady. Ak recenzenti hlásia problémy ako sú napríklad vážne problémy s&nbsp;výkonom, pády, Äasté problémy s&nbsp;funkciami doplnku alebo množstvo hlásení v&nbsp;chybovej konzole, mali by ste tieto hlásenia preveriÅ¥ po&nbsp;ich zistení ako najlepÅ¡ie viete a&nbsp;svoj doplnok nominovaÅ¥ nanovo. NeÄakáme, že doplnok perfektne optimalizujete ani že nebude obsahovaÅ¥ žiadne chyby. Firefox ako taký sa v&nbsp;tomto smere neustále vylepÅ¡uje, ale chceme, aby ste vyvinuli primerané úsilie na&nbsp;minimalizovanie chýb a&nbsp;jasne používateľom ukázali, kde ich môžu prekvapiÅ¥ pretrvávajúce chyby.</p>
+
+<p>Ak bol váš doplnok testovaný mimo procesu v&nbsp;Sandboxe na&nbsp;stránke AMO, napríklad skupinou používateľov vaÅ¡ej služby alebo interným tímom kontroly kvality, mali by ste to uviesÅ¥ v&nbsp;nominaÄnej správe. Pomôže to pri&nbsp;rozhodovaní o&nbsp;stupni testovania, ktoré bolo vykonané, a&nbsp;napomôže to dostaÅ¥ váš doplnok na&nbsp;stránku.</p>
+
+<h3>Zaobchádza doplnok a&nbsp;jeho autor s&nbsp;používateľmi úctivo?</h3>
+
+<p>Softvér nesmie byÅ¥ používateľom neúmerne vnucovaný, nesmie používateľov klamaÅ¥ ani skrývaÅ¥ pred&nbsp;nimi svoje aktivity. Používatelia (alebo dokonca aj tí, Äo ho nepoužívajú) sú niekedy vo&nbsp;svojich komentároch hrubí, hoci sa Äo najviac snažíme po&nbsp;oznámení také komentáre filtrovaÅ¥ – oÄakávame od&nbsp;autorov, že sa vyvarujú oplácaniu rovnakou hrubosÅ¥ou.</p>
+
+<h3>Je doplnok užitoÄný pre&nbsp;patriÄne veľkú ÄasÅ¥ používateľov Firefoxu?</h3>
+
+<p>Váš doplnok nemusí byÅ¥ Äalším rozšírením Greasemonkey alebo Firebug, ale ak je užitoÄný len pre&nbsp;ľudí vo&nbsp;vaÅ¡ej spoloÄnosti alebo pre&nbsp;ÄasÅ¥ malej webovej komunity, môže sa staÅ¥, že nebudeme považovaÅ¥ za&nbsp;vhodné doplnok prezentovaÅ¥ vÅ¡etkým používateľom Firefoxu.</p>
+
+<p>Neustále hľadáme spôsoby vylepÅ¡enia organizácie stránky, aby sme lepÅ¡ie prezentovali doplnky, ktoré sú v&nbsp;ostatných smeroch výnimoÄné, ale sú zamerané len na&nbsp;malú komunitu potenciálnych používateľov. Správne zaradenie do&nbsp;kategórií a&nbsp;starostlivosÅ¥ o&nbsp;meta údaje doplnku nám pomôžu pri&nbsp;navrhnutí spôsobu lepÅ¡ieho predloženia týchto typov doplnkov ľuÄom, ktorí z&nbsp;nich budú maÅ¥ najväÄší úžitok.</p>
+
+<p>Ak váš doplnok len poskytuje záložky alebo iné jednoduché prístupové body na&nbsp;vaÅ¡u stránku, pravdepodobne nie je vhodný pre&nbsp;verejnú ÄasÅ¥ stránky. Podobne ako pri&nbsp;zvyÅ¡ných projektoch Mozilla, páÄia sa nám webové aplikácie a&nbsp;nové webové služby, ale stránka AMO by mala poskytovaÅ¥ používateľom vylepÅ¡ené používanie webu a&nbsp;nie je teda spôsobom prezentácie novej stránky prostredníctvom zoznamu doplnkov na&nbsp;AMO. Ak je popis doplnku viac o&nbsp;službe ako o&nbsp;doplnku na&nbsp;vylepÅ¡enie používania webu, pravdepodobne nie ste na&nbsp;správnej ceste.</p>
+
+<h3>Nepodlieha doplnok nelicencovaným ochranným známkam alebo autorským právam?</h3>
+
+<p>Hoci nemáte v&nbsp;úmysle poÅ¡kodiÅ¥ držiteľov ochranných známok alebo vlastníkov práce chránenej autorským právom, nemôžeme hosÅ¥ovaÅ¥ doplnky, ktoré poruÅ¡ujú ochranné známky alebo autorské práva. Ak nemáte povolenie na&nbsp;používanie názvu alebo obrázka chráneného ochrannou známkou, neumiestňujte svoj doplnok na&nbsp;stránke AMO. Ak váš doplnok obsahuje kód, na&nbsp;ktorý niekto iný vlastní autorské práva a&nbsp;nemáte licenciu na&nbsp;jeho používanie vo&nbsp;svojom doplnku, neumiestňujte svoj doplnok na&nbsp;stránke AMO. (Ak existuje držiteľ ochrannej známky alebo objektov chránených autorským právom, veľmi pravdepodobne dostaneme žiadosÅ¥ o&nbsp;odstránenie vypracovanú právnikom a&nbsp;odstránime doplnok, ak to budeme považovaÅ¥ za&nbsp;nevyhnutné z&nbsp;hľadiska zákonov. Ide o&nbsp;zložitý proces vyžadujúci projektové zdroje vrátane Äasu a&nbsp;peňazí, takže vás žiadame o&nbsp;pochopenie. Nespôsobujte nám zbytoÄné Å¥ažkosti.)</p>
+
+<p>Ak si nie ste istí, Äi názov doplnku alebo nieÄo, Äo sa v&nbsp;ňom používa, už nie je na&nbsp;stránke uvedené, môžete sa obrátiÅ¥ o&nbsp;pomoc na&nbsp;adresu amo-editors@mozilla.org. DÔLEŽITÉ: nezabudnite, že naÅ¡a skupina neposkytuje právne rady. Aj v&nbsp;prípade, že bude vami použitý názov prijatý, a&nbsp;vo&nbsp;svetle nových faktov od&nbsp;oprávnených držiteľov a&nbsp;právnej rady sa zistia nové okolnosti, môžeme svoje rozhodnutie zmeniÅ¥.</p>
+
+<p>Pokiaľ ide o&nbsp;opakované použitie zdrojového kódu z&nbsp;iných doplnkov – ak autor kódu nestanoví jasne, že máte povolenie na&nbsp;jeho použitie vo&nbsp;svojom doplnku (napríklad tým, že vloží do&nbsp;svojho doplnku licenciu na&nbsp;otvorený zdrojový kód), mali by ste rešpektovať to, že na&nbsp;to nemáte oprávnenie. Môžete sa obrátiť na&nbsp;autora a&nbsp;požiadať ho o&nbsp;povolenie, ale v&nbsp;prípade, že vám autor na&nbsp;vašu požiadavku neodpovie, my vám nemôžeme poskytnúť žiadne špeciálne práva len preto, že bol pôvodný doplnok umiestnený na&nbsp;stránke AMO. (A&nbsp;opäť: my neposkytujeme právne rady, ale rady o&nbsp;tom, ako by mal doplnok spĺňať zásady našej stránky.)</p>
+
+<p>To sa týka aj používania ochranných známok patriacich nadácii Mozilla Foundation vrátane ochranných známok &quot;Mozilla&quot;, &quot;Firefox&quot; a&nbsp;&quot;Thunderbird&quot;. Zásady používania ochranných známok Mozilla sú urÄené na&nbsp;to, aby zamedzili zmätkom a&nbsp;neboli prekrúcané kvôli nedostatoÄnej ochrane. ReÅ¡pektujte prosím nutnosÅ¥ takejto ochrany a&nbsp;pomôžte nám chrániÅ¥ najcennejÅ¡ie aktíva nadácie Mozilla Foundation.</p>
+
+<h2>ÄŒo sa stane, ak nieÄo nominujem?</h2>
+
+<p>Ak bol doplnok nominovaný, bude otestovaný tímom editorov stránky AMO v&nbsp;súlade s&nbsp;vyššie uvedenými kritériami. Ak bude posúdený ako vhodný na&nbsp;verejné publikovanie, bude po&nbsp;otestovaní umiestnený na&nbsp;verejnú stránku a&nbsp;vy dostanete e-mailom oznámenie.</p>
+
+<p>Ak usúdime, že doplnok nie je momentálne vhodný na&nbsp;publikovanie na&nbsp;stránke AMO, dostanete e-mailom oznámenie obsahujúce dôvody a&nbsp;nominácia bude odstránená z&nbsp;poradovníka. Ak si myslíte, že ste sa už zamerali na&nbsp;záležitosti obsiahnuté v&nbsp;e-mailovom oznámení, a&nbsp;chcete doplnok otestovaÅ¥ znova, môžete tak urobiÅ¥ na&nbsp;základe vlastného úsudku. Opakované nominácie bez&nbsp;významných vylepÅ¡ení v&nbsp;doplnku nie sú veľmi vítané, takže ich prosím používajte rozumne. Neustálym omieľaním nás skôr rozÄúlite.</p>
+
+<h2>Môžem nominovať doplnok niekoho iného?</h2>
+
+<p>V&nbsp;súÄasnosti žiadame, aby doplnok nominoval na&nbsp;publikovanie jeho autor. Chceme sa uistiÅ¥, aby bol autor schopný odolávaÅ¥ zvýšenému tlaku a&nbsp;cítil, že jeho doplnok v&nbsp;súÄasnom stave zodpovedá kvalite jeho práce. Ak si myslíte, že je doplnok vyladený, že autor napĺňa podmienky a&nbsp;ducha stránky AMO, že bude prínosom pre&nbsp;Firefox, naÅ¡ich používateľov a&nbsp;pre&nbsp;web vo vÅ¡eobecnosti tak, že ho treba priblížiÅ¥ stovkám miliónov používateľov na&nbsp;celom svete, mali by ste autora doplnku povzbudiÅ¥ k&nbsp;nominácii jeho výtvoru.</p>
+
+<h2>Môj doplnok je vo fronte veľmi dlho, máte nieÄo proti mne?</h2>
+
+<p>Nie, nie je v&nbsp;tom niÄ také. Máme radi vývojárov doplnkov a&nbsp;snažíme sa, aby boli Å¡Å¥astní a&nbsp;produktívni, aby mali z&nbsp;ich práce úžitok používatelia na&nbsp;celom svete. Ale prítomnosÅ¥ na&nbsp;verejnej stránke AMO má presné pravidlá, na&nbsp;ktoré musíme dbaÅ¥, takže tento proces nemôžeme urýchľovaÅ¥. Vieme, že môže byÅ¥ frustrujúce ÄakaÅ¥ na&nbsp;otestovanie doplnku a&nbsp;chceme Äas jeho spracovania skrátiÅ¥ Äo najviac. Čím viac ľudí poskytne podrobnú a&nbsp;jasnú recenziu, tým ľahÅ¡ie bude pre&nbsp;nás testovanie, takže by ste tiež mohli porozmýšľaÅ¥ nad&nbsp;tým, ako nám pri&nbsp;Äasovom sklze môžete pomôcÅ¥.</p>
+
+<h2>Vo&nbsp;svojom doplnku som našiel vážnu chybu a&nbsp;naozaj rýchlo ju opraviť. Čo mám urobiť?</h2>
+
+<p>Ak ide o&nbsp;vážnu chybu (bezpeÄnosÅ¥, stabilita, problémy so&nbsp;základnou funkciou) v&nbsp;doplnku, ktorý chcete okamžite aktualizovaÅ¥, mali by ste to pri&nbsp;odosielaní aktualizácie uviesÅ¥ v&nbsp;poznámkach pre&nbsp;recenzenta ako aj v&nbsp;poznámkach k&nbsp;verzii! Môžete tiež uviesÅ¥ nejakých existujúcich používateľov svojho doplnku, ktorí testovali aktualizáciu a&nbsp;v&nbsp;Sandboxe podrobne uviesÅ¥ výsledky. Pripojenie sa ku&nbsp;kanálu #addons na irc.mozilla.org môže pomôcÅ¥ vyvarovaÅ¥ sa takejto situácie, ale buÄte trpezliví a&nbsp;sluÅ¡ní, ak to bude potrebné.</p>
+
+<p>NekriÄte prosím na&nbsp;poplach. Snažíme sa rýchlo reagovaÅ¥ pri&nbsp;aktualizáciásh s&nbsp;vysokou prioritou, ale otestovanie ostatných nominovaných doplnkov a&nbsp;alebo ich verzií nás stojí veľa Äasu a&nbsp;Äasto je to na&nbsp;úkor spánku alebo naÅ¡ich rodín a&nbsp;priateľov. Preto nemáme veľmi radi ľudí, ktorí sa pokúšajú vyÅ¥ažiÅ¥ výhody mechanizmu preskoÄenia poradia. Ak si nie ste istí tým, akou cestou sa vybraÅ¥, opýtajte sa na&nbsp;kanáli #addons na&nbsp;irc.mozilla.org. Môže vám to pomôcÅ¥ pri&nbsp;rozhodovaní.
+
+<h2>Myslím si, že môj doplnok nebol posúdený správne. Čo mám robiť?</h2>
+
+<p>Ak si myslíte, že váš doplnok nebol otestovaný správne, a&nbsp;že zamietnutie jeho publikovania je chybou, poÅ¡lite e-mail na&nbsp;adresu amo-editors@mozilla.org a&nbsp;uveÄte podrobnosti, preÄo si to myslíte. Vo&nbsp;svojej e-mailovej správe buÄte zdvorilí a&nbsp;jasne vysvetlite svoje názory. Overte si, Äi máte naozaj dôkazy, že bol doplnok posúdený nesprávne.</p>
+
+<p>(Ak ste napravili *všetky* problematické záležitosti uvedené v&nbsp;e-mailovom oznámení, nemali by ste žiadať o&nbsp;preskúšanie, ale namiesto toho zopakujte prostredníctvom panela Nástroje vývojára nomináciu.)</p>
+
+<h2>Môj doplnok by mal by verejný a&nbsp;teraz je len v&nbsp;Sandboxe. Čo sa stalo? </h2>
+
+<p>Ak už doplnok nespĺňa kritériá publikovania na&nbsp;stránke, môžeme ho znova presunúť do&nbsp;Sandboxu. Ak nám v&nbsp;tom nebránia zákony, oznámime vám e-mailom, Äo sa stalo a&nbsp;uvedieme dôvody, preÄo k&nbsp;tomu doÅ¡lo.</p>
+
+<p>Je tiež možné, že nájdete chybu na&nbsp;stránke. V&nbsp;takom prípade by ste to mali ohlásiÅ¥ prostredníctvom Bugzilly. V&nbsp;hlásení použite ako produkt "addons.mozilla.org" a&nbsp;ako komponent "Public Pages". Do&nbsp;hlásenia uveÄte Äo najviac podrobností.</p>
+
+<h2>Môj doplnok je verejný a&nbsp;ľudia ho majú v&nbsp;obľube. ÄŒo treba urobiÅ¥, aby sa dostal do&nbsp;zoznamu odporúÄaných doplnkov?</h2>
+
+<p>Ak si myslíte, že váš doplnok patrí medzi výborné doplnky, ktorý treba prezentovaÅ¥, a&nbsp;že rozÅ¡iruje hodnoty produktov Mozilla pre&nbsp;používateľmi ovládaný web a&nbsp;poskytuje používateľom vynikajúce vylepÅ¡enia, môžete požiadaÅ¥ o&nbsp;jeho zaradenie do&nbsp;zoznamu odporúÄaných doplnkov. Urobte tak odoslaním e-mailu na&nbsp;adresu amo-editors@mozilla.org a&nbsp;vysvetlite v&nbsp;ňom, preÄo je váš doplnok vynikajúci.</p>
+
+<p>E-mail by mal obsahovať <b>minimálne</b> tieto informácie:</p>
+<ul>
+<li>ako vylepšuje používateľom prácu s&nbsp;webom,</li>
+<li>ako je váš doplnok vhodný pre&nbsp;veľkú ÄasÅ¥ používateľov Firefoxu,</li>
+<li>ako váš doplnok zvyÅ¡uje alebo vylepÅ¡uje hodnoty projektu Mozilla, najmä pokiaľ ide o&nbsp;jeho význam, ochranu súkromia a&nbsp;zabezpeÄenie, univerzálny prístup k&nbsp;webu otvorený Å¡tandardom a&nbsp;údajom,</li>
+<li>v&nbsp;Äom je doplnok odliÅ¡ný od&nbsp;iných podobných doplnkov (Äo je lepÅ¡ie aj Äo je horÅ¡ie),</li>
+<li>aké reakcie máte od&nbsp;používateľov, recenzentov, blogerov, astronautov a&nbsp;vaÅ¡ich domácich miláÄikov – kladné aj záporné.</li>
+</ul>
+
+<p>Čím komplexnejÅ¡ie informácie uvediete vo&nbsp;svojej žiadosti, tým viac nás presvedÄíte, hoci ani vynikajúco napísaný a&nbsp;presvedÄivý popis nezaruÄuje umiestnenie doplnku v&nbsp;zozname odporúÄaných doplnkov. Tak Äi onak, zoznam musí byÅ¥ vytváraný (a&nbsp;aj je) na&nbsp;základe rozhodnutia Mozilly a&nbsp;skúsenosti a&nbsp;ochrana používateľa je nadovÅ¡etko.</p>
diff --git a/site/app/locale/sk/pages/reviewguide.thtml b/site/app/locale/sk/pages/reviewguide.thtml
new file mode 100644
index 0000000..17e423d
--- /dev/null
+++ b/site/app/locale/sk/pages/reviewguide.thtml
@@ -0,0 +1,83 @@
+<h1>Pravidlá pre pridanie recenzie</h1>
+<p>Recenzovanie doplnkov je pre používateľov stránky s doplnkami možnosťou zdieľať svoje názory
+na doplnky, ktoré si nainštalovali a používajú ich. Editori si vyhradzujú právo
+zamietnuť alebo vymazať recenziu, ktorá nevyhovuje ich pravidlám.</p>
+
+<div class="corner-box">
+ <h2>Niekoľko tipov, ako napísať dobrú recenziu</h2>
+
+<h3><b>OdporúÄame vám:</b></h3>
+<ul>
+<li>Píšte štýlom akoby ste vášmu známemu opisovali skúsenosti s daným doplnkom.</li>
+<li>Snažte sa, aby boli vaÅ¡e recenzie struÄné a ľahko pochopiteľné.</li>
+<li>Opíšte charakteristické a užitoÄné detaily. Napríklad:
+<ul>
+ <li>Fungoval doplnok podľa vašich predstáv?</li>
+ <li>Ktoré vlastnosti sa vám páÄili a ktoré nie?</li>
+ <li>Bol užitoÄný?</li>
+ <li>Bol jednoduchý na používanie?</li>
+ <li>Budete používaÅ¥ doplnok aj naÄalej?</li>
+</ul></li>
+
+<li>Pred publikovaním si preÄítajte svoju recenziu, aby ste sa vyhli nepríjemným preklepom alebo gramatickým chybám.</li>
+
+<li>Vyhýbajte sa odkazovaniu na doÄasné stránky a diskusné príspevky, pretože recenzie môžu na stránke zotrvaÅ¥ dlhý Äas.</li>
+</ul>
+
+<h3><b>NeodporúÄame vám:</b></h3>
+<ul>
+<li>PublikovaÅ¥ jednoduché recenzie, ako napríklad "Výborný!", "úžasný", alebo "zlý" bez ÄalÅ¡ieho popisu.</li>
+<li>Odosielať chybové alebo problémové hlásenia v recenziách. Využite dostupné možnosti podpory pre každý doplnok.</li>
+<li>Písať recenzie pre doplnky, ktoré nemáte osobne odskúšané.</li>
+<li>Použitie vulgárneho vyjadrovania, sexuálnych výrazov alebo jazyk, ktorý môže vyvolať nenávisť.</li>
+<li>ZahŕňaÅ¥ znaky HTML, odkazy na Å¡kodlivý softvér, zdrojový kód alebo Äasti kódu. Recenzie by mali byÅ¥ len vo forme textu.</li>
+<li>Podávať falošné vyhlásenia, znevažovať autora doplnkov alebo ho osobne urážať.</li>
+<li>Používať recenzie ako možnosť pre žiadanie podpory pre špecifickú verziu Firefoxu (alebo inej aplikácie).</li>
+<li>VkladaÅ¥ vaÅ¡u vlastnú e-mailovú adresu, telefónne Äíslo alebo iné osobné detaily.</li>
+<li>Publikovať recenziu pre doplnok vytvorený alebo reprezentovaný vami alebo vašou organizáciou.</li>
+</ul>
+</div>
+
+<div class="corner-box">
+ <h2>Pravidlá pre hodnotenie doplnkov</h2>
+
+<p>Hodnotenie doplnkov by malo byť férové a podávať pravdivú indikáciu celkovej kvality
+a použiteľnosti. Nedávajte doplnku hneÄ 5 hviezdiÄiek, keÄ sa vám páÄi alebo 1 hviezdiÄku, keÄ nie. Dôsledné hodnotenie je dôležitou ÄasÅ¥ou každej recenzie.</p>
+
+<ul>
+<li><b>5 hviezdiÄiek: Excelentný.</b> Nerobí len to, Äo má v popise,
+je použiteľnejší než mnoho iných doplnkov. Tento doplnok je jeden z tých,
+ktoré používate veľmi Äasto a odporúÄate ho aj iným.</li>
+<li><b>4 hviezdiÄky: Dobrý.</b> UžitoÄný a jednoduchý na používanie, i keÄ nie je nevyhnutný. Tento doplnok
+je odporúÄaný, ale niektorí ľudia od neho môžu oÄakávaÅ¥ viac.</li>
+<li><b>3 hviezdiÄky: Prijateľný.</b> Môže maÅ¥ niekoľko dizajnových nedostatkov a/alebo postrádaÅ¥ niektoré vlastnosti.
+Žiadny problém nie je príliš drastický pre jeho zavrhnutie a pre niektorých ľudí
+môže byÅ¥ užitoÄný. OdporuÄte ho niekomu, kto ho potrebuje a chcel by ho vyskúšaÅ¥.</li>
+<li><b>2 hviezdiÄky: Slabý.</b> Doplnok je menej kvalitný, menej použiteľný, alebo jednoducho nespĺňa to, Äo by mal.
+NeodporúÄate ho, zároveň vÅ¡ak môže byÅ¥ užitoÄný pre úzku skupinu ľudí.</li>
+<li><b>1 hviezdiÄka: Zlý.</b> Doplnok nepracuje správne alebo je úplne nepoužiteľný. Nevidíte žiadny pádny dôvod,
+preÄo by ho niekto mal vyskúšaÅ¥ a odporúÄate sa mu vyhnúť.</li>
+</ul>
+
+<p>Nie je niÄ zlé na tom, daÅ¥ nejakému rozšíreniu perfektnú alebo otrasnú recenziu, len zdôvodnite,
+preÄo ste tak uÄinili. HviezdiÄky neznamenajú niÄ, pokiaľ nevyslovíte dôvod vášho rozhodnutia.</p>
+</div>
+
+<div class="corner-box">
+ <h2>Často kladené otázky týkajúce sa recenzií</h2>
+
+<h3>Ako môžem nahlásiť problematickú recenziu?</h3>
+<p>Prosím, nahláste alebo oznaÄte vÅ¡etky diskutabilné recenzie kliknutím na odkaz "NahlásiÅ¥ túto recenziu"
+a táto recenzia bude odoslaná na posúdenie. Editori sa podľa pravidiel pre pridávanie recenzií rozhodnú,
+Äi recenziu odstránia alebo ju vrátia späť na stránku.</p>
+
+<h3>Som autorom doplnku, môžem reagovať na recenziu?</h3>
+<p>Ãno, autori doplnkov môžu dodaÅ¥ jednotlivé reakcie na recenzie.
+ÄŽalÅ¡ia diskusia by vÅ¡ak mala pokraÄovaÅ¥ na fóre podpory alebo v diskusnej skupine.</p>
+
+<h3>Som autorom doplnku, môžem odstrániť nepriaznivú recenziu?</h3>
+<p>ObyÄajne nie. Ak ale recenzia nespĺňa pravidlá recenzie popísané
+vyššie, môžete kliknúť na odkaz "Nahlásiť túto recenziu" a nechať ju posúdiť editorom.
+Ak recenzia obsahuje sťažnosti, ktoré už nie sú platné, lebo vyšla nová verzia doplnku, môžeme uvažovať o odstránení recenzie.
+Pošlite vašu detailnú požiadavku na adresu amo-editors@mozilla.org.</p>
+</div>
diff --git a/site/app/locale/sk/pages/sandbox.thtml b/site/app/locale/sk/pages/sandbox.thtml
new file mode 100644
index 0000000..35ea43c
--- /dev/null
+++ b/site/app/locale/sk/pages/sandbox.thtml
@@ -0,0 +1,13 @@
+<h1>Systém kontroly v&nbsp;Sandboxe</h1>
+<h2>ÄŒo je Sandbox?</h2>
+<p>Sandbox je priestor, kde môžu skúsení používatelia testovaÅ¥ doplnky pred&nbsp;tým, než budú skontrolované na&nbsp;vÅ¡eobecné používanie. Ak chcete maÅ¥ prístup do&nbsp;Sandboxu, musíte to povoliÅ¥ v&nbsp;nastavení svojho úÄtu. Pri&nbsp;inÅ¡talácii doplnku zo&nbsp;Sandboxu musí byÅ¥ používané upozornenie, že doplnok nebol testovaný editorom a&nbsp;môže poÅ¡kodiÅ¥ poÄítaÄ.</p>
+
+<h2>Ako dostať doplnok na&nbsp;verejnú stránku?</h2>
+<!-- To localize the flowchart image, see http://wiki.mozilla.org/Update:Remora_Sandbox_Flowchart -->
+<div style="text-align: center;">%s</div>
+<ol>
+ <li><b>OdoÅ¡lite svoj doplnok v&nbsp;paneli Nástroje vývojára.</b> Položka sa ihneÄ objaví v&nbsp;Sandboxe na&nbsp;webe Mozilla Add-ons, kde budú skúsení používatelia doplnok testovaÅ¥ a&nbsp;dodávaÅ¥ svoje ohlasy. Ak chcete maÅ¥ prístup do&nbsp;Sandboxu, musíte to povoliÅ¥ v&nbsp;nastavení svojho úÄtu.</li>
+ <li><b>Nominujte svoj doplnok na&nbsp;uverejnenie.</b> V&nbsp;paneli Nástroje vývojára je odkaz na&nbsp;nomináciu doplnku. Po&nbsp;nominácii sa doplnok objaví vo&nbsp;fronte recenzií editora, kde poÄká na&nbsp;kontrolu.</li>
+ <li><b>Niektorý editor skontrolujte váš doplnok.</b> Editor z&nbsp;webu Mozilla Add-ons nainštaluje váš doplnok a&nbsp;otestuje ako funguje. Prezrie aj posudky ľudí, ktorí doplnok testovali v&nbsp;Sandboxe.</li>
+ <li><b>Doplnok bude vložený na&nbsp;verejnú stránku alebo zostane v&nbsp;Sandboxe.</b> Editor buÄ vloží váš doplnok na&nbsp;verejnú stránku alebo ho ponechá v&nbsp;Sandboxe. Ak doplnok zostane v&nbsp;Sandboxe, môžete ho nominovaÅ¥ znova po&nbsp;vykonaní zmien odporúÄaných editorom vo&nbsp;svojich komentároch. Ak bude doplnok vložený na&nbsp;verejnú stránku, budúce verzie doplnku sa automaticky objavia v&nbsp;Sandboxe, kým ich editor neskontroluje a&nbsp;nevloží na&nbsp;verejnú stránku. Ak už je raz doplnok verejný, nie je potrebné ho znova nominovaÅ¥ – budúce verzie budú automaticky zaradené do&nbsp;frontu na&nbsp;recenziu.</li>
+</ol>
diff --git a/site/app/locale/sk/pages/statistics_help.thtml b/site/app/locale/sk/pages/statistics_help.thtml
new file mode 100644
index 0000000..f6c2548
--- /dev/null
+++ b/site/app/locale/sk/pages/statistics_help.thtml
@@ -0,0 +1,7 @@
+<h3>Pomocník</h3>
+<p>Panel Å tatistika zobrazuje údaje o poÄtoch prevzatí a aktualizácií vášho doplnku.</p>
+<h4>Prevzatia</h4>
+<p>PoÄet prevzatí je aktualizovaný každý deň a zahŕňa len poÄet priamych prevzatí, nie aktualizácie.</p>
+
+<h4>Aktualizácie</h4>
+<p>Doplnky prevzaté z tejto stránky kontrolujú aktualizácie každý deň. Celkový poÄet týchto kontrol je známy ako Aktívni denní používatelia. PoÄet aktívnych denných používateľov (ADU) môže byÅ¥ rozdelený podľa verzií doplnku, operaÄného systému, stavu doplnku a aplikácie, ktorej je nainÅ¡talovaný.</p>
diff --git a/site/app/locale/sk/pages/submission_help.thtml b/site/app/locale/sk/pages/submission_help.thtml
new file mode 100644
index 0000000..0b41169
--- /dev/null
+++ b/site/app/locale/sk/pages/submission_help.thtml
@@ -0,0 +1,35 @@
+<h1>Pomocník k odoslaniu</h1>
+Povinné polia sú <b>tuÄným</b> písmom. Voliteľné polia sú <i>kurzívou</i>.
+<h2 id="step1">1. krok: Odoslanie</h2>
+<ul class="submissionHelp">
+ <li><span class="required">Typ doplnku</span> – V&nbsp;predvolenom nastavení bude typ doplnku urÄený automaticky podľa odoslaného súboru. Toto pole by ste nemali meniÅ¥.</li>
+ <li><span class="required">Súbor doplnku</span> – Archívny súbor doplnku spolu so&nbsp;súborom install.rdf. Ak súbor funguje len na&nbsp;urÄitej platforme, výber tejto platformy umožní odoslaÅ¥ súÄasne viac súborov.</li>
+ <li><span class="optional">Súbor ikony</span> – Súbor ikony sa zobrazuje na&nbsp;stránke vedľa názvu doplnku a&nbsp;v&nbsp;inÅ¡talaÄnom dialógovom okne rozšírenia. VeľkosÅ¥ bude automaticky zmenená na 32&nbsp;x&nbsp;32&nbsp;bodov, pomer strán bude zachovaný.</li>
+ <li><span class="required">Predvolený jazyk</span> – Predvolený jazyk je hlavným jazykom. Ak používateľom vybraný jazyk nie je v&nbsp;tomto doplnku k&nbsp;dispozícii, preklad sa vráti k&nbsp;predvolenému jazyku.</li>
+ <li><span class="optional">PreskoÄiÅ¥ prezeranie informácií o&nbsp;mojom aktuálnom doplnku</span> – Ak aktualizujete existujúci doplnok, objaví sa toto pole. OznaÄením políÄka preskoÄíte na 3.&nbsp;krok, v&nbsp;ktorom môžete zadaÅ¥ informácie týkajúce sa verzie.</li>
+</ul>
+
+<h2 id="step2">2. krok: Podrobnosti doplnku</h2>
+<ul class="submissionHelp">
+ <li><span class="required">Názov</span> – Názov doplnku v&nbsp;predvolenom jazyku.</li>
+ <li><span class="required">Autori</span> – Na&nbsp;stránke budú ako autori uvedení všetci používatelia, ktorí mali prístup k&nbsp;úpravám doplnku.</li>
+ <li><span class="required">Kategórie</span> – Kategórie, do&nbsp;ktorých je možné doplnok zaradiť.</li>
+ <li><span class="optional">Domovská stránka</span> – Webová stránka doplnku v&nbsp;predvolenom jazyku.</li>
+ <li><span class="required">Súhrn</span> – Krátky súhrn doplnku v&nbsp;predvolenom jazyku. Najviac 250&nbsp;znakov.</li>
+ <li><span class="required">Popis</span> – Popis doplnku v&nbsp;predvolenom jazyku.</li>
+ <li><span class="optional">LicenÄná zmluva</span> – Pred&nbsp;prevzatím doplnku bude požadovaný súhlas s&nbsp;LicenÄnou zmluvou koncového používateľa (EULA) v&nbsp;predvolenom jazyku.</li>
+ <li><span class="optional">Zásady ochrany súkromia</span> – Zásady ochrany súkromia pre&nbsp;doplnok v&nbsp;predvolenom jazyku.</li>
+ <li><span class="optional">PovoliÅ¥ používateľom zobraziÅ¥ online zdrojové súbory</span> – OznaÄením tohto políÄka umožníte používateľom prehľadávaÅ¥ online zdrojové súbory doplnku.</li>
+ <li><span class="optional">Toto je vývojová verzia</span> – OznaÄením tohto políÄka urÄíte, že ide o&nbsp;vývojovú verziu PR alebo Beta.</li>
+ <li><span class="optional">Tento doplnok je pre Å¡pecifickú stránku</span> – OznaÄením tohto políÄka urÄíte, že ide o&nbsp;doplnok urÄený pre&nbsp;jednu webovú stránku.</li>
+ <li><span class="optional">Tento doplnok vyžaduje externý softvér</span> – OznaÄením tohto políÄka oznámite, že doplnok vyžaduje externý softvér.</li>
+</ul>
+
+<h2 id="step3">3. krok: Podrobnosti o verzii</h2>
+<ul class="submissionHelp">
+ <li><span class="required optional">Poznámky k verzii</span> – Zhrnutie alebo zoznam zmien v&nbsp;tejto verzii. Táto položka je voliteľná pri&nbsp;novom doplnku, ale povinná pri&nbsp;aktualizáciách.</li>
+ <li><span class="optional">Poznámky pre recenzenta</span> – Toto pole sa používa na&nbsp;komunikáciu s&nbsp;editormi, ktorí recenzujú doplnok. Sem zadajte údaje potrebné na&nbsp;testovanie a&nbsp;špeciálne poznámky.</li>
+</ul>
+
+<h2 id="step4">4. krok: Lokalizácia</h2>
+Ide o&nbsp;polia pre&nbsp;doplnok, ktoré možno lokalizovať do&nbsp;všetkých podporovaných jazykov. Jednoducho kliknutím na&nbsp;jazyk zadajte preklady.
diff --git a/site/app/locale/sq/LC_MESSAGES/messages.mo b/site/app/locale/sq/LC_MESSAGES/messages.mo
new file mode 100644
index 0000000..84bd566
--- /dev/null
+++ b/site/app/locale/sq/LC_MESSAGES/messages.mo
Binary files differ
diff --git a/site/app/locale/sq/LC_MESSAGES/messages.po b/site/app/locale/sq/LC_MESSAGES/messages.po
new file mode 100644
index 0000000..8309068
--- /dev/null
+++ b/site/app/locale/sq/LC_MESSAGES/messages.po
@@ -0,0 +1,7582 @@
+msgid ""
+msgstr ""
+"Project-Id-Version: \n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2009-01-16 11:45-0800\n"
+"PO-Revision-Date: 2009-06-09 11:47+0200\n"
+"Last-Translator: Besnik Bleta <besnik@programeshqip.org>\n"
+"Language-Team: Albanian <besnik@programeshqip.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#: views/addons/policy.thtml:98
+msgid "a_cancel_installation"
+msgstr "Anulo Instalimin"
+
+#. This is the text that appears on buttons to download add-ons.
+#. %$1s is an optional string that only appears if the add-on is only available for
+#. a certain platform. Examples: (Windows) or (Linux)
+#. Note that the parentheses are included in the string. :(
+#: views/elements/amo2009/install.thtml:126
+#: views/elements/amo2009/install.thtml:227
+#: views/elements/amo2009/install.thtml:257
+#: views/elements/amo2009/install.thtml:300
+#: views/elements/amo2009/install.thtml:312 views/elements/install.thtml:73
+#: views/elements/install.thtml:181 views/elements/install.thtml:205
+#: views/elements/install.thtml:248 views/elements/install.thtml:260
+#: views/addons/plugins.thtml:66 views/addons/plugins.thtml:76
+#: views/addons/plugins.thtml:86 views/addons/plugins.thtml:96
+#: views/addons/plugins.thtml:119
+#, php-format
+msgid "a_download"
+msgstr "Shkarkoje %s Tani"
+
+#: views/addons/policy.thtml:72
+msgid "a_eula_download"
+msgstr "Pranoje dhe Shkarko"
+
+#: views/addons/policy.thtml:74
+msgid "a_eula_install"
+msgstr "Pranoje dhe Instalo"
+
+#: views/elements/header.thtml:76 views/elements/header.thtml:82
+#: views/api/api_addon.thtml:55 views/api/collections_feed.thtml:75
+#: views/sharing_api/addon.thtml:64
+msgid "a_header_public"
+msgstr "Publike"
+
+#: views/elements/header.thtml:58 views/elements/header.thtml:75
+#: views/elements/header.thtml:80 views/api/api_addon.thtml:57
+#: views/api/collections_feed.thtml:77 views/sharing_api/addon.thtml:66
+msgid "a_header_sandbox"
+msgstr "Bankoprovë"
+
+#. %s is a date in the _('date') format
+#: views/elements/amo2009/homepage_addon.thtml:115
+#: views/elements/addon_listitem.thtml:122 views/elements/feature.thtml:106
+#: views/addons/display.thtml:104 views/addons/browse_thumbs.thtml:73
+msgid "addon_detail_last_updated"
+msgstr "Përditësuar më %s"
+
+#. %s is the version of the add-on. Example: 3.2a1
+#: views/elements/amo2009/addon_version_detail.thtml:51
+#: views/elements/addon_version_detail.thtml:51
+#, php-format
+msgid "addon_display_header_version"
+msgstr "Version %s"
+
+#: views/addons/browse_thumbs.thtml:80
+msgid "addon_downloads"
+msgstr "shkarkime"
+
+#: views/addons/display.thtml:147
+msgid "addon_downloads_total"
+msgstr "shkarkime gjithsej"
+
+#: views/elements/amo2009/homepage_addon.thtml:106
+#: views/elements/addon_listitem.thtml:115 views/elements/feature.thtml:101
+#: views/addons/category_landing.thtml:157 views/addons/display.thtml:146
+#: views/addons/browse_thumbs.thtml:80
+msgid "addon_downloads_weekly"
+msgstr "shkarkime javore"
+
+#. %1 is the add-on count, %2 the category name
+#: views/addons/browse_thumbs.thtml:104 views/addons/browse.thtml:60
+#, php-format
+msgid "addon_list_category_totalcount"
+msgid_plural "addon_list_category_totalcount"
+msgstr[0] "%1$s shtesë"
+msgstr[1] "%1$s shtesa"
+
+#: views/elements/amo2009/addon_list_options.thtml:103
+#: views/elements/pagination.thtml:67
+#: views/elements/addon_list_options.thtml:94
+msgid "addon_list_perpage"
+msgstr "për faqe"
+
+#: views/elements/amo2009/addon_list_options.thtml:84
+#: views/elements/addon_list_options.thtml:98
+msgid "addon_list_sortby"
+msgstr "Renditur sipas:"
+
+#: views/helpers/addons_html.php:568 views/elements/amo2009/install.thtml:321
+#: views/elements/feature.thtml:89
+msgid "addon_listitem_flag_experimental"
+msgstr "eksperimentale"
+
+#: views/helpers/addons_html.php:570
+msgid "addon_listitem_flag_recommended"
+msgstr "e këshilluar"
+
+#. %1 is the add-on name, %2 is the platform
+#: views/pages/js_constants.js.thtml:66
+msgid "addon_not_available_for_platform"
+msgstr "%1$s nuk është i passhëm për %2$s."
+
+#. %1 is the add-on name
+#: views/addons/policy.thtml:101 views/addons/previews.thtml:60
+#: views/addons/versions.thtml:130 views/reviews/flag.thtml:61
+#: views/reviews/add.thtml:114 views/reviews/display.thtml:216
+#: views/reviews/review_added.thtml:57
+#, php-format
+msgid "addon_review_a_back_to_addon_x"
+msgstr "Prapa te %1$s..."
+
+#. %1 is the add-on name
+#: views/reviews/flag.thtml:60 views/reviews/add.thtml:113
+#: views/reviews/review_added.thtml:56
+#, php-format
+msgid "addon_review_a_back_to_reviews"
+msgstr "Prapa te shqyrtimet..."
+
+#: views/reviews/add.thtml:85
+msgid "addon_review_add_rating_field"
+msgstr "Vlerësim:"
+
+#: views/reviews/add.thtml:102
+msgid "addon_review_add_review_field"
+msgstr "Shqyrtim:"
+
+#: views/reviews/add.thtml:107
+msgid "addon_review_add_submit"
+msgstr "Parashtroni shqyrtimin tuaj"
+
+#. %s is the name of the add-on
+#: views/reviews/add.thtml:51
+#, php-format
+msgid "addon_review_add_title"
+msgstr "Shtoni një shqyrtim për %s"
+
+#: views/reviews/add.thtml:78
+msgid "addon_review_add_title_field"
+msgstr "Titull/Përmbledhje:"
+
+#: views/reviews/display.thtml:77 views/reviews/display.thtml:161
+msgid "addon_review_admin_delete"
+msgstr "Fshije"
+
+#: views/reviews/display.thtml:76
+msgid "addon_review_author_reply_link"
+msgstr "Përgjigjju"
+
+#: views/reviews/delete.thtml:62
+msgid "addon_review_confirm_delete"
+msgstr "Jeni i sigurt se doni të fshini këtë shqyrtim?"
+
+#: views/reviews/delete.thtml:63
+msgid "addon_review_confirm_no"
+msgstr "Jo"
+
+#: views/reviews/delete.thtml:64
+msgid "addon_review_confirm_yes"
+msgstr "Po"
+
+#: views/reviews/delete.thtml:48
+msgid "addon_review_delete_header"
+msgstr "Fshije Shqyrtimin"
+
+#: controllers/reviews_controller.php:449
+msgid "addon_review_deleted_successfully"
+msgstr "Shqyrtimi u fshi me sukses."
+
+#. %s is the name of the add-on
+#: views/reviews/add.thtml:51
+#, php-format
+msgid "addon_review_edit_title"
+msgstr "Përpunoni Shqyrtimin për %s"
+
+#. %1 is the count of characters entered as notes for the review flag reason.
+#: controllers/reviews_controller.php:539
+msgid "addon_review_flag_error_other_length"
+msgstr ""
+"Problem me flamurëzimin e shqyrtimit: Shënimet për shqyrtime te flamurëzuar "
+"janë të kufizuara nga 10 deri në 100 shenja; tuaja qenë %1$s."
+
+#. Removing an extra comma
+#: views/reviews/review_added.thtml:53
+msgid "addon_review_in_moderation"
+msgstr ""
+"Vini re: Përpara se shqyrtimi juaj të shfaqet në \"site\"-in publik, do të "
+"shqyrtohet nga një redaktor."
+
+#: views/reviews/add.thtml:57
+msgid "addon_review_in_reply_to"
+msgstr "Përgjigje zhvilluesi për:"
+
+#. %1 is the review count, %2 is the nickname or full name of the user.
+#: views/reviews/display.thtml:131
+#, php-format
+msgid "addon_review_others_by_user"
+msgid_plural "addon_review_others_by_user"
+msgstr[0] ""
+"Shihni %1$s shqyrtim të mëparshëm parashtruar nga %2$s për këtë shtesë."
+msgstr[1] ""
+"Shihni %1$s shqyrtime të mëparshme parashtruar nga %2$s për këtë shtesë."
+
+#. %1 is the add-on name
+#: controllers/reviews_controller.php:201
+#: controllers/reviews_controller.php:250
+#: controllers/reviews_controller.php:345
+#: controllers/reviews_controller.php:424
+#, php-format
+msgid "addon_review_pagetitle"
+msgstr "Shqyrtime për %s"
+
+#. %1 is the user, %2 is the (localized) date
+#: views/reviews/display.thtml:160
+#, php-format
+msgid "addon_review_reply_on_x_by_y"
+msgstr "Përgjigje nga %1$s më %2$s"
+
+#: views/reviews/display.thtml:157
+msgid "addon_review_reply_prefix"
+msgstr "Përgjigje Zhvilluesi:"
+
+#: views/reviews/review_added.thtml:51
+msgid "addon_review_saved_successfully"
+msgstr "Shqyrtimi juaj u ruajt me sukses. Faleminderit!"
+
+#: views/addons/display.thtml:354 views/reviews/display.thtml:72
+msgid "addon_reviewed_by_u_on_d"
+msgstr "nga %1$s më %2$s"
+
+#. %1 is the user, %2 is the (localized) date, %3 is the rating
+#: views/editors/reviews_queue.thtml:57 views/editors/reviews_queue.thtml:68
+#: views/reviews/add.thtml:63 views/reviews/delete.thtml:54
+#, php-format
+msgid "addon_reviewed_on_x_rated_y"
+msgstr "nga %1$s më %2$s (vlerësuar si %3$s)"
+
+#: views/elements/amo2009/addon_version_detail.thtml:52
+#: views/elements/addon_version_detail.thtml:52
+msgid "addon_version_permalink"
+msgstr "Lidhje e përhershme për te ky version"
+
+#. %1 is the current Application name (e.g. Firefox)
+#. %2 is the Application's version number
+#: views/addons/versions.thtml:140
+msgid "addon_versions_getlatestversion"
+msgstr "Versioni më i fundit i përputhshëm me %1$s %2$s"
+
+#: views/addons/display.thtml:447
+msgid "addons_author_addons_submit"
+msgstr "Shko"
+
+#: views/elements/amo2009/homepage_addon.thtml:100
+#: views/elements/feature.thtml:95
+msgid "addons_author_tooltip"
+msgstr "Shihni Profilin e Autor-it"
+
+#. %1 is the name of the Application (eg. Firefox)
+#: controllers/addons_controller.php:1296
+msgid "addons_browse_all_themes_title"
+msgstr "Shfletoni tërë Temat :: Shtesa për %1$s"
+
+#. %s is the name of the category
+#: controllers/addons_controller.php:1016
+#, php-format
+msgid "addons_browse_browse_category"
+msgstr "Shfletoni %s"
+
+#. %1 is the name of the theme category (eg. Modern)
+#. %2 is the name of the Application (eg. Firefox)
+#: controllers/addons_controller.php:664
+msgid "addons_browse_categories_header_theme"
+msgstr "Shfletoni Tema %1$s-i :: Shtesa për %2$s"
+
+#: views/addons/display.thtml:249
+#, fuzzy
+msgid "addons_display_a_license_what"
+msgstr "What's this?"
+
+#: views/reviews/display.thtml:222
+msgid "addons_display_add_review"
+msgstr "Shtoni shqyrtim"
+
+#: views/addons/display.thtml:294
+msgid "addons_display_advanced_details"
+msgstr "Hollësi të Mëtejshme"
+
+#: views/addons/display.thtml:98
+msgid "addons_display_categories"
+msgstr "Kategori"
+
+#: views/addons/display.thtml:482
+#, fuzzy
+msgid "addons_display_collection_add"
+msgstr "Add to a collection:"
+
+#: views/addons/display.thtml:491
+#, fuzzy
+msgid "addons_display_collection_add_new"
+msgstr "New Collection..."
+
+#: views/addons/display.thtml:487
+#, fuzzy
+msgid "addons_display_collection_add_select_one"
+msgstr "Select a collection..."
+
+#: views/addons/display.thtml:493
+#, fuzzy
+msgid "addons_display_collection_add_submit"
+msgstr "Publish"
+
+#. %1$s is the add-on name
+#. %2$s is the collection name, linked to the collection's page
+#: views/pages/js_constants.js.thtml:103 views/addons/display.thtml:61
+#, fuzzy
+msgid "addons_display_collection_publish_success"
+msgstr "%1$s has been added to the %2$s collection."
+
+#: views/addons/display.thtml:483
+#, fuzzy
+msgid "addons_display_collection_whatsthis"
+msgstr "What's this?"
+
+#. %1$s is a number
+#: views/addons/display.thtml:473
+#, fuzzy
+msgid "addons_display_collections_more"
+msgid_plural "addons_display_collections_more"
+msgstr[0] "and %1$s more collection"
+msgstr[1] "and %1$s more collections"
+
+#: views/addons/display.thtml:403
+msgid "addons_display_detailed_review"
+msgstr "shqyrtim i hollësishëm"
+
+#: views/reviews/add.thtml:89 views/reviews/add.thtml:90
+msgid "addons_display_dont_like_it"
+msgstr "S'më pëlqen"
+
+#: views/reviews/display.thtml:220
+msgid "addons_display_edit_review"
+msgstr "Përpunoni shqyrtimin tuaj"
+
+#: views/addons/display.thtml:132
+msgid "addons_display_has_privacy"
+msgstr "Kjo shtesë ka rregulla vetësie."
+
+#: views/reviews/add.thtml:87 views/reviews/add.thtml:88
+msgid "addons_display_hate_it"
+msgstr "Urreje"
+
+#: views/addons/display.thtml:462
+#, fuzzy
+msgid "addons_display_header_collections"
+msgstr "Related Collections"
+
+#: views/addons/display.thtml:297
+msgid "addons_display_header_developer_comments"
+msgstr "Komente nga Zhvilluesa"
+
+#: views/addons/display.thtml:230
+msgid "addons_display_header_homepage"
+msgstr "Faqe Hyrëse"
+
+#: views/addons/display.thtml:247 views/addons/versions.thtml:110
+#, fuzzy
+msgid "addons_display_header_license"
+msgstr "Source Code License"
+
+#: views/addons/display.thtml:337
+msgid "addons_display_header_reviews"
+msgstr "Shqyrtime"
+
+#: views/addons/display.thtml:261
+msgid "addons_display_header_support"
+msgstr "Asistencë"
+
+#: views/reviews/add.thtml:91 views/reviews/add.thtml:92
+msgid "addons_display_like_it"
+msgstr "Pëlqeje"
+
+#: views/addons/display.thtml:210
+msgid "addons_display_long_description"
+msgstr "Përshkrim i Gjatë"
+
+#: views/reviews/add.thtml:95 views/reviews/add.thtml:96
+msgid "addons_display_love_it"
+msgstr "Duaje"
+
+#: views/addons/display.thtml:178
+msgid "addons_display_more_images"
+msgstr "Më tepër Pamje"
+
+#: views/addons/display.thtml:465
+#, fuzzy
+msgid "addons_display_nocollections"
+msgstr "This add-on is not yet in any collections."
+
+#. %1$s is either an author's name or a comma separated list of authors. Using
+#. the list doesn't make sense in the English plural form so we ignore the
+#. variable.
+#: views/addons/display.thtml:436
+msgid "addons_display_other_addons_by"
+msgid_plural "addons_display_other_addons_by"
+msgstr[0] "Të tjera shtesa nga %1$s"
+msgstr[1] "Të tjera shtesa nga këta autorë"
+
+#. %s is the name of the add-on and the add-on section. Example:
+#. Some Add-on :: Firefox Add-ons
+#. This should not be concatenated in the code and should be fixed.
+#: controllers/addons_controller.php:141 controllers/addons_controller.php:280
+#: controllers/addons_controller.php:1442
+#, php-format
+msgid "addons_display_pagetitle"
+msgstr "%s"
+
+#. %s is an email address
+#: views/addons/display.thtml:286
+#, php-format
+msgid "addons_display_paragraph_supportinfoemail"
+msgstr "Asistenca për këtë shtesë ofrohet te %s nga zhvilluesi i saj."
+
+#. %$1s is a URL
+#. %$2s is an email address
+#: views/addons/display.thtml:269
+#, php-format
+msgid "addons_display_paragraph_supportinfoemailurl"
+msgstr ""
+"Asistenca për këtë shtesë ofrohet te %s nga zhvilluesi i saj ose mund të "
+"kihet duke dërguar një e-mail te %s."
+
+#. %s is a URL
+#: views/addons/display.thtml:278
+#, php-format
+msgid "addons_display_paragraph_supportinfourl"
+msgstr "Asistenca për këtë shtesë ofrohet te %s nga zhvilluesi i saj."
+
+#: views/addons/display.thtml:383
+msgid "addons_display_rate_it"
+msgstr "Vlerësoje"
+
+#: views/reviews/add.thtml:93 views/reviews/add.thtml:94
+msgid "addons_display_really_like_it"
+msgstr "Vërtet më pëlqen"
+
+#: views/addons/display.thtml:410
+msgid "addons_display_review_etiquette"
+msgstr ""
+"Ju lutemi mos postoni raportime të metash në shqyrtime. Nuk ua japim "
+"vendndodhjet tuaja email zhvilluesve të shtesave, e ata mund të kenë nevojë "
+"të lidhen me ju për t'ju ndihmuar në zgjidhjen e problemit."
+
+#. %1 is the review guidelines link
+#: views/addons/display.thtml:417
+msgid "addons_display_review_guidelines_link"
+msgstr "<a href=\"%s\">Udhëzime Shqyrtimi</a>"
+
+#. %1 is the support section link
+#: views/addons/display.thtml:414
+msgid "addons_display_review_see_support"
+msgstr ""
+"Për të parë se prej nga mund të keni asistencë rreth kësaj shtese, hidhini "
+"një sy <a href=\"%1$s\">ndarjes për asistencë</a>."
+
+#: views/addons/display.thtml:404
+msgid "addons_display_review_submit"
+msgstr "Ruaje"
+
+#: views/addons/display.thtml:430
+#, php-format
+msgid "addons_display_see_all_addons"
+msgstr "Shihni Tërë Shtesat %1$s"
+
+#. %1 is the number of reviews
+#: views/addons/display.thtml:364
+#, php-format
+msgid "addons_display_see_all_reviews"
+msgstr "Shihni tërë shqyrtimet (%1$s)"
+
+#: views/addons/display.thtml:219
+msgid "addons_display_see_all_versions"
+msgstr "Shihni Tërë Versionet"
+
+#: views/addons/display.thtml:321 views/addons/versions.thtml:117
+msgid "addons_display_view_source"
+msgstr "Shihni burimin"
+
+#: views/addons/display.thtml:324
+msgid "addons_display_view_stats"
+msgstr "Shihni statistikat"
+
+#: views/addons/display.thtml:376
+msgid "addons_display_what_do_you_think"
+msgstr "Si ju duket?"
+
+#: views/elements/app_compatibility.thtml:49
+msgid "addons_display_workswith"
+msgstr "Punon me:"
+
+#: views/addons/home.thtml:112
+#, fuzzy
+msgid "addons_home_browse_new"
+msgstr "Just Added"
+
+#: views/addons/home.thtml:110
+#, fuzzy
+msgid "addons_home_browse_popular"
+msgstr "Popular"
+
+#: views/addons/home.thtml:108
+#, fuzzy
+msgid "addons_home_browse_recommended"
+msgstr "Recommended"
+
+#: views/addons/home.thtml:127 views/addons/home.thtml:134
+#: views/addons/home.thtml:141 views/addons/home.thtml:148
+#, fuzzy
+msgid "addons_home_browse_subscribe"
+msgstr "Subscribe"
+
+#: views/addons/home.thtml:101
+#, fuzzy
+msgid "addons_home_browse_title"
+msgstr "Browse Add-ons"
+
+#: views/addons/home.thtml:114
+#, fuzzy
+msgid "addons_home_browse_updated"
+msgstr "Updated"
+
+#: views/elements/amo2009/homepage_addon.thtml:100
+#: views/elements/addon_discussionheader.thtml:83
+#: views/elements/addon_listitem.thtml:109 views/elements/feature.thtml:95
+#: views/addons/category_landing.thtml:66 views/addons/policy.thtml:57
+#: views/addons/display.thtml:70 views/addons/home.thtml:178
+msgid "addons_home_by"
+msgstr "nga"
+
+#: views/addons/home.thtml:169
+#, fuzzy
+msgid "addons_home_collection_popular_title"
+msgstr "Popular Collections"
+
+#: views/elements/amo2009/categories.thtml:69 views/addons/home.thtml:160
+#, fuzzy
+msgid "addons_home_collections"
+msgstr "Collections"
+
+#. %1$s is the count of addons in a collection
+#: views/elements/amo2009/collection_listing_item.thtml:51
+#: views/addons/home.thtml:185
+#, fuzzy
+msgid "addons_home_collections_addon_count"
+msgid_plural "addons_home_collections_addon_count"
+msgstr[0] "<strong>%1$s</strong> add-on"
+msgstr[1] "<strong>%1$s</strong> add-ons"
+
+#: views/addons/home.thtml:196
+#, fuzzy
+msgid "addons_home_collections_all"
+msgstr "View All Collections"
+
+#: views/addons/home.thtml:162
+#, fuzzy
+msgid "addons_home_collections_intro"
+msgstr ""
+"Collections are a way for you to categorize, mix, match and mingle add-ons. "
+"Subscribe to collections created by other users or create your own."
+
+#. %1$s is the count of subscribers for a collection
+#: views/elements/amo2009/collection_listing_item.thtml:58
+#: views/collections/detail.thtml:96 views/addons/home.thtml:189
+#, fuzzy
+msgid "addons_home_collections_subscribers"
+msgid_plural "addons_home_collections_subscribers"
+msgstr[0] "<strong>%1$s</strong> subscriber"
+msgstr[1] "<strong>%1$s</strong> subscribers"
+
+#: views/addons/searchengines.thtml:54 views/addons/themes_landing.thtml:49
+msgid "addons_home_feature_head"
+msgstr "Ju Këshillojmë"
+
+#: controllers/search_controller.php:218 controllers/addons_controller.php:176
+#: controllers/addons_controller.php:428 controllers/addons_controller.php:671
+#: controllers/addons_controller.php:871
+#: controllers/addons_controller.php:1103
+#: controllers/addons_controller.php:1242
+#: controllers/addons_controller.php:1298
+#, php-format
+msgid "addons_home_header_details"
+msgstr ""
+"Shtesat zgjerojnë %1$s-in, duke ju bërë të mundur të personalizoni përvojën "
+"tuaj në shfletim. Hidhni një sy përreth dhe krijoni %1$s-in tuaj."
+
+#. %1$s is the HTML collection name link.
+#: views/elements/amo2009/teaser_collections.thtml:107
+#, fuzzy
+msgid "addons_home_introduction_collection_link"
+msgstr "Like these? Find related add-ons in the %1$s collection."
+
+#: views/elements/amo2009/teaser_collections.thtml:60
+#, fuzzy
+msgid "addons_home_introduction_extras"
+msgstr ""
+"<strong>Over 5000 free extras</strong> that let you customize and extend "
+"Firefox to meet your needs."
+
+#: views/elements/amo2009/teaser_collections.thtml:55
+#, fuzzy
+msgid "addons_home_introduction_header"
+msgstr "What are Add-ons?"
+
+#: views/elements/amo2009/teaser_collections.thtml:72
+msgid "addons_home_introduction_install"
+msgstr "<strong>Të lehta në instalim</strong> dhe në përditësim."
+
+#: views/elements/amo2009/teaser_collections.thtml:45
+#, fuzzy
+msgid "addons_home_introduction_name"
+msgstr "Introduction"
+
+#: views/elements/amo2009/teaser_collections.thtml:66
+#, fuzzy
+msgid "addons_home_introduction_themes"
+msgstr ""
+"Toolbars, themes and search providers that <strong>help you perform common "
+"tasks.</strong>"
+
+#: views/addons/home.thtml:161
+#, fuzzy
+msgid "addons_home_new_indicator"
+msgstr "NEW!"
+
+#: views/elements/app_chooser.thtml:48 views/layouts/amo2009.thtml:257
+msgid "addons_home_other_applications"
+msgstr "Zbatime të Tjera"
+
+#. %1$s is the application the user is browsing. Examples: Thunderbird, Firefox,
+#. Sunbird
+#: views/pages/collector_faq.thtml:49 views/pages/collector_firstrun.thtml:42
+#: views/pages/collector.thtml:46 views/pages/collector_features.thtml:54
+#: controllers/developers_controller.php:87
+#: controllers/compatibility_controller.php:72
+#: controllers/components/simple_acl.php:81 controllers/components/amo.php:607
+#: controllers/statistics_controller.php:60
+#: controllers/statistics_controller.php:240
+#: controllers/previews_controller.php:67 controllers/users_controller.php:90
+#: controllers/users_controller.php:223 controllers/users_controller.php:330
+#: controllers/users_controller.php:414 controllers/users_controller.php:708
+#: controllers/users_controller.php:723 controllers/reviews_controller.php:204
+#: controllers/reviews_controller.php:251
+#: controllers/reviews_controller.php:346
+#: controllers/reviews_controller.php:425
+#: controllers/search_controller.php:185 controllers/search_controller.php:297
+#: controllers/search_controller.php:301 controllers/addons_controller.php:147
+#: controllers/addons_controller.php:280 controllers/addons_controller.php:370
+#: controllers/addons_controller.php:667 controllers/addons_controller.php:874
+#: controllers/addons_controller.php:1019
+#: controllers/addons_controller.php:1034
+#: controllers/addons_controller.php:1101
+#: controllers/addons_controller.php:1121
+#: controllers/addons_controller.php:1240
+#: controllers/addons_controller.php:1357
+#: controllers/addons_controller.php:1364
+#: controllers/addons_controller.php:1442
+#: controllers/addons_controller.php:1477
+#: controllers/addons_controller.php:1538
+#: controllers/addons_controller.php:1543
+#: controllers/editors_controller.php:64 controllers/pages_controller.php:132
+#: controllers/groups_controller.php:65 controllers/groups_controller.php:71
+#: controllers/groups_controller.php:89 controllers/groups_controller.php:111
+#: controllers/collections_controller.php:57
+#: controllers/collections_controller.php:121
+#: controllers/collections_controller.php:205
+#: controllers/collections_controller.php:365
+#: controllers/collections_controller.php:404
+#: controllers/collections_controller.php:466
+#: controllers/collections_controller.php:538
+#: controllers/collections_controller.php:828
+#: controllers/localizers_controller.php:72
+#, php-format
+msgid "addons_home_pagetitle"
+msgstr "Shtesa %1$s"
+
+#. %1$s is the number of addons downloaded
+#: views/addons/home.thtml:57
+#, fuzzy, php-format
+msgid "addons_home_stats_downloaded"
+msgid_plural "addons_home_stats_downloaded"
+msgstr[0] "<strong>%1$s</strong> <span>add-on downloaded</span>"
+msgstr[1] "<strong>%1$s</strong> <span>add-ons downloaded</span>"
+
+#. %1$s is the number of addons in use
+#: views/addons/home.thtml:63
+#, fuzzy, php-format
+msgid "addons_home_stats_inuse"
+msgid_plural "addons_home_stats_inuse"
+msgstr[0] "<strong>%1$s</strong> <span>add-on in use</span>"
+msgstr[1] "<strong>%1$s</strong> <span>add-ons in use</span>"
+
+#: views/addons/home.thtml:136
+msgid "addons_home_view_all_newest_title"
+msgstr "Shihni tërë shtesat e krijuara rishtas"
+
+#: views/addons/home.thtml:129
+msgid "addons_home_view_all_popular_title"
+msgstr "Shihni tërë shtesat popullore"
+
+#: views/addons/home.thtml:150
+msgid "addons_home_view_all_recommended_title"
+msgstr "Shihni tërë shtesat e këshilluara"
+
+#: views/addons/home.thtml:143
+msgid "addons_home_view_all_updated_title"
+msgstr "Shihni tërë shtesat e përditësuara rishtas"
+
+#: views/elements/amo2009/install.thtml:334 views/elements/install.thtml:112
+msgid "addons_install_in_sunbird"
+msgstr ""
+"<ol><li>Klikoni mbi lidhjen e mëposhtme për të ruajtur kartelën.</li><li>Te "
+"Mozilla Sunbird-i, hapni Shtesa prej menusë Mjete.</li><li>Klikoni butonin "
+"Instaloje, mandej gjeni/përzgjidhni kartelën që shkarkuat dhe klikoni \"OK\"."
+"</li></ol>"
+
+#: views/elements/amo2009/install.thtml:333 views/elements/install.thtml:111
+msgid "addons_install_in_sunbird_title"
+msgstr "Si të Instalohet në Sunbird"
+
+#: views/elements/amo2009/install.thtml:331 views/elements/install.thtml:106
+msgid "addons_install_in_thunderbird"
+msgstr ""
+"<ol><li>Djathtas-klikoni lidhjen më poshtë dhe zgjidhni \"Ruaje Lidhjen Si..."
+"\" për të shkarkuar dhe ruajtur kartelën te hard disku juaj.</li><li>Te "
+"Mozilla Thunderbird, hapni Shtesat prej menusë Mjete.</li><li>Klikoni "
+"butonin Instaloje, dhe gjeni/përzgjidhni kartelën që shkarkuat dhe klikoni "
+"\"OK\".</li></ol>"
+
+#: views/elements/amo2009/install.thtml:330 views/elements/install.thtml:105
+msgid "addons_install_in_thunderbird_title"
+msgstr "Si ta Instaloni te Thunderbird-i"
+
+#: views/elements/amo2009/addon_list_options.thtml:108
+#: views/elements/addon_list_options.thtml:105
+msgid "addons_options_show_experimental"
+msgstr "shfaq shtesa eksperimentale"
+
+#: views/elements/amo2009/addon_list_options.thtml:113
+#: views/elements/addon_list_options.thtml:109
+msgid "addons_options_submit"
+msgstr "Shko"
+
+#: views/addons/plugins.thtml:63 views/addons/plugins.thtml:73
+#: views/addons/plugins.thtml:83 views/addons/plugins.thtml:93
+#: views/addons/plugins.thtml:103 views/addons/plugins.thtml:116
+#: views/addons/plugins.thtml:126
+msgid "addons_plugins_by"
+msgstr "Nga"
+
+#: views/addons/plugins.thtml:107
+msgid "addons_plugins_for_linux"
+msgstr "për Linux"
+
+#: views/addons/plugins.thtml:108 views/addons/plugins.thtml:131
+msgid "addons_plugins_for_macosx"
+msgstr "për Mac OS X"
+
+#: views/addons/plugins.thtml:106 views/addons/plugins.thtml:129
+#: views/addons/plugins.thtml:130
+msgid "addons_plugins_for_windows"
+msgstr "për Windows"
+
+#. %1$s is a URL
+#: views/addons/plugins.thtml:139
+#, php-format
+msgid "addons_plugins_looking_for_more"
+msgstr ""
+"Kjo faqe radhit vetëm disa prej shtojcave më të zakonshme dhe më të njohura. "
+"Për më tepër të dhëna rreth të tjera shtojcash të pashme për Shfletuesa me "
+"bazë Mozilla-n, vizitoni %1$s"
+
+#: views/addons/plugins.thtml:137
+msgid "addons_plugins_looking_for_plugin"
+msgstr "Po shihni për një shtojcë të paradhitur këtu?"
+
+#: views/addons/plugins.thtml:58
+msgid "addons_plugins_main_description"
+msgstr ""
+"Shtojcat e ndihmojnë shfletuesin tuaj të përmbushin funksione të veçantë si "
+"parje formatesh të veçantë grafikë ose luajtje kartelash multimedia. "
+"Shtojcat janë pakëz ndryshe nga zgjerimet, të cialt ndryshojnë ose shtojnë "
+"diçka te një anë ekzistuese."
+
+#. %1$s is the application name. Example: Firefox, Thunderbird, Sunbird
+#: controllers/addons_controller.php:1122
+#, php-format
+msgid "addons_plugins_main_header"
+msgstr "Shtojca të Zakonshme për %1$s"
+
+#: controllers/components/amo.php:698 controllers/addons_controller.php:1121
+msgid "addons_plugins_pagetitle"
+msgstr "Shtojca"
+
+#: views/addons/plugins.thtml:68 views/addons/plugins.thtml:78
+#: views/addons/plugins.thtml:88 views/addons/plugins.thtml:98
+#: views/addons/plugins.thtml:110 views/addons/plugins.thtml:121
+#: views/addons/plugins.thtml:133
+msgid "addons_plugins_support_documentation"
+msgstr "Dokumentacion Asistence: "
+
+#. %s is the name of the add-on
+#: views/addons/policy.thtml:61
+#, php-format
+msgid "addons_policy_eula_require"
+msgstr ""
+"%s kërkon që ju të pranoni \"End User License Agreement\" (Marrëveshje "
+"License Përdoruesi të Fundëm) vijuese para se të bëhet procesi i instalimit:"
+
+#. %1 is the add-on name
+#: controllers/addons_controller.php:1476
+#, php-format
+msgid "addons_previews_pagetitle"
+msgstr "Paraparje për %s"
+
+#: views/addons/category_landing.thtml:135
+#, fuzzy
+msgid "addons_recently_added"
+msgstr "Recently Added"
+
+#: views/addons/recommended.thtml:51 controllers/addons_controller.php:1365
+msgid "addons_recommended_introduction"
+msgstr ""
+"Me kaq shumë shtesa të forta të passhme, ka diçka për secilin. Për t'ia "
+"filluar, ja një listë me disa nga më populloret. Kënaquni!"
+
+#: controllers/addons_controller.php:1357
+#: controllers/addons_controller.php:1364
+msgid "addons_recommended_pagetitle"
+msgstr "Shtesa të Këshilluara"
+
+#: controllers/addons_controller.php:1360
+msgid "addons_recommended_title"
+msgstr "Shtesa të Këshilluara"
+
+#: views/addons/searchengines.thtml:136
+msgid "addons_searchengines_additional_resources"
+msgstr "Burime Shtesë"
+
+#. link text devmo
+#: views/addons/searchengines.thtml:141
+msgid "addons_searchengines_devmo_link"
+msgstr "Qendra e Zhvilluesave Mozilla"
+
+#: views/pages/js_constants.js.thtml:67
+msgid "addons_searchengines_error_mozilla_browser_required"
+msgstr ""
+"Na ndjeni, lypset të kini një shfletues me bazë Mozilla (si Firefox-i) për "
+"të instaluar një shtojcë kërkimi."
+
+#: views/addons/searchengines.thtml:49
+msgid "addons_searchengines_error_nojavascript"
+msgstr ""
+"Lypset JavaScript për të instaluar shtojcat, por duket sikur ju ta keni të "
+"çaktivizuar. Ju lutem aktivizoni JavaScript-in përpara se të provoni të "
+"instaloni ndonjërën prej shtojcave për kërkime që shihni."
+
+#. %1 is "make your own" link
+#. %2 is MDC link
+#: views/addons/searchengines.thtml:139
+msgid "addons_searchengines_learn_howto"
+msgstr "Mësoni se si të %1$s te %2$s."
+
+#. link path to search plugins instructions, relative to devmo
+#: views/addons/searchengines.thtml:140
+msgid "addons_searchengines_makeyourown_href"
+msgstr "/sq/docs/Creating_OpenSearch_plugins_for_Firefox"
+
+#. link text for "make your own" (opensearch engine)
+#: views/addons/searchengines.thtml:140
+msgid "addons_searchengines_makeyourown_link"
+msgstr "krijoni të tuajën"
+
+#. %1 is the link to mycroft.mozdev.org
+#: views/addons/searchengines.thtml:138
+msgid "addons_searchengines_more"
+msgstr "Shfletoni nëpër më tepër motorë kërkimesh te %1$s"
+
+#. link text to mycroft.mozdev.org
+#: views/addons/searchengines.thtml:138
+msgid "addons_searchengines_mycroft_link"
+msgstr "mycroft.mozdev.org"
+
+#: controllers/addons_controller.php:1100
+#: controllers/addons_controller.php:1110
+msgid "addons_searchengines_pagetitle"
+msgstr "Motorë Kërkimesh"
+
+#: views/addons/searchengines.thtml:143
+msgid "addons_searchengines_thanks"
+msgstr ""
+"Falënderime të veçanta Projektit Mycroft për punën e tyre në Motorë "
+"Kërkimesh për Firefox-in."
+
+#: views/addons/display.thtml:154
+msgid "addons_share_button_text"
+msgstr "Ndajeni me të tjerë"
+
+#: controllers/addons_controller.php:89
+msgid "addons_share_label_delicious"
+msgstr "Shtoje te Delicious"
+
+#: controllers/addons_controller.php:77
+msgid "addons_share_label_digg"
+msgstr "Digg this!"
+
+#: controllers/addons_controller.php:83
+msgid "addons_share_label_facebook"
+msgstr "Postoje te Facebook"
+
+#: controllers/addons_controller.php:101
+msgid "addons_share_label_friendfeed"
+msgstr "Ndajeni te FriendFeed"
+
+#: controllers/addons_controller.php:95
+msgid "addons_share_label_myspace"
+msgstr "Postoje te MySpace"
+
+#: controllers/components/amo.php:201 controllers/components/amo.php:229
+msgid "addons_status_disabled"
+msgstr "E çaktivizuar"
+
+#: controllers/components/amo.php:191 controllers/components/amo.php:224
+msgid "addons_status_incomplete"
+msgstr "Version Jo i Plotë"
+
+#: controllers/components/amo.php:197 controllers/components/amo.php:227
+msgid "addons_status_nominated"
+msgstr "Në Bankoprovë; Propozuar Publikisht"
+
+#: views/pages/js_constants.js.thtml:80 controllers/components/amo.php:195
+#: controllers/components/amo.php:226
+msgid "addons_status_pending"
+msgstr "Në Bankoprovë; Në Pritje të Shqyrtimit"
+
+#: views/pages/js_constants.js.thtml:78 controllers/components/amo.php:199
+#: controllers/components/amo.php:228
+msgid "addons_status_public"
+msgstr "Publike"
+
+#: views/pages/js_constants.js.thtml:79 controllers/components/amo.php:193
+#: controllers/components/amo.php:225
+msgid "addons_status_sandbox"
+msgstr "Në Bankoprovë"
+
+#: controllers/components/amo.php:203
+msgid "addons_status_unknown"
+msgstr "E panjohur"
+
+#: views/elements/amo2009/teaser_collections.thtml:91
+#: views/elements/amo2009/homepage_addon.thtml:99
+#: views/elements/feature.thtml:94
+msgid "addons_title_tooltip"
+msgstr "Mësoni më tepër rreth kësaj shtese"
+
+#: views/addons/category_landing.thtml:151
+#, fuzzy
+msgid "addons_top_downloads"
+msgstr "Top Downloads"
+
+#: views/addons/category_landing.thtml:165
+#, fuzzy
+msgid "addons_top_rated"
+msgstr "Top Rated"
+
+#: views/addons/versions.thtml:62
+msgid "addons_versions_careful"
+msgstr "Bëni Kujdes Me Versione të Vjetër"
+
+#: views/addons/versions.thtml:63
+msgid "addons_versions_careful_introduction"
+msgstr ""
+"Këta versione paraqiten për qëllime reference dhe prove. Do të duhej që të "
+"përdorni përherë versionin më të fundit të një shtese."
+
+#: controllers/addons_controller.php:1549
+msgid "addons_versions_history"
+msgstr "Historik Versionesh me Regjistrime Ndryshimesh"
+
+#. %1$s is the add-on name
+#: controllers/addons_controller.php:1535
+#, php-format
+msgid "addons_versions_pagetitle"
+msgstr "Historik Versionesh të %1$s"
+
+#: controllers/groups_controller.php:71
+msgid "admin_group_add_pagetitle"
+msgstr "Shto Grup"
+
+#: controllers/groups_controller.php:111
+msgid "admin_group_delete_pagetitle"
+msgstr "Fshi Group"
+
+#. %s is a number to identify the group
+#: controllers/groups_controller.php:117
+#, php-format
+msgid "admin_group_deleted"
+msgstr "Grupi me id %s u fshi"
+
+#: controllers/groups_controller.php:89
+msgid "admin_group_edit_pagetitle"
+msgstr "Përpunoni Grup"
+
+#: controllers/groups_controller.php:92 controllers/groups_controller.php:113
+msgid "admin_group_error_invalid_id"
+msgstr "Id e pavlefshme për Grup"
+
+#: controllers/groups_controller.php:65
+msgid "admin_group_pagetitle"
+msgstr "Adminstrator Grupi"
+
+#: controllers/groups_controller.php:77 controllers/groups_controller.php:99
+msgid "admin_group_saved"
+msgstr "Grupi u ruajt"
+
+#: views/elements/amo2009/search.thtml:257 views/elements/search.thtml:239
+msgid "advanced_search_form"
+msgstr "I thelluar"
+
+#: views/elements/amo2009/search.thtml:126 views/elements/search.thtml:125
+msgid "advanced_search_form_any_time"
+msgstr "Çfarëdo kohe"
+
+#: views/elements/amo2009/search.thtml:97
+#: views/elements/amo2009/search.thtml:110 views/elements/search.thtml:96
+#: views/elements/search.thtml:109
+msgid "advanced_search_form_any_type"
+msgstr "Çfarëdo"
+
+#: views/elements/amo2009/search.thtml:275 views/elements/search.thtml:254
+msgid "advanced_search_form_any_version"
+msgstr "Çfarëdo"
+
+#: views/elements/amo2009/search.thtml:217 views/elements/search.thtml:212
+msgid "advanced_search_form_application"
+msgstr "Zbatim"
+
+#: views/elements/amo2009/search.thtml:143 views/elements/search.thtml:142
+msgid "advanced_search_form_keyword_match"
+msgstr "Përputhje për Fjalëkyç"
+
+#: views/elements/amo2009/search.thtml:251 views/elements/search.thtml:225
+msgid "advanced_search_form_lastupdate"
+msgstr "Përditësuar Së Fundmi"
+
+#: views/elements/amo2009/search.thtml:145 views/elements/search.thtml:144
+msgid "advanced_search_form_name"
+msgstr "Emër"
+
+#: views/elements/amo2009/search.thtml:144 views/elements/search.thtml:143
+msgid "advanced_search_form_newest"
+msgstr "Më e reja"
+
+#: views/elements/amo2009/search.thtml:130 views/elements/search.thtml:129
+msgid "advanced_search_form_past_3_months"
+msgstr "3 muajt e kaluar"
+
+#: views/elements/amo2009/search.thtml:131 views/elements/search.thtml:130
+msgid "advanced_search_form_past_6_months"
+msgstr "6 muajt e kaluar"
+
+#: views/elements/amo2009/search.thtml:127 views/elements/search.thtml:126
+msgid "advanced_search_form_past_day"
+msgstr "Ditën e Kaluar"
+
+#: views/elements/amo2009/search.thtml:129 views/elements/search.thtml:128
+msgid "advanced_search_form_past_month"
+msgstr "Muajin e Kaluar"
+
+#: views/elements/amo2009/search.thtml:128 views/elements/search.thtml:127
+msgid "advanced_search_form_past_week"
+msgstr "Javën e Kaluar"
+
+#: views/elements/amo2009/search.thtml:132 views/elements/search.thtml:131
+msgid "advanced_search_form_past_year"
+msgstr "Vitin e kaluar"
+
+#: views/elements/amo2009/search.thtml:239 views/elements/search.thtml:230
+msgid "advanced_search_form_perpage"
+msgstr "Për Faqe"
+
+#: views/elements/amo2009/search.thtml:243 views/elements/search.thtml:224
+msgid "advanced_search_form_platform"
+msgstr "Platformë"
+
+#: views/elements/amo2009/search.thtml:147 views/elements/search.thtml:146
+msgid "advanced_search_form_popularity"
+msgstr "Popullaritet"
+
+#: views/elements/amo2009/search.thtml:146 views/elements/search.thtml:145
+msgid "advanced_search_form_rating"
+msgstr "Vlerësim"
+
+#: views/elements/amo2009/search.thtml:247 views/elements/search.thtml:231
+msgid "advanced_search_form_sortby"
+msgstr "Renditur Sipas"
+
+#: views/elements/amo2009/search.thtml:227 views/elements/search.thtml:216
+msgid "advanced_search_form_to"
+msgstr "te"
+
+#: views/elements/amo2009/search.thtml:257 views/elements/search.thtml:237
+msgid "advanced_search_form_toggle_tooltip"
+msgstr "Këmbe mënyrë kërkimi të përparuar"
+
+#: views/elements/amo2009/search.thtml:235 views/elements/search.thtml:223
+msgid "advanced_search_form_type"
+msgstr "Lloj"
+
+#: views/elements/amo2009/search.thtml:222 views/elements/search.thtml:214
+msgid "advanced_search_form_version"
+msgstr "version"
+
+#: views/elements/amo2009/pagination.thtml:42
+#, fuzzy
+msgid "amo2009_pagination_next_page"
+msgstr "Next"
+
+#: views/elements/amo2009/pagination.thtml:41
+#, fuzzy
+msgid "amo2009_pagination_previous_page"
+msgstr "Prev"
+
+#: views/pages/js_constants.js.thtml:96
+msgid "app_compat_ignore_check"
+msgstr "Shpërfill kontroll versioni"
+
+#: views/pages/js_constants.js.thtml:72
+msgid "app_compat_older_firefox_only"
+msgstr "Kjo shtesë është për versione te vjetra të Firefox-it"
+
+#. %1$s and %2$s are URLs
+#: views/pages/js_constants.js.thtml:74
+msgid "app_compat_older_version_or_ignore_check"
+msgstr ""
+"Mund <a href=\"%1$s\">të provoni një version të vjetër</a> ose <a href=\"#"
+"\" onclick=\"%2$s\">shpërfilleni këtë kontroll</a>"
+
+#. %1$s is a URL
+#: views/pages/js_constants.js.thtml:71
+msgid "app_compat_try_old_version"
+msgstr "Mund të bëjë punë ndonjë <a href=\"%1$s\">version më i vjetër</a>"
+
+#. %1$s is a URL
+#. %2$s is a version number. Example: 3.1
+#: views/pages/js_constants.js.thtml:73
+msgid "app_compat_unreleased_version"
+msgstr ""
+"Kjo shtesë lyp <a href=\"%1$s\">Firefox %2$s</a> ende të pahedhur në "
+"qarkullim"
+
+#: views/pages/js_constants.js.thtml:70
+msgid "app_compat_update_firefox"
+msgstr ""
+"<a href=\"http://getfirefox.com\">Përditësoni Firefox-in</a> që të mund të "
+"përdorni këtë shtesë"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#. %3$s is a status, like Public.
+#: controllers/components/audit.php:79
+#, fuzzy
+msgid "audit_addon_status"
+msgstr "%1$s changed the status of %2$s to %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:221
+#, fuzzy
+msgid "audit_admin_default"
+msgstr "%1$s committed unknown admin action %2$s to ID %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:153
+#, fuzzy
+msgid "audit_admin_feature_remove"
+msgstr "%1$s removed feature %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is an application, like Firefox.
+#: controllers/components/audit.php:92
+#, fuzzy
+msgid "audit_application_create"
+msgstr "%1$s created application %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is an application, like Firefox.
+#: controllers/components/audit.php:95
+#, fuzzy
+msgid "audit_application_edit"
+msgstr "%1$s edited application %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a version number, like 3.5.
+#. %3$s is an application, like Firefox.
+#: controllers/components/audit.php:105
+#, fuzzy
+msgid "audit_appversion_create"
+msgstr "%1$s created version %2$s for %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a version number, like 3.5.
+#. %3$s is an application, like Firefox.
+#: controllers/components/audit.php:108
+#, fuzzy
+msgid "audit_appversion_delete"
+msgstr "%1$s deleted version %2$s for %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a config field, like "awesomeness".
+#. %3$s is a config value, like "off".
+#. %4$s is a config value, like "on".
+#: controllers/components/audit.php:210
+#, fuzzy
+msgid "audit_config"
+msgstr "%1$s changed config '%2$s' from '%3$s' to '%4$s'"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:258
+#, fuzzy
+msgid "audit_editor_default"
+msgstr "%1$s committed unknown editor action %2$s to ID %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#: controllers/components/audit.php:236
+#, fuzzy
+msgid "audit_editor_feature_remove"
+msgstr "%1$s removed addon %2$s from feature list"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#: controllers/components/audit.php:231
+#, fuzzy
+msgid "audit_feature_add"
+msgstr "%1$s added addon %2$s to feature list"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:149
+#, fuzzy
+msgid "audit_feature_edit"
+msgstr "%1$s changed a feature for %2$s locale"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#: controllers/components/audit.php:241
+#, fuzzy
+msgid "audit_feature_locale_change"
+msgstr "%1$s changed locales for addon %2$s on feature list"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:83
+#, fuzzy
+msgid "audit_file_recalchash"
+msgstr "%1$s recalculated the hash for file %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>user name</a>
+#. %3$s is <a>group name</a>
+#: controllers/components/audit.php:182
+#, fuzzy
+msgid "audit_group_addmember"
+msgstr "%1$s added %2$s to group %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:313
+#, fuzzy
+msgid "audit_group_associated"
+msgstr "%1$s associated themselves with %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:162
+#, fuzzy
+msgid "audit_group_create"
+msgstr "%1s created group %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:170
+#, fuzzy
+msgid "audit_group_delete"
+msgstr "%1$s deleted group %2$s (ID %3$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:165
+#, fuzzy
+msgid "audit_group_edit"
+msgstr "%1$s edited group %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>user name</a>
+#. %3$s is <a>group name</a>
+#: controllers/components/audit.php:188
+#, fuzzy
+msgid "audit_group_removemember"
+msgstr "%1$s removed %2$s from group %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:280
+#, fuzzy
+msgid "audit_l10n_default"
+msgstr "%1$s committed unknown action %2$s for %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:295
+#, fuzzy
+msgid "audit_modify_locked_group"
+msgstr "%1$s attempted to modify locked group %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:299
+#, fuzzy
+msgid "audit_modify_other_locale"
+msgstr "%1$s attempted to modify translations in %2$s without permission"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a platform, like <a>Windows</a>
+#: controllers/components/audit.php:135
+#, fuzzy
+msgid "audit_platform_create"
+msgstr "%1$s created platform %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a platform, like <a>Windows</a>
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:143
+#, fuzzy
+msgid "audit_platform_delete"
+msgstr "%1$s deleted platform %2$s (ID %3$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a platform, like <a>Windows</a>
+#: controllers/components/audit.php:138
+#, fuzzy
+msgid "audit_platform_edit"
+msgstr "%1$s edited platform %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a part of the admin, like 'Site Config'
+#: controllers/components/audit.php:288
+#, fuzzy
+msgid "audit_reauthentication_failure"
+msgstr "%1$s failed to re-authenticate to access %2$s."
+
+#. %1$s is <a>user name</a>
+#. %2$s is the name of a canned response, like 'Ready for the public'
+#: controllers/components/audit.php:198
+#, fuzzy
+msgid "audit_response_create"
+msgstr "%1$s created response %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is the name of a canned response, like 'Ready for the public'
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:206
+#, fuzzy
+msgid "audit_response_delete"
+msgstr "%1$s deleted response %2$s (ID %3$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is the name of a canned response, like 'Ready for the public'
+#: controllers/components/audit.php:201
+#, fuzzy
+msgid "audit_response_edit"
+msgstr "%1$s edited response %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:245
+#, fuzzy
+msgid "audit_review_approve"
+msgstr "%1$s approved review %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:250 controllers/components/audit.php:253
+#, fuzzy
+msgid "audit_review_delete"
+msgstr "%1$s deleted review %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:303
+#, fuzzy
+msgid "audit_security_default"
+msgstr "%1$s committed unknown security action %2$s to ID %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a category name, like <a>Search Tools</a>
+#: controllers/components/audit.php:118
+#, fuzzy
+msgid "audit_tag_create"
+msgstr "%1$s created tag %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a category name, like <a>Search Tools</a>
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:126
+#, fuzzy
+msgid "audit_tag_delete"
+msgstr "%1$s deleted category %2$s (ID %3$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a category name, like <a>Search Tools</a>
+#: controllers/components/audit.php:121
+#, fuzzy
+msgid "audit_tag_edit"
+msgstr "%1$s edited category %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:266
+#, fuzzy
+msgid "audit_update_applications"
+msgstr "%1$s updated application translations for %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:277
+#, fuzzy
+msgid "audit_update_blog"
+msgstr "%1$s updated blog post translations for %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:274
+#, fuzzy
+msgid "audit_update_platforms"
+msgstr "%1$s updated platform translations for %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:270
+#, fuzzy
+msgid "audit_update_tags"
+msgstr "%1$s updated category translations for %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>user name</a>
+#: controllers/components/audit.php:217
+#, fuzzy
+msgid "audit_user_edit"
+msgstr "%1$s edited %2$s's user information"
+
+#: controllers/addons_controller.php:1012
+msgid "browse_addons_name"
+msgstr "Shtesa sipas Emrash"
+
+#: controllers/addons_controller.php:1010
+msgid "browse_addons_newest"
+msgstr "Shtesat Më të Reja"
+
+#: controllers/addons_controller.php:1008
+msgid "browse_addons_popular"
+msgstr "Shtesa Popullore"
+
+#: controllers/addons_controller.php:1011
+msgid "browse_addons_rated"
+msgstr "Shtesa sipas Vlerësimeve"
+
+#: controllers/addons_controller.php:1009
+msgid "browse_addons_updated"
+msgstr "Shtesa të Përditësuara së Fundmi"
+
+#: views/elements/categories.thtml:73 views/elements/categories.thtml:82
+msgid "categories_current_title"
+msgstr "Kategoria e Tanishme"
+
+#: views/elements/categories.thtml:50
+#: views/elements/amo2009/categories.thtml:43
+#: views/elements/amo2009/categories.thtml:45
+msgid "categories_header"
+msgstr "Kategori"
+
+#: views/elements/categories.thtml:50
+#: views/elements/amo2009/categories.thtml:41
+msgid "categories_header_title"
+msgstr "Zgjidhni kategori"
+
+#. %1$s is the category name
+#: views/addons/searchengines.thtml:129
+#, php-format
+msgid "category_extra_see_all"
+msgstr "Shihni Tërë %1$s"
+
+#. %1$s is a number.
+#: models/collection.php:130
+#, fuzzy
+msgid "collection_description_limit"
+msgstr "The description should be less than %1$s characters."
+
+#. %1$s is the name of the collection
+#: controllers/collections_controller.php:392
+#, fuzzy
+msgid "collection_detail_rss_title"
+msgstr "%s Collection"
+
+#: controllers/collections_controller.php:1065
+#, fuzzy
+msgid "collection_error_deleting_addon"
+msgstr "Error deleting add-on!"
+
+#: controllers/collections_controller.php:1051
+#, fuzzy
+msgid "collection_error_saving_addon"
+msgstr "Error saving add-on!"
+
+#: controllers/collections_controller.php:1080
+#, fuzzy
+msgid "collection_error_saving_comment"
+msgstr "Error saving comment!"
+
+#. %1$s is a number.
+#: models/collection.php:122
+#, fuzzy
+msgid "collection_name_limit"
+msgstr "The name should be less than %1$s characters."
+
+#: controllers/collections_controller.php:352
+#: controllers/collections_controller.php:487
+msgid "collection_not_found"
+msgstr "Nuk u gjet përmbledhje!"
+
+#. %1$s is the text on the "create collection" button
+#: views/collections/add.thtml:91
+#, fuzzy
+msgid "collections_add_formfield_addons_description"
+msgstr ""
+"If you already know which add-ons you want to add to your collection, just "
+"start typing their names below. If you'd rather wait and do this later, just "
+"click %1$s now."
+
+#: views/collections/add.thtml:90
+#, fuzzy
+msgid "collections_add_formfield_firstaddons"
+msgstr "Choose your first add-ons"
+
+#: views/collections/add.thtml:48
+#, fuzzy
+msgid "collections_add_header"
+msgstr "Create a Collection"
+
+#: views/collections/add.thtml:97
+#, fuzzy
+msgid "collections_add_header_selectedaddons"
+msgstr "Selected Add-ons"
+
+#: views/collections/add.thtml:50
+#, fuzzy
+msgid "collections_add_intro"
+msgstr ""
+"It's easy to create your own collection of add-ons by filling in a few "
+"fields below."
+
+#: views/collections/add.thtml:92 views/collections/add.thtml:103
+#, fuzzy
+msgid "collections_add_submit"
+msgstr "Create Collection"
+
+#: views/pages/collector_faq.thtml:50 views/pages/collector_firstrun.thtml:43
+#: views/pages/collector.thtml:47 views/pages/collector_features.thtml:55
+#: controllers/search_controller.php:302
+#: controllers/collections_controller.php:206
+#: controllers/collections_controller.php:405
+#: controllers/collections_controller.php:467
+#: controllers/collections_controller.php:539
+#, fuzzy
+msgid "collections_breadcrumb"
+msgstr "Collections"
+
+#: views/collections/detail.thtml:185
+#, fuzzy
+msgid "collections_detail_a_learn"
+msgstr "Learn More"
+
+#: views/elements/amo2009/collection_add_form.thtml:53
+#: views/elements/amo2009/collections_js_init.thtml:68
+#: views/pages/collector_firstrun.thtml:64
+#, fuzzy
+msgid "collections_detail_button_add"
+msgstr "Add to Favorites"
+
+#: views/elements/amo2009/collection_add_form.thtml:50
+#: views/elements/amo2009/collections_js_init.thtml:71
+#, fuzzy
+msgid "collections_detail_button_remove"
+msgstr "Remove from Favorites"
+
+#. %1$s is a URL.
+#. %2$s is a full <a href>.
+#: views/collections/detail.thtml:62
+#, fuzzy
+msgid "collections_detail_created_desc"
+msgstr ""
+"<p>You can view your new collection below. If you'd like to set a collection "
+"nickname, upload an icon, or change additional settings, please visit the <a "
+"href='%1$s'>Manage Collections</a> page.</p><p>Your collection can be "
+"accessed at this location: %2$s</p>"
+
+#: views/collections/detail.thtml:61
+#, fuzzy
+msgid "collections_detail_created_msg"
+msgstr "Your collection is now ready!"
+
+#: views/collections/detail.thtml:109
+#, fuzzy
+msgid "collections_detail_header_about"
+msgstr "About This Collection"
+
+#. %1$s is a number.
+#: views/collections/detail.thtml:126
+#, fuzzy
+msgid "collections_detail_header_count"
+msgid_plural "collections_detail_header_count"
+msgstr[0] "%1$s Add-on in this Collection"
+msgstr[1] "%1$s Add-ons in this Collection"
+
+#: views/collections/detail.thtml:113
+#, fuzzy
+msgid "collections_detail_info_created"
+msgstr "<strong>Created by:</strong> %1$s"
+
+#: views/collections/detail.thtml:117
+#, fuzzy
+msgid "collections_detail_info_updated"
+msgstr "<strong>Updated:</strong>"
+
+#: views/elements/amo2009/collections_js_init.thtml:62
+#, fuzzy
+msgid "collections_detail_js_adding"
+msgstr "Adding to Favorites&hellip;"
+
+#: views/elements/amo2009/collections_js_init.thtml:65
+#, fuzzy
+msgid "collections_detail_js_removing"
+msgstr "Removing Favorite&hellip;"
+
+#. %1$s is a URL
+#: views/collections/detail.thtml:90
+#, fuzzy
+msgid "collections_detail_login"
+msgstr "<a href=\"%1$s\">Log in</a> to add this collection to your favorites."
+
+#: views/collections/detail.thtml:104
+#, fuzzy
+msgid "collections_detail_manage"
+msgstr "Manage Collection"
+
+#: controllers/collections_controller.php:298
+#, fuzzy
+msgid "collections_detail_sort_date"
+msgstr "Date Added"
+
+#: controllers/collections_controller.php:299
+#, fuzzy
+msgid "collections_detail_sort_name"
+msgstr "Name"
+
+#: controllers/collections_controller.php:300
+#, fuzzy
+msgid "collections_detail_sort_popularity"
+msgstr "Popularity"
+
+#. %1$s is a number.
+#: views/collections/detail.thtml:166
+#, fuzzy
+msgid "collections_detail_weekly_downloads"
+msgid_plural "collections_detail_weekly_downloads"
+msgstr[0] "%1$s download this week"
+msgstr[1] "%1$s downloads this week"
+
+#: views/collections/edit.thtml:255
+#, fuzzy
+msgid "collections_edit_addons_delete_noscript"
+msgstr "Selected add-ons will be removed upon Save"
+
+#: views/collections/edit.thtml:247
+#, fuzzy
+msgid "collections_edit_addons_description"
+msgstr ""
+"To publish new add-ons to this collection, start typing their names below."
+
+#: views/collections/edit.thtml:248
+#, fuzzy
+msgid "collections_edit_addons_description_noscript"
+msgstr ""
+"To publish new add-ons to this collection, enter a comma-separated list of "
+"Add-on IDs below."
+
+#: views/collections/edit.thtml:247 views/collections/edit.thtml:248
+#, fuzzy
+msgid "collections_edit_addons_description_publish_detailspage"
+msgstr "You can also publish an add-on from its normal listing page."
+
+#. %1$s is the date the add-on was added to the collection
+#. %1$s is the name of the user who added the add-on to the collection
+#: views/collections/edit.thtml:260
+#, fuzzy
+msgid "collections_edit_addons_listitem_added"
+msgstr "Added %1$s by %2$s"
+
+#: views/collections/edit.thtml:263
+#, fuzzy
+msgid "collections_edit_addons_listitem_comment_add"
+msgstr "Add publisher comment"
+
+#: views/collections/edit.thtml:266
+#, fuzzy
+msgid "collections_edit_addons_listitem_comment_delete"
+msgstr "Delete publisher comment"
+
+#: views/collections/edit.thtml:265
+#, fuzzy
+msgid "collections_edit_addons_listitem_comment_edit"
+msgstr "Edit publisher comment"
+
+#: views/collections/edit.thtml:271
+#, fuzzy
+msgid "collections_edit_addons_listitem_comment_note"
+msgstr ""
+"Note: Comment will appear as though written by original publisher on the "
+"original publication date"
+
+#: views/collections/edit.thtml:270
+#, fuzzy
+msgid "collections_edit_addons_listitem_comment_submit"
+msgstr "Save Comment"
+
+#: views/collections/edit.thtml:261
+#, fuzzy
+msgid "collections_edit_addons_listitem_remove"
+msgstr "Remove"
+
+#: views/collections/edit.thtml:250
+#, fuzzy
+msgid "collections_edit_addons_submit"
+msgstr "Add to Collection"
+
+#: views/collections/edit.thtml:153
+#, fuzzy
+msgid "collections_edit_check_nickname"
+msgstr "Check Availability"
+
+#: views/collections/edit.thtml:299
+#, fuzzy
+msgid "collections_edit_confirm_deletecollection"
+msgstr "Yes, I would like to delete this collection."
+
+#. %1$s is the label of the edit form's submit button
+#: views/collections/edit.thtml:300
+#, fuzzy
+msgid "collections_edit_confirm_deletecollection_description"
+msgstr "Check the box, then click on \"%1$s\" to delete this collection."
+
+#. %1$s is the "delete" submit button text
+#. %2$s is the title of the "advanced" tab
+#: views/collections/edit.thtml:95
+#, fuzzy
+msgid "collections_edit_delete_upon_submit"
+msgstr ""
+"Upon clicking \"%1$s\" below, your collection will be deleted. If you do not "
+"want to delete your collection, uncheck the confirmation box in the \"%2$s\" "
+"tab and continue editing your collection. If you leave this page without "
+"saving, your collection will also not be deleted."
+
+#: views/collections/edit.thtml:94
+#, fuzzy
+msgid "collections_edit_delete_warning"
+msgstr "Your collection is about to be deleted!"
+
+#: views/collections/add.thtml:76 views/collections/edit.thtml:144
+#, fuzzy
+msgid "collections_edit_form_error_description"
+msgstr "You must provide a description of your collection."
+
+#: views/collections/edit.thtml:181
+#, fuzzy
+msgid "collections_edit_form_error_icon"
+msgstr "There was an error uploading your icon."
+
+#: views/collections/add.thtml:69 views/collections/edit.thtml:130
+#, fuzzy
+msgid "collections_edit_form_error_name"
+msgstr "You must give your collection a name."
+
+#: views/collections/edit.thtml:158
+#, fuzzy
+msgid "collections_edit_form_error_nickname"
+msgstr "If you choose a nickname, it must be unique."
+
+#: views/collections/add.thtml:93 views/collections/edit.thtml:249
+#, fuzzy
+msgid "collections_edit_formfield_addons"
+msgstr "Add-on name:"
+
+#: views/collections/edit.thtml:281
+#, fuzzy
+msgid "collections_edit_formfield_application"
+msgstr "Associated Application"
+
+#: views/collections/edit.thtml:282
+#, fuzzy
+msgid "collections_edit_formfield_application_description"
+msgstr "Select the application that your collection supports."
+
+#: views/collections/edit.thtml:288
+#, fuzzy
+msgid "collections_edit_formfield_collectiontype"
+msgstr "Collection Type"
+
+#: views/collections/edit.thtml:295
+#, fuzzy
+msgid "collections_edit_formfield_deletecollection"
+msgstr "Delete Collection"
+
+#: views/collections/edit.thtml:296
+#, fuzzy
+msgid "collections_edit_formfield_deletecollection_description"
+msgstr "Deleting your collection will permanently erase it."
+
+#: views/collections/add.thtml:73 views/collections/edit.thtml:140
+#, fuzzy
+msgid "collections_edit_formfield_description"
+msgstr "Collection Description"
+
+#: views/collections/add.thtml:74 views/collections/edit.thtml:141
+#, fuzzy
+msgid "collections_edit_formfield_description_description"
+msgstr "Briefly describe your collection and the kind of add-ons in it"
+
+#: views/collections/edit.thtml:162
+#, fuzzy
+msgid "collections_edit_formfield_icon"
+msgstr "Icon"
+
+#: views/collections/edit.thtml:163
+#, fuzzy
+msgid "collections_edit_formfield_icon_description"
+msgstr ""
+"You can upload a JPG, GIF or PNG icon that will be resized to 32x32 pixels."
+
+#: views/collections/add.thtml:80 views/collections/edit.thtml:189
+#, fuzzy
+msgid "collections_edit_formfield_listed"
+msgstr "Who can view your collection?"
+
+#: views/collections/add.thtml:81 views/collections/edit.thtml:190
+#, fuzzy
+msgid "collections_edit_formfield_listed_description"
+msgstr ""
+"By default, collections appear in the public Collection Directory and are "
+"discoverable by anyone. If you want to restrict your collection to be "
+"viewable only by people who are given a special link, choose that option "
+"below."
+
+#: views/collections/add.thtml:84 views/collections/edit.thtml:193
+#, fuzzy
+msgid "collections_edit_formfield_listed_false"
+msgstr "Only people I invite can view my collection"
+
+#: views/collections/add.thtml:83 views/collections/edit.thtml:192
+#, fuzzy
+msgid "collections_edit_formfield_listed_true"
+msgstr "Everyone can view my collection in the directory"
+
+#: views/collections/edit.thtml:223
+#, fuzzy
+msgid "collections_edit_formfield_managers"
+msgstr "Who can manage my collection?"
+
+#: views/collections/edit.thtml:224
+#, fuzzy
+msgid "collections_edit_formfield_managers_description"
+msgstr ""
+"These users can publish add-ons to your collection, manage all add-ons and "
+"settings, and grant other users permission."
+
+#: views/collections/add.thtml:66 views/collections/edit.thtml:126
+#, fuzzy
+msgid "collections_edit_formfield_name"
+msgstr "Collection Name"
+
+#: views/collections/add.thtml:67 views/collections/edit.thtml:127
+#, fuzzy
+msgid "collections_edit_formfield_name_description"
+msgstr ""
+"Give your collection a descriptive name, such as \"Dave's Favorite Travel "
+"Add-ons\""
+
+#: views/collections/edit.thtml:148
+#, fuzzy
+msgid "collections_edit_formfield_nickname"
+msgstr "Collection Nickname"
+
+#: views/collections/edit.thtml:149
+#, fuzzy
+msgid "collections_edit_formfield_nickname_description"
+msgstr "Optionally, give your collection a unique nickname for quick access:"
+
+#: views/collections/edit.thtml:201
+#, fuzzy
+msgid "collections_edit_formfield_publishers"
+msgstr "Who can publish add-ons to your collection?"
+
+#: views/collections/edit.thtml:202
+#, fuzzy
+msgid "collections_edit_formfield_publishers_description"
+msgstr ""
+"These users can publish add-ons to your collection and remove add-ons that "
+"they publish."
+
+#: views/collections/edit.thtml:210 views/collections/edit.thtml:232
+#, fuzzy
+msgid "collections_edit_formfield_users_add"
+msgstr "Enter the e-mail address of a Firefox Add-ons account:"
+
+#: views/collections/edit.thtml:216 views/collections/edit.thtml:238
+#, fuzzy
+msgid "collections_edit_formfield_users_delete_noscript"
+msgstr "Selected accounts will be removed upon Save"
+
+#: views/collections/edit.thtml:215 views/collections/edit.thtml:237
+#, fuzzy
+msgid "collections_edit_formfield_users_new_noscript"
+msgstr ""
+"Enter a comma-separated list of e-mail addresses of Firefox Add-ons accounts"
+
+#: views/collections/edit.thtml:204 views/collections/edit.thtml:226
+#, fuzzy
+msgid "collections_edit_formfield_users_onlyme"
+msgstr "Only me"
+
+#: views/collections/edit.thtml:205 views/collections/edit.thtml:227
+#, fuzzy
+msgid "collections_edit_formfield_users_otherusers"
+msgstr "Myself and these users:"
+
+#: views/collections/edit.thtml:211 views/collections/edit.thtml:233
+#, fuzzy
+msgid "collections_edit_formfield_users_submit"
+msgstr "Add"
+
+#. %1$s is the name of the collection
+#: views/collections/edit.thtml:68
+#, fuzzy
+msgid "collections_edit_header"
+msgstr "Manage %1$s"
+
+#: views/collections/edit.thtml:246
+#, fuzzy
+msgid "collections_edit_header_addons"
+msgstr "Manage Collection Contents"
+
+#: views/collections/edit.thtml:253 views/collections/edit.thtml:258
+#, fuzzy
+msgid "collections_edit_header_addons_current"
+msgstr "Current Add-ons:"
+
+#: views/collections/edit.thtml:279
+#, fuzzy
+msgid "collections_edit_header_advanced"
+msgstr "Advanced Settings"
+
+#: views/collections/edit.thtml:186
+#, fuzzy
+msgid "collections_edit_header_permissions"
+msgstr "Manage Collection Permissions"
+
+#: views/collections/edit.thtml:170
+#, fuzzy
+msgid "collections_edit_icon_cancel"
+msgstr "Cancel"
+
+#: views/collections/edit.thtml:174 views/collections/edit.thtml:179
+#, fuzzy
+msgid "collections_edit_icon_delete"
+msgstr "Delete Icon"
+
+#: views/collections/edit.thtml:178
+#, fuzzy
+msgid "collections_edit_icon_replace"
+msgstr "Replace Icon"
+
+#. %1$s is the label of the edit form's submit button
+#: views/collections/edit.thtml:169
+#, fuzzy
+msgid "collections_edit_icon_toberemoved"
+msgstr "Icon will be removed when \"%1$s\" is clicked below"
+
+#: views/collections/edit.thtml:155
+#, fuzzy
+msgid "collections_edit_nickname_available"
+msgstr "Nickname Available"
+
+#: controllers/collections_controller.php:943
+#, fuzzy
+msgid "collections_edit_nickname_error"
+msgstr ""
+"Your nickname contained invalid characters and was corrected. Please try "
+"again."
+
+#: views/collections/edit.thtml:156
+#, fuzzy
+msgid "collections_edit_nickname_taken"
+msgstr "Nickname Taken"
+
+#. This string is followed by a URL pointing to the collection's view page
+#: views/collections/edit.thtml:75
+#, fuzzy
+msgid "collections_edit_saved_nextstep"
+msgstr "Your collection can be accessed at this location:"
+
+#: views/collections/edit.thtml:74
+#, fuzzy
+msgid "collections_edit_saved_success"
+msgstr "Your collection was successfully saved!"
+
+#: views/collections/edit.thtml:169 views/collections/edit.thtml:300
+#: views/collections/edit.thtml:308 views/pages/js_constants.js.thtml:99
+#, fuzzy
+msgid "collections_edit_submit"
+msgstr "Update Collection"
+
+#: views/collections/edit.thtml:96 views/collections/edit.thtml:297
+#: views/pages/js_constants.js.thtml:100
+#, fuzzy
+msgid "collections_edit_submit_deletecollection"
+msgstr "Delete Collection"
+
+#: views/collections/edit.thtml:111
+#, fuzzy
+msgid "collections_edit_tabheader_addons"
+msgstr "Add-ons"
+
+#: views/collections/edit.thtml:97 views/collections/edit.thtml:113
+#, fuzzy
+msgid "collections_edit_tabheader_advanced"
+msgstr "Advanced"
+
+#: views/collections/edit.thtml:108
+#, fuzzy
+msgid "collections_edit_tabheader_details"
+msgstr "Name &amp; Details"
+
+#: views/collections/edit.thtml:109
+#, fuzzy
+msgid "collections_edit_tabheader_permissions"
+msgstr "Permissions"
+
+#: models/collection_promo.php:53
+msgid "collections_family_tagline"
+msgstr "Mbani nën kontroll fëmijët dhe kalendarin tuaj"
+
+#: models/collection_promo.php:53
+msgid "collections_family_title"
+msgstr "Familje"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:70
+#, fuzzy
+msgid "collections_index_a_check_out"
+msgstr "Check out Add-on Collector"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:52
+#, fuzzy
+msgid "collections_index_a_create"
+msgstr "Create a Collection"
+
+#: views/collections/detail.thtml:139 views/collections/listing.thtml:85
+#: views/search/collections.thtml:84
+#, fuzzy
+msgid "collections_index_button_go"
+msgstr "Go"
+
+#. %1$s is a URL.
+#: controllers/collections_controller.php:182
+#, fuzzy
+msgid "collections_index_filler_favorites"
+msgstr ""
+"<p><strong>You don't have any favorite collections yet.</strong></p> "
+"<p>Collections you mark as favorites can be quickly accessed from this page, "
+"and will appear in the <a href='%1$s'>Add-on Collector</a> if you've "
+"installed it.</p>"
+
+#. %1$s is a URL.
+#: controllers/collections_controller.php:167
+#, fuzzy
+msgid "collections_index_filler_mine"
+msgstr ""
+"<p>You haven't created any collections yet. Collections are easy to create "
+"and fill with your favorite add-ons. <a href='%1$s'>Try it out</a>!</p>"
+
+#: views/collections/listing.thtml:51
+#, fuzzy
+msgid "collections_index_header_collections"
+msgstr "Collections"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:60
+#, fuzzy
+msgid "collections_index_header_collector"
+msgstr "Add-on Collector"
+
+#. %1$s is a comma-separated list of author names
+#: views/elements/amo2009/collection_listing_item.thtml:84
+#: views/collections/detail.thtml:151
+#, fuzzy
+msgid "collections_index_header_created"
+msgstr "created by %1$s"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:47
+#, fuzzy
+msgid "collections_index_header_what"
+msgstr "What are Collections?"
+
+#: views/collections/detail.thtml:132 views/collections/listing.thtml:78
+#: views/search/collections.thtml:66
+#, fuzzy
+msgid "collections_index_label_sortby"
+msgstr "Sort by"
+
+#: controllers/collections_controller.php:130
+#, fuzzy
+msgid "collections_index_li_editors"
+msgstr "Editor's Picks"
+
+#: views/collections/subscribe.thtml:64
+#: controllers/collections_controller.php:140
+#, fuzzy
+msgid "collections_index_li_favorites"
+msgstr "My Favorites"
+
+#: controllers/collections_controller.php:138
+#, fuzzy
+msgid "collections_index_li_mine"
+msgstr "My Collections"
+
+#: controllers/collections_controller.php:132
+#, fuzzy
+msgid "collections_index_li_popular"
+msgstr "Popular"
+
+#: views/search/collections.thtml:74 controllers/collections_controller.php:81
+#, fuzzy
+msgid "collections_index_option_all"
+msgstr "Most popular all time"
+
+#: views/search/collections.thtml:72 controllers/collections_controller.php:78
+#, fuzzy
+msgid "collections_index_option_month"
+msgstr "Most popular this month"
+
+#: views/search/collections.thtml:76 controllers/collections_controller.php:84
+#, fuzzy
+msgid "collections_index_option_newest"
+msgstr "Newest"
+
+#: views/search/collections.thtml:70 controllers/collections_controller.php:75
+#, fuzzy
+msgid "collections_index_option_week"
+msgstr "Most popular this week"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:67
+#, fuzzy
+msgid "collections_index_p_collector"
+msgstr ""
+"There's a new way to manage and find favorite add-ons. Comment, share and "
+"sync collections, all from your browser"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:48
+#, fuzzy
+msgid "collections_index_p_what_are"
+msgstr "Collections are groups of related add-ons assembled for easy sharing."
+
+#. %s is a date in the _('date') format
+#: views/elements/collections_interactive_addon.thtml:85
+#, php-format
+msgid "collections_interactive_addon_added"
+msgstr "U shtua %s"
+
+#: models/collection_promo.php:55
+msgid "collections_reference_tagline"
+msgstr "Kërkoni \"online\" për gjithçka"
+
+#: models/collection_promo.php:55
+msgid "collections_reference_title"
+msgstr "Referencë"
+
+#: models/collection_promo.php:52
+msgid "collections_social_tagline"
+msgstr "Administroni rrjetin tuaj shoqëror"
+
+#: models/collection_promo.php:52
+msgid "collections_social_title"
+msgstr "Shoqërore"
+
+#: views/collections/subscribe.thtml:91
+#, fuzzy
+msgid "collections_subscribe_button_close"
+msgstr "Close"
+
+#: views/collections/subscribe.thtml:70
+#, fuzzy
+msgid "collections_subscribe_error"
+msgstr ""
+"An error occurred trying to add a favorite collection. Is this collection "
+"already a favorite?"
+
+#: views/collections/subscribe.thtml:96
+#, fuzzy
+msgid "collections_subscribe_label_bothersome"
+msgstr "Don't show me this message again."
+
+#. %1$s is the collection name
+#: views/collections/subscribe.thtml:60
+#, fuzzy
+msgid "collections_subscribe_success"
+msgstr "%1$s has been added to your favorite collections."
+
+#. %1$s is the link to the "My Favorites" tab on the main collections page
+#. %2$s is the localized title of the "My Favorites" tab
+#. %3$s is the link URL to the collector add-on
+#: views/collections/subscribe.thtml:62
+#, fuzzy
+msgid "collections_subscribe_success_desc"
+msgstr ""
+"You can now quickly find this collection from the <a href=\"%1$s\">%2$s</a> "
+"tab in the directory. For an even easier way to keep track of your favorite "
+"collections, try out our <a href=\"%3$s\">Add-on Collector</a> extension for "
+"Firefox."
+
+#: views/collections/listing.thtml:55
+#, fuzzy
+msgid "collections_success_delete"
+msgstr "The collection has been deleted."
+
+#: models/collection_promo.php:54
+msgid "collections_travel_tagline"
+msgstr "Planifikoni udhëtime pune dhe pushime të paharrueshme"
+
+#: models/collection_promo.php:54
+msgid "collections_travel_title"
+msgstr "Udhëtime"
+
+#. A collection of add-ons that is automatically built for a user. They are "automatically published" to this collection.
+#: controllers/collections_controller.php:581
+#, fuzzy
+msgid "collections_type_autopublisher"
+msgstr "Auto-publisher"
+
+#. A collection that has been chosen by an Editor as notable or exceptional
+#: controllers/collections_controller.php:582
+#, fuzzy
+msgid "collections_type_editorspick"
+msgstr "Editor's Pick"
+
+#: controllers/collections_controller.php:580
+#, fuzzy
+msgid "collections_type_normal"
+msgstr "Normal"
+
+#: views/collections/subscribe.thtml:84
+#, fuzzy
+msgid "collections_unsubscribe_error"
+msgstr ""
+"An error occurred trying to remove a favorite collection. Was this "
+"collection not a favorite?"
+
+#. %1$s is the collection name
+#: views/collections/subscribe.thtml:78
+#, fuzzy
+msgid "collections_unsubscribe_success"
+msgstr "%1$s has been removed from your favorite collections."
+
+#: models/collection_promo.php:56
+msgid "collections_webdev_tagline"
+msgstr "Krijoni \"site\"-in e përsosur web"
+
+#: models/collection_promo.php:56
+msgid "collections_webdev_title"
+msgstr "Zhvillim Web"
+
+#: views/elements/amo2009/collections_sidebar_whatare.thtml:40
+#, fuzzy
+msgid "collections_whatare_header"
+msgstr "What are Collections?"
+
+#: views/elements/amo2009/collections_sidebar_whatare.thtml:45
+#, fuzzy
+msgid "collections_whatare_learnmore"
+msgstr "Read the FAQ"
+
+#: views/elements/amo2009/collections_sidebar_whatare.thtml:44
+#, fuzzy
+msgid "collections_whatare_text"
+msgstr ""
+"There’s a new way to manage and find favorite add-ons. Comment, share and "
+"sync collections, all from your browser."
+
+#: views/pages/collector_faq.thtml:61 views/pages/collector_features.thtml:67
+#, fuzzy
+msgid "collector_features_a_home"
+msgstr "Add-on Collector Home"
+
+#: views/elements/amo2009/collector_sidebar_download.thtml:46
+#, fuzzy
+msgid "collector_features_heading_download"
+msgstr "Download the Add-on Collector:"
+
+#: views/elements/amo2009/collector_sidebar_download.thtml:43
+#: views/pages/collector_firstrun.thtml:116 views/pages/collector.thtml:69
+#, fuzzy
+msgid "collector_features_img_logo"
+msgstr "Add-on Collector Logo"
+
+#: views/compatibility/dashboard.thtml:49
+#: controllers/compatibility_controller.php:72
+msgid "compatibility_dashboard_center_header"
+msgstr "Qendra e Përputhshmërisë së Shtojcave"
+
+#. %1$s is the name of an application and a version. Example: Firefox 3.0
+#. %2$s is the name of an application. Example: Firefox
+#: views/compatibility/dashboard.thtml:50
+msgid "compatibility_dashboard_intro"
+msgstr ""
+"Të jini gati për hedhjen në qarkullim të %1$s me mjete dhe të dhëna për "
+"bashkësinë e Shtesave %2$s gjetur më poshtë."
+
+#: views/compatibility/dashboard.thtml:103
+msgid "compatibility_dashboard_loading"
+msgstr "Po ngarkohen të dhëna..."
+
+#: views/compatibility/dashboard.thtml:45
+msgid "compatibility_dashboard_main_link"
+msgstr "Mbrapsht te Kryesorja"
+
+#: views/compatibility/dashboard.thtml:100 views/compatibility/report.thtml:43
+msgid "compatibility_dashboard_report"
+msgstr "Raport Përputhshmërie Shtese"
+
+#: views/compatibility/dashboard.thtml:53
+#: views/compatibility/dashboard.thtml:110
+#: views/compatibility/developers.thtml:43
+msgid "compatibility_developer_info"
+msgstr "Të dhëna për Zhvilluesa Shtese"
+
+#: views/compatibility/developers.thtml:66
+msgid "compatibility_developers_adjust_maxversion"
+msgstr "Rregulloni maxVersion pa e ngarkuar"
+
+#: views/compatibility/dashboard.thtml:124
+msgid "compatibility_developers_check_status"
+msgstr "Kontrollo Gjendjen e Shtesave të Mia"
+
+#. %1$s is a URL
+#. %2$s is an application and version. Example: Firefox 3.0
+#: views/compatibility/dashboard.thtml:126
+msgid "compatibility_developers_login_first"
+msgstr ""
+"Nëse keni shtesa të strehuara te Shtesa Mozilla, <a href=\"%1$s\">ju lutem "
+"bëni hyrjen</a>, që të mund të analizoni gjendjen e shtesave tuaja për %2$s."
+
+#: views/compatibility/dashboard.thtml:114
+msgid "compatibility_developers_mdclogo_alt"
+msgstr "Shenja Dalluese e Qendrës Mozilla të Zhvilluesve"
+
+#: views/compatibility/developers.thtml:73
+msgid "compatibility_developers_no_addons"
+msgstr "Nuk keni ndonjë shtesë të strehuar te Shtesat Mozilla."
+
+#: views/compatibility/dashboard.thtml:133
+#: views/compatibility/developers.thtml:55
+msgid "compatibility_developers_results"
+msgstr "Përfundime Kontrolli për Gjendje Shtojce"
+
+#: views/compatibility/dashboard.thtml:137
+msgid "compatibility_developers_retrieving"
+msgstr "Po shihet gjendja e shtesave të strehuara..."
+
+#. %1$s is a number
+#. %2$s is an application name
+#. %3$s is a number.
+#. Full example: 50 Firefox users (10% of total)
+#: views/compatibility/developers.thtml:65
+msgid "compatibility_developers_user_count"
+msgstr "%1$s përdoruesa %2$s-i (%3$s&#37; gjithsej)"
+
+#: views/compatibility/report.thtml:45
+msgid "compatibility_report_detail_intro"
+msgstr ""
+"Shtesat e mëposhtme përbëjnë 95% të përdorimit të shtesave që di Mozilla dhe "
+"janë renditur sipas masës së përdorimit."
+
+#: views/compatibility/dashboard.thtml:94
+msgid "compatibility_report_detailed_link"
+msgstr "Shihni Raportin e Hollësishëm"
+
+#. %1$s and %2$s are numbers
+#. %3$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:65
+msgid "compatibility_report_intro"
+msgstr ""
+"Nga %1$s shtesat që përbëjnë 95&#37; të përdorimit të shtesa që di Mozilla, "
+"<b>%2$s&#37;</b> konsiderohen si të përputhshme me versionet e fundit të %3"
+"$s-it."
+
+#: views/compatibility/dashboard.thtml:81
+msgid "compatibility_report_legend_alpha"
+msgstr "Versione Alfa"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:81
+msgid "compatibility_report_legend_alpha_description"
+msgstr "Shtesa të përputhshme me një version alfa të %1$s-it"
+
+#: views/compatibility/dashboard.thtml:85
+msgid "compatibility_report_legend_beta"
+msgstr "Versione Beta"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:85
+msgid "compatibility_report_legend_beta_description"
+msgstr ""
+"Shtesa të përputhshme me një version beta ose version kandidat të %1$s-it"
+
+#: views/compatibility/dashboard.thtml:89
+msgid "compatibility_report_legend_latest"
+msgstr "Version Më i Fundit"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:89
+msgid "compatibility_report_legend_latest_description"
+msgstr "Shtesa të përditësuara për montimet më të fundit të %1$s-it"
+
+#: views/compatibility/dashboard.thtml:77
+msgid "compatibility_report_legend_other"
+msgstr "Versione të Tjera"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:77
+msgid "compatibility_report_legend_other_description"
+msgstr "Shtesa të papërputhshme me ndonjë version të %1$s-it"
+
+#: views/compatibility/dashboard.thtml:62
+msgid "compatibility_report_title"
+msgstr "Raport Përputhshmërie Shtese"
+
+#: views/compatibility/dashboard.thtml:54
+#: views/compatibility/dashboard.thtml:144 views/compatibility/users.thtml:42
+msgid "compatibility_user_info"
+msgstr "Të dhëna për Përdoruesit e Shtesës"
+
+#: views/compatibility/dashboard.thtml:52
+msgid "compatibility_view_report"
+msgstr "Shihni Raport Përputhshmërie"
+
+#. %s is a URL
+#: views/pages/credits.thtml:142
+#, php-format
+msgid "credits_contributing"
+msgstr "Për të dhëna se si të merrni pjesë, ju lutemi shihni %s tonë."
+
+#: views/pages/credits.thtml:142
+msgid "credits_contributing_wikipage"
+msgstr "faqe wiki"
+
+#: views/pages/credits.thtml:99
+msgid "credits_intro"
+msgstr ""
+"Mozilla dëshiron të falënderojë personat vijues për ndihmën e tyre te "
+"projekti addons.mozilla.org përgjatë vitesh:"
+
+#: views/pages/credits.thtml:103
+msgid "credits_section_developers"
+msgstr "Zhvilluesa"
+
+#: views/pages/credits.thtml:115
+msgid "credits_section_editors"
+msgstr "Redaktorë"
+
+#: views/pages/credits.thtml:109
+msgid "credits_section_localizers"
+msgstr "Përkthyesa"
+
+#: views/pages/credits.thtml:121
+msgid "credits_section_other_contributors"
+msgstr "Pjesëmarrës të Tjerë"
+
+#: views/pages/credits.thtml:127
+msgid "credits_section_past_developers"
+msgstr "Zhvilluesa të Dikurshëm"
+
+#: views/pages/credits.thtml:133
+msgid "credits_section_software"
+msgstr "Software dhe Pamje"
+
+#: views/pages/credits.thtml:136
+msgid "credits_software_famfamfam"
+msgstr ""
+"Disa ikona të përdorura janë prej <a href=\"http://www.famfamfam.com/lab/"
+"icons/silk/\">famfamfam Silk Icon Set</a>, licensuar sipas <a href=\"http://"
+"creativecommons.org/licenses/by/2.5/\">Licensës Creative Commons Attribution "
+"2.5</a>."
+
+#: views/pages/credits.thtml:137
+msgid "credits_software_timeplot"
+msgstr ""
+"Disa faqe përdorin elemente nga <a href=\"http://www.simile-widgets.org/"
+"timeplot/\">Timeplot</a>, të lejuar sipas një <a href=\"http://simile.mit."
+"edu/license.html\">Lejeje BSD</a>."
+
+#. date format string as used in PHP's strftime():
+#. http://php.net/strftime
+#: views/elements/collections_interactive_addon.thtml:85
+#: views/elements/amo2009/addon_version_detail.thtml:53
+#: views/elements/amo2009/homepage_addon.thtml:115
+#: views/elements/addon_version_detail.thtml:54
+#: views/elements/addon_listitem.thtml:124 views/elements/feature.thtml:106
+#: views/collections/detail.thtml:118 views/collections/edit.thtml:325
+#: views/users/info.thtml:76 views/editors/reviews_queue.thtml:57
+#: views/editors/reviews_queue.thtml:68 views/developers/dashboard.thtml:65
+#: views/developers/versions_edit.thtml:208 views/developers/versions.thtml:67
+#: views/search/rss/index.thtml:5 views/addons/rss/versions.thtml:42
+#: views/addons/display.thtml:104 views/addons/display.thtml:356
+#: views/addons/browse_thumbs.thtml:75 views/reviews/add.thtml:63
+#: views/reviews/display.thtml:74 views/reviews/display.thtml:160
+#: views/reviews/delete.thtml:54 controllers/statistics_controller.php:244
+#: controllers/collections_controller.php:1047
+msgid "date"
+msgstr "%e %B, %Y"
+
+#. date and time format string (strftime)
+#. http://php.net/strftime
+#: views/elements/addon_version_detail.thtml:53
+#: views/developers/discuss.thtml:52 views/developers/discuss.thtml:62
+#: views/admin/addons_status.thtml:57
+msgid "datetime"
+msgstr "%e %B, %Y, %I:%M %p"
+
+#: views/elements/developers/actionbar.thtml:47
+msgid "devcp_actionbar_link_details"
+msgstr "Të dhëna të Hollësishme"
+
+#: views/elements/developers/actionbar.thtml:42
+#: views/elements/developers/actionbar.thtml:50
+#: views/developers/dashboard.thtml:64
+msgid "devcp_actionbar_link_edit"
+msgstr "Përpunoni Shtesën"
+
+#: views/elements/developers/actionbar.thtml:51
+msgid "devcp_actionbar_link_newversion"
+msgstr "Ngarko Version të Ri"
+
+#: views/elements/developers/actionbar.thtml:44
+#: views/elements/developers/actionbar.thtml:49
+#: views/developers/dashboard.thtml:73
+msgid "devcp_actionbar_link_stats"
+msgstr "Pult Statistikash"
+
+#. %1$s is a filename, e.g. "foo.txt"
+#. %2$s is the extension, e.g. ".txt"
+#. %3$s is a list of valid extensions, like ".png, .jpg, .gif"
+#: controllers/developers_controller.php:1361
+msgid "devcp_add_previews_extension_error"
+msgstr "Kartela %1$s ka zgjatim të pavlefshëm (%2$s). Zgjatime të lejuar: %3$s"
+
+#. %s is the filename.
+#: controllers/developers_controller.php:1394
+msgid "devcp_add_previews_save_error"
+msgstr ""
+"Kartela %s nuk mund të ruhej dot te baza e të dhënave. Ju lutem riprovoni."
+
+#. %1$s is the preview ID number, %2$s is the filename.
+#: controllers/developers_controller.php:1389
+msgid "devcp_add_previews_success_replace"
+msgstr "Paraparja %1$s u zëvendësua me sukses me kartelën %2$s."
+
+#. %s is the filename.
+#: controllers/developers_controller.php:1391
+msgid "devcp_add_previews_success_upload"
+msgstr ""
+"Kartela %s u ngarkua me sukses. Më poshtë mund të shtoni një përshkrim."
+
+#: controllers/components/developers.php:1163
+msgid "devcp_additem_addontype_autodetect"
+msgstr "(vetë-zbulo)"
+
+#: views/elements/developers/additem.thtml:76
+msgid "devcp_additem_linktitle_opensin_newwindow"
+msgstr "Hapet në një dritare të re"
+
+#: views/elements/developers/additem.thtml:41
+msgid "devcp_additem_sidebar_title"
+msgstr "Parashtroni Shtesë"
+
+#: views/elements/developers/additem.thtml:53
+msgid "devcp_additem_step0_newlink"
+msgstr "Marrëveshje Zhvilluesi"
+
+#: views/elements/developers/additem.thtml:46
+msgid "devcp_additem_step1_link"
+msgstr "Hapi 1: Ngarkim"
+
+#: views/elements/developers/additem.thtml:47
+msgid "devcp_additem_step2_link"
+msgstr "Hap 2: Hollësi Shtese"
+
+#: views/elements/developers/additem.thtml:48
+msgid "devcp_additem_step3_link"
+msgstr "Hapi 3: Hollësi Versioni"
+
+#: views/elements/developers/additem.thtml:49
+msgid "devcp_additem_step4_link"
+msgstr "Hapi 4: Përkthim"
+
+#: views/elements/developers/additem.thtml:50
+msgid "devcp_additem_step5_link"
+msgstr "Hapi 5: Sukses"
+
+#: views/elements/developers/additem.thtml:76
+msgid "devcp_additem_submissionhelp_link"
+msgstr "Ndihmë për Parashtrim"
+
+#: controllers/previews_controller.php:168
+#: controllers/previews_controller.php:277
+msgid "devcp_addon_field_preview_caption_displaytitle"
+msgstr "Foto Paraparjeje"
+
+#: views/developers/addon_status.thtml:177
+msgid "devcp_addon_status_action_activate"
+msgstr "Bëje Aktive"
+
+#: views/developers/addon_status.thtml:178
+msgid "devcp_addon_status_action_activate_description"
+msgstr ""
+"Bëjeni shtesën tuaj aktive që të shfaqet në lista publike dhe aktivizoni "
+"shërbimin e kontrollit për përditësime."
+
+#: views/developers/addon_status.thtml:135
+msgid "devcp_addon_status_action_complete"
+msgstr "Plotësojeni Shtesën"
+
+#: views/developers/addon_status.thtml:136
+msgid "devcp_addon_status_action_complete_description"
+msgstr "Plotësoni shtesën tuaj dhe kalojeni në Bankoprovë"
+
+#: views/developers/addon_status.thtml:181
+msgid "devcp_addon_status_action_deactivate"
+msgstr "Bëje Joaktive"
+
+#: views/developers/addon_status.thtml:182
+msgid "devcp_addon_status_action_deactivate_description"
+msgstr ""
+"Kalojeni shtesën tuaj joaktive që të mos duket në asnjë listë publike dhe "
+"çaktivizoni shërbimin e kontrollit për përditësime."
+
+#: views/developers/addon_status.thtml:143
+msgid "devcp_addon_status_action_move"
+msgstr "Shpjere në Bankoprovë"
+
+#: views/developers/addon_status.thtml:144
+msgid "devcp_addon_status_action_move_description"
+msgstr ""
+"Shpjereni shtesën tuaj prapë te Bankoprova. Ky është veprim që mund të "
+"kthehet mbrapsht."
+
+#: views/developers/addon_status.thtml:139
+msgid "devcp_addon_status_action_nominate"
+msgstr "Propozojeni për Publike"
+
+#: views/developers/addon_status.thtml:140
+msgid "devcp_addon_status_action_nominate_description"
+msgstr "Propozojeni shtesën tuaj të bëhet Publike"
+
+#: views/developers/addon_status.thtml:147
+msgid "devcp_addon_status_action_public"
+msgstr "Bëje Publike"
+
+#: views/developers/addon_status.thtml:148
+msgid "devcp_addon_status_action_public_description"
+msgstr "Bëjeni shtesën tuaj sërish Publike"
+
+#: views/developers/addon_status.thtml:169
+msgid "devcp_addon_status_active"
+msgstr ""
+"Shtesa juaj është <span class=\"inactive-0\">Aktive</span>. Kjo do të thotë "
+"që shtesa juaj duket te tërë listat e passhme për gjendjen e saj si më sipër."
+
+#: views/developers/addon_status.thtml:111
+msgid "devcp_addon_status_completion_disabled"
+msgstr ""
+"Ju lutem përmbushni kriterin më sipër përpara se të plotësoni shtesën tuaj "
+"dhe kalojeni atë te <span class=\"status-1\">Bankoprova</span>."
+
+#: views/developers/addon_status.thtml:108
+msgid "devcp_addon_status_completion_enabled"
+msgstr ""
+"Tani mund të plotësoni shtesën tuaj dhe ta kaloni te <span class=\"status-1"
+"\">Bankoprova</span> duke klikuar butonin më poshtë."
+
+#: views/developers/addon_status.thtml:102
+msgid "devcp_addon_status_criteria_category"
+msgstr "Të paktën u përzgjodh një kategori"
+
+#: views/developers/addon_status.thtml:101
+msgid "devcp_addon_status_criteria_description"
+msgstr "Lypset Përshkrim Shtese"
+
+#: views/developers/addon_status.thtml:99
+msgid "devcp_addon_status_criteria_name"
+msgstr "Lypset Emër Shtese"
+
+#: views/developers/addon_status.thtml:120
+msgid "devcp_addon_status_criteria_prerelease"
+msgstr "Shtesa nuk ka shenjë si paraqarkullim."
+
+#: views/developers/addon_status.thtml:119
+msgid "devcp_addon_status_criteria_preview"
+msgstr "Për zgjerimet dhe temat lypset e pakta një pamje paraparjej."
+
+#: views/developers/addon_status.thtml:100
+msgid "devcp_addon_status_criteria_summary"
+msgstr "Lypset Përmbledhje Shtese"
+
+#. %s is the status in a span, e.g. "<span>_('Public')</span>".
+#: views/developers/addon_status.thtml:58
+msgid "devcp_addon_status_header"
+msgstr "Gjendje Shtese: %s"
+
+#: views/developers/addon_status.thtml:152
+#: views/developers/addon_status.thtml:173
+msgid "devcp_addon_status_header_actions"
+msgstr "Veprime të Mundshme"
+
+#: views/developers/addon_status.thtml:168
+msgid "devcp_addon_status_header_active"
+msgstr "Gjendje Aktive: <span class=\"inactive-0\">Aktive</span>"
+
+#: views/developers/addon_status.thtml:97
+msgid "devcp_addon_status_header_criteria"
+msgstr "Kriter Plotësimi Shtese"
+
+#: views/developers/addon_status.thtml:164
+msgid "devcp_addon_status_header_inactive"
+msgstr "Gjendje Aktive: <span class=\"inactive-1\">Joaktive</span>"
+
+#: views/developers/addon_status.thtml:117
+msgid "devcp_addon_status_header_nomination"
+msgstr "Kriter Propozimi Publik"
+
+#: views/developers/addon_status.thtml:190
+msgid "devcp_addon_status_header_trusted"
+msgstr "Gjendje Besimi: <span class=\"status-4\">E besueshme</span>"
+
+#: views/developers/addon_status.thtml:165
+msgid "devcp_addon_status_inactive"
+msgstr ""
+"Shtesa juaj është <span class=\"inactive-1\">Joaktive</span>. Kjo do të "
+"thotë që shtesa juaj nuk do të shfaqet në ndonjë radhitje, pavarësisht nga "
+"gjendja më sipër. <b>Nuk</b> do t'i ofrohen përditësime përmesh shërbimit të "
+"kontrollit për përditësime."
+
+#: views/developers/addon_status.thtml:128
+msgid "devcp_addon_status_nominate_disabled"
+msgstr ""
+"Ju lutem, plotësoni kriterin më sipër përpara se ta propozoni shtesën tuaj "
+"për ta bërë <span class=\"status-4\">Publike</span>."
+
+#: views/developers/addon_status.thtml:125
+msgid "devcp_addon_status_nominate_enabled"
+msgstr ""
+"Tani mund ta propozoni shtesën tuaj për ta bërë <span class=\"status-4"
+"\">Publike</span> duke klikuar butonin më sipër."
+
+#: views/developers/addon_status.thtml:64
+msgid "devcp_addon_status_public"
+msgstr "Publike"
+
+#: views/developers/addon_status.thtml:63
+msgid "devcp_addon_status_sandbox"
+msgstr "Bankoprovë"
+
+#. %s is an email address.
+#: views/developers/addon_status.thtml:89
+msgid "devcp_addon_status_switch_disabled"
+msgstr ""
+"Shtesa juaj qe <span class=\"status-5\">Çaktivizuar</span> nga një "
+"administrator dhe nuk mund të përdoret. nëse keni ndonjë pyetje, dërgoni një "
+"e-mail te %s."
+
+#: views/developers/addon_status.thtml:67
+msgid "devcp_addon_status_switch_incomplete"
+msgstr ""
+"Shtesa juaj hëpërhë është <span class=\"status-0\">E paplotë</span>. Kjo do "
+"të thotë që shtesa juaj nuk shfaqet në ndonjë vend të \"site\"-it ose te "
+"shërbimi i kontrollit për përditësime. Pasi ajo të plotësojë kriterin më "
+"poshtë, mund të ktheheni te kjo faqe për të plotësuar shtesën tuaj dhe "
+"kaluar te <span class=\"status-1\">Bankoprova</span>."
+
+#. %s is a number, perhaps 42.
+#: views/developers/addon_status.thtml:77
+msgid "devcp_addon_status_switch_nominated"
+msgstr ""
+"Shtesa juaj është e propozuar për t'u bërë <span class=\"status-4\">Publike</"
+"span> dhe është në pritje të shqyrtimit nga një redaktor. Hëpërhë ka %s "
+"shtesa të tjera në radhë për shqyrtim."
+
+#. %s is an email address.
+#: views/developers/addon_status.thtml:81
+msgid "devcp_addon_status_switch_pending"
+msgstr ""
+"Shtesa juaj gjendet në radhë. Kjo nuk duhej të ndodhte. Ju lutem dërgoni te %"
+"s një e-mail me ID-në e shtesës suaj dhe deklaroni këtë gabim."
+
+#: views/developers/addon_status.thtml:85
+msgid "devcp_addon_status_switch_public"
+msgstr ""
+"Shtesa juaj është <span class=\"status-4\">Publike</span>, që do të thotë se "
+"do të shfaqet te tërë listat dhe kërkimet, dhe se mund të shkarkohet pa "
+"kufizime. Për shtesën tuaj po jepen përditësime përmesh shërbimit të "
+"kontrollit për përditësime."
+
+#: views/developers/addon_status.thtml:71
+#: views/developers/addon_status.thtml:75
+msgid "devcp_addon_status_switch_sandbox"
+msgstr ""
+"Shtesa juaj gjendet në <span class=\"status-1\">Bankoprovë</span>, që do të "
+"thotë se do të shfaqet në lista dhe kërkime, por përdoruesit duhet të bëjnë "
+"hyrje para se ta shkarkojnë. <b>Nuk</b> po ofrohen përditësime për të te "
+"shërbimi i kontrollit për përditësime."
+
+#. %s is the add-on name.
+#: views/developers/addon_status_nominate.thtml:43
+#: views/developers/addon_status_confirm.thtml:43
+#: views/developers/addon_status.thtml:43
+msgid "devcp_addon_status_title"
+msgstr "Gjendje e %s"
+
+#: views/developers/addon_status.thtml:191
+msgid "devcp_addon_status_trusted"
+msgstr ""
+"Shtesa juaj është e <span class=\"status-4\">Besuar</span>. Kjo do të thotë "
+"që mund të parashtroni përditësime për shtesën tuaj pa shqyrtim nga "
+"redaktorët."
+
+#: views/developers/dashboard.thtml:68
+msgid "devcp_dashboard_active"
+msgstr "Vepruese"
+
+#. %1$s is the add-on type string
+#. %2$s is Inactive or Active in a <span>
+#. %3$s is the addon's public status (Public, In Sandbox, ...) in a <span>
+#: views/developers/dashboard.thtml:69
+msgid "devcp_dashboard_addontype_status"
+msgstr "%1$s hëpërhë %2$s dhe %3$s"
+
+#: views/developers/dashboard.thtml:67
+msgid "devcp_dashboard_change_status"
+msgstr "Ndryshojini Gjendjen"
+
+#. %s is the addons email address.
+#: views/developers/dashboard.thtml:99
+msgid "devcp_dashboard_disabled_questions"
+msgstr ""
+"Shtesa juaj është çaktivizuar nga një administrator dhe nuk mund të "
+"përdoret. Nëse keni ndonjë pyetje, dërgoni një email te %s."
+
+#. %s is the (localized) add-on status string in a span, e.g. "Disabled"
+#: views/developers/dashboard.thtml:98
+msgid "devcp_dashboard_disabled_status"
+msgstr "Gjendje Shtese: %s"
+
+#: views/developers/dashboard.thtml:43
+msgid "devcp_dashboard_header_main"
+msgstr "Pult Zhvilluesi"
+
+#: views/developers/dashboard.thtml:110
+msgid "devcp_dashboard_header_welcome"
+msgstr "Mirë se vini te Pulti i Zhvilluesit"
+
+#: views/developers/dashboard.thtml:68
+msgid "devcp_dashboard_inactive"
+msgstr "Jovepruese"
+
+#. %s is a date in the _('date') format
+#: views/developers/dashboard.thtml:65
+msgid "devcp_dashboard_last_edited"
+msgstr "Përpunuar së fundmi %s"
+
+#: views/developers/dashboard.thtml:111
+msgid "devcp_dashboard_learn"
+msgstr ""
+"Hëpërhë nuk keni ndonjë shtesë të strehuar te Shtesat Mozilla. Për të mësuar "
+"se funksionon procesi dhe për të parashtruar shtesën tuaj të parë, klikoni "
+"më poshtë te Fillojani."
+
+#: views/developers/dashboard.thtml:112
+msgid "devcp_dashboard_start"
+msgstr "Filloni"
+
+#: views/developers/dashboard.thtml:82
+msgid "devcp_dashboard_versions"
+msgstr "Versione dhe Kartela"
+
+#: views/developers/dashboard.thtml:91
+msgid "devcp_dashboard_versions_new"
+msgstr "Ngarkoni një version të ri"
+
+#. %s is the preview ID number.
+#: controllers/developers_controller.php:1415
+msgid "devcp_delete_previews_error"
+msgstr ""
+"Paraparja %s nuk mund të fshihet prej bazës së të dhënave. Ju lutem "
+"riprovoni."
+
+#. %s is the preview ID number.
+#: controllers/developers_controller.php:1413
+msgid "devcp_delete_previews_success"
+msgstr "Paraparja %s u fshi me sukses."
+
+#: controllers/developers_controller.php:1089
+msgid "devcp_delete_version_priv_error"
+msgstr "Nuk keni të drejta fshirjeje versionesh apo kartelash."
+
+#. %1$s is the count of files, a number
+#. %2$s is a status string like _('Public') or _('Incomplete')
+#: controllers/components/amo.php:549
+msgid "devcp_describe_version_status"
+msgid_plural "devcp_describe_version_status"
+msgstr[0] "%1$s kartelë %2$s"
+msgstr[1] "%1$s kartela %2$s "
+
+#. %s is a version number. Example: 3.0
+#: views/developers/versions.thtml:65
+#, php-format
+msgid "devcp_details_version"
+msgstr "Version %s"
+
+#: views/developers/discuss.thtml:68
+msgid "devcp_discuss_addreply_header"
+msgstr "Shtoni Përgjigje"
+
+#: views/developers/discuss.thtml:57
+msgid "devcp_discuss_allreplies_header"
+msgstr "Përgjigje"
+
+#. notice when an error occurs saving a discussion reply
+#. %1 is the email address (linked) for the amo-editors list
+#: views/developers/discuss.thtml:70
+msgid "devcp_discuss_error_notice"
+msgstr ""
+"Pati një gabim gjatë ruajtjes së përgjigjes suaj. Ju lutemi lidhuni me %1$s-"
+"n rreth kësaj çështjeje."
+
+#. %1 is the add-on name, %2 is the add-on's version number currently being reviewed by an editor
+#: views/developers/discuss.thtml:46
+msgid "devcp_discuss_intro"
+msgstr ""
+"Një redaktor Shtesash Mozilla ka kërkuar më tepër të dhëna nga ju lidhur me "
+"versionin %2$s të shtesës suaj %1$s."
+
+#. %1 is the add-on name
+#: views/developers/discuss.thtml:43
+msgid "devcp_discuss_pagetitle"
+msgstr "Jepni Më Tepër të Dhëna për Shqyrtim Shtese të %1$s"
+
+#. submit button text
+#: views/developers/discuss.thtml:79
+msgid "devcp_discuss_submit_reply"
+msgstr "Parashtrojeni Përgjigjen"
+
+#: views/developers/discuss.thtml:72
+msgid "devcp_discuss_success_message"
+msgstr ""
+"Përgjigja juaj u ruajt me sukses. Pjesëmarrësit e tjerë në diskutim do të "
+"njoftohen me email."
+
+#. in an author/editor discussion about an add-on to be reviewed:
+#. %1 is the commenter's user name (linked).
+#. %2 is the full date the comment was made.
+#: views/developers/discuss.thtml:52 views/developers/discuss.thtml:62
+msgid "devcp_discuss_writtenby"
+msgstr "shkruajtur nga %1$s më %2$s"
+
+#: views/developers/addon_edit_authors.thtml:72
+#: views/developers/addon_edit_authors.thtml:81
+msgid "devcp_edit_authors_add_author"
+msgstr "Shtoni Autor të Ri"
+
+#: views/developers/addon_edit_authors.thtml:96
+msgid "devcp_edit_authors_add_author_button"
+msgstr "Shtoni Autor"
+
+#: views/developers/addon_edit_authors.thtml:83
+msgid "devcp_edit_authors_add_email"
+msgstr "Email-i i Llogarisë së Autorit:"
+
+#: views/developers/addon_edit_authors.thtml:98
+msgid "devcp_edit_authors_add_loading"
+msgstr "Po kontrollohet email-i i llogarisë..."
+
+#: views/developers/addon_edit_authors.thtml:70
+msgid "devcp_edit_authors_click_save"
+msgstr "Klikoni butonin Përditëso Autorët më poshtë për ta ruajtur."
+
+#: views/developers/addon_edit_authors.thtml:58
+msgid "devcp_edit_authors_header_current"
+msgstr " Autorët e Tanishëm"
+
+#: views/developers/addon_edit_authors.thtml:50
+msgid "devcp_edit_authors_header_manage"
+msgstr "Administroni Autorë Shtese"
+
+#: views/developers/addon_edit_authors.thtml:93
+msgid "devcp_edit_authors_label_add_listed"
+msgstr "Paraqite si autor në faqe publike"
+
+#: views/developers/addon_edit_authors.thtml:89
+msgid "devcp_edit_authors_label_developer"
+msgstr ""
+"<strong>Zhvillues</strong> - Mund të administrojë tërë anët e e procesit të "
+"paraqitjes së shtesës, me përjashtim të shtimit dhe heqjes së autorëve të "
+"tjerë."
+
+#: views/developers/addon_edit_authors.thtml:88
+msgid "devcp_edit_authors_label_owner"
+msgstr ""
+"<strong>Pronar</strong> - Mund të administrojë tërë anët e e procesit të "
+"paraqitjes së shtesës, përfshi shtimin dhe heqjen e autorëve të tjerë."
+
+#: views/developers/addon_edit_authors.thtml:90
+msgid "devcp_edit_authors_label_viewer"
+msgstr ""
+"<strong>Parës</strong> - Mund të shorë lista dhe statistika zhvilluesish "
+"shtesash, por nuk mund të bëjë dot ndonjë ndryshim."
+
+#. Placeholder for the empty option in a <select>.
+#: views/developers/addon_edit_categories.thtml:69
+msgid "devcp_edit_authors_option_empty"
+msgstr "----------------"
+
+#: views/developers/addon_edit_authors.thtml:86
+msgid "devcp_edit_authors_select_role"
+msgstr "Përzgjidhni rol për autorin:"
+
+#. Column name in a table.
+#: views/developers/addon_edit_authors.thtml:62
+msgid "devcp_edit_authors_th_author"
+msgstr "Autor"
+
+#. Column name in a table.
+#: views/developers/addon_edit_authors.thtml:64
+#, fuzzy
+msgid "devcp_edit_authors_th_listed"
+msgstr "Në listë"
+
+#. Column name in a table.
+#: views/developers/addon_edit_authors.thtml:63
+msgid "devcp_edit_authors_th_role"
+msgstr "Rol"
+
+#: views/developers/addon_edit_authors.thtml:77
+msgid "devcp_edit_authors_update_author"
+msgstr "Përditësoni autorët"
+
+#: views/developers/addon_edit_categories.thtml:99
+msgid "devcp_edit_categories_button_update"
+msgstr "Përditësoni Kategoritë"
+
+#: views/developers/addon_edit_categories.thtml:88
+msgid "devcp_edit_categories_does_not_fit"
+msgstr "Shtesa ime nuk hyn në ndonjë nga kategoritë e mundshme."
+
+#. %s is the application name (Firefox, Thunderbird).
+#: views/developers/addon_edit_categories.thtml:61
+msgid "devcp_edit_categories_header_application"
+msgstr "%s Kategori"
+
+#: views/developers/addon_edit_categories.thtml:49
+msgid "devcp_edit_categories_header_manage"
+msgstr "Administroni Kategori Shtese"
+
+#: views/developers/addon_edit_categories.thtml:91
+msgid "devcp_edit_categories_hover"
+msgstr "Kalojeni miun sipër një kategorie që të shihni përshkrimin për të."
+
+#. %s is the category number (1, 2, 3).
+#: views/developers/addon_edit_categories.thtml:67
+msgid "devcp_edit_categories_label_category_num"
+msgstr "Kategori %s"
+
+#: views/developers/addon_edit_categories.thtml:94
+#: views/developers/addon_edit_categories.thtml:103
+msgid "devcp_edit_categories_none_available"
+msgstr "Nuk ka kategori për këtë lloj shtese dhe zbatimi."
+
+#: views/developers/addon_edit_categories.thtml:86
+msgid "devcp_edit_categories_other"
+msgstr ""
+"Vendoseni shtesën tuaj në këtë kategori vetëm nëse nuk hyn në ndonjë nga "
+"kategoritë e deritanishme."
+
+#. %s is the application name (Firefox, Thunderbird).
+#: views/developers/addon_edit_categories.thtml:63
+msgid "devcp_edit_categories_select_application_categories"
+msgstr "Përzgjidhni për shtesën tuaj deri në tre kategori %s-i"
+
+#: views/developers/addon_edit.thtml:47
+msgid "devcp_edit_dd_manage_authors"
+msgstr "Shtoni ose hiqni përdorues të cilët mund të administrojnë këtë shtesë."
+
+#: views/developers/addon_edit.thtml:49
+msgid "devcp_edit_dd_manage_categories"
+msgstr ""
+"Përzgjidhni kategoritë e afërta për secilin zbatim të mbuluar nga shtesa "
+"juaj."
+
+#: views/developers/addon_edit.thtml:51
+msgid "devcp_edit_dd_manage_description"
+msgstr ""
+"Shtoni dhe ndryshoni përkthime për përmbledhjen, përshkrimin, lejen e "
+"përdoruesit dhe rregullat e vetësisë të shtesës suaj."
+
+#: views/developers/addon_edit.thtml:53
+msgid "devcp_edit_dd_manage_properties"
+msgstr ""
+"Ndryshoni emrin e shtesës suaj, faqen hyrëse për të, ikonën, dhe të tjerë "
+"elementë."
+
+#: views/developers/addon_edit_descriptions.thtml:116
+msgid "devcp_edit_description_button_update"
+msgstr "Përditësoni Përshkrime"
+
+#: views/developers/addon_edit_descriptions.thtml:115
+msgid "devcp_edit_description_correct_error"
+msgstr "Ju lutem ndreqni gabimet e treguara më sipër me të kuqe."
+
+#: views/developers/addon_edit_descriptions.thtml:51
+msgid "devcp_edit_descriptions_header"
+msgstr "Përpunoni Përshkrime Shtese"
+
+#: views/developers/addon_edit_descriptions.thtml:94
+msgid "devcp_edit_descriptions_transbox_comments_description"
+msgstr ""
+"Çfarëdo të dhënash që përdoruesit mund të duan të dinë dhe që s'janë "
+"domosdoshmërisht të përshtatshme për përmbledhjen apo përshkrimin e shtesës. "
+"Raste të rëndomtë përfshijnë paraqitje të metash të rëndësishme, të dhëna "
+"rreth se si të njoftohen të meta për të, datë paraprake e hedhjes në "
+"qarkullim të një versioni të ri, etj."
+
+#: views/developers/addon_edit_descriptions.thtml:93
+msgid "devcp_edit_descriptions_transbox_comments_name"
+msgstr "Komente Zhvilluesi"
+
+#: views/developers/addon_edit_descriptions.thtml:86
+msgid "devcp_edit_descriptions_transbox_description_description"
+msgstr ""
+"Përshkrimi i shtesës suaj është një shpjegim pakëz më i shtjelluar i "
+"veçorive të saj, punimit, dhe të tjera të dhëna me rëndësi. Shfaqet nën "
+"përmbledhjen, te faqja e paraqitjes së shtesës."
+
+#: views/developers/addon_edit_descriptions.thtml:85
+msgid "devcp_edit_descriptions_transbox_description_name"
+msgstr "Përshkrim Shtese"
+
+#: views/developers/addon_edit_descriptions.thtml:103
+msgid "devcp_edit_descriptions_transbox_eula_description"
+msgstr ""
+"Nëse shtesa juaj ka një Marrëveshje Lejeje Përdoruesi (EULA), ju lutem "
+"jepeni tekstin e saj më poshtë. Po qe se më poshtë caktohet kështu, "
+"përdoruesve do t'u kërkohet të pajtohen me të, përpara se të mund të "
+"instalojnë shtesën tuaj. Ju lutem mbani shënim që kjo EULA nuk është njëlloj "
+"si lejet për kod, bie fjala GPL apo MPL."
+
+#: views/developers/addon_edit_descriptions.thtml:102
+msgid "devcp_edit_descriptions_transbox_eula_name"
+msgstr "Marrëveshje Leje Përdoruesi (EULA)"
+
+#: views/developers/addon_edit_descriptions.thtml:112
+msgid "devcp_edit_descriptions_transbox_privacy_description"
+msgstr ""
+"Po qe se shtesa juaj ka rregulla vetësie, jepeni tekstin e tyre këtu. Faqja "
+"e paraqitjes së shtesës suaj do të shfaqë një lidhje për te rregullat."
+
+#: views/developers/addon_edit_descriptions.thtml:111
+msgid "devcp_edit_descriptions_transbox_privacy_name"
+msgstr "Rregulla Vetësie"
+
+#: views/developers/addon_edit_descriptions.thtml:78
+msgid "devcp_edit_descriptions_transbox_summary_description"
+msgstr ""
+"Përmbledhja është një shpjegim i shkurtër i funksioneve bazë të shtesës suaj "
+"e që shfaqet në lista kërkimi dhe shfletimi, si edhe në krye të faqes së "
+"paraqitjes së shtesës suaj. <strong>E shumta 250 gërma.</strong>"
+
+#: views/developers/addon_edit_descriptions.thtml:77
+msgid "devcp_edit_descriptions_transbox_summary_name"
+msgstr "Përmbledhje Shtese"
+
+#: views/developers/addon_edit.thtml:46
+msgid "devcp_edit_dt_manage_authors"
+msgstr "Administroni Autorë Shtesash"
+
+#: views/developers/addon_edit.thtml:48
+msgid "devcp_edit_dt_manage_categories"
+msgstr "Administroni Kategori Shtesash"
+
+#: views/developers/addon_edit.thtml:50
+msgid "devcp_edit_dt_manage_descriptions"
+msgstr "Administroni Përshkrime Shtesash"
+
+#: views/developers/addon_edit.thtml:52
+msgid "devcp_edit_dt_manage_properties"
+msgstr "Administroni Veti Shtesash"
+
+#: views/developers/addon_edit_properties.thtml:170
+msgid "devcp_edit_label_externalsoftware"
+msgstr "Kjo shtesë lyp \"software\" të jashtëm"
+
+#: views/developers/addon_edit_properties.thtml:205
+msgid "devcp_edit_label_locale_disambiguation"
+msgstr "Të Dhëna Shtesë për Vendoren"
+
+#: views/developers/addon_edit_properties.thtml:168
+msgid "devcp_edit_label_prerelease"
+msgstr "Ky është paraqarkullim"
+
+#: views/developers/addon_edit_properties.thtml:169
+msgid "devcp_edit_label_sitespecific"
+msgstr "Kjo është një shtesë e lidhur me një \"site\" të caktuar"
+
+#: views/developers/addon_edit_properties.thtml:202
+msgid "devcp_edit_label_target_locale"
+msgstr "Vendore Objektiv"
+
+#: views/developers/addon_edit_properties.thtml:212
+msgid "devcp_edit_properties_button_update"
+msgstr "Përditësoni Vetitë"
+
+#: views/developers/addon_edit_properties.thtml:198
+msgid "devcp_edit_properties_change_guid"
+msgstr "Ndryshojeni vetëm nëse i kuptoni tërë pasojat."
+
+#: views/developers/addon_edit_properties.thtml:109
+msgid "devcp_edit_properties_current_icon"
+msgstr "Ikonë e Tanishme"
+
+#: views/developers/addon_edit_properties.thtml:85
+msgid "devcp_edit_properties_default_locale"
+msgstr ""
+"Në këtë \"site\" web, të dhënat mbi shtesën tuaj shfaqen në vendoren "
+"parazgjedhje, po qe se nuk e anashkaloni me një përkthim në një vendore të "
+"dhënë."
+
+#: views/developers/addon_edit_properties.thtml:167
+msgid "devcp_edit_properties_flags"
+msgstr "Këta filtra përdoren për të filtruar dhe kategorizuar shtesat."
+
+#: views/developers/addon_edit_properties.thtml:174
+msgid "devcp_edit_properties_guid"
+msgstr ""
+"GUID-ja e shtesës suaj caktohet te install.rdf-ja përkatëse dhe e "
+"identifikon atë në mënyrë unike. GUID-në nuk mund ta ndryshoni më dot pasi "
+"shtesa të jetë paraqitur te Shtesat Mozilla."
+
+#: views/developers/addon_edit_properties.thtml:53
+msgid "devcp_edit_properties_header"
+msgstr "Përpunoni Veti Shtese"
+
+#: views/developers/addon_edit_properties.thtml:186
+msgid "devcp_edit_properties_header_addon_type"
+msgstr "Lloj Shtese"
+
+#: views/developers/addon_edit_properties.thtml:181
+msgid "devcp_edit_properties_header_admin_settings"
+msgstr "Rregullime Administratori"
+
+#: views/developers/addon_edit_properties.thtml:84
+msgid "devcp_edit_properties_header_default_locale"
+msgstr "Gjuhë Parazgjedhje"
+
+#: views/developers/addon_edit_properties.thtml:166
+msgid "devcp_edit_properties_header_flags"
+msgstr "Flamurka Shtese"
+
+#: views/developers/addon_edit_properties.thtml:173
+#: views/developers/addon_edit_properties.thtml:197
+msgid "devcp_edit_properties_header_guid"
+msgstr "GUID Shtese"
+
+#: views/developers/addon_edit_properties.thtml:104
+msgid "devcp_edit_properties_header_icon"
+msgstr "Ikonë Shtese"
+
+#: views/developers/addon_edit_properties.thtml:159
+msgid "devcp_edit_properties_header_other_settings"
+msgstr "Rregullime të Tjera"
+
+#. A header on the admin page to toggle trusted status.
+#: views/developers/addon_edit_properties.thtml:182
+msgid "devcp_edit_properties_header_trusted"
+msgstr "Shtesë e Besuar?"
+
+#: views/developers/addon_edit_properties.thtml:160
+msgid "devcp_edit_properties_header_view_source"
+msgstr "Shihini Burimin \"Online\""
+
+#. %s is a comma-separated list of image extensions ".png, .jpg"
+#: views/developers/addon_edit_properties.thtml:106
+msgid "devcp_edit_properties_icon"
+msgstr ""
+"Ikona e një shtese është një pamje e vockël që shfaqet përbri emrit të "
+"shtesës suaj në përfundime kërkimi dhe shfletimi të tyre, faqe paraqitjeje, "
+"dhe te dialogu i instalimit të shtesës. Pamja do të ripërmasohet vetvetiu në "
+"32 x 32 piksela. Ju lutem përdorni një nga llojet vijuese të pamjeve: %s"
+
+#: views/developers/addon_edit_properties.thtml:171
+msgid "devcp_edit_properties_label_binary"
+msgstr "Kjo shtesë përmban përbërësa dyorë"
+
+#: views/developers/addon_edit_properties.thtml:185
+msgid "devcp_edit_properties_label_not_trusted"
+msgstr "Jo e Besuar"
+
+#: views/developers/addon_edit_properties.thtml:184
+msgid "devcp_edit_properties_label_trusted"
+msgstr "E besuar"
+
+#: views/developers/addon_edit_properties.thtml:110
+msgid "devcp_edit_properties_new_icon"
+msgstr "Ikonë e Re"
+
+#: views/developers/addon_edit_properties.thtml:118
+msgid "devcp_edit_properties_remove_icon"
+msgstr "Hiqe Ikonën"
+
+#: views/developers/addon_edit_properties.thtml:136
+msgid "devcp_edit_properties_transbox_homepage_description"
+msgstr ""
+"Po qe se shtesa juaj ka një tjetër faqe hyrëse, jepeni këtu vendndodhjen e "
+"saj. Shtimi i përkthimeve të tjera nuk është i nevojshëm, po qe se \"site\"-"
+"i juaj web nuk është përkthyer në gjuhë të tjera."
+
+#: views/developers/addon_edit_properties.thtml:135
+msgid "devcp_edit_properties_transbox_homepage_name"
+msgstr "Faqe Hyrëse e Shtesës"
+
+#: views/developers/addon_edit_properties.thtml:79
+msgid "devcp_edit_properties_transbox_name_description"
+msgstr "Emri i shtesës suaj shfaqet kudo ku paraqitet shtesa juaj."
+
+#: views/developers/addon_edit_properties.thtml:78
+msgid "devcp_edit_properties_transbox_name_name"
+msgstr "Emër Shtese"
+
+#: views/developers/addon_edit_properties.thtml:145
+msgid "devcp_edit_properties_transbox_supportemail_description"
+msgstr ""
+"Po qe se keni një vendndodhje email për kërkesa asistence, jepeni këtu. "
+"Shtimi i përkthimeve të tjera nuk është i nevojshëm, po qe se nuk keni "
+"vendndodhje email të ndryshme për gjuhë të ndryshme."
+
+#: views/developers/addon_edit_properties.thtml:144
+msgid "devcp_edit_properties_transbox_supportemail_name"
+msgstr "Vendndodhje Email për Asistencë"
+
+#: views/developers/addon_edit_properties.thtml:154
+msgid "devcp_edit_properties_transbox_supporturl_description"
+msgstr ""
+"Po qe se shtesa juaj ka një \"site\" web ose forum asistence, jepini këtu "
+"vendndodhjen e tyre. Shtimi i përkthimeve të tjera nuk është i nevojshëm, po "
+"qe se \"site\"-i juaj web nuk është përkthyer në gjuhë të tjera."
+
+#: views/developers/addon_edit_properties.thtml:153
+msgid "devcp_edit_properties_transbox_supporturl_name"
+msgstr "Site Web Asistence"
+
+#: views/developers/addon_edit_properties.thtml:183
+msgid "devcp_edit_properties_trusted"
+msgstr "Shtesat e besuara mund të bëhen publike pa shqyrtim Redaktori."
+
+#. %s is href="..." and should stay in the <a> tag.
+#: views/developers/addon_edit_properties.thtml:119
+msgid "devcp_edit_properties_undelete"
+msgstr "Ikona do të fshihet me ruajtjen. <a %s>Të anulohet?</a>"
+
+#: views/developers/addon_edit_properties.thtml:161
+msgid "devcp_edit_properties_view_source"
+msgstr ""
+"Burimi i kartelave të shtesës suaj mund të shihet \"online\" nga cilido "
+"përdorues që ka bërë hyrjen, nëse doni."
+
+#: views/developers/addon_edit_properties.thtml:162
+msgid "devcp_edit_properties_view_source_allow"
+msgstr "Lejo parje burimi \"online\""
+
+#: views/developers/addon_edit_properties.thtml:163
+msgid "devcp_edit_properties_view_source_do_not_allow"
+msgstr "Mos lejo parje burimi \"online\""
+
+#: views/elements/developers/editbox.thtml:46
+msgid "devcp_editbox_authors"
+msgstr "Autorë"
+
+#: views/elements/developers/editbox.thtml:47
+msgid "devcp_editbox_categories"
+msgstr "Kategori"
+
+#: views/elements/developers/editbox.thtml:52
+msgid "devcp_editbox_change_status"
+msgstr "Ndryshoji Gjendjen"
+
+#: views/elements/developers/editbox.thtml:48
+msgid "devcp_editbox_descriptions"
+msgstr "Përshkrime"
+
+#: views/elements/developers/editbox.thtml:43
+msgid "devcp_editbox_edit_addon"
+msgstr "Përpunoni Shtesën"
+
+#: views/elements/developers/editbox.thtml:57
+msgid "devcp_editbox_new_version"
+msgstr "Version i Ri"
+
+#: views/elements/developers/editbox.thtml:49
+msgid "devcp_editbox_properties"
+msgstr "Veti"
+
+#: views/elements/developers/editbox.thtml:60
+msgid "devcp_editbox_screenshots"
+msgstr "Paraparje Fotosh Ekrani"
+
+#: views/elements/developers/editbox.thtml:53
+msgid "devcp_editbox_statistics_dashboard"
+msgstr "Pult Statistikash"
+
+#: views/elements/developers/editbox.thtml:54
+msgid "devcp_editbox_versions"
+msgstr "Versione dhe Kartela"
+
+#: views/elements/developers/editbox.thtml:42
+#, fuzzy
+msgid "devcp_editbox_view_listing"
+msgstr "Shihni Listën"
+
+#: views/elements/developers/editorsmenu.thtml:59
+msgid "devcp_editorsqueue_featured"
+msgstr "Shtesa të Trajtuara"
+
+#. %1 is the review count
+#: views/elements/developers/editorsqueue.thtml:42
+#: views/elements/developers/editorsmenu.thtml:56
+#, php-format
+msgid "devcp_editorsqueue_moderatedreviews"
+msgid_plural "devcp_editorsqueue_moderatedreviews"
+msgstr[0] "Shqyrtim i Miratuar (%s)"
+msgstr[1] "Shqyrtime të Miratuara (%s)"
+
+#. %1 is the nominated addons count
+#: views/elements/developers/editorsqueue.thtml:44
+#: views/elements/developers/editorsmenu.thtml:58
+#, php-format
+msgid "devcp_editorsqueue_nominated"
+msgid_plural "devcp_editorsqueue_nominated"
+msgstr[0] "Shtesë e Propozuar (%s)"
+msgstr[1] "Shtesa të Propozuara (%s)"
+
+#. %1 is the update count
+#: views/elements/developers/editorsqueue.thtml:43
+#: views/elements/developers/editorsmenu.thtml:57
+#, php-format
+msgid "devcp_editorsqueue_pendingupdates"
+msgid_plural "devcp_editorsqueue_pendingupdates"
+msgstr[0] "Përditësim në radhë (%s)"
+msgstr[1] "Përditësime në Radhë (%s)"
+
+#: controllers/statistics_controller.php:147
+#: controllers/statistics_controller.php:361
+#: controllers/previews_controller.php:108
+#: controllers/previews_controller.php:211
+#: controllers/previews_controller.php:312
+msgid "devcp_error_addon_access_denied"
+msgstr "Nuk keni hyrje tek kjo shtesë."
+
+#. %s is a complete URL with the text from devcp_error_appversion_reference_link_text
+#. in the <a> tag. This should be fixed.
+#: controllers/components/developers.php:591
+#, php-format
+msgid "devcp_error_appversion_reference_link"
+msgstr "Ju lutem shihni %s për të dhëna."
+
+#. This is the link text in the <a> for devcp_error_appversion_reference_link. This
+#. should be fixed.
+#: controllers/components/developers.php:591
+msgid "devcp_error_appversion_reference_link_text"
+msgstr "këtë faqe"
+
+#: views/developers/addon_edit_authors.thtml:76
+msgid "devcp_error_empty_authors"
+msgstr "Shtesa juaj duhet të ketë të paktën një pronar."
+
+#. %1$s is the name of the file
+#: controllers/components/developers.php:658
+msgid "devcp_error_file_exists"
+msgstr ""
+"Ka tashmë një version të kësaj shtese. Për ta zëvendësuar, duhet së pari të "
+"fshini kartelën %1$s."
+
+#. %1$s is a file extension. Example: .exe
+#. %2$s is a comma separated list of extensions. Example: .xpi, .jar
+#: controllers/components/developers.php:355
+#, php-format
+msgid "devcp_error_file_extension"
+msgstr ""
+"Kjo prapashtesë kartele (%s) nuk lejohet për llojin e përzgjedhur të "
+"shtesës. Ju lutem përdorni një nga vijueset: %s"
+
+#: controllers/components/developers.php:64
+msgid "devcp_error_five_categories"
+msgstr "Ju lutem mos përzgjidhni më shumë se pesë kategori."
+
+#: controllers/components/developers.php:526
+msgid "devcp_error_guid_application"
+msgstr "ID-ja e kësaj shtese është në përdorim tashmë nga një zbatim."
+
+#: controllers/components/developers.php:337
+#: controllers/components/developers.php:389
+msgid "devcp_error_http_incomplete"
+msgstr "Shpërngulje jo e plotë"
+
+#: controllers/components/developers.php:335
+#: controllers/components/developers.php:336
+#: controllers/components/developers.php:387
+#: controllers/components/developers.php:388
+msgid "devcp_error_http_maxupload"
+msgstr "Tejkalon madhësinë maksimum për ngarkimet"
+
+#: controllers/components/developers.php:338
+#: controllers/components/developers.php:390
+msgid "devcp_error_http_nofile"
+msgstr "Nuk u ngarkua kartelë"
+
+#. %1$s is a file extension. Example: .exe
+#. %2$s is a comma separated list of extensions. Example: .xpi, .jar
+#: controllers/components/developers.php:401
+#, php-format
+msgid "devcp_error_icon_extension"
+msgstr ""
+"Kjo prapashtesë kartele (%s) nuk lejohet për një ikonë. Ju lutem përdorni "
+"një nga vijueset: %s"
+
+#: controllers/developers_controller.php:504
+msgid "devcp_error_index_rdf_notfound"
+msgstr "Pa install.rdf të pranishme."
+
+#: controllers/components/developers.php:601
+msgid "devcp_error_install_manifest"
+msgstr "U gjetën gabimet vijues te install.rdf:"
+
+#: controllers/developers_controller.php:1463
+msgid "devcp_error_invalid_addontype"
+msgstr ""
+
+#. %$1s is a version. Example: 3.1.1
+#. %$2s is an add-on name.
+#: controllers/components/developers.php:569
+#: controllers/components/developers.php:581
+#, php-format
+msgid "devcp_error_invalid_appversion"
+msgstr "%s nuk është version i vlefshëm për %s"
+
+#. %s is a string
+#: controllers/components/developers.php:521
+#, php-format
+msgid "devcp_error_invalid_guid"
+msgstr "ID-ja e kësaj shtese është e pavlefshme: %s"
+
+#. %$1s is a version. Example: 3.1.1
+#. %$2s is an add-on name.
+#: controllers/components/developers.php:572
+#, php-format
+msgid "devcp_error_invalid_minversion"
+msgstr ""
+"%s nuk është version i vlefshëm për %s: versionet më të vegjël nuk mund të "
+"përmbajnë *"
+
+#: controllers/components/developers.php:536
+msgid "devcp_error_invalid_version"
+msgstr ""
+"Versioni i kësaj shtese është i pavlefshëm: ju lutem shihni <a href=\"http://"
+"developer.mozilla.org/en/docs/Toolkit_version_format\">përcaktimet "
+"përkatëse</a>"
+
+#: controllers/components/developers.php:531
+msgid "devcp_error_invalid_version_spaces"
+msgstr ""
+"Versioni i kësaj shtese është i pavlefshëm: versionet nuk mund të përmbajnë "
+"hapësira."
+
+#. %s is an error message from the parser.
+#: controllers/components/developers.php:501
+#, php-format
+msgid "devcp_error_manifest_parse"
+msgstr "Ndodhi gabimi vijues gjatë përtypjes së install.rdf: %s"
+
+#: controllers/components/developers.php:373
+msgid "devcp_error_move_file"
+msgstr "Nuk lëviza dot kartelën"
+
+#. %s is the name of a file
+#: controllers/components/developers.php:650
+#: controllers/components/developers.php:662
+#: controllers/components/developers.php:667
+#: controllers/components/developers.php:727
+#: controllers/components/developers.php:738
+#: controllers/components/developers.php:743
+#, php-format
+msgid "devcp_error_moving_file"
+msgstr "Ndodhi një gabim gjatë lëvizjes së %s."
+
+#: controllers/components/developers.php:595
+msgid "devcp_error_mozilla_application"
+msgstr "Duhet të keni e pakta një zbatim të vlefshëm Mozilla si objekt."
+
+#: controllers/components/developers.php:516
+msgid "devcp_error_no_guid"
+msgstr "Nuk u gjet dot ID për këtë shtesë tek install.rdf."
+
+#: controllers/components/developers.php:287
+msgid "devcp_error_no_platform"
+msgstr "Nuk u përzgjodh platformë"
+
+#: controllers/components/developers.php:59
+msgid "devcp_error_one_category"
+msgstr "Ju lutem përzgjidhni të paktën një kategori."
+
+#: controllers/components/developers.php:92
+msgid "devcp_error_one_user"
+msgstr "Duhet të ketë të paktën një autor për këtë shtesë."
+
+#. %1$s is a file extension. Example: .exe
+#. %2$s is a comma separated list of extensions. Example: .xpi, .jar
+#: controllers/components/developers.php:1081
+#, php-format
+msgid "devcp_error_preview_extension"
+msgstr ""
+"Kjo prapashtesë kartelash (%s) nuk lejohet për paraparjet. Ju lutem përdorni "
+"një nga vijueset: %s"
+
+#: controllers/components/developers.php:511
+msgid "devcp_error_updatekey"
+msgstr ""
+"Shtesat nuk mund të përdorin Kyç të përditësuar. Ju lutem hiqeni atë prej "
+"install.rdf dhe riprovoni."
+
+#: controllers/components/developers.php:506
+msgid "devcp_error_updateurl"
+msgstr ""
+"Shtesat nuk mund të përdorin një updateURL të jashtme. Ju lutem hiqeni këtë "
+"prej install.rdf dhe riprovoni."
+
+#: controllers/developers_controller.php:465
+#: controllers/components/developers.php:271
+msgid "devcp_error_upload_file"
+msgstr "Ju lutem ngarkoni një kartelë."
+
+#: views/developers/uploader.thtml:135
+msgid "devcp_input_upload_file"
+msgstr "Ngarkoni Kartelë"
+
+#: views/pages/js_constants.js.thtml:89
+msgid "devcp_js_a_cancel"
+msgstr "Anuloje"
+
+#: views/pages/js_constants.js.thtml:90
+msgid "devcp_js_add_email"
+msgstr "Ju lutem jepni llogarinë email të autorit që doni të shtohet."
+
+#. alt text for a down-arrow image.
+#: views/pages/js_constants.js.thtml:81
+msgid "devcp_js_img_move_down"
+msgstr "Zbrite"
+
+#. alt text for an up-arrow image.
+#: views/pages/js_constants.js.thtml:82
+msgid "devcp_js_img_move_up"
+msgstr "Ngjite"
+
+#: views/pages/js_constants.js.thtml:91
+msgid "devcp_js_img_remove_compat"
+msgstr "Hiq Përputhshmëri Zbatimi"
+
+#: views/pages/js_constants.js.thtml:86
+msgid "devcp_js_input_list_author"
+msgstr "Shfaqe si autor në lista publike"
+
+#: views/pages/js_constants.js.thtml:92
+#, fuzzy
+msgid "devcp_js_license_select"
+msgstr "Please select a license."
+
+#: views/pages/js_constants.js.thtml:93
+#, fuzzy
+msgid "devcp_js_license_text"
+msgstr "Please enter text for your license."
+
+#. <option> text in a <select> for Author role in an add-on.
+#: views/pages/js_constants.js.thtml:84
+msgid "devcp_js_option_developer"
+msgstr "Zhvillues"
+
+#. <option> text in a <select> for Author role in an add-on.
+#: views/pages/js_constants.js.thtml:83
+msgid "devcp_js_option_owner"
+msgstr "Pronar"
+
+#. <option> text in a <select> for Author role in an add-on.
+#: views/pages/js_constants.js.thtml:85
+msgid "devcp_js_option_viewer"
+msgstr "Parës"
+
+#: views/pages/js_constants.js.thtml:88
+msgid "devcp_js_remove_author"
+msgstr "Hiqe Autorin"
+
+#: views/pages/js_constants.js.thtml:87
+msgid "devcp_js_sure_remove"
+msgstr "Jeni <strong>i sigurt</strong> se doni të hiqet ky autor?"
+
+#: views/pages/js_constants.js.thtml:77
+msgid "devcp_js_upload_alert"
+msgstr "Duhet të përzgjidhni një kartelë për ngarkim."
+
+#. %1$s is an addon id, like 32.
+#. %2$s is a version number, like 3.5.
+#: controllers/components/developers.php:1212
+#, fuzzy
+msgid "devcp_license_existing"
+msgstr "Custom license for add-on %1$s v%2$s"
+
+#: views/elements/developers/localebox.thtml:44
+msgid "devcp_localebox_header_localizedfields"
+msgstr "Pjesë të Përkthyera"
+
+#. %1 is the default locale
+#: views/elements/developers/localebox.thtml:48
+#, php-format
+msgid "devcp_localebox_intro"
+msgstr ""
+"Disa prej pjesëve në këtë faqe janë përkthyer për t'u shfaqur në gjuhën "
+"amëtare të përdoruesit. Përzgjidhni më poshtë një vendore për të përpunuar "
+"në atë gjuhë hollësitë e shtesës suaj. Nëse përkthimi për një vendore nuk "
+"është ende gati, do të kalohet vetiu te vendorja e përzgjedhur si "
+"parazgjedhje (%s)."
+
+#: views/elements/developers/sidebar.thtml:68
+#: views/elements/developers/myaddons.thtml:75
+msgid "devcp_myaddons_admincp_link"
+msgstr "Mjete për Administratorë"
+
+#: views/elements/developers/sidebar.thtml:65
+#: views/elements/developers/myaddons.thtml:72
+msgid "devcp_myaddons_editorcp_link"
+msgstr "Mjete për Komentatorë"
+
+#: views/elements/developers/myaddons.thtml:52
+msgid "devcp_myaddons_link"
+msgstr "Shtesat e Mia"
+
+#: views/elements/developers/sidebar.thtml:70
+#: views/elements/developers/myaddons.thtml:77
+msgid "devcp_myaddons_mainpage_link"
+msgstr "Prapa te Kryesorja"
+
+#: views/elements/developers/sidebar.thtml:63
+#: views/elements/developers/myaddons.thtml:70
+msgid "devcp_myaddons_statistics_link"
+msgstr "Pult Statistikash"
+
+#: views/elements/developers/sidebar.thtml:62
+#: views/elements/developers/myaddons.thtml:69
+msgid "devcp_myaddons_submitaddon_link"
+msgstr "Parashtroni Shtesë"
+
+#: views/elements/developers/sidebar.thtml:48
+#: views/elements/developers/myaddons.thtml:67
+msgid "devcp_myaddons_title"
+msgstr "Mjete Zhvilluesi"
+
+#. %1$s is an add-on ID, perhaps 167.
+#. %2$s is a URL.
+#: controllers/developers_controller.php:256
+msgid "devcp_new_addon_error"
+msgstr ""
+"Kjo ID shtese (%1$s) gjendet tashmë në bazën e të dhënave. Po qe se kjo "
+"është shtesë e juaja, mund të <a href=\"%2$s\">ngarkoni versionin e ri</a>."
+
+#: views/developers/addon_status_nominate.thtml:62
+msgid "devcp_nominate_cancel"
+msgstr "Anuloje dhe kthehu"
+
+#. %1 is the add-on name
+#: views/developers/addon_status_nominate.thtml:61
+#, php-format
+msgid "devcp_nominate_submit_nominate"
+msgstr "Propozoni %s"
+
+#: views/developers/addon_edit_properties.thtml:50
+#: views/developers/addon_status.thtml:49
+#: views/developers/versions_edit.thtml:50
+msgid "devcp_notice_changes_error"
+msgstr ""
+"<span>Një ose më shumë prej ndryshimeve tuaja nuk u ruajtën dot.</span><br /"
+">Ju lutem shihni më poshtë për gabime. Pjesa tjetër e ndryshimeve tuaja u "
+"ruajt me sukses."
+
+#: views/developers/addon_edit_authors.thtml:47
+#: views/developers/addon_edit_properties.thtml:47
+#: views/developers/addon_status.thtml:46
+#: views/developers/addon_edit_descriptions.thtml:47
+#: views/developers/versions_edit.thtml:47
+#: views/developers/addon_edit_categories.thtml:46
+msgid "devcp_notice_changes_saved"
+msgstr ""
+"<span>Ndryshimet tuaja u ruajtën.</span><br />Ju lutem mbani parasysh që "
+"disa ndryshime mund të duan disa orë që të duken në të tëra zoant e \"site\"-"
+"it web."
+
+#: controllers/previews_controller.php:252
+msgid "devcp_notice_cleardefault"
+msgstr ""
+"Heqja e kësaj si paraparje parazgjedhje do të bëjë që një tjetër paraparje "
+"të bëhet vetvetiu paraparja parazgjedhje."
+
+#: controllers/previews_controller.php:184
+#: controllers/previews_controller.php:251
+msgid "devcp_notice_makedefault"
+msgstr ""
+"Kalimi i kësaj si paraparje parazgjedhje do të heqë gjendjen parazgjedhje "
+"nga paraparja parazgjedhje e çastit."
+
+#: views/developers/addon_edit_authors.thtml:70
+msgid "devcp_notice_unsaved_changes"
+msgstr "Keni ndryshime të paruajtura."
+
+#: controllers/developers_controller.php:87
+#: controllers/developers_controller.php:97
+#: controllers/developers_controller.php:100
+#: controllers/previews_controller.php:67
+#: controllers/previews_controller.php:79
+#: controllers/previews_controller.php:82
+msgid "devcp_pagetitle"
+msgstr "Mjete për Zhvilluesa"
+
+#: controllers/previews_controller.php:103
+#: controllers/previews_controller.php:104
+msgid "devcp_preview_add_pagetitle"
+msgstr "Shto Paraparje"
+
+#: controllers/previews_controller.php:135
+msgid "devcp_preview_added_successfully"
+msgstr "Paraparja u shtua me sukses."
+
+#: controllers/previews_controller.php:323
+msgid "devcp_preview_deleted_successfully"
+msgstr "Paraparja u fshi me sukses."
+
+#: controllers/previews_controller.php:194
+#: controllers/previews_controller.php:195
+msgid "devcp_preview_edit_pagetitle"
+msgstr "Përpunoni Paraparje"
+
+#: controllers/previews_controller.php:237
+msgid "devcp_preview_updated_successfully"
+msgstr "Paraparja u ngarkua me sukses."
+
+#: views/developers/previews.thtml:120
+msgid "devcp_previews_a_another"
+msgstr "Shtoni një Tjetër Paraprje"
+
+#: views/developers/previews.thtml:96
+msgid "devcp_previews_a_delete"
+msgstr "Fshije Paraparjen"
+
+#: views/developers/previews.thtml:95
+msgid "devcp_previews_a_replace"
+msgstr "Zëvendësoje Paraparjen"
+
+#: views/developers/previews.thtml:126
+msgid "devcp_previews_a_update"
+msgstr "Përditësoje Paraparjen"
+
+#: views/developers/previews.thtml:115 views/developers/previews.thtml:124
+msgid "devcp_previews_add_new"
+msgstr "Shto Paraparje të Re"
+
+#. %s is a list of file extensions, e.g. ".png, .gif"
+#: views/developers/previews.thtml:116
+msgid "devcp_previews_add_select"
+msgstr ""
+"Përzgjidhni më poshtë një pamje për ngarkim. pamjet më të mëdhaja se 700 "
+"piksel të gjera dhe 525 piksel të larta do të ripërmasohen. Lloje të lejuar "
+"kartelash: %s"
+
+#: views/developers/previews.thtml:121
+msgid "devcp_previews_click_below"
+msgstr "Për ta ngarkuar, klikoni më poshtë Përditëso Paraparje."
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/previews.thtml:102
+msgid "devcp_previews_click_update"
+msgstr ""
+"Për ta ruajtur këtë pamje, klikoni më poshtë butonin Përditëso Paraparje. "
+"(<a %s>Të anulohet?</a>)"
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/previews.thtml:107
+msgid "devcp_previews_error_message"
+msgstr ""
+"Kjo paraparje do të fshihet kur të klikohet Përditëso Paraparje më poshtë. "
+"(<a %s>Të anulohet?</a>)"
+
+#: views/previews/add.thtml:45
+msgid "devcp_previews_filetype_info"
+msgstr ""
+"Përdorni formularin më poshtë për të ngarkuar një foto PNG, JPG, ose GIF të "
+"shtesës suaj. Pamje më të mëdhaja se 700 piksela gjerësi dhe 525 piksela "
+"lartësi do të ripërmasohen vetvetiu."
+
+#: views/previews/add.thtml:43
+msgid "devcp_previews_header_add"
+msgstr "Shtoni Paraparje"
+
+#: views/developers/previews.thtml:80
+msgid "devcp_previews_header_caption"
+msgstr "Përshkrim Paraparje"
+
+#: views/previews/edit.thtml:43
+msgid "devcp_previews_header_edit"
+msgstr "Përpunoni Paraparje"
+
+#: views/developers/previews.thtml:93
+msgid "devcp_previews_label_default"
+msgstr "Paraparje Parazgjedhje"
+
+#: views/previews/add.thtml:54
+msgid "devcp_previews_label_file"
+msgstr "Kartelë Paraparje"
+
+#: views/previews/add.thtml:59 views/previews/edit.thtml:50
+msgid "devcp_previews_label_makedefault"
+msgstr "Vendose këtë si pamje paraparjeje parazgjedhje"
+
+#: views/developers/previews.thtml:100
+msgid "devcp_previews_label_new"
+msgstr "Paraparje e re:"
+
+#: views/developers/previews.thtml:118
+msgid "devcp_previews_label_upload"
+msgstr "Ngarkoje Paraparjen: "
+
+#: views/developers/previews.thtml:50
+msgid "devcp_previews_notice_error"
+msgstr "Një ose disa prej paraparjeve tuaja nuk u ruajt dot."
+
+#: views/developers/previews.thtml:47
+msgid "devcp_previews_notice_success"
+msgstr "Paraparjet tuaja u përditësuan me sukses."
+
+#: views/developers/previews.thtml:59
+msgid "devcp_previews_p_screenshots"
+msgstr ""
+"Paraparjet për shtesën tuaj tregohen më poshtë. Në përshkrimet ose pamjet e "
+"mëposhtme mund të bëni ndryshime. Paraparja Parazgjedhje është paraparja që "
+"duket përbri shtesës suaj në përfundime kërkimesh dhe shfletimi."
+
+#: views/previews/edit.thtml:55
+msgid "devcp_previews_submit_delete"
+msgstr "Fshi Paraparje"
+
+#: views/previews/edit.thtml:55
+msgid "devcp_previews_submit_delete_confirm"
+msgstr "Jeni i sigurtë se doni të fshihet kjo paraparje?"
+
+#: views/previews/edit.thtml:54
+msgid "devcp_previews_submit_edit"
+msgstr "Përpunoni Paraparje"
+
+#: views/previews/add.thtml:63
+msgid "devcp_previews_submit_upload"
+msgstr "Ngarkoni Paraparje"
+
+#: views/developers/previews.thtml:78
+msgid "devcp_previews_thumbnail"
+msgstr "Miniaturë"
+
+#. %s is the add-on name.
+#: views/developers/previews.thtml:44
+msgid "devcp_previews_title"
+msgstr "Përgjegjës Paraparjesh për %s"
+
+#: views/developers/uploader.thtml:74
+msgid "devcp_review_agreement_please"
+msgstr ""
+"Ju lutem shqyrtoni dhe pranoni Marrëveshjen vijuese për Zhvilluesa përpara "
+"se të vazhdoni."
+
+#: views/elements/developers/rolecheck.thtml:42
+msgid "devcp_rolecheck_no_privs"
+msgstr ""
+"<span>Nuk keni privilegje të mjaftueshme për të bërë ndryshime në këtë faqe."
+"</span><br />Lidhuni me Pronarin e Shtesës, po qe se keni nevojë të bëni "
+"ndryshime."
+
+#: controllers/developers_controller.php:1315
+msgid "devcp_several_hours"
+msgstr ""
+"Ju lutem kini parasysh që disa ndryshime duan disa orë që të shfaqen në tërë "
+"zonat e \"site\"-it web."
+
+#: views/elements/developers/sidebar.thtml:52
+msgid "devcp_sidebar_a_dashboard"
+msgstr "Pult"
+
+#. %s is a number
+#: views/elements/developers/statsbar.thtml:45
+#: views/developers/dashboard.thtml:79
+#, php-format
+msgid "devcp_statsbar_adu"
+msgstr "<em>%s</em> Përdorues Aktivë të Përditshëm"
+
+#. %s is a number
+#: views/elements/developers/statsbar.thtml:41
+#: views/developers/dashboard.thtml:75
+#, php-format
+msgid "devcp_statsbar_total_downloads"
+msgstr "<em>%s</em> Shkarkime Gjithsej"
+
+#. %s is a number
+#: views/elements/developers/statsbar.thtml:43
+#: views/developers/dashboard.thtml:77
+#, php-format
+msgid "devcp_statsbar_weekly_downloads"
+msgstr "<em>%s</em> Shkarkime të Përjavshme"
+
+#: views/developers/addon_status_confirm.thtml:59
+msgid "devcp_status_confirm_active"
+msgstr ""
+"Shënimi i kësaj shtese si aktive do të bëjë që të duket në zona publike të "
+"përshtatshme për gjendjen e saj, përfshi përfundime kërkimesh dhe shfletimi. "
+"Do të mund të shkarkohet nga \"site\"-i web dhe të tregohen për të "
+"përditësime kur kontrollohet për ta, në varësi të gjendjes së saj. Do të "
+"keni mundësinë të riktheheni këtu dhe ta çaktivizoni sipas dëshirës."
+
+#: views/developers/addon_status_confirm.thtml:59
+msgid "devcp_status_confirm_active_sure"
+msgstr "Jeni i sigurt se doni ta shënoni këtë shtesë si aktive?"
+
+#: views/developers/addon_status_confirm.thtml:50
+msgid "devcp_status_confirm_header_sure"
+msgstr "Jeni i sigurt?"
+
+#: views/developers/addon_status_confirm.thtml:55
+msgid "devcp_status_confirm_inactive"
+msgstr ""
+"Shënimi i kësaj shtese si joaktive do të pengojë dukjen e saj në çfarëdo "
+"zone publike, përfshi përfundime kërkimesh dhe shfletimi. Nuk do të mund të "
+"shkarkohet nga \"site\"-i web dhe nuk do të tregohen për të përditësime kur "
+"kontrollohet për tillë. Do të keni mundësinë të riktheheni këtu dhe ta "
+"riaktivizoni sipas dëshirës."
+
+#: views/developers/addon_status_confirm.thtml:55
+msgid "devcp_status_confirm_inactive_sure"
+msgstr "Jeni i sigurt se doni të shënohet kjo shtesë si joaktive?"
+
+#: views/developers/addon_status_confirm.thtml:74
+msgid "devcp_status_confirm_no"
+msgstr "Jo, anuloje"
+
+#: views/developers/addon_status_confirm.thtml:67
+msgid "devcp_status_confirm_public"
+msgstr ""
+"Kalimi i kësaj shtese si publike do ta bëjë të passhme si shkarkim prej "
+"cilitdo dhe përdoruesve ekzistues do t'u ofrohen përditësime të saj."
+
+#: views/developers/addon_status_confirm.thtml:67
+msgid "devcp_status_confirm_public_sure"
+msgstr "Jeni i sigurt se doni ta bëni këtë shtesë publike?"
+
+#: views/developers/addon_status_confirm.thtml:63
+msgid "devcp_status_confirm_sandbox"
+msgstr ""
+"Kalimi i kësaj shtese në bankoprovë do të kërkojë që përdoruesit të bëjnë "
+"hyrjen përpara se të mundin ta shkarkojnë dhe për përdoruesit ekzistues nuk "
+"do të ofrohen më përditësime. Ngaqë shtesa juaj tani është publike, do të "
+"keni mundësinë të riktheheni këtu në çfarëdo kohe dhe ta bëni sërish publike."
+
+#: views/developers/addon_status_confirm.thtml:63
+msgid "devcp_status_confirm_sandbox_sure"
+msgstr "Jeni i sigurt se doni ta kaloni këtë shtesë te bankoprova?"
+
+#: views/developers/addon_status_confirm.thtml:73
+msgid "devcp_status_confirm_yes"
+msgstr "Po, Jam i Sigurt"
+
+#: views/developers/addon_status_nominate.thtml:46
+msgid "devcp_status_nominate_error_notice"
+msgstr ""
+"<span>Mesazhi i propozimit është i domosdoshëm.</span><br />Ju lutem, "
+"plotësoni kutinë e tekstit me të dhënat e nevojshme dhe riprovoni."
+
+#: views/developers/addon_status_nominate.thtml:55
+msgid "devcp_status_nominate_header"
+msgstr "Propozim Shtese"
+
+#: views/developers/dashboard.thtml:85
+msgid "devcp_summary_lastversion"
+msgstr "Versioni Më i Fundit:"
+
+#. %s is the add-on name.
+#: views/developers/addon_edit.thtml:43
+#: views/developers/addon_edit_authors.thtml:44
+#: views/developers/versions_delete.thtml:43
+#: views/developers/addon_edit_properties.thtml:44
+#: views/developers/addon_edit_descriptions.thtml:44
+#: views/developers/versions_edit.thtml:44
+#: views/developers/addon_edit_categories.thtml:43
+#: views/developers/versions.thtml:43
+msgid "devcp_title_edit_addon"
+msgstr "Përpunoni %s"
+
+#. title attribute for a javascript link that pops up a help dialog.
+#: views/elements/translationbox.thtml:68
+msgid "devcp_transbox_a_title_help"
+msgstr "Ndihmë (nuk ikën prej faqes)"
+
+#: views/elements/translationbox.thtml:68
+msgid "devcp_transbox_alt_help"
+msgstr "Ndihmë"
+
+#. %1$s is <span>17</span>, %2$s is 42.
+#: views/elements/translationbox.thtml:101
+msgid "devcp_transbox_chars_used"
+msgstr "Gërma të përdorura: %1$s / %2$s"
+
+#: views/elements/translationbox.thtml:132
+msgid "devcp_transbox_delete_sure"
+msgstr "Jeni i sigurt se doni ta fshini këtë përkthim?"
+
+#. %s is a locale, like en-US.
+#: views/elements/translationbox.thtml:143
+msgid "devcp_transbox_help_header_tabs"
+msgstr "Ç'janë këto %s skeda?"
+
+#: views/elements/translationbox.thtml:145
+msgid "devcp_transbox_help_header_what"
+msgstr "Po kur nuk kam ndonjë përkthim?"
+
+#: views/elements/translationbox.thtml:147
+msgid "devcp_transbox_help_hide"
+msgstr "Fshihe Ndihmën"
+
+#: views/elements/translationbox.thtml:146
+msgid "devcp_transbox_help_if"
+msgstr ""
+"Po qe se një përdorues shfleton \"site\"-in dhe nuk ka përkthim në gjuhën e "
+"tij, do të përdoret Vendorja Parazgjedhje e shtesës suaj, e caktuar te zona "
+"Përpunoni Veti Shtese. Nëse nuk keni ndonjë përkthim, jepni ç'të mundni te "
+"Vendorja Parazgjedhje, që i bie të jetë gjuha që flisni."
+
+#: views/elements/translationbox.thtml:144
+msgid "devcp_transbox_help_transbox"
+msgstr ""
+"Kjo është <i>Kutia e Përkthimit</i>. Ju lejon të përktheni një fushë të "
+"caktuar në çfarëdo gjuhe tjetër për të cilën ju mirëmbani një përkthim. Mund "
+"të shtoni, përpunoni, dhe hiqni përkthime duke përdorur skedat e vendores."
+
+#: views/elements/translationbox.thtml:85
+msgid "devcp_transbox_img_add_trans"
+msgstr "Shtoni Përkthim"
+
+#: views/elements/translationbox.thtml:86
+msgid "devcp_transbox_img_remove_trans"
+msgstr "Hiqe Përkthimin"
+
+#: views/elements/translationbox.thtml:123
+msgid "devcp_transbox_input_add_all"
+msgstr "Shtoni Vendore te Tërë"
+
+#: views/elements/translationbox.thtml:122
+msgid "devcp_transbox_input_add_locale"
+msgstr "Shtoni Vendore"
+
+#: views/elements/translationbox.thtml:124
+#: views/elements/translationbox.thtml:135
+msgid "devcp_transbox_input_cancel"
+msgstr "Anuloje"
+
+#: views/elements/translationbox.thtml:134
+msgid "devcp_transbox_input_delete"
+msgstr "Fshije"
+
+#: views/elements/translationbox.thtml:113
+msgid "devcp_transbox_select_locale"
+msgstr "Përzgjidhni gjuhën e përkthimit për shtim:"
+
+#. %1$s and %2$s are GUIDs.
+#: controllers/developers_controller.php:343
+msgid "devcp_update_addon_guid_error"
+msgstr ""
+"GUID-ja e shtesës e përdorur në këtë kartelë (%1$s) nuk përputhet me GUID-në "
+"ekzistuese për këtë shtesë (%2$s)."
+
+#: controllers/developers_controller.php:334
+msgid "devcp_update_addon_priv_error"
+msgstr "Nuk kini privilegje të mjaftueshme për të përditësuar këtë shtesë."
+
+#. %1$s is a version number, %2$s is an add-on ID.
+#: controllers/developers_controller.php:399
+msgid "devcp_update_addon_version_belong_error"
+msgstr "Versioni i treguar (%1$s) nuk gjendet për këtë shtesë (%2$s)."
+
+#. %1$s is a version number, maybe 1.1.
+#. %2$s is a URL.
+#: controllers/developers_controller.php:351
+msgid "devcp_update_addon_version_exists_error"
+msgstr ""
+"Numri i versionit që ngarkuat (%1$s) gjendet tashmë për këtë shtesë. Po qe "
+"se po provoni të shtoni një tjetër kartelë te ky version, <a href=\"%2$s"
+"\">klikoni këtu</a>."
+
+#. %1$s and %2$s are version numbers.
+#: controllers/developers_controller.php:405
+msgid "devcp_update_addon_version_match_error"
+msgstr ""
+"Numri i versionit që ngarkuat (%1$s) nuk përputhet me nurmin ekzistues të "
+"versionit (%2$s)."
+
+#: views/developers/uploader.thtml:68
+msgid "devcp_uploader_a_start"
+msgstr "Fillojani"
+
+#: views/developers/uploader.thtml:137
+msgid "devcp_uploader_ajax_loading"
+msgstr "Ngarkim kartele..."
+
+#: views/developers/uploader.thtml:82
+#, fuzzy
+msgid "devcp_uploader_button_agree"
+msgstr "Agree and continue"
+
+#: views/developers/uploader.thtml:157
+msgid "devcp_uploader_button_edit"
+msgstr "Përpuno Shtesën Time"
+
+#: views/developers/uploader.thtml:158
+msgid "devcp_uploader_button_later"
+msgstr "Do ta plotësoj shtesën time më vonë."
+
+#: views/developers/uploader.thtml:168
+msgid "devcp_uploader_button_release"
+msgstr "Shtoni Shënime Versioni"
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/uploader.thtml:156
+msgid "devcp_uploader_created_results"
+msgstr ""
+"<p>Pjesëmarrja e shtesës suaj u krijua me sukses. Të dhënat bazë të fituara "
+"nga kartela që ngarkuat u ruajtën, por ka mjaft gjëra të tjera që mund t'i "
+"përshtatni.</p><p>Shtesa suaj, hëpërhë, është shënuar si <strong>e Paplotë</"
+"strong>. Që ta plotësoni shtesën tuaj, lypset t'i vini një emër të saktë, "
+"një përmbledhje, dhe një përshkrim, si edhe t'i përzgjidhni të paktën një "
+"kategori. Duke klikuar lidhjen më poshtë mund të rregulloni të dhënat e "
+"shtesës dhe të shihni për gjendjen e shtesës suaj në cilëndo kohë te <a %"
+"s>faqja e gjendjes</a>."
+
+#: views/developers/uploader.thtml:143
+msgid "devcp_uploader_error_correct"
+msgstr "Ju lutem ndreqeni këtë problem dhe ngarkojeni kartelën tuaj sërish."
+
+#. %1$s is a version number, %2$s is a status, e.g Public or Incomplete.
+#: views/developers/uploader.thtml:175
+msgid "devcp_uploader_file_created"
+msgstr ""
+"Kartela juaj e re u shtua te versioni %1$s dhe hëpërhë është shënuar si %2$s."
+
+#: views/developers/uploader.thtml:154
+msgid "devcp_uploader_header_created"
+msgstr "U krijua Shtesa!"
+
+#: views/developers/uploader.thtml:141
+msgid "devcp_uploader_header_error"
+msgstr "Oh! Duket se ka një problem me këtë kartelë..."
+
+#: views/developers/uploader.thtml:173
+msgid "devcp_uploader_header_file_added"
+msgstr "Kartela u Shtua!"
+
+#: views/developers/uploader.thtml:66
+msgid "devcp_uploader_header_how"
+msgstr "Si punon gjithë kjo?"
+
+#. %s is the version number, e.g. 3.2.
+#: views/developers/uploader.thtml:163
+msgid "devcp_uploader_header_update_created"
+msgstr "U krijua Versioni %s"
+
+#: views/developers/uploader.thtml:117
+msgid "devcp_uploader_header_upload"
+msgstr "Ngarkoni Kartelën Tuaj"
+
+#: views/developers/uploader.thtml:67
+msgid "devcp_uploader_how"
+msgstr ""
+"<p>Faleminderit për interesin që tregoni duke parashtruar shtesën tuaj te "
+"Shtesat Mozilla. Strehimi i shtesës suaj te Shtesat Mozilla është rruga më e "
+"lehtë për të trajtuar shpërndarjen e saj. Ja ç'përfitoni:</p><ul><li>Çdo "
+"shtesë ka faqen e vet publike për paraqitje, me të dhënat që jepni, të tilla "
+"si një përmbledhje e shkurtër e funksioneve të shtesës, një përshkrim "
+"opsional më të gjatë, dhe shfaqjen e një pamjeje prej shtesës suaj në punë e "
+"sipër.</li><li>Shtesa juaj do të duket në përfundime kërkimesh dhe shfletimi "
+"kudo në \"site\", dhe madje edhe te Përgjegjësi i Shtesave të Firefox 3-it.</"
+"li><li>Do të kujdesemi ne për tërë shkarkimet e saj dhe ofrimit të "
+"përditësimeve të vetvetishme te përdoruesit kur të ngarkoni një version të "
+"ri.</li><li>Do të keni hyrje në një pult statistikash me të dhëna të "
+"hollësishme rreth bazës së përdoruesve për të.</li></ul><p>Shtesat e "
+"strehuara te \"site\"-i duhet të shqyrtohen nga një Redaktor i Shtesave "
+"Mozilla përpara se të ofrohen tërë veçoritë e mësipërme. Po qe se jeni gati "
+"për fillimin e procesit dhe e keni paketimin e shtesës suaj gati për "
+"ngarkim, thjesht klikoni më poshtë te Fillojani!</p>"
+
+#: views/developers/uploader.thtml:125
+msgid "devcp_uploader_label_platformtype"
+msgstr "Platforma të Mbuluara:"
+
+#: views/developers/uploader.thtml:124
+msgid "devcp_uploader_label_upload_field"
+msgstr "Kartelë Shtese: "
+
+#: controllers/components/developers.php:1221
+#, fuzzy
+msgid "devcp_uploader_option_other"
+msgstr "Other"
+
+#. %1$s is a number, %2$s is href="..." and should stay in the <a> tag.
+#: views/developers/uploader.thtml:176
+msgid "devcp_uploader_p_pending_file"
+msgstr ""
+"Kartela e re do të jetë e passhme për publikun sapo një redaktor ta "
+"shqyrtojë. Hëpërhë ka %1$s shtesa të tjera në radhë. Doni të shqyrtohet më "
+"shpejt? Shihni mundësinë të <a %2$s>bëheni një redaktor</a>."
+
+#. %1$s is a number, %2$s is href="..." and should stay in the <a> tag.
+#: views/developers/uploader.thtml:166
+msgid "devcp_uploader_p_pending_version"
+msgstr ""
+"Versioni i ri do të jetë i passhëm për publikun sapo një redaktor ta "
+"shqyrtojë. Hëpërhë ka %1$s shtesa të tjera në radhë. Doni të shqyrtohet më "
+"shpejt? Shihni mundësinë të <a %2$s>bëheni një redaktor</a>."
+
+#. %s is a status, e.g Public or Incomplete.
+#: views/developers/uploader.thtml:165
+msgid "devcp_uploader_p_update_created"
+msgstr "Versioni juaj i ri u krijua dhe hëpërhë është shënuar si %s."
+
+#. %1$s is href="..." and should stay in the 'Versions and Files' <a> tag.
+#. %2$s is href="..." and should stay in the 'current status' <a> tag.
+#: views/developers/uploader.thtml:177
+msgid "devcp_uploader_p_update_file"
+msgstr ""
+"Shiheni kartelën tuaj të re te <a %1$s>faqja Versione dhe Kartela</a>, "
+"kontrolloni <a %2$s>gjendjen e tanishme</a> të shtesës suaj, ose <b>shtoni "
+"shënime versioni</b> duke klikuar butonin më poshtë (këshillohet me forcë)."
+
+#. %1$s is href="..." and should stay in the 'Versions and Files' <a> tag.
+#. %2$s is href="..." and should stay in the 'current status' <a> tag.
+#: views/developers/uploader.thtml:167
+msgid "devcp_uploader_p_update_version"
+msgstr ""
+"Shiheni versionin tuaj të ri te <a %1$s>faqja Versione dhe Kartela</a>, "
+"kontrolloni <a %2$s>gjendjen e tanishme</a> të shtesës suaj, ose <b>shtoni "
+"shënime versioni</b> duke klikuar butonin më poshtë (këshillohet me forcë)."
+
+#: views/developers/uploader.thtml:118
+msgid "devcp_uploader_p_upload"
+msgstr ""
+"Ngarkojeni kartelën e shtesën suaj duke përdorur formularin më poshtë. Po qe "
+"se keni disa kartela, sipas platformave të caktuara, për ngarkim, zgjidhni "
+"një kartelë njëherë e mandej ngarkoni të tjerat duke përdorur Versione dhe "
+"Përgjegjësin e Kartelave."
+
+#: views/developers/uploader.thtml:125
+msgid "devcp_uploader_platformtype_all"
+msgstr "Të tëra"
+
+#: views/developers/uploader.thtml:126
+msgid "devcp_uploader_platformtype_specific"
+msgstr "Specifik:"
+
+#. Used as first item in a <select>.
+#: controllers/components/developers.php:1185
+#, fuzzy
+msgid "devcp_uploader_please_choose"
+msgstr "Please Choose..."
+
+#. %1$s is the add-on name, %2$s is the version number.
+#: views/developers/uploader.thtml:57
+msgid "devcp_uploader_title_file"
+msgstr "Shtoni Kartelë te %1$s %2$s"
+
+#: views/developers/uploader.thtml:50
+msgid "devcp_uploader_title_submit"
+msgstr "Parashtroni Shtesë të Re"
+
+#. %s is the add-on name.
+#: views/developers/uploader.thtml:54
+msgid "devcp_uploader_title_update"
+msgstr "Përditëso %s"
+
+#. %s is a full <a> tag
+#: controllers/developers_controller.php:503
+#, php-format
+msgid "devcp_valid_app_reference"
+msgstr "Ju lutem shihni %s për të dhëna."
+
+#. This is the text in the <a> tag for devcp_valid_app_reference. This should be
+#. fixed.
+#: controllers/developers_controller.php:503
+msgid "devcp_valid_app_reference_linktext"
+msgstr "këtë faqe"
+
+#: controllers/developers_controller.php:581
+msgid "devcp_verify_author_error"
+msgstr "Nuk u gjet llogari për këtë vendndodhje email."
+
+#: controllers/developers_controller.php:553
+#, fuzzy
+msgid "devcp_verify_search_engine_error"
+msgstr ""
+"Either the XML is invalid or required fields are missing. Please <a href="
+"\"https://developer.mozilla.org/en/Creating_OpenSearch_plugins_for_Firefox"
+"\">read the documentation</a>, verify your add-on, and try again."
+
+#: views/developers/versions.thtml:75
+msgid "devcp_versions_a_cancel"
+msgstr "Anuloje"
+
+#: views/developers/versions.thtml:79
+msgid "devcp_versions_a_delete"
+msgstr "Fshije Versionin"
+
+#: views/developers/versions.thtml:74
+msgid "devcp_versions_a_empty"
+msgstr "Hiq Version Bosh"
+
+#: views/developers/versions.thtml:71
+msgid "devcp_versions_a_remove"
+msgstr "Të hiqet?"
+
+#: views/developers/versions.thtml:91
+msgid "devcp_versions_add"
+msgstr "Shtoni Version të Ri"
+
+#: views/developers/versions_delete.thtml:58
+msgid "devcp_versions_delete_a_cancel"
+msgstr "Anuloje"
+
+#: views/developers/versions_delete.thtml:56
+msgid "devcp_versions_delete_a_delete"
+msgstr "Fshije Versionin"
+
+#. Followed by a list of reviews and files that will be removed.
+#: views/developers/versions_delete.thtml:50
+msgid "devcp_versions_delete_also"
+msgstr "Kjo do të fshijë gjithashtu:"
+
+#: views/developers/versions_delete.thtml:53
+msgid "devcp_versions_delete_files"
+msgid_plural "devcp_versions_delete_files"
+msgstr[0] "%s kartelë"
+msgstr[1] "%s kartela"
+
+#. %s is the version number.
+#: views/developers/versions_delete.thtml:48
+msgid "devcp_versions_delete_header"
+msgstr "Të fshihet Versioni %s?"
+
+#: views/developers/versions_delete.thtml:52
+msgid "devcp_versions_delete_reviews"
+msgid_plural "devcp_versions_delete_reviews"
+msgstr[0] "%s shqyrtim"
+msgstr[1] "%s shqyrtime"
+
+#. %s is the version number.
+#: views/developers/versions_delete.thtml:49
+msgid "devcp_versions_delete_sure"
+msgstr "Jeni i sigurt se doni të fshihet përgjithmonë versioni %s?"
+
+#: views/developers/versions_edit.thtml:102
+#: views/developers/versions_edit.thtml:155
+msgid "devcp_versions_edit_a_cancel"
+msgstr "Anuloje"
+
+#: views/developers/versions_edit.thtml:101
+msgid "devcp_versions_edit_a_delete"
+msgstr "Fshije Kartelën"
+
+#: views/developers/versions_edit.thtml:165
+msgid "devcp_versions_edit_a_new_app"
+msgstr "Shto Zbatim të Ri"
+
+#: views/developers/versions_edit.thtml:154
+msgid "devcp_versions_edit_a_remove_app"
+msgstr "Hiqe Zbatimin"
+
+#: views/developers/versions_edit.thtml:114
+msgid "devcp_versions_edit_add"
+msgstr "Shto Kartelë të Re"
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/versions_edit.thtml:121
+msgid "devcp_versions_edit_adjust"
+msgstr ""
+"Rregullimi i të dhënave të zbatimit këtu do t'u lejojë përdoruesve të "
+"instalojnë shtesën tuaj edhe kur install.rdf te paketa tregon që ajo shtesë "
+"është e papërputhshme. <a %s>Listë zbatimesh që mbulohen</a>"
+
+#: views/developers/versions_edit.thtml:153
+msgid "devcp_versions_edit_compat_sure"
+msgstr ""
+"Jeni <b>i sigurt</b> se dëshironi t'i hiqet përputhshmëria me këtë zbatim?"
+
+#: views/developers/versions_edit.thtml:100
+msgid "devcp_versions_edit_delete_sure"
+msgstr ""
+"Jeni <b>i sigurt</b> se dëshironi të fshihet kjo kartelë përgjithmonë?"
+
+#: views/developers/versions_edit.thtml:203
+msgid "devcp_versions_edit_header_approval"
+msgstr "Të dhëna Miratimi"
+
+#: views/developers/versions_edit.thtml:120
+msgid "devcp_versions_edit_header_compat"
+msgstr "Zbatime të Përputhshme"
+
+#: views/developers/versions_edit.thtml:74
+msgid "devcp_versions_edit_header_file"
+msgstr "Të dhëna Kartele"
+
+#: views/developers/versions_edit.thtml:189
+#, fuzzy
+msgid "devcp_versions_edit_header_license"
+msgstr "License"
+
+#. %s is the version number.
+#: views/developers/versions_edit.thtml:53
+msgid "devcp_versions_edit_header_manage"
+msgstr "Administroni Versionin %s"
+
+#: views/developers/versions_edit.thtml:212
+msgid "devcp_versions_edit_header_notes"
+msgstr "Shënime Miratimi"
+
+#: views/developers/versions_edit.thtml:98
+msgid "devcp_versions_edit_img_delete"
+msgstr "Fshije Kartelën"
+
+#. %1$s is the file id, e.g. 18723.
+#. %2$s is the platform name, e.g. ALL or Windows.
+#. %3$s is the _('date) created.
+#. %4$s is the status, e.g. "In Sandbox" or "Public".
+#. %5$s is the _('date') status was changed.
+#: views/developers/versions_edit.thtml:208
+msgid "devcp_versions_edit_li_file"
+msgstr "Kartela %1$s (%2$s) krijuar më %3$s dhe ndryshuar te %4$s më %5$s"
+
+#: views/developers/versions_edit.thtml:190
+#, fuzzy
+msgid "devcp_versions_edit_license_description"
+msgstr ""
+"Please select the appropriate license for your add-on. This license "
+"specifies the rights you grant on your source code."
+
+#: views/developers/versions_edit.thtml:111
+msgid "devcp_versions_edit_no_files"
+msgstr "Nuk u gjetën kartela."
+
+#: views/developers/versions_edit.thtml:213
+msgid "devcp_versions_edit_optional"
+msgstr "Të dhëna opsionale për Redaktorin që shqyrton këtë version."
+
+#: views/developers/versions_edit.thtml:151
+msgid "devcp_versions_edit_remove_compat"
+msgstr "Hiqi Përputhshmërinë me Zbatimin"
+
+#: views/developers/versions_edit.thtml:167
+msgid "devcp_versions_edit_select_app"
+msgstr "Ju lutem Përzgjidhni një Zbatim"
+
+#: views/developers/versions_edit.thtml:78
+msgid "devcp_versions_edit_th_file"
+msgstr "Kartelë"
+
+#: views/developers/versions_edit.thtml:79
+msgid "devcp_versions_edit_th_platform"
+msgstr "Platformë"
+
+#: views/developers/versions_edit.thtml:80
+msgid "devcp_versions_edit_th_size"
+msgstr "Madhësi"
+
+#: views/developers/versions_edit.thtml:81
+msgid "devcp_versions_edit_th_status"
+msgstr "Gjendje"
+
+#: views/developers/versions_edit.thtml:183
+msgid "devcp_versions_edit_transbox_releasenotes_description"
+msgstr ""
+"Të dhëna rreth ndryshimesh në këtë version, veçori të reja, të meta të "
+"njohura, dhe të tjera të dhëna të dobishme të lidhura me këtë version. Këto "
+"të dhëna do të mund të kihen gjithashtu nga përdoruesit që përditësojnë "
+"shtesën përmes ndërfaqes Përgjegjësi i Shtesave te Firefox 3-i."
+
+#: views/developers/versions_edit.thtml:182
+msgid "devcp_versions_edit_transbox_releasenotes_name"
+msgstr "Shënime Versioni"
+
+#: views/developers/versions_edit.thtml:164
+msgid "devcp_versions_edit_unsaved_compat"
+msgstr ""
+"<strong>Keni ndryshime të paruajtura.</strong> Përputhshmëria nuk do të "
+"fshihet para se të klikoni më poshtë Përditësoni Versionin."
+
+#: views/developers/versions_edit.thtml:113
+msgid "devcp_versions_edit_unsaved_files"
+msgstr ""
+"<strong>Keni ndryshime të paruajtura.</strong> Kartelat nuk do të fshihen "
+"para se të klikoni më poshtë Përditësoni Versionin."
+
+#: views/developers/versions_edit.thtml:218
+msgid "devcp_versions_edit_update"
+msgstr "Përditësoni Versione"
+
+#: views/developers/versions.thtml:49
+msgid "devcp_versions_header_manage"
+msgstr "Administroni Versione dhe Kartela"
+
+#: views/developers/versions.thtml:87
+msgid "devcp_versions_no_versions"
+msgstr "S'ka versione."
+
+#. %s is a version number, base 10.
+#: views/developers/versions.thtml:46
+msgid "devcp_versions_notice_success"
+msgstr "Versioni %s u fshi me sukses."
+
+#: views/developers/versions.thtml:73
+msgid "devcp_versions_p_remove"
+msgstr ""
+"Ky version nuk ka kartela të përshoqëruara me të dhe mund të hiqet. Do të "
+"donit ta hiqni këtë version?"
+
+#: views/developers/versions.thtml:58
+msgid "devcp_versions_th_created"
+msgstr "U krijua"
+
+#: views/developers/versions.thtml:57
+msgid "devcp_versions_th_status"
+msgstr "Gjendje"
+
+#: views/developers/versions.thtml:56
+msgid "devcp_versions_th_version"
+msgstr "Version"
+
+#: controllers/downloads_controller.php:91
+msgid "downloads_disable_warning"
+msgstr "Kjo shtesë është çaktivizuar"
+
+#: controllers/components/editors.php:57
+msgid "editor_review_error_addon_not_nominated"
+msgstr "Kjo shtesë nuk është propuzuar."
+
+#: controllers/components/editors.php:213
+msgid "editor_review_error_file_not_pending"
+msgstr "Kjo kartelë nuk është në pritje të shqyrtimit."
+
+#. Actions are, for example: approving or rejecting
+#: controllers/components/editors.php:79
+#: controllers/components/editors.php:182
+msgid "editor_review_error_no_action"
+msgstr "Ju lutem përzgjidhni një veprim shqyrtimi."
+
+#: controllers/components/editors.php:192
+msgid "editor_review_error_no_applications"
+msgstr "Ju lutem jepni zbatimin me të cilin e provuat."
+
+#. Comments are required when an editor approves or rejects an add-on.
+#: controllers/components/editors.php:84
+#: controllers/components/editors.php:187
+msgid "editor_review_error_no_comments"
+msgstr "Ju lutem jepni komente shqyrtimi."
+
+#: controllers/components/editors.php:161
+msgid "editor_review_error_no_files"
+msgstr "Ju lutem përzgjidhni të paktën një kartelë për shqyrtim."
+
+#: controllers/components/editors.php:197
+msgid "editor_review_error_no_operating_system"
+msgstr "Ju lutem jepni sistemet operative ku e provuat."
+
+#: views/editors/logs.thtml:51
+msgid "editorcp_logs_button_filter"
+msgstr "Filtro"
+
+#: views/editors/logs.thtml:44
+msgid "editorcp_logs_filter_by"
+msgstr "Filtro sipas llojesh/veprimi"
+
+#: views/editors/logs.thtml:42 controllers/editors_controller.php:964
+msgid "editorcp_logs_page_heading"
+msgstr "Regjistër Ngjarjesh"
+
+#: views/elements/developers/editorsmenu.thtml:60
+msgid "editorcp_menu_eventlog_link"
+msgstr "Regjistër Ngjarjesh"
+
+#: views/elements/developers/editorsmenu.thtml:62
+msgid "editorcp_menu_mainpage_link"
+msgstr "Prapa te Kryesorja"
+
+#: views/elements/developers/editorsmenu.thtml:61
+msgid "editorcp_menu_reviewlog_link"
+msgstr "Regjistër Shqyrtimesh"
+
+#: views/elements/developers/editorsmenu.thtml:55
+msgid "editorcp_menu_summary_link"
+msgstr "Përmbledhje Redaktori"
+
+#: views/elements/developers/editorsmenu.thtml:52
+msgid "editorcp_menu_title"
+msgstr "Mjete Redaktori"
+
+#: views/editors/reviewlog.thtml:49
+msgid "editorcp_reviewlog_button_filter"
+msgstr "Filtro"
+
+#: views/editors/reviewlog.thtml:58
+msgid "editorcp_reviewlog_column_action"
+msgstr "Veprim"
+
+#: views/editors/reviewlog.thtml:56
+msgid "editorcp_reviewlog_column_addon"
+msgstr "Shtesë"
+
+#: views/editors/reviewlog.thtml:55
+msgid "editorcp_reviewlog_column_date"
+msgstr "Datë"
+
+#: views/editors/reviewlog.thtml:57
+msgid "editorcp_reviewlog_column_editor"
+msgstr "Redaktor"
+
+#: views/editors/reviewlog.thtml:94
+msgid "editorcp_reviewlog_comments_hide"
+msgstr "Fshih Komente"
+
+#: views/editors/reviewlog.thtml:93
+msgid "editorcp_reviewlog_comments_show"
+msgstr "Shfaq Komente"
+
+#. %1$s and %2$s are full <input> tags for dates
+#: views/editors/reviewlog.thtml:45
+#, php-format
+msgid "editorcp_reviewlog_entries_between"
+msgstr "Shfaq zëra nga %s deri më %s"
+
+#: views/editors/reviewlog.thtml:104
+msgid "editorcp_reviewlog_none_found"
+msgstr "Nuk u gjetën shqyrtime për këtë periudhë."
+
+#: views/editors/reviewlog.thtml:42
+msgid "editorcp_reviewlog_page_heading"
+msgstr "Regjistër Shqyrtimesh"
+
+#: views/editors/summary.thtml:61
+msgid "editorcp_summary_monthreviews_heading"
+msgstr "Shqyrtimet e Muajit"
+
+#: views/editors/summary.thtml:77
+msgid "editorcp_summary_neweditors_heading"
+msgstr "Redaktorë të Rinj"
+
+#: views/editors/summary.thtml:42
+msgid "editorcp_summary_page_heading"
+msgstr "Përmbledhje Redaktori"
+
+#: views/editors/summary.thtml:94
+msgid "editorcp_summary_recentactivity_heading"
+msgstr "Veprimtari Redaktori së Fundmi"
+
+#: views/editors/summary.thtml:45
+msgid "editorcp_summary_totalreviews_heading"
+msgstr "Shqyrtime Gjithsej"
+
+#: controllers/editors_controller.php:248
+#: controllers/editors_controller.php:249
+msgid "editors_addon_review_pagetitle"
+msgstr "Shqyrtoni Shtesë"
+
+#: controllers/editors_controller.php:349
+msgid "editors_error_js-formerror"
+msgstr "Ju lutem plotësoni kutitë vijuese:"
+
+#: controllers/editors_controller.php:350
+msgid "editors_error_review_one_file"
+msgstr "Ju lutem përzgjidhni të paktën një kartelë për shqyrtim."
+
+#: controllers/editors_controller.php:274
+msgid "editors_error_self_reviews_forbidden"
+msgstr "Nuk lejohen shqyrtime nga vetja."
+
+#: controllers/editors_controller.php:699
+msgid "editors_external_software"
+msgstr "\"Software\" i Jashtëm"
+
+#: views/editors/featured.thtml:120 views/editors/featured.thtml:121
+msgid "editors_featured_add_feature"
+msgstr "Shto karakteristikë"
+
+#: views/editors/featured.thtml:126
+msgid "editors_featured_add_feature_submit"
+msgstr "Shto"
+
+#: views/editors/featured.thtml:49 controllers/editors_controller.php:832
+#: controllers/editors_controller.php:848
+msgid "editors_featured_addon_add_failure"
+msgstr "Dështova në shtim karakteristike."
+
+#: controllers/editors_controller.php:851
+msgid "editors_featured_addon_add_success"
+msgstr "Karakteristika u shtua me sukses."
+
+#: views/editors/featured.thtml:50 controllers/editors_controller.php:839
+#: controllers/editors_controller.php:868
+#: controllers/editors_controller.php:886
+msgid "editors_featured_addon_edit_failure"
+msgstr "Dështova në përpunim karakteristike."
+
+#: views/editors/featured.thtml:51 controllers/editors_controller.php:888
+msgid "editors_featured_addon_edit_success"
+msgstr "Karakteristika u përpunua me sukses."
+
+#: views/editors/featured.thtml:53 controllers/editors_controller.php:861
+msgid "editors_featured_addon_invalid_locale"
+msgstr "Një ose më tepër vendore janë të pavlefshme."
+
+#: views/editors/featured.thtml:52 controllers/editors_controller.php:906
+msgid "editors_featured_addon_remove_failure"
+msgstr "Dështova në heqjen e karakteristikës."
+
+#: controllers/editors_controller.php:901
+msgid "editors_featured_addon_remove_success"
+msgstr "Karakteristika u hoq me sukses."
+
+#: controllers/editors_controller.php:915
+#: controllers/editors_controller.php:917
+msgid "editors_featured_addons_pagetitle"
+msgstr "Shtesë e Trajtuar"
+
+#: views/editors/featured.thtml:54 views/editors/featured.thtml:107
+msgid "editors_featured_edit_feature_submit"
+msgstr "Shko"
+
+#: views/editors/featured.thtml:90 views/editors/featured.thtml:91
+msgid "editors_featured_remove_feature"
+msgstr "Hiqe karakteristikën"
+
+#: views/editors/queue.thtml:46
+msgid "editors_filter_queue"
+msgstr "Radhë Filtrimi"
+
+#: views/editors/queue.thtml:182
+msgid "editors_helpful_links"
+msgstr "Lidhje të Dobishme"
+
+#: views/editors/queue.thtml:182
+msgid "editors_link_guide"
+msgstr "Udhërrëfyes Redaktorësh"
+
+#: views/editors/queue.thtml:182
+msgid "editors_link_policy"
+msgstr "Rregulla Shtese"
+
+#: views/editors/queue.thtml:47
+msgid "editors_notice_filter_session"
+msgstr ""
+"Këta filtra do të jenë në punë për këtë sesion ose derisa të shfuqizohen."
+
+#. %1 is the queue mode
+#: views/editors/queue.thtml:177 views/admin/flagged_queue.thtml:89
+msgid "editors_notice_none_found"
+msgstr "Hëpërhë nuk shtesa të këtij lloji për shqyrtim."
+
+#: controllers/editors_controller.php:1040
+msgid "editors_one_day"
+msgstr "1 ditë"
+
+#: controllers/editors_controller.php:1048
+msgid "editors_one_hour"
+msgstr "1 orë"
+
+#: controllers/editors_controller.php:1056
+msgid "editors_one_minute"
+msgstr "1 minutë"
+
+#: controllers/editors_controller.php:64 controllers/editors_controller.php:73
+#: controllers/editors_controller.php:77
+msgid "editors_pagetitle"
+msgstr "Mjete Redaktorësh"
+
+#. %s is a comma separated list of platforms. Example: Windows, OS X
+#: controllers/editors_controller.php:680
+#: controllers/editors_controller.php:683
+#, php-format
+msgid "editors_platform_x_only"
+msgstr "vetëm %s"
+
+#: controllers/editors_controller.php:695
+msgid "editors_pre-release"
+msgstr "Paraqarkullim"
+
+#. %1 is the app name
+#: views/editors/queue.thtml:131
+#, php-format
+msgid "editors_queue_app_compatibility"
+msgstr "Përputhje %s me"
+
+#: views/editors/queue.thtml:51
+#, fuzzy
+msgid "editors_queue_filter_label_addon"
+msgstr "Add-on or Author Email"
+
+#: views/editors/queue.thtml:72
+#, fuzzy
+msgid "editors_queue_filter_label_addontypes"
+msgstr "Add-on Types"
+
+#: views/editors/queue.thtml:56
+#, fuzzy
+msgid "editors_queue_filter_label_application"
+msgstr "Application"
+
+#: views/editors/queue.thtml:61
+#, fuzzy
+msgid "editors_queue_filter_label_maxversion"
+msgstr "Max. Version"
+
+#: views/editors/queue.thtml:78
+#, fuzzy
+msgid "editors_queue_filter_label_platforms"
+msgstr "Platforms"
+
+#: views/editors/queue.thtml:66
+#, fuzzy
+msgid "editors_queue_filter_label_submissionage"
+msgstr "Age of Submission (days)"
+
+#. %1$s is a number
+#: views/editors/queue.thtml:90
+#, fuzzy
+msgid "editors_queue_filter_result_count"
+msgid_plural "editors_queue_filter_result_count"
+msgstr[0] "Results of your filtered search: <strong>%1$s</strong> Add-on"
+msgstr[1] "Results of your filtered search: <strong>%1$s</strong> Add-ons"
+
+#: views/editors/queue.thtml:84
+msgid "editors_queue_submit_clean"
+msgstr "Pastro"
+
+#: views/editors/queue.thtml:83
+msgid "editors_queue_submit_filter"
+msgstr "Filtër"
+
+#: controllers/editors_controller.php:133
+msgid "editors_queues_disabled"
+msgstr "Radhët për shqyrtime hëpërhë janë të bllokuara. Rikthehuni më vonë."
+
+#: views/editors/review.thtml:149
+#, fuzzy
+msgid "editors_review_a_edit_item"
+msgstr "Edit Item"
+
+#: views/editors/review.thtml:146
+#, fuzzy
+msgid "editors_review_a_item_history"
+msgstr "Item History"
+
+#: views/editors/review.thtml:148
+#, fuzzy
+msgid "editors_review_a_item_homepage"
+msgstr "Item Homepage"
+
+#: views/editors/review.thtml:145
+#, fuzzy
+msgid "editors_review_a_item_overview"
+msgstr "Item Overview"
+
+#: views/editors/review.thtml:147
+#, fuzzy
+msgid "editors_review_a_previews"
+msgstr "Previews"
+
+#: controllers/editors_controller.php:345
+msgid "editors_review_action"
+msgstr "Veprim për Shqyrtime"
+
+#: views/editors/review.thtml:159
+msgid "editors_review_action_info"
+msgstr "Kërkoni Më Tepër të Dhëna"
+
+#: views/editors/review.thtml:157
+msgid "editors_review_action_public"
+msgstr "Kaloje në Publik"
+
+#: views/editors/review.thtml:160
+msgid "editors_review_action_request_superreview"
+msgstr "Kërko Super-Shqyrtim"
+
+#: views/editors/review.thtml:158
+msgid "editors_review_action_sandbox"
+msgstr "Mbaje në Bankoprovë"
+
+#: controllers/editors_controller.php:346
+msgid "editors_review_comments"
+msgstr "Komente Shqyrtimi"
+
+#: views/editors/review.thtml:182
+msgid "editors_review_details_info_request"
+msgstr ""
+"Përdorni këtë formular për të kërkuar më tepër të dhëna prej autorit. Ai do "
+"të marrë një email dhe do të mundë të përgjigjet këtu. Do të njoftoheni me "
+"email kur të përgjigjet."
+
+#: views/editors/review.thtml:174
+msgid "editors_review_details_nominated_public"
+msgstr ""
+"Me këtë, shtesa dhe versioni më i fundit, së bashku me kartelat përkatëse, "
+"do të shfaqen si publike. Versione të ardhshme do të kalohen në bankoprovë "
+"derisa të jenë shqyrtuar nga një redaktor."
+
+#: views/editors/review.thtml:177
+msgid "editors_review_details_nominated_sandbox"
+msgstr "Kjo do ta mbajë shtesën në bankoprovë."
+
+#: views/editors/review.thtml:166
+msgid "editors_review_details_pending_public"
+msgstr ""
+"Kjo do të miratojë shfaqjen në pjesën publike të një versioni bankoprovë nga "
+"një shtese publike."
+
+#: views/editors/review.thtml:169
+msgid "editors_review_details_pending_sandbox"
+msgstr ""
+"Kjo do të bëjë që një version bankoprovë i një shtese publike të mbesë te "
+"bankoprova."
+
+#: views/editors/review.thtml:185
+msgid "editors_review_details_superreview"
+msgstr ""
+"Nëse keni shqetësime rreth sigurisë së kësaj shtese, problemesh me të "
+"drejtat e kopjimit, ose shqetësime të tjera të cilat duhet t'i shohë një "
+"administrator, jepini komentet tuaja në zonën më poshtë. Ato do t'u dërgohen "
+"administratorëve, jo autorit."
+
+#: views/editors/review.thtml:134
+msgid "editors_review_file_diff_link"
+msgstr "Krahasoje me versionin publik"
+
+#: views/editors/review.thtml:131
+msgid "editors_review_file_viewcontents_link"
+msgstr "Shihni Pëmbajtje"
+
+#: views/editors/review.thtml:65
+msgid "editors_review_header_authors"
+msgstr "Autorë:"
+
+#: views/editors/review.thtml:79
+msgid "editors_review_header_categories"
+msgstr "Kategori:"
+
+#: views/editors/review.thtml:92
+msgid "editors_review_header_compatibility"
+msgstr "Përputhshmëri:"
+
+#: views/editors/review.thtml:251
+msgid "editors_review_header_description"
+msgstr "Përshkrim"
+
+#: views/editors/review.thtml:275
+msgid "editors_review_header_devcomments"
+msgstr "Komente Zhvilluesish"
+
+#: views/editors/review.thtml:263
+msgid "editors_review_header_eula"
+msgstr "EULA"
+
+#: views/editors/review.thtml:115
+msgid "editors_review_header_files"
+msgstr "Kartela:"
+
+#: views/editors/review.thtml:284
+msgid "editors_review_header_itemhistory"
+msgstr "Historik Objekti"
+
+#: views/editors/review.thtml:232
+msgid "editors_review_header_nominationmessage"
+msgstr "Mesazh Propozimi"
+
+#: views/editors/review.thtml:311
+msgid "editors_review_header_previews"
+msgstr "Paraparje"
+
+#: views/editors/review.thtml:269
+msgid "editors_review_header_privacy"
+msgstr "Rregulla Vetësie"
+
+#. %1 is the add-on name and version
+#: views/editors/review.thtml:56
+#, php-format
+msgid "editors_review_header_review"
+msgstr "Shqyrtoni %s"
+
+#: views/editors/review.thtml:239
+msgid "editors_review_header_reviewernotes"
+msgstr "Shënime për Shqyrtuesin"
+
+#: views/editors/review.thtml:245
+msgid "editors_review_header_summary"
+msgstr "Përmbledhje"
+
+#: views/editors/review.thtml:257
+msgid "editors_review_header_versionnotes"
+msgstr "Shënime Versioni"
+
+#. a noun: shown in an add-on's editor review history
+#: views/elements/developers/editors_review_history_item.thtml:80
+msgid "editors_review_history_info_reply"
+msgstr "Përgjigjuni"
+
+#: views/elements/developers/editors_review_history_item.thtml:78
+msgid "editors_review_history_info_request"
+msgstr "Kërkesë Për të Dhëna"
+
+#: views/elements/developers/editors_review_history_item.thtml:62
+#: views/editors/reviewlog.thtml:77
+msgid "editors_review_history_nominated_adminreview"
+msgstr "Shqyrtim Administratori"
+
+#: views/elements/developers/editors_review_history_item.thtml:56
+#: views/editors/reviewlog.thtml:71
+msgid "editors_review_history_nominated_approved"
+msgstr "Propozimi u Miratua/Publike"
+
+#: views/elements/developers/editors_review_history_item.thtml:59
+#: views/editors/reviewlog.thtml:74
+msgid "editors_review_history_nominated_denied"
+msgstr "Propozimi u Mohua/Bankoprovë"
+
+#: views/editors/review.thtml:303
+msgid "editors_review_history_nonefound"
+msgstr "Nuk u gjetën shqyrtime të mëparshme."
+
+#: views/elements/developers/editors_review_history_item.thtml:73
+#: views/editors/reviewlog.thtml:88
+msgid "editors_review_history_pending_adminreview"
+msgstr "Shqyrtim Administratori"
+
+#: views/elements/developers/editors_review_history_item.thtml:67
+#: views/editors/reviewlog.thtml:82
+msgid "editors_review_history_pending_approved"
+msgstr "Miratuar/Publike"
+
+#: views/elements/developers/editors_review_history_item.thtml:70
+#: views/editors/reviewlog.thtml:85
+msgid "editors_review_history_pending_denied"
+msgstr "E papranuar/Bankoprovë"
+
+#. link text in an add-on's editor review history, allowing to hide and show an information request's replies
+#. %1 is the number of replies
+#: views/elements/developers/editors_review_history_item.thtml:90
+msgid "editors_review_history_show_hide_replies"
+msgid_plural "editors_review_history_show_hide_replies"
+msgstr[0] "Shfaqi/Fshihi Përgjigjet (%1$s)"
+msgstr[1] "Shfaqi/Fshihi Përgjigjet (%1$s)"
+
+#: views/editors/review.thtml:208
+msgid "editors_review_label_applications"
+msgstr "Zbatime:"
+
+#: views/editors/review.thtml:196
+msgid "editors_review_label_cannedresponse"
+msgstr "ose përzgjidhni një përgjigje të konservuar:"
+
+#: views/editors/review.thtml:190
+msgid "editors_review_label_comments"
+msgstr "Komente:"
+
+#: views/editors/review.thtml:204
+msgid "editors_review_label_operating_systems"
+msgstr "Sisteme Operativë:"
+
+#: views/editors/review.thtml:285 views/editors/review.thtml:312
+msgid "editors_review_link_pagetop"
+msgstr "Krye"
+
+#: views/editors/review.thtml:141
+#, fuzzy
+msgid "editors_review_mulitple_notice"
+msgstr ""
+"Notice: Only review more than one file if you have tested EVERY file you "
+"select."
+
+#: views/editors/review.thtml:51
+msgid "editors_review_next_link"
+msgstr "pasuesja &raquo;"
+
+#: views/editors/review.thtml:322
+msgid "editors_review_previews_notfound"
+msgstr "Nuk u gjetën paraparje."
+
+#: views/editors/review.thtml:50
+msgid "editors_review_previous_link"
+msgstr "&laquo; e mëparshmja"
+
+#: controllers/editors_controller.php:144
+#: controllers/editors_controller.php:146
+msgid "editors_review_queue_pagetitle"
+msgstr "Radhë Shqyrtimi"
+
+#. %1 is the add-ons rank in the queue, %2 is the total queue length
+#: views/editors/review.thtml:47
+msgid "editors_review_rank_in_queue"
+msgstr "<strong># %1$s</strong> nga %2$s në radhë"
+
+#. %1 is the add-ons rank in the queue, %2 is the total queue length. Both numbers
+#: views/editors/review.thtml:45
+#, fuzzy
+msgid "editors_review_rank_in_queue_filtered"
+msgstr "<strong># %1$s</strong> of %2$s in queue (filtered)"
+
+#: views/editors/review.thtml:223
+msgid "editors_review_submit_process_action"
+msgstr "Përpunoni Veprim"
+
+#: views/editors/review.thtml:293
+msgid "editors_review_th_action"
+msgstr "Veprim"
+
+#: views/editors/review.thtml:294
+msgid "editors_review_th_comments"
+msgstr "Komente"
+
+#: views/editors/review.thtml:291
+msgid "editors_review_th_date"
+msgstr "Datë"
+
+#: views/editors/review.thtml:292
+msgid "editors_review_th_reviewer"
+msgstr "Shqyrtues"
+
+#: views/editors/review.thtml:290
+msgid "editors_review_th_version_file"
+msgstr "Version/Kartelë"
+
+#: views/editors/review.thtml:217
+msgid "editors_review_update_notify_once"
+msgstr ""
+"Njoftomë herës tjetër që përditësohet kjo shtesë. (Përditësime të "
+"njëpasnjëshëm nuk do të shoqërohen me email)"
+
+#: controllers/editors_controller.php:298
+msgid "editors_reviewed_successfully"
+msgstr "Shqyrtimi u krye me sukses."
+
+#: views/editors/reviews_queue.thtml:106
+msgid "editors_reviews_action_delete_review"
+msgstr "Fshije shqyrtimin"
+
+#: views/editors/reviews_queue.thtml:104
+msgid "editors_reviews_action_keep"
+msgstr "Hiq flamurka; mbaj shqyrtime"
+
+#: views/editors/reviews_queue.thtml:102
+msgid "editors_reviews_action_skip"
+msgstr "Anashkalo"
+
+#: views/editors/reviews_queue.thtml:100
+msgid "editors_reviews_header_action"
+msgstr "Veprim"
+
+#: views/editors/reviews_queue.thtml:67
+msgid "editors_reviews_in_reply_to"
+msgstr "Në përgjigje të:"
+
+#: controllers/editors_controller.php:748
+msgid "editors_reviews_processed"
+msgstr "Shqyrtimet u kryen me sukses."
+
+#: views/editors/reviews_queue.thtml:117
+msgid "editors_reviews_queue_empty"
+msgstr "Nuk ka shqyrtime në pritje për miratim."
+
+#: views/editors/reviews_queue.thtml:111
+msgid "editors_reviews_submit_process_reviews"
+msgstr "Përpunoni Shqyrtime"
+
+#: controllers/editors_controller.php:691
+msgid "editors_site_specific"
+msgstr "Për një \"Site\" të Dhënë"
+
+#: controllers/editors_controller.php:348
+msgid "editors_tested_app"
+msgstr "Zbatim i Provuar"
+
+#: controllers/editors_controller.php:347
+msgid "editors_tested_os"
+msgstr "Sistem Operativ i Provuar"
+
+#: views/editors/queue.thtml:151
+msgid "editors_th_additional_info"
+msgstr "Të dhëna Shtesë"
+
+#: views/editors/featured.thtml:63 views/editors/queue.thtml:109
+#: views/admin/flagged_queue.thtml:53
+msgid "editors_th_addon"
+msgstr "Shtesë"
+
+#: views/editors/queue.thtml:125
+msgid "editors_th_addontype"
+msgstr "Lloj"
+
+#: views/editors/featured.thtml:64
+msgid "editors_th_locales"
+msgstr "Ta kufizoj te vendoret?"
+
+#: views/editors/queue.thtml:148
+msgid "editors_th_nomination_age"
+msgstr "Kohë në Radhë"
+
+#: views/editors/queue.thtml:101 views/editors/queue.thtml:117
+#: views/editors/queue.thtml:144
+#, fuzzy
+msgid "editors_th_sort_ascending"
+msgstr "Ascending sort"
+
+#: views/editors/queue.thtml:105 views/editors/queue.thtml:121
+#: views/editors/queue.thtml:140
+#, fuzzy
+msgid "editors_th_sort_descending"
+msgstr "Descending sort"
+
+#. %s is a number
+#: controllers/editors_controller.php:1036
+#, php-format
+msgid "editors_x_days"
+msgstr "%s ditë"
+
+#. %s is a number
+#: controllers/editors_controller.php:1044
+#, php-format
+msgid "editors_x_hours"
+msgstr "%s orë"
+
+#. %s is a number
+#: controllers/editors_controller.php:1052
+#, php-format
+msgid "editors_x_minutes"
+msgstr "%s minuta"
+
+#: views/errors/error401.thtml:50 controllers/components/simple_acl.php:81
+#: controllers/components/simple_acl.php:82
+#: controllers/components/simple_acl.php:83 controllers/components/amo.php:607
+#: controllers/components/amo.php:608 controllers/components/amo.php:609
+#: controllers/reviews_controller.php:353
+#: controllers/reviews_controller.php:485
+#: controllers/collections_controller.php:438
+#: controllers/collections_controller.php:496
+#: controllers/collections_controller.php:504
+#: controllers/collections_controller.php:971
+#: controllers/collections_controller.php:1034
+#: controllers/collections_controller.php:1077
+msgid "error_access_denied"
+msgstr "Hyrje e Mohuar"
+
+#: views/errors/error401.thtml:52
+msgid "error_access_denied_message"
+msgstr "Nuk jeni të autorizuar të shihni këtë faqe."
+
+#: controllers/collections_controller.php:1039
+#, fuzzy
+msgid "error_addon_exists"
+msgstr "Add-on already exists!"
+
+#: controllers/developers_controller.php:200
+#: controllers/developers_controller.php:593
+#: controllers/developers_controller.php:1016
+#: controllers/developers_controller.php:1429
+#: controllers/downloads_controller.php:95
+#: controllers/downloads_controller.php:102
+#: controllers/downloads_controller.php:164
+#: controllers/statistics_controller.php:135
+#: controllers/previews_controller.php:115
+#: controllers/previews_controller.php:206
+#: controllers/previews_controller.php:307
+#: controllers/reviews_controller.php:77
+#: controllers/reviews_controller.php:240
+#: controllers/reviews_controller.php:332
+#: controllers/reviews_controller.php:340 controllers/api_controller.php:123
+#: controllers/api_controller.php:759 controllers/addons_controller.php:131
+#: controllers/addons_controller.php:197
+#: controllers/addons_controller.php:1407
+#: controllers/addons_controller.php:1465
+#: controllers/addons_controller.php:1469
+#: controllers/addons_controller.php:1503
+#: controllers/editors_controller.php:265
+#: controllers/collections_controller.php:1041
+#: controllers/collections_controller.php:1074
+msgid "error_addon_notfound"
+msgstr "Shtesë që nuk gjendet!"
+
+#: controllers/files_controller.php:83 controllers/files_controller.php:196
+msgid "error_addon_notviewable"
+msgstr "Kjo shtesë nuk mund të shihet këtu."
+
+#: controllers/reviews_controller.php:246
+msgid "error_addon_selfreview"
+msgstr "Nuk mund shqyrtoni shtesën tuaj."
+
+#: controllers/addons_controller.php:970
+msgid "error_browse_no_addons"
+msgstr "Nuk ka shtesa në këtë kategori!"
+
+#: controllers/api_controller.php:424
+msgid "error_collection_feed_notfound"
+msgstr "Nuk u gjet prurje RSS për shtesën."
+
+#: views/users/register.thtml:65 views/users/edit.thtml:194
+msgid "error_email_invalid"
+msgstr "Kjo nuk është një vendndodhje email e vlefshme."
+
+#: views/users/pwreset.thtml:74 views/users/register.thtml:70
+#: views/users/register.thtml:80 views/users/register.thtml:86
+#: views/users/edit.thtml:105 views/users/edit.thtml:111
+#: views/users/edit.thtml:192 views/admin/users_edit.thtml:78
+#: views/admin/users_edit.thtml:83 views/reviews/add.thtml:80
+#: views/reviews/add.thtml:104
+msgid "error_field_required"
+msgstr "Kjo fushë nuk mund të lihet bosh."
+
+#: controllers/files_controller.php:75 controllers/files_controller.php:93
+#: controllers/files_controller.php:96 controllers/files_controller.php:163
+#: controllers/files_controller.php:176 controllers/files_controller.php:185
+#: controllers/files_controller.php:204 controllers/editors_controller.php:412
+msgid "error_file_notfound"
+msgstr "Nuk u gjet kartelë!"
+
+#. %s is a filename
+#: controllers/editors_controller.php:430
+#, php-format
+msgid "error_file_x_notfound"
+msgstr "Gabim kartele: %s nuk ekziston."
+
+#: views/collections/add.thtml:55 views/collections/edit.thtml:89
+#: views/users/register.thtml:54 views/users/edit.thtml:81
+#: views/reviews/add.thtml:70 controllers/groups_controller.php:80
+#: controllers/groups_controller.php:102
+msgid "error_formerrors"
+msgstr "Ka gabime në këtë formular. Ju lutem ndreqini dhe riparashtrojeni."
+
+#: views/users/register.thtml:109
+msgid "error_invalid_captcha"
+msgstr "Captcha e pavlefshme, ju lutem riprovoni!"
+
+#: views/users/register.thtml:100 views/users/edit.thtml:125
+#: views/admin/users_edit.thtml:101
+msgid "error_invalid_url"
+msgstr ""
+"Kjo URL ka format të pavlefshëm. URL-të e vlefshme kanë pamje si kjo http://"
+"shembull.com/faqja_ime."
+
+#. %s is a string representing what's missing. Example: file_id
+#: controllers/downloads_controller.php:65
+#: controllers/users_controller.php:185 controllers/users_controller.php:264
+#: controllers/users_controller.php:559 controllers/users_controller.php:653
+#: controllers/reviews_controller.php:71
+#: controllers/reviews_controller.php:234
+#: controllers/reviews_controller.php:325
+#: controllers/reviews_controller.php:473
+#: controllers/reviews_controller.php:475
+#: controllers/addons_controller.php:182
+#: controllers/addons_controller.php:1381
+#: controllers/addons_controller.php:1455
+#: controllers/collections_controller.php:266
+#: controllers/collections_controller.php:285
+#: controllers/collections_controller.php:346
+#: controllers/collections_controller.php:443
+#: controllers/collections_controller.php:482
+#: controllers/collections_controller.php:936
+#: controllers/collections_controller.php:959
+#: controllers/collections_controller.php:960
+#: controllers/collections_controller.php:975
+#: controllers/collections_controller.php:977
+#: controllers/collections_controller.php:994
+#: controllers/collections_controller.php:1003
+#: controllers/collections_controller.php:1016
+#: controllers/collections_controller.php:1017
+#: controllers/collections_controller.php:1024
+#: controllers/collections_controller.php:1070
+#: controllers/collections_controller.php:1090
+#, php-format
+msgid "error_missing_argument"
+msgstr "Mungon një argument: %s"
+
+#: controllers/components/amo.php:507 controllers/components/amo.php:532
+msgid "error_no_files_in_addon"
+msgstr "Pa Kartela"
+
+#: controllers/previews_controller.php:200
+msgid "error_preview_notfound"
+msgstr "Nuk u gjet paraparje!"
+
+#: views/addons/display.thtml:400 views/reviews/add.thtml:98
+msgid "error_review_rating_required"
+msgstr "Duhet të përzgjidhni një vlerësim."
+
+#: controllers/users_controller.php:160
+msgid "error_user_already_confirmed"
+msgstr "Kjo llogari përdoruesi është njohur tashmë."
+
+#: controllers/users_controller.php:202 controllers/users_controller.php:276
+#: controllers/users_controller.php:569 controllers/users_controller.php:581
+#: controllers/users_controller.php:587 controllers/users_controller.php:610
+#: controllers/users_controller.php:627
+msgid "error_user_badconfirmationcode"
+msgstr "Kod i pavlefshëm ripohimi!"
+
+#: views/users/pwreset.thtml:79 views/users/register.thtml:75
+#: views/users/edit.thtml:183
+msgid "error_user_confirmpw_nomatch"
+msgstr "Fjalëkalimet nuk u përputhën."
+
+#: views/users/register.thtml:65 views/users/edit.thtml:190
+#: controllers/users_controller.php:617
+msgid "error_user_email_notunique"
+msgstr "Kjo vendndodhje email është zënë tashmë nga një tjetër përdorues."
+
+#: controllers/users_controller.php:596
+msgid "error_user_emailchange_expired"
+msgstr ""
+"Ndryshimi i email-it ka skaduar. Ju lutem ndryshoni sërish vendndodhjen tuaj "
+"email te profili juaj i përdoruesit dhe mandej klikoni lidhjen te email-i i "
+"ripohimit sapo ta merrni."
+
+#: controllers/collections_controller.php:985
+#, fuzzy
+msgid "error_user_exists"
+msgstr ""
+"Users can only have one role at a time. Please remove the user from any "
+"existing roles before continuing."
+
+#: views/users/register.thtml:91 views/users/edit.thtml:116
+#: views/admin/users_edit.thtml:88
+msgid "error_user_nickname_notunique"
+msgstr "Kjo nofkë është e zënë tashmë."
+
+#: views/users/pwreset.thtml:54 controllers/users_controller.php:191
+#: controllers/users_controller.php:270 controllers/users_controller.php:603
+#: controllers/users_controller.php:659
+#: controllers/collections_controller.php:988
+#: controllers/collections_controller.php:998
+msgid "error_user_notfound"
+msgstr "Nuk u gjet përdorues!"
+
+#: views/users/activatefirst.thtml:47
+msgid "error_user_unconfirmed"
+msgstr ""
+"Ju lutem, fillimisht ripohoni llogarinë tuaj të përdoruesit me kodin që "
+"morët me email."
+
+#: views/users/login.thtml:67
+msgid "error_username_or_pw_wrong"
+msgstr "Emër përdoruesi ose fjalëkalim gabim!"
+
+#: controllers/editors_controller.php:260
+msgid "error_version_notfound"
+msgstr "Nuk u gjet version!"
+
+#: views/users/delete.thtml:125 views/users/edit.thtml:173
+msgid "error_wrong_password"
+msgstr "U dha fjalëkalim i gabuar!"
+
+#: views/elements/amo2009/homepage_addon.thtml:122
+#: views/elements/feature.thtml:122
+msgid "feature_learnmore"
+msgstr "Mësoni më tepër"
+
+#. %1 is the add-on name
+#: views/elements/amo2009/homepage_addon.thtml:123
+#: views/elements/feature.thtml:123
+#, php-format
+msgid "feature_learnmore_about_addon"
+msgstr "Mësoni më tepër rreth %1$s"
+
+#. %1$s is a number
+#: views/elements/amo2009/reviews.thtml:52
+#: views/elements/addon_listitem.thtml:112 views/elements/feature.thtml:99
+#: views/addons/browse_thumbs.thtml:86
+#, php-format
+msgid "feature_reviews"
+msgid_plural "feature_reviews"
+msgstr[0] "%1$s shqyrtim"
+msgstr[1] "%1$s shqyrtime"
+
+#: views/elements/amo2009/homepage_addon.thtml:127
+#: views/elements/feature.thtml:127
+msgid "feature_view_more_from_category"
+msgstr "Shihni më tepër prej"
+
+#. This appears on a page that views the source of an add-on. This link will return
+#. the user to the add-on's main page
+#: views/files/browse.thtml:65
+msgid "file_browser_link_addon"
+msgstr "Mbrapsht te shtesa"
+
+#. There is a list of directories and files on the page. Clicking this will show the
+#. contents of all the directories (normally you would click on each one to see the
+#. contents)
+#: views/files/browse.thtml:67
+msgid "file_browser_link_expand_all"
+msgstr "Zgjeroji të tëra"
+
+#. This appears on a page that views the source of an add-on. This link will return
+#. the user to the add-on's review page (it only appears if the add-on is being
+#. reviewed)
+#: views/files/browse.thtml:64
+msgid "file_browser_link_review"
+msgstr "Mbrapsh te shqyrtimi"
+
+#. The title of the page for viewing an add-on's source.
+#. %1$s is the name of the add-on
+#. %2$s is the name of the current application (e.g. Firefox or Thunderbird)
+#: views/files/browse.thtml:46
+msgid "file_browser_title"
+msgstr "%1$s :: Shfletues Kartelash :: Shtesa %2$s-i"
+
+#. This appears on a page that views the source of an add-on. There is a list of
+#. directories and files on the page. Clicking this link will toggle between an
+#. expanded or a collapsed list. This string should be kept short.
+#: views/files/browse.thtml:68
+msgid "file_browser_toggle_expand_collapse"
+msgstr "+/-"
+
+#. Link text for the AMO About page.
+#: views/elements/footer.thtml:72 views/layouts/amo2009.thtml:341
+msgid "footer_a_about"
+msgstr "Rreth"
+
+#. Link text to the AMO blog.
+#: views/elements/footer.thtml:74 views/layouts/amo2009.thtml:343
+msgid "footer_a_blog"
+msgstr "Blog"
+
+#. Link text to the Frequently Asked Questions page.
+#: views/elements/footer.thtml:73 views/layouts/amo2009.thtml:342
+msgid "footer_a_faq"
+msgstr "FAQ"
+
+#. Full text for the FAQ abbreviation.
+#: views/elements/footer.thtml:73 views/pages/collector_features.thtml:72
+#: views/layouts/amo2009.thtml:342
+msgid "footer_abbr_faq"
+msgstr "Pyetje të Bëra Shpesh"
+
+#: views/elements/footer.thtml:67 views/layouts/amo2009.thtml:336
+msgid "footer_all_rights_reserved"
+msgstr "Tërë të drejtat të rezervuara."
+
+#: views/elements/footer.thtml:67 views/layouts/amo2009.thtml:336
+msgid "footer_copyright"
+msgstr "Të drejta Kopjimi"
+
+#: views/elements/footer.thtml:71 views/layouts/amo2009.thtml:340
+msgid "footer_credits"
+msgstr "Kredite"
+
+#: views/elements/footer.thtml:76 views/layouts/amo2009.thtml:346
+msgid "footer_disclaimer"
+msgstr ""
+"Mozilla lidhjet për te këto zbatime i jep për mirësjellje, dhe nuk merr "
+"përsipër përfaqësime që kanë të bëjnë me zbatimet apo çfarëdo të dhëne të "
+"lidhur me to. Çfarëdo pyetjeje, ankese apo pretendimi lidhur me zbatimet "
+"duhet shpënë te shitësi përkatës i \"software\"-it."
+
+#: views/elements/footer.thtml:61 views/layouts/amo2009.thtml:332
+msgid "footer_lang_form_lang_submit_go"
+msgstr "Shko"
+
+#: views/elements/footer.thtml:70 views/layouts/amo2009.thtml:339
+msgid "footer_legal_notices"
+msgstr "Shënime Ligjore"
+
+#: views/elements/footer.thtml:50 views/layouts/amo2009.thtml:321
+msgid "footer_other_languages"
+msgstr "Gjuhë të tjera:"
+
+#: views/elements/footer.thtml:69 views/layouts/amo2009.thtml:338
+msgid "footer_privacy_policy"
+msgstr "Rregulla Vetësie"
+
+#: models/addontype.php:79
+msgid "general_addontype_dict"
+msgstr "Fjalor"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:100
+msgid "general_addontype_dict_plural"
+msgstr "Fjalorë"
+
+#: models/addontype.php:75
+msgid "general_addontype_extension"
+msgstr "Zgjerim"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:98
+msgid "general_addontype_extension_plural"
+msgstr "Zgjerime"
+
+#: models/addontype.php:85
+msgid "general_addontype_lpaddon"
+msgstr "Paketë Gjuhësore (Shtesë)"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:103
+msgid "general_addontype_lpaddon_plural"
+msgstr "Paketa Gjuhësore (Shtesë)"
+
+#: models/addontype.php:83
+msgid "general_addontype_lpapp"
+msgstr "Paketë Gjuhësore (Zbatim)"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:102
+msgid "general_addontype_lpapp_plural"
+msgstr "Paketa Gjuhësore (Zbatim)"
+
+#: models/addontype.php:87
+msgid "general_addontype_plugin"
+msgstr "Shtojcë"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:104
+msgid "general_addontype_plugin_plural"
+msgstr "Shtojca"
+
+#: models/addontype.php:81
+msgid "general_addontype_search"
+msgstr "Motor Kërkimi"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:101
+msgid "general_addontype_search_plural"
+msgstr "Motorë Kërkimesh"
+
+#: models/addontype.php:77
+msgid "general_addontype_theme"
+msgstr "Temë"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:99
+msgid "general_addontype_theme_plural"
+msgstr "Tema"
+
+#: config/language.php:367
+#, fuzzy
+msgid "general_languages_all_locales"
+msgstr "All Locales"
+
+#: views/layouts/amo2009.thtml:249
+#, fuzzy
+msgid "header_brand_name"
+msgstr "Mozilla"
+
+#. %1$s is the application name. Example: Firefox
+#: views/elements/header.thtml:111 views/elements/header.thtml:122
+#: views/layouts/amo2009.thtml:248
+#, php-format
+msgid "header_home_tooltip"
+msgstr "Kthehuni te faqja hyrëse e Shtesave %1$s"
+
+#: views/elements/header.thtml:87
+msgid "header_main_firefox_header"
+msgstr "Shtesa Firefox-i"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:218
+#, fuzzy
+msgid "header_main_firefox_header_with_logo"
+msgstr ""
+"Add-ons <em>for</em> <img alt=\"Firefox\" src=\"%1$s\" /> <strong>Firefox</"
+"strong>"
+
+#: views/elements/header.thtml:99
+msgid "header_main_header"
+msgstr "Shtesa"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:242
+#, fuzzy
+msgid "header_main_header_with_logo"
+msgstr "Add-ons <img alt=\"Add-ons\" src=\"%1$s\" />"
+
+#: views/elements/header.thtml:90
+msgid "header_main_seamonkey_header"
+msgstr "Shtesa Seamonkey"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:224
+#, fuzzy
+msgid "header_main_seamonkey_header_with_logo"
+msgstr ""
+"Add-ons <em>for</em> <img alt=\"seamonkey\" src=\"%1$s\" /> "
+"<strong>SeaMonkey</strong>"
+
+#: views/elements/header.thtml:93
+msgid "header_main_sunbird_header"
+msgstr "Shtesa Sunbird-i"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:230
+#, fuzzy
+msgid "header_main_sunbird_header_with_logo"
+msgstr ""
+"Add-ons <em>for</em> <img alt=\"sunbird\" src=\"%1$s\" /> <strong>Sunbird</"
+"strong>"
+
+#: views/elements/header.thtml:96
+msgid "header_main_thunderbird_header"
+msgstr "Shtesa Thunderbird-i"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:236
+#, fuzzy
+msgid "header_main_thunderbird_header_with_logo"
+msgstr ""
+"Add-ons <em>for</em> <img alt=\"thunderbird\" src=\"%1$s\" /> "
+"<strong>Thunderbird</strong>"
+
+#: views/layouts/amo2009.thtml:205
+#, fuzzy
+msgid "header_navaccess_applications_menu"
+msgstr "Skip to other applications menu"
+
+#: views/layouts/amo2009.thtml:204
+#, fuzzy
+msgid "header_navaccess_categories_menu"
+msgstr "Skip to categories menu"
+
+#: views/layouts/amo2009.thtml:202
+#, fuzzy
+msgid "header_navaccess_main_content"
+msgstr "Skip to main content"
+
+#: views/layouts/amo2009.thtml:203
+#, fuzzy
+msgid "header_navaccess_search_form"
+msgstr "Skip to search form"
+
+#: views/elements/header.thtml:62
+msgid "header_navlink_addons"
+msgstr "Shtesa"
+
+#: views/elements/developers/sidebar.thtml:72
+#: views/elements/developers/myaddons.thtml:50 views/elements/header.thtml:159
+#: views/addons/display.thtml:378
+msgid "header_navlink_login"
+msgstr "Hyni"
+
+#: views/elements/header.thtml:156 views/layouts/amo2009.thtml:304
+msgid "header_navlink_logout"
+msgstr "Dilni"
+
+#: views/elements/header.thtml:145 views/layouts/amo2009.thtml:303
+msgid "header_navlink_myaccount"
+msgstr "Llogaria Ime"
+
+#: views/elements/header.thtml:158
+msgid "header_navlink_register"
+msgstr "Regjistrohuni"
+
+#. %1 is the URL to the registration page
+#. %2 is the URL to the login page
+#: views/layouts/amo2009.thtml:278
+#, fuzzy
+msgid "header_navlink_register_or_login"
+msgstr "<a href=\"%1$s\">Register</a> or <a href=\"%2$s\">Log in</a>"
+
+#: views/layouts/amo2009.thtml:285
+#, fuzzy
+msgid "header_navlink_tools"
+msgstr "Tools"
+
+#. %s is the add-on name
+#: views/elements/collections_interactive_addon.thtml:62
+#: views/elements/amo2009/homepage_addon.thtml:77
+#: views/elements/addon_discussionheader.thtml:62
+#: views/elements/addon_listitem.thtml:67 views/elements/feature.thtml:84
+#: views/addons/category_landing.thtml:87 views/addons/browse_thumbs.thtml:60
+#, php-format
+msgid "img_preview_of"
+msgstr "Paraparje Pamjeje për %s"
+
+#. %1 is the login URL for the link tag
+#. %2 is the link to an explanatory page.
+#: views/elements/amo2009/install.thtml:307 views/elements/install.thtml:255
+msgid "install_a_login_to_install"
+msgstr "<a href=\"%1$s\">Hyni</a> që të instaloni këtë shtesë"
+
+#. %1 is the URL for the Experimental Add-ons section of the FAQ page
+#: views/elements/amo2009/install.thtml:283 views/elements/install.thtml:232
+msgid "install_button_confirm_exp_install"
+msgstr ""
+"Lermë ta instaloj këtë shtesë eksperimentale. <a href=\"%1$s\">Ç'është kjo?</"
+"a>"
+
+#. %1$s is the application name. Example: Firefox
+#. %2$s is an optional string used to specify a platform. Example: (Windows)
+#: views/elements/amo2009/install.thtml:128 views/elements/install.thtml:75
+#, php-format
+msgid "install_button_text"
+msgstr "Shtoje te %s %s"
+
+#. %1 is the add-on name, %2 is the app name
+#: views/elements/amo2009/install.thtml:191
+#: views/elements/amo2009/install.thtml:206
+#: views/elements/amo2009/install.thtml:249
+#: views/elements/amo2009/install.thtml:298 views/elements/install.thtml:150
+#: views/elements/install.thtml:165 views/elements/install.thtml:202
+#: views/elements/install.thtml:246
+#, php-format
+msgid "install_button_title"
+msgstr "Shto %1$s te %2$s"
+
+#. %1$s is the add-on name
+#: views/elements/amo2009/install.thtml:200 views/elements/install.thtml:159
+#, php-format
+msgid "install_download"
+msgstr "Shkarko %1$s"
+
+#: views/elements/amo2009/install.thtml:147 views/elements/install.thtml:94
+msgid "install_error_addon_not_found"
+msgstr "Kjo shtesë nuk është e vlefshme."
+
+#: views/addons/dictionaries.thtml:65
+msgid "langtools_a11y_tablesummary"
+msgstr "Listë paketash gjuhësore dhe fjalorësh."
+
+#: views/addons/dictionaries.thtml:47
+msgid "langtools_download_dictionary"
+msgstr "Shkarkoni Fjalor"
+
+#: views/addons/dictionaries.thtml:48
+msgid "langtools_download_langpack"
+msgstr "Shkarkoni Paketë Gjuhësore"
+
+#: views/addons/dictionaries.thtml:63 controllers/components/amo.php:685
+#: controllers/addons_controller.php:1239
+msgid "langtools_header_dicts_and_langpacks"
+msgstr "Fjalorë dhe Paketa Gjuhësore"
+
+#: views/addons/dictionaries.thtml:44
+msgid "langtools_install_dictionary"
+msgstr "Instalo Fjalor"
+
+#: views/addons/dictionaries.thtml:45
+msgid "langtools_install_langpack"
+msgstr "Instalo Paketë Gjuhësore"
+
+#: views/addons/dictionaries.thtml:69
+msgid "langtools_tableheader_dictionary"
+msgstr "Fjalor"
+
+#: views/addons/dictionaries.thtml:70
+msgid "langtools_tableheader_langpack"
+msgstr "Paketë Gjuhësore"
+
+#: views/addons/dictionaries.thtml:68
+msgid "langtools_tableheader_language"
+msgstr "Gjuhë"
+
+#: models/license.php:65
+#, fuzzy
+msgid "license_custom"
+msgstr "Custom License"
+
+#: config/bootstrap.php:303
+#, fuzzy
+msgid "licenses_bsd"
+msgstr "BSD License"
+
+#: config/bootstrap.php:298
+#, fuzzy
+msgid "licenses_gpl_2.0"
+msgstr "GNU General Public License, version 2.0"
+
+#: config/bootstrap.php:299
+#, fuzzy
+msgid "licenses_gpl_3.0"
+msgstr "GNU General Public License, version 3.0"
+
+#: config/bootstrap.php:300
+#, fuzzy
+msgid "licenses_lgpl_2.1"
+msgstr "GNU Lesser General Public License, version 2.1"
+
+#: config/bootstrap.php:301
+#, fuzzy
+msgid "licenses_lgpl_3.0"
+msgstr "GNU Lesser General Public License, version 3.0"
+
+#: config/bootstrap.php:302
+#, fuzzy
+msgid "licenses_mit"
+msgstr "MIT/X11 License"
+
+#: config/bootstrap.php:297
+#, fuzzy
+msgid "licenses_mpl_1.1"
+msgstr "Mozilla Public License, version 1.1"
+
+#: views/users/emailchange.thtml:51 views/users/delete.thtml:55
+#: views/users/delete.thtml:137 views/users/edit.thtml:74
+#: views/reviews/flag.thtml:54
+msgid "link_return_to_front_page"
+msgstr "Klikoni këtu për t'u kthyer te faqja hyrëse."
+
+#: views/elements/amo2009/addon_list_options.thtml:46
+#: views/elements/addon_list_options.thtml:46
+msgid "list_sortby_date"
+msgstr "Datë"
+
+#: views/elements/amo2009/addon_list_options.thtml:47
+#: views/elements/addon_list_options.thtml:47
+msgid "list_sortby_downloads"
+msgstr "Shkarkime"
+
+#: views/elements/amo2009/addon_list_options.thtml:45
+#: views/elements/addon_list_options.thtml:45
+msgid "list_sortby_name"
+msgstr "Emër Shtese"
+
+#: views/elements/amo2009/addon_list_options.thtml:48
+#: views/elements/addon_list_options.thtml:48
+msgid "list_sortby_rating"
+msgstr "Vlerësimi"
+
+#: config/bootstrap.php:278
+msgid "main_prettyname_fennec"
+msgstr "Fennec"
+
+#: config/bootstrap.php:274
+msgid "main_prettyname_firefox"
+msgstr "Firefox"
+
+#: config/bootstrap.php:277
+msgid "main_prettyname_seamonkey"
+msgstr "SeaMonkey"
+
+#: config/bootstrap.php:276
+msgid "main_prettyname_sunbird"
+msgstr "Sunbird"
+
+#: config/bootstrap.php:275
+msgid "main_prettyname_thunderbird"
+msgstr "Thunderbird"
+
+#: views/elements/addon_categories.thtml:52
+msgid "nav_category_dicts_langpacks"
+msgstr "Fjalorë & Paketa Gjuhësore"
+
+#: views/elements/addon_categories.thtml:55
+msgid "nav_category_themes"
+msgstr "Tema"
+
+#: views/elements/app_chooser.thtml:47 views/layouts/amo2009.thtml:255
+msgid "other_apps_tooltip"
+msgstr "Gjej shtesa për zbatime të tjera"
+
+#. In a user list: user 1, user 2, "others"
+#: views/helpers/addons_html.php:222
+msgid "other_users"
+msgstr "të tjera"
+
+#: controllers/pages_controller.php:90
+msgid "page_title_appversions"
+msgstr "Versione Zbatimesh"
+
+#: controllers/pages_controller.php:115
+#, fuzzy
+msgid "page_title_collector"
+msgstr "Add-on Collector"
+
+#: controllers/pages_controller.php:117
+#, fuzzy
+msgid "page_title_collector_faq"
+msgstr "Add-on Collector FAQ"
+
+#: controllers/pages_controller.php:119
+#, fuzzy
+msgid "page_title_collector_features"
+msgstr "Add-on Collector Features"
+
+#: controllers/pages_controller.php:122
+#, fuzzy
+msgid "page_title_collector_firstrun"
+msgstr "Welcome to the Add-on Collector"
+
+#: controllers/pages_controller.php:92
+msgid "page_title_credits"
+msgstr "Kredite"
+
+#: controllers/pages_controller.php:113
+#, fuzzy
+msgid "page_title_developer_faq"
+msgstr "Developer FAQ"
+
+#: controllers/pages_controller.php:111
+msgid "page_title_faq"
+msgstr "Pyetje të Bëra Shpesh (FAQ)"
+
+#: controllers/pages_controller.php:94
+msgid "page_title_fashionyourfirefox_faq"
+msgstr "FAQ Modernizoni Firefox-in tuaj"
+
+#: controllers/pages_controller.php:101
+msgid "page_title_policy"
+msgstr "Rregulla Shtesash"
+
+#: controllers/pages_controller.php:103
+msgid "page_title_privacy"
+msgstr "Rregulla Vetësie Mozilla"
+
+#: controllers/pages_controller.php:105
+msgid "page_title_review_guide"
+msgstr "Udhëzuesa Shqyrtimesh"
+
+#: controllers/pages_controller.php:107
+msgid "page_title_sandbox"
+msgstr "Sistemi Bankoprovë i Shqyrtimeve"
+
+#: controllers/pages_controller.php:109
+msgid "page_title_submissionhelp"
+msgstr "Ndihmë për Parashtrime"
+
+#: views/pages/appversions.thtml:87
+msgid "pages_appversions_guid"
+msgstr "GUID"
+
+#: views/pages/appversions.thtml:79 controllers/pages_controller.php:90
+msgid "pages_appversions_header"
+msgstr "Versione të Vlefshëm Zbatimi"
+
+#: views/pages/appversions.thtml:80
+msgid "pages_appversions_intro"
+msgstr ""
+"Shtesat e parashtruara te Shtesat Mozilla duhet të kenë një kartelë install."
+"rdf me mbulim për të paktën një nga zbatimet më poshtë. Janë të lejuar vetëm "
+"versionet e radhitur më poshtë për këta zbatime."
+
+#. %s is a full <a> tag
+#: views/pages/appversions.thtml:93
+#, php-format
+msgid "pages_appversions_required_files"
+msgstr ""
+"Nëse zbatimi juaj i mbuluar nuk kërkon një kartelë install.rdf file, prapë "
+"mund të përfshini një me vetitë e nevojshme siç tregohet nga %s."
+
+#. this is the text inside of an <a> tag for pages_appversions_required_files. This
+#. should be fixed.
+#: views/pages/appversions.thtml:93
+msgid "pages_appversions_required_files_link"
+msgstr "këtu"
+
+#: views/pages/appversions.thtml:88
+msgid "pages_appversions_versions"
+msgstr "Versione"
+
+#: views/pages/policy.thtml:51
+msgid "pages_policy_sandbox_link"
+msgstr "Faqe të Dhënash Bankoprove"
+
+#: views/elements/pagination.thtml:53
+msgid "pagination_next_page"
+msgstr "pasues"
+
+#: views/elements/pagination.thtml:52
+msgid "pagination_previous_page"
+msgstr "i mëparshëm"
+
+#: views/elements/recaptcha.thtml:65
+msgid "recaptcha_enter_both_words"
+msgstr ""
+"Ju lutem jepni më poshtë <strong>që të dyja fjalët</strong>, <strong>të "
+"ndara nga një hapësirë</strong>."
+
+#: views/elements/recaptcha.thtml:83
+msgid "recaptcha_enter_here"
+msgstr "Jepni këtu përgjigjent tuaj:"
+
+#: views/elements/recaptcha.thtml:74
+msgid "recaptcha_enter_whatyouhear"
+msgstr "Ju lutem, shtypni këtu atë çka dëgjoni."
+
+#. %1 is the link switching refreshing the captcha
+#. %2 is the link switching to a text captcha
+#: views/elements/recaptcha.thtml:77
+msgid "recaptcha_hardtohear_text"
+msgstr ""
+"Nëse është e zorshme të kuptohet, mundeni të <a href=\"%1$s\">dëgjoni diçka "
+"tjetër</a> ose <a href=\"%2$s\">të kaloni sërish te teksti</a>."
+
+#. %1 is the link switching refreshing the captcha
+#. %2 is the link switching to an audio captcha
+#: views/elements/recaptcha.thtml:68
+msgid "recaptcha_hardtoread_text"
+msgstr ""
+"Nëse është e zorshme të kuptohet, mundeni të <a href=\"%1$s\">provoni fjalë "
+"të ndryshme</a> ose <a href=\"%2$s\">të dëgjoni diçka tjetër</a>."
+
+#: views/users/register.thtml:105
+msgid "recaptcha_label"
+msgstr "Jeni qenie njerëzore?"
+
+#: views/users/register.thtml:106
+msgid "recaptcha_whatsthis"
+msgstr "Ç'është kjo?"
+
+#: controllers/reviews_controller.php:559
+msgid "review_flag_error"
+msgstr "Gabim në flamurëzimin e këtij shqyrtimi!"
+
+#: models/reviews_moderation_flag.php:69
+msgid "review_flag_reason_bug_support"
+msgstr "Njoftim të metash apo kërkesë për asistencë jo në vendin e duhur"
+
+#: views/reviews/display.thtml:103 views/reviews/display.thtml:186
+msgid "review_flag_reason_instructions"
+msgstr "Njoftojeni këtë shqyrtim (përzgjidhni një arsye)"
+
+#: models/reviews_moderation_flag.php:67
+msgid "review_flag_reason_language"
+msgstr "Gjuhë/dialog i papërshtatshëm"
+
+#: models/reviews_moderation_flag.php:71
+msgid "review_flag_reason_other"
+msgstr "Tjetër (ju lutem jepeni hollësisht)"
+
+#: models/reviews_moderation_flag.php:65
+msgid "review_flag_reason_spam"
+msgstr "Spam ose përndryshe lëndë jo nga shqyrtime"
+
+#: views/reviews/display.thtml:91 views/reviews/display.thtml:175
+#: controllers/reviews_controller.php:555
+msgid "review_flag_success"
+msgstr "Faleminderit; ky shqyrtim u flamurëzua për miratim nga botuesi."
+
+#: views/reviews/display.thtml:41
+msgid "review_flag_this"
+msgstr "Njoftoni mbi këtë shqyrtim"
+
+#: views/reviews/display.thtml:42
+msgid "review_flag_this_titletip"
+msgstr ""
+"A është ky shqyrtim i papërshtatshëm, i pasaktë apo spam? Klikoni këtu që të "
+"flamurëzohet për shqyrtim nga botuesi."
+
+#. %1 is the URL of the support section, %2 for the review guidelines
+#: views/reviews/add.thtml:53
+msgid "review_guidelines_short"
+msgstr ""
+"<p>Mbani parasysh këto ndihmëza:</p><ul><li>Shkruani si t'i tregonit një "
+"shoku rreth përshtypjeve nga shtesa. Jepni hollësi të veçanta dhe të "
+"dobishme, të tilla si cilat veçori ju pëlqyen dhe/ose nuk ju pëlqyen, sa i "
+"kollajtë qe përdorimi, dhe çfarëdo mangësie që ka. Shmangni gjuhën e "
+"përgjithshme si, fjala vjen, etiketimet si \"E shkëlqyeshme\" ose \"E keqe"
+"\", në rast se nuk keni arsye pse besoni të jetë kështu.</li><li>Ju lutem "
+"mos postoni në shqyrtime njoftime të metash. Nuk ua japim vendndodhjet tuaja "
+"email zhvilluesve të shtesave e këta mund të kenë nevojë të lidhen me ju për "
+"të zgjidhur problemin tuaj. Shihni <a href=\"%1$s\">ndarjen rreth "
+"asistencës</a> për të mësuar nga të kihet asistencë për këtë shtesë.</"
+"li><li>Ju lutem mbajini shqyrtimet pastër, shmangni përdorimin e "
+"papërshtatshëm të gjuhës dhe mos postoni të dhëna vetjake.</li></ul><p>Ju "
+"lutem, për më tepër hollësi rreth shqyrtimesh përdoruesi shtese, lexoni <a "
+"href=\"%2$s\">Udhëzuesa Shqyrtimesh</a>.</p>"
+
+#. %1 is the add-on name
+#: views/reviews/flag.thtml:56 views/reviews/display.thtml:55
+#: views/reviews/review_added.thtml:50
+#, php-format
+msgid "reviews_header"
+msgstr "Shqyrtime %s"
+
+#: controllers/addons_controller.php:435
+msgid "rss_featuredaddons"
+msgstr "Shtesa të Trajtuara"
+
+#: controllers/addons_controller.php:432
+msgid "rss_newestaddons"
+msgstr "Shtesat më të Reja"
+
+#: controllers/addons_controller.php:434
+#, fuzzy
+msgid "rss_popularaddons"
+msgstr "Popular Add-ons"
+
+#: controllers/addons_controller.php:433
+msgid "rss_updatedaddons"
+msgstr "Shtesa të Përditësuara"
+
+#: views/elements/search_mini.thtml:70
+#, fuzzy
+msgid "search"
+msgstr "Search"
+
+#: views/search/collections.thtml:51
+#, fuzzy
+msgid "search_collections_header"
+msgstr "Collection Search Results"
+
+#: controllers/search_controller.php:297
+#, fuzzy
+msgid "search_collections_pagetitle"
+msgstr "Collection Search Results"
+
+#: controllers/search_controller.php:99
+msgid "search_disabled"
+msgstr "Kërkimi është i çaktivizuar hëpërhë. Ju lutem riprovoni më vonë."
+
+#: views/elements/amo2009/search.thtml:188 views/elements/search.thtml:187
+#: views/elements/search_mini.thtml:54
+msgid "search_form_all_addons"
+msgstr "tërë shtesat"
+
+#. This string is in the main category dropdown when searching
+#: views/elements/amo2009/search.thtml:204
+#, fuzzy
+msgid "search_form_all_collections"
+msgstr "all collections"
+
+#: views/elements/amo2009/search.thtml:184
+#: views/elements/amo2009/search.thtml:385
+#: views/elements/amo2009/search.thtml:408 views/elements/search.thtml:171
+#: views/elements/search.thtml:183 views/elements/search_mini.thtml:43
+#: views/elements/search_mini.thtml:49 views/layouts/mozilla.thtml:188
+msgid "search_form_default_text"
+msgstr "kërkoni për shtesa"
+
+#: views/elements/amo2009/search.thtml:184
+#: views/elements/amo2009/search.thtml:404
+#, fuzzy
+msgid "search_form_default_text_collections"
+msgstr "search for collections"
+
+#: views/elements/amo2009/search.thtml:206 views/elements/search.thtml:202
+msgid "search_form_submit_tooltip"
+msgstr "Kërkoni për shtesa"
+
+#: views/elements/amo2009/search.thtml:184 views/elements/search.thtml:183
+#: views/elements/search_mini.thtml:49
+msgid "search_form_tooltip"
+msgstr "Klikoni për të dhënë terma kërkimi"
+
+#: views/elements/amo2009/search.thtml:186 views/elements/search.thtml:185
+#: views/elements/search_mini.thtml:52
+msgid "search_form_within"
+msgstr "te"
+
+#: views/addons/searchengines.thtml:118
+msgid "search_landing_all_search_engines"
+msgstr "Tërë Motorët e Kërkimeve"
+
+#: views/addons/searchengines.thtml:114
+msgid "search_landing_browse_search_engines"
+msgstr "Shfletoni Motorë Kërkimesh"
+
+#: views/search/collections.thtml:58 views/search/index.thtml:59
+msgid "search_nothing_found"
+msgstr "Nuk u gjetën përfundime."
+
+#: controllers/search_controller.php:185
+msgid "search_pagetitle"
+msgstr "Kërkoni në Shtesa"
+
+#: controllers/search_controller.php:242
+msgid "search_rss_description"
+msgstr "Prurje për përfundime kërkimi"
+
+#. %s is the terms the user is searching for (a string)
+#: controllers/search_controller.php:241
+#, php-format
+msgid "search_rss_results_for"
+msgstr "Përfundime kërkimi për: %s"
+
+#: views/elements/header.thtml:154 views/layouts/amo2009.thtml:296
+msgid "sidebar_navlink_admin_tools"
+msgstr "Mjete Admin"
+
+#: views/elements/header.thtml:146 views/layouts/amo2009.thtml:288
+msgid "sidebar_navlink_developer_tools"
+msgstr "Mjete Zhvilluesi"
+
+#: views/elements/header.thtml:148 views/layouts/amo2009.thtml:290
+msgid "sidebar_navlink_editor_tools"
+msgstr "Mjete Përpunuesi"
+
+#: views/layouts/amo2009.thtml:302
+msgid "sidebar_navlink_welcome"
+msgstr "Mirësevini"
+
+#. %s is the user's name
+#: views/layouts/amo2009.thtml:302
+#, php-format
+msgid "sidebar_navlink_welcome_name"
+msgstr "Mirësevini, %s"
+
+#: views/elements/pitch.thtml:50 views/elements/pitch.thtml:55
+msgid "sidebar_pitch_dictionary"
+msgstr "Fjalor"
+
+#: views/elements/pitch.thtml:72
+msgid "sidebar_pitch_featured_addons"
+msgstr "Shtesa të Trajtuara"
+
+#: views/elements/pitch.thtml:61
+msgid "sidebar_pitch_looking_for"
+msgstr "Po kërkoj për:"
+
+#: views/elements/pitch.thtml:70
+msgid "sidebar_pitch_newest_addons"
+msgstr "Shtesat Më Të Reja"
+
+#: views/elements/pitch.thtml:49
+msgid "sidebar_pitch_search"
+msgstr "Shtojcë Kërkimesh"
+
+#: views/elements/pitch.thtml:69
+msgid "sidebar_pitch_subscribe_to"
+msgstr "Pajtohuni te"
+
+#: views/elements/pitch.thtml:48 views/elements/pitch.thtml:54
+msgid "sidebar_pitch_theme"
+msgstr "Temë"
+
+#: views/elements/pitch.thtml:71
+msgid "sidebar_pitch_updated_addons"
+msgstr "Shtesa të Përditësuara"
+
+#. %1$s is a number
+#: views/helpers/localization.php:65 views/developers/versions_edit.thtml:95
+#: views/addons/dictionaries.thtml:92
+#, php-format
+msgid "size_kb"
+msgstr "%1$s KB"
+
+#: views/elements/amo2009/stars.thtml:57 views/elements/stars.thtml:63
+msgid "stars_not_yet_rated"
+msgstr "Ende e pavlerësuar"
+
+#. %1 is the number of stars this add-on has
+#: views/elements/amo2009/stars.thtml:49 views/elements/stars.thtml:54
+#, php-format
+msgid "stars_rated_x_outof_5"
+msgstr "Vlerësuar me %s nga 5 yje të mundshëm"
+
+#: views/statistics/addon.thtml:59
+msgid "statistics_addon_dashboard_link"
+msgstr "Hyrja e Pultit"
+
+#: views/statistics/addon.thtml:58
+msgid "statistics_addon_developertools_link"
+msgstr "Mjete Zhvilluesi"
+
+#: views/statistics/addon.thtml:53
+msgid "statistics_addon_switch"
+msgstr "Këmbe Shtesën"
+
+#. This is a date format.
+#. http://php.net/strftime
+#: views/statistics/rss/summary.thtml:54 views/statistics/addon.thtml:181
+msgid "statistics_date_shortmonth"
+msgstr "%e %b."
+
+#. This is a date format.
+#. http://php.net/strftime
+#: views/statistics/rss/summary.thtml:40 views/statistics/addon.thtml:152
+msgid "statistics_date_shortmonthwithyear"
+msgstr "%e %b. %Y"
+
+#. This is a date format.
+#. http://php.net/strftime
+#: views/statistics/rss/summary.thtml:41 views/statistics/rss/summary.thtml:48
+#: views/statistics/addon.thtml:161 views/statistics/addon.thtml:172
+msgid "statistics_date_weekdayshortmonth"
+msgstr "%A, %e %b."
+
+#. %1$s is an add-on name and version. Example: Add-on 3.5
+#: controllers/components/stats.php:519
+#, php-format
+msgid "statistics_events_addon_created"
+msgstr "%1$s të krijuara"
+
+#. %1$s is an application name and version. Example: Firefox 3.5
+#: controllers/components/stats.php:500
+#, php-format
+msgid "statistics_events_app_released"
+msgstr "%1$s të hedhura në qarkullim"
+
+#: views/statistics/addon.thtml:71
+msgid "statistics_help_close_link"
+msgstr "Mbylle"
+
+#: views/statistics/addon.thtml:60
+msgid "statistics_help_link"
+msgstr "Ndihmë"
+
+#: views/statistics/index.thtml:83
+msgid "statistics_index_anotheraddon"
+msgstr "ose, përzgjidhni një shtesë tjetër"
+
+#: views/statistics/index.thtml:85
+msgid "statistics_index_anotheraddon_public"
+msgstr "ose, përzgjidhni një shtesë me statistika publike"
+
+#: views/statistics/index.thtml:71
+msgid "statistics_index_myaddons"
+msgstr "Përzgjidhni një nga shtesat tuaja për të parë statistikat rreth saj"
+
+#: views/statistics/index.thtml:89
+msgid "statistics_index_selectaddon"
+msgstr "Përzgjidhni shtesë për të parë statistikat rreth saj"
+
+#: views/statistics/index.thtml:91
+msgid "statistics_index_selectaddon_public"
+msgstr "Përzgjidhni shtesë me statistika publike"
+
+#: views/statistics/index.thtml:39
+msgid "statistics_index_title"
+msgstr "Pult Statistikash"
+
+#: views/statistics/index.thtml:97
+msgid "statistics_index_view_button"
+msgstr "Shihni Statistika"
+
+#: views/statistics/addon.thtml:222 controllers/statistics_controller.php:247
+msgid "statistics_js_download_csv"
+msgstr "Shiheni këtë tabelë në formatin CSV"
+
+#: controllers/statistics_controller.php:246
+msgid "statistics_js_dropdowns_none"
+msgstr "asnjë"
+
+#: controllers/statistics_controller.php:245
+msgid "statistics_js_dropdowns_removeplot"
+msgstr "Hiqe këtë kurbë"
+
+#: controllers/statistics_controller.php:248
+msgid "statistics_js_groupby_selector_date"
+msgstr "Grupoji sipas: Ditësh"
+
+#: controllers/statistics_controller.php:251
+msgid "statistics_js_groupby_selector_month"
+msgstr "Grupoji sipas: Muajsh"
+
+#: controllers/statistics_controller.php:249
+msgid "statistics_js_groupby_selector_week"
+msgstr "Grupoji sipas: Javësh"
+
+#: controllers/statistics_controller.php:250
+msgid "statistics_js_groupby_selector_week_over_week"
+msgstr "Krahasoji sipas: Javësh"
+
+#: controllers/statistics_controller.php:260
+msgid "statistics_js_plotselection_foundinrange"
+msgstr "U gjetën %s te intervali"
+
+#: controllers/statistics_controller.php:270
+msgid "statistics_js_plotselection_options_addplot_name"
+msgstr "Shtoni Kurbë"
+
+#: controllers/statistics_controller.php:271
+msgid "statistics_js_plotselection_options_addplot_tooltip"
+msgstr "Shtoni një tjetër kurbë në këtë grafik"
+
+#: controllers/statistics_controller.php:261
+msgid "statistics_js_plotselection_options_count_name_checked"
+msgstr "Shfaqe Numërimin për Gjithsej"
+
+#: controllers/statistics_controller.php:262
+msgid "statistics_js_plotselection_options_count_name_unchecked"
+msgstr "Fshihe Numërimin për Gjithsej"
+
+#: controllers/statistics_controller.php:263
+msgid "statistics_js_plotselection_options_count_tooltip"
+msgstr "Hidhe në këtë grafik numërimin për gjithsej"
+
+#: controllers/statistics_controller.php:275
+msgid "statistics_js_plotselection_options_csv_name"
+msgstr "Shihni të Dhëna (CSV)"
+
+#: controllers/statistics_controller.php:276
+msgid "statistics_js_plotselection_options_csv_tooltip"
+msgstr "Merrni një kartelë \"Comma Separated Values\" të këtyre të dhënave"
+
+#: controllers/statistics_controller.php:267
+msgid "statistics_js_plotselection_options_events_addon_name_checked"
+msgstr "Fshih Ngjarje %s"
+
+#: controllers/statistics_controller.php:268
+msgid "statistics_js_plotselection_options_events_addon_name_unchecked"
+msgstr "Shfaq Ngjarje %s"
+
+#: controllers/statistics_controller.php:269
+msgid "statistics_js_plotselection_options_events_addon_tooltip"
+msgstr "Mbivendosja kurbave datat e qarkullimi të shtesës"
+
+#: controllers/statistics_controller.php:264
+msgid "statistics_js_plotselection_options_events_firefox_name_checked"
+msgstr "Fshih Ngjarje Firefox"
+
+#: controllers/statistics_controller.php:265
+msgid "statistics_js_plotselection_options_events_firefox_name_unchecked"
+msgstr "Shfaq Ngjarje Firefox"
+
+#: controllers/statistics_controller.php:266
+msgid "statistics_js_plotselection_options_events_firefox_tooltip"
+msgstr "Mbivendosja kurbave datat e qarkullimi të Firefox-it"
+
+#: controllers/statistics_controller.php:272
+msgid "statistics_js_plotselection_options_resize_name_checked"
+msgstr "Tkurre Grafikun"
+
+#: controllers/statistics_controller.php:273
+msgid "statistics_js_plotselection_options_resize_name_unchecked"
+msgstr "Zgjeroje Grafikun"
+
+#: controllers/statistics_controller.php:274
+msgid "statistics_js_plotselection_options_resize_tooltip"
+msgstr "Ripërmaso grafikun"
+
+#: controllers/statistics_controller.php:254
+msgid "statistics_js_plotselection_selector_adu"
+msgstr "Përdoruesa të Përditshëm Aktivë"
+
+#: controllers/statistics_controller.php:256
+msgid "statistics_js_plotselection_selector_application"
+msgstr "Zbatim"
+
+#: controllers/statistics_controller.php:259
+msgid "statistics_js_plotselection_selector_custom"
+msgstr "Vetjak"
+
+#: controllers/statistics_controller.php:253
+msgid "statistics_js_plotselection_selector_downloads"
+msgstr "Shkarkime"
+
+#: controllers/statistics_controller.php:258
+msgid "statistics_js_plotselection_selector_os"
+msgstr "Sistem Operativ"
+
+#: controllers/statistics_controller.php:257
+msgid "statistics_js_plotselection_selector_status"
+msgstr "Gjendje Shtese"
+
+#: controllers/statistics_controller.php:252
+msgid "statistics_js_plotselection_selector_summary"
+msgstr "Përmbledhje"
+
+#: controllers/statistics_controller.php:255
+msgid "statistics_js_plotselection_selector_version"
+msgstr "Version Shtese"
+
+#: controllers/components/stats.php:398
+msgid "statistics_longnames_application"
+msgstr "Zbatim"
+
+#: controllers/components/stats.php:400
+msgid "statistics_longnames_os"
+msgstr "Sistem Operativ"
+
+#: controllers/components/stats.php:399
+msgid "statistics_longnames_status"
+msgstr "Gjendje Shtese"
+
+#: controllers/components/stats.php:401
+msgid "statistics_longnames_unknown"
+msgstr "E panjohur"
+
+#: controllers/components/stats.php:397
+msgid "statistics_longnames_version"
+msgstr "Version Shtese"
+
+#: views/statistics/addon.thtml:118
+msgid "statistics_notice_data_insufficient"
+msgstr ""
+"Ende nuk ka të dhëna të mjafta për shfaqjen e këtij grafiku. Ju lutem "
+"kontrolloni sërish më vonë."
+
+#: views/statistics/addon.thtml:130
+msgid "statistics_notice_data_none"
+msgstr ""
+"Ende s'kemi ndonjë të dhënë për shtesën tuaj. Ju lutem kontrolloni sërish "
+"pas pak ditësh."
+
+#: views/statistics/addon.thtml:41
+msgid "statistics_notice_data_updating"
+msgstr ""
+"Hëpërhë statistikat e shtesës janë duke u përditësuar. Të dhënat më të "
+"fundit mund të mos jenë të plota, ngaqë programet tona ende janë në punë e "
+"sipër për përditësimin e tyre. Ju lutem kontrolloni sërish pas pak minutash."
+
+#: views/statistics/addon.thtml:136
+msgid "statistics_notice_disabled"
+msgstr ""
+"Pulti i Statistikave hëpërhë është i çaktivizuar. Ju lutem kontrolloni prapë "
+"më vonë."
+
+#: views/statistics/addon.thtml:123
+msgid "statistics_notice_nojavascript"
+msgstr "Për të parë grafikët e Pultit të Statistikave nevojitet JavaScript."
+
+#: views/statistics/addon.thtml:44
+msgid "statistics_notice_settings_updated"
+msgstr "Rregullimet tuaja u përditësuan!"
+
+#: controllers/statistics_controller.php:60
+#: controllers/statistics_controller.php:71
+#: controllers/statistics_controller.php:74
+#: controllers/statistics_controller.php:240
+msgid "statistics_pagetitle"
+msgstr "Pult Statistikash"
+
+#: views/statistics/addon.thtml:99
+msgid "statistics_plot_legend_adu"
+msgstr "Përdoruesa Aktivë të Përditshëm"
+
+#: views/statistics/addon.thtml:95
+msgid "statistics_plot_legend_downloads"
+msgstr "Shkarkime të Përditshme"
+
+#: views/statistics/addon.thtml:107
+msgid "statistics_plot_options_zoomin_alt"
+msgstr "Zmadhoje"
+
+#: views/statistics/addon.thtml:106
+msgid "statistics_plot_options_zoomin_title"
+msgstr "Zmadhoje me një muaj"
+
+#: views/statistics/addon.thtml:110
+msgid "statistics_plot_options_zoomout_alt"
+msgstr "Zvogëloje"
+
+#: views/statistics/addon.thtml:109
+msgid "statistics_plot_options_zoomout_title"
+msgstr "Zvogëloje me një muaj"
+
+#: controllers/statistics_controller.php:283
+#, php-format
+msgid "statistics_rss_description"
+msgstr "Përmbledhje e përditshme e statistikave për %1$s"
+
+#: views/statistics/rss/summary.thtml:68
+msgid "statistics_rss_title_fulldate"
+msgstr "%A, %e %B %Y"
+
+#: views/statistics/rss/summary.thtml:68
+#, php-format
+msgid "statistics_rss_title_statsfordate"
+msgstr "Statistika për %1$s"
+
+#: views/statistics/settings.thtml:49
+msgid "statistics_settings_access_description"
+msgstr ""
+"Si parazgjedhje, vetëm ju dhe Mozilla mund të hyjë në të dhënat te pulti "
+"juaj. Mund edhe ta hapni për publikun, që kështu cilido të mund të shohë të "
+"dhënat tuaja për shtesat."
+
+#: views/statistics/settings.thtml:48
+msgid "statistics_settings_access_heading"
+msgstr "Hyrje në Pult"
+
+#: views/statistics/settings.thtml:51
+msgid "statistics_settings_access_private"
+msgstr "Vetjake"
+
+#: views/statistics/settings.thtml:51
+msgid "statistics_settings_access_private_description"
+msgstr "Vetëm ju dhe Mozilla mund të shohin statistikat e kësaj shtese"
+
+#: views/statistics/settings.thtml:52
+msgid "statistics_settings_access_public"
+msgstr "Publike"
+
+#: views/statistics/settings.thtml:52
+msgid "statistics_settings_access_public_description"
+msgstr "Statistikat e kësaj shtese mund t'i shohë kushdo"
+
+#: views/statistics/addon.thtml:251
+msgid "statistics_settings_change_link"
+msgstr "Ndryshoni Rregullimet"
+
+#: views/statistics/addon.thtml:253
+msgid "statistics_settings_confidential"
+msgstr "Ju lutem trajtojini këto të dhëna si të rezervuara."
+
+#: views/statistics/addon.thtml:245
+msgid "statistics_settings_currently_private"
+msgstr "Ky pult, hëpërhë, është <b>vetjak</b>."
+
+#: views/statistics/addon.thtml:241
+msgid "statistics_settings_currently_public"
+msgstr "Ky pult, për çastin, është <b>publik</b>."
+
+#: views/statistics/addon.thtml:246
+msgid "statistics_settings_locked_alt"
+msgstr "Kyçur"
+
+#: views/statistics/settings.thtml:57
+msgid "statistics_settings_return_link"
+msgstr "Kthehu te Pulti"
+
+#: views/statistics/settings.thtml:56
+msgid "statistics_settings_save_button"
+msgstr "Ruaji Rregullimet"
+
+#: views/statistics/settings.thtml:46
+#, php-format
+msgid "statistics_settings_title"
+msgstr "Rregullime Pulti Statistikash për %1$s"
+
+#: views/statistics/addon.thtml:242
+msgid "statistics_settings_unlocked_alt"
+msgstr "Çkyçur"
+
+#: controllers/components/stats.php:405
+msgid "statistics_shortnames_application"
+msgstr "Zbt"
+
+#: controllers/components/stats.php:407
+msgid "statistics_shortnames_os"
+msgstr "OS"
+
+#: controllers/components/stats.php:406
+msgid "statistics_shortnames_status"
+msgstr "Gjn"
+
+#: controllers/components/stats.php:408
+msgid "statistics_shortnames_unknown"
+msgstr "Pnj"
+
+#: controllers/components/stats.php:404
+msgid "statistics_shortnames_version"
+msgstr "Ver"
+
+#: views/statistics/rss/summary.thtml:42 views/statistics/addon.thtml:192
+msgid "statistics_summary_downloads_average"
+msgstr "Shkarkime të Përditshme Mesatarisht"
+
+#: views/statistics/rss/summary.thtml:39
+msgid "statistics_summary_downloads_heading"
+msgstr "Shkarkime"
+
+#: views/statistics/rss/summary.thtml:41 views/statistics/addon.thtml:171
+msgid "statistics_summary_downloads_lastcount"
+msgstr "Numërimi i Ditës së Fundit"
+
+#: views/statistics/rss/summary.thtml:43 views/statistics/addon.thtml:199
+msgid "statistics_summary_downloads_lastweek"
+msgstr "Shkarkime gjatë 7 ditëve të fundit"
+
+#: views/statistics/rss/summary.thtml:40 views/statistics/addon.thtml:151
+msgid "statistics_summary_downloads_total"
+msgstr "Shkarkime Gjithsej"
+
+#: views/statistics/rss/summary.thtml:40 views/statistics/addon.thtml:152
+#, php-format
+msgid "statistics_summary_downloads_total_sincedate"
+msgstr "Që prej %1$s"
+
+#: views/statistics/rss/summary.thtml:50 views/statistics/rss/summary.thtml:56
+#: views/statistics/addon.thtml:163 views/statistics/addon.thtml:183
+msgid "statistics_summary_nodata"
+msgstr "Ende pa të dhëna"
+
+#: views/statistics/rss/summary.thtml:60 views/statistics/addon.thtml:195
+msgid "statistics_summary_updatepings_average"
+msgstr "Përdoruesa Aktivë të Përditshëm Mesatarisht"
+
+#: views/statistics/rss/summary.thtml:52 views/statistics/addon.thtml:177
+msgid "statistics_summary_updatepings_changefromprevious"
+msgstr "Ndryshimi me numërimin e mëparshëm"
+
+#: views/statistics/rss/summary.thtml:54 views/statistics/addon.thtml:181
+#, php-format
+msgid "statistics_summary_updatepings_changefromprevious_ondate"
+msgstr "%1$s më %2$s"
+
+#: views/statistics/rss/summary.thtml:45
+msgid "statistics_summary_updatepings_heading"
+msgstr "Përdoruesa Aktivë të Përditshëm"
+
+#: views/statistics/rss/summary.thtml:46 views/statistics/addon.thtml:157
+msgid "statistics_summary_updatepings_total"
+msgstr "Përdoruesa Aktivë të Përditshëm"
+
+#: views/statistics/rss/summary.thtml:48 views/statistics/addon.thtml:161
+#, php-format
+msgid "statistics_summary_updatepings_total_ondate"
+msgstr "Më %1$s"
+
+#: views/statistics/rss/summary.thtml:61 views/statistics/addon.thtml:203
+#, fuzzy
+msgid "statistics_summary_updatepings_weekly_average"
+msgstr "Average Daily Users this Week"
+
+#. %s is a percentage, like '+22.33%'. It sits next to another number, so
+#. the implied meaning is 'percentage change' from the previous stat point.
+#: views/statistics/rss/summary.thtml:62 views/statistics/addon.thtml:205
+#, fuzzy
+msgid "statistics_summary_updatepings_weekly_change"
+msgstr "%s from last week"
+
+#: views/statistics/addon.thtml:65 controllers/statistics_controller.php:184
+#: controllers/statistics_controller.php:282
+#, php-format
+msgid "statistics_title_addon_stats"
+msgstr "Statistika %1$s"
+
+#: views/addons/themes_landing.thtml:113
+msgid "themes_landing_all_themes"
+msgstr "Tërë Temat"
+
+#: views/addons/themes_landing.thtml:109
+msgid "themes_landing_browse_themes"
+msgstr "Shfletoni Tema"
+
+#: views/users/edit.thtml:185
+msgid "user_change_email"
+msgstr "Ndryshoni Vendndodhje Email"
+
+#: views/users/edit.thtml:169
+msgid "user_change_password"
+msgstr "Ndryshoni fjalëkalimin"
+
+#: views/users/edit.thtml:96
+#, fuzzy
+msgid "user_change_password_or_email"
+msgstr "Change Password or Email"
+
+#: controllers/users_controller.php:197
+msgid "user_confirmationcode_resent"
+msgstr "U ridërgua kodi i ripohimit!"
+
+#. %1 is the email address, %2 is the URL of the user registration page
+#: views/users/delete.thtml:51
+msgid "user_del_account_deleted"
+msgstr ""
+"Llogaria juaj si përdoruesi %1$s u fshi me sukses. Nëse doni të ktheheni "
+"ndonjëherë, mund të riregjistroheni te <a href=\"%2$s\">faqja e "
+"regjistrimeve të përdoruesve</a>."
+
+#: views/users/delete.thtml:102
+msgid "user_del_community_sad"
+msgstr "Bashkësia e Shtesave Mozilla trishtohet nga largimi juaj."
+
+#: views/users/delete.thtml:123
+msgid "user_del_confirm_password"
+msgstr "Ripohoni Fjalëkalimin"
+
+#: views/users/delete.thtml:134
+msgid "user_del_deletenow"
+msgstr "Fshije tani llogarinë time si përdorues"
+
+#. %1 is the URL of the user's info page
+#: views/users/delete.thtml:64
+msgid "user_del_error_addons"
+msgstr ""
+"Nuk mund ta fshini llogarinë tuaj, po qe se radhiteni mes <a href=\"%1$s"
+"\">autorëve të ndonjë shtese</a>. Për të fshirë llogarinë tuaj, ju lutem i "
+"kërkoni një personi tjetër nga grupi juaj i zhvillimeve t'ju fshijë nga "
+"lista e autorëve për shtesën tuaj. Më pas, do të jeni në gjendje të fshini "
+"llogarinë tuaj këtu."
+
+#. %1 is a link to the amo-editors mailing list
+#: views/users/delete.thtml:71
+msgid "user_del_error_addons_more_questions"
+msgstr "Nëse keni pyetje shtesë, për ndihmë ju lutem lidhuni me %1$s."
+
+#: views/users/delete.thtml:78
+msgid "user_del_error_checkbox"
+msgstr ""
+"Lypset të vini shenjë te kutiza \"E kuptoj...\" përpara se të fshijmë "
+"llogarinë tuaj."
+
+#: views/users/delete.thtml:84
+msgid "user_del_error_password"
+msgstr ""
+"Që të mund të plotësohet ky hap, ju lutem jepeni saktë fjalëkalimin tuaj."
+
+#. %1 is a link to the amo-admins mailing list
+#: views/users/delete.thtml:91
+msgid "user_del_error_unknown"
+msgstr ""
+"Ndodhi një gabim gjatë fshirjes së llogarisë suaj. Për problemin, ju lutem "
+"lidhuni me %1$s dhe do ta fshijmë ne për ju. Na ndjeni për problemin."
+
+#: views/users/delete.thtml:110
+msgid "user_del_header_confirm_deletion"
+msgstr "Ripohoni fshirjen e llogarisë"
+
+#. %1 is the user's email address
+#: views/users/delete.thtml:100
+msgid "user_del_header_delete_account"
+msgstr "Fshi Llogarinë e Përdoruesit %1$s"
+
+#: views/users/delete.thtml:50
+msgid "user_del_header_farewell"
+msgstr "Lamtumirë!"
+
+#: views/users/delete.thtml:115
+msgid "user_del_nologin"
+msgstr "Nuk do të jeni më në gjendje të hyni te Shtesat Mozilla."
+
+#: views/users/delete.thtml:112
+msgid "user_del_permanently_removed_means"
+msgstr ""
+"Duke klikuar \"fshije\" llogaria juaj <strong>ka për t'u fshirë "
+"përgjithmonë</strong>. Kjo do të thotë:"
+
+#: views/users/delete.thtml:116
+msgid "user_del_reviews_anonymized"
+msgstr ""
+"Shqyrtimet dhe vlerësimet tuaja nuk do të fshihen, por nuk do të shfaqen më "
+"si tuajat."
+
+#. %1 is a link to the amo-editors mailing list
+#: views/users/delete.thtml:104
+msgid "user_del_specific_problem_editors"
+msgstr ""
+"Mund t'ju ndihmojmë nëse keni një problem të veçantë; ju lutem mos e fshini "
+"llogarinë tuaj këtë herë, por lidhuni me ne te %1$s dhe do të bëjmë ç'të "
+"jetë e mundur për t'ju ndihur në zgjidhjen e tij."
+
+#: views/users/delete.thtml:130
+msgid "user_del_understand_permanent"
+msgstr "E kam të qartë që ky hap nuk mund të zhbëhet."
+
+#: views/helpers/addons_html.php:192
+msgid "user_deleted_nickname"
+msgstr "Përdoruesi u Fshi"
+
+#. %1 is the new email address
+#: views/users/edit.thtml:71
+msgid "user_edit_confirm_email_sent"
+msgstr ""
+"Për ripohimin e vendndodhjes tuaj të re email u dërgua një email te %1$s. Që "
+"të hyjë në fuqi ndryshimi, lypset të klikoni te lidhja e dhënë në këtë "
+"email. Deri atëherë, mund të vazhdoni të hyni me vendndodhjen tuaj të "
+"tanishme email."
+
+#: views/users/edit.thtml:201
+msgid "user_edit_delete_user"
+msgstr "Fshi llogari përdoruesi"
+
+#. This contains the email sent to users when they signed up for a new
+#. account:
+#. %1 is the confirmation URL, %2 is the current app
+#: views/users/email/confirm_plain.thtml:6
+#, php-format
+msgid "user_email_confirm_account_nopass"
+msgstr ""
+"Mirësevini te Shtesa %2$s.\n"
+"\n"
+"Para se ta përdorni llogarinë tuaj të re duhet ta aktivizoni atë - kjo na "
+"siguron që vendndodhja email që përdorët është e vlefshme dhe ju përket "
+"juve.\n"
+"Për aktivizimin e llogarisë suaj, klikoni lidhjen më poshtë ose kopjojeni "
+"dhe ngjiteni te shtylla e vendeve te shfletuesi juaj:\n"
+"\n"
+"%1$s\n"
+"\n"
+"Pasi të keni aktivizuar me sukses llogarinë tuaj, mund ta hidhni tej këtë e-"
+"mail.\n"
+"\n"
+"Ju faleminderit që ju bashkuat Shtesave %2$s\n"
+"-- Ekipi i Shtesave %2$s"
+
+#. %1 is the confirmation url, %2 is the application name
+#: views/users/email/emailchange_plain.thtml:5
+msgid "user_email_confirm_emailchange"
+msgstr ""
+"Kërkuat ndryshimin e vendndodhjes suaj email te Shtesa %2$s.\n"
+"\n"
+"Që të mund të ripohoni vendndodhjen e re, ju lutem klikoni lidhjen më poshtë "
+"ose kopjojeni dhe hidheni të tërën te shtylla e vendndodhjeve e shfletuesit "
+"tuaj:\n"
+"\n"
+"%1$s\n"
+"\n"
+"Keni 48 orë kohë për ripohimin e vendndodhjes suaj të re. Nëse nuk dëshironi "
+"më të ndryshoni vendndodhjen, mundeni thjesht ta shpërfillni këtë email.\n"
+"\n"
+"Faleminderit!\n"
+"-- Stafi i Shtesave r%2$s"
+
+#: controllers/users_controller.php:168
+#, php-format
+msgid "user_email_confirm_subject"
+msgstr "Faleminderit që ju bashkuat Shtesave %s"
+
+#. This is the password reset email
+#. %1 is the pw reset URL, %2 is the application
+#: views/users/email/pwreset_plain.thtml:5
+#, php-format
+msgid "user_email_pwreset"
+msgstr ""
+"Ricaktim Fjalëkalimi për te Shtesa %2$s\n"
+"\n"
+"Morëm një kërkesë për ricaktimin e fjalëkalimit për këtë llogari te addons."
+"mozilla.org. Për ta ndryshuar këtë fjalëkalim ju lutem klikoni lidhjen "
+"vijuese, ose ngjiteni te shtyllë vendesh te shfletuesi juaj:\n"
+"\n"
+"%1$s\n"
+"\n"
+"Nëse nuk e keni kërkuar këtë email nuk ka nevojë për veprime të mëtejshme.\n"
+"\n"
+"Faleminderit,\n"
+"-- Stafi i Shtesave %2$s"
+
+#: controllers/users_controller.php:245
+#, php-format
+msgid "user_email_pwreset_subject"
+msgstr "Ricaktoni fjalëkalimin tuaj për te Shtesa %s"
+
+#: views/users/emailchange.thtml:50
+msgid "user_emailchange_error"
+msgstr "Gabim!"
+
+#. %1 is the application name
+#: controllers/users_controller.php:533
+msgid "user_emailchange_subject"
+msgstr "Ju lutem ripohoni ndryshimin e vendndodhjes tuaj email te Shtesa %1$s"
+
+#: views/users/emailchange.thtml:48
+msgid "user_emailchange_success"
+msgstr "Sukses!"
+
+#. %1 is the new email address
+#: views/users/emailchange.thtml:49
+msgid "user_emailchange_successful_description"
+msgstr ""
+"Vendndodhja juaj email u ndryshua me sukses. Tani e tutje, ju lutem përdorni "
+"%1$s për hyrje."
+
+#: views/users/edit.thtml:134 views/admin/users_edit.thtml:111
+#, fuzzy
+msgid "user_form_bio"
+msgstr "About me"
+
+#: views/users/edit.thtml:135 views/admin/users_edit.thtml:112
+#, fuzzy
+msgid "user_form_bio_description"
+msgstr ""
+"Introduce yourself to the community, if you like! This text will appear "
+"publicly on your user info page. Line breaks will be preserved, but no HTML "
+"is allowed."
+
+#: views/users/pwreset.thtml:77 views/users/register.thtml:73
+#: views/users/edit.thtml:181
+msgid "user_form_confirmpassword"
+msgstr "Ripohoni fjalëkalimin"
+
+#: views/users/edit.thtml:145
+#, fuzzy
+msgid "user_form_display_collections"
+msgstr "Display the collections I have created in my user profile"
+
+#: views/users/edit.thtml:149
+#, fuzzy
+msgid "user_form_display_collections_fav"
+msgstr "Display my favorite collections in my user profile"
+
+#: views/users/edit.thtml:86
+#, php-format
+msgid "user_form_editprofile"
+msgstr "Përpunoni profil përdoruesi për %s"
+
+#: views/users/pwreset.thtml:52 views/users/login.thtml:81
+#: views/users/register.thtml:63 views/users/edit.thtml:187
+msgid "user_form_email"
+msgstr "Vendndodhje email"
+
+#: views/users/register.thtml:78 views/users/edit.thtml:103
+#: views/admin/users_edit.thtml:76
+msgid "user_form_firstname"
+msgstr "Emër"
+
+#: views/users/register.thtml:94 views/users/edit.thtml:119
+#: views/admin/users_edit.thtml:91
+msgid "user_form_hideemail"
+msgstr "Fshih vendndodhje email"
+
+#: views/users/register.thtml:98 views/users/edit.thtml:123
+#: views/admin/users_edit.thtml:99
+msgid "user_form_homepage"
+msgstr "URL \"website\"-i"
+
+#: views/users/register.thtml:84 views/users/edit.thtml:109
+#: views/admin/users_edit.thtml:81
+msgid "user_form_lastname"
+msgstr "Mbiemër"
+
+#: controllers/users_controller.php:333
+msgid "user_form_login"
+msgstr "Hyrje Përdoruesi"
+
+#: views/users/pwreset.thtml:72 views/users/edit.thtml:176
+msgid "user_form_newpassword"
+msgstr "Fjalëkalim i ri"
+
+#: views/users/register.thtml:89 views/users/edit.thtml:114
+#: views/admin/users_edit.thtml:86
+msgid "user_form_nickname"
+msgstr "Nofkë"
+
+#: views/users/edit.thtml:171
+msgid "user_form_oldpassword"
+msgstr "Fjalëkalim i vjetër"
+
+#: views/users/edit.thtml:97 views/users/edit.thtml:200
+msgid "user_form_otheractions"
+msgstr "Të tjera Veprime"
+
+#: views/users/login.thtml:85 views/users/register.thtml:68
+msgid "user_form_password"
+msgstr "Fjalëkalim"
+
+#: controllers/users_controller.php:93
+msgid "user_form_registration"
+msgstr "Regjistrim Përdoruesi të Ri"
+
+#: views/users/login.thtml:90
+msgid "user_form_remember_me"
+msgstr "Mbamë mend në këtë kompjuter"
+
+#: views/admin/users_edit.thtml:95
+msgid "user_form_showsandbox"
+msgstr "Të shfaq bankoprovën?"
+
+#: views/users/edit.thtml:205
+msgid "user_form_submit_edit"
+msgstr "Ruaj"
+
+#: views/users/login.thtml:93
+msgid "user_form_submit_login"
+msgstr "Hyrje"
+
+#: views/users/register.thtml:113
+msgid "user_form_submit_register"
+msgstr "Regjistrohuni"
+
+#: views/users/info.thtml:75
+#, php-format
+msgid "user_info_usersince"
+msgstr "Përdorues Shtesash %s që prej"
+
+#: views/users/login.thtml:102
+msgid "user_login_register_link"
+msgstr "Krijoni një llogari përdoruesi të re"
+
+#: views/users/edit.thtml:160
+msgid "user_notifications_item_compat"
+msgstr "Përputhshmëri Shtese (këshillohet me forcë)"
+
+#: views/users/edit.thtml:161
+msgid "user_notifications_item_events"
+msgstr "Veprimtare dhe konkurse"
+
+#: views/users/edit.thtml:156
+msgid "user_notifications_none_available"
+msgstr "Nuk ka njoftime që të mund t'i formësoni."
+
+#: views/users/edit.thtml:158
+msgid "user_notifications_select_topics"
+msgstr ""
+"Mozilla mund t'ju dërgojë, herë pas here, email rreth versionesh të ardhshëm "
+"dhe veprimtari që lidhen me shtesat. Ju lutem përzgjidhni më poshtë temat që "
+"ju interesojnë:"
+
+#: views/users/edit.thtml:164
+msgid "user_notifications_specific_contact"
+msgstr ""
+"Mozilla ruan të drejtën të lidhet me ju veçmas lidhur me çështje të caktuara "
+"te shtesat që keni strehuar këtu."
+
+#: controllers/users_controller.php:543
+msgid "user_profile_edit_error"
+msgstr ""
+"Pati gabime në ndryshimet që bëtë. Ndreqini, ju lutem, dhe riparashtrojini..."
+
+#: controllers/users_controller.php:540
+msgid "user_profile_saved"
+msgstr "Profili u përditësua."
+
+#: views/users/pwreset.thtml:65
+#, php-format
+msgid "user_pwreset_for_email"
+msgstr "Ricaktim fjalëkalimi për %s"
+
+#: controllers/users_controller.php:226
+msgid "user_pwreset_header"
+msgstr "Ricaktim Fjalëkalimi"
+
+#: views/users/login.thtml:103
+msgid "user_pwreset_link"
+msgstr "Harruat fjalëkalimin tuaj?"
+
+#: controllers/users_controller.php:248
+msgid "user_pwreset_link_sent"
+msgstr ""
+"Lidhja për ricaktim fjalëkalimi ju dërgua te vendndodhja email e juaja."
+
+#: controllers/users_controller.php:304
+msgid "user_pwreset_okay"
+msgstr "Fjalëkalim i ricaktuar me sukses."
+
+#: views/users/pwreset.thtml:82
+msgid "user_pwreset_submit_changepw"
+msgstr "Parashtroni ndryshim fjakëlalimi"
+
+#: views/users/pwreset.thtml:57
+msgid "user_pwreset_submit_sendlink"
+msgstr "Dërgo lidhje ricaktimi fjalëkalimi"
+
+#: views/users/register_complete.thtml:51
+#, php-format
+msgid "user_register_amo_link"
+msgstr "Shtesa %s"
+
+#. %1 is the user's email address, %2 is the current app
+#: views/users/activatefirst.thtml:49
+#, php-format
+msgid "user_register_click_confirm_link"
+msgstr ""
+"Ju dërguam me email lidhjen për aktivizimin e llogarisë suaj të përdoruesit "
+"te vendndodhja juaj %1$s. Duhet ta klikoni përpara se të hyni te Shtesa %2$s."
+
+#. %1 is the user's email address
+#: views/users/register_complete.thtml:49
+#, php-format
+msgid "user_register_confirm_email_sent"
+msgstr ""
+"Ju dërguam email te vendndodhja juaj %1$s që të ripohoni llogarinë tuaj. "
+"Përpara se të hyni, duhet ta aktivizoni llogarinë tuaj duke klikuar mbi "
+"lidhjen e dhënë në këtë email."
+
+#: views/users/activatefirst.thtml:51
+msgid "user_register_confirmation_link_text"
+msgstr "ridërgo mesazhin e ripohimit"
+
+#: views/users/register_complete.thtml:47
+msgid "user_register_congratulations"
+msgstr "Përgëzime! Llogaria juaj e përdoruesit u krijua me sukses."
+
+#: views/users/register.thtml:50
+msgid "user_register_details"
+msgstr ""
+"<p>Regjistrimi te AMO <strong>nuk është i domosdoshëm</strong> po qe se "
+"thjesht doni të shkarkoni dhe instaloni një shtesë publike.</p><p>Lypset të "
+"regjistroheni vetëm po qe se:</p><ul><li>Dëshironi të parashtroni shqyrtime "
+"për shtesa</li><li>Jeni zhvillues shtese dhe doni të ngarkoni shtesën tuaj "
+"për strehim te AMO</li></ul><p>Pas regjistrimit me sukses, do t'ju dërgohet "
+"një email ripohimi te vendndodhja që dhatë. Ju lutem ndiqni udhëzimet e "
+"atjeshme për të ripohuar llogarinë tuaj.</p><p>Nëse doni, mund të lexoni our "
+"<a href='%1$s' title='Legal Notices'>Shënimet Ligjore</a> dhe <a href='%2$s' "
+"title='Privacy Policy'>Rregullat e Vetësisë</a> tonat.</p>"
+
+#. %1 is the link to the "resend confirmation code" page
+#: views/users/activatefirst.thtml:51
+#, php-format
+msgid "user_register_resend_confirmation_link"
+msgstr ""
+"Nëse nuk morët email ripohimi, sigurohuni që shërbimi email nuk e ka shënuar "
+"\"postë hedhurinë\" ose \"spam\". Nëse e shihni të nevojshme, mund t'ju %1$s "
+"te vendndodhja juaj email e përmendur më sipër."
+
+#. %1 is the link to the Mozilla Add-ons front page
+#: views/users/register_complete.thtml:51
+#, php-format
+msgid "user_register_welcome"
+msgstr "Faleminderit që u regjistruat dhe mirësevini te %1$s!"
+
+#: views/users/register.thtml:49
+msgid "user_register_welcome_header"
+msgstr "Mirë se vini te addons.mozilla.org (AMO)!"
+
+#: views/users/register.thtml:81 views/users/edit.thtml:106
+msgid "user_required_firstlast_or_nickname"
+msgstr "Lypset një emër, mbiemër ose nofkë."
+
+#: views/users/edit.thtml:94 views/users/edit.thtml:142
+#, fuzzy
+msgid "user_tab_collections"
+msgstr "Collections"
+
+#: views/users/edit.thtml:95 views/users/edit.thtml:154
+msgid "user_tab_notifications"
+msgstr "Njoftime"
+
+#: views/users/edit.thtml:93 views/users/edit.thtml:101
+msgid "user_tab_profile"
+msgstr "Profil Përdoruesi"
+
+#: controllers/users_controller.php:209
+msgid "user_verified_okay"
+msgstr "Verifikuar me sukses!"
+
+#: controllers/users_controller.php:723
+msgid "users_delete_pagetitle"
+msgstr "Fshi Llogari Përdoruesi"
+
+#: controllers/users_controller.php:414
+msgid "users_edit_pagetitle"
+msgstr "Përpunim Llogarie Përdoruesi"
+
+#: views/users/info.thtml:71
+#, fuzzy
+msgid "users_info_aboutme"
+msgstr "About Me"
+
+#: views/users/info.thtml:96
+#, php-format
+msgid "users_info_addons_by_user"
+msgstr "Shtesa nga %1$s"
+
+#: views/users/info.thtml:51
+msgid "users_info_author_name"
+msgstr "Emër"
+
+#: views/users/info.thtml:48
+msgid "users_info_author_profile"
+msgstr "Profil Autori"
+
+#. %s is the user name
+#: views/users/info.thtml:137
+#, fuzzy
+msgid "users_info_collections_by_user"
+msgstr "Collections by %s"
+
+#: views/users/info.thtml:66
+msgid "users_info_email"
+msgstr "Vendndodhje email"
+
+#: views/users/info.thtml:155
+#, fuzzy
+msgid "users_info_fav_collections_by_user"
+msgstr "Favorite Collections"
+
+#: views/users/info.thtml:61
+msgid "users_info_homepage"
+msgstr "Faqe Hyrëse"
+
+#: views/users/info.thtml:56
+msgid "users_info_nickname"
+msgstr "Nofkë"
+
+#: controllers/users_controller.php:707
+#, php-format
+msgid "users_info_pagetitle"
+msgstr "Të dhëna Përdoruesi për %1$s"
+
+#. %1 is the user's name
+#: views/users/info.thtml:116
+msgid "users_info_reviews_by_user"
+msgstr "Shqyrtime nga %s"
+
+#: controllers/users_controller.php:330 controllers/users_controller.php:332
+msgid "users_login_pagetitle"
+msgstr "Hyrje përdoruesi"
+
+#. %1 is the link to the sandbox/policy explanation page
+#. This message is for a specific add-on not found
+#: views/users/login.thtml:53
+#, php-format
+msgid "users_login_sandbox_display_warning"
+msgstr ""
+"Shtesa që po kërkoni ndodhet në bankoprovë hëpërhë. Nëse keni tashmë një "
+"llogari te Shtesat Mozilla, ju lutem hyni në të, ose <a href=\"%1$s\">mësoni "
+"më tepër rreth bankoprovës.</a>"
+
+#. %1 is the link to the sandbox/policy explanation page
+#. This message is for any given sandbox-related page not found
+#: views/users/login.thtml:56
+#, php-format
+msgid "users_login_sandbox_page_warning"
+msgstr ""
+"Faqja që po kërkoni është pjesë e bankoprovës. Nëse keni tashmë një llogari "
+"te Shtesat Mozilla, ju lutem hyni në të, ose <a href=\"%1$s\">mësoni më "
+"tepër rreth bankoprovës.</a>"
+
+#: controllers/users_controller.php:223 controllers/users_controller.php:225
+msgid "users_pwreset_pagetitle"
+msgstr "Ricaktim Fjalëkalimi Përdoruesi"
+
+#: controllers/users_controller.php:90 controllers/users_controller.php:92
+msgid "users_register_pagetitle"
+msgstr "Regjistrim Përdoruesi të Ri"
+
+#. %1$s is an addon name, like <a>Firebug</a>
+#. %2$s is a version number, like <a>1.2</a>
+#: views/versions/license.thtml:52
+#, fuzzy
+msgid "versions_license_header_source"
+msgstr "Source code license for %1$s %2$s"
+
+#: views/addons/category_landing.thtml:147
+#, fuzzy
+msgid "view_recently_added"
+msgstr "View all recently added"
+
+#: views/addons/category_landing.thtml:161
+#, fuzzy
+msgid "view_top_downloads"
+msgstr "View all top downloads"
+
+#: views/addons/category_landing.thtml:175
+#, fuzzy
+msgid "view_top_rated"
+msgstr "View all top rated"
diff --git a/site/app/locale/sq/images/sandbox-review.png b/site/app/locale/sq/images/sandbox-review.png
new file mode 100644
index 0000000..2150442
--- /dev/null
+++ b/site/app/locale/sq/images/sandbox-review.png
Binary files differ
diff --git a/site/app/locale/sq/pages/about.thtml b/site/app/locale/sq/pages/about.thtml
new file mode 100644
index 0000000..c721f11
--- /dev/null
+++ b/site/app/locale/sq/pages/about.thtml
@@ -0,0 +1,56 @@
+<h2>Ç'është addons.mozilla.org?</h2>
+<p>
+ addons.mozilla.org (AMO) është <i>site</i>-i zyrtar i Mozilla-s për shtesa për zbatimet Mozilla.
+ Shtesat ju lejojnë të shtoni veçori të reja te Firefox-i, Thunderbird-i,
+ SeaMonkey-i, dhe Sunbird-i. Prej AMO-s, mund të shfletoni dhe shkarkoni mijëra shtesa
+ për të ndryshuar mënyrën se si e përdorni internetin.
+</p>
+
+<h2>Kush i krijon këto shtesa?</h2>
+<p>
+ Mijëra zhvillues shtesash që shtrihen nga hobistë individualë te korporatat e mëdha.
+ Tërë shtesat publike shqyrtohen nga një ekip vullnetarësh të përkushtuar përpara se të hidhen në qarkullim. Shtesat eksperimentale shënohen si të tilla dhe nuk shqyrtohen.
+</p>
+
+<h2>Si të jem në dijeni se ç'bëhet te AMO?</h2>
+<p>
+ <a href="http://blog.mozilla.com/addons/">Blogu</a> ynë përditësohet rregullisht,
+ dhe shpesh përmban postime prej bashkësisë së përdoruesve. Kemi po ashtu edhe një
+ <a href="https://addons.mozilla.org/newsletter">buletin</a> i cili dërgohet çdo muaj.
+</p>
+
+<h2>Jo keq! Si të marr pjesë?</h2>
+<p>
+ Ka mjaft rrugë për të marrë pjesë:
+</p>
+<ul>
+ <li>
+ <a href="https://wiki.mozilla.org/AMO:Editors/Applying">Bëhuni një redaktor</a>. Redaktorët tanë janë dashamirës të AMO-s me njohuri teknike që shqyrtojnë shtesat lidhur me cilësinë dhe qëndrueshmërinë e kodit.
+ </li>
+ <li>
+ <a href="http://developer.mozilla.org/">Krijoni shtesën tuaj</a>. AMO
+ ofron shërbime falas strehimi dhe përditësimi dhe mund t'ju ndihmojë të zgjeroni rrethin e përdoruesve.
+ </li>
+ <li>
+ Tregojuani miqve tuaj! <a href="http://spreadfirefox.com/">Spread Firefox</a>
+ dhe tregojuni njerëzve cilat shtesa përdorni.
+ </li>
+ <li>
+ Parashtroni të meta dhe ndreqje për to.
+ <a href="https://bugzilla.mozilla.org/buglist.cgi?quicksearch=addons">Bugzilla</a>
+ përmban tërë të metat tona AMO të tanishme. Mund të parashtroni një që nuk është hasur ende dhe të jepni mndihmesë duke ndrequr ato.
+ </li>
+</ul>
+
+<h2>Kam një pyetje.</h2>
+<p>
+ Një vend i përshtatshëm për t'ia nisur është ndarja jonë
+ <a href="https://addons.mozilla.org/pages/faq"><abbr title="Frequently Asked Questions">FAQ</abbr></a>. Nëse nuk gjeni përgjigje atje, përdorni të dhëna kontaktesh në fund të kësaj faqeje. Për pyetje rreth një shtesë të caktuar përdorni të dhëna kontakti te faqja e secilës shtesë.
+</p>
+
+<h2>Lidhuni Me Ne</h2>
+<dl>
+ <dt>Përmes <abbr title="Internet Relay Chat">IRC</abbr>:</dt>
+ <dd><a href="irc://irc.mozilla.org/#addons">#addons</a> te irc.mozilla.org për pyetje të përgjithshme dhe pyetje rreth shqyrtimesh</dd>
+ <dd><a href="irc://irc.mozilla.org/#amo">#amo</a> te irc.mozilla.org për çështje administrative apo zhvillimi</dd>
+</dl>
diff --git a/site/app/locale/sq/pages/collector_features.thtml b/site/app/locale/sq/pages/collector_features.thtml
new file mode 100644
index 0000000..6752666
--- /dev/null
+++ b/site/app/locale/sq/pages/collector_features.thtml
@@ -0,0 +1,29 @@
+<p>
+ Grumbulluesi i Shtesave ju mban në lidhje me shtesat tuaja të parapëlqyera dhe koleksione për to në disa rrugë:
+</p>
+
+<dl>
+ <dt>Hyni prej Firefox-it te koleksionet tuaj të parapëlqyer</dt>
+ <dd>
+ Koleksionet që u vini shenjë si të parapëlqyer te
+ <a href="%1$s">Lista e Koleksioneve</a> shfaqen në një vend special të
+ Përgjegjësit të Shtesave. Do të jeni në gjendje të përditësoni dhe shihni përmbajtjen
+ e secilit koleksion.
+ </dd>
+ <dt>Ndajini shtesat me të tjerët duke përdorur Menunë e Botimit</dt>
+ <dd>
+ Çdo shtesë që instaloni mund t'i jepet kollaj një shoku përmes e-mail-it ose
+ duke e botuar te një nga koleksionet tuaj përmes menusë së botimeve.
+ </dd>
+ <dt>Merrni njoftime</dt>
+ <dd>
+ Grumbulluesi do t'ju njoftojë kur ndonjë nga koleksionet tuaj të parapëlqyer ka të reja,
+ dhe do t'i vërë shenjë që ta shqyrtoni më vonë.
+ </dd>
+
+ <dt>Botoni vetvetiu te një koleksion shtesat tuaja të instaluara</dt>
+ <dd>
+ Funksioni i vetëbotimit i mban koleksionet tuaja vazhdimisht të përditësuar me
+ shtesat tuaja më të fundit, duke mbajtur në dijeni miqtë tuaj të pajtuar në to.
+ </dd>
+</dl>
diff --git a/site/app/locale/sq/pages/compatibility_developer_tips.thtml b/site/app/locale/sq/pages/compatibility_developer_tips.thtml
new file mode 100644
index 0000000..1d3a06a
--- /dev/null
+++ b/site/app/locale/sq/pages/compatibility_developer_tips.thtml
@@ -0,0 +1,6 @@
+<ul class="tips">
+ <li>Të dhëna rreth përditësimit të shtesave tuaja për %s mund të gjenden në këtë <a href="https://developer.mozilla.org/En/Updating_extensions_for_%s">artikull te Mozilla Developer Center</a>.</li>
+ <li>Të dhëna mbi ndryshimet në përgjithësi te %s mund të gjenden në <a href="https://developer.mozilla.org/en/%s_for_developers">këtë artikull</a>.</li>
+ <li>Mund të pajtoheni te <a href="https://addons.mozilla.org/newsletter">about:addons newsletter</a> dhe <a href="http://blog.mozilla.com/addons/">blogu i Shtesave të Mozilla-s</a> për më tepër njoftime rreth përditësimesh.</li>
+ <li>Po qe se shtesa juaj nuk lyp ndryshime në kod, për të pretenduar për përputhshmëri dhe gjendet te Shtesat Mozilla, mund t'ia rrisni versionin më të madh të përputhshmërisë (maxVersion) "online" pa ngarkuar një kartelë të re duke u drejtuar te <a href="%s">zona Mjete Zhvilluesish</a> ose duke parë gjendjen e saj më poshtë.</li>
+</ul>
diff --git a/site/app/locale/sq/pages/compatibility_user_tips.thtml b/site/app/locale/sq/pages/compatibility_user_tips.thtml
new file mode 100644
index 0000000..e84e268
--- /dev/null
+++ b/site/app/locale/sq/pages/compatibility_user_tips.thtml
@@ -0,0 +1,6 @@
+<ul class="tips">
+ <li>Edhe pse mjaft shtesa mund të mbulojnë ndryshimet në %s pa ndonjë ndryshim në kod, të tjera mund të duan punë shtesë nga autori për të bërë të mundur përmirësim të lëmuar. Ju lutem jini të durueshëm gjatë kësaj kohe, meqë shumë nga zhvilluesit e shtesave i mirëmbajnë shtesat e tyre vullnetarisht, si hobi.</li>
+ <li>Mozilla është kundër çaktivizimit të rregullimeve mbi kontrollin e përputhshmërisë, ngaqë kjo mund të shpjerë në probleme serioze në nisjen e %s-it dhe madje humbje të dhënash, po qe se përdoret një zgjerim i papërputhshëm karshi një versioni të ri të %s-it.</li>
+ <li>Po qe se zgjerimi që po provoni të përdorni mbetet i papërputhshëm pas hedhjes në qarkullim të %s-it, mund të shihni te <i>site</i>-i i vet web ose te faqja e autorit për ndonjë lajm lidhur me përditësimin.</li>
+ <li>Mundet edhe të doni të kërkoni te <i>site</i>-i web <a href="%s">Shtesa %s-i</a> për ndonjë shtesë me funksione të ngjashme e që mbulohet nga %s-i.</li>
+</ul>
diff --git a/site/app/locale/sq/pages/developer_faq.thtml b/site/app/locale/sq/pages/developer_faq.thtml
new file mode 100644
index 0000000..bc9c2b8
--- /dev/null
+++ b/site/app/locale/sq/pages/developer_faq.thtml
@@ -0,0 +1,62 @@
+<h2>REFERENCA RRETH LEJESH BURIMI TË HAPUR</h2>
+<p>
+ A keni nevojë për të tepër të dhëna rreth lejeve të ndryshme për burim të hapur? Jeni
+ i paqartë mbi cilën leje do duhej të zgjidhnit? Çfarë të drejtash jep një leje e caktuar?
+ Ndërkohë që asgjë nuk e zëvendëson leximin e plotë të kushteve të një lejeje,
+ më poshtë do të gjeni disa <i>site</i>-e që përmbajnë të dhëna rreth disa lejesh kyçe për burim të hapur,
+ të cilat mund t'ju ndihmojnë të kuptoni dallimet mes tyre. Këta
+ <i>site</>-e sillen këtu thjesht për lehtësinë tuaj dhe si referencë për
+ përdorim personal. Këto burime nuk përbëjnë këshillim ligjor, e as duhen përdorur
+ në vend të një këshillimi të tillë. Mozilla as garanton, e as është përgjegjëse
+ për përmbajtjen e këtyre <i>site</i>-eve ose peshën që i jepni përmbajtjes në fjalë.
+</p>
+<dl>
+ <dt>
+ <a href="http://www.mozilla.org/MPL/">http://www.mozilla.org/MPL/</a>
+ </dt>
+ <dd>
+ Veç tekstit të plotë të Lejes Publike Mozilla (Mozilla Public License - &#8220;MPL&#8221;),
+ këtu do të gjeni një version me shpjegime të MPL-së dhe një
+ <abbr title="Frequently Asked Questions">FAQ</abbr>, për t'ju ndihmuar po qe se doni të përdorni
+ apo shpërndani kod të lejuar sipas saj.
+ </dd>
+ <dt>
+ <a href="http://developer.kde.org/documentation/licensing/licenses_summary.html">
+ http://developer.kde.org/documentation/licensing/licenses_summary.html
+ </a>
+ </dt>
+ <dd>
+ Një tabelë përmbledhëse dhe krahasuese se si disa nga lejet kyçe për burim të hapur
+ trajtojnë shpërndarjet, lidhjen te <i>software</i> pronësor, dhe rishpërndarjen e kodit
+ me ndryshime.
+ </dd>
+ <dt>
+ <a href="http://www.fsf.org/licensing/licenses/">
+ http://www.fsf.org/licensing/licenses/
+ </a>
+ </dt>
+ <dd>
+ Free Software Foundation jep përmbledhje të shkurtra të lejeve kyçe për burim të hapur,
+ përfshi hollësi nëse leja hyn te lejet për <i>software</i> të lirë apo
+ leje <i>copyleft</i>. Përfshin po ashtu një diskutim rreth se çfarë është
+ leja për <i>software</i> të lirë ose leja <i>copyleft</i> (p.sh., leja <i>copyleft</i> është
+ metodë e përgjithshme për ta bërë një program ose një vepër tjetër të lirë, dhe që kërkon që
+ po kështu të jenë edhe tërë versionet e ndryshuar dhe të zgjeruar të programit.)
+ </dd>
+ <dt>
+ <a href="http://www.opensource.org/licenses/category">
+ http://www.opensource.org/licenses/category
+ </a>
+ </dt>
+ <dd>
+ Open Source Initiative ofron kushtet e disa prej lejeve kyçe për burim të hapur.
+ </dd>
+ <dt>
+ <a href="http://en.wikipedia.org/wiki/Open_source_license">
+ http://en.wikipedia.org/wiki/Open_source_license
+ </a>
+ </dt>
+ <dd>
+ Diskutim Wikipedia i lejeve në stil BSD.
+ </dd>
+</dl>
diff --git a/site/app/locale/sq/pages/error404.thtml b/site/app/locale/sq/pages/error404.thtml
new file mode 100644
index 0000000..cd66d1c
--- /dev/null
+++ b/site/app/locale/sq/pages/error404.thtml
@@ -0,0 +1,17 @@
+<h1>Na vjen keq, por s’gjejmë dot çfarë po kërkoni.</h1>
+
+<p>Faqja apo kartela që kërkuar s'u gjet në <i>site</i>-in tonë. Ka të ngjarë që klikuat mbi një lidhje
+ e cila është vjetëruar, ose vendndodhjen e shtypët pasaktësisht.</p>
+
+<ul>
+<li>Nëse e shtypët ju vendndodhjen, ju lutemi kontrolloni sërish drejtshkrimin.</li>
+<li>Nëse ndoqët një lidhje prej diku, ju lutem na vini në dijeni te <a href="mailto:webmaster@mozilla.com" title="Page Not Found on Mozilla.com">webmaster@mozilla.com</a>. Tregonani se prej nga jeni dhe se për çfarë po kërkonit, dhe do të bëjmë ç'është e mundur për ta ndrequr.</li>
+</ul>
+
+<p>Ose thjesht mund të hidheni te disa prej faqeve popullore të <i>site</i>-it tonë web.</p>
+
+<ul>
+<li>Ju intereson një <a href="%1$s">listë shtesash popullore</a>?</li>
+<li>Doni të <a href="%2$s">të kërkoni për shtesa</a>? Mund të shkoni te <a href="%2$s">faqja për kërkime</a> ose thjesht përdorni për kërkime fushën më sipër.</li>
+<li>Nëse parapëlqeni t'ia rinisni nga e para, thjesht kaloni te <a href="%3$s">faqja ballore e shtesave</a>.</li>
+</ul>
diff --git a/site/app/locale/sq/pages/experimental_addons.thtml b/site/app/locale/sq/pages/experimental_addons.thtml
new file mode 100644
index 0000000..c46934b
--- /dev/null
+++ b/site/app/locale/sq/pages/experimental_addons.thtml
@@ -0,0 +1,24 @@
+<h1>Shtesë Eksperimentale</h1>
+
+
+<h2>Ç'është shtesa eksperimentale?</h2>
+
+<p>Shtesat eksperimentale janë për përdorues të përparuar, që këta të vënë në provë shtesat përpara se të jepen për përdorim dhe shqyrtim të gjerë. Mjaft shtesa mund të jenë në formë fillestare. Shtesat eksperimentale mund të jenë alfa, beta ose para-prodhim për sa i përket cilësisë, punimit dhe veçorive.</p>
+
+<p>Duhet bërë kujdes kur instalohen shtesa eksperimentale, meqë këto nuk janë vënë në provë nga ndonjë redaktor dhe mund të dëmtojnë formësimin e kompjuterit tuaj.</p>
+
+
+<h2>Nga ta kuptoj që një shtesë është eksperimentale kur shoh një shtesë te <i>site</i>?</h2>
+
+<p>Shtesat eksperimentale kanë një shenjë "eksperimentale" dhe duhet të keni bërë hyrje përpara se të instaloni një të tillë.</p>
+
+
+<h2>Pse duhet të kem bërë hyrjen që të mund të instaloj një shtesë eksperimentale?</h2>
+
+<p>Te <i>site</i>-i është e domosdoshme që përdoruesit të kenë bërë hyrjen, që të mund të instalojnë shtesa eksperimentale, si kujtesë që jeni duke marrë përsipër një hap me rrezik.</p>
+
+
+<h2>Është e domosdoshme të bëj hyrjen apo a kam nevojë për një llogari këtu, që të mund të instaloj nëj shtesë publike?</h2>
+
+<p>Jo. Te <i>site</i>-i i shtesave nuk është e domosdoshme të keni një llogari përdoruesi ose të bëni hyrjen për të mundur të instaloni një shtesë publike.</p>
+
diff --git a/site/app/locale/sq/pages/faq.thtml b/site/app/locale/sq/pages/faq.thtml
new file mode 100755
index 0000000..2a30b19
--- /dev/null
+++ b/site/app/locale/sq/pages/faq.thtml
@@ -0,0 +1,78 @@
+<h1>Pyetje të Bëra Shpesh</h1>
+
+<p>Këto Pyetje të Bëra Shpesh për <a href="http://addons.mozilla.org">site-in e AMO-s</a> trajtojnë disa tema që nuk preken hëpërhë te <i>site</i>-i i Asistencës për Firefox-in. <i>Site</i>-i i Asistencës përfshin të dhëna fillesë rreth <a href="http://support.mozilla.com/kb/Customizing+Firefox+with+add-ons">përshtatjes së Firefox-it me shtesa</a> si edhe artikuj mbi:</p>
+
+<ul>
+ <li> Diagnostikimin <a href="http://support.mozilla.com/kb/Unable+to+install+add-ons">e instalimit të shtesave</a>, <a href="http://support.mozilla.com/kb/Troubleshooting+plugins">shtojcat</a> &amp; <a href="http://support.mozilla.com/kb/Troubleshooting+extensions+and+themes">probleme të përgjithshme</a>.</li>
+ <li> <a href="http://support.mozilla.com/kb/Uninstalling+add-ons">Si të çinstalohet një shtojcë</a> dhe <a href="http://support.mozilla.com/kb/Cannot+uninstall+an+add-on">të diagnostikohet çinstalimi</a>.</li>
+ <li> <a href="http://support.mozilla.com/kb/Gray+bar+below+the+status+bar">Trajtimi i shtesave problematike / çështja Gray Bar</a></li>
+</ul>
+
+<p></p>
+
+<div id="gsfn_list_widget">
+ <a href="https://getsatisfaction.com/mozilla" class="widget_title">Diskutime mbi shërbim klientësh rreth Shtesave Mozilla</a>
+ <div id="gsfn_content">Po ngarkohet...</div>
+ <div class="powered_by">
+ <a href="https://getsatisfaction.com/"><img alt="Favicon" src="https://www.getsatisfaction.com/favicon.gif" style="vertical-align: middle;" /></a>
+ <a href="https://getsatisfaction.com/">Rrjeti i asistencës "Get Satisfaction"</a>
+ </div>
+</div>
+
+<h2>Pyetje rreth Shtesash</h2>
+<dl class="faq">
+<dt>Ç'janë shtesat?</dt>
+<dd>Shtesat ju lejojnë të veçori që nuk janë pjesë e zbatimit standard. Temat ndryshojnë pamjen pa ndryshuar funksionet. Shtojca Kërkimesh dhe Fjalorë/Paketa Gjuhësore shtojnë motorë kërkimesh dhe mbulim gjuhësh. Zgjerimet shtojnë te shfletuesi veçori më të thella; disa shtojnë panele të thjeshtë, ndërkohë që të tjerat mund të shtojnë një gamë të gjerë veçorish të reja.</dd>
+
+<dt>A janë të lehta për t'u instaluar shtesat?</dt>
+<dd>Po! Shtesat janë shumë të lehta për t'u instaluar. Përgjithësisht janë shumë më të vogla se një zbatim i zakonshëm dhe shkarkohen shumë shpejt. Po qe se nuk ju pëlqen, po kaq kollaj është të hiqet apo çaktivizohet. Gjithashtu, po qe se ka të passhëm një përditësim për një nga shtesat tuaja, Firefox-i do t'ju njoftojë dhe lejojë përditësim me një klikim.</dd>
+
+<dt>Si ta administroj një shtesë?</dt>
+<dd>Te Firefox-i, për administrim Temash dhe Zgjerimesh, shkoni te "Shtesa" te menuja Mjete. Po qe se Zgjerimi juaj ka mundësi speciale, mund t'i shihni ato te ndarja Zgjerime e dritares Shtesa. Prej andej, mundeni po ashtu të çaktivizoni dhe çinstaloni shtesa. Fjalorët instalohen si Zgjerime. Shtojcat për Kërkim mund të administrohen te Paneli i Kërkimeve.</dd>
+
+<dt>A mund ta ngadalësojnë shtesat Firefox-in?</dt>
+<dd>Në shumicën e rasteve, nuk shkaktojnë ngadalësim të perceptueshëm të Firefox-it. Megjithatë, meqë janë zbatime, ndonjë prej tyre mund të prekë punimin e Firefox-it, varet nga formësimi i sistemit në fjalë. nëse dyshoni se një shtesë po prek xhirimin e Firefox-it, provoni ta çaktivizoni.</dd>
+
+<dt>Pse do të duhej ta çaktivizoj një shtesë?</dt>
+<dd>Çaktivizimi i një shtese pengon ngarkimin e saj kur nisni Firefox-in, por nuk heq shtesën apo ndonjë nga rregullimet për të. Aktivizimi sërish i shtesës do ta kthejë atje ku qe kur e çaktivizuat. Për shtesa që doni të heshtin pa i hequr, çaktivizimi është rruga e duhur.</dd>
+
+<dt>Si të bëj një kopjeruajtje të shtesave dhe temave që kam instaluar?</dt>
+<dd>Kopjeruajtja e drejtorisë së profilit tuaj do të bëjë një kopjeruajtje edhe të shtesave dhe temave tuaja. Një zbatim nga palë të treta, si MozBackup për shembull, mund t'ju ndihmonte për këtë po ashtu.</dd>
+</dl>
+
+<h2>Pyetje rreth Website-it</h2>
+<dl class="faq">
+<dt>Shof shtesa të ndryshme për të njëjtën punë. Si të vendos se cila është më e mira?</dt>
+<dd>Përgjithësisht, mund të hidhni një sy te vlerësimet dhe shkarkimet, që japin një ide. Shtesat e mira kanë prirjen të kenë më shumë shkarkime se ato të këqiat. Sidoqoftë, është kollaj të instalohen të dy palët dhe të vendosni vetë kë të përdorni. Mundet edhe që pas provës të vendosni t'i mbani të dyja për përdorim!</dd>
+
+<dt>Më kapi syri një shtesë të fortë, por thotë që është e përputhshme vetëm me Firefox 2.x. Nuk e instaloj dot për Firefox 3.x?</dt>
+<dd>Në përgjithësi, jo. Firefox 3.x ka një numër veçorish të reja dhe një shumicë e madhe e zhvilluesve të shtesave i kanë përditësuar shtesat e tyre që të punojnë nën 3.x. Po qe se shtesa mbulon vetëm Firefox 2, provoni të bëni një kërkim për tiutllin e shtesës. Në mjaft raste ka për të pasur një version të ri që mbulon Firefox 3-in, me të njëjtin titull ose të ngjashëm.</dd>
+
+<dt>Instalova një temë të re por do të doja të kthehem mbrapsht te tema parazgjedhje e Firefox-it. Si bëhet?</dt>
+<dd>Shkoni te "Shtesa" te menuja "Mjete". Klikoni te ndarja "Tema" dhe prej andej mund të përzgjidhni temën parazgjedhje, ose cilëndo tjetër që keni instaluar.</dd>
+
+<dt>Po qe se kam problem me një shtesë, duhet të lidhem me Mozilla-n?</dt>
+<dd>Shtesa, me pak përjashtime, krijohen nga një bashkësi dhe jo nga Mozilla. Gjëja më e mirë që mund të bëhet është të lidheni drejtpërsëdrejti me zhvilluesin për pyetjen tuaj. Për gjetje të dhënash kontakti për një zhvillues, klikoni mbi merin e tyre te rreshti i faqes ku radhitet Shtesa.</dd>
+
+<dt>Si shqyrtohen shtesat?</dt>
+<dd>Shtesat publiket shqyrtohen nga ekipi ynë i përkushtuar dhe i talentuar redaktorial. Prej tyre shqyrtohet kodi i tërë shtesave publike si dhe provohen shtesat për t'u siguruar që përshkruhen si duhet.</dd>
+
+<dt>Kalova te Firefox 3.5 or shtesa ime nuk punon më? Pse ndodh kjo?</dt>
+<dd>Shumica e shtesave tona tani janë gati për Firefox 3.5, dhe përditë shtohen të tjera. Po qe se shtesa juaj punonte nën 3.0, por jo më nën 3.5, ka gjasa që të jenë duke e ripunuar. Kur mbarojnë përmirësimin e një shtese, Firefox-i do t'ju njoftojë rreth përmirësimit.</dd>
+
+<dt id="experimental-addons">Ç'janë shtesat eksperimentale?</dt>
+<dd>
+ <p>Shtesat eksperimentale janë shtesat më të rej, të cilat nuk kanë kaluar ende në procesin tonë të shqyrtimit publik. Mjaft prej këtyre shtesave mund të jenë në gjendje prototipi. Meqë janë të pavëna në provë nga ekipi ynë redaktorial, mund të jenë alfa, beta ose pre-prodhim për sa i takon cilësisë, punimit dhe veçorive.</p>
+ <p>Duhet bërë kujde kur instalohen shtesa eksperimentale, ngaqë nuk janë provuar ende nga një redaktor dhe mund të dëmtojnë formësimin e kompjuterit tuaj.</p>
+</dd>
+
+<dt id="recognizing-experimental-addons">Nga ta kuptoj që një shtesë është eksperimentale, kur kam përpara një të tillë te <i>site</i>-i?</dt>
+<dd>Shtesat eksperimentale shënohen me etiketën "eksperimentale" dhe shfaqin një sinjalizim kur i instaloni.</dd>
+
+<dt id="recommended-addons">Cilat janë shtesat e Këshilluara?</dt>
+<dd>Ekipi i AMO-s këshillon një grup shtesash të cilat paraqesin disa nga shtesat më të mira, përsa i takon dobisë dhe punimit në përgjithësi. Këto shtesa të këshilluara duken te faqja e secilës kategori. Disa nga këto shtesa shfaqen njëra pas tjetrës te faqja hyrëse e AMO-s si shtesat e Këshilluara. Kuptohet që kjo në asnjë mënyrë nuk është listë e plotë dhe përfundimtare, dhe ne e përditësojmë listëm çdo muaj, për të vazhduar t'u tregojmë përdoruesve tanë një grup të freskët shtesash. Ca nga gjërat që kemi në mendje kur këshillojmë shtesat: cilësia, popullariteti, të qenët unike, dhe faktin nëse është këshilluar a jo tashmë.</dd>
+
+</dl>
+
+<script src="https://getsatisfaction.com/mozilla/widgets/javascripts/500b6b4141/widgets.js" type="text/javascript"></script>
+<script src="https://getsatisfaction.com/mozilla/topics.widget?callback=gsfnTopicsCallback&amp;limit=5&amp;product=mozilla_mozilla_add_ons&amp;sort=last_active_at&amp;style=topics" type="text/javascript"></script>
diff --git a/site/app/locale/sq/pages/fashion_faq.thtml b/site/app/locale/sq/pages/fashion_faq.thtml
new file mode 100644
index 0000000..ff5f62f
--- /dev/null
+++ b/site/app/locale/sq/pages/fashion_faq.thtml
@@ -0,0 +1,72 @@
+<h1>FAQ për "Fashion Your Firefox":</h1>
+
+<h2>Ç'është "Fashion Your Firefox"?</h2>
+<p>Firefox-i ju ofron më shumë rrugë se kushdo tjetër për ta përshtatur punimin tuaj online,
+duke ju lejuar ta sajoni shfletuesin tuaj sipas mënyrës që përdorni Web-in.
+"Fashion Your Firefox" është një zbatim i thjeshtë Web me të cilin mund të përshtasni Firefox-in
+tuaj mbi bazën e interesave dhe veprimtarive tuaja online. "Fashion Your Firefox"
+ju ndihmon të përzgjidhni shtesat që ju hyjnë në punë, dhe ju bën të mundur t'i instaloni thjesht me një klikim.</p>
+
+<h2>Ç'janë shtesat?</h2>
+<p>Shtesat e Firefox-it janë copëza të vockla <i>software</i>-i që shtojnë te shfletuesi juaj veçori ose funksione të reja. Shtesat zgjerojnë Firefox-in, duke ju lejuar ta sajoni shfletuesin tuaj të përputhet me nevojat dhe shijet tuaja.  Ka mbi 5000 shtesa në pritje që t'ju ndihmojnë të bëni më tepër punë, të zbaviteni më shumë dhe të jeni më krijues <i>online</i>.</p>
+
+<h2>Ç'do të thotë "Fashion Your Firefox"?</h2>
+<p>"Fashion Your Firefox" nënkupton aftësinë e zbatimit për përshtatje, sajim,
+dhe stilizim të Firefox-it që t'i rrijë sa më mirë veprimtarive tuaja të përditshme <i>online</i>.</p>
+
+<h2>A punon "Fashion Your Firefox" me tërë versionet e Firefox-it?</h2>
+<p>Hëpërhë, "Fashion Your Firefox" është i përputhshëm vetëm me Firefox 3-in.</p>
+
+<h2>Si të shtoj shumë shtesa te koleksioni im "Fashion Your Firefox"?</h2>
+<p>"Fashion Your Firefox" do t'ju udhëheqë përmes këtij procesi të kollajtë – nuk ju duhet të shihni
+për shtesa që iu përshtaten nevojave tuaja.  Thjesht përzgjidhni shtesa te kategoritë
+që janë me interes, klikoni butonin “E dua këtë shtesë!â€, dhe përzgjidhni
+lidhjen “Klikoni këtu për t'i instaluar†ngjitur.  Do t'ju kërkohet mandej të ripohoni
+zgjedhjet tuaja dhe shfletuesi do të riniset me përzgjedhjet shtuar te
+Firefox-i juaj pa u dashur t'i shtoni një nga një. Voilà – mirë se vini te shfletuesi juaj i personalizuar.</p>
+
+<h2>A do të ndërrohen ndonjëherë shtesat e ofruara te "Fashion Your Firefox"?</h2>
+<p>"Fashion Your Firefox" është koleksioni i parë i shtesave nga një grup prej mjaft koleksionesh
+që do të mund të kihen gjatë vitit.</p>
+
+<h2>Mbi ç'bazë i zgjidhni shtesat për "Fashion Your Firefox"?</h2>
+<p>Shtesat e përfshira duhej të plotësonin kushtet e mëposhtme:</p>
+<ul>
+ <li>Të ofrojnë një grup të plotë funksionesh</li>
+ <li>Të lehta në përdorim</li>
+ <li>Popullore në kategorinë përkatëse</li>
+ <li>Të përputhshme me Firefox 3 dhe Mac/PC</li>
+</ul>
+
+<h2>Nuk më duket se po e gjej shtesën time pasi shkarkova “Fashion Your Firefox.†Ku shkoi?</h2>
+<p>Secila shtesë mund të shfaqet në vende të ndryshme te shfletuesi juaj Firefox. Disa duken si
+panele ose butona në krye të shfletuesit tuaj, disa duken si ikona në pjesën e poshtme
+të shfletuesit dhe te disa shkohet përmes menusë “Mjete†te Firefox-i.  Po qe se prapë keni probleme me gjetjen e një shtese të përzgjedhur te "Fashion Your Firefox", provoni të bëni një kërkim të shpejtë te addons.mozilla.org për të dhëna shtesë rreth se ku ta gjeni në shfletues.</p>
+
+<h2>A është e mundur të instalohet më tepër se një temë prej kategorisë “Dekorator�</h2>
+<p>Mundet të instalohet më shumë se një, por vetëm një në herë do të shfaqet.
+  Për këmbim të lehtë temash, shkoni te menuja “Mjete†te Firefox-i dhe përzgjidhni
+“Shtesa†që të shfaqet përgjegjësi i Shtesave.  Klikoni te menuja “Tema†në krye,
+klikoni mbi temën që doni të shfaqet, dhe klikoni butonin “Përdore Temënâ€.</p>
+
+<h2>Si të çinstaloj një shtesë prej koleksionit tim?</h2>
+<p>Për çinstalimin e një shtese ose teme, shkoni te menuja “Mjete†te Firefox-i dhe përzgjidhni
+“Shtesa†që të shfaqet përgjegjësi i Shtesave.  Klikoni shtesën ose temën që doni të
+çinstaloni dhe përzgjidhni “Çinstaloje.† Pasi të keni rinisur shfletuesin,
+tema ose shtesa që nuk e doni më do të jetë çinstaluar.</p>
+
+<h2>Cilat gjuhë mbulon "Fashion Your Firefox"?</h2>
+<p>Hëpërhë, "Fashion Your Firefox" është vetëm në Anglisht, por po punohet për gjuhë të tjera.</p>
+
+<h2>Unë punoj në Linux.  A do të punojë "Fashion Your Firefox" për mua?</h2>
+<p>Për fat të keq, jo tani për tani.  Hëpërhë, "Fashion Your Firefox" mbulohet vetëm nën
+kompjutera Mac dhe Windows.</p>
+
+<h2>A ka ndonjë rrugë të lehtë për ta ndarë me shokët koleksionin e shtesave "Fashion Your Firefox"?</h2>
+<p>Në këtë çast nuk ka ndonjë mënyrë që të ndani shtesat tuaja të "Fashion Your Firefox" me shokët, po kjo mund të jetë e mundshme më vonë.</p>
+
+<h2>Si mund të gjej asistencë për çfarëdo problemi tjetër me "Fashion Your Firefox"?</h2>
+<p>Mund të shini te <i>site</i>-i Mozilla i asistencës,
+<a href="http://support.mozilla.com">support.mozilla.com</a>, për asistencë të përgjithshme.  Për asistencë rreth një shtese të dhënë, ju lutem vizitoni
+<a href="http://addons.mozilla.org">addons.mozilla.org</a>.</p>
+
diff --git a/site/app/locale/sq/pages/nomination.thtml b/site/app/locale/sq/pages/nomination.thtml
new file mode 100644
index 0000000..84a7479
--- /dev/null
+++ b/site/app/locale/sq/pages/nomination.thtml
@@ -0,0 +1,16 @@
+<p>Një shtesë që për çastin është ende në bankoprovë mund të kandidojë për të qenë pjesë e
+"site"-it publik dhe e passhme për tërë përdoruesit pasi kalon nëpër shqyrtimin e një redaktori.
+Për përfundimet më të mira, ju lutem kini parasysh sa vijon:</p>
+<ul>
+ <li>Pamjet paraparje janë të nevojshme në rastin e temave dhe tejet të këshillueshme
+ për tërë tipet e tjera të shtesave</li>
+ <li>Shtesa duhet të ketë kaluar kohë të mjaftueshme në bankoprovë për të grumbulluar recensione
+ dhe përshtypje nga përdoruesit. <b>Recensionet janë të nevojshme për bërjen publike.</b></li>
+ <li>Shtesat publike kanë tra kalimi të një cilësie më të lartë sesa shtesat në bankoprovë
+ dhe duhet të zgjerojnë punimin në web të përdoruesve</li>
+ <li>Kriteret e plota për propozime mund të kihen prej <a href="%s">Rregulla Shtese</a>.</li>
+</ul>
+<p>Nëse shtesa juaj plotëson kriteret e mësipërm, mund ta kandidoni duke plotësuar fushën më poshtë.
+Rreth gjendjes së kandidaturës suaj do të njoftoheni përmes e-mail-it.</p>
+
+<p>Për të propozuar shtesën tuaj, ju lutem përshkruani se si është vënë në provë (përfshi faktin që është pa gabime dhe sinjalizime) dhe se në ç'mënyrë është e dobishme për një pjesë më të madhe të web-it. Mundeni po ashtu të jepni lidhje te recensione të jashtme për shtesën tuaj.</p>
diff --git a/site/app/locale/sq/pages/policy.thtml b/site/app/locale/sq/pages/policy.thtml
new file mode 100644
index 0000000..ef88843
--- /dev/null
+++ b/site/app/locale/sq/pages/policy.thtml
@@ -0,0 +1,115 @@
+<h1>Rregulla Shtesash</h1>
+
+<h2>Çfarë është bankoprova?</h2>
+<p>Shihni %s.</p>
+
+<h2>Cilat shtesa gjenden në bankoprovë?</h2>
+<p>Bankoprova është vendi te AMO ku strehohen tërë shtesat, si fillim. Përmban versione të rinj shtesash të botuara, si dhe tërë versionet për shtesa që nuk janë bërë ende publike. Kur parashtrohet te AMO një shtesë e re, ose një përditësim i një shtese ekzistuese, ajo vendoset në bankoprovë.</p>
+
+<p>Disa shtesa, dhe versione të caktuar të tyre, janë bërë publike pasi procesi i shqyrtimit tregon që janë gati dhe të përshtatshme për paraqitjen në publik. Shtesat e tjera do të mbesin në bankoprovë pa afat, ku janë të passhme për përdoruesit që zgjedhin të shfletojnë listën e bankoprovës dhe të eksperimentojnë me <i>software</i>-in e atyshëm..</p>
+
+<h2>Si bëhet publike një shtesë?</h2>
+
+<p>Shtesat merren në shqyrtim nga përdorues të AMO-s të cilët zgjodhën të hedhin një sy në bankoprovë dhe të marrin në provë paketat e gjendura atje. Përshtypjet e shkruajtura nga përdoruesit e AMO-s do të tregojnë nëse një shtesë është e dobishme në mënyrë të mjaftueshme, e hartuar dhe e latuar mirë për ta vënë përpara tërë përdoruesve të Firefox-it. Këto përshtypje, mundësisht bashkë me të tjera shqyrtime dhe përshtypje nga ekipi i AMO-s, përdoren për të vendosur nëse një shtesë e dhënë duhet bërë publike, apo nëse lyp më tepër punë për t'u latuar drejt një përfshirje më të gjerë, ose nëse nuk është e përshtatshme për shfaqje te <i>site</i>-i i AMO-s, jashtë bankoprove pra.</p>
+
+<h2>Si i bëhet që shtesa ime të përparojë drejt të qenët publike?</h2>
+
+<p>Nëse besoni se shtesa juaj (dhe sjellja juaj!) i plotëson kushtet për një shtesë publike, mund ta propozoni nga paneli i kontrollit për zhvilluesat.</p>
+
+<h2>Cilët janë kushtet për një shtesë publike?</h2>
+
+<p>Një shtesë që është bërë publike te AMO do të duhej të ishte e një cilësie të lartë, dhe t'u japë përdoruesve një përvojë më të mirë në Web. Kërkojmë sa vijon përpara se të vendosim nëse një shtesë është e përshtatshme për pjesën publike të AMO-s:</p>
+
+<h3>Jeni përgjegjës?</h3>
+
+<p>Presim nga një autor, i cili është duke nxitur shtesën e tij drejt shumë përdoruesish të Firefox-it, të jetë përgjegjës kur raportohen probleme, të vërë në dispozicion të dhëna kontakti, dhe të përditësojë menjëherë shtesat e tij për të mbetur në një vijë me versionet e Firefox-it dhe ndryshime në rregullat e AMO-s. Kjo nuk do të thotë që do t'ju duhet t'i përgjigjeni cilësdo pyetje që bën dikush te diskutimet, ose që ju duhet të ndreqni çdo të metë, por presim që ju t'i përgjigjeni çështjeve në një mënyrë që është në përputhje me rëndësinë e çështjes në fjalë.</p>
+
+<h3>A përshkruhet shtesa qartë dhe përimtas?</h3>
+
+<p>Ka rëndësi të skajshme për ne që përdoruesit të kenë atë çfarë presin kur provojnë një shtesë të re. Përshkrimi juaj do të duhej të jepte hollësi rreth asaj se çfarë kryen shtesa, rreth se si një përdorues përfiton prej saj, dhe çfarë do të duhej të priste përdoruesi kur e instalon. Lidhjet te dokumentacion i jashtëm për udhëzime të hollësishme janë bukuri, por përshkrimi në vetvete do të duhej të mbulonte anët themelore dhe ta bëjë përdoruesin të besojë se di se çfarë po merr.</p>
+
+<p>Është gjithashtu e rëndësishme që të mirëmbani si duhet shënime versionesh, ndërkohë që përmirësoni dhe ndryshoni shtesën tuaj. Përdoruesit duhet të jenë në gjendje të shohin se çfarë ka të re në një shtesë që mund ta kenë provuar më parë, dhe duhet t'u vihen në dukje ndryshime që mund të prekin përdorimin e deriatyshëm të shtesës kur atë e përditësojnë. (Hëpërhë, përdoruesit nuk shohin shënime version kur u ofrohet përditësim nga brenda shfletuesit, por do të punojmë për ta ndrequr këtë anë. Nëse i mirëmbani si duhet shënimet e versioneve, përdoruesit tuaj do të përfitojnë mjaft përpara dhe pasi kjo punë të jetë plotësuar.)</p>
+
+<h3>A tregohen qartë tërë çështjet e sigurisë dhe vetësisë?</h3>
+
+<p>Kjo është punë përshkrimi të qartë dhe të saktë, por e një rëndësie të tillë që ne na duket se meriton të përmendet veçan. Mjaft shtesa shumë të dobishme dhe të mirëhartuara përdorin një formë a një tjetër të dhënash përdoruesi, ose të paraqesin rreziqe sigurie nëse keqpërdoren; të tilla janë të mirëpritura në pjesën publike të AMO-s, por ato duhet ta bëjnë shumë të qartë për përdoruesit se çfarë rreziqesh mund të hasin, dhe çfarë mund të bëjnë ata për t'u vetëmbrojtur.</p>
+
+<h3>A është provuar shtesa më së miri, dhe a është e lirë nga të meta të dukshme apo serioze?</h3>
+
+<p>Një gjë e rëndësishme që shohim kur marrim në shqyrtim një shtesë për hedhje në publik është fakti nëse shqyrtimet e saj në bankoprovë tregojnë që ajo ka kaluar plotësisht në prova, dhe që nuk ka probleme serioze ose ndërhyrje negative në shfletues. Nëse shqyrtuesit raportojnë probleme si, fjala vjen, çështje që prekin rëndë punimin e shfletuesit, vithisje, probleme të shpeshtë gjatë përdorimit të funksioneve të shtesës, ose dërgim mesazhesh të panumërt te konsola e gabimeve, duhet t'i merrni parasysh këto raportime dhe ta ripropozoni shtesën pasi të jeni marrë me to në rrugën më të mirë të mundshme. Nuk presim që ta përkryeni përfundimish apo që shtesa juaj të ketë zero të meta -- vetë Firefox-i i nënshtrohet përmirësimeve konstante në këtë pikëpamje -- por duam që ju të përpiqeni në mënyrë të arsyeshme për të ulur anët negative, dhe të tregoni qartë rastet kur përdoruesit mund të shtangen nga ato që mbeten.</p>
+
+<p>Nëse shtesa juaj është vënë në provë jashtë procesit të bankoprovës së AMO-s, si p.sh. nga një grup përdoruesish të shërbimit tuaj apo nga një ekip i brendshëm Sigurimi Cilësie, do të ishte mirë ta bënit këtë të ditur në mesazhin shoqërues të propozimit. Kjo sigurisht na ndihmon të përcaktojmë se e cilit nivel ka qenë prova, dhe mund të ndihmojë që shtesa juaj të bëhet pjesë e <i>site</i>-it.</p>
+
+<h3>A e trajtojnë përdoruesin me respekt, si shtesa, ashtu edhe autori?</h3>
+
+<p><i>Software</i> juaj nuk duhet të fusë hundët te përdoruesi pa qenë nevoja, as të provojë t'ia hedhë atij, ose t'i fshehë përdoruesit cilindo veprimt nga ana e programit. Përdoruesit (madje edhe jopërdoruesit) ngandonjëherë janë të hidhur në komentet e tyre, dhe ndërsa përpiqemi aq sa mundemi t'i filtrojmë ato që na raportohen, presim që autorët të shmangin hakmarrjen dhe hidhësinë nga ana e tyre.</p>
+
+<h3>A është shtesa e dobishme për një pjesë, të gjerë deri në një farë mase, përdoruesish të Firefox-it?</h3>
+
+<p>Shtesa juaj nuk ka nevojë të jetë kryevepër, por nëse është e dobishme vetëm për njerëz në punën tuaj apo për ata që janë pjesë e një bashkësie të vogël web, mund të mendojmë që nuk është ende e përshtatshme ta vëmë përpara tërë përdoruesve të Firefox-it.</p>
+
+<p>Jemi përherë në kërkim rrugësh për përmirësimin e organizimit të <i>site</i>-it lidhur me strehimin e shtesave që janë shembullore në anë të tjera, por që synojnë vetëm një bashkësi të vogël përdoruesish të mundshëm. Kategorizimi dhe mirëmbajtja si duhet e tejtëdhënave të shtesës suaj do të na ndihmojë të gjejmë se si mund të nxjerrim në pah më tepër shtesa të këtyre llojeve, për persona që ka më tepër të ngjarë të presin përfitim prej tyre.</p>
+
+<p>Nëse shtesa juaj thjesht ofron faqerojtësa apo të tjera pikëhyrje të thjeshta për te <i>site</i>-i juaj, ka mundësi të mos jetë e përshtatshme për pjesën publike të <i>site</i>-it. Si edhe pjesa tjetër e projektit Mozilla, na pëlqejnë zbatimet web dhe shërbimet e reja web, por shtesat e Firefox-it do të duhej të sillnin për përdoruesin një përvojë të përmirësuar shfletimi dhe jothjesht të jenë një rrugë për reklamimin e një <i>site</i>-i apo shërbimi të ri përmes listave të AMO-s. Nëse përshkrimi për shtesën tuaj është, në pjesën më të madhe, rreth shërbimit, në vend që të jetë rreth përmirësimesh që sjell në përvojën e përdoruesit në shfletim, ka gjasa që të mos jeni në udhën e duhur.</p>
+
+<h3>A është shtesa e lirë nga shenja tregtare të palicensuara apo nga të drejta kopjimi?</h3>
+
+
+<p>Edhe pse ju mund të mos synoni cënim të mbajtësit të një shenje tregtare, apo të të zotit të një pune nën të drejta kopjimi, nuk mund të strehojmë shtesa që prekin shenja tregtare apo të drejta kopjimi. Nëse nuk keni leje të përdorni një emër apo pamje nën shenjë tregtare, ju lutemi mos e parashtroni shtesën tuaj te AMO. Nëse shtesa juaj përfshin kod që është e drejtë kopjimi e dikujt tjetër, dhe nuk ju është dhënë leje për ta përdorur te shtesa juaj, ju lutemi mos e parashtroni shtesën tuaj te AMO. (Nëse mbajtësi i një shenje tregtare apo të drejte kopjimi ankohet për përdorimin e tyre, ka shumë të ngjarë që kërkesën për heqje ta shqyrtojmë në këshill, dhe do ta heqim shtesën nëse gjendet ligjërisht e nevojshme. Ky është një proces i kushtueshëm për burimet e projektit, përfshi kohë dhe para, kështu që ju kërkojmë të tregoni respekt dhe të mos na shkaktoni vështirësi të pamerituara.)</p>
+
+<p>Nëse nuk jeni i sigurt se emri i shtesës suaj, ose përdorimi i diçkaje tjetër brenda saj, do ta pengojë të radhitet në <i>site</i>, mund të pyesni te amo-editors@mozilla.org për udhëzime. E RËNDËSISHME: Ju lutem mbani shënim që ky grup nuk është në gjendje të ofrojë këshilla ligjore, dhe që edhe pse na duket se përdorimi juaj është i pranueshëm, mund t'i kthehemi atij vendimi nën dritën e ankesave nga mbajtës të drejtash dhe këshillave prej këshillit ligjor.</p>
+
+<p>Përsa i përket ripërdorimit të kodit burim prej shtesash të tjera, nëse autori nuk ka deklaruar qartë që ju lejohet të përdorni kodin e asaj shtese në veprën tuaj -- bie fjala, duke e vendosur në një licensë burimi të hapur -- atëherë do të duhej të merrnit të mirëqenë që nuk keni të drejtë ta bëni. Mund të lidheni me autorin për të kërkuar leje të tilla, por nuk mund t'ju ofrojmë ndonjë të drejtë speciale ndaj tij thjesht sepse gjendet në AMO, ose sepse autori nuk po i përgjigjet kërkesës suaj. (Dhe, sërish, s'mund të ofrojmë këshilla ligjore, por thjesht këshilla se si shtesa juaj, sipas gjasash, do të trajtohej nga rregullat e <i>site</i>-it.)</p>
+
+<p>Kjo zbatohet njësoj edhe për shenjat tregtare të Mozilla Foundation-it, përfshi "Mozilla", "Firefox", dhe "Thunderbird". Rregullat e Mozilla-s për përdorimin e shenjave tregtare janë hartuar për mbrojtje kundër ngatërrimit, dhe parandalojnë keqpërdorimin e shenjave në rast mungese mbrojtjeje; ju lutem respektoni nevojën për një mbrojtje të tillë, dhe na ndihmoni të ruajmë disa nga burimet më të çmuara të Mozilla Foundation-it.</p>
+
+<h2>Ç'ndodh pasi propozoj diçka?</h2>
+
+
+<p>Pasi të jetë propozuar shtesa juaj, ajo vlerësohet nga një ekip Redaktorësh të AMO-s në përputhje me kriterin e përshkruar më sipër. Nëse gjykohet gati për shfaqje publike, do të kalohet te pjesa publike sapo të jetë vlerësuar, dhe do të merrni një njoftim email.</p>
+
+<p>Nëse na duket se shtesa juaj nuk është e përshtatshme për pjesën publike të AMO-s për tani, do të merrni një njoftim email ku tregohet pse, dhe propozimi juaj do të hiqet nga radha. Nëse, dhe kur, mendoni se i keni trajtuar çështjet e treguara në atë njoftim notification, dhe doni që shtesa të vlerësohet sërish, mund ta bëni këtë kur t'ju duket e arsyeshme. Propozime të përsëritur pa përmirësime të dukshme te shtesa nuk shihen me sy dashamirës, pra ju lutemi të ecni me maturi; ka më tepër gjasa të na nxehni se sa të na konsumoni.</p>
+
+<h2>A mund të propozoj shtesën e dikujt tjetër?</h2>
+
+<p>Hëpërhë, kërkojmë që autori i shtesës të propozojë për botim punën e vet. Duam të sigurojmë që autori të jetë në rregull me rritjen e ekspozimit dhe të ndjejë që shtesa, siç është në atë çast, pasqyron si duhet cilësinë e punës së tij. Nëse besoni se një shtesë është e lëmuar, që autori u përmbahet gërmë për gërmë frymës së rregullave të AMO-s, se nga bërja e saj të pashme për gati njëqind milionë përdorues në mbarë botën, do të përfitonte Firefox-i, përdoruesit tanë, dhe web-i në përgjithësi, ndihuni i lirë të nxisni autorin e shtesës të propozojë krijimin e tij.</p>
+
+<h2>Shtesa ime ka mbetur në radhën e propozimeve për një kohë të gjatë, keni gjë me mua?</h2>
+
+<p>Nuk kemi gjë me ju. I duam zhvilluesat e shtesave, dhe punojmë fort për t'i kënaqur dhe për t'i ndihmuar të jenë prodhimtarë, kështu që përdorues në mbarë botën të mund të përfitojnë nga puna e tyre. Por të qenët në anën publike të AMO-s ka vlerë pikërisht ngaqë kujdesemi se çfarë përfundon në të, ndaj nuk mund të turremi thjesht për hir të shpejtësisë. E kuptojmë që mund të jetë jo e këndshme të presësh që shtesa jote të vlerësohet, dhe duam ta mbajmë kohën e pritjes sa më të shkurtër që të jetë e mundur. Sa më shumë përshtypje të menduara dhe të qarta që japin njerëzit mbi një shtesë në bankoprovë, aq më e lehtë është të kryhen këto vlerësime, kështu që mund shihni edhe mundësinë e ndihmesës në këtë anë, në qofshi i prirë.</p>
+
+<h2>Kam gjetur një të metë serioze te shtesa ime, dhe dua vërtet të arrijë ndreqja sa më parë te pjesa publike. Çfarë duhet të bëj?</h2>
+
+
+<p>Në u bëftë fjalë për një të metë serioze (siguri, qëndrueshmëri, problem i rëndësishëm në punim) në një shtesë për të cilën keni nevojë të dalë shpejt një përditësim, duhet ta tregoni te "shënime përshtypjesh" gjatë parashtrimit të përditësimit -- po ashtu edhe te shënimet e versionit, kuptohet! Mund edhe t'u kërkoni disa përdoruesve ekzistues të shtesës suaj të provojnë përditësimin dhe të raportojnë në hollësi përfundimet e bankorpovës. Një zë te #addons te irc.mozilla.org mund të ndihmojë që njerëzit të njohin situatën, por ju lutem jini i duruar dhe i sjellshëm edhe në këtë rast.</p>
+
+<p>Ju lutem mos u qani. Ne përpiqemi të hidhemi shpejt te përditësimet me përparësi të madhe, por vlerësimi i shtesave të tjera të propozuara apo versionesh të rinj na merr kohë, ndaj shpesh na kushton gjumin apo kohën për familjen dhe miqtë, kështu që i shohim zbehtë ata që përpiqen të përfitojnë nga ky mekanizëm i "daljes nga radha". Nëse nuk jeni i sigurtë nëse do të duhej shkuar nga kjo rrugë, interesimi te #addons te irc.mozilla.org mundet gjithashtu t'ju ndihmojë të vendosni.</p>
+
+<h2>Mendoj se u trajtova me hile gjatë vlerësimit të shtesës sime. Çfarë do të duhej të bëja?</h2>
+
+<p>Nëse besoni që shtesa juaj u vlerësua jokorrektësisht, dhe që gabimisht ju mohua statusi publik, do të duhej të dërgonit një email te amo-editors@mozilla.org me hollësitë e arsyetimit tuaj. Ju lutem jini i sjellshëm dhe i qartë në email-in tuaj, dhe bëni të mundur tregimin konkret rreth se si është keqgjykuar shtesa.</p>
+
+<p>(Nëse keni ndrequr *tërë* gjërat që qenë radhitur si probleme në njftimin që morët, nuk do të duhej të kërkonit vlerësim, më mirë ripropozim për shqyrtim përmes Panelit të Kontrollit për Zhvillesa.)</p>
+
+
+<h2>Shtesa ime qe publike, dhe tani gjendet vetëm në bankoprovë. Ç'ndodhi? </h2>
+
+<p>Nëse një shtesë nuk pajtohet më me kriteret për të qenët në pjesën publike të <i>site</i>-it, mund ta kalojmë prapa në bankoprovë. Do t'ju njoftojmë me email kur ndodh kjo, dhe t'ju tregojmë arsyet për të bërë kështu, veç na u pengoftë kjo ligjërisht.</p>
+
+<p>Mundet gjithashtu që të gjeni ndonjë të metë në <i>site</i>, e në këtë rast do të duhej ta raportonit përmes Bugzilla-s; përdorni produktin "addons.mozilla.org" dhe përbërësen "Public Pages" për raportimin tuaj, dhe përfshini sa më shumë hollësi që mundeni.</p>
+
+<h2>Shtesa ime është publike, dhe duket se njerëzia e pëlqen. Si mund të bëhem pjesë e listës së shtesave të këshilluara?</h2>
+
+<p>Nëse besoni se shtesa juaj është një shembull i ndritur i fuqisë së shtesave, që tregon dhe shtyn më tej vlerat e Mozilla-s për një web të thellueshëm dhe të kontrolluar nga përdoruesi, që ofron përvojë të bukur për përdoruesit, mund të kërkoni të shqyrtohet për shtim te lista e shtesave të këshilluara. Për këtë, do të duhej të dërgonit një email te amo-editors@mozilla.org ku të shpjegohet pse shtesa juaj është e fortë.</p>
+
+
+<p>Kërkesa juaj do të duhej të përfshinte të <b>paktën</b> të dhëna rreth këtyre gjërave:</p>
+<ul>
+<li>si përmirësohet puna në web e përdoruesve</li>
+<li>pse shtesa juaj është e përshtatshme për një masë të madhe përdoruesish të Firefox-it</li>
+<li>si tregohen nga shtesa juaj vlerat e projektit Mozilla dhe/ose si u shërbehet atyre, veçanërisht kur vjen fjala për bërjen e përdoruesit përgjegjës, mbrojtjen e vetësisë dhe sigurisë, hyrjen universale në web, dhe standarde dhe të dhëna të hapura</li>
+<li>ku ndryshon shtesa juaj nga shtesa të tjera të ngjashme (qoftë për mirë, qoftë për keq)</li>
+<li>çfarë kundërveprimi keni parë nga përdoruesa, shqyrtuesa, blogtarë, astronautë, apo kafshë shtëpiake, si pozitivet, ashtu edhe negativet</li>
+</ul>
+
+<p>Sa më të plota të dhënat që sillni me kërkesën, aq më e mundshme është t'ju akordohet çfarë prisni, edhe pse kërkesa e shkruajtur shkëlqyeshëm dhe shteruese nuk është garanci për vendosjen te lista e të këshilluarave. Së fundi, ajo listë duhet të jetë -- dhe është -- e mirëmbajtur nën hijen e Mozilla-s, dhe puna e përdoruesit dhe mbrojtja e tij duhet të jenë mbi gjithçka tjetër.</p>
diff --git a/site/app/locale/sq/pages/reviewguide.thtml b/site/app/locale/sq/pages/reviewguide.thtml
new file mode 100644
index 0000000..11bfd6f
--- /dev/null
+++ b/site/app/locale/sq/pages/reviewguide.thtml
@@ -0,0 +1,68 @@
+<h1>Udhëzime Shqyrtimi</h1>
+<p>Shqyrtimi i shtesave është një rrugë që përdoruesit e <i>site</i>-it të shtesave të ndajnë mes tyre përshtypjet rreth shtesave që kanë instaluar dhe përdorur. Redaktorët ruajnë të drejtën të hedhin poshtë ose të heqin çfarëdo shqyrtimi që nuk përputhet me këto udhëzime.</p>
+
+<div class="corner-box">
+ <h2>Disa ndihmëza rreth shkrimit të një shqyrtimi të fuqishëm</h2>
+
+<h3><b>Të:</b></h3>
+<ul>
+<li>shkruani sikur po i tregoni një shoku rreth përvojës suaj me shtesën.</li>
+<li>mbani shqyrtimet të përkora dhe të lehta për t'u kuptuar.</li>
+<li>jepni hollësi të përcaktuara dhe të dobishme. Për shembull:
+<ul>
+ <li>A punoi shtesa si e prisnit?</li>
+ <li>Cilat anë ju pëlqyen apo nuk ju pëlqyen?</li>
+ <li>A qe e dobishme?</li>
+ <li>A qe e lehtë për përdorim?</li>
+ <li>A do vazhdoni ta përdorni këtë shtesë?</li>
+</ul></li>
+
+<li>Ndaluni një çast e lexojeni shqyrtimin tuaj përpara se ta parashtroni, për të shmangur gabime shkrimi apo gramatike.</li>
+
+<li>Përpiquni të shmangni referenca të përkohshme, ngaqë shqyrtimet mund të rrinë në <i>site</i> për një kohë të gjatë.</li>
+</ul>
+
+<h3><b>Mos:</b></h3>
+<ul>
+<li>parashtroni shqyrtime me dy fjalë, si "E fortë!", "E mrekullueshme", ose "nuk bën", pa shpjegime të mëtejshme.</li>
+<li>postoni në shqyrtime njoftime për të meta apo probleme. Përdorni për secilën shtesë mundësitë për asistencë.</li>
+<li>shkruani shqyrtime për shtesa të cilat nuk i keni përdorur vetë.</li>
+<li>përdorni gjuhë përdhosëse, seksuale ose gjuhë që mund të merret si urrejtje.</li>
+<li>përfshini HTML, lidhje për te <i>malware</i>, kod burim apo copëza kodi. Shqyrtimet mendohen se janë tekst vetëm.</li>
+<li>bëni pohime të rreme, përçmoni autorë shtesash ose fyeni ata personalisht.</li>
+<li>përdorni shqyrtimin si rrugë për të lypur asistencë për një version specifik të Firefox-it (ose të një tjetër zbatimi).</li>
+<li>përfshini email-in tuaj, numrin e telefonit, apo të tjera hollësi personale.</li>
+<li>postoni shqyrtime rreth një shtese që e shkruajtët apo paraqitët ju apo organizmi juaj.</li>
+</ul>
+</div>
+
+<div class="corner-box">
+ <h2>Udhëzime mbi vlerësimin e shtesave</h2>
+
+<p>Vlerësimi i shtesave duhet të jetë i drejtë dhe të japë tregues të vlefshëm për cilësinë dhe dobinë në përgjithësi. Mos i jepni thjesht 5 yje pse e pëlqeni ose 1 sepse e urreni. Vlerësimi i bazuar është pjesë e rëndësishme e çdo shqyrtimi.</p>
+
+<ul>
+<li><b>5 yje: E shkëlqyer.</b> Jo vetëm që bën gjithçka që pretendon, por është dukshëm më e dobishme se mjaft shtesa të tjera. Kjo shtesë ka gjasa të jetë një që do ta përdorni shpesh dhe e këshilloni fuqishëm.</li>
+<li><b>4 yje: E mirë.</b> E dobishme dhe e lehtë në përdorim, por jo domosdo e veçantë. Kjo shtesë është e këshillueshme, por për disa mund të jetë më e përshtatshme e për disa jo.</li>
+<li><b>3 yje: Çka.</b> Mund të ketë ndonjë problem me konceptimin dhe/ose disa anë mangut.
+Çfarëdo problemi që të ketë nuk është aq i prerë sa për të mos e këshilluar, dhe disave prapë mund t'ju duket e dobishme. E këshillueshme për ata të cilëve u duhet dhe që duan ta provojnë.</li>
+<li><b>2 yje: E dobët.</b> Shtesa ka cilësi të ulët, përdorje po të tillë, ose thjesht nuk bën ato që thotë se duhej të bënte. Nuk e këshilloni përdorimin e kësaj shtese, duke vënë në dukje megjithatë që mund të ketë ndonjë farë vlere për pak vetë.</li>
+<li><b>1 yje: E keqe.</b> Shtesa ose nuk punon në rregull, ose është thellësisht pa vlerë. Nuk ju vjen në mend ndonjë arsye kuptimplote pse do të duhej ta provonte dikush dhe këshilloni që duhet shmangur plotësisht.</li>
+</ul>
+
+<p>Nuk ka asgjë të keqe t'i jepet një shtese një vlerësim i përkryer ose i shpifur, thjesht ju lutemi të tregoni pse bëni kështu. Yjet nuk kanë kuptim po nuk treguat pse.</p>
+</div>
+
+<div class="corner-box">
+ <h2>Pyetje të Bëra Shpesh rreth Shqyrtimesh</h2>
+
+<h3>Si të njoftoj një shqyrtim me probleme?</h3>
+<p>Ju lutem njoftojeni ose i vini shenjë cilitdo shqyrtimi të dyshimtë duke klikuar "Njoftojeni këtë shqyrtim" dhe do t'i parashtrohet administratorëve të <i>site</i>-it për moderim. Për të vendosur në duhet fshirë apo rikthyer te <i>site</i>-i, redaktorët do të përdorin Udhëzime Shqyrtimi.</p>
+
+<h3>Jam autor shtese, a mund t'i përgjigjem shqyrtimeve?</h3>
+<p>Po, autorët e shtesave mund të sjellin një përgjigje për shqyrtim. Diskutime dhe tjerrje shtesë do të duhej të kaloheshin te ndonjë forum asistence apo grup diskutimesh.</p>
+
+<h3>Jam autor shtese, a mund të fshij shqyrtime apo vlerësime të pafavorshme?</h3>
+<p>Përgjithësisht, jo. Por, nëse shqyrtimi nuk është bërë në përputhje me udhëzimet e shqyrtimit ravijëzuar më sipër, mund të klikoni "Njoftojeni këtë shqyrtim" që të moderohet nga një redaktor.
+Nëse një shqyrtim përmban ankesë që nuk ka më baza, për shkak të një versioni të ri të shtesës suaj, mund të marrim parasysh fshirjen e shqyrtimit. Parashtrojeni kërkesën tuaj të hollësishme te amo-editors@mozilla.org.</p>
+</div>
diff --git a/site/app/locale/sq/pages/sandbox.thtml b/site/app/locale/sq/pages/sandbox.thtml
new file mode 100644
index 0000000..0152068
--- /dev/null
+++ b/site/app/locale/sq/pages/sandbox.thtml
@@ -0,0 +1,13 @@
+<h1>Sistemi i Shqyrtimeve në Bankoprovë</h1>
+<h2>Çfarë është bankoprova?</h2>
+<p>Bankoprova është një zonë ku përdorues të përparuar mund të provojnë shtesa para se ato të merren në shqyrtim për përdorim të përgjithshëm. Që të mund të hyni në bankoprovë, duhet ta aktivizoni këtë mundësi te rregullimet e llogarisë suaj. Duhet treguar kujdes kur instalohen shtesa nga bankoprova, ngaqë nuk janë provuar nga ndonjë redaktor dhe mund të dëmtojnë kompjuterin tuaj.</p>
+
+<h2>Si i bëhet që shtesa ime të kalojë në pjesën publike të <i>site</i>-it?</h2>
+<!-- To localize the flowchart image, see http://wiki.mozilla.org/Update:Remora_Sandbox_Flowchart -->
+<div style="text-align: center;">%s</div>
+<ol>
+ <li><b>Parashtrojeni shtesën tuaj te Paneli i Kontrollit për Zhvilluesa.</b> Do të shfaqet aty menjëherë, te pjesa "Bankoprovë" e Shtesave të Mozilla-s, nga ku përdorues të sprovuar do ta provojnë dhe do të japin përshtypjet e tyre. Që të mund të shihni bankoprovën, duhet ta aktivizoni këtë mundësi te rregullimet për llogarinë tuaj.</li>
+ <li><b>Propozojeni shtesën tuaj të jetë publike.</b> Prej Panelit të Kontrollit për Zhvilluesa, ka një lidhje për propozime shtesash. Pasi ta keni propozuar, shtesa juaj do të shfaqet te Radha e Propozimeve për Përpunim.</li>
+ <li><b>Shtesa shqyrtohet nga një redaktor.</b> Një redaktor prej Shtesave të Mozilla-s do ta instalojë dhe provojë shtesën tuaj. Redaktori do t'u hedhë një sy edhe përshtypjeve të dhëna në bankoprovë nga provuesa te bankoprova.</li>
+ <li><b>Shtesa juaj kalohet publike ose mbahet në bankoprovë.</b> Redaktori ose do ta kalojë shtesën tuaj te pjesa publike ose do ta mbajë atë te bankoprova. Në u mbaftë te bankoprova, mund ta propozoni sërish pasi të bëni ndryshimet e këshilluara nga redaktori në komentet e tij. Në u kaloftë publike, versionet e ardhshëm të shtesës suaj do të shfaqen në bankoprovë derisa ata të jenë shqyrtuar nga nja redaktor dhe të jenë kaluar te pjesa publike. Pasi shtesa juaj bëhet publike, nuk ka nevojë ta propozoni sërish - versionet e ardhshëm do të kalojnë vetvetiu te radha e pritjes së shqyrtimit.</li>
+</ol>
diff --git a/site/app/locale/sq/pages/statistics_help.thtml b/site/app/locale/sq/pages/statistics_help.thtml
new file mode 100644
index 0000000..18b4bd1
--- /dev/null
+++ b/site/app/locale/sq/pages/statistics_help.thtml
@@ -0,0 +1,7 @@
+<h3>Ndihmë</h3>
+<p>Pulti i Statistikave shfaq të dhëna të mbledhura lidhur me shkarkimin dhe përditësimin e shtesës suaj.</p>
+<h4>Shkarkime</h4>
+<p>Numërimi i shkarkimeve përditësohet një herë në ditë dhe përfshin vetëm shtesën origjinale, jo përditësimet.</p>
+
+<h4>Përditësime</h4>
+<p>Shtesat e shkarkuara prej këtij <i>site</i> kontrollojnë për përditësime një herë në ditë, dhe numri gjithsej i këtyre kontakteve për përditësim njihet si Përdoruesa Ditorë Aktivë. Përdoruesat Ditorë Aktivë (PDA) mund të ndahen sipas versionit të shtesës, sistemit operativ, gjendjes së shtesës, dhe zbatimit. Këto të dhëna hëpërhë regjistrohen një ditë në javë, të mërkurave.</p>
diff --git a/site/app/locale/sq/pages/submission_help.thtml b/site/app/locale/sq/pages/submission_help.thtml
new file mode 100644
index 0000000..376690c
--- /dev/null
+++ b/site/app/locale/sq/pages/submission_help.thtml
@@ -0,0 +1,36 @@
+<h1>Ndihmë për Parashtrime</h1>
+Kutitë që duhen plotësuar paraqiten <b>me të trasha</b>. Kutitë në dëshirën tuaj paraqiten <i>me të pjerrëta</i>.
+<h2 id="step1">Hapi 1: Ngarkim</h2>
+<ul class="submissionHelp">
+ <li><span class="required">Tip Shtese</span> - Si parazgjedhje, tipi i shtesës do të përcaktohet vetvetiu duke marrë për bazë kartelën e ngarkuar. Do të ishte mirë të mos bënit ndryshime në këtë kuti.</li>
+ <li><span class="required">Kartelë Shtese</span> - Kartela paketë për shtesën tuaj, e plotësuar me një kartelë install.rdf. Nëse kartela punon vetëm me nën një platformë të caktuar, përzgjedhja e asaj platforme do të lejojë ngarkimin njëherësh të shumë kartelave.</li>
+ <li><span class="optional">Kartelë Ikone</span> - Kartela ikonë shfaqet ngjitur me emrin e shtesës, te faqja e paraqitjes dhe tregohet te dialogu i instalimit të shtesës. Do të ripërmasohet vetvetiu në 32x32 piksela, duke ruajtur përpjestimet.</li>
+ <li><span class="required">Gjuhë Parazgjedhje</span> - Gjuha parazgjedhje e një shtese është ajo e vendores kryesore. Nëse vendorja e përzgjedhur nga një përdorues nuk gjendet për shtesën, përkthimet të lihen anash në favor të vendores parazgjedhje.</li>
+ <li><span class="optional">Anashkalo rishikimin e të dhënave të mia të çastit për shtesën</span> - Nëse po përditësoni një shtesë ekzistuese, do të shfaqet edhe kjo kuti. Duke i vënë shenjë kutizës do të kaloheni te hapi 3 ku mund të jepni të dhënat rreth versionit.</li>
+</ul>
+
+<h2 id="step2">Hapi 2: Hollësi Shtese</h2>
+<ul class="submissionHelp">
+ <li><span class="required">Emër</span> - Emri i shtesës sipas vendores parazgjedhje.</li>
+ <li><span class="required">Autorë</span> - Tërë përdoruesit të cilëve u lejohet ndryshimi i shtesës dhe që do të radhiten si autorë te faqja përkatëse.</li>
+ <li><span class="required">Kategori</span> - Kategori te të cilat mund të përfshihet shtesa.</li>
+ <li><span class="optional">Përmbledhje</span> - Një përmbledhje e shkurtër e shtesës, në vendoren parazgjedhje. Kjo kuti nxë e shumta 250 shenja, dhe do të shfaqet te faqja e paraqitjes së shtesës, si edhe te përfundime kërkimi/shfletimi.</li>
+ <li><span class="required">Përshkrim</span> - Një përshkrim i shtesës, në vendoren parazgjedhje. Kjo do të shfaqet te faqja e paraqitjes së shtesës, nën përmbledhjen.</li>
+ <li><span class="optional">EULA</span> - Marrëveshje License Përdoruesi të Thjeshtë (End User License Agreement) të cilën përdoruesit lypset ta pranojnë përpara shkarkimit, në vendoren parazgjedhje.</li>
+ <li><span class="optional">Rregulla Vetësie</span> - Rregullat e Vetësisë për shtesën, në vendoren parazgjedhje. Rregullat e Vetësisë shpjegojnë se çfarë bëhet me të dhëna vetjake të përdoruesve të thjeshtë, dhe për të do të ketë një lidhje ngjitur me butonin e instalimit te faqja e paraqitjes së shtesës. Të dhëna shtesë, rreth çfarë do të duhej të përfshihej te Rregulla Vetësie dhe në lyp a jo shtesa juaj një të tillë, mund të kihen prej <a href="%s">Rregulla Shtese</a>.</li>
+ <li><span class="optional">Lejoni përdorues të shohin <i>online</i> kartelat burim</span> - Duke i vënë shenjën kësaj kutie përdoruesit do të lejohen të shfletojnë <i>online</i> kartelat burim të shtesës suaj.</li>
+ <li><span class="optional">Ky është një paraqarkullim</span> - Duke i vënë shenjë kësaj kutie tregohet që shtesa është një paraqarkullim ose version "beta". Shtesat paraqarkullim duhet të mbesin në bankoprovë dhe nuk mund të propozohen për t'u kaluar publike para se kjo flamurkë të jetë hequr.</li>
+ <li><span class="optional">Kjo është një shtesë për një <i>site</i> të caktuar</span> - Duke i vënë shenjë kësaj kutie tregohet që shtesa është e vlefshme për një <i>site</i> web të caktuar, fjala vjen një shtesë që ndryshon pamjen e një faqeje të caktuar ose që shfaq përmbajtje nga një <i>site</i> web i caktuar. Kjo kuti është e dobishme për redaktorët dhe mbikëqyrësit dhe mund të përdoret për të filtruar kërkimet në të ardhmen.</li>
+ <li><span class="optional">Kjo shtesë lyp <i>software</i> të jashtëm</span> - Duke i vënë shenjë kësaj kutie tregohet që shtesa lyp <i>software</i> të jashtëm. Kjo kuti është e dobishme për redaktorët dhe mund të përdoret për të filtruar kërkimet në të ardhmen.</li>
+</ul>
+
+
+<h2 id="step3">Hapi 3: Hollësi Versioni</h2>
+<ul class="submissionHelp">
+ <li><span class="required optional">Shënime Versioni</span> - Një përmbledhje ose një listë e ndryshimeve në këtë version. Kjo lihet në dëshirën e autorit për parashtrime të reja, por është e domosdoshme për përditësime.</li>
+ <li><span class="optional">Shënime për Redaktorin</span> - Kjo kuti përdoret për t'i kaluar të dhëna redaktorëve që do të marrin në shqyrtim shtesën tuaj. Të dhëna provimi llogarie dhe shënime speciale e kanë vendin këtu.</li>
+</ul>
+
+<h2 id="step4">Hapi 4: Përkthim</h2>
+Këtu jeni te fushat e shtesës që mund të përkthehen në cilëndo nga vendoret që mbulohen. Thjesht klikoni mbi një vendore për të hyrë te përkthimet.
+
diff --git a/site/app/locale/stats-po.sh b/site/app/locale/stats-po.sh
new file mode 100755
index 0000000..e27937e
--- /dev/null
+++ b/site/app/locale/stats-po.sh
@@ -0,0 +1,13 @@
+#!/bin/bash
+
+# syntax:
+# stats-po.sh
+
+echo "Printing number of fuzzy flags found in locales:"
+
+for lang in `find $1 -type f -name "messages.po"`; do
+ dir=`dirname $lang`
+ stem=`basename $lang .po`
+ count=$(grep -c "fuzzy" $lang)
+ echo -e "$(dirname $dir)\t$count"
+done
diff --git a/site/app/locale/sv_SE/LC_MESSAGES/messages.mo b/site/app/locale/sv_SE/LC_MESSAGES/messages.mo
new file mode 100644
index 0000000..dc54f86
--- /dev/null
+++ b/site/app/locale/sv_SE/LC_MESSAGES/messages.mo
Binary files differ
diff --git a/site/app/locale/sv_SE/LC_MESSAGES/messages.po b/site/app/locale/sv_SE/LC_MESSAGES/messages.po
new file mode 100644
index 0000000..5f2d3fb
--- /dev/null
+++ b/site/app/locale/sv_SE/LC_MESSAGES/messages.po
@@ -0,0 +1,7940 @@
+# Remora Preliminary Language File
+# Copyright (C) 2006 Mozilla Corporation
+# This file is distributed under the same license as the REMORA package.
+# Wil Clouser <clouserw@mozilla.com>, 2006.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: REMORA 0.1\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2009-01-16 11:45-0800\n"
+"PO-Revision-Date: 2009-05-30 20:42+0200\n"
+"Last-Translator: Pontus Freyhult <pontus_amo_translate@soua.net>\n"
+"Language-Team: SWEDISH <SV@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=n != 1;\n"
+
+#: views/addons/policy.thtml:98
+msgid "a_cancel_installation"
+msgstr "Avbryt installation"
+
+#. This is the text that appears on buttons to download add-ons.
+#. %$1s is an optional string that only appears if the add-on is only available for
+#. a certain platform. Examples: (Windows) or (Linux)
+#. Note that the parentheses are included in the string. :(
+#: views/elements/amo2009/install.thtml:126
+#: views/elements/amo2009/install.thtml:227
+#: views/elements/amo2009/install.thtml:257
+#: views/elements/amo2009/install.thtml:300
+#: views/elements/amo2009/install.thtml:312 views/elements/install.thtml:73
+#: views/elements/install.thtml:181 views/elements/install.thtml:205
+#: views/elements/install.thtml:248 views/elements/install.thtml:260
+#: views/addons/plugins.thtml:66 views/addons/plugins.thtml:76
+#: views/addons/plugins.thtml:86 views/addons/plugins.thtml:96
+#: views/addons/plugins.thtml:119
+#, php-format
+msgid "a_download"
+msgstr "Hämta hem nu %s"
+
+#: views/addons/policy.thtml:72
+msgid "a_eula_download"
+msgstr "Godkänn och hämta hem"
+
+#: views/addons/policy.thtml:74
+msgid "a_eula_install"
+msgstr "Godkänn och installera"
+
+#: views/elements/header.thtml:76 views/elements/header.thtml:82
+#: views/api/api_addon.thtml:55 views/api/collections_feed.thtml:75
+#: views/sharing_api/addon.thtml:64
+msgid "a_header_public"
+msgstr "Publikt"
+
+#: views/elements/header.thtml:58 views/elements/header.thtml:75
+#: views/elements/header.thtml:80 views/api/api_addon.thtml:57
+#: views/api/collections_feed.thtml:77 views/sharing_api/addon.thtml:66
+msgid "a_header_sandbox"
+msgstr "Sandlåda"
+
+#. %s is a date in the _('date') format
+#: views/elements/amo2009/homepage_addon.thtml:115
+#: views/elements/addon_listitem.thtml:122 views/elements/feature.thtml:106
+#: views/addons/display.thtml:104 views/addons/browse_thumbs.thtml:73
+msgid "addon_detail_last_updated"
+msgstr "Uppdaterad %s"
+
+#. %s is the version of the add-on. Example: 3.2a1
+#: views/elements/amo2009/addon_version_detail.thtml:51
+#: views/elements/addon_version_detail.thtml:51
+#, php-format
+msgid "addon_display_header_version"
+msgstr "Version %s"
+
+#: views/addons/browse_thumbs.thtml:80
+msgid "addon_downloads"
+msgstr "hämtningar"
+
+#: views/addons/display.thtml:147
+msgid "addon_downloads_total"
+msgstr "totala antal hämtningar"
+
+#: views/elements/amo2009/homepage_addon.thtml:106
+#: views/elements/addon_listitem.thtml:115 views/elements/feature.thtml:101
+#: views/addons/category_landing.thtml:157 views/addons/display.thtml:146
+#: views/addons/browse_thumbs.thtml:80
+msgid "addon_downloads_weekly"
+msgstr "hämtningar per vecka"
+
+#. %1 is the add-on count, %2 the category name
+#: views/addons/browse_thumbs.thtml:104 views/addons/browse.thtml:60
+#, php-format
+msgid "addon_list_category_totalcount"
+msgid_plural "addon_list_category_totalcount"
+msgstr[0] "%1$s tillägg"
+msgstr[1] "%1$s tillägg"
+
+#: views/elements/amo2009/addon_list_options.thtml:103
+#: views/elements/pagination.thtml:67
+#: views/elements/addon_list_options.thtml:94
+msgid "addon_list_perpage"
+msgstr "per sida"
+
+#: views/elements/amo2009/addon_list_options.thtml:84
+#: views/elements/addon_list_options.thtml:98
+msgid "addon_list_sortby"
+msgstr "Sortera på:"
+
+#: views/helpers/addons_html.php:568 views/elements/amo2009/install.thtml:321
+#: views/elements/feature.thtml:89
+msgid "addon_listitem_flag_experimental"
+msgstr "experimentell"
+
+#: views/helpers/addons_html.php:570
+msgid "addon_listitem_flag_recommended"
+msgstr "rekommenderat"
+
+#. %1 is the add-on name, %2 is the platform
+#: views/pages/js_constants.js.thtml:66
+msgid "addon_not_available_for_platform"
+msgstr "%1$s är inte tillgänglig för %2$s."
+
+#. %1 is the add-on name
+#: views/addons/policy.thtml:101 views/addons/previews.thtml:60
+#: views/addons/versions.thtml:130 views/reviews/flag.thtml:61
+#: views/reviews/add.thtml:114 views/reviews/display.thtml:216
+#: views/reviews/review_added.thtml:57
+#, php-format
+msgid "addon_review_a_back_to_addon_x"
+msgstr "Tillbaka till %1$s..."
+
+#. %1 is the add-on name
+#: views/reviews/flag.thtml:60 views/reviews/add.thtml:113
+#: views/reviews/review_added.thtml:56
+#, php-format
+msgid "addon_review_a_back_to_reviews"
+msgstr "Tillbaka till recensionerna..."
+
+#: views/reviews/add.thtml:85
+msgid "addon_review_add_rating_field"
+msgstr "Betyg:"
+
+#: views/reviews/add.thtml:102
+msgid "addon_review_add_review_field"
+msgstr "Recension:"
+
+#: views/reviews/add.thtml:107
+msgid "addon_review_add_submit"
+msgstr "Skicka in din recension"
+
+#. %s is the name of the add-on
+#: views/reviews/add.thtml:51
+#, php-format
+msgid "addon_review_add_title"
+msgstr "Lägg till en recension för %s"
+
+#: views/reviews/add.thtml:78
+msgid "addon_review_add_title_field"
+msgstr "Titel/Sammanfattning:"
+
+#: views/reviews/display.thtml:77 views/reviews/display.thtml:161
+msgid "addon_review_admin_delete"
+msgstr "Ta bort"
+
+#: views/reviews/display.thtml:76
+msgid "addon_review_author_reply_link"
+msgstr "Svara"
+
+#: views/reviews/delete.thtml:62
+msgid "addon_review_confirm_delete"
+msgstr "Är du säker på att du vill ta bort den här recensionen?"
+
+#: views/reviews/delete.thtml:63
+msgid "addon_review_confirm_no"
+msgstr "Nej"
+
+#: views/reviews/delete.thtml:64
+msgid "addon_review_confirm_yes"
+msgstr "Ja"
+
+#: views/reviews/delete.thtml:48
+msgid "addon_review_delete_header"
+msgstr "Ta bort recension"
+
+#: controllers/reviews_controller.php:449
+msgid "addon_review_deleted_successfully"
+msgstr "Recensionen är nu borttagen."
+
+#. %s is the name of the add-on
+#: views/reviews/add.thtml:51
+#, php-format
+msgid "addon_review_edit_title"
+msgstr "Redigera recension av %s"
+
+#. %1 is the count of characters entered as notes for the review flag reason.
+#: controllers/reviews_controller.php:539
+msgid "addon_review_flag_error_other_length"
+msgstr ""
+"Problem med att flagga recensionen: Information för flaggade recensioner "
+"begränsas till mellan 10 och 100 tecken, du hade %1$s."
+
+#. Removing an extra comma
+#: views/reviews/review_added.thtml:53
+msgid "addon_review_in_moderation"
+msgstr ""
+"Observera: Innan din recension dyker upp i det publika gränssnittet kommer "
+"den att granskas av en modererare."
+
+#: views/reviews/add.thtml:57
+msgid "addon_review_in_reply_to"
+msgstr "Svar från utvecklaren till:"
+
+#. %1 is the review count, %2 is the nickname or full name of the user.
+#: views/reviews/display.thtml:131
+#, php-format
+msgid "addon_review_others_by_user"
+msgid_plural "addon_review_others_by_user"
+msgstr[0] "Se %1$s tidigare recension inskickad av %2$s för detta tillägg."
+msgstr[1] "Se %1$s tidigare recensioner inskickade av %2$s för detta tillägg."
+
+#. %1 is the add-on name
+#: controllers/reviews_controller.php:201
+#: controllers/reviews_controller.php:250
+#: controllers/reviews_controller.php:345
+#: controllers/reviews_controller.php:424
+#, php-format
+msgid "addon_review_pagetitle"
+msgstr "Recensioner av %s"
+
+#. %1 is the user, %2 is the (localized) date
+#: views/reviews/display.thtml:160
+#, php-format
+msgid "addon_review_reply_on_x_by_y"
+msgstr "Svar från %1$s den %2$s"
+
+#: views/reviews/display.thtml:157
+msgid "addon_review_reply_prefix"
+msgstr "Svar från utvecklaren:"
+
+#: views/reviews/review_added.thtml:51
+msgid "addon_review_saved_successfully"
+msgstr "Din recension sparades, tack så mycket!"
+
+#: views/addons/display.thtml:354 views/reviews/display.thtml:72
+msgid "addon_reviewed_by_u_on_d"
+msgstr "av %1$s den %2$s"
+
+#. %1 is the user, %2 is the (localized) date, %3 is the rating
+#: views/editors/reviews_queue.thtml:57 views/editors/reviews_queue.thtml:68
+#: views/reviews/add.thtml:63 views/reviews/delete.thtml:54
+#, php-format
+msgid "addon_reviewed_on_x_rated_y"
+msgstr "av %1$s den %2$s (betyg %3$s)"
+
+#: views/elements/amo2009/addon_version_detail.thtml:52
+#: views/elements/addon_version_detail.thtml:52
+msgid "addon_version_permalink"
+msgstr "Permanent länk till denna version"
+
+#. %1 is the current Application name (e.g. Firefox)
+#. %2 is the Application's version number
+#: views/addons/versions.thtml:140
+msgid "addon_versions_getlatestversion"
+msgstr "Senaste versionen kompatibel med %1$s %2$s"
+
+#: views/addons/display.thtml:447
+msgid "addons_author_addons_submit"
+msgstr "Skicka in"
+
+#: views/elements/amo2009/homepage_addon.thtml:100
+#: views/elements/feature.thtml:95
+msgid "addons_author_tooltip"
+msgstr "Se författarens profil"
+
+#. %1 is the name of the Application (eg. Firefox)
+#: controllers/addons_controller.php:1296
+msgid "addons_browse_all_themes_title"
+msgstr "Bläddra bland alla teman :: %1$s Add-ons"
+
+#. %s is the name of the category
+#: controllers/addons_controller.php:1016
+#, php-format
+msgid "addons_browse_browse_category"
+msgstr "Bläddra bland %s"
+
+#. %1 is the name of the theme category (eg. Modern)
+#. %2 is the name of the Application (eg. Firefox)
+#: controllers/addons_controller.php:664
+msgid "addons_browse_categories_header_theme"
+msgstr "Bläddra bland %1$s teman :: %2$s tillägg"
+
+#: views/addons/display.thtml:249
+msgid "addons_display_a_license_what"
+msgstr "Vad är detta?"
+
+#: views/reviews/display.thtml:222
+msgid "addons_display_add_review"
+msgstr "Lägg till recension"
+
+#: views/addons/display.thtml:294
+msgid "addons_display_advanced_details"
+msgstr "Avancerad information"
+
+#: views/addons/display.thtml:98
+msgid "addons_display_categories"
+msgstr "Kategorier"
+
+#: views/addons/display.thtml:482
+msgid "addons_display_collection_add"
+msgstr "Lägg till samling:"
+
+#: views/addons/display.thtml:491
+msgid "addons_display_collection_add_new"
+msgstr "Ny samling..."
+
+#: views/addons/display.thtml:487
+msgid "addons_display_collection_add_select_one"
+msgstr "Välj en samling..."
+
+#: views/addons/display.thtml:493
+msgid "addons_display_collection_add_submit"
+msgstr "Publicera"
+
+#. %1$s is the add-on name
+#. %2$s is the collection name, linked to the collection's page
+#: views/pages/js_constants.js.thtml:103 views/addons/display.thtml:61
+msgid "addons_display_collection_publish_success"
+msgstr "%1$s har lagts till %2$s-samlingen."
+
+#: views/addons/display.thtml:483
+msgid "addons_display_collection_whatsthis"
+msgstr "Vad är detta?"
+
+#. %1$s is a number
+#: views/addons/display.thtml:473
+msgid "addons_display_collections_more"
+msgid_plural "addons_display_collections_more"
+msgstr[0] "och %1$s ytterligare samling"
+msgstr[1] "och %1$s ytterligare samlingar"
+
+#: views/addons/display.thtml:403
+msgid "addons_display_detailed_review"
+msgstr "utförlig recension"
+
+#: views/reviews/add.thtml:89 views/reviews/add.thtml:90
+msgid "addons_display_dont_like_it"
+msgstr "Gillar den inte"
+
+#: views/reviews/display.thtml:220
+msgid "addons_display_edit_review"
+msgstr "Redigera din recension"
+
+#: views/addons/display.thtml:132
+msgid "addons_display_has_privacy"
+msgstr "Detta tillägg har integritetsriktlinjer."
+
+#: views/reviews/add.thtml:87 views/reviews/add.thtml:88
+msgid "addons_display_hate_it"
+msgstr "Hatar det"
+
+#: views/addons/display.thtml:462
+msgid "addons_display_header_collections"
+msgstr "Relaterade samlingar"
+
+#: views/addons/display.thtml:297
+msgid "addons_display_header_developer_comments"
+msgstr "Utvecklarkommentarer"
+
+#: views/addons/display.thtml:230
+msgid "addons_display_header_homepage"
+msgstr "Hemsida"
+
+#: views/addons/display.thtml:247 views/addons/versions.thtml:110
+msgid "addons_display_header_license"
+msgstr "Källkodslicens"
+
+#: views/addons/display.thtml:337
+msgid "addons_display_header_reviews"
+msgstr "Recensioner"
+
+#: views/addons/display.thtml:261
+msgid "addons_display_header_support"
+msgstr "Hjälp"
+
+#: views/reviews/add.thtml:91 views/reviews/add.thtml:92
+msgid "addons_display_like_it"
+msgstr "Gillar det"
+
+#: views/addons/display.thtml:210
+msgid "addons_display_long_description"
+msgstr "Utförlig beskrivning"
+
+#: views/reviews/add.thtml:95 views/reviews/add.thtml:96
+msgid "addons_display_love_it"
+msgstr "Älskar det"
+
+#: views/addons/display.thtml:178
+msgid "addons_display_more_images"
+msgstr "Fler bilder"
+
+#: views/addons/display.thtml:465
+msgid "addons_display_nocollections"
+msgstr "Detta tillägg är inte inlagt i någon samling ännu."
+
+#. %1$s is either an author's name or a comma separated list of authors. Using
+#. the list doesn't make sense in the English plural form so we ignore the
+#. variable.
+#: views/addons/display.thtml:436
+msgid "addons_display_other_addons_by"
+msgid_plural "addons_display_other_addons_by"
+msgstr[0] "Andra tillägg från %1$s"
+msgstr[1] "Andra tillägg av dessa författare"
+
+#. %s is the name of the add-on and the add-on section. Example:
+#. Some Add-on :: Firefox Add-ons
+#. This should not be concatenated in the code and should be fixed.
+#: controllers/addons_controller.php:141 controllers/addons_controller.php:280
+#: controllers/addons_controller.php:1442
+#, php-format
+msgid "addons_display_pagetitle"
+msgstr "%s"
+
+#. %s is an email address
+#: views/addons/display.thtml:286
+#, php-format
+msgid "addons_display_paragraph_supportinfoemail"
+msgstr "Hjälp för denna utökning ges av utvecklaren på %s."
+
+#. %$1s is a URL
+#. %$2s is an email address
+#: views/addons/display.thtml:269
+#, php-format
+msgid "addons_display_paragraph_supportinfoemailurl"
+msgstr ""
+"Hjälp för denna utökning ges av utecklaren på %s eller genom att skicka e-"
+"post till %s."
+
+#. %s is a URL
+#: views/addons/display.thtml:278
+#, php-format
+msgid "addons_display_paragraph_supportinfourl"
+msgstr "Hjälp för denna utökning ges av utvecklaren på %s."
+
+#: views/addons/display.thtml:383
+msgid "addons_display_rate_it"
+msgstr "Betygsätt"
+
+#: views/reviews/add.thtml:93 views/reviews/add.thtml:94
+msgid "addons_display_really_like_it"
+msgstr "Tycker verkligen om det"
+
+#: views/addons/display.thtml:410
+msgid "addons_display_review_etiquette"
+msgstr ""
+"Skicka inte felrapporter i recensioner. Vi gör inte din e-postadress "
+"tillgänglig för tilläggsutvecklare och de kan behöva kontakta dig för att "
+"lösa ditt problem."
+
+#. %1 is the review guidelines link
+#: views/addons/display.thtml:417
+msgid "addons_display_review_guidelines_link"
+msgstr "<a href=\"%s\">riktlinjer för recensioner</a>"
+
+#. %1 is the support section link
+#: views/addons/display.thtml:414
+msgid "addons_display_review_see_support"
+msgstr ""
+"Se <a href=\"%1$s\">hjälpsektionen</a> för att ta reda på var du kan få "
+"hjälp med detta tillägg."
+
+#: views/addons/display.thtml:404
+msgid "addons_display_review_submit"
+msgstr "Spara"
+
+#: views/addons/display.thtml:430
+#, php-format
+msgid "addons_display_see_all_addons"
+msgstr "Visa alla %1$s tillägg"
+
+#. %1 is the number of reviews
+#: views/addons/display.thtml:364
+#, php-format
+msgid "addons_display_see_all_reviews"
+msgstr "Visa alla recensioner (%1$s)"
+
+#: views/addons/display.thtml:219
+msgid "addons_display_see_all_versions"
+msgstr "Visa alla versioner"
+
+#: views/addons/display.thtml:321 views/addons/versions.thtml:117
+msgid "addons_display_view_source"
+msgstr "Visa källkoden"
+
+#: views/addons/display.thtml:324
+msgid "addons_display_view_stats"
+msgstr "Visa statistik"
+
+#: views/addons/display.thtml:376
+msgid "addons_display_what_do_you_think"
+msgstr "Vad tycker du?"
+
+#: views/elements/app_compatibility.thtml:49
+msgid "addons_display_workswith"
+msgstr "Fungerar med:"
+
+#: views/addons/home.thtml:112
+msgid "addons_home_browse_new"
+msgstr "Nyss inlagda"
+
+#: views/addons/home.thtml:110
+msgid "addons_home_browse_popular"
+msgstr "Populära"
+
+#: views/addons/home.thtml:108
+msgid "addons_home_browse_recommended"
+msgstr "Rekommenderade"
+
+#: views/addons/home.thtml:127 views/addons/home.thtml:134
+#: views/addons/home.thtml:141 views/addons/home.thtml:148
+msgid "addons_home_browse_subscribe"
+msgstr "Prenumerera"
+
+#: views/addons/home.thtml:101
+msgid "addons_home_browse_title"
+msgstr "Bläddra bland tillägg"
+
+#: views/addons/home.thtml:114
+msgid "addons_home_browse_updated"
+msgstr "Uppdaterade"
+
+#: views/elements/amo2009/homepage_addon.thtml:100
+#: views/elements/addon_discussionheader.thtml:83
+#: views/elements/addon_listitem.thtml:109 views/elements/feature.thtml:95
+#: views/addons/category_landing.thtml:66 views/addons/policy.thtml:57
+#: views/addons/display.thtml:70 views/addons/home.thtml:178
+msgid "addons_home_by"
+msgstr "av"
+
+#: views/addons/home.thtml:169
+msgid "addons_home_collection_popular_title"
+msgstr "Populära samlingar"
+
+#: views/elements/amo2009/categories.thtml:69 views/addons/home.thtml:160
+msgid "addons_home_collections"
+msgstr "Samlingar"
+
+#. %1$s is the count of addons in a collection
+#: views/elements/amo2009/collection_listing_item.thtml:51
+#: views/addons/home.thtml:185
+msgid "addons_home_collections_addon_count"
+msgid_plural "addons_home_collections_addon_count"
+msgstr[0] "<strong>%1$s</strong> tillägg"
+msgstr[1] "<strong>%1$s</strong> tillägg"
+
+#: views/addons/home.thtml:196
+msgid "addons_home_collections_all"
+msgstr "Visa alla samlingar"
+
+#: views/addons/home.thtml:162
+msgid "addons_home_collections_intro"
+msgstr ""
+"Samlingar är ett sätt för dig att kategorisera, blanda, mixa och matcha "
+"tillägg. Prenumerera på samlingar skapad av andra användare eller skapa din "
+"egen."
+
+#. %1$s is the count of subscribers for a collection
+#: views/elements/amo2009/collection_listing_item.thtml:58
+#: views/collections/detail.thtml:96 views/addons/home.thtml:189
+msgid "addons_home_collections_subscribers"
+msgid_plural "addons_home_collections_subscribers"
+msgstr[0] "<strong>%1$s</strong> prenumerant"
+msgstr[1] "<strong>%1$s</strong> prenumeranter"
+
+#: views/addons/searchengines.thtml:54 views/addons/themes_landing.thtml:49
+msgid "addons_home_feature_head"
+msgstr "Vi rekommenderar"
+
+#: controllers/search_controller.php:218 controllers/addons_controller.php:176
+#: controllers/addons_controller.php:428 controllers/addons_controller.php:671
+#: controllers/addons_controller.php:871
+#: controllers/addons_controller.php:1103
+#: controllers/addons_controller.php:1242
+#: controllers/addons_controller.php:1298
+#, php-format
+msgid "addons_home_header_details"
+msgstr ""
+"Tillägg utökar %1$s och låter dig göra din webbupplevelse mer personlig. "
+"Titta runt lite och skapa din egen %1$s."
+
+#. %1$s is the HTML collection name link.
+#: views/elements/amo2009/teaser_collections.thtml:107
+msgid "addons_home_introduction_collection_link"
+msgstr "Gillar du dessa? Hitta fler tillägg i %1$s."
+
+#: views/elements/amo2009/teaser_collections.thtml:60
+msgid "addons_home_introduction_extras"
+msgstr ""
+"<strong>Mer än 5000 gratis tillägg</strong> som låter dig anpassa och utöka "
+"Firefox så den uppfyller dina behov."
+
+#: views/elements/amo2009/teaser_collections.thtml:55
+msgid "addons_home_introduction_header"
+msgstr "Vad är tillägg?"
+
+#: views/elements/amo2009/teaser_collections.thtml:72
+msgid "addons_home_introduction_install"
+msgstr ""
+"<strong>Lätt att installera</strong>, bli underrättade när uppdateringar "
+"finns tillgängliga."
+
+#: views/elements/amo2009/teaser_collections.thtml:45
+msgid "addons_home_introduction_name"
+msgstr "Introduktion"
+
+#: views/elements/amo2009/teaser_collections.thtml:66
+msgid "addons_home_introduction_themes"
+msgstr ""
+"Verktygsrader, teman och sökmotorer som <strong>hjälper dig utföra dina "
+"vanliga sysslor.</strong>"
+
+#: views/addons/home.thtml:161
+msgid "addons_home_new_indicator"
+msgstr "NYTT!"
+
+#: views/elements/app_chooser.thtml:48 views/layouts/amo2009.thtml:257
+msgid "addons_home_other_applications"
+msgstr "Andra applikationer"
+
+#. %1$s is the application the user is browsing. Examples: Thunderbird, Firefox,
+#. Sunbird
+#: views/pages/collector_faq.thtml:49 views/pages/collector_firstrun.thtml:42
+#: views/pages/collector.thtml:46 views/pages/collector_features.thtml:54
+#: controllers/developers_controller.php:87
+#: controllers/compatibility_controller.php:72
+#: controllers/components/simple_acl.php:81 controllers/components/amo.php:607
+#: controllers/statistics_controller.php:60
+#: controllers/statistics_controller.php:240
+#: controllers/previews_controller.php:67 controllers/users_controller.php:90
+#: controllers/users_controller.php:223 controllers/users_controller.php:330
+#: controllers/users_controller.php:414 controllers/users_controller.php:708
+#: controllers/users_controller.php:723 controllers/reviews_controller.php:204
+#: controllers/reviews_controller.php:251
+#: controllers/reviews_controller.php:346
+#: controllers/reviews_controller.php:425
+#: controllers/search_controller.php:185 controllers/search_controller.php:297
+#: controllers/search_controller.php:301 controllers/addons_controller.php:147
+#: controllers/addons_controller.php:280 controllers/addons_controller.php:370
+#: controllers/addons_controller.php:667 controllers/addons_controller.php:874
+#: controllers/addons_controller.php:1019
+#: controllers/addons_controller.php:1034
+#: controllers/addons_controller.php:1101
+#: controllers/addons_controller.php:1121
+#: controllers/addons_controller.php:1240
+#: controllers/addons_controller.php:1357
+#: controllers/addons_controller.php:1364
+#: controllers/addons_controller.php:1442
+#: controllers/addons_controller.php:1477
+#: controllers/addons_controller.php:1538
+#: controllers/addons_controller.php:1543
+#: controllers/editors_controller.php:64 controllers/pages_controller.php:132
+#: controllers/groups_controller.php:65 controllers/groups_controller.php:71
+#: controllers/groups_controller.php:89 controllers/groups_controller.php:111
+#: controllers/collections_controller.php:57
+#: controllers/collections_controller.php:121
+#: controllers/collections_controller.php:205
+#: controllers/collections_controller.php:365
+#: controllers/collections_controller.php:404
+#: controllers/collections_controller.php:466
+#: controllers/collections_controller.php:538
+#: controllers/collections_controller.php:828
+#: controllers/localizers_controller.php:72
+#, php-format
+msgid "addons_home_pagetitle"
+msgstr "%1$s Add-ons"
+
+#. %1$s is the number of addons downloaded
+#: views/addons/home.thtml:57
+#, php-format
+msgid "addons_home_stats_downloaded"
+msgid_plural "addons_home_stats_downloaded"
+msgstr[0] "<strong>%1$s</strong> <span>tillägg nedladdat</span>"
+msgstr[1] "<strong>%1$s</strong> <span>tillägg nedladdade</span>"
+
+#. %1$s is the number of addons in use
+#: views/addons/home.thtml:63
+#, php-format
+msgid "addons_home_stats_inuse"
+msgid_plural "addons_home_stats_inuse"
+msgstr[0] "<strong>%1$s</strong> <span>tillägg används</span>"
+msgstr[1] "<strong>%1$s</strong> <span>tillägg används</span>"
+
+#: views/addons/home.thtml:136
+msgid "addons_home_view_all_newest_title"
+msgstr "Visa alla nyligen skapade tillägg"
+
+#: views/addons/home.thtml:129
+msgid "addons_home_view_all_popular_title"
+msgstr "Visa alla populära tillägg"
+
+#: views/addons/home.thtml:150
+msgid "addons_home_view_all_recommended_title"
+msgstr "Visa alla rekommenderade tillägg"
+
+#: views/addons/home.thtml:143
+msgid "addons_home_view_all_updated_title"
+msgstr "Visa alla nyligen uppdaterade tillägg"
+
+#: views/elements/amo2009/install.thtml:334 views/elements/install.thtml:112
+msgid "addons_install_in_sunbird"
+msgstr ""
+"<ol><li>Klicka på länken nedan för att spara filen.</li><li>I Mozilla "
+"Sunbird, öppna Tillägg från Verktygsmenyn.</li><li>Klicka på knappen "
+"Installera och hitta/välj filen du laddat ner och tryck \"Öppna\".</li></ol>"
+
+#: views/elements/amo2009/install.thtml:333 views/elements/install.thtml:111
+msgid "addons_install_in_sunbird_title"
+msgstr "Hur du installerar i Sunbird"
+
+#: views/elements/amo2009/install.thtml:331 views/elements/install.thtml:106
+msgid "addons_install_in_thunderbird"
+msgstr ""
+"<ol><li>Högerklicka på länken nedan och välj \"Spara länk som...\" för att "
+"hämta hem och spara filen till din hårddisk.</li><li>I Mozilla Thunderbird, "
+"öppna Tillägg från Verktygsmenyn.</li><li>Klicka på knappen Installera, leta "
+"på och välj filen du hämtat hem och klicka \"OK\".</li></ol>"
+
+#: views/elements/amo2009/install.thtml:330 views/elements/install.thtml:105
+msgid "addons_install_in_thunderbird_title"
+msgstr "Hur man installerar i Thunderbird"
+
+#: views/elements/amo2009/addon_list_options.thtml:108
+#: views/elements/addon_list_options.thtml:105
+msgid "addons_options_show_experimental"
+msgstr "visa experimentella tillägg"
+
+#: views/elements/amo2009/addon_list_options.thtml:113
+#: views/elements/addon_list_options.thtml:109
+msgid "addons_options_submit"
+msgstr "Skicka"
+
+#: views/addons/plugins.thtml:63 views/addons/plugins.thtml:73
+#: views/addons/plugins.thtml:83 views/addons/plugins.thtml:93
+#: views/addons/plugins.thtml:103 views/addons/plugins.thtml:116
+#: views/addons/plugins.thtml:126
+msgid "addons_plugins_by"
+msgstr "från"
+
+#: views/addons/plugins.thtml:107
+msgid "addons_plugins_for_linux"
+msgstr "för Linux"
+
+#: views/addons/plugins.thtml:108 views/addons/plugins.thtml:131
+msgid "addons_plugins_for_macosx"
+msgstr "för Mac OS X"
+
+#: views/addons/plugins.thtml:106 views/addons/plugins.thtml:129
+#: views/addons/plugins.thtml:130
+msgid "addons_plugins_for_windows"
+msgstr "för Windows"
+
+#. %1$s is a URL
+#: views/addons/plugins.thtml:139
+#, php-format
+msgid "addons_plugins_looking_for_more"
+msgstr ""
+"Den här sidan listar bara några av de vanligaste och populära "
+"insticksprogrammen. För mer information om andra tillgängliga "
+"insticksprogram för Mozilla-baserade webbläsare, besök %1$s"
+
+#: views/addons/plugins.thtml:137
+msgid "addons_plugins_looking_for_plugin"
+msgstr "Letar du efter ett insticksprogram som inte finns listat här"
+
+#: views/addons/plugins.thtml:58
+msgid "addons_plugins_main_description"
+msgstr ""
+"Insticksprogram hjälper din webbläsare utföra särskilda funktioner som att "
+"visasärskilda grafikformat eller spela multimediafiler. Insticksprogram "
+"skiljer sig litefrån utökningar, som ändrar eller utökar existerande "
+"funktionalitet."
+
+#. %1$s is the application name. Example: Firefox, Thunderbird, Sunbird
+#: controllers/addons_controller.php:1122
+#, php-format
+msgid "addons_plugins_main_header"
+msgstr "Vanliga insticksprogram för %1$s"
+
+#: controllers/components/amo.php:698 controllers/addons_controller.php:1121
+msgid "addons_plugins_pagetitle"
+msgstr "Insticksprogram"
+
+#: views/addons/plugins.thtml:68 views/addons/plugins.thtml:78
+#: views/addons/plugins.thtml:88 views/addons/plugins.thtml:98
+#: views/addons/plugins.thtml:110 views/addons/plugins.thtml:121
+#: views/addons/plugins.thtml:133
+msgid "addons_plugins_support_documentation"
+msgstr "Hjälpdokumentation: "
+
+#. %s is the name of the add-on
+#: views/addons/policy.thtml:61
+#, php-format
+msgid "addons_policy_eula_require"
+msgstr ""
+"%s kräver att du accepterar följande användaravtal innan installationen kan "
+"fortsätta:"
+
+#. %1 is the add-on name
+#: controllers/addons_controller.php:1476
+#, php-format
+msgid "addons_previews_pagetitle"
+msgstr "Förhandsvisningar för %s"
+
+#: views/addons/category_landing.thtml:135
+msgid "addons_recently_added"
+msgstr "Nyligen tillagt"
+
+#: views/addons/recommended.thtml:51 controllers/addons_controller.php:1365
+msgid "addons_recommended_introduction"
+msgstr ""
+"Med så många utmärkta tillägg tillgängliga finns det alltid något för alla. "
+"För att komma igång får du här en lista med de populäraste. Lycka till!"
+
+#: controllers/addons_controller.php:1357
+#: controllers/addons_controller.php:1364
+msgid "addons_recommended_pagetitle"
+msgstr "Rekommenderade tillägg"
+
+#: controllers/addons_controller.php:1360
+msgid "addons_recommended_title"
+msgstr "Rekommenderat tillägg"
+
+#: views/addons/searchengines.thtml:136
+msgid "addons_searchengines_additional_resources"
+msgstr "Ytterligare resurser"
+
+#. link text devmo
+#: views/addons/searchengines.thtml:141
+msgid "addons_searchengines_devmo_link"
+msgstr "Mozilla Utvecklarcenter"
+
+#: views/pages/js_constants.js.thtml:67
+msgid "addons_searchengines_error_mozilla_browser_required"
+msgstr ""
+"Tyvärr, du behöver en Mozilla-baserad webbläsare (som Firefox) för att "
+"installera sökmotorer."
+
+#: views/addons/searchengines.thtml:49
+msgid "addons_searchengines_error_nojavascript"
+msgstr ""
+"JavaScript krävs för att installera tillägg, men det verkar som att du har "
+"det avstängt. Slå på JavaScript innan du försöker installera någon av "
+"sökmotorerna nedan."
+
+#. %1 is "make your own" link
+#. %2 is MDC link
+#: views/addons/searchengines.thtml:139
+msgid "addons_searchengines_learn_howto"
+msgstr "Lär hur du %1$s på %2$s."
+
+#. link path to search plugins instructions, relative to devmo
+#: views/addons/searchengines.thtml:140
+msgid "addons_searchengines_makeyourown_href"
+msgstr "/en/docs/Creating_OpenSearch_plugins_for_Firefox"
+
+#. link text for "make your own" (opensearch engine)
+#: views/addons/searchengines.thtml:140
+msgid "addons_searchengines_makeyourown_link"
+msgstr "gör din egen"
+
+#. %1 is the link to mycroft.mozdev.org
+#: views/addons/searchengines.thtml:138
+msgid "addons_searchengines_more"
+msgstr "Bläddra bland fler sökmotorer på %1$s"
+
+#. link text to mycroft.mozdev.org
+#: views/addons/searchengines.thtml:138
+msgid "addons_searchengines_mycroft_link"
+msgstr "mycroft.mozdev.org"
+
+#: controllers/addons_controller.php:1100
+#: controllers/addons_controller.php:1110
+msgid "addons_searchengines_pagetitle"
+msgstr "Sökmotorer"
+
+#: views/addons/searchengines.thtml:143
+msgid "addons_searchengines_thanks"
+msgstr ""
+"Särskilt tack till Mycroft-projektet för deras arbete med Firefox-sökmotorer."
+
+#: views/addons/display.thtml:154
+msgid "addons_share_button_text"
+msgstr "Dela detta"
+
+#: controllers/addons_controller.php:89
+msgid "addons_share_label_delicious"
+msgstr "Lägg till Delicious"
+
+#: controllers/addons_controller.php:77
+msgid "addons_share_label_digg"
+msgstr "Digga detta!"
+
+#: controllers/addons_controller.php:83
+msgid "addons_share_label_facebook"
+msgstr "Posta till Facebook"
+
+#: controllers/addons_controller.php:101
+msgid "addons_share_label_friendfeed"
+msgstr "Dela med FriendFeed"
+
+#: controllers/addons_controller.php:95
+msgid "addons_share_label_myspace"
+msgstr "Posta till MySpace"
+
+#: controllers/components/amo.php:201 controllers/components/amo.php:229
+msgid "addons_status_disabled"
+msgstr "Avstängd"
+
+#: controllers/components/amo.php:191 controllers/components/amo.php:224
+msgid "addons_status_incomplete"
+msgstr "Inkomplett version"
+
+#: controllers/components/amo.php:197 controllers/components/amo.php:227
+msgid "addons_status_nominated"
+msgstr "I sandlådan; Nominerad för publik"
+
+#: views/pages/js_constants.js.thtml:80 controllers/components/amo.php:195
+#: controllers/components/amo.php:226
+msgid "addons_status_pending"
+msgstr "I sandlådan; avvaktar granskning"
+
+#: views/pages/js_constants.js.thtml:78 controllers/components/amo.php:199
+#: controllers/components/amo.php:228
+msgid "addons_status_public"
+msgstr "Publik"
+
+#: views/pages/js_constants.js.thtml:79 controllers/components/amo.php:193
+#: controllers/components/amo.php:225
+msgid "addons_status_sandbox"
+msgstr "I sandlådan"
+
+#: controllers/components/amo.php:203
+msgid "addons_status_unknown"
+msgstr "Okänd"
+
+#: views/elements/amo2009/teaser_collections.thtml:91
+#: views/elements/amo2009/homepage_addon.thtml:99
+#: views/elements/feature.thtml:94
+msgid "addons_title_tooltip"
+msgstr "Läs mer om detta tillägg"
+
+#: views/addons/category_landing.thtml:151
+msgid "addons_top_downloads"
+msgstr "Mest nedladdat"
+
+#: views/addons/category_landing.thtml:165
+msgid "addons_top_rated"
+msgstr "Högst betyg"
+
+#: views/addons/versions.thtml:62
+msgid "addons_versions_careful"
+msgstr "Var försiktig med gamla versioner"
+
+#: views/addons/versions.thtml:63
+msgid "addons_versions_careful_introduction"
+msgstr ""
+"Dessa versioner visas för referens och teständamål. Du bör alltid använda "
+"den senaste versionen av ett tillägg."
+
+#: controllers/addons_controller.php:1549
+msgid "addons_versions_history"
+msgstr "Versionshistorik med ändringsloggar"
+
+#. %1$s is the add-on name
+#: controllers/addons_controller.php:1535
+#, php-format
+msgid "addons_versions_pagetitle"
+msgstr "%1$s versionshistorik"
+
+#: controllers/groups_controller.php:71
+msgid "admin_group_add_pagetitle"
+msgstr "Lägg till grupp"
+
+#: controllers/groups_controller.php:111
+msgid "admin_group_delete_pagetitle"
+msgstr "Ta bort grupp"
+
+#. %s is a number to identify the group
+#: controllers/groups_controller.php:117
+#, php-format
+msgid "admin_group_deleted"
+msgstr "Gruppen med id %s togs bort"
+
+#: controllers/groups_controller.php:89
+msgid "admin_group_edit_pagetitle"
+msgstr "Redigera grupp"
+
+#: controllers/groups_controller.php:92 controllers/groups_controller.php:113
+msgid "admin_group_error_invalid_id"
+msgstr "Felaktigt id för grupp"
+
+#: controllers/groups_controller.php:65
+msgid "admin_group_pagetitle"
+msgstr "Gruppadministratör"
+
+#: controllers/groups_controller.php:77 controllers/groups_controller.php:99
+msgid "admin_group_saved"
+msgstr "Gruppen har sparats"
+
+#: views/elements/amo2009/search.thtml:257 views/elements/search.thtml:239
+msgid "advanced_search_form"
+msgstr "Avancerad"
+
+#: views/elements/amo2009/search.thtml:126 views/elements/search.thtml:125
+msgid "advanced_search_form_any_time"
+msgstr "När som helst"
+
+#: views/elements/amo2009/search.thtml:97
+#: views/elements/amo2009/search.thtml:110 views/elements/search.thtml:96
+#: views/elements/search.thtml:109
+msgid "advanced_search_form_any_type"
+msgstr "Alla"
+
+#: views/elements/amo2009/search.thtml:275 views/elements/search.thtml:254
+msgid "advanced_search_form_any_version"
+msgstr "Alla"
+
+#: views/elements/amo2009/search.thtml:217 views/elements/search.thtml:212
+msgid "advanced_search_form_application"
+msgstr "Applikation"
+
+#: views/elements/amo2009/search.thtml:143 views/elements/search.thtml:142
+msgid "advanced_search_form_keyword_match"
+msgstr "Nyckelordspassning"
+
+#: views/elements/amo2009/search.thtml:251 views/elements/search.thtml:225
+msgid "advanced_search_form_lastupdate"
+msgstr "Senast uppdaterad"
+
+#: views/elements/amo2009/search.thtml:145 views/elements/search.thtml:144
+msgid "advanced_search_form_name"
+msgstr "Namn"
+
+#: views/elements/amo2009/search.thtml:144 views/elements/search.thtml:143
+msgid "advanced_search_form_newest"
+msgstr "Nyast"
+
+#: views/elements/amo2009/search.thtml:130 views/elements/search.thtml:129
+msgid "advanced_search_form_past_3_months"
+msgstr "Senaste 3 månaderna"
+
+#: views/elements/amo2009/search.thtml:131 views/elements/search.thtml:130
+msgid "advanced_search_form_past_6_months"
+msgstr "Senaste 6 månaderna"
+
+#: views/elements/amo2009/search.thtml:127 views/elements/search.thtml:126
+msgid "advanced_search_form_past_day"
+msgstr "Senaste dagen"
+
+#: views/elements/amo2009/search.thtml:129 views/elements/search.thtml:128
+msgid "advanced_search_form_past_month"
+msgstr "Senaste månaden"
+
+#: views/elements/amo2009/search.thtml:128 views/elements/search.thtml:127
+msgid "advanced_search_form_past_week"
+msgstr "Senaste veckan"
+
+#: views/elements/amo2009/search.thtml:132 views/elements/search.thtml:131
+msgid "advanced_search_form_past_year"
+msgstr "Senaste året"
+
+#: views/elements/amo2009/search.thtml:239 views/elements/search.thtml:230
+msgid "advanced_search_form_perpage"
+msgstr "Per sida"
+
+#: views/elements/amo2009/search.thtml:243 views/elements/search.thtml:224
+msgid "advanced_search_form_platform"
+msgstr "Plattform"
+
+#: views/elements/amo2009/search.thtml:147 views/elements/search.thtml:146
+msgid "advanced_search_form_popularity"
+msgstr "Popularitet"
+
+#: views/elements/amo2009/search.thtml:146 views/elements/search.thtml:145
+msgid "advanced_search_form_rating"
+msgstr "Betyg"
+
+#: views/elements/amo2009/search.thtml:247 views/elements/search.thtml:231
+msgid "advanced_search_form_sortby"
+msgstr "Sortera på"
+
+#: views/elements/amo2009/search.thtml:227 views/elements/search.thtml:216
+msgid "advanced_search_form_to"
+msgstr "till"
+
+#: views/elements/amo2009/search.thtml:257 views/elements/search.thtml:237
+msgid "advanced_search_form_toggle_tooltip"
+msgstr "Växla mellan enkelt och avancerat sökläge"
+
+#: views/elements/amo2009/search.thtml:235 views/elements/search.thtml:223
+msgid "advanced_search_form_type"
+msgstr "Typ"
+
+#: views/elements/amo2009/search.thtml:222 views/elements/search.thtml:214
+msgid "advanced_search_form_version"
+msgstr "version"
+
+#: views/elements/amo2009/pagination.thtml:42
+msgid "amo2009_pagination_next_page"
+msgstr "Nästa"
+
+#: views/elements/amo2009/pagination.thtml:41
+msgid "amo2009_pagination_previous_page"
+msgstr "Föreg"
+
+#: views/pages/js_constants.js.thtml:96
+msgid "app_compat_ignore_check"
+msgstr "Ignorera versionskontroll"
+
+#: views/pages/js_constants.js.thtml:72
+msgid "app_compat_older_firefox_only"
+msgstr "Detta tillägg är för en äldre version av Firefox"
+
+#. %1$s and %2$s are URLs
+#: views/pages/js_constants.js.thtml:74
+msgid "app_compat_older_version_or_ignore_check"
+msgstr ""
+"Du kan <a href=\"%1$s\">testa en äldre version</a> eller <a href=\"#\" "
+"onclick=\"%2$s\">strunta i den här kontrollen</a>"
+
+#. %1$s is a URL
+#: views/pages/js_constants.js.thtml:71
+msgid "app_compat_try_old_version"
+msgstr "En <a href=\"%1$s\">äldre version</a> kanske fungerar"
+
+#. %1$s is a URL
+#. %2$s is a version number. Example: 3.1
+#: views/pages/js_constants.js.thtml:73
+msgid "app_compat_unreleased_version"
+msgstr ""
+"Detta tillägg kräver den ännu ej släppta <a href=\"%1$s\">Firefox %2$s</a>"
+
+#: views/pages/js_constants.js.thtml:70
+msgid "app_compat_update_firefox"
+msgstr ""
+"<a href=\"http://getfirefox.com\">Uppgradera Firefox</a> för att använda "
+"detta tillägg"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#. %3$s is a status, like Public.
+#: controllers/components/audit.php:79
+msgid "audit_addon_status"
+msgstr "%1$s ändrade status för %2$s till %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:221
+msgid "audit_admin_default"
+msgstr "%1$s utförde okänd administrativ handling %2$s på id %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:153
+msgid "audit_admin_feature_remove"
+msgstr "%1$s tog bort egenskapen %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is an application, like Firefox.
+#: controllers/components/audit.php:92
+msgid "audit_application_create"
+msgstr "%1$s skapad applikationen %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is an application, like Firefox.
+#: controllers/components/audit.php:95
+msgid "audit_application_edit"
+msgstr "%1$s redigerade applikationen %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a version number, like 3.5.
+#. %3$s is an application, like Firefox.
+#: controllers/components/audit.php:105
+msgid "audit_appversion_create"
+msgstr "%1$s skapade version %2$s för %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a version number, like 3.5.
+#. %3$s is an application, like Firefox.
+#: controllers/components/audit.php:108
+msgid "audit_appversion_delete"
+msgstr "%1$s tog bort version %2$s för %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a config field, like "awesomeness".
+#. %3$s is a config value, like "off".
+#. %4$s is a config value, like "on".
+#: controllers/components/audit.php:210
+msgid "audit_config"
+msgstr "%1$s ändrade inställningen '%2$s' från '%3$s' till '%4$s'"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:258
+msgid "audit_editor_default"
+msgstr "%1$s utförde okänd redaktörshandling %2$s på id %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#: controllers/components/audit.php:236
+msgid "audit_editor_feature_remove"
+msgstr "%1$s tog bort %2$s från framhävningslistan"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#: controllers/components/audit.php:231
+msgid "audit_feature_add"
+msgstr "%1$s lade till tillägget %2$s till framhävningslistan"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:149
+msgid "audit_feature_edit"
+msgstr "%1$s ändrade en framhävning för %2$s lokalen"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#: controllers/components/audit.php:241
+msgid "audit_feature_locale_change"
+msgstr "%1$s ändrade lokaler för tillägget %2$s på framhävningslistan"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:83
+msgid "audit_file_recalchash"
+msgstr "%1$s kalkylerade om hashen för filen %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>user name</a>
+#. %3$s is <a>group name</a>
+#: controllers/components/audit.php:182
+msgid "audit_group_addmember"
+msgstr "%1$s adderade %2$s till gruppen %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:313
+msgid "audit_group_associated"
+msgstr "%1$s för knippade sig själv med %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:162
+msgid "audit_group_create"
+msgstr "%1s skapade gruppen %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:170
+msgid "audit_group_delete"
+msgstr "%1$s tog bot gruppen %2$s (ID %3$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:165
+msgid "audit_group_edit"
+msgstr "%1$s redigerade gruppen %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>user name</a>
+#. %3$s is <a>group name</a>
+#: controllers/components/audit.php:188
+msgid "audit_group_removemember"
+msgstr "%1$s tog bort %2$s från gruppen %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:280
+msgid "audit_l10n_default"
+msgstr "%1$s utförde okände handling %2$s för %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:295
+msgid "audit_modify_locked_group"
+msgstr "%1$s försökte ändra den låsta gruppen %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:299
+msgid "audit_modify_other_locale"
+msgstr "%1$s försökte ändra översättningar i %2$s utan att ha rätt till det"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a platform, like <a>Windows</a>
+#: controllers/components/audit.php:135
+msgid "audit_platform_create"
+msgstr "%1$s skapade plattformen %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a platform, like <a>Windows</a>
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:143
+msgid "audit_platform_delete"
+msgstr "%1$s tog bort plattformen %2$s (ID %3$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a platform, like <a>Windows</a>
+#: controllers/components/audit.php:138
+msgid "audit_platform_edit"
+msgstr "%1$s ändrade plattformen %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a part of the admin, like 'Site Config'
+#: controllers/components/audit.php:288
+msgid "audit_reauthentication_failure"
+msgstr "%1$s kunde inte omautentisera sig för att komma åt %2$s."
+
+#. %1$s is <a>user name</a>
+#. %2$s is the name of a canned response, like 'Ready for the public'
+#: controllers/components/audit.php:198
+msgid "audit_response_create"
+msgstr "%1$s skapade svaret %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is the name of a canned response, like 'Ready for the public'
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:206
+msgid "audit_response_delete"
+msgstr "%1$s tog bort svaret %2$s (ID %3$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is the name of a canned response, like 'Ready for the public'
+#: controllers/components/audit.php:201
+msgid "audit_response_edit"
+msgstr "%1$s ändrade svaret %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:245
+msgid "audit_review_approve"
+msgstr "%1$s godkände granskningen %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:250 controllers/components/audit.php:253
+msgid "audit_review_delete"
+msgstr "%1$s tog bort granskningen %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:303
+msgid "audit_security_default"
+msgstr "%1$s utförde okänd säkerhetshandling %2$s på id %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a category name, like <a>Search Tools</a>
+#: controllers/components/audit.php:118
+msgid "audit_tag_create"
+msgstr "%1$s skapade etiketten %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a category name, like <a>Search Tools</a>
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:126
+msgid "audit_tag_delete"
+msgstr "%1$s tog bort kategorin %2$s (ID %3$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a category name, like <a>Search Tools</a>
+#: controllers/components/audit.php:121
+msgid "audit_tag_edit"
+msgstr "%1$s redigerade kategorin %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:266
+msgid "audit_update_applications"
+msgstr "%1$s uppdaterade applikationsöversättningen för %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:277
+msgid "audit_update_blog"
+msgstr "%1$s uppdaterade översättningar av bloggposter för %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:274
+msgid "audit_update_platforms"
+msgstr "%1$s uppdaterade plattformsöversättningarna för %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:270
+msgid "audit_update_tags"
+msgstr "%1$s uppdaterade kategoriöversättningarna för %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>user name</a>
+#: controllers/components/audit.php:217
+msgid "audit_user_edit"
+msgstr "%1$s ändrade %2$ss användarinformation"
+
+#: controllers/addons_controller.php:1012
+msgid "browse_addons_name"
+msgstr "Tillägg sorterade på namn"
+
+#: controllers/addons_controller.php:1010
+msgid "browse_addons_newest"
+msgstr "Nyaste tilläggen"
+
+#: controllers/addons_controller.php:1008
+msgid "browse_addons_popular"
+msgstr "Populära tillägg"
+
+#: controllers/addons_controller.php:1011
+msgid "browse_addons_rated"
+msgstr "Tillägg sorterade på betyg"
+
+#: controllers/addons_controller.php:1009
+msgid "browse_addons_updated"
+msgstr "Nyligen uppdaterade tillägg"
+
+#: views/elements/categories.thtml:73 views/elements/categories.thtml:82
+msgid "categories_current_title"
+msgstr "Nuvarande kategori"
+
+#: views/elements/categories.thtml:50
+#: views/elements/amo2009/categories.thtml:43
+#: views/elements/amo2009/categories.thtml:45
+msgid "categories_header"
+msgstr "Kategorier"
+
+#: views/elements/categories.thtml:50
+#: views/elements/amo2009/categories.thtml:41
+msgid "categories_header_title"
+msgstr "Välj en kategori"
+
+#. %1$s is the category name
+#: views/addons/searchengines.thtml:129
+#, php-format
+msgid "category_extra_see_all"
+msgstr "Visa alla %1$s"
+
+#. %1$s is a number.
+#: models/collection.php:130
+msgid "collection_description_limit"
+msgstr "Beskrivningen ska vara kortare än %1$s tecken."
+
+#. %1$s is the name of the collection
+#: controllers/collections_controller.php:392
+#, fuzzy
+msgid "collection_detail_rss_title"
+msgstr "%s Collection"
+
+#: controllers/collections_controller.php:1065
+msgid "collection_error_deleting_addon"
+msgstr "Fel vid borttagning av tillägg!"
+
+#: controllers/collections_controller.php:1051
+msgid "collection_error_saving_addon"
+msgstr "Fel vid sparning av tillägg!"
+
+#: controllers/collections_controller.php:1080
+msgid "collection_error_saving_comment"
+msgstr "Fel vid sparning av kommentar!"
+
+#. %1$s is a number.
+#: models/collection.php:122
+msgid "collection_name_limit"
+msgstr "Namnet ska vara kortare än 1$s tecken."
+
+#: controllers/collections_controller.php:352
+#: controllers/collections_controller.php:487
+msgid "collection_not_found"
+msgstr "Samling ej hittad!"
+
+#. %1$s is the text on the "create collection" button
+#: views/collections/add.thtml:91
+msgid "collections_add_formfield_addons_description"
+msgstr ""
+"Om du redan vet vilka tillägg du vill ha i din samling kan du börja skriva "
+"deras namn nedanför. Om du hellre väntar och gör detta senare så kan du "
+"klicka på %1$s nu."
+
+#: views/collections/add.thtml:90
+msgid "collections_add_formfield_firstaddons"
+msgstr "Välj ditt första tillägg"
+
+#: views/collections/add.thtml:48
+msgid "collections_add_header"
+msgstr "Skapa en samling"
+
+#: views/collections/add.thtml:97
+msgid "collections_add_header_selectedaddons"
+msgstr "Valda tillägg"
+
+#: views/collections/add.thtml:50
+msgid "collections_add_intro"
+msgstr ""
+"Det är lätt stt skapa din egen samling av tillägg genom att fylla i några "
+"fält nedanför."
+
+#: views/collections/add.thtml:92 views/collections/add.thtml:103
+msgid "collections_add_submit"
+msgstr "Skapa samling"
+
+#: views/pages/collector_faq.thtml:50 views/pages/collector_firstrun.thtml:43
+#: views/pages/collector.thtml:47 views/pages/collector_features.thtml:55
+#: controllers/search_controller.php:302
+#: controllers/collections_controller.php:206
+#: controllers/collections_controller.php:405
+#: controllers/collections_controller.php:467
+#: controllers/collections_controller.php:539
+msgid "collections_breadcrumb"
+msgstr "Samlingar"
+
+#: views/collections/detail.thtml:185
+msgid "collections_detail_a_learn"
+msgstr "Läs mer"
+
+#: views/elements/amo2009/collection_add_form.thtml:53
+#: views/elements/amo2009/collections_js_init.thtml:68
+#: views/pages/collector_firstrun.thtml:64
+msgid "collections_detail_button_add"
+msgstr "Lägg till Favoriter"
+
+#: views/elements/amo2009/collection_add_form.thtml:50
+#: views/elements/amo2009/collections_js_init.thtml:71
+msgid "collections_detail_button_remove"
+msgstr "Ta bort från Favoriter"
+
+#. %1$s is a URL.
+#. %2$s is a full <a href>.
+#: views/collections/detail.thtml:62
+#, fuzzy
+msgid "collections_detail_created_desc"
+msgstr ""
+"<p>You can view your new collection below. If you'd like to set a collection "
+"nickname, upload an icon, or change additional settings, please visit the <a "
+"href='%1$s'>Manage Collections</a> page.</p><p>Your collection can be "
+"accessed at this location: %2$s</p>"
+
+#: views/collections/detail.thtml:61
+#, fuzzy
+msgid "collections_detail_created_msg"
+msgstr "Your collection is now ready!"
+
+#: views/collections/detail.thtml:109
+msgid "collections_detail_header_about"
+msgstr "Om denna samling"
+
+#. %1$s is a number.
+#: views/collections/detail.thtml:126
+msgid "collections_detail_header_count"
+msgid_plural "collections_detail_header_count"
+msgstr[0] "%1$s tillägg i denna samling"
+msgstr[1] "%1$s tillägg i denna samling"
+
+#: views/collections/detail.thtml:113
+msgid "collections_detail_info_created"
+msgstr "<strong>Skapad av:</strong> %1$s"
+
+#: views/collections/detail.thtml:117
+msgid "collections_detail_info_updated"
+msgstr "<strong>Uppdaterad:</strong>"
+
+#: views/elements/amo2009/collections_js_init.thtml:62
+#, fuzzy
+msgid "collections_detail_js_adding"
+msgstr "Adding to Favorites&hellip;"
+
+#: views/elements/amo2009/collections_js_init.thtml:65
+#, fuzzy
+msgid "collections_detail_js_removing"
+msgstr "Removing Favorite&hellip;"
+
+#. %1$s is a URL
+#: views/collections/detail.thtml:90
+#, fuzzy
+msgid "collections_detail_login"
+msgstr "<a href=\"%1$s\">Log in</a> to add this collection to your favorites."
+
+#: views/collections/detail.thtml:104
+#, fuzzy
+msgid "collections_detail_manage"
+msgstr "Manage Collection"
+
+#: controllers/collections_controller.php:298
+msgid "collections_detail_sort_date"
+msgstr "Tillagd datum"
+
+#: controllers/collections_controller.php:299
+msgid "collections_detail_sort_name"
+msgstr "Namn"
+
+#: controllers/collections_controller.php:300
+msgid "collections_detail_sort_popularity"
+msgstr "Popularitet"
+
+#. %1$s is a number.
+#: views/collections/detail.thtml:166
+msgid "collections_detail_weekly_downloads"
+msgid_plural "collections_detail_weekly_downloads"
+msgstr[0] "%1$s nedladdning denna vecka"
+msgstr[1] "%1$s nedladdningar denna vecka"
+
+#: views/collections/edit.thtml:255
+msgid "collections_edit_addons_delete_noscript"
+msgstr "Valda tillägg tas bort vid sparning"
+
+#: views/collections/edit.thtml:247
+msgid "collections_edit_addons_description"
+msgstr ""
+"För att publicera nya tillägg i den här samling, börja skriv deras namn "
+"nedanför."
+
+#: views/collections/edit.thtml:248
+msgid "collections_edit_addons_description_noscript"
+msgstr ""
+"För att publicera nya tillägg i den här samling, ange en kommaseparerad "
+"lista af deras tillägsid nedanför."
+
+#: views/collections/edit.thtml:247 views/collections/edit.thtml:248
+msgid "collections_edit_addons_description_publish_detailspage"
+msgstr "Du kan också publicera ett tillägg från dess vanliga sida."
+
+#. %1$s is the date the add-on was added to the collection
+#. %1$s is the name of the user who added the add-on to the collection
+#: views/collections/edit.thtml:260
+msgid "collections_edit_addons_listitem_added"
+msgstr "lades till %1$s av %2$s"
+
+#: views/collections/edit.thtml:263
+msgid "collections_edit_addons_listitem_comment_add"
+msgstr "Lägg till kommentar till samling"
+
+#: views/collections/edit.thtml:266
+msgid "collections_edit_addons_listitem_comment_delete"
+msgstr "Ta bort kommentar till samling"
+
+#: views/collections/edit.thtml:265
+msgid "collections_edit_addons_listitem_comment_edit"
+msgstr "Redigera kommentar till samling"
+
+#: views/collections/edit.thtml:271
+msgid "collections_edit_addons_listitem_comment_note"
+msgstr ""
+"Obs: Kommentaren kommer att synas som om den vore skriven av den som "
+"ursprungligen publicerade, med det ursprungliga publiceringsdatumet"
+
+#: views/collections/edit.thtml:270
+msgid "collections_edit_addons_listitem_comment_submit"
+msgstr "Spara kommentar"
+
+#: views/collections/edit.thtml:261
+msgid "collections_edit_addons_listitem_remove"
+msgstr "Ta bort"
+
+#: views/collections/edit.thtml:250
+msgid "collections_edit_addons_submit"
+msgstr "Lägg till i samling"
+
+#: views/collections/edit.thtml:153
+msgid "collections_edit_check_nickname"
+msgstr "Kontrollera tillgänglighet"
+
+#: views/collections/edit.thtml:299
+msgid "collections_edit_confirm_deletecollection"
+msgstr "Ja, jag vill ta bort den här samlingen."
+
+#. %1$s is the label of the edit form's submit button
+#: views/collections/edit.thtml:300
+msgid "collections_edit_confirm_deletecollection_description"
+msgstr "Kryssa i rutan, klicka sedan på \"%1$s\" för att ta bort samlingen."
+
+#. %1$s is the "delete" submit button text
+#. %2$s is the title of the "advanced" tab
+#: views/collections/edit.thtml:95
+msgid "collections_edit_delete_upon_submit"
+msgstr ""
+"När du klickar \"%1$s\" nedanför kommer din samling aatt tas bort. Om du "
+"inte vill radera din samling, välj bort bekräftelsen i \"%2$s\"-fliken och "
+"fortsätt redigera din samling. Om du lämnar den här sidan utan att spara "
+"kommer din samling inte att tas bort."
+
+#: views/collections/edit.thtml:94
+msgid "collections_edit_delete_warning"
+msgstr "Din samling tas bort!"
+
+#: views/collections/add.thtml:76 views/collections/edit.thtml:144
+msgid "collections_edit_form_error_description"
+msgstr "Du måste ge en beskrivning av din samling."
+
+#: views/collections/edit.thtml:181
+msgid "collections_edit_form_error_icon"
+msgstr "Det uppstod ett fel när du laddade upp ikonen."
+
+#: views/collections/add.thtml:69 views/collections/edit.thtml:130
+msgid "collections_edit_form_error_name"
+msgstr "Du måste ge din samling ett namn."
+
+#: views/collections/edit.thtml:158
+msgid "collections_edit_form_error_nickname"
+msgstr "Om du väljer ett smeknamn måste det vara unikt."
+
+#: views/collections/add.thtml:93 views/collections/edit.thtml:249
+msgid "collections_edit_formfield_addons"
+msgstr "Tillägsnamn:"
+
+#: views/collections/edit.thtml:281
+msgid "collections_edit_formfield_application"
+msgstr "Tillhörande applikation"
+
+#: views/collections/edit.thtml:282
+msgid "collections_edit_formfield_application_description"
+msgstr "Välj den applikation din samling är tänkt för."
+
+#: views/collections/edit.thtml:288
+#, fuzzy
+msgid "collections_edit_formfield_collectiontype"
+msgstr "Collection Type"
+
+#: views/collections/edit.thtml:295
+msgid "collections_edit_formfield_deletecollection"
+msgstr "Ta bort samling"
+
+#: views/collections/edit.thtml:296
+msgid "collections_edit_formfield_deletecollection_description"
+msgstr "Tar du bort din samling raderas den permanent."
+
+#: views/collections/add.thtml:73 views/collections/edit.thtml:140
+msgid "collections_edit_formfield_description"
+msgstr "Samlingsbeskrivning"
+
+#: views/collections/add.thtml:74 views/collections/edit.thtml:141
+msgid "collections_edit_formfield_description_description"
+msgstr "Beskriver kortfattat din samling och tilläggen i den"
+
+#: views/collections/edit.thtml:162
+msgid "collections_edit_formfield_icon"
+msgstr "Ikon"
+
+#: views/collections/edit.thtml:163
+msgid "collections_edit_formfield_icon_description"
+msgstr ""
+"Du kan ladda upp en JPG, GIF eller PNG-ikon som skalas om till 32x32 punkter."
+
+#: views/collections/add.thtml:80 views/collections/edit.thtml:189
+msgid "collections_edit_formfield_listed"
+msgstr "Vem kan se din samling?"
+
+#: views/collections/add.thtml:81 views/collections/edit.thtml:190
+msgid "collections_edit_formfield_listed_description"
+msgstr ""
+"Som standard syns samlingar i den publika Samlingskatalogen och kan hittas "
+"av vem som helst. Om du vill begränsa åtkomst till din samling så den bara "
+"kan ses av de du gett en särskild länk till, använd valet nedan."
+
+#: views/collections/add.thtml:84 views/collections/edit.thtml:193
+msgid "collections_edit_formfield_listed_false"
+msgstr "Bara de jag bjuder in att se min samling"
+
+#: views/collections/add.thtml:83 views/collections/edit.thtml:192
+msgid "collections_edit_formfield_listed_true"
+msgstr "Alla kan se min samling i katalogen"
+
+#: views/collections/edit.thtml:223
+msgid "collections_edit_formfield_managers"
+msgstr "Vem kan hantera min samling?"
+
+#: views/collections/edit.thtml:224
+msgid "collections_edit_formfield_managers_description"
+msgstr ""
+"Dessa användare kan publicera tillägg till din samling, hantera alla tillägg "
+"och inställningar och ge andra användare rättigheter."
+
+#: views/collections/add.thtml:66 views/collections/edit.thtml:126
+msgid "collections_edit_formfield_name"
+msgstr "Samlingsnamn"
+
+#: views/collections/add.thtml:67 views/collections/edit.thtml:127
+msgid "collections_edit_formfield_name_description"
+msgstr ""
+"Ge din samling ett beskrivande namn, som \"Dave's Favorite Travel Add-ons\""
+
+#: views/collections/edit.thtml:148
+msgid "collections_edit_formfield_nickname"
+msgstr "Smeknamn för samling"
+
+#: views/collections/edit.thtml:149
+msgid "collections_edit_formfield_nickname_description"
+msgstr "Frivilligt, ge din samling ett unikt smeknamn för snabb åtkomst:"
+
+#: views/collections/edit.thtml:201
+msgid "collections_edit_formfield_publishers"
+msgstr "Vem kan publicera tillägg i din samling?"
+
+#: views/collections/edit.thtml:202
+msgid "collections_edit_formfield_publishers_description"
+msgstr ""
+"Dessa användare kan publicera tillägg till din samling och ta bort tillägg "
+"de publicerat."
+
+#: views/collections/edit.thtml:210 views/collections/edit.thtml:232
+msgid "collections_edit_formfield_users_add"
+msgstr "Ang e-postadressen till ett Firefox Add-ons-konto:"
+
+#: views/collections/edit.thtml:216 views/collections/edit.thtml:238
+msgid "collections_edit_formfield_users_delete_noscript"
+msgstr "Valda konto tas bort när du sparar"
+
+#: views/collections/edit.thtml:215 views/collections/edit.thtml:237
+msgid "collections_edit_formfield_users_new_noscript"
+msgstr ""
+"Skriv en kommaseparerad lista med e-postadresser till Firefox Add-ons-konton"
+
+#: views/collections/edit.thtml:204 views/collections/edit.thtml:226
+msgid "collections_edit_formfield_users_onlyme"
+msgstr "Bara jag"
+
+#: views/collections/edit.thtml:205 views/collections/edit.thtml:227
+msgid "collections_edit_formfield_users_otherusers"
+msgstr "Jag och dessa användare:"
+
+#: views/collections/edit.thtml:211 views/collections/edit.thtml:233
+msgid "collections_edit_formfield_users_submit"
+msgstr "Lägg till"
+
+#. %1$s is the name of the collection
+#: views/collections/edit.thtml:68
+msgid "collections_edit_header"
+msgstr "Hantera %1$s"
+
+#: views/collections/edit.thtml:246
+msgid "collections_edit_header_addons"
+msgstr "Hantera samlingsinnehåll"
+
+#: views/collections/edit.thtml:253 views/collections/edit.thtml:258
+msgid "collections_edit_header_addons_current"
+msgstr "Nuvarande tillägg:"
+
+#: views/collections/edit.thtml:279
+msgid "collections_edit_header_advanced"
+msgstr "Avancerade inställningaar"
+
+#: views/collections/edit.thtml:186
+msgid "collections_edit_header_permissions"
+msgstr "Hantera samlingsrättigheter"
+
+#: views/collections/edit.thtml:170
+msgid "collections_edit_icon_cancel"
+msgstr "Avbryt"
+
+#: views/collections/edit.thtml:174 views/collections/edit.thtml:179
+msgid "collections_edit_icon_delete"
+msgstr "Ta bort ikon"
+
+#: views/collections/edit.thtml:178
+msgid "collections_edit_icon_replace"
+msgstr "Byt ut ikon"
+
+#. %1$s is the label of the edit form's submit button
+#: views/collections/edit.thtml:169
+msgid "collections_edit_icon_toberemoved"
+msgstr "Ikonen tas bort när du klickard \"%1$s\" nedanför"
+
+#: views/collections/edit.thtml:155
+msgid "collections_edit_nickname_available"
+msgstr "Smeknamnet är tillgängligt"
+
+#: controllers/collections_controller.php:943
+msgid "collections_edit_nickname_error"
+msgstr "Ditt smeknamn innehöll ogiltiga tecken och justerades. Försök igen."
+
+#: views/collections/edit.thtml:156
+msgid "collections_edit_nickname_taken"
+msgstr "Smeknamnet är upptaget"
+
+#. This string is followed by a URL pointing to the collection's view page
+#: views/collections/edit.thtml:75
+msgid "collections_edit_saved_nextstep"
+msgstr "Du kan komma åt din samling på den här adressen:"
+
+#: views/collections/edit.thtml:74
+msgid "collections_edit_saved_success"
+msgstr "Din samling är skapad!"
+
+#: views/collections/edit.thtml:169 views/collections/edit.thtml:300
+#: views/collections/edit.thtml:308 views/pages/js_constants.js.thtml:99
+msgid "collections_edit_submit"
+msgstr "Uppdatera samling"
+
+#: views/collections/edit.thtml:96 views/collections/edit.thtml:297
+#: views/pages/js_constants.js.thtml:100
+msgid "collections_edit_submit_deletecollection"
+msgstr "Ta bort samling"
+
+#: views/collections/edit.thtml:111
+msgid "collections_edit_tabheader_addons"
+msgstr "Tillägg"
+
+#: views/collections/edit.thtml:97 views/collections/edit.thtml:113
+msgid "collections_edit_tabheader_advanced"
+msgstr "Avancerat"
+
+#: views/collections/edit.thtml:108
+msgid "collections_edit_tabheader_details"
+msgstr "Namn &amp; Detaljer"
+
+#: views/collections/edit.thtml:109
+msgid "collections_edit_tabheader_permissions"
+msgstr "Rättigheter"
+
+#: models/collection_promo.php:53
+msgid "collections_family_tagline"
+msgstr "Tillägg kan hålla ett öga på dina barn och din kalender."
+
+#: models/collection_promo.php:53
+msgid "collections_family_title"
+msgstr "Familjeplanering"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:70
+msgid "collections_index_a_check_out"
+msgstr "Spana in tilläggssamlaren"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:52
+msgid "collections_index_a_create"
+msgstr "Skapa en samling"
+
+#: views/collections/detail.thtml:139 views/collections/listing.thtml:85
+#: views/search/collections.thtml:84
+msgid "collections_index_button_go"
+msgstr "Sätt igång"
+
+#. %1$s is a URL.
+#: controllers/collections_controller.php:182
+#, fuzzy
+msgid "collections_index_filler_favorites"
+msgstr ""
+"<p><strong>You don't have any favorite collections yet.</strong></p> "
+"<p>Collections you mark as favorites can be quickly accessed from this page, "
+"and will appear in the <a href='%1$s'>Add-on Collector</a> if you've "
+"installed it.</p>"
+
+#. %1$s is a URL.
+#: controllers/collections_controller.php:167
+#, fuzzy
+msgid "collections_index_filler_mine"
+msgstr ""
+"<p>You haven't created any collections yet. Collections are easy to create "
+"and fill with your favorite add-ons. <a href='%1$s'>Try it out</a>!</p>"
+
+#: views/collections/listing.thtml:51
+msgid "collections_index_header_collections"
+msgstr "Samlingar"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:60
+msgid "collections_index_header_collector"
+msgstr "Tilläggssamling"
+
+#. %1$s is a comma-separated list of author names
+#: views/elements/amo2009/collection_listing_item.thtml:84
+#: views/collections/detail.thtml:151
+msgid "collections_index_header_created"
+msgstr "skapad av %1$s"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:47
+msgid "collections_index_header_what"
+msgstr "Vad är samlingar?"
+
+#: views/collections/detail.thtml:132 views/collections/listing.thtml:78
+#: views/search/collections.thtml:66
+msgid "collections_index_label_sortby"
+msgstr "Sortera på"
+
+#: controllers/collections_controller.php:130
+msgid "collections_index_li_editors"
+msgstr "Redaktörernas utvalda"
+
+#: views/collections/subscribe.thtml:64
+#: controllers/collections_controller.php:140
+msgid "collections_index_li_favorites"
+msgstr "Mina favoriter"
+
+#: controllers/collections_controller.php:138
+msgid "collections_index_li_mine"
+msgstr "Mina samlingar"
+
+#: controllers/collections_controller.php:132
+msgid "collections_index_li_popular"
+msgstr "Populära"
+
+#: views/search/collections.thtml:74 controllers/collections_controller.php:81
+msgid "collections_index_option_all"
+msgstr "Mest populära totalt"
+
+#: views/search/collections.thtml:72 controllers/collections_controller.php:78
+msgid "collections_index_option_month"
+msgstr "Mest populära denna månad"
+
+#: views/search/collections.thtml:76 controllers/collections_controller.php:84
+#, fuzzy
+msgid "collections_index_option_newest"
+msgstr "Newest"
+
+#: views/search/collections.thtml:70 controllers/collections_controller.php:75
+msgid "collections_index_option_week"
+msgstr "Mest populära dennaa vecka"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:67
+msgid "collections_index_p_collector"
+msgstr ""
+"Det finns ett nytt sätt att hantera och hitta favorittillägg. Kommentera, "
+"dela och synkaa samlingar, allt detta från din webbläsare"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:48
+msgid "collections_index_p_what_are"
+msgstr ""
+"Samlingar är grupper av tillägg som samlats ihop för att dela med sig av dem "
+"enkelt."
+
+#. %s is a date in the _('date') format
+#: views/elements/collections_interactive_addon.thtml:85
+#, php-format
+msgid "collections_interactive_addon_added"
+msgstr "Lade till %s"
+
+#: models/collection_promo.php:55
+msgid "collections_reference_tagline"
+msgstr "Tillägg kan göra bättre nätsökningar."
+
+#: models/collection_promo.php:55
+msgid "collections_reference_title"
+msgstr "Referensdisken"
+
+#: models/collection_promo.php:52
+msgid "collections_social_tagline"
+msgstr "Tillägg som hjälper dig hantera sociala nätverk."
+
+#: models/collection_promo.php:52
+msgid "collections_social_title"
+msgstr "Sällskapslivet"
+
+#: views/collections/subscribe.thtml:91
+#, fuzzy
+msgid "collections_subscribe_button_close"
+msgstr "Close"
+
+#: views/collections/subscribe.thtml:70
+#, fuzzy
+msgid "collections_subscribe_error"
+msgstr ""
+"An error occurred trying to add a favorite collection. Is this collection "
+"already a favorite?"
+
+#: views/collections/subscribe.thtml:96
+#, fuzzy
+msgid "collections_subscribe_label_bothersome"
+msgstr "Don't show me this message again."
+
+#. %1$s is the collection name
+#: views/collections/subscribe.thtml:60
+#, fuzzy
+msgid "collections_subscribe_success"
+msgstr "%1$s has been added to your favorite collections."
+
+#. %1$s is the link to the "My Favorites" tab on the main collections page
+#. %2$s is the localized title of the "My Favorites" tab
+#. %3$s is the link URL to the collector add-on
+#: views/collections/subscribe.thtml:62
+#, fuzzy
+msgid "collections_subscribe_success_desc"
+msgstr ""
+"You can now quickly find this collection from the <a href=\"%1$s\">%2$s</a> "
+"tab in the directory. For an even easier way to keep track of your favorite "
+"collections, try out our <a href=\"%3$s\">Add-on Collector</a> extension for "
+"Firefox."
+
+#: views/collections/listing.thtml:55
+msgid "collections_success_delete"
+msgstr "Samlingen har tagits bort."
+
+#: models/collection_promo.php:54
+msgid "collections_travel_tagline"
+msgstr "Tilläggen som kan förvandla dig till en reseagent."
+
+#: models/collection_promo.php:54
+msgid "collections_travel_title"
+msgstr "Resepaketet"
+
+#. A collection of add-ons that is automatically built for a user. They are "automatically published" to this collection.
+#: controllers/collections_controller.php:581
+#, fuzzy
+msgid "collections_type_autopublisher"
+msgstr "Auto-publisher"
+
+#. A collection that has been chosen by an Editor as notable or exceptional
+#: controllers/collections_controller.php:582
+#, fuzzy
+msgid "collections_type_editorspick"
+msgstr "Editor's Pick"
+
+#: controllers/collections_controller.php:580
+#, fuzzy
+msgid "collections_type_normal"
+msgstr "Normal"
+
+#: views/collections/subscribe.thtml:84
+#, fuzzy
+msgid "collections_unsubscribe_error"
+msgstr ""
+"An error occurred trying to remove a favorite collection. Was this "
+"collection not a favorite?"
+
+#. %1$s is the collection name
+#: views/collections/subscribe.thtml:78
+#, fuzzy
+msgid "collections_unsubscribe_success"
+msgstr "%1$s has been removed from your favorite collections."
+
+#: models/collection_promo.php:56
+msgid "collections_webdev_tagline"
+msgstr "Tillägg gör det enklare att bygga den perfekta webbsidan."
+
+#: models/collection_promo.php:56
+msgid "collections_webdev_title"
+msgstr "Webbutvecklarens verktygslåda"
+
+#: views/elements/amo2009/collections_sidebar_whatare.thtml:40
+msgid "collections_whatare_header"
+msgstr "Vad är samlingar?"
+
+#: views/elements/amo2009/collections_sidebar_whatare.thtml:45
+msgid "collections_whatare_learnmore"
+msgstr "Läs FAQn"
+
+#: views/elements/amo2009/collections_sidebar_whatare.thtml:44
+msgid "collections_whatare_text"
+msgstr ""
+"Det finns ett nytt sätt att hitta och hantera favorittillägg. Kommentera, "
+"dela och synka, allt från din webbläsare."
+
+#: views/pages/collector_faq.thtml:61 views/pages/collector_features.thtml:67
+msgid "collector_features_a_home"
+msgstr "Tilläggssamlingars Hem"
+
+#: views/elements/amo2009/collector_sidebar_download.thtml:46
+msgid "collector_features_heading_download"
+msgstr "Ladda ner tilläggssamlaren:"
+
+#: views/elements/amo2009/collector_sidebar_download.thtml:43
+#: views/pages/collector_firstrun.thtml:116 views/pages/collector.thtml:69
+msgid "collector_features_img_logo"
+msgstr "Tilläggssamlarens logo"
+
+#: views/compatibility/dashboard.thtml:49
+#: controllers/compatibility_controller.php:72
+msgid "compatibility_dashboard_center_header"
+msgstr "Tillägskompatibilitetscenter"
+
+#. %1$s is the name of an application and a version. Example: Firefox 3.0
+#. %2$s is the name of an application. Example: Firefox
+#: views/compatibility/dashboard.thtml:50
+msgid "compatibility_dashboard_intro"
+msgstr ""
+"Var beredd på släppet av %1$s med de verktyg och den information som finns "
+"tillgänglig för %2$s tilläggsmakare nedan."
+
+#: views/compatibility/dashboard.thtml:103
+msgid "compatibility_dashboard_loading"
+msgstr "Laddar data..."
+
+#: views/compatibility/dashboard.thtml:45
+msgid "compatibility_dashboard_main_link"
+msgstr "Tillbaka till huvudsidan"
+
+#: views/compatibility/dashboard.thtml:100 views/compatibility/report.thtml:43
+msgid "compatibility_dashboard_report"
+msgstr "Tilläggskompatibilitetsrapport"
+
+#: views/compatibility/dashboard.thtml:53
+#: views/compatibility/dashboard.thtml:110
+#: views/compatibility/developers.thtml:43
+msgid "compatibility_developer_info"
+msgstr "Information för tilläggsutvecklare"
+
+#: views/compatibility/developers.thtml:66
+msgid "compatibility_developers_adjust_maxversion"
+msgstr "Justera maxVersion utan att ladda upp på nytt"
+
+#: views/compatibility/dashboard.thtml:124
+msgid "compatibility_developers_check_status"
+msgstr "Kontrollera status på Mina tillägg"
+
+#. %1$s is a URL
+#. %2$s is an application and version. Example: Firefox 3.0
+#: views/compatibility/dashboard.thtml:126
+msgid "compatibility_developers_login_first"
+msgstr ""
+"Om du har ett tillägg hos Mozilla Add-ons, <a href=\"%1$s\">logga in</a> för "
+"att analusera statusen på %2$s."
+
+#: views/compatibility/dashboard.thtml:114
+msgid "compatibility_developers_mdclogo_alt"
+msgstr "Mozilla Developer Center Logo"
+
+#: views/compatibility/developers.thtml:73
+msgid "compatibility_developers_no_addons"
+msgstr "Du har inga tillägg publicerade hos Mozilla Add-ons."
+
+#: views/compatibility/dashboard.thtml:133
+#: views/compatibility/developers.thtml:55
+msgid "compatibility_developers_results"
+msgstr "Tilläggsstatuskontrolresultat"
+
+#: views/compatibility/dashboard.thtml:137
+msgid "compatibility_developers_retrieving"
+msgstr "Hämtar status på publicerade tillägg..."
+
+#. %1$s is a number
+#. %2$s is an application name
+#. %3$s is a number.
+#. Full example: 50 Firefox users (10% of total)
+#: views/compatibility/developers.thtml:65
+msgid "compatibility_developers_user_count"
+msgstr "%1$s %2$s användare (%3$s&#37; av totala antalet)"
+
+#: views/compatibility/report.thtml:45
+msgid "compatibility_report_detail_intro"
+msgstr ""
+"Tilläggen nedan utgör 95% av tillägsanvändandet Mozilla känner till och är "
+"sorterade på deras användande."
+
+#: views/compatibility/dashboard.thtml:94
+msgid "compatibility_report_detailed_link"
+msgstr "Visa detaljerade rapport"
+
+#. %1$s and %2$s are numbers
+#. %3$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:65
+msgid "compatibility_report_intro"
+msgstr ""
+"Av de %1$s tillägg som utgör 95&#37; av användningen Mozilla känner till "
+"bedöms <b>%2$s&#37;</b> vara kompatibel med de senaste byggena av %3$s."
+
+#: views/compatibility/dashboard.thtml:81
+msgid "compatibility_report_legend_alpha"
+msgstr "Alpha-versioner"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:81
+msgid "compatibility_report_legend_alpha_description"
+msgstr "Tillägg kompatibla med en alphaversion av %1$s"
+
+#: views/compatibility/dashboard.thtml:85
+msgid "compatibility_report_legend_beta"
+msgstr "Beta-versioner"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:85
+msgid "compatibility_report_legend_beta_description"
+msgstr "Tillägg kompatibla med en betaversion eller släppkandidat av %1$s"
+
+#: views/compatibility/dashboard.thtml:89
+msgid "compatibility_report_legend_latest"
+msgstr "Senaste versionen"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:89
+msgid "compatibility_report_legend_latest_description"
+msgstr "Tillägg uppdaterade för de senaste byggena av %1$s"
+
+#: views/compatibility/dashboard.thtml:77
+msgid "compatibility_report_legend_other"
+msgstr "Andra versioner"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:77
+msgid "compatibility_report_legend_other_description"
+msgstr "Tillägg ej kompatibla med någon version av %1$s"
+
+#: views/compatibility/dashboard.thtml:62
+msgid "compatibility_report_title"
+msgstr "Tilläggskompatibilitetsrapport"
+
+#: views/compatibility/dashboard.thtml:54
+#: views/compatibility/dashboard.thtml:144 views/compatibility/users.thtml:42
+msgid "compatibility_user_info"
+msgstr "Information för tilläggsanvändare"
+
+#: views/compatibility/dashboard.thtml:52
+msgid "compatibility_view_report"
+msgstr "Visa kompatibilitetsrapport"
+
+#. %s is a URL
+#: views/pages/credits.thtml:142
+#, php-format
+msgid "credits_contributing"
+msgstr "För mer information om hur du kan bidra, se vår %s."
+
+#: views/pages/credits.thtml:142
+msgid "credits_contributing_wikipage"
+msgstr "wikisida"
+
+#: views/pages/credits.thtml:99
+msgid "credits_intro"
+msgstr ""
+"Mozilla vill tacka följande personer för deras bidrag till addons.mozilla."
+"org-projektet genom åren:"
+
+#: views/pages/credits.thtml:103
+msgid "credits_section_developers"
+msgstr "Utvecklare"
+
+#: views/pages/credits.thtml:115
+msgid "credits_section_editors"
+msgstr "Redaktörer"
+
+#: views/pages/credits.thtml:109
+msgid "credits_section_localizers"
+msgstr "Lokaliserare"
+
+#: views/pages/credits.thtml:121
+msgid "credits_section_other_contributors"
+msgstr "Andra som bidragit"
+
+#: views/pages/credits.thtml:127
+msgid "credits_section_past_developers"
+msgstr "Tidigare utvecklare"
+
+#: views/pages/credits.thtml:133
+msgid "credits_section_software"
+msgstr "Programvara och bilder"
+
+#: views/pages/credits.thtml:136
+msgid "credits_software_famfamfam"
+msgstr ""
+"Vissa ikoner kommer från<a href=\"http://www.famfamfam.com/lab/icons/silk/"
+"\">ikonuppsättningen famfamfam Silk</a>, licensierad under en <a href="
+"\"http://creativecommons.org/licenses/by/2.5/\">Creative Commons Attribution "
+"2.5 License</a>."
+
+#: views/pages/credits.thtml:137
+msgid "credits_software_timeplot"
+msgstr ""
+"Vissa sidor använder element från <a href=\"http://www.simile-widgets.org/"
+"timeplot/\">Timeplot</a>, licensierade enligt en <a href=\"http://simile.mit."
+"edu/license.html\">BSD-licens</a>."
+
+#. date format string as used in PHP's strftime():
+#. http://php.net/strftime
+#: views/elements/collections_interactive_addon.thtml:85
+#: views/elements/amo2009/addon_version_detail.thtml:53
+#: views/elements/amo2009/homepage_addon.thtml:115
+#: views/elements/addon_version_detail.thtml:54
+#: views/elements/addon_listitem.thtml:124 views/elements/feature.thtml:106
+#: views/collections/detail.thtml:118 views/collections/edit.thtml:325
+#: views/users/info.thtml:76 views/editors/reviews_queue.thtml:57
+#: views/editors/reviews_queue.thtml:68 views/developers/dashboard.thtml:65
+#: views/developers/versions_edit.thtml:208 views/developers/versions.thtml:67
+#: views/search/rss/index.thtml:5 views/addons/rss/versions.thtml:42
+#: views/addons/display.thtml:104 views/addons/display.thtml:356
+#: views/addons/browse_thumbs.thtml:75 views/reviews/add.thtml:63
+#: views/reviews/display.thtml:74 views/reviews/display.thtml:160
+#: views/reviews/delete.thtml:54 controllers/statistics_controller.php:244
+#: controllers/collections_controller.php:1047
+msgid "date"
+msgstr "%e %B, %Y"
+
+#. date and time format string (strftime)
+#. http://php.net/strftime
+#: views/elements/addon_version_detail.thtml:53
+#: views/developers/discuss.thtml:52 views/developers/discuss.thtml:62
+#: views/admin/addons_status.thtml:57
+msgid "datetime"
+msgstr "%e %B, %Y, %H:%M"
+
+#: views/elements/developers/actionbar.thtml:47
+msgid "devcp_actionbar_link_details"
+msgstr "Detaljerad information"
+
+#: views/elements/developers/actionbar.thtml:42
+#: views/elements/developers/actionbar.thtml:50
+#: views/developers/dashboard.thtml:64
+msgid "devcp_actionbar_link_edit"
+msgstr "Redigera tillägg"
+
+#: views/elements/developers/actionbar.thtml:51
+msgid "devcp_actionbar_link_newversion"
+msgstr "Ladda upp ny version"
+
+#: views/elements/developers/actionbar.thtml:44
+#: views/elements/developers/actionbar.thtml:49
+#: views/developers/dashboard.thtml:73
+msgid "devcp_actionbar_link_stats"
+msgstr "Statistikpanel"
+
+#. %1$s is a filename, e.g. "foo.txt"
+#. %2$s is the extension, e.g. ".txt"
+#. %3$s is a list of valid extensions, like ".png, .jpg, .gif"
+#: controllers/developers_controller.php:1361
+msgid "devcp_add_previews_extension_error"
+msgstr "Filen %1$s har ogiltig filändelse (%2$s). Tillåtna filändelser: %3$s"
+
+#. %s is the filename.
+#: controllers/developers_controller.php:1394
+msgid "devcp_add_previews_save_error"
+msgstr "Filen %s kunde inte sparas i databasen. Försök igen."
+
+#. %1$s is the preview ID number, %2$s is the filename.
+#: controllers/developers_controller.php:1389
+msgid "devcp_add_previews_success_replace"
+msgstr "Förhandsvisningen %1$s ersattes med %2$s."
+
+#. %s is the filename.
+#: controllers/developers_controller.php:1391
+msgid "devcp_add_previews_success_upload"
+msgstr "Filen %s laddades upp. Du kan ange en bildtext nedan."
+
+#: controllers/components/developers.php:1163
+msgid "devcp_additem_addontype_autodetect"
+msgstr "(autodetektera)"
+
+#: views/elements/developers/additem.thtml:76
+msgid "devcp_additem_linktitle_opensin_newwindow"
+msgstr "Öppna i ett nytt fönster"
+
+#: views/elements/developers/additem.thtml:41
+msgid "devcp_additem_sidebar_title"
+msgstr "Skicka in tillägg"
+
+#: views/elements/developers/additem.thtml:53
+msgid "devcp_additem_step0_newlink"
+msgstr "Utvecklaravtal"
+
+#: views/elements/developers/additem.thtml:46
+msgid "devcp_additem_step1_link"
+msgstr "Steg 1: Ladda upp"
+
+#: views/elements/developers/additem.thtml:47
+msgid "devcp_additem_step2_link"
+msgstr "Steg 2: Detaljer om tillägget"
+
+#: views/elements/developers/additem.thtml:48
+msgid "devcp_additem_step3_link"
+msgstr "Steg 3: Versionsdetaljer"
+
+#: views/elements/developers/additem.thtml:49
+msgid "devcp_additem_step4_link"
+msgstr "Steg 4: Lokalisering"
+
+#: views/elements/developers/additem.thtml:50
+msgid "devcp_additem_step5_link"
+msgstr "Steg 5: Klart"
+
+#: views/elements/developers/additem.thtml:76
+msgid "devcp_additem_submissionhelp_link"
+msgstr "Hjälp med inskickningsprocessen"
+
+#: controllers/previews_controller.php:168
+#: controllers/previews_controller.php:277
+msgid "devcp_addon_field_preview_caption_displaytitle"
+msgstr "Förhandsgranska bildtext"
+
+#: views/developers/addon_status.thtml:177
+msgid "devcp_addon_status_action_activate"
+msgstr "Gör aktiv"
+
+#: views/developers/addon_status.thtml:178
+msgid "devcp_addon_status_action_activate_description"
+msgstr ""
+"Gör ditt tillägg aktivt för att det ska dyka upp i publika listningar och "
+"erbjudas via uppdateringsskontrollen."
+
+#: views/developers/addon_status.thtml:135
+msgid "devcp_addon_status_action_complete"
+msgstr "Färdigställ tillägg"
+
+#: views/developers/addon_status.thtml:136
+msgid "devcp_addon_status_action_complete_description"
+msgstr "Färdigställ ditt tillägg och flytta till sandlådan"
+
+#: views/developers/addon_status.thtml:181
+msgid "devcp_addon_status_action_deactivate"
+msgstr "Gör inaktivt"
+
+#: views/developers/addon_status.thtml:182
+msgid "devcp_addon_status_action_deactivate_description"
+msgstr ""
+"Gör du ditt tillägg inaktivt tas det bort från publika listningar och "
+"uppdateringskontrolltjänsten."
+
+#: views/developers/addon_status.thtml:143
+msgid "devcp_addon_status_action_move"
+msgstr "Flytta till sandlådan"
+
+#: views/developers/addon_status.thtml:144
+msgid "devcp_addon_status_action_move_description"
+msgstr "Flytta ditt tillägg tillbaka till sandlådan. Detta går att ångra."
+
+#: views/developers/addon_status.thtml:139
+msgid "devcp_addon_status_action_nominate"
+msgstr "Nominera för att bli publikt"
+
+#: views/developers/addon_status.thtml:140
+msgid "devcp_addon_status_action_nominate_description"
+msgstr "Nominera ditt tillägg att bli publikt"
+
+#: views/developers/addon_status.thtml:147
+msgid "devcp_addon_status_action_public"
+msgstr "Gör publikt"
+
+#: views/developers/addon_status.thtml:148
+msgid "devcp_addon_status_action_public_description"
+msgstr "Gör ditt tillägg publikt igen."
+
+#: views/developers/addon_status.thtml:169
+msgid "devcp_addon_status_active"
+msgstr ""
+"Ditt tillägg är <span class=\"inactive-0\">Aktivt</span>. Det betyder att "
+"ditt tilägg dyker upp i all tillgängliga listor tillämpliga för dess status "
+"ovan."
+
+#: views/developers/addon_status.thtml:111
+msgid "devcp_addon_status_completion_disabled"
+msgstr ""
+"Du måste uppfylla kriterien ovan innan du kan färdigställa ditt tillägg och "
+"flytta det till <span class=\"status-1\">sandlådan</span>."
+
+#: views/developers/addon_status.thtml:108
+msgid "devcp_addon_status_completion_enabled"
+msgstr ""
+"Du kan nu färdigställa ditt tillägg och flytta det till <span class=\"status-"
+"1\">sandlådan</span> genom att klicka på knappen nedan."
+
+#: views/developers/addon_status.thtml:102
+msgid "devcp_addon_status_criteria_category"
+msgstr "Minst en kategori vald"
+
+#: views/developers/addon_status.thtml:101
+msgid "devcp_addon_status_criteria_description"
+msgstr "Tilläggsbeskrivning krävs"
+
+#: views/developers/addon_status.thtml:99
+msgid "devcp_addon_status_criteria_name"
+msgstr "Tilläggsnamn krävs"
+
+#: views/developers/addon_status.thtml:120
+msgid "devcp_addon_status_criteria_prerelease"
+msgstr "Tillägget är ej markerat som en förhandsversion."
+
+#: views/developers/addon_status.thtml:119
+msgid "devcp_addon_status_criteria_preview"
+msgstr "Minst en förhandsvisningsbild krävs för utökningar och teman."
+
+#: views/developers/addon_status.thtml:100
+msgid "devcp_addon_status_criteria_summary"
+msgstr "Tilläggssammanfattning krävs"
+
+#. %s is the status in a span, e.g. "<span>_('Public')</span>".
+#: views/developers/addon_status.thtml:58
+msgid "devcp_addon_status_header"
+msgstr "Tilläggstatus: %s"
+
+#: views/developers/addon_status.thtml:152
+#: views/developers/addon_status.thtml:173
+msgid "devcp_addon_status_header_actions"
+msgstr "Möjliga handlingar"
+
+#: views/developers/addon_status.thtml:168
+msgid "devcp_addon_status_header_active"
+msgstr "Aktiv status: <span class=\"inactive-0\">Aktiv</span>"
+
+#: views/developers/addon_status.thtml:97
+msgid "devcp_addon_status_header_criteria"
+msgstr "Tilläggsfärdigställningkriterie"
+
+#: views/developers/addon_status.thtml:164
+msgid "devcp_addon_status_header_inactive"
+msgstr "Aktiv status: <span class=\"inactive-1\">Inaktiv</span>"
+
+#: views/developers/addon_status.thtml:117
+msgid "devcp_addon_status_header_nomination"
+msgstr "Publiknomineringskriteria"
+
+#: views/developers/addon_status.thtml:190
+msgid "devcp_addon_status_header_trusted"
+msgstr "Betrott status: <span class=\"status-4\">Betrott</span>"
+
+#: views/developers/addon_status.thtml:165
+msgid "devcp_addon_status_inactive"
+msgstr ""
+"Ditt tillägg är <span class=\"inactive-1\">Inactive</span>. Det betyder att "
+"ditt tillägg inte dyker upp i några listor, oavsett dess status ovan. "
+"Uppdateringar av ditt tillägg erbjuds <b>ej</> via "
+"uppdateringskontrolltjänsten."
+
+#: views/developers/addon_status.thtml:128
+msgid "devcp_addon_status_nominate_disabled"
+msgstr ""
+"Du måste uppfylla kriterien ovan innan du kan nominera ditt tillägg att bli "
+"<span class=\"status-4\">publikt</span>."
+
+#: views/developers/addon_status.thtml:125
+msgid "devcp_addon_status_nominate_enabled"
+msgstr ""
+"Du kan nu nominera ditt tillägg att bli <span class=\"status-4\">publikt</"
+"span> genom att klicka på knappen nedan."
+
+#: views/developers/addon_status.thtml:64
+msgid "devcp_addon_status_public"
+msgstr "Publikt"
+
+#: views/developers/addon_status.thtml:63
+msgid "devcp_addon_status_sandbox"
+msgstr "Sandlåda"
+
+#. %s is an email address.
+#: views/developers/addon_status.thtml:89
+msgid "devcp_addon_status_switch_disabled"
+msgstr ""
+"Ditt tillägg har blivit <span class=\"status-5\">Avstängt</span> av en "
+"administratör och kan inte användas. Om du har några frågor, kontakta %s."
+
+#: views/developers/addon_status.thtml:67
+msgid "devcp_addon_status_switch_incomplete"
+msgstr ""
+"Ditt tillägg är för närvarande <span class=\"status-0\">Ej komplett</span>. "
+"Det betyder att ditt tillägg inte visas någonstans på webbplatsen eller "
+"erbjuds via uppdateringskontrolltjänsten. Du kan gå till den här sidan och "
+"färdigställa ditt tillägg när det uppfyller färdigkriterien nedan och flytta "
+"det till <span class=\"status-1\">sandlådan</span>."
+
+#. %s is a number, perhaps 42.
+#: views/developers/addon_status.thtml:77
+msgid "devcp_addon_status_switch_nominated"
+msgstr ""
+"Ditt tillägg är för nuvarande nominerat för att bli <span class=\"status-4"
+"\">publikt</span> och väntar på redaktörsgodkännande. Det är för närvarande %"
+"s andra tillägg i nomineringskön."
+
+#. %s is an email address.
+#: views/developers/addon_status.thtml:81
+msgid "devcp_addon_status_switch_pending"
+msgstr ""
+"Ditt tillägg är i vänteläge. Det borde inte vara så, kontakta %s med ditt "
+"tiläggs-id och berätta om detta fel."
+
+#: views/developers/addon_status.thtml:85
+msgid "devcp_addon_status_switch_public"
+msgstr ""
+"Ditt tillägg är <span class=\"status-4\">publikt</span>, vilket betyder att "
+"det dyker upp i alla listningar och sökningar och kan laddas ner utan "
+"restriktioner. Uppdateringar erbjuds genom uppdateringskontrolltjänsten."
+
+#: views/developers/addon_status.thtml:71
+#: views/developers/addon_status.thtml:75
+msgid "devcp_addon_status_switch_sandbox"
+msgstr ""
+"Ditt tillägg är i <span class=\"status-1\">sandlådan</span>, vilket betyder "
+"att det dyker upp i listningar och sökningar, men användare måste logga in "
+"för att ladda ner det. Uppdateringar erbjuds <b>inte</b> för ditt tillägg "
+"genom uppdateringskontrolltjänsten."
+
+#. %s is the add-on name.
+#: views/developers/addon_status_nominate.thtml:43
+#: views/developers/addon_status_confirm.thtml:43
+#: views/developers/addon_status.thtml:43
+msgid "devcp_addon_status_title"
+msgstr "%s status"
+
+#: views/developers/addon_status.thtml:191
+msgid "devcp_addon_status_trusted"
+msgstr ""
+"Ditt tillägg är <span class=\"status-4\">betrott</span>. Det betyder att du "
+"kan publicera uppdateringar av ditt tillägg utan redaktörsgranskning."
+
+#: views/developers/dashboard.thtml:68
+msgid "devcp_dashboard_active"
+msgstr "Aktiv"
+
+#. %1$s is the add-on type string
+#. %2$s is Inactive or Active in a <span>
+#. %3$s is the addon's public status (Public, In Sandbox, ...) in a <span>
+#: views/developers/dashboard.thtml:69
+msgid "devcp_dashboard_addontype_status"
+msgstr "%1$s för närvarande %2$s och %3$s"
+
+#: views/developers/dashboard.thtml:67
+msgid "devcp_dashboard_change_status"
+msgstr "Ändra status"
+
+#. %s is the addons email address.
+#: views/developers/dashboard.thtml:99
+msgid "devcp_dashboard_disabled_questions"
+msgstr ""
+"Ditt tillägg har blivit avstängt av en administratör och kan ej användas. "
+"Har du några frågor, kontakta %s."
+
+#. %s is the (localized) add-on status string in a span, e.g. "Disabled"
+#: views/developers/dashboard.thtml:98
+msgid "devcp_dashboard_disabled_status"
+msgstr "Tilläggsstatus: %s"
+
+#: views/developers/dashboard.thtml:43
+msgid "devcp_dashboard_header_main"
+msgstr "Utvecklarpanelen"
+
+#: views/developers/dashboard.thtml:110
+msgid "devcp_dashboard_header_welcome"
+msgstr "Välkommen till utvecklarpanelen"
+
+#: views/developers/dashboard.thtml:68
+msgid "devcp_dashboard_inactive"
+msgstr "Inaktiv"
+
+#. %s is a date in the _('date') format
+#: views/developers/dashboard.thtml:65
+msgid "devcp_dashboard_last_edited"
+msgstr "Senast redigerad den %s"
+
+#: views/developers/dashboard.thtml:111
+msgid "devcp_dashboard_learn"
+msgstr ""
+"Du har för närvarande inga tillägg publicerade på Mozilla Add-ons. För att "
+"lära dig hur processen fungerar och skicka in ditt första tillägg, klicka på "
+"Sätt igång nedanför."
+
+#: views/developers/dashboard.thtml:112
+msgid "devcp_dashboard_start"
+msgstr "Sätt igång"
+
+#: views/developers/dashboard.thtml:82
+msgid "devcp_dashboard_versions"
+msgstr "Versioner och filer"
+
+#: views/developers/dashboard.thtml:91
+msgid "devcp_dashboard_versions_new"
+msgstr "Ladda upp en ny version"
+
+#. %s is the preview ID number.
+#: controllers/developers_controller.php:1415
+msgid "devcp_delete_previews_error"
+msgstr "Förhandsvisningen %s kunde inte tas bort från databasen. Försök igen."
+
+#. %s is the preview ID number.
+#: controllers/developers_controller.php:1413
+msgid "devcp_delete_previews_success"
+msgstr "Förhandsvisningen %s har tagits bort."
+
+#: controllers/developers_controller.php:1089
+msgid "devcp_delete_version_priv_error"
+msgstr "Du har inte rättigheter att ta bort versioner eller filer."
+
+#. %1$s is the count of files, a number
+#. %2$s is a status string like _('Public') or _('Incomplete')
+#: controllers/components/amo.php:549
+msgid "devcp_describe_version_status"
+msgid_plural "devcp_describe_version_status"
+msgstr[0] "%1$s %2$s fil"
+msgstr[1] "%1$s %2$s filer"
+
+#. %s is a version number. Example: 3.0
+#: views/developers/versions.thtml:65
+#, php-format
+msgid "devcp_details_version"
+msgstr "Version %s"
+
+#: views/developers/discuss.thtml:68
+msgid "devcp_discuss_addreply_header"
+msgstr "Lägg till svar"
+
+#: views/developers/discuss.thtml:57
+msgid "devcp_discuss_allreplies_header"
+msgstr "Svar"
+
+#. notice when an error occurs saving a discussion reply
+#. %1 is the email address (linked) for the amo-editors list
+#: views/developers/discuss.thtml:70
+msgid "devcp_discuss_error_notice"
+msgstr ""
+"Det uppstod ett fel när ditt svar sparades. Kontakta gärna %1$s om problemet."
+
+#. %1 is the add-on name, %2 is the add-on's version number currently being reviewed by an editor
+#: views/developers/discuss.thtml:46
+msgid "devcp_discuss_intro"
+msgstr ""
+"En Mozilla Add-ons redaktör begärde ytterligare information från dig "
+"anågende version %2$s av ditt tillägg %1$s."
+
+#. %1 is the add-on name
+#: views/developers/discuss.thtml:43
+msgid "devcp_discuss_pagetitle"
+msgstr "Ge mer information för tilläggsgranskning av %1$s"
+
+#. submit button text
+#: views/developers/discuss.thtml:79
+msgid "devcp_discuss_submit_reply"
+msgstr "Skicka in svar"
+
+#: views/developers/discuss.thtml:72
+msgid "devcp_discuss_success_message"
+msgstr ""
+"Ditt svar sparades. Andra deltagare i diskussionen underrättas via e-post."
+
+#. in an author/editor discussion about an add-on to be reviewed:
+#. %1 is the commenter's user name (linked).
+#. %2 is the full date the comment was made.
+#: views/developers/discuss.thtml:52 views/developers/discuss.thtml:62
+msgid "devcp_discuss_writtenby"
+msgstr "Skriven av %1$s den %2$s"
+
+#: views/developers/addon_edit_authors.thtml:72
+#: views/developers/addon_edit_authors.thtml:81
+msgid "devcp_edit_authors_add_author"
+msgstr "Lägg till ny författare"
+
+#: views/developers/addon_edit_authors.thtml:96
+msgid "devcp_edit_authors_add_author_button"
+msgstr "Lägg till författare"
+
+#: views/developers/addon_edit_authors.thtml:83
+msgid "devcp_edit_authors_add_email"
+msgstr "Författarkontos e-post:"
+
+#: views/developers/addon_edit_authors.thtml:98
+msgid "devcp_edit_authors_add_loading"
+msgstr "Kontrollerar kontots e-post..."
+
+#: views/developers/addon_edit_authors.thtml:70
+msgid "devcp_edit_authors_click_save"
+msgstr "Klicka på Uppdatera författare nedan för att spara."
+
+#: views/developers/addon_edit_authors.thtml:58
+msgid "devcp_edit_authors_header_current"
+msgstr "Nuvarande författare"
+
+#: views/developers/addon_edit_authors.thtml:50
+msgid "devcp_edit_authors_header_manage"
+msgstr "Hantera tilläggsförfattare"
+
+#: views/developers/addon_edit_authors.thtml:93
+msgid "devcp_edit_authors_label_add_listed"
+msgstr "Lista som författare på de publika sidorna"
+
+#: views/developers/addon_edit_authors.thtml:89
+msgid "devcp_edit_authors_label_developer"
+msgstr ""
+"<strong>Utvecklare</strong> - Kan hantera alla aspekter av tilläggets "
+"visning, utom att lägga till eller ta bort författare."
+
+#: views/developers/addon_edit_authors.thtml:88
+msgid "devcp_edit_authors_label_owner"
+msgstr ""
+"<strong>Ägare</strong> - Kan hantera alla aspekter av tilläggets visning, "
+"inklusive lägga till och ta bort författare."
+
+#: views/developers/addon_edit_authors.thtml:90
+msgid "devcp_edit_authors_label_viewer"
+msgstr ""
+"<strong>Observatör</strong> - Kan se tilläggsutvecklarlistor och statistik, "
+"men kan inte göra några ändringar."
+
+#. Placeholder for the empty option in a <select>.
+#: views/developers/addon_edit_categories.thtml:69
+msgid "devcp_edit_authors_option_empty"
+msgstr "----------------"
+
+#: views/developers/addon_edit_authors.thtml:86
+msgid "devcp_edit_authors_select_role"
+msgstr "Välj en roll för författaren:"
+
+#. Column name in a table.
+#: views/developers/addon_edit_authors.thtml:62
+msgid "devcp_edit_authors_th_author"
+msgstr "Författare"
+
+#. Column name in a table.
+#: views/developers/addon_edit_authors.thtml:64
+msgid "devcp_edit_authors_th_listed"
+msgstr "Listad"
+
+#. Column name in a table.
+#: views/developers/addon_edit_authors.thtml:63
+msgid "devcp_edit_authors_th_role"
+msgstr "Roll"
+
+#: views/developers/addon_edit_authors.thtml:77
+msgid "devcp_edit_authors_update_author"
+msgstr "Uppdatera författare"
+
+#: views/developers/addon_edit_categories.thtml:99
+msgid "devcp_edit_categories_button_update"
+msgstr "Uppdatera kategorier"
+
+#: views/developers/addon_edit_categories.thtml:88
+msgid "devcp_edit_categories_does_not_fit"
+msgstr "Mitt tillägg passar inte i någon av de tillgängliga kategorierna."
+
+#. %s is the application name (Firefox, Thunderbird).
+#: views/developers/addon_edit_categories.thtml:61
+msgid "devcp_edit_categories_header_application"
+msgstr "%s kategorier"
+
+#: views/developers/addon_edit_categories.thtml:49
+msgid "devcp_edit_categories_header_manage"
+msgstr "Hantera tilläggskategorier"
+
+#: views/developers/addon_edit_categories.thtml:91
+msgid "devcp_edit_categories_hover"
+msgstr "Håll musen över en kategori för att se dess beskrivning."
+
+#. %s is the category number (1, 2, 3).
+#: views/developers/addon_edit_categories.thtml:67
+msgid "devcp_edit_categories_label_category_num"
+msgstr "Kategori %s"
+
+#: views/developers/addon_edit_categories.thtml:94
+#: views/developers/addon_edit_categories.thtml:103
+msgid "devcp_edit_categories_none_available"
+msgstr "Inga kategorier är tillgängliga för denna tilläggstyp och applikation."
+
+#: views/developers/addon_edit_categories.thtml:86
+msgid "devcp_edit_categories_other"
+msgstr ""
+"Lägg ditt tillägg i denna kategori bara om det inte passar i någon av de "
+"övriga kategorierna."
+
+#. %s is the application name (Firefox, Thunderbird).
+#: views/developers/addon_edit_categories.thtml:63
+msgid "devcp_edit_categories_select_application_categories"
+msgstr "Välj upp till tre %s kategorier för ditt tillägg"
+
+#: views/developers/addon_edit.thtml:47
+msgid "devcp_edit_dd_manage_authors"
+msgstr "Lägg till eller ta bort användare som kan hantera detta tillägg."
+
+#: views/developers/addon_edit.thtml:49
+msgid "devcp_edit_dd_manage_categories"
+msgstr "Välj relevanta kategorier för varje applikation ditt tillägg stöder."
+
+#: views/developers/addon_edit.thtml:51
+msgid "devcp_edit_dd_manage_description"
+msgstr ""
+"Lägg till och redigera översättningar för ditt tilläggs sammanfattning, "
+"beskrivning, användarlicens och integritetsriktlinjer."
+
+#: views/developers/addon_edit.thtml:53
+msgid "devcp_edit_dd_manage_properties"
+msgstr "Ändra ditt tilläggs namn, hemsida, ikon och andra flaggor."
+
+#: views/developers/addon_edit_descriptions.thtml:116
+msgid "devcp_edit_description_button_update"
+msgstr "Uppdatera beskrivningar"
+
+#: views/developers/addon_edit_descriptions.thtml:115
+msgid "devcp_edit_description_correct_error"
+msgstr "Rätta felen ovan markerade med rött."
+
+#: views/developers/addon_edit_descriptions.thtml:51
+msgid "devcp_edit_descriptions_header"
+msgstr "Redigera tilläggsbeskrivningar"
+
+#: views/developers/addon_edit_descriptions.thtml:94
+msgid "devcp_edit_descriptions_transbox_comments_description"
+msgstr ""
+"All information användare kan vilja ha som inte nödvändigtvis hör hemma i "
+"tilläggets sammanfattning eller beskrivning. Vanliga användningsområden är "
+"listor över kända problem, information om hur man felrapporterar, planerat "
+"datum för en framtida version med mera."
+
+#: views/developers/addon_edit_descriptions.thtml:93
+msgid "devcp_edit_descriptions_transbox_comments_name"
+msgstr "Utvecklarkommentarer"
+
+#: views/developers/addon_edit_descriptions.thtml:86
+msgid "devcp_edit_descriptions_transbox_description_description"
+msgstr ""
+"Beskrivningen av ditt tillägg är en längre genomgång av finesser, "
+"funktionalitet och annat relevant informaiton. Den visas under "
+"sammanfattningen på tilläggets sida."
+
+#: views/developers/addon_edit_descriptions.thtml:85
+msgid "devcp_edit_descriptions_transbox_description_name"
+msgstr "Tilläggsbeskrivning"
+
+#: views/developers/addon_edit_descriptions.thtml:103
+msgid "devcp_edit_descriptions_transbox_eula_description"
+msgstr ""
+"Om ditt tillägg har en användarlicens, skriv den i rutan nedan. Om den är "
+"ifylld kommer användare att behöva godkänna den innan de kan installera ditt "
+"tillägg. Notera att en avnändarlicens inte är samma sak som en kodlicens som "
+"GPL eller MPL."
+
+#: views/developers/addon_edit_descriptions.thtml:102
+msgid "devcp_edit_descriptions_transbox_eula_name"
+msgstr "Användarlicens"
+
+#: views/developers/addon_edit_descriptions.thtml:112
+msgid "devcp_edit_descriptions_transbox_privacy_description"
+msgstr ""
+"Om ditt tillägg har integritetsriktlinjer, skriv dem här. Ditt tilläggs "
+"visningssida kommer att ha en länk till dessa."
+
+#: views/developers/addon_edit_descriptions.thtml:111
+msgid "devcp_edit_descriptions_transbox_privacy_name"
+msgstr "Integritetsriktlinjer"
+
+#: views/developers/addon_edit_descriptions.thtml:78
+msgid "devcp_edit_descriptions_transbox_summary_description"
+msgstr ""
+"Sammanfattningen är en kort förklaring av ditt tilläggs grundläggande "
+"funktionalitet som visas i sök och bläddringslistor, liksom på ditt tilläggs "
+"visningssida. <strong>Högst 250 tecken.</strong>"
+
+#: views/developers/addon_edit_descriptions.thtml:77
+msgid "devcp_edit_descriptions_transbox_summary_name"
+msgstr "Tilläggssammanfattning"
+
+#: views/developers/addon_edit.thtml:46
+msgid "devcp_edit_dt_manage_authors"
+msgstr "Hantera tilläggsförfattare"
+
+#: views/developers/addon_edit.thtml:48
+msgid "devcp_edit_dt_manage_categories"
+msgstr "Hantera tilläggskategorier"
+
+#: views/developers/addon_edit.thtml:50
+msgid "devcp_edit_dt_manage_descriptions"
+msgstr "Hantera tilläggsbeskrivningar"
+
+#: views/developers/addon_edit.thtml:52
+msgid "devcp_edit_dt_manage_properties"
+msgstr "Hantera tilläggsegenskaper"
+
+#: views/developers/addon_edit_properties.thtml:170
+msgid "devcp_edit_label_externalsoftware"
+msgstr "Detta tillägg kräver extern programvara"
+
+#: views/developers/addon_edit_properties.thtml:205
+msgid "devcp_edit_label_locale_disambiguation"
+msgstr "Ytterligare lokalinformation"
+
+#: views/developers/addon_edit_properties.thtml:168
+msgid "devcp_edit_label_prerelease"
+msgstr "Detta är en förhandsversion"
+
+#: views/developers/addon_edit_properties.thtml:169
+msgid "devcp_edit_label_sitespecific"
+msgstr "Detta är ett tillägg för en specifik webbplats"
+
+#: views/developers/addon_edit_properties.thtml:202
+msgid "devcp_edit_label_target_locale"
+msgstr "MÃ¥llokal"
+
+#: views/developers/addon_edit_properties.thtml:212
+msgid "devcp_edit_properties_button_update"
+msgstr "Uppdatera egenskaper"
+
+#: views/developers/addon_edit_properties.thtml:198
+msgid "devcp_edit_properties_change_guid"
+msgstr "Ändra bara om du förstår konsekvenserna."
+
+#: views/developers/addon_edit_properties.thtml:109
+msgid "devcp_edit_properties_current_icon"
+msgstr "Nuvarande ikon"
+
+#: views/developers/addon_edit_properties.thtml:85
+msgid "devcp_edit_properties_default_locale"
+msgstr ""
+"Ett tilläggs standardlokal är dess huvudlokal för vilken de måste finnas en "
+"översättning. Om det inte finns någon översättning för ditt tillägg i "
+"användarens valda språk kommer denna lokal att användas istället."
+
+#: views/developers/addon_edit_properties.thtml:167
+msgid "devcp_edit_properties_flags"
+msgstr "Dessa flaggor användas för att filtrera och klassificera tillägg."
+
+#: views/developers/addon_edit_properties.thtml:174
+msgid "devcp_edit_properties_guid"
+msgstr ""
+"Ditt tilläggs GUID anges i dess install.rdf och används för att identifiera "
+"det. Du kan inte ändra ditt GUID när det väl är listat hos Mozilla Add-ons."
+
+#: views/developers/addon_edit_properties.thtml:53
+msgid "devcp_edit_properties_header"
+msgstr "Rediga tilläggsegenskaper"
+
+#: views/developers/addon_edit_properties.thtml:186
+msgid "devcp_edit_properties_header_addon_type"
+msgstr "Tilläggstyp"
+
+#: views/developers/addon_edit_properties.thtml:181
+msgid "devcp_edit_properties_header_admin_settings"
+msgstr "Administratörsinställningar"
+
+#: views/developers/addon_edit_properties.thtml:84
+msgid "devcp_edit_properties_header_default_locale"
+msgstr "Standardlokal"
+
+#: views/developers/addon_edit_properties.thtml:166
+msgid "devcp_edit_properties_header_flags"
+msgstr "Tilläggsflaggor"
+
+#: views/developers/addon_edit_properties.thtml:173
+#: views/developers/addon_edit_properties.thtml:197
+msgid "devcp_edit_properties_header_guid"
+msgstr "Tilläggets GUID"
+
+#: views/developers/addon_edit_properties.thtml:104
+msgid "devcp_edit_properties_header_icon"
+msgstr "Tilläggsikon"
+
+#: views/developers/addon_edit_properties.thtml:159
+msgid "devcp_edit_properties_header_other_settings"
+msgstr "Andra inställningar"
+
+#. A header on the admin page to toggle trusted status.
+#: views/developers/addon_edit_properties.thtml:182
+msgid "devcp_edit_properties_header_trusted"
+msgstr "Betrott tillägg?"
+
+#: views/developers/addon_edit_properties.thtml:160
+msgid "devcp_edit_properties_header_view_source"
+msgstr "Visa källkoden på nätet"
+
+#. %s is a comma-separated list of image extensions ".png, .jpg"
+#: views/developers/addon_edit_properties.thtml:106
+msgid "devcp_edit_properties_icon"
+msgstr ""
+"Tilläggets ikon är en liten bild som visas bredvid ditt tilläggs namn i sök- "
+"och bläddringslistor, dess huvudsida och installationsdialogen. Bilden "
+"skalas automatiskt ner till 32x32 pixlar. Använd en av följande bildtyper: %s"
+
+#: views/developers/addon_edit_properties.thtml:171
+msgid "devcp_edit_properties_label_binary"
+msgstr "Detta tillägg innehåller binära komponenter"
+
+#: views/developers/addon_edit_properties.thtml:185
+msgid "devcp_edit_properties_label_not_trusted"
+msgstr "Ej betrott"
+
+#: views/developers/addon_edit_properties.thtml:184
+msgid "devcp_edit_properties_label_trusted"
+msgstr "Betrott"
+
+#: views/developers/addon_edit_properties.thtml:110
+msgid "devcp_edit_properties_new_icon"
+msgstr "Ny ikon"
+
+#: views/developers/addon_edit_properties.thtml:118
+msgid "devcp_edit_properties_remove_icon"
+msgstr "Ta bort ikon"
+
+#: views/developers/addon_edit_properties.thtml:136
+msgid "devcp_edit_properties_transbox_homepage_description"
+msgstr ""
+"Om ditt tillägg har en till hemsida, skriv dess adress här. Översättningar "
+"behövs inte om inte din webbplats är lokaliserad för andra språk."
+
+#: views/developers/addon_edit_properties.thtml:135
+msgid "devcp_edit_properties_transbox_homepage_name"
+msgstr "Tilläggshemsida"
+
+#: views/developers/addon_edit_properties.thtml:79
+msgid "devcp_edit_properties_transbox_name_description"
+msgstr "Namnet på ditt tillägg visas överallt där ditt tilläg listas."
+
+#: views/developers/addon_edit_properties.thtml:78
+msgid "devcp_edit_properties_transbox_name_name"
+msgstr "Tilläggsnamn"
+
+#: views/developers/addon_edit_properties.thtml:145
+msgid "devcp_edit_properties_transbox_supportemail_description"
+msgstr ""
+"Om du har en e-postadress för hjälpförfrågningar, ange den här. "
+"Översättningar för andra språk behöver inte anges om du inte har olika e-"
+"postadresser för olika språk."
+
+#: views/developers/addon_edit_properties.thtml:144
+msgid "devcp_edit_properties_transbox_supportemail_name"
+msgstr "E-postadress för hjälp"
+
+#: views/developers/addon_edit_properties.thtml:154
+msgid "devcp_edit_properties_transbox_supporturl_description"
+msgstr ""
+"Om ditt tillägg har en webbplats eller ett forum för hjälp, ange adressen "
+"här. Översättningar för andra språk behövs inte om inte din webbplats har "
+"specialversioner för andra språk."
+
+#: views/developers/addon_edit_properties.thtml:153
+msgid "devcp_edit_properties_transbox_supporturl_name"
+msgstr "Webbplats för hjälp"
+
+#: views/developers/addon_edit_properties.thtml:183
+msgid "devcp_edit_properties_trusted"
+msgstr "Betrodda tillägg kan bli publika direkt utan redaktörsgodkännande."
+
+#. %s is href="..." and should stay in the <a> tag.
+#: views/developers/addon_edit_properties.thtml:119
+msgid "devcp_edit_properties_undelete"
+msgstr "Ikonen tas bort när du sparar. <a %s>Avbryt?</a>"
+
+#: views/developers/addon_edit_properties.thtml:161
+msgid "devcp_edit_properties_view_source"
+msgstr ""
+"Källkoden för ditt tillägg kan visas direkt på nätet för inloggade användare "
+"om du vill."
+
+#: views/developers/addon_edit_properties.thtml:162
+msgid "devcp_edit_properties_view_source_allow"
+msgstr "Tillåt källkodsvisning på nätet"
+
+#: views/developers/addon_edit_properties.thtml:163
+msgid "devcp_edit_properties_view_source_do_not_allow"
+msgstr "Tillåt inte källkodsvisning på nätet"
+
+#: views/elements/developers/editbox.thtml:46
+msgid "devcp_editbox_authors"
+msgstr "Författare"
+
+#: views/elements/developers/editbox.thtml:47
+msgid "devcp_editbox_categories"
+msgstr "Kategorier"
+
+#: views/elements/developers/editbox.thtml:52
+msgid "devcp_editbox_change_status"
+msgstr "Ändra status"
+
+#: views/elements/developers/editbox.thtml:48
+msgid "devcp_editbox_descriptions"
+msgstr "Beskrivningar"
+
+#: views/elements/developers/editbox.thtml:43
+msgid "devcp_editbox_edit_addon"
+msgstr "Redigera tillägg"
+
+#: views/elements/developers/editbox.thtml:57
+msgid "devcp_editbox_new_version"
+msgstr "Ny version"
+
+#: views/elements/developers/editbox.thtml:49
+msgid "devcp_editbox_properties"
+msgstr "Egenskaper"
+
+#: views/elements/developers/editbox.thtml:60
+msgid "devcp_editbox_screenshots"
+msgstr "Förhandsvisa skärmbilder"
+
+#: views/elements/developers/editbox.thtml:53
+msgid "devcp_editbox_statistics_dashboard"
+msgstr "Statistikpanelen"
+
+#: views/elements/developers/editbox.thtml:54
+msgid "devcp_editbox_versions"
+msgstr "Versioner och filer"
+
+#: views/elements/developers/editbox.thtml:42
+msgid "devcp_editbox_view_listing"
+msgstr "Visa listning"
+
+#: views/elements/developers/editorsmenu.thtml:59
+msgid "devcp_editorsqueue_featured"
+msgstr "Uppmärksammat tillägg"
+
+#. %1 is the review count
+#: views/elements/developers/editorsqueue.thtml:42
+#: views/elements/developers/editorsmenu.thtml:56
+#, php-format
+msgid "devcp_editorsqueue_moderatedreviews"
+msgid_plural "devcp_editorsqueue_moderatedreviews"
+msgstr[0] "Modererad recension (%s)"
+msgstr[1] "Modererade recensioner (%s)"
+
+#. %1 is the nominated addons count
+#: views/elements/developers/editorsqueue.thtml:44
+#: views/elements/developers/editorsmenu.thtml:58
+#, php-format
+msgid "devcp_editorsqueue_nominated"
+msgid_plural "devcp_editorsqueue_nominated"
+msgstr[0] "Nominerat tillägg (%s)"
+msgstr[1] "Nominerade tillägg (%s)"
+
+#. %1 is the update count
+#: views/elements/developers/editorsqueue.thtml:43
+#: views/elements/developers/editorsmenu.thtml:57
+#, php-format
+msgid "devcp_editorsqueue_pendingupdates"
+msgid_plural "devcp_editorsqueue_pendingupdates"
+msgstr[0] "Väntande uppdatering (%s)"
+msgstr[1] "Väntande uppdateringar (%s)"
+
+#: controllers/statistics_controller.php:147
+#: controllers/statistics_controller.php:361
+#: controllers/previews_controller.php:108
+#: controllers/previews_controller.php:211
+#: controllers/previews_controller.php:312
+msgid "devcp_error_addon_access_denied"
+msgstr "Du har inte åtkomst till det tillägget."
+
+#. %s is a complete URL with the text from devcp_error_appversion_reference_link_text
+#. in the <a> tag. This should be fixed.
+#: controllers/components/developers.php:591
+#, php-format
+msgid "devcp_error_appversion_reference_link"
+msgstr "Se %s för referens."
+
+#. This is the link text in the <a> for devcp_error_appversion_reference_link. This
+#. should be fixed.
+#: controllers/components/developers.php:591
+msgid "devcp_error_appversion_reference_link_text"
+msgstr "denna sida"
+
+#: views/developers/addon_edit_authors.thtml:76
+msgid "devcp_error_empty_authors"
+msgstr "Ditt tillägg måste ha minst en ägare."
+
+#. %1$s is the name of the file
+#: controllers/components/developers.php:658
+msgid "devcp_error_file_exists"
+msgstr ""
+"En version av det tillägget finns redan. För att ersätta det måste du ta "
+"bort filen %1$s först."
+
+#. %1$s is a file extension. Example: .exe
+#. %2$s is a comma separated list of extensions. Example: .xpi, .jar
+#: controllers/components/developers.php:355
+#, php-format
+msgid "devcp_error_file_extension"
+msgstr ""
+"Den filextensionen (%s) tillåts inte för den valda tilläggstypen. Använd en "
+"av följande: %s"
+
+#: controllers/components/developers.php:64
+msgid "devcp_error_five_categories"
+msgstr "Välj mindre en fem kategorier."
+
+#: controllers/components/developers.php:526
+msgid "devcp_error_guid_application"
+msgstr "IDt för detta tillägg används redan av en applikation."
+
+#: controllers/components/developers.php:337
+#: controllers/components/developers.php:389
+msgid "devcp_error_http_incomplete"
+msgstr "Överföringen var inte komplett"
+
+#: controllers/components/developers.php:335
+#: controllers/components/developers.php:336
+#: controllers/components/developers.php:387
+#: controllers/components/developers.php:388
+msgid "devcp_error_http_maxupload"
+msgstr "Överstiger maximalstorlek för uppladdningar"
+
+#: controllers/components/developers.php:338
+#: controllers/components/developers.php:390
+msgid "devcp_error_http_nofile"
+msgstr "Ingen fil uppladdad"
+
+#. %1$s is a file extension. Example: .exe
+#. %2$s is a comma separated list of extensions. Example: .xpi, .jar
+#: controllers/components/developers.php:401
+#, php-format
+msgid "devcp_error_icon_extension"
+msgstr ""
+"Den filextensionen (%s) är inte tillåten för en ikon. Använd en av följande: "
+"%s"
+
+#: controllers/developers_controller.php:504
+msgid "devcp_error_index_rdf_notfound"
+msgstr "Ingen install.rdf fanns."
+
+#: controllers/components/developers.php:601
+msgid "devcp_error_install_manifest"
+msgstr "Följande fel hittades i install.rdf:"
+
+#: controllers/developers_controller.php:1463
+msgid "devcp_error_invalid_addontype"
+msgstr "Välj en giltig tilläggstyp."
+
+#. %$1s is a version. Example: 3.1.1
+#. %$2s is an add-on name.
+#: controllers/components/developers.php:569
+#: controllers/components/developers.php:581
+#, php-format
+msgid "devcp_error_invalid_appversion"
+msgstr "%s är inte en giltig version för %s"
+
+#. %s is a string
+#: controllers/components/developers.php:521
+#, php-format
+msgid "devcp_error_invalid_guid"
+msgstr "IDt för detta tillägg är inte giltigt: %s"
+
+#. %$1s is a version. Example: 3.1.1
+#. %$2s is an add-on name.
+#: controllers/components/developers.php:572
+#, php-format
+msgid "devcp_error_invalid_minversion"
+msgstr ""
+"%s är inte en giltig version för %s: minimum-versioner kan inte innehålla *"
+
+#: controllers/components/developers.php:536
+msgid "devcp_error_invalid_version"
+msgstr ""
+"Denna version av detta tillägg är ogiltig: Se <a href=\"http://developer."
+"mozilla.org/en/docs/Toolkit_version_format\">specifikationen</a>"
+
+#: controllers/components/developers.php:531
+msgid "devcp_error_invalid_version_spaces"
+msgstr ""
+"Versionen för detta tillägg är ogiltig: versioner kan inte innehålla "
+"mellanslag."
+
+#. %s is an error message from the parser.
+#: controllers/components/developers.php:501
+#, php-format
+msgid "devcp_error_manifest_parse"
+msgstr "Följande fel hittades i install.rdf: %s"
+
+#: controllers/components/developers.php:373
+msgid "devcp_error_move_file"
+msgstr "Kunde inte flytta filen"
+
+#. %s is the name of a file
+#: controllers/components/developers.php:650
+#: controllers/components/developers.php:662
+#: controllers/components/developers.php:667
+#: controllers/components/developers.php:727
+#: controllers/components/developers.php:738
+#: controllers/components/developers.php:743
+#, php-format
+msgid "devcp_error_moving_file"
+msgstr "Ett fel inträffade när %s flyttades."
+
+#: controllers/components/developers.php:595
+msgid "devcp_error_mozilla_application"
+msgstr "Du måste ha minst en giltig Mozilla-målapplikation."
+
+#: controllers/components/developers.php:516
+msgid "devcp_error_no_guid"
+msgstr "Inget ID fanns för detta tillägg i install.rdf."
+
+#: controllers/components/developers.php:287
+msgid "devcp_error_no_platform"
+msgstr "Ingen plattform vald"
+
+#: controllers/components/developers.php:59
+msgid "devcp_error_one_category"
+msgstr "Välj minst en kategori."
+
+#: controllers/components/developers.php:92
+msgid "devcp_error_one_user"
+msgstr "Det måste finnas åtminstone en författare för detta tillägg."
+
+#. %1$s is a file extension. Example: .exe
+#. %2$s is a comma separated list of extensions. Example: .xpi, .jar
+#: controllers/components/developers.php:1081
+#, php-format
+msgid "devcp_error_preview_extension"
+msgstr ""
+"Den filändelsen (%s) är inte tillåten för en förhandsvisning. Använd en av "
+"följande: %s"
+
+#: controllers/components/developers.php:511
+msgid "devcp_error_updatekey"
+msgstr ""
+"Tillägg får inte ha en updateKey. Ta bort den från install.rdf och försök "
+"igen."
+
+#: controllers/components/developers.php:506
+msgid "devcp_error_updateurl"
+msgstr ""
+"Tillägg kan inte ha en extern updateURL. Ta bort den från install.rdf och "
+"försök igen."
+
+#: controllers/developers_controller.php:465
+#: controllers/components/developers.php:271
+msgid "devcp_error_upload_file"
+msgstr "Ladda upp en fil."
+
+#: views/developers/uploader.thtml:135
+msgid "devcp_input_upload_file"
+msgstr "Ladda upp fil"
+
+#: views/pages/js_constants.js.thtml:89
+msgid "devcp_js_a_cancel"
+msgstr "Avbryt"
+
+#: views/pages/js_constants.js.thtml:90
+msgid "devcp_js_add_email"
+msgstr "Ange e-postadressen för den författare du vill lägga till."
+
+#. alt text for a down-arrow image.
+#: views/pages/js_constants.js.thtml:81
+msgid "devcp_js_img_move_down"
+msgstr "Flytta ner"
+
+#. alt text for an up-arrow image.
+#: views/pages/js_constants.js.thtml:82
+msgid "devcp_js_img_move_up"
+msgstr "Flytta upp"
+
+#: views/pages/js_constants.js.thtml:91
+msgid "devcp_js_img_remove_compat"
+msgstr "Ta bort applikationskompatibilitet"
+
+#: views/pages/js_constants.js.thtml:86
+msgid "devcp_js_input_list_author"
+msgstr "Lista som författare i publika listningar"
+
+#: views/pages/js_constants.js.thtml:92
+msgid "devcp_js_license_select"
+msgstr "Välj en licens."
+
+#: views/pages/js_constants.js.thtml:93
+msgid "devcp_js_license_text"
+msgstr "Skriv texten för din licens."
+
+#. <option> text in a <select> for Author role in an add-on.
+#: views/pages/js_constants.js.thtml:84
+msgid "devcp_js_option_developer"
+msgstr "Utvecklare"
+
+#. <option> text in a <select> for Author role in an add-on.
+#: views/pages/js_constants.js.thtml:83
+msgid "devcp_js_option_owner"
+msgstr "Ägare"
+
+#. <option> text in a <select> for Author role in an add-on.
+#: views/pages/js_constants.js.thtml:85
+msgid "devcp_js_option_viewer"
+msgstr "Observatör"
+
+#: views/pages/js_constants.js.thtml:88
+msgid "devcp_js_remove_author"
+msgstr "Ta bort författare"
+
+#: views/pages/js_constants.js.thtml:87
+msgid "devcp_js_sure_remove"
+msgstr "Är du <strong>säker</strong> på att du vill ta bort denna författare?"
+
+#: views/pages/js_constants.js.thtml:77
+msgid "devcp_js_upload_alert"
+msgstr "Du måste välja en fil att ladda upp."
+
+#. %1$s is an addon id, like 32.
+#. %2$s is a version number, like 3.5.
+#: controllers/components/developers.php:1212
+msgid "devcp_license_existing"
+msgstr "Anpassad licens för tillägget %1$s v%2$s"
+
+#: views/elements/developers/localebox.thtml:44
+msgid "devcp_localebox_header_localizedfields"
+msgstr "Lokaliserade fält"
+
+#. %1 is the default locale
+#: views/elements/developers/localebox.thtml:48
+#, php-format
+msgid "devcp_localebox_intro"
+msgstr ""
+"Några fält på den här sidan är lokaliserade och presenteras i användarens "
+"eget språk. Välj en lokal nedan för att redigera ditt tilläggs information "
+"på det språket. Om en översättning inte finns tillgänglig för en lokal "
+"kommer den förvalda (%s) att användas istället."
+
+#: views/elements/developers/sidebar.thtml:68
+#: views/elements/developers/myaddons.thtml:75
+msgid "devcp_myaddons_admincp_link"
+msgstr "Adminverktyg"
+
+#: views/elements/developers/sidebar.thtml:65
+#: views/elements/developers/myaddons.thtml:72
+msgid "devcp_myaddons_editorcp_link"
+msgstr "Redigerarverktyg"
+
+#: views/elements/developers/myaddons.thtml:52
+msgid "devcp_myaddons_link"
+msgstr "Mina tillägg"
+
+#: views/elements/developers/sidebar.thtml:70
+#: views/elements/developers/myaddons.thtml:77
+msgid "devcp_myaddons_mainpage_link"
+msgstr "Tillbaka till huvudsidan"
+
+#: views/elements/developers/sidebar.thtml:63
+#: views/elements/developers/myaddons.thtml:70
+msgid "devcp_myaddons_statistics_link"
+msgstr "Statistikpanelen"
+
+#: views/elements/developers/sidebar.thtml:62
+#: views/elements/developers/myaddons.thtml:69
+msgid "devcp_myaddons_submitaddon_link"
+msgstr "Skicka in tillägg"
+
+#: views/elements/developers/sidebar.thtml:48
+#: views/elements/developers/myaddons.thtml:67
+msgid "devcp_myaddons_title"
+msgstr "Utvecklarverktyg"
+
+#. %1$s is an add-on ID, perhaps 167.
+#. %2$s is a URL.
+#: controllers/developers_controller.php:256
+msgid "devcp_new_addon_error"
+msgstr ""
+"Detta tilläggsid (%1$s) finns redan i databasen. Om detta är ditt tillägg "
+"kan du <a href=\"%2$s\">ladda upp en ny version</a>."
+
+#: views/developers/addon_status_nominate.thtml:62
+msgid "devcp_nominate_cancel"
+msgstr "Avbryt och återvänd"
+
+#. %1 is the add-on name
+#: views/developers/addon_status_nominate.thtml:61
+#, php-format
+msgid "devcp_nominate_submit_nominate"
+msgstr "Nominera %s"
+
+#: views/developers/addon_edit_properties.thtml:50
+#: views/developers/addon_status.thtml:49
+#: views/developers/versions_edit.thtml:50
+msgid "devcp_notice_changes_error"
+msgstr ""
+"<span>En eller flera av dina ändringar kunde inte sparas.</span><br />Se "
+"felen nedanför, dina övriga ändringar sparades ordentligt."
+
+#: views/developers/addon_edit_authors.thtml:47
+#: views/developers/addon_edit_properties.thtml:47
+#: views/developers/addon_status.thtml:46
+#: views/developers/addon_edit_descriptions.thtml:47
+#: views/developers/versions_edit.thtml:47
+#: views/developers/addon_edit_categories.thtml:46
+msgid "devcp_notice_changes_saved"
+msgstr ""
+"<span>Dina ändringar är sparade.</span><br />Notera att det kan ta flera "
+"timmar innan ändringar slår igenom på alla delar av webbplatsen."
+
+#: controllers/previews_controller.php:252
+msgid "devcp_notice_cleardefault"
+msgstr ""
+"Om du tar bort detta som standardförhandsvisning kommer en annan "
+"förhandsvisning automatiskt att bli ny standardförhandsvisning."
+
+#: controllers/previews_controller.php:184
+#: controllers/previews_controller.php:251
+msgid "devcp_notice_makedefault"
+msgstr ""
+"Om du gör detta till standardförhandsvisning kommer det att ta bort denna "
+"status från nuvarande standardförhandsvisning."
+
+#: views/developers/addon_edit_authors.thtml:70
+msgid "devcp_notice_unsaved_changes"
+msgstr "Du har osparade ändringar."
+
+#: controllers/developers_controller.php:87
+#: controllers/developers_controller.php:97
+#: controllers/developers_controller.php:100
+#: controllers/previews_controller.php:67
+#: controllers/previews_controller.php:79
+#: controllers/previews_controller.php:82
+msgid "devcp_pagetitle"
+msgstr "Utvecklarverktyg"
+
+#: controllers/previews_controller.php:103
+#: controllers/previews_controller.php:104
+msgid "devcp_preview_add_pagetitle"
+msgstr "Lägg till förhandsvisning"
+
+#: controllers/previews_controller.php:135
+msgid "devcp_preview_added_successfully"
+msgstr "Förhandsvisning tillagd."
+
+#: controllers/previews_controller.php:323
+msgid "devcp_preview_deleted_successfully"
+msgstr "Förhandsvisning borttagen."
+
+#: controllers/previews_controller.php:194
+#: controllers/previews_controller.php:195
+msgid "devcp_preview_edit_pagetitle"
+msgstr "Redigera förhandsvisning"
+
+#: controllers/previews_controller.php:237
+msgid "devcp_preview_updated_successfully"
+msgstr "Förhandsvisning uppdaterad."
+
+#: views/developers/previews.thtml:120
+msgid "devcp_previews_a_another"
+msgstr "Lägg till en till förhandsvisning"
+
+#: views/developers/previews.thtml:96
+msgid "devcp_previews_a_delete"
+msgstr "Ta bort förhandsvisning"
+
+#: views/developers/previews.thtml:95
+msgid "devcp_previews_a_replace"
+msgstr "Ersätt förhandsvisning"
+
+#: views/developers/previews.thtml:126
+msgid "devcp_previews_a_update"
+msgstr "Uppdatera förhandsvisningar"
+
+#: views/developers/previews.thtml:115 views/developers/previews.thtml:124
+msgid "devcp_previews_add_new"
+msgstr "Lägg till ny förhandsvisning"
+
+#. %s is a list of file extensions, e.g. ".png, .gif"
+#: views/developers/previews.thtml:116
+msgid "devcp_previews_add_select"
+msgstr ""
+"Välj en bild att ladda upp nedanför. Bilder större än maxstorleken 700 "
+"pixlar bred, 525 pixlar häg kommer att skalas ned. Godkända filtyper: %s"
+
+#: views/developers/previews.thtml:121
+msgid "devcp_previews_click_below"
+msgstr "Klicka uppdatera förhandsvisningar nedan för att ladda upp."
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/previews.thtml:102
+msgid "devcp_previews_click_update"
+msgstr ""
+"Klicka på knappen Uppdatera förhandsvisningar nedan för att spara denna "
+"bild. (<a %s>Avbryt?</a>)"
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/previews.thtml:107
+msgid "devcp_previews_error_message"
+msgstr ""
+"Denna förhandsvisning tas bort när du klickar på Uppdatera förhandsvisningar "
+"nedan. (<a %s>Avbryt?</a>)"
+
+#: views/previews/add.thtml:45
+msgid "devcp_previews_filetype_info"
+msgstr ""
+"Använd formuläret för att ladda upp en skärmdump av ditt tillägg i PNG, JPEG "
+"eller GIF-format. Bilder större än 700 punkter breda och 525 punkter höga "
+"kommer att skalas om automatiskt."
+
+#: views/previews/add.thtml:43
+msgid "devcp_previews_header_add"
+msgstr "Lägg till förhandsvisning"
+
+#: views/developers/previews.thtml:80
+msgid "devcp_previews_header_caption"
+msgstr "Bildtext för förhandsvisning"
+
+#: views/previews/edit.thtml:43
+msgid "devcp_previews_header_edit"
+msgstr "Redigera förhandsvisning"
+
+#: views/developers/previews.thtml:93
+msgid "devcp_previews_label_default"
+msgstr "Huvudförhandsvisning"
+
+#: views/previews/add.thtml:54
+msgid "devcp_previews_label_file"
+msgstr "Förhandsvisningsfil"
+
+#: views/previews/add.thtml:59 views/previews/edit.thtml:50
+msgid "devcp_previews_label_makedefault"
+msgstr "Gör detta till standardvald förhandsvisningsbild"
+
+#: views/developers/previews.thtml:100
+msgid "devcp_previews_label_new"
+msgstr "Ny bild:"
+
+#: views/developers/previews.thtml:118
+msgid "devcp_previews_label_upload"
+msgstr "Ladda upp förhandsvisning: "
+
+#: views/developers/previews.thtml:50
+msgid "devcp_previews_notice_error"
+msgstr "En eller flera av dina nya förhandsvisningar kunde inte sparas."
+
+#: views/developers/previews.thtml:47
+msgid "devcp_previews_notice_success"
+msgstr "Dina förhandsvisningar har uppdaterats."
+
+#: views/developers/previews.thtml:59
+msgid "devcp_previews_p_screenshots"
+msgstr ""
+"Förhandsvisningen för ditt tillägg visas nedan. Du kan ändra bildtexter "
+"eller bilder där. Huvudförhandsvisningen är den som visas bredvid ditt "
+"tillägg i sök- och bläddringslistor."
+
+#: views/previews/edit.thtml:55
+msgid "devcp_previews_submit_delete"
+msgstr "Ta bort förhandsvisning"
+
+#: views/previews/edit.thtml:55
+msgid "devcp_previews_submit_delete_confirm"
+msgstr "Är du säker på att du vill ta bort den här förhandsvisningen?"
+
+#: views/previews/edit.thtml:54
+msgid "devcp_previews_submit_edit"
+msgstr "Redigera förhandsvisning"
+
+#: views/previews/add.thtml:63
+msgid "devcp_previews_submit_upload"
+msgstr "Ladda upp förhandsvisning"
+
+#: views/developers/previews.thtml:78
+msgid "devcp_previews_thumbnail"
+msgstr "Tumnagel"
+
+#. %s is the add-on name.
+#: views/developers/previews.thtml:44
+msgid "devcp_previews_title"
+msgstr "%s förhandsvisningshanterare"
+
+#: views/developers/uploader.thtml:74
+msgid "devcp_review_agreement_please"
+msgstr ""
+"Var vänlig läs igenom och godkänn Utvecklaravtalet innan du fortsätter."
+
+#: views/elements/developers/rolecheck.thtml:42
+msgid "devcp_rolecheck_no_privs"
+msgstr ""
+"<span>Du har inte tillräckliga rättiigheter för att göra ändringar på denna "
+"sida.</span><br />Kontakta tilläggets ägare om du behöver göra ändringar."
+
+#: controllers/developers_controller.php:1315
+msgid "devcp_several_hours"
+msgstr ""
+"Notera att en del ändringar kan ta flera timmar innan de slår igenom på alla "
+"delar av webbplatsen."
+
+#: views/elements/developers/sidebar.thtml:52
+msgid "devcp_sidebar_a_dashboard"
+msgstr "Panelen"
+
+#. %s is a number
+#: views/elements/developers/statsbar.thtml:45
+#: views/developers/dashboard.thtml:79
+#, php-format
+msgid "devcp_statsbar_adu"
+msgstr "<em>%s</em> Aktiva dagliga användare"
+
+#. %s is a number
+#: views/elements/developers/statsbar.thtml:41
+#: views/developers/dashboard.thtml:75
+#, php-format
+msgid "devcp_statsbar_total_downloads"
+msgstr "<em>%s</em> hämtningar totalt"
+
+#. %s is a number
+#: views/elements/developers/statsbar.thtml:43
+#: views/developers/dashboard.thtml:77
+#, php-format
+msgid "devcp_statsbar_weekly_downloads"
+msgstr "<em>%s</em> hämtningar denna vecka"
+
+#: views/developers/addon_status_confirm.thtml:59
+msgid "devcp_status_confirm_active"
+msgstr ""
+"Markeras detta tillägg som aktivt gör att det dyker upp i publika områden "
+"tillämpliga för dess status, inklusive sökningar och när man bläddrar. Det "
+"kommer att kunna laddas ner från webbplatsen och kan vara tillgängligt via "
+"uppdateringskontrolltjänsten beroende på status. Du kan komma tillbaka hit "
+"och inaktivera det när du vill."
+
+#: views/developers/addon_status_confirm.thtml:59
+msgid "devcp_status_confirm_active_sure"
+msgstr "Är du säker på att du vill göra detta tillägg aktivt?"
+
+#: views/developers/addon_status_confirm.thtml:50
+msgid "devcp_status_confirm_header_sure"
+msgstr "Är du säker?"
+
+#: views/developers/addon_status_confirm.thtml:55
+msgid "devcp_status_confirm_inactive"
+msgstr ""
+"Markeras detta tillägg som inaktivt kommer det inte att dyka upp i publika "
+"områden, inklusive sökningar och när man bläddrar. Det kommer inte att "
+"kunnas laddas ner från webbplatsen och är inte tillgängligt via "
+"uppdateringskontrolltjänsten. Du kan komma in här och tillgängliggöra det "
+"igen när du vill."
+
+#: views/developers/addon_status_confirm.thtml:55
+msgid "devcp_status_confirm_inactive_sure"
+msgstr "Är du säker på att du vill markera detta tillägg som inaktivt?'"
+
+#: views/developers/addon_status_confirm.thtml:74
+msgid "devcp_status_confirm_no"
+msgstr "Nej, avbryt"
+
+#: views/developers/addon_status_confirm.thtml:67
+msgid "devcp_status_confirm_public"
+msgstr ""
+"Gör du detta tillägg publikt kommer det att bli tillgängligt att ladda ner "
+"för alla och erbjuds som uppdatering för befintliga användare."
+
+#: views/developers/addon_status_confirm.thtml:67
+msgid "devcp_status_confirm_public_sure"
+msgstr "Är du säker på att du vill göra tilläggget publikt?"
+
+#: views/developers/addon_status_confirm.thtml:63
+msgid "devcp_status_confirm_sandbox"
+msgstr ""
+"Flyttar du detta tillägg tillbaka till sandlådan kommer användare att behöva "
+"logga in innan de kan ladda ner det och uppdateringar kommer inte längre att "
+"erbjudas till befintliga användare. Eftersom ditt tillägg är publikt för "
+"närvarande kan du komma tillbaka hit när som helst och göra det publikt igen."
+
+#: views/developers/addon_status_confirm.thtml:63
+msgid "devcp_status_confirm_sandbox_sure"
+msgstr "Är du säker på att du vill flytta tillägget till sandlådan?"
+
+#: views/developers/addon_status_confirm.thtml:73
+msgid "devcp_status_confirm_yes"
+msgstr "Ja, jag är säker"
+
+#: views/developers/addon_status_nominate.thtml:46
+msgid "devcp_status_nominate_error_notice"
+msgstr ""
+"<span>Ett nomineringsmeddelande krävs.</span><br />Fyll i textrutan med den "
+"begärda informationen och försök igen."
+
+#: views/developers/addon_status_nominate.thtml:55
+msgid "devcp_status_nominate_header"
+msgstr "Tilläggsnominering"
+
+#: views/developers/dashboard.thtml:85
+msgid "devcp_summary_lastversion"
+msgstr "Senaste version:"
+
+#. %s is the add-on name.
+#: views/developers/addon_edit.thtml:43
+#: views/developers/addon_edit_authors.thtml:44
+#: views/developers/versions_delete.thtml:43
+#: views/developers/addon_edit_properties.thtml:44
+#: views/developers/addon_edit_descriptions.thtml:44
+#: views/developers/versions_edit.thtml:44
+#: views/developers/addon_edit_categories.thtml:43
+#: views/developers/versions.thtml:43
+msgid "devcp_title_edit_addon"
+msgstr "Redigera %s"
+
+#. title attribute for a javascript link that pops up a help dialog.
+#: views/elements/translationbox.thtml:68
+msgid "devcp_transbox_a_title_help"
+msgstr "Hjälp (lämnar inte sidan)"
+
+#: views/elements/translationbox.thtml:68
+msgid "devcp_transbox_alt_help"
+msgstr "Hjälp"
+
+#. %1$s is <span>17</span>, %2$s is 42.
+#: views/elements/translationbox.thtml:101
+msgid "devcp_transbox_chars_used"
+msgstr "Använda tecken: %1$s / %2$s"
+
+#: views/elements/translationbox.thtml:132
+msgid "devcp_transbox_delete_sure"
+msgstr "Är du säker på att du vill ta bort denna översättning?"
+
+#. %s is a locale, like en-US.
+#: views/elements/translationbox.thtml:143
+msgid "devcp_transbox_help_header_tabs"
+msgstr "Vad är dessa %s flikar?"
+
+#: views/elements/translationbox.thtml:145
+msgid "devcp_transbox_help_header_what"
+msgstr "Om jag inte har några översättningar?"
+
+#: views/elements/translationbox.thtml:147
+msgid "devcp_transbox_help_hide"
+msgstr "Göm hjälp"
+
+#: views/elements/translationbox.thtml:146
+msgid "devcp_transbox_help_if"
+msgstr ""
+"Om en användare bläddrar på webbplatsen och det inte finns någon "
+"översättning för deras språk kommer den att använda standardlokalen som "
+"anges på Redigera tilläggsegenskaper. Om du inte har några översättningar, "
+"skriv bara vad du kan i din standardlokal som bör vara ett språk du kan."
+
+#: views/elements/translationbox.thtml:144
+msgid "devcp_transbox_help_transbox"
+msgstr ""
+"Det här är en <i>översättnignsruta</i>. Det låter dig lokalisra ett enskilt "
+"fält till andra språk du har översättningar för. Du kan lägga till, redigera "
+"och ta bort översättningar på lokalfliken."
+
+#: views/elements/translationbox.thtml:85
+msgid "devcp_transbox_img_add_trans"
+msgstr "Lägg till översättning"
+
+#: views/elements/translationbox.thtml:86
+msgid "devcp_transbox_img_remove_trans"
+msgstr "Ta bort översättning"
+
+#: views/elements/translationbox.thtml:123
+msgid "devcp_transbox_input_add_all"
+msgstr "Lägg till lokal till alla"
+
+#: views/elements/translationbox.thtml:122
+msgid "devcp_transbox_input_add_locale"
+msgstr "Lägg till lokal"
+
+#: views/elements/translationbox.thtml:124
+#: views/elements/translationbox.thtml:135
+msgid "devcp_transbox_input_cancel"
+msgstr "Avbryt"
+
+#: views/elements/translationbox.thtml:134
+msgid "devcp_transbox_input_delete"
+msgstr "Ta bort den"
+
+#: views/elements/translationbox.thtml:113
+msgid "devcp_transbox_select_locale"
+msgstr "Välj lokal för översättningen du lägger till:"
+
+#. %1$s and %2$s are GUIDs.
+#: controllers/developers_controller.php:343
+msgid "devcp_update_addon_guid_error"
+msgstr ""
+"Det GUID som används i denna fil (%1$s) stämmer inte med GUID-t för detta "
+"tillägg (%2$s)."
+
+#: controllers/developers_controller.php:334
+msgid "devcp_update_addon_priv_error"
+msgstr "Du har inte rättighet att uppdatera detta tillägg."
+
+#. %1$s is a version number, %2$s is an add-on ID.
+#: controllers/developers_controller.php:399
+msgid "devcp_update_addon_version_belong_error"
+msgstr "Den angivna versionen (%1$s) tillhör inte detta tillägg (%2$s)."
+
+#. %1$s is a version number, maybe 1.1.
+#. %2$s is a URL.
+#: controllers/developers_controller.php:351
+msgid "devcp_update_addon_version_exists_error"
+msgstr ""
+"Versionsnumret du laddade upp (%1$s) finns redan för detta tillägg. Om du "
+"vill lägga till en till fil för denna version, <a href=\"%2$s\">klicka här</"
+"a>."
+
+#. %1$s and %2$s are version numbers.
+#: controllers/developers_controller.php:405
+msgid "devcp_update_addon_version_match_error"
+msgstr ""
+"Det uppladdade versionsnumret (%1$s) stämmer inte med befintligt "
+"versionsnummer (%2$s)."
+
+#: views/developers/uploader.thtml:68
+msgid "devcp_uploader_a_start"
+msgstr "Sätt igång"
+
+#: views/developers/uploader.thtml:137
+msgid "devcp_uploader_ajax_loading"
+msgstr "Laddar upp fil..."
+
+#: views/developers/uploader.thtml:82
+msgid "devcp_uploader_button_agree"
+msgstr "Godkänn och fortsätt"
+
+#: views/developers/uploader.thtml:157
+msgid "devcp_uploader_button_edit"
+msgstr "Redigera mitt tillägg"
+
+#: views/developers/uploader.thtml:158
+msgid "devcp_uploader_button_later"
+msgstr "Jag gör klart mitt tillägg senare."
+
+#: views/developers/uploader.thtml:168
+msgid "devcp_uploader_button_release"
+msgstr "Lägg till versionsinformation"
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/uploader.thtml:156
+msgid "devcp_uploader_created_results"
+msgstr ""
+"<p>Ditt tilläggslistning har skapats. Grundläggande information från din "
+"uppladdade fil har lagrats, men det finns mycket mer i din listning som kan "
+"anpassas.</p><p>Ditt tillägg är för närvarande märkt som <strong>ej "
+"komplett</strong>. För att färdigställa ditt tillägg måste du försäkra dig "
+"om att det har rätt namn, sammanfattning och beskrivning, liksom att välja "
+"minst en kategori. Du kan redigera ditt tilläggs information via länken "
+"nedanför och kontrollera status för ditt tillägg när som helst på <a %"
+"s>statussidan</a>."
+
+#: views/developers/uploader.thtml:143
+msgid "devcp_uploader_error_correct"
+msgstr "Vänligen rätta detta och ladda upp din fil igen."
+
+#. %1$s is a version number, %2$s is a status, e.g Public or Incomplete.
+#: views/developers/uploader.thtml:175
+msgid "devcp_uploader_file_created"
+msgstr ""
+"Din nya fil har lagts till version %1$s och är för närvarande märkt som %2$s."
+
+#: views/developers/uploader.thtml:154
+msgid "devcp_uploader_header_created"
+msgstr "Tillägg skapat!"
+
+#: views/developers/uploader.thtml:141
+msgid "devcp_uploader_header_error"
+msgstr "Oj! Det verkar vara ett problem med den här filen..."
+
+#: views/developers/uploader.thtml:173
+msgid "devcp_uploader_header_file_added"
+msgstr "Fil tillagd!"
+
+#: views/developers/uploader.thtml:66
+msgid "devcp_uploader_header_how"
+msgstr "Hur fungerar det?"
+
+#. %s is the version number, e.g. 3.2.
+#: views/developers/uploader.thtml:163
+msgid "devcp_uploader_header_update_created"
+msgstr "Version %s skapad"
+
+#: views/developers/uploader.thtml:117
+msgid "devcp_uploader_header_upload"
+msgstr "Ladda upp din fil"
+
+#: views/developers/uploader.thtml:67
+msgid "devcp_uploader_how"
+msgstr ""
+"<p>Tack för ditt intresse av att skicka in ditt tillägg till Mozilla Add-"
+"ons. Publicering på Mozilla Add-ons är det enklaste sättet att hantera "
+"distribution av ditt tillägg. Det här får du:</p><ul><li>Varje tillägg har "
+"en publik visningssida med information du anger, som en kort sammanfattning "
+"av tilläggets funktionalitet, en frivillig längre beskrivning och "
+"förhandsvisningar av ditt tillägg.</li><li>Ditt tillägg dyker upp i sök- och "
+"bläddringslistor på webbplatsen och till och med i tilläggshanteraren i "
+"Firefox 3.</li><li>Vi hanterar publicering av alla dina nedladdningsbara "
+"filer och erbjuder en automatisk uppdateringstjänst till användare när du "
+"laddar upp en ny version.</li><li>Du får tillgång till en statistikpanel med "
+"detaljerad information om dina användare.</li></ul><p>Tillägg publicerade på "
+"webbplatsen måste granskas av en redaktör från Mozilla Add-ons innan de "
+"åtnjuter alla finesser ovanför. Om du är redo att starta processen och har "
+"ditt tillägg färdigt för uppladdning, klicka bara på Sätt igång nedanför!</p>"
+
+#: views/developers/uploader.thtml:125
+msgid "devcp_uploader_label_platformtype"
+msgstr "Stödda plattformar:"
+
+#: views/developers/uploader.thtml:124
+msgid "devcp_uploader_label_upload_field"
+msgstr "Tilläggsfil: "
+
+#: controllers/components/developers.php:1221
+msgid "devcp_uploader_option_other"
+msgstr "Annat"
+
+#. %1$s is a number, %2$s is href="..." and should stay in the <a> tag.
+#: views/developers/uploader.thtml:176
+msgid "devcp_uploader_p_pending_file"
+msgstr ""
+"Den nya filen kommer att bli publikt tillgänglig så snart en editor har "
+"godkänt den. Det är för närvarande %1$s andra tillägg i kön. Vill du fått "
+"ditt tillägg granskat snabbare? Överväg att <a %2$s>bli en editor</a>."
+
+#. %1$s is a number, %2$s is href="..." and should stay in the <a> tag.
+#: views/developers/uploader.thtml:166
+msgid "devcp_uploader_p_pending_version"
+msgstr ""
+"Den nya versionen blir tillgänglig för alla så snart som en redaktör har "
+"granskat det. Det är för närvarande %1$s andra tillägg i kön. Vill du få det "
+"granskat snabbare? Fundera på att <a %2$s>bli redaktör</a>."
+
+#. %s is a status, e.g Public or Incomplete.
+#: views/developers/uploader.thtml:165
+msgid "devcp_uploader_p_update_created"
+msgstr "Din nya version är skapad och är för närvarande märkt som %s."
+
+#. %1$s is href="..." and should stay in the 'Versions and Files' <a> tag.
+#. %2$s is href="..." and should stay in the 'current status' <a> tag.
+#: views/developers/uploader.thtml:177
+msgid "devcp_uploader_p_update_file"
+msgstr ""
+"Se din nya fil på <a %1$s>Versioner och filer-sidan</a>, kontrollera ditt "
+"tilläggs <a %2$s>nuvarande status</a>, eller <b>lägg till "
+"versionsinformation</b> genom att klicka på knappen nedan (rekommenderas "
+"starkt)."
+
+#. %1$s is href="..." and should stay in the 'Versions and Files' <a> tag.
+#. %2$s is href="..." and should stay in the 'current status' <a> tag.
+#: views/developers/uploader.thtml:167
+msgid "devcp_uploader_p_update_version"
+msgstr ""
+"Se din nya version på <a %1$s>Versioner och filer-sidan</a>, kontrollera "
+"ditt tilläggs <a %2$s>nuvarande status</a>, eller <b>lägg till "
+"versionsinformation</b> genom att klicka på knappen nedan (rekommenderas "
+"starkt)."
+
+#: views/developers/uploader.thtml:118
+msgid "devcp_uploader_p_upload"
+msgstr ""
+"Ladda upp din fil med formuläret nedanför. Om du har flera, "
+"plattformsspecifika filer att ladda upp, välj en fil och ladda upp de andra "
+"senare med Versioner och filer-hanteraren."
+
+#: views/developers/uploader.thtml:125
+msgid "devcp_uploader_platformtype_all"
+msgstr "Alla"
+
+#: views/developers/uploader.thtml:126
+msgid "devcp_uploader_platformtype_specific"
+msgstr "Specifik:"
+
+#. Used as first item in a <select>.
+#: controllers/components/developers.php:1185
+msgid "devcp_uploader_please_choose"
+msgstr "Var god välj..."
+
+#. %1$s is the add-on name, %2$s is the version number.
+#: views/developers/uploader.thtml:57
+msgid "devcp_uploader_title_file"
+msgstr "Lägg till fil till %1$s %2$s"
+
+#: views/developers/uploader.thtml:50
+msgid "devcp_uploader_title_submit"
+msgstr "Skicka in nytt tillägg"
+
+#. %s is the add-on name.
+#: views/developers/uploader.thtml:54
+msgid "devcp_uploader_title_update"
+msgstr "Uppdatera %s"
+
+#. %s is a full <a> tag
+#: controllers/developers_controller.php:503
+#, php-format
+msgid "devcp_valid_app_reference"
+msgstr "Se %s för referens."
+
+#. This is the text in the <a> tag for devcp_valid_app_reference. This should be
+#. fixed.
+#: controllers/developers_controller.php:503
+msgid "devcp_valid_app_reference_linktext"
+msgstr "denna sida"
+
+#: controllers/developers_controller.php:581
+msgid "devcp_verify_author_error"
+msgstr "Det fanns inget konto med den e-postadressen."
+
+#: controllers/developers_controller.php:553
+msgid "devcp_verify_search_engine_error"
+msgstr ""
+"Antingen är XMLn ogiltig eller så saknas obligatoriska fält. <a href="
+"\"https://developer.mozilla.org/en/Creating_OpenSearch_plugins_for_Firefox"
+"\">Läs dokumentationen</a>, kontrollera ditt tillägg och försök igen."
+
+#: views/developers/versions.thtml:75
+msgid "devcp_versions_a_cancel"
+msgstr "Avbryt"
+
+#: views/developers/versions.thtml:79
+msgid "devcp_versions_a_delete"
+msgstr "Ta bort version"
+
+#: views/developers/versions.thtml:74
+msgid "devcp_versions_a_empty"
+msgstr "Ta bort tom version"
+
+#: views/developers/versions.thtml:71
+msgid "devcp_versions_a_remove"
+msgstr "Ta bort?"
+
+#: views/developers/versions.thtml:91
+msgid "devcp_versions_add"
+msgstr "Lägg till ny version"
+
+#: views/developers/versions_delete.thtml:58
+msgid "devcp_versions_delete_a_cancel"
+msgstr "Avbryt"
+
+#: views/developers/versions_delete.thtml:56
+msgid "devcp_versions_delete_a_delete"
+msgstr "Ta bort version"
+
+#. Followed by a list of reviews and files that will be removed.
+#: views/developers/versions_delete.thtml:50
+msgid "devcp_versions_delete_also"
+msgstr "Detta tar också bort:"
+
+#: views/developers/versions_delete.thtml:53
+msgid "devcp_versions_delete_files"
+msgid_plural "devcp_versions_delete_files"
+msgstr[0] "%s fil"
+msgstr[1] "%s filer"
+
+#. %s is the version number.
+#: views/developers/versions_delete.thtml:48
+msgid "devcp_versions_delete_header"
+msgstr "Ta bort version %s?"
+
+#: views/developers/versions_delete.thtml:52
+msgid "devcp_versions_delete_reviews"
+msgid_plural "devcp_versions_delete_reviews"
+msgstr[0] "%s recension"
+msgstr[1] "%s recensioner"
+
+#. %s is the version number.
+#: views/developers/versions_delete.thtml:49
+msgid "devcp_versions_delete_sure"
+msgstr "Är du säker på att du vill ta bort version %s permanent?"
+
+#: views/developers/versions_edit.thtml:102
+#: views/developers/versions_edit.thtml:155
+msgid "devcp_versions_edit_a_cancel"
+msgstr "Avbryt"
+
+#: views/developers/versions_edit.thtml:101
+msgid "devcp_versions_edit_a_delete"
+msgstr "Ta bort fil"
+
+#: views/developers/versions_edit.thtml:165
+msgid "devcp_versions_edit_a_new_app"
+msgstr "Lägg till ny applikation"
+
+#: views/developers/versions_edit.thtml:154
+msgid "devcp_versions_edit_a_remove_app"
+msgstr "Ta bort applikation"
+
+#: views/developers/versions_edit.thtml:114
+msgid "devcp_versions_edit_add"
+msgstr "Lägg till ny fil"
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/versions_edit.thtml:121
+msgid "devcp_versions_edit_adjust"
+msgstr ""
+"Ändrar du applikationsinformation här låter det användare installera ditt "
+"tillägg även om dess install.rdf säger att tillägget inte är kompatibelt. <a "
+"%s>Lista på applikationer som stöds</a>"
+
+#: views/developers/versions_edit.thtml:153
+msgid "devcp_versions_edit_compat_sure"
+msgstr ""
+"Är du <b>säker</b> på att du vill ta bort kompatibilitet med denna "
+"applikation?"
+
+#: views/developers/versions_edit.thtml:100
+msgid "devcp_versions_edit_delete_sure"
+msgstr "Är du <b>säker</b> på att du vill ta bort filen permanent?"
+
+#: views/developers/versions_edit.thtml:203
+msgid "devcp_versions_edit_header_approval"
+msgstr "Godkännandeinformation"
+
+#: views/developers/versions_edit.thtml:120
+msgid "devcp_versions_edit_header_compat"
+msgstr "Kompatibla applikationer"
+
+#: views/developers/versions_edit.thtml:74
+msgid "devcp_versions_edit_header_file"
+msgstr "Filinformation"
+
+#: views/developers/versions_edit.thtml:189
+msgid "devcp_versions_edit_header_license"
+msgstr "Licens"
+
+#. %s is the version number.
+#: views/developers/versions_edit.thtml:53
+msgid "devcp_versions_edit_header_manage"
+msgstr "Hantera version %s"
+
+#: views/developers/versions_edit.thtml:212
+msgid "devcp_versions_edit_header_notes"
+msgstr "Information vid godkännande"
+
+#: views/developers/versions_edit.thtml:98
+msgid "devcp_versions_edit_img_delete"
+msgstr "Ta bort fil"
+
+#. %1$s is the file id, e.g. 18723.
+#. %2$s is the platform name, e.g. ALL or Windows.
+#. %3$s is the _('date) created.
+#. %4$s is the status, e.g. "In Sandbox" or "Public".
+#. %5$s is the _('date') status was changed.
+#: views/developers/versions_edit.thtml:208
+msgid "devcp_versions_edit_li_file"
+msgstr "Filen %1$s (%2$s) skapad den %3$s och ändrad till %4$s den %5$s"
+
+#: views/developers/versions_edit.thtml:190
+msgid "devcp_versions_edit_license_description"
+msgstr ""
+"Välj den licens som är tillämplig för ditt tillägg. Denna licens bestämmer "
+"vilka rättigheter du ger till din källkod."
+
+#: views/developers/versions_edit.thtml:111
+msgid "devcp_versions_edit_no_files"
+msgstr "Hittade inga filer."
+
+#: views/developers/versions_edit.thtml:213
+msgid "devcp_versions_edit_optional"
+msgstr "Frivillig information för den redaktör som granskar denna version."
+
+#: views/developers/versions_edit.thtml:151
+msgid "devcp_versions_edit_remove_compat"
+msgstr "Ta bort applikationskompatibilitet"
+
+#: views/developers/versions_edit.thtml:167
+msgid "devcp_versions_edit_select_app"
+msgstr "Välj en applikation"
+
+#: views/developers/versions_edit.thtml:78
+msgid "devcp_versions_edit_th_file"
+msgstr "Fil"
+
+#: views/developers/versions_edit.thtml:79
+msgid "devcp_versions_edit_th_platform"
+msgstr "Plattform"
+
+#: views/developers/versions_edit.thtml:80
+msgid "devcp_versions_edit_th_size"
+msgstr "Storlek"
+
+#: views/developers/versions_edit.thtml:81
+msgid "devcp_versions_edit_th_status"
+msgstr "Status"
+
+#: views/developers/versions_edit.thtml:183
+msgid "devcp_versions_edit_transbox_releasenotes_description"
+msgstr ""
+"Information om ändringar i denna version, nya finesser, kända fel och annan "
+"användbar information för denna version. Denna information är även "
+"tillgänglig för användare som uppdaterar tillägget med Firefox 3s "
+"tilläggshanterare."
+
+#: views/developers/versions_edit.thtml:182
+msgid "devcp_versions_edit_transbox_releasenotes_name"
+msgstr "Versionsinformation"
+
+#: views/developers/versions_edit.thtml:164
+msgid "devcp_versions_edit_unsaved_compat"
+msgstr ""
+"<strong>Du har osparade ändringar.</strong> kompatibilitet tas inte bort "
+"förrän du klickar Uppdatera version nedanför."
+
+#: views/developers/versions_edit.thtml:113
+msgid "devcp_versions_edit_unsaved_files"
+msgstr ""
+"<strong>Du har osparade ändringar.</strong> Filer tas inte bort förrän du "
+"klickar Uppdatera version nedanför."
+
+#: views/developers/versions_edit.thtml:218
+msgid "devcp_versions_edit_update"
+msgstr "Uppdatera versioner"
+
+#: views/developers/versions.thtml:49
+msgid "devcp_versions_header_manage"
+msgstr "Hantera versioner och filer"
+
+#: views/developers/versions.thtml:87
+msgid "devcp_versions_no_versions"
+msgstr "Inga versioner."
+
+#. %s is a version number, base 10.
+#: views/developers/versions.thtml:46
+msgid "devcp_versions_notice_success"
+msgstr "Version %s togs bort."
+
+#: views/developers/versions.thtml:73
+msgid "devcp_versions_p_remove"
+msgstr ""
+"Denna version har inga filer kopplade till sig och kan tas bort.d Vill du ta "
+"bort denna version?"
+
+#: views/developers/versions.thtml:58
+msgid "devcp_versions_th_created"
+msgstr "Skapad"
+
+#: views/developers/versions.thtml:57
+msgid "devcp_versions_th_status"
+msgstr "Status"
+
+#: views/developers/versions.thtml:56
+msgid "devcp_versions_th_version"
+msgstr "Version"
+
+#: controllers/downloads_controller.php:91
+msgid "downloads_disable_warning"
+msgstr "Detta tillägg är inaktiverat"
+
+#: controllers/components/editors.php:57
+msgid "editor_review_error_addon_not_nominated"
+msgstr "Detta tillägg har inte blivit nominerat."
+
+#: controllers/components/editors.php:213
+msgid "editor_review_error_file_not_pending"
+msgstr "Denna fil väntar inte på granskning."
+
+#. Actions are, for example: approving or rejecting
+#: controllers/components/editors.php:79
+#: controllers/components/editors.php:182
+msgid "editor_review_error_no_action"
+msgstr "Välj ett granskningsutfall."
+
+#: controllers/components/editors.php:192
+msgid "editor_review_error_no_applications"
+msgstr "Skriv de applikationer du testat."
+
+#. Comments are required when an editor approves or rejects an add-on.
+#: controllers/components/editors.php:84
+#: controllers/components/editors.php:187
+msgid "editor_review_error_no_comments"
+msgstr "Ange granskningskommentarer."
+
+#: controllers/components/editors.php:161
+msgid "editor_review_error_no_files"
+msgstr "Välj minst en fil att granska."
+
+#: controllers/components/editors.php:197
+msgid "editor_review_error_no_operating_system"
+msgstr "Skriv de operativsystem du testat."
+
+#: views/editors/logs.thtml:51
+msgid "editorcp_logs_button_filter"
+msgstr "Filtrera"
+
+#: views/editors/logs.thtml:44
+msgid "editorcp_logs_filter_by"
+msgstr "Filtrera på typ/handling"
+
+#: views/editors/logs.thtml:42 controllers/editors_controller.php:964
+msgid "editorcp_logs_page_heading"
+msgstr "Händelselogg"
+
+#: views/elements/developers/editorsmenu.thtml:60
+msgid "editorcp_menu_eventlog_link"
+msgstr "Händelselogg"
+
+#: views/elements/developers/editorsmenu.thtml:62
+msgid "editorcp_menu_mainpage_link"
+msgstr "Tillbaka till huvudsidan"
+
+#: views/elements/developers/editorsmenu.thtml:61
+msgid "editorcp_menu_reviewlog_link"
+msgstr "Granskningslogg"
+
+#: views/elements/developers/editorsmenu.thtml:55
+msgid "editorcp_menu_summary_link"
+msgstr "Redaktörssammanfattning"
+
+#: views/elements/developers/editorsmenu.thtml:52
+msgid "editorcp_menu_title"
+msgstr "Redaktörsverktyg"
+
+#: views/editors/reviewlog.thtml:49
+msgid "editorcp_reviewlog_button_filter"
+msgstr "Filtrera"
+
+#: views/editors/reviewlog.thtml:58
+msgid "editorcp_reviewlog_column_action"
+msgstr "Handling"
+
+#: views/editors/reviewlog.thtml:56
+msgid "editorcp_reviewlog_column_addon"
+msgstr "Tillägg"
+
+#: views/editors/reviewlog.thtml:55
+msgid "editorcp_reviewlog_column_date"
+msgstr "Datum"
+
+#: views/editors/reviewlog.thtml:57
+msgid "editorcp_reviewlog_column_editor"
+msgstr "Redaktör"
+
+#: views/editors/reviewlog.thtml:94
+msgid "editorcp_reviewlog_comments_hide"
+msgstr "Göm kommentarer"
+
+#: views/editors/reviewlog.thtml:93
+msgid "editorcp_reviewlog_comments_show"
+msgstr "Visa kommentarer"
+
+#. %1$s and %2$s are full <input> tags for dates
+#: views/editors/reviewlog.thtml:45
+#, php-format
+msgid "editorcp_reviewlog_entries_between"
+msgstr "Visa poster mellan %s och %s"
+
+#: views/editors/reviewlog.thtml:104
+msgid "editorcp_reviewlog_none_found"
+msgstr "Inga granskningar hittade i denna period."
+
+#: views/editors/reviewlog.thtml:42
+msgid "editorcp_reviewlog_page_heading"
+msgstr "Granskningslogg"
+
+#: views/editors/summary.thtml:61
+msgid "editorcp_summary_monthreviews_heading"
+msgstr "MÃ¥nadsgranskningar"
+
+#: views/editors/summary.thtml:77
+msgid "editorcp_summary_neweditors_heading"
+msgstr "Nya redaktörer"
+
+#: views/editors/summary.thtml:42
+msgid "editorcp_summary_page_heading"
+msgstr "Redaktörssammanfattning"
+
+#: views/editors/summary.thtml:94
+msgid "editorcp_summary_recentactivity_heading"
+msgstr "Färsk redaktörsaktivitet"
+
+#: views/editors/summary.thtml:45
+msgid "editorcp_summary_totalreviews_heading"
+msgstr "Totala granskningar"
+
+#: controllers/editors_controller.php:248
+#: controllers/editors_controller.php:249
+msgid "editors_addon_review_pagetitle"
+msgstr "Granska tillägg"
+
+#: controllers/editors_controller.php:349
+msgid "editors_error_js-formerror"
+msgstr "Fyll i följande fält:"
+
+#: controllers/editors_controller.php:350
+msgid "editors_error_review_one_file"
+msgstr "Välj minst en fil att granska."
+
+#: controllers/editors_controller.php:274
+msgid "editors_error_self_reviews_forbidden"
+msgstr "Granskningar av eget material är inte tillåtet."
+
+#: controllers/editors_controller.php:699
+msgid "editors_external_software"
+msgstr "Extern programvara"
+
+#: views/editors/featured.thtml:120 views/editors/featured.thtml:121
+msgid "editors_featured_add_feature"
+msgstr "Lägg till uppmärksamhet"
+
+#: views/editors/featured.thtml:126
+msgid "editors_featured_add_feature_submit"
+msgstr "Lägg till"
+
+#: views/editors/featured.thtml:49 controllers/editors_controller.php:832
+#: controllers/editors_controller.php:848
+msgid "editors_featured_addon_add_failure"
+msgstr "Misslyckades med att lägga till uppmärksamhet för tillägg."
+
+#: controllers/editors_controller.php:851
+msgid "editors_featured_addon_add_success"
+msgstr "Uppmärksammade tillägg."
+
+#: views/editors/featured.thtml:50 controllers/editors_controller.php:839
+#: controllers/editors_controller.php:868
+#: controllers/editors_controller.php:886
+msgid "editors_featured_addon_edit_failure"
+msgstr "Misslyckades med att redigera uppmärksamhet."
+
+#: views/editors/featured.thtml:51 controllers/editors_controller.php:888
+msgid "editors_featured_addon_edit_success"
+msgstr "Redigerade uppmärksamhet."
+
+#: views/editors/featured.thtml:53 controllers/editors_controller.php:861
+msgid "editors_featured_addon_invalid_locale"
+msgstr "En eller flera lokaler är ogiltiga."
+
+#: views/editors/featured.thtml:52 controllers/editors_controller.php:906
+msgid "editors_featured_addon_remove_failure"
+msgstr "Misslyckades med att ta bort uppmärksamhet."
+
+#: controllers/editors_controller.php:901
+msgid "editors_featured_addon_remove_success"
+msgstr "Tog bort uppmärksamhet."
+
+#: controllers/editors_controller.php:915
+#: controllers/editors_controller.php:917
+msgid "editors_featured_addons_pagetitle"
+msgstr "Uppmärksammade tillägg"
+
+#: views/editors/featured.thtml:54 views/editors/featured.thtml:107
+msgid "editors_featured_edit_feature_submit"
+msgstr "Utför"
+
+#: views/editors/featured.thtml:90 views/editors/featured.thtml:91
+msgid "editors_featured_remove_feature"
+msgstr "Ta bort uppmärksamhet"
+
+#: views/editors/queue.thtml:46
+msgid "editors_filter_queue"
+msgstr "Filtrera kö"
+
+#: views/editors/queue.thtml:182
+msgid "editors_helpful_links"
+msgstr "Hjälpsamma länkar"
+
+#: views/editors/queue.thtml:182
+msgid "editors_link_guide"
+msgstr "Redaktörsguide"
+
+#: views/editors/queue.thtml:182
+msgid "editors_link_policy"
+msgstr "Add-ons riktlinjer"
+
+#: views/editors/queue.thtml:47
+msgid "editors_notice_filter_session"
+msgstr "Detta filter kvarstår för denna session eller tills de rensas."
+
+#. %1 is the queue mode
+#: views/editors/queue.thtml:177 views/admin/flagged_queue.thtml:89
+msgid "editors_notice_none_found"
+msgstr "Det finns just nu inga tillägg av denna typ att granska."
+
+#: controllers/editors_controller.php:1040
+msgid "editors_one_day"
+msgstr "1 dag"
+
+#: controllers/editors_controller.php:1048
+msgid "editors_one_hour"
+msgstr "1 timme"
+
+#: controllers/editors_controller.php:1056
+msgid "editors_one_minute"
+msgstr "1 minut"
+
+#: controllers/editors_controller.php:64 controllers/editors_controller.php:73
+#: controllers/editors_controller.php:77
+msgid "editors_pagetitle"
+msgstr "Redaktörsverktyg"
+
+#. %s is a comma separated list of platforms. Example: Windows, OS X
+#: controllers/editors_controller.php:680
+#: controllers/editors_controller.php:683
+#, php-format
+msgid "editors_platform_x_only"
+msgstr "%s bara"
+
+#: controllers/editors_controller.php:695
+msgid "editors_pre-release"
+msgstr "Förhandsversion"
+
+#. %1 is the app name
+#: views/editors/queue.thtml:131
+#, php-format
+msgid "editors_queue_app_compatibility"
+msgstr "%s kompatibilitet"
+
+#: views/editors/queue.thtml:51
+msgid "editors_queue_filter_label_addon"
+msgstr "Tilläggs- eller författarepostadress"
+
+#: views/editors/queue.thtml:72
+msgid "editors_queue_filter_label_addontypes"
+msgstr "Tilläggstyper"
+
+#: views/editors/queue.thtml:56
+msgid "editors_queue_filter_label_application"
+msgstr "Applikation"
+
+#: views/editors/queue.thtml:61
+msgid "editors_queue_filter_label_maxversion"
+msgstr "Max. version"
+
+#: views/editors/queue.thtml:78
+msgid "editors_queue_filter_label_platforms"
+msgstr "Plattformar"
+
+#: views/editors/queue.thtml:66
+msgid "editors_queue_filter_label_submissionage"
+msgstr "Ålder på inskickning (dagar)"
+
+#. %1$s is a number
+#: views/editors/queue.thtml:90
+msgid "editors_queue_filter_result_count"
+msgid_plural "editors_queue_filter_result_count"
+msgstr[0] "Resultatet av din filtrerade sökning: <strong>%1$s</strong> tillägg"
+msgstr[1] "Resultatet av din filtrerade sökning: <strong>%1$s</strong> tillägg"
+
+#: views/editors/queue.thtml:84
+msgid "editors_queue_submit_clean"
+msgstr "Rensa"
+
+#: views/editors/queue.thtml:83
+msgid "editors_queue_submit_filter"
+msgstr "Filtrera"
+
+#: controllers/editors_controller.php:133
+msgid "editors_queues_disabled"
+msgstr ""
+"Alla granskningsköer är för närvarande avstängda. Titta tillbaka senare."
+
+#: views/editors/review.thtml:149
+msgid "editors_review_a_edit_item"
+msgstr "Redigera post"
+
+#: views/editors/review.thtml:146
+msgid "editors_review_a_item_history"
+msgstr "Historik för post"
+
+#: views/editors/review.thtml:148
+msgid "editors_review_a_item_homepage"
+msgstr "Hemsida för post"
+
+#: views/editors/review.thtml:145
+msgid "editors_review_a_item_overview"
+msgstr "Översikt för post"
+
+#: views/editors/review.thtml:147
+msgid "editors_review_a_previews"
+msgstr "Förhandsgranskningar"
+
+#: controllers/editors_controller.php:345
+msgid "editors_review_action"
+msgstr "Granska handling"
+
+#: views/editors/review.thtml:159
+msgid "editors_review_action_info"
+msgstr "Begär mer information"
+
+#: views/editors/review.thtml:157
+msgid "editors_review_action_public"
+msgstr "Tryck ut till publika"
+
+#: views/editors/review.thtml:160
+msgid "editors_review_action_request_superreview"
+msgstr "Begär super-granskning"
+
+#: views/editors/review.thtml:158
+msgid "editors_review_action_sandbox"
+msgstr "Håll kvar i sandlådan"
+
+#: controllers/editors_controller.php:346
+msgid "editors_review_comments"
+msgstr "Granska kommentarer"
+
+#: views/editors/review.thtml:182
+msgid "editors_review_details_info_request"
+msgstr ""
+"Använd det här formuläret för att begära mer information av en författare. "
+"De får e-post och kan svara här. När de har svarat får du besked via e-post."
+
+#: views/editors/review.thtml:174
+msgid "editors_review_details_nominated_public"
+msgstr ""
+"Detta markerar tillägget och dess senaste version och filer som publika. "
+"Framtida versioner placeras i sandlådan tills de granskats av en redaktör."
+
+#: views/editors/review.thtml:177
+msgid "editors_review_details_nominated_sandbox"
+msgstr "Detta håller kvar tillägget i sandlådan."
+
+#: views/editors/review.thtml:166
+msgid "editors_review_details_pending_public"
+msgstr ""
+"Detta godkänner att en version i sandlådan av ett publikt tillägg flyttas "
+"över till den publika sidan."
+
+#: views/editors/review.thtml:169
+msgid "editors_review_details_pending_sandbox"
+msgstr ""
+"Detta gör att en version i sandlådan av ett publikt tillägg stannar kvar i "
+"sandlådan."
+
+#: views/editors/review.thtml:185
+msgid "editors_review_details_superreview"
+msgstr ""
+"Om du har farhågor om detta tilläggs säkerhet, upphovsrättsstatus eller "
+"annat som administratörerna borde undersöka, skriv dina kommentarer i rutan "
+"nedan. De kommer att skickas till administratörerna, inte författaren."
+
+#: views/editors/review.thtml:134
+msgid "editors_review_file_diff_link"
+msgstr "Jämför med publik version"
+
+#: views/editors/review.thtml:131
+msgid "editors_review_file_viewcontents_link"
+msgstr "Visa innehåll"
+
+#: views/editors/review.thtml:65
+msgid "editors_review_header_authors"
+msgstr "Författare:"
+
+#: views/editors/review.thtml:79
+msgid "editors_review_header_categories"
+msgstr "Kategorier:"
+
+#: views/editors/review.thtml:92
+msgid "editors_review_header_compatibility"
+msgstr "Kompatibilitet:"
+
+#: views/editors/review.thtml:251
+msgid "editors_review_header_description"
+msgstr "Beskrivning"
+
+#: views/editors/review.thtml:275
+msgid "editors_review_header_devcomments"
+msgstr "Utvecklarekommentarer"
+
+#: views/editors/review.thtml:263
+msgid "editors_review_header_eula"
+msgstr "Användningsvillkor (EULA)"
+
+#: views/editors/review.thtml:115
+msgid "editors_review_header_files"
+msgstr "Filer:"
+
+#: views/editors/review.thtml:284
+msgid "editors_review_header_itemhistory"
+msgstr "Historik"
+
+#: views/editors/review.thtml:232
+msgid "editors_review_header_nominationmessage"
+msgstr "Nomineringsmeddelande"
+
+#: views/editors/review.thtml:311
+msgid "editors_review_header_previews"
+msgstr "Förhandsvisningar"
+
+#: views/editors/review.thtml:269
+msgid "editors_review_header_privacy"
+msgstr "Integritetspolicy"
+
+#. %1 is the add-on name and version
+#: views/editors/review.thtml:56
+#, php-format
+msgid "editors_review_header_review"
+msgstr "Granskning %s"
+
+#: views/editors/review.thtml:239
+msgid "editors_review_header_reviewernotes"
+msgstr "Information till granskare"
+
+#: views/editors/review.thtml:245
+msgid "editors_review_header_summary"
+msgstr "Sammanfattning"
+
+#: views/editors/review.thtml:257
+msgid "editors_review_header_versionnotes"
+msgstr "Information för versionen"
+
+#. a noun: shown in an add-on's editor review history
+#: views/elements/developers/editors_review_history_item.thtml:80
+msgid "editors_review_history_info_reply"
+msgstr "Svara"
+
+#: views/elements/developers/editors_review_history_item.thtml:78
+msgid "editors_review_history_info_request"
+msgstr "Begäran av information"
+
+#: views/elements/developers/editors_review_history_item.thtml:62
+#: views/editors/reviewlog.thtml:77
+msgid "editors_review_history_nominated_adminreview"
+msgstr "Admingranskning"
+
+#: views/elements/developers/editors_review_history_item.thtml:56
+#: views/editors/reviewlog.thtml:71
+msgid "editors_review_history_nominated_approved"
+msgstr "Nominering godkänd/Publik"
+
+#: views/elements/developers/editors_review_history_item.thtml:59
+#: views/editors/reviewlog.thtml:74
+msgid "editors_review_history_nominated_denied"
+msgstr "Nominering nekad/Sandlåda"
+
+#: views/editors/review.thtml:303
+msgid "editors_review_history_nonefound"
+msgstr "Inga tidigare granskningsposter hittades."
+
+#: views/elements/developers/editors_review_history_item.thtml:73
+#: views/editors/reviewlog.thtml:88
+msgid "editors_review_history_pending_adminreview"
+msgstr "Admingranskning"
+
+#: views/elements/developers/editors_review_history_item.thtml:67
+#: views/editors/reviewlog.thtml:82
+msgid "editors_review_history_pending_approved"
+msgstr "Godkänd/Publikt"
+
+#: views/elements/developers/editors_review_history_item.thtml:70
+#: views/editors/reviewlog.thtml:85
+msgid "editors_review_history_pending_denied"
+msgstr "Nekad/Sandlåda"
+
+#. link text in an add-on's editor review history, allowing to hide and show an information request's replies
+#. %1 is the number of replies
+#: views/elements/developers/editors_review_history_item.thtml:90
+msgid "editors_review_history_show_hide_replies"
+msgid_plural "editors_review_history_show_hide_replies"
+msgstr[0] "Visa/göm svar (%1$s)"
+msgstr[1] "Visa/göm svar (%1$s)"
+
+#: views/editors/review.thtml:208
+msgid "editors_review_label_applications"
+msgstr "Applikationer:"
+
+#: views/editors/review.thtml:196
+msgid "editors_review_label_cannedresponse"
+msgstr "eller välj ett färdigt svar:"
+
+#: views/editors/review.thtml:190
+msgid "editors_review_label_comments"
+msgstr "Kommentarer:"
+
+#: views/editors/review.thtml:204
+msgid "editors_review_label_operating_systems"
+msgstr "Operativsystem:"
+
+#: views/editors/review.thtml:285 views/editors/review.thtml:312
+msgid "editors_review_link_pagetop"
+msgstr "Högst upp"
+
+#: views/editors/review.thtml:141
+msgid "editors_review_mulitple_notice"
+msgstr "Obs: Granska bara mer en än fil om du har testat VARJE fil du väljer."
+
+#: views/editors/review.thtml:51
+msgid "editors_review_next_link"
+msgstr "nästa &raquo;"
+
+#: views/editors/review.thtml:322
+msgid "editors_review_previews_notfound"
+msgstr "Inga förhandsivsningar funna."
+
+#: views/editors/review.thtml:50
+msgid "editors_review_previous_link"
+msgstr "&laquo; föregående"
+
+#: controllers/editors_controller.php:144
+#: controllers/editors_controller.php:146
+msgid "editors_review_queue_pagetitle"
+msgstr "Granskningskö"
+
+#. %1 is the add-ons rank in the queue, %2 is the total queue length
+#: views/editors/review.thtml:47
+msgid "editors_review_rank_in_queue"
+msgstr "<strong># %1$s</strong> av %2$s i kön"
+
+#. %1 is the add-ons rank in the queue, %2 is the total queue length. Both numbers
+#: views/editors/review.thtml:45
+msgid "editors_review_rank_in_queue_filtered"
+msgstr "<strong># %1$s</strong> av %2$s i kön (filtrerad)"
+
+#: views/editors/review.thtml:223
+msgid "editors_review_submit_process_action"
+msgstr "Utför"
+
+#: views/editors/review.thtml:293
+msgid "editors_review_th_action"
+msgstr "Handling"
+
+#: views/editors/review.thtml:294
+msgid "editors_review_th_comments"
+msgstr "Kommentarer"
+
+#: views/editors/review.thtml:291
+msgid "editors_review_th_date"
+msgstr "Datum"
+
+#: views/editors/review.thtml:292
+msgid "editors_review_th_reviewer"
+msgstr "Recensent"
+
+#: views/editors/review.thtml:290
+msgid "editors_review_th_version_file"
+msgstr "Version/Fil"
+
+#: views/editors/review.thtml:217
+msgid "editors_review_update_notify_once"
+msgstr ""
+"Underrätta mig nästa gång det här tillägget uppdateras (e-post skickas inte "
+"för därpå följande uppdateringar)"
+
+#: controllers/editors_controller.php:298
+msgid "editors_reviewed_successfully"
+msgstr "Recensionen hanterad."
+
+#: views/editors/reviews_queue.thtml:106
+msgid "editors_reviews_action_delete_review"
+msgstr "Ta bort recension"
+
+#: views/editors/reviews_queue.thtml:104
+msgid "editors_reviews_action_keep"
+msgstr "Ta bort flagga; behåll recension"
+
+#: views/editors/reviews_queue.thtml:102
+msgid "editors_reviews_action_skip"
+msgstr "Hoppa över"
+
+#: views/editors/reviews_queue.thtml:100
+msgid "editors_reviews_header_action"
+msgstr "Handling"
+
+#: views/editors/reviews_queue.thtml:67
+msgid "editors_reviews_in_reply_to"
+msgstr "Som svar till:"
+
+#: controllers/editors_controller.php:748
+msgid "editors_reviews_processed"
+msgstr "Recensioner hanterade!"
+
+#: views/editors/reviews_queue.thtml:117
+msgid "editors_reviews_queue_empty"
+msgstr "Det finns för närvarande inga recensioner att moderera."
+
+#: views/editors/reviews_queue.thtml:111
+msgid "editors_reviews_submit_process_reviews"
+msgstr "Hantera recensioner"
+
+#: controllers/editors_controller.php:691
+msgid "editors_site_specific"
+msgstr "Webbplatsspecifik"
+
+#: controllers/editors_controller.php:348
+msgid "editors_tested_app"
+msgstr "Testade applikationer"
+
+#: controllers/editors_controller.php:347
+msgid "editors_tested_os"
+msgstr "Testade operativsystem"
+
+#: views/editors/queue.thtml:151
+msgid "editors_th_additional_info"
+msgstr "Ytterligare information"
+
+#: views/editors/featured.thtml:63 views/editors/queue.thtml:109
+#: views/admin/flagged_queue.thtml:53
+msgid "editors_th_addon"
+msgstr "Tillägg"
+
+#: views/editors/queue.thtml:125
+msgid "editors_th_addontype"
+msgstr "Typ"
+
+#: views/editors/featured.thtml:64
+msgid "editors_th_locales"
+msgstr "Begränsa till lokaler?"
+
+#: views/editors/queue.thtml:148
+msgid "editors_th_nomination_age"
+msgstr "Tid i kön"
+
+#: views/editors/queue.thtml:101 views/editors/queue.thtml:117
+#: views/editors/queue.thtml:144
+msgid "editors_th_sort_ascending"
+msgstr "Stigande sortering"
+
+#: views/editors/queue.thtml:105 views/editors/queue.thtml:121
+#: views/editors/queue.thtml:140
+msgid "editors_th_sort_descending"
+msgstr "Fallande sortering"
+
+#. %s is a number
+#: controllers/editors_controller.php:1036
+#, php-format
+msgid "editors_x_days"
+msgstr "%s dagar"
+
+#. %s is a number
+#: controllers/editors_controller.php:1044
+#, php-format
+msgid "editors_x_hours"
+msgstr "%s timmar"
+
+#. %s is a number
+#: controllers/editors_controller.php:1052
+#, php-format
+msgid "editors_x_minutes"
+msgstr "%s minuter"
+
+#: views/errors/error401.thtml:50 controllers/components/simple_acl.php:81
+#: controllers/components/simple_acl.php:82
+#: controllers/components/simple_acl.php:83 controllers/components/amo.php:607
+#: controllers/components/amo.php:608 controllers/components/amo.php:609
+#: controllers/reviews_controller.php:353
+#: controllers/reviews_controller.php:485
+#: controllers/collections_controller.php:438
+#: controllers/collections_controller.php:496
+#: controllers/collections_controller.php:504
+#: controllers/collections_controller.php:971
+#: controllers/collections_controller.php:1034
+#: controllers/collections_controller.php:1077
+msgid "error_access_denied"
+msgstr "Ã…tkomst nekad"
+
+#: views/errors/error401.thtml:52
+msgid "error_access_denied_message"
+msgstr "Du har inte rättigheter att se denna sida."
+
+#: controllers/collections_controller.php:1039
+msgid "error_addon_exists"
+msgstr "Tillägget finns redan!"
+
+#: controllers/developers_controller.php:200
+#: controllers/developers_controller.php:593
+#: controllers/developers_controller.php:1016
+#: controllers/developers_controller.php:1429
+#: controllers/downloads_controller.php:95
+#: controllers/downloads_controller.php:102
+#: controllers/downloads_controller.php:164
+#: controllers/statistics_controller.php:135
+#: controllers/previews_controller.php:115
+#: controllers/previews_controller.php:206
+#: controllers/previews_controller.php:307
+#: controllers/reviews_controller.php:77
+#: controllers/reviews_controller.php:240
+#: controllers/reviews_controller.php:332
+#: controllers/reviews_controller.php:340 controllers/api_controller.php:123
+#: controllers/api_controller.php:759 controllers/addons_controller.php:131
+#: controllers/addons_controller.php:197
+#: controllers/addons_controller.php:1407
+#: controllers/addons_controller.php:1465
+#: controllers/addons_controller.php:1469
+#: controllers/addons_controller.php:1503
+#: controllers/editors_controller.php:265
+#: controllers/collections_controller.php:1041
+#: controllers/collections_controller.php:1074
+msgid "error_addon_notfound"
+msgstr "Tillägget hittades inte!"
+
+#: controllers/files_controller.php:83 controllers/files_controller.php:196
+msgid "error_addon_notviewable"
+msgstr "Detta tillägg är inte synligt här."
+
+#: controllers/reviews_controller.php:246
+msgid "error_addon_selfreview"
+msgstr "Du kan inte recensera ditt eget tillägg."
+
+#: controllers/addons_controller.php:970
+msgid "error_browse_no_addons"
+msgstr "Inga tillägg i denna kategori!"
+
+#: controllers/api_controller.php:424
+msgid "error_collection_feed_notfound"
+msgstr "Kanal för tillägg hittades inte."
+
+#: views/users/register.thtml:65 views/users/edit.thtml:194
+msgid "error_email_invalid"
+msgstr "Detta är inte en giltig e-postadress."
+
+#: views/users/pwreset.thtml:74 views/users/register.thtml:70
+#: views/users/register.thtml:80 views/users/register.thtml:86
+#: views/users/edit.thtml:105 views/users/edit.thtml:111
+#: views/users/edit.thtml:192 views/admin/users_edit.thtml:78
+#: views/admin/users_edit.thtml:83 views/reviews/add.thtml:80
+#: views/reviews/add.thtml:104
+msgid "error_field_required"
+msgstr "Detta fält får inte vara tomt."
+
+#: controllers/files_controller.php:75 controllers/files_controller.php:93
+#: controllers/files_controller.php:96 controllers/files_controller.php:163
+#: controllers/files_controller.php:176 controllers/files_controller.php:185
+#: controllers/files_controller.php:204 controllers/editors_controller.php:412
+msgid "error_file_notfound"
+msgstr "Filen hittades inte!"
+
+#. %s is a filename
+#: controllers/editors_controller.php:430
+#, php-format
+msgid "error_file_x_notfound"
+msgstr "Fel: filen %s finns inte."
+
+#: views/collections/add.thtml:55 views/collections/edit.thtml:89
+#: views/users/register.thtml:54 views/users/edit.thtml:81
+#: views/reviews/add.thtml:70 controllers/groups_controller.php:80
+#: controllers/groups_controller.php:102
+msgid "error_formerrors"
+msgstr "Det finns fel i formuläret. Rätta dem och skicka in igen."
+
+#: views/users/register.thtml:109
+msgid "error_invalid_captcha"
+msgstr "Felaktigt svar, försök igen!"
+
+#: views/users/register.thtml:100 views/users/edit.thtml:125
+#: views/admin/users_edit.thtml:101
+msgid "error_invalid_url"
+msgstr ""
+"URLen har ett ogiltigt format. Giltiga URLer ser ut som http://example.com/"
+"my_page."
+
+#. %s is a string representing what's missing. Example: file_id
+#: controllers/downloads_controller.php:65
+#: controllers/users_controller.php:185 controllers/users_controller.php:264
+#: controllers/users_controller.php:559 controllers/users_controller.php:653
+#: controllers/reviews_controller.php:71
+#: controllers/reviews_controller.php:234
+#: controllers/reviews_controller.php:325
+#: controllers/reviews_controller.php:473
+#: controllers/reviews_controller.php:475
+#: controllers/addons_controller.php:182
+#: controllers/addons_controller.php:1381
+#: controllers/addons_controller.php:1455
+#: controllers/collections_controller.php:266
+#: controllers/collections_controller.php:285
+#: controllers/collections_controller.php:346
+#: controllers/collections_controller.php:443
+#: controllers/collections_controller.php:482
+#: controllers/collections_controller.php:936
+#: controllers/collections_controller.php:959
+#: controllers/collections_controller.php:960
+#: controllers/collections_controller.php:975
+#: controllers/collections_controller.php:977
+#: controllers/collections_controller.php:994
+#: controllers/collections_controller.php:1003
+#: controllers/collections_controller.php:1016
+#: controllers/collections_controller.php:1017
+#: controllers/collections_controller.php:1024
+#: controllers/collections_controller.php:1070
+#: controllers/collections_controller.php:1090
+#, php-format
+msgid "error_missing_argument"
+msgstr "Saknat argument: %s"
+
+#: controllers/components/amo.php:507 controllers/components/amo.php:532
+msgid "error_no_files_in_addon"
+msgstr "Inga filer"
+
+#: controllers/previews_controller.php:200
+msgid "error_preview_notfound"
+msgstr "Förhandsvisning ej funnen!"
+
+#: views/addons/display.thtml:400 views/reviews/add.thtml:98
+msgid "error_review_rating_required"
+msgstr "Du måste välja ett betyg."
+
+#: controllers/users_controller.php:160
+msgid "error_user_already_confirmed"
+msgstr "Detta användarkonto har redan bekräftats."
+
+#: controllers/users_controller.php:202 controllers/users_controller.php:276
+#: controllers/users_controller.php:569 controllers/users_controller.php:581
+#: controllers/users_controller.php:587 controllers/users_controller.php:610
+#: controllers/users_controller.php:627
+msgid "error_user_badconfirmationcode"
+msgstr "Felaktig bekräftelsekod!"
+
+#: views/users/pwreset.thtml:79 views/users/register.thtml:75
+#: views/users/edit.thtml:183
+msgid "error_user_confirmpw_nomatch"
+msgstr "Lösenorden skiljde sig."
+
+#: views/users/register.thtml:65 views/users/edit.thtml:190
+#: controllers/users_controller.php:617
+msgid "error_user_email_notunique"
+msgstr "Denna e-postadress används redan av en annan användare."
+
+#: controllers/users_controller.php:596
+msgid "error_user_emailchange_expired"
+msgstr ""
+"E-poständringen har expirerat. Ändra din e-postadress i profilen igen och "
+"klicka på länken i bekräftelsebrevet direkt när du har fått det."
+
+#: controllers/collections_controller.php:985
+msgid "error_user_exists"
+msgstr ""
+"Användare kan bara ha en roll i tagit. Tabort användaren från existerande "
+"roller innan du fortsätter."
+
+#: views/users/register.thtml:91 views/users/edit.thtml:116
+#: views/admin/users_edit.thtml:88
+msgid "error_user_nickname_notunique"
+msgstr "Detta kortnamn är upptaget."
+
+#: views/users/pwreset.thtml:54 controllers/users_controller.php:191
+#: controllers/users_controller.php:270 controllers/users_controller.php:603
+#: controllers/users_controller.php:659
+#: controllers/collections_controller.php:988
+#: controllers/collections_controller.php:998
+msgid "error_user_notfound"
+msgstr "Användaren fanns inte!"
+
+#: views/users/activatefirst.thtml:47
+msgid "error_user_unconfirmed"
+msgstr "Bekräfta ditt konto med koden du fick via e-post först."
+
+#: views/users/login.thtml:67
+msgid "error_username_or_pw_wrong"
+msgstr "Fel användarnamn eller lösenord!"
+
+#: controllers/editors_controller.php:260
+msgid "error_version_notfound"
+msgstr "Versionen fanns inte!"
+
+#: views/users/delete.thtml:125 views/users/edit.thtml:173
+msgid "error_wrong_password"
+msgstr "Fel lösenord angett!"
+
+#: views/elements/amo2009/homepage_addon.thtml:122
+#: views/elements/feature.thtml:122
+msgid "feature_learnmore"
+msgstr "Läs mer"
+
+#. %1 is the add-on name
+#: views/elements/amo2009/homepage_addon.thtml:123
+#: views/elements/feature.thtml:123
+#, php-format
+msgid "feature_learnmore_about_addon"
+msgstr "Lär dig mer om %1$s"
+
+#. %1$s is a number
+#: views/elements/amo2009/reviews.thtml:52
+#: views/elements/addon_listitem.thtml:112 views/elements/feature.thtml:99
+#: views/addons/browse_thumbs.thtml:86
+#, php-format
+msgid "feature_reviews"
+msgid_plural "feature_reviews"
+msgstr[0] "%1$s recension"
+msgstr[1] "%1$s recensioner"
+
+#: views/elements/amo2009/homepage_addon.thtml:127
+#: views/elements/feature.thtml:127
+msgid "feature_view_more_from_category"
+msgstr "Se mer från"
+
+#. This appears on a page that views the source of an add-on. This link will return
+#. the user to the add-on's main page
+#: views/files/browse.thtml:65
+msgid "file_browser_link_addon"
+msgstr "Tillbaka till tillägg"
+
+#. There is a list of directories and files on the page. Clicking this will show the
+#. contents of all the directories (normally you would click on each one to see the
+#. contents)
+#: views/files/browse.thtml:67
+msgid "file_browser_link_expand_all"
+msgstr "Expandera alla"
+
+#. This appears on a page that views the source of an add-on. This link will return
+#. the user to the add-on's review page (it only appears if the add-on is being
+#. reviewed)
+#: views/files/browse.thtml:64
+msgid "file_browser_link_review"
+msgstr "Tillbaka till recension"
+
+#. The title of the page for viewing an add-on's source.
+#. %1$s is the name of the add-on
+#. %2$s is the name of the current application (e.g. Firefox or Thunderbird)
+#: views/files/browse.thtml:46
+msgid "file_browser_title"
+msgstr "%1$s :: Filbläddrare :: %2$s Tillägg"
+
+#. This appears on a page that views the source of an add-on. There is a list of
+#. directories and files on the page. Clicking this link will toggle between an
+#. expanded or a collapsed list. This string should be kept short.
+#: views/files/browse.thtml:68
+msgid "file_browser_toggle_expand_collapse"
+msgstr "+/-"
+
+#. Link text for the AMO About page.
+#: views/elements/footer.thtml:72 views/layouts/amo2009.thtml:341
+msgid "footer_a_about"
+msgstr "Om"
+
+#. Link text to the AMO blog.
+#: views/elements/footer.thtml:74 views/layouts/amo2009.thtml:343
+msgid "footer_a_blog"
+msgstr "Blog"
+
+#. Link text to the Frequently Asked Questions page.
+#: views/elements/footer.thtml:73 views/layouts/amo2009.thtml:342
+msgid "footer_a_faq"
+msgstr "FAQ"
+
+#. Full text for the FAQ abbreviation.
+#: views/elements/footer.thtml:73 views/pages/collector_features.thtml:72
+#: views/layouts/amo2009.thtml:342
+msgid "footer_abbr_faq"
+msgstr "Ofta ställda frågor"
+
+#: views/elements/footer.thtml:67 views/layouts/amo2009.thtml:336
+msgid "footer_all_rights_reserved"
+msgstr "Alla rättigheter reserverade."
+
+#: views/elements/footer.thtml:67 views/layouts/amo2009.thtml:336
+msgid "footer_copyright"
+msgstr "Upphovsrättsskyddad"
+
+#: views/elements/footer.thtml:71 views/layouts/amo2009.thtml:340
+msgid "footer_credits"
+msgstr "De som bidragit"
+
+#: views/elements/footer.thtml:76 views/layouts/amo2009.thtml:346
+msgid "footer_disclaimer"
+msgstr ""
+"Mozilla bistår med länkar till dessa applikationer av välvilja och kan inte "
+"ta något ansvar för applikationerna eller någon information rörande dem. "
+"Alla frågor, klagomål eller krav rörande applikationerna måste riktas till "
+"utgivaren av applikationen."
+
+#: views/elements/footer.thtml:61 views/layouts/amo2009.thtml:332
+msgid "footer_lang_form_lang_submit_go"
+msgstr "Utför"
+
+#: views/elements/footer.thtml:70 views/layouts/amo2009.thtml:339
+msgid "footer_legal_notices"
+msgstr "Rättighetsinformation"
+
+#: views/elements/footer.thtml:50 views/layouts/amo2009.thtml:321
+msgid "footer_other_languages"
+msgstr "Andra språk:"
+
+#: views/elements/footer.thtml:69 views/layouts/amo2009.thtml:338
+msgid "footer_privacy_policy"
+msgstr "Integritetsriktlinjer"
+
+#: models/addontype.php:79
+msgid "general_addontype_dict"
+msgstr "Ordlista"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:100
+msgid "general_addontype_dict_plural"
+msgstr "Ordlistor"
+
+#: models/addontype.php:75
+msgid "general_addontype_extension"
+msgstr "Utökning"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:98
+msgid "general_addontype_extension_plural"
+msgstr "Utökningar"
+
+#: models/addontype.php:85
+msgid "general_addontype_lpaddon"
+msgstr "Språkpaket (Tillägg)"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:103
+msgid "general_addontype_lpaddon_plural"
+msgstr "Språkpaket (Tillägg)"
+
+#: models/addontype.php:83
+msgid "general_addontype_lpapp"
+msgstr "Språkpaket (Applikation)"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:102
+msgid "general_addontype_lpapp_plural"
+msgstr "Språkpaket (Applikation)"
+
+#: models/addontype.php:87
+msgid "general_addontype_plugin"
+msgstr "Insticksprogram"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:104
+msgid "general_addontype_plugin_plural"
+msgstr "Insticksprogram"
+
+#: models/addontype.php:81
+msgid "general_addontype_search"
+msgstr "Sökmotor"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:101
+msgid "general_addontype_search_plural"
+msgstr "Sökmotorer"
+
+#: models/addontype.php:77
+msgid "general_addontype_theme"
+msgstr "Tema"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:99
+msgid "general_addontype_theme_plural"
+msgstr "Teman"
+
+#: config/language.php:367
+msgid "general_languages_all_locales"
+msgstr "Alla lokaler"
+
+#: views/layouts/amo2009.thtml:249
+msgid "header_brand_name"
+msgstr "Mozilla"
+
+#. %1$s is the application name. Example: Firefox
+#: views/elements/header.thtml:111 views/elements/header.thtml:122
+#: views/layouts/amo2009.thtml:248
+#, php-format
+msgid "header_home_tooltip"
+msgstr "tillbaka till %1$s tilläggshemsida"
+
+#: views/elements/header.thtml:87
+msgid "header_main_firefox_header"
+msgstr "Firefox-tillägg"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:218
+#, fuzzy
+msgid "header_main_firefox_header_with_logo"
+msgstr ""
+"Add-ons <em>for</em> <img alt=\"Firefox\" src=\"%1$s\" /> <strong>Firefox</"
+"strong>"
+
+#: views/elements/header.thtml:99
+msgid "header_main_header"
+msgstr "Tillägg"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:242
+#, fuzzy
+msgid "header_main_header_with_logo"
+msgstr "Add-ons <img alt=\"Add-ons\" src=\"%1$s\" />"
+
+#: views/elements/header.thtml:90
+msgid "header_main_seamonkey_header"
+msgstr "Seamonkey-tillägg"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:224
+#, fuzzy
+msgid "header_main_seamonkey_header_with_logo"
+msgstr ""
+"Add-ons <em>for</em> <img alt=\"seamonkey\" src=\"%1$s\" /> "
+"<strong>SeaMonkey</strong>"
+
+#: views/elements/header.thtml:93
+msgid "header_main_sunbird_header"
+msgstr "Sunbird-tillägg"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:230
+#, fuzzy
+msgid "header_main_sunbird_header_with_logo"
+msgstr ""
+"Add-ons <em>for</em> <img alt=\"sunbird\" src=\"%1$s\" /> <strong>Sunbird</"
+"strong>"
+
+#: views/elements/header.thtml:96
+msgid "header_main_thunderbird_header"
+msgstr "Thunderbird-tillägg"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:236
+#, fuzzy
+msgid "header_main_thunderbird_header_with_logo"
+msgstr ""
+"Add-ons <em>for</em> <img alt=\"thunderbird\" src=\"%1$s\" /> "
+"<strong>Thunderbird</strong>"
+
+#: views/layouts/amo2009.thtml:205
+msgid "header_navaccess_applications_menu"
+msgstr "Hoppa till menyn för andra applikationer"
+
+#: views/layouts/amo2009.thtml:204
+msgid "header_navaccess_categories_menu"
+msgstr "Hoppa till menyn för kategorier"
+
+#: views/layouts/amo2009.thtml:202
+msgid "header_navaccess_main_content"
+msgstr "Hoppa till huvudinnehållet"
+
+#: views/layouts/amo2009.thtml:203
+msgid "header_navaccess_search_form"
+msgstr "Hoppa till sökformuläret"
+
+#: views/elements/header.thtml:62
+msgid "header_navlink_addons"
+msgstr "Tillägg"
+
+#: views/elements/developers/sidebar.thtml:72
+#: views/elements/developers/myaddons.thtml:50 views/elements/header.thtml:159
+#: views/addons/display.thtml:378
+msgid "header_navlink_login"
+msgstr "Logga in"
+
+#: views/elements/header.thtml:156 views/layouts/amo2009.thtml:304
+msgid "header_navlink_logout"
+msgstr "Logga ut"
+
+#: views/elements/header.thtml:145 views/layouts/amo2009.thtml:303
+msgid "header_navlink_myaccount"
+msgstr "Mitt konto"
+
+#: views/elements/header.thtml:158
+msgid "header_navlink_register"
+msgstr "Registrera dig"
+
+#. %1 is the URL to the registration page
+#. %2 is the URL to the login page
+#: views/layouts/amo2009.thtml:278
+msgid "header_navlink_register_or_login"
+msgstr ""
+"<a href=\"%1$s\">Registrera dig</a> eller <a href=\"%2$s\">Logga in</a>"
+
+#: views/layouts/amo2009.thtml:285
+msgid "header_navlink_tools"
+msgstr "Verktyg"
+
+#. %s is the add-on name
+#: views/elements/collections_interactive_addon.thtml:62
+#: views/elements/amo2009/homepage_addon.thtml:77
+#: views/elements/addon_discussionheader.thtml:62
+#: views/elements/addon_listitem.thtml:67 views/elements/feature.thtml:84
+#: views/addons/category_landing.thtml:87 views/addons/browse_thumbs.thtml:60
+#, php-format
+msgid "img_preview_of"
+msgstr "Förhandsvisningsbild av %s"
+
+#. %1 is the login URL for the link tag
+#. %2 is the link to an explanatory page.
+#: views/elements/amo2009/install.thtml:307 views/elements/install.thtml:255
+msgid "install_a_login_to_install"
+msgstr "<a href=\"%1$s\">Logga in</a> för att installera detta tillägg"
+
+#. %1 is the URL for the Experimental Add-ons section of the FAQ page
+#: views/elements/amo2009/install.thtml:283 views/elements/install.thtml:232
+msgid "install_button_confirm_exp_install"
+msgstr ""
+"Låt mig installera detta experimentella tillägg. <a href=\"%1$s\">Vad är "
+"detta?</a>"
+
+#. %1$s is the application name. Example: Firefox
+#. %2$s is an optional string used to specify a platform. Example: (Windows)
+#: views/elements/amo2009/install.thtml:128 views/elements/install.thtml:75
+#, php-format
+msgid "install_button_text"
+msgstr "Lägg till %s %s"
+
+#. %1 is the add-on name, %2 is the app name
+#: views/elements/amo2009/install.thtml:191
+#: views/elements/amo2009/install.thtml:206
+#: views/elements/amo2009/install.thtml:249
+#: views/elements/amo2009/install.thtml:298 views/elements/install.thtml:150
+#: views/elements/install.thtml:165 views/elements/install.thtml:202
+#: views/elements/install.thtml:246
+#, php-format
+msgid "install_button_title"
+msgstr "Lägg till %1$s till %2$s"
+
+#. %1$s is the add-on name
+#: views/elements/amo2009/install.thtml:200 views/elements/install.thtml:159
+#, php-format
+msgid "install_download"
+msgstr "Hämta hem %1$s"
+
+#: views/elements/amo2009/install.thtml:147 views/elements/install.thtml:94
+msgid "install_error_addon_not_found"
+msgstr "Detta tillägg är inte tillgängligt."
+
+#: views/addons/dictionaries.thtml:65
+msgid "langtools_a11y_tablesummary"
+msgstr "Lista på språkpaket och ordböcker."
+
+#: views/addons/dictionaries.thtml:47
+msgid "langtools_download_dictionary"
+msgstr "Hämta hem ordlista"
+
+#: views/addons/dictionaries.thtml:48
+msgid "langtools_download_langpack"
+msgstr "Hämta hem språkpaket"
+
+#: views/addons/dictionaries.thtml:63 controllers/components/amo.php:685
+#: controllers/addons_controller.php:1239
+msgid "langtools_header_dicts_and_langpacks"
+msgstr "Ordlistor & språkpaket"
+
+#: views/addons/dictionaries.thtml:44
+msgid "langtools_install_dictionary"
+msgstr "Installera ordlista"
+
+#: views/addons/dictionaries.thtml:45
+msgid "langtools_install_langpack"
+msgstr "Installera språkpaket"
+
+#: views/addons/dictionaries.thtml:69
+msgid "langtools_tableheader_dictionary"
+msgstr "Ordlista"
+
+#: views/addons/dictionaries.thtml:70
+msgid "langtools_tableheader_langpack"
+msgstr "Språkpaket"
+
+#: views/addons/dictionaries.thtml:68
+msgid "langtools_tableheader_language"
+msgstr "Språk"
+
+#: models/license.php:65
+msgid "license_custom"
+msgstr "Anpassad licens"
+
+#: config/bootstrap.php:303
+msgid "licenses_bsd"
+msgstr "BSD-licens"
+
+#: config/bootstrap.php:298
+msgid "licenses_gpl_2.0"
+msgstr "GNU General Public License, version 2.0"
+
+#: config/bootstrap.php:299
+msgid "licenses_gpl_3.0"
+msgstr "GNU General Public License, version 3.0"
+
+#: config/bootstrap.php:300
+msgid "licenses_lgpl_2.1"
+msgstr "GNU Lesser General Public License, version 2.1"
+
+#: config/bootstrap.php:301
+msgid "licenses_lgpl_3.0"
+msgstr "GNU Lesser General Public License, version 3.0"
+
+#: config/bootstrap.php:302
+msgid "licenses_mit"
+msgstr "MIT/X11-licens"
+
+#: config/bootstrap.php:297
+msgid "licenses_mpl_1.1"
+msgstr "Mozilla Public License, version 1.1"
+
+#: views/users/emailchange.thtml:51 views/users/delete.thtml:55
+#: views/users/delete.thtml:137 views/users/edit.thtml:74
+#: views/reviews/flag.thtml:54
+msgid "link_return_to_front_page"
+msgstr "Klicka här för att komma tillbaka till förstasidan."
+
+#: views/elements/amo2009/addon_list_options.thtml:46
+#: views/elements/addon_list_options.thtml:46
+msgid "list_sortby_date"
+msgstr "Datum"
+
+#: views/elements/amo2009/addon_list_options.thtml:47
+#: views/elements/addon_list_options.thtml:47
+msgid "list_sortby_downloads"
+msgstr "Hämtningar"
+
+#: views/elements/amo2009/addon_list_options.thtml:45
+#: views/elements/addon_list_options.thtml:45
+msgid "list_sortby_name"
+msgstr "Tilläggets namn"
+
+#: views/elements/amo2009/addon_list_options.thtml:48
+#: views/elements/addon_list_options.thtml:48
+msgid "list_sortby_rating"
+msgstr "Betyg"
+
+#: config/bootstrap.php:278
+msgid "main_prettyname_fennec"
+msgstr "Fennec"
+
+#: config/bootstrap.php:274
+msgid "main_prettyname_firefox"
+msgstr "Firefox"
+
+#: config/bootstrap.php:277
+msgid "main_prettyname_seamonkey"
+msgstr "SeaMonkey"
+
+#: config/bootstrap.php:276
+msgid "main_prettyname_sunbird"
+msgstr "Sunbird"
+
+#: config/bootstrap.php:275
+msgid "main_prettyname_thunderbird"
+msgstr "Thunderbird"
+
+#: views/elements/addon_categories.thtml:52
+msgid "nav_category_dicts_langpacks"
+msgstr "Ordlistor och språkpaket"
+
+#: views/elements/addon_categories.thtml:55
+msgid "nav_category_themes"
+msgstr "Teman"
+
+#: views/elements/app_chooser.thtml:47 views/layouts/amo2009.thtml:255
+msgid "other_apps_tooltip"
+msgstr "Hitta tillägg för andra applikationer"
+
+#. In a user list: user 1, user 2, "others"
+#: views/helpers/addons_html.php:222
+msgid "other_users"
+msgstr "andra"
+
+#: controllers/pages_controller.php:90
+msgid "page_title_appversions"
+msgstr "Applikationsversioner"
+
+#: controllers/pages_controller.php:115
+msgid "page_title_collector"
+msgstr "Tillägssamlaren"
+
+#: controllers/pages_controller.php:117
+msgid "page_title_collector_faq"
+msgstr "Tillägssamlaren FAQ"
+
+#: controllers/pages_controller.php:119
+msgid "page_title_collector_features"
+msgstr "Tillägssamlaren finesser"
+
+#: controllers/pages_controller.php:122
+#, fuzzy
+msgid "page_title_collector_firstrun"
+msgstr "Welcome to the Add-on Collector"
+
+#: controllers/pages_controller.php:92
+msgid "page_title_credits"
+msgstr "De som bidragit"
+
+#: controllers/pages_controller.php:113
+msgid "page_title_developer_faq"
+msgstr "Utvecklar FAQ"
+
+#: controllers/pages_controller.php:111
+msgid "page_title_faq"
+msgstr "Ofta ställda frågor"
+
+#: controllers/pages_controller.php:94
+msgid "page_title_fashionyourfirefox_faq"
+msgstr "Vanliga frågor om Fashion your Firefox"
+
+#: controllers/pages_controller.php:101
+msgid "page_title_policy"
+msgstr "Add-ons-riktlinjer"
+
+#: controllers/pages_controller.php:103
+msgid "page_title_privacy"
+msgstr "Mozillas integritetsriktlinjer"
+
+#: controllers/pages_controller.php:105
+msgid "page_title_review_guide"
+msgstr "Recensionsriktlinjer"
+
+#: controllers/pages_controller.php:107
+msgid "page_title_sandbox"
+msgstr "Sandlåderecensionssystemet"
+
+#: controllers/pages_controller.php:109
+msgid "page_title_submissionhelp"
+msgstr "Hjälp med inskickning"
+
+#: views/pages/appversions.thtml:87
+msgid "pages_appversions_guid"
+msgstr "GUID"
+
+#: views/pages/appversions.thtml:79 controllers/pages_controller.php:90
+msgid "pages_appversions_header"
+msgstr "Giltiga applikationsversioner"
+
+#: views/pages/appversions.thtml:80
+msgid "pages_appversions_intro"
+msgstr ""
+"Tillägg som skickas in till Mozilla Add-ons måste ha en install.rdf-fil där "
+"minst en av följande applikationer stöds. Bara versionerna nedan är tillåtna "
+"för dessa applikationer."
+
+#. %s is a full <a> tag
+#: views/pages/appversions.thtml:93
+#, php-format
+msgid "pages_appversions_required_files"
+msgstr ""
+"Även om applikationen du stöder inte kräver en install.rdf-fil måste du ändå "
+"inkludera en med de egenskaper som specificeras %s."
+
+#. this is the text inside of an <a> tag for pages_appversions_required_files. This
+#. should be fixed.
+#: views/pages/appversions.thtml:93
+msgid "pages_appversions_required_files_link"
+msgstr "här"
+
+#: views/pages/appversions.thtml:88
+msgid "pages_appversions_versions"
+msgstr "Versioner"
+
+#: views/pages/policy.thtml:51
+msgid "pages_policy_sandbox_link"
+msgstr "Informationssida för sandlådan"
+
+#: views/elements/pagination.thtml:53
+msgid "pagination_next_page"
+msgstr "nästa"
+
+#: views/elements/pagination.thtml:52
+msgid "pagination_previous_page"
+msgstr "föregående"
+
+#: views/elements/recaptcha.thtml:65
+msgid "recaptcha_enter_both_words"
+msgstr ""
+"Skriv in <strong>båda orden</strong> nedanför, <strong>med ett mellanslag "
+"mellan</strong>."
+
+#: views/elements/recaptcha.thtml:83
+msgid "recaptcha_enter_here"
+msgstr "Skriv svaret här:"
+
+#: views/elements/recaptcha.thtml:74
+msgid "recaptcha_enter_whatyouhear"
+msgstr "Skriv vad du hör."
+
+#. %1 is the link switching refreshing the captcha
+#. %2 is the link switching to a text captcha
+#: views/elements/recaptcha.thtml:77
+msgid "recaptcha_hardtohear_text"
+msgstr ""
+"Om detta är svårt att första kan du <a href=\"%1$s\">lyssna till något "
+"annat</a> eller <a href=\"%2$s\">byta tillbaka till text</a>."
+
+#. %1 is the link switching refreshing the captcha
+#. %2 is the link switching to an audio captcha
+#: views/elements/recaptcha.thtml:68
+msgid "recaptcha_hardtoread_text"
+msgstr ""
+"Om detta är svårt att läsa kan du <a href=\"%1$s\">testa andra ord</a> eller "
+"<a href=\"%2$s\">lyssna på något</a> istället."
+
+#: views/users/register.thtml:105
+msgid "recaptcha_label"
+msgstr "Är du en människa?"
+
+#: views/users/register.thtml:106
+msgid "recaptcha_whatsthis"
+msgstr "Vad är detta?"
+
+#: controllers/reviews_controller.php:559
+msgid "review_flag_error"
+msgstr "Ett fel uppstod vid märkning av recensionen!"
+
+#: models/reviews_moderation_flag.php:69
+msgid "review_flag_reason_bug_support"
+msgstr "Felrapport eller begäran om hjälp på fel ställe"
+
+#: views/reviews/display.thtml:103 views/reviews/display.thtml:186
+msgid "review_flag_reason_instructions"
+msgstr "Rapportera den här recensionen (välj orsak)"
+
+#: models/reviews_moderation_flag.php:67
+msgid "review_flag_reason_language"
+msgstr "Opassande språk/innehåll"
+
+#: models/reviews_moderation_flag.php:71
+msgid "review_flag_reason_other"
+msgstr "Annan (var god ange)"
+
+#: models/reviews_moderation_flag.php:65
+msgid "review_flag_reason_spam"
+msgstr "Skräpkommentar eller annat icke recensionsartat innehåll"
+
+#: views/reviews/display.thtml:91 views/reviews/display.thtml:175
+#: controllers/reviews_controller.php:555
+msgid "review_flag_success"
+msgstr "Tack; recensionen har märkts för redaktörsgranskning."
+
+#: views/reviews/display.thtml:41
+msgid "review_flag_this"
+msgstr "Rapportera recensionen"
+
+#: views/reviews/display.thtml:42
+msgid "review_flag_this_titletip"
+msgstr ""
+"Är denna recension opassande, inkorrekt eller skräp? Klicka här för att "
+"märka den för redaktörsgranskning."
+
+#. %1 is the URL of the support section, %2 for the review guidelines
+#: views/reviews/add.thtml:53
+msgid "review_guidelines_short"
+msgstr ""
+"<p>Tänk på följande tips:</p><ul><li>Skriv som om du berättar för en vän om "
+"hur du upplevt tillägget. Ge specifika och hjälpfulla detaljer, som vilka "
+"finesser du gillade eller ogillade, hur lättanvänt det är och alla "
+"eventuella nackdelar det har. Undvik allmänna ordalag som att skriva att det "
+"är toppen \"toppen\" eller \"dåligt\" om du inte berättar varför du tycker "
+"så.</li><li>Snälla, skriv inte felrapporter i recensioner. Vi ger inte din e-"
+"postadress till tilläggsutvecklare och de kan behöva kontakta dig för att "
+"hjälpa dig lösa ditt problem. Se <a href=\"%1$s\">hjälpavsnittet</a> för att "
+"se var du kan få hjälp med detta tillägg.</li><li>Håll recensionerna "
+"trevliga, använd inte ovårdat språk och skriv ingen personlig information</"
+"li></ul><p>Var god läs <a href=\"%2$s\">recensionsriktlinjerna</a> för mer "
+"information om användares tilläggsrecensioner.</p>"
+
+#. %1 is the add-on name
+#: views/reviews/flag.thtml:56 views/reviews/display.thtml:55
+#: views/reviews/review_added.thtml:50
+#, php-format
+msgid "reviews_header"
+msgstr "Recensioner för %s"
+
+#: controllers/addons_controller.php:435
+msgid "rss_featuredaddons"
+msgstr "Uppmärksammade tillägg"
+
+#: controllers/addons_controller.php:432
+msgid "rss_newestaddons"
+msgstr "Nyaste tilläggen"
+
+#: controllers/addons_controller.php:434
+msgid "rss_popularaddons"
+msgstr "Populära tillägg"
+
+#: controllers/addons_controller.php:433
+msgid "rss_updatedaddons"
+msgstr "Uppdaterade tillägg"
+
+#: views/elements/search_mini.thtml:70
+msgid "search"
+msgstr "Sök"
+
+#: views/search/collections.thtml:51
+#, fuzzy
+msgid "search_collections_header"
+msgstr "Collection Search Results"
+
+#: controllers/search_controller.php:297
+#, fuzzy
+msgid "search_collections_pagetitle"
+msgstr "Collection Search Results"
+
+#: controllers/search_controller.php:99
+msgid "search_disabled"
+msgstr "Sökfunktion är avstängd för närvarande. Försök igen senare."
+
+#: views/elements/amo2009/search.thtml:188 views/elements/search.thtml:187
+#: views/elements/search_mini.thtml:54
+msgid "search_form_all_addons"
+msgstr "alla tillägg"
+
+#. This string is in the main category dropdown when searching
+#: views/elements/amo2009/search.thtml:204
+#, fuzzy
+msgid "search_form_all_collections"
+msgstr "all collections"
+
+#: views/elements/amo2009/search.thtml:184
+#: views/elements/amo2009/search.thtml:385
+#: views/elements/amo2009/search.thtml:408 views/elements/search.thtml:171
+#: views/elements/search.thtml:183 views/elements/search_mini.thtml:43
+#: views/elements/search_mini.thtml:49 views/layouts/mozilla.thtml:188
+msgid "search_form_default_text"
+msgstr "sök efter tillägg"
+
+#: views/elements/amo2009/search.thtml:184
+#: views/elements/amo2009/search.thtml:404
+#, fuzzy
+msgid "search_form_default_text_collections"
+msgstr "search for collections"
+
+#: views/elements/amo2009/search.thtml:206 views/elements/search.thtml:202
+msgid "search_form_submit_tooltip"
+msgstr "Sök efter tillägg"
+
+#: views/elements/amo2009/search.thtml:184 views/elements/search.thtml:183
+#: views/elements/search_mini.thtml:49
+msgid "search_form_tooltip"
+msgstr "Klicka för att ange söktermer"
+
+#: views/elements/amo2009/search.thtml:186 views/elements/search.thtml:185
+#: views/elements/search_mini.thtml:52
+msgid "search_form_within"
+msgstr "inom"
+
+#: views/addons/searchengines.thtml:118
+msgid "search_landing_all_search_engines"
+msgstr "Alla sökmotorer"
+
+#: views/addons/searchengines.thtml:114
+msgid "search_landing_browse_search_engines"
+msgstr "Bläddra bland sökmotorer"
+
+#: views/search/collections.thtml:58 views/search/index.thtml:59
+msgid "search_nothing_found"
+msgstr "Inga resultat funna."
+
+#: controllers/search_controller.php:185
+msgid "search_pagetitle"
+msgstr "Sök tillägg"
+
+#: controllers/search_controller.php:242
+msgid "search_rss_description"
+msgstr "Kanal för sökresultat"
+
+#. %s is the terms the user is searching for (a string)
+#: controllers/search_controller.php:241
+#, php-format
+msgid "search_rss_results_for"
+msgstr "Sökresultat för: %s"
+
+#: views/elements/header.thtml:154 views/layouts/amo2009.thtml:296
+msgid "sidebar_navlink_admin_tools"
+msgstr "Adminverktyg"
+
+#: views/elements/header.thtml:146 views/layouts/amo2009.thtml:288
+msgid "sidebar_navlink_developer_tools"
+msgstr "Utvecklarverktyg"
+
+#: views/elements/header.thtml:148 views/layouts/amo2009.thtml:290
+msgid "sidebar_navlink_editor_tools"
+msgstr "Redigerarverktyg"
+
+#: views/layouts/amo2009.thtml:302
+msgid "sidebar_navlink_welcome"
+msgstr "Välkommen"
+
+#. %s is the user's name
+#: views/layouts/amo2009.thtml:302
+#, php-format
+msgid "sidebar_navlink_welcome_name"
+msgstr "Välkommen, %s"
+
+#: views/elements/pitch.thtml:50 views/elements/pitch.thtml:55
+msgid "sidebar_pitch_dictionary"
+msgstr "Ordlista"
+
+#: views/elements/pitch.thtml:72
+msgid "sidebar_pitch_featured_addons"
+msgstr "Uppmärksammade tillägg"
+
+#: views/elements/pitch.thtml:61
+msgid "sidebar_pitch_looking_for"
+msgstr "Jag letar efter:"
+
+#: views/elements/pitch.thtml:70
+msgid "sidebar_pitch_newest_addons"
+msgstr "Senaste tilläggen"
+
+#: views/elements/pitch.thtml:49
+msgid "sidebar_pitch_search"
+msgstr "Sökmotor"
+
+#: views/elements/pitch.thtml:69
+msgid "sidebar_pitch_subscribe_to"
+msgstr "Prenumerera på"
+
+#: views/elements/pitch.thtml:48 views/elements/pitch.thtml:54
+msgid "sidebar_pitch_theme"
+msgstr "Tema"
+
+#: views/elements/pitch.thtml:71
+msgid "sidebar_pitch_updated_addons"
+msgstr "Uppdaterade tillägg"
+
+#. %1$s is a number
+#: views/helpers/localization.php:65 views/developers/versions_edit.thtml:95
+#: views/addons/dictionaries.thtml:92
+#, php-format
+msgid "size_kb"
+msgstr "%1$s KB"
+
+#: views/elements/amo2009/stars.thtml:57 views/elements/stars.thtml:63
+msgid "stars_not_yet_rated"
+msgstr "Inte betygsatt än"
+
+#. %1 is the number of stars this add-on has
+#: views/elements/amo2009/stars.thtml:49 views/elements/stars.thtml:54
+#, php-format
+msgid "stars_rated_x_outof_5"
+msgstr "Fått %s av 5 stjärnor i betyg"
+
+#: views/statistics/addon.thtml:59
+msgid "statistics_addon_dashboard_link"
+msgstr "Statistikpanelens hem"
+
+#: views/statistics/addon.thtml:58
+msgid "statistics_addon_developertools_link"
+msgstr "Utvecklarverktyg"
+
+#: views/statistics/addon.thtml:53
+msgid "statistics_addon_switch"
+msgstr "Byt tillägg"
+
+#. This is a date format.
+#. http://php.net/strftime
+#: views/statistics/rss/summary.thtml:54 views/statistics/addon.thtml:181
+msgid "statistics_date_shortmonth"
+msgstr "%b. %e"
+
+#. This is a date format.
+#. http://php.net/strftime
+#: views/statistics/rss/summary.thtml:40 views/statistics/addon.thtml:152
+msgid "statistics_date_shortmonthwithyear"
+msgstr "%b. %e, %Y"
+
+#. This is a date format.
+#. http://php.net/strftime
+#: views/statistics/rss/summary.thtml:41 views/statistics/rss/summary.thtml:48
+#: views/statistics/addon.thtml:161 views/statistics/addon.thtml:172
+msgid "statistics_date_weekdayshortmonth"
+msgstr "%A, %b. %e"
+
+#. %1$s is an add-on name and version. Example: Add-on 3.5
+#: controllers/components/stats.php:519
+#, php-format
+msgid "statistics_events_addon_created"
+msgstr "%1$s skapad"
+
+#. %1$s is an application name and version. Example: Firefox 3.5
+#: controllers/components/stats.php:500
+#, php-format
+msgid "statistics_events_app_released"
+msgstr "%1$s släpptes"
+
+#: views/statistics/addon.thtml:71
+msgid "statistics_help_close_link"
+msgstr "Stäng"
+
+#: views/statistics/addon.thtml:60
+msgid "statistics_help_link"
+msgstr "Hjälp"
+
+#: views/statistics/index.thtml:83
+msgid "statistics_index_anotheraddon"
+msgstr "eller, välj ett annat tillägg"
+
+#: views/statistics/index.thtml:85
+msgid "statistics_index_anotheraddon_public"
+msgstr "eller, välj ett tillägg med publik statistik"
+
+#: views/statistics/index.thtml:71
+msgid "statistics_index_myaddons"
+msgstr "Välj ett av dina tillägg för att se dess statistik"
+
+#: views/statistics/index.thtml:89
+msgid "statistics_index_selectaddon"
+msgstr "Välj ett tillägg för att se dess statistik"
+
+#: views/statistics/index.thtml:91
+msgid "statistics_index_selectaddon_public"
+msgstr "Välj ett tillägg med publik statistik"
+
+#: views/statistics/index.thtml:39
+msgid "statistics_index_title"
+msgstr "Statistikpanelen"
+
+#: views/statistics/index.thtml:97
+msgid "statistics_index_view_button"
+msgstr "Visa statistik"
+
+#: views/statistics/addon.thtml:222 controllers/statistics_controller.php:247
+msgid "statistics_js_download_csv"
+msgstr "Visa denna tabell i CSV-format"
+
+#: controllers/statistics_controller.php:246
+msgid "statistics_js_dropdowns_none"
+msgstr "inga"
+
+#: controllers/statistics_controller.php:245
+msgid "statistics_js_dropdowns_removeplot"
+msgstr "Ta bort denna kurva"
+
+#: controllers/statistics_controller.php:248
+msgid "statistics_js_groupby_selector_date"
+msgstr "Gruppera på: Dag"
+
+#: controllers/statistics_controller.php:251
+msgid "statistics_js_groupby_selector_month"
+msgstr "Gruppera på: Månad"
+
+#: controllers/statistics_controller.php:249
+msgid "statistics_js_groupby_selector_week"
+msgstr "Gruppera på: Vecka"
+
+#: controllers/statistics_controller.php:250
+msgid "statistics_js_groupby_selector_week_over_week"
+msgstr "Jämför på: Vecka"
+
+#: controllers/statistics_controller.php:260
+msgid "statistics_js_plotselection_foundinrange"
+msgstr "%s fanns i området"
+
+#: controllers/statistics_controller.php:270
+msgid "statistics_js_plotselection_options_addplot_name"
+msgstr "Lägg till kurva"
+
+#: controllers/statistics_controller.php:271
+msgid "statistics_js_plotselection_options_addplot_tooltip"
+msgstr "Lägg till en kurva till denna graf"
+
+#: controllers/statistics_controller.php:261
+msgid "statistics_js_plotselection_options_count_name_checked"
+msgstr "Göm totalräknare"
+
+#: controllers/statistics_controller.php:262
+msgid "statistics_js_plotselection_options_count_name_unchecked"
+msgstr "Visa totalräknare"
+
+#: controllers/statistics_controller.php:263
+msgid "statistics_js_plotselection_options_count_tooltip"
+msgstr "Visa totalräknaren i denna graf"
+
+#: controllers/statistics_controller.php:275
+msgid "statistics_js_plotselection_options_csv_name"
+msgstr "Visa data (CSV)"
+
+#: controllers/statistics_controller.php:276
+msgid "statistics_js_plotselection_options_csv_tooltip"
+msgstr "FÃ¥ en CSV-fil med dessa data"
+
+#: controllers/statistics_controller.php:267
+msgid "statistics_js_plotselection_options_events_addon_name_checked"
+msgstr "Göm %s-händelser"
+
+#: controllers/statistics_controller.php:268
+msgid "statistics_js_plotselection_options_events_addon_name_unchecked"
+msgstr "Visa %s-händelser"
+
+#: controllers/statistics_controller.php:269
+msgid "statistics_js_plotselection_options_events_addon_tooltip"
+msgstr "Visa datum för tilläggssläpp ovanpå plottarna"
+
+#: controllers/statistics_controller.php:264
+msgid "statistics_js_plotselection_options_events_firefox_name_checked"
+msgstr "Göm Firefox-händelser"
+
+#: controllers/statistics_controller.php:265
+msgid "statistics_js_plotselection_options_events_firefox_name_unchecked"
+msgstr "Visa Firefox-händelser"
+
+#: controllers/statistics_controller.php:266
+msgid "statistics_js_plotselection_options_events_firefox_tooltip"
+msgstr "Visa datum för Firefox-släpp ovanpå plottarna"
+
+#: controllers/statistics_controller.php:272
+msgid "statistics_js_plotselection_options_resize_name_checked"
+msgstr "Kollapsa graf"
+
+#: controllers/statistics_controller.php:273
+msgid "statistics_js_plotselection_options_resize_name_unchecked"
+msgstr "Expandera graf"
+
+#: controllers/statistics_controller.php:274
+msgid "statistics_js_plotselection_options_resize_tooltip"
+msgstr "Ändra storlek på grafen"
+
+#: controllers/statistics_controller.php:254
+msgid "statistics_js_plotselection_selector_adu"
+msgstr "Aktiva dagliga användare"
+
+#: controllers/statistics_controller.php:256
+msgid "statistics_js_plotselection_selector_application"
+msgstr "Applikation"
+
+#: controllers/statistics_controller.php:259
+msgid "statistics_js_plotselection_selector_custom"
+msgstr "Anpassad"
+
+#: controllers/statistics_controller.php:253
+msgid "statistics_js_plotselection_selector_downloads"
+msgstr "Hämtningar"
+
+#: controllers/statistics_controller.php:258
+msgid "statistics_js_plotselection_selector_os"
+msgstr "Operativsystem"
+
+#: controllers/statistics_controller.php:257
+msgid "statistics_js_plotselection_selector_status"
+msgstr "Tilläggstatus"
+
+#: controllers/statistics_controller.php:252
+msgid "statistics_js_plotselection_selector_summary"
+msgstr "Sammanfattning"
+
+#: controllers/statistics_controller.php:255
+msgid "statistics_js_plotselection_selector_version"
+msgstr "Tilläggsversion"
+
+#: controllers/components/stats.php:398
+msgid "statistics_longnames_application"
+msgstr "Applikation"
+
+#: controllers/components/stats.php:400
+msgid "statistics_longnames_os"
+msgstr "Operativsystem"
+
+#: controllers/components/stats.php:399
+msgid "statistics_longnames_status"
+msgstr "Tilläggstatus"
+
+#: controllers/components/stats.php:401
+msgid "statistics_longnames_unknown"
+msgstr "Okänt"
+
+#: controllers/components/stats.php:397
+msgid "statistics_longnames_version"
+msgstr "Tilläggsversion"
+
+#: views/statistics/addon.thtml:118
+msgid "statistics_notice_data_insufficient"
+msgstr ""
+"Det finns inte tillräckligt med data för att visa denna graf. Titta in igen "
+"senare."
+
+#: views/statistics/addon.thtml:130
+msgid "statistics_notice_data_none"
+msgstr "Vi har inga data för ditt tillägg än. Titta här igen om några dagar."
+
+#: views/statistics/addon.thtml:41
+msgid "statistics_notice_data_updating"
+msgstr ""
+"Tilläggstatistik uppdateras just nu. Nytillkomna data kan vara inkompletta "
+"då våra skript just nu arbetar med att uppdatera informationen. Kom tillbaka "
+"om några minuter."
+
+#: views/statistics/addon.thtml:136
+msgid "statistics_notice_disabled"
+msgstr "Statistikpanelen är just nu inte tillgänglig, kom tillbaka senare."
+
+#: views/statistics/addon.thtml:123
+msgid "statistics_notice_nojavascript"
+msgstr "JavaScript krävs för att visa statistikpanelens grafer."
+
+#: views/statistics/addon.thtml:44
+msgid "statistics_notice_settings_updated"
+msgstr "Dina inställningar har uppdaterats!"
+
+#: controllers/statistics_controller.php:60
+#: controllers/statistics_controller.php:71
+#: controllers/statistics_controller.php:74
+#: controllers/statistics_controller.php:240
+msgid "statistics_pagetitle"
+msgstr "Statistikpanel"
+
+#: views/statistics/addon.thtml:99
+msgid "statistics_plot_legend_adu"
+msgstr "Aktiva dagliga användare"
+
+#: views/statistics/addon.thtml:95
+msgid "statistics_plot_legend_downloads"
+msgstr "Dagliga hämtningar"
+
+#: views/statistics/addon.thtml:107
+msgid "statistics_plot_options_zoomin_alt"
+msgstr "Zooma in"
+
+#: views/statistics/addon.thtml:106
+msgid "statistics_plot_options_zoomin_title"
+msgstr "Zooma in en månad"
+
+#: views/statistics/addon.thtml:110
+msgid "statistics_plot_options_zoomout_alt"
+msgstr "Zooma ut"
+
+#: views/statistics/addon.thtml:109
+msgid "statistics_plot_options_zoomout_title"
+msgstr "Zooma ut en månad"
+
+#: controllers/statistics_controller.php:283
+#, php-format
+msgid "statistics_rss_description"
+msgstr "Daglig summering av statistik för %1$s"
+
+#: views/statistics/rss/summary.thtml:68
+msgid "statistics_rss_title_fulldate"
+msgstr "%A, %B %e, %Y"
+
+#: views/statistics/rss/summary.thtml:68
+#, php-format
+msgid "statistics_rss_title_statsfordate"
+msgstr "Statistik för %1$s"
+
+#: views/statistics/settings.thtml:49
+msgid "statistics_settings_access_description"
+msgstr ""
+"Som standard kan bara du och Mozilla komma åt informationen i din "
+"statistikpanel. Du kan ändra detta och låta alla se ditt tilläggs data om du "
+"vill."
+
+#: views/statistics/settings.thtml:48
+msgid "statistics_settings_access_heading"
+msgstr "Ã…tkomst till panelen"
+
+#: views/statistics/settings.thtml:51
+msgid "statistics_settings_access_private"
+msgstr "Privat"
+
+#: views/statistics/settings.thtml:51
+msgid "statistics_settings_access_private_description"
+msgstr "Bara du och Mozilla kan se detta tilläggs statistik"
+
+#: views/statistics/settings.thtml:52
+msgid "statistics_settings_access_public"
+msgstr "Publik"
+
+#: views/statistics/settings.thtml:52
+msgid "statistics_settings_access_public_description"
+msgstr "Alla kan se detta tilläggs statistik"
+
+#: views/statistics/addon.thtml:251
+msgid "statistics_settings_change_link"
+msgstr "Ändra inställningar"
+
+#: views/statistics/addon.thtml:253
+msgid "statistics_settings_confidential"
+msgstr "Behandla detta som konfidentiell information."
+
+#: views/statistics/addon.thtml:245
+msgid "statistics_settings_currently_private"
+msgstr "Denna statistikpanel är för närvarande <b>privat</b>."
+
+#: views/statistics/addon.thtml:241
+msgid "statistics_settings_currently_public"
+msgstr "Denna statistikpanel är för närvarande <b>publik</b>."
+
+#: views/statistics/addon.thtml:246
+msgid "statistics_settings_locked_alt"
+msgstr "LÃ¥st"
+
+#: views/statistics/settings.thtml:57
+msgid "statistics_settings_return_link"
+msgstr "Återvänd till panelen"
+
+#: views/statistics/settings.thtml:56
+msgid "statistics_settings_save_button"
+msgstr "Spara inställningar"
+
+#: views/statistics/settings.thtml:46
+#, php-format
+msgid "statistics_settings_title"
+msgstr "Statistikpanelinställningar för %1$s"
+
+#: views/statistics/addon.thtml:242
+msgid "statistics_settings_unlocked_alt"
+msgstr "Olåst"
+
+#: controllers/components/stats.php:405
+msgid "statistics_shortnames_application"
+msgstr "App"
+
+#: controllers/components/stats.php:407
+msgid "statistics_shortnames_os"
+msgstr "OS"
+
+#: controllers/components/stats.php:406
+msgid "statistics_shortnames_status"
+msgstr "St"
+
+#: controllers/components/stats.php:408
+msgid "statistics_shortnames_unknown"
+msgstr "Ok"
+
+#: controllers/components/stats.php:404
+msgid "statistics_shortnames_version"
+msgstr "Ver"
+
+#: views/statistics/rss/summary.thtml:42 views/statistics/addon.thtml:192
+msgid "statistics_summary_downloads_average"
+msgstr "Dagliga hämtningar i genomsnitt"
+
+#: views/statistics/rss/summary.thtml:39
+msgid "statistics_summary_downloads_heading"
+msgstr "Hämtningar"
+
+#: views/statistics/rss/summary.thtml:41 views/statistics/addon.thtml:171
+msgid "statistics_summary_downloads_lastcount"
+msgstr "Räknare för senaste dagen"
+
+#: views/statistics/rss/summary.thtml:43 views/statistics/addon.thtml:199
+msgid "statistics_summary_downloads_lastweek"
+msgstr "Hämtningar senaste 7 dagarna"
+
+#: views/statistics/rss/summary.thtml:40 views/statistics/addon.thtml:151
+msgid "statistics_summary_downloads_total"
+msgstr "Totalt antal hämtningar"
+
+#: views/statistics/rss/summary.thtml:40 views/statistics/addon.thtml:152
+#, php-format
+msgid "statistics_summary_downloads_total_sincedate"
+msgstr "Sedan %1$s"
+
+#: views/statistics/rss/summary.thtml:50 views/statistics/rss/summary.thtml:56
+#: views/statistics/addon.thtml:163 views/statistics/addon.thtml:183
+msgid "statistics_summary_nodata"
+msgstr "Inga data ännu"
+
+#: views/statistics/rss/summary.thtml:60 views/statistics/addon.thtml:195
+msgid "statistics_summary_updatepings_average"
+msgstr "Dagliga aktiva användare i genomsnitt"
+
+#: views/statistics/rss/summary.thtml:52 views/statistics/addon.thtml:177
+msgid "statistics_summary_updatepings_changefromprevious"
+msgstr "Förändring från tidigare räknare"
+
+#: views/statistics/rss/summary.thtml:54 views/statistics/addon.thtml:181
+#, php-format
+msgid "statistics_summary_updatepings_changefromprevious_ondate"
+msgstr "%1$s den %2$s"
+
+#: views/statistics/rss/summary.thtml:45
+msgid "statistics_summary_updatepings_heading"
+msgstr "Aktiva dagliga användare"
+
+#: views/statistics/rss/summary.thtml:46 views/statistics/addon.thtml:157
+msgid "statistics_summary_updatepings_total"
+msgstr "Aktiva dagliga användare"
+
+#: views/statistics/rss/summary.thtml:48 views/statistics/addon.thtml:161
+#, php-format
+msgid "statistics_summary_updatepings_total_ondate"
+msgstr "Den %1$s"
+
+#: views/statistics/rss/summary.thtml:61 views/statistics/addon.thtml:203
+msgid "statistics_summary_updatepings_weekly_average"
+msgstr "Genomsnittliga dagliga användar denna vecka"
+
+#. %s is a percentage, like '+22.33%'. It sits next to another number, so
+#. the implied meaning is 'percentage change' from the previous stat point.
+#: views/statistics/rss/summary.thtml:62 views/statistics/addon.thtml:205
+msgid "statistics_summary_updatepings_weekly_change"
+msgstr "%s sen förra veckan"
+
+#: views/statistics/addon.thtml:65 controllers/statistics_controller.php:184
+#: controllers/statistics_controller.php:282
+#, php-format
+msgid "statistics_title_addon_stats"
+msgstr "%1$s-statistik"
+
+#: views/addons/themes_landing.thtml:113
+msgid "themes_landing_all_themes"
+msgstr "Alla teman"
+
+#: views/addons/themes_landing.thtml:109
+msgid "themes_landing_browse_themes"
+msgstr "Bläddra bland teman"
+
+#: views/users/edit.thtml:185
+msgid "user_change_email"
+msgstr "Ändra e-postadress"
+
+#: views/users/edit.thtml:169
+msgid "user_change_password"
+msgstr "Ändra lösenord"
+
+#: views/users/edit.thtml:96
+msgid "user_change_password_or_email"
+msgstr "Ändra lösenord eller e-post"
+
+#: controllers/users_controller.php:197
+msgid "user_confirmationcode_resent"
+msgstr "Bekräftelsekoden omskickad!"
+
+#. %1 is the email address, %2 is the URL of the user registration page
+#: views/users/delete.thtml:51
+msgid "user_del_account_deleted"
+msgstr ""
+"Ditt användarkonto %1$s har tagits bort. Om du vill komma tillbaka vid något "
+"senare tillfälle kan du omregistera dig på <a href=\"%2$s"
+"\">användarregistreringssidan</a>."
+
+#: views/users/delete.thtml:102
+msgid "user_del_community_sad"
+msgstr "Gemenskapen kring Mozilla Add-ons beklagar att du försvinner."
+
+#: views/users/delete.thtml:123
+msgid "user_del_confirm_password"
+msgstr "Bekräfta lösenord"
+
+#: views/users/delete.thtml:134
+msgid "user_del_deletenow"
+msgstr "Ta bort mitt användarkonto nu"
+
+#. %1 is the URL of the user's info page
+#: views/users/delete.thtml:64
+msgid "user_del_error_addons"
+msgstr ""
+"Du kan inte ta bort ditt konto om du är listad som <a href=\"%1$s"
+"\">författare till något tillägg</a>. För att ta bort ditt konto, se till "
+"att någon annan i din utvecklingsgrupp tar bort dig från listan av "
+"författare till era tillägg. Efter detta kommer du att kunna ta bort ditt "
+"konto här."
+
+#. %1 is a link to the amo-editors mailing list
+#: views/users/delete.thtml:71
+msgid "user_del_error_addons_more_questions"
+msgstr "Om du har ytterligare frågor, kontakta %1$s för assistans."
+
+#: views/users/delete.thtml:78
+msgid "user_del_error_checkbox"
+msgstr ""
+"Du måste kryssa i rutan med texten \"Jag förstår...\" innan vi kan ta bort "
+"ditt konto."
+
+#: views/users/delete.thtml:84
+msgid "user_del_error_password"
+msgstr "Skriv ditt lösenord korrekt för att genomföra detta steg."
+
+#. %1 is a link to the amo-admins mailing list
+#: views/users/delete.thtml:91
+msgid "user_del_error_unknown"
+msgstr ""
+"Ett okänt fel uppstod när ditt konto skulle tas bort. Kontakta %1$s och "
+"berätta så tar vi bort det åt dig. Vi ber om ursäkt för besväret."
+
+#: views/users/delete.thtml:110
+msgid "user_del_header_confirm_deletion"
+msgstr "Bekräfta kontoborttagning"
+
+#. %1 is the user's email address
+#: views/users/delete.thtml:100
+msgid "user_del_header_delete_account"
+msgstr "Ta bort användarkonto %1$s"
+
+#: views/users/delete.thtml:50
+msgid "user_del_header_farewell"
+msgstr "Farväl!"
+
+#: views/users/delete.thtml:115
+msgid "user_del_nologin"
+msgstr "Du kan inte längre logga in på Mozilla Add-ons."
+
+#: views/users/delete.thtml:112
+msgid "user_del_permanently_removed_means"
+msgstr ""
+"Genom att klicka på \"ta bort\" blir ditt konto <strong>permanent borttaget</"
+"strong>. Det betyder:"
+
+#: views/users/delete.thtml:116
+msgid "user_del_reviews_anonymized"
+msgstr ""
+"Dina recensioner och betyg tas inte bort, men de är inte längre kopplade "
+"till dig."
+
+#. %1 is a link to the amo-editors mailing list
+#: views/users/delete.thtml:104
+msgid "user_del_specific_problem_editors"
+msgstr ""
+"Om du har ett specifikt problem du vill ha hjälp med, ta inte bort ditt "
+"konto nu utan kontakta oss på %1$s och vi kommer att göra vårt bästa för att "
+"hjälpa dig lösa problemet."
+
+#: views/users/delete.thtml:130
+msgid "user_del_understand_permanent"
+msgstr "Jag förstår att detta steg inte kan göras ogjort."
+
+#: views/helpers/addons_html.php:192
+msgid "user_deleted_nickname"
+msgstr "Tog bort användare"
+
+#. %1 is the new email address
+#: views/users/edit.thtml:71
+msgid "user_edit_confirm_email_sent"
+msgstr ""
+"Ett e-postmeddelande har skickats till %1$s för att bekräfta din nya e-"
+"postadress. För att ändringen ska ge effekt måste du klicka på länken i det "
+"brevet. Till dess det är gjort kan du fortsätta logga in med din nuvarande e-"
+"postadress."
+
+#: views/users/edit.thtml:201
+msgid "user_edit_delete_user"
+msgstr "Ta bort användarkonto"
+
+#. This contains the email sent to users when they signed up for a new
+#. account:
+#. %1 is the confirmation URL, %2 is the current app
+#: views/users/email/confirm_plain.thtml:6
+#, php-format
+msgid "user_email_confirm_account_nopass"
+msgstr ""
+"Välkommen till %2$s Add-ons.\n"
+"\n"
+"Innan du kan använda ditt nya konto måste du aktivera detta - det\n"
+"visar att e-postadressen du angav fungerar och tillhör dig.\n"
+"\n"
+"För att aktivera kontot, klicka på länken nedan eller klistra in allt i din "
+"webbläsares adressrad:\n"
+"\n"
+"%1$s\n"
+"\n"
+"När du aktiverat ditt konto kan du slänga detta brev.\n"
+"\n"
+"Tack för att du registerat dig på %2$s Add-ons\n"
+"-- %2$s Add-ons-staben"
+
+#. %1 is the confirmation url, %2 is the application name
+#: views/users/email/emailchange_plain.thtml:5
+msgid "user_email_confirm_emailchange"
+msgstr ""
+"Du ändrade din e-postadress på %2$s Add-ons.\n"
+"\n"
+"För att bekräfta den nya adressen, klicka på länken nedan eller kopiera och "
+"klistra alltihop i din webbläsares adressrad:\n"
+"\n"
+"%1$s\n"
+"\n"
+"Du har 48 timmar på dig att bekräfta den nya adressen. Om du inte vill ändra "
+"adressen längre kan du bara ignorera det här brevet.\n"
+"\n"
+"Tack!\n"
+"-- %2$s Add-ons-staben"
+
+#: controllers/users_controller.php:168
+#, php-format
+msgid "user_email_confirm_subject"
+msgstr "Tack för att du registrerat dig på %s Add-ons"
+
+#. This is the password reset email
+#. %1 is the pw reset URL, %2 is the application
+#: views/users/email/pwreset_plain.thtml:5
+#, php-format
+msgid "user_email_pwreset"
+msgstr ""
+"%2$s Add-ons Lösenordsåterställning\n"
+"\n"
+"En begäran om att återställa lösenordet för detta konto gjordes på addons."
+"mozilla.org. För att ändra detta lösenord klicka på länken nedan eller "
+"klistra in den i din webbläsares adressrad:\n"
+"\n"
+"%1$s\n"
+"\n"
+"Om du inte begärde denna återställning behöver du inte göra något alls.\n"
+"\n"
+"Tack,\n"
+"-- %2$s Add-ons-staben"
+
+#: controllers/users_controller.php:245
+#, php-format
+msgid "user_email_pwreset_subject"
+msgstr "Återställ ditt %s Add-ons lösenord"
+
+#: views/users/emailchange.thtml:50
+msgid "user_emailchange_error"
+msgstr "Fel!"
+
+#. %1 is the application name
+#: controllers/users_controller.php:533
+msgid "user_emailchange_subject"
+msgstr "Bekräfta din e-postadressändring på %1$s Add-ons"
+
+#: views/users/emailchange.thtml:48
+msgid "user_emailchange_success"
+msgstr "Klart!"
+
+#. %1 is the new email address
+#: views/users/emailchange.thtml:49
+msgid "user_emailchange_successful_description"
+msgstr ""
+"Din e-postadress ändrades. Från och med nu ska du använda %1$s för att logga "
+"in."
+
+#: views/users/edit.thtml:134 views/admin/users_edit.thtml:111
+msgid "user_form_bio"
+msgstr "Om mig"
+
+#: views/users/edit.thtml:135 views/admin/users_edit.thtml:112
+msgid "user_form_bio_description"
+msgstr ""
+"Presentera dig själv, om du vill! Denna text visas publikt på din "
+"användarinformationssida. Radbrytningar behålls, men ingen HTML kan användas."
+
+#: views/users/pwreset.thtml:77 views/users/register.thtml:73
+#: views/users/edit.thtml:181
+msgid "user_form_confirmpassword"
+msgstr "Bekräfta lösenord"
+
+#: views/users/edit.thtml:145
+msgid "user_form_display_collections"
+msgstr "Visa de samlingar jag har skapat i min profil"
+
+#: views/users/edit.thtml:149
+msgid "user_form_display_collections_fav"
+msgstr "Visa mina favoritsamlingar i min profil"
+
+#: views/users/edit.thtml:86
+#, php-format
+msgid "user_form_editprofile"
+msgstr "Redigera användarprofil för %s"
+
+#: views/users/pwreset.thtml:52 views/users/login.thtml:81
+#: views/users/register.thtml:63 views/users/edit.thtml:187
+msgid "user_form_email"
+msgstr "E-postadress"
+
+#: views/users/register.thtml:78 views/users/edit.thtml:103
+#: views/admin/users_edit.thtml:76
+msgid "user_form_firstname"
+msgstr "Förnamn"
+
+#: views/users/register.thtml:94 views/users/edit.thtml:119
+#: views/admin/users_edit.thtml:91
+msgid "user_form_hideemail"
+msgstr "Göm e-postadress"
+
+#: views/users/register.thtml:98 views/users/edit.thtml:123
+#: views/admin/users_edit.thtml:99
+msgid "user_form_homepage"
+msgstr "URL för webbplats"
+
+#: views/users/register.thtml:84 views/users/edit.thtml:109
+#: views/admin/users_edit.thtml:81
+msgid "user_form_lastname"
+msgstr "Efternamn"
+
+#: controllers/users_controller.php:333
+msgid "user_form_login"
+msgstr "Användarinloggning"
+
+#: views/users/pwreset.thtml:72 views/users/edit.thtml:176
+msgid "user_form_newpassword"
+msgstr "Nytt lösenord"
+
+#: views/users/register.thtml:89 views/users/edit.thtml:114
+#: views/admin/users_edit.thtml:86
+msgid "user_form_nickname"
+msgstr "Kortnamn"
+
+#: views/users/edit.thtml:171
+msgid "user_form_oldpassword"
+msgstr "Gammalt lösenord"
+
+#: views/users/edit.thtml:97 views/users/edit.thtml:200
+msgid "user_form_otheractions"
+msgstr "Annat"
+
+#: views/users/login.thtml:85 views/users/register.thtml:68
+msgid "user_form_password"
+msgstr "Lösenord"
+
+#: controllers/users_controller.php:93
+msgid "user_form_registration"
+msgstr "Registrering av ny användare"
+
+#: views/users/login.thtml:90
+msgid "user_form_remember_me"
+msgstr "Kom ihåg mig på denna dator"
+
+#: views/admin/users_edit.thtml:95
+msgid "user_form_showsandbox"
+msgstr "Visa sandlådan?"
+
+#: views/users/edit.thtml:205
+msgid "user_form_submit_edit"
+msgstr "Spara"
+
+#: views/users/login.thtml:93
+msgid "user_form_submit_login"
+msgstr "Logga in"
+
+#: views/users/register.thtml:113
+msgid "user_form_submit_register"
+msgstr "Registrera"
+
+#: views/users/info.thtml:75
+#, php-format
+msgid "user_info_usersince"
+msgstr "%s Add-ons-användare sedan"
+
+#: views/users/login.thtml:102
+msgid "user_login_register_link"
+msgstr "Skapa ett nytt användarkonto"
+
+#: views/users/edit.thtml:160
+msgid "user_notifications_item_compat"
+msgstr "Tillägskompatibilitet (starkt rekommenderat)"
+
+#: views/users/edit.thtml:161
+msgid "user_notifications_item_events"
+msgstr "Kommande händelser och tävlingar"
+
+#: views/users/edit.thtml:156
+msgid "user_notifications_none_available"
+msgstr "Just nu finns det inga notifieringar du behöver konfigurera."
+
+#: views/users/edit.thtml:158
+msgid "user_notifications_select_topics"
+msgstr ""
+"Ibland kan Mozilla skicka e-post om kommande programsläpp och händelser på "
+"Add-ons. Välj vilka ämnen du är intresserad av här nedanför:"
+
+#: views/users/edit.thtml:164
+msgid "user_notifications_specific_contact"
+msgstr ""
+"Mozilla reserverar sig rätten att kontakta dig individuellt om eventuella "
+"särskilda frågeställningar med ditt tillägg."
+
+#: controllers/users_controller.php:543
+msgid "user_profile_edit_error"
+msgstr "Det fanns fel i dina ändringar. Vänligen korrigera och skicka in igen."
+
+#: controllers/users_controller.php:540
+msgid "user_profile_saved"
+msgstr "Profilen uppdaterad."
+
+#: views/users/pwreset.thtml:65
+#, php-format
+msgid "user_pwreset_for_email"
+msgstr "Återställ lösenordet för %s"
+
+#: controllers/users_controller.php:226
+msgid "user_pwreset_header"
+msgstr "Återställ lösenord"
+
+#: views/users/login.thtml:103
+msgid "user_pwreset_link"
+msgstr "Glömt ditt lösenord?"
+
+#: controllers/users_controller.php:248
+msgid "user_pwreset_link_sent"
+msgstr ""
+"Länken för att återställa lösenordet har skickats till din e-postadress."
+
+#: controllers/users_controller.php:304
+msgid "user_pwreset_okay"
+msgstr "Lösenordet återställt."
+
+#: views/users/pwreset.thtml:82
+msgid "user_pwreset_submit_changepw"
+msgstr "Ändra lösenord"
+
+#: views/users/pwreset.thtml:57
+msgid "user_pwreset_submit_sendlink"
+msgstr "Skicka länk för att återställa lösenord"
+
+#: views/users/register_complete.thtml:51
+#, php-format
+msgid "user_register_amo_link"
+msgstr "%s Add-ons"
+
+#. %1 is the user's email address, %2 is the current app
+#: views/users/activatefirst.thtml:49
+#, php-format
+msgid "user_register_click_confirm_link"
+msgstr ""
+"En länk för att aktivera ditt konto skickades med e-post till din adress %1"
+"$s. Du måste klicka på den före du kan logga in på %2$s Add-ons."
+
+#. %1 is the user's email address
+#: views/users/register_complete.thtml:49
+#, php-format
+msgid "user_register_confirm_email_sent"
+msgstr ""
+"E-post har skickats till din adress %1$s för att bekräfta ditt konto. Innan "
+"du kan logga in måste du aktivera ditt konto genom att klicka på länken i "
+"detta brev."
+
+#: views/users/activatefirst.thtml:51
+msgid "user_register_confirmation_link_text"
+msgstr "skicka bekräftelsebrevet igen"
+
+#: views/users/register_complete.thtml:47
+msgid "user_register_congratulations"
+msgstr "Grattis! Ditt konto skapades."
+
+#: views/users/register.thtml:50
+msgid "user_register_details"
+msgstr ""
+"<p>Registrering på AMO <strong>krävs inte</strong> om du bara vill ladda ner "
+"och installera publika tillägg.</p><p>Du behöver bara registrera dig om:</"
+"p><ul><li>Du vill skriva recensioner av tillägg</li><li>Du är en "
+"tilläggsutvecklare och vill ladda upp ditt tillägg för publicering på AMO</"
+"li></ul><p>Efter registrering får du ett bekräftelsebrev via e-post till "
+"adressen du angett. Följ instruktionerna där för att bekräfta ditt konto.</"
+"p><p>Om du vill kan du läsa vår <a href='%1$s' "
+"title='Rättighetsinformation'>Rättighetsinformation</a> och <a href='%2$s' "
+"title='Integritetsriktlinjer'>Integritetsriktlinjer</a>.</p>"
+
+#. %1 is the link to the "resend confirmation code" page
+#: views/users/activatefirst.thtml:51
+#, php-format
+msgid "user_register_resend_confirmation_link"
+msgstr ""
+"Om du inte fick bekräftelsebrevet via e-post, försäkra dig om att din e-"
+"postleverantör inte sorterat det som skräppost (\"junk mail\" eller \"spam"
+"\"). Om du behöver kan vi %1$s till e-postadressen ovanför."
+
+#. %1 is the link to the Mozilla Add-ons front page
+#: views/users/register_complete.thtml:51
+#, php-format
+msgid "user_register_welcome"
+msgstr "Tack för att du registerade dig och välkommen till %1$s!"
+
+#: views/users/register.thtml:49
+msgid "user_register_welcome_header"
+msgstr "Välkommen till addons.mozilla.org (AMO)!"
+
+#: views/users/register.thtml:81 views/users/edit.thtml:106
+msgid "user_required_firstlast_or_nickname"
+msgstr "Ett förnamn, efternamn eller kortnamn krävs."
+
+#: views/users/edit.thtml:94 views/users/edit.thtml:142
+msgid "user_tab_collections"
+msgstr "Samlingar"
+
+#: views/users/edit.thtml:95 views/users/edit.thtml:154
+msgid "user_tab_notifications"
+msgstr "Underrättelser"
+
+#: views/users/edit.thtml:93 views/users/edit.thtml:101
+msgid "user_tab_profile"
+msgstr "Användarprofil"
+
+#: controllers/users_controller.php:209
+msgid "user_verified_okay"
+msgstr "Verifierad!"
+
+#: controllers/users_controller.php:723
+msgid "users_delete_pagetitle"
+msgstr "Ta bort användarkonto"
+
+#: controllers/users_controller.php:414
+msgid "users_edit_pagetitle"
+msgstr "Redigera användarkonto"
+
+#: views/users/info.thtml:71
+msgid "users_info_aboutme"
+msgstr "Om mig"
+
+#: views/users/info.thtml:96
+#, php-format
+msgid "users_info_addons_by_user"
+msgstr "Tillägg från %1$s"
+
+#: views/users/info.thtml:51
+msgid "users_info_author_name"
+msgstr "Namn"
+
+#: views/users/info.thtml:48
+msgid "users_info_author_profile"
+msgstr "Användarprofil"
+
+#. %s is the user name
+#: views/users/info.thtml:137
+msgid "users_info_collections_by_user"
+msgstr "Samlingar av %s"
+
+#: views/users/info.thtml:66
+msgid "users_info_email"
+msgstr "E-postadress"
+
+#: views/users/info.thtml:155
+msgid "users_info_fav_collections_by_user"
+msgstr "Favoritsamlingar"
+
+#: views/users/info.thtml:61
+msgid "users_info_homepage"
+msgstr "Hemsida"
+
+#: views/users/info.thtml:56
+msgid "users_info_nickname"
+msgstr "Kortnamn"
+
+#: controllers/users_controller.php:707
+#, php-format
+msgid "users_info_pagetitle"
+msgstr "Användarinformation för %1$s"
+
+#. %1 is the user's name
+#: views/users/info.thtml:116
+msgid "users_info_reviews_by_user"
+msgstr "Recensioner av %s"
+
+#: controllers/users_controller.php:330 controllers/users_controller.php:332
+msgid "users_login_pagetitle"
+msgstr "Användarinloggning"
+
+#. %1 is the link to the sandbox/policy explanation page
+#. This message is for a specific add-on not found
+#: views/users/login.thtml:53
+#, php-format
+msgid "users_login_sandbox_display_warning"
+msgstr ""
+"Tillägget du letar efter ligger för närvarande i sandlådan. Om du redan har "
+"ett konto på Mozilla Add-ons så logga in, eller <a href=\"%1$s\">läs mer om "
+"sandlådan.</a>"
+
+#. %1 is the link to the sandbox/policy explanation page
+#. This message is for any given sandbox-related page not found
+#: views/users/login.thtml:56
+#, php-format
+msgid "users_login_sandbox_page_warning"
+msgstr ""
+"Sidan du letar efter finns i sandlådan. Om du redan har ett konto på Mozilla "
+"Add-ons så logga in, eller <a href=\"%1$s\">läs mer om sandlådan.</a>"
+
+#: controllers/users_controller.php:223 controllers/users_controller.php:225
+msgid "users_pwreset_pagetitle"
+msgstr "Återställ användarlösenord"
+
+#: controllers/users_controller.php:90 controllers/users_controller.php:92
+msgid "users_register_pagetitle"
+msgstr "Registrering av ny användare"
+
+#. %1$s is an addon name, like <a>Firebug</a>
+#. %2$s is a version number, like <a>1.2</a>
+#: views/versions/license.thtml:52
+msgid "versions_license_header_source"
+msgstr "Källkodslicens för %1$s %2$s"
+
+#: views/addons/category_landing.thtml:147
+msgid "view_recently_added"
+msgstr "Visa alla nyligen tillagda"
+
+#: views/addons/category_landing.thtml:161
+msgid "view_top_downloads"
+msgstr "Visa alla mest nedladdade"
+
+#: views/addons/category_landing.thtml:175
+msgid "view_top_rated"
+msgstr "Visa alla högst rankade"
+
+#~ msgid "addon_slider_tooltip_next"
+#~ msgstr "Nästa tillägg"
+
+#~ msgid "addon_slider_tooltip_previous"
+#~ msgstr "Föregående tillägg"
+
+#~ msgid "addon_versions_getlatesttext"
+#~ msgstr "Senaste version som är kompatibel med"
+
+#~ msgid "addons_display_version_history"
+#~ msgstr "Komplett versionshistorik"
+
+#~ msgid "addons_home_newest_header"
+#~ msgstr "Nyaste:"
+
+#~ msgid "addons_home_popular_header"
+#~ msgstr "Populärast:"
+
+#~ msgid "addons_home_recommended_header"
+#~ msgstr "Vi rekommenderar:"
+
+#~ msgid "addons_home_updated_header"
+#~ msgstr "Nyligen uppdaterade:"
+
+#~ msgid "addons_home_view_all"
+#~ msgstr "Visa alla"
+
+#~ msgid "category_extra_allrecommended"
+#~ msgstr "Visa alla rekommederade tillägg"
+
+#~ msgid "category_extra_highestrated"
+#~ msgstr "Högst betyg först"
+
+#~ msgid "category_extra_lastupdated"
+#~ msgstr "Senast uppdaterat först"
+
+#~ msgid "category_extra_mostpopular"
+#~ msgstr "Mest populära först"
+
+#~ msgid "collections_detail_js_loading"
+#~ msgstr "Laddar"
+
+#~ msgid "collections_detail_more_info"
+#~ msgstr "Visa mer information"
+
+#~ msgid "devcp_additem_firefox_notice"
+#~ msgstr ""
+#~ "Denna version av ditt tillägg uppger sig inte vara kompatibelt med "
+#~ "Firefox %1$s. Mozilla kommer att släppa nästa version av Firefox snart, "
+#~ "så testa gärna ditt tillägg i den nya versionen och uppdatera "
+#~ "informationen om kompatibilitet. Du kan hitta mer information om detta <a "
+#~ "href=\"%2$s\">här</a>. Detta är bara en upplysning och du kan fortsätta "
+#~ "med att skicka in denna version till addons.mozilla.org."
+
+#~ msgid "devcp_addon_disabled_successfully"
+#~ msgstr "Tillägget inaktiverat"
+
+#~ msgid "devcp_addon_edit_pagetitle"
+#~ msgstr "Redigera tillägg"
+
+#~ msgid "devcp_addon_enabled_successfully"
+#~ msgstr "Tillägget aktiverades"
+
+#~ msgid "devcp_addon_field_description_displaytitle"
+#~ msgstr "Tilläggets beskrivning"
+
+#~ msgid "devcp_addon_field_eula_displaytitle"
+#~ msgstr "Användarvillkor"
+
+#~ msgid "devcp_addon_field_homepage_displaytitle"
+#~ msgstr "Tilläggets hemsida"
+
+#~ msgid "devcp_addon_field_name_displaytitle"
+#~ msgstr "Tilläggets namn"
+
+#~ msgid "devcp_addon_field_privacy_displaytitle"
+#~ msgstr "Integritetsriktlinjer"
+
+#~ msgid "devcp_addon_field_summary_displaytitle"
+#~ msgstr "Tilläggets sammanfattning"
+
+#~ msgid "devcp_addon_field_supportemail_displaytitle"
+#~ msgstr "E-postaddress för hjälp"
+
+#~ msgid "devcp_addon_field_supporturl_displaytitle"
+#~ msgstr "URL för hjälp"
+
+#~ msgid "devcp_addon_field_versionnotes_displaytitle"
+#~ msgstr "Viktig information för denna version"
+
+#~ msgid "devcp_addon_nominate_pagetitle"
+#~ msgstr "Nominera tillägg"
+
+#~ msgid "devcp_addon_nominated_successfully"
+#~ msgstr "Tillägget nominerades!"
+
+#~ msgid "devcp_addon_status_criteria_review"
+#~ msgstr ""
+#~ "Flera användarrecensioner av tillägget (kan vara externa recensioner)."
+
+#~ msgid "devcp_addon_submission_makechanges"
+#~ msgstr ""
+#~ "Besök %1$s-sidan för att ändra eller %2$s för att återvända till "
+#~ "Utvecklarverktygen."
+
+#~ msgid "devcp_addon_submission_makechanges_devcp_link"
+#~ msgstr "klicka här"
+
+#~ msgid "devcp_addon_submission_makechanges_link"
+#~ msgstr "Redigera tillägg"
+
+#~ msgid "devcp_addon_submission_pending"
+#~ msgstr ""
+#~ "Denna version har placerats i sandlådan tills den granskats av "
+#~ "sandlådetestare och redaktörer för Mozilla Add-ons. Du kommer att få e-"
+#~ "post när något händer."
+
+#~ msgid "devcp_addon_submission_sandbox_readmore"
+#~ msgstr "Du kan läsa mer om systemet med sandlådans granskningssystem %s."
+
+#~ msgid "devcp_addon_submission_sandbox_readmore_link"
+#~ msgstr "här"
+
+#~ msgid "devcp_addon_submission_sandboxed"
+#~ msgstr ""
+#~ "Denna version har placerats i sandlådan för erfarna användare. För att "
+#~ "finnas med på den publika webbplatsen måste du %s ditt tillägg och "
+#~ "genomgå en granskningsprocess."
+
+#~ msgid "devcp_addon_submission_sandboxed_nominate_link"
+#~ msgstr "nominera"
+
+#~ msgid "devcp_addon_submission_success"
+#~ msgstr "Ditt tilläggs inläggning är nu klar."
+
+#~ msgid "devcp_addon_submission_trusted_public"
+#~ msgstr ""
+#~ "Eftersom ditt tillägg är betrott har denna version automatiskt godkänts "
+#~ "för denna publika ytan."
+
+#~ msgid "devcp_addon_submit_pagetitle"
+#~ msgstr "Lägg till tillägg"
+
+#~ msgid "devcp_addon_updated_successfully"
+#~ msgstr "Tillägget uppdaterat"
+
+#~ msgid "devcp_addon_upload_preview"
+#~ msgstr "Du kan vilja %s för att öka intresset för ditt tillägg."
+
+#~ msgid "devcp_addon_upload_preview_link"
+#~ msgstr "lägga till en förhandsvisning"
+
+#~ msgid "devcp_author_lookup_none_found"
+#~ msgstr "Ingen författare hittad [%s]"
+
+#~ msgid "devcp_author_lookup_remove"
+#~ msgstr "Ta bort"
+
+#~ msgid "devcp_button_cancel"
+#~ msgstr "Avbryt"
+
+#~ msgid "devcp_button_cancel_confirm"
+#~ msgstr "Är du säker på att du vill avbryta din inskickning?"
+
+#~ msgid "devcp_button_next"
+#~ msgstr "Nästa"
+
+#~ msgid "devcp_change_addontype"
+#~ msgstr "Ändra tilläggstyp:"
+
+#~ msgid "devcp_comments_updated"
+#~ msgstr "Utvecklarekommentarer uppdaterade."
+
+#~ msgid "devcp_details_addpreview_link"
+#~ msgstr "Lägg till förhandsvisning"
+
+#~ msgid "devcp_details_author"
+#~ msgstr "Författare"
+
+#~ msgid "devcp_details_authors"
+#~ msgstr "Författare"
+
+#~ msgid "devcp_details_authors_none"
+#~ msgstr "Inga"
+
+#~ msgid "devcp_details_categories"
+#~ msgstr "Kategorier"
+
+#~ msgid "devcp_details_category"
+#~ msgstr "Kategori"
+
+#~ msgid "devcp_details_description"
+#~ msgstr "Beskrivning"
+
+#~ msgid "devcp_details_disabled"
+#~ msgstr "Inaktiverat"
+
+#~ msgid "devcp_details_guid"
+#~ msgstr "GUID"
+
+#~ msgid "devcp_details_header_details"
+#~ msgstr "Detaljer"
+
+#~ msgid "devcp_details_header_devcomments"
+#~ msgstr "Utvecklarekommentarer"
+
+#~ msgid "devcp_details_header_previews"
+#~ msgstr "Förhandsvisningar"
+
+#~ msgid "devcp_details_header_versions"
+#~ msgstr "Versioner"
+
+#~ msgid "devcp_details_homepage"
+#~ msgstr "Hemsida"
+
+#~ msgid "devcp_details_homepage_none"
+#~ msgstr "Inga"
+
+#~ msgid "devcp_details_preview_nocaption"
+#~ msgstr "Ingen bildtext"
+
+#~ msgid "devcp_details_previews_nonefound"
+#~ msgstr "Ingen förhandsvisning hittad."
+
+#~ msgid "devcp_details_submit_update"
+#~ msgstr "Uppdatera"
+
+#~ msgid "devcp_details_supportemail"
+#~ msgstr "E-post för hjälp"
+
+#~ msgid "devcp_details_supportemail_none"
+#~ msgstr "Ingen e-postadress för hjälp angiven av utvecklaren."
+
+#~ msgid "devcp_details_supporturl"
+#~ msgstr "URL för hjälp"
+
+#~ msgid "devcp_details_supporturl_none"
+#~ msgstr "Ingen URL för hjälp angiven av utvecklaren."
+
+#~ msgid "devcp_details_trusted"
+#~ msgstr "Betrott"
+
+#~ msgid "devcp_details_versions_none_found"
+#~ msgstr "Inga versioner hittade."
+
+#~ msgid "devcp_disable_cancel"
+#~ msgstr "Avbryt och gå tillbaka"
+
+#~ msgid "devcp_disable_disable_button"
+#~ msgstr "Ja, inaktivera det"
+
+#~ msgid "devcp_disable_disable_confirm"
+#~ msgstr "Är det säkert att du vill inaktivera detta tillägg?"
+
+#~ msgid "devcp_disable_disable_description"
+#~ msgstr ""
+#~ "Inaktivering av detta tillägg kommer att gömma det från sökningar och "
+#~ "listningar. Det kommer inte längre att kunnas laddas ner från webbplatsen "
+#~ "och hanteras inte av den automatiska klientuppdateringen. Tillägget "
+#~ "kommer för alla praktiska syften att verka borttaget, även om du kan "
+#~ "återvända hit och återaktivera det när det passar."
+
+#~ msgid "devcp_disable_disable_title"
+#~ msgstr "Inaktivera %s"
+
+#~ msgid "devcp_disable_enable_button"
+#~ msgstr "Ja, aktivera det"
+
+#~ msgid "devcp_disable_enable_confirm"
+#~ msgstr "Är du säker på att du vill aktivera detta tillägg?"
+
+#~ msgid "devcp_disable_enable_description"
+#~ msgstr ""
+#~ "Om du aktiverar detta tillägg kommer det återigen att finnas med i "
+#~ "sökningar och listningar. Det kommer att kunna laddas ner båda från "
+#~ "webbplatsen och automatisk klientuppdatering."
+
+#~ msgid "devcp_disable_enable_title"
+#~ msgstr "Aktivera %s"
+
+#~ msgid "devcp_edit_author_add"
+#~ msgstr "Lägg till författare"
+
+#~ msgid "devcp_edit_author_email"
+#~ msgstr "E-postadress till författaren"
+
+#~ msgid "devcp_edit_author_remove"
+#~ msgstr "Ta bort"
+
+#~ msgid "devcp_edit_error_categories_unavailable"
+#~ msgstr "Inga kategorier tillgängliga för detta tilläggs typ."
+
+#~ msgid "devcp_edit_file_error_incomplete"
+#~ msgstr "Incomplete transfer"
+
+#~ msgid "devcp_edit_file_error_no"
+#~ msgstr "No file uploaded"
+
+#~ msgid "devcp_edit_file_error_size"
+#~ msgstr "Exceeds maximum upload size"
+
+#~ msgid "devcp_edit_header_authors"
+#~ msgstr "Författare"
+
+#~ msgid "devcp_edit_icon_add_link"
+#~ msgstr "Lägg till ikon"
+
+#~ msgid "devcp_edit_icon_change_link"
+#~ msgstr "Byt ikon"
+
+#~ msgid "devcp_edit_label_allow_viewsource"
+#~ msgstr "Tillåt användare att se källkodsfilerna på nätet"
+
+#~ msgid "devcp_edit_label_categories"
+#~ msgstr "Kategorier"
+
+#~ msgid "devcp_edit_label_defaultlocale"
+#~ msgstr "Standardlokal"
+
+#~ msgid "devcp_edit_label_icon_delete"
+#~ msgstr "Rensa bara den existerande ikonen"
+
+#~ msgid "devcp_edit_label_icon_new"
+#~ msgstr "Ny ikonfil"
+
+#~ msgid "devcp_edit_label_info"
+#~ msgstr "Ikon"
+
+#~ msgid "devcp_edit_locale_disambiguation_explanation"
+#~ msgstr "kort ytterligare information (som namn på lokal dialekt)"
+
+#~ msgid "devcp_edit_submit_update"
+#~ msgstr "Uppdatera"
+
+#~ msgid "devcp_edit_target_locale_explanation"
+#~ msgstr ""
+#~ "<a href=\"http://wiki.mozilla.org/L10n:Simple_locale_names\">enkelt "
+#~ "lokalnamn</a>, exempelvis 'en-US'"
+
+#~ msgid "devcp_editversion_checkedfiles_delete"
+#~ msgstr "Förkryssade filer kommer att tas bort."
+
+#~ msgid "devcp_editversion_filename_size"
+#~ msgstr "%1$s (%2$s)"
+
+#~ msgid "devcp_editversion_label_files"
+#~ msgstr "Filer"
+
+#~ msgid "devcp_editversion_label_targetapps"
+#~ msgstr "MÃ¥lapplikationer"
+
+#~ msgid "devcp_editversion_nofiles"
+#~ msgstr "Inga filer."
+
+#~ msgid "devcp_editversion_reviewernotes"
+#~ msgstr "Information till granskare"
+
+#~ msgid "devcp_editversion_submit_update"
+#~ msgstr "Uppdatera"
+
+#~ msgid "devcp_error_addon_field_summary_toolong"
+#~ msgstr ""
+#~ "Sammanfattningar är begränsade till max 250 tecken \n"
+#~ "(du skrev %s)"
+
+#~ msgid "devcp_error_addonname_not_unique"
+#~ msgstr ""
+#~ "Namnet på detta tillägg finns redan i databasen. Försäkra dig om att: "
+#~ "<br /><li>Dina GUIDs stämmer. Den vanligaste orsaken till detta fel är "
+#~ "GUIDs som inte stämmer.</li><li>Du inte har två poster i databasen. Har "
+#~ "du det bör du uppdatera den posten eller ta bort den och försöka igen.</"
+#~ "li>"
+
+#~ msgid "devcp_error_describe_changes"
+#~ msgstr "Beskriv ändringarna i denna tilläggsuppdatering."
+
+#~ msgid "devcp_error_file_guids_dont_match"
+#~ msgstr "Inte alla fil-GUID stämde"
+
+#~ msgid "devcp_error_identical_version_exists"
+#~ msgstr ""
+#~ "En identisk version (%s) finns redan för detta tillägg och plattform."
+
+#~ msgid "devcp_error_nominate_message"
+#~ msgstr "Du måste ange de begärda detaljerna för att nominera."
+
+#~ msgid "devcp_error_nominate_no_prerelease"
+#~ msgstr "Du kan inte nominera ett förhandssläppt tillägg."
+
+#~ msgid "devcp_error_nominate_sandbox_only"
+#~ msgstr "Du kan bara nominera tillägg som finns i sandlådan."
+
+#~ msgid "devcp_error_saving"
+#~ msgstr "Ett fel inträffade när dina data skulle sparas."
+
+#~ msgid "devcp_error_update_access_denied"
+#~ msgstr "Du har inte rättighet att uppdatera detta tillägg."
+
+#~ msgid "devcp_file_addanother"
+#~ msgstr "Lägg till en till plattformsfil"
+
+#~ msgid "devcp_form_author_add"
+#~ msgstr "Lägg till författare"
+
+#~ msgid "devcp_form_author_remove"
+#~ msgstr "Ta bort"
+
+#~ msgid "devcp_form_categories_nextstep"
+#~ msgstr "Kategorier för din nya tilläggstyp kommer att finnas i nästa steg."
+
+#~ msgid "devcp_form_error_categories_unavailable"
+#~ msgstr "Inga kategorier fanns tillgängliga för denna tilläggstyp."
+
+#~ msgid "devcp_form_error_description_notempty"
+#~ msgstr "Ge en beskrivning av ditt tillägg."
+
+#~ msgid "devcp_form_error_name_required"
+#~ msgstr "Skriv namnet på ditt tillägg."
+
+#~ msgid "devcp_form_error_select_addontype"
+#~ msgstr "Välj typ på tillägget du skickar in."
+
+#~ msgid "devcp_form_error_summary_notempty"
+#~ msgstr "Skriv en sammanfattning av ditt tillägg."
+
+#~ msgid "devcp_form_label_addonfile"
+#~ msgstr "Tilläggsfil"
+
+#~ msgid "devcp_form_label_addonfile2"
+#~ msgstr "Tilläggsfil 2"
+
+#~ msgid "devcp_form_label_addonfile3"
+#~ msgstr "Tilläggsfil 3"
+
+#~ msgid "devcp_form_label_addontype"
+#~ msgstr "Tilläggstyp"
+
+#~ msgid "devcp_form_label_allow_viewsource"
+#~ msgstr "Tillåt användare att titta på källkoden direkt"
+
+#~ msgid "devcp_form_label_author_email"
+#~ msgstr "Författarens e-postadress"
+
+#~ msgid "devcp_form_label_authors"
+#~ msgstr "Författare"
+
+#~ msgid "devcp_form_label_categories"
+#~ msgstr "Kategorier"
+
+#~ msgid "devcp_form_label_defaultlocale"
+#~ msgstr "Standardlokal"
+
+#~ msgid "devcp_form_label_description"
+#~ msgstr "Beskrivning"
+
+#~ msgid "devcp_form_label_eula"
+#~ msgstr "Användningsvillkor (EULA)"
+
+#~ msgid "devcp_form_label_externalsoftware"
+#~ msgstr "Detta tillägg kräver extern programvara"
+
+#~ msgid "devcp_form_label_files"
+#~ msgstr "Filer"
+
+#~ msgid "devcp_form_label_homepage"
+#~ msgstr "Hemsida"
+
+#~ msgid "devcp_form_label_iconfile"
+#~ msgstr "Ikonfil"
+
+#~ msgid "devcp_form_label_name"
+#~ msgstr "Namn"
+
+#~ msgid "devcp_form_label_platforms"
+#~ msgstr "Plattformar som stöds"
+
+#~ msgid "devcp_form_label_prerelease"
+#~ msgstr "Detta är en förhandsversion"
+
+#~ msgid "devcp_form_label_privacy"
+#~ msgstr "Integritetsriktlinjer"
+
+#~ msgid "devcp_form_label_sitespecific"
+#~ msgstr "Detta tillägg är specifikt för en särskild webbplats"
+
+#~ msgid "devcp_form_label_summary"
+#~ msgstr "Sammanfattning"
+
+#~ msgid "devcp_form_label_supportemail"
+#~ msgstr "E-postadress för hjälp"
+
+#~ msgid "devcp_form_label_supporturl"
+#~ msgstr "URL för hjälp"
+
+#~ msgid "devcp_form_label_target_applications"
+#~ msgstr "MÃ¥lapplikationer"
+
+#~ msgid "devcp_form_label_version"
+#~ msgstr "Version"
+
+#~ msgid "devcp_form_label_versionnotes"
+#~ msgstr "Information för versionen"
+
+#~ msgid "devcp_form_no_target_apps"
+#~ msgstr "Inga"
+
+#~ msgid "devcp_form_reviewernotes"
+#~ msgstr "Information till granskaren"
+
+#~ msgid "devcp_form_trustedaddon_destination"
+#~ msgstr ""
+#~ "Efersom ditt tillägg är betrott, välj var denna version ska placeras:"
+
+#~ msgid "devcp_form_trustedaddon_destination_public"
+#~ msgstr "Publik"
+
+#~ msgid "devcp_form_trustedaddon_destination_sandbox"
+#~ msgstr "Sandlåda"
+
+#~ msgid "devcp_header_developer_agreement"
+#~ msgstr "Utvecklareavtal"
+
+#~ msgid "devcp_header_step1"
+#~ msgstr "Steg 1"
+
+#~ msgid "devcp_header_step1_upload"
+#~ msgstr "Ladda upp fil"
+
+#~ msgid "devcp_header_step2"
+#~ msgstr "Steg 2"
+
+#~ msgid "devcp_header_step2_addondetails"
+#~ msgstr "Detaljer för tillägget"
+
+#~ msgid "devcp_header_step3"
+#~ msgstr "Steg 3"
+
+#~ msgid "devcp_header_step3_versiondetails"
+#~ msgstr "Versionsdetaljer"
+
+#~ msgid "devcp_header_step4"
+#~ msgstr "Steg 4"
+
+#~ msgid "devcp_header_step4_localization"
+#~ msgstr "Lokalisering"
+
+#~ msgid "devcp_header_step5"
+#~ msgstr "Steg 5"
+
+#~ msgid "devcp_header_step5_success"
+#~ msgstr "Klart"
+
+#~ msgid "devcp_index_header_myaddons"
+#~ msgstr "Mina tillägg"
+
+#~ msgid "devcp_nominate_link_returnto_details"
+#~ msgstr "Tillbaka till detaljer för tillägget"
+
+#~ msgid "devcp_notice_autodetected_addontype"
+#~ msgstr "Automatiskt detekterad tilläggstyp: %s."
+
+#~ msgid "devcp_notice_different_defaultlocale"
+#~ msgstr ""
+#~ "Standardlokalen för detta tillägg (%1$s [%2$s]) skiljer sig från din "
+#~ "nuvarande lokal (%3$s [%4$s]). Fälten nedan bör fyllas i enligt %1$s."
+
+#~ msgid "devcp_question_addontype_incorrect"
+#~ msgstr "Felaktig?"
+
+#~ msgid "devcp_question_delete_file"
+#~ msgstr "Är du säker på att du vill ta bort den här filen?"
+
+#~ msgid "devcp_skip_reviewing_addon_info"
+#~ msgstr "Hoppa över uppdatering av information för mitt nuvarande tillägg"
+
+#~ msgid "devcp_submissions_disabled"
+#~ msgstr "Tillägg kan inte läggas till för närvarande. Försök igen senare."
+
+#~ msgid "devcp_submit_accept_dev_agreement"
+#~ msgstr "Jag accepterar"
+
+#~ msgid "devcp_submit_decline_dev_agreement"
+#~ msgstr "Jag avböjer"
+
+#~ msgid "devcp_summary_admin_disabled"
+#~ msgstr "Detta tillägg har inaktiverats av en administratör."
+
+#~ msgid "devcp_summary_header_disabled"
+#~ msgstr "Inaktiverat"
+
+#~ msgid "devcp_summary_header_trusted"
+#~ msgstr "Betrott"
+
+#~ msgid "devcp_summary_noaddons_submit_one"
+#~ msgstr "Du har inga tillägg. Klicka %s för att skicka in ett."
+
+#~ msgid "devcp_summary_noaddons_submit_one_link"
+#~ msgstr "här"
+
+#~ msgid "devcp_theme_upload_preview"
+#~ msgstr "Se till att %s för ditt tema."
+
+#~ msgid "devcp_theme_upload_preview_link"
+#~ msgstr "ladda upp en förhandsvisning"
+
+#~ msgid "devcp_version_edit_pagetitle"
+#~ msgstr "Redigera version"
+
+#~ msgid "devcp_version_updated_successfully"
+#~ msgstr "Versionen uppdaterad."
+
+#~ msgid "editors_submissiontype_new"
+#~ msgstr "Ny"
+
+#~ msgid "editors_submissiontype_updated"
+#~ msgstr "Uppdaterad"
+
+#~ msgid "editors_th_addon_age"
+#~ msgstr "Tilläggsålder"
+
+#~ msgid "editors_th_addontypes"
+#~ msgstr "Tilläggstyper"
+
+#~ msgid "editors_th_age"
+#~ msgstr "Ã…lder"
+
+#~ msgid "editors_th_applications"
+#~ msgstr "Applikationer"
+
+#~ msgid "editors_th_platforms"
+#~ msgstr "Plattformar"
+
+#~ msgid "editors_th_submissiontypes"
+#~ msgstr "Inskickningstyper"
+
+#~ msgid "error_notice"
+#~ msgstr "Information"
+
+#~ msgid "forum_save"
+#~ msgstr "Spara"
+
+#~ msgid "home"
+#~ msgstr "hem"
+
+#~ msgid "nav_category_plugins"
+#~ msgstr "Insticksprogram"
+
+#~ msgid "page_title_experimental_addons"
+#~ msgstr "Experimentella tillägg"
+
+#~ msgid "pages_experimental_addons_backbutton"
+#~ msgstr "Tillbaka till föregående sida"
+
+#~ msgid "pagination_page_number_title"
+#~ msgstr "Detta är sida %1$s av %2$s"
+
+#~ msgid "search_matching_addons_number"
+#~ msgid_plural "search_matching_addons_number"
+#~ msgstr[0] "%s passande tillägg"
+#~ msgstr[1] "%s passande tillägg"
+
+#~ msgid "statistics_rss_icon_title"
+#~ msgstr "RSS-kanal för sammanfattningsdata"
diff --git a/site/app/locale/sv_SE/pages/error404.thtml b/site/app/locale/sv_SE/pages/error404.thtml
new file mode 100644
index 0000000..e3558fb
--- /dev/null
+++ b/site/app/locale/sv_SE/pages/error404.thtml
@@ -0,0 +1,16 @@
+<h1>Tyvärr, men vi kan inte hitta det du letar efter.</h1>
+
+<p>Sidan eller filen du bad om fanns inte på vår webbplats. Det är möjligt att du följde en föråldrad länk eller skrivit fel när du skrev in en adress.</p>
+
+<ul>
+<li>Om du skrev in en adress, dubbelkolla att du stavat rätt.</li>
+<li>Om du följde en länk hit, berätta för oss på adressen <a href="mailto:webmaster@mozilla.com" title="Page Not Found on Mozilla.com">webmaster@mozilla.com</a>. Berätta var du kom från och vad du letade efter, och vi ska göra vårt bästa för att laga felet (skriv på engelska).</li>
+</ul>
+
+<p>Eller du kan hoppa över till några av de populäraste sidorna på vår webbplats.</p>
+
+<ul>
+<li>Är du intresserad av en <a href="%1$s">lista på populära tillägg</a>?</li>
+<li>Vill du <a href="%2$s">leta efter tillägg</a>? Du kan gå till <a href="%2$s">söksidan</a> eller använda sökfältet ovanför direkt.</li>
+<li>Om du vill börja om, gå bara till <a href="%3$s">Mozilla Add-ons förstasida</a>.</li>
+</ul>
diff --git a/site/app/locale/sv_SE/pages/nomination.thtml b/site/app/locale/sv_SE/pages/nomination.thtml
new file mode 100644
index 0000000..2d40cb8
--- /dev/null
+++ b/site/app/locale/sv_SE/pages/nomination.thtml
@@ -0,0 +1,10 @@
+<p>Ett tilläg som finns i sandlådan kan nomineras för att finnas på den publika webbplatsen och bli tillgänglig för alla användare efter att ha granskats av en redaktör. För bästa resultat, uppmärksamma följande instruktioner:</p>
+<ul>
+ <li>Förhandsvisningsbilder krävs för teman och rekommenderas starkt för alla andra typer av tillägg.</li>
+ <li>Tillägget ska ha funnits i sandlådan länge nog för att få recensioner och kommentarer från användare. <b>Ett tillägg måste ha recensioner för att bli publikt tillgänglig.</b></li>
+ <li>För publika tillägg lägger vi ribban högre kvalitetsmässigt än för tillägg i sandlådan - publika tillägg ska förbättra webbupplevelsen.</li>
+ <li>Fullständiga kriterier för nominering finns i <a href="%s">Add-ons riktlinjer</a>.</li>
+</ul>
+<p>Om ditt tillägg uppfyller dessa kriterier kan du nominera det genom att fylla i formuläret nedan. Du kommer att få besked via e-post om vad som händer me din nominering.</p>
+
+<p>För att nominera ditt tillägg, beskriv hur det har testats (inklusive att det är fritt från fel och varningar) och hur det är nyttigt för webben i stort. Du kan också inkludera länkar till externa recensioner av ditt tillägg.</p>
diff --git a/site/app/locale/sv_SE/pages/policy.thtml b/site/app/locale/sv_SE/pages/policy.thtml
new file mode 100644
index 0000000..1d9ed63
--- /dev/null
+++ b/site/app/locale/sv_SE/pages/policy.thtml
@@ -0,0 +1,112 @@
+<h1>Add-ons Riktlinjer</h1>
+
+<h2>Vad är sandlådan?</h2>
+<p>Se %s.</p>
+
+<h2>Vilka tillägg finns i sandlådan?</h2>
+<p>Sandlådan är där alla tillägg på AMO hamnar till att börja med. Den innehåller nya versioner av publika tillägg liksom alla versioner för tillägg som inte är publika. När ett nytt tillägg eller en uppdatering av ett existerande tillägg skicas in till AMO hamnar det i sandlådan.</p>
+
+<p>Några tillägg, och deras specifika versioner, blir publika efter granskningsprocesssen visat att de är klara och lämpliga att visas publikt. Andra tillägg stannar kvar i sandlådan tillsvidare, där de är tillgängliga för användare som väljer att bläddra i sandlådan och experimentera med mjukvaran där.</p>
+
+<h2>Hur blir tillägg publika?</h2>
+
+<p>Tillägg granskas av AMO-användare som valt att titta i sandlådan och testa paketen där. De recensioner som AMO-användare skriver indikerar om tillägget är tillräckligt nyttigt, välskrivet och finputsat att visas upp för alla Firefoxs användare. Dessa recensioner, eventuellt tillsammans med andra recensioner och inspektioner av AMO används för att avgöra om ett givet tillägg ska göras publikt, om det behöver mer arbete för att putsas upp för större synlighet och om det är lämpligt att framhållas på AMOs webbplats utanför sandlådan.</p>
+
+<h2>Hur gör jag för att få mitt tilläggt publikt?</h2>
+
+<p>Om du tror att ditt tillägg (och ditt uppförande!) uppfyller kriterien för ett publikt tillägg kan du nominera det från utvecklarverktygen.</p>
+
+<h2>Vilka är kriterien för pubilika tillägg?</h2>
+
+<p>Ett tillägg som görs publikt på AMO ska vara av hög kvalitet och ge användare en förbättrad webbupplevelse. Vi tittar på följande när vi avgör om ett tillägg är lämpligt för den publika sidan av AMO:</p>
+
+<h3>Är du alert?</h3>
+
+<p>Vi förväntar oss att författare som vill visa upp sitt tillägg för Firefoxs många användare är mottaglig för problemrapporter, håller sin kontaktinformation uppdaterad och uppdaterar sitt tillägg snabbt för att hänga med Firefoxs produktutveckling och ändringar i AMOs riktlinjer. Det betyder inte att du måste svara på varenda fråga någon postar i diskussionsforumen eller att du måste fixa varje programfel, men vi förväntar oss att du hanterar problem på lämpligt sätt utifrån hur allvarligt problemet i fråga är.</p>
+
+<h3>Är tillägget tydligt och korrekt beskrivet?</h3>
+
+<p>Det är av största vikt för oss att avnändare får vad de förväntar sig när de provar ett nytt tillägg. Din beskrivning bör ge detaljer om vad tillägget gör, hur en användare kan dra nytta av det och vad användaren kan förvänta sig när de installerar det. Länkar till externa dokument för detaljerade instruktioner går bra, men beskrivningen själv bör innehålla grunderna och ge användarna förtroende att de vet vad de får.</p>
+
+<p>Vidare är det viktigt att du underhåller versionsdetaljer ordentligt när du förbätttrar och ändrar ditt tillägg. Användare bör kunna se vad som är nytt i ett tillägg de har provat tidigare och bör medvetandegöras om ändringar som kan påverka deras nuvarande av tillägget när de uppdaterar. (Just nu ser inte användare versiondetaljerna när de tillfrågas om en uppdatering inuti webbläsaren, men vi arbetar på att fixa det. Om du underhåller versionsdetaljer ordentligt kommer dina användare att dra stor nytta av det, både före och efter att det arbetet är gjort.)</p>
+
+<h3>Är alla integritets- och säkerhetsproblem ordentligt belysta?</h3>
+
+<p>Det här är en del av en tydlig och korrekt beskrivning, men en så viktig del att vi tycker det förtjänar att nämnas separat. Många väldigt användbara och välskrivna tillägg arbetar med något slags användardata eller kan utgöra säkerhetsrisker om de används fel; de är välkomna till den publika sidan av AMO, men de måste göra det väldigt klart för användarna vilka risker de kan stöta på och hur de kan skydda sig.</p>
+
+<h3>Har tillägget blivit testat ordentligt och är det fritt från uppenbara eller allvarliga fel?</h3>
+
+<p>En viktig sak vi letar efter när vi bedömer om ett tillägg är lämpligt för publik åtkomst är om dess recensioner i sandlådan indikerar att det har genomgått oredentlig testning och att det inte har allvarliga problem eller påverkar webbläsaren negativt. Om recensenter rapporterar sådant som exempelvis stora prestandaproblem, krascher, upprepade problem med funktionen av tillägget eller alltför många meddelanden till felkonsollen, bör du ta dessa rapporter allvarligt och nominera ditt tillägg igen efter att ha åtgärdat dem så gott du kan. Vi förväntar oss inte att du optimerar perfekt eller att tillägget är helt felfritt -- Firefox självt genomgår hela tiden förbättringar inom dessa områden -- men vi vill att du gör rimliga ansträngningar att minimera problemen och tydligt peka ut fall där användare kan bli överraskad av de som kvarstår.</p>
+
+<p>Om ditt tillägg har testats utanför AMOs sandlådeprocess, exempelvis av en grupp användare av din tjänst eller en intern kvalitetsgrupp, bör du indikera det i ditt nomineringsmeddelande. Det hjälper oss definitivt att förstå nivån på testningen och kan hjälpa till att få upp ditt tillägg på webbplatsen.</p>
+
+<h3>Behandlar tillägget och dess författare användaren med respekt?</h3>
+
+<p>Din mjukvara ska inte tränga sig på användaren i onödan, försöka lura användaren eller dölja någon av sina aktiviteter från användaren. Användare (eller icke-användare) är ibland oförskämda i sina kommentarer, och medan vi kommer att göra vårt bästa för att filtrera ut sådana när de rapporteras till oss, förväntar vi oss att författare inte svarar med att vara oförskämda själva.</p>
+
+<h3>Är tillägget nyttigt till en tillräckligt sotr andel av Firefoxs användare?</h3>
+
+<p>Ditt tillägg behöver inte vara nästa Greasemonkey eller FireBug, men om det bara är nyttigt för folk på ditt företag eller de som är medlemmar i en liten webbgemenskap kan vi tycka att det inte ännu är lämpligt att sätta det framför alla Firefoxs användare.</p>
+
+<p>Vi letar hela tiden efter sätt att förbättra webbplatsens organisation för att bättre rymma tillägg som är exemplariska på andra sätt, men riktar sig bara åt en liten gemenskap av möjliga användare. Att kategorisera korrekt och underhålla metadatat för ditt tillägg hjälper oss att tänka ut hur vi kan framhålla fler av den sortens tillägg för de som är mest troliga att dra nytta av dem.</p>
+
+<p>Om ditt tillägg bara ger bokmärken eller andra enklare sätt att komma åt din webbplats är det förmodligen inte lämpat för den publika sidan. Liksom resten av Mozillaprojektet älskar vi webbapplikationer och nya webbtjänster, men Firefoxtillägg ska ge en förbättrad webbupplevelse för användaren och inte bara vara ett sätt att göra reklam för en ny webbplats eller tjänst genom att finnas på AMO. Om beskrivningen för ditt tillägg handlar mer om tjänsten än om hur tillägget förbättrar användrens upplevelse är du förmodligen på fel spår.</p>
+
+<h3>Är tillägget fritt från olicensierade varumärken och upphovsrättsskyddad material?</h3>
+
+<p>Även on du inte vill skada ägaren till ett varumärke eller ett upphovsrättsskyddad verk så kan vi inte hysa tillägg som gör intrång på upphovsrätt eller varumärken. Om du inte har rätt att använda ett varumärkesskyddat namn eller en bild, låt bli att lägga upp ditt tillägg på AMO. Om ditt tillägg innehåller kod som är upphovsrättsskyddad av någon annan och inte är licensierad för att användas i ditt tilläg, låt bli att lägga upp ditt tillägg på AMO. (Om ägaren till ett varumärke eller ett upphovsrättsskyddad verk protesterar mot avnändning kommer vi med stor sannolikhet bli tvungna att låta jurister titta på borttagningsbegäran och vi kommer att ta bort tillägget om det bedöms vara nödvändigt. Detta är en dyr process som slösar med projektets resurser, inklusive tid och pengar, så vi ber dig vördnadsfullt att inte orsaka oss problem i onödan.)</p>
+
+<p>Om du är osäker på om namnet på ditt tillägg eller något i det kommer att hindra det från att listas på webbplatsen kan du fråga amo-editors@mozilla.org om råd (skriv på engelska). VIKTIGT: Denna grupp kan inte ge juridisk rådgivning och även om vi tycker att din användning är acceptabel kan vi ändra det beslutet vid eventuella klagomål från rättsinnehavare eller juridisk rådgivning.</p>
+
+<p>Vad det gäller återanvändning av källkod från andra tillägg; om författaren inte klart och tydligt gett dig tillstånd att använda dennes kod i ditt verk -- exempelvis genom att släppa den med en öppen källkods-licens -- bör du anta att du inte ha rrätt att göra det. Du kan kontakta författaren för att be om tillåtelse, men du får inga särskilda sådana rättigheter bara för att det funnits på AMO eller för att författaren inte svarar på din förfrågan. (Och, återigen, vi kan inte ge juridisk rådgivning, bara råd om hur ditt tillägg troligen samverkar med denna webbplats riktlinjer.)</p>
+
+
+<p>Detta gäller även Mozilla Foundations varumärken, inklusive "Mozilla", "Firefox" och "Thunderbird". Mozillas riktlinjer om hur varumärkena får användas är framtagen för att skydda mot förvirring och förhindrar att varumärkena förloras genom brist på skydd; vänligen respektera det skyddsbehovet och hjälp oss att bevara några av Mozilla Foundations mest värdefulla tillgångar.</p>
+
+<h2>Vad händer efter att jag nominerar något?</h2>
+
+<p>När ditt tillägg har blivit nominerat bedöms det av en grup av AMO redaktöra enligt kriterien beskrivna ovan. Om det bedöms vara redo att visas publikt flyttas det över till den publika sidan när det har utvärderats och du får besked via e-post.</p>
+
+<p>Om vi tycker att tillägget ännu inte är lämpligt för den publika sidan av AMO kommer du att få ett e-post som berättar varför och din nominering tas bort från kön. Om och när du tycker att du har åtgärdat de bekymmer som uttryckts i brevet, och du vill bli bedömd igen kan du göra det efter eget omdöme. Upprepade nomineringar utan meningsfulla förbättringar i tillägget ses inte med blida ögon, så använd omdömet; det är mer troligt att du gör oss arga än tröttar ut oss.</p>
+
+<h2>Kan jag nominera någon annans tillägg?</h2>
+
+<p>I dagsläget vill vi att författare nominerar sina egna tillägg för publicering. Vi vill vara säkra på att författaren är bekväm med den ökade exponeringen och att de tycker tillägget i dess nuvarande form återspeglar kvaliten på deras arbete korrekt. Om du tycker att ett tillägg är välpolerat, att författaren följer AMOs riktlinjer i ord och mening och att det skulle gynna Firefox, våra användare, och webben i allmänhet att göra det tillgängligt för nära hundra miljoner användare världen runt, så uppmuntra gärna författaren att nominera sin skapelse.</p>
+
+<h2>Mitt tillägg har funnits i nomineringskön länge, hatar ni mig?</h2>
+
+<p>Vi hatar dig inte. Vi älskar utvecklare av tillägg, och vi arbetar hårt för att göra dem glada och produktiva, så att användare världen runt kan dra nytta av deras arbete. Men att finnas på den publika sidan av AMO är värdefullt just för att vi är noggranna med vad som hamnar där, så vi kan inte skynda bara för att det ska gå snabbare. Vi förstår att det kan vara frustrerande att vänta på att ditt tillägg ska bli bedömt, och vi vill hålla väntetiden så kort som möjligt. Desto fler som ger noggranna och klara recensioner av tillägg i sandlådan, desto enklare är det att utföra dessa bedömningar, så du kan också överväga att hjälpa till på den sidan om du vill.</p>
+
+
+<h2>Jag hittade ett allvarligt fel i mitt tillägg, och jag vill verkligen få ut fixen så fort som möjligt. Vad ska jag göra?</h2>
+
+<p>Om det finns ett allvarligt fel (säkerhets, stabilitets, viktigt funktionalitetsproblem) i ett tillägg för vilket du behöver få ut en uppdatering snabbt bör du skriva det i "information till granskare" när du skickar in uppdateringen -- liksom i informationen för versionen, så klart! Du kan också vilja be några nuvarande användare av ditt tilläg att testa uppdateringen och rapportera resultatet utförligt i sandlådan. Att titta in i #addons på irc.mozilla.org kan hjälpa till att göra folk medvetna om situationen, men var tålmodig och artig om du gör det.</p>
+
+<p>Ropa inte varg. Vi försöker hantera högprioriterade uppdateringar snabbt, men det tar tid för oss som annars hade använts till att utvärdera andra nominerade tillägg eller versioner, och ofta offrar vi sömn eller tid med familj och vänner, så vi ser mörkt på folk som försöker utnyttja den här mekanismen för att "gå före i kön". Om du inte är säker på om du bör göra detta så kan du troligen få hjälp att bestämma dig genom att fråga i #addons på irc.mozilla.org.
+
+<h2>Jag tycker jag blev orättvist behandlad i utvärderingen av mitt tillägg. Vad ska jag göra?</h2>
+
+<p>Om du tycker ditt tillägg utvärderades inkorrekt, och att det felaktigt nekades att bli publikt, ska du skicka e-post till amo-editors@mozilla.org (skriv på engelska) och beskriva hur du resonerar. Var artig och tydlig i ditt brev, och se till att du har med specifika detaljer om hur ditt tillägg blev missbedömt.</p>
+
+<p>(Om du har fixat *alla* de saker som listades som problem i ditt besked ska du inte överklaga utvärderingen utan istället nominera om det med utvecklarverktygen.)</p>
+
+<h2>Mitt tillägg var publikt, och nu finns det bara i sandlådan. Vad hände? </h2>
+
+<p>Om ett tillägg inte längre uppfyller kriterien för att finnas på den publika sidan av webbplatsen kan vi komma att flytta tillbaka det till sandlådan. Om vi inte är juridiskt förhindrade från det kommer vi att berätta för dig vad som händer via e-post, och beskriva skälen att göra så.</p>
+
+<p>Det är också möjligt att du hittat ett fel på webbplatsen, i så fall bör du rapportera det via Bugzilla; använd "addons.mozilla.org"-produkten och "Public Pages"-komponenten för din rapport, och ta med så mycket information du kan.</p>
+
+<h2>Mitt tillägg är publikt, och folk verkar älska det. Hur kan jag få in det i listan av rekommenderade tillägg?</h2>
+
+<p>Om du tycker att ditt tillägg är ett utmärkt exempel på tilläggens möjligheter, som visar och utökar Mozillas värde för den flexibla och användarkontrollerade webben samt att det har en storartad användarupplevelse, så kan du be om att få det bedömt för att att hamna på listan med rekommenderade tillägg. För att göra detta ska du skicka e-post till amo-editors@mozilla.org (skriv på engelska) och förklara varför ditt tilläg är så bra.</p>
+
+<p>Ditt brev ska innehålla <b>åtminstone</b> information om följande:</p>
+<ul>
+<li>hur webbupplevelsen förbättras för användarna</li>
+<li>varför ditt tillägg är lämpligt för en stor del av Firefoxs användare</li>
+<li>hur ditt tillägg visar tjänar eller visar på Mozillaprojektets kärnvärden, särskilt avseende att ge användaren kontroll, säkerhet och integritet, universell tillgången till webben samt öppna standarder och data</li>
+<li>hur ditt tillägg skiljer sig från andra liknande tillägg (både på de sätt det är bättre och de sätt det är sämre)</li>
+<li>vilka reaktioner du sett från användare, recensenter, bloggare, astronauter, eller ditt husdjur, både positiva och negativa</li>
+</ul>
+
+<p>Ju mer utförlig information du ger i din förfrågan desto mer medgörliga blir vi i hanteringen och godkännandet av den, även om inte ens en underbart skriven och fullödig ansökan är någon garanti för att hamna i rekommenderat-listan. Till slut måste listan vara - och är - underhållen efter Mozillas omdöme, och användarupplevelse och -skydd måste trumfa allt annat.</p>
diff --git a/site/app/locale/sv_SE/pages/reviewguide.thtml b/site/app/locale/sv_SE/pages/reviewguide.thtml
new file mode 100644
index 0000000..f4adf03
--- /dev/null
+++ b/site/app/locale/sv_SE/pages/reviewguide.thtml
@@ -0,0 +1,70 @@
+<h1>Recensionsriktlinjer</h1>
+<p>Recensioner av tillägg är ett sätt för användare av webbplatsen att dela
+med sig sina åsikter om tilläggen de har installerade och använder. Redaktörer
+förbehåller sig rätten att neka eller ta bort alla recensioner som inte följer
+dessa riktlinjer.</p>
+
+<div class="corner-box">
+ <h2>Några tips för att skriva en utmärkt recension</h2>
+
+<h3><b>Se till att:</b></h3>
+<ul>
+<li>Skriv som om du berättar för en vän om hur du upplevt tillägget.</li>
+<li>Håll recensionerna koncisa och lättförstålig.</li>
+<li>Ge specifika och hjälpsamma detaljer, exempelvis:
+<ul>
+ <li>Fungerade tillägget som du förväntade dig?</li>
+ <li>Vilka finesser gillade du och ogillade?</li>
+ <li>Var det användbart?</li>
+ <li>Var det lättanvänt?</li>
+ <li>Kommer du att fortsätta använda detta tillägg?</li>
+</ul></li>
+
+<li>Ta en stund till att läsa din recension innan du skickar in den för att undvika generande stavfel eller grammatikfel.</li>
+
+<li>Undvik att göra hänvisning till tidsreferenser eftersom recensioner kan finnas på webbplatsen för lång tid framåt.</li>
+</ul>
+
+<h3><b>LÃ¥t bli att:</b></h3>
+<ul>
+<li>Skicka in triviala recensioner som "Toppen!", "underbart" eller "dåligt" utan ytterligare förklaring.</li>
+<li>Ge fel- eller problemrapporter i recensioner. Använd de tillgängliga hjälpmöjligheterna för respektive tillägg.</li>
+<li>Skriva recensioner av tillägg du inte själv har använt.</li>
+<li>Använda svårdomar, könsord eller språk som kan uppfattas som hatfullt.</li>
+<li>Inkludera HTML, länkar till skadlig programvara, källkod eller kodbitar. Recensioner är avsedda att vara enbart text.</li>
+<li>Göra falska påståenden, nedvärdera eller förolämpa tilläggsförfattare.</li>
+<li>Använda recensioner som ett sätt att be om hjälp för en särskild Firefox- (eller annan applikation) version.</li>
+<li>Inkludera e-postadress, telefonnummer eller annan personlig information om dig.</li>
+<li>Skriva recensioner för tillägg du eller din organisation skrivit eller representerar.</li>
+</ul>
+</div>
+
+<div class="corner-box">
+ <h2>Riktlinjer för betygsättning av tillägg</h2>
+
+<p>Betyg för tillägg bör vara rättvisa och ge en bra indikation på ett övergripande plan av tilläggets kvalitet och användbarhet. Ge det inte 5 stjänor bara för att du gillar det eller 1 för att du hatar det. Konsekvent betygsättning är en viktig del av alla recensioner.</p>
+
+<ul>
+<li><b>5 stjärnor: Utmärkt.</b> Inte nog med att det gör allt det påstår, det är också väsentligt mycket mer användbart än många andra tillägg. Det här tillägget kommer nog att bli ett av de du använder mest och du rekommenderar det starkt.</li>
+<li><b>4 stjärnor: Bra.</b> Användbart och lättanvänt, även om det inte nödvändigtvis är särskilt speciellt. Detta tillägg rekommenderas men kan vara mer lämpat för vissa användare än andra.</li>
+<li><b>3 stjärnor: OK.</b> Kan ha vissa designmissar och/eller saknade finesser. De problem det har är inte stora nog för att avråda från användning och en del personer kan tycka att det är användbart. Rekommenderas för de som har behov avdet och är villiga att testa.</li>
+<li><b>2 stjärnor: Sämre.</b> Tillägget har låg kvalitet, användbarhet eller gör helt enkelt inte det de utger sig för. Du avråder från detta tillägg men håller med om att det kan ha visst värde för en del användare.</li>
+<li><b>1 stjärna: Dåligt.</b> Tillägget fungerar inte ordentligt eller är helt utan användingsområde. Du kan inte tänka dig någon anledning varför någon ska testa det och avråder helt från att använda det.</li>
+</ul>
+
+<p>Det är inget fel med att ge ett tillägg en perfekt eller hemsk recension, beskriv bara varför du gör det. Stjärnorna betyder inget om du inte berättar varför.</p>
+</div>
+
+<div class="corner-box">
+ <h2>Ofta ställda frågor om recensioner</h2>
+
+<h3>Hur kan jag rapportera en problematisk recension?</h3>
+<p>Rapportera elle flagga tveksamma recensioner genom att klicka på "Rapportera recensionen" och den kommer att läggas i kö för moderering. Redaktörer kommer att använda recensionsriktlinjerna för att utvärdera om recensionen ska tas bort eller läggas tillbaka.</p>
+
+<h3>Jag är tilläggsförfattare, kan jag svara på recensioner?</h3>
+<p>Ja, författare till tillägg kan ge ett enda svar på en recension. Ytterligare diskussion eller uppföljning bör flyttas till ett hjälpforum eller en diskussionsgrupp.</p>
+
+<h3>Jag är tilläggsförfattare, kan jag ta bort negativa recensioner eller betyg?</h3>
+<p>Generellt sett, nej. Men om recensionen inte följer riktlinjerna ovanför kan du klicka "Rapportera recensionen" och få den modererad av en redaktör.
+Om en recension innehåller ett klagomål som inte längre är aktuellt efter att du släppt en ny version av ditt tillägg kan vi överväga att ta bort recensionen. Skicka en detaljerad begäran till amo-editors@mozilla.org (skriv på engelska).</p>
+</div>
diff --git a/site/app/locale/sv_SE/pages/sandbox.thtml b/site/app/locale/sv_SE/pages/sandbox.thtml
new file mode 100644
index 0000000..735a9e8
--- /dev/null
+++ b/site/app/locale/sv_SE/pages/sandbox.thtml
@@ -0,0 +1,15 @@
+<h1>Sandlådans granskningssystem</h1>
+<h2>Vad är sandlådan?</h2>
+<p>Sandlådan är en plats där avancerade användare kan testa tillägg innan de granskas och godkänns för allmän användning. För att komma åt sandlådan måste du aktivera den i dina kontoinställningar. Försiktighet bör iakttas vid installation av tillägg från sandlådan då de inte har testats av en redaktör och kan skada din dator.</p>
+
+<h2>Hur får jag mitt tillägg på den publika sidan?</h2>
+<!-- To localize the flowchart image, see http://wiki.mozilla.org/Update:Remora_Sandbox_Flowchart -->
+<div style="text-align: center;">%s</div>
+<ol>
+ <li><b>Skicka in ditt tillägg med Utvecklarverktygen.</b> Ditt bidrag kommer omedelbart att dyka upp på "sandlådesidan" av Mozilla Add-ons, där erfarna användare kommer att testa det och ge kommentarer. För att se sandlådan måste du slå på det i dina kontoinställningar.</li>
+ <li><b>Nominera ditt tillägg till att bli publikt.</b> Bland utvecklarverktygen finns det en länk för att nominera ditt tillägg. Efter att det blivit nominerat kommer ditt tillägg att placeras i redaktörernas nomineringskö för granskning.</li>
+ <li><b>En redaktör granskar ditt tillägg.</b> En redaktör för Mozilla Add-ons installerar ditt tillägg och testar att det fungerar. Redaktören kommer även att läsa recensionerna det fått av testarna i sandlådan.</li>
+ <li><b>Ditt tillägg blir publikt eller hålls kvar i sandlådan.</b>
+Redaktören kommer antingen att göra ditt tillägg publikt eller hålla kvar det i sandlådan. Om det hålls kvar i sandlådan kan du nominera det igen efter att göra ändringar som redaktören föreslår i kommentarer.
+Om det görs publikt kommer framtida versioner av ditt tillägg att dyka upp i sandlådan tills de har granskats av en redaktör och gjorts publika. När ditt tillägg blivit publikt behöver du inte nominera det igen - framtida versioner placeras automatiskt i kön för granskningar.</li>
+</ol>
diff --git a/site/app/locale/sv_SE/pages/statistics_help.thtml b/site/app/locale/sv_SE/pages/statistics_help.thtml
new file mode 100644
index 0000000..54d19e5
--- /dev/null
+++ b/site/app/locale/sv_SE/pages/statistics_help.thtml
@@ -0,0 +1,7 @@
+<h3>Hjälp</h3>
+<p>Statistikbrädan visar nedladdningar och pingdata ihopsamlat för ditt tillägg.</p>
+<h4>Nedladdningar</h4>
+<p>Nedladdningsräknare uppdateras varje dag och inkluderar bara ursprungliga nedladdningar av tillägg, inte uppdateringar.</p>
+
+<h4>Uppdateringspingar</h4>
+<p>Tillägg nedladdade från denna webbplats kontrolleras för uppdateringar en gång per dag och det totala antalet sådana uppdateringspingar kallas Aktiva Dagliga Användare. Aktiva Dagliga Använda (ADA) kan brytas ner på tilläggsversion, operativsystem, tilläggsstatus och applikation. Dessa data samlas för närvarande in under en dag varje vecka, på onsdagar.</p>
diff --git a/site/app/locale/sv_SE/pages/submission_help.thtml b/site/app/locale/sv_SE/pages/submission_help.thtml
new file mode 100644
index 0000000..e7e50ad
--- /dev/null
+++ b/site/app/locale/sv_SE/pages/submission_help.thtml
@@ -0,0 +1,35 @@
+<h1>Hjälp för inskickning av tillägg</h1>
+Obligatoriska fält är markerade med <b>fetstil</b>. Frivilliga fält skrivs med <i>italic</i>.
+<h2 id="step1">Steg 1: Uppladdning</h2>
+<ul class="submissionHelp">
+ <li><span class="required">Tilläggstyp</span> - Som standard bestäms tilläggstypen automatiskt utifrån den uppladdade filen. Du borde inte behöva ändra det här fältet.</li>
+ <li><span class="required">Tilläggsfil</span> - Paketfilen för ditt tillägg, komplett med en install.rdf-fil. Om filen bara fungerar på en specifik plattofrm kan du ladda upp flera filer samtidigt genom att välja den plattformen.</li>
+ <li><span class="optional">Ikonfil</span> - Ikonfilen visas bredvid tilläggsnamnet på visningssidan samt i installationsdialogen. Den kommer automatiskt att skalas om till 32x32 pixlar med bibehållet bildformat.</li>
+ <li><span class="required">Standardlokal</span> - Ett tilläggs standardlokal är dess huvudlokal. Om en användares valda lokal inte är tillgängliga för tillägget kommer översättningen från standardlokalen att användas.</li>
+ <li><span class="optional">Hoppa över Granska nuvarande tilläggsinformation</span> - Om du uppgraderar ett existerande tillägg kommer detta fält att synas. Kryssar du i rutan hoppar du över steg 3 där du kan skriva in versionsspecifik information.</li>
+</ul>
+
+<h2 id="step2">Steg 2: Tilläggsdetaljer</h2>
+<ul class="submissionHelp">
+ <li><span class="required">Namn</span> - Namn på tillägget i dess standardlokal.</li>
+ <li><span class="required">Författare</span> - Alla användare som har åtkomst att ändra tilläggets listning och som listas som författare på visningssidan.</li>
+ <li><span class="required">Kategorier</span> - Kategorier tillämpliga för detta tillägg.</li>
+ <li><span class="optional">Hemsida</span> - Tilläggets webbsida i standardlokalen.</li>
+ <li><span class="required">Sammanfattning</span> - En kort sammanfattning av tillägget i standardlokalen. Detta fält tillåter max 250 tecken och kommer att visas på tilläggets visningssida liksom i sök/bläddra-resultat.</li>
+ <li><span class="required">Beskrivning</span> - En beskrivning av tillägg i standardlokan. Detta visas på tilläggets visningssida under sammanfattningen.</li>
+ <li><span class="optional">Användarlicensavtal</span> - Användarlicensavtalet som användare måste godkänna innan de hämtar hem tillägget, i standardlokalen.</li>
+ <li><span class="optional">Integritetsriktlinjer</span> - Tilläggets integritetsriktlinjer, i standardlokalen. Integritetsriktlinjer förklarar hur användarend personliga information hanteras och länkas in bredvid Installera-knappen på tilläggets visningssida. Ytterligare information om vad som bör ingå i en integritetsriktlinjer och om ditt tillägg kräver en finns på <a href="%s">Add-ons Riktlinjer</a>.</li>
+ <li><span class="optional">Tillåt användare att se källkodsfilerna direkt</span> - Kryssas denna ruta i kan användarna bläddra i ditt tilläggs källkodsfiler direkt på nätet.</li>
+ <li><span class="optional">Det här är en förhandsversion</span> - Kryssas denna ruta i indikerar det att tillägget är en förhands- eller "beta"-version. Förhandsversioner av tillägg bör stanna i sandlådan och kan inte nomineras för att bli publika innan den här flaggan har tagits bort.</li>
+ <li><span class="optional">Det här är ett webbplatsspecifikt tillägg</span> - Kryssas denna ruta i indikerar det att tillägget är specifikt för en enskild webbplats, exempelvis ett tillägg som ändrar en speciell webbplats utseende eller visar innehåll från en särskild webbplats. Detta fält hjälper redaktörerna och kan komma att användas för filtersökningar i framtiden.</li>
+ <li><span class="optional">Detta tillägg kräver extern programvara</span> - Kryssas denna ruta i indikerar det att tillägget kräver extern programvara. Detta fält hjälper redaktörerna och kan komma att användas för filtersökningar i framtiden.</li>
+</ul>
+
+<h2 id="step3">Steg 3: Versionsdetaljer</h2>
+<ul class="submissionHelp">
+ <li><span class="required optional">Versionsdetaljer</span> - En sammanfattning eller lista över ändringar i denna version. Detta är valfritt för nya tillägg, men krävs för uppdateringar.</li>
+ <li><span class="optional">Information till granskare</span> - Det här fält används för att ge information till redaktörer som granskar ditt tillägg. Information om testkonton och särskild information bör placeras här.</li>
+</ul>
+
+<h2 id="step4">Steg 4: Lokalisering</h2>
+Här kan tilläggets fält lokaliseras för alla stödda lokaler. Klicka bara på en lokal för att skriva in översättningar.
diff --git a/site/app/locale/tr/LC_MESSAGES/messages.mo b/site/app/locale/tr/LC_MESSAGES/messages.mo
new file mode 100644
index 0000000..02ef67c
--- /dev/null
+++ b/site/app/locale/tr/LC_MESSAGES/messages.mo
Binary files differ
diff --git a/site/app/locale/tr/LC_MESSAGES/messages.po b/site/app/locale/tr/LC_MESSAGES/messages.po
new file mode 100644
index 0000000..2f5d570
--- /dev/null
+++ b/site/app/locale/tr/LC_MESSAGES/messages.po
@@ -0,0 +1,9193 @@
+# Remora Preliminary Language File
+# Copyright (C) 2006 Mozilla Corporation
+# This file is distributed under the same license as the REMORA package.
+# Wil Clouser <clouserw@mozilla.com>, 2006.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: REMORA 0.1\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2009-01-16 11:45-0800\n"
+"PO-Revision-Date: 2007-01-23 13:55+0200\n"
+"Last-Translator: Ahmet Serkan Tıratacı, Adem Alp Yıldız, Murat Serdar "
+"Alperen\n"
+"Language-Team: Turkish (Türkçe)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+
+#: views/addons/policy.thtml:98
+msgid "a_cancel_installation"
+msgstr "Cancel Installation"
+
+#. This is the text that appears on buttons to download add-ons.
+#. %$1s is an optional string that only appears if the add-on is only available for
+#. a certain platform. Examples: (Windows) or (Linux)
+#. Note that the parentheses are included in the string. :(
+#: views/elements/amo2009/install.thtml:126
+#: views/elements/amo2009/install.thtml:227
+#: views/elements/amo2009/install.thtml:257
+#: views/elements/amo2009/install.thtml:300
+#: views/elements/amo2009/install.thtml:312 views/elements/install.thtml:73
+#: views/elements/install.thtml:181 views/elements/install.thtml:205
+#: views/elements/install.thtml:248 views/elements/install.thtml:260
+#: views/addons/plugins.thtml:66 views/addons/plugins.thtml:76
+#: views/addons/plugins.thtml:86 views/addons/plugins.thtml:96
+#: views/addons/plugins.thtml:119
+#, fuzzy, php-format
+msgid "a_download"
+msgstr "Download Now %s"
+
+#: views/addons/policy.thtml:72
+#, fuzzy
+msgid "a_eula_download"
+msgstr "Accept and Download"
+
+#: views/addons/policy.thtml:74
+msgid "a_eula_install"
+msgstr "Accept and Install"
+
+#: views/elements/header.thtml:76 views/elements/header.thtml:82
+#: views/api/api_addon.thtml:55 views/api/collections_feed.thtml:75
+#: views/sharing_api/addon.thtml:64
+msgid "a_header_public"
+msgstr "Public"
+
+#: views/elements/header.thtml:58 views/elements/header.thtml:75
+#: views/elements/header.thtml:80 views/api/api_addon.thtml:57
+#: views/api/collections_feed.thtml:77 views/sharing_api/addon.thtml:66
+msgid "a_header_sandbox"
+msgstr "Sandbox"
+
+#. %s is a date in the _('date') format
+#: views/elements/amo2009/homepage_addon.thtml:115
+#: views/elements/addon_listitem.thtml:122 views/elements/feature.thtml:106
+#: views/addons/display.thtml:104 views/addons/browse_thumbs.thtml:73
+#, fuzzy
+msgid "addon_detail_last_updated"
+msgstr "Updated %s"
+
+#. %s is the version of the add-on. Example: 3.2a1
+#: views/elements/amo2009/addon_version_detail.thtml:51
+#: views/elements/addon_version_detail.thtml:51
+#, php-format
+msgid "addon_display_header_version"
+msgstr "%s sürümü"
+
+#: views/addons/browse_thumbs.thtml:80
+#, fuzzy
+msgid "addon_downloads"
+msgstr "downloads"
+
+#: views/addons/display.thtml:147
+#, fuzzy
+msgid "addon_downloads_total"
+msgstr "total downloads"
+
+#: views/elements/amo2009/homepage_addon.thtml:106
+#: views/elements/addon_listitem.thtml:115 views/elements/feature.thtml:101
+#: views/addons/category_landing.thtml:157 views/addons/display.thtml:146
+#: views/addons/browse_thumbs.thtml:80
+#, fuzzy
+msgid "addon_downloads_weekly"
+msgstr "weekly downloads"
+
+# %1 is the add-on count, %2 the category name
+#. %1 is the add-on count, %2 the category name
+#: views/addons/browse_thumbs.thtml:104 views/addons/browse.thtml:60
+#, fuzzy, php-format
+msgid "addon_list_category_totalcount"
+msgid_plural "addon_list_category_totalcount"
+msgstr[0] "%1$s \"%2$s\" add-on"
+msgstr[1] "%1$s \"%2$s\" add-ons"
+
+#: views/elements/amo2009/addon_list_options.thtml:103
+#: views/elements/pagination.thtml:67
+#: views/elements/addon_list_options.thtml:94
+#, fuzzy
+msgid "addon_list_perpage"
+msgstr "per page"
+
+#: views/elements/amo2009/addon_list_options.thtml:84
+#: views/elements/addon_list_options.thtml:98
+#, fuzzy
+msgid "addon_list_sortby"
+msgstr "Sort by:"
+
+#: views/helpers/addons_html.php:568 views/elements/amo2009/install.thtml:321
+#: views/elements/feature.thtml:89
+#, fuzzy
+msgid "addon_listitem_flag_experimental"
+msgstr "experimental"
+
+#: views/helpers/addons_html.php:570
+#, fuzzy
+msgid "addon_listitem_flag_recommended"
+msgstr "recommended"
+
+# %1 is the addon name, %2 is the platform
+#. %1 is the add-on name, %2 is the platform
+#: views/pages/js_constants.js.thtml:66
+#, fuzzy
+msgid "addon_not_available_for_platform"
+msgstr "%1$s is not available for %2$s."
+
+# %1 is the addon name
+#. %1 is the add-on name
+#: views/addons/policy.thtml:101 views/addons/previews.thtml:60
+#: views/addons/versions.thtml:130 views/reviews/flag.thtml:61
+#: views/reviews/add.thtml:114 views/reviews/display.thtml:216
+#: views/reviews/review_added.thtml:57
+#, php-format
+msgid "addon_review_a_back_to_addon_x"
+msgstr "%1$s... eklentisine geri dön"
+
+# %1 is the addon name
+#. %1 is the add-on name
+#: views/reviews/flag.thtml:60 views/reviews/add.thtml:113
+#: views/reviews/review_added.thtml:56
+#, php-format
+msgid "addon_review_a_back_to_reviews"
+msgstr "Görüşlere geri dön..."
+
+#: views/reviews/add.thtml:85
+msgid "addon_review_add_rating_field"
+msgstr "BeÄŸeni:"
+
+#: views/reviews/add.thtml:102
+msgid "addon_review_add_review_field"
+msgstr "Ä°nceleme:"
+
+#: views/reviews/add.thtml:107
+msgid "addon_review_add_submit"
+msgstr "Görüşü gönder"
+
+#. %s is the name of the add-on
+#: views/reviews/add.thtml:51
+#, php-format
+msgid "addon_review_add_title"
+msgstr "%s hakkında görüş ekle"
+
+#: views/reviews/add.thtml:78
+msgid "addon_review_add_title_field"
+msgstr "Başlık/Özet:"
+
+#: views/reviews/display.thtml:77 views/reviews/display.thtml:161
+#, fuzzy
+msgid "addon_review_admin_delete"
+msgstr "Delete"
+
+#: views/reviews/display.thtml:76
+#, fuzzy
+msgid "addon_review_author_reply_link"
+msgstr "Reply"
+
+#: views/reviews/delete.thtml:62
+#, fuzzy
+msgid "addon_review_confirm_delete"
+msgstr "Are you sure you wish to delete this review?"
+
+#: views/reviews/delete.thtml:63
+#, fuzzy
+msgid "addon_review_confirm_no"
+msgstr "No"
+
+#: views/reviews/delete.thtml:64
+#, fuzzy
+msgid "addon_review_confirm_yes"
+msgstr "Yes"
+
+#: views/reviews/delete.thtml:48
+#, fuzzy
+msgid "addon_review_delete_header"
+msgstr "Delete Review"
+
+#: controllers/reviews_controller.php:449
+#, fuzzy
+msgid "addon_review_deleted_successfully"
+msgstr "Review deleted successfully."
+
+#. %s is the name of the add-on
+#: views/reviews/add.thtml:51
+#, php-format
+msgid "addon_review_edit_title"
+msgstr "%s hakkındaki görüşü düzenle"
+
+# %1 is the count of characters entered as notes for the review flag reason.
+#. %1 is the count of characters entered as notes for the review flag reason.
+#: controllers/reviews_controller.php:539
+#, fuzzy
+msgid "addon_review_flag_error_other_length"
+msgstr ""
+"Problem flagging review: Notes for flagged reviews are limited to between 10 "
+"and 100 characters; your character length was %1$s."
+
+#. Removing an extra comma
+#: views/reviews/review_added.thtml:53
+#, fuzzy
+msgid "addon_review_in_moderation"
+msgstr ""
+"Please note: Before your review shows up on the public site, it will be "
+"moderated by an editor."
+
+#: views/reviews/add.thtml:57
+#, fuzzy
+msgid "addon_review_in_reply_to"
+msgstr "Developer reply to:"
+
+# %1 is the review count, %2 is the nickname or full name of the user.
+#. %1 is the review count, %2 is the nickname or full name of the user.
+#: views/reviews/display.thtml:131
+#, fuzzy, php-format
+msgid "addon_review_others_by_user"
+msgid_plural "addon_review_others_by_user"
+msgstr[0] "See %1$s previous review submitted by %2$s for this add-on."
+msgstr[1] "See %1$s previous reviews submitted by %2$s for this add-on."
+
+# %1 is the addon name
+#. %1 is the add-on name
+#: controllers/reviews_controller.php:201
+#: controllers/reviews_controller.php:250
+#: controllers/reviews_controller.php:345
+#: controllers/reviews_controller.php:424
+#, php-format
+msgid "addon_review_pagetitle"
+msgstr "%s incelemeleri"
+
+# %1 is the user, %2 is the (localized) date
+#. %1 is the user, %2 is the (localized) date
+#: views/reviews/display.thtml:160
+#, fuzzy, php-format
+msgid "addon_review_reply_on_x_by_y"
+msgstr "Reply by %1$s on %2$s"
+
+#: views/reviews/display.thtml:157
+#, fuzzy
+msgid "addon_review_reply_prefix"
+msgstr "Developer Reply:"
+
+#: views/reviews/review_added.thtml:51
+msgid "addon_review_saved_successfully"
+msgstr "Görüşünüz başarıyla kaydedildi. Teşekkürler!"
+
+#: views/addons/display.thtml:354 views/reviews/display.thtml:72
+#, fuzzy
+msgid "addon_reviewed_by_u_on_d"
+msgstr "by %1$s on %2$s"
+
+# %1 is the (localized) date, y is the rating
+#. %1 is the user, %2 is the (localized) date, %3 is the rating
+#: views/editors/reviews_queue.thtml:57 views/editors/reviews_queue.thtml:68
+#: views/reviews/add.thtml:63 views/reviews/delete.thtml:54
+#, php-format
+msgid "addon_reviewed_on_x_rated_y"
+msgstr " %1$s tarihinde ,%2$d izlendi"
+
+#: views/elements/amo2009/addon_version_detail.thtml:52
+#: views/elements/addon_version_detail.thtml:52
+#, fuzzy
+msgid "addon_version_permalink"
+msgstr "Permanent link to this version"
+
+# %1 is the current Application name (e.g. Firefox)
+# %2 is the Application's version number
+#. %1 is the current Application name (e.g. Firefox)
+#. %2 is the Application's version number
+#: views/addons/versions.thtml:140
+#, fuzzy
+msgid "addon_versions_getlatestversion"
+msgstr "The most recent version compatible with %1$s %2$s"
+
+#: views/addons/display.thtml:447
+#, fuzzy
+msgid "addons_author_addons_submit"
+msgstr "Go"
+
+#: views/elements/amo2009/homepage_addon.thtml:100
+#: views/elements/feature.thtml:95
+#, fuzzy
+msgid "addons_author_tooltip"
+msgstr "View Author's Profile"
+
+# %1 is the name of the Application (eg. Firefox)
+#. %1 is the name of the Application (eg. Firefox)
+#: controllers/addons_controller.php:1296
+#, fuzzy
+msgid "addons_browse_all_themes_title"
+msgstr "Browse all Themes :: %1$s Add-ons"
+
+#. %s is the name of the category
+#: controllers/addons_controller.php:1016
+#, php-format
+msgid "addons_browse_browse_category"
+msgstr "%s gözat"
+
+# %1 is the name of the theme category (eg. Modern)
+# %2 is the name of the Application (eg. Firefox)
+#. %1 is the name of the theme category (eg. Modern)
+#. %2 is the name of the Application (eg. Firefox)
+#: controllers/addons_controller.php:664
+#, fuzzy
+msgid "addons_browse_categories_header_theme"
+msgstr "Browse %1$s Themes :: %2$s Add-ons"
+
+#: views/addons/display.thtml:249
+#, fuzzy
+msgid "addons_display_a_license_what"
+msgstr "What's this?"
+
+#: views/reviews/display.thtml:222
+msgid "addons_display_add_review"
+msgstr "Görüş ekle"
+
+#: views/addons/display.thtml:294
+#, fuzzy
+msgid "addons_display_advanced_details"
+msgstr "Advanced Details"
+
+#: views/addons/display.thtml:98
+#, fuzzy
+msgid "addons_display_categories"
+msgstr "Categories"
+
+#: views/addons/display.thtml:482
+#, fuzzy
+msgid "addons_display_collection_add"
+msgstr "Add to a collection:"
+
+#: views/addons/display.thtml:491
+#, fuzzy
+msgid "addons_display_collection_add_new"
+msgstr "New Collection..."
+
+#: views/addons/display.thtml:487
+#, fuzzy
+msgid "addons_display_collection_add_select_one"
+msgstr "Select a collection..."
+
+#: views/addons/display.thtml:493
+#, fuzzy
+msgid "addons_display_collection_add_submit"
+msgstr "Publish"
+
+#. %1$s is the add-on name
+#. %2$s is the collection name, linked to the collection's page
+#: views/pages/js_constants.js.thtml:103 views/addons/display.thtml:61
+#, fuzzy
+msgid "addons_display_collection_publish_success"
+msgstr "%1$s has been added to the %2$s collection."
+
+#: views/addons/display.thtml:483
+#, fuzzy
+msgid "addons_display_collection_whatsthis"
+msgstr "What's this?"
+
+#. %1$s is a number
+#: views/addons/display.thtml:473
+#, fuzzy
+msgid "addons_display_collections_more"
+msgid_plural "addons_display_collections_more"
+msgstr[0] "and %1$s more collection"
+msgstr[1] "and %1$s more collections"
+
+#: views/addons/display.thtml:403
+#, fuzzy
+msgid "addons_display_detailed_review"
+msgstr "detailed review"
+
+#: views/reviews/add.thtml:89 views/reviews/add.thtml:90
+#, fuzzy
+msgid "addons_display_dont_like_it"
+msgstr "Don't like it"
+
+#: views/reviews/display.thtml:220
+msgid "addons_display_edit_review"
+msgstr "Görüşü düzenle"
+
+#: views/addons/display.thtml:132
+msgid "addons_display_has_privacy"
+msgstr "This add-on has a privacy policy."
+
+#: views/reviews/add.thtml:87 views/reviews/add.thtml:88
+#, fuzzy
+msgid "addons_display_hate_it"
+msgstr "Hate it"
+
+#: views/addons/display.thtml:462
+#, fuzzy
+msgid "addons_display_header_collections"
+msgstr "Related Collections"
+
+#: views/addons/display.thtml:297
+msgid "addons_display_header_developer_comments"
+msgstr "Developer Comments"
+
+#: views/addons/display.thtml:230
+#, fuzzy
+msgid "addons_display_header_homepage"
+msgstr "Homepage"
+
+#: views/addons/display.thtml:247 views/addons/versions.thtml:110
+#, fuzzy
+msgid "addons_display_header_license"
+msgstr "Source Code License"
+
+#: views/addons/display.thtml:337
+msgid "addons_display_header_reviews"
+msgstr "Görüşler"
+
+#: views/addons/display.thtml:261
+#, fuzzy
+msgid "addons_display_header_support"
+msgstr "Support"
+
+#: views/reviews/add.thtml:91 views/reviews/add.thtml:92
+#, fuzzy
+msgid "addons_display_like_it"
+msgstr "Like it"
+
+#: views/addons/display.thtml:210
+#, fuzzy
+msgid "addons_display_long_description"
+msgstr "Long Description"
+
+#: views/reviews/add.thtml:95 views/reviews/add.thtml:96
+#, fuzzy
+msgid "addons_display_love_it"
+msgstr "Love it"
+
+#: views/addons/display.thtml:178
+#, fuzzy
+msgid "addons_display_more_images"
+msgstr "More Images"
+
+#: views/addons/display.thtml:465
+#, fuzzy
+msgid "addons_display_nocollections"
+msgstr "This add-on is not yet in any collections."
+
+# %1$s is either an author's name or a comma separated list of authors. Using
+# the list doesn't make sense in the English plural form so we ignore the
+# variable.
+#. %1$s is either an author's name or a comma separated list of authors. Using
+#. the list doesn't make sense in the English plural form so we ignore the
+#. variable.
+#: views/addons/display.thtml:436
+#, fuzzy
+msgid "addons_display_other_addons_by"
+msgid_plural "addons_display_other_addons_by"
+msgstr[0] "Other add-ons by %1$s"
+msgstr[1] "Other add-ons by these authors"
+
+#. %s is the name of the add-on and the add-on section. Example:
+#. Some Add-on :: Firefox Add-ons
+#. This should not be concatenated in the code and should be fixed.
+#: controllers/addons_controller.php:141 controllers/addons_controller.php:280
+#: controllers/addons_controller.php:1442
+#, php-format
+msgid "addons_display_pagetitle"
+msgstr "%s"
+
+#. %s is an email address
+#: views/addons/display.thtml:286
+#, fuzzy, php-format
+msgid "addons_display_paragraph_supportinfoemail"
+msgstr ""
+"Support for this Extension is available at %s.If you have a bug report it "
+"might be best to file it with the developer so that that they can follow up "
+"with you. Reviews are not really the place for detailed bug reports, and the "
+"developer may require several details in order to re-create the bug. Since "
+"we do not make your email address available to extension developers when you "
+"post a review, they will not be able to contact you to ask for more details "
+"or let you know if the bug has been fixed in an upcoming version."
+
+#. %$1s is a URL
+#. %$2s is an email address
+#: views/addons/display.thtml:269
+#, fuzzy, php-format
+msgid "addons_display_paragraph_supportinfoemailurl"
+msgstr ""
+"Support for this Extension is available at %s or %s. If you have a bug "
+"report it might be best to file it with the developer so that that they can "
+"follow up with you. Reviews are not really the place for detailed bug "
+"reports, and the developer may require several details in order to re-create "
+"the bug. Since we do not make your email address available to extension "
+"developers when you post a review, they will not be able to contact you to "
+"ask for more details or let you know if the bug has been fixed in an "
+"upcoming version."
+
+#. %s is a URL
+#: views/addons/display.thtml:278
+#, fuzzy, php-format
+msgid "addons_display_paragraph_supportinfourl"
+msgstr ""
+"Support for this Extension is available at %s. If you have a bug report it "
+"might be best to file it with the developer so that that they can follow up "
+"with you. Reviews are not really the place for detailed bug reports, and the "
+"developer may require several details in order to re-create the bug. Since "
+"we do not make your email address available to extension developers when you "
+"post a review, they will not be able to contact you to ask for more details "
+"or let you know if the bug has been fixed in an upcoming version."
+
+#: views/addons/display.thtml:383
+#, fuzzy
+msgid "addons_display_rate_it"
+msgstr "Rate It"
+
+#: views/reviews/add.thtml:93 views/reviews/add.thtml:94
+#, fuzzy
+msgid "addons_display_really_like_it"
+msgstr "Really like it"
+
+#: views/addons/display.thtml:410
+#, fuzzy
+msgid "addons_display_review_etiquette"
+msgstr ""
+"Please do not post bug reports in reviews. We do not make your email address "
+"available to add-on developers and they may need to contact you to help "
+"resolve your issue."
+
+# %1 is the review guidelines link
+#. %1 is the review guidelines link
+#: views/addons/display.thtml:417
+#, fuzzy
+msgid "addons_display_review_guidelines_link"
+msgstr "<a href=\"%s\">Review Guidelines</a>"
+
+# %1 is the support section link
+#. %1 is the support section link
+#: views/addons/display.thtml:414
+#, fuzzy
+msgid "addons_display_review_see_support"
+msgstr ""
+"See the <a href=\"%1$s\">support section</a> to find out where to get "
+"assistance for this add-on."
+
+#: views/addons/display.thtml:404
+#, fuzzy
+msgid "addons_display_review_submit"
+msgstr "Save"
+
+#: views/addons/display.thtml:430
+#, fuzzy, php-format
+msgid "addons_display_see_all_addons"
+msgstr "See All %1$s Add-ons"
+
+# %1 is the number of reviews
+#. %1 is the number of reviews
+#: views/addons/display.thtml:364
+#, php-format
+msgid "addons_display_see_all_reviews"
+msgstr "Tüm incelemelere bak (%1$s)"
+
+#: views/addons/display.thtml:219
+#, fuzzy
+msgid "addons_display_see_all_versions"
+msgstr "See All Versions"
+
+#: views/addons/display.thtml:321 views/addons/versions.thtml:117
+msgid "addons_display_view_source"
+msgstr "View the source"
+
+#: views/addons/display.thtml:324
+#, fuzzy
+msgid "addons_display_view_stats"
+msgstr "View statistics"
+
+#: views/addons/display.thtml:376
+#, fuzzy
+msgid "addons_display_what_do_you_think"
+msgstr "What do you think?"
+
+#: views/elements/app_compatibility.thtml:49
+#, fuzzy
+msgid "addons_display_workswith"
+msgstr "Works with:"
+
+#: views/addons/home.thtml:112
+#, fuzzy
+msgid "addons_home_browse_new"
+msgstr "Just Added"
+
+#: views/addons/home.thtml:110
+#, fuzzy
+msgid "addons_home_browse_popular"
+msgstr "Popular"
+
+#: views/addons/home.thtml:108
+#, fuzzy
+msgid "addons_home_browse_recommended"
+msgstr "Recommended"
+
+#: views/addons/home.thtml:127 views/addons/home.thtml:134
+#: views/addons/home.thtml:141 views/addons/home.thtml:148
+#, fuzzy
+msgid "addons_home_browse_subscribe"
+msgstr "Subscribe"
+
+#: views/addons/home.thtml:101
+#, fuzzy
+msgid "addons_home_browse_title"
+msgstr "Browse Add-ons"
+
+#: views/addons/home.thtml:114
+#, fuzzy
+msgid "addons_home_browse_updated"
+msgstr "Updated"
+
+#: views/elements/amo2009/homepage_addon.thtml:100
+#: views/elements/addon_discussionheader.thtml:83
+#: views/elements/addon_listitem.thtml:109 views/elements/feature.thtml:95
+#: views/addons/category_landing.thtml:66 views/addons/policy.thtml:57
+#: views/addons/display.thtml:70 views/addons/home.thtml:178
+msgid "addons_home_by"
+msgstr "Yazan:"
+
+#: views/addons/home.thtml:169
+#, fuzzy
+msgid "addons_home_collection_popular_title"
+msgstr "Popular Collections"
+
+#: views/elements/amo2009/categories.thtml:69 views/addons/home.thtml:160
+#, fuzzy
+msgid "addons_home_collections"
+msgstr "Collections"
+
+#. %1$s is the count of addons in a collection
+#: views/elements/amo2009/collection_listing_item.thtml:51
+#: views/addons/home.thtml:185
+#, fuzzy
+msgid "addons_home_collections_addon_count"
+msgid_plural "addons_home_collections_addon_count"
+msgstr[0] "<strong>%1$s</strong> add-on"
+msgstr[1] "<strong>%1$s</strong> add-ons"
+
+#: views/addons/home.thtml:196
+#, fuzzy
+msgid "addons_home_collections_all"
+msgstr "View All Collections"
+
+#: views/addons/home.thtml:162
+#, fuzzy
+msgid "addons_home_collections_intro"
+msgstr ""
+"Collections are a way for you to categorize, mix, match and mingle add-ons. "
+"Subscribe to collections created by other users or create your own."
+
+#. %1$s is the count of subscribers for a collection
+#: views/elements/amo2009/collection_listing_item.thtml:58
+#: views/collections/detail.thtml:96 views/addons/home.thtml:189
+#, fuzzy
+msgid "addons_home_collections_subscribers"
+msgid_plural "addons_home_collections_subscribers"
+msgstr[0] "<strong>%1$s</strong> subscriber"
+msgstr[1] "<strong>%1$s</strong> subscribers"
+
+#: views/addons/searchengines.thtml:54 views/addons/themes_landing.thtml:49
+msgid "addons_home_feature_head"
+msgstr "Tavsiyemiz"
+
+#: controllers/search_controller.php:218 controllers/addons_controller.php:176
+#: controllers/addons_controller.php:428 controllers/addons_controller.php:671
+#: controllers/addons_controller.php:871
+#: controllers/addons_controller.php:1103
+#: controllers/addons_controller.php:1242
+#: controllers/addons_controller.php:1298
+#, php-format
+msgid "addons_home_header_details"
+msgstr ""
+"Add-ons extend %1$s, letting you personalize your browsing experience. Take "
+"a look around and make %1$s your own."
+
+#. %1$s is the HTML collection name link.
+#: views/elements/amo2009/teaser_collections.thtml:107
+#, fuzzy
+msgid "addons_home_introduction_collection_link"
+msgstr "Like these? Find more add-ons in %1$s."
+
+#: views/elements/amo2009/teaser_collections.thtml:60
+#, fuzzy
+msgid "addons_home_introduction_extras"
+msgstr ""
+"<strong>Over 5000 free extras</strong> that let you customize and extend "
+"Firefox to meet your needs."
+
+#: views/elements/amo2009/teaser_collections.thtml:55
+#, fuzzy
+msgid "addons_home_introduction_header"
+msgstr "What are Add-ons?"
+
+#: views/elements/amo2009/teaser_collections.thtml:72
+#, fuzzy
+msgid "addons_home_introduction_install"
+msgstr ""
+"<strong>Easy to install</strong>, get notified when updates are available."
+
+#: views/elements/amo2009/teaser_collections.thtml:45
+#, fuzzy
+msgid "addons_home_introduction_name"
+msgstr "Introduction"
+
+#: views/elements/amo2009/teaser_collections.thtml:66
+#, fuzzy
+msgid "addons_home_introduction_themes"
+msgstr ""
+"Toolbars, themes and search providers that <strong>help you perform common "
+"tasks.</strong>"
+
+#: views/addons/home.thtml:161
+#, fuzzy
+msgid "addons_home_new_indicator"
+msgstr "NEW!"
+
+#: views/elements/app_chooser.thtml:48 views/layouts/amo2009.thtml:257
+#, fuzzy
+msgid "addons_home_other_applications"
+msgstr "Other Applications"
+
+#. %1$s is the application the user is browsing. Examples: Thunderbird, Firefox,
+#. Sunbird
+#: views/pages/collector_faq.thtml:49 views/pages/collector_firstrun.thtml:42
+#: views/pages/collector.thtml:46 views/pages/collector_features.thtml:54
+#: controllers/developers_controller.php:87
+#: controllers/compatibility_controller.php:72
+#: controllers/components/simple_acl.php:81 controllers/components/amo.php:607
+#: controllers/statistics_controller.php:60
+#: controllers/statistics_controller.php:240
+#: controllers/previews_controller.php:67 controllers/users_controller.php:90
+#: controllers/users_controller.php:223 controllers/users_controller.php:330
+#: controllers/users_controller.php:414 controllers/users_controller.php:708
+#: controllers/users_controller.php:723 controllers/reviews_controller.php:204
+#: controllers/reviews_controller.php:251
+#: controllers/reviews_controller.php:346
+#: controllers/reviews_controller.php:425
+#: controllers/search_controller.php:185 controllers/search_controller.php:297
+#: controllers/search_controller.php:301 controllers/addons_controller.php:147
+#: controllers/addons_controller.php:280 controllers/addons_controller.php:370
+#: controllers/addons_controller.php:667 controllers/addons_controller.php:874
+#: controllers/addons_controller.php:1019
+#: controllers/addons_controller.php:1034
+#: controllers/addons_controller.php:1101
+#: controllers/addons_controller.php:1121
+#: controllers/addons_controller.php:1240
+#: controllers/addons_controller.php:1357
+#: controllers/addons_controller.php:1364
+#: controllers/addons_controller.php:1442
+#: controllers/addons_controller.php:1477
+#: controllers/addons_controller.php:1538
+#: controllers/addons_controller.php:1543
+#: controllers/editors_controller.php:64 controllers/pages_controller.php:132
+#: controllers/groups_controller.php:65 controllers/groups_controller.php:71
+#: controllers/groups_controller.php:89 controllers/groups_controller.php:111
+#: controllers/collections_controller.php:57
+#: controllers/collections_controller.php:121
+#: controllers/collections_controller.php:205
+#: controllers/collections_controller.php:365
+#: controllers/collections_controller.php:404
+#: controllers/collections_controller.php:466
+#: controllers/collections_controller.php:538
+#: controllers/collections_controller.php:828
+#: controllers/localizers_controller.php:72
+#, php-format
+msgid "addons_home_pagetitle"
+msgstr "Mozilla Eklentileri :: Mozilla Yazılımına Özellik Ekle"
+
+#. %1$s is the number of addons downloaded
+#: views/addons/home.thtml:57
+#, fuzzy, php-format
+msgid "addons_home_stats_downloaded"
+msgid_plural "addons_home_stats_downloaded"
+msgstr[0] "<strong>%1$s</strong> <span>add-on downloaded</span>"
+msgstr[1] "<strong>%1$s</strong> <span>add-ons downloaded</span>"
+
+#. %1$s is the number of addons in use
+#: views/addons/home.thtml:63
+#, fuzzy, php-format
+msgid "addons_home_stats_inuse"
+msgid_plural "addons_home_stats_inuse"
+msgstr[0] "<strong>%1$s</strong> <span>add-on in use</span>"
+msgstr[1] "<strong>%1$s</strong> <span>add-ons in use</span>"
+
+#: views/addons/home.thtml:136
+#, fuzzy
+msgid "addons_home_view_all_newest_title"
+msgstr "View all newly created add-ons"
+
+#: views/addons/home.thtml:129
+#, fuzzy
+msgid "addons_home_view_all_popular_title"
+msgstr "View all popular add-ons"
+
+#: views/addons/home.thtml:150
+#, fuzzy
+msgid "addons_home_view_all_recommended_title"
+msgstr "View all recommended add-ons"
+
+#: views/addons/home.thtml:143
+#, fuzzy
+msgid "addons_home_view_all_updated_title"
+msgstr "View all recently updated add-ons"
+
+#: views/elements/amo2009/install.thtml:334 views/elements/install.thtml:112
+#, fuzzy
+msgid "addons_install_in_sunbird"
+msgstr ""
+"<ol><li>Click the link below to save the file.</li><li>In Mozilla Sunbird, "
+"open Add-ons from the Tools menu.</li><li>Click the Install button, and "
+"locate/select the file you downloaded and click \"OK\".</li></ol>"
+
+#: views/elements/amo2009/install.thtml:333 views/elements/install.thtml:111
+#, fuzzy
+msgid "addons_install_in_sunbird_title"
+msgstr "How to Install in Sunbird"
+
+#: views/elements/amo2009/install.thtml:331 views/elements/install.thtml:106
+#, fuzzy
+msgid "addons_install_in_thunderbird"
+msgstr ""
+"<ol><li>Right-click the link below and choose \"Save Link As...\" to "
+"download and save the file to your hard disk.</li><li>In Mozilla "
+"Thunderbird, open Add-ons from the Tools menu.</li><li>Click the Install "
+"button, and locate/select the file you downloaded and click \"OK\".</li></ol>"
+
+#: views/elements/amo2009/install.thtml:330 views/elements/install.thtml:105
+#, fuzzy
+msgid "addons_install_in_thunderbird_title"
+msgstr "How to Install in Thunderbird"
+
+#: views/elements/amo2009/addon_list_options.thtml:108
+#: views/elements/addon_list_options.thtml:105
+#, fuzzy
+msgid "addons_options_show_experimental"
+msgstr "show experimental add-ons"
+
+#: views/elements/amo2009/addon_list_options.thtml:113
+#: views/elements/addon_list_options.thtml:109
+#, fuzzy
+msgid "addons_options_submit"
+msgstr "Go"
+
+#: views/addons/plugins.thtml:63 views/addons/plugins.thtml:73
+#: views/addons/plugins.thtml:83 views/addons/plugins.thtml:93
+#: views/addons/plugins.thtml:103 views/addons/plugins.thtml:116
+#: views/addons/plugins.thtml:126
+msgid "addons_plugins_by"
+msgstr "By"
+
+#: views/addons/plugins.thtml:107
+msgid "addons_plugins_for_linux"
+msgstr "for Linux"
+
+#: views/addons/plugins.thtml:108 views/addons/plugins.thtml:131
+msgid "addons_plugins_for_macosx"
+msgstr "for Mac OS X"
+
+#: views/addons/plugins.thtml:106 views/addons/plugins.thtml:129
+#: views/addons/plugins.thtml:130
+msgid "addons_plugins_for_windows"
+msgstr "for Windows"
+
+#. %1$s is a URL
+#: views/addons/plugins.thtml:139
+#, php-format
+msgid "addons_plugins_looking_for_more"
+msgstr ""
+"This page only lists some of the most common and most popular plugins. For "
+"more information about other plugins available for Mozilla-based Browsers, "
+"visit %1$s"
+
+#: views/addons/plugins.thtml:137
+msgid "addons_plugins_looking_for_plugin"
+msgstr "Looking for a plugin not listed here?"
+
+#: views/addons/plugins.thtml:58
+msgid "addons_plugins_main_description"
+msgstr ""
+"Plugins help your browser perform specific functions like viewing special "
+"graphic formats or playing multimedia files. Plugins are slightly different "
+"from extensions, which modify or add to existing functionality."
+
+#. %1$s is the application name. Example: Firefox, Thunderbird, Sunbird
+#: controllers/addons_controller.php:1122
+#, fuzzy, php-format
+msgid "addons_plugins_main_header"
+msgstr "Common Plugins for %1$s"
+
+#: controllers/components/amo.php:698 controllers/addons_controller.php:1121
+msgid "addons_plugins_pagetitle"
+msgstr "Plugins"
+
+#: views/addons/plugins.thtml:68 views/addons/plugins.thtml:78
+#: views/addons/plugins.thtml:88 views/addons/plugins.thtml:98
+#: views/addons/plugins.thtml:110 views/addons/plugins.thtml:121
+#: views/addons/plugins.thtml:133
+msgid "addons_plugins_support_documentation"
+msgstr "Support Documentation: "
+
+#. %s is the name of the add-on
+#: views/addons/policy.thtml:61
+#, php-format
+msgid "addons_policy_eula_require"
+msgstr ""
+"%s requires that you accept the following End User License Agreement before "
+"installation can proceed:"
+
+# %1 is the addon name
+#. %1 is the add-on name
+#: controllers/addons_controller.php:1476
+#, php-format
+msgid "addons_previews_pagetitle"
+msgstr "Previews for %s"
+
+#: views/addons/category_landing.thtml:135
+#, fuzzy
+msgid "addons_recently_added"
+msgstr "Recently Added"
+
+#: views/addons/recommended.thtml:51 controllers/addons_controller.php:1365
+msgid "addons_recommended_introduction"
+msgstr ""
+"Binden fazla eklentiyle, herkes için birşey bulunmaktadır. Başlamanıza "
+"yardımcı olmak için beğendiklerimizden bazılarının listesini sunuyoruz. İyi "
+"eÄŸlenceler!"
+
+#: controllers/addons_controller.php:1357
+#: controllers/addons_controller.php:1364
+msgid "addons_recommended_pagetitle"
+msgstr "Önerilen Eklentiler"
+
+#: controllers/addons_controller.php:1360
+msgid "addons_recommended_title"
+msgstr "Tavsiye edilen eklentiler"
+
+#: views/addons/searchengines.thtml:136
+msgid "addons_searchengines_additional_resources"
+msgstr "Additional Resources"
+
+# link text devmo
+#. link text devmo
+#: views/addons/searchengines.thtml:141
+msgid "addons_searchengines_devmo_link"
+msgstr "Mozilla Developer Center"
+
+#: views/pages/js_constants.js.thtml:67
+msgid "addons_searchengines_error_mozilla_browser_required"
+msgstr ""
+"Sorry, you need a Mozilla-based browser (such as Firefox) to install a "
+"search plugin."
+
+#: views/addons/searchengines.thtml:49
+msgid "addons_searchengines_error_nojavascript"
+msgstr ""
+"JavaScript is required to install plugins, but it looks like you have it "
+"disabled. Please enable JavaScript before trying to install any of the "
+"search plugins below."
+
+# %1 is "make your own" link
+# %2 is MDC link
+#. %1 is "make your own" link
+#. %2 is MDC link
+#: views/addons/searchengines.thtml:139
+#, fuzzy
+msgid "addons_searchengines_learn_howto"
+msgstr "Learn how to %1$s at the %2$s."
+
+# link path to search plugins instructions, relative to devmo
+#. link path to search plugins instructions, relative to devmo
+#: views/addons/searchengines.thtml:140
+msgid "addons_searchengines_makeyourown_href"
+msgstr "/en/docs/Creating_OpenSearch_plugins_for_Firefox"
+
+# link text for "make your own" (opensearch engine)
+#. link text for "make your own" (opensearch engine)
+#: views/addons/searchengines.thtml:140
+msgid "addons_searchengines_makeyourown_link"
+msgstr "make your own"
+
+# %1 is the link to mycroft.mozdev.org
+#. %1 is the link to mycroft.mozdev.org
+#: views/addons/searchengines.thtml:138
+#, fuzzy
+msgid "addons_searchengines_more"
+msgstr "Browse through more search engines at %1$s"
+
+# link text to mycroft.mozdev.org
+#. link text to mycroft.mozdev.org
+#: views/addons/searchengines.thtml:138
+msgid "addons_searchengines_mycroft_link"
+msgstr "mycroft.mozdev.org"
+
+#: controllers/addons_controller.php:1100
+#: controllers/addons_controller.php:1110
+msgid "addons_searchengines_pagetitle"
+msgstr "Search Engines"
+
+#: views/addons/searchengines.thtml:143
+msgid "addons_searchengines_thanks"
+msgstr ""
+"Special thanks to the Mycroft Project for their work on Firefox Search "
+"Engines."
+
+#: views/addons/display.thtml:154
+#, fuzzy
+msgid "addons_share_button_text"
+msgstr "Share this"
+
+#: controllers/addons_controller.php:89
+#, fuzzy
+msgid "addons_share_label_delicious"
+msgstr "Add to Delicious"
+
+#: controllers/addons_controller.php:77
+#, fuzzy
+msgid "addons_share_label_digg"
+msgstr "Digg this!"
+
+#: controllers/addons_controller.php:83
+#, fuzzy
+msgid "addons_share_label_facebook"
+msgstr "Post to Facebook"
+
+#: controllers/addons_controller.php:101
+#, fuzzy
+msgid "addons_share_label_friendfeed"
+msgstr "Share on FriendFeed"
+
+#: controllers/addons_controller.php:95
+#, fuzzy
+msgid "addons_share_label_myspace"
+msgstr "Post to MySpace"
+
+#: controllers/components/amo.php:201 controllers/components/amo.php:229
+#, fuzzy
+msgid "addons_status_disabled"
+msgstr "Disabled"
+
+#: controllers/components/amo.php:191 controllers/components/amo.php:224
+#, fuzzy
+msgid "addons_status_incomplete"
+msgstr "Incomplete Version"
+
+#: controllers/components/amo.php:197 controllers/components/amo.php:227
+#, fuzzy
+msgid "addons_status_nominated"
+msgstr "In Sandbox; Public Nomination"
+
+#: views/pages/js_constants.js.thtml:80 controllers/components/amo.php:195
+#: controllers/components/amo.php:226
+#, fuzzy
+msgid "addons_status_pending"
+msgstr "In Sandbox; Pending Review"
+
+#: views/pages/js_constants.js.thtml:78 controllers/components/amo.php:199
+#: controllers/components/amo.php:228
+#, fuzzy
+msgid "addons_status_public"
+msgstr "Public"
+
+#: views/pages/js_constants.js.thtml:79 controllers/components/amo.php:193
+#: controllers/components/amo.php:225
+#, fuzzy
+msgid "addons_status_sandbox"
+msgstr "In Sandbox"
+
+#: controllers/components/amo.php:203
+#, fuzzy
+msgid "addons_status_unknown"
+msgstr "Unknown"
+
+#: views/elements/amo2009/teaser_collections.thtml:91
+#: views/elements/amo2009/homepage_addon.thtml:99
+#: views/elements/feature.thtml:94
+#, fuzzy
+msgid "addons_title_tooltip"
+msgstr "Learn more about this add-on"
+
+#: views/addons/category_landing.thtml:151
+#, fuzzy
+msgid "addons_top_downloads"
+msgstr "Top Downloads"
+
+#: views/addons/category_landing.thtml:165
+#, fuzzy
+msgid "addons_top_rated"
+msgstr "Top Rated"
+
+#: views/addons/versions.thtml:62
+msgid "addons_versions_careful"
+msgstr "Be Careful With Old Versions"
+
+#: views/addons/versions.thtml:63
+msgid "addons_versions_careful_introduction"
+msgstr ""
+"These versions are displayed for reference and testing purposes. You should "
+"always use the latest version of an add-on."
+
+#: controllers/addons_controller.php:1549
+msgid "addons_versions_history"
+msgstr "Version History with Changelogs"
+
+#. %1$s is the add-on name
+#: controllers/addons_controller.php:1535
+#, php-format
+msgid "addons_versions_pagetitle"
+msgstr "%1$s Version History"
+
+#: controllers/groups_controller.php:71
+msgid "admin_group_add_pagetitle"
+msgstr "Add Group"
+
+#: controllers/groups_controller.php:111
+msgid "admin_group_delete_pagetitle"
+msgstr "Delete Group"
+
+#. %s is a number to identify the group
+#: controllers/groups_controller.php:117
+#, php-format
+msgid "admin_group_deleted"
+msgstr "The Group with id %s was deleted"
+
+#: controllers/groups_controller.php:89
+msgid "admin_group_edit_pagetitle"
+msgstr "Edit Group"
+
+#: controllers/groups_controller.php:92 controllers/groups_controller.php:113
+msgid "admin_group_error_invalid_id"
+msgstr "Invalid id for Group"
+
+#: controllers/groups_controller.php:65
+msgid "admin_group_pagetitle"
+msgstr "Group Admin"
+
+#: controllers/groups_controller.php:77 controllers/groups_controller.php:99
+msgid "admin_group_saved"
+msgstr "The Group has been saved"
+
+#: views/elements/amo2009/search.thtml:257 views/elements/search.thtml:239
+#, fuzzy
+msgid "advanced_search_form"
+msgstr "Advanced"
+
+#: views/elements/amo2009/search.thtml:126 views/elements/search.thtml:125
+#, fuzzy
+msgid "advanced_search_form_any_time"
+msgstr "Any time"
+
+#: views/elements/amo2009/search.thtml:97
+#: views/elements/amo2009/search.thtml:110 views/elements/search.thtml:96
+#: views/elements/search.thtml:109
+#, fuzzy
+msgid "advanced_search_form_any_type"
+msgstr "Any"
+
+#: views/elements/amo2009/search.thtml:275 views/elements/search.thtml:254
+#, fuzzy
+msgid "advanced_search_form_any_version"
+msgstr "Any"
+
+#: views/elements/amo2009/search.thtml:217 views/elements/search.thtml:212
+#, fuzzy
+msgid "advanced_search_form_application"
+msgstr "Application"
+
+#: views/elements/amo2009/search.thtml:143 views/elements/search.thtml:142
+#, fuzzy
+msgid "advanced_search_form_keyword_match"
+msgstr "Keyword Match"
+
+#: views/elements/amo2009/search.thtml:251 views/elements/search.thtml:225
+#, fuzzy
+msgid "advanced_search_form_lastupdate"
+msgstr "Last Updated"
+
+#: views/elements/amo2009/search.thtml:145 views/elements/search.thtml:144
+#, fuzzy
+msgid "advanced_search_form_name"
+msgstr "Name"
+
+#: views/elements/amo2009/search.thtml:144 views/elements/search.thtml:143
+#, fuzzy
+msgid "advanced_search_form_newest"
+msgstr "Newest"
+
+#: views/elements/amo2009/search.thtml:130 views/elements/search.thtml:129
+#, fuzzy
+msgid "advanced_search_form_past_3_months"
+msgstr "Past 3 months"
+
+#: views/elements/amo2009/search.thtml:131 views/elements/search.thtml:130
+#, fuzzy
+msgid "advanced_search_form_past_6_months"
+msgstr "Past 6 months"
+
+#: views/elements/amo2009/search.thtml:127 views/elements/search.thtml:126
+#, fuzzy
+msgid "advanced_search_form_past_day"
+msgstr "Past Day"
+
+#: views/elements/amo2009/search.thtml:129 views/elements/search.thtml:128
+#, fuzzy
+msgid "advanced_search_form_past_month"
+msgstr "Past month"
+
+#: views/elements/amo2009/search.thtml:128 views/elements/search.thtml:127
+#, fuzzy
+msgid "advanced_search_form_past_week"
+msgstr "Past week"
+
+#: views/elements/amo2009/search.thtml:132 views/elements/search.thtml:131
+#, fuzzy
+msgid "advanced_search_form_past_year"
+msgstr "Past year"
+
+#: views/elements/amo2009/search.thtml:239 views/elements/search.thtml:230
+#, fuzzy
+msgid "advanced_search_form_perpage"
+msgstr "Per Page"
+
+#: views/elements/amo2009/search.thtml:243 views/elements/search.thtml:224
+#, fuzzy
+msgid "advanced_search_form_platform"
+msgstr "Platform"
+
+#: views/elements/amo2009/search.thtml:147 views/elements/search.thtml:146
+#, fuzzy
+msgid "advanced_search_form_popularity"
+msgstr "Popularity"
+
+#: views/elements/amo2009/search.thtml:146 views/elements/search.thtml:145
+#, fuzzy
+msgid "advanced_search_form_rating"
+msgstr "Rating"
+
+#: views/elements/amo2009/search.thtml:247 views/elements/search.thtml:231
+#, fuzzy
+msgid "advanced_search_form_sortby"
+msgstr "Sort By"
+
+#: views/elements/amo2009/search.thtml:227 views/elements/search.thtml:216
+#, fuzzy
+msgid "advanced_search_form_to"
+msgstr "to"
+
+#: views/elements/amo2009/search.thtml:257 views/elements/search.thtml:237
+#, fuzzy
+msgid "advanced_search_form_toggle_tooltip"
+msgstr "Toggle advanced search mode"
+
+#: views/elements/amo2009/search.thtml:235 views/elements/search.thtml:223
+#, fuzzy
+msgid "advanced_search_form_type"
+msgstr "Type"
+
+#: views/elements/amo2009/search.thtml:222 views/elements/search.thtml:214
+#, fuzzy
+msgid "advanced_search_form_version"
+msgstr "version"
+
+#: views/elements/amo2009/pagination.thtml:42
+#, fuzzy
+msgid "amo2009_pagination_next_page"
+msgstr "Next"
+
+#: views/elements/amo2009/pagination.thtml:41
+#, fuzzy
+msgid "amo2009_pagination_previous_page"
+msgstr "Prev"
+
+#: views/pages/js_constants.js.thtml:96
+#, fuzzy
+msgid "app_compat_ignore_check"
+msgstr "Ignore version check"
+
+#: views/pages/js_constants.js.thtml:72
+#, fuzzy
+msgid "app_compat_older_firefox_only"
+msgstr "This add-on is for older versions of Firefox"
+
+#. %1$s and %2$s are URLs
+#: views/pages/js_constants.js.thtml:74
+#, fuzzy
+msgid "app_compat_older_version_or_ignore_check"
+msgstr ""
+"You can <a href=\"%1$s\">try an older version</a> or <a href=\"#\" onclick="
+"\"%2$s\">ignore this check</a>"
+
+#. %1$s is a URL
+#: views/pages/js_constants.js.thtml:71
+#, fuzzy
+msgid "app_compat_try_old_version"
+msgstr "An <a href=\"%1$s\">older version</a> may work"
+
+#. %1$s is a URL
+#. %2$s is a version number. Example: 3.1
+#: views/pages/js_constants.js.thtml:73
+#, fuzzy
+msgid "app_compat_unreleased_version"
+msgstr ""
+"This add-on requires the not-yet released <a href=\"%1$s\">Firefox %2$s</a>"
+
+#: views/pages/js_constants.js.thtml:70
+#, fuzzy
+msgid "app_compat_update_firefox"
+msgstr ""
+"<a href=\"http://getfirefox.com\">Upgrade Firefox</a> to use this add-on"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#. %3$s is a status, like Public.
+#: controllers/components/audit.php:79
+#, fuzzy
+msgid "audit_addon_status"
+msgstr "%1$s changed the status of %2$s to %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:221
+#, fuzzy
+msgid "audit_admin_default"
+msgstr "%1$s committed unknown admin action %2$s to ID %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:153
+#, fuzzy
+msgid "audit_admin_feature_remove"
+msgstr "%1$s removed feature %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is an application, like Firefox.
+#: controllers/components/audit.php:92
+#, fuzzy
+msgid "audit_application_create"
+msgstr "%1$s created application %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is an application, like Firefox.
+#: controllers/components/audit.php:95
+#, fuzzy
+msgid "audit_application_edit"
+msgstr "%1$s edited application %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a version number, like 3.5.
+#. %3$s is an application, like Firefox.
+#: controllers/components/audit.php:105
+#, fuzzy
+msgid "audit_appversion_create"
+msgstr "%1$s created version %2$s for %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a version number, like 3.5.
+#. %3$s is an application, like Firefox.
+#: controllers/components/audit.php:108
+#, fuzzy
+msgid "audit_appversion_delete"
+msgstr "%1$s deleted version %2$s for %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a config field, like "awesomeness".
+#. %3$s is a config value, like "off".
+#. %4$s is a config value, like "on".
+#: controllers/components/audit.php:210
+#, fuzzy
+msgid "audit_config"
+msgstr "%1$s changed config '%2$s' from '%3$s' to '%4$s'"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:258
+#, fuzzy
+msgid "audit_editor_default"
+msgstr "%1$s committed unknown editor action %2$s to ID %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#: controllers/components/audit.php:236
+#, fuzzy
+msgid "audit_editor_feature_remove"
+msgstr "%1$s removed addon %2$s from feature list"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#: controllers/components/audit.php:231
+#, fuzzy
+msgid "audit_feature_add"
+msgstr "%1$s added addon %2$s to feature list"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:149
+#, fuzzy
+msgid "audit_feature_edit"
+msgstr "%1$s changed a feature for %2$s locale"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#: controllers/components/audit.php:241
+#, fuzzy
+msgid "audit_feature_locale_change"
+msgstr "%1$s changed locales for addon %2$s on feature list"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:83
+#, fuzzy
+msgid "audit_file_recalchash"
+msgstr "%1$s recalculated the hash for file %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>user name</a>
+#. %3$s is <a>group name</a>
+#: controllers/components/audit.php:182
+#, fuzzy
+msgid "audit_group_addmember"
+msgstr "%1$s added %2$s to group %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:313
+#, fuzzy
+msgid "audit_group_associated"
+msgstr "%1$s associated themselves with %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:162
+#, fuzzy
+msgid "audit_group_create"
+msgstr "%1s created group %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:170
+#, fuzzy
+msgid "audit_group_delete"
+msgstr "%1$s deleted group %2$s (ID %3$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:165
+#, fuzzy
+msgid "audit_group_edit"
+msgstr "%1$s edited group %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>user name</a>
+#. %3$s is <a>group name</a>
+#: controllers/components/audit.php:188
+#, fuzzy
+msgid "audit_group_removemember"
+msgstr "%1$s removed %2$s from group %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:280
+#, fuzzy
+msgid "audit_l10n_default"
+msgstr "%1$s committed unknown action %2$s for %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:295
+#, fuzzy
+msgid "audit_modify_locked_group"
+msgstr "%1$s attempted to modify locked group %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:299
+#, fuzzy
+msgid "audit_modify_other_locale"
+msgstr "%1$s attempted to modify translations in %2$s without permission"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a platform, like <a>Windows</a>
+#: controllers/components/audit.php:135
+#, fuzzy
+msgid "audit_platform_create"
+msgstr "%1$s created platform %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a platform, like <a>Windows</a>
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:143
+#, fuzzy
+msgid "audit_platform_delete"
+msgstr "%1$s deleted platform %2$s (ID %3$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a platform, like <a>Windows</a>
+#: controllers/components/audit.php:138
+#, fuzzy
+msgid "audit_platform_edit"
+msgstr "%1$s edited platform %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a part of the admin, like 'Site Config'
+#: controllers/components/audit.php:288
+#, fuzzy
+msgid "audit_reauthentication_failure"
+msgstr "%1$s failed to re-authenticate to access %2$s."
+
+#. %1$s is <a>user name</a>
+#. %2$s is the name of a canned response, like 'Ready for the public'
+#: controllers/components/audit.php:198
+#, fuzzy
+msgid "audit_response_create"
+msgstr "%1$s created response %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is the name of a canned response, like 'Ready for the public'
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:206
+#, fuzzy
+msgid "audit_response_delete"
+msgstr "%1$s deleted response %2$s (ID %3$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is the name of a canned response, like 'Ready for the public'
+#: controllers/components/audit.php:201
+#, fuzzy
+msgid "audit_response_edit"
+msgstr "%1$s edited response %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:245
+#, fuzzy
+msgid "audit_review_approve"
+msgstr "%1$s approved review %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:250 controllers/components/audit.php:253
+#, fuzzy
+msgid "audit_review_delete"
+msgstr "%1$s deleted review %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:303
+#, fuzzy
+msgid "audit_security_default"
+msgstr "%1$s committed unknown security action %2$s to ID %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a category name, like <a>Search Tools</a>
+#: controllers/components/audit.php:118
+#, fuzzy
+msgid "audit_tag_create"
+msgstr "%1$s created tag %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a category name, like <a>Search Tools</a>
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:126
+#, fuzzy
+msgid "audit_tag_delete"
+msgstr "%1$s deleted category %2$s (ID %3$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a category name, like <a>Search Tools</a>
+#: controllers/components/audit.php:121
+#, fuzzy
+msgid "audit_tag_edit"
+msgstr "%1$s edited category %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:266
+#, fuzzy
+msgid "audit_update_applications"
+msgstr "%1$s updated application translations for %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:277
+#, fuzzy
+msgid "audit_update_blog"
+msgstr "%1$s updated blog post translations for %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:274
+#, fuzzy
+msgid "audit_update_platforms"
+msgstr "%1$s updated platform translations for %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:270
+#, fuzzy
+msgid "audit_update_tags"
+msgstr "%1$s updated category translations for %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>user name</a>
+#: controllers/components/audit.php:217
+#, fuzzy
+msgid "audit_user_edit"
+msgstr "%1$s edited %2$s's user information"
+
+#: controllers/addons_controller.php:1012
+#, fuzzy
+msgid "browse_addons_name"
+msgstr "Add-ons by Name"
+
+#: controllers/addons_controller.php:1010
+#, fuzzy
+msgid "browse_addons_newest"
+msgstr "Newest Add-ons"
+
+#: controllers/addons_controller.php:1008
+#, fuzzy
+msgid "browse_addons_popular"
+msgstr "Popular Add-ons"
+
+#: controllers/addons_controller.php:1011
+#, fuzzy
+msgid "browse_addons_rated"
+msgstr "Add-ons by Rating"
+
+#: controllers/addons_controller.php:1009
+#, fuzzy
+msgid "browse_addons_updated"
+msgstr "Recently Updated Add-ons"
+
+#: views/elements/categories.thtml:73 views/elements/categories.thtml:82
+#, fuzzy
+msgid "categories_current_title"
+msgstr "Current Category"
+
+#: views/elements/categories.thtml:50
+#: views/elements/amo2009/categories.thtml:43
+#: views/elements/amo2009/categories.thtml:45
+#, fuzzy
+msgid "categories_header"
+msgstr "Categories"
+
+#: views/elements/categories.thtml:50
+#: views/elements/amo2009/categories.thtml:41
+#, fuzzy
+msgid "categories_header_title"
+msgstr "Choose a category"
+
+# %1 is the category name
+#. %1$s is the category name
+#: views/addons/searchengines.thtml:129
+#, fuzzy, php-format
+msgid "category_extra_see_all"
+msgstr "See All %1$s"
+
+#. %1$s is a number.
+#: models/collection.php:130
+#, fuzzy
+msgid "collection_description_limit"
+msgstr "The description should be less than %1$s characters."
+
+#. %1$s is the name of the collection
+#: controllers/collections_controller.php:392
+#, fuzzy
+msgid "collection_detail_rss_title"
+msgstr "%s Collection"
+
+#: controllers/collections_controller.php:1065
+#, fuzzy
+msgid "collection_error_deleting_addon"
+msgstr "Error deleting add-on!"
+
+#: controllers/collections_controller.php:1051
+#, fuzzy
+msgid "collection_error_saving_addon"
+msgstr "Error saving add-on!"
+
+#: controllers/collections_controller.php:1080
+#, fuzzy
+msgid "collection_error_saving_comment"
+msgstr "Error saving comment!"
+
+#. %1$s is a number.
+#: models/collection.php:122
+#, fuzzy
+msgid "collection_name_limit"
+msgstr "The name should be less than %1$s characters."
+
+#: controllers/collections_controller.php:352
+#: controllers/collections_controller.php:487
+#, fuzzy
+msgid "collection_not_found"
+msgstr "Collection not found!"
+
+#. %1$s is the text on the "create collection" button
+#: views/collections/add.thtml:91
+#, fuzzy
+msgid "collections_add_formfield_addons_description"
+msgstr ""
+"If you already know which add-ons you want to add to your collection, just "
+"start typing their names below. If you'd rather wait and do this later, just "
+"click %1$s now."
+
+#: views/collections/add.thtml:90
+#, fuzzy
+msgid "collections_add_formfield_firstaddons"
+msgstr "Choose your first add-ons"
+
+#: views/collections/add.thtml:48
+#, fuzzy
+msgid "collections_add_header"
+msgstr "Create a Collection"
+
+#: views/collections/add.thtml:97
+#, fuzzy
+msgid "collections_add_header_selectedaddons"
+msgstr "Selected Add-ons"
+
+#: views/collections/add.thtml:50
+#, fuzzy
+msgid "collections_add_intro"
+msgstr ""
+"It's easy to create your own collection of add-ons by filling in a few "
+"fields below."
+
+#: views/collections/add.thtml:92 views/collections/add.thtml:103
+#, fuzzy
+msgid "collections_add_submit"
+msgstr "Create Collection"
+
+#: views/pages/collector_faq.thtml:50 views/pages/collector_firstrun.thtml:43
+#: views/pages/collector.thtml:47 views/pages/collector_features.thtml:55
+#: controllers/search_controller.php:302
+#: controllers/collections_controller.php:206
+#: controllers/collections_controller.php:405
+#: controllers/collections_controller.php:467
+#: controllers/collections_controller.php:539
+#, fuzzy
+msgid "collections_breadcrumb"
+msgstr "Collections"
+
+#: views/collections/detail.thtml:185
+#, fuzzy
+msgid "collections_detail_a_learn"
+msgstr "Learn More"
+
+#: views/elements/amo2009/collection_add_form.thtml:53
+#: views/elements/amo2009/collections_js_init.thtml:68
+#: views/pages/collector_firstrun.thtml:64
+#, fuzzy
+msgid "collections_detail_button_add"
+msgstr "Add to Favorites"
+
+#: views/elements/amo2009/collection_add_form.thtml:50
+#: views/elements/amo2009/collections_js_init.thtml:71
+#, fuzzy
+msgid "collections_detail_button_remove"
+msgstr "Remove from Favorites"
+
+#. %1$s is a URL.
+#. %2$s is a full <a href>.
+#: views/collections/detail.thtml:62
+#, fuzzy
+msgid "collections_detail_created_desc"
+msgstr ""
+"<p>You can view your new collection below. If you'd like to set a collection "
+"nickname, upload an icon, or change additional settings, please visit the <a "
+"href='%1$s'>Manage Collections</a> page.</p><p>Your collection can be "
+"accessed at this location: %2$s</p>"
+
+#: views/collections/detail.thtml:61
+#, fuzzy
+msgid "collections_detail_created_msg"
+msgstr "Your collection is now ready!"
+
+#: views/collections/detail.thtml:109
+#, fuzzy
+msgid "collections_detail_header_about"
+msgstr "About This Collection"
+
+#. %1$s is a number.
+#: views/collections/detail.thtml:126
+#, fuzzy
+msgid "collections_detail_header_count"
+msgid_plural "collections_detail_header_count"
+msgstr[0] "%1$s Add-on in this Collection"
+msgstr[1] "%1$s Add-ons in this Collection"
+
+#: views/collections/detail.thtml:113
+#, fuzzy
+msgid "collections_detail_info_created"
+msgstr "<strong>Created by:</strong> %1$s"
+
+#: views/collections/detail.thtml:117
+#, fuzzy
+msgid "collections_detail_info_updated"
+msgstr "<strong>Updated:</strong>"
+
+#: views/elements/amo2009/collections_js_init.thtml:62
+#, fuzzy
+msgid "collections_detail_js_adding"
+msgstr "Adding to Favorites&hellip;"
+
+#: views/elements/amo2009/collections_js_init.thtml:65
+#, fuzzy
+msgid "collections_detail_js_removing"
+msgstr "Removing Favorite&hellip;"
+
+#. %1$s is a URL
+#: views/collections/detail.thtml:90
+#, fuzzy
+msgid "collections_detail_login"
+msgstr "<a href=\"%1$s\">Log in</a> to add this collection to your favorites."
+
+#: views/collections/detail.thtml:104
+#, fuzzy
+msgid "collections_detail_manage"
+msgstr "Manage Collection"
+
+#: controllers/collections_controller.php:298
+#, fuzzy
+msgid "collections_detail_sort_date"
+msgstr "Date Added"
+
+#: controllers/collections_controller.php:299
+#, fuzzy
+msgid "collections_detail_sort_name"
+msgstr "Name"
+
+#: controllers/collections_controller.php:300
+#, fuzzy
+msgid "collections_detail_sort_popularity"
+msgstr "Popularity"
+
+#. %1$s is a number.
+#: views/collections/detail.thtml:166
+#, fuzzy
+msgid "collections_detail_weekly_downloads"
+msgid_plural "collections_detail_weekly_downloads"
+msgstr[0] "%1$s download this week"
+msgstr[1] "%1$s downloads this week"
+
+#: views/collections/edit.thtml:255
+#, fuzzy
+msgid "collections_edit_addons_delete_noscript"
+msgstr "Selected add-ons will be removed upon Save"
+
+#: views/collections/edit.thtml:247
+#, fuzzy
+msgid "collections_edit_addons_description"
+msgstr ""
+"To publish new add-ons to this collection, start typing their names below."
+
+#: views/collections/edit.thtml:248
+#, fuzzy
+msgid "collections_edit_addons_description_noscript"
+msgstr ""
+"To publish new add-ons to this collection, enter a comma-separated list of "
+"Add-on IDs below."
+
+#: views/collections/edit.thtml:247 views/collections/edit.thtml:248
+#, fuzzy
+msgid "collections_edit_addons_description_publish_detailspage"
+msgstr "You can also publish an add-on from its normal listing page."
+
+#. %1$s is the date the add-on was added to the collection
+#. %1$s is the name of the user who added the add-on to the collection
+#: views/collections/edit.thtml:260
+#, fuzzy
+msgid "collections_edit_addons_listitem_added"
+msgstr "Added %1$s by %2$s"
+
+#: views/collections/edit.thtml:263
+#, fuzzy
+msgid "collections_edit_addons_listitem_comment_add"
+msgstr "Add publisher comment"
+
+#: views/collections/edit.thtml:266
+#, fuzzy
+msgid "collections_edit_addons_listitem_comment_delete"
+msgstr "Delete publisher comment"
+
+#: views/collections/edit.thtml:265
+#, fuzzy
+msgid "collections_edit_addons_listitem_comment_edit"
+msgstr "Edit publisher comment"
+
+#: views/collections/edit.thtml:271
+#, fuzzy
+msgid "collections_edit_addons_listitem_comment_note"
+msgstr ""
+"Note: Comment will appear as though written by original publisher on the "
+"original publication date"
+
+#: views/collections/edit.thtml:270
+#, fuzzy
+msgid "collections_edit_addons_listitem_comment_submit"
+msgstr "Save Comment"
+
+#: views/collections/edit.thtml:261
+#, fuzzy
+msgid "collections_edit_addons_listitem_remove"
+msgstr "Remove"
+
+#: views/collections/edit.thtml:250
+#, fuzzy
+msgid "collections_edit_addons_submit"
+msgstr "Add to Collection"
+
+#: views/collections/edit.thtml:153
+#, fuzzy
+msgid "collections_edit_check_nickname"
+msgstr "Check Availability"
+
+#: views/collections/edit.thtml:299
+#, fuzzy
+msgid "collections_edit_confirm_deletecollection"
+msgstr "Yes, I would like to delete this collection."
+
+#. %1$s is the label of the edit form's submit button
+#: views/collections/edit.thtml:300
+#, fuzzy
+msgid "collections_edit_confirm_deletecollection_description"
+msgstr "Check the box, then click on \"%1$s\" to delete this collection."
+
+#. %1$s is the "delete" submit button text
+#. %2$s is the title of the "advanced" tab
+#: views/collections/edit.thtml:95
+#, fuzzy
+msgid "collections_edit_delete_upon_submit"
+msgstr ""
+"Upon clicking \"%1$s\" below, your collection will be deleted. If you do not "
+"want to delete your collection, uncheck the confirmation box in the \"%2$s\" "
+"tab and continue editing your collection. If you leave this page without "
+"saving, your collection will also not be deleted."
+
+#: views/collections/edit.thtml:94
+#, fuzzy
+msgid "collections_edit_delete_warning"
+msgstr "Your collection is about to be deleted!"
+
+#: views/collections/add.thtml:76 views/collections/edit.thtml:144
+#, fuzzy
+msgid "collections_edit_form_error_description"
+msgstr "You must provide a description of your collection."
+
+#: views/collections/edit.thtml:181
+#, fuzzy
+msgid "collections_edit_form_error_icon"
+msgstr "There was an error uploading your icon."
+
+#: views/collections/add.thtml:69 views/collections/edit.thtml:130
+#, fuzzy
+msgid "collections_edit_form_error_name"
+msgstr "You must give your collection a name."
+
+#: views/collections/edit.thtml:158
+#, fuzzy
+msgid "collections_edit_form_error_nickname"
+msgstr "If you choose a nickname, it must be unique."
+
+#: views/collections/add.thtml:93 views/collections/edit.thtml:249
+#, fuzzy
+msgid "collections_edit_formfield_addons"
+msgstr "Add-on name:"
+
+#: views/collections/edit.thtml:281
+#, fuzzy
+msgid "collections_edit_formfield_application"
+msgstr "Associated Application"
+
+#: views/collections/edit.thtml:282
+#, fuzzy
+msgid "collections_edit_formfield_application_description"
+msgstr "Select the application that your collection supports."
+
+#: views/collections/edit.thtml:288
+#, fuzzy
+msgid "collections_edit_formfield_collectiontype"
+msgstr "Collection Type"
+
+#: views/collections/edit.thtml:295
+#, fuzzy
+msgid "collections_edit_formfield_deletecollection"
+msgstr "Delete Collection"
+
+#: views/collections/edit.thtml:296
+#, fuzzy
+msgid "collections_edit_formfield_deletecollection_description"
+msgstr "Deleting your collection will permanently erase it."
+
+#: views/collections/add.thtml:73 views/collections/edit.thtml:140
+#, fuzzy
+msgid "collections_edit_formfield_description"
+msgstr "Collection Description"
+
+#: views/collections/add.thtml:74 views/collections/edit.thtml:141
+#, fuzzy
+msgid "collections_edit_formfield_description_description"
+msgstr "Briefly describe your collection and the kind of add-ons in it"
+
+#: views/collections/edit.thtml:162
+#, fuzzy
+msgid "collections_edit_formfield_icon"
+msgstr "Icon"
+
+#: views/collections/edit.thtml:163
+#, fuzzy
+msgid "collections_edit_formfield_icon_description"
+msgstr ""
+"You can upload a JPG, GIF or PNG icon that will be resized to 32x32 pixels."
+
+#: views/collections/add.thtml:80 views/collections/edit.thtml:189
+#, fuzzy
+msgid "collections_edit_formfield_listed"
+msgstr "Who can view your collection?"
+
+#: views/collections/add.thtml:81 views/collections/edit.thtml:190
+#, fuzzy
+msgid "collections_edit_formfield_listed_description"
+msgstr ""
+"By default, collections appear in the public Collection Directory and are "
+"discoverable by anyone. If you want to restrict your collection to be "
+"viewable only by people who are given a special link, choose that option "
+"below."
+
+#: views/collections/add.thtml:84 views/collections/edit.thtml:193
+#, fuzzy
+msgid "collections_edit_formfield_listed_false"
+msgstr "Only people I invite can view my collection"
+
+#: views/collections/add.thtml:83 views/collections/edit.thtml:192
+#, fuzzy
+msgid "collections_edit_formfield_listed_true"
+msgstr "Everyone can view my collection in the directory"
+
+#: views/collections/edit.thtml:223
+#, fuzzy
+msgid "collections_edit_formfield_managers"
+msgstr "Who can manage my collection?"
+
+#: views/collections/edit.thtml:224
+#, fuzzy
+msgid "collections_edit_formfield_managers_description"
+msgstr ""
+"These users can publish add-ons to your collection, manage all add-ons and "
+"settings, and grant other users permission."
+
+#: views/collections/add.thtml:66 views/collections/edit.thtml:126
+#, fuzzy
+msgid "collections_edit_formfield_name"
+msgstr "Collection Name"
+
+#: views/collections/add.thtml:67 views/collections/edit.thtml:127
+#, fuzzy
+msgid "collections_edit_formfield_name_description"
+msgstr ""
+"Give your collection a descriptive name, such as \"Dave's Favorite Travel "
+"Add-ons\""
+
+#: views/collections/edit.thtml:148
+#, fuzzy
+msgid "collections_edit_formfield_nickname"
+msgstr "Collection Nickname"
+
+#: views/collections/edit.thtml:149
+#, fuzzy
+msgid "collections_edit_formfield_nickname_description"
+msgstr "Optionally, give your collection a unique nickname for quick access:"
+
+#: views/collections/edit.thtml:201
+#, fuzzy
+msgid "collections_edit_formfield_publishers"
+msgstr "Who can publish add-ons to your collection?"
+
+#: views/collections/edit.thtml:202
+#, fuzzy
+msgid "collections_edit_formfield_publishers_description"
+msgstr ""
+"These users can publish add-ons to your collection and remove add-ons that "
+"they publish."
+
+#: views/collections/edit.thtml:210 views/collections/edit.thtml:232
+#, fuzzy
+msgid "collections_edit_formfield_users_add"
+msgstr "Enter the e-mail address of a Firefox Add-ons account:"
+
+#: views/collections/edit.thtml:216 views/collections/edit.thtml:238
+#, fuzzy
+msgid "collections_edit_formfield_users_delete_noscript"
+msgstr "Selected accounts will be removed upon Save"
+
+#: views/collections/edit.thtml:215 views/collections/edit.thtml:237
+#, fuzzy
+msgid "collections_edit_formfield_users_new_noscript"
+msgstr ""
+"Enter a comma-separated list of e-mail addresses of Firefox Add-ons accounts"
+
+#: views/collections/edit.thtml:204 views/collections/edit.thtml:226
+#, fuzzy
+msgid "collections_edit_formfield_users_onlyme"
+msgstr "Only me"
+
+#: views/collections/edit.thtml:205 views/collections/edit.thtml:227
+#, fuzzy
+msgid "collections_edit_formfield_users_otherusers"
+msgstr "Myself and these users:"
+
+#: views/collections/edit.thtml:211 views/collections/edit.thtml:233
+#, fuzzy
+msgid "collections_edit_formfield_users_submit"
+msgstr "Add"
+
+#. %1$s is the name of the collection
+#: views/collections/edit.thtml:68
+#, fuzzy
+msgid "collections_edit_header"
+msgstr "Manage %1$s"
+
+#: views/collections/edit.thtml:246
+#, fuzzy
+msgid "collections_edit_header_addons"
+msgstr "Manage Collection Contents"
+
+#: views/collections/edit.thtml:253 views/collections/edit.thtml:258
+#, fuzzy
+msgid "collections_edit_header_addons_current"
+msgstr "Current Add-ons:"
+
+#: views/collections/edit.thtml:279
+#, fuzzy
+msgid "collections_edit_header_advanced"
+msgstr "Advanced Settings"
+
+#: views/collections/edit.thtml:186
+#, fuzzy
+msgid "collections_edit_header_permissions"
+msgstr "Manage Collection Permissions"
+
+#: views/collections/edit.thtml:170
+#, fuzzy
+msgid "collections_edit_icon_cancel"
+msgstr "Cancel"
+
+#: views/collections/edit.thtml:174 views/collections/edit.thtml:179
+#, fuzzy
+msgid "collections_edit_icon_delete"
+msgstr "Delete Icon"
+
+#: views/collections/edit.thtml:178
+#, fuzzy
+msgid "collections_edit_icon_replace"
+msgstr "Replace Icon"
+
+#. %1$s is the label of the edit form's submit button
+#: views/collections/edit.thtml:169
+#, fuzzy
+msgid "collections_edit_icon_toberemoved"
+msgstr "Icon will be removed when \"%1$s\" is clicked below"
+
+#: views/collections/edit.thtml:155
+#, fuzzy
+msgid "collections_edit_nickname_available"
+msgstr "Nickname Available"
+
+#: controllers/collections_controller.php:943
+#, fuzzy
+msgid "collections_edit_nickname_error"
+msgstr ""
+"Your nickname contained invalid characters and was corrected. Please try "
+"again."
+
+#: views/collections/edit.thtml:156
+#, fuzzy
+msgid "collections_edit_nickname_taken"
+msgstr "Nickname Taken"
+
+#. This string is followed by a URL pointing to the collection's view page
+#: views/collections/edit.thtml:75
+#, fuzzy
+msgid "collections_edit_saved_nextstep"
+msgstr "Your collection can be accessed at this location:"
+
+#: views/collections/edit.thtml:74
+#, fuzzy
+msgid "collections_edit_saved_success"
+msgstr "Your collection was successfully saved!"
+
+#: views/collections/edit.thtml:169 views/collections/edit.thtml:300
+#: views/collections/edit.thtml:308 views/pages/js_constants.js.thtml:99
+#, fuzzy
+msgid "collections_edit_submit"
+msgstr "Update Collection"
+
+#: views/collections/edit.thtml:96 views/collections/edit.thtml:297
+#: views/pages/js_constants.js.thtml:100
+#, fuzzy
+msgid "collections_edit_submit_deletecollection"
+msgstr "Delete Collection"
+
+#: views/collections/edit.thtml:111
+#, fuzzy
+msgid "collections_edit_tabheader_addons"
+msgstr "Add-ons"
+
+#: views/collections/edit.thtml:97 views/collections/edit.thtml:113
+#, fuzzy
+msgid "collections_edit_tabheader_advanced"
+msgstr "Advanced"
+
+#: views/collections/edit.thtml:108
+#, fuzzy
+msgid "collections_edit_tabheader_details"
+msgstr "Name &amp; Details"
+
+#: views/collections/edit.thtml:109
+#, fuzzy
+msgid "collections_edit_tabheader_permissions"
+msgstr "Permissions"
+
+#: models/collection_promo.php:53
+#, fuzzy
+msgid "collections_family_tagline"
+msgstr "Add-ons can keep an eye on your kids and your calendar."
+
+#: models/collection_promo.php:53
+#, fuzzy
+msgid "collections_family_title"
+msgstr "Family Organizer"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:70
+#, fuzzy
+msgid "collections_index_a_check_out"
+msgstr "Check out Add-on Collector"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:52
+#, fuzzy
+msgid "collections_index_a_create"
+msgstr "Create a Collection"
+
+#: views/collections/detail.thtml:139 views/collections/listing.thtml:85
+#: views/search/collections.thtml:84
+#, fuzzy
+msgid "collections_index_button_go"
+msgstr "Go"
+
+#. %1$s is a URL.
+#: controllers/collections_controller.php:182
+#, fuzzy
+msgid "collections_index_filler_favorites"
+msgstr ""
+"<p><strong>You don't have any favorite collections yet.</strong></p> "
+"<p>Collections you mark as favorites can be quickly accessed from this page, "
+"and will appear in the <a href='%1$s'>Add-on Collector</a> if you've "
+"installed it.</p>"
+
+#. %1$s is a URL.
+#: controllers/collections_controller.php:167
+#, fuzzy
+msgid "collections_index_filler_mine"
+msgstr ""
+"<p>You haven't created any collections yet. Collections are easy to create "
+"and fill with your favorite add-ons. <a href='%1$s'>Try it out</a>!</p>"
+
+#: views/collections/listing.thtml:51
+#, fuzzy
+msgid "collections_index_header_collections"
+msgstr "Collections"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:60
+#, fuzzy
+msgid "collections_index_header_collector"
+msgstr "Add-on Collector"
+
+#. %1$s is a comma-separated list of author names
+#: views/elements/amo2009/collection_listing_item.thtml:84
+#: views/collections/detail.thtml:151
+#, fuzzy
+msgid "collections_index_header_created"
+msgstr "created by %1$s"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:47
+#, fuzzy
+msgid "collections_index_header_what"
+msgstr "What are Collections?"
+
+#: views/collections/detail.thtml:132 views/collections/listing.thtml:78
+#: views/search/collections.thtml:66
+#, fuzzy
+msgid "collections_index_label_sortby"
+msgstr "Sort by"
+
+#: controllers/collections_controller.php:130
+#, fuzzy
+msgid "collections_index_li_editors"
+msgstr "Editor's Picks"
+
+#: views/collections/subscribe.thtml:64
+#: controllers/collections_controller.php:140
+#, fuzzy
+msgid "collections_index_li_favorites"
+msgstr "My Favorites"
+
+#: controllers/collections_controller.php:138
+#, fuzzy
+msgid "collections_index_li_mine"
+msgstr "My Collections"
+
+#: controllers/collections_controller.php:132
+#, fuzzy
+msgid "collections_index_li_popular"
+msgstr "Popular"
+
+#: views/search/collections.thtml:74 controllers/collections_controller.php:81
+#, fuzzy
+msgid "collections_index_option_all"
+msgstr "Most popular all time"
+
+#: views/search/collections.thtml:72 controllers/collections_controller.php:78
+#, fuzzy
+msgid "collections_index_option_month"
+msgstr "Most popular this month"
+
+#: views/search/collections.thtml:76 controllers/collections_controller.php:84
+#, fuzzy
+msgid "collections_index_option_newest"
+msgstr "Newest"
+
+#: views/search/collections.thtml:70 controllers/collections_controller.php:75
+#, fuzzy
+msgid "collections_index_option_week"
+msgstr "Most popular this week"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:67
+#, fuzzy
+msgid "collections_index_p_collector"
+msgstr ""
+"There's a new way to manage and find favorite add-ons. Comment, share and "
+"sync collections, all from your browser"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:48
+#, fuzzy
+msgid "collections_index_p_what_are"
+msgstr "Collections are groups of related add-ons assembled for easy sharing."
+
+#. %s is a date in the _('date') format
+#: views/elements/collections_interactive_addon.thtml:85
+#, fuzzy, php-format
+msgid "collections_interactive_addon_added"
+msgstr "Added %s"
+
+#: models/collection_promo.php:55
+#, fuzzy
+msgid "collections_reference_tagline"
+msgstr "Add-ons can do better research online."
+
+#: models/collection_promo.php:55
+#, fuzzy
+msgid "collections_reference_title"
+msgstr "Reference Desk"
+
+#: models/collection_promo.php:52
+#, fuzzy
+msgid "collections_social_tagline"
+msgstr "Add-ons can manage your social network."
+
+#: models/collection_promo.php:52
+#, fuzzy
+msgid "collections_social_title"
+msgstr "Social Circuit"
+
+#: views/collections/subscribe.thtml:91
+#, fuzzy
+msgid "collections_subscribe_button_close"
+msgstr "Close"
+
+#: views/collections/subscribe.thtml:70
+#, fuzzy
+msgid "collections_subscribe_error"
+msgstr ""
+"An error occurred trying to add a favorite collection. Is this collection "
+"already a favorite?"
+
+#: views/collections/subscribe.thtml:96
+#, fuzzy
+msgid "collections_subscribe_label_bothersome"
+msgstr "Don't show me this message again."
+
+#. %1$s is the collection name
+#: views/collections/subscribe.thtml:60
+#, fuzzy
+msgid "collections_subscribe_success"
+msgstr "%1$s has been added to your favorite collections."
+
+#. %1$s is the link to the "My Favorites" tab on the main collections page
+#. %2$s is the localized title of the "My Favorites" tab
+#. %3$s is the link URL to the collector add-on
+#: views/collections/subscribe.thtml:62
+#, fuzzy
+msgid "collections_subscribe_success_desc"
+msgstr ""
+"You can now quickly find this collection from the <a href=\"%1$s\">%2$s</a> "
+"tab in the directory. For an even easier way to keep track of your favorite "
+"collections, try out our <a href=\"%3$s\">Add-on Collector</a> extension for "
+"Firefox."
+
+#: views/collections/listing.thtml:55
+#, fuzzy
+msgid "collections_success_delete"
+msgstr "The collection has been deleted."
+
+#: models/collection_promo.php:54
+#, fuzzy
+msgid "collections_travel_tagline"
+msgstr "Add-ons can turn you into a travel agent."
+
+#: models/collection_promo.php:54
+#, fuzzy
+msgid "collections_travel_title"
+msgstr "The Traveler's Pack"
+
+#. A collection of add-ons that is automatically built for a user. They are "automatically published" to this collection.
+#: controllers/collections_controller.php:581
+#, fuzzy
+msgid "collections_type_autopublisher"
+msgstr "Auto-publisher"
+
+#. A collection that has been chosen by an Editor as notable or exceptional
+#: controllers/collections_controller.php:582
+#, fuzzy
+msgid "collections_type_editorspick"
+msgstr "Editor's Pick"
+
+#: controllers/collections_controller.php:580
+#, fuzzy
+msgid "collections_type_normal"
+msgstr "Normal"
+
+#: views/collections/subscribe.thtml:84
+#, fuzzy
+msgid "collections_unsubscribe_error"
+msgstr ""
+"An error occurred trying to remove a favorite collection. Was this "
+"collection not a favorite?"
+
+#. %1$s is the collection name
+#: views/collections/subscribe.thtml:78
+#, fuzzy
+msgid "collections_unsubscribe_success"
+msgstr "%1$s has been removed from your favorite collections."
+
+#: models/collection_promo.php:56
+#, fuzzy
+msgid "collections_webdev_tagline"
+msgstr "Add-ons make it easier to build the perfect website."
+
+#: models/collection_promo.php:56
+#, fuzzy
+msgid "collections_webdev_title"
+msgstr "Web Developer's Toolbox"
+
+#: views/elements/amo2009/collections_sidebar_whatare.thtml:40
+#, fuzzy
+msgid "collections_whatare_header"
+msgstr "What are Collections?"
+
+#: views/elements/amo2009/collections_sidebar_whatare.thtml:45
+#, fuzzy
+msgid "collections_whatare_learnmore"
+msgstr "Read the FAQ"
+
+#: views/elements/amo2009/collections_sidebar_whatare.thtml:44
+#, fuzzy
+msgid "collections_whatare_text"
+msgstr ""
+"There’s a new way to manage and find favorite add-ons. Comment, share and "
+"sync collections, all from your browser."
+
+#: views/pages/collector_faq.thtml:61 views/pages/collector_features.thtml:67
+#, fuzzy
+msgid "collector_features_a_home"
+msgstr "Add-on Collector Home"
+
+#: views/elements/amo2009/collector_sidebar_download.thtml:46
+#, fuzzy
+msgid "collector_features_heading_download"
+msgstr "Download the Add-on Collector:"
+
+#: views/elements/amo2009/collector_sidebar_download.thtml:43
+#: views/pages/collector_firstrun.thtml:116 views/pages/collector.thtml:69
+#, fuzzy
+msgid "collector_features_img_logo"
+msgstr "Add-on Collector Logo"
+
+#: views/compatibility/dashboard.thtml:49
+#: controllers/compatibility_controller.php:72
+#, fuzzy
+msgid "compatibility_dashboard_center_header"
+msgstr "Add-on Compatibility Center"
+
+#. %1$s is the name of an application and a version. Example: Firefox 3.0
+#. %2$s is the name of an application. Example: Firefox
+#: views/compatibility/dashboard.thtml:50
+#, fuzzy
+msgid "compatibility_dashboard_intro"
+msgstr ""
+"Be prepared for the release of %1$s with the tools and information available "
+"for the %2$s Add-ons community found below."
+
+#: views/compatibility/dashboard.thtml:103
+#, fuzzy
+msgid "compatibility_dashboard_loading"
+msgstr "Loading data..."
+
+#: views/compatibility/dashboard.thtml:45
+#, fuzzy
+msgid "compatibility_dashboard_main_link"
+msgstr "Back to Main"
+
+#: views/compatibility/dashboard.thtml:100 views/compatibility/report.thtml:43
+#, fuzzy
+msgid "compatibility_dashboard_report"
+msgstr "Add-on Compatibility Report"
+
+#: views/compatibility/dashboard.thtml:53
+#: views/compatibility/dashboard.thtml:110
+#: views/compatibility/developers.thtml:43
+#, fuzzy
+msgid "compatibility_developer_info"
+msgstr "Information for Add-on Developers"
+
+#: views/compatibility/developers.thtml:66
+#, fuzzy
+msgid "compatibility_developers_adjust_maxversion"
+msgstr "Adjust maxVersion without uploading"
+
+#: views/compatibility/dashboard.thtml:124
+#, fuzzy
+msgid "compatibility_developers_check_status"
+msgstr "Check Status of My Add-ons"
+
+#. %1$s is a URL
+#. %2$s is an application and version. Example: Firefox 3.0
+#: views/compatibility/dashboard.thtml:126
+#, fuzzy
+msgid "compatibility_developers_login_first"
+msgstr ""
+"If you have add-ons hosted on Mozilla Add-ons, <a href=\"%1$s\">please "
+"login</a> to analyze the status of your add-ons for %2$s."
+
+#: views/compatibility/dashboard.thtml:114
+#, fuzzy
+msgid "compatibility_developers_mdclogo_alt"
+msgstr "Mozilla Developer Center Logo"
+
+#: views/compatibility/developers.thtml:73
+#, fuzzy
+msgid "compatibility_developers_no_addons"
+msgstr "You do not have any add-ons hosted on Mozilla Add-ons."
+
+#: views/compatibility/dashboard.thtml:133
+#: views/compatibility/developers.thtml:55
+#, fuzzy
+msgid "compatibility_developers_results"
+msgstr "Add-on Status Check Results"
+
+#: views/compatibility/dashboard.thtml:137
+#, fuzzy
+msgid "compatibility_developers_retrieving"
+msgstr "Retrieving status of hosted add-ons..."
+
+#. %1$s is a number
+#. %2$s is an application name
+#. %3$s is a number.
+#. Full example: 50 Firefox users (10% of total)
+#: views/compatibility/developers.thtml:65
+#, fuzzy
+msgid "compatibility_developers_user_count"
+msgstr "%1$s %2$s users (%3$s&#37; of total)"
+
+#: views/compatibility/report.thtml:45
+#, fuzzy
+msgid "compatibility_report_detail_intro"
+msgstr ""
+"The add-ons below make up 95% of add-on usage known to Mozilla and are "
+"ordered by their usage size."
+
+#: views/compatibility/dashboard.thtml:94
+#, fuzzy
+msgid "compatibility_report_detailed_link"
+msgstr "View Detailed Report"
+
+#. %1$s and %2$s are numbers
+#. %3$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:65
+#, fuzzy
+msgid "compatibility_report_intro"
+msgstr ""
+"Of the %1$s add-ons that make up 95&#37; of add-on usage known to Mozilla, "
+"<b>%2$s&#37;</b> are currently considered compatible with the latest builds "
+"of %3$s."
+
+#: views/compatibility/dashboard.thtml:81
+#, fuzzy
+msgid "compatibility_report_legend_alpha"
+msgstr "Alpha Versions"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:81
+#, fuzzy
+msgid "compatibility_report_legend_alpha_description"
+msgstr "Add-ons compatible with an alpha version of %1$s"
+
+#: views/compatibility/dashboard.thtml:85
+#, fuzzy
+msgid "compatibility_report_legend_beta"
+msgstr "Beta Versions"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:85
+#, fuzzy
+msgid "compatibility_report_legend_beta_description"
+msgstr "Add-ons compatible with a beta version or release candidate of %1$s"
+
+#: views/compatibility/dashboard.thtml:89
+#, fuzzy
+msgid "compatibility_report_legend_latest"
+msgstr "Latest Version"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:89
+#, fuzzy
+msgid "compatibility_report_legend_latest_description"
+msgstr "Add-ons up-to-date with the latest builds of %1$s"
+
+#: views/compatibility/dashboard.thtml:77
+#, fuzzy
+msgid "compatibility_report_legend_other"
+msgstr "Other Versions"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:77
+#, fuzzy
+msgid "compatibility_report_legend_other_description"
+msgstr "Add-ons not compatible with any version of %1$s"
+
+#: views/compatibility/dashboard.thtml:62
+#, fuzzy
+msgid "compatibility_report_title"
+msgstr "Add-on Compatibility Report"
+
+#: views/compatibility/dashboard.thtml:54
+#: views/compatibility/dashboard.thtml:144 views/compatibility/users.thtml:42
+#, fuzzy
+msgid "compatibility_user_info"
+msgstr "Information for Add-on Users"
+
+#: views/compatibility/dashboard.thtml:52
+#, fuzzy
+msgid "compatibility_view_report"
+msgstr "View Compatibility Report"
+
+#. %s is a URL
+#: views/pages/credits.thtml:142
+#, fuzzy, php-format
+msgid "credits_contributing"
+msgstr "For information on contributing, please see our %s."
+
+#: views/pages/credits.thtml:142
+#, fuzzy
+msgid "credits_contributing_wikipage"
+msgstr "wiki page"
+
+#: views/pages/credits.thtml:99
+#, fuzzy
+msgid "credits_intro"
+msgstr ""
+"Mozilla would like to thank the following people for their contributions to "
+"the addons.mozilla.org project over the years:"
+
+#: views/pages/credits.thtml:103
+#, fuzzy
+msgid "credits_section_developers"
+msgstr "Developers"
+
+#: views/pages/credits.thtml:115
+#, fuzzy
+msgid "credits_section_editors"
+msgstr "Editors"
+
+#: views/pages/credits.thtml:109
+#, fuzzy
+msgid "credits_section_localizers"
+msgstr "Localizers"
+
+#: views/pages/credits.thtml:121
+#, fuzzy
+msgid "credits_section_other_contributors"
+msgstr "Other Contributors"
+
+#: views/pages/credits.thtml:127
+#, fuzzy
+msgid "credits_section_past_developers"
+msgstr "Past Developers"
+
+#: views/pages/credits.thtml:133
+#, fuzzy
+msgid "credits_section_software"
+msgstr "Software and Images"
+
+#: views/pages/credits.thtml:136
+#, fuzzy
+msgid "credits_software_famfamfam"
+msgstr ""
+"Some icons used are from the <a href=\"http://www.famfamfam.com/lab/icons/"
+"silk/\">famfamfam Silk Icon Set</a>, licensed under a <a href=\"http://"
+"creativecommons.org/licenses/by/2.5/\">Creative Commons Attribution 2.5 "
+"License</a>."
+
+#: views/pages/credits.thtml:137
+#, fuzzy
+msgid "credits_software_timeplot"
+msgstr ""
+"Some pages use elements of <a href=\"http://www.simile-widgets.org/timeplot/"
+"\">Timeplot</a>, licensed under a <a href=\"http://simile.mit.edu/license."
+"html\">BSD License</a>."
+
+# date format string as used in PHP's strftime():
+# http://php.net/strftime
+#. date format string as used in PHP's strftime():
+#. http://php.net/strftime
+#: views/elements/collections_interactive_addon.thtml:85
+#: views/elements/amo2009/addon_version_detail.thtml:53
+#: views/elements/amo2009/homepage_addon.thtml:115
+#: views/elements/addon_version_detail.thtml:54
+#: views/elements/addon_listitem.thtml:124 views/elements/feature.thtml:106
+#: views/collections/detail.thtml:118 views/collections/edit.thtml:325
+#: views/users/info.thtml:76 views/editors/reviews_queue.thtml:57
+#: views/editors/reviews_queue.thtml:68 views/developers/dashboard.thtml:65
+#: views/developers/versions_edit.thtml:208 views/developers/versions.thtml:67
+#: views/search/rss/index.thtml:5 views/addons/rss/versions.thtml:42
+#: views/addons/display.thtml:104 views/addons/display.thtml:356
+#: views/addons/browse_thumbs.thtml:75 views/reviews/add.thtml:63
+#: views/reviews/display.thtml:74 views/reviews/display.thtml:160
+#: views/reviews/delete.thtml:54 controllers/statistics_controller.php:244
+#: controllers/collections_controller.php:1047
+msgid "date"
+msgstr "%e %B %Y"
+
+# date and time format string (strftime)
+#. date and time format string (strftime)
+#. http://php.net/strftime
+#: views/elements/addon_version_detail.thtml:53
+#: views/developers/discuss.thtml:52 views/developers/discuss.thtml:62
+#: views/admin/addons_status.thtml:57
+msgid "datetime"
+msgstr "%e %B %Y %H:%M"
+
+#: views/elements/developers/actionbar.thtml:47
+#, fuzzy
+msgid "devcp_actionbar_link_details"
+msgstr "Detailed Info"
+
+#: views/elements/developers/actionbar.thtml:42
+#: views/elements/developers/actionbar.thtml:50
+#: views/developers/dashboard.thtml:64
+#, fuzzy
+msgid "devcp_actionbar_link_edit"
+msgstr "Edit Add-on"
+
+#: views/elements/developers/actionbar.thtml:51
+#, fuzzy
+msgid "devcp_actionbar_link_newversion"
+msgstr "Upload New Version"
+
+#: views/elements/developers/actionbar.thtml:44
+#: views/elements/developers/actionbar.thtml:49
+#: views/developers/dashboard.thtml:73
+#, fuzzy
+msgid "devcp_actionbar_link_stats"
+msgstr "Statistics Dashboard"
+
+#. %1$s is a filename, e.g. "foo.txt"
+#. %2$s is the extension, e.g. ".txt"
+#. %3$s is a list of valid extensions, like ".png, .jpg, .gif"
+#: controllers/developers_controller.php:1361
+#, fuzzy
+msgid "devcp_add_previews_extension_error"
+msgstr "File %1$s has an invalid extension (%2$s). Allowed extensions: %3$s"
+
+#. %s is the filename.
+#: controllers/developers_controller.php:1394
+#, fuzzy
+msgid "devcp_add_previews_save_error"
+msgstr "File %s could not be saved to the database. Please try again."
+
+#. %1$s is the preview ID number, %2$s is the filename.
+#: controllers/developers_controller.php:1389
+#, fuzzy
+msgid "devcp_add_previews_success_replace"
+msgstr "Preview %1$s was replaced with file %2$s successfully."
+
+#. %s is the filename.
+#: controllers/developers_controller.php:1391
+#, fuzzy
+msgid "devcp_add_previews_success_upload"
+msgstr "File %s was uploaded successfully. You can add a caption below."
+
+#: controllers/components/developers.php:1163
+#, fuzzy
+msgid "devcp_additem_addontype_autodetect"
+msgstr "(auto-detect)"
+
+#: views/elements/developers/additem.thtml:76
+msgid "devcp_additem_linktitle_opensin_newwindow"
+msgstr "Opens in a new window"
+
+#: views/elements/developers/additem.thtml:41
+#, fuzzy
+msgid "devcp_additem_sidebar_title"
+msgstr "Submit Add-on"
+
+#: views/elements/developers/additem.thtml:53
+msgid "devcp_additem_step0_newlink"
+msgstr "Developer Agreement"
+
+#: views/elements/developers/additem.thtml:46
+msgid "devcp_additem_step1_link"
+msgstr "Step 1: Upload"
+
+#: views/elements/developers/additem.thtml:47
+msgid "devcp_additem_step2_link"
+msgstr "Step 2: Add-on Details"
+
+#: views/elements/developers/additem.thtml:48
+msgid "devcp_additem_step3_link"
+msgstr "Step 3: Version Details"
+
+#: views/elements/developers/additem.thtml:49
+msgid "devcp_additem_step4_link"
+msgstr "Step 4: Localization"
+
+#: views/elements/developers/additem.thtml:50
+msgid "devcp_additem_step5_link"
+msgstr "Step 5: Success"
+
+#: views/elements/developers/additem.thtml:76
+msgid "devcp_additem_submissionhelp_link"
+msgstr "Submission Help"
+
+#: controllers/previews_controller.php:168
+#: controllers/previews_controller.php:277
+msgid "devcp_addon_field_preview_caption_displaytitle"
+msgstr "Preview Caption"
+
+#: views/developers/addon_status.thtml:177
+#, fuzzy
+msgid "devcp_addon_status_action_activate"
+msgstr "Make Active"
+
+#: views/developers/addon_status.thtml:178
+#, fuzzy
+msgid "devcp_addon_status_action_activate_description"
+msgstr ""
+"Make your add-on active for it to show up in public listings and enable the "
+"update check service."
+
+#: views/developers/addon_status.thtml:135
+#, fuzzy
+msgid "devcp_addon_status_action_complete"
+msgstr "Complete Add-on"
+
+#: views/developers/addon_status.thtml:136
+#, fuzzy
+msgid "devcp_addon_status_action_complete_description"
+msgstr "Complete your add-on and move to the Sandbox"
+
+#: views/developers/addon_status.thtml:181
+#, fuzzy
+msgid "devcp_addon_status_action_deactivate"
+msgstr "Make Inactive"
+
+#: views/developers/addon_status.thtml:182
+#, fuzzy
+msgid "devcp_addon_status_action_deactivate_description"
+msgstr ""
+"Make your add-on inactive to hide it from all public listings and disable "
+"the update check service."
+
+#: views/developers/addon_status.thtml:143
+#, fuzzy
+msgid "devcp_addon_status_action_move"
+msgstr "Move to Sandbox"
+
+#: views/developers/addon_status.thtml:144
+#, fuzzy
+msgid "devcp_addon_status_action_move_description"
+msgstr "Move your add-on back to the Sandbox. This is reversible."
+
+#: views/developers/addon_status.thtml:139
+#, fuzzy
+msgid "devcp_addon_status_action_nominate"
+msgstr "Nominate for Public"
+
+#: views/developers/addon_status.thtml:140
+#, fuzzy
+msgid "devcp_addon_status_action_nominate_description"
+msgstr "Nominate your add-on to become Public"
+
+#: views/developers/addon_status.thtml:147
+#, fuzzy
+msgid "devcp_addon_status_action_public"
+msgstr "Make Public"
+
+#: views/developers/addon_status.thtml:148
+#, fuzzy
+msgid "devcp_addon_status_action_public_description"
+msgstr "Make your add-on Public again."
+
+#: views/developers/addon_status.thtml:169
+#, fuzzy
+msgid "devcp_addon_status_active"
+msgstr ""
+"Your add-on is <span class=\"inactive-0\">Active</span>. This means your add-"
+"on is showing up in all available listings appropriate for its status above."
+
+#: views/developers/addon_status.thtml:111
+#, fuzzy
+msgid "devcp_addon_status_completion_disabled"
+msgstr ""
+"Please fulfill the criteria above before you can complete your add-on and "
+"move it to the <span class=\"status-1\">Sandbox</span>."
+
+#: views/developers/addon_status.thtml:108
+#, fuzzy
+msgid "devcp_addon_status_completion_enabled"
+msgstr ""
+"You may now complete your add-on and move it to the <span class=\"status-1"
+"\">Sandbox</span> by clicking the button below."
+
+#: views/developers/addon_status.thtml:102
+#, fuzzy
+msgid "devcp_addon_status_criteria_category"
+msgstr "At least one category selected"
+
+#: views/developers/addon_status.thtml:101
+#, fuzzy
+msgid "devcp_addon_status_criteria_description"
+msgstr "Add-on Description required"
+
+#: views/developers/addon_status.thtml:99
+#, fuzzy
+msgid "devcp_addon_status_criteria_name"
+msgstr "Add-on Name required"
+
+#: views/developers/addon_status.thtml:120
+#, fuzzy
+msgid "devcp_addon_status_criteria_prerelease"
+msgstr "Add-on is not marked as pre-release."
+
+#: views/developers/addon_status.thtml:119
+#, fuzzy
+msgid "devcp_addon_status_criteria_preview"
+msgstr "At least one preview image required for extensions and themes."
+
+#: views/developers/addon_status.thtml:100
+#, fuzzy
+msgid "devcp_addon_status_criteria_summary"
+msgstr "Add-on Summary required"
+
+#. %s is the status in a span, e.g. "<span>_('Public')</span>".
+#: views/developers/addon_status.thtml:58
+#, fuzzy
+msgid "devcp_addon_status_header"
+msgstr "Add-on Status: %s"
+
+#: views/developers/addon_status.thtml:152
+#: views/developers/addon_status.thtml:173
+#, fuzzy
+msgid "devcp_addon_status_header_actions"
+msgstr "Available Actions"
+
+#: views/developers/addon_status.thtml:168
+#, fuzzy
+msgid "devcp_addon_status_header_active"
+msgstr "Active Status: <span class=\"inactive-0\">Active</span>"
+
+#: views/developers/addon_status.thtml:97
+#, fuzzy
+msgid "devcp_addon_status_header_criteria"
+msgstr "Add-on Completion Criteria"
+
+#: views/developers/addon_status.thtml:164
+#, fuzzy
+msgid "devcp_addon_status_header_inactive"
+msgstr "Active Status: <span class=\"inactive-1\">Inactive</span>"
+
+#: views/developers/addon_status.thtml:117
+#, fuzzy
+msgid "devcp_addon_status_header_nomination"
+msgstr "Public Nomination Criteria"
+
+#: views/developers/addon_status.thtml:190
+#, fuzzy
+msgid "devcp_addon_status_header_trusted"
+msgstr "Trusted Status: <span class=\"status-4\">Trusted</span>"
+
+#: views/developers/addon_status.thtml:165
+#, fuzzy
+msgid "devcp_addon_status_inactive"
+msgstr ""
+"Your add-on is <span class=\"inactive-1\">Inactive</span>. This means your "
+"add-on will not show up in any listing, regardless of its status above. "
+"Updates are <b>not</b> being provided to your add-on through the update "
+"check service."
+
+#: views/developers/addon_status.thtml:128
+#, fuzzy
+msgid "devcp_addon_status_nominate_disabled"
+msgstr ""
+"Please fulfill the criteria above before nominating your add-on to become "
+"<span class=\"status-4\">Public</span>."
+
+#: views/developers/addon_status.thtml:125
+#, fuzzy
+msgid "devcp_addon_status_nominate_enabled"
+msgstr ""
+"You may now nominate your add-on for <span class=\"status-4\">Public</span> "
+"by clicking the button below."
+
+#: views/developers/addon_status.thtml:64
+#, fuzzy
+msgid "devcp_addon_status_public"
+msgstr "Public"
+
+#: views/developers/addon_status.thtml:63
+#, fuzzy
+msgid "devcp_addon_status_sandbox"
+msgstr "Sandbox"
+
+#. %s is an email address.
+#: views/developers/addon_status.thtml:89
+#, fuzzy
+msgid "devcp_addon_status_switch_disabled"
+msgstr ""
+"Your add-on was <span class=\"status-5\">Disabled</span> by an administrator "
+"and cannot be used. If you have any questions, please e-mail %s."
+
+#: views/developers/addon_status.thtml:67
+#, fuzzy
+msgid "devcp_addon_status_switch_incomplete"
+msgstr ""
+"Your add-on is currently <span class=\"status-0\">Incomplete</span>. This "
+"means your add-on is not showing up on any portion of the site or update "
+"check service. You may come to this page to complete your add-on after it "
+"meets the criteria below for completion and transfer to the <span class="
+"\"status-1\">Sandbox</span>."
+
+#. %s is a number, perhaps 42.
+#: views/developers/addon_status.thtml:77
+#, fuzzy
+msgid "devcp_addon_status_switch_nominated"
+msgstr ""
+"Your add-on is currently nominated to become <span class=\"status-4"
+"\">Public</span> and is awaiting editor review. There are currently %s other "
+"add-ons in the nomination queue."
+
+#. %s is an email address.
+#: views/developers/addon_status.thtml:81
+#, fuzzy
+msgid "devcp_addon_status_switch_pending"
+msgstr ""
+"Your add-on is pending. This shouldn't have happened. Please e-mail %s with "
+"your add-on ID and state this error."
+
+#: views/developers/addon_status.thtml:85
+#, fuzzy
+msgid "devcp_addon_status_switch_public"
+msgstr ""
+"Your add-on is <span class=\"status-4\">Public</span>, which means it will "
+"show up in all listings and searches and can be downloaded without "
+"restriction. Updates are being provided to your add-on through the update "
+"check service."
+
+#: views/developers/addon_status.thtml:71
+#: views/developers/addon_status.thtml:75
+#, fuzzy
+msgid "devcp_addon_status_switch_sandbox"
+msgstr ""
+"Your add-on is in the <span class=\"status-1\">Sandbox</span>, which means "
+"it will show up in listings and searches, but users must log in to download "
+"it. Updates are <b>not</b> being provided to your add-on through the update "
+"check service."
+
+#. %s is the add-on name.
+#: views/developers/addon_status_nominate.thtml:43
+#: views/developers/addon_status_confirm.thtml:43
+#: views/developers/addon_status.thtml:43
+#, fuzzy
+msgid "devcp_addon_status_title"
+msgstr "%s Status"
+
+#: views/developers/addon_status.thtml:191
+#, fuzzy
+msgid "devcp_addon_status_trusted"
+msgstr ""
+"Your add-on is <span class=\"status-4\">Trusted</span>. This means you can "
+"submit updates to your add-on without editor review."
+
+#: views/developers/dashboard.thtml:68
+#, fuzzy
+msgid "devcp_dashboard_active"
+msgstr "Active"
+
+#. %1$s is the add-on type string
+#. %2$s is Inactive or Active in a <span>
+#. %3$s is the addon's public status (Public, In Sandbox, ...) in a <span>
+#: views/developers/dashboard.thtml:69
+#, fuzzy
+msgid "devcp_dashboard_addontype_status"
+msgstr "%1$s currenty %2$s and %3$s"
+
+#: views/developers/dashboard.thtml:67
+#, fuzzy
+msgid "devcp_dashboard_change_status"
+msgstr "Change Status"
+
+#. %s is the addons email address.
+#: views/developers/dashboard.thtml:99
+#, fuzzy
+msgid "devcp_dashboard_disabled_questions"
+msgstr ""
+"Your add-on was disabled by an administrator and cannot be used. If you "
+"have any questions, please email %s."
+
+#. %s is the (localized) add-on status string in a span, e.g. "Disabled"
+#: views/developers/dashboard.thtml:98
+#, fuzzy
+msgid "devcp_dashboard_disabled_status"
+msgstr "Add-on Status: %s"
+
+#: views/developers/dashboard.thtml:43
+#, fuzzy
+msgid "devcp_dashboard_header_main"
+msgstr "Developer Dashboard"
+
+#: views/developers/dashboard.thtml:110
+#, fuzzy
+msgid "devcp_dashboard_header_welcome"
+msgstr "Welcome to the Developer Dashboard"
+
+#: views/developers/dashboard.thtml:68
+#, fuzzy
+msgid "devcp_dashboard_inactive"
+msgstr "Inactive"
+
+#. %s is a date in the _('date') format
+#: views/developers/dashboard.thtml:65
+#, fuzzy
+msgid "devcp_dashboard_last_edited"
+msgstr "Last edited on %s"
+
+#: views/developers/dashboard.thtml:111
+#, fuzzy
+msgid "devcp_dashboard_learn"
+msgstr ""
+"You don't currently have any add-ons hosted on Mozilla Add-ons. To learn how "
+"the process works and submit your first add-on, click Get Started below."
+
+#: views/developers/dashboard.thtml:112
+#, fuzzy
+msgid "devcp_dashboard_start"
+msgstr "Get Started"
+
+#: views/developers/dashboard.thtml:82
+#, fuzzy
+msgid "devcp_dashboard_versions"
+msgstr "Versions and Files"
+
+#: views/developers/dashboard.thtml:91
+#, fuzzy
+msgid "devcp_dashboard_versions_new"
+msgstr "Upload a new version"
+
+#. %s is the preview ID number.
+#: controllers/developers_controller.php:1415
+#, fuzzy
+msgid "devcp_delete_previews_error"
+msgstr "Preview %s could not be deleted from the database. Please try again."
+
+#. %s is the preview ID number.
+#: controllers/developers_controller.php:1413
+#, fuzzy
+msgid "devcp_delete_previews_success"
+msgstr "Preview %s has been deleted successfully."
+
+#: controllers/developers_controller.php:1089
+#, fuzzy
+msgid "devcp_delete_version_priv_error"
+msgstr "You do not have privileges to delete versions or files."
+
+#. %1$s is the count of files, a number
+#. %2$s is a status string like _('Public') or _('Incomplete')
+#: controllers/components/amo.php:549
+#, fuzzy
+msgid "devcp_describe_version_status"
+msgid_plural "devcp_describe_version_status"
+msgstr[0] "%1$s %2$s file"
+msgstr[1] "%1$s %2$s files"
+
+#. %s is a version number. Example: 3.0
+#: views/developers/versions.thtml:65
+#, php-format
+msgid "devcp_details_version"
+msgstr "Version %s"
+
+#: views/developers/discuss.thtml:68
+#, fuzzy
+msgid "devcp_discuss_addreply_header"
+msgstr "Add Reply"
+
+#: views/developers/discuss.thtml:57
+#, fuzzy
+msgid "devcp_discuss_allreplies_header"
+msgstr "Replies"
+
+#. notice when an error occurs saving a discussion reply
+#. %1 is the email address (linked) for the amo-editors list
+#: views/developers/discuss.thtml:70
+#, fuzzy
+msgid "devcp_discuss_error_notice"
+msgstr ""
+"There was an error saving your reply. Please contact %1$s about the issue."
+
+#. %1 is the add-on name, %2 is the add-on's version number currently being reviewed by an editor
+#: views/developers/discuss.thtml:46
+#, fuzzy
+msgid "devcp_discuss_intro"
+msgstr ""
+"A Mozilla Add-ons Editor requested further information from you regarding "
+"version %2$s of your add-on %1$s."
+
+#. %1 is the add-on name
+#: views/developers/discuss.thtml:43
+#, fuzzy
+msgid "devcp_discuss_pagetitle"
+msgstr "Provide More Information For the Add-on Review of %1$s"
+
+#. submit button text
+#: views/developers/discuss.thtml:79
+#, fuzzy
+msgid "devcp_discuss_submit_reply"
+msgstr "Submit Reply"
+
+#: views/developers/discuss.thtml:72
+#, fuzzy
+msgid "devcp_discuss_success_message"
+msgstr ""
+"Your reply was successfully saved. The other participants of the discussion "
+"will be notified by email."
+
+#. in an author/editor discussion about an add-on to be reviewed:
+#. %1 is the commenter's user name (linked).
+#. %2 is the full date the comment was made.
+#: views/developers/discuss.thtml:52 views/developers/discuss.thtml:62
+#, fuzzy
+msgid "devcp_discuss_writtenby"
+msgstr "written by %1$s on %2$s"
+
+#: views/developers/addon_edit_authors.thtml:72
+#: views/developers/addon_edit_authors.thtml:81
+#, fuzzy
+msgid "devcp_edit_authors_add_author"
+msgstr "Add New Author"
+
+#: views/developers/addon_edit_authors.thtml:96
+#, fuzzy
+msgid "devcp_edit_authors_add_author_button"
+msgstr "Add Author"
+
+#: views/developers/addon_edit_authors.thtml:83
+#, fuzzy
+msgid "devcp_edit_authors_add_email"
+msgstr "Author Account Email:"
+
+#: views/developers/addon_edit_authors.thtml:98
+#, fuzzy
+msgid "devcp_edit_authors_add_loading"
+msgstr "Checking account email..."
+
+#: views/developers/addon_edit_authors.thtml:70
+#, fuzzy
+msgid "devcp_edit_authors_click_save"
+msgstr "Click the Update Authors button below to save."
+
+#: views/developers/addon_edit_authors.thtml:58
+#, fuzzy
+msgid "devcp_edit_authors_header_current"
+msgstr "Current Authors"
+
+#: views/developers/addon_edit_authors.thtml:50
+#, fuzzy
+msgid "devcp_edit_authors_header_manage"
+msgstr "Manage Add-on Authors"
+
+#: views/developers/addon_edit_authors.thtml:93
+#, fuzzy
+msgid "devcp_edit_authors_label_add_listed"
+msgstr "List as author in pubilc display pages"
+
+#: views/developers/addon_edit_authors.thtml:89
+#, fuzzy
+msgid "devcp_edit_authors_label_developer"
+msgstr ""
+"<strong>Developer</strong> - Can manage all aspects of the add-on listing, "
+"except for adding and removing other authors."
+
+#: views/developers/addon_edit_authors.thtml:88
+#, fuzzy
+msgid "devcp_edit_authors_label_owner"
+msgstr ""
+"<strong>Owner</strong> - Can manage all aspects of the add-on listing, "
+"including adding and removing other authors."
+
+#: views/developers/addon_edit_authors.thtml:90
+#, fuzzy
+msgid "devcp_edit_authors_label_viewer"
+msgstr ""
+"<strong>Viewer</strong> - Can view add-on developer listing and statistics, "
+"but can't make any changes."
+
+#. Placeholder for the empty option in a <select>.
+#: views/developers/addon_edit_categories.thtml:69
+#, fuzzy
+msgid "devcp_edit_authors_option_empty"
+msgstr "----------------"
+
+#: views/developers/addon_edit_authors.thtml:86
+#, fuzzy
+msgid "devcp_edit_authors_select_role"
+msgstr "Select a role for the author:"
+
+#. Column name in a table.
+#: views/developers/addon_edit_authors.thtml:62
+#, fuzzy
+msgid "devcp_edit_authors_th_author"
+msgstr "Author"
+
+#. Column name in a table.
+#: views/developers/addon_edit_authors.thtml:64
+#, fuzzy
+msgid "devcp_edit_authors_th_listed"
+msgstr "Listed"
+
+#. Column name in a table.
+#: views/developers/addon_edit_authors.thtml:63
+#, fuzzy
+msgid "devcp_edit_authors_th_role"
+msgstr "Role"
+
+#: views/developers/addon_edit_authors.thtml:77
+#, fuzzy
+msgid "devcp_edit_authors_update_author"
+msgstr "Update authors"
+
+#: views/developers/addon_edit_categories.thtml:99
+#, fuzzy
+msgid "devcp_edit_categories_button_update"
+msgstr "Update Categories"
+
+#: views/developers/addon_edit_categories.thtml:88
+#, fuzzy
+msgid "devcp_edit_categories_does_not_fit"
+msgstr "My add-on doesn't fit into any available categories."
+
+#. %s is the application name (Firefox, Thunderbird).
+#: views/developers/addon_edit_categories.thtml:61
+#, fuzzy
+msgid "devcp_edit_categories_header_application"
+msgstr "%s Categories"
+
+#: views/developers/addon_edit_categories.thtml:49
+#, fuzzy
+msgid "devcp_edit_categories_header_manage"
+msgstr "Manage Add-on Categories"
+
+#: views/developers/addon_edit_categories.thtml:91
+#, fuzzy
+msgid "devcp_edit_categories_hover"
+msgstr "Hover over a category to see its description."
+
+#. %s is the category number (1, 2, 3).
+#: views/developers/addon_edit_categories.thtml:67
+#, fuzzy
+msgid "devcp_edit_categories_label_category_num"
+msgstr "Category %s"
+
+#: views/developers/addon_edit_categories.thtml:94
+#: views/developers/addon_edit_categories.thtml:103
+#, fuzzy
+msgid "devcp_edit_categories_none_available"
+msgstr "No categories are available for this add-on type and application."
+
+#: views/developers/addon_edit_categories.thtml:86
+#, fuzzy
+msgid "devcp_edit_categories_other"
+msgstr ""
+"Place your add-on into this category only if it does not fit into any other "
+"available categories."
+
+#. %s is the application name (Firefox, Thunderbird).
+#: views/developers/addon_edit_categories.thtml:63
+#, fuzzy
+msgid "devcp_edit_categories_select_application_categories"
+msgstr "Select up to three %s categories for your add-on"
+
+#: views/developers/addon_edit.thtml:47
+#, fuzzy
+msgid "devcp_edit_dd_manage_authors"
+msgstr "Add or remove users that can manage this add-on."
+
+#: views/developers/addon_edit.thtml:49
+#, fuzzy
+msgid "devcp_edit_dd_manage_categories"
+msgstr ""
+"Select the relevant categories for each application your add-on supports."
+
+#: views/developers/addon_edit.thtml:51
+#, fuzzy
+msgid "devcp_edit_dd_manage_description"
+msgstr ""
+"Add and modify translations for your add-on's summary, description, end-user "
+"license, and privacy policy."
+
+#: views/developers/addon_edit.thtml:53
+#, fuzzy
+msgid "devcp_edit_dd_manage_properties"
+msgstr "Change your add-on's name, homepage, icon, and other flags."
+
+#: views/developers/addon_edit_descriptions.thtml:116
+#, fuzzy
+msgid "devcp_edit_description_button_update"
+msgstr "Update Descriptions"
+
+#: views/developers/addon_edit_descriptions.thtml:115
+#, fuzzy
+msgid "devcp_edit_description_correct_error"
+msgstr "Please correct the errors above indicated in red."
+
+#: views/developers/addon_edit_descriptions.thtml:51
+#, fuzzy
+msgid "devcp_edit_descriptions_header"
+msgstr "Edit Add-on Descriptions"
+
+#: views/developers/addon_edit_descriptions.thtml:94
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_comments_description"
+msgstr ""
+"Any information end users may want to know that isn't necessarily applicable "
+"to the add-on summary or description. Common uses include listing known "
+"major bugs, information on how to report bugs, anticipated release date of a "
+"new version, etc."
+
+#: views/developers/addon_edit_descriptions.thtml:93
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_comments_name"
+msgstr "Developer Comments"
+
+#: views/developers/addon_edit_descriptions.thtml:86
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_description_description"
+msgstr ""
+"The description of your add-on is a longer explanation of features, "
+"functionality, and other relevant information. It is displayed under the "
+"summary on the add-on's display page."
+
+#: views/developers/addon_edit_descriptions.thtml:85
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_description_name"
+msgstr "Add-on Description"
+
+#: views/developers/addon_edit_descriptions.thtml:103
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_eula_description"
+msgstr ""
+"If your add-on has an End-User License Agreement (EULA), please enter its "
+"text below. If set below, users will be required to agree to this before "
+"installing your add-on. Please note that a EULA is not the same as a code "
+"license such as GPL or MPL."
+
+#: views/developers/addon_edit_descriptions.thtml:102
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_eula_name"
+msgstr "End-User License Agreement"
+
+#: views/developers/addon_edit_descriptions.thtml:112
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_privacy_description"
+msgstr ""
+"If your add-on has a privacy policy, enter its text here. Your add-on's "
+"display page will display a link to the policy."
+
+#: views/developers/addon_edit_descriptions.thtml:111
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_privacy_name"
+msgstr "Privacy Policy"
+
+#: views/developers/addon_edit_descriptions.thtml:78
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_summary_description"
+msgstr ""
+"The summary is a short explanation of your add-on's basic functionality that "
+"is displayed in search and browse listings, as well as at the top of your "
+"add-on's display page. <strong>Limit of 250 characters.</strong>"
+
+#: views/developers/addon_edit_descriptions.thtml:77
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_summary_name"
+msgstr "Add-on Summary"
+
+#: views/developers/addon_edit.thtml:46
+#, fuzzy
+msgid "devcp_edit_dt_manage_authors"
+msgstr "Manage Add-on Authors"
+
+#: views/developers/addon_edit.thtml:48
+#, fuzzy
+msgid "devcp_edit_dt_manage_categories"
+msgstr "Manage Add-on Categories"
+
+#: views/developers/addon_edit.thtml:50
+#, fuzzy
+msgid "devcp_edit_dt_manage_descriptions"
+msgstr "Manage Add-on Descriptions"
+
+#: views/developers/addon_edit.thtml:52
+#, fuzzy
+msgid "devcp_edit_dt_manage_properties"
+msgstr "Manage Add-on Properties"
+
+#: views/developers/addon_edit_properties.thtml:170
+msgid "devcp_edit_label_externalsoftware"
+msgstr "This add-on requires external software"
+
+#: views/developers/addon_edit_properties.thtml:205
+#, fuzzy
+msgid "devcp_edit_label_locale_disambiguation"
+msgstr "Additional Locale Info"
+
+#: views/developers/addon_edit_properties.thtml:168
+msgid "devcp_edit_label_prerelease"
+msgstr "This is a pre-release"
+
+#: views/developers/addon_edit_properties.thtml:169
+msgid "devcp_edit_label_sitespecific"
+msgstr "This is a site-specific add-on"
+
+#: views/developers/addon_edit_properties.thtml:202
+#, fuzzy
+msgid "devcp_edit_label_target_locale"
+msgstr "Target Locale"
+
+#: views/developers/addon_edit_properties.thtml:212
+#, fuzzy
+msgid "devcp_edit_properties_button_update"
+msgstr "Update Properties"
+
+#: views/developers/addon_edit_properties.thtml:198
+#, fuzzy
+msgid "devcp_edit_properties_change_guid"
+msgstr "Only change if you understand all of the consequences."
+
+#: views/developers/addon_edit_properties.thtml:109
+#, fuzzy
+msgid "devcp_edit_properties_current_icon"
+msgstr "Current Icon"
+
+#: views/developers/addon_edit_properties.thtml:85
+#, fuzzy
+msgid "devcp_edit_properties_default_locale"
+msgstr ""
+"An add-on's default locale is the main locale in which translations must be "
+"present. If translations for your add-on's descriptions are unavailable in a "
+"user's selected language, they will fall back to this default locale."
+
+#: views/developers/addon_edit_properties.thtml:167
+#, fuzzy
+msgid "devcp_edit_properties_flags"
+msgstr "These flags are used to filter and classify add-ons."
+
+#: views/developers/addon_edit_properties.thtml:174
+#, fuzzy
+msgid "devcp_edit_properties_guid"
+msgstr ""
+"The GUID of your add-on is specified in its install.rdf and uniquely "
+"identifies it. You cannot change your GUID once it is listed on Mozilla Add-"
+"ons."
+
+#: views/developers/addon_edit_properties.thtml:53
+#, fuzzy
+msgid "devcp_edit_properties_header"
+msgstr "Edit Add-on Properties"
+
+#: views/developers/addon_edit_properties.thtml:186
+#, fuzzy
+msgid "devcp_edit_properties_header_addon_type"
+msgstr "Add-on Type"
+
+#: views/developers/addon_edit_properties.thtml:181
+#, fuzzy
+msgid "devcp_edit_properties_header_admin_settings"
+msgstr "Admin Settings"
+
+#: views/developers/addon_edit_properties.thtml:84
+#, fuzzy
+msgid "devcp_edit_properties_header_default_locale"
+msgstr "Default Locale"
+
+#: views/developers/addon_edit_properties.thtml:166
+#, fuzzy
+msgid "devcp_edit_properties_header_flags"
+msgstr "Add-on Flags"
+
+#: views/developers/addon_edit_properties.thtml:173
+#: views/developers/addon_edit_properties.thtml:197
+#, fuzzy
+msgid "devcp_edit_properties_header_guid"
+msgstr "Add-on GUID"
+
+#: views/developers/addon_edit_properties.thtml:104
+#, fuzzy
+msgid "devcp_edit_properties_header_icon"
+msgstr "Add-on Icon"
+
+#: views/developers/addon_edit_properties.thtml:159
+#, fuzzy
+msgid "devcp_edit_properties_header_other_settings"
+msgstr "Other Settings"
+
+#. A header on the admin page to toggle trusted status.
+#: views/developers/addon_edit_properties.thtml:182
+#, fuzzy
+msgid "devcp_edit_properties_header_trusted"
+msgstr "Trusted Add-on?"
+
+#: views/developers/addon_edit_properties.thtml:160
+#, fuzzy
+msgid "devcp_edit_properties_header_view_source"
+msgstr "View Source Online"
+
+#. %s is a comma-separated list of image extensions ".png, .jpg"
+#: views/developers/addon_edit_properties.thtml:106
+#, fuzzy
+msgid "devcp_edit_properties_icon"
+msgstr ""
+"The add-on icon is a small image that is displayed next to your add-on's "
+"name in browse and search results, display pages, and in the add-on "
+"installation dialog. The image will automatically be resized to 32 x 32 "
+"pixels. Please use one of the following image types: %s"
+
+#: views/developers/addon_edit_properties.thtml:171
+#, fuzzy
+msgid "devcp_edit_properties_label_binary"
+msgstr "This add-on contains binary components"
+
+#: views/developers/addon_edit_properties.thtml:185
+#, fuzzy
+msgid "devcp_edit_properties_label_not_trusted"
+msgstr "Not Trusted"
+
+#: views/developers/addon_edit_properties.thtml:184
+#, fuzzy
+msgid "devcp_edit_properties_label_trusted"
+msgstr "Trusted"
+
+#: views/developers/addon_edit_properties.thtml:110
+#, fuzzy
+msgid "devcp_edit_properties_new_icon"
+msgstr "New Icon"
+
+#: views/developers/addon_edit_properties.thtml:118
+#, fuzzy
+msgid "devcp_edit_properties_remove_icon"
+msgstr "Remove Icon"
+
+#: views/developers/addon_edit_properties.thtml:136
+#, fuzzy
+msgid "devcp_edit_properties_transbox_homepage_description"
+msgstr ""
+"If your add-on has another homepage, enter its address here. Adding other "
+"translations is not necessary unless your website is localized into other "
+"languages."
+
+#: views/developers/addon_edit_properties.thtml:135
+#, fuzzy
+msgid "devcp_edit_properties_transbox_homepage_name"
+msgstr "Add-on Homepage"
+
+#: views/developers/addon_edit_properties.thtml:79
+#, fuzzy
+msgid "devcp_edit_properties_transbox_name_description"
+msgstr "The name of your add-on is displayed everywhere your add-on is listed."
+
+#: views/developers/addon_edit_properties.thtml:78
+#, fuzzy
+msgid "devcp_edit_properties_transbox_name_name"
+msgstr "Add-on Name"
+
+#: views/developers/addon_edit_properties.thtml:145
+#, fuzzy
+msgid "devcp_edit_properties_transbox_supportemail_description"
+msgstr ""
+"If you have an email address for support inquiries, enter it here. Adding "
+"other translations is not necessary unless you have different email "
+"addresses for different languages."
+
+#: views/developers/addon_edit_properties.thtml:144
+#, fuzzy
+msgid "devcp_edit_properties_transbox_supportemail_name"
+msgstr "Support Email Address"
+
+#: views/developers/addon_edit_properties.thtml:154
+#, fuzzy
+msgid "devcp_edit_properties_transbox_supporturl_description"
+msgstr ""
+"If your add-on has a support website or forum, enter its address here. "
+"Adding other translations is not necessary unless your website is localized "
+"into other languages."
+
+#: views/developers/addon_edit_properties.thtml:153
+#, fuzzy
+msgid "devcp_edit_properties_transbox_supporturl_name"
+msgstr "Support Website"
+
+#: views/developers/addon_edit_properties.thtml:183
+#, fuzzy
+msgid "devcp_edit_properties_trusted"
+msgstr "Trusted add-ons can become public without Editor review."
+
+#. %s is href="..." and should stay in the <a> tag.
+#: views/developers/addon_edit_properties.thtml:119
+#, fuzzy
+msgid "devcp_edit_properties_undelete"
+msgstr "Icon will be deleted on save. <a %s>Cancel?</a>"
+
+#: views/developers/addon_edit_properties.thtml:161
+#, fuzzy
+msgid "devcp_edit_properties_view_source"
+msgstr ""
+"The source of your add-on files can be viewed online by any logged in user "
+"if you wish."
+
+#: views/developers/addon_edit_properties.thtml:162
+#, fuzzy
+msgid "devcp_edit_properties_view_source_allow"
+msgstr "Allow online source viewing"
+
+#: views/developers/addon_edit_properties.thtml:163
+#, fuzzy
+msgid "devcp_edit_properties_view_source_do_not_allow"
+msgstr "Do not allow online source viewing"
+
+#: views/elements/developers/editbox.thtml:46
+#, fuzzy
+msgid "devcp_editbox_authors"
+msgstr "Authors"
+
+#: views/elements/developers/editbox.thtml:47
+#, fuzzy
+msgid "devcp_editbox_categories"
+msgstr "Categories"
+
+#: views/elements/developers/editbox.thtml:52
+#, fuzzy
+msgid "devcp_editbox_change_status"
+msgstr "Change Status"
+
+#: views/elements/developers/editbox.thtml:48
+#, fuzzy
+msgid "devcp_editbox_descriptions"
+msgstr "Descriptions"
+
+#: views/elements/developers/editbox.thtml:43
+#, fuzzy
+msgid "devcp_editbox_edit_addon"
+msgstr "Edit Add-on"
+
+#: views/elements/developers/editbox.thtml:57
+#, fuzzy
+msgid "devcp_editbox_new_version"
+msgstr "New Version"
+
+#: views/elements/developers/editbox.thtml:49
+#, fuzzy
+msgid "devcp_editbox_properties"
+msgstr "Properties"
+
+#: views/elements/developers/editbox.thtml:60
+#, fuzzy
+msgid "devcp_editbox_screenshots"
+msgstr "Preview Screenshots"
+
+#: views/elements/developers/editbox.thtml:53
+#, fuzzy
+msgid "devcp_editbox_statistics_dashboard"
+msgstr "Statistics Dashboard"
+
+#: views/elements/developers/editbox.thtml:54
+#, fuzzy
+msgid "devcp_editbox_versions"
+msgstr "Versions and Files"
+
+#: views/elements/developers/editbox.thtml:42
+#, fuzzy
+msgid "devcp_editbox_view_listing"
+msgstr "View Listing"
+
+#: views/elements/developers/editorsmenu.thtml:59
+#, fuzzy
+msgid "devcp_editorsqueue_featured"
+msgstr "Featured Add-ons"
+
+# %1 is the review count
+#. %1 is the review count
+#: views/elements/developers/editorsqueue.thtml:42
+#: views/elements/developers/editorsmenu.thtml:56
+#, php-format
+msgid "devcp_editorsqueue_moderatedreviews"
+msgid_plural "devcp_editorsqueue_moderatedreviews"
+msgstr[0] "One Moderated Review"
+msgstr[1] "Moderated Reviews (%s)"
+
+# %1 is the nominated addons count
+#. %1 is the nominated addons count
+#: views/elements/developers/editorsqueue.thtml:44
+#: views/elements/developers/editorsmenu.thtml:58
+#, php-format
+msgid "devcp_editorsqueue_nominated"
+msgid_plural "devcp_editorsqueue_nominated"
+msgstr[0] "One Nominated Add-on"
+msgstr[1] "Nominated Add-ons (%s)"
+
+# %1 is the update count
+#. %1 is the update count
+#: views/elements/developers/editorsqueue.thtml:43
+#: views/elements/developers/editorsmenu.thtml:57
+#, php-format
+msgid "devcp_editorsqueue_pendingupdates"
+msgid_plural "devcp_editorsqueue_pendingupdates"
+msgstr[0] "One Pending update"
+msgstr[1] "Pending Updates (%s)"
+
+#: controllers/statistics_controller.php:147
+#: controllers/statistics_controller.php:361
+#: controllers/previews_controller.php:108
+#: controllers/previews_controller.php:211
+#: controllers/previews_controller.php:312
+msgid "devcp_error_addon_access_denied"
+msgstr "You do not have access to that add-on."
+
+#. %s is a complete URL with the text from devcp_error_appversion_reference_link_text
+#. in the <a> tag. This should be fixed.
+#: controllers/components/developers.php:591
+#, fuzzy, php-format
+msgid "devcp_error_appversion_reference_link"
+msgstr "Please see %s for reference."
+
+#. This is the link text in the <a> for devcp_error_appversion_reference_link. This
+#. should be fixed.
+#: controllers/components/developers.php:591
+#, fuzzy
+msgid "devcp_error_appversion_reference_link_text"
+msgstr "this page"
+
+#: views/developers/addon_edit_authors.thtml:76
+#, fuzzy
+msgid "devcp_error_empty_authors"
+msgstr "Your add-on must have at least one owner."
+
+#. %1$s is the name of the file
+#: controllers/components/developers.php:658
+#, fuzzy
+msgid "devcp_error_file_exists"
+msgstr ""
+"A version of that addon already exists. To replace it, you must delete the "
+"file %1$s first."
+
+#. %1$s is a file extension. Example: .exe
+#. %2$s is a comma separated list of extensions. Example: .xpi, .jar
+#: controllers/components/developers.php:355
+#, fuzzy, php-format
+msgid "devcp_error_file_extension"
+msgstr ""
+"That file extension (%s) is not allowed for the selected add-on type. Please "
+"use one of the following: %s"
+
+#: controllers/components/developers.php:64
+#, fuzzy
+msgid "devcp_error_five_categories"
+msgstr "Please select no more than five categories."
+
+#: controllers/components/developers.php:526
+#, fuzzy
+msgid "devcp_error_guid_application"
+msgstr "The ID of this add-on is already used by an application."
+
+#: controllers/components/developers.php:337
+#: controllers/components/developers.php:389
+#, fuzzy
+msgid "devcp_error_http_incomplete"
+msgstr "Incomplete transfer"
+
+#: controllers/components/developers.php:335
+#: controllers/components/developers.php:336
+#: controllers/components/developers.php:387
+#: controllers/components/developers.php:388
+#, fuzzy
+msgid "devcp_error_http_maxupload"
+msgstr "Exceeds maximum upload size"
+
+#: controllers/components/developers.php:338
+#: controllers/components/developers.php:390
+#, fuzzy
+msgid "devcp_error_http_nofile"
+msgstr "No file uploaded"
+
+#. %1$s is a file extension. Example: .exe
+#. %2$s is a comma separated list of extensions. Example: .xpi, .jar
+#: controllers/components/developers.php:401
+#, fuzzy, php-format
+msgid "devcp_error_icon_extension"
+msgstr ""
+"That file extension (%s) is not allowed for an icon. Please use one of the "
+"following: %s"
+
+#: controllers/developers_controller.php:504
+msgid "devcp_error_index_rdf_notfound"
+msgstr "No install.rdf present."
+
+#: controllers/components/developers.php:601
+#, fuzzy
+msgid "devcp_error_install_manifest"
+msgstr "The following errors were found in install.rdf:"
+
+#: controllers/developers_controller.php:1463
+msgid "devcp_error_invalid_addontype"
+msgstr "Please select a valid add-on type."
+
+#. %$1s is a version. Example: 3.1.1
+#. %$2s is an add-on name.
+#: controllers/components/developers.php:569
+#: controllers/components/developers.php:581
+#, fuzzy, php-format
+msgid "devcp_error_invalid_appversion"
+msgstr "%s is not a valid version for %s"
+
+#. %s is a string
+#: controllers/components/developers.php:521
+#, fuzzy, php-format
+msgid "devcp_error_invalid_guid"
+msgstr "The ID of this add-on is invalid: %s"
+
+#. %$1s is a version. Example: 3.1.1
+#. %$2s is an add-on name.
+#: controllers/components/developers.php:572
+#, fuzzy, php-format
+msgid "devcp_error_invalid_minversion"
+msgstr "%s is not a valid version for %s: minimum versions cannot contain *"
+
+#: controllers/components/developers.php:536
+#, fuzzy
+msgid "devcp_error_invalid_version"
+msgstr ""
+"The version of this add-on is invalid: please see the <a href=\"http://"
+"developer.mozilla.org/en/docs/Toolkit_version_format\">specification</a>"
+
+#: controllers/components/developers.php:531
+#, fuzzy
+msgid "devcp_error_invalid_version_spaces"
+msgstr "The version of this add-on is invalid: versions cannot contain spaces."
+
+#. %s is an error message from the parser.
+#: controllers/components/developers.php:501
+#, fuzzy, php-format
+msgid "devcp_error_manifest_parse"
+msgstr "The following error occurred while parsing install.rdf: %s"
+
+#: controllers/components/developers.php:373
+#, fuzzy
+msgid "devcp_error_move_file"
+msgstr "Could not move file"
+
+#. %s is the name of a file
+#: controllers/components/developers.php:650
+#: controllers/components/developers.php:662
+#: controllers/components/developers.php:667
+#: controllers/components/developers.php:727
+#: controllers/components/developers.php:738
+#: controllers/components/developers.php:743
+#, fuzzy, php-format
+msgid "devcp_error_moving_file"
+msgstr "An error occurred moving %s."
+
+#: controllers/components/developers.php:595
+#, fuzzy
+msgid "devcp_error_mozilla_application"
+msgstr "You must have at least one valid Mozilla target application."
+
+#: controllers/components/developers.php:516
+#, fuzzy
+msgid "devcp_error_no_guid"
+msgstr "No ID could be found for this add-on in install.rdf."
+
+#: controllers/components/developers.php:287
+#, fuzzy
+msgid "devcp_error_no_platform"
+msgstr "No platform selected"
+
+#: controllers/components/developers.php:59
+#, fuzzy
+msgid "devcp_error_one_category"
+msgstr "Please select at least one category."
+
+#: controllers/components/developers.php:92
+#, fuzzy
+msgid "devcp_error_one_user"
+msgstr "There must be at least one author for this add-on."
+
+#. %1$s is a file extension. Example: .exe
+#. %2$s is a comma separated list of extensions. Example: .xpi, .jar
+#: controllers/components/developers.php:1081
+#, fuzzy, php-format
+msgid "devcp_error_preview_extension"
+msgstr ""
+"That file extension (%s) is not allowed for a preview. Please use one of the "
+"following: %s"
+
+#: controllers/components/developers.php:511
+#, fuzzy
+msgid "devcp_error_updatekey"
+msgstr ""
+"Add-ons cannot use an updateKey. Please remove this from install.rdf and try "
+"again."
+
+#: controllers/components/developers.php:506
+#, fuzzy
+msgid "devcp_error_updateurl"
+msgstr ""
+"Add-ons cannot use an external updateURL. Please remove this from install."
+"rdf and try again."
+
+#: controllers/developers_controller.php:465
+#: controllers/components/developers.php:271
+#, fuzzy
+msgid "devcp_error_upload_file"
+msgstr "Please upload a file."
+
+#: views/developers/uploader.thtml:135
+#, fuzzy
+msgid "devcp_input_upload_file"
+msgstr "Upload File"
+
+#: views/pages/js_constants.js.thtml:89
+#, fuzzy
+msgid "devcp_js_a_cancel"
+msgstr "Cancel"
+
+#: views/pages/js_constants.js.thtml:90
+#, fuzzy
+msgid "devcp_js_add_email"
+msgstr "Please enter the account email of the author you wish to add."
+
+#. alt text for a down-arrow image.
+#: views/pages/js_constants.js.thtml:81
+#, fuzzy
+msgid "devcp_js_img_move_down"
+msgstr "Move Down"
+
+#. alt text for an up-arrow image.
+#: views/pages/js_constants.js.thtml:82
+#, fuzzy
+msgid "devcp_js_img_move_up"
+msgstr "Move Up"
+
+#: views/pages/js_constants.js.thtml:91
+#, fuzzy
+msgid "devcp_js_img_remove_compat"
+msgstr "Remove Application Compatibility"
+
+#: views/pages/js_constants.js.thtml:86
+#, fuzzy
+msgid "devcp_js_input_list_author"
+msgstr "List as author in public listings"
+
+#: views/pages/js_constants.js.thtml:92
+#, fuzzy
+msgid "devcp_js_license_select"
+msgstr "Please select a license."
+
+#: views/pages/js_constants.js.thtml:93
+#, fuzzy
+msgid "devcp_js_license_text"
+msgstr "Please enter text for your license."
+
+#. <option> text in a <select> for Author role in an add-on.
+#: views/pages/js_constants.js.thtml:84
+#, fuzzy
+msgid "devcp_js_option_developer"
+msgstr "Developer"
+
+#. <option> text in a <select> for Author role in an add-on.
+#: views/pages/js_constants.js.thtml:83
+#, fuzzy
+msgid "devcp_js_option_owner"
+msgstr "Owner"
+
+#. <option> text in a <select> for Author role in an add-on.
+#: views/pages/js_constants.js.thtml:85
+#, fuzzy
+msgid "devcp_js_option_viewer"
+msgstr "Viewer"
+
+#: views/pages/js_constants.js.thtml:88
+#, fuzzy
+msgid "devcp_js_remove_author"
+msgstr "Remove Author"
+
+#: views/pages/js_constants.js.thtml:87
+#, fuzzy
+msgid "devcp_js_sure_remove"
+msgstr "Are you <strong>sure</strong> you wish to remove this author?"
+
+#: views/pages/js_constants.js.thtml:77
+#, fuzzy
+msgid "devcp_js_upload_alert"
+msgstr "You must select a file to upload."
+
+#. %1$s is an addon id, like 32.
+#. %2$s is a version number, like 3.5.
+#: controllers/components/developers.php:1212
+#, fuzzy
+msgid "devcp_license_existing"
+msgstr "Custom license for add-on %1$s v%2$s"
+
+#: views/elements/developers/localebox.thtml:44
+msgid "devcp_localebox_header_localizedfields"
+msgstr "Localized Fields"
+
+# %1 is the default locale
+#. %1 is the default locale
+#: views/elements/developers/localebox.thtml:48
+#, php-format
+msgid "devcp_localebox_intro"
+msgstr ""
+"Some of the fields on this page are localized to appear in the end user's "
+"native language. Select a locale below to edit your add-on's details in that "
+"language. If a translation for a locale is not available, it will fall back "
+"to the selected default locale (%s)."
+
+#: views/elements/developers/sidebar.thtml:68
+#: views/elements/developers/myaddons.thtml:75
+msgid "devcp_myaddons_admincp_link"
+msgstr "Admin Control Panel"
+
+#: views/elements/developers/sidebar.thtml:65
+#: views/elements/developers/myaddons.thtml:72
+msgid "devcp_myaddons_editorcp_link"
+msgstr "Editor Control Panel"
+
+#: views/elements/developers/myaddons.thtml:52
+msgid "devcp_myaddons_link"
+msgstr "My Add-ons"
+
+#: views/elements/developers/sidebar.thtml:70
+#: views/elements/developers/myaddons.thtml:77
+msgid "devcp_myaddons_mainpage_link"
+msgstr "Back to Main"
+
+#: views/elements/developers/sidebar.thtml:63
+#: views/elements/developers/myaddons.thtml:70
+#, fuzzy
+msgid "devcp_myaddons_statistics_link"
+msgstr "Statistics Dashboard"
+
+#: views/elements/developers/sidebar.thtml:62
+#: views/elements/developers/myaddons.thtml:69
+msgid "devcp_myaddons_submitaddon_link"
+msgstr "Submit Add-on"
+
+#: views/elements/developers/sidebar.thtml:48
+#: views/elements/developers/myaddons.thtml:67
+#, fuzzy
+msgid "devcp_myaddons_title"
+msgstr "Developer Tools"
+
+#. %1$s is an add-on ID, perhaps 167.
+#. %2$s is a URL.
+#: controllers/developers_controller.php:256
+#, fuzzy
+msgid "devcp_new_addon_error"
+msgstr ""
+"This add-on ID (%1$s) already exists in the database. If this is your add-"
+"on, you can <a href=\"%2$s\">upload a new version</a>."
+
+#: views/developers/addon_status_nominate.thtml:62
+#, fuzzy
+msgid "devcp_nominate_cancel"
+msgstr "Cancel and return"
+
+# %1 is the addon name
+#. %1 is the add-on name
+#: views/developers/addon_status_nominate.thtml:61
+#, php-format
+msgid "devcp_nominate_submit_nominate"
+msgstr "Nominate %s"
+
+#: views/developers/addon_edit_properties.thtml:50
+#: views/developers/addon_status.thtml:49
+#: views/developers/versions_edit.thtml:50
+#, fuzzy
+msgid "devcp_notice_changes_error"
+msgstr ""
+"<span>One or more of your changes couldn't be saved.</span><br />Please look "
+"for the errors below. The rest of your changes were successfully saved."
+
+#: views/developers/addon_edit_authors.thtml:47
+#: views/developers/addon_edit_properties.thtml:47
+#: views/developers/addon_status.thtml:46
+#: views/developers/addon_edit_descriptions.thtml:47
+#: views/developers/versions_edit.thtml:47
+#: views/developers/addon_edit_categories.thtml:46
+#, fuzzy
+msgid "devcp_notice_changes_saved"
+msgstr ""
+"<span>Your changes have been saved.</span><br />Please note that some "
+"changes may take several hours to appear in all areas of the website."
+
+#: controllers/previews_controller.php:252
+msgid "devcp_notice_cleardefault"
+msgstr ""
+"Removing this as the default preview will cause another preview to "
+"automatically become the default preview."
+
+#: controllers/previews_controller.php:184
+#: controllers/previews_controller.php:251
+msgid "devcp_notice_makedefault"
+msgstr ""
+"Making this the default preview will remove default status from the current "
+"default preview."
+
+#: views/developers/addon_edit_authors.thtml:70
+#, fuzzy
+msgid "devcp_notice_unsaved_changes"
+msgstr "You have unsaved changes."
+
+#: controllers/developers_controller.php:87
+#: controllers/developers_controller.php:97
+#: controllers/developers_controller.php:100
+#: controllers/previews_controller.php:67
+#: controllers/previews_controller.php:79
+#: controllers/previews_controller.php:82
+msgid "devcp_pagetitle"
+msgstr "Developer Control Panel"
+
+#: controllers/previews_controller.php:103
+#: controllers/previews_controller.php:104
+msgid "devcp_preview_add_pagetitle"
+msgstr "Add Preview"
+
+#: controllers/previews_controller.php:135
+msgid "devcp_preview_added_successfully"
+msgstr "Preview added successfully."
+
+#: controllers/previews_controller.php:323
+msgid "devcp_preview_deleted_successfully"
+msgstr "Preview deleted successfully."
+
+#: controllers/previews_controller.php:194
+#: controllers/previews_controller.php:195
+msgid "devcp_preview_edit_pagetitle"
+msgstr "Edit Preview"
+
+#: controllers/previews_controller.php:237
+msgid "devcp_preview_updated_successfully"
+msgstr "Preview updated successfully."
+
+#: views/developers/previews.thtml:120
+#, fuzzy
+msgid "devcp_previews_a_another"
+msgstr "Add Another Preview"
+
+#: views/developers/previews.thtml:96
+#, fuzzy
+msgid "devcp_previews_a_delete"
+msgstr "Delete Preview"
+
+#: views/developers/previews.thtml:95
+#, fuzzy
+msgid "devcp_previews_a_replace"
+msgstr "Replace Preview"
+
+#: views/developers/previews.thtml:126
+#, fuzzy
+msgid "devcp_previews_a_update"
+msgstr "Update Previews"
+
+#: views/developers/previews.thtml:115 views/developers/previews.thtml:124
+#, fuzzy
+msgid "devcp_previews_add_new"
+msgstr "Add New Preview"
+
+#. %s is a list of file extensions, e.g. ".png, .gif"
+#: views/developers/previews.thtml:116
+#, fuzzy
+msgid "devcp_previews_add_select"
+msgstr ""
+"Select an image to upload below. Images larger than the maximum size of 700 "
+"pixels wide by 525 pixels tall will be resized. Allowed file types: %s"
+
+#: views/developers/previews.thtml:121
+#, fuzzy
+msgid "devcp_previews_click_below"
+msgstr "Click Update Previews below to upload."
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/previews.thtml:102
+#, fuzzy
+msgid "devcp_previews_click_update"
+msgstr ""
+"Click the Update Previews button below to save this image. (<a %s>Cancel?</"
+"a>)"
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/previews.thtml:107
+#, fuzzy
+msgid "devcp_previews_error_message"
+msgstr ""
+"This preview will be deleted when Update Previews is clicked below. (<a %"
+"s>Cancel?</a>)"
+
+#: views/previews/add.thtml:45
+msgid "devcp_previews_filetype_info"
+msgstr ""
+"Use the form below to upload a PNG, JPG, or GIF screenshot of your add-on. "
+"Images larger than 700 pixels wide and 525 pixels high will automatically be "
+"resized."
+
+#: views/previews/add.thtml:43
+msgid "devcp_previews_header_add"
+msgstr "Add Preview"
+
+#: views/developers/previews.thtml:80
+#, fuzzy
+msgid "devcp_previews_header_caption"
+msgstr "Preview Caption"
+
+#: views/previews/edit.thtml:43
+msgid "devcp_previews_header_edit"
+msgstr "Edit Preview"
+
+#: views/developers/previews.thtml:93
+#, fuzzy
+msgid "devcp_previews_label_default"
+msgstr "Default Preview"
+
+#: views/previews/add.thtml:54
+msgid "devcp_previews_label_file"
+msgstr "Preview File"
+
+#: views/previews/add.thtml:59 views/previews/edit.thtml:50
+msgid "devcp_previews_label_makedefault"
+msgstr "Make this the default preview image"
+
+#: views/developers/previews.thtml:100
+#, fuzzy
+msgid "devcp_previews_label_new"
+msgstr "New image:"
+
+#: views/developers/previews.thtml:118
+#, fuzzy
+msgid "devcp_previews_label_upload"
+msgstr "Upload Preview: "
+
+#: views/developers/previews.thtml:50
+#, fuzzy
+msgid "devcp_previews_notice_error"
+msgstr "One or more of your new previews could not be saved."
+
+#: views/developers/previews.thtml:47
+#, fuzzy
+msgid "devcp_previews_notice_success"
+msgstr "Your previews have been updated successfully."
+
+#: views/developers/previews.thtml:59
+#, fuzzy
+msgid "devcp_previews_p_screenshots"
+msgstr ""
+"The preview screenshots for your add-on are shown below. You can make "
+"changes to captions or images below. The Default Preview is the preview that "
+"is displayed next to your add-on in search and browse listings."
+
+#: views/previews/edit.thtml:55
+msgid "devcp_previews_submit_delete"
+msgstr "Delete Preview"
+
+#: views/previews/edit.thtml:55
+msgid "devcp_previews_submit_delete_confirm"
+msgstr "Are you sure you wish to delete this preview?"
+
+#: views/previews/edit.thtml:54
+msgid "devcp_previews_submit_edit"
+msgstr "Edit Preview"
+
+#: views/previews/add.thtml:63
+msgid "devcp_previews_submit_upload"
+msgstr "Upload Preview"
+
+#: views/developers/previews.thtml:78
+#, fuzzy
+msgid "devcp_previews_thumbnail"
+msgstr "Thumbnail"
+
+#. %s is the add-on name.
+#: views/developers/previews.thtml:44
+#, fuzzy
+msgid "devcp_previews_title"
+msgstr "%s Preview Manager"
+
+#: views/developers/uploader.thtml:74
+msgid "devcp_review_agreement_please"
+msgstr ""
+"Please review and accept the following Developer Agreement before proceeding."
+
+#: views/elements/developers/rolecheck.thtml:42
+#, fuzzy
+msgid "devcp_rolecheck_no_privs"
+msgstr ""
+"<span>You do not have sufficient privileges to make changes on this page.</"
+"span><br />Contact the Add-on Owner if you need to make changes."
+
+#: controllers/developers_controller.php:1315
+#, fuzzy
+msgid "devcp_several_hours"
+msgstr ""
+"Please note that some changes may take several hours to appear in all areas "
+"of the website."
+
+#: views/elements/developers/sidebar.thtml:52
+#, fuzzy
+msgid "devcp_sidebar_a_dashboard"
+msgstr "Dashboard"
+
+#. %s is a number
+#: views/elements/developers/statsbar.thtml:45
+#: views/developers/dashboard.thtml:79
+#, fuzzy, php-format
+msgid "devcp_statsbar_adu"
+msgstr "<em>%s</em> Active Daily Users"
+
+#. %s is a number
+#: views/elements/developers/statsbar.thtml:41
+#: views/developers/dashboard.thtml:75
+#, fuzzy, php-format
+msgid "devcp_statsbar_total_downloads"
+msgstr "<em>%s</em> Total Downloads"
+
+#. %s is a number
+#: views/elements/developers/statsbar.thtml:43
+#: views/developers/dashboard.thtml:77
+#, fuzzy, php-format
+msgid "devcp_statsbar_weekly_downloads"
+msgstr "<em>%s</em> Weekly Downloads"
+
+#: views/developers/addon_status_confirm.thtml:59
+#, fuzzy
+msgid "devcp_status_confirm_active"
+msgstr ""
+"Marking this add-on active will cause it to show up in public areas "
+"appropriate for its status, including search and browse listings. It will be "
+"downloadable from the website and could be returned in client update checks, "
+"depending on its status. You will be able to return here and disable it "
+"again at your convenience."
+
+#: views/developers/addon_status_confirm.thtml:59
+#, fuzzy
+msgid "devcp_status_confirm_active_sure"
+msgstr "Are you sure you wish to mark this add-on active?"
+
+#: views/developers/addon_status_confirm.thtml:50
+#, fuzzy
+msgid "devcp_status_confirm_header_sure"
+msgstr "Are you sure?"
+
+#: views/developers/addon_status_confirm.thtml:55
+#, fuzzy
+msgid "devcp_status_confirm_inactive"
+msgstr ""
+"Marking this add-on inactive will prevent it from showing up in any public "
+"areas, including search and browse listings. It will not be downloadable "
+"from the website and will not be returned in client update checks. You will "
+"be able to return here and re-enable it at your convenience."
+
+#: views/developers/addon_status_confirm.thtml:55
+#, fuzzy
+msgid "devcp_status_confirm_inactive_sure"
+msgstr "Are you sure you wish to mark this add-on inactive?'"
+
+#: views/developers/addon_status_confirm.thtml:74
+#, fuzzy
+msgid "devcp_status_confirm_no"
+msgstr "No, cancel"
+
+#: views/developers/addon_status_confirm.thtml:67
+#, fuzzy
+msgid "devcp_status_confirm_public"
+msgstr ""
+"Making this add-on public will make it available for anyone to download and "
+"will begin offering updates to existing users."
+
+#: views/developers/addon_status_confirm.thtml:67
+#, fuzzy
+msgid "devcp_status_confirm_public_sure"
+msgstr "Are you sure you wish to make this add-on public?"
+
+#: views/developers/addon_status_confirm.thtml:63
+#, fuzzy
+msgid "devcp_status_confirm_sandbox"
+msgstr ""
+"Moving this add-on back to the sandbox will require users to login before "
+"downloading and updates will no longer be offered to existing users. Because "
+"your add-on is currently public, you will be able to return here at any time "
+"to make it public again."
+
+#: views/developers/addon_status_confirm.thtml:63
+#, fuzzy
+msgid "devcp_status_confirm_sandbox_sure"
+msgstr "Are you sure you wish to move this add-on to the sandbox?"
+
+#: views/developers/addon_status_confirm.thtml:73
+#, fuzzy
+msgid "devcp_status_confirm_yes"
+msgstr "Yes, I'm Sure"
+
+#: views/developers/addon_status_nominate.thtml:46
+#, fuzzy
+msgid "devcp_status_nominate_error_notice"
+msgstr ""
+"<span>A nomination message is required.</span><br />Please fill in the text "
+"box with the requested information and try again."
+
+#: views/developers/addon_status_nominate.thtml:55
+#, fuzzy
+msgid "devcp_status_nominate_header"
+msgstr "Add-on Nomination"
+
+#: views/developers/dashboard.thtml:85
+msgid "devcp_summary_lastversion"
+msgstr "Latest Version:"
+
+#. %s is the add-on name.
+#: views/developers/addon_edit.thtml:43
+#: views/developers/addon_edit_authors.thtml:44
+#: views/developers/versions_delete.thtml:43
+#: views/developers/addon_edit_properties.thtml:44
+#: views/developers/addon_edit_descriptions.thtml:44
+#: views/developers/versions_edit.thtml:44
+#: views/developers/addon_edit_categories.thtml:43
+#: views/developers/versions.thtml:43
+#, fuzzy
+msgid "devcp_title_edit_addon"
+msgstr "Edit %s"
+
+#. title attribute for a javascript link that pops up a help dialog.
+#: views/elements/translationbox.thtml:68
+#, fuzzy
+msgid "devcp_transbox_a_title_help"
+msgstr "Help (does not leave page)"
+
+#: views/elements/translationbox.thtml:68
+#, fuzzy
+msgid "devcp_transbox_alt_help"
+msgstr "Help"
+
+#. %1$s is <span>17</span>, %2$s is 42.
+#: views/elements/translationbox.thtml:101
+#, fuzzy
+msgid "devcp_transbox_chars_used"
+msgstr "Characters used: %1$s / %2$s"
+
+#: views/elements/translationbox.thtml:132
+#, fuzzy
+msgid "devcp_transbox_delete_sure"
+msgstr "Are you sure you wish to delete this translation?"
+
+#. %s is a locale, like en-US.
+#: views/elements/translationbox.thtml:143
+#, fuzzy
+msgid "devcp_transbox_help_header_tabs"
+msgstr "What are these %s tabs?"
+
+#: views/elements/translationbox.thtml:145
+#, fuzzy
+msgid "devcp_transbox_help_header_what"
+msgstr "What if I don't have any translations?"
+
+#: views/elements/translationbox.thtml:147
+#, fuzzy
+msgid "devcp_transbox_help_hide"
+msgstr "Hide Help"
+
+#: views/elements/translationbox.thtml:146
+#, fuzzy
+msgid "devcp_transbox_help_if"
+msgstr ""
+"If a user browses the site and a translation isn't available in their own "
+"language, it will fall back to your add-on's Default Locale, specified in "
+"the Edit Add-on Properties area. If you don't have any translations, just "
+"enter what you can into your Default Locale, which should be a language you "
+"speak."
+
+#: views/elements/translationbox.thtml:144
+#, fuzzy
+msgid "devcp_transbox_help_transbox"
+msgstr ""
+"This is a <i>Translation Box</i>. It allows you to localize a specific field "
+"into any other languages for which you might have a translation. You can "
+"add, edit, and remove translations using the locale tabs."
+
+#: views/elements/translationbox.thtml:85
+#, fuzzy
+msgid "devcp_transbox_img_add_trans"
+msgstr "Add Translation"
+
+#: views/elements/translationbox.thtml:86
+#, fuzzy
+msgid "devcp_transbox_img_remove_trans"
+msgstr "Remove Translation"
+
+#: views/elements/translationbox.thtml:123
+#, fuzzy
+msgid "devcp_transbox_input_add_all"
+msgstr "Add Locale to All"
+
+#: views/elements/translationbox.thtml:122
+#, fuzzy
+msgid "devcp_transbox_input_add_locale"
+msgstr "Add Locale"
+
+#: views/elements/translationbox.thtml:124
+#: views/elements/translationbox.thtml:135
+#, fuzzy
+msgid "devcp_transbox_input_cancel"
+msgstr "Cancel"
+
+#: views/elements/translationbox.thtml:134
+#, fuzzy
+msgid "devcp_transbox_input_delete"
+msgstr "Delete It"
+
+#: views/elements/translationbox.thtml:113
+#, fuzzy
+msgid "devcp_transbox_select_locale"
+msgstr "Select the locale of the translation to add:"
+
+#. %1$s and %2$s are GUIDs.
+#: controllers/developers_controller.php:343
+#, fuzzy
+msgid "devcp_update_addon_guid_error"
+msgstr ""
+"The add-on GUID used in this file (%1$s) does not match the existing GUID "
+"for this add-on (%2$s)."
+
+#: controllers/developers_controller.php:334
+#, fuzzy
+msgid "devcp_update_addon_priv_error"
+msgstr "You do not have sufficient privileges to update this add-on."
+
+#. %1$s is a version number, %2$s is an add-on ID.
+#: controllers/developers_controller.php:399
+#, fuzzy
+msgid "devcp_update_addon_version_belong_error"
+msgstr "The specified version (%1$s) does not belong to this add-on (%2$s)."
+
+#. %1$s is a version number, maybe 1.1.
+#. %2$s is a URL.
+#: controllers/developers_controller.php:351
+#, fuzzy
+msgid "devcp_update_addon_version_exists_error"
+msgstr ""
+"The version number uploaded (%1$s) already exists for this add-on. If you "
+"are trying to add another file to this version, <a href=\"%2$s\">click here</"
+"a>."
+
+#. %1$s and %2$s are version numbers.
+#: controllers/developers_controller.php:405
+#, fuzzy
+msgid "devcp_update_addon_version_match_error"
+msgstr ""
+"The uploaded version number (%1$s) does not match the existing version "
+"number (%2$s)."
+
+#: views/developers/uploader.thtml:68
+#, fuzzy
+msgid "devcp_uploader_a_start"
+msgstr "Get Started"
+
+#: views/developers/uploader.thtml:137
+#, fuzzy
+msgid "devcp_uploader_ajax_loading"
+msgstr "Uploading file..."
+
+#: views/developers/uploader.thtml:82
+#, fuzzy
+msgid "devcp_uploader_button_agree"
+msgstr "Agree and continue"
+
+#: views/developers/uploader.thtml:157
+#, fuzzy
+msgid "devcp_uploader_button_edit"
+msgstr "Edit My Add-on"
+
+#: views/developers/uploader.thtml:158
+#, fuzzy
+msgid "devcp_uploader_button_later"
+msgstr "I'll complete my add-on later."
+
+#: views/developers/uploader.thtml:168
+#, fuzzy
+msgid "devcp_uploader_button_release"
+msgstr "Add Release Notes"
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/uploader.thtml:156
+#, fuzzy
+msgid "devcp_uploader_created_results"
+msgstr ""
+"<p>Your add-on listing has been successfully created. The basic information "
+"obtained from your uploaded file has been stored, but there's a lot more to "
+"your listing that can be customized.</p><p>Your add-on is currently marked "
+"as <strong>Incomplete</strong>. In order to complete your add-on, you'll "
+"need to make sure it has an accurate name, summary, and description, as well "
+"as at least one selected category. You can edit your add-on's information "
+"using the link below and check the status of your add-on at any time on the "
+"<a %s>status page</a>."
+
+#: views/developers/uploader.thtml:143
+#, fuzzy
+msgid "devcp_uploader_error_correct"
+msgstr "Please correct this problem and upload your file again."
+
+#. %1$s is a version number, %2$s is a status, e.g Public or Incomplete.
+#: views/developers/uploader.thtml:175
+#, fuzzy
+msgid "devcp_uploader_file_created"
+msgstr ""
+"Your new file has been added to version %1$s and is currently marked as %2$s."
+
+#: views/developers/uploader.thtml:154
+#, fuzzy
+msgid "devcp_uploader_header_created"
+msgstr "Add-on Created!"
+
+#: views/developers/uploader.thtml:141
+#, fuzzy
+msgid "devcp_uploader_header_error"
+msgstr "Oops! There seems to be a problem with this file..."
+
+#: views/developers/uploader.thtml:173
+#, fuzzy
+msgid "devcp_uploader_header_file_added"
+msgstr "File Added!"
+
+#: views/developers/uploader.thtml:66
+#, fuzzy
+msgid "devcp_uploader_header_how"
+msgstr "How does it all work?"
+
+#. %s is the version number, e.g. 3.2.
+#: views/developers/uploader.thtml:163
+#, fuzzy
+msgid "devcp_uploader_header_update_created"
+msgstr "Version %s Created"
+
+#: views/developers/uploader.thtml:117
+#, fuzzy
+msgid "devcp_uploader_header_upload"
+msgstr "Upload Your File"
+
+#: views/developers/uploader.thtml:67
+#, fuzzy
+msgid "devcp_uploader_how"
+msgstr ""
+"<p>Thanks for your interest in submitting your add-on to Mozilla Add-ons. "
+"Hosting your add-on on Mozilla Add-ons is the easiest way to handle "
+"distribution of your add-on. Here's what you'll get:</p><ul><li>Each add-on "
+"will have a public display page with information you provide, such as a "
+"brief summary of the add-on's functionality, an optional longer description, "
+"and a showcase of preview screenshots of your add-on.</li><li>Your add-on "
+"will appear in search and browse listings across the site, and even in the "
+"Add-ons Manager of Firefox 3.</li><li>We'll take care of hosting all of your "
+"downloads and providing automatic updates to users when you upload a new "
+"version.</li><li>You'll have access to a statistics dashboard with detailed "
+"information about your user base.</li></ul><p>Add-ons hosted on the site "
+"must be reviewed by a Mozilla Add-ons Editor before they will have all of "
+"the features listed above. If you're ready to start the process and have "
+"your add-on package ready for upload, just click on Get Started below!</p>"
+
+#: views/developers/uploader.thtml:125
+#, fuzzy
+msgid "devcp_uploader_label_platformtype"
+msgstr "Supported Platforms:"
+
+#: views/developers/uploader.thtml:124
+#, fuzzy
+msgid "devcp_uploader_label_upload_field"
+msgstr "Add-on File: "
+
+#: controllers/components/developers.php:1221
+#, fuzzy
+msgid "devcp_uploader_option_other"
+msgstr "Other"
+
+#. %1$s is a number, %2$s is href="..." and should stay in the <a> tag.
+#: views/developers/uploader.thtml:176
+#, fuzzy
+msgid "devcp_uploader_p_pending_file"
+msgstr ""
+"The new file will be available to the public as soon as an editor is able to "
+"review it. There are currently %1$s other add-ons in the queue. Want to be "
+"reviewed faster? Consider <a %2$s>becoming an editor</a>."
+
+#. %1$s is a number, %2$s is href="..." and should stay in the <a> tag.
+#: views/developers/uploader.thtml:166
+#, fuzzy
+msgid "devcp_uploader_p_pending_version"
+msgstr ""
+"The new version will be available to the public as soon as an editor is able "
+"to review it. There are currently %1$s other add-ons in the queue. Want to "
+"be reviewed faster? Consider <a %2$s>becoming an editor</a>."
+
+#. %s is a status, e.g Public or Incomplete.
+#: views/developers/uploader.thtml:165
+#, fuzzy
+msgid "devcp_uploader_p_update_created"
+msgstr "Your new version has been created and is currently marked as %s."
+
+#. %1$s is href="..." and should stay in the 'Versions and Files' <a> tag.
+#. %2$s is href="..." and should stay in the 'current status' <a> tag.
+#: views/developers/uploader.thtml:177
+#, fuzzy
+msgid "devcp_uploader_p_update_file"
+msgstr ""
+"View your new file in the <a %1$s>Versions and Files page</a>, check out "
+"your add-on's <a %2$s>current status</a>, or <b>add release notes</b> by "
+"clicking the button below (highly recommended)."
+
+#. %1$s is href="..." and should stay in the 'Versions and Files' <a> tag.
+#. %2$s is href="..." and should stay in the 'current status' <a> tag.
+#: views/developers/uploader.thtml:167
+#, fuzzy
+msgid "devcp_uploader_p_update_version"
+msgstr ""
+"View your new version in the <a %1$s>Versions and Files page</a>, check out "
+"your add-on's <a %2$s>current status</a>, or <b>add release notes</b> by "
+"clicking the button below (highly recommended)."
+
+#: views/developers/uploader.thtml:118
+#, fuzzy
+msgid "devcp_uploader_p_upload"
+msgstr ""
+"Upload your add-on file using the form below. If you have multiple, platform-"
+"specific files to upload, choose a single file and then upload the others "
+"using the Versions and Files Manager."
+
+#: views/developers/uploader.thtml:125
+#, fuzzy
+msgid "devcp_uploader_platformtype_all"
+msgstr "All"
+
+#: views/developers/uploader.thtml:126
+#, fuzzy
+msgid "devcp_uploader_platformtype_specific"
+msgstr "Specific:"
+
+#. Used as first item in a <select>.
+#: controllers/components/developers.php:1185
+#, fuzzy
+msgid "devcp_uploader_please_choose"
+msgstr "Please Choose..."
+
+#. %1$s is the add-on name, %2$s is the version number.
+#: views/developers/uploader.thtml:57
+#, fuzzy
+msgid "devcp_uploader_title_file"
+msgstr "Add File to %1$s %2$s"
+
+#: views/developers/uploader.thtml:50
+#, fuzzy
+msgid "devcp_uploader_title_submit"
+msgstr "Submit New Add-on"
+
+#. %s is the add-on name.
+#: views/developers/uploader.thtml:54
+#, fuzzy
+msgid "devcp_uploader_title_update"
+msgstr "Update %s"
+
+#. %s is a full <a> tag
+#: controllers/developers_controller.php:503
+#, php-format
+msgid "devcp_valid_app_reference"
+msgstr "Please see %s for reference."
+
+#. This is the text in the <a> tag for devcp_valid_app_reference. This should be
+#. fixed.
+#: controllers/developers_controller.php:503
+msgid "devcp_valid_app_reference_linktext"
+msgstr "this page"
+
+#: controllers/developers_controller.php:581
+#, fuzzy
+msgid "devcp_verify_author_error"
+msgstr "No account found for that email address."
+
+#: controllers/developers_controller.php:553
+#, fuzzy
+msgid "devcp_verify_search_engine_error"
+msgstr ""
+"Either the XML is invalid or required fields are missing. Please <a href="
+"\"https://developer.mozilla.org/en/Creating_OpenSearch_plugins_for_Firefox"
+"\">read the documentation</a>, verify your add-on, and try again."
+
+#: views/developers/versions.thtml:75
+#, fuzzy
+msgid "devcp_versions_a_cancel"
+msgstr "Cancel"
+
+#: views/developers/versions.thtml:79
+#, fuzzy
+msgid "devcp_versions_a_delete"
+msgstr "Delete Version"
+
+#: views/developers/versions.thtml:74
+#, fuzzy
+msgid "devcp_versions_a_empty"
+msgstr "Remove Empty Version"
+
+#: views/developers/versions.thtml:71
+#, fuzzy
+msgid "devcp_versions_a_remove"
+msgstr "Remove?"
+
+#: views/developers/versions.thtml:91
+#, fuzzy
+msgid "devcp_versions_add"
+msgstr "Add New Version"
+
+#: views/developers/versions_delete.thtml:58
+#, fuzzy
+msgid "devcp_versions_delete_a_cancel"
+msgstr "Cancel"
+
+#: views/developers/versions_delete.thtml:56
+#, fuzzy
+msgid "devcp_versions_delete_a_delete"
+msgstr "Delete Version"
+
+#. Followed by a list of reviews and files that will be removed.
+#: views/developers/versions_delete.thtml:50
+#, fuzzy
+msgid "devcp_versions_delete_also"
+msgstr "This will also delete:"
+
+#: views/developers/versions_delete.thtml:53
+#, fuzzy
+msgid "devcp_versions_delete_files"
+msgid_plural "devcp_versions_delete_files"
+msgstr[0] "%s file"
+msgstr[1] "%s files"
+
+#. %s is the version number.
+#: views/developers/versions_delete.thtml:48
+#, fuzzy
+msgid "devcp_versions_delete_header"
+msgstr "Delete Version %s?"
+
+#: views/developers/versions_delete.thtml:52
+#, fuzzy
+msgid "devcp_versions_delete_reviews"
+msgid_plural "devcp_versions_delete_reviews"
+msgstr[0] "%s review"
+msgstr[1] "%s reviews"
+
+#. %s is the version number.
+#: views/developers/versions_delete.thtml:49
+#, fuzzy
+msgid "devcp_versions_delete_sure"
+msgstr "Are you sure you want to permanently delete version %s?"
+
+#: views/developers/versions_edit.thtml:102
+#: views/developers/versions_edit.thtml:155
+#, fuzzy
+msgid "devcp_versions_edit_a_cancel"
+msgstr "Cancel"
+
+#: views/developers/versions_edit.thtml:101
+#, fuzzy
+msgid "devcp_versions_edit_a_delete"
+msgstr "Delete File"
+
+#: views/developers/versions_edit.thtml:165
+#, fuzzy
+msgid "devcp_versions_edit_a_new_app"
+msgstr "Add New Application"
+
+#: views/developers/versions_edit.thtml:154
+#, fuzzy
+msgid "devcp_versions_edit_a_remove_app"
+msgstr "Remove Application"
+
+#: views/developers/versions_edit.thtml:114
+#, fuzzy
+msgid "devcp_versions_edit_add"
+msgstr "Add New File"
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/versions_edit.thtml:121
+#, fuzzy
+msgid "devcp_versions_edit_adjust"
+msgstr ""
+"Adjusting application information here will allow users to install your add-"
+"on even if the install.rdf in the package indicates that the add-on is "
+"incompatible. <a %s>List of supported applications</a>"
+
+#: views/developers/versions_edit.thtml:153
+#, fuzzy
+msgid "devcp_versions_edit_compat_sure"
+msgstr ""
+"Are you <b>sure</b> you wish to remove compatibility with this application?"
+
+#: views/developers/versions_edit.thtml:100
+#, fuzzy
+msgid "devcp_versions_edit_delete_sure"
+msgstr "Are you <b>sure</b> you wish to permanently delete this file?"
+
+#: views/developers/versions_edit.thtml:203
+#, fuzzy
+msgid "devcp_versions_edit_header_approval"
+msgstr "Approval Information"
+
+#: views/developers/versions_edit.thtml:120
+#, fuzzy
+msgid "devcp_versions_edit_header_compat"
+msgstr "Compatible Applications"
+
+#: views/developers/versions_edit.thtml:74
+#, fuzzy
+msgid "devcp_versions_edit_header_file"
+msgstr "File Information"
+
+#: views/developers/versions_edit.thtml:189
+#, fuzzy
+msgid "devcp_versions_edit_header_license"
+msgstr "License"
+
+#. %s is the version number.
+#: views/developers/versions_edit.thtml:53
+#, fuzzy
+msgid "devcp_versions_edit_header_manage"
+msgstr "Manage Version %s"
+
+#: views/developers/versions_edit.thtml:212
+#, fuzzy
+msgid "devcp_versions_edit_header_notes"
+msgstr "Approval Notes"
+
+#: views/developers/versions_edit.thtml:98
+#, fuzzy
+msgid "devcp_versions_edit_img_delete"
+msgstr "Delete File"
+
+#. %1$s is the file id, e.g. 18723.
+#. %2$s is the platform name, e.g. ALL or Windows.
+#. %3$s is the _('date) created.
+#. %4$s is the status, e.g. "In Sandbox" or "Public".
+#. %5$s is the _('date') status was changed.
+#: views/developers/versions_edit.thtml:208
+#, fuzzy
+msgid "devcp_versions_edit_li_file"
+msgstr "File %1$s (%2$s) created on %3$s and changed to %4$s on %5$s"
+
+#: views/developers/versions_edit.thtml:190
+#, fuzzy
+msgid "devcp_versions_edit_license_description"
+msgstr ""
+"Please select the appropriate license for your add-on. This license "
+"specifies the rights you grant on your source code."
+
+#: views/developers/versions_edit.thtml:111
+#, fuzzy
+msgid "devcp_versions_edit_no_files"
+msgstr "No files found."
+
+#: views/developers/versions_edit.thtml:213
+#, fuzzy
+msgid "devcp_versions_edit_optional"
+msgstr "Optional information for the Editor that reviews this version."
+
+#: views/developers/versions_edit.thtml:151
+#, fuzzy
+msgid "devcp_versions_edit_remove_compat"
+msgstr "Remove Application Compatibility"
+
+#: views/developers/versions_edit.thtml:167
+#, fuzzy
+msgid "devcp_versions_edit_select_app"
+msgstr "Please Select an Application"
+
+#: views/developers/versions_edit.thtml:78
+#, fuzzy
+msgid "devcp_versions_edit_th_file"
+msgstr "File"
+
+#: views/developers/versions_edit.thtml:79
+#, fuzzy
+msgid "devcp_versions_edit_th_platform"
+msgstr "Platform"
+
+#: views/developers/versions_edit.thtml:80
+#, fuzzy
+msgid "devcp_versions_edit_th_size"
+msgstr "Size"
+
+#: views/developers/versions_edit.thtml:81
+#, fuzzy
+msgid "devcp_versions_edit_th_status"
+msgstr "Status"
+
+#: views/developers/versions_edit.thtml:183
+#, fuzzy
+msgid "devcp_versions_edit_transbox_releasenotes_description"
+msgstr ""
+"Information about changes in this release, new features, known bugs, and "
+"other useful information specific to this release/version. This information "
+"will also be available to users updating the add-on in the Firefox 3 Add-ons "
+"Manager interface."
+
+#: views/developers/versions_edit.thtml:182
+#, fuzzy
+msgid "devcp_versions_edit_transbox_releasenotes_name"
+msgstr "Release Notes"
+
+#: views/developers/versions_edit.thtml:164
+#, fuzzy
+msgid "devcp_versions_edit_unsaved_compat"
+msgstr ""
+"<strong>You have unsaved changes.</strong> Compatibility will not be deleted "
+"until you click Update Version below."
+
+#: views/developers/versions_edit.thtml:113
+#, fuzzy
+msgid "devcp_versions_edit_unsaved_files"
+msgstr ""
+"<strong>You have unsaved changes.</strong> Files will not be deleted until "
+"you click Update Version below."
+
+#: views/developers/versions_edit.thtml:218
+#, fuzzy
+msgid "devcp_versions_edit_update"
+msgstr "Update Versions"
+
+#: views/developers/versions.thtml:49
+#, fuzzy
+msgid "devcp_versions_header_manage"
+msgstr "Manage Versions and Files"
+
+#: views/developers/versions.thtml:87
+#, fuzzy
+msgid "devcp_versions_no_versions"
+msgstr "No versions."
+
+#. %s is a version number, base 10.
+#: views/developers/versions.thtml:46
+#, fuzzy
+msgid "devcp_versions_notice_success"
+msgstr "Version %s deleted successfully."
+
+#: views/developers/versions.thtml:73
+#, fuzzy
+msgid "devcp_versions_p_remove"
+msgstr ""
+"This version has no files associated with it and can be removed. Would you "
+"like to remove this version?"
+
+#: views/developers/versions.thtml:58
+#, fuzzy
+msgid "devcp_versions_th_created"
+msgstr "Created"
+
+#: views/developers/versions.thtml:57
+#, fuzzy
+msgid "devcp_versions_th_status"
+msgstr "Status"
+
+#: views/developers/versions.thtml:56
+#, fuzzy
+msgid "devcp_versions_th_version"
+msgstr "Version"
+
+#: controllers/downloads_controller.php:91
+#, fuzzy
+msgid "downloads_disable_warning"
+msgstr "This add-on is disabled"
+
+#: controllers/components/editors.php:57
+#, fuzzy
+msgid "editor_review_error_addon_not_nominated"
+msgstr "This add-on has not been nominated."
+
+#: controllers/components/editors.php:213
+#, fuzzy
+msgid "editor_review_error_file_not_pending"
+msgstr "This file is not pending review."
+
+#. Actions are, for example: approving or rejecting
+#: controllers/components/editors.php:79
+#: controllers/components/editors.php:182
+#, fuzzy
+msgid "editor_review_error_no_action"
+msgstr "Please select a review action."
+
+#: controllers/components/editors.php:192
+#, fuzzy
+msgid "editor_review_error_no_applications"
+msgstr "Please enter the applications you tested."
+
+#. Comments are required when an editor approves or rejects an add-on.
+#: controllers/components/editors.php:84
+#: controllers/components/editors.php:187
+#, fuzzy
+msgid "editor_review_error_no_comments"
+msgstr "Please enter review comments."
+
+#: controllers/components/editors.php:161
+#, fuzzy
+msgid "editor_review_error_no_files"
+msgstr "Please select at least one file to review."
+
+#: controllers/components/editors.php:197
+#, fuzzy
+msgid "editor_review_error_no_operating_system"
+msgstr "Please enter the operating systems you tested."
+
+#: views/editors/logs.thtml:51
+#, fuzzy
+msgid "editorcp_logs_button_filter"
+msgstr "Filter"
+
+#: views/editors/logs.thtml:44
+#, fuzzy
+msgid "editorcp_logs_filter_by"
+msgstr "Filter by type/action"
+
+#: views/editors/logs.thtml:42 controllers/editors_controller.php:964
+#, fuzzy
+msgid "editorcp_logs_page_heading"
+msgstr "Event Log"
+
+#: views/elements/developers/editorsmenu.thtml:60
+#, fuzzy
+msgid "editorcp_menu_eventlog_link"
+msgstr "Event Log"
+
+#: views/elements/developers/editorsmenu.thtml:62
+#, fuzzy
+msgid "editorcp_menu_mainpage_link"
+msgstr "Back to Main"
+
+#: views/elements/developers/editorsmenu.thtml:61
+#, fuzzy
+msgid "editorcp_menu_reviewlog_link"
+msgstr "Review Log"
+
+#: views/elements/developers/editorsmenu.thtml:55
+#, fuzzy
+msgid "editorcp_menu_summary_link"
+msgstr "Editor Summary"
+
+#: views/elements/developers/editorsmenu.thtml:52
+#, fuzzy
+msgid "editorcp_menu_title"
+msgstr "Editor Tools"
+
+#: views/editors/reviewlog.thtml:49
+#, fuzzy
+msgid "editorcp_reviewlog_button_filter"
+msgstr "Filter"
+
+#: views/editors/reviewlog.thtml:58
+#, fuzzy
+msgid "editorcp_reviewlog_column_action"
+msgstr "Action"
+
+#: views/editors/reviewlog.thtml:56
+#, fuzzy
+msgid "editorcp_reviewlog_column_addon"
+msgstr "Add-on"
+
+#: views/editors/reviewlog.thtml:55
+#, fuzzy
+msgid "editorcp_reviewlog_column_date"
+msgstr "Date"
+
+#: views/editors/reviewlog.thtml:57
+#, fuzzy
+msgid "editorcp_reviewlog_column_editor"
+msgstr "Editor"
+
+#: views/editors/reviewlog.thtml:94
+#, fuzzy
+msgid "editorcp_reviewlog_comments_hide"
+msgstr "Hide Comments"
+
+#: views/editors/reviewlog.thtml:93
+#, fuzzy
+msgid "editorcp_reviewlog_comments_show"
+msgstr "Show Comments"
+
+#. %1$s and %2$s are full <input> tags for dates
+#: views/editors/reviewlog.thtml:45
+#, fuzzy, php-format
+msgid "editorcp_reviewlog_entries_between"
+msgstr "View entries between %s and %s"
+
+#: views/editors/reviewlog.thtml:104
+#, fuzzy
+msgid "editorcp_reviewlog_none_found"
+msgstr "No reviews found for this period."
+
+#: views/editors/reviewlog.thtml:42
+#, fuzzy
+msgid "editorcp_reviewlog_page_heading"
+msgstr "Review Log"
+
+#: views/editors/summary.thtml:61
+#, fuzzy
+msgid "editorcp_summary_monthreviews_heading"
+msgstr "Month Reviews"
+
+#: views/editors/summary.thtml:77
+#, fuzzy
+msgid "editorcp_summary_neweditors_heading"
+msgstr "New Editors"
+
+#: views/editors/summary.thtml:42
+#, fuzzy
+msgid "editorcp_summary_page_heading"
+msgstr "Editor Summary"
+
+#: views/editors/summary.thtml:94
+#, fuzzy
+msgid "editorcp_summary_recentactivity_heading"
+msgstr "Recent Editor Activity"
+
+#: views/editors/summary.thtml:45
+#, fuzzy
+msgid "editorcp_summary_totalreviews_heading"
+msgstr "Total Reviews"
+
+#: controllers/editors_controller.php:248
+#: controllers/editors_controller.php:249
+msgid "editors_addon_review_pagetitle"
+msgstr "Review Add-on"
+
+#: controllers/editors_controller.php:349
+msgid "editors_error_js-formerror"
+msgstr "Please complete the following fields:"
+
+#: controllers/editors_controller.php:350
+msgid "editors_error_review_one_file"
+msgstr "Please select at least one file to review."
+
+#: controllers/editors_controller.php:274
+msgid "editors_error_self_reviews_forbidden"
+msgstr "Self-reviews are not allowed."
+
+#: controllers/editors_controller.php:699
+msgid "editors_external_software"
+msgstr "External Software"
+
+#: views/editors/featured.thtml:120 views/editors/featured.thtml:121
+#, fuzzy
+msgid "editors_featured_add_feature"
+msgstr "Add feature"
+
+#: views/editors/featured.thtml:126
+#, fuzzy
+msgid "editors_featured_add_feature_submit"
+msgstr "Add"
+
+#: views/editors/featured.thtml:49 controllers/editors_controller.php:832
+#: controllers/editors_controller.php:848
+#, fuzzy
+msgid "editors_featured_addon_add_failure"
+msgstr "Failed to add feature."
+
+#: controllers/editors_controller.php:851
+#, fuzzy
+msgid "editors_featured_addon_add_success"
+msgstr "Successfully added feature."
+
+#: views/editors/featured.thtml:50 controllers/editors_controller.php:839
+#: controllers/editors_controller.php:868
+#: controllers/editors_controller.php:886
+#, fuzzy
+msgid "editors_featured_addon_edit_failure"
+msgstr "Failed to edit feature."
+
+#: views/editors/featured.thtml:51 controllers/editors_controller.php:888
+#, fuzzy
+msgid "editors_featured_addon_edit_success"
+msgstr "Successfully edited feature."
+
+#: views/editors/featured.thtml:53 controllers/editors_controller.php:861
+#, fuzzy
+msgid "editors_featured_addon_invalid_locale"
+msgstr "One or more locales are invalid."
+
+#: views/editors/featured.thtml:52 controllers/editors_controller.php:906
+#, fuzzy
+msgid "editors_featured_addon_remove_failure"
+msgstr "Failed to remove feature."
+
+#: controllers/editors_controller.php:901
+#, fuzzy
+msgid "editors_featured_addon_remove_success"
+msgstr "Successfully removed feature."
+
+#: controllers/editors_controller.php:915
+#: controllers/editors_controller.php:917
+#, fuzzy
+msgid "editors_featured_addons_pagetitle"
+msgstr "Featured Add-ons"
+
+#: views/editors/featured.thtml:54 views/editors/featured.thtml:107
+#, fuzzy
+msgid "editors_featured_edit_feature_submit"
+msgstr "Go"
+
+#: views/editors/featured.thtml:90 views/editors/featured.thtml:91
+#, fuzzy
+msgid "editors_featured_remove_feature"
+msgstr "Remove feature"
+
+#: views/editors/queue.thtml:46
+msgid "editors_filter_queue"
+msgstr "Filter Queue"
+
+#: views/editors/queue.thtml:182
+#, fuzzy
+msgid "editors_helpful_links"
+msgstr "Helpful Links"
+
+#: views/editors/queue.thtml:182
+#, fuzzy
+msgid "editors_link_guide"
+msgstr "Editors' Guide"
+
+#: views/editors/queue.thtml:182
+#, fuzzy
+msgid "editors_link_policy"
+msgstr "Add-on Policy"
+
+#: views/editors/queue.thtml:47
+msgid "editors_notice_filter_session"
+msgstr "These filters will remain in place for this session or until cleared."
+
+# %1 is the queue mode
+#. %1 is the queue mode
+#: views/editors/queue.thtml:177 views/admin/flagged_queue.thtml:89
+msgid "editors_notice_none_found"
+msgstr "There are currently no %s add-ons to review."
+
+#: controllers/editors_controller.php:1040
+msgid "editors_one_day"
+msgstr "1 day"
+
+#: controllers/editors_controller.php:1048
+msgid "editors_one_hour"
+msgstr "1 hour"
+
+#: controllers/editors_controller.php:1056
+msgid "editors_one_minute"
+msgstr "1 minute"
+
+#: controllers/editors_controller.php:64 controllers/editors_controller.php:73
+#: controllers/editors_controller.php:77
+msgid "editors_pagetitle"
+msgstr "Editor Control Panel"
+
+#. %s is a comma separated list of platforms. Example: Windows, OS X
+#: controllers/editors_controller.php:680
+#: controllers/editors_controller.php:683
+#, php-format
+msgid "editors_platform_x_only"
+msgstr "%s only"
+
+#: controllers/editors_controller.php:695
+msgid "editors_pre-release"
+msgstr "Pre-release"
+
+# %1 is the app name
+#. %1 is the app name
+#: views/editors/queue.thtml:131
+#, php-format
+msgid "editors_queue_app_compatibility"
+msgstr "%s Compatibility"
+
+#: views/editors/queue.thtml:51
+#, fuzzy
+msgid "editors_queue_filter_label_addon"
+msgstr "Add-on or Author Email"
+
+#: views/editors/queue.thtml:72
+#, fuzzy
+msgid "editors_queue_filter_label_addontypes"
+msgstr "Add-on Types"
+
+#: views/editors/queue.thtml:56
+#, fuzzy
+msgid "editors_queue_filter_label_application"
+msgstr "Application"
+
+#: views/editors/queue.thtml:61
+#, fuzzy
+msgid "editors_queue_filter_label_maxversion"
+msgstr "Max. Version"
+
+#: views/editors/queue.thtml:78
+#, fuzzy
+msgid "editors_queue_filter_label_platforms"
+msgstr "Platforms"
+
+#: views/editors/queue.thtml:66
+#, fuzzy
+msgid "editors_queue_filter_label_submissionage"
+msgstr "Age of Submission (days)"
+
+#. %1$s is a number
+#: views/editors/queue.thtml:90
+#, fuzzy
+msgid "editors_queue_filter_result_count"
+msgid_plural "editors_queue_filter_result_count"
+msgstr[0] "Results of your filtered search: <strong>%1$s</strong> Add-on"
+msgstr[1] "Results of your filtered search: <strong>%1$s</strong> Add-ons"
+
+#: views/editors/queue.thtml:84
+msgid "editors_queue_submit_clean"
+msgstr "Clear"
+
+#: views/editors/queue.thtml:83
+msgid "editors_queue_submit_filter"
+msgstr "Filter"
+
+#: controllers/editors_controller.php:133
+msgid "editors_queues_disabled"
+msgstr ""
+"All review queues are currently disabled. Please check back at a later time."
+
+#: views/editors/review.thtml:149
+#, fuzzy
+msgid "editors_review_a_edit_item"
+msgstr "Edit Item"
+
+#: views/editors/review.thtml:146
+#, fuzzy
+msgid "editors_review_a_item_history"
+msgstr "Item History"
+
+#: views/editors/review.thtml:148
+#, fuzzy
+msgid "editors_review_a_item_homepage"
+msgstr "Item Homepage"
+
+#: views/editors/review.thtml:145
+#, fuzzy
+msgid "editors_review_a_item_overview"
+msgstr "Item Overview"
+
+#: views/editors/review.thtml:147
+#, fuzzy
+msgid "editors_review_a_previews"
+msgstr "Previews"
+
+#: controllers/editors_controller.php:345
+msgid "editors_review_action"
+msgstr "Review Action"
+
+#: views/editors/review.thtml:159
+#, fuzzy
+msgid "editors_review_action_info"
+msgstr "Request More Information"
+
+#: views/editors/review.thtml:157
+msgid "editors_review_action_public"
+msgstr "Push to Public"
+
+#: views/editors/review.thtml:160
+msgid "editors_review_action_request_superreview"
+msgstr "Request Super-Review"
+
+#: views/editors/review.thtml:158
+msgid "editors_review_action_sandbox"
+msgstr "Retain in Sandbox"
+
+#: controllers/editors_controller.php:346
+msgid "editors_review_comments"
+msgstr "Review Comments"
+
+#: views/editors/review.thtml:182
+#, fuzzy
+msgid "editors_review_details_info_request"
+msgstr ""
+"Use this form to request more information from the author. They will receive "
+"an email and be able to answer here. You will be notified by email when they "
+"reply."
+
+#: views/editors/review.thtml:174
+msgid "editors_review_details_nominated_public"
+msgstr ""
+"This will mark the add-on and its most recent version and files as public. "
+"Future versions will go into the sandbox until they are reviewed by an "
+"editor."
+
+#: views/editors/review.thtml:177
+msgid "editors_review_details_nominated_sandbox"
+msgstr "This will retain the add-on in the sandbox."
+
+#: views/editors/review.thtml:166
+msgid "editors_review_details_pending_public"
+msgstr ""
+"This will approve a sandboxed version of a public add-on to appear on the "
+"public side."
+
+#: views/editors/review.thtml:169
+msgid "editors_review_details_pending_sandbox"
+msgstr ""
+"This will cause a sandboxed version of a public add-on to remain in the "
+"sandbox."
+
+#: views/editors/review.thtml:185
+msgid "editors_review_details_superreview"
+msgstr ""
+"If you have concerns about this add-on's security, copyright issues, or "
+"other concerns that an administrator should look into, enter your comments "
+"in the area below. They will be sent to administrators, not the author."
+
+#: views/editors/review.thtml:134
+#, fuzzy
+msgid "editors_review_file_diff_link"
+msgstr "Compare with public version"
+
+#: views/editors/review.thtml:131
+msgid "editors_review_file_viewcontents_link"
+msgstr "View Contents"
+
+#: views/editors/review.thtml:65
+msgid "editors_review_header_authors"
+msgstr "Authors:"
+
+#: views/editors/review.thtml:79
+msgid "editors_review_header_categories"
+msgstr "Categories:"
+
+#: views/editors/review.thtml:92
+msgid "editors_review_header_compatibility"
+msgstr "Compatibility:"
+
+#: views/editors/review.thtml:251
+msgid "editors_review_header_description"
+msgstr "Description"
+
+#: views/editors/review.thtml:275
+msgid "editors_review_header_devcomments"
+msgstr "Developer Comments"
+
+#: views/editors/review.thtml:263
+msgid "editors_review_header_eula"
+msgstr "EULA"
+
+#: views/editors/review.thtml:115
+msgid "editors_review_header_files"
+msgstr "Files:"
+
+#: views/editors/review.thtml:284
+msgid "editors_review_header_itemhistory"
+msgstr "Item History"
+
+#: views/editors/review.thtml:232
+#, fuzzy
+msgid "editors_review_header_nominationmessage"
+msgstr "Nomination Message"
+
+#: views/editors/review.thtml:311
+msgid "editors_review_header_previews"
+msgstr "Previews"
+
+#: views/editors/review.thtml:269
+msgid "editors_review_header_privacy"
+msgstr "Privacy Policy"
+
+# %1 is the addon name and version
+#. %1 is the add-on name and version
+#: views/editors/review.thtml:56
+#, php-format
+msgid "editors_review_header_review"
+msgstr "Review %s"
+
+#: views/editors/review.thtml:239
+msgid "editors_review_header_reviewernotes"
+msgstr "Notes to Reviewer"
+
+#: views/editors/review.thtml:245
+msgid "editors_review_header_summary"
+msgstr "Summary"
+
+#: views/editors/review.thtml:257
+msgid "editors_review_header_versionnotes"
+msgstr "Version Notes"
+
+#. a noun: shown in an add-on's editor review history
+#: views/elements/developers/editors_review_history_item.thtml:80
+#, fuzzy
+msgid "editors_review_history_info_reply"
+msgstr "Reply"
+
+#: views/elements/developers/editors_review_history_item.thtml:78
+#, fuzzy
+msgid "editors_review_history_info_request"
+msgstr "Information Request"
+
+#: views/elements/developers/editors_review_history_item.thtml:62
+#: views/editors/reviewlog.thtml:77
+msgid "editors_review_history_nominated_adminreview"
+msgstr "Admin Review"
+
+#: views/elements/developers/editors_review_history_item.thtml:56
+#: views/editors/reviewlog.thtml:71
+msgid "editors_review_history_nominated_approved"
+msgstr "Nomination Approved/Public"
+
+#: views/elements/developers/editors_review_history_item.thtml:59
+#: views/editors/reviewlog.thtml:74
+msgid "editors_review_history_nominated_denied"
+msgstr "Nomination Denied/Sandbox"
+
+#: views/editors/review.thtml:303
+msgid "editors_review_history_nonefound"
+msgstr "No previous review entries could be found."
+
+#: views/elements/developers/editors_review_history_item.thtml:73
+#: views/editors/reviewlog.thtml:88
+msgid "editors_review_history_pending_adminreview"
+msgstr "Admin Review"
+
+#: views/elements/developers/editors_review_history_item.thtml:67
+#: views/editors/reviewlog.thtml:82
+msgid "editors_review_history_pending_approved"
+msgstr "Approved/Public"
+
+#: views/elements/developers/editors_review_history_item.thtml:70
+#: views/editors/reviewlog.thtml:85
+msgid "editors_review_history_pending_denied"
+msgstr "Denied/Sandbox"
+
+#. link text in an add-on's editor review history, allowing to hide and show an information request's replies
+#. %1 is the number of replies
+#: views/elements/developers/editors_review_history_item.thtml:90
+#, fuzzy
+msgid "editors_review_history_show_hide_replies"
+msgid_plural "editors_review_history_show_hide_replies"
+msgstr[0] "Show/Hide Replies (%1$s)"
+msgstr[1] "Show/Hide Replies (%1$s)"
+
+#: views/editors/review.thtml:208
+msgid "editors_review_label_applications"
+msgstr "Applications:"
+
+#: views/editors/review.thtml:196
+msgid "editors_review_label_cannedresponse"
+msgstr "or select a canned response:"
+
+#: views/editors/review.thtml:190
+msgid "editors_review_label_comments"
+msgstr "Comments:"
+
+#: views/editors/review.thtml:204
+msgid "editors_review_label_operating_systems"
+msgstr "Operating Systems:"
+
+#: views/editors/review.thtml:285 views/editors/review.thtml:312
+msgid "editors_review_link_pagetop"
+msgstr "Top"
+
+#: views/editors/review.thtml:141
+#, fuzzy
+msgid "editors_review_mulitple_notice"
+msgstr ""
+"Notice: Only review more than one file if you have tested EVERY file you "
+"select."
+
+#: views/editors/review.thtml:51
+#, fuzzy
+msgid "editors_review_next_link"
+msgstr "next &raquo;"
+
+#: views/editors/review.thtml:322
+msgid "editors_review_previews_notfound"
+msgstr "No previews found."
+
+#: views/editors/review.thtml:50
+#, fuzzy
+msgid "editors_review_previous_link"
+msgstr "&laquo; prev"
+
+#: controllers/editors_controller.php:144
+#: controllers/editors_controller.php:146
+msgid "editors_review_queue_pagetitle"
+msgstr "Review Queue"
+
+# %1 is the add-ons rank in the queue, %2 is the total queue length
+#. %1 is the add-ons rank in the queue, %2 is the total queue length
+#: views/editors/review.thtml:47
+#, fuzzy
+msgid "editors_review_rank_in_queue"
+msgstr "<strong># %1$s</strong> of %2$s in queue"
+
+#. %1 is the add-ons rank in the queue, %2 is the total queue length. Both numbers
+#: views/editors/review.thtml:45
+#, fuzzy
+msgid "editors_review_rank_in_queue_filtered"
+msgstr "<strong># %1$s</strong> of %2$s in queue (filtered)"
+
+#: views/editors/review.thtml:223
+msgid "editors_review_submit_process_action"
+msgstr "Process Action"
+
+#: views/editors/review.thtml:293
+msgid "editors_review_th_action"
+msgstr "Action"
+
+#: views/editors/review.thtml:294
+msgid "editors_review_th_comments"
+msgstr "Comments"
+
+#: views/editors/review.thtml:291
+msgid "editors_review_th_date"
+msgstr "Date"
+
+#: views/editors/review.thtml:292
+msgid "editors_review_th_reviewer"
+msgstr "Reviewer"
+
+#: views/editors/review.thtml:290
+msgid "editors_review_th_version_file"
+msgstr "Version/File"
+
+#: views/editors/review.thtml:217
+#, fuzzy
+msgid "editors_review_update_notify_once"
+msgstr ""
+"Notify me the next time this add-on is updated. (Subsequent updates will not "
+"generate an email)"
+
+#: controllers/editors_controller.php:298
+msgid "editors_reviewed_successfully"
+msgstr "Review successfully processed."
+
+#: views/editors/reviews_queue.thtml:106
+#, fuzzy
+msgid "editors_reviews_action_delete_review"
+msgstr "Delete review"
+
+#: views/editors/reviews_queue.thtml:104
+#, fuzzy
+msgid "editors_reviews_action_keep"
+msgstr "Remove flags; keep review"
+
+#: views/editors/reviews_queue.thtml:102
+msgid "editors_reviews_action_skip"
+msgstr "Skip"
+
+#: views/editors/reviews_queue.thtml:100
+msgid "editors_reviews_header_action"
+msgstr "Action"
+
+#: views/editors/reviews_queue.thtml:67
+#, fuzzy
+msgid "editors_reviews_in_reply_to"
+msgstr "In reply to:"
+
+#: controllers/editors_controller.php:748
+msgid "editors_reviews_processed"
+msgstr "Reviews processed successfully!"
+
+#: views/editors/reviews_queue.thtml:117
+msgid "editors_reviews_queue_empty"
+msgstr "There are currently no reviews in moderation."
+
+#: views/editors/reviews_queue.thtml:111
+msgid "editors_reviews_submit_process_reviews"
+msgstr "Process Reviews"
+
+#: controllers/editors_controller.php:691
+msgid "editors_site_specific"
+msgstr "Site Specific"
+
+#: controllers/editors_controller.php:348
+msgid "editors_tested_app"
+msgstr "Tested Application"
+
+#: controllers/editors_controller.php:347
+msgid "editors_tested_os"
+msgstr "Tested Operating Systems"
+
+#: views/editors/queue.thtml:151
+msgid "editors_th_additional_info"
+msgstr "Additional Information"
+
+#: views/editors/featured.thtml:63 views/editors/queue.thtml:109
+#: views/admin/flagged_queue.thtml:53
+msgid "editors_th_addon"
+msgstr "Add-on"
+
+#: views/editors/queue.thtml:125
+msgid "editors_th_addontype"
+msgstr "Type"
+
+#: views/editors/featured.thtml:64
+#, fuzzy
+msgid "editors_th_locales"
+msgstr "Restrict to locales?"
+
+#: views/editors/queue.thtml:148
+#, fuzzy
+msgid "editors_th_nomination_age"
+msgstr "Time in Queue"
+
+#: views/editors/queue.thtml:101 views/editors/queue.thtml:117
+#: views/editors/queue.thtml:144
+#, fuzzy
+msgid "editors_th_sort_ascending"
+msgstr "Ascending sort"
+
+#: views/editors/queue.thtml:105 views/editors/queue.thtml:121
+#: views/editors/queue.thtml:140
+#, fuzzy
+msgid "editors_th_sort_descending"
+msgstr "Descending sort"
+
+#. %s is a number
+#: controllers/editors_controller.php:1036
+#, php-format
+msgid "editors_x_days"
+msgstr "%s days"
+
+#. %s is a number
+#: controllers/editors_controller.php:1044
+#, php-format
+msgid "editors_x_hours"
+msgstr "%s hours"
+
+#. %s is a number
+#: controllers/editors_controller.php:1052
+#, php-format
+msgid "editors_x_minutes"
+msgstr "%s minutes"
+
+#: views/errors/error401.thtml:50 controllers/components/simple_acl.php:81
+#: controllers/components/simple_acl.php:82
+#: controllers/components/simple_acl.php:83 controllers/components/amo.php:607
+#: controllers/components/amo.php:608 controllers/components/amo.php:609
+#: controllers/reviews_controller.php:353
+#: controllers/reviews_controller.php:485
+#: controllers/collections_controller.php:438
+#: controllers/collections_controller.php:496
+#: controllers/collections_controller.php:504
+#: controllers/collections_controller.php:971
+#: controllers/collections_controller.php:1034
+#: controllers/collections_controller.php:1077
+msgid "error_access_denied"
+msgstr "Access Denied"
+
+#: views/errors/error401.thtml:52
+msgid "error_access_denied_message"
+msgstr "You are not authorized to view this page."
+
+#: controllers/collections_controller.php:1039
+#, fuzzy
+msgid "error_addon_exists"
+msgstr "Add-on already exists!"
+
+#: controllers/developers_controller.php:200
+#: controllers/developers_controller.php:593
+#: controllers/developers_controller.php:1016
+#: controllers/developers_controller.php:1429
+#: controllers/downloads_controller.php:95
+#: controllers/downloads_controller.php:102
+#: controllers/downloads_controller.php:164
+#: controllers/statistics_controller.php:135
+#: controllers/previews_controller.php:115
+#: controllers/previews_controller.php:206
+#: controllers/previews_controller.php:307
+#: controllers/reviews_controller.php:77
+#: controllers/reviews_controller.php:240
+#: controllers/reviews_controller.php:332
+#: controllers/reviews_controller.php:340 controllers/api_controller.php:123
+#: controllers/api_controller.php:759 controllers/addons_controller.php:131
+#: controllers/addons_controller.php:197
+#: controllers/addons_controller.php:1407
+#: controllers/addons_controller.php:1465
+#: controllers/addons_controller.php:1469
+#: controllers/addons_controller.php:1503
+#: controllers/editors_controller.php:265
+#: controllers/collections_controller.php:1041
+#: controllers/collections_controller.php:1074
+msgid "error_addon_notfound"
+msgstr "Eklenti bulunamadı!"
+
+#: controllers/files_controller.php:83 controllers/files_controller.php:196
+msgid "error_addon_notviewable"
+msgstr "This add-on is not viewable here."
+
+#: controllers/reviews_controller.php:246
+#, fuzzy
+msgid "error_addon_selfreview"
+msgstr "You cannot review your own add-on."
+
+#: controllers/addons_controller.php:970
+msgid "error_browse_no_addons"
+msgstr "Kategoride eklenti yok!"
+
+#: controllers/api_controller.php:424
+#, fuzzy
+msgid "error_collection_feed_notfound"
+msgstr "Add-on feed not found."
+
+#: views/users/register.thtml:65 views/users/edit.thtml:194
+msgid "error_email_invalid"
+msgstr "Bu geçerli bir eposta adresi değil."
+
+#: views/users/pwreset.thtml:74 views/users/register.thtml:70
+#: views/users/register.thtml:80 views/users/register.thtml:86
+#: views/users/edit.thtml:105 views/users/edit.thtml:111
+#: views/users/edit.thtml:192 views/admin/users_edit.thtml:78
+#: views/admin/users_edit.thtml:83 views/reviews/add.thtml:80
+#: views/reviews/add.thtml:104
+msgid "error_field_required"
+msgstr "Bu alan boş bırakılmamalı."
+
+#: controllers/files_controller.php:75 controllers/files_controller.php:93
+#: controllers/files_controller.php:96 controllers/files_controller.php:163
+#: controllers/files_controller.php:176 controllers/files_controller.php:185
+#: controllers/files_controller.php:204 controllers/editors_controller.php:412
+msgid "error_file_notfound"
+msgstr "File not found!"
+
+#. %s is a filename
+#: controllers/editors_controller.php:430
+#, php-format
+msgid "error_file_x_notfound"
+msgstr "File error: %s does not exist."
+
+#: views/collections/add.thtml:55 views/collections/edit.thtml:89
+#: views/users/register.thtml:54 views/users/edit.thtml:81
+#: views/reviews/add.thtml:70 controllers/groups_controller.php:80
+#: controllers/groups_controller.php:102
+msgid "error_formerrors"
+msgstr "Bu formda hatalar var. Lütfen düzeltip yeniden gönderin."
+
+#: views/users/register.thtml:109
+#, fuzzy
+msgid "error_invalid_captcha"
+msgstr "Invalid captcha, please try again!"
+
+#: views/users/register.thtml:100 views/users/edit.thtml:125
+#: views/admin/users_edit.thtml:101
+msgid "error_invalid_url"
+msgstr ""
+"This URL has an invalid format. Valid URLs look like http://example.com/"
+"my_page."
+
+#. %s is a string representing what's missing. Example: file_id
+#: controllers/downloads_controller.php:65
+#: controllers/users_controller.php:185 controllers/users_controller.php:264
+#: controllers/users_controller.php:559 controllers/users_controller.php:653
+#: controllers/reviews_controller.php:71
+#: controllers/reviews_controller.php:234
+#: controllers/reviews_controller.php:325
+#: controllers/reviews_controller.php:473
+#: controllers/reviews_controller.php:475
+#: controllers/addons_controller.php:182
+#: controllers/addons_controller.php:1381
+#: controllers/addons_controller.php:1455
+#: controllers/collections_controller.php:266
+#: controllers/collections_controller.php:285
+#: controllers/collections_controller.php:346
+#: controllers/collections_controller.php:443
+#: controllers/collections_controller.php:482
+#: controllers/collections_controller.php:936
+#: controllers/collections_controller.php:959
+#: controllers/collections_controller.php:960
+#: controllers/collections_controller.php:975
+#: controllers/collections_controller.php:977
+#: controllers/collections_controller.php:994
+#: controllers/collections_controller.php:1003
+#: controllers/collections_controller.php:1016
+#: controllers/collections_controller.php:1017
+#: controllers/collections_controller.php:1024
+#: controllers/collections_controller.php:1070
+#: controllers/collections_controller.php:1090
+#, php-format
+msgid "error_missing_argument"
+msgstr "Eksik argüman: %s"
+
+#: controllers/components/amo.php:507 controllers/components/amo.php:532
+#, fuzzy
+msgid "error_no_files_in_addon"
+msgstr "No Files"
+
+#: controllers/previews_controller.php:200
+msgid "error_preview_notfound"
+msgstr "Preview not found!"
+
+#: views/addons/display.thtml:400 views/reviews/add.thtml:98
+#, fuzzy
+msgid "error_review_rating_required"
+msgstr "You must select a rating."
+
+#: controllers/users_controller.php:160
+msgid "error_user_already_confirmed"
+msgstr "This user account is already confirmed."
+
+#: controllers/users_controller.php:202 controllers/users_controller.php:276
+#: controllers/users_controller.php:569 controllers/users_controller.php:581
+#: controllers/users_controller.php:587 controllers/users_controller.php:610
+#: controllers/users_controller.php:627
+msgid "error_user_badconfirmationcode"
+msgstr "Geçersiz onay kodu!"
+
+#: views/users/pwreset.thtml:79 views/users/register.thtml:75
+#: views/users/edit.thtml:183
+msgid "error_user_confirmpw_nomatch"
+msgstr "Parolalar eÅŸleÅŸmedi."
+
+#: views/users/register.thtml:65 views/users/edit.thtml:190
+#: controllers/users_controller.php:617
+msgid "error_user_email_notunique"
+msgstr "Bu eposta adresi başka bir kullanıcı tarafından alınmış."
+
+#: controllers/users_controller.php:596
+#, fuzzy
+msgid "error_user_emailchange_expired"
+msgstr ""
+"The email change has expired. Please change your email address again in your "
+"user profile and click the link in the confirmation email as soon as you "
+"receive it."
+
+#: controllers/collections_controller.php:985
+#, fuzzy
+msgid "error_user_exists"
+msgstr ""
+"Users can only have one role at a time. Please remove the user from any "
+"existing roles before continuing."
+
+#: views/users/register.thtml:91 views/users/edit.thtml:116
+#: views/admin/users_edit.thtml:88
+msgid "error_user_nickname_notunique"
+msgstr "Bu takma ad alınmış durumda."
+
+#: views/users/pwreset.thtml:54 controllers/users_controller.php:191
+#: controllers/users_controller.php:270 controllers/users_controller.php:603
+#: controllers/users_controller.php:659
+#: controllers/collections_controller.php:988
+#: controllers/collections_controller.php:998
+msgid "error_user_notfound"
+msgstr "Kullanıcı bulunamadı!"
+
+#: views/users/activatefirst.thtml:47
+msgid "error_user_unconfirmed"
+msgstr "Lütfen önce kullanıcı hesabınızı doğrulayınız."
+
+#: views/users/login.thtml:67
+msgid "error_username_or_pw_wrong"
+msgstr "Yanlış kullanıcı adı ya da parola girildi!"
+
+#: controllers/editors_controller.php:260
+msgid "error_version_notfound"
+msgstr "Version not found!"
+
+#: views/users/delete.thtml:125 views/users/edit.thtml:173
+msgid "error_wrong_password"
+msgstr "Yanlış parola girildi!"
+
+#: views/elements/amo2009/homepage_addon.thtml:122
+#: views/elements/feature.thtml:122
+#, fuzzy
+msgid "feature_learnmore"
+msgstr "Learn more"
+
+# %1 is the add-on name
+#. %1 is the add-on name
+#: views/elements/amo2009/homepage_addon.thtml:123
+#: views/elements/feature.thtml:123
+#, fuzzy, php-format
+msgid "feature_learnmore_about_addon"
+msgstr "Learn more about %1$s"
+
+#. %1$s is a number
+#: views/elements/amo2009/reviews.thtml:52
+#: views/elements/addon_listitem.thtml:112 views/elements/feature.thtml:99
+#: views/addons/browse_thumbs.thtml:86
+#, fuzzy, php-format
+msgid "feature_reviews"
+msgid_plural "feature_reviews"
+msgstr[0] "reviews"
+
+#: views/elements/amo2009/homepage_addon.thtml:127
+#: views/elements/feature.thtml:127
+#, fuzzy
+msgid "feature_view_more_from_category"
+msgstr "View more from"
+
+#. This appears on a page that views the source of an add-on. This link will return
+#. the user to the add-on's main page
+#: views/files/browse.thtml:65
+#, fuzzy
+msgid "file_browser_link_addon"
+msgstr "Back to add-on"
+
+#. There is a list of directories and files on the page. Clicking this will show the
+#. contents of all the directories (normally you would click on each one to see the
+#. contents)
+#: views/files/browse.thtml:67
+#, fuzzy
+msgid "file_browser_link_expand_all"
+msgstr "Expand all"
+
+#. This appears on a page that views the source of an add-on. This link will return
+#. the user to the add-on's review page (it only appears if the add-on is being
+#. reviewed)
+#: views/files/browse.thtml:64
+#, fuzzy
+msgid "file_browser_link_review"
+msgstr "Back to review"
+
+#. The title of the page for viewing an add-on's source.
+#. %1$s is the name of the add-on
+#. %2$s is the name of the current application (e.g. Firefox or Thunderbird)
+#: views/files/browse.thtml:46
+#, fuzzy
+msgid "file_browser_title"
+msgstr "%1$s :: File Browser :: %2$s Add-ons"
+
+#. This appears on a page that views the source of an add-on. There is a list of
+#. directories and files on the page. Clicking this link will toggle between an
+#. expanded or a collapsed list. This string should be kept short.
+#: views/files/browse.thtml:68
+#, fuzzy
+msgid "file_browser_toggle_expand_collapse"
+msgstr "+/-"
+
+#. Link text for the AMO About page.
+#: views/elements/footer.thtml:72 views/layouts/amo2009.thtml:341
+#, fuzzy
+msgid "footer_a_about"
+msgstr "About"
+
+#. Link text to the AMO blog.
+#: views/elements/footer.thtml:74 views/layouts/amo2009.thtml:343
+#, fuzzy
+msgid "footer_a_blog"
+msgstr "Blog"
+
+#. Link text to the Frequently Asked Questions page.
+#: views/elements/footer.thtml:73 views/layouts/amo2009.thtml:342
+#, fuzzy
+msgid "footer_a_faq"
+msgstr "FAQ"
+
+#. Full text for the FAQ abbreviation.
+#: views/elements/footer.thtml:73 views/pages/collector_features.thtml:72
+#: views/layouts/amo2009.thtml:342
+#, fuzzy
+msgid "footer_abbr_faq"
+msgstr "Frequently Asked Questions"
+
+#: views/elements/footer.thtml:67 views/layouts/amo2009.thtml:336
+msgid "footer_all_rights_reserved"
+msgstr "Bütün hakları saklıdır."
+
+#: views/elements/footer.thtml:67 views/layouts/amo2009.thtml:336
+msgid "footer_copyright"
+msgstr "Telif hakları"
+
+#: views/elements/footer.thtml:71 views/layouts/amo2009.thtml:340
+#, fuzzy
+msgid "footer_credits"
+msgstr "Credits"
+
+#: views/elements/footer.thtml:76 views/layouts/amo2009.thtml:346
+msgid "footer_disclaimer"
+msgstr ""
+"Mozilla is providing links to these applications as a courtesy, and makes no "
+"representations regarding the applications or any information related there "
+"to. Any questions, complaints or claims regarding the applications must be "
+"directed to the appropriate software vendor."
+
+#: views/elements/footer.thtml:61 views/layouts/amo2009.thtml:332
+msgid "footer_lang_form_lang_submit_go"
+msgstr "Git"
+
+#: views/elements/footer.thtml:70 views/layouts/amo2009.thtml:339
+msgid "footer_legal_notices"
+msgstr "Yasal uyarılar"
+
+# This is the lang code -- should be the same as the dir for this locale.
+#: views/elements/footer.thtml:50 views/layouts/amo2009.thtml:321
+msgid "footer_other_languages"
+msgstr "DiÄŸer diller:"
+
+#: views/elements/footer.thtml:69 views/layouts/amo2009.thtml:338
+msgid "footer_privacy_policy"
+msgstr "Gizlilik politikası"
+
+#: models/addontype.php:79
+#, fuzzy
+msgid "general_addontype_dict"
+msgstr "Dictionary"
+
+# Plural in this context means many of the add-on type
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:100
+#, fuzzy
+msgid "general_addontype_dict_plural"
+msgstr "Dictionaries"
+
+#: models/addontype.php:75
+#, fuzzy
+msgid "general_addontype_extension"
+msgstr "Extension"
+
+# Plural in this context means many of the add-on type
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:98
+#, fuzzy
+msgid "general_addontype_extension_plural"
+msgstr "Extensions"
+
+#: models/addontype.php:85
+#, fuzzy
+msgid "general_addontype_lpaddon"
+msgstr "Language Pack (Add-on)"
+
+# Plural in this context means many of the add-on type
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:103
+#, fuzzy
+msgid "general_addontype_lpaddon_plural"
+msgstr "Language Packs (Add-on)"
+
+#: models/addontype.php:83
+#, fuzzy
+msgid "general_addontype_lpapp"
+msgstr "Language Pack (Application)"
+
+# Plural in this context means many of the add-on type
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:102
+#, fuzzy
+msgid "general_addontype_lpapp_plural"
+msgstr "Language Packs (Application)"
+
+#: models/addontype.php:87
+#, fuzzy
+msgid "general_addontype_plugin"
+msgstr "Plugin"
+
+# Plural in this context means many of the add-on type
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:104
+#, fuzzy
+msgid "general_addontype_plugin_plural"
+msgstr "Plugins"
+
+#: models/addontype.php:81
+#, fuzzy
+msgid "general_addontype_search"
+msgstr "Search Engine"
+
+# Plural in this context means many of the add-on type
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:101
+#, fuzzy
+msgid "general_addontype_search_plural"
+msgstr "Search Engines"
+
+#: models/addontype.php:77
+#, fuzzy
+msgid "general_addontype_theme"
+msgstr "Theme"
+
+# Plural in this context means many of the add-on type
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:99
+#, fuzzy
+msgid "general_addontype_theme_plural"
+msgstr "Themes"
+
+#: config/language.php:367
+#, fuzzy
+msgid "general_languages_all_locales"
+msgstr "All Locales"
+
+#: views/layouts/amo2009.thtml:249
+#, fuzzy
+msgid "header_brand_name"
+msgstr "Mozilla"
+
+#. %1$s is the application name. Example: Firefox
+#: views/elements/header.thtml:111 views/elements/header.thtml:122
+#: views/layouts/amo2009.thtml:248
+#, fuzzy, php-format
+msgid "header_home_tooltip"
+msgstr "Return to the %1$s Add-ons homepage"
+
+#: views/elements/header.thtml:87
+#, fuzzy
+msgid "header_main_firefox_header"
+msgstr "Firefox Add-ons"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:218
+#, fuzzy
+msgid "header_main_firefox_header_with_logo"
+msgstr ""
+"Add-ons <em>for</em> <img alt=\"Firefox\" src=\"%1$s\" /> <strong>Firefox</"
+"strong>"
+
+#: views/elements/header.thtml:99
+#, fuzzy
+msgid "header_main_header"
+msgstr "Add-ons"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:242
+#, fuzzy
+msgid "header_main_header_with_logo"
+msgstr "Add-ons <img alt=\"Add-ons\" src=\"%1$s\" />"
+
+#: views/elements/header.thtml:90
+#, fuzzy
+msgid "header_main_seamonkey_header"
+msgstr "Seamonkey Add-ons"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:224
+#, fuzzy
+msgid "header_main_seamonkey_header_with_logo"
+msgstr ""
+"Add-ons <em>for</em> <img alt=\"seamonkey\" src=\"%1$s\" /> "
+"<strong>SeaMonkey</strong>"
+
+#: views/elements/header.thtml:93
+#, fuzzy
+msgid "header_main_sunbird_header"
+msgstr "Sunbird Add-ons"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:230
+#, fuzzy
+msgid "header_main_sunbird_header_with_logo"
+msgstr ""
+"Add-ons <em>for</em> <img alt=\"sunbird\" src=\"%1$s\" /> <strong>Sunbird</"
+"strong>"
+
+#: views/elements/header.thtml:96
+#, fuzzy
+msgid "header_main_thunderbird_header"
+msgstr "Thunderbird Add-ons"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:236
+#, fuzzy
+msgid "header_main_thunderbird_header_with_logo"
+msgstr ""
+"Add-ons <em>for</em> <img alt=\"thunderbird\" src=\"%1$s\" /> "
+"<strong>Thunderbird</strong>"
+
+#: views/layouts/amo2009.thtml:205
+#, fuzzy
+msgid "header_navaccess_applications_menu"
+msgstr "Skip to other applications menu"
+
+#: views/layouts/amo2009.thtml:204
+#, fuzzy
+msgid "header_navaccess_categories_menu"
+msgstr "Skip to categories menu"
+
+#: views/layouts/amo2009.thtml:202
+#, fuzzy
+msgid "header_navaccess_main_content"
+msgstr "Skip to main content"
+
+#: views/layouts/amo2009.thtml:203
+#, fuzzy
+msgid "header_navaccess_search_form"
+msgstr "Skip to search form"
+
+#: views/elements/header.thtml:62
+msgid "header_navlink_addons"
+msgstr "Add-ons"
+
+#: views/elements/developers/sidebar.thtml:72
+#: views/elements/developers/myaddons.thtml:50 views/elements/header.thtml:159
+#: views/addons/display.thtml:378
+msgid "header_navlink_login"
+msgstr "GiriÅŸ yap"
+
+#: views/elements/header.thtml:156 views/layouts/amo2009.thtml:304
+msgid "header_navlink_logout"
+msgstr "Çıkış yap"
+
+#: views/elements/header.thtml:145 views/layouts/amo2009.thtml:303
+#, fuzzy
+msgid "header_navlink_myaccount"
+msgstr "My Account"
+
+#: views/elements/header.thtml:158
+msgid "header_navlink_register"
+msgstr "Kaydol"
+
+#. %1 is the URL to the registration page
+#. %2 is the URL to the login page
+#: views/layouts/amo2009.thtml:278
+#, fuzzy
+msgid "header_navlink_register_or_login"
+msgstr "<a href=\"%1$s\">Register</a> or <a href=\"%2$s\">Log in</a>"
+
+#: views/layouts/amo2009.thtml:285
+#, fuzzy
+msgid "header_navlink_tools"
+msgstr "Tools"
+
+#. %s is the add-on name
+#: views/elements/collections_interactive_addon.thtml:62
+#: views/elements/amo2009/homepage_addon.thtml:77
+#: views/elements/addon_discussionheader.thtml:62
+#: views/elements/addon_listitem.thtml:67 views/elements/feature.thtml:84
+#: views/addons/category_landing.thtml:87 views/addons/browse_thumbs.thtml:60
+#, fuzzy, php-format
+msgid "img_preview_of"
+msgstr "Preview Image of %s"
+
+# %1 is the login URL for the link tag
+#. %1 is the login URL for the link tag
+#. %2 is the link to an explanatory page.
+#: views/elements/amo2009/install.thtml:307 views/elements/install.thtml:255
+#, fuzzy
+msgid "install_a_login_to_install"
+msgstr "<a href=\"%1$s\">Log in</a> to install this add-on"
+
+#. %1 is the URL for the Experimental Add-ons section of the FAQ page
+#: views/elements/amo2009/install.thtml:283 views/elements/install.thtml:232
+#, fuzzy
+msgid "install_button_confirm_exp_install"
+msgstr ""
+"Let me install this experimental add-on. <a href=\"%1$s\">What's this?</a>"
+
+#. %1$s is the application name. Example: Firefox
+#. %2$s is an optional string used to specify a platform. Example: (Windows)
+#: views/elements/amo2009/install.thtml:128 views/elements/install.thtml:75
+#, fuzzy, php-format
+msgid "install_button_text"
+msgstr "Add to %s %s"
+
+# %1 is the add-on name, %2 is the app name
+#. %1 is the add-on name, %2 is the app name
+#: views/elements/amo2009/install.thtml:191
+#: views/elements/amo2009/install.thtml:206
+#: views/elements/amo2009/install.thtml:249
+#: views/elements/amo2009/install.thtml:298 views/elements/install.thtml:150
+#: views/elements/install.thtml:165 views/elements/install.thtml:202
+#: views/elements/install.thtml:246
+#, fuzzy, php-format
+msgid "install_button_title"
+msgstr "Add %1$s to %2$s"
+
+#. %1$s is the add-on name
+#: views/elements/amo2009/install.thtml:200 views/elements/install.thtml:159
+#, fuzzy, php-format
+msgid "install_download"
+msgstr "Download %1$s"
+
+#: views/elements/amo2009/install.thtml:147 views/elements/install.thtml:94
+msgid "install_error_addon_not_found"
+msgstr "Eklenti bulunamadı!"
+
+#: views/addons/dictionaries.thtml:65
+#, fuzzy
+msgid "langtools_a11y_tablesummary"
+msgstr "List of language packs and dictionaries."
+
+#: views/addons/dictionaries.thtml:47
+#, fuzzy
+msgid "langtools_download_dictionary"
+msgstr "Download Dictionary"
+
+#: views/addons/dictionaries.thtml:48
+#, fuzzy
+msgid "langtools_download_langpack"
+msgstr "Download Language Pack"
+
+#: views/addons/dictionaries.thtml:63 controllers/components/amo.php:685
+#: controllers/addons_controller.php:1239
+#, fuzzy
+msgid "langtools_header_dicts_and_langpacks"
+msgstr "Dictionaries & Language Packs"
+
+#: views/addons/dictionaries.thtml:44
+#, fuzzy
+msgid "langtools_install_dictionary"
+msgstr "Install Dictionary"
+
+#: views/addons/dictionaries.thtml:45
+#, fuzzy
+msgid "langtools_install_langpack"
+msgstr "Install Language Pack"
+
+#: views/addons/dictionaries.thtml:69
+#, fuzzy
+msgid "langtools_tableheader_dictionary"
+msgstr "Dictionary"
+
+#: views/addons/dictionaries.thtml:70
+#, fuzzy
+msgid "langtools_tableheader_langpack"
+msgstr "Language Pack"
+
+#: views/addons/dictionaries.thtml:68
+#, fuzzy
+msgid "langtools_tableheader_language"
+msgstr "Language"
+
+#: models/license.php:65
+#, fuzzy
+msgid "license_custom"
+msgstr "Custom License"
+
+#: config/bootstrap.php:303
+#, fuzzy
+msgid "licenses_bsd"
+msgstr "BSD License"
+
+#: config/bootstrap.php:298
+#, fuzzy
+msgid "licenses_gpl_2.0"
+msgstr "GNU General Public License, version 2.0"
+
+#: config/bootstrap.php:299
+#, fuzzy
+msgid "licenses_gpl_3.0"
+msgstr "GNU General Public License, version 3.0"
+
+#: config/bootstrap.php:300
+#, fuzzy
+msgid "licenses_lgpl_2.1"
+msgstr "GNU Lesser General Public License, version 2.1"
+
+#: config/bootstrap.php:301
+#, fuzzy
+msgid "licenses_lgpl_3.0"
+msgstr "GNU Lesser General Public License, version 3.0"
+
+#: config/bootstrap.php:302
+#, fuzzy
+msgid "licenses_mit"
+msgstr "MIT/X11 License"
+
+#: config/bootstrap.php:297
+#, fuzzy
+msgid "licenses_mpl_1.1"
+msgstr "Mozilla Public License, version 1.1"
+
+#: views/users/emailchange.thtml:51 views/users/delete.thtml:55
+#: views/users/delete.thtml:137 views/users/edit.thtml:74
+#: views/reviews/flag.thtml:54
+#, fuzzy
+msgid "link_return_to_front_page"
+msgstr "Click here to return to the front page."
+
+#: views/elements/amo2009/addon_list_options.thtml:46
+#: views/elements/addon_list_options.thtml:46
+#, fuzzy
+msgid "list_sortby_date"
+msgstr "Date"
+
+#: views/elements/amo2009/addon_list_options.thtml:47
+#: views/elements/addon_list_options.thtml:47
+#, fuzzy
+msgid "list_sortby_downloads"
+msgstr "Downloads"
+
+#: views/elements/amo2009/addon_list_options.thtml:45
+#: views/elements/addon_list_options.thtml:45
+#, fuzzy
+msgid "list_sortby_name"
+msgstr "Add-on Name"
+
+#: views/elements/amo2009/addon_list_options.thtml:48
+#: views/elements/addon_list_options.thtml:48
+#, fuzzy
+msgid "list_sortby_rating"
+msgstr "Rating"
+
+#: config/bootstrap.php:278
+#, fuzzy
+msgid "main_prettyname_fennec"
+msgstr "Fennec"
+
+#: config/bootstrap.php:274
+#, fuzzy
+msgid "main_prettyname_firefox"
+msgstr "Firefox"
+
+#: config/bootstrap.php:277
+#, fuzzy
+msgid "main_prettyname_seamonkey"
+msgstr "SeaMonkey"
+
+#: config/bootstrap.php:276
+#, fuzzy
+msgid "main_prettyname_sunbird"
+msgstr "Sunbird"
+
+#: config/bootstrap.php:275
+#, fuzzy
+msgid "main_prettyname_thunderbird"
+msgstr "Thunderbird"
+
+#: views/elements/addon_categories.thtml:52
+#, fuzzy
+msgid "nav_category_dicts_langpacks"
+msgstr "Dictionaries & Language Packs"
+
+#: views/elements/addon_categories.thtml:55
+#, fuzzy
+msgid "nav_category_themes"
+msgstr "Themes"
+
+#: views/elements/app_chooser.thtml:47 views/layouts/amo2009.thtml:255
+#, fuzzy
+msgid "other_apps_tooltip"
+msgstr "Find add-ons for other applications"
+
+# In a user list: user 1, user 2, "others"
+#. In a user list: user 1, user 2, "others"
+#: views/helpers/addons_html.php:222
+msgid "other_users"
+msgstr "others"
+
+#: controllers/pages_controller.php:90
+#, fuzzy
+msgid "page_title_appversions"
+msgstr "Application Versions"
+
+#: controllers/pages_controller.php:115
+#, fuzzy
+msgid "page_title_collector"
+msgstr "Add-on Collector"
+
+#: controllers/pages_controller.php:117
+#, fuzzy
+msgid "page_title_collector_faq"
+msgstr "Add-on Collector FAQ"
+
+#: controllers/pages_controller.php:119
+#, fuzzy
+msgid "page_title_collector_features"
+msgstr "Add-on Collector Features"
+
+#: controllers/pages_controller.php:122
+#, fuzzy
+msgid "page_title_collector_firstrun"
+msgstr "Welcome to the Add-on Collector"
+
+#: controllers/pages_controller.php:92
+#, fuzzy
+msgid "page_title_credits"
+msgstr "Credits"
+
+#: controllers/pages_controller.php:113
+#, fuzzy
+msgid "page_title_developer_faq"
+msgstr "Developer FAQ"
+
+#: controllers/pages_controller.php:111
+#, fuzzy
+msgid "page_title_faq"
+msgstr "Frequently Asked Questions"
+
+#: controllers/pages_controller.php:94
+#, fuzzy
+msgid "page_title_fashionyourfirefox_faq"
+msgstr "Fashion your Firefox FAQ"
+
+#: controllers/pages_controller.php:101
+#, fuzzy
+msgid "page_title_policy"
+msgstr "Add-ons Policy"
+
+#: controllers/pages_controller.php:103
+#, fuzzy
+msgid "page_title_privacy"
+msgstr "Mozilla Privacy Policy"
+
+#: controllers/pages_controller.php:105
+#, fuzzy
+msgid "page_title_review_guide"
+msgstr "Review Guidelines"
+
+#: controllers/pages_controller.php:107
+#, fuzzy
+msgid "page_title_sandbox"
+msgstr "Sandbox Review System"
+
+#: controllers/pages_controller.php:109
+#, fuzzy
+msgid "page_title_submissionhelp"
+msgstr "Submission Help"
+
+#: views/pages/appversions.thtml:87
+#, fuzzy
+msgid "pages_appversions_guid"
+msgstr "GUID"
+
+#: views/pages/appversions.thtml:79 controllers/pages_controller.php:90
+#, fuzzy
+msgid "pages_appversions_header"
+msgstr "Valid Application Versions"
+
+#: views/pages/appversions.thtml:80
+#, fuzzy
+msgid "pages_appversions_intro"
+msgstr ""
+"Add-ons submitted to Mozilla Add-ons must have an install.rdf file with at "
+"least one of the below applications supported. Only the versions listed "
+"below are allowed for these applications."
+
+#. %s is a full <a> tag
+#: views/pages/appversions.thtml:93
+#, fuzzy, php-format
+msgid "pages_appversions_required_files"
+msgstr ""
+"If your supported application does not require an install.rdf file, you "
+"still must include one with the required properties as specified %s."
+
+#. this is the text inside of an <a> tag for pages_appversions_required_files. This
+#. should be fixed.
+#: views/pages/appversions.thtml:93
+#, fuzzy
+msgid "pages_appversions_required_files_link"
+msgstr "here"
+
+#: views/pages/appversions.thtml:88
+#, fuzzy
+msgid "pages_appversions_versions"
+msgstr "Versions"
+
+#: views/pages/policy.thtml:51
+msgid "pages_policy_sandbox_link"
+msgstr "Sandbox Information Page"
+
+#: views/elements/pagination.thtml:53
+msgid "pagination_next_page"
+msgstr "sonraki"
+
+#: views/elements/pagination.thtml:52
+msgid "pagination_previous_page"
+msgstr "önceki"
+
+#: views/elements/recaptcha.thtml:65
+#, fuzzy
+msgid "recaptcha_enter_both_words"
+msgstr ""
+"Please enter <strong>both words</strong> below, <strong>separated by a "
+"space</strong>."
+
+#: views/elements/recaptcha.thtml:83
+#, fuzzy
+msgid "recaptcha_enter_here"
+msgstr "Enter your answer here:"
+
+#: views/elements/recaptcha.thtml:74
+#, fuzzy
+msgid "recaptcha_enter_whatyouhear"
+msgstr "Please type what you hear."
+
+# %1 is the link switching refreshing the captcha
+# %2 is the link switching to a text captcha
+#. %1 is the link switching refreshing the captcha
+#. %2 is the link switching to a text captcha
+#: views/elements/recaptcha.thtml:77
+#, fuzzy
+msgid "recaptcha_hardtohear_text"
+msgstr ""
+"If this is hard to understand, you can <a href=\"%1$s\">listen to something "
+"else</a> or <a href=\"%2$s\">switch back to text</a>."
+
+# %1 is the link switching refreshing the captcha
+# %2 is the link switching to an audio captcha
+#. %1 is the link switching refreshing the captcha
+#. %2 is the link switching to an audio captcha
+#: views/elements/recaptcha.thtml:68
+#, fuzzy
+msgid "recaptcha_hardtoread_text"
+msgstr ""
+"If this is hard to read, you can <a href=\"%1$s\">try different words</a> or "
+"<a href=\"%2$s\">listen to something</a> instead."
+
+#: views/users/register.thtml:105
+#, fuzzy
+msgid "recaptcha_label"
+msgstr "Are you human?"
+
+#: views/users/register.thtml:106
+#, fuzzy
+msgid "recaptcha_whatsthis"
+msgstr "What's this?"
+
+#: controllers/reviews_controller.php:559
+#, fuzzy
+msgid "review_flag_error"
+msgstr "Error flagging this review!"
+
+#: models/reviews_moderation_flag.php:69
+#, fuzzy
+msgid "review_flag_reason_bug_support"
+msgstr "Misplaced bug report or support request"
+
+#: views/reviews/display.thtml:103 views/reviews/display.thtml:186
+#, fuzzy
+msgid "review_flag_reason_instructions"
+msgstr "Report this review (select a reason)"
+
+#: models/reviews_moderation_flag.php:67
+#, fuzzy
+msgid "review_flag_reason_language"
+msgstr "Inappropriate language/dialog"
+
+#: models/reviews_moderation_flag.php:71
+#, fuzzy
+msgid "review_flag_reason_other"
+msgstr "Other (please specify)"
+
+#: models/reviews_moderation_flag.php:65
+#, fuzzy
+msgid "review_flag_reason_spam"
+msgstr "Spam or otherwise non-review content"
+
+#: views/reviews/display.thtml:91 views/reviews/display.thtml:175
+#: controllers/reviews_controller.php:555
+#, fuzzy
+msgid "review_flag_success"
+msgstr "Thanks; this review has been flagged for editor approval."
+
+#: views/reviews/display.thtml:41
+#, fuzzy
+msgid "review_flag_this"
+msgstr "Report this review"
+
+#: views/reviews/display.thtml:42
+#, fuzzy
+msgid "review_flag_this_titletip"
+msgstr ""
+"Is this review inappropriate, inaccurate or spam? Click here to flag it for "
+"editor review."
+
+# %1 is the URL of the support section, %2 for the review guidelines
+#. %1 is the URL of the support section, %2 for the review guidelines
+#: views/reviews/add.thtml:53
+#, fuzzy
+msgid "review_guidelines_short"
+msgstr ""
+"<p>Keep these tips in mind:</p><ul><li>Write like you're telling a friend "
+"about your experience with the add-on. Give specifics and helpful details, "
+"such as what features you liked and/ordisliked, how easy to use it is, and "
+"any disadvantages it has. Avoid genericlanguage such as calling it \"Great"
+"\" or \"Bad\" unless you can give reasons whyyou believe this is so.</"
+"li><li>Please do not post bug reports in reviews. We do not make your email "
+"address available to add-on developers and they may need to contact you to "
+"help resolveyour issue. See the <a href=\"%1$s\">support section</a> to find "
+"out where to get assistance for this add-on.</li><li>Please keep reviews "
+"clean, avoid the use of improper language and do not post any personal "
+"information.</li></ul><p>Please read the <a href=\"%2$s\">Review Guidelines</"
+"a> for more detail about user add-on reviews.</p>"
+
+#. %1 is the add-on name
+#: views/reviews/flag.thtml:56 views/reviews/display.thtml:55
+#: views/reviews/review_added.thtml:50
+#, php-format
+msgid "reviews_header"
+msgstr "%s hakkındaki görüşler"
+
+#: controllers/addons_controller.php:435
+msgid "rss_featuredaddons"
+msgstr "Özellikli Eklenti"
+
+#: controllers/addons_controller.php:432
+msgid "rss_newestaddons"
+msgstr "En yeni eklentiler"
+
+#: controllers/addons_controller.php:434
+#, fuzzy
+msgid "rss_popularaddons"
+msgstr "Popular Add-ons"
+
+#: controllers/addons_controller.php:433
+#, fuzzy
+msgid "rss_updatedaddons"
+msgstr "Updated Add-ons"
+
+#: views/elements/search_mini.thtml:70
+#, fuzzy
+msgid "search"
+msgstr "Search"
+
+#: views/search/collections.thtml:51
+#, fuzzy
+msgid "search_collections_header"
+msgstr "Collection Search Results"
+
+#: controllers/search_controller.php:297
+#, fuzzy
+msgid "search_collections_pagetitle"
+msgstr "Collection Search Results"
+
+#: controllers/search_controller.php:99
+#, fuzzy
+msgid "search_disabled"
+msgstr "Search is currently disabled. Please try again later."
+
+#: views/elements/amo2009/search.thtml:188 views/elements/search.thtml:187
+#: views/elements/search_mini.thtml:54
+#, fuzzy
+msgid "search_form_all_addons"
+msgstr "all add-ons"
+
+#. This string is in the main category dropdown when searching
+#: views/elements/amo2009/search.thtml:204
+#, fuzzy
+msgid "search_form_all_collections"
+msgstr "all collections"
+
+#: views/elements/amo2009/search.thtml:184
+#: views/elements/amo2009/search.thtml:385
+#: views/elements/amo2009/search.thtml:408 views/elements/search.thtml:171
+#: views/elements/search.thtml:183 views/elements/search_mini.thtml:43
+#: views/elements/search_mini.thtml:49 views/layouts/mozilla.thtml:188
+#, fuzzy
+msgid "search_form_default_text"
+msgstr "search for add-ons"
+
+#: views/elements/amo2009/search.thtml:184
+#: views/elements/amo2009/search.thtml:404
+#, fuzzy
+msgid "search_form_default_text_collections"
+msgstr "search for collections"
+
+#: views/elements/amo2009/search.thtml:206 views/elements/search.thtml:202
+#, fuzzy
+msgid "search_form_submit_tooltip"
+msgstr "Search for add-ons"
+
+#: views/elements/amo2009/search.thtml:184 views/elements/search.thtml:183
+#: views/elements/search_mini.thtml:49
+#, fuzzy
+msgid "search_form_tooltip"
+msgstr "Click to enter search terms"
+
+#: views/elements/amo2009/search.thtml:186 views/elements/search.thtml:185
+#: views/elements/search_mini.thtml:52
+#, fuzzy
+msgid "search_form_within"
+msgstr "within"
+
+#: views/addons/searchengines.thtml:118
+#, fuzzy
+msgid "search_landing_all_search_engines"
+msgstr "All Search Engines"
+
+#: views/addons/searchengines.thtml:114
+#, fuzzy
+msgid "search_landing_browse_search_engines"
+msgstr "Browse Search Engines"
+
+#: views/search/collections.thtml:58 views/search/index.thtml:59
+msgid "search_nothing_found"
+msgstr "Sonuç bulunamadı."
+
+#: controllers/search_controller.php:185
+msgid "search_pagetitle"
+msgstr "Eklentilerde ara"
+
+#: controllers/search_controller.php:242
+msgid "search_rss_description"
+msgstr "Arama sonuçları beslemesi"
+
+#. %s is the terms the user is searching for (a string)
+#: controllers/search_controller.php:241
+#, php-format
+msgid "search_rss_results_for"
+msgstr "Sonuçlarda bunu ara: %s"
+
+#: views/elements/header.thtml:154 views/layouts/amo2009.thtml:296
+msgid "sidebar_navlink_admin_tools"
+msgstr "Admin Tools"
+
+#: views/elements/header.thtml:146 views/layouts/amo2009.thtml:288
+msgid "sidebar_navlink_developer_tools"
+msgstr "Developer Tools"
+
+#: views/elements/header.thtml:148 views/layouts/amo2009.thtml:290
+msgid "sidebar_navlink_editor_tools"
+msgstr "Editor Tools"
+
+#: views/layouts/amo2009.thtml:302
+#, fuzzy
+msgid "sidebar_navlink_welcome"
+msgstr "Welcome"
+
+#. %s is the user's name
+#: views/layouts/amo2009.thtml:302
+#, fuzzy, php-format
+msgid "sidebar_navlink_welcome_name"
+msgstr "Welcome, %s"
+
+#: views/elements/pitch.thtml:50 views/elements/pitch.thtml:55
+#, fuzzy
+msgid "sidebar_pitch_dictionary"
+msgstr "Dictionary"
+
+#: views/elements/pitch.thtml:72
+#, fuzzy
+msgid "sidebar_pitch_featured_addons"
+msgstr "Featured Add-ons"
+
+#: views/elements/pitch.thtml:61
+#, fuzzy
+msgid "sidebar_pitch_looking_for"
+msgstr "I am looking for a:"
+
+#: views/elements/pitch.thtml:70
+#, fuzzy
+msgid "sidebar_pitch_newest_addons"
+msgstr "Newest Add-ons"
+
+#: views/elements/pitch.thtml:49
+#, fuzzy
+msgid "sidebar_pitch_search"
+msgstr "Search Plugin"
+
+#: views/elements/pitch.thtml:69
+#, fuzzy
+msgid "sidebar_pitch_subscribe_to"
+msgstr "Subscribe to"
+
+#: views/elements/pitch.thtml:48 views/elements/pitch.thtml:54
+#, fuzzy
+msgid "sidebar_pitch_theme"
+msgstr "Theme"
+
+#: views/elements/pitch.thtml:71
+#, fuzzy
+msgid "sidebar_pitch_updated_addons"
+msgstr "Updated Add-ons"
+
+#. %1$s is a number
+#: views/helpers/localization.php:65 views/developers/versions_edit.thtml:95
+#: views/addons/dictionaries.thtml:92
+#, php-format
+msgid "size_kb"
+msgstr "%1$s KB"
+
+#: views/elements/amo2009/stars.thtml:57 views/elements/stars.thtml:63
+#, fuzzy
+msgid "stars_not_yet_rated"
+msgstr "Not yet rated"
+
+# %1 is the number of stars this add-on has
+#. %1 is the number of stars this add-on has
+#: views/elements/amo2009/stars.thtml:49 views/elements/stars.thtml:54
+#, fuzzy, php-format
+msgid "stars_rated_x_outof_5"
+msgstr "Rated %s out of 5 stars"
+
+#: views/statistics/addon.thtml:59
+#, fuzzy
+msgid "statistics_addon_dashboard_link"
+msgstr "Dashboard Home"
+
+#: views/statistics/addon.thtml:58
+#, fuzzy
+msgid "statistics_addon_developertools_link"
+msgstr "Developer Tools"
+
+#: views/statistics/addon.thtml:53
+#, fuzzy
+msgid "statistics_addon_switch"
+msgstr "Switch Add-on"
+
+#. This is a date format.
+#. http://php.net/strftime
+#: views/statistics/rss/summary.thtml:54 views/statistics/addon.thtml:181
+#, fuzzy
+msgid "statistics_date_shortmonth"
+msgstr "M. j"
+
+#. This is a date format.
+#. http://php.net/strftime
+#: views/statistics/rss/summary.thtml:40 views/statistics/addon.thtml:152
+#, fuzzy
+msgid "statistics_date_shortmonthwithyear"
+msgstr "M. j, Y"
+
+#. This is a date format.
+#. http://php.net/strftime
+#: views/statistics/rss/summary.thtml:41 views/statistics/rss/summary.thtml:48
+#: views/statistics/addon.thtml:161 views/statistics/addon.thtml:172
+#, fuzzy
+msgid "statistics_date_weekdayshortmonth"
+msgstr "l, M. j"
+
+#. %1$s is an add-on name and version. Example: Add-on 3.5
+#: controllers/components/stats.php:519
+#, fuzzy, php-format
+msgid "statistics_events_addon_created"
+msgstr "%1$s created"
+
+#. %1$s is an application name and version. Example: Firefox 3.5
+#: controllers/components/stats.php:500
+#, fuzzy, php-format
+msgid "statistics_events_app_released"
+msgstr "%1$s released"
+
+#: views/statistics/addon.thtml:71
+#, fuzzy
+msgid "statistics_help_close_link"
+msgstr "Close"
+
+#: views/statistics/addon.thtml:60
+#, fuzzy
+msgid "statistics_help_link"
+msgstr "Help"
+
+#: views/statistics/index.thtml:83
+#, fuzzy
+msgid "statistics_index_anotheraddon"
+msgstr "or, select another add-on"
+
+#: views/statistics/index.thtml:85
+#, fuzzy
+msgid "statistics_index_anotheraddon_public"
+msgstr "or, select an add-on with public statistics"
+
+#: views/statistics/index.thtml:71
+#, fuzzy
+msgid "statistics_index_myaddons"
+msgstr "Select one of your add-ons to view its statistics"
+
+#: views/statistics/index.thtml:89
+#, fuzzy
+msgid "statistics_index_selectaddon"
+msgstr "Select an add-on to view its statistics"
+
+#: views/statistics/index.thtml:91
+#, fuzzy
+msgid "statistics_index_selectaddon_public"
+msgstr "Select an add-on with public statistics"
+
+#: views/statistics/index.thtml:39
+#, fuzzy
+msgid "statistics_index_title"
+msgstr "Statistics Dashboard"
+
+#: views/statistics/index.thtml:97
+#, fuzzy
+msgid "statistics_index_view_button"
+msgstr "View Statistics"
+
+#: views/statistics/addon.thtml:222 controllers/statistics_controller.php:247
+#, fuzzy
+msgid "statistics_js_download_csv"
+msgstr "View this table in CSV format"
+
+#: controllers/statistics_controller.php:246
+#, fuzzy
+msgid "statistics_js_dropdowns_none"
+msgstr "none"
+
+#: controllers/statistics_controller.php:245
+#, fuzzy
+msgid "statistics_js_dropdowns_removeplot"
+msgstr "Remove this plot"
+
+#: controllers/statistics_controller.php:248
+#, fuzzy
+msgid "statistics_js_groupby_selector_date"
+msgstr "Group by: Day"
+
+#: controllers/statistics_controller.php:251
+#, fuzzy
+msgid "statistics_js_groupby_selector_month"
+msgstr "Group by: Month"
+
+#: controllers/statistics_controller.php:249
+#, fuzzy
+msgid "statistics_js_groupby_selector_week"
+msgstr "Group by: Week"
+
+#: controllers/statistics_controller.php:250
+#, fuzzy
+msgid "statistics_js_groupby_selector_week_over_week"
+msgstr "Compare by: Week"
+
+#: controllers/statistics_controller.php:260
+#, fuzzy
+msgid "statistics_js_plotselection_foundinrange"
+msgstr "%s found in range"
+
+#: controllers/statistics_controller.php:270
+#, fuzzy
+msgid "statistics_js_plotselection_options_addplot_name"
+msgstr "Add Plot"
+
+#: controllers/statistics_controller.php:271
+#, fuzzy
+msgid "statistics_js_plotselection_options_addplot_tooltip"
+msgstr "Add another plot to this graph"
+
+#: controllers/statistics_controller.php:261
+#, fuzzy
+msgid "statistics_js_plotselection_options_count_name_checked"
+msgstr "Hide Total Count"
+
+#: controllers/statistics_controller.php:262
+#, fuzzy
+msgid "statistics_js_plotselection_options_count_name_unchecked"
+msgstr "Show Total Count"
+
+#: controllers/statistics_controller.php:263
+#, fuzzy
+msgid "statistics_js_plotselection_options_count_tooltip"
+msgstr "Plot the total count on this graph"
+
+#: controllers/statistics_controller.php:275
+#, fuzzy
+msgid "statistics_js_plotselection_options_csv_name"
+msgstr "View Data (CSV)"
+
+#: controllers/statistics_controller.php:276
+#, fuzzy
+msgid "statistics_js_plotselection_options_csv_tooltip"
+msgstr "Get a Comma Separated Values file of this data"
+
+#: controllers/statistics_controller.php:267
+#, fuzzy
+msgid "statistics_js_plotselection_options_events_addon_name_checked"
+msgstr "Hide %s Events"
+
+#: controllers/statistics_controller.php:268
+#, fuzzy
+msgid "statistics_js_plotselection_options_events_addon_name_unchecked"
+msgstr "Show %s Events"
+
+#: controllers/statistics_controller.php:269
+#, fuzzy
+msgid "statistics_js_plotselection_options_events_addon_tooltip"
+msgstr "Overlay add-on release dates on the plots"
+
+#: controllers/statistics_controller.php:264
+#, fuzzy
+msgid "statistics_js_plotselection_options_events_firefox_name_checked"
+msgstr "Hide Firefox Events"
+
+#: controllers/statistics_controller.php:265
+#, fuzzy
+msgid "statistics_js_plotselection_options_events_firefox_name_unchecked"
+msgstr "Show Firefox Events"
+
+#: controllers/statistics_controller.php:266
+#, fuzzy
+msgid "statistics_js_plotselection_options_events_firefox_tooltip"
+msgstr "Overlay Firefox release dates on the plots"
+
+#: controllers/statistics_controller.php:272
+#, fuzzy
+msgid "statistics_js_plotselection_options_resize_name_checked"
+msgstr "Collapse Graph"
+
+#: controllers/statistics_controller.php:273
+#, fuzzy
+msgid "statistics_js_plotselection_options_resize_name_unchecked"
+msgstr "Expand Graph"
+
+#: controllers/statistics_controller.php:274
+#, fuzzy
+msgid "statistics_js_plotselection_options_resize_tooltip"
+msgstr "Resize the graph"
+
+#: controllers/statistics_controller.php:254
+#, fuzzy
+msgid "statistics_js_plotselection_selector_adu"
+msgstr "Active Daily Users"
+
+#: controllers/statistics_controller.php:256
+#, fuzzy
+msgid "statistics_js_plotselection_selector_application"
+msgstr "Application"
+
+#: controllers/statistics_controller.php:259
+#, fuzzy
+msgid "statistics_js_plotselection_selector_custom"
+msgstr "Custom"
+
+#: controllers/statistics_controller.php:253
+#, fuzzy
+msgid "statistics_js_plotselection_selector_downloads"
+msgstr "Downloads"
+
+#: controllers/statistics_controller.php:258
+#, fuzzy
+msgid "statistics_js_plotselection_selector_os"
+msgstr "Operating System"
+
+#: controllers/statistics_controller.php:257
+#, fuzzy
+msgid "statistics_js_plotselection_selector_status"
+msgstr "Add-on Status"
+
+#: controllers/statistics_controller.php:252
+#, fuzzy
+msgid "statistics_js_plotselection_selector_summary"
+msgstr "Summary"
+
+#: controllers/statistics_controller.php:255
+#, fuzzy
+msgid "statistics_js_plotselection_selector_version"
+msgstr "Add-on Version"
+
+#: controllers/components/stats.php:398
+#, fuzzy
+msgid "statistics_longnames_application"
+msgstr "Application"
+
+#: controllers/components/stats.php:400
+#, fuzzy
+msgid "statistics_longnames_os"
+msgstr "Operating System"
+
+#: controllers/components/stats.php:399
+#, fuzzy
+msgid "statistics_longnames_status"
+msgstr "Add-on Status"
+
+#: controllers/components/stats.php:401
+#, fuzzy
+msgid "statistics_longnames_unknown"
+msgstr "Unknown"
+
+#: controllers/components/stats.php:397
+#, fuzzy
+msgid "statistics_longnames_version"
+msgstr "Add-on Version"
+
+#: views/statistics/addon.thtml:118
+#, fuzzy
+msgid "statistics_notice_data_insufficient"
+msgstr ""
+"There is not yet enough data to display this graph. Please check back later."
+
+#: views/statistics/addon.thtml:130
+#, fuzzy
+msgid "statistics_notice_data_none"
+msgstr ""
+"We don't have any data for your add-on yet. Please check back in a few days."
+
+#: views/statistics/addon.thtml:41
+#, fuzzy
+msgid "statistics_notice_data_updating"
+msgstr ""
+"Add-on statistics are currently in the process of being updated. Recent data "
+"may be incomplete as our scripts work to update this information. Please "
+"check back in a few minutes."
+
+#: views/statistics/addon.thtml:136
+#, fuzzy
+msgid "statistics_notice_disabled"
+msgstr ""
+"The Statistics Dashboard is currently disabled. Please check back later."
+
+#: views/statistics/addon.thtml:123
+#, fuzzy
+msgid "statistics_notice_nojavascript"
+msgstr "JavaScript is required to view the Statistics Dashboard graphs."
+
+#: views/statistics/addon.thtml:44
+#, fuzzy
+msgid "statistics_notice_settings_updated"
+msgstr "Your settings have been updated!"
+
+#: controllers/statistics_controller.php:60
+#: controllers/statistics_controller.php:71
+#: controllers/statistics_controller.php:74
+#: controllers/statistics_controller.php:240
+#, fuzzy
+msgid "statistics_pagetitle"
+msgstr "Statistics Dashboard"
+
+#: views/statistics/addon.thtml:99
+#, fuzzy
+msgid "statistics_plot_legend_adu"
+msgstr "Active Daily Users"
+
+#: views/statistics/addon.thtml:95
+#, fuzzy
+msgid "statistics_plot_legend_downloads"
+msgstr "Daily Downloads"
+
+#: views/statistics/addon.thtml:107
+#, fuzzy
+msgid "statistics_plot_options_zoomin_alt"
+msgstr "Zoom In"
+
+#: views/statistics/addon.thtml:106
+#, fuzzy
+msgid "statistics_plot_options_zoomin_title"
+msgstr "Zoom in one month"
+
+#: views/statistics/addon.thtml:110
+#, fuzzy
+msgid "statistics_plot_options_zoomout_alt"
+msgstr "Zoom Out"
+
+#: views/statistics/addon.thtml:109
+#, fuzzy
+msgid "statistics_plot_options_zoomout_title"
+msgstr "Zoom out one month"
+
+#: controllers/statistics_controller.php:283
+#, fuzzy, php-format
+msgid "statistics_rss_description"
+msgstr "Daily summary of statistics for %1$s"
+
+#: views/statistics/rss/summary.thtml:68
+#, fuzzy
+msgid "statistics_rss_title_fulldate"
+msgstr "l, F j, Y"
+
+#: views/statistics/rss/summary.thtml:68
+#, fuzzy, php-format
+msgid "statistics_rss_title_statsfordate"
+msgstr "Statistics for %1$s"
+
+#: views/statistics/settings.thtml:49
+#, fuzzy
+msgid "statistics_settings_access_description"
+msgstr ""
+"By default, only you and Mozilla can access the information in your "
+"dashboard. You can open this up to the public so that anyone can view your "
+"add-on's data."
+
+#: views/statistics/settings.thtml:48
+#, fuzzy
+msgid "statistics_settings_access_heading"
+msgstr "Dashboard Access"
+
+#: views/statistics/settings.thtml:51
+#, fuzzy
+msgid "statistics_settings_access_private"
+msgstr "Private"
+
+#: views/statistics/settings.thtml:51
+#, fuzzy
+msgid "statistics_settings_access_private_description"
+msgstr "Only you and Mozilla can view this add-on's statistics"
+
+#: views/statistics/settings.thtml:52
+#, fuzzy
+msgid "statistics_settings_access_public"
+msgstr "Public"
+
+#: views/statistics/settings.thtml:52
+#, fuzzy
+msgid "statistics_settings_access_public_description"
+msgstr "Anyone can view this add-on's statistics"
+
+#: views/statistics/addon.thtml:251
+#, fuzzy
+msgid "statistics_settings_change_link"
+msgstr "Change Settings"
+
+#: views/statistics/addon.thtml:253
+#, fuzzy
+msgid "statistics_settings_confidential"
+msgstr "Please treat this information as confidential."
+
+#: views/statistics/addon.thtml:245
+#, fuzzy
+msgid "statistics_settings_currently_private"
+msgstr "This dashboard is currently <b>private</b>."
+
+#: views/statistics/addon.thtml:241
+#, fuzzy
+msgid "statistics_settings_currently_public"
+msgstr "This dashboard is currently <b>public</b>."
+
+#: views/statistics/addon.thtml:246
+#, fuzzy
+msgid "statistics_settings_locked_alt"
+msgstr "Locked"
+
+#: views/statistics/settings.thtml:57
+#, fuzzy
+msgid "statistics_settings_return_link"
+msgstr "Return to Dashboard"
+
+#: views/statistics/settings.thtml:56
+#, fuzzy
+msgid "statistics_settings_save_button"
+msgstr "Save Settings"
+
+#: views/statistics/settings.thtml:46
+#, fuzzy, php-format
+msgid "statistics_settings_title"
+msgstr "Statistics Dashboard Settings for %1$s"
+
+#: views/statistics/addon.thtml:242
+#, fuzzy
+msgid "statistics_settings_unlocked_alt"
+msgstr "Unlocked"
+
+#: controllers/components/stats.php:405
+#, fuzzy
+msgid "statistics_shortnames_application"
+msgstr "App"
+
+#: controllers/components/stats.php:407
+#, fuzzy
+msgid "statistics_shortnames_os"
+msgstr "OS"
+
+#: controllers/components/stats.php:406
+#, fuzzy
+msgid "statistics_shortnames_status"
+msgstr "St"
+
+#: controllers/components/stats.php:408
+#, fuzzy
+msgid "statistics_shortnames_unknown"
+msgstr "Uk"
+
+#: controllers/components/stats.php:404
+#, fuzzy
+msgid "statistics_shortnames_version"
+msgstr "Ver"
+
+#: views/statistics/rss/summary.thtml:42 views/statistics/addon.thtml:192
+#, fuzzy
+msgid "statistics_summary_downloads_average"
+msgstr "Average Daily Downloads"
+
+#: views/statistics/rss/summary.thtml:39
+#, fuzzy
+msgid "statistics_summary_downloads_heading"
+msgstr "Downloads"
+
+#: views/statistics/rss/summary.thtml:41 views/statistics/addon.thtml:171
+#, fuzzy
+msgid "statistics_summary_downloads_lastcount"
+msgstr "Last Day Count"
+
+#: views/statistics/rss/summary.thtml:43 views/statistics/addon.thtml:199
+#, fuzzy
+msgid "statistics_summary_downloads_lastweek"
+msgstr "Downloads in the last 7 days"
+
+#: views/statistics/rss/summary.thtml:40 views/statistics/addon.thtml:151
+#, fuzzy
+msgid "statistics_summary_downloads_total"
+msgstr "Total Downloads"
+
+#: views/statistics/rss/summary.thtml:40 views/statistics/addon.thtml:152
+#, fuzzy, php-format
+msgid "statistics_summary_downloads_total_sincedate"
+msgstr "Since %1$s"
+
+#: views/statistics/rss/summary.thtml:50 views/statistics/rss/summary.thtml:56
+#: views/statistics/addon.thtml:163 views/statistics/addon.thtml:183
+#, fuzzy
+msgid "statistics_summary_nodata"
+msgstr "No data yet"
+
+#: views/statistics/rss/summary.thtml:60 views/statistics/addon.thtml:195
+#, fuzzy
+msgid "statistics_summary_updatepings_average"
+msgstr "Average Daily Active Users"
+
+#: views/statistics/rss/summary.thtml:52 views/statistics/addon.thtml:177
+#, fuzzy
+msgid "statistics_summary_updatepings_changefromprevious"
+msgstr "Change from previous count"
+
+#: views/statistics/rss/summary.thtml:54 views/statistics/addon.thtml:181
+#, fuzzy, php-format
+msgid "statistics_summary_updatepings_changefromprevious_ondate"
+msgstr "%1$s on %2$s"
+
+#: views/statistics/rss/summary.thtml:45
+#, fuzzy
+msgid "statistics_summary_updatepings_heading"
+msgstr "Active Daily Users"
+
+#: views/statistics/rss/summary.thtml:46 views/statistics/addon.thtml:157
+#, fuzzy
+msgid "statistics_summary_updatepings_total"
+msgstr "Active Daily Users"
+
+#: views/statistics/rss/summary.thtml:48 views/statistics/addon.thtml:161
+#, fuzzy, php-format
+msgid "statistics_summary_updatepings_total_ondate"
+msgstr "On %1$s"
+
+#: views/statistics/rss/summary.thtml:61 views/statistics/addon.thtml:203
+#, fuzzy
+msgid "statistics_summary_updatepings_weekly_average"
+msgstr "Average Daily Users this Week"
+
+#. %s is a percentage, like '+22.33%'. It sits next to another number, so
+#. the implied meaning is 'percentage change' from the previous stat point.
+#: views/statistics/rss/summary.thtml:62 views/statistics/addon.thtml:205
+#, fuzzy
+msgid "statistics_summary_updatepings_weekly_change"
+msgstr "%s from last week"
+
+#: views/statistics/addon.thtml:65 controllers/statistics_controller.php:184
+#: controllers/statistics_controller.php:282
+#, fuzzy, php-format
+msgid "statistics_title_addon_stats"
+msgstr "%1$s Statistics"
+
+#: views/addons/themes_landing.thtml:113
+#, fuzzy
+msgid "themes_landing_all_themes"
+msgstr "All Themes"
+
+#: views/addons/themes_landing.thtml:109
+#, fuzzy
+msgid "themes_landing_browse_themes"
+msgstr "Browse Themes"
+
+#: views/users/edit.thtml:185
+#, fuzzy
+msgid "user_change_email"
+msgstr "Change Email Address"
+
+#: views/users/edit.thtml:169
+msgid "user_change_password"
+msgstr "Parolayı değiştir"
+
+#: views/users/edit.thtml:96
+#, fuzzy
+msgid "user_change_password_or_email"
+msgstr "Change Password or Email"
+
+#: controllers/users_controller.php:197
+msgid "user_confirmationcode_resent"
+msgstr "The confirmation code was resent!"
+
+# %1 is the email address, %2 is the URL of the user registration page
+#. %1 is the email address, %2 is the URL of the user registration page
+#: views/users/delete.thtml:51
+#, fuzzy
+msgid "user_del_account_deleted"
+msgstr ""
+"Your user account %1$s has been successfully deleted. If you want to come "
+"back some time, you can re-register on the <a href=\"%2$s\">user "
+"registration page</a>."
+
+#: views/users/delete.thtml:102
+#, fuzzy
+msgid "user_del_community_sad"
+msgstr "The Mozilla Add-ons community is sad to see you go."
+
+#: views/users/delete.thtml:123
+#, fuzzy
+msgid "user_del_confirm_password"
+msgstr "Confirm Password"
+
+#: views/users/delete.thtml:134
+#, fuzzy
+msgid "user_del_deletenow"
+msgstr "Delete my user account now"
+
+# %1 is the URL of the user's info page
+#. %1 is the URL of the user's info page
+#: views/users/delete.thtml:64
+#, fuzzy
+msgid "user_del_error_addons"
+msgstr ""
+"You cannot delete your account if you are listed as an <a href=\"%1$s"
+"\">author of any add-ons</a>. To delete your account, please have another "
+"person in your development group delete you from the list of authors for "
+"your add-ons. Afterwards you will be able to delete your account here."
+
+# %1 is a link to the amo-editors mailing list
+#. %1 is a link to the amo-editors mailing list
+#: views/users/delete.thtml:71
+#, fuzzy
+msgid "user_del_error_addons_more_questions"
+msgstr "If you have additional questions, please contact %1$s for assistance."
+
+#: views/users/delete.thtml:78
+#, fuzzy
+msgid "user_del_error_checkbox"
+msgstr ""
+"You need to check the box \"I understand...\" before we can delete your "
+"account."
+
+#: views/users/delete.thtml:84
+#, fuzzy
+msgid "user_del_error_password"
+msgstr "Please enter your password correctly in order to perform this step."
+
+# %1 is a link to the amo-admins mailing list
+#. %1 is a link to the amo-admins mailing list
+#: views/users/delete.thtml:91
+#, fuzzy
+msgid "user_del_error_unknown"
+msgstr ""
+"An unknown error occured deleting your account. Please contact %1$s with the "
+"issue and we will delete it for you. We apologize for the inconvenience."
+
+#: views/users/delete.thtml:110
+#, fuzzy
+msgid "user_del_header_confirm_deletion"
+msgstr "Confirm account deletion"
+
+# %1 is the user's email address
+#. %1 is the user's email address
+#: views/users/delete.thtml:100
+#, fuzzy
+msgid "user_del_header_delete_account"
+msgstr "Delete User Account %1$s"
+
+#: views/users/delete.thtml:50
+#, fuzzy
+msgid "user_del_header_farewell"
+msgstr "Farewell!"
+
+#: views/users/delete.thtml:115
+#, fuzzy
+msgid "user_del_nologin"
+msgstr "You will not be able to log into Mozilla Add-ons anymore."
+
+#: views/users/delete.thtml:112
+#, fuzzy
+msgid "user_del_permanently_removed_means"
+msgstr ""
+"By clicking \"delete\" your account is going to be <strong>permanently "
+"removed</strong>. That means:"
+
+#: views/users/delete.thtml:116
+#, fuzzy
+msgid "user_del_reviews_anonymized"
+msgstr ""
+"Your reviews and ratings will not be deleted, but they will no longer be "
+"associated with you."
+
+# %1 is a link to the amo-editors mailing list
+#. %1 is a link to the amo-editors mailing list
+#: views/users/delete.thtml:104
+#, fuzzy
+msgid "user_del_specific_problem_editors"
+msgstr ""
+"If you have a specific problem we may help you with, please do not delete "
+"your account now, but contact us at %1$s and we will do our best to assist "
+"you in solving it."
+
+#: views/users/delete.thtml:130
+#, fuzzy
+msgid "user_del_understand_permanent"
+msgstr "I understand that this step cannot be undone."
+
+#: views/helpers/addons_html.php:192
+#, fuzzy
+msgid "user_deleted_nickname"
+msgstr "Deleted User"
+
+# %1 is the new email address
+#. %1 is the new email address
+#: views/users/edit.thtml:71
+#, fuzzy
+msgid "user_edit_confirm_email_sent"
+msgstr ""
+"An email has been sent to %1$s to confirm your new email address. For the "
+"change to take effect, you need to click on the link provided in this email. "
+"Until then, you can keep logging in with your current email address."
+
+#: views/users/edit.thtml:201
+#, fuzzy
+msgid "user_edit_delete_user"
+msgstr "Delete user account"
+
+# This contains the email sent to users when they signed up for a new
+# account:
+# %1 is the confirmation URL, %2 is the current app
+#. This contains the email sent to users when they signed up for a new
+#. account:
+#. %1 is the confirmation URL, %2 is the current app
+#: views/users/email/confirm_plain.thtml:6
+#, php-format
+msgid "user_email_confirm_account_nopass"
+msgstr ""
+"Welcome to %2$s Add-ons.\n"
+"\n"
+"Before you can use your new account you must activate it - this ensures the "
+"e-mail address you used is valid and belongs to you.\n"
+"To activate your account, click the link below or copy and paste the whole "
+"thing into your browser's location bar:\n"
+"\n"
+"%1$s\n"
+"\n"
+"Once you successfully activated your account, you can throw away this e-"
+"mail.\n"
+"\n"
+"Thanks for joining %2$s Add-ons\n"
+"-- %2$s Add-ons Staff"
+
+# %1 is the confirmation url, %2 is the application name
+#. %1 is the confirmation url, %2 is the application name
+#: views/users/email/emailchange_plain.thtml:5
+#, fuzzy
+msgid "user_email_confirm_emailchange"
+msgstr ""
+"You requested a change to your email address at %2$s Add-ons.\n"
+"\n"
+"In order to confirm the new address, please click the link below or copy and "
+"paste the whole thing into your browser's location bar:\n"
+"\n"
+"%1$s\n"
+"\n"
+"You have 48 hours to confirm the new address. If you do not want to change "
+"the address anymore, you can just ignore this email.\n"
+"\n"
+"Thanks!\n"
+"-- %2$s Add-ons Staff"
+
+#: controllers/users_controller.php:168
+#, php-format
+msgid "user_email_confirm_subject"
+msgstr "Mozilla Eklentileri'ne katıldığnız için teşekkürler"
+
+# This is the password reset email
+# %1 is the pw reset URL
+#. This is the password reset email
+#. %1 is the pw reset URL, %2 is the application
+#: views/users/email/pwreset_plain.thtml:5
+#, php-format
+msgid "user_email_pwreset"
+msgstr ""
+"Mozilla Eklentileri Şifre Sıfırlama\n"
+"\n"
+"addons.mozilla.org hesabınız için bir şifre sıfırlama isteği alındı. Şifreyi "
+"değiştirmek için izleyen bağlantıyı tıklayın veya tarayıcınızın adres "
+"çubuğuna yapıştırın:\n"
+"\n"
+"%1$s\n"
+"\n"
+"Eğer ihtiyacınız yoksa bu e-postayı dikkate almayın.\n"
+"\n"
+"Teşekkürler,\n"
+"-- Mozilla Eklentileri Yönetimi"
+
+#: controllers/users_controller.php:245
+#, php-format
+msgid "user_email_pwreset_subject"
+msgstr "Mozilla Eklentileri şifremi sıfırla"
+
+#: views/users/emailchange.thtml:50
+#, fuzzy
+msgid "user_emailchange_error"
+msgstr "Error!"
+
+# %1 is the application name
+#. %1 is the application name
+#: controllers/users_controller.php:533
+#, fuzzy
+msgid "user_emailchange_subject"
+msgstr "Please confirm your email address change at %1$s Add-ons"
+
+#: views/users/emailchange.thtml:48
+#, fuzzy
+msgid "user_emailchange_success"
+msgstr "Success!"
+
+# %1 is the new email address
+#. %1 is the new email address
+#: views/users/emailchange.thtml:49
+#, fuzzy
+msgid "user_emailchange_successful_description"
+msgstr ""
+"Your email address was changed successfully. From now on, please use %1$s to "
+"log in."
+
+#: views/users/edit.thtml:134 views/admin/users_edit.thtml:111
+#, fuzzy
+msgid "user_form_bio"
+msgstr "About me"
+
+#: views/users/edit.thtml:135 views/admin/users_edit.thtml:112
+#, fuzzy
+msgid "user_form_bio_description"
+msgstr ""
+"Introduce yourself to the community, if you like! This text will appear "
+"publicly on your user info page. Line breaks will be preserved, but no HTML "
+"is allowed."
+
+#: views/users/pwreset.thtml:77 views/users/register.thtml:73
+#: views/users/edit.thtml:181
+msgid "user_form_confirmpassword"
+msgstr "Parolayı doğrulayın"
+
+#: views/users/edit.thtml:145
+#, fuzzy
+msgid "user_form_display_collections"
+msgstr "Display the collections I have created in my user profile"
+
+#: views/users/edit.thtml:149
+#, fuzzy
+msgid "user_form_display_collections_fav"
+msgstr "Display my favorite collections in my user profile"
+
+#: views/users/edit.thtml:86
+#, php-format
+msgid "user_form_editprofile"
+msgstr "%s hakkındaki kullanıcı profilini düzenle"
+
+#: views/users/pwreset.thtml:52 views/users/login.thtml:81
+#: views/users/register.thtml:63 views/users/edit.thtml:187
+msgid "user_form_email"
+msgstr "E-posta adresi"
+
+#: views/users/register.thtml:78 views/users/edit.thtml:103
+#: views/admin/users_edit.thtml:76
+msgid "user_form_firstname"
+msgstr "Ad"
+
+#: views/users/register.thtml:94 views/users/edit.thtml:119
+#: views/admin/users_edit.thtml:91
+msgid "user_form_hideemail"
+msgstr "E-posta adresini gizle"
+
+#: views/users/register.thtml:98 views/users/edit.thtml:123
+#: views/admin/users_edit.thtml:99
+msgid "user_form_homepage"
+msgstr "Web sitesi"
+
+#: views/users/register.thtml:84 views/users/edit.thtml:109
+#: views/admin/users_edit.thtml:81
+msgid "user_form_lastname"
+msgstr "Soyad"
+
+#: controllers/users_controller.php:333
+msgid "user_form_login"
+msgstr "Kullanıcı Girişi"
+
+#: views/users/pwreset.thtml:72 views/users/edit.thtml:176
+msgid "user_form_newpassword"
+msgstr "Yeni parola"
+
+#: views/users/register.thtml:89 views/users/edit.thtml:114
+#: views/admin/users_edit.thtml:86
+msgid "user_form_nickname"
+msgstr "Takma ad"
+
+#: views/users/edit.thtml:171
+msgid "user_form_oldpassword"
+msgstr "Eski parola"
+
+#: views/users/edit.thtml:97 views/users/edit.thtml:200
+#, fuzzy
+msgid "user_form_otheractions"
+msgstr "Other Actions"
+
+#: views/users/login.thtml:85 views/users/register.thtml:68
+msgid "user_form_password"
+msgstr "Parola"
+
+#: controllers/users_controller.php:93
+msgid "user_form_registration"
+msgstr "Yeni kullanıcı kaydı"
+
+#: views/users/login.thtml:90
+#, fuzzy
+msgid "user_form_remember_me"
+msgstr "Remember me on this computer"
+
+#: views/admin/users_edit.thtml:95
+msgid "user_form_showsandbox"
+msgstr "Show sandbox?"
+
+#: views/users/edit.thtml:205
+msgid "user_form_submit_edit"
+msgstr "Kaydet"
+
+#: views/users/login.thtml:93
+msgid "user_form_submit_login"
+msgstr "Oturum aç"
+
+#: views/users/register.thtml:113
+msgid "user_form_submit_register"
+msgstr "Kaydol"
+
+#: views/users/info.thtml:75
+#, php-format
+msgid "user_info_usersince"
+msgstr "%s Add-ons user since"
+
+#: views/users/login.thtml:102
+msgid "user_login_register_link"
+msgstr "Yeni kullanıcı hesabı aç"
+
+#: views/users/edit.thtml:160
+#, fuzzy
+msgid "user_notifications_item_compat"
+msgstr "Add-on Compatibility (strongly recommended)"
+
+#: views/users/edit.thtml:161
+#, fuzzy
+msgid "user_notifications_item_events"
+msgstr "Upcoming events and contests"
+
+#: views/users/edit.thtml:156
+#, fuzzy
+msgid "user_notifications_none_available"
+msgstr "There are currently no notifications available for you to configure."
+
+#: views/users/edit.thtml:158
+#, fuzzy
+msgid "user_notifications_select_topics"
+msgstr ""
+"From time to time, Mozilla may send you email about upcoming releases and "
+"add-on events. Please select the topics you are interested in below:"
+
+#: views/users/edit.thtml:164
+#, fuzzy
+msgid "user_notifications_specific_contact"
+msgstr ""
+"Mozilla reserves the right to contact you individually about specific "
+"concerns with your hosted add-ons."
+
+#: controllers/users_controller.php:543
+msgid "user_profile_edit_error"
+msgstr ""
+"Yaptığınız değişikliklerde hatalar bulunmaktadır. Lütfen düzeltip yeniden "
+"gönderiniz..."
+
+#: controllers/users_controller.php:540
+msgid "user_profile_saved"
+msgstr "Profil güncellendi."
+
+#: views/users/pwreset.thtml:65
+#, php-format
+msgid "user_pwreset_for_email"
+msgstr "%s kullanıcısı için parolayı sıfırla"
+
+#: controllers/users_controller.php:226
+msgid "user_pwreset_header"
+msgstr "Parola Sıfırlama"
+
+#: views/users/login.thtml:103
+msgid "user_pwreset_link"
+msgstr "Parolanızı mı unuttunuz?"
+
+#: controllers/users_controller.php:248
+msgid "user_pwreset_link_sent"
+msgstr "Şifre sıfırlama bağlantısı e-postanıza gönderildi."
+
+#: controllers/users_controller.php:304
+msgid "user_pwreset_okay"
+msgstr "Şifre başarıyla sıfırlandı."
+
+#: views/users/pwreset.thtml:82
+msgid "user_pwreset_submit_changepw"
+msgstr "Parola değişikliğini gönder"
+
+#: views/users/pwreset.thtml:57
+msgid "user_pwreset_submit_sendlink"
+msgstr "Parola sıfırlama bağlantısı gönder"
+
+#: views/users/register_complete.thtml:51
+#, php-format
+msgid "user_register_amo_link"
+msgstr "%s Add-ons"
+
+# %1 is the user's email address, %2 is the current app
+#. %1 is the user's email address, %2 is the current app
+#: views/users/activatefirst.thtml:49
+#, php-format
+msgid "user_register_click_confirm_link"
+msgstr ""
+"A link to activate your user account was sent by email to your address %1$s. "
+"You have to click it before you can log into %2$s Add-ons."
+
+# %1 is the user's email address
+#. %1 is the user's email address
+#: views/users/register_complete.thtml:49
+#, php-format
+msgid "user_register_confirm_email_sent"
+msgstr ""
+"An email has been sent to your address %1$s to confirm your account. Before "
+"you can log in, you have to activate your account by clicking on the link "
+"provided in this email."
+
+#: views/users/activatefirst.thtml:51
+msgid "user_register_confirmation_link_text"
+msgstr "resend the confirmation message"
+
+#: views/users/register_complete.thtml:47
+msgid "user_register_congratulations"
+msgstr "Congratulations! Your user account was successfully created."
+
+#: views/users/register.thtml:50
+#, fuzzy
+msgid "user_register_details"
+msgstr ""
+"<p>Registration on AMO is <strong>not required</strong> if you simply want "
+"to download and install public add-ons.</p><p>You only need to register if:</"
+"p><ul><li>You want to submit reviews for add-ons</li><li>You are an add-on "
+"developer and want to upload your add-on for hosting on AMO</li></ul><p>Upon "
+"successful registration, you will be sent a confirmation email to the "
+"address you provided. Please follow the instructions there to confirm your "
+"account.</p><p>If you like, you can read our <a href='%1$s' title='Legal "
+"Notices'>Legal Notices</a> and <a href='%2$s' title='Privacy Policy'>Privacy "
+"Policy</a>.</p>"
+
+# %1 is the link to the "resend confirmation code" page
+#. %1 is the link to the "resend confirmation code" page
+#: views/users/activatefirst.thtml:51
+#, php-format
+msgid "user_register_resend_confirmation_link"
+msgstr ""
+"If you did not receive the confirmation email, make sure your email service "
+"did not mark it as \"junk mail\" or \"spam\". If you need to, you can have "
+"us %1$s to your email address mentioned above."
+
+# %1 is the link to the Mozilla Add-ons front page
+#. %1 is the link to the Mozilla Add-ons front page
+#: views/users/register_complete.thtml:51
+#, php-format
+msgid "user_register_welcome"
+msgstr "Thanks for registering and welcome to %1$s!"
+
+#: views/users/register.thtml:49
+#, fuzzy
+msgid "user_register_welcome_header"
+msgstr "Welcome to addons.mozilla.org (AMO)!"
+
+#: views/users/register.thtml:81 views/users/edit.thtml:106
+#, fuzzy
+msgid "user_required_firstlast_or_nickname"
+msgstr "A first name, last name or nickname is required."
+
+#: views/users/edit.thtml:94 views/users/edit.thtml:142
+#, fuzzy
+msgid "user_tab_collections"
+msgstr "Collections"
+
+#: views/users/edit.thtml:95 views/users/edit.thtml:154
+#, fuzzy
+msgid "user_tab_notifications"
+msgstr "Notifications"
+
+#: views/users/edit.thtml:93 views/users/edit.thtml:101
+#, fuzzy
+msgid "user_tab_profile"
+msgstr "User Profile"
+
+#: controllers/users_controller.php:209
+msgid "user_verified_okay"
+msgstr "Başarıyla doğrulandı!"
+
+#: controllers/users_controller.php:723
+#, fuzzy
+msgid "users_delete_pagetitle"
+msgstr "Delete User Account"
+
+#: controllers/users_controller.php:414
+msgid "users_edit_pagetitle"
+msgstr "Kullanıcı Hesabı Düzenlemesi"
+
+#: views/users/info.thtml:71
+#, fuzzy
+msgid "users_info_aboutme"
+msgstr "About Me"
+
+#: views/users/info.thtml:96
+#, php-format
+msgid "users_info_addons_by_user"
+msgstr "Add-ons by %1$s"
+
+#: views/users/info.thtml:51
+#, fuzzy
+msgid "users_info_author_name"
+msgstr "Name"
+
+#: views/users/info.thtml:48
+msgid "users_info_author_profile"
+msgstr "Author Profile"
+
+#. %s is the user name
+#: views/users/info.thtml:137
+#, fuzzy
+msgid "users_info_collections_by_user"
+msgstr "Collections by %s"
+
+#: views/users/info.thtml:66
+msgid "users_info_email"
+msgstr "Email address"
+
+#: views/users/info.thtml:155
+#, fuzzy
+msgid "users_info_fav_collections_by_user"
+msgstr "Favorite Collections"
+
+#: views/users/info.thtml:61
+msgid "users_info_homepage"
+msgstr "Homepage"
+
+#: views/users/info.thtml:56
+msgid "users_info_nickname"
+msgstr "Nickname"
+
+#: controllers/users_controller.php:707
+#, php-format
+msgid "users_info_pagetitle"
+msgstr "User Info for %1$s"
+
+# %1 is the user's name
+#. %1 is the user's name
+#: views/users/info.thtml:116
+#, fuzzy
+msgid "users_info_reviews_by_user"
+msgstr "Reviews by %s"
+
+#: controllers/users_controller.php:330 controllers/users_controller.php:332
+msgid "users_login_pagetitle"
+msgstr "Kullanıcı Girişi"
+
+# %1 is the link to the sandbox/policy explanation page
+# This message is for a specific add-on not found
+#. %1 is the link to the sandbox/policy explanation page
+#. This message is for a specific add-on not found
+#: views/users/login.thtml:53
+#, fuzzy, php-format
+msgid "users_login_sandbox_display_warning"
+msgstr ""
+"The add-on you're looking for is currently in the sandbox. If you already "
+"have an account on Mozilla Add-ons, please login, or <a href=\"%1$s\">learn "
+"more about the sandbox.</a>"
+
+# %1 is the link to the sandbox/policy explanation page
+# This message is for any given sandbox-related page not found
+#. %1 is the link to the sandbox/policy explanation page
+#. This message is for any given sandbox-related page not found
+#: views/users/login.thtml:56
+#, fuzzy, php-format
+msgid "users_login_sandbox_page_warning"
+msgstr ""
+"The page you're looking for is part of the sandbox. If you already have an "
+"account on Mozilla Add-ons, please login, or <a href=\"%1$s\">learn more "
+"about the sandbox.</a>"
+
+#: controllers/users_controller.php:223 controllers/users_controller.php:225
+msgid "users_pwreset_pagetitle"
+msgstr "Kullanıcı Şifre Sıfırlaması"
+
+#: controllers/users_controller.php:90 controllers/users_controller.php:92
+msgid "users_register_pagetitle"
+msgstr "Yeni Kullanıcı Kaydı"
+
+#. %1$s is an addon name, like <a>Firebug</a>
+#. %2$s is a version number, like <a>1.2</a>
+#: views/versions/license.thtml:52
+#, fuzzy
+msgid "versions_license_header_source"
+msgstr "Source code license for %1$s %2$s"
+
+#: views/addons/category_landing.thtml:147
+#, fuzzy
+msgid "view_recently_added"
+msgstr "View all recently added"
+
+#: views/addons/category_landing.thtml:161
+#, fuzzy
+msgid "view_top_downloads"
+msgstr "View all top downloads"
+
+#: views/addons/category_landing.thtml:175
+#, fuzzy
+msgid "view_top_rated"
+msgstr "View all top rated"
+
+#, fuzzy
+#~ msgid "addon_slider_tooltip_next"
+#~ msgstr "Next Add-on"
+
+#, fuzzy
+#~ msgid "addon_slider_tooltip_previous"
+#~ msgstr "Previous Add-on"
+
+#, fuzzy
+#~ msgid "addon_versions_getlatesttext"
+#~ msgstr "The most recent version compatible with"
+
+#, fuzzy
+#~ msgid "addons_display_version_history"
+#~ msgstr "Complete Version History"
+
+#, fuzzy
+#~ msgid "addons_home_newest_header"
+#~ msgstr "Newest:"
+
+#, fuzzy
+#~ msgid "addons_home_popular_header"
+#~ msgstr "Most Popular:"
+
+#, fuzzy
+#~ msgid "addons_home_recommended_header"
+#~ msgstr "We Recommend:"
+
+#, fuzzy
+#~ msgid "addons_home_updated_header"
+#~ msgstr "Recently Updated:"
+
+#, fuzzy
+#~ msgid "addons_home_view_all"
+#~ msgstr "View all"
+
+#, fuzzy
+#~ msgid "category_extra_allrecommended"
+#~ msgstr "See All Recommended Add-ons"
+
+#, fuzzy
+#~ msgid "category_extra_highestrated"
+#~ msgstr "Highest Rated First"
+
+#, fuzzy
+#~ msgid "category_extra_lastupdated"
+#~ msgstr "Last Updated First"
+
+#, fuzzy
+#~ msgid "category_extra_mostpopular"
+#~ msgstr "Most Popular First"
+
+#, fuzzy
+#~ msgid "collections_detail_js_loading"
+#~ msgstr "Loading"
+
+#, fuzzy
+#~ msgid "collections_detail_more_info"
+#~ msgstr "Show More Info"
+
+#, fuzzy
+#~ msgid "devcp_additem_firefox_notice"
+#~ msgstr ""
+#~ "This version of your add-on does not claim compatibility with Firefox %1"
+#~ "$s. Mozilla is expecting the next version of Firefox to be released soon, "
+#~ "so please test your add-on in the new version and update compatibility "
+#~ "information. You can find out more about this <a href=\"%2$s\">here</a>. "
+#~ "This is only a notice and you may continue to submit this version to "
+#~ "addons.mozilla.org."
+
+#~ msgid "devcp_addon_disabled_successfully"
+#~ msgstr "Add-on disabled successfully"
+
+#~ msgid "devcp_addon_edit_pagetitle"
+#~ msgstr "Edit Add-on"
+
+#~ msgid "devcp_addon_enabled_successfully"
+#~ msgstr "Add-on enabled successfully"
+
+#~ msgid "devcp_addon_field_description_displaytitle"
+#~ msgstr "Add-on Description"
+
+#~ msgid "devcp_addon_field_eula_displaytitle"
+#~ msgstr "EULA"
+
+#~ msgid "devcp_addon_field_homepage_displaytitle"
+#~ msgstr "Add-on Homepage"
+
+#~ msgid "devcp_addon_field_name_displaytitle"
+#~ msgstr "Add-on Name"
+
+#~ msgid "devcp_addon_field_privacy_displaytitle"
+#~ msgstr "Privacy Policy"
+
+#~ msgid "devcp_addon_field_summary_displaytitle"
+#~ msgstr "Add-on Summary"
+
+#, fuzzy
+#~ msgid "devcp_addon_field_supportemail_displaytitle"
+#~ msgstr "Support Email"
+
+#, fuzzy
+#~ msgid "devcp_addon_field_supporturl_displaytitle"
+#~ msgstr "Support URL"
+
+#~ msgid "devcp_addon_field_versionnotes_displaytitle"
+#~ msgstr "Version Notes"
+
+#~ msgid "devcp_addon_nominate_pagetitle"
+#~ msgstr "Nominate Add-on"
+
+#~ msgid "devcp_addon_nominated_successfully"
+#~ msgstr "Add-on nominated successfully!"
+
+#, fuzzy
+#~ msgid "devcp_addon_status_criteria_review"
+#~ msgstr "Several user reviews of the add-on (may be external reviews)."
+
+# %1 is the addon edit link
+# %2 is the main dev CP link
+#, fuzzy
+#~ msgid "devcp_addon_submission_makechanges"
+#~ msgstr ""
+#~ "Visit the %1$s page to make changes to your submission, or %2$s to return "
+#~ "to the Developer Control Panel."
+
+#~ msgid "devcp_addon_submission_makechanges_devcp_link"
+#~ msgstr "click here"
+
+#~ msgid "devcp_addon_submission_makechanges_link"
+#~ msgstr "Edit Add-on"
+
+#~ msgid "devcp_addon_submission_pending"
+#~ msgstr ""
+#~ "This version has been placed in the sandbox while it awaits review from "
+#~ "sandbox testers and a Mozilla Add-ons editor. You will be notified by e-"
+#~ "mail when action has been taken."
+
+# %1 is the link to the sandbox information page
+#, fuzzy
+#~ msgid "devcp_addon_submission_sandbox_readmore"
+#~ msgstr "You can read more about the Sandbox Review System %s."
+
+#~ msgid "devcp_addon_submission_sandbox_readmore_link"
+#~ msgstr "here"
+
+# %1 is the "nominate" link
+#, fuzzy
+#~ msgid "devcp_addon_submission_sandboxed"
+#~ msgstr ""
+#~ "This version has been placed in the sandbox for use by experienced users. "
+#~ "In order for it to be shown on the public site, you must %s your add-on "
+#~ "and undergo a review process."
+
+#~ msgid "devcp_addon_submission_sandboxed_nominate_link"
+#~ msgstr "nominate"
+
+#~ msgid "devcp_addon_submission_success"
+#~ msgstr "Your add-on submission has been completed successfully."
+
+#~ msgid "devcp_addon_submission_trusted_public"
+#~ msgstr ""
+#~ "Because your add-on is trusted, this version has automatically been "
+#~ "approved for the public area."
+
+#~ msgid "devcp_addon_submit_pagetitle"
+#~ msgstr "Submit Add-on"
+
+#~ msgid "devcp_addon_updated_successfully"
+#~ msgstr "Add-on updated successfully"
+
+# %1 is the link to the preview upload page
+#, fuzzy
+#~ msgid "devcp_addon_upload_preview"
+#~ msgstr "You may wish to %s to increase interest in your add-on."
+
+#~ msgid "devcp_addon_upload_preview_link"
+#~ msgstr "upload a preview"
+
+# #1 is the author email
+#~ msgid "devcp_author_lookup_none_found"
+#~ msgstr "No author found [%s]"
+
+#~ msgid "devcp_author_lookup_remove"
+#~ msgstr "Remove"
+
+#~ msgid "devcp_button_cancel"
+#~ msgstr "Cancel"
+
+#~ msgid "devcp_button_cancel_confirm"
+#~ msgstr "Are you sure you wish to cancel your submission?"
+
+#~ msgid "devcp_button_next"
+#~ msgstr "Next"
+
+#~ msgid "devcp_change_addontype"
+#~ msgstr "Change add-on type:"
+
+#~ msgid "devcp_comments_updated"
+#~ msgstr "Developer Comments updated."
+
+#~ msgid "devcp_details_addpreview_link"
+#~ msgstr "Add Preview"
+
+#~ msgid "devcp_details_author"
+#~ msgstr "Author"
+
+#~ msgid "devcp_details_authors"
+#~ msgstr "Authors"
+
+#~ msgid "devcp_details_authors_none"
+#~ msgstr "None"
+
+#~ msgid "devcp_details_categories"
+#~ msgstr "Categories"
+
+#~ msgid "devcp_details_category"
+#~ msgstr "Category"
+
+#~ msgid "devcp_details_description"
+#~ msgstr "Description"
+
+#~ msgid "devcp_details_disabled"
+#~ msgstr "Disabled"
+
+#~ msgid "devcp_details_guid"
+#~ msgstr "GUID"
+
+#~ msgid "devcp_details_header_details"
+#~ msgstr "Details"
+
+#~ msgid "devcp_details_header_devcomments"
+#~ msgstr "Developer Comments"
+
+#~ msgid "devcp_details_header_previews"
+#~ msgstr "Previews"
+
+#~ msgid "devcp_details_header_versions"
+#~ msgstr "Versions"
+
+#~ msgid "devcp_details_homepage"
+#~ msgstr "Homepage"
+
+#~ msgid "devcp_details_homepage_none"
+#~ msgstr "None"
+
+#~ msgid "devcp_details_preview_nocaption"
+#~ msgstr "No caption"
+
+#~ msgid "devcp_details_previews_nonefound"
+#~ msgstr "No previews found."
+
+#~ msgid "devcp_details_submit_update"
+#~ msgstr "Update"
+
+#, fuzzy
+#~ msgid "devcp_details_supportemail"
+#~ msgstr "Support Email"
+
+#, fuzzy
+#~ msgid "devcp_details_supportemail_none"
+#~ msgstr "No support email provided by developer."
+
+#, fuzzy
+#~ msgid "devcp_details_supporturl"
+#~ msgstr "Support URL"
+
+#, fuzzy
+#~ msgid "devcp_details_supporturl_none"
+#~ msgstr "No support url provided by developer."
+
+#~ msgid "devcp_details_trusted"
+#~ msgstr "Trusted"
+
+#~ msgid "devcp_details_versions_none_found"
+#~ msgstr "No versions found."
+
+#, fuzzy
+#~ msgid "devcp_disable_cancel"
+#~ msgstr "Cancel and go back"
+
+#, fuzzy
+#~ msgid "devcp_disable_disable_button"
+#~ msgstr "Yes, disable it"
+
+#, fuzzy
+#~ msgid "devcp_disable_disable_confirm"
+#~ msgstr "Are you sure you want to disable this add-on?"
+
+#, fuzzy
+#~ msgid "devcp_disable_disable_description"
+#~ msgstr ""
+#~ "Disabling this add-on will hide it from searches and listings. It will "
+#~ "not be downloadable from the website and will not be returned in client "
+#~ "update checks. The add-on will effectively be deleted, although you will "
+#~ "be able to return here and re-enable it at your convenience."
+
+#, fuzzy
+#~ msgid "devcp_disable_disable_title"
+#~ msgstr "Disable %s"
+
+#, fuzzy
+#~ msgid "devcp_disable_enable_button"
+#~ msgstr "Yes, enable it"
+
+#, fuzzy
+#~ msgid "devcp_disable_enable_confirm"
+#~ msgstr "Are you sure you want to enable this add-on?"
+
+#, fuzzy
+#~ msgid "devcp_disable_enable_description"
+#~ msgstr ""
+#~ "Enabling this add-on will cause it to once again appear in searches and "
+#~ "listings. It will be downloadable both from the website and from client "
+#~ "update checks."
+
+#, fuzzy
+#~ msgid "devcp_disable_enable_title"
+#~ msgstr "Enable %s"
+
+#~ msgid "devcp_edit_author_add"
+#~ msgstr "Add Author"
+
+#~ msgid "devcp_edit_author_email"
+#~ msgstr "Author's Email Address"
+
+#~ msgid "devcp_edit_author_remove"
+#~ msgstr "Remove"
+
+#~ msgid "devcp_edit_error_categories_unavailable"
+#~ msgstr "No categories available for this add-on type."
+
+#, fuzzy
+#~ msgid "devcp_edit_file_error_incomplete"
+#~ msgstr "Incomplete transfer"
+
+#, fuzzy
+#~ msgid "devcp_edit_file_error_no"
+#~ msgstr "No file uploaded"
+
+#, fuzzy
+#~ msgid "devcp_edit_file_error_size"
+#~ msgstr "Exceeds maximum upload size"
+
+#~ msgid "devcp_edit_header_authors"
+#~ msgstr "Authors"
+
+#~ msgid "devcp_edit_icon_add_link"
+#~ msgstr "Add Icon"
+
+#~ msgid "devcp_edit_icon_change_link"
+#~ msgstr "Change Icon"
+
+#~ msgid "devcp_edit_label_allow_viewsource"
+#~ msgstr "Allow users to view the source files online"
+
+#~ msgid "devcp_edit_label_categories"
+#~ msgstr "Categories"
+
+#~ msgid "devcp_edit_label_defaultlocale"
+#~ msgstr "Default Locale"
+
+#~ msgid "devcp_edit_label_icon_delete"
+#~ msgstr "Only clear the existing icon"
+
+#~ msgid "devcp_edit_label_icon_new"
+#~ msgstr "New Icon File"
+
+#~ msgid "devcp_edit_label_info"
+#~ msgstr "Icon"
+
+#, fuzzy
+#~ msgid "devcp_edit_locale_disambiguation_explanation"
+#~ msgstr "short additional info (such as a local dialect name)"
+
+#~ msgid "devcp_edit_submit_update"
+#~ msgstr "Update"
+
+#, fuzzy
+#~ msgid "devcp_edit_target_locale_explanation"
+#~ msgstr ""
+#~ "<a href=\"http://wiki.mozilla.org/L10n:Simple_locale_names\">simple "
+#~ "locale name</a>, such as 'en-US'"
+
+#~ msgid "devcp_editversion_checkedfiles_delete"
+#~ msgstr "Checked files will be deleted."
+
+# %1 is the file name
+# %2 is the file size (150 KB)
+#~ msgid "devcp_editversion_filename_size"
+#~ msgstr "%1$s (%2$s)"
+
+#~ msgid "devcp_editversion_label_files"
+#~ msgstr "Files"
+
+#~ msgid "devcp_editversion_label_targetapps"
+#~ msgstr "Target Applications"
+
+#~ msgid "devcp_editversion_nofiles"
+#~ msgstr "No files."
+
+#~ msgid "devcp_editversion_reviewernotes"
+#~ msgstr "Notes to Reviewer"
+
+#~ msgid "devcp_editversion_submit_update"
+#~ msgstr "Update"
+
+#~ msgid "devcp_error_addon_field_summary_toolong"
+#~ msgstr ""
+#~ "Summaries are limited to a maximum of 250 characters.\n"
+#~ "(You entered %s)"
+
+#~ msgid "devcp_error_addonname_not_unique"
+#~ msgstr ""
+#~ "The name for your add-on already exists in the database. Please make sure "
+#~ "that: <br /><li>Your GUIDs match. The most common cause for this error is "
+#~ "mismatched GUIDs.</li><li>You do not have a duplicate entry in the "
+#~ "database. If you do, you should update that entry or delete it and try "
+#~ "again.</li>"
+
+#~ msgid "devcp_error_describe_changes"
+#~ msgstr "Please describe the changes made in this add-on update."
+
+#~ msgid "devcp_error_file_guids_dont_match"
+#~ msgstr "Not all file GUIDs match"
+
+#~ msgid "devcp_error_identical_version_exists"
+#~ msgstr ""
+#~ "An identical version (%s) already exists for this add-on and platform."
+
+#, fuzzy
+#~ msgid "devcp_error_nominate_message"
+#~ msgstr "You must supply the requested details for nomination."
+
+#, fuzzy
+#~ msgid "devcp_error_nominate_no_prerelease"
+#~ msgstr "You cannot nominate a pre-release add-on."
+
+#~ msgid "devcp_error_nominate_sandbox_only"
+#~ msgstr "You can only nominate add-ons currently in the sandbox."
+
+#~ msgid "devcp_error_saving"
+#~ msgstr "An error occurred trying to save your data."
+
+#~ msgid "devcp_error_update_access_denied"
+#~ msgstr "You do not have permission to update this add-on."
+
+#~ msgid "devcp_file_addanother"
+#~ msgstr "Add Another Platform File"
+
+#~ msgid "devcp_form_author_add"
+#~ msgstr "Add Author"
+
+#~ msgid "devcp_form_author_remove"
+#~ msgstr "Remove"
+
+#~ msgid "devcp_form_categories_nextstep"
+#~ msgstr ""
+#~ "Categories for your new add-on type will be available in the next step."
+
+#~ msgid "devcp_form_error_categories_unavailable"
+#~ msgstr "No categories available for this add-on type."
+
+#~ msgid "devcp_form_error_description_notempty"
+#~ msgstr "Please enter a description of your add-on."
+
+#~ msgid "devcp_form_error_name_required"
+#~ msgstr "Please enter the name of your add-on."
+
+#~ msgid "devcp_form_error_select_addontype"
+#~ msgstr "Please select the type of add-on you are submitting."
+
+#~ msgid "devcp_form_error_summary_notempty"
+#~ msgstr "Please enter a summary of your add-on."
+
+#~ msgid "devcp_form_label_addonfile"
+#~ msgstr "Add-on File"
+
+#~ msgid "devcp_form_label_addonfile2"
+#~ msgstr "Add-on File 2"
+
+#~ msgid "devcp_form_label_addonfile3"
+#~ msgstr "Add-on File 3"
+
+#~ msgid "devcp_form_label_addontype"
+#~ msgstr "Add-on Type"
+
+#~ msgid "devcp_form_label_allow_viewsource"
+#~ msgstr "Allow users to view the source files online"
+
+#~ msgid "devcp_form_label_author_email"
+#~ msgstr "Author's Email Address"
+
+#~ msgid "devcp_form_label_authors"
+#~ msgstr "Authors"
+
+#~ msgid "devcp_form_label_categories"
+#~ msgstr "Categories"
+
+#~ msgid "devcp_form_label_defaultlocale"
+#~ msgstr "Default Locale"
+
+#~ msgid "devcp_form_label_description"
+#~ msgstr "Description"
+
+#~ msgid "devcp_form_label_eula"
+#~ msgstr "End User License Agreement (EULA)"
+
+#~ msgid "devcp_form_label_externalsoftware"
+#~ msgstr "This add-on requires external software"
+
+#~ msgid "devcp_form_label_files"
+#~ msgstr "Files"
+
+#~ msgid "devcp_form_label_homepage"
+#~ msgstr "Homepage"
+
+#~ msgid "devcp_form_label_iconfile"
+#~ msgstr "Icon File"
+
+#~ msgid "devcp_form_label_name"
+#~ msgstr "Name"
+
+#~ msgid "devcp_form_label_platforms"
+#~ msgstr "Supported Platforms"
+
+#~ msgid "devcp_form_label_prerelease"
+#~ msgstr "This is a pre-release"
+
+#~ msgid "devcp_form_label_privacy"
+#~ msgstr "Privacy Policy"
+
+#~ msgid "devcp_form_label_sitespecific"
+#~ msgstr "This is a site-specific add-on"
+
+#~ msgid "devcp_form_label_summary"
+#~ msgstr "Summary"
+
+#, fuzzy
+#~ msgid "devcp_form_label_supportemail"
+#~ msgstr "Support Email"
+
+#, fuzzy
+#~ msgid "devcp_form_label_supporturl"
+#~ msgstr "Support URL"
+
+#~ msgid "devcp_form_label_target_applications"
+#~ msgstr "Target Applications"
+
+#~ msgid "devcp_form_label_version"
+#~ msgstr "Version"
+
+#~ msgid "devcp_form_label_versionnotes"
+#~ msgstr "Version Notes"
+
+#~ msgid "devcp_form_no_target_apps"
+#~ msgstr "None"
+
+#~ msgid "devcp_form_reviewernotes"
+#~ msgstr "Notes to Reviewer"
+
+#~ msgid "devcp_form_trustedaddon_destination"
+#~ msgstr ""
+#~ "Because your add-on is trusted, please choose where this version should "
+#~ "go:"
+
+#~ msgid "devcp_form_trustedaddon_destination_public"
+#~ msgstr "Public"
+
+#~ msgid "devcp_form_trustedaddon_destination_sandbox"
+#~ msgstr "Sandbox"
+
+#~ msgid "devcp_header_developer_agreement"
+#~ msgstr "Developer Agreement"
+
+#~ msgid "devcp_header_step1"
+#~ msgstr "Step 1"
+
+#~ msgid "devcp_header_step1_upload"
+#~ msgstr "Upload File"
+
+#~ msgid "devcp_header_step2"
+#~ msgstr "Step 2"
+
+#~ msgid "devcp_header_step2_addondetails"
+#~ msgstr "Add-on Details"
+
+#~ msgid "devcp_header_step3"
+#~ msgstr "Step 3"
+
+#~ msgid "devcp_header_step3_versiondetails"
+#~ msgstr "Version Details"
+
+#~ msgid "devcp_header_step4"
+#~ msgstr "Step 4"
+
+#~ msgid "devcp_header_step4_localization"
+#~ msgstr "Localization"
+
+#~ msgid "devcp_header_step5"
+#~ msgstr "Step 5"
+
+#~ msgid "devcp_header_step5_success"
+#~ msgstr "Success"
+
+#~ msgid "devcp_index_header_myaddons"
+#~ msgstr "My Add-ons"
+
+#~ msgid "devcp_nominate_link_returnto_details"
+#~ msgstr "Return to add-on details"
+
+# %1 is the autodetected addon type
+#~ msgid "devcp_notice_autodetected_addontype"
+#~ msgstr "Automatically detected add-on type: %s."
+
+# %1 is the default locale name (English (US))
+# %2 is the default locale code (en-US)
+# %3 is the current page locale name (Deutsch)
+# %4 is the current page locale code (de)
+#~ msgid "devcp_notice_different_defaultlocale"
+#~ msgstr ""
+#~ "The default locale of this add-on (%1$s [%2$s]) is different from your "
+#~ "currently selected locale (%3$s [%4$s]). The fields below should be "
+#~ "completed in %1$s."
+
+#~ msgid "devcp_question_addontype_incorrect"
+#~ msgstr "Incorrect?"
+
+#~ msgid "devcp_question_delete_file"
+#~ msgstr "Are you sure you want to delete this file?"
+
+#~ msgid "devcp_skip_reviewing_addon_info"
+#~ msgstr "Skip reviewing my current add-on information"
+
+#~ msgid "devcp_submissions_disabled"
+#~ msgstr ""
+#~ "Add-on submissions are currently disabled. Please check back at a later "
+#~ "time."
+
+#~ msgid "devcp_submit_accept_dev_agreement"
+#~ msgstr "I Accept"
+
+#~ msgid "devcp_submit_decline_dev_agreement"
+#~ msgstr "I Decline"
+
+#~ msgid "devcp_summary_admin_disabled"
+#~ msgstr "This add-on has been disabled by an administrator."
+
+#~ msgid "devcp_summary_header_disabled"
+#~ msgstr "Disabled"
+
+#~ msgid "devcp_summary_header_trusted"
+#~ msgstr "Trusted"
+
+# %1 is a link to the addon submit page
+#~ msgid "devcp_summary_noaddons_submit_one"
+#~ msgstr "You don't have any add-ons. Click %s to submit one."
+
+#~ msgid "devcp_summary_noaddons_submit_one_link"
+#~ msgstr "here"
+
+# %1 is the link to the preview upload page
+#, fuzzy
+#~ msgid "devcp_theme_upload_preview"
+#~ msgstr "Please be sure to %s for your theme."
+
+#~ msgid "devcp_theme_upload_preview_link"
+#~ msgstr "upload a preview"
+
+#~ msgid "devcp_version_edit_pagetitle"
+#~ msgstr "Edit Version"
+
+#~ msgid "devcp_version_updated_successfully"
+#~ msgstr "Version updated successfully."
+
+#~ msgid "editors_submissiontype_new"
+#~ msgstr "New"
+
+#~ msgid "editors_submissiontype_updated"
+#~ msgstr "Updated"
+
+#, fuzzy
+#~ msgid "editors_th_addon_age"
+#~ msgstr "Addon Age"
+
+#~ msgid "editors_th_addontypes"
+#~ msgstr "Add-on Types"
+
+#~ msgid "editors_th_age"
+#~ msgstr "Age"
+
+#~ msgid "editors_th_applications"
+#~ msgstr "Applications"
+
+#~ msgid "editors_th_platforms"
+#~ msgstr "Platforms"
+
+#~ msgid "editors_th_submissiontypes"
+#~ msgstr "Submission Types"
+
+#~ msgid "error_notice"
+#~ msgstr "Notice"
+
+#~ msgid "forum_save"
+#~ msgstr "Kaydet"
+
+#, fuzzy
+#~ msgid "home"
+#~ msgstr "home"
+
+#, fuzzy
+#~ msgid "nav_category_plugins"
+#~ msgstr "Plugins"
+
+#, fuzzy
+#~ msgid "page_title_experimental_addons"
+#~ msgstr "Experimental Add-ons"
+
+#, fuzzy
+#~ msgid "pages_experimental_addons_backbutton"
+#~ msgstr "Back to the previous page"
+
+# %1 is page number, %2 is total page count
+#, fuzzy
+#~ msgid "pagination_page_number_title"
+#~ msgstr "This is page %1$s of %2$s"
+
+#, fuzzy
+#~ msgid "search_matching_addons_number"
+#~ msgid_plural "search_matching_addons_number"
+#~ msgstr[0] "%s matching add-on"
+#~ msgstr[1] "%s matching add-ons"
+
+#, fuzzy
+#~ msgid "statistics_rss_icon_title"
+#~ msgstr "RSS feed of summary data"
diff --git a/site/app/locale/uk/LC_MESSAGES/messages.mo b/site/app/locale/uk/LC_MESSAGES/messages.mo
new file mode 100644
index 0000000..53443ae
--- /dev/null
+++ b/site/app/locale/uk/LC_MESSAGES/messages.mo
Binary files differ
diff --git a/site/app/locale/uk/LC_MESSAGES/messages.po b/site/app/locale/uk/LC_MESSAGES/messages.po
new file mode 100644
index 0000000..e82842c
--- /dev/null
+++ b/site/app/locale/uk/LC_MESSAGES/messages.po
@@ -0,0 +1,8611 @@
+# Remora Preliminary Language File
+# Copyright (C) 2006 Mozilla Corporation
+# This file is distributed under the same license as the REMORA package.
+# Wil Clouser <clouserw@mozilla.com>, 2006.
+#
+# Timothy Babych <tim.babych@gmail.com>, 2007
+# Oleksandr Korytskyy <osk369@lycos.com>, 2007.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: REMORA 0.1\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2009-01-16 11:45-0800\n"
+"PO-Revision-Date: 2008-07-17 17:02+EET\n"
+"Last-Translator: Timothy Babych <tim.babych@gmail.com>\n"
+"Language-Team: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=n != 1;\n"
+
+#: views/addons/policy.thtml:98
+msgid "a_cancel_installation"
+msgstr "СкаÑувати вÑтановленнÑ"
+
+#. This is the text that appears on buttons to download add-ons.
+#. %$1s is an optional string that only appears if the add-on is only available for
+#. a certain platform. Examples: (Windows) or (Linux)
+#. Note that the parentheses are included in the string. :(
+#: views/elements/amo2009/install.thtml:126
+#: views/elements/amo2009/install.thtml:227
+#: views/elements/amo2009/install.thtml:257
+#: views/elements/amo2009/install.thtml:300
+#: views/elements/amo2009/install.thtml:312 views/elements/install.thtml:73
+#: views/elements/install.thtml:181 views/elements/install.thtml:205
+#: views/elements/install.thtml:248 views/elements/install.thtml:260
+#: views/addons/plugins.thtml:66 views/addons/plugins.thtml:76
+#: views/addons/plugins.thtml:86 views/addons/plugins.thtml:96
+#: views/addons/plugins.thtml:119
+#, php-format
+msgid "a_download"
+msgstr "Завантажити зараз %s"
+
+#: views/addons/policy.thtml:72
+msgid "a_eula_download"
+msgstr "ПрийнÑти Ñ– завантажити"
+
+#: views/addons/policy.thtml:74
+msgid "a_eula_install"
+msgstr "ПрийнÑти Ñ– вÑтановити"
+
+#: views/elements/header.thtml:76 views/elements/header.thtml:82
+#: views/api/api_addon.thtml:55 views/api/collections_feed.thtml:75
+#: views/sharing_api/addon.thtml:64
+msgid "a_header_public"
+msgstr "Публічний"
+
+#: views/elements/header.thtml:58 views/elements/header.thtml:75
+#: views/elements/header.thtml:80 views/api/api_addon.thtml:57
+#: views/api/collections_feed.thtml:77 views/sharing_api/addon.thtml:66
+msgid "a_header_sandbox"
+msgstr "ПіÑочницÑ"
+
+#. %s is a date in the _('date') format
+#: views/elements/amo2009/homepage_addon.thtml:115
+#: views/elements/addon_listitem.thtml:122 views/elements/feature.thtml:106
+#: views/addons/display.thtml:104 views/addons/browse_thumbs.thtml:73
+msgid "addon_detail_last_updated"
+msgstr "Оновлено %s"
+
+#. %s is the version of the add-on. Example: 3.2a1
+#: views/elements/amo2009/addon_version_detail.thtml:51
+#: views/elements/addon_version_detail.thtml:51
+#, php-format
+msgid "addon_display_header_version"
+msgstr "ВерÑÑ–Ñ %s"
+
+#: views/addons/browse_thumbs.thtml:80
+msgid "addon_downloads"
+msgstr "завантаженнÑ"
+
+#: views/addons/display.thtml:147
+msgid "addon_downloads_total"
+msgstr "вÑього завантажень"
+
+#: views/elements/amo2009/homepage_addon.thtml:106
+#: views/elements/addon_listitem.thtml:115 views/elements/feature.thtml:101
+#: views/addons/category_landing.thtml:157 views/addons/display.thtml:146
+#: views/addons/browse_thumbs.thtml:80
+msgid "addon_downloads_weekly"
+msgstr "завантажень на тижні"
+
+#. %1 is the add-on count, %2 the category name
+#: views/addons/browse_thumbs.thtml:104 views/addons/browse.thtml:60
+#, php-format
+msgid "addon_list_category_totalcount"
+msgid_plural "addon_list_category_totalcount"
+msgstr[0] "%1$s \"%2$s\" додаток"
+msgstr[1] "%1$s \"%2$s\" додатків"
+
+#: views/elements/amo2009/addon_list_options.thtml:103
+#: views/elements/pagination.thtml:67
+#: views/elements/addon_list_options.thtml:94
+msgid "addon_list_perpage"
+msgstr "на Ñторінку"
+
+#: views/elements/amo2009/addon_list_options.thtml:84
+#: views/elements/addon_list_options.thtml:98
+msgid "addon_list_sortby"
+msgstr "Сортувати за:"
+
+#: views/helpers/addons_html.php:568 views/elements/amo2009/install.thtml:321
+#: views/elements/feature.thtml:89
+msgid "addon_listitem_flag_experimental"
+msgstr "екÑпериментальний"
+
+#: views/helpers/addons_html.php:570
+msgid "addon_listitem_flag_recommended"
+msgstr "рекомендований"
+
+#. %1 is the add-on name, %2 is the platform
+#: views/pages/js_constants.js.thtml:66
+msgid "addon_not_available_for_platform"
+msgstr "%1$s недоÑтупний Ð´Ð»Ñ %2$s."
+
+#. %1 is the add-on name
+#: views/addons/policy.thtml:101 views/addons/previews.thtml:60
+#: views/addons/versions.thtml:130 views/reviews/flag.thtml:61
+#: views/reviews/add.thtml:114 views/reviews/display.thtml:216
+#: views/reviews/review_added.thtml:57
+#, php-format
+msgid "addon_review_a_back_to_addon_x"
+msgstr "Ðазад до %1$s…"
+
+#. %1 is the add-on name
+#: views/reviews/flag.thtml:60 views/reviews/add.thtml:113
+#: views/reviews/review_added.thtml:56
+#, php-format
+msgid "addon_review_a_back_to_reviews"
+msgstr "Ðазад до відгуків…"
+
+#: views/reviews/add.thtml:85
+msgid "addon_review_add_rating_field"
+msgstr "Рейтинг:"
+
+#: views/reviews/add.thtml:102
+msgid "addon_review_add_review_field"
+msgstr "Відгук:"
+
+#: views/reviews/add.thtml:107
+msgid "addon_review_add_submit"
+msgstr "ÐадіÑлати Ñвій відгук"
+
+#. %s is the name of the add-on
+#: views/reviews/add.thtml:51
+#, php-format
+msgid "addon_review_add_title"
+msgstr "Додати відгук Ð´Ð»Ñ %s"
+
+#: views/reviews/add.thtml:78
+msgid "addon_review_add_title_field"
+msgstr "Заголовок/ПідÑумок:"
+
+#: views/reviews/display.thtml:77 views/reviews/display.thtml:161
+msgid "addon_review_admin_delete"
+msgstr "Стерти"
+
+#: views/reviews/display.thtml:76
+msgid "addon_review_author_reply_link"
+msgstr "ВідповіÑти"
+
+#: views/reviews/delete.thtml:62
+msgid "addon_review_confirm_delete"
+msgstr "Ви впевнені, що хочете Ñтерти цей відгук?"
+
+#: views/reviews/delete.thtml:63
+msgid "addon_review_confirm_no"
+msgstr "ÐÑ–"
+
+#: views/reviews/delete.thtml:64
+msgid "addon_review_confirm_yes"
+msgstr "Так"
+
+#: views/reviews/delete.thtml:48
+msgid "addon_review_delete_header"
+msgstr "Стерти відгук"
+
+#: controllers/reviews_controller.php:449
+msgid "addon_review_deleted_successfully"
+msgstr "Відгук уÑпішно Ñтерто."
+
+#. %s is the name of the add-on
+#: views/reviews/add.thtml:51
+#, php-format
+msgid "addon_review_edit_title"
+msgstr "Редагувати відгук Ð´Ð»Ñ %s"
+
+#. %1 is the count of characters entered as notes for the review flag reason.
+#: controllers/reviews_controller.php:539
+msgid "addon_review_flag_error_other_length"
+msgstr ""
+"Проблема при помітці відгуку: текÑÑ‚ помітки має бути довжиною від 10 до 100 "
+"Ñимволів, а ваш має довжину %1$s Ñимволів."
+
+#. Removing an extra comma
+#: views/reviews/review_added.thtml:53
+msgid "addon_review_in_moderation"
+msgstr ""
+"Будь лаÑка, зауважте: перед тим, Ñк ваш відгук з’ÑвитьÑÑ Ð½Ð° публічному "
+"Ñайті, його буде модеровано редактором."
+
+#: views/reviews/add.thtml:57
+msgid "addon_review_in_reply_to"
+msgstr "Відповідь розробника на:"
+
+#. %1 is the review count, %2 is the nickname or full name of the user.
+#: views/reviews/display.thtml:131
+#, php-format
+msgid "addon_review_others_by_user"
+msgid_plural "addon_review_others_by_user"
+msgstr[0] "ПодивитиÑÑ %1$s попередній відгук про цей додаток, надіÑланий %2$s."
+msgstr[1] ""
+"ПодивитиÑÑ %1$s попередніх відгуків про цей додаток, надіÑланих %2$s."
+
+#. %1 is the add-on name
+#: controllers/reviews_controller.php:201
+#: controllers/reviews_controller.php:250
+#: controllers/reviews_controller.php:345
+#: controllers/reviews_controller.php:424
+#, php-format
+msgid "addon_review_pagetitle"
+msgstr "Відгук Ð´Ð»Ñ %s"
+
+#. %1 is the user, %2 is the (localized) date
+#: views/reviews/display.thtml:160
+#, php-format
+msgid "addon_review_reply_on_x_by_y"
+msgstr "Відповідь %1$s на %2$s"
+
+#: views/reviews/display.thtml:157
+msgid "addon_review_reply_prefix"
+msgstr "Відповідь розробника:"
+
+#: views/reviews/review_added.thtml:51
+msgid "addon_review_saved_successfully"
+msgstr "Ваш відгук збережено вдало. ДÑкуємо!"
+
+#: views/addons/display.thtml:354 views/reviews/display.thtml:72
+msgid "addon_reviewed_by_u_on_d"
+msgstr "оглÑнено %1$s %2$s"
+
+#. %1 is the user, %2 is the (localized) date, %3 is the rating
+#: views/editors/reviews_queue.thtml:57 views/editors/reviews_queue.thtml:68
+#: views/reviews/add.thtml:63 views/reviews/delete.thtml:54
+#, php-format
+msgid "addon_reviewed_on_x_rated_y"
+msgstr "%1$s %2$s (рейтинг %3$s)"
+
+#: views/elements/amo2009/addon_version_detail.thtml:52
+#: views/elements/addon_version_detail.thtml:52
+msgid "addon_version_permalink"
+msgstr "ПоÑтійне поÑÐ¸Ð»Ð°Ð½Ð½Ñ Ð½Ð° цю верÑÑ–ÑŽ"
+
+#. %1 is the current Application name (e.g. Firefox)
+#. %2 is the Application's version number
+#: views/addons/versions.thtml:140
+msgid "addon_versions_getlatestversion"
+msgstr "Ðайновіша верÑÑ–Ñ, ÑуміÑна з %1$s %2$s"
+
+#: views/addons/display.thtml:447
+msgid "addons_author_addons_submit"
+msgstr "ЗаÑлати"
+
+#: views/elements/amo2009/homepage_addon.thtml:100
+#: views/elements/feature.thtml:95
+msgid "addons_author_tooltip"
+msgstr "ПереглÑнути профіль автора"
+
+#. %1 is the name of the Application (eg. Firefox)
+#: controllers/addons_controller.php:1296
+msgid "addons_browse_all_themes_title"
+msgstr "ПереглÑд уÑÑ–Ñ… тем :: Додатки до %1$s"
+
+#. %s is the name of the category
+#: controllers/addons_controller.php:1016
+#, php-format
+msgid "addons_browse_browse_category"
+msgstr "ПереглÑнути %s"
+
+#. %1 is the name of the theme category (eg. Modern)
+#. %2 is the name of the Application (eg. Firefox)
+#: controllers/addons_controller.php:664
+msgid "addons_browse_categories_header_theme"
+msgstr "ПереглÑд тем — %1$s :: Додатки до %2$s"
+
+#: views/addons/display.thtml:249
+#, fuzzy
+msgid "addons_display_a_license_what"
+msgstr "What's this?"
+
+#: views/reviews/display.thtml:222
+msgid "addons_display_add_review"
+msgstr "Додати відгук"
+
+#: views/addons/display.thtml:294
+msgid "addons_display_advanced_details"
+msgstr "Додаткові подробиці"
+
+#: views/addons/display.thtml:98
+msgid "addons_display_categories"
+msgstr "Категорії"
+
+#: views/addons/display.thtml:482
+#, fuzzy
+msgid "addons_display_collection_add"
+msgstr "Add to a collection:"
+
+#: views/addons/display.thtml:491
+#, fuzzy
+msgid "addons_display_collection_add_new"
+msgstr "New Collection..."
+
+#: views/addons/display.thtml:487
+#, fuzzy
+msgid "addons_display_collection_add_select_one"
+msgstr "Select a collection..."
+
+#: views/addons/display.thtml:493
+#, fuzzy
+msgid "addons_display_collection_add_submit"
+msgstr "Publish"
+
+#. %1$s is the add-on name
+#. %2$s is the collection name, linked to the collection's page
+#: views/pages/js_constants.js.thtml:103 views/addons/display.thtml:61
+#, fuzzy
+msgid "addons_display_collection_publish_success"
+msgstr "%1$s has been added to the %2$s collection."
+
+#: views/addons/display.thtml:483
+#, fuzzy
+msgid "addons_display_collection_whatsthis"
+msgstr "What's this?"
+
+#. %1$s is a number
+#: views/addons/display.thtml:473
+#, fuzzy
+msgid "addons_display_collections_more"
+msgid_plural "addons_display_collections_more"
+msgstr[0] "and %1$s more collection"
+msgstr[1] "and %1$s more collections"
+
+#: views/addons/display.thtml:403
+msgid "addons_display_detailed_review"
+msgstr "детальний оглÑд"
+
+#: views/reviews/add.thtml:89 views/reviews/add.thtml:90
+msgid "addons_display_dont_like_it"
+msgstr "Ðе ÑподобалоÑÑŒ"
+
+#: views/reviews/display.thtml:220
+msgid "addons_display_edit_review"
+msgstr "Редагувати Ñвій відгук"
+
+#: views/addons/display.thtml:132
+msgid "addons_display_has_privacy"
+msgstr "У цього додатку Ñ” умови конфіденційноÑÑ‚Ñ–."
+
+#: views/reviews/add.thtml:87 views/reviews/add.thtml:88
+msgid "addons_display_hate_it"
+msgstr "Ðенавиджу"
+
+#: views/addons/display.thtml:462
+#, fuzzy
+msgid "addons_display_header_collections"
+msgstr "Related Collections"
+
+#: views/addons/display.thtml:297
+msgid "addons_display_header_developer_comments"
+msgstr "Коментарі розробника"
+
+#: views/addons/display.thtml:230
+msgid "addons_display_header_homepage"
+msgstr "Початкова"
+
+#: views/addons/display.thtml:247 views/addons/versions.thtml:110
+#, fuzzy
+msgid "addons_display_header_license"
+msgstr "Source Code License"
+
+#: views/addons/display.thtml:337
+msgid "addons_display_header_reviews"
+msgstr "Відгуки"
+
+#: views/addons/display.thtml:261
+msgid "addons_display_header_support"
+msgstr "Підтримка"
+
+#: views/reviews/add.thtml:91 views/reviews/add.thtml:92
+msgid "addons_display_like_it"
+msgstr "СподобалоÑÑŒ"
+
+#: views/addons/display.thtml:210
+msgid "addons_display_long_description"
+msgstr "Докладний опиÑ"
+
+#: views/reviews/add.thtml:95 views/reviews/add.thtml:96
+msgid "addons_display_love_it"
+msgstr "Обожнюю"
+
+#: views/addons/display.thtml:178
+msgid "addons_display_more_images"
+msgstr "Додаткові зображеннÑ"
+
+#: views/addons/display.thtml:465
+#, fuzzy
+msgid "addons_display_nocollections"
+msgstr "This add-on is not yet in any collections."
+
+#. %1$s is either an author's name or a comma separated list of authors. Using
+#. the list doesn't make sense in the English plural form so we ignore the
+#. variable.
+#: views/addons/display.thtml:436
+msgid "addons_display_other_addons_by"
+msgid_plural "addons_display_other_addons_by"
+msgstr[0] "Інші додатки від %1$s"
+msgstr[1] "Інші додатки від цих авторів"
+
+#. %s is the name of the add-on and the add-on section. Example:
+#. Some Add-on :: Firefox Add-ons
+#. This should not be concatenated in the code and should be fixed.
+#: controllers/addons_controller.php:141 controllers/addons_controller.php:280
+#: controllers/addons_controller.php:1442
+#, php-format
+msgid "addons_display_pagetitle"
+msgstr "%s"
+
+#. %s is an email address
+#: views/addons/display.thtml:286
+#, php-format
+msgid "addons_display_paragraph_supportinfoemail"
+msgstr ""
+"Ви можете отримати підтримку ÑтоÑовно цього Ð Ð¾Ð·ÑˆÐ¸Ñ€ÐµÐ½Ð½Ñ Ð²Ñ–Ð´ %s. Якщо ви "
+"хочете повідомити про ваду то можливо варто зв’ÑзатиÑÑŒ з розробником щоб "
+"детальніше у вÑьому розібратиÑÑŒ. відгуки не призначені Ð´Ð»Ñ Ð´ÐµÑ‚Ð°Ð»ÑŒÐ½Ð¸Ñ… "
+"повідомлень про помилки, а розробнику можуть знадобитиÑÑŒ додаткові подробиці "
+"щоб відтворити проблему. ОÑкільки ми не розголошуємо ваш емейл навіть "
+"розробникам котрими ви пиÑали відгуки, вони не зможуть перепитати Ð²Ð°Ñ Ð°Ð±Ð¾ "
+"ÑповіÑтити про те що ваду було виправлено."
+
+#. %$1s is a URL
+#. %$2s is an email address
+#: views/addons/display.thtml:269
+#, php-format
+msgid "addons_display_paragraph_supportinfoemailurl"
+msgstr ""
+"Ви можете отримати підтримку ÑтоÑовно цього Ð Ð¾Ð·ÑˆÐ¸Ñ€ÐµÐ½Ð½Ñ Ð²Ñ–Ð´ %s або на %s. "
+"Якщо ви хочете повідомити про ваду то можливо варто зв’ÑзатиÑÑŒ з розробником "
+"щоб детальніше у вÑьому розібратиÑÑŒ. відгуки не призначені Ð´Ð»Ñ Ð´ÐµÑ‚Ð°Ð»ÑŒÐ½Ð¸Ñ… "
+"повідомлень про помилки, а розробнику можуть знадобитиÑÑŒ додаткові подробиці "
+"щоб відтворити проблему. ОÑкільки ми не розголошуємо ваш емейл навіть "
+"розробникам котрими ви пиÑали відгуки, вони не зможуть перепитати Ð²Ð°Ñ Ð°Ð±Ð¾ "
+"ÑповіÑтити про те що ваду було виправлено."
+
+#. %s is a URL
+#: views/addons/display.thtml:278
+#, php-format
+msgid "addons_display_paragraph_supportinfourl"
+msgstr ""
+"Ви можете отримати підтримку ÑтоÑовно цього Ð Ð¾Ð·ÑˆÐ¸Ñ€ÐµÐ½Ð½Ñ Ð½Ð° %s. Якщо ви хочете "
+"повідомити про ваду то можливо варто зв’ÑзатиÑÑŒ з розробником щоб детальніше "
+"у вÑьому розібратиÑÑŒ. відгуки не призначені Ð´Ð»Ñ Ð´ÐµÑ‚Ð°Ð»ÑŒÐ½Ð¸Ñ… повідомлень про "
+"помилки, а розробнику можуть знадобитиÑÑŒ додаткові подробиці щоб відтворити "
+"проблему. ОÑкільки ми не розголошуємо ваш емейл навіть розробникам котрими "
+"ви пиÑали відгуки, вони не зможуть перепитати Ð²Ð°Ñ Ð°Ð±Ð¾ ÑповіÑтити про те що "
+"ваду було виправлено."
+
+#: views/addons/display.thtml:383
+msgid "addons_display_rate_it"
+msgstr "Оцінка"
+
+#: views/reviews/add.thtml:93 views/reviews/add.thtml:94
+msgid "addons_display_really_like_it"
+msgstr "ДійÑно ÑподобалоÑÑŒ"
+
+#: views/addons/display.thtml:410
+msgid "addons_display_review_etiquette"
+msgstr ""
+"Будь лаÑка не надÑилайте Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð¿Ñ€Ð¾ помилки у відгуках. Ми не "
+"розголошуємо ваш емейл, а розробникам може бути потрібно зв’ÑзатиÑÑŒ з вами "
+"щоб допомогти."
+
+#. %1 is the review guidelines link
+#: views/addons/display.thtml:417
+msgid "addons_display_review_guidelines_link"
+msgstr "<a href=\"%s\">Поради щодо оцінюваннÑ</a>"
+
+#. %1 is the support section link
+#: views/addons/display.thtml:414
+msgid "addons_display_review_see_support"
+msgstr ""
+"Завітайте у <a href=\"%1$s\">розділ підтримки</a> щоб дізнатиÑÑŒ де ви "
+"зможете отримати допомогу ÑтоÑовно цього додатку."
+
+#: views/addons/display.thtml:404
+msgid "addons_display_review_submit"
+msgstr "Зберегти"
+
+#: views/addons/display.thtml:430
+#, php-format
+msgid "addons_display_see_all_addons"
+msgstr "ПереглÑнути вÑÑ– додатки %1$s"
+
+#. %1 is the number of reviews
+#: views/addons/display.thtml:364
+#, php-format
+msgid "addons_display_see_all_reviews"
+msgstr "ДивитиÑÑ Ð²ÑÑ– відгуки (%1$s)"
+
+#: views/addons/display.thtml:219
+msgid "addons_display_see_all_versions"
+msgstr "Показати вÑÑ– верÑÑ–Ñ—"
+
+#: views/addons/display.thtml:321 views/addons/versions.thtml:117
+msgid "addons_display_view_source"
+msgstr "ПереглÑнути джерело"
+
+#: views/addons/display.thtml:324
+msgid "addons_display_view_stats"
+msgstr "ПереглÑнути ÑтатиÑтику"
+
+#: views/addons/display.thtml:376
+msgid "addons_display_what_do_you_think"
+msgstr "Що Ñкажете?"
+
+#: views/elements/app_compatibility.thtml:49
+msgid "addons_display_workswith"
+msgstr "Працює з:"
+
+#: views/addons/home.thtml:112
+#, fuzzy
+msgid "addons_home_browse_new"
+msgstr "Just Added"
+
+#: views/addons/home.thtml:110
+#, fuzzy
+msgid "addons_home_browse_popular"
+msgstr "Popular"
+
+#: views/addons/home.thtml:108
+#, fuzzy
+msgid "addons_home_browse_recommended"
+msgstr "Recommended"
+
+#: views/addons/home.thtml:127 views/addons/home.thtml:134
+#: views/addons/home.thtml:141 views/addons/home.thtml:148
+#, fuzzy
+msgid "addons_home_browse_subscribe"
+msgstr "Subscribe"
+
+#: views/addons/home.thtml:101
+#, fuzzy
+msgid "addons_home_browse_title"
+msgstr "Browse Add-ons"
+
+#: views/addons/home.thtml:114
+#, fuzzy
+msgid "addons_home_browse_updated"
+msgstr "Updated"
+
+#: views/elements/amo2009/homepage_addon.thtml:100
+#: views/elements/addon_discussionheader.thtml:83
+#: views/elements/addon_listitem.thtml:109 views/elements/feature.thtml:95
+#: views/addons/category_landing.thtml:66 views/addons/policy.thtml:57
+#: views/addons/display.thtml:70 views/addons/home.thtml:178
+msgid "addons_home_by"
+msgstr "від"
+
+#: views/addons/home.thtml:169
+#, fuzzy
+msgid "addons_home_collection_popular_title"
+msgstr "Popular Collections"
+
+#: views/elements/amo2009/categories.thtml:69 views/addons/home.thtml:160
+#, fuzzy
+msgid "addons_home_collections"
+msgstr "Collections"
+
+#. %1$s is the count of addons in a collection
+#: views/elements/amo2009/collection_listing_item.thtml:51
+#: views/addons/home.thtml:185
+#, fuzzy
+msgid "addons_home_collections_addon_count"
+msgid_plural "addons_home_collections_addon_count"
+msgstr[0] "<strong>%1$s</strong> add-on"
+msgstr[1] "<strong>%1$s</strong> add-ons"
+
+#: views/addons/home.thtml:196
+#, fuzzy
+msgid "addons_home_collections_all"
+msgstr "View All Collections"
+
+#: views/addons/home.thtml:162
+#, fuzzy
+msgid "addons_home_collections_intro"
+msgstr ""
+"Collections are a way for you to categorize, mix, match and mingle add-ons. "
+"Subscribe to collections created by other users or create your own."
+
+#. %1$s is the count of subscribers for a collection
+#: views/elements/amo2009/collection_listing_item.thtml:58
+#: views/collections/detail.thtml:96 views/addons/home.thtml:189
+#, fuzzy
+msgid "addons_home_collections_subscribers"
+msgid_plural "addons_home_collections_subscribers"
+msgstr[0] "<strong>%1$s</strong> subscriber"
+msgstr[1] "<strong>%1$s</strong> subscribers"
+
+#: views/addons/searchengines.thtml:54 views/addons/themes_landing.thtml:49
+msgid "addons_home_feature_head"
+msgstr "Ми рекомендуємо"
+
+#: controllers/search_controller.php:218 controllers/addons_controller.php:176
+#: controllers/addons_controller.php:428 controllers/addons_controller.php:671
+#: controllers/addons_controller.php:871
+#: controllers/addons_controller.php:1103
+#: controllers/addons_controller.php:1242
+#: controllers/addons_controller.php:1298
+#, php-format
+msgid "addons_home_header_details"
+msgstr ""
+"Додатки розширюють можливоÑÑ‚Ñ– %1$s, роблÑÑ‚ÑŒ подорожі мережею більш "
+"комфортними. ОзирнітьÑÑ Ð½Ð°Ð²ÐºÐ¾Ð»Ð¾ та зробіть %1$s таким, Ñким його хочете "
+"бачити оÑобиÑто ви."
+
+#. %1$s is the HTML collection name link.
+#: views/elements/amo2009/teaser_collections.thtml:107
+#, fuzzy
+msgid "addons_home_introduction_collection_link"
+msgstr "Like these? Find more add-ons in %1$s."
+
+#: views/elements/amo2009/teaser_collections.thtml:60
+#, fuzzy
+msgid "addons_home_introduction_extras"
+msgstr ""
+"<strong>Over 5000 free extras</strong> that let you customize and extend "
+"Firefox to meet your needs."
+
+#: views/elements/amo2009/teaser_collections.thtml:55
+#, fuzzy
+msgid "addons_home_introduction_header"
+msgstr "What are Add-ons?"
+
+#: views/elements/amo2009/teaser_collections.thtml:72
+#, fuzzy
+msgid "addons_home_introduction_install"
+msgstr ""
+"<strong>Easy to install</strong>, get notified when updates are available."
+
+#: views/elements/amo2009/teaser_collections.thtml:45
+#, fuzzy
+msgid "addons_home_introduction_name"
+msgstr "Introduction"
+
+#: views/elements/amo2009/teaser_collections.thtml:66
+#, fuzzy
+msgid "addons_home_introduction_themes"
+msgstr ""
+"Toolbars, themes and search providers that <strong>help you perform common "
+"tasks.</strong>"
+
+#: views/addons/home.thtml:161
+#, fuzzy
+msgid "addons_home_new_indicator"
+msgstr "NEW!"
+
+#: views/elements/app_chooser.thtml:48 views/layouts/amo2009.thtml:257
+msgid "addons_home_other_applications"
+msgstr "Інші програми"
+
+#. %1$s is the application the user is browsing. Examples: Thunderbird, Firefox,
+#. Sunbird
+#: views/pages/collector_faq.thtml:49 views/pages/collector_firstrun.thtml:42
+#: views/pages/collector.thtml:46 views/pages/collector_features.thtml:54
+#: controllers/developers_controller.php:87
+#: controllers/compatibility_controller.php:72
+#: controllers/components/simple_acl.php:81 controllers/components/amo.php:607
+#: controllers/statistics_controller.php:60
+#: controllers/statistics_controller.php:240
+#: controllers/previews_controller.php:67 controllers/users_controller.php:90
+#: controllers/users_controller.php:223 controllers/users_controller.php:330
+#: controllers/users_controller.php:414 controllers/users_controller.php:708
+#: controllers/users_controller.php:723 controllers/reviews_controller.php:204
+#: controllers/reviews_controller.php:251
+#: controllers/reviews_controller.php:346
+#: controllers/reviews_controller.php:425
+#: controllers/search_controller.php:185 controllers/search_controller.php:297
+#: controllers/search_controller.php:301 controllers/addons_controller.php:147
+#: controllers/addons_controller.php:280 controllers/addons_controller.php:370
+#: controllers/addons_controller.php:667 controllers/addons_controller.php:874
+#: controllers/addons_controller.php:1019
+#: controllers/addons_controller.php:1034
+#: controllers/addons_controller.php:1101
+#: controllers/addons_controller.php:1121
+#: controllers/addons_controller.php:1240
+#: controllers/addons_controller.php:1357
+#: controllers/addons_controller.php:1364
+#: controllers/addons_controller.php:1442
+#: controllers/addons_controller.php:1477
+#: controllers/addons_controller.php:1538
+#: controllers/addons_controller.php:1543
+#: controllers/editors_controller.php:64 controllers/pages_controller.php:132
+#: controllers/groups_controller.php:65 controllers/groups_controller.php:71
+#: controllers/groups_controller.php:89 controllers/groups_controller.php:111
+#: controllers/collections_controller.php:57
+#: controllers/collections_controller.php:121
+#: controllers/collections_controller.php:205
+#: controllers/collections_controller.php:365
+#: controllers/collections_controller.php:404
+#: controllers/collections_controller.php:466
+#: controllers/collections_controller.php:538
+#: controllers/collections_controller.php:828
+#: controllers/localizers_controller.php:72
+#, php-format
+msgid "addons_home_pagetitle"
+msgstr "Додатки %1$s"
+
+#. %1$s is the number of addons downloaded
+#: views/addons/home.thtml:57
+#, fuzzy, php-format
+msgid "addons_home_stats_downloaded"
+msgid_plural "addons_home_stats_downloaded"
+msgstr[0] "<strong>%1$s</strong> <span>add-on downloaded</span>"
+msgstr[1] "<strong>%1$s</strong> <span>add-ons downloaded</span>"
+
+#. %1$s is the number of addons in use
+#: views/addons/home.thtml:63
+#, fuzzy, php-format
+msgid "addons_home_stats_inuse"
+msgid_plural "addons_home_stats_inuse"
+msgstr[0] "<strong>%1$s</strong> <span>add-on in use</span>"
+msgstr[1] "<strong>%1$s</strong> <span>add-ons in use</span>"
+
+#: views/addons/home.thtml:136
+msgid "addons_home_view_all_newest_title"
+msgstr "ПереглÑнути вÑÑ– недавно Ñтворені додатки"
+
+#: views/addons/home.thtml:129
+msgid "addons_home_view_all_popular_title"
+msgstr "ПереглÑнути вÑÑ– популÑрні додатки"
+
+#: views/addons/home.thtml:150
+msgid "addons_home_view_all_recommended_title"
+msgstr "ПереглÑнути вÑÑ– рекомендовані додатки"
+
+#: views/addons/home.thtml:143
+msgid "addons_home_view_all_updated_title"
+msgstr "ПереглÑнути вÑÑ– недавно оновлені додатки"
+
+#: views/elements/amo2009/install.thtml:334 views/elements/install.thtml:112
+msgid "addons_install_in_sunbird"
+msgstr ""
+"<ol><li>Ð”Ð»Ñ Ñ‚Ð¾Ð³Ð¾ щоб зберегти файл, натиÑніть на поÑиланні нижче.</li><li>У "
+"Mozilla Sunbird, відкрийте Додатки з меню ІнÑтрументи.</li><li>ÐатиÑніть "
+"кнопку Ð’Ñтановити, виберіть завантажений вами файл та натиÑніть \"OK\".</"
+"li></ol>"
+
+#: views/elements/amo2009/install.thtml:333 views/elements/install.thtml:111
+msgid "addons_install_in_sunbird_title"
+msgstr "Як вÑтановлювати у Sunbird"
+
+#: views/elements/amo2009/install.thtml:331 views/elements/install.thtml:106
+msgid "addons_install_in_thunderbird"
+msgstr ""
+"<ol><li>Клацніть правою клавішею мишки на поÑиланні нижче Ñ– оберіть "
+"\"Зберегти Ñк…\" Ð´Ð»Ñ Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ Ñ– Ð·Ð±ÐµÑ€ÐµÐ¶ÐµÐ½Ð½Ñ Ñ„Ð°Ð¹Ð»Ñƒ на Ñвій диÑк.</li><li>У "
+"Mozilla Thunderbird, відкрийте додатки у меню ІнÑтрументи.</li><li>Клікніть "
+"на кнопці Ð’Ñтановити, знайдіть/оберіть файл, Ñкий ви завантажили Ñ– клацніть "
+"\"Гаразд\".</li></ol>"
+
+#: views/elements/amo2009/install.thtml:330 views/elements/install.thtml:105
+msgid "addons_install_in_thunderbird_title"
+msgstr "Як вÑтановлювати у Thunderbird"
+
+#: views/elements/amo2009/addon_list_options.thtml:108
+#: views/elements/addon_list_options.thtml:105
+msgid "addons_options_show_experimental"
+msgstr "показувати екÑпериментальні додатки"
+
+#: views/elements/amo2009/addon_list_options.thtml:113
+#: views/elements/addon_list_options.thtml:109
+msgid "addons_options_submit"
+msgstr "Перейти"
+
+#: views/addons/plugins.thtml:63 views/addons/plugins.thtml:73
+#: views/addons/plugins.thtml:83 views/addons/plugins.thtml:93
+#: views/addons/plugins.thtml:103 views/addons/plugins.thtml:116
+#: views/addons/plugins.thtml:126
+msgid "addons_plugins_by"
+msgstr "Від"
+
+#: views/addons/plugins.thtml:107
+msgid "addons_plugins_for_linux"
+msgstr "Ð´Ð»Ñ Linux"
+
+#: views/addons/plugins.thtml:108 views/addons/plugins.thtml:131
+msgid "addons_plugins_for_macosx"
+msgstr "Ð´Ð»Ñ Mac OS X"
+
+#: views/addons/plugins.thtml:106 views/addons/plugins.thtml:129
+#: views/addons/plugins.thtml:130
+msgid "addons_plugins_for_windows"
+msgstr "Ð´Ð»Ñ Windows"
+
+#. %1$s is a URL
+#: views/addons/plugins.thtml:139
+#, php-format
+msgid "addons_plugins_looking_for_more"
+msgstr ""
+"Ð¦Ñ Ñторінка дає перелік лише найпоширеніших та найпопулÑрніших модулів. Ð”Ð»Ñ "
+"подальшої інформації щодо інших модулів, доÑтупних Ð´Ð»Ñ Ð±Ñ€Ð°ÑƒÐ·ÐµÑ€Ñ–Ð² на оÑнові "
+"Mozilla, відвідайте %1$s"
+
+#: views/addons/plugins.thtml:137
+msgid "addons_plugins_looking_for_plugin"
+msgstr "Шукаєте модуль, не зазначений тут?"
+
+#: views/addons/plugins.thtml:58
+msgid "addons_plugins_main_description"
+msgstr ""
+"Модулі допомагають вашому браузеру виконувати окремі функції, такі Ñк "
+"переглÑд оÑобливих графічних форматів або Ð²Ñ–Ð´Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ð¼ÑƒÐ»ÑŒÑ‚Ð¸Ð¼ÐµÐ´Ñ–Ð¹Ð½Ð¸Ñ… файлів. "
+"Модулі трохи відрізнÑÑŽÑ‚ÑŒÑÑ Ð²Ñ–Ð´ розширень, Ñкі модифікують або додаютьÑÑ Ð´Ð¾ "
+"Ñ–Ñнуючої функціональноÑÑ‚Ñ–."
+
+#. %1$s is the application name. Example: Firefox, Thunderbird, Sunbird
+#: controllers/addons_controller.php:1122
+#, php-format
+msgid "addons_plugins_main_header"
+msgstr "Поширені модулі Ð´Ð»Ñ %1$s"
+
+#: controllers/components/amo.php:698 controllers/addons_controller.php:1121
+msgid "addons_plugins_pagetitle"
+msgstr "Модулі"
+
+#: views/addons/plugins.thtml:68 views/addons/plugins.thtml:78
+#: views/addons/plugins.thtml:88 views/addons/plugins.thtml:98
+#: views/addons/plugins.thtml:110 views/addons/plugins.thtml:121
+#: views/addons/plugins.thtml:133
+msgid "addons_plugins_support_documentation"
+msgstr "ДокументаціÑ: "
+
+#. %s is the name of the add-on
+#: views/addons/policy.thtml:61
+#, php-format
+msgid "addons_policy_eula_require"
+msgstr ""
+"%s потребує, щоб ви прийнÑли наÑтупну Ліцензійну угоду з кінцевим "
+"кориÑтувачем перед продовженнÑм вÑтановленнÑ:"
+
+#. %1 is the add-on name
+#: controllers/addons_controller.php:1476
+#, php-format
+msgid "addons_previews_pagetitle"
+msgstr "Знімки екрану Ð´Ð»Ñ %s"
+
+#: views/addons/category_landing.thtml:135
+#, fuzzy
+msgid "addons_recently_added"
+msgstr "Recently Added"
+
+#: views/addons/recommended.thtml:51 controllers/addons_controller.php:1365
+msgid "addons_recommended_introduction"
+msgstr ""
+"З такою кількіÑÑ‚ÑŽ наÑвних додатків кожен може знайти Ñобі щоÑÑŒ цікаве. "
+"Почніть з переліку найпопулÑрніших. ÐаÑолоджуйтеÑÑŒ!"
+
+#: controllers/addons_controller.php:1357
+#: controllers/addons_controller.php:1364
+msgid "addons_recommended_pagetitle"
+msgstr "Рекомендовані додатки"
+
+#: controllers/addons_controller.php:1360
+msgid "addons_recommended_title"
+msgstr "Рекомендовані додатки"
+
+#: views/addons/searchengines.thtml:136
+msgid "addons_searchengines_additional_resources"
+msgstr "Додаткові реÑурÑи"
+
+#. link text devmo
+#: views/addons/searchengines.thtml:141
+msgid "addons_searchengines_devmo_link"
+msgstr "Центр розробників Mozilla"
+
+#: views/pages/js_constants.js.thtml:67
+msgid "addons_searchengines_error_mozilla_browser_required"
+msgstr ""
+"Вибачте, але вам потрібно мати браузер на оÑнові Mozilla (Ñк Firefox) Ð´Ð»Ñ "
+"вÑÑ‚Ð°Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ð¼Ð¾Ð´ÑƒÐ»Ñ Ð¿Ð¾ÑˆÑƒÐºÑƒ."
+
+#: views/addons/searchengines.thtml:49
+msgid "addons_searchengines_error_nojavascript"
+msgstr ""
+"JavaScript потрібен Ð´Ð»Ñ Ð²ÑÑ‚Ð°Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ð¼Ð¾Ð´ÑƒÐ»Ñ–Ð², але, здаєтьÑÑ, ви його "
+"відключили. Будь лаÑка, включіть JavaScript перед Ñпробою вÑтановити будь-"
+"Ñкий з модулів пошуку нижче."
+
+#. %1 is "make your own" link
+#. %2 is MDC link
+#: views/addons/searchengines.thtml:139
+msgid "addons_searchengines_learn_howto"
+msgstr "ДізнайтеÑÑŒ Ñк %1$s на %2$s."
+
+#. link path to search plugins instructions, relative to devmo
+#: views/addons/searchengines.thtml:140
+msgid "addons_searchengines_makeyourown_href"
+msgstr "/en/docs/Creating_OpenSearch_plugins_for_Firefox"
+
+#. link text for "make your own" (opensearch engine)
+#: views/addons/searchengines.thtml:140
+msgid "addons_searchengines_makeyourown_link"
+msgstr "Ñтворіть Ñвій"
+
+#. %1 is the link to mycroft.mozdev.org
+#: views/addons/searchengines.thtml:138
+msgid "addons_searchengines_more"
+msgstr "ПереглÑнути заÑоби пошуку на %1$s"
+
+#. link text to mycroft.mozdev.org
+#: views/addons/searchengines.thtml:138
+msgid "addons_searchengines_mycroft_link"
+msgstr "mycroft.mozdev.org"
+
+#: controllers/addons_controller.php:1100
+#: controllers/addons_controller.php:1110
+msgid "addons_searchengines_pagetitle"
+msgstr "ЗаÑоби пошуку"
+
+#: views/addons/searchengines.thtml:143
+msgid "addons_searchengines_thanks"
+msgstr ""
+"ОÑоблива подÑка проекту Mycroft за Ñ—Ñ… роботу над заÑобами пошуку Firefox"
+
+#: views/addons/display.thtml:154
+msgid "addons_share_button_text"
+msgstr "ПоділитиÑÑ"
+
+#: controllers/addons_controller.php:89
+msgid "addons_share_label_delicious"
+msgstr "Додати до Delicious"
+
+#: controllers/addons_controller.php:77
+msgid "addons_share_label_digg"
+msgstr "ÐадіÑлати до Digg"
+
+#: controllers/addons_controller.php:83
+msgid "addons_share_label_facebook"
+msgstr "ÐадіÑлати на Facebook"
+
+#: controllers/addons_controller.php:101
+msgid "addons_share_label_friendfeed"
+msgstr "ПоділитиÑÑ Ð· друзÑми на FriendFeed"
+
+#: controllers/addons_controller.php:95
+msgid "addons_share_label_myspace"
+msgstr "ÐадіÑлати до MySpace"
+
+#: controllers/components/amo.php:201 controllers/components/amo.php:229
+msgid "addons_status_disabled"
+msgstr "Вимкнено"
+
+#: controllers/components/amo.php:191 controllers/components/amo.php:224
+msgid "addons_status_incomplete"
+msgstr "Ðеповна верÑÑ–Ñ"
+
+#: controllers/components/amo.php:197 controllers/components/amo.php:227
+msgid "addons_status_nominated"
+msgstr "У піÑочниці; кандидат у загальнодоÑтупні"
+
+#: views/pages/js_constants.js.thtml:80 controllers/components/amo.php:195
+#: controllers/components/amo.php:226
+msgid "addons_status_pending"
+msgstr "У піÑочниці; очікує на відгук"
+
+#: views/pages/js_constants.js.thtml:78 controllers/components/amo.php:199
+#: controllers/components/amo.php:228
+msgid "addons_status_public"
+msgstr "ЗагальнодоÑтупний"
+
+#: views/pages/js_constants.js.thtml:79 controllers/components/amo.php:193
+#: controllers/components/amo.php:225
+msgid "addons_status_sandbox"
+msgstr "У піÑочниці"
+
+#: controllers/components/amo.php:203
+msgid "addons_status_unknown"
+msgstr "Ðевідомо"
+
+#: views/elements/amo2009/teaser_collections.thtml:91
+#: views/elements/amo2009/homepage_addon.thtml:99
+#: views/elements/feature.thtml:94
+msgid "addons_title_tooltip"
+msgstr "ДізнайтеÑÑŒ більше про цей додаток"
+
+#: views/addons/category_landing.thtml:151
+#, fuzzy
+msgid "addons_top_downloads"
+msgstr "Top Downloads"
+
+#: views/addons/category_landing.thtml:165
+#, fuzzy
+msgid "addons_top_rated"
+msgstr "Top Rated"
+
+#: views/addons/versions.thtml:62
+msgid "addons_versions_careful"
+msgstr "Будьте обережні з Ñтарими верÑÑ–Ñми"
+
+#: views/addons/versions.thtml:63
+msgid "addons_versions_careful_introduction"
+msgstr ""
+"Ці верÑÑ–Ñ— показані з метою поÑÐ¸Ð»Ð°Ð½Ð½Ñ Ñ– випробуваннÑ. Ви повинні завжди "
+"викориÑтовувати найоÑтаннішу верÑÑ–ÑŽ додатку."
+
+#: controllers/addons_controller.php:1549
+msgid "addons_versions_history"
+msgstr "ІÑÑ‚Ð¾Ñ€Ñ–Ñ Ð²ÐµÑ€Ñій із протоколом змін"
+
+#. %1$s is the add-on name
+#: controllers/addons_controller.php:1535
+#, php-format
+msgid "addons_versions_pagetitle"
+msgstr "ІÑÑ‚Ð¾Ñ€Ñ–Ñ Ð²ÐµÑ€Ñій %1$s"
+
+#: controllers/groups_controller.php:71
+msgid "admin_group_add_pagetitle"
+msgstr "Додати групу"
+
+#: controllers/groups_controller.php:111
+msgid "admin_group_delete_pagetitle"
+msgstr "Стерти групу"
+
+#. %s is a number to identify the group
+#: controllers/groups_controller.php:117
+#, php-format
+msgid "admin_group_deleted"
+msgstr "Група з ідентифікатором %s була Ñтерта"
+
+#: controllers/groups_controller.php:89
+msgid "admin_group_edit_pagetitle"
+msgstr "Редагувати групу"
+
+#: controllers/groups_controller.php:92 controllers/groups_controller.php:113
+msgid "admin_group_error_invalid_id"
+msgstr "Ðевірний ідентифікатор Ð´Ð»Ñ Ð³Ñ€ÑƒÐ¿Ð¸"
+
+#: controllers/groups_controller.php:65
+msgid "admin_group_pagetitle"
+msgstr "Група адміна"
+
+#: controllers/groups_controller.php:77 controllers/groups_controller.php:99
+msgid "admin_group_saved"
+msgstr "Група збережена"
+
+#: views/elements/amo2009/search.thtml:257 views/elements/search.thtml:239
+msgid "advanced_search_form"
+msgstr "Хитріше"
+
+#: views/elements/amo2009/search.thtml:126 views/elements/search.thtml:125
+msgid "advanced_search_form_any_time"
+msgstr "Будь-коли"
+
+#: views/elements/amo2009/search.thtml:97
+#: views/elements/amo2009/search.thtml:110 views/elements/search.thtml:96
+#: views/elements/search.thtml:109
+msgid "advanced_search_form_any_type"
+msgstr "Будь-що"
+
+#: views/elements/amo2009/search.thtml:275 views/elements/search.thtml:254
+msgid "advanced_search_form_any_version"
+msgstr "Будь-Ñка"
+
+#: views/elements/amo2009/search.thtml:217 views/elements/search.thtml:212
+msgid "advanced_search_form_application"
+msgstr "Програма"
+
+#: views/elements/amo2009/search.thtml:143 views/elements/search.thtml:142
+msgid "advanced_search_form_keyword_match"
+msgstr "Ð¡Ð¿Ñ–Ð²Ð¿Ð°Ð´Ñ–Ð½Ð½Ñ Ñлова"
+
+#: views/elements/amo2009/search.thtml:251 views/elements/search.thtml:225
+msgid "advanced_search_form_lastupdate"
+msgstr "ВоÑтаннє оновлено"
+
+#: views/elements/amo2009/search.thtml:145 views/elements/search.thtml:144
+msgid "advanced_search_form_name"
+msgstr "Ім’Ñ"
+
+#: views/elements/amo2009/search.thtml:144 views/elements/search.thtml:143
+msgid "advanced_search_form_newest"
+msgstr "Ðайновіші"
+
+#: views/elements/amo2009/search.thtml:130 views/elements/search.thtml:129
+msgid "advanced_search_form_past_3_months"
+msgstr "Минулі 3 міÑÑці"
+
+#: views/elements/amo2009/search.thtml:131 views/elements/search.thtml:130
+msgid "advanced_search_form_past_6_months"
+msgstr "Минулі 6 міÑÑців"
+
+#: views/elements/amo2009/search.thtml:127 views/elements/search.thtml:126
+msgid "advanced_search_form_past_day"
+msgstr "Минулий день"
+
+#: views/elements/amo2009/search.thtml:129 views/elements/search.thtml:128
+msgid "advanced_search_form_past_month"
+msgstr "Минулий міÑÑць"
+
+#: views/elements/amo2009/search.thtml:128 views/elements/search.thtml:127
+msgid "advanced_search_form_past_week"
+msgstr "Минулий тиждень"
+
+#: views/elements/amo2009/search.thtml:132 views/elements/search.thtml:131
+msgid "advanced_search_form_past_year"
+msgstr "Минулий рік"
+
+#: views/elements/amo2009/search.thtml:239 views/elements/search.thtml:230
+msgid "advanced_search_form_perpage"
+msgstr "Ðа Ñторінку"
+
+#: views/elements/amo2009/search.thtml:243 views/elements/search.thtml:224
+msgid "advanced_search_form_platform"
+msgstr "Платформа"
+
+#: views/elements/amo2009/search.thtml:147 views/elements/search.thtml:146
+msgid "advanced_search_form_popularity"
+msgstr "ПопулÑрніÑÑ‚ÑŒ"
+
+#: views/elements/amo2009/search.thtml:146 views/elements/search.thtml:145
+msgid "advanced_search_form_rating"
+msgstr "Рейтинг"
+
+#: views/elements/amo2009/search.thtml:247 views/elements/search.thtml:231
+msgid "advanced_search_form_sortby"
+msgstr "Сортувати за"
+
+#: views/elements/amo2009/search.thtml:227 views/elements/search.thtml:216
+msgid "advanced_search_form_to"
+msgstr "до"
+
+#: views/elements/amo2009/search.thtml:257 views/elements/search.thtml:237
+msgid "advanced_search_form_toggle_tooltip"
+msgstr "Перемкнути хитрий режим пошуку"
+
+#: views/elements/amo2009/search.thtml:235 views/elements/search.thtml:223
+msgid "advanced_search_form_type"
+msgstr "Тип"
+
+#: views/elements/amo2009/search.thtml:222 views/elements/search.thtml:214
+msgid "advanced_search_form_version"
+msgstr "верÑÑ–Ñ"
+
+#: views/elements/amo2009/pagination.thtml:42
+#, fuzzy
+msgid "amo2009_pagination_next_page"
+msgstr "Next"
+
+#: views/elements/amo2009/pagination.thtml:41
+#, fuzzy
+msgid "amo2009_pagination_previous_page"
+msgstr "Prev"
+
+#: views/pages/js_constants.js.thtml:96
+msgid "app_compat_ignore_check"
+msgstr "Ðе зважати на цільову верÑÑ–ÑŽ"
+
+#: views/pages/js_constants.js.thtml:72
+msgid "app_compat_older_firefox_only"
+msgstr "Цей додаток розраховано на Ñтару верÑÑ–ÑŽ Firefox"
+
+#. %1$s and %2$s are URLs
+#: views/pages/js_constants.js.thtml:74
+msgid "app_compat_older_version_or_ignore_check"
+msgstr ""
+"Ви можете <a href=\"%1$s\">Ñпробувати Ñтарішу верÑÑ–ÑŽ додатку</a> чи <a href="
+"\"#\" onclick=\"%2$s\">пропуÑтити цю перевірку</a>"
+
+#. %1$s is a URL
+#: views/pages/js_constants.js.thtml:71
+msgid "app_compat_try_old_version"
+msgstr "<a href=\"%1$s\">Старіша верÑÑ–Ñ</a> може запрацювати"
+
+#. %1$s is a URL
+#. %2$s is a version number. Example: 3.1
+#: views/pages/js_constants.js.thtml:73
+msgid "app_compat_unreleased_version"
+msgstr "Цей додаток вимагає ще не випущений <a href=\"%1$s\">Firefox %2$s</a>"
+
+#: views/pages/js_constants.js.thtml:70
+msgid "app_compat_update_firefox"
+msgstr ""
+"<a href=\"http://getfirefox.com\">Оновіть Firefox</a> щоб ÑкориÑтатиÑÑŒ цим "
+"додатком"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#. %3$s is a status, like Public.
+#: controllers/components/audit.php:79
+#, fuzzy
+msgid "audit_addon_status"
+msgstr "%1$s changed the status of %2$s to %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:221
+#, fuzzy
+msgid "audit_admin_default"
+msgstr "%1$s committed unknown admin action %2$s to ID %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:153
+#, fuzzy
+msgid "audit_admin_feature_remove"
+msgstr "%1$s removed feature %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is an application, like Firefox.
+#: controllers/components/audit.php:92
+#, fuzzy
+msgid "audit_application_create"
+msgstr "%1$s created application %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is an application, like Firefox.
+#: controllers/components/audit.php:95
+#, fuzzy
+msgid "audit_application_edit"
+msgstr "%1$s edited application %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a version number, like 3.5.
+#. %3$s is an application, like Firefox.
+#: controllers/components/audit.php:105
+#, fuzzy
+msgid "audit_appversion_create"
+msgstr "%1$s created version %2$s for %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a version number, like 3.5.
+#. %3$s is an application, like Firefox.
+#: controllers/components/audit.php:108
+#, fuzzy
+msgid "audit_appversion_delete"
+msgstr "%1$s deleted version %2$s for %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a config field, like "awesomeness".
+#. %3$s is a config value, like "off".
+#. %4$s is a config value, like "on".
+#: controllers/components/audit.php:210
+#, fuzzy
+msgid "audit_config"
+msgstr "%1$s changed config '%2$s' from '%3$s' to '%4$s'"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:258
+#, fuzzy
+msgid "audit_editor_default"
+msgstr "%1$s committed unknown editor action %2$s to ID %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#: controllers/components/audit.php:236
+#, fuzzy
+msgid "audit_editor_feature_remove"
+msgstr "%1$s removed addon %2$s from feature list"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#: controllers/components/audit.php:231
+#, fuzzy
+msgid "audit_feature_add"
+msgstr "%1$s added addon %2$s to feature list"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:149
+#, fuzzy
+msgid "audit_feature_edit"
+msgstr "%1$s changed a feature for %2$s locale"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#: controllers/components/audit.php:241
+#, fuzzy
+msgid "audit_feature_locale_change"
+msgstr "%1$s changed locales for addon %2$s on feature list"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:83
+#, fuzzy
+msgid "audit_file_recalchash"
+msgstr "%1$s recalculated the hash for file %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>user name</a>
+#. %3$s is <a>group name</a>
+#: controllers/components/audit.php:182
+#, fuzzy
+msgid "audit_group_addmember"
+msgstr "%1$s added %2$s to group %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:313
+#, fuzzy
+msgid "audit_group_associated"
+msgstr "%1$s associated themselves with %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:162
+#, fuzzy
+msgid "audit_group_create"
+msgstr "%1s created group %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:170
+#, fuzzy
+msgid "audit_group_delete"
+msgstr "%1$s deleted group %2$s (ID %3$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:165
+#, fuzzy
+msgid "audit_group_edit"
+msgstr "%1$s edited group %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>user name</a>
+#. %3$s is <a>group name</a>
+#: controllers/components/audit.php:188
+#, fuzzy
+msgid "audit_group_removemember"
+msgstr "%1$s removed %2$s from group %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:280
+#, fuzzy
+msgid "audit_l10n_default"
+msgstr "%1$s committed unknown action %2$s for %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:295
+#, fuzzy
+msgid "audit_modify_locked_group"
+msgstr "%1$s attempted to modify locked group %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:299
+#, fuzzy
+msgid "audit_modify_other_locale"
+msgstr "%1$s attempted to modify translations in %2$s without permission"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a platform, like <a>Windows</a>
+#: controllers/components/audit.php:135
+#, fuzzy
+msgid "audit_platform_create"
+msgstr "%1$s created platform %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a platform, like <a>Windows</a>
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:143
+#, fuzzy
+msgid "audit_platform_delete"
+msgstr "%1$s deleted platform %2$s (ID %3$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a platform, like <a>Windows</a>
+#: controllers/components/audit.php:138
+#, fuzzy
+msgid "audit_platform_edit"
+msgstr "%1$s edited platform %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a part of the admin, like 'Site Config'
+#: controllers/components/audit.php:288
+#, fuzzy
+msgid "audit_reauthentication_failure"
+msgstr "%1$s failed to re-authenticate to access %2$s."
+
+#. %1$s is <a>user name</a>
+#. %2$s is the name of a canned response, like 'Ready for the public'
+#: controllers/components/audit.php:198
+#, fuzzy
+msgid "audit_response_create"
+msgstr "%1$s created response %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is the name of a canned response, like 'Ready for the public'
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:206
+#, fuzzy
+msgid "audit_response_delete"
+msgstr "%1$s deleted response %2$s (ID %3$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is the name of a canned response, like 'Ready for the public'
+#: controllers/components/audit.php:201
+#, fuzzy
+msgid "audit_response_edit"
+msgstr "%1$s edited response %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:245
+#, fuzzy
+msgid "audit_review_approve"
+msgstr "%1$s approved review %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:250 controllers/components/audit.php:253
+#, fuzzy
+msgid "audit_review_delete"
+msgstr "%1$s deleted review %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:303
+#, fuzzy
+msgid "audit_security_default"
+msgstr "%1$s committed unknown security action %2$s to ID %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a category name, like <a>Search Tools</a>
+#: controllers/components/audit.php:118
+#, fuzzy
+msgid "audit_tag_create"
+msgstr "%1$s created tag %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a category name, like <a>Search Tools</a>
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:126
+#, fuzzy
+msgid "audit_tag_delete"
+msgstr "%1$s deleted category %2$s (ID %3$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a category name, like <a>Search Tools</a>
+#: controllers/components/audit.php:121
+#, fuzzy
+msgid "audit_tag_edit"
+msgstr "%1$s edited category %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:266
+#, fuzzy
+msgid "audit_update_applications"
+msgstr "%1$s updated application translations for %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:277
+#, fuzzy
+msgid "audit_update_blog"
+msgstr "%1$s updated blog post translations for %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:274
+#, fuzzy
+msgid "audit_update_platforms"
+msgstr "%1$s updated platform translations for %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:270
+#, fuzzy
+msgid "audit_update_tags"
+msgstr "%1$s updated category translations for %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>user name</a>
+#: controllers/components/audit.php:217
+#, fuzzy
+msgid "audit_user_edit"
+msgstr "%1$s edited %2$s's user information"
+
+#: controllers/addons_controller.php:1012
+msgid "browse_addons_name"
+msgstr "Додатки за ім’Ñм"
+
+#: controllers/addons_controller.php:1010
+msgid "browse_addons_newest"
+msgstr "Ðайновіші додатки"
+
+#: controllers/addons_controller.php:1008
+msgid "browse_addons_popular"
+msgstr "ПопулÑрні додатки"
+
+#: controllers/addons_controller.php:1011
+msgid "browse_addons_rated"
+msgstr "Додатки за рейтингом"
+
+#: controllers/addons_controller.php:1009
+msgid "browse_addons_updated"
+msgstr "Ðедавно оновлені додатки"
+
+#: views/elements/categories.thtml:73 views/elements/categories.thtml:82
+msgid "categories_current_title"
+msgstr "Поточна категоріÑ"
+
+#: views/elements/categories.thtml:50
+#: views/elements/amo2009/categories.thtml:43
+#: views/elements/amo2009/categories.thtml:45
+msgid "categories_header"
+msgstr "Категорії"
+
+#: views/elements/categories.thtml:50
+#: views/elements/amo2009/categories.thtml:41
+msgid "categories_header_title"
+msgstr "Оберіть категорії"
+
+#. %1$s is the category name
+#: views/addons/searchengines.thtml:129
+#, php-format
+msgid "category_extra_see_all"
+msgstr "Показати вÑÑ– %1$s"
+
+#. %1$s is a number.
+#: models/collection.php:130
+#, fuzzy
+msgid "collection_description_limit"
+msgstr "The description should be less than %1$s characters."
+
+#. %1$s is the name of the collection
+#: controllers/collections_controller.php:392
+#, fuzzy
+msgid "collection_detail_rss_title"
+msgstr "%s Collection"
+
+#: controllers/collections_controller.php:1065
+#, fuzzy
+msgid "collection_error_deleting_addon"
+msgstr "Error deleting add-on!"
+
+#: controllers/collections_controller.php:1051
+#, fuzzy
+msgid "collection_error_saving_addon"
+msgstr "Error saving add-on!"
+
+#: controllers/collections_controller.php:1080
+#, fuzzy
+msgid "collection_error_saving_comment"
+msgstr "Error saving comment!"
+
+#. %1$s is a number.
+#: models/collection.php:122
+#, fuzzy
+msgid "collection_name_limit"
+msgstr "The name should be less than %1$s characters."
+
+#: controllers/collections_controller.php:352
+#: controllers/collections_controller.php:487
+msgid "collection_not_found"
+msgstr "Колекцію не знайдено!"
+
+#. %1$s is the text on the "create collection" button
+#: views/collections/add.thtml:91
+#, fuzzy
+msgid "collections_add_formfield_addons_description"
+msgstr ""
+"If you already know which add-ons you want to add to your collection, just "
+"start typing their names below. If you'd rather wait and do this later, just "
+"click %1$s now."
+
+#: views/collections/add.thtml:90
+#, fuzzy
+msgid "collections_add_formfield_firstaddons"
+msgstr "Choose your first add-ons"
+
+#: views/collections/add.thtml:48
+#, fuzzy
+msgid "collections_add_header"
+msgstr "Create a Collection"
+
+#: views/collections/add.thtml:97
+#, fuzzy
+msgid "collections_add_header_selectedaddons"
+msgstr "Selected Add-ons"
+
+#: views/collections/add.thtml:50
+#, fuzzy
+msgid "collections_add_intro"
+msgstr ""
+"It's easy to create your own collection of add-ons by filling in a few "
+"fields below."
+
+#: views/collections/add.thtml:92 views/collections/add.thtml:103
+#, fuzzy
+msgid "collections_add_submit"
+msgstr "Create Collection"
+
+#: views/pages/collector_faq.thtml:50 views/pages/collector_firstrun.thtml:43
+#: views/pages/collector.thtml:47 views/pages/collector_features.thtml:55
+#: controllers/search_controller.php:302
+#: controllers/collections_controller.php:206
+#: controllers/collections_controller.php:405
+#: controllers/collections_controller.php:467
+#: controllers/collections_controller.php:539
+#, fuzzy
+msgid "collections_breadcrumb"
+msgstr "Collections"
+
+#: views/collections/detail.thtml:185
+#, fuzzy
+msgid "collections_detail_a_learn"
+msgstr "Learn More"
+
+#: views/elements/amo2009/collection_add_form.thtml:53
+#: views/elements/amo2009/collections_js_init.thtml:68
+#: views/pages/collector_firstrun.thtml:64
+#, fuzzy
+msgid "collections_detail_button_add"
+msgstr "Add to Favorites"
+
+#: views/elements/amo2009/collection_add_form.thtml:50
+#: views/elements/amo2009/collections_js_init.thtml:71
+#, fuzzy
+msgid "collections_detail_button_remove"
+msgstr "Remove from Favorites"
+
+#. %1$s is a URL.
+#. %2$s is a full <a href>.
+#: views/collections/detail.thtml:62
+#, fuzzy
+msgid "collections_detail_created_desc"
+msgstr ""
+"<p>You can view your new collection below. If you'd like to set a collection "
+"nickname, upload an icon, or change additional settings, please visit the <a "
+"href='%1$s'>Manage Collections</a> page.</p><p>Your collection can be "
+"accessed at this location: %2$s</p>"
+
+#: views/collections/detail.thtml:61
+#, fuzzy
+msgid "collections_detail_created_msg"
+msgstr "Your collection is now ready!"
+
+#: views/collections/detail.thtml:109
+#, fuzzy
+msgid "collections_detail_header_about"
+msgstr "About This Collection"
+
+#. %1$s is a number.
+#: views/collections/detail.thtml:126
+#, fuzzy
+msgid "collections_detail_header_count"
+msgid_plural "collections_detail_header_count"
+msgstr[0] "%1$s Add-on in this Collection"
+msgstr[1] "%1$s Add-ons in this Collection"
+
+#: views/collections/detail.thtml:113
+#, fuzzy
+msgid "collections_detail_info_created"
+msgstr "<strong>Created by:</strong> %1$s"
+
+#: views/collections/detail.thtml:117
+#, fuzzy
+msgid "collections_detail_info_updated"
+msgstr "<strong>Updated:</strong>"
+
+#: views/elements/amo2009/collections_js_init.thtml:62
+#, fuzzy
+msgid "collections_detail_js_adding"
+msgstr "Adding to Favorites&hellip;"
+
+#: views/elements/amo2009/collections_js_init.thtml:65
+#, fuzzy
+msgid "collections_detail_js_removing"
+msgstr "Removing Favorite&hellip;"
+
+#. %1$s is a URL
+#: views/collections/detail.thtml:90
+#, fuzzy
+msgid "collections_detail_login"
+msgstr "<a href=\"%1$s\">Log in</a> to add this collection to your favorites."
+
+#: views/collections/detail.thtml:104
+#, fuzzy
+msgid "collections_detail_manage"
+msgstr "Manage Collection"
+
+#: controllers/collections_controller.php:298
+#, fuzzy
+msgid "collections_detail_sort_date"
+msgstr "Date Added"
+
+#: controllers/collections_controller.php:299
+#, fuzzy
+msgid "collections_detail_sort_name"
+msgstr "Name"
+
+#: controllers/collections_controller.php:300
+#, fuzzy
+msgid "collections_detail_sort_popularity"
+msgstr "Popularity"
+
+#. %1$s is a number.
+#: views/collections/detail.thtml:166
+#, fuzzy
+msgid "collections_detail_weekly_downloads"
+msgid_plural "collections_detail_weekly_downloads"
+msgstr[0] "%1$s download this week"
+msgstr[1] "%1$s downloads this week"
+
+#: views/collections/edit.thtml:255
+#, fuzzy
+msgid "collections_edit_addons_delete_noscript"
+msgstr "Selected add-ons will be removed upon Save"
+
+#: views/collections/edit.thtml:247
+#, fuzzy
+msgid "collections_edit_addons_description"
+msgstr ""
+"To publish new add-ons to this collection, start typing their names below."
+
+#: views/collections/edit.thtml:248
+#, fuzzy
+msgid "collections_edit_addons_description_noscript"
+msgstr ""
+"To publish new add-ons to this collection, enter a comma-separated list of "
+"Add-on IDs below."
+
+#: views/collections/edit.thtml:247 views/collections/edit.thtml:248
+#, fuzzy
+msgid "collections_edit_addons_description_publish_detailspage"
+msgstr "You can also publish an add-on from its normal listing page."
+
+#. %1$s is the date the add-on was added to the collection
+#. %1$s is the name of the user who added the add-on to the collection
+#: views/collections/edit.thtml:260
+#, fuzzy
+msgid "collections_edit_addons_listitem_added"
+msgstr "Added %1$s by %2$s"
+
+#: views/collections/edit.thtml:263
+#, fuzzy
+msgid "collections_edit_addons_listitem_comment_add"
+msgstr "Add publisher comment"
+
+#: views/collections/edit.thtml:266
+#, fuzzy
+msgid "collections_edit_addons_listitem_comment_delete"
+msgstr "Delete publisher comment"
+
+#: views/collections/edit.thtml:265
+#, fuzzy
+msgid "collections_edit_addons_listitem_comment_edit"
+msgstr "Edit publisher comment"
+
+#: views/collections/edit.thtml:271
+#, fuzzy
+msgid "collections_edit_addons_listitem_comment_note"
+msgstr ""
+"Note: Comment will appear as though written by original publisher on the "
+"original publication date"
+
+#: views/collections/edit.thtml:270
+#, fuzzy
+msgid "collections_edit_addons_listitem_comment_submit"
+msgstr "Save Comment"
+
+#: views/collections/edit.thtml:261
+#, fuzzy
+msgid "collections_edit_addons_listitem_remove"
+msgstr "Remove"
+
+#: views/collections/edit.thtml:250
+#, fuzzy
+msgid "collections_edit_addons_submit"
+msgstr "Add to Collection"
+
+#: views/collections/edit.thtml:153
+#, fuzzy
+msgid "collections_edit_check_nickname"
+msgstr "Check Availability"
+
+#: views/collections/edit.thtml:299
+#, fuzzy
+msgid "collections_edit_confirm_deletecollection"
+msgstr "Yes, I would like to delete this collection."
+
+#. %1$s is the label of the edit form's submit button
+#: views/collections/edit.thtml:300
+#, fuzzy
+msgid "collections_edit_confirm_deletecollection_description"
+msgstr "Check the box, then click on \"%1$s\" to delete this collection."
+
+#. %1$s is the "delete" submit button text
+#. %2$s is the title of the "advanced" tab
+#: views/collections/edit.thtml:95
+#, fuzzy
+msgid "collections_edit_delete_upon_submit"
+msgstr ""
+"Upon clicking \"%1$s\" below, your collection will be deleted. If you do not "
+"want to delete your collection, uncheck the confirmation box in the \"%2$s\" "
+"tab and continue editing your collection. If you leave this page without "
+"saving, your collection will also not be deleted."
+
+#: views/collections/edit.thtml:94
+#, fuzzy
+msgid "collections_edit_delete_warning"
+msgstr "Your collection is about to be deleted!"
+
+#: views/collections/add.thtml:76 views/collections/edit.thtml:144
+#, fuzzy
+msgid "collections_edit_form_error_description"
+msgstr "You must provide a description of your collection."
+
+#: views/collections/edit.thtml:181
+#, fuzzy
+msgid "collections_edit_form_error_icon"
+msgstr "There was an error uploading your icon."
+
+#: views/collections/add.thtml:69 views/collections/edit.thtml:130
+#, fuzzy
+msgid "collections_edit_form_error_name"
+msgstr "You must give your collection a name."
+
+#: views/collections/edit.thtml:158
+#, fuzzy
+msgid "collections_edit_form_error_nickname"
+msgstr "If you choose a nickname, it must be unique."
+
+#: views/collections/add.thtml:93 views/collections/edit.thtml:249
+#, fuzzy
+msgid "collections_edit_formfield_addons"
+msgstr "Add-on name:"
+
+#: views/collections/edit.thtml:281
+#, fuzzy
+msgid "collections_edit_formfield_application"
+msgstr "Associated Application"
+
+#: views/collections/edit.thtml:282
+#, fuzzy
+msgid "collections_edit_formfield_application_description"
+msgstr "Select the application that your collection supports."
+
+#: views/collections/edit.thtml:288
+#, fuzzy
+msgid "collections_edit_formfield_collectiontype"
+msgstr "Collection Type"
+
+#: views/collections/edit.thtml:295
+#, fuzzy
+msgid "collections_edit_formfield_deletecollection"
+msgstr "Delete Collection"
+
+#: views/collections/edit.thtml:296
+#, fuzzy
+msgid "collections_edit_formfield_deletecollection_description"
+msgstr "Deleting your collection will permanently erase it."
+
+#: views/collections/add.thtml:73 views/collections/edit.thtml:140
+#, fuzzy
+msgid "collections_edit_formfield_description"
+msgstr "Collection Description"
+
+#: views/collections/add.thtml:74 views/collections/edit.thtml:141
+#, fuzzy
+msgid "collections_edit_formfield_description_description"
+msgstr "Briefly describe your collection and the kind of add-ons in it"
+
+#: views/collections/edit.thtml:162
+#, fuzzy
+msgid "collections_edit_formfield_icon"
+msgstr "Icon"
+
+#: views/collections/edit.thtml:163
+#, fuzzy
+msgid "collections_edit_formfield_icon_description"
+msgstr ""
+"You can upload a JPG, GIF or PNG icon that will be resized to 32x32 pixels."
+
+#: views/collections/add.thtml:80 views/collections/edit.thtml:189
+#, fuzzy
+msgid "collections_edit_formfield_listed"
+msgstr "Who can view your collection?"
+
+#: views/collections/add.thtml:81 views/collections/edit.thtml:190
+#, fuzzy
+msgid "collections_edit_formfield_listed_description"
+msgstr ""
+"By default, collections appear in the public Collection Directory and are "
+"discoverable by anyone. If you want to restrict your collection to be "
+"viewable only by people who are given a special link, choose that option "
+"below."
+
+#: views/collections/add.thtml:84 views/collections/edit.thtml:193
+#, fuzzy
+msgid "collections_edit_formfield_listed_false"
+msgstr "Only people I invite can view my collection"
+
+#: views/collections/add.thtml:83 views/collections/edit.thtml:192
+#, fuzzy
+msgid "collections_edit_formfield_listed_true"
+msgstr "Everyone can view my collection in the directory"
+
+#: views/collections/edit.thtml:223
+#, fuzzy
+msgid "collections_edit_formfield_managers"
+msgstr "Who can manage my collection?"
+
+#: views/collections/edit.thtml:224
+#, fuzzy
+msgid "collections_edit_formfield_managers_description"
+msgstr ""
+"These users can publish add-ons to your collection, manage all add-ons and "
+"settings, and grant other users permission."
+
+#: views/collections/add.thtml:66 views/collections/edit.thtml:126
+#, fuzzy
+msgid "collections_edit_formfield_name"
+msgstr "Collection Name"
+
+#: views/collections/add.thtml:67 views/collections/edit.thtml:127
+#, fuzzy
+msgid "collections_edit_formfield_name_description"
+msgstr ""
+"Give your collection a descriptive name, such as \"Dave's Favorite Travel "
+"Add-ons\""
+
+#: views/collections/edit.thtml:148
+#, fuzzy
+msgid "collections_edit_formfield_nickname"
+msgstr "Collection Nickname"
+
+#: views/collections/edit.thtml:149
+#, fuzzy
+msgid "collections_edit_formfield_nickname_description"
+msgstr "Optionally, give your collection a unique nickname for quick access:"
+
+#: views/collections/edit.thtml:201
+#, fuzzy
+msgid "collections_edit_formfield_publishers"
+msgstr "Who can publish add-ons to your collection?"
+
+#: views/collections/edit.thtml:202
+#, fuzzy
+msgid "collections_edit_formfield_publishers_description"
+msgstr ""
+"These users can publish add-ons to your collection and remove add-ons that "
+"they publish."
+
+#: views/collections/edit.thtml:210 views/collections/edit.thtml:232
+#, fuzzy
+msgid "collections_edit_formfield_users_add"
+msgstr "Enter the e-mail address of a Firefox Add-ons account:"
+
+#: views/collections/edit.thtml:216 views/collections/edit.thtml:238
+#, fuzzy
+msgid "collections_edit_formfield_users_delete_noscript"
+msgstr "Selected accounts will be removed upon Save"
+
+#: views/collections/edit.thtml:215 views/collections/edit.thtml:237
+#, fuzzy
+msgid "collections_edit_formfield_users_new_noscript"
+msgstr ""
+"Enter a comma-separated list of e-mail addresses of Firefox Add-ons accounts"
+
+#: views/collections/edit.thtml:204 views/collections/edit.thtml:226
+#, fuzzy
+msgid "collections_edit_formfield_users_onlyme"
+msgstr "Only me"
+
+#: views/collections/edit.thtml:205 views/collections/edit.thtml:227
+#, fuzzy
+msgid "collections_edit_formfield_users_otherusers"
+msgstr "Myself and these users:"
+
+#: views/collections/edit.thtml:211 views/collections/edit.thtml:233
+#, fuzzy
+msgid "collections_edit_formfield_users_submit"
+msgstr "Add"
+
+#. %1$s is the name of the collection
+#: views/collections/edit.thtml:68
+#, fuzzy
+msgid "collections_edit_header"
+msgstr "Manage %1$s"
+
+#: views/collections/edit.thtml:246
+#, fuzzy
+msgid "collections_edit_header_addons"
+msgstr "Manage Collection Contents"
+
+#: views/collections/edit.thtml:253 views/collections/edit.thtml:258
+#, fuzzy
+msgid "collections_edit_header_addons_current"
+msgstr "Current Add-ons:"
+
+#: views/collections/edit.thtml:279
+#, fuzzy
+msgid "collections_edit_header_advanced"
+msgstr "Advanced Settings"
+
+#: views/collections/edit.thtml:186
+#, fuzzy
+msgid "collections_edit_header_permissions"
+msgstr "Manage Collection Permissions"
+
+#: views/collections/edit.thtml:170
+#, fuzzy
+msgid "collections_edit_icon_cancel"
+msgstr "Cancel"
+
+#: views/collections/edit.thtml:174 views/collections/edit.thtml:179
+#, fuzzy
+msgid "collections_edit_icon_delete"
+msgstr "Delete Icon"
+
+#: views/collections/edit.thtml:178
+#, fuzzy
+msgid "collections_edit_icon_replace"
+msgstr "Replace Icon"
+
+#. %1$s is the label of the edit form's submit button
+#: views/collections/edit.thtml:169
+#, fuzzy
+msgid "collections_edit_icon_toberemoved"
+msgstr "Icon will be removed when \"%1$s\" is clicked below"
+
+#: views/collections/edit.thtml:155
+#, fuzzy
+msgid "collections_edit_nickname_available"
+msgstr "Nickname Available"
+
+#: controllers/collections_controller.php:943
+#, fuzzy
+msgid "collections_edit_nickname_error"
+msgstr ""
+"Your nickname contained invalid characters and was corrected. Please try "
+"again."
+
+#: views/collections/edit.thtml:156
+#, fuzzy
+msgid "collections_edit_nickname_taken"
+msgstr "Nickname Taken"
+
+#. This string is followed by a URL pointing to the collection's view page
+#: views/collections/edit.thtml:75
+#, fuzzy
+msgid "collections_edit_saved_nextstep"
+msgstr "Your collection can be accessed at this location:"
+
+#: views/collections/edit.thtml:74
+#, fuzzy
+msgid "collections_edit_saved_success"
+msgstr "Your collection was successfully saved!"
+
+#: views/collections/edit.thtml:169 views/collections/edit.thtml:300
+#: views/collections/edit.thtml:308 views/pages/js_constants.js.thtml:99
+#, fuzzy
+msgid "collections_edit_submit"
+msgstr "Update Collection"
+
+#: views/collections/edit.thtml:96 views/collections/edit.thtml:297
+#: views/pages/js_constants.js.thtml:100
+#, fuzzy
+msgid "collections_edit_submit_deletecollection"
+msgstr "Delete Collection"
+
+#: views/collections/edit.thtml:111
+#, fuzzy
+msgid "collections_edit_tabheader_addons"
+msgstr "Add-ons"
+
+#: views/collections/edit.thtml:97 views/collections/edit.thtml:113
+#, fuzzy
+msgid "collections_edit_tabheader_advanced"
+msgstr "Advanced"
+
+#: views/collections/edit.thtml:108
+#, fuzzy
+msgid "collections_edit_tabheader_details"
+msgstr "Name &amp; Details"
+
+#: views/collections/edit.thtml:109
+#, fuzzy
+msgid "collections_edit_tabheader_permissions"
+msgstr "Permissions"
+
+#: models/collection_promo.php:53
+#, fuzzy
+msgid "collections_family_tagline"
+msgstr "Add-ons can keep an eye on your kids and your calendar."
+
+#: models/collection_promo.php:53
+#, fuzzy
+msgid "collections_family_title"
+msgstr "Family Organizer"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:70
+#, fuzzy
+msgid "collections_index_a_check_out"
+msgstr "Check out Add-on Collector"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:52
+#, fuzzy
+msgid "collections_index_a_create"
+msgstr "Create a Collection"
+
+#: views/collections/detail.thtml:139 views/collections/listing.thtml:85
+#: views/search/collections.thtml:84
+#, fuzzy
+msgid "collections_index_button_go"
+msgstr "Go"
+
+#. %1$s is a URL.
+#: controllers/collections_controller.php:182
+#, fuzzy
+msgid "collections_index_filler_favorites"
+msgstr ""
+"<p><strong>You don't have any favorite collections yet.</strong></p> "
+"<p>Collections you mark as favorites can be quickly accessed from this page, "
+"and will appear in the <a href='%1$s'>Add-on Collector</a> if you've "
+"installed it.</p>"
+
+#. %1$s is a URL.
+#: controllers/collections_controller.php:167
+#, fuzzy
+msgid "collections_index_filler_mine"
+msgstr ""
+"<p>You haven't created any collections yet. Collections are easy to create "
+"and fill with your favorite add-ons. <a href='%1$s'>Try it out</a>!</p>"
+
+#: views/collections/listing.thtml:51
+#, fuzzy
+msgid "collections_index_header_collections"
+msgstr "Collections"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:60
+#, fuzzy
+msgid "collections_index_header_collector"
+msgstr "Add-on Collector"
+
+#. %1$s is a comma-separated list of author names
+#: views/elements/amo2009/collection_listing_item.thtml:84
+#: views/collections/detail.thtml:151
+#, fuzzy
+msgid "collections_index_header_created"
+msgstr "created by %1$s"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:47
+#, fuzzy
+msgid "collections_index_header_what"
+msgstr "What are Collections?"
+
+#: views/collections/detail.thtml:132 views/collections/listing.thtml:78
+#: views/search/collections.thtml:66
+#, fuzzy
+msgid "collections_index_label_sortby"
+msgstr "Sort by"
+
+#: controllers/collections_controller.php:130
+#, fuzzy
+msgid "collections_index_li_editors"
+msgstr "Editor's Picks"
+
+#: views/collections/subscribe.thtml:64
+#: controllers/collections_controller.php:140
+#, fuzzy
+msgid "collections_index_li_favorites"
+msgstr "My Favorites"
+
+#: controllers/collections_controller.php:138
+#, fuzzy
+msgid "collections_index_li_mine"
+msgstr "My Collections"
+
+#: controllers/collections_controller.php:132
+#, fuzzy
+msgid "collections_index_li_popular"
+msgstr "Popular"
+
+#: views/search/collections.thtml:74 controllers/collections_controller.php:81
+#, fuzzy
+msgid "collections_index_option_all"
+msgstr "Most popular all time"
+
+#: views/search/collections.thtml:72 controllers/collections_controller.php:78
+#, fuzzy
+msgid "collections_index_option_month"
+msgstr "Most popular this month"
+
+#: views/search/collections.thtml:76 controllers/collections_controller.php:84
+#, fuzzy
+msgid "collections_index_option_newest"
+msgstr "Newest"
+
+#: views/search/collections.thtml:70 controllers/collections_controller.php:75
+#, fuzzy
+msgid "collections_index_option_week"
+msgstr "Most popular this week"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:67
+#, fuzzy
+msgid "collections_index_p_collector"
+msgstr ""
+"There's a new way to manage and find favorite add-ons. Comment, share and "
+"sync collections, all from your browser"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:48
+#, fuzzy
+msgid "collections_index_p_what_are"
+msgstr "Collections are groups of related add-ons assembled for easy sharing."
+
+#. %s is a date in the _('date') format
+#: views/elements/collections_interactive_addon.thtml:85
+#, php-format
+msgid "collections_interactive_addon_added"
+msgstr "Додано %s"
+
+#: models/collection_promo.php:55
+#, fuzzy
+msgid "collections_reference_tagline"
+msgstr "Add-ons can do better research online."
+
+#: models/collection_promo.php:55
+#, fuzzy
+msgid "collections_reference_title"
+msgstr "Reference Desk"
+
+#: models/collection_promo.php:52
+#, fuzzy
+msgid "collections_social_tagline"
+msgstr "Add-ons can manage your social network."
+
+#: models/collection_promo.php:52
+#, fuzzy
+msgid "collections_social_title"
+msgstr "Social Circuit"
+
+#: views/collections/subscribe.thtml:91
+#, fuzzy
+msgid "collections_subscribe_button_close"
+msgstr "Close"
+
+#: views/collections/subscribe.thtml:70
+#, fuzzy
+msgid "collections_subscribe_error"
+msgstr ""
+"An error occurred trying to add a favorite collection. Is this collection "
+"already a favorite?"
+
+#: views/collections/subscribe.thtml:96
+#, fuzzy
+msgid "collections_subscribe_label_bothersome"
+msgstr "Don't show me this message again."
+
+#. %1$s is the collection name
+#: views/collections/subscribe.thtml:60
+#, fuzzy
+msgid "collections_subscribe_success"
+msgstr "%1$s has been added to your favorite collections."
+
+#. %1$s is the link to the "My Favorites" tab on the main collections page
+#. %2$s is the localized title of the "My Favorites" tab
+#. %3$s is the link URL to the collector add-on
+#: views/collections/subscribe.thtml:62
+#, fuzzy
+msgid "collections_subscribe_success_desc"
+msgstr ""
+"You can now quickly find this collection from the <a href=\"%1$s\">%2$s</a> "
+"tab in the directory. For an even easier way to keep track of your favorite "
+"collections, try out our <a href=\"%3$s\">Add-on Collector</a> extension for "
+"Firefox."
+
+#: views/collections/listing.thtml:55
+#, fuzzy
+msgid "collections_success_delete"
+msgstr "The collection has been deleted."
+
+#: models/collection_promo.php:54
+#, fuzzy
+msgid "collections_travel_tagline"
+msgstr "Add-ons can turn you into a travel agent."
+
+#: models/collection_promo.php:54
+#, fuzzy
+msgid "collections_travel_title"
+msgstr "The Traveler's Pack"
+
+#. A collection of add-ons that is automatically built for a user. They are "automatically published" to this collection.
+#: controllers/collections_controller.php:581
+#, fuzzy
+msgid "collections_type_autopublisher"
+msgstr "Auto-publisher"
+
+#. A collection that has been chosen by an Editor as notable or exceptional
+#: controllers/collections_controller.php:582
+#, fuzzy
+msgid "collections_type_editorspick"
+msgstr "Editor's Pick"
+
+#: controllers/collections_controller.php:580
+#, fuzzy
+msgid "collections_type_normal"
+msgstr "Normal"
+
+#: views/collections/subscribe.thtml:84
+#, fuzzy
+msgid "collections_unsubscribe_error"
+msgstr ""
+"An error occurred trying to remove a favorite collection. Was this "
+"collection not a favorite?"
+
+#. %1$s is the collection name
+#: views/collections/subscribe.thtml:78
+#, fuzzy
+msgid "collections_unsubscribe_success"
+msgstr "%1$s has been removed from your favorite collections."
+
+#: models/collection_promo.php:56
+#, fuzzy
+msgid "collections_webdev_tagline"
+msgstr "Add-ons make it easier to build the perfect website."
+
+#: models/collection_promo.php:56
+#, fuzzy
+msgid "collections_webdev_title"
+msgstr "Web Developer's Toolbox"
+
+#: views/elements/amo2009/collections_sidebar_whatare.thtml:40
+#, fuzzy
+msgid "collections_whatare_header"
+msgstr "What are Collections?"
+
+#: views/elements/amo2009/collections_sidebar_whatare.thtml:45
+#, fuzzy
+msgid "collections_whatare_learnmore"
+msgstr "Read the FAQ"
+
+#: views/elements/amo2009/collections_sidebar_whatare.thtml:44
+#, fuzzy
+msgid "collections_whatare_text"
+msgstr ""
+"There’s a new way to manage and find favorite add-ons. Comment, share and "
+"sync collections, all from your browser."
+
+#: views/pages/collector_faq.thtml:61 views/pages/collector_features.thtml:67
+#, fuzzy
+msgid "collector_features_a_home"
+msgstr "Add-on Collector Home"
+
+#: views/elements/amo2009/collector_sidebar_download.thtml:46
+#, fuzzy
+msgid "collector_features_heading_download"
+msgstr "Download the Add-on Collector:"
+
+#: views/elements/amo2009/collector_sidebar_download.thtml:43
+#: views/pages/collector_firstrun.thtml:116 views/pages/collector.thtml:69
+#, fuzzy
+msgid "collector_features_img_logo"
+msgstr "Add-on Collector Logo"
+
+#: views/compatibility/dashboard.thtml:49
+#: controllers/compatibility_controller.php:72
+msgid "compatibility_dashboard_center_header"
+msgstr "Центр ÑуміÑноÑÑ‚Ñ– додатків"
+
+#. %1$s is the name of an application and a version. Example: Firefox 3.0
+#. %2$s is the name of an application. Example: Firefox
+#: views/compatibility/dashboard.thtml:50
+msgid "compatibility_dashboard_intro"
+msgstr ""
+"Будьте готові до випуÑку %1$s з інÑтрументами та інформацією, "
+"доÑтупниминижче Ð´Ð»Ñ Ñпільноти розробників додатків до %2$s."
+
+#: views/compatibility/dashboard.thtml:103
+msgid "compatibility_dashboard_loading"
+msgstr "Ð—Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ Ð´Ð°Ð½Ð¸Ñ…..."
+
+#: views/compatibility/dashboard.thtml:45
+msgid "compatibility_dashboard_main_link"
+msgstr "Ðазад до опиÑу"
+
+#: views/compatibility/dashboard.thtml:100 views/compatibility/report.thtml:43
+msgid "compatibility_dashboard_report"
+msgstr "Звіт про ÑуміÑніÑÑ‚ÑŒ додатку"
+
+#: views/compatibility/dashboard.thtml:53
+#: views/compatibility/dashboard.thtml:110
+#: views/compatibility/developers.thtml:43
+msgid "compatibility_developer_info"
+msgstr "Ð†Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ñ–Ñ Ð´Ð»Ñ Ñ€Ð¾Ð·Ñ€Ð¾Ð±Ð½Ð¸ÐºÑ–Ð² додатків"
+
+#: views/compatibility/developers.thtml:66
+msgid "compatibility_developers_adjust_maxversion"
+msgstr "Змінити maxVersion без відвантаженнÑ"
+
+#: views/compatibility/dashboard.thtml:124
+msgid "compatibility_developers_check_status"
+msgstr "Перевірити ÑÑ‚Ð°Ñ‚ÑƒÑ Ð¼Ð¾Ñ—Ñ… додатків"
+
+#. %1$s is a URL
+#. %2$s is an application and version. Example: Firefox 3.0
+#: views/compatibility/dashboard.thtml:126
+msgid "compatibility_developers_login_first"
+msgstr ""
+"Якщо ваші додатки розміщені на Сайті додатків Mozilla, <a href=\"%1$s"
+"\">зайдітьіз паролем</a> Ð´Ð»Ñ Ñ‚Ð¾Ð³Ð¾, щоб дізнатиÑÑ Ð¿Ñ€Ð¾ Ñтан ваших додатків до %"
+"2$s."
+
+#: views/compatibility/dashboard.thtml:114
+msgid "compatibility_developers_mdclogo_alt"
+msgstr "Лого Центру розробників Mozilla"
+
+#: views/compatibility/developers.thtml:73
+msgid "compatibility_developers_no_addons"
+msgstr "Ðа Сайті додатків Mozilla не розміщено жодного вашого додатку."
+
+#: views/compatibility/dashboard.thtml:133
+#: views/compatibility/developers.thtml:55
+msgid "compatibility_developers_results"
+msgstr "Результати перевірки Ñтану додатків"
+
+#: views/compatibility/dashboard.thtml:137
+msgid "compatibility_developers_retrieving"
+msgstr "ÐžÑ‚Ñ€Ð¸Ð¼Ð°Ð½Ð½Ñ Ñтану розміщених додатків..."
+
+#. %1$s is a number
+#. %2$s is an application name
+#. %3$s is a number.
+#. Full example: 50 Firefox users (10% of total)
+#: views/compatibility/developers.thtml:65
+msgid "compatibility_developers_user_count"
+msgstr "%1$s кориÑтувачів %2$s users (%3$s&#37; від загальної кількоÑÑ‚Ñ–)"
+
+#: views/compatibility/report.thtml:45
+msgid "compatibility_report_detail_intro"
+msgstr ""
+"Подані нижче додатки разом, наÑкільки відомо Mozilla, Ñкладають 95% від "
+"загального викориÑтаннÑ; Ñ—Ñ… відÑортовано за мірою викориÑтаннÑ."
+
+#: views/compatibility/dashboard.thtml:94
+msgid "compatibility_report_detailed_link"
+msgstr "Показати детальний звіт"
+
+#. %1$s and %2$s are numbers
+#. %3$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:65
+msgid "compatibility_report_intro"
+msgstr ""
+"Із %1$s додатків, Ñкі Ñкладають 95&#37; від загального відомого Mozilla "
+"викориÑтаннÑ, <b>%2$s&#37;</b> вважаютьÑÑ ÑуміÑними з найновішими збірками %3"
+"$s."
+
+#: views/compatibility/dashboard.thtml:81
+msgid "compatibility_report_legend_alpha"
+msgstr "Ðльфа-верÑÑ–Ñ"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:81
+msgid "compatibility_report_legend_alpha_description"
+msgstr "Додатки, ÑуміÑні з альфа-верÑією %1$s"
+
+#: views/compatibility/dashboard.thtml:85
+msgid "compatibility_report_legend_beta"
+msgstr "Бета-верÑÑ–Ñ"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:85
+msgid "compatibility_report_legend_beta_description"
+msgstr "Додатки, ÑуміÑні з бета-верÑією чи з реліз-кандидатом %1$s"
+
+#: views/compatibility/dashboard.thtml:89
+msgid "compatibility_report_legend_latest"
+msgstr "Ðайновіша верÑÑ–Ñ"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:89
+msgid "compatibility_report_legend_latest_description"
+msgstr "Додатки, ÑуміÑні з найновішими збірками %1$s"
+
+#: views/compatibility/dashboard.thtml:77
+msgid "compatibility_report_legend_other"
+msgstr "Інші верÑÑ–Ñ—"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:77
+msgid "compatibility_report_legend_other_description"
+msgstr "Додатки, не ÑуміÑні з жодною верÑією %1$s"
+
+#: views/compatibility/dashboard.thtml:62
+msgid "compatibility_report_title"
+msgstr "Звіт про ÑуміÑніÑÑ‚ÑŒ додатків"
+
+#: views/compatibility/dashboard.thtml:54
+#: views/compatibility/dashboard.thtml:144 views/compatibility/users.thtml:42
+msgid "compatibility_user_info"
+msgstr "Ð†Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ñ–Ñ Ð´Ð»Ñ ÐºÐ¾Ñ€Ð¸Ñтувачів додатку"
+
+#: views/compatibility/dashboard.thtml:52
+msgid "compatibility_view_report"
+msgstr "Показати звіт про ÑуміÑніÑÑ‚ÑŒ"
+
+#. %s is a URL
+#: views/pages/credits.thtml:142
+#, php-format
+msgid "credits_contributing"
+msgstr "Ð”Ð»Ñ Ñ–Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ñ–Ñ— щодо внеÑку, будь лаÑка, завітайте на нашу %s."
+
+#: views/pages/credits.thtml:142
+msgid "credits_contributing_wikipage"
+msgstr "вікі-Ñторінку"
+
+#: views/pages/credits.thtml:99
+msgid "credits_intro"
+msgstr ""
+"Mozilla хотіла б подÑкувати наÑтупним людÑм за їхні внеÑки у проект addons."
+"mozilla.org впродовж років:"
+
+#: views/pages/credits.thtml:103
+msgid "credits_section_developers"
+msgstr "Розробники"
+
+#: views/pages/credits.thtml:115
+msgid "credits_section_editors"
+msgstr "Редактори"
+
+#: views/pages/credits.thtml:109
+msgid "credits_section_localizers"
+msgstr "Перекладачі"
+
+#: views/pages/credits.thtml:121
+msgid "credits_section_other_contributors"
+msgstr "Інші помічники"
+
+#: views/pages/credits.thtml:127
+msgid "credits_section_past_developers"
+msgstr "Минулі розробники"
+
+#: views/pages/credits.thtml:133
+msgid "credits_section_software"
+msgstr "Програми та зображеннÑ"
+
+#: views/pages/credits.thtml:136
+msgid "credits_software_famfamfam"
+msgstr ""
+"ДеÑкі іконки взÑто з <a href=\"http://www.famfamfam.com/lab/icons/silk/"
+"\">famfamfam Silk Icon Set</a>, доÑтупні за ліцензією<a href=\"http://"
+"creativecommons.org/licenses/by/2.5/\">Creative Commons Attribution 2.5 </a>."
+
+#: views/pages/credits.thtml:137
+#, fuzzy
+msgid "credits_software_timeplot"
+msgstr ""
+"Some pages use elements of <a href=\"http://www.simile-widgets.org/timeplot/"
+"\">Timeplot</a>, licensed under a <a href=\"http://simile.mit.edu/license."
+"html\">BSD License</a>."
+
+#. date format string as used in PHP's strftime():
+#. http://php.net/strftime
+#: views/elements/collections_interactive_addon.thtml:85
+#: views/elements/amo2009/addon_version_detail.thtml:53
+#: views/elements/amo2009/homepage_addon.thtml:115
+#: views/elements/addon_version_detail.thtml:54
+#: views/elements/addon_listitem.thtml:124 views/elements/feature.thtml:106
+#: views/collections/detail.thtml:118 views/collections/edit.thtml:325
+#: views/users/info.thtml:76 views/editors/reviews_queue.thtml:57
+#: views/editors/reviews_queue.thtml:68 views/developers/dashboard.thtml:65
+#: views/developers/versions_edit.thtml:208 views/developers/versions.thtml:67
+#: views/search/rss/index.thtml:5 views/addons/rss/versions.thtml:42
+#: views/addons/display.thtml:104 views/addons/display.thtml:356
+#: views/addons/browse_thumbs.thtml:75 views/reviews/add.thtml:63
+#: views/reviews/display.thtml:74 views/reviews/display.thtml:160
+#: views/reviews/delete.thtml:54 controllers/statistics_controller.php:244
+#: controllers/collections_controller.php:1047
+msgid "date"
+msgstr "%e %b %Y"
+
+#. date and time format string (strftime)
+#. http://php.net/strftime
+#: views/elements/addon_version_detail.thtml:53
+#: views/developers/discuss.thtml:52 views/developers/discuss.thtml:62
+#: views/admin/addons_status.thtml:57
+msgid "datetime"
+msgstr "%e %b %Y, %H:%M"
+
+#: views/elements/developers/actionbar.thtml:47
+msgid "devcp_actionbar_link_details"
+msgstr "Докладна інформаціÑ"
+
+#: views/elements/developers/actionbar.thtml:42
+#: views/elements/developers/actionbar.thtml:50
+#: views/developers/dashboard.thtml:64
+msgid "devcp_actionbar_link_edit"
+msgstr "Редагувати додаток"
+
+#: views/elements/developers/actionbar.thtml:51
+msgid "devcp_actionbar_link_newversion"
+msgstr "Відвантажити нову верÑÑ–ÑŽ"
+
+#: views/elements/developers/actionbar.thtml:44
+#: views/elements/developers/actionbar.thtml:49
+#: views/developers/dashboard.thtml:73
+msgid "devcp_actionbar_link_stats"
+msgstr "Панель ÑтатиÑтики"
+
+#. %1$s is a filename, e.g. "foo.txt"
+#. %2$s is the extension, e.g. ".txt"
+#. %3$s is a list of valid extensions, like ".png, .jpg, .gif"
+#: controllers/developers_controller.php:1361
+msgid "devcp_add_previews_extension_error"
+msgstr "Файл %1$s має недійÑне Ñ€Ð¾Ð·ÑˆÐ¸Ñ€ÐµÐ½Ð½Ñ (2$s). Дозволені розширеннÑ: %3$s"
+
+#. %s is the filename.
+#: controllers/developers_controller.php:1394
+msgid "devcp_add_previews_save_error"
+msgstr ""
+"Ðе вдалоÑÑ Ð·Ð±ÐµÑ€ÐµÐ³Ñ‚Ð¸ файл %s у базі даних. Спробуйте ще раз, будь лаÑка."
+
+#. %1$s is the preview ID number, %2$s is the filename.
+#: controllers/developers_controller.php:1389
+msgid "devcp_add_previews_success_replace"
+msgstr "Файл попереднього переглÑду %1$s було з уÑпіхом замінено файлом %2$s."
+
+#. %s is the filename.
+#: controllers/developers_controller.php:1391
+msgid "devcp_add_previews_success_upload"
+msgstr "Файл %s уÑпішно завантажено. Ðижче можна дати йому заголовок."
+
+#: controllers/components/developers.php:1163
+msgid "devcp_additem_addontype_autodetect"
+msgstr "(автовизначеннÑ)"
+
+#: views/elements/developers/additem.thtml:76
+msgid "devcp_additem_linktitle_opensin_newwindow"
+msgstr "Відкриває нове вікно"
+
+#: views/elements/developers/additem.thtml:41
+msgid "devcp_additem_sidebar_title"
+msgstr "ЗаÑлати додаток"
+
+#: views/elements/developers/additem.thtml:53
+msgid "devcp_additem_step0_newlink"
+msgstr "Угода з розробником"
+
+#: views/elements/developers/additem.thtml:46
+msgid "devcp_additem_step1_link"
+msgstr "Крок 1: ВивантаженнÑ"
+
+#: views/elements/developers/additem.thtml:47
+msgid "devcp_additem_step2_link"
+msgstr "Крок 2: Подробиці додатку"
+
+#: views/elements/developers/additem.thtml:48
+msgid "devcp_additem_step3_link"
+msgstr "Крок 3: Подробиці верÑÑ–Ñ—"
+
+#: views/elements/developers/additem.thtml:49
+msgid "devcp_additem_step4_link"
+msgstr "Крок 4: Переклади"
+
+#: views/elements/developers/additem.thtml:50
+msgid "devcp_additem_step5_link"
+msgstr "Крок 5: УÑпіх"
+
+#: views/elements/developers/additem.thtml:76
+msgid "devcp_additem_submissionhelp_link"
+msgstr "Підказка з подаваннÑ"
+
+#: controllers/previews_controller.php:168
+#: controllers/previews_controller.php:277
+msgid "devcp_addon_field_preview_caption_displaytitle"
+msgstr "ПереглÑд заголовку"
+
+#: views/developers/addon_status.thtml:177
+msgid "devcp_addon_status_action_activate"
+msgstr "Зробити активним"
+
+#: views/developers/addon_status.thtml:178
+msgid "devcp_addon_status_action_activate_description"
+msgstr ""
+"Зробити додаток активним, внаÑлідок чого він з’ÑвитьÑÑ Ñƒ публічних ÑпиÑках, "
+"а Ñлужбу перевірки його оновлень буде запущено."
+
+#: views/developers/addon_status.thtml:135
+msgid "devcp_addon_status_action_complete"
+msgstr "Завершити додаток"
+
+#: views/developers/addon_status.thtml:136
+msgid "devcp_addon_status_action_complete_description"
+msgstr "Завершити ваш додаток Ñ– перенеÑти його до ПіÑочниці"
+
+#: views/developers/addon_status.thtml:181
+msgid "devcp_addon_status_action_deactivate"
+msgstr "Зробити неактивним"
+
+#: views/developers/addon_status.thtml:182
+msgid "devcp_addon_status_action_deactivate_description"
+msgstr ""
+"Зробити ваш додаток неактивним Ð´Ð»Ñ Ñ‚Ð¾Ð³Ð¾, щоб Ñховати його з публічних "
+"ÑпиÑків Ñ– вимкнути Ð´Ð»Ñ Ð½ÑŒÐ¾Ð³Ð¾ Ñлужбу перевірки оновлень."
+
+#: views/developers/addon_status.thtml:143
+msgid "devcp_addon_status_action_move"
+msgstr "ПеренеÑти до ПіÑочниці"
+
+#: views/developers/addon_status.thtml:144
+msgid "devcp_addon_status_action_move_description"
+msgstr "ПеренеÑти ваш додаток назад до ПіÑочниці. Цю дію не можна ÑкаÑувати."
+
+#: views/developers/addon_status.thtml:139
+msgid "devcp_addon_status_action_nominate"
+msgstr "Подати в загальнодоÑтупні"
+
+#: views/developers/addon_status.thtml:140
+msgid "devcp_addon_status_action_nominate_description"
+msgstr "ВиÑунути ваш додаток у кандидати в категорію загальнодоÑтупних"
+
+#: views/developers/addon_status.thtml:147
+msgid "devcp_addon_status_action_public"
+msgstr "Зробити загальнодоÑтупним"
+
+#: views/developers/addon_status.thtml:148
+msgid "devcp_addon_status_action_public_description"
+msgstr "Знову зробити ваш додаток загальнодоÑтупним."
+
+#: views/developers/addon_status.thtml:169
+msgid "devcp_addon_status_active"
+msgstr ""
+"Ваш додаток <span class=\"inactive-0\">активний</span>. Це означає, що "
+"йогоможна побачити в уÑÑ–Ñ… ÑпиÑках, відповідних його Ñтанові."
+
+#: views/developers/addon_status.thtml:111
+msgid "devcp_addon_status_completion_disabled"
+msgstr ""
+"Приведіть, будь лаÑка, ваш додаток до вимог, наведених вище, перш ніж "
+"переводити його до <span class=\"status-1\">ПіÑочниці</span>."
+
+#: views/developers/addon_status.thtml:108
+msgid "devcp_addon_status_completion_enabled"
+msgstr ""
+"Тепер ви можете завершити ваш додаток Ñ– перенеÑти його до <span class="
+"\"status-1\">ПіÑочниці</span> одним натиÑком кнопки, розташованої нижче."
+
+#: views/developers/addon_status.thtml:102
+msgid "devcp_addon_status_criteria_category"
+msgstr "Обрано хоча б одну категорію"
+
+#: views/developers/addon_status.thtml:101
+msgid "devcp_addon_status_criteria_description"
+msgstr "Ðеобхідний Ð¾Ð¿Ð¸Ñ Ð´Ð¾Ð´Ð°Ñ‚ÐºÑƒ"
+
+#: views/developers/addon_status.thtml:99
+msgid "devcp_addon_status_criteria_name"
+msgstr "Ðеобхідне Ñ–Ð¼â€™Ñ Ð´Ð¾Ð´Ð°Ñ‚ÐºÑƒ"
+
+#: views/developers/addon_status.thtml:120
+msgid "devcp_addon_status_criteria_prerelease"
+msgstr "Додаток не помічено Ñк попередній реліз."
+
+#: views/developers/addon_status.thtml:119
+msgid "devcp_addon_status_criteria_preview"
+msgstr ""
+"Ð”Ð»Ñ Ñ‚ÐµÐ¼ та розширень необхідне хоча б одне Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ Ð¿Ð¾Ð¿ÐµÑ€ÐµÐ´Ð½ÑŒÐ¾Ð³Ð¾ переглÑду."
+
+#: views/developers/addon_status.thtml:100
+msgid "devcp_addon_status_criteria_summary"
+msgstr "Ðеобхідне резюме додатку"
+
+#. %s is the status in a span, e.g. "<span>_('Public')</span>".
+#: views/developers/addon_status.thtml:58
+msgid "devcp_addon_status_header"
+msgstr "Стан додатку: %s"
+
+#: views/developers/addon_status.thtml:152
+#: views/developers/addon_status.thtml:173
+msgid "devcp_addon_status_header_actions"
+msgstr "Можливі дії"
+
+#: views/developers/addon_status.thtml:168
+msgid "devcp_addon_status_header_active"
+msgstr "Стан активноÑÑ‚Ñ–: <span class=\"inactive-0\">Ðктивний</span>"
+
+#: views/developers/addon_status.thtml:97
+msgid "devcp_addon_status_header_criteria"
+msgstr "Умови завершеноÑÑ‚Ñ– додатку"
+
+#: views/developers/addon_status.thtml:164
+msgid "devcp_addon_status_header_inactive"
+msgstr "Стан активноÑÑ‚Ñ–: <span class=\"inactive-1\">Ðеактивний</span>"
+
+#: views/developers/addon_status.thtml:117
+msgid "devcp_addon_status_header_nomination"
+msgstr "Умови виÑÑƒÐ½ÐµÐ½Ð½Ñ Ð² кандидати до загальнодоÑтупних"
+
+#: views/developers/addon_status.thtml:190
+msgid "devcp_addon_status_header_trusted"
+msgstr "Стан довіри: <span class=\"status-4\">Можна довірÑти</span>"
+
+#: views/developers/addon_status.thtml:165
+msgid "devcp_addon_status_inactive"
+msgstr ""
+"Ваш додаток зараз <span class=\"inactive-1\">неактивний</span>. Це означає, "
+"що йогоне можна побачити в жодному ÑпиÑку незалежно від його Ñтану. "
+"ÐžÐ½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ñ‡ÐµÑ€ÐµÐ· Ñлужбу Ð¾Ð½Ð¾Ð²Ð»ÐµÐ½ÑŒÐ´Ð»Ñ Ð½ÑŒÐ¾Ð³Ð¾ <b>не</b> надаютьÑÑ."
+
+#: views/developers/addon_status.thtml:128
+msgid "devcp_addon_status_nominate_disabled"
+msgstr ""
+"Приведіть, будь лаÑка, ваш додаток до наÑтупних умов, перш ніж виÑувати його "
+"в кандидати до <span class=\"status-4\">загальнодоÑтупних</span>."
+
+#: views/developers/addon_status.thtml:125
+msgid "devcp_addon_status_nominate_enabled"
+msgstr ""
+"Тепер ви можете виÑунути ваш додаток у кандидати до <span class=\"status-4"
+"\">загальнодоÑтупних</span>, натиÑнувши кнопку нижче."
+
+#: views/developers/addon_status.thtml:64
+msgid "devcp_addon_status_public"
+msgstr "ЗагальнодоÑтупний"
+
+#: views/developers/addon_status.thtml:63
+msgid "devcp_addon_status_sandbox"
+msgstr "ПіÑочницÑ"
+
+#. %s is an email address.
+#: views/developers/addon_status.thtml:89
+msgid "devcp_addon_status_switch_disabled"
+msgstr ""
+"Ваш додаток було <span class=\"status-5\">заблоковано</span> "
+"адмініÑтратором; ним не можна кориÑтуватиÑÑ. Якщо ви маєте питаннÑ, "
+"надішліть електронного лиÑта на адреÑу %s."
+
+#: views/developers/addon_status.thtml:67
+#, fuzzy
+msgid "devcp_addon_status_switch_incomplete"
+msgstr ""
+"Your add-on is currently <span class=\"status-0\">Incomplete</span>. This "
+"means your add-on is not showing up on any portion of the site or update "
+"check service. You may come to this page to complete your add-on after it "
+"meets the criteria below for completion and transfer to the <span class="
+"\"status-1\">Sandbox</span>."
+
+#. %s is a number, perhaps 42.
+#: views/developers/addon_status.thtml:77
+#, fuzzy
+msgid "devcp_addon_status_switch_nominated"
+msgstr ""
+"Your add-on is currently nominated to become <span class=\"status-4"
+"\">Public</span> and is awaiting editor review. There are currently %s other "
+"add-ons in the nomination queue."
+
+#. %s is an email address.
+#: views/developers/addon_status.thtml:81
+#, fuzzy
+msgid "devcp_addon_status_switch_pending"
+msgstr ""
+"Your add-on is pending. This shouldn't have happened. Please e-mail %s with "
+"your add-on ID and state this error."
+
+#: views/developers/addon_status.thtml:85
+#, fuzzy
+msgid "devcp_addon_status_switch_public"
+msgstr ""
+"Your add-on is <span class=\"status-4\">Public</span>, which means it will "
+"show up in all listings and searches and can be downloaded without "
+"restriction. Updates are being provided to your add-on through the update "
+"check service."
+
+#: views/developers/addon_status.thtml:71
+#: views/developers/addon_status.thtml:75
+#, fuzzy
+msgid "devcp_addon_status_switch_sandbox"
+msgstr ""
+"Your add-on is in the <span class=\"status-1\">Sandbox</span>, which means "
+"it will show up in listings and searches, but users must log in to download "
+"it. Updates are <b>not</b> being provided to your add-on through the update "
+"check service."
+
+#. %s is the add-on name.
+#: views/developers/addon_status_nominate.thtml:43
+#: views/developers/addon_status_confirm.thtml:43
+#: views/developers/addon_status.thtml:43
+#, fuzzy
+msgid "devcp_addon_status_title"
+msgstr "%s Status"
+
+#: views/developers/addon_status.thtml:191
+#, fuzzy
+msgid "devcp_addon_status_trusted"
+msgstr ""
+"Your add-on is <span class=\"status-4\">Trusted</span>. This means you can "
+"submit updates to your add-on without editor review."
+
+#: views/developers/dashboard.thtml:68
+#, fuzzy
+msgid "devcp_dashboard_active"
+msgstr "Active"
+
+#. %1$s is the add-on type string
+#. %2$s is Inactive or Active in a <span>
+#. %3$s is the addon's public status (Public, In Sandbox, ...) in a <span>
+#: views/developers/dashboard.thtml:69
+#, fuzzy
+msgid "devcp_dashboard_addontype_status"
+msgstr "%1$s currenty %2$s and %3$s"
+
+#: views/developers/dashboard.thtml:67
+#, fuzzy
+msgid "devcp_dashboard_change_status"
+msgstr "Change Status"
+
+#. %s is the addons email address.
+#: views/developers/dashboard.thtml:99
+#, fuzzy
+msgid "devcp_dashboard_disabled_questions"
+msgstr ""
+"Your add-on was disabled by an administrator and cannot be used. If you "
+"have any questions, please email %s."
+
+#. %s is the (localized) add-on status string in a span, e.g. "Disabled"
+#: views/developers/dashboard.thtml:98
+#, fuzzy
+msgid "devcp_dashboard_disabled_status"
+msgstr "Add-on Status: %s"
+
+#: views/developers/dashboard.thtml:43
+#, fuzzy
+msgid "devcp_dashboard_header_main"
+msgstr "Developer Dashboard"
+
+#: views/developers/dashboard.thtml:110
+#, fuzzy
+msgid "devcp_dashboard_header_welcome"
+msgstr "Welcome to the Developer Dashboard"
+
+#: views/developers/dashboard.thtml:68
+#, fuzzy
+msgid "devcp_dashboard_inactive"
+msgstr "Inactive"
+
+#. %s is a date in the _('date') format
+#: views/developers/dashboard.thtml:65
+#, fuzzy
+msgid "devcp_dashboard_last_edited"
+msgstr "Last edited on %s"
+
+#: views/developers/dashboard.thtml:111
+#, fuzzy
+msgid "devcp_dashboard_learn"
+msgstr ""
+"You don't currently have any add-ons hosted on Mozilla Add-ons. To learn how "
+"the process works and submit your first add-on, click Get Started below."
+
+#: views/developers/dashboard.thtml:112
+#, fuzzy
+msgid "devcp_dashboard_start"
+msgstr "Get Started"
+
+#: views/developers/dashboard.thtml:82
+#, fuzzy
+msgid "devcp_dashboard_versions"
+msgstr "Versions and Files"
+
+#: views/developers/dashboard.thtml:91
+#, fuzzy
+msgid "devcp_dashboard_versions_new"
+msgstr "Upload a new version"
+
+#. %s is the preview ID number.
+#: controllers/developers_controller.php:1415
+#, fuzzy
+msgid "devcp_delete_previews_error"
+msgstr "Preview %s could not be deleted from the database. Please try again."
+
+#. %s is the preview ID number.
+#: controllers/developers_controller.php:1413
+#, fuzzy
+msgid "devcp_delete_previews_success"
+msgstr "Preview %s has been deleted successfully."
+
+#: controllers/developers_controller.php:1089
+#, fuzzy
+msgid "devcp_delete_version_priv_error"
+msgstr "You do not have privileges to delete versions or files."
+
+#. %1$s is the count of files, a number
+#. %2$s is a status string like _('Public') or _('Incomplete')
+#: controllers/components/amo.php:549
+#, fuzzy
+msgid "devcp_describe_version_status"
+msgid_plural "devcp_describe_version_status"
+msgstr[0] "%1$s %2$s file"
+msgstr[1] "%1$s %2$s files"
+
+#. %s is a version number. Example: 3.0
+#: views/developers/versions.thtml:65
+#, php-format
+msgid "devcp_details_version"
+msgstr "ВерÑÑ–Ñ %s"
+
+#: views/developers/discuss.thtml:68
+#, fuzzy
+msgid "devcp_discuss_addreply_header"
+msgstr "Add Reply"
+
+#: views/developers/discuss.thtml:57
+#, fuzzy
+msgid "devcp_discuss_allreplies_header"
+msgstr "Replies"
+
+#. notice when an error occurs saving a discussion reply
+#. %1 is the email address (linked) for the amo-editors list
+#: views/developers/discuss.thtml:70
+#, fuzzy
+msgid "devcp_discuss_error_notice"
+msgstr ""
+"There was an error saving your reply. Please contact %1$s about the issue."
+
+#. %1 is the add-on name, %2 is the add-on's version number currently being reviewed by an editor
+#: views/developers/discuss.thtml:46
+#, fuzzy
+msgid "devcp_discuss_intro"
+msgstr ""
+"A Mozilla Add-ons Editor requested further information from you regarding "
+"version %2$s of your add-on %1$s."
+
+#. %1 is the add-on name
+#: views/developers/discuss.thtml:43
+#, fuzzy
+msgid "devcp_discuss_pagetitle"
+msgstr "Provide More Information For the Add-on Review of %1$s"
+
+#. submit button text
+#: views/developers/discuss.thtml:79
+#, fuzzy
+msgid "devcp_discuss_submit_reply"
+msgstr "Submit Reply"
+
+#: views/developers/discuss.thtml:72
+#, fuzzy
+msgid "devcp_discuss_success_message"
+msgstr ""
+"Your reply was successfully saved. The other participants of the discussion "
+"will be notified by email."
+
+#. in an author/editor discussion about an add-on to be reviewed:
+#. %1 is the commenter's user name (linked).
+#. %2 is the full date the comment was made.
+#: views/developers/discuss.thtml:52 views/developers/discuss.thtml:62
+#, fuzzy
+msgid "devcp_discuss_writtenby"
+msgstr "written by %1$s on %2$s"
+
+#: views/developers/addon_edit_authors.thtml:72
+#: views/developers/addon_edit_authors.thtml:81
+#, fuzzy
+msgid "devcp_edit_authors_add_author"
+msgstr "Add New Author"
+
+#: views/developers/addon_edit_authors.thtml:96
+#, fuzzy
+msgid "devcp_edit_authors_add_author_button"
+msgstr "Add Author"
+
+#: views/developers/addon_edit_authors.thtml:83
+#, fuzzy
+msgid "devcp_edit_authors_add_email"
+msgstr "Author Account Email:"
+
+#: views/developers/addon_edit_authors.thtml:98
+#, fuzzy
+msgid "devcp_edit_authors_add_loading"
+msgstr "Checking account email..."
+
+#: views/developers/addon_edit_authors.thtml:70
+#, fuzzy
+msgid "devcp_edit_authors_click_save"
+msgstr "Click the Update Authors button below to save."
+
+#: views/developers/addon_edit_authors.thtml:58
+#, fuzzy
+msgid "devcp_edit_authors_header_current"
+msgstr "Current Authors"
+
+#: views/developers/addon_edit_authors.thtml:50
+#, fuzzy
+msgid "devcp_edit_authors_header_manage"
+msgstr "Manage Add-on Authors"
+
+#: views/developers/addon_edit_authors.thtml:93
+#, fuzzy
+msgid "devcp_edit_authors_label_add_listed"
+msgstr "List as author in pubilc display pages"
+
+#: views/developers/addon_edit_authors.thtml:89
+#, fuzzy
+msgid "devcp_edit_authors_label_developer"
+msgstr ""
+"<strong>Developer</strong> - Can manage all aspects of the add-on listing, "
+"except for adding and removing other authors."
+
+#: views/developers/addon_edit_authors.thtml:88
+#, fuzzy
+msgid "devcp_edit_authors_label_owner"
+msgstr ""
+"<strong>Owner</strong> - Can manage all aspects of the add-on listing, "
+"including adding and removing other authors."
+
+#: views/developers/addon_edit_authors.thtml:90
+#, fuzzy
+msgid "devcp_edit_authors_label_viewer"
+msgstr ""
+"<strong>Viewer</strong> - Can view add-on developer listing and statistics, "
+"but can't make any changes."
+
+#. Placeholder for the empty option in a <select>.
+#: views/developers/addon_edit_categories.thtml:69
+#, fuzzy
+msgid "devcp_edit_authors_option_empty"
+msgstr "----------------"
+
+#: views/developers/addon_edit_authors.thtml:86
+#, fuzzy
+msgid "devcp_edit_authors_select_role"
+msgstr "Select a role for the author:"
+
+#. Column name in a table.
+#: views/developers/addon_edit_authors.thtml:62
+#, fuzzy
+msgid "devcp_edit_authors_th_author"
+msgstr "Author"
+
+#. Column name in a table.
+#: views/developers/addon_edit_authors.thtml:64
+#, fuzzy
+msgid "devcp_edit_authors_th_listed"
+msgstr "Listed"
+
+#. Column name in a table.
+#: views/developers/addon_edit_authors.thtml:63
+#, fuzzy
+msgid "devcp_edit_authors_th_role"
+msgstr "Role"
+
+#: views/developers/addon_edit_authors.thtml:77
+#, fuzzy
+msgid "devcp_edit_authors_update_author"
+msgstr "Update authors"
+
+#: views/developers/addon_edit_categories.thtml:99
+#, fuzzy
+msgid "devcp_edit_categories_button_update"
+msgstr "Update Categories"
+
+#: views/developers/addon_edit_categories.thtml:88
+#, fuzzy
+msgid "devcp_edit_categories_does_not_fit"
+msgstr "My add-on doesn't fit into any available categories."
+
+#. %s is the application name (Firefox, Thunderbird).
+#: views/developers/addon_edit_categories.thtml:61
+#, fuzzy
+msgid "devcp_edit_categories_header_application"
+msgstr "%s Categories"
+
+#: views/developers/addon_edit_categories.thtml:49
+#, fuzzy
+msgid "devcp_edit_categories_header_manage"
+msgstr "Manage Add-on Categories"
+
+#: views/developers/addon_edit_categories.thtml:91
+#, fuzzy
+msgid "devcp_edit_categories_hover"
+msgstr "Hover over a category to see its description."
+
+#. %s is the category number (1, 2, 3).
+#: views/developers/addon_edit_categories.thtml:67
+#, fuzzy
+msgid "devcp_edit_categories_label_category_num"
+msgstr "Category %s"
+
+#: views/developers/addon_edit_categories.thtml:94
+#: views/developers/addon_edit_categories.thtml:103
+#, fuzzy
+msgid "devcp_edit_categories_none_available"
+msgstr "No categories are available for this add-on type and application."
+
+#: views/developers/addon_edit_categories.thtml:86
+#, fuzzy
+msgid "devcp_edit_categories_other"
+msgstr ""
+"Place your add-on into this category only if it does not fit into any other "
+"available categories."
+
+#. %s is the application name (Firefox, Thunderbird).
+#: views/developers/addon_edit_categories.thtml:63
+#, fuzzy
+msgid "devcp_edit_categories_select_application_categories"
+msgstr "Select up to three %s categories for your add-on"
+
+#: views/developers/addon_edit.thtml:47
+#, fuzzy
+msgid "devcp_edit_dd_manage_authors"
+msgstr "Add or remove users that can manage this add-on."
+
+#: views/developers/addon_edit.thtml:49
+#, fuzzy
+msgid "devcp_edit_dd_manage_categories"
+msgstr ""
+"Select the relevant categories for each application your add-on supports."
+
+#: views/developers/addon_edit.thtml:51
+#, fuzzy
+msgid "devcp_edit_dd_manage_description"
+msgstr ""
+"Add and modify translations for your add-on's summary, description, end-user "
+"license, and privacy policy."
+
+#: views/developers/addon_edit.thtml:53
+#, fuzzy
+msgid "devcp_edit_dd_manage_properties"
+msgstr "Change your add-on's name, homepage, icon, and other flags."
+
+#: views/developers/addon_edit_descriptions.thtml:116
+#, fuzzy
+msgid "devcp_edit_description_button_update"
+msgstr "Update Descriptions"
+
+#: views/developers/addon_edit_descriptions.thtml:115
+#, fuzzy
+msgid "devcp_edit_description_correct_error"
+msgstr "Please correct the errors above indicated in red."
+
+#: views/developers/addon_edit_descriptions.thtml:51
+#, fuzzy
+msgid "devcp_edit_descriptions_header"
+msgstr "Edit Add-on Descriptions"
+
+#: views/developers/addon_edit_descriptions.thtml:94
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_comments_description"
+msgstr ""
+"Any information end users may want to know that isn't necessarily applicable "
+"to the add-on summary or description. Common uses include listing known "
+"major bugs, information on how to report bugs, anticipated release date of a "
+"new version, etc."
+
+#: views/developers/addon_edit_descriptions.thtml:93
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_comments_name"
+msgstr "Developer Comments"
+
+#: views/developers/addon_edit_descriptions.thtml:86
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_description_description"
+msgstr ""
+"The description of your add-on is a longer explanation of features, "
+"functionality, and other relevant information. It is displayed under the "
+"summary on the add-on's display page."
+
+#: views/developers/addon_edit_descriptions.thtml:85
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_description_name"
+msgstr "Add-on Description"
+
+#: views/developers/addon_edit_descriptions.thtml:103
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_eula_description"
+msgstr ""
+"If your add-on has an End-User License Agreement (EULA), please enter its "
+"text below. If set below, users will be required to agree to this before "
+"installing your add-on. Please note that a EULA is not the same as a code "
+"license such as GPL or MPL."
+
+#: views/developers/addon_edit_descriptions.thtml:102
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_eula_name"
+msgstr "End-User License Agreement"
+
+#: views/developers/addon_edit_descriptions.thtml:112
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_privacy_description"
+msgstr ""
+"If your add-on has a privacy policy, enter its text here. Your add-on's "
+"display page will display a link to the policy."
+
+#: views/developers/addon_edit_descriptions.thtml:111
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_privacy_name"
+msgstr "Privacy Policy"
+
+#: views/developers/addon_edit_descriptions.thtml:78
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_summary_description"
+msgstr ""
+"The summary is a short explanation of your add-on's basic functionality that "
+"is displayed in search and browse listings, as well as at the top of your "
+"add-on's display page. <strong>Limit of 250 characters.</strong>"
+
+#: views/developers/addon_edit_descriptions.thtml:77
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_summary_name"
+msgstr "Add-on Summary"
+
+#: views/developers/addon_edit.thtml:46
+#, fuzzy
+msgid "devcp_edit_dt_manage_authors"
+msgstr "Manage Add-on Authors"
+
+#: views/developers/addon_edit.thtml:48
+#, fuzzy
+msgid "devcp_edit_dt_manage_categories"
+msgstr "Manage Add-on Categories"
+
+#: views/developers/addon_edit.thtml:50
+#, fuzzy
+msgid "devcp_edit_dt_manage_descriptions"
+msgstr "Manage Add-on Descriptions"
+
+#: views/developers/addon_edit.thtml:52
+#, fuzzy
+msgid "devcp_edit_dt_manage_properties"
+msgstr "Manage Add-on Properties"
+
+#: views/developers/addon_edit_properties.thtml:170
+msgid "devcp_edit_label_externalsoftware"
+msgstr "Цей додаток потребує зовнішніх програм"
+
+#: views/developers/addon_edit_properties.thtml:205
+msgid "devcp_edit_label_locale_disambiguation"
+msgstr "Additional Locale Info"
+
+#: views/developers/addon_edit_properties.thtml:168
+msgid "devcp_edit_label_prerelease"
+msgstr "Це попередній випуÑк"
+
+#: views/developers/addon_edit_properties.thtml:169
+msgid "devcp_edit_label_sitespecific"
+msgstr "Це додаток Ð´Ð»Ñ Ð¾ÐºÑ€ÐµÐ¼Ð¾Ð³Ð¾ Ñайту"
+
+#: views/developers/addon_edit_properties.thtml:202
+msgid "devcp_edit_label_target_locale"
+msgstr "Target Locale"
+
+#: views/developers/addon_edit_properties.thtml:212
+#, fuzzy
+msgid "devcp_edit_properties_button_update"
+msgstr "Update Properties"
+
+#: views/developers/addon_edit_properties.thtml:198
+#, fuzzy
+msgid "devcp_edit_properties_change_guid"
+msgstr "Only change if you understand all of the consequences."
+
+#: views/developers/addon_edit_properties.thtml:109
+#, fuzzy
+msgid "devcp_edit_properties_current_icon"
+msgstr "Current Icon"
+
+#: views/developers/addon_edit_properties.thtml:85
+#, fuzzy
+msgid "devcp_edit_properties_default_locale"
+msgstr ""
+"An add-on's default locale is the main locale in which translations must be "
+"present. If translations for your add-on's descriptions are unavailable in a "
+"user's selected language, they will fall back to this default locale."
+
+#: views/developers/addon_edit_properties.thtml:167
+#, fuzzy
+msgid "devcp_edit_properties_flags"
+msgstr "These flags are used to filter and classify add-ons."
+
+#: views/developers/addon_edit_properties.thtml:174
+#, fuzzy
+msgid "devcp_edit_properties_guid"
+msgstr ""
+"The GUID of your add-on is specified in its install.rdf and uniquely "
+"identifies it. You cannot change your GUID once it is listed on Mozilla Add-"
+"ons."
+
+#: views/developers/addon_edit_properties.thtml:53
+#, fuzzy
+msgid "devcp_edit_properties_header"
+msgstr "Edit Add-on Properties"
+
+#: views/developers/addon_edit_properties.thtml:186
+#, fuzzy
+msgid "devcp_edit_properties_header_addon_type"
+msgstr "Add-on Type"
+
+#: views/developers/addon_edit_properties.thtml:181
+#, fuzzy
+msgid "devcp_edit_properties_header_admin_settings"
+msgstr "Admin Settings"
+
+#: views/developers/addon_edit_properties.thtml:84
+#, fuzzy
+msgid "devcp_edit_properties_header_default_locale"
+msgstr "Default Locale"
+
+#: views/developers/addon_edit_properties.thtml:166
+#, fuzzy
+msgid "devcp_edit_properties_header_flags"
+msgstr "Add-on Flags"
+
+#: views/developers/addon_edit_properties.thtml:173
+#: views/developers/addon_edit_properties.thtml:197
+#, fuzzy
+msgid "devcp_edit_properties_header_guid"
+msgstr "Add-on GUID"
+
+#: views/developers/addon_edit_properties.thtml:104
+#, fuzzy
+msgid "devcp_edit_properties_header_icon"
+msgstr "Add-on Icon"
+
+#: views/developers/addon_edit_properties.thtml:159
+#, fuzzy
+msgid "devcp_edit_properties_header_other_settings"
+msgstr "Other Settings"
+
+#. A header on the admin page to toggle trusted status.
+#: views/developers/addon_edit_properties.thtml:182
+#, fuzzy
+msgid "devcp_edit_properties_header_trusted"
+msgstr "Trusted Add-on?"
+
+#: views/developers/addon_edit_properties.thtml:160
+#, fuzzy
+msgid "devcp_edit_properties_header_view_source"
+msgstr "View Source Online"
+
+#. %s is a comma-separated list of image extensions ".png, .jpg"
+#: views/developers/addon_edit_properties.thtml:106
+#, fuzzy
+msgid "devcp_edit_properties_icon"
+msgstr ""
+"The add-on icon is a small image that is displayed next to your add-on's "
+"name in browse and search results, display pages, and in the add-on "
+"installation dialog. The image will automatically be resized to 32 x 32 "
+"pixels. Please use one of the following image types: %s"
+
+#: views/developers/addon_edit_properties.thtml:171
+#, fuzzy
+msgid "devcp_edit_properties_label_binary"
+msgstr "This add-on contains binary components"
+
+#: views/developers/addon_edit_properties.thtml:185
+#, fuzzy
+msgid "devcp_edit_properties_label_not_trusted"
+msgstr "Not Trusted"
+
+#: views/developers/addon_edit_properties.thtml:184
+#, fuzzy
+msgid "devcp_edit_properties_label_trusted"
+msgstr "Trusted"
+
+#: views/developers/addon_edit_properties.thtml:110
+#, fuzzy
+msgid "devcp_edit_properties_new_icon"
+msgstr "New Icon"
+
+#: views/developers/addon_edit_properties.thtml:118
+#, fuzzy
+msgid "devcp_edit_properties_remove_icon"
+msgstr "Remove Icon"
+
+#: views/developers/addon_edit_properties.thtml:136
+#, fuzzy
+msgid "devcp_edit_properties_transbox_homepage_description"
+msgstr ""
+"If your add-on has another homepage, enter its address here. Adding other "
+"translations is not necessary unless your website is localized into other "
+"languages."
+
+#: views/developers/addon_edit_properties.thtml:135
+#, fuzzy
+msgid "devcp_edit_properties_transbox_homepage_name"
+msgstr "Add-on Homepage"
+
+#: views/developers/addon_edit_properties.thtml:79
+#, fuzzy
+msgid "devcp_edit_properties_transbox_name_description"
+msgstr "The name of your add-on is displayed everywhere your add-on is listed."
+
+#: views/developers/addon_edit_properties.thtml:78
+#, fuzzy
+msgid "devcp_edit_properties_transbox_name_name"
+msgstr "Add-on Name"
+
+#: views/developers/addon_edit_properties.thtml:145
+#, fuzzy
+msgid "devcp_edit_properties_transbox_supportemail_description"
+msgstr ""
+"If you have an email address for support inquiries, enter it here. Adding "
+"other translations is not necessary unless you have different email "
+"addresses for different languages."
+
+#: views/developers/addon_edit_properties.thtml:144
+#, fuzzy
+msgid "devcp_edit_properties_transbox_supportemail_name"
+msgstr "Support Email Address"
+
+#: views/developers/addon_edit_properties.thtml:154
+#, fuzzy
+msgid "devcp_edit_properties_transbox_supporturl_description"
+msgstr ""
+"If your add-on has a support website or forum, enter its address here. "
+"Adding other translations is not necessary unless your website is localized "
+"into other languages."
+
+#: views/developers/addon_edit_properties.thtml:153
+#, fuzzy
+msgid "devcp_edit_properties_transbox_supporturl_name"
+msgstr "Support Website"
+
+#: views/developers/addon_edit_properties.thtml:183
+#, fuzzy
+msgid "devcp_edit_properties_trusted"
+msgstr "Trusted add-ons can become public without Editor review."
+
+#. %s is href="..." and should stay in the <a> tag.
+#: views/developers/addon_edit_properties.thtml:119
+#, fuzzy
+msgid "devcp_edit_properties_undelete"
+msgstr "Icon will be deleted on save. <a %s>Cancel?</a>"
+
+#: views/developers/addon_edit_properties.thtml:161
+#, fuzzy
+msgid "devcp_edit_properties_view_source"
+msgstr ""
+"The source of your add-on files can be viewed online by any logged in user "
+"if you wish."
+
+#: views/developers/addon_edit_properties.thtml:162
+#, fuzzy
+msgid "devcp_edit_properties_view_source_allow"
+msgstr "Allow online source viewing"
+
+#: views/developers/addon_edit_properties.thtml:163
+#, fuzzy
+msgid "devcp_edit_properties_view_source_do_not_allow"
+msgstr "Do not allow online source viewing"
+
+#: views/elements/developers/editbox.thtml:46
+#, fuzzy
+msgid "devcp_editbox_authors"
+msgstr "Authors"
+
+#: views/elements/developers/editbox.thtml:47
+#, fuzzy
+msgid "devcp_editbox_categories"
+msgstr "Categories"
+
+#: views/elements/developers/editbox.thtml:52
+#, fuzzy
+msgid "devcp_editbox_change_status"
+msgstr "Change Status"
+
+#: views/elements/developers/editbox.thtml:48
+#, fuzzy
+msgid "devcp_editbox_descriptions"
+msgstr "Descriptions"
+
+#: views/elements/developers/editbox.thtml:43
+#, fuzzy
+msgid "devcp_editbox_edit_addon"
+msgstr "Edit Add-on"
+
+#: views/elements/developers/editbox.thtml:57
+#, fuzzy
+msgid "devcp_editbox_new_version"
+msgstr "New Version"
+
+#: views/elements/developers/editbox.thtml:49
+#, fuzzy
+msgid "devcp_editbox_properties"
+msgstr "Properties"
+
+#: views/elements/developers/editbox.thtml:60
+#, fuzzy
+msgid "devcp_editbox_screenshots"
+msgstr "Preview Screenshots"
+
+#: views/elements/developers/editbox.thtml:53
+#, fuzzy
+msgid "devcp_editbox_statistics_dashboard"
+msgstr "Statistics Dashboard"
+
+#: views/elements/developers/editbox.thtml:54
+#, fuzzy
+msgid "devcp_editbox_versions"
+msgstr "Versions and Files"
+
+#: views/elements/developers/editbox.thtml:42
+#, fuzzy
+msgid "devcp_editbox_view_listing"
+msgstr "View Listing"
+
+#: views/elements/developers/editorsmenu.thtml:59
+msgid "devcp_editorsqueue_featured"
+msgstr "Featured Add-ons"
+
+#. %1 is the review count
+#: views/elements/developers/editorsqueue.thtml:42
+#: views/elements/developers/editorsmenu.thtml:56
+#, php-format
+msgid "devcp_editorsqueue_moderatedreviews"
+msgid_plural "devcp_editorsqueue_moderatedreviews"
+msgstr[0] "Модеровані переглÑди (%s)"
+msgstr[1] "Модеровані переглÑди (%s)"
+
+#. %1 is the nominated addons count
+#: views/elements/developers/editorsqueue.thtml:44
+#: views/elements/developers/editorsmenu.thtml:58
+#, php-format
+msgid "devcp_editorsqueue_nominated"
+msgid_plural "devcp_editorsqueue_nominated"
+msgstr[0] "Ðоміновані додатки (%s)"
+msgstr[1] "Ðоміновані додатки (%s)"
+
+#. %1 is the update count
+#: views/elements/developers/editorsqueue.thtml:43
+#: views/elements/developers/editorsmenu.thtml:57
+#, php-format
+msgid "devcp_editorsqueue_pendingupdates"
+msgid_plural "devcp_editorsqueue_pendingupdates"
+msgstr[0] "ÐžÐ½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ð² черзі (%s)"
+msgstr[1] "ÐžÐ½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ð² черзі (%s)"
+
+#: controllers/statistics_controller.php:147
+#: controllers/statistics_controller.php:361
+#: controllers/previews_controller.php:108
+#: controllers/previews_controller.php:211
+#: controllers/previews_controller.php:312
+msgid "devcp_error_addon_access_denied"
+msgstr "У Ð²Ð°Ñ Ð½ÐµÐ¼Ð°Ñ” доÑтупу до цього додатку."
+
+#. %s is a complete URL with the text from devcp_error_appversion_reference_link_text
+#. in the <a> tag. This should be fixed.
+#: controllers/components/developers.php:591
+#, php-format
+msgid "devcp_error_appversion_reference_link"
+msgstr "Будь лаÑка, дивітьÑÑ %s Ð´Ð»Ñ Ð´Ð¾Ð²Ñ–Ð´ÐºÐ¸."
+
+#. This is the link text in the <a> for devcp_error_appversion_reference_link. This
+#. should be fixed.
+#: controllers/components/developers.php:591
+msgid "devcp_error_appversion_reference_link_text"
+msgstr "цю Ñторінку"
+
+#: views/developers/addon_edit_authors.thtml:76
+#, fuzzy
+msgid "devcp_error_empty_authors"
+msgstr "Your add-on must have at least one owner."
+
+#. %1$s is the name of the file
+#: controllers/components/developers.php:658
+#, fuzzy
+msgid "devcp_error_file_exists"
+msgstr ""
+"A version of that addon already exists. To replace it, you must delete the "
+"file %1$s first."
+
+#. %1$s is a file extension. Example: .exe
+#. %2$s is a comma separated list of extensions. Example: .xpi, .jar
+#: controllers/components/developers.php:355
+#, php-format
+msgid "devcp_error_file_extension"
+msgstr ""
+"Це Ñ€Ð¾Ð·ÑˆÐ¸Ñ€ÐµÐ½Ð½Ñ Ñ„Ð°Ð¹Ð»Ñƒ (%s) недозволене Ð´Ð»Ñ Ð¾Ð±Ñ€Ð°Ð½Ð¾Ð³Ð¾ типу додатку. Будь лаÑка, "
+"викориÑтайте одне з наÑтупних: %s"
+
+#: controllers/components/developers.php:64
+msgid "devcp_error_five_categories"
+msgstr "Будь лаÑка, оберіть не більше п’Ñти категорій."
+
+#: controllers/components/developers.php:526
+msgid "devcp_error_guid_application"
+msgstr "ID цього додатку вже викориÑтовуєтьÑÑ Ð¿Ñ€Ð¾Ð³Ñ€Ð°Ð¼Ð¾ÑŽ."
+
+#: controllers/components/developers.php:337
+#: controllers/components/developers.php:389
+msgid "devcp_error_http_incomplete"
+msgstr "Ðезавершена передача"
+
+#: controllers/components/developers.php:335
+#: controllers/components/developers.php:336
+#: controllers/components/developers.php:387
+#: controllers/components/developers.php:388
+msgid "devcp_error_http_maxupload"
+msgstr "Перевищує макÑимальний розмір відвантаженнÑ"
+
+#: controllers/components/developers.php:338
+#: controllers/components/developers.php:390
+msgid "devcp_error_http_nofile"
+msgstr "Жодного файла не відвантажено"
+
+#. %1$s is a file extension. Example: .exe
+#. %2$s is a comma separated list of extensions. Example: .xpi, .jar
+#: controllers/components/developers.php:401
+#, php-format
+msgid "devcp_error_icon_extension"
+msgstr ""
+"Це Ñ€Ð¾Ð·ÑˆÐ¸Ñ€ÐµÐ½Ð½Ñ Ñ„Ð°Ð¹Ð»Ñƒ (%s) недозволене Ð´Ð»Ñ Ð·Ð½Ð°Ñ‡ÐºÐ°. Будь лаÑка, викориÑтайте "
+"одне з наÑтупних: %s"
+
+#: controllers/developers_controller.php:504
+msgid "devcp_error_index_rdf_notfound"
+msgstr "ВідÑутній install.rdf."
+
+#: controllers/components/developers.php:601
+msgid "devcp_error_install_manifest"
+msgstr "ÐаÑтупні помилки знайдені у install.rdf:"
+
+#: controllers/developers_controller.php:1463
+msgid "devcp_error_invalid_addontype"
+msgstr "Будь лаÑка, оберіть дійÑний тип додатку."
+
+#. %$1s is a version. Example: 3.1.1
+#. %$2s is an add-on name.
+#: controllers/components/developers.php:569
+#: controllers/components/developers.php:581
+#, php-format
+msgid "devcp_error_invalid_appversion"
+msgstr "%s не Ñ” дійÑною верÑією Ð´Ð»Ñ %s"
+
+#. %s is a string
+#: controllers/components/developers.php:521
+#, php-format
+msgid "devcp_error_invalid_guid"
+msgstr "ID цього додатку недійÑне: %s"
+
+#. %$1s is a version. Example: 3.1.1
+#. %$2s is an add-on name.
+#: controllers/components/developers.php:572
+#, php-format
+msgid "devcp_error_invalid_minversion"
+msgstr "%s не Ñ” дійÑною верÑією Ð´Ð»Ñ %s: мінімальні верÑÑ–Ñ— не повинні міÑтити *"
+
+#: controllers/components/developers.php:536
+msgid "devcp_error_invalid_version"
+msgstr ""
+"ВерÑÑ–Ñ Ñ†ÑŒÐ¾Ð³Ð¾ додатку недійÑна: будь лаÑка, дивітьÑÑ <a href=\"http://"
+"developer.mozilla.org/en/docs/Toolkit_version_format\">Ñпецифікацію</a>"
+
+#: controllers/components/developers.php:531
+msgid "devcp_error_invalid_version_spaces"
+msgstr "ВерÑÑ–Ñ Ñ†ÑŒÐ¾Ð³Ð¾ додатку недійÑна: верÑÑ–Ñ— не можуть міÑтити пробілів."
+
+#. %s is an error message from the parser.
+#: controllers/components/developers.php:501
+#, php-format
+msgid "devcp_error_manifest_parse"
+msgstr "ÐаÑтупна помилка з’ÑвилаÑÑ Ð¿Ñ–Ð´ Ñ‡Ð°Ñ Ð°Ð½Ð°Ð»Ñ–Ð·Ñƒ install.rdf: %s"
+
+#: controllers/components/developers.php:373
+msgid "devcp_error_move_file"
+msgstr "Ðеможливо переміÑтити файл"
+
+#. %s is the name of a file
+#: controllers/components/developers.php:650
+#: controllers/components/developers.php:662
+#: controllers/components/developers.php:667
+#: controllers/components/developers.php:727
+#: controllers/components/developers.php:738
+#: controllers/components/developers.php:743
+#, php-format
+msgid "devcp_error_moving_file"
+msgstr "Помилка з’ÑвилаÑÑ Ð¿Ñ–Ð´ Ñ‡Ð°Ñ Ð¿ÐµÑ€ÐµÐ¼Ñ–Ñ‰ÐµÐ½Ð½Ñ %s."
+
+#: controllers/components/developers.php:595
+msgid "devcp_error_mozilla_application"
+msgstr "Ви повинні мати принаймні одну дійÑну цільову програму Mozilla."
+
+#: controllers/components/developers.php:516
+msgid "devcp_error_no_guid"
+msgstr "Ð”Ð»Ñ Ñ†ÑŒÐ¾Ð³Ð¾ додатку не знайдено жодного ID у install.rdf."
+
+#: controllers/components/developers.php:287
+msgid "devcp_error_no_platform"
+msgstr "Жодної платформи не обрано"
+
+#: controllers/components/developers.php:59
+msgid "devcp_error_one_category"
+msgstr "Будь лаÑка, оберіть принаймні одну категорію."
+
+#: controllers/components/developers.php:92
+msgid "devcp_error_one_user"
+msgstr "Ð”Ð»Ñ Ñ†ÑŒÐ¾Ð³Ð¾ додатку повинен бути принаймні один автор."
+
+#. %1$s is a file extension. Example: .exe
+#. %2$s is a comma separated list of extensions. Example: .xpi, .jar
+#: controllers/components/developers.php:1081
+#, php-format
+msgid "devcp_error_preview_extension"
+msgstr ""
+"Це Ñ€Ð¾Ð·ÑˆÐ¸Ñ€ÐµÐ½Ð½Ñ Ñ„Ð°Ð¹Ð»Ñƒ (%s) недозволене Ð´Ð»Ñ Ð·Ð½Ñ–Ð¼ÐºÑƒ екрану. Будь лаÑка, "
+"викориÑтайте одне з наÑтупних: %s"
+
+#: controllers/components/developers.php:511
+msgid "devcp_error_updatekey"
+msgstr ""
+"Додатки не можуть викориÑтовувати updateKey. Будь лаÑка приберіть його з "
+"install.rdf та Ñпробуйте знову"
+
+#: controllers/components/developers.php:506
+msgid "devcp_error_updateurl"
+msgstr ""
+"Додатки не можуть викориÑтовувати URL оновленнÑ. Будь лаÑка, вилучте його з "
+"install.rdf та Ñпробуйте знову."
+
+#: controllers/developers_controller.php:465
+#: controllers/components/developers.php:271
+msgid "devcp_error_upload_file"
+msgstr "Будь лаÑка, відвантажте файл."
+
+#: views/developers/uploader.thtml:135
+#, fuzzy
+msgid "devcp_input_upload_file"
+msgstr "Upload File"
+
+#: views/pages/js_constants.js.thtml:89
+#, fuzzy
+msgid "devcp_js_a_cancel"
+msgstr "Cancel"
+
+#: views/pages/js_constants.js.thtml:90
+#, fuzzy
+msgid "devcp_js_add_email"
+msgstr "Please enter the account email of the author you wish to add."
+
+#. alt text for a down-arrow image.
+#: views/pages/js_constants.js.thtml:81
+#, fuzzy
+msgid "devcp_js_img_move_down"
+msgstr "Move Down"
+
+#. alt text for an up-arrow image.
+#: views/pages/js_constants.js.thtml:82
+#, fuzzy
+msgid "devcp_js_img_move_up"
+msgstr "Move Up"
+
+#: views/pages/js_constants.js.thtml:91
+#, fuzzy
+msgid "devcp_js_img_remove_compat"
+msgstr "Remove Application Compatibility"
+
+#: views/pages/js_constants.js.thtml:86
+#, fuzzy
+msgid "devcp_js_input_list_author"
+msgstr "List as author in public listings"
+
+#: views/pages/js_constants.js.thtml:92
+#, fuzzy
+msgid "devcp_js_license_select"
+msgstr "Please select a license."
+
+#: views/pages/js_constants.js.thtml:93
+#, fuzzy
+msgid "devcp_js_license_text"
+msgstr "Please enter text for your license."
+
+#. <option> text in a <select> for Author role in an add-on.
+#: views/pages/js_constants.js.thtml:84
+#, fuzzy
+msgid "devcp_js_option_developer"
+msgstr "Developer"
+
+#. <option> text in a <select> for Author role in an add-on.
+#: views/pages/js_constants.js.thtml:83
+#, fuzzy
+msgid "devcp_js_option_owner"
+msgstr "Owner"
+
+#. <option> text in a <select> for Author role in an add-on.
+#: views/pages/js_constants.js.thtml:85
+#, fuzzy
+msgid "devcp_js_option_viewer"
+msgstr "Viewer"
+
+#: views/pages/js_constants.js.thtml:88
+#, fuzzy
+msgid "devcp_js_remove_author"
+msgstr "Remove Author"
+
+#: views/pages/js_constants.js.thtml:87
+#, fuzzy
+msgid "devcp_js_sure_remove"
+msgstr "Are you <strong>sure</strong> you wish to remove this author?"
+
+#: views/pages/js_constants.js.thtml:77
+#, fuzzy
+msgid "devcp_js_upload_alert"
+msgstr "You must select a file to upload."
+
+#. %1$s is an addon id, like 32.
+#. %2$s is a version number, like 3.5.
+#: controllers/components/developers.php:1212
+#, fuzzy
+msgid "devcp_license_existing"
+msgstr "Custom license for add-on %1$s v%2$s"
+
+#: views/elements/developers/localebox.thtml:44
+msgid "devcp_localebox_header_localizedfields"
+msgstr "Локалізовані полÑ"
+
+#. %1 is the default locale
+#: views/elements/developers/localebox.thtml:48
+#, php-format
+msgid "devcp_localebox_intro"
+msgstr ""
+"ДеÑкі Ð¿Ð¾Ð»Ñ Ð½Ð° цій Ñторінці локалізовані, щоб з’ÑвитиÑÑ Ñ€Ñ–Ð´Ð½Ð¾ÑŽ мовою "
+"кінцевого кориÑтувача. Оберіть мову нижче, щоб відредагувати деталі вашого "
+"додатку на цій мові. Якщо переклад Ð´Ð»Ñ Ð¼Ð¾Ð²Ð¸ недоÑтупний, вона перейде до "
+"обраної типової мови (%s)."
+
+#: views/elements/developers/sidebar.thtml:68
+#: views/elements/developers/myaddons.thtml:75
+msgid "devcp_myaddons_admincp_link"
+msgstr "Панель ÑƒÐ¿Ñ€Ð°Ð²Ð»Ñ–Ð½Ð½Ñ Ð°Ð´Ð¼Ñ–Ð½Ð°"
+
+#: views/elements/developers/sidebar.thtml:65
+#: views/elements/developers/myaddons.thtml:72
+msgid "devcp_myaddons_editorcp_link"
+msgstr "Панель ÑƒÐ¿Ñ€Ð°Ð²Ð»Ñ–Ð½Ð½Ñ Ñ€ÐµÐ´Ð°ÐºÑ‚Ð¾Ñ€Ð°"
+
+#: views/elements/developers/myaddons.thtml:52
+msgid "devcp_myaddons_link"
+msgstr "Мої додатки"
+
+#: views/elements/developers/sidebar.thtml:70
+#: views/elements/developers/myaddons.thtml:77
+msgid "devcp_myaddons_mainpage_link"
+msgstr "Ðазад до головного"
+
+#: views/elements/developers/sidebar.thtml:63
+#: views/elements/developers/myaddons.thtml:70
+msgid "devcp_myaddons_statistics_link"
+msgstr "Statistics Dashboard"
+
+#: views/elements/developers/sidebar.thtml:62
+#: views/elements/developers/myaddons.thtml:69
+msgid "devcp_myaddons_submitaddon_link"
+msgstr "ÐадіÑлати додаток"
+
+#: views/elements/developers/sidebar.thtml:48
+#: views/elements/developers/myaddons.thtml:67
+msgid "devcp_myaddons_title"
+msgstr "Developer Tools"
+
+#. %1$s is an add-on ID, perhaps 167.
+#. %2$s is a URL.
+#: controllers/developers_controller.php:256
+#, fuzzy
+msgid "devcp_new_addon_error"
+msgstr ""
+"This add-on ID (%1$s) already exists in the database. If this is your add-"
+"on, you can <a href=\"%2$s\">upload a new version</a>."
+
+#: views/developers/addon_status_nominate.thtml:62
+#, fuzzy
+msgid "devcp_nominate_cancel"
+msgstr "Cancel and return"
+
+#. %1 is the add-on name
+#: views/developers/addon_status_nominate.thtml:61
+#, php-format
+msgid "devcp_nominate_submit_nominate"
+msgstr "Подати %s"
+
+#: views/developers/addon_edit_properties.thtml:50
+#: views/developers/addon_status.thtml:49
+#: views/developers/versions_edit.thtml:50
+#, fuzzy
+msgid "devcp_notice_changes_error"
+msgstr ""
+"<span>One or more of your changes couldn't be saved.</span><br />Please look "
+"for the errors below. The rest of your changes were successfully saved."
+
+#: views/developers/addon_edit_authors.thtml:47
+#: views/developers/addon_edit_properties.thtml:47
+#: views/developers/addon_status.thtml:46
+#: views/developers/addon_edit_descriptions.thtml:47
+#: views/developers/versions_edit.thtml:47
+#: views/developers/addon_edit_categories.thtml:46
+#, fuzzy
+msgid "devcp_notice_changes_saved"
+msgstr ""
+"<span>Your changes have been saved.</span><br />Please note that some "
+"changes may take several hours to appear in all areas of the website."
+
+#: controllers/previews_controller.php:252
+msgid "devcp_notice_cleardefault"
+msgstr ""
+"СкаÑÑƒÐ²Ð°Ð½Ð½Ñ Ñ†ÑŒÐ¾Ð³Ð¾, Ñк типового знімку екрану Ñпричинить автоматичне "
+"Ð¿ÐµÑ€ÐµÐ¼Ð¸ÐºÐ°Ð½Ð½Ñ Ñ–Ð½ÑˆÐ¾Ð³Ð¾ знімку на роль типового."
+
+#: controllers/previews_controller.php:184
+#: controllers/previews_controller.php:251
+msgid "devcp_notice_makedefault"
+msgstr ""
+"Зробивши цей знімок типовим ви приберете типовий ÑÑ‚Ð°Ñ‚ÑƒÑ Ð· поточного типового "
+"знімку."
+
+#: views/developers/addon_edit_authors.thtml:70
+#, fuzzy
+msgid "devcp_notice_unsaved_changes"
+msgstr "You have unsaved changes."
+
+#: controllers/developers_controller.php:87
+#: controllers/developers_controller.php:97
+#: controllers/developers_controller.php:100
+#: controllers/previews_controller.php:67
+#: controllers/previews_controller.php:79
+#: controllers/previews_controller.php:82
+msgid "devcp_pagetitle"
+msgstr "Панель ÑƒÐ¿Ñ€Ð°Ð²Ð»Ñ–Ð½Ð½Ñ Ñ€Ð¾Ð·Ñ€Ð¾Ð±Ð½Ð¸ÐºÐ°"
+
+#: controllers/previews_controller.php:103
+#: controllers/previews_controller.php:104
+msgid "devcp_preview_add_pagetitle"
+msgstr "Додати знімок екрану"
+
+#: controllers/previews_controller.php:135
+msgid "devcp_preview_added_successfully"
+msgstr "Знімок екрану додано уÑпішно."
+
+#: controllers/previews_controller.php:323
+msgid "devcp_preview_deleted_successfully"
+msgstr "ПереглÑд Ñтерто уÑпішно."
+
+#: controllers/previews_controller.php:194
+#: controllers/previews_controller.php:195
+msgid "devcp_preview_edit_pagetitle"
+msgstr "Редагувати знімок"
+
+#: controllers/previews_controller.php:237
+msgid "devcp_preview_updated_successfully"
+msgstr "Знімок екрану оновлено уÑпішно."
+
+#: views/developers/previews.thtml:120
+#, fuzzy
+msgid "devcp_previews_a_another"
+msgstr "Add Another Preview"
+
+#: views/developers/previews.thtml:96
+#, fuzzy
+msgid "devcp_previews_a_delete"
+msgstr "Delete Preview"
+
+#: views/developers/previews.thtml:95
+#, fuzzy
+msgid "devcp_previews_a_replace"
+msgstr "Replace Preview"
+
+#: views/developers/previews.thtml:126
+#, fuzzy
+msgid "devcp_previews_a_update"
+msgstr "Update Previews"
+
+#: views/developers/previews.thtml:115 views/developers/previews.thtml:124
+#, fuzzy
+msgid "devcp_previews_add_new"
+msgstr "Add New Preview"
+
+#. %s is a list of file extensions, e.g. ".png, .gif"
+#: views/developers/previews.thtml:116
+#, fuzzy
+msgid "devcp_previews_add_select"
+msgstr ""
+"Select an image to upload below. Images larger than the maximum size of 700 "
+"pixels wide by 525 pixels tall will be resized. Allowed file types: %s"
+
+#: views/developers/previews.thtml:121
+#, fuzzy
+msgid "devcp_previews_click_below"
+msgstr "Click Update Previews below to upload."
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/previews.thtml:102
+#, fuzzy
+msgid "devcp_previews_click_update"
+msgstr ""
+"Click the Update Previews button below to save this image. (<a %s>Cancel?</"
+"a>)"
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/previews.thtml:107
+#, fuzzy
+msgid "devcp_previews_error_message"
+msgstr ""
+"This preview will be deleted when Update Previews is clicked below. (<a %"
+"s>Cancel?</a>)"
+
+#: views/previews/add.thtml:45
+msgid "devcp_previews_filetype_info"
+msgstr ""
+"ВикориÑтовуйте форму нижче Ð´Ð»Ñ Ð²Ñ–Ð´Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½ÑŒ вашого додатку у PNG, "
+"JPG, або GIF. Ð—Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ Ð±Ñ–Ð»ÑŒÑˆÑ– за 700 пікÑелів у ширину Ñ– 525 пікÑелів у "
+"виÑоту буде автоматично змаÑштабовано."
+
+#: views/previews/add.thtml:43
+msgid "devcp_previews_header_add"
+msgstr "Додати знімок екрану"
+
+#: views/developers/previews.thtml:80
+#, fuzzy
+msgid "devcp_previews_header_caption"
+msgstr "Preview Caption"
+
+#: views/previews/edit.thtml:43
+msgid "devcp_previews_header_edit"
+msgstr "Редагувати знімок екрану"
+
+#: views/developers/previews.thtml:93
+#, fuzzy
+msgid "devcp_previews_label_default"
+msgstr "Default Preview"
+
+#: views/previews/add.thtml:54
+msgid "devcp_previews_label_file"
+msgstr "Файл знімку екрану"
+
+#: views/previews/add.thtml:59 views/previews/edit.thtml:50
+msgid "devcp_previews_label_makedefault"
+msgstr "Зробити це типовим зображеннÑм переглÑду"
+
+#: views/developers/previews.thtml:100
+#, fuzzy
+msgid "devcp_previews_label_new"
+msgstr "New image:"
+
+#: views/developers/previews.thtml:118
+#, fuzzy
+msgid "devcp_previews_label_upload"
+msgstr "Upload Preview: "
+
+#: views/developers/previews.thtml:50
+#, fuzzy
+msgid "devcp_previews_notice_error"
+msgstr "One or more of your new previews could not be saved."
+
+#: views/developers/previews.thtml:47
+#, fuzzy
+msgid "devcp_previews_notice_success"
+msgstr "Your previews have been updated successfully."
+
+#: views/developers/previews.thtml:59
+#, fuzzy
+msgid "devcp_previews_p_screenshots"
+msgstr ""
+"The preview screenshots for your add-on are shown below. You can make "
+"changes to captions or images below. The Default Preview is the preview that "
+"is displayed next to your add-on in search and browse listings."
+
+#: views/previews/edit.thtml:55
+msgid "devcp_previews_submit_delete"
+msgstr "Стерти знімок екрану"
+
+#: views/previews/edit.thtml:55
+msgid "devcp_previews_submit_delete_confirm"
+msgstr "Ви впевнені, що бажаєте Ñтерти цей знімок?"
+
+#: views/previews/edit.thtml:54
+msgid "devcp_previews_submit_edit"
+msgstr "Редагувати знімок"
+
+#: views/previews/add.thtml:63
+msgid "devcp_previews_submit_upload"
+msgstr "Відвантажити знімок екрану"
+
+#: views/developers/previews.thtml:78
+#, fuzzy
+msgid "devcp_previews_thumbnail"
+msgstr "Thumbnail"
+
+#. %s is the add-on name.
+#: views/developers/previews.thtml:44
+#, fuzzy
+msgid "devcp_previews_title"
+msgstr "%s Preview Manager"
+
+#: views/developers/uploader.thtml:74
+msgid "devcp_review_agreement_please"
+msgstr "Будь лаÑка, переглÑньте та прийміть наÑтупну Угоду перед продовженнÑм."
+
+#: views/elements/developers/rolecheck.thtml:42
+#, fuzzy
+msgid "devcp_rolecheck_no_privs"
+msgstr ""
+"<span>You do not have sufficient privileges to make changes on this page.</"
+"span><br />Contact the Add-on Owner if you need to make changes."
+
+#: controllers/developers_controller.php:1315
+#, fuzzy
+msgid "devcp_several_hours"
+msgstr ""
+"Please note that some changes may take several hours to appear in all areas "
+"of the website."
+
+#: views/elements/developers/sidebar.thtml:52
+#, fuzzy
+msgid "devcp_sidebar_a_dashboard"
+msgstr "Dashboard"
+
+#. %s is a number
+#: views/elements/developers/statsbar.thtml:45
+#: views/developers/dashboard.thtml:79
+#, php-format
+msgid "devcp_statsbar_adu"
+msgstr "<em>%s</em> Active Daily Users"
+
+#. %s is a number
+#: views/elements/developers/statsbar.thtml:41
+#: views/developers/dashboard.thtml:75
+#, php-format
+msgid "devcp_statsbar_total_downloads"
+msgstr "<em>%s</em> Total Downloads"
+
+#. %s is a number
+#: views/elements/developers/statsbar.thtml:43
+#: views/developers/dashboard.thtml:77
+#, php-format
+msgid "devcp_statsbar_weekly_downloads"
+msgstr "<em>%s</em> Weekly Downloads"
+
+#: views/developers/addon_status_confirm.thtml:59
+#, fuzzy
+msgid "devcp_status_confirm_active"
+msgstr ""
+"Marking this add-on active will cause it to show up in public areas "
+"appropriate for its status, including search and browse listings. It will be "
+"downloadable from the website and could be returned in client update checks, "
+"depending on its status. You will be able to return here and disable it "
+"again at your convenience."
+
+#: views/developers/addon_status_confirm.thtml:59
+#, fuzzy
+msgid "devcp_status_confirm_active_sure"
+msgstr "Are you sure you wish to mark this add-on active?"
+
+#: views/developers/addon_status_confirm.thtml:50
+#, fuzzy
+msgid "devcp_status_confirm_header_sure"
+msgstr "Are you sure?"
+
+#: views/developers/addon_status_confirm.thtml:55
+#, fuzzy
+msgid "devcp_status_confirm_inactive"
+msgstr ""
+"Marking this add-on inactive will prevent it from showing up in any public "
+"areas, including search and browse listings. It will not be downloadable "
+"from the website and will not be returned in client update checks. You will "
+"be able to return here and re-enable it at your convenience."
+
+#: views/developers/addon_status_confirm.thtml:55
+#, fuzzy
+msgid "devcp_status_confirm_inactive_sure"
+msgstr "Are you sure you wish to mark this add-on inactive?'"
+
+#: views/developers/addon_status_confirm.thtml:74
+#, fuzzy
+msgid "devcp_status_confirm_no"
+msgstr "No, cancel"
+
+#: views/developers/addon_status_confirm.thtml:67
+#, fuzzy
+msgid "devcp_status_confirm_public"
+msgstr ""
+"Making this add-on public will make it available for anyone to download and "
+"will begin offering updates to existing users."
+
+#: views/developers/addon_status_confirm.thtml:67
+#, fuzzy
+msgid "devcp_status_confirm_public_sure"
+msgstr "Are you sure you wish to make this add-on public?"
+
+#: views/developers/addon_status_confirm.thtml:63
+#, fuzzy
+msgid "devcp_status_confirm_sandbox"
+msgstr ""
+"Moving this add-on back to the sandbox will require users to login before "
+"downloading and updates will no longer be offered to existing users. Because "
+"your add-on is currently public, you will be able to return here at any time "
+"to make it public again."
+
+#: views/developers/addon_status_confirm.thtml:63
+#, fuzzy
+msgid "devcp_status_confirm_sandbox_sure"
+msgstr "Are you sure you wish to move this add-on to the sandbox?"
+
+#: views/developers/addon_status_confirm.thtml:73
+#, fuzzy
+msgid "devcp_status_confirm_yes"
+msgstr "Yes, I'm Sure"
+
+#: views/developers/addon_status_nominate.thtml:46
+#, fuzzy
+msgid "devcp_status_nominate_error_notice"
+msgstr ""
+"<span>A nomination message is required.</span><br />Please fill in the text "
+"box with the requested information and try again."
+
+#: views/developers/addon_status_nominate.thtml:55
+#, fuzzy
+msgid "devcp_status_nominate_header"
+msgstr "Add-on Nomination"
+
+#: views/developers/dashboard.thtml:85
+msgid "devcp_summary_lastversion"
+msgstr "ОÑÑ‚Ð°Ð½Ð½Ñ Ð²ÐµÑ€ÑÑ–Ñ:"
+
+#. %s is the add-on name.
+#: views/developers/addon_edit.thtml:43
+#: views/developers/addon_edit_authors.thtml:44
+#: views/developers/versions_delete.thtml:43
+#: views/developers/addon_edit_properties.thtml:44
+#: views/developers/addon_edit_descriptions.thtml:44
+#: views/developers/versions_edit.thtml:44
+#: views/developers/addon_edit_categories.thtml:43
+#: views/developers/versions.thtml:43
+#, fuzzy
+msgid "devcp_title_edit_addon"
+msgstr "Edit %s"
+
+#. title attribute for a javascript link that pops up a help dialog.
+#: views/elements/translationbox.thtml:68
+#, fuzzy
+msgid "devcp_transbox_a_title_help"
+msgstr "Help (does not leave page)"
+
+#: views/elements/translationbox.thtml:68
+#, fuzzy
+msgid "devcp_transbox_alt_help"
+msgstr "Help"
+
+#. %1$s is <span>17</span>, %2$s is 42.
+#: views/elements/translationbox.thtml:101
+#, fuzzy
+msgid "devcp_transbox_chars_used"
+msgstr "Characters used: %1$s / %2$s"
+
+#: views/elements/translationbox.thtml:132
+#, fuzzy
+msgid "devcp_transbox_delete_sure"
+msgstr "Are you sure you wish to delete this translation?"
+
+#. %s is a locale, like en-US.
+#: views/elements/translationbox.thtml:143
+#, fuzzy
+msgid "devcp_transbox_help_header_tabs"
+msgstr "What are these %s tabs?"
+
+#: views/elements/translationbox.thtml:145
+#, fuzzy
+msgid "devcp_transbox_help_header_what"
+msgstr "What if I don't have any translations?"
+
+#: views/elements/translationbox.thtml:147
+#, fuzzy
+msgid "devcp_transbox_help_hide"
+msgstr "Hide Help"
+
+#: views/elements/translationbox.thtml:146
+#, fuzzy
+msgid "devcp_transbox_help_if"
+msgstr ""
+"If a user browses the site and a translation isn't available in their own "
+"language, it will fall back to your add-on's Default Locale, specified in "
+"the Edit Add-on Properties area. If you don't have any translations, just "
+"enter what you can into your Default Locale, which should be a language you "
+"speak."
+
+#: views/elements/translationbox.thtml:144
+#, fuzzy
+msgid "devcp_transbox_help_transbox"
+msgstr ""
+"This is a <i>Translation Box</i>. It allows you to localize a specific field "
+"into any other languages for which you might have a translation. You can "
+"add, edit, and remove translations using the locale tabs."
+
+#: views/elements/translationbox.thtml:85
+#, fuzzy
+msgid "devcp_transbox_img_add_trans"
+msgstr "Add Translation"
+
+#: views/elements/translationbox.thtml:86
+#, fuzzy
+msgid "devcp_transbox_img_remove_trans"
+msgstr "Remove Translation"
+
+#: views/elements/translationbox.thtml:123
+#, fuzzy
+msgid "devcp_transbox_input_add_all"
+msgstr "Add Locale to All"
+
+#: views/elements/translationbox.thtml:122
+#, fuzzy
+msgid "devcp_transbox_input_add_locale"
+msgstr "Add Locale"
+
+#: views/elements/translationbox.thtml:124
+#: views/elements/translationbox.thtml:135
+#, fuzzy
+msgid "devcp_transbox_input_cancel"
+msgstr "Cancel"
+
+#: views/elements/translationbox.thtml:134
+#, fuzzy
+msgid "devcp_transbox_input_delete"
+msgstr "Delete It"
+
+#: views/elements/translationbox.thtml:113
+#, fuzzy
+msgid "devcp_transbox_select_locale"
+msgstr "Select the locale of the translation to add:"
+
+#. %1$s and %2$s are GUIDs.
+#: controllers/developers_controller.php:343
+#, fuzzy
+msgid "devcp_update_addon_guid_error"
+msgstr ""
+"The add-on GUID used in this file (%1$s) does not match the existing GUID "
+"for this add-on (%2$s)."
+
+#: controllers/developers_controller.php:334
+#, fuzzy
+msgid "devcp_update_addon_priv_error"
+msgstr "You do not have sufficient privileges to update this add-on."
+
+#. %1$s is a version number, %2$s is an add-on ID.
+#: controllers/developers_controller.php:399
+#, fuzzy
+msgid "devcp_update_addon_version_belong_error"
+msgstr "The specified version (%1$s) does not belong to this add-on (%2$s)."
+
+#. %1$s is a version number, maybe 1.1.
+#. %2$s is a URL.
+#: controllers/developers_controller.php:351
+#, fuzzy
+msgid "devcp_update_addon_version_exists_error"
+msgstr ""
+"The version number uploaded (%1$s) already exists for this add-on. If you "
+"are trying to add another file to this version, <a href=\"%2$s\">click here</"
+"a>."
+
+#. %1$s and %2$s are version numbers.
+#: controllers/developers_controller.php:405
+#, fuzzy
+msgid "devcp_update_addon_version_match_error"
+msgstr ""
+"The uploaded version number (%1$s) does not match the existing version "
+"number (%2$s)."
+
+#: views/developers/uploader.thtml:68
+#, fuzzy
+msgid "devcp_uploader_a_start"
+msgstr "Get Started"
+
+#: views/developers/uploader.thtml:137
+#, fuzzy
+msgid "devcp_uploader_ajax_loading"
+msgstr "Uploading file..."
+
+#: views/developers/uploader.thtml:82
+#, fuzzy
+msgid "devcp_uploader_button_agree"
+msgstr "Agree and continue"
+
+#: views/developers/uploader.thtml:157
+#, fuzzy
+msgid "devcp_uploader_button_edit"
+msgstr "Edit My Add-on"
+
+#: views/developers/uploader.thtml:158
+#, fuzzy
+msgid "devcp_uploader_button_later"
+msgstr "I'll complete my add-on later."
+
+#: views/developers/uploader.thtml:168
+#, fuzzy
+msgid "devcp_uploader_button_release"
+msgstr "Add Release Notes"
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/uploader.thtml:156
+#, fuzzy
+msgid "devcp_uploader_created_results"
+msgstr ""
+"<p>Your add-on listing has been successfully created. The basic information "
+"obtained from your uploaded file has been stored, but there's a lot more to "
+"your listing that can be customized.</p><p>Your add-on is currently marked "
+"as <strong>Incomplete</strong>. In order to complete your add-on, you'll "
+"need to make sure it has an accurate name, summary, and description, as well "
+"as at least one selected category. You can edit your add-on's information "
+"using the link below and check the status of your add-on at any time on the "
+"<a %s>status page</a>."
+
+#: views/developers/uploader.thtml:143
+#, fuzzy
+msgid "devcp_uploader_error_correct"
+msgstr "Please correct this problem and upload your file again."
+
+#. %1$s is a version number, %2$s is a status, e.g Public or Incomplete.
+#: views/developers/uploader.thtml:175
+#, fuzzy
+msgid "devcp_uploader_file_created"
+msgstr ""
+"Your new file has been added to version %1$s and is currently marked as %2$s."
+
+#: views/developers/uploader.thtml:154
+#, fuzzy
+msgid "devcp_uploader_header_created"
+msgstr "Add-on Created!"
+
+#: views/developers/uploader.thtml:141
+#, fuzzy
+msgid "devcp_uploader_header_error"
+msgstr "Oops! There seems to be a problem with this file..."
+
+#: views/developers/uploader.thtml:173
+#, fuzzy
+msgid "devcp_uploader_header_file_added"
+msgstr "File Added!"
+
+#: views/developers/uploader.thtml:66
+#, fuzzy
+msgid "devcp_uploader_header_how"
+msgstr "How does it all work?"
+
+#. %s is the version number, e.g. 3.2.
+#: views/developers/uploader.thtml:163
+#, fuzzy
+msgid "devcp_uploader_header_update_created"
+msgstr "Version %s Created"
+
+#: views/developers/uploader.thtml:117
+#, fuzzy
+msgid "devcp_uploader_header_upload"
+msgstr "Upload Your File"
+
+#: views/developers/uploader.thtml:67
+#, fuzzy
+msgid "devcp_uploader_how"
+msgstr ""
+"<p>Thanks for your interest in submitting your add-on to Mozilla Add-ons. "
+"Hosting your add-on on Mozilla Add-ons is the easiest way to handle "
+"distribution of your add-on. Here's what you'll get:</p><ul><li>Each add-on "
+"will have a public display page with information you provide, such as a "
+"brief summary of the add-on's functionality, an optional longer description, "
+"and a showcase of preview screenshots of your add-on.</li><li>Your add-on "
+"will appear in search and browse listings across the site, and even in the "
+"Add-ons Manager of Firefox 3.</li><li>We'll take care of hosting all of your "
+"downloads and providing automatic updates to users when you upload a new "
+"version.</li><li>You'll have access to a statistics dashboard with detailed "
+"information about your user base.</li></ul><p>Add-ons hosted on the site "
+"must be reviewed by a Mozilla Add-ons Editor before they will have all of "
+"the features listed above. If you're ready to start the process and have "
+"your add-on package ready for upload, just click on Get Started below!</p>"
+
+#: views/developers/uploader.thtml:125
+#, fuzzy
+msgid "devcp_uploader_label_platformtype"
+msgstr "Supported Platforms:"
+
+#: views/developers/uploader.thtml:124
+#, fuzzy
+msgid "devcp_uploader_label_upload_field"
+msgstr "Add-on File: "
+
+#: controllers/components/developers.php:1221
+#, fuzzy
+msgid "devcp_uploader_option_other"
+msgstr "Other"
+
+#. %1$s is a number, %2$s is href="..." and should stay in the <a> tag.
+#: views/developers/uploader.thtml:176
+#, fuzzy
+msgid "devcp_uploader_p_pending_file"
+msgstr ""
+"The new file will be available to the public as soon as an editor is able to "
+"review it. There are currently %1$s other add-ons in the queue. Want to be "
+"reviewed faster? Consider <a %2$s>becoming an editor</a>."
+
+#. %1$s is a number, %2$s is href="..." and should stay in the <a> tag.
+#: views/developers/uploader.thtml:166
+#, fuzzy
+msgid "devcp_uploader_p_pending_version"
+msgstr ""
+"The new version will be available to the public as soon as an editor is able "
+"to review it. There are currently %1$s other add-ons in the queue. Want to "
+"be reviewed faster? Consider <a %2$s>becoming an editor</a>."
+
+#. %s is a status, e.g Public or Incomplete.
+#: views/developers/uploader.thtml:165
+#, fuzzy
+msgid "devcp_uploader_p_update_created"
+msgstr "Your new version has been created and is currently marked as %s."
+
+#. %1$s is href="..." and should stay in the 'Versions and Files' <a> tag.
+#. %2$s is href="..." and should stay in the 'current status' <a> tag.
+#: views/developers/uploader.thtml:177
+#, fuzzy
+msgid "devcp_uploader_p_update_file"
+msgstr ""
+"View your new file in the <a %1$s>Versions and Files page</a>, check out "
+"your add-on's <a %2$s>current status</a>, or <b>add release notes</b> by "
+"clicking the button below (highly recommended)."
+
+#. %1$s is href="..." and should stay in the 'Versions and Files' <a> tag.
+#. %2$s is href="..." and should stay in the 'current status' <a> tag.
+#: views/developers/uploader.thtml:167
+#, fuzzy
+msgid "devcp_uploader_p_update_version"
+msgstr ""
+"View your new version in the <a %1$s>Versions and Files page</a>, check out "
+"your add-on's <a %2$s>current status</a>, or <b>add release notes</b> by "
+"clicking the button below (highly recommended)."
+
+#: views/developers/uploader.thtml:118
+#, fuzzy
+msgid "devcp_uploader_p_upload"
+msgstr ""
+"Upload your add-on file using the form below. If you have multiple, platform-"
+"specific files to upload, choose a single file and then upload the others "
+"using the Versions and Files Manager."
+
+#: views/developers/uploader.thtml:125
+#, fuzzy
+msgid "devcp_uploader_platformtype_all"
+msgstr "All"
+
+#: views/developers/uploader.thtml:126
+#, fuzzy
+msgid "devcp_uploader_platformtype_specific"
+msgstr "Specific:"
+
+#. Used as first item in a <select>.
+#: controllers/components/developers.php:1185
+#, fuzzy
+msgid "devcp_uploader_please_choose"
+msgstr "Please Choose..."
+
+#. %1$s is the add-on name, %2$s is the version number.
+#: views/developers/uploader.thtml:57
+#, fuzzy
+msgid "devcp_uploader_title_file"
+msgstr "Add File to %1$s %2$s"
+
+#: views/developers/uploader.thtml:50
+#, fuzzy
+msgid "devcp_uploader_title_submit"
+msgstr "Submit New Add-on"
+
+#. %s is the add-on name.
+#: views/developers/uploader.thtml:54
+#, fuzzy
+msgid "devcp_uploader_title_update"
+msgstr "Update %s"
+
+#. %s is a full <a> tag
+#: controllers/developers_controller.php:503
+#, php-format
+msgid "devcp_valid_app_reference"
+msgstr "Будь лаÑка, дивітьÑÑ %s Ð´Ð»Ñ Ð´Ð¾Ð²Ñ–Ð´ÐºÐ¸."
+
+#. This is the text in the <a> tag for devcp_valid_app_reference. This should be
+#. fixed.
+#: controllers/developers_controller.php:503
+msgid "devcp_valid_app_reference_linktext"
+msgstr "цю Ñторінку"
+
+#: controllers/developers_controller.php:581
+#, fuzzy
+msgid "devcp_verify_author_error"
+msgstr "No account found for that email address."
+
+#: controllers/developers_controller.php:553
+#, fuzzy
+msgid "devcp_verify_search_engine_error"
+msgstr ""
+"Either the XML is invalid or required fields are missing. Please <a href="
+"\"https://developer.mozilla.org/en/Creating_OpenSearch_plugins_for_Firefox"
+"\">read the documentation</a>, verify your add-on, and try again."
+
+#: views/developers/versions.thtml:75
+#, fuzzy
+msgid "devcp_versions_a_cancel"
+msgstr "Cancel"
+
+#: views/developers/versions.thtml:79
+#, fuzzy
+msgid "devcp_versions_a_delete"
+msgstr "Delete Version"
+
+#: views/developers/versions.thtml:74
+#, fuzzy
+msgid "devcp_versions_a_empty"
+msgstr "Remove Empty Version"
+
+#: views/developers/versions.thtml:71
+#, fuzzy
+msgid "devcp_versions_a_remove"
+msgstr "Remove?"
+
+#: views/developers/versions.thtml:91
+#, fuzzy
+msgid "devcp_versions_add"
+msgstr "Add New Version"
+
+#: views/developers/versions_delete.thtml:58
+#, fuzzy
+msgid "devcp_versions_delete_a_cancel"
+msgstr "Cancel"
+
+#: views/developers/versions_delete.thtml:56
+#, fuzzy
+msgid "devcp_versions_delete_a_delete"
+msgstr "Delete Version"
+
+#. Followed by a list of reviews and files that will be removed.
+#: views/developers/versions_delete.thtml:50
+#, fuzzy
+msgid "devcp_versions_delete_also"
+msgstr "This will also delete:"
+
+#: views/developers/versions_delete.thtml:53
+#, fuzzy
+msgid "devcp_versions_delete_files"
+msgid_plural "devcp_versions_delete_files"
+msgstr[0] "%s file"
+msgstr[1] "%s files"
+
+#. %s is the version number.
+#: views/developers/versions_delete.thtml:48
+#, fuzzy
+msgid "devcp_versions_delete_header"
+msgstr "Delete Version %s?"
+
+#: views/developers/versions_delete.thtml:52
+#, fuzzy
+msgid "devcp_versions_delete_reviews"
+msgid_plural "devcp_versions_delete_reviews"
+msgstr[0] "%s review"
+msgstr[1] "%s reviews"
+
+#. %s is the version number.
+#: views/developers/versions_delete.thtml:49
+#, fuzzy
+msgid "devcp_versions_delete_sure"
+msgstr "Are you sure you want to permanently delete version %s?"
+
+#: views/developers/versions_edit.thtml:102
+#: views/developers/versions_edit.thtml:155
+#, fuzzy
+msgid "devcp_versions_edit_a_cancel"
+msgstr "Cancel"
+
+#: views/developers/versions_edit.thtml:101
+#, fuzzy
+msgid "devcp_versions_edit_a_delete"
+msgstr "Delete File"
+
+#: views/developers/versions_edit.thtml:165
+#, fuzzy
+msgid "devcp_versions_edit_a_new_app"
+msgstr "Add New Application"
+
+#: views/developers/versions_edit.thtml:154
+#, fuzzy
+msgid "devcp_versions_edit_a_remove_app"
+msgstr "Remove Application"
+
+#: views/developers/versions_edit.thtml:114
+#, fuzzy
+msgid "devcp_versions_edit_add"
+msgstr "Add New File"
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/versions_edit.thtml:121
+#, fuzzy
+msgid "devcp_versions_edit_adjust"
+msgstr ""
+"Adjusting application information here will allow users to install your add-"
+"on even if the install.rdf in the package indicates that the add-on is "
+"incompatible. <a %s>List of supported applications</a>"
+
+#: views/developers/versions_edit.thtml:153
+#, fuzzy
+msgid "devcp_versions_edit_compat_sure"
+msgstr ""
+"Are you <b>sure</b> you wish to remove compatibility with this application?"
+
+#: views/developers/versions_edit.thtml:100
+#, fuzzy
+msgid "devcp_versions_edit_delete_sure"
+msgstr "Are you <b>sure</b> you wish to permanently delete this file?"
+
+#: views/developers/versions_edit.thtml:203
+#, fuzzy
+msgid "devcp_versions_edit_header_approval"
+msgstr "Approval Information"
+
+#: views/developers/versions_edit.thtml:120
+#, fuzzy
+msgid "devcp_versions_edit_header_compat"
+msgstr "Compatible Applications"
+
+#: views/developers/versions_edit.thtml:74
+#, fuzzy
+msgid "devcp_versions_edit_header_file"
+msgstr "File Information"
+
+#: views/developers/versions_edit.thtml:189
+#, fuzzy
+msgid "devcp_versions_edit_header_license"
+msgstr "License"
+
+#. %s is the version number.
+#: views/developers/versions_edit.thtml:53
+#, fuzzy
+msgid "devcp_versions_edit_header_manage"
+msgstr "Manage Version %s"
+
+#: views/developers/versions_edit.thtml:212
+#, fuzzy
+msgid "devcp_versions_edit_header_notes"
+msgstr "Approval Notes"
+
+#: views/developers/versions_edit.thtml:98
+#, fuzzy
+msgid "devcp_versions_edit_img_delete"
+msgstr "Delete File"
+
+#. %1$s is the file id, e.g. 18723.
+#. %2$s is the platform name, e.g. ALL or Windows.
+#. %3$s is the _('date) created.
+#. %4$s is the status, e.g. "In Sandbox" or "Public".
+#. %5$s is the _('date') status was changed.
+#: views/developers/versions_edit.thtml:208
+#, fuzzy
+msgid "devcp_versions_edit_li_file"
+msgstr "File %1$s (%2$s) created on %3$s and changed to %4$s on %5$s"
+
+#: views/developers/versions_edit.thtml:190
+#, fuzzy
+msgid "devcp_versions_edit_license_description"
+msgstr ""
+"Please select the appropriate license for your add-on. This license "
+"specifies the rights you grant on your source code."
+
+#: views/developers/versions_edit.thtml:111
+#, fuzzy
+msgid "devcp_versions_edit_no_files"
+msgstr "No files found."
+
+#: views/developers/versions_edit.thtml:213
+#, fuzzy
+msgid "devcp_versions_edit_optional"
+msgstr "Optional information for the Editor that reviews this version."
+
+#: views/developers/versions_edit.thtml:151
+#, fuzzy
+msgid "devcp_versions_edit_remove_compat"
+msgstr "Remove Application Compatibility"
+
+#: views/developers/versions_edit.thtml:167
+#, fuzzy
+msgid "devcp_versions_edit_select_app"
+msgstr "Please Select an Application"
+
+#: views/developers/versions_edit.thtml:78
+#, fuzzy
+msgid "devcp_versions_edit_th_file"
+msgstr "File"
+
+#: views/developers/versions_edit.thtml:79
+#, fuzzy
+msgid "devcp_versions_edit_th_platform"
+msgstr "Platform"
+
+#: views/developers/versions_edit.thtml:80
+#, fuzzy
+msgid "devcp_versions_edit_th_size"
+msgstr "Size"
+
+#: views/developers/versions_edit.thtml:81
+#, fuzzy
+msgid "devcp_versions_edit_th_status"
+msgstr "Status"
+
+#: views/developers/versions_edit.thtml:183
+#, fuzzy
+msgid "devcp_versions_edit_transbox_releasenotes_description"
+msgstr ""
+"Information about changes in this release, new features, known bugs, and "
+"other useful information specific to this release/version. This information "
+"will also be available to users updating the add-on in the Firefox 3 Add-ons "
+"Manager interface."
+
+#: views/developers/versions_edit.thtml:182
+#, fuzzy
+msgid "devcp_versions_edit_transbox_releasenotes_name"
+msgstr "Release Notes"
+
+#: views/developers/versions_edit.thtml:164
+#, fuzzy
+msgid "devcp_versions_edit_unsaved_compat"
+msgstr ""
+"<strong>You have unsaved changes.</strong> Compatibility will not be deleted "
+"until you click Update Version below."
+
+#: views/developers/versions_edit.thtml:113
+#, fuzzy
+msgid "devcp_versions_edit_unsaved_files"
+msgstr ""
+"<strong>You have unsaved changes.</strong> Files will not be deleted until "
+"you click Update Version below."
+
+#: views/developers/versions_edit.thtml:218
+#, fuzzy
+msgid "devcp_versions_edit_update"
+msgstr "Update Versions"
+
+#: views/developers/versions.thtml:49
+#, fuzzy
+msgid "devcp_versions_header_manage"
+msgstr "Manage Versions and Files"
+
+#: views/developers/versions.thtml:87
+#, fuzzy
+msgid "devcp_versions_no_versions"
+msgstr "No versions."
+
+#. %s is a version number, base 10.
+#: views/developers/versions.thtml:46
+#, fuzzy
+msgid "devcp_versions_notice_success"
+msgstr "Version %s deleted successfully."
+
+#: views/developers/versions.thtml:73
+#, fuzzy
+msgid "devcp_versions_p_remove"
+msgstr ""
+"This version has no files associated with it and can be removed. Would you "
+"like to remove this version?"
+
+#: views/developers/versions.thtml:58
+#, fuzzy
+msgid "devcp_versions_th_created"
+msgstr "Created"
+
+#: views/developers/versions.thtml:57
+#, fuzzy
+msgid "devcp_versions_th_status"
+msgstr "Status"
+
+#: views/developers/versions.thtml:56
+#, fuzzy
+msgid "devcp_versions_th_version"
+msgstr "Version"
+
+#: controllers/downloads_controller.php:91
+msgid "downloads_disable_warning"
+msgstr "Цей додаток відключено"
+
+#: controllers/components/editors.php:57
+#, fuzzy
+msgid "editor_review_error_addon_not_nominated"
+msgstr "This add-on has not been nominated."
+
+#: controllers/components/editors.php:213
+#, fuzzy
+msgid "editor_review_error_file_not_pending"
+msgstr "This file is not pending review."
+
+#. Actions are, for example: approving or rejecting
+#: controllers/components/editors.php:79
+#: controllers/components/editors.php:182
+#, fuzzy
+msgid "editor_review_error_no_action"
+msgstr "Please select a review action."
+
+#: controllers/components/editors.php:192
+#, fuzzy
+msgid "editor_review_error_no_applications"
+msgstr "Please enter the applications you tested."
+
+#. Comments are required when an editor approves or rejects an add-on.
+#: controllers/components/editors.php:84
+#: controllers/components/editors.php:187
+#, fuzzy
+msgid "editor_review_error_no_comments"
+msgstr "Please enter review comments."
+
+#: controllers/components/editors.php:161
+#, fuzzy
+msgid "editor_review_error_no_files"
+msgstr "Please select at least one file to review."
+
+#: controllers/components/editors.php:197
+#, fuzzy
+msgid "editor_review_error_no_operating_system"
+msgstr "Please enter the operating systems you tested."
+
+#: views/editors/logs.thtml:51
+msgid "editorcp_logs_button_filter"
+msgstr "Фільтр"
+
+#: views/editors/logs.thtml:44
+msgid "editorcp_logs_filter_by"
+msgstr "Фільтр за типом/дією"
+
+#: views/editors/logs.thtml:42 controllers/editors_controller.php:964
+msgid "editorcp_logs_page_heading"
+msgstr "Журнал подій"
+
+#: views/elements/developers/editorsmenu.thtml:60
+msgid "editorcp_menu_eventlog_link"
+msgstr "Журнал подій"
+
+#: views/elements/developers/editorsmenu.thtml:62
+msgid "editorcp_menu_mainpage_link"
+msgstr "Ðазад до оÑновного"
+
+#: views/elements/developers/editorsmenu.thtml:61
+msgid "editorcp_menu_reviewlog_link"
+msgstr "Журнал оглÑду"
+
+#: views/elements/developers/editorsmenu.thtml:55
+msgid "editorcp_menu_summary_link"
+msgstr "ПідÑумок редактора"
+
+#: views/elements/developers/editorsmenu.thtml:52
+msgid "editorcp_menu_title"
+msgstr "Editor Tools"
+
+#: views/editors/reviewlog.thtml:49
+msgid "editorcp_reviewlog_button_filter"
+msgstr "Фільтр"
+
+#: views/editors/reviewlog.thtml:58
+msgid "editorcp_reviewlog_column_action"
+msgstr "ДіÑ"
+
+#: views/editors/reviewlog.thtml:56
+msgid "editorcp_reviewlog_column_addon"
+msgstr "Додаток"
+
+#: views/editors/reviewlog.thtml:55
+msgid "editorcp_reviewlog_column_date"
+msgstr "Дата"
+
+#: views/editors/reviewlog.thtml:57
+msgid "editorcp_reviewlog_column_editor"
+msgstr "Редактор"
+
+#: views/editors/reviewlog.thtml:94
+msgid "editorcp_reviewlog_comments_hide"
+msgstr "Приховати коментарі"
+
+#: views/editors/reviewlog.thtml:93
+msgid "editorcp_reviewlog_comments_show"
+msgstr "Показати коментарі"
+
+#. %1$s and %2$s are full <input> tags for dates
+#: views/editors/reviewlog.thtml:45
+#, php-format
+msgid "editorcp_reviewlog_entries_between"
+msgstr "ДивитиÑÑ Ð·Ð°Ð¿Ð¸Ñи між %s та %s"
+
+#: views/editors/reviewlog.thtml:104
+msgid "editorcp_reviewlog_none_found"
+msgstr "За цей період не знайдено переглÑдів."
+
+#: views/editors/reviewlog.thtml:42
+msgid "editorcp_reviewlog_page_heading"
+msgstr "Журнал оглÑду"
+
+#: views/editors/summary.thtml:61
+msgid "editorcp_summary_monthreviews_heading"
+msgstr "ПереглÑдів за міÑÑць"
+
+#: views/editors/summary.thtml:77
+msgid "editorcp_summary_neweditors_heading"
+msgstr "Ðові редактори"
+
+#: views/editors/summary.thtml:42
+msgid "editorcp_summary_page_heading"
+msgstr "ПідÑумок редактора"
+
+#: views/editors/summary.thtml:94
+msgid "editorcp_summary_recentactivity_heading"
+msgstr "ÐÐµÑ‰Ð¾Ð´Ð°Ð²Ð½Ñ Ð°ÐºÑ‚Ð¸Ð²Ð½Ñ–ÑÑ‚ÑŒ редакторів"
+
+#: views/editors/summary.thtml:45
+msgid "editorcp_summary_totalreviews_heading"
+msgstr "Загалом переглÑдів"
+
+#: controllers/editors_controller.php:248
+#: controllers/editors_controller.php:249
+msgid "editors_addon_review_pagetitle"
+msgstr "ПереглÑд додатку"
+
+#: controllers/editors_controller.php:349
+msgid "editors_error_js-formerror"
+msgstr "Будь лаÑка, заповніть наÑтупні полÑ:"
+
+#: controllers/editors_controller.php:350
+msgid "editors_error_review_one_file"
+msgstr "Будь лаÑка, оберіть принаймні один файл Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÐ³Ð»Ñду."
+
+#: controllers/editors_controller.php:274
+msgid "editors_error_self_reviews_forbidden"
+msgstr "СамопереглÑди недозволені."
+
+#: controllers/editors_controller.php:699
+msgid "editors_external_software"
+msgstr "Зовнішні програми"
+
+#: views/editors/featured.thtml:120 views/editors/featured.thtml:121
+msgid "editors_featured_add_feature"
+msgstr "Add feature"
+
+#: views/editors/featured.thtml:126
+msgid "editors_featured_add_feature_submit"
+msgstr "Add"
+
+#: views/editors/featured.thtml:49 controllers/editors_controller.php:832
+#: controllers/editors_controller.php:848
+msgid "editors_featured_addon_add_failure"
+msgstr "Failed to add feature."
+
+#: controllers/editors_controller.php:851
+msgid "editors_featured_addon_add_success"
+msgstr "Successfully added feature."
+
+#: views/editors/featured.thtml:50 controllers/editors_controller.php:839
+#: controllers/editors_controller.php:868
+#: controllers/editors_controller.php:886
+msgid "editors_featured_addon_edit_failure"
+msgstr "Failed to edit feature."
+
+#: views/editors/featured.thtml:51 controllers/editors_controller.php:888
+msgid "editors_featured_addon_edit_success"
+msgstr "Successfully edited feature."
+
+#: views/editors/featured.thtml:53 controllers/editors_controller.php:861
+msgid "editors_featured_addon_invalid_locale"
+msgstr "One or more locales are invalid."
+
+#: views/editors/featured.thtml:52 controllers/editors_controller.php:906
+msgid "editors_featured_addon_remove_failure"
+msgstr "Failed to remove feature."
+
+#: controllers/editors_controller.php:901
+msgid "editors_featured_addon_remove_success"
+msgstr "Successfully removed feature."
+
+#: controllers/editors_controller.php:915
+#: controllers/editors_controller.php:917
+msgid "editors_featured_addons_pagetitle"
+msgstr "Featured Add-ons"
+
+#: views/editors/featured.thtml:54 views/editors/featured.thtml:107
+msgid "editors_featured_edit_feature_submit"
+msgstr "Go"
+
+#: views/editors/featured.thtml:90 views/editors/featured.thtml:91
+msgid "editors_featured_remove_feature"
+msgstr "Remove feature"
+
+#: views/editors/queue.thtml:46
+msgid "editors_filter_queue"
+msgstr "Фільтр черги"
+
+#: views/editors/queue.thtml:182
+msgid "editors_helpful_links"
+msgstr "Помічні поÑиланнÑ"
+
+#: views/editors/queue.thtml:182
+msgid "editors_link_guide"
+msgstr "Керівництво редакторів"
+
+#: views/editors/queue.thtml:182
+msgid "editors_link_policy"
+msgstr "Політика додатків"
+
+#: views/editors/queue.thtml:47
+msgid "editors_notice_filter_session"
+msgstr "Ці фільтри залишатимутьÑÑ Ð½Ð° міÑці на цю ÑеÑÑ–ÑŽ або до очищеннÑ."
+
+#. %1 is the queue mode
+#: views/editors/queue.thtml:177 views/admin/flagged_queue.thtml:89
+msgid "editors_notice_none_found"
+msgstr "Зараз немає %s додатків Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÐ³Ð»Ñду."
+
+#: controllers/editors_controller.php:1040
+msgid "editors_one_day"
+msgstr "1 день"
+
+#: controllers/editors_controller.php:1048
+msgid "editors_one_hour"
+msgstr "1 година"
+
+#: controllers/editors_controller.php:1056
+msgid "editors_one_minute"
+msgstr "1 хвилина"
+
+#: controllers/editors_controller.php:64 controllers/editors_controller.php:73
+#: controllers/editors_controller.php:77
+msgid "editors_pagetitle"
+msgstr "Панель ÑƒÐ¿Ñ€Ð°Ð²Ð»Ñ–Ð½Ð½Ñ Ñ€ÐµÐ´Ð°ÐºÑ‚Ð¾Ñ€Ð°"
+
+#. %s is a comma separated list of platforms. Example: Windows, OS X
+#: controllers/editors_controller.php:680
+#: controllers/editors_controller.php:683
+#, php-format
+msgid "editors_platform_x_only"
+msgstr "лише %s"
+
+#: controllers/editors_controller.php:695
+msgid "editors_pre-release"
+msgstr "ÐŸÐ¾Ð¿ÐµÑ€ÐµÐ´Ð½Ñ Ð²ÐµÑ€ÑÑ–Ñ"
+
+#. %1 is the app name
+#: views/editors/queue.thtml:131
+#, php-format
+msgid "editors_queue_app_compatibility"
+msgstr "СуміÑніÑÑ‚ÑŒ %s"
+
+#: views/editors/queue.thtml:51
+#, fuzzy
+msgid "editors_queue_filter_label_addon"
+msgstr "Add-on or Author Email"
+
+#: views/editors/queue.thtml:72
+#, fuzzy
+msgid "editors_queue_filter_label_addontypes"
+msgstr "Add-on Types"
+
+#: views/editors/queue.thtml:56
+#, fuzzy
+msgid "editors_queue_filter_label_application"
+msgstr "Application"
+
+#: views/editors/queue.thtml:61
+#, fuzzy
+msgid "editors_queue_filter_label_maxversion"
+msgstr "Max. Version"
+
+#: views/editors/queue.thtml:78
+#, fuzzy
+msgid "editors_queue_filter_label_platforms"
+msgstr "Platforms"
+
+#: views/editors/queue.thtml:66
+#, fuzzy
+msgid "editors_queue_filter_label_submissionage"
+msgstr "Age of Submission (days)"
+
+#. %1$s is a number
+#: views/editors/queue.thtml:90
+#, fuzzy
+msgid "editors_queue_filter_result_count"
+msgid_plural "editors_queue_filter_result_count"
+msgstr[0] "Results of your filtered search: <strong>%1$s</strong> Add-on"
+msgstr[1] "Results of your filtered search: <strong>%1$s</strong> Add-ons"
+
+#: views/editors/queue.thtml:84
+msgid "editors_queue_submit_clean"
+msgstr "ОчиÑтка"
+
+#: views/editors/queue.thtml:83
+msgid "editors_queue_submit_filter"
+msgstr "Фільтр"
+
+#: controllers/editors_controller.php:133
+msgid "editors_queues_disabled"
+msgstr ""
+"Ð’ÑÑ– черги переглÑдів зараз відключено. Будь лаÑка, Ñпробуйте знову пізніше."
+
+#: views/editors/review.thtml:149
+#, fuzzy
+msgid "editors_review_a_edit_item"
+msgstr "Edit Item"
+
+#: views/editors/review.thtml:146
+#, fuzzy
+msgid "editors_review_a_item_history"
+msgstr "Item History"
+
+#: views/editors/review.thtml:148
+#, fuzzy
+msgid "editors_review_a_item_homepage"
+msgstr "Item Homepage"
+
+#: views/editors/review.thtml:145
+#, fuzzy
+msgid "editors_review_a_item_overview"
+msgstr "Item Overview"
+
+#: views/editors/review.thtml:147
+#, fuzzy
+msgid "editors_review_a_previews"
+msgstr "Previews"
+
+#: controllers/editors_controller.php:345
+msgid "editors_review_action"
+msgstr "Ð”Ñ–Ñ Ð¿ÐµÑ€ÐµÐ³Ð»Ñду"
+
+#: views/editors/review.thtml:159
+#, fuzzy
+msgid "editors_review_action_info"
+msgstr "Request More Information"
+
+#: views/editors/review.thtml:157
+msgid "editors_review_action_public"
+msgstr "Проштовхнути на публіку"
+
+#: views/editors/review.thtml:160
+msgid "editors_review_action_request_superreview"
+msgstr "ЗапроÑити ÑуперпереглÑд"
+
+#: views/editors/review.thtml:158
+msgid "editors_review_action_sandbox"
+msgstr "Залишити у піÑочниці"
+
+#: controllers/editors_controller.php:346
+msgid "editors_review_comments"
+msgstr "ПереглÑд коментарів"
+
+#: views/editors/review.thtml:182
+#, fuzzy
+msgid "editors_review_details_info_request"
+msgstr ""
+"Use this form to request more information from the author. They will receive "
+"an email and be able to answer here. You will be notified by email when they "
+"reply."
+
+#: views/editors/review.thtml:174
+msgid "editors_review_details_nominated_public"
+msgstr ""
+"Це позначить додаток Ñ– його оÑтанню верÑÑ–ÑŽ та файли Ñк публічні. Майбутні "
+"верÑÑ–Ñ— підуть у піÑочницю, поки Ñ—Ñ… не переглÑне редактор."
+
+#: views/editors/review.thtml:177
+msgid "editors_review_details_nominated_sandbox"
+msgstr "Це залишить додаток у піÑочниці."
+
+#: views/editors/review.thtml:166
+msgid "editors_review_details_pending_public"
+msgstr ""
+"Це Ñхвалить верÑÑ–ÑŽ піÑочниці публічного додатку до поÑви на публічній "
+"Ñтороні."
+
+#: views/editors/review.thtml:169
+msgid "editors_review_details_pending_sandbox"
+msgstr "Це змуÑить верÑÑ–ÑŽ піÑочниці публічного додатку залишитиÑÑ Ñƒ піÑочниці."
+
+#: views/editors/review.thtml:185
+msgid "editors_review_details_superreview"
+msgstr ""
+"Якщо у Ð²Ð°Ñ Ñ” думки щодо безпеки цього додатку, питань авторÑьких прав або "
+"інші думки, Ñкі повинен розглÑнути адмініÑтратор, введіть Ñвої коментарі у "
+"поле нижче. Їх буде надіÑлано адмініÑтратору, не автору."
+
+#: views/editors/review.thtml:134
+msgid "editors_review_file_diff_link"
+msgstr "ПорівнÑти з публічною верÑією"
+
+#: views/editors/review.thtml:131
+msgid "editors_review_file_viewcontents_link"
+msgstr "ДивитиÑÑ Ð·Ð¼Ñ–ÑÑ‚"
+
+#: views/editors/review.thtml:65
+msgid "editors_review_header_authors"
+msgstr "Ðвтори:"
+
+#: views/editors/review.thtml:79
+msgid "editors_review_header_categories"
+msgstr "Категорії:"
+
+#: views/editors/review.thtml:92
+msgid "editors_review_header_compatibility"
+msgstr "СуміÑніÑÑ‚ÑŒ:"
+
+#: views/editors/review.thtml:251
+msgid "editors_review_header_description"
+msgstr "ОпиÑ"
+
+#: views/editors/review.thtml:275
+msgid "editors_review_header_devcomments"
+msgstr "Коментарі розробника"
+
+#: views/editors/review.thtml:263
+msgid "editors_review_header_eula"
+msgstr "ЛУКК"
+
+#: views/editors/review.thtml:115
+msgid "editors_review_header_files"
+msgstr "Файли:"
+
+#: views/editors/review.thtml:284
+msgid "editors_review_header_itemhistory"
+msgstr "ІÑÑ‚Ð¾Ñ€Ñ–Ñ Ð¿Ñ€ÐµÐ´Ð¼ÐµÑ‚Ñƒ"
+
+#: views/editors/review.thtml:232
+msgid "editors_review_header_nominationmessage"
+msgstr "ÐŸÐ¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð¿Ð¾Ð´Ð°Ð½Ð½Ñ"
+
+#: views/editors/review.thtml:311
+msgid "editors_review_header_previews"
+msgstr "Попередні переглÑди"
+
+#: views/editors/review.thtml:269
+msgid "editors_review_header_privacy"
+msgstr "Умови конфіденційноÑÑ‚Ñ–"
+
+#. %1 is the add-on name and version
+#: views/editors/review.thtml:56
+#, php-format
+msgid "editors_review_header_review"
+msgstr "ПереглÑд %s"
+
+#: views/editors/review.thtml:239
+msgid "editors_review_header_reviewernotes"
+msgstr "Примітки переглÑдачу"
+
+#: views/editors/review.thtml:245
+msgid "editors_review_header_summary"
+msgstr "ПідÑумок"
+
+#: views/editors/review.thtml:257
+msgid "editors_review_header_versionnotes"
+msgstr "Примітки верÑÑ–Ñ—"
+
+#. a noun: shown in an add-on's editor review history
+#: views/elements/developers/editors_review_history_item.thtml:80
+#, fuzzy
+msgid "editors_review_history_info_reply"
+msgstr "Reply"
+
+#: views/elements/developers/editors_review_history_item.thtml:78
+#, fuzzy
+msgid "editors_review_history_info_request"
+msgstr "Information Request"
+
+#: views/elements/developers/editors_review_history_item.thtml:62
+#: views/editors/reviewlog.thtml:77
+msgid "editors_review_history_nominated_adminreview"
+msgstr "ПереглÑд адміна"
+
+#: views/elements/developers/editors_review_history_item.thtml:56
+#: views/editors/reviewlog.thtml:71
+msgid "editors_review_history_nominated_approved"
+msgstr "ÐŸÐ¾Ð´Ð°Ð½Ð½Ñ Ñхвалено/публіка"
+
+#: views/elements/developers/editors_review_history_item.thtml:59
+#: views/editors/reviewlog.thtml:74
+msgid "editors_review_history_nominated_denied"
+msgstr "ÐŸÐ¾Ð´Ð°Ð½Ð½Ñ Ð²Ñ–Ð´Ñ…Ð¸Ð»ÐµÐ½Ð¾/піÑочницÑ"
+
+#: views/editors/review.thtml:303
+msgid "editors_review_history_nonefound"
+msgstr "Ðеможливо знайти попередні переглÑди."
+
+#: views/elements/developers/editors_review_history_item.thtml:73
+#: views/editors/reviewlog.thtml:88
+msgid "editors_review_history_pending_adminreview"
+msgstr "ПереглÑд адміна"
+
+#: views/elements/developers/editors_review_history_item.thtml:67
+#: views/editors/reviewlog.thtml:82
+msgid "editors_review_history_pending_approved"
+msgstr "Схвалено/публіка"
+
+#: views/elements/developers/editors_review_history_item.thtml:70
+#: views/editors/reviewlog.thtml:85
+msgid "editors_review_history_pending_denied"
+msgstr "Відхилено/піÑочницÑ"
+
+#. link text in an add-on's editor review history, allowing to hide and show an information request's replies
+#. %1 is the number of replies
+#: views/elements/developers/editors_review_history_item.thtml:90
+#, fuzzy
+msgid "editors_review_history_show_hide_replies"
+msgid_plural "editors_review_history_show_hide_replies"
+msgstr[0] "Show/Hide Replies (%1$s)"
+msgstr[1] "Show/Hide Replies (%1$s)"
+
+#: views/editors/review.thtml:208
+msgid "editors_review_label_applications"
+msgstr "Програми:"
+
+#: views/editors/review.thtml:196
+msgid "editors_review_label_cannedresponse"
+msgstr "або оберіть Ñтандартну відповідь:"
+
+#: views/editors/review.thtml:190
+msgid "editors_review_label_comments"
+msgstr "Коментарі:"
+
+#: views/editors/review.thtml:204
+msgid "editors_review_label_operating_systems"
+msgstr "Операційні ÑиÑтеми:"
+
+#: views/editors/review.thtml:285 views/editors/review.thtml:312
+msgid "editors_review_link_pagetop"
+msgstr "Верх"
+
+#: views/editors/review.thtml:141
+#, fuzzy
+msgid "editors_review_mulitple_notice"
+msgstr ""
+"Notice: Only review more than one file if you have tested EVERY file you "
+"select."
+
+#: views/editors/review.thtml:51
+#, fuzzy
+msgid "editors_review_next_link"
+msgstr "next &raquo;"
+
+#: views/editors/review.thtml:322
+msgid "editors_review_previews_notfound"
+msgstr "Ðе знайдено попередніх переглÑдів."
+
+#: views/editors/review.thtml:50
+#, fuzzy
+msgid "editors_review_previous_link"
+msgstr "&laquo; prev"
+
+#: controllers/editors_controller.php:144
+#: controllers/editors_controller.php:146
+msgid "editors_review_queue_pagetitle"
+msgstr "ПереглÑд черги"
+
+#. %1 is the add-ons rank in the queue, %2 is the total queue length
+#: views/editors/review.thtml:47
+#, fuzzy
+msgid "editors_review_rank_in_queue"
+msgstr "<strong># %1$s</strong> of %2$s in queue"
+
+#. %1 is the add-ons rank in the queue, %2 is the total queue length. Both numbers
+#: views/editors/review.thtml:45
+#, fuzzy
+msgid "editors_review_rank_in_queue_filtered"
+msgstr "<strong># %1$s</strong> of %2$s in queue (filtered)"
+
+#: views/editors/review.thtml:223
+msgid "editors_review_submit_process_action"
+msgstr "Ð”Ñ–Ñ Ð¾Ð±Ñ€Ð¾Ð±ÐºÐ¸"
+
+#: views/editors/review.thtml:293
+msgid "editors_review_th_action"
+msgstr "ДіÑ"
+
+#: views/editors/review.thtml:294
+msgid "editors_review_th_comments"
+msgstr "Коментарі"
+
+#: views/editors/review.thtml:291
+msgid "editors_review_th_date"
+msgstr "Дата"
+
+#: views/editors/review.thtml:292
+msgid "editors_review_th_reviewer"
+msgstr "ПереглÑдач"
+
+#: views/editors/review.thtml:290
+msgid "editors_review_th_version_file"
+msgstr "ВерÑÑ–Ñ/файл"
+
+#: views/editors/review.thtml:217
+#, fuzzy
+msgid "editors_review_update_notify_once"
+msgstr ""
+"Notify me the next time this add-on is updated. (Subsequent updates will not "
+"generate an email)"
+
+#: controllers/editors_controller.php:298
+msgid "editors_reviewed_successfully"
+msgstr "ПереглÑд уÑпішно оброблено."
+
+#: views/editors/reviews_queue.thtml:106
+#, fuzzy
+msgid "editors_reviews_action_delete_review"
+msgstr "Delete review"
+
+#: views/editors/reviews_queue.thtml:104
+#, fuzzy
+msgid "editors_reviews_action_keep"
+msgstr "Remove flags; keep review"
+
+#: views/editors/reviews_queue.thtml:102
+msgid "editors_reviews_action_skip"
+msgstr "ПропуÑк"
+
+#: views/editors/reviews_queue.thtml:100
+msgid "editors_reviews_header_action"
+msgstr "ДіÑ"
+
+#: views/editors/reviews_queue.thtml:67
+msgid "editors_reviews_in_reply_to"
+msgstr "У відповідь на:"
+
+#: controllers/editors_controller.php:748
+msgid "editors_reviews_processed"
+msgstr "ПереглÑди оброблено уÑпішно!"
+
+#: views/editors/reviews_queue.thtml:117
+msgid "editors_reviews_queue_empty"
+msgstr "Ðа модеруванні зараз немає переглÑдів."
+
+#: views/editors/reviews_queue.thtml:111
+msgid "editors_reviews_submit_process_reviews"
+msgstr "ПереглÑди обробки"
+
+#: controllers/editors_controller.php:691
+msgid "editors_site_specific"
+msgstr "Окремий Ñайт"
+
+#: controllers/editors_controller.php:348
+msgid "editors_tested_app"
+msgstr "Випробувана програма"
+
+#: controllers/editors_controller.php:347
+msgid "editors_tested_os"
+msgstr "Випробувані операційні ÑиÑтеми"
+
+#: views/editors/queue.thtml:151
+msgid "editors_th_additional_info"
+msgstr "Додаткова інформаціÑ"
+
+#: views/editors/featured.thtml:63 views/editors/queue.thtml:109
+#: views/admin/flagged_queue.thtml:53
+msgid "editors_th_addon"
+msgstr "Додаток"
+
+#: views/editors/queue.thtml:125
+msgid "editors_th_addontype"
+msgstr "Тип"
+
+#: views/editors/featured.thtml:64
+msgid "editors_th_locales"
+msgstr "Restrict to locales?"
+
+#: views/editors/queue.thtml:148
+#, fuzzy
+msgid "editors_th_nomination_age"
+msgstr "Time in Queue"
+
+#: views/editors/queue.thtml:101 views/editors/queue.thtml:117
+#: views/editors/queue.thtml:144
+#, fuzzy
+msgid "editors_th_sort_ascending"
+msgstr "Ascending sort"
+
+#: views/editors/queue.thtml:105 views/editors/queue.thtml:121
+#: views/editors/queue.thtml:140
+#, fuzzy
+msgid "editors_th_sort_descending"
+msgstr "Descending sort"
+
+#. %s is a number
+#: controllers/editors_controller.php:1036
+#, php-format
+msgid "editors_x_days"
+msgstr "%s днів"
+
+#. %s is a number
+#: controllers/editors_controller.php:1044
+#, php-format
+msgid "editors_x_hours"
+msgstr "%s годин"
+
+#. %s is a number
+#: controllers/editors_controller.php:1052
+#, php-format
+msgid "editors_x_minutes"
+msgstr "%s хвилин"
+
+#: views/errors/error401.thtml:50 controllers/components/simple_acl.php:81
+#: controllers/components/simple_acl.php:82
+#: controllers/components/simple_acl.php:83 controllers/components/amo.php:607
+#: controllers/components/amo.php:608 controllers/components/amo.php:609
+#: controllers/reviews_controller.php:353
+#: controllers/reviews_controller.php:485
+#: controllers/collections_controller.php:438
+#: controllers/collections_controller.php:496
+#: controllers/collections_controller.php:504
+#: controllers/collections_controller.php:971
+#: controllers/collections_controller.php:1034
+#: controllers/collections_controller.php:1077
+msgid "error_access_denied"
+msgstr "У доÑтупі відмовлено"
+
+#: views/errors/error401.thtml:52
+msgid "error_access_denied_message"
+msgstr "Вам недозволено оглÑдати цю Ñторінку."
+
+#: controllers/collections_controller.php:1039
+#, fuzzy
+msgid "error_addon_exists"
+msgstr "Add-on already exists!"
+
+#: controllers/developers_controller.php:200
+#: controllers/developers_controller.php:593
+#: controllers/developers_controller.php:1016
+#: controllers/developers_controller.php:1429
+#: controllers/downloads_controller.php:95
+#: controllers/downloads_controller.php:102
+#: controllers/downloads_controller.php:164
+#: controllers/statistics_controller.php:135
+#: controllers/previews_controller.php:115
+#: controllers/previews_controller.php:206
+#: controllers/previews_controller.php:307
+#: controllers/reviews_controller.php:77
+#: controllers/reviews_controller.php:240
+#: controllers/reviews_controller.php:332
+#: controllers/reviews_controller.php:340 controllers/api_controller.php:123
+#: controllers/api_controller.php:759 controllers/addons_controller.php:131
+#: controllers/addons_controller.php:197
+#: controllers/addons_controller.php:1407
+#: controllers/addons_controller.php:1465
+#: controllers/addons_controller.php:1469
+#: controllers/addons_controller.php:1503
+#: controllers/editors_controller.php:265
+#: controllers/collections_controller.php:1041
+#: controllers/collections_controller.php:1074
+msgid "error_addon_notfound"
+msgstr "Додаток не знайдено!"
+
+#: controllers/files_controller.php:83 controllers/files_controller.php:196
+msgid "error_addon_notviewable"
+msgstr "Цей додаток не переглÑдаєтьÑÑ Ñ‚ÑƒÑ‚."
+
+#: controllers/reviews_controller.php:246
+msgid "error_addon_selfreview"
+msgstr "Ви не можете оглÑдати Ñвої влаÑні додатки."
+
+#: controllers/addons_controller.php:970
+msgid "error_browse_no_addons"
+msgstr "Жодних додатків у цій категорії!"
+
+#: controllers/api_controller.php:424
+#, fuzzy
+msgid "error_collection_feed_notfound"
+msgstr "Add-on feed not found."
+
+#: views/users/register.thtml:65 views/users/edit.thtml:194
+msgid "error_email_invalid"
+msgstr "Це недійÑна email адреÑа."
+
+#: views/users/pwreset.thtml:74 views/users/register.thtml:70
+#: views/users/register.thtml:80 views/users/register.thtml:86
+#: views/users/edit.thtml:105 views/users/edit.thtml:111
+#: views/users/edit.thtml:192 views/admin/users_edit.thtml:78
+#: views/admin/users_edit.thtml:83 views/reviews/add.thtml:80
+#: views/reviews/add.thtml:104
+msgid "error_field_required"
+msgstr "Це поле не повинно бути пуÑтим."
+
+#: controllers/files_controller.php:75 controllers/files_controller.php:93
+#: controllers/files_controller.php:96 controllers/files_controller.php:163
+#: controllers/files_controller.php:176 controllers/files_controller.php:185
+#: controllers/files_controller.php:204 controllers/editors_controller.php:412
+msgid "error_file_notfound"
+msgstr "Файл не знайдено!"
+
+#. %s is a filename
+#: controllers/editors_controller.php:430
+#, php-format
+msgid "error_file_x_notfound"
+msgstr "Помилка файлу: %s не знайдено."
+
+#: views/collections/add.thtml:55 views/collections/edit.thtml:89
+#: views/users/register.thtml:54 views/users/edit.thtml:81
+#: views/reviews/add.thtml:70 controllers/groups_controller.php:80
+#: controllers/groups_controller.php:102
+msgid "error_formerrors"
+msgstr "У цій формі Ñ” помилки. Будь лаÑка, виправте Ñ—Ñ… Ñ– знову надішліть."
+
+#: views/users/register.thtml:109
+msgid "error_invalid_captcha"
+msgstr "Ðевірно введено код перевірки людÑноÑÑ‚Ñ– (каптча), пробуйте ще раз!"
+
+#: views/users/register.thtml:100 views/users/edit.thtml:125
+#: views/admin/users_edit.thtml:101
+msgid "error_invalid_url"
+msgstr ""
+"Цей URL має недійÑний формат. ДійÑні URLи виглÑдають http://example.com/"
+"my_page."
+
+#. %s is a string representing what's missing. Example: file_id
+#: controllers/downloads_controller.php:65
+#: controllers/users_controller.php:185 controllers/users_controller.php:264
+#: controllers/users_controller.php:559 controllers/users_controller.php:653
+#: controllers/reviews_controller.php:71
+#: controllers/reviews_controller.php:234
+#: controllers/reviews_controller.php:325
+#: controllers/reviews_controller.php:473
+#: controllers/reviews_controller.php:475
+#: controllers/addons_controller.php:182
+#: controllers/addons_controller.php:1381
+#: controllers/addons_controller.php:1455
+#: controllers/collections_controller.php:266
+#: controllers/collections_controller.php:285
+#: controllers/collections_controller.php:346
+#: controllers/collections_controller.php:443
+#: controllers/collections_controller.php:482
+#: controllers/collections_controller.php:936
+#: controllers/collections_controller.php:959
+#: controllers/collections_controller.php:960
+#: controllers/collections_controller.php:975
+#: controllers/collections_controller.php:977
+#: controllers/collections_controller.php:994
+#: controllers/collections_controller.php:1003
+#: controllers/collections_controller.php:1016
+#: controllers/collections_controller.php:1017
+#: controllers/collections_controller.php:1024
+#: controllers/collections_controller.php:1070
+#: controllers/collections_controller.php:1090
+#, php-format
+msgid "error_missing_argument"
+msgstr "Бракує аргумента: %s"
+
+#: controllers/components/amo.php:507 controllers/components/amo.php:532
+#, fuzzy
+msgid "error_no_files_in_addon"
+msgstr "No Files"
+
+#: controllers/previews_controller.php:200
+msgid "error_preview_notfound"
+msgstr "Знімок не знайдено!"
+
+#: views/addons/display.thtml:400 views/reviews/add.thtml:98
+msgid "error_review_rating_required"
+msgstr "Ви повинні зазначити рейтинг."
+
+#: controllers/users_controller.php:160
+msgid "error_user_already_confirmed"
+msgstr "Цей рахунок кориÑтувача вже підтверджений."
+
+#: controllers/users_controller.php:202 controllers/users_controller.php:276
+#: controllers/users_controller.php:569 controllers/users_controller.php:581
+#: controllers/users_controller.php:587 controllers/users_controller.php:610
+#: controllers/users_controller.php:627
+msgid "error_user_badconfirmationcode"
+msgstr "ÐедійÑний код підтвердженнÑ!"
+
+#: views/users/pwreset.thtml:79 views/users/register.thtml:75
+#: views/users/edit.thtml:183
+msgid "error_user_confirmpw_nomatch"
+msgstr "Паролі не Ñпіпадають."
+
+#: views/users/register.thtml:65 views/users/edit.thtml:190
+#: controllers/users_controller.php:617
+msgid "error_user_email_notunique"
+msgstr "Ð¦Ñ email адреÑа вже зайнÑта іншим кориÑтувачем."
+
+#: controllers/users_controller.php:596
+msgid "error_user_emailchange_expired"
+msgstr ""
+"The email change has expired. Please change your email address again in your "
+"user profile and click the link in the confirmation email as soon as you "
+"receive it."
+
+#: controllers/collections_controller.php:985
+#, fuzzy
+msgid "error_user_exists"
+msgstr ""
+"Users can only have one role at a time. Please remove the user from any "
+"existing roles before continuing."
+
+#: views/users/register.thtml:91 views/users/edit.thtml:116
+#: views/admin/users_edit.thtml:88
+msgid "error_user_nickname_notunique"
+msgstr "Це прізвиÑько вже зайнÑте."
+
+#: views/users/pwreset.thtml:54 controllers/users_controller.php:191
+#: controllers/users_controller.php:270 controllers/users_controller.php:603
+#: controllers/users_controller.php:659
+#: controllers/collections_controller.php:988
+#: controllers/collections_controller.php:998
+msgid "error_user_notfound"
+msgstr "КориÑтувача не знайдено!"
+
+#: views/users/activatefirst.thtml:47
+msgid "error_user_unconfirmed"
+msgstr ""
+"Будь лаÑка, Ñпочатку підтвердіть ваш кориÑтувацький рахунок кодом, Ñкий ви "
+"отримали email’ом."
+
+#: views/users/login.thtml:67
+msgid "error_username_or_pw_wrong"
+msgstr "Ðевірне Ñ–Ð¼â€™Ñ ÐºÐ¾Ñ€Ð¸Ñтувача або пароль!"
+
+#: controllers/editors_controller.php:260
+msgid "error_version_notfound"
+msgstr "ВерÑÑ–ÑŽ не знайдено!"
+
+#: views/users/delete.thtml:125 views/users/edit.thtml:173
+msgid "error_wrong_password"
+msgstr "Введено невірний пароль!"
+
+#: views/elements/amo2009/homepage_addon.thtml:122
+#: views/elements/feature.thtml:122
+msgid "feature_learnmore"
+msgstr "ДізнайтеÑÑŒ більше"
+
+#. %1 is the add-on name
+#: views/elements/amo2009/homepage_addon.thtml:123
+#: views/elements/feature.thtml:123
+#, php-format
+msgid "feature_learnmore_about_addon"
+msgstr "ДізнатиÑÑŒ більше про %1$s"
+
+#. %1$s is a number
+#: views/elements/amo2009/reviews.thtml:52
+#: views/elements/addon_listitem.thtml:112 views/elements/feature.thtml:99
+#: views/addons/browse_thumbs.thtml:86
+#, php-format
+msgid "feature_reviews"
+msgid_plural "feature_reviews"
+msgstr[0] "оглÑдів"
+msgstr[1] "оглÑдів"
+
+#: views/elements/amo2009/homepage_addon.thtml:127
+#: views/elements/feature.thtml:127
+msgid "feature_view_more_from_category"
+msgstr "ПереглÑнути ще з"
+
+#. This appears on a page that views the source of an add-on. This link will return
+#. the user to the add-on's main page
+#: views/files/browse.thtml:65
+#, fuzzy
+msgid "file_browser_link_addon"
+msgstr "Back to add-on"
+
+#. There is a list of directories and files on the page. Clicking this will show the
+#. contents of all the directories (normally you would click on each one to see the
+#. contents)
+#: views/files/browse.thtml:67
+#, fuzzy
+msgid "file_browser_link_expand_all"
+msgstr "Expand all"
+
+#. This appears on a page that views the source of an add-on. This link will return
+#. the user to the add-on's review page (it only appears if the add-on is being
+#. reviewed)
+#: views/files/browse.thtml:64
+#, fuzzy
+msgid "file_browser_link_review"
+msgstr "Back to review"
+
+#. The title of the page for viewing an add-on's source.
+#. %1$s is the name of the add-on
+#. %2$s is the name of the current application (e.g. Firefox or Thunderbird)
+#: views/files/browse.thtml:46
+#, fuzzy
+msgid "file_browser_title"
+msgstr "%1$s :: File Browser :: %2$s Add-ons"
+
+#. This appears on a page that views the source of an add-on. There is a list of
+#. directories and files on the page. Clicking this link will toggle between an
+#. expanded or a collapsed list. This string should be kept short.
+#: views/files/browse.thtml:68
+#, fuzzy
+msgid "file_browser_toggle_expand_collapse"
+msgstr "+/-"
+
+#. Link text for the AMO About page.
+#: views/elements/footer.thtml:72 views/layouts/amo2009.thtml:341
+#, fuzzy
+msgid "footer_a_about"
+msgstr "About"
+
+#. Link text to the AMO blog.
+#: views/elements/footer.thtml:74 views/layouts/amo2009.thtml:343
+#, fuzzy
+msgid "footer_a_blog"
+msgstr "Blog"
+
+#. Link text to the Frequently Asked Questions page.
+#: views/elements/footer.thtml:73 views/layouts/amo2009.thtml:342
+#, fuzzy
+msgid "footer_a_faq"
+msgstr "FAQ"
+
+#. Full text for the FAQ abbreviation.
+#: views/elements/footer.thtml:73 views/pages/collector_features.thtml:72
+#: views/layouts/amo2009.thtml:342
+#, fuzzy
+msgid "footer_abbr_faq"
+msgstr "Frequently Asked Questions"
+
+#: views/elements/footer.thtml:67 views/layouts/amo2009.thtml:336
+msgid "footer_all_rights_reserved"
+msgstr "Ð’ÑÑ– права захищені."
+
+#: views/elements/footer.thtml:67 views/layouts/amo2009.thtml:336
+msgid "footer_copyright"
+msgstr "ÐвторÑькі права"
+
+#: views/elements/footer.thtml:71 views/layouts/amo2009.thtml:340
+msgid "footer_credits"
+msgstr "Колектив"
+
+#: views/elements/footer.thtml:76 views/layouts/amo2009.thtml:346
+msgid "footer_disclaimer"
+msgstr ""
+"Mozilla люб’Ñзно надає поÑÐ¸Ð»Ð°Ð½Ð½Ñ Ð½Ð° ці програми, але не відповідає за Ñ—Ñ… "
+"заÑтоÑÑƒÐ²Ð°Ð½Ð½Ñ Ñ‡Ð¸ інформацію. Будь-Ñкі питаннÑ, Ñкарги або позови ÑтоÑовно "
+"програм Ñлід надÑилати до відповідного поÑтачальника програмного "
+"забезпеченнÑ."
+
+#: views/elements/footer.thtml:61 views/layouts/amo2009.thtml:332
+msgid "footer_lang_form_lang_submit_go"
+msgstr "Далі"
+
+#: views/elements/footer.thtml:70 views/layouts/amo2009.thtml:339
+msgid "footer_legal_notices"
+msgstr "Правові повідомленнÑ"
+
+#: views/elements/footer.thtml:50 views/layouts/amo2009.thtml:321
+msgid "footer_other_languages"
+msgstr "Інші мови:"
+
+#: views/elements/footer.thtml:69 views/layouts/amo2009.thtml:338
+msgid "footer_privacy_policy"
+msgstr "Умови конфіденційноÑÑ‚Ñ–"
+
+#: models/addontype.php:79
+msgid "general_addontype_dict"
+msgstr "Словник"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:100
+msgid "general_addontype_dict_plural"
+msgstr "Словники"
+
+#: models/addontype.php:75
+msgid "general_addontype_extension"
+msgstr "РозширеннÑ"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:98
+msgid "general_addontype_extension_plural"
+msgstr "РозширеннÑ"
+
+#: models/addontype.php:85
+msgid "general_addontype_lpaddon"
+msgstr "Пакет перекладу додатка"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:103
+msgid "general_addontype_lpaddon_plural"
+msgstr "Пакети перекладу додатка"
+
+#: models/addontype.php:83
+msgid "general_addontype_lpapp"
+msgstr "Пакет перекладу"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:102
+msgid "general_addontype_lpapp_plural"
+msgstr "Пакети перекладу"
+
+#: models/addontype.php:87
+msgid "general_addontype_plugin"
+msgstr "Модуль"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:104
+msgid "general_addontype_plugin_plural"
+msgstr "Модулі"
+
+#: models/addontype.php:81
+msgid "general_addontype_search"
+msgstr "ЗаÑіб Пошуку"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:101
+msgid "general_addontype_search_plural"
+msgstr "ЗаÑіб Пошуку"
+
+#: models/addontype.php:77
+msgid "general_addontype_theme"
+msgstr "Тема"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:99
+msgid "general_addontype_theme_plural"
+msgstr "Теми"
+
+#: config/language.php:367
+#, fuzzy
+msgid "general_languages_all_locales"
+msgstr "All Locales"
+
+#: views/layouts/amo2009.thtml:249
+#, fuzzy
+msgid "header_brand_name"
+msgstr "Mozilla"
+
+#. %1$s is the application name. Example: Firefox
+#: views/elements/header.thtml:111 views/elements/header.thtml:122
+#: views/layouts/amo2009.thtml:248
+#, php-format
+msgid "header_home_tooltip"
+msgstr "ПовернутиÑÑŒ на %1$s домашню Ñторінку додатків"
+
+#: views/elements/header.thtml:87
+msgid "header_main_firefox_header"
+msgstr "Додатки Firefox"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:218
+#, fuzzy
+msgid "header_main_firefox_header_with_logo"
+msgstr ""
+"Add-ons <em>for</em> <img alt=\"Firefox\" src=\"%1$s\" /> <strong>Firefox</"
+"strong>"
+
+#: views/elements/header.thtml:99
+msgid "header_main_header"
+msgstr "Додатки"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:242
+#, fuzzy
+msgid "header_main_header_with_logo"
+msgstr "Add-ons <img alt=\"Add-ons\" src=\"%1$s\" />"
+
+#: views/elements/header.thtml:90
+msgid "header_main_seamonkey_header"
+msgstr "Додатки Seamonkey"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:224
+#, fuzzy
+msgid "header_main_seamonkey_header_with_logo"
+msgstr ""
+"Add-ons <em>for</em> <img alt=\"seamonkey\" src=\"%1$s\" /> "
+"<strong>SeaMonkey</strong>"
+
+#: views/elements/header.thtml:93
+msgid "header_main_sunbird_header"
+msgstr "Додатки Sunbird"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:230
+#, fuzzy
+msgid "header_main_sunbird_header_with_logo"
+msgstr ""
+"Add-ons <em>for</em> <img alt=\"sunbird\" src=\"%1$s\" /> <strong>Sunbird</"
+"strong>"
+
+#: views/elements/header.thtml:96
+msgid "header_main_thunderbird_header"
+msgstr "Додатки Thunderbird"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:236
+#, fuzzy
+msgid "header_main_thunderbird_header_with_logo"
+msgstr ""
+"Add-ons <em>for</em> <img alt=\"thunderbird\" src=\"%1$s\" /> "
+"<strong>Thunderbird</strong>"
+
+#: views/layouts/amo2009.thtml:205
+#, fuzzy
+msgid "header_navaccess_applications_menu"
+msgstr "Skip to other applications menu"
+
+#: views/layouts/amo2009.thtml:204
+#, fuzzy
+msgid "header_navaccess_categories_menu"
+msgstr "Skip to categories menu"
+
+#: views/layouts/amo2009.thtml:202
+#, fuzzy
+msgid "header_navaccess_main_content"
+msgstr "Skip to main content"
+
+#: views/layouts/amo2009.thtml:203
+#, fuzzy
+msgid "header_navaccess_search_form"
+msgstr "Skip to search form"
+
+#: views/elements/header.thtml:62
+msgid "header_navlink_addons"
+msgstr "Додатки"
+
+#: views/elements/developers/sidebar.thtml:72
+#: views/elements/developers/myaddons.thtml:50 views/elements/header.thtml:159
+#: views/addons/display.thtml:378
+msgid "header_navlink_login"
+msgstr "Увійти"
+
+#: views/elements/header.thtml:156 views/layouts/amo2009.thtml:304
+msgid "header_navlink_logout"
+msgstr "Вийти"
+
+#: views/elements/header.thtml:145 views/layouts/amo2009.thtml:303
+msgid "header_navlink_myaccount"
+msgstr "Мій профіль"
+
+#: views/elements/header.thtml:158
+msgid "header_navlink_register"
+msgstr "РеєÑтраціÑ"
+
+#. %1 is the URL to the registration page
+#. %2 is the URL to the login page
+#: views/layouts/amo2009.thtml:278
+#, fuzzy
+msgid "header_navlink_register_or_login"
+msgstr "<a href=\"%1$s\">Register</a> or <a href=\"%2$s\">Log in</a>"
+
+#: views/layouts/amo2009.thtml:285
+#, fuzzy
+msgid "header_navlink_tools"
+msgstr "Tools"
+
+#. %s is the add-on name
+#: views/elements/collections_interactive_addon.thtml:62
+#: views/elements/amo2009/homepage_addon.thtml:77
+#: views/elements/addon_discussionheader.thtml:62
+#: views/elements/addon_listitem.thtml:67 views/elements/feature.thtml:84
+#: views/addons/category_landing.thtml:87 views/addons/browse_thumbs.thtml:60
+#, php-format
+msgid "img_preview_of"
+msgstr "Попередній переглÑд %s"
+
+#. %1 is the login URL for the link tag
+#. %2 is the link to an explanatory page.
+#: views/elements/amo2009/install.thtml:307 views/elements/install.thtml:255
+msgid "install_a_login_to_install"
+msgstr "<a href=\"%1$s\">Увійдіть</a>, щоб вÑтановити цей додаток"
+
+#. %1 is the URL for the Experimental Add-ons section of the FAQ page
+#: views/elements/amo2009/install.thtml:283 views/elements/install.thtml:232
+#, fuzzy
+msgid "install_button_confirm_exp_install"
+msgstr ""
+"Let me install this experimental add-on. <a href=\"%1$s\">What's this?</a>"
+
+#. %1$s is the application name. Example: Firefox
+#. %2$s is an optional string used to specify a platform. Example: (Windows)
+#: views/elements/amo2009/install.thtml:128 views/elements/install.thtml:75
+#, php-format
+msgid "install_button_text"
+msgstr "Додати до %s %s"
+
+#. %1 is the add-on name, %2 is the app name
+#: views/elements/amo2009/install.thtml:191
+#: views/elements/amo2009/install.thtml:206
+#: views/elements/amo2009/install.thtml:249
+#: views/elements/amo2009/install.thtml:298 views/elements/install.thtml:150
+#: views/elements/install.thtml:165 views/elements/install.thtml:202
+#: views/elements/install.thtml:246
+#, php-format
+msgid "install_button_title"
+msgstr "Додати %1$s до %2$s"
+
+#. %1$s is the add-on name
+#: views/elements/amo2009/install.thtml:200 views/elements/install.thtml:159
+#, php-format
+msgid "install_download"
+msgstr "Завантажити %1$s"
+
+#: views/elements/amo2009/install.thtml:147 views/elements/install.thtml:94
+msgid "install_error_addon_not_found"
+msgstr "Цей додаток недоÑтупний."
+
+#: views/addons/dictionaries.thtml:65
+msgid "langtools_a11y_tablesummary"
+msgstr "Перелік мовних пакетів та Ñловників."
+
+#: views/addons/dictionaries.thtml:47
+msgid "langtools_download_dictionary"
+msgstr "Завантажити Ñловник"
+
+#: views/addons/dictionaries.thtml:48
+msgid "langtools_download_langpack"
+msgstr "Завантажити мовний пакет"
+
+#: views/addons/dictionaries.thtml:63 controllers/components/amo.php:685
+#: controllers/addons_controller.php:1239
+msgid "langtools_header_dicts_and_langpacks"
+msgstr "Словники та мовні пакети"
+
+#: views/addons/dictionaries.thtml:44
+msgid "langtools_install_dictionary"
+msgstr "Ð’Ñтановити Ñловник"
+
+#: views/addons/dictionaries.thtml:45
+msgid "langtools_install_langpack"
+msgstr "Ð’Ñтановити мовний пакет"
+
+#: views/addons/dictionaries.thtml:69
+msgid "langtools_tableheader_dictionary"
+msgstr "Словник"
+
+#: views/addons/dictionaries.thtml:70
+msgid "langtools_tableheader_langpack"
+msgstr "Мовний пакет"
+
+#: views/addons/dictionaries.thtml:68
+msgid "langtools_tableheader_language"
+msgstr "Мова"
+
+#: models/license.php:65
+#, fuzzy
+msgid "license_custom"
+msgstr "Custom License"
+
+#: config/bootstrap.php:303
+#, fuzzy
+msgid "licenses_bsd"
+msgstr "BSD License"
+
+#: config/bootstrap.php:298
+#, fuzzy
+msgid "licenses_gpl_2.0"
+msgstr "GNU General Public License, version 2.0"
+
+#: config/bootstrap.php:299
+#, fuzzy
+msgid "licenses_gpl_3.0"
+msgstr "GNU General Public License, version 3.0"
+
+#: config/bootstrap.php:300
+#, fuzzy
+msgid "licenses_lgpl_2.1"
+msgstr "GNU Lesser General Public License, version 2.1"
+
+#: config/bootstrap.php:301
+#, fuzzy
+msgid "licenses_lgpl_3.0"
+msgstr "GNU Lesser General Public License, version 3.0"
+
+#: config/bootstrap.php:302
+#, fuzzy
+msgid "licenses_mit"
+msgstr "MIT/X11 License"
+
+#: config/bootstrap.php:297
+#, fuzzy
+msgid "licenses_mpl_1.1"
+msgstr "Mozilla Public License, version 1.1"
+
+#: views/users/emailchange.thtml:51 views/users/delete.thtml:55
+#: views/users/delete.thtml:137 views/users/edit.thtml:74
+#: views/reviews/flag.thtml:54
+msgid "link_return_to_front_page"
+msgstr "Клацніть тут щоб повернутиÑÑŒ на початкову Ñторінку."
+
+#: views/elements/amo2009/addon_list_options.thtml:46
+#: views/elements/addon_list_options.thtml:46
+msgid "list_sortby_date"
+msgstr "Датою"
+
+#: views/elements/amo2009/addon_list_options.thtml:47
+#: views/elements/addon_list_options.thtml:47
+msgid "list_sortby_downloads"
+msgstr "ЗавантаженнÑми"
+
+#: views/elements/amo2009/addon_list_options.thtml:45
+#: views/elements/addon_list_options.thtml:45
+msgid "list_sortby_name"
+msgstr "Ðазвою"
+
+#: views/elements/amo2009/addon_list_options.thtml:48
+#: views/elements/addon_list_options.thtml:48
+msgid "list_sortby_rating"
+msgstr "Рейтингом"
+
+#: config/bootstrap.php:278
+#, fuzzy
+msgid "main_prettyname_fennec"
+msgstr "Fennec"
+
+#: config/bootstrap.php:274
+msgid "main_prettyname_firefox"
+msgstr "Firefox"
+
+#: config/bootstrap.php:277
+msgid "main_prettyname_seamonkey"
+msgstr "SeaMonkey"
+
+#: config/bootstrap.php:276
+msgid "main_prettyname_sunbird"
+msgstr "Sunbird"
+
+#: config/bootstrap.php:275
+msgid "main_prettyname_thunderbird"
+msgstr "Thunderbird"
+
+#: views/elements/addon_categories.thtml:52
+msgid "nav_category_dicts_langpacks"
+msgstr "Словники та мовні пакети"
+
+#: views/elements/addon_categories.thtml:55
+msgid "nav_category_themes"
+msgstr "Теми"
+
+#: views/elements/app_chooser.thtml:47 views/layouts/amo2009.thtml:255
+msgid "other_apps_tooltip"
+msgstr "Знайти додатки Ð´Ð»Ñ Ñ–Ð½ÑˆÐ¾Ñ— програми"
+
+#. In a user list: user 1, user 2, "others"
+#: views/helpers/addons_html.php:222
+msgid "other_users"
+msgstr "інші"
+
+#: controllers/pages_controller.php:90
+#, fuzzy
+msgid "page_title_appversions"
+msgstr "Application Versions"
+
+#: controllers/pages_controller.php:115
+#, fuzzy
+msgid "page_title_collector"
+msgstr "Add-on Collector"
+
+#: controllers/pages_controller.php:117
+#, fuzzy
+msgid "page_title_collector_faq"
+msgstr "Add-on Collector FAQ"
+
+#: controllers/pages_controller.php:119
+#, fuzzy
+msgid "page_title_collector_features"
+msgstr "Add-on Collector Features"
+
+#: controllers/pages_controller.php:122
+#, fuzzy
+msgid "page_title_collector_firstrun"
+msgstr "Welcome to the Add-on Collector"
+
+#: controllers/pages_controller.php:92
+#, fuzzy
+msgid "page_title_credits"
+msgstr "Credits"
+
+#: controllers/pages_controller.php:113
+#, fuzzy
+msgid "page_title_developer_faq"
+msgstr "Developer FAQ"
+
+#: controllers/pages_controller.php:111
+#, fuzzy
+msgid "page_title_faq"
+msgstr "Frequently Asked Questions"
+
+#: controllers/pages_controller.php:94
+#, fuzzy
+msgid "page_title_fashionyourfirefox_faq"
+msgstr "Fashion your Firefox FAQ"
+
+#: controllers/pages_controller.php:101
+#, fuzzy
+msgid "page_title_policy"
+msgstr "Add-ons Policy"
+
+#: controllers/pages_controller.php:103
+#, fuzzy
+msgid "page_title_privacy"
+msgstr "Mozilla Privacy Policy"
+
+#: controllers/pages_controller.php:105
+#, fuzzy
+msgid "page_title_review_guide"
+msgstr "Review Guidelines"
+
+#: controllers/pages_controller.php:107
+#, fuzzy
+msgid "page_title_sandbox"
+msgstr "Sandbox Review System"
+
+#: controllers/pages_controller.php:109
+#, fuzzy
+msgid "page_title_submissionhelp"
+msgstr "Submission Help"
+
+#: views/pages/appversions.thtml:87
+msgid "pages_appversions_guid"
+msgstr "GUID"
+
+#: views/pages/appversions.thtml:79 controllers/pages_controller.php:90
+msgid "pages_appversions_header"
+msgstr "ДійÑні верÑÑ–Ñ— програми"
+
+#: views/pages/appversions.thtml:80
+msgid "pages_appversions_intro"
+msgstr ""
+"Додатки, надіÑлані до додатків Mozilla’и, повинні мати файл install.rdf з "
+"підтримкою принаймні однієї з нижчевказаних програм. Лише нижчевказані "
+"верÑÑ–Ñ— дозволені Ð´Ð»Ñ Ñ†Ð¸Ñ… програм."
+
+#. %s is a full <a> tag
+#: views/pages/appversions.thtml:93
+#, php-format
+msgid "pages_appversions_required_files"
+msgstr ""
+"Якщо ваша цільова програма не потребує файлу install.rdf, ви вÑе одно "
+"повинні включити таке з потрібними влаÑтивоÑÑ‚Ñми, Ñк визначені %s."
+
+#. this is the text inside of an <a> tag for pages_appversions_required_files. This
+#. should be fixed.
+#: views/pages/appversions.thtml:93
+msgid "pages_appversions_required_files_link"
+msgstr "тут"
+
+#: views/pages/appversions.thtml:88
+msgid "pages_appversions_versions"
+msgstr "ВерÑÑ–Ñ—"
+
+#: views/pages/policy.thtml:51
+msgid "pages_policy_sandbox_link"
+msgstr "Сторінка інформації піÑочниці"
+
+#: views/elements/pagination.thtml:53
+msgid "pagination_next_page"
+msgstr "далі"
+
+#: views/elements/pagination.thtml:52
+msgid "pagination_previous_page"
+msgstr "назад"
+
+#: views/elements/recaptcha.thtml:65
+msgid "recaptcha_enter_both_words"
+msgstr ""
+"Будь лаÑка введіть <strong>обидва Ñлова</strong> нижче, <strong>розділені "
+"пробілом</strong>."
+
+#: views/elements/recaptcha.thtml:83
+msgid "recaptcha_enter_here"
+msgstr "Введіть відповідь Ñюди:"
+
+#: views/elements/recaptcha.thtml:74
+#, fuzzy
+msgid "recaptcha_enter_whatyouhear"
+msgstr "Please type what you hear."
+
+#. %1 is the link switching refreshing the captcha
+#. %2 is the link switching to a text captcha
+#: views/elements/recaptcha.thtml:77
+#, fuzzy
+msgid "recaptcha_hardtohear_text"
+msgstr ""
+"If this is hard to understand, you can <a href=\"%1$s\">listen to something "
+"else</a> or <a href=\"%2$s\">switch back to text</a>."
+
+#. %1 is the link switching refreshing the captcha
+#. %2 is the link switching to an audio captcha
+#: views/elements/recaptcha.thtml:68
+#, fuzzy
+msgid "recaptcha_hardtoread_text"
+msgstr ""
+"If this is hard to read, you can <a href=\"%1$s\">try different words</a> or "
+"<a href=\"%2$s\">listen to something</a> instead."
+
+#: views/users/register.thtml:105
+msgid "recaptcha_label"
+msgstr "Ви людина?"
+
+#: views/users/register.thtml:106
+msgid "recaptcha_whatsthis"
+msgstr "Що це?"
+
+#: controllers/reviews_controller.php:559
+msgid "review_flag_error"
+msgstr "Помилка Ð²Ñ–Ð´Ð¼Ñ–Ñ‡Ð°Ð½Ð½Ñ Ñ†ÑŒÐ¾Ð³Ð¾ відгуку!"
+
+#: models/reviews_moderation_flag.php:69
+#, fuzzy
+msgid "review_flag_reason_bug_support"
+msgstr "Misplaced bug report or support request"
+
+#: views/reviews/display.thtml:103 views/reviews/display.thtml:186
+#, fuzzy
+msgid "review_flag_reason_instructions"
+msgstr "Report this review (select a reason)"
+
+#: models/reviews_moderation_flag.php:67
+#, fuzzy
+msgid "review_flag_reason_language"
+msgstr "Inappropriate language/dialog"
+
+#: models/reviews_moderation_flag.php:71
+#, fuzzy
+msgid "review_flag_reason_other"
+msgstr "Other (please specify)"
+
+#: models/reviews_moderation_flag.php:65
+#, fuzzy
+msgid "review_flag_reason_spam"
+msgstr "Spam or otherwise non-review content"
+
+#: views/reviews/display.thtml:91 views/reviews/display.thtml:175
+#: controllers/reviews_controller.php:555
+msgid "review_flag_success"
+msgstr "Thanks; this review has been flagged for editor approval."
+
+#: views/reviews/display.thtml:41
+msgid "review_flag_this"
+msgstr "Report this review"
+
+#: views/reviews/display.thtml:42
+msgid "review_flag_this_titletip"
+msgstr ""
+"Is this review inappropriate, inaccurate or spam? Click here to flag it for "
+"editor review."
+
+#. %1 is the URL of the support section, %2 for the review guidelines
+#: views/reviews/add.thtml:53
+msgid "review_guidelines_short"
+msgstr ""
+"<p>Keep these tips in mind:</p><ul><li>Write like you're telling a friend "
+"about your experience with the add-on. Give specifics and helpful details, "
+"such as what features you liked and/ordisliked, how easy to use it is, and "
+"any disadvantages it has. Avoid genericlanguage such as calling it \"Great"
+"\" or \"Bad\" unless you can give reasons whyyou believe this is so.</"
+"li><li>Please do not post bug reports in reviews. We do not make your email "
+"address available to add-on developers and they may need to contact you to "
+"help resolveyour issue. See the <a href=\"%1$s\">support section</a> to find "
+"out where to get assistance for this add-on.</li><li>Please keep reviews "
+"clean, avoid the use of improper language and do not post any personal "
+"information.</li></ul><p>Please read the <a href=\"%2$s\">Review Guidelines</"
+"a> for more detail about user add-on reviews.</p>"
+
+#. %1 is the add-on name
+#: views/reviews/flag.thtml:56 views/reviews/display.thtml:55
+#: views/reviews/review_added.thtml:50
+#, php-format
+msgid "reviews_header"
+msgstr "ПереглÑдів Ð´Ð»Ñ %s"
+
+#: controllers/addons_controller.php:435
+msgid "rss_featuredaddons"
+msgstr "ВлаÑтиві додатки"
+
+#: controllers/addons_controller.php:432
+msgid "rss_newestaddons"
+msgstr "Ðайновіші додатки"
+
+#: controllers/addons_controller.php:434
+#, fuzzy
+msgid "rss_popularaddons"
+msgstr "Popular Add-ons"
+
+#: controllers/addons_controller.php:433
+msgid "rss_updatedaddons"
+msgstr "Оновлені додатки"
+
+#: views/elements/search_mini.thtml:70
+#, fuzzy
+msgid "search"
+msgstr "Search"
+
+#: views/search/collections.thtml:51
+#, fuzzy
+msgid "search_collections_header"
+msgstr "Collection Search Results"
+
+#: controllers/search_controller.php:297
+#, fuzzy
+msgid "search_collections_pagetitle"
+msgstr "Collection Search Results"
+
+#: controllers/search_controller.php:99
+msgid "search_disabled"
+msgstr "Пошук зараз відключено. Будь лаÑка, Ñпробуйте пізніше."
+
+#: views/elements/amo2009/search.thtml:188 views/elements/search.thtml:187
+#: views/elements/search_mini.thtml:54
+msgid "search_form_all_addons"
+msgstr "уÑÑ–Ñ… додатків"
+
+#. This string is in the main category dropdown when searching
+#: views/elements/amo2009/search.thtml:204
+#, fuzzy
+msgid "search_form_all_collections"
+msgstr "all collections"
+
+#: views/elements/amo2009/search.thtml:184
+#: views/elements/amo2009/search.thtml:385
+#: views/elements/amo2009/search.thtml:408 views/elements/search.thtml:171
+#: views/elements/search.thtml:183 views/elements/search_mini.thtml:43
+#: views/elements/search_mini.thtml:49 views/layouts/mozilla.thtml:188
+msgid "search_form_default_text"
+msgstr "шукати додатки"
+
+#: views/elements/amo2009/search.thtml:184
+#: views/elements/amo2009/search.thtml:404
+#, fuzzy
+msgid "search_form_default_text_collections"
+msgstr "search for collections"
+
+#: views/elements/amo2009/search.thtml:206 views/elements/search.thtml:202
+msgid "search_form_submit_tooltip"
+msgstr "Шукати додатки"
+
+#: views/elements/amo2009/search.thtml:184 views/elements/search.thtml:183
+#: views/elements/search_mini.thtml:49
+msgid "search_form_tooltip"
+msgstr "Клацніть щоб ввеÑти терміни пошуку"
+
+#: views/elements/amo2009/search.thtml:186 views/elements/search.thtml:185
+#: views/elements/search_mini.thtml:52
+msgid "search_form_within"
+msgstr "Ñеред"
+
+#: views/addons/searchengines.thtml:118
+msgid "search_landing_all_search_engines"
+msgstr "Ð’ÑÑ– пошукові заÑоби"
+
+#: views/addons/searchengines.thtml:114
+msgid "search_landing_browse_search_engines"
+msgstr "переглÑнути пошукові заÑоби"
+
+#: views/search/collections.thtml:58 views/search/index.thtml:59
+msgid "search_nothing_found"
+msgstr "Ðемає результатів."
+
+#: controllers/search_controller.php:185
+msgid "search_pagetitle"
+msgstr "Пошук додатків"
+
+#: controllers/search_controller.php:242
+msgid "search_rss_description"
+msgstr "Пошук RSS результатів"
+
+#. %s is the terms the user is searching for (a string)
+#: controllers/search_controller.php:241
+#, php-format
+msgid "search_rss_results_for"
+msgstr "Пошук результатів длÑ: %s"
+
+#: views/elements/header.thtml:154 views/layouts/amo2009.thtml:296
+msgid "sidebar_navlink_admin_tools"
+msgstr "ІнÑтрументи адміна"
+
+#: views/elements/header.thtml:146 views/layouts/amo2009.thtml:288
+msgid "sidebar_navlink_developer_tools"
+msgstr "ІнÑтрументи розробника"
+
+#: views/elements/header.thtml:148 views/layouts/amo2009.thtml:290
+msgid "sidebar_navlink_editor_tools"
+msgstr "ІнÑтрументи редактора"
+
+#: views/layouts/amo2009.thtml:302
+msgid "sidebar_navlink_welcome"
+msgstr "ЛаÑкаво проÑимо"
+
+#. %s is the user's name
+#: views/layouts/amo2009.thtml:302
+#, php-format
+msgid "sidebar_navlink_welcome_name"
+msgstr "Вітаємо, %s"
+
+#: views/elements/pitch.thtml:50 views/elements/pitch.thtml:55
+msgid "sidebar_pitch_dictionary"
+msgstr "Словник"
+
+#: views/elements/pitch.thtml:72
+msgid "sidebar_pitch_featured_addons"
+msgstr "Обрані додатки"
+
+#: views/elements/pitch.thtml:61
+msgid "sidebar_pitch_looking_for"
+msgstr "Я шукаю"
+
+#: views/elements/pitch.thtml:70
+msgid "sidebar_pitch_newest_addons"
+msgstr "Ðайновіші додатки"
+
+#: views/elements/pitch.thtml:49
+msgid "sidebar_pitch_search"
+msgstr "Пошуковий заÑіб"
+
+#: views/elements/pitch.thtml:69
+msgid "sidebar_pitch_subscribe_to"
+msgstr "ПідпиÑатиÑÑŒ на"
+
+#: views/elements/pitch.thtml:48 views/elements/pitch.thtml:54
+msgid "sidebar_pitch_theme"
+msgstr "Тему"
+
+#: views/elements/pitch.thtml:71
+msgid "sidebar_pitch_updated_addons"
+msgstr "Оновлені додатки"
+
+#. %1$s is a number
+#: views/helpers/localization.php:65 views/developers/versions_edit.thtml:95
+#: views/addons/dictionaries.thtml:92
+#, php-format
+msgid "size_kb"
+msgstr "%1$s КБ"
+
+#: views/elements/amo2009/stars.thtml:57 views/elements/stars.thtml:63
+msgid "stars_not_yet_rated"
+msgstr "Ще не оцінений:"
+
+#. %1 is the number of stars this add-on has
+#: views/elements/amo2009/stars.thtml:49 views/elements/stars.thtml:54
+#, php-format
+msgid "stars_rated_x_outof_5"
+msgstr "Оцінений на %s з 5 зірочок"
+
+#: views/statistics/addon.thtml:59
+msgid "statistics_addon_dashboard_link"
+msgstr "Початкова панель"
+
+#: views/statistics/addon.thtml:58
+msgid "statistics_addon_developertools_link"
+msgstr "ІнÑтрументи розробника"
+
+#: views/statistics/addon.thtml:53
+msgid "statistics_addon_switch"
+msgstr "Перемкнути додаток"
+
+#. This is a date format.
+#. http://php.net/strftime
+#: views/statistics/rss/summary.thtml:54 views/statistics/addon.thtml:181
+msgid "statistics_date_shortmonth"
+msgstr "M. j"
+
+#. This is a date format.
+#. http://php.net/strftime
+#: views/statistics/rss/summary.thtml:40 views/statistics/addon.thtml:152
+msgid "statistics_date_shortmonthwithyear"
+msgstr "M. j, Y"
+
+#. This is a date format.
+#. http://php.net/strftime
+#: views/statistics/rss/summary.thtml:41 views/statistics/rss/summary.thtml:48
+#: views/statistics/addon.thtml:161 views/statistics/addon.thtml:172
+msgid "statistics_date_weekdayshortmonth"
+msgstr "l, M. j"
+
+#. %1$s is an add-on name and version. Example: Add-on 3.5
+#: controllers/components/stats.php:519
+#, php-format
+msgid "statistics_events_addon_created"
+msgstr "Ñтворений %1$s"
+
+#. %1$s is an application name and version. Example: Firefox 3.5
+#: controllers/components/stats.php:500
+#, php-format
+msgid "statistics_events_app_released"
+msgstr "випущений %1$s"
+
+#: views/statistics/addon.thtml:71
+msgid "statistics_help_close_link"
+msgstr "Закрити"
+
+#: views/statistics/addon.thtml:60
+msgid "statistics_help_link"
+msgstr "Довідка"
+
+#: views/statistics/index.thtml:83
+msgid "statistics_index_anotheraddon"
+msgstr "або оберіть інший додаток"
+
+#: views/statistics/index.thtml:85
+msgid "statistics_index_anotheraddon_public"
+msgstr "або оберіть додаток з публічною ÑтатиÑтикою"
+
+#: views/statistics/index.thtml:71
+msgid "statistics_index_myaddons"
+msgstr "Select one of your add-ons to view its statistics"
+
+#: views/statistics/index.thtml:89
+msgid "statistics_index_selectaddon"
+msgstr "Select an add-on to view its statistics"
+
+#: views/statistics/index.thtml:91
+msgid "statistics_index_selectaddon_public"
+msgstr "Select an add-on with public statistics"
+
+#: views/statistics/index.thtml:39
+msgid "statistics_index_title"
+msgstr "Statistics Dashboard"
+
+#: views/statistics/index.thtml:97
+msgid "statistics_index_view_button"
+msgstr "View Statistics"
+
+#: views/statistics/addon.thtml:222 controllers/statistics_controller.php:247
+#, fuzzy
+msgid "statistics_js_download_csv"
+msgstr "View this table in CSV format"
+
+#: controllers/statistics_controller.php:246
+msgid "statistics_js_dropdowns_none"
+msgstr "none"
+
+#: controllers/statistics_controller.php:245
+msgid "statistics_js_dropdowns_removeplot"
+msgstr "Remove this plot"
+
+#: controllers/statistics_controller.php:248
+#, fuzzy
+msgid "statistics_js_groupby_selector_date"
+msgstr "Group by: Day"
+
+#: controllers/statistics_controller.php:251
+#, fuzzy
+msgid "statistics_js_groupby_selector_month"
+msgstr "Group by: Month"
+
+#: controllers/statistics_controller.php:249
+#, fuzzy
+msgid "statistics_js_groupby_selector_week"
+msgstr "Group by: Week"
+
+#: controllers/statistics_controller.php:250
+#, fuzzy
+msgid "statistics_js_groupby_selector_week_over_week"
+msgstr "Compare by: Week"
+
+#: controllers/statistics_controller.php:260
+msgid "statistics_js_plotselection_foundinrange"
+msgstr "%s found in range"
+
+#: controllers/statistics_controller.php:270
+msgid "statistics_js_plotselection_options_addplot_name"
+msgstr "Add Plot"
+
+#: controllers/statistics_controller.php:271
+msgid "statistics_js_plotselection_options_addplot_tooltip"
+msgstr "Add another plot to this graph"
+
+#: controllers/statistics_controller.php:261
+msgid "statistics_js_plotselection_options_count_name_checked"
+msgstr "Hide Total Count"
+
+#: controllers/statistics_controller.php:262
+msgid "statistics_js_plotselection_options_count_name_unchecked"
+msgstr "Show Total Count"
+
+#: controllers/statistics_controller.php:263
+#, fuzzy
+msgid "statistics_js_plotselection_options_count_tooltip"
+msgstr "Plot the total count on this graph"
+
+#: controllers/statistics_controller.php:275
+msgid "statistics_js_plotselection_options_csv_name"
+msgstr "View Data (CSV)"
+
+#: controllers/statistics_controller.php:276
+msgid "statistics_js_plotselection_options_csv_tooltip"
+msgstr "Get a Comma Separated Values file of this data"
+
+#: controllers/statistics_controller.php:267
+msgid "statistics_js_plotselection_options_events_addon_name_checked"
+msgstr "Hide %s Events"
+
+#: controllers/statistics_controller.php:268
+msgid "statistics_js_plotselection_options_events_addon_name_unchecked"
+msgstr "Show %s Events"
+
+#: controllers/statistics_controller.php:269
+msgid "statistics_js_plotselection_options_events_addon_tooltip"
+msgstr "Overlay add-on release dates on the plots"
+
+#: controllers/statistics_controller.php:264
+msgid "statistics_js_plotselection_options_events_firefox_name_checked"
+msgstr "Hide Firefox Events"
+
+#: controllers/statistics_controller.php:265
+msgid "statistics_js_plotselection_options_events_firefox_name_unchecked"
+msgstr "Show Firefox Events"
+
+#: controllers/statistics_controller.php:266
+msgid "statistics_js_plotselection_options_events_firefox_tooltip"
+msgstr "Overlay Firefox release dates on the plots"
+
+#: controllers/statistics_controller.php:272
+msgid "statistics_js_plotselection_options_resize_name_checked"
+msgstr "Collapse Graph"
+
+#: controllers/statistics_controller.php:273
+msgid "statistics_js_plotselection_options_resize_name_unchecked"
+msgstr "Expand Graph"
+
+#: controllers/statistics_controller.php:274
+msgid "statistics_js_plotselection_options_resize_tooltip"
+msgstr "Resize the graph"
+
+#: controllers/statistics_controller.php:254
+msgid "statistics_js_plotselection_selector_adu"
+msgstr "Active Daily Users"
+
+#: controllers/statistics_controller.php:256
+msgid "statistics_js_plotselection_selector_application"
+msgstr "Application"
+
+#: controllers/statistics_controller.php:259
+msgid "statistics_js_plotselection_selector_custom"
+msgstr "Custom"
+
+#: controllers/statistics_controller.php:253
+msgid "statistics_js_plotselection_selector_downloads"
+msgstr "Downloads"
+
+#: controllers/statistics_controller.php:258
+msgid "statistics_js_plotselection_selector_os"
+msgstr "Operating System"
+
+#: controllers/statistics_controller.php:257
+msgid "statistics_js_plotselection_selector_status"
+msgstr "Add-on Status"
+
+#: controllers/statistics_controller.php:252
+msgid "statistics_js_plotselection_selector_summary"
+msgstr "Summary"
+
+#: controllers/statistics_controller.php:255
+msgid "statistics_js_plotselection_selector_version"
+msgstr "Add-on Version"
+
+#: controllers/components/stats.php:398
+msgid "statistics_longnames_application"
+msgstr "Application"
+
+#: controllers/components/stats.php:400
+msgid "statistics_longnames_os"
+msgstr "Operating System"
+
+#: controllers/components/stats.php:399
+msgid "statistics_longnames_status"
+msgstr "Add-on Status"
+
+#: controllers/components/stats.php:401
+msgid "statistics_longnames_unknown"
+msgstr "Unknown"
+
+#: controllers/components/stats.php:397
+msgid "statistics_longnames_version"
+msgstr "Add-on Version"
+
+#: views/statistics/addon.thtml:118
+msgid "statistics_notice_data_insufficient"
+msgstr ""
+"There is not yet enough data to display this graph. Please check back later."
+
+#: views/statistics/addon.thtml:130
+msgid "statistics_notice_data_none"
+msgstr ""
+"We don't have any data for your add-on yet. Please check back in a few days."
+
+#: views/statistics/addon.thtml:41
+msgid "statistics_notice_data_updating"
+msgstr ""
+"Add-on statistics are currently in the process of being updated. Recent data "
+"may be incomplete as our scripts work to update this information. Please "
+"check back in a few minutes."
+
+#: views/statistics/addon.thtml:136
+msgid "statistics_notice_disabled"
+msgstr ""
+"The Statistics Dashboard is currently disabled. Please check back later."
+
+#: views/statistics/addon.thtml:123
+msgid "statistics_notice_nojavascript"
+msgstr "JavaScript is required to view the Statistics Dashboard graphs."
+
+#: views/statistics/addon.thtml:44
+msgid "statistics_notice_settings_updated"
+msgstr "Your settings have been updated!"
+
+#: controllers/statistics_controller.php:60
+#: controllers/statistics_controller.php:71
+#: controllers/statistics_controller.php:74
+#: controllers/statistics_controller.php:240
+msgid "statistics_pagetitle"
+msgstr "Statistics Dashboard"
+
+#: views/statistics/addon.thtml:99
+msgid "statistics_plot_legend_adu"
+msgstr "Active Daily Users"
+
+#: views/statistics/addon.thtml:95
+msgid "statistics_plot_legend_downloads"
+msgstr "Daily Downloads"
+
+#: views/statistics/addon.thtml:107
+msgid "statistics_plot_options_zoomin_alt"
+msgstr "Zoom In"
+
+#: views/statistics/addon.thtml:106
+msgid "statistics_plot_options_zoomin_title"
+msgstr "Zoom in one month"
+
+#: views/statistics/addon.thtml:110
+msgid "statistics_plot_options_zoomout_alt"
+msgstr "Zoom Out"
+
+#: views/statistics/addon.thtml:109
+msgid "statistics_plot_options_zoomout_title"
+msgstr "Zoom out one month"
+
+#: controllers/statistics_controller.php:283
+#, php-format
+msgid "statistics_rss_description"
+msgstr "Daily summary of statistics for %1$s"
+
+#: views/statistics/rss/summary.thtml:68
+msgid "statistics_rss_title_fulldate"
+msgstr "l, F j, Y"
+
+#: views/statistics/rss/summary.thtml:68
+#, php-format
+msgid "statistics_rss_title_statsfordate"
+msgstr "Statistics for %1$s"
+
+#: views/statistics/settings.thtml:49
+msgid "statistics_settings_access_description"
+msgstr ""
+"By default, only you and Mozilla can access the information in your "
+"dashboard. You can open this up to the public so that anyone can view your "
+"add-on's data."
+
+#: views/statistics/settings.thtml:48
+msgid "statistics_settings_access_heading"
+msgstr "Dashboard Access"
+
+#: views/statistics/settings.thtml:51
+msgid "statistics_settings_access_private"
+msgstr "Private"
+
+#: views/statistics/settings.thtml:51
+msgid "statistics_settings_access_private_description"
+msgstr "Only you and Mozilla can view this add-on's statistics"
+
+#: views/statistics/settings.thtml:52
+msgid "statistics_settings_access_public"
+msgstr "Public"
+
+#: views/statistics/settings.thtml:52
+msgid "statistics_settings_access_public_description"
+msgstr "Anyone can view this add-on's statistics"
+
+#: views/statistics/addon.thtml:251
+msgid "statistics_settings_change_link"
+msgstr "Change Settings"
+
+#: views/statistics/addon.thtml:253
+msgid "statistics_settings_confidential"
+msgstr "Please treat this information as confidential."
+
+#: views/statistics/addon.thtml:245
+msgid "statistics_settings_currently_private"
+msgstr "This dashboard is currently <b>private</b>."
+
+#: views/statistics/addon.thtml:241
+msgid "statistics_settings_currently_public"
+msgstr "This dashboard is currently <b>public</b>."
+
+#: views/statistics/addon.thtml:246
+msgid "statistics_settings_locked_alt"
+msgstr "Locked"
+
+#: views/statistics/settings.thtml:57
+msgid "statistics_settings_return_link"
+msgstr "Return to Dashboard"
+
+#: views/statistics/settings.thtml:56
+msgid "statistics_settings_save_button"
+msgstr "Save Settings"
+
+#: views/statistics/settings.thtml:46
+#, php-format
+msgid "statistics_settings_title"
+msgstr "Statistics Dashboard Settings for %1$s"
+
+#: views/statistics/addon.thtml:242
+msgid "statistics_settings_unlocked_alt"
+msgstr "Unlocked"
+
+#: controllers/components/stats.php:405
+msgid "statistics_shortnames_application"
+msgstr "App"
+
+#: controllers/components/stats.php:407
+msgid "statistics_shortnames_os"
+msgstr "OS"
+
+#: controllers/components/stats.php:406
+msgid "statistics_shortnames_status"
+msgstr "St"
+
+#: controllers/components/stats.php:408
+msgid "statistics_shortnames_unknown"
+msgstr "Uk"
+
+#: controllers/components/stats.php:404
+msgid "statistics_shortnames_version"
+msgstr "Ver"
+
+#: views/statistics/rss/summary.thtml:42 views/statistics/addon.thtml:192
+msgid "statistics_summary_downloads_average"
+msgstr "Average Daily Downloads"
+
+#: views/statistics/rss/summary.thtml:39
+msgid "statistics_summary_downloads_heading"
+msgstr "Downloads"
+
+#: views/statistics/rss/summary.thtml:41 views/statistics/addon.thtml:171
+msgid "statistics_summary_downloads_lastcount"
+msgstr "Last Day Count"
+
+#: views/statistics/rss/summary.thtml:43 views/statistics/addon.thtml:199
+msgid "statistics_summary_downloads_lastweek"
+msgstr "Downloads in the last 7 days"
+
+#: views/statistics/rss/summary.thtml:40 views/statistics/addon.thtml:151
+msgid "statistics_summary_downloads_total"
+msgstr "Total Downloads"
+
+#: views/statistics/rss/summary.thtml:40 views/statistics/addon.thtml:152
+#, php-format
+msgid "statistics_summary_downloads_total_sincedate"
+msgstr "Since %1$s"
+
+#: views/statistics/rss/summary.thtml:50 views/statistics/rss/summary.thtml:56
+#: views/statistics/addon.thtml:163 views/statistics/addon.thtml:183
+msgid "statistics_summary_nodata"
+msgstr "No data yet"
+
+#: views/statistics/rss/summary.thtml:60 views/statistics/addon.thtml:195
+msgid "statistics_summary_updatepings_average"
+msgstr "Average Daily Active Users"
+
+#: views/statistics/rss/summary.thtml:52 views/statistics/addon.thtml:177
+msgid "statistics_summary_updatepings_changefromprevious"
+msgstr "Change from previous count"
+
+#: views/statistics/rss/summary.thtml:54 views/statistics/addon.thtml:181
+#, php-format
+msgid "statistics_summary_updatepings_changefromprevious_ondate"
+msgstr "%1$s on %2$s"
+
+#: views/statistics/rss/summary.thtml:45
+msgid "statistics_summary_updatepings_heading"
+msgstr "Active Daily Users"
+
+#: views/statistics/rss/summary.thtml:46 views/statistics/addon.thtml:157
+msgid "statistics_summary_updatepings_total"
+msgstr "Active Daily Users"
+
+#: views/statistics/rss/summary.thtml:48 views/statistics/addon.thtml:161
+#, php-format
+msgid "statistics_summary_updatepings_total_ondate"
+msgstr "On %1$s"
+
+#: views/statistics/rss/summary.thtml:61 views/statistics/addon.thtml:203
+#, fuzzy
+msgid "statistics_summary_updatepings_weekly_average"
+msgstr "Average Daily Users this Week"
+
+#. %s is a percentage, like '+22.33%'. It sits next to another number, so
+#. the implied meaning is 'percentage change' from the previous stat point.
+#: views/statistics/rss/summary.thtml:62 views/statistics/addon.thtml:205
+#, fuzzy
+msgid "statistics_summary_updatepings_weekly_change"
+msgstr "%s from last week"
+
+#: views/statistics/addon.thtml:65 controllers/statistics_controller.php:184
+#: controllers/statistics_controller.php:282
+#, php-format
+msgid "statistics_title_addon_stats"
+msgstr "%1$s Statistics"
+
+#: views/addons/themes_landing.thtml:113
+msgid "themes_landing_all_themes"
+msgstr "Ð’ÑÑ– теми"
+
+#: views/addons/themes_landing.thtml:109
+msgid "themes_landing_browse_themes"
+msgstr "ПереглÑнути теми"
+
+#: views/users/edit.thtml:185
+msgid "user_change_email"
+msgstr "Змінити мою поштову адреÑу"
+
+#: views/users/edit.thtml:169
+msgid "user_change_password"
+msgstr "Змінити пароль"
+
+#: views/users/edit.thtml:96
+#, fuzzy
+msgid "user_change_password_or_email"
+msgstr "Change Password or Email"
+
+#: controllers/users_controller.php:197
+msgid "user_confirmationcode_resent"
+msgstr "Код Ð¿Ñ–Ð´Ñ‚Ð²ÐµÑ€Ð´Ð¶ÐµÐ½Ð½Ñ Ð±ÑƒÐ»Ð¾ повторно надіÑлано!"
+
+#. %1 is the email address, %2 is the URL of the user registration page
+#: views/users/delete.thtml:51
+#, fuzzy
+msgid "user_del_account_deleted"
+msgstr ""
+"Your user account %1$s has been successfully deleted. If you want to come "
+"back some time, you can re-register on the <a href=\"%2$s\">user "
+"registration page</a>."
+
+#: views/users/delete.thtml:102
+#, fuzzy
+msgid "user_del_community_sad"
+msgstr "The Mozilla Add-ons community is sad to see you go."
+
+#: views/users/delete.thtml:123
+#, fuzzy
+msgid "user_del_confirm_password"
+msgstr "Confirm Password"
+
+#: views/users/delete.thtml:134
+#, fuzzy
+msgid "user_del_deletenow"
+msgstr "Delete my user account now"
+
+#. %1 is the URL of the user's info page
+#: views/users/delete.thtml:64
+#, fuzzy
+msgid "user_del_error_addons"
+msgstr ""
+"You cannot delete your account if you are listed as an <a href=\"%1$s"
+"\">author of any add-ons</a>. To delete your account, please have another "
+"person in your development group delete you from the list of authors for "
+"your add-ons. Afterwards you will be able to delete your account here."
+
+#. %1 is a link to the amo-editors mailing list
+#: views/users/delete.thtml:71
+#, fuzzy
+msgid "user_del_error_addons_more_questions"
+msgstr "If you have additional questions, please contact %1$s for assistance."
+
+#: views/users/delete.thtml:78
+#, fuzzy
+msgid "user_del_error_checkbox"
+msgstr ""
+"You need to check the box \"I understand...\" before we can delete your "
+"account."
+
+#: views/users/delete.thtml:84
+#, fuzzy
+msgid "user_del_error_password"
+msgstr "Please enter your password correctly in order to perform this step."
+
+#. %1 is a link to the amo-admins mailing list
+#: views/users/delete.thtml:91
+#, fuzzy
+msgid "user_del_error_unknown"
+msgstr ""
+"An unknown error occured deleting your account. Please contact %1$s with the "
+"issue and we will delete it for you. We apologize for the inconvenience."
+
+#: views/users/delete.thtml:110
+#, fuzzy
+msgid "user_del_header_confirm_deletion"
+msgstr "Confirm account deletion"
+
+#. %1 is the user's email address
+#: views/users/delete.thtml:100
+#, fuzzy
+msgid "user_del_header_delete_account"
+msgstr "Delete User Account %1$s"
+
+#: views/users/delete.thtml:50
+#, fuzzy
+msgid "user_del_header_farewell"
+msgstr "Farewell!"
+
+#: views/users/delete.thtml:115
+#, fuzzy
+msgid "user_del_nologin"
+msgstr "You will not be able to log into Mozilla Add-ons anymore."
+
+#: views/users/delete.thtml:112
+#, fuzzy
+msgid "user_del_permanently_removed_means"
+msgstr ""
+"By clicking \"delete\" your account is going to be <strong>permanently "
+"removed</strong>. That means:"
+
+#: views/users/delete.thtml:116
+#, fuzzy
+msgid "user_del_reviews_anonymized"
+msgstr ""
+"Your reviews and ratings will not be deleted, but they will no longer be "
+"associated with you."
+
+#. %1 is a link to the amo-editors mailing list
+#: views/users/delete.thtml:104
+#, fuzzy
+msgid "user_del_specific_problem_editors"
+msgstr ""
+"If you have a specific problem we may help you with, please do not delete "
+"your account now, but contact us at %1$s and we will do our best to assist "
+"you in solving it."
+
+#: views/users/delete.thtml:130
+#, fuzzy
+msgid "user_del_understand_permanent"
+msgstr "Я розумію, що цей крок не відворотній."
+
+#: views/helpers/addons_html.php:192
+#, fuzzy
+msgid "user_deleted_nickname"
+msgstr "Видалений кориÑтувач"
+
+#. %1 is the new email address
+#: views/users/edit.thtml:71
+msgid "user_edit_confirm_email_sent"
+msgstr ""
+"An email has been sent to %1$s to confirm your new email address. For the "
+"change to take effect, you need to click on the link provided in this email. "
+"Until then, you can keep logging in with your current email address."
+
+#: views/users/edit.thtml:201
+#, fuzzy
+msgid "user_edit_delete_user"
+msgstr "Видалити ваш обліковий запиÑ"
+
+#. This contains the email sent to users when they signed up for a new
+#. account:
+#. %1 is the confirmation URL, %2 is the current app
+#: views/users/email/confirm_plain.thtml:6
+#, php-format
+msgid "user_email_confirm_account_nopass"
+msgstr ""
+"ЛаÑкаво проÑимо до Ñайту додатків %2$s.\n"
+"\n"
+"Перед тим, Ñк ви зможете викориÑтати новий рахунок, ви повинні активувати "
+"його – це забезпечує, що адреÑа e-mail, Ñку ви викориÑтали, дійÑна Ñ– "
+"належить вам.\n"
+"Щоб активувати ваш рахунок, клацніть на поÑиланні нижче або Ñкопіюйте Ñ– "
+"вÑтавте повніÑÑ‚ÑŽ у панель адреÑи вашого браузера:\n"
+"\n"
+"%1$s\n"
+"\n"
+"Коли ви уÑпішно активували Ñвій рахунок, можете викинути цей e-mail.\n"
+"\n"
+"ДÑкуємо, що приєдналиÑÑ Ð´Ð¾ Ñайту додатків %2$s\n"
+"-- Колектив додатків %2$s"
+
+#. %1 is the confirmation url, %2 is the application name
+#: views/users/email/emailchange_plain.thtml:5
+#, fuzzy
+msgid "user_email_confirm_emailchange"
+msgstr ""
+"You requested a change to your email address at %2$s Add-ons.\n"
+"\n"
+"In order to confirm the new address, please click the link below or copy and "
+"paste the whole thing into your browser's location bar:\n"
+"\n"
+"%1$s\n"
+"\n"
+"You have 48 hours to confirm the new address. If you do not want to change "
+"the address anymore, you can just ignore this email.\n"
+"\n"
+"Thanks!\n"
+"-- %2$s Add-ons Staff"
+
+#: controllers/users_controller.php:168
+#, php-format
+msgid "user_email_confirm_subject"
+msgstr "ДÑкуємо за реєÑтрацію на Ñайті додатків %s"
+
+#. This is the password reset email
+#. %1 is the pw reset URL, %2 is the application
+#: views/users/email/pwreset_plain.thtml:5
+#, php-format
+msgid "user_email_pwreset"
+msgstr ""
+"Ð¡ÐºÐ¸Ð´Ð°Ð½Ð½Ñ Ð¿Ð°Ñ€Ð¾Ð»Ñ Ð½Ð° Ñайт додатків %2$s\n"
+"\n"
+"Отримано запит на ÑÐºÐ¸Ð´Ð°Ð½Ð½Ñ Ð¿Ð°Ñ€Ð¾Ð»Ñ Ð´Ð»Ñ Ñ†ÑŒÐ¾Ð³Ð¾ рахунку на addons.mozilla.org. "
+"Ð”Ð»Ñ Ð·Ð¼Ñ–Ð½Ð¸ цього паролÑ, будь лаÑка, клацніть на наÑтупному поÑиланні, або "
+"вÑтавте його у панель адреÑи вашого браузера:\n"
+"\n"
+"%1$s\n"
+"\n"
+"Якщо ви не подавали запит на цей email, нічого робити не потрібно.\n"
+"\n"
+"ДÑкуємо,\n"
+"-- Колектив додатків %2$s"
+
+#: controllers/users_controller.php:245
+#, php-format
+msgid "user_email_pwreset_subject"
+msgstr "Скиньте Ñвій пароль додатків %s"
+
+#: views/users/emailchange.thtml:50
+msgid "user_emailchange_error"
+msgstr "Помилка!"
+
+#. %1 is the application name
+#: controllers/users_controller.php:533
+#, fuzzy
+msgid "user_emailchange_subject"
+msgstr "Будь лаÑка підтвердіть зміну Ñвоєї поштової адреÑи на %1$s Додатків"
+
+#: views/users/emailchange.thtml:48
+msgid "user_emailchange_success"
+msgstr "УÑпіх!"
+
+#. %1 is the new email address
+#: views/users/emailchange.thtml:49
+#, fuzzy
+msgid "user_emailchange_successful_description"
+msgstr ""
+"Вашу поштову адреÑу уÑпішно змінено. від цього моменту, викориÑтовуйте Ð´Ð»Ñ "
+"входу %1$s"
+
+#: views/users/edit.thtml:134 views/admin/users_edit.thtml:111
+#, fuzzy
+msgid "user_form_bio"
+msgstr "About me"
+
+#: views/users/edit.thtml:135 views/admin/users_edit.thtml:112
+#, fuzzy
+msgid "user_form_bio_description"
+msgstr ""
+"Introduce yourself to the community, if you like! This text will appear "
+"publicly on your user info page. Line breaks will be preserved, but no HTML "
+"is allowed."
+
+#: views/users/pwreset.thtml:77 views/users/register.thtml:73
+#: views/users/edit.thtml:181
+msgid "user_form_confirmpassword"
+msgstr "Підтвердіть пароль"
+
+#: views/users/edit.thtml:145
+#, fuzzy
+msgid "user_form_display_collections"
+msgstr "Display the collections I have created in my user profile"
+
+#: views/users/edit.thtml:149
+#, fuzzy
+msgid "user_form_display_collections_fav"
+msgstr "Display my favorite collections in my user profile"
+
+#: views/users/edit.thtml:86
+#, php-format
+msgid "user_form_editprofile"
+msgstr "Редагувати профіль кориÑтувача Ð´Ð»Ñ %s"
+
+#: views/users/pwreset.thtml:52 views/users/login.thtml:81
+#: views/users/register.thtml:63 views/users/edit.thtml:187
+msgid "user_form_email"
+msgstr "Email"
+
+#: views/users/register.thtml:78 views/users/edit.thtml:103
+#: views/admin/users_edit.thtml:76
+msgid "user_form_firstname"
+msgstr "Ім’Ñ"
+
+#: views/users/register.thtml:94 views/users/edit.thtml:119
+#: views/admin/users_edit.thtml:91
+msgid "user_form_hideemail"
+msgstr "Приховати email"
+
+#: views/users/register.thtml:98 views/users/edit.thtml:123
+#: views/admin/users_edit.thtml:99
+msgid "user_form_homepage"
+msgstr "URL вебÑайту"
+
+#: views/users/register.thtml:84 views/users/edit.thtml:109
+#: views/admin/users_edit.thtml:81
+msgid "user_form_lastname"
+msgstr "Прізвище"
+
+#: controllers/users_controller.php:333
+msgid "user_form_login"
+msgstr "Вхід кориÑтувача"
+
+#: views/users/pwreset.thtml:72 views/users/edit.thtml:176
+msgid "user_form_newpassword"
+msgstr "Ðовий пароль"
+
+#: views/users/register.thtml:89 views/users/edit.thtml:114
+#: views/admin/users_edit.thtml:86
+msgid "user_form_nickname"
+msgstr "ПрізвиÑько"
+
+#: views/users/edit.thtml:171
+msgid "user_form_oldpassword"
+msgstr "Старий пароль"
+
+#: views/users/edit.thtml:97 views/users/edit.thtml:200
+#, fuzzy
+msgid "user_form_otheractions"
+msgstr "Інше"
+
+#: views/users/login.thtml:85 views/users/register.thtml:68
+msgid "user_form_password"
+msgstr "Пароль"
+
+#: controllers/users_controller.php:93
+msgid "user_form_registration"
+msgstr "РеєÑÑ‚Ñ€Ð°Ñ†Ñ–Ñ Ð½Ð¾Ð²Ð¾Ð³Ð¾ кориÑтувача"
+
+#: views/users/login.thtml:90
+msgid "user_form_remember_me"
+msgstr "Запам’Ñтати мене на цьому комп’ютері"
+
+#: views/admin/users_edit.thtml:95
+msgid "user_form_showsandbox"
+msgstr "Показати піÑочницю?"
+
+#: views/users/edit.thtml:205
+msgid "user_form_submit_edit"
+msgstr "Зберегти"
+
+#: views/users/login.thtml:93
+msgid "user_form_submit_login"
+msgstr "Вхід"
+
+#: views/users/register.thtml:113
+msgid "user_form_submit_register"
+msgstr "РеєÑтраціÑ"
+
+#: views/users/info.thtml:75
+#, php-format
+msgid "user_info_usersince"
+msgstr "%s додатків з чаÑу"
+
+#: views/users/login.thtml:102
+msgid "user_login_register_link"
+msgstr "Створити новий рахунок кориÑтувача"
+
+#: views/users/edit.thtml:160
+#, fuzzy
+msgid "user_notifications_item_compat"
+msgstr "Add-on Compatibility (strongly recommended)"
+
+#: views/users/edit.thtml:161
+#, fuzzy
+msgid "user_notifications_item_events"
+msgstr "Upcoming events and contests"
+
+#: views/users/edit.thtml:156
+#, fuzzy
+msgid "user_notifications_none_available"
+msgstr "There are currently no notifications available for you to configure."
+
+#: views/users/edit.thtml:158
+#, fuzzy
+msgid "user_notifications_select_topics"
+msgstr ""
+"From time to time, Mozilla may send you email about upcoming releases and "
+"add-on events. Please select the topics you are interested in below:"
+
+#: views/users/edit.thtml:164
+#, fuzzy
+msgid "user_notifications_specific_contact"
+msgstr ""
+"Mozilla reserves the right to contact you individually about specific "
+"concerns with your hosted add-ons."
+
+#: controllers/users_controller.php:543
+msgid "user_profile_edit_error"
+msgstr ""
+"Були помилки у змінах, Ñкі ви зробили. Будь лаÑка, виправте Ñ– знову "
+"надішліть…"
+
+#: controllers/users_controller.php:540
+msgid "user_profile_saved"
+msgstr "Профіль оновлено."
+
+#: views/users/pwreset.thtml:65
+#, php-format
+msgid "user_pwreset_for_email"
+msgstr "Ð¡ÐºÐ¸Ð´Ð°Ð½Ð½Ñ Ð¿Ð°Ñ€Ð¾Ð»Ñ Ð´Ð»Ñ %s"
+
+#: controllers/users_controller.php:226
+msgid "user_pwreset_header"
+msgstr "Ð¡ÐºÐ¸Ð´Ð°Ð½Ð½Ñ Ð¿Ð°Ñ€Ð¾Ð»Ñ"
+
+#: views/users/login.thtml:103
+msgid "user_pwreset_link"
+msgstr "Забули Ñвій пароль?"
+
+#: controllers/users_controller.php:248
+msgid "user_pwreset_link_sent"
+msgstr "ПоÑÐ¸Ð»Ð°Ð½Ð½Ñ ÑÐºÐ¸Ð´Ð°Ð½Ð½Ñ Ð¿Ð°Ñ€Ð¾Ð»Ñ Ð½Ð°Ð´Ñ–Ñлано на ваш email."
+
+#: controllers/users_controller.php:304
+msgid "user_pwreset_okay"
+msgstr "Пароль уÑпішно Ñкинуто."
+
+#: views/users/pwreset.thtml:82
+msgid "user_pwreset_submit_changepw"
+msgstr "ÐадіÑлати зміну паролÑ"
+
+#: views/users/pwreset.thtml:57
+msgid "user_pwreset_submit_sendlink"
+msgstr "ÐадіÑлати поÑÐ¸Ð»Ð°Ð½Ð½Ñ ÑÐºÐ¸Ð´Ð°Ð½Ð½Ñ Ð¿Ð°Ñ€Ð¾Ð»Ñ"
+
+#: views/users/register_complete.thtml:51
+#, php-format
+msgid "user_register_amo_link"
+msgstr "%s додатків"
+
+#. %1 is the user's email address, %2 is the current app
+#: views/users/activatefirst.thtml:49
+#, php-format
+msgid "user_register_click_confirm_link"
+msgstr ""
+"ПоÑÐ¸Ð»Ð°Ð½Ð½Ñ Ð´Ð»Ñ Ð°ÐºÑ‚Ð¸Ð²ÑƒÐ²Ð°Ð½Ð½Ñ Ð²Ð°ÑˆÐ¾Ð³Ð¾ кориÑтувацького рахунку надіÑлано "
+"електронною поштою на вашу адреÑу %1$s. Ви повинні клікнути його перед тим, "
+"Ñк увійти на Додатки %2$s."
+
+#. %1 is the user's email address
+#: views/users/register_complete.thtml:49
+#, php-format
+msgid "user_register_confirm_email_sent"
+msgstr ""
+"ÐадіÑлано електронного лиÑта на вашу адреÑу %1$s Ð´Ð»Ñ Ð¿Ñ–Ð´Ñ‚Ð²ÐµÑ€Ð´Ð¶ÐµÐ½Ð½Ñ Ð²Ð°ÑˆÐ¾Ð³Ð¾ "
+"рахунку. Перед тим, Ñк увійти, ви повинні активувати ваш рахунок, клікнувши "
+"на наведеному у лиÑÑ‚Ñ– поÑиланні."
+
+#: views/users/activatefirst.thtml:51
+msgid "user_register_confirmation_link_text"
+msgstr "повторно надіÑлати Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð¿Ñ–Ð´Ñ‚Ð²ÐµÑ€Ð´Ð¶ÐµÐ½Ð½Ñ"
+
+#: views/users/register_complete.thtml:47
+msgid "user_register_congratulations"
+msgstr "Вітаємо! Ваш кориÑтувацький рахунок уÑпішно Ñтворено."
+
+#: views/users/register.thtml:50
+#, fuzzy
+msgid "user_register_details"
+msgstr ""
+"<p>Registration on AMO is <strong>not required</strong> if you simply want "
+"to download and install public add-ons.</p><p>You only need to register if:</"
+"p><ul><li>You want to submit reviews for add-ons</li><li>You are an add-on "
+"developer and want to upload your add-on for hosting on AMO</li></ul><p>Upon "
+"successful registration, you will be sent a confirmation email to the "
+"address you provided. Please follow the instructions there to confirm your "
+"account.</p><p>If you like, you can read our <a href='%1$s' title='Legal "
+"Notices'>Legal Notices</a> and <a href='%2$s' title='Privacy Policy'>Privacy "
+"Policy</a>.</p>"
+
+#. %1 is the link to the "resend confirmation code" page
+#: views/users/activatefirst.thtml:51
+#, php-format
+msgid "user_register_resend_confirmation_link"
+msgstr ""
+"Якщо ви не отримали email підтвердженнÑ, переконайтеÑÑ, що Ñлужба вашого "
+"email’у не позначила його Ñк \"junk mail\" або \"spam\". Якщо потрібно, ми "
+"можемо %1$s на ваш вищезгаданий email."
+
+#. %1 is the link to the Mozilla Add-ons front page
+#: views/users/register_complete.thtml:51
+#, php-format
+msgid "user_register_welcome"
+msgstr "ДÑкуємо за реєÑтрацію Ñ– вітаємо на %1$s!"
+
+#: views/users/register.thtml:49
+#, fuzzy
+msgid "user_register_welcome_header"
+msgstr "Welcome to addons.mozilla.org (AMO)!"
+
+#: views/users/register.thtml:81 views/users/edit.thtml:106
+#, fuzzy
+msgid "user_required_firstlast_or_nickname"
+msgstr "Ðеобхідно ім’Ñ, прізвище або прізвиÑько."
+
+#: views/users/edit.thtml:94 views/users/edit.thtml:142
+#, fuzzy
+msgid "user_tab_collections"
+msgstr "Collections"
+
+#: views/users/edit.thtml:95 views/users/edit.thtml:154
+#, fuzzy
+msgid "user_tab_notifications"
+msgstr "Notifications"
+
+#: views/users/edit.thtml:93 views/users/edit.thtml:101
+#, fuzzy
+msgid "user_tab_profile"
+msgstr "User Profile"
+
+#: controllers/users_controller.php:209
+msgid "user_verified_okay"
+msgstr "УÑпішно перевірено!"
+
+#: controllers/users_controller.php:723
+#, fuzzy
+msgid "users_delete_pagetitle"
+msgstr "Видалити обліковий запиÑ"
+
+#: controllers/users_controller.php:414
+msgid "users_edit_pagetitle"
+msgstr "Ð ÐµÐ´Ð°Ð³ÑƒÐ²Ð°Ð½Ð½Ñ Ð²Ð°ÑˆÐ¾Ð³Ð¾ облікового запиÑу"
+
+#: views/users/info.thtml:71
+#, fuzzy
+msgid "users_info_aboutme"
+msgstr "About Me"
+
+#: views/users/info.thtml:96
+#, php-format
+msgid "users_info_addons_by_user"
+msgstr "Додатки від %1$s"
+
+#: views/users/info.thtml:51
+msgid "users_info_author_name"
+msgstr "Ðазва"
+
+#: views/users/info.thtml:48
+msgid "users_info_author_profile"
+msgstr "Профіль кориÑтувача"
+
+#. %s is the user name
+#: views/users/info.thtml:137
+#, fuzzy
+msgid "users_info_collections_by_user"
+msgstr "Collections by %s"
+
+#: views/users/info.thtml:66
+msgid "users_info_email"
+msgstr "Ваша електронна пошта"
+
+#: views/users/info.thtml:155
+#, fuzzy
+msgid "users_info_fav_collections_by_user"
+msgstr "Favorite Collections"
+
+#: views/users/info.thtml:61
+msgid "users_info_homepage"
+msgstr "Ð”Ð¾Ð¼Ð°ÑˆÐ½Ñ Ñторінка"
+
+#: views/users/info.thtml:56
+msgid "users_info_nickname"
+msgstr "ПрізвиÑько"
+
+#: controllers/users_controller.php:707
+#, php-format
+msgid "users_info_pagetitle"
+msgstr "Ð†Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ñ–Ñ ÐºÐ¾Ñ€Ð¸Ñтувача Ð´Ð»Ñ %1$s"
+
+#. %1 is the user's name
+#: views/users/info.thtml:116
+#, fuzzy
+msgid "users_info_reviews_by_user"
+msgstr "Reviews by %s"
+
+#: controllers/users_controller.php:330 controllers/users_controller.php:332
+msgid "users_login_pagetitle"
+msgstr "Вхід кориÑтувача"
+
+#. %1 is the link to the sandbox/policy explanation page
+#. This message is for a specific add-on not found
+#: views/users/login.thtml:53
+#, php-format
+msgid "users_login_sandbox_display_warning"
+msgstr ""
+"Додаток, Ñкий ви шукаєте, зараз у піÑочниці. Якщо ви вже маєте рахунок на "
+"Додатках Mozilla’и, будь лаÑка, увійдіть, або <a href=\"%1$s\">дізнайтеÑÑ "
+"більше про піÑочницю.</a>"
+
+#. %1 is the link to the sandbox/policy explanation page
+#. This message is for any given sandbox-related page not found
+#: views/users/login.thtml:56
+#, php-format
+msgid "users_login_sandbox_page_warning"
+msgstr ""
+"Сторінка, Ñку ви шукаєте, Ñ” чаÑтиною піÑочниці. Якщо ви вже маєте рахунок на "
+"Додатках Mozilla’и, будь лаÑка, увійдіть, або <a href=\"%1$s\">дізнайтеÑÑ "
+"більше про піÑочницю.</a>"
+
+#: controllers/users_controller.php:223 controllers/users_controller.php:225
+msgid "users_pwreset_pagetitle"
+msgstr "Ð¡ÐºÐ¸Ð´Ð°Ð½Ð½Ñ Ð¿Ð°Ñ€Ð¾Ð»Ñ ÐºÐ¾Ñ€Ð¸Ñтувача"
+
+#: controllers/users_controller.php:90 controllers/users_controller.php:92
+msgid "users_register_pagetitle"
+msgstr "РеєÑÑ‚Ñ€Ð°Ñ†Ñ–Ñ Ð½Ð¾Ð²Ð¾Ð³Ð¾ кориÑтувача"
+
+#. %1$s is an addon name, like <a>Firebug</a>
+#. %2$s is a version number, like <a>1.2</a>
+#: views/versions/license.thtml:52
+#, fuzzy
+msgid "versions_license_header_source"
+msgstr "Source code license for %1$s %2$s"
+
+#: views/addons/category_landing.thtml:147
+#, fuzzy
+msgid "view_recently_added"
+msgstr "View all recently added"
+
+#: views/addons/category_landing.thtml:161
+#, fuzzy
+msgid "view_top_downloads"
+msgstr "View all top downloads"
+
+#: views/addons/category_landing.thtml:175
+#, fuzzy
+msgid "view_top_rated"
+msgstr "View all top rated"
+
+#~ msgid "addon_slider_tooltip_next"
+#~ msgstr "ÐаÑтупний додаток"
+
+#~ msgid "addon_slider_tooltip_previous"
+#~ msgstr "Попередній додаток"
+
+#~ msgid "addon_versions_getlatesttext"
+#~ msgstr "ÐайоÑтанніша верÑÑ–Ñ ÑуміÑна з"
+
+#~ msgid "addons_display_version_history"
+#~ msgstr "Повна Ñ–ÑÑ‚Ð¾Ñ€Ñ–Ñ Ð²ÐµÑ€Ñій"
+
+#~ msgid "addons_home_newest_header"
+#~ msgstr "Ðайновіші:"
+
+#~ msgid "addons_home_popular_header"
+#~ msgstr "ÐайпопулÑрніші:"
+
+#~ msgid "addons_home_recommended_header"
+#~ msgstr "Ми рекомендуємо:"
+
+#~ msgid "addons_home_updated_header"
+#~ msgstr "Ðедавно оновлені:"
+
+#~ msgid "addons_home_view_all"
+#~ msgstr "ПереглÑнути вÑÑ–"
+
+#~ msgid "category_extra_allrecommended"
+#~ msgstr "ПереглÑнути вÑÑ– рекомендовані додатки"
+
+#~ msgid "category_extra_highestrated"
+#~ msgstr "Ðайрейтинговіші Ñпочатку"
+
+#~ msgid "category_extra_lastupdated"
+#~ msgstr "Ðайновіші Ñпочатку"
+
+#~ msgid "category_extra_mostpopular"
+#~ msgstr "ÐайпопулÑрніші Ñпочатку"
+
+#, fuzzy
+#~ msgid "collections_detail_js_loading"
+#~ msgstr "Loading"
+
+#, fuzzy
+#~ msgid "collections_detail_more_info"
+#~ msgstr "Show More Info"
+
+#~ msgid "devcp_additem_firefox_notice"
+#~ msgstr ""
+#~ "This version of your add-on does not claim compatibility with Firefox %1"
+#~ "$s. Mozilla is expecting the next version of Firefox to be released soon, "
+#~ "so please test your add-on in the new version and update compatibility "
+#~ "information. You can find out more about this <a href=\"%2$s\">here</a>. "
+#~ "This is only a notice and you may continue to submit this version to "
+#~ "addons.mozilla.org."
+
+#~ msgid "devcp_addon_disabled_successfully"
+#~ msgstr "Додаток відключено уÑпішно"
+
+#~ msgid "devcp_addon_edit_pagetitle"
+#~ msgstr "Редагувати додаток"
+
+#~ msgid "devcp_addon_enabled_successfully"
+#~ msgstr "Додаток включено уÑпішно"
+
+#~ msgid "devcp_addon_field_description_displaytitle"
+#~ msgstr "ÐžÐ¿Ð¸Ñ Ð´Ð¾Ð´Ð°Ñ‚ÐºÑƒ"
+
+#~ msgid "devcp_addon_field_eula_displaytitle"
+#~ msgstr "ЛУКК"
+
+#~ msgid "devcp_addon_field_homepage_displaytitle"
+#~ msgstr "Ð”Ð¾Ð¼Ð°ÑˆÐ½Ñ Ñторінка додатку"
+
+#~ msgid "devcp_addon_field_name_displaytitle"
+#~ msgstr "Ðазва додатку"
+
+#~ msgid "devcp_addon_field_privacy_displaytitle"
+#~ msgstr "Умови конфіденційноÑÑ‚Ñ–"
+
+#~ msgid "devcp_addon_field_summary_displaytitle"
+#~ msgstr "ПідÑумок додатку"
+
+#~ msgid "devcp_addon_field_supportemail_displaytitle"
+#~ msgstr "Support Email"
+
+#~ msgid "devcp_addon_field_supporturl_displaytitle"
+#~ msgstr "Support URL"
+
+#~ msgid "devcp_addon_field_versionnotes_displaytitle"
+#~ msgstr "Примітки верÑÑ–Ñ—"
+
+#~ msgid "devcp_addon_nominate_pagetitle"
+#~ msgstr "Подати додаток"
+
+#~ msgid "devcp_addon_nominated_successfully"
+#~ msgstr "Додаток подано уÑпішно!"
+
+#~ msgid "devcp_addon_status_criteria_review"
+#~ msgstr "Кілька відгуків кориÑтувачів додатку (можна зовнішніх)."
+
+#~ msgid "devcp_addon_submission_makechanges"
+#~ msgstr ""
+#~ "Відвідайте Ñторінку %1$ Ð´Ð»Ñ Ð²Ð½ÐµÑÐµÐ½Ð½Ñ Ð·Ð¼Ñ–Ð½ в Ñвоє поданнÑ, або %2$s Ð´Ð»Ñ "
+#~ "Ð¿Ð¾Ð²ÐµÑ€Ð½ÐµÐ½Ð½Ñ Ñƒ Панель ÑƒÐ¿Ñ€Ð°Ð²Ð»Ñ–Ð½Ð½Ñ Ñ€Ð¾Ð·Ñ€Ð¾Ð±Ð½Ð¸ÐºÐ°."
+
+#~ msgid "devcp_addon_submission_makechanges_devcp_link"
+#~ msgstr "клацніть тут"
+
+#~ msgid "devcp_addon_submission_makechanges_link"
+#~ msgstr "Редагувати додаток"
+
+#~ msgid "devcp_addon_submission_pending"
+#~ msgstr ""
+#~ "Ð¦Ñ Ð²ÐµÑ€ÑÑ–Ñ Ñ€Ð¾Ð·Ð¼Ñ–Ñ‰ÐµÐ½Ð° у піÑочниці Ñ– очікує переглÑдів від випробувальників "
+#~ "піÑочниці та редактора додатків Mozilla’и. Ð’Ð°Ñ Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÑÑ‚ÑŒ електронною "
+#~ "поштою, коли відбудетьÑÑ Ð¿Ð¾Ð´Ñ–Ñ."
+
+#~ msgid "devcp_addon_submission_sandbox_readmore"
+#~ msgstr "Ви можете прочитати більше про ÑиÑтему переглÑду піÑочниці %s."
+
+#~ msgid "devcp_addon_submission_sandbox_readmore_link"
+#~ msgstr "тут"
+
+#~ msgid "devcp_addon_submission_sandboxed"
+#~ msgstr ""
+#~ "Ð¦Ñ Ð²ÐµÑ€ÑÑ–Ñ Ñ€Ð¾Ð·Ð¼Ñ–Ñ‰ÐµÐ½Ð° у піÑочниці Ð´Ð»Ñ Ð²Ð¸ÐºÐ¾Ñ€Ð¸ÑÑ‚Ð°Ð½Ð½Ñ Ð´Ð¾Ñвідченими "
+#~ "кориÑтувачами. Щоб Ñ—Ñ— показали на публічному Ñайті, ви повинні %s ваш "
+#~ "додаток Ñ– пройти Ð¿Ñ€Ð¾Ñ†ÐµÑ Ð¿ÐµÑ€ÐµÐ³Ð»Ñду."
+
+#~ msgid "devcp_addon_submission_sandboxed_nominate_link"
+#~ msgstr "надіÑлати"
+
+#~ msgid "devcp_addon_submission_success"
+#~ msgstr "ÐадÑÐ¸Ð»Ð°Ð½Ð½Ñ Ð²Ð°ÑˆÐ¾Ð³Ð¾ додатку завершено уÑпішно."
+
+#~ msgid "devcp_addon_submission_trusted_public"
+#~ msgstr ""
+#~ "Тому, що вашому додатку довірÑÑŽÑ‚ÑŒ, Ñ†Ñ Ð²ÐµÑ€ÑÑ–Ñ Ð°Ð²Ñ‚Ð¾Ð¼Ð°Ñ‚Ð¸Ñ‡Ð½Ð¾ Ñхвалена Ð´Ð»Ñ "
+#~ "публічної ділÑнки."
+
+#~ msgid "devcp_addon_submit_pagetitle"
+#~ msgstr "ÐадіÑлати додаток"
+
+#~ msgid "devcp_addon_updated_successfully"
+#~ msgstr "Додаток оновлено уÑпішно"
+
+#~ msgid "devcp_addon_upload_preview"
+#~ msgstr "Ви можете захотіти %s , щоб підвищити Ñ–Ð½Ñ‚ÐµÑ€ÐµÑ Ð´Ð¾ Ñвого додатку."
+
+#~ msgid "devcp_addon_upload_preview_link"
+#~ msgstr "відвантажити знімок екрану"
+
+#~ msgid "devcp_author_lookup_none_found"
+#~ msgstr "Жодного автора [%s] не знайдено"
+
+#~ msgid "devcp_author_lookup_remove"
+#~ msgstr "Вилучити"
+
+#~ msgid "devcp_button_cancel"
+#~ msgstr "Відкликати"
+
+#~ msgid "devcp_button_cancel_confirm"
+#~ msgstr "Певні, що бажаєте відкликати Ñвоє поданнÑ?"
+
+#~ msgid "devcp_button_next"
+#~ msgstr "Далі"
+
+#~ msgid "devcp_change_addontype"
+#~ msgstr "Змінити тип додатку:"
+
+#~ msgid "devcp_comments_updated"
+#~ msgstr "Оновлено коментарі розробника."
+
+#~ msgid "devcp_details_addpreview_link"
+#~ msgstr "Додати знімок екрану"
+
+#~ msgid "devcp_details_author"
+#~ msgstr "Ðвтор"
+
+#~ msgid "devcp_details_authors"
+#~ msgstr "Ðвтори"
+
+#~ msgid "devcp_details_authors_none"
+#~ msgstr "Жодних"
+
+#~ msgid "devcp_details_categories"
+#~ msgstr "Категорії"
+
+#~ msgid "devcp_details_category"
+#~ msgstr "КатегоріÑ"
+
+#~ msgid "devcp_details_description"
+#~ msgstr "ОпиÑ"
+
+#~ msgid "devcp_details_disabled"
+#~ msgstr "Відключено"
+
+#~ msgid "devcp_details_guid"
+#~ msgstr "GUID"
+
+#~ msgid "devcp_details_header_details"
+#~ msgstr "Деталі"
+
+#~ msgid "devcp_details_header_devcomments"
+#~ msgstr "Коментарі розробника"
+
+#~ msgid "devcp_details_header_previews"
+#~ msgstr "Знімки екрану"
+
+#~ msgid "devcp_details_header_versions"
+#~ msgstr "ВерÑÑ–Ñ—"
+
+#~ msgid "devcp_details_homepage"
+#~ msgstr "Ð”Ð¾Ð¼Ð°ÑˆÐ½Ñ Ñторінка"
+
+#~ msgid "devcp_details_homepage_none"
+#~ msgstr "Жодних"
+
+#~ msgid "devcp_details_preview_nocaption"
+#~ msgstr "Без заголовка"
+
+#~ msgid "devcp_details_previews_nonefound"
+#~ msgstr "Знімків екрану не знайдено."
+
+#~ msgid "devcp_details_submit_update"
+#~ msgstr "Оновити"
+
+#~ msgid "devcp_details_supportemail"
+#~ msgstr "Support Email"
+
+#~ msgid "devcp_details_supportemail_none"
+#~ msgstr "No support email provided by developer."
+
+#~ msgid "devcp_details_supporturl"
+#~ msgstr "Support URL"
+
+#~ msgid "devcp_details_supporturl_none"
+#~ msgstr "No support url provided by developer."
+
+#~ msgid "devcp_details_trusted"
+#~ msgstr "Довірити"
+
+#~ msgid "devcp_details_versions_none_found"
+#~ msgstr "ВерÑій не знайдено."
+
+#~ msgid "devcp_disable_cancel"
+#~ msgstr "Cancel and go back"
+
+#~ msgid "devcp_disable_disable_button"
+#~ msgstr "Yes, disable it"
+
+#~ msgid "devcp_disable_disable_confirm"
+#~ msgstr "Are you sure you want to disable this add-on?"
+
+#~ msgid "devcp_disable_disable_description"
+#~ msgstr ""
+#~ "Disabling this add-on will hide it from searches and listings. It will "
+#~ "not be downloadable from the website and will not be returned in client "
+#~ "update checks. The add-on will effectively be deleted, although you will "
+#~ "be able to return here and re-enable it at your convenience."
+
+#~ msgid "devcp_disable_disable_title"
+#~ msgstr "Disable %s"
+
+#~ msgid "devcp_disable_enable_button"
+#~ msgstr "Yes, enable it"
+
+#~ msgid "devcp_disable_enable_confirm"
+#~ msgstr "Are you sure you want to enable this add-on?"
+
+#~ msgid "devcp_disable_enable_description"
+#~ msgstr ""
+#~ "Enabling this add-on will cause it to once again appear in searches and "
+#~ "listings. It will be downloadable both from the website and from client "
+#~ "update checks."
+
+#~ msgid "devcp_disable_enable_title"
+#~ msgstr "Enable %s"
+
+#~ msgid "devcp_edit_author_add"
+#~ msgstr "Додати автора"
+
+#~ msgid "devcp_edit_author_email"
+#~ msgstr "Email автора"
+
+#~ msgid "devcp_edit_author_remove"
+#~ msgstr "Стерти"
+
+#~ msgid "devcp_edit_error_categories_unavailable"
+#~ msgstr "Категорії відÑутні Ð´Ð»Ñ Ñ†ÑŒÐ¾Ð³Ð¾ типу додатку."
+
+#, fuzzy
+#~ msgid "devcp_edit_file_error_incomplete"
+#~ msgstr "Incomplete transfer"
+
+#, fuzzy
+#~ msgid "devcp_edit_file_error_no"
+#~ msgstr "No file uploaded"
+
+#, fuzzy
+#~ msgid "devcp_edit_file_error_size"
+#~ msgstr "Exceeds maximum upload size"
+
+#~ msgid "devcp_edit_header_authors"
+#~ msgstr "Ðвтори"
+
+#~ msgid "devcp_edit_icon_add_link"
+#~ msgstr "Додати значка"
+
+#~ msgid "devcp_edit_icon_change_link"
+#~ msgstr "Змінити значок"
+
+#~ msgid "devcp_edit_label_allow_viewsource"
+#~ msgstr "Дозволити кориÑтувачам читати початкові файли в мережі"
+
+#~ msgid "devcp_edit_label_categories"
+#~ msgstr "Категорії"
+
+#~ msgid "devcp_edit_label_defaultlocale"
+#~ msgstr "Типова мова"
+
+#~ msgid "devcp_edit_label_icon_delete"
+#~ msgstr "Тільки Ñтерти Ñ–Ñнуючий значок"
+
+#~ msgid "devcp_edit_label_icon_new"
+#~ msgstr "Ðовий файл значка"
+
+#~ msgid "devcp_edit_label_info"
+#~ msgstr "Значок"
+
+#~ msgid "devcp_edit_locale_disambiguation_explanation"
+#~ msgstr "short additional info (such as a local dialect name)"
+
+#~ msgid "devcp_edit_submit_update"
+#~ msgstr "Оновити"
+
+#~ msgid "devcp_edit_target_locale_explanation"
+#~ msgstr ""
+#~ "<a href=\"http://wiki.mozilla.org/L10n:Simple_locale_names\">simple "
+#~ "locale name</a>, such as 'en-US'"
+
+#~ msgid "devcp_editversion_checkedfiles_delete"
+#~ msgstr "Позначені файли будуть Ñтерті."
+
+#~ msgid "devcp_editversion_filename_size"
+#~ msgstr "%1$s (%2$s)"
+
+#~ msgid "devcp_editversion_label_files"
+#~ msgstr "Файли"
+
+#~ msgid "devcp_editversion_label_targetapps"
+#~ msgstr "Цільові програми"
+
+#~ msgid "devcp_editversion_nofiles"
+#~ msgstr "Ðемає файлів."
+
+#~ msgid "devcp_editversion_reviewernotes"
+#~ msgstr "Примітки оглÑдачу"
+
+#~ msgid "devcp_editversion_submit_update"
+#~ msgstr "Оновити"
+
+#~ msgid "devcp_error_addon_field_summary_toolong"
+#~ msgstr ""
+#~ "ПідÑумки обмежені до макÑимально 250 Ñимволів.\n"
+#~ "(Ви ввели %s)"
+
+#~ msgid "devcp_error_addonname_not_unique"
+#~ msgstr ""
+#~ "Ðазва Ð´Ð»Ñ Ð²Ð°ÑˆÐ¾Ð³Ð¾ додатку вже Ñ–Ñнує в базі даних. Будь лаÑка, "
+#~ "переконайтеÑÑ, що: <br /><li>ваші GUIDи відповідають. Ðайпоширеніша "
+#~ "причина цієї помилки – це невідповідні GUIDи.</li><li>ви не маєте "
+#~ "дублікату запиÑу у базі даних. Якщо маєте, ви повинні оновити або Ñтерти "
+#~ "цей Ð·Ð°Ð¿Ð¸Ñ Ñ– Ñпробувати знову.</li>"
+
+#~ msgid "devcp_error_describe_changes"
+#~ msgstr "Будь лаÑка, опишіть зміни, зроблені у цьому оновленні додатку."
+
+#~ msgid "devcp_error_file_guids_dont_match"
+#~ msgstr "Ðе вÑÑ– файли GUIDів відповідають"
+
+#~ msgid "devcp_error_identical_version_exists"
+#~ msgstr "Ідентична верÑÑ–Ñ (%s) вже Ñ–Ñнує Ð´Ð»Ñ Ñ†ÑŒÐ¾Ð³Ð¾ додатку Ñ– платформи."
+
+#~ msgid "devcp_error_nominate_message"
+#~ msgstr "Ви повинні подати потрібні деталі Ð´Ð»Ñ Ð¿Ð¾Ð´Ð°Ð½Ð½Ñ."
+
+#~ msgid "devcp_error_nominate_no_prerelease"
+#~ msgstr "Ви не можете подавати додаток попередньої верÑÑ–Ñ—."
+
+#~ msgid "devcp_error_nominate_sandbox_only"
+#~ msgstr "Ви можете подавати тільки додатки, Ñкі вже в піÑочниці."
+
+#~ msgid "devcp_error_saving"
+#~ msgstr "СталаÑÑ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ° при збереженні ваших даних."
+
+#~ msgid "devcp_error_update_access_denied"
+#~ msgstr "Вам не дозволено оновлювати цей додаток."
+
+#~ msgid "devcp_file_addanother"
+#~ msgstr "Додати файл іншої платформи"
+
+#~ msgid "devcp_form_author_add"
+#~ msgstr "Додати автора"
+
+#~ msgid "devcp_form_author_remove"
+#~ msgstr "Вилучити"
+
+#~ msgid "devcp_form_categories_nextstep"
+#~ msgstr ""
+#~ "Категорії Ð´Ð»Ñ Ð²Ð°ÑˆÐ¾Ð³Ð¾ нового типу додатку будуть доÑтупні на наÑтупному "
+#~ "кроці."
+
+#~ msgid "devcp_form_error_categories_unavailable"
+#~ msgstr "Ð”Ð»Ñ Ñ†ÑŒÐ¾Ð³Ð¾ типу додатку категорії недоÑтупні."
+
+#~ msgid "devcp_form_error_description_notempty"
+#~ msgstr "Будь лаÑка, введіть Ð¾Ð¿Ð¸Ñ Ð²Ð°ÑˆÐ¾Ð³Ð¾ додатку."
+
+#~ msgid "devcp_form_error_name_required"
+#~ msgstr "Будь лаÑка, введіть назву вашого додатку."
+
+#~ msgid "devcp_form_error_select_addontype"
+#~ msgstr "Будь лаÑка, оберіть тип додатку, Ñкий ви подаєте."
+
+#~ msgid "devcp_form_error_summary_notempty"
+#~ msgstr "Будь лаÑка, введіть підÑумок вашого додатку."
+
+#~ msgid "devcp_form_label_addonfile"
+#~ msgstr "Файл додатку"
+
+#~ msgid "devcp_form_label_addonfile2"
+#~ msgstr "Файл додатку 2"
+
+#~ msgid "devcp_form_label_addonfile3"
+#~ msgstr "Файл додатку 3"
+
+#~ msgid "devcp_form_label_addontype"
+#~ msgstr "Тип додатку"
+
+#~ msgid "devcp_form_label_allow_viewsource"
+#~ msgstr "Дозволити кориÑтувачам переглÑдати початковий код в онлайні"
+
+#~ msgid "devcp_form_label_author_email"
+#~ msgstr "Email адреÑа автора"
+
+#~ msgid "devcp_form_label_authors"
+#~ msgstr "Ðвтори"
+
+#~ msgid "devcp_form_label_categories"
+#~ msgstr "Категорії"
+
+#~ msgid "devcp_form_label_defaultlocale"
+#~ msgstr "Типова мова"
+
+#~ msgid "devcp_form_label_description"
+#~ msgstr "ОпиÑ"
+
+#~ msgid "devcp_form_label_eula"
+#~ msgstr "Ліцензійна угода з кінцевим кориÑтувачем (ЛУКК)"
+
+#~ msgid "devcp_form_label_externalsoftware"
+#~ msgstr "Цей додаток потребує зовнішніх програм"
+
+#~ msgid "devcp_form_label_files"
+#~ msgstr "Файли"
+
+#~ msgid "devcp_form_label_homepage"
+#~ msgstr "Ð”Ð¾Ð¼Ð°ÑˆÐ½Ñ Ñторінка"
+
+#~ msgid "devcp_form_label_iconfile"
+#~ msgstr "Файл значка"
+
+#~ msgid "devcp_form_label_name"
+#~ msgstr "Ім’Ñ"
+
+#~ msgid "devcp_form_label_platforms"
+#~ msgstr "Підтримувані платформи"
+
+#~ msgid "devcp_form_label_prerelease"
+#~ msgstr "Це Ð¿Ð¾Ð¿ÐµÑ€ÐµÐ´Ð½Ñ Ð²ÐµÑ€ÑÑ–Ñ"
+
+#~ msgid "devcp_form_label_privacy"
+#~ msgstr "Умови конфіденційноÑÑ‚Ñ–"
+
+#~ msgid "devcp_form_label_sitespecific"
+#~ msgstr "Це додаток Ð´Ð»Ñ Ð¾ÐºÑ€ÐµÐ¼Ð¾Ð³Ð¾ Ñайту"
+
+#~ msgid "devcp_form_label_summary"
+#~ msgstr "ПідÑумок"
+
+#~ msgid "devcp_form_label_supportemail"
+#~ msgstr "Support Email"
+
+#~ msgid "devcp_form_label_supporturl"
+#~ msgstr "Support URL"
+
+#~ msgid "devcp_form_label_target_applications"
+#~ msgstr "Цільові програми"
+
+#~ msgid "devcp_form_label_version"
+#~ msgstr "ВерÑÑ–Ñ"
+
+#~ msgid "devcp_form_label_versionnotes"
+#~ msgstr "Примітки верÑÑ–Ñ—"
+
+#~ msgid "devcp_form_no_target_apps"
+#~ msgstr "Жодних"
+
+#~ msgid "devcp_form_reviewernotes"
+#~ msgstr "Примітки переглÑдачу"
+
+#~ msgid "devcp_form_trustedaddon_destination"
+#~ msgstr ""
+#~ "Тому що вашому додатку довірÑÑŽÑ‚ÑŒ, будь лаÑка, оберіть куди повинна піти "
+#~ "Ñ†Ñ Ð²ÐµÑ€ÑÑ–Ñ:"
+
+#~ msgid "devcp_form_trustedaddon_destination_public"
+#~ msgstr "Публіка"
+
+#~ msgid "devcp_form_trustedaddon_destination_sandbox"
+#~ msgstr "ПіÑочницÑ"
+
+#~ msgid "devcp_header_developer_agreement"
+#~ msgstr "Угода з розробником"
+
+#~ msgid "devcp_header_step1"
+#~ msgstr "Крок 1"
+
+#~ msgid "devcp_header_step1_upload"
+#~ msgstr "Відвантажити файл"
+
+#~ msgid "devcp_header_step2"
+#~ msgstr "Крок 2"
+
+#~ msgid "devcp_header_step2_addondetails"
+#~ msgstr "Деталі додатку"
+
+#~ msgid "devcp_header_step3"
+#~ msgstr "Крок 3"
+
+#~ msgid "devcp_header_step3_versiondetails"
+#~ msgstr "Деталі верÑÑ–Ñ—"
+
+#~ msgid "devcp_header_step4"
+#~ msgstr "Крок 4"
+
+#~ msgid "devcp_header_step4_localization"
+#~ msgstr "Переклади"
+
+#~ msgid "devcp_header_step5"
+#~ msgstr "Крок 5"
+
+#~ msgid "devcp_header_step5_success"
+#~ msgstr "УÑпіх"
+
+#~ msgid "devcp_index_header_myaddons"
+#~ msgstr "Мої додатки"
+
+#~ msgid "devcp_nominate_link_returnto_details"
+#~ msgstr "ПовернутиÑÑ Ð´Ð¾ деталей додатку"
+
+#~ msgid "devcp_notice_autodetected_addontype"
+#~ msgstr "Ðвтоматично визначений тип додатку: %s."
+
+#~ msgid "devcp_notice_different_defaultlocale"
+#~ msgstr ""
+#~ "Типова мова цього додатку (%1$s [%2$s]) відмінна від поточно обраної вами "
+#~ "мови (%3$s [%4$s]). ÐŸÐ¾Ð»Ñ Ð½Ð¸Ð¶Ñ‡Ðµ повинні бути заповнені на %1$s."
+
+#~ msgid "devcp_question_addontype_incorrect"
+#~ msgstr "Ðевірно?"
+
+#~ msgid "devcp_question_delete_file"
+#~ msgstr "Ви впевнені, що хочете Ñтерти цей файл?"
+
+#~ msgid "devcp_skip_reviewing_addon_info"
+#~ msgstr "ПропуÑтити Ð¾Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ñ–Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ñ–Ñ— про мій поточний додаток"
+
+#~ msgid "devcp_submissions_disabled"
+#~ msgstr ""
+#~ "ÐŸÐ¾Ð´Ð°Ð²Ð°Ð½Ð½Ñ Ð´Ð¾Ð´Ð°Ñ‚ÐºÑ–Ð² зараз відключено. Будь лаÑка, Ñпробуйте знову пізніше."
+
+#~ msgid "devcp_submit_accept_dev_agreement"
+#~ msgstr "Я погоджуюÑÑŒ"
+
+#~ msgid "devcp_submit_decline_dev_agreement"
+#~ msgstr "Я відмовлÑÑŽÑÑŒ"
+
+#~ msgid "devcp_summary_admin_disabled"
+#~ msgstr "Цей додаток було відключено адмініÑтратором."
+
+#~ msgid "devcp_summary_header_disabled"
+#~ msgstr "Відключено"
+
+#~ msgid "devcp_summary_header_trusted"
+#~ msgstr "Довірено"
+
+#~ msgid "devcp_summary_noaddons_submit_one"
+#~ msgstr "У Ð²Ð°Ñ Ð½ÐµÐ¼Ð°Ñ” жодних додатків. Клацніть %s Ð´Ð»Ñ Ð¿Ð¾Ð´Ð°Ð½Ð½Ñ."
+
+#~ msgid "devcp_summary_noaddons_submit_one_link"
+#~ msgstr "тут"
+
+#~ msgid "devcp_theme_upload_preview"
+#~ msgstr "Будь лаÑка, переконайтеÑÑ, що %s Ð´Ð»Ñ Ð²Ð°ÑˆÐ¾Ñ— теми."
+
+#~ msgid "devcp_theme_upload_preview_link"
+#~ msgstr "Відвантажити знімок екрану"
+
+#~ msgid "devcp_version_edit_pagetitle"
+#~ msgstr "Редагувати верÑÑ–ÑŽ"
+
+#~ msgid "devcp_version_updated_successfully"
+#~ msgstr "ВерÑÑ–Ñ Ð¾Ð½Ð¾Ð²Ð»ÐµÐ½Ð° уÑпішно."
+
+#~ msgid "editors_submissiontype_new"
+#~ msgstr "Ðове"
+
+#~ msgid "editors_submissiontype_updated"
+#~ msgstr "Оновлене"
+
+#, fuzzy
+#~ msgid "editors_th_addon_age"
+#~ msgstr "Add-on Age"
+
+#~ msgid "editors_th_addontypes"
+#~ msgstr "Тип додатків"
+
+#~ msgid "editors_th_age"
+#~ msgstr "Вік"
+
+#~ msgid "editors_th_applications"
+#~ msgstr "Програми"
+
+#~ msgid "editors_th_platforms"
+#~ msgstr "Платформи"
+
+#~ msgid "editors_th_submissiontypes"
+#~ msgstr "Типи подаваннÑ"
+
+#~ msgid "error_notice"
+#~ msgstr "ПовідомленнÑ"
+
+#~ msgid "forum_save"
+#~ msgstr "Зберегти"
+
+#, fuzzy
+#~ msgid "home"
+#~ msgstr "home"
+
+#~ msgid "nav_category_plugins"
+#~ msgstr "Модулі"
+
+#, fuzzy
+#~ msgid "page_title_experimental_addons"
+#~ msgstr "Experimental Add-ons"
+
+#~ msgid "pages_experimental_addons_backbutton"
+#~ msgstr "Ðазад на попередню Ñторінку"
+
+#~ msgid "pagination_page_number_title"
+#~ msgstr "Це Ñторінка %1$s з %2$s"
+
+#~ msgid "search_matching_addons_number"
+#~ msgid_plural "search_matching_addons_number"
+#~ msgstr[0] "%s відповідний додаток"
+#~ msgstr[1] "%s відповідних додатків"
+
+#~ msgid "statistics_rss_icon_title"
+#~ msgstr "RSS feed of summary data"
diff --git a/site/app/locale/uk/images/sandbox-review.png b/site/app/locale/uk/images/sandbox-review.png
new file mode 100644
index 0000000..dda0622
--- /dev/null
+++ b/site/app/locale/uk/images/sandbox-review.png
Binary files differ
diff --git a/site/app/locale/uk/pages/error404.thtml b/site/app/locale/uk/pages/error404.thtml
new file mode 100644
index 0000000..5f4ba71
--- /dev/null
+++ b/site/app/locale/uk/pages/error404.thtml
@@ -0,0 +1,16 @@
+<h1>Перепрошуємо, <br/> але шукане знайти не вдалоÑÑŒ.</h1>
+
+<p>Сторінка чи файл, що ви шукали, відÑÑƒÑ‚Ð½Ñ Ð½Ð° нашому Ñайті. Можливо, ви клацнули на поÑиланні, котре вже заÑтаріло, або невірно набрали адреÑу.</p>
+
+<ul>
+<li>Якщо ви набирали адреÑу, перевірте напиÑÐ°Ð½Ð½Ñ Ñ‰Ðµ раз.</li>
+<li>Якщо ви переходили звідкиÑÑŒ за поÑиланнÑм, будь лаÑка, дайте нам знати на <a href="mailto:webmaster@mozilla.com" title="Сторінку на Mozilla.com не знайдено">webmaster@mozilla.com</a>. Скажіть, звідки ви перейшли Ñ– що шукали, Ñ– ми зробимо вÑе можливе Ð´Ð»Ñ Ñ‚Ð¾Ð³Ð¾, щоб виправити цей негаразд.</li>
+</ul>
+
+<p>Ðбо ви можете перейти на інші популÑрні Ñторінки нашого вебÑайту.</p>
+
+<ul>
+<li>Чи зацікавить Ð²Ð°Ñ <a href="%1$s">перелік популÑрних додатків</a>?</li>
+<li>Щукаєте <a href="%2$s">додатки</a>? Можете перейти на <a href="%2$s">Ñторінку пошуку</a> або проÑто ÑкориÑтатиÑÑŒ полем унизу Ñторінки.</li>
+<li>Якщо хочете розпочати з початку, перейдіть на <a href="%3$s">початкову Ñторінку додатків</a>.</li>
+</ul>
diff --git a/site/app/locale/uk/pages/nomination.thtml b/site/app/locale/uk/pages/nomination.thtml
new file mode 100644
index 0000000..0bc474f
--- /dev/null
+++ b/site/app/locale/uk/pages/nomination.thtml
@@ -0,0 +1,10 @@
+<p>Додаток, Ñкий зараз в піÑочниці, може подаватиÑÑ Ð½Ð° те, щоб бути чаÑтиною публічного Ñайту Ñ– бути доÑтупним вÑім кориÑтувачам піÑÐ»Ñ Ñ‚Ð¾Ð³Ð¾, Ñк його переглÑне редактор. Ð”Ð»Ñ Ð½Ð°Ð¹ÐºÑ€Ð°Ñ‰Ð¸Ñ… результатів зауважте на наÑтупне:</p>
+<ul>
+ <li>Презентаційні Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ Ð¿Ð¾Ñ‚Ñ€Ñ–Ð±Ð½Ñ– Ð´Ð»Ñ Ñ‚ÐµÐ¼ Ñ– дуже рекомендуютьÑÑ Ð´Ð»Ñ Ð²ÑÑ–Ñ… інших типів додатків.</li>
+ <li>Додаток повинен провеÑти доÑтатньо чаÑу у піÑочниці, щоб отримати оглÑди Ñ– зворотній зв’Ñзок від кориÑтувачів. <b>ОглÑди потрібні Ð´Ð»Ñ Ñ‚Ð¾Ð³Ð¾, щоб Ñтати публічним.</b></li>
+ <li>Публічні додатки мають вищий рівень ÑкоÑÑ‚Ñ–, ніж додатки з піÑочниці, Ñ– повинні покращувати мережу.</li>
+ <li>Ð’ÑÑ– критерії Ð¿Ð¾Ð´Ð°Ð½Ð½Ñ Ð´Ð¾Ñтупні у <a href="%s">Політиці додатків</a>.</li>
+</ul>
+<p>Якщо ваш додаток відповідає вищезазначеним критеріÑм, ви можете подавати його, заповнивши поле нижче. Ð’Ð°Ñ Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÑÑ‚ÑŒ електронною поштою про Ñтан вашого поданнÑ.</p>
+
+<p>Ð”Ð»Ñ Ð¿Ð¾Ð´Ð°Ð½Ð½Ñ Ð²Ð°ÑˆÐ¾Ð³Ð¾ додатку, будь лаÑка, опишіть, Ñк його теÑтували (маючи на увазі, що у ньому відÑутні помилки Ñ– попередженнÑ) Ñ– Ñк він буде кориÑним розширенню мережі. Можете також включити поÑÐ¸Ð»Ð°Ð½Ð½Ñ Ð½Ð° зовнішні оглÑди вашого додатку.</p>
diff --git a/site/app/locale/uk/pages/policy.thtml b/site/app/locale/uk/pages/policy.thtml
new file mode 100644
index 0000000..aa1509a
--- /dev/null
+++ b/site/app/locale/uk/pages/policy.thtml
@@ -0,0 +1,110 @@
+<h1>Правила Ð¿Ð¾Ð´Ð°Ð½Ð½Ñ Ð´Ð¾Ð´Ð°Ñ‚ÐºÑ–Ð²</h1>
+
+<h2>Що таке піÑочницÑ?</h2>
+<p>ДивітьÑÑ %s.</p>
+
+<h2>Які додатки знаходÑÑ‚ÑŒÑÑ Ñƒ піÑочниці?</h2>
+<p>Ð’ÑÑ– додатки, що надходÑÑ‚ÑŒ до ÐМО Ñпочатку попадають у піÑочницю. Вона міÑтить нові верÑÑ–Ñ— публічних додатків, а також вÑÑ– верÑÑ–Ñ— додатків, що не Ñтали публічними. При відвантаженні на ÐМО нового додатку, або оновленні Ñ–Ñнуючого, його розміщують у піÑочниці.</p>
+
+<p>ДеÑкі додатки та окремі Ñ—Ñ… верÑÑ–Ñ— Ñтають публічними піÑÐ»Ñ Ñ‚Ð¾Ð³Ð¾, Ñк перевірка покаже, що вони до цього готові. Інші додатки залишатимутьÑÑ Ñƒ піÑочниці невизначено довго, де вони будуть доÑтупні Ð´Ð»Ñ ÐºÐ¾Ñ€Ð¸Ñтувачів, Ñкі обирають переглÑдати піÑочницю та екÑпериментувати там з програмним забезпеченнÑм.</p>
+
+<h2>Як додатки Ñтають публічними?</h2>
+
+<p>Додатки теÑтуютьÑÑ ÐºÐ¾Ñ€Ð¸Ñтувачами AMO, Ñкі надають перевагу переглÑду піÑочниці та випробуванню пакетів, Ñкі там можна знайти. Відгуки, Ñкі напишуть кориÑтувачі AMO, показуватимуть, чи Ñ” додаток доÑтатньо кориÑним, добре напиÑаним Ñ– готовим до того, щоб його виклаÑти у загальний доÑтуп. Вони, можливо, на додачу до інших відгуків та превірки командою AMO, допоможуть визначити, чи даний додаток пора зробити публічним, чи він потребує ще Ð¾Ð¿Ñ€Ð°Ñ†ÑŽÐ²Ð°Ð½Ð½Ñ Ð´Ð¾ ширшого оглÑду, чи може він не підходить Ð´Ð»Ñ Ð¿Ñ€Ð¾ÑÑƒÐ²Ð°Ð½Ð½Ñ Ð½Ð° Ñайті AMO за межі піÑочниці взагалі.</p>
+
+<h2>Як мені опубліковати Ñвій додаток?</h2>
+
+<p>Якщо ви вірите, що ваш додаток (Ñ– ваша поведінка!) відповідають критеріÑм що виÑуваютьÑÑ Ð´Ð¾ публічних додатків, ви можете подавати його з панелі ÑƒÐ¿Ñ€Ð°Ð²Ð»Ñ–Ð½Ð½Ñ Ñ€Ð¾Ð·Ñ€Ð¾Ð±Ð½Ð¸ÐºÐ°.</p>
+
+<h2>Які Ñ” інші критерії Ð´Ð»Ñ Ð¿ÑƒÐ±Ð»Ñ–Ñ‡Ð½Ð¸Ñ… додатків?</h2>
+
+<p>Додаток, щоб Ñтати публічним на AMO, повинен бути виÑокоÑкіÑним: покращувати кориÑтувачам роботу в мережі. Ми зважаємо на наÑтупні речі при вірішенні, чи додаток відповідає публічній Ñтороні AMO:</p>
+
+<h3>Чи ви відповідальні?</h3>
+
+<p>Ми очікуємо, що автор, Ñкий проÑуває Ñвій додаток Ð´Ð»Ñ Ð±Ð°Ð³Ð°Ñ‚ÑŒÐ¾Ñ… кориÑтувачів Firefox’у, Ñ” відповідальним щодо звітів з проблем, підтримує Ñвою контактну інформацію актуальною, та оновлює Ñвій додаток відповідно до правил ÐМО щодо випуÑків та змін Firefox. Це не означає, що ви повинні відповідати на кожне запитаннÑ, Ñке хтоÑÑŒ надÑилає у диÑкуÑÑ–ÑÑ…, або навіть що вам потрібно виправлÑти кожну ваду, але ми Ñправді очікуємо, що ви відповідатимете на Ð¿Ð¸Ñ‚Ð°Ð½Ð½Ñ Ñ‚Ð°Ðº, Ñк вимагає Ñ—Ñ… рівень ÑерйозноÑÑ‚Ñ–.</p>
+
+<h3>Чи додаток чітко Ñ– правильно опиÑуєтьÑÑ?</h3>
+
+<p>Ð”Ð»Ñ Ð½Ð°Ñ Ð½Ð°Ð¹Ð±Ñ–Ð»ÑŒÑˆ важливо, щоб кориÑтувачі отримували те, чого вони чекають, пробуючи новий додаток. Ваш Ð¾Ð¿Ð¸Ñ Ð¿Ð¾Ð²Ð¸Ð½ÐµÐ½ детально розповідати про те, що робить додаток, Ñк кориÑтувач може кориÑтуватиÑÑ Ð¹Ð¾Ð³Ð¾ перевагами, Ñ– чого кориÑтувач повинен очікувати при його вÑтановленні. ПоÑÐ¸Ð»Ð°Ð½Ð½Ñ Ð½Ð° зовнішні документи про детальні інÑтрукції ÑприймаютьÑÑ Ñ‡ÑƒÐ´Ð¾Ð²Ð¾, але Ñам Ð¾Ð¿Ð¸Ñ Ð¿Ð¾Ð²Ð¸Ð½ÐµÐ½ охоплювати оÑнови Ñ– залишати кориÑтувачів впевненими, що вони знають, що отримують.</p>
+
+<p>Також важливо, щоб ви підтримували примітки верÑій відповідно до того, Ñк вдоÑконалюєте Ñ– змінюєте Ñвій додаток. КориÑтувачі повинні бути в змозі побачити, що нового у додатку, Ñкий вони вже, можливо, випробовували. І повинні розуміти зміни, Ñкі можуть вплинути на їхнє поточне викориÑÑ‚Ð°Ð½Ð½Ñ Ð´Ð¾Ð´Ð°Ñ‚ÐºÑƒ, Ñкий вони оновлюють. (ПрÑмо зараз кориÑтувачі не бачать приміток верÑій, коли Ñ—Ñ… питають про Ð¾Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ð²Ñередині браузера, але ми над цим працюємо. Якщо ви добре підтримуєте примітки верÑій, ваші кориÑтувачі отримуватимуть зиÑк до та піÑÐ»Ñ Ñ‚Ð¾Ð³Ð¾, Ñк завершитьÑÑ Ñ†Ñ Ñ€Ð¾Ð±Ð¾Ñ‚Ð°.)</p>
+
+<h3>Чи вÑÑ– Ð¿Ð¸Ñ‚Ð°Ð½Ð½Ñ ÐºÐ¾Ð½Ñ„Ñ–Ð´ÐµÐ½Ñ†Ñ–Ð¹Ð½Ð¾ÑÑ‚Ñ– та безпеки чітко розглÑдаютьÑÑ?</h3>
+
+<p>Це аÑпект чіткого Ñ– точного опиÑу, але наÑтільки важливий, що ми вважаємо, що він заÑлуговує на окрему згадку. Багато дуже кориÑних Ñ– добре напиÑаних додатків маніпулювали ÑкимÑÑŒ чином даними кориÑтувача, або ÑвлÑли небезпеку за неправильного викориÑтаннÑ; вони бажані на публічній чаÑтині AMO, але також повинні чітко роз’ÑÑнювати кориÑтувачам, з Ñким ризиком вони можуть ÑтикнутиÑÑ Ñ‚Ð° що можуть зробити Ð´Ð»Ñ Ð²Ð»Ð°Ñного захиÑту.</p>
+
+<h3>Чи додаток добре протеÑтовано, Ñ– чи немає в ньому очевидних або Ñерйозних дефектів?</h3>
+
+<p>Важливим критерієм під Ñ‡Ð°Ñ Ð¾Ð±Ð¼Ñ–Ñ€ÐºÐ¾Ð²ÑƒÐ²Ð°Ð½Ð½Ñ Ñ‡Ð¸ Ñтавити додаток у публічний доÑтуп Ñ” відгуки з піÑочниці. Вони показують, чи було його доÑтатньо протеÑтовано, Ñ– чи не має він Ñерйозних проблем або негативних впливів на браузер. Якщо оглÑдачі повідомлÑÑŽÑ‚ÑŒ про негаразди, такі, Ñк Ñильні проблеми з роботою, падіннÑ, чаÑÑ‚Ñ– збої через викориÑÑ‚Ð°Ð½Ð½Ñ Ñ„ÑƒÐ½ÐºÑ†Ñ–Ð¹ додатку, або наплив повідомлень у конÑоль помилок — ви повинні прийнÑти такі звіти близько до ÑерцÑ, й повторно подати Ñвій додаток лише піÑÐ»Ñ Ñ‚Ð¾Ð³Ð¾ Ñк впоралиÑÑ. Ми не очікуємо ідеальної оптимізації або повної відÑутноÑÑ‚Ñ– вад — Firefox Ñам поÑтійно вдоÑконалюєтьÑÑ â€” але ми не хочемо, щоб ви витрачали значні зуÑÐ¸Ð»Ð»Ñ Ð´Ð»Ñ Ð¼Ñ–Ð½Ñ–Ð¼Ñ–Ð·Ð°Ñ†Ñ–Ñ— маленьких негараздів Ñ– в той же Ñ‡Ð°Ñ Ð¾Ð¼Ð¸Ð½Ð°Ð»Ð¸ Ñ‚Ñ– моменти, Ñкими кориÑтувачі можуть бути неприємно здивовані.</p>
+
+<p>Якщо ваш додаток було протеÑтовано поза межами піÑочниці AMO, Ñк, наприклад, групою кориÑтувачів вашої компанії або внутрішньою командою ТК (технічного контролю), ви повинні це вказати у Ñвоєму повідомленні поданнÑ. Це неодмінно допоможе нам вÑтановити рівень проведеного теÑтуваннÑ, Ñ– може допомогти виклаÑти ваш додаток на Ñайт.</p>
+
+<h3>Чи додаток та автор додатку ÑтавлÑÑ‚ÑŒÑÑ Ð´Ð¾ кориÑтувача з повагою?</h3>
+
+<p>Ваше програмне Ð·Ð°Ð±ÐµÐ·Ð¿ÐµÑ‡ÐµÐ½Ð½Ñ Ð½Ðµ повинно втручатиÑÑ Ð±ÐµÐ· потреби до Ñправ кориÑтувача, пробувати надурити кориÑтувача, або приховувати таку діÑльніÑÑ‚ÑŒ від кориÑтувача. КориÑтувачі (або навіть не-кориÑтувачі) чаÑом бувають грубі в Ñвоїх коментарÑÑ…, Ñ– поки ми намагаємоÑÑ Ð·Ñ€Ð¾Ð±Ð¸Ñ‚Ð¸ вÑе можливе Ð´Ð»Ñ Ð²Ñ–Ð´Ñ„Ñ–Ð»ÑŒÑ‚Ñ€Ð¾Ð²ÑƒÐ²Ð°Ð½Ð½Ñ Ñ‚Ð¸Ñ… хто нам не допомагає, ми дійÑно очікуємо, що автори уникатимуть відповідати їм Ñвоєю грубіÑÑ‚ÑŽ.</p>
+
+<h3>Чи додаток кориÑний доÑтатньо широкому загалу кориÑтувачів Firefox’а?</h3>
+
+<p>Ваш додаток не зобов’Ñзаний Ñтати наÑтупним Greasemonkey або FireBug, але Ñкщо він кориÑний лише людÑм вашої компанії або чаÑтині малої мережевої Ñпільноти, ми можемо відчути, що ще не Ñ‡Ð°Ñ Ð²Ð¸ÐºÐ»Ð°Ð´Ð°Ñ‚Ð¸ його перед уÑіма кориÑтувачами Firefox’у.</p>
+
+<p>Ми поÑтійно шукаємо шлÑхів вдоÑÐºÐ¾Ð½Ð°Ð»ÐµÐ½Ð½Ñ Ð¾Ñ€Ð³Ð°Ð½Ñ–Ð·Ð°Ñ†Ñ–Ñ— Ñайту Ð´Ð»Ñ ÐºÑ€Ð°Ñ‰Ð¾Ð³Ð¾ Ð¾Ñ‚Ñ€Ð¸Ð¼Ð°Ð½Ð½Ñ Ð´Ð¾Ð´Ð°Ñ‚ÐºÑ–Ð², котрі певним чином кориÑні, але націлені на лише малу Ñпільноту потенційних кориÑтувачів. Правильний вибір категорії та підтримка метаданих вашого додатку допоможе нам зрозуміти, Ñк ми можемо виклаÑти на поверхню більшу кількіÑÑ‚ÑŒ такого типу додатків людÑм, Ñкі б найшвидше отримали з них кориÑÑ‚ÑŒ.</p>
+
+<p>Якщо ваш додаток надає лише закладку або інші Ñпрощені шлÑхи доÑтупу до вашого Ñайту, можливо, це не підходить Ð´Ð»Ñ Ð¿ÑƒÐ±Ð»Ñ–Ñ‡Ð½Ð¾Ñ— чаÑтини нашого Ñайту. Як Ñ– решта проекту Mozilla, ми любимо мережеві зручноÑÑ‚Ñ– та нові поÑлуги, але додатки Firefox повинні покращувати Ð¶Ð¸Ñ‚Ñ‚Ñ Ð² інтернеті, а не бути проÑто ÑпоÑобом проÑÑƒÐ²Ð°Ð½Ð½Ñ Ð½Ð¾Ð²Ð¾Ð³Ð¾ Ñайту або ÑервіÑу за допомогою переліку AMO. Якщо Ð¾Ð¿Ð¸Ñ Ð²Ð°ÑˆÐ¾Ð³Ð¾ додатка радше про ÑервіÑ, ніж про вдоÑÐºÐ¾Ð½Ð°Ð»ÐµÐ½Ð½Ñ Ñ€Ð¾Ð±Ð¾Ñ‚Ð¸ браузера в мережі, то, можливо, ви не туди потрапили.</p>
+
+<h3>Чи не міÑтить додаток неліцензованих торгових марок, чи не порушує він чиїÑÑŒ права?</h3>
+
+<p>Хоча ви можете не мати наміру вчинити шкоду влаÑнику торгової марки, або влаÑнику авторÑької роботи, ми не можемо тримати додатки, Ñкі порушують торгові марки або права. Якщо у Ð²Ð°Ñ Ð½ÐµÐ¼Ð°Ñ” дозволу на викориÑÑ‚Ð°Ð½Ð½Ñ Ñ–Ð¼ÐµÐ½Ñ– торгової марки або зображеннÑ, будь лаÑка, не подавайте ваш додаток до AMO. Якщо ваш додаток включає код, Ñкий заÑтережено кимÑÑŒ іншим, Ñ– не ліцензовано вам на викориÑÑ‚Ð°Ð½Ð½Ñ Ñƒ додатку, будь лаÑка, не подавайте ваш додаток до AMO. (Якщо влаÑник торгової марки або об’єктів, заÑтережених правами, протеÑтуватиме проти Ð´Ð»Ñ Ð²Ð¸ÐºÐ¾Ñ€Ð¸ÑÑ‚Ð°Ð½Ð½Ñ Ð¹Ð¾Ð³Ð¾ торгової марки, ваш запит буде розглÑдатиÑÑŒ комітетом. Якщо буде необхідно за законом, ми вилучимо ваш додаток. Це дорогий Ð¿Ñ€Ð¾Ñ†ÐµÑ Ñƒ термінах реÑурÑів проекту, включно по чаÑу Ñ– грошам, тому ми проÑимо Ð²Ð°Ñ Ð±ÑƒÑ‚Ð¸ ввічливими Ñ– не Ñтворювати непотрібні Ñкладнощі.)</p>
+
+<p>Якщо ви непевні, чи назва вашого додатку або викориÑÑ‚Ð°Ð½Ð½Ñ Ñ‡Ð¾Ð³Ð¾ÑÑŒ у ньому не дозволить його поÑтавити на Ñайт, ви можете звернутиÑÑŒ до amo-editors@mozilla.org по допомогу. Ð’ÐЖЛИВО: будь лаÑка, зауважте, що Ñ†Ñ Ð³Ñ€ÑƒÐ¿Ð° не може надавати юридичні поради, Ñ– навіть Ñкщо б ми відчували, що ваше викориÑÑ‚Ð°Ð½Ð½Ñ Ð¿Ñ€Ð¸Ð¹Ð½Ñтне, ми можемо переглÑнути таке Ñ€Ñ–ÑˆÐµÐ½Ð½Ñ Ñƒ Ñвітлі Ñкарг від правовлаÑників Ñ– порад від юридичних радників.</p>
+
+<p>У термінах повторного викориÑÑ‚Ð°Ð½Ð½Ñ ÐºÐ¾Ð´Ñƒ інших додатків, Ñкщо автор чітко не зазначив, що вам дозволено викориÑтовувати його код у влаÑній роботі — ліцензувавши його під ліцензію відкритого коду — тоді ви повинні припуÑкати, що у Ð²Ð°Ñ Ð½ÐµÐ¼Ð°Ñ” на це права. Ви можете ÑконтактуватиÑÑ Ð· автором Ð´Ð»Ñ Ð¾Ñ‚Ñ€Ð¸Ð¼Ð°Ð½Ð½Ñ Ñ‚Ð°ÐºÐ¾Ð³Ð¾ дозволу, але повторюємо: ніÑких додаткових прав через те що «додаток вже був на ÐМО» чи тому, що автор не відповідає на ваш запит у Ð²Ð°Ñ Ð½Ðµ з’ÑвлÑєтьÑÑ. (І, знову, ми не можемо надавати юридичні поради, лише поради щодо того, Ñк ваш додаток повинен взаємодіÑти з правилами Ñайту.)</p>
+
+<p>Це ÑтоÑуєтьÑÑ Ñ‚Ð¾Ñ€Ð³Ð¾Ð²Ð¸Ñ… марок Фонду Mozilla, включно з «Mozilla», «Firefox», та «Thunderbird». Політика Mozilla щодо викориÑÑ‚Ð°Ð½Ð½Ñ Ñ‚Ð¾Ñ€Ð³Ð¾Ð²Ð¸Ñ… марок призначена Ð´Ð»Ñ Ð·Ð°Ñ…Ð¸Ñту від непорозумінь та Ð´Ð»Ñ Ð·Ð°Ð¿Ð¾Ð±Ñ–Ð³Ð°Ð½Ð½Ñ Ð¿ÐµÑ€ÐµÐºÑ€ÑƒÑ‡ÐµÐ½Ð½ÑŽ торгових марок через брак захиÑту; будь лаÑка, поважайте потребу такого захиÑту Ñ– допомагайте нам зберігати деÑкі з найцінніших влаÑноÑтей фонду Mozilla.</p>
+
+<h2>Що відбуваєтьÑÑ Ð¿Ñ–ÑÐ»Ñ Ñ‚Ð¾Ð³Ð¾, Ñк Ñ Ð¿Ð¾Ð´Ð°ÑŽ додаток?</h2>
+
+<p>Коли ваш додаток подано, його оцінює команда редакторів AMO відповідно до вищеопиÑаних критеріїв. Якщо його визнано готовим до публічного показу, його виÑтавлÑÑ‚ÑŒ у загальний доÑтуп, Ñ– ви отримаєте Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ ÐµÐ»ÐµÐºÑ‚Ñ€Ð¾Ð½Ð½Ð¾ÑŽ поштою.</p>
+
+<p>Якщо ми відчуємо, що додаток ще не годитьÑÑ Ð´Ð»Ñ Ð¿ÑƒÐ±Ð»Ñ–Ñ‡Ð½Ð¾Ñ— Ñторони AMO, ви отримаєте Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ ÐµÐ»ÐµÐºÑ‚Ñ€Ð¾Ð½Ð½Ð¾ÑŽ поштою з поÑÑненнÑм чому, а ваше Ð¿Ð¾Ð´Ð°Ð½Ð½Ñ Ð±ÑƒÐ´Ðµ вилучено з черги. Якщо Ñ– коли ви відчуєте, що ви виправили недоліки, зазначені у повідомленні, Ñ– хочете щоб знову це оцінили, ви можете надіÑлати запит ще раз. Повторювані заÑвки без значних вдоÑконалень у додатку ÑпоглÑдаютьÑÑ Ð½ÐµÑхвально. Тому, будь лаÑка, робіть перерви; ви швидше можете Ð½Ð°Ñ Ñ€Ð¾Ð·Ñердити, ніж подолати.</p>
+
+<h2>Чи можу Ñ Ð¿Ð¾Ð´Ð°Ð²Ð°Ñ‚Ð¸ додаток когоÑÑŒ іншого?</h2>
+
+<p>Ðаразі ми проÑимо, щоб автори додатків Ñамі подавали влаÑну роботу на публікацію. Ми хочемо переконатиÑÑ, що автор почуваєтьÑÑ Ð·Ñ€ÑƒÑ‡Ð½Ð¾ з збільшеною публічніÑÑ‚ÑŽ, Ñ– що він відчуває, що додаток у поточному Ñтані відповідно показує ÑкіÑÑ‚ÑŒ його роботи. Якщо ви вірите, що додаток відполіровано, що автор вірний букві Ñ– духу політик AMO, Ñ– що Firefox, наші кориÑтувачі та мережа загалом від того тільки виграють, коли майже мільйон чоловік у вÑьому Ñвіті отримають доÑтуп до додатку, обов’Ñзково підбадьорте автора до Ð¿Ð¾Ð´Ð°Ð½Ð½Ñ Ñвого твору.</p>
+
+<h2>Мій додаток вже довгий Ñ‡Ð°Ñ Ñƒ черзі поданнÑ, чи ви мене ненавидите?</h2>
+
+<p>Ми не ненавидимо ваÑ. Ми любимо розробників додатків, Ñ– важко працюємо, щоб зробити Ñ—Ñ… щаÑливими Ñ– продуктивними, щоб кориÑтувачі уÑього Ñвіту могли отримувати кориÑÑ‚ÑŒ від їхньої роботи. Ðле Ð¿ÐµÑ€ÐµÐ±ÑƒÐ²Ð°Ð½Ð½Ñ Ð½Ð° публічній Ñтороні AMO має цінніÑÑ‚ÑŒ Ñаме завдÑки тому, що ми турбуємоÑÑŒ про те, що туди надходить, тому ми не можемо поÑпішати лише щоб приÑкорити процеÑ. Ми розуміємо, що Ñ‡ÐµÐºÐ°Ð½Ð½Ñ Ð½Ð° оцінку вашого додатку може заÑмучувати, Ñ– ми ÑтараємоÑÑŒ робити оглÑди Ñкнайшвидше. Що більше людей надають виважені та чіткі переглÑди додатків у піÑочниці, то проÑтіше Ñ—Ñ… оцінювати. Тому ви можете допомогти нам в цьому, Ñкщо така ваша лаÑка.</p>
+
+<h2>Я знайшов Ñерйозну ваду у Ñвоєму додатку, Ñ– Ñ Ñправді хочу його швидко виправити. Що мені потрібно зробити?</h2>
+
+<p>Якщо Ñ” Ñерйозна вада (безпеки, ÑтабільноÑÑ‚Ñ–, велика проблема з функціональніÑÑ‚ÑŽ) у додатку, через Ñку ви хочете негайно зробити оновленнÑ, ви так Ñ– повинні зазначити у «примітках Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÐ³Ð»Ñдача» при поданні Ð¾Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ â€” Ñк, певно ж, Ñ– у примітках верÑÑ–Ñ—! Ви також можете Ñпробувати доручити кориÑтувачам вашого додатку потеÑтити його та відпиÑати результати в піÑочницю. Ð”Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð½Ñ Ð´Ð¾ каналу #addons на irc.mozilla.org може допомогти людÑм бути в курÑÑ– Ñитуації, але будь лаÑка, будьте терплÑчі Ñ– ввічливі в таких випадках.</p>
+
+<p>Будь лаÑка, не кричить «вовки!» без потреби. Ми намагаємоÑÑ ÑˆÐ²Ð¸Ð´ÐºÐ¾ пропуÑкати виÑокоприорітетні оновленнÑ, проте переглÑÐ´Ð°Ð½Ð½Ñ Ñ–Ð½ÑˆÐ¸Ñ… оновлень та верÑій забирає наші Ñили, Ñ– чаÑто коштує нам Ñну або чаÑу з Ñім’Ñми та друзÑми. Тому ми не дуже любимо людей людей, Ñкі хочуть ÑкориÑтуватиÑÑ Ñ†Ð¸Ð¼ механізмом, щоб «проÑкочити чергу». Якщо ви непевні, чи варто йти цим шлÑхом, запитайтеÑÑ Ñƒ #addons на irc.mozilla.org, там вам можуть допомогти вирішити.</p>
+
+<h2>Я думаю, що до мене нечеÑно віднеÑлиÑÑ Ð¿Ñ€Ð¸ оцінці мого додатку. Що Ñ Ð¿Ð¾Ð²Ð¸Ð½ÐµÐ½ робити?</h2>
+
+<p>Якщо ви вірите, що ваш додаток був невірно оцінений, Ñ– йому не надали публічного ÑтатуÑу помилково, вам потрібно надіÑлати лиÑта на amo-editors@mozilla.org з детальним обґрунтуваннÑм. Будь лаÑка, будьте ввічливими Ñ– чіткими у Ñвоєму лиÑÑ‚Ñ–, Ñ– переконайтеÑÑ, що надаєте подробиці того, Ñк додаток був недооцінений.</p>
+
+<p>(Якщо ви виправили *вÑÑ–* речі, Ñкі були зазначені Ñк проблеми у повідомленні, вам не треба апелювати на оцінку, але, натоміÑÑ‚ÑŒ, Ñлід проÑто подати новий варіант за допомогою панелі ÐºÐµÑ€ÑƒÐ²Ð°Ð½Ð½Ñ Ñ€Ð¾Ð·Ñ€Ð¾Ð±Ð½Ð¸ÐºÐ°.)</p>
+
+<h2>Мій додаток був публічним, а зараз він лише у піÑочниці. Що ÑталоÑÑ? </h2>
+
+<p>Якщо додаток більше не задовольнÑÑ” критеріÑм Ð¿ÐµÑ€ÐµÐ±ÑƒÐ²Ð°Ð½Ð½Ñ Ð½Ð° публічній Ñтороні Ñайту, ми можемо переміÑтити його назад до піÑочниці. Якщо нам юридично не заборонÑÑ‚ÑŒ цього зробити, ми повідомимо вам про це електронною поштою, Ñ– зазначимо причини таких дій.</p>
+
+<p>Також можливо, що ви найшли ваду у Ñайті, в такому випадку прозвітуйте за допомогою Bugzilla; викориÑтовуйте продукт «addons.mozilla.org» та компоненту «Публічні Ñторінки» Ð´Ð»Ñ Ñвого звіту Ñ– надайте Ñкнайбільше подробиць.</p>
+
+<h2>Мій додаток публічний, Ñ–, здаєтьÑÑ, люди його люблÑÑ‚ÑŒ. Як Ñ Ð¼Ð¾Ð¶Ñƒ попаÑти у перелік рекомендованих додатків?</h2>
+
+<p>Якщо ви вважаєте, що ваш додаток Ñ” блиÑкучим прикладом могутноÑÑ‚Ñ– додатків, що він демонÑтрує Ñ– розширює цінноÑÑ‚Ñ– Mozilla Ð´Ð»Ñ Ð¼ÐµÑ€ÐµÐ¶Ñ–, розширюваної Ñ– контрольованої кориÑтувачем, Ñ– що він дає кориÑтувачу нову функціональніÑÑ‚ÑŒ, можете попроÑити про те, щоб розглÑнули можливіÑÑ‚ÑŒ внеÑÐµÐ½Ð½Ñ Ð¹Ð¾Ð³Ð¾ до переліку рекомендованих додатків. Щоб зробити це, ви повинні надіÑлати лиÑта на amo-editors@mozilla.org з поÑÑненнÑм про те, чому ваш додаток чудовий.</p>
+
+<p>Ваш лиÑÑ‚ повинен включати <b>принаймні</b> інформацію про такі речі:</p>
+<ul>
+<li>Ñк покращуєтьÑÑ Ð¶Ð¸Ñ‚Ñ‚Ñ ÐºÐ¾Ñ€Ð¸Ñтувачів в мережі</li>
+<li>Ñким чином ваш додаток підходить великій чаÑтині кориÑтувачів Firefox’у</li>
+<li>Ñк ваш додаток демонÑтрує та/або Ñлужить цінноÑÑ‚Ñм проекту Mozilla, оÑобливо з поглÑду Ð½Ð°Ð´Ð°Ð½Ð½Ñ Ð¿Ð¾Ð²Ð½Ð¾Ð²Ð°Ð¶ÐµÐ½ÑŒ кориÑтувачу, захиÑту конфіденційноÑÑ‚Ñ– та безпеки, універÑальному доÑтупу до мережі, та відкритим Ñтандартам Ñ– даним</li>
+<li>Ñк ваш додаток відрізнÑєтьÑÑ Ð²Ñ–Ð´ інших Ñхожих додатків ( чим гірший, чим кращий)</li>
+<li>Ñку реакцію ви бачили від кориÑтувачів, переглÑдачів, блоґґерів, коÑмонавтів ваших домашніх тварин. Як Ñ– позитивну, так Ñ– негативну</li>
+</ul>
+
+<p>Що повнішу інформацію ви надаÑте у Ñвоєму запиті, то більше шанÑів буде на те, що ми включимо додаток у перелік рекомендованих. Хоча навіть чудово напиÑаний Ñ– вичерпний Ð¾Ð¿Ð¸Ñ Ð½Ðµ дає на це гарантії. Зрештою, цей перелік повинен — Ñ– Ñ” — підтримуватиÑÑŒ на розÑуд Mozilla Ñ– турбота про кориÑтувачів має переважувати інші міркуваннÑ.</p>
diff --git a/site/app/locale/uk/pages/sandbox.thtml b/site/app/locale/uk/pages/sandbox.thtml
new file mode 100644
index 0000000..000fa25
--- /dev/null
+++ b/site/app/locale/uk/pages/sandbox.thtml
@@ -0,0 +1,13 @@
+<h1>Перевірка у піÑочниці</h1>
+<h2>Що таке піÑочницÑ?</h2>
+<p>ПіÑÐ¾Ñ‡Ð½Ð¸Ñ†Ñ Ñ” міÑцем, де передові кориÑтувачі можуть випробувати додатки до того, Ñк Ñ—Ñ… випуÑÑ‚ÑÑ‚ÑŒ у загальне кориÑтуваннÑ. Щоб отримати доÑтуп до піÑочниці, ви повинні включити Ñ—Ñ— у Ñвоїх налаштуваннÑÑ…. Обережно вÑтановлюйте додатки з піÑочниці, оÑкільки Ñ—Ñ… ще не перевірив редактор Ñ– вони можуть зашкодити вашому комп’ютеру.</p>
+
+<h2>Як Ñ Ð¼Ð¾Ð¶Ñƒ поміÑтити Ñвій додаток на публічний Ñайт?</h2>
+<!-- To localize the flowchart image, see http://wiki.mozilla.org/Update:Remora_Sandbox_Flowchart -->
+<div style="text-align: center;">%s</div>
+<ol>
+ <li><b>Відвантажте Ñвій додаток через Панель ÐºÐµÑ€ÑƒÐ²Ð°Ð½Ð½Ñ Ñ€Ð¾Ð·Ñ€Ð¾Ð±Ð½Ð¸ÐºÐ°.</b> Він одразу з’ÑвитьÑÑ Ñƒ ПіÑочниці Додатків Mozilla, де доÑвідчені кориÑтувачі будуть випробовувати його Ñ– надаватимуть зворотній зв’Ñзок. Ð”Ð»Ñ Ñ‚Ð¾Ð³Ð¾ щоб побачити піÑочницю, потрібно увімкнути Ñ—Ñ— в Ñвоїх Ð½Ð°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ñ€Ð°Ñ…ÑƒÐ½ÐºÑƒ.</li>
+ <li><b>Подайте запит на публікацію.</b> У Панелі ÐºÐµÑ€ÑƒÐ²Ð°Ð½Ð½Ñ Ñ€Ð¾Ð·Ñ€Ð¾Ð±Ð½Ð¸ÐºÐ° Ñ” поÑÐ¸Ð»Ð°Ð½Ð½Ñ Ð½Ð° Ð¿Ð¾Ð´Ð°Ð½Ð½Ñ Ñвого додатка. ПіÑÐ»Ñ Ñ†ÑŒÐ¾Ð³Ð¾ він з’ÑвитьÑÑ Ñƒ редакторÑькій черзі переглÑду.</li>
+ <li><b>Редактор переглÑне ваш додаток.</b> Редактор додатків Mozilla вÑтановить ваш додаток Ñ– випробує його роботу. Редактор також зважить на відгуки випробувачів з піÑочниці.</li>
+ <li><b>Ваш додаток Ñтає публічним або залишаєтьÑÑ Ñƒ піÑочниці.</b> Редактор або робить ваш додаток публічним, або залишає його у піÑочниці. Якщо додаток залишаєтьÑÑ Ñƒ піÑочниці, ви можете знову його подати піÑÐ»Ñ Ð²Ð¸Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð½Ñ Ð·Ð¼Ñ–Ð½, Ñкі запропонує редактор у коментарÑÑ…. Якщо він Ñтає публічним, майбутні верÑÑ–Ñ— вашого додатку з’ÑвлÑтимутьÑÑ Ñƒ піÑочниці до того чаÑу, доки Ñ—Ñ… не оглÑне редактор Ñ– не зробить публічними. Коли ваш додаток Ñтає публічним, немає потреби знову його подавати — майбутні верÑÑ–Ñ— автоматично переходитимуть у чергу Ð¾Ñ‡Ñ–ÐºÑƒÐ²Ð°Ð½Ð½Ñ Ð½Ð° оглÑд.</li>
+</ol>
diff --git a/site/app/locale/uk/pages/submission_help.thtml b/site/app/locale/uk/pages/submission_help.thtml
new file mode 100644
index 0000000..cbcebc5
--- /dev/null
+++ b/site/app/locale/uk/pages/submission_help.thtml
@@ -0,0 +1,37 @@
+<h1>Підказка з подаваннÑ</h1>
+Обов’Ñзкові Ð¿Ð¾Ð»Ñ Ð²Ð¸Ð´Ñ–Ð»ÐµÐ½Ñ– <b>жирним</b>. Ðеобов’Ñзкові Ð¿Ð¾Ð»Ñ Ð²Ð¸Ð´Ñ–Ð»ÐµÐ½Ñ– <i>курÑивом</i>.
+<h2 id="step1">Крок 1: ВідвантаженнÑ</h2>
+<ul class="submissionHelp">
+ <li><span class="required">Тип додатку</span> — зазвичай тип додатку автоматично визначаєтьÑÑ Ð· відвантаженого файла. Ви не зобов’Ñзані змінювати це поле.</li>
+ <li><span class="required">Файл додатку</span> — пакетний файл вашого додатку що міÑтить файл install.rdf. Якщо файл працює тільки з окремою платформою, вибір такої платформи дозволить відвантажити багато файлів за один раз.</li>
+ <li><span class="optional">Файл значка</span> — значок показуєтьÑÑ Ð¿Ð¾Ñ€Ñд із назвою додатку на його Ñторінці та у діалозі вÑÑ‚Ð°Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ð´Ð¾Ð´Ð°Ñ‚ÐºÑƒ. Його розміри автоматично будуть змінені на 32x32 пікÑелі, зберігаючи ÑÐ¿Ñ–Ð²Ð²Ñ–Ð´Ð½Ð¾ÑˆÐµÐ½Ð½Ñ Ñторін.</li>
+ <li><span class="required">Типова мова</span> — типова мова додатку буде його оÑновною мовою. Якщо Ð´Ð»Ñ Ð´Ð¾Ð´Ð°Ñ‚ÐºÑƒ недоÑтупна мова обрана кориÑтувачем, то буде викориÑтана типова.</li>
+ <li><span class="optional">ПропуÑтити переглÑд інформації цього додатку</span> — Ñкщо ви оновлюєте Ñ–Ñнуючий додаток, з’ÑвитьÑÑ Ñ†Ðµ поле. Ð’Ð¸Ð´Ñ–Ð»ÐµÐ½Ð½Ñ Ð¿Ñ€Ð°Ð¿Ð¾Ñ€Ñ†Ñ Ð¿ÐµÑ€ÐµÐ¼Ñ–Ñтить Ð²Ð°Ñ Ð´Ð¾ кроку 3, де можна буде ввеÑти інформацію про верÑÑ–ÑŽ.</li>
+</ul>
+
+<h2 id="step2">Крок 2: Подробиці додатку</h2>
+<ul class="submissionHelp">
+ <li><span class="required">Ðазва</span> — назва додатку типовою мовою.</li>
+ <li><span class="required">Ðвтори</span> — вÑÑ– кориÑтувачі, Ñкі можуть змінювати інформацію додатка Ñ– будуть перелічені Ñк автори на його Ñторінці.</li>
+ <li><span class="required">Категорії</span> — категорії, заÑтоÑовувані до додатку.</li>
+ <li><span class="optional">Ð”Ð¾Ð¼Ð°ÑˆÐ½Ñ Ñторінка</span> — вебÑайт додатку типовою мовою.</li>
+ <li><span class="required">ПідÑумок</span> — короткий підÑумок додатку типовою мовою. МакÑимум 250 Ñимволів. Цей текÑÑ‚ з’ÑвлÑтиметьÑÑ Ð½Ð° Ñторінці показу додатка, а також у результатах пошуку/оглÑду.</li>
+ <li><span class="required">ОпиÑ</span> — Ð¾Ð¿Ð¸Ñ Ð´Ð¾Ð´Ð°Ñ‚ÐºÑƒ типовою мовою. З’ÑвлÑтиметьÑÑ Ð½Ð° Ñторінці показу додатка під підÑумком.</li>
+ <li><span class="optional">ЛУКК</span> — Ліцензійна угода з кінцевим кориÑтувачем, Ñку кориÑтувачі повинні прийнÑти перед завантаженнÑм. Типовою мовою.</li>
+ <li><span class="optional">Умови конфіденційноÑÑ‚Ñ–</span> — умови конфіденційноÑÑ‚Ñ– додатка типовою мовою. Умови конфіденційноÑÑ‚Ñ– поÑÑнюють, що робитьÑÑ Ð· оÑобиÑтою інформацією кінцевого кориÑтувача. ПоÑÐ¸Ð»Ð°Ð½Ð½Ñ Ð½Ð° умови конфіденційноÑÑ‚Ñ– з’ÑвитьÑÑ Ð±Ñ–Ð»Ñ ÐºÐ½Ð¾Ð¿ÐºÐ¸ вÑÑ‚Ð°Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ð½Ð° Ñторінці додатка. Додаткова Ñ–Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ñ–Ñ ÑтоÑовно того, що повинно включатиÑÑ Ð² умови кофіденційноÑÑ‚Ñ– Ñ– чи ваш додаток Ñ—Ñ— потребує, доÑтупна у <a href="%s">Правилах Додатків</a>.</li>
+ <li><span class="optional">Дозволити кориÑтувачам переглÑдати джерела файлів в мережі</span> — кориÑтувачі зможуть читати початковий код вашого додатку.</li>
+ <li><span class="optional">Попередній випуÑк</span> — додаток Ñ” попереднім випуÑком або «бета»-верÑією. Додатки попереднього випуÑку повинні залишатиÑÑ Ñƒ піÑочниці Ñ– не можуть подаватиÑÑ Ð½Ð° публікацію, доки цей прапорець не буде знÑто.</li>
+ <li><span class="optional">Додаток Ð´Ð»Ñ Ð¾ÐºÑ€ÐµÐ¼Ð¾Ð³Ð¾ Ñайту</span> — додаток призначено Ð´Ð»Ñ Ð¿ÐµÐ²Ð½Ð¾Ð³Ð¾ вебÑайту. Скажімо, додаток змінює його зміÑÑ‚ чи виглÑд. Ðбо призначений Ð´Ð»Ñ Ð¾Ñ‚Ñ€Ð¸Ð¼Ð°Ð½Ð½Ñ Ð·Ð²Ñ–Ð´Ñ‚Ð¸ інформації.
+Це поле допомагає редакторам Ñ– у майбутньому може викориÑтовуватиÑÑ Ð´Ð»Ñ Ñ„Ñ–Ð»ÑŒÑ‚Ñ€ÑƒÐ²Ð°Ð½Ð½Ñ Ð¿Ð¾ÑˆÑƒÐºÑƒ.</li>
+ <li><span class="optional">Додаток потребує зовнішнього програмного забезпеченнÑ</span> — додаток потребує зовнішніх програм або бібліотек.
+Це поле допомагає редакторам Ñ– у майбутньому може викориÑтовуватиÑÑ Ð´Ð»Ñ Ñ„Ñ–Ð»ÑŒÑ‚Ñ€ÑƒÐ²Ð°Ð½Ð½Ñ Ð¿Ð¾ÑˆÑƒÐºÑƒ.</li>
+</ul>
+
+<h2 id="step3">Крок 3: Подробиці верÑÑ–Ñ—</h2>
+<ul class="submissionHelp">
+ <li><span class="required optional">Примітки до верÑÑ–Ñ—</span> — підÑумок або перелік змін у цій верÑÑ–Ñ—. Це необов’Ñзково Ð´Ð»Ñ Ð½Ð¾Ð²Ð¸Ñ… подань, але потрібно Ð´Ð»Ñ Ð¾Ð½Ð¾Ð²Ð»ÐµÐ½ÑŒ.</li>
+ <li><span class="optional">Примітки Ð´Ð»Ñ Ð¾Ð³Ð»Ñдача</span> — це поле викориÑтовуєтьÑÑ Ð´Ð»Ñ Ð½Ð°Ð´Ð°Ð½Ð½Ñ Ñ–Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ñ–Ñ— редакторам, Ñкі переглÑдатимуть ваш додаток. Тут Ñлід вказати дані про теÑтовий доÑтуп (Ñкщо потрібен) та інші оÑобливі примітки.</li>
+</ul>
+
+<h2 id="step4">Крок 4: Переклади</h2>
+Тут Ð¿Ð¾Ð»Ñ Ð´Ð¾Ð´Ð°Ñ‚ÐºÑƒ можуть перекладатиÑÑ Ð²Ñіма підтримуваними мовами. ПроÑто клацніть на мові, щоб почати перекладати.
diff --git a/site/app/locale/vi/LC_MESSAGES/messages.mo b/site/app/locale/vi/LC_MESSAGES/messages.mo
new file mode 100644
index 0000000..e16f270
--- /dev/null
+++ b/site/app/locale/vi/LC_MESSAGES/messages.mo
Binary files differ
diff --git a/site/app/locale/vi/LC_MESSAGES/messages.po b/site/app/locale/vi/LC_MESSAGES/messages.po
new file mode 100644
index 0000000..c38e99b
--- /dev/null
+++ b/site/app/locale/vi/LC_MESSAGES/messages.po
@@ -0,0 +1,7520 @@
+msgid ""
+msgstr ""
+"Project-Id-Version: addons.mozilla.org\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2009-01-16 11:45-0800\n"
+"PO-Revision-Date: 2009-06-08 01:40+0700\n"
+"Last-Translator: Hung. NGUYEN Manh <loveleeyoungae@yahoo.com>\n"
+"Language-Team: Vietnamese <LL@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=n != 1;\n"
+"X-Generator: Narro 0.9.2 on https://l10n.mozilla.org/narro\n"
+
+#: views/addons/policy.thtml:98
+msgid "a_cancel_installation"
+msgstr "Hủy bỠCài đặt"
+
+#. This is the text that appears on buttons to download add-ons.
+#. %$1s is an optional string that only appears if the add-on is only available for
+#. a certain platform. Examples: (Windows) or (Linux)
+#. Note that the parentheses are included in the string. :(
+#: views/elements/amo2009/install.thtml:126
+#: views/elements/amo2009/install.thtml:227
+#: views/elements/amo2009/install.thtml:257
+#: views/elements/amo2009/install.thtml:300
+#: views/elements/amo2009/install.thtml:312
+#: views/elements/install.thtml:73
+#: views/elements/install.thtml:181
+#: views/elements/install.thtml:205
+#: views/elements/install.thtml:248
+#: views/elements/install.thtml:260
+#: views/addons/plugins.thtml:66
+#: views/addons/plugins.thtml:76
+#: views/addons/plugins.thtml:86
+#: views/addons/plugins.thtml:96
+#: views/addons/plugins.thtml:119
+#, php-format
+msgid "a_download"
+msgstr "Tải Ngay %s"
+
+#: views/addons/policy.thtml:72
+msgid "a_eula_download"
+msgstr "Chấp thuận và Tải xuống"
+
+#: views/addons/policy.thtml:74
+msgid "a_eula_install"
+msgstr "Chấp thuận và Cài đặt"
+
+#: views/elements/header.thtml:76
+#: views/elements/header.thtml:82
+#: views/api/api_addon.thtml:55
+#: views/api/collections_feed.thtml:75
+#: views/sharing_api/addon.thtml:64
+msgid "a_header_public"
+msgstr "Công cộng"
+
+#: views/elements/header.thtml:58
+#: views/elements/header.thtml:75
+#: views/elements/header.thtml:80
+#: views/api/api_addon.thtml:57
+#: views/api/collections_feed.thtml:77
+#: views/sharing_api/addon.thtml:66
+msgid "a_header_sandbox"
+msgstr "Hộp cát"
+
+#. %s is a date in the _('date') format
+#: views/elements/amo2009/homepage_addon.thtml:115
+#: views/elements/addon_listitem.thtml:122
+#: views/elements/feature.thtml:106
+#: views/addons/display.thtml:104
+#: views/addons/browse_thumbs.thtml:73
+msgid "addon_detail_last_updated"
+msgstr "Cập nhật %s"
+
+#. %s is the version of the add-on. Example: 3.2a1
+#: views/elements/amo2009/addon_version_detail.thtml:51
+#: views/elements/addon_version_detail.thtml:51
+#, php-format
+msgid "addon_display_header_version"
+msgstr "Phiên bản %s"
+
+#: views/addons/browse_thumbs.thtml:80
+msgid "addon_downloads"
+msgstr "số lượt tải"
+
+#: views/addons/display.thtml:147
+msgid "addon_downloads_total"
+msgstr "tổng số lượt tải"
+
+#: views/elements/amo2009/homepage_addon.thtml:106
+#: views/elements/addon_listitem.thtml:115
+#: views/elements/feature.thtml:101
+#: views/addons/category_landing.thtml:157
+#: views/addons/display.thtml:146
+#: views/addons/browse_thumbs.thtml:80
+msgid "addon_downloads_weekly"
+msgstr "lượt tải hàng tuần"
+
+#. %1 is the add-on count, %2 the category name
+#: views/addons/browse_thumbs.thtml:104
+#: views/addons/browse.thtml:60
+#, php-format
+msgid "addon_list_category_totalcount"
+msgid_plural "addon_list_category_totalcount"
+msgstr[0] "%1$s tiện ích"
+msgstr[1] "%1$s tiện ích"
+
+#: views/elements/amo2009/addon_list_options.thtml:103
+#: views/elements/pagination.thtml:67
+#: views/elements/addon_list_options.thtml:94
+msgid "addon_list_perpage"
+msgstr "má»—i trang"
+
+#: views/elements/amo2009/addon_list_options.thtml:84
+#: views/elements/addon_list_options.thtml:98
+msgid "addon_list_sortby"
+msgstr "Sắp xếp theo:"
+
+#: views/helpers/addons_html.php:568
+#: views/elements/amo2009/install.thtml:321
+#: views/elements/feature.thtml:89
+msgid "addon_listitem_flag_experimental"
+msgstr "thử nghiệm"
+
+#: views/helpers/addons_html.php:570
+msgid "addon_listitem_flag_recommended"
+msgstr "khuyên dùng"
+
+#. %1 is the add-on name, %2 is the platform
+#: views/pages/js_constants.js.thtml:66
+msgid "addon_not_available_for_platform"
+msgstr "%1$s không hiện hữu cho %2$s."
+
+#. %1 is the add-on name
+#: views/addons/policy.thtml:101
+#: views/addons/previews.thtml:60
+#: views/addons/versions.thtml:130
+#: views/reviews/flag.thtml:61
+#: views/reviews/add.thtml:114
+#: views/reviews/display.thtml:216
+#: views/reviews/review_added.thtml:57
+#, php-format
+msgid "addon_review_a_back_to_addon_x"
+msgstr "Quay lại %1$s..."
+
+#. %1 is the add-on name
+#: views/reviews/flag.thtml:60
+#: views/reviews/add.thtml:113
+#: views/reviews/review_added.thtml:56
+#, php-format
+msgid "addon_review_a_back_to_reviews"
+msgstr "Quay lại phần đánh giá..."
+
+#: views/reviews/add.thtml:85
+msgid "addon_review_add_rating_field"
+msgstr "Xếp hạng:"
+
+#: views/reviews/add.thtml:102
+msgid "addon_review_add_review_field"
+msgstr "Äánh giá:"
+
+#: views/reviews/add.thtml:107
+msgid "addon_review_add_submit"
+msgstr "Gửi đánh giá"
+
+#. %s is the name of the add-on
+#: views/reviews/add.thtml:51
+#, php-format
+msgid "addon_review_add_title"
+msgstr "Thêm đánh giá cho %s"
+
+#: views/reviews/add.thtml:78
+msgid "addon_review_add_title_field"
+msgstr "Tiêu đỠ/ Tóm tắt:"
+
+#: views/reviews/display.thtml:77
+#: views/reviews/display.thtml:161
+msgid "addon_review_admin_delete"
+msgstr "Xóa"
+
+#: views/reviews/display.thtml:76
+msgid "addon_review_author_reply_link"
+msgstr "Trả lá»i"
+
+#: views/reviews/delete.thtml:62
+msgid "addon_review_confirm_delete"
+msgstr "Bạn có chắc bạn muốn xóa đánh giá này?"
+
+#: views/reviews/delete.thtml:63
+msgid "addon_review_confirm_no"
+msgstr "Không"
+
+#: views/reviews/delete.thtml:64
+msgid "addon_review_confirm_yes"
+msgstr "Có"
+
+#: views/reviews/delete.thtml:48
+msgid "addon_review_delete_header"
+msgstr "Xóa đánh giá"
+
+#: controllers/reviews_controller.php:449
+msgid "addon_review_deleted_successfully"
+msgstr "Äánh giá đã được xóa thành công."
+
+#. %s is the name of the add-on
+#: views/reviews/add.thtml:51
+#, php-format
+msgid "addon_review_edit_title"
+msgstr "Chỉnh sá»­a Äánh giá của %s"
+
+#. %1 is the count of characters entered as notes for the review flag reason.
+#: controllers/reviews_controller.php:539
+msgid "addon_review_flag_error_other_length"
+msgstr "Vấn đỠkhi gán cỠhiệu cho đánh giá: Ghi chú cho các đánh giá được gán cỠbị giới hạn trong 10 đến 100 kí tự; độ dài kí tự bạn vừa gõ là %1$s."
+
+#. Removing an extra comma
+#: views/reviews/review_added.thtml:53
+msgid "addon_review_in_moderation"
+msgstr "Vui lòng chú ý: TrÆ°á»›c khi đánh giá của bạn hiện công khai trên trang, nó sẽ được Ä‘iá»u chỉnh bởi má»™t biên tập viên."
+
+#: views/reviews/add.thtml:57
+msgid "addon_review_in_reply_to"
+msgstr "Nhà phát triển trả lá»i:"
+
+#. %1 is the review count, %2 is the nickname or full name of the user.
+#: views/reviews/display.thtml:131
+#, php-format
+msgid "addon_review_others_by_user"
+msgid_plural "addon_review_others_by_user"
+msgstr[0] "Xem %1$s bài đánh giá trước được gửi bởi %2$s cho tiện ích này."
+msgstr[1] "Xem %1$s bài đánh giá trước được gửi bởi %2$s cho tiện ích này."
+
+#. %1 is the add-on name
+#: controllers/reviews_controller.php:201
+#: controllers/reviews_controller.php:250
+#: controllers/reviews_controller.php:345
+#: controllers/reviews_controller.php:424
+#, php-format
+msgid "addon_review_pagetitle"
+msgstr "Äánh giá cho %s"
+
+#. %1 is the user, %2 is the (localized) date
+#: views/reviews/display.thtml:160
+#, php-format
+msgid "addon_review_reply_on_x_by_y"
+msgstr "Trả lá»i bởi %1$s ngày %2$s"
+
+#: views/reviews/display.thtml:157
+msgid "addon_review_reply_prefix"
+msgstr "Nhà phát triển trả lá»i:"
+
+#: views/reviews/review_added.thtml:51
+msgid "addon_review_saved_successfully"
+msgstr "Äánh giá của bạn đã được lÆ°u thành công. Cảm Æ¡n!"
+
+#: views/addons/display.thtml:354
+#: views/reviews/display.thtml:72
+msgid "addon_reviewed_by_u_on_d"
+msgstr "bởi %1$s ngày %2$s"
+
+#. %1 is the user, %2 is the (localized) date, %3 is the rating
+#: views/editors/reviews_queue.thtml:57
+#: views/editors/reviews_queue.thtml:68
+#: views/reviews/add.thtml:63
+#: views/reviews/delete.thtml:54
+#, php-format
+msgid "addon_reviewed_on_x_rated_y"
+msgstr "bởi %1$s ngày %2$s (xếp hạng %3$s)"
+
+#: views/elements/amo2009/addon_version_detail.thtml:52
+#: views/elements/addon_version_detail.thtml:52
+msgid "addon_version_permalink"
+msgstr "Liên kết tĩnh đến tiện ích này"
+
+#. %1 is the current Application name (e.g. Firefox)
+#. %2 is the Application's version number
+#: views/addons/versions.thtml:140
+msgid "addon_versions_getlatestversion"
+msgstr "Phiên bản mới nhất tương thích với %1$s %2$s"
+
+#: views/addons/display.thtml:447
+msgid "addons_author_addons_submit"
+msgstr "Gá»­i Ä‘i"
+
+#: views/elements/amo2009/homepage_addon.thtml:100
+#: views/elements/feature.thtml:95
+msgid "addons_author_tooltip"
+msgstr "Xem hồ sơ của Tác giả"
+
+#. %1 is the name of the Application (eg. Firefox)
+#: controllers/addons_controller.php:1296
+msgid "addons_browse_all_themes_title"
+msgstr "Duyệt xem tất cả Giao diện :: Tiện ích %1$s"
+
+#. %s is the name of the category
+#: controllers/addons_controller.php:1016
+#, php-format
+msgid "addons_browse_browse_category"
+msgstr "Duyệt %s"
+
+#. %1 is the name of the theme category (eg. Modern)
+#. %2 is the name of the Application (eg. Firefox)
+#: controllers/addons_controller.php:664
+msgid "addons_browse_categories_header_theme"
+msgstr "Duyệt xem Giao diện %1$s :: Tiện ích %2$s"
+
+#: views/addons/display.thtml:249
+msgid "addons_display_a_license_what"
+msgstr "Äây là gì?"
+
+#: views/reviews/display.thtml:222
+msgid "addons_display_add_review"
+msgstr "Thêm đánh giá"
+
+#: views/addons/display.thtml:294
+msgid "addons_display_advanced_details"
+msgstr "Chi tiết Nâng cao"
+
+#: views/addons/display.thtml:98
+msgid "addons_display_categories"
+msgstr "Phân mục"
+
+#: views/addons/display.thtml:482
+msgid "addons_display_collection_add"
+msgstr "Thêm vào một bộ sưu tập:"
+
+#: views/addons/display.thtml:491
+msgid "addons_display_collection_add_new"
+msgstr "Bộ sưu tập mới..."
+
+#: views/addons/display.thtml:487
+msgid "addons_display_collection_add_select_one"
+msgstr "Chá»n má»™t bá»™ sÆ°u tập..."
+
+#: views/addons/display.thtml:493
+msgid "addons_display_collection_add_submit"
+msgstr "Xuất bản"
+
+#. %1$s is the add-on name
+#. %2$s is the collection name, linked to the collection's page
+#: views/pages/js_constants.js.thtml:103
+#: views/addons/display.thtml:61
+msgid "addons_display_collection_publish_success"
+msgstr "%1$s vừa được thêm vào bộ sưu tập %2$s."
+
+#: views/addons/display.thtml:483
+msgid "addons_display_collection_whatsthis"
+msgstr "Äây là gì?"
+
+#. %1$s is a number
+#: views/addons/display.thtml:473
+msgid "addons_display_collections_more"
+msgid_plural "addons_display_collections_more"
+msgstr[0] "và %1$s bộ sưu tập nữa"
+msgstr[1] "và %1$s bộ sưu tập nữa"
+
+#: views/addons/display.thtml:403
+msgid "addons_display_detailed_review"
+msgstr "đánh giá chi tiết"
+
+#: views/reviews/add.thtml:89
+#: views/reviews/add.thtml:90
+msgid "addons_display_dont_like_it"
+msgstr "Không thích"
+
+#: views/reviews/display.thtml:220
+msgid "addons_display_edit_review"
+msgstr "Chỉnh sửa đánh giá của bạn"
+
+#: views/addons/display.thtml:132
+msgid "addons_display_has_privacy"
+msgstr "Tiện ích này có Ä‘iá»u khoản vá» quyá»n riêng tÆ°."
+
+#: views/reviews/add.thtml:87
+#: views/reviews/add.thtml:88
+msgid "addons_display_hate_it"
+msgstr "Ghét"
+
+#: views/addons/display.thtml:462
+msgid "addons_display_header_collections"
+msgstr "Bộ sưu tập Liên quan"
+
+#: views/addons/display.thtml:297
+msgid "addons_display_header_developer_comments"
+msgstr "Bình luận của Nhà phát triển"
+
+#: views/addons/display.thtml:230
+msgid "addons_display_header_homepage"
+msgstr "Trang chủ"
+
+#: views/addons/display.thtml:247
+#: views/addons/versions.thtml:110
+msgid "addons_display_header_license"
+msgstr "Giấy phép Mã nguồn"
+
+#: views/addons/display.thtml:337
+msgid "addons_display_header_reviews"
+msgstr "Äánh giá"
+
+#: views/addons/display.thtml:261
+msgid "addons_display_header_support"
+msgstr "Hỗ trợ"
+
+#: views/reviews/add.thtml:91
+#: views/reviews/add.thtml:92
+msgid "addons_display_like_it"
+msgstr "Thích"
+
+#: views/addons/display.thtml:210
+msgid "addons_display_long_description"
+msgstr "Mô tả Äầy đủ"
+
+#: views/reviews/add.thtml:95
+#: views/reviews/add.thtml:96
+msgid "addons_display_love_it"
+msgstr "Yêu"
+
+#: views/addons/display.thtml:178
+msgid "addons_display_more_images"
+msgstr "Nhiá»u Hình HÆ¡n"
+
+#: views/addons/display.thtml:465
+msgid "addons_display_nocollections"
+msgstr "Tiện ích này chưa có trong bất kì bộ sưu tập nào."
+
+#. %1$s is either an author's name or a comma separated list of authors. Using
+#. the list doesn't make sense in the English plural form so we ignore the
+#. variable.
+#: views/addons/display.thtml:436
+msgid "addons_display_other_addons_by"
+msgid_plural "addons_display_other_addons_by"
+msgstr[0] "Tiện ích khác của %1$s"
+msgstr[1] "Tiện ích khác của các tác giả này"
+
+#. %s is the name of the add-on and the add-on section. Example:
+#. Some Add-on :: Firefox Add-ons
+#. This should not be concatenated in the code and should be fixed.
+#: controllers/addons_controller.php:141
+#: controllers/addons_controller.php:280
+#: controllers/addons_controller.php:1442
+#, php-format
+msgid "addons_display_pagetitle"
+msgstr "%s"
+
+#. %s is an email address
+#: views/addons/display.thtml:286
+#, php-format
+msgid "addons_display_paragraph_supportinfoemail"
+msgstr "Hỗ trợ cho tiện ích này được cung cấp bởi nhà phát triển tại %s"
+
+#. %$1s is a URL
+#. %$2s is an email address
+#: views/addons/display.thtml:269
+#, php-format
+msgid "addons_display_paragraph_supportinfoemailurl"
+msgstr "Hỗ trợ cho tiện ích này được cung cấp bởi nhà phát triển tại %s hoặc bằng cách gửi e-mail đến %s"
+
+#. %s is a URL
+#: views/addons/display.thtml:278
+#, php-format
+msgid "addons_display_paragraph_supportinfourl"
+msgstr "Hỗ trợ cho tiện ích này được cung cấp bởi nhà phát triển tại %s"
+
+#: views/addons/display.thtml:383
+msgid "addons_display_rate_it"
+msgstr "Xếp hạng nó"
+
+#: views/reviews/add.thtml:93
+#: views/reviews/add.thtml:94
+msgid "addons_display_really_like_it"
+msgstr "Thật sự thích"
+
+#: views/addons/display.thtml:410
+msgid "addons_display_review_etiquette"
+msgstr "Vui lòng đừng báo lá»—i trong phần đánh giá. Chúng tôi không cho nhà phát triển tiện ích thấy địa chỉ email của bạn, trong khi há» có thể cần liên lạc riêng vá»›i bạn để giải quyết vấn Ä‘á»."
+
+#. %1 is the review guidelines link
+#: views/addons/display.thtml:417
+msgid "addons_display_review_guidelines_link"
+msgstr "<a href=\"%s\">HÆ°á»›ng dẫn Äánh giá</a>"
+
+#. %1 is the support section link
+#: views/addons/display.thtml:414
+msgid "addons_display_review_see_support"
+msgstr "Xem <a href=\"%1$s\">phần hỗ trợ</a> để tìm nơi nhận được hỗ trợ cho tiện ích này."
+
+#: views/addons/display.thtml:404
+msgid "addons_display_review_submit"
+msgstr "LÆ°u"
+
+#: views/addons/display.thtml:430
+#, php-format
+msgid "addons_display_see_all_addons"
+msgstr "Xem tất cả Tiện ích %1$s"
+
+#. %1 is the number of reviews
+#: views/addons/display.thtml:364
+#, php-format
+msgid "addons_display_see_all_reviews"
+msgstr "Xem tất cả đánh giá (%1$s)"
+
+#: views/addons/display.thtml:219
+msgid "addons_display_see_all_versions"
+msgstr "Xem tất cả Phiên bản"
+
+#: views/addons/display.thtml:321
+#: views/addons/versions.thtml:117
+msgid "addons_display_view_source"
+msgstr "Xem mã nguồn"
+
+#: views/addons/display.thtml:324
+msgid "addons_display_view_stats"
+msgstr "Xem thống kê"
+
+#: views/addons/display.thtml:376
+msgid "addons_display_what_do_you_think"
+msgstr "Bạn nghĩ sao?"
+
+#: views/elements/app_compatibility.thtml:49
+msgid "addons_display_workswith"
+msgstr "Hoạt động trên:"
+
+#: views/addons/home.thtml:112
+msgid "addons_home_browse_new"
+msgstr "Vừa thêm"
+
+#: views/addons/home.thtml:110
+msgid "addons_home_browse_popular"
+msgstr "Thông dụng"
+
+#: views/addons/home.thtml:108
+msgid "addons_home_browse_recommended"
+msgstr "Khuyên dùng"
+
+#: views/addons/home.thtml:127
+#: views/addons/home.thtml:134
+#: views/addons/home.thtml:141
+#: views/addons/home.thtml:148
+msgid "addons_home_browse_subscribe"
+msgstr "Äăng kí"
+
+#: views/addons/home.thtml:101
+msgid "addons_home_browse_title"
+msgstr "Duyệt xem Tiện ích"
+
+#: views/addons/home.thtml:114
+msgid "addons_home_browse_updated"
+msgstr "Cập nhật"
+
+#: views/elements/amo2009/homepage_addon.thtml:100
+#: views/elements/addon_discussionheader.thtml:83
+#: views/elements/addon_listitem.thtml:109
+#: views/elements/feature.thtml:95
+#: views/addons/category_landing.thtml:66
+#: views/addons/policy.thtml:57
+#: views/addons/display.thtml:70
+#: views/addons/home.thtml:178
+msgid "addons_home_by"
+msgstr "bởi"
+
+#: views/addons/home.thtml:169
+msgid "addons_home_collection_popular_title"
+msgstr "Bộ sưu tập Thông dụng"
+
+#: views/elements/amo2009/categories.thtml:69
+#: views/addons/home.thtml:160
+msgid "addons_home_collections"
+msgstr "Bộ sưu tập"
+
+#. %1$s is the count of addons in a collection
+#: views/elements/amo2009/collection_listing_item.thtml:51
+#: views/addons/home.thtml:185
+msgid "addons_home_collections_addon_count"
+msgid_plural "addons_home_collections_addon_count"
+msgstr[0] "<strong>%1$s</strong> tiện ích"
+msgstr[1] "<strong>%1$s</strong> tiện ích"
+
+#: views/addons/home.thtml:196
+msgid "addons_home_collections_all"
+msgstr "Xem tất cả Các bộ sưu tập"
+
+#: views/addons/home.thtml:162
+msgid "addons_home_collections_intro"
+msgstr "Bá»™ sÆ°u tập là má»™t cách để bạn phân loại, trá»™n, so sánh các tiện ích. Hãy đăng kí vào bá»™ sÆ°u tập tạo bởi ngÆ°á»i dùng khác hoặc tá»± tạo cho riêng bạn."
+
+#. %1$s is the count of subscribers for a collection
+#: views/elements/amo2009/collection_listing_item.thtml:58
+#: views/collections/detail.thtml:96
+#: views/addons/home.thtml:189
+msgid "addons_home_collections_subscribers"
+msgid_plural "addons_home_collections_subscribers"
+msgstr[0] "<strong>%1$s</strong> ngÆ°á»i đăng kí"
+msgstr[1] "<strong>%1$s</strong> ngÆ°á»i đăng kí"
+
+#: views/addons/searchengines.thtml:54
+#: views/addons/themes_landing.thtml:49
+msgid "addons_home_feature_head"
+msgstr "<a href=\"http://vi.mozdev.org\" target=\"_blank\">Mozilla Việt Nam</a> khuyên dùng"
+
+#: controllers/search_controller.php:218
+#: controllers/addons_controller.php:176
+#: controllers/addons_controller.php:428
+#: controllers/addons_controller.php:671
+#: controllers/addons_controller.php:871
+#: controllers/addons_controller.php:1103
+#: controllers/addons_controller.php:1242
+#: controllers/addons_controller.php:1298
+#, php-format
+msgid "addons_home_header_details"
+msgstr "Tiện ích mở rộng %1$s, cho phép bạn tùy biến việc duyệt web. Hãy dạo quanh một vòng và làm chủ %1$s."
+
+#. %1$s is the HTML collection name link.
+#: views/elements/amo2009/teaser_collections.thtml:107
+msgid "addons_home_introduction_collection_link"
+msgstr "Thích những cái này? Hãy tìm thêm tiện ích trong %1$s."
+
+#: views/elements/amo2009/teaser_collections.thtml:60
+msgid "addons_home_introduction_extras"
+msgstr "<strong>Trên 5000 thành phần bổ sung miễn phí</strong> giúp bạn tùy biến và mở rộng Firefox phù hợp với nhu cầu của mình."
+
+#: views/elements/amo2009/teaser_collections.thtml:55
+msgid "addons_home_introduction_header"
+msgstr "Tiện ích là gì?"
+
+#: views/elements/amo2009/teaser_collections.thtml:72
+msgid "addons_home_introduction_install"
+msgstr "<strong>Dễ cài đặt</strong> và luôn được cập nhật."
+
+#: views/elements/amo2009/teaser_collections.thtml:45
+msgid "addons_home_introduction_name"
+msgstr "Giới thiệu"
+
+#: views/elements/amo2009/teaser_collections.thtml:66
+msgid "addons_home_introduction_themes"
+msgstr "Thanh công cụ, giao diện và nhà cung cấp tìm kiếm <strong>giúp bạn thá»±c hiện các tác vụ thông thÆ°á»ng.</strong>"
+
+#: views/addons/home.thtml:161
+msgid "addons_home_new_indicator"
+msgstr "MỚI!"
+
+#: views/elements/app_chooser.thtml:48
+#: views/layouts/amo2009.thtml:257
+msgid "addons_home_other_applications"
+msgstr "Chương trình Khác"
+
+#. %1$s is the application the user is browsing. Examples: Thunderbird, Firefox,
+#. Sunbird
+#: views/pages/collector_faq.thtml:49
+#: views/pages/collector_firstrun.thtml:42
+#: views/pages/collector.thtml:46
+#: views/pages/collector_features.thtml:54
+#: controllers/developers_controller.php:87
+#: controllers/compatibility_controller.php:72
+#: controllers/components/simple_acl.php:81
+#: controllers/components/amo.php:607
+#: controllers/statistics_controller.php:60
+#: controllers/statistics_controller.php:240
+#: controllers/previews_controller.php:67
+#: controllers/users_controller.php:90
+#: controllers/users_controller.php:223
+#: controllers/users_controller.php:330
+#: controllers/users_controller.php:414
+#: controllers/users_controller.php:708
+#: controllers/users_controller.php:723
+#: controllers/reviews_controller.php:204
+#: controllers/reviews_controller.php:251
+#: controllers/reviews_controller.php:346
+#: controllers/reviews_controller.php:425
+#: controllers/search_controller.php:185
+#: controllers/search_controller.php:297
+#: controllers/search_controller.php:301
+#: controllers/addons_controller.php:147
+#: controllers/addons_controller.php:280
+#: controllers/addons_controller.php:370
+#: controllers/addons_controller.php:667
+#: controllers/addons_controller.php:874
+#: controllers/addons_controller.php:1019
+#: controllers/addons_controller.php:1034
+#: controllers/addons_controller.php:1101
+#: controllers/addons_controller.php:1121
+#: controllers/addons_controller.php:1240
+#: controllers/addons_controller.php:1357
+#: controllers/addons_controller.php:1364
+#: controllers/addons_controller.php:1442
+#: controllers/addons_controller.php:1477
+#: controllers/addons_controller.php:1538
+#: controllers/addons_controller.php:1543
+#: controllers/editors_controller.php:64
+#: controllers/pages_controller.php:132
+#: controllers/groups_controller.php:65
+#: controllers/groups_controller.php:71
+#: controllers/groups_controller.php:89
+#: controllers/groups_controller.php:111
+#: controllers/collections_controller.php:57
+#: controllers/collections_controller.php:121
+#: controllers/collections_controller.php:205
+#: controllers/collections_controller.php:365
+#: controllers/collections_controller.php:404
+#: controllers/collections_controller.php:466
+#: controllers/collections_controller.php:538
+#: controllers/collections_controller.php:828
+#: controllers/localizers_controller.php:72
+#, php-format
+msgid "addons_home_pagetitle"
+msgstr "%1$s Add-ons - Tiện ích %1$s"
+
+#. %1$s is the number of addons downloaded
+#: views/addons/home.thtml:57
+#, php-format
+msgid "addons_home_stats_downloaded"
+msgid_plural "addons_home_stats_downloaded"
+msgstr[0] "<strong>%1$s</strong> <span>tiện ích đã được tải xuống</span>"
+msgstr[1] "<strong>%1$s</strong> <span>tiện ích đã được tải xuống</span>"
+
+#. %1$s is the number of addons in use
+#: views/addons/home.thtml:63
+#, php-format
+msgid "addons_home_stats_inuse"
+msgid_plural "addons_home_stats_inuse"
+msgstr[0] "<strong>%1$s</strong> <span>tiện ích đang được dùng</span>"
+msgstr[1] "<strong>%1$s</strong> <span>tiện ích đang được dùng</span>"
+
+#: views/addons/home.thtml:136
+msgid "addons_home_view_all_newest_title"
+msgstr "xem tất cả các tiện ích mới được tạo"
+
+#: views/addons/home.thtml:129
+msgid "addons_home_view_all_popular_title"
+msgstr "xem tất cả các tiện ích thông dụng"
+
+#: views/addons/home.thtml:150
+msgid "addons_home_view_all_recommended_title"
+msgstr "xem tất cả các tiện ích khuyên dùng"
+
+#: views/addons/home.thtml:143
+msgid "addons_home_view_all_updated_title"
+msgstr "xem tất cả các tiện ích được cập nhật gần đây"
+
+#: views/elements/amo2009/install.thtml:334
+#: views/elements/install.thtml:112
+msgid "addons_install_in_sunbird"
+msgstr "<ol><li>Nhấn vào liên kết bên dÆ°á»›i để lÆ°u tập tin.</li><li>Trong Mozilla Sunbird, mở Tiện ích từ trình Ä‘Æ¡n Công cụ</li><li>Nhấn vào nút Cài đặt, và tìm/chá»n tập tin bạn đã tải xuống và nhấn \"OK\".</li></ol>"
+
+#: views/elements/amo2009/install.thtml:333
+#: views/elements/install.thtml:111
+msgid "addons_install_in_sunbird_title"
+msgstr "Cách thức Cài đặt trong Sunbird"
+
+#: views/elements/amo2009/install.thtml:331
+#: views/elements/install.thtml:106
+msgid "addons_install_in_thunderbird"
+msgstr "<ol><li>Nhấn chuá»™t phải liên kết bên dÆ°á»›i và chá»n \"LÆ°u Liên Kết dÆ°á»›i dạng...\" để tải xuống và lÆ°u tập tin vào Ä‘Ä©a của bạn.</li><li>Trong Mozilla Thunderbird, mở Tiện ích từ trình Ä‘Æ¡n Công cụ.</li><li>Nhấn nút Cài đặt, và định vị/chá»n tập tin bạn đã tải xuống rồi nhấn \"OK\".</li></ol>"
+
+#: views/elements/amo2009/install.thtml:330
+#: views/elements/install.thtml:105
+msgid "addons_install_in_thunderbird_title"
+msgstr "Làm thế nào để Cài đặt trong Thunderbird"
+
+#: views/elements/amo2009/addon_list_options.thtml:108
+#: views/elements/addon_list_options.thtml:105
+msgid "addons_options_show_experimental"
+msgstr "hiện các tiện ích đang thử nghiệm"
+
+#: views/elements/amo2009/addon_list_options.thtml:113
+#: views/elements/addon_list_options.thtml:109
+msgid "addons_options_submit"
+msgstr "Gá»­i Ä‘i"
+
+#: views/addons/plugins.thtml:63
+#: views/addons/plugins.thtml:73
+#: views/addons/plugins.thtml:83
+#: views/addons/plugins.thtml:93
+#: views/addons/plugins.thtml:103
+#: views/addons/plugins.thtml:116
+#: views/addons/plugins.thtml:126
+msgid "addons_plugins_by"
+msgstr "Bởi"
+
+#: views/addons/plugins.thtml:107
+msgid "addons_plugins_for_linux"
+msgstr "cho Linux"
+
+#: views/addons/plugins.thtml:108
+#: views/addons/plugins.thtml:131
+msgid "addons_plugins_for_macosx"
+msgstr "cho Max OS X"
+
+#: views/addons/plugins.thtml:106
+#: views/addons/plugins.thtml:129
+#: views/addons/plugins.thtml:130
+msgid "addons_plugins_for_windows"
+msgstr "cho Windows"
+
+#. %1$s is a URL
+#: views/addons/plugins.thtml:139
+#, php-format
+msgid "addons_plugins_looking_for_more"
+msgstr "Trang này chỉ liệt kê má»™t số phần bổ trợ thông dụng nhất. Äể có thêm thông tin vá» các phần bổ trợ khác cho các Trình duyệt dá»±a trên Mozilla, hãy vào %1$s"
+
+#: views/addons/plugins.thtml:137
+msgid "addons_plugins_looking_for_plugin"
+msgstr "Äang tìm má»™t phần bổ trợ không được liệt kê tại đây?"
+
+#: views/addons/plugins.thtml:58
+msgid "addons_plugins_main_description"
+msgstr "Phần bổ trợ giúp trình duyệt của bạn thá»±c hiện má»™t số chức năng nhÆ° xem các định dạng đồ há»a đặc biệt hoặc chÆ¡i các tập tin Ä‘a phÆ°Æ¡ng tiện. Phần bổ trợ hÆ¡i khác má»™t chút so vá»›i phần mở rá»™ng - những cái dùng để chỉnh sá»­a hoặc thêm tính năng cho những chức năng sẵn có."
+
+#. %1$s is the application name. Example: Firefox, Thunderbird, Sunbird
+#: controllers/addons_controller.php:1122
+#, php-format
+msgid "addons_plugins_main_header"
+msgstr "Phần bổ trợ Thông dụng cho %1$s"
+
+#: controllers/components/amo.php:698
+#: controllers/addons_controller.php:1121
+msgid "addons_plugins_pagetitle"
+msgstr "Phần bổ trợ"
+
+#: views/addons/plugins.thtml:68
+#: views/addons/plugins.thtml:78
+#: views/addons/plugins.thtml:88
+#: views/addons/plugins.thtml:98
+#: views/addons/plugins.thtml:110
+#: views/addons/plugins.thtml:121
+#: views/addons/plugins.thtml:133
+msgid "addons_plugins_support_documentation"
+msgstr "Tài liệu Trợ giúp: "
+
+#. %s is the name of the add-on
+#: views/addons/policy.thtml:61
+#, php-format
+msgid "addons_policy_eula_require"
+msgstr "%s yêu cầu bạn chấp thuận Thá»a thuận Giấy phép NgÆ°á»i dùng Cuối trÆ°á»›c khi việc cài đặt có thể tiến hành:"
+
+#. %1 is the add-on name
+#: controllers/addons_controller.php:1476
+#, php-format
+msgid "addons_previews_pagetitle"
+msgstr "Xem trÆ°á»›c cho %s"
+
+#: views/addons/category_landing.thtml:135
+msgid "addons_recently_added"
+msgstr "Vừa được Thêm"
+
+#: views/addons/recommended.thtml:51
+#: controllers/addons_controller.php:1365
+msgid "addons_recommended_introduction"
+msgstr "Vá»›i nhiá»u tiện ích tuyệt vá»i hiện có, hẳn sẽ có gì đó cho từng ngÆ°á»i. Äể giúp bạn bắt đầu, đây là danh sách má»™t số cái thông dụng. Hãy thá»­ nhé!"
+
+#: controllers/addons_controller.php:1357
+#: controllers/addons_controller.php:1364
+msgid "addons_recommended_pagetitle"
+msgstr "Tiện ích được Khuyên dùng"
+
+#: controllers/addons_controller.php:1360
+msgid "addons_recommended_title"
+msgstr "Tiện ích được Khuyên dùng"
+
+#: views/addons/searchengines.thtml:136
+msgid "addons_searchengines_additional_resources"
+msgstr "Tài nguyên Khác"
+
+#. link text devmo
+#: views/addons/searchengines.thtml:141
+msgid "addons_searchengines_devmo_link"
+msgstr "Trung tâm Phát triển Mozilla"
+
+#: views/pages/js_constants.js.thtml:67
+msgid "addons_searchengines_error_mozilla_browser_required"
+msgstr "Xin lỗi, bạn cần một trình duyệt dựa trên Mozilla (như Firefox) để có thể cài đặt phần bổ trợ tìm kiếm."
+
+#: views/addons/searchengines.thtml:49
+msgid "addons_searchengines_error_nojavascript"
+msgstr "JavaScript cần có để cài đặt phần bổ trợ, nhưng có vẻ như bạn đã vô hiệu hóa nó. Vui lòng kích hoạt JavaScript trước khi có ý định cài đặt bất kì phần bổ trợ tìm kiếm nào."
+
+#. %1 is "make your own" link
+#. %2 is MDC link
+#: views/addons/searchengines.thtml:139
+msgid "addons_searchengines_learn_howto"
+msgstr "Há»c cách %1$s trên %2$s."
+
+#. link path to search plugins instructions, relative to devmo
+#: views/addons/searchengines.thtml:140
+msgid "addons_searchengines_makeyourown_href"
+msgstr "/en/docs/Creating_OpenSearch_plugins_for_Firefox"
+
+#. link text for "make your own" (opensearch engine)
+#: views/addons/searchengines.thtml:140
+msgid "addons_searchengines_makeyourown_link"
+msgstr "tự tạo cho mình một cái"
+
+#. %1 is the link to mycroft.mozdev.org
+#: views/addons/searchengines.thtml:138
+msgid "addons_searchengines_more"
+msgstr "Duyệt qua các máy tìm kiếm tại %1$s"
+
+#. link text to mycroft.mozdev.org
+#: views/addons/searchengines.thtml:138
+msgid "addons_searchengines_mycroft_link"
+msgstr "mycroft.mozdev.org"
+
+#: controllers/addons_controller.php:1100
+#: controllers/addons_controller.php:1110
+msgid "addons_searchengines_pagetitle"
+msgstr "Máy tìm kiếm"
+
+#: views/addons/searchengines.thtml:143
+msgid "addons_searchengines_thanks"
+msgstr "Äặc biệt cảm Æ¡n Dá»± án Mycroft vì công việc của há» trong Máy tìm kiếm Firefox."
+
+#: views/addons/display.thtml:154
+msgid "addons_share_button_text"
+msgstr "Chia sẻ cái này"
+
+#: controllers/addons_controller.php:89
+msgid "addons_share_label_delicious"
+msgstr "Thêm vào Delicious"
+
+#: controllers/addons_controller.php:77
+msgid "addons_share_label_digg"
+msgstr "Digg cái này!"
+
+#: controllers/addons_controller.php:83
+msgid "addons_share_label_facebook"
+msgstr "Äăng lên Facebook"
+
+#: controllers/addons_controller.php:101
+msgid "addons_share_label_friendfeed"
+msgstr "Chia sẻ trên FriendFeed"
+
+#: controllers/addons_controller.php:95
+msgid "addons_share_label_myspace"
+msgstr "Äăng lên MySpace"
+
+#: controllers/components/amo.php:201
+#: controllers/components/amo.php:229
+msgid "addons_status_disabled"
+msgstr "Bị vô hiệu hóa"
+
+#: controllers/components/amo.php:191
+#: controllers/components/amo.php:224
+msgid "addons_status_incomplete"
+msgstr "Phiên bản Chưa hoàn thành"
+
+#: controllers/components/amo.php:197
+#: controllers/components/amo.php:227
+msgid "addons_status_nominated"
+msgstr "Trong Há»™p-cát; Äá» cá»­ thành Công cá»™ng"
+
+#: views/pages/js_constants.js.thtml:80
+#: controllers/components/amo.php:195
+#: controllers/components/amo.php:226
+msgid "addons_status_pending"
+msgstr "Trong Há»™p-cát; Äang chá» Äánh giá"
+
+#: views/pages/js_constants.js.thtml:78
+#: controllers/components/amo.php:199
+#: controllers/components/amo.php:228
+msgid "addons_status_public"
+msgstr "Công cộng"
+
+#: views/pages/js_constants.js.thtml:79
+#: controllers/components/amo.php:193
+#: controllers/components/amo.php:225
+msgid "addons_status_sandbox"
+msgstr "Trong Hộp-cát"
+
+#: controllers/components/amo.php:203
+msgid "addons_status_unknown"
+msgstr "Không rõ"
+
+#: views/elements/amo2009/teaser_collections.thtml:91
+#: views/elements/amo2009/homepage_addon.thtml:99
+#: views/elements/feature.thtml:94
+msgid "addons_title_tooltip"
+msgstr "Äá»c thêm vá» tiện ích này"
+
+#: views/addons/category_landing.thtml:151
+msgid "addons_top_downloads"
+msgstr "Tải xuống Nhiá»u nhất"
+
+#: views/addons/category_landing.thtml:165
+msgid "addons_top_rated"
+msgstr "Xếp hạng Cao nhất"
+
+#: views/addons/versions.thtml:62
+msgid "addons_versions_careful"
+msgstr "Hãy Cẩn Thận Với Phiên Bản Cũ"
+
+#: views/addons/versions.thtml:63
+msgid "addons_versions_careful_introduction"
+msgstr "Những phiên bản này được hiện ra cho mục đích thử nghiệm và tham khảo. Bạn chỉ nên dùng phiên bản mới nhất của tiện ích này."
+
+#: controllers/addons_controller.php:1549
+msgid "addons_versions_history"
+msgstr "Lịch sử Phiên bản cùng với Lưu kí Thay đổi"
+
+#. %1$s is the add-on name
+#: controllers/addons_controller.php:1535
+#, php-format
+msgid "addons_versions_pagetitle"
+msgstr "%1$s Lược sử Phiên bản"
+
+#: controllers/groups_controller.php:71
+msgid "admin_group_add_pagetitle"
+msgstr "Thêm Nhóm"
+
+#: controllers/groups_controller.php:111
+msgid "admin_group_delete_pagetitle"
+msgstr "Xóa Nhóm"
+
+#. %s is a number to identify the group
+#: controllers/groups_controller.php:117
+#, php-format
+msgid "admin_group_deleted"
+msgstr "Nhóm có định danh %s đã được xóa"
+
+#: controllers/groups_controller.php:89
+msgid "admin_group_edit_pagetitle"
+msgstr "Chỉnh sửa Nhóm"
+
+#: controllers/groups_controller.php:92
+#: controllers/groups_controller.php:113
+msgid "admin_group_error_invalid_id"
+msgstr "ID không phù hợp cho Nhóm"
+
+#: controllers/groups_controller.php:65
+msgid "admin_group_pagetitle"
+msgstr "Quản trị Nhóm"
+
+#: controllers/groups_controller.php:77
+#: controllers/groups_controller.php:99
+msgid "admin_group_saved"
+msgstr "Nhóm đã được lưu"
+
+#: views/elements/amo2009/search.thtml:257
+#: views/elements/search.thtml:239
+msgid "advanced_search_form"
+msgstr "Nâng cao"
+
+#: views/elements/amo2009/search.thtml:126
+#: views/elements/search.thtml:125
+msgid "advanced_search_form_any_time"
+msgstr "Bất kì lúc nào"
+
+#: views/elements/amo2009/search.thtml:97
+#: views/elements/amo2009/search.thtml:110
+#: views/elements/search.thtml:96
+#: views/elements/search.thtml:109
+msgid "advanced_search_form_any_type"
+msgstr "Kiểu bất kì"
+
+#: views/elements/amo2009/search.thtml:275
+#: views/elements/search.thtml:254
+msgid "advanced_search_form_any_version"
+msgstr "Phiên bản bất kì"
+
+#: views/elements/amo2009/search.thtml:217
+#: views/elements/search.thtml:212
+msgid "advanced_search_form_application"
+msgstr "Chương trình"
+
+#: views/elements/amo2009/search.thtml:143
+#: views/elements/search.thtml:142
+msgid "advanced_search_form_keyword_match"
+msgstr "Từ khóa Phù hợp"
+
+#: views/elements/amo2009/search.thtml:251
+#: views/elements/search.thtml:225
+msgid "advanced_search_form_lastupdate"
+msgstr "Cập nhật cuối"
+
+#: views/elements/amo2009/search.thtml:145
+#: views/elements/search.thtml:144
+msgid "advanced_search_form_name"
+msgstr "Tên"
+
+#: views/elements/amo2009/search.thtml:144
+#: views/elements/search.thtml:143
+msgid "advanced_search_form_newest"
+msgstr "Mới nhất"
+
+#: views/elements/amo2009/search.thtml:130
+#: views/elements/search.thtml:129
+msgid "advanced_search_form_past_3_months"
+msgstr "3 tháng qua"
+
+#: views/elements/amo2009/search.thtml:131
+#: views/elements/search.thtml:130
+msgid "advanced_search_form_past_6_months"
+msgstr "6 tháng qua"
+
+#: views/elements/amo2009/search.thtml:127
+#: views/elements/search.thtml:126
+msgid "advanced_search_form_past_day"
+msgstr "Ngày qua"
+
+#: views/elements/amo2009/search.thtml:129
+#: views/elements/search.thtml:128
+msgid "advanced_search_form_past_month"
+msgstr "Tháng qua"
+
+#: views/elements/amo2009/search.thtml:128
+#: views/elements/search.thtml:127
+msgid "advanced_search_form_past_week"
+msgstr "Tuần qua"
+
+#: views/elements/amo2009/search.thtml:132
+#: views/elements/search.thtml:131
+msgid "advanced_search_form_past_year"
+msgstr "Năm qua"
+
+#: views/elements/amo2009/search.thtml:239
+#: views/elements/search.thtml:230
+msgid "advanced_search_form_perpage"
+msgstr "Má»—i trang"
+
+#: views/elements/amo2009/search.thtml:243
+#: views/elements/search.thtml:224
+msgid "advanced_search_form_platform"
+msgstr "Hệ Ä‘iá»u hành"
+
+#: views/elements/amo2009/search.thtml:147
+#: views/elements/search.thtml:146
+msgid "advanced_search_form_popularity"
+msgstr "Mức độ thông dụng"
+
+#: views/elements/amo2009/search.thtml:146
+#: views/elements/search.thtml:145
+msgid "advanced_search_form_rating"
+msgstr "Xếp hạng"
+
+#: views/elements/amo2009/search.thtml:247
+#: views/elements/search.thtml:231
+msgid "advanced_search_form_sortby"
+msgstr "Sắp xếp theo"
+
+#: views/elements/amo2009/search.thtml:227
+#: views/elements/search.thtml:216
+msgid "advanced_search_form_to"
+msgstr "đến"
+
+#: views/elements/amo2009/search.thtml:257
+#: views/elements/search.thtml:237
+msgid "advanced_search_form_toggle_tooltip"
+msgstr "Bật/Tắt chế độ tìm kiếm nâng cao"
+
+#: views/elements/amo2009/search.thtml:235
+#: views/elements/search.thtml:223
+msgid "advanced_search_form_type"
+msgstr "Kiểu"
+
+#: views/elements/amo2009/search.thtml:222
+#: views/elements/search.thtml:214
+msgid "advanced_search_form_version"
+msgstr "phiên bản"
+
+#: views/elements/amo2009/pagination.thtml:42
+msgid "amo2009_pagination_next_page"
+msgstr "Tiếp"
+
+#: views/elements/amo2009/pagination.thtml:41
+msgid "amo2009_pagination_previous_page"
+msgstr "TrÆ°á»›c"
+
+#: views/pages/js_constants.js.thtml:96
+msgid "app_compat_ignore_check"
+msgstr "BỠqua việc kiểm tra phiên bản"
+
+#: views/pages/js_constants.js.thtml:72
+msgid "app_compat_older_firefox_only"
+msgstr "Tiện ích này dành cho các phiên bản Firefox cũ"
+
+#. %1$s and %2$s are URLs
+#: views/pages/js_constants.js.thtml:74
+msgid "app_compat_older_version_or_ignore_check"
+msgstr "Bạn có thể <a href=\"%1$s\">thử dùng phiên bản cũ hơn</a> hoặc <a href=\"#\" onclick=\"%2$s\">bỠqua việc kiểm tra này</a>"
+
+#. %1$s is a URL
+#: views/pages/js_constants.js.thtml:71
+msgid "app_compat_try_old_version"
+msgstr "Có lẽ <a href=\"%1$s\">phiên bản cũ</a> chạy được"
+
+#. %1$s is a URL
+#. %2$s is a version number. Example: 3.1
+#: views/pages/js_constants.js.thtml:73
+msgid "app_compat_unreleased_version"
+msgstr "Tiện ích này yêu cầu phiên bản <a href=\"%1$s\">Firefox %2$s</a> chưa phát hành."
+
+#: views/pages/js_constants.js.thtml:70
+msgid "app_compat_update_firefox"
+msgstr "<a href=\"http://getfirefox.com\">Nâng cấp Firefox</a> để dùng tiện ích này"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#. %3$s is a status, like Public.
+#: controllers/components/audit.php:79
+msgid "audit_addon_status"
+msgstr "%1$s đã thay đổi trạng thái của %2$s thành %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:221
+msgid "audit_admin_default"
+msgstr "%1$s thực hiện thao tác quản trị chưa biết %2$s để ID %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:153
+msgid "audit_admin_feature_remove"
+msgstr "%1$s đã xóa tính năng %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is an application, like Firefox.
+#: controllers/components/audit.php:92
+msgid "audit_application_create"
+msgstr "%1$s đã tạo chương trình %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is an application, like Firefox.
+#: controllers/components/audit.php:95
+msgid "audit_application_edit"
+msgstr "%1$s đã sửa đổi chương trình %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a version number, like 3.5.
+#. %3$s is an application, like Firefox.
+#: controllers/components/audit.php:105
+msgid "audit_appversion_create"
+msgstr "%1$s đã tạo phiên bản %2$s cho %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a version number, like 3.5.
+#. %3$s is an application, like Firefox.
+#: controllers/components/audit.php:108
+msgid "audit_appversion_delete"
+msgstr "%1$s đã xóa phiên bản %2$s cho %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a config field, like "awesomeness".
+#. %3$s is a config value, like "off".
+#. %4$s is a config value, like "on".
+#: controllers/components/audit.php:210
+msgid "audit_config"
+msgstr "%1$s đã thay đổi cấu hình '%2$s' từ '%3$s' thành '%4$s'"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:258
+msgid "audit_editor_default"
+msgstr "%1$s thực hiện thao tác biên tập chưa biết %2$s để ID %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#: controllers/components/audit.php:236
+msgid "audit_editor_feature_remove"
+msgstr "%1$s đã xóa tiện ích %2$s khá»i danh sách khuyên dùng"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#: controllers/components/audit.php:231
+msgid "audit_feature_add"
+msgstr "%1$s đã thêm tiện ích %2$s vào danh sách khuyên dùng"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:149
+msgid "audit_feature_edit"
+msgstr "%1$s đã thay đổi một tính năng cho bản địa %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#: controllers/components/audit.php:241
+msgid "audit_feature_locale_change"
+msgstr "%1$s đã thay đổi bản địa cho tiện ích %2$s trên danh sách khuyên dùng"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:83
+msgid "audit_file_recalchash"
+msgstr "%1$s đã tính toán lại mã băm cho tập tin %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>user name</a>
+#. %3$s is <a>group name</a>
+#: controllers/components/audit.php:182
+msgid "audit_group_addmember"
+msgstr "%1$s thêm %2$s vào nhóm %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:313
+msgid "audit_group_associated"
+msgstr "%1$s kết hợp hỠvới %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:162
+msgid "audit_group_create"
+msgstr "%1s đã tạo nhóm %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:170
+msgid "audit_group_delete"
+msgstr "%1$s đã xóa nhóm %2$s (ID %3$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:165
+msgid "audit_group_edit"
+msgstr "%1$s đã chỉnh sửa nhóm %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>user name</a>
+#. %3$s is <a>group name</a>
+#: controllers/components/audit.php:188
+msgid "audit_group_removemember"
+msgstr "%1$s đã xóa %2$s khá»i nhóm %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:280
+msgid "audit_l10n_default"
+msgstr "%1$s thực hiện thao tác chưa biết %2$s đối với %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:295
+msgid "audit_modify_locked_group"
+msgstr "%1$s đã cố gắng sửa đổi nhóm bị khóa %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:299
+msgid "audit_modify_other_locale"
+msgstr "%1$s đã cố gắng sửa đổi bản dịch trong %2$s mà chưa được phép"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a platform, like <a>Windows</a>
+#: controllers/components/audit.php:135
+msgid "audit_platform_create"
+msgstr "%1$s đã tạo ná»n tảng %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a platform, like <a>Windows</a>
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:143
+msgid "audit_platform_delete"
+msgstr "%1$s đã xóa ná»n tảng %2$s (ID %3$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a platform, like <a>Windows</a>
+#: controllers/components/audit.php:138
+msgid "audit_platform_edit"
+msgstr "%1$s đã chỉnh sá»­a ná»n tảng %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a part of the admin, like 'Site Config'
+#: controllers/components/audit.php:288
+msgid "audit_reauthentication_failure"
+msgstr "%1$s gặp thất bại khi xác thực lại để truy cập %2$s."
+
+#. %1$s is <a>user name</a>
+#. %2$s is the name of a canned response, like 'Ready for the public'
+#: controllers/components/audit.php:198
+msgid "audit_response_create"
+msgstr "%1$s đã tạo phản hồi %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is the name of a canned response, like 'Ready for the public'
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:206
+msgid "audit_response_delete"
+msgstr "%1$s đã xóa phản hồi %2$s (ID %3$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is the name of a canned response, like 'Ready for the public'
+#: controllers/components/audit.php:201
+msgid "audit_response_edit"
+msgstr "%1$s đã chỉnh sửa phản hồi %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:245
+msgid "audit_review_approve"
+msgstr "%1$s đã chấp thuận đánh giá %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:250
+#: controllers/components/audit.php:253
+msgid "audit_review_delete"
+msgstr "%1$s đã xóa đánh giá %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:303
+msgid "audit_security_default"
+msgstr "%1$s thực hiện thao tác bảo mật chưa biết %2$s để ID %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a category name, like <a>Search Tools</a>
+#: controllers/components/audit.php:118
+msgid "audit_tag_create"
+msgstr "%1$s đã tạo nhãn %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a category name, like <a>Search Tools</a>
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:126
+msgid "audit_tag_delete"
+msgstr "%1$s đã xóa phân mục %2$s (ID %3$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a category name, like <a>Search Tools</a>
+#: controllers/components/audit.php:121
+msgid "audit_tag_edit"
+msgstr "%1$s đã chỉnh sửa phân mục %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:266
+msgid "audit_update_applications"
+msgstr "%1$s đã cập nhật bản dịch ứng dụng cho %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:277
+msgid "audit_update_blog"
+msgstr "%1$s đã cập nhật bản dịch bài viết blog cho %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:274
+msgid "audit_update_platforms"
+msgstr "%1$s đã cập nhật bản dịch ná»n tảng cho %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:270
+msgid "audit_update_tags"
+msgstr "%1$s đã cập nhật bản dịch phân mục cho %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>user name</a>
+#: controllers/components/audit.php:217
+msgid "audit_user_edit"
+msgstr "%1$s đã chỉnh sá»­a thông tin ngÆ°á»i dùng của %2$s"
+
+#: controllers/addons_controller.php:1012
+msgid "browse_addons_name"
+msgstr "Tiện ích xếp theo Tên"
+
+#: controllers/addons_controller.php:1010
+msgid "browse_addons_newest"
+msgstr "Tiện ích Mới nhất"
+
+#: controllers/addons_controller.php:1008
+msgid "browse_addons_popular"
+msgstr "Tiện ích Thông dụng"
+
+#: controllers/addons_controller.php:1011
+msgid "browse_addons_rated"
+msgstr "Tiện ích xếp theo Xếp hạng"
+
+#: controllers/addons_controller.php:1009
+msgid "browse_addons_updated"
+msgstr "Tiện ích được Cập nhật Gần đây"
+
+#: views/elements/categories.thtml:73
+#: views/elements/categories.thtml:82
+msgid "categories_current_title"
+msgstr "Phân mục Hiện tại"
+
+#: views/elements/categories.thtml:50
+#: views/elements/amo2009/categories.thtml:43
+#: views/elements/amo2009/categories.thtml:45
+msgid "categories_header"
+msgstr "Phân mục"
+
+#: views/elements/categories.thtml:50
+#: views/elements/amo2009/categories.thtml:41
+msgid "categories_header_title"
+msgstr "Chá»n má»™t phân mục"
+
+#. %1$s is the category name
+#: views/addons/searchengines.thtml:129
+#, php-format
+msgid "category_extra_see_all"
+msgstr "Xem tất cả %1$s"
+
+#. %1$s is a number.
+#: models/collection.php:130
+msgid "collection_description_limit"
+msgstr "Mô tả phải ít hơn %1$s kí tự."
+
+#. %1$s is the name of the collection
+#: controllers/collections_controller.php:392
+msgid "collection_detail_rss_title"
+msgstr "Bộ sưu tập %s"
+
+#: controllers/collections_controller.php:1065
+msgid "collection_error_deleting_addon"
+msgstr "Gặp lỗi khi xóa tiện ích!"
+
+#: controllers/collections_controller.php:1051
+msgid "collection_error_saving_addon"
+msgstr "Gặp lỗi khi lưu tiện ích!"
+
+#: controllers/collections_controller.php:1080
+msgid "collection_error_saving_comment"
+msgstr "Gặp lỗi khi lưu bình luận!"
+
+#. %1$s is a number.
+#: models/collection.php:122
+msgid "collection_name_limit"
+msgstr "Tên phải ít hơn %1$s kí tự."
+
+#: controllers/collections_controller.php:352
+#: controllers/collections_controller.php:487
+msgid "collection_not_found"
+msgstr "Không tìm thấy bộ sưu tập!"
+
+#. %1$s is the text on the "create collection" button
+#: views/collections/add.thtml:91
+msgid "collections_add_formfield_addons_description"
+msgstr "Nếu bạn đã biết tiện ích nào mà mình muốn thêm vào bá»™ sÆ°u tập, chỉ cần gõ tên của chúng ở bên dÆ°á»›i. Nếu bạn muốn đợi và làm việc này sau, chỉ cần nhấn %1$s ngay bây giá»."
+
+#: views/collections/add.thtml:90
+msgid "collections_add_formfield_firstaddons"
+msgstr "Chá»n các tiện ích đầu tiên của bạn"
+
+#: views/collections/add.thtml:48
+msgid "collections_add_header"
+msgstr "Tạo một Bộ sưu tập"
+
+#: views/collections/add.thtml:97
+msgid "collections_add_header_selectedaddons"
+msgstr "Tiện ích Äã chá»n"
+
+#: views/collections/add.thtml:50
+msgid "collections_add_intro"
+msgstr "Thật dá»… dàng tạo ra bá»™ sÆ°u tập các tiện ích của riêng bạn bằng cách Ä‘iá»n vào các khung bên dÆ°á»›i."
+
+#: views/collections/add.thtml:92
+#: views/collections/add.thtml:103
+msgid "collections_add_submit"
+msgstr "Tạo mới Bộ sưu tập"
+
+#: views/pages/collector_faq.thtml:50
+#: views/pages/collector_firstrun.thtml:43
+#: views/pages/collector.thtml:47
+#: views/pages/collector_features.thtml:55
+#: controllers/search_controller.php:302
+#: controllers/collections_controller.php:206
+#: controllers/collections_controller.php:405
+#: controllers/collections_controller.php:467
+#: controllers/collections_controller.php:539
+msgid "collections_breadcrumb"
+msgstr "Bộ sưu tập"
+
+#: views/collections/detail.thtml:185
+msgid "collections_detail_a_learn"
+msgstr "Tìm hiểu Thêm"
+
+#: views/elements/amo2009/collection_add_form.thtml:53
+#: views/elements/amo2009/collections_js_init.thtml:68
+#: views/pages/collector_firstrun.thtml:64
+msgid "collections_detail_button_add"
+msgstr "Thêm vào Ưa thích"
+
+#: views/elements/amo2009/collection_add_form.thtml:50
+#: views/elements/amo2009/collections_js_init.thtml:71
+msgid "collections_detail_button_remove"
+msgstr "Xóa khá»i Ưa thích"
+
+#. %1$s is a URL.
+#. %2$s is a full <a href>.
+#: views/collections/detail.thtml:62
+msgid "collections_detail_created_desc"
+msgstr "<p>Bạn có thể xem bộ sưu tập mới của mình ở dưới. Nếu bạn muốn đặt một biệt hiệu, tải lên biểu tượng, hoặc thay đổi thiết lập phụ, vui lòng vào trang <a href='%1$s'>Quản lí Bộ sưu tập</a>.</p><p>Bộ sưu tập có thể được truy cập tại địa chỉ: %2$s</p>"
+
+#: views/collections/detail.thtml:61
+msgid "collections_detail_created_msg"
+msgstr "Bộ sưu tập của bạn đã sẵn sàng!"
+
+#: views/collections/detail.thtml:109
+msgid "collections_detail_header_about"
+msgstr "Thông tin vỠBộ sưu tập này"
+
+#. %1$s is a number.
+#: views/collections/detail.thtml:126
+msgid "collections_detail_header_count"
+msgid_plural "collections_detail_header_count"
+msgstr[0] "%1$s Tiện ích trong Bộ sưu tập"
+msgstr[1] "%1$s Tiện ích trong Bộ sưu tập"
+
+#: views/collections/detail.thtml:113
+msgid "collections_detail_info_created"
+msgstr "<strong>Tạo bởi:</strong> %1$s"
+
+#: views/collections/detail.thtml:117
+msgid "collections_detail_info_updated"
+msgstr "<strong>Cập nhật:</strong>"
+
+#: views/elements/amo2009/collections_js_init.thtml:62
+msgid "collections_detail_js_adding"
+msgstr "Thêm vào Ưa thích&hellip;"
+
+#: views/elements/amo2009/collections_js_init.thtml:65
+msgid "collections_detail_js_removing"
+msgstr "Xóa Ưa thích&hellip;"
+
+#. %1$s is a URL
+#: views/collections/detail.thtml:90
+msgid "collections_detail_login"
+msgstr "<a href=\"%1$s\">Äăng nhập</a> để thêm bá»™ sÆ°u tập này vào danh sách Æ°a thích của bạn."
+
+#: views/collections/detail.thtml:104
+msgid "collections_detail_manage"
+msgstr "Quản lí Bộ sưu tập"
+
+#: controllers/collections_controller.php:298
+msgid "collections_detail_sort_date"
+msgstr "Ngày thêm"
+
+#: controllers/collections_controller.php:299
+msgid "collections_detail_sort_name"
+msgstr "Tên"
+
+#: controllers/collections_controller.php:300
+msgid "collections_detail_sort_popularity"
+msgstr "Thông dụng"
+
+#. %1$s is a number.
+#: views/collections/detail.thtml:166
+msgid "collections_detail_weekly_downloads"
+msgid_plural "collections_detail_weekly_downloads"
+msgstr[0] "%1$s lượt tải tuần này"
+msgstr[1] "%1$s lượt tải tuần này"
+
+#: views/collections/edit.thtml:255
+msgid "collections_edit_addons_delete_noscript"
+msgstr "Các tiện ích đã chá»n sẽ bị xóa khi LÆ°u"
+
+#: views/collections/edit.thtml:247
+msgid "collections_edit_addons_description"
+msgstr "Äể xuất bản các tiện ích má»›i vào bá»™ sÆ°u tập này, hãy bắt đầu gõ tên của chúng ở bên dÆ°á»›i."
+
+#: views/collections/edit.thtml:248
+msgid "collections_edit_addons_description_noscript"
+msgstr "Äể xuất bản các tiện ích má»›i vào bá»™ sÆ°u tập này, hãy nhập má»™t danh sách ID Tiện ích được ngăn cách bởi dấu phẩy ở bên dÆ°á»›i."
+
+#: views/collections/edit.thtml:247
+#: views/collections/edit.thtml:248
+msgid "collections_edit_addons_description_publish_detailspage"
+msgstr "Bạn cÅ©ng có thể xuất bản má»™t tiện ích từ trang liệt kê thông thÆ°á»ng của nó."
+
+#. %1$s is the date the add-on was added to the collection
+#. %1$s is the name of the user who added the add-on to the collection
+#: views/collections/edit.thtml:260
+msgid "collections_edit_addons_listitem_added"
+msgstr "Äã thêm %1$s bởi %2$s"
+
+#: views/collections/edit.thtml:263
+msgid "collections_edit_addons_listitem_comment_add"
+msgstr "Thêm bình luận của ngÆ°á»i xuất bản"
+
+#: views/collections/edit.thtml:266
+msgid "collections_edit_addons_listitem_comment_delete"
+msgstr "Xóa bình luận của ngÆ°á»i xuất bản"
+
+#: views/collections/edit.thtml:265
+msgid "collections_edit_addons_listitem_comment_edit"
+msgstr "Chỉnh sá»­a bình luận của ngÆ°á»i xuất bản"
+
+#: views/collections/edit.thtml:271
+msgid "collections_edit_addons_listitem_comment_note"
+msgstr "LÆ°u ý: Bình luận sẽ xuất hiện nhÆ° thể được viết bởi ngÆ°á»i xuất bản gốc vào ngày xuất bản"
+
+#: views/collections/edit.thtml:270
+msgid "collections_edit_addons_listitem_comment_submit"
+msgstr "Lưu bình luận"
+
+#: views/collections/edit.thtml:261
+msgid "collections_edit_addons_listitem_remove"
+msgstr "Xóa"
+
+#: views/collections/edit.thtml:250
+msgid "collections_edit_addons_submit"
+msgstr "Thêm vào Bộ sưu tập"
+
+#: views/collections/edit.thtml:153
+msgid "collections_edit_check_nickname"
+msgstr "Kiểm tra Tính khả thi"
+
+#: views/collections/edit.thtml:299
+msgid "collections_edit_confirm_deletecollection"
+msgstr "Có, tôi muốn xóa bộ sưu tập này."
+
+#. %1$s is the label of the edit form's submit button
+#: views/collections/edit.thtml:300
+msgid "collections_edit_confirm_deletecollection_description"
+msgstr "Hãy chá»n há»™p này, rồi nhấn \"%1$s\" để xóa bá»™ sÆ°u tập này."
+
+#. %1$s is the "delete" submit button text
+#. %2$s is the title of the "advanced" tab
+#: views/collections/edit.thtml:95
+msgid "collections_edit_delete_upon_submit"
+msgstr "Ngay khi nhấn \"%1$s\" bên dÆ°á»›i, bá»™ sÆ°u tập của bạn sẽ bị xóa. Nếu bạn không muốn xóa bá»™ sÆ°u tập của mình, hãy bá» chá»n há»™p xác nhận trong thẻ \"%2$s\" và tiếp tục chỉnh sá»­a bá»™ sÆ°u tập. Nếu bạn rá»i trang này mà không lÆ°u, bá»™ sÆ°u tập cÅ©ng sẽ không bị xóa."
+
+#: views/collections/edit.thtml:94
+msgid "collections_edit_delete_warning"
+msgstr "Bộ sưu tập của bạn sắp sửa bị xóa!"
+
+#: views/collections/add.thtml:76
+#: views/collections/edit.thtml:144
+msgid "collections_edit_form_error_description"
+msgstr "Bạn phải cung cấp một mô tả cho bộ sưu tập của bạn."
+
+#: views/collections/edit.thtml:181
+msgid "collections_edit_form_error_icon"
+msgstr "Có một lỗi khi đang tải lên biểu tượng của bạn."
+
+#: views/collections/add.thtml:69
+#: views/collections/edit.thtml:130
+msgid "collections_edit_form_error_name"
+msgstr "Bạn phải đặt tên cho bộ sưu tập."
+
+#: views/collections/edit.thtml:158
+msgid "collections_edit_form_error_nickname"
+msgstr "Nếu bạn chá»n má»™t biệt hiệu, nó phải là Ä‘á»™c nhất."
+
+#: views/collections/add.thtml:93
+#: views/collections/edit.thtml:249
+msgid "collections_edit_formfield_addons"
+msgstr "Tên tiện ích:"
+
+#: views/collections/edit.thtml:281
+msgid "collections_edit_formfield_application"
+msgstr "Chương trình Kết hợp"
+
+#: views/collections/edit.thtml:282
+msgid "collections_edit_formfield_application_description"
+msgstr "Chá»n chÆ°Æ¡ng trình mà bá»™ sÆ°u tập của bạn há»— trợ."
+
+#: views/collections/edit.thtml:288
+msgid "collections_edit_formfield_collectiontype"
+msgstr "Kiểu của Bộ sưu tập"
+
+#: views/collections/edit.thtml:295
+msgid "collections_edit_formfield_deletecollection"
+msgstr "Xóa bộ sưu tập"
+
+#: views/collections/edit.thtml:296
+msgid "collections_edit_formfield_deletecollection_description"
+msgstr "Xóa bộ sưu tập của bạn cũng sẽ xóa nó vĩnh viễn."
+
+#: views/collections/add.thtml:73
+#: views/collections/edit.thtml:140
+msgid "collections_edit_formfield_description"
+msgstr "Mô tả Bộ sưu tập"
+
+#: views/collections/add.thtml:74
+#: views/collections/edit.thtml:141
+msgid "collections_edit_formfield_description_description"
+msgstr "Mô tả ngắn gá»n bá»™ sÆ°u tập của bạn và kiểu tiện ích trong nó"
+
+#: views/collections/edit.thtml:162
+msgid "collections_edit_formfield_icon"
+msgstr "Biểu tượng"
+
+#: views/collections/edit.thtml:163
+msgid "collections_edit_formfield_icon_description"
+msgstr "Bạn có thể tải lên một biểu tượng JPG, GIF hoặc PNG, nó sẽ được chỉnh lại thành cỡ 32x32 điểm ảnh."
+
+#: views/collections/add.thtml:80
+#: views/collections/edit.thtml:189
+msgid "collections_edit_formfield_listed"
+msgstr "Ai có thể xem bộ sưu tập của bạn?"
+
+#: views/collections/add.thtml:81
+#: views/collections/edit.thtml:190
+msgid "collections_edit_formfield_listed_description"
+msgstr "Mặc định, các bá»™ sÆ°u tập xuất hiện trong ThÆ° mục Bá»™ sÆ°u tập và có thể được khám phá bởi bất kì ai. Nếu bạn muốn giá»›i hạn bá»™ sÆ°u tập của mình chỉ có thể được xem bởi những ngÆ°á»i được bạn Ä‘Æ°a má»™t liên kết đặc biệt, hãy chá»n tùy chá»n bên dÆ°á»›i."
+
+#: views/collections/add.thtml:84
+#: views/collections/edit.thtml:193
+msgid "collections_edit_formfield_listed_false"
+msgstr "Chỉ những ngÆ°á»i tôi má»i má»›i có thể xem bá»™ sÆ°u tập của tôi"
+
+#: views/collections/add.thtml:83
+#: views/collections/edit.thtml:192
+msgid "collections_edit_formfield_listed_true"
+msgstr "Má»i ngÆ°á»i Ä‘á»u có thể xem bá»™ sÆ°u tập của tôi trong thÆ° mục"
+
+#: views/collections/edit.thtml:223
+msgid "collections_edit_formfield_managers"
+msgstr "Ai có thể quản lí bộ sưu tập của tôi?"
+
+#: views/collections/edit.thtml:224
+msgid "collections_edit_formfield_managers_description"
+msgstr "Những ngÆ°á»i dùng này có thể xuất bản các tiện ích vào bá»™ sÆ°u tập của bạn, quản lí tất cả các tiện ích và thiết lập, và trao quyá»n cho ngÆ°á»i dùng khác."
+
+#: views/collections/add.thtml:66
+#: views/collections/edit.thtml:126
+msgid "collections_edit_formfield_name"
+msgstr "Tên bộ sưu tập"
+
+#: views/collections/add.thtml:67
+#: views/collections/edit.thtml:127
+msgid "collections_edit_formfield_name_description"
+msgstr "Äặt má»™t tên có tính mô tả cho bá»™ sÆ°u tập, ví dụ nhÆ° \"Tiện ích Du lịch Ưa thích của Mạnh Hùng\""
+
+#: views/collections/edit.thtml:148
+msgid "collections_edit_formfield_nickname"
+msgstr "Biệt hiệu Bộ sưu tập"
+
+#: views/collections/edit.thtml:149
+msgid "collections_edit_formfield_nickname_description"
+msgstr "Thêm vào đó, nên đặt một biệt hiệu riêng biệt cho bộ sưu tập của bạn để truy cập nhanh:"
+
+#: views/collections/edit.thtml:201
+msgid "collections_edit_formfield_publishers"
+msgstr "Ai có thể xuất bản tiện ích vào bộ sưu tập của bạn?"
+
+#: views/collections/edit.thtml:202
+msgid "collections_edit_formfield_publishers_description"
+msgstr "Những ngÆ°á»i dùng này có thể xuất bản các tiện ích vào bá»™ sÆ°u tập của bạn và xóa các tiện ích mà há» xuất bản."
+
+#: views/collections/edit.thtml:210
+#: views/collections/edit.thtml:232
+msgid "collections_edit_formfield_users_add"
+msgstr "Nhập địa chỉ email của một tài khoản Tiện ích Firefox:"
+
+#: views/collections/edit.thtml:216
+#: views/collections/edit.thtml:238
+msgid "collections_edit_formfield_users_delete_noscript"
+msgstr "Các tài khoản đã chá»n sẽ bị xóa ngay khi LÆ°u"
+
+#: views/collections/edit.thtml:215
+#: views/collections/edit.thtml:237
+msgid "collections_edit_formfield_users_new_noscript"
+msgstr "Nhập một danh sách địa chỉ email tài khoản Tiện ích Firefox ngăn cách bởi dấu phẩy"
+
+#: views/collections/edit.thtml:204
+#: views/collections/edit.thtml:226
+msgid "collections_edit_formfield_users_onlyme"
+msgstr "Chỉ mình tôi"
+
+#: views/collections/edit.thtml:205
+#: views/collections/edit.thtml:227
+msgid "collections_edit_formfield_users_otherusers"
+msgstr "Tôi và những ngÆ°á»i dùng này:"
+
+#: views/collections/edit.thtml:211
+#: views/collections/edit.thtml:233
+msgid "collections_edit_formfield_users_submit"
+msgstr "Thêm"
+
+#. %1$s is the name of the collection
+#: views/collections/edit.thtml:68
+msgid "collections_edit_header"
+msgstr "Quản lí %1$s"
+
+#: views/collections/edit.thtml:246
+msgid "collections_edit_header_addons"
+msgstr "Quản lí Nội dung Bộ sưu tập"
+
+#: views/collections/edit.thtml:253
+#: views/collections/edit.thtml:258
+msgid "collections_edit_header_addons_current"
+msgstr "Tiện ích Hiện tại:"
+
+#: views/collections/edit.thtml:279
+msgid "collections_edit_header_advanced"
+msgstr "Thiết lập Nâng cao"
+
+#: views/collections/edit.thtml:186
+msgid "collections_edit_header_permissions"
+msgstr "Quản lí Quyá»n hạn Bá»™ sÆ°u tập"
+
+#: views/collections/edit.thtml:170
+msgid "collections_edit_icon_cancel"
+msgstr "Hủy bá»"
+
+#: views/collections/edit.thtml:174
+#: views/collections/edit.thtml:179
+msgid "collections_edit_icon_delete"
+msgstr "Xóa biểu tượng"
+
+#: views/collections/edit.thtml:178
+msgid "collections_edit_icon_replace"
+msgstr "Thay thế Biểu tượng"
+
+#. %1$s is the label of the edit form's submit button
+#: views/collections/edit.thtml:169
+msgid "collections_edit_icon_toberemoved"
+msgstr "Biểu tượng sẽ bị xóa khi \"%1$s\" được nhấn bên dưới"
+
+#: views/collections/edit.thtml:155
+msgid "collections_edit_nickname_available"
+msgstr "Biệt hiệu Khả thi"
+
+#: controllers/collections_controller.php:943
+msgid "collections_edit_nickname_error"
+msgstr "Biệt hiệu của bạn chứa các kí tự không hợp lệ nên đã được sửa. Vui lòng thử lại."
+
+#: views/collections/edit.thtml:156
+msgid "collections_edit_nickname_taken"
+msgstr "Biệt hiệu Äã bị lấy"
+
+#. This string is followed by a URL pointing to the collection's view page
+#: views/collections/edit.thtml:75
+msgid "collections_edit_saved_nextstep"
+msgstr "Bộ sưu tập của bạn có thể được truy cập tại địa chỉ này:"
+
+#: views/collections/edit.thtml:74
+msgid "collections_edit_saved_success"
+msgstr "Bộ sưu tập đã được lưu thành công!"
+
+#: views/collections/edit.thtml:169
+#: views/collections/edit.thtml:300
+#: views/collections/edit.thtml:308
+#: views/pages/js_constants.js.thtml:99
+msgid "collections_edit_submit"
+msgstr "Cập nhật Bộ sưu tập"
+
+#: views/collections/edit.thtml:96
+#: views/collections/edit.thtml:297
+#: views/pages/js_constants.js.thtml:100
+msgid "collections_edit_submit_deletecollection"
+msgstr "Xóa bộ sưu tập"
+
+#: views/collections/edit.thtml:111
+msgid "collections_edit_tabheader_addons"
+msgstr "Tiện ích"
+
+#: views/collections/edit.thtml:97
+#: views/collections/edit.thtml:113
+msgid "collections_edit_tabheader_advanced"
+msgstr "Nâng cao"
+
+#: views/collections/edit.thtml:108
+msgid "collections_edit_tabheader_details"
+msgstr "Tên &amp; Chi tiết"
+
+#: views/collections/edit.thtml:109
+msgid "collections_edit_tabheader_permissions"
+msgstr "Quyá»n hạn"
+
+#: models/collection_promo.php:53
+msgid "collections_family_tagline"
+msgstr "Trông chừng con cái và bộ lịch của bạn"
+
+#: models/collection_promo.php:53
+msgid "collections_family_title"
+msgstr "Gia đình"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:70
+msgid "collections_index_a_check_out"
+msgstr "Hãy thử Add-on Collector (Trình sưu tập Tiện ích)"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:52
+msgid "collections_index_a_create"
+msgstr "Tạo một Bộ sưu tập"
+
+#: views/collections/detail.thtml:139
+#: views/collections/listing.thtml:85
+#: views/search/collections.thtml:84
+msgid "collections_index_button_go"
+msgstr "Gá»­i"
+
+#. %1$s is a URL.
+#: controllers/collections_controller.php:182
+msgid "collections_index_filler_favorites"
+msgstr "<p><strong>Bạn chưa có bộ sưu tập ưa thích nào.</strong></p> <p>Các bộ sưu tập mà bạn đánh dấu là ưa thích có thể được truy cập nhanh từ trang này, và sẽ xuất hiện trong <a href='%1$s'>Trình sưu tập Tiện ích</a> nếu bạn đã có cài đặt nó.</p>"
+
+#. %1$s is a URL.
+#: controllers/collections_controller.php:167
+msgid "collections_index_filler_mine"
+msgstr "<p>Bạn chưa tạo bộ sưu tập nào. Các bộ sưu tập có thể dễ dàng được tạo và chứa đầy các tiện ích ưa thích của bạn. <a href='%1$s'>Hãy thử ngay</a>!</p>"
+
+#: views/collections/listing.thtml:51
+msgid "collections_index_header_collections"
+msgstr "Bộ sưu tập"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:60
+msgid "collections_index_header_collector"
+msgstr "Trình sưu tập Tiện ích"
+
+#. %1$s is a comma-separated list of author names
+#: views/elements/amo2009/collection_listing_item.thtml:84
+#: views/collections/detail.thtml:151
+msgid "collections_index_header_created"
+msgstr "tạo bởi %1$s"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:47
+msgid "collections_index_header_what"
+msgstr "Bộ sưu tập là gì?"
+
+#: views/collections/detail.thtml:132
+#: views/collections/listing.thtml:78
+#: views/search/collections.thtml:66
+msgid "collections_index_label_sortby"
+msgstr "Sắp xếp theo"
+
+#: controllers/collections_controller.php:130
+msgid "collections_index_li_editors"
+msgstr "Lá»±a chá»n của Biên tập viên"
+
+#: views/collections/subscribe.thtml:64
+#: controllers/collections_controller.php:140
+msgid "collections_index_li_favorites"
+msgstr "Ưa thích của Tôi"
+
+#: controllers/collections_controller.php:138
+msgid "collections_index_li_mine"
+msgstr "Bộ sưu tập của Tôi"
+
+#: controllers/collections_controller.php:132
+msgid "collections_index_li_popular"
+msgstr "Thông dụng"
+
+#: views/search/collections.thtml:74
+#: controllers/collections_controller.php:81
+msgid "collections_index_option_all"
+msgstr "Thông dụng nhất từ trước đến nay"
+
+#: views/search/collections.thtml:72
+#: controllers/collections_controller.php:78
+msgid "collections_index_option_month"
+msgstr "Thông dụng nhất tháng này"
+
+#: views/search/collections.thtml:76
+#: controllers/collections_controller.php:84
+msgid "collections_index_option_newest"
+msgstr "Mới nhất"
+
+#: views/search/collections.thtml:70
+#: controllers/collections_controller.php:75
+msgid "collections_index_option_week"
+msgstr "Thông dụng nhất tuần này"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:67
+msgid "collections_index_p_collector"
+msgstr "Có một cách mới để quản lí và tìm các tiện ích ưa thích. Bình luận, chia sẻ và đồng bộ các bộ sưu tập, từ ngay trong trình duyệt của bạn"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:48
+msgid "collections_index_p_what_are"
+msgstr "Các bộ sưu tập là nhóm gồm các tiện ích liên quan được kết hợp để chia sẻ dễ dàng."
+
+#. %s is a date in the _('date') format
+#: views/elements/collections_interactive_addon.thtml:85
+#, php-format
+msgid "collections_interactive_addon_added"
+msgstr "Äã thêm %s"
+
+#: models/collection_promo.php:55
+msgid "collections_reference_tagline"
+msgstr "Thực hiện nghiên cứu trực tuyến"
+
+#: models/collection_promo.php:55
+msgid "collections_reference_title"
+msgstr "Tham khảo"
+
+#: models/collection_promo.php:52
+msgid "collections_social_tagline"
+msgstr "Quản lí mạng xã hội của bạn"
+
+#: models/collection_promo.php:52
+msgid "collections_social_title"
+msgstr "Mạng xã hội"
+
+#: views/collections/subscribe.thtml:91
+msgid "collections_subscribe_button_close"
+msgstr "Äóng"
+
+#: views/collections/subscribe.thtml:70
+msgid "collections_subscribe_error"
+msgstr "Một lỗi đã xảy ra khi đang cố thêm một bộ sưu tập ưa thích. Có phải bộ sưu tập này đã được đánh dấu là ưa thích rồi?"
+
+#: views/collections/subscribe.thtml:96
+msgid "collections_subscribe_label_bothersome"
+msgstr "Không hiện thông báo này nữa."
+
+#. %1$s is the collection name
+#: views/collections/subscribe.thtml:60
+msgid "collections_subscribe_success"
+msgstr "%1$s vừa được thêm vào danh sách bộ sưu tập ưa thích của bạn."
+
+#. %1$s is the link to the "My Favorites" tab on the main collections page
+#. %2$s is the localized title of the "My Favorites" tab
+#. %3$s is the link URL to the collector add-on
+#: views/collections/subscribe.thtml:62
+msgid "collections_subscribe_success_desc"
+msgstr "Bây giỠbạn có thể nhanh chóng tìm thấy bộ sưu tập này từ thẻ <a href=\"%1$s\">%2$s</a> trong thư mục. Nếu muốn theo dõi các bộ sưu tập ưa thích dễ dàng hơn, hãy thử phần mở rộng <a href=\"%3$s\">Trình sưu tập Tiện ích</a> cho Firefox."
+
+#: views/collections/listing.thtml:55
+msgid "collections_success_delete"
+msgstr "Bộ sưu tập đã được xóa."
+
+#: models/collection_promo.php:54
+msgid "collections_travel_tagline"
+msgstr "Lập kế hoạch cho những chuyến du ngoạn và kì nghỉ đáng nhớ"
+
+#: models/collection_promo.php:54
+msgid "collections_travel_title"
+msgstr "Du lịch"
+
+#. A collection of add-ons that is automatically built for a user. They are "automatically published" to this collection.
+#: controllers/collections_controller.php:581
+msgid "collections_type_autopublisher"
+msgstr "Tự động Xuất bản"
+
+#. A collection that has been chosen by an Editor as notable or exceptional
+#: controllers/collections_controller.php:582
+msgid "collections_type_editorspick"
+msgstr "Lá»±a chá»n của Biên tập viên"
+
+#: controllers/collections_controller.php:580
+msgid "collections_type_normal"
+msgstr "Bình thÆ°á»ng"
+
+#: views/collections/subscribe.thtml:84
+msgid "collections_unsubscribe_error"
+msgstr "Một lỗi đã xảy ra khi đang cố xóa một bộ sưu tập ưa thích. Có phải bộ sưu tập này vốn đã không nằm trong danh sách ưa thích?"
+
+#. %1$s is the collection name
+#: views/collections/subscribe.thtml:78
+msgid "collections_unsubscribe_success"
+msgstr "%1$s vừa bị xóa khá»i danh sách bá»™ sÆ°u tập Æ°a thích của bạn."
+
+#: models/collection_promo.php:56
+msgid "collections_webdev_tagline"
+msgstr "Xây dựng trang web hoàn hảo"
+
+#: models/collection_promo.php:56
+msgid "collections_webdev_title"
+msgstr "Phát triển Web"
+
+#: views/elements/amo2009/collections_sidebar_whatare.thtml:40
+msgid "collections_whatare_header"
+msgstr "Bộ sưu tập là gì?"
+
+#: views/elements/amo2009/collections_sidebar_whatare.thtml:45
+msgid "collections_whatare_learnmore"
+msgstr "Äá»c FAQ"
+
+#: views/elements/amo2009/collections_sidebar_whatare.thtml:44
+msgid "collections_whatare_text"
+msgstr "Có một cách mới để quản lí và tìm các tiện ích ưa thích. Bình luận, chia sẻ và đồng bộ các bộ sưu tập, ngay trong trình duyệt của bạn."
+
+#: views/pages/collector_faq.thtml:61
+#: views/pages/collector_features.thtml:67
+msgid "collector_features_a_home"
+msgstr "Trang chủ Trình sưu tập Tiện ích"
+
+#: views/elements/amo2009/collector_sidebar_download.thtml:46
+msgid "collector_features_heading_download"
+msgstr "Tải xuống Trình sưu tập Tiện ích:"
+
+#: views/elements/amo2009/collector_sidebar_download.thtml:43
+#: views/pages/collector_firstrun.thtml:116
+#: views/pages/collector.thtml:69
+msgid "collector_features_img_logo"
+msgstr "Biểu trưng Trình sưu tập Tiện ích"
+
+#: views/compatibility/dashboard.thtml:49
+#: controllers/compatibility_controller.php:72
+msgid "compatibility_dashboard_center_header"
+msgstr "Trung tâm Tính tương thích Tiện ích"
+
+#. %1$s is the name of an application and a version. Example: Firefox 3.0
+#. %2$s is the name of an application. Example: Firefox
+#: views/compatibility/dashboard.thtml:50
+msgid "compatibility_dashboard_intro"
+msgstr "Sẵn sàng cho lần phát hành %1$s vá»›i các công cụ và thông tin cho cá»™ng đồng Tiện Ãch %2$s ở bên dÆ°á»›i."
+
+#: views/compatibility/dashboard.thtml:103
+msgid "compatibility_dashboard_loading"
+msgstr "Äang tải dữ liệu..."
+
+#: views/compatibility/dashboard.thtml:45
+msgid "compatibility_dashboard_main_link"
+msgstr "Trở vỠTrang Chính"
+
+#: views/compatibility/dashboard.thtml:100
+#: views/compatibility/report.thtml:43
+msgid "compatibility_dashboard_report"
+msgstr "Báo cáo Tính tương thích Tiện ích"
+
+#: views/compatibility/dashboard.thtml:53
+#: views/compatibility/dashboard.thtml:110
+#: views/compatibility/developers.thtml:43
+msgid "compatibility_developer_info"
+msgstr "Thông tin cho Nhà phát triển Tiện ích"
+
+#: views/compatibility/developers.thtml:66
+msgid "compatibility_developers_adjust_maxversion"
+msgstr "Äiá»u chỉnh maxVersion mà không cần tải lên"
+
+#: views/compatibility/dashboard.thtml:124
+msgid "compatibility_developers_check_status"
+msgstr "Kiểm tra Trạng thái của Tiện ích của Tôi"
+
+#. %1$s is a URL
+#. %2$s is an application and version. Example: Firefox 3.0
+#: views/compatibility/dashboard.thtml:126
+msgid "compatibility_developers_login_first"
+msgstr "Nếu bạn có tiện ích được lÆ°u trữ trên Tiện Ãch Mozilla, <a href=\"%1$s\">vui lòng đăng nhập</a> để phân tích trạng thái tiện ích của bạn cho %2$s."
+
+#: views/compatibility/dashboard.thtml:114
+msgid "compatibility_developers_mdclogo_alt"
+msgstr "Biểu trưng Trung tâm Nhà phát triển Mozilla"
+
+#: views/compatibility/developers.thtml:73
+msgid "compatibility_developers_no_addons"
+msgstr "Bạn không có tiện ích nào được lÆ°u trữ trên Tiện Ãch Mozilla."
+
+#: views/compatibility/dashboard.thtml:133
+#: views/compatibility/developers.thtml:55
+msgid "compatibility_developers_results"
+msgstr "Kết quả Kiểm tra Trạng thái Tiện ích"
+
+#: views/compatibility/dashboard.thtml:137
+msgid "compatibility_developers_retrieving"
+msgstr "Äang thu thập trạng thái của các tiện ích được lÆ°u trữ..."
+
+#. %1$s is a number
+#. %2$s is an application name
+#. %3$s is a number.
+#. Full example: 50 Firefox users (10% of total)
+#: views/compatibility/developers.thtml:65
+msgid "compatibility_developers_user_count"
+msgstr "%1$s ngÆ°á»i dùng %2$s (%3$s&#37; trên tổng số)"
+
+#: views/compatibility/report.thtml:45
+msgid "compatibility_report_detail_intro"
+msgstr "Các tiện ích bên dưới chiếm 95% số lượng sử dụng tiện ích của Mozilla và được sắp xếp theo khối lượng sử dụng."
+
+#: views/compatibility/dashboard.thtml:94
+msgid "compatibility_report_detailed_link"
+msgstr "Hiển thị Báo cáo Chi tiết"
+
+#. %1$s and %2$s are numbers
+#. %3$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:65
+msgid "compatibility_report_intro"
+msgstr "Trong số %1$s tiện ích chiếm 95&#37; lượng sử dụng tiện ích của Mozilla, <b>%2$s&#37;</b> tương thích với các bản xây dựng hiện tại của %3$s."
+
+#: views/compatibility/dashboard.thtml:81
+msgid "compatibility_report_legend_alpha"
+msgstr "Phiên bản Alpha"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:81
+msgid "compatibility_report_legend_alpha_description"
+msgstr "Các tiện ích tương thích với phiên bản alpha của %1$s"
+
+#: views/compatibility/dashboard.thtml:85
+msgid "compatibility_report_legend_beta"
+msgstr "Phiên bản Beta"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:85
+msgid "compatibility_report_legend_beta_description"
+msgstr "Các tiện ích tương thích với phiên bản beta hoặc ứng cử phát hành của %1$s"
+
+#: views/compatibility/dashboard.thtml:89
+msgid "compatibility_report_legend_latest"
+msgstr "Phiên bản Mới nhất"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:89
+msgid "compatibility_report_legend_latest_description"
+msgstr "Các tiện ích cập nhật theo các bản xây dựng của %1$s"
+
+#: views/compatibility/dashboard.thtml:77
+msgid "compatibility_report_legend_other"
+msgstr "Phiên bản Khác"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:77
+msgid "compatibility_report_legend_other_description"
+msgstr "Các tiện ích không tương thích với bất kì phiên bản nào của %1$s"
+
+#: views/compatibility/dashboard.thtml:62
+msgid "compatibility_report_title"
+msgstr "Báo cáo Tính tương thích Tiện ích"
+
+#: views/compatibility/dashboard.thtml:54
+#: views/compatibility/dashboard.thtml:144
+#: views/compatibility/users.thtml:42
+msgid "compatibility_user_info"
+msgstr "Thông tin cho NgÆ°á»i dùng Tiện ích"
+
+#: views/compatibility/dashboard.thtml:52
+msgid "compatibility_view_report"
+msgstr "Hiển thị Báo cáo Tính tương thích"
+
+#. %s is a URL
+#: views/pages/credits.thtml:142
+#, php-format
+msgid "credits_contributing"
+msgstr "Äể biết thêm thông tin vá» việc đóng góp, vui lòng xem %s."
+
+#: views/pages/credits.thtml:142
+msgid "credits_contributing_wikipage"
+msgstr "trang wiki"
+
+#: views/pages/credits.thtml:99
+msgid "credits_intro"
+msgstr "Mozilla gá»­i lá»i cảm Æ¡n đến những ngÆ°á»i sau vì sá»± đóng góp của há» cho dá»± án addons.mozilla.org trong các năm qua:"
+
+#: views/pages/credits.thtml:103
+msgid "credits_section_developers"
+msgstr "Nhà phát triển"
+
+#: views/pages/credits.thtml:115
+msgid "credits_section_editors"
+msgstr "Biên tập viên"
+
+#: views/pages/credits.thtml:109
+msgid "credits_section_localizers"
+msgstr "Những ngÆ°á»i làm bản địa hóa"
+
+#: views/pages/credits.thtml:121
+msgid "credits_section_other_contributors"
+msgstr "Những ngÆ°á»i đóng góp khác"
+
+#: views/pages/credits.thtml:127
+msgid "credits_section_past_developers"
+msgstr "Những nhà phát triển trước đây"
+
+#: views/pages/credits.thtml:133
+msgid "credits_section_software"
+msgstr "Phần má»m và Hình ảnh"
+
+#: views/pages/credits.thtml:136
+msgid "credits_software_famfamfam"
+msgstr "Một số biểu tượng được lấy từ <a href=\"http://www.famfamfam.com/lab/icons/silk/\">Bộ biểu tượng Lụa famfamfam</a>, được cấp phép theo <a href=\"http://creativecommons.org/licenses/by/2.5/\">Giấy phép Creative Commons Attribution 2.5</a>."
+
+#: views/pages/credits.thtml:137
+msgid "credits_software_timeplot"
+msgstr "Một số trang sử dụng các thành phần của <a href=\"http://www.simile-widgets.org/timeplot/\">Timeplot</a>, được cấp phép theo <a href=\"http://simile.mit.edu/license.html\">Giấy phép BSD</a>."
+
+#. date format string as used in PHP's strftime():
+#. http://php.net/strftime
+#: views/elements/collections_interactive_addon.thtml:85
+#: views/elements/amo2009/addon_version_detail.thtml:53
+#: views/elements/amo2009/homepage_addon.thtml:115
+#: views/elements/addon_version_detail.thtml:54
+#: views/elements/addon_listitem.thtml:124
+#: views/elements/feature.thtml:106
+#: views/collections/detail.thtml:118
+#: views/collections/edit.thtml:325
+#: views/users/info.thtml:76
+#: views/editors/reviews_queue.thtml:57
+#: views/editors/reviews_queue.thtml:68
+#: views/developers/dashboard.thtml:65
+#: views/developers/versions_edit.thtml:208
+#: views/developers/versions.thtml:67
+#: views/search/rss/index.thtml:5
+#: views/addons/rss/versions.thtml:42
+#: views/addons/display.thtml:104
+#: views/addons/display.thtml:356
+#: views/addons/browse_thumbs.thtml:75
+#: views/reviews/add.thtml:63
+#: views/reviews/display.thtml:74
+#: views/reviews/display.thtml:160
+#: views/reviews/delete.thtml:54
+#: controllers/statistics_controller.php:244
+#: controllers/collections_controller.php:1047
+msgid "date"
+msgstr "%e tháng %m năm %Y"
+
+#. date and time format string (strftime)
+#. http://php.net/strftime
+#: views/elements/addon_version_detail.thtml:53
+#: views/developers/discuss.thtml:52
+#: views/developers/discuss.thtml:62
+#: views/admin/addons_status.thtml:57
+msgid "datetime"
+msgstr "%e tháng %m năm %Y, %I:%M %p"
+
+#: views/elements/developers/actionbar.thtml:47
+msgid "devcp_actionbar_link_details"
+msgstr "Thông tin Chi tiết"
+
+#: views/elements/developers/actionbar.thtml:42
+#: views/elements/developers/actionbar.thtml:50
+#: views/developers/dashboard.thtml:64
+msgid "devcp_actionbar_link_edit"
+msgstr "Chỉnh sửa Tiện ích"
+
+#: views/elements/developers/actionbar.thtml:51
+msgid "devcp_actionbar_link_newversion"
+msgstr "Tải lên Bản Mới"
+
+#: views/elements/developers/actionbar.thtml:44
+#: views/elements/developers/actionbar.thtml:49
+#: views/developers/dashboard.thtml:73
+msgid "devcp_actionbar_link_stats"
+msgstr "Bảng Thống Kê"
+
+#. %1$s is a filename, e.g. "foo.txt"
+#. %2$s is the extension, e.g. ".txt"
+#. %3$s is a list of valid extensions, like ".png, .jpg, .gif"
+#: controllers/developers_controller.php:1361
+msgid "devcp_add_previews_extension_error"
+msgstr "Tập tin %1$s có đuôi mở rộng bất hợp lệ (%2$s). Các đuôi mở rộng được cho phép: %3$s"
+
+#. %s is the filename.
+#: controllers/developers_controller.php:1394
+msgid "devcp_add_previews_save_error"
+msgstr "Không thể lưu tập tin %s vào cơ sở dữ liệu. Vui lòng thử lại lần nữa."
+
+#. %1$s is the preview ID number, %2$s is the filename.
+#: controllers/developers_controller.php:1389
+msgid "devcp_add_previews_success_replace"
+msgstr "Phần xem trước %1$s đã được thay thế bằng tập tin %2$s thành công."
+
+#. %s is the filename.
+#: controllers/developers_controller.php:1391
+msgid "devcp_add_previews_success_upload"
+msgstr "Tập tin %s đã được tải lên thành công. Bạn có thể thêm tiêu đỠở bên dưới."
+
+#: controllers/components/developers.php:1163
+msgid "devcp_additem_addontype_autodetect"
+msgstr "(tá»± Ä‘á»™ng chá»n)"
+
+#: views/elements/developers/additem.thtml:76
+msgid "devcp_additem_linktitle_opensin_newwindow"
+msgstr "Mở trong cửa sổ mới"
+
+#: views/elements/developers/additem.thtml:41
+msgid "devcp_additem_sidebar_title"
+msgstr "Gá»­i Tiện Ãch"
+
+#: views/elements/developers/additem.thtml:53
+msgid "devcp_additem_step0_newlink"
+msgstr "Thá»a thuận Nhà phát triển"
+
+#: views/elements/developers/additem.thtml:46
+msgid "devcp_additem_step1_link"
+msgstr "Bước 1: Tải lên"
+
+#: views/elements/developers/additem.thtml:47
+msgid "devcp_additem_step2_link"
+msgstr "Bước 2: Chi tiết Tiện ích"
+
+#: views/elements/developers/additem.thtml:48
+msgid "devcp_additem_step3_link"
+msgstr "Bước 3: Chi tiết Phiên bản"
+
+#: views/elements/developers/additem.thtml:49
+msgid "devcp_additem_step4_link"
+msgstr "Bước 4: Bản địa hóa"
+
+#: views/elements/developers/additem.thtml:50
+msgid "devcp_additem_step5_link"
+msgstr "Bước 5: Thành công"
+
+#: views/elements/developers/additem.thtml:76
+msgid "devcp_additem_submissionhelp_link"
+msgstr "Trợ giúp Gửi lên"
+
+#: controllers/previews_controller.php:168
+#: controllers/previews_controller.php:277
+msgid "devcp_addon_field_preview_caption_displaytitle"
+msgstr "Tiêu đỠxem trước"
+
+#: views/developers/addon_status.thtml:177
+msgid "devcp_addon_status_action_activate"
+msgstr "Kích hoạt"
+
+#: views/developers/addon_status.thtml:178
+msgid "devcp_addon_status_action_activate_description"
+msgstr "Kích hoạt tiện ích của bạn để cho nó hiện lên trong phần liệt kê công cộng và kích hoạt dịch vụ kiểm tra cập nhật."
+
+#: views/developers/addon_status.thtml:135
+msgid "devcp_addon_status_action_complete"
+msgstr "Hoàn tất Tiện ích"
+
+#: views/developers/addon_status.thtml:136
+msgid "devcp_addon_status_action_complete_description"
+msgstr "Hoàn tất tiện ích của bạn và di chuyển nó qua Hộp cát"
+
+#: views/developers/addon_status.thtml:181
+msgid "devcp_addon_status_action_deactivate"
+msgstr "Ngừng kích hoạt"
+
+#: views/developers/addon_status.thtml:182
+msgid "devcp_addon_status_action_deactivate_description"
+msgstr "Ngừng kích hoạt tiện ích của bạn để ẩn nó khá»i tất cả danh sách liệt kê công cá»™ng và vô hiệu hóa dịch vụ kiểm tra cập nhật."
+
+#: views/developers/addon_status.thtml:143
+msgid "devcp_addon_status_action_move"
+msgstr "Di chuyển vào Hộp cát"
+
+#: views/developers/addon_status.thtml:144
+msgid "devcp_addon_status_action_move_description"
+msgstr "Di chuyển tiện ích của bạn trở lại Hộp cát. Việc này không thể đảo ngược được."
+
+#: views/developers/addon_status.thtml:139
+msgid "devcp_addon_status_action_nominate"
+msgstr "Äá» cá»­ ra Công cá»™ng"
+
+#: views/developers/addon_status.thtml:140
+msgid "devcp_addon_status_action_nominate_description"
+msgstr "Äá» cá»­ tiện ích của bạn trở thành Công cá»™ng"
+
+#: views/developers/addon_status.thtml:147
+msgid "devcp_addon_status_action_public"
+msgstr "Chuyển thành Công cộng"
+
+#: views/developers/addon_status.thtml:148
+msgid "devcp_addon_status_action_public_description"
+msgstr "Chuyển tiện ích của bạn thành Công cộng lần nữa."
+
+#: views/developers/addon_status.thtml:169
+msgid "devcp_addon_status_active"
+msgstr "Tiện ích của bạn Ä‘ang <span class=\"inactive-0\">Hoạt Ä‘á»™ng</span>. Äiá»u này có nghÄ©a là tiệních của bạn Ä‘ang hiện trong tất cả danh sách liệt kê phù hợp vá»›i trạng thái của nó ở trên."
+
+#: views/developers/addon_status.thtml:111
+msgid "devcp_addon_status_completion_disabled"
+msgstr "Vui lòng Ä‘iá»n đầy đủ các tiêu chí ở trên trÆ°á»›c khi bạn hoàn tất tiện ích của mình và di chuyển nó vào <span class=\"status-1\">Há»™p cát</span>."
+
+#: views/developers/addon_status.thtml:108
+msgid "devcp_addon_status_completion_enabled"
+msgstr "Bây giỠbạn có thể hoàn tất tiện ích và di chuyển nó vào <span class=\"status-1\">Hộp cát</span> bằng cách nhấn lên nút bên dưới."
+
+#: views/developers/addon_status.thtml:102
+msgid "devcp_addon_status_criteria_category"
+msgstr "Ãt nhất má»™t phân mục được chá»n"
+
+#: views/developers/addon_status.thtml:101
+msgid "devcp_addon_status_criteria_description"
+msgstr "Cần có Mô tả Tiện ích"
+
+#: views/developers/addon_status.thtml:99
+msgid "devcp_addon_status_criteria_name"
+msgstr "Cần có Tên của Tiện ích"
+
+#: views/developers/addon_status.thtml:120
+msgid "devcp_addon_status_criteria_prerelease"
+msgstr "Tiện ích không được đánh dấu là phát-hành-thử."
+
+#: views/developers/addon_status.thtml:119
+msgid "devcp_addon_status_criteria_preview"
+msgstr "Ãt nhất cần có má»™t ảnh xem trÆ°á»›c cho phần mở rá»™ng và giao diện."
+
+#: views/developers/addon_status.thtml:100
+msgid "devcp_addon_status_criteria_summary"
+msgstr "Cần có Tóm tắt Tiện ích"
+
+#. %s is the status in a span, e.g. "<span>_('Public')</span>".
+#: views/developers/addon_status.thtml:58
+msgid "devcp_addon_status_header"
+msgstr "Trạng thái Tiện ích: %s"
+
+#: views/developers/addon_status.thtml:152
+#: views/developers/addon_status.thtml:173
+msgid "devcp_addon_status_header_actions"
+msgstr "Thao tác Khả thi"
+
+#: views/developers/addon_status.thtml:168
+msgid "devcp_addon_status_header_active"
+msgstr "Trạng thái Hoạt động: <span class=\"inactive-0\">Hoạt động</span>"
+
+#: views/developers/addon_status.thtml:97
+msgid "devcp_addon_status_header_criteria"
+msgstr "Tiêu chí Hoàn tất Tiện ích"
+
+#: views/developers/addon_status.thtml:164
+msgid "devcp_addon_status_header_inactive"
+msgstr "Trạng thái Hoạt động: <span class=\"inactive-1\">Im lìm</span>"
+
+#: views/developers/addon_status.thtml:117
+msgid "devcp_addon_status_header_nomination"
+msgstr "Tiêu chí Äá» cá»­ Công cá»™ng"
+
+#: views/developers/addon_status.thtml:190
+msgid "devcp_addon_status_header_trusted"
+msgstr "Trạng thái Tin cậy: <span class=\"status-4\">Äáng tin</span>"
+
+#: views/developers/addon_status.thtml:165
+msgid "devcp_addon_status_inactive"
+msgstr "Tiện ích của bạn Ä‘ang <span class=\"inactive-1\">Im lìm</span>. Äiá»u này có nghÄ©a là tiện ích của bạn sẽ không hiện trong bất kì liệt kê nào, liên quan đến trạng thái của nó ở trên. Các bản cập nhật sẽ <b>không</b> được cung cấp cho tiện ích của bạn thông qua dịch vụ kiểm tra cập nhật."
+
+#: views/developers/addon_status.thtml:128
+msgid "devcp_addon_status_nominate_disabled"
+msgstr "Vui lòng Ä‘iá»n đầy đủ tiêu chí ở trên trÆ°á»›c khi Ä‘á» cá»­ tiện ích của bạn trở thành <span class=\"status-4\">Công cá»™ng</span>."
+
+#: views/developers/addon_status.thtml:125
+msgid "devcp_addon_status_nominate_enabled"
+msgstr "Bây giỠbạn có thể đỠcử tiện ích của mình trở thành <span class=\"status-4\">Công cộng</span> bằng cách nhấn vào nút bên dưới."
+
+#: views/developers/addon_status.thtml:64
+msgid "devcp_addon_status_public"
+msgstr "Công cộng"
+
+#: views/developers/addon_status.thtml:63
+msgid "devcp_addon_status_sandbox"
+msgstr "Hộp cát"
+
+#. %s is an email address.
+#: views/developers/addon_status.thtml:89
+msgid "devcp_addon_status_switch_disabled"
+msgstr "Tiện ích của bạn đã bị <span class=\"status-5\">Vô hiệu hóa</span> bởi một quản trị viên và không thể sử dụng được. Nếu có thắc mắc, vui lòng email tới %s."
+
+#: views/developers/addon_status.thtml:67
+msgid "devcp_addon_status_switch_incomplete"
+msgstr "Tiện ích của bạn hiện tại Ä‘ang <span class=\"status-0\">Dang dở</span>. Äiá»u này có nghÄ©a là tiện ích của bạn không hiện trên bất kì mục nào của site hoặc dịch vụ kiểm tra cập nhật. Bạn có thể vào trang này để hoàn tất tiện ích của bạn sau khi nó đạt đủ tiêu chí bên dÆ°á»›i cho việc hoàn tất và di chuyển vào <span class=\"status-1\">Há»™p cát</span>."
+
+#. %s is a number, perhaps 42.
+#: views/developers/addon_status.thtml:77
+msgid "devcp_addon_status_switch_nominated"
+msgstr "Tiện ích của bạn hiện đang được đỠcử để trở thành <span class=\"status-4\">Công cộng</span> và đang chỠđánh giá của biên tập viên. Hiện đang có %s tiện ích khác trong danh sách chỠđỠcử."
+
+#. %s is an email address.
+#: views/developers/addon_status.thtml:81
+msgid "devcp_addon_status_switch_pending"
+msgstr "Tiện ích của bạn Ä‘ang bị kẹt. Äáng nhẽ Ä‘iá»u này không thể xảy ra. Vui lòng email tá»›i %s vá»›i ID tiện ích của bạn và thông báo lá»—i này."
+
+#: views/developers/addon_status.thtml:85
+msgid "devcp_addon_status_switch_public"
+msgstr "Tiện ích của bạn đang là <span class=\"status-4\">Công cộng</span>, có nghĩa là nó sẽ hiện trong tất cả liệt kê và tìm kiếm và có thể được tải xuống mà không bị giới hạn. Các bản cập nhật được cung cấp tới tiện ích của bạn thông qua dịch vụ kiểm tra cập nhật."
+
+#: views/developers/addon_status.thtml:71
+#: views/developers/addon_status.thtml:75
+msgid "devcp_addon_status_switch_sandbox"
+msgstr "Tiện ích của bạn Ä‘ang nằm trong <span class=\"status-1\">Há»™p cát</span>, có nghÄ©a là nó sẽ hiện trong liệt kê và tìm kiếm, nhÆ°ng ngÆ°á»i dùng phải đăng nhập để tải nó xuống. Các bản cập nhật <b>không</b> được cung cấp tá»›i tiện ích của bạn thông qua dịch vụ kiểm tra cập nhật."
+
+#. %s is the add-on name.
+#: views/developers/addon_status_nominate.thtml:43
+#: views/developers/addon_status_confirm.thtml:43
+#: views/developers/addon_status.thtml:43
+msgid "devcp_addon_status_title"
+msgstr "Trạng thái %s"
+
+#: views/developers/addon_status.thtml:191
+msgid "devcp_addon_status_trusted"
+msgstr "Tiện ích của bạn là <span class=\"status-4\">Äáng tin</span>. Äiá»u này có nghÄ©a là bạn có thể gá»­i lên các bản cập nhật cho tiện ích của mình mà không cần đánh giá của biên tập viên."
+
+#: views/developers/dashboard.thtml:68
+msgid "devcp_dashboard_active"
+msgstr "Hoạt động"
+
+#. %1$s is the add-on type string
+#. %2$s is Inactive or Active in a <span>
+#. %3$s is the addon's public status (Public, In Sandbox, ...) in a <span>
+#: views/developers/dashboard.thtml:69
+msgid "devcp_dashboard_addontype_status"
+msgstr "%1$s hiện đang %2$s và %3$s"
+
+#: views/developers/dashboard.thtml:67
+msgid "devcp_dashboard_change_status"
+msgstr "Thay đổi Trạng thái"
+
+#. %s is the addons email address.
+#: views/developers/dashboard.thtml:99
+msgid "devcp_dashboard_disabled_questions"
+msgstr "Tiện ích của bạn đã bị vô hiệu hóa bởi một quản trị viên và không thể dùng được. Nếu bạn có thắc mắc, vui lòng email tới %s."
+
+#. %s is the (localized) add-on status string in a span, e.g. "Disabled"
+#: views/developers/dashboard.thtml:98
+msgid "devcp_dashboard_disabled_status"
+msgstr "Trạng thái Tiện ích: %s"
+
+#: views/developers/dashboard.thtml:43
+msgid "devcp_dashboard_header_main"
+msgstr "Bảng Ä‘iá»u khiển của Nhà phát triển"
+
+#: views/developers/dashboard.thtml:110
+msgid "devcp_dashboard_header_welcome"
+msgstr "Chào mừng đến Bảng Ä‘iá»u khiển của Nhà phát triển"
+
+#: views/developers/dashboard.thtml:68
+msgid "devcp_dashboard_inactive"
+msgstr "Im lìm"
+
+#. %s is a date in the _('date') format
+#: views/developers/dashboard.thtml:65
+msgid "devcp_dashboard_last_edited"
+msgstr "Chỉnh sửa lần cuối vào %s"
+
+#: views/developers/dashboard.thtml:111
+msgid "devcp_dashboard_learn"
+msgstr "Bạn hiện không có tiện ích nào được lÆ°u trữ trên Tiện ích Mozilla. Äể tìm hiểu vá» cách thức quy trình hoạt Ä‘á»™ng và gá»­i lên tiện ích đầu tiên của bạn, hãy nhấn vào nút Bắt Äầu ở dÆ°á»›i."
+
+#: views/developers/dashboard.thtml:112
+msgid "devcp_dashboard_start"
+msgstr "Bắt Äầu"
+
+#: views/developers/dashboard.thtml:82
+msgid "devcp_dashboard_versions"
+msgstr "Phiên bản và Tập tin"
+
+#: views/developers/dashboard.thtml:91
+msgid "devcp_dashboard_versions_new"
+msgstr "Tải lên một phiên bản mới"
+
+#. %s is the preview ID number.
+#: controllers/developers_controller.php:1415
+msgid "devcp_delete_previews_error"
+msgstr "Không thể xóa phần xem trÆ°á»›c %s khá»i cÆ¡ sở dữ liệu. Vui lòng thá»­ lại lần nữa."
+
+#. %s is the preview ID number.
+#: controllers/developers_controller.php:1413
+msgid "devcp_delete_previews_success"
+msgstr "Phần xem trước %s đã được xóa thành công."
+
+#: controllers/developers_controller.php:1089
+msgid "devcp_delete_version_priv_error"
+msgstr "Bạn không có thẩm quyá»n xóa các phiên bản hoặc tập tin."
+
+#. %1$s is the count of files, a number
+#. %2$s is a status string like _('Public') or _('Incomplete')
+#: controllers/components/amo.php:549
+msgid "devcp_describe_version_status"
+msgid_plural "devcp_describe_version_status"
+msgstr[0] "%1$s tập tin %2$s"
+msgstr[1] "%1$s tập tin %2$s"
+
+#. %s is a version number. Example: 3.0
+#: views/developers/versions.thtml:65
+#, php-format
+msgid "devcp_details_version"
+msgstr "Phiên bản %s"
+
+#: views/developers/discuss.thtml:68
+msgid "devcp_discuss_addreply_header"
+msgstr "Thêm Trả Lá»i"
+
+#: views/developers/discuss.thtml:57
+msgid "devcp_discuss_allreplies_header"
+msgstr "Trả lá»i"
+
+#. notice when an error occurs saving a discussion reply
+#. %1 is the email address (linked) for the amo-editors list
+#: views/developers/discuss.thtml:70
+msgid "devcp_discuss_error_notice"
+msgstr "Có lá»—i khi Ä‘ang lÆ°u trả lá»i của bạn. Vui lòng liên hệ %1$s vá» vấn Ä‘á» này."
+
+#. %1 is the add-on name, %2 is the add-on's version number currently being reviewed by an editor
+#: views/developers/discuss.thtml:46
+msgid "devcp_discuss_intro"
+msgstr "Một Biên tập viên của Tiện ích Mozilla yêu cầu thêm thông tin vỠphiên bản %2$s của tiện ích %1$s của bạn."
+
+#. %1 is the add-on name
+#: views/developers/discuss.thtml:43
+msgid "devcp_discuss_pagetitle"
+msgstr "Cung cấp thêm Thông tin cho Äánh giá Tiện ích %1$s"
+
+#. submit button text
+#: views/developers/discuss.thtml:79
+msgid "devcp_discuss_submit_reply"
+msgstr "Gá»­i Trả Lá»i"
+
+#: views/developers/discuss.thtml:72
+msgid "devcp_discuss_success_message"
+msgstr "Trả lá»i của bạn đã được lÆ°u thành công. Những ngÆ°á»i tham gia vào thảo luận sẽ được thông báo qua email."
+
+#. in an author/editor discussion about an add-on to be reviewed:
+#. %1 is the commenter's user name (linked).
+#. %2 is the full date the comment was made.
+#: views/developers/discuss.thtml:52
+#: views/developers/discuss.thtml:62
+msgid "devcp_discuss_writtenby"
+msgstr "được viết bởi %1$s vào %2$s"
+
+#: views/developers/addon_edit_authors.thtml:72
+#: views/developers/addon_edit_authors.thtml:81
+msgid "devcp_edit_authors_add_author"
+msgstr "Thêm Tác Giả Mới"
+
+#: views/developers/addon_edit_authors.thtml:96
+msgid "devcp_edit_authors_add_author_button"
+msgstr "Thêm Tác Giả"
+
+#: views/developers/addon_edit_authors.thtml:83
+msgid "devcp_edit_authors_add_email"
+msgstr "Email Tài khoản Tác giả:"
+
+#: views/developers/addon_edit_authors.thtml:98
+msgid "devcp_edit_authors_add_loading"
+msgstr "Kiểm tra email tài khoản..."
+
+#: views/developers/addon_edit_authors.thtml:70
+msgid "devcp_edit_authors_click_save"
+msgstr "Nhấn nút Cập nhật Tác giả bên dưới để lưu."
+
+#: views/developers/addon_edit_authors.thtml:58
+msgid "devcp_edit_authors_header_current"
+msgstr "Tác giả Hiện tại"
+
+#: views/developers/addon_edit_authors.thtml:50
+msgid "devcp_edit_authors_header_manage"
+msgstr "Quản lí Tác giả Tiện ích"
+
+#: views/developers/addon_edit_authors.thtml:93
+msgid "devcp_edit_authors_label_add_listed"
+msgstr "Liệt kê là tác giả trong trang hiển thị công cộng"
+
+#: views/developers/addon_edit_authors.thtml:89
+msgid "devcp_edit_authors_label_developer"
+msgstr "<strong>Nhà phát triển</strong> - Có thể quản lí tất cả khía cạnh của việc liệt kê tiện ích, ngoại trừ việc thêm và xóa các tác giả khác."
+
+#: views/developers/addon_edit_authors.thtml:88
+msgid "devcp_edit_authors_label_owner"
+msgstr "<strong>NgÆ°á»i sở hữu</strong> - Có thể quản lí tất cả khía cạnh của việc liệt kê tiện ích, bao gồm cả việc thêm và xóa các tác giả khác."
+
+#: views/developers/addon_edit_authors.thtml:90
+msgid "devcp_edit_authors_label_viewer"
+msgstr "<strong>NgÆ°á»i quan sát</strong> - Có thể xem thống kê và danh sách liệt kê các nhà phát triển tiện ích nhÆ°ng không thể thay đổi bất kì mục nào."
+
+#. Placeholder for the empty option in a <select>.
+#: views/developers/addon_edit_categories.thtml:69
+msgid "devcp_edit_authors_option_empty"
+msgstr "----------------"
+
+#: views/developers/addon_edit_authors.thtml:86
+msgid "devcp_edit_authors_select_role"
+msgstr "Chá»n má»™t vai trò cho tác giả:"
+
+#. Column name in a table.
+#: views/developers/addon_edit_authors.thtml:62
+msgid "devcp_edit_authors_th_author"
+msgstr "Tác giả"
+
+#. Column name in a table.
+#: views/developers/addon_edit_authors.thtml:64
+msgid "devcp_edit_authors_th_listed"
+msgstr "Liệt kê"
+
+#. Column name in a table.
+#: views/developers/addon_edit_authors.thtml:63
+msgid "devcp_edit_authors_th_role"
+msgstr "Vai trò"
+
+#: views/developers/addon_edit_authors.thtml:77
+msgid "devcp_edit_authors_update_author"
+msgstr "Cập nhật tác giả"
+
+#: views/developers/addon_edit_categories.thtml:99
+msgid "devcp_edit_categories_button_update"
+msgstr "Cập nhật Phân mục"
+
+#: views/developers/addon_edit_categories.thtml:88
+msgid "devcp_edit_categories_does_not_fit"
+msgstr "Tiện ích của tôi không phù hợp với bất kì phân mục nào."
+
+#. %s is the application name (Firefox, Thunderbird).
+#: views/developers/addon_edit_categories.thtml:61
+msgid "devcp_edit_categories_header_application"
+msgstr "Phân mục %s"
+
+#: views/developers/addon_edit_categories.thtml:49
+msgid "devcp_edit_categories_header_manage"
+msgstr "Quản lí Phân mục Tiện ích"
+
+#: views/developers/addon_edit_categories.thtml:91
+msgid "devcp_edit_categories_hover"
+msgstr "Rê chuột lên một phân mục để xem mô tả của nó."
+
+#. %s is the category number (1, 2, 3).
+#: views/developers/addon_edit_categories.thtml:67
+msgid "devcp_edit_categories_label_category_num"
+msgstr "Phân mục %s"
+
+#: views/developers/addon_edit_categories.thtml:94
+#: views/developers/addon_edit_categories.thtml:103
+msgid "devcp_edit_categories_none_available"
+msgstr "Không có phân mục nào cho chương trình và kiểu tiện ích này."
+
+#: views/developers/addon_edit_categories.thtml:86
+msgid "devcp_edit_categories_other"
+msgstr "Chỉ đặt tiện ích của bạn vào phân mục này nếu nó không phù hợp với bất kì phân mục nào."
+
+#. %s is the application name (Firefox, Thunderbird).
+#: views/developers/addon_edit_categories.thtml:63
+msgid "devcp_edit_categories_select_application_categories"
+msgstr "Chá»n tối Ä‘a ba phân mục %s cho tiện ích của bạn"
+
+#: views/developers/addon_edit.thtml:47
+msgid "devcp_edit_dd_manage_authors"
+msgstr "Thêm hoặc xóa những ngÆ°á»i dùng có quyá»n quản lí tiện ích này."
+
+#: views/developers/addon_edit.thtml:49
+msgid "devcp_edit_dd_manage_categories"
+msgstr "Chá»n phân mục tÆ°Æ¡ng ứng cho má»—i chÆ°Æ¡ng trình mà tiện ích của bạn há»— trợ."
+
+#: views/developers/addon_edit.thtml:51
+msgid "devcp_edit_dd_manage_description"
+msgstr "Thêm hoặc sá»­a đổi các bản dịch cho các phần chính sách riêng tÆ°, giấy phép, ngÆ°á»i dùng cuối, mô tả và tóm tắt cho tiện ích của bạn."
+
+#: views/developers/addon_edit.thtml:53
+msgid "devcp_edit_dd_manage_properties"
+msgstr "Thay đổi tên, trang chủ, biểu tượng, và các cỠhiệu khác cho tiện ích của bạn."
+
+#: views/developers/addon_edit_descriptions.thtml:116
+msgid "devcp_edit_description_button_update"
+msgstr "Cập nhật Mô tả"
+
+#: views/developers/addon_edit_descriptions.thtml:115
+msgid "devcp_edit_description_correct_error"
+msgstr "Vui lòng sửa các lỗi được đánh dấu màu đỠở trên."
+
+#: views/developers/addon_edit_descriptions.thtml:51
+msgid "devcp_edit_descriptions_header"
+msgstr "Chỉnh sửa Mô tả Tiện ích"
+
+#: views/developers/addon_edit_descriptions.thtml:94
+msgid "devcp_edit_descriptions_transbox_comments_description"
+msgstr "Bất kì thông tin nào có thể ngÆ°á»i dùng cuối muốn biết mà không phù hợp để Ä‘Æ°a vào mô tả hoặc tóm tắt của tiện ích. Thông thÆ°á»ng dùng cho việc bao gồm thông tin vá» các lá»—i lá»›n đã biết, cách báo lá»—i, ngày phát hành dá»± kiến của phiên bản má»›i, v.v.."
+
+#: views/developers/addon_edit_descriptions.thtml:93
+msgid "devcp_edit_descriptions_transbox_comments_name"
+msgstr "Bình luận của Nhà phát triển"
+
+#: views/developers/addon_edit_descriptions.thtml:86
+msgid "devcp_edit_descriptions_transbox_description_description"
+msgstr "Mô tả của tiện ích là lá»i giải thích rõ ràng hÆ¡n vá» các tính năng, và các thông tin liên quan khác. Nó được hiển thị ngay dÆ°á»›i phần tóm tắt trên trang giá»›i thiệu tiện ích."
+
+#: views/developers/addon_edit_descriptions.thtml:85
+msgid "devcp_edit_descriptions_transbox_description_name"
+msgstr "Mô tả Tiện ích"
+
+#: views/developers/addon_edit_descriptions.thtml:103
+msgid "devcp_edit_descriptions_transbox_eula_description"
+msgstr "Nếu tiện ích của bạn có má»™t Thá»a thuận Giấy phép NgÆ°á»i dùng Cuối (EULA), vui lòng nhập văn bản của nó ở dÆ°á»›i. Nếu được thiết lập, ngÆ°á»i dùng sẽ được yêu cầu phải đồng ý nó trÆ°á»›c khi cài đặt tiện ích của bạn. Vui lòng lÆ°u ý là EULA không giống giấy phép mã nguồn nhÆ° GPL hoặc MPL."
+
+#: views/developers/addon_edit_descriptions.thtml:102
+msgid "devcp_edit_descriptions_transbox_eula_name"
+msgstr "Thá»a thuận Giấy phép NgÆ°á»i dùng Cuối"
+
+#: views/developers/addon_edit_descriptions.thtml:112
+msgid "devcp_edit_descriptions_transbox_privacy_description"
+msgstr "Nếu tiện ích của bạn có một chính sách riêng tư, vui lòng nhập văn bản của nó ở đây. Trang giới thiệu tiện ích của bạn sẽ hiển thị một liên kết đến chính sách đó."
+
+#: views/developers/addon_edit_descriptions.thtml:111
+msgid "devcp_edit_descriptions_transbox_privacy_name"
+msgstr "Chính sách Riêng tư"
+
+#: views/developers/addon_edit_descriptions.thtml:78
+msgid "devcp_edit_descriptions_transbox_summary_description"
+msgstr "Tóm tắt là một đoạn giải thích ngắn vỠchức năng cơ bản của tiện ích của bạn, sẽ được hiển thị trong tìm kiếm và liệt kê, cũng như Ỡtrên đầu trang giới thiệu tiện ích của bạn. <strong>Giới hạn 250 kí tự.</strong>"
+
+#: views/developers/addon_edit_descriptions.thtml:77
+msgid "devcp_edit_descriptions_transbox_summary_name"
+msgstr "Tóm tắt Tiện ích"
+
+#: views/developers/addon_edit.thtml:46
+msgid "devcp_edit_dt_manage_authors"
+msgstr "Quản lí Tác giả Tiện ích"
+
+#: views/developers/addon_edit.thtml:48
+msgid "devcp_edit_dt_manage_categories"
+msgstr "Quản lí Phân mục Tiện ích"
+
+#: views/developers/addon_edit.thtml:50
+msgid "devcp_edit_dt_manage_descriptions"
+msgstr "Quản lí Mô tả Tiện ích"
+
+#: views/developers/addon_edit.thtml:52
+msgid "devcp_edit_dt_manage_properties"
+msgstr "Quản lí Thuộc tính Tiện ích"
+
+#: views/developers/addon_edit_properties.thtml:170
+msgid "devcp_edit_label_externalsoftware"
+msgstr "Tiện ích này yêu cầu có phần má»m bên ngoài"
+
+#: views/developers/addon_edit_properties.thtml:205
+msgid "devcp_edit_label_locale_disambiguation"
+msgstr "Thông tin Bản địa Bổ sung"
+
+#: views/developers/addon_edit_properties.thtml:168
+msgid "devcp_edit_label_prerelease"
+msgstr "Äây là bản phát hành thá»­"
+
+#: views/developers/addon_edit_properties.thtml:169
+msgid "devcp_edit_label_sitespecific"
+msgstr "Äây là tiện ích liên quan đến trang web"
+
+#: views/developers/addon_edit_properties.thtml:202
+msgid "devcp_edit_label_target_locale"
+msgstr "Äịa danh Äích"
+
+#: views/developers/addon_edit_properties.thtml:212
+msgid "devcp_edit_properties_button_update"
+msgstr "Cập nhật Thuộc tính"
+
+#: views/developers/addon_edit_properties.thtml:198
+msgid "devcp_edit_properties_change_guid"
+msgstr "Chỉ thay đổi nếu bạn đã hiểu rõ tất cả hậu quả."
+
+#: views/developers/addon_edit_properties.thtml:109
+msgid "devcp_edit_properties_current_icon"
+msgstr "Biểu tượng Hiện tại"
+
+#: views/developers/addon_edit_properties.thtml:85
+msgid "devcp_edit_properties_default_locale"
+msgstr "Bản địa mặc định của má»™t tiện ích là bản địa chính cần có bản dịch. Nếu không có các bản dịch cho ngôn ngữ của ngÆ°á»i dùng, chúng sẽ tá»± Ä‘á»™ng dùng bản địa mặc định này."
+
+#: views/developers/addon_edit_properties.thtml:167
+msgid "devcp_edit_properties_flags"
+msgstr "Các cá» hiệu này dùng để lá»c và phân loại các tiện ích."
+
+#: views/developers/addon_edit_properties.thtml:174
+msgid "devcp_edit_properties_guid"
+msgstr "GUID tiện ích của bạn được chỉ định trong install.rdf và dùng để nhận dạng riêng nó. Bạn không thể thay GUID một khi nó đã được liệt kê trên Tiện ích Mozilla."
+
+#: views/developers/addon_edit_properties.thtml:53
+msgid "devcp_edit_properties_header"
+msgstr "Chỉnh sửa Thuộc tính Tiện ích"
+
+#: views/developers/addon_edit_properties.thtml:186
+msgid "devcp_edit_properties_header_addon_type"
+msgstr "Kiểu của Tiện ích"
+
+#: views/developers/addon_edit_properties.thtml:181
+msgid "devcp_edit_properties_header_admin_settings"
+msgstr "Quản trị Thiết lập"
+
+#: views/developers/addon_edit_properties.thtml:84
+msgid "devcp_edit_properties_header_default_locale"
+msgstr "Bản địa Mặc định"
+
+#: views/developers/addon_edit_properties.thtml:166
+msgid "devcp_edit_properties_header_flags"
+msgstr "CỠhiệu Tiện ích"
+
+#: views/developers/addon_edit_properties.thtml:173
+#: views/developers/addon_edit_properties.thtml:197
+msgid "devcp_edit_properties_header_guid"
+msgstr "GUID Tiện ích"
+
+#: views/developers/addon_edit_properties.thtml:104
+msgid "devcp_edit_properties_header_icon"
+msgstr "Biểu tượng Tiện ích"
+
+#: views/developers/addon_edit_properties.thtml:159
+msgid "devcp_edit_properties_header_other_settings"
+msgstr "Thiết lập Khác"
+
+#. A header on the admin page to toggle trusted status.
+#: views/developers/addon_edit_properties.thtml:182
+msgid "devcp_edit_properties_header_trusted"
+msgstr "Tiện ích Äáng tin?"
+
+#: views/developers/addon_edit_properties.thtml:160
+msgid "devcp_edit_properties_header_view_source"
+msgstr "Hiển thị Mã nguồn Trực tuyến"
+
+#. %s is a comma-separated list of image extensions ".png, .jpg"
+#: views/developers/addon_edit_properties.thtml:106
+msgid "devcp_edit_properties_icon"
+msgstr "Biểu tượng tiện ích là một hình nhỠđược hiển thị bên cạnh tên tiện ích của bạn trong kết quả tìm kiếm, trang giới thiệu, và trong hộp thoại cài đặt. Hình này sẽ tự động được sửa kích thước thành 32 x 32 pixel. Vui lòng dùng một trong các kiểu hình ảnh sau: %s"
+
+#: views/developers/addon_edit_properties.thtml:171
+msgid "devcp_edit_properties_label_binary"
+msgstr "Tiện ích này chứa các thành phần nhị phân"
+
+#: views/developers/addon_edit_properties.thtml:185
+msgid "devcp_edit_properties_label_not_trusted"
+msgstr "Không đáng tin"
+
+#: views/developers/addon_edit_properties.thtml:184
+msgid "devcp_edit_properties_label_trusted"
+msgstr "Äáng tin"
+
+#: views/developers/addon_edit_properties.thtml:110
+msgid "devcp_edit_properties_new_icon"
+msgstr "Biểu tượng Mới"
+
+#: views/developers/addon_edit_properties.thtml:118
+msgid "devcp_edit_properties_remove_icon"
+msgstr "Xóa Biểu tượng"
+
+#: views/developers/addon_edit_properties.thtml:136
+msgid "devcp_edit_properties_transbox_homepage_description"
+msgstr "Nếu tiện ích của bạn có trang chủ khác, hãy nhập địa chỉ của nó vào đây. Thêm bản dịch khác là không cần thiết trừ khi trang web của bạn được dịch sang các ngôn ngữ khác."
+
+#: views/developers/addon_edit_properties.thtml:135
+msgid "devcp_edit_properties_transbox_homepage_name"
+msgstr "Trang chủ Tiện ích"
+
+#: views/developers/addon_edit_properties.thtml:79
+msgid "devcp_edit_properties_transbox_name_description"
+msgstr "Tên tiện ích của bạn được hiển thị ở má»i nÆ¡i mà nó được liệt kê."
+
+#: views/developers/addon_edit_properties.thtml:78
+msgid "devcp_edit_properties_transbox_name_name"
+msgstr "Tên của Tiện ích"
+
+#: views/developers/addon_edit_properties.thtml:145
+msgid "devcp_edit_properties_transbox_supportemail_description"
+msgstr "Nếu bạn có một địa chỉ email để hỗ trợ, nhập nó vào đây. Thêm các bản dịch khác là không cần thiết trừ khi bạn có các địa chỉ email khác cho các ngôn ngữ khác."
+
+#: views/developers/addon_edit_properties.thtml:144
+msgid "devcp_edit_properties_transbox_supportemail_name"
+msgstr "Äịa chỉ Email Há»— trợ"
+
+#: views/developers/addon_edit_properties.thtml:154
+msgid "devcp_edit_properties_transbox_supporturl_description"
+msgstr "Nếu tiện ích của bạn có diễn đàn hoặc trang web hỗ trợ, hãy nhập nó vào đây. Thêm bản dịch khác là không cần thiết trừ khi trang web của bạn được dịch sang các ngôn ngữ khácI."
+
+#: views/developers/addon_edit_properties.thtml:153
+msgid "devcp_edit_properties_transbox_supporturl_name"
+msgstr "Trang web Hỗ trợ"
+
+#: views/developers/addon_edit_properties.thtml:183
+msgid "devcp_edit_properties_trusted"
+msgstr "Các tiện ích đáng tin có thể trở thành công cộng mà không cần đánh giá của Biên tập viên."
+
+#. %s is href="..." and should stay in the <a> tag.
+#: views/developers/addon_edit_properties.thtml:119
+msgid "devcp_edit_properties_undelete"
+msgstr "Biểu tượng sẽ bị xóa khi lưu. <a %s>Hủy b�</a>"
+
+#: views/developers/addon_edit_properties.thtml:161
+msgid "devcp_edit_properties_view_source"
+msgstr "Mã nguồn các tập tin tiện ích của bạn có thể được xem trá»±c tuyến bởi bất kì ngÆ°á»i dùng nào nếu bạn muốn."
+
+#: views/developers/addon_edit_properties.thtml:162
+msgid "devcp_edit_properties_view_source_allow"
+msgstr "Cho phép xem mã nguồn trực tuyến"
+
+#: views/developers/addon_edit_properties.thtml:163
+msgid "devcp_edit_properties_view_source_do_not_allow"
+msgstr "Không cho phép xem mã nguồn trực tuyến"
+
+#: views/elements/developers/editbox.thtml:46
+msgid "devcp_editbox_authors"
+msgstr "Tác giả"
+
+#: views/elements/developers/editbox.thtml:47
+msgid "devcp_editbox_categories"
+msgstr "Phân mục"
+
+#: views/elements/developers/editbox.thtml:52
+msgid "devcp_editbox_change_status"
+msgstr "Thay đổi Trạng thái"
+
+#: views/elements/developers/editbox.thtml:48
+msgid "devcp_editbox_descriptions"
+msgstr "Mô tả"
+
+#: views/elements/developers/editbox.thtml:43
+msgid "devcp_editbox_edit_addon"
+msgstr "Chỉnh sửa Tiện ích"
+
+#: views/elements/developers/editbox.thtml:57
+msgid "devcp_editbox_new_version"
+msgstr "Phiên bản Mới"
+
+#: views/elements/developers/editbox.thtml:49
+msgid "devcp_editbox_properties"
+msgstr "Thuộc tính"
+
+#: views/elements/developers/editbox.thtml:60
+msgid "devcp_editbox_screenshots"
+msgstr "Hình ảnh Xem trước"
+
+#: views/elements/developers/editbox.thtml:53
+msgid "devcp_editbox_statistics_dashboard"
+msgstr "Bảng Thống Kê"
+
+#: views/elements/developers/editbox.thtml:54
+msgid "devcp_editbox_versions"
+msgstr "Phiên bản và Tập tin"
+
+#: views/elements/developers/editbox.thtml:42
+msgid "devcp_editbox_view_listing"
+msgstr "Xem Liệt Kê"
+
+#: views/elements/developers/editorsmenu.thtml:59
+msgid "devcp_editorsqueue_featured"
+msgstr "Tiện ích Nổi bật"
+
+#. %1 is the review count
+#: views/elements/developers/editorsqueue.thtml:42
+#: views/elements/developers/editorsmenu.thtml:56
+#, php-format
+msgid "devcp_editorsqueue_moderatedreviews"
+msgid_plural "devcp_editorsqueue_moderatedreviews"
+msgstr[0] "Các đánh giá Äã Ä‘iá»u chỉnh (%s)"
+msgstr[1] "Các đánh giá Äã Ä‘iá»u chỉnh (%s)"
+
+#. %1 is the nominated addons count
+#: views/elements/developers/editorsqueue.thtml:44
+#: views/elements/developers/editorsmenu.thtml:58
+#, php-format
+msgid "devcp_editorsqueue_nominated"
+msgid_plural "devcp_editorsqueue_nominated"
+msgstr[0] "Các tiện ích Äược Ä‘á» cá»­ (%s)"
+msgstr[1] "Các tiện ích Äược Ä‘á» cá»­ (%s)"
+
+#. %1 is the update count
+#: views/elements/developers/editorsqueue.thtml:43
+#: views/elements/developers/editorsmenu.thtml:57
+#, php-format
+msgid "devcp_editorsqueue_pendingupdates"
+msgid_plural "devcp_editorsqueue_pendingupdates"
+msgstr[0] "Các bản cập nhật Äang xem xét (%s)"
+msgstr[1] "Các bản cập nhật Äang xem xét (%s)"
+
+#: controllers/statistics_controller.php:147
+#: controllers/statistics_controller.php:361
+#: controllers/previews_controller.php:108
+#: controllers/previews_controller.php:211
+#: controllers/previews_controller.php:312
+msgid "devcp_error_addon_access_denied"
+msgstr "Bạn không có quyá»n truy nhập tiện ích đó."
+
+#. %s is a complete URL with the text from devcp_error_appversion_reference_link_text
+#. in the <a> tag. This should be fixed.
+#: controllers/components/developers.php:591
+#, php-format
+msgid "devcp_error_appversion_reference_link"
+msgstr "Vui lòng xem %s để tham khảo."
+
+#. This is the link text in the <a> for devcp_error_appversion_reference_link. This
+#. should be fixed.
+#: controllers/components/developers.php:591
+msgid "devcp_error_appversion_reference_link_text"
+msgstr "trang này"
+
+#: views/developers/addon_edit_authors.thtml:76
+msgid "devcp_error_empty_authors"
+msgstr "Tiện ích của bạn phải có ít nhất má»™t ngÆ°á»i sở hữu."
+
+#. %1$s is the name of the file
+#: controllers/components/developers.php:658
+msgid "devcp_error_file_exists"
+msgstr "Má»™t phiên bản của tiện ích đó đã tồn tại. Äể thay thế nó, bạn phải xóa tập tin %1$S trÆ°á»›c."
+
+#. %1$s is a file extension. Example: .exe
+#. %2$s is a comma separated list of extensions. Example: .xpi, .jar
+#: controllers/components/developers.php:355
+#, php-format
+msgid "devcp_error_file_extension"
+msgstr "Phần mở rá»™ng tập tin (%s) không được cho phép đối vá»›i kiểu tiện ích đã chá»n. Vui lòng dùng má»™t trong các Ä‘uôi sau: %s"
+
+#: controllers/components/developers.php:64
+msgid "devcp_error_five_categories"
+msgstr "Vui lòng không chá»n nhiá»u hÆ¡n năm phân mục."
+
+#: controllers/components/developers.php:526
+msgid "devcp_error_guid_application"
+msgstr "Äịnh danh của tiện ích này đã được dùng bởi má»™t chÆ°Æ¡ng trình."
+
+#: controllers/components/developers.php:337
+#: controllers/components/developers.php:389
+msgid "devcp_error_http_incomplete"
+msgstr "Truyá»n tải chÆ°a hoàn tất"
+
+#: controllers/components/developers.php:335
+#: controllers/components/developers.php:336
+#: controllers/components/developers.php:387
+#: controllers/components/developers.php:388
+msgid "devcp_error_http_maxupload"
+msgstr "Vượt quá kích thước tải lên tối đa"
+
+#: controllers/components/developers.php:338
+#: controllers/components/developers.php:390
+msgid "devcp_error_http_nofile"
+msgstr "Không có tập tin nào được tải lên"
+
+#. %1$s is a file extension. Example: .exe
+#. %2$s is a comma separated list of extensions. Example: .xpi, .jar
+#: controllers/components/developers.php:401
+#, php-format
+msgid "devcp_error_icon_extension"
+msgstr "Phần mở rộng tập tin (%s) không được phép dùng cho biểu tượng. Vui lòng dùng trong các đuôi sau: %s"
+
+#: controllers/developers_controller.php:504
+msgid "devcp_error_index_rdf_notfound"
+msgstr "Không có install.rdf."
+
+#: controllers/components/developers.php:601
+msgid "devcp_error_install_manifest"
+msgstr "Tìm thấy những lỗi sau trong install.rdf:"
+
+#: controllers/developers_controller.php:1463
+msgid "devcp_error_invalid_addontype"
+msgstr "Vui lòng chá»n má»™t kiểu tiện ích hợp lệ."
+
+#. %$1s is a version. Example: 3.1.1
+#. %$2s is an add-on name.
+#: controllers/components/developers.php:569
+#: controllers/components/developers.php:581
+#, php-format
+msgid "devcp_error_invalid_appversion"
+msgstr "%s không phải là một phiên bản hợp lệ cho %s"
+
+#. %s is a string
+#: controllers/components/developers.php:521
+#, php-format
+msgid "devcp_error_invalid_guid"
+msgstr "Äịnh danh của tiện ích này không hợp lệ: %s"
+
+#. %$1s is a version. Example: 3.1.1
+#. %$2s is an add-on name.
+#: controllers/components/developers.php:572
+#, php-format
+msgid "devcp_error_invalid_minversion"
+msgstr "%s không phải là phiên bản hợp lệ cho %s: các phiên bản nhỠnhất không được để dấu *"
+
+#: controllers/components/developers.php:536
+msgid "devcp_error_invalid_version"
+msgstr "Phiên bản của tiện ích này không hợp lệ: vui lòng xem <a href=\"http://developer.mozilla.org/en/docs/Toolkit_version_format\">chi tiết kĩ thuật</a>"
+
+#: controllers/components/developers.php:531
+msgid "devcp_error_invalid_version_spaces"
+msgstr "Phiên bản của tiện ích này không hợp lệ: phiên bản không được chứa khoảng trắng."
+
+#. %s is an error message from the parser.
+#: controllers/components/developers.php:501
+#, php-format
+msgid "devcp_error_manifest_parse"
+msgstr "Lỗi sau xảy ra trong khi phân tích install.rdf: %s"
+
+#: controllers/components/developers.php:373
+msgid "devcp_error_move_file"
+msgstr "Không thể di chuyển tập tin"
+
+#. %s is the name of a file
+#: controllers/components/developers.php:650
+#: controllers/components/developers.php:662
+#: controllers/components/developers.php:667
+#: controllers/components/developers.php:727
+#: controllers/components/developers.php:738
+#: controllers/components/developers.php:743
+#, php-format
+msgid "devcp_error_moving_file"
+msgstr "Lỗi xảy ra khi đang di chuyển %s."
+
+#: controllers/components/developers.php:595
+msgid "devcp_error_mozilla_application"
+msgstr "Bạn phải có ít nhất một chương trình hợp lệ dùng với Mozilla."
+
+#: controllers/components/developers.php:516
+msgid "devcp_error_no_guid"
+msgstr "Không tìm thấy định danh cho tiện ích này trong install.rdf."
+
+#: controllers/components/developers.php:287
+msgid "devcp_error_no_platform"
+msgstr "Ná»n tảng chÆ°a được chá»n"
+
+#: controllers/components/developers.php:59
+msgid "devcp_error_one_category"
+msgstr "Vui lòng thêm ít nhất một phân mục."
+
+#: controllers/components/developers.php:92
+msgid "devcp_error_one_user"
+msgstr "Tiện ích này cần có ít nhất một tác giả."
+
+#. %1$s is a file extension. Example: .exe
+#. %2$s is a comma separated list of extensions. Example: .xpi, .jar
+#: controllers/components/developers.php:1081
+#, php-format
+msgid "devcp_error_preview_extension"
+msgstr "Phần mở rộng tập tin (%s) không được phép cho tính năng xem trước. Vui lòng sử dụng một trong các đuôi sau: %s"
+
+#: controllers/components/developers.php:511
+msgid "devcp_error_updatekey"
+msgstr "Tiện ích không thể dùng Khóa cập nhật. Vui lòng xóa trong install.rdf và thử lại."
+
+#: controllers/components/developers.php:506
+msgid "devcp_error_updateurl"
+msgstr "Tiện ích không thể dùng URL cập nhật bên ngoài. Vui lòng xóa khá»i install.rdf và thá»­ lại."
+
+#: controllers/developers_controller.php:465
+#: controllers/components/developers.php:271
+msgid "devcp_error_upload_file"
+msgstr "Vui lòng tải lên một tập tin."
+
+#: views/developers/uploader.thtml:135
+msgid "devcp_input_upload_file"
+msgstr "Tải lên Tập tin"
+
+#: views/pages/js_constants.js.thtml:89
+msgid "devcp_js_a_cancel"
+msgstr "Hủy bá»"
+
+#: views/pages/js_constants.js.thtml:90
+msgid "devcp_js_add_email"
+msgstr "Vui lòng nhập email tài khoản của tác giả mà bạn muốn thêm vào."
+
+#. alt text for a down-arrow image.
+#: views/pages/js_constants.js.thtml:81
+msgid "devcp_js_img_move_down"
+msgstr "Chuyển Xuống"
+
+#. alt text for an up-arrow image.
+#: views/pages/js_constants.js.thtml:82
+msgid "devcp_js_img_move_up"
+msgstr "Chuyển Lên"
+
+#: views/pages/js_constants.js.thtml:91
+msgid "devcp_js_img_remove_compat"
+msgstr "Xóa Tính tương thích Chương trình"
+
+#: views/pages/js_constants.js.thtml:86
+msgid "devcp_js_input_list_author"
+msgstr "Liệt kê tác giả trong phần liệt kê công khai"
+
+#: views/pages/js_constants.js.thtml:92
+msgid "devcp_js_license_select"
+msgstr "Vui lòng chá»n má»™t giấy phép."
+
+#: views/pages/js_constants.js.thtml:93
+msgid "devcp_js_license_text"
+msgstr "Vui lòng nhập văn bản cho giấy phép của bạn."
+
+#. <option> text in a <select> for Author role in an add-on.
+#: views/pages/js_constants.js.thtml:84
+msgid "devcp_js_option_developer"
+msgstr "Nhà phát triển"
+
+#. <option> text in a <select> for Author role in an add-on.
+#: views/pages/js_constants.js.thtml:83
+msgid "devcp_js_option_owner"
+msgstr "NgÆ°á»i sở hữu"
+
+#. <option> text in a <select> for Author role in an add-on.
+#: views/pages/js_constants.js.thtml:85
+msgid "devcp_js_option_viewer"
+msgstr "NgÆ°á»i quan sát"
+
+#: views/pages/js_constants.js.thtml:88
+msgid "devcp_js_remove_author"
+msgstr "Xóa Tác Giả"
+
+#: views/pages/js_constants.js.thtml:87
+msgid "devcp_js_sure_remove"
+msgstr "Bạn có <strong>chắc</strong> là bạn muốn xóa tác giả này không?"
+
+#: views/pages/js_constants.js.thtml:77
+msgid "devcp_js_upload_alert"
+msgstr "Bạn phải chá»n má»™t tập tin để tải lên."
+
+#. %1$s is an addon id, like 32.
+#. %2$s is a version number, like 3.5.
+#: controllers/components/developers.php:1212
+msgid "devcp_license_existing"
+msgstr "Giấy phép tùy biến cho tiện ích %1$s v%2$s"
+
+#: views/elements/developers/localebox.thtml:44
+msgid "devcp_localebox_header_localizedfields"
+msgstr "Các phần được Bản địa hóa"
+
+#. %1 is the default locale
+#: views/elements/developers/localebox.thtml:48
+#, php-format
+msgid "devcp_localebox_intro"
+msgstr "Má»™t số phần trên trang này được bản địa hóa để hiển thị theo ngôn ngữ địa phÆ°Æ¡ng của ngÆ°á»i dùng. Vui lòng chá»n má»™t địa danh bên dÆ°á»›i để chỉnh sá»­a chi tiết tiện ích của bạn trong ngôn ngữ đó. Nếu bản dịch cho địa danh đó không tồn tại, nó sẽ hiển thị theo địa danh mặc định đã chá»n (%s)."
+
+#: views/elements/developers/sidebar.thtml:68
+#: views/elements/developers/myaddons.thtml:75
+msgid "devcp_myaddons_admincp_link"
+msgstr "Công cụ Quản trị"
+
+#: views/elements/developers/sidebar.thtml:65
+#: views/elements/developers/myaddons.thtml:72
+msgid "devcp_myaddons_editorcp_link"
+msgstr "Công cụ Biên tập"
+
+#: views/elements/developers/myaddons.thtml:52
+msgid "devcp_myaddons_link"
+msgstr "Tiện ích của Tôi"
+
+#: views/elements/developers/sidebar.thtml:70
+#: views/elements/developers/myaddons.thtml:77
+msgid "devcp_myaddons_mainpage_link"
+msgstr "Trở lại Trang Chính"
+
+#: views/elements/developers/sidebar.thtml:63
+#: views/elements/developers/myaddons.thtml:70
+msgid "devcp_myaddons_statistics_link"
+msgstr "Bảng Thống Kê"
+
+#: views/elements/developers/sidebar.thtml:62
+#: views/elements/developers/myaddons.thtml:69
+msgid "devcp_myaddons_submitaddon_link"
+msgstr "Gá»­i Tiện Ãch"
+
+#: views/elements/developers/sidebar.thtml:48
+#: views/elements/developers/myaddons.thtml:67
+msgid "devcp_myaddons_title"
+msgstr "Công cụ Nhà phát triển"
+
+#. %1$s is an add-on ID, perhaps 167.
+#. %2$s is a URL.
+#: controllers/developers_controller.php:256
+msgid "devcp_new_addon_error"
+msgstr "ID tiện ích này (%1$s) đã tồn tại trong cơ sở dữ liệu. Nếu đây là tiện ích của mình, bạn có thể <a href=\"%2$s\">tải lên một phiên bản mới</a>."
+
+#: views/developers/addon_status_nominate.thtml:62
+msgid "devcp_nominate_cancel"
+msgstr "Hủy bỠvà quay trở lại"
+
+#. %1 is the add-on name
+#: views/developers/addon_status_nominate.thtml:61
+#, php-format
+msgid "devcp_nominate_submit_nominate"
+msgstr "Äá» cá»­ %s"
+
+#: views/developers/addon_edit_properties.thtml:50
+#: views/developers/addon_status.thtml:49
+#: views/developers/versions_edit.thtml:50
+msgid "devcp_notice_changes_error"
+msgstr "<span>Má»™t hoặc nhiá»u thay đổi của bạn đã không được lÆ°u.</span><br />Vui lòng xem lá»—i ở dÆ°á»›i. Các thay đổi còn lại của bạn đã được lÆ°u thành công."
+
+#: views/developers/addon_edit_authors.thtml:47
+#: views/developers/addon_edit_properties.thtml:47
+#: views/developers/addon_status.thtml:46
+#: views/developers/addon_edit_descriptions.thtml:47
+#: views/developers/versions_edit.thtml:47
+#: views/developers/addon_edit_categories.thtml:46
+msgid "devcp_notice_changes_saved"
+msgstr "<span>Các thay đổi của bạn đã được lưu.</span><br />Vui lòng lưu ý rằng một số thay đổi có thể mất vài giỠmới xuất hiện trên tất cả khu vực của trang web."
+
+#: controllers/previews_controller.php:252
+msgid "devcp_notice_cleardefault"
+msgstr "Xóa hình ảnh xem trước này sẽ đưa hình khác thành hình ảnh xem trước mặc định."
+
+#: controllers/previews_controller.php:184
+#: controllers/previews_controller.php:251
+msgid "devcp_notice_makedefault"
+msgstr "ÄÆ°a cái này lên thành hình ảnh mặc định sẽ xóa bá» trạng thái mặc định của hình ảnh xem trÆ°á»›c mặc định Ä‘ang dùng."
+
+#: views/developers/addon_edit_authors.thtml:70
+msgid "devcp_notice_unsaved_changes"
+msgstr "Bạn có các thay đổi chưa lưu."
+
+#: controllers/developers_controller.php:87
+#: controllers/developers_controller.php:97
+#: controllers/developers_controller.php:100
+#: controllers/previews_controller.php:67
+#: controllers/previews_controller.php:79
+#: controllers/previews_controller.php:82
+msgid "devcp_pagetitle"
+msgstr "Công cụ Nhà phát triển"
+
+#: controllers/previews_controller.php:103
+#: controllers/previews_controller.php:104
+msgid "devcp_preview_add_pagetitle"
+msgstr "Thêm ảnh Xem trước"
+
+#: controllers/previews_controller.php:135
+msgid "devcp_preview_added_successfully"
+msgstr "Ảnh xem trước đã được thêm thành công."
+
+#: controllers/previews_controller.php:323
+msgid "devcp_preview_deleted_successfully"
+msgstr "Ảnh xem trước đã được xóa thành công."
+
+#: controllers/previews_controller.php:194
+#: controllers/previews_controller.php:195
+msgid "devcp_preview_edit_pagetitle"
+msgstr "Chỉnh sửa Ảnh xem trước"
+
+#: controllers/previews_controller.php:237
+msgid "devcp_preview_updated_successfully"
+msgstr "Ảnh xem trước được cập nhật thành công."
+
+#: views/developers/previews.thtml:120
+msgid "devcp_previews_a_another"
+msgstr "Thêm Hình ảnh Xem trước Khác"
+
+#: views/developers/previews.thtml:96
+msgid "devcp_previews_a_delete"
+msgstr "Xóa Hình ảnh Xem trước"
+
+#: views/developers/previews.thtml:95
+msgid "devcp_previews_a_replace"
+msgstr "Thay thế Hình ảnh Xem trước"
+
+#: views/developers/previews.thtml:126
+msgid "devcp_previews_a_update"
+msgstr "Cập nhật Hình ảnh Xem trước"
+
+#: views/developers/previews.thtml:115
+#: views/developers/previews.thtml:124
+msgid "devcp_previews_add_new"
+msgstr "Thêm Hình ảnh Xem trước Mới"
+
+#. %s is a list of file extensions, e.g. ".png, .gif"
+#: views/developers/previews.thtml:116
+msgid "devcp_previews_add_select"
+msgstr "Chá»n má»™t hình để tải lên. Các hình lá»›n hÆ¡n kích thÆ°á»›c tối Ä‘a 700 pixel chiá»u rá»™ng và 525 pixel chiá»u cao sẽ bị chỉnh lại. Các kiểu tập tin cho phép: %s"
+
+#: views/developers/previews.thtml:121
+msgid "devcp_previews_click_below"
+msgstr "Nhấn Cập nhật Hình ảnh Xem trước để tải lên."
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/previews.thtml:102
+msgid "devcp_previews_click_update"
+msgstr "Nhấn nút Cập nhật Hình ảnh Xem trước để lưu hình này. (<a %s>Hủy b�</a>)"
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/previews.thtml:107
+msgid "devcp_previews_error_message"
+msgstr "Hình xem trước này sẽ bị xóa khi Cập nhật Hình ảnh Xem trước được nhấn. (<a %s>Hủy b�</a>)"
+
+#: views/previews/add.thtml:45
+msgid "devcp_previews_filetype_info"
+msgstr "Dùng biểu mẫu bên dÆ°á»›i để tải lên má»™t ảnh chụp PNG, JPG, hoặc GIF của tiện ích của bạn. Các hình ảnh rá»™ng hÆ¡n 700 pixel và cao hÆ¡n 525 pixel sẽ tá»± Ä‘á»™ng được Ä‘iá»u chỉnh kích thÆ°á»›c."
+
+#: views/previews/add.thtml:43
+msgid "devcp_previews_header_add"
+msgstr "Thêm ảnh Xem trước"
+
+#: views/developers/previews.thtml:80
+msgid "devcp_previews_header_caption"
+msgstr "Tiêu đỠẢnh xem Trước"
+
+#: views/previews/edit.thtml:43
+msgid "devcp_previews_header_edit"
+msgstr "Chỉnh sửa Ảnh xem trước"
+
+#: views/developers/previews.thtml:93
+msgid "devcp_previews_label_default"
+msgstr "Ảnh xem trước Mặc định"
+
+#: views/previews/add.thtml:54
+msgid "devcp_previews_label_file"
+msgstr "Tập tin Ảnh xem trước"
+
+#: views/previews/add.thtml:59
+#: views/previews/edit.thtml:50
+msgid "devcp_previews_label_makedefault"
+msgstr "ÄÆ°a ảnh này thành hình ảnh xem trÆ°á»›c mặc định"
+
+#: views/developers/previews.thtml:100
+msgid "devcp_previews_label_new"
+msgstr "Hình mới:"
+
+#: views/developers/previews.thtml:118
+msgid "devcp_previews_label_upload"
+msgstr "Tải lên Hình xem trước: "
+
+#: views/developers/previews.thtml:50
+msgid "devcp_previews_notice_error"
+msgstr "Má»™t hoặc nhiá»u hình xem trÆ°á»›c má»›i của bạn không thể lÆ°u được."
+
+#: views/developers/previews.thtml:47
+msgid "devcp_previews_notice_success"
+msgstr "Hình xem trước của bạn đã được cập nhật thành công."
+
+#: views/developers/previews.thtml:59
+msgid "devcp_previews_p_screenshots"
+msgstr "Hình ảnh xem trước của tiện ích của bạn được hiển thị bên dưới. Bạn có thể thay đổi tiêu đỠhoặc hình ảnh. Hình xem trước Mặc định là hình được hiển thị bên canh tiện ích của bạn trong liệt kê và tìm kiếm."
+
+#: views/previews/edit.thtml:55
+msgid "devcp_previews_submit_delete"
+msgstr "Xóa hình Xem trước"
+
+#: views/previews/edit.thtml:55
+msgid "devcp_previews_submit_delete_confirm"
+msgstr "Bạn có chắc bạn muốn xóa hình ảnh xem trước này?"
+
+#: views/previews/edit.thtml:54
+msgid "devcp_previews_submit_edit"
+msgstr "Chỉnh sửa Ảnh xem trước"
+
+#: views/previews/add.thtml:63
+msgid "devcp_previews_submit_upload"
+msgstr "Tải lên Ảnh xem trước"
+
+#: views/developers/previews.thtml:78
+msgid "devcp_previews_thumbnail"
+msgstr "Hình thu nhá»"
+
+#. %s is the add-on name.
+#: views/developers/previews.thtml:44
+msgid "devcp_previews_title"
+msgstr "Quản lí Hình xem trước %s"
+
+#: views/developers/uploader.thtml:74
+msgid "devcp_review_agreement_please"
+msgstr "Vui lòng xem lại và chấp thuận Thá»a thuận Nhà phát triển trÆ°á»›c khi tiến hành."
+
+#: views/elements/developers/rolecheck.thtml:42
+msgid "devcp_rolecheck_no_privs"
+msgstr "<span>Bạn không có đủ quyá»n để tạo ra thay đổi trên trang này.</span><br />Liên hệ NgÆ°á»i sở hữu Tiện ích nếu bạn muốn tạo ra thay đổi."
+
+#: controllers/developers_controller.php:1315
+msgid "devcp_several_hours"
+msgstr "Vui lòng lưu ý rằng một số thay đổi có thể mất vài giỠmới xuất hiện trên tất cả khu vực của trang web."
+
+#: views/elements/developers/sidebar.thtml:52
+msgid "devcp_sidebar_a_dashboard"
+msgstr "Bảng Äiá»u Khiển"
+
+#. %s is a number
+#: views/elements/developers/statsbar.thtml:45
+#: views/developers/dashboard.thtml:79
+#, php-format
+msgid "devcp_statsbar_adu"
+msgstr "<em>%s</em> NgÆ°á»i dùng Hàng ngày"
+
+#. %s is a number
+#: views/elements/developers/statsbar.thtml:41
+#: views/developers/dashboard.thtml:75
+#, php-format
+msgid "devcp_statsbar_total_downloads"
+msgstr "<em>%s</em> Tổng số Lượt tải"
+
+#. %s is a number
+#: views/elements/developers/statsbar.thtml:43
+#: views/developers/dashboard.thtml:77
+#, php-format
+msgid "devcp_statsbar_weekly_downloads"
+msgstr "<em>%s</em> Số lượt tải Hàng tuần"
+
+#: views/developers/addon_status_confirm.thtml:59
+msgid "devcp_status_confirm_active"
+msgstr "Äánh dấu tiện ích này là hoạt Ä‘á»™ng sẽ cho nó hiển thị trong những khu vá»±c công cá»™ng phù hợp vá»›i trạng thái của nó, bao gồm liệt kê và tìm kiếm. Nó có thể được tải xuống từ trang web và quay trở lại trong việc kiểm tra cập nhật trên máy khách, tùy vào trạng thái của nó. Bạn có thể trở lại đây và vô hiệu hóa nó lần nữa nếu muốn."
+
+#: views/developers/addon_status_confirm.thtml:59
+msgid "devcp_status_confirm_active_sure"
+msgstr "Bạn có chắc là bạn muốn đánh dấu tiện ích này là hoạt động không?"
+
+#: views/developers/addon_status_confirm.thtml:50
+msgid "devcp_status_confirm_header_sure"
+msgstr "Bạn có chắc không?"
+
+#: views/developers/addon_status_confirm.thtml:55
+msgid "devcp_status_confirm_inactive"
+msgstr "Äánh dấu tiện ích này là im lìm sẽ không cho nó hiển thị trong bất kì khu vá»±c công cá»™ng nào, bao gồm liệt kê và tìm kiếm. Nó sẽ không thể được tải xuống từ trang web và sẽ không được quay trở lại trong việc kiểm tra cập nhật trên máy khách. Bạn có thể trở lại đây và kích hoạt nó nếu muốn."
+
+#: views/developers/addon_status_confirm.thtml:55
+msgid "devcp_status_confirm_inactive_sure"
+msgstr "Bạn có chắc là bạn muốn đánh dấu tiện ích này là im lìm không?'"
+
+#: views/developers/addon_status_confirm.thtml:74
+msgid "devcp_status_confirm_no"
+msgstr "Không, hủy bá»"
+
+#: views/developers/addon_status_confirm.thtml:67
+msgid "devcp_status_confirm_public"
+msgstr "Äánh dấu tiện ích này là công cá»™ng sẽ làm nó hiện hữu để má»i ngÆ°á»i tải và sẽ bắt đầu cung cấp các cập nhật cho ngÆ°á»i dùng hiện tại."
+
+#: views/developers/addon_status_confirm.thtml:67
+msgid "devcp_status_confirm_public_sure"
+msgstr "Bạn có chắc là bạn muốn đưa tiện ích này thành công cộng?"
+
+#: views/developers/addon_status_confirm.thtml:63
+msgid "devcp_status_confirm_sandbox"
+msgstr "Di chuyển tiện ích này trở lại há»™p cát sẽ yêu cầu ngÆ°á»i dùng phải đăng nhập trÆ°á»›c khi tải xuống và cập nhật sẽ không còn được cung cấp cho ngÆ°á»i dùng hiện tại. Vì tiện ích của bạn hiện Ä‘ang là công cá»™ng, bạn có thể trở lại đây vào bất kì lúc nào để chuyển nó thành công cá»™ng."
+
+#: views/developers/addon_status_confirm.thtml:63
+msgid "devcp_status_confirm_sandbox_sure"
+msgstr "Bạn có chắc là mình muốn di chuyển tiện ích này vào hộp cát không?"
+
+#: views/developers/addon_status_confirm.thtml:73
+msgid "devcp_status_confirm_yes"
+msgstr "Có, tôi chắc chắn"
+
+#: views/developers/addon_status_nominate.thtml:46
+msgid "devcp_status_nominate_error_notice"
+msgstr "<span>Cần có thông Ä‘iệp Ä‘á» cá»­.</span><br />Vui lòng Ä‘iá»n vào há»™p văn bản thông tin được yêu cầu và thá»­ lại."
+
+#: views/developers/addon_status_nominate.thtml:55
+msgid "devcp_status_nominate_header"
+msgstr "Äá» cá»­ Tiện ích"
+
+#: views/developers/dashboard.thtml:85
+msgid "devcp_summary_lastversion"
+msgstr "Phiên bản Gần nhất:"
+
+#. %s is the add-on name.
+#: views/developers/addon_edit.thtml:43
+#: views/developers/addon_edit_authors.thtml:44
+#: views/developers/versions_delete.thtml:43
+#: views/developers/addon_edit_properties.thtml:44
+#: views/developers/addon_edit_descriptions.thtml:44
+#: views/developers/versions_edit.thtml:44
+#: views/developers/addon_edit_categories.thtml:43
+#: views/developers/versions.thtml:43
+msgid "devcp_title_edit_addon"
+msgstr "Chỉnh sửa %s"
+
+#. title attribute for a javascript link that pops up a help dialog.
+#: views/elements/translationbox.thtml:68
+msgid "devcp_transbox_a_title_help"
+msgstr "Trợ giúp (không rá»i trang)"
+
+#: views/elements/translationbox.thtml:68
+msgid "devcp_transbox_alt_help"
+msgstr "Trợ giúp"
+
+#. %1$s is <span>17</span>, %2$s is 42.
+#: views/elements/translationbox.thtml:101
+msgid "devcp_transbox_chars_used"
+msgstr "Kí tự đã dùng: %1$s / %2$s"
+
+#: views/elements/translationbox.thtml:132
+msgid "devcp_transbox_delete_sure"
+msgstr "Bạn có chắc là bạn muốn xóa bản dịch này không?"
+
+#. %s is a locale, like en-US.
+#: views/elements/translationbox.thtml:143
+msgid "devcp_transbox_help_header_tabs"
+msgstr "Các thẻ %s là gì?"
+
+#: views/elements/translationbox.thtml:145
+msgid "devcp_transbox_help_header_what"
+msgstr "Nếu tôi không có bất kì bản dịch nào thì sao?"
+
+#: views/elements/translationbox.thtml:147
+msgid "devcp_transbox_help_hide"
+msgstr "Ẩn Trợ giúp"
+
+#: views/elements/translationbox.thtml:146
+msgid "devcp_transbox_help_if"
+msgstr "Nếu má»™t ngÆ°á»i dùng duyệt xem má»™t site và không có bản dịch cho ngôn ngữ của ngÆ°á»i đó, nó sẽ dùng Bản địa Mặc định của tiện ích của bạn, được xác định trong khu vá»±c Chỉnh sá»­a Thuá»™c tính Tiện ích. Nếu không có bản dịch nào, chỉ cần nhập những gì mà bạn muốn vào Bản địa Mặc định, vốn phải là ngôn ngữ mà bạn nói."
+
+#: views/elements/translationbox.thtml:144
+msgid "devcp_transbox_help_transbox"
+msgstr "Äây là má»™t <i>Há»™p Dịch Thuật</i>. Nó cho phép bạn bản địa hóa má»™t trÆ°á»ng xác định thành các ngôn ngữ khác mà bạn có bản dịch. Bạn có thể thêm, chỉnh sá»­a, và xóa các bản dịch bằng cách dùng thẻ bản địa."
+
+#: views/elements/translationbox.thtml:85
+msgid "devcp_transbox_img_add_trans"
+msgstr "Thêm Bản Dịch"
+
+#: views/elements/translationbox.thtml:86
+msgid "devcp_transbox_img_remove_trans"
+msgstr "Xóa Bản Dịch"
+
+#: views/elements/translationbox.thtml:123
+msgid "devcp_transbox_input_add_all"
+msgstr "Thêm Bản địa cho Tất cả"
+
+#: views/elements/translationbox.thtml:122
+msgid "devcp_transbox_input_add_locale"
+msgstr "Thêm Bản Äịa"
+
+#: views/elements/translationbox.thtml:124
+#: views/elements/translationbox.thtml:135
+msgid "devcp_transbox_input_cancel"
+msgstr "Hủy bá»"
+
+#: views/elements/translationbox.thtml:134
+msgid "devcp_transbox_input_delete"
+msgstr "Xóa nó"
+
+#: views/elements/translationbox.thtml:113
+msgid "devcp_transbox_select_locale"
+msgstr "Chá»n tên bản địa của bản dịch mà bạn muốn thêm vào:"
+
+#. %1$s and %2$s are GUIDs.
+#: controllers/developers_controller.php:343
+msgid "devcp_update_addon_guid_error"
+msgstr "GUID tiện ích dùng trong tập tin này (%1$s) không phù hợp với GUID có sẵn của tiện ích này (%2$s)."
+
+#: controllers/developers_controller.php:334
+msgid "devcp_update_addon_priv_error"
+msgstr "Bạn không có đủ thẩm quyá»n để cập nhật tiện ích này."
+
+#. %1$s is a version number, %2$s is an add-on ID.
+#: controllers/developers_controller.php:399
+msgid "devcp_update_addon_version_belong_error"
+msgstr "Phiên bản xác định (%1$s) không thuộc vỠtiện ích này (%2$s)."
+
+#. %1$s is a version number, maybe 1.1.
+#. %2$s is a URL.
+#: controllers/developers_controller.php:351
+msgid "devcp_update_addon_version_exists_error"
+msgstr "Số phiên bản tải lên (%1$s) đã tồn tại. Nếu bạn đang cố thêm tập tin khác cho phiên bản này, <a href=\"%2$s\">nhấn vào đây</a>."
+
+#. %1$s and %2$s are version numbers.
+#: controllers/developers_controller.php:405
+msgid "devcp_update_addon_version_match_error"
+msgstr "Số phiên bản tải lên (%1$s) không phù hợp với số phiên bản sẵn có (%2$s)."
+
+#: views/developers/uploader.thtml:68
+msgid "devcp_uploader_a_start"
+msgstr "Bắt Äầu"
+
+#: views/developers/uploader.thtml:137
+msgid "devcp_uploader_ajax_loading"
+msgstr "Äang tải tập tin..."
+
+#: views/developers/uploader.thtml:82
+msgid "devcp_uploader_button_agree"
+msgstr "Äồng ý và tiếp tục"
+
+#: views/developers/uploader.thtml:157
+msgid "devcp_uploader_button_edit"
+msgstr "Chỉnh sửa Tiện ích Của tôi"
+
+#: views/developers/uploader.thtml:158
+msgid "devcp_uploader_button_later"
+msgstr "Tôi sẽ hoàn tất tiện ích của tôi sau."
+
+#: views/developers/uploader.thtml:168
+msgid "devcp_uploader_button_release"
+msgstr "Thêm Ghi chú Phát hành"
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/uploader.thtml:156
+msgid "devcp_uploader_created_results"
+msgstr "<p>Liệt kê cho tiện ích của bạn đã được tạo thành công. Thông tin cÆ¡ bản lấy từ tập tin tải lên đã được lÆ°u trữ, nhÆ°ng vẫn còn nhiá»u thứ trong phần liệt kê có thể tùy biến được.</p><p>Tiện ích của bạn hiện Ä‘ang được đánh dấu là <strong>Im lìm</strong>. Äể hoàn tất tiện ích của mình, bạn sẽ cần phải chắc chắn rằng nó có tên, tóm tắt, và mô tả chính xác, cÅ©ng nhÆ° có ít nhất má»™t phân mục được chá»n. Bạn có thể chỉnh sá»­a thông tin tiện ích bằng cách dùng liên kết bên dÆ°á»›i và kiểm tra trạng thái tiện ích của bạn vào bất kì lúc nào trên <a %s>trang trạng thái</a>."
+
+#: views/developers/uploader.thtml:143
+msgid "devcp_uploader_error_correct"
+msgstr "Vui lòng sửa vấn đỠvà tải tập tin lên lần nữa."
+
+#. %1$s is a version number, %2$s is a status, e.g Public or Incomplete.
+#: views/developers/uploader.thtml:175
+msgid "devcp_uploader_file_created"
+msgstr "Tập tin mới của bạn đã được thêm vào phiên bản %1$s và hiện được đánh dấu là %2$s."
+
+#: views/developers/uploader.thtml:154
+msgid "devcp_uploader_header_created"
+msgstr "Tiện ích Äã được tạo!"
+
+#: views/developers/uploader.thtml:141
+msgid "devcp_uploader_header_error"
+msgstr "Ôi! Hình như có vấn đỠvới tập tin này..."
+
+#: views/developers/uploader.thtml:173
+msgid "devcp_uploader_header_file_added"
+msgstr "Tập tin Äã được thêm!"
+
+#: views/developers/uploader.thtml:66
+msgid "devcp_uploader_header_how"
+msgstr "Nó hoạt động như thế nào?"
+
+#. %s is the version number, e.g. 3.2.
+#: views/developers/uploader.thtml:163
+msgid "devcp_uploader_header_update_created"
+msgstr "Phiên bản %s Äã được tạo"
+
+#: views/developers/uploader.thtml:117
+msgid "devcp_uploader_header_upload"
+msgstr "Tải lên Tập tin Của bạn"
+
+#: views/developers/uploader.thtml:67
+msgid "devcp_uploader_how"
+msgstr "<p>Cảm Æ¡n bạn đã có nhã ý gá»­i tiện ích lên Tiện ích Mozilla. LÆ°u trữ tiện ích trên Tiện ích Mozilla là cách thức dá»… dàng nhất để quản lí việc phân phối tiện ích của bạn. Äây là những gì bạn sẽ nhận được:</p><ul><li>Má»—i tiện ích sẽ có má»™t trang giá»›i thiệu công cá»™ng vá»›i các thông tin do bạn cung cấp, ví dụ nhÆ° má»™t tóm tắt ngắn gá»n vá» chức năng của tiện ích, má»™t mô tả dài hÆ¡n, và má»™t mục trÆ°ng bày các hình ảnh xem trÆ°á»›c vá» tiện ích của bạn.</li><li>Tiện ích của bạn sẽ xuất hiện trong phần liệt kê và tìm kiếm xuyên suốt site, và thậm chí trong mục Quản lí Tiện ích của Firefox.</li><li>Chúng tôi sẽ lo nÆ¡i lÆ°u trữ tất cả các phiên tải xuống của bạn, và cung cấp cập nhật tá»± Ä‘á»™ng cho ngÆ°á»i dùng khi bạn tải lên má»™t phiên bản má»›i.</li><li>Bạn sẽ có quyá»n truy cập bảng thống kê vá»›i các thông tin chi tiết vá» dữ liệu ngÆ°á»i dùng.</li></ul><p>Tiện ích được lÆ°u trữ trên site phải được đánh giá bởi Biên tập viên Tiện ích Mozilla trÆ°á»›c khi chúng có tất cả các tính năng được liệt kê ở trên. Nếu bạn đã sẵn sàng để bắt đầu quá trình và gói tiện ích của bạn đã sẵn sàng để tải lên, hãy nhấn nút Bắt Äầu bên dÆ°á»›i!</p>"
+
+#: views/developers/uploader.thtml:125
+msgid "devcp_uploader_label_platformtype"
+msgstr "Ná»n tảng Há»— trợ:"
+
+#: views/developers/uploader.thtml:124
+msgid "devcp_uploader_label_upload_field"
+msgstr "Tập tin Tiện ích: "
+
+#: controllers/components/developers.php:1221
+msgid "devcp_uploader_option_other"
+msgstr "Khác"
+
+#. %1$s is a number, %2$s is href="..." and should stay in the <a> tag.
+#: views/developers/uploader.thtml:176
+msgid "devcp_uploader_p_pending_file"
+msgstr "Tập tin má»›i sẽ hiện hữu ra công cá»™ng ngay khi biên tập viên có thể đánh giá nó. Hiện có %1$s tiện ích khác cÅ©ng Ä‘ang trong hàng chá». Muốn được đánh giá nhanh hÆ¡n? Hãy cân nhắc việc <a %2$s>trở thành má»™t biên tập viên</a> nhé."
+
+#. %1$s is a number, %2$s is href="..." and should stay in the <a> tag.
+#: views/developers/uploader.thtml:166
+msgid "devcp_uploader_p_pending_version"
+msgstr "Phiên bản má»›i sẽ hiện hữu ra công cá»™ng ngay khi biên tập viên có thể đánh giá nó. Hiện có %1$s tiện ích khác cÅ©ng Ä‘ang trong hàng chá». Muốn được đánh giá nhanh hÆ¡n? Hãy cân nhắc việc <a %2$s>trở thành má»™t biên tập viên</a> nhé."
+
+#. %s is a status, e.g Public or Incomplete.
+#: views/developers/uploader.thtml:165
+msgid "devcp_uploader_p_update_created"
+msgstr "Phiên bản mới của bạn đã được tạo và hiện được đánh dấu là %s."
+
+#. %1$s is href="..." and should stay in the 'Versions and Files' <a> tag.
+#. %2$s is href="..." and should stay in the 'current status' <a> tag.
+#: views/developers/uploader.thtml:177
+msgid "devcp_uploader_p_update_file"
+msgstr "Xem tập tin mới của bạn trong <a %1$s>trang Phiên bản và Tập tin</a>, kiểm tra <a %2$s>trạng thái hiện tại</a> của tiện ích của bạn, hoặc <b>thêm ghi chú phát hành</b> bằng cách nhấn vào nút bên dưới (đặc biệt khuyến nghị)."
+
+#. %1$s is href="..." and should stay in the 'Versions and Files' <a> tag.
+#. %2$s is href="..." and should stay in the 'current status' <a> tag.
+#: views/developers/uploader.thtml:167
+msgid "devcp_uploader_p_update_version"
+msgstr "Xem phiên bản mới của bạn trong <a %1$s>trang Phiên bản và Tập tin</a>, kiểm tra <a %2$s>trạng thái hiện tại</a> của tiện ích của bạn, hoặc <b>thêm ghi chú phát hành</b> bằng cách nhấn vào nút bên dưới (đặc biệt khuyến nghị)."
+
+#: views/developers/uploader.thtml:118
+msgid "devcp_uploader_p_upload"
+msgstr "Tải lên tập tin tiện ích của bạn bằng biểu mẫu bên dÆ°á»›i. Nếu bạn có các tập tin cho nhiá»u ná»n tảng riêng biệt cần tải lên, hãy chá»n má»™t tập tin Ä‘Æ¡n lẻ và tải lên những tập tin khác bằng phần Quản lí Phiên bản và Tập tin."
+
+#: views/developers/uploader.thtml:125
+msgid "devcp_uploader_platformtype_all"
+msgstr "Tất cả"
+
+#: views/developers/uploader.thtml:126
+msgid "devcp_uploader_platformtype_specific"
+msgstr "Riêng biệt:"
+
+#. Used as first item in a <select>.
+#: controllers/components/developers.php:1185
+msgid "devcp_uploader_please_choose"
+msgstr "Vui lòng chá»n..."
+
+#. %1$s is the add-on name, %2$s is the version number.
+#: views/developers/uploader.thtml:57
+msgid "devcp_uploader_title_file"
+msgstr "Thêm Tập Tin vào %1$s %2$s"
+
+#: views/developers/uploader.thtml:50
+msgid "devcp_uploader_title_submit"
+msgstr "Gửi lên Tiện ích Mới"
+
+#. %s is the add-on name.
+#: views/developers/uploader.thtml:54
+msgid "devcp_uploader_title_update"
+msgstr "Cập nhật %s"
+
+#. %s is a full <a> tag
+#: controllers/developers_controller.php:503
+#, php-format
+msgid "devcp_valid_app_reference"
+msgstr "Vui lòng xem %s để tham khảo."
+
+#. This is the text in the <a> tag for devcp_valid_app_reference. This should be
+#. fixed.
+#: controllers/developers_controller.php:503
+msgid "devcp_valid_app_reference_linktext"
+msgstr "trang này"
+
+#: controllers/developers_controller.php:581
+msgid "devcp_verify_author_error"
+msgstr "Không tìm thấy tài khoản cho địa chỉ email đó."
+
+#: controllers/developers_controller.php:553
+msgid "devcp_verify_search_engine_error"
+msgstr "Hoặc XML bất hợp lệ hoặc các trÆ°á»ng Ä‘ang bị để trống. Vui lòng <a href=\"https://developer.mozilla.org/en/Creating_OpenSearch_plugins_for_Firefox\">Ä‘á»c tài liệu</a>, xác minh tiện ích của bạn, rồi thá»­ lại."
+
+#: views/developers/versions.thtml:75
+msgid "devcp_versions_a_cancel"
+msgstr "Hủy bá»"
+
+#: views/developers/versions.thtml:79
+msgid "devcp_versions_a_delete"
+msgstr "Xóa Phiên Bản"
+
+#: views/developers/versions.thtml:74
+msgid "devcp_versions_a_empty"
+msgstr "Xóa Phiên Bản Trống"
+
+#: views/developers/versions.thtml:71
+msgid "devcp_versions_a_remove"
+msgstr "Xóa?"
+
+#: views/developers/versions.thtml:91
+msgid "devcp_versions_add"
+msgstr "Thêm Phiên Bản Mới"
+
+#: views/developers/versions_delete.thtml:58
+msgid "devcp_versions_delete_a_cancel"
+msgstr "Hủy bá»"
+
+#: views/developers/versions_delete.thtml:56
+msgid "devcp_versions_delete_a_delete"
+msgstr "Xóa Phiên Bản"
+
+#. Followed by a list of reviews and files that will be removed.
+#: views/developers/versions_delete.thtml:50
+msgid "devcp_versions_delete_also"
+msgstr "Thao tác này cũng sẽ xóa:"
+
+#: views/developers/versions_delete.thtml:53
+msgid "devcp_versions_delete_files"
+msgid_plural "devcp_versions_delete_files"
+msgstr[0] "%s tập tin"
+msgstr[1] "%s tập tin"
+
+#. %s is the version number.
+#: views/developers/versions_delete.thtml:48
+msgid "devcp_versions_delete_header"
+msgstr "Xóa Phiên Bản %s?"
+
+#: views/developers/versions_delete.thtml:52
+msgid "devcp_versions_delete_reviews"
+msgid_plural "devcp_versions_delete_reviews"
+msgstr[0] "%s đánh giá"
+msgstr[1] "%s đánh giá"
+
+#. %s is the version number.
+#: views/developers/versions_delete.thtml:49
+msgid "devcp_versions_delete_sure"
+msgstr "Bạn có chắc là mình muốn xóa vĩnh viễn phiên bản %s không?"
+
+#: views/developers/versions_edit.thtml:102
+#: views/developers/versions_edit.thtml:155
+msgid "devcp_versions_edit_a_cancel"
+msgstr "Hủy bá»"
+
+#: views/developers/versions_edit.thtml:101
+msgid "devcp_versions_edit_a_delete"
+msgstr "Xóa Tập Tin"
+
+#: views/developers/versions_edit.thtml:165
+msgid "devcp_versions_edit_a_new_app"
+msgstr "Thêm Chương Trình Mới"
+
+#: views/developers/versions_edit.thtml:154
+msgid "devcp_versions_edit_a_remove_app"
+msgstr "Xóa Chương Trình"
+
+#: views/developers/versions_edit.thtml:114
+msgid "devcp_versions_edit_add"
+msgstr "Thêm Tập Tin Mới"
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/versions_edit.thtml:121
+msgid "devcp_versions_edit_adjust"
+msgstr "Äiá»u chỉnh thông tin chÆ°Æ¡ng trình ở đây sẽ cho phép ngÆ°á»i dùng cài đặt tiện ích của bạn cho dù install.rdf trong gói thông báo là tiện ích không tÆ°Æ¡ng thích. <a %s>Liệt kê các chÆ°Æ¡ng trình được há»— trợ</a>"
+
+#: views/developers/versions_edit.thtml:153
+msgid "devcp_versions_edit_compat_sure"
+msgstr "Bạn có <b>chắc</b> là mình muốn xóa tính tương thích với chương trình này không?"
+
+#: views/developers/versions_edit.thtml:100
+msgid "devcp_versions_edit_delete_sure"
+msgstr "Bạn có <b>chắc</b> là mình muốn xóa vĩnh viễn tập tin này không?"
+
+#: views/developers/versions_edit.thtml:203
+msgid "devcp_versions_edit_header_approval"
+msgstr "Thông tin Chấp thuận"
+
+#: views/developers/versions_edit.thtml:120
+msgid "devcp_versions_edit_header_compat"
+msgstr "Chương trình Tương thích"
+
+#: views/developers/versions_edit.thtml:74
+msgid "devcp_versions_edit_header_file"
+msgstr "Thông tin Tập tin"
+
+#: views/developers/versions_edit.thtml:189
+msgid "devcp_versions_edit_header_license"
+msgstr "Giấy phép"
+
+#. %s is the version number.
+#: views/developers/versions_edit.thtml:53
+msgid "devcp_versions_edit_header_manage"
+msgstr "Quản lí Phiên bản %s"
+
+#: views/developers/versions_edit.thtml:212
+msgid "devcp_versions_edit_header_notes"
+msgstr "Ghi chú Chấp thuận"
+
+#: views/developers/versions_edit.thtml:98
+msgid "devcp_versions_edit_img_delete"
+msgstr "Xóa Tập Tin"
+
+#. %1$s is the file id, e.g. 18723.
+#. %2$s is the platform name, e.g. ALL or Windows.
+#. %3$s is the _('date) created.
+#. %4$s is the status, e.g. "In Sandbox" or "Public".
+#. %5$s is the _('date') status was changed.
+#: views/developers/versions_edit.thtml:208
+msgid "devcp_versions_edit_li_file"
+msgstr "Tập tin %1$s (%2$s) được tạo vào %3$s và đã được thay đổi thành %4$s vào %5$s"
+
+#: views/developers/versions_edit.thtml:190
+msgid "devcp_versions_edit_license_description"
+msgstr "Vui lòng chá»n má»™t giấy phép phù hợp cho tiện ích của bạn. Giấy phép này xác định các quyá»n mà bạn xác lập cho mã nguồn của mình."
+
+#: views/developers/versions_edit.thtml:111
+msgid "devcp_versions_edit_no_files"
+msgstr "Không tìm thấy tập tin."
+
+#: views/developers/versions_edit.thtml:213
+msgid "devcp_versions_edit_optional"
+msgstr "Thông tin phụ cho Biên tập viên đánh giá phiên bản này."
+
+#: views/developers/versions_edit.thtml:151
+msgid "devcp_versions_edit_remove_compat"
+msgstr "Xóa Tính tương thích Chương trình"
+
+#: views/developers/versions_edit.thtml:167
+msgid "devcp_versions_edit_select_app"
+msgstr "Vui lòng Chá»n má»™t ChÆ°Æ¡ng trình"
+
+#: views/developers/versions_edit.thtml:78
+msgid "devcp_versions_edit_th_file"
+msgstr "Tập tin"
+
+#: views/developers/versions_edit.thtml:79
+msgid "devcp_versions_edit_th_platform"
+msgstr "Ná»n tảng"
+
+#: views/developers/versions_edit.thtml:80
+msgid "devcp_versions_edit_th_size"
+msgstr "Dung lượng"
+
+#: views/developers/versions_edit.thtml:81
+msgid "devcp_versions_edit_th_status"
+msgstr "Trạng thái"
+
+#: views/developers/versions_edit.thtml:183
+msgid "devcp_versions_edit_transbox_releasenotes_description"
+msgstr "Thông tin vá» các thay đổi, các tính năng má»›i, các lá»—i đã biết, và các thông tin hữu ích khác riêng cho bản phát hành/phiên bản này. Thông tin này cÅ©ng sẽ hiện hữu tá»›i những ngÆ°á»i dùng cập nhật tiện ích trong phần Quản lí Tiện ích Firefox."
+
+#: views/developers/versions_edit.thtml:182
+msgid "devcp_versions_edit_transbox_releasenotes_name"
+msgstr "Ghi chú Phát hành"
+
+#: views/developers/versions_edit.thtml:164
+msgid "devcp_versions_edit_unsaved_compat"
+msgstr "<strong>Bạn có các thay đổi chưa lưu.</strong> Tính tương thích sẽ không bị xóa cho tới khi bạn nhấn Cập nhật Phiên bản ở dưới."
+
+#: views/developers/versions_edit.thtml:113
+msgid "devcp_versions_edit_unsaved_files"
+msgstr "<strong>Bạn có các thay đổi chưa lưu.</strong> Tập tin sẽ không bị xóa cho tới khi bạn nhấn Cập nhật Phiên bản ở dưới."
+
+#: views/developers/versions_edit.thtml:218
+msgid "devcp_versions_edit_update"
+msgstr "Cập nhật Phiên bản"
+
+#: views/developers/versions.thtml:49
+msgid "devcp_versions_header_manage"
+msgstr "Quản lí Phiên bản và Tập tin"
+
+#: views/developers/versions.thtml:87
+msgid "devcp_versions_no_versions"
+msgstr "Không có phiên bản nào."
+
+#. %s is a version number, base 10.
+#: views/developers/versions.thtml:46
+msgid "devcp_versions_notice_success"
+msgstr "Phiên bản %s đã được xóa thành công."
+
+#: views/developers/versions.thtml:73
+msgid "devcp_versions_p_remove"
+msgstr "Phiên bản này không có tập tin nào đi kèm với nó và sẽ bị xóa. Bạn có muốn xóa phiên bản này không?"
+
+#: views/developers/versions.thtml:58
+msgid "devcp_versions_th_created"
+msgstr "Äã tạo"
+
+#: views/developers/versions.thtml:57
+msgid "devcp_versions_th_status"
+msgstr "Trạng thái"
+
+#: views/developers/versions.thtml:56
+msgid "devcp_versions_th_version"
+msgstr "Phiên bản"
+
+#: controllers/downloads_controller.php:91
+msgid "downloads_disable_warning"
+msgstr "Tiện ích này đã bị vô hiệu hóa."
+
+#: controllers/components/editors.php:57
+msgid "editor_review_error_addon_not_nominated"
+msgstr "Tiện ích này chưa được ứng cử."
+
+#: controllers/components/editors.php:213
+msgid "editor_review_error_file_not_pending"
+msgstr "Tập tin này không còn chỠđánh giá nữa."
+
+#. Actions are, for example: approving or rejecting
+#: controllers/components/editors.php:79
+#: controllers/components/editors.php:182
+msgid "editor_review_error_no_action"
+msgstr "Vui lòng chá»n má»™t thao tác đánh giá."
+
+#: controllers/components/editors.php:192
+msgid "editor_review_error_no_applications"
+msgstr "Vui lòng nhập tên chương trình mà bạn đã kiểm nghiệm."
+
+#. Comments are required when an editor approves or rejects an add-on.
+#: controllers/components/editors.php:84
+#: controllers/components/editors.php:187
+msgid "editor_review_error_no_comments"
+msgstr "Vui lòng nhập bình luận cho đánh giá."
+
+#: controllers/components/editors.php:161
+msgid "editor_review_error_no_files"
+msgstr "Vui lòng chá»n ít nhất má»™t tập tin để đánh giá."
+
+#: controllers/components/editors.php:197
+msgid "editor_review_error_no_operating_system"
+msgstr "Vui lòng nhập hệ Ä‘iá»u hành mà bạn đã kiểm nghiệm."
+
+#: views/editors/logs.thtml:51
+msgid "editorcp_logs_button_filter"
+msgstr "Bá»™ lá»c"
+
+#: views/editors/logs.thtml:44
+msgid "editorcp_logs_filter_by"
+msgstr "Lá»c theo kiểu/thao tác"
+
+#: views/editors/logs.thtml:42
+#: controllers/editors_controller.php:964
+msgid "editorcp_logs_page_heading"
+msgstr "Lưu kí Sự kiện"
+
+#: views/elements/developers/editorsmenu.thtml:60
+msgid "editorcp_menu_eventlog_link"
+msgstr "Lưu kí Sự kiện"
+
+#: views/elements/developers/editorsmenu.thtml:62
+msgid "editorcp_menu_mainpage_link"
+msgstr "Trở lại Trang Chính"
+
+#: views/elements/developers/editorsmenu.thtml:61
+msgid "editorcp_menu_reviewlog_link"
+msgstr "LÆ°u kí Äánh giá"
+
+#: views/elements/developers/editorsmenu.thtml:55
+msgid "editorcp_menu_summary_link"
+msgstr "Tóm tắt vỠBiên tập viên"
+
+#: views/elements/developers/editorsmenu.thtml:52
+msgid "editorcp_menu_title"
+msgstr "Công cụ Biên tập"
+
+#: views/editors/reviewlog.thtml:49
+msgid "editorcp_reviewlog_button_filter"
+msgstr "Bá»™ lá»c"
+
+#: views/editors/reviewlog.thtml:58
+msgid "editorcp_reviewlog_column_action"
+msgstr "Thao tác"
+
+#: views/editors/reviewlog.thtml:56
+msgid "editorcp_reviewlog_column_addon"
+msgstr "Tiện ích"
+
+#: views/editors/reviewlog.thtml:55
+msgid "editorcp_reviewlog_column_date"
+msgstr "Ngày"
+
+#: views/editors/reviewlog.thtml:57
+msgid "editorcp_reviewlog_column_editor"
+msgstr "Biên tập viên"
+
+#: views/editors/reviewlog.thtml:94
+msgid "editorcp_reviewlog_comments_hide"
+msgstr "Ẩn bình luận"
+
+#: views/editors/reviewlog.thtml:93
+msgid "editorcp_reviewlog_comments_show"
+msgstr "Hiện bình luận"
+
+#. %1$s and %2$s are full <input> tags for dates
+#: views/editors/reviewlog.thtml:45
+#, php-format
+msgid "editorcp_reviewlog_entries_between"
+msgstr "Xem các mục trong khoảng %s và %s"
+
+#: views/editors/reviewlog.thtml:104
+msgid "editorcp_reviewlog_none_found"
+msgstr "Không tìm thấy đánh giá nào trong khoảng thá»i gian này."
+
+#: views/editors/reviewlog.thtml:42
+msgid "editorcp_reviewlog_page_heading"
+msgstr "LÆ°u kí Äánh giá"
+
+#: views/editors/summary.thtml:61
+msgid "editorcp_summary_monthreviews_heading"
+msgstr "Äánh giá của Tháng"
+
+#: views/editors/summary.thtml:77
+msgid "editorcp_summary_neweditors_heading"
+msgstr "Biên tập viên Mới"
+
+#: views/editors/summary.thtml:42
+msgid "editorcp_summary_page_heading"
+msgstr "Tóm tắt vỠBiên tập viên"
+
+#: views/editors/summary.thtml:94
+msgid "editorcp_summary_recentactivity_heading"
+msgstr "Hoạt động Biên tập Gần đây"
+
+#: views/editors/summary.thtml:45
+msgid "editorcp_summary_totalreviews_heading"
+msgstr "Tổng số Bài đánh giá"
+
+#: controllers/editors_controller.php:248
+#: controllers/editors_controller.php:249
+msgid "editors_addon_review_pagetitle"
+msgstr "Äánh giá Tiện ích"
+
+#: controllers/editors_controller.php:349
+msgid "editors_error_js-formerror"
+msgstr "Vui lòng hoàn tất các phần sau:"
+
+#: controllers/editors_controller.php:350
+msgid "editors_error_review_one_file"
+msgstr "Vui lòng chá»n ít nhất má»™t tập tin để đánh giá."
+
+#: controllers/editors_controller.php:274
+msgid "editors_error_self_reviews_forbidden"
+msgstr "Không được phép tự đánh giá."
+
+#: controllers/editors_controller.php:699
+msgid "editors_external_software"
+msgstr "Phần má»m Bên ngoài"
+
+#: views/editors/featured.thtml:120
+#: views/editors/featured.thtml:121
+msgid "editors_featured_add_feature"
+msgstr "Thêm tính năng"
+
+#: views/editors/featured.thtml:126
+msgid "editors_featured_add_feature_submit"
+msgstr "Thêm"
+
+#: views/editors/featured.thtml:49
+#: controllers/editors_controller.php:832
+#: controllers/editors_controller.php:848
+msgid "editors_featured_addon_add_failure"
+msgstr "Thất bại khi thêm tính năng."
+
+#: controllers/editors_controller.php:851
+msgid "editors_featured_addon_add_success"
+msgstr "Thêm tính năng thành công."
+
+#: views/editors/featured.thtml:50
+#: controllers/editors_controller.php:839
+#: controllers/editors_controller.php:868
+#: controllers/editors_controller.php:886
+msgid "editors_featured_addon_edit_failure"
+msgstr "Thất bại khi chỉnh sửa tính năng."
+
+#: views/editors/featured.thtml:51
+#: controllers/editors_controller.php:888
+msgid "editors_featured_addon_edit_success"
+msgstr "Chỉnh sửa tính năng thành công."
+
+#: views/editors/featured.thtml:53
+#: controllers/editors_controller.php:861
+msgid "editors_featured_addon_invalid_locale"
+msgstr "Má»™t hay nhiá»u bản địa không hợp lệ."
+
+#: views/editors/featured.thtml:52
+#: controllers/editors_controller.php:906
+msgid "editors_featured_addon_remove_failure"
+msgstr "Thất bại khi xóa bỠtính năng"
+
+#: controllers/editors_controller.php:901
+msgid "editors_featured_addon_remove_success"
+msgstr "Xóa bỠtính năng thành công."
+
+#: controllers/editors_controller.php:915
+#: controllers/editors_controller.php:917
+msgid "editors_featured_addons_pagetitle"
+msgstr "Các Tiện-ích được Giới thiệu"
+
+#: views/editors/featured.thtml:54
+#: views/editors/featured.thtml:107
+msgid "editors_featured_edit_feature_submit"
+msgstr "Gá»­i Ä‘i"
+
+#: views/editors/featured.thtml:90
+#: views/editors/featured.thtml:91
+msgid "editors_featured_remove_feature"
+msgstr "Xóa tính năng"
+
+#: views/editors/queue.thtml:46
+msgid "editors_filter_queue"
+msgstr "Dãy Bá»™ Lá»c"
+
+#: views/editors/queue.thtml:182
+msgid "editors_helpful_links"
+msgstr "Liên kết Hữu ích"
+
+#: views/editors/queue.thtml:182
+msgid "editors_link_guide"
+msgstr "Hướng dẫn của Biên tập viên"
+
+#: views/editors/queue.thtml:182
+msgid "editors_link_policy"
+msgstr "Chính sách Tiện ích"
+
+#: views/editors/queue.thtml:47
+msgid "editors_notice_filter_session"
+msgstr "Các bá»™ lá»c này vẫn sẽ giữ nguyên cho phiên này hoặc cho đến khi bị xóa."
+
+#. %1 is the queue mode
+#: views/editors/queue.thtml:177
+#: views/admin/flagged_queue.thtml:89
+msgid "editors_notice_none_found"
+msgstr "Hiện tại không có tiện ích nào thuộc kiểu này để đánh giá."
+
+#: controllers/editors_controller.php:1040
+msgid "editors_one_day"
+msgstr "1 ngày"
+
+#: controllers/editors_controller.php:1048
+msgid "editors_one_hour"
+msgstr "1 giá»"
+
+#: controllers/editors_controller.php:1056
+msgid "editors_one_minute"
+msgstr "1 phút"
+
+#: controllers/editors_controller.php:64
+#: controllers/editors_controller.php:73
+#: controllers/editors_controller.php:77
+msgid "editors_pagetitle"
+msgstr "Công cụ Biên tập"
+
+#. %s is a comma separated list of platforms. Example: Windows, OS X
+#: controllers/editors_controller.php:680
+#: controllers/editors_controller.php:683
+#, php-format
+msgid "editors_platform_x_only"
+msgstr "Chỉ cho %s"
+
+#: controllers/editors_controller.php:695
+msgid "editors_pre-release"
+msgstr "Phát hành thử"
+
+#. %1 is the app name
+#: views/editors/queue.thtml:131
+#, php-format
+msgid "editors_queue_app_compatibility"
+msgstr "Tính tương thích %s"
+
+#: views/editors/queue.thtml:51
+msgid "editors_queue_filter_label_addon"
+msgstr "Tiện ích hoặc Äịa chỉ Tác giả"
+
+#: views/editors/queue.thtml:72
+msgid "editors_queue_filter_label_addontypes"
+msgstr "Kiểu tiện ích"
+
+#: views/editors/queue.thtml:56
+msgid "editors_queue_filter_label_application"
+msgstr "Chương trình"
+
+#: views/editors/queue.thtml:61
+msgid "editors_queue_filter_label_maxversion"
+msgstr "Phiên bản Cao nhất"
+
+#: views/editors/queue.thtml:78
+msgid "editors_queue_filter_label_platforms"
+msgstr "Ná»n tảng"
+
+#: views/editors/queue.thtml:66
+msgid "editors_queue_filter_label_submissionage"
+msgstr "Thá»i gian Gá»­i lên (ngày)"
+
+#. %1$s is a number
+#: views/editors/queue.thtml:90
+msgid "editors_queue_filter_result_count"
+msgid_plural "editors_queue_filter_result_count"
+msgstr[0] "Kết quả tìm kiếm đã được lá»c của bạn: <strong>%1$s</strong> Tiện ích"
+msgstr[1] "Kết quả tìm kiếm đã được lá»c của bạn: <strong>%1$s</strong> Tiện ích"
+
+#: views/editors/queue.thtml:84
+msgid "editors_queue_submit_clean"
+msgstr "Xóa trắng"
+
+#: views/editors/queue.thtml:83
+msgid "editors_queue_submit_filter"
+msgstr "Bá»™ lá»c"
+
+#: controllers/editors_controller.php:133
+msgid "editors_queues_disabled"
+msgstr "Tất cả dãy đánh giá hiện đang bị vô hiệu hóa. Vui lòng kiểm tra lại sau."
+
+#: views/editors/review.thtml:149
+msgid "editors_review_a_edit_item"
+msgstr "Chỉnh sửa Mục"
+
+#: views/editors/review.thtml:146
+msgid "editors_review_a_item_history"
+msgstr "Lược sử của Mục"
+
+#: views/editors/review.thtml:148
+msgid "editors_review_a_item_homepage"
+msgstr "Trang chủ của Mục"
+
+#: views/editors/review.thtml:145
+msgid "editors_review_a_item_overview"
+msgstr "Tổng quan vỠMục"
+
+#: views/editors/review.thtml:147
+msgid "editors_review_a_previews"
+msgstr "Xem trÆ°á»›c"
+
+#: controllers/editors_controller.php:345
+msgid "editors_review_action"
+msgstr "Thao tác Äánh giá"
+
+#: views/editors/review.thtml:159
+msgid "editors_review_action_info"
+msgstr "Yêu cầu Thêm Thông tin"
+
+#: views/editors/review.thtml:157
+msgid "editors_review_action_public"
+msgstr "ÄÆ°a ra Công cá»™ng"
+
+#: views/editors/review.thtml:160
+msgid "editors_review_action_request_superreview"
+msgstr "Äá» nghị Äánh giá Cấp cao"
+
+#: views/editors/review.thtml:158
+msgid "editors_review_action_sandbox"
+msgstr "Vẫn để trong Hộp cát"
+
+#: controllers/editors_controller.php:346
+msgid "editors_review_comments"
+msgstr "Äánh giá Bình luận"
+
+#: views/editors/review.thtml:182
+msgid "editors_review_details_info_request"
+msgstr "Dùng biểu mẫu này để yêu cầu thêm thông tin từ tác giả. Há» sẽ nhận được má»™t email và có thể trả lá»i ngay tại đây. Bạn cÅ©ng sẽ được thông báo qua email khi há» trả lá»i."
+
+#: views/editors/review.thtml:174
+msgid "editors_review_details_nominated_public"
+msgstr "Phần này sẽ đánh dấu tiện ích cùng các tập tin và phiên bản gần nhất của nó là công cộng. Các phiên bản tương lai sẽ ở trong hộp cát cho đến khi chúng được đánh giá bởi một biên tập viên."
+
+#: views/editors/review.thtml:177
+msgid "editors_review_details_nominated_sandbox"
+msgstr "Phần này vẫn sẽ giữ tiện ích lại trong hộp cát."
+
+#: views/editors/review.thtml:166
+msgid "editors_review_details_pending_public"
+msgstr "Phần này sẽ chấp thuận một phiên bản trong hộp cát của một tiện ích công cộng được xuất hiện ngoài công cộng."
+
+#: views/editors/review.thtml:169
+msgid "editors_review_details_pending_sandbox"
+msgstr "Phần này vẫn sẽ giữ một phiên bản hộp cát của một tiện ích công cộng trong hộp cát."
+
+#: views/editors/review.thtml:185
+msgid "editors_review_details_superreview"
+msgstr "Nếu bạn quan tâm vá» tính bảo mật, vấn Ä‘á» bản quyá»n của tiện ích, hoặc các vấn Ä‘á» khác mà quản trị viên cần xem xét, hãy nhập bình luận của bạn vào ô bên dÆ°á»›i. Chúng sẽ chỉ được gá»­i tá»›i quản trị viên, chứ không gá»­i tá»›i tác giả."
+
+#: views/editors/review.thtml:134
+msgid "editors_review_file_diff_link"
+msgstr "So sánh phiên bản công cộng"
+
+#: views/editors/review.thtml:131
+msgid "editors_review_file_viewcontents_link"
+msgstr "Xem Ná»™i Dung"
+
+#: views/editors/review.thtml:65
+msgid "editors_review_header_authors"
+msgstr "Tác giả:"
+
+#: views/editors/review.thtml:79
+msgid "editors_review_header_categories"
+msgstr "Phân mục:"
+
+#: views/editors/review.thtml:92
+msgid "editors_review_header_compatibility"
+msgstr "Tính tương thích:"
+
+#: views/editors/review.thtml:251
+msgid "editors_review_header_description"
+msgstr "Mô tả"
+
+#: views/editors/review.thtml:275
+msgid "editors_review_header_devcomments"
+msgstr "Bình luận của Nhà phát triển"
+
+#: views/editors/review.thtml:263
+msgid "editors_review_header_eula"
+msgstr "Thá»a thuận NgÆ°á»i dùng Cuối"
+
+#: views/editors/review.thtml:115
+msgid "editors_review_header_files"
+msgstr "Tập tin:"
+
+#: views/editors/review.thtml:284
+msgid "editors_review_header_itemhistory"
+msgstr "Lược sử Danh mục"
+
+#: views/editors/review.thtml:232
+msgid "editors_review_header_nominationmessage"
+msgstr "Thông Ä‘iệp Äá» cá»­"
+
+#: views/editors/review.thtml:311
+msgid "editors_review_header_previews"
+msgstr "Xem trÆ°á»›c"
+
+#: views/editors/review.thtml:269
+msgid "editors_review_header_privacy"
+msgstr "Chính sách Riêng tư"
+
+#. %1 is the add-on name and version
+#: views/editors/review.thtml:56
+#, php-format
+msgid "editors_review_header_review"
+msgstr "Äánh giá %s"
+
+#: views/editors/review.thtml:239
+msgid "editors_review_header_reviewernotes"
+msgstr "Ghi chú cho NgÆ°á»i đánh giá"
+
+#: views/editors/review.thtml:245
+msgid "editors_review_header_summary"
+msgstr "Tóm tắt"
+
+#: views/editors/review.thtml:257
+msgid "editors_review_header_versionnotes"
+msgstr "Ghi chú Phiên bản"
+
+#. a noun: shown in an add-on's editor review history
+#: views/elements/developers/editors_review_history_item.thtml:80
+msgid "editors_review_history_info_reply"
+msgstr "Trả lá»i"
+
+#: views/elements/developers/editors_review_history_item.thtml:78
+msgid "editors_review_history_info_request"
+msgstr "Yêu cầu Thông tin"
+
+#: views/elements/developers/editors_review_history_item.thtml:62
+#: views/editors/reviewlog.thtml:77
+msgid "editors_review_history_nominated_adminreview"
+msgstr "Äánh giá của Quản trị"
+
+#: views/elements/developers/editors_review_history_item.thtml:56
+#: views/editors/reviewlog.thtml:71
+msgid "editors_review_history_nominated_approved"
+msgstr "Äá» cá»­ Äược chấp thuận / Công cá»™ng"
+
+#: views/elements/developers/editors_review_history_item.thtml:59
+#: views/editors/reviewlog.thtml:74
+msgid "editors_review_history_nominated_denied"
+msgstr "Äá» cá»­ Bị từ chối / Há»™p cát"
+
+#: views/editors/review.thtml:303
+msgid "editors_review_history_nonefound"
+msgstr "Không tìm thấy các mục đánh giá trước đây."
+
+#: views/elements/developers/editors_review_history_item.thtml:73
+#: views/editors/reviewlog.thtml:88
+msgid "editors_review_history_pending_adminreview"
+msgstr "Äánh giá của Quản trị"
+
+#: views/elements/developers/editors_review_history_item.thtml:67
+#: views/editors/reviewlog.thtml:82
+msgid "editors_review_history_pending_approved"
+msgstr "Chấp thuận / Công cộng"
+
+#: views/elements/developers/editors_review_history_item.thtml:70
+#: views/editors/reviewlog.thtml:85
+msgid "editors_review_history_pending_denied"
+msgstr "Từ chối / Hộp cát"
+
+#. link text in an add-on's editor review history, allowing to hide and show an information request's replies
+#. %1 is the number of replies
+#: views/elements/developers/editors_review_history_item.thtml:90
+msgid "editors_review_history_show_hide_replies"
+msgid_plural "editors_review_history_show_hide_replies"
+msgstr[0] "Hiện/Ẩn Trả lá»i (%1$s)"
+msgstr[1] "Hiện/Ẩn Trả lá»i (%1$s)"
+
+#: views/editors/review.thtml:208
+msgid "editors_review_label_applications"
+msgstr "Ứng dụng:"
+
+#: views/editors/review.thtml:196
+msgid "editors_review_label_cannedresponse"
+msgstr "hoặc chá»n má»™t phản hồi đã được đóng kín:"
+
+#: views/editors/review.thtml:190
+msgid "editors_review_label_comments"
+msgstr "Bình luận:"
+
+#: views/editors/review.thtml:204
+msgid "editors_review_label_operating_systems"
+msgstr "Hệ Ä‘iá»u hành:"
+
+#: views/editors/review.thtml:285
+#: views/editors/review.thtml:312
+msgid "editors_review_link_pagetop"
+msgstr "Trên cùng"
+
+#: views/editors/review.thtml:141
+msgid "editors_review_mulitple_notice"
+msgstr "LÆ°u ý: Chỉ nên đánh giá nhiá»u hÆ¡n má»™t tập tin nếu bạn đã kiểm tra MỌI tập tin mà bạn chá»n."
+
+#: views/editors/review.thtml:51
+msgid "editors_review_next_link"
+msgstr "tiếp &raquo;"
+
+#: views/editors/review.thtml:322
+msgid "editors_review_previews_notfound"
+msgstr "Không tìm thấy ảnh xem trước."
+
+#: views/editors/review.thtml:50
+msgid "editors_review_previous_link"
+msgstr "&laquo; trÆ°á»›c"
+
+#: controllers/editors_controller.php:144
+#: controllers/editors_controller.php:146
+msgid "editors_review_queue_pagetitle"
+msgstr "Danh sách chá» Äánh giá"
+
+#. %1 is the add-ons rank in the queue, %2 is the total queue length
+#: views/editors/review.thtml:47
+msgid "editors_review_rank_in_queue"
+msgstr "<strong># %1$s</strong> trên %2$s trong danh sách chá»"
+
+#. %1 is the add-ons rank in the queue, %2 is the total queue length. Both numbers
+#: views/editors/review.thtml:45
+msgid "editors_review_rank_in_queue_filtered"
+msgstr "<strong># %1$s</strong> trên %2$s trong danh sách chá» (đã lá»c)"
+
+#: views/editors/review.thtml:223
+msgid "editors_review_submit_process_action"
+msgstr "Thao tác Xử lí"
+
+#: views/editors/review.thtml:293
+msgid "editors_review_th_action"
+msgstr "Thao tác"
+
+#: views/editors/review.thtml:294
+msgid "editors_review_th_comments"
+msgstr "Bình luận"
+
+#: views/editors/review.thtml:291
+msgid "editors_review_th_date"
+msgstr "Ngày"
+
+#: views/editors/review.thtml:292
+msgid "editors_review_th_reviewer"
+msgstr "NgÆ°á»i đánh giá"
+
+#: views/editors/review.thtml:290
+msgid "editors_review_th_version_file"
+msgstr "Phiên bản / Tập tin"
+
+#: views/editors/review.thtml:217
+msgid "editors_review_update_notify_once"
+msgstr "Báo tôi khi tiện ích này được cập nhật lần tới. (Các cập nhật tiếp theo sẽ không gửi email)"
+
+#: controllers/editors_controller.php:298
+msgid "editors_reviewed_successfully"
+msgstr "Äánh giá được tiến hành thành công."
+
+#: views/editors/reviews_queue.thtml:106
+msgid "editors_reviews_action_delete_review"
+msgstr "Xóa đánh giá"
+
+#: views/editors/reviews_queue.thtml:104
+msgid "editors_reviews_action_keep"
+msgstr "Xóa cá»; tiếp tục đánh giá"
+
+#: views/editors/reviews_queue.thtml:102
+msgid "editors_reviews_action_skip"
+msgstr "Bá» qua"
+
+#: views/editors/reviews_queue.thtml:100
+msgid "editors_reviews_header_action"
+msgstr "Thao tác"
+
+#: views/editors/reviews_queue.thtml:67
+msgid "editors_reviews_in_reply_to"
+msgstr "Trả lá»i:"
+
+#: controllers/editors_controller.php:748
+msgid "editors_reviews_processed"
+msgstr "Äánh giá đã được tiến hành thành công!"
+
+#: views/editors/reviews_queue.thtml:117
+msgid "editors_reviews_queue_empty"
+msgstr "Hiện tại không có đánh giá nào Ä‘ang được Ä‘iá»u chỉnh."
+
+#: views/editors/reviews_queue.thtml:111
+msgid "editors_reviews_submit_process_reviews"
+msgstr "Tiến hành Äánh giá"
+
+#: controllers/editors_controller.php:691
+msgid "editors_site_specific"
+msgstr "Riêng biệt của Trang"
+
+#: controllers/editors_controller.php:348
+msgid "editors_tested_app"
+msgstr "Ứng dụng đã được Thử nghiệm"
+
+#: controllers/editors_controller.php:347
+msgid "editors_tested_os"
+msgstr "Hệ Ä‘iá»u hành đã được Thá»­ nghiệm"
+
+#: views/editors/queue.thtml:151
+msgid "editors_th_additional_info"
+msgstr "Thông tin Thêm"
+
+#: views/editors/featured.thtml:63
+#: views/editors/queue.thtml:109
+#: views/admin/flagged_queue.thtml:53
+msgid "editors_th_addon"
+msgstr "Tiện ích"
+
+#: views/editors/queue.thtml:125
+msgid "editors_th_addontype"
+msgstr "Kiểu"
+
+#: views/editors/featured.thtml:64
+msgid "editors_th_locales"
+msgstr "Giới hạn cho các bản địa?"
+
+#: views/editors/queue.thtml:148
+msgid "editors_th_nomination_age"
+msgstr "Thá»i gian trong Hàng chá»"
+
+#: views/editors/queue.thtml:101
+#: views/editors/queue.thtml:117
+#: views/editors/queue.thtml:144
+msgid "editors_th_sort_ascending"
+msgstr "Sắp xếp thuận chiá»u"
+
+#: views/editors/queue.thtml:105
+#: views/editors/queue.thtml:121
+#: views/editors/queue.thtml:140
+msgid "editors_th_sort_descending"
+msgstr "Sắp xếp ngược chiá»u"
+
+#. %s is a number
+#: controllers/editors_controller.php:1036
+#, php-format
+msgid "editors_x_days"
+msgstr "%s ngày"
+
+#. %s is a number
+#: controllers/editors_controller.php:1044
+#, php-format
+msgid "editors_x_hours"
+msgstr "%s giá»"
+
+#. %s is a number
+#: controllers/editors_controller.php:1052
+#, php-format
+msgid "editors_x_minutes"
+msgstr "%s phút"
+
+#: views/errors/error401.thtml:50
+#: controllers/components/simple_acl.php:81
+#: controllers/components/simple_acl.php:82
+#: controllers/components/simple_acl.php:83
+#: controllers/components/amo.php:607
+#: controllers/components/amo.php:608
+#: controllers/components/amo.php:609
+#: controllers/reviews_controller.php:353
+#: controllers/reviews_controller.php:485
+#: controllers/collections_controller.php:438
+#: controllers/collections_controller.php:496
+#: controllers/collections_controller.php:504
+#: controllers/collections_controller.php:971
+#: controllers/collections_controller.php:1034
+#: controllers/collections_controller.php:1077
+msgid "error_access_denied"
+msgstr "Truy cập Bị từ chối"
+
+#: views/errors/error401.thtml:52
+msgid "error_access_denied_message"
+msgstr "Bạn không có quyá»n xem trang này."
+
+#: controllers/collections_controller.php:1039
+msgid "error_addon_exists"
+msgstr "Tiện ích đã tồn tại!"
+
+#: controllers/developers_controller.php:200
+#: controllers/developers_controller.php:593
+#: controllers/developers_controller.php:1016
+#: controllers/developers_controller.php:1429
+#: controllers/downloads_controller.php:95
+#: controllers/downloads_controller.php:102
+#: controllers/downloads_controller.php:164
+#: controllers/statistics_controller.php:135
+#: controllers/previews_controller.php:115
+#: controllers/previews_controller.php:206
+#: controllers/previews_controller.php:307
+#: controllers/reviews_controller.php:77
+#: controllers/reviews_controller.php:240
+#: controllers/reviews_controller.php:332
+#: controllers/reviews_controller.php:340
+#: controllers/api_controller.php:123
+#: controllers/api_controller.php:759
+#: controllers/addons_controller.php:131
+#: controllers/addons_controller.php:197
+#: controllers/addons_controller.php:1407
+#: controllers/addons_controller.php:1465
+#: controllers/addons_controller.php:1469
+#: controllers/addons_controller.php:1503
+#: controllers/editors_controller.php:265
+#: controllers/collections_controller.php:1041
+#: controllers/collections_controller.php:1074
+msgid "error_addon_notfound"
+msgstr "Không tìm thấy tiện ích!"
+
+#: controllers/files_controller.php:83
+#: controllers/files_controller.php:196
+msgid "error_addon_notviewable"
+msgstr "Tiện ích không thể xem được tại đây."
+
+#: controllers/reviews_controller.php:246
+msgid "error_addon_selfreview"
+msgstr "Bạn không thể tự đánh giá tiện ích của bạn."
+
+#: controllers/addons_controller.php:970
+msgid "error_browse_no_addons"
+msgstr "Không có tiện ích trong phân mục này!"
+
+#: controllers/api_controller.php:424
+msgid "error_collection_feed_notfound"
+msgstr "Không tìm thấy feed tiện ích"
+
+#: views/users/register.thtml:65
+#: views/users/edit.thtml:194
+msgid "error_email_invalid"
+msgstr "Äây không phải là địa chỉ email hợp lệ."
+
+#: views/users/pwreset.thtml:74
+#: views/users/register.thtml:70
+#: views/users/register.thtml:80
+#: views/users/register.thtml:86
+#: views/users/edit.thtml:105
+#: views/users/edit.thtml:111
+#: views/users/edit.thtml:192
+#: views/admin/users_edit.thtml:78
+#: views/admin/users_edit.thtml:83
+#: views/reviews/add.thtml:80
+#: views/reviews/add.thtml:104
+msgid "error_field_required"
+msgstr "Phần này không được để trống."
+
+#: controllers/files_controller.php:75
+#: controllers/files_controller.php:93
+#: controllers/files_controller.php:96
+#: controllers/files_controller.php:163
+#: controllers/files_controller.php:176
+#: controllers/files_controller.php:185
+#: controllers/files_controller.php:204
+#: controllers/editors_controller.php:412
+msgid "error_file_notfound"
+msgstr "Không tìm thấy tập tin!"
+
+#. %s is a filename
+#: controllers/editors_controller.php:430
+#, php-format
+msgid "error_file_x_notfound"
+msgstr "Lỗi tập tin: %s không tồn tại."
+
+#: views/collections/add.thtml:55
+#: views/collections/edit.thtml:89
+#: views/users/register.thtml:54
+#: views/users/edit.thtml:81
+#: views/reviews/add.thtml:70
+#: controllers/groups_controller.php:80
+#: controllers/groups_controller.php:102
+msgid "error_formerrors"
+msgstr "Có lỗi trong biểu mẫu này. Vui lòng sửa chúng và gửi lại."
+
+#: views/users/register.thtml:109
+msgid "error_invalid_captcha"
+msgstr "Captcha không đúng, hãy thử lại!"
+
+#: views/users/register.thtml:100
+#: views/users/edit.thtml:125
+#: views/admin/users_edit.thtml:101
+msgid "error_invalid_url"
+msgstr "URL có định dạng sai. URL đúng sẽ trông như thế này http://www.mozilla.com/vi."
+
+#. %s is a string representing what's missing. Example: file_id
+#: controllers/downloads_controller.php:65
+#: controllers/users_controller.php:185
+#: controllers/users_controller.php:264
+#: controllers/users_controller.php:559
+#: controllers/users_controller.php:653
+#: controllers/reviews_controller.php:71
+#: controllers/reviews_controller.php:234
+#: controllers/reviews_controller.php:325
+#: controllers/reviews_controller.php:473
+#: controllers/reviews_controller.php:475
+#: controllers/addons_controller.php:182
+#: controllers/addons_controller.php:1381
+#: controllers/addons_controller.php:1455
+#: controllers/collections_controller.php:266
+#: controllers/collections_controller.php:285
+#: controllers/collections_controller.php:346
+#: controllers/collections_controller.php:443
+#: controllers/collections_controller.php:482
+#: controllers/collections_controller.php:936
+#: controllers/collections_controller.php:959
+#: controllers/collections_controller.php:960
+#: controllers/collections_controller.php:975
+#: controllers/collections_controller.php:977
+#: controllers/collections_controller.php:994
+#: controllers/collections_controller.php:1003
+#: controllers/collections_controller.php:1016
+#: controllers/collections_controller.php:1017
+#: controllers/collections_controller.php:1024
+#: controllers/collections_controller.php:1070
+#: controllers/collections_controller.php:1090
+#, php-format
+msgid "error_missing_argument"
+msgstr "Thiếu tham số: %s"
+
+#: controllers/components/amo.php:507
+#: controllers/components/amo.php:532
+msgid "error_no_files_in_addon"
+msgstr "Không có Tập tin"
+
+#: controllers/previews_controller.php:200
+msgid "error_preview_notfound"
+msgstr "Không tìm thấy ảnh xem trước!"
+
+#: views/addons/display.thtml:400
+#: views/reviews/add.thtml:98
+msgid "error_review_rating_required"
+msgstr "Bạn phải chá»n má»™t mức xếp hạng."
+
+#: controllers/users_controller.php:160
+msgid "error_user_already_confirmed"
+msgstr "Tài khoản ngÆ°á»i dùng này đã được xác nhận."
+
+#: controllers/users_controller.php:202
+#: controllers/users_controller.php:276
+#: controllers/users_controller.php:569
+#: controllers/users_controller.php:581
+#: controllers/users_controller.php:587
+#: controllers/users_controller.php:610
+#: controllers/users_controller.php:627
+msgid "error_user_badconfirmationcode"
+msgstr "Mã xác nhận không hợp lệ!"
+
+#: views/users/pwreset.thtml:79
+#: views/users/register.thtml:75
+#: views/users/edit.thtml:183
+msgid "error_user_confirmpw_nomatch"
+msgstr "Mật khẩu không khớp."
+
+#: views/users/register.thtml:65
+#: views/users/edit.thtml:190
+#: controllers/users_controller.php:617
+msgid "error_user_email_notunique"
+msgstr "Äịa chỉ email này đã được dùng bởi ngÆ°á»i khác."
+
+#: controllers/users_controller.php:596
+msgid "error_user_emailchange_expired"
+msgstr "Thá»i gian thay đổi email đã hết hạn. Vui lòng thay đổi lại địa chỉ email trong hồ sÆ¡ của bạn và nhấn vào liên kết trong email ngay khi bạn nhận được nó."
+
+#: controllers/collections_controller.php:985
+msgid "error_user_exists"
+msgstr "NgÆ°á»i dùng chỉ có thể có má»™t vai trò. Vui lòng xóa ngÆ°á»i dùng khá»i các vai trò hiện tại trÆ°á»›c khi tiếp tục."
+
+#: views/users/register.thtml:91
+#: views/users/edit.thtml:116
+#: views/admin/users_edit.thtml:88
+msgid "error_user_nickname_notunique"
+msgstr "Tên truy nhập này đã được dùng."
+
+#: views/users/pwreset.thtml:54
+#: controllers/users_controller.php:191
+#: controllers/users_controller.php:270
+#: controllers/users_controller.php:603
+#: controllers/users_controller.php:659
+#: controllers/collections_controller.php:988
+#: controllers/collections_controller.php:998
+msgid "error_user_notfound"
+msgstr "Không tìm thấy ngÆ°á»i dùng!"
+
+#: views/users/activatefirst.thtml:47
+msgid "error_user_unconfirmed"
+msgstr "Vui lòng xác nhận tài khoản của bạn trước bằng mã xác nhận bạn nhận được trong email."
+
+#: views/users/login.thtml:67
+msgid "error_username_or_pw_wrong"
+msgstr "Sai tên truy nhập hoặc mật khẩu!"
+
+#: controllers/editors_controller.php:260
+msgid "error_version_notfound"
+msgstr "Không tìm thấy phiên bản!"
+
+#: views/users/delete.thtml:125
+#: views/users/edit.thtml:173
+msgid "error_wrong_password"
+msgstr "Nhập sai mật khẩu!"
+
+#: views/elements/amo2009/homepage_addon.thtml:122
+#: views/elements/feature.thtml:122
+msgid "feature_learnmore"
+msgstr "Tìm hiểu thêm"
+
+#. %1 is the add-on name
+#: views/elements/amo2009/homepage_addon.thtml:123
+#: views/elements/feature.thtml:123
+#, php-format
+msgid "feature_learnmore_about_addon"
+msgstr "Tìm hiểu thêm vỠ%1$s"
+
+#. %1$s is a number
+#: views/elements/amo2009/reviews.thtml:52
+#: views/elements/addon_listitem.thtml:112
+#: views/elements/feature.thtml:99
+#: views/addons/browse_thumbs.thtml:86
+#, php-format
+msgid "feature_reviews"
+msgid_plural "feature_reviews"
+msgstr[0] "%1$s đánh giá"
+msgstr[1] "%1$s đánh giá"
+
+#: views/elements/amo2009/homepage_addon.thtml:127
+#: views/elements/feature.thtml:127
+msgid "feature_view_more_from_category"
+msgstr "Xem thêm trong"
+
+#. This appears on a page that views the source of an add-on. This link will return
+#. the user to the add-on's main page
+#: views/files/browse.thtml:65
+msgid "file_browser_link_addon"
+msgstr "Trở lại tiện ích"
+
+#. There is a list of directories and files on the page. Clicking this will show the
+#. contents of all the directories (normally you would click on each one to see the
+#. contents)
+#: views/files/browse.thtml:67
+msgid "file_browser_link_expand_all"
+msgstr "Mở rộng tất cả"
+
+#. This appears on a page that views the source of an add-on. This link will return
+#. the user to the add-on's review page (it only appears if the add-on is being
+#. reviewed)
+#: views/files/browse.thtml:64
+msgid "file_browser_link_review"
+msgstr "Trở lại đánh giá"
+
+#. The title of the page for viewing an add-on's source.
+#. %1$s is the name of the add-on
+#. %2$s is the name of the current application (e.g. Firefox or Thunderbird)
+#: views/files/browse.thtml:46
+msgid "file_browser_title"
+msgstr "%1$s :: Duyệt Tập Tin :: Tiện ích %2$s"
+
+#. This appears on a page that views the source of an add-on. There is a list of
+#. directories and files on the page. Clicking this link will toggle between an
+#. expanded or a collapsed list. This string should be kept short.
+#: views/files/browse.thtml:68
+msgid "file_browser_toggle_expand_collapse"
+msgstr "+/-"
+
+#. Link text for the AMO About page.
+#: views/elements/footer.thtml:72
+#: views/layouts/amo2009.thtml:341
+msgid "footer_a_about"
+msgstr "Giới thiệu"
+
+#. Link text to the AMO blog.
+#: views/elements/footer.thtml:74
+#: views/layouts/amo2009.thtml:343
+msgid "footer_a_blog"
+msgstr "Blog"
+
+#. Link text to the Frequently Asked Questions page.
+#: views/elements/footer.thtml:73
+#: views/layouts/amo2009.thtml:342
+msgid "footer_a_faq"
+msgstr "FAQ"
+
+#. Full text for the FAQ abbreviation.
+#: views/elements/footer.thtml:73
+#: views/pages/collector_features.thtml:72
+#: views/layouts/amo2009.thtml:342
+msgid "footer_abbr_faq"
+msgstr "Há»i đáp ThÆ°á»ng gặp"
+
+#: views/elements/footer.thtml:67
+#: views/layouts/amo2009.thtml:336
+msgid "footer_all_rights_reserved"
+msgstr "Má»i quyá»n được bảo lÆ°u. <br/><b>Vào trang web</b> <a href=\"http://vi.mozdev.org\">Mozilla Việt Nam</a>"
+
+#: views/elements/footer.thtml:67
+#: views/layouts/amo2009.thtml:336
+msgid "footer_copyright"
+msgstr "Bản quyá»n"
+
+#: views/elements/footer.thtml:71
+#: views/layouts/amo2009.thtml:340
+msgid "footer_credits"
+msgstr "Công trạng"
+
+#: views/elements/footer.thtml:76
+#: views/layouts/amo2009.thtml:346
+msgid "footer_disclaimer"
+msgstr "Mozilla cung cấp liên kết đến các ứng dụng này theo đúng trách nhiệm của mình, và không đại diện cho ứng dụng hoặc bất kì thông tin nào liên quan đến chúng. Má»i câu há»i, phàn nàn hoặc yêu cầu đối vá»›i các ứng dụng này phải được chuyển trá»±c tiếp tá»›i nhà viết phần má»m tÆ°Æ¡ng ứng."
+
+#: views/elements/footer.thtml:61
+#: views/layouts/amo2009.thtml:332
+msgid "footer_lang_form_lang_submit_go"
+msgstr "Gá»­i Ä‘i"
+
+#: views/elements/footer.thtml:70
+#: views/layouts/amo2009.thtml:339
+msgid "footer_legal_notices"
+msgstr "Lưu ý Pháp lí"
+
+#: views/elements/footer.thtml:50
+#: views/layouts/amo2009.thtml:321
+msgid "footer_other_languages"
+msgstr "Ngôn ngữ khác:"
+
+#: views/elements/footer.thtml:69
+#: views/layouts/amo2009.thtml:338
+msgid "footer_privacy_policy"
+msgstr "Chính sách Riêng tư"
+
+#: models/addontype.php:79
+msgid "general_addontype_dict"
+msgstr "Từ điển"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:100
+msgid "general_addontype_dict_plural"
+msgstr "Từ điển"
+
+#: models/addontype.php:75
+msgid "general_addontype_extension"
+msgstr "Phần mở rộng"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:98
+msgid "general_addontype_extension_plural"
+msgstr "Phần mở rộng"
+
+#: models/addontype.php:85
+msgid "general_addontype_lpaddon"
+msgstr "Gói ngôn ngữ (Tiện ích)"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:103
+msgid "general_addontype_lpaddon_plural"
+msgstr "Gói ngôn ngữ (Tiện ích)"
+
+#: models/addontype.php:83
+msgid "general_addontype_lpapp"
+msgstr "Gói ngôn ngữ (Chương trình)"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:102
+msgid "general_addontype_lpapp_plural"
+msgstr "Gói ngôn ngữ (Chương trình)"
+
+#: models/addontype.php:87
+msgid "general_addontype_plugin"
+msgstr "Phần bổ trợ"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:104
+msgid "general_addontype_plugin_plural"
+msgstr "Phần bổ trợ"
+
+#: models/addontype.php:81
+msgid "general_addontype_search"
+msgstr "Máy tìm kiếm"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:101
+msgid "general_addontype_search_plural"
+msgstr "Máy tìm kiếm"
+
+#: models/addontype.php:77
+msgid "general_addontype_theme"
+msgstr "Giao diện"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:99
+msgid "general_addontype_theme_plural"
+msgstr "Giao diện"
+
+#: config/language.php:367
+msgid "general_languages_all_locales"
+msgstr "Tất cả Bản địa"
+
+#: views/layouts/amo2009.thtml:249
+msgid "header_brand_name"
+msgstr "Mozilla"
+
+#. %1$s is the application name. Example: Firefox
+#: views/elements/header.thtml:111
+#: views/elements/header.thtml:122
+#: views/layouts/amo2009.thtml:248
+#, php-format
+msgid "header_home_tooltip"
+msgstr "Trở lại trang chủ Tiện ích %1$s"
+
+#: views/elements/header.thtml:87
+msgid "header_main_firefox_header"
+msgstr "Firefox Add-ons - Tiện ích Cáo Lửa Siêu Việt"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:218
+msgid "header_main_firefox_header_with_logo"
+msgstr "Tiện ích <em>cho</em> <img alt=\"Firefox\" src=\"%1$s\" /> <strong>Firefox - Cáo Lửa</strong>"
+
+#: views/elements/header.thtml:99
+msgid "header_main_header"
+msgstr "Tiện ích"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:242
+msgid "header_main_header_with_logo"
+msgstr "Tiện ích <img alt=\"Tiện ích\" src=\"%1$s\" />"
+
+#: views/elements/header.thtml:90
+msgid "header_main_seamonkey_header"
+msgstr "Seamonkey Add-ons - Tiện ích Khỉ Biển Oai Hùng"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:224
+msgid "header_main_seamonkey_header_with_logo"
+msgstr "Tiện ích <em>cho</em> <img alt=\"seamonkey\" src=\"%1$s\" /> <strong>SeaMonkey - Khỉ Biển</strong>"
+
+#: views/elements/header.thtml:93
+msgid "header_main_sunbird_header"
+msgstr "Sunbird Add-ons - Tiện ích Chim Hút Mật"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:230
+msgid "header_main_sunbird_header_with_logo"
+msgstr "Tiện ích <em>cho</em> <img alt=\"sunbird\" src=\"%1$s\" /> <strong>Sunbird - Chim Hút Mật</strong>"
+
+#: views/elements/header.thtml:96
+msgid "header_main_thunderbird_header"
+msgstr "Thunderbird Add-ons - Tiện ích Chim Sét Thần Thánh"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:236
+msgid "header_main_thunderbird_header_with_logo"
+msgstr "Tiện ích <em>cho</em> <img alt=\"thunderbird\" src=\"%1$s\" /> <strong>Thunderbird - Chim Sét</strong>"
+
+#: views/layouts/amo2009.thtml:205
+msgid "header_navaccess_applications_menu"
+msgstr "Äi tá»›i trình Ä‘Æ¡n chÆ°Æ¡ng trình khác"
+
+#: views/layouts/amo2009.thtml:204
+msgid "header_navaccess_categories_menu"
+msgstr "Äi tá»›i trình Ä‘Æ¡n phân mục"
+
+#: views/layouts/amo2009.thtml:202
+msgid "header_navaccess_main_content"
+msgstr "Äi tá»›i ná»™i dung chính"
+
+#: views/layouts/amo2009.thtml:203
+msgid "header_navaccess_search_form"
+msgstr "Äi tá»›i biểu mẫu tìm kiếm"
+
+#: views/elements/header.thtml:62
+msgid "header_navlink_addons"
+msgstr "Tiện ích"
+
+#: views/elements/developers/sidebar.thtml:72
+#: views/elements/developers/myaddons.thtml:50
+#: views/elements/header.thtml:159
+#: views/addons/display.thtml:378
+msgid "header_navlink_login"
+msgstr "Äăng nhập"
+
+#: views/elements/header.thtml:156
+#: views/layouts/amo2009.thtml:304
+msgid "header_navlink_logout"
+msgstr "Thoát"
+
+#: views/elements/header.thtml:145
+#: views/layouts/amo2009.thtml:303
+msgid "header_navlink_myaccount"
+msgstr "Tài khoản của Tôi"
+
+#: views/elements/header.thtml:158
+msgid "header_navlink_register"
+msgstr "Äăng kí"
+
+#. %1 is the URL to the registration page
+#. %2 is the URL to the login page
+#: views/layouts/amo2009.thtml:278
+msgid "header_navlink_register_or_login"
+msgstr "<a href=\"%1$s\">Äăng kí</a> hoặc <a href=\"%2$s\">Äăng nhập</a>"
+
+#: views/layouts/amo2009.thtml:285
+msgid "header_navlink_tools"
+msgstr "Công cụ"
+
+#. %s is the add-on name
+#: views/elements/collections_interactive_addon.thtml:62
+#: views/elements/amo2009/homepage_addon.thtml:77
+#: views/elements/addon_discussionheader.thtml:62
+#: views/elements/addon_listitem.thtml:67
+#: views/elements/feature.thtml:84
+#: views/addons/category_landing.thtml:87
+#: views/addons/browse_thumbs.thtml:60
+#, php-format
+msgid "img_preview_of"
+msgstr "Hình ảnh Xem trước của %s"
+
+#. %1 is the login URL for the link tag
+#. %2 is the link to an explanatory page.
+#: views/elements/amo2009/install.thtml:307
+#: views/elements/install.thtml:255
+msgid "install_a_login_to_install"
+msgstr "<a href=\"%1$s\">Äăng nhập</a> để cài đặt tiện ích thá»­ nghiệm này. <a href=\"%2$s\">Tại sao</a>?"
+
+#. %1 is the URL for the Experimental Add-ons section of the FAQ page
+#: views/elements/amo2009/install.thtml:283
+#: views/elements/install.thtml:232
+msgid "install_button_confirm_exp_install"
+msgstr "Hãy để tôi cài đặt tiện ích thá»­ nghiệm này. <a href=\"%1$s\">Äây là gì?</a>"
+
+#. %1$s is the application name. Example: Firefox
+#. %2$s is an optional string used to specify a platform. Example: (Windows)
+#: views/elements/amo2009/install.thtml:128
+#: views/elements/install.thtml:75
+#, php-format
+msgid "install_button_text"
+msgstr "Thêm vào %s %s"
+
+#. %1 is the add-on name, %2 is the app name
+#: views/elements/amo2009/install.thtml:191
+#: views/elements/amo2009/install.thtml:206
+#: views/elements/amo2009/install.thtml:249
+#: views/elements/amo2009/install.thtml:298
+#: views/elements/install.thtml:150
+#: views/elements/install.thtml:165
+#: views/elements/install.thtml:202
+#: views/elements/install.thtml:246
+#, php-format
+msgid "install_button_title"
+msgstr "Thêm %1$s vào %2$s"
+
+#. %1$s is the add-on name
+#: views/elements/amo2009/install.thtml:200
+#: views/elements/install.thtml:159
+#, php-format
+msgid "install_download"
+msgstr "Tải xuống %1$s"
+
+#: views/elements/amo2009/install.thtml:147
+#: views/elements/install.thtml:94
+msgid "install_error_addon_not_found"
+msgstr "Tiện ích này không tồn tại."
+
+#: views/addons/dictionaries.thtml:65
+msgid "langtools_a11y_tablesummary"
+msgstr "Danh sách gói ngôn ngữ và từ điển."
+
+#: views/addons/dictionaries.thtml:47
+msgid "langtools_download_dictionary"
+msgstr "Tải xuống Từ điển"
+
+#: views/addons/dictionaries.thtml:48
+msgid "langtools_download_langpack"
+msgstr "Tải xuống Gói ngôn ngữ"
+
+#: views/addons/dictionaries.thtml:63
+#: controllers/components/amo.php:685
+#: controllers/addons_controller.php:1239
+msgid "langtools_header_dicts_and_langpacks"
+msgstr "Từ điển và Gói ngôn ngữ"
+
+#: views/addons/dictionaries.thtml:44
+msgid "langtools_install_dictionary"
+msgstr "Cài đặt Từ điển"
+
+#: views/addons/dictionaries.thtml:45
+msgid "langtools_install_langpack"
+msgstr "Cài đặt Gói ngôn ngữ"
+
+#: views/addons/dictionaries.thtml:69
+msgid "langtools_tableheader_dictionary"
+msgstr "Từ điển"
+
+#: views/addons/dictionaries.thtml:70
+msgid "langtools_tableheader_langpack"
+msgstr "Gói ngôn ngữ"
+
+#: views/addons/dictionaries.thtml:68
+msgid "langtools_tableheader_language"
+msgstr "Ngôn ngữ"
+
+#: models/license.php:65
+msgid "license_custom"
+msgstr "Giấy phép Tùy biến"
+
+#: config/bootstrap.php:303
+msgid "licenses_bsd"
+msgstr "Giấy phép BSD"
+
+#: config/bootstrap.php:298
+msgid "licenses_gpl_2.0"
+msgstr "Giấy phép Công cộng GNU, phiên bản 2.0"
+
+#: config/bootstrap.php:299
+msgid "licenses_gpl_3.0"
+msgstr "Giấy phép Công cộng GNU, phiên bản 3.0"
+
+#: config/bootstrap.php:300
+msgid "licenses_lgpl_2.1"
+msgstr "Giấy phép Công cá»™ng Ãt hÆ¡n GNU, phiên bản 2.1"
+
+#: config/bootstrap.php:301
+msgid "licenses_lgpl_3.0"
+msgstr "Giấy phép Công cá»™ng Ãt hÆ¡n GNU, phiên bản 3.0"
+
+#: config/bootstrap.php:302
+msgid "licenses_mit"
+msgstr "Giấy phép MIT/X11"
+
+#: config/bootstrap.php:297
+msgid "licenses_mpl_1.1"
+msgstr "Giấy phép Công cộng Mozilla, phiên bản 1.1"
+
+#: views/users/emailchange.thtml:51
+#: views/users/delete.thtml:55
+#: views/users/delete.thtml:137
+#: views/users/edit.thtml:74
+#: views/reviews/flag.thtml:54
+msgid "link_return_to_front_page"
+msgstr "Nhấn vào đây để trở lại trang chủ."
+
+#: views/elements/amo2009/addon_list_options.thtml:46
+#: views/elements/addon_list_options.thtml:46
+msgid "list_sortby_date"
+msgstr "Ngày"
+
+#: views/elements/amo2009/addon_list_options.thtml:47
+#: views/elements/addon_list_options.thtml:47
+msgid "list_sortby_downloads"
+msgstr "Số lượt tải"
+
+#: views/elements/amo2009/addon_list_options.thtml:45
+#: views/elements/addon_list_options.thtml:45
+msgid "list_sortby_name"
+msgstr "Tên tiện ích"
+
+#: views/elements/amo2009/addon_list_options.thtml:48
+#: views/elements/addon_list_options.thtml:48
+msgid "list_sortby_rating"
+msgstr "Xếp hạng"
+
+#: config/bootstrap.php:278
+msgid "main_prettyname_fennec"
+msgstr "Fennec"
+
+#: config/bootstrap.php:274
+msgid "main_prettyname_firefox"
+msgstr "Firefox"
+
+#: config/bootstrap.php:277
+msgid "main_prettyname_seamonkey"
+msgstr "SeaMonkey"
+
+#: config/bootstrap.php:276
+msgid "main_prettyname_sunbird"
+msgstr "Sunbird"
+
+#: config/bootstrap.php:275
+msgid "main_prettyname_thunderbird"
+msgstr "Thunderbird"
+
+#: views/elements/addon_categories.thtml:52
+msgid "nav_category_dicts_langpacks"
+msgstr "Từ điển & Gói ngôn ngữ"
+
+#: views/elements/addon_categories.thtml:55
+msgid "nav_category_themes"
+msgstr "Giao diện"
+
+#: views/elements/app_chooser.thtml:47
+#: views/layouts/amo2009.thtml:255
+msgid "other_apps_tooltip"
+msgstr "Tìm tiện ích cho các chương trình khác"
+
+#. In a user list: user 1, user 2, "others"
+#: views/helpers/addons_html.php:222
+msgid "other_users"
+msgstr "ngÆ°á»i khác"
+
+#: controllers/pages_controller.php:90
+msgid "page_title_appversions"
+msgstr "Phiên bản Ứng dụng"
+
+#: controllers/pages_controller.php:115
+msgid "page_title_collector"
+msgstr "Trình sưu tập Tiện ích"
+
+#: controllers/pages_controller.php:117
+msgid "page_title_collector_faq"
+msgstr "FAQ của Trình sưu tập Tiện ích"
+
+#: controllers/pages_controller.php:119
+msgid "page_title_collector_features"
+msgstr "Tính năng của Trình sưu tập Tiện ích"
+
+#: controllers/pages_controller.php:122
+msgid "page_title_collector_firstrun"
+msgstr "Chào mừng đến với Trình sưu tập Tiện ích"
+
+#: controllers/pages_controller.php:92
+msgid "page_title_credits"
+msgstr "Công trạng"
+
+#: controllers/pages_controller.php:113
+msgid "page_title_developer_faq"
+msgstr "FAQ cho Nhà phát triển"
+
+#: controllers/pages_controller.php:111
+msgid "page_title_faq"
+msgstr "Há»i Äáp ThÆ°á»ng Gặp"
+
+#: controllers/pages_controller.php:94
+msgid "page_title_fashionyourfirefox_faq"
+msgstr "Câu há»i ThÆ°á»ng gặp vá» Tạo mốt cho Firefox của bạn"
+
+#: controllers/pages_controller.php:101
+msgid "page_title_policy"
+msgstr "Chính sách vỠTiện ích"
+
+#: controllers/pages_controller.php:103
+msgid "page_title_privacy"
+msgstr "Chính sách Riêng tư của Mozilla"
+
+#: controllers/pages_controller.php:105
+msgid "page_title_review_guide"
+msgstr "HÆ°á»›ng dẫn Äánh giá"
+
+#: controllers/pages_controller.php:107
+msgid "page_title_sandbox"
+msgstr "Hệ thống Äánh giá Há»™p cát"
+
+#: controllers/pages_controller.php:109
+msgid "page_title_submissionhelp"
+msgstr "Trợ giúp Gửi lên"
+
+#: views/pages/appversions.thtml:87
+msgid "pages_appversions_guid"
+msgstr "GUID"
+
+#: views/pages/appversions.thtml:79
+#: controllers/pages_controller.php:90
+msgid "pages_appversions_header"
+msgstr "Các phiên bản Ứng dụng Hợp lệ"
+
+#: views/pages/appversions.thtml:80
+msgid "pages_appversions_intro"
+msgstr "Tiện ích được gá»­i lên Tiện Ãch Mozilla phải có má»™t tập tin install.rdf vá»›i ít nhất má»™t trong các ứng dụng bên dÆ°á»›i được há»— trợ. Chỉ các phiên bản được liệt kê bên dÆ°á»›i là được phép cho các ứng dụng này."
+
+#. %s is a full <a> tag
+#: views/pages/appversions.thtml:93
+#, php-format
+msgid "pages_appversions_required_files"
+msgstr "Nếu ứng dụng được hỗ trợ không yêu cầu một tập tin install.rdf, bạn vẫn phải kèm theo một cái với các thuộc tính bắt buộc đã được chỉ định %s."
+
+#. this is the text inside of an <a> tag for pages_appversions_required_files. This
+#. should be fixed.
+#: views/pages/appversions.thtml:93
+msgid "pages_appversions_required_files_link"
+msgstr "ở đây"
+
+#: views/pages/appversions.thtml:88
+msgid "pages_appversions_versions"
+msgstr "Phiên bản"
+
+#: views/pages/policy.thtml:51
+msgid "pages_policy_sandbox_link"
+msgstr "Trang thông tin Hộp cát"
+
+#: views/elements/pagination.thtml:53
+msgid "pagination_next_page"
+msgstr "tiếp"
+
+#: views/elements/pagination.thtml:52
+msgid "pagination_previous_page"
+msgstr "trÆ°á»›c"
+
+#: views/elements/recaptcha.thtml:65
+msgid "recaptcha_enter_both_words"
+msgstr "Vui lòng nhập <strong>cả hai từ</strong> bên dưới, <strong>cách nhau bởi khoảng trắng</strong>."
+
+#: views/elements/recaptcha.thtml:83
+msgid "recaptcha_enter_here"
+msgstr "Nhập câu trả lá»i của bạn ở đây:"
+
+#: views/elements/recaptcha.thtml:74
+msgid "recaptcha_enter_whatyouhear"
+msgstr "Vui lòng gõ những gì bạn nghe thấy."
+
+#. %1 is the link switching refreshing the captcha
+#. %2 is the link switching to a text captcha
+#: views/elements/recaptcha.thtml:77
+msgid "recaptcha_hardtohear_text"
+msgstr "Nếu khó hiểu, bạn có thể <a href=\"%1$s\">nghe cái gì đó khác</a> hoặc <a href=\"%2$s\">quay lại phần văn bản</a>."
+
+#. %1 is the link switching refreshing the captcha
+#. %2 is the link switching to an audio captcha
+#: views/elements/recaptcha.thtml:68
+msgid "recaptcha_hardtoread_text"
+msgstr "Nếu khó Ä‘á»c, bạn có thể <a href=\"%1$s\">thá»­ từ khác</a> hoặc <a href=\"%2$s\">nghe Ä‘á»c cái khác</a>."
+
+#: views/users/register.thtml:105
+msgid "recaptcha_label"
+msgstr "Bạn có phải là ngÆ°á»i?"
+
+#: views/users/register.thtml:106
+msgid "recaptcha_whatsthis"
+msgstr "Äây là gì?"
+
+#: controllers/reviews_controller.php:559
+msgid "review_flag_error"
+msgstr "Lỗi khi gán cỠhiệu cho đánh giá này!"
+
+#: models/reviews_moderation_flag.php:69
+msgid "review_flag_reason_bug_support"
+msgstr "Yêu cầu hỗ trợ hoặc báo cáo lỗi bị đặt nhầm"
+
+#: views/reviews/display.thtml:103
+#: views/reviews/display.thtml:186
+msgid "review_flag_reason_instructions"
+msgstr "Báo cáo đánh giá này (hãy chá»n má»™t lí do)"
+
+#: models/reviews_moderation_flag.php:67
+msgid "review_flag_reason_language"
+msgstr "Hộp thoại / ngôn ngữ không phù hợp"
+
+#: models/reviews_moderation_flag.php:71
+msgid "review_flag_reason_other"
+msgstr "Khác (vui lòng chỉ ra)"
+
+#: models/reviews_moderation_flag.php:65
+msgid "review_flag_reason_spam"
+msgstr "Spam hoặc các nội dung không phải là đánh giá"
+
+#: views/reviews/display.thtml:91
+#: views/reviews/display.thtml:175
+#: controllers/reviews_controller.php:555
+msgid "review_flag_success"
+msgstr "Cảm ơn; đánh giá này được gán cỠđể chỠchấp thuận của biên tập viên."
+
+#: views/reviews/display.thtml:41
+msgid "review_flag_this"
+msgstr "Báo cáo đánh giá này"
+
+#: views/reviews/display.thtml:42
+msgid "review_flag_this_titletip"
+msgstr "Báo cáo này không phù hợp, không chính xác hoặc chỉ là spam? Nhấn vào đây để gán cỠđể chỠđánh giá của biên tập viên."
+
+#. %1 is the URL of the support section, %2 for the review guidelines
+#: views/reviews/add.thtml:53
+msgid "review_guidelines_short"
+msgstr "<p>Hãy ghi nhá»› các mẹo này trong đầu:</p><ul><li>Viết nhÆ° thể bạn Ä‘ang kể cho má»™t ngÆ°á»i bạn vá» trải nghiệm của bạn đối vá»›i tiện ích. ÄÆ°a ra những chi tiết hữu ích và cụ thể, nhÆ° là những tính năng nào mà bạn thích và/hoặc không thích, dùng nó khó hay dá»… nhÆ° thế nào, và những Ä‘iểm chÆ°a hay của nó. Tránh ngôn ngữ thông thÆ°á»ng nhÆ° là \"Tuyệt vá»i\" hoặc \"Dở tệ\" trừ khi bạn có thể Ä‘Æ°a ra lí do vì sao bạn tin nhÆ° vậy.</li><li>Vui lòng không báo lá»—i trong bài đánh giá. Chúng tôi không để địa chỉ email của bạn hiện hữu trÆ°á»›c nhà phát triển tiện ích, trong khi có thể há» cần liên hệ vá»›i bạn để giúp bạn giải quyết vấn Ä‘á». Xem <a href=\"%1$s\">phần trợ giúp</a> để tìm nÆ¡i nhận được há»— trợ cho tiện ích này.</li><li>Vui lòng giữ phần đánh giá được sạch sẽ, tránh dùng ngôn từ không phù hợp và đừng Ä‘Æ°a lên bất kì thông tin cá nhân nào.</li></ul><p>Vui lòng Ä‘á»c <a href=\"%2$s\">HÆ°á»›ng dẫn Äánh giá</a> để biết thêm chi tiết vá» cách đánh giá tiện ích.</p>"
+
+#. %1 is the add-on name
+#: views/reviews/flag.thtml:56
+#: views/reviews/display.thtml:55
+#: views/reviews/review_added.thtml:50
+#, php-format
+msgid "reviews_header"
+msgstr "Äánh giá cho %s"
+
+#: controllers/addons_controller.php:435
+msgid "rss_featuredaddons"
+msgstr "Tiện ích được Äá» cao"
+
+#: controllers/addons_controller.php:432
+msgid "rss_newestaddons"
+msgstr "Tiện ích Mới nhất"
+
+#: controllers/addons_controller.php:434
+msgid "rss_popularaddons"
+msgstr "Tiện ích Thông dụng"
+
+#: controllers/addons_controller.php:433
+msgid "rss_updatedaddons"
+msgstr "Tiện ích được Cập nhật"
+
+#: views/elements/search_mini.thtml:70
+msgid "search"
+msgstr "Tìm kiếm"
+
+#: views/search/collections.thtml:51
+msgid "search_collections_header"
+msgstr "Kết quả Tìm kiếm Bộ sưu tập"
+
+#: controllers/search_controller.php:297
+msgid "search_collections_pagetitle"
+msgstr "Kết quả Tìm kiếm Bộ sưu tập"
+
+#: controllers/search_controller.php:99
+msgid "search_disabled"
+msgstr "Tìm kiếm hiện đang bị vô hiệu hóa. Vui lòng thử lại sau."
+
+#: views/elements/amo2009/search.thtml:188
+#: views/elements/search.thtml:187
+#: views/elements/search_mini.thtml:54
+msgid "search_form_all_addons"
+msgstr "tất cả tiện ích"
+
+#. This string is in the main category dropdown when searching
+#: views/elements/amo2009/search.thtml:204
+msgid "search_form_all_collections"
+msgstr "tất cả các bộ sưu tập"
+
+#: views/elements/amo2009/search.thtml:184
+#: views/elements/amo2009/search.thtml:385
+#: views/elements/amo2009/search.thtml:408
+#: views/elements/search.thtml:171
+#: views/elements/search.thtml:183
+#: views/elements/search_mini.thtml:43
+#: views/elements/search_mini.thtml:49
+#: views/layouts/mozilla.thtml:188
+msgid "search_form_default_text"
+msgstr "tìm kiếm tiện ích"
+
+#: views/elements/amo2009/search.thtml:184
+#: views/elements/amo2009/search.thtml:404
+msgid "search_form_default_text_collections"
+msgstr "tìm kiếm các bộ sưu tập"
+
+#: views/elements/amo2009/search.thtml:206
+#: views/elements/search.thtml:202
+msgid "search_form_submit_tooltip"
+msgstr "Tìm kiếm tiện ích"
+
+#: views/elements/amo2009/search.thtml:184
+#: views/elements/search.thtml:183
+#: views/elements/search_mini.thtml:49
+msgid "search_form_tooltip"
+msgstr "Nhấn để nhập thuật ngữ tìm kiếm"
+
+#: views/elements/amo2009/search.thtml:186
+#: views/elements/search.thtml:185
+#: views/elements/search_mini.thtml:52
+msgid "search_form_within"
+msgstr "trong"
+
+#: views/addons/searchengines.thtml:118
+msgid "search_landing_all_search_engines"
+msgstr "Tất cả Bộ máy Tìm kiếm"
+
+#: views/addons/searchengines.thtml:114
+msgid "search_landing_browse_search_engines"
+msgstr "Duyệt các Máy tìm kiếm"
+
+#: views/search/collections.thtml:58
+#: views/search/index.thtml:59
+msgid "search_nothing_found"
+msgstr "Không tìm thấy kết quả."
+
+#: controllers/search_controller.php:185
+msgid "search_pagetitle"
+msgstr "Tìm kiếm Tiện ích"
+
+#: controllers/search_controller.php:242
+msgid "search_rss_description"
+msgstr "Feed từ kết quả tìm kiếm"
+
+#. %s is the terms the user is searching for (a string)
+#: controllers/search_controller.php:241
+#, php-format
+msgid "search_rss_results_for"
+msgstr "Kết quả tìm kiếm cho: %s"
+
+#: views/elements/header.thtml:154
+#: views/layouts/amo2009.thtml:296
+msgid "sidebar_navlink_admin_tools"
+msgstr "Công cụ Quản trị"
+
+#: views/elements/header.thtml:146
+#: views/layouts/amo2009.thtml:288
+msgid "sidebar_navlink_developer_tools"
+msgstr "Công cụ Nhà phát triển"
+
+#: views/elements/header.thtml:148
+#: views/layouts/amo2009.thtml:290
+msgid "sidebar_navlink_editor_tools"
+msgstr "Công cụ Biên tập viên"
+
+#: views/layouts/amo2009.thtml:302
+msgid "sidebar_navlink_welcome"
+msgstr "Chào mừng"
+
+#. %s is the user's name
+#: views/layouts/amo2009.thtml:302
+#, php-format
+msgid "sidebar_navlink_welcome_name"
+msgstr "Chào mừng, %s"
+
+#: views/elements/pitch.thtml:50
+#: views/elements/pitch.thtml:55
+msgid "sidebar_pitch_dictionary"
+msgstr "Từ điển"
+
+#: views/elements/pitch.thtml:72
+msgid "sidebar_pitch_featured_addons"
+msgstr "Tiện ích Nổi bật"
+
+#: views/elements/pitch.thtml:61
+msgid "sidebar_pitch_looking_for"
+msgstr "Tôi đang tìm một:"
+
+#: views/elements/pitch.thtml:70
+msgid "sidebar_pitch_newest_addons"
+msgstr "Tiện ích Mới nhất"
+
+#: views/elements/pitch.thtml:49
+msgid "sidebar_pitch_search"
+msgstr "Phần bổ trợ Tìm kiếm"
+
+#: views/elements/pitch.thtml:69
+msgid "sidebar_pitch_subscribe_to"
+msgstr "Äăng kí nhận tin từ"
+
+#: views/elements/pitch.thtml:48
+#: views/elements/pitch.thtml:54
+msgid "sidebar_pitch_theme"
+msgstr "Giao diện"
+
+#: views/elements/pitch.thtml:71
+msgid "sidebar_pitch_updated_addons"
+msgstr "Tiện ích Cập nhật"
+
+#. %1$s is a number
+#: views/helpers/localization.php:65
+#: views/developers/versions_edit.thtml:95
+#: views/addons/dictionaries.thtml:92
+#, php-format
+msgid "size_kb"
+msgstr "%1$s kB"
+
+#: views/elements/amo2009/stars.thtml:57
+#: views/elements/stars.thtml:63
+msgid "stars_not_yet_rated"
+msgstr "Chưa được xếp hạng"
+
+#. %1 is the number of stars this add-on has
+#: views/elements/amo2009/stars.thtml:49
+#: views/elements/stars.thtml:54
+#, php-format
+msgid "stars_rated_x_outof_5"
+msgstr "Xếp hạng %s trong 5 sao"
+
+#: views/statistics/addon.thtml:59
+msgid "statistics_addon_dashboard_link"
+msgstr "Trang chủ Bảng"
+
+#: views/statistics/addon.thtml:58
+msgid "statistics_addon_developertools_link"
+msgstr "Công cụ Nhà phát triển"
+
+#: views/statistics/addon.thtml:53
+msgid "statistics_addon_switch"
+msgstr "Chuyển Tiện Ãch"
+
+#. This is a date format.
+#. http://php.net/strftime
+#: views/statistics/rss/summary.thtml:54
+#: views/statistics/addon.thtml:181
+msgid "statistics_date_shortmonth"
+msgstr "%e tháng %m"
+
+#. This is a date format.
+#. http://php.net/strftime
+#: views/statistics/rss/summary.thtml:40
+#: views/statistics/addon.thtml:152
+msgid "statistics_date_shortmonthwithyear"
+msgstr "%e tháng %m, %Y"
+
+#. This is a date format.
+#. http://php.net/strftime
+#: views/statistics/rss/summary.thtml:41
+#: views/statistics/rss/summary.thtml:48
+#: views/statistics/addon.thtml:161
+#: views/statistics/addon.thtml:172
+msgid "statistics_date_weekdayshortmonth"
+msgstr "%A, %e tháng %m"
+
+#. %1$s is an add-on name and version. Example: Add-on 3.5
+#: controllers/components/stats.php:519
+#, php-format
+msgid "statistics_events_addon_created"
+msgstr "%1$s được tạo"
+
+#. %1$s is an application name and version. Example: Firefox 3.5
+#: controllers/components/stats.php:500
+#, php-format
+msgid "statistics_events_app_released"
+msgstr "%1$s được phát hành"
+
+#: views/statistics/addon.thtml:71
+msgid "statistics_help_close_link"
+msgstr "Äóng"
+
+#: views/statistics/addon.thtml:60
+msgid "statistics_help_link"
+msgstr "Trợ giúp"
+
+#: views/statistics/index.thtml:83
+msgid "statistics_index_anotheraddon"
+msgstr "hoặc, chá»n má»™t tiện ích khác"
+
+#: views/statistics/index.thtml:85
+msgid "statistics_index_anotheraddon_public"
+msgstr "hoặc, chá»n má»™t tiện ích có thống kê công khai"
+
+#: views/statistics/index.thtml:71
+msgid "statistics_index_myaddons"
+msgstr "Chá»n má»™t trong các tiện ích của bạn để xem thống kê của nó"
+
+#: views/statistics/index.thtml:89
+msgid "statistics_index_selectaddon"
+msgstr "Chá»n má»™t tiện ích để xem thống kê của nó"
+
+#: views/statistics/index.thtml:91
+msgid "statistics_index_selectaddon_public"
+msgstr "Chá»n má»™t tiện ích để xem thống kê công khai của nó"
+
+#: views/statistics/index.thtml:39
+msgid "statistics_index_title"
+msgstr "Bảng Thống Kê"
+
+#: views/statistics/index.thtml:97
+msgid "statistics_index_view_button"
+msgstr "Xem Thống Kê"
+
+#: views/statistics/addon.thtml:222
+#: controllers/statistics_controller.php:247
+msgid "statistics_js_download_csv"
+msgstr "Xem bảng này trong dạng CSV"
+
+#: controllers/statistics_controller.php:246
+msgid "statistics_js_dropdowns_none"
+msgstr "không có"
+
+#: controllers/statistics_controller.php:245
+msgid "statistics_js_dropdowns_removeplot"
+msgstr "Xóa bỠđồ thị này"
+
+#: controllers/statistics_controller.php:248
+msgid "statistics_js_groupby_selector_date"
+msgstr "Nhóm theo: Ngày"
+
+#: controllers/statistics_controller.php:251
+msgid "statistics_js_groupby_selector_month"
+msgstr "Nhóm theo: Tháng"
+
+#: controllers/statistics_controller.php:249
+msgid "statistics_js_groupby_selector_week"
+msgstr "Nhóm theo: Tuần"
+
+#: controllers/statistics_controller.php:250
+msgid "statistics_js_groupby_selector_week_over_week"
+msgstr "So sánh theo: Tuần"
+
+#: controllers/statistics_controller.php:260
+msgid "statistics_js_plotselection_foundinrange"
+msgstr "%s được tìm thấy trong khoảng"
+
+#: controllers/statistics_controller.php:270
+msgid "statistics_js_plotselection_options_addplot_name"
+msgstr "Thêm Äồ Thị"
+
+#: controllers/statistics_controller.php:271
+msgid "statistics_js_plotselection_options_addplot_tooltip"
+msgstr "Thêm đồ thị vào biểu đồ này"
+
+#: controllers/statistics_controller.php:261
+msgid "statistics_js_plotselection_options_count_name_checked"
+msgstr "Ẩn Tổng Số Lần Äếm"
+
+#: controllers/statistics_controller.php:262
+msgid "statistics_js_plotselection_options_count_name_unchecked"
+msgstr "Hiện Tổng Số Lần Äếm"
+
+#: controllers/statistics_controller.php:263
+msgid "statistics_js_plotselection_options_count_tooltip"
+msgstr "Vẽ đồ thị tổng số lần đếm trên biểu đồ này"
+
+#: controllers/statistics_controller.php:275
+msgid "statistics_js_plotselection_options_csv_name"
+msgstr "Xem Dữ Liệu (CSV)"
+
+#: controllers/statistics_controller.php:276
+msgid "statistics_js_plotselection_options_csv_tooltip"
+msgstr "Lấy một tập tin Giá trị Ngăn cách Theo dấu phẩy (Comma Separated Values) của dữ liệu này"
+
+#: controllers/statistics_controller.php:267
+msgid "statistics_js_plotselection_options_events_addon_name_checked"
+msgstr "Ẩn Sự Kiện %s"
+
+#: controllers/statistics_controller.php:268
+msgid "statistics_js_plotselection_options_events_addon_name_unchecked"
+msgstr "Hiện Sự Kiện %s"
+
+#: controllers/statistics_controller.php:269
+msgid "statistics_js_plotselection_options_events_addon_tooltip"
+msgstr "Cho ngày phát hành tiện ích phủ lên đồ thị"
+
+#: controllers/statistics_controller.php:264
+msgid "statistics_js_plotselection_options_events_firefox_name_checked"
+msgstr "Ẩn Sự Kiện Firefox"
+
+#: controllers/statistics_controller.php:265
+msgid "statistics_js_plotselection_options_events_firefox_name_unchecked"
+msgstr "Hiện Sự Kiện Firefox"
+
+#: controllers/statistics_controller.php:266
+msgid "statistics_js_plotselection_options_events_firefox_tooltip"
+msgstr "Cho ngày phát hành Firefox phủ lên đồ thị"
+
+#: controllers/statistics_controller.php:272
+msgid "statistics_js_plotselection_options_resize_name_checked"
+msgstr "Thu gá»n Biểu đồ"
+
+#: controllers/statistics_controller.php:273
+msgid "statistics_js_plotselection_options_resize_name_unchecked"
+msgstr "Mở rộng Biểu đồ"
+
+#: controllers/statistics_controller.php:274
+msgid "statistics_js_plotselection_options_resize_tooltip"
+msgstr "Äiá»u chỉnh kích thÆ°á»›c Biểu đồ"
+
+#: controllers/statistics_controller.php:254
+msgid "statistics_js_plotselection_selector_adu"
+msgstr "NgÆ°á»i dùng Má»—i ngày"
+
+#: controllers/statistics_controller.php:256
+msgid "statistics_js_plotselection_selector_application"
+msgstr "Ứng dụng"
+
+#: controllers/statistics_controller.php:259
+msgid "statistics_js_plotselection_selector_custom"
+msgstr "Tùy biến"
+
+#: controllers/statistics_controller.php:253
+msgid "statistics_js_plotselection_selector_downloads"
+msgstr "Số lần tải"
+
+#: controllers/statistics_controller.php:258
+msgid "statistics_js_plotselection_selector_os"
+msgstr "Hệ Ä‘iá»u hành"
+
+#: controllers/statistics_controller.php:257
+msgid "statistics_js_plotselection_selector_status"
+msgstr "Trạng thái Tiện ích"
+
+#: controllers/statistics_controller.php:252
+msgid "statistics_js_plotselection_selector_summary"
+msgstr "Tóm tắt"
+
+#: controllers/statistics_controller.php:255
+msgid "statistics_js_plotselection_selector_version"
+msgstr "Phiên bản Tiện ích"
+
+#: controllers/components/stats.php:398
+msgid "statistics_longnames_application"
+msgstr "Ứng dụng"
+
+#: controllers/components/stats.php:400
+msgid "statistics_longnames_os"
+msgstr "Hệ Ä‘iá»u hành"
+
+#: controllers/components/stats.php:399
+msgid "statistics_longnames_status"
+msgstr "Trạng thái Tiện ích"
+
+#: controllers/components/stats.php:401
+msgid "statistics_longnames_unknown"
+msgstr "Không rõ"
+
+#: controllers/components/stats.php:397
+msgid "statistics_longnames_version"
+msgstr "Phiên bản Tiện ích"
+
+#: views/statistics/addon.thtml:118
+msgid "statistics_notice_data_insufficient"
+msgstr "Không đủ dữ liệu để hiển thị biểu đồ này. Vui lòng kiểm tra lại sau."
+
+#: views/statistics/addon.thtml:130
+msgid "statistics_notice_data_none"
+msgstr "Chúng tôi chưa có dữ liệu cho tiện ích này. Vui lòng kiểm tra lại sau vài ngày."
+
+#: views/statistics/addon.thtml:41
+msgid "statistics_notice_data_updating"
+msgstr "Thống kê cho tiện ích hiện tại đang trong quá trình cập nhật. Dữ liệu gần đây có thể chưa hoàn tất vì script của chúng tôi hoạt động để cập nhật thông tin này. Vui lòng kiểm tra lại sau vài phút."
+
+#: views/statistics/addon.thtml:136
+msgid "statistics_notice_disabled"
+msgstr "Bảng Thống Kê hiện đang bị vô hiệu hóa. Vui lòng kiểm tra lại sau."
+
+#: views/statistics/addon.thtml:123
+msgid "statistics_notice_nojavascript"
+msgstr "JavaScript cần có để xem biểu đồ Bảng Thống Kê."
+
+#: views/statistics/addon.thtml:44
+msgid "statistics_notice_settings_updated"
+msgstr "Thiết lập của bạn đã được cập nhật!"
+
+#: controllers/statistics_controller.php:60
+#: controllers/statistics_controller.php:71
+#: controllers/statistics_controller.php:74
+#: controllers/statistics_controller.php:240
+msgid "statistics_pagetitle"
+msgstr "Bảng Thống Kê"
+
+#: views/statistics/addon.thtml:99
+msgid "statistics_plot_legend_adu"
+msgstr "NgÆ°á»i dùng Má»—i ngày"
+
+#: views/statistics/addon.thtml:95
+msgid "statistics_plot_legend_downloads"
+msgstr "Số lần tải Mỗi ngày"
+
+#: views/statistics/addon.thtml:107
+msgid "statistics_plot_options_zoomin_alt"
+msgstr "Phóng To"
+
+#: views/statistics/addon.thtml:106
+msgid "statistics_plot_options_zoomin_title"
+msgstr "Phóng to một tháng"
+
+#: views/statistics/addon.thtml:110
+msgid "statistics_plot_options_zoomout_alt"
+msgstr "Thu Nhá»"
+
+#: views/statistics/addon.thtml:109
+msgid "statistics_plot_options_zoomout_title"
+msgstr "Thu nhỠmột tháng"
+
+#: controllers/statistics_controller.php:283
+#, php-format
+msgid "statistics_rss_description"
+msgstr "Tóm tắt thống kê mỗi ngày cho %1$s"
+
+#: views/statistics/rss/summary.thtml:68
+msgid "statistics_rss_title_fulldate"
+msgstr "%A, %e tháng %m năm %Y"
+
+#: views/statistics/rss/summary.thtml:68
+#, php-format
+msgid "statistics_rss_title_statsfordate"
+msgstr "Thống kê cho %1$s"
+
+#: views/statistics/settings.thtml:49
+msgid "statistics_settings_access_description"
+msgstr "Mặc định, chỉ có bạn và Mozilla có thể truy cập thông tin trên bảng thống kê của bạn. Bạn có thể đưa nó ra công khai để ai cũng xem được dữ liệu vỠtiện ích của bạn."
+
+#: views/statistics/settings.thtml:48
+msgid "statistics_settings_access_heading"
+msgstr "Truy cập Bảng"
+
+#: views/statistics/settings.thtml:51
+msgid "statistics_settings_access_private"
+msgstr "Riêng tư"
+
+#: views/statistics/settings.thtml:51
+msgid "statistics_settings_access_private_description"
+msgstr "Chỉ bạn và Mozilla có thể xem thống kê của tiện ích này"
+
+#: views/statistics/settings.thtml:52
+msgid "statistics_settings_access_public"
+msgstr "Công cộng"
+
+#: views/statistics/settings.thtml:52
+msgid "statistics_settings_access_public_description"
+msgstr "Bất kì ai cũng có thể xem thống kê của tiện ích này"
+
+#: views/statistics/addon.thtml:251
+msgid "statistics_settings_change_link"
+msgstr "Thay đổi Thiết lập"
+
+#: views/statistics/addon.thtml:253
+msgid "statistics_settings_confidential"
+msgstr "Vui lòng xem như thông tin này là bí mật."
+
+#: views/statistics/addon.thtml:245
+msgid "statistics_settings_currently_private"
+msgstr "Bảng thống kê hiện đang ở chế độ <b>riêng tư</b>."
+
+#: views/statistics/addon.thtml:241
+msgid "statistics_settings_currently_public"
+msgstr "Bảng thống kê hiện đang ở chế độ <b>công khai</b>."
+
+#: views/statistics/addon.thtml:246
+msgid "statistics_settings_locked_alt"
+msgstr "Äã khóa"
+
+#: views/statistics/settings.thtml:57
+msgid "statistics_settings_return_link"
+msgstr "Trở lại Bảng"
+
+#: views/statistics/settings.thtml:56
+msgid "statistics_settings_save_button"
+msgstr "Lưu Thiết Lập"
+
+#: views/statistics/settings.thtml:46
+#, php-format
+msgid "statistics_settings_title"
+msgstr "Thiết lập Bảng Thống Kê cho %1$s"
+
+#: views/statistics/addon.thtml:242
+msgid "statistics_settings_unlocked_alt"
+msgstr "Không khóa"
+
+#: controllers/components/stats.php:405
+msgid "statistics_shortnames_application"
+msgstr "Ứ.dụng"
+
+#: controllers/components/stats.php:407
+msgid "statistics_shortnames_os"
+msgstr "HÄH"
+
+#: controllers/components/stats.php:406
+msgid "statistics_shortnames_status"
+msgstr "Tr.thái"
+
+#: controllers/components/stats.php:408
+msgid "statistics_shortnames_unknown"
+msgstr "Ko.rõ"
+
+#: controllers/components/stats.php:404
+msgid "statistics_shortnames_version"
+msgstr "P.bản"
+
+#: views/statistics/rss/summary.thtml:42
+#: views/statistics/addon.thtml:192
+msgid "statistics_summary_downloads_average"
+msgstr "Số lượt tải Trung bình Mỗi ngày"
+
+#: views/statistics/rss/summary.thtml:39
+msgid "statistics_summary_downloads_heading"
+msgstr "Số lần tải"
+
+#: views/statistics/rss/summary.thtml:41
+#: views/statistics/addon.thtml:171
+msgid "statistics_summary_downloads_lastcount"
+msgstr "Số lượt của Ngày Cuối"
+
+#: views/statistics/rss/summary.thtml:43
+#: views/statistics/addon.thtml:199
+msgid "statistics_summary_downloads_lastweek"
+msgstr "Số lượt tải trong 7 ngày vừa qua"
+
+#: views/statistics/rss/summary.thtml:40
+#: views/statistics/addon.thtml:151
+msgid "statistics_summary_downloads_total"
+msgstr "Tổng số lượt Tải"
+
+#: views/statistics/rss/summary.thtml:40
+#: views/statistics/addon.thtml:152
+#, php-format
+msgid "statistics_summary_downloads_total_sincedate"
+msgstr "Từ %1$s"
+
+#: views/statistics/rss/summary.thtml:50
+#: views/statistics/rss/summary.thtml:56
+#: views/statistics/addon.thtml:163
+#: views/statistics/addon.thtml:183
+msgid "statistics_summary_nodata"
+msgstr "Chưa có dữ liệu"
+
+#: views/statistics/rss/summary.thtml:60
+#: views/statistics/addon.thtml:195
+msgid "statistics_summary_updatepings_average"
+msgstr "Số ngÆ°á»i dùng Trung bình Má»—i ngày"
+
+#: views/statistics/rss/summary.thtml:52
+#: views/statistics/addon.thtml:177
+msgid "statistics_summary_updatepings_changefromprevious"
+msgstr "Thay đổi kể từ lượt đếm trước"
+
+#: views/statistics/rss/summary.thtml:54
+#: views/statistics/addon.thtml:181
+#, php-format
+msgid "statistics_summary_updatepings_changefromprevious_ondate"
+msgstr "%1$s vào %2$s"
+
+#: views/statistics/rss/summary.thtml:45
+msgid "statistics_summary_updatepings_heading"
+msgstr "NgÆ°á»i dùng Trung bình Má»—i ngày"
+
+#: views/statistics/rss/summary.thtml:46
+#: views/statistics/addon.thtml:157
+msgid "statistics_summary_updatepings_total"
+msgstr "Số ngÆ°á»i dùng Trung bình Má»—i ngày"
+
+#: views/statistics/rss/summary.thtml:48
+#: views/statistics/addon.thtml:161
+#, php-format
+msgid "statistics_summary_updatepings_total_ondate"
+msgstr "Vào %1$s"
+
+#: views/statistics/rss/summary.thtml:61
+#: views/statistics/addon.thtml:203
+msgid "statistics_summary_updatepings_weekly_average"
+msgstr "NgÆ°á»i dùng Hàng ngày Trung bình của Tuần này"
+
+#. %s is a percentage, like '+22.33%'. It sits next to another number, so
+#. the implied meaning is 'percentage change' from the previous stat point.
+#: views/statistics/rss/summary.thtml:62
+#: views/statistics/addon.thtml:205
+msgid "statistics_summary_updatepings_weekly_change"
+msgstr "%s kể từ tuần trước"
+
+#: views/statistics/addon.thtml:65
+#: controllers/statistics_controller.php:184
+#: controllers/statistics_controller.php:282
+#, php-format
+msgid "statistics_title_addon_stats"
+msgstr "Thống kê %1$s"
+
+#: views/addons/themes_landing.thtml:113
+msgid "themes_landing_all_themes"
+msgstr "Tất cả Giao diện"
+
+#: views/addons/themes_landing.thtml:109
+msgid "themes_landing_browse_themes"
+msgstr "Duyệt xem Giao diện"
+
+#: views/users/edit.thtml:185
+msgid "user_change_email"
+msgstr "Thay đổi Äịa chỉ Email"
+
+#: views/users/edit.thtml:169
+msgid "user_change_password"
+msgstr "Thay đổi mật khẩu"
+
+#: views/users/edit.thtml:96
+msgid "user_change_password_or_email"
+msgstr "Thay đổi Mật khẩu hoặc Email"
+
+#: controllers/users_controller.php:197
+msgid "user_confirmationcode_resent"
+msgstr "Mã xác nhận đã được gửi lại!"
+
+#. %1 is the email address, %2 is the URL of the user registration page
+#: views/users/delete.thtml:51
+msgid "user_del_account_deleted"
+msgstr "Tài khoản của bạn %1$s đã được xóa thành công. Nếu bạn muốn quay lại lúc nào đó, bạn có thể đăng kí lại trên <a href=\"%2$s\">trang đăng kí</a>."
+
+#: views/users/delete.thtml:102
+msgid "user_del_community_sad"
+msgstr "Cá»™ng đồng Tiện Ãch Mozilla rất buồn khi thấy bạn bá» Ä‘i."
+
+#: views/users/delete.thtml:123
+msgid "user_del_confirm_password"
+msgstr "Xác nhận Mật khẩu"
+
+#: views/users/delete.thtml:134
+msgid "user_del_deletenow"
+msgstr "Xóa tài khoản của tôi ngay bây giá»"
+
+#. %1 is the URL of the user's info page
+#: views/users/delete.thtml:64
+msgid "user_del_error_addons"
+msgstr "Bạn không thể xóa tài khoản của bạn nếu bạn được liệt kê là <a href=\"%1$s\">tác giả của bất kì tiện ích nào</a>. Äể xóa tài khoản của bạn, vui lòng nhá» ngÆ°á»i khác trong nhóm phát triển của bạn xóa bạn khá»i danh sách tác giả của tiện ích đó. Sau đó bạn sẽ có thể xóa tài khoản của mình tại đây."
+
+#. %1 is a link to the amo-editors mailing list
+#: views/users/delete.thtml:71
+msgid "user_del_error_addons_more_questions"
+msgstr "Nêu bạn còn câu há»i nào, vui lòng liên hệt %1$s để được há»— trợ."
+
+#: views/users/delete.thtml:78
+msgid "user_del_error_checkbox"
+msgstr "Bạn cần xóa hộp \"Tôi hiểu...\" trước khi chúng tôi có thể xóa tài khoản của bạn."
+
+#: views/users/delete.thtml:84
+msgid "user_del_error_password"
+msgstr "Vui lòng nhập mật khẩu chính xác để thực hiện bước này."
+
+#. %1 is a link to the amo-admins mailing list
+#: views/users/delete.thtml:91
+msgid "user_del_error_unknown"
+msgstr "Mội lỗi không rõ xảy ra khi đang xóa tài khoản của bạn. Vui lòng liên hệ %1$s và kèm theo vấn đỠđể chúng tôi xóa nó cho bạn. Chúng tôi xin lỗi vì sự bất tiện này."
+
+#: views/users/delete.thtml:110
+msgid "user_del_header_confirm_deletion"
+msgstr "Xác nhận xóa tài khoản"
+
+#. %1 is the user's email address
+#: views/users/delete.thtml:100
+msgid "user_del_header_delete_account"
+msgstr "Xóa Tài Khoản %1$s"
+
+#: views/users/delete.thtml:50
+msgid "user_del_header_farewell"
+msgstr "Vĩnh biệt!"
+
+#: views/users/delete.thtml:115
+msgid "user_del_nologin"
+msgstr "Bạn sẽ không thể đăng nhập vào Tiện Ãch Mozilla được nữa."
+
+#: views/users/delete.thtml:112
+msgid "user_del_permanently_removed_means"
+msgstr "Khi nhấn \"xóa\" tài khoản của bạn sẽ bị <strong>xóa vÄ©nh viá»…n</strong>. Äiá»u đó có nghÄ©a là:"
+
+#: views/users/delete.thtml:116
+msgid "user_del_reviews_anonymized"
+msgstr "Các đánh giá và xếp hạng của bạn sẽ không bị xóa, nhưng chúng sẽ không còn được gán cho bạn."
+
+#. %1 is a link to the amo-editors mailing list
+#: views/users/delete.thtml:104
+msgid "user_del_specific_problem_editors"
+msgstr "Nếu bạn có má»™t vấn Ä‘á» riêng biệt nào đó, chúng tôi có thể giúp bạn. Vui lòng đừng xóa tài khoản của bạn bây giá», mà hãy liên hệ chúng tôi tại %1$s và chúng tôi sẽ cố hết sức để há»— trợ bạn giải quyết nó."
+
+#: views/users/delete.thtml:130
+msgid "user_del_understand_permanent"
+msgstr "Tôi hiểu rằng bước này sẽ không thể hoàn tác được."
+
+#: views/helpers/addons_html.php:192
+msgid "user_deleted_nickname"
+msgstr "NgÆ°á»i dùng Äã bị xóa"
+
+#. %1 is the new email address
+#: views/users/edit.thtml:71
+msgid "user_edit_confirm_email_sent"
+msgstr "Má»™t email đã được gá»­i tá»›i %1$s để xác nhận địa chỉ email má»›i của bạn. Äể thay đổi có hiệu lá»±c, bạn cần nhấn lên liên kết được cung cấp trong email. Cho đến lúc đó, bạn vẫn có thể đăng nhập bằng địa chỉ email hiện tại."
+
+#: views/users/edit.thtml:201
+msgid "user_edit_delete_user"
+msgstr "Xóa tài khoản ngÆ°á»i dùng"
+
+#. This contains the email sent to users when they signed up for a new
+#. account:
+#. %1 is the confirmation URL, %2 is the current app
+#: views/users/email/confirm_plain.thtml:6
+#, php-format
+msgid "user_email_confirm_account_nopass"
+msgstr ""
+"Chào mừng đến vá»›i Tiện Ãch %2$s.\n"
+"\n"
+"Hãy luôn tìm Ä‘á»c thêm thông tin tại trang web của <a href=\"http://vi.mozdev.org\">Mozilla Việt Nam</a>.\n"
+"\n"
+"TrÆ°á»›c khi có thể sá»­ dụng tài khoản má»›i bạn phải kích hoạt nó - Ä‘iá»u này nhằm đảm bảo rằng địa chỉ email bạn dùng là hợp lệ và thuá»™c vá» bạn.\n"
+"Äể kích hoạt tài khoản của bạn, hãy nhấn vào liên kết bên dÆ°á»›i hoặc chép và dán tòan bá»™ vào thanh địa chỉ trên trình duyệt:\n"
+"\n"
+"%1$s\n"
+"\n"
+"Một khi bạn kích hoạt thành công, bạn có thể xóa e-mail này.\n"
+"\n"
+"Cảm Æ¡n đã tham gia Tiện Ãch %2$s\n"
+"-- Äá»™i ngÅ© Tiện Ãch %2$s"
+
+#. %1 is the confirmation url, %2 is the application name
+#: views/users/email/emailchange_plain.thtml:5
+msgid "user_email_confirm_emailchange"
+msgstr ""
+"Bạn đã yêu cầu thay đổi địa chỉ email trên Tiện Ãch %2$s.\n"
+"\n"
+"Hãy luôn tìm Ä‘á»c thêm thông tin tại trang web của <a href=\"http://vi.mozdev.org\">Mozilla Việt Nam</a>.\n"
+"\n"
+"Äể xác nhận địa chỉ má»›i, vui lòng nhấn vào liên kết bên dÆ°á»›i hoặc chép và dán toàn bá»™ vào thanh địa chỉ trên trình duyệt:\n"
+"\n"
+"%1$s\n"
+"\n"
+"Bạn có 48 giỠđể xác nhận địa chỉ mới. Nếu bạn không muốn thay đổi địa chỉ nữa, bạn chỉ cần bỠqua email này.\n"
+"\n"
+"Cảm ơn!\n"
+"-- Äá»™i ngÅ© Tiện Ãch %2$s"
+
+#: controllers/users_controller.php:168
+#, php-format
+msgid "user_email_confirm_subject"
+msgstr "Cảm ơn đã tham gia Tiện ích %s "
+
+#. This is the password reset email
+#. %1 is the pw reset URL, %2 is the application
+#: views/users/email/pwreset_plain.thtml:5
+#, php-format
+msgid "user_email_pwreset"
+msgstr ""
+"Khôi phục Mật khẩu Tiện ích %2$s\n"
+"\n"
+"Hãy luôn tìm Ä‘á»c thêm thông tin tại trang web của <a href=\"http://vi.mozdev.org\">Mozilla Việt Nam</a>.\n"
+"\n"
+"Nhận được yêu cầu khôi phục mật khẩu cho tài khoản này trên addons.mozilla.org. Äể thay đổi mật khẩu vui lòng nhấn vào liên kết sau đây, hoặc dán nó vào thanh địa chỉ trên trình duyệt:\n"
+"\n"
+"%1$s\n"
+"\n"
+"Nếu bạn không yêu cầu email này thì không cần làm gì cả.\n"
+"\n"
+"Cảm ơn,\n"
+"-- Äá»™i ngÅ© Tiện Ãch %2$s"
+
+#: controllers/users_controller.php:245
+#, php-format
+msgid "user_email_pwreset_subject"
+msgstr "Khôi phục mật khẩu Tiện ích %s"
+
+#: views/users/emailchange.thtml:50
+msgid "user_emailchange_error"
+msgstr "Lá»—i!"
+
+#. %1 is the application name
+#: controllers/users_controller.php:533
+msgid "user_emailchange_subject"
+msgstr "Vuil lòng xác nhận thay đổi địa chỉ email trên Tiện ích %1$s"
+
+#: views/users/emailchange.thtml:48
+msgid "user_emailchange_success"
+msgstr "Thành công!"
+
+#. %1 is the new email address
+#: views/users/emailchange.thtml:49
+msgid "user_emailchange_successful_description"
+msgstr "Äịa chỉ email của bạn đã được thay đổi thành công. Kể từ bây giá», hãy dùng %1$s để đăng nhập."
+
+#: views/users/edit.thtml:134
+#: views/admin/users_edit.thtml:111
+msgid "user_form_bio"
+msgstr "VỠtôi"
+
+#: views/users/edit.thtml:135
+#: views/admin/users_edit.thtml:112
+msgid "user_form_bio_description"
+msgstr "Giá»›i thiệu bản thân bạn trÆ°á»›c cá»™ng đồng, nếu bạn thích! Văn bản này sẽ xuất hiện công khai trên trang thông tin ngÆ°á»i dùng của bạn. Dấu ngắt dòng vẫn được giữ nguyên, nhÆ°ng HTML sẽ không được dùng."
+
+#: views/users/pwreset.thtml:77
+#: views/users/register.thtml:73
+#: views/users/edit.thtml:181
+msgid "user_form_confirmpassword"
+msgstr "Xác nhận mật khẩu"
+
+#: views/users/edit.thtml:145
+msgid "user_form_display_collections"
+msgstr "Hiển thị các bá»™ sÆ°u tập mà tôi đã tạo trong hồ sÆ¡ ngÆ°á»i dùng của tôi"
+
+#: views/users/edit.thtml:149
+msgid "user_form_display_collections_fav"
+msgstr "Hiển thị các bá»™ sÆ°u tập Æ°a thích trong hồ sÆ¡ ngÆ°á»i dùng của tôi"
+
+#: views/users/edit.thtml:86
+#, php-format
+msgid "user_form_editprofile"
+msgstr "Chỉnh sá»­a hồ sÆ¡ ngÆ°á»i dùng cho %s"
+
+#: views/users/pwreset.thtml:52
+#: views/users/login.thtml:81
+#: views/users/register.thtml:63
+#: views/users/edit.thtml:187
+msgid "user_form_email"
+msgstr "Äịa chỉ email"
+
+#: views/users/register.thtml:78
+#: views/users/edit.thtml:103
+#: views/admin/users_edit.thtml:76
+msgid "user_form_firstname"
+msgstr "Tên"
+
+#: views/users/register.thtml:94
+#: views/users/edit.thtml:119
+#: views/admin/users_edit.thtml:91
+msgid "user_form_hideemail"
+msgstr "Ẩn địa chỉ email"
+
+#: views/users/register.thtml:98
+#: views/users/edit.thtml:123
+#: views/admin/users_edit.thtml:99
+msgid "user_form_homepage"
+msgstr "URL trang web"
+
+#: views/users/register.thtml:84
+#: views/users/edit.thtml:109
+#: views/admin/users_edit.thtml:81
+msgid "user_form_lastname"
+msgstr "Há»"
+
+#: controllers/users_controller.php:333
+msgid "user_form_login"
+msgstr "NgÆ°á»i dùng Äăng nhập"
+
+#: views/users/pwreset.thtml:72
+#: views/users/edit.thtml:176
+msgid "user_form_newpassword"
+msgstr "Mật khẩu mới"
+
+#: views/users/register.thtml:89
+#: views/users/edit.thtml:114
+#: views/admin/users_edit.thtml:86
+msgid "user_form_nickname"
+msgstr "Tên nick"
+
+#: views/users/edit.thtml:171
+msgid "user_form_oldpassword"
+msgstr "Mật khẩu cũ"
+
+#: views/users/edit.thtml:97
+#: views/users/edit.thtml:200
+msgid "user_form_otheractions"
+msgstr "Thao tác Khác"
+
+#: views/users/login.thtml:85
+#: views/users/register.thtml:68
+msgid "user_form_password"
+msgstr "Mật khẩu"
+
+#: controllers/users_controller.php:93
+msgid "user_form_registration"
+msgstr "Äăng kí NgÆ°á»i dùng Má»›i"
+
+#: views/users/login.thtml:90
+msgid "user_form_remember_me"
+msgstr "Nhớ tôi trên máy tính này"
+
+#: views/admin/users_edit.thtml:95
+msgid "user_form_showsandbox"
+msgstr "Hiện hộp cát?"
+
+#: views/users/edit.thtml:205
+msgid "user_form_submit_edit"
+msgstr "LÆ°u"
+
+#: views/users/login.thtml:93
+msgid "user_form_submit_login"
+msgstr "Äăng nhập"
+
+#: views/users/register.thtml:113
+msgid "user_form_submit_register"
+msgstr "Äăng kí"
+
+#: views/users/info.thtml:75
+#, php-format
+msgid "user_info_usersince"
+msgstr "NgÆ°á»i dùng trên Tiện ích %s kể từ"
+
+#: views/users/login.thtml:102
+msgid "user_login_register_link"
+msgstr "Tạo một tài khoản mới"
+
+#: views/users/edit.thtml:160
+msgid "user_notifications_item_compat"
+msgstr "Tính tương thích Tiện ích (đặc biệt khuyến nghị)"
+
+#: views/users/edit.thtml:161
+msgid "user_notifications_item_events"
+msgstr "Các sự kiện và cuộc thi sắp diễn ra"
+
+#: views/users/edit.thtml:156
+msgid "user_notifications_none_available"
+msgstr "Hiện tại không có thông báo nào để bạn cấu hình."
+
+#: views/users/edit.thtml:158
+msgid "user_notifications_select_topics"
+msgstr "Thỉnh thoảng, Mozilla có thể gá»­i email cho bạn vá» các bản phát hành sắp có và các sá»± kiện liên quan đến tiện ích. Vui lòng chá»n chủ Ä‘á» mà bạn thích bên dÆ°á»›i:"
+
+#: views/users/edit.thtml:164
+msgid "user_notifications_specific_contact"
+msgstr "Mozilla bảo lÆ°u quyá»n liên hệ vá»›i cá nhân bạn vá» các mối quan tâm đối vá»›i tiện ích được lÆ°u trữ trên đây của bạn."
+
+#: controllers/users_controller.php:543
+msgid "user_profile_edit_error"
+msgstr "Có lỗi trong các thay đổi mà bạn đã tạo. Vui lòng sửa chúng và gửi lại."
+
+#: controllers/users_controller.php:540
+msgid "user_profile_saved"
+msgstr "Hồ sơ đã được cập nhật."
+
+#: views/users/pwreset.thtml:65
+#, php-format
+msgid "user_pwreset_for_email"
+msgstr "Khôi phục mật khẩu cho %s"
+
+#: controllers/users_controller.php:226
+msgid "user_pwreset_header"
+msgstr "Khôi phục Mật khẩu"
+
+#: views/users/login.thtml:103
+msgid "user_pwreset_link"
+msgstr "Quên mật khẩu?"
+
+#: controllers/users_controller.php:248
+msgid "user_pwreset_link_sent"
+msgstr "Liên kết để khôi phục mật khẩu đã được gửi tới địa chỉ email của bạn."
+
+#: controllers/users_controller.php:304
+msgid "user_pwreset_okay"
+msgstr "Mật khẩu đã được khôi phục thành công"
+
+#: views/users/pwreset.thtml:82
+msgid "user_pwreset_submit_changepw"
+msgstr "Gửi lên thay đổi mật khẩu"
+
+#: views/users/pwreset.thtml:57
+msgid "user_pwreset_submit_sendlink"
+msgstr "Gửi liên kết khôi phục mật khẩu"
+
+#: views/users/register_complete.thtml:51
+#, php-format
+msgid "user_register_amo_link"
+msgstr "Tiện ích %s"
+
+#. %1 is the user's email address, %2 is the current app
+#: views/users/activatefirst.thtml:49
+#, php-format
+msgid "user_register_click_confirm_link"
+msgstr "Má»™t liên kết để kích hoạt tài khoản đã được gá»­i bằng email đến địa chỉ %1$s của bạn. Bạn phải nhấn vào nó trÆ°á»›c khi bạn có thể đăng nhập vào Tiện Ãch %2$s."
+
+#. %1 is the user's email address
+#: views/users/register_complete.thtml:49
+#, php-format
+msgid "user_register_confirm_email_sent"
+msgstr "Một email đã được gửi tới địa chỉ %1$s của bạn để xác nhận tài khoản của bạn. Trước khi có thể đăng nhập, bạn phải kích hoạt tài khoản bằng cách nhấn lên liên kết trong email này."
+
+#: views/users/activatefirst.thtml:51
+msgid "user_register_confirmation_link_text"
+msgstr "gửi lại thư xác nhận"
+
+#: views/users/register_complete.thtml:47
+msgid "user_register_congratulations"
+msgstr "Chúc mừng! Tài khoản của bạn đã được tạo thành công."
+
+#: views/users/register.thtml:50
+msgid "user_register_details"
+msgstr "<p>Äăng kí trên AMO là <strong>không bắt buá»™c</strong> nếu nhÆ° bạn chỉ Ä‘Æ¡n giản muốn tải xuống và cài đặt tiện ích công cá»™ng.</p><p>Bạn chỉ cần đăng kí nếu:</p><ul><li>Bạn muốn gá»­i đánh giá cho tiện ích</li><li>Bạn là má»™t nhà phát triển tiện ích và muốn tải tiện ích của bạn lên AMO để lÆ°u trữ</li></ul><p>Khi đăng kí thành công, bạn sẽ nhận được má»™t email xác nhận tại địa chỉ mà bạn đã cung cấp. Vui lòng làm theo chỉ dẫn trong đó để xác nhận tài khoản của bạn.</p><p>Nếu muốn, bạn có thể Ä‘á»c <a href='%1$s' title='LÆ°u ý Pháp lí'>LÆ°u ý Pháp lí</a> và <a href='%2$s' title='Chính sách Riêng tÆ°'>Chính sách Riêng tÆ°</a> của chúng tôi.</p>"
+
+#. %1 is the link to the "resend confirmation code" page
+#: views/users/activatefirst.thtml:51
+#, php-format
+msgid "user_register_resend_confirmation_link"
+msgstr "Nếu bạn không nhận được email xác nhận, hãy chắc chắn rằng dịch vụ email không đánh dấu nó là \"thư rác\" hoặc \"spam\". Nếu cần, bạn có thể yêu cầu chúng tôi %1$s đến địa chỉ email đã nhắc tới ở trên."
+
+#. %1 is the link to the Mozilla Add-ons front page
+#: views/users/register_complete.thtml:51
+#, php-format
+msgid "user_register_welcome"
+msgstr "Cảm ơn đã đăng kí và chào mừng đến %1$s!"
+
+#: views/users/register.thtml:49
+msgid "user_register_welcome_header"
+msgstr "Chào mừng đến addons.mozilla.org (AMO)!"
+
+#: views/users/register.thtml:81
+#: views/users/edit.thtml:106
+msgid "user_required_firstlast_or_nickname"
+msgstr "Tên, hỠhoặc tên nick là bắt buộc."
+
+#: views/users/edit.thtml:94
+#: views/users/edit.thtml:142
+msgid "user_tab_collections"
+msgstr "Bộ sưu tập"
+
+#: views/users/edit.thtml:95
+#: views/users/edit.thtml:154
+msgid "user_tab_notifications"
+msgstr "Thông báo"
+
+#: views/users/edit.thtml:93
+#: views/users/edit.thtml:101
+msgid "user_tab_profile"
+msgstr "Hồ sÆ¡ NgÆ°á»i dùng"
+
+#: controllers/users_controller.php:209
+msgid "user_verified_okay"
+msgstr "Äã xác thá»±c thành công!"
+
+#: controllers/users_controller.php:723
+msgid "users_delete_pagetitle"
+msgstr "Xóa Tài Khoản"
+
+#: controllers/users_controller.php:414
+msgid "users_edit_pagetitle"
+msgstr "Chỉnh sửa Tài khoản"
+
+#: views/users/info.thtml:71
+msgid "users_info_aboutme"
+msgstr "VỠtôi"
+
+#: views/users/info.thtml:96
+#, php-format
+msgid "users_info_addons_by_user"
+msgstr "Tiện ích bởi %1$s"
+
+#: views/users/info.thtml:51
+msgid "users_info_author_name"
+msgstr "Tên"
+
+#: views/users/info.thtml:48
+msgid "users_info_author_profile"
+msgstr "Hồ sÆ¡ NgÆ°á»i dùng"
+
+#. %s is the user name
+#: views/users/info.thtml:137
+msgid "users_info_collections_by_user"
+msgstr "Bộ sưu tập bởi %s"
+
+#: views/users/info.thtml:66
+msgid "users_info_email"
+msgstr "Äịa chỉ email"
+
+#: views/users/info.thtml:155
+msgid "users_info_fav_collections_by_user"
+msgstr "Bộ sưu tập Ưa thích"
+
+#: views/users/info.thtml:61
+msgid "users_info_homepage"
+msgstr "Trang chủ"
+
+#: views/users/info.thtml:56
+msgid "users_info_nickname"
+msgstr "Tên nick"
+
+#: controllers/users_controller.php:707
+#, php-format
+msgid "users_info_pagetitle"
+msgstr "Thông tin NgÆ°á»i dùng cho %1$s"
+
+#. %1 is the user's name
+#: views/users/info.thtml:116
+msgid "users_info_reviews_by_user"
+msgstr "Äánh giá bởi %s"
+
+#: controllers/users_controller.php:330
+#: controllers/users_controller.php:332
+msgid "users_login_pagetitle"
+msgstr "NgÆ°á»i dùng Äăng nhập"
+
+#. %1 is the link to the sandbox/policy explanation page
+#. This message is for a specific add-on not found
+#: views/users/login.thtml:53
+#, php-format
+msgid "users_login_sandbox_display_warning"
+msgstr "Tiện ích bạn Ä‘ang tìm hiện Ä‘ang trong há»™p cát. Nếu bạn đã có má»™t tài khoản trên Tiện Ãch Mozilla, vui lòng đăng nhập, hoặc <a href=\"%1$s\">tìm hiểu thêm vá» há»™p cát.</a>"
+
+#. %1 is the link to the sandbox/policy explanation page
+#. This message is for any given sandbox-related page not found
+#: views/users/login.thtml:56
+#, php-format
+msgid "users_login_sandbox_page_warning"
+msgstr "Trang bạn Ä‘ang tìm là má»™t phần của há»™p cát. Nếu bạn đã có má»™t tài khoản trên Tiện Ãch Mozilla, vui lòng đăng nhập, hoặc <a href=\"%1$s\">tìm hiểu thêm vá» há»™p cát.</a>"
+
+#: controllers/users_controller.php:223
+#: controllers/users_controller.php:225
+msgid "users_pwreset_pagetitle"
+msgstr "Khôi phục Mật khẩu NgÆ°á»i dùng"
+
+#: controllers/users_controller.php:90
+#: controllers/users_controller.php:92
+msgid "users_register_pagetitle"
+msgstr "Äăng kí NgÆ°á»i dùng Má»›i"
+
+#. %1$s is an addon name, like <a>Firebug</a>
+#. %2$s is a version number, like <a>1.2</a>
+#: views/versions/license.thtml:52
+msgid "versions_license_header_source"
+msgstr "Giấy phép mã nguồn cho %1$s %2$s"
+
+#: views/addons/category_landing.thtml:147
+msgid "view_recently_added"
+msgstr "Xem tất cả những cái được thêm gần đây"
+
+#: views/addons/category_landing.thtml:161
+msgid "view_top_downloads"
+msgstr "Xem tất cả những cái được tải nhiá»u nhất"
+
+#: views/addons/category_landing.thtml:175
+msgid "view_top_rated"
+msgstr "Xem tất cả những cái được xếp hạng cao nhất"
+
+#~ msgid "addon_slider_tooltip_next"
+#~ msgstr "Tiện ích Kế"
+#~ msgid "addon_slider_tooltip_previous"
+#~ msgstr "Tiện ích Trước"
+#~ msgid "addon_versions_getlatesttext"
+#~ msgstr "Phiên bản gần nhất tương thích với"
+#~ msgid "addons_display_version_history"
+#~ msgstr "Lịch sử Phiên bản Hoàn thiện"
+#~ msgid "addons_home_newest_header"
+#~ msgstr "Mới nhất:"
+#~ msgid "addons_home_popular_header"
+#~ msgstr "Thông dụng Nhất:"
+#~ msgid "addons_home_recommended_header"
+#~ msgstr "Khuyên Dùng:"
+#~ msgid "addons_home_updated_header"
+#~ msgstr "Cập nhật Gần đây:"
+#~ msgid "addons_home_view_all"
+#~ msgstr "xem tất cả"
+#~ msgid "category_extra_allrecommended"
+#~ msgstr "Xem tất cả các Tiện ích được khuyên dùng"
+#~ msgid "category_extra_highestrated"
+#~ msgstr "Xếp hạng Cao nhất Trước"
+#~ msgid "category_extra_lastupdated"
+#~ msgstr "Cập nhật Gần đây Trước"
+#~ msgid "category_extra_mostpopular"
+#~ msgstr "Thông dụng nhất Trước"
+#~ msgid "collections_detail_js_loading"
+#~ msgstr "Äang tải"
+#~ msgid "collections_detail_more_info"
+#~ msgstr "Hiện thêm Thông tin"
+#~ msgid "devcp_additem_firefox_notice"
+#~ msgstr ""
+#~ "Phiên bản tiện ích này của bạn không cho thấy sự tương thích với Firefox %"
+#~ "1$s. Mozilla đang chuẩn bị cho ra mắt phiên bản Firefox kế tiếp trong nay "
+#~ "mai, cho nên vui lòng kiểm tra tiện ích của bạn trong phiên bản mới và "
+#~ "cập nhật thông tin vỠtính tương thích cho nó. Bạn có thể tìm hiểu thêm "
+#~ "vá» việc này <a href=\"%2$s\">tại đây</a>. Äây chỉ là má»™t thông báo, bạn "
+#~ "vẫn có thể tiếp tục gửi phiên bản này lên addons.mozilla.org."
+#~ msgid "devcp_addon_disabled_successfully"
+#~ msgstr "Tiện ích đã được vô hiệu hóa thành công"
+#~ msgid "devcp_addon_edit_pagetitle"
+#~ msgstr "Chỉnh sửa Tiện ích"
+#~ msgid "devcp_addon_enabled_successfully"
+#~ msgstr "Tiện ích đã được kích hoạt thành công"
+#~ msgid "devcp_addon_field_description_displaytitle"
+#~ msgstr "Mô tả Tiện ích"
+#~ msgid "devcp_addon_field_eula_displaytitle"
+#~ msgstr "EULA"
+#~ msgid "devcp_addon_field_homepage_displaytitle"
+#~ msgstr "Trang chủ Tiện ích"
+#~ msgid "devcp_addon_field_name_displaytitle"
+#~ msgstr "Tên của Tiện ích"
+#~ msgid "devcp_addon_field_privacy_displaytitle"
+#~ msgstr "Chính sách Riêng tư"
+#~ msgid "devcp_addon_field_summary_displaytitle"
+#~ msgstr "Tóm tắt vỠTiện ích"
+#~ msgid "devcp_addon_field_supportemail_displaytitle"
+#~ msgstr "Email hỗ trợ"
+#~ msgid "devcp_addon_field_supporturl_displaytitle"
+#~ msgstr "URL hỗ trợ"
+#~ msgid "devcp_addon_field_versionnotes_displaytitle"
+#~ msgstr "Chú ý Phiên bản"
+#~ msgid "devcp_addon_nominate_pagetitle"
+#~ msgstr "Äá» cá»­ Tiện ích"
+#~ msgid "devcp_addon_nominated_successfully"
+#~ msgstr "Tiện ích đã được ứng cử thành công!"
+#~ msgid "devcp_addon_status_criteria_review"
+#~ msgstr ""
+#~ "Má»™t số bài đánh giá của ngÆ°á»i dùng vá» tiện ích (có thể dùng bài bên "
+#~ "ngoài)."
+#~ msgid "devcp_addon_submission_makechanges"
+#~ msgstr ""
+#~ "Vào trang %1$s để thay đổi những gì bạn gửi lên, hoặc %2$s để trở lại "
+#~ "Công cụ Nhà phát triển."
+#~ msgid "devcp_addon_submission_makechanges_devcp_link"
+#~ msgstr "nhấn vào đây"
+#~ msgid "devcp_addon_submission_makechanges_link"
+#~ msgstr "Chỉnh sửa Tiện ích"
+#~ msgid "devcp_addon_submission_pending"
+#~ msgstr ""
+#~ "Phiên bản này đã được đưa vào hộp cát trong khi chỠđợi sự đánh giá của "
+#~ "những ngÆ°á»i kiểm tra há»™p cát và má»™t ngÆ°á»i biên tập Tiện ích của Mozilla. "
+#~ "Bạn sẽ được thông báo qua e-mail sau khi má»i thứ đã được kiểm tra."
+#~ msgid "devcp_addon_submission_sandbox_readmore"
+#~ msgstr "Bạn có thể Ä‘á»c thêm vá» Hệ Thống Äánh Giá Há»™p Cát %s."
+#~ msgid "devcp_addon_submission_sandbox_readmore_link"
+#~ msgstr "tại đây"
+#~ msgid "devcp_addon_submission_sandboxed"
+#~ msgstr ""
+#~ "Phiên bản này đã được Ä‘Æ°a vào há»™p cát để những ngÆ°á»i có kinh nghiệm dùng "
+#~ "thá»­. Äể nó được hiện trên trang công cá»™ng, bạn phải %s tiện ích của bạn "
+#~ "và chỠcho xong quá trình đánh giá."
+#~ msgid "devcp_addon_submission_sandboxed_nominate_link"
+#~ msgstr "ứng cử"
+#~ msgid "devcp_addon_submission_success"
+#~ msgstr "Việc gửi lên tiện ích của bạn đã thực hiện thành công."
+#~ msgid "devcp_addon_submission_trusted_public"
+#~ msgstr ""
+#~ "Vì tiện ích của bạn đã được tin tưởng, nên phiên bản này được chấp thuận "
+#~ "tự động để đưa sang khu vực công cộng."
+#~ msgid "devcp_addon_submit_pagetitle"
+#~ msgstr "Gá»­i Tiện Ãch"
+#~ msgid "devcp_addon_updated_successfully"
+#~ msgstr "Tiện ích đã được cập nhật thành công"
+#~ msgid "devcp_addon_upload_preview"
+#~ msgstr "Có thể bạn sẽ muốn %s để tăng sự quan tâm đối với tiện ích của bạn."
+#~ msgid "devcp_addon_upload_preview_link"
+#~ msgstr "tải lên một phiên bản để xem trước"
+#~ msgid "devcp_author_lookup_none_found"
+#~ msgstr "không tìm thấy tác giả [%s]"
+#~ msgid "devcp_author_lookup_remove"
+#~ msgstr "Xóa"
+#~ msgid "devcp_button_cancel"
+#~ msgstr "Hủy bá»"
+#~ msgid "devcp_button_cancel_confirm"
+#~ msgstr "Bạn có chắc bạn muốn hủy bỠviệc gửi lên?"
+#~ msgid "devcp_button_next"
+#~ msgstr "Tiếp"
+#~ msgid "devcp_change_addontype"
+#~ msgstr "Thay đổi kiểu tiện ích:"
+#~ msgid "devcp_comments_updated"
+#~ msgstr "Bình luận của Nhà phát triển đã được cập nhật."
+#~ msgid "devcp_details_addpreview_link"
+#~ msgstr "Thêm hình ảnh xem trước"
+#~ msgid "devcp_details_author"
+#~ msgstr "Tác giả"
+#~ msgid "devcp_details_authors"
+#~ msgstr "Tác giả"
+#~ msgid "devcp_details_authors_none"
+#~ msgstr "Không"
+#~ msgid "devcp_details_categories"
+#~ msgstr "Phân mục"
+#~ msgid "devcp_details_category"
+#~ msgstr "Phân mục"
+#~ msgid "devcp_details_description"
+#~ msgstr "Mô tả"
+#~ msgid "devcp_details_disabled"
+#~ msgstr "Bị vô hiệu hóa"
+#~ msgid "devcp_details_guid"
+#~ msgstr "GUID"
+#~ msgid "devcp_details_header_details"
+#~ msgstr "Chi tiết"
+#~ msgid "devcp_details_header_devcomments"
+#~ msgstr "Bình luận của Nhà phát triển"
+#~ msgid "devcp_details_header_previews"
+#~ msgstr "Xem trÆ°á»›c"
+#~ msgid "devcp_details_header_versions"
+#~ msgstr "Phiên bản"
+#~ msgid "devcp_details_homepage"
+#~ msgstr "Trang chủ"
+#~ msgid "devcp_details_homepage_none"
+#~ msgstr "Không"
+#~ msgid "devcp_details_preview_nocaption"
+#~ msgstr "Không tiêu Ä‘á»"
+#~ msgid "devcp_details_previews_nonefound"
+#~ msgstr "Không có phần xem trước."
+#~ msgid "devcp_details_submit_update"
+#~ msgstr "Cập nhật"
+#~ msgid "devcp_details_supportemail"
+#~ msgstr "Email hỗ trợ"
+#~ msgid "devcp_details_supportemail_none"
+#~ msgstr "Không có email hỗ trợ của nhà phát triển."
+#~ msgid "devcp_details_supporturl"
+#~ msgstr "URL hỗ trợ"
+#~ msgid "devcp_details_supporturl_none"
+#~ msgstr "Không có url hỗ trợ của nhà phát triển."
+#~ msgid "devcp_details_trusted"
+#~ msgstr "Äược tin tưởng"
+#~ msgid "devcp_details_versions_none_found"
+#~ msgstr "Không tìm thấy phiên bản nào."
+#~ msgid "devcp_disable_cancel"
+#~ msgstr "Hủy bỠvà quay trở lại"
+#~ msgid "devcp_disable_disable_button"
+#~ msgstr "Äúng, vô hiệu hóa nó"
+#~ msgid "devcp_disable_disable_confirm"
+#~ msgstr "Bạn có chắc bạn muốn vô hiệu hóa tiện ích này?"
+#~ msgid "devcp_disable_disable_description"
+#~ msgstr ""
+#~ "Vô hiệu hóa tiện ích này sẽ ẩn nó khi tìm kiếm và liệt kê. Không thể tải "
+#~ "nó xuống từ trang web và trình duyệt sẽ không hiện nó khi kiểm tra các "
+#~ "cập nhật. Tiện ích rồi cũng sẽ bị xóa, mặc dù vậy bạn vẫn có thể quay lại "
+#~ "đây và kích hoạt lại khi bạn muốn."
+#~ msgid "devcp_disable_disable_title"
+#~ msgstr "Vô hiệu hóa %s"
+#~ msgid "devcp_disable_enable_button"
+#~ msgstr "Äúng, kích hoạt nó"
+#~ msgid "devcp_disable_enable_confirm"
+#~ msgstr "Bạn có chắc bạn muốn kích hoạt tiện ích này?"
+#~ msgid "devcp_disable_enable_description"
+#~ msgstr ""
+#~ "Kích hoạt tiện ích này sẽ cho phép nó được hiện ra khi tìm kiếm và liệt "
+#~ "kê. Nó có thể được tải xuống từ trang web và trình duyệt."
+#~ msgid "devcp_disable_enable_title"
+#~ msgstr "Kích hoạt %s"
+#~ msgid "devcp_edit_author_add"
+#~ msgstr "Thêm Tác Giả"
+#~ msgid "devcp_edit_author_email"
+#~ msgstr "Äịa chỉ Email của Tác giả"
+#~ msgid "devcp_edit_author_remove"
+#~ msgstr "Xóa"
+#~ msgid "devcp_edit_error_categories_unavailable"
+#~ msgstr "Không có phân mục nào cho kiểu tiện ích này."
+#~ msgid "devcp_edit_file_error_incomplete"
+#~ msgstr "Truyá»n tải không hoàn tất"
+#~ msgid "devcp_edit_file_error_no"
+#~ msgstr "Không có tập tin nào được tải lên"
+#~ msgid "devcp_edit_file_error_size"
+#~ msgstr "Vượt quá dung lượng tải lên tối đa"
+#~ msgid "devcp_edit_header_authors"
+#~ msgstr "Tác giả"
+#~ msgid "devcp_edit_icon_add_link"
+#~ msgstr "Thêm Biểu Tượng"
+#~ msgid "devcp_edit_icon_change_link"
+#~ msgstr "Thay đổi Biểu tượng"
+#~ msgid "devcp_edit_label_allow_viewsource"
+#~ msgstr "Cho phép ngÆ°á»i dùng xem tập tin nguồn trá»±c tuyến"
+#~ msgid "devcp_edit_label_categories"
+#~ msgstr "Phân mục"
+#~ msgid "devcp_edit_label_defaultlocale"
+#~ msgstr "Bản địa Mặc định"
+#~ msgid "devcp_edit_label_icon_delete"
+#~ msgstr "Chỉ xóa biểu tượng sẵn có"
+#~ msgid "devcp_edit_label_icon_new"
+#~ msgstr "Tập tin Biểu tượng Mới"
+#~ msgid "devcp_edit_label_info"
+#~ msgstr "Biểu tượng"
+#~ msgid "devcp_edit_locale_disambiguation_explanation"
+#~ msgstr "thông tin bổ sung ngắn gá»n (nhÆ° là tên phÆ°Æ¡ng ngữ)"
+#~ msgid "devcp_edit_submit_update"
+#~ msgstr "Cập nhật"
+#~ msgid "devcp_edit_target_locale_explanation"
+#~ msgstr ""
+#~ "<a href=\"http://wiki.mozilla.org/L10n:Simple_locale_names\">tên địa danh "
+#~ "đơn giản</a>, như là 'vi-VN'"
+#~ msgid "devcp_editversion_checkedfiles_delete"
+#~ msgstr "Tập tin đã đánh dấu sẽ bị xóa."
+#~ msgid "devcp_editversion_filename_size"
+#~ msgstr "%1$s (%2$s)"
+#~ msgid "devcp_editversion_label_files"
+#~ msgstr "Tập tin"
+#~ msgid "devcp_editversion_label_targetapps"
+#~ msgstr "ChÆ°Æ¡ng trình Äích"
+#~ msgid "devcp_editversion_nofiles"
+#~ msgstr "Không có tập tin nào."
+#~ msgid "devcp_editversion_reviewernotes"
+#~ msgstr "Chú ý đối vá»›i NgÆ°á»i đánh giá"
+#~ msgid "devcp_editversion_submit_update"
+#~ msgstr "Cập nhật"
+#~ msgid "devcp_error_addon_field_summary_toolong"
+#~ msgstr ""
+#~ "Tóm tắt có giới hạn tối đa 250 kí tự.\n"
+#~ "(Bạn đã nhập %s)"
+#~ msgid "devcp_error_addonname_not_unique"
+#~ msgstr ""
+#~ "Tên cho tiện ích này đã tồn tại trong cơ sở dữ liệu. Vui lòng chắc chắn "
+#~ "rằng: <br /><li>GUIDs của bạn đã khớp. Nguyên nhân thông dụng nhất của "
+#~ "lỗi này là vì GUIDs không khớp.</li><li>Bạn không thể có một mục bị trùng "
+#~ "trong cơ sở dữ liệu. Nếu như vậy, bạn phải cập nhật mục đó hoặc xóa nó và "
+#~ "thử lại.</li>"
+#~ msgid "devcp_error_describe_changes"
+#~ msgstr "Vui lòng mô tả các thay đổi trong lần cập nhật này."
+#~ msgid "devcp_error_file_guids_dont_match"
+#~ msgstr "Tất cả GUIDs tập tin chưa khớp"
+#~ msgid "devcp_error_identical_version_exists"
+#~ msgstr "Má»™t phiên bản giống hệt tiện ích vá»›i ná»n tảng này (%s) đã tồn tại."
+#~ msgid "devcp_error_nominate_message"
+#~ msgstr "Bạn phải cung cấp các chi tiết được yêu cầu để đỠcử."
+#~ msgid "devcp_error_nominate_no_prerelease"
+#~ msgstr "Bạn không thể đỠcử một tiện ích được phát hành thử."
+#~ msgid "devcp_error_nominate_sandbox_only"
+#~ msgstr "Bạn chỉ có thể đỠcử các tiện ích hiện có trong hộp cát."
+#~ msgid "devcp_error_saving"
+#~ msgstr "Lỗi xảy ra khi đang cố gắng lưu dữ liệu của bạn."
+#~ msgid "devcp_error_update_access_denied"
+#~ msgstr "Bạn không có quyá»n cập nhật tiện ích này."
+#~ msgid "devcp_file_addanother"
+#~ msgstr "Thêm má»™t Tập tin Ná»n tảng Khác"
+#~ msgid "devcp_form_author_add"
+#~ msgstr "Thêm Tác Giả"
+#~ msgid "devcp_form_author_remove"
+#~ msgstr "Xóa"
+#~ msgid "devcp_form_categories_nextstep"
+#~ msgstr ""
+#~ "Phân mục cho kiểu tiện ích của bạn sẽ hiện hữu trong bước tiếp theo."
+#~ msgid "devcp_form_error_categories_unavailable"
+#~ msgstr "Không có phân mục nào cho kiểu tiện ích này."
+#~ msgid "devcp_form_error_description_notempty"
+#~ msgstr "Vui lòng nhập mô tả cho tiện ích của bạn."
+#~ msgid "devcp_form_error_name_required"
+#~ msgstr "Vui lòng nhập tên cho tiện ích của bạn."
+#~ msgid "devcp_form_error_select_addontype"
+#~ msgstr "Vui lòng chá»n kiểu cho tiện ích bạn gá»­i lên."
+#~ msgid "devcp_form_error_summary_notempty"
+#~ msgstr "Vui lòng nhập tóm tắt cho tiện ích của bạn."
+#~ msgid "devcp_form_label_addonfile"
+#~ msgstr "Tập tin Tiện ích"
+#~ msgid "devcp_form_label_addonfile2"
+#~ msgstr "Tập tin Tiện ích 2"
+#~ msgid "devcp_form_label_addonfile3"
+#~ msgstr "Tập tin Tiện ích 3"
+#~ msgid "devcp_form_label_addontype"
+#~ msgstr "Kiểu của Tiện ích"
+#~ msgid "devcp_form_label_allow_viewsource"
+#~ msgstr "Cho phép ngÆ°á»i dùng xem tập tin nguồn trá»±c tuyến"
+#~ msgid "devcp_form_label_author_email"
+#~ msgstr "Äịa chỉ Email của Tác giả"
+#~ msgid "devcp_form_label_authors"
+#~ msgstr "Tác giả"
+#~ msgid "devcp_form_label_categories"
+#~ msgstr "Phân mục"
+#~ msgid "devcp_form_label_defaultlocale"
+#~ msgstr "Bản địa Mặc định"
+#~ msgid "devcp_form_label_description"
+#~ msgstr "Mô tả"
+#~ msgid "devcp_form_label_eula"
+#~ msgstr "Thá»a thuận Giấy phép NgÆ°á»i dùng Cuối (EULA)"
+#~ msgid "devcp_form_label_externalsoftware"
+#~ msgstr "Tiện ích này yêu cầu có phần má»m bên ngoài"
+#~ msgid "devcp_form_label_files"
+#~ msgstr "Tập tin"
+#~ msgid "devcp_form_label_homepage"
+#~ msgstr "Trang chủ"
+#~ msgid "devcp_form_label_iconfile"
+#~ msgstr "Tập tin Biểu tượng"
+#~ msgid "devcp_form_label_name"
+#~ msgstr "Tên"
+#~ msgid "devcp_form_label_platforms"
+#~ msgstr "Ná»n tảng được Há»— trợ"
+#~ msgid "devcp_form_label_prerelease"
+#~ msgstr "Äây là bản phát hành thá»­"
+#~ msgid "devcp_form_label_privacy"
+#~ msgstr "Chính sách Riêng tư"
+#~ msgid "devcp_form_label_sitespecific"
+#~ msgstr "Äây là tiện ích liên quan đến trang web"
+#~ msgid "devcp_form_label_summary"
+#~ msgstr "Tóm tắt"
+#~ msgid "devcp_form_label_supportemail"
+#~ msgstr "Email Hỗ Trợ"
+#~ msgid "devcp_form_label_supporturl"
+#~ msgstr "URL Hỗ Trợ"
+#~ msgid "devcp_form_label_target_applications"
+#~ msgstr "Ứng dụng Äích"
+#~ msgid "devcp_form_label_version"
+#~ msgstr "Phiên bản"
+#~ msgid "devcp_form_label_versionnotes"
+#~ msgstr "Ghi chú Phiên bản"
+#~ msgid "devcp_form_no_target_apps"
+#~ msgstr "Không"
+#~ msgid "devcp_form_reviewernotes"
+#~ msgstr "Ghi chú cho NgÆ°á»i đánh giá"
+#~ msgid "devcp_form_trustedaddon_destination"
+#~ msgstr ""
+#~ "Bởi vì tiện ích của bạn được tin tưởng, vui lòng chá»n nÆ¡i hiển thị phiên "
+#~ "bản này:"
+#~ msgid "devcp_form_trustedaddon_destination_public"
+#~ msgstr "Công cộng"
+#~ msgid "devcp_form_trustedaddon_destination_sandbox"
+#~ msgstr "Hộp cát"
+#~ msgid "devcp_header_developer_agreement"
+#~ msgstr "Thá»a thuận Nhà phát triển"
+#~ msgid "devcp_header_step1"
+#~ msgstr "BÆ°á»›c 1"
+#~ msgid "devcp_header_step1_upload"
+#~ msgstr "Tải lên Tập tin"
+#~ msgid "devcp_header_step2"
+#~ msgstr "BÆ°á»›c 2"
+#~ msgid "devcp_header_step2_addondetails"
+#~ msgstr "Chi tiết vỠTiện ích"
+#~ msgid "devcp_header_step3"
+#~ msgstr "BÆ°á»›c 3"
+#~ msgid "devcp_header_step3_versiondetails"
+#~ msgstr "Chi tiết vỠPhiên bản"
+#~ msgid "devcp_header_step4"
+#~ msgstr "BÆ°á»›c 4"
+#~ msgid "devcp_header_step4_localization"
+#~ msgstr "Bản địa hóa"
+#~ msgid "devcp_header_step5"
+#~ msgstr "BÆ°á»›c 5"
+#~ msgid "devcp_header_step5_success"
+#~ msgstr "Thành công"
+#~ msgid "devcp_index_header_myaddons"
+#~ msgstr "Tiện ích của Tôi"
+#~ msgid "devcp_nominate_link_returnto_details"
+#~ msgstr "Trở lại phần chi tiết tiện ích"
+#~ msgid "devcp_notice_autodetected_addontype"
+#~ msgstr "Tự động dò kiểu tiện ích: %s."
+#~ msgid "devcp_notice_different_defaultlocale"
+#~ msgstr ""
+#~ "Bản địa mặc định cho tiện ích này (%1$s [%2$s]) khác vá»›i bản địa đã chá»n "
+#~ "của bạn (%3$s [%4$s]). Các phần sau nên được hoàn tất trong %1$s."
+#~ msgid "devcp_question_addontype_incorrect"
+#~ msgstr "Không đúng?"
+#~ msgid "devcp_question_delete_file"
+#~ msgstr "Bạn có chắc bạn muốn xóa tập tin này?"
+#~ msgid "devcp_skip_reviewing_addon_info"
+#~ msgstr "BỠqua việc cập nhật thông tin cho tiện ích hiện tại của tôi"
+#~ msgid "devcp_submissions_disabled"
+#~ msgstr ""
+#~ "Việc gửi lên tiện ích hiện đang bị vô hiệu hóa. Vui lòng kiểm tra lại sau."
+#~ msgid "devcp_submit_accept_dev_agreement"
+#~ msgstr "Tôi Chấp Thuận"
+#~ msgid "devcp_submit_decline_dev_agreement"
+#~ msgstr "Tôi Từ Chối"
+#~ msgid "devcp_summary_admin_disabled"
+#~ msgstr "Tiện ích này bị vô hiệu hóa bởi quản trị viên."
+#~ msgid "devcp_summary_header_disabled"
+#~ msgstr "Bị vô hiệu hóa"
+#~ msgid "devcp_summary_header_trusted"
+#~ msgstr "Tin cậy"
+#~ msgid "devcp_summary_noaddons_submit_one"
+#~ msgstr "Bạn không có tiện ích nào. Nhấn %s để gửi lên một cái."
+#~ msgid "devcp_summary_noaddons_submit_one_link"
+#~ msgstr "vào đây"
+#~ msgid "devcp_theme_upload_preview"
+#~ msgstr "Vui lòng nhớ %s cho giao diện của bạn."
+#~ msgid "devcp_theme_upload_preview_link"
+#~ msgstr "tải lên một ảnh xem trước"
+#~ msgid "devcp_version_edit_pagetitle"
+#~ msgstr "Chỉnh sửa Phiên bản"
+#~ msgid "devcp_version_updated_successfully"
+#~ msgstr "Phiên bản được cập nhật thành công."
+#~ msgid "editors_submissiontype_new"
+#~ msgstr "Má»›i"
+#~ msgid "editors_submissiontype_updated"
+#~ msgstr "Äã cập nhật"
+#~ msgid "editors_th_addon_age"
+#~ msgstr "Tuổi của Tiện ích"
+#~ msgid "editors_th_addontypes"
+#~ msgstr "Kiểu của Tiện ích"
+#~ msgid "editors_th_age"
+#~ msgstr "Tuổi"
+#~ msgid "editors_th_applications"
+#~ msgstr "Ứng dụng"
+#~ msgid "editors_th_platforms"
+#~ msgstr "Ná»n tảng"
+#~ msgid "editors_th_submissiontypes"
+#~ msgstr "Kiểu gửi lên"
+#~ msgid "error_notice"
+#~ msgstr "Cảnh báo"
+#~ msgid "forum_save"
+#~ msgstr "LÆ°u"
+#~ msgid "home"
+#~ msgstr "trang chủ"
+#~ msgid "nav_category_plugins"
+#~ msgstr "Phần bổ trợ"
+#~ msgid "page_title_experimental_addons"
+#~ msgstr "Các tiện ích Thử nghiệm"
+#~ msgid "pages_experimental_addons_backbutton"
+#~ msgstr "Trở vỠtrang trước"
+#~ msgid "pagination_page_number_title"
+#~ msgstr "Äây là trang %1$s trong %2$s"
+#~ msgid "search_matching_addons_number"
+#~ msgid_plural "search_matching_addons_number"
+#~ msgstr[0] "%s tiện ích phù hợp"
+#~ msgstr[1] "%s tiện ích phù hợp"
+#~ msgid "statistics_rss_icon_title"
+#~ msgstr "RSS feed của dữ liệu tóm tắt"
+
diff --git a/site/app/locale/vi/images/sandbox-review.png b/site/app/locale/vi/images/sandbox-review.png
new file mode 100644
index 0000000..6d86735
--- /dev/null
+++ b/site/app/locale/vi/images/sandbox-review.png
Binary files differ
diff --git a/site/app/locale/vi/pages/about.thtml b/site/app/locale/vi/pages/about.thtml
new file mode 100644
index 0000000..8937c8c
--- /dev/null
+++ b/site/app/locale/vi/pages/about.thtml
@@ -0,0 +1,66 @@
+<h2>addons.mozilla.org là gì?</h2>
+<p>
+ addons.mozilla.org (AMO) là nơi chính thức để chứa những tiện ích cho các chương trình
+ của Mozilla. Tiện ích cho phép bạn thêm các tính năng mới vào Firefox, Thunderbird,
+ SeaMonkey, và Sunbird. Từ AMO, bạn có thể duyệt và tải xuống hàng nghìn
+ tiện ích để thay đổi cách thức mà bạn sử dụng internet.
+</p>
+
+<h2>Ai tạo ra những tiện ích này?</h2>
+<p>
+ Hàng nghìn nhà phát triển tiện ích, từ cá nhân riêng lẻ cho đến các tập đoàn
+ lớn. Tất cả tiện ích công cộng được đánh giá bởi một nhóm nhân viên tình nguyện
+ trước khi chúng được phát hành. Những tiện ích thử nghiệm sẽ được đánh dấu và
+ chưa được đánh giá.
+</p>
+
+<h2>Làm thế nào để tôi biết chuyện gì đang diễn ra trên AMO?</h2>
+<p>
+ <a href="http://blog.mozilla.com/addons/">Blog</a> của chúng tôi được cập nhật thÆ°á»ng xuyên,
+ và chúng tôi cÅ©ng thÆ°á»ng giá»›i thiệu các bài viết từ cá»™ng đồng chung. Chúng tôi cÅ©ng có má»™t
+ <a href="https://addons.mozilla.org/newsletter">há»™p thÆ° tin</a> gá»­i thÆ°
+ hàng tháng.
+</p>
+
+<h2>Nghe thật tuyệt! Vậy tôi có thể tham gia như thế nào?</h2>
+<p>
+ Có rất nhiá»u cách để tham gia:
+</p>
+<ul>
+ <li>
+ <a href="https://wiki.mozilla.org/AMO:Editors/Applying">Hãy trở thành một
+ biên tập viên</a>. Các biên tập viên của chúng tôi là những ngÆ°á»i có hiểu biết kÄ© thuật và hâm má»™
+ AMO, hỠsẽ đánh giá chất lượng và sự ổn định của các tiện ích.
+ </li>
+ <li>
+ <a href="http://developer.mozilla.org/">Tạo ra tiện ích của riêng bạn</a>. AMO
+ cung cấp dịch vụ cập nhật và lưu trữ miễn phí, và có thể giúp bạn tiếp cận một
+ lượng lá»›n ngÆ°á»i dùng.
+ </li>
+ <li>
+ Hãy nói cho bạn bè cùng biết! <a href="http://spreadfirefox.com/">Lan truyá»n Firefox</a>
+ và cho má»i ngÆ°á»i biết những tiện ích mà bạn dùng.
+ </li>
+ <li>
+ Báo lỗi và gửi bản sửa.
+ <a href="https://bugzilla.mozilla.org/buglist.cgi?quicksearch=addons">Bugzilla</a>
+ có nói tới tất cả các lỗi AMO hiện tại. Bạn có thể báo thêm những lỗi chưa được
+ phát hiện hoặc đóng góp các bản vá.
+ </li>
+</ul>
+
+<h2>Tôi có má»™t câu há»i.</h2>
+<p>
+ Một nơi tốt để bắt đầu là
+ <a href="https://addons.mozilla.org/pages/faq"><abbr title="Há»i Äáp ThÆ°á»ng Gặp">FAQ</abbr></a> của
+ chúng tôi. Nếu bạn không tìm thấy câu trả lá»i ở đó, hãy dùng thông tin liên hệ ở cuối trang này. Äối
+ vá»›i các câu há»i vá» má»™t tiện ích nào đó, hãy dùng thông tin liên hệ trên trang giá»›i thiệu của nó.
+</p>
+
+<h2>Liên hệ Chúng tôi</h2>
+<dl>
+ <dt>Mozilla Việt Nam: <a href="http://vi.mozdev.org">vi.mozdev.org</a></dt>
+ <dt>Sử dụng <abbr title="Internet Relay Chat">IRC</abbr> (tiếng Anh):</dt>
+ <dd><a href="irc://irc.mozilla.org/#addons">#addons</a> trên irc.mozilla.org cho các câu há»i thông thÆ°á»ng và liên quan đến đánh giá</dd>
+ <dd><a href="irc://irc.mozilla.org/#amo">#amo</a> trên irc.mozilla.org cho các mối quan tâm vỠviệc phát triển hoặc quản trị</dd>
+</dl>
diff --git a/site/app/locale/vi/pages/collector.thtml b/site/app/locale/vi/pages/collector.thtml
new file mode 100644
index 0000000..b3d0eee
--- /dev/null
+++ b/site/app/locale/vi/pages/collector.thtml
@@ -0,0 +1,47 @@
+<h2>Trình sưu tập Tiện ích Mozilla Firefox</h2>
+
+<p class="intro">Giúp cho việc tùy biến trình duyệt của bạn luôn ở đỉnh cao.</p>
+
+<div class="primary">
+ <p>Khám phá thêm các tiện ích tốt nhất và tổ chức các tiện ích Æ°a thích của bạn trong các bá»™ sÆ°u tập dá»… quản lí. Äăng kí theo dõi để xem các bá»™ sÆ°u tập mà bạn ngưỡng má»™ phát triển nhÆ° thế nào, và ngÆ°á»i hâm má»™ sẽ bám Ä‘uôi khi bạn quản lí và cập nhật bá»™ sÆ°u tập của riêng mình.</p>
+</div>
+
+<div class="secondary">
+ <div class="highlight">
+ <h4>Tải xuống Trình sưu tập Tiện ích:</h4>
+ %1$s
+ </div><!-- /.highlight -->
+</div>
+
+<div class="column-wrapper article-wrapper">
+
+ <div class="column first">
+ <div class="article">
+ <h3>Bộ sưu tập Khuyên dùng</h3>
+ <p>Äăng kí theo dõi má»™t Bá»™ sÆ°u tập Tiện ích và nhận thông báo khi nó phát triển. Nếu bạn tạo bá»™ sÆ°u tập, có má»™t chá»— để nói tại sao bạn thích má»™t tiện ích nào đó và cung cấp má»™t vài ngữ cảnh để tùy biến.</p>
+
+ </div>
+ </div>
+
+ <div class="column">
+ <div class="article">
+ <h3>Chia sẻ Tiện ích</h3>
+ <p>Báo bạn bè biết những phát hiện thú vị. Chá»n “Xuất bản tá»›i†và há» sẽ nhận tin vá» các tiện ích trong má»™t định dạng sẵn sàng để dùng được chứng thá»±c bởi nguồn (chính là bạn!).</p>
+ </div>
+
+ </div>
+
+
+ <div class="column">
+ <div class="article">
+ <h3>Äồng bá»™ vá»›i Tất cả Các nguồn</h3>
+ <p>Loan báo Bá»™ sÆ°u tập Tiện ích má»›i và cung cấp các liên kết luôn hiện hữu, nhá» Trình xuất bản Tá»± Ä‘á»™ng. Äồng bá»™ hóa các thiết bị và giữ cho các trình duyệt của bạn được trang bị vá»›i bá»™ sÆ°u tập má»›i nhất.</p>
+ </div>
+ </div>
+
+</div><!-- /.column-wrapper .article-wrapper -->
+
+<ul class="further-navigation">
+ <li><a href="%2$s">Tính năng Trình sưu tập Tiện ích</a></li>
+ <li><a href="%3$s">Câu há»i ThÆ°á»ng gặp</a></li>
+</ul>
diff --git a/site/app/locale/vi/pages/collector_faq.thtml b/site/app/locale/vi/pages/collector_faq.thtml
new file mode 100644
index 0000000..e0bfa28
--- /dev/null
+++ b/site/app/locale/vi/pages/collector_faq.thtml
@@ -0,0 +1,24 @@
+<h2>Câu há»i ThÆ°á»ng gặp vá» Trình sÆ°u tập Tiện ích </h2>
+
+<dl class="faq">
+<dt>Bộ sưu tập là gì?</dt>
+<dd>Bộ sưu tập là nhóm các tiện ích liên quan được kết hợp lại để chia sẻ dễ dàng.</dd>
+
+<dt>Trình sưu tập Tiện ích là gì?</dt>
+<dd>Trình sưu tập Tiện ích là một phần mở rộng cho Firefox giúp bạn dễ dàng được cập nhật thông tin vỠcác bộ sưu tập ưa thích.</dd>
+
+<dt>Tôi cần làm gì để dùng Trình sưu tập Tiện ích?</dt>
+<dd>Bạn sẽ cần một <a href="%s">tài khoản trên Tiện ích Mozilla</a> và phiên bản mới nhất của <a href="http://www.getfirefox.com">Firefox</a>.</dd>
+
+<dt>Làm thế nào để tôi đăng kí theo dõi một bộ sưu tập?</dt>
+<dd>Bạn có thể đăng kí theo dõi một bộ sưu tập bằng cách đánh dấu nó là ưa thích trong <a href="%s">Thư mục Bộ sưu tập</a>. Bộ sưu tập ưa thích của bạn sẽ xuất hiện dưới dạng mục đăng kí theo dõi trong Trình quản lí Tiện ích.</dd>
+
+<dt>Tôi có thể đồng bộ tiện ích của mình giữa các máy tính với Trình sưu tập Tiện ích bằng cách nào?</dt>
+<dd>Chỉ cần thiết lập một trình-xuất-bản-tự-động trên một máy tính, và nó sẽ xuất hiện ở trên đầu danh sách đăng kí theo dõi của bạn trên tất cả máy tính có Trình sưu tập. Bạn sẽ có thể thấy các tiện ích đã được cài trên mỗi máy tính có thiết lập trình-xuất-bản-tự-động.</dd>
+
+<dt>Chẳng phải Weave từ Mozilla Labs cũng đang nghiên cứu cách đồng bộ tiện ích đấy sao?</dt>
+<dd>Trong tÆ°Æ¡ng lai Weave không có kế hoạch há»— trợ việc đồng bá»™ tiện ích giữa các hồ sÆ¡ và thiết bị. Việc đồng bá»™ của Trình sÆ°u tập Tiện ích hoạt Ä‘á»™ng hÆ¡i khác má»™t chút, đó là các dữ liệu được xuất-bản-tá»±-Ä‘á»™ng của bạn không được mã hóa và được thiết kế để chia sẻ vá»›i bạn bè dÆ°á»›i hình thức của má»™t bá»™ sÆ°u tập. Tiện ích có thể được chia sẻ giữa các hồ sÆ¡ thông qua nhiá»u bá»™ sÆ°u tập.</dd>
+
+<dt>Tôi có thể cung cấp phản hồi hoặc báo lỗi ở đâu?</dt>
+<dd>Nếu bạn tìm thấy má»™t lá»—i hoặc muốn Ä‘á» xuất má»™t tính năng, vui lòng gá»­i nó lên Bugzilla thông qua <a href="https://bugzilla.mozilla.org/enter_bug.cgi?component=Bandwagon&amp;product=addons.mozilla.org">biểu mẫu này</a>. Nếu bạn muốn cung cấp phản hồi thông thÆ°á»ng, vui lòng gá»­i nó lên <a href="http://groups.google.com/group/mozilla.dev.amo">nhóm tin của chúng tôi</a>.</dd>
+</dl>
diff --git a/site/app/locale/vi/pages/collector_features.thtml b/site/app/locale/vi/pages/collector_features.thtml
new file mode 100644
index 0000000..30139ef
--- /dev/null
+++ b/site/app/locale/vi/pages/collector_features.thtml
@@ -0,0 +1,30 @@
+<p>
+ Bộ sưu tập Tiện ích giúp cho bạn luôn được kết nối với các tiện ích ưa thích và
+ các bá»™ sÆ°u tập theo nhiá»u cách:
+</p>
+
+<dl>
+ <dt>Truy cập các bộ sưu tập ưa thích của bạn từ Firefox</dt>
+ <dd>
+ Các bộ sưu tập mà bạn đánh dấu là ưa thích trong
+ <a href="%1$s">Thư mục Bộ sưu tập</a> xuất hiện với vai trò đặc biệt trong
+ Trình quản lí Tiện ích. Bạn sẽ có thể luôn được cập nhật và xem nội dung
+ của mỗi bộ sưu tập.
+ </dd>
+ <dt>Chia sẻ tiện ích với Trình đơn Xuất bản</dt>
+ <dd>
+ Má»—i tiện ích mà bạn cài Ä‘á»u có thể được chia sẻ dá»… dàng vá»›i má»™t ngÆ°á»i bạn thông qua email hoặc
+ được xuất bản tới một trong các bộ sưu tập của bạn thông qua một trình đơn xuất bản.
+ </dd>
+ <dt>Nhận thông báo</dt>
+ <dd>
+ Trình sưu tập sẽ báo bạn khi một trong các bộ sưu tập ưa thích của bạn có một
+ mục mới, và đánh dấu nó để bạn xem sau.
+ </dd>
+
+ <dt>Tự động xuất bản các tiện ích đã cài của bạn tới một bộ sưu tập</dt>
+ <dd>
+ Chức năng tự động xuất bản giữ cho bộ sưu tập của bạn liên tục được cập nhật với
+ các tiện ích mới nhất của bạn, giúp những bạn bè đang theo dõi cũng được cập nhật.
+ </dd>
+</dl>
diff --git a/site/app/locale/vi/pages/collector_firstrun.thtml b/site/app/locale/vi/pages/collector_firstrun.thtml
new file mode 100644
index 0000000..479b9c7
--- /dev/null
+++ b/site/app/locale/vi/pages/collector_firstrun.thtml
@@ -0,0 +1,38 @@
+<div>
+ <h2>Chào mừng</h2>
+ <p class="intro">Trình sưu tập Tiện ích Firefox đã được thêm vào trình duyệt Firefox của bạn. Bạn coi như là đã sẵn sàng để xây dựng, quản lí, chia sẻ và nhận các Bộ sưu tập Tiện ích.</p>
+</div>
+
+ <div class="primary">
+ <h3>Äể bắt đầu dùng Trình sÆ°u tập Tiện ích Firefox</h3>
+ <ol class="numbered">
+ <li>
+ <h4 class="step">1</h4>
+ Nhấn lên trình Ä‘Æ¡n Công cụ trên thanh công cụ Firefox và chá»n “Tiện ích.â€
+ </li>
+ <li>
+ <h4 class="step">2</h4>
+ Từ bảng Äăng kí theo dõi, đăng nhập bằng thông tin tài khoản tiện ích Mozilla của bạn.
+ </li>
+ <li>
+ <h4 class="step">3</h4>
+ Bạn sẽ thấy má»™t danh sách tất cả các bá»™ sÆ°u tập ở bên trái. Nhấn lên bất kì bá»™ sÆ°u tập nào để xem danh sách ná»™i dung chi tiết. Nhấn “Thêm vào Firefox†hoặc “Xuất bản tá»›i†để quản lí bá»™ sÆ°u tập đó hoặc gá»­i tá»›i má»™t ngÆ°á»i bạn qua email.
+ </li>
+ </ol>
+ <p>Cho dù bạn là má»™t ngÆ°á»i luôn thèm khát săn lùng tiện ích hoặc chỉ là má»™t ngÆ°á»i sá»­ dụng tiện ích để làm cho trải nghiệm web của mình tốt hÆ¡n, Trình sÆ°u tập Tiện ích ở đây là để giúp bạn việc đó. Äể biết thêm thông tin vá» tính năng của Trình sÆ°u tập Tiện ích Firefox và các câu há»i thÆ°á»ng gặp, hãy xem <a href="%1$s">trang tính năng</a> và <a href="%2$s">FAQ</a>.</p>
+ </div><!-- / .primary -->
+
+ <div class="secondary">
+ <div class="highlight">
+ <h4>Bắt Äầu vá»›i các Bá»™ sÆ°u tập này</h4>
+
+ <ul>
+ %3$s
+ </ul>
+
+ <ul class="further-navigation">
+ <li><a href="%4$s" class="more-info">Xem tất cả Bộ sưu tập</a></li>
+ </ul>
+ </div><!-- /. highlight -->
+ </div><!-- /. secondary-->
+
diff --git a/site/app/locale/vi/pages/compatibility_developer_tips.thtml b/site/app/locale/vi/pages/compatibility_developer_tips.thtml
new file mode 100644
index 0000000..ad42f00
--- /dev/null
+++ b/site/app/locale/vi/pages/compatibility_developer_tips.thtml
@@ -0,0 +1,6 @@
+<ul class="tips">
+ <li>Thông tin vỠviệc cập nhật tiện ích cho %s có thể được tìm thấy trong <a href="https://developer.mozilla.org/En/Updating_extensions_for_%s">bài viết này trên Trung tâm Phát triển Mozilla</a>.</li>
+ <li>Thông tin vỠcác thay đổi trong %s có thể được tìm thấy trong <a href="https://developer.mozilla.org/en/%s_for_developers">bài viết này</a>.</li>
+ <li>Bạn có thể đăng kí nhận tin từ <a href="https://addons.mozilla.org/newsletter">thÆ° tin about:addons</a> và <a href="http://blog.mozilla.com/addons/">blog của Tiện Ãch Mozilla</a> để biết thêm các cập nhật khác.</li>
+ <li>Nếu tiện ích của bạn không cần phải sá»­a mã nguồn cho tÆ°Æ¡ng thích vá»›i phiên bản má»›i và Ä‘ang được để trên Tiện Ãch Mozilla, bạn chỉ cần tăng thuá»™c tính maxVersion má»™t cách trá»±c tuyến mà không cần tải lên tập tin má»›i bằng cách vào <a href="%s">khu vá»±c Công cụ Nhà phát triển</a> hoặc bằng cách xem trạng thái của nó ở bên dÆ°á»›i.</li>
+</ul> \ No newline at end of file
diff --git a/site/app/locale/vi/pages/compatibility_user_tips.thtml b/site/app/locale/vi/pages/compatibility_user_tips.thtml
new file mode 100644
index 0000000..cb752ba
--- /dev/null
+++ b/site/app/locale/vi/pages/compatibility_user_tips.thtml
@@ -0,0 +1,6 @@
+<ul class="tips">
+ <li>Trong khi nhiá»u tiện ích có thể há»— trợ các thay đổi trong %s mà không cần sá»­a mã nguồn, nhiá»u cái khác có thể vẫn cần tác giả chỉnh sá»­a má»™t chút để đảm bảo cho má»™t sá»± nâng cấp suôn sẻ. Vui lòng kiên nhẫn trong thá»i gian này, vì nhiá»u nhà phát triển duy trì các tiện ích của há» chủ yếu là tá»± nguyện dá»±a trên sở thích mà thôi.</li>
+ <li>Mozilla không khuyến khích việc vô hiệu hóa thiết lập kiểm tra tính tÆ°Æ¡ng thích, vì Ä‘iá»u này có thể dẫn đến nhiá»u vấn Ä‘á» nghiêm trá»ng khi khởi Ä‘á»™ng %s, và thậm chí có thể làm mất dữ liệu nếu phần mở rá»™ng không tÆ°Æ¡ng thích vá»›i phiên bản má»›i của %s bị ép chạy.</li>
+ <li>Nếu phần mở rộng mà bạn đang muốn dùng không còn tương thích sau khi %s được phát hành, có thể bạn cần kiểm tra trang web của nó hoặc trang của tác giả để tìm các thông tin liên quan đến việc cập nhật.</li>
+ <li>Có thể bạn cũng sẽ muốn tìm một tiện ích có các chức năng tương tự và có hỗ trợ %s trên trang web <a href="%s">Tiện ích %s</a>.</li>
+</ul> \ No newline at end of file
diff --git a/site/app/locale/vi/pages/error404.thtml b/site/app/locale/vi/pages/error404.thtml
new file mode 100644
index 0000000..3fbf2e9
--- /dev/null
+++ b/site/app/locale/vi/pages/error404.thtml
@@ -0,0 +1,16 @@
+<h1>Xin lỗi, nhưng chúng tôi không thể tìm thấy cái bạn đang tìm.</h1>
+
+<p>Trang hay tập tin bạn yêu cầu không được tìm thấy trên trang chúng tôi. Có thể bạn đã nhấn lên một liên kết bị hết hạn, hoặc đã gõ địa chỉ không chính xác.</p>
+
+<ul>
+<li>Nếu bạn gõ địa chỉ, vui lòng kiểm tra kĩ chính tả.</li>
+<li>Nếu bạn vào liên kết từ đâu đó, vui lòng cho chúng tôi biết tại <a href="mailto:webmaster@mozilla.com" title="Không Tìm Thấy Trang trên Mozilla.com">webmaster@mozilla.com</a>. Cho chúng tôi biết bạn đến từ đâu và đang tìm gì, chúng tôi sẽ cố gắng hết sức để khắc phục.</li>
+</ul>
+
+<p>Hoặc bạn có thể chuyển đến những trang thông dụng trên trang web của chúng tôi.</p>
+
+<ul>
+<li>Bạn có hứng thú với <a href="%1$s">danh sách các tiện ích thông dụng</a>?</li>
+<li>Bạn có muốn <a href="%2$s">tìm kiếm tiện ích</a>? Bạn có thể vào <a href="%2$s">trang tìm kiếm</a> hoặc chỉ cần dùng ô tìm kiếm ở bên trên.</li>
+<li>Nếu bạn thích bắt đầu từ đầu, chỉ cần vào <a href="%3$s">trang chủ tiện ích</a>.</li>
+</ul>
diff --git a/site/app/locale/vi/pages/faq.thtml b/site/app/locale/vi/pages/faq.thtml
new file mode 100644
index 0000000..6a89e30
--- /dev/null
+++ b/site/app/locale/vi/pages/faq.thtml
@@ -0,0 +1,60 @@
+<h1>Há»i Äáp ThÆ°á»ng Gặp</h1>
+
+<p>Bản FAQ cho <a href="http://addons.mozilla.org">trang AMO</a> đưa ra một số chủ đỠkhông được nhắc tới trên trang web Hỗ Trợ Firefox. Trang web Hỗ Trợ bao gồm thông tin giới thiệu vỠ<a href="http://support.mozilla.com/kb/Customizing+Firefox+with+add-ons">tùy biến Firefox với tiện ích</a> cũng như các bài viết khác trên:</p>
+
+<ul>
+ <li> Khắc phục vấn Ä‘á» <a href="http://support.mozilla.com/kb/Unable+to+install+add-ons">cài đặt tiện ích</a>, <a href="http://support.mozilla.com/kb/Troubleshooting+plugins">phần bổ trợ</a> &amp; <a href="http://support.mozilla.com/kb/Troubleshooting+extensions+and+themes">các vấn Ä‘á» thông thÆ°á»ng</a>.</li>
+ <li> <a href="http://support.mozilla.com/kb/Uninstalling+add-ons">Làm thế nào để gỡ bá» tiện ích</a> và <a href="http://support.mozilla.com/kb/Cannot+uninstall+an+add-on">khắc phục vấn Ä‘á» gỡ bá»</a>.</li>
+ <li> <a href="http://support.mozilla.com/kb/Gray+bar+below+the+status+bar">Xử lí các tiện ích trục trặc / vấn đỠThanh Bị Xám</a></li>
+</ul>
+
+<p></p>
+
+<h2>Câu há»i vá» Tiện ích</h2>
+<dl class="faq">
+<dt>Tiện ích (Add-on) là gì?</dt>
+<dd>Tiện ích cho phép bạn thêm các tính năng vốn không có trong chương trình chuẩn. Giao diện (Theme) thay đổi diện mạo mà không làm thay đổi chức năng. Phần bổ trợ Tìm kiếm và Từ điển/Gói ngôn ngữ thêm các hỗ trợ ngôn ngữ và máy tìm kiếm. Phần mở rộng thêm các tính năng đa dạng cho trình duyệt; một số thêm các thanh công cụ đơn giản trong khi một số khác có thể thêm hàng loạt tính năng mới.</dd>
+
+<dt>Tiện ích có dễ cài đặt không?</dt>
+<dd>Có! Tiện ích rất dá»… cài. Chúng thÆ°á»ng nhá» hÆ¡n má»™t chÆ°Æ¡ng trình bình thÆ°á»ng và tải xuống rất nhanh chóng. Nếu không thích cái nào, bạn có thể dá»… dàng gỡ bá» hoặc vô hiệu hóa chúng. TÆ°Æ¡ng tá»±, nếu có bản cập nhật cho tiện ích của bạn, Firefox sẽ tá»± Ä‘á»™ng thông báo và cho phép bạn nâng cấp chỉ bằng má»™t cú nhấp chuá»™t.</dd>
+
+<dt>Tôi có thể quản lí tiện ích như thế nào?</dt>
+<dd>Trong Firefox, vào "Tiện ích" trên trình Ä‘Æ¡n Công cụ để quản lí Giao diện và Phần mở rá»™ng. Nếu Phần mở rá»™ng của bạn có các tùy chá»n đặc biệt, bạn có thể xem chúng trong mục Phần mở rá»™ng của cá»­a sổ Tiện ích. Từ đây, bạn cÅ©ng có thể vô hiệu hóa và gỡ bá» tiện ích. Từ Ä‘iển được cài đặt nhÆ° Phần mở rá»™ng. Phần bổ trợ Tìm kiếm có thể được quản lí trong Thanh Tìm Kiếm.</dd>
+
+<dt>Tiện ích có làm Firefox chậm hơn không?</dt>
+<dd>Trong Ä‘a số trÆ°á»ng hợp, các tiện ích không làm chậm Firefox. Tuy nhiên, vì chúng cÅ©ng là chÆ°Æ¡ng trình, má»™t số có thể ảnh hưởng đến hiệu năng của Firefox tùy vào cấu hình hệ thống của bạn. Nếu nghi ngá» có tiện ích nào đó ảnh hưởng đến quá trình Firefox chạy trên máy, hãy thá»­ vô hiệu hóa nó.</dd>
+
+<dt>Tại sao tôi chỉ nên vô hiệu hóa tiện ích?</dt>
+<dd>Vô hiệu hóa tiện ích ngăn không cho nó được nạp khi bạn khởi Ä‘á»™ng Firefox, nhÆ°ng việc đó sẽ không gỡ bá» tiện ích hay xóa các thiết lập của nó. Kích hoạt lại tiện ích sẽ Ä‘Æ°a nó vá» lại trạng thái trÆ°á»›c thá»i Ä‘iểm bạn vô hiệu hóa. Äối vá»›i các tiện ích mà bạn muốn tắt mà không muốn gỡ bá», vô hiệu hóa là cách nên làm.</dd>
+
+<dt>Tôi có thể sao lưu tất cả tiện ích và giao diện đã cài như thế nào?</dt>
+<dd>Bạn có thể sao lưu thư mục hồ sơ của mình, việc này cũng sẽ sao lưu tiện ích và giao diện của bạn. Một chương trình của bên thứ ba như MozBackup cũng có thể giúp cho bạn.</dd>
+</dl>
+
+<h2>Câu há»i vá» Website</h2>
+<dl class="faq">
+<dt>Tôi thấy vài tiện ích cung cấp các chức năng giống nhau. Làm sao để tôi có thể quyết định cái nào là tốt nhất?</dt>
+<dd>Nói chung, bạn có thể nhìn vào xếp hạng và số lượt tải để tham khảo. Các tiện ích tốt có xu hÆ°á»›ng được tải nhiá»u hÆ¡n những cái kém. Tuy nhiên, cÅ©ng dá»… dàng cài đặt cả hai tiện ích để quyết định cái nào bạn muốn dùng. Có khi bạn lại quyết định dùng luôn cả hai sau khi thá»­ đấy!</dd>
+
+<dt>Tôi thấy một tiện ích rất tuyệt nhưng nó nói rằng nó chỉ tương thích với Firefox 2.x. Liệu tôi có thể cài nó trong Firefox 3.x không?</dt>
+<dd>Nói chung là, không. Firefox 3.x có má»™t số tính năng má»›i và phần lá»›n các nhà phát triển tiện ích đã cập nhật các tiện ích của há» cho 3.x. Nếu tiện ích đó chỉ há»— trợ Firefox 2, hãy thá»­ tìm kiếm tên của nó. Trong nhiá»u trÆ°á»ng hợp, sẽ có má»™t phiên bản há»— trợ Firefox 3 và có tên giống hoặc tÆ°Æ¡ng tá»± nhÆ° thế.</dd>
+
+<dt>Tôi đã cài má»™t giao diện má»›i nhÆ°ng muốn quay trở lại giao diện mặc định của Firefox. Tôi có thể làm Ä‘iá»u đó nhÆ° thế nào?</dt>
+<dd>Vào "Tiện ích" trên trình Ä‘Æ¡n "Công cụ". Nhấn lên mục "Giao diện" và từ đây bạn có thể chá»n giao diện mặc định, hoặc bất kì giao diện nào khác mà bạn đã cài.</dd>
+
+<dt>Nếu gặp một vấn đỠvới tiện ích, tôi có nên liên hệ Mozilla không?</dt>
+<dd>Tiện ích, ngoại trừ má»™t số trÆ°á»ng hợp, được tạo bởi cá»™ng đồng chứ không phải Mozilla. Äiá»u tốt nhất nên làm là liên hệ trá»±c tiếp nhà phát triển nó. Äể tìm thông tin liên hệ của má»™t nhà phát triển, nhấn vào tên của há» trên trang giá»›i thiệu Tiện ích.</dd>
+
+<dt>Tiện ích được đánh giá xem xét như thế nào?</dt>
+<dd>Tiện ích công cộng được đánh giá bởi đội ngũ biên tập tài năng và tận tụy của chúng tôi. HỠđánh giá mã nguồn của tất cả các tiện ích công cộng và cũng thử nghiệm các tiện ích để chắc chắn rằng chúng được mô tả chính xác.</dd>
+
+<dt>Tôi vừa nâng cấp lên Firefox 3.5 nhưng tiện ích của tôi không còn hoạt động nữa? Tại sao vậy?</dt>
+<dd>Äa số tiện ích của chúng tôi nay đã tÆ°Æ¡ng thích vá»›i Firefox 3.5, và luôn có thêm nhiá»u cái má»—i ngày. Nếu tiện ích của bạn chạy trên 3.0 nhÆ°ng không chạy trên 3.5, nhiá»u khả năng là các tác giả vẫn Ä‘ang chỉnh sá»­a chúng. Khi há» cập nhật các tiện ích của mình, Firefox sẽ thông báo cho bạn vá» việc nâng cấp.</dd>
+
+<dt id="experimental-addons">Tiện ích thử nghiệm là gì?</dt>
+<dd>Tiện ích Thá»­ nghiệm thÆ°á»ng là các tiện ích má»›i nhất được lÆ°u trữ trên AMO. Những tiện ích này chÆ°a trải qua việc đánh giá của biên tập viên (vốn cần để trở thành công cá»™ng) và thÆ°á»ng chỉ má»›i ở má»™t mức Ä‘á»™ chất lượng thuá»™c dạng phát hành thá»­. Vì chúng chÆ°a được đánh giá, nhiá»u khả năng sẽ có lá»—i nào đó khi bạn cài đặt.</dd>
+
+<dt id="recommended-addons">Các tiện ích được Khuyến nghị và Khuyên dùng là gì?</dt>
+<dd>Nhóm AMO khuyên dùng má»™t bá»™ tiện ích đại diện cho má»™t số các tiện ích tốt nhất theo cả ý nghÄ©a tiện lợi và trải nghiệm nói chung. Các tiện ích được Khuyên dùng này xuất hiện trên các trang phân mục riêng lẻ. Má»™t số các tiện ích này cÅ©ng được xếp xoay vòng ở trang đầu của AMO dÆ°á»›i dạng các tiện ích được Khuyến nghị. Äây không phải là má»™t danh sách toàn diện, và chúng tôi cập nhật danh sách này hàng tháng để liên tục cho ngÆ°á»i dùng thấy má»™t bá»™ má»›i. Vài Ä‘iá»u chúng tôi luôn cân nhắc khi khuyên dùng các tiện ích này: chất lượng, mức Ä‘á»™ phổ biến, tính Ä‘á»™c đáo, và tiện ích đã được giá»›i thiệu hay chÆ°a.</dd>
+
+</dl>
diff --git a/site/app/locale/vi/pages/fashion_faq.thtml b/site/app/locale/vi/pages/fashion_faq.thtml
new file mode 100644
index 0000000..0a69290
--- /dev/null
+++ b/site/app/locale/vi/pages/fashion_faq.thtml
@@ -0,0 +1,57 @@
+<h1>Câu há»i ThÆ°á»ng gặp</h1>
+</div><!-- END branding -->
+
+<div id="content-main" class="faq">
+
+<dl>
+<dt>Tạo Mốt Cho Firefox Của Bạn là gì?</dt>
+<dd>Firefox cung cấp cho bạn các cách thức tốt nhất để tùy biến trải nghiệm trá»±c tuyến của bạn, cho phép bạn canh chỉnh trình duyệt riêng cho cách thức bạn sá»­ dụng Web. Tạo Mốt Cho Firefox Của Bạn là má»™t ứng dụng Web Ä‘Æ¡n giản giúp tùy biến trình duyệt Firefox dá»±a trên sở thích và hoạt Ä‘á»™ng trá»±c tuyến của bạn. Tạo Mốt Cho Firefox Của Bạn giúp bạn lá»±a chá»n các tiện ích phù hợp nhu cầu, và cài đặt chúng chỉ vá»›i má»™t cú nhấp chuá»™t.</dd>
+
+<dt>Tiện ích là gì?</dt>
+<dd>Tiện ích Firefox là những mẩu phần má»m nhá» Ä‘Æ°a thêm tính năng hoặc chức năng vào trình duyệt của bạn. Tiện ích mở rá»™ng Firefox, giúp bạn canh chỉnh trình duyệt cho phù hợp vá»›i nhu cầu và thị hiếu của bạn.  Có hÆ¡n 5000 tiện ích Ä‘ang chỠđợi được giúp bạn làm thêm nhiá»u việc, có thêm niá»m vui và trở nên sáng tạo hÆ¡n.</dd>
+
+<dt>"Tạo Mốt Cho Firefox Của Bạn" có ý nghĩa gì?</dt>
+<dd>Tạo Mốt Cho Firefox Của Bạn ám chỉ khả năng của ứng dụng có thể tùy biến, canh chỉnh, và "tạo mốt" cho Firefox của bạn phù hợp với các hoạt động trực tuyến hàng ngày của bạn.</dd>
+
+<dt>Tạo Mốt Cho Firefox Của Bạn có làm việc vá»›i má»i phiên bản của Firefox?</dt>
+<dd>Vào lúc này, Tạo Mốt Cho Firefox Của Bạn chỉ tương thích với Firefox 3. </dd>
+
+<dt>Làm cách nào để tôi có thể thêm nhiá»u tiện ích vào bá»™ sÆ°u tập Tạo Mốt Cho Firefox Của Bạn?</dt>
+<dd>Tạo Mốt Cho Firefox Của Bạn sẽ hÆ°á»›ng dẫn bạn quá trình dá»… dàng này – không còn cần phải tá»± Ä‘i tìm tiện ích phù hợp nhu cầu của bạn nữa.  Chỉ cần chá»n các tiện ích trong những phân mục thú vị, nhấn lên nút “Tôi muốn tiện ích này!â€, và chá»n liên kết “Nhấn vào đây để cài đặtâ€.  Bạn sẽ được Ä‘á» nghị xác nhận sá»± lá»±a chá»n của mình, sau đó trình duyệt sẽ khởi Ä‘á»™ng lại - các tiện ích sẽ được thêm vào Firefox mà không cần phải cài từng cái. Thế đấy – chào mừng đến vá»›i trình duyệt cá nhân hóa của bạn.</dd>
+
+<dt>Liệu các tiện ích được cung cấp trong Tạo Mốt Cho Firefox Của Bạn có bao giỠthay đổi?</dt>
+<dd>Tạo Mốt Cho Firefox Của Bạn là bộ tiện ích đầu tiên trong số những bộ sẽ được đưa ra trong năm.</dd>
+
+<dt>Mozilla lá»±a chá»n tiện ích cho Tạo Mốt Cho Firefox Của Bạn nhÆ° thế nào?</dt>
+
+<dd>Các tiện ích này bắt buộc phải phù hợp các tiêu chí sau đây:</dd>
+<ul>
+<li>Cung cấp má»™t loạt chức năng tốt đồng Ä‘á»u</li>
+<li>Dễ sử dụng</li>
+<li>Thông dụng trong phân mục</li>
+<li>Tương thích Firefox 3 và Mac/PC</li>
+</ul>
+
+<dt>DÆ°á»ng nhÆ° tôi không thể tìm thấy các tiện ích của tôi sau khi tải “Tạo Mốt Cho Firefox Của Bạn.†Nó đâu rồi?</dt>
+<dd>Má»—i tiện ích có thể xuất hiện ở nhiá»u nÆ¡i khác nhau trong trình duyệt Firefox của bạn. Má»™t số xuất hiện dÆ°á»›i dạng thanh công cụ hoặc nút trên trình duyệt, má»™t số lại xuất hiện dÆ°á»›i dạng biểu tượng ở phần dÆ°á»›i của trình duyệt và má»™t số có thể truy cập được từ trình Ä‘Æ¡n “Công cụ†trong Firefox.  Nếu bạn gặp vấn Ä‘á» trong việc tìm má»™t tiện ích trong bá»™ Tạo Mốt Cho Firefox Của Bạn đã chá»n, hãy thá»­ tìm nhanh trên addons.mozilla.org để biết thêm thông tin vá» cách tìm nó trong trình duyệt.</dd>
+
+<dt>Có thể cài đặt nhiá»u hÆ¡n má»™t giao diện từ phân mục “Trang trí†không?</dt>
+<dd>Có thể cài đặt nhiá»u hÆ¡n má»™t, nhÆ°ng chỉ má»™t giao diện được hiển thị trong má»™t thá»i Ä‘iểm. Äể dá»… dàng chuyển giao diện, vào trình Ä‘Æ¡n “Công cụ†trong Firefox và chá»n “Tiện ích†để vào trình quản lí Tiện ích.  Nhấn lên trình Ä‘Æ¡n “Giao diện†ở trên cùng, chá»n giao diện mà bạn muốn hiển thị, và nhấn lên nút “Dùng Giao diệnâ€.</dd>
+
+<dt>Làm cách nào để tôi có thể gỡ bá» má»™t tiện ích ra khá»i bá»™ sÆ°u tập?</dt>
+<dd>Äể gỡ bá» má»™t tiện ích hay giao diện, hãy vào trình Ä‘Æ¡n “Công cụ†trong Firefox và chá»n “Tiện ích†để vào trình quản lí Tiện ích.  Nhấn lên tiện ích hoặc giao diện mà bạn muốn gỡ bá» và chá»n “Gỡ bá».† Khi bạn khởi Ä‘á»™ng lại trình duyệt, giao diện hoặc tiện ích không mong muốn sẽ được gỡ bá».</dd>
+
+<dt>Những ngôn ngữ nào được Tạo Mốt Cho Firefox Của Bạn hỗ trợ?</dt>
+<dd>Hiện tại, Tạo Mốt Cho Firefox Của Bạn chỉ có tiếng Anh, mặc dù vậy, việc hỗ trợ những ngôn ngữ khác cũng đang được tiến hành. </dd>
+
+<dt>Có cách nào đơn giản để chia sẻ bộ sưu tập Tạo Mốt Cho Firefox Của Bạn với bạn bè không?</dt>
+<dd>Hiện tại chưa có cách nào chia sẻ các tiện ích Tạo Mốt Cho Firefox Của Bạn với bạn bè, nhưng tính năng này có thể sẽ có trong tương lai.</dd>
+
+<dt>Làm cách nào để tôi có thể nhận được trợ giúp cho các vấn đỠcủa Tạo Mốt Cho Firefox Của Bạn mà tôi gặp phải?</dt>
+<dd>Bạn có thể vào trang trợ giúp của Mozilla,
+<a href="http://support.mozilla.com/vi">support.mozilla.com/vi</a>, để được trợ giúp
+chung.  Äối vá»›i các trợ giúp vá» tiện ích, vui lòng vào
+<a href="http://addons.mozilla.org/vi">addons.mozilla.org/vi</a>.</dd>
+
+</dl>
+</div>
diff --git a/site/app/locale/vi/pages/nomination.thtml b/site/app/locale/vi/pages/nomination.thtml
new file mode 100644
index 0000000..c8ba064
--- /dev/null
+++ b/site/app/locale/vi/pages/nomination.thtml
@@ -0,0 +1,10 @@
+<p>Má»™t tiện ích hiện Ä‘ang trong há»™p cát có thể được Ä‘á» cá»­ để trở thành má»™t phần của trang công cá»™ng và hiện hữu trÆ°á»›c tất cả ngÆ°á»i dùng sau khi được đánh giá bởi má»™t biên tập viên. Äể có kết quả tốt nhất, vui lòng chú ý những Ä‘iá»u sau:</p>
+<ul>
+ <li>Ảnh xem trước là bắt buộc đối với giao diện và đặc biệt khuyến khích cho tất cả các kiểu tiện ích.</li>
+ <li>Tiện ích phải trải qua đủ thá»i gian trong há»™p cát để tích lÅ©y đánh giá và phản hồi từ ngÆ°á»i dùng. <b>Phải có bài đánh giá trÆ°á»›c khi được Ä‘Æ°a ra trang công cá»™ng.</b></li>
+ <li>Tiện ích công cộng có chất lượng cao hơn tiện ích trong hộp cát và nên giúp cải tiến web.</li>
+ <li>Tiêu chí đỠcử đầy đủ có trong <a href="%s">Chính sách Tiện ích</a>.</li>
+</ul>
+<p>Nếu tiện ích của bạn phù hợp các tiêu chí trên, bạn có thể Ä‘á» cá»­ nó bằng cách Ä‘iá»n vào phần bên dÆ°á»›i. Bạn sẽ được thông báo qua e-mail vá» trạng thái của việc Ä‘á» cá»­.</p>
+
+<p>Äể Ä‘á» cá»­ tiện ích của bạn, hãy mô tả nó đã được kiểm tra nhÆ° thế nào (bao gồm cả việc nó không có lá»—i hoặc cảnh báo) và nó hữu ích nhÆ° thế nào đối vá»›i thế giá»›i web. Bạn cÅ©ng có thể kèm theo liên kết đến các đánh giá bên ngoài vá» tiện ích của bạn.</p>
diff --git a/site/app/locale/vi/pages/policy.thtml b/site/app/locale/vi/pages/policy.thtml
new file mode 100644
index 0000000..38aaaca
--- /dev/null
+++ b/site/app/locale/vi/pages/policy.thtml
@@ -0,0 +1,112 @@
+<h1>Chính sách Tiện ích</h1>
+
+<h2>Hộp cát là gì?</h2>
+<p>Hãy xem %s.</p>
+
+<h2>Những tiện ích nào nằm trong hộp cát?</h2>
+<p>Hộp cát là nơi tất cả tiện ích trên AMO phải đi vào, trước khi có thể triển khai. Nó bao gồm các phiên bản mới của các tiện ích công cộng, cũng như tất cả các phiên bản của những tiện ích chưa được đưa ra công cộng. Khi có một tiện ích mới, hoặc bản cập nhật cho một tiện ích đã tồn tại, được gửi lên AMO, nó sẽ được đặt trong hộp cát.</p>
+
+<p>Má»™t số tiện ích, và phiên bản của chúng, được Ä‘Æ°a ra công cá»™ng sau khi quá trình đánh giá cho thấy chúng đã sẵn sàng và phù hợp cho khu vá»±c công cá»™ng. Những tiện ích khác vẫn sẽ nằm trong há»™p cát, nÆ¡i chúng hiện hữu trÆ°á»›c những ngÆ°á»i dùng muốn duyệt danh sách trong há»™p cát và thá»­ nghiệm các phần má»m ở trong đó.</p>
+
+<h2>Tiện ích được đưa ra công cộng như thế nào?</h2>
+
+<p>Tiện ích được đánh giá bởi những ngÆ°á»i dùng có tài khoản trên AMO để xem há»™p cát và kiểm tra các gói phần má»m trong đó. Những bài đánh giá của ngÆ°á»i dùng AMO sẽ cho biết liệu tiện ích có đủ hữu ích, được lập trình kÄ© càng và đủ tinh gá»n để được Ä‘Æ°a ra trÆ°á»›c tất cả ngÆ°á»i dùng Firefox hay chÆ°a. Có thể những đánh giá này, bên cạnh các đánh giá và kiểm tra của nhóm AMO, cÅ©ng được dùng để xác định liệu má»™t tiện ích có nên được Ä‘Æ°a ra khá»i há»™p cát và đặt công cá»™ng hay chÆ°a, liệu nó có cần hiệu chỉnh thêm trÆ°á»›c khi phổ biến rá»™ng rãi, hay liệu nó có phù hợp để giá»›i thiệu trên trang AMO hay chÆ°a.</p>
+
+<h2>Làm cách nào để tiện ích của tôi được đưa lên trạng thái công cộng?</h2>
+
+<p>Nếu bạn tin rằng tiện ích của bạn (và hành vi của bạn nữa!) phù hợp với tiêu chí cho một tiện ích công cộng, bạn có thể đỠcử nó trong công cụ của nhà phát triển.</p>
+
+<h2>Tiêu chí cho tiện ích công cộng là gì?</h2>
+
+<p>Má»™t tiện ích được Ä‘Æ°a ra công cá»™ng trên AMO cần có chất lượng cao, và cho ngÆ°á»i dùng má»™t trải nghiệm web tốt hÆ¡n. Chúng tôi để ý những Ä‘iá»u sau khi quyết định liệu má»™t tiện ích có phù hợp để Ä‘Æ°a ra khu vá»±c công cá»™ng của AMO hay không:</p>
+
+<h3>Bạn có nhiệt tình không?</h3>
+
+<p>Chúng tôi mong rằng tác giả nào quảng bá tiện ích của há» trÆ°á»›c ngÆ°á»i dùng Firefox thì cÅ©ng sẽ luôn phản hồi các báo cáo lá»—i, duy trì thông tin liên hệ của há», và cập nhật tiện ích thÆ°á»ng xuyên để giữ tính đồng bá»™ vá»›i các phiên bản Firefox hiện thá»i và các thay đổi trong chính sách của AMO. Äiá»u này không có nghÄ©a là bạn phải trả lá»i má»i câu há»i mà ngÆ°á»i khác gá»­i lên trong phần thảo luận, hoặc bạn cần phải sá»­a má»i lá»—i, nhÆ°ng chúng tôi mong đợi bạn sẽ phản hồi các vấn Ä‘á» bằng thái Ä‘á»™ phù hợp vá»›i tính nghiêm trá»ng của vấn đỠđược há»i.</p>
+
+<h3>Tiện ích có được mô tả chính xác và rõ ràng không?</h3>
+
+<p>Äiá»u quan trá»ng nhất đối vá»›i chúng tôi là ngÆ°á»i dùng nhận được Ä‘iá»u há» mong đợi khi há» thá»­ dùng má»™t tiện ích má»›i. Mô tả của bạn phải cung cấp chi tiết vá» những gì tiện ích làm, cách thức ngÆ°á»i dùng có thể tận dụng nó, và ngÆ°á»i dùng có thể trông mong Ä‘iá»u gì khi cài nó. Liên kết đến các tài liệu hÆ°á»›ng dẫn chi tiết ở bên ngoài được cho phép, nhÆ°ng phần mô tả cần có những cái cÆ¡ bản và giúp cho ngÆ°á»i đùng tá»± tin biết rõ há» sẽ nhận được gì.</p>
+
+<p>CÅ©ng nhÆ° thế, Ä‘iá»u quan trá»ng là bạn duy trì các ghi chú phiên bản cho phù hợp khi bạn cải tiến và thay đổi tiện ích của bạn. NgÆ°á»i dùng cần biết có Ä‘iá»u gì má»›i trong tiện ích hỠđã dùng trÆ°á»›c đây, và phải được biết vá» các thay đổi có thể ảnh hưởng đến việc sá»­ dụng tiện ích hiện tại của há» khi há» cập nhật. (Hiện tại, ngÆ°á»i dùng không thấy ghi chú phiên bản khi hỠđược Ä‘á» nghị cập nhật trong trình duyệt, nhÆ°ng chúng tôi sẽ khắc phục Ä‘iá»u đó. Nếu bạn duy trì tốt các ghi chú phiên bản, ngÆ°á»i dùng của bạn sẽ được hưởng lợi rất nhiá»u trÆ°á»›c và sau khi việc khắc phục được hoàn tất.)</p>
+
+<h3>Tất cả các mối quan tâm vá» bảo mật và quyá»n riêng tÆ° được nói ra hết chÆ°a?</h3>
+
+<p>Äây là má»™t khía cạnh của má»™t bản mô tả chính xác và rõ ràng, nhÆ°ng vì nó rất quan trá»ng nên chúng tôi nghÄ© rằng nó xứng đáng được nhắc đến cụ thể. Nhiá»u tiện ích rất có ích và được viết tốt vẫn có thể thao túng má»™t dạng dữ liệu ngÆ°á»i dùng nào đó, hoặc có thể dẫn đến nguy cÆ¡ bảo mật nếu bị sá»­ dụng sai; chúng được đón chào trên phần công cá»™ng của AMO, nhÆ°ng chúng phải nói rõ ràng cho ngÆ°á»i dùng biết những nguy cÆ¡ mà há» có thể gặp, và những gì há» có thể làm để tá»± bảo vệ mình</p>
+
+<h3>Tiện ích đã được kiểm tra kÄ© càng chÆ°a, và có đúng là nó hoàn toàn không có sai sót nghiêm trá»ng hoặc dá»… thấy?</h3>
+
+<p>Má»™t Ä‘iá»u quan trá»ng mà chúng tôi để ý khi cân nhắc việc Ä‘Æ°a má»™t tiện ích ra nÆ¡i công cá»™ng là liệu các đánh giá trong há»™p cát có cho biết nó đã nhận được sá»± thá»­ nghiệm kÄ© lưỡng hay chÆ°a, và nó không có vấn Ä‘á» nghiêm trá»ng hoặc gây ảnh hưởng xấu đến trình duyệt. Nếu những ngÆ°á»i đánh giá báo cáo các vấn Ä‘á» nhÆ° các lá»—i hoạt Ä‘á»™ng quan trá»ng, các đổ vỡ, những vấn Ä‘á» thÆ°á»ng xuyên xảy ra khi sá»­ dụng các chức năng của tiện ích, hoặc gá»­i đầy thông Ä‘iệp đến bảng kiểm soát lá»—i, bạn cần lÆ°u ý những báo cáo đó trong tâm trí, và Ä‘á» cá»­ lại tiện ích của bạn sau khi bạn đã khắc phục chúng ở mức tốt nhất có thể. Chúng tôi không mong đợi bạn phải tối Æ°u hóa hoàn hảo hoặc không có lá»—i nào -- bản thân Firefox cÅ©ng trải qua cải tiến liên tục ở các mặt này -- nhÆ°ng chúng tôi muốn bạn có ná»— lá»±c hợp lí để giảm thiểu các khiếm khuyết, và nói rõ những trÆ°á»ng hợp có thể khiến ngÆ°á»i dùng ngạc nhiên vì những lá»—i còn sót.</p>
+
+<p>Nếu tiện ích của bạn đã được thá»­ nghiệm bên ngoài quá trình Há»™p cát Amo, ví dụ bởi má»™t nhóm ngÆ°á»i dùng dịch vụ của bạn hay má»™t nhóm QA (Quality Assurance - Äảm bảo Chất lượng) ná»™i bá»™, bạn nên cho biết Ä‘iá»u đó trong thông Ä‘iệp Ä‘á» cá»­. Äiá»u đó chắc chắn sẽ giúp chúng tôi xác lập mức Ä‘á»™ thá»­ nghiệm đã có, và có thể giúp tiện ích của bạn được Ä‘Æ°a lên trang.</p>
+
+<h3>Tiện ích và tác giả tiện ích có đối xá»­ vá»›i ngÆ°á»i dùng má»™t cách tôn trá»ng?</h3>
+
+<p>Phần má»m của bạn không được xâm nhập máy ngÆ°á»i dùng nếu không cần thiết, cố gắng lừa ngÆ°á»i dùng, hoặc che giấu bất kì hoạt Ä‘á»™ng nào của nó trÆ°á»›c ngÆ°á»i dùng. NgÆ°á»i dùng (hoặc thậm chí những ngÆ°á»i không dùng) đôi khi thô lá»— trong các bình luận của há», và trong lúc chúng tôi sẽ cố hết sức để lá»c bá» các bình luận đó khi chúng được gá»­i lên, chúng tôi cÅ©ng mong rằng các tác giả tránh ăn miếng trả miếng bằng thái Ä‘á»™ thô lá»—.</p>
+
+<h3>Tiện ích có phù hợp vá»›i lượng ngÆ°á»i dùng rá»™ng rãi của Firefox?</h3>
+
+<p>Tiện ích của bạn không cần phải là Greasemonkey hoặc Firebug kế tiếp, nhÆ°ng nếu nó chỉ hữu ích đối vá»›i những ngÆ°á»i trong công ty của bạn hoặc những ngÆ°á»i thuá»™c má»™t cá»™ng đồng web nhá», thì chúng tôi nghÄ© là chÆ°a phù hợp để Ä‘Æ°a nó ra trÆ°á»›c tất cả ngÆ°á»i dùng Firefox.</p>
+
+<p>Chúng tôi Ä‘ang liên tục tìm cách cải tiến tính tổ chức của trang để thích nghi tốt hÆ¡n vá»›i các tiện ích vốn mẫu má»±c ở nhiá»u phÆ°Æ¡ng diện, nhÆ°ng chỉ nhắm đến má»™t cá»™ng đồng nhá». Phân loại chính xác và duy trì siêu-dữ-liệu cho tiện ích của bạn sẽ giúp chúng tôi tìm ra cách Ä‘Æ°a thêm các kiểu tiện ích này đến những ngÆ°á»i hưởng lợi ích từ chúng nhiá»u nhất.</p>
+
+<p>Nếu tiện ích của bạn chỉ cung cấp trang đánh dấu hoặc các điểm truy cập đơn giản đến trang của bạn, nó có thể không
+phù hợp cho khu vực công cộng của trang chúng tôi. Giống như những dự án Mozilla khác, chúng tôi yêu thích ứng dụng web và
+các dịch vụ web má»›i, nhÆ°ng tiện ích Firefox nên cung cấp má»™t trải nghiệm duyệt web tốt hÆ¡n cho ngÆ°á»i dùng chứ không nên chỉ là cách để quảng bá má»™t dịch vụ hay trang web má»›i thông qua danh sách trên AMO. Nếu phần mô tả tiện ích của bạn chủ yếu là vá» dịch vụ hÆ¡n là vá» các cải tiến mà nó tạo ra đối vá»›i trải nghiệm duyệt web của ngÆ°á»i dùng, thì có lẽ bạn chÆ°a Ä‘i đúng Ä‘Æ°á»ng rồi.</p>
+
+<h3>Tiện ích không kèm theo bản quyá»n hay thÆ°Æ¡ng hiệu không có giấy phép chứ?</h3>
+
+<p>Mặc dù có thể bạn không có ý làm tổn hại ngÆ°á»i nắm giữ thÆ°Æ¡ng hiệu, hoặc ngÆ°á»i sở hữu sản phẩm có bản quyá»n, nhÆ°ng chúng tôi không thể lÆ°u trữ những tiện ích xâm phạm thÆ°Æ¡ng hiệu hoặc bản quyá»n. Nếu bạn không có quyá»n sá»­ dụng má»™t tên hoặc hình ảnh đã được đăng kí thÆ°Æ¡ng hiệu, vui lòng không gá»­i tiện ích của bạn lên AMO. Nếu tiện ích của bạn bao gồm Ä‘oạn mã thuá»™c bản quyá»n của ngÆ°á»i khác, và không được cấp phép cho bạn sá»­ dụng trong tiện ích, vui lòng không gá»­i tiện ích của bạn lên AMO. (Nếu ngÆ°á»i nắm giữ thÆ°Æ¡ng hiệu hay bản quyá»n phản đối việc sá»­ dụng thÆ°Æ¡ng hiệu của há», chúng tôi sẽ phải Ä‘Æ°a yêu cầu gỡ bá» này cho luật sÆ° xem xét, và chúng tôi sẽ gỡ bá» tiện ích nếu Ä‘iá»u đó là cần thiết theo luật. Äây là má»™t quá trình đắt Ä‘á» so vá»›i tài nguyên của dá»± án, tính cả thá»i gian và tiá»n bạc, cho nên chúng tôi Ä‘á» nghị bạn hãy tôn trá»ng và đừng gây cho chúng tôi những khó khăn không đáng có.)</p>
+
+<p>Nếu bạn không chắc vá» tên của tiện ích, hay việc sá»­ dụng thành phần nào đó trong nó, thì Ä‘iá»u này sẽ khiến nó không được liệt kê trên trang, bạn có thể há»i amo-editors@mozilla.org để được hÆ°á»›ng dẫn. QUAN TRỌNG: Vui lòng chú ý rằng nhóm này không thể cung cấp tÆ° vấn pháp lí, và thậm chí nếu chúng tôi cảm thấy việc sá»­ dụng của bạn có thể chấp nhận được, chúng tôi vẫn có thể thay đổi quyết định khi thấy có phàn nàn từ những ngÆ°á»i nắm giữ các quyá»n và lá»i khuyên từ bên tÆ° vấn luật.</p>
+
+<p>Vá» việc sá»­ dụng lại mã nguồn của tiện ích khác, nếu tác giả đó chÆ°a xác nhận rõ rằng bạn được phép sá»­ dụng mã của há» trong sản phẩm của bạn -- ví dụ nhÆ° phát hành mã nguồn theo giấy phép mã nguồn mở -- thì bạn nên cho rằng bạn không có quyá»n làm vậy. Bạn có thể liên hệ tác giả để tìm kiếm quyá»n hạn đó, nhÆ°ng chúng tôi không thể cung cấp cho bạn bất kì quyá»n hạn đặc biệt nào đối vá»›i nó chỉ vì nó đã có trên AMO, hoặc vì tác giả không phản hồi yêu cầu của bạn. (Và, xin nhắc lại, chúng tôi không thể cung cấp tÆ° vấn pháp lí, chỉ là lá»i khuyên vá» cách thức tiện ích của bạn tÆ°Æ¡ng tác vá»›i chính sách của trang chúng tôi.)</p>
+
+<p>Äiá»u này cÅ©ng áp dụng cho các thÆ°Æ¡ng hiệu của Quỹ Mozilla, bao gồm "Mozilla", "Firefox", và "Thunderbird". Chính sách của Mozilla vá» việc sá»­ dụng thÆ°Æ¡ng hiệu được thiết kế để tránh nhầm lẫn, và tránh việc thÆ°Æ¡ng hiệu bị sụp đổ vì thiếu sá»± bảo vệ; vui lòng tôn trá»ng sá»± cần thiết của việc bảo vệ nhÆ° vậy, và giúp chúng tôi giữ gìn má»™t vài trong số các tài sản giá trị nhất của Tổ chức Mozilla.</p>
+
+<h2>Äiá»u gì xảy ra sau khi tôi Ä‘á» cá»­?</h2>
+
+<p>Một khi tiện ích của bạn được đỠcử, nó sẽ được xem xét bởi một nhóm Biên tập viên AMO tùy theo tiêu chí đã được mô tả ở trên. Nếu sẵn sàng cho việc hiển thị nơi công cộng, nó sẽ được đưa ra khu vực công cộng một khi nó đã được xem xét, và bạn sẽ nhận được một email thông báo.</p>
+
+<p>Nếu chúng tôi cảm thấy tiện ích không phù hợp cho khu vá»±c công cá»™ng của AMO vào lúc này, bạn sẽ nhận được má»™t email thông báo chỉ rõ vì sao, và Ä‘á» cá»­ của bạn sẽ bị rút ra khá»i danh sách chá». Nếu và khi bạn cảm thấy bạn đã khắc phục những mối quan tâm được nhắc tá»›i trong thông báo đó, và bạn muốn được xem xét má»™t lần nữa, bạn có thể làm theo ý mình. Äá» cá»­ liên tục mà không có cải tiến ý nghÄ©a nào trong tiện ích sẽ không được xem trá»ng, cho nên vui lòng tập cách suy xét; có vẻ bạn sẽ làm chúng tôi tức giận hÆ¡n là làm chúng tôi kiệt sức.</p>
+
+<h2>Tôi có thể Ä‘á» cá»­ tiện ích của ngÆ°á»i khác không?</h2>
+
+<p>Hiện tại, chúng tôi Ä‘á» nghị tác giả của tiện ích tá»± Ä‘á» cá»­ sản phẩm của hỠđể được công bố. Chúng tôi muốn chắc chắn rằng tác giả thoải mái vá»›i việc công khai sản phẩm và rằng cảm giác tiện ích trong tình trạng hiện tại của nó cÅ©ng phản ánh má»™t cách đúng đắn chất lượng công việc của há». Nếu bạn tin rằng má»™t tiện ích nào đó tốt, tác giả của nó tuân thủ giấy tá» và tinh thần của chính sách trên AMO, và nó làm lợi cho Firefox, ngÆ°á»i dùng của chúng tôi, bạn có thể thoải mái Ä‘á»™ng viên tác giả của tiện ích đó tá»± Ä‘á» cá»­ sáng tạo của há».</p>
+
+<h2>Tiện ích của tôi nằm trong danh sách chỠđỠcử quá lâu rồi, có phải các bạn ghét tôi?</h2>
+
+<p>Chúng tôi không ghét bạn. Chúng tôi yêu quý những nhà phát triển tiện ích, và chúng tôi làm việc hết mình để làm há» vui và hoạt Ä‘á»™ng năng suất hÆ¡n, để ngÆ°á»i dùng khắp thế giá»›i có thể được lợi từ công việc của há». NhÆ°ng nằm ở khu vá»±c công cá»™ng của AMO là có giá trị chính xác vì chúng tôi cẩn thận vá»›i những gì nằm ở đó, cho nên chúng tôi không thể vá»™i chỉ vì muốn nó Ä‘i nhanh hÆ¡n. Chúng tôi hiểu rằng có thể sẽ gây ra bá»±c bá»™i khi chỠđợi tiện ích của bạn được xem xét, và chúng tôi muốn thá»i gian xoay vòng càng ngắn càng tốt. Càng nhiá»u ngÆ°á»i cung cấp các đánh giá rõ ràng và kÄ© càng vá» các tiện ích trong há»™p cát, càng dá»… thá»±c hiện những xem xét này, cho nên có thể bạn cÅ©ng muốn giúp má»™t tay vá» mặt đó nếu bạn sẵn lòng.</p>
+
+<h2>Tôi tìm thấy má»™t lá»—i nghiêm trá»ng trong tiện ích của tôi, và tôi thật sá»± muốn Ä‘Æ°a bản sá»­a lá»—i lên ngay. Tôi nên làm gì?</h2>
+
+<p>Nếu có má»™t lá»—i nghiêm trá»ng (vấn Ä‘á» vá» bảo mật, tính ổn định, chức năng quan trá»ng) trong má»™t tiện ích mà bạn cần cập nhật nhanh chóng, bạn nên chỉ ra Ä‘iá»u đó trong "ghi chú cho ngÆ°á»i đánh giá" khi gá»­i lên bản cập nhật -- cÅ©ng nhÆ° trong ghi chú của phiên bản, tất nhiên rồi! Bạn cÅ©ng có thể muốn lên danh sách má»™t số ngÆ°á»i dùng tiện ích của bạn hiện tại để kiểm tra bản cập nhật và báo cáo kết quả chi tiết của há» trong há»™p cát. Nhảy vào #addons trên irc.mozilla.org có thể giúp má»i ngÆ°á»i nhận ra tình huống, nhÆ°ng vui lòng kiên nhẫn và lịch sá»± khi bạn làm vậy.</p>
+
+<p>Vui lòng đừng gầm gừ. Chúng tôi cố gắng nhảy nhanh tá»›i các bản cập nhật có mức Æ°u tiên cao, nhÆ°ng nó làm chúng tôi mất thá»i gian xem xét các tiện ích hoặc phiên bản được Ä‘á» cá»­ khác, và thÆ°á»ng lấy Ä‘i của chúng tôi giấc ngủ và thá»i gian vá»›i gia đình và bạn bè, cho nên chúng tôi có cái nhìn không tốt đẹp vá»›i những ngÆ°á»i cố lợi dụng hệ thống để "nhảy danh sách". Nếu bạn không chắc liệu bạn có nên Ä‘i theo lá»™ trình này hay không, há»i tại #addons trên irc.mozilla.org có thể giúp bạn quyết định.
+
+<h2>Tôi nghĩ mình bị đối xử không công bằng trong việc xem xét tiện ích của tôi. Tôi nên làm gì?</h2>
+
+<p>Nếu bạn tin rằng tiện ích của mình bị đánh giá không chính xác, và có lỗi khi nó bị từ chối đưa ra trạng thái công cộng, bạn nên gửi một email tới amo-editors@mozilla.org với chi tiết lí do của bạn. Vui lòng tỠra lịch sự và rõ ràng trong email, và hãy chắc chắn rằng bạn có thông tin cụ thể vỠviệc tiện ích của bạn bị đánh giá sai như thế nào.</p>
+
+<p>(Nếu bạn đã sửa *tất cả* những phần được liệt kê là lỗi trong thư thông báo, bạn không nên kháng lại việc đánh giá, mà thay vào đó hãy đỠcử lại thông qua Công cụ Nhà phát triển.)</p>
+
+<h2>Tiện ích của tôi từng được đưa ra công cộng, nhưng bây giỠnó chỉ nằm trong hộp cát. Chuyện gì đã xảy ra? </h2>
+
+<p>Nếu má»™t tiện ích không còn phù hợp vá»›i tiêu chí cho việc nằm ở khu vá»±c công cá»™ng của trang, chúng tôi sẽ chuyển nó vào lại há»™p cát. Trừ khi chúng tôi bị luật cấm làm vậy, chúng tôi sẽ thông báo cho bạn qua email khi Ä‘iá»u đó xảy ra, nói rõ lí do làm vậy.</p>
+
+<p>CÅ©ng có thể bạn tìm thấy má»™t lá»—i trên trang, trong trÆ°á»ng hợp nào bạn cÅ©ng nên báo cáo thông qua Bugzilla; chá»n sản phẩm "addons.mozilla.org" và thành phần "Trang Công Cá»™ng" trong báo cáo của bạn, kèm theo má»i chi tiết mà bạn biết.</p>
+
+<h2>Tiện ích của tôi Ä‘ang ở phần công cá»™ng, và má»i ngÆ°á»i có vẻ yêu thích nó. Làm sao để tôi có thể vào danh sách tiện ích được khuyên dùng?</h2>
+
+<p>Nếu bạn tin rằng tiện ích của bạn là má»™t ví dụ sáng chói cho sức mạnh của tiện ích, rằng nó biểu dÆ°Æ¡ng và đẩy mạnh các giá trị của Mozilla cho má»™t thế giá»›i web được Ä‘iá»u khiển bởi ngÆ°á»i sá»­ dụng và có khả năng mở rá»™ng, rằng nó cung cấp má»™t trải nghiệm ngÆ°á»i dùng tuyệt vá»i, bạn có thể Ä‘á» nghị được xem xét Ä‘Æ°a vào danh sách những tiện ích được khuyên dùng. Äể làm Ä‘iá»u này, bạn nên gá»­i má»™t email tá»›i amo-editors@mozilla.org giải thích vì sao tiện ích của bạn là tuyệt vá»i.</p>
+
+<p>ThÆ° của bạn nên kèm theo <b>tối thiểu</b> là thông tin vá» những Ä‘iá»u sau:</p>
+<ul>
+<li>trải nghiệm web được cải tiến cho ngÆ°á»i dùng nhÆ° thế nào</li>
+<li>tiện ích của bạn phù hợp vá»›i má»™t lượng lá»›n ngÆ°á»i dùng Firefox nhÆ° thế nào</li>
+<li>tiện ích của bạn biểu dÆ°Æ¡ng và/hoặc phục vụ các giá trị của dá»± án Mozilla nhÆ° thế nào, đặc biệt cùng vá»›i việc đặt ngÆ°á»i dùng trong vị trí thÆ°á»ng trá»±c, việc bảo vệ quyá»n riêng tÆ° và bảo mật, truy nhập toàn cầu vào web, và các dữ liệu và chuẩn mở</li>
+<li>tiện ích của bạn khác các tiện ích tương tự như thế nào (cả mặt tốt hơn và mặt kém hơn)</li>
+<li>những phản hồi mà bạn thấy từ ngÆ°á»i dùng, ngÆ°á»i đánh giá, ngÆ°á»i viết blog, phi hành gia, hoặc thú cÆ°ng trong nhà bạn, cả tích cá»±c lẫn tiêu cá»±c</li>
+</ul>
+
+<p>Thông tin mà bạn cung cấp trong yêu cầu càng đầy đủ, chúng tôi càng dá»… dàng công nhận nó, mặc dù thậm chí má»™t ứng dụng toàn diện và được viết chu đáo không thể bảo đảm cho sá»± có mặt trong danh sách được khuyên dùng. Cuối cùng, danh sách phải được -- và Ä‘ang được -- duy trì theo ý muốn của Mozilla, và trải nghiệm ngÆ°á»i dùng cÅ©ng nhÆ° sá»± bảo vệ phải bao trùm má»i thứ khác.</p>
diff --git a/site/app/locale/vi/pages/reviewguide.thtml b/site/app/locale/vi/pages/reviewguide.thtml
new file mode 100644
index 0000000..f0dc1e0
--- /dev/null
+++ b/site/app/locale/vi/pages/reviewguide.thtml
@@ -0,0 +1,90 @@
+<h1>HÆ°á»›ng dẫn Äánh giá</h1>
+<p>Äánh giá Tiện ích là má»™t cách để ngÆ°á»i dùng trên trang tiện ích chia sẻ ý kiến của há» vá»
+tiện ích hỠđã cài đặt và sá»­ dụng. Biên tập viên có quyá»n
+từ chối hoặc xóa bất kì đánh giá nào không tuân theo những hướng dẫn này.</p>
+
+<div class="corner-box">
+ <h2>Má»™t vài mẹo để viết má»™t bài đánh giá tuyệt vá»i</h2>
+
+<h3><b>Nên:</b></h3>
+<ul>
+<li>Viết nhÆ° thể bạn Ä‘ang kể cho má»™t ngÆ°á»i bạn vá» trải nghiệm của bạn đối vá»›i tiện ích.</li>
+<li>Giữ cho bài đánh giá được ngắn gá»n và dá»… hiểu.</li>
+<li>ÄÆ°a ra những chi tiết hữu ích và cụ thể. Ví dụ:
+<ul>
+ <li>Tiện ích có hoạt động như bạn mong đợi không?</li>
+ <li>Những tính năng nào bạn thích hoặc không thích?</li>
+ <li>Nó có ích không?</li>
+ <li>Nó có dễ sử dụng không?</li>
+ <li>Bạn có tiếp tục sử dụng tiện ích này không?</li>
+</ul></li>
+
+<li>Bá» ra má»™t chút thá»i gian Ä‘á»c lại bài đánh giá trÆ°á»›c khi gá»­i nó lên để tránh các lá»—i ngữ pháp hoặc chính tả đáng xấu hổ.</li>
+
+<li>Tránh Ä‘á» cập các mục tham khảo tạm thá»i hoặc diá»…n ra tùy theo thá»i gian vì các bài đánh giá có thể vẫn nằm ở trên trang trong má»™t thá»i gian dài.</li>
+</ul>
+
+<h3><b>Không nên:</b></h3>
+<ul>
+<li>Gá»­i lên các bài đánh giá Ä‘Æ¡n giản nhÆ° "Quá hay!", "tuyệt vá»i", hay "dở tệ" mà không giải thích gì thêm.</li>
+<li>Gá»­i lên báo cáo lá»—i trong bài đánh giá. Hãy sá»­ dụng các tùy chá»n trợ giúp hiện có của má»—i tiện ích.</li>
+<li>Viết đánh giá cho các tiện ích mà bạn chưa từng sử dụng.</li>
+<li>Dùng từ ngữ tục tĩu, dâm ô hoặc những từ ngữ có thể bị hiểu là mang tính hận thù.</li>
+<li>Bao gồm HTML, liên kết đến phần má»m Ä‘á»™c hại, mã nguồn hoặc trích dẫn mã nguồn. Bài đánh giá chỉ nên là văn bản thuần túy.</li>
+<li>ÄÆ°a ra chỉ trích sai, chê bai tác giả tiện ích hoặc xúc phạm cá nhân há».</li>
+<li>Sử dụng đánh giá như một cách để yêu cầu hỗ trợ cho một phiên bản Firefox (hoặc chương trình khác) nào đó.</li>
+<li>Bao gồm email, số điện thoại của bạn, hoặc bất kì chi tiết cá nhân nào khác.</li>
+<li>Gửi đánh giá cho một tiện ích mà bạn hoặc tổ chức của bạn viết ra hoặc đại diện.</li>
+</ul>
+</div>
+
+<div class="corner-box">
+ <h2>Hướng dẫn xếp hạng tiện ích</h2>
+
+<p>Việc xếp hạng tiện ích phải công bằng và Ä‘Æ°a ra má»™t chỉ báo rõ ràng vá» chất lượng má»i mặt
+và tính hữu ích. Äừng chỉ cho nó 5 sao nếu bạn thích hoặc chỉ 1 sao nếu bạn
+ghét. Sá»± lá»±a chá»n ổn định là má»™t phần quan trá»ng của má»i bài đánh giá.</p>
+
+<ul>
+<li><b>5 sao: Xuất sắc.</b> Không chỉ làm má»i thứ mà nó tuyên bố, mà nó còn
+hữu dụng hÆ¡n rất nhiá»u các tiện ích khác. Tiện ích này có vẻ là
+cái mà bạn sá»­ dụng thÆ°á»ng xuyên và bạn đặc biệt khuyên dùng nó.</li>
+<li><b>4 sao: Tốt.</b> Hữu ích và dễ dùng, mặc dù không quá đặc biệt. Tiện ích
+này được khuyên dùng nhÆ°ng có thể phù hợp vá»›i má»™t số ngÆ°á»i này hÆ¡n má»™t số ngÆ°á»i khác.</li>
+<li><b>3 sao: Tạm được.</b> Có thể có vài vấn đỠtrong thiết kế và/hoặc vài tính năng bị thiếu.
+Bất kì vấn đỠnào nó có cũng không đủ lớn đến mức phải từ bỠviệc sử dụng, và một số
+ngÆ°á»i có thể vẫn thấy nó hữu ích. Khuyên dùng cho những ai cần nó và Ä‘ang
+sẵn lòng cho nó một cơ hội.</li>
+<li><b>2 sao: Kém.</b> Tiện ích có chất lượng thấp, khả năng sử dụng kém, hoặc không làm được những gì
+nó nói. Bạn khuyên chống lại việc sử dụng tiện ích, trong khi vẫn lưu ý rằng
+nó có thể có giá trị đối vá»›i má»™t vài ngÆ°á»i.</li>
+<li><b>1 sao: Dở tệ.</b> Tiện ích không hoạt động đúng hoặc hoàn toàn vô dụng. Bạn
+không thể nghĩ ra lí do để ai đó còn muốn cho nó một cơ hội và
+khuyên rằng cần phải tránh nó hoàn toàn.</li>
+</ul>
+
+<p>Không có gì sai với việc đánh giá một tiện ích là hoàn hảo hay tệ hại, chỉ cần
+vui lòng cho biết vì sao bạn làm vậy. Những dấu sao chẳng có ý nghĩa gì nếu như bạn không nói
+cho chúng tôi biết lí do.</p>
+</div>
+
+<div class="corner-box">
+ <h2>Câu há»i ThÆ°á»ng gặp vá» Äánh giá</h2>
+
+<h3>Làm sao tôi có thể báo cáo một bài đánh giá có vấn đ�</h3>
+<p>Vui lòng báo cáo hoặc gán cỠhiệu bất kì đánh giá nghi vấn nào bằng cách nhấn lên "Báo cáo
+bài đánh giá này" và nó sẽ được gửi lên trang để xem xét. Biên tập viên sẽ dùng
+HÆ°á»›ng dẫn Äánh giá để xác định có nên xóa bài đánh giá
+hay là khôi phục nó trở lại.</p>
+
+<h3>Tôi là một tác giả của tiện ích, tôi có thể phản hồi các đánh giá không?</h3>
+<p>Có, các tác giả tiện ích có thể cung cấp một phản hồi đơn lẻ cho một bài đánh giá. Thảo luận
+thêm hoặc các trao đổi liên tiếp nên chuyển qua một diễn đàn hỗ trợ hoặc nhóm thảo luận.</p>
+
+<h3>Tôi là một tác giả của tiện ích, tôi có thể xóa các xếp hạng hoặc đánh giá bất lợi không?</h3>
+<p>Nói chung là, không. Nhưng nếu bài đánh giá không phù hợp với hướng dẫn đánh giá được đưa ra
+ở trên, bạn có thể nhấn "Báo cáo bài đánh giá này" và để nó cho một biên tập viên xem xét.
+Nếu má»™t bài đánh giá bao gồm lá»i phàn nàn vốn không còn hiệu lá»±c vì đã có bản phát hành má»›i
+của bạn, chúng tôi có thể cân nhắc việc xóa bài đánh giá đó. Gửi lên yêu cầu
+chi tiết tới amo-editors@mozilla.org.</p>
+</div>
diff --git a/site/app/locale/vi/pages/sandbox.thtml b/site/app/locale/vi/pages/sandbox.thtml
new file mode 100644
index 0000000..bedec64
--- /dev/null
+++ b/site/app/locale/vi/pages/sandbox.thtml
@@ -0,0 +1,13 @@
+<h1>Hệ thống Äánh giá Há»™p cát</h1>
+<h2>Hộp cát là gì?</h2>
+<p>Há»™p cát là má»™t khu cho ngÆ°á»i dùng cấp cao kiểm tra các tiện ích trÆ°á»›c khi chúng được đánh giá cho việc sá»­ dụng thông thÆ°á»ng. Äể truy cập há»™p cát, bạn phải kích hoạt nó trong thiết lập tài khoản của bạn. Cần phải cẩn trá»ng khi cài đặt các tiện ích trong há»™p cát, vì chúng chÆ°a được kiểm tra bởi biên tập viên và có thể làm hại máy tính của bạn.</p>
+
+<h2>Làm cách nào để tiện ích của tôi được đưa ra khu vực công cộng?</h2>
+<!-- Äể bản địa hóa sÆ¡ đồ sau, hãy xem http://wiki.mozilla.org/Update:Remora_Sandbox_Flowchart -->
+<div style="text-align: center;">%s</div>
+<ol>
+ <li><b>Gá»­i lên tiện ích của bạn trong Công cụ Nhà phát triển.</b> Tiện ích của bạn sẽ lập tức xuất hiện trong khu vá»±c "Há»™p cát" của Tiện Ãch Mozilla, nÆ¡i những ngÆ°á»i dùng có kinh nghiệm sẽ kiểm tra và phản hồi vá» nó. Äể nhìn thấy há»™p cát, bạn sẽ phải bật nó trong thiết lập tài khoản.</li>
+ <li><b>Äá» cá»­ tiện ích của bạn ra công cá»™ng.</b> Trong Công-cụ Nhà phát triển, có má»™t liên kết để Ä‘á» cá»­ tiện ích của bạn. Sau khi được Ä‘á» cá»­, tiện ích của bạn sẽ xuất hiện trong Danh sách Äá» cá»­ của Biên tập viên để chỠđược đánh giá.</li>
+ <li><b>Má»™t biên tập viên đánh giá tiện ích của bạn.</b> Má»™t biên tập viên Tiện Ãch Mozilla sẽ cài đặt tiện ích của bạn và kiểm tra xem nó có hoạt Ä‘á»™ng không. Biên tập viên này cÅ©ng sẽ xem các bài đánh giá của những ngÆ°á»i dùng thá»­ nghiệm há»™p cát.</li>
+ <li><b>Tiện ích của bạn được đưa ra công cộng hoặc vẫn ở trong hộp cát.</b> Biên tập viên sẽ đưa tiện ích của bạn ra công cộng hoặc giữ nó lại trong hộp cát. Nếu vẫn bị giữ lại trong hộp cát, bạn có thể đỠcử nó lại sau khi sửa đổi theo đỠxuất của biên tập viên. Nếu được đưa ra công cộng, các phiên bản tương lai của tiện ích vẫn sẽ xuất hiện trong hộp cát cho đến khi chúng được đánh giá bởi một biên tập viên và đưa ra công cộng tiếp. Một khi tiện ích của bạn được đưa ra công cộng, không còn cần phải đỠcử nó nữa - các phiên bản trong tương lai sẽ tự động được chuyển vào danh sách chỠđánh giá.</li>
+</ol>
diff --git a/site/app/locale/vi/pages/statistics_help.thtml b/site/app/locale/vi/pages/statistics_help.thtml
new file mode 100644
index 0000000..a8961ad
--- /dev/null
+++ b/site/app/locale/vi/pages/statistics_help.thtml
@@ -0,0 +1,7 @@
+<h3>Trợ giúp</h3>
+<p>Bảng Thống Kê hiển thị dữ liệu ping cập nhật và tải xuống cho tiện ích của bạn.</p>
+<h4>Tải xuống</h4>
+<p>Số lần tải được cập nhật mỗi ngày và chỉ tính việc tải tiện ích gốc, không tính việc tải bản cập nhật.</p>
+
+<h4>Ping cập nhật</h4>
+<p>Các tiện ích được tải sẽ kiểm tra cập nhật má»™t lần má»—i ngày, và tổng số các ping cập nhật này được gá»i là NgÆ°á»i dùng Hoạt Ä‘á»™ng Má»—i ngày. NgÆ°á»i dùng Hoạt Ä‘á»™ng Má»—i ngày (Active Daily Users - ADU) có thể được xem theo phiên bản tiện ích, hệ Ä‘iá»u hành, trạng thái tiện ích, và chÆ°Æ¡ng trình.</p> \ No newline at end of file
diff --git a/site/app/locale/vi/pages/submission_help.thtml b/site/app/locale/vi/pages/submission_help.thtml
new file mode 100644
index 0000000..c7829a6
--- /dev/null
+++ b/site/app/locale/vi/pages/submission_help.thtml
@@ -0,0 +1,35 @@
+<h1>Trợ giúp Gửi lên</h1>
+Các phần bắt buá»™c được <b>in đậm</b>. Các phần tùy chá»n được <i>in nghiêng</i>.
+<h2 id="step1">Bước 1: Tải lên</h2>
+<ul class="submissionHelp">
+ <li><span class="required">Kiểu của Tiện ích</span> - Mặc định, kiểu tiện ích sẽ tự động được xác định dựa trên tập tin được tải lên. Bạn không phải thay đổi phần này.</li>
+ <li><span class="required">Tập tin Tiện ích</span> - Tập tin đóng gói cho tiện ích của bạn, hoàn tất vá»›i má»™t tập tin install.rdf. Nếu tập tin hoạt Ä‘á»™ng vá»›i má»™t ná»n tảng nào đó, chá»n ná»n tảng đó sẽ cho phép nhiá»u tập tin được tải lên cùng lúc.</li>
+ <li><span class="optional">Tập tin Biểu tượng</span> - Tập tin biểu tượng được hiển thị bên cạnh tên tiện ích trên trang giá»›i thiệu và nó hiển thị trong há»™p thoại cài đặt tiện ích. Nó sẽ tá»± Ä‘á»™ng được Ä‘iá»u chỉnh sang kích thÆ°á»›c 32x32 pixel, vẫn giữ nguyên tỉ lệ các cạnh.</li>
+ <li><span class="required">Bản địa Mặc định</span> - Bản địa mặc định của má»™t tiện ích là bản địa chính của nó. Nếu không có bản địa được chá»n, phần chuyển ngữ sẽ tá»± Ä‘á»™ng dùng bản địa mặc định.</li>
+ <li><span class="optional">Bá» qua việc kiểm tra thông tin tiện ích hiện tại của tôi</span> - Nếu bạn cập nhật má»™t tiện ích Ä‘ang có sẵn, phần này sẽ xuất hiện. Äánh dấu há»™p chá»n sẽ bá» qua và Ä‘i thẳng tá»›i bÆ°á»›c 3 nÆ¡i bạn có thể nhập thông tin riêng cho phiên bản.</li>
+</ul>
+
+<h2 id="step2">Bước 2: Chi tiết Tiện ích</h2>
+<ul class="submissionHelp">
+ <li><span class="required">Tên</span> - Tên của tiện ích trong bản địa mặc định.</li>
+ <li><span class="required">Tác giả</span> - Tất cả ngÆ°á»i dùng có quyá»n truy nhập chỉnh sá»­a danh mục của tiện ích sẽ được liệt kê là tác giả trên trang giá»›i thiệu.</li>
+ <li><span class="required">Phân mục</span> - Phân mục cho tiện ích.</li>
+ <li><span class="optional">Trang chủ</span> - Trang web của tiện ích trong bản địa mặc định.</li>
+ <li><span class="required">Tóm tắt</span> - Má»™t bản tóm tắt ngắn gá»n vá» tiện ích trong bản địa mặc định. Phần này có tối Ä‘a 250 kí tá»±, và sẽ xuất hiện trên trang giá»›i thiệu tiện ích, cÅ©ng nhÆ° trong kết quả tìm kiếm / duyệt xem.</li>
+ <li><span class="required">Mô tả</span> - Một bản mô tả tiện ích trong bản địa mặc định. Phần này sẽ xuất hiện trên trang giới thiệu tiện ích ngay dưới phần tóm tắt.</li>
+ <li><span class="optional">EULA</span> - Thá»a thuận Giấy phép NgÆ°á»i dùng Cuối tức là ngÆ°á»i dùng sẽ được yêu cầu cần phải chấp thuận trÆ°á»›c khi tải xuống, trong bản địa mặc định.</li>
+ <li><span class="optional">Chính sách Riêng tÆ°</span> - Chính sách Riêng tÆ° của tiện ích, trong bản địa mặc định. Chính sách Riêng tÆ° giải thích những gì sẽ xảy ra đối vá»›i thông tin cá nhân của ngÆ°á»i dùng cuối, và nó sẽ được đặt kế bên nút cài đặt trên trang giá»›i thiệu tiện ích. Thông tin thêm vá» những gì cần nói trong Chính sách Riêng tÆ° và liệu tiện ích của bạn có cần đến thông tin đó hay không, có trong <a href="%s">Chính sách Tiện ích</a>.</li>
+ <li><span class="optional">Cho phép ngÆ°á»i dùng xem tập tin nguồn trá»±c tuyến</span> - Äánh dấu há»™p này sẽ cho phép ngÆ°á»i dùng duyệt xem trá»±c tuyến tập tin nguồn của tiện ích.</li>
+ <li><span class="optional">Äây là phát hành thá»­</span> - Äánh dấu há»™p này sẽ cho biết tiện ích này là phiên bản "beta" hoặc phát hành thá»­. Các tiện ích phát hành thá»­ phải ở trong há»™p cát và không thể được Ä‘á» cá»­ cho đến khi cá» hiệu này được bá».</li>
+ <li><span class="optional">Äây là má»™t tiện ích riêng biệt cho trang web</span> - Äánh dấu há»™p này sẽ cho biết tiện ích này chỉ dành riêng cho má»™t trang web, ví dụ nhÆ° tiện ích thay đổi giao diện má»™t trang web nào đó hoặc hiển thị ná»™i dung từ má»™t trang web nào đó. Phần này có ích cho các biên tập viên và có thể được dùng để lá»c các tìm kiếm trong tÆ°Æ¡ng lai.</li>
+ <li><span class="optional">Tiện ích này yêu cầu phần má»m bên ngoài</span> - Äánh dấu há»™p này sẽ cho biết tiện ích yêu cầu phần má»m bên ngoài.Phần này có ích cho các biên tập viên và có thể được dùng để lá»c các tìm kiếm trong tÆ°Æ¡ng lai.</li>
+</ul>
+
+<h2 id="step3">Bước 3: Chi tiết Phiên bản</h2>
+<ul class="submissionHelp">
+ <li><span class="required optional">Ghi chú Phiên bản</span> - Má»™t bản tóm tắt hoặc danh sách các thay đổi trong phiên bản này. Phần này là tùy chá»n cho các tiện ích má»›i, nhÆ°ng là bắt buá»™c đối vá»›i các bản cập nhật.</li>
+ <li><span class="optional">Ghi chú cho NgÆ°á»i đánh giá</span> - Phần này được dùng trong việc liên lạc thông tin vá»›i biên tập viên đánh giá tiện ích của bạn. Thông tin tài khoản thá»­ nghiệm và ghi chú đặc biệt nên để ở đây.</li>
+</ul>
+
+<h2 id="step4">Bước 4: Bản địa hóa</h2>
+Äây là nÆ¡i các phần thông tin của tiện ích có thể được bản địa hóa sang các bản địa được há»— trợ. Chỉ cần nhấn lên má»™t tên bản địa để nhập bản dịch. \ No newline at end of file
diff --git a/site/app/locale/zh_CN/LC_MESSAGES/messages.mo b/site/app/locale/zh_CN/LC_MESSAGES/messages.mo
new file mode 100644
index 0000000..b0d6f08
--- /dev/null
+++ b/site/app/locale/zh_CN/LC_MESSAGES/messages.mo
Binary files differ
diff --git a/site/app/locale/zh_CN/LC_MESSAGES/messages.po b/site/app/locale/zh_CN/LC_MESSAGES/messages.po
new file mode 100644
index 0000000..0522e6d
--- /dev/null
+++ b/site/app/locale/zh_CN/LC_MESSAGES/messages.po
@@ -0,0 +1,8584 @@
+# Remora Preliminary Language File
+# Copyright (C) 2006 Mozilla Corporation
+# This file is distributed under the same license as the REMORA package.
+# Wil Clouser <clouserw@mozilla.com>, 2006.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: REMORA 0.1\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2009-01-16 11:45-0800\n"
+"PO-Revision-Date: 2008-03-16 20:57+0800\n"
+"Last-Translator: 金箭 <steekid@gmail.com>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=n != 1;\n"
+
+#: views/addons/policy.thtml:98
+msgid "a_cancel_installation"
+msgstr "放弃安装"
+
+#. This is the text that appears on buttons to download add-ons.
+#. %$1s is an optional string that only appears if the add-on is only available for
+#. a certain platform. Examples: (Windows) or (Linux)
+#. Note that the parentheses are included in the string. :(
+#: views/elements/amo2009/install.thtml:126
+#: views/elements/amo2009/install.thtml:227
+#: views/elements/amo2009/install.thtml:257
+#: views/elements/amo2009/install.thtml:300
+#: views/elements/amo2009/install.thtml:312 views/elements/install.thtml:73
+#: views/elements/install.thtml:181 views/elements/install.thtml:205
+#: views/elements/install.thtml:248 views/elements/install.thtml:260
+#: views/addons/plugins.thtml:66 views/addons/plugins.thtml:76
+#: views/addons/plugins.thtml:86 views/addons/plugins.thtml:96
+#: views/addons/plugins.thtml:119
+#, php-format
+msgid "a_download"
+msgstr "现在下载 %s"
+
+#: views/addons/policy.thtml:72
+msgid "a_eula_download"
+msgstr "åŒæ„并下载"
+
+#: views/addons/policy.thtml:74
+msgid "a_eula_install"
+msgstr "åŒæ„并安装"
+
+#: views/elements/header.thtml:76 views/elements/header.thtml:82
+#: views/api/api_addon.thtml:55 views/api/collections_feed.thtml:75
+#: views/sharing_api/addon.thtml:64
+msgid "a_header_public"
+msgstr "公开"
+
+#: views/elements/header.thtml:58 views/elements/header.thtml:75
+#: views/elements/header.thtml:80 views/api/api_addon.thtml:57
+#: views/api/collections_feed.thtml:77 views/sharing_api/addon.thtml:66
+msgid "a_header_sandbox"
+msgstr "沙盒"
+
+#. %s is a date in the _('date') format
+#: views/elements/amo2009/homepage_addon.thtml:115
+#: views/elements/addon_listitem.thtml:122 views/elements/feature.thtml:106
+#: views/addons/display.thtml:104 views/addons/browse_thumbs.thtml:73
+msgid "addon_detail_last_updated"
+msgstr "已更新 %s"
+
+#. %s is the version of the add-on. Example: 3.2a1
+#: views/elements/amo2009/addon_version_detail.thtml:51
+#: views/elements/addon_version_detail.thtml:51
+#, php-format
+msgid "addon_display_header_version"
+msgstr "版本 %s"
+
+#: views/addons/browse_thumbs.thtml:80
+msgid "addon_downloads"
+msgstr "次下载"
+
+#: views/addons/display.thtml:147
+msgid "addon_downloads_total"
+msgstr "总下载é‡"
+
+#: views/elements/amo2009/homepage_addon.thtml:106
+#: views/elements/addon_listitem.thtml:115 views/elements/feature.thtml:101
+#: views/addons/category_landing.thtml:157 views/addons/display.thtml:146
+#: views/addons/browse_thumbs.thtml:80
+msgid "addon_downloads_weekly"
+msgstr "周下载é‡"
+
+# %1 is the add-on count, %2 the category name
+#. %1 is the add-on count, %2 the category name
+#: views/addons/browse_thumbs.thtml:104 views/addons/browse.thtml:60
+#, php-format
+msgid "addon_list_category_totalcount"
+msgid_plural "addon_list_category_totalcount"
+msgstr[0] "%1$s \"%2$s\" 个附加组件"
+msgstr[1] "%1$s \"%2$s\" 个附加组件"
+
+#: views/elements/amo2009/addon_list_options.thtml:103
+#: views/elements/pagination.thtml:67
+#: views/elements/addon_list_options.thtml:94
+msgid "addon_list_perpage"
+msgstr "个结果æ¯é¡µ"
+
+#: views/elements/amo2009/addon_list_options.thtml:84
+#: views/elements/addon_list_options.thtml:98
+msgid "addon_list_sortby"
+msgstr "排åºä¾æ®:"
+
+#: views/helpers/addons_html.php:568 views/elements/amo2009/install.thtml:321
+#: views/elements/feature.thtml:89
+msgid "addon_listitem_flag_experimental"
+msgstr "试验性的"
+
+#: views/helpers/addons_html.php:570
+msgid "addon_listitem_flag_recommended"
+msgstr "推èçš„"
+
+# %1 is the addon name, %2 is the platform
+#. %1 is the add-on name, %2 is the platform
+#: views/pages/js_constants.js.thtml:66
+msgid "addon_not_available_for_platform"
+msgstr "%1$s 无法在 %2$s 上使用。"
+
+# %1 is the addon name
+#. %1 is the add-on name
+#: views/addons/policy.thtml:101 views/addons/previews.thtml:60
+#: views/addons/versions.thtml:130 views/reviews/flag.thtml:61
+#: views/reviews/add.thtml:114 views/reviews/display.thtml:216
+#: views/reviews/review_added.thtml:57
+#, php-format
+msgid "addon_review_a_back_to_addon_x"
+msgstr "返回 %1$s..."
+
+# %1 is the addon name
+#. %1 is the add-on name
+#: views/reviews/flag.thtml:60 views/reviews/add.thtml:113
+#: views/reviews/review_added.thtml:56
+#, php-format
+msgid "addon_review_a_back_to_reviews"
+msgstr "返回æ„è§åˆ—表..."
+
+#: views/reviews/add.thtml:85
+msgid "addon_review_add_rating_field"
+msgstr "评分:"
+
+#: views/reviews/add.thtml:102
+msgid "addon_review_add_review_field"
+msgstr "æ„è§:"
+
+#: views/reviews/add.thtml:107
+msgid "addon_review_add_submit"
+msgstr "æ交你的æ„è§"
+
+#. %s is the name of the add-on
+#: views/reviews/add.thtml:51
+#, php-format
+msgid "addon_review_add_title"
+msgstr "æ交对 %s çš„æ„è§"
+
+#: views/reviews/add.thtml:78
+msgid "addon_review_add_title_field"
+msgstr "标题/摘è¦:"
+
+#: views/reviews/display.thtml:77 views/reviews/display.thtml:161
+msgid "addon_review_admin_delete"
+msgstr "删除"
+
+#: views/reviews/display.thtml:76
+msgid "addon_review_author_reply_link"
+msgstr "回å¤"
+
+#: views/reviews/delete.thtml:62
+msgid "addon_review_confirm_delete"
+msgstr "你确定è¦åˆ é™¤è¯¥æ„è§ï¼Ÿ"
+
+#: views/reviews/delete.thtml:63
+msgid "addon_review_confirm_no"
+msgstr "å¦"
+
+#: views/reviews/delete.thtml:64
+msgid "addon_review_confirm_yes"
+msgstr "是"
+
+#: views/reviews/delete.thtml:48
+msgid "addon_review_delete_header"
+msgstr "删除æ„è§"
+
+#: controllers/reviews_controller.php:449
+msgid "addon_review_deleted_successfully"
+msgstr "æ„è§æˆåŠŸåˆ é™¤ã€‚"
+
+#. %s is the name of the add-on
+#: views/reviews/add.thtml:51
+#, php-format
+msgid "addon_review_edit_title"
+msgstr "编辑对 %s çš„æ„è§"
+
+# %1 is the count of characters entered as notes for the review flag reason.
+#. %1 is the count of characters entered as notes for the review flag reason.
+#: controllers/reviews_controller.php:539
+msgid "addon_review_flag_error_other_length"
+msgstr ""
+"标记æ„è§æœ‰é—®é¢˜: 标记æ„è§å†…容应该在10至100个字符之间;你输入了 %1$s 个字符。"
+
+#. Removing an extra comma
+#: views/reviews/review_added.thtml:53
+msgid "addon_review_in_moderation"
+msgstr "请注æ„:你的æ„è§è¦ç»è¿‡ç¼–辑审核以åŽæ‰èƒ½æ˜¾ç¤ºåœ¨å…¬å¼€ç½‘站上。"
+
+#: views/reviews/add.thtml:57
+msgid "addon_review_in_reply_to"
+msgstr "å¼€å‘者回å¤:"
+
+# %1 is the review count, %2 is the nickname or full name of the user.
+#. %1 is the review count, %2 is the nickname or full name of the user.
+#: views/reviews/display.thtml:131
+#, php-format
+msgid "addon_review_others_by_user"
+msgid_plural "addon_review_others_by_user"
+msgstr[0] "查看 %2$s 以å‰å¯¹è¯¥é™„加组件å‘表的 %1$s æ¡è¯„论."
+msgstr[1] "查看 %2$s 以å‰å¯¹è¯¥é™„加组件å‘表的 %1$s æ¡è¯„论。"
+
+# %1 is the addon name
+#. %1 is the add-on name
+#: controllers/reviews_controller.php:201
+#: controllers/reviews_controller.php:250
+#: controllers/reviews_controller.php:345
+#: controllers/reviews_controller.php:424
+#, php-format
+msgid "addon_review_pagetitle"
+msgstr "对 %s çš„æ„è§"
+
+# %1 is the user, %2 is the (localized) date
+#. %1 is the user, %2 is the (localized) date
+#: views/reviews/display.thtml:160
+#, php-format
+msgid "addon_review_reply_on_x_by_y"
+msgstr "%1$s 于 %2$s 回å¤"
+
+#: views/reviews/display.thtml:157
+msgid "addon_review_reply_prefix"
+msgstr "å¼€å‘者回å¤:"
+
+#: views/reviews/review_added.thtml:51
+msgid "addon_review_saved_successfully"
+msgstr "ä½ çš„æ„è§å·²ç»æˆåŠŸä¿å­˜ã€‚谢谢ï¼"
+
+#: views/addons/display.thtml:354 views/reviews/display.thtml:72
+msgid "addon_reviewed_by_u_on_d"
+msgstr "ç”± %1$s å‘表于 %2$s"
+
+# %1 is the user, %2 is the (localized) date, %3 is the rating
+#. %1 is the user, %2 is the (localized) date, %3 is the rating
+#: views/editors/reviews_queue.thtml:57 views/editors/reviews_queue.thtml:68
+#: views/reviews/add.thtml:63 views/reviews/delete.thtml:54
+#, php-format
+msgid "addon_reviewed_on_x_rated_y"
+msgstr "日期:%2$s(打 %3$s 分)"
+
+#: views/elements/amo2009/addon_version_detail.thtml:52
+#: views/elements/addon_version_detail.thtml:52
+msgid "addon_version_permalink"
+msgstr "该版本的永久链接"
+
+# %1 is the current Application name (e.g. Firefox)
+# %2 is the Application's version number
+#. %1 is the current Application name (e.g. Firefox)
+#. %2 is the Application's version number
+#: views/addons/versions.thtml:140
+#, fuzzy
+msgid "addon_versions_getlatestversion"
+msgstr "The most recent version compatible with %1$s %2$s"
+
+#: views/addons/display.thtml:447
+msgid "addons_author_addons_submit"
+msgstr "æ交"
+
+#: views/elements/amo2009/homepage_addon.thtml:100
+#: views/elements/feature.thtml:95
+msgid "addons_author_tooltip"
+msgstr "查看作者介ç»"
+
+# %1 is the name of the Application (eg. Firefox)
+#. %1 is the name of the Application (eg. Firefox)
+#: controllers/addons_controller.php:1296
+#, fuzzy
+msgid "addons_browse_all_themes_title"
+msgstr "Browse all Themes :: %1$s Add-ons"
+
+#. %s is the name of the category
+#: controllers/addons_controller.php:1016
+#, php-format
+msgid "addons_browse_browse_category"
+msgstr "æµè§ˆ %s"
+
+# %1 is the name of the theme category (eg. Modern)
+# %2 is the name of the Application (eg. Firefox)
+#. %1 is the name of the theme category (eg. Modern)
+#. %2 is the name of the Application (eg. Firefox)
+#: controllers/addons_controller.php:664
+#, fuzzy
+msgid "addons_browse_categories_header_theme"
+msgstr "Browse %1$s Themes :: %2$s Add-ons"
+
+#: views/addons/display.thtml:249
+#, fuzzy
+msgid "addons_display_a_license_what"
+msgstr "What's this?"
+
+#: views/reviews/display.thtml:222
+msgid "addons_display_add_review"
+msgstr "新增æ„è§"
+
+#: views/addons/display.thtml:294
+msgid "addons_display_advanced_details"
+msgstr "更多详情"
+
+#: views/addons/display.thtml:98
+msgid "addons_display_categories"
+msgstr "分类"
+
+#: views/addons/display.thtml:482
+#, fuzzy
+msgid "addons_display_collection_add"
+msgstr "Add to a collection:"
+
+#: views/addons/display.thtml:491
+#, fuzzy
+msgid "addons_display_collection_add_new"
+msgstr "New Collection..."
+
+#: views/addons/display.thtml:487
+#, fuzzy
+msgid "addons_display_collection_add_select_one"
+msgstr "Select a collection..."
+
+#: views/addons/display.thtml:493
+#, fuzzy
+msgid "addons_display_collection_add_submit"
+msgstr "Publish"
+
+#. %1$s is the add-on name
+#. %2$s is the collection name, linked to the collection's page
+#: views/pages/js_constants.js.thtml:103 views/addons/display.thtml:61
+#, fuzzy
+msgid "addons_display_collection_publish_success"
+msgstr "%1$s has been added to the %2$s collection."
+
+#: views/addons/display.thtml:483
+#, fuzzy
+msgid "addons_display_collection_whatsthis"
+msgstr "What's this?"
+
+#. %1$s is a number
+#: views/addons/display.thtml:473
+#, fuzzy
+msgid "addons_display_collections_more"
+msgid_plural "addons_display_collections_more"
+msgstr[0] "and %1$s more collection"
+msgstr[1] "and %1$s more collections"
+
+#: views/addons/display.thtml:403
+msgid "addons_display_detailed_review"
+msgstr "æ„è§è¯¦æƒ…"
+
+#: views/reviews/add.thtml:89 views/reviews/add.thtml:90
+msgid "addons_display_dont_like_it"
+msgstr "ä¸å–œæ¬¢"
+
+#: views/reviews/display.thtml:220
+msgid "addons_display_edit_review"
+msgstr "编辑你的æ„è§"
+
+#: views/addons/display.thtml:132
+msgid "addons_display_has_privacy"
+msgstr "该附加组件有自己的éšç§ç­–略。"
+
+#: views/reviews/add.thtml:87 views/reviews/add.thtml:88
+msgid "addons_display_hate_it"
+msgstr "很ä¸å–œæ¬¢"
+
+#: views/addons/display.thtml:462
+#, fuzzy
+msgid "addons_display_header_collections"
+msgstr "Related Collections"
+
+#: views/addons/display.thtml:297
+msgid "addons_display_header_developer_comments"
+msgstr "å¼€å‘者留言"
+
+#: views/addons/display.thtml:230
+msgid "addons_display_header_homepage"
+msgstr "主页"
+
+#: views/addons/display.thtml:247 views/addons/versions.thtml:110
+#, fuzzy
+msgid "addons_display_header_license"
+msgstr "Source Code License"
+
+#: views/addons/display.thtml:337
+msgid "addons_display_header_reviews"
+msgstr "æ„è§"
+
+#: views/addons/display.thtml:261
+msgid "addons_display_header_support"
+msgstr "技术支æŒ"
+
+#: views/reviews/add.thtml:91 views/reviews/add.thtml:92
+msgid "addons_display_like_it"
+msgstr "喜欢"
+
+#: views/addons/display.thtml:210
+msgid "addons_display_long_description"
+msgstr "详细æè¿°"
+
+#: views/reviews/add.thtml:95 views/reviews/add.thtml:96
+msgid "addons_display_love_it"
+msgstr "太喜欢了"
+
+#: views/addons/display.thtml:178
+msgid "addons_display_more_images"
+msgstr "更多图片"
+
+#: views/addons/display.thtml:465
+#, fuzzy
+msgid "addons_display_nocollections"
+msgstr "This add-on is not yet in any collections."
+
+# %1$s is either an author's name or a comma separated list of authors. Using
+# the list doesn't make sense in the English plural form so we ignore the
+# variable.
+#. %1$s is either an author's name or a comma separated list of authors. Using
+#. the list doesn't make sense in the English plural form so we ignore the
+#. variable.
+#: views/addons/display.thtml:436
+#, fuzzy
+msgid "addons_display_other_addons_by"
+msgid_plural "addons_display_other_addons_by"
+msgstr[0] "%1$s 的其他附加组件"
+msgstr[1] "Other add-ons by these authors"
+
+#. %s is the name of the add-on and the add-on section. Example:
+#. Some Add-on :: Firefox Add-ons
+#. This should not be concatenated in the code and should be fixed.
+#: controllers/addons_controller.php:141 controllers/addons_controller.php:280
+#: controllers/addons_controller.php:1442
+#, php-format
+msgid "addons_display_pagetitle"
+msgstr "%s"
+
+#. %s is an email address
+#: views/addons/display.thtml:286
+#, php-format
+msgid "addons_display_paragraph_supportinfoemail"
+msgstr ""
+"该附加组件由开å‘者在 %s æ供技术支æŒã€‚如果你è¦æ±‡æŠ¥ç¼ºé™·ï¼Œæœ€å¥½çš„æ–¹å¼æ˜¯ç›´æŽ¥å°†æ–‡"
+"件å‘é€ç»™å¼€å‘者,以便他们回å¤ä½ ã€‚评论并ä¸æ˜¯é€‚åˆç”¨äºŽè¯¦ç»†æ±‡æŠ¥ç¼ºé™·ã€‚å¼€å‘者å¯èƒ½éœ€"
+"è¦æ›´å¤šè¯¦æƒ…去é‡çŽ°ç¼ºé™·ã€‚当你å‘é€è¯„论æ„è§çš„时候,扩展的开å‘者ä¸èƒ½çœ‹åˆ°ä½ çš„电å­é‚®"
+"件地å€ï¼Œæ‰€ä»¥ä»–们也就无法è”系你获å–更进一步的信æ¯ï¼Œåœ¨æœªæ¥ç‰ˆæœ¬ä¸­ä¿®å¤ç¼ºé™·çš„时候"
+"也无法通知你。"
+
+#. %$1s is a URL
+#. %$2s is an email address
+#: views/addons/display.thtml:269
+#, php-format
+msgid "addons_display_paragraph_supportinfoemailurl"
+msgstr ""
+"该附加组件由作者在 %s æ供技术支æŒæˆ–者å¯ä»¥å‘é€é‚®ä»¶åˆ° %s 。 如果你è¦æ±‡æŠ¥ç¼ºé™·ï¼Œ"
+"最好的方å¼æ˜¯ç›´æŽ¥å°†æ–‡ä»¶å‘é€ç»™å¼€å‘者,以便他们回å¤ä½ ã€‚评论并ä¸æ˜¯é€‚åˆç”¨äºŽè¯¦ç»†æ±‡"
+"报缺陷。开å‘者å¯èƒ½éœ€è¦æ›´å¤šè¯¦æƒ…去é‡çŽ°ç¼ºé™·ã€‚当你å‘é€è¯„论æ„è§çš„时候,扩展的开å‘"
+"者ä¸èƒ½çœ‹åˆ°ä½ çš„电å­é‚®ä»¶åœ°å€ï¼Œæ‰€ä»¥ä»–们也就无法è”系你获å–更进一步的信æ¯ï¼Œåœ¨æœªæ¥"
+"版本中修å¤ç¼ºé™·çš„时候也无法通知你。"
+
+#. %s is a URL
+#: views/addons/display.thtml:278
+#, php-format
+msgid "addons_display_paragraph_supportinfourl"
+msgstr ""
+"该附加组件由开å‘者在 %s æ供技术支æŒã€‚ 如果你è¦æ±‡æŠ¥ç¼ºé™·ï¼Œæœ€å¥½çš„æ–¹å¼æ˜¯ç›´æŽ¥å°†æ–‡"
+"件å‘é€ç»™å¼€å‘者,以便他们回å¤ä½ ã€‚评论并ä¸æ˜¯é€‚åˆç”¨äºŽè¯¦ç»†æ±‡æŠ¥ç¼ºé™·ã€‚å¼€å‘者å¯èƒ½éœ€"
+"è¦æ›´å¤šè¯¦æƒ…去é‡çŽ°ç¼ºé™·ã€‚当你å‘é€è¯„论æ„è§çš„时候,扩展的开å‘者ä¸èƒ½çœ‹åˆ°ä½ çš„电å­é‚®"
+"件地å€ï¼Œæ‰€ä»¥ä»–们也就无法è”系你获å–更进一步的信æ¯ï¼Œåœ¨æœªæ¥ç‰ˆæœ¬ä¸­ä¿®å¤ç¼ºé™·çš„时候"
+"也无法通知你。"
+
+#: views/addons/display.thtml:383
+msgid "addons_display_rate_it"
+msgstr "评分"
+
+#: views/reviews/add.thtml:93 views/reviews/add.thtml:94
+msgid "addons_display_really_like_it"
+msgstr "很喜欢"
+
+#: views/addons/display.thtml:410
+msgid "addons_display_review_etiquette"
+msgstr ""
+"ä¸è¦åœ¨è¯„论中æ交缺陷报告。我们并ä¸å…许附加组件的开å‘者看到你的邮件地å€ï¼Œè€Œä»–"
+"们å¯èƒ½éœ€è¦è”系你以便帮助解决问题。"
+
+# %1 is the review guidelines link
+#. %1 is the review guidelines link
+#: views/addons/display.thtml:417
+msgid "addons_display_review_guidelines_link"
+msgstr "<a href=\"%s\">审查指å—</a>"
+
+# %1 is the support section link
+#. %1 is the support section link
+#: views/addons/display.thtml:414
+msgid "addons_display_review_see_support"
+msgstr ""
+"查阅 <a href=\"%1$s\">支æŒç›¸å…³çš„章节</a> 以了解从何处获å–有关该附加组件的帮"
+"助。"
+
+#: views/addons/display.thtml:404
+msgid "addons_display_review_submit"
+msgstr "ä¿å­˜"
+
+#: views/addons/display.thtml:430
+#, php-format
+msgid "addons_display_see_all_addons"
+msgstr "查阅所有 %1$s "
+
+# %1 is the number of reviews
+#. %1 is the number of reviews
+#: views/addons/display.thtml:364
+#, php-format
+msgid "addons_display_see_all_reviews"
+msgstr "查阅所有æ„è§ (%1$s)"
+
+#: views/addons/display.thtml:219
+msgid "addons_display_see_all_versions"
+msgstr "查看所有版本"
+
+#: views/addons/display.thtml:321 views/addons/versions.thtml:117
+msgid "addons_display_view_source"
+msgstr "查看æºä»£ç "
+
+#: views/addons/display.thtml:324
+msgid "addons_display_view_stats"
+msgstr "查看统计"
+
+#: views/addons/display.thtml:376
+msgid "addons_display_what_do_you_think"
+msgstr "你觉得怎样?"
+
+#: views/elements/app_compatibility.thtml:49
+msgid "addons_display_workswith"
+msgstr "兼容于:"
+
+#: views/addons/home.thtml:112
+#, fuzzy
+msgid "addons_home_browse_new"
+msgstr "Just Added"
+
+#: views/addons/home.thtml:110
+#, fuzzy
+msgid "addons_home_browse_popular"
+msgstr "Popular"
+
+#: views/addons/home.thtml:108
+#, fuzzy
+msgid "addons_home_browse_recommended"
+msgstr "Recommended"
+
+#: views/addons/home.thtml:127 views/addons/home.thtml:134
+#: views/addons/home.thtml:141 views/addons/home.thtml:148
+#, fuzzy
+msgid "addons_home_browse_subscribe"
+msgstr "Subscribe"
+
+#: views/addons/home.thtml:101
+#, fuzzy
+msgid "addons_home_browse_title"
+msgstr "Browse Add-ons"
+
+#: views/addons/home.thtml:114
+#, fuzzy
+msgid "addons_home_browse_updated"
+msgstr "Updated"
+
+#: views/elements/amo2009/homepage_addon.thtml:100
+#: views/elements/addon_discussionheader.thtml:83
+#: views/elements/addon_listitem.thtml:109 views/elements/feature.thtml:95
+#: views/addons/category_landing.thtml:66 views/addons/policy.thtml:57
+#: views/addons/display.thtml:70 views/addons/home.thtml:178
+msgid "addons_home_by"
+msgstr "作者"
+
+#: views/addons/home.thtml:169
+#, fuzzy
+msgid "addons_home_collection_popular_title"
+msgstr "Popular Collections"
+
+#: views/elements/amo2009/categories.thtml:69 views/addons/home.thtml:160
+#, fuzzy
+msgid "addons_home_collections"
+msgstr "Collections"
+
+#. %1$s is the count of addons in a collection
+#: views/elements/amo2009/collection_listing_item.thtml:51
+#: views/addons/home.thtml:185
+#, fuzzy
+msgid "addons_home_collections_addon_count"
+msgid_plural "addons_home_collections_addon_count"
+msgstr[0] "<strong>%1$s</strong> add-on"
+msgstr[1] "<strong>%1$s</strong> add-ons"
+
+#: views/addons/home.thtml:196
+#, fuzzy
+msgid "addons_home_collections_all"
+msgstr "View All Collections"
+
+#: views/addons/home.thtml:162
+#, fuzzy
+msgid "addons_home_collections_intro"
+msgstr ""
+"Collections are a way for you to categorize, mix, match and mingle add-ons. "
+"Subscribe to collections created by other users or create your own."
+
+#. %1$s is the count of subscribers for a collection
+#: views/elements/amo2009/collection_listing_item.thtml:58
+#: views/collections/detail.thtml:96 views/addons/home.thtml:189
+#, fuzzy
+msgid "addons_home_collections_subscribers"
+msgid_plural "addons_home_collections_subscribers"
+msgstr[0] "<strong>%1$s</strong> subscriber"
+msgstr[1] "<strong>%1$s</strong> subscribers"
+
+#: views/addons/searchengines.thtml:54 views/addons/themes_landing.thtml:49
+msgid "addons_home_feature_head"
+msgstr "推è"
+
+#: controllers/search_controller.php:218 controllers/addons_controller.php:176
+#: controllers/addons_controller.php:428 controllers/addons_controller.php:671
+#: controllers/addons_controller.php:871
+#: controllers/addons_controller.php:1103
+#: controllers/addons_controller.php:1242
+#: controllers/addons_controller.php:1298
+#, php-format
+msgid "addons_home_header_details"
+msgstr ""
+"通过附加组件扩展 %1$s,建立个性化的æµè§ˆä½“验。æµè§ˆä»¥ä¸‹å†…容打造属于你自己的 %1"
+"$s 。"
+
+#. %1$s is the HTML collection name link.
+#: views/elements/amo2009/teaser_collections.thtml:107
+#, fuzzy
+msgid "addons_home_introduction_collection_link"
+msgstr "Like these? Find more add-ons in %1$s."
+
+#: views/elements/amo2009/teaser_collections.thtml:60
+#, fuzzy
+msgid "addons_home_introduction_extras"
+msgstr ""
+"<strong>Over 5000 free extras</strong> that let you customize and extend "
+"Firefox to meet your needs."
+
+#: views/elements/amo2009/teaser_collections.thtml:55
+#, fuzzy
+msgid "addons_home_introduction_header"
+msgstr "What are Add-ons?"
+
+#: views/elements/amo2009/teaser_collections.thtml:72
+#, fuzzy
+msgid "addons_home_introduction_install"
+msgstr ""
+"<strong>Easy to install</strong>, get notified when updates are available."
+
+#: views/elements/amo2009/teaser_collections.thtml:45
+#, fuzzy
+msgid "addons_home_introduction_name"
+msgstr "Introduction"
+
+#: views/elements/amo2009/teaser_collections.thtml:66
+#, fuzzy
+msgid "addons_home_introduction_themes"
+msgstr ""
+"Toolbars, themes and search providers that <strong>help you perform common "
+"tasks.</strong>"
+
+#: views/addons/home.thtml:161
+#, fuzzy
+msgid "addons_home_new_indicator"
+msgstr "NEW!"
+
+#: views/elements/app_chooser.thtml:48 views/layouts/amo2009.thtml:257
+msgid "addons_home_other_applications"
+msgstr "其他应用程åº"
+
+#. %1$s is the application the user is browsing. Examples: Thunderbird, Firefox,
+#. Sunbird
+#: views/pages/collector_faq.thtml:49 views/pages/collector_firstrun.thtml:42
+#: views/pages/collector.thtml:46 views/pages/collector_features.thtml:54
+#: controllers/developers_controller.php:87
+#: controllers/compatibility_controller.php:72
+#: controllers/components/simple_acl.php:81 controllers/components/amo.php:607
+#: controllers/statistics_controller.php:60
+#: controllers/statistics_controller.php:240
+#: controllers/previews_controller.php:67 controllers/users_controller.php:90
+#: controllers/users_controller.php:223 controllers/users_controller.php:330
+#: controllers/users_controller.php:414 controllers/users_controller.php:708
+#: controllers/users_controller.php:723 controllers/reviews_controller.php:204
+#: controllers/reviews_controller.php:251
+#: controllers/reviews_controller.php:346
+#: controllers/reviews_controller.php:425
+#: controllers/search_controller.php:185 controllers/search_controller.php:297
+#: controllers/search_controller.php:301 controllers/addons_controller.php:147
+#: controllers/addons_controller.php:280 controllers/addons_controller.php:370
+#: controllers/addons_controller.php:667 controllers/addons_controller.php:874
+#: controllers/addons_controller.php:1019
+#: controllers/addons_controller.php:1034
+#: controllers/addons_controller.php:1101
+#: controllers/addons_controller.php:1121
+#: controllers/addons_controller.php:1240
+#: controllers/addons_controller.php:1357
+#: controllers/addons_controller.php:1364
+#: controllers/addons_controller.php:1442
+#: controllers/addons_controller.php:1477
+#: controllers/addons_controller.php:1538
+#: controllers/addons_controller.php:1543
+#: controllers/editors_controller.php:64 controllers/pages_controller.php:132
+#: controllers/groups_controller.php:65 controllers/groups_controller.php:71
+#: controllers/groups_controller.php:89 controllers/groups_controller.php:111
+#: controllers/collections_controller.php:57
+#: controllers/collections_controller.php:121
+#: controllers/collections_controller.php:205
+#: controllers/collections_controller.php:365
+#: controllers/collections_controller.php:404
+#: controllers/collections_controller.php:466
+#: controllers/collections_controller.php:538
+#: controllers/collections_controller.php:828
+#: controllers/localizers_controller.php:72
+#, php-format
+msgid "addons_home_pagetitle"
+msgstr "%1$s 附加组件"
+
+#. %1$s is the number of addons downloaded
+#: views/addons/home.thtml:57
+#, fuzzy, php-format
+msgid "addons_home_stats_downloaded"
+msgid_plural "addons_home_stats_downloaded"
+msgstr[0] "<strong>%1$s</strong> <span>add-on downloaded</span>"
+msgstr[1] "<strong>%1$s</strong> <span>add-ons downloaded</span>"
+
+#. %1$s is the number of addons in use
+#: views/addons/home.thtml:63
+#, fuzzy, php-format
+msgid "addons_home_stats_inuse"
+msgid_plural "addons_home_stats_inuse"
+msgstr[0] "<strong>%1$s</strong> <span>add-on in use</span>"
+msgstr[1] "<strong>%1$s</strong> <span>add-ons in use</span>"
+
+#: views/addons/home.thtml:136
+msgid "addons_home_view_all_newest_title"
+msgstr "查看全部新建立的附加组件"
+
+#: views/addons/home.thtml:129
+msgid "addons_home_view_all_popular_title"
+msgstr "查看全部热门的附加组件"
+
+#: views/addons/home.thtml:150
+msgid "addons_home_view_all_recommended_title"
+msgstr "查看全部推è的附加组件"
+
+#: views/addons/home.thtml:143
+msgid "addons_home_view_all_updated_title"
+msgstr "查看所有近期更新的附加组件"
+
+#: views/elements/amo2009/install.thtml:334 views/elements/install.thtml:112
+msgid "addons_install_in_sunbird"
+msgstr ""
+"<ol><li>点击下é¢çš„链接ä¿å­˜æ–‡ä»¶ã€‚</li><li>在 Mozilla Sunbird 中,从 工具 èœå•"
+"打开 附加组件。</li><li>点击 安装 按钮,然åŽæ‰¾åˆ°/选择你下载的文件并点击 \"ç¡®"
+"定\".</li></ol>"
+
+#: views/elements/amo2009/install.thtml:333 views/elements/install.thtml:111
+msgid "addons_install_in_sunbird_title"
+msgstr "如何在 Sunbird 中安装"
+
+#: views/elements/amo2009/install.thtml:331 views/elements/install.thtml:106
+msgid "addons_install_in_thunderbird"
+msgstr ""
+"<ol><li>å³é”®ç‚¹å‡»ä»¥ä¸‹é“¾æŽ¥ï¼Œé€‰æ‹© \"链接å¦å­˜ä¸º...\" 将文件下载并ä¿å­˜åˆ°ä½ çš„硬盘"
+"上。</li><li>在 Mozilla Thunderbird 中,从工具èœå•æ‰“开附加组件。</li><li>点击"
+"安装按钮,定ä½/选择你下载的文件,并点击\"确定\"。</li></ol>"
+
+#: views/elements/amo2009/install.thtml:330 views/elements/install.thtml:105
+msgid "addons_install_in_thunderbird_title"
+msgstr "如何在 Thunderbird 中安装"
+
+#: views/elements/amo2009/addon_list_options.thtml:108
+#: views/elements/addon_list_options.thtml:105
+msgid "addons_options_show_experimental"
+msgstr "显示试验性的附加组件"
+
+#: views/elements/amo2009/addon_list_options.thtml:113
+#: views/elements/addon_list_options.thtml:109
+msgid "addons_options_submit"
+msgstr "æ交"
+
+#: views/addons/plugins.thtml:63 views/addons/plugins.thtml:73
+#: views/addons/plugins.thtml:83 views/addons/plugins.thtml:93
+#: views/addons/plugins.thtml:103 views/addons/plugins.thtml:116
+#: views/addons/plugins.thtml:126
+msgid "addons_plugins_by"
+msgstr "作者"
+
+#: views/addons/plugins.thtml:107
+msgid "addons_plugins_for_linux"
+msgstr "Linux å¹³å°"
+
+#: views/addons/plugins.thtml:108 views/addons/plugins.thtml:131
+msgid "addons_plugins_for_macosx"
+msgstr "Mac OS X å¹³å°"
+
+#: views/addons/plugins.thtml:106 views/addons/plugins.thtml:129
+#: views/addons/plugins.thtml:130
+msgid "addons_plugins_for_windows"
+msgstr "Windows å¹³å°"
+
+#. %1$s is a URL
+#: views/addons/plugins.thtml:139
+#, php-format
+msgid "addons_plugins_looking_for_more"
+msgstr ""
+"本页仅列出了一些最常用和最热门的æ’件。è¦æŸ¥æ‰¾åŸºäºŽMozillaæµè§ˆå™¨çš„其他å¯ç”¨æ’件信"
+"æ¯ï¼Œè¯·è®¿é—® %1$s"
+
+#: views/addons/plugins.thtml:137
+msgid "addons_plugins_looking_for_plugin"
+msgstr "è¦æŸ¥æ‰¾çš„æ’件未在这里列出?"
+
+#: views/addons/plugins.thtml:58
+msgid "addons_plugins_main_description"
+msgstr ""
+"æ’件能帮助æµè§ˆå™¨å®žçŽ°ç‰¹å®šçš„功能,诸如显示特殊格å¼çš„图片或者播放多媒体文件。这"
+"与扩展有所ä¸åŒï¼ŒåŽè€…是用于改å˜æˆ–者加强现有的功能。"
+
+#. %1$s is the application name. Example: Firefox, Thunderbird, Sunbird
+#: controllers/addons_controller.php:1122
+#, php-format
+msgid "addons_plugins_main_header"
+msgstr "%1$s 常用æ’件"
+
+#: controllers/components/amo.php:698 controllers/addons_controller.php:1121
+msgid "addons_plugins_pagetitle"
+msgstr "æ’件"
+
+#: views/addons/plugins.thtml:68 views/addons/plugins.thtml:78
+#: views/addons/plugins.thtml:88 views/addons/plugins.thtml:98
+#: views/addons/plugins.thtml:110 views/addons/plugins.thtml:121
+#: views/addons/plugins.thtml:133
+msgid "addons_plugins_support_documentation"
+msgstr "说明文档: "
+
+#. %s is the name of the add-on
+#: views/addons/policy.thtml:61
+#, php-format
+msgid "addons_policy_eula_require"
+msgstr "安装 %s 之å‰ï¼Œä½ å¿…须接å—以下《最终用户许å¯å议》。"
+
+# %1 is the addon name
+#. %1 is the add-on name
+#: controllers/addons_controller.php:1476
+#, php-format
+msgid "addons_previews_pagetitle"
+msgstr "%s 的预览图"
+
+#: views/addons/category_landing.thtml:135
+#, fuzzy
+msgid "addons_recently_added"
+msgstr "Recently Added"
+
+#: views/addons/recommended.thtml:51 controllers/addons_controller.php:1365
+msgid "addons_recommended_introduction"
+msgstr ""
+"这里有数é‡ä¼—多的附加组件,其中一些适åˆå¤§å¤šæ•°äººã€‚下é¢åˆ—出了一些最热门的,你å¯"
+"以开始用用看ï¼"
+
+#: controllers/addons_controller.php:1357
+#: controllers/addons_controller.php:1364
+msgid "addons_recommended_pagetitle"
+msgstr "推è的附加组件"
+
+#: controllers/addons_controller.php:1360
+msgid "addons_recommended_title"
+msgstr "推è的附加组件"
+
+#: views/addons/searchengines.thtml:136
+msgid "addons_searchengines_additional_resources"
+msgstr "附加资æº"
+
+# link text devmo
+#. link text devmo
+#: views/addons/searchengines.thtml:141
+msgid "addons_searchengines_devmo_link"
+msgstr "Mozilla å¼€å‘者中心"
+
+#: views/pages/js_constants.js.thtml:67
+msgid "addons_searchengines_error_mozilla_browser_required"
+msgstr "抱歉,你需è¦åŸºäºŽMozillaçš„æµè§ˆå™¨ï¼ˆä¾‹å¦‚Firefox)æ¥å®‰è£…æœç´¢æ’件。"
+
+#: views/addons/searchengines.thtml:49
+msgid "addons_searchengines_error_nojavascript"
+msgstr ""
+"安装æœç´¢æ’ä»¶éœ€è¦ JavaScript,但是看上去你ç¦ç”¨äº†å®ƒã€‚安装下é¢çš„任何æœç´¢æ’件之"
+"å‰ï¼Œè¯·å¯ç”¨JavaScript。"
+
+# %1 is "make your own" link
+# %2 is MDC link
+#. %1 is "make your own" link
+#. %2 is MDC link
+#: views/addons/searchengines.thtml:139
+msgid "addons_searchengines_learn_howto"
+msgstr "访问 %2$s 学习如何 %1$s 。"
+
+# link path to search plugins instructions, relative to devmo
+#. link path to search plugins instructions, relative to devmo
+#: views/addons/searchengines.thtml:140
+msgid "addons_searchengines_makeyourown_href"
+msgstr "/cn/docs/为Firefox编写开放æœç´¢æ’件"
+
+# link text for "make your own" (opensearch engine)
+#. link text for "make your own" (opensearch engine)
+#: views/addons/searchengines.thtml:140
+msgid "addons_searchengines_makeyourown_link"
+msgstr "建立自己的æœç´¢æ’件"
+
+# %1 is the link to mycroft.mozdev.org
+#. %1 is the link to mycroft.mozdev.org
+#: views/addons/searchengines.thtml:138
+msgid "addons_searchengines_more"
+msgstr "访问 %1$s æµè§ˆæ›´å¤šçš„æœç´¢å¼•æ“Ž"
+
+# link text to mycroft.mozdev.org
+#. link text to mycroft.mozdev.org
+#: views/addons/searchengines.thtml:138
+msgid "addons_searchengines_mycroft_link"
+msgstr "mycroft.mozdev.org"
+
+#: controllers/addons_controller.php:1100
+#: controllers/addons_controller.php:1110
+msgid "addons_searchengines_pagetitle"
+msgstr "æœç´¢å¼•æ“Ž"
+
+#: views/addons/searchengines.thtml:143
+msgid "addons_searchengines_thanks"
+msgstr "特别感谢Mycroft项目团队在Firefox æœç´¢å¼•æ“Žæ–¹é¢çš„贡献"
+
+#: views/addons/display.thtml:154
+#, fuzzy
+msgid "addons_share_button_text"
+msgstr "Share this"
+
+#: controllers/addons_controller.php:89
+#, fuzzy
+msgid "addons_share_label_delicious"
+msgstr "Add to Delicious"
+
+#: controllers/addons_controller.php:77
+#, fuzzy
+msgid "addons_share_label_digg"
+msgstr "Digg this!"
+
+#: controllers/addons_controller.php:83
+#, fuzzy
+msgid "addons_share_label_facebook"
+msgstr "Post to Facebook"
+
+#: controllers/addons_controller.php:101
+#, fuzzy
+msgid "addons_share_label_friendfeed"
+msgstr "Share on FriendFeed"
+
+#: controllers/addons_controller.php:95
+#, fuzzy
+msgid "addons_share_label_myspace"
+msgstr "Post to MySpace"
+
+#: controllers/components/amo.php:201 controllers/components/amo.php:229
+msgid "addons_status_disabled"
+msgstr "ç¦ç”¨"
+
+#: controllers/components/amo.php:191 controllers/components/amo.php:224
+msgid "addons_status_incomplete"
+msgstr "未完æˆç‰ˆæœ¬"
+
+#: controllers/components/amo.php:197 controllers/components/amo.php:227
+msgid "addons_status_nominated"
+msgstr "在沙盒中; æ交公开å‘布"
+
+#: views/pages/js_constants.js.thtml:80 controllers/components/amo.php:195
+#: controllers/components/amo.php:226
+msgid "addons_status_pending"
+msgstr "在沙盒中; 正在审查中"
+
+#: views/pages/js_constants.js.thtml:78 controllers/components/amo.php:199
+#: controllers/components/amo.php:228
+msgid "addons_status_public"
+msgstr "公开å‘布"
+
+#: views/pages/js_constants.js.thtml:79 controllers/components/amo.php:193
+#: controllers/components/amo.php:225
+msgid "addons_status_sandbox"
+msgstr "在沙盒中"
+
+#: controllers/components/amo.php:203
+msgid "addons_status_unknown"
+msgstr "未知"
+
+#: views/elements/amo2009/teaser_collections.thtml:91
+#: views/elements/amo2009/homepage_addon.thtml:99
+#: views/elements/feature.thtml:94
+msgid "addons_title_tooltip"
+msgstr "查看有关该附加组件的更多信æ¯"
+
+#: views/addons/category_landing.thtml:151
+#, fuzzy
+msgid "addons_top_downloads"
+msgstr "Top Downloads"
+
+#: views/addons/category_landing.thtml:165
+#, fuzzy
+msgid "addons_top_rated"
+msgstr "Top Rated"
+
+#: views/addons/versions.thtml:62
+msgid "addons_versions_careful"
+msgstr "å°å¿ƒï¼Œè¿™é‡Œéƒ½æ˜¯æ—§ç‰ˆæœ¬"
+
+#: views/addons/versions.thtml:63
+msgid "addons_versions_careful_introduction"
+msgstr ""
+"显示这些版本是为了å‚考和测试目的,如果是正常使用,请安装最新版本的附加组件。"
+
+#: controllers/addons_controller.php:1549
+msgid "addons_versions_history"
+msgstr "版本历å²è®°å½•"
+
+#. %1$s is the add-on name
+#: controllers/addons_controller.php:1535
+#, php-format
+msgid "addons_versions_pagetitle"
+msgstr "%1$s 版本历å²"
+
+#: controllers/groups_controller.php:71
+msgid "admin_group_add_pagetitle"
+msgstr "添加组"
+
+#: controllers/groups_controller.php:111
+msgid "admin_group_delete_pagetitle"
+msgstr "删除组"
+
+#. %s is a number to identify the group
+#: controllers/groups_controller.php:117
+#, php-format
+msgid "admin_group_deleted"
+msgstr "ID为 %s 的组已ç»åˆ é™¤"
+
+#: controllers/groups_controller.php:89
+msgid "admin_group_edit_pagetitle"
+msgstr "编辑组"
+
+#: controllers/groups_controller.php:92 controllers/groups_controller.php:113
+msgid "admin_group_error_invalid_id"
+msgstr "组ID无效"
+
+#: controllers/groups_controller.php:65
+msgid "admin_group_pagetitle"
+msgstr "组管ç†å‘˜"
+
+#: controllers/groups_controller.php:77 controllers/groups_controller.php:99
+msgid "admin_group_saved"
+msgstr "组已ä¿å­˜"
+
+#: views/elements/amo2009/search.thtml:257 views/elements/search.thtml:239
+msgid "advanced_search_form"
+msgstr "高级æœç´¢"
+
+#: views/elements/amo2009/search.thtml:126 views/elements/search.thtml:125
+msgid "advanced_search_form_any_time"
+msgstr "任何时间"
+
+#: views/elements/amo2009/search.thtml:97
+#: views/elements/amo2009/search.thtml:110 views/elements/search.thtml:96
+#: views/elements/search.thtml:109
+msgid "advanced_search_form_any_type"
+msgstr "ä»»æ„"
+
+#: views/elements/amo2009/search.thtml:275 views/elements/search.thtml:254
+msgid "advanced_search_form_any_version"
+msgstr "ä»»æ„"
+
+#: views/elements/amo2009/search.thtml:217 views/elements/search.thtml:212
+msgid "advanced_search_form_application"
+msgstr "应用程åº"
+
+#: views/elements/amo2009/search.thtml:143 views/elements/search.thtml:142
+msgid "advanced_search_form_keyword_match"
+msgstr "关键字匹é…"
+
+#: views/elements/amo2009/search.thtml:251 views/elements/search.thtml:225
+msgid "advanced_search_form_lastupdate"
+msgstr "上次更新"
+
+#: views/elements/amo2009/search.thtml:145 views/elements/search.thtml:144
+msgid "advanced_search_form_name"
+msgstr "åå­—"
+
+#: views/elements/amo2009/search.thtml:144 views/elements/search.thtml:143
+msgid "advanced_search_form_newest"
+msgstr "最新的"
+
+#: views/elements/amo2009/search.thtml:130 views/elements/search.thtml:129
+msgid "advanced_search_form_past_3_months"
+msgstr "过去3个月"
+
+#: views/elements/amo2009/search.thtml:131 views/elements/search.thtml:130
+msgid "advanced_search_form_past_6_months"
+msgstr "过去6个月"
+
+#: views/elements/amo2009/search.thtml:127 views/elements/search.thtml:126
+msgid "advanced_search_form_past_day"
+msgstr "昨天"
+
+#: views/elements/amo2009/search.thtml:129 views/elements/search.thtml:128
+msgid "advanced_search_form_past_month"
+msgstr "上个月"
+
+#: views/elements/amo2009/search.thtml:128 views/elements/search.thtml:127
+msgid "advanced_search_form_past_week"
+msgstr "上周"
+
+#: views/elements/amo2009/search.thtml:132 views/elements/search.thtml:131
+msgid "advanced_search_form_past_year"
+msgstr "去年"
+
+#: views/elements/amo2009/search.thtml:239 views/elements/search.thtml:230
+msgid "advanced_search_form_perpage"
+msgstr "æ¯é¡µ"
+
+#: views/elements/amo2009/search.thtml:243 views/elements/search.thtml:224
+msgid "advanced_search_form_platform"
+msgstr "系统平å°"
+
+#: views/elements/amo2009/search.thtml:147 views/elements/search.thtml:146
+msgid "advanced_search_form_popularity"
+msgstr "热门的"
+
+#: views/elements/amo2009/search.thtml:146 views/elements/search.thtml:145
+msgid "advanced_search_form_rating"
+msgstr "评分"
+
+#: views/elements/amo2009/search.thtml:247 views/elements/search.thtml:231
+msgid "advanced_search_form_sortby"
+msgstr "排åºä¾æ®"
+
+#: views/elements/amo2009/search.thtml:227 views/elements/search.thtml:216
+msgid "advanced_search_form_to"
+msgstr "到"
+
+#: views/elements/amo2009/search.thtml:257 views/elements/search.thtml:237
+msgid "advanced_search_form_toggle_tooltip"
+msgstr "切æ¢é«˜çº§æœç´¢æ¨¡å¼"
+
+#: views/elements/amo2009/search.thtml:235 views/elements/search.thtml:223
+msgid "advanced_search_form_type"
+msgstr "类别"
+
+#: views/elements/amo2009/search.thtml:222 views/elements/search.thtml:214
+msgid "advanced_search_form_version"
+msgstr "版本"
+
+#: views/elements/amo2009/pagination.thtml:42
+#, fuzzy
+msgid "amo2009_pagination_next_page"
+msgstr "Next"
+
+#: views/elements/amo2009/pagination.thtml:41
+#, fuzzy
+msgid "amo2009_pagination_previous_page"
+msgstr "Prev"
+
+#: views/pages/js_constants.js.thtml:96
+msgid "app_compat_ignore_check"
+msgstr "忽略版本检查"
+
+#: views/pages/js_constants.js.thtml:72
+msgid "app_compat_older_firefox_only"
+msgstr "这是一个针对旧版本Firefox的附加组件"
+
+#. %1$s and %2$s are URLs
+#: views/pages/js_constants.js.thtml:74
+msgid "app_compat_older_version_or_ignore_check"
+msgstr ""
+"ä½ å¯ä»¥ <a href=\"%1$s\">å°è¯•æ›´æ—©çš„版本</a> 或者 <a href=\"#\" onclick=\"%2$s"
+"\">忽略这个检查</a>"
+
+#. %1$s is a URL
+#: views/pages/js_constants.js.thtml:71
+msgid "app_compat_try_old_version"
+msgstr "<a href=\"%1$s\">旧版本</a> 下å¯ä»¥ä½¿ç”¨"
+
+#. %1$s is a URL
+#. %2$s is a version number. Example: 3.1
+#: views/pages/js_constants.js.thtml:73
+msgid "app_compat_unreleased_version"
+msgstr "这个附加组件需è¦å°šæœªå‘布的 <a href=\"%1$s\">Firefox %2$s</a>"
+
+#: views/pages/js_constants.js.thtml:70
+msgid "app_compat_update_firefox"
+msgstr "<a href=\"http://getfirefox.com\">å‡çº§ Firefox</a> 以便使用该附加组件"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#. %3$s is a status, like Public.
+#: controllers/components/audit.php:79
+#, fuzzy
+msgid "audit_addon_status"
+msgstr "%1$s changed the status of %2$s to %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:221
+#, fuzzy
+msgid "audit_admin_default"
+msgstr "%1$s committed unknown admin action %2$s to ID %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:153
+#, fuzzy
+msgid "audit_admin_feature_remove"
+msgstr "%1$s removed feature %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is an application, like Firefox.
+#: controllers/components/audit.php:92
+#, fuzzy
+msgid "audit_application_create"
+msgstr "%1$s created application %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is an application, like Firefox.
+#: controllers/components/audit.php:95
+#, fuzzy
+msgid "audit_application_edit"
+msgstr "%1$s edited application %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a version number, like 3.5.
+#. %3$s is an application, like Firefox.
+#: controllers/components/audit.php:105
+#, fuzzy
+msgid "audit_appversion_create"
+msgstr "%1$s created version %2$s for %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a version number, like 3.5.
+#. %3$s is an application, like Firefox.
+#: controllers/components/audit.php:108
+#, fuzzy
+msgid "audit_appversion_delete"
+msgstr "%1$s deleted version %2$s for %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a config field, like "awesomeness".
+#. %3$s is a config value, like "off".
+#. %4$s is a config value, like "on".
+#: controllers/components/audit.php:210
+#, fuzzy
+msgid "audit_config"
+msgstr "%1$s changed config '%2$s' from '%3$s' to '%4$s'"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:258
+#, fuzzy
+msgid "audit_editor_default"
+msgstr "%1$s committed unknown editor action %2$s to ID %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#: controllers/components/audit.php:236
+#, fuzzy
+msgid "audit_editor_feature_remove"
+msgstr "%1$s removed addon %2$s from feature list"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#: controllers/components/audit.php:231
+#, fuzzy
+msgid "audit_feature_add"
+msgstr "%1$s added addon %2$s to feature list"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:149
+#, fuzzy
+msgid "audit_feature_edit"
+msgstr "%1$s changed a feature for %2$s locale"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#: controllers/components/audit.php:241
+#, fuzzy
+msgid "audit_feature_locale_change"
+msgstr "%1$s changed locales for addon %2$s on feature list"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:83
+#, fuzzy
+msgid "audit_file_recalchash"
+msgstr "%1$s recalculated the hash for file %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>user name</a>
+#. %3$s is <a>group name</a>
+#: controllers/components/audit.php:182
+#, fuzzy
+msgid "audit_group_addmember"
+msgstr "%1$s added %2$s to group %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:313
+#, fuzzy
+msgid "audit_group_associated"
+msgstr "%1$s associated themselves with %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:162
+#, fuzzy
+msgid "audit_group_create"
+msgstr "%1s created group %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:170
+#, fuzzy
+msgid "audit_group_delete"
+msgstr "%1$s deleted group %2$s (ID %3$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:165
+#, fuzzy
+msgid "audit_group_edit"
+msgstr "%1$s edited group %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>user name</a>
+#. %3$s is <a>group name</a>
+#: controllers/components/audit.php:188
+#, fuzzy
+msgid "audit_group_removemember"
+msgstr "%1$s removed %2$s from group %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:280
+#, fuzzy
+msgid "audit_l10n_default"
+msgstr "%1$s committed unknown action %2$s for %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:295
+#, fuzzy
+msgid "audit_modify_locked_group"
+msgstr "%1$s attempted to modify locked group %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:299
+#, fuzzy
+msgid "audit_modify_other_locale"
+msgstr "%1$s attempted to modify translations in %2$s without permission"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a platform, like <a>Windows</a>
+#: controllers/components/audit.php:135
+#, fuzzy
+msgid "audit_platform_create"
+msgstr "%1$s created platform %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a platform, like <a>Windows</a>
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:143
+#, fuzzy
+msgid "audit_platform_delete"
+msgstr "%1$s deleted platform %2$s (ID %3$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a platform, like <a>Windows</a>
+#: controllers/components/audit.php:138
+#, fuzzy
+msgid "audit_platform_edit"
+msgstr "%1$s edited platform %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a part of the admin, like 'Site Config'
+#: controllers/components/audit.php:288
+#, fuzzy
+msgid "audit_reauthentication_failure"
+msgstr "%1$s failed to re-authenticate to access %2$s."
+
+#. %1$s is <a>user name</a>
+#. %2$s is the name of a canned response, like 'Ready for the public'
+#: controllers/components/audit.php:198
+#, fuzzy
+msgid "audit_response_create"
+msgstr "%1$s created response %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is the name of a canned response, like 'Ready for the public'
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:206
+#, fuzzy
+msgid "audit_response_delete"
+msgstr "%1$s deleted response %2$s (ID %3$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is the name of a canned response, like 'Ready for the public'
+#: controllers/components/audit.php:201
+#, fuzzy
+msgid "audit_response_edit"
+msgstr "%1$s edited response %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:245
+#, fuzzy
+msgid "audit_review_approve"
+msgstr "%1$s approved review %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:250 controllers/components/audit.php:253
+#, fuzzy
+msgid "audit_review_delete"
+msgstr "%1$s deleted review %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:303
+#, fuzzy
+msgid "audit_security_default"
+msgstr "%1$s committed unknown security action %2$s to ID %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a category name, like <a>Search Tools</a>
+#: controllers/components/audit.php:118
+#, fuzzy
+msgid "audit_tag_create"
+msgstr "%1$s created tag %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a category name, like <a>Search Tools</a>
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:126
+#, fuzzy
+msgid "audit_tag_delete"
+msgstr "%1$s deleted category %2$s (ID %3$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a category name, like <a>Search Tools</a>
+#: controllers/components/audit.php:121
+#, fuzzy
+msgid "audit_tag_edit"
+msgstr "%1$s edited category %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:266
+#, fuzzy
+msgid "audit_update_applications"
+msgstr "%1$s updated application translations for %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:277
+#, fuzzy
+msgid "audit_update_blog"
+msgstr "%1$s updated blog post translations for %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:274
+#, fuzzy
+msgid "audit_update_platforms"
+msgstr "%1$s updated platform translations for %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:270
+#, fuzzy
+msgid "audit_update_tags"
+msgstr "%1$s updated category translations for %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>user name</a>
+#: controllers/components/audit.php:217
+#, fuzzy
+msgid "audit_user_edit"
+msgstr "%1$s edited %2$s's user information"
+
+#: controllers/addons_controller.php:1012
+msgid "browse_addons_name"
+msgstr "按å称排åº"
+
+#: controllers/addons_controller.php:1010
+msgid "browse_addons_newest"
+msgstr "最新附加组件"
+
+#: controllers/addons_controller.php:1008
+msgid "browse_addons_popular"
+msgstr "热门附加组件"
+
+#: controllers/addons_controller.php:1011
+msgid "browse_addons_rated"
+msgstr "按评分排åº"
+
+#: controllers/addons_controller.php:1009
+msgid "browse_addons_updated"
+msgstr "最近更新的附加组件"
+
+#: views/elements/categories.thtml:73 views/elements/categories.thtml:82
+msgid "categories_current_title"
+msgstr "当å‰åˆ†ç±»"
+
+#: views/elements/categories.thtml:50
+#: views/elements/amo2009/categories.thtml:43
+#: views/elements/amo2009/categories.thtml:45
+msgid "categories_header"
+msgstr "分类"
+
+#: views/elements/categories.thtml:50
+#: views/elements/amo2009/categories.thtml:41
+msgid "categories_header_title"
+msgstr "选择一个分类"
+
+# %1 is the category name
+#. %1$s is the category name
+#: views/addons/searchengines.thtml:129
+#, php-format
+msgid "category_extra_see_all"
+msgstr "查看所有的 %1$s"
+
+#. %1$s is a number.
+#: models/collection.php:130
+#, fuzzy
+msgid "collection_description_limit"
+msgstr "The description should be less than %1$s characters."
+
+#. %1$s is the name of the collection
+#: controllers/collections_controller.php:392
+#, fuzzy
+msgid "collection_detail_rss_title"
+msgstr "%s Collection"
+
+#: controllers/collections_controller.php:1065
+#, fuzzy
+msgid "collection_error_deleting_addon"
+msgstr "Error deleting add-on!"
+
+#: controllers/collections_controller.php:1051
+#, fuzzy
+msgid "collection_error_saving_addon"
+msgstr "Error saving add-on!"
+
+#: controllers/collections_controller.php:1080
+#, fuzzy
+msgid "collection_error_saving_comment"
+msgstr "Error saving comment!"
+
+#. %1$s is a number.
+#: models/collection.php:122
+#, fuzzy
+msgid "collection_name_limit"
+msgstr "The name should be less than %1$s characters."
+
+#: controllers/collections_controller.php:352
+#: controllers/collections_controller.php:487
+msgid "collection_not_found"
+msgstr "未找到收è—ï¼"
+
+#. %1$s is the text on the "create collection" button
+#: views/collections/add.thtml:91
+#, fuzzy
+msgid "collections_add_formfield_addons_description"
+msgstr ""
+"If you already know which add-ons you want to add to your collection, just "
+"start typing their names below. If you'd rather wait and do this later, just "
+"click %1$s now."
+
+#: views/collections/add.thtml:90
+#, fuzzy
+msgid "collections_add_formfield_firstaddons"
+msgstr "Choose your first add-ons"
+
+#: views/collections/add.thtml:48
+#, fuzzy
+msgid "collections_add_header"
+msgstr "Create a Collection"
+
+#: views/collections/add.thtml:97
+#, fuzzy
+msgid "collections_add_header_selectedaddons"
+msgstr "Selected Add-ons"
+
+#: views/collections/add.thtml:50
+#, fuzzy
+msgid "collections_add_intro"
+msgstr ""
+"It's easy to create your own collection of add-ons by filling in a few "
+"fields below."
+
+#: views/collections/add.thtml:92 views/collections/add.thtml:103
+#, fuzzy
+msgid "collections_add_submit"
+msgstr "Create Collection"
+
+#: views/pages/collector_faq.thtml:50 views/pages/collector_firstrun.thtml:43
+#: views/pages/collector.thtml:47 views/pages/collector_features.thtml:55
+#: controllers/search_controller.php:302
+#: controllers/collections_controller.php:206
+#: controllers/collections_controller.php:405
+#: controllers/collections_controller.php:467
+#: controllers/collections_controller.php:539
+#, fuzzy
+msgid "collections_breadcrumb"
+msgstr "Collections"
+
+#: views/collections/detail.thtml:185
+#, fuzzy
+msgid "collections_detail_a_learn"
+msgstr "Learn More"
+
+#: views/elements/amo2009/collection_add_form.thtml:53
+#: views/elements/amo2009/collections_js_init.thtml:68
+#: views/pages/collector_firstrun.thtml:64
+#, fuzzy
+msgid "collections_detail_button_add"
+msgstr "Add to Favorites"
+
+#: views/elements/amo2009/collection_add_form.thtml:50
+#: views/elements/amo2009/collections_js_init.thtml:71
+#, fuzzy
+msgid "collections_detail_button_remove"
+msgstr "Remove from Favorites"
+
+#. %1$s is a URL.
+#. %2$s is a full <a href>.
+#: views/collections/detail.thtml:62
+#, fuzzy
+msgid "collections_detail_created_desc"
+msgstr ""
+"<p>You can view your new collection below. If you'd like to set a collection "
+"nickname, upload an icon, or change additional settings, please visit the <a "
+"href='%1$s'>Manage Collections</a> page.</p><p>Your collection can be "
+"accessed at this location: %2$s</p>"
+
+#: views/collections/detail.thtml:61
+#, fuzzy
+msgid "collections_detail_created_msg"
+msgstr "Your collection is now ready!"
+
+#: views/collections/detail.thtml:109
+#, fuzzy
+msgid "collections_detail_header_about"
+msgstr "About This Collection"
+
+#. %1$s is a number.
+#: views/collections/detail.thtml:126
+#, fuzzy
+msgid "collections_detail_header_count"
+msgid_plural "collections_detail_header_count"
+msgstr[0] "%1$s Add-on in this Collection"
+msgstr[1] "%1$s Add-ons in this Collection"
+
+#: views/collections/detail.thtml:113
+#, fuzzy
+msgid "collections_detail_info_created"
+msgstr "<strong>Created by:</strong> %1$s"
+
+#: views/collections/detail.thtml:117
+#, fuzzy
+msgid "collections_detail_info_updated"
+msgstr "<strong>Updated:</strong>"
+
+#: views/elements/amo2009/collections_js_init.thtml:62
+#, fuzzy
+msgid "collections_detail_js_adding"
+msgstr "Adding to Favorites&hellip;"
+
+#: views/elements/amo2009/collections_js_init.thtml:65
+#, fuzzy
+msgid "collections_detail_js_removing"
+msgstr "Removing Favorite&hellip;"
+
+#. %1$s is a URL
+#: views/collections/detail.thtml:90
+#, fuzzy
+msgid "collections_detail_login"
+msgstr "<a href=\"%1$s\">Log in</a> to add this collection to your favorites."
+
+#: views/collections/detail.thtml:104
+#, fuzzy
+msgid "collections_detail_manage"
+msgstr "Manage Collection"
+
+#: controllers/collections_controller.php:298
+#, fuzzy
+msgid "collections_detail_sort_date"
+msgstr "Date Added"
+
+#: controllers/collections_controller.php:299
+#, fuzzy
+msgid "collections_detail_sort_name"
+msgstr "Name"
+
+#: controllers/collections_controller.php:300
+#, fuzzy
+msgid "collections_detail_sort_popularity"
+msgstr "Popularity"
+
+#. %1$s is a number.
+#: views/collections/detail.thtml:166
+#, fuzzy
+msgid "collections_detail_weekly_downloads"
+msgid_plural "collections_detail_weekly_downloads"
+msgstr[0] "%1$s download this week"
+msgstr[1] "%1$s downloads this week"
+
+#: views/collections/edit.thtml:255
+#, fuzzy
+msgid "collections_edit_addons_delete_noscript"
+msgstr "Selected add-ons will be removed upon Save"
+
+#: views/collections/edit.thtml:247
+#, fuzzy
+msgid "collections_edit_addons_description"
+msgstr ""
+"To publish new add-ons to this collection, start typing their names below."
+
+#: views/collections/edit.thtml:248
+#, fuzzy
+msgid "collections_edit_addons_description_noscript"
+msgstr ""
+"To publish new add-ons to this collection, enter a comma-separated list of "
+"Add-on IDs below."
+
+#: views/collections/edit.thtml:247 views/collections/edit.thtml:248
+#, fuzzy
+msgid "collections_edit_addons_description_publish_detailspage"
+msgstr "You can also publish an add-on from its normal listing page."
+
+#. %1$s is the date the add-on was added to the collection
+#. %1$s is the name of the user who added the add-on to the collection
+#: views/collections/edit.thtml:260
+#, fuzzy
+msgid "collections_edit_addons_listitem_added"
+msgstr "Added %1$s by %2$s"
+
+#: views/collections/edit.thtml:263
+#, fuzzy
+msgid "collections_edit_addons_listitem_comment_add"
+msgstr "Add publisher comment"
+
+#: views/collections/edit.thtml:266
+#, fuzzy
+msgid "collections_edit_addons_listitem_comment_delete"
+msgstr "Delete publisher comment"
+
+#: views/collections/edit.thtml:265
+#, fuzzy
+msgid "collections_edit_addons_listitem_comment_edit"
+msgstr "Edit publisher comment"
+
+#: views/collections/edit.thtml:271
+#, fuzzy
+msgid "collections_edit_addons_listitem_comment_note"
+msgstr ""
+"Note: Comment will appear as though written by original publisher on the "
+"original publication date"
+
+#: views/collections/edit.thtml:270
+#, fuzzy
+msgid "collections_edit_addons_listitem_comment_submit"
+msgstr "Save Comment"
+
+#: views/collections/edit.thtml:261
+#, fuzzy
+msgid "collections_edit_addons_listitem_remove"
+msgstr "Remove"
+
+#: views/collections/edit.thtml:250
+#, fuzzy
+msgid "collections_edit_addons_submit"
+msgstr "Add to Collection"
+
+#: views/collections/edit.thtml:153
+#, fuzzy
+msgid "collections_edit_check_nickname"
+msgstr "Check Availability"
+
+#: views/collections/edit.thtml:299
+#, fuzzy
+msgid "collections_edit_confirm_deletecollection"
+msgstr "Yes, I would like to delete this collection."
+
+#. %1$s is the label of the edit form's submit button
+#: views/collections/edit.thtml:300
+#, fuzzy
+msgid "collections_edit_confirm_deletecollection_description"
+msgstr "Check the box, then click on \"%1$s\" to delete this collection."
+
+#. %1$s is the "delete" submit button text
+#. %2$s is the title of the "advanced" tab
+#: views/collections/edit.thtml:95
+#, fuzzy
+msgid "collections_edit_delete_upon_submit"
+msgstr ""
+"Upon clicking \"%1$s\" below, your collection will be deleted. If you do not "
+"want to delete your collection, uncheck the confirmation box in the \"%2$s\" "
+"tab and continue editing your collection. If you leave this page without "
+"saving, your collection will also not be deleted."
+
+#: views/collections/edit.thtml:94
+#, fuzzy
+msgid "collections_edit_delete_warning"
+msgstr "Your collection is about to be deleted!"
+
+#: views/collections/add.thtml:76 views/collections/edit.thtml:144
+#, fuzzy
+msgid "collections_edit_form_error_description"
+msgstr "You must provide a description of your collection."
+
+#: views/collections/edit.thtml:181
+#, fuzzy
+msgid "collections_edit_form_error_icon"
+msgstr "There was an error uploading your icon."
+
+#: views/collections/add.thtml:69 views/collections/edit.thtml:130
+#, fuzzy
+msgid "collections_edit_form_error_name"
+msgstr "You must give your collection a name."
+
+#: views/collections/edit.thtml:158
+#, fuzzy
+msgid "collections_edit_form_error_nickname"
+msgstr "If you choose a nickname, it must be unique."
+
+#: views/collections/add.thtml:93 views/collections/edit.thtml:249
+#, fuzzy
+msgid "collections_edit_formfield_addons"
+msgstr "Add-on name:"
+
+#: views/collections/edit.thtml:281
+#, fuzzy
+msgid "collections_edit_formfield_application"
+msgstr "Associated Application"
+
+#: views/collections/edit.thtml:282
+#, fuzzy
+msgid "collections_edit_formfield_application_description"
+msgstr "Select the application that your collection supports."
+
+#: views/collections/edit.thtml:288
+#, fuzzy
+msgid "collections_edit_formfield_collectiontype"
+msgstr "Collection Type"
+
+#: views/collections/edit.thtml:295
+#, fuzzy
+msgid "collections_edit_formfield_deletecollection"
+msgstr "Delete Collection"
+
+#: views/collections/edit.thtml:296
+#, fuzzy
+msgid "collections_edit_formfield_deletecollection_description"
+msgstr "Deleting your collection will permanently erase it."
+
+#: views/collections/add.thtml:73 views/collections/edit.thtml:140
+#, fuzzy
+msgid "collections_edit_formfield_description"
+msgstr "Collection Description"
+
+#: views/collections/add.thtml:74 views/collections/edit.thtml:141
+#, fuzzy
+msgid "collections_edit_formfield_description_description"
+msgstr "Briefly describe your collection and the kind of add-ons in it"
+
+#: views/collections/edit.thtml:162
+#, fuzzy
+msgid "collections_edit_formfield_icon"
+msgstr "Icon"
+
+#: views/collections/edit.thtml:163
+#, fuzzy
+msgid "collections_edit_formfield_icon_description"
+msgstr ""
+"You can upload a JPG, GIF or PNG icon that will be resized to 32x32 pixels."
+
+#: views/collections/add.thtml:80 views/collections/edit.thtml:189
+#, fuzzy
+msgid "collections_edit_formfield_listed"
+msgstr "Who can view your collection?"
+
+#: views/collections/add.thtml:81 views/collections/edit.thtml:190
+#, fuzzy
+msgid "collections_edit_formfield_listed_description"
+msgstr ""
+"By default, collections appear in the public Collection Directory and are "
+"discoverable by anyone. If you want to restrict your collection to be "
+"viewable only by people who are given a special link, choose that option "
+"below."
+
+#: views/collections/add.thtml:84 views/collections/edit.thtml:193
+#, fuzzy
+msgid "collections_edit_formfield_listed_false"
+msgstr "Only people I invite can view my collection"
+
+#: views/collections/add.thtml:83 views/collections/edit.thtml:192
+#, fuzzy
+msgid "collections_edit_formfield_listed_true"
+msgstr "Everyone can view my collection in the directory"
+
+#: views/collections/edit.thtml:223
+#, fuzzy
+msgid "collections_edit_formfield_managers"
+msgstr "Who can manage my collection?"
+
+#: views/collections/edit.thtml:224
+#, fuzzy
+msgid "collections_edit_formfield_managers_description"
+msgstr ""
+"These users can publish add-ons to your collection, manage all add-ons and "
+"settings, and grant other users permission."
+
+#: views/collections/add.thtml:66 views/collections/edit.thtml:126
+#, fuzzy
+msgid "collections_edit_formfield_name"
+msgstr "Collection Name"
+
+#: views/collections/add.thtml:67 views/collections/edit.thtml:127
+#, fuzzy
+msgid "collections_edit_formfield_name_description"
+msgstr ""
+"Give your collection a descriptive name, such as \"Dave's Favorite Travel "
+"Add-ons\""
+
+#: views/collections/edit.thtml:148
+#, fuzzy
+msgid "collections_edit_formfield_nickname"
+msgstr "Collection Nickname"
+
+#: views/collections/edit.thtml:149
+#, fuzzy
+msgid "collections_edit_formfield_nickname_description"
+msgstr "Optionally, give your collection a unique nickname for quick access:"
+
+#: views/collections/edit.thtml:201
+#, fuzzy
+msgid "collections_edit_formfield_publishers"
+msgstr "Who can publish add-ons to your collection?"
+
+#: views/collections/edit.thtml:202
+#, fuzzy
+msgid "collections_edit_formfield_publishers_description"
+msgstr ""
+"These users can publish add-ons to your collection and remove add-ons that "
+"they publish."
+
+#: views/collections/edit.thtml:210 views/collections/edit.thtml:232
+#, fuzzy
+msgid "collections_edit_formfield_users_add"
+msgstr "Enter the e-mail address of a Firefox Add-ons account:"
+
+#: views/collections/edit.thtml:216 views/collections/edit.thtml:238
+#, fuzzy
+msgid "collections_edit_formfield_users_delete_noscript"
+msgstr "Selected accounts will be removed upon Save"
+
+#: views/collections/edit.thtml:215 views/collections/edit.thtml:237
+#, fuzzy
+msgid "collections_edit_formfield_users_new_noscript"
+msgstr ""
+"Enter a comma-separated list of e-mail addresses of Firefox Add-ons accounts"
+
+#: views/collections/edit.thtml:204 views/collections/edit.thtml:226
+#, fuzzy
+msgid "collections_edit_formfield_users_onlyme"
+msgstr "Only me"
+
+#: views/collections/edit.thtml:205 views/collections/edit.thtml:227
+#, fuzzy
+msgid "collections_edit_formfield_users_otherusers"
+msgstr "Myself and these users:"
+
+#: views/collections/edit.thtml:211 views/collections/edit.thtml:233
+#, fuzzy
+msgid "collections_edit_formfield_users_submit"
+msgstr "Add"
+
+#. %1$s is the name of the collection
+#: views/collections/edit.thtml:68
+#, fuzzy
+msgid "collections_edit_header"
+msgstr "Manage %1$s"
+
+#: views/collections/edit.thtml:246
+#, fuzzy
+msgid "collections_edit_header_addons"
+msgstr "Manage Collection Contents"
+
+#: views/collections/edit.thtml:253 views/collections/edit.thtml:258
+#, fuzzy
+msgid "collections_edit_header_addons_current"
+msgstr "Current Add-ons:"
+
+#: views/collections/edit.thtml:279
+#, fuzzy
+msgid "collections_edit_header_advanced"
+msgstr "Advanced Settings"
+
+#: views/collections/edit.thtml:186
+#, fuzzy
+msgid "collections_edit_header_permissions"
+msgstr "Manage Collection Permissions"
+
+#: views/collections/edit.thtml:170
+#, fuzzy
+msgid "collections_edit_icon_cancel"
+msgstr "Cancel"
+
+#: views/collections/edit.thtml:174 views/collections/edit.thtml:179
+#, fuzzy
+msgid "collections_edit_icon_delete"
+msgstr "Delete Icon"
+
+#: views/collections/edit.thtml:178
+#, fuzzy
+msgid "collections_edit_icon_replace"
+msgstr "Replace Icon"
+
+#. %1$s is the label of the edit form's submit button
+#: views/collections/edit.thtml:169
+#, fuzzy
+msgid "collections_edit_icon_toberemoved"
+msgstr "Icon will be removed when \"%1$s\" is clicked below"
+
+#: views/collections/edit.thtml:155
+#, fuzzy
+msgid "collections_edit_nickname_available"
+msgstr "Nickname Available"
+
+#: controllers/collections_controller.php:943
+#, fuzzy
+msgid "collections_edit_nickname_error"
+msgstr ""
+"Your nickname contained invalid characters and was corrected. Please try "
+"again."
+
+#: views/collections/edit.thtml:156
+#, fuzzy
+msgid "collections_edit_nickname_taken"
+msgstr "Nickname Taken"
+
+#. This string is followed by a URL pointing to the collection's view page
+#: views/collections/edit.thtml:75
+#, fuzzy
+msgid "collections_edit_saved_nextstep"
+msgstr "Your collection can be accessed at this location:"
+
+#: views/collections/edit.thtml:74
+#, fuzzy
+msgid "collections_edit_saved_success"
+msgstr "Your collection was successfully saved!"
+
+#: views/collections/edit.thtml:169 views/collections/edit.thtml:300
+#: views/collections/edit.thtml:308 views/pages/js_constants.js.thtml:99
+#, fuzzy
+msgid "collections_edit_submit"
+msgstr "Update Collection"
+
+#: views/collections/edit.thtml:96 views/collections/edit.thtml:297
+#: views/pages/js_constants.js.thtml:100
+#, fuzzy
+msgid "collections_edit_submit_deletecollection"
+msgstr "Delete Collection"
+
+#: views/collections/edit.thtml:111
+#, fuzzy
+msgid "collections_edit_tabheader_addons"
+msgstr "Add-ons"
+
+#: views/collections/edit.thtml:97 views/collections/edit.thtml:113
+#, fuzzy
+msgid "collections_edit_tabheader_advanced"
+msgstr "Advanced"
+
+#: views/collections/edit.thtml:108
+#, fuzzy
+msgid "collections_edit_tabheader_details"
+msgstr "Name &amp; Details"
+
+#: views/collections/edit.thtml:109
+#, fuzzy
+msgid "collections_edit_tabheader_permissions"
+msgstr "Permissions"
+
+#: models/collection_promo.php:53
+#, fuzzy
+msgid "collections_family_tagline"
+msgstr "Add-ons can keep an eye on your kids and your calendar."
+
+#: models/collection_promo.php:53
+#, fuzzy
+msgid "collections_family_title"
+msgstr "Family Organizer"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:70
+#, fuzzy
+msgid "collections_index_a_check_out"
+msgstr "Check out Add-on Collector"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:52
+#, fuzzy
+msgid "collections_index_a_create"
+msgstr "Create a Collection"
+
+#: views/collections/detail.thtml:139 views/collections/listing.thtml:85
+#: views/search/collections.thtml:84
+#, fuzzy
+msgid "collections_index_button_go"
+msgstr "Go"
+
+#. %1$s is a URL.
+#: controllers/collections_controller.php:182
+#, fuzzy
+msgid "collections_index_filler_favorites"
+msgstr ""
+"<p><strong>You don't have any favorite collections yet.</strong></p> "
+"<p>Collections you mark as favorites can be quickly accessed from this page, "
+"and will appear in the <a href='%1$s'>Add-on Collector</a> if you've "
+"installed it.</p>"
+
+#. %1$s is a URL.
+#: controllers/collections_controller.php:167
+#, fuzzy
+msgid "collections_index_filler_mine"
+msgstr ""
+"<p>You haven't created any collections yet. Collections are easy to create "
+"and fill with your favorite add-ons. <a href='%1$s'>Try it out</a>!</p>"
+
+#: views/collections/listing.thtml:51
+#, fuzzy
+msgid "collections_index_header_collections"
+msgstr "Collections"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:60
+#, fuzzy
+msgid "collections_index_header_collector"
+msgstr "Add-on Collector"
+
+#. %1$s is a comma-separated list of author names
+#: views/elements/amo2009/collection_listing_item.thtml:84
+#: views/collections/detail.thtml:151
+#, fuzzy
+msgid "collections_index_header_created"
+msgstr "created by %1$s"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:47
+#, fuzzy
+msgid "collections_index_header_what"
+msgstr "What are Collections?"
+
+#: views/collections/detail.thtml:132 views/collections/listing.thtml:78
+#: views/search/collections.thtml:66
+#, fuzzy
+msgid "collections_index_label_sortby"
+msgstr "Sort by"
+
+#: controllers/collections_controller.php:130
+#, fuzzy
+msgid "collections_index_li_editors"
+msgstr "Editor's Picks"
+
+#: views/collections/subscribe.thtml:64
+#: controllers/collections_controller.php:140
+#, fuzzy
+msgid "collections_index_li_favorites"
+msgstr "My Favorites"
+
+#: controllers/collections_controller.php:138
+#, fuzzy
+msgid "collections_index_li_mine"
+msgstr "My Collections"
+
+#: controllers/collections_controller.php:132
+#, fuzzy
+msgid "collections_index_li_popular"
+msgstr "Popular"
+
+#: views/search/collections.thtml:74 controllers/collections_controller.php:81
+#, fuzzy
+msgid "collections_index_option_all"
+msgstr "Most popular all time"
+
+#: views/search/collections.thtml:72 controllers/collections_controller.php:78
+#, fuzzy
+msgid "collections_index_option_month"
+msgstr "Most popular this month"
+
+#: views/search/collections.thtml:76 controllers/collections_controller.php:84
+#, fuzzy
+msgid "collections_index_option_newest"
+msgstr "Newest"
+
+#: views/search/collections.thtml:70 controllers/collections_controller.php:75
+#, fuzzy
+msgid "collections_index_option_week"
+msgstr "Most popular this week"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:67
+#, fuzzy
+msgid "collections_index_p_collector"
+msgstr ""
+"There's a new way to manage and find favorite add-ons. Comment, share and "
+"sync collections, all from your browser"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:48
+#, fuzzy
+msgid "collections_index_p_what_are"
+msgstr "Collections are groups of related add-ons assembled for easy sharing."
+
+#. %s is a date in the _('date') format
+#: views/elements/collections_interactive_addon.thtml:85
+#, php-format
+msgid "collections_interactive_addon_added"
+msgstr "已添加 %s"
+
+#: models/collection_promo.php:55
+#, fuzzy
+msgid "collections_reference_tagline"
+msgstr "Add-ons can do better research online."
+
+#: models/collection_promo.php:55
+#, fuzzy
+msgid "collections_reference_title"
+msgstr "Reference Desk"
+
+#: models/collection_promo.php:52
+#, fuzzy
+msgid "collections_social_tagline"
+msgstr "Add-ons can manage your social network."
+
+#: models/collection_promo.php:52
+#, fuzzy
+msgid "collections_social_title"
+msgstr "Social Circuit"
+
+#: views/collections/subscribe.thtml:91
+#, fuzzy
+msgid "collections_subscribe_button_close"
+msgstr "Close"
+
+#: views/collections/subscribe.thtml:70
+#, fuzzy
+msgid "collections_subscribe_error"
+msgstr ""
+"An error occurred trying to add a favorite collection. Is this collection "
+"already a favorite?"
+
+#: views/collections/subscribe.thtml:96
+#, fuzzy
+msgid "collections_subscribe_label_bothersome"
+msgstr "Don't show me this message again."
+
+#. %1$s is the collection name
+#: views/collections/subscribe.thtml:60
+#, fuzzy
+msgid "collections_subscribe_success"
+msgstr "%1$s has been added to your favorite collections."
+
+#. %1$s is the link to the "My Favorites" tab on the main collections page
+#. %2$s is the localized title of the "My Favorites" tab
+#. %3$s is the link URL to the collector add-on
+#: views/collections/subscribe.thtml:62
+#, fuzzy
+msgid "collections_subscribe_success_desc"
+msgstr ""
+"You can now quickly find this collection from the <a href=\"%1$s\">%2$s</a> "
+"tab in the directory. For an even easier way to keep track of your favorite "
+"collections, try out our <a href=\"%3$s\">Add-on Collector</a> extension for "
+"Firefox."
+
+#: views/collections/listing.thtml:55
+#, fuzzy
+msgid "collections_success_delete"
+msgstr "The collection has been deleted."
+
+#: models/collection_promo.php:54
+#, fuzzy
+msgid "collections_travel_tagline"
+msgstr "Add-ons can turn you into a travel agent."
+
+#: models/collection_promo.php:54
+#, fuzzy
+msgid "collections_travel_title"
+msgstr "The Traveler's Pack"
+
+#. A collection of add-ons that is automatically built for a user. They are "automatically published" to this collection.
+#: controllers/collections_controller.php:581
+#, fuzzy
+msgid "collections_type_autopublisher"
+msgstr "Auto-publisher"
+
+#. A collection that has been chosen by an Editor as notable or exceptional
+#: controllers/collections_controller.php:582
+#, fuzzy
+msgid "collections_type_editorspick"
+msgstr "Editor's Pick"
+
+#: controllers/collections_controller.php:580
+#, fuzzy
+msgid "collections_type_normal"
+msgstr "Normal"
+
+#: views/collections/subscribe.thtml:84
+#, fuzzy
+msgid "collections_unsubscribe_error"
+msgstr ""
+"An error occurred trying to remove a favorite collection. Was this "
+"collection not a favorite?"
+
+#. %1$s is the collection name
+#: views/collections/subscribe.thtml:78
+#, fuzzy
+msgid "collections_unsubscribe_success"
+msgstr "%1$s has been removed from your favorite collections."
+
+#: models/collection_promo.php:56
+#, fuzzy
+msgid "collections_webdev_tagline"
+msgstr "Add-ons make it easier to build the perfect website."
+
+#: models/collection_promo.php:56
+#, fuzzy
+msgid "collections_webdev_title"
+msgstr "Web Developer's Toolbox"
+
+#: views/elements/amo2009/collections_sidebar_whatare.thtml:40
+#, fuzzy
+msgid "collections_whatare_header"
+msgstr "What are Collections?"
+
+#: views/elements/amo2009/collections_sidebar_whatare.thtml:45
+#, fuzzy
+msgid "collections_whatare_learnmore"
+msgstr "Read the FAQ"
+
+#: views/elements/amo2009/collections_sidebar_whatare.thtml:44
+#, fuzzy
+msgid "collections_whatare_text"
+msgstr ""
+"There’s a new way to manage and find favorite add-ons. Comment, share and "
+"sync collections, all from your browser."
+
+#: views/pages/collector_faq.thtml:61 views/pages/collector_features.thtml:67
+#, fuzzy
+msgid "collector_features_a_home"
+msgstr "Add-on Collector Home"
+
+#: views/elements/amo2009/collector_sidebar_download.thtml:46
+#, fuzzy
+msgid "collector_features_heading_download"
+msgstr "Download the Add-on Collector:"
+
+#: views/elements/amo2009/collector_sidebar_download.thtml:43
+#: views/pages/collector_firstrun.thtml:116 views/pages/collector.thtml:69
+#, fuzzy
+msgid "collector_features_img_logo"
+msgstr "Add-on Collector Logo"
+
+#: views/compatibility/dashboard.thtml:49
+#: controllers/compatibility_controller.php:72
+msgid "compatibility_dashboard_center_header"
+msgstr "附加组件兼容性中心"
+
+#. %1$s is the name of an application and a version. Example: Firefox 3.0
+#. %2$s is the name of an application. Example: Firefox
+#: views/compatibility/dashboard.thtml:50
+msgid "compatibility_dashboard_intro"
+msgstr "为 %1$s çš„å‘布准备了以下工具和信æ¯ä¾› %2$s 社区使用。"
+
+#: views/compatibility/dashboard.thtml:103
+msgid "compatibility_dashboard_loading"
+msgstr "正在读å–æ•°æ®..."
+
+#: views/compatibility/dashboard.thtml:45
+msgid "compatibility_dashboard_main_link"
+msgstr "返回主页"
+
+#: views/compatibility/dashboard.thtml:100 views/compatibility/report.thtml:43
+msgid "compatibility_dashboard_report"
+msgstr "附加组件兼容性汇报"
+
+#: views/compatibility/dashboard.thtml:53
+#: views/compatibility/dashboard.thtml:110
+#: views/compatibility/developers.thtml:43
+msgid "compatibility_developer_info"
+msgstr "供附加组件开å‘者查看的信æ¯"
+
+#: views/compatibility/developers.thtml:66
+msgid "compatibility_developers_adjust_maxversion"
+msgstr "ä¸ä¸Šä¼ æ ¡æ­£æœ€å¤§ç‰ˆæœ¬å·"
+
+#: views/compatibility/dashboard.thtml:124
+msgid "compatibility_developers_check_status"
+msgstr "检查我的附加组件状æ€"
+
+#. %1$s is a URL
+#. %2$s is an application and version. Example: Firefox 3.0
+#: views/compatibility/dashboard.thtml:126
+msgid "compatibility_developers_login_first"
+msgstr ""
+"如果你在 Mozilla 附加组件上å‘布了附加组件,<a href=\"%1$s\">请登录</a>以便分"
+"æžä½ çš„ %2$s 附加组件的状æ€ã€‚"
+
+#: views/compatibility/dashboard.thtml:114
+msgid "compatibility_developers_mdclogo_alt"
+msgstr "Mozilla å¼€å‘者中心图标"
+
+#: views/compatibility/developers.thtml:73
+msgid "compatibility_developers_no_addons"
+msgstr "在 Mozilla 附加组件网站上你没有任何附加组件。"
+
+#: views/compatibility/dashboard.thtml:133
+#: views/compatibility/developers.thtml:55
+msgid "compatibility_developers_results"
+msgstr "附加组件状æ€æ£€æŸ¥ç»“æžœ"
+
+#: views/compatibility/dashboard.thtml:137
+msgid "compatibility_developers_retrieving"
+msgstr "正在接收附加组件状æ€..."
+
+#. %1$s is a number
+#. %2$s is an application name
+#. %3$s is a number.
+#. Full example: 50 Firefox users (10% of total)
+#: views/compatibility/developers.thtml:65
+msgid "compatibility_developers_user_count"
+msgstr "%1$s %2$s 用户 ( å ç”¨æˆ·æ€»æ•°çš„ %3$s&#37; )"
+
+#: views/compatibility/report.thtml:45
+msgid "compatibility_report_detail_intro"
+msgstr ""
+"以下附加组件构æˆäº†Mozilla已知的95%的附加组件使用é‡ï¼ŒæŒ‰å„自使用é‡å¤šå°‘排åºã€‚"
+
+#: views/compatibility/dashboard.thtml:94
+msgid "compatibility_report_detailed_link"
+msgstr "查看详细报告"
+
+#. %1$s and %2$s are numbers
+#. %3$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:65
+msgid "compatibility_report_intro"
+msgstr ""
+"%1$s 附加组件构æˆäº†Mozilla已知的 95&#37; 的附加组件使用é‡ï¼Œç›®å‰<b>%2$s&#37;</"
+"b>被认为兼容最新版本的 %3$s 。"
+
+#: views/compatibility/dashboard.thtml:81
+msgid "compatibility_report_legend_alpha"
+msgstr "Alpha 版本"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:81
+msgid "compatibility_report_legend_alpha_description"
+msgstr "兼容 %1$s alpha 版本的附加组件"
+
+#: views/compatibility/dashboard.thtml:85
+msgid "compatibility_report_legend_beta"
+msgstr "Beta 版本"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:85
+msgid "compatibility_report_legend_beta_description"
+msgstr "兼容 %1$s 的 beta 版本或预览版的附加组件"
+
+#: views/compatibility/dashboard.thtml:89
+msgid "compatibility_report_legend_latest"
+msgstr "最新版本"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:89
+msgid "compatibility_report_legend_latest_description"
+msgstr "æœ€æ–°æ”¯æŒ %1$s 最新版本的附加组件"
+
+#: views/compatibility/dashboard.thtml:77
+msgid "compatibility_report_legend_other"
+msgstr "其他版本"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:77
+msgid "compatibility_report_legend_other_description"
+msgstr "该附加组件ä¸å…¼å®¹ %1$s 的任何版本"
+
+#: views/compatibility/dashboard.thtml:62
+msgid "compatibility_report_title"
+msgstr "附加组件兼容性报告"
+
+#: views/compatibility/dashboard.thtml:54
+#: views/compatibility/dashboard.thtml:144 views/compatibility/users.thtml:42
+msgid "compatibility_user_info"
+msgstr "供附加组件用户查看的信æ¯"
+
+#: views/compatibility/dashboard.thtml:52
+msgid "compatibility_view_report"
+msgstr "查看兼容性报告"
+
+#. %s is a URL
+#: views/pages/credits.thtml:142
+#, php-format
+msgid "credits_contributing"
+msgstr "有关贡献的更多信æ¯ï¼Œè¯·æŸ¥é˜…我们的 %s 。"
+
+#: views/pages/credits.thtml:142
+msgid "credits_contributing_wikipage"
+msgstr "维基页é¢"
+
+#: views/pages/credits.thtml:99
+msgid "credits_intro"
+msgstr "Mozilla è¦æ„Ÿè°¢ä»¥ä¸‹äººå‘˜åœ¨è¿‡åŽ»çš„几年中对 addons.mozilla.org 项目的贡献:"
+
+#: views/pages/credits.thtml:103
+msgid "credits_section_developers"
+msgstr "å¼€å‘者"
+
+#: views/pages/credits.thtml:115
+msgid "credits_section_editors"
+msgstr "编辑"
+
+#: views/pages/credits.thtml:109
+msgid "credits_section_localizers"
+msgstr "本地化人员"
+
+#: views/pages/credits.thtml:121
+msgid "credits_section_other_contributors"
+msgstr "其他贡献者"
+
+#: views/pages/credits.thtml:127
+msgid "credits_section_past_developers"
+msgstr "曾ç»çš„å¼€å‘者"
+
+#: views/pages/credits.thtml:133
+msgid "credits_section_software"
+msgstr "软件和图片"
+
+#: views/pages/credits.thtml:136
+msgid "credits_software_famfamfam"
+msgstr ""
+"用到的一些图标æ¥è‡ª <a href=\"http://www.famfamfam.com/lab/icons/silk/"
+"\">famfamfam Silk Icon Set</a>, 许å¯å议为 <a href=\"http://creativecommons."
+"org/licenses/by/2.5/\">Creative Commons Attribution 2.5 License</a>."
+
+#: views/pages/credits.thtml:137
+#, fuzzy
+msgid "credits_software_timeplot"
+msgstr ""
+"Some pages use elements of <a href=\"http://www.simile-widgets.org/timeplot/"
+"\">Timeplot</a>, licensed under a <a href=\"http://simile.mit.edu/license."
+"html\">BSD License</a>."
+
+# date format string as used in PHP's strftime():
+# http://php.net/strftime
+#. date format string as used in PHP's strftime():
+#. http://php.net/strftime
+#: views/elements/collections_interactive_addon.thtml:85
+#: views/elements/amo2009/addon_version_detail.thtml:53
+#: views/elements/amo2009/homepage_addon.thtml:115
+#: views/elements/addon_version_detail.thtml:54
+#: views/elements/addon_listitem.thtml:124 views/elements/feature.thtml:106
+#: views/collections/detail.thtml:118 views/collections/edit.thtml:325
+#: views/users/info.thtml:76 views/editors/reviews_queue.thtml:57
+#: views/editors/reviews_queue.thtml:68 views/developers/dashboard.thtml:65
+#: views/developers/versions_edit.thtml:208 views/developers/versions.thtml:67
+#: views/search/rss/index.thtml:5 views/addons/rss/versions.thtml:42
+#: views/addons/display.thtml:104 views/addons/display.thtml:356
+#: views/addons/browse_thumbs.thtml:75 views/reviews/add.thtml:63
+#: views/reviews/display.thtml:74 views/reviews/display.thtml:160
+#: views/reviews/delete.thtml:54 controllers/statistics_controller.php:244
+#: controllers/collections_controller.php:1047
+msgid "date"
+msgstr "%Y 年 %m 月 %e 日"
+
+# date and time format string (strftime)
+#. date and time format string (strftime)
+#. http://php.net/strftime
+#: views/elements/addon_version_detail.thtml:53
+#: views/developers/discuss.thtml:52 views/developers/discuss.thtml:62
+#: views/admin/addons_status.thtml:57
+msgid "datetime"
+msgstr "%Y 年 %m 月 %e 日 %H:%M"
+
+#: views/elements/developers/actionbar.thtml:47
+msgid "devcp_actionbar_link_details"
+msgstr "详细信æ¯"
+
+#: views/elements/developers/actionbar.thtml:42
+#: views/elements/developers/actionbar.thtml:50
+#: views/developers/dashboard.thtml:64
+msgid "devcp_actionbar_link_edit"
+msgstr "编辑附加组件"
+
+#: views/elements/developers/actionbar.thtml:51
+msgid "devcp_actionbar_link_newversion"
+msgstr "上传新版本"
+
+#: views/elements/developers/actionbar.thtml:44
+#: views/elements/developers/actionbar.thtml:49
+#: views/developers/dashboard.thtml:73
+msgid "devcp_actionbar_link_stats"
+msgstr "统计信æ¯"
+
+#. %1$s is a filename, e.g. "foo.txt"
+#. %2$s is the extension, e.g. ".txt"
+#. %3$s is a list of valid extensions, like ".png, .jpg, .gif"
+#: controllers/developers_controller.php:1361
+#, fuzzy
+msgid "devcp_add_previews_extension_error"
+msgstr "File %1$s has an invalid extension (%2$s). Allowed extensions: %3$s"
+
+#. %s is the filename.
+#: controllers/developers_controller.php:1394
+#, fuzzy
+msgid "devcp_add_previews_save_error"
+msgstr "File %s could not be saved to the database. Please try again."
+
+#. %1$s is the preview ID number, %2$s is the filename.
+#: controllers/developers_controller.php:1389
+#, fuzzy
+msgid "devcp_add_previews_success_replace"
+msgstr "Preview %1$s was replaced with file %2$s successfully."
+
+#. %s is the filename.
+#: controllers/developers_controller.php:1391
+#, fuzzy
+msgid "devcp_add_previews_success_upload"
+msgstr "File %s was uploaded successfully. You can add a caption below."
+
+#: controllers/components/developers.php:1163
+msgid "devcp_additem_addontype_autodetect"
+msgstr "(自动检测)"
+
+#: views/elements/developers/additem.thtml:76
+msgid "devcp_additem_linktitle_opensin_newwindow"
+msgstr "在新窗å£æ‰“å¼€"
+
+#: views/elements/developers/additem.thtml:41
+msgid "devcp_additem_sidebar_title"
+msgstr "æ交附加组件"
+
+#: views/elements/developers/additem.thtml:53
+msgid "devcp_additem_step0_newlink"
+msgstr "å¼€å‘者授æƒåè®®"
+
+#: views/elements/developers/additem.thtml:46
+msgid "devcp_additem_step1_link"
+msgstr "第一步:上传"
+
+#: views/elements/developers/additem.thtml:47
+msgid "devcp_additem_step2_link"
+msgstr "第二步:附加组件详情"
+
+#: views/elements/developers/additem.thtml:48
+msgid "devcp_additem_step3_link"
+msgstr "第三步:版本详情"
+
+#: views/elements/developers/additem.thtml:49
+msgid "devcp_additem_step4_link"
+msgstr "第四步:本地化"
+
+#: views/elements/developers/additem.thtml:50
+msgid "devcp_additem_step5_link"
+msgstr "第五步:æˆåŠŸ"
+
+#: views/elements/developers/additem.thtml:76
+msgid "devcp_additem_submissionhelp_link"
+msgstr "上传说明"
+
+#: controllers/previews_controller.php:168
+#: controllers/previews_controller.php:277
+msgid "devcp_addon_field_preview_caption_displaytitle"
+msgstr "预览图片说明"
+
+#: views/developers/addon_status.thtml:177
+#, fuzzy
+msgid "devcp_addon_status_action_activate"
+msgstr "Make Active"
+
+#: views/developers/addon_status.thtml:178
+#, fuzzy
+msgid "devcp_addon_status_action_activate_description"
+msgstr ""
+"Make your add-on active for it to show up in public listings and enable the "
+"update check service."
+
+#: views/developers/addon_status.thtml:135
+#, fuzzy
+msgid "devcp_addon_status_action_complete"
+msgstr "Complete Add-on"
+
+#: views/developers/addon_status.thtml:136
+#, fuzzy
+msgid "devcp_addon_status_action_complete_description"
+msgstr "Complete your add-on and move to the Sandbox"
+
+#: views/developers/addon_status.thtml:181
+#, fuzzy
+msgid "devcp_addon_status_action_deactivate"
+msgstr "Make Inactive"
+
+#: views/developers/addon_status.thtml:182
+#, fuzzy
+msgid "devcp_addon_status_action_deactivate_description"
+msgstr ""
+"Make your add-on inactive to hide it from all public listings and disable "
+"the update check service."
+
+#: views/developers/addon_status.thtml:143
+#, fuzzy
+msgid "devcp_addon_status_action_move"
+msgstr "Move to Sandbox"
+
+#: views/developers/addon_status.thtml:144
+#, fuzzy
+msgid "devcp_addon_status_action_move_description"
+msgstr "Move your add-on back to the Sandbox. This is reversible."
+
+#: views/developers/addon_status.thtml:139
+#, fuzzy
+msgid "devcp_addon_status_action_nominate"
+msgstr "Nominate for Public"
+
+#: views/developers/addon_status.thtml:140
+#, fuzzy
+msgid "devcp_addon_status_action_nominate_description"
+msgstr "Nominate your add-on to become Public"
+
+#: views/developers/addon_status.thtml:147
+#, fuzzy
+msgid "devcp_addon_status_action_public"
+msgstr "Make Public"
+
+#: views/developers/addon_status.thtml:148
+#, fuzzy
+msgid "devcp_addon_status_action_public_description"
+msgstr "Make your add-on Public again."
+
+#: views/developers/addon_status.thtml:169
+#, fuzzy
+msgid "devcp_addon_status_active"
+msgstr ""
+"Your add-on is <span class=\"inactive-0\">Active</span>. This means your add-"
+"on is showing up in all available listings appropriate for its status above."
+
+#: views/developers/addon_status.thtml:111
+#, fuzzy
+msgid "devcp_addon_status_completion_disabled"
+msgstr ""
+"Please fulfill the criteria above before you can complete your add-on and "
+"move it to the <span class=\"status-1\">Sandbox</span>."
+
+#: views/developers/addon_status.thtml:108
+#, fuzzy
+msgid "devcp_addon_status_completion_enabled"
+msgstr ""
+"You may now complete your add-on and move it to the <span class=\"status-1"
+"\">Sandbox</span> by clicking the button below."
+
+#: views/developers/addon_status.thtml:102
+#, fuzzy
+msgid "devcp_addon_status_criteria_category"
+msgstr "At least one category selected"
+
+#: views/developers/addon_status.thtml:101
+#, fuzzy
+msgid "devcp_addon_status_criteria_description"
+msgstr "Add-on Description required"
+
+#: views/developers/addon_status.thtml:99
+#, fuzzy
+msgid "devcp_addon_status_criteria_name"
+msgstr "Add-on Name required"
+
+#: views/developers/addon_status.thtml:120
+#, fuzzy
+msgid "devcp_addon_status_criteria_prerelease"
+msgstr "Add-on is not marked as pre-release."
+
+#: views/developers/addon_status.thtml:119
+#, fuzzy
+msgid "devcp_addon_status_criteria_preview"
+msgstr "At least one preview image required for extensions and themes."
+
+#: views/developers/addon_status.thtml:100
+#, fuzzy
+msgid "devcp_addon_status_criteria_summary"
+msgstr "Add-on Summary required"
+
+#. %s is the status in a span, e.g. "<span>_('Public')</span>".
+#: views/developers/addon_status.thtml:58
+#, fuzzy
+msgid "devcp_addon_status_header"
+msgstr "Add-on Status: %s"
+
+#: views/developers/addon_status.thtml:152
+#: views/developers/addon_status.thtml:173
+#, fuzzy
+msgid "devcp_addon_status_header_actions"
+msgstr "Available Actions"
+
+#: views/developers/addon_status.thtml:168
+#, fuzzy
+msgid "devcp_addon_status_header_active"
+msgstr "Active Status: <span class=\"inactive-0\">Active</span>"
+
+#: views/developers/addon_status.thtml:97
+#, fuzzy
+msgid "devcp_addon_status_header_criteria"
+msgstr "Add-on Completion Criteria"
+
+#: views/developers/addon_status.thtml:164
+#, fuzzy
+msgid "devcp_addon_status_header_inactive"
+msgstr "Active Status: <span class=\"inactive-1\">Inactive</span>"
+
+#: views/developers/addon_status.thtml:117
+#, fuzzy
+msgid "devcp_addon_status_header_nomination"
+msgstr "Public Nomination Criteria"
+
+#: views/developers/addon_status.thtml:190
+#, fuzzy
+msgid "devcp_addon_status_header_trusted"
+msgstr "Trusted Status: <span class=\"status-4\">Trusted</span>"
+
+#: views/developers/addon_status.thtml:165
+#, fuzzy
+msgid "devcp_addon_status_inactive"
+msgstr ""
+"Your add-on is <span class=\"inactive-1\">Inactive</span>. This means your "
+"add-on will not show up in any listing, regardless of its status above. "
+"Updates are <b>not</b> being provided to your add-on through the update "
+"check service."
+
+#: views/developers/addon_status.thtml:128
+#, fuzzy
+msgid "devcp_addon_status_nominate_disabled"
+msgstr ""
+"Please fulfill the criteria above before nominating your add-on to become "
+"<span class=\"status-4\">Public</span>."
+
+#: views/developers/addon_status.thtml:125
+#, fuzzy
+msgid "devcp_addon_status_nominate_enabled"
+msgstr ""
+"You may now nominate your add-on for <span class=\"status-4\">Public</span> "
+"by clicking the button below."
+
+#: views/developers/addon_status.thtml:64
+#, fuzzy
+msgid "devcp_addon_status_public"
+msgstr "Public"
+
+#: views/developers/addon_status.thtml:63
+#, fuzzy
+msgid "devcp_addon_status_sandbox"
+msgstr "Sandbox"
+
+#. %s is an email address.
+#: views/developers/addon_status.thtml:89
+#, fuzzy
+msgid "devcp_addon_status_switch_disabled"
+msgstr ""
+"Your add-on was <span class=\"status-5\">Disabled</span> by an administrator "
+"and cannot be used. If you have any questions, please e-mail %s."
+
+#: views/developers/addon_status.thtml:67
+#, fuzzy
+msgid "devcp_addon_status_switch_incomplete"
+msgstr ""
+"Your add-on is currently <span class=\"status-0\">Incomplete</span>. This "
+"means your add-on is not showing up on any portion of the site or update "
+"check service. You may come to this page to complete your add-on after it "
+"meets the criteria below for completion and transfer to the <span class="
+"\"status-1\">Sandbox</span>."
+
+#. %s is a number, perhaps 42.
+#: views/developers/addon_status.thtml:77
+#, fuzzy
+msgid "devcp_addon_status_switch_nominated"
+msgstr ""
+"Your add-on is currently nominated to become <span class=\"status-4"
+"\">Public</span> and is awaiting editor review. There are currently %s other "
+"add-ons in the nomination queue."
+
+#. %s is an email address.
+#: views/developers/addon_status.thtml:81
+#, fuzzy
+msgid "devcp_addon_status_switch_pending"
+msgstr ""
+"Your add-on is pending. This shouldn't have happened. Please e-mail %s with "
+"your add-on ID and state this error."
+
+#: views/developers/addon_status.thtml:85
+#, fuzzy
+msgid "devcp_addon_status_switch_public"
+msgstr ""
+"Your add-on is <span class=\"status-4\">Public</span>, which means it will "
+"show up in all listings and searches and can be downloaded without "
+"restriction. Updates are being provided to your add-on through the update "
+"check service."
+
+#: views/developers/addon_status.thtml:71
+#: views/developers/addon_status.thtml:75
+#, fuzzy
+msgid "devcp_addon_status_switch_sandbox"
+msgstr ""
+"Your add-on is in the <span class=\"status-1\">Sandbox</span>, which means "
+"it will show up in listings and searches, but users must log in to download "
+"it. Updates are <b>not</b> being provided to your add-on through the update "
+"check service."
+
+#. %s is the add-on name.
+#: views/developers/addon_status_nominate.thtml:43
+#: views/developers/addon_status_confirm.thtml:43
+#: views/developers/addon_status.thtml:43
+#, fuzzy
+msgid "devcp_addon_status_title"
+msgstr "%s Status"
+
+#: views/developers/addon_status.thtml:191
+#, fuzzy
+msgid "devcp_addon_status_trusted"
+msgstr ""
+"Your add-on is <span class=\"status-4\">Trusted</span>. This means you can "
+"submit updates to your add-on without editor review."
+
+#: views/developers/dashboard.thtml:68
+#, fuzzy
+msgid "devcp_dashboard_active"
+msgstr "Active"
+
+#. %1$s is the add-on type string
+#. %2$s is Inactive or Active in a <span>
+#. %3$s is the addon's public status (Public, In Sandbox, ...) in a <span>
+#: views/developers/dashboard.thtml:69
+#, fuzzy
+msgid "devcp_dashboard_addontype_status"
+msgstr "%1$s currenty %2$s and %3$s"
+
+#: views/developers/dashboard.thtml:67
+#, fuzzy
+msgid "devcp_dashboard_change_status"
+msgstr "Change Status"
+
+#. %s is the addons email address.
+#: views/developers/dashboard.thtml:99
+#, fuzzy
+msgid "devcp_dashboard_disabled_questions"
+msgstr ""
+"Your add-on was disabled by an administrator and cannot be used. If you "
+"have any questions, please email %s."
+
+#. %s is the (localized) add-on status string in a span, e.g. "Disabled"
+#: views/developers/dashboard.thtml:98
+#, fuzzy
+msgid "devcp_dashboard_disabled_status"
+msgstr "Add-on Status: %s"
+
+#: views/developers/dashboard.thtml:43
+#, fuzzy
+msgid "devcp_dashboard_header_main"
+msgstr "Developer Dashboard"
+
+#: views/developers/dashboard.thtml:110
+#, fuzzy
+msgid "devcp_dashboard_header_welcome"
+msgstr "Welcome to the Developer Dashboard"
+
+#: views/developers/dashboard.thtml:68
+#, fuzzy
+msgid "devcp_dashboard_inactive"
+msgstr "Inactive"
+
+#. %s is a date in the _('date') format
+#: views/developers/dashboard.thtml:65
+#, fuzzy
+msgid "devcp_dashboard_last_edited"
+msgstr "Last edited on %s"
+
+#: views/developers/dashboard.thtml:111
+#, fuzzy
+msgid "devcp_dashboard_learn"
+msgstr ""
+"You don't currently have any add-ons hosted on Mozilla Add-ons. To learn how "
+"the process works and submit your first add-on, click Get Started below."
+
+#: views/developers/dashboard.thtml:112
+#, fuzzy
+msgid "devcp_dashboard_start"
+msgstr "Get Started"
+
+#: views/developers/dashboard.thtml:82
+#, fuzzy
+msgid "devcp_dashboard_versions"
+msgstr "Versions and Files"
+
+#: views/developers/dashboard.thtml:91
+#, fuzzy
+msgid "devcp_dashboard_versions_new"
+msgstr "Upload a new version"
+
+#. %s is the preview ID number.
+#: controllers/developers_controller.php:1415
+#, fuzzy
+msgid "devcp_delete_previews_error"
+msgstr "Preview %s could not be deleted from the database. Please try again."
+
+#. %s is the preview ID number.
+#: controllers/developers_controller.php:1413
+#, fuzzy
+msgid "devcp_delete_previews_success"
+msgstr "Preview %s has been deleted successfully."
+
+#: controllers/developers_controller.php:1089
+#, fuzzy
+msgid "devcp_delete_version_priv_error"
+msgstr "You do not have privileges to delete versions or files."
+
+#. %1$s is the count of files, a number
+#. %2$s is a status string like _('Public') or _('Incomplete')
+#: controllers/components/amo.php:549
+#, fuzzy
+msgid "devcp_describe_version_status"
+msgid_plural "devcp_describe_version_status"
+msgstr[0] "%1$s %2$s file"
+msgstr[1] "%1$s %2$s files"
+
+#. %s is a version number. Example: 3.0
+#: views/developers/versions.thtml:65
+#, php-format
+msgid "devcp_details_version"
+msgstr "版本 %s"
+
+#: views/developers/discuss.thtml:68
+#, fuzzy
+msgid "devcp_discuss_addreply_header"
+msgstr "Add Reply"
+
+#: views/developers/discuss.thtml:57
+#, fuzzy
+msgid "devcp_discuss_allreplies_header"
+msgstr "Replies"
+
+#. notice when an error occurs saving a discussion reply
+#. %1 is the email address (linked) for the amo-editors list
+#: views/developers/discuss.thtml:70
+#, fuzzy
+msgid "devcp_discuss_error_notice"
+msgstr ""
+"There was an error saving your reply. Please contact %1$s about the issue."
+
+#. %1 is the add-on name, %2 is the add-on's version number currently being reviewed by an editor
+#: views/developers/discuss.thtml:46
+#, fuzzy
+msgid "devcp_discuss_intro"
+msgstr ""
+"A Mozilla Add-ons Editor requested further information from you regarding "
+"version %2$s of your add-on %1$s."
+
+#. %1 is the add-on name
+#: views/developers/discuss.thtml:43
+#, fuzzy
+msgid "devcp_discuss_pagetitle"
+msgstr "Provide More Information For the Add-on Review of %1$s"
+
+#. submit button text
+#: views/developers/discuss.thtml:79
+#, fuzzy
+msgid "devcp_discuss_submit_reply"
+msgstr "Submit Reply"
+
+#: views/developers/discuss.thtml:72
+#, fuzzy
+msgid "devcp_discuss_success_message"
+msgstr ""
+"Your reply was successfully saved. The other participants of the discussion "
+"will be notified by email."
+
+#. in an author/editor discussion about an add-on to be reviewed:
+#. %1 is the commenter's user name (linked).
+#. %2 is the full date the comment was made.
+#: views/developers/discuss.thtml:52 views/developers/discuss.thtml:62
+#, fuzzy
+msgid "devcp_discuss_writtenby"
+msgstr "written by %1$s on %2$s"
+
+#: views/developers/addon_edit_authors.thtml:72
+#: views/developers/addon_edit_authors.thtml:81
+#, fuzzy
+msgid "devcp_edit_authors_add_author"
+msgstr "Add New Author"
+
+#: views/developers/addon_edit_authors.thtml:96
+#, fuzzy
+msgid "devcp_edit_authors_add_author_button"
+msgstr "Add Author"
+
+#: views/developers/addon_edit_authors.thtml:83
+#, fuzzy
+msgid "devcp_edit_authors_add_email"
+msgstr "Author Account Email:"
+
+#: views/developers/addon_edit_authors.thtml:98
+#, fuzzy
+msgid "devcp_edit_authors_add_loading"
+msgstr "Checking account email..."
+
+#: views/developers/addon_edit_authors.thtml:70
+#, fuzzy
+msgid "devcp_edit_authors_click_save"
+msgstr "Click the Update Authors button below to save."
+
+#: views/developers/addon_edit_authors.thtml:58
+#, fuzzy
+msgid "devcp_edit_authors_header_current"
+msgstr "Current Authors"
+
+#: views/developers/addon_edit_authors.thtml:50
+#, fuzzy
+msgid "devcp_edit_authors_header_manage"
+msgstr "Manage Add-on Authors"
+
+#: views/developers/addon_edit_authors.thtml:93
+#, fuzzy
+msgid "devcp_edit_authors_label_add_listed"
+msgstr "List as author in pubilc display pages"
+
+#: views/developers/addon_edit_authors.thtml:89
+#, fuzzy
+msgid "devcp_edit_authors_label_developer"
+msgstr ""
+"<strong>Developer</strong> - Can manage all aspects of the add-on listing, "
+"except for adding and removing other authors."
+
+#: views/developers/addon_edit_authors.thtml:88
+#, fuzzy
+msgid "devcp_edit_authors_label_owner"
+msgstr ""
+"<strong>Owner</strong> - Can manage all aspects of the add-on listing, "
+"including adding and removing other authors."
+
+#: views/developers/addon_edit_authors.thtml:90
+#, fuzzy
+msgid "devcp_edit_authors_label_viewer"
+msgstr ""
+"<strong>Viewer</strong> - Can view add-on developer listing and statistics, "
+"but can't make any changes."
+
+#. Placeholder for the empty option in a <select>.
+#: views/developers/addon_edit_categories.thtml:69
+#, fuzzy
+msgid "devcp_edit_authors_option_empty"
+msgstr "----------------"
+
+#: views/developers/addon_edit_authors.thtml:86
+#, fuzzy
+msgid "devcp_edit_authors_select_role"
+msgstr "Select a role for the author:"
+
+#. Column name in a table.
+#: views/developers/addon_edit_authors.thtml:62
+#, fuzzy
+msgid "devcp_edit_authors_th_author"
+msgstr "Author"
+
+#. Column name in a table.
+#: views/developers/addon_edit_authors.thtml:64
+#, fuzzy
+msgid "devcp_edit_authors_th_listed"
+msgstr "Listed"
+
+#. Column name in a table.
+#: views/developers/addon_edit_authors.thtml:63
+#, fuzzy
+msgid "devcp_edit_authors_th_role"
+msgstr "Role"
+
+#: views/developers/addon_edit_authors.thtml:77
+#, fuzzy
+msgid "devcp_edit_authors_update_author"
+msgstr "Update authors"
+
+#: views/developers/addon_edit_categories.thtml:99
+#, fuzzy
+msgid "devcp_edit_categories_button_update"
+msgstr "Update Categories"
+
+#: views/developers/addon_edit_categories.thtml:88
+#, fuzzy
+msgid "devcp_edit_categories_does_not_fit"
+msgstr "My add-on doesn't fit into any available categories."
+
+#. %s is the application name (Firefox, Thunderbird).
+#: views/developers/addon_edit_categories.thtml:61
+#, fuzzy
+msgid "devcp_edit_categories_header_application"
+msgstr "%s Categories"
+
+#: views/developers/addon_edit_categories.thtml:49
+#, fuzzy
+msgid "devcp_edit_categories_header_manage"
+msgstr "Manage Add-on Categories"
+
+#: views/developers/addon_edit_categories.thtml:91
+#, fuzzy
+msgid "devcp_edit_categories_hover"
+msgstr "Hover over a category to see its description."
+
+#. %s is the category number (1, 2, 3).
+#: views/developers/addon_edit_categories.thtml:67
+#, fuzzy
+msgid "devcp_edit_categories_label_category_num"
+msgstr "Category %s"
+
+#: views/developers/addon_edit_categories.thtml:94
+#: views/developers/addon_edit_categories.thtml:103
+#, fuzzy
+msgid "devcp_edit_categories_none_available"
+msgstr "No categories are available for this add-on type and application."
+
+#: views/developers/addon_edit_categories.thtml:86
+#, fuzzy
+msgid "devcp_edit_categories_other"
+msgstr ""
+"Place your add-on into this category only if it does not fit into any other "
+"available categories."
+
+#. %s is the application name (Firefox, Thunderbird).
+#: views/developers/addon_edit_categories.thtml:63
+#, fuzzy
+msgid "devcp_edit_categories_select_application_categories"
+msgstr "Select up to three %s categories for your add-on"
+
+#: views/developers/addon_edit.thtml:47
+#, fuzzy
+msgid "devcp_edit_dd_manage_authors"
+msgstr "Add or remove users that can manage this add-on."
+
+#: views/developers/addon_edit.thtml:49
+#, fuzzy
+msgid "devcp_edit_dd_manage_categories"
+msgstr ""
+"Select the relevant categories for each application your add-on supports."
+
+#: views/developers/addon_edit.thtml:51
+#, fuzzy
+msgid "devcp_edit_dd_manage_description"
+msgstr ""
+"Add and modify translations for your add-on's summary, description, end-user "
+"license, and privacy policy."
+
+#: views/developers/addon_edit.thtml:53
+#, fuzzy
+msgid "devcp_edit_dd_manage_properties"
+msgstr "Change your add-on's name, homepage, icon, and other flags."
+
+#: views/developers/addon_edit_descriptions.thtml:116
+#, fuzzy
+msgid "devcp_edit_description_button_update"
+msgstr "Update Descriptions"
+
+#: views/developers/addon_edit_descriptions.thtml:115
+#, fuzzy
+msgid "devcp_edit_description_correct_error"
+msgstr "Please correct the errors above indicated in red."
+
+#: views/developers/addon_edit_descriptions.thtml:51
+#, fuzzy
+msgid "devcp_edit_descriptions_header"
+msgstr "Edit Add-on Descriptions"
+
+#: views/developers/addon_edit_descriptions.thtml:94
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_comments_description"
+msgstr ""
+"Any information end users may want to know that isn't necessarily applicable "
+"to the add-on summary or description. Common uses include listing known "
+"major bugs, information on how to report bugs, anticipated release date of a "
+"new version, etc."
+
+#: views/developers/addon_edit_descriptions.thtml:93
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_comments_name"
+msgstr "Developer Comments"
+
+#: views/developers/addon_edit_descriptions.thtml:86
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_description_description"
+msgstr ""
+"The description of your add-on is a longer explanation of features, "
+"functionality, and other relevant information. It is displayed under the "
+"summary on the add-on's display page."
+
+#: views/developers/addon_edit_descriptions.thtml:85
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_description_name"
+msgstr "Add-on Description"
+
+#: views/developers/addon_edit_descriptions.thtml:103
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_eula_description"
+msgstr ""
+"If your add-on has an End-User License Agreement (EULA), please enter its "
+"text below. If set below, users will be required to agree to this before "
+"installing your add-on. Please note that a EULA is not the same as a code "
+"license such as GPL or MPL."
+
+#: views/developers/addon_edit_descriptions.thtml:102
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_eula_name"
+msgstr "End-User License Agreement"
+
+#: views/developers/addon_edit_descriptions.thtml:112
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_privacy_description"
+msgstr ""
+"If your add-on has a privacy policy, enter its text here. Your add-on's "
+"display page will display a link to the policy."
+
+#: views/developers/addon_edit_descriptions.thtml:111
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_privacy_name"
+msgstr "Privacy Policy"
+
+#: views/developers/addon_edit_descriptions.thtml:78
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_summary_description"
+msgstr ""
+"The summary is a short explanation of your add-on's basic functionality that "
+"is displayed in search and browse listings, as well as at the top of your "
+"add-on's display page. <strong>Limit of 250 characters.</strong>"
+
+#: views/developers/addon_edit_descriptions.thtml:77
+#, fuzzy
+msgid "devcp_edit_descriptions_transbox_summary_name"
+msgstr "Add-on Summary"
+
+#: views/developers/addon_edit.thtml:46
+#, fuzzy
+msgid "devcp_edit_dt_manage_authors"
+msgstr "Manage Add-on Authors"
+
+#: views/developers/addon_edit.thtml:48
+#, fuzzy
+msgid "devcp_edit_dt_manage_categories"
+msgstr "Manage Add-on Categories"
+
+#: views/developers/addon_edit.thtml:50
+#, fuzzy
+msgid "devcp_edit_dt_manage_descriptions"
+msgstr "Manage Add-on Descriptions"
+
+#: views/developers/addon_edit.thtml:52
+#, fuzzy
+msgid "devcp_edit_dt_manage_properties"
+msgstr "Manage Add-on Properties"
+
+#: views/developers/addon_edit_properties.thtml:170
+msgid "devcp_edit_label_externalsoftware"
+msgstr "这个附加组件需è¦å¤–部软件支æŒã€‚"
+
+#: views/developers/addon_edit_properties.thtml:205
+msgid "devcp_edit_label_locale_disambiguation"
+msgstr "附加本地化信æ¯"
+
+#: views/developers/addon_edit_properties.thtml:168
+msgid "devcp_edit_label_prerelease"
+msgstr "这是一个预å‘布版本"
+
+#: views/developers/addon_edit_properties.thtml:169
+msgid "devcp_edit_label_sitespecific"
+msgstr "这是一个针对特定网站的附加组件"
+
+#: views/developers/addon_edit_properties.thtml:202
+msgid "devcp_edit_label_target_locale"
+msgstr "本地化目标"
+
+#: views/developers/addon_edit_properties.thtml:212
+#, fuzzy
+msgid "devcp_edit_properties_button_update"
+msgstr "Update Properties"
+
+#: views/developers/addon_edit_properties.thtml:198
+#, fuzzy
+msgid "devcp_edit_properties_change_guid"
+msgstr "Only change if you understand all of the consequences."
+
+#: views/developers/addon_edit_properties.thtml:109
+#, fuzzy
+msgid "devcp_edit_properties_current_icon"
+msgstr "Current Icon"
+
+#: views/developers/addon_edit_properties.thtml:85
+#, fuzzy
+msgid "devcp_edit_properties_default_locale"
+msgstr ""
+"An add-on's default locale is the main locale in which translations must be "
+"present. If translations for your add-on's descriptions are unavailable in a "
+"user's selected language, they will fall back to this default locale."
+
+#: views/developers/addon_edit_properties.thtml:167
+#, fuzzy
+msgid "devcp_edit_properties_flags"
+msgstr "These flags are used to filter and classify add-ons."
+
+#: views/developers/addon_edit_properties.thtml:174
+#, fuzzy
+msgid "devcp_edit_properties_guid"
+msgstr ""
+"The GUID of your add-on is specified in its install.rdf and uniquely "
+"identifies it. You cannot change your GUID once it is listed on Mozilla Add-"
+"ons."
+
+#: views/developers/addon_edit_properties.thtml:53
+#, fuzzy
+msgid "devcp_edit_properties_header"
+msgstr "Edit Add-on Properties"
+
+#: views/developers/addon_edit_properties.thtml:186
+#, fuzzy
+msgid "devcp_edit_properties_header_addon_type"
+msgstr "Add-on Type"
+
+#: views/developers/addon_edit_properties.thtml:181
+#, fuzzy
+msgid "devcp_edit_properties_header_admin_settings"
+msgstr "Admin Settings"
+
+#: views/developers/addon_edit_properties.thtml:84
+#, fuzzy
+msgid "devcp_edit_properties_header_default_locale"
+msgstr "Default Locale"
+
+#: views/developers/addon_edit_properties.thtml:166
+#, fuzzy
+msgid "devcp_edit_properties_header_flags"
+msgstr "Add-on Flags"
+
+#: views/developers/addon_edit_properties.thtml:173
+#: views/developers/addon_edit_properties.thtml:197
+#, fuzzy
+msgid "devcp_edit_properties_header_guid"
+msgstr "Add-on GUID"
+
+#: views/developers/addon_edit_properties.thtml:104
+#, fuzzy
+msgid "devcp_edit_properties_header_icon"
+msgstr "Add-on Icon"
+
+#: views/developers/addon_edit_properties.thtml:159
+#, fuzzy
+msgid "devcp_edit_properties_header_other_settings"
+msgstr "Other Settings"
+
+#. A header on the admin page to toggle trusted status.
+#: views/developers/addon_edit_properties.thtml:182
+#, fuzzy
+msgid "devcp_edit_properties_header_trusted"
+msgstr "Trusted Add-on?"
+
+#: views/developers/addon_edit_properties.thtml:160
+#, fuzzy
+msgid "devcp_edit_properties_header_view_source"
+msgstr "View Source Online"
+
+#. %s is a comma-separated list of image extensions ".png, .jpg"
+#: views/developers/addon_edit_properties.thtml:106
+#, fuzzy
+msgid "devcp_edit_properties_icon"
+msgstr ""
+"The add-on icon is a small image that is displayed next to your add-on's "
+"name in browse and search results, display pages, and in the add-on "
+"installation dialog. The image will automatically be resized to 32 x 32 "
+"pixels. Please use one of the following image types: %s"
+
+#: views/developers/addon_edit_properties.thtml:171
+#, fuzzy
+msgid "devcp_edit_properties_label_binary"
+msgstr "This add-on contains binary components"
+
+#: views/developers/addon_edit_properties.thtml:185
+#, fuzzy
+msgid "devcp_edit_properties_label_not_trusted"
+msgstr "Not Trusted"
+
+#: views/developers/addon_edit_properties.thtml:184
+#, fuzzy
+msgid "devcp_edit_properties_label_trusted"
+msgstr "Trusted"
+
+#: views/developers/addon_edit_properties.thtml:110
+#, fuzzy
+msgid "devcp_edit_properties_new_icon"
+msgstr "New Icon"
+
+#: views/developers/addon_edit_properties.thtml:118
+#, fuzzy
+msgid "devcp_edit_properties_remove_icon"
+msgstr "Remove Icon"
+
+#: views/developers/addon_edit_properties.thtml:136
+#, fuzzy
+msgid "devcp_edit_properties_transbox_homepage_description"
+msgstr ""
+"If your add-on has another homepage, enter its address here. Adding other "
+"translations is not necessary unless your website is localized into other "
+"languages."
+
+#: views/developers/addon_edit_properties.thtml:135
+#, fuzzy
+msgid "devcp_edit_properties_transbox_homepage_name"
+msgstr "Add-on Homepage"
+
+#: views/developers/addon_edit_properties.thtml:79
+#, fuzzy
+msgid "devcp_edit_properties_transbox_name_description"
+msgstr "The name of your add-on is displayed everywhere your add-on is listed."
+
+#: views/developers/addon_edit_properties.thtml:78
+#, fuzzy
+msgid "devcp_edit_properties_transbox_name_name"
+msgstr "Add-on Name"
+
+#: views/developers/addon_edit_properties.thtml:145
+#, fuzzy
+msgid "devcp_edit_properties_transbox_supportemail_description"
+msgstr ""
+"If you have an email address for support inquiries, enter it here. Adding "
+"other translations is not necessary unless you have different email "
+"addresses for different languages."
+
+#: views/developers/addon_edit_properties.thtml:144
+#, fuzzy
+msgid "devcp_edit_properties_transbox_supportemail_name"
+msgstr "Support Email Address"
+
+#: views/developers/addon_edit_properties.thtml:154
+#, fuzzy
+msgid "devcp_edit_properties_transbox_supporturl_description"
+msgstr ""
+"If your add-on has a support website or forum, enter its address here. "
+"Adding other translations is not necessary unless your website is localized "
+"into other languages."
+
+#: views/developers/addon_edit_properties.thtml:153
+#, fuzzy
+msgid "devcp_edit_properties_transbox_supporturl_name"
+msgstr "Support Website"
+
+#: views/developers/addon_edit_properties.thtml:183
+#, fuzzy
+msgid "devcp_edit_properties_trusted"
+msgstr "Trusted add-ons can become public without Editor review."
+
+#. %s is href="..." and should stay in the <a> tag.
+#: views/developers/addon_edit_properties.thtml:119
+#, fuzzy
+msgid "devcp_edit_properties_undelete"
+msgstr "Icon will be deleted on save. <a %s>Cancel?</a>"
+
+#: views/developers/addon_edit_properties.thtml:161
+#, fuzzy
+msgid "devcp_edit_properties_view_source"
+msgstr ""
+"The source of your add-on files can be viewed online by any logged in user "
+"if you wish."
+
+#: views/developers/addon_edit_properties.thtml:162
+#, fuzzy
+msgid "devcp_edit_properties_view_source_allow"
+msgstr "Allow online source viewing"
+
+#: views/developers/addon_edit_properties.thtml:163
+#, fuzzy
+msgid "devcp_edit_properties_view_source_do_not_allow"
+msgstr "Do not allow online source viewing"
+
+#: views/elements/developers/editbox.thtml:46
+#, fuzzy
+msgid "devcp_editbox_authors"
+msgstr "Authors"
+
+#: views/elements/developers/editbox.thtml:47
+#, fuzzy
+msgid "devcp_editbox_categories"
+msgstr "Categories"
+
+#: views/elements/developers/editbox.thtml:52
+#, fuzzy
+msgid "devcp_editbox_change_status"
+msgstr "Change Status"
+
+#: views/elements/developers/editbox.thtml:48
+#, fuzzy
+msgid "devcp_editbox_descriptions"
+msgstr "Descriptions"
+
+#: views/elements/developers/editbox.thtml:43
+#, fuzzy
+msgid "devcp_editbox_edit_addon"
+msgstr "Edit Add-on"
+
+#: views/elements/developers/editbox.thtml:57
+#, fuzzy
+msgid "devcp_editbox_new_version"
+msgstr "New Version"
+
+#: views/elements/developers/editbox.thtml:49
+#, fuzzy
+msgid "devcp_editbox_properties"
+msgstr "Properties"
+
+#: views/elements/developers/editbox.thtml:60
+#, fuzzy
+msgid "devcp_editbox_screenshots"
+msgstr "Preview Screenshots"
+
+#: views/elements/developers/editbox.thtml:53
+#, fuzzy
+msgid "devcp_editbox_statistics_dashboard"
+msgstr "Statistics Dashboard"
+
+#: views/elements/developers/editbox.thtml:54
+#, fuzzy
+msgid "devcp_editbox_versions"
+msgstr "Versions and Files"
+
+#: views/elements/developers/editbox.thtml:42
+#, fuzzy
+msgid "devcp_editbox_view_listing"
+msgstr "View Listing"
+
+#: views/elements/developers/editorsmenu.thtml:59
+msgid "devcp_editorsqueue_featured"
+msgstr "特定的附加组件"
+
+# %1 is the review count
+#. %1 is the review count
+#: views/elements/developers/editorsqueue.thtml:42
+#: views/elements/developers/editorsmenu.thtml:56
+#, php-format
+msgid "devcp_editorsqueue_moderatedreviews"
+msgid_plural "devcp_editorsqueue_moderatedreviews"
+msgstr[0] "待审查æ„è§ (%s)"
+msgstr[1] "待审查æ„è§ (%s)"
+
+# %1 is the nominated addons count
+#. %1 is the nominated addons count
+#: views/elements/developers/editorsqueue.thtml:44
+#: views/elements/developers/editorsmenu.thtml:58
+#, php-format
+msgid "devcp_editorsqueue_nominated"
+msgid_plural "devcp_editorsqueue_nominated"
+msgstr[0] "æ请审查的附加组件 (%s)"
+msgstr[1] "æ请审查的附加组件 (%s)"
+
+# %1 is the update count
+#. %1 is the update count
+#: views/elements/developers/editorsqueue.thtml:43
+#: views/elements/developers/editorsmenu.thtml:57
+#, php-format
+msgid "devcp_editorsqueue_pendingupdates"
+msgid_plural "devcp_editorsqueue_pendingupdates"
+msgstr[0] "待审查更新 (%s)"
+msgstr[1] "待审查更新 (%s)"
+
+#: controllers/statistics_controller.php:147
+#: controllers/statistics_controller.php:361
+#: controllers/previews_controller.php:108
+#: controllers/previews_controller.php:211
+#: controllers/previews_controller.php:312
+msgid "devcp_error_addon_access_denied"
+msgstr "æ— æƒè®¿é—®è¯¥é™„加组件。"
+
+#. %s is a complete URL with the text from devcp_error_appversion_reference_link_text
+#. in the <a> tag. This should be fixed.
+#: controllers/components/developers.php:591
+#, php-format
+msgid "devcp_error_appversion_reference_link"
+msgstr "相关说明请查阅 %s 。"
+
+#. This is the link text in the <a> for devcp_error_appversion_reference_link. This
+#. should be fixed.
+#: controllers/components/developers.php:591
+msgid "devcp_error_appversion_reference_link_text"
+msgstr "本页"
+
+#: views/developers/addon_edit_authors.thtml:76
+#, fuzzy
+msgid "devcp_error_empty_authors"
+msgstr "Your add-on must have at least one owner."
+
+#. %1$s is the name of the file
+#: controllers/components/developers.php:658
+#, fuzzy
+msgid "devcp_error_file_exists"
+msgstr ""
+"A version of that addon already exists. To replace it, you must delete the "
+"file %1$s first."
+
+#. %1$s is a file extension. Example: .exe
+#. %2$s is a comma separated list of extensions. Example: .xpi, .jar
+#: controllers/components/developers.php:355
+#, php-format
+msgid "devcp_error_file_extension"
+msgstr "选定的附加组件ç§ç±»ä¸å…许这个文件扩展å(%s),请使用下列扩展å之一:%s"
+
+#: controllers/components/developers.php:64
+msgid "devcp_error_five_categories"
+msgstr "请ä¸è¦é€‰æ‹©å¤šäºŽäº”个分类。"
+
+#: controllers/components/developers.php:526
+msgid "devcp_error_guid_application"
+msgstr "这个附加组件的IDå·²ç»è¢«å…¶ä»–应用程åºä½¿ç”¨ã€‚"
+
+#: controllers/components/developers.php:337
+#: controllers/components/developers.php:389
+msgid "devcp_error_http_incomplete"
+msgstr "传输未完æˆã€‚"
+
+#: controllers/components/developers.php:335
+#: controllers/components/developers.php:336
+#: controllers/components/developers.php:387
+#: controllers/components/developers.php:388
+msgid "devcp_error_http_maxupload"
+msgstr "超过许å¯çš„最大上传体积。"
+
+#: controllers/components/developers.php:338
+#: controllers/components/developers.php:390
+msgid "devcp_error_http_nofile"
+msgstr "未上传文件"
+
+#. %1$s is a file extension. Example: .exe
+#. %2$s is a comma separated list of extensions. Example: .xpi, .jar
+#: controllers/components/developers.php:401
+#, php-format
+msgid "devcp_error_icon_extension"
+msgstr "图标ä¸èƒ½ä½¿ç”¨è¿™ä¸ªæ–‡ä»¶æ‰©å±•å(%s)。请选用下列扩展å之一:%s"
+
+#: controllers/developers_controller.php:504
+msgid "devcp_error_index_rdf_notfound"
+msgstr "install.rdf 文件ä¸å­˜åœ¨ã€‚"
+
+#: controllers/components/developers.php:601
+msgid "devcp_error_install_manifest"
+msgstr "install.rdf 中å‘现以下错误:"
+
+#: controllers/developers_controller.php:1463
+msgid "devcp_error_invalid_addontype"
+msgstr "请选择一个有效的附加组件类型。"
+
+#. %$1s is a version. Example: 3.1.1
+#. %$2s is an add-on name.
+#: controllers/components/developers.php:569
+#: controllers/components/developers.php:581
+#, php-format
+msgid "devcp_error_invalid_appversion"
+msgstr "%s ä¸æ˜¯ %s 的有效版本"
+
+#. %s is a string
+#: controllers/components/developers.php:521
+#, php-format
+msgid "devcp_error_invalid_guid"
+msgstr "这个附加组件的ID无效:%s"
+
+#. %$1s is a version. Example: 3.1.1
+#. %$2s is an add-on name.
+#: controllers/components/developers.php:572
+#, php-format
+msgid "devcp_error_invalid_minversion"
+msgstr "%s ä¸æ˜¯ %s 的有效版本: 最å°ç‰ˆæœ¬ä¸èƒ½åŒ…å« *"
+
+#: controllers/components/developers.php:536
+msgid "devcp_error_invalid_version"
+msgstr ""
+"该附加组件的这个版本无法使用:请查阅 <a href=\"http://developer.mozilla.org/"
+"cn/docs/%E7%89%88%E6%9C%AC%E6%A0%BC%E5%BC%8F%E8%AF%B4%E6%98%8E\">版本格å¼è¯´æ˜Ž"
+"</a>"
+
+#: controllers/components/developers.php:531
+msgid "devcp_error_invalid_version_spaces"
+msgstr "这个附加组件的版本无效:版本中ä¸èƒ½åŒ…å«ç©ºæ ¼ã€‚"
+
+#. %s is an error message from the parser.
+#: controllers/components/developers.php:501
+#, php-format
+msgid "devcp_error_manifest_parse"
+msgstr "è§£æž install.rdf æ—¶å‘生以下错误: %s"
+
+#: controllers/components/developers.php:373
+msgid "devcp_error_move_file"
+msgstr "无法移动文件"
+
+#. %s is the name of a file
+#: controllers/components/developers.php:650
+#: controllers/components/developers.php:662
+#: controllers/components/developers.php:667
+#: controllers/components/developers.php:727
+#: controllers/components/developers.php:738
+#: controllers/components/developers.php:743
+#, php-format
+msgid "devcp_error_moving_file"
+msgstr "移动 %s æ—¶å‘生错误。"
+
+#: controllers/components/developers.php:595
+msgid "devcp_error_mozilla_application"
+msgstr "至少è¦æœ‰ä¸€ä¸ªå¯ç”¨çš„Mozilla目标应用程åºã€‚"
+
+#: controllers/components/developers.php:516
+msgid "devcp_error_no_guid"
+msgstr "install.rdf 中未找到这个附加组件的ID。"
+
+#: controllers/components/developers.php:287
+msgid "devcp_error_no_platform"
+msgstr "未选择系统平å°ã€‚"
+
+#: controllers/components/developers.php:59
+msgid "devcp_error_one_category"
+msgstr "请至少选择一个分类。"
+
+#: controllers/components/developers.php:92
+msgid "devcp_error_one_user"
+msgstr "这个附加组件至少è¦æœ‰ä¸€ä¸ªä½œè€…。"
+
+#. %1$s is a file extension. Example: .exe
+#. %2$s is a comma separated list of extensions. Example: .xpi, .jar
+#: controllers/components/developers.php:1081
+#, php-format
+msgid "devcp_error_preview_extension"
+msgstr "该文件类型 (%s) ä¸èƒ½ä½œä¸ºé¢„览图片。请使用以下格å¼ä¹‹ä¸€ï¼š %s"
+
+#: controllers/components/developers.php:511
+msgid "devcp_error_updatekey"
+msgstr "附加组件无法使用一个 updateKey。请从 install.rdf 中删除它并å†æ¬¡å°è¯•ã€‚"
+
+#: controllers/components/developers.php:506
+msgid "devcp_error_updateurl"
+msgstr ""
+"附加组件ä¸èƒ½ä½¿ç”¨ä¸€ä¸ªå¤–部的更新地å€ï¼Œè¯·ä»Ž install.rdf 中删除它并å†æ¬¡å°è¯•ã€‚"
+
+#: controllers/developers_controller.php:465
+#: controllers/components/developers.php:271
+msgid "devcp_error_upload_file"
+msgstr "请上传一个文件。"
+
+#: views/developers/uploader.thtml:135
+#, fuzzy
+msgid "devcp_input_upload_file"
+msgstr "Upload File"
+
+#: views/pages/js_constants.js.thtml:89
+#, fuzzy
+msgid "devcp_js_a_cancel"
+msgstr "Cancel"
+
+#: views/pages/js_constants.js.thtml:90
+#, fuzzy
+msgid "devcp_js_add_email"
+msgstr "Please enter the account email of the author you wish to add."
+
+#. alt text for a down-arrow image.
+#: views/pages/js_constants.js.thtml:81
+#, fuzzy
+msgid "devcp_js_img_move_down"
+msgstr "Move Down"
+
+#. alt text for an up-arrow image.
+#: views/pages/js_constants.js.thtml:82
+#, fuzzy
+msgid "devcp_js_img_move_up"
+msgstr "Move Up"
+
+#: views/pages/js_constants.js.thtml:91
+#, fuzzy
+msgid "devcp_js_img_remove_compat"
+msgstr "Remove Application Compatibility"
+
+#: views/pages/js_constants.js.thtml:86
+#, fuzzy
+msgid "devcp_js_input_list_author"
+msgstr "List as author in public listings"
+
+#: views/pages/js_constants.js.thtml:92
+#, fuzzy
+msgid "devcp_js_license_select"
+msgstr "Please select a license."
+
+#: views/pages/js_constants.js.thtml:93
+#, fuzzy
+msgid "devcp_js_license_text"
+msgstr "Please enter text for your license."
+
+#. <option> text in a <select> for Author role in an add-on.
+#: views/pages/js_constants.js.thtml:84
+#, fuzzy
+msgid "devcp_js_option_developer"
+msgstr "Developer"
+
+#. <option> text in a <select> for Author role in an add-on.
+#: views/pages/js_constants.js.thtml:83
+#, fuzzy
+msgid "devcp_js_option_owner"
+msgstr "Owner"
+
+#. <option> text in a <select> for Author role in an add-on.
+#: views/pages/js_constants.js.thtml:85
+#, fuzzy
+msgid "devcp_js_option_viewer"
+msgstr "Viewer"
+
+#: views/pages/js_constants.js.thtml:88
+#, fuzzy
+msgid "devcp_js_remove_author"
+msgstr "Remove Author"
+
+#: views/pages/js_constants.js.thtml:87
+#, fuzzy
+msgid "devcp_js_sure_remove"
+msgstr "Are you <strong>sure</strong> you wish to remove this author?"
+
+#: views/pages/js_constants.js.thtml:77
+#, fuzzy
+msgid "devcp_js_upload_alert"
+msgstr "You must select a file to upload."
+
+#. %1$s is an addon id, like 32.
+#. %2$s is a version number, like 3.5.
+#: controllers/components/developers.php:1212
+#, fuzzy
+msgid "devcp_license_existing"
+msgstr "Custom license for add-on %1$s v%2$s"
+
+#: views/elements/developers/localebox.thtml:44
+msgid "devcp_localebox_header_localizedfields"
+msgstr "本地化字段"
+
+# %1 is the default locale
+#. %1 is the default locale
+#: views/elements/developers/localebox.thtml:48
+#, php-format
+msgid "devcp_localebox_intro"
+msgstr ""
+"本页的æŸäº›å­—段已ç»è¿›è¡Œäº†æœ¬åœ°åŒ–,以便按照最终用户的æ¯è¯­æ˜¾ç¤ºã€‚从下é¢é€‰æ‹©ä¸€ç§è¯­"
+"言编写你的附加组件详情。如果æŸç§è¯­è¨€çš„翻译ä¸å¯ç”¨ï¼Œå°†ä¼šè¿”回选定的默认语言(%"
+"s)。"
+
+#: views/elements/developers/sidebar.thtml:68
+#: views/elements/developers/myaddons.thtml:75
+msgid "devcp_myaddons_admincp_link"
+msgstr "管ç†å·¥å…·"
+
+#: views/elements/developers/sidebar.thtml:65
+#: views/elements/developers/myaddons.thtml:72
+msgid "devcp_myaddons_editorcp_link"
+msgstr "编辑工具"
+
+#: views/elements/developers/myaddons.thtml:52
+msgid "devcp_myaddons_link"
+msgstr "我的附加组件"
+
+#: views/elements/developers/sidebar.thtml:70
+#: views/elements/developers/myaddons.thtml:77
+msgid "devcp_myaddons_mainpage_link"
+msgstr "返回主界é¢"
+
+#: views/elements/developers/sidebar.thtml:63
+#: views/elements/developers/myaddons.thtml:70
+msgid "devcp_myaddons_statistics_link"
+msgstr "统计信æ¯"
+
+#: views/elements/developers/sidebar.thtml:62
+#: views/elements/developers/myaddons.thtml:69
+msgid "devcp_myaddons_submitaddon_link"
+msgstr "æ交附加组件"
+
+#: views/elements/developers/sidebar.thtml:48
+#: views/elements/developers/myaddons.thtml:67
+msgid "devcp_myaddons_title"
+msgstr "å¼€å‘者工具"
+
+#. %1$s is an add-on ID, perhaps 167.
+#. %2$s is a URL.
+#: controllers/developers_controller.php:256
+#, fuzzy
+msgid "devcp_new_addon_error"
+msgstr ""
+"This add-on ID (%1$s) already exists in the database. If this is your add-"
+"on, you can <a href=\"%2$s\">upload a new version</a>."
+
+#: views/developers/addon_status_nominate.thtml:62
+#, fuzzy
+msgid "devcp_nominate_cancel"
+msgstr "Cancel and return"
+
+# %1 is the addon name
+#. %1 is the add-on name
+#: views/developers/addon_status_nominate.thtml:61
+#, php-format
+msgid "devcp_nominate_submit_nominate"
+msgstr "æ请审核 %s"
+
+#: views/developers/addon_edit_properties.thtml:50
+#: views/developers/addon_status.thtml:49
+#: views/developers/versions_edit.thtml:50
+#, fuzzy
+msgid "devcp_notice_changes_error"
+msgstr ""
+"<span>One or more of your changes couldn't be saved.</span><br />Please look "
+"for the errors below. The rest of your changes were successfully saved."
+
+#: views/developers/addon_edit_authors.thtml:47
+#: views/developers/addon_edit_properties.thtml:47
+#: views/developers/addon_status.thtml:46
+#: views/developers/addon_edit_descriptions.thtml:47
+#: views/developers/versions_edit.thtml:47
+#: views/developers/addon_edit_categories.thtml:46
+#, fuzzy
+msgid "devcp_notice_changes_saved"
+msgstr ""
+"<span>Your changes have been saved.</span><br />Please note that some "
+"changes may take several hours to appear in all areas of the website."
+
+#: controllers/previews_controller.php:252
+msgid "devcp_notice_cleardefault"
+msgstr "删除该预览图片将会使其他预览图片自动å˜æˆé»˜è®¤çš„。"
+
+#: controllers/previews_controller.php:184
+#: controllers/previews_controller.php:251
+msgid "devcp_notice_makedefault"
+msgstr "这样åšé»˜è®¤çš„预览图片将会去掉默认状æ€ã€‚"
+
+#: views/developers/addon_edit_authors.thtml:70
+#, fuzzy
+msgid "devcp_notice_unsaved_changes"
+msgstr "You have unsaved changes."
+
+#: controllers/developers_controller.php:87
+#: controllers/developers_controller.php:97
+#: controllers/developers_controller.php:100
+#: controllers/previews_controller.php:67
+#: controllers/previews_controller.php:79
+#: controllers/previews_controller.php:82
+msgid "devcp_pagetitle"
+msgstr "å¼€å‘者工具"
+
+#: controllers/previews_controller.php:103
+#: controllers/previews_controller.php:104
+msgid "devcp_preview_add_pagetitle"
+msgstr "增加预览图片"
+
+#: controllers/previews_controller.php:135
+msgid "devcp_preview_added_successfully"
+msgstr "增加预览图片æˆåŠŸã€‚"
+
+#: controllers/previews_controller.php:323
+msgid "devcp_preview_deleted_successfully"
+msgstr "删除预览图片æˆåŠŸã€‚"
+
+#: controllers/previews_controller.php:194
+#: controllers/previews_controller.php:195
+msgid "devcp_preview_edit_pagetitle"
+msgstr "编辑预览图片。"
+
+#: controllers/previews_controller.php:237
+msgid "devcp_preview_updated_successfully"
+msgstr "预览图片更新æˆåŠŸã€‚"
+
+#: views/developers/previews.thtml:120
+#, fuzzy
+msgid "devcp_previews_a_another"
+msgstr "Add Another Preview"
+
+#: views/developers/previews.thtml:96
+#, fuzzy
+msgid "devcp_previews_a_delete"
+msgstr "Delete Preview"
+
+#: views/developers/previews.thtml:95
+#, fuzzy
+msgid "devcp_previews_a_replace"
+msgstr "Replace Preview"
+
+#: views/developers/previews.thtml:126
+#, fuzzy
+msgid "devcp_previews_a_update"
+msgstr "Update Previews"
+
+#: views/developers/previews.thtml:115 views/developers/previews.thtml:124
+#, fuzzy
+msgid "devcp_previews_add_new"
+msgstr "Add New Preview"
+
+#. %s is a list of file extensions, e.g. ".png, .gif"
+#: views/developers/previews.thtml:116
+#, fuzzy
+msgid "devcp_previews_add_select"
+msgstr ""
+"Select an image to upload below. Images larger than the maximum size of 700 "
+"pixels wide by 525 pixels tall will be resized. Allowed file types: %s"
+
+#: views/developers/previews.thtml:121
+#, fuzzy
+msgid "devcp_previews_click_below"
+msgstr "Click Update Previews below to upload."
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/previews.thtml:102
+#, fuzzy
+msgid "devcp_previews_click_update"
+msgstr ""
+"Click the Update Previews button below to save this image. (<a %s>Cancel?</"
+"a>)"
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/previews.thtml:107
+#, fuzzy
+msgid "devcp_previews_error_message"
+msgstr ""
+"This preview will be deleted when Update Previews is clicked below. (<a %"
+"s>Cancel?</a>)"
+
+#: views/previews/add.thtml:45
+msgid "devcp_previews_filetype_info"
+msgstr ""
+"通过下é¢çš„表å•ä½ä½ çš„附加组件上传PNG,JPG或者GIFæ ¼å¼çš„å±å¹•æˆªå›¾ã€‚如果图片宽度大"
+"于700åƒç´ æˆ–者高度大于525åƒç´ åˆ™ä¼šè¢«è‡ªåŠ¨è°ƒæ•´å¤§å°ã€‚"
+
+#: views/previews/add.thtml:43
+msgid "devcp_previews_header_add"
+msgstr "增加预览图片"
+
+#: views/developers/previews.thtml:80
+#, fuzzy
+msgid "devcp_previews_header_caption"
+msgstr "Preview Caption"
+
+#: views/previews/edit.thtml:43
+msgid "devcp_previews_header_edit"
+msgstr "编辑预览图片"
+
+#: views/developers/previews.thtml:93
+#, fuzzy
+msgid "devcp_previews_label_default"
+msgstr "Default Preview"
+
+#: views/previews/add.thtml:54
+msgid "devcp_previews_label_file"
+msgstr "预览图片文件"
+
+#: views/previews/add.thtml:59 views/previews/edit.thtml:50
+msgid "devcp_previews_label_makedefault"
+msgstr "设置为默认预览图片"
+
+#: views/developers/previews.thtml:100
+#, fuzzy
+msgid "devcp_previews_label_new"
+msgstr "New image:"
+
+#: views/developers/previews.thtml:118
+#, fuzzy
+msgid "devcp_previews_label_upload"
+msgstr "Upload Preview: "
+
+#: views/developers/previews.thtml:50
+#, fuzzy
+msgid "devcp_previews_notice_error"
+msgstr "One or more of your new previews could not be saved."
+
+#: views/developers/previews.thtml:47
+#, fuzzy
+msgid "devcp_previews_notice_success"
+msgstr "Your previews have been updated successfully."
+
+#: views/developers/previews.thtml:59
+#, fuzzy
+msgid "devcp_previews_p_screenshots"
+msgstr ""
+"The preview screenshots for your add-on are shown below. You can make "
+"changes to captions or images below. The Default Preview is the preview that "
+"is displayed next to your add-on in search and browse listings."
+
+#: views/previews/edit.thtml:55
+msgid "devcp_previews_submit_delete"
+msgstr "删除预览图片"
+
+#: views/previews/edit.thtml:55
+msgid "devcp_previews_submit_delete_confirm"
+msgstr "你确认è¦åˆ é™¤è¯¥é¢„览图片?"
+
+#: views/previews/edit.thtml:54
+msgid "devcp_previews_submit_edit"
+msgstr "编辑预览图片"
+
+#: views/previews/add.thtml:63
+msgid "devcp_previews_submit_upload"
+msgstr "上传预览图片"
+
+#: views/developers/previews.thtml:78
+#, fuzzy
+msgid "devcp_previews_thumbnail"
+msgstr "Thumbnail"
+
+#. %s is the add-on name.
+#: views/developers/previews.thtml:44
+#, fuzzy
+msgid "devcp_previews_title"
+msgstr "%s Preview Manager"
+
+#: views/developers/uploader.thtml:74
+msgid "devcp_review_agreement_please"
+msgstr "处ç†å‰è¯·å®¡é˜…并接å—以下的开å‘者许å¯å议。"
+
+#: views/elements/developers/rolecheck.thtml:42
+#, fuzzy
+msgid "devcp_rolecheck_no_privs"
+msgstr ""
+"<span>You do not have sufficient privileges to make changes on this page.</"
+"span><br />Contact the Add-on Owner if you need to make changes."
+
+#: controllers/developers_controller.php:1315
+#, fuzzy
+msgid "devcp_several_hours"
+msgstr ""
+"Please note that some changes may take several hours to appear in all areas "
+"of the website."
+
+#: views/elements/developers/sidebar.thtml:52
+#, fuzzy
+msgid "devcp_sidebar_a_dashboard"
+msgstr "Dashboard"
+
+#. %s is a number
+#: views/elements/developers/statsbar.thtml:45
+#: views/developers/dashboard.thtml:79
+#, php-format
+msgid "devcp_statsbar_adu"
+msgstr "<em>%s</em> æ¯æ—¥æ´»åŠ¨ç”¨æˆ·"
+
+#. %s is a number
+#: views/elements/developers/statsbar.thtml:41
+#: views/developers/dashboard.thtml:75
+#, php-format
+msgid "devcp_statsbar_total_downloads"
+msgstr "总计下载 <em>%s</em> 次"
+
+#. %s is a number
+#: views/elements/developers/statsbar.thtml:43
+#: views/developers/dashboard.thtml:77
+#, php-format
+msgid "devcp_statsbar_weekly_downloads"
+msgstr "本周下载 <em>%s</em> 次"
+
+#: views/developers/addon_status_confirm.thtml:59
+#, fuzzy
+msgid "devcp_status_confirm_active"
+msgstr ""
+"Marking this add-on active will cause it to show up in public areas "
+"appropriate for its status, including search and browse listings. It will be "
+"downloadable from the website and could be returned in client update checks, "
+"depending on its status. You will be able to return here and disable it "
+"again at your convenience."
+
+#: views/developers/addon_status_confirm.thtml:59
+#, fuzzy
+msgid "devcp_status_confirm_active_sure"
+msgstr "Are you sure you wish to mark this add-on active?"
+
+#: views/developers/addon_status_confirm.thtml:50
+#, fuzzy
+msgid "devcp_status_confirm_header_sure"
+msgstr "Are you sure?"
+
+#: views/developers/addon_status_confirm.thtml:55
+#, fuzzy
+msgid "devcp_status_confirm_inactive"
+msgstr ""
+"Marking this add-on inactive will prevent it from showing up in any public "
+"areas, including search and browse listings. It will not be downloadable "
+"from the website and will not be returned in client update checks. You will "
+"be able to return here and re-enable it at your convenience."
+
+#: views/developers/addon_status_confirm.thtml:55
+#, fuzzy
+msgid "devcp_status_confirm_inactive_sure"
+msgstr "Are you sure you wish to mark this add-on inactive?'"
+
+#: views/developers/addon_status_confirm.thtml:74
+#, fuzzy
+msgid "devcp_status_confirm_no"
+msgstr "No, cancel"
+
+#: views/developers/addon_status_confirm.thtml:67
+#, fuzzy
+msgid "devcp_status_confirm_public"
+msgstr ""
+"Making this add-on public will make it available for anyone to download and "
+"will begin offering updates to existing users."
+
+#: views/developers/addon_status_confirm.thtml:67
+#, fuzzy
+msgid "devcp_status_confirm_public_sure"
+msgstr "Are you sure you wish to make this add-on public?"
+
+#: views/developers/addon_status_confirm.thtml:63
+#, fuzzy
+msgid "devcp_status_confirm_sandbox"
+msgstr ""
+"Moving this add-on back to the sandbox will require users to login before "
+"downloading and updates will no longer be offered to existing users. Because "
+"your add-on is currently public, you will be able to return here at any time "
+"to make it public again."
+
+#: views/developers/addon_status_confirm.thtml:63
+#, fuzzy
+msgid "devcp_status_confirm_sandbox_sure"
+msgstr "Are you sure you wish to move this add-on to the sandbox?"
+
+#: views/developers/addon_status_confirm.thtml:73
+#, fuzzy
+msgid "devcp_status_confirm_yes"
+msgstr "Yes, I'm Sure"
+
+#: views/developers/addon_status_nominate.thtml:46
+#, fuzzy
+msgid "devcp_status_nominate_error_notice"
+msgstr ""
+"<span>A nomination message is required.</span><br />Please fill in the text "
+"box with the requested information and try again."
+
+#: views/developers/addon_status_nominate.thtml:55
+#, fuzzy
+msgid "devcp_status_nominate_header"
+msgstr "Add-on Nomination"
+
+#: views/developers/dashboard.thtml:85
+msgid "devcp_summary_lastversion"
+msgstr "最新版本:"
+
+#. %s is the add-on name.
+#: views/developers/addon_edit.thtml:43
+#: views/developers/addon_edit_authors.thtml:44
+#: views/developers/versions_delete.thtml:43
+#: views/developers/addon_edit_properties.thtml:44
+#: views/developers/addon_edit_descriptions.thtml:44
+#: views/developers/versions_edit.thtml:44
+#: views/developers/addon_edit_categories.thtml:43
+#: views/developers/versions.thtml:43
+#, fuzzy
+msgid "devcp_title_edit_addon"
+msgstr "Edit %s"
+
+#. title attribute for a javascript link that pops up a help dialog.
+#: views/elements/translationbox.thtml:68
+#, fuzzy
+msgid "devcp_transbox_a_title_help"
+msgstr "Help (does not leave page)"
+
+#: views/elements/translationbox.thtml:68
+#, fuzzy
+msgid "devcp_transbox_alt_help"
+msgstr "Help"
+
+#. %1$s is <span>17</span>, %2$s is 42.
+#: views/elements/translationbox.thtml:101
+#, fuzzy
+msgid "devcp_transbox_chars_used"
+msgstr "Characters used: %1$s / %2$s"
+
+#: views/elements/translationbox.thtml:132
+#, fuzzy
+msgid "devcp_transbox_delete_sure"
+msgstr "Are you sure you wish to delete this translation?"
+
+#. %s is a locale, like en-US.
+#: views/elements/translationbox.thtml:143
+#, fuzzy
+msgid "devcp_transbox_help_header_tabs"
+msgstr "What are these %s tabs?"
+
+#: views/elements/translationbox.thtml:145
+#, fuzzy
+msgid "devcp_transbox_help_header_what"
+msgstr "What if I don't have any translations?"
+
+#: views/elements/translationbox.thtml:147
+#, fuzzy
+msgid "devcp_transbox_help_hide"
+msgstr "Hide Help"
+
+#: views/elements/translationbox.thtml:146
+#, fuzzy
+msgid "devcp_transbox_help_if"
+msgstr ""
+"If a user browses the site and a translation isn't available in their own "
+"language, it will fall back to your add-on's Default Locale, specified in "
+"the Edit Add-on Properties area. If you don't have any translations, just "
+"enter what you can into your Default Locale, which should be a language you "
+"speak."
+
+#: views/elements/translationbox.thtml:144
+#, fuzzy
+msgid "devcp_transbox_help_transbox"
+msgstr ""
+"This is a <i>Translation Box</i>. It allows you to localize a specific field "
+"into any other languages for which you might have a translation. You can "
+"add, edit, and remove translations using the locale tabs."
+
+#: views/elements/translationbox.thtml:85
+#, fuzzy
+msgid "devcp_transbox_img_add_trans"
+msgstr "Add Translation"
+
+#: views/elements/translationbox.thtml:86
+#, fuzzy
+msgid "devcp_transbox_img_remove_trans"
+msgstr "Remove Translation"
+
+#: views/elements/translationbox.thtml:123
+#, fuzzy
+msgid "devcp_transbox_input_add_all"
+msgstr "Add Locale to All"
+
+#: views/elements/translationbox.thtml:122
+#, fuzzy
+msgid "devcp_transbox_input_add_locale"
+msgstr "Add Locale"
+
+#: views/elements/translationbox.thtml:124
+#: views/elements/translationbox.thtml:135
+#, fuzzy
+msgid "devcp_transbox_input_cancel"
+msgstr "Cancel"
+
+#: views/elements/translationbox.thtml:134
+#, fuzzy
+msgid "devcp_transbox_input_delete"
+msgstr "Delete It"
+
+#: views/elements/translationbox.thtml:113
+#, fuzzy
+msgid "devcp_transbox_select_locale"
+msgstr "Select the locale of the translation to add:"
+
+#. %1$s and %2$s are GUIDs.
+#: controllers/developers_controller.php:343
+#, fuzzy
+msgid "devcp_update_addon_guid_error"
+msgstr ""
+"The add-on GUID used in this file (%1$s) does not match the existing GUID "
+"for this add-on (%2$s)."
+
+#: controllers/developers_controller.php:334
+#, fuzzy
+msgid "devcp_update_addon_priv_error"
+msgstr "You do not have sufficient privileges to update this add-on."
+
+#. %1$s is a version number, %2$s is an add-on ID.
+#: controllers/developers_controller.php:399
+#, fuzzy
+msgid "devcp_update_addon_version_belong_error"
+msgstr "The specified version (%1$s) does not belong to this add-on (%2$s)."
+
+#. %1$s is a version number, maybe 1.1.
+#. %2$s is a URL.
+#: controllers/developers_controller.php:351
+#, fuzzy
+msgid "devcp_update_addon_version_exists_error"
+msgstr ""
+"The version number uploaded (%1$s) already exists for this add-on. If you "
+"are trying to add another file to this version, <a href=\"%2$s\">click here</"
+"a>."
+
+#. %1$s and %2$s are version numbers.
+#: controllers/developers_controller.php:405
+#, fuzzy
+msgid "devcp_update_addon_version_match_error"
+msgstr ""
+"The uploaded version number (%1$s) does not match the existing version "
+"number (%2$s)."
+
+#: views/developers/uploader.thtml:68
+#, fuzzy
+msgid "devcp_uploader_a_start"
+msgstr "Get Started"
+
+#: views/developers/uploader.thtml:137
+#, fuzzy
+msgid "devcp_uploader_ajax_loading"
+msgstr "Uploading file..."
+
+#: views/developers/uploader.thtml:82
+#, fuzzy
+msgid "devcp_uploader_button_agree"
+msgstr "Agree and continue"
+
+#: views/developers/uploader.thtml:157
+#, fuzzy
+msgid "devcp_uploader_button_edit"
+msgstr "Edit My Add-on"
+
+#: views/developers/uploader.thtml:158
+#, fuzzy
+msgid "devcp_uploader_button_later"
+msgstr "I'll complete my add-on later."
+
+#: views/developers/uploader.thtml:168
+#, fuzzy
+msgid "devcp_uploader_button_release"
+msgstr "Add Release Notes"
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/uploader.thtml:156
+#, fuzzy
+msgid "devcp_uploader_created_results"
+msgstr ""
+"<p>Your add-on listing has been successfully created. The basic information "
+"obtained from your uploaded file has been stored, but there's a lot more to "
+"your listing that can be customized.</p><p>Your add-on is currently marked "
+"as <strong>Incomplete</strong>. In order to complete your add-on, you'll "
+"need to make sure it has an accurate name, summary, and description, as well "
+"as at least one selected category. You can edit your add-on's information "
+"using the link below and check the status of your add-on at any time on the "
+"<a %s>status page</a>."
+
+#: views/developers/uploader.thtml:143
+#, fuzzy
+msgid "devcp_uploader_error_correct"
+msgstr "Please correct this problem and upload your file again."
+
+#. %1$s is a version number, %2$s is a status, e.g Public or Incomplete.
+#: views/developers/uploader.thtml:175
+#, fuzzy
+msgid "devcp_uploader_file_created"
+msgstr ""
+"Your new file has been added to version %1$s and is currently marked as %2$s."
+
+#: views/developers/uploader.thtml:154
+#, fuzzy
+msgid "devcp_uploader_header_created"
+msgstr "Add-on Created!"
+
+#: views/developers/uploader.thtml:141
+#, fuzzy
+msgid "devcp_uploader_header_error"
+msgstr "Oops! There seems to be a problem with this file..."
+
+#: views/developers/uploader.thtml:173
+#, fuzzy
+msgid "devcp_uploader_header_file_added"
+msgstr "File Added!"
+
+#: views/developers/uploader.thtml:66
+#, fuzzy
+msgid "devcp_uploader_header_how"
+msgstr "How does it all work?"
+
+#. %s is the version number, e.g. 3.2.
+#: views/developers/uploader.thtml:163
+#, fuzzy
+msgid "devcp_uploader_header_update_created"
+msgstr "Version %s Created"
+
+#: views/developers/uploader.thtml:117
+#, fuzzy
+msgid "devcp_uploader_header_upload"
+msgstr "Upload Your File"
+
+#: views/developers/uploader.thtml:67
+#, fuzzy
+msgid "devcp_uploader_how"
+msgstr ""
+"<p>Thanks for your interest in submitting your add-on to Mozilla Add-ons. "
+"Hosting your add-on on Mozilla Add-ons is the easiest way to handle "
+"distribution of your add-on. Here's what you'll get:</p><ul><li>Each add-on "
+"will have a public display page with information you provide, such as a "
+"brief summary of the add-on's functionality, an optional longer description, "
+"and a showcase of preview screenshots of your add-on.</li><li>Your add-on "
+"will appear in search and browse listings across the site, and even in the "
+"Add-ons Manager of Firefox 3.</li><li>We'll take care of hosting all of your "
+"downloads and providing automatic updates to users when you upload a new "
+"version.</li><li>You'll have access to a statistics dashboard with detailed "
+"information about your user base.</li></ul><p>Add-ons hosted on the site "
+"must be reviewed by a Mozilla Add-ons Editor before they will have all of "
+"the features listed above. If you're ready to start the process and have "
+"your add-on package ready for upload, just click on Get Started below!</p>"
+
+#: views/developers/uploader.thtml:125
+#, fuzzy
+msgid "devcp_uploader_label_platformtype"
+msgstr "Supported Platforms:"
+
+#: views/developers/uploader.thtml:124
+#, fuzzy
+msgid "devcp_uploader_label_upload_field"
+msgstr "Add-on File: "
+
+#: controllers/components/developers.php:1221
+#, fuzzy
+msgid "devcp_uploader_option_other"
+msgstr "Other"
+
+#. %1$s is a number, %2$s is href="..." and should stay in the <a> tag.
+#: views/developers/uploader.thtml:176
+#, fuzzy
+msgid "devcp_uploader_p_pending_file"
+msgstr ""
+"The new file will be available to the public as soon as an editor is able to "
+"review it. There are currently %1$s other add-ons in the queue. Want to be "
+"reviewed faster? Consider <a %2$s>becoming an editor</a>."
+
+#. %1$s is a number, %2$s is href="..." and should stay in the <a> tag.
+#: views/developers/uploader.thtml:166
+#, fuzzy
+msgid "devcp_uploader_p_pending_version"
+msgstr ""
+"The new version will be available to the public as soon as an editor is able "
+"to review it. There are currently %1$s other add-ons in the queue. Want to "
+"be reviewed faster? Consider <a %2$s>becoming an editor</a>."
+
+#. %s is a status, e.g Public or Incomplete.
+#: views/developers/uploader.thtml:165
+#, fuzzy
+msgid "devcp_uploader_p_update_created"
+msgstr "Your new version has been created and is currently marked as %s."
+
+#. %1$s is href="..." and should stay in the 'Versions and Files' <a> tag.
+#. %2$s is href="..." and should stay in the 'current status' <a> tag.
+#: views/developers/uploader.thtml:177
+#, fuzzy
+msgid "devcp_uploader_p_update_file"
+msgstr ""
+"View your new file in the <a %1$s>Versions and Files page</a>, check out "
+"your add-on's <a %2$s>current status</a>, or <b>add release notes</b> by "
+"clicking the button below (highly recommended)."
+
+#. %1$s is href="..." and should stay in the 'Versions and Files' <a> tag.
+#. %2$s is href="..." and should stay in the 'current status' <a> tag.
+#: views/developers/uploader.thtml:167
+#, fuzzy
+msgid "devcp_uploader_p_update_version"
+msgstr ""
+"View your new version in the <a %1$s>Versions and Files page</a>, check out "
+"your add-on's <a %2$s>current status</a>, or <b>add release notes</b> by "
+"clicking the button below (highly recommended)."
+
+#: views/developers/uploader.thtml:118
+#, fuzzy
+msgid "devcp_uploader_p_upload"
+msgstr ""
+"Upload your add-on file using the form below. If you have multiple, platform-"
+"specific files to upload, choose a single file and then upload the others "
+"using the Versions and Files Manager."
+
+#: views/developers/uploader.thtml:125
+#, fuzzy
+msgid "devcp_uploader_platformtype_all"
+msgstr "All"
+
+#: views/developers/uploader.thtml:126
+#, fuzzy
+msgid "devcp_uploader_platformtype_specific"
+msgstr "Specific:"
+
+#. Used as first item in a <select>.
+#: controllers/components/developers.php:1185
+#, fuzzy
+msgid "devcp_uploader_please_choose"
+msgstr "Please Choose..."
+
+#. %1$s is the add-on name, %2$s is the version number.
+#: views/developers/uploader.thtml:57
+#, fuzzy
+msgid "devcp_uploader_title_file"
+msgstr "Add File to %1$s %2$s"
+
+#: views/developers/uploader.thtml:50
+#, fuzzy
+msgid "devcp_uploader_title_submit"
+msgstr "Submit New Add-on"
+
+#. %s is the add-on name.
+#: views/developers/uploader.thtml:54
+#, fuzzy
+msgid "devcp_uploader_title_update"
+msgstr "Update %s"
+
+#. %s is a full <a> tag
+#: controllers/developers_controller.php:503
+#, php-format
+msgid "devcp_valid_app_reference"
+msgstr "请查阅 %s 获å–说明。"
+
+#. This is the text in the <a> tag for devcp_valid_app_reference. This should be
+#. fixed.
+#: controllers/developers_controller.php:503
+msgid "devcp_valid_app_reference_linktext"
+msgstr "本页"
+
+#: controllers/developers_controller.php:581
+#, fuzzy
+msgid "devcp_verify_author_error"
+msgstr "No account found for that email address."
+
+#: controllers/developers_controller.php:553
+#, fuzzy
+msgid "devcp_verify_search_engine_error"
+msgstr ""
+"Either the XML is invalid or required fields are missing. Please <a href="
+"\"https://developer.mozilla.org/en/Creating_OpenSearch_plugins_for_Firefox"
+"\">read the documentation</a>, verify your add-on, and try again."
+
+#: views/developers/versions.thtml:75
+#, fuzzy
+msgid "devcp_versions_a_cancel"
+msgstr "Cancel"
+
+#: views/developers/versions.thtml:79
+#, fuzzy
+msgid "devcp_versions_a_delete"
+msgstr "Delete Version"
+
+#: views/developers/versions.thtml:74
+#, fuzzy
+msgid "devcp_versions_a_empty"
+msgstr "Remove Empty Version"
+
+#: views/developers/versions.thtml:71
+#, fuzzy
+msgid "devcp_versions_a_remove"
+msgstr "Remove?"
+
+#: views/developers/versions.thtml:91
+#, fuzzy
+msgid "devcp_versions_add"
+msgstr "Add New Version"
+
+#: views/developers/versions_delete.thtml:58
+#, fuzzy
+msgid "devcp_versions_delete_a_cancel"
+msgstr "Cancel"
+
+#: views/developers/versions_delete.thtml:56
+#, fuzzy
+msgid "devcp_versions_delete_a_delete"
+msgstr "Delete Version"
+
+#. Followed by a list of reviews and files that will be removed.
+#: views/developers/versions_delete.thtml:50
+#, fuzzy
+msgid "devcp_versions_delete_also"
+msgstr "This will also delete:"
+
+#: views/developers/versions_delete.thtml:53
+#, fuzzy
+msgid "devcp_versions_delete_files"
+msgid_plural "devcp_versions_delete_files"
+msgstr[0] "%s file"
+msgstr[1] "%s files"
+
+#. %s is the version number.
+#: views/developers/versions_delete.thtml:48
+#, fuzzy
+msgid "devcp_versions_delete_header"
+msgstr "Delete Version %s?"
+
+#: views/developers/versions_delete.thtml:52
+#, fuzzy
+msgid "devcp_versions_delete_reviews"
+msgid_plural "devcp_versions_delete_reviews"
+msgstr[0] "%s review"
+msgstr[1] "%s reviews"
+
+#. %s is the version number.
+#: views/developers/versions_delete.thtml:49
+#, fuzzy
+msgid "devcp_versions_delete_sure"
+msgstr "Are you sure you want to permanently delete version %s?"
+
+#: views/developers/versions_edit.thtml:102
+#: views/developers/versions_edit.thtml:155
+#, fuzzy
+msgid "devcp_versions_edit_a_cancel"
+msgstr "Cancel"
+
+#: views/developers/versions_edit.thtml:101
+#, fuzzy
+msgid "devcp_versions_edit_a_delete"
+msgstr "Delete File"
+
+#: views/developers/versions_edit.thtml:165
+#, fuzzy
+msgid "devcp_versions_edit_a_new_app"
+msgstr "Add New Application"
+
+#: views/developers/versions_edit.thtml:154
+#, fuzzy
+msgid "devcp_versions_edit_a_remove_app"
+msgstr "Remove Application"
+
+#: views/developers/versions_edit.thtml:114
+#, fuzzy
+msgid "devcp_versions_edit_add"
+msgstr "Add New File"
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/versions_edit.thtml:121
+#, fuzzy
+msgid "devcp_versions_edit_adjust"
+msgstr ""
+"Adjusting application information here will allow users to install your add-"
+"on even if the install.rdf in the package indicates that the add-on is "
+"incompatible. <a %s>List of supported applications</a>"
+
+#: views/developers/versions_edit.thtml:153
+#, fuzzy
+msgid "devcp_versions_edit_compat_sure"
+msgstr ""
+"Are you <b>sure</b> you wish to remove compatibility with this application?"
+
+#: views/developers/versions_edit.thtml:100
+#, fuzzy
+msgid "devcp_versions_edit_delete_sure"
+msgstr "Are you <b>sure</b> you wish to permanently delete this file?"
+
+#: views/developers/versions_edit.thtml:203
+#, fuzzy
+msgid "devcp_versions_edit_header_approval"
+msgstr "Approval Information"
+
+#: views/developers/versions_edit.thtml:120
+#, fuzzy
+msgid "devcp_versions_edit_header_compat"
+msgstr "Compatible Applications"
+
+#: views/developers/versions_edit.thtml:74
+#, fuzzy
+msgid "devcp_versions_edit_header_file"
+msgstr "File Information"
+
+#: views/developers/versions_edit.thtml:189
+#, fuzzy
+msgid "devcp_versions_edit_header_license"
+msgstr "License"
+
+#. %s is the version number.
+#: views/developers/versions_edit.thtml:53
+#, fuzzy
+msgid "devcp_versions_edit_header_manage"
+msgstr "Manage Version %s"
+
+#: views/developers/versions_edit.thtml:212
+#, fuzzy
+msgid "devcp_versions_edit_header_notes"
+msgstr "Approval Notes"
+
+#: views/developers/versions_edit.thtml:98
+#, fuzzy
+msgid "devcp_versions_edit_img_delete"
+msgstr "Delete File"
+
+#. %1$s is the file id, e.g. 18723.
+#. %2$s is the platform name, e.g. ALL or Windows.
+#. %3$s is the _('date) created.
+#. %4$s is the status, e.g. "In Sandbox" or "Public".
+#. %5$s is the _('date') status was changed.
+#: views/developers/versions_edit.thtml:208
+#, fuzzy
+msgid "devcp_versions_edit_li_file"
+msgstr "File %1$s (%2$s) created on %3$s and changed to %4$s on %5$s"
+
+#: views/developers/versions_edit.thtml:190
+#, fuzzy
+msgid "devcp_versions_edit_license_description"
+msgstr ""
+"Please select the appropriate license for your add-on. This license "
+"specifies the rights you grant on your source code."
+
+#: views/developers/versions_edit.thtml:111
+#, fuzzy
+msgid "devcp_versions_edit_no_files"
+msgstr "No files found."
+
+#: views/developers/versions_edit.thtml:213
+#, fuzzy
+msgid "devcp_versions_edit_optional"
+msgstr "Optional information for the Editor that reviews this version."
+
+#: views/developers/versions_edit.thtml:151
+#, fuzzy
+msgid "devcp_versions_edit_remove_compat"
+msgstr "Remove Application Compatibility"
+
+#: views/developers/versions_edit.thtml:167
+#, fuzzy
+msgid "devcp_versions_edit_select_app"
+msgstr "Please Select an Application"
+
+#: views/developers/versions_edit.thtml:78
+#, fuzzy
+msgid "devcp_versions_edit_th_file"
+msgstr "File"
+
+#: views/developers/versions_edit.thtml:79
+#, fuzzy
+msgid "devcp_versions_edit_th_platform"
+msgstr "Platform"
+
+#: views/developers/versions_edit.thtml:80
+#, fuzzy
+msgid "devcp_versions_edit_th_size"
+msgstr "Size"
+
+#: views/developers/versions_edit.thtml:81
+#, fuzzy
+msgid "devcp_versions_edit_th_status"
+msgstr "Status"
+
+#: views/developers/versions_edit.thtml:183
+#, fuzzy
+msgid "devcp_versions_edit_transbox_releasenotes_description"
+msgstr ""
+"Information about changes in this release, new features, known bugs, and "
+"other useful information specific to this release/version. This information "
+"will also be available to users updating the add-on in the Firefox 3 Add-ons "
+"Manager interface."
+
+#: views/developers/versions_edit.thtml:182
+#, fuzzy
+msgid "devcp_versions_edit_transbox_releasenotes_name"
+msgstr "Release Notes"
+
+#: views/developers/versions_edit.thtml:164
+#, fuzzy
+msgid "devcp_versions_edit_unsaved_compat"
+msgstr ""
+"<strong>You have unsaved changes.</strong> Compatibility will not be deleted "
+"until you click Update Version below."
+
+#: views/developers/versions_edit.thtml:113
+#, fuzzy
+msgid "devcp_versions_edit_unsaved_files"
+msgstr ""
+"<strong>You have unsaved changes.</strong> Files will not be deleted until "
+"you click Update Version below."
+
+#: views/developers/versions_edit.thtml:218
+#, fuzzy
+msgid "devcp_versions_edit_update"
+msgstr "Update Versions"
+
+#: views/developers/versions.thtml:49
+#, fuzzy
+msgid "devcp_versions_header_manage"
+msgstr "Manage Versions and Files"
+
+#: views/developers/versions.thtml:87
+#, fuzzy
+msgid "devcp_versions_no_versions"
+msgstr "No versions."
+
+#. %s is a version number, base 10.
+#: views/developers/versions.thtml:46
+#, fuzzy
+msgid "devcp_versions_notice_success"
+msgstr "Version %s deleted successfully."
+
+#: views/developers/versions.thtml:73
+#, fuzzy
+msgid "devcp_versions_p_remove"
+msgstr ""
+"This version has no files associated with it and can be removed. Would you "
+"like to remove this version?"
+
+#: views/developers/versions.thtml:58
+#, fuzzy
+msgid "devcp_versions_th_created"
+msgstr "Created"
+
+#: views/developers/versions.thtml:57
+#, fuzzy
+msgid "devcp_versions_th_status"
+msgstr "Status"
+
+#: views/developers/versions.thtml:56
+#, fuzzy
+msgid "devcp_versions_th_version"
+msgstr "Version"
+
+#: controllers/downloads_controller.php:91
+msgid "downloads_disable_warning"
+msgstr "附加组件已ç¦ç”¨ã€‚"
+
+#: controllers/components/editors.php:57
+#, fuzzy
+msgid "editor_review_error_addon_not_nominated"
+msgstr "This add-on has not been nominated."
+
+#: controllers/components/editors.php:213
+#, fuzzy
+msgid "editor_review_error_file_not_pending"
+msgstr "This file is not pending review."
+
+#. Actions are, for example: approving or rejecting
+#: controllers/components/editors.php:79
+#: controllers/components/editors.php:182
+#, fuzzy
+msgid "editor_review_error_no_action"
+msgstr "Please select a review action."
+
+#: controllers/components/editors.php:192
+#, fuzzy
+msgid "editor_review_error_no_applications"
+msgstr "Please enter the applications you tested."
+
+#. Comments are required when an editor approves or rejects an add-on.
+#: controllers/components/editors.php:84
+#: controllers/components/editors.php:187
+#, fuzzy
+msgid "editor_review_error_no_comments"
+msgstr "Please enter review comments."
+
+#: controllers/components/editors.php:161
+#, fuzzy
+msgid "editor_review_error_no_files"
+msgstr "Please select at least one file to review."
+
+#: controllers/components/editors.php:197
+#, fuzzy
+msgid "editor_review_error_no_operating_system"
+msgstr "Please enter the operating systems you tested."
+
+#: views/editors/logs.thtml:51
+msgid "editorcp_logs_button_filter"
+msgstr "过滤器"
+
+#: views/editors/logs.thtml:44
+msgid "editorcp_logs_filter_by"
+msgstr "以类型/æ“作过滤"
+
+#: views/editors/logs.thtml:42 controllers/editors_controller.php:964
+msgid "editorcp_logs_page_heading"
+msgstr "事件日志"
+
+#: views/elements/developers/editorsmenu.thtml:60
+msgid "editorcp_menu_eventlog_link"
+msgstr "事件日志"
+
+#: views/elements/developers/editorsmenu.thtml:62
+msgid "editorcp_menu_mainpage_link"
+msgstr "返回首页"
+
+#: views/elements/developers/editorsmenu.thtml:61
+msgid "editorcp_menu_reviewlog_link"
+msgstr "审查日志"
+
+#: views/elements/developers/editorsmenu.thtml:55
+msgid "editorcp_menu_summary_link"
+msgstr "编辑摘è¦"
+
+#: views/elements/developers/editorsmenu.thtml:52
+msgid "editorcp_menu_title"
+msgstr "编辑工具"
+
+#: views/editors/reviewlog.thtml:49
+msgid "editorcp_reviewlog_button_filter"
+msgstr "过滤器"
+
+#: views/editors/reviewlog.thtml:58
+msgid "editorcp_reviewlog_column_action"
+msgstr "æ“作"
+
+#: views/editors/reviewlog.thtml:56
+msgid "editorcp_reviewlog_column_addon"
+msgstr "附加组件"
+
+#: views/editors/reviewlog.thtml:55
+msgid "editorcp_reviewlog_column_date"
+msgstr "日期"
+
+#: views/editors/reviewlog.thtml:57
+msgid "editorcp_reviewlog_column_editor"
+msgstr "编辑"
+
+#: views/editors/reviewlog.thtml:94
+msgid "editorcp_reviewlog_comments_hide"
+msgstr "éšè—评论"
+
+#: views/editors/reviewlog.thtml:93
+msgid "editorcp_reviewlog_comments_show"
+msgstr "显示评论"
+
+#. %1$s and %2$s are full <input> tags for dates
+#: views/editors/reviewlog.thtml:45
+#, php-format
+msgid "editorcp_reviewlog_entries_between"
+msgstr "显示 %s 到 %s 之间的记录"
+
+#: views/editors/reviewlog.thtml:104
+msgid "editorcp_reviewlog_none_found"
+msgstr "这段时间未找到评论。"
+
+#: views/editors/reviewlog.thtml:42
+msgid "editorcp_reviewlog_page_heading"
+msgstr "审查日志"
+
+#: views/editors/summary.thtml:61
+msgid "editorcp_summary_monthreviews_heading"
+msgstr "月度æ„è§æ±‡æ€»"
+
+#: views/editors/summary.thtml:77
+msgid "editorcp_summary_neweditors_heading"
+msgstr "新编辑"
+
+#: views/editors/summary.thtml:42
+msgid "editorcp_summary_page_heading"
+msgstr "编辑摘è¦"
+
+#: views/editors/summary.thtml:94
+msgid "editorcp_summary_recentactivity_heading"
+msgstr "最近编辑活动"
+
+#: views/editors/summary.thtml:45
+msgid "editorcp_summary_totalreviews_heading"
+msgstr "æ„è§æ±‡æ€»"
+
+#: controllers/editors_controller.php:248
+#: controllers/editors_controller.php:249
+msgid "editors_addon_review_pagetitle"
+msgstr "审查附加组件。"
+
+#: controllers/editors_controller.php:349
+msgid "editors_error_js-formerror"
+msgstr "请完整填写以下字段:"
+
+#: controllers/editors_controller.php:350
+msgid "editors_error_review_one_file"
+msgstr "请至少选择一个文件审查。"
+
+#: controllers/editors_controller.php:274
+msgid "editors_error_self_reviews_forbidden"
+msgstr "ä¸å…许自审查。"
+
+#: controllers/editors_controller.php:699
+msgid "editors_external_software"
+msgstr "外部软件"
+
+#: views/editors/featured.thtml:120 views/editors/featured.thtml:121
+msgid "editors_featured_add_feature"
+msgstr "增加特性"
+
+#: views/editors/featured.thtml:126
+msgid "editors_featured_add_feature_submit"
+msgstr "增加"
+
+#: views/editors/featured.thtml:49 controllers/editors_controller.php:832
+#: controllers/editors_controller.php:848
+msgid "editors_featured_addon_add_failure"
+msgstr "增加特性失败"
+
+#: controllers/editors_controller.php:851
+msgid "editors_featured_addon_add_success"
+msgstr "增加特性æˆåŠŸã€‚"
+
+#: views/editors/featured.thtml:50 controllers/editors_controller.php:839
+#: controllers/editors_controller.php:868
+#: controllers/editors_controller.php:886
+msgid "editors_featured_addon_edit_failure"
+msgstr "编辑特性失败。"
+
+#: views/editors/featured.thtml:51 controllers/editors_controller.php:888
+msgid "editors_featured_addon_edit_success"
+msgstr "编辑特性æˆåŠŸã€‚"
+
+#: views/editors/featured.thtml:53 controllers/editors_controller.php:861
+msgid "editors_featured_addon_invalid_locale"
+msgstr "一个或者多个语言无效。"
+
+#: views/editors/featured.thtml:52 controllers/editors_controller.php:906
+msgid "editors_featured_addon_remove_failure"
+msgstr "删除特性失败。"
+
+#: controllers/editors_controller.php:901
+msgid "editors_featured_addon_remove_success"
+msgstr "删除特性æˆåŠŸã€‚"
+
+#: controllers/editors_controller.php:915
+#: controllers/editors_controller.php:917
+msgid "editors_featured_addons_pagetitle"
+msgstr "特定的附加组件"
+
+#: views/editors/featured.thtml:54 views/editors/featured.thtml:107
+msgid "editors_featured_edit_feature_submit"
+msgstr "æ交"
+
+#: views/editors/featured.thtml:90 views/editors/featured.thtml:91
+msgid "editors_featured_remove_feature"
+msgstr "删除特性"
+
+#: views/editors/queue.thtml:46
+msgid "editors_filter_queue"
+msgstr "过滤器队列"
+
+#: views/editors/queue.thtml:182
+msgid "editors_helpful_links"
+msgstr "有用的链接"
+
+#: views/editors/queue.thtml:182
+msgid "editors_link_guide"
+msgstr "编辑å‘导"
+
+#: views/editors/queue.thtml:182
+msgid "editors_link_policy"
+msgstr "附加组件策略"
+
+#: views/editors/queue.thtml:47
+msgid "editors_notice_filter_session"
+msgstr "这些过滤器将ä¿ç•™åœ¨é€‚当的ä½ç½®ç›´åˆ°æœ¬æ¬¡ä¼šè¯ç»“æŸæˆ–者被清除。"
+
+# %1 is the queue mode
+#. %1 is the queue mode
+#: views/editors/queue.thtml:177 views/admin/flagged_queue.thtml:89
+msgid "editors_notice_none_found"
+msgstr "ç›®å‰æ²¡æœ‰è¦å®¡æŸ¥çš„附加组件。"
+
+#: controllers/editors_controller.php:1040
+msgid "editors_one_day"
+msgstr "一天"
+
+#: controllers/editors_controller.php:1048
+msgid "editors_one_hour"
+msgstr "一å°æ—¶"
+
+#: controllers/editors_controller.php:1056
+msgid "editors_one_minute"
+msgstr "一分钟"
+
+#: controllers/editors_controller.php:64 controllers/editors_controller.php:73
+#: controllers/editors_controller.php:77
+msgid "editors_pagetitle"
+msgstr "编辑工具"
+
+#. %s is a comma separated list of platforms. Example: Windows, OS X
+#: controllers/editors_controller.php:680
+#: controllers/editors_controller.php:683
+#, php-format
+msgid "editors_platform_x_only"
+msgstr "åªé€‚用 %s"
+
+#: controllers/editors_controller.php:695
+msgid "editors_pre-release"
+msgstr "预å‘布"
+
+# %1 is the app name
+#. %1 is the app name
+#: views/editors/queue.thtml:131
+#, php-format
+msgid "editors_queue_app_compatibility"
+msgstr "兼容 %s"
+
+#: views/editors/queue.thtml:51
+#, fuzzy
+msgid "editors_queue_filter_label_addon"
+msgstr "Add-on or Author Email"
+
+#: views/editors/queue.thtml:72
+#, fuzzy
+msgid "editors_queue_filter_label_addontypes"
+msgstr "Add-on Types"
+
+#: views/editors/queue.thtml:56
+#, fuzzy
+msgid "editors_queue_filter_label_application"
+msgstr "Application"
+
+#: views/editors/queue.thtml:61
+#, fuzzy
+msgid "editors_queue_filter_label_maxversion"
+msgstr "Max. Version"
+
+#: views/editors/queue.thtml:78
+#, fuzzy
+msgid "editors_queue_filter_label_platforms"
+msgstr "Platforms"
+
+#: views/editors/queue.thtml:66
+#, fuzzy
+msgid "editors_queue_filter_label_submissionage"
+msgstr "Age of Submission (days)"
+
+#. %1$s is a number
+#: views/editors/queue.thtml:90
+#, fuzzy
+msgid "editors_queue_filter_result_count"
+msgid_plural "editors_queue_filter_result_count"
+msgstr[0] "Results of your filtered search: <strong>%1$s</strong> Add-on"
+msgstr[1] "Results of your filtered search: <strong>%1$s</strong> Add-ons"
+
+#: views/editors/queue.thtml:84
+msgid "editors_queue_submit_clean"
+msgstr "清除"
+
+#: views/editors/queue.thtml:83
+msgid "editors_queue_submit_filter"
+msgstr "过滤器"
+
+#: controllers/editors_controller.php:133
+msgid "editors_queues_disabled"
+msgstr ""
+"All review queues are currently disabled. Please check back at a later time."
+"ç›®å‰æ‰€æœ‰å®¡æŸ¥é˜Ÿåˆ—都ç¦ç”¨ã€‚请ç¨åŽå†è¯•ã€‚"
+
+#: views/editors/review.thtml:149
+#, fuzzy
+msgid "editors_review_a_edit_item"
+msgstr "Edit Item"
+
+#: views/editors/review.thtml:146
+#, fuzzy
+msgid "editors_review_a_item_history"
+msgstr "Item History"
+
+#: views/editors/review.thtml:148
+#, fuzzy
+msgid "editors_review_a_item_homepage"
+msgstr "Item Homepage"
+
+#: views/editors/review.thtml:145
+#, fuzzy
+msgid "editors_review_a_item_overview"
+msgstr "Item Overview"
+
+#: views/editors/review.thtml:147
+#, fuzzy
+msgid "editors_review_a_previews"
+msgstr "Previews"
+
+#: controllers/editors_controller.php:345
+msgid "editors_review_action"
+msgstr "进行审查"
+
+#: views/editors/review.thtml:159
+#, fuzzy
+msgid "editors_review_action_info"
+msgstr "Request More Information"
+
+#: views/editors/review.thtml:157
+msgid "editors_review_action_public"
+msgstr "å‘布到公共网站"
+
+#: views/editors/review.thtml:160
+msgid "editors_review_action_request_superreview"
+msgstr "è¦æ±‚特别审查"
+
+#: views/editors/review.thtml:158
+msgid "editors_review_action_sandbox"
+msgstr "ä¿ç•™åœ¨æ²™ç›’中"
+
+#: controllers/editors_controller.php:346
+msgid "editors_review_comments"
+msgstr "审查评论"
+
+#: views/editors/review.thtml:182
+#, fuzzy
+msgid "editors_review_details_info_request"
+msgstr ""
+"Use this form to request more information from the author. They will receive "
+"an email and be able to answer here. You will be notified by email when they "
+"reply."
+
+#: views/editors/review.thtml:174
+msgid "editors_review_details_nominated_public"
+msgstr ""
+"这会将该附加组件和他的最新版本ã€æ–‡ä»¶å‘布到公共网站。其åŽç»­ç‰ˆæœ¬å°†ä¼šè¿›å…¥æ²™ç›’知"
+"é“有编辑对其进行审查。"
+
+#: views/editors/review.thtml:177
+msgid "editors_review_details_nominated_sandbox"
+msgstr "这会将附加组件ä¿ç•™åœ¨æ²™ç›’中。"
+
+#: views/editors/review.thtml:166
+msgid "editors_review_details_pending_public"
+msgstr "这会将附加组件的沙盒版本放到公开区域。"
+
+#: views/editors/review.thtml:169
+msgid "editors_review_details_pending_sandbox"
+msgstr "这会将附加组件的沙盒版本ä¿ç•™åœ¨æ²™ç›’中。"
+
+#: views/editors/review.thtml:185
+msgid "editors_review_details_superreview"
+msgstr ""
+"如果你觉得这个附加组件有安全ã€ç‰ˆæƒæˆ–者其他方é¢çš„问题需è¦ç®¡ç†å‘˜å¤„ç†ï¼Œåœ¨ä¸‹é¢è¾“"
+"入你的评论。内容将会å‘é€ç»™ç®¡ç†å‘˜è€Œä¸æ˜¯ä½œè€…。"
+
+#: views/editors/review.thtml:134
+#, fuzzy
+msgid "editors_review_file_diff_link"
+msgstr "Compare with public version"
+
+#: views/editors/review.thtml:131
+msgid "editors_review_file_viewcontents_link"
+msgstr "查看内容"
+
+#: views/editors/review.thtml:65
+msgid "editors_review_header_authors"
+msgstr "作者:"
+
+#: views/editors/review.thtml:79
+msgid "editors_review_header_categories"
+msgstr "分类:"
+
+#: views/editors/review.thtml:92
+msgid "editors_review_header_compatibility"
+msgstr "兼容性:"
+
+#: views/editors/review.thtml:251
+msgid "editors_review_header_description"
+msgstr "æè¿°"
+
+#: views/editors/review.thtml:275
+msgid "editors_review_header_devcomments"
+msgstr "å¼€å‘者评论"
+
+#: views/editors/review.thtml:263
+msgid "editors_review_header_eula"
+msgstr "许å¯åè®®"
+
+#: views/editors/review.thtml:115
+msgid "editors_review_header_files"
+msgstr "文件:"
+
+#: views/editors/review.thtml:284
+msgid "editors_review_header_itemhistory"
+msgstr "项目历å²"
+
+#: views/editors/review.thtml:232
+msgid "editors_review_header_nominationmessage"
+msgstr "æ交说明"
+
+#: views/editors/review.thtml:311
+msgid "editors_review_header_previews"
+msgstr "预览图片"
+
+#: views/editors/review.thtml:269
+msgid "editors_review_header_privacy"
+msgstr "éšç§ç­–ç•¥"
+
+# %1 is the addon name and version
+#. %1 is the add-on name and version
+#: views/editors/review.thtml:56
+#, php-format
+msgid "editors_review_header_review"
+msgstr "审查 %s"
+
+#: views/editors/review.thtml:239
+msgid "editors_review_header_reviewernotes"
+msgstr "给审查者的说明"
+
+#: views/editors/review.thtml:245
+msgid "editors_review_header_summary"
+msgstr "摘è¦"
+
+#: views/editors/review.thtml:257
+msgid "editors_review_header_versionnotes"
+msgstr "版本说明"
+
+#. a noun: shown in an add-on's editor review history
+#: views/elements/developers/editors_review_history_item.thtml:80
+#, fuzzy
+msgid "editors_review_history_info_reply"
+msgstr "Reply"
+
+#: views/elements/developers/editors_review_history_item.thtml:78
+#, fuzzy
+msgid "editors_review_history_info_request"
+msgstr "Information Request"
+
+#: views/elements/developers/editors_review_history_item.thtml:62
+#: views/editors/reviewlog.thtml:77
+msgid "editors_review_history_nominated_adminreview"
+msgstr "交管ç†å‘˜å®¡æŸ¥"
+
+#: views/elements/developers/editors_review_history_item.thtml:56
+#: views/editors/reviewlog.thtml:71
+msgid "editors_review_history_nominated_approved"
+msgstr "已通过审查/公开区域"
+
+#: views/elements/developers/editors_review_history_item.thtml:59
+#: views/editors/reviewlog.thtml:74
+msgid "editors_review_history_nominated_denied"
+msgstr "æ‹’ç»é€šè¿‡/沙盒区域"
+
+#: views/editors/review.thtml:303
+msgid "editors_review_history_nonefound"
+msgstr "未找到更早的审查记录。"
+
+#: views/elements/developers/editors_review_history_item.thtml:73
+#: views/editors/reviewlog.thtml:88
+msgid "editors_review_history_pending_adminreview"
+msgstr "交管ç†å‘˜å®¡æŸ¥"
+
+#: views/elements/developers/editors_review_history_item.thtml:67
+#: views/editors/reviewlog.thtml:82
+msgid "editors_review_history_pending_approved"
+msgstr "已通过/公开区域"
+
+#: views/elements/developers/editors_review_history_item.thtml:70
+#: views/editors/reviewlog.thtml:85
+msgid "editors_review_history_pending_denied"
+msgstr "æ‹’ç»é€šè¿‡/沙盒区域"
+
+#. link text in an add-on's editor review history, allowing to hide and show an information request's replies
+#. %1 is the number of replies
+#: views/elements/developers/editors_review_history_item.thtml:90
+#, fuzzy
+msgid "editors_review_history_show_hide_replies"
+msgid_plural "editors_review_history_show_hide_replies"
+msgstr[0] "Show/Hide Replies (%1$s)"
+msgstr[1] "Show/Hide Replies (%1$s)"
+
+#: views/editors/review.thtml:208
+msgid "editors_review_label_applications"
+msgstr "应用程åº:"
+
+#: views/editors/review.thtml:196
+msgid "editors_review_label_cannedresponse"
+msgstr "或者选择预定的回å¤ä¿¡æ¯:"
+
+#: views/editors/review.thtml:190
+msgid "editors_review_label_comments"
+msgstr "评论:"
+
+#: views/editors/review.thtml:204
+msgid "editors_review_label_operating_systems"
+msgstr "æ“作系统:"
+
+#: views/editors/review.thtml:285 views/editors/review.thtml:312
+msgid "editors_review_link_pagetop"
+msgstr "回顶端"
+
+#: views/editors/review.thtml:141
+#, fuzzy
+msgid "editors_review_mulitple_notice"
+msgstr ""
+"Notice: Only review more than one file if you have tested EVERY file you "
+"select."
+
+#: views/editors/review.thtml:51
+msgid "editors_review_next_link"
+msgstr "ä¸‹ä¸€æ¡ &raquo;"
+
+#: views/editors/review.thtml:322
+msgid "editors_review_previews_notfound"
+msgstr "未找到预览图片。"
+
+#: views/editors/review.thtml:50
+msgid "editors_review_previous_link"
+msgstr "&laquo; 上一æ¡"
+
+#: controllers/editors_controller.php:144
+#: controllers/editors_controller.php:146
+msgid "editors_review_queue_pagetitle"
+msgstr "æ„è§é˜Ÿåˆ—"
+
+# %1 is the add-ons rank in the queue, %2 is the total queue length
+#. %1 is the add-ons rank in the queue, %2 is the total queue length
+#: views/editors/review.thtml:47
+msgid "editors_review_rank_in_queue"
+msgstr "队列中 <strong># %1$s</strong> of %2$s"
+
+#. %1 is the add-ons rank in the queue, %2 is the total queue length. Both numbers
+#: views/editors/review.thtml:45
+#, fuzzy
+msgid "editors_review_rank_in_queue_filtered"
+msgstr "<strong># %1$s</strong> of %2$s in queue (filtered)"
+
+#: views/editors/review.thtml:223
+msgid "editors_review_submit_process_action"
+msgstr "处ç†åŠ¨ä½œ"
+
+#: views/editors/review.thtml:293
+msgid "editors_review_th_action"
+msgstr "动作"
+
+#: views/editors/review.thtml:294
+msgid "editors_review_th_comments"
+msgstr "评论"
+
+#: views/editors/review.thtml:291
+msgid "editors_review_th_date"
+msgstr "日期"
+
+#: views/editors/review.thtml:292
+msgid "editors_review_th_reviewer"
+msgstr "建议者"
+
+#: views/editors/review.thtml:290
+msgid "editors_review_th_version_file"
+msgstr "版本/文件"
+
+#: views/editors/review.thtml:217
+#, fuzzy
+msgid "editors_review_update_notify_once"
+msgstr ""
+"Notify me the next time this add-on is updated. (Subsequent updates will not "
+"generate an email)"
+
+#: controllers/editors_controller.php:298
+msgid "editors_reviewed_successfully"
+msgstr "æ„è§å·²æˆåŠŸå¤„ç†ã€‚"
+
+#: views/editors/reviews_queue.thtml:106
+msgid "editors_reviews_action_delete_review"
+msgstr "删除æ„è§"
+
+#: views/editors/reviews_queue.thtml:104
+msgid "editors_reviews_action_keep"
+msgstr "删除标记; ä¿ç•™æ„è§"
+
+#: views/editors/reviews_queue.thtml:102
+msgid "editors_reviews_action_skip"
+msgstr "跳过"
+
+#: views/editors/reviews_queue.thtml:100
+msgid "editors_reviews_header_action"
+msgstr "动作"
+
+#: views/editors/reviews_queue.thtml:67
+msgid "editors_reviews_in_reply_to"
+msgstr "回å¤:"
+
+#: controllers/editors_controller.php:748
+msgid "editors_reviews_processed"
+msgstr "审查æˆåŠŸå®Œæˆï¼"
+
+#: views/editors/reviews_queue.thtml:117
+msgid "editors_reviews_queue_empty"
+msgstr "ç›®å‰æ²¡æœ‰éœ€è¦å®¡æŸ¥çš„项目。"
+
+#: views/editors/reviews_queue.thtml:111
+msgid "editors_reviews_submit_process_reviews"
+msgstr "进行审查"
+
+#: controllers/editors_controller.php:691
+msgid "editors_site_specific"
+msgstr "针对特定网站"
+
+#: controllers/editors_controller.php:348
+msgid "editors_tested_app"
+msgstr "已测试的应用程åº"
+
+#: controllers/editors_controller.php:347
+msgid "editors_tested_os"
+msgstr "ç»è¿‡æµ‹è¯•çš„æ“作系统环境"
+
+#: views/editors/queue.thtml:151
+msgid "editors_th_additional_info"
+msgstr "附加信æ¯"
+
+#: views/editors/featured.thtml:63 views/editors/queue.thtml:109
+#: views/admin/flagged_queue.thtml:53
+msgid "editors_th_addon"
+msgstr "附加组件"
+
+#: views/editors/queue.thtml:125
+msgid "editors_th_addontype"
+msgstr "类别"
+
+#: views/editors/featured.thtml:64
+msgid "editors_th_locales"
+msgstr "é™åˆ¶è¯­è¨€ï¼Ÿ"
+
+#: views/editors/queue.thtml:148
+#, fuzzy
+msgid "editors_th_nomination_age"
+msgstr "Time in Queue"
+
+#: views/editors/queue.thtml:101 views/editors/queue.thtml:117
+#: views/editors/queue.thtml:144
+#, fuzzy
+msgid "editors_th_sort_ascending"
+msgstr "Ascending sort"
+
+#: views/editors/queue.thtml:105 views/editors/queue.thtml:121
+#: views/editors/queue.thtml:140
+#, fuzzy
+msgid "editors_th_sort_descending"
+msgstr "Descending sort"
+
+#. %s is a number
+#: controllers/editors_controller.php:1036
+#, php-format
+msgid "editors_x_days"
+msgstr "%s 天"
+
+#. %s is a number
+#: controllers/editors_controller.php:1044
+#, php-format
+msgid "editors_x_hours"
+msgstr "%s å°æ—¶"
+
+#. %s is a number
+#: controllers/editors_controller.php:1052
+#, php-format
+msgid "editors_x_minutes"
+msgstr "%s 分钟"
+
+#: views/errors/error401.thtml:50 controllers/components/simple_acl.php:81
+#: controllers/components/simple_acl.php:82
+#: controllers/components/simple_acl.php:83 controllers/components/amo.php:607
+#: controllers/components/amo.php:608 controllers/components/amo.php:609
+#: controllers/reviews_controller.php:353
+#: controllers/reviews_controller.php:485
+#: controllers/collections_controller.php:438
+#: controllers/collections_controller.php:496
+#: controllers/collections_controller.php:504
+#: controllers/collections_controller.php:971
+#: controllers/collections_controller.php:1034
+#: controllers/collections_controller.php:1077
+msgid "error_access_denied"
+msgstr "ç¦æ­¢è®¿é—®"
+
+#: views/errors/error401.thtml:52
+msgid "error_access_denied_message"
+msgstr "ä½ æ— æƒæŸ¥çœ‹æ­¤é¡µã€‚"
+
+#: controllers/collections_controller.php:1039
+#, fuzzy
+msgid "error_addon_exists"
+msgstr "Add-on already exists!"
+
+#: controllers/developers_controller.php:200
+#: controllers/developers_controller.php:593
+#: controllers/developers_controller.php:1016
+#: controllers/developers_controller.php:1429
+#: controllers/downloads_controller.php:95
+#: controllers/downloads_controller.php:102
+#: controllers/downloads_controller.php:164
+#: controllers/statistics_controller.php:135
+#: controllers/previews_controller.php:115
+#: controllers/previews_controller.php:206
+#: controllers/previews_controller.php:307
+#: controllers/reviews_controller.php:77
+#: controllers/reviews_controller.php:240
+#: controllers/reviews_controller.php:332
+#: controllers/reviews_controller.php:340 controllers/api_controller.php:123
+#: controllers/api_controller.php:759 controllers/addons_controller.php:131
+#: controllers/addons_controller.php:197
+#: controllers/addons_controller.php:1407
+#: controllers/addons_controller.php:1465
+#: controllers/addons_controller.php:1469
+#: controllers/addons_controller.php:1503
+#: controllers/editors_controller.php:265
+#: controllers/collections_controller.php:1041
+#: controllers/collections_controller.php:1074
+msgid "error_addon_notfound"
+msgstr "附加组件未找到ï¼"
+
+#: controllers/files_controller.php:83 controllers/files_controller.php:196
+msgid "error_addon_notviewable"
+msgstr "此附加组件在这里无法查看。"
+
+#: controllers/reviews_controller.php:246
+msgid "error_addon_selfreview"
+msgstr "ä½ ä¸èƒ½å®¡æŸ¥è‡ªå·±çš„附加组件"
+
+#: controllers/addons_controller.php:970
+msgid "error_browse_no_addons"
+msgstr "本类无附加组件。"
+
+#: controllers/api_controller.php:424
+#, fuzzy
+msgid "error_collection_feed_notfound"
+msgstr "Add-on feed not found."
+
+#: views/users/register.thtml:65 views/users/edit.thtml:194
+msgid "error_email_invalid"
+msgstr "è¿™ä¸æ˜¯ä¸€ä¸ªæœ‰æ•ˆçš„电å­é‚®ä»¶åœ°å€ã€‚"
+
+#: views/users/pwreset.thtml:74 views/users/register.thtml:70
+#: views/users/register.thtml:80 views/users/register.thtml:86
+#: views/users/edit.thtml:105 views/users/edit.thtml:111
+#: views/users/edit.thtml:192 views/admin/users_edit.thtml:78
+#: views/admin/users_edit.thtml:83 views/reviews/add.thtml:80
+#: views/reviews/add.thtml:104
+msgid "error_field_required"
+msgstr "该项目ä¸èƒ½ä¸ºç©ºã€‚"
+
+#: controllers/files_controller.php:75 controllers/files_controller.php:93
+#: controllers/files_controller.php:96 controllers/files_controller.php:163
+#: controllers/files_controller.php:176 controllers/files_controller.php:185
+#: controllers/files_controller.php:204 controllers/editors_controller.php:412
+msgid "error_file_notfound"
+msgstr "文件未找到ï¼"
+
+#. %s is a filename
+#: controllers/editors_controller.php:430
+#, php-format
+msgid "error_file_x_notfound"
+msgstr "文件错误: %s ä¸å­˜åœ¨ã€‚"
+
+#: views/collections/add.thtml:55 views/collections/edit.thtml:89
+#: views/users/register.thtml:54 views/users/edit.thtml:81
+#: views/reviews/add.thtml:70 controllers/groups_controller.php:80
+#: controllers/groups_controller.php:102
+msgid "error_formerrors"
+msgstr "表å•æœ‰é”™è¯¯ï¼Œè¯·æ›´æ­£åŽé‡æ–°æ交。"
+
+#: views/users/register.thtml:109
+msgid "error_invalid_captcha"
+msgstr "验è¯ç æ— æ•ˆï¼è¯·é‡è¯•ã€‚"
+
+#: views/users/register.thtml:100 views/users/edit.thtml:125
+#: views/admin/users_edit.thtml:101
+msgid "error_invalid_url"
+msgstr "URLæ ¼å¼æ— æ•ˆã€‚有效的URL类似于 http://example.com/ 。"
+
+#. %s is a string representing what's missing. Example: file_id
+#: controllers/downloads_controller.php:65
+#: controllers/users_controller.php:185 controllers/users_controller.php:264
+#: controllers/users_controller.php:559 controllers/users_controller.php:653
+#: controllers/reviews_controller.php:71
+#: controllers/reviews_controller.php:234
+#: controllers/reviews_controller.php:325
+#: controllers/reviews_controller.php:473
+#: controllers/reviews_controller.php:475
+#: controllers/addons_controller.php:182
+#: controllers/addons_controller.php:1381
+#: controllers/addons_controller.php:1455
+#: controllers/collections_controller.php:266
+#: controllers/collections_controller.php:285
+#: controllers/collections_controller.php:346
+#: controllers/collections_controller.php:443
+#: controllers/collections_controller.php:482
+#: controllers/collections_controller.php:936
+#: controllers/collections_controller.php:959
+#: controllers/collections_controller.php:960
+#: controllers/collections_controller.php:975
+#: controllers/collections_controller.php:977
+#: controllers/collections_controller.php:994
+#: controllers/collections_controller.php:1003
+#: controllers/collections_controller.php:1016
+#: controllers/collections_controller.php:1017
+#: controllers/collections_controller.php:1024
+#: controllers/collections_controller.php:1070
+#: controllers/collections_controller.php:1090
+#, php-format
+msgid "error_missing_argument"
+msgstr "缺少å‚æ•°: %s"
+
+#: controllers/components/amo.php:507 controllers/components/amo.php:532
+msgid "error_no_files_in_addon"
+msgstr "没有文件"
+
+#: controllers/previews_controller.php:200
+msgid "error_preview_notfound"
+msgstr "Preview not found!"
+
+#: views/addons/display.thtml:400 views/reviews/add.thtml:98
+msgid "error_review_rating_required"
+msgstr "你必须选择一个评分。"
+
+#: controllers/users_controller.php:160
+msgid "error_user_already_confirmed"
+msgstr "这个用户å¸æˆ·å·²ç»ç¡®è®¤ã€‚"
+
+#: controllers/users_controller.php:202 controllers/users_controller.php:276
+#: controllers/users_controller.php:569 controllers/users_controller.php:581
+#: controllers/users_controller.php:587 controllers/users_controller.php:610
+#: controllers/users_controller.php:627
+msgid "error_user_badconfirmationcode"
+msgstr "无效的确认ç ï¼"
+
+#: views/users/pwreset.thtml:79 views/users/register.thtml:75
+#: views/users/edit.thtml:183
+msgid "error_user_confirmpw_nomatch"
+msgstr "密ç ä¸åŒ¹é…。"
+
+#: views/users/register.thtml:65 views/users/edit.thtml:190
+#: controllers/users_controller.php:617
+msgid "error_user_email_notunique"
+msgstr "这个邮件地å€å·²ç»è¢«å…¶ä»–用户使用。"
+
+#: controllers/users_controller.php:596
+msgid "error_user_emailchange_expired"
+msgstr ""
+"更改邮件已ç»è¿‡æœŸã€‚请在用户设置中å†æ¬¡ä¿®æ”¹ä½ çš„邮件地å€å¹¶åœ¨æ”¶åˆ°ç¡®è®¤é‚®ä»¶ä»¥åŽå°½å¿«"
+"点击其中的链接。"
+
+#: controllers/collections_controller.php:985
+#, fuzzy
+msgid "error_user_exists"
+msgstr ""
+"Users can only have one role at a time. Please remove the user from any "
+"existing roles before continuing."
+
+#: views/users/register.thtml:91 views/users/edit.thtml:116
+#: views/admin/users_edit.thtml:88
+msgid "error_user_nickname_notunique"
+msgstr "这个昵称已ç»è¢«ä½¿ç”¨ã€‚"
+
+#: views/users/pwreset.thtml:54 controllers/users_controller.php:191
+#: controllers/users_controller.php:270 controllers/users_controller.php:603
+#: controllers/users_controller.php:659
+#: controllers/collections_controller.php:988
+#: controllers/collections_controller.php:998
+msgid "error_user_notfound"
+msgstr "用户未找到ï¼"
+
+#: views/users/activatefirst.thtml:47
+msgid "error_user_unconfirmed"
+msgstr "请根æ®ä½ çš„邮件中收到的代ç å…ˆç¡®è®¤ä½ çš„用户å¸å·ã€‚"
+
+#: views/users/login.thtml:67
+msgid "error_username_or_pw_wrong"
+msgstr "错误的用户å或密ç ï¼"
+
+#: controllers/editors_controller.php:260
+msgid "error_version_notfound"
+msgstr "版本未找到ï¼"
+
+#: views/users/delete.thtml:125 views/users/edit.thtml:173
+msgid "error_wrong_password"
+msgstr "输入密ç é”™è¯¯ï¼"
+
+#: views/elements/amo2009/homepage_addon.thtml:122
+#: views/elements/feature.thtml:122
+msgid "feature_learnmore"
+msgstr "了解更多"
+
+# %1 is the add-on name
+#. %1 is the add-on name
+#: views/elements/amo2009/homepage_addon.thtml:123
+#: views/elements/feature.thtml:123
+#, php-format
+msgid "feature_learnmore_about_addon"
+msgstr "了解有关 %1$s 的更多内容"
+
+#. %1$s is a number
+#: views/elements/amo2009/reviews.thtml:52
+#: views/elements/addon_listitem.thtml:112 views/elements/feature.thtml:99
+#: views/addons/browse_thumbs.thtml:86
+#, php-format
+msgid "feature_reviews"
+msgid_plural "feature_reviews"
+msgstr[0] "%1$s æ¡æ„è§"
+msgstr[1] "%1$s æ¡æ„è§"
+
+#: views/elements/amo2009/homepage_addon.thtml:127
+#: views/elements/feature.thtml:127
+msgid "feature_view_more_from_category"
+msgstr "查看更多"
+
+#. This appears on a page that views the source of an add-on. This link will return
+#. the user to the add-on's main page
+#: views/files/browse.thtml:65
+#, fuzzy
+msgid "file_browser_link_addon"
+msgstr "Back to add-on"
+
+#. There is a list of directories and files on the page. Clicking this will show the
+#. contents of all the directories (normally you would click on each one to see the
+#. contents)
+#: views/files/browse.thtml:67
+#, fuzzy
+msgid "file_browser_link_expand_all"
+msgstr "Expand all"
+
+#. This appears on a page that views the source of an add-on. This link will return
+#. the user to the add-on's review page (it only appears if the add-on is being
+#. reviewed)
+#: views/files/browse.thtml:64
+#, fuzzy
+msgid "file_browser_link_review"
+msgstr "Back to review"
+
+#. The title of the page for viewing an add-on's source.
+#. %1$s is the name of the add-on
+#. %2$s is the name of the current application (e.g. Firefox or Thunderbird)
+#: views/files/browse.thtml:46
+#, fuzzy
+msgid "file_browser_title"
+msgstr "%1$s :: File Browser :: %2$s Add-ons"
+
+#. This appears on a page that views the source of an add-on. There is a list of
+#. directories and files on the page. Clicking this link will toggle between an
+#. expanded or a collapsed list. This string should be kept short.
+#: views/files/browse.thtml:68
+#, fuzzy
+msgid "file_browser_toggle_expand_collapse"
+msgstr "+/-"
+
+#. Link text for the AMO About page.
+#: views/elements/footer.thtml:72 views/layouts/amo2009.thtml:341
+#, fuzzy
+msgid "footer_a_about"
+msgstr "About"
+
+#. Link text to the AMO blog.
+#: views/elements/footer.thtml:74 views/layouts/amo2009.thtml:343
+#, fuzzy
+msgid "footer_a_blog"
+msgstr "Blog"
+
+#. Link text to the Frequently Asked Questions page.
+#: views/elements/footer.thtml:73 views/layouts/amo2009.thtml:342
+#, fuzzy
+msgid "footer_a_faq"
+msgstr "FAQ"
+
+#. Full text for the FAQ abbreviation.
+#: views/elements/footer.thtml:73 views/pages/collector_features.thtml:72
+#: views/layouts/amo2009.thtml:342
+#, fuzzy
+msgid "footer_abbr_faq"
+msgstr "Frequently Asked Questions"
+
+#: views/elements/footer.thtml:67 views/layouts/amo2009.thtml:336
+msgid "footer_all_rights_reserved"
+msgstr "所有æƒåˆ©ä¿ç•™"
+
+#: views/elements/footer.thtml:67 views/layouts/amo2009.thtml:336
+msgid "footer_copyright"
+msgstr "版æƒæ‰€æœ‰"
+
+#: views/elements/footer.thtml:71 views/layouts/amo2009.thtml:340
+msgid "footer_credits"
+msgstr "贡献者"
+
+#: views/elements/footer.thtml:76 views/layouts/amo2009.thtml:346
+msgid "footer_disclaimer"
+msgstr ""
+"Mozilla出于好æ„æ供这些应用程åºï¼Œå¹¶ä¸è¡¨æ˜Žå’Œè¿™äº›åº”用程åºæˆ–者任何相关的信æ¯æœ‰å…³"
+"è”。任何有关这些应用程åºçš„问题ã€æŠ±æ€¨æˆ–者è¦æ±‚应该直接å‘相应的软件厂商æ出。"
+
+#: views/elements/footer.thtml:61 views/layouts/amo2009.thtml:332
+msgid "footer_lang_form_lang_submit_go"
+msgstr "转到"
+
+#: views/elements/footer.thtml:70 views/layouts/amo2009.thtml:339
+msgid "footer_legal_notices"
+msgstr "法律声明"
+
+#: views/elements/footer.thtml:50 views/layouts/amo2009.thtml:321
+msgid "footer_other_languages"
+msgstr "其他语言:"
+
+#: views/elements/footer.thtml:69 views/layouts/amo2009.thtml:338
+msgid "footer_privacy_policy"
+msgstr "éšç§ç­–ç•¥"
+
+#: models/addontype.php:79
+msgid "general_addontype_dict"
+msgstr "å­—å…¸"
+
+# Plural in this context means many of the add-on type
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:100
+msgid "general_addontype_dict_plural"
+msgstr "å­—å…¸"
+
+#: models/addontype.php:75
+msgid "general_addontype_extension"
+msgstr "扩展"
+
+# Plural in this context means many of the add-on type
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:98
+msgid "general_addontype_extension_plural"
+msgstr "扩展"
+
+#: models/addontype.php:85
+msgid "general_addontype_lpaddon"
+msgstr "语言包(附加组件)"
+
+# Plural in this context means many of the add-on type
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:103
+msgid "general_addontype_lpaddon_plural"
+msgstr "语言包(附加组件)"
+
+#: models/addontype.php:83
+msgid "general_addontype_lpapp"
+msgstr "语言包(应用程åºï¼‰"
+
+# Plural in this context means many of the add-on type
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:102
+msgid "general_addontype_lpapp_plural"
+msgstr "语言包(应用程åºï¼‰"
+
+#: models/addontype.php:87
+msgid "general_addontype_plugin"
+msgstr "æ’件"
+
+# Plural in this context means many of the add-on type
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:104
+msgid "general_addontype_plugin_plural"
+msgstr "æ’件"
+
+#: models/addontype.php:81
+msgid "general_addontype_search"
+msgstr "æœç´¢å¼•æ“Ž"
+
+# Plural in this context means many of the add-on type
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:101
+msgid "general_addontype_search_plural"
+msgstr "æœç´¢å¼•æ“Ž"
+
+#: models/addontype.php:77
+msgid "general_addontype_theme"
+msgstr "主题"
+
+# Plural in this context means many of the add-on type
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:99
+msgid "general_addontype_theme_plural"
+msgstr "主题"
+
+#: config/language.php:367
+#, fuzzy
+msgid "general_languages_all_locales"
+msgstr "All Locales"
+
+#: views/layouts/amo2009.thtml:249
+#, fuzzy
+msgid "header_brand_name"
+msgstr "Mozilla"
+
+#. %1$s is the application name. Example: Firefox
+#: views/elements/header.thtml:111 views/elements/header.thtml:122
+#: views/layouts/amo2009.thtml:248
+#, php-format
+msgid "header_home_tooltip"
+msgstr "返回附加组件 %1$s 的主页"
+
+#: views/elements/header.thtml:87
+msgid "header_main_firefox_header"
+msgstr "Firefox 附加组件"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:218
+#, fuzzy
+msgid "header_main_firefox_header_with_logo"
+msgstr ""
+"Add-ons <em>for</em> <img alt=\"Firefox\" src=\"%1$s\" /> <strong>Firefox</"
+"strong>"
+
+#: views/elements/header.thtml:99
+msgid "header_main_header"
+msgstr "附加组件"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:242
+#, fuzzy
+msgid "header_main_header_with_logo"
+msgstr "Add-ons <img alt=\"Add-ons\" src=\"%1$s\" />"
+
+#: views/elements/header.thtml:90
+msgid "header_main_seamonkey_header"
+msgstr "Seamonkey 附加组件"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:224
+#, fuzzy
+msgid "header_main_seamonkey_header_with_logo"
+msgstr ""
+"Add-ons <em>for</em> <img alt=\"seamonkey\" src=\"%1$s\" /> "
+"<strong>SeaMonkey</strong>"
+
+#: views/elements/header.thtml:93
+msgid "header_main_sunbird_header"
+msgstr "Sunbird 附加组件"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:230
+#, fuzzy
+msgid "header_main_sunbird_header_with_logo"
+msgstr ""
+"Add-ons <em>for</em> <img alt=\"sunbird\" src=\"%1$s\" /> <strong>Sunbird</"
+"strong>"
+
+#: views/elements/header.thtml:96
+msgid "header_main_thunderbird_header"
+msgstr "Thunderbird 附加组件"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:236
+#, fuzzy
+msgid "header_main_thunderbird_header_with_logo"
+msgstr ""
+"Add-ons <em>for</em> <img alt=\"thunderbird\" src=\"%1$s\" /> "
+"<strong>Thunderbird</strong>"
+
+#: views/layouts/amo2009.thtml:205
+#, fuzzy
+msgid "header_navaccess_applications_menu"
+msgstr "Skip to other applications menu"
+
+#: views/layouts/amo2009.thtml:204
+#, fuzzy
+msgid "header_navaccess_categories_menu"
+msgstr "Skip to categories menu"
+
+#: views/layouts/amo2009.thtml:202
+#, fuzzy
+msgid "header_navaccess_main_content"
+msgstr "Skip to main content"
+
+#: views/layouts/amo2009.thtml:203
+#, fuzzy
+msgid "header_navaccess_search_form"
+msgstr "Skip to search form"
+
+#: views/elements/header.thtml:62
+msgid "header_navlink_addons"
+msgstr "附加组件"
+
+#: views/elements/developers/sidebar.thtml:72
+#: views/elements/developers/myaddons.thtml:50 views/elements/header.thtml:159
+#: views/addons/display.thtml:378
+msgid "header_navlink_login"
+msgstr "登录"
+
+#: views/elements/header.thtml:156 views/layouts/amo2009.thtml:304
+msgid "header_navlink_logout"
+msgstr "注销"
+
+#: views/elements/header.thtml:145 views/layouts/amo2009.thtml:303
+msgid "header_navlink_myaccount"
+msgstr "我的å¸æˆ·"
+
+#: views/elements/header.thtml:158
+msgid "header_navlink_register"
+msgstr "注册"
+
+#. %1 is the URL to the registration page
+#. %2 is the URL to the login page
+#: views/layouts/amo2009.thtml:278
+#, fuzzy
+msgid "header_navlink_register_or_login"
+msgstr "<a href=\"%1$s\">Register</a> or <a href=\"%2$s\">Log in</a>"
+
+#: views/layouts/amo2009.thtml:285
+#, fuzzy
+msgid "header_navlink_tools"
+msgstr "Tools"
+
+#. %s is the add-on name
+#: views/elements/collections_interactive_addon.thtml:62
+#: views/elements/amo2009/homepage_addon.thtml:77
+#: views/elements/addon_discussionheader.thtml:62
+#: views/elements/addon_listitem.thtml:67 views/elements/feature.thtml:84
+#: views/addons/category_landing.thtml:87 views/addons/browse_thumbs.thtml:60
+#, php-format
+msgid "img_preview_of"
+msgstr "%s 的预览图"
+
+# %1 is the login URL for the link tag
+#. %1 is the login URL for the link tag
+#. %2 is the link to an explanatory page.
+#: views/elements/amo2009/install.thtml:307 views/elements/install.thtml:255
+msgid "install_a_login_to_install"
+msgstr "<a href=\"%1$s\">登录</a>以便安装这个附加组件"
+
+#. %1 is the URL for the Experimental Add-ons section of the FAQ page
+#: views/elements/amo2009/install.thtml:283 views/elements/install.thtml:232
+#, fuzzy
+msgid "install_button_confirm_exp_install"
+msgstr ""
+"Let me install this experimental add-on. <a href=\"%1$s\">What's this?</a>"
+
+#. %1$s is the application name. Example: Firefox
+#. %2$s is an optional string used to specify a platform. Example: (Windows)
+#: views/elements/amo2009/install.thtml:128 views/elements/install.thtml:75
+#, php-format
+msgid "install_button_text"
+msgstr "安装到 %s %s"
+
+# %1 is the add-on name, %2 is the app name
+#. %1 is the add-on name, %2 is the app name
+#: views/elements/amo2009/install.thtml:191
+#: views/elements/amo2009/install.thtml:206
+#: views/elements/amo2009/install.thtml:249
+#: views/elements/amo2009/install.thtml:298 views/elements/install.thtml:150
+#: views/elements/install.thtml:165 views/elements/install.thtml:202
+#: views/elements/install.thtml:246
+#, php-format
+msgid "install_button_title"
+msgstr "安装 %1$s 到 %2$s"
+
+#. %1$s is the add-on name
+#: views/elements/amo2009/install.thtml:200 views/elements/install.thtml:159
+#, php-format
+msgid "install_download"
+msgstr "下载 %1$s"
+
+#: views/elements/amo2009/install.thtml:147 views/elements/install.thtml:94
+msgid "install_error_addon_not_found"
+msgstr "该附加组件ä¸å¯ç”¨ã€‚"
+
+#: views/addons/dictionaries.thtml:65
+msgid "langtools_a11y_tablesummary"
+msgstr "语言包和字典列表"
+
+#: views/addons/dictionaries.thtml:47
+msgid "langtools_download_dictionary"
+msgstr "下载字典"
+
+#: views/addons/dictionaries.thtml:48
+msgid "langtools_download_langpack"
+msgstr "下载语言包"
+
+#: views/addons/dictionaries.thtml:63 controllers/components/amo.php:685
+#: controllers/addons_controller.php:1239
+msgid "langtools_header_dicts_and_langpacks"
+msgstr "字典和语言包"
+
+#: views/addons/dictionaries.thtml:44
+msgid "langtools_install_dictionary"
+msgstr "安装字典"
+
+#: views/addons/dictionaries.thtml:45
+msgid "langtools_install_langpack"
+msgstr "安装语言包"
+
+#: views/addons/dictionaries.thtml:69
+msgid "langtools_tableheader_dictionary"
+msgstr "å­—å…¸"
+
+#: views/addons/dictionaries.thtml:70
+msgid "langtools_tableheader_langpack"
+msgstr "语言包"
+
+#: views/addons/dictionaries.thtml:68
+msgid "langtools_tableheader_language"
+msgstr "语言"
+
+#: models/license.php:65
+#, fuzzy
+msgid "license_custom"
+msgstr "Custom License"
+
+#: config/bootstrap.php:303
+#, fuzzy
+msgid "licenses_bsd"
+msgstr "BSD License"
+
+#: config/bootstrap.php:298
+#, fuzzy
+msgid "licenses_gpl_2.0"
+msgstr "GNU General Public License, version 2.0"
+
+#: config/bootstrap.php:299
+#, fuzzy
+msgid "licenses_gpl_3.0"
+msgstr "GNU General Public License, version 3.0"
+
+#: config/bootstrap.php:300
+#, fuzzy
+msgid "licenses_lgpl_2.1"
+msgstr "GNU Lesser General Public License, version 2.1"
+
+#: config/bootstrap.php:301
+#, fuzzy
+msgid "licenses_lgpl_3.0"
+msgstr "GNU Lesser General Public License, version 3.0"
+
+#: config/bootstrap.php:302
+#, fuzzy
+msgid "licenses_mit"
+msgstr "MIT/X11 License"
+
+#: config/bootstrap.php:297
+#, fuzzy
+msgid "licenses_mpl_1.1"
+msgstr "Mozilla Public License, version 1.1"
+
+#: views/users/emailchange.thtml:51 views/users/delete.thtml:55
+#: views/users/delete.thtml:137 views/users/edit.thtml:74
+#: views/reviews/flag.thtml:54
+msgid "link_return_to_front_page"
+msgstr "点击这里返回开始的页é¢ã€‚"
+
+#: views/elements/amo2009/addon_list_options.thtml:46
+#: views/elements/addon_list_options.thtml:46
+msgid "list_sortby_date"
+msgstr "日期"
+
+#: views/elements/amo2009/addon_list_options.thtml:47
+#: views/elements/addon_list_options.thtml:47
+msgid "list_sortby_downloads"
+msgstr "下载次数"
+
+#: views/elements/amo2009/addon_list_options.thtml:45
+#: views/elements/addon_list_options.thtml:45
+msgid "list_sortby_name"
+msgstr "附加组件å称"
+
+#: views/elements/amo2009/addon_list_options.thtml:48
+#: views/elements/addon_list_options.thtml:48
+msgid "list_sortby_rating"
+msgstr "评分"
+
+#: config/bootstrap.php:278
+msgid "main_prettyname_fennec"
+msgstr "Fennec"
+
+#: config/bootstrap.php:274
+msgid "main_prettyname_firefox"
+msgstr "Firefox"
+
+#: config/bootstrap.php:277
+msgid "main_prettyname_seamonkey"
+msgstr "SeaMonkey"
+
+#: config/bootstrap.php:276
+msgid "main_prettyname_sunbird"
+msgstr "Sunbird"
+
+#: config/bootstrap.php:275
+msgid "main_prettyname_thunderbird"
+msgstr "Thunderbird"
+
+#: views/elements/addon_categories.thtml:52
+msgid "nav_category_dicts_langpacks"
+msgstr "语言包"
+
+#: views/elements/addon_categories.thtml:55
+msgid "nav_category_themes"
+msgstr "主题"
+
+#: views/elements/app_chooser.thtml:47 views/layouts/amo2009.thtml:255
+msgid "other_apps_tooltip"
+msgstr "查找其他应用程åºçš„附加组件"
+
+# In a user list: user 1, user 2, "others"
+#. In a user list: user 1, user 2, "others"
+#: views/helpers/addons_html.php:222
+msgid "other_users"
+msgstr "其他"
+
+#: controllers/pages_controller.php:90
+msgid "page_title_appversions"
+msgstr "应用程åºç‰ˆæœ¬"
+
+#: controllers/pages_controller.php:115
+#, fuzzy
+msgid "page_title_collector"
+msgstr "Add-on Collector"
+
+#: controllers/pages_controller.php:117
+#, fuzzy
+msgid "page_title_collector_faq"
+msgstr "Add-on Collector FAQ"
+
+#: controllers/pages_controller.php:119
+#, fuzzy
+msgid "page_title_collector_features"
+msgstr "Add-on Collector Features"
+
+#: controllers/pages_controller.php:122
+#, fuzzy
+msgid "page_title_collector_firstrun"
+msgstr "Welcome to the Add-on Collector"
+
+#: controllers/pages_controller.php:92
+msgid "page_title_credits"
+msgstr "贡献者"
+
+#: controllers/pages_controller.php:113
+#, fuzzy
+msgid "page_title_developer_faq"
+msgstr "Developer FAQ"
+
+#: controllers/pages_controller.php:111
+#, fuzzy
+msgid "page_title_faq"
+msgstr "Frequently Asked Questions"
+
+#: controllers/pages_controller.php:94
+msgid "page_title_fashionyourfirefox_faq"
+msgstr "常è§é—®ç­”之定制自己的Firefox"
+
+#: controllers/pages_controller.php:101
+msgid "page_title_policy"
+msgstr "附加组件策略"
+
+#: controllers/pages_controller.php:103
+msgid "page_title_privacy"
+msgstr "Mozilla éšç§ç­–ç•¥"
+
+#: controllers/pages_controller.php:105
+msgid "page_title_review_guide"
+msgstr "评论指导"
+
+#: controllers/pages_controller.php:107
+msgid "page_title_sandbox"
+msgstr "沙盒评论系统"
+
+#: controllers/pages_controller.php:109
+msgid "page_title_submissionhelp"
+msgstr "æ交说明"
+
+#: views/pages/appversions.thtml:87
+msgid "pages_appversions_guid"
+msgstr "GUID"
+
+#: views/pages/appversions.thtml:79 controllers/pages_controller.php:90
+msgid "pages_appversions_header"
+msgstr "正确的应用程åºç‰ˆæœ¬"
+
+#: views/pages/appversions.thtml:80
+msgid "pages_appversions_intro"
+msgstr ""
+"æ交到Mozilla Add-ons的附加组件必须带有 install.rdf 文件,其中至少è¦æ”¯æŒä»¥ä¸‹"
+"应用之一。对于这些应用,åªæœ‰ä»¥ä¸‹åˆ—出的版本是å¯ä»¥ä½¿ç”¨çš„。"
+
+#. %s is a full <a> tag
+#: views/pages/appversions.thtml:93
+#, php-format
+msgid "pages_appversions_required_files"
+msgstr ""
+"如果你支æŒçš„应用并ä¸éœ€è¦ä¸€ä¸ªinstall.rdf文件,你ä»å¿…须包括一个符åˆè¦æ±‚的属性作"
+"为指定的 %s 。"
+
+#. this is the text inside of an <a> tag for pages_appversions_required_files. This
+#. should be fixed.
+#: views/pages/appversions.thtml:93
+msgid "pages_appversions_required_files_link"
+msgstr "这里"
+
+#: views/pages/appversions.thtml:88
+msgid "pages_appversions_versions"
+msgstr "版本"
+
+#: views/pages/policy.thtml:51
+msgid "pages_policy_sandbox_link"
+msgstr "沙盒信æ¯é¡µé¢"
+
+#: views/elements/pagination.thtml:53
+msgid "pagination_next_page"
+msgstr "下一页"
+
+#: views/elements/pagination.thtml:52
+msgid "pagination_previous_page"
+msgstr "å‰ä¸€é¡µ"
+
+#: views/elements/recaptcha.thtml:65
+msgid "recaptcha_enter_both_words"
+msgstr "è¯·è¾“å…¥ä¸‹é¢ <strong>两个è¯</strong> , <strong>以空格 分隔</strong>."
+
+#: views/elements/recaptcha.thtml:83
+msgid "recaptcha_enter_here"
+msgstr "在这里输入你的答案:"
+
+#: views/elements/recaptcha.thtml:74
+msgid "recaptcha_enter_whatyouhear"
+msgstr "请输入你å¬åˆ°çš„内容。"
+
+# %1 is the link switching refreshing the captcha
+# %2 is the link switching to a text captcha
+#. %1 is the link switching refreshing the captcha
+#. %2 is the link switching to a text captcha
+#: views/elements/recaptcha.thtml:77
+msgid "recaptcha_hardtohear_text"
+msgstr ""
+"如果觉得很难ç†è§£ï¼Œä½ å¯ä»¥ <a href=\"%1$s\">收å¬å…¶ä»–内容 </a> 或者 <a href=\"%2"
+"$s\">切æ¢å›žæ–‡æœ¬æ–¹å¼</a>。"
+
+# %1 is the link switching refreshing the captcha
+# %2 is the link switching to an audio captcha
+#. %1 is the link switching refreshing the captcha
+#. %2 is the link switching to an audio captcha
+#: views/elements/recaptcha.thtml:68
+msgid "recaptcha_hardtoread_text"
+msgstr ""
+"如果觉得难以辨识,你å¯ä»¥ <a href=\"%1$s\">å°è¯•å…¶ä»–字符</a> 或者改为<a href="
+"\"%2$s\">收å¬éªŒè¯ç </a> 。"
+
+#: views/users/register.thtml:105
+msgid "recaptcha_label"
+msgstr "你是人类?"
+
+#: views/users/register.thtml:106
+msgid "recaptcha_whatsthis"
+msgstr "这是什么?"
+
+#: controllers/reviews_controller.php:559
+msgid "review_flag_error"
+msgstr "该评论标记错误!"
+
+#: models/reviews_moderation_flag.php:69
+msgid "review_flag_reason_bug_support"
+msgstr "错误的缺陷报告或支æŒè¯·æ±‚"
+
+#: views/reviews/display.thtml:103 views/reviews/display.thtml:186
+msgid "review_flag_reason_instructions"
+msgstr "举报该评论 (选择一个原因)"
+
+#: models/reviews_moderation_flag.php:67
+msgid "review_flag_reason_language"
+msgstr "ä¸æ­£ç¡®çš„语言/对è¯"
+
+#: models/reviews_moderation_flag.php:71
+msgid "review_flag_reason_other"
+msgstr "其他 (请说明)"
+
+#: models/reviews_moderation_flag.php:65
+msgid "review_flag_reason_spam"
+msgstr "çŒæ°´æˆ–其他éžè¯„论内容"
+
+#: views/reviews/display.thtml:91 views/reviews/display.thtml:175
+#: controllers/reviews_controller.php:555
+msgid "review_flag_success"
+msgstr "谢谢;该评论以被编辑标记为批准。"
+
+#: views/reviews/display.thtml:41
+msgid "review_flag_this"
+msgstr "报告此评论"
+
+#: views/reviews/display.thtml:42
+msgid "review_flag_this_titletip"
+msgstr "该评论ä¸é€‚当ã€ä¸å‡†ç¡®æˆ–者是垃圾信æ¯ï¼Ÿç‚¹å‡»è¿™é‡Œå°†å…¶æ ‡è®°ï¼Œæ请编辑审查。"
+
+# %1 is the URL of the support section, %2 for the review guidelines
+#. %1 is the URL of the support section, %2 for the review guidelines
+#: views/reviews/add.thtml:53
+msgid "review_guidelines_short"
+msgstr ""
+"<p>è®°ä½è¿™äº›æ示:</p><ul><li>撰写时就åƒå‘Šè¯‰ä½ çš„朋å‹ä½ å¯¹è¿™ä¸ªé™„加组件的使用体"
+"验。写明具体的和有帮助的细节,例如你喜欢和/或ä¸å–œæ¬¢çš„特性,用起æ¥å¦‚何方便,以"
+"åŠä»»ä½•ç¼ºç‚¹ã€‚é¿å…一些泛泛的说法,例如“很好â€æˆ–者“很差â€ï¼Œé™¤éžä½ èƒ½ç»™å‡ºç›¸åº”çš„ç†"
+"由。</li><li>请ä¸è¦åœ¨è¯„价中汇报缺陷。我们ä¸ä¼šè®©å¼€å‘者看到你的邮件地å€ï¼Œè€Œä»–们"
+"å¯èƒ½éœ€è¦è”系你以便帮助解决问题。å‚阅 <a href=\"%1$s\">有关支æŒçš„部分</a>获知"
+"如何å–得有关该附加组件的帮助。</li><li>请注æ„ä¿æŒè¯„论内容的文明,é¿å…使用ä¸é“"
+"德的语言,ä¸è¦é€éœ²ä»»ä½•ç§äººä¿¡æ¯ã€‚</li></ul><p>请阅读<a href=\"%2$s\">评论指å—"
+"</a>获å–有关评价附加组件的更多介ç»ã€‚</p>"
+
+#. %1 is the add-on name
+#: views/reviews/flag.thtml:56 views/reviews/display.thtml:55
+#: views/reviews/review_added.thtml:50
+#, php-format
+msgid "reviews_header"
+msgstr "对 %s çš„æ„è§"
+
+#: controllers/addons_controller.php:435
+msgid "rss_featuredaddons"
+msgstr "特别推è"
+
+#: controllers/addons_controller.php:432
+msgid "rss_newestaddons"
+msgstr "最新附加组件"
+
+#: controllers/addons_controller.php:434
+#, fuzzy
+msgid "rss_popularaddons"
+msgstr "Popular Add-ons"
+
+#: controllers/addons_controller.php:433
+msgid "rss_updatedaddons"
+msgstr "更新的附加组件"
+
+#: views/elements/search_mini.thtml:70
+#, fuzzy
+msgid "search"
+msgstr "Search"
+
+#: views/search/collections.thtml:51
+#, fuzzy
+msgid "search_collections_header"
+msgstr "Collection Search Results"
+
+#: controllers/search_controller.php:297
+#, fuzzy
+msgid "search_collections_pagetitle"
+msgstr "Collection Search Results"
+
+#: controllers/search_controller.php:99
+msgid "search_disabled"
+msgstr "现在ç¦æ­¢æœç´¢ï¼Œè¯·ç¨å€™å†è¯•ã€‚"
+
+#: views/elements/amo2009/search.thtml:188 views/elements/search.thtml:187
+#: views/elements/search_mini.thtml:54
+msgid "search_form_all_addons"
+msgstr "所有附加组件"
+
+#. This string is in the main category dropdown when searching
+#: views/elements/amo2009/search.thtml:204
+#, fuzzy
+msgid "search_form_all_collections"
+msgstr "all collections"
+
+#: views/elements/amo2009/search.thtml:184
+#: views/elements/amo2009/search.thtml:385
+#: views/elements/amo2009/search.thtml:408 views/elements/search.thtml:171
+#: views/elements/search.thtml:183 views/elements/search_mini.thtml:43
+#: views/elements/search_mini.thtml:49 views/layouts/mozilla.thtml:188
+msgid "search_form_default_text"
+msgstr "æœç´¢é™„加组件"
+
+#: views/elements/amo2009/search.thtml:184
+#: views/elements/amo2009/search.thtml:404
+#, fuzzy
+msgid "search_form_default_text_collections"
+msgstr "search for collections"
+
+#: views/elements/amo2009/search.thtml:206 views/elements/search.thtml:202
+msgid "search_form_submit_tooltip"
+msgstr "æœç´¢é™„加组件"
+
+#: views/elements/amo2009/search.thtml:184 views/elements/search.thtml:183
+#: views/elements/search_mini.thtml:49
+msgid "search_form_tooltip"
+msgstr "点击输入æœç´¢å†…容"
+
+#: views/elements/amo2009/search.thtml:186 views/elements/search.thtml:185
+#: views/elements/search_mini.thtml:52
+msgid "search_form_within"
+msgstr "范围"
+
+#: views/addons/searchengines.thtml:118
+msgid "search_landing_all_search_engines"
+msgstr "所有æœç´¢å¼•æ“Ž"
+
+#: views/addons/searchengines.thtml:114
+msgid "search_landing_browse_search_engines"
+msgstr "æµè§ˆæœç´¢å¼•æ“Ž"
+
+#: views/search/collections.thtml:58 views/search/index.thtml:59
+msgid "search_nothing_found"
+msgstr "未找到结果。"
+
+#: controllers/search_controller.php:185
+msgid "search_pagetitle"
+msgstr "æœç´¢é™„加组件"
+
+#: controllers/search_controller.php:242
+msgid "search_rss_description"
+msgstr "æœç´¢ç»“果收å–点"
+
+#. %s is the terms the user is searching for (a string)
+#: controllers/search_controller.php:241
+#, php-format
+msgid "search_rss_results_for"
+msgstr "æœç´¢ç»“æžœ: %s"
+
+#: views/elements/header.thtml:154 views/layouts/amo2009.thtml:296
+msgid "sidebar_navlink_admin_tools"
+msgstr "管ç†å‘˜å·¥å…·"
+
+#: views/elements/header.thtml:146 views/layouts/amo2009.thtml:288
+msgid "sidebar_navlink_developer_tools"
+msgstr "å¼€å‘者工具"
+
+#: views/elements/header.thtml:148 views/layouts/amo2009.thtml:290
+msgid "sidebar_navlink_editor_tools"
+msgstr "编辑工具"
+
+#: views/layouts/amo2009.thtml:302
+msgid "sidebar_navlink_welcome"
+msgstr "欢迎"
+
+#. %s is the user's name
+#: views/layouts/amo2009.thtml:302
+#, php-format
+msgid "sidebar_navlink_welcome_name"
+msgstr "欢迎你, %s"
+
+#: views/elements/pitch.thtml:50 views/elements/pitch.thtml:55
+msgid "sidebar_pitch_dictionary"
+msgstr "å­—å…¸"
+
+#: views/elements/pitch.thtml:72
+msgid "sidebar_pitch_featured_addons"
+msgstr "特别的附加组件"
+
+#: views/elements/pitch.thtml:61
+msgid "sidebar_pitch_looking_for"
+msgstr "我è¦å¯»æ‰¾ä¸€ä¸ªï¼š"
+
+#: views/elements/pitch.thtml:70
+msgid "sidebar_pitch_newest_addons"
+msgstr "最新附加组件"
+
+#: views/elements/pitch.thtml:49
+msgid "sidebar_pitch_search"
+msgstr "æœç´¢å¼•æ“Ž"
+
+#: views/elements/pitch.thtml:69
+msgid "sidebar_pitch_subscribe_to"
+msgstr "订阅到"
+
+#: views/elements/pitch.thtml:48 views/elements/pitch.thtml:54
+msgid "sidebar_pitch_theme"
+msgstr "主题"
+
+#: views/elements/pitch.thtml:71
+msgid "sidebar_pitch_updated_addons"
+msgstr "更新的附加组件"
+
+#. %1$s is a number
+#: views/helpers/localization.php:65 views/developers/versions_edit.thtml:95
+#: views/addons/dictionaries.thtml:92
+#, php-format
+msgid "size_kb"
+msgstr "%1$s KB"
+
+#: views/elements/amo2009/stars.thtml:57 views/elements/stars.thtml:63
+msgid "stars_not_yet_rated"
+msgstr "尚未评分"
+
+# %1 is the number of stars this add-on has
+#. %1 is the number of stars this add-on has
+#: views/elements/amo2009/stars.thtml:49 views/elements/stars.thtml:54
+#, php-format
+msgid "stars_rated_x_outof_5"
+msgstr "评分 %s 超过了 5 星"
+
+#: views/statistics/addon.thtml:59
+msgid "statistics_addon_dashboard_link"
+msgstr "ä¿¡æ¯é¦–页"
+
+#: views/statistics/addon.thtml:58
+msgid "statistics_addon_developertools_link"
+msgstr "å¼€å‘者工具"
+
+#: views/statistics/addon.thtml:53
+msgid "statistics_addon_switch"
+msgstr "切æ¢é™„加组件"
+
+#. This is a date format.
+#. http://php.net/strftime
+#: views/statistics/rss/summary.thtml:54 views/statistics/addon.thtml:181
+msgid "statistics_date_shortmonth"
+msgstr "%m 月 %e 日"
+
+#. This is a date format.
+#. http://php.net/strftime
+#: views/statistics/rss/summary.thtml:40 views/statistics/addon.thtml:152
+msgid "statistics_date_shortmonthwithyear"
+msgstr "%Y 年 %m 月 %e 日"
+
+#. This is a date format.
+#. http://php.net/strftime
+#: views/statistics/rss/summary.thtml:41 views/statistics/rss/summary.thtml:48
+#: views/statistics/addon.thtml:161 views/statistics/addon.thtml:172
+msgid "statistics_date_weekdayshortmonth"
+msgstr "%m 月 %e 日 (%a)"
+
+#. %1$s is an add-on name and version. Example: Add-on 3.5
+#: controllers/components/stats.php:519
+#, php-format
+msgid "statistics_events_addon_created"
+msgstr "%1$s 已建立"
+
+#. %1$s is an application name and version. Example: Firefox 3.5
+#: controllers/components/stats.php:500
+#, php-format
+msgid "statistics_events_app_released"
+msgstr "%1$s å·²å‘布"
+
+#: views/statistics/addon.thtml:71
+msgid "statistics_help_close_link"
+msgstr "关闭"
+
+#: views/statistics/addon.thtml:60
+msgid "statistics_help_link"
+msgstr "帮助"
+
+#: views/statistics/index.thtml:83
+msgid "statistics_index_anotheraddon"
+msgstr "或者,选择其他附加组件"
+
+#: views/statistics/index.thtml:85
+msgid "statistics_index_anotheraddon_public"
+msgstr "或者,选择一个已公开å‘布的附加组件"
+
+#: views/statistics/index.thtml:71
+msgid "statistics_index_myaddons"
+msgstr "选择你的一个附加组件查看统计信æ¯"
+
+#: views/statistics/index.thtml:89
+msgid "statistics_index_selectaddon"
+msgstr "选择一个附加组件查看统计信æ¯"
+
+#: views/statistics/index.thtml:91
+msgid "statistics_index_selectaddon_public"
+msgstr "选择一个公开统计的附加组件"
+
+#: views/statistics/index.thtml:39
+msgid "statistics_index_title"
+msgstr "统计信æ¯"
+
+#: views/statistics/index.thtml:97
+msgid "statistics_index_view_button"
+msgstr "显示统计"
+
+#: views/statistics/addon.thtml:222 controllers/statistics_controller.php:247
+#, fuzzy
+msgid "statistics_js_download_csv"
+msgstr "View this table in CSV format"
+
+#: controllers/statistics_controller.php:246
+msgid "statistics_js_dropdowns_none"
+msgstr "æ— "
+
+#: controllers/statistics_controller.php:245
+msgid "statistics_js_dropdowns_removeplot"
+msgstr "删除此图"
+
+#: controllers/statistics_controller.php:248
+#, fuzzy
+msgid "statistics_js_groupby_selector_date"
+msgstr "Group by: Day"
+
+#: controllers/statistics_controller.php:251
+#, fuzzy
+msgid "statistics_js_groupby_selector_month"
+msgstr "Group by: Month"
+
+#: controllers/statistics_controller.php:249
+#, fuzzy
+msgid "statistics_js_groupby_selector_week"
+msgstr "Group by: Week"
+
+#: controllers/statistics_controller.php:250
+#, fuzzy
+msgid "statistics_js_groupby_selector_week_over_week"
+msgstr "Compare by: Week"
+
+#: controllers/statistics_controller.php:260
+msgid "statistics_js_plotselection_foundinrange"
+msgstr "范围内找到 %s 个"
+
+#: controllers/statistics_controller.php:270
+msgid "statistics_js_plotselection_options_addplot_name"
+msgstr "新增图"
+
+#: controllers/statistics_controller.php:271
+msgid "statistics_js_plotselection_options_addplot_tooltip"
+msgstr "为该图表增加图"
+
+#: controllers/statistics_controller.php:261
+msgid "statistics_js_plotselection_options_count_name_checked"
+msgstr "éšè—总计"
+
+#: controllers/statistics_controller.php:262
+msgid "statistics_js_plotselection_options_count_name_unchecked"
+msgstr "显示总计"
+
+#: controllers/statistics_controller.php:263
+msgid "statistics_js_plotselection_options_count_tooltip"
+msgstr "图表中图的数é‡"
+
+#: controllers/statistics_controller.php:275
+msgid "statistics_js_plotselection_options_csv_name"
+msgstr "查看数æ®ï¼ˆCSV)"
+
+#: controllers/statistics_controller.php:276
+msgid "statistics_js_plotselection_options_csv_tooltip"
+msgstr "获å–此数æ®çš„逗å·åˆ†éš”文件"
+
+#: controllers/statistics_controller.php:267
+msgid "statistics_js_plotselection_options_events_addon_name_checked"
+msgstr "éšè— %s 事件"
+
+#: controllers/statistics_controller.php:268
+msgid "statistics_js_plotselection_options_events_addon_name_unchecked"
+msgstr "显示 %s 事件"
+
+#: controllers/statistics_controller.php:269
+msgid "statistics_js_plotselection_options_events_addon_tooltip"
+msgstr "é‡ç½®æ­¤å›¾çš„附加组件å‘布日期"
+
+#: controllers/statistics_controller.php:264
+msgid "statistics_js_plotselection_options_events_firefox_name_checked"
+msgstr "éšè—Firefox事件"
+
+#: controllers/statistics_controller.php:265
+msgid "statistics_js_plotselection_options_events_firefox_name_unchecked"
+msgstr "显示Firefox事件"
+
+#: controllers/statistics_controller.php:266
+msgid "statistics_js_plotselection_options_events_firefox_tooltip"
+msgstr "é‡ç½®æ­¤å›¾çš„Firefoxå‘布日期"
+
+#: controllers/statistics_controller.php:272
+msgid "statistics_js_plotselection_options_resize_name_checked"
+msgstr "折å å›¾è¡¨"
+
+#: controllers/statistics_controller.php:273
+msgid "statistics_js_plotselection_options_resize_name_unchecked"
+msgstr "展开图表"
+
+#: controllers/statistics_controller.php:274
+msgid "statistics_js_plotselection_options_resize_tooltip"
+msgstr "调整图表尺寸"
+
+#: controllers/statistics_controller.php:254
+msgid "statistics_js_plotselection_selector_adu"
+msgstr "日访问用户"
+
+#: controllers/statistics_controller.php:256
+msgid "statistics_js_plotselection_selector_application"
+msgstr "应用程åº"
+
+#: controllers/statistics_controller.php:259
+msgid "statistics_js_plotselection_selector_custom"
+msgstr "自定义"
+
+#: controllers/statistics_controller.php:253
+msgid "statistics_js_plotselection_selector_downloads"
+msgstr "下载"
+
+#: controllers/statistics_controller.php:258
+msgid "statistics_js_plotselection_selector_os"
+msgstr "æ“作系统"
+
+#: controllers/statistics_controller.php:257
+msgid "statistics_js_plotselection_selector_status"
+msgstr "附加组件状æ€"
+
+#: controllers/statistics_controller.php:252
+msgid "statistics_js_plotselection_selector_summary"
+msgstr "汇总"
+
+#: controllers/statistics_controller.php:255
+msgid "statistics_js_plotselection_selector_version"
+msgstr "附加组件版本"
+
+#: controllers/components/stats.php:398
+msgid "statistics_longnames_application"
+msgstr "应用程åº"
+
+#: controllers/components/stats.php:400
+msgid "statistics_longnames_os"
+msgstr "æ“作系统"
+
+#: controllers/components/stats.php:399
+msgid "statistics_longnames_status"
+msgstr "附加组件状æ€"
+
+#: controllers/components/stats.php:401
+msgid "statistics_longnames_unknown"
+msgstr "未知"
+
+#: controllers/components/stats.php:397
+msgid "statistics_longnames_version"
+msgstr "附加组件版本"
+
+#: views/statistics/addon.thtml:118
+msgid "statistics_notice_data_insufficient"
+msgstr "没有足够的数æ®æ˜¾ç¤ºå›¾è¡¨ï¼Œè¯·ç¨åŽå†çœ‹ã€‚"
+
+#: views/statistics/addon.thtml:130
+msgid "statistics_notice_data_none"
+msgstr "你的附加组件还没有任何数æ®ï¼Œè¯·è¿‡å‡ å¤©å†æ¥ã€‚"
+
+#: views/statistics/addon.thtml:41
+msgid "statistics_notice_data_updating"
+msgstr ""
+"附加组件统计数æ®æ­£åœ¨æ›´æ–°ï¼Œç”±äºŽæˆ‘们的脚本正在更新这些信æ¯ï¼Œæ‰€ä»¥è¿‘期数æ®å¯èƒ½ä¸"
+"准确。请过几分钟å†å°è¯•ã€‚"
+
+#: views/statistics/addon.thtml:136
+msgid "statistics_notice_disabled"
+msgstr "ç¦ç”¨ç»Ÿè®¡ä¿¡æ¯ï¼Œè¯·ç¨åŽå†æ¥ã€‚"
+
+#: views/statistics/addon.thtml:123
+msgid "statistics_notice_nojavascript"
+msgstr "å¯ç”¨JavaScriptæ‰èƒ½æŸ¥é˜…统计信æ¯å›¾è¡¨ã€‚"
+
+#: views/statistics/addon.thtml:44
+msgid "statistics_notice_settings_updated"
+msgstr "你的设置已更新。"
+
+#: controllers/statistics_controller.php:60
+#: controllers/statistics_controller.php:71
+#: controllers/statistics_controller.php:74
+#: controllers/statistics_controller.php:240
+msgid "statistics_pagetitle"
+msgstr "统计信æ¯"
+
+#: views/statistics/addon.thtml:99
+msgid "statistics_plot_legend_adu"
+msgstr "日活跃用户"
+
+#: views/statistics/addon.thtml:95
+msgid "statistics_plot_legend_downloads"
+msgstr "日下载"
+
+#: views/statistics/addon.thtml:107
+msgid "statistics_plot_options_zoomin_alt"
+msgstr "缩å°"
+
+#: views/statistics/addon.thtml:106
+msgid "statistics_plot_options_zoomin_title"
+msgstr "缩å°åˆ°ä¸€ä¸ªæœˆ"
+
+#: views/statistics/addon.thtml:110
+msgid "statistics_plot_options_zoomout_alt"
+msgstr "放大"
+
+#: views/statistics/addon.thtml:109
+msgid "statistics_plot_options_zoomout_title"
+msgstr "放大到一个月"
+
+#: controllers/statistics_controller.php:283
+#, php-format
+msgid "statistics_rss_description"
+msgstr "%1$s çš„æ¯æ—¥ç»Ÿè®¡æ±‡æ€»"
+
+#: views/statistics/rss/summary.thtml:68
+msgid "statistics_rss_title_fulldate"
+msgstr "Y 年 %m 月 %e 日 (%a)"
+
+#: views/statistics/rss/summary.thtml:68
+#, php-format
+msgid "statistics_rss_title_statsfordate"
+msgstr "%1$s 的统计"
+
+#: views/statistics/settings.thtml:49
+msgid "statistics_settings_access_description"
+msgstr ""
+"默认情况下,åªæœ‰ä½ å’ŒMozillaå¯ä»¥è®¿é—®ä½ çš„é¢æ¿ä¸Šçš„ä¿¡æ¯ã€‚ä½ å¯ä»¥å¯¹å…¬ä¼—开放以便任何"
+"人都能查阅你的附加组件的数æ®ã€‚"
+
+#: views/statistics/settings.thtml:48
+msgid "statistics_settings_access_heading"
+msgstr "统计é¢æ¿è®¿é—®æƒé™"
+
+#: views/statistics/settings.thtml:51
+msgid "statistics_settings_access_private"
+msgstr "ç§æœ‰"
+
+#: views/statistics/settings.thtml:51
+msgid "statistics_settings_access_private_description"
+msgstr "åªæœ‰ä½ å’ŒMozillaå¯ä»¥æŸ¥é˜…这个附加组件的统计"
+
+#: views/statistics/settings.thtml:52
+msgid "statistics_settings_access_public"
+msgstr "公开"
+
+#: views/statistics/settings.thtml:52
+msgid "statistics_settings_access_public_description"
+msgstr "任何人都å¯ä»¥æŸ¥é˜…这个附加组件的统计"
+
+#: views/statistics/addon.thtml:251
+msgid "statistics_settings_change_link"
+msgstr "更改设置"
+
+#: views/statistics/addon.thtml:253
+msgid "statistics_settings_confidential"
+msgstr "请将这些信æ¯ä¿å¯†ã€‚"
+
+#: views/statistics/addon.thtml:245
+msgid "statistics_settings_currently_private"
+msgstr "本é¢æ¿ç›®å‰å¤„于<b>ç§æœ‰</b>状æ€ã€‚"
+
+#: views/statistics/addon.thtml:241
+msgid "statistics_settings_currently_public"
+msgstr "本é¢æ¿ç›®å‰å¤„于<b>公开</b>状æ€ã€‚"
+
+#: views/statistics/addon.thtml:246
+msgid "statistics_settings_locked_alt"
+msgstr "é”定"
+
+#: views/statistics/settings.thtml:57
+msgid "statistics_settings_return_link"
+msgstr "返回é¢æ¿"
+
+#: views/statistics/settings.thtml:56
+msgid "statistics_settings_save_button"
+msgstr "ä¿å­˜è®¾ç½®"
+
+#: views/statistics/settings.thtml:46
+#, php-format
+msgid "statistics_settings_title"
+msgstr "%1$s 的统计é¢æ¿è®¾ç½®"
+
+#: views/statistics/addon.thtml:242
+msgid "statistics_settings_unlocked_alt"
+msgstr "解é”"
+
+#: controllers/components/stats.php:405
+msgid "statistics_shortnames_application"
+msgstr "应用程åº"
+
+#: controllers/components/stats.php:407
+msgid "statistics_shortnames_os"
+msgstr "æ“作系统"
+
+#: controllers/components/stats.php:406
+msgid "statistics_shortnames_status"
+msgstr "状æ€"
+
+#: controllers/components/stats.php:408
+msgid "statistics_shortnames_unknown"
+msgstr "未知"
+
+#: controllers/components/stats.php:404
+msgid "statistics_shortnames_version"
+msgstr "版本"
+
+#: views/statistics/rss/summary.thtml:42 views/statistics/addon.thtml:192
+msgid "statistics_summary_downloads_average"
+msgstr "å¹³å‡æ—¥ä¸‹è½½é‡"
+
+#: views/statistics/rss/summary.thtml:39
+msgid "statistics_summary_downloads_heading"
+msgstr "下载é‡"
+
+#: views/statistics/rss/summary.thtml:41 views/statistics/addon.thtml:171
+msgid "statistics_summary_downloads_lastcount"
+msgstr "最近一天"
+
+#: views/statistics/rss/summary.thtml:43 views/statistics/addon.thtml:199
+msgid "statistics_summary_downloads_lastweek"
+msgstr "最近七天"
+
+#: views/statistics/rss/summary.thtml:40 views/statistics/addon.thtml:151
+msgid "statistics_summary_downloads_total"
+msgstr "总下载"
+
+#: views/statistics/rss/summary.thtml:40 views/statistics/addon.thtml:152
+#, php-format
+msgid "statistics_summary_downloads_total_sincedate"
+msgstr "从 %1$s 以æ¥"
+
+#: views/statistics/rss/summary.thtml:50 views/statistics/rss/summary.thtml:56
+#: views/statistics/addon.thtml:163 views/statistics/addon.thtml:183
+msgid "statistics_summary_nodata"
+msgstr "å°šæ— æ•°æ®"
+
+#: views/statistics/rss/summary.thtml:60 views/statistics/addon.thtml:195
+msgid "statistics_summary_updatepings_average"
+msgstr "å¹³å‡æ—¥æ´»è·ƒç”¨æˆ·"
+
+#: views/statistics/rss/summary.thtml:52 views/statistics/addon.thtml:177
+msgid "statistics_summary_updatepings_changefromprevious"
+msgstr "更改自此å‰çš„æ•°æ®"
+
+#: views/statistics/rss/summary.thtml:54 views/statistics/addon.thtml:181
+#, php-format
+msgid "statistics_summary_updatepings_changefromprevious_ondate"
+msgstr "%1$s 在 %2$s"
+
+#: views/statistics/rss/summary.thtml:45
+msgid "statistics_summary_updatepings_heading"
+msgstr "日活跃用户"
+
+#: views/statistics/rss/summary.thtml:46 views/statistics/addon.thtml:157
+msgid "statistics_summary_updatepings_total"
+msgstr "日活跃用户"
+
+#: views/statistics/rss/summary.thtml:48 views/statistics/addon.thtml:161
+#, php-format
+msgid "statistics_summary_updatepings_total_ondate"
+msgstr "在 %1$s"
+
+#: views/statistics/rss/summary.thtml:61 views/statistics/addon.thtml:203
+#, fuzzy
+msgid "statistics_summary_updatepings_weekly_average"
+msgstr "Average Daily Users this Week"
+
+#. %s is a percentage, like '+22.33%'. It sits next to another number, so
+#. the implied meaning is 'percentage change' from the previous stat point.
+#: views/statistics/rss/summary.thtml:62 views/statistics/addon.thtml:205
+#, fuzzy
+msgid "statistics_summary_updatepings_weekly_change"
+msgstr "%s from last week"
+
+#: views/statistics/addon.thtml:65 controllers/statistics_controller.php:184
+#: controllers/statistics_controller.php:282
+#, php-format
+msgid "statistics_title_addon_stats"
+msgstr "%1$s 统计"
+
+#: views/addons/themes_landing.thtml:113
+msgid "themes_landing_all_themes"
+msgstr "所有主题"
+
+#: views/addons/themes_landing.thtml:109
+msgid "themes_landing_browse_themes"
+msgstr "æµè§ˆä¸»é¢˜"
+
+#: views/users/edit.thtml:185
+msgid "user_change_email"
+msgstr "更改邮件地å€"
+
+#: views/users/edit.thtml:169
+msgid "user_change_password"
+msgstr "更改密ç "
+
+#: views/users/edit.thtml:96
+#, fuzzy
+msgid "user_change_password_or_email"
+msgstr "Change Password or Email"
+
+#: controllers/users_controller.php:197
+msgid "user_confirmationcode_resent"
+msgstr "确认ç å·²é‡æ–°å‘é€ï¼"
+
+# %1 is the email address, %2 is the URL of the user registration page
+#. %1 is the email address, %2 is the URL of the user registration page
+#: views/users/delete.thtml:51
+msgid "user_del_account_deleted"
+msgstr ""
+"ä½ çš„å¸æˆ· %1$s å·²ç»æˆåŠŸåˆ é™¤ã€‚如果日åŽä½ è¿˜å¸Œæœ›å›žæ¥ï¼Œéœ€è¦åˆ° <a href=\"%2$s\"> 用"
+"æˆ·æ³¨å†Œé¡µé¢ </a> é‡æ–°æ³¨å†Œã€‚"
+
+#: views/users/delete.thtml:102
+msgid "user_del_community_sad"
+msgstr "对于你的离开,Mozilla 附加组件社区感到很难过。"
+
+#: views/users/delete.thtml:123
+msgid "user_del_confirm_password"
+msgstr "确认密ç "
+
+#: views/users/delete.thtml:134
+msgid "user_del_deletenow"
+msgstr "现在删除我的用户å¸å·"
+
+# %1 is the URL of the user's info page
+#. %1 is the URL of the user's info page
+#: views/users/delete.thtml:64
+msgid "user_del_error_addons"
+msgstr ""
+"如果你列于 <a href=\"%1$s\"> 任何附加组件的作者列表 </a> 中,就ä¸èƒ½åˆ é™¤ä½ çš„å¸"
+"å·ã€‚è¦åˆ é™¤å¸å·ï¼Œè¯·è®©ä½ çš„附加组件开å‘å°ç»„中的其他人从作者列表中删除你的å字,"
+"之åŽä½ å°±å¯ä»¥åœ¨è¿™é‡Œåˆ é™¤å¸å·äº†ã€‚"
+
+# %1 is a link to the amo-editors mailing list
+#. %1 is a link to the amo-editors mailing list
+#: views/users/delete.thtml:71
+msgid "user_del_error_addons_more_questions"
+msgstr "如果你有其他问题,请è”ç³» %1$s 获得帮助。"
+
+#: views/users/delete.thtml:78
+msgid "user_del_error_checkbox"
+msgstr "删除你的å¸æˆ·ä¹‹å‰ï¼Œä½ éœ€è¦é€‰ä¸­å¤é€‰æ¡†\"我已明白...\""
+
+#: views/users/delete.thtml:84
+msgid "user_del_error_password"
+msgstr "请准确输入你的密ç ä»¥ä¾¿æ‰§è¡Œå½“å‰æ­¥éª¤ã€‚"
+
+# %1 is a link to the amo-admins mailing list
+#. %1 is a link to the amo-admins mailing list
+#: views/users/delete.thtml:91
+msgid "user_del_error_unknown"
+msgstr ""
+"删除你的å¸æˆ·æ—¶å‘生了未知错误,请è”ç³» %1$s 说明该问题,我们会为您删除å¸æˆ·ã€‚ç”±"
+"此带æ¥çš„ä¸ä¾¿ï¼Œæˆ‘们表示歉æ„。"
+
+#: views/users/delete.thtml:110
+msgid "user_del_header_confirm_deletion"
+msgstr "确认å¸æˆ·åˆ é™¤"
+
+# %1 is the user's email address
+#. %1 is the user's email address
+#: views/users/delete.thtml:100
+msgid "user_del_header_delete_account"
+msgstr "删除用户å¸æˆ· %1$s"
+
+#: views/users/delete.thtml:50
+msgid "user_del_header_farewell"
+msgstr "å†ä¼š!"
+
+#: views/users/delete.thtml:115
+msgid "user_del_nologin"
+msgstr "ä½ å°†å†ä¹Ÿä¸èƒ½ç™»å½•åˆ° Mozilla 附加组件网站。"
+
+#: views/users/delete.thtml:112
+msgid "user_del_permanently_removed_means"
+msgstr "点击 \"删除\" åŽä½ çš„å¸æˆ·å°†ä¼šè¢« <strong>永久删除</strong>。这æ„味ç€ï¼š"
+
+#: views/users/delete.thtml:116
+msgid "user_del_reviews_anonymized"
+msgstr "你的评论和评分将ä¸ä¼šè¢«åˆ é™¤ï¼Œä½†æ˜¯å°†ä¸å†å’Œä½ æœ‰å…³è”。"
+
+# %1 is a link to the amo-editors mailing list
+#. %1 is a link to the amo-editors mailing list
+#: views/users/delete.thtml:104
+msgid "user_del_specific_problem_editors"
+msgstr ""
+"如果你有我们å¯ä»¥å¸®åŠ©è§£å†³çš„问题,请ä¸è¦çŽ°åœ¨åˆ é™¤ä½ çš„å¸æˆ·ï¼Œè€Œæ˜¯é€šè¿‡ %1$s è”系我"
+"们,我们会尽力为你æ供帮助以解决问题。"
+
+#: views/users/delete.thtml:130
+msgid "user_del_understand_permanent"
+msgstr "我明白这个æ“作ä¸å¯æ’¤é”€ã€‚"
+
+#: views/helpers/addons_html.php:192
+msgid "user_deleted_nickname"
+msgstr "已删除用户"
+
+# %1 is the new email address
+#. %1 is the new email address
+#: views/users/edit.thtml:71
+msgid "user_edit_confirm_email_sent"
+msgstr ""
+"一å°é‚®ä»¶å·²ç»å‘é€åˆ° %1$s 以确认你的新邮件地å€ã€‚è¦è®©ä½ çš„更改生效,你需è¦ç‚¹å‡»è¿™"
+"å°é‚®ä»¶ä¸­æ供的链接。在此之å‰ï¼Œä½ ä»ç„¶å¯ä»¥é€šè¿‡çŽ°æœ‰çš„邮件地å€ç»§ç»­ç™»å½•ã€‚"
+
+#: views/users/edit.thtml:201
+msgid "user_edit_delete_user"
+msgstr "删除用户å¸æˆ·"
+
+# This contains the email sent to users when they signed up for a new
+# account:
+# %1 is the confirmation URL, %2 is the current app
+#. This contains the email sent to users when they signed up for a new
+#. account:
+#. %1 is the confirmation URL, %2 is the current app
+#: views/users/email/confirm_plain.thtml:6
+#, php-format
+msgid "user_email_confirm_account_nopass"
+msgstr ""
+"欢迎访问 %2$s 附加组件。\n"
+"\n"
+"在你使用新å¸å·ä¹‹å‰å¿…须激活 - è¿™å¯ä»¥ä¿è¯ä½ ä½¿ç”¨çš„邮件地å€æ˜¯æœ‰æ•ˆçš„并且确实属于"
+"你。\n"
+"è¦æ¿€æ´»ä½ çš„å¸å·ï¼Œç‚¹å‡»ä¸‹é¢çš„链接或者将其整个å¤åˆ¶ã€ç²˜è´´åˆ°ä½ çš„æµè§ˆå™¨åœ°å€æ ï¼š\n"
+"\n"
+"%1$s\n"
+"\n"
+"一旦æˆåŠŸæ¿€æ´»ä½ çš„å¸å·ï¼Œå°±å¯ä»¥åºŸå¼ƒè¿™å°é‚®ä»¶äº†ã€‚\n"
+"\n"
+"æ„Ÿè°¢å‚与附加组件 %2$s \n"
+"-- %2$s 附加组件团队"
+
+# %1 is the confirmation url, %2 is the application name
+#. %1 is the confirmation url, %2 is the application name
+#: views/users/email/emailchange_plain.thtml:5
+msgid "user_email_confirm_emailchange"
+msgstr ""
+"你请求更改 %2$s 附加组件中你的电å­é‚®ä»¶åœ°å€ã€‚\n"
+"\n"
+"为了确认新的地å€ï¼Œè¯·ç‚¹å‡»ä¸‹é¢çš„链接或者将链接地å€å¤åˆ¶åˆ°ä½ çš„æµè§ˆå™¨çš„地å€æ "
+"中:\n"
+"\n"
+"%1$s\n"
+"\n"
+"你有48å°æ—¶çš„时间确认新的地å€ã€‚如果你ä¸å¸Œæœ›æ›´æ”¹é‚®ä»¶åœ°å€ï¼Œå¿½ç•¥è¿™å°é‚®ä»¶å³å¯ã€‚\n"
+"\n"
+"谢谢ï¼\n"
+"-- %2$s 附加组件团队"
+
+#: controllers/users_controller.php:168
+#, php-format
+msgid "user_email_confirm_subject"
+msgstr "æ„Ÿè°¢å‚与 %s Add-ons"
+
+# This is the password reset email
+# %1 is the pw reset URL, %2 is the application
+#. This is the password reset email
+#. %1 is the pw reset URL, %2 is the application
+#: views/users/email/pwreset_plain.thtml:5
+#, php-format
+msgid "user_email_pwreset"
+msgstr ""
+"%2$s 附加组件密ç é‡ç½®\n"
+"\n"
+"addons.mozilla.org 收到了该å¸å·å……值密ç çš„请求。è¦æ›´æ”¹è¿™ä¸ªå¯†ç è¯·ç‚¹å‡»ä»¥ä¸‹é“¾æŽ¥ï¼Œ"
+"或者将其整体粘贴到你的æµè§ˆå™¨çš„地å€æ ï¼š\n"
+"\n"
+"%1$s\n"
+"\n"
+"如果你没有è¦æ±‚这么åšï¼Œåˆ™ä¸éœ€è¦æœ‰å…¶ä»–进一步的æ“作。\n"
+"\n"
+"谢谢,\n"
+"-- %2$s 附加组件团队"
+
+#: controllers/users_controller.php:245
+#, php-format
+msgid "user_email_pwreset_subject"
+msgstr "é‡ç½®ä½ çš„ %s 附加组件密ç "
+
+#: views/users/emailchange.thtml:50
+msgid "user_emailchange_error"
+msgstr "错误!"
+
+# %1 is the application name
+#. %1 is the application name
+#: controllers/users_controller.php:533
+msgid "user_emailchange_subject"
+msgstr "请确认更改 %1$s 附加组件中你的邮件地å€"
+
+#: views/users/emailchange.thtml:48
+msgid "user_emailchange_success"
+msgstr "æˆåŠŸï¼"
+
+# %1 is the new email address
+#. %1 is the new email address
+#: views/users/emailchange.thtml:49
+msgid "user_emailchange_successful_description"
+msgstr "你的电å­é‚®ä»¶åœ°å€å·²ç»ä¿®æ”¹æˆåŠŸã€‚从现在开始,请使用%1$s 登录。"
+
+#: views/users/edit.thtml:134 views/admin/users_edit.thtml:111
+#, fuzzy
+msgid "user_form_bio"
+msgstr "About me"
+
+#: views/users/edit.thtml:135 views/admin/users_edit.thtml:112
+#, fuzzy
+msgid "user_form_bio_description"
+msgstr ""
+"Introduce yourself to the community, if you like! This text will appear "
+"publicly on your user info page. Line breaks will be preserved, but no HTML "
+"is allowed."
+
+#: views/users/pwreset.thtml:77 views/users/register.thtml:73
+#: views/users/edit.thtml:181
+msgid "user_form_confirmpassword"
+msgstr "确认密ç "
+
+#: views/users/edit.thtml:145
+#, fuzzy
+msgid "user_form_display_collections"
+msgstr "Display the collections I have created in my user profile"
+
+#: views/users/edit.thtml:149
+#, fuzzy
+msgid "user_form_display_collections_fav"
+msgstr "Display my favorite collections in my user profile"
+
+#: views/users/edit.thtml:86
+#, php-format
+msgid "user_form_editprofile"
+msgstr "编辑 %s 的用户é…置文件"
+
+#: views/users/pwreset.thtml:52 views/users/login.thtml:81
+#: views/users/register.thtml:63 views/users/edit.thtml:187
+msgid "user_form_email"
+msgstr "邮件地å€"
+
+#: views/users/register.thtml:78 views/users/edit.thtml:103
+#: views/admin/users_edit.thtml:76
+msgid "user_form_firstname"
+msgstr "姓æ°"
+
+#: views/users/register.thtml:94 views/users/edit.thtml:119
+#: views/admin/users_edit.thtml:91
+msgid "user_form_hideemail"
+msgstr "éšè—邮件地å€"
+
+#: views/users/register.thtml:98 views/users/edit.thtml:123
+#: views/admin/users_edit.thtml:99
+msgid "user_form_homepage"
+msgstr "网站 URL"
+
+#: views/users/register.thtml:84 views/users/edit.thtml:109
+#: views/admin/users_edit.thtml:81
+msgid "user_form_lastname"
+msgstr "åå­—"
+
+#: controllers/users_controller.php:333
+msgid "user_form_login"
+msgstr "用户登录"
+
+#: views/users/pwreset.thtml:72 views/users/edit.thtml:176
+msgid "user_form_newpassword"
+msgstr "新密ç "
+
+#: views/users/register.thtml:89 views/users/edit.thtml:114
+#: views/admin/users_edit.thtml:86
+msgid "user_form_nickname"
+msgstr "昵称"
+
+#: views/users/edit.thtml:171
+msgid "user_form_oldpassword"
+msgstr "旧密ç "
+
+#: views/users/edit.thtml:97 views/users/edit.thtml:200
+msgid "user_form_otheractions"
+msgstr "其他æ“作"
+
+#: views/users/login.thtml:85 views/users/register.thtml:68
+msgid "user_form_password"
+msgstr "密ç "
+
+#: controllers/users_controller.php:93
+msgid "user_form_registration"
+msgstr "新用户注册"
+
+#: views/users/login.thtml:90
+msgid "user_form_remember_me"
+msgstr "è®°ä½æˆ‘的登录状æ€"
+
+#: views/admin/users_edit.thtml:95
+msgid "user_form_showsandbox"
+msgstr "显示沙盒?"
+
+#: views/users/edit.thtml:205
+msgid "user_form_submit_edit"
+msgstr "ä¿å­˜"
+
+#: views/users/login.thtml:93
+msgid "user_form_submit_login"
+msgstr "登录"
+
+#: views/users/register.thtml:113
+msgid "user_form_submit_register"
+msgstr "注册"
+
+#: views/users/info.thtml:75
+#, php-format
+msgid "user_info_usersince"
+msgstr "%s 附加组件注册日期"
+
+#: views/users/login.thtml:102
+msgid "user_login_register_link"
+msgstr "建立新å¸å·"
+
+#: views/users/edit.thtml:160
+msgid "user_notifications_item_compat"
+msgstr "附加组件兼容性 (强烈建议)"
+
+#: views/users/edit.thtml:161
+msgid "user_notifications_item_events"
+msgstr "å³å°†å‘生的事件和争论"
+
+#: views/users/edit.thtml:156
+msgid "user_notifications_none_available"
+msgstr "æ ¹æ®ä½ çš„é…置,目å‰æ²¡æœ‰é€šçŸ¥ä¿¡æ¯ã€‚"
+
+#: views/users/edit.thtml:158
+msgid "user_notifications_select_topics"
+msgstr ""
+"有时,Mozilla 会å‘é€é‚®ä»¶è¯´æ˜Žå³å°†å‘布的版本和附加组件信æ¯ã€‚请在下é¢é€‰æ‹©ä½ æ„Ÿå…´"
+"趣的è¯é¢˜ï¼š"
+
+#: views/users/edit.thtml:164
+msgid "user_notifications_specific_contact"
+msgstr ""
+"对于你å‘布的附加组件,为了沟通一些特别关心的问题,Mozillaä¿ç•™å•ç‹¬è”系你的æƒ"
+"力。"
+
+#: controllers/users_controller.php:543
+msgid "user_profile_edit_error"
+msgstr "ä½ åšçš„更改有错误,请确认åŽé‡æ–°æ交。"
+
+#: controllers/users_controller.php:540
+msgid "user_profile_saved"
+msgstr "é…置文件已更新。"
+
+#: views/users/pwreset.thtml:65
+#, php-format
+msgid "user_pwreset_for_email"
+msgstr "为 %s é‡ç½®å¯†ç ã€‚"
+
+#: controllers/users_controller.php:226
+msgid "user_pwreset_header"
+msgstr "密ç é‡ç½®"
+
+#: views/users/login.thtml:103
+msgid "user_pwreset_link"
+msgstr "忘记密ç ï¼Ÿ"
+
+#: controllers/users_controller.php:248
+msgid "user_pwreset_link_sent"
+msgstr "密ç é‡ç½®é“¾æŽ¥å·²ç»å‘é€åˆ°ä½ çš„邮件地å€ã€‚"
+
+#: controllers/users_controller.php:304
+msgid "user_pwreset_okay"
+msgstr "密ç é‡ç½®æˆåŠŸã€‚"
+
+#: views/users/pwreset.thtml:82
+msgid "user_pwreset_submit_changepw"
+msgstr "æ交更改密ç "
+
+#: views/users/pwreset.thtml:57
+msgid "user_pwreset_submit_sendlink"
+msgstr "å‘é€é‡ç½®å¯†ç é“¾æŽ¥"
+
+#: views/users/register_complete.thtml:51
+#, php-format
+msgid "user_register_amo_link"
+msgstr "%s 附加组件"
+
+# %1 is the user's email address, %2 is the current app
+#. %1 is the user's email address, %2 is the current app
+#: views/users/activatefirst.thtml:49
+#, php-format
+msgid "user_register_click_confirm_link"
+msgstr ""
+"激活你的å¸æˆ·çš„链接已ç»é€šè¿‡ç”µå­é‚®ä»¶å‘é€åˆ°ä½ çš„é‚®ä»¶åœ°å€ %1$s 中。点击这个链接以"
+"åŽä½ æ‰èƒ½ç™»å½•åˆ°é™„加组件 %2$s 。"
+
+# %1 is the user's email address
+#. %1 is the user's email address
+#: views/users/register_complete.thtml:49
+#, php-format
+msgid "user_register_confirm_email_sent"
+msgstr ""
+"一å°é‚®ä»¶å·²ç»å‘é€åˆ°ä½ çš„åœ°å€ %1$s 以确认你的å¸å·ã€‚在登录之å‰ï¼Œä½ å¿…须通过点击该"
+"邮件中æ供的链接激活你的å¸å·ã€‚"
+
+#: views/users/activatefirst.thtml:51
+msgid "user_register_confirmation_link_text"
+msgstr "é‡æ–°å‘é€ç¡®è®¤æ¶ˆæ¯ã€‚"
+
+#: views/users/register_complete.thtml:47
+msgid "user_register_congratulations"
+msgstr "ç¥è´ºä½ ï¼ä½ çš„用户å¸å·å·²ç»æˆåŠŸå»ºç«‹ã€‚"
+
+#: views/users/register.thtml:50
+#, fuzzy
+msgid "user_register_details"
+msgstr ""
+"<p>Registration on AMO is <strong>not required</strong> if you simply want "
+"to download and install public add-ons.</p><p>You only need to register if:</"
+"p><ul><li>You want to submit reviews for add-ons</li><li>You are an add-on "
+"developer and want to upload your add-on for hosting on AMO</li></ul><p>Upon "
+"successful registration, you will be sent a confirmation email to the "
+"address you provided. Please follow the instructions there to confirm your "
+"account.</p><p>If you like, you can read our <a href='%1$s' title='Legal "
+"Notices'>Legal Notices</a> and <a href='%2$s' title='Privacy Policy'>Privacy "
+"Policy</a>.</p>"
+
+# %1 is the link to the "resend confirmation code" page
+#. %1 is the link to the "resend confirmation code" page
+#: views/users/activatefirst.thtml:51
+#, php-format
+msgid "user_register_resend_confirmation_link"
+msgstr ""
+"如果你没有收到确认邮件,请检查确认你的邮件æœåŠ¡æ²¡æœ‰å°†å…¶æ ‡è®°ä¸ºåžƒåœ¾é‚®ä»¶æˆ–者或者"
+"广告邮件。如果需è¦ï¼Œä½ å¯ä»¥è¦æ±‚我们 %1$s 到你的电å­ä¿¡ç®±ä¸­ã€‚"
+
+# %1 is the link to the Mozilla Add-ons front page
+#. %1 is the link to the Mozilla Add-ons front page
+#: views/users/register_complete.thtml:51
+#, php-format
+msgid "user_register_welcome"
+msgstr "感谢注册并欢迎æ¥åˆ° %1$s ï¼"
+
+#: views/users/register.thtml:49
+#, fuzzy
+msgid "user_register_welcome_header"
+msgstr "Welcome to addons.mozilla.org (AMO)!"
+
+#: views/users/register.thtml:81 views/users/edit.thtml:106
+msgid "user_required_firstlast_or_nickname"
+msgstr "å称, 姓æ°æˆ–昵称是必ä¸å¯å°‘的。"
+
+#: views/users/edit.thtml:94 views/users/edit.thtml:142
+#, fuzzy
+msgid "user_tab_collections"
+msgstr "Collections"
+
+#: views/users/edit.thtml:95 views/users/edit.thtml:154
+msgid "user_tab_notifications"
+msgstr "通知"
+
+#: views/users/edit.thtml:93 views/users/edit.thtml:101
+msgid "user_tab_profile"
+msgstr "用户é…ç½®"
+
+#: controllers/users_controller.php:209
+msgid "user_verified_okay"
+msgstr "验è¯æˆåŠŸï¼"
+
+#: controllers/users_controller.php:723
+msgid "users_delete_pagetitle"
+msgstr "删除用户å¸æˆ·"
+
+#: controllers/users_controller.php:414
+msgid "users_edit_pagetitle"
+msgstr "正在编辑用户å¸æˆ·"
+
+#: views/users/info.thtml:71
+#, fuzzy
+msgid "users_info_aboutme"
+msgstr "About Me"
+
+#: views/users/info.thtml:96
+#, php-format
+msgid "users_info_addons_by_user"
+msgstr "%1$s 的附加组件"
+
+#: views/users/info.thtml:51
+msgid "users_info_author_name"
+msgstr "åå­—"
+
+#: views/users/info.thtml:48
+msgid "users_info_author_profile"
+msgstr "用户档案"
+
+#. %s is the user name
+#: views/users/info.thtml:137
+#, fuzzy
+msgid "users_info_collections_by_user"
+msgstr "Collections by %s"
+
+#: views/users/info.thtml:66
+msgid "users_info_email"
+msgstr "电å­é‚®ä»¶"
+
+#: views/users/info.thtml:155
+#, fuzzy
+msgid "users_info_fav_collections_by_user"
+msgstr "Favorite Collections"
+
+#: views/users/info.thtml:61
+msgid "users_info_homepage"
+msgstr "主页"
+
+#: views/users/info.thtml:56
+msgid "users_info_nickname"
+msgstr "昵称"
+
+#: controllers/users_controller.php:707
+#, php-format
+msgid "users_info_pagetitle"
+msgstr "%1$s 的用户信æ¯"
+
+# %1 is the user's name
+#. %1 is the user's name
+#: views/users/info.thtml:116
+msgid "users_info_reviews_by_user"
+msgstr "%s å‘布"
+
+#: controllers/users_controller.php:330 controllers/users_controller.php:332
+msgid "users_login_pagetitle"
+msgstr "用户登录"
+
+# %1 is the link to the sandbox/policy explanation page
+# This message is for a specific add-on not found
+#. %1 is the link to the sandbox/policy explanation page
+#. This message is for a specific add-on not found
+#: views/users/login.thtml:53
+#, php-format
+msgid "users_login_sandbox_display_warning"
+msgstr ""
+"你正在查找的附加组件目å‰åœ¨æ²™ç›’中。如果你已ç»æ‹¥æœ‰ä¸€ä¸ªMozilla附加组件å¸å·ï¼Œè¯·ç™»"
+"录,或者 <a href=\"%1$s\">获å–有关沙盒的更多信æ¯ã€‚"
+
+# %1 is the link to the sandbox/policy explanation page
+# This message is for any given sandbox-related page not found
+#. %1 is the link to the sandbox/policy explanation page
+#. This message is for any given sandbox-related page not found
+#: views/users/login.thtml:56
+#, php-format
+msgid "users_login_sandbox_page_warning"
+msgstr ""
+"你正在查找的页é¢æ˜¯æ²™ç›’的一部分。如果你已ç»æ‹¥æœ‰ä¸€ä¸ªMozilla附加组件å¸å·ï¼Œè¯·ç™»"
+"录,或者 <a href=\"%1$s\">获å–更多有关沙盒的信æ¯ã€‚</a>"
+
+#: controllers/users_controller.php:223 controllers/users_controller.php:225
+msgid "users_pwreset_pagetitle"
+msgstr "用户密ç é‡ç½®"
+
+#: controllers/users_controller.php:90 controllers/users_controller.php:92
+msgid "users_register_pagetitle"
+msgstr "新用户注册"
+
+#. %1$s is an addon name, like <a>Firebug</a>
+#. %2$s is a version number, like <a>1.2</a>
+#: views/versions/license.thtml:52
+#, fuzzy
+msgid "versions_license_header_source"
+msgstr "Source code license for %1$s %2$s"
+
+#: views/addons/category_landing.thtml:147
+#, fuzzy
+msgid "view_recently_added"
+msgstr "View all recently added"
+
+#: views/addons/category_landing.thtml:161
+#, fuzzy
+msgid "view_top_downloads"
+msgstr "View all top downloads"
+
+#: views/addons/category_landing.thtml:175
+#, fuzzy
+msgid "view_top_rated"
+msgstr "View all top rated"
+
+#~ msgid "addon_slider_tooltip_next"
+#~ msgstr "下一个附加组件"
+
+#~ msgid "addon_slider_tooltip_previous"
+#~ msgstr "å‰ä¸€ä¸ªé™„加组件"
+
+#~ msgid "addon_versions_getlatesttext"
+#~ msgstr "兼容的最新版本"
+
+#~ msgid "addons_display_version_history"
+#~ msgstr "完整的版本历å²"
+
+#~ msgid "addons_home_newest_header"
+#~ msgstr "最新的:"
+
+#~ msgid "addons_home_popular_header"
+#~ msgstr "最热门的:"
+
+#~ msgid "addons_home_recommended_header"
+#~ msgstr "推è:"
+
+#~ msgid "addons_home_updated_header"
+#~ msgstr "最近更新:"
+
+#~ msgid "addons_home_view_all"
+#~ msgstr "查看全部"
+
+#~ msgid "category_extra_allrecommended"
+#~ msgstr "查看所有推è的附加组件"
+
+#~ msgid "category_extra_highestrated"
+#~ msgstr "评分最高的在å‰"
+
+#~ msgid "category_extra_lastupdated"
+#~ msgstr "最近更新的在å‰"
+
+#~ msgid "category_extra_mostpopular"
+#~ msgstr "最热门的在å‰"
+
+#, fuzzy
+#~ msgid "collections_detail_js_loading"
+#~ msgstr "Loading"
+
+#, fuzzy
+#~ msgid "collections_detail_more_info"
+#~ msgstr "Show More Info"
+
+#~ msgid "devcp_additem_firefox_notice"
+#~ msgstr ""
+#~ "你的这个版本的附加组件未生命与Firefox %1$s 兼容。Mozilla的下一个Firefox版"
+#~ "本很快就è¦å‘布,所以请您在新版本中测试您的附加组件并更新兼容性信æ¯ã€‚ä½ å¯ä»¥"
+#~ "在 <a href=\"%2$s\">这里</a> 找到更多信æ¯ã€‚这仅仅是一个æ醒,你å¯ä»¥ç»§ç»­å‘ "
+#~ "addons.mozilla.org æ交该版本。"
+
+#~ msgid "devcp_addon_disabled_successfully"
+#~ msgstr "æˆåŠŸç¦ç”¨é™„加组件"
+
+#~ msgid "devcp_addon_edit_pagetitle"
+#~ msgstr "编辑附加组件"
+
+#~ msgid "devcp_addon_enabled_successfully"
+#~ msgstr "æˆåŠŸå¯ç”¨é™„加组件"
+
+#~ msgid "devcp_addon_field_description_displaytitle"
+#~ msgstr "附加组件æè¿°"
+
+#~ msgid "devcp_addon_field_eula_displaytitle"
+#~ msgstr "许å¯åè®®"
+
+#~ msgid "devcp_addon_field_homepage_displaytitle"
+#~ msgstr "附加组件主页"
+
+#~ msgid "devcp_addon_field_name_displaytitle"
+#~ msgstr "附加组件å称"
+
+#~ msgid "devcp_addon_field_privacy_displaytitle"
+#~ msgstr "éšç§ç­–ç•¥"
+
+#~ msgid "devcp_addon_field_summary_displaytitle"
+#~ msgstr "附加组件摘è¦"
+
+#~ msgid "devcp_addon_field_supportemail_displaytitle"
+#~ msgstr "技术支æŒé‚®ç®±"
+
+#~ msgid "devcp_addon_field_supporturl_displaytitle"
+#~ msgstr "技术支æŒç½‘ç«™"
+
+#~ msgid "devcp_addon_field_versionnotes_displaytitle"
+#~ msgstr "版本信æ¯"
+
+#~ msgid "devcp_addon_nominate_pagetitle"
+#~ msgstr "æ请批准附加组件"
+
+#~ msgid "devcp_addon_nominated_successfully"
+#~ msgstr "附加组件æ请批准æˆåŠŸï¼"
+
+#, fuzzy
+#~ msgid "devcp_addon_status_criteria_review"
+#~ msgstr "Several user reviews of the add-on (may be external reviews)."
+
+# %1 is the addon edit link
+# %2 is the main dev CP link
+#~ msgid "devcp_addon_submission_makechanges"
+#~ msgstr ""
+#~ "访问 %1$s 页é¢å¯¹ä½ ä¸Šä¼ çš„内容进行修改,或者点击 %2$s 返回开å‘者工具。"
+
+#~ msgid "devcp_addon_submission_makechanges_devcp_link"
+#~ msgstr "点击这里"
+
+#~ msgid "devcp_addon_submission_makechanges_link"
+#~ msgstr "编辑附加组件"
+
+#~ msgid "devcp_addon_submission_pending"
+#~ msgstr ""
+#~ "这个版本已ç»æ”¾å…¥æ²™ç›’,供沙盒测试者和Mozilla附加组件编辑审查。通过以åŽä¼šä»¥"
+#~ "电å­é‚®ä»¶é€šçŸ¥ä½ ã€‚"
+
+# %1 is the link to the sandbox information page
+#~ msgid "devcp_addon_submission_sandbox_readmore"
+#~ msgstr "ä½ å¯ä»¥æŸ¥çœ‹ %s 获å–有关沙盒审查系统的更多信æ¯ã€‚"
+
+#~ msgid "devcp_addon_submission_sandbox_readmore_link"
+#~ msgstr "这里"
+
+# %1 is the "nominate" link
+#~ msgid "devcp_addon_submission_sandboxed"
+#~ msgstr ""
+#~ "这个版本已ç»æ”¾å…¥æ²™ç›’供专业用户使用。为了使其能够显示在公开网站,你必须%s "
+#~ "你的附加组件并通过这个审查æµç¨‹ã€‚"
+
+#~ msgid "devcp_addon_submission_sandboxed_nominate_link"
+#~ msgstr "æ请批准"
+
+#~ msgid "devcp_addon_submission_success"
+#~ msgstr "你的上传已ç»æˆåŠŸè¿›è¡Œå®Œæ¯•ã€‚"
+
+#~ msgid "devcp_addon_submission_trusted_public"
+#~ msgstr "因为你的附加组件是被信任的,该版本已ç»è‡ªåŠ¨èŽ·å¾—核准å‘布到公开网站。"
+
+#~ msgid "devcp_addon_submit_pagetitle"
+#~ msgstr "上传附加组件"
+
+#~ msgid "devcp_addon_updated_successfully"
+#~ msgstr "附加组件更新æˆåŠŸ"
+
+# %1 is the link to the preview upload page
+#~ msgid "devcp_addon_upload_preview"
+#~ msgstr "%s å¯ä»¥æå‡ä½¿ç”¨è€…对你的附加组件的兴趣。"
+
+#~ msgid "devcp_addon_upload_preview_link"
+#~ msgstr "上传预览图片"
+
+# #1 is the author email
+#~ msgid "devcp_author_lookup_none_found"
+#~ msgstr "未找到作者 [%s]"
+
+#~ msgid "devcp_author_lookup_remove"
+#~ msgstr "删除"
+
+#~ msgid "devcp_button_cancel"
+#~ msgstr "放弃"
+
+#~ msgid "devcp_button_cancel_confirm"
+#~ msgstr "你确信è¦æ”¾å¼ƒä¸Šä¼ ï¼Ÿ"
+
+#~ msgid "devcp_button_next"
+#~ msgstr "下一步"
+
+#~ msgid "devcp_change_addontype"
+#~ msgstr "更改附加组件类型:"
+
+#~ msgid "devcp_comments_updated"
+#~ msgstr "å¼€å‘者评论已更新。"
+
+#~ msgid "devcp_details_addpreview_link"
+#~ msgstr "添加预览图"
+
+#~ msgid "devcp_details_author"
+#~ msgstr "作者"
+
+#~ msgid "devcp_details_authors"
+#~ msgstr "作者"
+
+#~ msgid "devcp_details_authors_none"
+#~ msgstr "æ— "
+
+#~ msgid "devcp_details_categories"
+#~ msgstr "分类"
+
+#~ msgid "devcp_details_category"
+#~ msgstr "分类"
+
+#~ msgid "devcp_details_description"
+#~ msgstr "æè¿°"
+
+#~ msgid "devcp_details_disabled"
+#~ msgstr "ç¦ç”¨"
+
+#~ msgid "devcp_details_guid"
+#~ msgstr "GUID"
+
+#~ msgid "devcp_details_header_details"
+#~ msgstr "详情"
+
+#~ msgid "devcp_details_header_devcomments"
+#~ msgstr "å¼€å‘者评论"
+
+#~ msgid "devcp_details_header_previews"
+#~ msgstr "预览图"
+
+#~ msgid "devcp_details_header_versions"
+#~ msgstr "版本"
+
+#~ msgid "devcp_details_homepage"
+#~ msgstr "主页"
+
+#~ msgid "devcp_details_homepage_none"
+#~ msgstr "æ— "
+
+#~ msgid "devcp_details_preview_nocaption"
+#~ msgstr "无说明"
+
+#~ msgid "devcp_details_previews_nonefound"
+#~ msgstr "未找到预览图。"
+
+#~ msgid "devcp_details_submit_update"
+#~ msgstr "æ›´æ–°"
+
+#~ msgid "devcp_details_supportemail"
+#~ msgstr "技术支æŒé‚®ä»¶"
+
+#~ msgid "devcp_details_supportemail_none"
+#~ msgstr "å¼€å‘者未æ供技术支æŒé‚®ç®±"
+
+#~ msgid "devcp_details_supporturl"
+#~ msgstr "技术支æŒç½‘ç«™"
+
+#~ msgid "devcp_details_supporturl_none"
+#~ msgstr "å¼€å‘者未æ供技术支æŒç½‘ç«™"
+
+#~ msgid "devcp_details_trusted"
+#~ msgstr "å—信任的"
+
+#~ msgid "devcp_details_versions_none_found"
+#~ msgstr "未找到版本。"
+
+#~ msgid "devcp_disable_cancel"
+#~ msgstr "放弃并返回"
+
+#~ msgid "devcp_disable_disable_button"
+#~ msgstr "好的,ç¦ç”¨å®ƒã€‚"
+
+#~ msgid "devcp_disable_disable_confirm"
+#~ msgstr "你确认è¦ç¦ç”¨è¿™ä¸ªé™„加组件?"
+
+#~ msgid "devcp_disable_disable_description"
+#~ msgstr ""
+#~ "ç¦ç”¨è¿™ä¸ªé™„加组件将会导致他从æœç´¢ç»“果和列表中消失,将ä¸èƒ½ä»Žå…¬å¼€ç½‘站下载到,"
+#~ "也ä¸èƒ½ä¸ºå®¢æˆ·ç«¯æ供更新检测。附加组件将会处于一ç§è¢«åˆ é™¤çš„效果,尽管你å¯ä»¥å¾ˆ"
+#~ "方便地回到这里é‡æ–°å¯ç”¨å®ƒã€‚"
+
+#~ msgid "devcp_disable_disable_title"
+#~ msgstr "ç¦ç”¨ %s"
+
+#~ msgid "devcp_disable_enable_button"
+#~ msgstr "好的,å¯ç”¨å®ƒã€‚"
+
+#~ msgid "devcp_disable_enable_confirm"
+#~ msgstr "你确认è¦å¯ç”¨è¿™ä¸ªé™„加组件?"
+
+#~ msgid "devcp_disable_enable_description"
+#~ msgstr ""
+#~ "å¯ç”¨è¿™ä¸ªé™„加组件将会使其å†æ¬¡æ˜¾ç¤ºåœ¨æœç´¢ç»“果和列表中,将能够从网站下载到并从"
+#~ "客户端进行更新检测。"
+
+#~ msgid "devcp_disable_enable_title"
+#~ msgstr "å¯ç”¨ %s"
+
+#~ msgid "devcp_edit_author_add"
+#~ msgstr "增加作者"
+
+#~ msgid "devcp_edit_author_email"
+#~ msgstr "作者的电å­é‚®ä»¶ï¼š"
+
+#~ msgid "devcp_edit_author_remove"
+#~ msgstr "删除"
+
+#~ msgid "devcp_edit_error_categories_unavailable"
+#~ msgstr "è¿™ç§é™„加组件没有å¯ç”¨çš„分类。"
+
+#, fuzzy
+#~ msgid "devcp_edit_file_error_incomplete"
+#~ msgstr "Incomplete transfer"
+
+#, fuzzy
+#~ msgid "devcp_edit_file_error_no"
+#~ msgstr "No file uploaded"
+
+#, fuzzy
+#~ msgid "devcp_edit_file_error_size"
+#~ msgstr "Exceeds maximum upload size"
+
+#~ msgid "devcp_edit_header_authors"
+#~ msgstr "作者"
+
+#~ msgid "devcp_edit_icon_add_link"
+#~ msgstr "增加图标"
+
+#~ msgid "devcp_edit_icon_change_link"
+#~ msgstr "更改图标"
+
+#~ msgid "devcp_edit_label_allow_viewsource"
+#~ msgstr "å…许用户在线查看æºæ–‡ä»¶ã€‚"
+
+#~ msgid "devcp_edit_label_categories"
+#~ msgstr "类别"
+
+#~ msgid "devcp_edit_label_defaultlocale"
+#~ msgstr "默认语言"
+
+#~ msgid "devcp_edit_label_icon_delete"
+#~ msgstr "仅清除已有图标。"
+
+#~ msgid "devcp_edit_label_icon_new"
+#~ msgstr "新图标文件"
+
+#~ msgid "devcp_edit_label_info"
+#~ msgstr "图标"
+
+#~ msgid "devcp_edit_locale_disambiguation_explanation"
+#~ msgstr "简短的附加信æ¯ï¼ˆä¾‹å¦‚本地语言å称)"
+
+#~ msgid "devcp_edit_submit_update"
+#~ msgstr "æ›´æ–°"
+
+#~ msgid "devcp_edit_target_locale_explanation"
+#~ msgstr ""
+#~ "<a href=\"http://wiki.mozilla.org/L10n:Simple_locale_names\">本地化语言简"
+#~ "称</a>, 例如 'zh-CN'"
+
+#~ msgid "devcp_editversion_checkedfiles_delete"
+#~ msgstr "选中的文件将被删除。"
+
+# %1 is the file name
+# %2 is the file size (150 KB)
+#~ msgid "devcp_editversion_filename_size"
+#~ msgstr "%1$s (%2$s)"
+
+#~ msgid "devcp_editversion_label_files"
+#~ msgstr "文件"
+
+#~ msgid "devcp_editversion_label_targetapps"
+#~ msgstr "目标应用程åº"
+
+#~ msgid "devcp_editversion_nofiles"
+#~ msgstr "没有文件。"
+
+#~ msgid "devcp_editversion_reviewernotes"
+#~ msgstr "建议者说明"
+
+#~ msgid "devcp_editversion_submit_update"
+#~ msgstr "æ›´æ–°"
+
+#~ msgid "devcp_error_addon_field_summary_toolong"
+#~ msgstr "摘è¦é™åˆ¶åœ¨250字符以内。(你输入了 %s 个字符)"
+
+#~ msgid "devcp_error_addonname_not_unique"
+#~ msgstr ""
+#~ "你的扩展å称在数æ®åº“中已ç»å­˜åœ¨ã€‚请确认:<br /><li>ä½ çš„GUID是å¦åŒ¹é…。该错误"
+#~ "最常è§çš„原因是GUIDä¸åŒ¹é…。</li><li>æ•°æ®åº“中ä¸èƒ½æœ‰é‡å¤çš„记录。如果你è¦è¿™ä¹ˆ"
+#~ "åšä½ åº”该更新那个项目或者删除以åŽå†è¯•ã€‚</li>"
+
+#~ msgid "devcp_error_describe_changes"
+#~ msgstr "请æ述该附加组件更新的更改详情。"
+
+#~ msgid "devcp_error_file_guids_dont_match"
+#~ msgstr "文件GUIDä¸å®Œå…¨åŒ¹é…。"
+
+#~ msgid "devcp_error_identical_version_exists"
+#~ msgstr "该附加组件在该平å°ä¸‹å·²æœ‰ç›¸åŒçš„版本(%s)。"
+
+#~ msgid "devcp_error_nominate_message"
+#~ msgstr "ä½ å¿…é¡»æ供推è时所è¦æ±‚的细节。"
+
+#~ msgid "devcp_error_nominate_no_prerelease"
+#~ msgstr "ä½ ä¸èƒ½æŽ¨è预å‘行版本的附加组件。"
+
+#~ msgid "devcp_error_nominate_sandbox_only"
+#~ msgstr "ä½ åªèƒ½æŽ¨è当å‰åœ¨æ²™ç›’中的附加组件。"
+
+#~ msgid "devcp_error_saving"
+#~ msgstr "ä¿å­˜æ•°æ®æ—¶å‘生错误。"
+
+#~ msgid "devcp_error_update_access_denied"
+#~ msgstr "你没有更新这个附加组件的æƒåˆ©ã€‚"
+
+#~ msgid "devcp_file_addanother"
+#~ msgstr "增加å¦ä¸€å¹³å°çš„文件"
+
+#~ msgid "devcp_form_author_add"
+#~ msgstr "增加作者"
+
+#~ msgid "devcp_form_author_remove"
+#~ msgstr "移走"
+
+#~ msgid "devcp_form_categories_nextstep"
+#~ msgstr "新的附加组件分类在下一步中å¯ç”¨ã€‚"
+
+#~ msgid "devcp_form_error_categories_unavailable"
+#~ msgstr "这个附加组件的类型没有有效的分类。"
+
+#~ msgid "devcp_form_error_description_notempty"
+#~ msgstr "请输入你附加组件的æ述。"
+
+#~ msgid "devcp_form_error_name_required"
+#~ msgstr "请输入你附加组件的å称。"
+
+#~ msgid "devcp_form_error_select_addontype"
+#~ msgstr "请选择你æ交的附加组件的类型。"
+
+#~ msgid "devcp_form_error_summary_notempty"
+#~ msgstr "请输入你附加组件的摘è¦ã€‚"
+
+#~ msgid "devcp_form_label_addonfile"
+#~ msgstr "附加组件文件"
+
+#~ msgid "devcp_form_label_addonfile2"
+#~ msgstr "附加组件文件 2"
+
+#~ msgid "devcp_form_label_addonfile3"
+#~ msgstr "附加组件文件 3"
+
+#~ msgid "devcp_form_label_addontype"
+#~ msgstr "附加组件类型"
+
+#~ msgid "devcp_form_label_allow_viewsource"
+#~ msgstr "å…许用户在线æµè§ˆæºæ–‡ä»¶"
+
+#~ msgid "devcp_form_label_author_email"
+#~ msgstr "作者邮件地å€"
+
+#~ msgid "devcp_form_label_authors"
+#~ msgstr "作者"
+
+#~ msgid "devcp_form_label_categories"
+#~ msgstr "分类"
+
+#~ msgid "devcp_form_label_defaultlocale"
+#~ msgstr "默认语ç§"
+
+#~ msgid "devcp_form_label_description"
+#~ msgstr "æè¿°"
+
+#~ msgid "devcp_form_label_eula"
+#~ msgstr "最终用户许å¯åè®®(EULA)"
+
+#~ msgid "devcp_form_label_externalsoftware"
+#~ msgstr "这个附加组件需è¦å¤–部软件"
+
+#~ msgid "devcp_form_label_files"
+#~ msgstr "文件"
+
+#~ msgid "devcp_form_label_homepage"
+#~ msgstr "主页"
+
+#~ msgid "devcp_form_label_iconfile"
+#~ msgstr "图标文件"
+
+#~ msgid "devcp_form_label_name"
+#~ msgstr "å称"
+
+#~ msgid "devcp_form_label_platforms"
+#~ msgstr "支æŒå¹³å°"
+
+#~ msgid "devcp_form_label_prerelease"
+#~ msgstr "这是预å‘行版"
+
+#~ msgid "devcp_form_label_privacy"
+#~ msgstr "éšç§ç­–ç•¥"
+
+#~ msgid "devcp_form_label_sitespecific"
+#~ msgstr "这是一个特定站点附加组件"
+
+#~ msgid "devcp_form_label_summary"
+#~ msgstr "摘è¦"
+
+#~ msgid "devcp_form_label_supportemail"
+#~ msgstr "技术支æŒé‚®ç®±"
+
+#~ msgid "devcp_form_label_supporturl"
+#~ msgstr "技术支æŒç½‘ç«™"
+
+#~ msgid "devcp_form_label_target_applications"
+#~ msgstr "目标应用程åº"
+
+#~ msgid "devcp_form_label_version"
+#~ msgstr "版本"
+
+#~ msgid "devcp_form_label_versionnotes"
+#~ msgstr "版本记录"
+
+#~ msgid "devcp_form_no_target_apps"
+#~ msgstr "æ— "
+
+#~ msgid "devcp_form_reviewernotes"
+#~ msgstr "给审阅者消æ¯"
+
+#~ msgid "devcp_form_trustedaddon_destination"
+#~ msgstr "因为你的附加组件å¯ä¿¡ä»»ï¼Œè¯·é€‰æ‹©è¿™ä¸ªç‰ˆæœ¬åŽ»å‘:"
+
+#~ msgid "devcp_form_trustedaddon_destination_public"
+#~ msgstr "公共"
+
+#~ msgid "devcp_form_trustedaddon_destination_sandbox"
+#~ msgstr "沙盒"
+
+#~ msgid "devcp_header_developer_agreement"
+#~ msgstr "å¼€å‘者åè®®"
+
+#~ msgid "devcp_header_step1"
+#~ msgstr "步骤 1"
+
+#~ msgid "devcp_header_step1_upload"
+#~ msgstr "上传文件"
+
+#~ msgid "devcp_header_step2"
+#~ msgstr "步骤 2"
+
+#~ msgid "devcp_header_step2_addondetails"
+#~ msgstr "附加组件细节"
+
+#~ msgid "devcp_header_step3"
+#~ msgstr "步骤 3"
+
+#~ msgid "devcp_header_step3_versiondetails"
+#~ msgstr "版本细节"
+
+#~ msgid "devcp_header_step4"
+#~ msgstr "步骤 4"
+
+#~ msgid "devcp_header_step4_localization"
+#~ msgstr "本地化"
+
+#~ msgid "devcp_header_step5"
+#~ msgstr "步骤 5"
+
+#~ msgid "devcp_header_step5_success"
+#~ msgstr "完æˆ"
+
+#~ msgid "devcp_index_header_myaddons"
+#~ msgstr "我的附加组件"
+
+#~ msgid "devcp_nominate_link_returnto_details"
+#~ msgstr "返回附加组件详情"
+
+# %1 is the autodetected addon type
+#~ msgid "devcp_notice_autodetected_addontype"
+#~ msgstr "自动检测附加组件类型: %s."
+
+# %1 is the default locale name (English (US))
+# %2 is the default locale code (en-US)
+# %3 is the current page locale name (Deutsch)
+# %4 is the current page locale code (de)
+#~ msgid "devcp_notice_different_defaultlocale"
+#~ msgstr ""
+#~ "该附加组件的默认语言设置(%1$s [%2$s])与你当å‰é€‰æ‹©çš„语言(%3$s [%4$s])ä¸ä¸€"
+#~ "致。下é¢çš„字段应该在 %1$s 完æˆã€‚"
+
+#~ msgid "devcp_question_addontype_incorrect"
+#~ msgstr "ä¸æ­£ç¡®ï¼Ÿ"
+
+#~ msgid "devcp_question_delete_file"
+#~ msgstr "你确认è¦åˆ é™¤è¿™ä¸ªæ–‡ä»¶ï¼Ÿ"
+
+#~ msgid "devcp_skip_reviewing_addon_info"
+#~ msgstr "ä¸æ›´æ–°æˆ‘当å‰çš„附加组件信æ¯"
+
+#~ msgid "devcp_submissions_disabled"
+#~ msgstr "ç›®å‰ä¸èƒ½æ交附加组件,请ç¨åŽå†è¯•ã€‚"
+
+#~ msgid "devcp_submit_accept_dev_agreement"
+#~ msgstr "我接å—"
+
+#~ msgid "devcp_submit_decline_dev_agreement"
+#~ msgstr "我ä¸æŽ¥å—"
+
+#~ msgid "devcp_summary_admin_disabled"
+#~ msgstr "该附加组件被管ç†å‘˜ç¦ç”¨ã€‚"
+
+#~ msgid "devcp_summary_header_disabled"
+#~ msgstr "ç¦ç”¨"
+
+#~ msgid "devcp_summary_header_trusted"
+#~ msgstr "å—信任的"
+
+# %1 is a link to the addon submit page
+#~ msgid "devcp_summary_noaddons_submit_one"
+#~ msgstr "你没有任何附加组件,点击 %s æ交。"
+
+#~ msgid "devcp_summary_noaddons_submit_one_link"
+#~ msgstr "这里"
+
+# %1 is the link to the preview upload page
+#~ msgid "devcp_theme_upload_preview"
+#~ msgstr "è¯·ç¡®è®¤è¯¥ä¸»é¢˜å·²ç» %s 。"
+
+#~ msgid "devcp_theme_upload_preview_link"
+#~ msgstr "上传预览图片"
+
+#~ msgid "devcp_version_edit_pagetitle"
+#~ msgstr "编辑版本"
+
+#~ msgid "devcp_version_updated_successfully"
+#~ msgstr "版本更新æˆåŠŸã€‚"
+
+#~ msgid "editors_submissiontype_new"
+#~ msgstr "新组件"
+
+#~ msgid "editors_submissiontype_updated"
+#~ msgstr "已更新"
+
+#, fuzzy
+#~ msgid "editors_th_addon_age"
+#~ msgstr "Addon Age"
+
+#~ msgid "editors_th_addontypes"
+#~ msgstr "附加组件类别"
+
+#~ msgid "editors_th_age"
+#~ msgstr "历ç»çš„时间"
+
+#~ msgid "editors_th_applications"
+#~ msgstr "应用程åº"
+
+#~ msgid "editors_th_platforms"
+#~ msgstr "å¹³å°"
+
+#~ msgid "editors_th_submissiontypes"
+#~ msgstr "æ交的类别"
+
+#~ msgid "error_notice"
+#~ msgstr "注æ„"
+
+#~ msgid "forum_save"
+#~ msgstr "ä¿å­˜"
+
+#, fuzzy
+#~ msgid "home"
+#~ msgstr "home"
+
+#~ msgid "nav_category_plugins"
+#~ msgstr "æ’件"
+
+#~ msgid "page_title_experimental_addons"
+#~ msgstr "试验性的"
+
+#~ msgid "pages_experimental_addons_backbutton"
+#~ msgstr "返回å‰ä¸€é¡µ"
+
+# %1 is page number, %2 is total page count
+#~ msgid "pagination_page_number_title"
+#~ msgstr "这是第 %1$s 页 共 %2$s 页"
+
+#~ msgid "search_matching_addons_number"
+#~ msgid_plural "search_matching_addons_number"
+#~ msgstr[0] "%s 个符åˆæ¡ä»¶çš„附加组件"
+#~ msgstr[1] "%s 个符åˆæ¡ä»¶çš„附加组件"
+
+#~ msgid "statistics_rss_icon_title"
+#~ msgstr "统计数æ®æ”¶å–点"
diff --git a/site/app/locale/zh_CN/images/sandbox-review.png b/site/app/locale/zh_CN/images/sandbox-review.png
new file mode 100644
index 0000000..5a2759e
--- /dev/null
+++ b/site/app/locale/zh_CN/images/sandbox-review.png
Binary files differ
diff --git a/site/app/locale/zh_CN/pages/error404.thtml b/site/app/locale/zh_CN/pages/error404.thtml
new file mode 100644
index 0000000..54d4f5c
--- /dev/null
+++ b/site/app/locale/zh_CN/pages/error404.thtml
@@ -0,0 +1,16 @@
+<h1>很抱歉,未找到你æœå¯»çš„内容。</h1>
+
+<p>你请求的页é¢æˆ–文件在本站未找到。å¯èƒ½æ˜¯å› ä¸ºä½ ç‚¹å‡»äº†è¿‡æœŸçš„链接,或者输入了错误的地å€ã€‚</p>
+
+<ul>
+<li>如果是输入的地å€ï¼Œè¯·å†æ¬¡æ£€æŸ¥æ‹¼å†™ã€‚</li>
+<li>如果是通过其他链接进入,请æ¥ä¿¡å‘ŠçŸ¥<a href="mailto:webmaster@mozilla.com" title="Page Not Found on Mozilla.com">我们</a>,说明从何处点击以åŠä½ å¸Œæœ›çœ‹åˆ°çš„内容,我们会尽é‡ä¿®å¤ã€‚</li>
+</ul>
+
+<p>或者你å¯ä»¥è½¬åˆ°æœ¬ç«™å¸¸è§çš„页é¢çœ‹çœ‹ã€‚</p>
+
+<ul>
+<li>你对<a href="%1$s">热门附加组件列表</a>感兴趣么?</li>
+<li>你想ä¸æƒ³ <a href="%2$s">æœç´¢é™„加组件</a>? å¯ä»¥åŽ» <a href="%2$s">æœç´¢é¡µ</a> 或者利用上é¢çš„æœç´¢æ¡†ã€‚</li>
+<li>如果你喜欢从头开始,å¯ä»¥è½¬åˆ°<a href="%3$s">附加组件首页</a>。</li>
+</ul>
diff --git a/site/app/locale/zh_CN/pages/nomination.thtml b/site/app/locale/zh_CN/pages/nomination.thtml
new file mode 100644
index 0000000..4d84820
--- /dev/null
+++ b/site/app/locale/zh_CN/pages/nomination.thtml
@@ -0,0 +1,10 @@
+<p>当å‰åœ¨æ²™ç›’中的附加组件,ç»è¿‡ç¼–辑评审之åŽï¼Œå¯ä»¥æŽ¨è到公开站点并å…许所有用户访问。为了获得最佳效果,请注æ„以下信æ¯ï¼š</p>
+<ul>
+ <li>主题必须具有预览图,对于其他类型的附加组件,我们也强烈建议您æ供预览图片。</li>
+ <li>附加组件应该在沙盒中放置足够长的时间,以积累æ¥è‡ªç”¨æˆ·çš„评论和å馈。<b>è¦æˆä¸ºå…¬å¼€çš„附加组件,必须ç»è¿‡è¯„审。</b></li>
+ <li>公开的附加组件相比沙盒中的附加组件,具有更高的质é‡è¦æ±‚,并且,应该能够增强网络应用。</li>
+ <li>在 <a href="%s">附加组件政策</a> 中å¯ä»¥å¾—到完整的推è标准。</li>
+</ul>
+<p>如果您的附加组件符åˆä»¥ä¸Šæ ‡å‡†ï¼Œæ‚¨å¯ä»¥å°†ä¸‹åˆ—æ ç›®å¡«å†™å®Œæ•´ä»¥åŽæŽ¨è您的附加组件。通过电å­é‚®ä»¶ï¼Œæ‚¨å°†èŽ·å¾—关于您的推è状æ€çš„通知。</p>
+
+<p>è¦æŽ¨è您的附加组件,请说明该附加组件如何ç»è¿‡æµ‹è¯•(包括它是å¦å·²ä¸å­˜åœ¨é”™è¯¯å’Œè­¦å‘Š)以åŠå®ƒå¯¹äºŽæ‹“展网络具有多大用处。说明中也å¯ä»¥åŒ…å«è¯¥é™„加组件的外部评审的链接。</p>
diff --git a/site/app/locale/zh_CN/pages/policy.thtml b/site/app/locale/zh_CN/pages/policy.thtml
new file mode 100644
index 0000000..83f2756
--- /dev/null
+++ b/site/app/locale/zh_CN/pages/policy.thtml
@@ -0,0 +1,110 @@
+<h1>附加组件策略</h1>
+
+<h2>什么是"沙盒"(sandbox)?</h2>
+<p>å‚看 %s.</p>
+
+<h2>"沙盒"里有些什么附加组件?</h2>
+<p>"沙盒"是所有å‘布在AMO上的附加组件å¯åŠ¨å’Œæ‰§è¡Œçš„地方。它包å«äº†å…¬å…±é™„加组件的新版本,也有所有版本的éžå…¬å…±è½¯ä»¶ã€‚当一个新的附加组件或已有软件的更新å‘布到AMO,它就会被放进“沙盒â€ã€‚</p>
+
+<p>有些附加组件和它们的æŸäº›ç‰¹å®šç‰ˆæœ¬é€šè¿‡å®¡æŸ¥è¯´æ˜Žå®ƒä»¬å·²é€‚åˆå‘布之åŽï¼Œå°±ä¼šè¢«å…¬å¼€å‘布。其它的附加组件将无期é™åœ°ç•™åœ¨â€œæ²™ç›’â€å†…,用户å¯ä»¥æµè§ˆâ€œæ²™ç›’â€è½¯ä»¶åˆ—表并体验这些软件。</p>
+
+<h2>如何将附加组件å‘布到公开区域?</h2>
+
+<p>附加组件由AMO用户进行审查,他们查看沙盒,对å‘现的安装包进行测试。AMO用户写的评论显示了一个附加组件是å¦æœ‰ç”¨ï¼Œå†™çš„是å¦å¤Ÿå¥½ä»¥åŠæ˜¯å¦å€¼å¾—æ供给所有Firefox用户选择。这些评论,å¯èƒ½è¿˜åŒ…括由AMO团队进行的其他审查审核,将会决定该附加组件是å¦è¢«å…¬å¼€å‘布,或者需è¦åšæ›´å¤šçš„工作予以改进,或者就ä¸åˆé€‚å‘布到AMO沙盒以外的地方。</p>
+
+<h2>如何让我的附加组件å‘布到公共区域?</h2>
+
+<p>如果你确信自己的附加组件(以åŠå¼€å‘状æ€ï¼‰å·²ç»æ»¡è¶³å…¬å¼€å‘布组件的è¦æ±‚,你å¯ä»¥é€šè¿‡å¼€å‘者控制é¢æ¿æ交。</p>
+
+<h2>公开å‘布的附加组件的标准是什么?</h2>
+
+<p>公开å‘布在AMO的附加组件必须是高质é‡çš„,能够改善用户的网络体验。我们通过检查以下项目决定一个附加组件是å¦åº”该å‘布到AMO的公共区域:</p>
+
+<h3>你回应了么?</h3>
+
+<p>我们希望将附加组件æ交给Firefox众多用户的作者,能够对报告的问题作出å“应,维护他们的è”系信æ¯ï¼Œæ›´æ–°é™„加组件版本以适应Firefox版本的更新。这并ä¸æ„味ç€ä½ å¿…须回å¤è®ºå›ä¸Šæ¯ä¸€ä¸ªç”¨æˆ·çš„æ¯ä¸€ä¸ªé—®é¢˜ï¼Œæˆ–者必须修å¤æ¯ä¸€ä¸ªç¼ºé™·ã€‚但是我们希望你能够严肃地对待讨论中å映出æ¥çš„问题。</p>
+
+<h3>附加组件是å¦æœ‰æ¸…晰准确的æ述?</h3>
+
+<p>用户å°è¯•ä¸€ä¸ªæ–°çš„附加组件之å‰ï¼Œå‡†ç¡®èŽ·çŸ¥å…¶åŠŸèƒ½æ˜¯éžå¸¸é‡è¦çš„。你的æè¿°è¦è¯¦ç»†è¯´æ˜Žè¿™ä¸ªé™„加组件能åšä»€ä¹ˆï¼Œç”¨æˆ·å¦‚何è¿ç”¨ï¼Œä»¥åŠå®‰è£…以åŽèƒ½å¤Ÿè¾¾åˆ°ä»€ä¹ˆæ•ˆæžœã€‚链接外部文档æ供详细说明是一个ä¸é”™çš„主æ„,但是自我æ述能够æ供基本的信æ¯å¹¶ä¸”增强用户试用的信心。</p>
+
+<p>å¦å¤–,维护版本说明与更新附加组件本身一样é‡è¦ã€‚用户通过它å¯ä»¥çŸ¥é“新版本比先å‰æœ‰å“ªäº›æ›´æ–°ï¼Œå‡çº§çš„时候对他们的使用å¯èƒ½å¸¦æ¥ä»€ä¹ˆå½±å“。(眼下,用户在æµè§ˆå™¨é‡Œå¾—到更新æ示的时候,是看ä¸åˆ°ç‰ˆæœ¬è¯´æ˜Žçš„,但是我们正在试图修å¤è¿™ä¸ªé—®é¢˜ã€‚如果你良好地维护了版本说明,该问题修å¤åŽä½ çš„用户就会因此获益。)</p>
+
+<h3>所有éšç§å’Œå®‰å…¨æ–¹é¢çš„问题是å¦éƒ½å·²è¯´æ˜Žï¼Ÿ</h3>
+
+<p>清晰准确的æ述是一个方é¢ï¼Œä½†æ˜¯ä¸€ä¸ªå¾ˆé‡è¦çš„问题我们觉得有必è¦ç‰¹åˆ«ç•™æ„。很多有用的ã€åˆ¶ä½œç²¾è‰¯çš„附加组件,会收集用户资料,或者在使用ä¸å½“的情况下存在æŸäº›å®‰å…¨éšæ‚£ã€‚这些附加组件ä»ç„¶å¯ä»¥å‘布到AMO的公共区域,但是必须å‘用户明确说明å¯èƒ½é‡åˆ°çš„风险,以åŠå¦‚何自我ä¿æŠ¤ã€‚</p>
+
+<h3>附加组件是å¦ç»è¿‡äº†å……分测试?是å¦å·²ç»å¤„ç†äº†æ‰€æœ‰æ˜Žæ˜¾çš„或者严é‡çš„问题?</h3>
+
+<p>我们考虑一个沙盒中的附加组件能å¦å‘布给公众使用时,有一个很é‡è¦çš„因素,根æ®æ²™ç›’中的评论看它是å¦ç»è¿‡äº†å……分测试,ä¸èƒ½å­˜åœ¨ä¸¥é‡çš„问题或者给æµè§ˆå™¨å¸¦æ¥ä¸å¥½çš„å½±å“。如果评审报告显示,在使用附加组件的功能时,é‡åˆ°äº†é‡å¤§æ€§èƒ½é—®é¢˜ï¼Œå´©æºƒï¼Œé¢‘å‘故障,或者在错误控制å°æ”¶åˆ°å¤§é‡ä¿¡æ¯ï¼Œä½ åº”当认真对待这些报告,尽å¯èƒ½è§£å†³å®ƒä»¬ï¼Œç„¶åŽé‡æ–°æ交申请。我们ä¸æœŸå¾…你的附加组件ç»è¿‡å®Œç¾Žä¼˜åŒ–或者没有任何缺陷——Firefox自身在这方é¢ç»åŽ†è¿‡é•¿æœŸçš„改进——但是我们希望你作出必è¦çš„努力,尽é‡å‡å°‘è´Ÿé¢å½±å“,并且在用户é‡åˆ°é—®é¢˜æ—¶åšå‡ºæ˜Žç¡®å“应。</p>
+
+<p>如果你的附加组件已ç»ç»è¿‡AMO沙盒以外的测试,例如ç»è¿‡äº†ä½ æœåŠ¡çš„一组用户或者质é‡å›¢é˜Ÿçš„测试,你å¯ä»¥åœ¨æ交申请的信æ¯ä¸­è¯´æ˜Žã€‚这通常有助于我们确认已进行了何ç§ç¨‹åº¦çš„测试,并有助于你的附加组件公开å‘布。</p>
+
+<h3>附加组件åŠä½œè€…是å¦å……分尊é‡ç”¨æˆ·ï¼Ÿ</h3>
+
+<p>你的软件ä¸èƒ½å¯¹ç”¨æˆ·åšä¸å¿…è¦çš„干涉,试图欺骗用户,或者对用户éšçž’自身的活动。用户(甚至éžç”¨æˆ·ï¼‰æœ‰æ—¶ä¼šæœ‰ç²—é²çš„评论,当然我们会在接到报告以åŽå°½å¿«è¿‡æ»¤æŽ‰ã€‚我们希望作者能够é¿å…以粗é²çš„言辞进行报å¤ã€‚</p>
+
+<h3>附加组件是å¦å¯¹ä¸€ä¸ªç›¸å½“广泛的Firefox用户群体都有用?</h3>
+
+<p>你的附加组件ä¸ä¸€å®šè¦æˆä¸ºä¸‹ä¸€ä¸ªGreasemonkey或者FireBug,但是如果它åªå¯¹ä½ çš„å…¬å¸æˆ–者很少一部分社区人群有用,我们认为是ä¸é€‚åˆå°†å…¶å‘布给全体Firefox用户的。</p>
+
+<p>我们一直试图改善网站的组织结构,用其他方å¼æ›´å¥½åœ°å±•ç¤ºä¸€äº›å ªç§°å…¸èŒƒçš„附加组件——但是它们仅针对一个很å°çš„用户群体。正确地分类,维护好你的附加组件的元数æ®ï¼Œèƒ½å¤Ÿå¸®åŠ©æˆ‘们确定一个更好的秩åºå±•ç¤ºè¿™äº›é™„加组件,使相应的用户能够从中获益。</p>
+
+<p>如果你的附加组件仅仅æ供了通å‘你的网站的书签或其他简å•çš„访问入å£ï¼Œå®ƒæ˜¾ç„¶ä¸é€‚åˆå‘布到网站的公共区域。和其它Mozilla项目一样,我们喜爱网页应用程åºå’Œæ–°çš„网络æœåŠ¡ï¼Œä½†æ˜¯Firefox附加组件时应该能改善用户æµè§ˆç½‘络的体验,而ä¸ä»…仅是通过AMO列表推广一个新的网站或者æœåŠ¡ã€‚如果你的附加组件的æ述主è¦æ˜¯å…³äºŽæœåŠ¡è€Œéžæ”¹å–„用户的æµè§ˆä½“验,那么显然你æžé”™äº†æ–¹å‘。</p>
+
+<h3>附加组件是å¦ä¾µçŠ¯äº†å•†æ ‡è®¸å¯æˆ–者版æƒï¼Ÿ</h3>
+
+<p>ä½ å¯èƒ½æ— æ„侵害商标æŒæœ‰è€…或者版æƒä½œå“所有者的æƒç›Šï¼Œæˆ‘们ä¸ä¼šå­˜æ”¾ä¾µçŠ¯å•†æ ‡æƒæˆ–者版æƒçš„附加组件。如果你没有获得许å¯ä½¿ç”¨ä¸€ä¸ªå•†æ ‡å称或图案,请ä¸è¦å°†ä½ çš„附加组件æ交到AMO。如果你的附加组件包å«äº†å…¶ä»–人版æƒæ‰€æœ‰çš„代ç ï¼Œå¹¶ä¸”没有得到许å¯åœ¨ä½ çš„附加组件中使用,也请ä¸è¦æ交。(如果商标ã€ç‰ˆæƒæ‰€æœ‰è€…å‘现他们的商标被使用,我们很å¯èƒ½ä¼šæŽ¥åˆ°å¾‹å¸ˆçš„删除建议,并且我们会根æ®æ³•å¾‹è¦æ±‚删除相关的附加组件。对于项目资æºæ¥è¯´ï¼Œè¿™æ˜¯ä¸€ä¸ªä»£ä»·é«˜æ˜‚的过程,包括时间和ç»æµŽæ–¹é¢çš„,所以我们希望你å°å¿ƒä»Žäº‹ï¼Œå¹¶ä¸”ä¸è¦ä½¿æˆ‘们陷入这ç§å›°æ‰°ã€‚</p>
+
+<p>如果你无法确认附加组件的å称或者内容是å¦æ¶‰åŠä»¥ä¸Šé—®é¢˜ï¼Œæ˜¯å¦ä¼šå½±å“å…¶å‘布,你å¯ä»¥å‘ amo-editors@mozilla.org 咨询。é‡è¦æ示:请注æ„这个团队ä¸èƒ½æ供法律建议,甚至如果我们认为你的使用是å¯ä»¥æŽ¥å—的,ä»ç„¶å¯èƒ½ç»“åˆæƒåˆ©æ‰€æœ‰äººçš„投诉ã€æ³•å¾‹é¡¾é—®çš„建议é‡æ–°ä½œå‡ºå†³å®šã€‚</p>
+
+<p>é‡ç”¨å…¶ä»–附加组件的æºä»£ç æ—¶ï¼Œå¦‚果作者没有明确许å¯ä½ ä½¿ç”¨ä»–的代ç â€”—例如将代ç ç½®äºŽä¸€ä¸ªå¼€æ”¾æºä»£ç è®¸å¯å议下——那么你应该知é“自己无æƒä½¿ç”¨ã€‚ä½ å¯ä»¥è”系作者以或许许å¯ï¼Œä½†æ˜¯æˆ‘们ä¸èƒ½å‘ä½ æ供任何特别的æƒåˆ©ï¼Œä¸è®ºæ˜¯å› ä¸ºä»–呈现在AMO上,或者因为作者没有åŠæ—¶å›žåº”你的请求。(并且,é‡ç”³ä¸€ä¸‹ï¼Œæˆ‘们ä¸èƒ½æ供法律建议,而仅仅是æ示你的附加组件看上去是å¦ç¬¦åˆæœ¬ç«™è¦æ±‚。)</p>
+
+<p>è¿™åŒæ ·é€‚用于Mozilla基金会的商标,包括"Mozilla","Firefox",以åŠ"Thunderbird"。Mozilla有关商标使用的政策是为了防止商标使用中的混淆,以åŠå•†æ ‡å› ä¸ºç¼ºä¹ä¿æŠ¤è€Œè¢«å®£å¸ƒæ— æ•ˆï¼›è¯·å°Šé‡è¿™ç§ä¿æŠ¤çš„å¿…è¦æ€§ï¼Œå¹¶å¸®åŠ©æˆ‘们维护Mozilla基金会这些最å®è´µçš„资产。</p>
+
+<h2>我æ交了一个附加组件以åŽä¼šæ€Žæ ·å‘¢ï¼Ÿ</h2>
+
+<p>一旦你的附加组件æ请审查,就会有AMO的编辑根æ®ä»¥ä¸Šå„项è¦æ±‚进行评估。如果认为å¯ä»¥å‘布到公共区域,就会å‘布上去。一开始评估,你就会收到邮件æ示。</p>
+
+<p>如果我们觉得这个附加组件此时ä¸é€‚宜å‘布到AMO公共区域,你将会收到邮件æ示说明原因,你的请求会被从审核队列中删除。如果当你觉得已ç»è§£å†³äº†æ示中所说的问题,你希望å†æ¬¡è¯„估,你有æƒè¿™æ ·åšã€‚在没有进行实质改进的情况下é‡å¤æ请审查,是ä¸å—欢迎的,所以请三æ€åŽè¡Œï¼›ä½ çš„行动å¯èƒ½ä¼šæ¿€æ€’我们。</p>
+
+<h2>我能å¦æ交其他人的附加组件?</h2>
+
+<p>ç›®å‰ï¼Œæˆ‘们è¦æ±‚由附加组件的作者æ交他们的作å“。我们è¦ç¡®è®¤ä½œè€…æ„¿æ„扩大产å“çš„å½±å“,并且认为产å“当å‰çš„状æ€å·²ç»èƒ½å¤Ÿå映他们的工作质é‡ã€‚如果你认为一个附加组件是优秀的,他的作者éµå®ˆäº†AMO相关政策的æ¡æ¬¾ä¸Žç²¾ç¥žï¼Œä¸”它对Firefoxã€ç”¨æˆ·å’Œå…¨ä¸–ç•Œåƒåƒä¸‡ä¸‡çš„网络使用者有益,那么你应该积æžé¼“励作者æ交他们的附加组件。</p>
+
+<h2>我的附加组件已ç»åŠ å…¥å®¡æŸ¥é˜Ÿåˆ—很久了,你们讨厌我么?</h2>
+
+<p>我们ä¸è®¨åŽŒä½ ï¼Œæˆ‘们喜爱附加组件的开å‘者,我们辛勤工作以便让他们高兴而能够制作更多的作å“,以便全世界都能够从他们的工作中å—益。但是å‘布到AMO公共区域是一个éžå¸¸ä¸¥æ ¼çš„æµç¨‹ï¼Œå› ä¸ºæˆ‘们è¦å°å¿ƒçš„é¢å¯¹å„ç§é£Žé™©ã€‚因此我们ä¸èƒ½è¿‡äºŽè‰çŽ‡åœ°å¤„ç†è¿™äº›é—®é¢˜ã€‚我们能够ç†è§£ç­‰å¾…评估时的焦虑甚至沮丧,也希望将这段时间尽å¯èƒ½ç¼©çŸ­ã€‚在沙盒中有越多的用户æ供谨慎而明确的评论,评估过程就会越顺利。所以你也å¯ä»¥è€ƒè™‘å‚加沙盒内的测试活动以帮助加快这个进程。</p>
+
+<h2>我å‘现自己的附加组件中存在一个严é‡çš„缺陷,并且确实希望尽快修å¤ã€‚应该怎么åšå‘¢ï¼Ÿ</h2>
+
+<p>如果存在严é‡çš„缺陷(安全性ã€ç¨³å®šæ€§ã€ä¸»è¦åŠŸèƒ½æœ‰é—®é¢˜ï¼‰ä½ éœ€è¦è¿›è¡Œæ›´æ–°ï¼Œä½ åº”该在æ交更新时写在审核说明中——和在版本说明中一样,显然的ï¼ä½ å¯èƒ½ä¹Ÿå¸Œæœ›çŽ°æœ‰ç”¨æˆ·èƒ½å¤Ÿåœ¨æ²™ç›’中帮助你测试附加组件的更新并汇报结果。进入 irc.mozilla.org çš„ #addons 频é“能够帮助用户认清问题,但是如果你这么åšï¼Œè¯·æ³¨æ„ä¿æŒè€å¿ƒå’Œç¤¼è²Œã€‚</p>
+
+<p>请ä¸è¦ç»å¸¸å–Šç‹¼æ¥äº†ã€‚我们å°è¯•ç€å¯¹é«˜ä¼˜å…ˆçº§çš„更新进行快速处ç†ï¼Œä½†æ˜¯è¿™ä¼šå»¶ç¼“我们对其他附加组件或版本的审核,且ç»å¸¸ä¼šæ¶ˆè€—我们的ç¡çœ æ—¶é—´æˆ–者与家人ã€æœ‹å‹åœ¨ä¸€èµ·çš„时间,所以我们低调å°è¯•æ供一ç§â€œæ’队â€æœºåˆ¶ã€‚如果你ä¸èƒ½ç¡®å®šæ˜¯å¦åº”该借助这个机制,å¯ä»¥åœ¨ irc.mozilla.org çš„ #addons频é“寻求帮助。
+
+<h2>当我认为我的附加组件在审查的过程中é‡åˆ°äº†ä¸å…¬æ­£çš„对待时,应该怎么办呢?</h2>
+
+<p>如果你确信你的附加组件没有被正确的审核,以至于无法å‘公众å‘布,你应该å‘一å°ç”µå­é‚®ä»¶åˆ° amo-editors@mozilla.org 申诉。请注æ„在你的邮件中è¦æ³¨æ„礼貌,并且请井然有åºçš„列举出你认为你的附加组件没有被公正审核的详细ç†ç”±ã€‚</p>
+
+<p>(如果你已ç»ä¿®å¤äº†*所有*的在我们å‘给你的确认邮件中列举出的问题,你就å¯ä»¥é€šè¿‡æŽ§åˆ¶é¢æ¿é‡æ–°æ交你的附加组件,ä¸å¿…å†æ¬¡å‘邮件申诉了。)</p>
+
+<h2>我的附加组件曾ç»å…¬å¼€å‘布过,现在放入了沙盒,å‘生什么问题了?</h2>
+
+<p>如果附加组件ä¸å†é€‚åˆæ”¾åœ¨ç½‘站公开区域,我们å¯ä»¥å°†å…¶ç§»å›žæ²™ç›’。除éžé­åˆ°æ³•å¾‹é™åˆ¶ï¼Œå¦åˆ™å‘生这ç§æƒ…况时我们会å‘é€ç”µå­é‚®ä»¶æ示你,并说明这么åšçš„ç†ç”±ã€‚</p>
+
+<p>å¦ä¸€ç§å¯èƒ½æ˜¯ä½ å‘现了网站上的缺陷,这ç§æƒ…况下你å¯ä»¥é€šè¿‡Bugzilla系统汇报,产å“是 "addons.mozilla.org",组件为"Public Pages",并且尽å¯èƒ½è¯¦ç»†è¯´æ˜Žæƒ…况。</p>
+
+<h2>我的附加组件已ç»å‘布,用户看上去很喜欢。我如何能将他列入推è附加组件列表?</h2>
+
+<p>如果你相信自己的附加组件是优秀的典范, 显示并æå‡äº†Mozilla产å“在扩展性和用户控制网络方é¢çš„价值,并且æ供了å“越的用户体验,你å¯ä»¥è¦æ±‚将其列入推è附加组件列表。为此,你应该å‘é€ä¸€å°ç”µå­é‚®ä»¶åˆ° amo-editors@mozilla.org 说明你的附加组件好在何处。</p>
+
+<p>你的邮件应该<b>至少</b>包括以下内容:</p>
+<ul>
+<li>是如何改善用户的网络体验的</li>
+<li>你的附加组件是如何赢得大é‡Firefox用户é’ççš„</li>
+<li>你的附加组件如何显示和/或æå‡äº†Mozilla项目的价值,特别是关于对用户负责,ä¿æŠ¤éšç§å’Œå®‰å…¨æ€§ï¼Œç½‘络访问适应性以åŠå¼€æ”¾æ ‡å‡†å’Œæ•°æ®ã€‚</li>
+<li>你的附加组件与其他相似产å“有什么区别(包括优缺点)</li>
+<li>你从用户,评论者,åšå®¢ï¼Œå®‡èˆªå‘˜ä¹ƒè‡³ä½ çš„家庭宠物哪里获得了哪些å馈,无论是正é¢è¿˜æ˜¯è´Ÿé¢çš„。</li>
+</ul>
+
+<p>你的申请中,对以上信æ¯æ供得越详细,我们接å—它的å¯èƒ½æ€§è¶Šå¤§ï¼Œå°½ç®¡å†™å¾—很好很详尽也并ä¸èƒ½ä¿è¯ä¸€å®šå¯ä»¥èŽ·å¾—推è列表中的ä½ç½®ã€‚最åŽï¼Œè¿™ä¸ªåˆ—表一定是——并且正是——由Mozilla确认维护的,而用户体验并获得ä¿æŠ¤æ˜¯æœ€é‡è¦çš„。</p>
diff --git a/site/app/locale/zh_CN/pages/sandbox.thtml b/site/app/locale/zh_CN/pages/sandbox.thtml
new file mode 100644
index 0000000..8b1cf72
--- /dev/null
+++ b/site/app/locale/zh_CN/pages/sandbox.thtml
@@ -0,0 +1,14 @@
+<h1>沙盒预览系统</h1>
+
+<h2>什么是沙盒?</h2>
+<p>沙盒是高级用户在通常使用之å‰æµ‹è¯•é™„加组件预览区。必须在账户设置中打开æ‰èƒ½ä½¿ç”¨æ²™ç›’。安装沙盒里的附加组件è¦å°å¿ƒï¼Œå› ä¸ºå®ƒä»¬æ²¡æœ‰è¢«ç¼–辑测试,并且有å¯èƒ½å±å®³åˆ°ä½ çš„计算机。</p>
+
+<h2>如何公布我的附加组件?</h2>
+<!-- To localize the flowchart image, see http://wiki.mozilla.org/Update:Remora_Sandbox_Flowchart -->
+<div style="text-align: center;">%s</div>
+<ol>
+ <li><b>在开å‘者控制é¢æ¿æ交你的附加组件。</b> 你的项目会被立å³å±•ç¤ºåœ¨ Mozilla 附加组件沙盒,在那,有ç»éªŒçš„用户将会测试并æ交å馈。必须在账户设置中打开æ‰èƒ½ä½¿ç”¨æ²™ç›’。</li>
+ <li><b>推è你的附加组件å‘布。</b>在开å‘者控制é¢æ¿ï¼Œæœ‰ä¸€ä¸ªé“¾æŽ¥å¯ä»¥æŽ¨è你的附加组件。推èåŽï¼Œä½ çš„附加组件会进入编辑推è队列待审批。</li>
+ <li><b>编辑审阅你的附加组件。</b>ä¸€ä½ Mozilla 附加组件编辑将安装你的附加组件并测试其工作。编辑将åŒæ—¶æŸ¥çœ‹æ²™ç›’测试情况。.</li>
+ <li><b>你的附加组件被å‘布或继续ä¿ç•™åœ¨æ²™ç›’。</b> 编辑会å‘布你的附加组件或继续ä¿ç•™åœ¨æ²™ç›’。如果是继续ä¿ç•™åœ¨æ²™ç›’,你å¯ä»¥åœ¨æŒ‰ç…§ç¼–辑建议修改åŽå†æ¬¡æŽ¨è。如果被å‘布,你附加组件的未æ¥ç‰ˆæœ¬å°†åœ¨æ²™ç›’中,直到编辑审阅并å‘布。一旦你的附加组件å‘布,就ä¸éœ€è¦å†æ¬¡æŽ¨è - 未æ¥ç‰ˆæœ¬ä¼šè‡ªåŠ¨è¿›å…¥å®¡æ‰¹ç­‰å¾…队列。</li>
+</ol>
diff --git a/site/app/locale/zh_CN/pages/statistics_help.thtml b/site/app/locale/zh_CN/pages/statistics_help.thtml
new file mode 100644
index 0000000..3099065
--- /dev/null
+++ b/site/app/locale/zh_CN/pages/statistics_help.thtml
@@ -0,0 +1,7 @@
+<h3>帮助</h3>
+<p>统计é¢æ¿æ˜¾ç¤ºä½ çš„附加组件的下载和更新信æ¯ã€‚</p>
+<h4>下载é‡</h4>
+<p>下载统计信æ¯æ¯å¤©æ›´æ–°ï¼ŒåªåŒ…括原始下载的数é‡ï¼Œä¸åŒ…括更新。</p>
+
+<h4>更新次数</h4>
+<p>从这里下载的附加组件会æ¯å¤©æ£€æŸ¥ä¸€æ¬¡æ›´æ–°ï¼Œæ‰€æœ‰è¿™äº›æ›´æ–°çš„次数会被计入æ¯æ—¥æ´»è·ƒç”¨æˆ·æ•°ã€‚æ¯æ—¥æ´»è·ƒç”¨æˆ·æ•°ï¼ˆADU)会因附加组件的版本ã€æ“作系统ã€é™„加组件状æ€åŠåº”用程åºçš„ä¸åŒè€Œä¸­æ–­ã€‚这个数æ®ç›®å‰åªè®°å½•æ¯å‘¨çš„一天,å³å‘¨ä¸‰ã€‚</p> \ No newline at end of file
diff --git a/site/app/locale/zh_CN/pages/submission_help.thtml b/site/app/locale/zh_CN/pages/submission_help.thtml
new file mode 100644
index 0000000..d3acf62
--- /dev/null
+++ b/site/app/locale/zh_CN/pages/submission_help.thtml
@@ -0,0 +1,36 @@
+<h1>æ交帮助</h1>
+å¿…è¦å­—段使用<b>粗体</b>。å¯é€‰å­—段使用<i>斜体</i>。
+
+<h2 id="step1">步骤 1:上传</h2>
+<ul class="submissionHelp">
+ <li><span class="required">附加组件类型</span> - 默认,附加组件类型将根æ®ä¸Šä¼ æ–‡ä»¶è‡ªåŠ¨åˆ¤æ–­ã€‚ä½ å¯ä»¥ä¸ç”¨ä¿®æ”¹è¿™ä¸€å­—段。</li>
+ <li><span class="required">附加组件文件</span> - 你附加组件的包文件,完善的 install.rdf,如果文件åªèƒ½å·¥ä½œåœ¨æŒ‡å®šçš„å¹³å°ä¸Šï¼Œé€‰æ‹©ç›¸åº”å¹³å°ä»¥ä¾¿å…许一次上传多个文件。</li>
+ <li><span class="optional">图标文件</span> - 图标文件显示在附加组件å称的附近和附加组件安装对è¯æ¡†ã€‚将被自动调整至32x32åƒç´ ï¼Œä¿æŒæ–¹å‘比例。</li>
+ <li><span class="required">默认语ç§</span> - 附加组件的默认语ç§æ˜¯å®ƒçš„主è¦è¯­ç§ã€‚如果用户选择的语ç§å¯¹äºŽé™„加组件ä¸å¯ç”¨ï¼Œè½¬æ¢ç³»ç»Ÿå°†ä¼šè‡ªåŠ¨å¡«å†™é»˜è®¤è¯­ç§ã€‚</li>
+ <li><span class="optional">跳过语言当å‰é™„加组件信æ¯</span> - 如果你上传一个已ç»å­˜åœ¨çš„附加组件,这个字段将会出现,选择å¤é€‰æ¡†å°†è·³è¿‡ 步骤 3 的输入特定版本信æ¯ã€‚</li>
+</ul>
+
+<h2 id="step2">步骤 2:附加组件细节</h2>
+<ul class="submissionHelp">
+ <li><span class="required">å称</span> - 这个附加组件默认语ç§çš„å称</li>
+ <li><span class="required">作者</span> - 所有有æƒä¿®æ”¹è¿™ä¸ªé™„加组件用户的列表,并在页é¢ä¸Šæ˜¾ç¤ºæˆä½œè€…。</li>
+ <li><span class="required">分类</span> - 这个附加组件适用的分类。</li>
+ <li><span class="optional">主页</span> - 默认语ç§çš„附加组件站点</li>
+ <li><span class="required">摘è¦</span> - 默认语ç§çš„简短摘è¦ï¼Œè¿™ä¸ªå­—段最多å…许 250 个字符,展示在这个附加组件的显示页上,以åŠæœç´¢ã€æµè§ˆç»“果。</li>
+ <li><span class="required">æè¿°</span> - 默认语ç§çš„附加组件æ述,展示在这个附加组件显示页的摘è¦ä¸‹é¢ã€‚</li>
+ <li><span class="optional">EULA</span> - 用户在下载之å‰å¿…须接å—最终用户å议,使用默认语ç§ã€‚</li>
+ <li><span class="optional">éšç§ç­–ç•¥</span> - 附加组件的éšç§ç­–略,使用默认语ç§ã€‚éšç§ç­–略解释如何处ç†æœ€ç»ˆç”¨æˆ·çš„个人信æ¯ï¼Œå±•ç¤ºåœ¨é™„加组件显示页的按照按钮æ—边。附加信æ¯ä¸Šåº”包å«éšç§ç­–略,你的附加组件是å¦æœ‰ä¸€ä¸ªæœ‰æ•ˆçš„ <a href="%s">附加组件策略</a>.</li>
+ <li><span class="optional">å…许用户在线查看æºæ–‡ä»¶</span> - 选择这个å¤é€‰æ¡†å…许用户在线æµè§ˆä½ çš„附加组件æºæ–‡ä»¶ã€‚</li>
+ <li><span class="optional">这是预å‘行版</span> -选择这个å¤é€‰æ¡†æŒ‡ç¤ºè¿™ä¸ªé™„加组件是预å‘行版或 "beta" 版本。预å‘行版将ä¿æŒåœ¨æ²™ç›’中,ä¸èƒ½æŽ¨èå‘布,直到标志被清除。</li>
+ <li><span class="optional">这是一个特定站点的附加组件</span> - 选择这个å¤é€‰æ¡†æŒ‡ç¤ºè¿™ä¸ªé™„加组件特定到一个站点上。例如改å˜ä¸€å®šç«™ç‚¹çš„外观或显示特定站点的内容。这个字段对于编辑很有帮助以åŠå°†æ¥è¿‡æ»¤æœç´¢ã€‚</li>
+ <li><span class="optional">这个附加组件需è¦å¤–部软件</span> - 选择这个å¤é€‰æ¡†æŒ‡ç¤ºè¿™ä¸ªé™„加组件需è¦å¤–部软件。这个字段对于编辑很有帮助以åŠå°†æ¥è¿‡æ»¤æœç´¢ã€‚</li>
+</ul>
+
+<h2 id="step3">步骤 3:版本细节</h2>
+<ul class="submissionHelp">
+ <li><span class="required optional">版本记录</span> - 列出这个版本的修改摘è¦ï¼Œå¯¹äºŽæ–°æ交是å¯é€‰ï¼Œä½†æ›´æ–°æ—¶å¿…须。</li>
+ <li><span class="optional">传递记录给审阅者</span> - 这个字段是å‘é€ç»™å®¡é˜…你的附加组件的审阅者的信æ¯ï¼Œæµ‹è¯•å¸æˆ·ä¿¡æ¯å’ŒæŒ‡å®šçš„记录将会到达这里。</li>
+</ul>
+
+<h2 id="step4">步骤 4:本地化</h2>
+这是一个å¯ä»¥è¢«æœ¬åœ°åŒ–到所有支æŒçš„语ç§çš„附加组件字段。简å•çš„点选语ç§è¿›å…¥ç¿»è¯‘。
diff --git a/site/app/locale/zh_TW/LC_MESSAGES/messages.mo b/site/app/locale/zh_TW/LC_MESSAGES/messages.mo
new file mode 100644
index 0000000..329016e
--- /dev/null
+++ b/site/app/locale/zh_TW/LC_MESSAGES/messages.mo
Binary files differ
diff --git a/site/app/locale/zh_TW/LC_MESSAGES/messages.po b/site/app/locale/zh_TW/LC_MESSAGES/messages.po
new file mode 100644
index 0000000..fa11c5d
--- /dev/null
+++ b/site/app/locale/zh_TW/LC_MESSAGES/messages.po
@@ -0,0 +1,6992 @@
+msgid ""
+msgstr ""
+"Project-Id-Version: svn: Mozilla Addons\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2009-01-16 11:45-0800\n"
+"PO-Revision-Date: 2009-06-04 23:25+0800\n"
+"Last-Translator: timdream <timdream+narro@gmail.com>\n"
+"Language-Team: Chinese Traditional, Taiwan <LL@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+"X-Generator: Narro 0.9.2 on http://translate.moztw.org\n"
+
+#: views/addons/policy.thtml:98
+msgid "a_cancel_installation"
+msgstr "å–消安è£"
+
+#. This is the text that appears on buttons to download add-ons.
+#. %$1s is an optional string that only appears if the add-on is only available for
+#. a certain platform. Examples: (Windows) or (Linux)
+#. Note that the parentheses are included in the string. :(
+#: views/elements/amo2009/install.thtml:126
+#: views/elements/amo2009/install.thtml:227
+#: views/elements/amo2009/install.thtml:257
+#: views/elements/amo2009/install.thtml:300
+#: views/elements/amo2009/install.thtml:312 views/elements/install.thtml:73
+#: views/elements/install.thtml:181 views/elements/install.thtml:205
+#: views/elements/install.thtml:248 views/elements/install.thtml:260
+#: views/addons/plugins.thtml:66 views/addons/plugins.thtml:76
+#: views/addons/plugins.thtml:86 views/addons/plugins.thtml:96
+#: views/addons/plugins.thtml:119
+#, php-format
+msgid "a_download"
+msgstr "立刻下載 %s"
+
+#: views/addons/policy.thtml:72
+msgid "a_eula_download"
+msgstr "接å—並下載"
+
+#: views/addons/policy.thtml:74
+msgid "a_eula_install"
+msgstr "接å—並安è£"
+
+#: views/elements/header.thtml:76 views/elements/header.thtml:82
+#: views/api/api_addon.thtml:55 views/api/collections_feed.thtml:75
+#: views/sharing_api/addon.thtml:64
+msgid "a_header_public"
+msgstr "公開"
+
+#: views/elements/header.thtml:58 views/elements/header.thtml:75
+#: views/elements/header.thtml:80 views/api/api_addon.thtml:57
+#: views/api/collections_feed.thtml:77 views/sharing_api/addon.thtml:66
+msgid "a_header_sandbox"
+msgstr "沙箱"
+
+#. %s is a date in the _('date') format
+#: views/elements/amo2009/homepage_addon.thtml:115
+#: views/elements/addon_listitem.thtml:122 views/elements/feature.thtml:106
+#: views/addons/display.thtml:104 views/addons/browse_thumbs.thtml:73
+msgid "addon_detail_last_updated"
+msgstr "更新時間:%s"
+
+#. %s is the version of the add-on. Example: 3.2a1
+#: views/elements/amo2009/addon_version_detail.thtml:51
+#: views/elements/addon_version_detail.thtml:51
+#, php-format
+msgid "addon_display_header_version"
+msgstr "版本 %s"
+
+#: views/addons/browse_thumbs.thtml:80
+msgid "addon_downloads"
+msgstr "次下載"
+
+#: views/addons/display.thtml:147
+msgid "addon_downloads_total"
+msgstr "總下載次數"
+
+#: views/elements/amo2009/homepage_addon.thtml:106
+#: views/elements/addon_listitem.thtml:115 views/elements/feature.thtml:101
+#: views/addons/category_landing.thtml:157 views/addons/display.thtml:146
+#: views/addons/browse_thumbs.thtml:80
+msgid "addon_downloads_weekly"
+msgstr "本週下載次數"
+
+#. %1 is the add-on count, %2 the category name
+#: views/addons/browse_thumbs.thtml:104 views/addons/browse.thtml:60
+#, php-format
+msgid "addon_list_category_totalcount"
+msgid_plural "addon_list_category_totalcount"
+msgstr[0] "%1$s 個元件"
+
+#: views/elements/amo2009/addon_list_options.thtml:103
+#: views/elements/pagination.thtml:67
+#: views/elements/addon_list_options.thtml:94
+msgid "addon_list_perpage"
+msgstr "æ¯é é¡¯ç¤º"
+
+#: views/elements/amo2009/addon_list_options.thtml:84
+#: views/elements/addon_list_options.thtml:98
+msgid "addon_list_sortby"
+msgstr "排åºä¾ç…§ï¼š"
+
+#: views/helpers/addons_html.php:568 views/elements/amo2009/install.thtml:321
+#: views/elements/feature.thtml:89
+msgid "addon_listitem_flag_experimental"
+msgstr "實驗中"
+
+#: views/helpers/addons_html.php:570
+msgid "addon_listitem_flag_recommended"
+msgstr "推薦"
+
+#. %1 is the add-on name, %2 is the platform
+#: views/pages/js_constants.js.thtml:66
+msgid "addon_not_available_for_platform"
+msgstr "%1$s 無法在 %2$s 上使用。"
+
+#. %1 is the add-on name
+#: views/addons/policy.thtml:101 views/addons/previews.thtml:60
+#: views/addons/versions.thtml:130 views/reviews/flag.thtml:61
+#: views/reviews/add.thtml:114 views/reviews/display.thtml:216
+#: views/reviews/review_added.thtml:57
+#, php-format
+msgid "addon_review_a_back_to_addon_x"
+msgstr "回到 %1$s…"
+
+#. %1 is the add-on name
+#: views/reviews/flag.thtml:60 views/reviews/add.thtml:113
+#: views/reviews/review_added.thtml:56
+#, php-format
+msgid "addon_review_a_back_to_reviews"
+msgstr "回到æ„見列表…"
+
+#: views/reviews/add.thtml:85
+msgid "addon_review_add_rating_field"
+msgstr "評分:"
+
+#: views/reviews/add.thtml:102
+msgid "addon_review_add_review_field"
+msgstr "æ„見:"
+
+#: views/reviews/add.thtml:107
+msgid "addon_review_add_submit"
+msgstr "é€å‡ºæ„見"
+
+#. %s is the name of the add-on
+#: views/reviews/add.thtml:51
+#, php-format
+msgid "addon_review_add_title"
+msgstr "æ–°å¢žå° %s çš„æ„見"
+
+#: views/reviews/add.thtml:78
+msgid "addon_review_add_title_field"
+msgstr "主旨ï¼æ‘˜è¦ï¼š"
+
+#: views/reviews/display.thtml:77 views/reviews/display.thtml:161
+msgid "addon_review_admin_delete"
+msgstr "刪除"
+
+#: views/reviews/display.thtml:76
+msgid "addon_review_author_reply_link"
+msgstr "回覆"
+
+#: views/reviews/delete.thtml:62
+msgid "addon_review_confirm_delete"
+msgstr "您確定è¦åˆªé™¤æ­¤æ„見?"
+
+#: views/reviews/delete.thtml:63
+msgid "addon_review_confirm_no"
+msgstr "å¦"
+
+#: views/reviews/delete.thtml:64
+msgid "addon_review_confirm_yes"
+msgstr "是"
+
+#: views/reviews/delete.thtml:48
+msgid "addon_review_delete_header"
+msgstr "刪除æ„見"
+
+#: controllers/reviews_controller.php:449
+msgid "addon_review_deleted_successfully"
+msgstr "æ„見已æˆåŠŸåˆªé™¤ã€‚"
+
+#. %s is the name of the add-on
+#: views/reviews/add.thtml:51
+#, php-format
+msgid "addon_review_edit_title"
+msgstr "ç·¨è¼¯å° %s çš„æ„見"
+
+#. %1 is the count of characters entered as notes for the review flag reason.
+#: controllers/reviews_controller.php:539
+msgid "addon_review_flag_error_other_length"
+msgstr ""
+"回報此æ„見時發生錯誤:回報æ„見的註記文字長度é™åˆ¶åœ¨ 10 至 100 個字元;您的文字"
+"長度為 %1$s。"
+
+#. Removing an extra comma
+#: views/reviews/review_added.thtml:53
+msgid "addon_review_in_moderation"
+msgstr "請注æ„:您的æ„見會先經審核通éŽå¾Œæ‰æœƒé¡¯ç¤ºåœ¨ç¶²ç«™ä¸Šå…¬é–‹ã€‚"
+
+#: views/reviews/add.thtml:57
+msgid "addon_review_in_reply_to"
+msgstr "開發者回覆:"
+
+#. %1 is the review count, %2 is the nickname or full name of the user.
+#: views/reviews/display.thtml:131
+#, php-format
+msgid "addon_review_others_by_user"
+msgid_plural "addon_review_others_by_user"
+msgstr[0] "顯示由 %2$s å°æ­¤é™„加元件發出的 %1$s 篇æ„見。"
+
+#. %1 is the add-on name
+#: controllers/reviews_controller.php:201
+#: controllers/reviews_controller.php:250
+#: controllers/reviews_controller.php:345
+#: controllers/reviews_controller.php:424
+#, php-format
+msgid "addon_review_pagetitle"
+msgstr "å° %s çš„æ„見"
+
+#. %1 is the user, %2 is the (localized) date
+#: views/reviews/display.thtml:160
+#, php-format
+msgid "addon_review_reply_on_x_by_y"
+msgstr "回覆者:%1$s 日期:%2$s"
+
+#: views/reviews/display.thtml:157
+msgid "addon_review_reply_prefix"
+msgstr "開發者回覆:"
+
+#: views/reviews/review_added.thtml:51
+msgid "addon_review_saved_successfully"
+msgstr "您的æ„見已æˆåŠŸå„²å­˜ï¼Œæ„Ÿè¬ï¼"
+
+#: views/addons/display.thtml:354 views/reviews/display.thtml:72
+msgid "addon_reviewed_by_u_on_d"
+msgstr "作者:%1$s 日期:%2$s"
+
+#. %1 is the user, %2 is the (localized) date, %3 is the rating
+#: views/editors/reviews_queue.thtml:57 views/editors/reviews_queue.thtml:68
+#: views/reviews/add.thtml:63 views/reviews/delete.thtml:54
+#, php-format
+msgid "addon_reviewed_on_x_rated_y"
+msgstr "作者:%1$s 日期:%2$s(給 %3$s 分)"
+
+#: views/elements/amo2009/addon_version_detail.thtml:52
+#: views/elements/addon_version_detail.thtml:52
+msgid "addon_version_permalink"
+msgstr "到此版本的固定éˆçµ"
+
+#. %1 is the current Application name (e.g. Firefox)
+#. %2 is the Application's version number
+#: views/addons/versions.thtml:140
+msgid "addon_versions_getlatestversion"
+msgstr "此附加元件的最新版本與 %1$s %2$s 相容"
+
+#: views/addons/display.thtml:447
+msgid "addons_author_addons_submit"
+msgstr "è¡"
+
+#: views/elements/amo2009/homepage_addon.thtml:100
+#: views/elements/feature.thtml:95
+msgid "addons_author_tooltip"
+msgstr "檢視作者個人檔案"
+
+#. %1 is the name of the Application (eg. Firefox)
+#: controllers/addons_controller.php:1296
+msgid "addons_browse_all_themes_title"
+msgstr "ç€è¦½æ‰€æœ‰ä½ˆæ™¯ä¸»é¡Œ :: %1$s 附加元件"
+
+#. %s is the name of the category
+#: controllers/addons_controller.php:1016
+#, php-format
+msgid "addons_browse_browse_category"
+msgstr "ç€è¦½%s"
+
+#. %1 is the name of the theme category (eg. Modern)
+#. %2 is the name of the Application (eg. Firefox)
+#: controllers/addons_controller.php:664
+msgid "addons_browse_categories_header_theme"
+msgstr "ç€è¦½%1$s佈景主題 :: %2$s 附加元件"
+
+#: views/addons/display.thtml:249
+msgid "addons_display_a_license_what"
+msgstr "這是什麼?"
+
+#: views/reviews/display.thtml:222
+msgid "addons_display_add_review"
+msgstr "新增æ„見"
+
+#: views/addons/display.thtml:294
+msgid "addons_display_advanced_details"
+msgstr "詳細資訊"
+
+#: views/addons/display.thtml:98
+msgid "addons_display_categories"
+msgstr "分類"
+
+#: views/addons/display.thtml:482
+msgid "addons_display_collection_add"
+msgstr "加入到收è—集:"
+
+#: views/addons/display.thtml:491
+msgid "addons_display_collection_add_new"
+msgstr "新收è—集…"
+
+#: views/addons/display.thtml:487
+msgid "addons_display_collection_add_select_one"
+msgstr "é¸æ“‡ä¸€å€‹æ”¶è—集…"
+
+#: views/addons/display.thtml:493
+msgid "addons_display_collection_add_submit"
+msgstr "發表"
+
+#. %1$s is the add-on name
+#. %2$s is the collection name, linked to the collection's page
+#: views/pages/js_constants.js.thtml:103 views/addons/display.thtml:61
+msgid "addons_display_collection_publish_success"
+msgstr "已將 %1$s 加入 %2$s 收è—集。"
+
+#: views/addons/display.thtml:483
+msgid "addons_display_collection_whatsthis"
+msgstr "這是什麼?"
+
+#. %1$s is a number
+#: views/addons/display.thtml:473
+msgid "addons_display_collections_more"
+msgid_plural "addons_display_collections_more"
+msgstr[0] "與其他 %1$s 個收è—集"
+
+#: views/addons/display.thtml:403
+msgid "addons_display_detailed_review"
+msgstr "填寫詳細æ„見"
+
+#: views/reviews/add.thtml:89 views/reviews/add.thtml:90
+msgid "addons_display_dont_like_it"
+msgstr "ä¸å–œæ­¡"
+
+#: views/reviews/display.thtml:220
+msgid "addons_display_edit_review"
+msgstr "編輯您的æ„見"
+
+#: views/addons/display.thtml:132
+msgid "addons_display_has_privacy"
+msgstr "本元件有自己的隱ç§æ”¿ç­–。"
+
+#: views/reviews/add.thtml:87 views/reviews/add.thtml:88
+msgid "addons_display_hate_it"
+msgstr "討厭"
+
+#: views/addons/display.thtml:462
+msgid "addons_display_header_collections"
+msgstr "相關收è—集"
+
+#: views/addons/display.thtml:297
+msgid "addons_display_header_developer_comments"
+msgstr "開發者留言"
+
+#: views/addons/display.thtml:230
+msgid "addons_display_header_homepage"
+msgstr "網站首é "
+
+#: views/addons/display.thtml:247 views/addons/versions.thtml:110
+msgid "addons_display_header_license"
+msgstr "原始碼授權æ¢æ¬¾"
+
+#: views/addons/display.thtml:337
+msgid "addons_display_header_reviews"
+msgstr "æ„見"
+
+#: views/addons/display.thtml:261
+msgid "addons_display_header_support"
+msgstr "技術支æ´"
+
+#: views/reviews/add.thtml:91 views/reviews/add.thtml:92
+msgid "addons_display_like_it"
+msgstr "喜歡"
+
+#: views/addons/display.thtml:210
+msgid "addons_display_long_description"
+msgstr "完整敘述"
+
+#: views/reviews/add.thtml:95 views/reviews/add.thtml:96
+msgid "addons_display_love_it"
+msgstr "喜愛"
+
+#: views/addons/display.thtml:178
+msgid "addons_display_more_images"
+msgstr "更多圖片"
+
+#: views/addons/display.thtml:465
+msgid "addons_display_nocollections"
+msgstr "這個元件尚ä¸å±¬æ–¼ä»»ä½•æ”¶è—集。"
+
+#. %1$s is either an author's name or a comma separated list of authors. Using
+#. the list doesn't make sense in the English plural form so we ignore the
+#. variable.
+#: views/addons/display.thtml:436
+msgid "addons_display_other_addons_by"
+msgid_plural "addons_display_other_addons_by"
+msgstr[0] "%1$s 的其他作å“"
+
+#. %s is the name of the add-on and the add-on section. Example:
+#. Some Add-on :: Firefox Add-ons
+#. This should not be concatenated in the code and should be fixed.
+#: controllers/addons_controller.php:141 controllers/addons_controller.php:280
+#: controllers/addons_controller.php:1442
+#, php-format
+msgid "addons_display_pagetitle"
+msgstr "%s"
+
+#. %s is an email address
+#: views/addons/display.thtml:286
+#, php-format
+msgid "addons_display_paragraph_supportinfoemail"
+msgstr "此套件由作者於 %s æä¾› Email 技術支æ´"
+
+#. %$1s is a URL
+#. %$2s is an email address
+#: views/addons/display.thtml:269
+#, php-format
+msgid "addons_display_paragraph_supportinfoemailurl"
+msgstr "此元件的技術支æ´é€éŽé–‹ç™¼è€…在 %1$s ï¼Œæˆ–å¯„é€ Email 至 %2$s æä¾›"
+
+#. %s is a URL
+#: views/addons/display.thtml:278
+#, php-format
+msgid "addons_display_paragraph_supportinfourl"
+msgstr "此套件由作者於 %s æ供技術支æ´"
+
+#: views/addons/display.thtml:383
+msgid "addons_display_rate_it"
+msgstr "評分"
+
+#: views/reviews/add.thtml:93 views/reviews/add.thtml:94
+msgid "addons_display_really_like_it"
+msgstr "éžå¸¸å–œæ­¡"
+
+#: views/addons/display.thtml:410
+msgid "addons_display_review_etiquette"
+msgstr ""
+"請勿在此回報程å¼éŒ¯èª¤ã€‚因為我們並ä¸æœƒè¨˜éŒ„您的 Email 地å€ï¼Œè‹¥é–‹ç™¼è€…想得知進一步"
+"的細節以解決å•é¡Œæ™‚就無法與您è¯çµ¡äº†ã€‚"
+
+#. %1 is the review guidelines link
+#: views/addons/display.thtml:417
+msgid "addons_display_review_guidelines_link"
+msgstr "<a href=\"%s\">æ„見撰寫指å—</a>"
+
+#. %1 is the support section link
+#: views/addons/display.thtml:414
+msgid "addons_display_review_see_support"
+msgstr "請見 <a href=\"%1$s\">技術支æ´</a> 一節了解如何å–得此元件的進一步å”助。"
+
+#: views/addons/display.thtml:404
+msgid "addons_display_review_submit"
+msgstr "儲存"
+
+#: views/addons/display.thtml:430
+#, php-format
+msgid "addons_display_see_all_addons"
+msgstr "查看所有 %1$s 類元件"
+
+#. %1 is the number of reviews
+#: views/addons/display.thtml:364
+#, php-format
+msgid "addons_display_see_all_reviews"
+msgstr "查看所有æ„見 (%1$s)"
+
+#: views/addons/display.thtml:219
+msgid "addons_display_see_all_versions"
+msgstr "看看所有版本"
+
+#: views/addons/display.thtml:321 views/addons/versions.thtml:117
+msgid "addons_display_view_source"
+msgstr "檢視原始碼"
+
+#: views/addons/display.thtml:324
+msgid "addons_display_view_stats"
+msgstr "檢視統計資訊"
+
+#: views/addons/display.thtml:376
+msgid "addons_display_what_do_you_think"
+msgstr "留下您的æ„見?"
+
+#: views/elements/app_compatibility.thtml:49
+msgid "addons_display_workswith"
+msgstr "相容於:"
+
+#: views/addons/home.thtml:112
+msgid "addons_home_browse_new"
+msgstr "新加入"
+
+#: views/addons/home.thtml:110
+msgid "addons_home_browse_popular"
+msgstr "熱門"
+
+#: views/addons/home.thtml:108
+msgid "addons_home_browse_recommended"
+msgstr "推薦元件"
+
+#: views/addons/home.thtml:127 views/addons/home.thtml:134
+#: views/addons/home.thtml:141 views/addons/home.thtml:148
+msgid "addons_home_browse_subscribe"
+msgstr "訂閱"
+
+#: views/addons/home.thtml:101
+msgid "addons_home_browse_title"
+msgstr "ç€è¦½é™„加元件"
+
+#: views/addons/home.thtml:114
+msgid "addons_home_browse_updated"
+msgstr "已更新"
+
+#: views/elements/amo2009/homepage_addon.thtml:100
+#: views/elements/addon_discussionheader.thtml:83
+#: views/elements/addon_listitem.thtml:109 views/elements/feature.thtml:95
+#: views/addons/category_landing.thtml:66 views/addons/policy.thtml:57
+#: views/addons/display.thtml:70 views/addons/home.thtml:178
+msgid "addons_home_by"
+msgstr "作者:"
+
+#: views/addons/home.thtml:169
+msgid "addons_home_collection_popular_title"
+msgstr "熱門收è—集"
+
+#: views/elements/amo2009/categories.thtml:69 views/addons/home.thtml:160
+msgid "addons_home_collections"
+msgstr "收è—集"
+
+#. %1$s is the count of addons in a collection
+#: views/elements/amo2009/collection_listing_item.thtml:51
+#: views/addons/home.thtml:185
+msgid "addons_home_collections_addon_count"
+msgid_plural "addons_home_collections_addon_count"
+msgstr[0] "<strong>%1$s</strong> 個附加元件"
+
+#: views/addons/home.thtml:196
+msgid "addons_home_collections_all"
+msgstr "檢視所有收è—集"
+
+#: views/addons/home.thtml:162
+msgid "addons_home_collections_intro"
+msgstr ""
+"收è—集是讓您分類ã€çµ„åˆã€é…å°èˆ‡æ”ªå’Œé™„加元件的方å¼ã€‚您å¯ä»¥è¨‚閱其他使用者建立的收"
+"è—集,或自己建立一個。"
+
+#. %1$s is the count of subscribers for a collection
+#: views/elements/amo2009/collection_listing_item.thtml:58
+#: views/collections/detail.thtml:96 views/addons/home.thtml:189
+msgid "addons_home_collections_subscribers"
+msgid_plural "addons_home_collections_subscribers"
+msgstr[0] "<strong>%1$s</strong> ä½è¨‚閱者"
+
+#: views/addons/searchengines.thtml:54 views/addons/themes_landing.thtml:49
+msgid "addons_home_feature_head"
+msgstr "推薦元件"
+
+#: controllers/search_controller.php:218 controllers/addons_controller.php:176
+#: controllers/addons_controller.php:428 controllers/addons_controller.php:671
+#: controllers/addons_controller.php:871 controllers/addons_controller.php:1103
+#: controllers/addons_controller.php:1242
+#: controllers/addons_controller.php:1298
+#, php-format
+msgid "addons_home_header_details"
+msgstr ""
+"附加元件能擴充 %1$s 功能,打造您ç¨æ¨¹ä¸€æ ¼çš„ç€è¦½é«”驗。在這網站四處看看,來親手打"
+"造您專屬的 %1$s å§ï¼"
+
+#. %1$s is the HTML collection name link.
+#: views/elements/amo2009/teaser_collections.thtml:107
+msgid "addons_home_introduction_collection_link"
+msgstr "喜歡嗎?在 %1$s 收è—集尋找更多相關的附加元件å§ã€‚"
+
+#: views/elements/amo2009/teaser_collections.thtml:60
+msgid "addons_home_introduction_extras"
+msgstr ""
+"<strong>超éŽäº”åƒå€‹å…費的å°å·¥å…·</strong>,讓您自訂並擴充 Firefox 來滿足您的需"
+"求。"
+
+#: views/elements/amo2009/teaser_collections.thtml:55
+msgid "addons_home_introduction_header"
+msgstr "什麼是附加元件?"
+
+#: views/elements/amo2009/teaser_collections.thtml:72
+msgid "addons_home_introduction_install"
+msgstr "<strong>安è£å分簡單</strong>並隨時ä¿æŒæœ€æ–°ç‹€æ…‹ã€‚"
+
+#: views/elements/amo2009/teaser_collections.thtml:45
+msgid "addons_home_introduction_name"
+msgstr "介紹"
+
+#: views/elements/amo2009/teaser_collections.thtml:66
+msgid "addons_home_introduction_themes"
+msgstr "<strong>å”助您進行常見工作</strong>的工具列ã€ä½ˆæ™¯ä¸»é¡Œå’Œæœå°‹æ供者。"
+
+#: views/addons/home.thtml:161
+msgid "addons_home_new_indicator"
+msgstr "新登場ï¼"
+
+#: views/elements/app_chooser.thtml:48 views/layouts/amo2009.thtml:257
+msgid "addons_home_other_applications"
+msgstr "其他應用程å¼"
+
+#. %1$s is the application the user is browsing. Examples: Thunderbird, Firefox,
+#. Sunbird
+#: views/pages/collector_faq.thtml:49 views/pages/collector_firstrun.thtml:42
+#: views/pages/collector.thtml:46 views/pages/collector_features.thtml:54
+#: controllers/developers_controller.php:87
+#: controllers/compatibility_controller.php:72
+#: controllers/components/simple_acl.php:81 controllers/components/amo.php:607
+#: controllers/statistics_controller.php:60
+#: controllers/statistics_controller.php:240
+#: controllers/previews_controller.php:67 controllers/users_controller.php:90
+#: controllers/users_controller.php:223 controllers/users_controller.php:330
+#: controllers/users_controller.php:414 controllers/users_controller.php:708
+#: controllers/users_controller.php:723 controllers/reviews_controller.php:204
+#: controllers/reviews_controller.php:251
+#: controllers/reviews_controller.php:346
+#: controllers/reviews_controller.php:425 controllers/search_controller.php:185
+#: controllers/search_controller.php:297 controllers/search_controller.php:301
+#: controllers/addons_controller.php:147 controllers/addons_controller.php:280
+#: controllers/addons_controller.php:370 controllers/addons_controller.php:667
+#: controllers/addons_controller.php:874 controllers/addons_controller.php:1019
+#: controllers/addons_controller.php:1034
+#: controllers/addons_controller.php:1101
+#: controllers/addons_controller.php:1121
+#: controllers/addons_controller.php:1240
+#: controllers/addons_controller.php:1357
+#: controllers/addons_controller.php:1364
+#: controllers/addons_controller.php:1442
+#: controllers/addons_controller.php:1477
+#: controllers/addons_controller.php:1538
+#: controllers/addons_controller.php:1543 controllers/editors_controller.php:64
+#: controllers/pages_controller.php:132 controllers/groups_controller.php:65
+#: controllers/groups_controller.php:71 controllers/groups_controller.php:89
+#: controllers/groups_controller.php:111
+#: controllers/collections_controller.php:57
+#: controllers/collections_controller.php:121
+#: controllers/collections_controller.php:205
+#: controllers/collections_controller.php:365
+#: controllers/collections_controller.php:404
+#: controllers/collections_controller.php:466
+#: controllers/collections_controller.php:538
+#: controllers/collections_controller.php:828
+#: controllers/localizers_controller.php:72
+#, php-format
+msgid "addons_home_pagetitle"
+msgstr "%1$s 附加元件"
+
+#. %1$s is the number of addons downloaded
+#: views/addons/home.thtml:57
+#, php-format
+msgid "addons_home_stats_downloaded"
+msgid_plural "addons_home_stats_downloaded"
+msgstr[0] "<strong>%1$s</strong> <span>個元件已被下載</span>"
+
+#. %1$s is the number of addons in use
+#: views/addons/home.thtml:63
+#, php-format
+msgid "addons_home_stats_inuse"
+msgid_plural "addons_home_stats_inuse"
+msgstr[0] "<strong>%1$s</strong> <span>個元件使用中</span>"
+
+#: views/addons/home.thtml:136
+msgid "addons_home_view_all_newest_title"
+msgstr "檢視所有最新上傳元件"
+
+#: views/addons/home.thtml:129
+msgid "addons_home_view_all_popular_title"
+msgstr "檢視所有熱門元件"
+
+#: views/addons/home.thtml:150
+msgid "addons_home_view_all_recommended_title"
+msgstr "檢視所有推薦元件"
+
+#: views/addons/home.thtml:143
+msgid "addons_home_view_all_updated_title"
+msgstr "檢視所有最近更新元件"
+
+#: views/elements/amo2009/install.thtml:334 views/elements/install.thtml:112
+msgid "addons_install_in_sunbird"
+msgstr ""
+"<ol><li>下載並儲存檔案到您的硬碟裡。</li><li>æ–¼ Mozilla Sunbird 中é¸æ“‡ã€Œå·¥å…·ï¼ž"
+"附加元件ã€ã€‚</li><li>按「安è£ã€éˆ•ï¼Œæ‰¾åˆ°æ‚¨å‰›å‰›ä¸‹è¼‰å›žä¾†çš„檔案後按「確定ã€å³å¯ã€‚"
+"</li></ol>"
+
+#: views/elements/amo2009/install.thtml:333 views/elements/install.thtml:111
+msgid "addons_install_in_sunbird_title"
+msgstr "如何於 Sunbird 安è£é™„加元件"
+
+#: views/elements/amo2009/install.thtml:331 views/elements/install.thtml:106
+msgid "addons_install_in_thunderbird"
+msgstr ""
+"<ol><li>下載並儲存檔案到您的硬碟裡。</li><li>æ–¼ Mozilla Thunderbird 中é¸æ“‡ã€Œå·¥"
+"具>附加元件ã€ã€‚</li><li>按「安è£ã€éˆ•ï¼Œæ‰¾åˆ°æ‚¨å‰›å‰›ä¸‹è¼‰å›žä¾†çš„檔案後按「確定ã€å³"
+"å¯ã€‚</li></ol>"
+
+#: views/elements/amo2009/install.thtml:330 views/elements/install.thtml:105
+msgid "addons_install_in_thunderbird_title"
+msgstr "如何於 Thunderbird 安è£é™„加元件"
+
+#: views/elements/amo2009/addon_list_options.thtml:108
+#: views/elements/addon_list_options.thtml:105
+msgid "addons_options_show_experimental"
+msgstr "顯示實驗中元件"
+
+#: views/elements/amo2009/addon_list_options.thtml:113
+#: views/elements/addon_list_options.thtml:109
+msgid "addons_options_submit"
+msgstr "è¡"
+
+#: views/addons/plugins.thtml:63 views/addons/plugins.thtml:73
+#: views/addons/plugins.thtml:83 views/addons/plugins.thtml:93
+#: views/addons/plugins.thtml:103 views/addons/plugins.thtml:116
+#: views/addons/plugins.thtml:126
+msgid "addons_plugins_by"
+msgstr "作者:"
+
+#: views/addons/plugins.thtml:107
+msgid "addons_plugins_for_linux"
+msgstr "Linux 作業系統"
+
+#: views/addons/plugins.thtml:108 views/addons/plugins.thtml:131
+msgid "addons_plugins_for_macosx"
+msgstr "Mac OS X 作業系統"
+
+#: views/addons/plugins.thtml:106 views/addons/plugins.thtml:129
+#: views/addons/plugins.thtml:130
+msgid "addons_plugins_for_windows"
+msgstr "Windows 作業系統"
+
+#. %1$s is a URL
+#: views/addons/plugins.thtml:139
+#, php-format
+msgid "addons_plugins_looking_for_more"
+msgstr ""
+"本é é¢åªåˆ—出最常見和最æµè¡Œçš„外掛程å¼ã€‚若您想找其他 Mozilla 系列ç€è¦½å™¨å¯ç”¨çš„外"
+"掛程å¼ï¼Œè«‹å‰å¾€ %1$s"
+
+#: views/addons/plugins.thtml:137
+msgid "addons_plugins_looking_for_plugin"
+msgstr "想找的外掛程å¼ä¸åœ¨é€™è£¡ï¼Ÿ"
+
+#: views/addons/plugins.thtml:58
+msgid "addons_plugins_main_description"
+msgstr ""
+"外掛程å¼èƒ½è®“ç€è¦½å™¨é”到顯示特殊圖片格å¼ã€æ’­æ”¾å¤šåª’體檔案等功能。和擴充套件改變或"
+"加強已有的功能ä¸åŒï¼Œå¤–掛程å¼å¯è®“ç€è¦½å™¨æ”¯æ´å…¨æ–°çš„æ ¼å¼ã€‚"
+
+#. %1$s is the application name. Example: Firefox, Thunderbird, Sunbird
+#: controllers/addons_controller.php:1122
+#, php-format
+msgid "addons_plugins_main_header"
+msgstr "%1$s 常用外掛程å¼"
+
+#: controllers/components/amo.php:698 controllers/addons_controller.php:1121
+msgid "addons_plugins_pagetitle"
+msgstr "外掛程å¼"
+
+#: views/addons/plugins.thtml:68 views/addons/plugins.thtml:78
+#: views/addons/plugins.thtml:88 views/addons/plugins.thtml:98
+#: views/addons/plugins.thtml:110 views/addons/plugins.thtml:121
+#: views/addons/plugins.thtml:133
+msgid "addons_plugins_support_documentation"
+msgstr "說明文件:"
+
+#. %s is the name of the add-on
+#: views/addons/policy.thtml:61
+#, php-format
+msgid "addons_policy_eula_require"
+msgstr "%s 需è¦ä½ åœ¨å®‰è£å‰æŽ¥å—下é¢çš„「使用者授權åˆç´„ã€æ‰èƒ½ç¹¼çºŒï¼š"
+
+#. %1 is the add-on name
+#: controllers/addons_controller.php:1476
+#, php-format
+msgid "addons_previews_pagetitle"
+msgstr "%s çš„é è¦½åœ–片"
+
+#: views/addons/category_landing.thtml:135
+msgid "addons_recently_added"
+msgstr "最近新增"
+
+#: views/addons/recommended.thtml:51 controllers/addons_controller.php:1365
+msgid "addons_recommended_introduction"
+msgstr ""
+"這裡有æˆå †çš„附加元件,其中有些大家都該試試。您å¯ä»¥å¾žä¸‹åˆ—我們推薦的附加元件開始"
+"玩玩看ï¼"
+
+#: controllers/addons_controller.php:1357
+#: controllers/addons_controller.php:1364
+msgid "addons_recommended_pagetitle"
+msgstr "推薦附加元件"
+
+#: controllers/addons_controller.php:1360
+msgid "addons_recommended_title"
+msgstr "推薦附加元件"
+
+#: views/addons/searchengines.thtml:136
+msgid "addons_searchengines_additional_resources"
+msgstr "其他資æº"
+
+#. link text devmo
+#: views/addons/searchengines.thtml:141
+msgid "addons_searchengines_devmo_link"
+msgstr "Mozilla 開發者中心網站"
+
+#: views/pages/js_constants.js.thtml:67
+msgid "addons_searchengines_error_mozilla_browser_required"
+msgstr "æŠ±æ­‰ï¼Œæ‚¨éœ€è¦ Mozilla 系列的ç€è¦½å™¨ï¼ˆåƒ Firefox)æ‰èƒ½å®‰è£æ­¤æœå°‹å¼•æ“Žã€‚"
+
+#: views/addons/searchengines.thtml:49
+msgid "addons_searchengines_error_nojavascript"
+msgstr ""
+"安è£æœ¬æœå°‹å¼•æ“Žéœ€è¦ä½¿ç”¨ Javascript,但看起來您把它關掉了。請在安è£ä¸‹åˆ—æœå°‹å¼•æ“Ž"
+"之å‰å…ˆå•Ÿç”¨ Javascript。"
+
+#. %1 is "make your own" link
+#. %2 is MDC link
+#: views/addons/searchengines.thtml:139
+msgid "addons_searchengines_learn_howto"
+msgstr "到 %2$s 學習如何 %1$s。"
+
+#. link path to search plugins instructions, relative to devmo
+#: views/addons/searchengines.thtml:140
+msgid "addons_searchengines_makeyourown_href"
+msgstr ""
+"/zhtw/%E8%A3%BD%E4%BD%9C__OpenSearch_%E6%90%9C%E5%B0%8B%E6%A8%A1%E7%B5%84"
+
+#. link text for "make your own" (opensearch engine)
+#: views/addons/searchengines.thtml:140
+msgid "addons_searchengines_makeyourown_link"
+msgstr "製作æœå°‹å¼•æ“Ž"
+
+#. %1 is the link to mycroft.mozdev.org
+#: views/addons/searchengines.thtml:138
+msgid "addons_searchengines_more"
+msgstr "到 %1$s 尋找更多æœå°‹å¼•æ“Ž"
+
+#. link text to mycroft.mozdev.org
+#: views/addons/searchengines.thtml:138
+msgid "addons_searchengines_mycroft_link"
+msgstr "mycroft.mozdev.org"
+
+#: controllers/addons_controller.php:1100
+#: controllers/addons_controller.php:1110
+msgid "addons_searchengines_pagetitle"
+msgstr "æœå°‹å¼•æ“Ž"
+
+#: views/addons/searchengines.thtml:143
+msgid "addons_searchengines_thanks"
+msgstr "ç‰¹åˆ¥æ„Ÿè¬ Mycroft 專案於 Firefox æœå°‹å¼•æ“Žæ‰€åŠªåŠ›çš„æˆæžœã€‚"
+
+#: views/addons/display.thtml:154
+msgid "addons_share_button_text"
+msgstr "分享元件"
+
+#: controllers/addons_controller.php:89
+msgid "addons_share_label_delicious"
+msgstr "加到 Delicious"
+
+#: controllers/addons_controller.php:77
+msgid "addons_share_label_digg"
+msgstr "Digg 這個ï¼"
+
+#: controllers/addons_controller.php:83
+msgid "addons_share_label_facebook"
+msgstr "發佈到 Facebook"
+
+#: controllers/addons_controller.php:101
+msgid "addons_share_label_friendfeed"
+msgstr "在 FriendFeed 分享"
+
+#: controllers/addons_controller.php:95
+msgid "addons_share_label_myspace"
+msgstr "發佈到 MySpace"
+
+#: controllers/components/amo.php:201 controllers/components/amo.php:229
+msgid "addons_status_disabled"
+msgstr "å·²åœç”¨"
+
+#: controllers/components/amo.php:191 controllers/components/amo.php:224
+msgid "addons_status_incomplete"
+msgstr "未完æˆç‰ˆæœ¬"
+
+#: controllers/components/amo.php:197 controllers/components/amo.php:227
+msgid "addons_status_nominated"
+msgstr "在「沙箱ã€ï¼›å·²è¢«æå"
+
+#: views/pages/js_constants.js.thtml:80 controllers/components/amo.php:195
+#: controllers/components/amo.php:226
+msgid "addons_status_pending"
+msgstr "在「沙箱ã€ï¼›ç­‰å¾…審核"
+
+#: views/pages/js_constants.js.thtml:78 controllers/components/amo.php:199
+#: controllers/components/amo.php:228
+msgid "addons_status_public"
+msgstr "公開"
+
+#: views/pages/js_constants.js.thtml:79 controllers/components/amo.php:193
+#: controllers/components/amo.php:225
+msgid "addons_status_sandbox"
+msgstr "在「沙箱ã€"
+
+#: controllers/components/amo.php:203
+msgid "addons_status_unknown"
+msgstr "ä¸æ˜Ž"
+
+#: views/elements/amo2009/teaser_collections.thtml:91
+#: views/elements/amo2009/homepage_addon.thtml:99
+#: views/elements/feature.thtml:94
+msgid "addons_title_tooltip"
+msgstr "了解關於此元件的更多資訊"
+
+#: views/addons/category_landing.thtml:151
+msgid "addons_top_downloads"
+msgstr "下載排行"
+
+#: views/addons/category_landing.thtml:165
+msgid "addons_top_rated"
+msgstr "評分排行"
+
+#: views/addons/versions.thtml:62
+msgid "addons_versions_careful"
+msgstr "å°å¿ƒï¼é€™è£¡éƒ½æ˜¯èˆŠç‰ˆæœ¬"
+
+#: views/addons/versions.thtml:63
+msgid "addons_versions_careful_introduction"
+msgstr ""
+"這裡列出的舊版本僅供åƒè€ƒåŠæ¸¬è©¦ä¹‹ç”¨ã€‚若無特別需求,請安è£æœ€æ–°ç‰ˆçš„附加元件。"
+
+#: controllers/addons_controller.php:1549
+msgid "addons_versions_history"
+msgstr "版本歷å²è¨˜éŒ„"
+
+#. %1$s is the add-on name
+#: controllers/addons_controller.php:1535
+#, php-format
+msgid "addons_versions_pagetitle"
+msgstr "%1$s 版本記錄"
+
+#: controllers/groups_controller.php:71
+msgid "admin_group_add_pagetitle"
+msgstr "新增群組"
+
+#: controllers/groups_controller.php:111
+msgid "admin_group_delete_pagetitle"
+msgstr "刪除群組"
+
+#. %s is a number to identify the group
+#: controllers/groups_controller.php:117
+#, php-format
+msgid "admin_group_deleted"
+msgstr "ID %s 的群組已刪除"
+
+#: controllers/groups_controller.php:89
+msgid "admin_group_edit_pagetitle"
+msgstr "編輯群組"
+
+#: controllers/groups_controller.php:92 controllers/groups_controller.php:113
+msgid "admin_group_error_invalid_id"
+msgstr "無效的群組 ID"
+
+#: controllers/groups_controller.php:65
+msgid "admin_group_pagetitle"
+msgstr "群組管ç†å“¡"
+
+#: controllers/groups_controller.php:77 controllers/groups_controller.php:99
+msgid "admin_group_saved"
+msgstr "群組已儲存"
+
+#: views/elements/amo2009/search.thtml:257 views/elements/search.thtml:239
+msgid "advanced_search_form"
+msgstr "進階æœå°‹"
+
+#: views/elements/amo2009/search.thtml:126 views/elements/search.thtml:125
+msgid "advanced_search_form_any_time"
+msgstr "ä»»æ„時間"
+
+#: views/elements/amo2009/search.thtml:97
+#: views/elements/amo2009/search.thtml:110 views/elements/search.thtml:96
+#: views/elements/search.thtml:109
+msgid "advanced_search_form_any_type"
+msgstr "所有種類"
+
+#: views/elements/amo2009/search.thtml:275 views/elements/search.thtml:254
+msgid "advanced_search_form_any_version"
+msgstr "所有版本"
+
+#: views/elements/amo2009/search.thtml:217 views/elements/search.thtml:212
+msgid "advanced_search_form_application"
+msgstr "應用程å¼"
+
+#: views/elements/amo2009/search.thtml:143 views/elements/search.thtml:142
+msgid "advanced_search_form_keyword_match"
+msgstr "é—œéµå­—"
+
+#: views/elements/amo2009/search.thtml:251 views/elements/search.thtml:225
+msgid "advanced_search_form_lastupdate"
+msgstr "更新時間"
+
+#: views/elements/amo2009/search.thtml:145 views/elements/search.thtml:144
+msgid "advanced_search_form_name"
+msgstr "å稱"
+
+#: views/elements/amo2009/search.thtml:144 views/elements/search.thtml:143
+msgid "advanced_search_form_newest"
+msgstr "新舊"
+
+#: views/elements/amo2009/search.thtml:130 views/elements/search.thtml:129
+msgid "advanced_search_form_past_3_months"
+msgstr "最近 3 個月"
+
+#: views/elements/amo2009/search.thtml:131 views/elements/search.thtml:130
+msgid "advanced_search_form_past_6_months"
+msgstr "最近 6 個月"
+
+#: views/elements/amo2009/search.thtml:127 views/elements/search.thtml:126
+msgid "advanced_search_form_past_day"
+msgstr "昨天"
+
+#: views/elements/amo2009/search.thtml:129 views/elements/search.thtml:128
+msgid "advanced_search_form_past_month"
+msgstr "最近 1 個月"
+
+#: views/elements/amo2009/search.thtml:128 views/elements/search.thtml:127
+msgid "advanced_search_form_past_week"
+msgstr "最近 1 星期"
+
+#: views/elements/amo2009/search.thtml:132 views/elements/search.thtml:131
+msgid "advanced_search_form_past_year"
+msgstr "最近 1 年"
+
+#: views/elements/amo2009/search.thtml:239 views/elements/search.thtml:230
+msgid "advanced_search_form_perpage"
+msgstr "æ¯é é¡¯ç¤ºæ•¸é‡"
+
+#: views/elements/amo2009/search.thtml:243 views/elements/search.thtml:224
+msgid "advanced_search_form_platform"
+msgstr "作業系統"
+
+#: views/elements/amo2009/search.thtml:147 views/elements/search.thtml:146
+msgid "advanced_search_form_popularity"
+msgstr "熱門程度"
+
+#: views/elements/amo2009/search.thtml:146 views/elements/search.thtml:145
+msgid "advanced_search_form_rating"
+msgstr "評分"
+
+#: views/elements/amo2009/search.thtml:247 views/elements/search.thtml:231
+msgid "advanced_search_form_sortby"
+msgstr "排åºæ–¹å¼"
+
+#: views/elements/amo2009/search.thtml:227 views/elements/search.thtml:216
+msgid "advanced_search_form_to"
+msgstr "到"
+
+#: views/elements/amo2009/search.thtml:257 views/elements/search.thtml:237
+msgid "advanced_search_form_toggle_tooltip"
+msgstr "切æ›é€²éšŽæœå°‹åŠŸèƒ½"
+
+#: views/elements/amo2009/search.thtml:235 views/elements/search.thtml:223
+msgid "advanced_search_form_type"
+msgstr "種類"
+
+#: views/elements/amo2009/search.thtml:222 views/elements/search.thtml:214
+msgid "advanced_search_form_version"
+msgstr "版本從"
+
+#: views/elements/amo2009/pagination.thtml:42
+msgid "amo2009_pagination_next_page"
+msgstr "下一é "
+
+#: views/elements/amo2009/pagination.thtml:41
+msgid "amo2009_pagination_previous_page"
+msgstr "上一é "
+
+#: views/pages/js_constants.js.thtml:96
+msgid "app_compat_ignore_check"
+msgstr "忽略版本檢查"
+
+#: views/pages/js_constants.js.thtml:72
+msgid "app_compat_older_firefox_only"
+msgstr "此元件僅é©ç”¨æ–¼èˆŠç‰ˆçš„ Firefox"
+
+#. %1$s and %2$s are URLs
+#: views/pages/js_constants.js.thtml:74
+msgid "app_compat_older_version_or_ignore_check"
+msgstr ""
+"您å¯ä»¥<a href=\"%1$s\">安è£èˆŠç‰ˆæœ¬</a>或是<a href=\"#\" onclick=\"%2$s\">忽略此"
+"檢查</a>"
+
+#. %1$s is a URL
+#: views/pages/js_constants.js.thtml:71
+msgid "app_compat_try_old_version"
+msgstr "或安è£æ­¤å…ƒä»¶çš„ <a href=\"%1$s\">舊版本</a>"
+
+#. %1$s is a URL
+#. %2$s is a version number. Example: 3.1
+#: views/pages/js_constants.js.thtml:73
+msgid "app_compat_unreleased_version"
+msgstr "這個附加元件需è¦å°šæœªç™¼è¡Œçš„ <a href=\"%1$s\">Firefox %2$s</a>"
+
+#: views/pages/js_constants.js.thtml:70
+msgid "app_compat_update_firefox"
+msgstr "<a href=\"http://getfirefox.com\">å‡ç´š Firefox</a> æ‰èƒ½ä½¿ç”¨æ­¤å…ƒä»¶"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#. %3$s is a status, like Public.
+#: controllers/components/audit.php:79
+msgid "audit_addon_status"
+msgstr "%1$s å°‡ %2$s 的狀態改為「%3$sã€"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:221
+msgid "audit_admin_default"
+msgstr "%1$s å° ID %3$s æ交了未知的管ç†è¡Œå‹• %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:153
+msgid "audit_admin_feature_remove"
+msgstr "%1$s 移除了推薦 %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is an application, like Firefox.
+#: controllers/components/audit.php:92
+msgid "audit_application_create"
+msgstr "%1$s æ–°å¢žäº†æ‡‰ç”¨ç¨‹å¼ %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is an application, like Firefox.
+#: controllers/components/audit.php:95
+msgid "audit_application_edit"
+msgstr "%1$s ç·¨è¼¯äº†æ‡‰ç”¨ç¨‹å¼ %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a version number, like 3.5.
+#. %3$s is an application, like Firefox.
+#: controllers/components/audit.php:105
+msgid "audit_appversion_create"
+msgstr "%1$s 新增了 %3$s 的版本 %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a version number, like 3.5.
+#. %3$s is an application, like Firefox.
+#: controllers/components/audit.php:108
+msgid "audit_appversion_delete"
+msgstr "%1$s 刪除了 %3$s 的版本 %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a config field, like "awesomeness".
+#. %3$s is a config value, like "off".
+#. %4$s is a config value, like "on".
+#: controllers/components/audit.php:210
+msgid "audit_config"
+msgstr "%1$s 將設定 '%2$s' 由 '%3$s' 改為 '%4$s'"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:258
+msgid "audit_editor_default"
+msgstr "%1$s å° ID %3$s æ交了未知的審核行動 %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#: controllers/components/audit.php:236
+msgid "audit_editor_feature_remove"
+msgstr "%1$s 將附加元件 %2$s 由推薦清單中移除了"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#: controllers/components/audit.php:231
+msgid "audit_feature_add"
+msgstr "%1$s 將附加元件 %2$s 加入了推薦清單"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:149
+msgid "audit_feature_edit"
+msgstr "%1$s 修改了一個 %2$s 語言的推薦元件"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>addon name</a>
+#: controllers/components/audit.php:241
+msgid "audit_feature_locale_change"
+msgstr "%1$s 修改了推薦元件 %2$s 的語言"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:83
+msgid "audit_file_recalchash"
+msgstr "%1$s é‡æ–°è¨ˆç®—了檔案 %2$s 的雜湊值"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>user name</a>
+#. %3$s is <a>group name</a>
+#: controllers/components/audit.php:182
+msgid "audit_group_addmember"
+msgstr "%1$s 將 %2$s 加入了群組 %3$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:313
+msgid "audit_group_associated"
+msgstr "%1$s 將自己關è¯åˆ°ç¾¤çµ„ %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:162
+msgid "audit_group_create"
+msgstr "%1s 建立了群組 %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:170
+msgid "audit_group_delete"
+msgstr "%1$s 刪除了群組 %2$s(ID %3$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:165
+msgid "audit_group_edit"
+msgstr "%1$s 編輯了群組 %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>user name</a>
+#. %3$s is <a>group name</a>
+#: controllers/components/audit.php:188
+msgid "audit_group_removemember"
+msgstr "%1$s 將 %2$s 由群組 %3$s 中移除了"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:280
+msgid "audit_l10n_default"
+msgstr "%1$s å° %3$s æ交了未知的行動 %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>group name</a>
+#: controllers/components/audit.php:295
+msgid "audit_modify_locked_group"
+msgstr "%1$s 想è¦ä¿®æ”¹å·²éŽ–定的群組 %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:299
+msgid "audit_modify_other_locale"
+msgstr "%1$s 想è¦ä¿®æ”¹ %2$s 的翻譯,但沒有權é™"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a platform, like <a>Windows</a>
+#: controllers/components/audit.php:135
+msgid "audit_platform_create"
+msgstr "%1$s 新增了作業系統 %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a platform, like <a>Windows</a>
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:143
+msgid "audit_platform_delete"
+msgstr "%1$s 刪除了作業系統 %2$s(ID %3$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a platform, like <a>Windows</a>
+#: controllers/components/audit.php:138
+msgid "audit_platform_edit"
+msgstr "%1$s 編輯了作業系統 %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a part of the admin, like 'Site Config'
+#: controllers/components/audit.php:288
+msgid "audit_reauthentication_failure"
+msgstr "%1$s æ–¼å­˜å– %2$s 時,é‡æ–°èªè­‰å¤±æ•—。"
+
+#. %1$s is <a>user name</a>
+#. %2$s is the name of a canned response, like 'Ready for the public'
+#: controllers/components/audit.php:198
+msgid "audit_response_create"
+msgstr "%1$s æ–°å¢žäº†å›žè¦†è¨Šæ¯ %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is the name of a canned response, like 'Ready for the public'
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:206
+msgid "audit_response_delete"
+msgstr "%1$s åˆªé™¤äº†å›žè¦†è¨Šæ¯ %2$s(ID %3$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is the name of a canned response, like 'Ready for the public'
+#: controllers/components/audit.php:201
+msgid "audit_response_edit"
+msgstr "%1$s ç·¨è¼¯äº†å›žè¦†è¨Šæ¯ %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:245
+msgid "audit_review_approve"
+msgstr "%1$s 批准了審核 %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a numeric id.
+#: controllers/components/audit.php:250 controllers/components/audit.php:253
+msgid "audit_review_delete"
+msgstr "%1$s 刪除了審核 %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s an action string, but we don't know what it could be.
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:303
+msgid "audit_security_default"
+msgstr "%1$s å° ID %3$s æ交了未知的安全性行動 %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a category name, like <a>Search Tools</a>
+#: controllers/components/audit.php:118
+msgid "audit_tag_create"
+msgstr "%1$s 新增了分類 %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a category name, like <a>Search Tools</a>
+#. %3$s is a numeric id.
+#: controllers/components/audit.php:126
+msgid "audit_tag_delete"
+msgstr "%1$s 刪除了分類 %2$s(ID %3$s)"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a category name, like <a>Search Tools</a>
+#: controllers/components/audit.php:121
+msgid "audit_tag_edit"
+msgstr "%1$s 編輯了分類 %2$s"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:266
+msgid "audit_update_applications"
+msgstr "%1$s 更新了 %2$s 語言的應用程å¼ç¿»è­¯"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:277
+msgid "audit_update_blog"
+msgstr "%1$s 更新了 %2$s 語言的部è½æ ¼æ–‡ç« ç¿»è­¯"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:274
+msgid "audit_update_platforms"
+msgstr "%1$s 更新了 %2$s 語言的作業系統翻譯"
+
+#. %1$s is <a>user name</a>
+#. %2$s is a locale, like en-US.
+#: controllers/components/audit.php:270
+msgid "audit_update_tags"
+msgstr "%1$s 更新了 %2$s 語言的分類翻譯"
+
+#. %1$s is <a>user name</a>
+#. %2$s is <a>user name</a>
+#: controllers/components/audit.php:217
+msgid "audit_user_edit"
+msgstr "%1$s 編輯了 %2$s 的使用者資訊"
+
+#: controllers/addons_controller.php:1012
+msgid "browse_addons_name"
+msgstr "ä¾å稱排åº"
+
+#: controllers/addons_controller.php:1010
+msgid "browse_addons_newest"
+msgstr "最新元件"
+
+#: controllers/addons_controller.php:1008
+msgid "browse_addons_popular"
+msgstr "熱門元件"
+
+#: controllers/addons_controller.php:1011
+msgid "browse_addons_rated"
+msgstr "ä¾è©•åˆ†æŽ’åº"
+
+#: controllers/addons_controller.php:1009
+msgid "browse_addons_updated"
+msgstr "最近更新元件"
+
+#: views/elements/categories.thtml:73 views/elements/categories.thtml:82
+msgid "categories_current_title"
+msgstr "ç›®å‰åˆ†é¡ž"
+
+#: views/elements/categories.thtml:50
+#: views/elements/amo2009/categories.thtml:43
+#: views/elements/amo2009/categories.thtml:45
+msgid "categories_header"
+msgstr "分類"
+
+#: views/elements/categories.thtml:50
+#: views/elements/amo2009/categories.thtml:41
+msgid "categories_header_title"
+msgstr "è«‹é¸æ“‡åˆ†é¡ž"
+
+#. %1$s is the category name
+#: views/addons/searchengines.thtml:129
+#, php-format
+msgid "category_extra_see_all"
+msgstr "看看所有 %1$s 類元件"
+
+#. %1$s is a number.
+#: models/collection.php:130
+msgid "collection_description_limit"
+msgstr "敘述應少於 %1$s 個字元。"
+
+#. %1$s is the name of the collection
+#: controllers/collections_controller.php:392
+msgid "collection_detail_rss_title"
+msgstr "%s 收è—集"
+
+#: controllers/collections_controller.php:1065
+msgid "collection_error_deleting_addon"
+msgstr "元件刪除失敗ï¼"
+
+#: controllers/collections_controller.php:1051
+msgid "collection_error_saving_addon"
+msgstr "元件儲存失敗ï¼"
+
+#: controllers/collections_controller.php:1080
+msgid "collection_error_saving_comment"
+msgstr "æ„見儲存失敗ï¼"
+
+#. %1$s is a number.
+#: models/collection.php:122
+msgid "collection_name_limit"
+msgstr "å稱應少於 %1$s 個字元。"
+
+#: controllers/collections_controller.php:352
+#: controllers/collections_controller.php:487
+msgid "collection_not_found"
+msgstr "找ä¸åˆ°æ”¶è—集ï¼"
+
+#. %1$s is the text on the "create collection" button
+#: views/collections/add.thtml:91
+msgid "collections_add_formfield_addons_description"
+msgstr ""
+"如果您已經有一些想加入收è—集的元件,請在下é¢è¼¸å…¥å®ƒå€‘çš„å稱。如果您想ç¨å¾Œé€²è¡Œï¼Œ"
+"ç¾åœ¨è«‹æŒ‰ %1$s。"
+
+#: views/collections/add.thtml:90
+msgid "collections_add_formfield_firstaddons"
+msgstr "é¸æ“‡æ‚¨çš„第一個元件"
+
+#: views/collections/add.thtml:48
+msgid "collections_add_header"
+msgstr "建立收è—集"
+
+#: views/collections/add.thtml:97
+msgid "collections_add_header_selectedaddons"
+msgstr "é¸æ“‡é™„加元件"
+
+#: views/collections/add.thtml:50
+msgid "collections_add_intro"
+msgstr "填寫下列欄ä½ï¼Œå³å¯ç°¡å–®åœ°å»ºç«‹å±¬æ–¼æ‚¨çš„收è—集。"
+
+#: views/collections/add.thtml:92 views/collections/add.thtml:103
+msgid "collections_add_submit"
+msgstr "建立收è—集"
+
+#: views/pages/collector_faq.thtml:50 views/pages/collector_firstrun.thtml:43
+#: views/pages/collector.thtml:47 views/pages/collector_features.thtml:55
+#: controllers/search_controller.php:302
+#: controllers/collections_controller.php:206
+#: controllers/collections_controller.php:405
+#: controllers/collections_controller.php:467
+#: controllers/collections_controller.php:539
+msgid "collections_breadcrumb"
+msgstr "收è—集"
+
+#: views/collections/detail.thtml:185
+msgid "collections_detail_a_learn"
+msgstr "更多資訊"
+
+#: views/elements/amo2009/collection_add_form.thtml:53
+#: views/elements/amo2009/collections_js_init.thtml:68
+#: views/pages/collector_firstrun.thtml:64
+msgid "collections_detail_button_add"
+msgstr "加入到最愛"
+
+#: views/elements/amo2009/collection_add_form.thtml:50
+#: views/elements/amo2009/collections_js_init.thtml:71
+msgid "collections_detail_button_remove"
+msgstr "從最愛移除"
+
+#. %1$s is a URL.
+#. %2$s is a full <a href>.
+#: views/collections/detail.thtml:62
+msgid "collections_detail_created_desc"
+msgstr ""
+"<p>您å¯ä»¥åœ¨ä¸‹æ–¹æª¢è¦–您的收è—集。如果è¦è¨­ç½®æ”¶è—集暱稱ã€ä¸Šå‚³åœ–示,或修改更多設"
+"定,請造訪<a href='%1$s'>管ç†æ”¶è—集</a>é é¢ã€‚</p><p>您å¯ä»¥åœ¨é€™å€‹ç¶²å€å­˜å–您的收"
+"è—集:%2$s</p>"
+
+#: views/collections/detail.thtml:61
+msgid "collections_detail_created_msg"
+msgstr "您的收è—集已經準備就緒ï¼"
+
+#: views/collections/detail.thtml:109
+msgid "collections_detail_header_about"
+msgstr "關於這個收è—集"
+
+#. %1$s is a number.
+#: views/collections/detail.thtml:126
+msgid "collections_detail_header_count"
+msgid_plural "collections_detail_header_count"
+msgstr[0] "這個收è—集有 %1$s 個元件"
+
+#: views/collections/detail.thtml:113
+msgid "collections_detail_info_created"
+msgstr "<strong>建立者:</strong> %1$s"
+
+#: views/collections/detail.thtml:117
+msgid "collections_detail_info_updated"
+msgstr "<strong>更新時間:</strong>"
+
+#: views/elements/amo2009/collections_js_init.thtml:62
+msgid "collections_detail_js_adding"
+msgstr "加入到最愛中…"
+
+#: views/elements/amo2009/collections_js_init.thtml:65
+msgid "collections_detail_js_removing"
+msgstr "從最愛移除中…"
+
+#. %1$s is a URL
+#: views/collections/detail.thtml:90
+msgid "collections_detail_login"
+msgstr "<a href=\"%1$s\">登入</a>後方å¯åŠ å…¥é€™å€‹æ”¶è—集到最愛。"
+
+#: views/collections/detail.thtml:104
+msgid "collections_detail_manage"
+msgstr "管ç†æ”¶è—集"
+
+#: controllers/collections_controller.php:298
+msgid "collections_detail_sort_date"
+msgstr "新增日期"
+
+#: controllers/collections_controller.php:299
+msgid "collections_detail_sort_name"
+msgstr "å稱"
+
+#: controllers/collections_controller.php:300
+msgid "collections_detail_sort_popularity"
+msgstr "熱門程度"
+
+#. %1$s is a number.
+#: views/collections/detail.thtml:166
+msgid "collections_detail_weekly_downloads"
+msgid_plural "collections_detail_weekly_downloads"
+msgstr[0] "本週有 %1$s 次下載"
+
+#: views/collections/edit.thtml:255
+msgid "collections_edit_addons_delete_noscript"
+msgstr "é¸æ“‡çš„元件將在儲存時被移除"
+
+#: views/collections/edit.thtml:247
+msgid "collections_edit_addons_description"
+msgstr "è¦åœ¨æ”¶è—集發表新的元件,請在下é¢è¼¸å…¥å®ƒå€‘çš„å稱。"
+
+#: views/collections/edit.thtml:248
+msgid "collections_edit_addons_description_noscript"
+msgstr "è¦åœ¨æ”¶è—集發表新的元件,請在下é¢è¼¸å…¥å®ƒå€‘的元件 ID,以逗號分隔æ¯å€‹é …目。"
+
+#: views/collections/edit.thtml:247 views/collections/edit.thtml:248
+msgid "collections_edit_addons_description_publish_detailspage"
+msgstr "您也å¯ä»¥åœ¨å„元件的顯示é é¢ç™¼è¡¨å®ƒå€‘。"
+
+#. %1$s is the date the add-on was added to the collection
+#. %1$s is the name of the user who added the add-on to the collection
+#: views/collections/edit.thtml:260
+msgid "collections_edit_addons_listitem_added"
+msgstr "%2$s 於 %1$s 新增"
+
+#: views/collections/edit.thtml:263
+msgid "collections_edit_addons_listitem_comment_add"
+msgstr "新增發佈者æ„見"
+
+#: views/collections/edit.thtml:266
+msgid "collections_edit_addons_listitem_comment_delete"
+msgstr "刪除發佈者æ„見"
+
+#: views/collections/edit.thtml:265
+msgid "collections_edit_addons_listitem_comment_edit"
+msgstr "編輯發佈者æ„見"
+
+#: views/collections/edit.thtml:271
+msgid "collections_edit_addons_listitem_comment_note"
+msgstr "注æ„:æ„見顯示將包å«åŽŸç™¼è¡¨è€…與原發表日期"
+
+#: views/collections/edit.thtml:270
+msgid "collections_edit_addons_listitem_comment_submit"
+msgstr "儲存æ„見"
+
+#: views/collections/edit.thtml:261
+msgid "collections_edit_addons_listitem_remove"
+msgstr "移除"
+
+#: views/collections/edit.thtml:250
+msgid "collections_edit_addons_submit"
+msgstr "加入收è—集"
+
+#: views/collections/edit.thtml:153
+msgid "collections_edit_check_nickname"
+msgstr "檢查是å¦å¯ç”¨"
+
+#: views/collections/edit.thtml:299
+msgid "collections_edit_confirm_deletecollection"
+msgstr "是的,我è¦åˆªé™¤é€™å€‹æ”¶è—集。"
+
+#. %1$s is the label of the edit form's submit button
+#: views/collections/edit.thtml:300
+msgid "collections_edit_confirm_deletecollection_description"
+msgstr "勾é¸æ­¤æ–¹å¡Šï¼Œç„¶å¾ŒæŒ‰ä¸‹ã€Œ%1$sã€åˆªé™¤é€™å€‹æ”¶è—集。"
+
+#. %1$s is the "delete" submit button text
+#. %2$s is the title of the "advanced" tab
+#: views/collections/edit.thtml:95
+msgid "collections_edit_delete_upon_submit"
+msgstr ""
+"由於勾é¸äº†ä¸‹é¢çš„「%1$sã€ï¼Œæ‚¨çš„收è—集將被刪除。如果您ä¸æƒ³åˆªé™¤å®ƒï¼Œè«‹å–消勾é¸ã€Œ%2"
+"$sã€é ç±¤ä¸­çš„確èªæ–¹å¡Šï¼Œç„¶å¾Œç¹¼çºŒç·¨è¼¯æ”¶è—集。如果您未儲存就離開此é é¢ï¼Œæ”¶è—集亦ä¸"
+"會被刪除。"
+
+#: views/collections/edit.thtml:94
+msgid "collections_edit_delete_warning"
+msgstr "您的收è—集將被刪除ï¼"
+
+#: views/collections/add.thtml:76 views/collections/edit.thtml:144
+msgid "collections_edit_form_error_description"
+msgstr "您必須為收è—集æ供敘述。"
+
+#: views/collections/edit.thtml:181
+msgid "collections_edit_form_error_icon"
+msgstr "上傳圖示時發生錯誤。"
+
+#: views/collections/add.thtml:69 views/collections/edit.thtml:130
+msgid "collections_edit_form_error_name"
+msgstr "您必須給收è—集一個å字。"
+
+#: views/collections/edit.thtml:158
+msgid "collections_edit_form_error_nickname"
+msgstr "您é¸æ“‡çš„暱稱必須是沒有被用éŽçš„。"
+
+#: views/collections/add.thtml:93 views/collections/edit.thtml:249
+msgid "collections_edit_formfield_addons"
+msgstr "元件å稱:"
+
+#: views/collections/edit.thtml:281
+msgid "collections_edit_formfield_application"
+msgstr "é—œè¯æ‡‰ç”¨ç¨‹å¼"
+
+#: views/collections/edit.thtml:282
+msgid "collections_edit_formfield_application_description"
+msgstr "é¸æ“‡æ‚¨æ”¶è—集支æ´çš„應用程å¼ã€‚"
+
+#: views/collections/edit.thtml:288
+msgid "collections_edit_formfield_collectiontype"
+msgstr "收è—集類型"
+
+#: views/collections/edit.thtml:295
+msgid "collections_edit_formfield_deletecollection"
+msgstr "刪除收è—集"
+
+#: views/collections/edit.thtml:296
+msgid "collections_edit_formfield_deletecollection_description"
+msgstr "刪除您的收è—集將會永久地消除它。"
+
+#: views/collections/add.thtml:73 views/collections/edit.thtml:140
+msgid "collections_edit_formfield_description"
+msgstr "收è—集敘述"
+
+#: views/collections/add.thtml:74 views/collections/edit.thtml:141
+msgid "collections_edit_formfield_description_description"
+msgstr "簡短æ述您的收è—集,以åŠå®ƒæ”¶è—哪種類型的元件"
+
+#: views/collections/edit.thtml:162
+msgid "collections_edit_formfield_icon"
+msgstr "圖示"
+
+#: views/collections/edit.thtml:163
+msgid "collections_edit_formfield_icon_description"
+msgstr "您å¯ä»¥ä¸Šå‚³ JPGã€GIF 或 PNG 圖示,圖示會被縮放為 32x32 åƒç´ ã€‚"
+
+#: views/collections/add.thtml:80 views/collections/edit.thtml:189
+msgid "collections_edit_formfield_listed"
+msgstr "誰å¯ä»¥æª¢è¦–您的收è—集?"
+
+#: views/collections/add.thtml:81 views/collections/edit.thtml:190
+msgid "collections_edit_formfield_listed_description"
+msgstr ""
+"é è¨­æƒ…形下,收è—集會出ç¾åœ¨å…¬é–‹ä¸”æ¯å€‹äººéƒ½èƒ½æ‰¾åˆ°çš„「收è—集目錄ã€ä¸­ã€‚如果您想é™åˆ¶"
+"åªè®“知é“特殊éˆçµçš„人看見您的收è—集,請在下方é¸æ“‡è©²é¸é …。"
+
+#: views/collections/add.thtml:84 views/collections/edit.thtml:193
+msgid "collections_edit_formfield_listed_false"
+msgstr "åªæœ‰æˆ‘邀請的人能檢視我的收è—集"
+
+#: views/collections/add.thtml:83 views/collections/edit.thtml:192
+msgid "collections_edit_formfield_listed_true"
+msgstr "所有人å‡å¯åœ¨ç›®éŒ„檢視我的收è—集"
+
+#: views/collections/edit.thtml:223
+msgid "collections_edit_formfield_managers"
+msgstr "誰å¯ä»¥ç®¡ç†æˆ‘的收è—集?"
+
+#: views/collections/edit.thtml:224
+msgid "collections_edit_formfield_managers_description"
+msgstr ""
+"這些使用者å¯ä»¥ç™¼è¡¨é™„加元件至您的收è—集ã€ç®¡ç†æ‰€æœ‰å…ƒä»¶å’Œè¨­å®šã€ä»¥åŠçµ¦äºˆå…¶ä»–使用者"
+"權é™ã€‚"
+
+#: views/collections/add.thtml:66 views/collections/edit.thtml:126
+msgid "collections_edit_formfield_name"
+msgstr "收è—集å稱"
+
+#: views/collections/add.thtml:67 views/collections/edit.thtml:127
+msgid "collections_edit_formfield_name_description"
+msgstr "請替您的收è—集å–一個敘述性的å稱,例如「å°æ˜Žæœ€æ„›çš„旅行相關元件ã€ã€‚"
+
+#: views/collections/edit.thtml:148
+msgid "collections_edit_formfield_nickname"
+msgstr "收è—庫暱稱"
+
+#: views/collections/edit.thtml:149
+msgid "collections_edit_formfield_nickname_description"
+msgstr "給收è—集一個ç¨ç‰¹çš„暱稱,方便快速存å–(å¯ä¸æ供):"
+
+#: views/collections/edit.thtml:201
+msgid "collections_edit_formfield_publishers"
+msgstr "誰å¯ä»¥ç™¼è¡¨é™„加元件至您的收è—集?"
+
+#: views/collections/edit.thtml:202
+msgid "collections_edit_formfield_publishers_description"
+msgstr "這些使用者å¯ä»¥ç™¼è¡¨é™„加元件至您的收è—集,或移除他們所發表的元件。"
+
+#: views/collections/edit.thtml:210 views/collections/edit.thtml:232
+msgid "collections_edit_formfield_users_add"
+msgstr "輸入 Firefox 附加元件網站帳號的 Email 地å€ï¼š"
+
+#: views/collections/edit.thtml:216 views/collections/edit.thtml:238
+msgid "collections_edit_formfield_users_delete_noscript"
+msgstr "é¸æ“‡çš„帳號將在儲存時被移除"
+
+#: views/collections/edit.thtml:215 views/collections/edit.thtml:237
+msgid "collections_edit_formfield_users_new_noscript"
+msgstr "輸入 Firefox 附加元件網站帳號的 Email 地å€ï¼Œä»¥é€—號分隔å„個項目"
+
+#: views/collections/edit.thtml:204 views/collections/edit.thtml:226
+msgid "collections_edit_formfield_users_onlyme"
+msgstr "åªæœ‰æˆ‘"
+
+#: views/collections/edit.thtml:205 views/collections/edit.thtml:227
+msgid "collections_edit_formfield_users_otherusers"
+msgstr "我自己和這些使用者:"
+
+#: views/collections/edit.thtml:211 views/collections/edit.thtml:233
+msgid "collections_edit_formfield_users_submit"
+msgstr "新增"
+
+#. %1$s is the name of the collection
+#: views/collections/edit.thtml:68
+msgid "collections_edit_header"
+msgstr "ç®¡ç† %1$s"
+
+#: views/collections/edit.thtml:246
+msgid "collections_edit_header_addons"
+msgstr "管ç†æ”¶è—集內容"
+
+#: views/collections/edit.thtml:253 views/collections/edit.thtml:258
+msgid "collections_edit_header_addons_current"
+msgstr "ç›®å‰çš„附加元件:"
+
+#: views/collections/edit.thtml:279
+msgid "collections_edit_header_advanced"
+msgstr "進階設定"
+
+#: views/collections/edit.thtml:186
+msgid "collections_edit_header_permissions"
+msgstr "管ç†æ”¶è—集權é™"
+
+#: views/collections/edit.thtml:170
+msgid "collections_edit_icon_cancel"
+msgstr "å–消"
+
+#: views/collections/edit.thtml:174 views/collections/edit.thtml:179
+msgid "collections_edit_icon_delete"
+msgstr "刪除圖示"
+
+#: views/collections/edit.thtml:178
+msgid "collections_edit_icon_replace"
+msgstr "å–代圖示"
+
+#. %1$s is the label of the edit form's submit button
+#: views/collections/edit.thtml:169
+msgid "collections_edit_icon_toberemoved"
+msgstr "點é¸ä¸‹é¢çš„「%1$sã€å¾Œï¼Œåœ–示將被移除"
+
+#: views/collections/edit.thtml:155
+msgid "collections_edit_nickname_available"
+msgstr "å¯ç”¨çš„暱稱"
+
+#: controllers/collections_controller.php:943
+msgid "collections_edit_nickname_error"
+msgstr "您的暱稱包å«ç„¡æ•ˆå­—元,已被修正。請å†è©¦ä¸€æ¬¡ã€‚"
+
+#: views/collections/edit.thtml:156
+msgid "collections_edit_nickname_taken"
+msgstr "å·²å–用暱稱"
+
+#. This string is followed by a URL pointing to the collection's view page
+#: views/collections/edit.thtml:75
+msgid "collections_edit_saved_nextstep"
+msgstr "å¯ä»¥åœ¨é€™å€‹ç¶²å€å­˜å–您的收è—集:"
+
+#: views/collections/edit.thtml:74
+msgid "collections_edit_saved_success"
+msgstr "å·²æˆåŠŸå„²å­˜æ‚¨çš„收è—集ï¼"
+
+#: views/collections/edit.thtml:169 views/collections/edit.thtml:300
+#: views/collections/edit.thtml:308 views/pages/js_constants.js.thtml:99
+msgid "collections_edit_submit"
+msgstr "更新收è—集"
+
+#: views/collections/edit.thtml:96 views/collections/edit.thtml:297
+#: views/pages/js_constants.js.thtml:100
+msgid "collections_edit_submit_deletecollection"
+msgstr "刪除收è—集"
+
+#: views/collections/edit.thtml:111
+msgid "collections_edit_tabheader_addons"
+msgstr "附加元件"
+
+#: views/collections/edit.thtml:97 views/collections/edit.thtml:113
+msgid "collections_edit_tabheader_advanced"
+msgstr "進階"
+
+#: views/collections/edit.thtml:108
+msgid "collections_edit_tabheader_details"
+msgstr "å稱 &amp; 細節"
+
+#: views/collections/edit.thtml:109
+msgid "collections_edit_tabheader_permissions"
+msgstr "權é™"
+
+#: models/collection_promo.php:53
+msgid "collections_family_tagline"
+msgstr "關照您的å°å­©å’Œæ‚¨çš„行事曆"
+
+#: models/collection_promo.php:53
+msgid "collections_family_title"
+msgstr "家庭"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:70
+msgid "collections_index_a_check_out"
+msgstr "試試 Add-on Collector"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:52
+msgid "collections_index_a_create"
+msgstr "建立收è—集"
+
+#: views/collections/detail.thtml:139 views/collections/listing.thtml:85
+#: views/search/collections.thtml:84
+msgid "collections_index_button_go"
+msgstr "è¡"
+
+#. %1$s is a URL.
+#: controllers/collections_controller.php:182
+msgid "collections_index_filler_favorites"
+msgstr ""
+"<p><strong>您還沒有最愛的收è—集。</strong></p> <p>這個é é¢å¯ä»¥å¿«é€Ÿå­˜å–您標記為"
+"最愛的收è—集,若您安è£äº† <a href='%1$s'>Add-on Collector</a>,它們也會出ç¾åœ¨é‚£"
+"裡。</p>"
+
+#. %1$s is a URL.
+#: controllers/collections_controller.php:167
+msgid "collections_index_filler_mine"
+msgstr ""
+"<p>您尚未建立任何收è—集。簡單地將喜愛的附加元件新增並加入收è—集å³å¯ï¼Œ<a "
+"href='%1$s'>試試看å§</a>ï¼</p>"
+
+#: views/collections/listing.thtml:51
+msgid "collections_index_header_collections"
+msgstr "收è—集"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:60
+msgid "collections_index_header_collector"
+msgstr "Add-on Collector"
+
+#. %1$s is a comma-separated list of author names
+#: views/elements/amo2009/collection_listing_item.thtml:84
+#: views/collections/detail.thtml:151
+msgid "collections_index_header_created"
+msgstr "由 %1$s 建立"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:47
+msgid "collections_index_header_what"
+msgstr "什麼是收è—集?"
+
+#: views/collections/detail.thtml:132 views/collections/listing.thtml:78
+#: views/search/collections.thtml:66
+msgid "collections_index_label_sortby"
+msgstr "排åºæ–¹å¼"
+
+#: controllers/collections_controller.php:130
+msgid "collections_index_li_editors"
+msgstr "編輯精é¸"
+
+#: views/collections/subscribe.thtml:64
+#: controllers/collections_controller.php:140
+msgid "collections_index_li_favorites"
+msgstr "我的最愛"
+
+#: controllers/collections_controller.php:138
+msgid "collections_index_li_mine"
+msgstr "我的收è—集"
+
+#: controllers/collections_controller.php:132
+msgid "collections_index_li_popular"
+msgstr "熱門"
+
+#: views/search/collections.thtml:74 controllers/collections_controller.php:81
+msgid "collections_index_option_all"
+msgstr "所有時間最熱門"
+
+#: views/search/collections.thtml:72 controllers/collections_controller.php:78
+msgid "collections_index_option_month"
+msgstr "本月最熱門"
+
+#: views/search/collections.thtml:76 controllers/collections_controller.php:84
+msgid "collections_index_option_newest"
+msgstr "新舊"
+
+#: views/search/collections.thtml:70 controllers/collections_controller.php:75
+msgid "collections_index_option_week"
+msgstr "本週最熱門"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:67
+msgid "collections_index_p_collector"
+msgstr ""
+"ç¾åœ¨æœ‰å…¨æ–°çš„æ–¹å¼å¯ä»¥ç®¡ç†å’Œå°‹æ‰¾æ‚¨å–œæ„›çš„附加元件:在您的ç€è¦½å™¨è£¡é ­ç›´æŽ¥è©•è«–ã€åˆ†äº«"
+"å’ŒåŒæ­¥æ”¶è—集"
+
+#: views/elements/amo2009/collector_info_secondary.thtml:48
+msgid "collections_index_p_what_are"
+msgstr "收è—集是將相關的附加元件集çµèµ·ä¾†ï¼Œä»¥æ–¹ä¾¿åˆ†äº«çš„群集。"
+
+#. %s is a date in the _('date') format
+#: views/elements/collections_interactive_addon.thtml:85
+#, php-format
+msgid "collections_interactive_addon_added"
+msgstr "已新增 %s"
+
+#: models/collection_promo.php:55
+msgid "collections_reference_tagline"
+msgstr "在線上研究任何æ±è¥¿"
+
+#: models/collection_promo.php:55
+msgid "collections_reference_title"
+msgstr "åƒè€ƒè³‡æº"
+
+#: models/collection_promo.php:52
+msgid "collections_social_tagline"
+msgstr "管ç†æ‚¨çš„社交網路"
+
+#: models/collection_promo.php:52
+msgid "collections_social_title"
+msgstr "社交"
+
+#: views/collections/subscribe.thtml:91
+msgid "collections_subscribe_button_close"
+msgstr "關閉"
+
+#: views/collections/subscribe.thtml:70
+msgid "collections_subscribe_error"
+msgstr "嘗試加入到最愛收è—集時發生錯誤。這個收è—集已經是您的最愛嗎?"
+
+#: views/collections/subscribe.thtml:96
+msgid "collections_subscribe_label_bothersome"
+msgstr "ä¸å†é¡¯ç¤ºæ­¤è¨Šæ¯ã€‚"
+
+#. %1$s is the collection name
+#: views/collections/subscribe.thtml:60
+msgid "collections_subscribe_success"
+msgstr "已將 %1$s 加入您的最愛收è—集。"
+
+#. %1$s is the link to the "My Favorites" tab on the main collections page
+#. %2$s is the localized title of the "My Favorites" tab
+#. %3$s is the link URL to the collector add-on
+#: views/collections/subscribe.thtml:62
+msgid "collections_subscribe_success_desc"
+msgstr ""
+"您ç¾åœ¨å¯ä»¥å¾žç›®éŒ„下的<a href=\"%1$s\">%2$s</a>é ç±¤å¿«é€Ÿæ‰¾åˆ°é€™å€‹æ”¶è—集。é€éŽæˆ‘們"
+"用於 Firefox 的擴充套件 <a href=\"%3$s\">Add-on Collector</a>,以更簡單的方å¼"
+"追蹤您最愛的收è—集。"
+
+#: views/collections/listing.thtml:55
+msgid "collections_success_delete"
+msgstr "收è—集已經被刪除。"
+
+#: models/collection_promo.php:54
+msgid "collections_travel_tagline"
+msgstr "計劃商業旅行和難忘å‡æœŸ"
+
+#: models/collection_promo.php:54
+msgid "collections_travel_title"
+msgstr "æ—…éŠ"
+
+#. A collection of add-ons that is automatically built for a user. They are "automatically published" to this collection.
+#: controllers/collections_controller.php:581
+msgid "collections_type_autopublisher"
+msgstr "自動發表"
+
+#. A collection that has been chosen by an Editor as notable or exceptional
+#: controllers/collections_controller.php:582
+msgid "collections_type_editorspick"
+msgstr "編輯精é¸"
+
+#: controllers/collections_controller.php:580
+msgid "collections_type_normal"
+msgstr "標準"
+
+#: views/collections/subscribe.thtml:84
+msgid "collections_unsubscribe_error"
+msgstr "嘗試移除最愛收è—集時發生錯誤。這個收è—集ä¸æ›¾æ˜¯æ‚¨çš„最愛嗎?"
+
+#. %1$s is the collection name
+#: views/collections/subscribe.thtml:78
+msgid "collections_unsubscribe_success"
+msgstr "%1$s 已經從您的最愛收è—集中移除。"
+
+#: models/collection_promo.php:56
+msgid "collections_webdev_tagline"
+msgstr "建立完美的網站"
+
+#: models/collection_promo.php:56
+msgid "collections_webdev_title"
+msgstr "網é é–‹ç™¼"
+
+#: views/elements/amo2009/collections_sidebar_whatare.thtml:40
+msgid "collections_whatare_header"
+msgstr "什麼是收è—集?"
+
+#: views/elements/amo2009/collections_sidebar_whatare.thtml:45
+msgid "collections_whatare_learnmore"
+msgstr "閱讀常見å•é¡Œé›†"
+
+#: views/elements/amo2009/collections_sidebar_whatare.thtml:44
+msgid "collections_whatare_text"
+msgstr ""
+"ç¾åœ¨æœ‰å…¨æ–°çš„æ–¹å¼å¯ä»¥ç®¡ç†å’Œå°‹æ‰¾æ‚¨å–œæ„›çš„附加元件:在您的ç€è¦½å™¨è£¡é ­ç›´æŽ¥è©•è«–ã€åˆ†äº«"
+"å’ŒåŒæ­¥æ”¶è—集。"
+
+#: views/pages/collector_faq.thtml:61 views/pages/collector_features.thtml:67
+msgid "collector_features_a_home"
+msgstr "Add-on Collector 首é "
+
+#: views/elements/amo2009/collector_sidebar_download.thtml:46
+msgid "collector_features_heading_download"
+msgstr "下載 Add-on Collector:"
+
+#: views/elements/amo2009/collector_sidebar_download.thtml:43
+#: views/pages/collector_firstrun.thtml:116 views/pages/collector.thtml:69
+msgid "collector_features_img_logo"
+msgstr "Add-on Collector Logo"
+
+#: views/compatibility/dashboard.thtml:49
+#: controllers/compatibility_controller.php:72
+msgid "compatibility_dashboard_center_header"
+msgstr "附加元件相容性中心"
+
+#. %1$s is the name of an application and a version. Example: Firefox 3.0
+#. %2$s is the name of an application. Example: Firefox
+#: views/compatibility/dashboard.thtml:50
+msgid "compatibility_dashboard_intro"
+msgstr ""
+"使用以下æ供給 %2$s 附加元件開發社群的工具與資訊,é å…ˆæº–備版本 %1$s 的推出。"
+
+#: views/compatibility/dashboard.thtml:103
+msgid "compatibility_dashboard_loading"
+msgstr "資料載入中…"
+
+#: views/compatibility/dashboard.thtml:45
+msgid "compatibility_dashboard_main_link"
+msgstr "回到主é é¢"
+
+#: views/compatibility/dashboard.thtml:100 views/compatibility/report.thtml:43
+msgid "compatibility_dashboard_report"
+msgstr "附加元件相容性報告"
+
+#: views/compatibility/dashboard.thtml:53
+#: views/compatibility/dashboard.thtml:110
+#: views/compatibility/developers.thtml:43
+msgid "compatibility_developer_info"
+msgstr "给附加元件開發者的資訊"
+
+#: views/compatibility/developers.thtml:66
+msgid "compatibility_developers_adjust_maxversion"
+msgstr "調整 maxVersion 而ä¸é‡æ–°ä¸Šå‚³"
+
+#: views/compatibility/dashboard.thtml:124
+msgid "compatibility_developers_check_status"
+msgstr "檢查我的附加元件的狀態"
+
+#. %1$s is a URL
+#. %2$s is an application and version. Example: Firefox 3.0
+#: views/compatibility/dashboard.thtml:126
+msgid "compatibility_developers_login_first"
+msgstr ""
+"如果您有放在 Mozilla 附加元件網站上的元件,<a href=\"%1$s\">請登入</a>以分æžå…ƒ"
+"件在 %2$s 上的狀態。"
+
+#: views/compatibility/dashboard.thtml:114
+msgid "compatibility_developers_mdclogo_alt"
+msgstr "Mozilla Developer Center Logo"
+
+#: views/compatibility/developers.thtml:73
+msgid "compatibility_developers_no_addons"
+msgstr "您沒有任何放在 Mozilla 附加元件網站的附加元件。"
+
+#: views/compatibility/dashboard.thtml:133
+#: views/compatibility/developers.thtml:55
+msgid "compatibility_developers_results"
+msgstr "附加元件狀態檢查çµæžœ"
+
+#: views/compatibility/dashboard.thtml:137
+msgid "compatibility_developers_retrieving"
+msgstr "正在接收您的附加元件狀態…"
+
+#. %1$s is a number
+#. %2$s is an application name
+#. %3$s is a number.
+#. Full example: 50 Firefox users (10% of total)
+#: views/compatibility/developers.thtml:65
+msgid "compatibility_developers_user_count"
+msgstr "%1$s %2$s 使用者 (佔總數的 %3$s&#37;)"
+
+#: views/compatibility/report.thtml:45
+msgid "compatibility_report_detail_intro"
+msgstr "以下是 Mozilla 在以使用率大å°æŽ’åºå¾Œï¼Œæ‰€çŸ¥ç¸½è¨ˆé”到 95% 使用率的元件。"
+
+#: views/compatibility/dashboard.thtml:94
+msgid "compatibility_report_detailed_link"
+msgstr "檢視詳細報告"
+
+#. %1$s and %2$s are numbers
+#. %3$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:65
+msgid "compatibility_report_intro"
+msgstr ""
+"Mozilla 所知總計é”到 95&#37; 使用率的 %1$s 個元件中,目å‰å…±æœ‰ <b>%2$s&#37;</"
+"b> 與 %3$s 最新版本相容。"
+
+#: views/compatibility/dashboard.thtml:81
+msgid "compatibility_report_legend_alpha"
+msgstr "Alpha 版本"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:81
+msgid "compatibility_report_legend_alpha_description"
+msgstr "和 %1$s 的 Alpha 版本相容的附加元件"
+
+#: views/compatibility/dashboard.thtml:85
+msgid "compatibility_report_legend_beta"
+msgstr "Beta 版本 (測試版)"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:85
+msgid "compatibility_report_legend_beta_description"
+msgstr "與 %1$s 的測試版或是 RC 版相容的附加元件"
+
+#: views/compatibility/dashboard.thtml:89
+msgid "compatibility_report_legend_latest"
+msgstr "最新版"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:89
+msgid "compatibility_report_legend_latest_description"
+msgstr "已經更新到與 %1$s 最新版相容的附加元件"
+
+#: views/compatibility/dashboard.thtml:77
+msgid "compatibility_report_legend_other"
+msgstr "其它版本"
+
+#. %1$s is an application name and version. Example: Firefox 3.1
+#: views/compatibility/dashboard.thtml:77
+msgid "compatibility_report_legend_other_description"
+msgstr "與任何版本的 %1$s 皆ä¸ç›¸å®¹çš„附加元件"
+
+#: views/compatibility/dashboard.thtml:62
+msgid "compatibility_report_title"
+msgstr "附加元件相容性報告"
+
+#: views/compatibility/dashboard.thtml:54
+#: views/compatibility/dashboard.thtml:144 views/compatibility/users.thtml:42
+msgid "compatibility_user_info"
+msgstr "給附加元件使用者的資訊"
+
+#: views/compatibility/dashboard.thtml:52
+msgid "compatibility_view_report"
+msgstr "顯示相容性報告"
+
+#. %s is a URL
+#: views/pages/credits.thtml:142
+#, php-format
+msgid "credits_contributing"
+msgstr "想瞭解他們的貢ç»ï¼Œæ‚¨å¯ä»¥åƒè€ƒ Mozilla 上的 %s。"
+
+#: views/pages/credits.thtml:142
+msgid "credits_contributing_wikipage"
+msgstr "Wiki é é¢"
+
+#: views/pages/credits.thtml:99
+msgid "credits_intro"
+msgstr "Mozilla 謹此感è¬ä»¥ä¸‹é•·æœŸä¾†ç‚º addons.mozilla.org è²¢ç»è‰¯å¤šçš„人:"
+
+#: views/pages/credits.thtml:103
+msgid "credits_section_developers"
+msgstr "開發者"
+
+#: views/pages/credits.thtml:115
+msgid "credits_section_editors"
+msgstr "審核者"
+
+#: views/pages/credits.thtml:109
+msgid "credits_section_localizers"
+msgstr "在地化"
+
+#: views/pages/credits.thtml:121
+msgid "credits_section_other_contributors"
+msgstr "其他貢ç»"
+
+#: views/pages/credits.thtml:127
+msgid "credits_section_past_developers"
+msgstr "å‰ä»»é–‹ç™¼è€…"
+
+#: views/pages/credits.thtml:133
+msgid "credits_section_software"
+msgstr "軟體åŠåœ–片"
+
+#: views/pages/credits.thtml:136
+msgid "credits_software_famfamfam"
+msgstr ""
+"部分圖示是來自於 <a href=\"http://www.famfamfam.com/lab/icons/silk/"
+"\">famfamfam Silk 圖示集</a>,以 <a href=\"http://creativecommons.org/"
+"licenses/by/2.5/\">創用 CC 姓å標示 2.5 通用版</a> 授權æ¢æ¬¾ç™¼ä½ˆã€‚"
+
+#: views/pages/credits.thtml:137
+msgid "credits_software_timeplot"
+msgstr ""
+"部分é é¢ä½¿ç”¨ <a href=\"http://www.simile-widgets.org/timeplot/\">Timeplot</a> "
+"元素,以 <a href=\"http://simile.mit.edu/license.html\">BSD</a> 授權æ¢æ¬¾ç™¼ä½ˆã€‚"
+
+#. date format string as used in PHP's strftime():
+#. http://php.net/strftime
+#: views/elements/collections_interactive_addon.thtml:85
+#: views/elements/amo2009/addon_version_detail.thtml:53
+#: views/elements/amo2009/homepage_addon.thtml:115
+#: views/elements/addon_version_detail.thtml:54
+#: views/elements/addon_listitem.thtml:124 views/elements/feature.thtml:106
+#: views/collections/detail.thtml:118 views/collections/edit.thtml:325
+#: views/users/info.thtml:76 views/editors/reviews_queue.thtml:57
+#: views/editors/reviews_queue.thtml:68 views/developers/dashboard.thtml:65
+#: views/developers/versions_edit.thtml:208 views/developers/versions.thtml:67
+#: views/search/rss/index.thtml:5 views/addons/rss/versions.thtml:42
+#: views/addons/display.thtml:104 views/addons/display.thtml:356
+#: views/addons/browse_thumbs.thtml:75 views/reviews/add.thtml:63
+#: views/reviews/display.thtml:74 views/reviews/display.thtml:160
+#: views/reviews/delete.thtml:54 controllers/statistics_controller.php:244
+#: controllers/collections_controller.php:1047
+msgid "date"
+msgstr "%Y 年 %m 月 %e 日"
+
+#. date and time format string (strftime)
+#. http://php.net/strftime
+#: views/elements/addon_version_detail.thtml:53
+#: views/developers/discuss.thtml:52 views/developers/discuss.thtml:62
+#: views/admin/addons_status.thtml:57
+msgid "datetime"
+msgstr "%Y 年 %m 月 %e 日 %H:%M"
+
+#: views/elements/developers/actionbar.thtml:47
+msgid "devcp_actionbar_link_details"
+msgstr "詳細資訊"
+
+#: views/elements/developers/actionbar.thtml:42
+#: views/elements/developers/actionbar.thtml:50
+#: views/developers/dashboard.thtml:64
+msgid "devcp_actionbar_link_edit"
+msgstr "編輯附加元件"
+
+#: views/elements/developers/actionbar.thtml:51
+msgid "devcp_actionbar_link_newversion"
+msgstr "上傳新版本"
+
+#: views/elements/developers/actionbar.thtml:44
+#: views/elements/developers/actionbar.thtml:49
+#: views/developers/dashboard.thtml:73
+msgid "devcp_actionbar_link_stats"
+msgstr "統計資訊顯示æ¿"
+
+#. %1$s is a filename, e.g. "foo.txt"
+#. %2$s is the extension, e.g. ".txt"
+#. %3$s is a list of valid extensions, like ".png, .jpg, .gif"
+#: controllers/developers_controller.php:1361
+msgid "devcp_add_previews_extension_error"
+msgstr "檔案 %1$s 包å«ç„¡æ•ˆçš„副檔å(%2$s)。å…許的副檔å: %3$s"
+
+#. %s is the filename.
+#: controllers/developers_controller.php:1394
+msgid "devcp_add_previews_save_error"
+msgstr "檔案 %s ä¸èƒ½å„²å­˜åˆ°è³‡æ–™åº«ã€‚è«‹å†è©¦ä¸€æ¬¡ã€‚"
+
+#. %1$s is the preview ID number, %2$s is the filename.
+#: controllers/developers_controller.php:1389
+msgid "devcp_add_previews_success_replace"
+msgstr "å·²æˆåŠŸä½¿ç”¨ %2$s å–代é è¦½åœ–片 %1$s。"
+
+#. %s is the filename.
+#: controllers/developers_controller.php:1391
+msgid "devcp_add_previews_success_upload"
+msgstr "檔案 %s 上傳æˆåŠŸã€‚您å¯ä»¥åœ¨ä¸‹é¢åŠ å…¥èªªæ˜Žã€‚"
+
+#: controllers/components/developers.php:1163
+msgid "devcp_additem_addontype_autodetect"
+msgstr "(自動åµæ¸¬ï¼‰"
+
+#: views/elements/developers/additem.thtml:76
+msgid "devcp_additem_linktitle_opensin_newwindow"
+msgstr "用新視窗開啟"
+
+#: views/elements/developers/additem.thtml:41
+msgid "devcp_additem_sidebar_title"
+msgstr "上傳附加元件"
+
+#: views/elements/developers/additem.thtml:53
+msgid "devcp_additem_step0_newlink"
+msgstr "開發者授權åˆç´„"
+
+#: views/elements/developers/additem.thtml:46
+msgid "devcp_additem_step1_link"
+msgstr "步驟 1:上傳"
+
+#: views/elements/developers/additem.thtml:47
+msgid "devcp_additem_step2_link"
+msgstr "步驟 2:元件詳細資訊"
+
+#: views/elements/developers/additem.thtml:48
+msgid "devcp_additem_step3_link"
+msgstr "步驟 3:版本詳細資訊"
+
+#: views/elements/developers/additem.thtml:49
+msgid "devcp_additem_step4_link"
+msgstr "步驟 4:在地化"
+
+#: views/elements/developers/additem.thtml:50
+msgid "devcp_additem_step5_link"
+msgstr "步驟 5:完æˆ"
+
+#: views/elements/developers/additem.thtml:76
+msgid "devcp_additem_submissionhelp_link"
+msgstr "上傳說明"
+
+#: controllers/previews_controller.php:168
+#: controllers/previews_controller.php:277
+msgid "devcp_addon_field_preview_caption_displaytitle"
+msgstr "é è¦½åœ–片說明"
+
+#: views/developers/addon_status.thtml:177
+msgid "devcp_addon_status_action_activate"
+msgstr "設為「活動中ã€"
+
+#: views/developers/addon_status.thtml:178
+msgid "devcp_addon_status_action_activate_description"
+msgstr "將您的附加元件設為活動中,以顯示在公開列表,並啟動更新檢查æœå‹™ã€‚"
+
+#: views/developers/addon_status.thtml:135
+msgid "devcp_addon_status_action_complete"
+msgstr "完æˆå…ƒä»¶"
+
+#: views/developers/addon_status.thtml:136
+msgid "devcp_addon_status_action_complete_description"
+msgstr "完æˆæ‚¨çš„元件並移到「沙箱ã€å€"
+
+#: views/developers/addon_status.thtml:181
+msgid "devcp_addon_status_action_deactivate"
+msgstr "設為「éžæ´»å‹•ä¸­ã€"
+
+#: views/developers/addon_status.thtml:182
+msgid "devcp_addon_status_action_deactivate_description"
+msgstr "將您的附加元件設為éžæ´»å‹•ä¸­ï¼Œä»¥å¾žå…¬é–‹åˆ—表裡隱è—,並å–消更新檢查æœå‹™ã€‚"
+
+#: views/developers/addon_status.thtml:143
+msgid "devcp_addon_status_action_move"
+msgstr "移至「沙箱ã€å€"
+
+#: views/developers/addon_status.thtml:144
+msgid "devcp_addon_status_action_move_description"
+msgstr "將您的元件移回「沙箱ã€å€ã€‚這個動作是å¯ä»¥æ’¤éŠ·çš„。"
+
+#: views/developers/addon_status.thtml:139
+msgid "devcp_addon_status_action_nominate"
+msgstr "é€äº¤æ‰¹å‡†"
+
+#: views/developers/addon_status.thtml:140
+msgid "devcp_addon_status_action_nominate_description"
+msgstr "將你的元件é€äº¤æ‰¹å‡†è‡³ã€Œå…¬é–‹ã€å€"
+
+#: views/developers/addon_status.thtml:147
+msgid "devcp_addon_status_action_public"
+msgstr "設為「公開ã€"
+
+#: views/developers/addon_status.thtml:148
+msgid "devcp_addon_status_action_public_description"
+msgstr "å†æ¬¡å…¬é–‹æ‚¨çš„元件。"
+
+#: views/developers/addon_status.thtml:169
+msgid "devcp_addon_status_active"
+msgstr ""
+"您的元件目å‰ç‚ºã€Œ<span class=\"inactive-0\">活動中</span>ã€ã€‚這表示元件會出ç¾åœ¨"
+"所有與以上狀態相符的列表中。"
+
+#: views/developers/addon_status.thtml:111
+msgid "devcp_addon_status_completion_disabled"
+msgstr ""
+"在完æˆæ‚¨çš„附加元件並將其移至「<span class=\"status-1\">沙箱</span>ã€å€å‰ï¼Œè«‹å…ˆ"
+"é”æˆä¸Šè¿°æ¨™æº–。"
+
+#: views/developers/addon_status.thtml:108
+msgid "devcp_addon_status_completion_enabled"
+msgstr ""
+"您ç¾åœ¨å¯ä»¥æŒ‰ä¸‹é¢çš„按鈕,完æˆæ‚¨çš„元件並將其é€è‡³ã€Œ<span class=\"status-1\">沙箱"
+"</span>ã€å€ã€‚"
+
+#: views/developers/addon_status.thtml:102
+msgid "devcp_addon_status_criteria_category"
+msgstr "至少è¦é¸æ“‡ä¸€å€‹åˆ†é¡ž"
+
+#: views/developers/addon_status.thtml:101
+msgid "devcp_addon_status_criteria_description"
+msgstr "需è¦é™„加元件敘述"
+
+#: views/developers/addon_status.thtml:99
+msgid "devcp_addon_status_criteria_name"
+msgstr "需è¦å…ƒä»¶å稱"
+
+#: views/developers/addon_status.thtml:120
+msgid "devcp_addon_status_criteria_prerelease"
+msgstr "元件ä¸å¾—被標示為發行å‰ç‰ˆæœ¬ï¼ˆPre-release)。"
+
+#: views/developers/addon_status.thtml:119
+msgid "devcp_addon_status_criteria_preview"
+msgstr "擴充套件和佈景主題至少è¦æœ‰ä¸€å¼µé è¦½åœ–片。"
+
+#: views/developers/addon_status.thtml:100
+msgid "devcp_addon_status_criteria_summary"
+msgstr "需è¦é™„加元件摘è¦"
+
+#. %s is the status in a span, e.g. "<span>_('Public')</span>".
+#: views/developers/addon_status.thtml:58
+msgid "devcp_addon_status_header"
+msgstr "元件狀態: %s"
+
+#: views/developers/addon_status.thtml:152
+#: views/developers/addon_status.thtml:173
+msgid "devcp_addon_status_header_actions"
+msgstr "å¯é€²è¡Œçš„æ“作"
+
+#: views/developers/addon_status.thtml:168
+msgid "devcp_addon_status_header_active"
+msgstr "活動狀態: <span class=\"inactive-0\">活動中</span>"
+
+#: views/developers/addon_status.thtml:97
+msgid "devcp_addon_status_header_criteria"
+msgstr "元件完æˆæ¨™æº–"
+
+#: views/developers/addon_status.thtml:164
+msgid "devcp_addon_status_header_inactive"
+msgstr "活動狀態: <span class=\"inactive-1\">éžæ´»å‹•ä¸­</span>"
+
+#: views/developers/addon_status.thtml:117
+msgid "devcp_addon_status_header_nomination"
+msgstr "公開批准標準"
+
+#: views/developers/addon_status.thtml:190
+msgid "devcp_addon_status_header_trusted"
+msgstr "信任狀態: <span class=\"status-4\">å—信任的</span>"
+
+#: views/developers/addon_status.thtml:165
+msgid "devcp_addon_status_inactive"
+msgstr ""
+"您的元件目å‰ç‚ºã€Œ<span class=\"inactive-1\">éžæ´»å‹•ä¸­</span>ã€ã€‚這表示無論以上狀"
+"態為何,元件都ä¸æœƒå‡ºç¾åœ¨ä»»ä½•åˆ—表中。更新檢查æœå‹™å°‡<b>ä¸æœƒ</b>å°æ‚¨çš„元件æ供更"
+"新。"
+
+#: views/developers/addon_status.thtml:128
+msgid "devcp_addon_status_nominate_disabled"
+msgstr ""
+"在將您的附加元件æå至「<span class=\"status-4\">公開</span>ã€å‰ï¼Œè«‹å…ˆé”æˆä¸Šè¿°"
+"標準。"
+
+#: views/developers/addon_status.thtml:125
+msgid "devcp_addon_status_nominate_enabled"
+msgstr ""
+"您ç¾åœ¨å¯ä»¥æŒ‰ä¸‹é¢çš„按鈕,將元件é€äº¤æ‰¹å‡†è‡³ã€Œ<span class=\"status-4\">公開</"
+"span>ã€å€ã€‚"
+
+#: views/developers/addon_status.thtml:64
+msgid "devcp_addon_status_public"
+msgstr "「公開ã€å€"
+
+#: views/developers/addon_status.thtml:63
+msgid "devcp_addon_status_sandbox"
+msgstr "「沙箱ã€å€"
+
+#. %s is an email address.
+#: views/developers/addon_status.thtml:89
+msgid "devcp_addon_status_switch_disabled"
+msgstr ""
+"您的附加元件被管ç†å“¡<span class=\"status-5\">åœç”¨</span>而無法使用。如果您有任"
+"何å•é¡Œï¼Œè«‹å¯„é€ Email 到 %s。"
+
+#: views/developers/addon_status.thtml:67
+msgid "devcp_addon_status_switch_incomplete"
+msgstr ""
+"您的元件目å‰ç‚ºã€Œ<span class=\"status-0\">未完æˆ</span>ã€ã€‚這表示元件將ä¸æœƒå‡ºç¾"
+"於網站的任何ä½ç½®æˆ–更新檢查æœå‹™ä¸­ã€‚當您的元件é”æˆä»¥ä¸‹æ¨™æº–,而å¯ä»¥å®Œæˆä¸¦ç§»è‡³"
+"「<span class=\"status-1\">沙箱</span>ã€å€æ™‚,您å¯ä»¥å†é€ è¨ªé€™å€‹é é¢ä»¥å®Œæˆå…ƒä»¶ã€‚"
+
+#. %s is a number, perhaps 42.
+#: views/developers/addon_status.thtml:77
+msgid "devcp_addon_status_switch_nominated"
+msgstr ""
+"您的元件目å‰å·²é€äº¤æ‰¹å‡†ä»¥å‰å¾€ã€Œ<span class=\"status-4\">公開</span>ã€å€ï¼Œæ­£åœ¨ç­‰"
+"待審核者批准。目å‰æœ‰ %s 個其他元件正在排隊。"
+
+#. %s is an email address.
+#: views/developers/addon_status.thtml:81
+msgid "devcp_addon_status_switch_pending"
+msgstr ""
+"您的附加元件目å‰è¢«æ“±ç½®ï¼Œé€™ä¸æ˜¯æ­£å¸¸ç¾è±¡ã€‚è«‹å¯„é€ Email 到 %s ,附上您的元件 ID "
+"並æåŠé€™å€‹éŒ¯èª¤ã€‚"
+
+#: views/developers/addon_status.thtml:85
+msgid "devcp_addon_status_switch_public"
+msgstr ""
+"您的元件目å‰ç‚ºã€Œ<span class=\"status-4\">公開</span>ã€ã€‚這表示元件會出ç¾åœ¨æ‰€æœ‰"
+"列表和æœå°‹ä¸­ï¼Œä¸”å¯ä»¥ä¸å—é™åˆ¶åœ°è¢«ä¸‹è¼‰ã€‚更新檢查æœå‹™æœƒå°æ‚¨çš„元件æ供更新。"
+
+#: views/developers/addon_status.thtml:71
+#: views/developers/addon_status.thtml:75
+msgid "devcp_addon_status_switch_sandbox"
+msgstr ""
+"您的元件在「<span class=\"status-1\">沙箱</span>ã€å€ï¼Œé€™è¡¨ç¤ºå®ƒæœƒå‡ºç¾åœ¨åˆ—表和æœ"
+"尋中,但使用者必須先登入æ‰èƒ½ä¸‹è¼‰ã€‚更新檢查æœå‹™å°‡<b>ä¸æœƒ</b>å°æ‚¨çš„元件æ供更"
+"新。"
+
+#. %s is the add-on name.
+#: views/developers/addon_status_nominate.thtml:43
+#: views/developers/addon_status_confirm.thtml:43
+#: views/developers/addon_status.thtml:43
+msgid "devcp_addon_status_title"
+msgstr "%s 狀態"
+
+#: views/developers/addon_status.thtml:191
+msgid "devcp_addon_status_trusted"
+msgstr ""
+"您的附加元件目å‰ç‚ºã€Œ<span class=\"status-4\">å—信任的</span>ã€ã€‚這表示您ä¸éœ€è¦"
+"編輯者的審核就å¯ä»¥ä¸Šå‚³æ›´æ–°ã€‚"
+
+#: views/developers/dashboard.thtml:68
+msgid "devcp_dashboard_active"
+msgstr "活動中"
+
+#. %1$s is the add-on type string
+#. %2$s is Inactive or Active in a <span>
+#. %3$s is the addon's public status (Public, In Sandbox, ...) in a <span>
+#: views/developers/dashboard.thtml:69
+msgid "devcp_dashboard_addontype_status"
+msgstr "%1$sç›®å‰%2$s且%3$s"
+
+#: views/developers/dashboard.thtml:67
+msgid "devcp_dashboard_change_status"
+msgstr "變更狀態"
+
+#. %s is the addons email address.
+#: views/developers/dashboard.thtml:99
+msgid "devcp_dashboard_disabled_questions"
+msgstr ""
+"您的附加元件被管ç†å“¡åœç”¨è€Œç„¡æ³•ä½¿ç”¨ã€‚如果您有任何å•é¡Œï¼Œè«‹å¯„é€ Email 到 %s。"
+
+#. %s is the (localized) add-on status string in a span, e.g. "Disabled"
+#: views/developers/dashboard.thtml:98
+msgid "devcp_dashboard_disabled_status"
+msgstr "元件狀態: %s"
+
+#: views/developers/dashboard.thtml:43
+msgid "devcp_dashboard_header_main"
+msgstr "開發者資訊顯示æ¿"
+
+#: views/developers/dashboard.thtml:110
+msgid "devcp_dashboard_header_welcome"
+msgstr "歡迎來到開發者資訊顯示æ¿"
+
+#: views/developers/dashboard.thtml:68
+msgid "devcp_dashboard_inactive"
+msgstr "éžæ´»å‹•ä¸­"
+
+#. %s is a date in the _('date') format
+#: views/developers/dashboard.thtml:65
+msgid "devcp_dashboard_last_edited"
+msgstr "最後一次編輯於 %s"
+
+#: views/developers/dashboard.thtml:111
+msgid "devcp_dashboard_learn"
+msgstr ""
+"您目å‰æ²’有任何放在 Mozilla 附加元件網站的元件。按下é¢çš„「開始ã€ä»¥çž­è§£é€™å€‹éŽç¨‹"
+"並é€å‡ºæ‚¨çš„第一個元件。"
+
+#: views/developers/dashboard.thtml:112
+msgid "devcp_dashboard_start"
+msgstr "開始"
+
+#: views/developers/dashboard.thtml:82
+msgid "devcp_dashboard_versions"
+msgstr "版本與檔案"
+
+#: views/developers/dashboard.thtml:91
+msgid "devcp_dashboard_versions_new"
+msgstr "上傳新版本"
+
+#. %s is the preview ID number.
+#: controllers/developers_controller.php:1415
+msgid "devcp_delete_previews_error"
+msgstr "無法從資料庫刪除é è¦½åœ–片 %s,請å†è©¦ä¸€æ¬¡ã€‚"
+
+#. %s is the preview ID number.
+#: controllers/developers_controller.php:1413
+msgid "devcp_delete_previews_success"
+msgstr "å·²æˆåŠŸåˆªé™¤é è¦½åœ–片 %s。"
+
+#: controllers/developers_controller.php:1089
+msgid "devcp_delete_version_priv_error"
+msgstr "您沒有刪除版本或檔案的權é™ã€‚"
+
+#. %1$s is the count of files, a number
+#. %2$s is a status string like _('Public') or _('Incomplete')
+#: controllers/components/amo.php:549
+msgid "devcp_describe_version_status"
+msgid_plural "devcp_describe_version_status"
+msgstr[0] "%1$s 個%2$s的檔案"
+
+#. %s is a version number. Example: 3.0
+#: views/developers/versions.thtml:65
+#, php-format
+msgid "devcp_details_version"
+msgstr "版本 %s"
+
+#: views/developers/discuss.thtml:68
+msgid "devcp_discuss_addreply_header"
+msgstr "新增回覆"
+
+#: views/developers/discuss.thtml:57
+msgid "devcp_discuss_allreplies_header"
+msgstr "回覆"
+
+#. notice when an error occurs saving a discussion reply
+#. %1 is the email address (linked) for the amo-editors list
+#: views/developers/discuss.thtml:70
+msgid "devcp_discuss_error_notice"
+msgstr "儲存您的回覆時發生了錯誤。關於此å•é¡Œï¼Œè«‹è¯ç¹« %1$s。"
+
+#. %1 is the add-on name, %2 is the add-on's version number currently being reviewed by an editor
+#: views/developers/discuss.thtml:46
+msgid "devcp_discuss_intro"
+msgstr "ä¸€ä½ Mozilla 元件審核者請求您的元件 %1$s 之 %2$s 版本的更多資訊。"
+
+#. %1 is the add-on name
+#: views/developers/discuss.thtml:43
+msgid "devcp_discuss_pagetitle"
+msgstr "æä¾›å°å…ƒä»¶ %1$s 之æ„見的更多資訊"
+
+#. submit button text
+#: views/developers/discuss.thtml:79
+msgid "devcp_discuss_submit_reply"
+msgstr "é€å‡ºå›žè¦†"
+
+#: views/developers/discuss.thtml:72
+msgid "devcp_discuss_success_message"
+msgstr "å·²æˆåŠŸå„²å­˜æ‚¨çš„回覆。此討論的其他åƒèˆ‡è€…將收到 Email 通知。"
+
+#. in an author/editor discussion about an add-on to be reviewed:
+#. %1 is the commenter's user name (linked).
+#. %2 is the full date the comment was made.
+#: views/developers/discuss.thtml:52 views/developers/discuss.thtml:62
+msgid "devcp_discuss_writtenby"
+msgstr "由 %1$s 撰寫於 %2$s"
+
+#: views/developers/addon_edit_authors.thtml:72
+#: views/developers/addon_edit_authors.thtml:81
+msgid "devcp_edit_authors_add_author"
+msgstr "新增作者"
+
+#: views/developers/addon_edit_authors.thtml:96
+msgid "devcp_edit_authors_add_author_button"
+msgstr "新增作者"
+
+#: views/developers/addon_edit_authors.thtml:83
+msgid "devcp_edit_authors_add_email"
+msgstr "作者帳號 Email:"
+
+#: views/developers/addon_edit_authors.thtml:98
+msgid "devcp_edit_authors_add_loading"
+msgstr "正在檢查帳號 Email…"
+
+#: views/developers/addon_edit_authors.thtml:70
+msgid "devcp_edit_authors_click_save"
+msgstr "按下é¢çš„「更新作者ã€æŒ‰éˆ•ä»¥å„²å­˜ã€‚"
+
+#: views/developers/addon_edit_authors.thtml:58
+msgid "devcp_edit_authors_header_current"
+msgstr "ç›®å‰ä½œè€…"
+
+#: views/developers/addon_edit_authors.thtml:50
+msgid "devcp_edit_authors_header_manage"
+msgstr "管ç†å…ƒä»¶ä½œè€…"
+
+#: views/developers/addon_edit_authors.thtml:93
+msgid "devcp_edit_authors_label_add_listed"
+msgstr "列為公開é é¢ä¸Šçš„作者"
+
+#: views/developers/addon_edit_authors.thtml:89
+msgid "devcp_edit_authors_label_developer"
+msgstr ""
+"<strong>開發者</strong> - å¯ä»¥å…¨é¢ç®¡ç†å…ƒä»¶æ¸…單,新增和刪除其他作者除外。"
+
+#: views/developers/addon_edit_authors.thtml:88
+msgid "devcp_edit_authors_label_owner"
+msgstr ""
+"<strong>æ“有者</strong> - å¯ä»¥å…¨é¢ç®¡ç†å…ƒä»¶æ¸…單,包括新增和刪除其他作者。"
+
+#: views/developers/addon_edit_authors.thtml:90
+msgid "devcp_edit_authors_label_viewer"
+msgstr ""
+"<strong>檢視者</strong> - å¯ä»¥æª¢è¦–元件的開發者清單和統計資訊,但ä¸èƒ½åšä»»ä½•æ›´"
+"動。"
+
+#. Placeholder for the empty option in a <select>.
+#: views/developers/addon_edit_categories.thtml:69
+msgid "devcp_edit_authors_option_empty"
+msgstr "----------------"
+
+#: views/developers/addon_edit_authors.thtml:86
+msgid "devcp_edit_authors_select_role"
+msgstr "é¸æ“‡ä½œè€…的角色:"
+
+#. Column name in a table.
+#: views/developers/addon_edit_authors.thtml:62
+msgid "devcp_edit_authors_th_author"
+msgstr "作者"
+
+#. Column name in a table.
+#: views/developers/addon_edit_authors.thtml:64
+msgid "devcp_edit_authors_th_listed"
+msgstr "列出"
+
+#. Column name in a table.
+#: views/developers/addon_edit_authors.thtml:63
+msgid "devcp_edit_authors_th_role"
+msgstr "角色"
+
+#: views/developers/addon_edit_authors.thtml:77
+msgid "devcp_edit_authors_update_author"
+msgstr "更新作者"
+
+#: views/developers/addon_edit_categories.thtml:99
+msgid "devcp_edit_categories_button_update"
+msgstr "更新分類"
+
+#: views/developers/addon_edit_categories.thtml:88
+msgid "devcp_edit_categories_does_not_fit"
+msgstr "沒有é©åˆæˆ‘的元件的分類。"
+
+#. %s is the application name (Firefox, Thunderbird).
+#: views/developers/addon_edit_categories.thtml:61
+msgid "devcp_edit_categories_header_application"
+msgstr "%s 分類"
+
+#: views/developers/addon_edit_categories.thtml:49
+msgid "devcp_edit_categories_header_manage"
+msgstr "管ç†å…ƒä»¶åˆ†é¡ž"
+
+#: views/developers/addon_edit_categories.thtml:91
+msgid "devcp_edit_categories_hover"
+msgstr "將滑鼠游標移至分類上以觀看敘述。"
+
+#. %s is the category number (1, 2, 3).
+#: views/developers/addon_edit_categories.thtml:67
+msgid "devcp_edit_categories_label_category_num"
+msgstr "分類 %s"
+
+#: views/developers/addon_edit_categories.thtml:94
+#: views/developers/addon_edit_categories.thtml:103
+msgid "devcp_edit_categories_none_available"
+msgstr "沒有é©ç”¨æ–¼æ­¤å…ƒä»¶é¡žåž‹èˆ‡æ‡‰ç”¨ç¨‹å¼çš„分類。"
+
+#: views/developers/addon_edit_categories.thtml:86
+msgid "devcp_edit_categories_other"
+msgstr "åªæœ‰ç•¶æ‚¨çš„元件ä¸ç¬¦åˆä»»ä½•å…¶ä»–分類時,æ‰å°‡å®ƒæ”¾åœ¨é€™å€‹åˆ†é¡žã€‚"
+
+#. %s is the application name (Firefox, Thunderbird).
+#: views/developers/addon_edit_categories.thtml:63
+msgid "devcp_edit_categories_select_application_categories"
+msgstr "為您的元件é¸æ“‡è‡³å¤šä¸‰å€‹ %s 分類"
+
+#: views/developers/addon_edit.thtml:47
+msgid "devcp_edit_dd_manage_authors"
+msgstr "新增或移除å¯ä»¥ç®¡ç†é€™å€‹å…ƒä»¶çš„使用者。"
+
+#: views/developers/addon_edit.thtml:49
+msgid "devcp_edit_dd_manage_categories"
+msgstr "為元件支æ´çš„å„個應用程å¼é¸æ“‡ç›¸é—œåˆ†é¡žã€‚"
+
+#: views/developers/addon_edit.thtml:51
+msgid "devcp_edit_dd_manage_description"
+msgstr "新增與修改您元件的摘è¦ã€æ•˜è¿°ã€ä½¿ç”¨è€…授權åˆç´„與隱ç§æ”¿ç­–之翻譯。"
+
+#: views/developers/addon_edit.thtml:53
+msgid "devcp_edit_dd_manage_properties"
+msgstr "變更您元件的å稱ã€é¦–é ã€åœ–示與其他註記。"
+
+#: views/developers/addon_edit_descriptions.thtml:116
+msgid "devcp_edit_description_button_update"
+msgstr "更新敘述"
+
+#: views/developers/addon_edit_descriptions.thtml:115
+msgid "devcp_edit_description_correct_error"
+msgstr "請修正上述以紅色標記的錯誤。"
+
+#: views/developers/addon_edit_descriptions.thtml:51
+msgid "devcp_edit_descriptions_header"
+msgstr "編輯元件敘述"
+
+#: views/developers/addon_edit_descriptions.thtml:94
+msgid "devcp_edit_descriptions_transbox_comments_description"
+msgstr ""
+"任何並ä¸é©åˆåœ¨å…ƒä»¶æ‘˜è¦æˆ–敘述中æåŠï¼Œä½†å¯èƒ½ä½¿ç”¨è€…會想知é“的資訊。一般而言會包å«"
+"已知的主è¦è‡­èŸ²æ¸…å–®ã€é—œæ–¼å¦‚何回報臭蟲的資訊ã€æ–°ç‰ˆæœ¬é å®šé‡‹å‡ºçš„日期等等。"
+
+#: views/developers/addon_edit_descriptions.thtml:93
+msgid "devcp_edit_descriptions_transbox_comments_name"
+msgstr "開發者留言"
+
+#: views/developers/addon_edit_descriptions.thtml:86
+msgid "devcp_edit_descriptions_transbox_description_description"
+msgstr ""
+"您元件的敘述是å°å…¶ç‰¹è‰²ã€åŠŸèƒ½èˆ‡å…¶ä»–相關資訊的較長說明。這會在元件é é¢ä¸­æ‘˜è¦çš„下"
+"方顯示。"
+
+#: views/developers/addon_edit_descriptions.thtml:85
+msgid "devcp_edit_descriptions_transbox_description_name"
+msgstr "附加元件敘述"
+
+#: views/developers/addon_edit_descriptions.thtml:103
+msgid "devcp_edit_descriptions_transbox_eula_description"
+msgstr ""
+"如果您的元件具有「使用者授權åˆç´„ã€ï¼ˆEULA),請將其內文輸入於下方。如此一來,使"
+"用者必須åŒæ„該內容後æ‰èƒ½å®‰è£æ‚¨çš„å…ƒä»¶ã€‚è«‹æ³¨æ„ EULA å’Œ GPL 或 MPL 等程å¼ç¢¼æŽˆæ¬Šæ˜¯"
+"ä¸ä¸€æ¨£çš„。"
+
+#: views/developers/addon_edit_descriptions.thtml:102
+msgid "devcp_edit_descriptions_transbox_eula_name"
+msgstr "使用者授權åˆç´„"
+
+#: views/developers/addon_edit_descriptions.thtml:112
+msgid "devcp_edit_descriptions_transbox_privacy_description"
+msgstr ""
+"如果您的元件有自己的隱ç§æ”¿ç­–,請在此輸入其文字。您元件的顯示é é¢å°‡é¡¯ç¤ºè©²éš±ç§æ”¿"
+"ç­–çš„éˆçµã€‚"
+
+#: views/developers/addon_edit_descriptions.thtml:111
+msgid "devcp_edit_descriptions_transbox_privacy_name"
+msgstr "éš±ç§æ”¿ç­–"
+
+#: views/developers/addon_edit_descriptions.thtml:78
+msgid "devcp_edit_descriptions_transbox_summary_description"
+msgstr ""
+"摘è¦æ˜¯å°æ‚¨å…ƒä»¶åŸºæœ¬åŠŸèƒ½çš„簡短說明,會顯示於æœå°‹èˆ‡ç€è¦½çš„清單,以åŠå…ƒä»¶é¡¯ç¤ºé é¢çš„"
+"頂端。 <strong>長度以 250 個字元為é™ã€‚</strong>"
+
+#: views/developers/addon_edit_descriptions.thtml:77
+msgid "devcp_edit_descriptions_transbox_summary_name"
+msgstr "附加元件摘è¦"
+
+#: views/developers/addon_edit.thtml:46
+msgid "devcp_edit_dt_manage_authors"
+msgstr "管ç†å…ƒä»¶ä½œè€…"
+
+#: views/developers/addon_edit.thtml:48
+msgid "devcp_edit_dt_manage_categories"
+msgstr "管ç†å…ƒä»¶åˆ†é¡ž"
+
+#: views/developers/addon_edit.thtml:50
+msgid "devcp_edit_dt_manage_descriptions"
+msgstr "管ç†å…ƒä»¶æ•˜è¿°"
+
+#: views/developers/addon_edit.thtml:52
+msgid "devcp_edit_dt_manage_properties"
+msgstr "管ç†å…ƒä»¶å±¬æ€§"
+
+#: views/developers/addon_edit_properties.thtml:170
+msgid "devcp_edit_label_externalsoftware"
+msgstr "需è¦å¤–部軟體支æ´"
+
+#: views/developers/addon_edit_properties.thtml:205
+msgid "devcp_edit_label_locale_disambiguation"
+msgstr "é¡å¤–語言資訊"
+
+#: views/developers/addon_edit_properties.thtml:168
+msgid "devcp_edit_label_prerelease"
+msgstr "這是一個發行å‰ç‰ˆæœ¬ï¼ˆPre-release)"
+
+#: views/developers/addon_edit_properties.thtml:169
+msgid "devcp_edit_label_sitespecific"
+msgstr "專為特定網站設計"
+
+#: views/developers/addon_edit_properties.thtml:202
+msgid "devcp_edit_label_target_locale"
+msgstr "目標語言"
+
+#: views/developers/addon_edit_properties.thtml:212
+msgid "devcp_edit_properties_button_update"
+msgstr "更新屬性"
+
+#: views/developers/addon_edit_properties.thtml:198
+msgid "devcp_edit_properties_change_guid"
+msgstr "唯有在您瞭解所有後果時,æ‰é€²è¡Œè®Šæ›´ã€‚"
+
+#: views/developers/addon_edit_properties.thtml:109
+msgid "devcp_edit_properties_current_icon"
+msgstr "ç›®å‰åœ–示"
+
+#: views/developers/addon_edit_properties.thtml:85
+msgid "devcp_edit_properties_default_locale"
+msgstr ""
+"元件的é è¨­èªžè¨€æ˜¯å„個翻譯中必須æ供的主è¦èªžè¨€ã€‚如果您的元件未æ供使用者當å‰é¸æ“‡"
+"語言的敘述,便會自動使用é è¨­èªžè¨€ã€‚"
+
+#: views/developers/addon_edit_properties.thtml:167
+msgid "devcp_edit_properties_flags"
+msgstr "這些註記是用來éŽæ¿¾å’Œåˆ†é¡žå…ƒä»¶çš„。"
+
+#: views/developers/addon_edit_properties.thtml:174
+msgid "devcp_edit_properties_guid"
+msgstr ""
+"您元件的 GUID 是由其 install.rdf 指定的唯一識別。您的元件加入 Mozilla 附加元件"
+"網站後便無法變更其 GUID。"
+
+#: views/developers/addon_edit_properties.thtml:53
+msgid "devcp_edit_properties_header"
+msgstr "編輯元件屬性"
+
+#: views/developers/addon_edit_properties.thtml:186
+msgid "devcp_edit_properties_header_addon_type"
+msgstr "附加元件種類"
+
+#: views/developers/addon_edit_properties.thtml:181
+msgid "devcp_edit_properties_header_admin_settings"
+msgstr "管ç†å“¡è¨­å®š"
+
+#: views/developers/addon_edit_properties.thtml:84
+msgid "devcp_edit_properties_header_default_locale"
+msgstr "é è¨­èªžè¨€"
+
+#: views/developers/addon_edit_properties.thtml:166
+msgid "devcp_edit_properties_header_flags"
+msgstr "元件註記"
+
+#: views/developers/addon_edit_properties.thtml:173
+#: views/developers/addon_edit_properties.thtml:197
+msgid "devcp_edit_properties_header_guid"
+msgstr "元件 GUID"
+
+#: views/developers/addon_edit_properties.thtml:104
+msgid "devcp_edit_properties_header_icon"
+msgstr "元件圖示"
+
+#: views/developers/addon_edit_properties.thtml:159
+msgid "devcp_edit_properties_header_other_settings"
+msgstr "其他設定"
+
+#. A header on the admin page to toggle trusted status.
+#: views/developers/addon_edit_properties.thtml:182
+msgid "devcp_edit_properties_header_trusted"
+msgstr "å—信任的元件?"
+
+#: views/developers/addon_edit_properties.thtml:160
+msgid "devcp_edit_properties_header_view_source"
+msgstr "線上檢視原始碼"
+
+#. %s is a comma-separated list of image extensions ".png, .jpg"
+#: views/developers/addon_edit_properties.thtml:106
+msgid "devcp_edit_properties_icon"
+msgstr ""
+"元件圖示是顯示於元件å稱æ—çš„å°åœ–片,會出ç¾åœ¨ç€è¦½æœå°‹çµæžœã€é¡¯ç¤ºé é¢ï¼Œèˆ‡å®‰è£å…ƒä»¶"
+"çš„å°è©±æ¡†ä¸­ã€‚圖片會自動縮放為 32 x 32 åƒç´ ï¼Œè«‹ä½¿ç”¨ä¸‹åˆ—圖片類型:%s"
+
+#: views/developers/addon_edit_properties.thtml:171
+msgid "devcp_edit_properties_label_binary"
+msgstr "這個元件包å«äºŒå…ƒç¢¼å…ƒä»¶ï¼ˆBinary component)"
+
+#: views/developers/addon_edit_properties.thtml:185
+msgid "devcp_edit_properties_label_not_trusted"
+msgstr "éžå—信任的"
+
+#: views/developers/addon_edit_properties.thtml:184
+msgid "devcp_edit_properties_label_trusted"
+msgstr "å—信任的"
+
+#: views/developers/addon_edit_properties.thtml:110
+msgid "devcp_edit_properties_new_icon"
+msgstr "新增圖示"
+
+#: views/developers/addon_edit_properties.thtml:118
+msgid "devcp_edit_properties_remove_icon"
+msgstr "移除圖示"
+
+#: views/developers/addon_edit_properties.thtml:136
+msgid "devcp_edit_properties_transbox_homepage_description"
+msgstr ""
+"如果您的元件有å¦å¤–的首é ï¼Œè«‹åœ¨æ­¤è¼¸å…¥ç¶²å€ã€‚除éžæ‚¨çš„網站æ供了其他語言,å¦å‰‡æ‚¨ä¸"
+"需è¦å¢žåŠ å…¶ä»–翻譯。"
+
+#: views/developers/addon_edit_properties.thtml:135
+msgid "devcp_edit_properties_transbox_homepage_name"
+msgstr "元件首é "
+
+#: views/developers/addon_edit_properties.thtml:79
+msgid "devcp_edit_properties_transbox_name_description"
+msgstr "您的元件å稱會在所有列出您元件的地方出ç¾ã€‚"
+
+#: views/developers/addon_edit_properties.thtml:78
+msgid "devcp_edit_properties_transbox_name_name"
+msgstr "元件å稱"
+
+#: views/developers/addon_edit_properties.thtml:145
+msgid "devcp_edit_properties_transbox_supportemail_description"
+msgstr ""
+"如果您有æ供支æ´è«®è©¢çš„ Email 地å€ï¼Œè«‹è¼¸å…¥æ–¼æ­¤ã€‚除éžæ‚¨ç‚ºä¸åŒèªžè¨€æ供了ä¸åŒçš„ "
+"Email 地å€ï¼Œå¦å‰‡æ‚¨ä¸éœ€è¦å¢žåŠ å…¶ä»–翻譯。"
+
+#: views/developers/addon_edit_properties.thtml:144
+msgid "devcp_edit_properties_transbox_supportemail_name"
+msgstr "æŠ€è¡“æ”¯æ´ Email 地å€"
+
+#: views/developers/addon_edit_properties.thtml:154
+msgid "devcp_edit_properties_transbox_supporturl_description"
+msgstr ""
+"如果您的元件有技術支æ´ç¶²ç«™æˆ–論壇,請在此輸入其網å€ã€‚除éžæ‚¨çš„網站æ供了其他語"
+"言,å¦å‰‡æ‚¨ä¸éœ€è¦å¢žåŠ å…¶ä»–翻譯。"
+
+#: views/developers/addon_edit_properties.thtml:153
+msgid "devcp_edit_properties_transbox_supporturl_name"
+msgstr "技術支æ´ç¶²ç«™"
+
+#: views/developers/addon_edit_properties.thtml:183
+msgid "devcp_edit_properties_trusted"
+msgstr "å—信任的元件å¯ä»¥ä¸ç¶“審核者批准就公開。"
+
+#. %s is href="..." and should stay in the <a> tag.
+#: views/developers/addon_edit_properties.thtml:119
+msgid "devcp_edit_properties_undelete"
+msgstr "圖示將在儲存時刪除,<a %s>å–消?</a>"
+
+#: views/developers/addon_edit_properties.thtml:161
+msgid "devcp_edit_properties_view_source"
+msgstr "如果您願æ„,任何已登入的使用者都能在線上檢視您元件的原始碼。"
+
+#: views/developers/addon_edit_properties.thtml:162
+msgid "devcp_edit_properties_view_source_allow"
+msgstr "å…許線上檢視原始碼"
+
+#: views/developers/addon_edit_properties.thtml:163
+msgid "devcp_edit_properties_view_source_do_not_allow"
+msgstr "ä¸å…許線上檢視原始碼"
+
+#: views/elements/developers/editbox.thtml:46
+msgid "devcp_editbox_authors"
+msgstr "作者"
+
+#: views/elements/developers/editbox.thtml:47
+msgid "devcp_editbox_categories"
+msgstr "分類"
+
+#: views/elements/developers/editbox.thtml:52
+msgid "devcp_editbox_change_status"
+msgstr "變更狀態"
+
+#: views/elements/developers/editbox.thtml:48
+msgid "devcp_editbox_descriptions"
+msgstr "敘述"
+
+#: views/elements/developers/editbox.thtml:43
+msgid "devcp_editbox_edit_addon"
+msgstr "編輯附加元件"
+
+#: views/elements/developers/editbox.thtml:57
+msgid "devcp_editbox_new_version"
+msgstr "新版本"
+
+#: views/elements/developers/editbox.thtml:49
+msgid "devcp_editbox_properties"
+msgstr "屬性"
+
+#: views/elements/developers/editbox.thtml:60
+msgid "devcp_editbox_screenshots"
+msgstr "é è¦½æ“·åœ–"
+
+#: views/elements/developers/editbox.thtml:53
+msgid "devcp_editbox_statistics_dashboard"
+msgstr "統計資訊顯示æ¿"
+
+#: views/elements/developers/editbox.thtml:54
+msgid "devcp_editbox_versions"
+msgstr "版本與檔案"
+
+#: views/elements/developers/editbox.thtml:42
+msgid "devcp_editbox_view_listing"
+msgstr "檢視清單"
+
+#: views/elements/developers/editorsmenu.thtml:59
+msgid "devcp_editorsqueue_featured"
+msgstr "ç²¾é¸å…ƒä»¶"
+
+#. %1 is the review count
+#: views/elements/developers/editorsqueue.thtml:42
+#: views/elements/developers/editorsmenu.thtml:56
+#, php-format
+msgid "devcp_editorsqueue_moderatedreviews"
+msgid_plural "devcp_editorsqueue_moderatedreviews"
+msgstr[0] "待審核æ„見 (%s)"
+
+#. %1 is the nominated addons count
+#: views/elements/developers/editorsqueue.thtml:44
+#: views/elements/developers/editorsmenu.thtml:58
+#, php-format
+msgid "devcp_editorsqueue_nominated"
+msgid_plural "devcp_editorsqueue_nominated"
+msgstr[0] "待批准元件 (%s)"
+
+#. %1 is the update count
+#: views/elements/developers/editorsqueue.thtml:43
+#: views/elements/developers/editorsmenu.thtml:57
+#, php-format
+msgid "devcp_editorsqueue_pendingupdates"
+msgid_plural "devcp_editorsqueue_pendingupdates"
+msgstr[0] "待審核更新 (%s)"
+
+#: controllers/statistics_controller.php:147
+#: controllers/statistics_controller.php:361
+#: controllers/previews_controller.php:108
+#: controllers/previews_controller.php:211
+#: controllers/previews_controller.php:312
+msgid "devcp_error_addon_access_denied"
+msgstr "您並無此附加元件的權é™ã€‚"
+
+#. %s is a complete URL with the text from devcp_error_appversion_reference_link_text
+#. in the <a> tag. This should be fixed.
+#: controllers/components/developers.php:591
+#, php-format
+msgid "devcp_error_appversion_reference_link"
+msgstr "è«‹åƒè€ƒ %s。"
+
+#. This is the link text in the <a> for devcp_error_appversion_reference_link. This
+#. should be fixed.
+#: controllers/components/developers.php:591
+msgid "devcp_error_appversion_reference_link_text"
+msgstr "æ­¤é é¢"
+
+#: views/developers/addon_edit_authors.thtml:76
+msgid "devcp_error_empty_authors"
+msgstr "您的元件至少è¦æœ‰ä¸€ä½æ“有者。"
+
+#. %1$s is the name of the file
+#: controllers/components/developers.php:658
+msgid "devcp_error_file_exists"
+msgstr "元件的這個版本已經存在,若è¦å–代它,您必須先刪除檔案 %1$s。"
+
+#. %1$s is a file extension. Example: .exe
+#. %2$s is a comma separated list of extensions. Example: .xpi, .jar
+#: controllers/components/developers.php:355
+#, php-format
+msgid "devcp_error_file_extension"
+msgstr "é¸æ“‡çš„元件類型ä¸æŽ¥å—這個副檔å(%1$s)。請使用下列中的一個:%2$s"
+
+#: controllers/components/developers.php:64
+msgid "devcp_error_five_categories"
+msgstr "è«‹å‹¿é¸æ“‡è¶…éŽäº”個分類。"
+
+#: controllers/components/developers.php:526
+msgid "devcp_error_guid_application"
+msgstr "此附加元件的 ID 已被應用程å¼æ‰€ä½¿ç”¨ã€‚"
+
+#: controllers/components/developers.php:337
+#: controllers/components/developers.php:389
+msgid "devcp_error_http_incomplete"
+msgstr "傳輸未完æˆ"
+
+#: controllers/components/developers.php:335
+#: controllers/components/developers.php:336
+#: controllers/components/developers.php:387
+#: controllers/components/developers.php:388
+msgid "devcp_error_http_maxupload"
+msgstr "上傳大å°è¶…éŽæœ€å¤§å€¼"
+
+#: controllers/components/developers.php:338
+#: controllers/components/developers.php:390
+msgid "devcp_error_http_nofile"
+msgstr "無檔案已上傳"
+
+#. %1$s is a file extension. Example: .exe
+#. %2$s is a comma separated list of extensions. Example: .xpi, .jar
+#: controllers/components/developers.php:401
+#, php-format
+msgid "devcp_error_icon_extension"
+msgstr "ä¸æŽ¥å—這個副檔å(%1$s)的圖示。請使用下列中的一個:%2$s"
+
+#: controllers/developers_controller.php:504
+msgid "devcp_error_index_rdf_notfound"
+msgstr "找ä¸åˆ° install.rdf 檔案。"
+
+#: controllers/components/developers.php:601
+msgid "devcp_error_install_manifest"
+msgstr "install.rdf 中å«æœ‰ä¸‹åˆ—錯誤:"
+
+#: controllers/developers_controller.php:1463
+msgid "devcp_error_invalid_addontype"
+msgstr ""
+
+#. %$1s is a version. Example: 3.1.1
+#. %$2s is an add-on name.
+#: controllers/components/developers.php:569
+#: controllers/components/developers.php:581
+#, php-format
+msgid "devcp_error_invalid_appversion"
+msgstr "%1$s ä¸æ˜¯æœ‰æ•ˆçš„ %2$s 版本"
+
+#. %s is a string
+#: controllers/components/developers.php:521
+#, php-format
+msgid "devcp_error_invalid_guid"
+msgstr "此附加元件的 ID 無效:%s"
+
+#. %$1s is a version. Example: 3.1.1
+#. %$2s is an add-on name.
+#: controllers/components/developers.php:572
+#, php-format
+msgid "devcp_error_invalid_minversion"
+msgstr "%1$s ä¸æ˜¯æœ‰æ•ˆçš„ %2$s 版本:最低版本ä¸èƒ½åŒ…å« *"
+
+#: controllers/components/developers.php:536
+msgid "devcp_error_invalid_version"
+msgstr ""
+"此附加元件版本號無效:請見 <a href=\"http://developer.mozilla.org/en/docs/"
+"Toolkit_version_format\">è¦æ ¼èªªæ˜Ž</a>"
+
+#: controllers/components/developers.php:531
+msgid "devcp_error_invalid_version_spaces"
+msgstr "此附加元件的版本號無效:版本號ä¸èƒ½æœ‰ç©ºç™½ã€‚"
+
+#. %s is an error message from the parser.
+#: controllers/components/developers.php:501
+#, php-format
+msgid "devcp_error_manifest_parse"
+msgstr "è§£æž install.rdf 時發生下列錯誤:%s"
+
+#: controllers/components/developers.php:373
+msgid "devcp_error_move_file"
+msgstr "無法移動檔案"
+
+#. %s is the name of a file
+#: controllers/components/developers.php:650
+#: controllers/components/developers.php:662
+#: controllers/components/developers.php:667
+#: controllers/components/developers.php:727
+#: controllers/components/developers.php:738
+#: controllers/components/developers.php:743
+#, php-format
+msgid "devcp_error_moving_file"
+msgstr "移動 %s 時發生錯誤。"
+
+#: controllers/components/developers.php:595
+msgid "devcp_error_mozilla_application"
+msgstr "您至少è¦é¸ä¸€å€‹æœ‰æ•ˆçš„ Mozilla 目標應用程å¼ã€‚"
+
+#: controllers/components/developers.php:516
+msgid "devcp_error_no_guid"
+msgstr "此附加元件的 install.rdf 中找ä¸åˆ° ID。"
+
+#: controllers/components/developers.php:287
+msgid "devcp_error_no_platform"
+msgstr "未é¸æ“‡ä½œæ¥­ç³»çµ±"
+
+#: controllers/components/developers.php:59
+msgid "devcp_error_one_category"
+msgstr "請至少é¸ä¸€é …分類。"
+
+#: controllers/components/developers.php:92
+msgid "devcp_error_one_user"
+msgstr "此附加元件至少è¦æœ‰ä¸€ä½ä½œè€…。"
+
+#. %1$s is a file extension. Example: .exe
+#. %2$s is a comma separated list of extensions. Example: .xpi, .jar
+#: controllers/components/developers.php:1081
+#, php-format
+msgid "devcp_error_preview_extension"
+msgstr "ä¸æŽ¥å—這個副檔å(%1$s)的é è¦½åœ–片。請使用下列中的一個:%2$s"
+
+#: controllers/components/developers.php:511
+msgid "devcp_error_updatekey"
+msgstr "附加元件ä¸èƒ½ä½¿ç”¨ updateKey,請將其從 install.rdf 中移除後å†è©¦ä¸€æ¬¡ã€‚"
+
+#: controllers/components/developers.php:506
+msgid "devcp_error_updateurl"
+msgstr ""
+"附加元件ä¸èƒ½ä½¿ç”¨å¤–部的 updateURL,請將其從 install.rdf 中移除後å†è©¦ä¸€æ¬¡ã€‚"
+
+#: controllers/developers_controller.php:465
+#: controllers/components/developers.php:271
+msgid "devcp_error_upload_file"
+msgstr "請上傳檔案。"
+
+#: views/developers/uploader.thtml:135
+msgid "devcp_input_upload_file"
+msgstr "上傳檔案"
+
+#: views/pages/js_constants.js.thtml:89
+msgid "devcp_js_a_cancel"
+msgstr "å–消"
+
+#: views/pages/js_constants.js.thtml:90
+msgid "devcp_js_add_email"
+msgstr "請輸入您想新增的作者的帳號 Email。"
+
+#. alt text for a down-arrow image.
+#: views/pages/js_constants.js.thtml:81
+msgid "devcp_js_img_move_down"
+msgstr "å‘下移"
+
+#. alt text for an up-arrow image.
+#: views/pages/js_constants.js.thtml:82
+msgid "devcp_js_img_move_up"
+msgstr "å‘上移"
+
+#: views/pages/js_constants.js.thtml:91
+msgid "devcp_js_img_remove_compat"
+msgstr "移除應用程å¼ç›¸å®¹æ€§"
+
+#: views/pages/js_constants.js.thtml:86
+msgid "devcp_js_input_list_author"
+msgstr "列為公開的作者"
+
+#: views/pages/js_constants.js.thtml:92
+msgid "devcp_js_license_select"
+msgstr "è«‹é¸æ“‡ä¸€å€‹æŽˆæ¬Šæ¢æ¬¾ã€‚"
+
+#: views/pages/js_constants.js.thtml:93
+msgid "devcp_js_license_text"
+msgstr "請輸入您授權æ¢æ¬¾çš„內文。"
+
+#. <option> text in a <select> for Author role in an add-on.
+#: views/pages/js_constants.js.thtml:84
+msgid "devcp_js_option_developer"
+msgstr "開發者"
+
+#. <option> text in a <select> for Author role in an add-on.
+#: views/pages/js_constants.js.thtml:83
+msgid "devcp_js_option_owner"
+msgstr "æ“有者"
+
+#. <option> text in a <select> for Author role in an add-on.
+#: views/pages/js_constants.js.thtml:85
+msgid "devcp_js_option_viewer"
+msgstr "檢視者"
+
+#: views/pages/js_constants.js.thtml:88
+msgid "devcp_js_remove_author"
+msgstr "移除作者"
+
+#: views/pages/js_constants.js.thtml:87
+msgid "devcp_js_sure_remove"
+msgstr "您<strong>確定</strong>è¦ç§»é™¤é€™ä½ä½œè€…嗎?"
+
+#: views/pages/js_constants.js.thtml:77
+msgid "devcp_js_upload_alert"
+msgstr "您必須é¸æ“‡è¦ä¸Šå‚³çš„檔案。"
+
+#. %1$s is an addon id, like 32.
+#. %2$s is a version number, like 3.5.
+#: controllers/components/developers.php:1212
+msgid "devcp_license_existing"
+msgstr "附加元件 %1$s 版本 %2$s 使用的自訂授權æ¢æ¬¾"
+
+#: views/elements/developers/localebox.thtml:44
+msgid "devcp_localebox_header_localizedfields"
+msgstr "在地化欄ä½"
+
+#. %1 is the default locale
+#: views/elements/developers/localebox.thtml:48
+#, php-format
+msgid "devcp_localebox_intro"
+msgstr ""
+"本é çš„æŸäº›æ¬„ä½å¯ç”¨ä½¿ç”¨è€…熟悉的語言顯示。請從下é¢çš„語言中é¸æ“‡æ‚¨è¦ç·¨è¼¯çš„元件詳細"
+"資訊,如果使用者é¸çš„語言沒有內容就會用é è¨­èªžè¨€ (%s) 顯示。"
+
+#: views/elements/developers/sidebar.thtml:68
+#: views/elements/developers/myaddons.thtml:75
+msgid "devcp_myaddons_admincp_link"
+msgstr "管ç†å“¡å·¥å…·"
+
+#: views/elements/developers/sidebar.thtml:65
+#: views/elements/developers/myaddons.thtml:72
+msgid "devcp_myaddons_editorcp_link"
+msgstr "審核者工具"
+
+#: views/elements/developers/myaddons.thtml:52
+msgid "devcp_myaddons_link"
+msgstr "我的附加元件"
+
+#: views/elements/developers/sidebar.thtml:70
+#: views/elements/developers/myaddons.thtml:77
+msgid "devcp_myaddons_mainpage_link"
+msgstr "回到主é é¢"
+
+#: views/elements/developers/sidebar.thtml:63
+#: views/elements/developers/myaddons.thtml:70
+msgid "devcp_myaddons_statistics_link"
+msgstr "統計資訊顯示æ¿"
+
+#: views/elements/developers/sidebar.thtml:62
+#: views/elements/developers/myaddons.thtml:69
+msgid "devcp_myaddons_submitaddon_link"
+msgstr "上傳附加元件"
+
+#: views/elements/developers/sidebar.thtml:48
+#: views/elements/developers/myaddons.thtml:67
+msgid "devcp_myaddons_title"
+msgstr "開發者工具"
+
+#. %1$s is an add-on ID, perhaps 167.
+#. %2$s is a URL.
+#: controllers/developers_controller.php:256
+msgid "devcp_new_addon_error"
+msgstr ""
+"資料庫中已經有這個元件 ID(%1$s)了。如果這是您的元件,您å¯ä»¥<a href=\"%2$s\">"
+"上傳新版本</a>。"
+
+#: views/developers/addon_status_nominate.thtml:62
+msgid "devcp_nominate_cancel"
+msgstr "å–消並返回"
+
+#. %1 is the add-on name
+#: views/developers/addon_status_nominate.thtml:61
+#, php-format
+msgid "devcp_nominate_submit_nominate"
+msgstr "é€äº¤æ‰¹å‡† %s"
+
+#: views/developers/addon_edit_properties.thtml:50
+#: views/developers/addon_status.thtml:49
+#: views/developers/versions_edit.thtml:50
+msgid "devcp_notice_changes_error"
+msgstr ""
+"<span>您有至少一個變更無法儲存。</span><br />請見下述錯誤,其餘變更已æˆåŠŸå„²"
+"存。"
+
+#: views/developers/addon_edit_authors.thtml:47
+#: views/developers/addon_edit_properties.thtml:47
+#: views/developers/addon_status.thtml:46
+#: views/developers/addon_edit_descriptions.thtml:47
+#: views/developers/versions_edit.thtml:47
+#: views/developers/addon_edit_categories.thtml:46
+msgid "devcp_notice_changes_saved"
+msgstr ""
+"<span>å·²æˆåŠŸå„²å­˜æ‚¨çš„變更。</span><br />請注æ„有些變更也許è¦éŽå¹¾å€‹å°æ™‚æ‰æœƒå‡ºç¾"
+"在網站的所有å€åŸŸä¸Šã€‚"
+
+#: controllers/previews_controller.php:252
+msgid "devcp_notice_cleardefault"
+msgstr "移除é è¨­é è¦½åœ–片將會使其他é è¦½åœ–片自動æˆç‚ºé è¨­åœ–片。"
+
+#: controllers/previews_controller.php:184
+#: controllers/previews_controller.php:251
+msgid "devcp_notice_makedefault"
+msgstr "將此圖片設為é è¨­é è¦½åœ–片將會å–消先å‰çš„é è¨­åœ–片設定。"
+
+#: views/developers/addon_edit_authors.thtml:70
+msgid "devcp_notice_unsaved_changes"
+msgstr "您有未儲存的變更。"
+
+#: controllers/developers_controller.php:87
+#: controllers/developers_controller.php:97
+#: controllers/developers_controller.php:100
+#: controllers/previews_controller.php:67
+#: controllers/previews_controller.php:79
+#: controllers/previews_controller.php:82
+msgid "devcp_pagetitle"
+msgstr "開發者工具"
+
+#: controllers/previews_controller.php:103
+#: controllers/previews_controller.php:104
+msgid "devcp_preview_add_pagetitle"
+msgstr "新增é è¦½åœ–片"
+
+#: controllers/previews_controller.php:135
+msgid "devcp_preview_added_successfully"
+msgstr "é è¦½åœ–片加入æˆåŠŸã€‚"
+
+#: controllers/previews_controller.php:323
+msgid "devcp_preview_deleted_successfully"
+msgstr "é è¦½åœ–片刪除æˆåŠŸã€‚"
+
+#: controllers/previews_controller.php:194
+#: controllers/previews_controller.php:195
+msgid "devcp_preview_edit_pagetitle"
+msgstr "編輯é è¦½åœ–片"
+
+#: controllers/previews_controller.php:237
+msgid "devcp_preview_updated_successfully"
+msgstr "é è¦½åœ–片更新æˆåŠŸã€‚"
+
+#: views/developers/previews.thtml:120
+msgid "devcp_previews_a_another"
+msgstr "新增其他é è¦½åœ–片"
+
+#: views/developers/previews.thtml:96
+msgid "devcp_previews_a_delete"
+msgstr "刪除é è¦½åœ–片"
+
+#: views/developers/previews.thtml:95
+msgid "devcp_previews_a_replace"
+msgstr "å–代é è¦½åœ–片"
+
+#: views/developers/previews.thtml:126
+msgid "devcp_previews_a_update"
+msgstr "æ›´æ–°é è¦½åœ–片"
+
+#: views/developers/previews.thtml:115 views/developers/previews.thtml:124
+msgid "devcp_previews_add_new"
+msgstr "新增é è¦½åœ–片"
+
+#. %s is a list of file extensions, e.g. ".png, .gif"
+#: views/developers/previews.thtml:116
+msgid "devcp_previews_add_select"
+msgstr ""
+"在下é¢é¸æ“‡ä¸€å¼µåœ–片上傳。超éŽå¯¬ 700 åƒç´ ã€é«˜ 525 åƒç´ çš„圖片將被é‡æ–°ç¸®æ”¾ã€‚å…許的"
+"檔案類型:%s"
+
+#: views/developers/previews.thtml:121
+msgid "devcp_previews_click_below"
+msgstr "按下é¢çš„「更新é è¦½åœ–片ã€é€²è¡Œä¸Šå‚³ã€‚"
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/previews.thtml:102
+msgid "devcp_previews_click_update"
+msgstr "按下é¢çš„「更新é è¦½åœ–片ã€æŒ‰éˆ•ä»¥å„²å­˜é€™å¼µåœ–片。(<a %s>å–消?</a>)"
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/previews.thtml:107
+msgid "devcp_previews_error_message"
+msgstr "按下「更新é è¦½åœ–片ã€å¾Œï¼Œé€™å¼µé è¦½åœ–片將被刪除。(<a %s>å–消?</a>)"
+
+#: views/previews/add.thtml:45
+msgid "devcp_previews_filetype_info"
+msgstr ""
+"請用下é¢çš„表單上傳格å¼ç‚º PNG, JPG 或 GIF 的附加元件é è¦½åœ–片。大於 700 x 525 åƒ"
+"素的圖片會自動縮å°ã€‚"
+
+#: views/previews/add.thtml:43
+msgid "devcp_previews_header_add"
+msgstr "新增é è¦½åœ–片"
+
+#: views/developers/previews.thtml:80
+msgid "devcp_previews_header_caption"
+msgstr "é è¦½åœ–片說明"
+
+#: views/previews/edit.thtml:43
+msgid "devcp_previews_header_edit"
+msgstr "編輯é è¦½åœ–片"
+
+#: views/developers/previews.thtml:93
+msgid "devcp_previews_label_default"
+msgstr "é è¨­é è¦½åœ–片"
+
+#: views/previews/add.thtml:54
+msgid "devcp_previews_label_file"
+msgstr "é è¦½åœ–片檔案"
+
+#: views/previews/add.thtml:59 views/previews/edit.thtml:50
+msgid "devcp_previews_label_makedefault"
+msgstr "設為é è¨­é è¦½åœ–片"
+
+#: views/developers/previews.thtml:100
+msgid "devcp_previews_label_new"
+msgstr "新增圖片:"
+
+#: views/developers/previews.thtml:118
+msgid "devcp_previews_label_upload"
+msgstr "上傳é è¦½åœ–片:"
+
+#: views/developers/previews.thtml:50
+msgid "devcp_previews_notice_error"
+msgstr "您有至少一張新的é è¦½åœ–片無法儲存。"
+
+#: views/developers/previews.thtml:47
+msgid "devcp_previews_notice_success"
+msgstr "å·²æˆåŠŸæ›´æ–°æ‚¨çš„é è¦½åœ–片。"
+
+#: views/developers/previews.thtml:59
+msgid "devcp_previews_p_screenshots"
+msgstr ""
+"下é¢é¡¯ç¤ºçš„是您元件的é è¦½æ“·åœ–,您å¯ä»¥å°èªªæ˜Žæˆ–圖片進行修改。æœå°‹å’Œç€è¦½æ¸…單時,"
+"「é è¨­é è¦½åœ–片ã€æœƒå‡ºç¾åœ¨æ‚¨çš„元件æ—邊。"
+
+#: views/previews/edit.thtml:55
+msgid "devcp_previews_submit_delete"
+msgstr "刪除é è¦½åœ–片"
+
+#: views/previews/edit.thtml:55
+msgid "devcp_previews_submit_delete_confirm"
+msgstr "您確定è¦åˆªé™¤æ­¤åœ–片嗎?"
+
+#: views/previews/edit.thtml:54
+msgid "devcp_previews_submit_edit"
+msgstr "編輯é è¦½åœ–片"
+
+#: views/previews/add.thtml:63
+msgid "devcp_previews_submit_upload"
+msgstr "上傳é è¦½åœ–片"
+
+#: views/developers/previews.thtml:78
+msgid "devcp_previews_thumbnail"
+msgstr "縮圖"
+
+#. %s is the add-on name.
+#: views/developers/previews.thtml:44
+msgid "devcp_previews_title"
+msgstr "%s é è¦½åœ–片管ç†å“¡"
+
+#: views/developers/uploader.thtml:74
+msgid "devcp_review_agreement_please"
+msgstr "繼續使用å‰è«‹å…ˆç€è¦½ä¸¦æŽ¥å—下é¢çš„開發者授權åˆç´„。"
+
+#: views/elements/developers/rolecheck.thtml:42
+msgid "devcp_rolecheck_no_privs"
+msgstr ""
+"<span>您沒有足夠的權é™è®Šæ›´é€™å€‹é é¢ã€‚</span><br />如果您需è¦ä¿®æ”¹ï¼Œè«‹è¯ç¹«å…ƒä»¶æ“"
+"有者。"
+
+#: controllers/developers_controller.php:1315
+msgid "devcp_several_hours"
+msgstr "請注æ„有些變更也許è¦éŽå¹¾å€‹å°æ™‚æ‰æœƒå‡ºç¾åœ¨ç¶²ç«™çš„所有å€åŸŸä¸Šã€‚"
+
+#: views/elements/developers/sidebar.thtml:52
+msgid "devcp_sidebar_a_dashboard"
+msgstr "資訊顯示æ¿"
+
+#. %s is a number
+#: views/elements/developers/statsbar.thtml:45
+#: views/developers/dashboard.thtml:79
+#, php-format
+msgid "devcp_statsbar_adu"
+msgstr "æ¯æ—¥æœ‰æ•ˆä½¿ç”¨è€…:<em>%s</em>"
+
+#. %s is a number
+#: views/elements/developers/statsbar.thtml:41
+#: views/developers/dashboard.thtml:75
+#, php-format
+msgid "devcp_statsbar_total_downloads"
+msgstr "總下載次數:<em>%s</em>"
+
+#. %s is a number
+#: views/elements/developers/statsbar.thtml:43
+#: views/developers/dashboard.thtml:77
+#, php-format
+msgid "devcp_statsbar_weekly_downloads"
+msgstr "本週下載數:<em>%s</em>"
+
+#: views/developers/addon_status_confirm.thtml:59
+msgid "devcp_status_confirm_active"
+msgstr ""
+"將這個元件設為「活動中ã€æœƒä½¿å®ƒå‡ºç¾åœ¨ç‹€æ…‹ç›¸ç¬¦çš„公開å€åŸŸï¼ŒåŒ…括æœå°‹èˆ‡ç€è¦½æ¸…單。根"
+"據元件的狀態,網站將æ供下載,並在客戶端檢查更新時傳é€å…ƒä»¶ã€‚您需è¦çš„時候,也å¯"
+"以å†å›žåˆ°é€™è£¡åœç”¨å®ƒã€‚"
+
+#: views/developers/addon_status_confirm.thtml:59
+msgid "devcp_status_confirm_active_sure"
+msgstr "您確定è¦å°‡é€™å€‹å…ƒä»¶è¨­ç‚ºã€Œæ´»å‹•ä¸­ã€å—Žï¼Ÿ"
+
+#: views/developers/addon_status_confirm.thtml:50
+msgid "devcp_status_confirm_header_sure"
+msgstr "您確定嗎?"
+
+#: views/developers/addon_status_confirm.thtml:55
+msgid "devcp_status_confirm_inactive"
+msgstr ""
+"將這個元件設為「éžæ´»å‹•ä¸­ã€æœƒè®“它ä¸å†å‡ºç¾æ–¼ä»»ä½•å…¬é–‹å€åŸŸï¼ŒåŒ…括æœå°‹èˆ‡ç€è¦½æ¸…單。網"
+"站將ä¸æ供下載,也ä¸æœƒåœ¨å®¢æˆ¶ç«¯æª¢æŸ¥æ›´æ–°æ™‚傳é€å…ƒä»¶ã€‚您需è¦çš„時候,也å¯ä»¥å†å›žåˆ°é€™"
+"裡啟用它。"
+
+#: views/developers/addon_status_confirm.thtml:55
+msgid "devcp_status_confirm_inactive_sure"
+msgstr "您確定è¦å°‡é€™å€‹å…ƒä»¶è¨­ç‚ºã€Œéžæ´»å‹•ä¸­ã€å—Žï¼Ÿ"
+
+#: views/developers/addon_status_confirm.thtml:74
+msgid "devcp_status_confirm_no"
+msgstr "ä¸ï¼Œç®—了"
+
+#: views/developers/addon_status_confirm.thtml:67
+msgid "devcp_status_confirm_public"
+msgstr "公開這個元件將讓所有人都能下載,並å°æ—¢æœ‰çš„使用者æ供更新。"
+
+#: views/developers/addon_status_confirm.thtml:67
+msgid "devcp_status_confirm_public_sure"
+msgstr "您確定è¦ã€Œå…¬é–‹ã€é€™å€‹å…ƒä»¶å—Žï¼Ÿ"
+
+#: views/developers/addon_status_confirm.thtml:63
+msgid "devcp_status_confirm_sandbox"
+msgstr ""
+"將這個元件移回「沙箱ã€å€æœƒè¦æ±‚使用者先登入æ‰èƒ½ä¸‹è¼‰ï¼Œä¹Ÿå°‡åœæ­¢æä¾›å°æ—¢æœ‰ä½¿ç”¨è€…çš„"
+"更新。由於您的元件目å‰æ˜¯å…¬é–‹çš„,您å¯ä»¥éš¨æ™‚回來這裡å†åº¦å…¬é–‹å®ƒã€‚"
+
+#: views/developers/addon_status_confirm.thtml:63
+msgid "devcp_status_confirm_sandbox_sure"
+msgstr "您確定è¦å°‡é€™å€‹å…ƒä»¶ç§»è‡³ã€Œæ²™ç®±ã€å€å—Žï¼Ÿ"
+
+#: views/developers/addon_status_confirm.thtml:73
+msgid "devcp_status_confirm_yes"
+msgstr "是的,我確定"
+
+#: views/developers/addon_status_nominate.thtml:46
+msgid "devcp_status_nominate_error_notice"
+msgstr ""
+"<span>需è¦é€äº¤æ‰¹å‡†è¨Šæ¯ã€‚</span><br />請在文字欄ä½å…§å¡«å¯«éœ€è¦çš„資訊後å†è©¦ã€‚"
+
+#: views/developers/addon_status_nominate.thtml:55
+msgid "devcp_status_nominate_header"
+msgstr "元件批准"
+
+#: views/developers/dashboard.thtml:85
+msgid "devcp_summary_lastversion"
+msgstr "最新版本:"
+
+#. %s is the add-on name.
+#: views/developers/addon_edit.thtml:43
+#: views/developers/addon_edit_authors.thtml:44
+#: views/developers/versions_delete.thtml:43
+#: views/developers/addon_edit_properties.thtml:44
+#: views/developers/addon_edit_descriptions.thtml:44
+#: views/developers/versions_edit.thtml:44
+#: views/developers/addon_edit_categories.thtml:43
+#: views/developers/versions.thtml:43
+msgid "devcp_title_edit_addon"
+msgstr "編輯 %s"
+
+#. title attribute for a javascript link that pops up a help dialog.
+#: views/elements/translationbox.thtml:68
+msgid "devcp_transbox_a_title_help"
+msgstr "說明(ä¸é›¢é–‹é é¢ï¼‰"
+
+#: views/elements/translationbox.thtml:68
+msgid "devcp_transbox_alt_help"
+msgstr "說明"
+
+#. %1$s is <span>17</span>, %2$s is 42.
+#: views/elements/translationbox.thtml:101
+msgid "devcp_transbox_chars_used"
+msgstr "已使用字元數:%1$s / %2$s"
+
+#: views/elements/translationbox.thtml:132
+msgid "devcp_transbox_delete_sure"
+msgstr "您確定è¦åˆªé™¤é€™å€‹ç¿»è­¯å—Žï¼Ÿ"
+
+#. %s is a locale, like en-US.
+#: views/elements/translationbox.thtml:143
+msgid "devcp_transbox_help_header_tabs"
+msgstr "這些 %s é ç±¤æ˜¯ä»€éº¼ï¼Ÿ"
+
+#: views/elements/translationbox.thtml:145
+msgid "devcp_transbox_help_header_what"
+msgstr "如果我沒有任何翻譯的話呢?"
+
+#: views/elements/translationbox.thtml:147
+msgid "devcp_transbox_help_hide"
+msgstr "éš±è—說明"
+
+#: views/elements/translationbox.thtml:146
+msgid "devcp_transbox_help_if"
+msgstr ""
+"如果使用者ç€è¦½ç¶²ç«™æ™‚沒有å¯ç”¨çš„翻譯,就會變回您在「編輯元件屬性ã€å€æŒ‡å®šçš„é è¨­èªž"
+"言。如果您沒有任何翻譯,就輸入您會的é è¨­èªžè¨€å³å¯ï¼Œå®ƒæ‡‰è©²æ˜¯æ‚¨å¹³æ™‚說的語言。"
+
+#: views/elements/translationbox.thtml:144
+msgid "devcp_transbox_help_transbox"
+msgstr ""
+"這個是<i>翻譯方塊</i>,讓您使用手上的翻譯將特定欄ä½æœ¬åœ°åŒ–。您å¯ä»¥ç”¨é€™äº›èªžè¨€é "
+"籤新增ã€ç·¨è¼¯å’Œç§»é™¤ç¿»è­¯ã€‚"
+
+#: views/elements/translationbox.thtml:85
+msgid "devcp_transbox_img_add_trans"
+msgstr "新增翻譯"
+
+#: views/elements/translationbox.thtml:86
+msgid "devcp_transbox_img_remove_trans"
+msgstr "移除翻譯"
+
+#: views/elements/translationbox.thtml:123
+msgid "devcp_transbox_input_add_all"
+msgstr "新增語言至全部"
+
+#: views/elements/translationbox.thtml:122
+msgid "devcp_transbox_input_add_locale"
+msgstr "新增語言"
+
+#: views/elements/translationbox.thtml:124
+#: views/elements/translationbox.thtml:135
+msgid "devcp_transbox_input_cancel"
+msgstr "å–消"
+
+#: views/elements/translationbox.thtml:134
+msgid "devcp_transbox_input_delete"
+msgstr "刪除"
+
+#: views/elements/translationbox.thtml:113
+msgid "devcp_transbox_select_locale"
+msgstr "é¸æ“‡è¦æ–°å¢žç¿»è­¯çš„語言:"
+
+#. %1$s and %2$s are GUIDs.
+#: controllers/developers_controller.php:343
+msgid "devcp_update_addon_guid_error"
+msgstr "這個檔案(%1$s)的元件 GUID 與既有元件(%2$s)的 GUID ä¸ç¬¦ã€‚"
+
+#: controllers/developers_controller.php:334
+msgid "devcp_update_addon_priv_error"
+msgstr "您沒有足夠的權é™æ›´æ–°é€™å€‹å…ƒä»¶ã€‚"
+
+#. %1$s is a version number, %2$s is an add-on ID.
+#: controllers/developers_controller.php:399
+msgid "devcp_update_addon_version_belong_error"
+msgstr "指定的版本(%1$s)ä¸å±¬æ–¼é€™å€‹å…ƒä»¶ï¼ˆ%2$s)。"
+
+#. %1$s is a version number, maybe 1.1.
+#. %2$s is a URL.
+#: controllers/developers_controller.php:351
+msgid "devcp_update_addon_version_exists_error"
+msgstr ""
+"元件的這個版本(%1$s)已經存在了,如果您è¦ç‚ºé€™å€‹ç‰ˆæœ¬æ–°å¢žå¦ä¸€å€‹æª”案,<a href="
+"\"%2$s\">按一下這裡</a>。"
+
+#. %1$s and %2$s are version numbers.
+#: controllers/developers_controller.php:405
+msgid "devcp_update_addon_version_match_error"
+msgstr "上傳檔案的版本號(%1$s)與既有的版本號(%2$s)ä¸ç¬¦ã€‚"
+
+#: views/developers/uploader.thtml:68
+msgid "devcp_uploader_a_start"
+msgstr "開始"
+
+#: views/developers/uploader.thtml:137
+msgid "devcp_uploader_ajax_loading"
+msgstr "正在上傳檔案…"
+
+#: views/developers/uploader.thtml:82
+msgid "devcp_uploader_button_agree"
+msgstr "åŒæ„並繼續"
+
+#: views/developers/uploader.thtml:157
+msgid "devcp_uploader_button_edit"
+msgstr "編輯我的元件"
+
+#: views/developers/uploader.thtml:158
+msgid "devcp_uploader_button_later"
+msgstr "我會ç¨å¾Œå®Œæˆæˆ‘的元件。"
+
+#: views/developers/uploader.thtml:168
+msgid "devcp_uploader_button_release"
+msgstr "新增版本資訊"
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/uploader.thtml:156
+msgid "devcp_uploader_created_results"
+msgstr ""
+"<p>å·²æˆåŠŸå»ºç«‹æ‚¨å…ƒä»¶çš„清單。由您的上傳檔案中å–得的基本資訊已被儲存,但ä»æœ‰è¨±å¤š"
+"資訊是å¯è‡ªè¨‚的。</p><p>元件目å‰è¢«æ¨™è¨˜ç‚ºã€Œ<strong>未完æˆ</strong>ã€ï¼Œè¦å®Œæˆæ‚¨çš„"
+"元件,您需è¦ç¢ºèªå®ƒæœ‰æ˜Žç¢ºçš„å稱ã€æ‘˜è¦ã€æ•˜è¿°ï¼Œä¸”至少é¸æ“‡ä¸€å€‹åˆ†é¡žã€‚您å¯ä»¥ç”¨ä»¥ä¸‹éˆ"
+"çµç·¨è¼¯å…ƒä»¶è³‡è¨Šï¼Œä¸”隨時都å¯ä»¥åœ¨<a %s>狀態é é¢</a>檢查元件狀態。"
+
+#: views/developers/uploader.thtml:143
+msgid "devcp_uploader_error_correct"
+msgstr "請修正這個å•é¡Œå¾Œå†ä¸Šå‚³æª”案。"
+
+#. %1$s is a version number, %2$s is a status, e.g Public or Incomplete.
+#: views/developers/uploader.thtml:175
+msgid "devcp_uploader_file_created"
+msgstr "您的新檔案已加入版本 %1$s,目å‰è¢«æ¨™è¨˜ç‚º%2$s。"
+
+#: views/developers/uploader.thtml:154
+msgid "devcp_uploader_header_created"
+msgstr "元件已建立ï¼"
+
+#: views/developers/uploader.thtml:141
+msgid "devcp_uploader_header_error"
+msgstr "å“Žå‘€ï¼é€™å€‹æª”案似乎有些å•é¡Œâ€¦"
+
+#: views/developers/uploader.thtml:173
+msgid "devcp_uploader_header_file_added"
+msgstr "檔案已新增ï¼"
+
+#: views/developers/uploader.thtml:66
+msgid "devcp_uploader_header_how"
+msgstr "這是如何é‹ä½œçš„?"
+
+#. %s is the version number, e.g. 3.2.
+#: views/developers/uploader.thtml:163
+msgid "devcp_uploader_header_update_created"
+msgstr "已建立版本 %s"
+
+#: views/developers/uploader.thtml:117
+msgid "devcp_uploader_header_upload"
+msgstr "上傳您的檔案"
+
+#: views/developers/uploader.thtml:67
+msgid "devcp_uploader_how"
+msgstr ""
+"<p>æ„Ÿè¬æ‚¨å¸Œæœ›å°‡ä¸Šå‚³å…ƒä»¶åˆ° Mozilla 附加元件網站。將元件放在 Mozilla 附加元件是"
+"發佈元件最簡單的方å¼ã€‚您將得到以下的功能:</p><ul><li>æ¯å€‹å…ƒä»¶å°‡æœ‰å„自的公開顯"
+"示é é¢ï¼Œå…§å®¹åŒ…å«å…ƒä»¶åŠŸèƒ½çš„簡短摘è¦ã€å¯é¸ç”¨çš„較長敘述ã€é è¦½æ“·åœ–的展示等您æ供的"
+"資訊。</li><li>您的元件會出ç¾åœ¨ç¶²ç«™çš„æœå°‹èˆ‡ç€è¦½æ¸…單,甚至於 Firefox 3 的附加元"
+"件管ç†å“¡ã€‚</li><li>我們會用心地æ供下載æœå‹™ï¼Œä¸¦åœ¨æ‚¨ä¸Šå‚³æ–°ç‰ˆæœ¬æ™‚æ供自動更新。"
+"</li><li>您å¯ä»¥å­˜å–統計資訊顯示æ¿ï¼Œçž­è§£é—œæ–¼ä½¿ç”¨è€…的詳細資訊。</li></ul><p>放在"
+"ç¶²ç«™çš„å…ƒä»¶å¿…é ˆç¶“éŽ Mozilla 附加元件網站審核者的批准,æ‰èƒ½æ“有上述全部功能。如"
+"果您已經準備好進行這個æµç¨‹ï¼Œä¸¦ä¸”已經準備好了è¦ä¸Šå‚³çš„元件檔案,就按下é¢çš„「開"
+"始ã€å§ï¼</p>"
+
+#: views/developers/uploader.thtml:125
+msgid "devcp_uploader_label_platformtype"
+msgstr "支æ´çš„作業系統:"
+
+#: views/developers/uploader.thtml:124
+msgid "devcp_uploader_label_upload_field"
+msgstr "元件檔案:"
+
+#: controllers/components/developers.php:1221
+msgid "devcp_uploader_option_other"
+msgstr "其它"
+
+#. %1$s is a number, %2$s is href="..." and should stay in the <a> tag.
+#: views/developers/uploader.thtml:176
+msgid "devcp_uploader_p_pending_file"
+msgstr ""
+"一當審核者å¯ä»¥é€²è¡Œå¯©æ ¸æ™‚,就會公開這個新檔案。目å‰æœ‰ %1$s 個其他元件正在排隊。"
+"希望審核快一點嗎?ä¸å¦‚<a %2$s>æˆç‚ºå¯©æ ¸è€…</a>å§ã€‚"
+
+#. %1$s is a number, %2$s is href="..." and should stay in the <a> tag.
+#: views/developers/uploader.thtml:166
+msgid "devcp_uploader_p_pending_version"
+msgstr ""
+"一當審核者å¯ä»¥é€²è¡Œå¯©æ ¸æ™‚,就會公開這個新版本。目å‰æœ‰ %1$s 個其他元件正在排隊。"
+"希望審核快一點嗎?ä¸å¦‚<a %2$s>æˆç‚ºå¯©æ ¸è€…</a>å§ã€‚"
+
+#. %s is a status, e.g Public or Incomplete.
+#: views/developers/uploader.thtml:165
+msgid "devcp_uploader_p_update_created"
+msgstr "已建立您的新版本,目å‰è¢«æ¨™è¨˜ç‚º%s。"
+
+#. %1$s is href="..." and should stay in the 'Versions and Files' <a> tag.
+#. %2$s is href="..." and should stay in the 'current status' <a> tag.
+#: views/developers/uploader.thtml:177
+msgid "devcp_uploader_p_update_file"
+msgstr ""
+"在<a %1$s>「版本與檔案ã€é é¢</a>檢視您的新檔案ã€æª¢æŸ¥æ‚¨å…ƒä»¶çš„<a %2$s>ç›®å‰ç‹€æ…‹</"
+"a>,或按下é¢çš„按鈕<b>新增版本資訊</b>(相當建議)。"
+
+#. %1$s is href="..." and should stay in the 'Versions and Files' <a> tag.
+#. %2$s is href="..." and should stay in the 'current status' <a> tag.
+#: views/developers/uploader.thtml:167
+msgid "devcp_uploader_p_update_version"
+msgstr ""
+"在<a %1$s>「版本與檔案ã€é é¢</a>檢視您的新版本ã€æª¢æŸ¥æ‚¨å…ƒä»¶çš„<a %2$s>ç›®å‰ç‹€æ…‹</"
+"a>,或按下é¢çš„按鈕<b>新增版本資訊</b>(相當建議)。"
+
+#: views/developers/uploader.thtml:118
+msgid "devcp_uploader_p_upload"
+msgstr ""
+"使用下é¢çš„表單上傳您的元件。如果您有多個ã€ç‚ºç‰¹å®šä½œæ¥­ç³»çµ±è¨­è¨ˆçš„檔案,先é¸æ“‡å…¶ä¸­"
+"之一,å†ä½¿ç”¨ã€Œç‰ˆæœ¬èˆ‡æª”案管ç†å“¡ã€ä¸Šå‚³å…¶ä»–的。"
+
+#: views/developers/uploader.thtml:125
+msgid "devcp_uploader_platformtype_all"
+msgstr "全部"
+
+#: views/developers/uploader.thtml:126
+msgid "devcp_uploader_platformtype_specific"
+msgstr "é©ç”¨æ–¼ï¼š"
+
+#. Used as first item in a <select>.
+#: controllers/components/developers.php:1185
+msgid "devcp_uploader_please_choose"
+msgstr "è«‹é¸æ“‡â€¦"
+
+#. %1$s is the add-on name, %2$s is the version number.
+#: views/developers/uploader.thtml:57
+msgid "devcp_uploader_title_file"
+msgstr "新增檔案至 %1$s %2$s"
+
+#: views/developers/uploader.thtml:50
+msgid "devcp_uploader_title_submit"
+msgstr "é€å‡ºæ–°å…ƒä»¶"
+
+#. %s is the add-on name.
+#: views/developers/uploader.thtml:54
+msgid "devcp_uploader_title_update"
+msgstr "æ›´æ–° %s"
+
+#. %s is a full <a> tag
+#: controllers/developers_controller.php:503
+#, php-format
+msgid "devcp_valid_app_reference"
+msgstr "è«‹ç€è¦½ %s 閱讀åƒè€ƒè³‡è¨Šã€‚"
+
+#. This is the text in the <a> tag for devcp_valid_app_reference. This should be
+#. fixed.
+#: controllers/developers_controller.php:503
+msgid "devcp_valid_app_reference_linktext"
+msgstr "æ­¤é é¢"
+
+#: controllers/developers_controller.php:581
+msgid "devcp_verify_author_error"
+msgstr "找ä¸åˆ°ç¬¦åˆé€™å€‹ Email 地å€çš„帳號。"
+
+#: controllers/developers_controller.php:553
+msgid "devcp_verify_search_engine_error"
+msgstr ""
+"XML 無效或éºå¤±å¿…è¦çš„欄ä½ã€‚è«‹<a href=\"https://developer.mozilla.org/en/"
+"Creating_OpenSearch_plugins_for_Firefox\">閱讀文件</a>並檢查您的附加元件後,å†"
+"é‡æ–°å˜—試。"
+
+#: views/developers/versions.thtml:75
+msgid "devcp_versions_a_cancel"
+msgstr "å–消"
+
+#: views/developers/versions.thtml:79
+msgid "devcp_versions_a_delete"
+msgstr "刪除版本"
+
+#: views/developers/versions.thtml:74
+msgid "devcp_versions_a_empty"
+msgstr "移除空的版本"
+
+#: views/developers/versions.thtml:71
+msgid "devcp_versions_a_remove"
+msgstr "移除?"
+
+#: views/developers/versions.thtml:91
+msgid "devcp_versions_add"
+msgstr "新增版本"
+
+#: views/developers/versions_delete.thtml:58
+msgid "devcp_versions_delete_a_cancel"
+msgstr "å–消"
+
+#: views/developers/versions_delete.thtml:56
+msgid "devcp_versions_delete_a_delete"
+msgstr "刪除版本"
+
+#. Followed by a list of reviews and files that will be removed.
+#: views/developers/versions_delete.thtml:50
+msgid "devcp_versions_delete_also"
+msgstr "將一併刪除:"
+
+#: views/developers/versions_delete.thtml:53
+msgid "devcp_versions_delete_files"
+msgid_plural "devcp_versions_delete_files"
+msgstr[0] "%s 個檔案"
+
+#. %s is the version number.
+#: views/developers/versions_delete.thtml:48
+msgid "devcp_versions_delete_header"
+msgstr "刪除版本 %s?"
+
+#: views/developers/versions_delete.thtml:52
+msgid "devcp_versions_delete_reviews"
+msgid_plural "devcp_versions_delete_reviews"
+msgstr[0] "%s 則æ„見"
+
+#. %s is the version number.
+#: views/developers/versions_delete.thtml:49
+msgid "devcp_versions_delete_sure"
+msgstr "您確定è¦æ°¸ä¹…刪除版本 %s 嗎?"
+
+#: views/developers/versions_edit.thtml:102
+#: views/developers/versions_edit.thtml:155
+msgid "devcp_versions_edit_a_cancel"
+msgstr "å–消"
+
+#: views/developers/versions_edit.thtml:101
+msgid "devcp_versions_edit_a_delete"
+msgstr "刪除檔案"
+
+#: views/developers/versions_edit.thtml:165
+msgid "devcp_versions_edit_a_new_app"
+msgstr "新增應用程å¼"
+
+#: views/developers/versions_edit.thtml:154
+msgid "devcp_versions_edit_a_remove_app"
+msgstr "移除應用程å¼"
+
+#: views/developers/versions_edit.thtml:114
+msgid "devcp_versions_edit_add"
+msgstr "新增檔案"
+
+#. %s is href=... and should stay in the <a> tag.
+#: views/developers/versions_edit.thtml:121
+msgid "devcp_versions_edit_adjust"
+msgstr ""
+"調整這裡的應用程å¼è³‡è¨Šæœƒå…許使用者安è£æ‚¨çš„元件,å³ä½¿æª”案中的 install.rdf 指出"
+"元件是ä¸ç›¸å®¹çš„。 <a %s>支æ´çš„應用程å¼åˆ—表</a>"
+
+#: views/developers/versions_edit.thtml:153
+msgid "devcp_versions_edit_compat_sure"
+msgstr "您<b>確定</b>è¦ç§»é™¤å°é€™å€‹æ‡‰ç”¨ç¨‹å¼çš„相容性嗎?"
+
+#: views/developers/versions_edit.thtml:100
+msgid "devcp_versions_edit_delete_sure"
+msgstr "您<b>確定</b>è¦æ°¸ä¹…刪除這個檔案嗎?"
+
+#: views/developers/versions_edit.thtml:203
+msgid "devcp_versions_edit_header_approval"
+msgstr "審核資訊"
+
+#: views/developers/versions_edit.thtml:120
+msgid "devcp_versions_edit_header_compat"
+msgstr "相容的應用程å¼"
+
+#: views/developers/versions_edit.thtml:74
+msgid "devcp_versions_edit_header_file"
+msgstr "檔案資訊"
+
+#: views/developers/versions_edit.thtml:189
+msgid "devcp_versions_edit_header_license"
+msgstr "授權æ¢æ¬¾"
+
+#. %s is the version number.
+#: views/developers/versions_edit.thtml:53
+msgid "devcp_versions_edit_header_manage"
+msgstr "管ç†ç‰ˆæœ¬ %s"
+
+#: views/developers/versions_edit.thtml:212
+msgid "devcp_versions_edit_header_notes"
+msgstr "審核註解"
+
+#: views/developers/versions_edit.thtml:98
+msgid "devcp_versions_edit_img_delete"
+msgstr "刪除檔案"
+
+#. %1$s is the file id, e.g. 18723.
+#. %2$s is the platform name, e.g. ALL or Windows.
+#. %3$s is the _('date) created.
+#. %4$s is the status, e.g. "In Sandbox" or "Public".
+#. %5$s is the _('date') status was changed.
+#: views/developers/versions_edit.thtml:208
+msgid "devcp_versions_edit_li_file"
+msgstr "檔案 %1$s(%2$s)建立於 %3$s,於 %5$s 變更為%4$s"
+
+#: views/developers/versions_edit.thtml:190
+msgid "devcp_versions_edit_license_description"
+msgstr ""
+"請為您的附加元件é¸æ“‡ä¸€å€‹é©ç•¶çš„授權æ¢æ¬¾ã€‚該授權æ¢æ¬¾è¦å®šäº†æ‚¨åœ¨åŽŸå§‹ç¢¼æ–¹é¢æ‰€çµ¦äºˆçš„"
+"權利。"
+
+#: views/developers/versions_edit.thtml:111
+msgid "devcp_versions_edit_no_files"
+msgstr "找ä¸åˆ°æª”案。"
+
+#: views/developers/versions_edit.thtml:213
+msgid "devcp_versions_edit_optional"
+msgstr "æ供給此版本審核者的資訊(å¯ä¸æ供)。"
+
+#: views/developers/versions_edit.thtml:151
+msgid "devcp_versions_edit_remove_compat"
+msgstr "移除應用程å¼ç›¸å®¹æ€§"
+
+#: views/developers/versions_edit.thtml:167
+msgid "devcp_versions_edit_select_app"
+msgstr "è«‹é¸æ“‡ä¸€å€‹æ‡‰ç”¨ç¨‹å¼"
+
+#: views/developers/versions_edit.thtml:78
+msgid "devcp_versions_edit_th_file"
+msgstr "檔案"
+
+#: views/developers/versions_edit.thtml:79
+msgid "devcp_versions_edit_th_platform"
+msgstr "作業系統"
+
+#: views/developers/versions_edit.thtml:80
+msgid "devcp_versions_edit_th_size"
+msgstr "大å°"
+
+#: views/developers/versions_edit.thtml:81
+msgid "devcp_versions_edit_th_status"
+msgstr "狀態"
+
+#: views/developers/versions_edit.thtml:183
+msgid "devcp_versions_edit_transbox_releasenotes_description"
+msgstr ""
+"關於這個版本的新功能ã€å·²çŸ¥å•é¡ŒåŠå…¶ä»–有用資訊。使用 Firefox 3 附加元件管ç†å“¡æ›´"
+"新的使用者也能看到這個資訊。"
+
+#: views/developers/versions_edit.thtml:182
+msgid "devcp_versions_edit_transbox_releasenotes_name"
+msgstr "版本資訊"
+
+#: views/developers/versions_edit.thtml:164
+msgid "devcp_versions_edit_unsaved_compat"
+msgstr ""
+"<strong>您有未儲存的變更。</strong>除éžæ‚¨æŒ‰ä¸‹é¢çš„「更新版本ã€ï¼Œå¦å‰‡ç›¸å®¹æ€§ä¸æœƒ"
+"被刪除。"
+
+#: views/developers/versions_edit.thtml:113
+msgid "devcp_versions_edit_unsaved_files"
+msgstr ""
+"<strong>您有未儲存的變更。</strong>除éžæ‚¨æŒ‰ä¸‹é¢çš„「更新版本ã€ï¼Œå¦å‰‡æª”案ä¸æœƒè¢«"
+"刪除。"
+
+#: views/developers/versions_edit.thtml:218
+msgid "devcp_versions_edit_update"
+msgstr "更新版本"
+
+#: views/developers/versions.thtml:49
+msgid "devcp_versions_header_manage"
+msgstr "管ç†ç‰ˆæœ¬èˆ‡æª”案"
+
+#: views/developers/versions.thtml:87
+msgid "devcp_versions_no_versions"
+msgstr "沒有版本。"
+
+#. %s is a version number, base 10.
+#: views/developers/versions.thtml:46
+msgid "devcp_versions_notice_success"
+msgstr "å·²æˆåŠŸåˆªé™¤ç‰ˆæœ¬ %s。"
+
+#: views/developers/versions.thtml:73
+msgid "devcp_versions_p_remove"
+msgstr "這個版本沒有相關的檔案,å¯ä»¥è¢«ç§»é™¤ã€‚您è¦ç§»é™¤é€™å€‹ç‰ˆæœ¬å—Žï¼Ÿ"
+
+#: views/developers/versions.thtml:58
+msgid "devcp_versions_th_created"
+msgstr "已建立"
+
+#: views/developers/versions.thtml:57
+msgid "devcp_versions_th_status"
+msgstr "狀態"
+
+#: views/developers/versions.thtml:56
+msgid "devcp_versions_th_version"
+msgstr "版本"
+
+#: controllers/downloads_controller.php:91
+msgid "downloads_disable_warning"
+msgstr "此附加元件已åœç”¨"
+
+#: controllers/components/editors.php:57
+msgid "editor_review_error_addon_not_nominated"
+msgstr "這個元件還沒有被é€äº¤æ‰¹å‡†ã€‚"
+
+#: controllers/components/editors.php:213
+msgid "editor_review_error_file_not_pending"
+msgstr "這個元件並未等待審核。"
+
+#. Actions are, for example: approving or rejecting
+#: controllers/components/editors.php:79 controllers/components/editors.php:182
+msgid "editor_review_error_no_action"
+msgstr "è«‹é¸æ“‡ä¸€å€‹å¯©æ ¸è¡Œå‹•ã€‚"
+
+#: controllers/components/editors.php:192
+msgid "editor_review_error_no_applications"
+msgstr "請輸入您測試用的應用程å¼ã€‚"
+
+#. Comments are required when an editor approves or rejects an add-on.
+#: controllers/components/editors.php:84 controllers/components/editors.php:187
+msgid "editor_review_error_no_comments"
+msgstr "請輸入審核æ„見。"
+
+#: controllers/components/editors.php:161
+msgid "editor_review_error_no_files"
+msgstr "請至少é¸ä¸€å€‹æª”案審核。"
+
+#: controllers/components/editors.php:197
+msgid "editor_review_error_no_operating_system"
+msgstr "請輸入您測試用的作業系統。"
+
+#: views/editors/logs.thtml:51
+msgid "editorcp_logs_button_filter"
+msgstr "éŽæ¿¾æ¢ä»¶"
+
+#: views/editors/logs.thtml:44
+msgid "editorcp_logs_filter_by"
+msgstr "ä¾é¡žåž‹â•±å‹•ä½œéŽæ¿¾"
+
+#: views/editors/logs.thtml:42 controllers/editors_controller.php:964
+msgid "editorcp_logs_page_heading"
+msgstr "事件記錄"
+
+#: views/elements/developers/editorsmenu.thtml:60
+msgid "editorcp_menu_eventlog_link"
+msgstr "事件記錄"
+
+#: views/elements/developers/editorsmenu.thtml:62
+msgid "editorcp_menu_mainpage_link"
+msgstr "回到主é¸å–®"
+
+#: views/elements/developers/editorsmenu.thtml:61
+msgid "editorcp_menu_reviewlog_link"
+msgstr "審核記錄"
+
+#: views/elements/developers/editorsmenu.thtml:55
+msgid "editorcp_menu_summary_link"
+msgstr "審核者摘è¦"
+
+#: views/elements/developers/editorsmenu.thtml:52
+msgid "editorcp_menu_title"
+msgstr "審核者工具"
+
+#: views/editors/reviewlog.thtml:49
+msgid "editorcp_reviewlog_button_filter"
+msgstr "éŽæ¿¾æ¢ä»¶"
+
+#: views/editors/reviewlog.thtml:58
+msgid "editorcp_reviewlog_column_action"
+msgstr "動作"
+
+#: views/editors/reviewlog.thtml:56
+msgid "editorcp_reviewlog_column_addon"
+msgstr "附加元件"
+
+#: views/editors/reviewlog.thtml:55
+msgid "editorcp_reviewlog_column_date"
+msgstr "日期"
+
+#: views/editors/reviewlog.thtml:57
+msgid "editorcp_reviewlog_column_editor"
+msgstr "審核者"
+
+#: views/editors/reviewlog.thtml:94
+msgid "editorcp_reviewlog_comments_hide"
+msgstr "éš±è—留言"
+
+#: views/editors/reviewlog.thtml:93
+msgid "editorcp_reviewlog_comments_show"
+msgstr "顯示留言"
+
+#. %1$s and %2$s are full <input> tags for dates
+#: views/editors/reviewlog.thtml:45
+#, php-format
+msgid "editorcp_reviewlog_entries_between"
+msgstr "檢視從 %1$s 到 %2$s 的項目"
+
+#: views/editors/reviewlog.thtml:104
+msgid "editorcp_reviewlog_none_found"
+msgstr "此日期間無審核記錄。"
+
+#: views/editors/reviewlog.thtml:42
+msgid "editorcp_reviewlog_page_heading"
+msgstr "審核記錄"
+
+#: views/editors/summary.thtml:61
+msgid "editorcp_summary_monthreviews_heading"
+msgstr "æ¯æœˆå¯©æ ¸"
+
+#: views/editors/summary.thtml:77
+msgid "editorcp_summary_neweditors_heading"
+msgstr "新審核者"
+
+#: views/editors/summary.thtml:42
+msgid "editorcp_summary_page_heading"
+msgstr "審核者摘è¦"
+
+#: views/editors/summary.thtml:94
+msgid "editorcp_summary_recentactivity_heading"
+msgstr "最近審核者動態"
+
+#: views/editors/summary.thtml:45
+msgid "editorcp_summary_totalreviews_heading"
+msgstr "所有審核"
+
+#: controllers/editors_controller.php:248
+#: controllers/editors_controller.php:249
+msgid "editors_addon_review_pagetitle"
+msgstr "審核附加元件"
+
+#: controllers/editors_controller.php:349
+msgid "editors_error_js-formerror"
+msgstr "請完æˆä¸‹é¢çš„欄ä½ï¼š"
+
+#: controllers/editors_controller.php:350
+msgid "editors_error_review_one_file"
+msgstr "請至少é¸ä¸€å€‹æª”案審核。"
+
+#: controllers/editors_controller.php:274
+msgid "editors_error_self_reviews_forbidden"
+msgstr "ä¸å…許自己審核自己。"
+
+#: controllers/editors_controller.php:699
+msgid "editors_external_software"
+msgstr "外部軟體支æ´"
+
+#: views/editors/featured.thtml:120 views/editors/featured.thtml:121
+msgid "editors_featured_add_feature"
+msgstr "新增精é¸å…ƒä»¶"
+
+#: views/editors/featured.thtml:126
+msgid "editors_featured_add_feature_submit"
+msgstr "新增"
+
+#: views/editors/featured.thtml:49 controllers/editors_controller.php:832
+#: controllers/editors_controller.php:848
+msgid "editors_featured_addon_add_failure"
+msgstr "新增精é¸å…ƒä»¶å¤±æ•—。"
+
+#: controllers/editors_controller.php:851
+msgid "editors_featured_addon_add_success"
+msgstr "新增精é¸å…ƒä»¶æˆåŠŸã€‚"
+
+#: views/editors/featured.thtml:50 controllers/editors_controller.php:839
+#: controllers/editors_controller.php:868
+#: controllers/editors_controller.php:886
+msgid "editors_featured_addon_edit_failure"
+msgstr "編輯精é¸å…ƒä»¶å¤±æ•—。"
+
+#: views/editors/featured.thtml:51 controllers/editors_controller.php:888
+msgid "editors_featured_addon_edit_success"
+msgstr "編輯精é¸å…ƒä»¶æˆåŠŸã€‚"
+
+#: views/editors/featured.thtml:53 controllers/editors_controller.php:861
+msgid "editors_featured_addon_invalid_locale"
+msgstr "一個以上的語言無效。"
+
+#: views/editors/featured.thtml:52 controllers/editors_controller.php:906
+msgid "editors_featured_addon_remove_failure"
+msgstr "移除精é¸å…ƒä»¶å¤±æ•—。"
+
+#: controllers/editors_controller.php:901
+msgid "editors_featured_addon_remove_success"
+msgstr "移除精é¸å…ƒä»¶æˆåŠŸã€‚"
+
+#: controllers/editors_controller.php:915
+#: controllers/editors_controller.php:917
+msgid "editors_featured_addons_pagetitle"
+msgstr "ç²¾é¸é™„加元件"
+
+#: views/editors/featured.thtml:54 views/editors/featured.thtml:107
+msgid "editors_featured_edit_feature_submit"
+msgstr "è¡"
+
+#: views/editors/featured.thtml:90 views/editors/featured.thtml:91
+msgid "editors_featured_remove_feature"
+msgstr "移除精é¸å…ƒä»¶"
+
+#: views/editors/queue.thtml:46
+msgid "editors_filter_queue"
+msgstr "佇列éŽæ¿¾æ¢ä»¶"
+
+#: views/editors/queue.thtml:182
+msgid "editors_helpful_links"
+msgstr "一些有幫助的éˆçµ"
+
+#: views/editors/queue.thtml:182
+msgid "editors_link_guide"
+msgstr "審核者指å—"
+
+#: views/editors/queue.thtml:182
+msgid "editors_link_policy"
+msgstr "附加元件政策"
+
+#: views/editors/queue.thtml:47
+msgid "editors_notice_filter_session"
+msgstr "這些éŽæ¿¾æ¢ä»¶æœƒä¿ç•™åˆ°é—œé–‰ç€è¦½å™¨æˆ–手動清除。"
+
+#. %1 is the queue mode
+#: views/editors/queue.thtml:177 views/admin/flagged_queue.thtml:89
+msgid "editors_notice_none_found"
+msgstr "ç›®å‰æ²’有 %s 附加元件待審核。"
+
+#: controllers/editors_controller.php:1040
+msgid "editors_one_day"
+msgstr "1 天"
+
+#: controllers/editors_controller.php:1048
+msgid "editors_one_hour"
+msgstr "1 å°æ™‚"
+
+#: controllers/editors_controller.php:1056
+msgid "editors_one_minute"
+msgstr "1 分"
+
+#: controllers/editors_controller.php:64 controllers/editors_controller.php:73
+#: controllers/editors_controller.php:77
+msgid "editors_pagetitle"
+msgstr "審核者工具"
+
+#. %s is a comma separated list of platforms. Example: Windows, OS X
+#: controllers/editors_controller.php:680
+#: controllers/editors_controller.php:683
+#, php-format
+msgid "editors_platform_x_only"
+msgstr "%s 專用"
+
+#: controllers/editors_controller.php:695
+msgid "editors_pre-release"
+msgstr "發行å‰ç‰ˆæœ¬ï¼ˆPre-release)"
+
+#. %1 is the app name
+#: views/editors/queue.thtml:131
+#, php-format
+msgid "editors_queue_app_compatibility"
+msgstr "相容於 %s"
+
+#: views/editors/queue.thtml:51
+msgid "editors_queue_filter_label_addon"
+msgstr "附加元件或作者 Email"
+
+#: views/editors/queue.thtml:72
+msgid "editors_queue_filter_label_addontypes"
+msgstr "附加元件種類"
+
+#: views/editors/queue.thtml:56
+msgid "editors_queue_filter_label_application"
+msgstr "應用程å¼"
+
+#: views/editors/queue.thtml:61
+msgid "editors_queue_filter_label_maxversion"
+msgstr "Max. Version"
+
+#: views/editors/queue.thtml:78
+msgid "editors_queue_filter_label_platforms"
+msgstr "作業系統"
+
+#: views/editors/queue.thtml:66
+msgid "editors_queue_filter_label_submissionage"
+msgstr "傳é€æ™‚間(日)"
+
+#. %1$s is a number
+#: views/editors/queue.thtml:90
+msgid "editors_queue_filter_result_count"
+msgid_plural "editors_queue_filter_result_count"
+msgstr[0] "éŽæ¿¾å¾Œçš„æœå°‹çµæžœï¼š <strong>%1$s</strong> 個附加元件"
+
+#: views/editors/queue.thtml:84
+msgid "editors_queue_submit_clean"
+msgstr "清除"
+
+#: views/editors/queue.thtml:83
+msgid "editors_queue_submit_filter"
+msgstr "éŽæ¿¾æ¢ä»¶"
+
+#: controllers/editors_controller.php:133
+msgid "editors_queues_disabled"
+msgstr "所有審核佇列目å‰å·²åœç”¨ï¼Œè«‹ç¨å¾Œå†å›žä¾†æŸ¥çœ‹ã€‚"
+
+#: views/editors/review.thtml:149
+msgid "editors_review_a_edit_item"
+msgstr "編輯項目"
+
+#: views/editors/review.thtml:146
+msgid "editors_review_a_item_history"
+msgstr "項目歷å²"
+
+#: views/editors/review.thtml:148
+msgid "editors_review_a_item_homepage"
+msgstr "項目首é "
+
+#: views/editors/review.thtml:145
+msgid "editors_review_a_item_overview"
+msgstr "項目概觀"
+
+#: views/editors/review.thtml:147
+msgid "editors_review_a_previews"
+msgstr "é è¦½åœ–片"
+
+#: controllers/editors_controller.php:345
+msgid "editors_review_action"
+msgstr "審核動作"
+
+#: views/editors/review.thtml:159
+msgid "editors_review_action_info"
+msgstr "請求更多資訊"
+
+#: views/editors/review.thtml:157
+msgid "editors_review_action_public"
+msgstr "é€è‡³ã€Œå…¬é–‹ã€å€"
+
+#: views/editors/review.thtml:160
+msgid "editors_review_action_request_superreview"
+msgstr "é€äº¤ç®¡ç†å“¡å¯©æ ¸"
+
+#: views/editors/review.thtml:158
+msgid "editors_review_action_sandbox"
+msgstr "退回「沙箱ã€å€"
+
+#: controllers/editors_controller.php:346
+msgid "editors_review_comments"
+msgstr "審核者留言"
+
+#: views/editors/review.thtml:182
+msgid "editors_review_details_info_request"
+msgstr ""
+"使用這個表單å‘ä½œè€…è«‹æ±‚æ›´å¤šè³‡è¨Šï¼Œä»–å€‘æœƒæ”¶åˆ°ä¸€å° Email 並能在此答覆。當他們回應"
+"時,您將收到 Email 通知。"
+
+#: views/editors/review.thtml:174
+msgid "editors_review_details_nominated_public"
+msgstr ""
+"這個é¸é …會讓附加元件最新版本和其檔案放上「公開ã€å€ï¼Œä½†å¾ŒçºŒæ›´æ–°ç‰ˆæœ¬é‚„是會先é€åˆ°"
+"「沙箱ã€å€ç­‰å¾…審核者批准。"
+
+#: views/editors/review.thtml:177
+msgid "editors_review_details_nominated_sandbox"
+msgstr "這個é¸é …會將附加元件留在「沙箱ã€å€ã€‚"
+
+#: views/editors/review.thtml:166
+msgid "editors_review_details_pending_public"
+msgstr "這個é¸é …會附加元件在「沙箱ã€å€çš„待審核版本放上「公開ã€å€ã€‚"
+
+#: views/editors/review.thtml:169
+msgid "editors_review_details_pending_sandbox"
+msgstr "這個é¸é …會讓附加元件在「沙箱ã€å€çš„待審核版本留在「沙箱ã€å€ã€‚"
+
+#: views/editors/review.thtml:185
+msgid "editors_review_details_superreview"
+msgstr ""
+"如果您覺得此附加元件有安全上ã€ç‰ˆæ¬Šä¸Šçš„疑慮或其他需è¦ç®¡ç†å“¡è™•ç†çš„å•é¡Œï¼Œè«‹åœ¨ä¸‹é¢"
+"輸入您的留言。這會直接é€äº¤çµ¦ç®¡ç†å“¡è™•ç†ã€‚"
+
+#: views/editors/review.thtml:134
+msgid "editors_review_file_diff_link"
+msgstr "與公開版本比較"
+
+#: views/editors/review.thtml:131
+msgid "editors_review_file_viewcontents_link"
+msgstr "檢視內容"
+
+#: views/editors/review.thtml:65
+msgid "editors_review_header_authors"
+msgstr "作者:"
+
+#: views/editors/review.thtml:79
+msgid "editors_review_header_categories"
+msgstr "分類:"
+
+#: views/editors/review.thtml:92
+msgid "editors_review_header_compatibility"
+msgstr "相容於:"
+
+#: views/editors/review.thtml:251
+msgid "editors_review_header_description"
+msgstr "敘述:"
+
+#: views/editors/review.thtml:275
+msgid "editors_review_header_devcomments"
+msgstr "開發者留言"
+
+#: views/editors/review.thtml:263
+msgid "editors_review_header_eula"
+msgstr "授權åˆç´„"
+
+#: views/editors/review.thtml:115
+msgid "editors_review_header_files"
+msgstr "檔案:"
+
+#: views/editors/review.thtml:284
+msgid "editors_review_header_itemhistory"
+msgstr "項目歷å²"
+
+#: views/editors/review.thtml:232
+msgid "editors_review_header_nominationmessage"
+msgstr "é€äº¤æ‰¹å‡†è¨Šæ¯"
+
+#: views/editors/review.thtml:311
+msgid "editors_review_header_previews"
+msgstr "é è¦½åœ–片"
+
+#: views/editors/review.thtml:269
+msgid "editors_review_header_privacy"
+msgstr "éš±ç§æ”¿ç­–"
+
+#. %1 is the add-on name and version
+#: views/editors/review.thtml:56
+#, php-format
+msgid "editors_review_header_review"
+msgstr "審核 %s"
+
+#: views/editors/review.thtml:239
+msgid "editors_review_header_reviewernotes"
+msgstr "給審核者的留言"
+
+#: views/editors/review.thtml:245
+msgid "editors_review_header_summary"
+msgstr "摘è¦"
+
+#: views/editors/review.thtml:257
+msgid "editors_review_header_versionnotes"
+msgstr "版本資訊"
+
+#. a noun: shown in an add-on's editor review history
+#: views/elements/developers/editors_review_history_item.thtml:80
+msgid "editors_review_history_info_reply"
+msgstr "回覆"
+
+#: views/elements/developers/editors_review_history_item.thtml:78
+msgid "editors_review_history_info_request"
+msgstr "資訊請求"
+
+#: views/elements/developers/editors_review_history_item.thtml:62
+#: views/editors/reviewlog.thtml:77
+msgid "editors_review_history_nominated_adminreview"
+msgstr "é€ç®¡ç†å“¡å¯©æ ¸"
+
+#: views/elements/developers/editors_review_history_item.thtml:56
+#: views/editors/reviewlog.thtml:71
+msgid "editors_review_history_nominated_approved"
+msgstr "批准通éŽï¼å…¬é–‹å€"
+
+#: views/elements/developers/editors_review_history_item.thtml:59
+#: views/editors/reviewlog.thtml:74
+msgid "editors_review_history_nominated_denied"
+msgstr "批准失敗ï¼æ²™ç®±å€"
+
+#: views/editors/review.thtml:303
+msgid "editors_review_history_nonefound"
+msgstr "找ä¸åˆ°å…ˆå‰çš„審核記錄。"
+
+#: views/elements/developers/editors_review_history_item.thtml:73
+#: views/editors/reviewlog.thtml:88
+msgid "editors_review_history_pending_adminreview"
+msgstr "é€ç®¡ç†å“¡å¯©æ ¸"
+
+#: views/elements/developers/editors_review_history_item.thtml:67
+#: views/editors/reviewlog.thtml:82
+msgid "editors_review_history_pending_approved"
+msgstr "å·²åŒæ„ï¼å…¬é–‹å€"
+
+#: views/elements/developers/editors_review_history_item.thtml:70
+#: views/editors/reviewlog.thtml:85
+msgid "editors_review_history_pending_denied"
+msgstr "已拒絕ï¼æ²™ç®±å€"
+
+#. link text in an add-on's editor review history, allowing to hide and show an information request's replies
+#. %1 is the number of replies
+#: views/elements/developers/editors_review_history_item.thtml:90
+msgid "editors_review_history_show_hide_replies"
+msgid_plural "editors_review_history_show_hide_replies"
+msgstr[0] "顯示ï¼éš±è—回覆(%1$s)"
+
+#: views/editors/review.thtml:208
+msgid "editors_review_label_applications"
+msgstr "應用程å¼ï¼š"
+
+#: views/editors/review.thtml:196
+msgid "editors_review_label_cannedresponse"
+msgstr "或é¸ä¸€å€‹å›žè¦†è¨Šæ¯ï¼š"
+
+#: views/editors/review.thtml:190
+msgid "editors_review_label_comments"
+msgstr "留言:"
+
+#: views/editors/review.thtml:204
+msgid "editors_review_label_operating_systems"
+msgstr "作業系統:"
+
+#: views/editors/review.thtml:285 views/editors/review.thtml:312
+msgid "editors_review_link_pagetop"
+msgstr "回頂端"
+
+#: views/editors/review.thtml:141
+msgid "editors_review_mulitple_notice"
+msgstr "注æ„:唯有當您已測試「æ¯ä¸€å€‹ã€æ‰€é¸æ“‡çš„檔案時,æ‰å¯©æ ¸å¤šæ–¼ä¸€å€‹æª”案。"
+
+#: views/editors/review.thtml:51
+msgid "editors_review_next_link"
+msgstr "ä¸‹ä¸€é  &raquo;"
+
+#: views/editors/review.thtml:322
+msgid "editors_review_previews_notfound"
+msgstr "ç„¡é è¦½åœ–片。"
+
+#: views/editors/review.thtml:50
+msgid "editors_review_previous_link"
+msgstr "&laquo; 上一é "
+
+#: controllers/editors_controller.php:144
+#: controllers/editors_controller.php:146
+msgid "editors_review_queue_pagetitle"
+msgstr "審核佇列"
+
+#. %1 is the add-ons rank in the queue, %2 is the total queue length
+#: views/editors/review.thtml:47
+msgid "editors_review_rank_in_queue"
+msgstr "在 %2$s 篇中排行 <strong># %1$s</strong>"
+
+#. %1 is the add-ons rank in the queue, %2 is the total queue length. Both numbers
+#: views/editors/review.thtml:45
+msgid "editors_review_rank_in_queue_filtered"
+msgstr "在 %2$s 篇中排行 <strong># %1$s</strong> (éŽæ¿¾å¾Œï¼‰"
+
+#: views/editors/review.thtml:223
+msgid "editors_review_submit_process_action"
+msgstr "處ç†å‹•ä½œ"
+
+#: views/editors/review.thtml:293
+msgid "editors_review_th_action"
+msgstr "動作"
+
+#: views/editors/review.thtml:294
+msgid "editors_review_th_comments"
+msgstr "留言"
+
+#: views/editors/review.thtml:291
+msgid "editors_review_th_date"
+msgstr "日期"
+
+#: views/editors/review.thtml:292
+msgid "editors_review_th_reviewer"
+msgstr "審核者"
+
+#: views/editors/review.thtml:290
+msgid "editors_review_th_version_file"
+msgstr "版本ï¼æª”案"
+
+#: views/editors/review.thtml:217
+msgid "editors_review_update_notify_once"
+msgstr "這個元件下次更新時通知我。(之後的更新將ä¸æœƒå¯„é€ Email)"
+
+#: controllers/editors_controller.php:298
+msgid "editors_reviewed_successfully"
+msgstr "審核已æˆåŠŸã€‚"
+
+#: views/editors/reviews_queue.thtml:106
+msgid "editors_reviews_action_delete_review"
+msgstr "刪除æ„見"
+
+#: views/editors/reviews_queue.thtml:104
+msgid "editors_reviews_action_keep"
+msgstr "刪除回報;ä¿ç•™æ„見"
+
+#: views/editors/reviews_queue.thtml:102
+msgid "editors_reviews_action_skip"
+msgstr "ç•¥éŽ"
+
+#: views/editors/reviews_queue.thtml:100
+msgid "editors_reviews_header_action"
+msgstr "動作"
+
+#: views/editors/reviews_queue.thtml:67
+msgid "editors_reviews_in_reply_to"
+msgstr "回覆:"
+
+#: controllers/editors_controller.php:748
+msgid "editors_reviews_processed"
+msgstr "審核已æˆåŠŸè™•ç†ï¼"
+
+#: views/editors/reviews_queue.thtml:117
+msgid "editors_reviews_queue_empty"
+msgstr "ç›®å‰æ²’有待審核項目。"
+
+#: views/editors/reviews_queue.thtml:111
+msgid "editors_reviews_submit_process_reviews"
+msgstr "處ç†å¯©æ ¸"
+
+#: controllers/editors_controller.php:691
+msgid "editors_site_specific"
+msgstr "為特定網站設計"
+
+#: controllers/editors_controller.php:348
+msgid "editors_tested_app"
+msgstr "已測試應用程å¼"
+
+#: controllers/editors_controller.php:347
+msgid "editors_tested_os"
+msgstr "已測試作業系統"
+
+#: views/editors/queue.thtml:151
+msgid "editors_th_additional_info"
+msgstr "附加資訊"
+
+#: views/editors/featured.thtml:63 views/editors/queue.thtml:109
+#: views/admin/flagged_queue.thtml:53
+msgid "editors_th_addon"
+msgstr "附加元件"
+
+#: views/editors/queue.thtml:125
+msgid "editors_th_addontype"
+msgstr "種類"
+
+#: views/editors/featured.thtml:64
+msgid "editors_th_locales"
+msgstr "é™åˆ¶èªžè¨€ï¼Ÿ"
+
+#: views/editors/queue.thtml:148
+msgid "editors_th_nomination_age"
+msgstr "排隊時間"
+
+#: views/editors/queue.thtml:101 views/editors/queue.thtml:117
+#: views/editors/queue.thtml:144
+msgid "editors_th_sort_ascending"
+msgstr "å‡å†ªæŽ’åº"
+
+#: views/editors/queue.thtml:105 views/editors/queue.thtml:121
+#: views/editors/queue.thtml:140
+msgid "editors_th_sort_descending"
+msgstr "é™å†ªæŽ’åº"
+
+#. %s is a number
+#: controllers/editors_controller.php:1036
+#, php-format
+msgid "editors_x_days"
+msgstr "%s 天"
+
+#. %s is a number
+#: controllers/editors_controller.php:1044
+#, php-format
+msgid "editors_x_hours"
+msgstr "%s å°æ™‚"
+
+#. %s is a number
+#: controllers/editors_controller.php:1052
+#, php-format
+msgid "editors_x_minutes"
+msgstr "%s 分"
+
+#: views/errors/error401.thtml:50 controllers/components/simple_acl.php:81
+#: controllers/components/simple_acl.php:82
+#: controllers/components/simple_acl.php:83 controllers/components/amo.php:607
+#: controllers/components/amo.php:608 controllers/components/amo.php:609
+#: controllers/reviews_controller.php:353
+#: controllers/reviews_controller.php:485
+#: controllers/collections_controller.php:438
+#: controllers/collections_controller.php:496
+#: controllers/collections_controller.php:504
+#: controllers/collections_controller.php:971
+#: controllers/collections_controller.php:1034
+#: controllers/collections_controller.php:1077
+msgid "error_access_denied"
+msgstr "å­˜å–被拒絕"
+
+#: views/errors/error401.thtml:52
+msgid "error_access_denied_message"
+msgstr "您未經授權檢視此é é¢ã€‚"
+
+#: controllers/collections_controller.php:1039
+msgid "error_addon_exists"
+msgstr "附加元件已經存在ï¼"
+
+#: controllers/developers_controller.php:200
+#: controllers/developers_controller.php:593
+#: controllers/developers_controller.php:1016
+#: controllers/developers_controller.php:1429
+#: controllers/downloads_controller.php:95
+#: controllers/downloads_controller.php:102
+#: controllers/downloads_controller.php:164
+#: controllers/statistics_controller.php:135
+#: controllers/previews_controller.php:115
+#: controllers/previews_controller.php:206
+#: controllers/previews_controller.php:307
+#: controllers/reviews_controller.php:77 controllers/reviews_controller.php:240
+#: controllers/reviews_controller.php:332
+#: controllers/reviews_controller.php:340 controllers/api_controller.php:123
+#: controllers/api_controller.php:759 controllers/addons_controller.php:131
+#: controllers/addons_controller.php:197 controllers/addons_controller.php:1407
+#: controllers/addons_controller.php:1465
+#: controllers/addons_controller.php:1469
+#: controllers/addons_controller.php:1503
+#: controllers/editors_controller.php:265
+#: controllers/collections_controller.php:1041
+#: controllers/collections_controller.php:1074
+msgid "error_addon_notfound"
+msgstr "找ä¸åˆ°é™„加元件ï¼"
+
+#: controllers/files_controller.php:83 controllers/files_controller.php:196
+msgid "error_addon_notviewable"
+msgstr "此附加元件無法在此ç€è¦½ã€‚"
+
+#: controllers/reviews_controller.php:246
+msgid "error_addon_selfreview"
+msgstr "您無法å°æ‚¨è‡ªå·±çš„附加元件發表æ„見。"
+
+#: controllers/addons_controller.php:970
+msgid "error_browse_no_addons"
+msgstr "此分類無附加元件ï¼"
+
+#: controllers/api_controller.php:424
+msgid "error_collection_feed_notfound"
+msgstr "沒有找到附加元件的消æ¯ä¾†æºã€‚"
+
+#: views/users/register.thtml:65 views/users/edit.thtml:194
+msgid "error_email_invalid"
+msgstr "Email 地å€ç„¡æ•ˆã€‚"
+
+#: views/users/pwreset.thtml:74 views/users/register.thtml:70
+#: views/users/register.thtml:80 views/users/register.thtml:86
+#: views/users/edit.thtml:105 views/users/edit.thtml:111
+#: views/users/edit.thtml:192 views/admin/users_edit.thtml:78
+#: views/admin/users_edit.thtml:83 views/reviews/add.thtml:80
+#: views/reviews/add.thtml:104
+msgid "error_field_required"
+msgstr "此欄ä½ä¸èƒ½ç•™ç©ºã€‚"
+
+#: controllers/files_controller.php:75 controllers/files_controller.php:93
+#: controllers/files_controller.php:96 controllers/files_controller.php:163
+#: controllers/files_controller.php:176 controllers/files_controller.php:185
+#: controllers/files_controller.php:204 controllers/editors_controller.php:412
+msgid "error_file_notfound"
+msgstr "找ä¸åˆ°æª”案ï¼"
+
+#. %s is a filename
+#: controllers/editors_controller.php:430
+#, php-format
+msgid "error_file_x_notfound"
+msgstr "檔案錯誤:%s ä¸å­˜åœ¨ã€‚"
+
+#: views/collections/add.thtml:55 views/collections/edit.thtml:89
+#: views/users/register.thtml:54 views/users/edit.thtml:81
+#: views/reviews/add.thtml:70 controllers/groups_controller.php:80
+#: controllers/groups_controller.php:102
+msgid "error_formerrors"
+msgstr "此表單中有錯誤,請更正後å†é€å‡ºä¸€æ¬¡ã€‚"
+
+#: views/users/register.thtml:109
+msgid "error_invalid_captcha"
+msgstr "錯誤的圖形檢核碼,請å†è©¦ä¸€æ¬¡ï¼"
+
+#: views/users/register.thtml:100 views/users/edit.thtml:125
+#: views/admin/users_edit.thtml:101
+msgid "error_invalid_url"
+msgstr "URL æ ¼å¼ç„¡æ•ˆï¼Œæœ‰æ•ˆçš„ URL åƒé€™æ¨£ï¼š htt_p://example.com/mypage。"
+
+#. %s is a string representing what's missing. Example: file_id
+#: controllers/downloads_controller.php:65 controllers/users_controller.php:185
+#: controllers/users_controller.php:264 controllers/users_controller.php:559
+#: controllers/users_controller.php:653 controllers/reviews_controller.php:71
+#: controllers/reviews_controller.php:234
+#: controllers/reviews_controller.php:325
+#: controllers/reviews_controller.php:473
+#: controllers/reviews_controller.php:475 controllers/addons_controller.php:182
+#: controllers/addons_controller.php:1381
+#: controllers/addons_controller.php:1455
+#: controllers/collections_controller.php:266
+#: controllers/collections_controller.php:285
+#: controllers/collections_controller.php:346
+#: controllers/collections_controller.php:443
+#: controllers/collections_controller.php:482
+#: controllers/collections_controller.php:936
+#: controllers/collections_controller.php:959
+#: controllers/collections_controller.php:960
+#: controllers/collections_controller.php:975
+#: controllers/collections_controller.php:977
+#: controllers/collections_controller.php:994
+#: controllers/collections_controller.php:1003
+#: controllers/collections_controller.php:1016
+#: controllers/collections_controller.php:1017
+#: controllers/collections_controller.php:1024
+#: controllers/collections_controller.php:1070
+#: controllers/collections_controller.php:1090
+#, php-format
+msgid "error_missing_argument"
+msgstr "缺少åƒæ•¸ï¼š%s"
+
+#: controllers/components/amo.php:507 controllers/components/amo.php:532
+msgid "error_no_files_in_addon"
+msgstr "沒有檔案"
+
+#: controllers/previews_controller.php:200
+msgid "error_preview_notfound"
+msgstr "找ä¸åˆ°é è¦½åœ–片ï¼"
+
+#: views/addons/display.thtml:400 views/reviews/add.thtml:98
+msgid "error_review_rating_required"
+msgstr "您必須é¸ä¸€å€‹è©•åˆ†ã€‚"
+
+#: controllers/users_controller.php:160
+msgid "error_user_already_confirmed"
+msgstr "此使用者帳號已確èªã€‚"
+
+#: controllers/users_controller.php:202 controllers/users_controller.php:276
+#: controllers/users_controller.php:569 controllers/users_controller.php:581
+#: controllers/users_controller.php:587 controllers/users_controller.php:610
+#: controllers/users_controller.php:627
+msgid "error_user_badconfirmationcode"
+msgstr "確èªç¢¼ç„¡æ•ˆï¼"
+
+#: views/users/pwreset.thtml:79 views/users/register.thtml:75
+#: views/users/edit.thtml:183
+msgid "error_user_confirmpw_nomatch"
+msgstr "密碼ä¸ç¬¦ã€‚"
+
+#: views/users/register.thtml:65 views/users/edit.thtml:190
+#: controllers/users_controller.php:617
+msgid "error_user_email_notunique"
+msgstr "æ­¤ Email 地å€å·²è¢«å…¶ä»–使用者使用。"
+
+#: controllers/users_controller.php:596
+msgid "error_user_emailchange_expired"
+msgstr ""
+"Email 變更éˆçµå·²éŽæœŸã€‚請到使用者帳號é é¢å†è®Šæ›´ä¸€æ¬¡ Email 地å€å¾Œï¼Œæˆ‘們會寄給您"
+"一å°ç¢ºèªä¿¡ï¼Œè«‹å„˜å¿«æŒ‰ä¸‹ä¿¡ä¸­çš„éˆçµè®Šæ›´æ‰ç®—生效。"
+
+#: controllers/collections_controller.php:985
+msgid "error_user_exists"
+msgstr "使用者一次åªèƒ½æ‰®æ¼”一個角色。請在繼續å‰å°‡ä½¿ç”¨è€…從任何既存的角色中移除。"
+
+#: views/users/register.thtml:91 views/users/edit.thtml:116
+#: views/admin/users_edit.thtml:88
+msgid "error_user_nickname_notunique"
+msgstr "此暱稱已被使用。"
+
+#: views/users/pwreset.thtml:54 controllers/users_controller.php:191
+#: controllers/users_controller.php:270 controllers/users_controller.php:603
+#: controllers/users_controller.php:659
+#: controllers/collections_controller.php:988
+#: controllers/collections_controller.php:998
+msgid "error_user_notfound"
+msgstr "找ä¸åˆ°ä½¿ç”¨è€…ï¼"
+
+#: views/users/activatefirst.thtml:47
+msgid "error_user_unconfirmed"
+msgstr "請先用您收到的確èªç¢¼ç¢ºèªæ‚¨çš„使用者帳號。"
+
+#: views/users/login.thtml:67
+msgid "error_username_or_pw_wrong"
+msgstr "使用者å稱或密碼錯誤ï¼"
+
+#: controllers/editors_controller.php:260
+msgid "error_version_notfound"
+msgstr "找ä¸åˆ°ç‰ˆæœ¬ï¼"
+
+#: views/users/delete.thtml:125 views/users/edit.thtml:173
+msgid "error_wrong_password"
+msgstr "輸入的密碼錯誤ï¼"
+
+#: views/elements/amo2009/homepage_addon.thtml:122
+#: views/elements/feature.thtml:122
+msgid "feature_learnmore"
+msgstr "詳細資訊"
+
+#. %1 is the add-on name
+#: views/elements/amo2009/homepage_addon.thtml:123
+#: views/elements/feature.thtml:123
+#, php-format
+msgid "feature_learnmore_about_addon"
+msgstr "%1$s 的詳細資訊"
+
+#. %1$s is a number
+#: views/elements/amo2009/reviews.thtml:52
+#: views/elements/addon_listitem.thtml:112 views/elements/feature.thtml:99
+#: views/addons/browse_thumbs.thtml:86
+#, php-format
+msgid "feature_reviews"
+msgid_plural "feature_reviews"
+msgstr[0] "%1$s 篇æ„見"
+
+#: views/elements/amo2009/homepage_addon.thtml:127
+#: views/elements/feature.thtml:127
+msgid "feature_view_more_from_category"
+msgstr "更多åŒé¡žå…ƒä»¶ï¼š"
+
+#. This appears on a page that views the source of an add-on. This link will return
+#. the user to the add-on's main page
+#: views/files/browse.thtml:65
+msgid "file_browser_link_addon"
+msgstr "回到附加元件"
+
+#. There is a list of directories and files on the page. Clicking this will show the
+#. contents of all the directories (normally you would click on each one to see the
+#. contents)
+#: views/files/browse.thtml:67
+msgid "file_browser_link_expand_all"
+msgstr "全部展開"
+
+#. This appears on a page that views the source of an add-on. This link will return
+#. the user to the add-on's review page (it only appears if the add-on is being
+#. reviewed)
+#: views/files/browse.thtml:64
+msgid "file_browser_link_review"
+msgstr "回到審核"
+
+#. The title of the page for viewing an add-on's source.
+#. %1$s is the name of the add-on
+#. %2$s is the name of the current application (e.g. Firefox or Thunderbird)
+#: views/files/browse.thtml:46
+msgid "file_browser_title"
+msgstr "%1$s :: 檔案ç€è¦½å™¨ :: %2$s 附加元件"
+
+#. This appears on a page that views the source of an add-on. There is a list of
+#. directories and files on the page. Clicking this link will toggle between an
+#. expanded or a collapsed list. This string should be kept short.
+#: views/files/browse.thtml:68
+msgid "file_browser_toggle_expand_collapse"
+msgstr "+/-"
+
+#. Link text for the AMO About page.
+#: views/elements/footer.thtml:72 views/layouts/amo2009.thtml:341
+msgid "footer_a_about"
+msgstr "關於"
+
+#. Link text to the AMO blog.
+#: views/elements/footer.thtml:74 views/layouts/amo2009.thtml:343
+msgid "footer_a_blog"
+msgstr "部è½æ ¼"
+
+#. Link text to the Frequently Asked Questions page.
+#: views/elements/footer.thtml:73 views/layouts/amo2009.thtml:342
+msgid "footer_a_faq"
+msgstr "常見å•é¡Œé›†"
+
+#. Full text for the FAQ abbreviation.
+#: views/elements/footer.thtml:73 views/pages/collector_features.thtml:72
+#: views/layouts/amo2009.thtml:342
+msgid "footer_abbr_faq"
+msgstr "常見å•é¡Œé›†"
+
+#: views/elements/footer.thtml:67 views/layouts/amo2009.thtml:336
+msgid "footer_all_rights_reserved"
+msgstr "ä¿ç•™æ‰€æœ‰æ¬Šåˆ©ã€‚"
+
+#: views/elements/footer.thtml:67 views/layouts/amo2009.thtml:336
+msgid "footer_copyright"
+msgstr "版權所有"
+
+#: views/elements/footer.thtml:71 views/layouts/amo2009.thtml:340
+msgid "footer_credits"
+msgstr "æ„Ÿè¬"
+
+#: views/elements/footer.thtml:76 views/layouts/amo2009.thtml:346
+msgid "footer_disclaimer"
+msgstr ""
+"Mozilla 出於善æ„æ供以上程å¼éˆçµï¼Œç„¶è€Œæˆ‘們並ä¸ä»£è¡¨ä»¥ä¸Šç¨‹å¼æˆ–相關資訊的作者。使"
+"用以上程å¼æ™‚若有任何疑å•æˆ–ä¸æ»¿ï¼Œæˆ–需è¦é€²ä¸€æ­¥çš„æœå‹™ï¼Œé‚„請直接與軟體供應者è¯ç¹«ã€‚"
+
+#: views/elements/footer.thtml:61 views/layouts/amo2009.thtml:332
+msgid "footer_lang_form_lang_submit_go"
+msgstr "è¡"
+
+#: views/elements/footer.thtml:70 views/layouts/amo2009.thtml:339
+msgid "footer_legal_notices"
+msgstr "法律è²æ˜Ž"
+
+#: views/elements/footer.thtml:50 views/layouts/amo2009.thtml:321
+msgid "footer_other_languages"
+msgstr "其他語言:"
+
+#: views/elements/footer.thtml:69 views/layouts/amo2009.thtml:338
+msgid "footer_privacy_policy"
+msgstr "éš±ç§æ”¿ç­–"
+
+#: models/addontype.php:79
+msgid "general_addontype_dict"
+msgstr "字典套件"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:100
+msgid "general_addontype_dict_plural"
+msgstr "å­—å…¸"
+
+#: models/addontype.php:75
+msgid "general_addontype_extension"
+msgstr "擴充套件"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:98
+msgid "general_addontype_extension_plural"
+msgstr "擴充套件"
+
+#: models/addontype.php:85
+msgid "general_addontype_lpaddon"
+msgstr "語言套件 (附加元件)"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:103
+msgid "general_addontype_lpaddon_plural"
+msgstr "語言套件 (附加元件)"
+
+#: models/addontype.php:83
+msgid "general_addontype_lpapp"
+msgstr "語言套件 (應用程å¼)"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:102
+msgid "general_addontype_lpapp_plural"
+msgstr "語言套件 (應用程å¼)"
+
+#: models/addontype.php:87
+msgid "general_addontype_plugin"
+msgstr "外掛程å¼"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:104
+msgid "general_addontype_plugin_plural"
+msgstr "外掛程å¼"
+
+#: models/addontype.php:81
+msgid "general_addontype_search"
+msgstr "æœå°‹å¼•æ“Ž"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:101
+msgid "general_addontype_search_plural"
+msgstr "æœå°‹å¼•æ“Ž"
+
+#: models/addontype.php:77
+msgid "general_addontype_theme"
+msgstr "佈景主題"
+
+#. Plural in this context means many of the add-on type
+#: models/addontype.php:99
+msgid "general_addontype_theme_plural"
+msgstr "佈景主題"
+
+#: config/language.php:367
+msgid "general_languages_all_locales"
+msgstr "所有語言"
+
+#: views/layouts/amo2009.thtml:249
+msgid "header_brand_name"
+msgstr "Mozilla"
+
+#. %1$s is the application name. Example: Firefox
+#: views/elements/header.thtml:111 views/elements/header.thtml:122
+#: views/layouts/amo2009.thtml:248
+#, php-format
+msgid "header_home_tooltip"
+msgstr "回到 %1$s 附加元件首é "
+
+#: views/elements/header.thtml:87
+msgid "header_main_firefox_header"
+msgstr "Firefox 附加元件"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:218
+msgid "header_main_firefox_header_with_logo"
+msgstr "<img alt=\"Firefox\" src=\"%1$s\" /> <strong>Firefox</strong> 附加元件"
+
+#: views/elements/header.thtml:99
+msgid "header_main_header"
+msgstr "附加元件"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:242
+msgid "header_main_header_with_logo"
+msgstr "附加元件 <img alt=\"Add-ons\" src=\"%1$s\" />"
+
+#: views/elements/header.thtml:90
+msgid "header_main_seamonkey_header"
+msgstr "SeaMonkey 附加元件"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:224
+msgid "header_main_seamonkey_header_with_logo"
+msgstr ""
+"<img alt=\"seamonkey\" src=\"%1$s\" /> <strong>SeaMonkey</strong> 附加元件"
+
+#: views/elements/header.thtml:93
+msgid "header_main_sunbird_header"
+msgstr "Sunbird 附加元件"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:230
+msgid "header_main_sunbird_header_with_logo"
+msgstr "<img alt=\"sunbird\" src=\"%1$s\" /> <strong>Sunbird</strong> 附加元件"
+
+#: views/elements/header.thtml:96
+msgid "header_main_thunderbird_header"
+msgstr "Thunderbird 附加元件"
+
+#. %1$s is the URL to the logo image
+#: views/layouts/amo2009.thtml:236
+msgid "header_main_thunderbird_header_with_logo"
+msgstr ""
+"<img alt=\"thunderbird\" src=\"%1$s\" /> <strong>Thunderbird</strong> 附加元件"
+
+#: views/layouts/amo2009.thtml:205
+msgid "header_navaccess_applications_menu"
+msgstr "跳至其他應用程å¼åŠŸèƒ½è¡¨"
+
+#: views/layouts/amo2009.thtml:204
+msgid "header_navaccess_categories_menu"
+msgstr "跳至分類功能表"
+
+#: views/layouts/amo2009.thtml:202
+msgid "header_navaccess_main_content"
+msgstr "跳至主內容"
+
+#: views/layouts/amo2009.thtml:203
+msgid "header_navaccess_search_form"
+msgstr "跳至æœå°‹è¡¨å–®"
+
+#: views/elements/header.thtml:62
+msgid "header_navlink_addons"
+msgstr "附加元件"
+
+#: views/elements/developers/sidebar.thtml:72
+#: views/elements/developers/myaddons.thtml:50 views/elements/header.thtml:159
+#: views/addons/display.thtml:378
+msgid "header_navlink_login"
+msgstr "登入"
+
+#: views/elements/header.thtml:156 views/layouts/amo2009.thtml:304
+msgid "header_navlink_logout"
+msgstr "登出"
+
+#: views/elements/header.thtml:145 views/layouts/amo2009.thtml:303
+msgid "header_navlink_myaccount"
+msgstr "我的帳號"
+
+#: views/elements/header.thtml:158
+msgid "header_navlink_register"
+msgstr "註冊"
+
+#. %1 is the URL to the registration page
+#. %2 is the URL to the login page
+#: views/layouts/amo2009.thtml:278
+msgid "header_navlink_register_or_login"
+msgstr "<a href=\"%1$s\">註冊</a> 或 <a href=\"%2$s\">登入</a>"
+
+#: views/layouts/amo2009.thtml:285
+msgid "header_navlink_tools"
+msgstr "工具"
+
+#. %s is the add-on name
+#: views/elements/collections_interactive_addon.thtml:62
+#: views/elements/amo2009/homepage_addon.thtml:77
+#: views/elements/addon_discussionheader.thtml:62
+#: views/elements/addon_listitem.thtml:67 views/elements/feature.thtml:84
+#: views/addons/category_landing.thtml:87 views/addons/browse_thumbs.thtml:60
+#, php-format
+msgid "img_preview_of"
+msgstr "%s çš„é è¦½åœ–片"
+
+#. %1 is the login URL for the link tag
+#. %2 is the link to an explanatory page.
+#: views/elements/amo2009/install.thtml:307 views/elements/install.thtml:255
+msgid "install_a_login_to_install"
+msgstr "<a href=\"%1$s\">登入</a> æ‰èƒ½å®‰è£æ­¤å…ƒä»¶ã€‚<a href=\"%2$s\">為什麼</a>?"
+
+#. %1 is the URL for the Experimental Add-ons section of the FAQ page
+#: views/elements/amo2009/install.thtml:283 views/elements/install.thtml:232
+msgid "install_button_confirm_exp_install"
+msgstr "讓我安è£æ­¤å¯¦é©—中附加元件。<a href=\"%1$s\">這是什麼?</a>"
+
+#. %1$s is the application name. Example: Firefox
+#. %2$s is an optional string used to specify a platform. Example: (Windows)
+#: views/elements/amo2009/install.thtml:128 views/elements/install.thtml:75
+#, php-format
+msgid "install_button_text"
+msgstr "安è£åˆ° %1$s %2$s"
+
+#. %1 is the add-on name, %2 is the app name
+#: views/elements/amo2009/install.thtml:191
+#: views/elements/amo2009/install.thtml:206
+#: views/elements/amo2009/install.thtml:249
+#: views/elements/amo2009/install.thtml:298 views/elements/install.thtml:150
+#: views/elements/install.thtml:165 views/elements/install.thtml:202
+#: views/elements/install.thtml:246
+#, php-format
+msgid "install_button_title"
+msgstr "å®‰è£ %1$s 到 %2$s"
+
+#. %1$s is the add-on name
+#: views/elements/amo2009/install.thtml:200 views/elements/install.thtml:159
+#, php-format
+msgid "install_download"
+msgstr "下載 %1$s"
+
+#: views/elements/amo2009/install.thtml:147 views/elements/install.thtml:94
+msgid "install_error_addon_not_found"
+msgstr "找ä¸åˆ°æ­¤é™„加元件。"
+
+#: views/addons/dictionaries.thtml:65
+msgid "langtools_a11y_tablesummary"
+msgstr "所有語言套件åŠå­—典套件的清單。"
+
+#: views/addons/dictionaries.thtml:47
+msgid "langtools_download_dictionary"
+msgstr "下載字典套件"
+
+#: views/addons/dictionaries.thtml:48
+msgid "langtools_download_langpack"
+msgstr "下載語言套件"
+
+#: views/addons/dictionaries.thtml:63 controllers/components/amo.php:685
+#: controllers/addons_controller.php:1239
+msgid "langtools_header_dicts_and_langpacks"
+msgstr "å­—å…¸åŠèªžè¨€å¥—件"
+
+#: views/addons/dictionaries.thtml:44
+msgid "langtools_install_dictionary"
+msgstr "安è£å­—典套件"
+
+#: views/addons/dictionaries.thtml:45
+msgid "langtools_install_langpack"
+msgstr "安è£èªžè¨€å¥—件"
+
+#: views/addons/dictionaries.thtml:69
+msgid "langtools_tableheader_dictionary"
+msgstr "字典套件"
+
+#: views/addons/dictionaries.thtml:70
+msgid "langtools_tableheader_langpack"
+msgstr "語言套件"
+
+#: views/addons/dictionaries.thtml:68
+msgid "langtools_tableheader_language"
+msgstr "語言套件"
+
+#: models/license.php:65
+msgid "license_custom"
+msgstr "自訂授權æ¢æ¬¾"
+
+#: config/bootstrap.php:303
+msgid "licenses_bsd"
+msgstr "BSD License"
+
+#: config/bootstrap.php:298
+msgid "licenses_gpl_2.0"
+msgstr "GNU General Public License,版本 2.0"
+
+#: config/bootstrap.php:299
+msgid "licenses_gpl_3.0"
+msgstr "GNU General Public License,版本 3.0"
+
+#: config/bootstrap.php:300
+msgid "licenses_lgpl_2.1"
+msgstr "GNU Lesser General Public License,版本 2.1"
+
+#: config/bootstrap.php:301
+msgid "licenses_lgpl_3.0"
+msgstr "GNU Lesser General Public License,版本 3.0"
+
+#: config/bootstrap.php:302
+msgid "licenses_mit"
+msgstr "MIT/X11 License"
+
+#: config/bootstrap.php:297
+msgid "licenses_mpl_1.1"
+msgstr "Mozilla Public License,版本 1.1"
+
+#: views/users/emailchange.thtml:51 views/users/delete.thtml:55
+#: views/users/delete.thtml:137 views/users/edit.thtml:74
+#: views/reviews/flag.thtml:54
+msgid "link_return_to_front_page"
+msgstr "按這裡回到網站首é ã€‚"
+
+#: views/elements/amo2009/addon_list_options.thtml:46
+#: views/elements/addon_list_options.thtml:46
+msgid "list_sortby_date"
+msgstr "日期"
+
+#: views/elements/amo2009/addon_list_options.thtml:47
+#: views/elements/addon_list_options.thtml:47
+msgid "list_sortby_downloads"
+msgstr "下載次數"
+
+#: views/elements/amo2009/addon_list_options.thtml:45
+#: views/elements/addon_list_options.thtml:45
+msgid "list_sortby_name"
+msgstr "元件å稱"
+
+#: views/elements/amo2009/addon_list_options.thtml:48
+#: views/elements/addon_list_options.thtml:48
+msgid "list_sortby_rating"
+msgstr "評分"
+
+#: config/bootstrap.php:278
+msgid "main_prettyname_fennec"
+msgstr "Fennec"
+
+#: config/bootstrap.php:274
+msgid "main_prettyname_firefox"
+msgstr "Firefox"
+
+#: config/bootstrap.php:277
+msgid "main_prettyname_seamonkey"
+msgstr "SeaMonkey"
+
+#: config/bootstrap.php:276
+msgid "main_prettyname_sunbird"
+msgstr "Sunbird"
+
+#: config/bootstrap.php:275
+msgid "main_prettyname_thunderbird"
+msgstr "Thunderbird"
+
+#: views/elements/addon_categories.thtml:52
+msgid "nav_category_dicts_langpacks"
+msgstr "字典套件åŠèªžè¨€å¥—件"
+
+#: views/elements/addon_categories.thtml:55
+msgid "nav_category_themes"
+msgstr "佈景主題"
+
+#: views/elements/app_chooser.thtml:47 views/layouts/amo2009.thtml:255
+msgid "other_apps_tooltip"
+msgstr "尋找其他應用程å¼ä½¿ç”¨çš„附加元件"
+
+#. In a user list: user 1, user 2, "others"
+#: views/helpers/addons_html.php:222
+msgid "other_users"
+msgstr "其他使用者"
+
+#: controllers/pages_controller.php:90
+msgid "page_title_appversions"
+msgstr "應用程å¼ç‰ˆæœ¬"
+
+#: controllers/pages_controller.php:115
+msgid "page_title_collector"
+msgstr "Add-on Collector"
+
+#: controllers/pages_controller.php:117
+msgid "page_title_collector_faq"
+msgstr "Add-on Collector 常見å•é¡Œé›†"
+
+#: controllers/pages_controller.php:119
+msgid "page_title_collector_features"
+msgstr "Add-on Collector 功能"
+
+#: controllers/pages_controller.php:122
+msgid "page_title_collector_firstrun"
+msgstr "歡迎來到 Add-on Collector"
+
+#: controllers/pages_controller.php:92
+msgid "page_title_credits"
+msgstr "æ„Ÿè¬"
+
+#: controllers/pages_controller.php:113
+msgid "page_title_developer_faq"
+msgstr "開發者常見å•é¡Œé›†"
+
+#: controllers/pages_controller.php:111
+msgid "page_title_faq"
+msgstr "常見å•é¡Œé›†"
+
+#: controllers/pages_controller.php:94
+msgid "page_title_fashionyourfirefox_faq"
+msgstr "Fashion your Firefox FAQ"
+
+#: controllers/pages_controller.php:101
+msgid "page_title_policy"
+msgstr "附加元件使用æ¢æ¬¾"
+
+#: controllers/pages_controller.php:103
+msgid "page_title_privacy"
+msgstr "Mozilla éš±ç§æ¬Šä¿è­·æ”¿ç­–"
+
+#: controllers/pages_controller.php:105
+msgid "page_title_review_guide"
+msgstr "æ„見撰寫指å—"
+
+#: controllers/pages_controller.php:107
+msgid "page_title_sandbox"
+msgstr "沙箱審核系統"
+
+#: controllers/pages_controller.php:109
+msgid "page_title_submissionhelp"
+msgstr "上傳說明"
+
+#: views/pages/appversions.thtml:87
+msgid "pages_appversions_guid"
+msgstr "GUID"
+
+#: views/pages/appversions.thtml:79 controllers/pages_controller.php:90
+msgid "pages_appversions_header"
+msgstr "有效應用程å¼ç‰ˆæœ¬"
+
+#: views/pages/appversions.thtml:80
+msgid "pages_appversions_intro"
+msgstr ""
+"上傳到 Mozilla 附加元件的元件必須å«æœ‰ install.rdf 檔案,並至少支æ´ä¸‹é¢å…¶ä¸­ä¹‹ä¸€"
+"的應用程å¼ã€‚åªæœ‰ä¸‹é¢åˆ—出的應用程å¼ç‰ˆæœ¬å…許上傳。"
+
+#. %s is a full <a> tag
+#: views/pages/appversions.thtml:93
+#, php-format
+msgid "pages_appversions_required_files"
+msgstr ""
+"如果您支æ´çš„應用程å¼ä¸éœ€è¦ install.rdf 檔案,還是必須包å«ä¸€å€‹ç¬¦åˆè¦æ±‚çš„ %s。"
+
+#. this is the text inside of an <a> tag for pages_appversions_required_files. This
+#. should be fixed.
+#: views/pages/appversions.thtml:93
+msgid "pages_appversions_required_files_link"
+msgstr "這裡"
+
+#: views/pages/appversions.thtml:88
+msgid "pages_appversions_versions"
+msgstr "版本"
+
+#: views/pages/policy.thtml:51
+msgid "pages_policy_sandbox_link"
+msgstr "「沙箱ã€å€è³‡è¨Šé "
+
+#: views/elements/pagination.thtml:53
+msgid "pagination_next_page"
+msgstr "下一é "
+
+#: views/elements/pagination.thtml:52
+msgid "pagination_previous_page"
+msgstr "上一é "
+
+#: views/elements/recaptcha.thtml:65
+msgid "recaptcha_enter_both_words"
+msgstr ""
+"請輸入下é¢<strong>兩個英文單字</strong>,<strong>中間用åŠå½¢ç©ºç™½åˆ†é–‹</strong>。"
+
+#: views/elements/recaptcha.thtml:83
+msgid "recaptcha_enter_here"
+msgstr "輸入您的答案:"
+
+#: views/elements/recaptcha.thtml:74
+msgid "recaptcha_enter_whatyouhear"
+msgstr "請輸入您所è½åˆ°çš„數字。"
+
+#. %1 is the link switching refreshing the captcha
+#. %2 is the link switching to a text captcha
+#: views/elements/recaptcha.thtml:77
+msgid "recaptcha_hardtohear_text"
+msgstr ""
+"若這å°æ‚¨ä¾†èªªé›£ä»¥äº†è§£ï¼Œæ‚¨å¯ä»¥<a href=\"%1$s\">å†è½çœ‹çœ‹å…¶ä»–çš„</a>或是<a href=\"%"
+"2$s\">切æ›å›žè¼¸å…¥å–®å­—</a>。"
+
+#. %1 is the link switching refreshing the captcha
+#. %2 is the link switching to an audio captcha
+#: views/elements/recaptcha.thtml:68
+msgid "recaptcha_hardtoread_text"
+msgstr ""
+"若這å°æ‚¨ä¾†èªªé›£ä»¥äº†è§£ï¼Œæ‚¨å¯ä»¥<a href=\"%1$s\">試其他單字</a>或是改<a href=\"%2"
+"$s\">用è½çš„</a>。"
+
+#: views/users/register.thtml:105
+msgid "recaptcha_label"
+msgstr "您是人類嗎?"
+
+#: views/users/register.thtml:106
+msgid "recaptcha_whatsthis"
+msgstr "這是什麼?"
+
+#: controllers/reviews_controller.php:559
+msgid "review_flag_error"
+msgstr "回報此æ„見發生錯誤ï¼"
+
+#: models/reviews_moderation_flag.php:69
+msgid "review_flag_reason_bug_support"
+msgstr "誤置的臭蟲回報或是技術支æ´è¦æ±‚"
+
+#: views/reviews/display.thtml:103 views/reviews/display.thtml:186
+msgid "review_flag_reason_instructions"
+msgstr "回報這個æ„見(é¸æ“‡ä¸€å€‹åŽŸå› ï¼‰"
+
+#: models/reviews_moderation_flag.php:67
+msgid "review_flag_reason_language"
+msgstr "ä¸é©å®œçš„用字é£è©žï¼å°è©±"
+
+#: models/reviews_moderation_flag.php:71
+msgid "review_flag_reason_other"
+msgstr "其他(請詳述)"
+
+#: models/reviews_moderation_flag.php:65
+msgid "review_flag_reason_spam"
+msgstr "廣告訊æ¯æˆ–是其他無關的內容"
+
+#: views/reviews/display.thtml:91 views/reviews/display.thtml:175
+#: controllers/reviews_controller.php:555
+msgid "review_flag_success"
+msgstr "è¬è¬æ‚¨ï¼Œæ­¤æ„見已經標記為需è¦å¯©æ ¸ã€‚"
+
+#: views/reviews/display.thtml:41
+msgid "review_flag_this"
+msgstr "回報此æ„見"
+
+#: views/reviews/display.thtml:42
+msgid "review_flag_this_titletip"
+msgstr "這篇æ„見ä¸é©åˆã€æœ‰éŒ¯èª¤æˆ–是廣告留言?按這裡將其標記為需è¦å¯©æ ¸"
+
+#. %1 is the URL of the support section, %2 for the review guidelines
+#: views/reviews/add.thtml:53
+msgid "review_guidelines_short"
+msgstr ""
+"<p>請將這些話記在心裡:</p><ul><li>用寫給朋å‹çš„æ–¹å¼å‘Šè¨´å¤§å®¶æ‚¨å°æ­¤é™„加元件的使"
+"用經驗。請寫出特定且有幫助的細節,åƒæ˜¯æ‚¨å–œæ­¡æˆ–是ä¸å–œæ­¡çš„功能,此附加元件是å¦å®¹"
+"易使用,和它的缺點在哪等等。é¿å…一般的形容åƒæ˜¯ã€Œå¥½æ£’ã€æˆ–是「真難用ã€ï¼Œé™¤éžæ‚¨è§£"
+"釋了為何您這樣èªç‚ºã€‚</li><li>請勿在æ„見處回報程å¼è‡­èŸ²ã€‚我們ä¸æœƒå°‡æ‚¨çš„ e-mail "
+"顯示給擴充套件作者,而他們或許需è¦å’Œæ‚¨è¯çµ¡æ‰èƒ½è§£æ±ºè©²å•é¡Œã€‚請至<a href=\"%1$s"
+"\">技術支æ´å°ç¯€</a>åƒè€ƒå¦‚何尋求使用上的å”助。</li><li>請勿使用髒話,或是洩æ¼å€‹"
+"人資訊。</li></ul><p>更多關於使用者æ„見的資訊,請åƒè€ƒ<a href=\"%2$s\">æ„見撰寫"
+"指å—</a>。</p>"
+
+#. %1 is the add-on name
+#: views/reviews/flag.thtml:56 views/reviews/display.thtml:55
+#: views/reviews/review_added.thtml:50
+#, php-format
+msgid "reviews_header"
+msgstr "å° %s çš„æ„見"
+
+#: controllers/addons_controller.php:435
+msgid "rss_featuredaddons"
+msgstr "推薦附加元件"
+
+#: controllers/addons_controller.php:432
+msgid "rss_newestaddons"
+msgstr "最新附加元件"
+
+#: controllers/addons_controller.php:434
+msgid "rss_popularaddons"
+msgstr "熱門元件"
+
+#: controllers/addons_controller.php:433
+msgid "rss_updatedaddons"
+msgstr "最近更新元件"
+
+#: views/elements/search_mini.thtml:70
+msgid "search"
+msgstr "æœå°‹"
+
+#: views/search/collections.thtml:51
+msgid "search_collections_header"
+msgstr "收è—集æœå°‹çµæžœ"
+
+#: controllers/search_controller.php:297
+msgid "search_collections_pagetitle"
+msgstr "收è—集æœå°‹çµæžœ"
+
+#: controllers/search_controller.php:99
+msgid "search_disabled"
+msgstr "æœå°‹åŠŸèƒ½ç›®å‰æš«åœä½¿ç”¨ï¼Œè«‹ç¨å¾Œå†è©¦è©¦çœ‹ã€‚"
+
+#: views/elements/amo2009/search.thtml:188 views/elements/search.thtml:187
+#: views/elements/search_mini.thtml:54
+msgid "search_form_all_addons"
+msgstr "所有元件"
+
+#. This string is in the main category dropdown when searching
+#: views/elements/amo2009/search.thtml:204
+msgid "search_form_all_collections"
+msgstr "所有收è—集"
+
+#: views/elements/amo2009/search.thtml:184
+#: views/elements/amo2009/search.thtml:385
+#: views/elements/amo2009/search.thtml:408 views/elements/search.thtml:171
+#: views/elements/search.thtml:183 views/elements/search_mini.thtml:43
+#: views/elements/search_mini.thtml:49 views/layouts/mozilla.thtml:188
+msgid "search_form_default_text"
+msgstr "æœå°‹é™„加元件"
+
+#: views/elements/amo2009/search.thtml:184
+#: views/elements/amo2009/search.thtml:404
+msgid "search_form_default_text_collections"
+msgstr "æœå°‹æ”¶è—集"
+
+#: views/elements/amo2009/search.thtml:206 views/elements/search.thtml:202
+msgid "search_form_submit_tooltip"
+msgstr "æœå°‹é™„加元件"
+
+#: views/elements/amo2009/search.thtml:184 views/elements/search.thtml:183
+#: views/elements/search_mini.thtml:49
+msgid "search_form_tooltip"
+msgstr "按此處輸入æœå°‹é—œéµå­—"
+
+#: views/elements/amo2009/search.thtml:186 views/elements/search.thtml:185
+#: views/elements/search_mini.thtml:52
+msgid "search_form_within"
+msgstr "範åœ"
+
+#: views/addons/searchengines.thtml:118
+msgid "search_landing_all_search_engines"
+msgstr "所有æœå°‹å¼•æ“Ž"
+
+#: views/addons/searchengines.thtml:114
+msgid "search_landing_browse_search_engines"
+msgstr "ç€è¦½æœå°‹å¼•æ“Ž"
+
+#: views/search/collections.thtml:58 views/search/index.thtml:59
+msgid "search_nothing_found"
+msgstr "找ä¸åˆ°çµæžœã€‚"
+
+#: controllers/search_controller.php:185
+msgid "search_pagetitle"
+msgstr "æœå°‹é™„加元件"
+
+#: controllers/search_controller.php:242
+msgid "search_rss_description"
+msgstr "æœå°‹çµæžœæ¶ˆæ¯ä¾†æº"
+
+#. %s is the terms the user is searching for (a string)
+#: controllers/search_controller.php:241
+#, php-format
+msgid "search_rss_results_for"
+msgstr "æœå°‹çµæžœï¼š%s "
+
+#: views/elements/header.thtml:154 views/layouts/amo2009.thtml:296
+msgid "sidebar_navlink_admin_tools"
+msgstr "管ç†å“¡å·¥å…·"
+
+#: views/elements/header.thtml:146 views/layouts/amo2009.thtml:288
+msgid "sidebar_navlink_developer_tools"
+msgstr "開發者工具"
+
+#: views/elements/header.thtml:148 views/layouts/amo2009.thtml:290
+msgid "sidebar_navlink_editor_tools"
+msgstr "審核者工具"
+
+#: views/layouts/amo2009.thtml:302
+msgid "sidebar_navlink_welcome"
+msgstr "æ­¡è¿Ž"
+
+#. %s is the user's name
+#: views/layouts/amo2009.thtml:302
+#, php-format
+msgid "sidebar_navlink_welcome_name"
+msgstr "歡迎您,%s"
+
+#: views/elements/pitch.thtml:50 views/elements/pitch.thtml:55
+msgid "sidebar_pitch_dictionary"
+msgstr "字典套件"
+
+#: views/elements/pitch.thtml:72
+msgid "sidebar_pitch_featured_addons"
+msgstr "推薦元件"
+
+#: views/elements/pitch.thtml:61
+msgid "sidebar_pitch_looking_for"
+msgstr "我想找的是:"
+
+#: views/elements/pitch.thtml:70
+msgid "sidebar_pitch_newest_addons"
+msgstr "最新元件"
+
+#: views/elements/pitch.thtml:49
+msgid "sidebar_pitch_search"
+msgstr "æœå°‹å¼•æ“Ž"
+
+#: views/elements/pitch.thtml:69
+msgid "sidebar_pitch_subscribe_to"
+msgstr "訂閱消æ¯ä¾†æº"
+
+#: views/elements/pitch.thtml:48 views/elements/pitch.thtml:54
+msgid "sidebar_pitch_theme"
+msgstr "佈景主題"
+
+#: views/elements/pitch.thtml:71
+msgid "sidebar_pitch_updated_addons"
+msgstr "最近更新元件"
+
+#. %1$s is a number
+#: views/helpers/localization.php:65 views/developers/versions_edit.thtml:95
+#: views/addons/dictionaries.thtml:92
+#, php-format
+msgid "size_kb"
+msgstr "%1$s KB"
+
+#: views/elements/amo2009/stars.thtml:57 views/elements/stars.thtml:63
+msgid "stars_not_yet_rated"
+msgstr "尚未評分"
+
+#. %1 is the number of stars this add-on has
+#: views/elements/amo2009/stars.thtml:49 views/elements/stars.thtml:54
+#, php-format
+msgid "stars_rated_x_outof_5"
+msgstr "評分:%s / 5 顆星"
+
+#: views/statistics/addon.thtml:59
+msgid "statistics_addon_dashboard_link"
+msgstr "顯示æ¿é¦–é "
+
+#: views/statistics/addon.thtml:58
+msgid "statistics_addon_developertools_link"
+msgstr "開發者工具"
+
+#: views/statistics/addon.thtml:53
+msgid "statistics_addon_switch"
+msgstr "切æ›å…ƒä»¶"
+
+#. This is a date format.
+#. http://php.net/strftime
+#: views/statistics/rss/summary.thtml:54 views/statistics/addon.thtml:181
+msgid "statistics_date_shortmonth"
+msgstr "%m 月 %e 日"
+
+#. This is a date format.
+#. http://php.net/strftime
+#: views/statistics/rss/summary.thtml:40 views/statistics/addon.thtml:152
+msgid "statistics_date_shortmonthwithyear"
+msgstr "%Y 年 %m 月 %e 日"
+
+#. This is a date format.
+#. http://php.net/strftime
+#: views/statistics/rss/summary.thtml:41 views/statistics/rss/summary.thtml:48
+#: views/statistics/addon.thtml:161 views/statistics/addon.thtml:172
+msgid "statistics_date_weekdayshortmonth"
+msgstr "%m 月 %e 日 (%a)"
+
+#. %1$s is an add-on name and version. Example: Add-on 3.5
+#: controllers/components/stats.php:519
+#, php-format
+msgid "statistics_events_addon_created"
+msgstr "%1$s 發佈"
+
+#. %1$s is an application name and version. Example: Firefox 3.5
+#: controllers/components/stats.php:500
+#, php-format
+msgid "statistics_events_app_released"
+msgstr "%1$s 發行"
+
+#: views/statistics/addon.thtml:71
+msgid "statistics_help_close_link"
+msgstr "關閉"
+
+#: views/statistics/addon.thtml:60
+msgid "statistics_help_link"
+msgstr "說明"
+
+#: views/statistics/index.thtml:83
+msgid "statistics_index_anotheraddon"
+msgstr "或é¸æ“‡å…¶ä»–元件"
+
+#: views/statistics/index.thtml:85
+msgid "statistics_index_anotheraddon_public"
+msgstr "或é¸æ“‡å…ƒä»¶çš„公開資訊"
+
+#: views/statistics/index.thtml:71
+msgid "statistics_index_myaddons"
+msgstr "è«‹é¸æ“‡ä»»ä¸€å…ƒä»¶æª¢è¦–其統計資訊"
+
+#: views/statistics/index.thtml:89
+msgid "statistics_index_selectaddon"
+msgstr "è«‹é¸æ“‡å…ƒä»¶æª¢è¦–其統計資訊"
+
+#: views/statistics/index.thtml:91
+msgid "statistics_index_selectaddon_public"
+msgstr "è«‹é¸æ“‡å…ƒä»¶æª¢è¦–其公開資訊"
+
+#: views/statistics/index.thtml:39
+msgid "statistics_index_title"
+msgstr "統計資訊顯示æ¿"
+
+#: views/statistics/index.thtml:97
+msgid "statistics_index_view_button"
+msgstr "檢視統計資訊"
+
+#: views/statistics/addon.thtml:222 controllers/statistics_controller.php:247
+msgid "statistics_js_download_csv"
+msgstr "下載此表格 (CSV æ ¼å¼)"
+
+#: controllers/statistics_controller.php:246
+msgid "statistics_js_dropdowns_none"
+msgstr "ç„¡"
+
+#: controllers/statistics_controller.php:245
+msgid "statistics_js_dropdowns_removeplot"
+msgstr "移除這一點"
+
+#: controllers/statistics_controller.php:248
+msgid "statistics_js_groupby_selector_date"
+msgstr "分類ä¾æ“š: 日期"
+
+#: controllers/statistics_controller.php:251
+msgid "statistics_js_groupby_selector_month"
+msgstr "分類ä¾æ“š: 月份"
+
+#: controllers/statistics_controller.php:249
+msgid "statistics_js_groupby_selector_week"
+msgstr "分類ä¾æ“š: 星期"
+
+#: controllers/statistics_controller.php:250
+msgid "statistics_js_groupby_selector_week_over_week"
+msgstr "分類ä¾æ“š: 星期"
+
+#: controllers/statistics_controller.php:260
+msgid "statistics_js_plotselection_foundinrange"
+msgstr "在此範åœæ‰¾åˆ°%s"
+
+#: controllers/statistics_controller.php:270
+msgid "statistics_js_plotselection_options_addplot_name"
+msgstr "新增座標點"
+
+#: controllers/statistics_controller.php:271
+msgid "statistics_js_plotselection_options_addplot_tooltip"
+msgstr "新增此圖表的其他座標點"
+
+#: controllers/statistics_controller.php:261
+msgid "statistics_js_plotselection_options_count_name_checked"
+msgstr "éš±è—總計數"
+
+#: controllers/statistics_controller.php:262
+msgid "statistics_js_plotselection_options_count_name_unchecked"
+msgstr "顯示總計數"
+
+#: controllers/statistics_controller.php:263
+msgid "statistics_js_plotselection_options_count_tooltip"
+msgstr "在此圖形æ繪總數"
+
+#: controllers/statistics_controller.php:275
+msgid "statistics_js_plotselection_options_csv_name"
+msgstr "檢視資料 (CSV)"
+
+#: controllers/statistics_controller.php:276
+msgid "statistics_js_plotselection_options_csv_tooltip"
+msgstr "å–得此資料的逗點分隔檔案"
+
+#: controllers/statistics_controller.php:267
+msgid "statistics_js_plotselection_options_events_addon_name_checked"
+msgstr "éš±è— %s 事件"
+
+#: controllers/statistics_controller.php:268
+msgid "statistics_js_plotselection_options_events_addon_name_unchecked"
+msgstr "顯示 %s 事件"
+
+#: controllers/statistics_controller.php:269
+msgid "statistics_js_plotselection_options_events_addon_tooltip"
+msgstr "於座標點上顯示元件發行日期"
+
+#: controllers/statistics_controller.php:264
+msgid "statistics_js_plotselection_options_events_firefox_name_checked"
+msgstr "éš±è— Firefox 事件"
+
+#: controllers/statistics_controller.php:265
+msgid "statistics_js_plotselection_options_events_firefox_name_unchecked"
+msgstr "顯示 Firefox 事件"
+
+#: controllers/statistics_controller.php:266
+msgid "statistics_js_plotselection_options_events_firefox_tooltip"
+msgstr "於座標點上顯示 Firefox 發行日期"
+
+#: controllers/statistics_controller.php:272
+msgid "statistics_js_plotselection_options_resize_name_checked"
+msgstr "收起圖表"
+
+#: controllers/statistics_controller.php:273
+msgid "statistics_js_plotselection_options_resize_name_unchecked"
+msgstr "展開圖表"
+
+#: controllers/statistics_controller.php:274
+msgid "statistics_js_plotselection_options_resize_tooltip"
+msgstr "縮放圖表"
+
+#: controllers/statistics_controller.php:254
+msgid "statistics_js_plotselection_selector_adu"
+msgstr "æ¯æ—¥æœ‰æ•ˆä½¿ç”¨è€…"
+
+#: controllers/statistics_controller.php:256
+msgid "statistics_js_plotselection_selector_application"
+msgstr "應用程å¼"
+
+#: controllers/statistics_controller.php:259
+msgid "statistics_js_plotselection_selector_custom"
+msgstr "自訂"
+
+#: controllers/statistics_controller.php:253
+msgid "statistics_js_plotselection_selector_downloads"
+msgstr "下載"
+
+#: controllers/statistics_controller.php:258
+msgid "statistics_js_plotselection_selector_os"
+msgstr "作業系統"
+
+#: controllers/statistics_controller.php:257
+msgid "statistics_js_plotselection_selector_status"
+msgstr "元件狀態"
+
+#: controllers/statistics_controller.php:252
+msgid "statistics_js_plotselection_selector_summary"
+msgstr "摘è¦"
+
+#: controllers/statistics_controller.php:255
+msgid "statistics_js_plotselection_selector_version"
+msgstr "元件版本"
+
+#: controllers/components/stats.php:398
+msgid "statistics_longnames_application"
+msgstr "應用程å¼"
+
+#: controllers/components/stats.php:400
+msgid "statistics_longnames_os"
+msgstr "作業系統"
+
+#: controllers/components/stats.php:399
+msgid "statistics_longnames_status"
+msgstr "元件狀態"
+
+#: controllers/components/stats.php:401
+msgid "statistics_longnames_unknown"
+msgstr "未知"
+
+#: controllers/components/stats.php:397
+msgid "statistics_longnames_version"
+msgstr "元件版本"
+
+#: views/statistics/addon.thtml:118
+msgid "statistics_notice_data_insufficient"
+msgstr "所ç²è³‡è¨Šä¸è¶³ä»¥ç”¢ç”Ÿæ­¤åœ–表,請ç¨å€™å†å›žä¾†æª¢æŸ¥ã€‚"
+
+#: views/statistics/addon.thtml:130
+msgid "statistics_notice_data_none"
+msgstr "我們還沒有任何關於此附加元件的資料,請éŽå¹¾å¤©å¾Œå†å›žä¾†æª¢æŸ¥ã€‚"
+
+#: views/statistics/addon.thtml:41
+msgid "statistics_notice_data_updating"
+msgstr ""
+"附加元件統計資訊正在更新中,因程å¼ç¢¼æ­£åœ¨æ›´æ–°ç›¸é—œè³‡è¨Šçš„緣故,最近的資料å¯èƒ½æœƒä¸"
+"完整。請éŽå¹¾åˆ†é˜å¾Œå†å›žä¾†æª¢æŸ¥ã€‚"
+
+#: views/statistics/addon.thtml:136
+msgid "statistics_notice_disabled"
+msgstr "統計資訊顯示æ¿å·²åœç”¨ï¼Œè«‹ç¨å€™å†å›žä¾†æª¢æŸ¥ã€‚"
+
+#: views/statistics/addon.thtml:123
+msgid "statistics_notice_nojavascript"
+msgstr "檢視統計資訊顯示æ¿ä¸­çš„圖表需è¦é–‹å•Ÿ JavaScript。"
+
+#: views/statistics/addon.thtml:44
+msgid "statistics_notice_settings_updated"
+msgstr "您的設定已更新ï¼"
+
+#: controllers/statistics_controller.php:60
+#: controllers/statistics_controller.php:71
+#: controllers/statistics_controller.php:74
+#: controllers/statistics_controller.php:240
+msgid "statistics_pagetitle"
+msgstr "統計資訊顯示æ¿"
+
+#: views/statistics/addon.thtml:99
+msgid "statistics_plot_legend_adu"
+msgstr "æ¯æ—¥æœ‰æ•ˆä½¿ç”¨è€…"
+
+#: views/statistics/addon.thtml:95
+msgid "statistics_plot_legend_downloads"
+msgstr "æ¯æ—¥ä¸‹è¼‰æ¬¡æ•¸"
+
+#: views/statistics/addon.thtml:107
+msgid "statistics_plot_options_zoomin_alt"
+msgstr "放大"
+
+#: views/statistics/addon.thtml:106
+msgid "statistics_plot_options_zoomin_title"
+msgstr "放大到一個月"
+
+#: views/statistics/addon.thtml:110
+msgid "statistics_plot_options_zoomout_alt"
+msgstr "縮å°"
+
+#: views/statistics/addon.thtml:109
+msgid "statistics_plot_options_zoomout_title"
+msgstr "縮å°åˆ°ä¸€å€‹æœˆ"
+
+#: controllers/statistics_controller.php:283
+#, php-format
+msgid "statistics_rss_description"
+msgstr "%1$s çš„æ¯æ—¥çµ±è¨ˆè³‡è¨Šæ‘˜è¦"
+
+#: views/statistics/rss/summary.thtml:68
+msgid "statistics_rss_title_fulldate"
+msgstr "%Y 年 %m 月 %e 日 (%a)"
+
+#: views/statistics/rss/summary.thtml:68
+#, php-format
+msgid "statistics_rss_title_statsfordate"
+msgstr "%1$s 的統計資訊"
+
+#: views/statistics/settings.thtml:49
+msgid "statistics_settings_access_description"
+msgstr ""
+"在é è¨­æƒ…æ³ä¸‹ï¼Œåªæœ‰æ‚¨è‡ªå·±åŠ Mozilla 能看到您元件的統計資訊。但您å¯ä»¥å…¬é–‹çµ±è¨ˆè³‡"
+"訊,讓所有人看到您的元件統計資訊。"
+
+#: views/statistics/settings.thtml:48
+msgid "statistics_settings_access_heading"
+msgstr "顯示æ¿å­˜å–權é™"
+
+#: views/statistics/settings.thtml:51
+msgid "statistics_settings_access_private"
+msgstr "ç§äºº"
+
+#: views/statistics/settings.thtml:51
+msgid "statistics_settings_access_private_description"
+msgstr "åªæœ‰æ‚¨è‡ªå·±å’Œ Mozilla 看得到統計資訊"
+
+#: views/statistics/settings.thtml:52
+msgid "statistics_settings_access_public"
+msgstr "公開"
+
+#: views/statistics/settings.thtml:52
+msgid "statistics_settings_access_public_description"
+msgstr "任何人都å¯ä»¥çœ‹åˆ°çµ±è¨ˆè³‡è¨Š"
+
+#: views/statistics/addon.thtml:251
+msgid "statistics_settings_change_link"
+msgstr "變更設定"
+
+#: views/statistics/addon.thtml:253
+msgid "statistics_settings_confidential"
+msgstr "請將此資訊視為機密資料。"
+
+#: views/statistics/addon.thtml:245
+msgid "statistics_settings_currently_private"
+msgstr "顯示æ¿ç›®å‰è¨­ç‚º <b>ç§äºº</b>。"
+
+#: views/statistics/addon.thtml:241
+msgid "statistics_settings_currently_public"
+msgstr "顯示æ¿ç›®å‰è¨­ç‚º <b>公開</b>。"
+
+#: views/statistics/addon.thtml:246
+msgid "statistics_settings_locked_alt"
+msgstr "已上鎖"
+
+#: views/statistics/settings.thtml:57
+msgid "statistics_settings_return_link"
+msgstr "回到顯示æ¿"
+
+#: views/statistics/settings.thtml:56
+msgid "statistics_settings_save_button"
+msgstr "儲存設定"
+
+#: views/statistics/settings.thtml:46
+#, php-format
+msgid "statistics_settings_title"
+msgstr "%1$s 的統計資訊顯示æ¿è¨­å®š"
+
+#: views/statistics/addon.thtml:242
+msgid "statistics_settings_unlocked_alt"
+msgstr "已解鎖"
+
+#: controllers/components/stats.php:405
+msgid "statistics_shortnames_application"
+msgstr "程å¼"
+
+#: controllers/components/stats.php:407
+msgid "statistics_shortnames_os"
+msgstr "作業系統"
+
+#: controllers/components/stats.php:406
+msgid "statistics_shortnames_status"
+msgstr "狀態"
+
+#: controllers/components/stats.php:408
+msgid "statistics_shortnames_unknown"
+msgstr "未知"
+
+#: controllers/components/stats.php:404
+msgid "statistics_shortnames_version"
+msgstr "版本"
+
+#: views/statistics/rss/summary.thtml:42 views/statistics/addon.thtml:192
+msgid "statistics_summary_downloads_average"
+msgstr "æ¯æ—¥å¹³å‡ä¸‹è¼‰æ•¸"
+
+#: views/statistics/rss/summary.thtml:39
+msgid "statistics_summary_downloads_heading"
+msgstr "下載"
+
+#: views/statistics/rss/summary.thtml:41 views/statistics/addon.thtml:171
+msgid "statistics_summary_downloads_lastcount"
+msgstr "昨日下載次數"
+
+#: views/statistics/rss/summary.thtml:43 views/statistics/addon.thtml:199
+msgid "statistics_summary_downloads_lastweek"
+msgstr "最近七日下載次數"
+
+#: views/statistics/rss/summary.thtml:40 views/statistics/addon.thtml:151
+msgid "statistics_summary_downloads_total"
+msgstr "總下載次數"
+
+#: views/statistics/rss/summary.thtml:40 views/statistics/addon.thtml:152
+#, php-format
+msgid "statistics_summary_downloads_total_sincedate"
+msgstr "從 %1$s 開始"
+
+#: views/statistics/rss/summary.thtml:50 views/statistics/rss/summary.thtml:56
+#: views/statistics/addon.thtml:163 views/statistics/addon.thtml:183
+msgid "statistics_summary_nodata"
+msgstr "尚無資料"
+
+#: views/statistics/rss/summary.thtml:60 views/statistics/addon.thtml:195
+msgid "statistics_summary_updatepings_average"
+msgstr "æ¯æ—¥å¹³å‡æœ‰æ•ˆä½¿ç”¨è€…"
+
+#: views/statistics/rss/summary.thtml:52 views/statistics/addon.thtml:177
+msgid "statistics_summary_updatepings_changefromprevious"
+msgstr "與上次計數相比"
+
+#: views/statistics/rss/summary.thtml:54 views/statistics/addon.thtml:181
+#, php-format
+msgid "statistics_summary_updatepings_changefromprevious_ondate"
+msgstr "%1$s æ–¼ %2$s"
+
+#: views/statistics/rss/summary.thtml:45
+msgid "statistics_summary_updatepings_heading"
+msgstr "æ¯æ—¥æœ‰æ•ˆä½¿ç”¨è€…"
+
+#: views/statistics/rss/summary.thtml:46 views/statistics/addon.thtml:157
+msgid "statistics_summary_updatepings_total"
+msgstr "æ¯æ—¥æœ‰æ•ˆä½¿ç”¨è€…"
+
+#: views/statistics/rss/summary.thtml:48 views/statistics/addon.thtml:161
+#, php-format
+msgid "statistics_summary_updatepings_total_ondate"
+msgstr "æ–¼ %1$s"
+
+#: views/statistics/rss/summary.thtml:61 views/statistics/addon.thtml:203
+msgid "statistics_summary_updatepings_weekly_average"
+msgstr "本週平å‡æœ‰æ•ˆä½¿ç”¨è€…"
+
+#. %s is a percentage, like '+22.33%'. It sits next to another number, so
+#. the implied meaning is 'percentage change' from the previous stat point.
+#: views/statistics/rss/summary.thtml:62 views/statistics/addon.thtml:205
+msgid "statistics_summary_updatepings_weekly_change"
+msgstr "和上週相比 %s"
+
+#: views/statistics/addon.thtml:65 controllers/statistics_controller.php:184
+#: controllers/statistics_controller.php:282
+#, php-format
+msgid "statistics_title_addon_stats"
+msgstr "%1$s 統計資訊"
+
+#: views/addons/themes_landing.thtml:113
+msgid "themes_landing_all_themes"
+msgstr "所有佈景主題"
+
+#: views/addons/themes_landing.thtml:109
+msgid "themes_landing_browse_themes"
+msgstr "ç€è¦½ä½ˆæ™¯ä¸»é¡Œ"
+
+#: views/users/edit.thtml:185
+msgid "user_change_email"
+msgstr "變更 Email 地å€"
+
+#: views/users/edit.thtml:169
+msgid "user_change_password"
+msgstr "變更密碼"
+
+#: views/users/edit.thtml:96
+msgid "user_change_password_or_email"
+msgstr "變更密碼或 Email"
+
+#: controllers/users_controller.php:197
+msgid "user_confirmationcode_resent"
+msgstr "確èªç¢¼å·²é‡å¯„ï¼"
+
+#. %1 is the email address, %2 is the URL of the user registration page
+#: views/users/delete.thtml:51
+msgid "user_del_account_deleted"
+msgstr ""
+"您的使用者帳號 %1$s 已經刪除æˆåŠŸã€‚若您回心轉æ„,請到<a href=\"%2$s\">新使用者"
+"註冊</a>é é¢é‡æ–°è¨»å†Šã€‚"
+
+#: views/users/delete.thtml:102
+msgid "user_del_community_sad"
+msgstr "Mozilla 附加網站社群很éºæ†¾æ‚¨çš„離開。"
+
+#: views/users/delete.thtml:123
+msgid "user_del_confirm_password"
+msgstr "è«‹å†æ¬¡è¼¸å…¥å¯†ç¢¼"
+
+#: views/users/delete.thtml:134
+msgid "user_del_deletenow"
+msgstr "立刻刪掉我的帳號"
+
+#. %1 is the URL of the user's info page
+#: views/users/delete.thtml:64
+msgid "user_del_error_addons"
+msgstr ""
+"您ä¸èƒ½åˆªé™¤æ‚¨çš„帳號,因為您目å‰çš„角色是<a href=\"%1$s\">附加元件作者</a>。è¦åˆª"
+"除您的帳號,請通知其他附加元件共åŒä½œè€…請他們將您從作者清單中移除。之後您就能刪"
+"除帳號了。"
+
+#. %1 is a link to the amo-editors mailing list
+#: views/users/delete.thtml:71
+msgid "user_del_error_addons_more_questions"
+msgstr "如果您有其他,請è¯çµ¡ %1$s 尋求å”助。"
+
+#: views/users/delete.thtml:78
+msgid "user_del_error_checkbox"
+msgstr "您必須è¦å‹¾é¸ã€Œæˆ‘了解…ã€æˆ‘們æ‰èƒ½å°‡æ‚¨çš„帳號移除。"
+
+#: views/users/delete.thtml:84
+msgid "user_del_error_password"
+msgstr "請輸入正確的密碼以完æˆé€™å€‹æ­¥é©Ÿã€‚"
+
+#. %1 is a link to the amo-admins mailing list
+#: views/users/delete.thtml:91
+msgid "user_del_error_unknown"
+msgstr ""
+"在刪除帳號時發生ä¸æ˜Žçš„éŒ¯èª¤ã€‚è«‹å‘ %1$s 通知這個å•é¡Œï¼Œæˆ‘們會幫您手動移除帳號。我"
+"們å°é€ æˆçš„ä¸ä¾¿æ„Ÿåˆ°æŠ±æ­‰ã€‚"
+
+#: views/users/delete.thtml:110
+msgid "user_del_header_confirm_deletion"
+msgstr "確èªåˆªé™¤å¸³è™Ÿ"
+
+#. %1 is the user's email address
+#: views/users/delete.thtml:100
+msgid "user_del_header_delete_account"
+msgstr "刪除使用者帳號 %1$s"
+
+#: views/users/delete.thtml:50
+msgid "user_del_header_farewell"
+msgstr "å†æœƒäº†ï¼"
+
+#: views/users/delete.thtml:115
+msgid "user_del_nologin"
+msgstr "您以後將無法登入 Mozilla 附加元件網站。"
+
+#: views/users/delete.thtml:112
+msgid "user_del_permanently_removed_means"
+msgstr "按下「刪除ã€å°‡æœƒå°‡æ‚¨å¸³è™Ÿ<strong>永久刪除</strong>。這代表:"
+
+#: views/users/delete.thtml:116
+msgid "user_del_reviews_anonymized"
+msgstr "您的æ„見和評分ä¸æœƒè¢«åˆªé™¤ï¼Œä½†é‚£äº›è³‡æ–™èˆ‡å¸³è™Ÿçš„連çµæœƒè¢«åˆ‡æ–·ã€‚"
+
+#. %1 is a link to the amo-editors mailing list
+#: views/users/delete.thtml:104
+msgid "user_del_specific_problem_editors"
+msgstr ""
+"若您有任何我們å¯èƒ½èƒ½å¹«ä¸Šå¿™çš„å•é¡Œï¼Œè«‹åˆ¥åˆªæŽ‰æ‚¨çš„帳號,而是到 %1$s è¯çµ¡æˆ‘們,我們"
+"會竭盡所能的幫助您解決å•é¡Œã€‚"
+
+#: views/users/delete.thtml:130
+msgid "user_del_understand_permanent"
+msgstr "我了解這個動作無法復原。"
+
+#: views/helpers/addons_html.php:192
+msgid "user_deleted_nickname"
+msgstr "刪除使用者帳號"
+
+#. %1 is the new email address
+#: views/users/edit.thtml:71
+msgid "user_edit_confirm_email_sent"
+msgstr ""
+"我們已寄出一å°ä¿¡åˆ° %1$s 以確èªæ‚¨çš„æ–° Email 地å€ã€‚您必須按下信中的éˆçµæ‰ç®—å®Œæˆ "
+"Email 變更的程åºã€‚在完æˆè®Šæ›´ç¨‹åºä»¥å‰ï¼Œæ‚¨é‚„是å¯ä»¥ç”¨ç¾åœ¨çš„ Email 地å€ç™»å…¥ç¶²ç«™ã€‚"
+
+#: views/users/edit.thtml:201
+msgid "user_edit_delete_user"
+msgstr "刪除使用者帳號"
+
+#. This contains the email sent to users when they signed up for a new
+#. account:
+#. %1 is the confirmation URL, %2 is the current app
+#: views/users/email/confirm_plain.thtml:6
+#, php-format
+msgid "user_email_confirm_account_nopass"
+msgstr ""
+"歡迎來到 %2$s 附加元件網站。\n"
+"\n"
+"您需è¦åœ¨ä½¿ç”¨æ–°çš„帳號之å‰å…ˆå•Ÿå‹•å®ƒâ€”—這能確ä¿æ‚¨ä½¿ç”¨çš„ Email 地å€æ˜¯æœ‰æ•ˆä¸”確實為您"
+"所有。\n"
+"è‹¥è¦å•Ÿå‹•æ‚¨çš„帳號,請點é¸ä»¥ä¸‹çš„éˆçµï¼Œæˆ–將以下內容複製到您ç€è¦½å™¨çš„ä½å€åˆ—:\n"
+"\n"
+"%1$s\n"
+"\n"
+"當您æˆåŠŸåœ°å•Ÿå‹•æ‚¨çš„帳號後,您å¯ä»¥å°‡é€™å° Email æŸä¹‹é«˜é–£ã€‚\n"
+"\n"
+"æ„Ÿè¬æ‚¨åŠ å…¥ %2$s 附加元件網站\n"
+"-- %2$s 附加元件網站工作人員"
+
+#. %1 is the confirmation url, %2 is the application name
+#: views/users/email/emailchange_plain.thtml:5
+msgid "user_email_confirm_emailchange"
+msgstr ""
+"您已è¦æ±‚變更 %2$s 附加元件網站上的 Email 地å€ã€‚\n"
+"\n"
+"為了確èªæ‚¨çš„æ–° Email 地å€ï¼Œè«‹æŒ‰ä¸‹é¢çš„éˆçµæˆ–複製整串網å€åˆ°ç€è¦½å™¨çš„ä½å€åˆ—後貼上"
+"以啟用您的帳號:\n"
+"\n"
+"%1$s\n"
+"\n"
+"您有 48 å°æ™‚的時間å¯ç¢ºèªæ–° Email 地å€ã€‚若您中途å悔,ä¸æƒ³è®Šæ›´ Email 地å€çš„話,"
+"è«‹ä¸è¦ç†æœƒé€™å°ä¿¡å³å¯ã€‚\n"
+"\n"
+"æ„Ÿè¬æ‚¨ï¼\n"
+"-- %2$s 附加元件開發å°çµ„"
+
+#: controllers/users_controller.php:168
+#, php-format
+msgid "user_email_confirm_subject"
+msgstr "æ„Ÿè¬æ‚¨åŠ å…¥ %s 附加元件"
+
+#. This is the password reset email
+#. %1 is the pw reset URL, %2 is the application
+#: views/users/email/pwreset_plain.thtml:5
+#, php-format
+msgid "user_email_pwreset"
+msgstr ""
+"%2$s 附加元件密碼é‡è¨­\n"
+"\n"
+"我們已收到您è¦æ±‚é‡è¨­ addons.mozilla.org 上的密碼。請按下é¢çš„éˆçµæˆ–複製整串網å€"
+"到ç€è¦½å™¨çš„ä½å€åˆ—後貼上以變更密碼:\n"
+"\n"
+"%1$s\n"
+"\n"
+"如果您從來沒有è¦æ±‚é‡è¨­å¯†ç¢¼è«‹ä¸è¦ç†æœƒé€™å°ä¿¡ã€‚\n"
+"\n"
+"éžå¸¸æ„Ÿè¬ã€‚\n"
+"-- %2$s 附加元件開發å°çµ„"
+
+#: controllers/users_controller.php:245
+#, php-format
+msgid "user_email_pwreset_subject"
+msgstr "é‡è¨­ %s 附加元件密碼"
+
+#: views/users/emailchange.thtml:50
+msgid "user_emailchange_error"
+msgstr "錯誤ï¼"
+
+#. %1 is the application name
+#: controllers/users_controller.php:533
+msgid "user_emailchange_subject"
+msgstr "請確èªæ‚¨åœ¨ %1$s 附加元件網站變更的 Email 地å€"
+
+#: views/users/emailchange.thtml:48
+msgid "user_emailchange_success"
+msgstr "æˆåŠŸï¼"
+
+#. %1 is the new email address
+#: views/users/emailchange.thtml:49
+msgid "user_emailchange_successful_description"
+msgstr "您的 Email 地å€å·²è®Šæ›´æˆåŠŸï¼Œå¾žç¾åœ¨èµ·è«‹ç”¨ %1$s 來登入網站。"
+
+#: views/users/edit.thtml:134 views/admin/users_edit.thtml:111
+msgid "user_form_bio"
+msgstr "有關我"
+
+#: views/users/edit.thtml:135 views/admin/users_edit.thtml:112
+msgid "user_form_bio_description"
+msgstr ""
+"如果您願æ„,å‘社群介紹您自己å§ï¼é€™æ®µæ–‡å­—將會在您的使用者資訊é é¢å…¬é–‹ã€‚斷行將會"
+"被ä¿ç•™ï¼Œä½†ä¸å…許輸入 HTML 語法。"
+
+#: views/users/pwreset.thtml:77 views/users/register.thtml:73
+#: views/users/edit.thtml:181
+msgid "user_form_confirmpassword"
+msgstr "è«‹å†æ¬¡è¼¸å…¥å¯†ç¢¼"
+
+#: views/users/edit.thtml:145
+msgid "user_form_display_collections"
+msgstr "在我的使用者檔案顯示我所建立的收è—集"
+
+#: views/users/edit.thtml:149
+msgid "user_form_display_collections_fav"
+msgstr "在我的使用者檔案顯示我最愛的收è—集"
+
+#: views/users/edit.thtml:86
+#, php-format
+msgid "user_form_editprofile"
+msgstr "編輯 %s 的使用者檔案"
+
+#: views/users/pwreset.thtml:52 views/users/login.thtml:81
+#: views/users/register.thtml:63 views/users/edit.thtml:187
+msgid "user_form_email"
+msgstr "Email 地å€"
+
+#: views/users/register.thtml:78 views/users/edit.thtml:103
+#: views/admin/users_edit.thtml:76
+msgid "user_form_firstname"
+msgstr "åå­—"
+
+#: views/users/register.thtml:94 views/users/edit.thtml:119
+#: views/admin/users_edit.thtml:91
+msgid "user_form_hideemail"
+msgstr "我è¦éš±è— Email 地å€"
+
+#: views/users/register.thtml:98 views/users/edit.thtml:123
+#: views/admin/users_edit.thtml:99
+msgid "user_form_homepage"
+msgstr "網站 URL"
+
+#: views/users/register.thtml:84 views/users/edit.thtml:109
+#: views/admin/users_edit.thtml:81
+msgid "user_form_lastname"
+msgstr "姓æ°"
+
+#: controllers/users_controller.php:333
+msgid "user_form_login"
+msgstr "使用者登入"
+
+#: views/users/pwreset.thtml:72 views/users/edit.thtml:176
+msgid "user_form_newpassword"
+msgstr "新密碼"
+
+#: views/users/register.thtml:89 views/users/edit.thtml:114
+#: views/admin/users_edit.thtml:86
+msgid "user_form_nickname"
+msgstr "暱稱"
+
+#: views/users/edit.thtml:171
+msgid "user_form_oldpassword"
+msgstr "舊密碼"
+
+#: views/users/edit.thtml:97 views/users/edit.thtml:200
+msgid "user_form_otheractions"
+msgstr "其他動作"
+
+#: views/users/login.thtml:85 views/users/register.thtml:68
+msgid "user_form_password"
+msgstr "密碼"
+
+#: controllers/users_controller.php:93
+msgid "user_form_registration"
+msgstr "新使用者註冊"
+
+#: views/users/login.thtml:90
+msgid "user_form_remember_me"
+msgstr "在此電腦上記ä½æˆ‘"
+
+#: views/admin/users_edit.thtml:95
+msgid "user_form_showsandbox"
+msgstr "我è¦é¡¯ç¤ºã€Œæ²™ç®±ã€å€ï¼Ÿ"
+
+#: views/users/edit.thtml:205
+msgid "user_form_submit_edit"
+msgstr "儲存"
+
+#: views/users/login.thtml:93
+msgid "user_form_submit_login"
+msgstr "登入"
+
+#: views/users/register.thtml:113
+msgid "user_form_submit_register"
+msgstr "註冊"
+
+#: views/users/info.thtml:75
+#, php-format
+msgid "user_info_usersince"
+msgstr "%s 附加元件註冊日期"
+
+#: views/users/login.thtml:102
+msgid "user_login_register_link"
+msgstr "建立新帳號"
+
+#: views/users/edit.thtml:160
+msgid "user_notifications_item_compat"
+msgstr "附加元件相容性 (強烈建議開啟)"
+
+#: views/users/edit.thtml:161
+msgid "user_notifications_item_events"
+msgstr "近期活動與競賽"
+
+#: views/users/edit.thtml:156
+msgid "user_notifications_none_available"
+msgstr "ç›®å‰æ²’有é©åˆçš„通知供您使用。"
+
+#: views/users/edit.thtml:158
+msgid "user_notifications_select_topics"
+msgstr ""
+"Mozilla å°‡ä¸æ™‚å¯„é€ E-mail å‘您通知最新活動與新版本發行。請在下é¢é¸æ“‡æ‚¨æœ‰èˆˆè¶£çš„"
+"主題:"
+
+#: views/users/edit.thtml:164
+msgid "user_notifications_specific_contact"
+msgstr ""
+"Mozilla ä¿ç•™ä½¿ç”¨æ­¤è³‡è¨Šèˆ‡æ‚¨è¯çµ¡ï¼Œè©¢å•é—œæ–¼æ‚¨æ”¾ä¸Šç¶²çš„附加元件相關å•é¡Œçš„權利。"
+
+#: controllers/users_controller.php:543
+msgid "user_profile_edit_error"
+msgstr "您所作的變更中有錯誤,請更正後å†é‡æ–°é€å‡ºä¸€æ¬¡.."
+
+#: controllers/users_controller.php:540
+msgid "user_profile_saved"
+msgstr "使用者檔案已更新。"
+
+#: views/users/pwreset.thtml:65
+#, php-format
+msgid "user_pwreset_for_email"
+msgstr "é‡è¨­ %s 的密碼"
+
+#: controllers/users_controller.php:226
+msgid "user_pwreset_header"
+msgstr "é‡è¨­å¯†ç¢¼"
+
+#: views/users/login.thtml:103
+msgid "user_pwreset_link"
+msgstr "忘記密碼?"
+
+#: controllers/users_controller.php:248
+msgid "user_pwreset_link_sent"
+msgstr "é‡è¨­å¯†ç¢¼çš„éˆçµæœƒå¯„到您的 Email 地å€ã€‚"
+
+#: controllers/users_controller.php:304
+msgid "user_pwreset_okay"
+msgstr "é‡è¨­å¯†ç¢¼æˆåŠŸã€‚"
+
+#: views/users/pwreset.thtml:82
+msgid "user_pwreset_submit_changepw"
+msgstr "é€å‡ºå¯†ç¢¼è®Šæ›´"
+
+#: views/users/pwreset.thtml:57
+msgid "user_pwreset_submit_sendlink"
+msgstr "寄出é‡è¨­å¯†ç¢¼éˆçµ"
+
+#: views/users/register_complete.thtml:51
+#, php-format
+msgid "user_register_amo_link"
+msgstr "%s 附加元件"
+
+#. %1 is the user's email address, %2 is the current app
+#: views/users/activatefirst.thtml:49
+#, php-format
+msgid "user_register_click_confirm_link"
+msgstr ""
+"啟動您帳號的éˆçµå·²å¯„到您的 Email åœ°å€ %1$s,在您登入 %2$s 附加元件之å‰å¿…須先按"
+"下該éˆçµä»¥å•Ÿå‹•å¸³è™Ÿã€‚"
+
+#. %1 is the user's email address
+#: views/users/register_complete.thtml:49
+#, php-format
+msgid "user_register_confirm_email_sent"
+msgstr ""
+"我們已經寄出一å°ä¿¡åˆ°æ‚¨çš„ Email ä½å€ %1$s 以確èªå¸³è™Ÿã€‚在您登入å‰å¿…須按下該éˆçµ"
+"啟用您的帳號。"
+
+#: views/users/activatefirst.thtml:51
+msgid "user_register_confirmation_link_text"
+msgstr "é‡å¯„確èªä¿¡"
+
+#: views/users/register_complete.thtml:47
+msgid "user_register_congratulations"
+msgstr "æ­å–œæ‚¨ï¼æ‚¨çš„使用者帳號已æˆåŠŸå»ºç«‹ã€‚"
+
+#: views/users/register.thtml:50
+msgid "user_register_details"
+msgstr ""
+"<p>如果您åªæ˜¯è¦ä¸‹è¼‰ä¸¦å®‰è£å…¬é–‹çš„附加元件,您<strong>ä¸éœ€è¦</strong>在 AMO 註"
+"冊。</p><p>您什麼時候需è¦è¨»å†Šï¼š</p><ul><li>您è¦ç™¼è¡¨å°é™„加元件的æ„見</li><li>您"
+"是附加元件的開發者,想è¦ä¸Šå‚³æ‚¨çš„附加元件並放在 AMO</li></ul><p>註冊æˆåŠŸå¾Œï¼Œæ‚¨"
+"將在所æ供的 email 地å€ä¸­æ”¶åˆ°ä¸€å°ç¢ºèªä¿¡ã€‚è«‹éµç…§ä¿¡ä¸­æŒ‡ç¤ºçš„步驟確èªæ‚¨çš„帳號。</"
+"p><p>如果您有興趣,å¯ä»¥é–±è®€æˆ‘們的<a href='%1$s' title='法律è²æ˜Ž'>法律è²æ˜Ž</a>"
+"å’Œ<a href='%2$s' title='éš±ç§æ”¿ç­–'>éš±ç§æ”¿ç­–</a>。</p>"
+
+#. %1 is the link to the "resend confirmation code" page
+#: views/users/activatefirst.thtml:51
+#, php-format
+msgid "user_register_resend_confirmation_link"
+msgstr ""
+"如果您還沒收到信,請確定您的 Email æœå‹™æ²’有將它標示為「垃圾郵件ã€æˆ–「廣告ã€ã€‚"
+"如果您需è¦çš„話,å¯ä»¥%1$s到您的 Email 地å€ã€‚"
+
+#. %1 is the link to the Mozilla Add-ons front page
+#: views/users/register_complete.thtml:51
+#, php-format
+msgid "user_register_welcome"
+msgstr "æ„Ÿè¬æ‚¨è¨»å†Šä¸¦æ­¡è¿ŽåŠ å…¥ %1$sï¼"
+
+#: views/users/register.thtml:49
+msgid "user_register_welcome_header"
+msgstr "歡迎來到 addons.mozilla.org(AMO)ï¼"
+
+#: views/users/register.thtml:81 views/users/edit.thtml:106
+msgid "user_required_firstlast_or_nickname"
+msgstr "需è¦å§“æ°ã€å稱或是暱稱之一。"
+
+#: views/users/edit.thtml:94 views/users/edit.thtml:142
+msgid "user_tab_collections"
+msgstr "收è—集"
+
+#: views/users/edit.thtml:95 views/users/edit.thtml:154
+msgid "user_tab_notifications"
+msgstr "通知"
+
+#: views/users/edit.thtml:93 views/users/edit.thtml:101
+msgid "user_tab_profile"
+msgstr "使用者檔案"
+
+#: controllers/users_controller.php:209
+msgid "user_verified_okay"
+msgstr "é©—è­‰æˆåŠŸï¼"
+
+#: controllers/users_controller.php:723
+msgid "users_delete_pagetitle"
+msgstr "刪除使用者帳號"
+
+#: controllers/users_controller.php:414
+msgid "users_edit_pagetitle"
+msgstr "編輯使用者帳號"
+
+#: views/users/info.thtml:71
+msgid "users_info_aboutme"
+msgstr "有關我"
+
+#: views/users/info.thtml:96
+#, php-format
+msgid "users_info_addons_by_user"
+msgstr "%1$s 的附加元件"
+
+#: views/users/info.thtml:51
+msgid "users_info_author_name"
+msgstr "å稱"
+
+#: views/users/info.thtml:48
+msgid "users_info_author_profile"
+msgstr "使用者檔案"
+
+#. %s is the user name
+#: views/users/info.thtml:137
+msgid "users_info_collections_by_user"
+msgstr "%s 所作的收è—集"
+
+#: views/users/info.thtml:66
+msgid "users_info_email"
+msgstr "Email 地å€"
+
+#: views/users/info.thtml:155
+msgid "users_info_fav_collections_by_user"
+msgstr "最愛的收è—集"
+
+#: views/users/info.thtml:61
+msgid "users_info_homepage"
+msgstr "個人首é "
+
+#: views/users/info.thtml:56
+msgid "users_info_nickname"
+msgstr "暱稱"
+
+#: controllers/users_controller.php:707
+#, php-format
+msgid "users_info_pagetitle"
+msgstr "%1$s 的使用者資訊"
+
+#. %1 is the user's name
+#: views/users/info.thtml:116
+msgid "users_info_reviews_by_user"
+msgstr "%s 撰寫的æ„見"
+
+#: controllers/users_controller.php:330 controllers/users_controller.php:332
+msgid "users_login_pagetitle"
+msgstr "使用者登入"
+
+#. %1 is the link to the sandbox/policy explanation page
+#. This message is for a specific add-on not found
+#: views/users/login.thtml:53
+#, php-format
+msgid "users_login_sandbox_display_warning"
+msgstr ""
+"您正在ç€è¦½çš„附加元件放在「沙箱ã€å€ä¸­ï¼Œå¦‚果您有 Mozilla 附加元件的帳號,請先登"
+"入或<a href=\"%1$s\">了解什麼是「沙箱ã€å€</a>。"
+
+#. %1 is the link to the sandbox/policy explanation page
+#. This message is for any given sandbox-related page not found
+#: views/users/login.thtml:56
+#, php-format
+msgid "users_login_sandbox_page_warning"
+msgstr ""
+"您正在ç€è¦½çš„é é¢æ˜¯ã€Œæ²™ç®±ã€å€çš„一部分。如果您有 Mozilla 附加元件的帳號,請先登"
+"入或<a href=\"%1$s\">了解什麼是「沙箱ã€å€</a>。"
+
+#: controllers/users_controller.php:223 controllers/users_controller.php:225
+msgid "users_pwreset_pagetitle"
+msgstr "使用者密碼é‡è¨­"
+
+#: controllers/users_controller.php:90 controllers/users_controller.php:92
+msgid "users_register_pagetitle"
+msgstr "新使用者註冊"
+
+#. %1$s is an addon name, like <a>Firebug</a>
+#. %2$s is a version number, like <a>1.2</a>
+#: views/versions/license.thtml:52
+msgid "versions_license_header_source"
+msgstr "%1$s %2$s 的原始碼授權æ¢æ¬¾"
+
+#: views/addons/category_landing.thtml:147
+msgid "view_recently_added"
+msgstr "檢視所有最近新增"
+
+#: views/addons/category_landing.thtml:161
+msgid "view_top_downloads"
+msgstr "檢視所有下載排行"
+
+#: views/addons/category_landing.thtml:175
+msgid "view_top_rated"
+msgstr "檢視所有評分排行"
diff --git a/site/app/locale/zh_TW/images/sandbox-review.png b/site/app/locale/zh_TW/images/sandbox-review.png
new file mode 100644
index 0000000..dd68cc8
--- /dev/null
+++ b/site/app/locale/zh_TW/images/sandbox-review.png
Binary files differ
diff --git a/site/app/locale/zh_TW/pages/about.thtml b/site/app/locale/zh_TW/pages/about.thtml
new file mode 100644
index 0000000..ee5e85d
--- /dev/null
+++ b/site/app/locale/zh_TW/pages/about.thtml
@@ -0,0 +1,57 @@
+<h2>什麼是 addons.mozilla.org?</h2>
+<p>
+ addons.mozilla.org (AMO) 是屬於 Mozilla 應用程å¼é™„加元件的 Mozilla 官方網站。
+ 附加元件讓您新增功能到 Firefoxã€Thunderbirdã€SeaMonkey å’Œ Sunbird。
+ 您å¯ä»¥åœ¨ AMO ç€è¦½ä¸¦ä¸‹è¼‰æˆåƒä¸Šè¬çš„附加元件,並改變您使用網際網路的方å¼ã€‚
+</p>
+
+<h2>誰建立了這些附加元件?</h2>
+<p>
+ 由上åƒä½ï¼Œå¾žå–®ç¨çš„愛好者到大公å¸éƒ½æœ‰çš„附加元件開發者所為。
+ 所有公開的附加元件在釋出å‰éƒ½ç¶“éŽè·å“¡æˆ–專屬志工所審核。
+ 尚未被審核的項目則會被標示為實驗中附加元件。
+</p>
+
+<h2>我è¦å¦‚何隨時得知 AMO 的最新消æ¯ï¼Ÿ</h2>
+<p>
+ 我們會定期更新<a href="http://blog.mozilla.com/addons/">部è½æ ¼</a>,而且會經常引介一般社群的文章。
+ 我們也有約æ¯ä¸€å€‹æœˆå‡ºåˆŠä¸€æ¬¡çš„<a href="https://addons.mozilla.org/newsletter">é›»å­å ±</a>。
+</p>
+
+<h2>這真ä¸éŒ¯ï¼æˆ‘è¦å¦‚何åƒèˆ‡ï¼Ÿ</h2>
+<p>
+ 有許多方å¼å¯ä»¥åƒèˆ‡ï¼š
+</p>
+<ul>
+ <li>
+ <a href="https://wiki.mozilla.org/AMO:Editors/Applying">æˆç‚ºä¸€å€‹å¯©æ ¸è€…</a>。
+ 我們的審核者是具有技術背景的AMO粉絲,會ä¾æ“šç¨‹å¼ç¢¼çš„å“質和穩定性審核附加元件。
+ </li>
+ <li>
+ <a href="http://developer.mozilla.org/">製作您自己的附加元件</a>。
+ AMOæä¾›å…費的寄存和更新æœå‹™ï¼Œå¯ä»¥å¹«åŠ©æ‚¨èˆ‡å»£å¤§çš„使用者群間相接觸。
+ </li>
+ <li>
+ 告訴您的朋å‹ï¼<a href="http://spreadfirefox.com/">推廣 Firefox</a>
+ 並且告訴大家您使用的附加元件。
+ </li>
+ <li>
+ éžäº¤ç¨‹å¼éŒ¯èª¤å’Œä¿®æ­£ã€‚
+ <a href="https://bugzilla.mozilla.org/buglist.cgi?quicksearch=addons">Bugzilla</a>
+ 包å«ç›®å‰ AMO 網站的所有程å¼éŒ¯èª¤ã€‚您å¯ä»¥éžäº¤å°šæœªç™¼ç¾çš„程å¼éŒ¯èª¤æˆ–æ供修正檔。
+ </li>
+</ul>
+
+<h2>我有å•é¡Œï¼</h2>
+<p>
+ 您å¯ä»¥å…ˆçœ‹çœ‹æˆ‘們的<a href="https://addons.mozilla.org/pages/faq">常見å•é¡Œé›†</a>。
+ 如果您在那兒找ä¸åˆ°ç­”案,您å¯ä»¥ä½¿ç”¨æ­¤é ä¸‹æ–¹çš„è¯çµ¡è³‡è¨Šä¾†è¯çµ¡æˆ‘們。
+ 若是å°æ–¼ç‰¹å®šé™„加元件的å•é¡Œï¼Œè«‹åˆ©ç”¨è©²é™„加元件列表é ä¸­æ‰€é™„çš„è¯çµ¡è³‡è¨Šã€‚
+</p>
+
+<h2>è¯çµ¡æˆ‘們</h2>
+<dl>
+ <dt>é€éŽ<abbr title="Internet Relay Chat">IRC</abbr>:</dt>
+ <dd>一般與審核å•é¡Œï¼Œè«‹åˆ° irc.mozilla.org çš„ <a href="irc://irc.mozilla.org/#addons">#addons</a></dd>
+ <dd>管ç†å’Œé–‹ç™¼äº‹é …,請到 irc.mozilla.org çš„ <a href="irc://irc.mozilla.org/#amo">#amo</a></dd>
+</dl>
diff --git a/site/app/locale/zh_TW/pages/collector.thtml b/site/app/locale/zh_TW/pages/collector.thtml
new file mode 100644
index 0000000..9dcfd5b
--- /dev/null
+++ b/site/app/locale/zh_TW/pages/collector.thtml
@@ -0,0 +1,45 @@
+<h2>Mozilla Firefox Add-on Collector</h2>
+
+<p class="intro">讓您的ç€è¦½å™¨å§‹çµ‚æ­ä¸Šæœ€æ™‚髦的é…備。</p>
+
+<div class="primary">
+ <p>在易於管ç†çš„收è—集中,尋找更多超棒的附加元件並組織您的最愛。訂閱收è—集,來看看您喜歡的收è—集是如何日漸èŒå£¯ï¼Œä»¥åŠç•¶æ‚¨ç®¡ç†å’Œæ›´æ–°è‡ªå·±çš„收è—集時,粉絲們的追隨狀æ³ã€‚</p>
+</div>
+
+<div class="secondary">
+ <div class="highlight">
+ <h4>下載 Add-on Collector:</h4>
+ %1$s
+ </div><!-- /.highlight -->
+</div>
+
+<div class="column-wrapper article-wrapper">
+
+ <div class="column first">
+ <div class="article">
+ <h3>推薦的收è—集</h3>
+ <p>訂閱一個附加元件的收è—集,並在其發展時得到通知。如果您在建立收è—集,會留下空間讓你告訴大家為何您喜歡æŸå€‹å…ƒä»¶ï¼Œä¸¦é™„下一些自訂內容。</p>
+ </div>
+ </div>
+
+ <div class="column">
+ <div class="article">
+ <h3>分享附加元件</h3>
+ <p>æ醒朋å‹æ‚¨çš„新發ç¾ã€‚é¸æ“‡ã€Œç™¼è¡¨çµ¦ã€å¾Œï¼Œæ‚¨çš„朋å‹å€‘就會接到由來æºï¼ˆå°±æ˜¯æ‚¨ï¼ï¼‰ç°½ç™¼è€Œå®Œå–„的附加元件相關訊æ¯ã€‚</p>
+ </div>
+ </div>
+
+
+ <div class="column">
+ <div class="article">
+ <h3>從所有來æºåŒæ­¥</h3>
+ <p>多虧有了自動發表,å¯ä»¥åœ¨æ–°çš„附加元件收è—集出ç¾æ™‚通報,並æä¾›ä¿æŒæœ€æ–°ç‹€æ…‹çš„éˆçµã€‚åŒæ­¥æ–¼è£ç½®ä¹‹é–“,讓所有您的ç€è¦½å™¨éƒ½æ­ä¸Šæ‚¨æœ€æ–°çš„收è—集。</p>
+ </div>
+ </div>
+
+</div><!-- /.column-wrapper .article-wrapper -->
+
+<ul class="further-navigation">
+ <li><a href="%2$s">Add-on Collector 功能</a></li>
+ <li><a href="%3$s">常見å•é¡Œé›†</a></li>
+</ul>
diff --git a/site/app/locale/zh_TW/pages/collector_faq.thtml b/site/app/locale/zh_TW/pages/collector_faq.thtml
new file mode 100644
index 0000000..c3ea296
--- /dev/null
+++ b/site/app/locale/zh_TW/pages/collector_faq.thtml
@@ -0,0 +1,24 @@
+<h2>Add-on Collector 常見å•é¡Œé›†</h2>
+
+<dl class="faq">
+<dt>什麼是收è—集?</dt>
+<dd>收è—集是將相關的附加元件集çµèµ·ä¾†ï¼Œä»¥æ–¹ä¾¿åˆ†äº«çš„群集。</dd>
+
+<dt>什麼是 Add-on Collector?</dt>
+<dd>Add-on Collector 是一個用於 Firefox 的擴充套件,讓您能簡單地與您喜愛的收è—集間ä¿æŒåŒæ­¥ç‹€æ…‹ã€‚</dd>
+
+<dt>使用 Add-on Collector å‰æˆ‘需è¦æº–備什麼呢?</dt>
+<dd>您需è¦ä¸€å€‹ <a href="%s">Mozilla 附加元件網站帳號</a>,以åŠæœ€æ–°ç‰ˆæœ¬çš„ <a href="http://www.getfirefox.com">Firefox</a>。</dd>
+
+<dt>我è¦å¦‚何訂閱一個收è—集?</dt>
+<dd>您å¯ä»¥åœ¨<a href="%s">收è—集目錄</a>中將收è—集標為最愛來訂閱收è—集。您最愛的收è—集接著會在附加元件管ç†å™¨ä¸­é¡¯ç¤ºç‚ºè¨‚閱項目。</dd>
+
+<dt>我è¦å¦‚何使用 Add-on Collector 在電腦間åŒæ­¥æˆ‘的附加元件?</dt>
+<dd>åªè¦åœ¨ä¸€å°é›»è…¦ä¸­è¨­å®šå¥½è‡ªå‹•ç™¼è¡¨ï¼Œå®ƒå°±æœƒå‡ºç¾æ–¼æ‰€æœ‰å·²å®‰è£ Add-on Collector 電腦內訂閱列表的頂端。然後您將å¯ä»¥çœ‹è¦‹æ¯å°è¨­å®šå¥½è‡ªå‹•ç™¼è¡¨çš„電腦所安è£çš„元件。</dd>
+
+<dt>Mozilla Labs çš„ Weave ä¸æ˜¯æ­£è‡´åŠ›æ–¼é™„加元件的åŒæ­¥å—Žï¼Ÿ</dt>
+<dd>Weave 的確計畫在未來將支æ´å€‹äººè¨­å®šæª”å’Œè£ç½®é–“的附加元件åŒæ­¥ã€‚然而 Add-on Collector çš„åŒæ­¥æ–¹å¼æœ‰é‚£éº¼ä¸€é»žä¸åŒï¼šæ‚¨è‡ªå‹•ç™¼è¡¨çš„資料並ä¸æœƒé€²è¡ŒåŠ å¯†ï¼Œè€Œæ˜¯è¨­è¨ˆç”¨ä¾†ä»¥æ”¶è—集的方å¼å’Œæœ‹å‹åˆ†äº«ã€‚也å¯ä»¥ç”¨å¤šå€‹æ”¶è—集在ä¸åŒå€‹äººè¨­å®šæª”間分享附加元件。</dd>
+
+<dt>我å¯ä»¥åœ¨å“ªè£¡æä¾›æ„見或回報臭蟲?</dt>
+<dd>如果您發ç¾äº†è‡­èŸ²ï¼Œæˆ–著想給予功能建議,請用 Bugzilla 下的<a href="https://bugzilla.mozilla.org/enter_bug.cgi?component=Bandwagon&amp;product=addons.mozilla.org">這個表單</a>將其建檔。如果您想æ供一般的æ„見回饋,請將其張貼到<a href="http://groups.google.com/group/mozilla.dev.amo">我們的新èžç¾¤çµ„</a>。</dd>
+</dl>
diff --git a/site/app/locale/zh_TW/pages/collector_features.thtml b/site/app/locale/zh_TW/pages/collector_features.thtml
new file mode 100644
index 0000000..d29a22d
--- /dev/null
+++ b/site/app/locale/zh_TW/pages/collector_features.thtml
@@ -0,0 +1,30 @@
+<h2>Mozilla Firefox Add-on Collector</h2>
+<h4>讓您的ç€è¦½å™¨å§‹çµ‚æ­ä¸Šæœ€æ™‚髦的é…備。</h4>
+<h3>擴充元件功能</h3>
+<p>
+ Add-on Collector é€éŽä»¥ä¸‹çš„æ–¹å¼ï¼Œè®“您ä¿æŒèˆ‡å–œæ„›é™„加元件之間的è¯ç¹«ï¼š
+</p>
+
+<dl>
+ <dt>從 Firefox å­˜å–您最愛的收è—集</dt>
+ <dd>
+ 在<a href="%1$s">收è—集目錄</a>被您標示為最愛的收è—集,將會出ç¾åœ¨é™„加元件
+ 管ç†å™¨ä¸­ä¸€å€‹ç‰¹åˆ¥çš„地方。您將å¯ä»¥ç¶­æŒæ–¼æœ€æ–°ç‹€æ…‹å’Œæª¢è¦–å„收è—集中的內容。
+ </dd>
+ <dt>使用發表功能表分享附加元件</dt>
+ <dd>
+ æ¯å€‹æ‚¨å®‰è£çš„é™„åŠ å…ƒä»¶ï¼Œéƒ½èƒ½åˆ©ç”¨ç™¼è¡¨åŠŸèƒ½è¡¨å¯„é€ Email 或發表到您的收è—集,
+ 輕鬆地分享給您的朋å‹ã€‚
+ </dd>
+ <dt>接收通知</dt>
+ <dd>
+ Add-on Collector 將會在您最愛的收è—集有新的項目時通知,並將其標示起來,讓
+ 您å¯ä»¥åœ¨ç¨å¾Œæª¢æŸ¥ã€‚
+ </dd>
+
+ <dt>自動發表您安è£çš„附加元件到收è—集</dt>
+ <dd>
+ 自動發表功能讓您的收è—集æŒçºŒæ›´æ–°æˆç›®å‰çš„附加元件,讓訂閱收è—集的朋å‹å€‘也能
+ ä¿æŒåœ¨æœ€æ–°ç‹€æ…‹ã€‚
+ </dd>
+</dl>
diff --git a/site/app/locale/zh_TW/pages/collector_firstrun.thtml b/site/app/locale/zh_TW/pages/collector_firstrun.thtml
new file mode 100644
index 0000000..5181546
--- /dev/null
+++ b/site/app/locale/zh_TW/pages/collector_firstrun.thtml
@@ -0,0 +1,38 @@
+<div>
+ <h2>æ­¡è¿Ž</h2>
+ <p class="intro">Firefox çš„ Add-on Collector 已經被安è£åœ¨æ‚¨çš„ Firefox ç€è¦½å™¨ä¸­ã€‚您緊接著就å¯ä»¥å»ºç«‹ã€ç®¡ç†ã€åˆ†äº«å’ŒæŽ¥æ”¶é™„加元件收è—集。</p>
+</div>
+
+ <div class="primary">
+ <h3>è¦é–‹å§‹ä½¿ç”¨æ‚¨ Firefox çš„ Add-on Collector</h3>
+ <ol class="numbered">
+ <li>
+ <h4 class="step">1</h4>
+ 按下 Firefox 工具列中的「工具ã€åŠŸèƒ½è¡¨ï¼Œé¸æ“‡ã€Œé™„加元件ã€ã€‚
+ </li>
+ <li>
+ <h4 class="step">2</h4>
+ 在「訂閱ã€çª—格,以您 Mozilla 附加元件網站的帳號資訊登入。
+ </li>
+ <li>
+ <h4 class="step">3</h4>
+ 您將會在左å´çœ‹åˆ°æ‚¨æ‰€æœ‰æ”¶è—集的列表。按下任何一個收è—集來檢視其詳細內容。按下「增加到 Firefoxã€æˆ–「發表給ã€ä¾†ç®¡ç†æ‚¨çš„收è—集或é€éŽ Email 傳é€çµ¦æœ‹å‹ã€‚
+ </li>
+ </ol>
+ <p>無論您是附加元件的狂熱粉絲,還是僅僅é€éŽé™„加元件來改進網路使用經驗的人,Add-on Collector 都能幫上忙。有關 Firefox 下 Add-on Collector 的功能和常被å•åˆ°çš„å•é¡Œï¼Œå¯ä»¥çœ‹çœ‹<a href="%1$s">功能介紹é </a>與<a href="%2$s">常見å•é¡Œé›†</a>。</p>
+ </div><!-- / .primary -->
+
+ <div class="secondary">
+ <div class="highlight">
+ <h4>從這些收è—集開始試試</h4>
+
+ <ul>
+ %3$s
+ </ul>
+
+ <ul class="further-navigation">
+ <li><a href="%4$s" class="more-info">檢視所有收è—集</a></li>
+ </ul>
+ </div><!-- /. highlight -->
+ </div><!-- /. secondary-->
+
diff --git a/site/app/locale/zh_TW/pages/compatibility_developer_tips.thtml b/site/app/locale/zh_TW/pages/compatibility_developer_tips.thtml
new file mode 100644
index 0000000..b7287dd
--- /dev/null
+++ b/site/app/locale/zh_TW/pages/compatibility_developer_tips.thtml
@@ -0,0 +1,6 @@
+<ul class="tips">
+ <li>將您的套件更新到 %s 的資訊å¯ä»¥åœ¨é€™ç¯‡ <a href="https://developer.mozilla.org/En/Updating_extensions_for_%s">Mozilla 開發者中心的文章</a>中找到。</li>
+ <li>有關 %s 大致的更新資訊å¯ä»¥åœ¨<a href="https://developer.mozilla.org/en/%s_for_developers">這篇文章</a>找到。</li>
+ <li>欲知更多消æ¯ï¼Œæ‚¨å¯ä»¥è¨‚é–± <a href="https://addons.mozilla.org/newsletter">about:addons é›»å­å ±</a>å’Œ <a href="http://blog.mozilla.com/addons/">Mozilla 附加元件部è½æ ¼</a>。</li>
+ <li>如果您的元件放在 Mozilla 附加元件網站,且ä¸éœ€è¦ä»»ä½•ç¨‹å¼ç¢¼ä¿®æ”¹å³å¯é”æˆç›¸å®¹ï¼Œæ‚¨ä¸éœ€è¦ä¸Šå‚³æ–°çš„檔案就å¯ä»¥åœ¨èª¿æ•´å…¶ç›¸å®¹ä¹‹ maxVersion,åªè¦ï¼šåœ¨<a href="%s">「開發者工具ã€å€åŸŸä¸­</a>設定,或著é€éŽä¸‹æ–¹çš„元件狀態檢查調整。</li>
+</ul>
diff --git a/site/app/locale/zh_TW/pages/compatibility_user_tips.thtml b/site/app/locale/zh_TW/pages/compatibility_user_tips.thtml
new file mode 100644
index 0000000..9f403af
--- /dev/null
+++ b/site/app/locale/zh_TW/pages/compatibility_user_tips.thtml
@@ -0,0 +1,6 @@
+<ul class="tips">
+ <li>雖然許多附加元件能在ä¸ä¿®æ”¹ä»»ä½•åŽŸå§‹ç¢¼çš„情æ³ä¸‹æ”¯æ´ %s,ä»ç„¶æœ‰å…ƒä»¶éœ€è¦ä½œè€…進行é¡å¤–的調整,以確ä¿å‡ç´šçš„平順。請在這段時間ä¿æŒè€å¿ƒï¼Œç•¢ç«Ÿæœ‰è¨±å¤šå…ƒä»¶é–‹ç™¼è€…是將開發元件視為嗜好而自發地更新他們的元件。</li>
+ <li>Mozilla ä¸é¼“勵將相容性檢查設為åœç”¨ï¼šé€™å¯èƒ½æœƒå°Žè‡´ %s 啟動時發生嚴é‡çš„å•é¡Œï¼Œç”šè‡³é€ æˆè³‡æ–™çš„æ失——如果強制使用ä¸ç›¸å®¹æ–¼æ–°ç‰ˆ %s 的擴充套件。</li>
+ <li>如果您想使用的擴充套件在 %s 推出後ä»ä¸ç›¸å®¹ï¼Œå¯ä»¥çœ‹çœ‹å®ƒå€‘的網站或作者的首é æ˜¯å¦æœ‰èˆ‡æ›´æ–°ç›¸é—œçš„消æ¯ã€‚</li>
+ <li>您也å¯ä»¥è©¦è©¦çœ‹å°‹æ‰¾æ”¯æ´ %s 且æ供類似功能的元件——到<a href="%s">%s 附加元件</a>網站看看。</li>
+</ul>
diff --git a/site/app/locale/zh_TW/pages/developer_faq.thtml b/site/app/locale/zh_TW/pages/developer_faq.thtml
new file mode 100644
index 0000000..d048f59
--- /dev/null
+++ b/site/app/locale/zh_TW/pages/developer_faq.thtml
@@ -0,0 +1,55 @@
+<h2>有關開放æºç¢¼æŽˆæ¬Šçš„資訊</h2>
+<p>
+ 您是å¦éœ€è¦é—œæ–¼å„種開放æºç¢¼æŽˆæ¬Šçš„更多資訊?您是å¦ç–‘惑於è¦é¸æ“‡å“ªä¸€ç¨®æŽˆæ¬Šæ¢æ¬¾ï¼Ÿ
+ 哪些權利在哪些æ¢æ¬¾ä¹‹ä¸­æœƒåŠ ä»¥çµ¦äºˆï¼Ÿé›–然任何形å¼çš„解釋方法都比ä¸ä¸Šè©³é–±æ¢æ¬¾å…¨æ–‡ï¼Œ
+ 底下æ供的網站中,包å«å°ä¸€äº›é‡è¦é–‹æ”¾æºç¢¼æŽˆæ¬Šçš„介紹,也許能幫您å€åˆ†é€™äº›æ¢æ¬¾ã€‚
+ æ供這些網站僅僅是為了方便您,以åšç‚ºæ‚¨å€‹äººç”¨é€”çš„åƒè€ƒï¼›é€™äº›è³‡æºä¸¦ä¸åŒ…å«æ³•å¾‹ä¸Š
+ 的建議,也ä¸æ‡‰è©²å°‡å…¶åœ¨çµ¦äºˆæ³•å¾‹å»ºè­°æ™‚使用。Mozilla æ—¢ä¸ä¿è­‰ï¼Œä¹Ÿä¸å°é€™äº›ç¶²ç«™çš„
+ 內容,以åŠæ‚¨å°é€™äº›å…§å®¹çš„信賴負責。
+</p>
+<dl>
+ <dt>
+ <a href="http://www.mozilla.org/MPL/">http://www.mozilla.org/MPL/</a>
+ </dt>
+ <dd>
+ é™¤äº†åŒ…å« Mozilla Public License(「MPLã€ï¼‰çš„全文,也æ供了包å«è¨»é‡‹çš„ MPL 版本
+ ,和幫助您使用或散布此授權下程å¼ç¢¼çš„ <abbr title="常見å•é¡Œé›†">FAQ</abbr>。
+ (英文)
+ </dd>
+ <dt>
+ <a href="http://developer.kde.org/documentation/licensing/licenses_summary.html">
+ http://developer.kde.org/documentation/licensing/licenses_summary.html
+ </a>
+ </dt>
+ <dd>
+ 一張表格,總çµå’Œæ¯”較了一些關éµé–‹æ”¾æºç¢¼æŽˆæ¬Šå°å¾…散佈ã€å°ˆæœ‰è»Ÿé«”è¯ç¹«ã€é‡æ–°æ•£ä½ˆ
+ 修改éŽçš„程å¼ç¢¼ä¸Šçš„è¦ç¯„。(英文)
+ </dd>
+ <dt>
+ <a href="http://www.fsf.org/licensing/licenses/">
+ http://www.fsf.org/licensing/licenses/
+ </a>
+ </dt>
+ <dd>
+ 自由軟體基金會æ供了å°é—œéµé–‹æ”¾æºç¢¼æŽˆæ¬Šçš„簡單總çµï¼ŒåŒ…å«æŽˆæ¬Šæ˜¯å¦è¢«èªå®šç‚ºè‡ªç”±
+ 軟體授權或是 Copyleft 授權。這也包å«äº†çµ„æˆè‡ªç”±è»Ÿé«”授權或 Copyleft 授權所需
+ æ¢ä»¶çš„相關討論(例如,Copyleft 授權是一種使程å¼æˆ–其他作å“自由的常見方å¼ï¼Œ
+ 且其è¦æ±‚所有修改後和擴充後的程å¼ç‰ˆæœ¬ä¹Ÿå¿…é ˆä¿æŒè‡ªç”±ã€‚) (英文)
+ </dd>
+ <dt>
+ <a href="http://www.opensource.org/licenses/category">
+ http://www.opensource.org/licenses/category
+ </a>
+ </dt>
+ <dd>
+ Open Source Initiative æ供了一些關éµé–‹æ”¾æºç¢¼æŽˆæ¬Šçš„æ¢æ¬¾åŽŸæ–‡ã€‚(英文)
+ </dd>
+ <dt>
+ <a href="http://en.wikipedia.org/wiki/Open_source_license">
+ http://en.wikipedia.org/wiki/Open_source_license
+ </a>
+ </dt>
+ <dd>
+ 英文維基百科上有關 BSD 型態授權æ¢æ¬¾çš„討論。(英文)
+ </dd>
+</dl>
diff --git a/site/app/locale/zh_TW/pages/error404.thtml b/site/app/locale/zh_TW/pages/error404.thtml
new file mode 100644
index 0000000..fe7cf98
--- /dev/null
+++ b/site/app/locale/zh_TW/pages/error404.thtml
@@ -0,0 +1,16 @@
+<h1>真是éžå¸¸æŠ±æ­‰ï¼Œä½†æˆ‘們找ä¸åˆ°ä½ æƒ³æ‰¾çš„æ±è¥¿ã€‚</h1>
+
+<p>你請求的é é¢æˆ–檔案ä¸åœ¨ç¶²ç«™ä¸Šï¼Œå¯èƒ½æ˜¯ä½ æŒ‰äº†éŽæœŸçš„連çµæˆ–輸入了錯誤的網å€ã€‚</p>
+
+<ul>
+<li>如果你用手動輸入網å€ï¼Œè«‹å†æ¬¡ç¢ºèªæœ‰ç„¡æ‹¼å­—錯誤。</li>
+<li>如果你是從其他地方連éŽä¾†ï¼Œè«‹å›žå ±çµ¦ <a href="mailto:webmaster@mozilla.com" title="Page Not Found on Mozilla.com">webmaster@mozilla.com</a>。告訴我們你從哪裡連éŽä¾†å’Œä½ æƒ³æ‰¾ä»€éº¼ï¼Œæˆ‘們會儘速修復。</li>
+</ul>
+
+<p>ä¸ç„¶ä¹¾è„†è·³åˆ°ç¶²ç«™å…¶ä»–地方逛逛å§ã€‚</p>
+
+<ul>
+<li>ä½ å°æˆ‘們的<a href="%1$s">ç²¾é¸é™„加元件</a>有興趣嗎?</li>
+<li>你想<a href="%2$s">æœå°‹é™„加元件</a>嗎?請到<a href="%2$s">æœå°‹é é¢</a>找找或直接利用下é¢çš„æœå°‹æ¬„。</li>
+<li>如果你習慣從頭找起,å¯ä»¥å›žåˆ°<a href="%3$s">附加元件首é </a>。</li>
+</ul>
diff --git a/site/app/locale/zh_TW/pages/faq.thtml b/site/app/locale/zh_TW/pages/faq.thtml
new file mode 100644
index 0000000..027b42d
--- /dev/null
+++ b/site/app/locale/zh_TW/pages/faq.thtml
@@ -0,0 +1,78 @@
+<h1>常見å•é¡Œé›†</h1>
+
+<p>這份 <a href="http://addons.mozilla.org">AMO 網站</a> 的常見å•é¡Œé›†ä¸­ï¼Œæè¿°äº†ç›®å‰ Firefox 線上支æ´ç¶²ç«™æ‰€æ²’有包å«åˆ°çš„議題。支æ´ç¶²ç«™å…§åŒ…å«æœ‰é—œ <a href="http://support.mozilla.com/kb/Customizing+Firefox+with+add-ons">使用附加元件自訂 Firefox</a> 的入門資訊外,也包å«äº†ä»¥ä¸‹ä¸»é¡Œçš„文章:</p>
+
+<ul>
+ <li> <a href="http://support.mozilla.com/kb/Unable+to+install+add-ons">安è£é™„加元件</a>ã€<a href="http://support.mozilla.com/kb/Troubleshooting+plugins">外掛程å¼</a>ã€å’Œ<a href="http://support.mozilla.com/kb/Troubleshooting+extensions+and+themes">一般å•é¡Œ</a>的疑難排解。</li>
+ <li> <a href="http://support.mozilla.com/kb/Uninstalling+add-ons">如何解除安è£é™„加元件</a>å’Œ<a href="http://support.mozilla.com/kb/Cannot+uninstall+an+add-on">解除安è£ç–‘難排解</a>。</li>
+ <li> <a href="http://support.mozilla.com/kb/Gray+bar+below+the+status+bar">處ç†æœ‰å•é¡Œçš„附加元件ï¼å¤šå‡ºçš„ç°è‰²å€å¡Šå•é¡Œ</a></li>
+</ul>
+
+<p></p>
+
+<div id="gsfn_list_widget">
+ <a href="https://getsatisfaction.com/mozilla" class="widget_title">Mozilla 附加元件進行中的客戶æœå‹™è¨Žè«–</a>
+ <div id="gsfn_content">載入中...</div>
+ <div class="powered_by">
+ <a href="https://getsatisfaction.com/"><img alt="Favicon" src="https://www.getsatisfaction.com/favicon.gif" style="vertical-align: middle;" /></a>
+ <a href="https://getsatisfaction.com/">Get Satisfaction 支æ´ç¶²è·¯</a>
+ </div>
+</div>
+
+<h2>附加元件å•é¡Œ</h2>
+<dl class="faq">
+<dt>什麼是附加元件?</dt>
+<dd>附加元件讓您新增一般程å¼ä¸­æ²’有的功能:佈景主題在ä¸æ”¹è®ŠåŠŸèƒ½çš„情æ³ä¸‹æ›´å‹•å¤–觀;æœå°‹å·¥å…·å’Œå­—å…¸ï¼èªžè¨€å¥—件新增é¡å¤–çš„æœå°‹å¼•æ“Žå’Œèªžè¨€æ”¯æ´ï¼›æ“´å……套件替ç€è¦½å™¨å¢žåŠ çœ¾å¤šçš„功能ï¼ï¼æœ‰äº›å¢žåŠ äº†ç°¡å–®çš„工具列,也有些增加了å分廣泛的新功能。</dd>
+
+<dt>附加元件容易安è£å—Žï¼Ÿ</dt>
+<dd>沒錯ï¼å®‰è£é™„加元件éžå¸¸å®¹æ˜“。它們跟一般的程å¼ç›¸æ¯”之下éžå¸¸å°ï¼Œä¸‹è¼‰ä¹Ÿéžå¸¸å¿«é€Ÿã€‚如果你ä¸å–œæ­¡æŸæ¨£å…ƒä»¶ï¼Œè¦ç§»é™¤æˆ–åœç”¨ä¹Ÿå分容易。å¦å¤–,如果您有å¯ä»¥æ›´æ–°çš„附加元件,Firefox 會æ醒您,且åªéœ€è¦å–®æ“Šæ»‘鼠就能完æˆå‡ç´šã€‚</dd>
+
+<dt>我è¦å¦‚何管ç†é™„加元件?</dt>
+<dd>在 Firefox 中,到工具功能表中的「附加元件ã€ç®¡ç†ä½ˆæ™¯ä¸»é¡Œå’Œæ“´å……套件。如果您的擴充套件有特別的é¸é …,您å¯ä»¥åœ¨é™„加元件視窗的擴充套件部分找到é¸é …。您也å¯ä»¥åœ¨é€™è£¡åœç”¨å’Œè§£é™¤å®‰è£é™„加元件。æœå°‹å·¥å…·å¯ä»¥é€éŽæœå°‹åˆ—進行管ç†ã€‚</dd>
+
+<dt>附加元件會讓 Firefox 變慢嗎?</dt>
+<dd>大部分情æ³ä¸‹ï¼Œé™„加元件ä¸æœƒè®“ Firefox 變得慢上太多。然而,因為它們是應用程å¼ï¼Œä¹Ÿå¤šå°‘會影響到 Firefox 的效能,而幅度則隨您的系統組態而異。如果您èªç‚ºæŸå€‹é™„加元件影響 Firefox 在您機器上的é‹ä½œï¼Œè©¦è‘—åœç”¨è©²å…ƒä»¶ã€‚</dd>
+
+<dt>為何我需è¦åœç”¨é™„加元件?</dt>
+<dd>åœç”¨é™„加元件會é¿å…在您啟動 Firefox 時載入它,但ä¸æœƒç§»é™¤å…ƒä»¶æœ¬èº«å’Œä»»ä½•å…¶è¨­å®šã€‚é‡æ–°å•Ÿç”¨é™„加元件會讓元件回到您åœç”¨æ™‚的狀態。åœç”¨é™„加元件是當您想關閉但ä¸ç§»é™¤å…ƒä»¶æ™‚å¯ç”¨çš„é¸æ“‡ã€‚</dd>
+
+<dt>我è¦å¦‚何備份所有我安è£éŽçš„附加元件和佈景主題?</dt>
+<dd>您å¯ä»¥å‚™ä»½æ‚¨çš„設定檔 (Profile) 資料夾,這åŒæ™‚也會備份您的附加元件和佈景主題。MozBackup之類的第三方應用程å¼å¯ä»¥å¹«åŠ©æ‚¨é€²è¡Œå‚™ä»½ã€‚</dd>
+</dl>
+
+<h2>網站å•é¡Œ</h2>
+<dl class="faq">
+<dt>我看到數種æ供相åŒåŠŸèƒ½çš„附加元件。我è¦å¦‚何決定哪個是最好的?</dt>
+<dd>通常您å¯ä»¥é€éŽè©•åˆ†å’Œä¸‹è¼‰æ¬¡æ•¸ç•¥çŸ¥ä¸€äºŒã€‚優良的附加元件比較容易å–得較多的下載次數。然而,都下載看看å†æ±ºå®šè¦ä½¿ç”¨å“ªå€‹é™„加元件,是比較容易的方法。您å¯èƒ½åœ¨å˜—試éŽå¾Œæ±ºå®šå…©å€‹å¥—件都使用呢ï¼</dd>
+
+<dt>我看到一個很棒的套件,但它åªç›¸å®¹æ–¼ Firefox 2.x 。我å¯ä»¥åœ¨ Firefox 3.x 安è£é€™å€‹å…ƒä»¶å—Žï¼Ÿ</dt>
+<dd>通常ä¸å¯è¡Œã€‚Firefox 3.x æœ‰çœ¾å¤šçš„æ–°åŠŸèƒ½ï¼Œä¸”å¤§å¤šæ•¸çš„é™„åŠ å…ƒä»¶é–‹ç™¼è€…å·²ç¶“å°‡ä»–å€‘çš„é™„åŠ å…ƒä»¶æ›´æ–°ï¼Œä½¿å…¶æ”¯æ´ 3.x 版本。如果有åªæ”¯æ´ Firefox 2 的附加元件,試著æœå°‹è©²é™„加元件的標題。通常會有相åŒæˆ–類似標題的元件相容於 Firefox 3。</dd>
+
+<dt>我安è£äº†ä¸€å€‹æ–°çš„佈景主題,但想è¦ç”¨å›žåŽŸä¾† Firefox çš„é è¨­ä½ˆæ™¯ä¸»é¡Œã€‚我該怎麼åšï¼Ÿ</dt>
+<dd>到「工具ã€åŠŸèƒ½è¡¨ä¸‹çš„「附加元件ã€ã€‚點é¸ã€Œä½ˆæ™¯ä¸»é¡Œã€éƒ¨åˆ†ï¼Œåœ¨é€™è£¡é¸æ“‡ã€ŒDefaultã€ï¼ˆé è¨­ï¼‰ä½ˆæ™¯ä¸»é¡Œï¼Œæˆ–其他您所安è£çš„佈景主題。</dd>
+
+<dt>如果我有一個附加元件的å•é¡Œï¼Œæˆ‘應該連絡 Mozilla 嗎?</dt>
+<dd>å¤§éƒ¨åˆ†çš„é™„åŠ å…ƒä»¶ï¼Œé™¤äº†å°‘æ•¸ä¾‹å¤–ï¼Œéƒ½æ˜¯ç”±ç¤¾ç¾¤è€Œéž Mozilla 所建立。最好的方法是å‘開發者直接詢å•æ‚¨çš„å•é¡Œã€‚您å¯ä»¥åœ¨é™„加元件列表é ä¸­æŒ‰ä¸‹é–‹ç™¼è€…çš„å字,以å–得它們的連絡資訊。</dd>
+
+<dt>附加元件是如何被審核的?</dt>
+<dd>公開的附加元件由我們專屬而æ‰è¯æ´‹æº¢çš„審核團隊所審核。他們審核所有公開附加元件的原始碼,並測試附加元件,確èªå®ƒå€‘åƒèªªæ˜Žä¸­ä¸€èˆ¬æº–確地é‹ä½œã€‚</dd>
+
+<dt>為什麼我å‡ç´šåˆ° Firefox 3.5 後,æŸäº›é™„加元件就沒辦法使用了?</dt>
+<dd>我們大部分的附加元件都相容於 Firefox 3.5 ,而且相容的元件æ¯å¤©éƒ½åœ¨å¢žåŠ ã€‚如果您的附加元件在 3.0 下å¯ä»¥é‹ä½œä½† 3.5 下ä¸è¡Œï¼Œå¾ˆæœ‰å¯èƒ½ä»–們還正在努力調整中。Firefox 在他們å‡ç´šäº†ç›¸å®¹çš„附加元件後會通知您。</dd>
+
+<dt id="experimental-addons">什麼是實驗中附加元件?</dt>
+<dd>
+ <p>實驗中附加元件是尚未經éŽå…¬é–‹å¯©æ ¸ç¨‹åºçš„較新附加元件。這其中å¯èƒ½æœ‰è¨±å¤šé‚„在原型的階段。因為它們尚未被我們的審核團隊所測試,它們在å“質ã€æ•ˆèƒ½å’ŒåŠŸèƒ½ä¸Šï¼Œå¯èƒ½ä¸€å¦‚ Alphaã€Beta 或é‡ç”¢å‰ç‰ˆæœ¬èˆ¬ä¸ç©©å®šã€‚</p>
+ <p>安è£å¯¦é©—中元件時應多加留æ„,因為它們尚未被審核者測試,å¯èƒ½æœƒå‚·å®³æ‚¨é›»è…¦çš„組態。</p>
+</dd>
+
+<dt id="recognizing-experimental-addons">在站上我è¦å¦‚何知é“一個附加元件是å¦ä»åœ¨å¯¦é©—中?</dt>
+<dd>實驗中元件會標上「實驗中ã€æ¨™ç±¤ï¼Œä¸¦ä¸”在安è£æ™‚會顯示警告。</dd>
+
+<dt id="recommended-addons">什麼是推薦元件ã€ç²¾é¸å…ƒä»¶ï¼Ÿ</dt>
+<dd>AMO 團隊會推薦一些在使用性和整體體驗上皆為上乘之é¸çš„附加元件。這些推薦的元件會顯示在個別分類é ä¸­ã€‚有一些元件也會以精é¸å…ƒä»¶çš„æ–¹å¼åœ¨ AMO 的首é è¼ªè½‰ã€‚這並ä¸æ˜¯ä¸€å€‹ç„¡æ‰€ä¸åŒ…的列表,且我們會在æ¯å€‹æœˆæ›´æ–°åˆ—表,æŒçºŒæ供給使用者新鮮的附加元件清單。當我們推薦元件時會考é‡åˆ°å“質ã€ç†±é–€ç¨‹åº¦ã€ç¨ç‰¹æ€§ç­‰è¦ç´ ï¼Œä»¥åŠé€™å€‹å…ƒä»¶æ˜¯å¦å·²è¢«æŽ¨è–¦éŽã€‚</dd>
+
+</dl>
+
+<script src="https://getsatisfaction.com/mozilla/widgets/javascripts/500b6b4141/widgets.js" type="text/javascript"></script>
+<script src="https://getsatisfaction.com/mozilla/topics.widget?callback=gsfnTopicsCallback&amp;limit=5&amp;product=mozilla_mozilla_add_ons&amp;sort=last_active_at&amp;style=topics" type="text/javascript"></script>
diff --git a/site/app/locale/zh_TW/pages/nomination.thtml b/site/app/locale/zh_TW/pages/nomination.thtml
new file mode 100644
index 0000000..5aaeb27
--- /dev/null
+++ b/site/app/locale/zh_TW/pages/nomination.thtml
@@ -0,0 +1,10 @@
+<p>存放在「沙箱ã€å€çš„附加元件需è¦ç¶“éŽå¯©æ ¸è€…批准後æ‰èƒ½æ”¾åˆ°ã€Œå…¬é–‹ã€å€ä¾›æ‰€æœ‰ä½¿ç”¨è€…下載。為了儘速通éŽæ‰¹å‡†ï¼Œè«‹æ³¨æ„下列事項:</p>
+<ul>
+ <li>佈景主題一定è¦é™„上é è¦½åœ–片,其他種類的附加元件也建議你附上</li>
+ <li>新的附加元件應該在「沙箱ã€å€å­˜æ”¾ä¸€æ®µæ™‚間,累ç©ä¸€å®šçš„使用者æ„見和錯誤回報</li>
+ <li>「公開ã€å€çš„附加元件比起「沙箱ã€å€æœ‰æ›´é«˜çš„å“質è¦æ±‚,並è¦èƒ½å¢žå¼·ä½¿ç”¨è€…的網路體驗</li>
+ <li>完整的批准標準å¯åˆ°<a href="%s">附加元件政策</a>查看</li>
+</ul>
+<p>如果你的附加元件符åˆä¸Šè¿°æ¨™æº–,å¯ä»¥ç”¨ä¸‹é¢çš„表格將元件é€äº¤æ‰¹å‡†ã€‚當批准çµæžœå‡ºçˆæœƒç”¨ Email 通知你。</p>
+
+<p>將元件é€äº¤æ‰¹å‡†æ™‚,請說明測試此元件的方法åŠéŽç¨‹ï¼ˆåŒ…å«å°šæœªè§£æ±ºçš„錯誤åŠè­¦å‘Šè¨Šæ¯ï¼‰ï¼ŒåŠæ­¤å…ƒä»¶çš„主è¦ç”¨é€”。你也å¯ä»¥åˆ—出評論此元件的外部連çµã€‚</p> \ No newline at end of file
diff --git a/site/app/locale/zh_TW/pages/policy.thtml b/site/app/locale/zh_TW/pages/policy.thtml
new file mode 100644
index 0000000..f1ce002
--- /dev/null
+++ b/site/app/locale/zh_TW/pages/policy.thtml
@@ -0,0 +1,110 @@
+<h1>附加元件政策</h1>
+
+<h2>什麼是「沙箱ã€å€ï¼Ÿ</h2>
+<p>請見 %s。</p>
+
+<h2>什麼樣的元件會放在「沙箱ã€å€ï¼Ÿ</h2>
+<p>「沙箱ã€æ˜¯æ‰€æœ‰é™„加元件一開始的存放處,ä¸ä½†æœ‰å·²å…¬é–‹å…ƒä»¶çš„新版本,還有尚未公開元件的所有版本。當一個新元件或是舊元件的更新版上傳到 AMO 上時就會先放在「沙箱ã€å€ã€‚</p>
+
+<p>æŸäº›å…ƒä»¶æˆ–其特定版本經審核者審核通éŽï¼Œèªç‚ºèƒ½å¤ è®“所有人下載時就會放上「公開ã€å€ã€‚而其他未經審核的元件會一直留在「沙箱ã€ï¼Œåªæœ‰é€²éšŽä½¿ç”¨è€…主動é¸æ“‡ç€è¦½ã€Œæ²™ç®±ã€å€æ™‚æ‰æœƒé¡¯ç¤ºå‡ºä¾†ã€‚</p>
+
+<h2>如何將元件é€è‡³ã€Œå…¬é–‹ã€å€ï¼Ÿ</h2>
+
+<p>附加元件一開始åªæœƒå‡ºç¾åœ¨ã€Œæ²™ç®±ã€å€ï¼Œä¾›å·²é¸æ“‡ç€è¦½ã€Œæ²™ç®±ã€å€çš„使用者測試並留下æ„見,使用者會指出該元件是å¦æœ‰ç”¨ï¼›æœ‰ç„¡æœªç™¼ç¾çš„錯誤;å“質能å¦è®“所有使用者下載等。這些寶貴的æ„見是 AMO 團隊用來決定該元件å¯å¦å…¬é–‹ä¸‹è¼‰ï¼›éœ€è¦ç¹¼çºŒæ”¹å–„å“質或根本ä¸é©åˆæ”¾ä¸Šã€Œå…¬é–‹ã€å€ä¾›æ‰€æœ‰äººä½¿ç”¨çš„ä¾æ“šã€‚</p>
+
+<h2>如何讓我的元件æˆç‚ºã€Œå…¬é–‹ã€ç‹€æ…‹ï¼Ÿ</h2>
+清楚
+<p>如果你覺得你的元件(和你的態度ï¼ï¼‰å·²ç¶“é”到å¯ä»¥é€è‡³ã€Œå…¬é–‹ã€å€çš„標準,你å¯ä»¥å¾žã€Œé–‹ç™¼è€…工具ã€ä¸­å°‡è©²å…ƒä»¶é€äº¤æ‰¹å‡†ã€‚</p>
+
+<h2>公開附加元件的標準是什麼?</h2>
+
+<p>放上「公開ã€å€çš„附加元件會有更高的å“質è¦æ±‚,並è¦èƒ½å¢žå¼·ä½¿ç”¨è€…的網路體驗,我們會ä¾ç…§ä¸‹åˆ—標準決定元件é©ä¸é©åˆæ”¾ä¸Š AMO 網站的「公開ã€å€ï¼š</p>
+
+<h3>ä½ èªçœŸè² è²¬å—Žï¼Ÿ</h3>
+
+<p>我們希望套件作者能å°è‡ªå·±çš„套件負責,盡力解決套件å•é¡Œã€ä¿æŒè¯çµ¡ç®¡é“暢通並在 Firefox ç™¼è¡Œæ–°ç‰ˆæœ¬åŠ AMO 改變政策時迅速更新。這ä¸æ˜¯è¦ä½ å›žè¦†æ¯å€‹å•é¡Œæˆ–討論,也ä¸æ˜¯å«ä½ ä¿®å¾©æ‰€æœ‰éŒ¯èª¤ï¼Œä½†èµ·ç¢¼å°æ–¼åš´é‡å•é¡Œè¦èƒ½å¤ å³æ™‚回應並處ç†ã€‚</p>
+
+<h3>元件有清楚且正確的敘述嗎?</h3>
+
+<p>讓使用者知é“他們安è£äº†é€™å€‹å…ƒä»¶ä¹‹å¾Œæœ‰ä»€éº¼ä½œç”¨éžå¸¸é‡è¦ã€‚元件敘述應該è¦è¼‰æ˜Žè©²å¥—件的所有細節ã€å¦‚何使用該元件以åŠå®‰è£å¾Œæœƒç™¼ç”Ÿä»€éº¼äº‹ç­‰ã€‚如果內容太多,也å¯ä»¥é€£çµåˆ°å¤–部文件æ供更詳細的內容,但是敘述中一定è¦åŒ…å«åŸºæœ¬ä¸”最é‡è¦çš„資訊,讓使用者清楚知é“他們安è£äº†ä»€éº¼ã€‚</p>
+
+<p>åŒæ™‚,維護æ¯å€‹æ–°ç‰ˆæœ¬çš„版本資訊也很é‡è¦ï¼Œè£¡é¢æ‡‰è©²è¦å¯«å‡ºä½ åŠ å¼·æˆ–修改了那些地方。使用者è¦èƒ½çŸ¥é“新舊版本相比有什麼新功能,åŠæ醒使用者更新後ç¾æœ‰çš„功能會有什麼改變。(目å‰ç‚ºæ­¢ï¼Œä½¿ç”¨è€…é€éŽç€è¦½å™¨ç·šä¸Šæ›´æ–°æ™‚看ä¸åˆ°ç‰ˆæœ¬è³‡è¨Šï¼Œä½†æˆ‘們未來會修正。如果你有確實維護版本資訊的話,ä¸ç®¡æ­¤å•é¡Œä¿®å¾©èˆ‡å¦éƒ½å°ä½¿ç”¨è€…éžå¸¸æœ‰ç”¨ã€‚)</p>
+
+<h3>是å¦æ¸…楚說明關於隱ç§åŠå®‰å…¨çš„å•é¡Œï¼Ÿ</h3>
+
+<p>這其實是上個標準的一部分,但其é‡è¦æ€§è®“我們覺得應該特別æ起。很多有用的優質元件都會é‹ç”¨æŸäº›ä½¿ç”¨è€…資料,但是這些資料若é­åˆ°èª¤ç”¨å¯èƒ½æœƒå±åŠä½¿ç”¨è€…çš„éš±ç§åŠå®‰å…¨ã€‚我們歡迎這些好用的元件進入「公開ã€å€ï¼Œä½†æ˜¯ä½ å¿…須清楚註明使用者å¯èƒ½æœƒé‡åˆ°çš„風險åŠä¿è­·ä»–們自己的方法。</p>
+
+<h3>元件已經éŽå……分測試ã€ç„¡æ˜Žé¡¯æˆ–åš´é‡çš„缺陷?</h3>
+
+<p>我們會ä¾æ“šæ²™ç®±ä¸­ä½¿ç”¨è€…測試後的æ„見(有無嚴é‡å•é¡Œæˆ–å°ç€è¦½å™¨é€ æˆä¸è‰¯å½±éŸ¿ï¼‰ä¾†æ±ºå®šå…ƒä»¶èƒ½å¦è¢«å…¬é–‹ä¸‹è¼‰ã€‚如果審核者發ç¾å…ƒä»¶æœƒåš´é‡å½±éŸ¿æ•ˆèƒ½ã€ä¸æ­£å¸¸é—œé–‰ã€æŸåŠŸèƒ½ç¶“常發生錯誤或是在錯誤主控å°ä¸­æ¿«å¡žéŒ¯èª¤è¨Šæ¯æ™‚,你應該謹慎處ç†é€™äº›å•é¡Œï¼Œç›¡åŠ›ä¿®å¾©å¾Œé‡æ–°é€äº¤æ‰¹å‡†ã€‚這並ä¸æ˜¯è¦ä½ èª¿æ ¡åˆ°æœ€å®Œç¾Žæˆ–是完全零錯誤–就連 Firefox 本身也有很多地方需è¦ä¸æ–·æ”¹é€²ï¼Œåªæ˜¯è¦ä½ åœ¨èƒ½åŠ›æ‰€åŠçš„程度內盡é‡æ¸›å°‘å•é¡Œï¼Œä¸¦æ¸…楚指出還有哪些å•é¡Œæœƒå°ä½¿ç”¨è€…造æˆå›°æ“¾ã€‚</p>
+
+<p>如果你的附加元件在 AMO 沙箱機制以外就已經測試éŽï¼Œä¾‹å¦‚ä½ æœå‹™å…¬å¸å…§çš„一å°ç¾¤ä½¿ç”¨è€…或是內部的 QA 團隊,你應該在é€äº¤æ‰¹å‡†æ™‚註明,以便我們知é“該元件已經測試的程度,也讓元件能盡早上傳到網站上。</p>
+
+<h3>你和你寫的元件尊é‡ä½¿ç”¨è€…嗎?</h3>
+
+<p>你的元件ä¸æ‡‰è©²å°ä½¿ç”¨è€…åšå‡ºä¸å¿…è¦çš„騷擾ã€æ¬ºé¨™ä½¿ç”¨è€…或是隱瞞元件的活動等。使用者(甚至éžä½¿ç”¨è€…)有時候會留下無禮的言論,除了我們會在得悉後盡力刪除外,也希望你ä¸è¦æŽ¡ç”¨ç„¡ç¦®çš„行動報復。</p>
+
+<h3>元件å°å¤§éƒ¨åˆ†çš„ Firefox 使用者都有用嗎?</h3>
+
+<p>並ä¸æ˜¯ä½ çš„元件必須è¦åƒ Greasemonkey 或是 FireBug 那樣å‰å¤§æ‰èƒ½é€šéŽæ‰¹å‡†ï¼Œä½†æ˜¯å¦‚果這個元件åªå°ä½ å…¬å¸å…§éƒ¨æˆ–是一å°ç¾¤ç¤¾ç¾¤å…§çš„人æ‰æœ‰ç”¨ï¼Œå°±ä¸é©åˆè®“所有使用者下載。</p>
+
+<p>我們會ä¸æ–·æ”¹å–„網站的架構,以涵蓋那些åªé‡å°ä¸€å°ç¾¤æ½›åœ¨ä½¿ç”¨è€…設計的附加元件。正確的分類åŠç¶­è­·ä½ æ‰€ä¸Šå‚³é™„加元件的詳細資訊能幫助我們了解該怎麼åšæ‰èƒ½è®“最多的使用者從這些元件中ç²ç›Šã€‚</p>
+
+<p>如果你的元件åªæ˜¯æ供連到你網站上的書籤或其他連çµï¼Œå°±ä¸é©åˆæ”¾åœ¨ã€Œå…¬é–‹ã€å€ä¾›å¤§å®¶ä¸‹è¼‰ã€‚é›–ç„¶æˆ‘å€‘ç†±æ„›åƒ Mozilla 專案這類的網路應用åŠæ–°çš„網路æœå‹™ï¼Œä½†æ˜¯ Firefox 附加元件應該è¦èƒ½æ”¹å–„使用者的ç€è¦½é«”驗,而éžé€éŽ AMO å¹³å°ä¾†æŽ¨å»£æ–°ç¶²ç«™æˆ–æœå‹™ã€‚如果你的元件敘述都是推銷æŸå€‹ç¶²ç«™ï¼Œè€Œä¸æ˜¯å¢žé€²ä½¿ç”¨è€…çš„ç€è¦½é«”驗時,很å¯èƒ½ç„¡æ³•é€šéŽæ‰¹å‡†ã€‚</p>
+
+<h3>元件是å¦æœ‰å•†æ¨™æˆ–版權上的å•é¡Œï¼Ÿ</h3>
+
+<p>雖然你å¯èƒ½ä¸æ˜¯æ•…æ„è¦ä¾µå®³å•†æ¨™æ“有者或版權所有者的權利,但是我們ä¸èƒ½å°‡ä¾µçŠ¯å•†æ¨™æ¬ŠåŠè‘—作權的附加元件放上網站。如果你未å—許å¯ä½¿ç”¨äº†å—商標ä¿è­·çš„å稱或圖åƒï¼Œè«‹å‹¿ä¸Šå‚³è©²å…ƒä»¶åˆ° AMO 上。如果你的元件å«æœ‰å…¶ä»–人å—版權ä¿è­·çš„程å¼ç¢¼ï¼Œä¸”未經所有者授權使用於你的元件時,請勿上傳該元件到 AMO 上。(如果商標或版權æ“有者主張其權利時,我們很å¯èƒ½å¿…é ˆè¦æ‰¾å¾‹å¸«å¯©æŸ¥å…¶æ˜¯å¦ä¾µæ¬Šï¼Œè‹¥ç¢ºå®šä¾µæ¬Šæ‰æœƒç§»é™¤è©²å…ƒä»¶ã€‚就計畫資æºï¼ˆæ‰€èŠ±è²»çš„時間ã€é‡‘錢)來說éžå¸¸æ˜‚貴,所以我們希望你尊é‡ç‰ˆæ¬Šï¼Œåˆ¥å¢žåŠ æˆ‘們ä¸å¿…è¦çš„困難。)</p>
+
+<p>如果你ä¸ç¢ºå®šä½ é™„加元件的å稱或其中使用的程å¼ç¢¼æ˜¯å¦æœ‰å•é¡Œè€Œå°Žè‡´ç„¡æ³•é€šéŽæ‰¹å‡†ï¼Œå¯ä»¥å¯«ä¿¡çµ¦ amo-editors@mozilla.org ç²å¾—å”助。<b>é‡è¦è²æ˜Ž</b>:請注æ„此團隊並ä¸èƒ½çµ¦ä½ æ³•å¾‹ä¸Šçš„å”助,而且å³ä½¿æˆ‘們覺得沒有å•é¡Œï¼Œç•¶æœ‰ç‰ˆæ¬Šæ“有者åŠæ³•å¾‹é¡§å•å‘我們投訴時,我們會é‡æ–°å¯©æŸ¥ä½ çš„元件是å¦ä¾µæ¬Šã€‚</p>
+
+<p>在利用其他元件的程å¼ç¢¼æ–¹é¢ï¼Œå¦‚果該作者沒有清楚指明你å¯ä»¥ä½¿ç”¨ä»–的程å¼ç¢¼æ–¼ä½ çš„作å“時–例如將元件採用開放原始碼授權,你應該å‡è¨­ä½ ç„¡æ¬Šä½¿ç”¨ä»–的程å¼ç¢¼ã€‚ä½ å¯ä»¥è¯çµ¡è©²å…ƒä»¶ä½œè€…請求授權,但是我們ä¸èƒ½å› ç‚ºè©²å…ƒä»¶æ”¾åœ¨ AMO 上,或是作者ä¸ç†ä½ å°±æ“…自給你任何授權。(å†å¼·èª¿ä¸€æ¬¡ï¼Œæˆ‘們ä¸èƒ½æ供你任何法律å”助,åªèƒ½å»ºè­°ä½ å¦‚何讓你的元件符åˆæˆ‘們網站的政策。)</p>
+
+<p>上é¢æ‰€è¿°åŒæ¨£é©ç”¨æ–¼ Mozilla 基金會所有的商標,包å«ã€ŒMozillaã€ã€ã€ŒFirefoxã€åŠã€ŒThunderbirdã€å­—樣。Mozilla 政策中å°æ–¼å•†æ¨™çš„ä¿è­·æ˜¯ç‚ºäº†é¿å…使用者混淆åŠé˜²æ­¢å•†æ¨™ç‚ºç¼ºä¹ä¿è­·è€Œè¢«ç›œç”¨ï¼›è«‹å°Šé‡é€™é¡žä¿è­·çš„å¿…è¦æ€§ï¼Œä¸¦å¹«åŠ©æˆ‘們ä¿å­˜é€™äº› Mozilla 基金會最é‡è¦çš„資產。</p>
+
+<h2>當我é€äº¤æ‰¹å‡†å¾Œæœƒç™¼ç”Ÿä»€éº¼äº‹ï¼Ÿ</h2>
+
+<p>一旦你將元件é€äº¤æ‰¹å‡†ï¼ŒAMO 審核者們會ä¾ç…§ä¸Šè¿°æ¨™æº–進行審核。如果我們èªç‚ºè©²å…ƒä»¶å·²ç¶“é©åˆå…¬é–‹å±•ç¤ºï¼Œä¾¿æœƒåœ¨é€šéŽæ‰¹å‡†å¾Œé€ä¸Šã€Œå…¬é–‹ã€å€ï¼Œä¸¦ç”¨é›»å­éƒµä»¶é€šçŸ¥ä½ ã€‚</p>
+
+<p>如果我們覺得該元件ç¾éšŽæ®µé‚„ä¸é©åˆæ”¾ä¸Šã€Œå…¬é–‹ã€å€ï¼Œä½ æœƒæ”¶åˆ°é›»å­éƒµä»¶é€šçŸ¥èªªæ˜ŽåŽŸå› ï¼Œä¸”將你的批准請求從佇列中移除。如果你已經處ç†å¥½é€šçŸ¥éƒµä»¶ä¸Šæ到的å•é¡Œï¼Œå¯ä»¥éš¨æ™‚å†æ¬¡é€äº¤æ‰¹å‡†ã€‚但如果元件沒有改善而你一直é‡è¤‡é€äº¤æ‰¹å‡†ï¼Œæˆ‘們並ä¸æœƒè™•ç†ï¼Œæ•…請自é‡ï¼Œä¸ç„¶ä¸ä½†ç„¡æ³•èªªæœæˆ‘們,甚至會觸怒我們。</p>
+
+<h2>我å¯ä»¥å°‡åˆ¥äººçš„元件é€äº¤æ‰¹å‡†å—Žï¼Ÿ</h2>
+
+<p>ç›®å‰æˆ‘們åªè®“元件作者自己將其作å“é€äº¤æ‰¹å‡†ã€‚如此æ‰èƒ½ç¢ºä¿å¥—件作者å°å…¶ä½œå“在公開後的大é‡æ›å…‰æœ‰å¿ƒç†æº–備,也能ä¿è­‰å¥—件å“質已經é”到公開的標準。如果你覺得有附加元件å“質極佳;作者能了解 AMO 政策的æ„義åŠå…¶ç²¾ç¥žï¼›å¥—ä»¶å° Firefoxã€å…¶ä½¿ç”¨è€…ã€åŠæ•´å€‹ç¶²è·¯æœ‰æ‰€åŠ©ç›Šã€ä¸¦èƒ½è®“å…¨çƒæä¾›æˆåƒä¸Šè¬çš„網路使用者å–得,那麼請鼓勵作者主動將其作å“é€äº¤æ‰¹å‡†ã€‚</p>
+
+<h2>我的元件已經在等待批准佇列中排了好久都沒有動éœï¼Œæ˜¯ä½ å€‘討厭我嗎?</h2>
+
+<p>怎麼會討厭呢?æ¯å€‹é™„加元件作者都是我們的最愛,而且我們也盡力讓作者們愉快且樂於創作,如此一來全çƒçš„使用者都能從中ç²ç›Šã€‚但是 AMO「公開ã€å€çš„價值就在於我們很é‡è¦–該å€çš„元件å“質,所以無法為了加快審核速度而è‰çŽ‡äº†äº‹ã€‚我們了解那種等待批准å»é²é²æ²’有çµæžœçš„挫折感,所以我們會盡å¯èƒ½è®“這段等待時間縮到最短。若是有越多人在「沙箱ã€å€ä¸­å›žå ±æ¸…楚且有用的æ„見,則該套件會越容易通éŽæ‰¹å‡†ï¼Œæ‰€ä»¥å¤šå¤šæ¸¬è©¦ä¸¦å›žå ±å•é¡Œå°±æ˜¯å¹«åŠ©å…ƒä»¶é€šéŽæ‰¹å‡†çš„最佳方法ï¼</p>
+
+<h2>我發ç¾æˆ‘的元件中有個嚴é‡éŒ¯èª¤ï¼Œæˆ‘想儘快修復該怎麼åšï¼Ÿ</h2>
+
+<p>若附加元件中å«æœ‰åš´é‡éŒ¯èª¤ï¼ˆå®‰å…¨æ€§ã€ç©©å®šæ€§ã€ä¸»è¦åŠŸèƒ½æœ‰å•é¡Œï¼‰ï¼Œè€Œä½ æƒ³è¦å„˜å¿«ç™¼ä½ˆæ›´æ–°æª”時,你應該在上傳更新版時於「給審核者的說明ã€æ¬„ä½ä¸­ç‰¹åˆ¥èªªæ˜Žï¼ŒåŒæ™‚該更新版的「版本資訊ã€ä¸­ä¹Ÿæ‡‰è©²æ¸…楚敘述。最好å¯ä»¥æ‰¾ä¸€äº›è©²å…ƒä»¶çš„舊使用者先於「沙箱ã€å€æ¸¬è©¦ï¼Œä¸¦è«‹ä»–們回報çµæžœã€‚在 irc.mozilla.org çš„ #addons èŠå¤©å®¤ä¸­ç•™ä¸‹è¨Šæ¯ä¹Ÿæ˜¯è®“大家注æ„到的好方法,但請è€å¿ƒç­‰å¾…回應並ä¿æŒç¦®è²Œã€‚</p>
+
+<p>ä¸è¦å‘放羊的å°å­©ä¸€æ¨£å¤§å–Šã€Œç‹¼ä¾†äº†ã€ã€‚雖然高優先度的更新版本我們會優先處ç†ï¼Œä½†é€™æœƒæŽ’擠到其他等待批准的套件或更新版,也會減少我們的ç¡çœ åŠå’Œå®¶äººæœ‹å‹ç›¸è™•çš„時間。為了é¿å…有人利用此機制「æ’隊ã€ï¼Œæˆ‘們會以嚴格的態度決定是å¦æŽ¡ç”¨å¿«é€Ÿå¯©æ ¸æ©Ÿåˆ¶ã€‚若你ä¸ç¢ºå®šæ˜¯å¦è¦åˆ©ç”¨æ­¤æ©Ÿåˆ¶å¿«é€Ÿé€šéŽå¯©æ ¸ï¼Œè«‹ä¸Š irc.mozilla.org #addons 尋求å”助。
+
+<h2>我覺得我的元件審核ä¸å…¬å¹³ï¼Œæˆ‘該怎麼åšï¼Ÿ</h2>
+
+<p>若你èªç‚ºä½ çš„元件被ä¸æ­£ç¢ºå¯©æ ¸ï¼Œä¸”審核çµæžœæ˜Žé¡¯æœ‰èª¤ï¼Œä½ å¯ä»¥å¯„信給 amo-editors@mozilla.org 並詳細說明ç†ç”±ã€‚請注æ„禮貌並於信中清楚說明,並æ出å¯ä»¥é¿å…附加元件被誤判的方法。</p>
+
+<p>(若你已經將我們於é€äº¤æ‰¹å‡†ä¿¡ä¸­åˆ—出的所有å•é¡Œã€Œå…¨éƒ¨ã€ä¿®æ­£çš„話,請ä¸è¦æŽ¡å–此方å¼æ出異議,而應該利用「開發者工具ã€é‡æ–°é€äº¤æ‰¹å‡†ã€‚)</p>
+
+<h2>我的元件之å‰æ›¾è¢«æ”¾åˆ°ã€Œå…¬é–‹ã€å€ï¼Œä½†ç¾åœ¨åªæœƒåœ¨ã€Œæ²™ç®±ã€å€å‡ºç¾ï¼Œåˆ°åº•æ˜¯æ€Žéº¼å›žäº‹ï¼Ÿ</h2>
+
+<p>若「公開ã€å€çš„附加元件ä¸å†ç¬¦åˆæ¨™æº–時,我們會將其移回「沙箱ã€å€ã€‚除éžæ˜¯é•æ³•çš„情æ³ï¼Œæˆ‘們會在移回「沙箱ã€å€çš„åŒæ™‚寄信通知你原因。</p>
+
+<p>å¦ä¸€å€‹å¯èƒ½æ˜¯ç¶²ç«™å‡ºç¾äº†å•é¡Œï¼Œè‹¥æ˜¯é€™ç¨®æƒ…æ³è«‹åˆ©ç”¨ Bugzilla 回報錯誤:Product è«‹é¸ã€Œaddons.mozilla.orgã€ï¼ŒComponent é¸ã€ŒPublic Pagesã€ï¼Œä¸¦å¯«ä¸‹ç™¼ç”Ÿæ­¤å•é¡Œçš„詳細éŽç¨‹ã€‚</p>
+
+<h2>我的附加元件在「公開ã€å€å¾ˆå—使用者歡迎,我è¦æ€Žéº¼å°‡å®ƒåŠ åˆ°æŽ¨è–¦æ¸…單中?</h2>
+
+<p>若你覺得你的作å“創æ„å足ã€åŠŸèƒ½å¼·å¤§ï¼Œé™¤äº†ç¬¦åˆ Mozilla 一貫強調的延展性åŠè‡ªè¨‚性外,還能æ供使用者更優質的ç€è¦½é«”驗的話,就有機會加進我們的推薦清單中。åªè¦å¯„信到 amo-editors@mozilla.org,並載明此元件優秀之處å³å¯ã€‚</p>
+
+<p>信中<b>至少</b>è¦åŒ…å«ä¸‹åˆ—資訊:</p>
+<ul>
+<li>此元件如何增進使用者的ç€è¦½é«”驗?</li>
+<li>此元件é©åˆå¤§å¤šæ•¸çš„ Firefox 使用者嗎?</li>
+<li>æ­¤å…ƒä»¶å“ªä¸€é»žç¬¦åˆ Mozilla 計畫中的核心價值,特別是在讓使用者有é¸æ“‡çš„機會ã€ä¿è­·å…¶éš±ç§æ¬ŠåŠå®‰å…¨æ€§ã€ä½¿ç¶²éš›ç¶²è·¯æ›´èƒ½æ–¹ä¾¿äººå€‘å­˜å–ã€åŠç¬¦åˆé–‹æ”¾æ¨™æº–åŠè³‡è¨Šç­‰ç›®æ¨™ã€‚</li>
+<li>和其他類似功能的元件相比有何ä¸åŒï¼ˆåˆ—出互相比較的優缺點)</li>
+<li>å„種ä¸åŒé ˜åŸŸä½¿ç”¨è€…(一般使用者ã€å¯©æ ¸è€…ã€éƒ¨è½å®¢ã€å¤ªç©ºäººæˆ–是你家寵物等等)的使用心得,最好列出正å兩種æ„見</li>
+</ul>
+
+<p>若你能æ供的資訊越完整,你的申請就越有機會被接å—,但並ä¸æ˜¯å¯«çš„好就一定會被收錄進推薦清單中,還是è¦ä»¥å…ƒä»¶æœ¬èº«è€Œå®šã€‚總而言之,你申請的元件最後加入與å¦é‚„是由 Mozilla 決定,但是使用者的ç€è¦½é«”é©—åŠéš±ç§ä¿è­·çµ•å°æ˜¯æˆ‘們優先考é‡çš„é‡é»žã€‚</p>
diff --git a/site/app/locale/zh_TW/pages/sandbox.thtml b/site/app/locale/zh_TW/pages/sandbox.thtml
new file mode 100644
index 0000000..1c4c2c9
--- /dev/null
+++ b/site/app/locale/zh_TW/pages/sandbox.thtml
@@ -0,0 +1,13 @@
+<h1>沙箱審核系統</h1>
+<h2>什麼是「沙箱ã€å€ï¼Ÿ</h2>
+<p>「沙箱ã€å€æ˜¯ä¾›é€²éšŽä½¿ç”¨è€…在附加元件審核å‰æ¸¬è©¦ä¸¦å›žå ±æ„見的特別å€åŸŸã€‚è¦é€²å…¥ã€Œæ²™ç®±ã€å€ï¼Œä½ å¿…須在你自己的「帳號設定ã€é ä¸­å‹¾é¸å•Ÿç”¨é¡¯ç¤ºã€Œæ²™ç®±ã€å€æ‰çœ‹çš„到。安è£ã€Œæ²™ç®±ã€å€ä¸­çš„元件時需特別注æ„,因為「沙箱ã€è£¡çš„元件尚未經éŽå¯©æ ¸è€…測試,也許有å¯èƒ½å‚·å®³é›»è…¦ã€‚</p>
+
+<h2>我該如何將附加元件é€åˆ°ã€Œå…¬é–‹ã€å€ï¼Ÿ</h2>
+<!-- To localize the flowchart image, see http://wiki.mozilla.org/Update:Remora_Sandbox_Flowchart -->
+<div style="text-align: center;">%s</div>
+<ol>
+ <li><b>用「開發者工具ã€ä¸Šå‚³é™„加元件。</b> 你傳上來的æ±è¥¿æœƒç«‹å³é¡¯ç¤ºåœ¨ Mozilla 附加元件的「沙箱ã€å€ï¼Œè¼ƒè€ç·´çš„使用者會在那邊測試你的附加元件並æä¾›æ„見。你必須在你自己的「帳號設定ã€é ä¸­å‹¾é¸å•Ÿç”¨é¡¯ç¤ºã€Œæ²™ç®±ã€å€æ‰çœ‹çš„到。</li>
+ <li><b>將元件é€äº¤æ‰¹å‡†ã€‚</b> 「開發者工具ã€ä¸­æœ‰å€‹é€£çµå¯ä»¥å°‡ä½ çš„元件é€äº¤æ‰¹å‡†ã€‚é€äº¤æ‰¹å‡†å¾Œï¼Œä½ çš„元件就會出ç¾åœ¨å¯©æ ¸è€…的「待批准元件ã€æ¸…單中。</li>
+ <li><b>審核者審核你的附加元件。</b> Mozilla 附加元件網站的審核者此時將安è£ä½ çš„附加元件,並測試一切是å¦æ­£å¸¸ï¼›åŒæ™‚,審核者也會查閱此元件在「沙箱ã€è£¡çš„回報紀錄。</li>
+ <li><b>é€è‡³ã€Œå…¬é–‹ã€å€æˆ–回到「沙箱ã€ã€‚</b> 審核者隨後會決定公開你的元件或é€å›žã€Œæ²™ç®±ã€å€ã€‚若元件最後é€å›žã€Œæ²™ç®±ã€å€ï¼Œå‰‡ä½ å¯ä»¥åœ¨è§£æ±ºå¯©æ ¸è€…所æ出的å•é¡Œå¾Œå†æ¬¡é€äº¤æ‰¹å‡†ã€‚若元件é€è‡³ã€Œå…¬é–‹ã€å€ï¼Œè€Œä½ åˆä¸Šå‚³äº†æ­¤å¥—件的更新版本,則更新版會先出ç¾åœ¨ã€Œæ²™ç®±ã€å€ä¸­ï¼Œç­‰å¾…審核者審核並é€è‡³ã€Œå…¬é–‹ã€å€ã€‚一旦你的附加元件被é€ä¸Šã€Œå…¬é–‹ã€å€ï¼Œå¾€å¾Œæ­¤å…ƒä»¶çš„更新版就會直接列入審核者的「待審核更新ã€æ¸…單中,無需å†æ¬¡é€äº¤æ‰¹å‡†ã€‚</li>
+</ol>
diff --git a/site/app/locale/zh_TW/pages/statistics_help.thtml b/site/app/locale/zh_TW/pages/statistics_help.thtml
new file mode 100644
index 0000000..8bd50ce
--- /dev/null
+++ b/site/app/locale/zh_TW/pages/statistics_help.thtml
@@ -0,0 +1,8 @@
+<h3>說明</h3>
+<p>統計資訊顯示æ¿èƒ½é¡¯ç¤ºé™„加元件的下載次數åŠæ›´æ–°è«‹æ±‚。</p>
+
+<h4>下載</h4>
+<p>附加元件的下載次數æ¯æ—¥æ›´æ–°ï¼Œä¸”åªè¨ˆç®—åˆæ¬¡ä¸‹è¼‰çš„次數,更新版ä¸ç´å…¥çµ±è¨ˆã€‚</p>
+
+<h4>更新請求</h4>
+<p>安è£åœ¨ä½¿ç”¨è€…電腦上的附加元件æ¯å¤©éƒ½æœƒæª¢æŸ¥æœ‰ç„¡æ›´æ–°ï¼Œé€™äº›æ›´æ–°è«‹æ±‚的次數總計å³æ‰€è¬‚的「æ¯æ—¥æœ‰æ•ˆä½¿ç”¨è€…ã€ã€‚但是「æ¯æ—¥æœ‰æ•ˆä½¿ç”¨è€…ã€(ADU) 會因元件版本ã€ä½œæ¥­ç³»çµ±ã€å…ƒä»¶ç‹€æ…‹åŠç¨‹å¼çš„ä¸åŒè€Œä¸æº–確。此資訊目å‰æ¯é€±ä¸‰è¨˜éŒ„一次。</p>
diff --git a/site/app/locale/zh_TW/pages/submission_help.thtml b/site/app/locale/zh_TW/pages/submission_help.thtml
new file mode 100644
index 0000000..d97d371
--- /dev/null
+++ b/site/app/locale/zh_TW/pages/submission_help.thtml
@@ -0,0 +1,35 @@
+<h1>上傳說明</h1>
+å¿…è¦æ¬„ä½æœƒä»¥<b>ç²—é«”</b>表示,é¸å¡«æ¬„ä½å‰‡æœƒä»¥<i>斜體</i>表示。
+<h2 id="step1">步驟 1:上傳</h2>
+<ul class="submissionHelp">
+ <li><span class="required">附加元件種類</span> - 此欄ä½é è¨­æœƒéš¨ä½ ä¸Šå‚³çš„檔案ä¸åŒè€Œè‡ªå‹•åµæ¸¬ï¼Œä½ ä¸æ‡‰è©²æ›´æ”¹æ­¤æ¬„ä½ã€‚</li>
+ <li><span class="required">附加元件檔案</span> - 附加元件的包è£æª”ï¼Œå¿…é ˆåŒ…å« install.rdf 檔案æ‰ç®—是完整的包è£æª”。若此檔案åªèƒ½åœ¨ç‰¹å®šå¹³å°ä¸Šé‹ä½œï¼Œé¸æ“‡å¯é‹ä½œçš„å¹³å°å¾Œå°±å¯ä»¥ä¸€æ¬¡ä¸Šå‚³å¤šå€‹æª”案。</li>
+ <li><span class="optional">圖示檔案</span> - 圖示檔會出ç¾åœ¨é™„加元件å稱æ—邊,以åŠé¡¯ç¤ºæ–¼é™„加元件的安è£è¦–窗中。上傳的檔案會維æŒåŽŸæ¯”例,自動縮放為 32x32 åƒç´ ã€‚</li>
+ <li><span class="required">é è¨­èªžè¨€</span> - 該元件的é è¨­èªžè¨€åŠå…¶ä¸»è¦èªžè¨€ã€‚若使用者所é¸çš„語言此套件ä¸æ”¯æ´æ™‚,則會以é è¨­èªžè¨€é¡¯ç¤ºã€‚</li>
+ <li><span class="optional">往後ä¸é¡¯ç¤ºå…ƒä»¶çš„詳細資訊</span> - 若你上傳的是元件的更新版則會出ç¾æ­¤é¸é …,勾é¸æ­¤é¸é …就會直接跳到步驟 3,åªè¦è¼¸å…¥ä¾ç‰ˆæœ¬ä¸åŒè€Œç•°çš„資訊å³å¯ã€‚</li>
+</ul>
+
+<h2 id="step2">步驟 2:元件詳細資訊</h2>
+<ul class="submissionHelp">
+ <li><span class="required">å稱</span> - é è¨­èªžè¨€ä¸‹çš„附加元件å稱。</li>
+ <li><span class="required">作者</span> - 列出全部有權修改此元件的使用者,這會出ç¾åœ¨é¡¯ç¤ºé é¢ä¸­çš„作者欄ä½ã€‚</li>
+ <li><span class="required">分類</span> - é¸æ“‡æ­¤å…ƒä»¶é©åˆçš„分類。</li>
+ <li><span class="optional">首é </span> - é è¨­èªžè¨€ä¸‹çš„元件網站。</li>
+ <li><span class="required">摘è¦</span> - é è¨­èªžè¨€ä¸‹æ­¤å¥—件的簡短摘è¦ã€‚此欄ä½æœ€é•· 250 個字元,會出ç¾åœ¨å…ƒä»¶çš„顯示é é¢åŠæœå°‹â•±ç€è¦½çš„çµæžœä¸­ã€‚</li>
+ <li><span class="required">敘述</span> - é è¨­èªžè¨€ä¸‹çš„元件敘述。此敘述會出ç¾åœ¨å…ƒä»¶é¡¯ç¤ºé é¢çš„摘è¦æ¬„ä½ä¸‹é¢ã€‚</li>
+ <li><span class="optional">授權åˆç´„</span> - é è¨­èªžè¨€ä¸‹çš„「終端使用者授權åˆç´„ã€(EULA),使用者須åŒæ„æ­¤åˆç´„æ–¹å¯ä¸‹è¼‰å…ƒä»¶ã€‚</li>
+ <li><span class="optional">éš±ç§æ”¿ç­–</span> - é è¨­èªžè¨€ä¸‹é™„加元件的隱ç§æ”¿ç­–。隱ç§æ”¿ç­–需載明此元件所得到的使用者個人資訊會用於何處,使用者å¯å¾žå…ƒä»¶çš„顯示é é¢ä¸­å®‰è£æŒ‰éˆ•ä¸‹æ–¹çš„連çµé–±è®€ã€‚若想得知隱ç§æ”¿ç­–中需包å«ä½•ç¨®è³‡è¨ŠåŠä½ çš„元件應載明何種內容,請見<a href="%s">附加元件政策</a>。</li>
+ <li><span class="optional">使用者å¯å¦ç·šä¸Šæª¢è¦–原始碼</span> - 勾é¸æ­¤æ–¹å¡Šå¯è®“使用者於網站上ç€è¦½é™„加元件的原始碼。</li>
+ <li><span class="optional">發行å‰ç‰ˆæœ¬ (Pre-release)</span> - 勾é¸æ­¤æ–¹å¡Šè¡¨ç¤ºæ­¤å…ƒä»¶ç‚ºç™¼è¡Œå‰ (Pre-release) 或測試 (beta) 版本。發行å‰ç‰ˆæœ¬å…ƒä»¶åªèƒ½æ”¾åœ¨ã€Œæ²™ç®±ã€å€ä¸­ï¼Œé™¤éžæ­¤å…ƒä»¶ä¸å†è¢«æ¨™ç‚ºç™¼è¡Œå‰ç‰ˆæœ¬ï¼Œå¦å‰‡ç„¡æ³•é€äº¤æ‰¹å‡†è‡³å…¬é–‹å€ã€‚</li>
+ <li><span class="optional">專為特定網站設計的元件</span> - 勾é¸æ­¤æ–¹å¡Šè¡¨ç¤ºæ­¤å…ƒä»¶æ˜¯å°ˆç‚ºå–®ä¸€ç¶²ç«™è¨­è¨ˆï¼Œæ¯”如此元件是專門用來改變網站外觀或顯示該網站內容等。本欄ä½ä»¥å¾Œèƒ½å¹«åŠ©å¯©æ ¸è€…éŽæ¿¾å„種元件。</li>
+ <li><span class="optional">需è¦å¤–部軟體支æ´</span> - 勾é¸æ­¤æ–¹å¡Šè¡¨ç¤ºæ­¤å…ƒä»¶éœ€è¦å¤–部軟體支æ´æ‰èƒ½æ­£å¸¸é‹ä½œï¼Œæœ¬æ¬„ä½ä»¥å¾Œèƒ½å¹«åŠ©å¯©æ ¸è€…éŽæ¿¾å„種元件。</li>
+</ul>
+
+<h2 id="step3">步驟 3:版本詳細資訊</h2>
+<ul class="submissionHelp">
+ <li><span class="required optional">版本資訊</span> - 此版本新增或修改之處的摘è¦åˆ—表,新上傳的元件å¯ä»¥ä¸å¡«æ­¤æ¬„ä½ï¼Œä½†æ›´æ–°ç‰ˆæœ¬å‰‡ä¸€å®šè¦å¡«ã€‚</li>
+ <li><span class="optional">給審核者的說明</span> - 此欄ä½å¯èˆ‡å¯©æ ¸è€…æºé€šï¼Œä½ å¯ä»¥åœ¨æ­¤å¯«ä¸Šè¦æ供給審核者的資訊。若元件需è¦å¸³è™Ÿæ‰èƒ½æ¸¬è©¦ï¼Œä½ å¯ä»¥åœ¨æ­¤æ供測試帳號ã€å¯†ç¢¼æˆ–特別說明。</li>
+</ul>
+
+<h2 id="step4">步驟 4:在地化</h2>
+此欄ä½æœƒåˆ—出所有å¯åœ¨åœ°åŒ–的欄ä½åŠæ”¯æ´çš„語言,åªè¦é»žé¸èªžè¨€å°±èƒ½è¼¸å…¥ç¿»è­¯å…§å®¹ã€‚
diff --git a/site/app/models/addon.php b/site/app/models/addon.php
new file mode 100644
index 0000000..6c09124
--- /dev/null
+++ b/site/app/models/addon.php
@@ -0,0 +1,883 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Andrei Hajdukewycz <sancus@off.net> (Original Author)
+ * Justin Scott <fligtar@gmail.com>
+ * Mike Morgan <morgamic@mozilla.com>
+ * Frederic Wenzel <fwenzel@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+class Addon extends AppModel
+{
+ var $name = 'Addon';
+ var $hasAndBelongsToMany = array('User' =>
+ array('className' => 'User',
+ 'joinTable' => 'addons_users',
+ 'foreignKey' => 'addon_id',
+ 'associationForeignKey'=> 'user_id',
+ 'conditions' => 'addons_users.listed=1',
+ 'order' => 'addons_users.position'
+ ),
+ 'Tag' =>
+ array('className' => 'Tag',
+ 'joinTable' => 'addons_tags',
+ 'foreignKey' => 'addon_id',
+ 'associationForeignKey'=> 'tag_id'
+ ),
+ 'Collection' =>
+ array('classname' => 'Collection',
+ 'joinTable' => 'addons_collections',
+ 'foreignKey' => 'addon_id',
+ 'associationForeignKey' => 'collection_id')
+ );
+ var $belongsTo = array('Addontype');
+ var $hasMany = array('Version' =>
+ array('className' => 'Version',
+ 'conditions' => '',
+ 'order' => 'Version.created DESC',
+ 'limit' => '',
+ 'foreignKey' => 'addon_id',
+ 'dependent' => true,
+ 'exclusive' => false,
+ 'finderSql' => ''
+ ),
+ // see the addon_tag model for details
+ 'AddonTag' =>
+ array('classname' => 'AddonTag',
+ 'conditions' => '',
+ 'order' => '',
+ 'limit' => '',
+ 'foreignKey' => 'addon_id',
+ 'dependent' => true,
+ 'exclusive' => false,
+ 'finderSql' => ''
+ ),
+ 'Feature' =>
+ array('classname' => 'Feature',
+ 'conditions' => '',
+ 'order' => '',
+ 'limit' => '',
+ 'foreignKey' => 'addon_id',
+ 'dependent' => true,
+ 'exclusive' => false,
+ 'finderSql' => ''
+ ),
+ 'Favorite' =>
+ array('classname' => 'Favorite',
+ 'conditions' => '',
+ 'order' => '',
+ 'limit' => '',
+ 'foreignKey' => 'addon_id',
+ 'dependent' => true,
+ 'exclusive' => false,
+ 'finderSql' => ''
+ )
+ );
+
+ var $hasMany_full = array(
+ 'Preview' =>
+ array('className' => 'Preview',
+ 'conditions' => '',
+ 'order' => 'Preview.highlight DESC',
+ 'limit' => '',
+ 'foreignKey' => 'addon_id',
+ 'dependent' => true,
+ 'exclusive' => false,
+ 'finderSql' => ''
+ )
+ );
+
+
+ var $translated_fields = array(
+ 'description',
+ 'developercomments',
+ 'eula',
+ 'supportemail',
+ 'supporturl',
+ 'homepage',
+ 'name',
+ 'privacypolicy',
+ 'summary'
+ );
+
+ var $validate = array(
+ 'guid' => VALID_NOT_EMPTY,
+ 'name' => VALID_NOT_EMPTY,
+ 'addontype_id' => VALID_NUMBER,
+ 'defaultlocale' => VALID_NOT_EMPTY,
+ 'description' => VALID_NOT_EMPTY,
+ 'summary' => VALID_NOT_EMPTY,
+ 'supportemail' => VALID_EMAIL_OPT,
+ 'supporturl' => VALID_URL_OPT,
+ 'homepage' => VALID_URL_OPT
+ );
+
+ var $default_fields = array('id', 'guid', 'name', 'defaultlocale', 'addontype_id', 'status',
+ 'higheststatus', 'icontype', 'supportemail', 'supporturl', 'homepage', 'description', 'summary',
+ 'averagerating', 'weeklydownloads', 'totaldownloads', 'totalreviews',
+ 'developercomments', 'inactive', 'trusted', 'viewsource', 'publicstats',
+ 'prerelease', 'adminreview', 'sitespecific', 'externalsoftware', 'binary',
+ 'eula', 'privacypolicy', 'nominationmessage', 'target_locale', 'locale_disambiguation',
+ 'created', 'modified');
+
+ /**
+ * Get a single add-on, along with the desired associations
+ * (uses the object-invalidation framework)
+ * @param int $id add-on id to be fetched
+ * @param array $associations list of additional items to return
+ *
+ * By convention, the associations array should be all lower case and sorted
+ * alphabetically, to promote cache hits across pages.
+ */
+ function getAddon($id, $associations = array()) {
+ global $valid_status;
+
+ // if this object is cached, grab it from memcache
+ $identifier = array("addon:$id", $associations);
+ if (QUERY_CACHE && $cached = $this->Cache->readCacheObject($identifier)) {
+ if (DEBUG >= 2) debug("addon $id was cached");
+ return $cached;
+ }
+
+ // deactivate query caching
+ $caching_was = $this->caching;
+ $this->caching = false;
+
+ // start with very basic fields and association list, then add more as desired
+ $this->unbindFully();
+ $fields = array('id', 'name', 'status');
+
+ foreach ($associations as $association) {
+ switch ($association) {
+ case 'all_tags':
+ // all categories this add-on is associated with
+ $this->bindModel(array('hasMany' =>
+ array('AddonTag' =>
+ array('className' => 'AddonTag',
+ 'foreignKey' => 'addon_id'
+ ))));
+ break;
+
+ case 'authors':
+ // addon authors
+ $this->bindModel(array('hasAndBelongsToMany' =>
+ array('User' =>
+ array('className' => 'User',
+ 'joinTable' => 'addons_users',
+ 'foreignKey' => 'addon_id',
+ 'associationForeignKey'=> 'user_id',
+ 'conditions' => 'addons_users.listed=1',
+ 'order' => 'addons_users.position'
+ ))));
+ break;
+
+ case 'compatible_apps':
+ // list of applications this add-on is compatible with
+ break;
+
+ case 'files':
+ // list of files for all versions returned (depends on lastversion
+ // or allversions);
+ loadModel('File');
+ break;
+
+ case 'latest_version':
+ // latest public version for public add-ons, latest valid
+ // version otherwise
+ break;
+
+ case 'list_details':
+ // add-on details needed for a list item
+ $fields = array_merge($fields, array('summary', 'eula',
+ 'weeklydownloads', 'addontype_id', 'averagerating', 'totalreviews'));
+ break;
+
+ case 'single_tag':
+ // the first category this add-on is associated with
+ $this->bindModel(array('hasMany' =>
+ array('AddonTag' =>
+ array('className' => 'AddonTag',
+ 'foreignKey' => 'addon_id',
+ 'limit' => 1
+ ))));
+ break;
+
+ default:
+ debug("Association $association not declared!");
+ break;
+ }
+ }
+
+ // get desired add-on from DB
+ $addon = $this->findById($id, $fields);
+
+ // add additional data
+ if (in_array('latest_version', $associations)) {
+ // pull in last version
+ $this->Version->unbindFully();
+ $this->Version->caching = false;
+ $this->Version->useDbConfig = 'shadow';
+ $buf = $this->Version->findAll(array(
+ 'Version.id' => $this->Version->getVersionByAddonId($id,
+ ($addon['Addon']['status']==STATUS_PUBLIC ? STATUS_PUBLIC : $valid_status))),
+ array('Version.id', 'Version.version', 'Version.created'));
+ if (!empty($buf[0]['Version'])) {
+ $addon['Version'][0] = $buf[0]['Version'];
+
+ if (in_array('compatible_apps', $associations)) {
+ /* get add-on app compatibility info for that version */
+ $addon['compatible_apps'] = $this->Version->getCompatibleApps($buf[0]['Version']['id']);
+ }
+ }
+ }
+
+ if (in_array('list_details', $associations)) {
+ // is the addon recommended?
+ $addon['Addon']['recommended'] = $this->is_recommended($id);
+ }
+
+ // files
+ if (in_array('files', $associations) && in_array('latest_version', $associations)
+ && !empty($addon['Version'])) {
+
+ loadModel('File');
+ $this->File =& new File();
+ $this->File->unbindfully();
+ $this->File->caching = false;
+ $_files = $this->File->findAll("File.version_id = '{$addon['Version'][0]['id']}'");
+ foreach ($_files as $_file)
+ $addon['File'][] = $_file['File'];
+
+ // date of addon status change
+ if (!empty($addon['File'])) {
+ if ($addon['Addon']['status'] == STATUS_PUBLIC && $addon['File'][0]['datestatuschanged'] > 0)
+ $addon['Addon']['datestatuschanged'] = $addon['File'][0]['datestatuschanged'];
+ else
+ $addon['Addon']['datestatuschanged'] = $addon['File'][0]['created'];
+ } else {
+ $addon['Addon']['datestatuschanged'] = $addon['Version'][0]['created'];
+ }
+ }
+
+ // add addon tags
+ if ((in_array('all_tags', $associations) || in_array('single_tag', $associations))
+ && !empty($addon['AddonTag'])) {
+
+ $_tag_ids = array();
+ foreach ($addon['AddonTag'] as $_tag)
+ $_tag_ids[] = $_tag['tag_id'];
+ $tags = array();
+ if (!empty($_tag_ids))
+ $tags = $this->Tag->findAll(array('Tag.id' => $_tag_ids, 'Tag.application_id' => APP_ID));
+ $addon['Tag'] = $tags;
+ }
+
+ // cache this object...
+ if (QUERY_CACHE)
+ $this->Cache->writeCacheObject($identifier, $addon, "addon:$id");
+
+ // re-enable query caching
+ $this->caching = $caching_was;
+
+ // ... then hand it back to the caller
+ return $addon;
+ }
+
+ /**
+ * Get a list of add-ons by id, each with the given associations
+ * uses the object invalidation framework
+ */
+ function getAddonList($ids, $associations = array()) {
+ $result = array();
+ foreach ($ids as $id) {
+ $result[] = $this->getAddon($id, $associations);
+ }
+ return $result;
+ }
+
+ /**
+ * Get addons in a category, sorted by name, popularity (weekly downloads)
+ * or "recently updated" (last file approval timestamp).
+ *
+ * @return array list of matching add-on ids
+ */
+ function getAddonsFromCategory($status = array(STATUS_PUBLIC),
+ $addontypes = ADDON_EXTENSION, $category = 'all', $sort_by = 'name',
+ $direction = 'ASC', $limit = '5', $page = '1', $friends = '') {
+
+ $this->unbindFully();
+
+ $select_field = 'DISTINCT Addon.id';
+
+ // make input data uniform
+ if (!is_array($addontypes)) $addontypes = array($addontypes);
+ if (!is_array($status)) $status = array($status);
+ if ($page <= 0) $page = 1;
+
+ // additional joins for sort order etc.
+ $add_joins = $orderby = $limitclause = $groupby = $where = '';
+ if ($category != 'all') {
+ // if cat == all, don't worry about the category. Otherwise only select the chosen one.
+ $add_joins .= "INNER JOIN addons_tags AS at ON (at.tag_id = '{$category}' AND at.addon_id = Addon.id) ";
+ }
+ // only select add-ons that have any files to offer
+ $add_joins .= "INNER JOIN files AS File ON (Version.id = File.version_id AND File.status IN (".implode(',',$status).")) ";
+
+ // Facebook friends
+ if (!empty($friends)) {
+ $add_joins .= "INNER JOIN facebook_favorites AS ff ON ff.addon_id = Addon.id ";
+ $where .= "AND ff.fb_user IN ({$friends}) ";
+ }
+
+ // additional joins etc per list type
+ switch ($sort_by) {
+ case 'name':
+ $add_joins .= "LEFT JOIN translations AS tr_l ON (tr_l.id = Addon.name AND tr_l.locale = '".LANG."') "
+ ."LEFT JOIN translations AS tr_en ON (tr_en.id = Addon.name AND tr_en.locale = `Addon`.`defaultlocale`) ";
+ break;
+ case 'updated':
+ // for public addons: last date of a file being pushed public
+ // for sandboxed addons: last file modification date
+ $select_field .= ', IF(Addon.status = '.STATUS_PUBLIC.', '
+ .'MAX(File.datestatuschanged), MAX(File.created)) '
+ .'AS datestatuschanged';
+ $groupby = 'GROUP BY Addon.id';
+ break;
+ }
+
+ // translate sort_by into SQL ORDER BY
+ if (!empty($sort_by)) {
+ $orderby = 'ORDER BY ';
+ switch ($sort_by) {
+ case 'popular':
+ $orderby .= 'Addon.weeklydownloads';
+ break;
+ case 'updated':
+ $orderby .= 'datestatuschanged';
+ break;
+ case 'rated':
+ $orderby .= 'Addon.bayesianrating';
+ break;
+ case 'newest':
+ $orderby .= 'Addon.created';
+ break;
+ case 'name':
+ default:
+ $orderby .= 'IFNULL(tr_l.localized_string, tr_en.localized_string)'; break;
+ }
+ $orderby .= ' '.$direction;
+ } else {
+ $orderby = '';
+ }
+
+ if (!empty($page) && !empty($limit))
+ $limitclause = "LIMIT ".(($page-1)*$limit).", {$limit}";
+ else
+ $limitclause = '';
+
+ // If the search engine type is the only add-on we're looking for, we remove
+ // the restriction on applications. If the search engine type is in the list
+ // with other types, it _won't work_ because there is no application
+ // relationship for search engines.
+ if (in_array(ADDON_SEARCH, $addontypes) && count($addontypes) == 1) {
+ $sql = "SELECT {$select_field} FROM addons AS Addon "
+ ."INNER JOIN versions AS Version ON (Addon.id = Version.addon_id) "
+ .$add_joins
+ ."WHERE Addon.addontype_id IN(".implode(',',$addontypes).") "
+ ."AND Addon.status IN(".implode(',',$status).") "
+ ."AND Addon.inactive = 0 "
+ ."{$where} {$groupby} {$orderby} {$limitclause}";
+ } else {
+ $sql = "SELECT {$select_field} FROM addons AS Addon "
+ ."INNER JOIN versions AS Version ON (Addon.id = Version.addon_id) "
+ ."INNER JOIN applications_versions AS av ON (av.version_id = Version.id AND av.application_id = ".APP_ID.") "
+ .$add_joins
+ ."WHERE Addon.addontype_id IN(".implode(',',$addontypes).") "
+ ."AND Addon.status IN(".implode(',',$status).") "
+ ."AND Addon.inactive = 0 "
+ ."{$where} {$groupby} {$orderby} {$limitclause}";
+ }
+
+ $addon_list = $this->query($sql,true);
+
+ // if there are no results, we are done.
+ if (empty($addon_list)) return $addon_list;
+
+ // otherwise return the ids
+ $addon_ids = array();
+ foreach($addon_list as $id) $addon_ids[] = $id['Addon']['id'];
+ return $addon_ids;
+ }
+
+ /**
+ * Sort and optionally paginate the addons in $addon_ids.
+ */
+ function sorted($addon_ids, $field, $limit=null, $page=null, $extra='') {
+ // Bail early if there isn't anything to sort.
+ if (empty($addon_ids)) {
+ return $addon_ids;
+ }
+
+ $join = $orderby = $direction = $limit_clause = '';
+
+ $select = "SELECT DISTINCT Addon.id FROM addons AS Addon";
+
+ $ids = implode(',', $addon_ids);
+ $where = "WHERE Addon.id IN ({$ids})";
+
+ if (strstr($field, ' ')) {
+ list($field, $direction) = explode(' ', $field);
+ }
+
+ if (in_array($field, $this->translated_fields)) {
+ $join = "LEFT JOIN translations AS tr_l
+ ON (tr_l.id = Addon.{$field} AND tr_l.locale = '".LANG."')
+ LEFT JOIN translations AS tr_en
+ ON (tr_en.id = Addon.{$field} AND tr_en.locale = `Addon`.`defaultlocale`) ";
+ $orderby = "ORDER BY IFNULL(tr_l.localized_string, tr_en.localized_string)";
+ } else if (!empty($extra)) {
+ $join = $extra;
+ $orderby = "ORDER BY {$field}";
+ } else {
+ $orderby = "ORDER BY Addon.{$field}";
+ }
+
+ if (isset($limit) && isset($page)) {
+ $offset = ($page - 1) * $limit;
+ $limit_clause .= "LIMIT {$limit} OFFSET {$offset}";
+ }
+
+ $sql = implode(' ', array($select, $join, $where, $orderby, $direction, $limit_clause));
+
+ foreach($this->query($sql) as $a) $sorted[] = $a['Addon']['id'];
+
+ return $sorted;
+ }
+
+ /**
+ * Get a list of addon IDs from a collection
+ * @param int $collectionId ID of the collection
+ * @param string $orderBy field name to sort the list by
+ * @param int $cat_id sub-category ID, null for all
+ */
+ function getAddonsFromCollection($collectionId = null, $orderBy = null, $cat_id = null, $limit = null) {
+ global $valid_status;
+
+ $this->unbindFully();
+
+ $query = "SELECT DISTINCT(Addon.id) FROM addons AS Addon INNER JOIN versions AS Version ON (Addon.id = Version.addon_id) "
+ ."INNER JOIN files AS File ON (Version.id = File.version_id AND File.status IN (".join(",",$valid_status).")) "
+ ."INNER JOIN addons_collections AS ac ON (ac.addon_id = Addon.id AND ac.collection_id = $collectionId AND "
+ .((is_null($cat_id))?'1':"ac.category='{$cat_id}'").") WHERE "
+ ."Addon.status IN (".join(",",$valid_status).") AND Addon.inactive = 0";
+
+ if (!is_null($orderBy)) {
+ $query .= " ORDER BY {$orderBy}";
+ }
+
+ if (!is_null($limit)) {
+ $query .= " LIMIT {$limit}";
+ }
+
+
+ $addon_list = $this->query($query, true);
+ $addons_ids = array();
+ if(!empty($addon_list)) {
+ foreach($addon_list as $id) {
+ $addons_ids[] = $id['Addon']['id'];
+ }
+ }
+
+ return $addons_ids;
+ }
+
+ /**
+ * Get a list of addon IDs from a category, divided into subcategories
+ */
+ function getCategorizedAddonsFromCollection($collectionId = null) {
+ $subcatlist = $this->query('SELECT DISTINCT(ac.category) FROM addons_collections AS ac '
+ ."WHERE ac.collection_id='{$collectionId}' ORDER BY ac.category");
+
+ $result = array();
+ if (empty($subcatlist)) return $result;
+ foreach ($subcatlist as $cat) {
+ $catid = $cat['ac']['category'];
+ $result[$catid] = $this->getAddonsFromCollection($collectionId, 'name', $catid);
+ }
+ return $result;
+ }
+
+ /**
+ * Get the number of addons in a specific category
+ */
+ function countAddonsInCategory($status = array(STATUS_PUBLIC),
+ $addontypes = ADDON_EXTENSION, $category = 'all', $friends = '') {
+
+ $rowcount = $this->getAddonsFromCategory($status, $addontypes, $category,
+ null, null, null, null, $friends);
+ return count($rowcount);
+ }
+
+ /**
+ * Count all addons in all categories for a given type.
+ */
+ function countAddonsInAllCategories($status = array(STATUS_PUBLIC), $addontypes = array(ADDON_THEME)) {
+
+ if (!is_array($status))
+ $status = array($status);
+ if (!is_array($addontypes))
+ $addontypes = array($addontypes);
+
+ // Construct the SQL query, stolen from getAddonsByCategory
+ $sql = 'SELECT at.tag_id, COUNT(DISTINCT Addon.id) AS co '
+ .'FROM addons AS Addon '
+ .'INNER JOIN versions AS Version ON (Addon.id = Version.addon_id) '
+ .'INNER JOIN applications_versions AS av ON (av.version_id = Version.id AND av.application_id = '.APP_ID.') '
+ .'INNER JOIN addons_tags AS at ON (at.addon_id = Addon.id) '
+ .'INNER JOIN files AS File ON (Version.id = File.version_id AND File.status IN ('.implode(',',$status).')) '
+ .'WHERE Addon.addontype_id IN('.implode(',',$addontypes).') '
+ .'AND Addon.status IN('.implode(',',$status).') '
+ .'AND Addon.inactive = 0 '
+ .'GROUP BY at.tag_id';
+
+ $rows = $this->query($sql, true);
+
+ // Reduce the rows from the DB down to simple ID / count
+ $addon_counts = array();
+ foreach ($rows as $row) {
+ $addon_counts[ $row['at']['tag_id'] ] = $row[0]['co'];
+ }
+
+ return $addon_counts;
+ }
+
+ /**
+ * Returns the name of the add-on with given id
+ */
+ function getAddonName($addon_id) {
+ $addon = $this->find("Addon.id={$addon_id}", array('name'), null, 0);
+ if ($addon)
+ return $addon['Translation']['name']['string'];
+ else
+ return false;
+ }
+
+ /**
+ * Returns the name and ids of all add-ons by the user
+ */
+ function getAddonsByUser($user_id) {
+ $addons = array();
+ $addon_ids = $this->query("SELECT DISTINCT addon_id FROM addons_users WHERE user_id={$user_id}");
+ if (!empty($addon_ids)) {
+ foreach ($addon_ids as $addon_id) {
+ $addons[$addon_id['addons_users']['addon_id']] = $this->getAddonName($addon_id['addons_users']['addon_id']);
+ }
+ }
+
+ asort($addons);
+
+ return $addons;
+ }
+
+ /**
+ * Returns an array of recommended add-ons' ids.
+ * To be used with getAddonList()
+ *
+ * @param int $limit max. amount of results to return
+ * @param string $order SQL order by clause
+ */
+ function getRecommendedAddons($limit=null, $order='RAND()') {
+ $this->Feature->unbindFully();
+ $criteria = "Feature.start < NOW() AND Feature.end > NOW() "
+ ."AND Feature.application_id ='" . APP_ID . "' AND "
+ ."(Feature.locale = '" . LANG . "' OR Feature.locale IS NULL)";
+ $featAddons = $this->Feature->findAll($criteria, null, $order, $limit, 0);
+
+ $_addon_ids = array();
+ foreach ($featAddons as $_addon)
+ $_addon_ids[] = $_addon['Feature']['addon_id'];
+
+ return $_addon_ids;
+ }
+
+ /**
+ * Is this add-on currently recommended?
+ * @param int addon ID
+ * @return bool addon is currently featured
+ */
+ function is_recommended($addon_id) {
+ $this->Feature->unbindFully();
+ $criteria = "Feature.addon_id = $addon_id AND "
+ ."Feature.start < NOW() AND Feature.end > NOW() AND "
+ ."Feature.application_id ='" . APP_ID . "' AND "
+ ."(Feature.locale = '" . LANG . "' OR Feature.locale IS NULL)";
+
+ $_rec = $this->Feature->findCount($criteria);
+
+ return ($_rec >= 1);
+ }
+
+ /**
+ * Get the most recent update ping count
+ * This is temporary until we can store this in addons and update
+ * it via cron
+ */
+ function getMostRecentUpdatePingCount($addon_id) {
+ $count = $this->query("SELECT `count` FROM update_counts WHERE addon_id={$addon_id} ORDER BY `date` DESC LIMIT 1");
+
+ return !empty($count) ? $count[0]['update_counts']['count'] : 0;
+ }
+
+ /**
+ * Retrieves all details from addons_users for a particular add-on
+ */
+ function getAuthors($addon_id, $onlyListed = true) {
+ $listedQry = $onlyListed ? 'AND addons_users.listed=1 ' : '';
+
+ $authors = $this->query("SELECT addons_users.*, User.id, User.email, User.firstname, User.lastname, User.nickname FROM addons_users INNER JOIN users AS User ON addons_users.user_id = User.id WHERE addons_users.addon_id={$addon_id} {$listedQry}ORDER BY addons_users.position");
+
+ return $authors;
+ }
+
+ /**
+ * Removes all authors from an add-on
+ */
+ function clearAuthors($addon_id) {
+ return $this->execute("DELETE FROM addons_users WHERE addon_id={$addon_id}");
+ }
+
+ /**
+ * Saves an add-on author
+ */
+ function saveAuthor($addon_id, $user_id, $role = AUTHOR_ROLE_OWNER, $listed = 1, $position = 0) {
+ return $this->execute("INSERT INTO addons_users (addon_id, user_id, role, listed, position) VALUES({$addon_id}, {$user_id}, {$role}, {$listed}, {$position})");
+ }
+
+ /**
+ * Gets all applications ever supported by the add-on
+ */
+ function getApplicationsEverSupported($addon_id) {
+ return $this->query("SELECT DISTINCT Application.* FROM addons AS Addon INNER JOIN versions AS Version on Version.addon_id=Addon.id INNER JOIN applications_versions AS av ON av.version_id=Version.id INNER JOIN applications AS Application ON Application.id=av.application_id WHERE Addon.id={$addon_id}");
+ }
+
+ /**
+ * afterSave callback. Mark cached objects for flush.
+ */
+ function afterSave() {
+ if (QUERY_CACHE) $this->Cache->markListForFlush("addon:{$this->id}");
+ return parent::afterSave();
+ }
+
+ /**
+ * Get the date the addon was added to a specific collection
+ */
+ function getCollectionPublishDetails($addon_id, $collectionId) {
+ $this->unbindFully();
+
+ // comments are en-US only
+ $sql = "SELECT addons_collections.added, translations.localized_string as comment, users.id, users.firstname, users.lastname, users.nickname
+ FROM addons_collections
+ LEFT JOIN translations
+ ON translations.id = addons_collections.comments AND translations.locale='en-US'
+ INNER JOIN users
+ ON users.id = addons_collections.user_id
+ WHERE collection_id = {$collectionId} AND addon_id = {$addon_id}";
+ $data = $this->query($sql);
+
+ $details = array(
+ 'dateadded' => $data[0]['addons_collections']['added'],
+ 'publisher' => $data[0]['users'],
+ 'comment' => $data[0]['translations']['comment']
+ );
+ return $details;
+ }
+
+ /**
+ * Return the ids of addons authored by any of the User ids.
+ */
+ function getAddonsForAuthors($author_ids) {
+ $addon_id_sql = "SELECT DISTINCT addons.id
+ FROM addons
+ INNER JOIN addons_users
+ ON (addons.id=addons_users.addon_id AND
+ addons_users.user_id IN (".implode(', ', $author_ids)."))";
+ foreach($this->query($addon_id_sql) as $addon)
+ $addon_ids[] = $addon['addons']['id'];
+ return $addon_ids;
+ }
+
+ /**
+ * When an add-on was shared with others by email, increase the counter
+ * accordingly.
+ * @param int $addonid Add-on ID
+ * @param int $number times shared
+ * @return boolean success
+ */
+ function increaseShareCount($addonid, $number) {
+ $sql = "UPDATE addons SET sharecount = sharecount + {$number} WHERE id = {$addonid};";
+ return $this->execute($sql);
+ }
+
+ /* * * * * * deprecated functions * * * * * */
+ /**
+ * Return add-ons with latest version information.
+ *
+ * @params mixed $id int or array of ints
+ * @params array $status
+ * @deprecated since 4.0.1, use getAddonList() instead
+ */
+ function getListAddons($id, $status = array(STATUS_PUBLIC), $order = null, $includeFiles = false) {
+
+ // Bind previews and include only the fields we want.
+ $this->unbindModel(array('hasMany'=>array('className'=>'Version')));
+ $this->bindModel(
+ array(
+ 'hasMany'=>
+ array(
+ 'Preview' =>
+ array(
+ 'className' => 'Preview',
+ 'conditions' => '',
+ 'order' => 'Preview.highlight DESC',
+ 'limit' => '',
+ 'foreignKey' => 'addon_id',
+ 'dependent' => true,
+ 'exclusive' => false,
+ 'finderSql' => '',
+ 'fields' => array('id', 'addon_id', 'filetype', 'thumbtype', 'caption', 'highlight', 'created', 'modified')
+ ),
+
+ 'AddonTag' =>
+ array('classname' => 'AddonTag',
+ 'conditions' => '',
+ 'order' => '',
+ 'limit' => '',
+ 'foreignKey' => 'addon_id',
+ 'dependent' => true,
+ 'exclusive' => false,
+ 'finderSql' => ''
+ )
+ )
+ )
+ );
+
+ $this->useDbConfig = 'shadow';
+
+ $_fields = array('id', 'guid', 'name', 'defaultlocale', 'addontype_id', 'status',
+ 'icontype', 'icondata', 'supportemail', 'supporturl', 'homepage', 'description', 'summary',
+ 'averagerating', 'weeklydownloads', 'totaldownloads', 'totalreviews',
+ 'developercomments', 'inactive', 'trusted', 'viewsource', 'publicstats',
+ 'prerelease', 'adminreview', 'sitespecific', 'externalsoftware',
+ 'eula', 'privacypolicy', 'target_locale', 'locale_disambiguation',
+ 'nominationmessage', 'created', 'modified');
+
+ $addons = $this->findAllById($id, $_fields, $order);
+
+ if (!empty($addons) && is_array($addons)) {
+ // we need to File model to pull in the files if requested
+ if ($includeFiles) {
+ loadModel('File');
+ $this->File =& new File();
+ }
+
+ foreach ($addons as $key=>$addon) {
+ /* pull in last version */
+ $this->Version->unbindFully();
+ $this->Version->useDbConfig = 'shadow';
+ $buf = $this->Version->findAll(array(
+ 'Version.id' => $this->Version->getVersionByAddonId($addon['Addon']['id'],
+ ($addon['Addon']['status']==STATUS_PUBLIC ? STATUS_PUBLIC : $status))),
+ array('Version.id', 'Version.version', 'Version.created'));
+ if (!empty($buf[0]['Version'])) {
+ $addons[$key]['Version'][0] = $buf[0]['Version'];
+
+ /* get add-on app compatibility info for that version */
+ $addons[$key]['compatible_apps'] = $this->Version->getCompatibleApps($buf[0]['Version']['id']);
+ }
+
+ // is the addon recommended?
+ $addons[$key]['Addon']['recommended'] = $this->is_recommended($addon['Addon']['id']);
+
+ // add addon tags
+ if (!empty($addon['AddonTag'])) {
+ $_tag_ids = array();
+ foreach($addon['AddonTag'] as $_tag)
+ $_tag_ids[] = $_tag['tag_id'];
+ $tags = array();
+ if (!empty($_tag_ids))
+ $tags = $this->Tag->findAll(array('Tag.id' => $_tag_ids, 'Tag.application_id' => APP_ID));
+ $addons[$key]['Tag'] = $tags;
+ }
+
+ /* add files for last version, if requested */
+ if ($includeFiles && !empty($addons[$key]['Version'])) {
+ $this->File->unbindfully();
+ $_files = $this->File->findAll("File.version_id = '{$addons[$key]['Version'][0]['id']}'");
+ foreach ($_files as $_file)
+ $addons[$key]['File'][] = $_file['File'];
+ }
+ }
+ }
+ return $addons;
+ }
+
+ /**
+ * Get addons in a category, sorted by name, popularity (weekly downloads)
+ * or "recently updated" (last file approval timestamp).
+ *
+ * @deprecated since 4.0.1, use getAddonsFromCategory along with getAddonList instead
+ */
+ function getAddonsByCategory($fields = null, $status = array(STATUS_PUBLIC),
+ $addontypes = ADDON_EXTENSION, $category = 'all', $sort_by = 'name',
+ $direction = 'ASC', $limit = '5', $page = '1', $friends = '', $includeFiles = false) {
+
+ $associations = array('all_tags', 'authors', 'compatible_apps',
+ 'latest_version', 'list_details');
+ if ($includeFiles) {
+ $associations[] = 'files';
+ sort($associations);
+ }
+ // are we just counting the total rows?
+ $counting = (is_string($fields) && strpos(low($fields), 'count') === 0);
+ if (!$counting) {
+ $ids = $this->getAddonsFromCategory($status, $addontypes, $category,
+ $sort_by, $direction, $limit, $page, $friends);
+ return $this->getAddonList($ids, $associations);
+ } else {
+ return $this->countAddonsInCategory($status, $addontypes, $category, $friends);
+ }
+ }
+}
+?>
diff --git a/site/app/models/addon_collection.php b/site/app/models/addon_collection.php
new file mode 100644
index 0000000..00d2b0a
--- /dev/null
+++ b/site/app/models/addon_collection.php
@@ -0,0 +1,222 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Ryan Doherty <rdoherty@mozilla.com>
+ * Frederic Wenzel <fwenzel@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+class AddonCollection extends AppModel
+{
+ var $name = "AddonCollection";
+ var $useTable = 'addons_collections';
+ var $belongsTo = array('Addon', 'Collection');
+ var $recursive = -1;
+ var $translated_fields = array(
+ 'comments'
+ );
+
+ /**
+ * Delete any addon/collection associations by addon_id and collection_id
+ *
+ * @param int $addon_id
+ * @param int $collection_id
+ * @param int $user_id optional: only delete the association if $user_id was the publisher.
+ * @return bool success (false on error or when nothing was deleted)
+ */
+ function deleteByAddonIdAndCollectionId($addon_id, $collection_id, $user_id = null) {
+ if (!is_numeric($addon_id)) return false;
+ if (!is_numeric($collection_id)) return false;
+ if (!empty($user_id) && !is_numeric($user_id)) return false;
+
+ $sql = "DELETE FROM addons_collections WHERE addon_id={$addon_id} AND collection_id={$collection_id}";
+ if (!empty($user_id)) $sql .= " AND user_id = {$user_id}";
+
+ $res = $this->query($sql);
+ return (!($res === false || $this->getAffectedRows() == 0));
+ }
+
+ /**
+ * Get a list of add-ons belonging to this collection
+ *
+ * @param int $collection_id Collection ID
+ * @return array list of add-ons
+ */
+ function getAddonsFromCollection($collection_id) {
+ $db =& ConnectionManager::getDataSource($this->useDbConfig);
+ $collection_id = $db->value($collection_id);
+ $this->unbindFully();
+ $res = $this->findAll(array('collection_id' => $collection_id));
+ if (!empty($res)) {
+ loadModel('Addon');
+ loadModel('User');
+ if (empty($this->Addon)) $this->Addon =& new Addon();
+ if (empty($this->User)) $this->User =& new User();
+ foreach ($res as &$row) {
+ $row['Addon'] = $this->Addon->getAddon($row['AddonCollection']['addon_id']);
+ $user = $this->User->findById($row['AddonCollection']['user_id']);
+ $row['User'] = $user['User'];
+ }
+ }
+ return $res;
+ }
+
+ /**
+ * set the publisher comment for a specific add-on in a collection (for now,
+ * en-US only)
+ *
+ * @param int $collection_id
+ * @param int $addon_id
+ * @param string $comment comment to be saved
+ * @return bool success
+ */
+ function setComment($collection_id, $addon_id, $comment) {
+ $db =& ConnectionManager::getDataSource($this->useDbConfig);
+ $collection_id = $db->value($collection_id);
+ $addon_id = $db->value($addon_id);
+ $comment = $db->value($comment);
+
+ $row = $this->query("SELECT comments FROM addons_collections "
+ ."WHERE collection_id = {$collection_id} AND addon_id = {$addon_id}");
+ if (empty($row)) return false; // not found or access denied
+
+ $this->begin(); // transactions are our friends
+
+ if (!empty($row[0]['addons_collections']['comments'])) {
+ $id = $row[0]['addons_collections']['comments'];
+ } else {
+ // generate a new primary key id
+ $db->execute('UPDATE translations_seq SET id=LAST_INSERT_ID(id+1);');
+ $_res = $db->execute('SELECT LAST_INSERT_ID() AS id FROM translations_seq;');
+ if ($_row = $db->fetchRow()) {
+ $id = $_row[0]['id'];
+ } else {
+ $this->rollback();
+ return false;
+ }
+ }
+ // delete all existing comments
+ $db->execute("UPDATE translations SET localized_string = NULL WHERE id = {$id}");
+
+ // insert the new one, if applicable (en-US only)
+ if (!empty($comment)) {
+ $db->execute("INSERT INTO translations (id, locale, localized_string, created) "
+ ."VALUES ({$id}, 'en-US', {$comment}, NOW()) "
+ ."ON DUPLICATE KEY UPDATE localized_string=VALUES(localized_string), modified=VALUES(created);");
+ }
+ // link comments field to translations
+ $res = $db->execute("UPDATE addons_collections SET comments = {$id} "
+ ."WHERE collection_id = {$collection_id} AND addon_id = {$addon_id}");
+ if (false !== $res) {
+ $this->commit();
+ return true;
+ } else {
+ $this->rollback();
+ return false;
+ }
+ }
+
+ /**
+ * is an add-on part of a given collection?
+ *
+ * @param int addon_id
+ * @param int collection_id
+ * @return bool true if addon is in collection, false otherwise
+ */
+ function isAddonInCollection($addon_id, $collection_id) {
+ if (!is_numeric($collection_id) || !is_numeric($addon_id)) return null;
+ $res = $this->query("SELECT addon_id FROM addons_collections WHERE addon_id = {$addon_id} AND collection_id = {$collection_id};");
+ return (!empty($res));
+ }
+
+ /**
+ * get most popular collections that a given add-on is part of
+ * @param int $addon_id
+ * @param int $limit (optional) max. amount of collections returned, default 3
+ * @param string $app (optional) application ID to restrict search to, default all
+ * @return array collection ids
+ */
+ function getPopularCollectionsForAddon($addon_id, $limit = 3, $app = null) {
+ if (!is_numeric($addon_id)) return false;
+
+ if (is_numeric($limit) && $limit > 0)
+ $_lim = " LIMIT {$limit}";
+ else
+ $_lim = '';
+
+ if (is_numeric($app) && $app > 0) {
+ $_where = " AND c.application_id = {$app}";
+ } else {
+ $_where = '';
+ }
+
+ $colls = array();
+ $res = $this->query(
+ "SELECT collection_id "
+ ."FROM addons_collections AS ac "
+ ."INNER JOIN collections AS c ON (c.id = ac.collection_id) "
+ ."WHERE addon_id = {$addon_id}{$_where} "
+ ."ORDER BY c.subscribers DESC"
+ .$_lim.";");
+ foreach ($res as &$row) {
+ $colls[] = $row['ac']['collection_id'];
+ }
+ return $colls;
+ }
+
+ /**
+ * count amount of collections that a given add-on is in
+ * @param int $addon_id
+ * @return int collection count >= 0, false in case of error
+ * @param string $app (optional) application ID to restrict search to, default all
+ */
+ function getCollectionCountForAddon($addon_id, $app = null) {
+ if (!is_numeric($addon_id)) return false;
+
+ if (is_numeric($app) && $app > 0) {
+ $_join = " INNER JOIN collections AS c ON (c.id = ac.collection_id AND c.application_id = {$app})";
+ } else {
+ $_join = '';
+ }
+
+ $res = $this->query(
+ "SELECT COUNT(ac.collection_id) AS cnt "
+ ."FROM addons_collections AS ac "
+ . $_join
+ ."WHERE ac.addon_id = {$addon_id};");
+ if (!$res) return false;
+ return $res[0][0]['cnt'];
+ }
+
+}
diff --git a/site/app/models/addon_tag.php b/site/app/models/addon_tag.php
new file mode 100644
index 0000000..19cbe2e
--- /dev/null
+++ b/site/app/models/addon_tag.php
@@ -0,0 +1,90 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Wil Clouser <clouserw@mozilla.com> (Original Author)
+ * Frederic Wenzel <fwenzel@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+class AddonTag extends AppModel
+{
+ // This is sort of experimental. I need to retrieve information stored with this
+ // relationship (in the addons_tags model). Cake 1.1 doesn't provide a way to do that
+ // so I'm sort of abusing it here and making the Addon model do an extra hasMany join
+ // against this model (it's already doing an HABTM join against Tag using this table).
+ // Cake 1.2 fixes this problem and we can rip all this code out... --clouserw
+
+ var $name = 'AddonTag';
+ var $useTable = 'addons_tags';
+ var $belongsTo = array('Addon', 'Tag');
+
+ var $recursive = -1;
+
+ /**
+ * Returns add-ons for the given category (recommended or not).
+ *
+ * @param mixed single tag or array of tags
+ * @param bool return recommended or non-recommended add-ons?
+ * @param int limit amount of add-ons to return
+ * @param string SQL order, default random
+ * @return array Add-on IDs that match the criteria
+ */
+ function getRandomAddons($tag, $recommended=false, $limit=null, $order='RAND()', $addontype=null) {
+ global $valid_status;
+
+ if (!is_array($tag)) $tag = array($tag);
+ if (!is_null($addontype) && !is_array($addontype)) $addontype = array($addontype);
+
+ $raw_addons = $this->query(
+ "SELECT DISTINCT Addon.id "
+ ."FROM addons_tags AS AddonTag "
+ ."INNER JOIN addons AS Addon ON (AddonTag.addon_id = Addon.id)"
+ ."WHERE "
+ ."AddonTag.tag_id IN (".implode(',', $tag).') AND '
+ ."AddonTag.feature = ".($recommended ? '1' : '0')." AND "
+ ."Addon.status IN (".implode(',', $valid_status).') AND '
+ .'Addon.inactive = 0 '
+ .(!empty($addontype) ? ' AND Addon.addontype_id IN ('.implode(',', $addontype).') ' : '')
+ ."ORDER BY $order "
+ .(!empty($limit) ? "LIMIT $limit" : '')
+ );
+
+ $idlist = array();
+ if (!empty($raw_addons))
+ foreach ($raw_addons as $addon) $idlist[] = $addon['Addon']['id'];
+
+ return $idlist;
+ }
+}
+?>
diff --git a/site/app/models/addontype.php b/site/app/models/addontype.php
new file mode 100644
index 0000000..8353724
--- /dev/null
+++ b/site/app/models/addontype.php
@@ -0,0 +1,110 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Andrei Hajdukewycz <sancus@off.net> (Original Author)
+ * Justin Scott <fligtar@gmail.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+class Addontype extends AppModel
+{
+ var $name = 'Addontype';
+
+ var $hasMany_full = array('Addon' =>
+ array('className' => 'Addon',
+ 'conditions' => '',
+ 'order' => '',
+ 'limit' => '',
+ 'foreignKey' => 'addontype_id',
+ 'dependent' => false,
+ 'exclusive' => false,
+ 'finderSql' => ''
+ ),
+ 'Tag' =>
+ array('className' => 'Tag',
+ 'conditions' => '',
+ 'order' => '',
+ 'limit' => '',
+ 'foreignKey' => 'addontype_id',
+ 'dependent' => false,
+ 'exclusive' => false,
+ 'finderSql' => ''
+ )
+ );
+
+ /**
+ * Returns the name of the add-on type requested
+ *
+ * @param int id of the add-on type
+ * @return string
+ */
+ function getName($id) {
+ switch($id) {
+ case ADDON_EXTENSION:
+ return ___('general_addontype_extension');
+ case ADDON_THEME:
+ return ___('general_addontype_theme');
+ case ADDON_DICT:
+ return ___('general_addontype_dict');
+ case ADDON_SEARCH:
+ return ___('general_addontype_search');
+ case ADDON_LPAPP:
+ return ___('general_addontype_lpapp');
+ case ADDON_LPADDON:
+ return ___('general_addontype_lpaddon');
+ case ADDON_PLUGIN:
+ return ___('general_addontype_plugin');
+ }
+ }
+
+ /**
+ * Returns an array of all addontype names and IDs in the form of:
+ * id => name
+ * @return array
+ */
+ function getNames() {
+ $addontypes = array(
+ ADDON_EXTENSION => ___('general_addontype_extension_plural'),
+ ADDON_THEME => ___('general_addontype_theme_plural'),
+ ADDON_DICT => ___('general_addontype_dict_plural'),
+ ADDON_SEARCH => ___('general_addontype_search_plural'),
+ ADDON_LPAPP => ___('general_addontype_lpapp_plural'),
+ ADDON_LPADDON => ___('general_addontype_lpaddon_plural'),
+ ADDON_PLUGIN => ___('general_addontype_plugin_plural')
+ );
+
+ return $addontypes;
+ }
+}
+?>
diff --git a/site/app/models/api_auth_token.php b/site/app/models/api_auth_token.php
new file mode 100644
index 0000000..e7924c1
--- /dev/null
+++ b/site/app/models/api_auth_token.php
@@ -0,0 +1,190 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * l.m.orchard <lorchard@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+class ApiAuthToken extends AppModel
+{
+ var $name = "ApiAuthToken";
+
+ var $belongsTo = array(
+ 'User' => array(
+ 'className' => 'User',
+ 'conditions' => '',
+ 'order' => '',
+ 'foreignKey' => 'user_id'
+ ),
+ );
+
+ var $belongsTo_full = array(
+ 'User' => array(
+ 'className' => 'User',
+ 'conditions' => '',
+ 'order' => '',
+ 'foreignKey' => 'user_id'
+ ),
+ );
+
+ var $validate = array(
+ 'user_id' => VALID_NOT_EMPTY
+ );
+
+ /**
+ * Generate and return a new random token value.
+ *
+ * @return string
+ */
+ function generateTokenValue()
+ {
+ mt_srand((double)microtime()*10000);
+ return md5(uniqid(rand(), true));
+ }
+
+ /**
+ * Generate a hash of siginificant user profile data. Currently, this
+ * includes email and password - changes in either causes a change in
+ * hash.
+ *
+ * @param string User ID
+ * @return string User profile hash
+ */
+ function buildUserProfileHash($user)
+ {
+ return md5(join(' ', array(
+ $user['User']['email'],
+ $user['User']['password']
+ )));
+ }
+
+ /**
+ * Before saving, set a token, UA hash, and profile hash if not all
+ * available.
+ */
+ function beforeSave() {
+ if (empty($this->data['ApiAuthToken']['token'])) {
+ $this->data['ApiAuthToken']['token'] =
+ $this->generateTokenValue();
+ }
+ if (empty($this->data['ApiAuthToken']['user_agent_hash'])) {
+ $this->data['ApiAuthToken']['user_agent_hash'] =
+ md5(env('HTTP_USER_AGENT'));
+ }
+ if (empty($this->data['ApiAuthToken']['user_profile_hash'])) {
+ $user = $this->User->findById(
+ $this->data['ApiAuthToken']['user_id']
+ );
+ $this->data['ApiAuthToken']['user_profile_hash'] =
+ $this->buildUserProfileHash($user);
+ }
+ return parent::beforeSave();
+ }
+
+ /**
+ * Attempt to look up a user for a given auth token.
+ * The user agent hash and user profile hash are verified against any
+ * record found by token string before returning a user record.
+ *
+ * @param string Auth token string
+ * @param string Optional user agent string, pulled from environment if null
+ * @return array Authenticated user details
+ */
+ function getUserForAuthToken($auth_token, $user_agent=null)
+ {
+ if (strpos($auth_token, 'http') === 0) {
+ $auth_token = substr($auth_token, strrpos($auth_token, '/')+1);
+ }
+ if (empty($user_agent)) {
+ $user_agent = env('HTTP_USER_AGENT');
+ }
+ $conditions = array(
+ 'ApiAuthToken.token' => $auth_token,
+ 'ApiAuthToken.user_agent_hash' => md5($user_agent)
+ );
+ $row = $this->find($conditions);
+
+ if (empty($row)) {
+ // No token found for the token string and user agent hash,
+ // so return empty handed.
+ return null;
+ }
+
+ $expected_hash =
+ $this->buildUserProfileHash($row);
+ $token_hash =
+ $row['ApiAuthToken']['user_profile_hash'];
+
+ if ($token_hash != $expected_hash) {
+ // The profile hash didn't match, so delete the token
+ // and return null. Assumes user changed profile details,
+ // so this token should be destroyed since it will never
+ // be valid again.
+ $this->delete($row['ApiAuthToken']['id']);
+ return null;
+ }
+
+ return $row['User'];
+ }
+
+ /**
+ * Delete a token for the given user ID, also performing a user agent check
+ * on top of the auth user check.
+ *
+ * @param string User ID
+ * @param string Token string value
+ * @param string optional user agent string
+ * @return boolean Whether or not the deletion was successful.
+ */
+ function deleteByUserIdAndToken($user_id, $auth_token, $user_agent=null)
+ {
+ if (empty($user_agent)) {
+ $user_agent = env('HTTP_USER_AGENT');
+ }
+ $conditions = array(
+ 'ApiAuthToken.user_id' => $user_id,
+ 'ApiAuthToken.token'=> $auth_token,
+ 'ApiAuthToken.user_agent_hash' => md5($user_agent)
+ );
+ $row = $this->find($conditions);
+
+ if (empty($row)) {
+ return null;
+ }
+
+ $this->delete($row['ApiAuthToken']['id']);
+ return true;
+ }
+
+}
diff --git a/site/app/models/application.php b/site/app/models/application.php
new file mode 100644
index 0000000..da37fb2
--- /dev/null
+++ b/site/app/models/application.php
@@ -0,0 +1,142 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Andrei Hajdukewycz <sancus@off.net> (Original Author)
+ * Justin Scott <fligtar@gmail.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+class Application extends AppModel
+{
+ var $name = 'Application';
+ var $hasMany = array('Appversion' =>
+ array('className' => 'Appversion',
+ 'conditions' => '',
+ 'order' => '',
+ 'limit' => '',
+ 'foreignKey' => 'application_id',
+ 'dependent' => true,
+ 'exclusive' => false,
+ 'finderSql' => ''
+ ),
+ 'Tag' =>
+ array('className' => 'Tag',
+ 'conditions' => '',
+ 'order' => '',
+ 'limit' => '',
+ 'foreignKey' => 'application_id',
+ 'dependent' => false,
+ 'exclusive' => false,
+ 'finderSql' => ''
+ ),
+
+ );
+ var $hasAndBelongsToMany = array('Version' =>
+ array('className' => 'Version',
+ 'joinTable' => 'applications_versions',
+ 'foreignKey' => 'application_id',
+ 'associationForeignKey'=> 'version_id',
+ 'conditions' => '',
+ 'order' => '',
+ 'limit' => '',
+ 'unique' => false,
+ 'finderSql' => '',
+ 'deleteQuery'=> ''
+ )
+ );
+ var $translated_fields = array(
+ 'name',
+ 'shortname'
+ );
+
+ /**
+ * Returns an array of application GUIDs with their associated names
+ */
+ function getGUIDList() {
+ $list = array();
+ $apps = $this->findAll(null, array('guid', 'name'), null, null, null, -1);
+
+ if (!empty($apps)) {
+ foreach ($apps as $app) {
+ $list[$app['Application']['guid']] = $app['Translation']['name']['string'];
+ }
+ }
+
+ return $list;
+ }
+
+ /**
+ * Return a list of application ids and names
+ * @deprecated since 3.5 - use getNames()
+ */
+ function getIDList() {
+ return $this->getNames();
+ }
+
+ /**
+ * Returns an array of all application names and IDs in the form of:
+ * id => name
+ */
+ function getNames() {
+ $_applications = $this->findAll(null, array('Application.id', 'Application.name'), null, null, null, -1);
+
+ $applications = array();
+ if (!empty($_applications)) {
+ foreach ($_applications as $application) {
+ $applications[$application['Application']['id']] = $application['Translation']['name']['string'];
+ }
+ asort($applications);
+ }
+ return $applications;
+ }
+
+ /**
+ * Returns an array of all application shortnames and IDs in the form of:
+ * id => shortname
+ */
+ function getShortNames() {
+ $_applications = $this->findAll(null, array('Application.id', 'Application.shortname'), null, null, null, -1);
+
+ $applications = array();
+ if (!empty($_applications)) {
+ foreach ($_applications as $application) {
+ $applications[$application['Application']['id']] = $application['Translation']['shortname']['string'];
+ }
+ asort($applications);
+ }
+ return $applications;
+ }
+
+}
+?>
diff --git a/site/app/models/approval.php b/site/app/models/approval.php
new file mode 100644
index 0000000..5869592
--- /dev/null
+++ b/site/app/models/approval.php
@@ -0,0 +1,56 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Andrei Hajdukewycz <sancus@off.net> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+class Approval extends AppModel
+{
+ var $name = 'Approval';
+ var $belongsTo = array('User' =>
+ array('className' => 'User',
+ 'conditions' => '',
+ 'order' => '',
+ 'foreignKey' => 'user_id'
+ ),
+ 'File' =>
+ array('className' => 'File',
+ 'conditions' => '',
+ 'order' => '',
+ 'foreignKey' => 'file_id'
+ )
+ );
+}
+?>
diff --git a/site/app/models/appversion.php b/site/app/models/appversion.php
new file mode 100644
index 0000000..c80fa64
--- /dev/null
+++ b/site/app/models/appversion.php
@@ -0,0 +1,80 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Andrei Hajdukewycz <sancus@off.net> (Original Author)
+ * Justin Scott <fligtar@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+class Appversion extends AppModel
+{
+ var $name = 'Appversion';
+ var $belongsTo = 'Application';
+
+ /**
+ * Retrieves all appversions for all applications
+ */
+ function getAllVersions() {
+ $_versionlist = $this->findAll(null, null, null, null, null, -1);
+
+ $versions = array();
+
+ if (!empty($_versionlist)) {
+ foreach ($_versionlist as $version) {
+ $versions[$version['Appversion']['application_id']][$version['Appversion']['id']] = $version['Appversion']['version'];
+ }
+ }
+
+ return $versions;
+ }
+
+ /**
+ * Retrieves all appversions that start with the passed version.
+ * For example, passing 3.1 would return 3.1a1pre, 3.1a1, 3.1b1, 3.1.*
+ */
+ function getRelatedVersions($version) {
+ $_versionlist = $this->findAll("Appversion.version LIKE '{$version}%'", null, null, null, null, -1);
+
+ $versions = array();
+
+ if (!empty($_versionlist)) {
+ foreach ($_versionlist as $version) {
+ $versions[$version['Appversion']['application_id']][$version['Appversion']['id']] = $version['Appversion']['version'];
+ }
+ }
+
+ return $versions;
+ }
+}
+?>
diff --git a/site/app/models/blapp.php b/site/app/models/blapp.php
new file mode 100644
index 0000000..059fd94
--- /dev/null
+++ b/site/app/models/blapp.php
@@ -0,0 +1,44 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Andrei Hajdukewycz <sancus@off.net> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+class Blapp extends AppModel
+{
+ var $name = 'Blapp';
+ var $belongsTo = 'Blitem';
+}
+?>
diff --git a/site/app/models/blitem.php b/site/app/models/blitem.php
new file mode 100644
index 0000000..02a00d4
--- /dev/null
+++ b/site/app/models/blitem.php
@@ -0,0 +1,54 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Andrei Hajdukewycz <sancus@off.net> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+class Blitem extends AppModel
+{
+ var $name = 'Blitem';
+ var $hasMany = array('Blapp' =>
+ array('className' => 'Blapp',
+ 'conditions' => '',
+ 'order' => '',
+ 'limit' => '',
+ 'foreignKey' => 'blitem_id',
+ 'dependent' => true,
+ 'exclusive' => false,
+ 'finderSql' => ''
+ )
+ );
+}
+?>
diff --git a/site/app/models/blplugin.php b/site/app/models/blplugin.php
new file mode 100644
index 0000000..864d30e
--- /dev/null
+++ b/site/app/models/blplugin.php
@@ -0,0 +1,43 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Michael Morgan <morgamic@mozilla.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+class Blplugin extends AppModel
+{
+ var $name = 'Blplugin';
+}
+?>
diff --git a/site/app/models/cake_session.php b/site/app/models/cake_session.php
new file mode 100644
index 0000000..13a81db
--- /dev/null
+++ b/site/app/models/cake_session.php
@@ -0,0 +1,45 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Andrei Hajdukewycz <sancus@off.net> (Original Author)
+ * Justin Scott <fligtar@gmail.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+class Cake_Session extends AppModel
+{
+ var $name = 'Cake_Session';
+ var $useTable = 'cake_sessions';
+}
+?>
diff --git a/site/app/models/cannedresponse.php b/site/app/models/cannedresponse.php
new file mode 100644
index 0000000..ceeefa5
--- /dev/null
+++ b/site/app/models/cannedresponse.php
@@ -0,0 +1,47 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * Justin Scott <fligtar@gmail.com>.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+class Cannedresponse extends AppModel
+{
+ var $name = 'Cannedresponse';
+
+ var $translated_fields = array(
+ 'name',
+ 'response'
+ );
+}
+?>
diff --git a/site/app/models/collection.php b/site/app/models/collection.php
new file mode 100644
index 0000000..59e0d13
--- /dev/null
+++ b/site/app/models/collection.php
@@ -0,0 +1,630 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Ryan Doherty <rdoherty@mozilla.com>
+ * l.m.orchard <lorchard@mozilla.com>
+ * Frederic Wenzel <fwenzel@mozilla.com>
+ * Wil Clouser <wclouser@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+class Collection extends AppModel
+{
+ var $name = "Collection";
+
+ var $hasAndBelongsToMany = array(
+ 'Addon' => array(
+ 'className' => 'Addon',
+ 'joinTable' => 'addons_collections',
+ 'foreignKey' => 'collection_id',
+ 'associationForeignKey' => 'addon_id'
+ ),
+ 'Subscriptions' => array(
+ 'className' => 'User',
+ 'joinTable' => 'collection_subscriptions',
+ 'foreignKey' => 'collection_id',
+ 'associationForeignKey' => 'user_id'
+ ),
+ 'Users' => array(
+ 'className' => 'User',
+ 'joinTable' => 'collections_users',
+ 'foreignKey' => 'collection_id',
+ 'associationForeignKey' => 'user_id'
+ )
+ );
+
+ var $hasAndBelongsToMany_full = array(
+ 'Tag' => array(
+ 'className' => 'Tag',
+ 'joinTable' => 'collections_tags',
+ 'foreignKey' => 'collection_id',
+ 'associationForeignKey'=> 'tag_id'
+ ),
+ 'Addon' => array(
+ 'className' => 'Addon',
+ 'joinTable' => 'addons_collections',
+ 'foreignKey' => 'collection_id',
+ 'associationForeignKey' => 'addon_id'
+ ),
+ 'Subscriptions' => array(
+ 'className' => 'User',
+ 'joinTable' => 'collection_subscriptions',
+ 'foreignKey' => 'collection_id',
+ 'associationForeignKey' => 'user_id'
+ ),
+ 'Users' => array(
+ 'className' => 'User',
+ 'joinTable' => 'collections_users',
+ 'foreignKey' => 'collection_id',
+ 'associationForeignKey' => 'user_id'
+ )
+ );
+
+ var $hasMany_full = array(
+ 'Promo' =>
+ array('className' => 'CollectionPromo',
+ 'conditions' => '',
+ 'order' => '',
+ 'limit' => '',
+ 'foreignKey' => 'collection_id',
+ 'dependent' => true,
+ 'exclusive' => false,
+ 'finderSql' => ''
+ )
+ );
+
+
+ var $validate = array(
+ 'name' => VALID_NOT_EMPTY,
+ 'description' => VALID_NOT_EMPTY
+ );
+
+ var $translated_fields = array(
+ 'name',
+ 'description',
+ );
+
+ /**
+ * validate name field
+ */
+ function clean_name($input) {
+ $msg = sprintf(___('collection_name_limit'), Collection::MAX_NAME_LENGTH);
+ $this->maxLength('name', $input, Collection::MAX_NAME_LENGTH, $msg);
+ }
+
+ /**
+ * validate description field
+ */
+ function clean_description($input) {
+ $msg = sprintf(___('collection_description_limit'), Collection::MAX_DESC_LENGTH);
+ $this->maxLength('description', $input, Collection::MAX_DESC_LENGTH, $msg);
+ }
+
+ /**
+ * validate nickname field
+ */
+ function clean_nickname($input) {
+ if (preg_match(INVALID_COLLECTION_NICKNAME_CHARS, $input)
+ || $this->isNicknameTaken($input)) {
+ $this->invalidate('nickname');
+ }
+ }
+
+ const COLLECTION_TYPE_NORMAL = 0;
+ const COLLECTION_TYPE_AUTOPUBLISHER = 1;
+ const COLLECTION_TYPE_EDITORSPICK = 2;
+
+ const MAX_NAME_LENGTH = 50;
+ const MAX_DESC_LENGTH = 200;
+
+ /**
+ * Generates a pseudo-random UUID.
+ * Slightly modified version of a function submitted to php.net:
+ * http://us2.php.net/manual/en/function.com-create-guid.php#52354
+ *
+ * @access public
+ */
+ function uuid() {
+ mt_srand((double)microtime()*10000);
+ $charid = md5(uniqid(rand(), true));
+ $hyphen = chr(45);// "-"
+ $uuid = substr($charid, 0, 8).$hyphen
+ . substr($charid, 8, 4).$hyphen
+ . substr($charid,12, 4).$hyphen
+ . substr($charid,16, 4).$hyphen
+ . substr($charid,20,12);
+
+ return $uuid;
+ }
+
+ /**
+ * Verifies a UUID's structure (not that it actually exists in our database).
+ *
+ * @param string uuid
+ * @return boolean
+ */
+ function isValidUUID($uuid) {
+ if (preg_match(VALID_UUID_REQ, $uuid) > 0) {
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Before saving, set a UUID if none yet set.
+ */
+ function beforeSave() {
+ if (empty($this->id) && empty($this->data[$this->name]['id'])) {
+ // If no ID set yet, assume this is a new record and give it a UUID
+ $this->data[$this->name]['uuid'] = $this->uuid();
+ }
+
+ // if nickname is set, make sure it's unique
+ if (!empty($this->data[$this->name]['nickname'])) {
+ if ($this->isNicknameTaken($this->data[$this->name]['nickname'])) {
+ $this->invalidate('nickname');
+ return false;
+ }
+ } else {
+ $this->data[$this->name]['nickname'] = null;
+ }
+
+ return parent::beforeSave();
+ }
+
+ /**
+ * Subscribes a user to a collection
+ *
+ * @param int $id - the id of the collection
+ * @param int $userId - the id of the user
+ * @return bool success
+ */
+ function subscribe($id, $userId) {
+ // Perform SQL escaping.
+ $db =& ConnectionManager::getDataSource($this->useDbConfig);
+ $e_id = $db->value($id);
+ $e_userId = $db->value($userId);
+
+ $this->execute("
+ INSERT IGNORE INTO collection_subscriptions
+ (collection_id, user_id, created, modified)
+ VALUES
+ ({$e_id}, {$e_userId}, NOW(), NOW())
+ ");
+ return ($this->getAffectedRows() > 0);
+ }
+
+ /**
+ * Unsubscribe a user to a collection
+ *
+ * @param int $id - id of the collection
+ * @param int $userId - id of user
+ * @return bool success
+ */
+ function unsubscribe($id, $userId) {
+ // Perform SQL escaping.
+ $db =& ConnectionManager::getDataSource($this->useDbConfig);
+ $e_id = $db->value($id);
+ $e_userId = $db->value($userId);
+
+ $this->execute("
+ DELETE FROM collection_subscriptions
+ WHERE
+ user_id = {$e_userId} AND
+ collection_id = {$e_id}
+ ");
+ return ($this->getAffectedRows() > 0);
+ }
+
+ /**
+ * Update the subscribers count for a collection.
+ *
+ * @param int $id - id of the collection
+ */
+ function _updateSubscribersCount($e_id) {
+ return $this->execute("
+ UPDATE collections
+ SET subscribers=(
+ SELECT count(collection_id)
+ FROM collection_subscriptions
+ WHERE collection_id={$e_id}
+ )
+ WHERE id={$e_id}
+ ");
+ }
+
+ /**
+ * Add an add-on to a collection
+ *
+ * @param int $collectionId - collection id
+ * @param int $addonId - add-on id
+ */
+ function addAddonToCollection($collection_id, $user_id, $addon_id) {
+ $db =& ConnectionManager::getDataSource($this->useDbConfig);
+
+ $collection_id = $db->value($collection_id);
+ $user_id = $db->value($user_id);
+ $addon_id = $db->value($addon_id);
+
+ $ret = $this->execute("
+ INSERT INTO addons_collections
+ (addon_id, user_id, collection_id, added)
+ VALUES
+ ({$addon_id}, {$user_id}, {$collection_id}, NOW())
+ ");
+ return $ret;
+ }
+
+ /* Update the addon count for collection $id. */
+ function _updateAddonCount($id) {
+ return $this->execute("
+ UPDATE collections
+ SET addonCount=(SELECT COUNT(*)
+ FROM addons_collections
+ WHERE collection_id={$id})
+ WHERE id=${id}");
+ }
+
+ /**
+ * Adds a user to a collection so they can edit it
+ *
+ * @param int $collectionId - id of the collection
+ * @param int $userId - id of the user
+ * @param int $role - role type
+ */
+ function addUser($collectionId, $userId, $role) {
+ $db =& ConnectionManager::getDataSource($this->useDbConfig);
+
+ $collectionId = $db->value($collectionId);
+ $userId = $db->value($userId);
+ $role = $db->value($role);
+
+ return $this->execute("INSERT INTO collections_users (collection_id, user_id, role) VALUES ({$collectionId}, {$userId}, {$role})");
+ }
+
+ /**
+ * Remove a user
+ *
+ * @param int $collectionId - id of the collection
+ * @param int $userId - id of the user
+ */
+ function removeUser($collectionId, $userId) {
+ $db =& ConnectionManager::getDataSource($this->useDbConfig);
+
+ $collectionId = $db->value($collectionId);
+ $userId = $db->value($userId);
+
+ return $this->execute("DELETE FROM collections_users WHERE user_id = {$userId} AND collection_id={$collectionId}");
+ }
+
+ /**
+ * Remove all user rights from a collection, by role
+ * Warning: do not do this with OWNER unless you know what you are doing.
+ *
+ * @param int $collection_id
+ * @param int $role user role to remove, for example COLLECTION_ROLE_ADMIN
+ */
+ function removeAllUsersByRole($collection_id, $role) {
+ return $this->execute("DELETE FROM collections_users WHERE collection_id={$collection_id} AND role={$role};");
+ }
+
+ /**
+ * Deletes a collection
+ *
+ * @param int $id - collection id
+ */
+ function delete($id) {
+ $this->execute("DELETE FROM collections_users WHERE collection_id = {$id}");
+ $this->execute("DELETE FROM addons_collections WHERE collection_id = {$id}");
+ $this->execute("DELETE FROM collections_tags WHERE collection_id = {$id}");
+ $this->execute("DELETE FROM collection_subscriptions WHERE collection_id = {$id}");
+ $this->execute("DELETE FROM collection_promos WHERE collection_id = {$id}");
+ $this->execute("DELETE FROM collections WHERE id = {$id}");
+ return true;
+ }
+
+ /**
+ * returns the ids of all collections owned or managed by a given user
+ * @param int $userid
+ * @param mixed $roles (optional) array of allowed roles, defaults to "any role"
+ * @return array collection ids, false on error
+ */
+ function getCollectionsByUser($userid, $roles = null) {
+ if (!is_numeric($userid)) return false;
+
+ $role_sql = '';
+ if (!empty($role)) {
+ if (is_scalar($roles)) $roles = array($roles);
+ foreach ($roles as &$role) if (!is_numeric($role)) return false;
+ $role_sql = ' AND role IN ('.implode(',', $roles).')';
+ }
+
+ $res = $this->query("SELECT collection_id FROM collections_users WHERE user_id = {$userid}{$role_sql}");
+ if (empty($res)) return array();
+
+ $ids = array();
+ foreach ($res as &$row) $ids[] = $row['collections_users']['collection_id'];
+ return $ids;
+ }
+
+ /**
+ * returns the ids of all collections subscribed to by a given user
+ * @param int $userid
+ * @return array collection ids, false on error
+ */
+ function getSubscriptionsByUser($userid) {
+ if (!is_numeric($userid)) return false;
+
+ $res = $this->query("SELECT collection_id FROM collection_subscriptions WHERE user_id = {$userid}");
+ if (empty($res)) return array();
+
+ $ids = array();
+ foreach ($res as &$row) $ids[] = $row['collection_subscriptions']['collection_id'];
+ return $ids;
+ }
+
+ /**
+ * Get a list of users and roles
+ *
+ * @param int id of the collection
+ * @param array (optional) list of roles for which users should be fetched
+ */
+ function getUsers($collectionId, $roles=null) {
+ if (!is_numeric($collectionId)) return null;
+
+ // Build SQL to look up user IDs and roles for collection
+ $sql = "
+ SELECT user_id, role
+ FROM collections_users
+ WHERE collection_id={$collectionId}
+ ";
+
+ // Add an IN clause if roles supplied.
+ if (null !== $roles && is_array($roles)) {
+ $s_roles = array();
+ foreach ($roles as $role) if (is_numeric($role))
+ $s_roles[] = $role;
+ $sql .= " AND role IN ( ". join(',', $s_roles) . " )";
+ }
+
+ // Fetch the rows and map them to user IDs.
+ $rows = $this->execute($sql);
+ $user_map = array();
+ foreach ($rows as $row) {
+ $user_map[$row['collections_users']['user_id']] =
+ $row['collections_users'];
+ }
+
+ // Look up users with user IDs, merge the role info into each found.
+ $users = $this->User->findAllById(array_keys($user_map));
+ for ($i=0; $i<count($users); $i++) {
+ // HACK: CollectionUser used in lieu of an actual model class.
+ $users[$i]['CollectionUser'] =
+ $user_map[$users[$i]['User']['id']];
+ }
+
+ return $users;
+ }
+
+ /**
+ * Decide whether or not a given collection is writable by a user.
+ *
+ * @param int id of the collection
+ * @param int id of the user
+ */
+ function isWritableByUser($collection_id, $user_id) {
+ if (!is_numeric($collection_id)) return null;
+ if (!is_numeric($user_id)) return null;
+
+ $role = $this->getUserRole($collection_id, $user_id);
+ if ($role === false) return false; // no access rights
+ return in_array($role, array(
+ COLLECTION_ROLE_OWNER,
+ COLLECTION_ROLE_ADMIN,
+ COLLECTION_ROLE_PUBLISHER
+ ));
+ }
+
+ /**
+ * Determine a user's role for a collection (admin, owner, subscriber...).
+ *
+ * @param int $collection_id
+ * @param int $user_id
+ * @return role ID, false if none
+ */
+ function getUserRole($collection_id, $user_id) {
+ if (!is_numeric($collection_id)) return null;
+ if (!is_numeric($user_id)) return null;
+
+ $rows = $this->execute("
+ SELECT role
+ FROM collections_users
+ WHERE
+ collection_id={$collection_id} AND
+ user_id={$user_id}
+ ");
+ if (empty($rows)) return false;
+ return (int)$rows[0]['collections_users']['role'];
+ }
+
+ /**
+ * Look up the ID for a collection by UUID, less expensive than a full
+ * fetch.
+ *
+ * @param string Collection UUID
+ * @return string Collection ID
+ */
+ function getIdForUuid($uuid) {
+ $db =& ConnectionManager::getDataSource($this->useDbConfig);
+ $uuid = $db->value($uuid);
+ $rows = $this->execute("
+ SELECT id
+ FROM collections
+ WHERE uuid={$uuid}
+ ");
+ $id = null;
+ if (!empty($rows[0])) {
+ $id = $rows[0]['Collection']['id'];
+ }
+ return $id;
+ }
+
+ /**
+ * Look up ID for a UUID or nickname.
+ *
+ * @param string UUID or nickname
+ * @return int collection ID
+ */
+ function getIdForUuidOrNickname($uuid_or_nickname) {
+ $id = null;
+ if (strlen($uuid_or_nickname) == 36) { // possibly a UUID
+ $id = $this->getIdForUuid($uuid_or_nickname);
+ }
+ if (is_null($id)) { // try nickname
+ $db =& ConnectionManager::getDataSource($this->useDbConfig);
+ $uuid_or_nickname = $db->value($uuid_or_nickname);
+ $rows = $this->execute("
+ SELECT id
+ FROM collections
+ WHERE nickname={$uuid_or_nickname}
+ ");
+ if (!empty($rows[0])) {
+ $id = $rows[0]['Collection']['id'];
+ }
+ }
+ return $id;
+ }
+
+ /**
+ * Determine the last modified time for a collection, found either by
+ * ID or UUID. If a UUID is supplied, it's converted to an ID via
+ * query first.
+ *
+ * @param string Collection ID
+ * @param string Collection UUID, replaces ID if supplied
+ * @return string Last modified date for collection and addons
+ */
+ function getLastModifiedForCollection($id=null, $uuid=null) {
+ $db =& ConnectionManager::getDataSource($this->useDbConfig);
+
+ if (null !== $uuid) {
+ $id = $this->getIdForUUID($uuid);
+ }
+
+ $id = $db->value($id);
+
+ $dates = array();
+
+ $rows = $this->execute("
+ SELECT added, modified
+ FROM addons_collections
+ WHERE collection_id={$id}
+ ORDER BY added DESC
+ LIMIT 1
+ ");
+ foreach ($rows as $row) {
+ $dates[] = $row['addons_collections']['added'];
+ $dates[] = $row['addons_collections']['modified'];
+ }
+
+ $rows = $this->execute("
+ SELECT modified
+ FROM collections
+ WHERE id={$id}
+ ");
+ foreach ($rows as $row) {
+ $dates[] = $row['Collection']['modified'];
+ }
+
+ if (empty($dates)) return null;
+ rsort($dates);
+ return strtotime($dates[0]);
+ }
+
+ /**
+ * is collection nickname taken yet?
+ * @param string $nickname proposed nickname
+ * @return bool true if nickname is occupied already, false otherwise
+ */
+ function isNicknameTaken($nickname) {
+ $db =& ConnectionManager::getDataSource($this->useDbConfig);
+ $nickname = $db->value($nickname);
+ $res = $this->query("SELECT id FROM collections WHERE nickname = {$nickname}");
+ if (empty($res)) return false;
+ if (empty($this->id))
+ return (!empty($res));
+ else
+ return ($this->id != $res[0]['collections']['id']);
+ }
+
+ function isSubscribed($collection_id, $user_id) {
+ $res = $this->execute("SELECT user_id FROM collection_subscriptions
+ WHERE user_id={$user_id}
+ AND collection_id={$collection_id}");
+ return !empty($res);
+ }
+
+ function getNickname($collection) {
+ $c = $collection['Collection'];
+ return isset($c['nickname']) ? $c['nickname'] : $c['uuid'];
+ }
+
+ function getDetailUrl($collection) {
+ return '/collection/' . $this->getNickname($collection);
+ }
+
+ function getSubscribeUrl($ajax=false) {
+ return '/collections/subscribe/' . ($ajax === true ? 'ajax' : '');
+ }
+
+ function getUnsubscribeUrl($ajax=false) {
+ return '/collections/unsubscribe/' . ($ajax === true ? 'ajax' : '');
+ }
+
+ /**
+ * Get editor's picks for the current application.
+ *
+ * @param limit the number you want
+ * @return array of collections
+ */
+ function getEditorPicks($limit=null) {
+ $conditions = array(
+ 'Collection.collection_type' => Collection::COLLECTION_TYPE_EDITORSPICK,
+ 'Collection.application_id' => APP_ID
+ );
+ $this->unbindFully();
+ $collections = $this->findAll($conditions,null,'Collection.downloads DESC',$limit);
+ return $collections;
+ }
+}
diff --git a/site/app/models/collection_promo.php b/site/app/models/collection_promo.php
new file mode 100644
index 0000000..5c88cce
--- /dev/null
+++ b/site/app/models/collection_promo.php
@@ -0,0 +1,140 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Wil Clouser <wclouser@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+class CollectionPromo extends AppModel
+{
+ var $name = "CollectionPromo";
+ var $useTable = 'collection_promos';
+ var $belongsTo = array('Collection');
+ var $recursive = 1;
+ var $translated_fields = array();
+
+ var $titles_and_taglines = array();
+
+ function __construct() {
+ // Order is used in the database so it must be maintained. Append new entries to the end.
+ $this->titles_and_taglines = array(
+ 0 => array('title' => ___('collections_social_title'), 'tagline' => ___('collections_social_tagline')),
+ 1 => array('title' => ___('collections_family_title'), 'tagline' => ___('collections_family_tagline')),
+ 2 => array('title' => ___('collections_travel_title'), 'tagline' => ___('collections_travel_tagline')),
+ 3 => array('title' => ___('collections_reference_title'), 'tagline' => ___('collections_reference_tagline')),
+ 4 => array('title' => ___('collections_webdev_title'), 'tagline' => ___('collections_webdev_tagline'))
+ );
+
+ return parent::__construct();
+ }
+
+ /**
+ * Will return an array of all promoted collections in the format:
+ *
+ * [locale] =>
+ * [title_tagline_id] =>
+ * [collection_id] =>
+ * [name] => [collection_name]
+ * [application_id] => [application_id]
+ * [collection_id] => [collection_name]
+ * [name] => [collection_name]
+ * [application_id] => [application_id]
+ * ...
+ *
+ * @return array of results
+ */
+ function findAll() {
+ $_query = "
+ SELECT
+ collection_promos.id as promo_id,
+ collection_promos.locale as promo_locale,
+ collection_promos.title_tagline as promo_title_tagline,
+ collections.id as collection_id,
+ collections.application_id as application_id,
+ c_name.localized_string as collection_name
+ FROM collections RIGHT JOIN collection_promos ON collections.id = collection_promos.collection_id
+ LEFT JOIN translations as `c_name` ON collections.name = c_name.id and c_name.locale='en-US'
+ ORDER BY application_id ASC
+ ";
+ $_result = $this->query($_query);
+
+ $_return = array();
+
+ foreach ($_result as $_res) {
+ if (empty($_res['collection_promos']['promo_locale'])) {
+ $_locale = 'all';
+ } else {
+ $_locale = $_res['collection_promos']['promo_locale'];
+ }
+
+ $_return[$_locale][$_res['collection_promos']['promo_title_tagline']][$_res['collections']['collection_id']] = array('name' => $_res['c_name']['collection_name'], 'application_id' => $_res['collections']['application_id']);
+
+ }
+
+ return $_return;
+ }
+
+
+ /**
+ * Promote a collection + tagline + locale in the database.
+ *
+ * @param int collection id
+ * @param int titletagline id
+ * @param string locale to add. An empty locale means all locales.
+ */
+ function promoteCollection($collection_id, $titletagline, $locale) {
+ global $valid_languages;
+ if (!is_numeric($collection_id)) return false;
+ if (!in_array($titletagline, array_keys($this->titles_and_taglines))) return false;
+ if (!(empty($locale) || in_array($locale, array_keys($valid_languages)))) return false;
+
+ return $this->execute("INSERT INTO collection_promos (collection_id, locale, title_tagline, created) VALUES ({$collection_id}, '{$locale}', {$titletagline}, NOW())");
+ }
+
+ /**
+ * Demote a collection + tagline + locale in the database. This only demotes it if it was promoted to begin with. It doesn't actually flag a collection as crappy. ;)
+ *
+ * @param int collection id
+ * @param int titletagline id
+ * @param string locale to add. An empty locale means all locales.
+ */
+ function demoteCollection($collection_id, $titletagline, $locale) {
+ global $valid_languages;
+ if (!is_numeric($collection_id)) return false;
+ if (!in_array($titletagline, array_keys($this->titles_and_taglines))) return false;
+ if (!(empty($locale) || in_array($locale, array_keys($valid_languages)))) return false;
+
+ return $this->execute("DELETE FROM collection_promos WHERE collection_id={$collection_id} AND title_tagline={$titletagline} AND locale='{$locale}' LIMIT 1");
+ }
+}
diff --git a/site/app/models/config.php b/site/app/models/config.php
new file mode 100644
index 0000000..fd9687d
--- /dev/null
+++ b/site/app/models/config.php
@@ -0,0 +1,88 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * Justin Scott <fligtar@gmail.com>.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+class Config extends AppModel
+{
+ var $name = 'Config';
+ var $useTable = 'config';
+ var $primaryKey = 'key';
+
+ var $config = array();
+
+ /**
+ * Retrieve the value of a specific key.
+ * @param string $key the key to retrieve
+ * @return string
+ */
+ function getValue($key) {
+ //If the config has been retrieved already, use it.
+ if (!empty($this->config)) {
+ return array_key_exists($key, $this->config) ? $this->config[$key] : null;
+ }
+ else {
+ $config = $this->getConfig();
+ return array_key_exists($key, $this->config) ? $config[$key] : null;
+ }
+ }
+
+ /**
+ * Pull all config from the database and store it
+ * @return array
+ */
+ function getConfig() {
+ $config = array();
+
+ if ($configQry = $this->findAll()) {
+ foreach ($configQry as $item) {
+ $config[$item['Config']['key']] = $item['Config']['value'];
+ }
+ }
+
+ //Store config for future use
+ $this->config = $config;
+
+ return $config;
+ }
+
+ /**
+ * Clear the cached config values.
+ */
+ function expire() {
+ $this->config = array();
+ }
+}
+?>
diff --git a/site/app/models/dbo/dbo_amo_mysql.php b/site/app/models/dbo/dbo_amo_mysql.php
new file mode 100644
index 0000000..7dc1fef
--- /dev/null
+++ b/site/app/models/dbo/dbo_amo_mysql.php
@@ -0,0 +1,270 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Frederic Wenzel <fwenzel@mozilla.com> (Original Author)
+ * Justin Scott <fligtar@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/**
+ * This datasource completely inherits Cake's MySQL datasource, except
+ * it doesn't filter out our dynamic translations in the __filterResults()
+ * function, like Cake does by default.
+ *
+ * It also provides support for shadow databases not working.
+ */
+
+
+/**
+ * Include Cake's DBO model for MySQL, which we are extending here
+ */
+uses('model'.DS.'dbo'.DS.'dbo_mysql');
+
+class DboAmoMysql extends DboMysql {
+ /**
+ * Let Cake do its filtering, but strip out translations before and
+ * re-add them afterwards.
+ * Note: Because translated fields do not have an associated table name
+ * (they are renamed in the query) Cake stores them as follows:
+ * array( 'Addon' => (addon data),
+ * 0 => (translation data)
+ * )
+ */
+ function __filterResults(&$results, &$model, $filtered = array()) {
+ // if there's no translations, we don't change anything
+ // (also: if there's no results for the queried model, this is
+ // probably a custom query. Don't do anything either)
+ if (empty($results) || !isset($results[0][$model->name]) || !isset($results[0][0]))
+ return parent::__filterResults($results, $model, $filtered);
+
+ // Used to figure out direction of language and/or fallback
+ global $rtl_languages;
+
+ // rename the missing table name to "Translation"
+ foreach ($results as $key => $item) {
+ $results[$key]['Translation'] = $results[$key][0];
+ unset($results[$key][0]);
+ }
+
+ $trans_filtered = in_array('Translation', $filtered); // were Translations handled before?
+
+ // run Cake's filter magic
+ if (!$trans_filtered) $filtered[] = 'Translation'; // make sure Cake doesn't touch our translations
+ $filtering = parent::__filterResults($results, $model, $filtered);
+
+ // if we haven't done this before, format translations uniformly
+ if (!$trans_filtered) {
+ // strip the raw translations from the results array
+ $translations = array();
+ foreach ($results as $_key => $_val) {
+ $translations[$_key] = $results[$_key]['Translation'];
+ unset($results[$_key]['Translation']);
+ }
+ // re-add translations in the desired format.
+ foreach ($results as $_key => $_result) {
+ $_temp = array();
+ foreach ($model->translated_fields as $field) {
+ if (array_key_exists($field, $translations[$_key])) { // only translated fields that were actually selected
+ $_temp[$field]['string'] = $translations[$_key][$field];
+ $_temp[$field]['locale'] = $translations[$_key]["{$field}_locale"];
+ $_temp[$field]['textdir'] = in_array($_temp[$field]['locale'], $rtl_languages) ? 'rtl' : 'ltr';
+ if (empty($_temp[$field]['locale']) || $model->getLang() == $_temp[$field]['locale']) {
+ $_temp[$field]['locale_html'] = '';
+ } else {
+ $_temp[$field]['locale_html'] = ' lang="'.$_temp[$field]['locale'].'" dir="'.$_temp[$field]['textdir'].'" ';
+ }
+ }
+ }
+ $results[$_key]['Translation'] = $_temp;
+ }
+
+ // now add translations to the "filtered models" array we'll return,
+ // so we don't touch them again when we come back.
+ $filtering[] = 'Translation';
+ }
+ return $filtering;
+ }
+
+/**
+ * Attempts to connect to a database. If a connection can't be established
+ * and we were attempting to connect to a shadow database, we'll try the
+ * remaining shadow databases before disabling shadow databases and forcing
+ * queries to use the master.
+ *
+ * @return boolean True if the database could be connected, else false
+ */
+ function connect() {
+ if (parent::connect()) {
+ // Connected to database.
+ return true;
+ }
+ elseif ($this->config['shadow']) {
+ /* Couldn't connect to shadow.
+ We can't redefine the SHADOW constants, so let's just try
+ to find something we *can* connect to, regardless of weight */
+ global $shadow_databases;
+ if (!empty($shadow_databases)) {
+ // Save known bad info
+ $bad = $this->config;
+
+ foreach ($shadow_databases as $shadow_database) {
+ // Make sure this isn't the known-bad one
+ if ($bad['host'] == $shadow_database['DB_HOST'] &&
+ $bad['database'] == $shadow_database['DB_NAME']) {
+ continue;
+ }
+
+ $this->config['host'] = $shadow_database['DB_HOST'].':'.$shadow_database['DB_PORT'];
+ $this->config['login'] = $shadow_database['DB_USER'];
+ $this->config['password'] = $shadow_database['DB_PASS'];
+ $this->config['database'] = $shadow_database['DB_NAME'];
+
+ if (parent::connect()) {
+ // DB worked - let's get out of here!
+ return true;
+ }
+ // else - no luck. try next shadow db
+ }
+ }
+ /* If we're still here, none of the other shadow db's worked.
+ We'll disable queries to the SHADOW db, which means they'll
+ pull from the master unless that's down too */
+ define('SHADOW_DISABLED', true);
+ }
+ // else, we couldn't connect to master db. Umm...run away!
+ // mail('morgamic@gmail.com', 'Hey guess what!!!!');
+
+ return false;
+ }
+
+ /**
+ * Outputs a pretty version of the Cake query log that is hidden by default.
+ */
+ function showLog($sorted = false) {
+ // If using CLI, use normal showLog method for handling
+ if (php_sapi_name() == 'cli') {
+ parent::showLog($sorted);
+ return;
+ }
+
+ // Sort log if requested
+ $logs = $sorted ? sortByKey($this->_queriesLog, 'took', 'desc', SORT_NUMERIC) : $this->_queriesLog;
+
+ // Create unique id for this log
+ $id = 'querylog-'.str_replace(array(' ', '.'), '', microtime());
+
+ // CSS
+ echo '<style type="text/css">';
+ echo "div.querylog { border: 1px solid black; margin: 10px 0; }";
+ echo "table.querylog-summary { width: 100%; }";
+ echo "table.querylog-summary:hover { background-color: #DDDDFF; cursor: pointer; }";
+ echo "#{$id} { width: 100%; border-top: 1px solid black; }";
+ echo "#{$id} tr.alt td { background-color: #EEEEEE; }";
+ echo "#{$id} th, #{$id} td { text-align: left; margin: 0; padding: 2px;}";
+ echo "#{$id} th { font-weight: bold; }";
+ echo '</style>';
+
+ // Summary table
+ echo '<div class="querylog">';
+ echo '<table class="querylog-summary" onclick="var table = document.getElementById(\''.$id.'\'); if (table.style.display == \'none\') { table.style.display = \'\'; } else { table.style.display = \'none\'; }"><tbody><tr>';
+ echo '<td style="font-weight: bold;">Query Log</td>';
+ echo "<td style=\"text-align: center;\">{$this->_queriesCnt} ".($this->_queriesCnt > 1 ? 'queries' : 'query')." took {$this->_queriesTime} ms</td>";
+ echo '<td style="text-align: center;">Query distribution: ';
+ if (!empty($this->_configQueriesCnt)) {
+ foreach ($this->_configQueriesCnt as $config => $count) {
+ echo $config.': '.round(($count / $this->_queriesCnt) * 100, 2).'%';
+ }
+ }
+ echo '</td>';
+ echo '<td style="text-align: right;">Click to Toggle Queries</td>';
+ echo '</tr></tbody></table>';
+
+ // Log table
+ echo '<table id="'.$id.'" style="display: none;"><thead>';
+ echo '<tr>';
+ echo '<th>#</th>';
+ echo '<th>Query</th>';
+ echo '<th>Error</th>';
+ echo '<th>Affected</th>';
+ echo '<th>Num. Rows</th>';
+ echo '<th>Took (ms)</th>';
+ echo '<th>DB config</th>';
+ echo '</tr>';
+ echo '</thead><tbody>';
+
+ foreach ($logs as $k => $log) {
+ echo '<tr'.($k % 2 == 0 ? ' class="alt"' : '').'>';
+ echo '<td>'.($k + 1).'</td>';
+ echo '<td>'.h($log['query']).'</td>';
+ echo "<td>{$log['error']}</td>";
+ echo "<td>{$log['affected']}</td>";
+ echo "<td>{$log['numRows']}</td>";
+ echo "<td>{$log['took']}</td>";
+ echo "<td>{$log['db']}</td>";
+ echo '</tr>';
+ }
+
+ echo '</tbody></table>';
+ echo '</div>';
+ }
+
+ /**
+ * Logs given SQL query.
+ * Modified Cake default to add support for configKeyName
+ */
+ function logQuery($sql) {
+ $this->_queriesCnt++;
+ $this->_queriesTime += $this->took;
+ $this->_queriesLog[] = array(
+ 'query' => $sql,
+ 'error' => $this->error,
+ 'affected' => $this->affected,
+ 'numRows' => $this->numRows,
+ 'took' => $this->took,
+ 'db' => $this->configKeyName
+ );
+
+ if (!empty($this->_configQueriesCnt[$this->configKeyName])) {
+ $this->_configQueriesCnt[$this->configKeyName]++;
+ }
+ else {
+ $this->_configQueriesCnt[$this->configKeyName] = 1;
+ }
+
+ if ($this->error) {
+ return false;
+ }
+ }
+}
+?>
diff --git a/site/app/models/download.php b/site/app/models/download.php
new file mode 100644
index 0000000..1dd90ea
--- /dev/null
+++ b/site/app/models/download.php
@@ -0,0 +1,45 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Andrei Hajdukewycz <sancus@off.net> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+class Download extends AppModel
+{
+ var $name = 'Download';
+ var $belongsTo = 'File';
+ var $useTable = DOWNLOADS_TABLE;
+}
+?>
diff --git a/site/app/models/editor_subscription.php b/site/app/models/editor_subscription.php
new file mode 100644
index 0000000..76dbe2f
--- /dev/null
+++ b/site/app/models/editor_subscription.php
@@ -0,0 +1,94 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * Frederic Wenzel <fwenzel@mozilla.com>
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+class EditorSubscription extends AppModel
+{
+ var $name = 'EditorSubscription';
+ var $useTable = 'editor_subscriptions';
+ var $belongsTo = array('Addon', 'User');
+
+ var $recursive = -1;
+
+ /**
+ * Sign editor up for an email the next time an add-on is updated.
+ * @param int $userid User's ID to be signed up for the next update
+ * @param int $addonid Addon's ID to subscribe the user to
+ * @return void
+ */
+ function subscribeToUpdates($userid, $addonid) {
+ $this->query("
+ INSERT INTO editor_subscriptions
+ SET
+ user_id = '{$userid}',
+ addon_id = '{$addonid}';");
+ }
+
+ /**
+ * Do not notify editor the next time an add-on is updated.
+ * @param int $userid User's ID to be signed up for the next update
+ * @param int $addonid Addon's ID to subscribe the user to
+ * @return void
+ */
+ function cancelUpdates($userid, $addonid) {
+ $this->query("
+ DELETE FROM editor_subscriptions
+ WHERE
+ user_id = '{$userid}' AND
+ addon_id = '{$addonid}';");
+ }
+
+ /**
+ * get list of subscribers for a given add-on
+ * @param int $addonid ID of the add-on whose subscribers are required
+ * @return array user IDs for all subscribers of the add-on
+ */
+ function getSubscribers($addonid) {
+ $_result = $this->query("
+ SELECT user_id
+ FROM editor_subscriptions
+ WHERE addon_id = '{$addonid};'");
+ if (empty($_result)) return array();
+
+ $_ids = array();
+ foreach ($_result as &$_id) {
+ $_ids[] = $_id['editor_subscriptions']['user_id'];
+ }
+
+ return $_ids;
+ }
+}
+?>
diff --git a/site/app/models/eventlog.php b/site/app/models/eventlog.php
new file mode 100644
index 0000000..5d914ed
--- /dev/null
+++ b/site/app/models/eventlog.php
@@ -0,0 +1,63 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * Justin Scott <fligtar@gmail.com>.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+class Eventlog extends AppModel
+{
+ var $name = 'Eventlog';
+ var $useTable = 'eventlog';
+
+
+ function log(&$controller, $type = '', $action = '', $field = '', $changed_id = '', $added = '', $removed = '', $notes = '') {
+ $session = $controller->Session->read('User');
+
+ $auditData = array(
+ 'id' => null,
+ 'type' => $type,
+ 'action' => $action,
+ 'field' => $field,
+ 'user_id' => $session['id'],
+ 'changed_id' => $changed_id,
+ 'added' => $added,
+ 'removed' => $removed,
+ 'notes' => $notes
+ );
+
+ return $this->save($auditData);
+ }
+
+}
+?>
diff --git a/site/app/models/facebook_data.php b/site/app/models/facebook_data.php
new file mode 100644
index 0000000..cf7f7ff
--- /dev/null
+++ b/site/app/models/facebook_data.php
@@ -0,0 +1,118 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Justin Scott <fligtar@mozilla.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+class FacebookData extends AppModel
+{
+ var $name = 'FacebookData';
+ var $tableName = 'facebook_data';
+
+ /**
+ * Updates anonymous usage data
+ */
+ function updateData($action, $fbUser, &$api_client) {
+ $data = $this->getData($fbUser, $api_client);
+
+ $age = $this->getAge($data[0]['birthday']);
+ $ageRange = $this->getAgeRange($age);
+ $sex = $this->getSex($data[0]['sex']);
+
+ if ($sex !== false) {
+ if ($action == 'add')
+ $this->execute("UPDATE {$this->tableName} SET count_current=count_current+1, count_ever=count_ever+1 WHERE trait='sex_{$sex}'");
+ elseif ($action == 'remove')
+ $this->execute("UPDATE {$this->tableName} SET count_current=count_current-1 WHERE trait='sex_{$sex}'");
+ }
+
+ if ($age !== false) {
+ if ($action == 'add')
+ $this->execute("UPDATE {$this->tableName} SET count_current=count_current+1, count_ever=count_ever+1 WHERE trait='age_{$ageRange}'");
+ elseif ($action == 'remove')
+ $this->execute("UPDATE {$this->tableName} SET count_current=count_current-1 WHERE trait='age_{$ageRange}'");
+ }
+ }
+
+ function getData($fbUser, &$api_client) {
+ return $api_client->fql_query("SELECT sex, birthday FROM user WHERE uid='{$fbUser}'");
+ }
+
+ function getAge($birthday) {
+ if (preg_match('/\d{4}/', $birthday, $matches)) {
+ $year = $matches[0];
+
+ return date('Y') - $year;
+ }
+
+ return false;
+ }
+
+ function getAgeRange($age) {
+ if ($age < 12)
+ return 'under12';
+ elseif ($age >= 12 && $age <= 15)
+ return '12to15';
+ elseif ($age >= 16 && $age <= 19)
+ return '16to19';
+ elseif ($age >= 20 && $age <= 23)
+ return '20to23';
+ elseif ($age >= 24 && $age <= 27)
+ return '24to27';
+ elseif ($age >= 28 && $age <= 31)
+ return '28to31';
+ elseif ($age >= 32 && $age <= 35)
+ return '32to35';
+ elseif ($age >= 36 && $age <= 39)
+ return '36to39';
+ elseif ($age >= 40 && $age <= 49)
+ return '40to49';
+ elseif ($age >= 50 && $age <= 59)
+ return '50to59';
+ elseif ($age >= 60)
+ return 'above60';
+ }
+
+ function getSex($sex) {
+ if ($sex == 'male')
+ return 'male';
+ elseif ($sex == 'female')
+ return 'female';
+ else
+ return false;
+ }
+
+}
+?>
diff --git a/site/app/models/facebook_detected.php b/site/app/models/facebook_detected.php
new file mode 100644
index 0000000..ff9549c
--- /dev/null
+++ b/site/app/models/facebook_detected.php
@@ -0,0 +1,65 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Justin Scott <fligtar@mozilla.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+class FacebookDetected extends AppModel
+{
+ var $name = 'FacebookDetected';
+ var $tableName = 'facebook_detected';
+
+ /**
+ * Updates anonymous usage data
+ */
+ function getDetectedAddons($fbUser) {
+ return $this->query("
+ SELECT
+ addons.id,
+ translations.localized_string,
+ facebook_detected.disabled
+ FROM facebook_detected
+ INNER JOIN addons ON addons.guid=facebook_detected.addon_guid
+ INNER JOIN translations ON addons.name=translations.id
+ WHERE
+ translations.locale = 'en-US' AND
+ facebook_detected.fb_user = '{$fbUser}'
+ ORDER BY
+ translations.localized_string
+ ");
+ }
+
+}
+?>
diff --git a/site/app/models/facebook_favorite.php b/site/app/models/facebook_favorite.php
new file mode 100644
index 0000000..eca777c
--- /dev/null
+++ b/site/app/models/facebook_favorite.php
@@ -0,0 +1,200 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Justin Scott <fligtar@mozilla.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+class FacebookFavorite extends AppModel
+{
+ var $name = 'FacebookFavorite';
+ var $tableName = 'facebook_favorites';
+
+ var $belongsTo = array('Addon' =>
+ array('className' => 'Addon',
+ 'conditions' => '',
+ 'order' => '',
+ 'limit' => '',
+ 'foreignKey' => 'addon_id',
+ 'dependent' => true,
+ 'exclusive' => false,
+ 'finderSql' => ''
+ )
+ );
+
+ var $userFavorites = array();
+
+ /**
+ * Checks if the add-on is a favorite of the user.
+ * Can optionally pull from cached list of favorites
+ */
+ function isFavorite($fbUser, $addon_id, $cache = false) {
+ if ($cache) {
+ if (empty($this->userFavorites)) {
+ $this->getFavoriteIds($fbUser, true);
+ }
+
+ return in_array($addon_id, $this->userFavorites);
+ }
+ else {
+ return $this->query("SELECT id FROM facebook_favorites WHERE addon_id='{$addon_id}' AND fb_user='{$fbUser}'");
+ }
+ }
+
+ /**
+ * Adds add-on as a favorite for the user
+ */
+ function addFavorite($fbUser, $addon_id, $imported = false) {
+ $isImported = ($imported == true) ? 1 : 0;
+ return $this->execute("INSERT INTO facebook_favorites (fb_user, addon_id, imported, created) VALUES('{$fbUser}', '{$addon_id}', {$isImported}, NOW())");
+ }
+
+ /**
+ * Removes add-on as a favorite for the user
+ */
+ function removeFavorite($fbUser, $addon_id) {
+ return $this->execute("DELETE FROM facebook_favorites WHERE addon_id='{$addon_id}' AND fb_user='{$fbUser}'");
+ }
+
+ /**
+ * Gets add-on ids of favorite add-ons for the user
+ */
+ function getFavoriteIds($fbUser, $cache = false) {
+ // If caching, check to see if already cached
+ if ($cache && !empty($this->userFavorites)) {
+ return $this->userFavorites;
+ }
+
+ $favorites = array();
+ if ($addons = $this->query("SELECT addon_id FROM facebook_favorites WHERE fb_user='{$fbUser}'")) {
+ foreach ($addons as $addon) {
+ $favorites[] = $addon['facebook_favorites']['addon_id'];
+ }
+ }
+
+ // If caching, save
+ if ($cache) {
+ $this->userFavorites = $favorites;
+ }
+
+ return $favorites;
+ }
+
+ function getFavoriteList($fbUser, $order = 'translations.localized_string') {
+ return $this->query("SELECT
+ addons.id,
+ addons.icontype,
+ addons.modified,
+ facebook_favorites.imported,
+ translations.localized_string AS name
+ FROM facebook_favorites
+ INNER JOIN addons ON addons.id=facebook_favorites.addon_id
+ INNER JOIN translations ON addons.name=translations.id
+ WHERE
+ fb_user='{$fbUser}' AND
+ translations.locale='en-US'
+ ORDER BY {$order}");
+ }
+
+ function getDetailedFavoriteList($fbUser, $page = 0, $order = 'translations_name.localized_string') {
+ if (!empty($page)) {
+ $start = ($page - 1) * RESULTS_PER_PAGE;
+ $limit = "LIMIT {$start}, ".RESULTS_PER_PAGE;
+ }
+ else
+ $limit = '';
+
+ return $this->query("SELECT
+ addons.id,
+ addons.icontype,
+ translations_name.localized_string AS name,
+ translations_summary.localized_string AS summary,
+ (SELECT COUNT(*) FROM previews WHERE previews.addon_id=addons.id) AS pcount
+ FROM facebook_favorites
+ INNER JOIN addons ON addons.id=facebook_favorites.addon_id
+ INNER JOIN translations AS translations_name ON addons.name=translations_name.id
+ INNER JOIN translations AS translations_summary ON addons.summary=translations_summary.id
+ WHERE
+ fb_user='{$fbUser}' AND
+ translations_name.locale='en-US' AND
+ translations_summary.locale='en-US'
+ ORDER BY {$order}
+ {$limit}
+ ", true);
+ }
+
+ function countFavorites($fbUser) {
+ $addons = $this->query("SELECT COUNT(*) AS num FROM facebook_favorites WHERE fb_user='{$fbUser}'");
+ return $addons[0][0]['num'];
+ }
+
+ function getFriendFavorites($friends, $page = 0) {
+ if (!empty($page)) {
+ $start = ($page - 1) * RESULTS_PER_PAGE;
+ $limit = "LIMIT {$start}, ".RESULTS_PER_PAGE;
+ }
+ else
+ $limit = '';
+
+ return $this->query("SELECT
+ addons.id,
+ COUNT(*) AS fcount,
+ translations_name.localized_string AS name,
+ translations_summary.localized_string AS summary,
+ GROUP_CONCAT(facebook_favorites.fb_user) AS friends,
+ (SELECT COUNT(*) FROM previews WHERE previews.addon_id=addons.id) AS pcount
+ FROM facebook_favorites
+ INNER JOIN addons ON addons.id=facebook_favorites.addon_id
+ INNER JOIN translations AS translations_name ON addons.name=translations_name.id
+ INNER JOIN translations AS translations_summary ON addons.summary=translations_summary.id
+ WHERE
+ translations_name.locale='en-US' AND
+ translations_summary.locale='en-US' AND
+ facebook_favorites.fb_user IN ({$friends})
+ GROUP BY
+ addons.id
+ ORDER BY
+ fcount DESC,
+ addons.totaldownloads DESC
+ {$limit}
+ ", true);
+ }
+
+ function countFriendFavorites($friends) {
+ $addons = $this->query("SELECT COUNT(*) AS num FROM facebook_favorites WHERE fb_user IN ({$friends}) GROUP BY addon_id", true);
+ return count($addons);
+ }
+
+}
+?>
diff --git a/site/app/models/facebook_session.php b/site/app/models/facebook_session.php
new file mode 100644
index 0000000..23c2ba9
--- /dev/null
+++ b/site/app/models/facebook_session.php
@@ -0,0 +1,65 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Justin Scott <fligtar@mozilla.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+class FacebookSession extends AppModel
+{
+ var $name = 'FacebookSession';
+ var $tableName = 'facebook_sessions';
+
+ /**
+ * Generates a random key and inserts it into the db
+ */
+ function generateKey($fbUser) {
+ $key = md5($fbUser).rand(1, 999999);
+
+ $this->execute("INSERT INTO facebook_sessions (session_key, fb_user, created) VALUES('{$key}', '{$fbUser}', NOW())");
+
+ return $key;
+ }
+
+ /**
+ * Retrieves the fb user id based on the session key
+ */
+ function retrieveUser($key) {
+ $record = $this->query("SELECT fb_user FROM facebook_sessions WHERE session_key = '{$key}' LIMIT 1");
+
+ return $record[0]['facebook_sessions']['fb_user'];
+ }
+
+}
+?>
diff --git a/site/app/models/facebook_user.php b/site/app/models/facebook_user.php
new file mode 100644
index 0000000..1620ad4
--- /dev/null
+++ b/site/app/models/facebook_user.php
@@ -0,0 +1,114 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Justin Scott <fligtar@mozilla.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+class FacebookUser extends AppModel
+{
+ var $name = 'FacebookUser';
+ var $tableName = 'facebook_users';
+
+ /**
+ * Check if user is in db
+ */
+ function exists($fbUser) {
+ if ($this->query("SELECT * FROM {$this->tableName} WHERE fb_user='{$fbUser}'"))
+ return true;
+ else
+ return false;
+ }
+
+ /**
+ * Update timestamp of when user added the app
+ */
+ function add($fbUser) {
+ if ($this->exists($fbUser)) {
+ $this->execute("UPDATE {$this->tableName} SET added=NOW(), lastactivity=NOW() WHERE fb_user='{$fbUser}'");
+ }
+ else {
+ $this->execute("INSERT INTO {$this->tableName} (fb_user, added, lastactivity) VALUES('{$fbUser}', NOW(), NOW())");
+ }
+ }
+
+ /**
+ * Update timestamp of when user removed the app
+ */
+ function remove($fbUser) {
+ if ($this->exists($fbUser)) {
+ $this->execute("UPDATE {$this->tableName} SET removed=NOW() WHERE fb_user='{$fbUser}'");
+ }
+ else {
+ $this->execute("INSERT INTO {$this->tableName} (fb_user, removed) VALUES('{$fbUser}', NOW())");
+ }
+ }
+
+ /**
+ * Update last activity
+ */
+ function updateActivity($fbUser) {
+ return $this->execute("UPDATE {$this->tableName} SET lastactivity=NOW() WHERE fb_user='{$fbUser}'");
+ }
+
+ /**
+ * Count of users within a certain interval
+ */
+ function getUsersInInterval($field, $interval) {
+ $result = $this->query("SELECT COUNT(*) AS users FROM {$this->tableName} WHERE {$field} >= DATE_SUB(NOW(), INTERVAL {$interval})");
+
+ return $result[0][0]['users'];
+ }
+
+ /**
+ * Count of users that currently have the app added
+ */
+ function getUsersTotal() {
+ $result = $this->query("SELECT COUNT(*) AS users FROM {$this->tableName} WHERE removed = '0000-00-00 00:00:00'", true);
+
+ return $result[0][0]['users'];
+ }
+
+ /**
+ * Count of users that have ever used the app
+ */
+ function getUsersEver() {
+ $result = $this->query("SELECT COUNT(*) AS users FROM {$this->tableName}", true);
+
+ return $result[0][0]['users'];
+ }
+
+
+}
+?>
diff --git a/site/app/models/favorite.php b/site/app/models/favorite.php
new file mode 100644
index 0000000..35c1ff5
--- /dev/null
+++ b/site/app/models/favorite.php
@@ -0,0 +1,43 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * Justin Scott <fligtar@gmail.com>
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+class Favorite extends AppModel
+{
+ var $name = 'Favorite';
+ var $belongsTo = array('Addon', 'User');
+}
+?>
diff --git a/site/app/models/feature.php b/site/app/models/feature.php
new file mode 100644
index 0000000..80bcbe2
--- /dev/null
+++ b/site/app/models/feature.php
@@ -0,0 +1,45 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Andrei Hajdukewycz <sancus@off.net> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+class Feature extends AppModel
+{
+ var $name = 'Feature';
+ var $belongsTo = 'Addon';
+
+}
+?>
diff --git a/site/app/models/file.php b/site/app/models/file.php
new file mode 100644
index 0000000..53a23b5
--- /dev/null
+++ b/site/app/models/file.php
@@ -0,0 +1,113 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Andrei Hajdukewycz <sancus@off.net> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+class File extends AppModel
+{
+ var $name = 'File';
+ var $belongsTo = array('Version' =>
+ array('className' => 'Version',
+ 'conditions' => '',
+ 'order' => '',
+ 'foreignKey' => 'version_id'
+ ),
+ 'Platform' =>
+ array('className' => 'Platform',
+ 'conditions' => '',
+ 'order' => '',
+ 'foreignKey' => 'platform_id'
+ )
+ );
+ var $hasMany_full = array('Download' =>
+ array('className' => 'Download',
+ 'conditions' => '',
+ 'order' => '',
+ 'limit' => '',
+ 'foreignKey' => 'file_id',
+ 'dependent' => true,
+ 'exclusive' => false,
+ 'finderSql' => ''
+ )
+ );
+ var $hasMany = array('Approval' =>
+ array('className' => 'Approval',
+ 'conditions' => '',
+ 'order' => '',
+ 'limit' => '',
+ 'foreignKey' => 'file_id',
+ 'dependent' => true,
+ 'exclusive' => false,
+ 'finderSql' => ''
+ )
+ );
+
+ /**
+ * Returns the latest public file of the add-on with the specified platform
+ * @param int $addon_id the add-on id
+ * @param int $platform_id optional platform id
+ * @return int the file ID
+ */
+ function getLatestFileByAddonId($addon_id, $platform_id = null) {
+ // Platform WHERE if necessary
+ $platform = !empty($platform_id) ? " AND (File.platform_id = ".PLATFORM_ALL." OR File.platform_id = {$platform_id})" : '';
+
+ $sql = "
+ SELECT
+ File.id
+ FROM
+ files AS File
+ INNER JOIN versions AS Version
+ ON File.version_id = Version.id AND Version.addon_id = {$addon_id}
+ WHERE
+ File.status = ".STATUS_PUBLIC."
+ {$platform}
+ ORDER BY
+ Version.created DESC
+ LIMIT 1
+ ";
+
+ $result = $this->query($sql);
+
+ if (!empty($result[0]['File']['id'])) {
+ return $result[0]['File']['id'];
+ }
+ else {
+ return 0;
+ }
+ }
+}
+?>
diff --git a/site/app/models/global_stat.php b/site/app/models/global_stat.php
new file mode 100644
index 0000000..0b3ba0b
--- /dev/null
+++ b/site/app/models/global_stat.php
@@ -0,0 +1,55 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * l.m.orchard <lorchard@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+class GlobalStat extends AppModel
+{
+ var $name = "GlobalStat";
+ var $useTable = 'global_stats';
+
+ /**
+ * Shortcut to fetch a named count
+ *
+ * @param string name
+ * @return numeric
+ */
+ function getNamedCount($name) {
+ $rv = $this->findByName($name);
+ if (empty($rv)) return null;
+ return $rv['GlobalStat']['count'];
+ }
+}
diff --git a/site/app/models/group.php b/site/app/models/group.php
new file mode 100644
index 0000000..1091034
--- /dev/null
+++ b/site/app/models/group.php
@@ -0,0 +1,57 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Mike Morgan <morgamic@mozilla.com> (Original Developer)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+class Group extends AppModel {
+
+ var $name = 'Group';
+ var $hasAndBelongsToMany = array('User' =>
+ array(
+ 'className' => 'User',
+ 'joinTable' => 'groups_users',
+ 'foreignKey' => 'group_id',
+ 'associationForeignKey' => 'user_id'
+ )
+ );
+
+ var $validate = array(
+ 'name' => VALID_NOT_EMPTY,
+ 'rules' => '/^([\*a-zA-Z]+:[\-\*a-zA-Z]+?,*)*$/'
+ );
+
+}
+?>
diff --git a/site/app/models/license.php b/site/app/models/license.php
new file mode 100644
index 0000000..c32d293
--- /dev/null
+++ b/site/app/models/license.php
@@ -0,0 +1,89 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ *
+ * Contributor(s):
+ * Jeff Balogh <jbalogh@mozilla.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+class License extends AppModel {
+ var $name = 'License';
+ var $hasMany = array('Version' =>
+ array('className' => 'Version',
+ 'foreignKey' => 'license_id'
+ )
+ );
+ var $translated_fields = array('text');
+
+ function getNames() {
+ global $licenses;
+ return $licenses;
+ }
+
+ function getBuiltin($license_num) {
+ $license = $this->findByName($license_num);
+ if ($license == false) {
+ $data['License']['name'] = $license_num;
+ $this->save($data);
+ return $this->getLastInsertId();
+ } else {
+ return $license['License']['id'];
+ }
+ }
+
+ function getName($license_id) {
+ $license = $this->findById($license_id);
+ if ($license['License']['name'] == -1) {
+ return ___('license_custom');
+ } else {
+ $names = $this->getNames();
+ return $names[$license['License']['name']];
+ }
+ }
+
+ function getText($license_id) {
+ $license = $this->findById($license_id);
+ $name = $license['License']['name'];
+ if ($name == -1) {
+ return $license['Translation']['text']['string'];
+ }
+ else {
+ return $this->getBuiltinText($name);
+ }
+ }
+
+ function getBuiltinText($id) {
+ // This is gross! Fixing in 5.0.6.
+ $path = APP.DS.WEBROOT_DIR.DS.'licenses'.DS.$id.'.txt';
+ return file_get_contents($path);
+ }
+}
+?>
diff --git a/site/app/models/memcaching.php b/site/app/models/memcaching.php
new file mode 100644
index 0000000..3802806
--- /dev/null
+++ b/site/app/models/memcaching.php
@@ -0,0 +1,296 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Frederic Wenzel <fwenzel@mozilla.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/**
+ * This model is an interface to Memcache.
+ * It's called Memcaching to not interfere with the actual Memcache class.
+ */
+
+class Memcaching extends Model {
+ var $cache; // holds the memcache object
+ var $memcacheConnected; // did we find a valid memcache server?
+ var $config; // holds global memcache config
+
+ function __construct() {
+ global $memcache_config;
+ $this->config = $memcache_config;
+
+ if (class_exists('Memcache') && is_array($this->config))
+ $this->cache = new Memcache();
+ else
+ return false;
+
+ foreach ($this->config as $host=>$options) {
+ if ($this->cache->addServer($host, $options['port'], $options['persistent'], $options['weight'], $options['timeout'], $options['retry_interval'])) {
+ $this->memcacheConnected = true;
+ }
+ }
+
+ if (!$this->memcacheConnected)
+ error_log('Memcache Error: Unable to connect to memcache server. Please check configuration and try again.');
+ }
+
+ /**
+ * Get an item from the cache, if it exists
+ * @return mixed item if found, else false
+ */
+ function get($key) {
+ if (!$this->memcacheConnected) return false;
+ return $this->cache->get($key);
+ }
+
+ /**
+ * Store an item in the cache. Replaces an existing item.
+ * @return bool success
+ */
+ function set($key, $var, $flag = null, $expire = CACHE_PAGES_FOR) {
+ if (!$this->memcacheConnected) return false;
+ return $this->cache->set($key, $var, $flag, $expire);
+ }
+
+ /**
+ * Store an item in the cache. Returns false if the key is
+ * already present in the cache.
+ * @return bool success
+ */
+ function add($key, $var, $flag = null, $expire = CACHE_PAGES_FOR) {
+ if (!$this->memcacheConnected) return false;
+ return $this->cache->add($key, $var, $flag, $expire);
+ }
+
+ /**
+ * Store an item in the cache. Returns false if the key did
+ * NOT exist in the cache before.
+ * @return bool success
+ */
+ function replace($key, $var, $flag = null, $expire = CACHE_PAGES_FOR) {
+ if (!$this->memcacheConnected) return false;
+ return $this->cache->replace($key, $var, $flag, $expire);
+ }
+
+ /**
+ * Close the connection to _ALL_ cache servers
+ * @return bool success
+ */
+ function close() {
+ if (!$this->memcacheConnected) return false;
+ return $this->cache->close();
+ }
+
+ /**
+ * Delete something off the cache
+ * @return bool success
+ */
+ function delete($key, $timeout = null) {
+ if (!$this->memcacheConnected) return false;
+ return $this->cache->delete($key, $timeout);
+ }
+
+ /**
+ * Flush the cache
+ * @return bool success
+ */
+ function flush() {
+ foreach ($this->config as $server=>$params) {
+ $m = new Memcache;
+ if (!$m->connect($server,$params['port']) || !$m->flush()) {
+ return false;
+ }
+ $m->close();
+ }
+ return true;
+ }
+
+ /**
+ * Get server statistics.
+ * return array
+ */
+ function getExtendedStats() {
+ if (!$this->memcacheConnected) return false;
+ return $this->cache->getExtendedStats();
+ }
+
+
+ /* * * Object-based memcaching * * */
+
+ /**
+ * get object from memcache
+ *
+ * @param array $identifier unique object identifier
+ * @return mixed cached object if found, false otherwise
+ */
+ function readCacheObject($identifier) {
+ $cachekey = $this->_generateCacheKey($identifier);
+ return $this->get($cachekey);
+ }
+
+ /**
+ * write object to memcache, then add it to cache invalidation list(s)
+ *
+ * @param array $identifier unique object identifier
+ * @param array $data the object
+ * @param array $invalidlists invalidation lists
+ * @param int $expiration (optional) time-to-live
+ * @return bool success
+ */
+ function writeCacheObject($identifier, $data, $invalidlists, $expiration = CACHE_PAGES_FOR) {
+ $cachekey = $this->_generateCacheKey($identifier);
+ $res = $this->set($cachekey, $data, null, $expiration);
+ if (!$res) return false;
+
+ $this->_generateExpirationIDs($invalidlists);
+ // add this object to each expiration list
+ foreach ($invalidlists as $listid) {
+ $this->_addObjectToExpirationList($cachekey, $listid);
+ }
+
+ return true;
+ }
+
+ /**
+ * add an object's cache key to an invalidation list so that it is removed
+ * when that list is flushed
+ *
+ * @param string $cachekey memcache ID of the object to put on the list
+ * @param string $listid id of the invalidation list to put it on
+ * @return void
+ */
+ function _addObjectToExpirationList($cachekey, $listid) {
+ $memcache_listid = MEMCACHE_PREFIX.'expirationlist:'.$listid;
+ // fetch list from memcache if present, otherwise make a new one
+ $exp_list = $this->get($memcache_listid);
+ if (!$exp_list || !is_array($exp_list)) $exp_list = array();
+
+ // add object to list, make sure it's no duplicate, store it
+ if (!in_array($cachekey, $exp_list)) {
+ $exp_list[] = $cachekey;
+ $res = $this->set($memcache_listid, $exp_list, null, 0);
+
+ // in debug mode, display what we did
+ if (DEBUG >= 2) debug("updated $listid, replaced with ".print_r($exp_list, true));
+ }
+ }
+
+ /**
+ * Mark a cache invalidation list for flushing (usually executed from afterSave())
+ * We're not actually flushing the cache here because afterSave() is
+ * called after every query. Instead, we'll just mark this list as needing
+ * flushed for the controller to pick up when we're done.
+ *
+ * @param string list id containing objects to be flushed
+ * @return void
+ */
+ function markListForFlush($listid) {
+ global $flush_lists;
+ $memcache_listid = MEMCACHE_PREFIX.'expirationlist:'.$listid;
+ $flush_lists[] = $memcache_listid;
+ if (DEBUG >= 2) debug("marked $listid for flush");
+ }
+
+ /**
+ * Flush cache lists that have been marked for flush (executed from
+ * AppController::afterFilter())
+ *
+ * @return void
+ */
+ function flushMarkedLists() {
+ global $flush_lists;
+
+ // If this isn't empty, it's holding the names of what we need to flush.
+ if (empty($flush_lists)) return;
+
+ foreach ($flush_lists as $val) {
+ // get list from the cache and delete it
+ $objects = $this->get($val);
+ if (DEBUG >= 2) debug("flushing list $val");
+ if (false === $objects) continue;
+ $this->delete($val);
+
+ // delete each cache object on the list
+ foreach ($objects as $cacheobject) {
+ $this->delete($cacheobject);
+ if (DEBUG >= 2) debug("flushing object $cacheobject off list $val");
+ }
+ }
+ }
+
+ /**
+ * generate unique key hash to store/retrieve objects to/from memcache
+ *
+ * @param mixed $identifier string or array capable of unmistakably identifying the object
+ * @return string hash to be used as memcache ID
+ */
+ function _generateCacheKey($identifier) {
+ // attach language and app
+ $key = LANG.':'.APP_ID.':';
+ // serialize the identifier
+ $key .= serialize($identifier);
+
+ return MEMCACHE_PREFIX.md5($key);
+ }
+
+ /**
+ * (recursively and by reference) generate a list of cache expiration
+ * identifiers from shorthand notation, i.e., transforms:
+ * array('addon' => array(1,2,3)) to
+ * array('addon:1', 'addon:2', 'addon:3')
+ *
+ * @param mixed $shorthand string or array containing a list of list ids, possibly in shorthand notation
+ * @return void
+ */
+ function _generateExpirationIDs(&$shorthand) {
+ if (is_string($shorthand)) {
+ $shorthand = array($shorthand);
+ return;
+ }
+ foreach ($shorthand as $key => $val) {
+ if (is_string($val)) {
+ continue;
+ } elseif (is_array($val)) {
+ // convert sub-array to strings
+ $this->_generateExpirationIDs($val);
+ // add strings to regular array
+ foreach ($val as $subtext)
+ $shorthand[] = $key.':'.$subtext;
+ unset($shorthand[$key]);
+ }
+
+ }
+ }
+}
+?>
diff --git a/site/app/models/platform.php b/site/app/models/platform.php
new file mode 100644
index 0000000..ff0649d
--- /dev/null
+++ b/site/app/models/platform.php
@@ -0,0 +1,93 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Andrei Hajdukewycz <sancus@off.net> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+class Platform extends AppModel
+{
+ var $name = 'Platform';
+ var $hasMany = array('File' =>
+ array('className' => 'File',
+ 'conditions' => '',
+ 'order' => '',
+ 'limit' => '',
+ 'foreignKey' => 'platform_id',
+ 'dependent' => true,
+ 'exclusive' => false,
+ 'finderSql' => ''
+ )
+ );
+
+ var $translated_fields = array(
+ 'name',
+ 'shortname'
+ );
+
+ /**
+ * Returns an array of all platform names and IDs in the form of:
+ * id => name
+ */
+ function getNames() {
+ $_platforms = $this->findAll(null, array('Platform.id', 'Platform.name'), null, null, null, -1);
+
+ $platforms = array();
+ if (!empty($_platforms)) {
+ foreach ($_platforms as $platform) {
+ $platforms[$platform['Platform']['id']] = $platform['Translation']['name']['string'];
+ }
+ asort($platforms);
+ }
+ return $platforms;
+ }
+
+ /**
+ * Returns an array of all platform shortnames and IDs in the form of:
+ * id => shortname
+ */
+ function getShortNames() {
+ $_platforms = $this->findAll(null, array('Platform.id', 'Platform.shortname'), null, null, null, -1);
+
+ $platforms = array();
+ if (!empty($_platforms)) {
+ foreach ($_platforms as $platform) {
+ $platforms[$platform['Platform']['id']] = $platform['Translation']['shortname']['string'];
+ }
+ asort($platforms);
+ }
+ return $platforms;
+ }
+}
+?>
diff --git a/site/app/models/preview.php b/site/app/models/preview.php
new file mode 100644
index 0000000..8220d66
--- /dev/null
+++ b/site/app/models/preview.php
@@ -0,0 +1,97 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Andrei Hajdukewycz <sancus@off.net> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+class Preview extends AppModel
+{
+ var $name = 'Preview';
+ var $belongsTo_full = array('Addon');
+ var $order = 'Preview.highlight DESC';
+
+ var $translated_fields = array(
+ 'caption'
+ );
+
+ var $default_fields = array(
+ 'id', 'addon_id', 'caption', 'highlight', 'created', 'modified'
+ );
+
+ /**
+ * Highlights the specified preview and unhighlights others
+ * @param int $addon_id the add-on id
+ * @param int $preview_id the preview id to highlight
+ */
+ function saveHighlight($addon_id, $preview_id) {
+ // Get existing preview IDs
+ $existing = $this->getIDsForAddon($addon_id);
+
+ // Remove all highlights for the add-on
+ $this->execute("UPDATE previews SET highlight=0 WHERE addon_id={$addon_id}");
+
+ if (!empty($existing) && in_array($preview_id, $existing)) {
+ // Set specified id to highlighted
+ $this->execute("UPDATE previews SET highlight=1 WHERE id={$preview_id}");
+ }
+ else {
+ // Preview was deleted or not belonging to this add-on
+ if (!empty($existing)) {
+ // Set to the first preview available
+ $this->execute("UPDATE previews SET highlight=1 WHERE id={$existing[0]}");
+ }
+ }
+ }
+
+ /**
+ * Returns an array of preview ids for the specified add-on
+ * @param int $addon_id the add-on id
+ * @return array
+ */
+ function getIDsForAddon($addon_id) {
+ // Pull preview ids from master db, not cached
+ $_existing = $this->query("SELECT id FROM previews AS Preview WHERE addon_id={$addon_id}", false, false);
+ $existing = array();
+
+ if (!empty($_existing)) {
+ foreach ($_existing as $preview) {
+ $existing[] = $preview['Preview']['id'];
+ }
+ }
+
+ return $existing;
+ }
+}
+?>
diff --git a/site/app/models/review.php b/site/app/models/review.php
new file mode 100644
index 0000000..96ad236
--- /dev/null
+++ b/site/app/models/review.php
@@ -0,0 +1,308 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Andrei Hajdukewycz <sancus@off.net> (Original Author)
+ * Les Orchard <lorchard@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+class Review extends AppModel
+{
+ var $name = 'Review';
+ var $belongsTo = array('Version' =>
+ array('className' => 'Version',
+ 'conditions' => '',
+ 'order' => '',
+ 'foreignKey' => 'version_id'
+ ),
+ 'User' =>
+ array('className' => 'User',
+ 'conditions' => '',
+ 'order' => '',
+ 'foreignKey' => 'user_id'
+ )
+ );
+ var $hasMany = array('Reviewrating' =>
+ array('className' => 'Reviewrating',
+ 'conditions' => '',
+ 'order' => '',
+ 'limit' => '',
+ 'foreignKey' => 'review_id',
+ 'dependent' => true,
+ 'exclusive' => false,
+ 'finderSql' => ''
+ )
+ );
+ var $validate = array(
+ 'rating' => VALID_NUMBER,
+ 'title' => VALID_NOT_EMPTY,
+ 'body' => VALID_NOT_EMPTY
+ );
+
+ var $translated_fields = array(
+ 'title',
+ 'body'
+ );
+
+ /**
+ * For a given list of review ids, return them with all translations
+ * that are available for each review.
+ *
+ * @param array $reviewids List of ids for the reviews to be returned
+ * @param bool $includeAddon include the add-on ID each review belongs to in the result set?
+ */
+ function getReviews($reviewids, $includeAddon = false) {
+ global $rtl_languages;
+
+ // disable automatic translation so that translations don't get fetched twice
+ $trfields_old = $this->translated_fields;
+ $this->translated_fields = array();
+
+ if (empty($reviewids)) return array(); // nothing to do
+ if (!is_array($reviewids)) $reviewids = array($reviewids);
+
+ // This needs to be a manual query because of bug 442208.
+ $reviews = $this->query("
+ SELECT
+ `Review`.`id`, `Review`.`version_id`, `Review`.`body`, `Review`.`title`,
+ `Review`.`created`, `Review`.`rating`, `User`.`id`, `User`.`nickname`,
+ `User`.`firstname`, `User`.`lastname` FROM `reviews` AS `Review` LEFT JOIN
+ `versions` AS `Version` ON (`Review`.`version_id` = `Version`.`id`) LEFT JOIN
+ `users` AS `User` ON (`Review`.`user_id` = `User`.`id`) WHERE `Review`.`id` IN
+ (".implode(',', $reviewids).") ORDER BY FIELD(`Review`.`id`,".implode(',', $reviewids).") ASC
+ ");
+
+ if (!empty($reviews)) {
+ // we need the Translation model to pull in reviews in all locales
+ loadModel('Translation');
+ $this->Translation =& new Translation();
+ foreach ($reviews as $_id => $_review) {
+ $reviews[$_id]['Translation'] = array();
+ // for each translated field, fetch all its translations.
+ foreach ($trfields_old as $field) {
+ $translations = $this->Translation->findAll(array(
+ 'Translation.id' => $_review['Review'][$field],
+ 'Translation.localized_string IS NOT NULL'
+ ), null, "FIELD(Translation.locale,'".$this->getLang()."') DESC");
+
+ // add the translations found to the reviews array
+ if (!empty($translations)) {
+ foreach($translations as $_trans) {
+ $_temp = array();
+ $_temp['string'] = $_trans['Translation']['localized_string'];
+ $_temp['locale'] = $_trans['Translation']['locale'];
+ $_temp['textdir'] = in_array($_trans['Translation']['locale'], $rtl_languages) ? 'rtl' : 'ltr';
+ if (empty($_trans['Translation']['locale']) || $this->getLang() == $_trans['Translation']['locale']) {
+ $_temp['locale_html'] = '';
+ } else {
+ $_temp['locale_html'] = ' lang="'.$_trans['Translation']['locale'].'" dir="'.$_temp['textdir'].'" ';
+ }
+ if (!empty($_trans['Translation']['locale']))
+ $reviews[$_id]['Translation'][$_temp['locale']][$field] = $_temp;
+ }
+ }
+ }
+
+ // include add-on this review belongs to, if applicable
+ if ($includeAddon) {
+ if (!isset($this->Version)) {
+ loadModel('Version');
+ $this->Version =& new Version();
+ }
+ $_addonid = $this->Version->find("Version.id = {$_review['Review']['version_id']}",
+ 'Version.addon_id');
+ $reviews[$_id]['Review']['addon_id'] = $_addonid['Version']['addon_id'];
+ }
+ }
+ }
+ // reset automatic translation
+ $this->translated_fields = $trfields_old;
+ return $reviews;
+ }
+
+ /**
+ * For a given addon, return the count of users who submitted reviews.
+ *
+ * @param numeric The addon ID
+ * @return numeric Number of users with submitted reviews
+ */
+ function countLatestReviewsForAddon($addon_id) {
+
+ // Prevent SQL injection here with a quick numeric check on the parameters.
+ if (!is_numeric($addon_id))
+ return array();
+
+ $rows = $this->query("
+ SELECT
+ COUNT(DISTINCT reviews.user_id) AS count
+ FROM
+ reviews
+ INNER JOIN
+ versions ON reviews.version_id = versions.id
+ WHERE
+ reviews.reply_to IS NULL AND
+ reviews.version_id=versions.id AND
+ versions.addon_id=$addon_id
+ ");
+
+ return ( $rows ) ? $rows[0][0]['count'] : 0;
+ }
+
+ /**
+ * For a given addon, build a list of latest reviews per user in reverse
+ * chronological order. Only the ID of the latest single review for each
+ * user will be returned, pared with a count of earlier reviews also
+ * submitted by the user for the given addon.
+ *
+ * @param numeric The addon ID
+ * @param numeric Optional limit per page of results
+ * @param numeric Optional page within set of results
+ * @return array List of review records with 'id' and 'others_count'
+ */
+ function findLatestReviewsForAddon($addon_id, $limit=10, $page=1) {
+
+ // Prevent SQL injection here with a quick numeric check on the parameters.
+ if (!is_numeric($addon_id) || !is_numeric($limit) || !is_numeric($page))
+ return array();
+
+ /**
+ * This custom MySQL query uses some GROUP BY sleight of hand to come
+ * up with only the latest review submitted for each user, while sorting
+ * the whole list by that latest review's creation date. A count of
+ * earlier submitted reviews is also derived.
+ */
+ $rows = $this->query("
+ SELECT
+ SUBSTRING_INDEX( GROUP_CONCAT( r.id ORDER BY r.created DESC SEPARATOR ';'), ';', 1 ) AS latest_id,
+ SUBSTRING_INDEX( GROUP_CONCAT( r.created ORDER BY r.created DESC SEPARATOR ';'), ';', 1 ) AS latest_created,
+ COUNT(r.id)-1 AS others_count
+ FROM
+ reviews r
+ INNER JOIN
+ versions v ON r.version_id = v.id
+ WHERE
+ r.reply_to IS NULL AND
+ v.addon_id=$addon_id
+ GROUP BY r.user_id
+ ORDER BY latest_created DESC
+ LIMIT $limit OFFSET " . ( $limit * ($page - 1) )
+ );
+
+ // Simplify the DB rows for easier use in the controller.
+ $results = array();
+ foreach ($rows as $row) {
+ $results[] = array(
+ 'id' =>
+ $row[0]['latest_id'],
+ 'others_count' =>
+ $row[0]['others_count']
+ );
+ }
+ return $results;
+ }
+
+ /**
+ * Update the bayesian rating (cf. bug 477343) for a single (or multiple) add-on(s).
+ * Also updates average rating and total review count.
+ *
+ * Note that similar code exists in the reviews/ratings sections of bin/maintenance.php
+ *
+ * @param array addonids add-on IDs whose bayesian ratings to update.
+ * @return boolean success
+ */
+ function updateBayesianRating($addonids = array()) {
+ if (empty($addonids)) return false;
+
+ // get average review count and average rating
+ $rows = $this->query("
+ SELECT AVG(a.cnt) AS avg_cnt
+ FROM (
+ SELECT COUNT(*) AS cnt
+ FROM reviews AS r
+ INNER JOIN versions AS v ON (r.version_id = v.id)
+ WHERE reply_to IS NULL
+ AND rating > 0
+ GROUP BY v.addon_id
+ ) AS a
+ ");
+ $avg_num_votes = $rows[0][0]['avg_cnt'];
+
+ $rows = $this->query("
+ SELECT AVG(a.addon_rating) AS avg_rating
+ FROM (
+ SELECT AVG(rating) AS addon_rating
+ FROM reviews AS r
+ INNER JOIN versions AS v ON (r.version_id = v.id)
+ WHERE reply_to IS NULL
+ AND rating > 0
+ GROUP BY v.addon_id
+ ) AS a
+ ");
+ $avg_rating = $rows[0][0]['avg_rating'];
+
+ // update total review count and average rating
+ $this->query("
+ UPDATE addons AS a
+ INNER JOIN (
+ SELECT
+ versions.addon_id as addon_id,
+ COUNT(*) as count,
+ AVG(rating) as avg_rating
+ FROM reviews
+ INNER JOIN versions ON reviews.version_id = versions.id
+ WHERE reviews.reply_to IS NULL
+ AND versions.addon_id IN (".(implode(',',$addonids)).")
+ AND reviews.rating > 0
+ GROUP BY versions.addon_id
+ ) AS c ON (a.id = c.addon_id)
+ SET a.totalreviews = c.count,
+ a.averagerating = ROUND(c.avg_rating, 2)
+ WHERE a.id IN (".(implode(',',$addonids)).")
+ ");
+
+ // calculate and store bayesian rating
+ $this->query("
+ UPDATE addons AS a
+ SET a.bayesianrating =
+ IF (a.totalreviews > 0, (
+ ( ({$avg_num_votes} * {$avg_rating}) + (a.totalreviews * a.averagerating) ) /
+ ({$avg_num_votes} + a.totalreviews)
+ ), 0)
+ WHERE a.id IN (".(implode(',',$addonids)).")
+ ");
+ return true;
+ }
+
+}
+?>
diff --git a/site/app/models/reviewrating.php b/site/app/models/reviewrating.php
new file mode 100644
index 0000000..c822317
--- /dev/null
+++ b/site/app/models/reviewrating.php
@@ -0,0 +1,56 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Andrei Hajdukewycz <sancus@off.net> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+class Reviewrating extends AppModel
+{
+ var $name = 'Reviewrating';
+ var $belongsTo = array('User' =>
+ array('className' => 'User',
+ 'conditions' => '',
+ 'order' => '',
+ 'foreignKey' => 'user_id'
+ ),
+ 'Review' =>
+ array('className' => 'Review',
+ 'conditions' => '',
+ 'order' => '',
+ 'foreignKey' => 'review_id'
+ )
+ );
+}
+?>
diff --git a/site/app/models/reviews_moderation_flag.php b/site/app/models/reviews_moderation_flag.php
new file mode 100644
index 0000000..e740784
--- /dev/null
+++ b/site/app/models/reviews_moderation_flag.php
@@ -0,0 +1,77 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Les Orchard <lorchard@mozilla.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+class ReviewsModerationFlag extends AppModel
+{
+ var $name = 'ReviewsModerationFlag';
+ var $tableName = 'reviews_moderation_flag';
+ var $belongsTo = array(
+ 'User' => array(
+ 'className' => 'User',
+ 'conditions' => '',
+ 'order' => '',
+ 'foreignKey' => 'user_id'
+ ),
+ 'Review' => array(
+ 'className' => 'Review',
+ 'conditions' => '',
+ 'order' => '',
+ 'foreignKey' => 'review_id'
+ )
+ );
+
+ function __construct() {
+ parent::__construct();
+
+ // Constants defined here because the ___() function can't be called in static
+ // class definition.
+ $this->reasons = array(
+ 'review_flag_reason_spam' =>
+ ___('review_flag_reason_spam', 'Spam or otherwise non-review content'),
+ 'review_flag_reason_language' =>
+ ___('review_flag_reason_language', 'Inappropriate language/dialog'),
+ 'review_flag_reason_bug_support' =>
+ ___('review_flag_reason_bug_support', 'Misplaced bug report or support request'),
+ 'review_flag_reason_other' =>
+ ___('review_flag_reason_other', 'Other (please specify)')
+ );
+
+ }
+
+}
+?>
diff --git a/site/app/models/tag.php b/site/app/models/tag.php
new file mode 100644
index 0000000..42877e1
--- /dev/null
+++ b/site/app/models/tag.php
@@ -0,0 +1,134 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Andrei Hajdukewycz <sancus@off.net> (Original Author)
+ * Justin Scott <fligtar@gmail.com>
+ * Wil Clouser <clouserw@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+class Tag extends AppModel
+{
+ var $name = 'Tag';
+ var $hasAndBelongsToMany_full = array('Addon' =>
+ array('className' => 'Addon',
+ 'joinTable' => 'addons_tags',
+ 'foreignKey' => 'tag_id',
+ 'associationForeignKey'=> 'addon_id')
+ );
+ var $belongsTo = array('Addontype', 'Application');
+
+ /**
+ * Fields here will looked up in the translations table
+ *
+ * @var array
+ * @access public
+ */
+ var $translated_fields = array('name', 'description');
+
+ /**
+ * Saves selected categories by only removing deleted categories and inserting
+ * new categories rather than deleting all existing categories and adding all
+ * back.
+ * @param int $addon_id add-on id
+ * @param array $data tag data from form
+ */
+ function saveCategories($addon_id, $data) {
+ if (empty($data)) {
+ return;
+ }
+
+ foreach ($data as $application_id => $selectedTags) {
+ foreach ($selectedTags as $tag_id) {
+ if (!empty($tag_id)) {
+ $newTags[] = $tag_id;
+ }
+ }
+ }
+
+ if (!empty($newTags)) {
+ // Only delete tags that aren't still selected to retain additional
+ // information, such as featured status
+ $this->execute("DELETE FROM addons_tags WHERE addon_id={$addon_id} AND tag_id NOT IN (".implode(',', $newTags).")");
+ }
+
+ $_currentTags = $this->query("SELECT tag_id FROM addons_tags WHERE addon_id={$addon_id}");
+ if (!empty($_currentTags)) {
+ foreach ($_currentTags as $currentTag) {
+ $currentTags[] = $currentTag['addons_tags']['tag_id'];
+ }
+ }
+
+ // Insert tags that aren't already there
+ foreach ($newTags as $tag_id) {
+ if (empty($currentTags) || (!empty($currentTags) && !in_array($tag_id, $currentTags))) {
+ $this->execute("INSERT INTO addons_tags (addon_id, tag_id) VALUES({$addon_id}, {$tag_id})");
+ }
+ }
+ }
+
+ /**
+ * same as above method but backported to 3.2
+ * @deprecate
+ */
+ function LEGACY_saveCategories($addon_id, $data) {
+ if (empty($data)) {
+ return;
+ }
+
+ $newTags = $data;
+
+ if (!empty($newTags)) {
+ // Only delete tags that aren't still selected to retain additional
+ // information, such as featured status
+ $this->execute("DELETE FROM addons_tags WHERE addon_id={$addon_id} AND tag_id NOT IN (".implode(',', $newTags).")");
+ }
+
+ $_currentTags = $this->query("SELECT tag_id FROM addons_tags WHERE addon_id={$addon_id}");
+ if (!empty($_currentTags)) {
+ foreach ($_currentTags as $currentTag) {
+ $currentTags[] = $currentTag['addons_tags']['tag_id'];
+ }
+ }
+
+ // Insert tags that aren't already there
+ foreach ($newTags as $tag_id) {
+ if (!in_array($tag_id, $currentTags)) {
+ $this->execute("INSERT INTO addons_tags (addon_id, tag_id) VALUES({$addon_id}, {$tag_id})");
+ }
+ }
+ }
+
+}
+?>
diff --git a/site/app/models/translation.php b/site/app/models/translation.php
new file mode 100644
index 0000000..2b954aa
--- /dev/null
+++ b/site/app/models/translation.php
@@ -0,0 +1,60 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Andrei Hajdukewycz <sancus@off.net> (Original Author)
+ * Wil Clouser <clouserw@mozilla.com>
+ * Justin Scott <fligtar@gmail.com>
+ * Frederic Wenzel <fwenzel@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/**
+ * Remora translation is described in more detail
+ * here: http://wiki.mozilla.org/Update:Remora_Localization
+ *
+ * Please note that due to the transparent nature of the dynamic localization,
+ * the Translation model is not used. Instead, the translations are
+ * transparently JOINed into regular queries by the app_model's beforefind()
+ * function.
+ */
+class Translation extends AppModel
+{
+ /**
+ * Cake Requirement for php4
+ * @var string
+ */
+ var $name = 'Translation';
+
+}
+?>
diff --git a/site/app/models/update_count.php b/site/app/models/update_count.php
new file mode 100644
index 0000000..46ba40c
--- /dev/null
+++ b/site/app/models/update_count.php
@@ -0,0 +1,57 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Laura Thomson <lthomson@mozilla.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+class UpdateCount extends AppModel
+{
+ var $name = 'UpdateCount';
+ var $tableName = 'update_counts';
+
+ var $belongsTo = array('Addon' =>
+ array('className' => 'Addon',
+ 'conditions' => '',
+ 'order' => '',
+ 'limit' => '',
+ 'foreignKey' => 'addon_id',
+ 'dependent' => true,
+ 'exclusive' => false,
+ 'finderSql' => ''
+ )
+ );
+
+}
+?>
diff --git a/site/app/models/user.php b/site/app/models/user.php
new file mode 100644
index 0000000..6a92c7b
--- /dev/null
+++ b/site/app/models/user.php
@@ -0,0 +1,316 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Andrei Hajdukewycz <sancus@off.net> (Original Author)
+ * Justin Scott <fligtar@gmail.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+class User extends AppModel
+{
+ var $name = 'User';
+ var $hasAndBelongsToMany = array('Group' =>
+ array('className' => 'Group',
+ 'joinTable' => 'groups_users',
+ 'foreignKey' => 'user_id',
+ 'associationForeignKey' => 'group_id'
+ )
+ );
+
+ var $hasAndBelongsToMany_full = array('Addon' =>
+ array('className' => 'Addon',
+ 'joinTable' => 'addons_users',
+ 'foreignKey' => 'user_id',
+ 'associationForeignKey' => 'addon_id'
+ ),
+ 'CollectionSubscriptions' =>
+ array('className' => 'Collection',
+ 'joinTable' => 'collection_subscriptions',
+ 'foreignKey' => 'user_id',
+ 'associationForeignKey' => 'collection_id'
+ ),
+ 'Collections' =>
+ array('className' => 'Collection',
+ 'joinTable' => 'collections_users',
+ 'foreignKey' => 'user_id',
+ 'associationForeignKey' => 'collection_id')
+ );
+ var $hasMany_full = array('Approval' =>
+ array('className' => 'Approval',
+ 'conditions' => '',
+ 'order' => '',
+ 'limit' => '',
+ 'foreignKey' => 'user_id',
+ 'dependent' => true,
+ 'exclusive' => false,
+ 'finderSql' => ''
+ ),
+ 'Reviewrating' =>
+ array('className' => 'Reviewrating',
+ 'conditions' => '',
+ 'order' => '',
+ 'limit' => '',
+ 'foreignKey' => 'user_id',
+ 'dependent' => true,
+ 'exclusive' => false,
+ 'finderSql' => ''
+ ),
+ 'Favorite' =>
+ array('className' => 'Favorite',
+ 'conditions' => '',
+ 'order' => '',
+ 'limit' => '',
+ 'foreignKey' => 'user_id',
+ 'dependent' => true,
+ 'exclusive' => false,
+ 'finderSql' => ''
+ ),
+ 'Review' =>
+ array('className' => 'Review',
+ 'conditions' => '',
+ 'order' => '',
+ 'limit' => '',
+ 'foreignKey' => 'user_id',
+ 'dependent' => true,
+ 'exclusive' => false,
+ 'finderSql' => ''
+ ),
+ );
+
+ var $translated_fields = array('bio');
+
+ var $validate = array(
+ 'email' => VALID_EMAIL,
+ 'password' => VALID_NOT_EMPTY,
+ 'homepage' => VALID_URL_OPT
+ );
+
+ /**
+ * Get number of add-ons this user is affiliated with
+ *
+ * @param int $id user id
+ * @return int number of add-ons
+ */
+ function getAddonCount($id) {
+ $res = $this->execute("SELECT COUNT(*) as c FROM addons_users AS au WHERE au.user_id = '{$id}';");
+ return $res[0][0]['c'];
+ }
+
+ /**
+ * Anonymize a user account.
+ * This is the user-facing "delete account" feature, which does not delete
+ * the actual row in the DB (to prevent untraceable spam etc.), but removes
+ * all personal information from the user account.
+ *
+ * @param int $id user id
+ * @return bool success
+ */
+ function anonymize($id) {
+ // generate anonymized data array
+ $data = array('User' => array(
+ 'id' => $id,
+ 'email' => null,
+ 'password' => '', // empty pw will result in login failure
+ 'firstname' => '',
+ 'lastname' => '',
+ 'nickname' => 'Deleted User',
+ 'homepage' => ''
+ ));
+ return $this->save($data, false, array_keys($data['User']));
+ }
+
+ /**
+ * Enforce one of the name fields not to be empty
+ */
+ function beforeValidate() {
+ if (!$this->data) return false;
+ if (array_key_exists('nickname', $this->data['User']) &&
+ array_key_exists('lastname', $this->data['User']) &&
+ array_key_exists('firstname', $this->data['User']) &&
+ empty($this->data['User']['nickname']) && empty($this->data['User']['firstname'])
+ && empty($this->data['User']['lastname'])) {
+ $this->invalidate('firstname');
+ $this->invalidate('lastname');
+ $this->invalidate('nickname');
+ }
+
+ return parent::beforeValidate();
+ }
+
+ /* Password handling inspired by Django. */
+
+ /**
+ * Check a raw password against the User's stored password.
+ * If the User has an old-style md5 password it will be updated
+ * to the new hashing scheme if the $rawPassword checks.
+ *
+ * $self must be an assoc array containing 'password' and 'id'.
+ */
+ function checkPassword($self, $rawPassword) {
+ $storedPassword = $self['password'];
+ if (strpos($storedPassword, '$') === false) {
+ // Old-style password.
+ $hashedPassword = md5($rawPassword);
+ $valid = !empty($storedPassword) && $storedPassword == $hashedPassword;
+ // Update to the new scheme.
+ if ($valid) {
+ // Using SQL so we don't upset $this->User.
+ $newPassword = $this->createPassword($rawPassword);
+ $this->execute("UPDATE users
+ SET `password`='{$newPassword}'
+ WHERE `id`={$self['id']}");
+ }
+ return $valid;
+ }
+ return $this->_checkPassword($rawPassword, $storedPassword);
+ }
+
+ /**
+ * Validate a new-style password.
+ */
+ function _checkPassword($rawPassword, $encPassword) {
+ if (empty($encPassword)) {
+ return false;
+ }
+ list($algo, $salt, $storedPassword) = split('\$', $encPassword);
+ $hashedPassword = $this->getHexDigest($algo, $salt, $rawPassword);
+ // Check isset to make sure the split worked.
+ return isset($storedPassword) && $storedPassword == $hashedPassword;
+ }
+
+ /**
+ * Create a password that looks like '$algorithm$salt$encrypted'.
+ */
+ function createPassword($rawPassword, $algo='sha512') {
+ // 64 chars ought to be enough salt for anybody.
+ $salt = $this->getHexDigest($algo, uniqid(rand(), true), uniqid(rand(), true));
+ $salt = substr($salt, 0, 64);
+
+ $hashedPassword = $this->getHexDigest($algo, $salt, $rawPassword);
+ $password = $algo.'$'.$salt.'$'.$hashedPassword;
+ return $password;
+ }
+
+ /**
+ * Returns a string of the hexdigest of the given plaintext password and
+ * salt using the given algorithm.
+ */
+ function getHexDigest($algo, $salt, $rawPassword) {
+ return hash($algo, $salt.$rawPassword);
+ }
+
+ function setResetCode($user_id) {
+ $code = md5(mt_rand());
+ $expires = strtotime(PASSWORD_RESET_EXPIRES.' days');
+ $this->save(array('id' => $user_id,
+ 'resetcode' => $code,
+ 'resetcode_expires' => date('Y-m-d H:i:s', $expires)));
+ return $code;
+ }
+
+ function checkResetCode($user_id, $code) {
+ $user = $this->find(array("User.id = {$user_id}",
+ "User.resetcode_expires > NOW()"));
+ return $user && $code == $user['User']['resetcode'];
+ }
+
+ /**
+ * Get subscriptions
+ *
+ * @param int $userId user id
+ */
+ function getSubscriptions($userId) {
+
+ // Just bind to the collection subscriptions relation.
+ $this->bindModel(array(
+ 'hasAndBelongsToMany' => array(
+ 'CollectionSubscriptions' =>
+ $this->hasAndBelongsToMany_full['CollectionSubscriptions']
+ )
+ ));
+ $user = $this->findById($userId);
+
+ $collectionIds = array();
+ //Fetch collections to get translations
+ foreach($user['CollectionSubscriptions'] as $collection) {
+ $collectionIds[] = $collection['id'];
+ }
+
+ $criteria = array('Collection.id' => $collectionIds);
+ $subscriptions = $this->Collection->findAll($criteria);
+ return $subscriptions;
+ }
+
+ /**
+ * Get IDs of collections this user has write access to
+ *
+ * @param int $userId user id
+ * @param int $app (optional) only show collections with this app ID, defaults to all
+ * @param array $filterAddons (optional) list of add-ons to exclude:
+ * collections containing these will not be returned
+ * @return array unsorted list of IDs this user has write access to
+ */
+ function getCollections($userId, $app = null, $filterAddons = array()) {
+ if (!is_numeric($userId)) return false;
+
+ $db =& ConnectionManager::getDataSource($this->useDbConfig);
+ if (!empty($filterAddons)) {
+ $_join = ' LEFT JOIN addons_collections AS ac ON (ac.collection_id = c.id '
+ .'AND ac.addon_id IN ('.implode(',', array_map(array($db, 'value'), $filterAddons)).'))';
+ $_where = ' AND ac.addon_id IS NULL';
+ } else {
+ $_join = '';
+ $_where = '';
+ }
+
+ if (!empty($app) && is_numeric($app)) {
+ $_where .= " AND c.application_id = {$app}";
+ }
+
+ $res = $this->query(
+ "SELECT DISTINCT c.id "
+ ."FROM collections_users AS cu "
+ ."INNER JOIN collections AS c ON (cu.collection_id = c.id) "
+ .$_join
+ ."WHERE cu.user_id = {$userId} "
+ ."AND cu.role IN (".implode(',', array(COLLECTION_ROLE_OWNER,
+ COLLECTION_ROLE_ADMIN, COLLECTION_ROLE_PUBLISHER))."){$_where}");
+
+ $collectionIds = array();
+ foreach($res as &$_coll) $collectionIds[] = $_coll['c']['id'];
+
+ return $collectionIds;
+ }
+}
+?>
diff --git a/site/app/models/version.php b/site/app/models/version.php
new file mode 100644
index 0000000..70c7468
--- /dev/null
+++ b/site/app/models/version.php
@@ -0,0 +1,305 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Andrei Hajdukewycz <sancus@off.net> (Original Author)
+ * Justin Scott <fligtar@gmail.com>
+ * Mike Morgan <morgamic@mozilla.com>
+ * Frederic Wenzel <fwenzel@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+class Version extends AppModel
+{
+ var $name = 'Version';
+ var $belongsTo_full = array('Addon' =>
+ array('className' => 'Addon'),
+ 'License' =>
+ array('className' => 'License',
+ 'conditions' => '',
+ 'order' => '',
+ 'foreignKey' => 'license_id'
+ )
+ );
+
+ var $hasMany = array('Review' =>
+ array('className' => 'Review',
+ 'conditions' => '',
+ 'order' => '',
+ 'limit' => '',
+ 'foreignKey' => 'version_id',
+ 'dependent' => true,
+ 'exclusive' => false,
+ 'finderSql' => ''
+ ),
+ 'File' =>
+ array('className' => 'File',
+ 'conditions' => '',
+ 'order' => '',
+ 'limit' => '',
+ 'foreignKey' => 'version_id',
+ 'dependent' => true,
+ 'exclusive' => false,
+ 'finderSql' => ''
+ )
+ );
+ var $hasAndBelongsToMany = array('Application' =>
+ array('className' => 'Application',
+ 'joinTable' => 'applications_versions',
+ 'foreignKey' => 'version_id',
+ 'associationForeignKey'=> 'application_id',
+ 'conditions' => '',
+ 'order' => '',
+ 'limit' => '',
+ 'unique' => false,
+ 'finderSql' => '',
+ 'deleteQuery'=> ''
+ )
+ );
+
+ var $translated_fields = array(
+ 'releasenotes'
+ );
+
+ var $validate = array(
+ 'addon_id' => VALID_NUMBER,
+ 'version' => VALID_NOT_EMPTY
+ );
+
+ /**
+ * Return the id or ids of valid versions by add-on id.
+ *
+ * @param mixed $id
+ * @param array $status non-empty array
+ * @return aray|boolean array of valid version_ids on success or false on failure
+ */
+ function getVersionIdsByAddonId($id, $status = array(STATUS_PUBLIC)) {
+
+ // Implode our status array
+ $status_sql = implode(',',$status);
+
+ $id_sql = is_array($id) ? implode(',',$id) : $id;
+
+ $sql = "
+ SELECT DISTINCT
+ Version.id
+ FROM
+ versions AS Version
+ INNER JOIN
+ files AS File ON File.status IN ({$status_sql}) AND File.version_id = Version.id
+ WHERE
+ Version.addon_id IN ({$id_sql})
+ ORDER BY
+ Version.created DESC
+ ";
+
+ return $this->query($sql);
+ }
+
+ /**
+ * Return the latest version id by add-on id.
+ *
+ * @param int $id
+ * @param array $status non-empty array
+ * @return int $id of the latest version or 0
+ */
+ function getVersionByAddonId($id, $status = array(STATUS_PUBLIC)) {
+ if (!is_array($status)) $status = array($status);
+ $status_sql = implode(',',$status);
+
+ $sql = "
+ SELECT
+ Version.id
+ FROM
+ versions AS Version
+ INNER JOIN
+ files AS File ON File.status IN ({$status_sql}) AND File.version_id = Version.id
+ WHERE
+ Version.addon_id = {$id}
+ ORDER BY
+ Version.created DESC
+ LIMIT 1
+ ";
+
+ $buf = $this->query($sql);
+
+ if (!empty($buf[0]['Version']['id'])) {
+ return $buf[0]['Version']['id'];
+ }
+
+ return 0;
+ }
+
+ /**
+ * Get the apps compatible with a given addon version
+ */
+ function getCompatibleApps($id) {
+ global $app_shortnames;
+
+ $supported_app_ids = implode(',',array_values($app_shortnames));
+ $sql = "
+ SELECT
+ Application.application_id,
+ Min_Version.version,
+ Max_Version.version
+ FROM
+ applications_versions AS Application
+ INNER JOIN
+ appversions AS Min_Version ON (Min_Version.id = Application.`min`)
+ INNER JOIN
+ appversions AS Max_Version ON (Max_Version.id = Application.`max`)
+ WHERE
+ Application.version_id = '{$id}'
+ AND
+ Application.application_id IN ({$supported_app_ids})
+ ORDER BY
+ (Application.application_id = '".APP_ID."') DESC,
+ FIELD(Application.application_id,{$supported_app_ids})
+ ";
+ return $this->query($sql, true);
+ }
+
+ /**
+ * Gets the apps compatible with a given add-on version in the form of ids
+ * instead of the actual version numbers and organizes them by application_id
+ */
+ function getCompatibleAppIds($version_id) {
+ $apps = $this->query("
+ SELECT
+ `applications_versions`.`application_id`,
+ `min`.`id`,
+ `max`.`id`
+ FROM
+ `applications_versions`
+ INNER JOIN
+ `appversions` AS `min` ON `applications_versions`.`min`=`min`.`id`
+ INNER JOIN
+ `appversions` AS `max` ON `applications_versions`.`max`=`max`.`id`
+ WHERE
+ `applications_versions`.`version_id`='{$version_id}'
+ ", true);
+
+ $list = array();
+
+ if (!empty($apps)) {
+ foreach ($apps as $app) {
+ $list[$app['applications_versions']['application_id']] = array(
+ 'min' => $app['min']['id'],
+ 'max' => $app['max']['id']
+ );
+ }
+ }
+
+ return $list;
+ }
+
+ /**
+ * Adds a compatible application to the specified version
+ * @param int $version_id version id
+ * @param int $application_id application id
+ * @param int $minVersion appversion id (not the actual version string)
+ * @param int $maxVersion appversion id (not the actual version string)
+ */
+ function addCompatibleApp($version_id, $application_id, $minVersion, $maxVersion) {
+ $this->execute("
+ INSERT INTO
+ applications_versions (
+ application_id,
+ version_id,
+ min,
+ max
+ )
+ VALUES (
+ {$application_id},
+ {$version_id},
+ {$minVersion},
+ {$maxVersion}
+ )
+ ");
+ }
+
+ /**
+ * Removes a compatible application from the specified version
+ * @param int $version_id version id
+ * @param int $application_id application id
+ */
+ function removeCompatibleApp($version_id, $application_id) {
+ $this->execute("
+ DELETE FROM
+ applications_versions
+ WHERE
+ version_id={$version_id} AND
+ application_id={$application_id}
+ ");
+ }
+
+ /**
+ * Updates compatiblity for the specified app and version
+ * @param int $version_id version id
+ * @param int $application_id application id
+ * @param int $minVersion appversion id (not the actual version string)
+ * @param int $maxVersion appversion id (not the actual version string)
+ */
+ function updateCompatibility($version_id, $application_id, $minVersion, $maxVersion) {
+ $this->execute("
+ UPDATE
+ applications_versions
+ SET
+ min={$minVersion},
+ max={$maxVersion}
+ WHERE
+ version_id={$version_id} AND
+ application_id={$application_id}
+ ");
+ }
+
+ /**
+ * Returns an array of file ids associated with the given version.
+ * @param int $version_id version id
+ * @return array
+ */
+ function getFileIDs($version_id) {
+ $files = $this->query("SELECT id FROM files WHERE version_id={$version_id}");
+ $file_ids = array();
+
+ if (!empty($files)) {
+ foreach ($files as $file) {
+ $file_ids[] = $file['files']['id'];
+ }
+ }
+
+ return $file_ids;
+ }
+
+}
+?>
diff --git a/site/app/tests/amo-selenium.html b/site/app/tests/amo-selenium.html
new file mode 100644
index 0000000..37a4662
--- /dev/null
+++ b/site/app/tests/amo-selenium.html
@@ -0,0 +1,412 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head profile="http://selenium-ide.openqa.org/profiles/test-case">
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+<link rel="selenium.base" href="https://addons.mozilla.org/" />
+<title>amo-selenium</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">amo-selenium</td></tr>
+</thead><tbody>
+<tr>
+ <td>open</td>
+ <td>/en-US/firefox/users/logout?to=</td>
+ <td></td>
+</tr>
+<tr>
+ <td>open</td>
+ <td>/en-US/firefox/</td>
+ <td></td>
+</tr>
+<tr>
+ <td>open</td>
+ <td>/en-US/firefox/browse/type:1/cat:72</td>
+ <td></td>
+</tr>
+<tr>
+ <td>verifyTextPresent</td>
+ <td>See All Alerts &amp; Updates</td>
+ <td></td>
+</tr>
+<tr>
+ <td>clickAndWait</td>
+ <td>link=Appearance</td>
+ <td></td>
+</tr>
+<tr>
+ <td>verifyTextPresent</td>
+ <td>See All Appearance</td>
+ <td></td>
+</tr>
+<tr>
+ <td>clickAndWait</td>
+ <td>link=Bookmarks</td>
+ <td></td>
+</tr>
+<tr>
+ <td>verifyTextPresent</td>
+ <td>See All Bookmarks</td>
+ <td></td>
+</tr>
+<tr>
+ <td>clickAndWait</td>
+ <td>link=Dictionaries &amp; Language Packs</td>
+ <td></td>
+</tr>
+<tr>
+ <td>clickAndWait</td>
+ <td>link=Download Management</td>
+ <td></td>
+</tr>
+<tr>
+ <td>verifyTextPresent</td>
+ <td>See All Download Management</td>
+ <td></td>
+</tr>
+<tr>
+ <td>clickAndWait</td>
+ <td>link=Feeds, News &amp; Blogging</td>
+ <td></td>
+</tr>
+<tr>
+ <td>verifyTextPresent</td>
+ <td>See All Feeds, News &amp; Blogging</td>
+ <td></td>
+</tr>
+<tr>
+ <td>clickAndWait</td>
+ <td>link=Language Support</td>
+ <td></td>
+</tr>
+<tr>
+ <td>verifyTextPresent</td>
+ <td>See All Language Support</td>
+ <td></td>
+</tr>
+<tr>
+ <td>clickAndWait</td>
+ <td>//img[@alt='Firefox Add-ons']</td>
+ <td></td>
+</tr>
+<tr>
+ <td>clickAndWait</td>
+ <td>link=Photos, Music &amp; Videos</td>
+ <td></td>
+</tr>
+<tr>
+ <td>verifyTextPresent</td>
+ <td>See All Photos, Music &amp; Videos</td>
+ <td></td>
+</tr>
+<tr>
+ <td>clickAndWait</td>
+ <td>link=Plugins</td>
+ <td></td>
+</tr>
+<tr>
+ <td>verifyTextPresent</td>
+ <td>Windows Media Player</td>
+ <td></td>
+</tr>
+<tr>
+ <td>verifyTextPresent</td>
+ <td>Shockwave</td>
+ <td></td>
+</tr>
+<tr>
+ <td>verifyTextPresent</td>
+ <td>RealPlayer</td>
+ <td></td>
+</tr>
+<tr>
+ <td>verifyTextPresent</td>
+ <td>QuickTime</td>
+ <td></td>
+</tr>
+<tr>
+ <td>verifyTextPresent</td>
+ <td>Java</td>
+ <td></td>
+</tr>
+<tr>
+ <td>verifyTextPresent</td>
+ <td>Adobe Flash Player</td>
+ <td></td>
+</tr>
+<tr>
+ <td>verifyTextPresent</td>
+ <td>Adobe Reader</td>
+ <td></td>
+</tr>
+<tr>
+ <td>clickAndWait</td>
+ <td>//img[@alt='Firefox Add-ons']</td>
+ <td></td>
+</tr>
+<tr>
+ <td>clickAndWait</td>
+ <td>link=Privacy &amp; Security</td>
+ <td></td>
+</tr>
+<tr>
+ <td>verifyTextPresent</td>
+ <td>See All Privacy &amp; Security</td>
+ <td></td>
+</tr>
+<tr>
+ <td>clickAndWait</td>
+ <td>link=Search Tools</td>
+ <td></td>
+</tr>
+<tr>
+ <td>verifyTextPresent</td>
+ <td>Browse Search Engines</td>
+ <td></td>
+</tr>
+<tr>
+ <td>clickAndWait</td>
+ <td>link=See All Search Tools</td>
+ <td></td>
+</tr>
+<tr>
+ <td>selectAndWait</td>
+ <td>show-perpage</td>
+ <td>label=100</td>
+</tr>
+<tr>
+ <td>verifyTextPresent</td>
+ <td>/Find Bar/</td>
+ <td></td>
+</tr>
+<tr>
+ <td>clickAndWait</td>
+ <td>//li[12]/a</td>
+ <td></td>
+</tr>
+<tr>
+ <td>verifyTextPresent</td>
+ <td>See All Social &amp; Communication</td>
+ <td></td>
+</tr>
+<tr>
+ <td>clickAndWait</td>
+ <td>link=Tabs</td>
+ <td></td>
+</tr>
+<tr>
+ <td>verifyTextPresent</td>
+ <td>See All Tabs</td>
+ <td></td>
+</tr>
+<tr>
+ <td>clickAndWait</td>
+ <td>link=Themes</td>
+ <td></td>
+</tr>
+<tr>
+ <td>verifyTextPresent</td>
+ <td>Browse Themes</td>
+ <td></td>
+</tr>
+<tr>
+ <td>clickAndWait</td>
+ <td>link=Toolbars</td>
+ <td></td>
+</tr>
+<tr>
+ <td>verifyTextPresent</td>
+ <td>See All Toolbars</td>
+ <td></td>
+</tr>
+<tr>
+ <td>clickAndWait</td>
+ <td>link=Web Development</td>
+ <td></td>
+</tr>
+<tr>
+ <td>verifyTextPresent</td>
+ <td>See All Web Development</td>
+ <td></td>
+</tr>
+<tr>
+ <td>clickAndWait</td>
+ <td>link=Other</td>
+ <td></td>
+</tr>
+<tr>
+ <td>verifyTextPresent</td>
+ <td>See All Other</td>
+ <td></td>
+</tr>
+<tr>
+ <td>open</td>
+ <td>/en-US/firefox/</td>
+ <td></td>
+</tr>
+<tr>
+ <td>verifyTextPresent</td>
+ <td>1 / 6</td>
+ <td></td>
+</tr>
+<tr>
+ <td>click</td>
+ <td>//img[@alt='Next Add-on']</td>
+ <td></td>
+</tr>
+<tr>
+ <td>verifyTextPresent</td>
+ <td>2 / 6</td>
+ <td></td>
+</tr>
+<tr>
+ <td>click</td>
+ <td>//img[@alt='Next Add-on']</td>
+ <td></td>
+</tr>
+<tr>
+ <td>verifyTextPresent</td>
+ <td>3 / 6</td>
+ <td></td>
+</tr>
+<tr>
+ <td>click</td>
+ <td>//img[@alt='Next Add-on']</td>
+ <td></td>
+</tr>
+<tr>
+ <td>verifyTextPresent</td>
+ <td>4 / 6</td>
+ <td></td>
+</tr>
+<tr>
+ <td>click</td>
+ <td>//img[@alt='Next Add-on']</td>
+ <td></td>
+</tr>
+<tr>
+ <td>verifyTextPresent</td>
+ <td>5 / 6</td>
+ <td></td>
+</tr>
+<tr>
+ <td>click</td>
+ <td>//img[@alt='Next Add-on']</td>
+ <td></td>
+</tr>
+<tr>
+ <td>verifyTextPresent</td>
+ <td>6 / 6</td>
+ <td></td>
+</tr>
+<tr>
+ <td>clickAndWait</td>
+ <td>my-submit</td>
+ <td></td>
+</tr>
+<tr>
+ <td>type</td>
+ <td>query</td>
+ <td>foxytunes</td>
+</tr>
+<tr>
+ <td>verifyTextPresent</td>
+ <td>Photos, Music &amp; Videos</td>
+ <td></td>
+</tr>
+<tr>
+ <td>verifyTextPresent</td>
+ <td>Social &amp; Communication</td>
+ <td></td>
+</tr>
+<tr>
+ <td>verifyTextPresent</td>
+ <td>Alerts &amp; Updates</td>
+ <td></td>
+</tr>
+<tr>
+ <td>select</td>
+ <td>category</td>
+ <td>label=Themes</td>
+</tr>
+<tr>
+ <td>clickAndWait</td>
+ <td>my-submit</td>
+ <td></td>
+</tr>
+<tr>
+ <td>select</td>
+ <td>category</td>
+ <td>label=Alerts &amp; Updates</td>
+</tr>
+<tr>
+ <td>clickAndWait</td>
+ <td>my-submit</td>
+ <td></td>
+</tr>
+<tr>
+ <td>select</td>
+ <td>category</td>
+ <td>label=Dictionaries &amp; Language Packs</td>
+</tr>
+<tr>
+ <td>clickAndWait</td>
+ <td>my-submit</td>
+ <td></td>
+</tr>
+<tr>
+ <td>verifyTextPresent</td>
+ <td>No results found.</td>
+ <td></td>
+</tr>
+<tr>
+ <td>type</td>
+ <td>query</td>
+ <td>javascript:alert(&quot;XSS&quot;);</td>
+</tr>
+<tr>
+ <td>clickAndWait</td>
+ <td>my-submit</td>
+ <td></td>
+</tr>
+<tr>
+ <td>verifyTextPresent</td>
+ <td>No results found.</td>
+ <td></td>
+</tr>
+<tr>
+ <td>open</td>
+ <td>/en-US/thunderbird/browse/type:2</td>
+ <td></td>
+</tr>
+<tr>
+ <td>verifyTextPresent</td>
+ <td>We Recommend</td>
+ <td></td>
+</tr>
+<tr>
+ <td>open</td>
+ <td>/en-US/firefox/users/register</td>
+ <td></td>
+</tr>
+<tr>
+ <td>clickAndWait</td>
+ <td>//input[@value='Register']</td>
+ <td></td>
+</tr>
+<tr>
+ <td>verifyTextPresent</td>
+ <td>This field must not be empty.</td>
+ <td></td>
+</tr>
+<tr>
+ <td>verifyTextPresent</td>
+ <td>Invalid captcha, please try again!</td>
+ <td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/site/app/tests/app_controller.test.php b/site/app/tests/app_controller.test.php
new file mode 100644
index 0000000..8d799ae
--- /dev/null
+++ b/site/app/tests/app_controller.test.php
@@ -0,0 +1,80 @@
+<?php
+// dummy controller, along with associated dummy model
+class DummyController extends AppController { var $uses = array(); }
+
+class AppControllerTest extends UnitTestCase {
+
+ function testLoad() {
+ $this->helper =& new UnitTestHelper();
+
+ // Create dummy controller
+ $this->controller =& $this->helper->getController('Dummy', $this);
+ }
+
+ /**
+ * test array sanitization, values only (default)
+ */
+ function testSanitizeArrayValuesOnly() {
+ $testarray = array('abc' => array('some"quotes' => "a'b",
+ 'more' => 'quot"es'));
+ $sanitized = array('abc' => array('some"quotes' => 'a&#039;b',
+ 'more' => 'quot&quot;es'));
+
+ $this->controller->publish('testarray', $testarray);
+
+ $result = $this->controller->viewVars['testarray'];
+ $this->assertTrue($this->helper->array_compare_recursive($result, $sanitized),
+ 'array sanitization, default: values only');
+ }
+
+ /**
+ * test array sanitization, values and keys
+ */
+ function testSanitizeArrayValuesAndKeys() {
+ $testarray = array('abc' => array('some"quotes' => "a'b",
+ 'more' => 'quot"es'));
+ $sanitized = array('abc' => array('some&quot;quotes' => 'a&#039;b',
+ 'more' => 'quot&quot;es'));
+
+ $this->controller->publish('testarray', $testarray, true, true);
+
+ $result = $this->controller->viewVars['testarray'];
+ $this->assertTrue($this->helper->array_compare_recursive($result, $sanitized),
+ 'array sanitization, values and keys');
+ }
+
+ /**
+ * does sanitization leave an empty array intact?
+ */
+ function testPublishEmptyArray() {
+ $this->controller->publish('testarray', array());
+ $result = $this->controller->viewVars['testarray'];
+ $this->assertTrue(is_array($result) && empty($result), 'empty published array is preserved.');
+ }
+
+ /**
+ * does sanitization work on simple strings?
+ */
+ function testPublishString() {
+ $simplestring = 'blah"blah\'blah';
+ $sanitized = 'blah&quot;blah&#039;blah';
+ $this->controller->publish('teststring', $simplestring);
+ $result = $this->controller->viewVars['teststring'];
+ $this->assertEqual($result, $sanitized, 'simple string sanitization');
+ }
+
+ /**
+ * is the array left untouched when desired?
+ */
+ function testSanitizeDisabled() {
+ $testarray = array('abc' => array('some"quotes' => "a'b",
+ 'more' => 'quot"es'));
+ $this->controller->publish('testarray', $testarray, false);
+
+ $result = $this->controller->viewVars['testarray'];
+ $this->assertTrue($this->helper->array_compare_recursive($result, $testarray),
+ 'array sanitization can be disabled');
+ }
+}
+
+?>
diff --git a/site/app/tests/bot_reporter.php b/site/app/tests/bot_reporter.php
new file mode 100644
index 0000000..000e24d
--- /dev/null
+++ b/site/app/tests/bot_reporter.php
@@ -0,0 +1,41 @@
+<?php
+class BotReporter extends HtmlReporter {
+ var $testName;
+ var $show;
+ var $output;
+
+ function BotReporter($character_set = 'ISO-8859-1') {
+ parent::HtmlReporter($character_set);
+ }
+
+ function paintHeader($test_name) {
+ $this->output .= '<fails>';
+ }
+
+ function paintFooter($test_name) {
+ $this->output .= '</fails><results>';
+ $this->output .= $this->getTestCaseProgress() . '/' . $this->getTestCaseCount();
+ $this->output .= ' test cases complete - ';
+ $this->output .= $this->getPassCount() . ' passes, ';
+ $this->output .= $this->getFailCount() . ' fails and ';
+ $this->output .= $this->getExceptionCount() . ' exceptions';
+ $this->output .= '</results>';
+ }
+
+ function paintPass($message) {
+ parent::paintPass($message);
+ }
+
+ function paintFail($message) {
+ SimpleReporter::paintFail($message);
+ $breadcrumb = $this->getTestList();
+ $this->output .= "\n\t".$breadcrumb[3]." - ".$message;
+ }
+
+ function paintError($message) {
+ SimpleReporter::paintError($message);
+ }
+
+}
+
+?>
diff --git a/site/app/tests/cake_reporter.php b/site/app/tests/cake_reporter.php
new file mode 100644
index 0000000..be26b32
--- /dev/null
+++ b/site/app/tests/cake_reporter.php
@@ -0,0 +1,181 @@
+<?php
+/* SVN FILE: $Id: cake_reporter.php,v 1.1.1.1 2006/08/14 23:54:57 sancus%off.net Exp $ */
+/**
+ * Short description for file.
+ *
+ * Long description for file
+ *
+ * PHP versions 4 and 5
+ *
+ * CakePHP Test Suite <https://trac.cakephp.org/wiki/Developement/TestSuite>
+ * Copyright (c) 2006, Larry E. Masters Shorewood, IL. 60431
+ * Author(s): Larry E. Masters aka PhpNut <phpnut@gmail.com>
+ * Justin Scott aka fligtar <fligtar@gmail.com>
+ *
+ * Portions modifiied from WACT Test Suite
+ * Author(s): Harry Fuecks
+ * Jon Ramsey
+ * Jason E. Sweat
+ * Franco Ponticelli
+ * Lorenzo Alberton
+ *
+ * Licensed under The Open Group Test Suite License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @author Larry E. Masters aka PhpNut <phpnut@gmail.com>
+ * @copyright Copyright (c) 2006, Larry E. Masters Shorewood, IL. 60431
+ * @link http://www.phpnut.com/projects/
+ * @package tests
+ * @subpackage tests.libs
+ * @since CakePHP Test Suite v 1.0.0.0
+ * @version $Revision: 1.1.1.1 $
+ * @modifiedby $LastChangedBy: phpnut $
+ * @lastmodified $Date: 2006/08/14 23:54:57 $
+ * @license http://www.opensource.org/licenses/opengroup.php The Open Group Test Suite License
+ */
+/**
+ * Short description for class.
+ *
+ * @package tests
+ * @subpackage tests.libs
+ * @since CakePHP Test Suite v 1.0.0.0
+ */
+class CakeHtmlReporter extends HtmlReporter {
+ var $testName;
+ var $output = '';
+ var $header;
+
+/**
+ * Does nothing yet. The first output will
+ * be sent on the first test start. For use
+ * by a web browser.
+ * @access public
+ */
+ function CakeHtmlReporter($character_set = 'ISO-8859-1') {
+ parent::HtmlReporter($character_set);
+ }
+/**
+ * Paints the top of the web page setting the
+ * title to the name of the starting test.
+ * @param string $test_name Name class of test.
+ * @access public
+ */
+ function paintHeader($test_name) {
+ $this->testName = $test_name;
+ $this->header = '<div class="name">'.$test_name.'</div><br>';
+ }
+
+/**
+ * Creates link to SVN for file this test tests
+ */
+ function SVNLink($test_name = '') {
+ if (empty($test_name)) {
+ $test_name = $this->testName;
+ if (preg_match('/Test Case: (\S+)/i', $test_name, $matches)) {
+ $path = $matches[1];
+ }
+ }
+ else {
+ $path = str_replace(TESTS, '', $test_name);
+ }
+
+ if (!empty($path)) {
+ if (strpos($path, 'views') !== false) {
+ $name = str_replace('.test.php', '.thtml', $path);
+ }
+ else {
+ $name = str_replace('.test', '', $path);
+ }
+
+ $link = '<a class="svn" href="http://svn.mozilla.org/addons/trunk/site/app/'.$name.'">Test Subject</a>';
+ return $link;
+ }
+ }
+
+ function paintGroupStart($test_name, $size) {
+ parent::paintGroupStart($test_name, $size);
+
+ //If it has a space, it's very likely the header, so don't show it
+ if (strpos($test_name, ' ') !== false) {
+ return;
+ }
+
+ $header = str_replace(TESTS, '', $test_name);
+ $header = str_replace('//', '/', $header);
+
+ $this->output .= '<div class="groupdivider">';
+ $this->output .= '<div class="header">'.$header.'</div>';
+ $this->output .= '<div class="victim">'.$this->SVNLink($test_name).'</div>';
+ $this->output .= '</div>';
+ }
+
+/**
+ * Paints the end of the test with a summary of
+ * the passes and failures.
+ * @param string $test_name Name class of test.
+ * @access public
+ *
+ */
+ function paintFooter($test_name) {
+ $color = ($this->getFailCount() + $this->getExceptionCount() > 0 ? 'red' : 'green');
+ $results = '<div id="results" style="padding: 8px; margin-top: 1em; background-color: '.$color.'; color: white;">';
+ $results .= $this->getTestCaseProgress() . '/' . $this->getTestCaseCount();
+ $results .= ' test cases complete: ';
+ $results .= '<strong>' . $this->getPassCount() . '</strong> passes, ';
+ $results .= '<strong>' . $this->getFailCount() . '</strong> fails and ';
+ $results .= '<strong>' . $this->getExceptionCount() . '</strong> exceptions.';
+ $results .= '</div>';
+
+ $this->output = $this->header.$results.$this->output;
+ $this->output .= $results;
+ }
+
+ function paintPass($message) {
+ parent::paintPass($message);
+ if (!empty($_SESSION['Tests']['Passes']) && $_SESSION['Tests']['Passes'] === false) {
+ return;
+ }
+
+ $breadcrumb = $this->getTestList();
+ $this->output .= '<div class="pass"><span class="pass">PASS</span>: ';
+ $this->output .= $breadcrumb[3].' -> ';
+ $this->output .= $this->parseMessage($message);
+ $this->output .= '</div>';
+ }
+
+ function paintFail($message) {
+ SimpleReporter::paintFail($message);
+ $this->output .= '<div class="fail"><span class="fail">FAIL</span>: ';
+ $breadcrumb = $this->getTestList();
+ if (isset($_GET['group'])) {
+ $this->output .= $breadcrumb[2].' -> ';
+ }
+ $this->output .= $breadcrumb[3].' -> ';
+ $this->output .= $this->parseMessage($message);
+ $this->output .= '</div>';
+ }
+
+ function paintError($message) {
+ SimpleReporter::paintError($message);
+ $this->output .= '<div class="fail"><span class="fail">EXCEPTION</span>: ';
+ $breadcrumb = $this->getTestList();
+ if (isset($_GET['group'])) {
+ $this->output .= $breadcrumb[2].' -> ';
+ }
+ $this->output .= $breadcrumb[3].' -> ';
+ $this->output .= $this->parseMessage($message);
+ $this->output .= '</div>';
+ }
+
+ function parseMessage($message) {
+ if (preg_match('/(.*) at \['.str_replace(DS, '\\'.DS, TESTS).'(\S+) (line (\d+))\]/i', $message, $matches)) {
+ $memusage = function_exists('memory_get_usage') ? memory_get_usage() : ''; // some platforms don't have that
+ $message = $matches[1].' @ <a href="http://svn.mozilla.org/addons/trunk/site/app/tests/'.$matches[2].'#'.$matches[4].'">'.$matches[3].'</a> ('.$memusage.')<br>';
+ }
+ return $message;
+ }
+
+}
+
+?>
diff --git a/site/app/tests/controllers/addons_controller.test.php b/site/app/tests/controllers/addons_controller.test.php
new file mode 100644
index 0000000..95b08e6
--- /dev/null
+++ b/site/app/tests/controllers/addons_controller.test.php
@@ -0,0 +1,117 @@
+<?php
+
+class AddonsTest extends UnitTestCase {
+
+ function testLoad() {
+ $this->helper =& new UnitTestHelper();
+ $this->controller = $this->helper->getController('Addons', $this);
+ $this->helper->mockComponents($this->controller, $this);
+ }
+
+ function testDisplay() {
+ $this->controller->status = array(STATUS_PUBLIC);
+ $this->controller->params['controller'] = 'Addons';
+ $output = $this->helper->callControllerAction($this->controller, 'display', $this, array(7));
+ $this->assertWantedPattern('/Harvest MicroFormats from web pages/', $output);
+ }
+
+ function countOtherAddons($item, $key, $params) {
+ $count = &$params[0];
+
+ if (is_array($item)) {
+ array_walk($item, array(&$this, 'countOtherAddons'), $params);
+ } else {
+ if ($key === 'summary' && !($item == 'Harvest MicroFormats from web pages with the click of a button.' || $item == '' || $item == 'en-US' || $item == 53)) {
+ $count++;
+ }
+ }
+
+ }
+
+ /**
+ * This tests that no addons other than #7 have data loaded by checking for "summary" data
+ */
+ function testNoExcessiveRetrieval() {
+ $this->helper->callControllerAction($this->controller, 'display', $this, array(7));
+ $count = 0;
+ array_walk($this->controller->viewVars, array(&$this, 'countOtherAddons'), array(&$count));
+
+ $this->assertEqual($count, 0, "no other addons loaded: %s");
+ }
+
+ function testSandboxedVersionsNotListed() {
+ $this->helper->callControllerAction($this->controller, 'display', $this, array(4022));
+ $this->assertEqual($this->controller->viewVars['addon']['Version'][0]['File'][0]['status'], STATUS_PUBLIC, 'only showing public versions: %s');
+ }
+ function testSandboxVersionsExcludedInPublicVersionList() {
+ $count = 0;
+ $this->helper->callControllerAction($this->controller, 'versions', $this, array(4022));
+ foreach ($this->controller->viewVars['versions'] as $version) {
+ foreach ($version['File'] as $file) {
+ if ($file['status'] != STATUS_PUBLIC)
+ $count++;
+ }
+ }
+ $this->assertEqual($count, 0, 'sandboxed versions in public list: %s');
+ }
+ function testNoSandboxDisplayForVersions() {
+ $this->helper->callControllerAction($this->controller, 'versions', $this, array(4023));
+ $this->assertTrue(empty($this->controller->viewVars['versions']));
+ }
+ function nyi_testSandboxedVersionsListedWhenViewingSandbox() {
+
+ }
+
+ /**
+ * Test if the different addon list sort orders are correct
+ */
+ function testListSortOrders() {
+ $all_expected_results = array(
+ 'name' => array(4022, 7, 4021),
+ 'popular' => array(7, 4021, 4022),
+ 'updated' => array(4021, 4022, 7),
+ 'rated' => array(4022, 7, 4021),
+ 'newest' => array(4022, 4021, 7),
+ );
+
+ $this->controller->Pagination->setReturnvalue('init', array(0, 10, 1));
+ $this->controller->status = array(STATUS_PUBLIC);
+ $this->controller->sandboxAccess = false;
+
+ foreach (array_keys($all_expected_results) as $sort_by) {
+ $expected_results = $all_expected_results[$sort_by];
+ $num_results = count($expected_results);
+
+ // prepare controller, then fetch its results
+ $url = '/'.LANG.'/'.APP_SHORTNAME."/browse/type:1/cat:all/sort:{$sort_by}";
+ $this->controller->params['url']['url'] = $url;
+ $this->controller->namedArgs = array('type' => '1', 'cat'=>'all', 'sort'=>$sort_by);
+ $this->controller->set('paging', array(
+ 'sortBy' => $sort_by,
+ 'direction' => '',
+ 'pageCount' => 1,
+ 'url' => $url,
+ 'showLimits' => true,
+ 'maxPages' => 10,
+ 'paramSeperator' => '/',
+ 'show' => 10,
+ 'page' => 1,
+ 'total' => count($expected_results),
+ 'resultsPerPage' => array(5),
+ 'paramStyle' => 'get',
+ 'ajaxDivUpdate' => 'content',
+ ));
+ $this->helper->callControllerAction($this->controller, 'browse', $this);
+
+ $addons = $this->controller->viewVars['addons'];
+ $this->assertEqual(count($addons), $num_results, $sort_by . ' sorting: received the correct number of addons');
+ foreach ($addons as $addon) {
+ $expected_id = array_shift($expected_results);
+ $this->assertEqual($addon['Addon']['id'], $expected_id, $sort_by . " sorting: correct addon id {$addon['Addon']['id']} received");
+ }
+ }
+ }
+
+}
+
+?>
diff --git a/site/app/tests/controllers/admin_controller.test.php b/site/app/tests/controllers/admin_controller.test.php
new file mode 100644
index 0000000..1088e34
--- /dev/null
+++ b/site/app/tests/controllers/admin_controller.test.php
@@ -0,0 +1,71 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * Mike Morgan <morgamic@mozilla.com>.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+class AdminControllerTest extends UnitTestCase {
+
+ /**
+ * Setup memcaching model and admin controller
+ */
+ function testLoad() {
+ $this->helper = new UnitTestHelper();
+ $this->controller = $this->helper->getController('Admin', $this);
+ loadModel('Memcaching');
+ $this->memcache =& new Memcaching();
+ }
+
+ /**
+ * Tests flushing of memcache entries
+ */
+ function testServerflush() {
+ global $memcache_config;
+ $this->assertTrue(!empty($memcache_config), 'Memcache config exists');
+ $this->assertTrue(class_exists('Memcache'), 'Memcache class exists');
+ $this->assertTrue(class_exists('Memcaching') && $this->memcache->memcacheConnected, 'Memcaching class exists and is loaded');
+
+ // Set an arbitrary key.
+ $this->memcache->set('foo','bar');
+
+ // Verify that it's there.
+ $this->assertEqual($this->memcache->get('foo'),'bar','Key exists after set() call');
+
+ // Flush it.
+ $this->memcache->flush();
+
+ // Get same key, and assert that it does not return anything, trying more than one server.
+ $this->assertFalse($this->memcache->get('foo'),'No key exists after flush');
+ }
+}
+?>
diff --git a/site/app/tests/controllers/api_controller.test.php b/site/app/tests/controllers/api_controller.test.php
new file mode 100644
index 0000000..e3a6ef2
--- /dev/null
+++ b/site/app/tests/controllers/api_controller.test.php
@@ -0,0 +1,33 @@
+<?php
+
+class ApiControllerTest extends WebTestHelper {
+
+ function setUp() {
+
+ $this->helper = new UnitTestHelper();
+ $this->controller = $this->helper->getController('Api', $this);
+ loadModel('Config');
+ $this->Config =& new Config();
+ $this->Config->caching = False;
+ $this->Config->cacheQueries = False;
+
+ // Store the old value so we can reset it in teardown.
+ $this->_oldVal = $this->Config->getValue('api_disabled');
+ // Make sure the api is disabled.
+ $this->Config->save(array('key' => 'api_disabled',
+ 'value' => '1'));
+ // Clear out the config cache.
+ $this->Config->expire();
+ }
+
+ function tearDown() {
+ $this->Config->save(array('key' => 'api_disabled',
+ 'value' => $this->_oldVal));
+ }
+
+ function testApiDisabled() {
+ $this->assertEqual($this->Config->getValue('api_disabled'), 1);
+ $this->getAction('/api/list_addons');
+ $this->assertResponse('503');
+ }
+}
diff --git a/site/app/tests/controllers/compatibility_controller.test.php b/site/app/tests/controllers/compatibility_controller.test.php
new file mode 100644
index 0000000..bdf73d3
--- /dev/null
+++ b/site/app/tests/controllers/compatibility_controller.test.php
@@ -0,0 +1,31 @@
+<?php
+
+
+class CompatTest extends UnitTestCase {
+
+ function testLoad() {
+ $this->helper = new UnitTestHelper();
+ $this->controller = $this->helper->getController('Compatibility', $this);
+ $this->helper->mockComponents($this->controller, $this);
+ }
+
+ /* Helper to get a totals array. */
+ function assert100($other, $alpha, $beta, $latest, $outof) {
+ $t = array('adu95' => $outof);
+ $t[COMPAT_OTHER]['adu'] = $other;
+ $t[COMPAT_ALPHA]['adu'] = $alpha;
+ $t[COMPAT_BETA]['adu'] = $beta;
+ $t[COMPAT_LATEST]['adu'] = $latest;
+
+ $percentages = $this->controller->_percentages($t);
+ $this->assertEqual(100, array_sum($percentages));
+ }
+
+ function testPercentages() {
+ /* The sum of the percentages should always be 100. */
+ $this->assert100(1, 2, 3, 4, 10); // Even
+ $this->assert100(1, 2, 3, 3, 9); // Over
+ $this->assert100(3, 3, 4, 9, 19); // Under
+ }
+}
+?>
diff --git a/site/app/tests/controllers/components/amo.test.php b/site/app/tests/controllers/components/amo.test.php
new file mode 100644
index 0000000..00442d9
--- /dev/null
+++ b/site/app/tests/controllers/components/amo.test.php
@@ -0,0 +1,122 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * Justin Scott <fligtar@gmail.com>.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Frederic Wenzel <fwenzel@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+class AmoTest extends UnitTestCase {
+
+ //Setup the Amo Component
+ function setUp() {
+ $this->controller =& new AppController();
+ loadComponent('Amo');
+ $this->controller->Amo =& new AmoComponent();
+ $this->controller->Amo->startup($this->controller);
+ }
+
+ /**
+ * Test the checkOwnership() method
+ */
+ function testCheckOwnership() {
+ return $this->pass('Skipping XFAIL');
+
+ $this->fail('Method not yet operational');
+ }
+
+ /**
+ * Test the clean() method
+ */
+ function testClean() {
+ $array = array(
+ 'test1' => '<script language="JavaScript">alert("BAD THINGS!");</script>',
+ 'test2' => 'Tyla\'s attendance at the "Quote Convention" was plagued by morgamic\'s suggestive outfits.'
+ );
+ $shouldbe = array(
+ 'test1' => 'alert(\"BAD THINGS!\");',
+ 'test2' => 'Tyla\\\'s attendance at the \"Quote Convention\" was plagued by morgamic\\\'s suggestive outfits.'
+ );
+
+ // test cleaning a whole array
+ $dirty = array();
+ $dirty['test1'] = $array['test1'];
+ $dirty['test2'] = $array['test2'];
+ $this->controller->Amo->clean($dirty);
+
+ //Check for HTML stripping
+ $this->assertEqual($dirty['test1'], $shouldbe['test1'], 'HTML stripped (array): %s');
+ //Check for SQL quote escape
+ $this->assertEqual($dirty['test2'], $shouldbe['test2'], 'SQL quotes escaped (array): %s');
+
+
+ // test cleaning individual strings
+ $str1 = $array['test1'];
+ $str2 = $array['test2'];
+ $this->controller->Amo->clean($str1);
+ $this->assertEqual($str1, $shouldbe['test1'], 'HTML stripped (string): %s');
+
+ $this->controller->Amo->clean($str2);
+ $this->assertEqual($str2, $shouldbe['test2'], 'SQL quotes escaped (string): %s');
+ }
+
+ /**
+ * Test Approval Status strings
+ */
+ function testGetApprovalStatus() {
+ $array = $this->controller->Amo->getApprovalStatus();
+ $this->assertIsA($array, 'array');
+ for ($s = 0; $s <= 6; $s++) {
+ $this->assertEqual($this->controller->Amo->getApprovalStatus("$s"), $array[$s], 'Approval Status: %s');
+ }
+ }
+
+ /**
+ * Test Platform retrieval
+ */
+ function testGetPlatformName() {
+ $array = $this->controller->Amo->getPlatformName();
+ $this->assertIsA($array, 'array');
+ foreach ($array as $id=>$platform) {
+ $this->assertEqual($this->controller->Amo->getPlatformName($id), $array[$id], 'Platform string: %s');
+ }
+ }
+
+ /**
+ * Test the getApplicationName() method
+ */
+ function testGetApplicationName() {
+ //$this->assertEqual($this->controller->Amo->getApplicationName(1), 'Firefox', 'Application name string: %s');
+ //$this->assertEqual($this->controller->Amo->getApplicationName(2), 'Thunderbird', 'Application name string: %s');
+ }
+}
+?>
diff --git a/site/app/tests/controllers/components/audit.test.php b/site/app/tests/controllers/components/audit.test.php
new file mode 100644
index 0000000..0259788
--- /dev/null
+++ b/site/app/tests/controllers/components/audit.test.php
@@ -0,0 +1,286 @@
+<?php
+
+Mock::generate('SessionComponent');
+Mock::generate('SimpleAclComponent');
+Mock::generate('AmoComponent');
+
+class AuditTest extends UnitTestCase {
+
+ function setUp() {
+ $this->controller =& new AppController();
+ loadComponent('Audit');
+ $this->controller->Audit =& new AuditComponent();
+ $this->controller->Audit->startup($this->controller);
+
+ $this->controller->User =& new User();
+ $this->controller->Addon =& new Addon();
+ $this->controller->Group =& new Group();
+ $this->controller->Application =& new Application();
+ $this->controller->Tag =& new Tag();
+ $this->controller->Platform =& new Platform();
+ $this->controller->Feature =& new Feature();
+ $this->controller->Cannedresponse =& new Cannedresponse();
+
+ $this->controller->Session =& new MockSessionComponent();
+ $this->controller->SimpleAcl =& new MockSimpleAclComponent();
+ $this->controller->Amo =& new AmoComponent();
+
+ $this->user_id = 3;
+ $user = $this->controller->User->findById($this->user_id);
+ $this->userName = $user['User']['firstname'].' '.$user['User']['lastname'];
+ $this->user = $this->link($this->userName, '/users/info/'.$this->user_id);
+ $this->adminUser = $this->link($this->userName, '/admin/users/'.$this->user_id);
+
+
+ $this->addon_id = 7;
+ $addon = $this->controller->Addon->findById($this->addon_id);
+ $name = $addon['Translation']['name']['string'];
+ $this->addonIdLink = $this->link($this->addon_id, '/addon/'.$this->addon_id);
+ $this->addonStatusLink = $this->link($addon['Translation']['name']['string'],
+ '/admin/addons/status/'.$this->addon_id);
+
+ $this->review_id = 1;
+
+ $this->group_id = 1;
+ $group = $this->controller->Group->findById($this->group_id);
+ $this->groupLink = $this->link($group['Group']['name'], '/admin/groups');
+ }
+
+ function makeLog($type, $action, $kwargs) {
+ $log = array('type' => $type, 'action' => $action,
+ 'user_id' => $this->user_id, 'created' => 0);
+ $log = array_merge($log, $kwargs);
+ return array('Eventlog' => $log);
+ }
+
+ /**
+ * @param string type: the Eventlog type
+ * @param [(array, string)] actions: list of (kwargs, expected) pairs.
+ The kwargs are passed to `makeLog`.
+ */
+ function checkLogs($type, $actions) {
+ foreach($actions as $action=>$params) {
+ $kwargs = $params[0];
+ $expected = $params[1];
+ $log = $this->makeLog($type, $action, $kwargs);
+ $actual = $this->controller->Audit->explainLog(array($log));
+ $this->assertEqual($actual[0]['entry'], $expected);
+ }
+ }
+
+ function link($title, $url) {
+ return "<a href=\"{$this->controller->url($url)}\">{$title}</a>";
+ }
+
+ function testExplainLogEditor() {
+ $actions = array(
+ 'feature_add' => array(
+ array('added' => $this->addon_id),
+ "{$this->user} added addon {$this->addonIdLink} to feature list",
+ ),
+ 'feature_remove' => array(
+ array('removed' => $this->addon_id),
+ "{$this->user} removed addon {$this->addonIdLink} from feature list",
+ ),
+ 'feature_locale_change' => array(
+ array('changed_id' => $this->addon_id),
+ "{$this->user} changed locales for addon {$this->addonIdLink} on feature list",
+ ),
+ 'review_approve' => array(
+ array('changed_id' => $this->review_id),
+ "{$this->user} approved review {$this->review_id}",
+ ),
+ # TODO: check with SimpleAcl->actionAllowed = True
+ 'review_delete' => array(
+ array('changed_id' => $this->review_id),
+ "{$this->user} deleted review {$this->review_id}",
+ ),
+ );
+ $this->checkLogs('editor', $actions);
+ }
+
+ function testExplainLogL10n() {
+ $lang = 'lang';
+ $kwargs = array('notes' => $lang);
+ $link = $this->link($lang, "/localizers/%s/?userlang=${lang}");
+ $appLink = sprintf($link, 'applications');
+ $tagLink = sprintf($link, 'tags');
+ $platformLink = sprintf($link, 'platforms');
+
+ $actions = array(
+ 'update_applications' => array(
+ $kwargs,
+ "{$this->user} updated application translations for {$appLink}",
+ ),
+ 'update_tags' => array(
+ $kwargs,
+ "{$this->user} updated category translations for {$tagLink}",
+ ),
+ 'update_platforms' => array(
+ $kwargs,
+ "{$this->user} updated platform translations for {$platformLink}",
+ ),
+ 'update_blog' => array(
+ $kwargs,
+ "{$this->user} updated blog post translations for {$platformLink}",
+ ),
+ );
+ $this->checkLogs('l10n', $actions);
+ }
+
+ function testExplainLogSecurity() {
+ $notes = 'bla';
+
+ $actions = array(
+ 'reauthentication_failure' => array(
+ array('notes' => $notes),
+ "{$this->user} failed to re-authenticate to access {$notes}.",
+ ),
+ 'modify_locked_group' => array(
+ array('changed_id' => $this->group_id),
+ "{$this->user} attempted to modify locked group {$this->groupLink}",
+ ),
+ 'modify_other_locale' => array(
+ array('notes' => $notes),
+ "{$this->user} attempted to modify translations in {$notes} without permission",
+ ),
+ );
+ $this->checkLogs('security', $actions);
+ }
+
+ function testExplainLogUser() {
+ $actions = array(
+ 'group_associated' => array(
+ array('changed_id' => $this->group_id),
+ "{$this->user} associated themselves with {$this->groupLink}",
+ )
+ );
+ $this->checkLogs('user', $actions);
+ }
+
+ function testExplainLogAdmin() {
+ $app_id = 1;
+ $app = $this->controller->Application->findById($app_id);
+ $appLink = $this->link($app['Translation']['name']['string'],
+ '/admin/applications');
+
+ $tag_id = 1;
+ $tag = $this->controller->Tag->findById($tag_id);
+ $tagLink = $this->link($tag['Translation']['name']['string'],
+ '/admin/tags');
+
+ $platform_id = 1;
+ $platform = $this->controller->Platform->findById($platform_id);
+ $platformLink = $this->link($platform['Translation']['name']['string'],
+ '/admin/platforms');
+
+ $feature_id = 1;
+ $feature = $this->controller->Feature->findById($feature_id);
+
+ $response_id = 1;
+ $response = $this->controller->Cannedresponse->findById($response_id);
+ $responseLink = $this->link($response['Translation']['name']['string'],
+ '/admin/responses');
+
+ $actions = array(
+ 'addon_status' => array(
+ array('added' => $this->addon_id, 'changed_id' => $this->addon_id),
+ "{$this->user} changed the status of {$this->addonStatusLink} to Unknown",
+ ),
+ 'file_recalchash' => array(
+ array('changed_id' => $this->addon_id),
+ "{$this->user} recalculated the hash for file {$this->addon_id}",
+ ),
+ 'application_create' => array(
+ array('changed_id' => $app_id),
+ "{$this->user} created application {$appLink}",
+ ),
+ 'application_edit' => array(
+ array('changed_id' => $app_id),
+ "{$this->user} edited application {$appLink}",
+ ),
+ 'appversion_create' => array(
+ array('notes' => $app_id, 'added' => $app_id),
+ "{$this->user} created version {$app_id} for {$appLink}",
+ ),
+ 'appversion_delete' => array(
+ array('notes' => $app_id, 'removed' => $app_id),
+ "{$this->user} deleted version {$app_id} for {$appLink}",
+ ),
+ 'tag_create' => array(
+ array('changed_id' => $tag_id),
+ "{$this->user} created tag {$tagLink}",
+ ),
+ 'tag_edit' => array(
+ array('changed_id' => $tag_id),
+ "{$this->user} edited category {$tagLink}",
+ ),
+ 'tag_delete' => array(
+ array('changed_id' => $tag_id, 'removed' => $tag_id),
+ "{$this->user} deleted category {$tag_id} (ID {$tag_id})",
+ ),
+ 'platform_create' => array(
+ array('changed_id' => $platform_id),
+ "{$this->user} created platform {$platformLink}",
+ ),
+ 'platform_edit' => array(
+ array('changed_id' => $platform_id),
+ "{$this->user} edited platform {$platformLink}",
+ ),
+ 'platform_delete' => array(
+ array('changed_id' => $platform_id, 'removed' => $platform_id),
+ "{$this->user} deleted platform {$platform_id} (ID {$platform_id})",
+ ),
+ 'feature_edit' => array(
+ array('changed_id' => $feature_id),
+ "{$this->user} changed a feature for {$feature['Feature']['locale']} locale",
+ ),
+ 'feature_remove' => array(
+ array('removed' => $feature_id),
+ "{$this->user} removed feature {$feature_id}",
+ ),
+ 'group_create' => array(
+ array('changed_id' => $this->group_id),
+ "{$this->user} created group {$this->groupLink}",
+ ),
+ 'group_edit' => array(
+ array('changed_id' => $this->group_id),
+ "{$this->user} edited group {$this->groupLink}",
+ ),
+ 'group_delete' => array(
+ array('changed_id' => $this->group_id, 'removed' => $this->group_id),
+ "{$this->user} deleted group {$this->group_id} (ID {$this->group_id})",
+ ),
+ 'group_addmember' => array(
+ array('changed_id' => $this->group_id, 'added' => $this->user_id),
+ "{$this->user} added {$this->adminUser} to group {$this->groupLink}",
+ ),
+ 'group_removemember' => array(
+ array('changed_id' => $this->group_id, 'removed' => $this->user_id),
+ "{$this->user} removed {$this->adminUser} from group {$this->groupLink}",
+ ),
+ 'response_create' => array(
+ array('changed_id' => $response_id),
+ "{$this->user} created response {$responseLink}",
+ ),
+ 'response_edit' => array(
+ array('changed_id' => $response_id),
+ "{$this->user} edited response {$responseLink}",
+ ),
+ 'response_delete' => array(
+ array('changed_id' => $response_id, 'removed' => $response_id),
+ "{$this->user} deleted response {$response_id} (ID {$response_id})",
+ ),
+ 'config' => array(
+ array('field' => 'foo', 'removed' => 1, 'added' => 2),
+ "{$this->user} changed config 'foo' from '1' to '2'",
+ ),
+ 'user_edit' => array(
+ array('changed_id' => $this->user_id),
+ "{$this->user} edited {$this->adminUser}'s user information",
+ ),
+ );
+ $this->checkLogs('admin', $actions);
+ }
+}
+?>
diff --git a/site/app/tests/controllers/components/developers.test.php b/site/app/tests/controllers/components/developers.test.php
new file mode 100644
index 0000000..118195b
--- /dev/null
+++ b/site/app/tests/controllers/components/developers.test.php
@@ -0,0 +1,420 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * Justin Scott <fligtar@gmail.com>.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Frederic Wenzel <fwenzel@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+class DevelopersTest extends UnitTestCase {
+
+ //Setup the Developers Component
+ function setUp() {
+ $this->controller =& new AppController();
+ loadComponent('Developers');
+ $this->controller->Developers =& new DevelopersComponent();
+ $this->controller->Developers->startup($this->controller);
+ loadComponent('Error');
+ $this->controller->Error =& new ErrorComponent();
+ $this->controller->Error->startup($this->controller);
+ loadComponent('Amo');
+ $this->controller->Amo =& new AmoComponent();
+ $this->controller->Amo->startup($this->controller);
+ }
+
+ /**
+ * Test the validateTags() method
+ */
+ function testValidateTags() {
+ $this->controller->Tag =& new Tag();
+
+ //Test selecting valid number of categories
+ $this->assertTrue($this->controller->Developers->validateTags(array('1', '2', '3', '4', '5')), 'Select valid number of categories (return true)');
+ $this->assertEqual($this->controller->Error->errors['Tag/Tag'], null, 'Select valid number of categories (error string)');
+
+ //Test selecting no categories
+ $this->assertFalse($this->controller->Developers->validateTags(array()), 'Must select at least one category (return false)');
+ $this->assertEqual($this->controller->Error->errors['Tag/Tag'], 'Please select at least one category.', 'Must select at least one category (error string): %s');
+
+ //Test selecting many categories
+ $this->assertFalse($this->controller->Developers->validateTags(array('1', '2', '3', '4', '5', '6')), 'Select no more than 5 categories (return false)');
+ $this->assertEqual($this->controller->Error->errors['Tag/Tag'], 'Please select no more than five categories.', 'Select no more than 5 categories (error string): %s');
+ }
+
+ /**
+ * Test the validateUsers() method
+ */
+ function testValidateUsers() {
+ $this->controller->User =& new User();
+
+ //Test removing duplicate authors
+ $array = array('1', '2', '1');
+ $this->assertTrue($this->controller->Developers->validateUsers($array), 'At least one author (return true)');
+ $this->assertEqual(count($array), 2, 'Duplicate authors removed');
+
+ //Test selecting no authors
+ $array = array();
+ $this->assertFalse($this->controller->Developers->validateUsers($array), 'Must select at least one author (return false)');
+ $this->assertEqual($this->controller->Error->errors['User/User'], 'There must be at least one author for this add-on.', 'Must select at least one author (error string): %s');
+ }
+
+ /**
+ * Test the getTags() method
+ */
+ function testGetTags() {
+ $this->controller->Tag =& new Tag();
+
+ //Get all tags for extensions
+ $testArray = $this->controller->Developers->getTags(ADDON_EXTENSION, array(1));
+ $this->assertIsA($testArray, 'Array', 'Retrieved tags for addon type');
+ }
+
+ /**
+ * Test the getSelectedTags() method
+ */
+ function testGetSelectedTags() {
+ $this->controller->Tag =& new Tag();
+
+ //Test order of selected tags - none selected
+ $testArray = $this->controller->Developers->getSelectedTags(null);
+ $this->assertTrue(empty($testArray), 'No selected tags');
+
+ //Current tags in database
+ $currentTags = array(
+ array(
+ 'id' => '15',
+ 'name' => 'Test'
+ )
+ );
+ $testArray = $this->controller->Developers->getSelectedTags($currentTags);
+ $this->assertTrue(in_array(15, $testArray), 'Database selected tags');
+
+ //Post data selected tags
+ $this->controller->data['Tag']['Tag'][] = 20;
+ $testArray = $this->controller->Developers->getSelectedTags($currentTags);
+ $this->assertTrue(in_array(20, $testArray), 'POST data selected tags');
+
+ }
+
+ /**
+ * Test the getAuthors() method
+ */
+ function testGetAuthors() {
+ $this->controller->User =& new User();
+
+ //Test order of selected users - none selected
+ $testArray = $this->controller->Developers->getAuthors(null, false);
+ $this->assertTrue(empty($testArray), 'No selected users');
+
+ //Current users in database
+ $currentUsers = array(
+ array(
+ 'id' => '15',
+ 'firstname' => 'Filliam',
+ 'lastname' => 'Muffman',
+ 'email' => 'fmuffman@excite.com'
+ )
+ );
+ $testArray = $this->controller->Developers->getAuthors($currentUsers, false);
+ $this->assertEqual($testArray[15], 'Filliam Muffman [fmuffman@excite.com]', 'Database selected users');
+
+ //Post data selected users
+ $this->controller->data['User']['User'][] = 20;
+ $testArray = $this->controller->Developers->getAuthors($currentUsers, false);
+ $this->assertTrue($testArray[20], 'POST data selected users');
+
+ }
+
+ /**
+ * Resets the file information to a valid state and clears the errors from previous instance
+ */
+ function setupValidateFiles() {
+ $this->controller->Error->resetErrors();
+
+ $this->controller->data['Addon']['addontype_id'] = ADDON_EXTENSION;
+ $this->controller->data['File']['file1']['name'] = 'extension-works.xpi';
+ $this->controller->data['File']['file1']['tmp_name'] = TEST_DATA.'/extension-works.xpi';
+ $this->controller->data['File']['file1']['size'] = 0;
+ $this->controller->data['File']['file1']['error'] = 0;
+ $this->controller->data['File']['platform_id1'] = '1';
+ }
+
+ /**
+ * Test the validateFiles() method
+ */
+ function testValidateFiles() {
+
+ $this->controller->File =& new File();
+
+ //Make sure file is uploaded
+ $this->setupValidateFiles();
+ $this->controller->data['File']['file1']['name'] = '';
+ $this->controller->Developers->validateFiles();
+ $this->assertEqual($this->controller->Error->errors['File/file1'], 'Please upload a file.', 'No file uploaded: %s');
+
+ //Make sure platform selected and file extensions are checked
+ $this->setupValidateFiles();
+
+ $this->controller->data['File']['platform_id1'] = '';
+ $this->controller->data['File']['file1']['name'] = 'badextension.exe';
+ $this->controller->Developers->validateFiles();
+ $this->assertEqual($this->controller->Error->errors['File/platform_id1'], 'No platform selected', 'No platform selected: %s');
+ $this->assertEqual($this->controller->Error->errors['File/file1'], 'That file extension (.exe) is not allowed for the selected add-on type. Please use one of the following: .xpi', 'Disallowed file extension: %s');
+
+ //HTTP errors - file upload size (http)
+ $this->setupValidateFiles();
+ $this->controller->data['File']['file1']['error'] = 1;
+ $this->controller->Developers->validateFiles();
+ $this->assertEqual($this->controller->Error->errors['File/file1'], 'Exceeds maximum upload size', 'HTTP File Error: HTTP max upload size: %s');
+
+ //HTTP errors - file upload size (php)
+ $this->setupValidateFiles();
+ $this->controller->data['File']['file1']['error'] = 2;
+ $this->controller->Developers->validateFiles();
+ $this->assertEqual($this->controller->Error->errors['File/file1'], 'Exceeds maximum upload size', 'HTTP File Error: PHP max upload size: %s');
+
+ //HTTP errors - incomplete transfer
+ $this->setupValidateFiles();
+ $this->controller->data['File']['file1']['error'] = 3;
+ $this->controller->Developers->validateFiles();
+ $this->assertEqual($this->controller->Error->errors['File/file1'], 'Incomplete transfer', 'HTTP File Error: Incomplete transfer: %s');
+
+ //HTTP errors - no file uploaded
+ $this->setupValidateFiles();
+ $this->controller->data['File']['file1']['error'] = 4;
+ $this->controller->Developers->validateFiles();
+ $this->assertEqual($this->controller->Error->errors['File/file1'], 'No file uploaded', 'HTTP File Error: No file uploaded: %s');
+
+ //Could not move file
+ $this->setupValidateFiles();
+ $this->controller->Developers->validateFiles();
+ $this->assertEqual($this->controller->Error->errors['File/file1'], 'Could not move file');
+ }
+
+
+ /**
+ * Test validateIcon() icon method incl. the image data it produces
+ */
+ function testValidateIcon() {
+ $allowedImage = array('.png', '.jpg', '.gif');
+ $fileErrors = array('1' => _('devcp_error_http_maxupload'),
+ '2' => _('devcp_error_http_maxupload'),
+ '3' => _('devcp_error_http_incomplete'),
+ '4' => _('devcp_error_http_nofile')
+ );
+
+ /* test vector for extension tests */
+ $extTestVec = array(
+ 'base-image' => sprintf(_('devcp_error_icon_extension'), 'base-image', implode(', ', $allowedImage)),
+ 'base-image.xpi' => sprintf(_('devcp_error_icon_extension'), '.xpi', implode(', ', $allowedImage))
+ );
+
+ /* test image */
+ $fileSize = filesize(TEST_DATA.'/base-icon.png');
+ $baseFile = array(
+ 'name' => 'base-image.png',
+ 'tmp_name' => TEST_DATA.'/base-icon.png',
+ 'size' => $fileSize,
+ 'type'=> 'image/png',
+ 'error' => 0
+ );
+
+ /* test error processing */
+ for ($i = 1; $i < 5; $i++) {
+ $file = $baseFile;
+ $file['error'] = $i;
+ $resized = $this->controller->Developers->validateIcon($file, $fileErrors, $allowedImage);
+ $this->assertEqual($resized, $fileErrors[$i], '%s');
+ }
+
+ /* test allowed extensions */
+ foreach ($extTestVec as $name => $err) {
+ $file = $baseFile;
+ $file['name'] = $name;
+ $resized = $this->controller->Developers->validateIcon($file, $fileErrors, $allowedImage);
+ $this->assertEqual($resized, $err, '%s');
+ }
+
+ /* test correct output */
+ $file = $baseFile;
+
+ $resized = $this->controller->Developers->validateIcon($file, $fileErrors, $allowedImage);
+ $this->assertFalse(empty($resized) || empty($resized['icondata']), "failed to load image");
+
+ // XXX: better compare pixel-wise, but not sure how to achieve it at this point
+ // $fp = fopen(TEST_DATA.'/resized-icon.png', 'wb'); fwrite($fp, $resized['icondata']); fclose($fp);
+ $cmp = file_get_contents(TEST_DATA.'/resized-icon.png');
+ $this->assertEqual($resized['icondata'], $cmp, "resized icon data doesn't match provided image data");
+ }
+
+ /**
+ * Test the getAllowedExtensions() method
+ */
+ function testGetAllowedExtensions() {
+ $allowed = $this->controller->Developers->getAllowedExtensions(ADDON_EXTENSION);
+ $this->assertTrue(in_array('.xpi', $allowed), '.xpi files allowed for extensions');
+ $this->assertFalse(in_array('.jar', $allowed), '.jar files not allowed for extensions');
+
+ $allowed = $this->controller->Developers->getAllowedExtensions(ADDON_THEME);
+ $this->assertTrue(in_array('.xpi', $allowed), '.xpi files allowed for themes');
+ $this->assertTrue(in_array('.jar', $allowed), '.jar files allowed for themes');
+
+ $allowed = $this->controller->Developers->getAllowedExtensions(ADDON_SEARCH);
+ $this->assertTrue(in_array('.xml', $allowed), '.xml files allowed for search plugins');
+ $this->assertFalse(in_array('.xpi', $allowed), '.xpi files not allowed for search plugins');
+ }
+
+ /**
+ * Start each test with a valid install.rdf copy and add errors after
+ */
+ function setupValidateManifestData() {
+ $fileContents = file_get_contents(TEST_DATA.'/test-install.rdf');
+ $manifestData = $this->Rdf->parseInstallManifest($fileContents);
+
+ return $manifestData;
+ }
+
+ /**
+ * Test the validateManifestData() method
+ */
+ function testValidateManifestData() {
+ loadComponent('Rdf');
+ $this->Rdf =& new RdfComponent();
+ $this->controller->Application =& new Application();
+
+ //Test a valid manifest file
+ $manifestData = $this->setupValidateManifestData();
+ $this->assertTrue($this->controller->Developers->validateManifestData($manifestData), 'Valid manifest data (return true)');
+ $this->assertEqual($this->controller->Error->errors['main'], '', 'Valid manifest data (error string)');
+
+ //GUID of an application not allowed
+ $manifestData = $this->setupValidateManifestData();
+ $manifestData['id'] = '{ec8030f7-c20a-464f-9b0e-13a3a9e97384}';
+ $return = $this->controller->Developers->validateManifestData($manifestData);
+ $this->assertEqual($return, 'The ID of this add-on is already used by an application.', 'Using an application GUID: %s');
+
+ //Invalid GUID
+ $manifestData = $this->setupValidateManifestData();
+ $manifestData['id'] = '{B17C1C5A-04B1-11DB-9804-B622A1EF5}';
+ $return = $this->controller->Developers->validateManifestData($manifestData);
+ $this->assertEqual($return, 'The ID of this add-on is invalid: {B17C1C5A-04B1-11DB-9804-B622A1EF5}', 'Invalid GUID: %s');
+
+ //Invalid version
+ $manifestData = $this->setupValidateManifestData();
+ $manifestData['version'] = 'Bad Version';
+ $return = $this->controller->Developers->validateManifestData($manifestData);
+ $this->assertEqual($return, 'The version of this add-on is invalid: versions cannot contain spaces.', 'Invalid Version: %s');
+
+ //Invalid version - strange
+ $manifestData = $this->setupValidateManifestData();
+ $manifestData['version'] = '1#$$3k';
+ $return = $this->controller->Developers->validateManifestData($manifestData);
+ $this->assertEqual($return, 'The version of this add-on is invalid: please see the <a href="http://developer.mozilla.org/en/docs/Toolkit_version_format">specification</a>', 'Invalid Version: %s');
+
+ //updateURL present
+ $manifestData = $this->setupValidateManifestData();
+ $manifestData['updateURL'] = 'http://addons.mozilla.org';
+ $return = $this->controller->Developers->validateManifestData($manifestData);
+ $this->assertEqual($return, 'Add-ons cannot use an external updateURL. Please remove this from install.rdf and try again.', 'updateURL present: %s');
+
+ //updateKey present
+ $manifestData = $this->setupValidateManifestData();
+ $manifestData['updateKey'] = 'MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDK426erD';
+ $return = $this->controller->Developers->validateManifestData($manifestData);
+ $this->assertEqual($return, 'Add-ons cannot use an updateKey. Please remove this from install.rdf and try again.', 'updateKey present: %s');
+
+ //Parse error (any string = parse error)
+ $manifestData = 'Something was wrong!';
+ $return = $this->controller->Developers->validateManifestData($manifestData);
+ $this->assertEqual($return, 'The following error occurred while parsing install.rdf: Something was wrong!', 'Parse error: %s');
+
+ }
+
+ /**
+ * Setup valid target applications
+ */
+ function setupValidateTargetApplications() {
+ $this->controller->Error->errors['main'] = '';
+ $targetApps = array(
+ '{ec8030f7-c20a-464f-9b0e-13a3a9e97384}' => array(
+ 'minVersion' => '1.5',
+ 'maxVersion' => '3.0a1'
+ ),
+ '{3550f703-e582-4d05-9a08-453d09bdfdc6}' => array(
+ 'minVersion' => '1.5',
+ 'maxVersion' => '1.5'
+ )
+ );
+
+ return $targetApps;
+ }
+
+ /**
+ * Test validateTargetApplications() method
+ */
+ function testValidateTargetApplications() {
+ $this->controller->Application =& new Application();
+ $this->controller->Appversion =& new Appversion();
+
+ //Valid target applications
+ $targetApps = $this->setupValidateTargetApplications();
+ $this->assertIsA($this->controller->Developers->validateTargetApplications($targetApps), 'array', 'Valid target applications');
+
+ //Invalid versions
+ $targetApps = $this->setupValidateTargetApplications();
+ $targetApps['{ec8030f7-c20a-464f-9b0e-13a3a9e97384}']['minVersion'] = '42';
+ $targetApps['{ec8030f7-c20a-464f-9b0e-13a3a9e97384}']['maxVersion'] = '1337';
+ $return = $this->controller->Developers->validateTargetApplications($targetApps);
+ $this->assertEqual($return, 'The following errors were found in install.rdf:<br />42 is not a valid version for Firefox<br />1337 is not a valid version for Firefox<br />Please see <a href="/en-US/firefox/pages/appversions">this page</a> for reference.', 'Invalid versions: %s');
+
+ //Only Flock
+ $targetApps = $this->setupValidateTargetApplications();
+ unset($targetApps['{ec8030f7-c20a-464f-9b0e-13a3a9e97384}']);
+ unset($targetApps['{3550f703-e582-4d05-9a08-453d09bdfdc6}']);
+ $return = $this->controller->Developers->validateTargetApplications($targetApps);
+ $this->assertEqual($return, 'You must have at least one valid Mozilla target application.<br />Please see <a href="/en-US/firefox/pages/appversions">this page</a> for reference.', 'No Mozilla applications: %s');
+
+ //No applications at all
+ $targetApps = array();
+ $return = $this->controller->Developers->validateTargetApplications($targetApps);
+ $this->assertEqual($return, 'You must have at least one valid Mozilla target application.<br />Please see <a href="/en-US/firefox/pages/appversions">this page</a> for reference.', 'No applications at all: %s');
+
+ //Unknown application
+ $targetApps = $this->setupValidateTargetApplications();
+ $targetApps['{12345-12345}'] = array(
+ 'minVersion' => '1.0',
+ 'maxVersion' => '2.0'
+ );
+ $this->assertIsA($this->controller->Developers->validateTargetApplications($targetApps), 'array', 'Unknown application');
+ }
+}
+?>
diff --git a/site/app/tests/controllers/components/error.test.php b/site/app/tests/controllers/components/error.test.php
new file mode 100644
index 0000000..b77c8f4
--- /dev/null
+++ b/site/app/tests/controllers/components/error.test.php
@@ -0,0 +1,69 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * Justin Scott <fligtar@gmail.com>.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+class ErrorTest extends UnitTestCase {
+
+ //Setup the Src Component
+ function setUp() {
+ $this->controller =& new AppController();
+ loadComponent('Error');
+ $this->controller->Error =& new ErrorComponent();
+ $this->controller->Error->startup($this->controller);
+ }
+
+ /**
+ * Test addError() method
+ */
+ function testAddError() {
+ $this->controller->Error->addError('Something something', 'Test/test');
+ $this->controller->Error->addError('Something else!');
+ $this->assertEqual($this->controller->Error->errors['Test/test'], 'Something something', 'Add field error: %s');
+ $this->assertEqual($this->controller->Error->errors['main'], 'Something else!', 'Add main error: %s');
+ }
+
+ /**
+ * Test noErrors() method
+ */
+ function testNoErrors() {
+ $this->controller->Addon =& new Addon();
+
+ $this->assertTrue($this->controller->Error->noErrors(), 'Check for no errors');
+ $this->controller->Error->addError('Something something');
+ $this->assertFalse($this->controller->Error->noErrors(), 'Check for errors');
+ }
+
+}
+?> \ No newline at end of file
diff --git a/site/app/tests/controllers/components/image.test.php b/site/app/tests/controllers/components/image.test.php
new file mode 100644
index 0000000..b075a6f
--- /dev/null
+++ b/site/app/tests/controllers/components/image.test.php
@@ -0,0 +1,42 @@
+<?php
+
+class ImageTest extends WebTestHelper {
+ function setUp() {
+ global $TestController;
+ $this->helper = new UnitTestHelper();
+ $this->controller = $this->helper->getController('Addons', $this);
+ $this->controller->base = $TestController->base;
+ loadComponent('Image');
+ $this->controller->Image =& new ImageComponent();
+ $this->controller->Image->startup($this->controller);
+ }
+
+ function testAddonIcon() {
+ $url = $this->controller->Image->getAddonIconURL(7);
+ //The models tests change the modified time, so the timestamp isn't
+ //predictable; thus, only checking that the numbers are there.
+ $wantedPattern = "#".$this->actionPath('/images/addon_icon/7/\d{10}')."#";
+ UnitTestCase::assertPattern($wantedPattern, $url, htmlentities($wantedPattern));
+ $this->getPath($url);
+ $this->assertResponse('200');
+ $this->assertMime('image/gif');
+ }
+
+ function testAddonThumbnail() {
+ $url = $this->controller->Image->getHighlightedPreviewURL(7);
+ $this->assertEqual($url, $this->actionPath('/images/t/1/1159459234'));
+ $this->getPath($url);
+ $this->assertResponse('200');
+ $this->assertMime('image/png');
+ }
+
+ function testAddonPreview() {
+ $url = $this->controller->Image->getHighlightedPreviewURL(7, 'full');
+ $this->assertEqual($url, $this->actionPath('/images/p/1/1159459234'));
+ $this->getPath($url);
+ $this->assertResponse('200');
+ $this->assertMime('image/png');
+ }
+}
+
+?>
diff --git a/site/app/tests/controllers/components/opensearch.test.php b/site/app/tests/controllers/components/opensearch.test.php
new file mode 100644
index 0000000..d7c4fcf
--- /dev/null
+++ b/site/app/tests/controllers/components/opensearch.test.php
@@ -0,0 +1,349 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Gavin Sharp <gavin@gavinsharp.com> (Original author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+class OpensearchTest extends UnitTestCase {
+
+ function setUp() {
+ loadComponent('opensearch');
+ $this->Os =& new OpensearchComponent();
+ }
+
+ function testSherlockConversion() {
+ $data = '<OpenSearchDescription xmlns="http://a9.com/-/spec/opensearchdescription/1.1/">
+ <ShortName>OpenSearch Test</ShortName>
+ <Alias>OST</Alias>
+ <Description>This is a test plugin.</Description>
+ <InputEncoding>UTF-8</InputEncoding>
+ <Image width="16" height="16">data:image/x-icon;base64,Qk02AwAAAAAAADYAAAAoAAAAEAAAABAAAAABABgAAAAAAAADAAAAAAAAAAAAAAAAAAAAAAAA////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////AAAA////////AAAAAAAA////////AAAAAAAA////////AAAA////AAAA////////AAAA////AAAA////////////AAAA////////AAAA////AAAA////AAAA////////AAAA////AAAA////////////AAAA////////AAAA////AAAAAAAAAAAA////////AAAA////////AAAAAAAA////////AAAAAAAA////////AAAA////AAAA////////////////////////////////////////////////////////////////////////////AAAA////////////AAAA////AAAA////////AAAA////////////////////////AAAAAAAA////////AAAAAAAAAAAA////AAAA////AAAA////////////////////AAAA////////////AAAA////AAAA////AAAA////AAAA////////////////////AAAAAAAAAAAA////////AAAA////////AAAA////AAAA////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////</Image>
+ <Url type="text/html" method="get" template="http://test.template.url/search/">
+ <Param name="q" value="{searchTerms}"/>
+ <Param name="sourceid" value="firefox"/>
+ </Url>
+ <UpdateUrl>http://fake.update.url/</UpdateUrl>
+ <UpdateInterval>7</UpdateInterval>
+ <IconUpdateUrl>http://fake.icon.update.url/</IconUpdateUrl>
+ <UnknownTag>This tag shouldn\'t be included in the output.</UnknownTag>
+ </OpenSearchDescription>';
+ $expected = '<SEARCH
+ name="OpenSearch Test"
+ action="http://test.template.url/search/"
+ method="GET"
+ description="This is a test plugin."
+ queryCharset="UTF-8"
+>
+<input name="q" user>
+<input name="sourceid" value="firefox">
+</SEARCH>
+
+<BROWSER
+ update="http://fake.update.url/"
+ updateIcon="http://fake.icon.update.url/"
+ updateCheckDays="7"
+>
+';
+
+ $engine = $this->Os->parse($data);
+ $src = $engine->toSherlock();
+ $this->assertEqual($src, $expected, 'Basic plugin was serialized correctly');
+
+ $data = '<OpenSearchDescription xmlns="http://a9.com/-/spec/opensearchdescription/1.1/">
+ <ShortName>OpenSearch Test</ShortName>
+ <Url type="text/html" method="get" template="http://test.template.url/search/{searchTerms}"/>
+ </OpenSearchDescription>';
+ $expected = '<SEARCH
+ name="OpenSearch Test"
+ action="http://test.template.url/search/"
+ method="GET"
+>
+<input user>
+</SEARCH>
+';
+
+ $engine = $this->Os->parse($data);
+ $src = $engine->toSherlock();
+ $this->assertEqual($src, $expected, '"Append-to-tempate" plugin was serialized correctly');
+
+ $data = '<OpenSearchDescription xmlns="http://a9.com/-/spec/opensearchdescription/1.1/">
+ <ShortName>OpenSearch Test</ShortName>
+ <Url type="text/html" method="get" template="http://test.template.url/search/{searchTerms}/"/>
+ </OpenSearchDescription>';
+ $expected = NULL;
+
+ $engine = $this->Os->parse($data);
+ $src = $engine->toSherlock();
+ $this->assertEqual($src, $expected, 'Unsupported template');
+
+ $data = '<OpenSearchDescription xmlns="http://a9.com/-/spec/opensearchdescription/1.1/">
+ <ShortName>OpenSearch Test</ShortName>
+ <Url type="text/html" method="get" template="http://test.template.url/search/"/>
+ </OpenSearchDescription>';
+ $expected = NULL;
+
+ $engine = $this->Os->parse($data);
+ $src = $engine->toSherlock();
+ $this->assertEqual($src, $expected, 'No user input');
+ }
+
+ function testSimple() {
+ $data = '<OpenSearchDescription xmlns="http://a9.com/-/spec/opensearchdescription/1.1/">
+ <ShortName>OpenSearch Test</ShortName>
+ <Alias>OST</Alias>
+ <Description>This is a test plugin.</Description>
+ <InputEncoding>UTF-8</InputEncoding>
+ <Image width="16" height="16">data:image/x-icon;base64,Qk02AwAAAAAAADYAAAAoAAAAEAAAABAAAAABABgAAAAAAAADAAAAAAAAAAAAAAAAAAAAAAAA////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////AAAA////////AAAAAAAA////////AAAAAAAA////////AAAA////AAAA////////AAAA////AAAA////////////AAAA////////AAAA////AAAA////AAAA////////AAAA////AAAA////////////AAAA////////AAAA////AAAAAAAAAAAA////////AAAA////////AAAAAAAA////////AAAAAAAA////////AAAA////AAAA////////////////////////////////////////////////////////////////////////////AAAA////////////AAAA////AAAA////////AAAA////////////////////////AAAAAAAA////////AAAAAAAAAAAA////AAAA////AAAA////////////////////AAAA////////////AAAA////AAAA////AAAA////AAAA////////////////////AAAAAAAAAAAA////////AAAA////////AAAA////AAAA////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////</Image>
+ <Url type="text/html" method="get" template="http://test.template.url/search/">
+ <Param name="q" value="{searchTerms}"/>
+ <Param name="sourceid" value="firefox"/>
+ </Url>
+ <UpdateUrl>http://fake.update.url/</UpdateUrl>
+ <UpdateInterval>7</UpdateInterval>
+ <IconUpdateUrl>http://fake.icon.update.url/</IconUpdateUrl>
+ <UnknownTag>This tag shouldn\'t be included in the output.</UnknownTag>
+ </OpenSearchDescription>';
+
+ $engine = $this->Os->parse($data);
+ $this->assertEqual($engine->name, 'OpenSearch Test', 'Correct name');
+ $this->assertEqual($engine->alias, 'OST', 'Correct alias');
+ $this->assertEqual($engine->description, 'This is a test plugin.', 'Correct description');
+ $this->assertEqual($engine->inputEncoding, 'UTF-8', 'Correct inputencoding');
+ $this->assertEqual($engine->imageUrl, 'data:image/x-icon;base64,Qk02AwAAAAAAADYAAAAoAAAAEAAAABAAAAABABgAAAAAAAADAAAAAAAAAAAAAAAAAAAAAAAA////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////AAAA////////AAAAAAAA////////AAAAAAAA////////AAAA////AAAA////////AAAA////AAAA////////////AAAA////////AAAA////AAAA////AAAA////////AAAA////AAAA////////////AAAA////////AAAA////AAAAAAAAAAAA////////AAAA////////AAAAAAAA////////AAAAAAAA////////AAAA////AAAA////////////////////////////////////////////////////////////////////////////AAAA////////////AAAA////AAAA////////AAAA////////////////////////AAAAAAAA////////AAAAAAAAAAAA////AAAA////AAAA////////////////////AAAA////////////AAAA////AAAA////AAAA////AAAA////////////////////AAAAAAAAAAAA////////AAAA////////AAAA////AAAA////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////', 'Correct image');
+ $this->assertEqual($engine->updateUrl, 'http://fake.update.url/', 'Correct updateUrl');
+ $this->assertEqual($engine->iconUpdateUrl, 'http://fake.icon.update.url/', 'Correct iconUpdateUrl');
+ $this->assertEqual($engine->updateInterval, '7', 'Correct updateInterval');
+
+ $this->assertEqual($engine->urls['text/html']->method, 'GET', 'Correct URL Method');
+ $this->assertEqual($engine->urls['text/html']->template, 'http://test.template.url/search/', 'Correct URL Template');
+ }
+
+ function testSubstitution() {
+ $data = '<OpenSearchDescription xmlns="http://a9.com/-/spec/opensearchdescription/1.1/">
+ <ShortName>OpenSearch Test</ShortName>
+ <InputEncoding>Shift_JIS</InputEncoding>
+ <Url type="text/html" method="get" template="http://test.template.url/search/">
+ <Param name="inputEncoding" value="{inputEncoding}"/>
+ <Param name="outputEncoding" value="{outputEncoding}"/>
+ <Param name="language" value="{language}"/>
+ <Param name="startPage" value="{startPage}"/>
+ <Param name="startIndex" value="{startPage}"/>
+ <Param name="count" value="{count}"/>
+ <Param name="optional" value="{count?}"/>
+ <Param name="extended" value="{inputEncoding}appended"/>
+ </Url>
+ </OpenSearchDescription>';
+
+ $engine = $this->Os->parse($data);
+
+ $params = $engine->getParams('text/html');
+ $this->assertTrue($params, "Got params!");
+
+ $expected = array(array('inputEncoding', 'Shift_JIS'),
+ array('outputEncoding', 'UTF-8'),
+ array('language', '*'),
+ array('startPage', '1'),
+ array('startIndex', '1'),
+ array('count', '20'),
+ array('extended', 'Shift_JISappended'));
+ $this->assertEqual($params, $expected, "Parameters were correctly replaced");
+ }
+
+ function testURLs() {
+ $data = '<OpenSearchDescription xmlns="http://a9.com/-/spec/opensearch/1.0/">
+ <ShortName>OpenSearch Test</ShortName>
+ <Url type="text/html" method="get" template="http://test.template.url/search/">
+ <Param name="q" value="{searchTerms}"/>
+ <Param name="sourceid" value="firefox"/>
+ </Url>
+ <Url type="application/x-suggestions+json" method="get" template="http://test.template.url/suggest/">
+ <Param name="q" value="{searchTerms}"/>
+ <Param name="q2" value="{searchTerms}2"/>
+ <Param name="dupe" value="first"/>
+ <Param name="dupe" value="second"/>
+ </Url>
+ <Url type="x/unknown" method="get" template="http://test.template.url/unknown/">
+ <Param name="q" value="{searchTerms}"/>
+ <Param name="sourceid" value="firefox-unknown"/>
+ </Url>
+ </OpenSearchDescription>';
+
+ $engine = $this->Os->parse($data);
+ $this->assertEqual($engine->urls['text/html']->method, 'GET', 'Correct HTML URL Method');
+ $this->assertEqual($engine->urls['text/html']->template, 'http://test.template.url/search/', 'Correct HTML URL Template');
+ $this->assertEqual($engine->urls['text/html']->params[0], array('q', '{searchTerms}'), 'Correct HTML URL Param0');
+ $this->assertEqual($engine->urls['text/html']->params[1], array('sourceid', 'firefox'), 'Correct HTML URL Param1');
+ $this->assertEqual($engine->urls['application/x-suggestions+json']->method, 'GET', 'Correct Suggest URL Method');
+ $this->assertEqual($engine->urls['application/x-suggestions+json']->template, 'http://test.template.url/suggest/', 'Correct Suggest URL Template');
+ $this->assertEqual($engine->urls['application/x-suggestions+json']->params[0], array('q', '{searchTerms}'), 'Correct Suggest URL Param0');
+ $this->assertEqual($engine->urls['application/x-suggestions+json']->params[1], array('q2', '{searchTerms}2'), 'Correct Suggest URL Param1');
+ $this->assertEqual($engine->urls['application/x-suggestions+json']->params[2], array('dupe', 'first'), 'Correct Suggest URL Param2');
+ $this->assertEqual($engine->urls['application/x-suggestions+json']->params[3], array('dupe', 'second'), 'Correct Suggest URL Param3');
+ $this->assertEqual(count($engine->urls), 2, 'No other URLs');
+ $this->assertEqual(count($engine->urls['text/html']->params), 2, 'Correct number of params for text/html URL');
+ $this->assertEqual(count($engine->urls['application/x-suggestions+json']->params), 4, 'Correct number of params for suggest URL');
+
+ $data = '<OpenSearchDescription xmlns="http://a9.com/-/spec/opensearch/1.0/">
+ <ShortName>OpenSearch Test</ShortName>
+ <Url type="text/html" method="get" template="http://test.template.url/search1/">
+ <Param name="q" value="{searchTerms}-1"/>
+ <Param name="sourceid" value="firefox-1"/>
+ </Url>
+ <Url type="text/html" method="post" template="http://test.template.url/search2/">
+ <Param name="q" value="{searchTerms}-2"/>
+ <Param name="sourceid" value="firefox-2"/>
+ </Url>
+ </OpenSearchDescription>';
+ $engine = $this->Os->parse($data);
+ $this->assertEqual($engine->urls['text/html']->method, 'POST', 'Second method took precedence');
+ $this->assertEqual($engine->urls['text/html']->template, 'http://test.template.url/search2/', 'Second URL took precedence');
+ $this->assertEqual($engine->urls['text/html']->params[0], array('q', '{searchTerms}-2'), 'Second param0 took precedence');
+ $this->assertEqual($engine->urls['text/html']->params[1], array('sourceid', 'firefox-2'), 'Second param1 took precedence');
+ }
+
+ function testOverwrite() {
+ $data = '<OpenSearchDescription xmlns="http://a9.com/-/spec/opensearch/1.0/">
+ <ShortName>OpenSearch Test</ShortName>
+ <ShortName>Second OpenSearch Test</ShortName>
+ <Url type="text/html" method="get" template="http://test.template.url/search/">
+ <Param name="q" value="{searchTerms}"/>
+ <Param name="sourceid" value="firefox"/>
+ </Url>
+ </OpenSearchDescription>';
+
+ $engine = $this->Os->parse($data);
+ $this->assertEqual($engine->name, 'Second OpenSearch Test', 'Second element correctly overwrote the first');
+ }
+
+ function testInvalid() {
+ $data = '<OpenSearchDescription>
+ <ShortName>OpenSearch Test</ShortName>
+ <Url type="text/html" method="get" template="http://test.template.url/search/">
+ <Param name="q" value="{searchTerms}"/>
+ <Param name="sourceid" value="firefox"/>
+ </Url>
+ </OpenSearchDescription>';
+
+ $engine = $this->Os->parse($data);
+ $this->assertFalse($engine, "Invalid namespace");
+
+ $data = '<OpenSearchDescription xmlns="http://a9.com/-/spec/opensearch/1.0/">
+ <Url type="text/html" method="get" template="http://test.template.url/search/">
+ <Param name="q" value="{searchTerms}"/>
+ <Param name="sourceid" value="firefox"/>
+ </Url>
+ </OpenSearchDescription>';
+
+ $engine = $this->Os->parse($data);
+ $this->assertFalse($engine, "No name");
+
+ $data = '<OpenSearchDescription xmlns="http://a9.com/-/spec/opensearch/1.0/">
+ <ShortName>OpenSearch Test</ShortName>
+ </OpenSearchDescription>';
+
+ $engine = $this->Os->parse($data);
+ $this->assertFalse($engine, "No Url");
+
+ $data = '<OpenSearchDescription xmlns="http://a9.com/-/spec/opensearch/1.0/">
+ <ShortName>OpenSearch Test</ShortName>
+ <Url type="application/x-suggestions+json" method="get" template="http://test.template.url/suggest/">
+ <Param name="q" value="{searchTerms}"/>
+ <Param name="sourceid" value="firefox-suggest"/>
+ </Url>
+ </OpenSearchDescription>';
+
+ $engine = $this->Os->parse($data);
+ $this->assertFalse($engine, "No text/html Url");
+
+ $data = '<OpenSearchDescription xmlns="http://a9.com/-/spec/opensearch/1.0/">
+ <ShortName>OpenSearch Test</ShortName>
+ <Url type="text/html" method="invalid" template="http://test.template.url/search/"/>
+ </OpenSearchDescription>';
+
+ $engine = $this->Os->parse($data);
+ $this->assertFalse($engine, "Invalid method");
+
+ $data = '<OpenSearchDescription xmlns="http://a9.com/-/spec/opensearch/1.0/">
+ <ShortName>OpenSearch Test</ShortName>
+ <Url type="text/html" method="get" template="mailto://test.template.url/search/"/>
+ </OpenSearchDescription>';
+
+ $engine = $this->Os->parse($data);
+ $this->assertFalse($engine, "Invalid template (non-HTTP)");
+
+ $data = '<OpenSearchDescription/>
+ <OpenSearchDescription>
+ <ShortName>OpenSearch Test</ShortName>
+ <Url type="text/html" method="get" template="http://test.template.url/search/">
+ <Param name="q" value="{searchTerms}"/>
+ <Param name="sourceid" value="firefox"/>
+ </Url>
+ </OpenSearchDescription>';
+ $engine = $this->Os->parse($data);
+ $this->assertFalse($engine, "Multiple root elements");
+ }
+
+ function testUrlAttrHandling() {
+ $data = '<OpenSearchDescription xmlns="http://a9.com/-/spec/opensearch/1.0/">
+ <ShortName>OpenSearch Test</ShortName>
+ <Url type="TEXT/HTML" template="http://test.template.url/Search/"/>
+ </OpenSearchDescription>';
+
+ $engine = $this->Os->parse($data);
+ $this->assertTrue(isset($engine->urls['text/html']), 'Type attribute is normalized');
+ $this->assertEqual($engine->urls['text/html']->method, 'GET', 'Missing method falls back to GET');
+ $this->assertEqual($engine->urls['text/html']->template, 'http://test.template.url/Search/', 'Template is case-sensitive');
+ }
+
+ function testImage() {
+ $data = '<OpenSearchDescription xmlns="http://a9.com/-/spec/opensearch/1.0/">
+ <ShortName>OpenSearch Test</ShortName>
+ <Image>data:image/x-icon;base64,Qk02AwAAAAAAADYAAAAoAAAAEAAAABAAAAABABgAAAAAAAADAAAAAAAAAAAAAAAAAAAAAAAA////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////AAAA////////AAAAAAAA////////AAAAAAAA////////AAAA////AAAA////////AAAA////AAAA////////////AAAA////////AAAA////AAAA////AAAA////////AAAA////AAAA////////////AAAA////////AAAA////AAAAAAAAAAAA////////AAAA////////AAAAAAAA////////AAAAAAAA////////AAAA////AAAA////////////////////////////////////////////////////////////////////////////AAAA////////////AAAA////AAAA////////AAAA////////////////////////AAAAAAAA////////AAAAAAAAAAAA////AAAA////AAAA////////////////////AAAA////////////AAAA////AAAA////AAAA////AAAA////////////////////AAAAAAAAAAAA////////AAAA////////AAAA////AAAA////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////</Image>
+ <Url type="TEXT/HTML" template="http://test.template.url/Search/"/>
+ </OpenSearchDescription>';
+
+ $engine = $this->Os->parse($data);
+ $this->assertFalse($engine->imageUrl, 'Image with invalid dimensions');
+
+ $data = '<OpenSearchDescription xmlns="http://a9.com/-/spec/opensearch/1.0/">
+ <ShortName>OpenSearch Test</ShortName>
+ <Image height="16" width="16">data:image/x-icon;base64,Qk02AwAAAAAAADYAAAAoAAAAEAAAABAAAAABABgAAAAAAAADAAAAAAAAAAAAAAAAAAAAAAAA////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////AAAA////////AAAAAAAA////////AAAAAAAA////////AAAA////AAAA////////AAAA////AAAA////////////AAAA////////AAAA////AAAA////AAAA////////AAAA////AAAA////////////AAAA////////AAAA////AAAAAAAAAAAA////////AAAA////////AAAAAAAA////////AAAAAAAA////////AAAA////AAAA////////////////////////////////////////////////////////////////////////////AAAA////////////AAAA////AAAA////////AAAA////////////////////////AAAAAAAA////////AAAAAAAAAAAA////AAAA////AAAA////////////////////AAAA////////////AAAA////AAAA////AAAA////AAAA////////////////////AAAAAAAAAAAA////////AAAA////////AAAA////AAAA////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////</Image>
+ <Url type="text/html" template="http://test.template.url/Search/"/>
+ </OpenSearchDescription>';
+
+ $engine = $this->Os->parse($data);
+ $this->assertEqual(base64_encode($engine->getImage()), 'Qk02AwAAAAAAADYAAAAoAAAAEAAAABAAAAABABgAAAAAAAADAAAAAAAAAAAAAAAAAAAAAAAA////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////AAAA////////AAAAAAAA////////AAAAAAAA////////AAAA////AAAA////////AAAA////AAAA////////////AAAA////////AAAA////AAAA////AAAA////////AAAA////AAAA////////////AAAA////////AAAA////AAAAAAAAAAAA////////AAAA////////AAAAAAAA////////AAAAAAAA////////AAAA////AAAA////////////////////////////////////////////////////////////////////////////AAAA////////////AAAA////AAAA////////AAAA////////////////////////AAAAAAAA////////AAAAAAAAAAAA////AAAA////AAAA////////////////////AAAA////////////AAAA////AAAA////AAAA////AAAA////////////////////AAAAAAAAAAAA////////AAAA////////AAAA////AAAA////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////', 'getImage');
+ }
+}
+?>
diff --git a/site/app/tests/controllers/components/rdf.test.php b/site/app/tests/controllers/components/rdf.test.php
new file mode 100644
index 0000000..eb09461
--- /dev/null
+++ b/site/app/tests/controllers/components/rdf.test.php
@@ -0,0 +1,78 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * Justin Scott <fligtar@gmail.com>.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+class RdfTest extends UnitTestCase {
+
+ //Setup the RDF Component
+ function setUp() {
+ loadComponent('Rdf');
+ $this->Rdf =& new RdfComponent();
+ }
+
+ /**
+ * Test the RDF parser
+ */
+ function testRDF() {
+ $fileContents = file_get_contents(TEST_DATA.'/test-install.rdf');
+ $manifestData = $this->Rdf->parseInstallManifest($fileContents);
+
+ //Make sure the XML returns an array of parsed data
+ $this->assertIsA($manifestData, 'array', 'manifestData returns an array');
+
+ //Make sure the XML generates an error if invalid
+ $badResults = $this->Rdf->parseInstallManifest($manifestData." this is so not valid xml");
+ $this->assertIsA($badResults, 'string', 'Invalid XML returns parse error');
+
+ //Make sure the parsed addon name is correct
+ $this->assertEqual($manifestData['name']['en-US'], 'Test Extension', 'Parse name: %s');
+
+ //Make sure the parsed addon GUID is correct
+ $this->assertEqual($manifestData['id'], '{B17C1C5A-04B1-11DB-9804-B622A1EF5496}', 'Parse ID: %s');
+
+ //Make sure the parsed addon version is correct
+ $this->assertEqual($manifestData['version'], '1.0', 'Parse version: %s');
+
+ //Make sure the parsed addon GUID is correct
+ $this->assertEqual($manifestData['description']['en-US'], 'Test description of the test extension.', 'Parse en-US description: %s');
+
+ //Make sure the parsed addon target applications are correct
+ $this->assertEqual($manifestData['targetApplication']['{ec8030f7-c20a-464f-9b0e-13a3a9e97384}']['minVersion'], '1.5', 'Parse minVersion: %s');
+
+ //Make sure the parsed addon target applications are correct
+ $this->assertEqual($manifestData['targetApplication']['{ec8030f7-c20a-464f-9b0e-13a3a9e97384}']['maxVersion'], '3.0a1', 'Parse maxVersion: %s');
+ }
+}
+?>
diff --git a/site/app/tests/controllers/components/simple_acl.test.php b/site/app/tests/controllers/components/simple_acl.test.php
new file mode 100644
index 0000000..28556dd
--- /dev/null
+++ b/site/app/tests/controllers/components/simple_acl.test.php
@@ -0,0 +1,121 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * Contributor(s):
+ * Mike Morgan <morgamic@mozilla.com> (Original Developer)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+class SimpleAclTest extends UnitTestCase {
+
+ /**
+ * Set up our required models and components.
+ */
+ function setUp() {
+ loadController('Groups');
+ $this->controller =& new GroupsController();
+
+ loadComponent('Session');
+ $this->controller->Session =& new SessionComponent();
+ $this->controller->Session->startup($this->controller);
+
+ loadComponent('SimpleAuth');
+ $this->controller->SimpleAuth =& new SimpleAuthComponent();
+ $this->controller->SimpleAuth->startup($this->controller);
+
+ loadComponent('SimpleAcl');
+ $this->controller->SimpleAcl =& new SimpleAclComponent();
+ $this->controller->SimpleAcl->startup($this->controller);
+ }
+
+ /**
+ * Test action allowed.
+ */
+ function testActionAllowed() {
+ $this->controller->SimpleAuth->setActiveUser(6,true);
+ $this->assertTrue($this->controller->SimpleAcl->actionAllowed('Editors','*',$this->controller->SimpleAuth->getActiveUser()), 'User editor@test has access to Editors:* via group permissions.');
+
+ $this->controller->SimpleAuth->setActiveUser(5,true);
+ $this->assertTrue($this->controller->SimpleAcl->actionAllowed('*','*',$this->controller->SimpleAuth->getActiveUser()), 'User nobody@mozilla.org has access to Groups:* via group permissions.');
+ }
+
+ /**
+ * Test permission denied.
+ */
+ function testPermissionDenied() {
+ $this->controller->SimpleAuth->setActiveUser(7,true);
+ $this->assertFalse($this->controller->SimpleAcl->actionAllowed('Editors','*',$this->controller->SimpleAuth->getActiveUser()), 'User user@test does not have access to Editors:* via group permissions.');
+ }
+
+ /**
+ * Test aclException.
+ */
+ function testAclException() {
+ $this->controller->SimpleAuth->setActiveUser(7,true);
+ $this->assertFalse($this->controller->SimpleAcl->actionAllowed('Groups','add',$this->controller->SimpleAuth->getActiveUser()), 'User user@test does not have access to Groups:add.');
+
+ $this->controller->aclExceptions = array('add');
+ $this->assertTrue($this->controller->SimpleAcl->actionAllowed('Groups','add',$this->controller->SimpleAuth->getActiveUser()), 'User user@test has access to Groups:add after adding aclException.');
+ }
+
+ /**
+ * Test disabled.
+ */
+ function testDisabled() {
+ $this->controller->SimpleAuth->setActiveUser(7,true);
+ $this->assertFalse($this->controller->SimpleAcl->actionAllowed('Groups','*',$this->controller->SimpleAuth->getActiveUser()), 'User user@test does not have access to Groups:add.');
+
+ // Load a controller and make sure ACL is disabled.
+ loadController('Groups');
+ $this->otherController =& new GroupsController();
+
+ loadComponent('Session');
+ $this->otherController->Session =& new SessionComponent();
+ $this->otherController->Session->startup($this->otherController);
+
+ loadComponent('SimpleAuth');
+ $this->otherController->SimpleAuth =& new SimpleAuthComponent();
+ $this->otherController->SimpleAuth->enabled = false;
+ $this->otherController->SimpleAuth->startup($this->otherController);
+
+ loadComponent('SimpleAcl');
+ $this->otherController->SimpleAcl =& new SimpleAclComponent();
+ $this->otherController->SimpleAuth->enabled = false;
+ $this->otherController->SimpleAcl->startup($this->otherController);
+
+ // First, we show that no user exists, which means the system won't even check for permissions on load unless it's explicit.
+ $this->assertEqual(null,$this->otherController->SimpleAuth->activeUser, 'No active user was ever set by SimpleAuth when it was disabled.');
+
+ // Second, we verify that because no SimpleAuth user was instantiated, access checks will fail when attempted against the default active user.
+ $this->assertFalse($this->otherController->SimpleAcl->actionAllowed('Groups','*'), 'Default active user does not have access to Groups:add when SimpleAcl is disabled.');
+
+ // However, we still want the ability to check again if we set an explicit user.
+ $this->controller->SimpleAuth->setActiveUser(5,true);
+ $this->assertTrue($this->otherController->SimpleAcl->actionAllowed('Groups','*',$this->controller->SimpleAuth->getActiveUser()), 'You can still check the access of a user that is explicitly set and chekced manually.');
+ }
+}
+?>
diff --git a/site/app/tests/controllers/components/src.test.php b/site/app/tests/controllers/components/src.test.php
new file mode 100644
index 0000000..70a3cef
--- /dev/null
+++ b/site/app/tests/controllers/components/src.test.php
@@ -0,0 +1,86 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * Justin Scott <fligtar@gmail.com>.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+class SrcTest extends UnitTestCase {
+ var $data = '# Mozilla/Google plug-in by amitp+mozilla@google.com
+
+<search
+ name="Google"
+ description="Google Search"
+ method="GET"
+ action="http://www.google.com/search"
+ queryCharset="utf-8"
+>
+
+<input name="q" user>
+<inputnext name="start" factor="10">
+<inputprev>
+<input name="ie" value="utf-8">
+<input name="oe" value="utf-8">
+
+<interpret
+ browserResultType="result"
+ charset = "UTF-8"
+ resultListStart="<!--a-->"
+ resultListEnd="<!--z-->"
+ resultItemStart="<!--m-->"
+ resultItemEnd="<!--n-->"
+>
+</search>
+
+<browser
+ update="https://addons.mozilla.org/searchplugins/updates/google.src"
+ updateIcon="https://addons.mozilla.org/searchplugins/updates/google.gif"
+ updateCheckDays="0"
+>
+';
+
+ //Setup the Src Component
+ function setUp() {
+ loadComponent('Src');
+ $this->Src =& new SrcComponent();
+ }
+
+ /**
+ * Test .src parser
+ */
+ function testSrc() {
+ $name = $this->Src->parse($this->data);
+ $this->assertEqual($name, 'Google Search');
+ }
+
+}
+?> \ No newline at end of file
diff --git a/site/app/tests/controllers/components/versioncompare.test.php b/site/app/tests/controllers/components/versioncompare.test.php
new file mode 100644
index 0000000..9ff3ced
--- /dev/null
+++ b/site/app/tests/controllers/components/versioncompare.test.php
@@ -0,0 +1,130 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * Justin Scott <fligtar@gmail.com>.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Mike Shaver <shaver@mozilla.org>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+class VersionCompareTest extends UnitTestCase {
+ function compareVersions($a, $b) {
+ return $this->VersionCompare->CompareVersions($a, $b);
+ }
+
+ // $test is in the inclusive range bounded by $lower and $upper
+ function assertVersionBetweenClosed($test, $lower, $upper) {
+ $this->assertTrue($this->VersionCompare->VersionBetween($test, $lower, $upper));
+ }
+
+ // $test is NOT in the inclusive range bounded by $lower and $upper
+ function assertVersionNotBetweenClosed($test, $lower, $upper) {
+ $this->assertFalse($this->VersionCompare->VersionBetween($test, $lower, $upper));
+ }
+
+ // The versions are considered equal
+ function assertVersionsEqual($a, $b) {
+ $this->assertEqual($this->compareVersions($a, $b), 0);
+ }
+
+ // The first version is greater than the second
+ function assertVersionGreater($greater, $lesser) {
+ $this->assertEqual($this->compareVersions($greater, $lesser), 1);
+ }
+
+ function assertVersionAliases($version, $aliases, $expected) {
+ $actual = $this->VersionCompare->_versionAlias($version, $aliases);
+ $this->assertEqual($expected, $actual);
+ }
+
+ //Setup the VC Component
+ function setUp() {
+ loadComponent('Versioncompare');
+ $this->VersionCompare =& new VersionCompareComponent();
+ }
+
+ //Make sure there are no PHP errors
+ function testNoErrors() {
+ $this->assertNoErrors();
+ }
+
+ // Minor update is greater than base version
+ function testMinorUpdateGreater() {
+ $this->assertVersionGreater('1.0.1.4', '1.0');
+ }
+
+ // A later update with fewer components is greater than earlier+longer
+ function testLaterShorterMinorUpdateGreater() {
+ $this->assertVersionGreater('1.0.2', '1.0.1.5');
+ }
+
+ // Beta is less than release-stream wildcard
+ function testBetaLessThanReleaseStreamWildcard() {
+ $this->assertVersionGreater('2.0.0.*', '2.0b1');
+ }
+
+ // Alpha is less than beta, beta less than final
+ function testAlphaBetaRCFinalOrdering() {
+ $this->assertVersionGreater('3.0b1', '3.0a2');
+ $this->assertVersionGreater('2.0', '2.0b3');
+ }
+
+ // A compatible update is between the release version and the compatible-stream wildcard
+ function testCompatibleUpdateInReleaseStream() {
+ $this->assertVersionBetweenClosed('2.0.0.1', '2.0', '2.0.0.*');
+ }
+
+ // Incompatible updates aren't
+ function testIncompatibleUpdateNotInStream() {
+ $this->assertVersionNotBetweenClosed('2.0.1', '2.0', '2.0.0.*');
+ }
+
+ // Extra zeroes don't matter
+ function testImpliedZeroes() {
+ $this->assertVersionsEqual('1.0', '1.0.0.0');
+ $this->assertVersionsEqual('1.0.0', '1.0');
+ $this->assertVersionsEqual('1.5', '1.5.0.0');
+ }
+
+ function testVersionAlias() {
+ $aliases = array(
+ '1.0' => array('0.5'),
+ '3.0' => array('2.0', '3.0'));
+
+ // Check that the key is included in the returned array.
+ $this->assertVersionAliases('1.0', $aliases, array('0.5', '1.0'));
+ // Check that a version without aliases just returns the given version.
+ $this->assertVersionAliases('2.0', $aliases, array('2.0'));
+ // Check that the key doesn't show up in the returned array mulitple times.
+ $this->assertVersionAliases('3.0', $aliases, array('2.0', '3.0'));
+ }
+}
+?>
diff --git a/site/app/tests/controllers/developers_controller.test.php b/site/app/tests/controllers/developers_controller.test.php
new file mode 100644
index 0000000..6762319
--- /dev/null
+++ b/site/app/tests/controllers/developers_controller.test.php
@@ -0,0 +1,73 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * Justin Scott <fligtar@gmail.com>.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+class DevelopersControllerTest extends UnitTestCase {
+
+ /**
+ * Setup the Developers Controller
+ */
+ function testLoad() {
+ $this->helper = new UnitTestHelper();
+ $this->controller = $this->helper->getController('Developers', $this);
+ //$this->helper->mockModels($this->controller, $this);
+ $this->helper->mockComponents($this->controller, $this);
+ }
+
+ /**
+ * Tests aspects of step 1
+ */
+ function testAddStep1() {
+ //Test that the RDF parser has been included
+ $this->assertTrue(class_exists('Rdf_parser'), 'RDF parser included');
+
+ //Setup so we don't have exceptions.
+ $this->controller->data['Addon']['add_step1'] = true;
+ $this->controller->data['File']['platform_id1'] = 1;
+ $this->controller->data['File']['platform_id2'] = 1;
+ $this->controller->data['File']['platform_id3'] = 1;
+ $this->controller->data['File']['platform_id4'] = 1;
+ $this->controller->data['Addon']['addontype_id'] = ADDON_EXTENSION;
+ $this->controller->data['File']['file1']['size'] = 0;
+ $this->controller->data['File']['file1']['error'] = 0;
+
+ /*//Test for an extension without install.rdf
+ $this->controller->data['File']['file1']['name'] = 'extension-noinstall.xpi';
+ $this->controller->data['File']['file1']['tmp_name'] = TEST_DATA.'/extension-noinstall.xpi';
+ $this->helper->callControllerAction($this->controller, 'add', $this);
+ $this->assertEqual($this->controller->addVars['mainError'], 'No install.rdf present', 'Install Manifest: No install.rdf present: %s');*/
+
+ }
+}
diff --git a/site/app/tests/controllers/downloads_controller.test.php b/site/app/tests/controllers/downloads_controller.test.php
new file mode 100644
index 0000000..94e889f
--- /dev/null
+++ b/site/app/tests/controllers/downloads_controller.test.php
@@ -0,0 +1,77 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Andrei Hajdukewycz <sancus@off.net> (Original Author)
+ * Frederic Wenzel <fwenzel@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+class DownloadsTest extends WebTestHelper {
+
+ function testLoad() {
+ $this->WebTestCase("Download Tests");
+ loadModel('Download');
+ $this->Download =& new Download();
+ $this->Download->caching = false; // Make sure we set this to false so count tests work.
+ loadModel('File');
+ $this->File =& new File();
+ $this->File->caching = false;
+ }
+
+ function testNoCacheHeaders() {
+ $action = $this->actionURI("/downloads/file/9/");
+ $this->get($action);
+ $this->assertHeader('Cache-Control', 'no-store, must-revalidate, post-check=0, pre-check=0, private, max-age=0', "cache-control header for {$action}");
+ $this->assertHeader('Pragma', 'private', "Pragma private header for {$action}");
+ }
+
+ function testNoSandboxForYou() {
+ $this->getAction("/downloads/file/25982/");
+ $this->assertWantedPattern("@Add-on not found@", "Sandbox Denied without Login?");
+ }
+
+ function assertFileDownload($file_id, $action, $message) {
+ $this->getAction($action);
+ $file_data = $this->File->findById($file_id);
+ $file_loc = REPO_PATH . '/' . $file_data['Version']['addon_id'] . '/' . $file_data['File']['filename'];
+ $this->assertEqual(md5_file($file_loc), md5($this->_browser->getContent()), $message);
+ }
+
+ function testDownloads() {
+ $this->assertFileDownload(9, '/downloads/file/9/', 'Extension download works.');
+ $this->assertFileDownload(8, '/downloads/file/8/a9.src', 'Search download works.');
+ $this->assertFileDownload(23559, '/downloads/file/23559', 'Dictionary download works.');
+ }
+}
+?>
diff --git a/site/app/tests/controllers/editors_controller.test.php b/site/app/tests/controllers/editors_controller.test.php
new file mode 100644
index 0000000..7f86245
--- /dev/null
+++ b/site/app/tests/controllers/editors_controller.test.php
@@ -0,0 +1,329 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Wil Clouser <clouserw@mozilla.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+class EditorsControllerTest extends WebTestHelper {
+
+ var $testdata = array(
+ 'addonid' => 7, // microfarmer
+ 'tagid' => 2, // viruses
+ 'feature_locales' => 'en-US,fr,de'
+ );
+
+ var $queuedata = array(
+ 'addonid' => 4022,
+ 'name' => 'Chrome List',
+ 'addontypeid' => 1,
+ 'platformid' => 2,
+ 'applicationid' => 1,
+ );
+
+ var $performancedata = array(
+ 'userid' => 5,
+ );
+
+ /**
+ * Setup the Editors Controller
+ */
+ function testLoad() {
+ $this->WebTestCase('Editor Feature Tests');
+
+ loadModel('Addon');
+ $this->Addon =& new Addon();
+ $this->Addon->caching = false;
+ $this->Addon->cacheQueries = false;
+
+ $this->helper = new UnitTestHelper();
+ $this->controller =& $this->helper->getController('Editors', $this);
+ $this->helper->mockComponents($this->controller, $this);
+ }
+
+ function testAddFeature() {
+ $this->assertFalse($this->_checkIfDataExists(), "Make sure the data we're going to use doesn't exist.");
+
+ $this->login();
+ $this->setMaximumRedirects(0);
+
+ $this->getAction("/editors/featured/add/{$this->testdata['tagid']}/{$this->testdata['addonid']}/ajax");
+ $this->assertResponse(array('200'), "Valid AJAX data gets appropriate response.");
+ $this->assertTrue($this->_checkIfDataExists(), "Valid AJAX data gets inserted into the db");
+ $this->_removeTestData();
+
+ $this->getAction("/editors/featured/add/broken{$this->testdata['tagid']}/blah{$this->testdata['addonid']}/ajax");
+ $this->assertResponse(array('400'), "Invalid AJAX data gets appropriate response.");
+
+ $_data = array( 'data[Addon][id]' => 'Microfarmer [7]', 'data[Tag][id]' => 2);
+ $this->post($this->actionURI("/editors/featured/add"),$_data);
+ $this->assertResponse(array('200'), "Valid POST data gets appropriate response.");
+ $this->assertTrue($this->_checkIfDataExists(), "Valid POST data gets inserted into the db");
+ $this->_removeTestData();
+ unset($_data);
+
+ $_data = array( 'data[Addon][id]' => '7broken', 'data[Tag][id]' => '2broken');
+ $this->post($this->actionURI("/editors/featured/add"),$_data);
+ $this->assertResponse(array('400'), "Invalid POST data gets appropriate response.");
+ unset($_data);
+
+ }
+ function testEditFeature() {
+ $this->login();
+ $this->setMaximumRedirects(0);
+
+ $this->_addTestData();
+
+ $_data = array('data[AddonTag][feature_locales]' => 'en-US,de');
+ $this->post($this->actionURI("/editors/featured/edit/{$this->testdata['tagid']}/{$this->testdata['addonid']}/ajax"), $_data);
+ $this->assertResponse(array('200'), "Valid AJAX edit request with valid data gets accepted.");
+ $_ret = $this->Addon->execute("SELECT feature_locales FROM `addons_tags` WHERE addon_id={$this->testdata['addonid']} AND tag_id={$this->testdata['tagid']}");
+ $this->assertEqual('de,en-US', $_ret[0]['AddonTag']['feature_locales'], 'Valid AJAX edit request changes data');
+ unset($_data, $_ret);
+
+ $_data = array('data[AddonTag][feature_locales]' => 'en-US,de');
+ $this->post($this->actionURI("/editors/featured/edit/{$this->testdata['tagid']}broken/{$this->testdata['addonid']}broken/ajax"), $_data);
+ $this->assertResponse(array('400'), "Invalid AJAX edit request with valid data gets rejected.");
+
+ $_data = array('data[AddonTag][feature_locales]' => 'en-US,broken,de');
+ $this->post($this->actionURI("/editors/featured/edit/{$this->testdata['tagid']}/{$this->testdata['addonid']}/ajax"), $_data);
+ $this->assertResponse(array('400'), "Valid AJAX edit request with invalid data gets rejected.");
+
+ $_data = array( 'data[Addon][id]' => 7, 'data[Tag][id]' => 2, 'data[AddonTag][feature_locales]' => 'en-US,fr');
+ $this->post($this->actionURI("/editors/featured/edit"), $_data);
+ $this->assertResponse(array('200'), "Valid POST edit request with valid data gets accepted.");
+ $_ret = $this->Addon->execute("SELECT feature_locales FROM `addons_tags` WHERE addon_id={$this->testdata['addonid']} AND tag_id={$this->testdata['tagid']}");
+ $this->assertEqual('en-US,fr', $_ret[0]['AddonTag']['feature_locales'], 'Valid POST edit request changes data');
+ unset($_data, $_ret);
+
+ $_data = array( 'data[Addon][id]' => 7, 'data[Tag][id]' => '2broken', 'data[AddonTag][feature_locales]' => 'en-US,fr');
+ $this->post($this->actionURI("/editors/featured/edit"), $_data);
+ $this->assertResponse(array('400'), "Valid POST edit request with invalid data gets rejected.");
+
+ $_data = array( 'data[Addon][id]' => 7, 'data[Tag][id]' => 2, 'data[AddonTag][feature_locales]' => 'en-US,broken,fr');
+ $this->post($this->actionURI("/editors/featured/edit"), $_data);
+ $this->assertResponse(array('400'), "Valid POST edit request with invalid locales gets rejected.");
+
+ $this->_removeTestData();
+ }
+ function testRemoveFeature() {
+ $this->login();
+ $this->setMaximumRedirects(0);
+
+ $this->_addTestData();
+ $this->getAction("/editors/featured/remove/{$this->testdata['tagid']}/{$this->testdata['addonid']}");
+ $this->assertResponse(array('200'), "Valid GET removal request gets appropriate response.");
+ $this->assertFalse($this->_checkIfDataExists(), "Valid GET removal request removes data.");
+
+ $this->getAction("/editors/featured/remove/{$this->testdata['tagid']}broken/{$this->testdata['addonid']}broken");
+ $this->assertResponse(array('400'), "Invalid GET removal request gets appropriate response.");
+ }
+
+ function testPendingQueueFilter() {
+ $addonName = $this->queuedata['name'];
+ $addonAppId = $this->queuedata['applicationid'];
+ $addonType = $this->queuedata['addontypeid'];
+ $addonPlatform = $this->queuedata['platformid'];
+ $nameSearch = substr($addonName, 0, -4);
+
+ $path = $this->actionURI('/editors/queue/pending');
+
+ // login
+ $this->login();
+
+ // test no filter
+ $this->get($path);
+ $this->clickSubmitByName('clear');
+ $this->assertText($addonName, "'$addonName' in unfiltered queue.");
+
+ // filters that include add-on
+ $this->clickSubmitByName('filter', array('data[Filter][AddonOrAuthor]' => $nameSearch));
+ $this->assertText($addonName, "'$addonName' in queue with Addon filter.");
+
+ $this->clickSubmitByName('clear');
+ $this->clickSubmitByName('filter', array('data[Filter][Application]' => $addonAppId));
+ $this->assertText($addonName, "'$addonName' in queue with Application filter.");
+
+ $this->clickSubmitByName('clear');
+ $this->clickSubmitByName('filter', array('data[Filter][SubmissionAge]' => '10+'));
+ $this->assertText($addonName, "'$addonName' in queue with Age filter.");
+
+ $this->clickSubmitByName('clear');
+ $this->clickSubmitByName('filter', array('data[Filter][Addontype][]' => $addonType));
+ $this->assertText($addonName, "'$addonName' in queue with Addontype filter.");
+
+ $this->clickSubmitByName('clear');
+ $this->clickSubmitByName('filter', array('data[Filter][Platform][]' => $addonPlatform));
+ $this->assertText($addonName, "'$addonName' in queue with Platform filter.");
+
+ $this->clickSubmitByName('clear');
+ $this->clickSubmitByName('filter', array(
+ 'data[Filter][AddonOrAuthor]' => $nameSearch,
+ 'data[Filter][Application]' => $addonAppId,
+ 'data[Filter][SubmissionAge]' => '10+',
+ 'data[Filter][Addontype][]' => $addonType,
+ 'data[Filter][AddonPlatform][]' => $addonPlatform)
+ );
+ $this->assertText($addonName, "'$addonName' in queue with multi-field filter.");
+
+ // filters that exclude add-on
+ $this->clickSubmitByName('clear');
+ $this->clickSubmitByName('filter', array('data[Filter][AddonOrAuthor]' => "{$nameSearch}wolf!"));
+ $this->assertNoText($addonName, "'$addonName' not in queue with unmatching Addon filter.");
+
+ $this->clickSubmitByName('clear');
+ $this->clickSubmitByName('filter', array('data[Filter][Application]' => $addonAppId+12345));
+ $this->assertNoText($addonName, "'$addonName' not in queue with unmatching Application filter.");
+
+ $this->clickSubmitByName('clear');
+ $this->clickSubmitByName('filter', array('data[Filter][SubmissionAge]' => 1));
+ $this->assertNoText($addonName, "'$addonName' not in queue with unmatching Age filter.");
+
+ $this->clickSubmitByName('clear');
+ $this->clickSubmitByName('filter', array('data[Filter][Addontype][]' => $addonType+12345));
+ $this->assertNoText($addonName, "'$addonName' not in queue with unmatching Addontype filter.");
+
+ $this->clickSubmitByName('clear');
+ $this->clickSubmitByName('filter', array('data[Filter][Platform][]' => $addonPlatform+12345));
+ $this->assertNoText($addonName, "'$addonName' not in queue with unmatching Platform filter.");
+ }
+
+ function testNominatedQueueFilter() {
+ $addonName = $this->queuedata['name'];
+ $addonAppId = $this->queuedata['applicationid'];
+ $addonType = $this->queuedata['addontypeid'];
+ $nameSearch = substr($addonName, 0, -4);
+
+ $path = $this->actionURI('/editors/queue/nominated');
+
+ // login
+ $this->login();
+
+ // initially our test add-on should NOT be in the nominated queue
+ $this->get($path);
+ $this->clickSubmitByName('clear');
+ $this->assertNoText($addonName, "'$addonName' (status=PUBLIC) not in unfiltered queue.");
+
+ // now temporarily change the status (and nomination date)
+ $this->_setNominatedStatus();
+
+ // test no filter
+ $this->clickSubmitByName('clear');
+ $this->assertText($addonName, "'$addonName' in unfiltered queue.");
+
+ // filters that include add-on
+ $this->clickSubmitByName('filter', array('data[Filter][AddonOrAuthor]' => $nameSearch));
+ $this->assertText($addonName, "'$addonName' in queue with Addon filter.");
+
+ $this->clickSubmitByName('clear');
+ $this->clickSubmitByName('filter', array('data[Filter][Application]' => $addonAppId));
+ $this->assertText($addonName, "'$addonName' in queue with Application filter.");
+
+ $this->clickSubmitByName('clear');
+ $this->clickSubmitByName('filter', array('data[Filter][SubmissionAge]' => '3'));
+ $this->assertText($addonName, "'$addonName' in queue with Age filter.");
+
+ $this->clickSubmitByName('clear');
+ $this->clickSubmitByName('filter', array('data[Filter][Addontype][]' => $addonType));
+ $this->assertText($addonName, "'$addonName' in queue with Addontype filter.");
+
+ $this->clickSubmitByName('clear');
+ $this->clickSubmitByName('filter', array(
+ 'data[Filter][AddonOrAuthor]' => $nameSearch,
+ 'data[Filter][Application]' => $addonAppId,
+ 'data[Filter][SubmissionAge]' => 3,
+ 'data[Filter][Addontype][]' => $addonType)
+ );
+ $this->assertText($addonName, "'$addonName' in queue with multi-field filter.");
+
+ // filters that exclude add-on
+ $this->clickSubmitByName('clear');
+ $this->clickSubmitByName('filter', array('data[Filter][AddonOrAuthor]' => "{$nameSearch}robot!"));
+ $this->assertNoText($addonName, "'$addonName' not in queue with unmatching Addon filter.");
+
+ $this->clickSubmitByName('clear');
+ $this->clickSubmitByName('filter', array('data[Filter][Application]' => $addonAppId+12345));
+ $this->assertNoText($addonName, "'$addonName' not in queue with unmatching Application filter.");
+
+ $this->clickSubmitByName('clear');
+ $this->clickSubmitByName('filter', array('data[Filter][SubmissionAge]' => 1));
+ $this->assertNoText($addonName, "'$addonName' not in queue with unmatching Age filter.");
+
+ $this->clickSubmitByName('clear');
+ $this->clickSubmitByName('filter', array('data[Filter][Addontype][]' => $addonType+12345));
+ $this->assertNoText($addonName, "'$addonName' not in queue with unmatching Addontype filter.");
+
+ // restore changed status
+ $this->_restoreStatus();
+ }
+
+ function testPerformanceByCategory() {
+ $summary = $this->controller->_performanceSummaryByCategory($this->performancedata['userid']);
+ $this->assertTrue(array_sum($summary['usercount']) > 0, 'user has approvals in category breakdown summary');
+ $this->assertTrue(array_sum($summary['teamcount']) > 0, 'team has approvals in category breakdown summary');
+ }
+
+ function testPerformanceByMonth() {
+ $summary = $this->controller->_performanceSummaryByMonth($this->performancedata['userid']);
+ $this->assertTrue(array_sum($summary['usercount']) > 0, 'user has approvals in monthly summary');
+ $this->assertTrue(array_sum($summary['teamcount']) > 0, 'team has approvals in monthly summary');
+ }
+
+ /**
+ * We've got to use direct queries here because cake 1.1 doesn't support getting data in join tables. :-/
+ */
+ function _checkIfDataExists() {
+ $ret = $this->Addon->execute("SELECT addon_id FROM `addons_tags` WHERE addon_id={$this->testdata['addonid']} AND tag_id={$this->testdata['tagid']}");
+ return !empty($ret);
+ }
+
+ function _addTestData() {
+ $this->Addon->execute("INSERT INTO `addons_tags` VALUES('{$this->testdata['addonid']}','{$this->testdata['tagid']}', 1, '{$this->testdata['feature_locales']}')");
+ }
+
+ function _removeTestData() {
+ $this->Addon->execute("DELETE FROM `addons_tags` WHERE addon_id={$this->testdata['addonid']} AND tag_id={$this->testdata['tagid']} LIMIT 1");
+ }
+
+
+ /**
+ * Test data doesn't have any nominated addons. We'll use these methods to nominate temporarily
+ */
+ function _setNominatedStatus() {
+ $this->Addon->execute("UPDATE `addons` SET `status`=".STATUS_NOMINATED.", nominationdate=DATE_SUB(NOW(), INTERVAL 3 DAY) WHERE id={$this->queuedata['addonid']} LIMIT 1");
+ }
+
+ function _restoreStatus() {
+ $this->Addon->execute("UPDATE `addons` SET `status`=".STATUS_PUBLIC.", nominationdate=0 WHERE id={$this->queuedata['addonid']} LIMIT 1");
+ }
+}
diff --git a/site/app/tests/controllers/groups_controller.test.php b/site/app/tests/controllers/groups_controller.test.php
new file mode 100644
index 0000000..cefb7f9
--- /dev/null
+++ b/site/app/tests/controllers/groups_controller.test.php
@@ -0,0 +1,79 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * Justin Scott <fligtar@gmail.com>.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+class GroupsControllerTestCase extends UnitTestCase {
+
+ var $testgroup = array(
+ 'id' => '10000',
+ 'name' => 'testgroup',
+ 'rules' => '*:*'
+ );
+
+ function testLoad() {
+ $this->helper = new UnitTestHelper();
+ $this->controller = $this->helper->getController('Groups', $this);
+ $this->helper->mockComponents($this->controller, $this);
+ $this->controller->params['controller'] = 'Users';
+ $this->controller->Group->cacheQueries = false;
+
+ // Make sure we aren't caching when testing edits.
+ $this->controller->Group->caching = false;
+ $this->controller->User->caching = false;
+ }
+
+ function testAdd() {
+ $this->controller->data = $this->testgroup;
+ $this->helper->callControllerAction($this->controller, 'add', $this);
+ $this->id = $this->controller->Group->getLastInsertId();
+ $this->assertTrue($this->controller->Group->findById($this->id), 'Test group was added successfully.');
+ }
+
+ function testEdit() {
+ $this->controller->data = $this->testgroup;
+ $this->controller->data['name'] = 'othertestgroup';
+ $this->helper->callControllerAction($this->controller, 'edit', $this);
+ $group = $this->controller->Group->findById($this->id);
+ $this->assertEqual($group['Group']['name'],'othertestgroup');
+ }
+
+ function testDelete() {
+ $this->helper->callControllerAction($this->controller, 'delete', $this, array('id'=>$this->id));
+ $group = $this->controller->Group->findById($this->id);
+ $this->assertFalse($group,'Test group was deleted successfully.');
+ }
+}
+?>
diff --git a/site/app/tests/controllers/legacy_url_controller.test.php b/site/app/tests/controllers/legacy_url_controller.test.php
new file mode 100644
index 0000000..c3f9180
--- /dev/null
+++ b/site/app/tests/controllers/legacy_url_controller.test.php
@@ -0,0 +1,11 @@
+<?php
+
+class LegacyUrlTest extends WebTestHelper {
+
+ function nyi_testOldSections() {
+
+ }
+
+}
+
+?>
diff --git a/site/app/tests/controllers/reviews_controller.test.php b/site/app/tests/controllers/reviews_controller.test.php
new file mode 100644
index 0000000..9b76ce1
--- /dev/null
+++ b/site/app/tests/controllers/reviews_controller.test.php
@@ -0,0 +1,49 @@
+<?php
+
+class ReviewsTest extends UnitTestCase {
+
+ function testLoad() {
+ $this->helper =& new UnitTestHelper();
+ $this->controller =& $this->helper->getController('Reviews', $this);
+ $this->helper->mockComponents($this->controller, $this);
+ }
+
+ function testAddReview() {
+ $this->controller->params['controller'] = 'Reviews';
+ // set up components needed by controller
+ $this->controller->set('paging', array());
+
+ $review = array(
+ 'id' => '',
+ 'rating' => 5,
+ 'title' => 'Review Test',
+ 'body' => 'A long, loooong review.'
+ );
+ $this->controller->data['Review'] = $review;
+
+ // try it logged out
+ $this->helper->callControllerAction($this->controller, 'add', $this, array(7));
+ $id = $this->controller->Review->getLastInsertId();
+ $this->assertTrue(($id == 0), 'Not adding reviews if not logged in');
+ @$this->controller->Review->del($id);
+
+ // now logged in
+ $this->helper->login($this->controller);
+ $this->controller->sandboxAccess = true;
+ $this->helper->callControllerAction($this->controller, 'add', $this, array(7));
+ $id = $this->controller->Review->getLastInsertId();
+ $this->assertTrue(($id > 0), 'Adding a review as a logged in user');
+
+ // try editing this review
+ /*
+ $review2 = $review;
+ $review2['rating'] = 10;
+ $this->helper->callControllerAction($this->controller, 'add', $this, array(7));
+ $saved = $this->controller->Review->findById($id);
+ $this->assertEquals($saved['Review']['rating'], 10, 'Editing a review');
+ */
+ @$this->controller->Review->del($id);
+ }
+}
+
+?>
diff --git a/site/app/tests/controllers/search_controller.test.php b/site/app/tests/controllers/search_controller.test.php
new file mode 100644
index 0000000..110be38
--- /dev/null
+++ b/site/app/tests/controllers/search_controller.test.php
@@ -0,0 +1,140 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Wil Clouser <wclouser@mozilla.com> (Original Author)
+ * Frederic Wenzel <fwenzel@mozilla.com>
+ * Justin Scott <fligtar@gmail.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+
+class SearchTest extends UnitTestCase {
+
+ function SearchTest() {
+ }
+
+ /* N.B.: this is first so that it does the setup without spamming the result list
+ * each time.
+ */
+ function testLoad()
+ {
+ $this->helper = new UnitTestHelper();
+ $this->controller =& $this->helper->getController('Search', $this);
+ $this->helper->mockComponents($this->controller, $this);
+
+ // real SearchComponent for real (simple) searches
+ loadComponent('Search');
+ $this->controller->Search =& new SearchComponent();
+ $this->controller->Search->startup($this->controller);
+ }
+
+ function runSimpleSearch($terms) {
+ return $this->controller->Search->search($terms);
+ }
+
+ function runSimpleCollectionSearch($terms) {
+ return $this->controller->Search->searchCollections($terms);
+ }
+
+ function testSearchHandlesInvalidInput() {
+ // a throwaway test - just making sure if we pass in an invalid
+ // value, it comes back as an array anyway
+ $this->assertIsA($this->runSimpleSearch(array()), 'array');
+ }
+
+ function testSearchAddonName() {
+ $results = $this->runSimpleSearch("Farmer");
+ $this->assertFalse(empty($results), "found results for name match");
+ }
+
+ function testSearchAddonSummary() {
+ $results = $this->runSimpleSearch("Harvest MicroFormats");
+ $this->assertFalse(empty($results), "found results for summary match");
+ }
+
+ function testSearchExcludesSearchPlugins() {
+ $results = $this->runSimpleSearch("Google search, mark two");
+ $this->assertTrue(empty($results), "excluded search plugins in searches");
+ }
+
+ function testSearchAddonDescription() {
+ $results = $this->runSimpleSearch("MicroFormat XOXO hCalendar");
+ $this->assertFalse(empty($results), "found results for description match");
+ }
+
+ function testSearchTermOrderIndependence() {
+ $results1 = $this->runSimpleSearch("firefox hcalendar");
+ $results2 = $this->runSimpleSearch("hcalendar firefox");
+ $this->assertTrue($this->helper->array_compare_recursive($results1, $results2), "order of query terms doesn't matter");
+ }
+
+ function testSearchSuppressesDuplicates() {
+ $results = $this->runSimpleSearch("te");
+ foreach ($results as $result) {
+ $this->assertEqual(count(array_keys($results, $result)), 1,
+ "no duplicates found in results");
+ }
+ }
+
+ function testSearchDuplicateTerms() {
+ $results1 = $this->runSimpleSearch("firefox");
+ $results2 = $this->runSimpleSearch("firefox firefox");
+ $this->assertTrue($this->helper->array_compare_recursive($results1, $results2), "entering the same term multiple times doesn't affect the results");
+ }
+
+ function testSearchQuoted() {
+ $results = $this->runSimpleSearch('"Adds MicroFormat detection"');
+ $this->assertFalse(empty($results), "found results for quoted search");
+
+ $results_unquoted = $this->runSimpleSearch('Adds MicroFormat detection');
+ $results_quoted = $this->runSimpleSearch('"MicroFormat Adds detection"');
+ $this->assertTrue(!empty($results_unquoted) && empty($results_quoted), "quoted search returns nothing for query that matches when unquoted");
+ }
+
+ function testUsesFile() {
+ $this->assertTrue(in_array('File', $this->controller->uses),
+ 'The File model is available on the controller');
+ }
+
+ function testSearchCollectionName() {
+ $results = $this->runSimpleCollectionSearch('name');
+ $this->assertTrue(!empty($results), "found results for collection name match");
+ }
+
+ function testSearchCollectionDescription() {
+ $results = $this->runSimpleCollectionSearch('description');
+ $this->assertTrue(!empty($results), "found results for collection description match");
+ }
+}
+?>
diff --git a/site/app/tests/controllers/sharing_api_controller.test.php b/site/app/tests/controllers/sharing_api_controller.test.php
new file mode 100644
index 0000000..d92fd02
--- /dev/null
+++ b/site/app/tests/controllers/sharing_api_controller.test.php
@@ -0,0 +1,1506 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is The Mozilla Foundation.
+ *
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * l.m.orchard <lorchard@mozilla.com> (Original Author)
+ * Frederic Wenzel <fwenzel@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+class SharingApiTest extends WebTestHelper {
+
+ const XML_NS = 'http://www.w3.org/XML/1998/namespace';
+
+ function setUp()
+ {
+ // Instantiate some useful models.
+ $models = array(
+ 'User', 'Collection', 'Addon'
+ );
+ foreach ($models as $model) {
+ loadModel($model);
+ $this->{$model} =& new $model();
+ $this->{$model}->caching = false;
+ $this->{$model}->cacheQueries = false;
+ }
+
+ // Grab a pile of known addons for testing.
+ $addon_rows = $this->Addon->findAll(array(
+ 'Addon.inactive' => 0,
+ 'Addon.addontype_id' => array(
+ ADDON_EXTENSION, ADDON_THEME, ADDON_DICT,
+ ADDON_SEARCH, ADDON_PLUGIN
+ )
+ ), null, null, 20, 1);
+
+ // Index the addons by GUID.
+ $this->addons = array();
+ foreach ($addon_rows as $row) {
+ $this->addons[$row['Addon']['guid']] = $row;
+ }
+
+ // Build the service URL
+ $this->service_url = $this->actionURI('/api/1.3/sharing/');
+
+ // Establish the user/pass for the test user.
+ $this->username = 'nobody@mozilla.org';
+ $this->password = 'test';
+
+ // Ensure each test starts off logged out.
+ $this->get($this->actionURI('/users/logout'));
+
+ // Get the record for the test user
+ $this->test_user = $this->User->findByEmail($this->username);
+ $this->nickname = $this->test_user['User']['nickname'];
+
+ // Get some other test users
+ $this->test_user_2 = $this->User->findByEmail('user@test');
+ $this->test_user_3 = $this->User->findByEmail('nobody@addons.mozilla.org');
+ $this->test_user_4 = $this->User->findByEmail('sandbox@test');
+
+ $this->all_test_users = array(
+ $this->test_user, $this->test_user_2,
+ $this->test_user_3, $this->test_user_4
+ );
+
+ // Delete all collections for the test users.
+ foreach ($this->all_test_users as $user) {
+ $c = $this->User->getCollections($user['User']['id']);
+ if (!empty($c)) foreach ($c as $row) {
+ $this->Collection->delete($row);
+ }
+ }
+ }
+
+ /**
+ * Ensure that the service document can be fetched, but that authentication
+ * is demanded.
+ */
+ function testServiceDocumentBasics()
+ {
+ // Try fetching the service document, but assert that auth is required.
+ $this->get($this->service_url);
+ $this->assertAuthentication('Basic');
+ $this->assertResponse(401);
+
+ // Use website cookie login and assert that auth is satisfied.
+ $this->login();
+ $this->get($this->service_url);
+ $this->assertResponse(200);
+
+ // Logout, and assert that auth is required again.
+ $this->get($this->actionURI('/users/logout'));
+ $this->get($this->service_url);
+ $this->assertAuthentication('Basic');
+ $this->assertResponse(401);
+
+ // Now, try HTTP Basic Auth and assert auth is satisfied.
+ $this->authenticate($this->username, $this->password);
+ $doc = $this->getXml($this->service_url);
+ $this->assertResponse(200);
+
+ // There should at least be <email> and <collections> elements, each
+ // with href attributes.
+ $this->assertTrue( isset($doc->email),
+ 'email element present' );
+ $this->assertTrue( !empty($doc->email['href']),
+ 'email element has @href' );
+ $this->assertTrue( isset($doc->collections),
+ 'collections element present' );
+ $this->assertTrue( !empty($doc->collections['href']),
+ 'collections has @href' );
+ }
+
+ /**
+ * Ensure that GET requests for service doc, collections, and collection
+ * documents all reflect presence of collections in the database.
+ */
+ function testEmptyCollectionsWithModel()
+ {
+ // Use website cookie login and assert that auth is satisfied.
+ $this->login();
+ $doc = $this->getXml($this->service_url);
+ $this->assertResponse(200,
+ "Service document should be found at {$this->service_url}");
+
+ // Try to get a base URL, based on either the service doc URL or an
+ // xml:base in the document
+ $base_url = $this->getBaseUrl($this->service_url, $doc);
+
+ // Get an absolute URL for collections.
+ $collections_url =
+ $this->resolveUrl($base_url, $doc->collections['href']);
+
+ // Since collections for the test user are deleted in setup, there
+ // shouldn't be any collections at first.
+ $nodes = $doc->collections->children();
+ $this->assertTrue(count($nodes) == 0,
+ 'Collections for user should be empty at first');
+
+ // Now, create new test collections
+ $test_collections = $this->createTestCollections();
+
+ // Assert that service doc reflects addition of collection.
+ $doc = $this->getXml($this->service_url);
+ $this->assertExpectedCollectionNodes(
+ $test_collections,
+ $doc->collections->children()
+ );
+
+ // Iterate through each collection in the collections doc and verify
+ // contents of individual empty collections.
+ $nodes = $doc->collections->children();
+ for ($i=0; $i<count($test_collections); $i++) {
+ $test = $test_collections[$i];
+ $node = $nodes[$i];
+ $c_url = $this->resolveUrl($base_url, (string)$node['href']);
+
+ $collection_doc = $this->getXml($c_url);
+ $this->assertExpectedCollectionNodes(
+ array($test), array($collection_doc)
+ );
+ }
+
+ }
+
+ /**
+ * Create / delete collections with the API, verify results.
+ */
+ function testEmptyCollectionsWithApi()
+ {
+ $user_id = $this->test_user['User']['id'];
+
+ $test_collection = array(
+ 'Collection' => array(
+ 'name' => 'New creation',
+ 'description' => 'check out this new sensation!',
+ 'nickname' => 'newcollection',
+ 'app' => 'thunderbird',
+ 'listed' => 1
+ )
+ );
+
+ $this->login();
+ $doc = $this->getXml($this->service_url);
+ $this->assertResponse(200,
+ "Service document should be found at {$this->service_url}");
+
+ $base_url =
+ $this->getBaseUrl($this->service_url, $doc);
+ $collections_url =
+ $this->resolveUrl($base_url, $doc->collections['href']);
+
+ $this->post($collections_url, array());
+ $this->assertResponse(400,
+ "Missing / invalid fields should result in 400 Bad Request");
+
+ $this->post($collections_url, array('name' => 'blah'));
+ $this->assertResponse(400,
+ "Missing / invalid fields should result in 400 Bad Request");
+
+ $this->post($collections_url, array(
+ 'name' => $test_collection['Collection']['name'],
+ 'description' => $test_collection['Collection']['description'],
+ 'nickname' => $test_collection['Collection']['nickname'],
+ 'app' => $test_collection['Collection']['app'],
+ 'listed' => $test_collection['Collection']['listed']
+ ));
+
+ $this->assertResponse(201,
+ "POST to collections URL should result in 201 Created");
+
+ $headers = $this->getBrowserHeaders();
+ $this->assertTrue(isset($headers['location']),
+ 'Collection creation should yield a location: header');
+ $result_url = $headers['location'];
+
+ // Ensure that the same content is found at the detail URL for the new collection.
+ $resp_doc = $this->getXml($result_url);
+ $this->assertExpectedCollectionNodes(array($test_collection), array($resp_doc));
+
+ // Ensure that the same content is found at the service doc URL.
+ $resp_doc = $this->getXml($this->service_url);
+ $nodes = $resp_doc->collections->children();
+ $this->assertExpectedCollectionNodes(array($test_collection), $nodes);
+
+ // Try editing collection details.
+ $this->put($result_url, array(
+ 'name' => 'edited name',
+ 'description' => 'edited description',
+ 'nickname' => 'edited nickname',
+ 'listed' => 'no'
+ ));
+ $this->assertResponse(200,
+ "PUT to update a collection should result in 200 OK");
+
+ // Assert that the edited details are in place.
+ $resp_doc = $this->getXml($result_url);
+ $new_details = array(
+ 'Collection' => array(
+ 'name' => 'edited name',
+ 'description' => 'edited description',
+ 'nickname' => 'edited nickname',
+ 'listed' => 'no'
+ )
+ );
+ $this->assertExpectedCollectionNodes(
+ array($new_details), array($resp_doc)
+ );
+
+ // Delete the collection and ensure it's gone.
+ $this->delete($result_url);
+ $this->assertResponse(410,
+ "DELETE to a collection resource should result in 410 Gone");
+ $this->get($result_url);
+ $this->assertResponse(404,
+ "GET to a deleted collection resource should result in 404 Not Found");
+
+ // Ensure that the deleted collection appears nowhere in the collections doc.
+ $resp_doc = $this->getXml($collections_url);
+ $nodes = $resp_doc->children();
+ foreach ($nodes as $node) {
+ $url = $this->resolveUrl($collections_url, $node['href']);
+ $this->assertNotEqual($url, $result_url,
+ 'The deleted collection resource should not be found in the collections document');
+ }
+
+ }
+
+ /**
+ * Create a collection, try adding and deleting some addons.
+ */
+ function testCollectionAddonCrud() {
+ $this->login();
+ $doc = $this->getXml($this->service_url);
+ $base_url = $this->getBaseUrl($this->service_url, $doc);
+ $collections_url =
+ $this->resolveUrl($base_url, $doc->collections['href']);
+
+ $this->post($collections_url, array(
+ 'name' => 'fresh addons',
+ 'description' => 'new collection expectant for addons'
+ ));
+
+ $this->assertResponse(201,
+ "POST to collections URL should result in 201 created");
+
+ $headers = $this->getBrowserHeaders();
+ $collection_url = $headers['location'];
+
+ $collection_doc = $this->getXml($collection_url);
+
+ $addons_url = $this->resolveUrl(
+ $this->getBaseUrl($collection_url, $collection_doc),
+ $collection_doc->addons['href']
+ );
+
+ $test_adds = array();
+ $guids = array_slice(array_keys($this->addons), 0, 5);
+
+ foreach ($guids as $guid) {
+
+ $data = array(
+ 'guid' => $guid,
+ 'comments' => "these are test notes for addon {$guid} " . rand(0,100)
+ );
+ $this->post($addons_url, $data);
+
+ $this->assertResponse(201,
+ "POST to collection URL ({$collection_url}) should result in 201 Created");
+
+ $headers = $this->getBrowserHeaders();
+ $this->assertTrue(isset($headers['location']),
+ 'Collection addon addition should yield a location: header');
+ $addon_url = $headers['location'];
+
+ $this->post($addons_url, $data);
+ $this->assertResponse(409,
+ "Attempt to add addon already added should result in 409 Conflict");
+
+ $addon_doc = $this->getXml($addon_url);
+
+ if ($addon_doc) {
+ $addon_base_url = $this->getBaseUrl($addon_url, $addon_doc);
+ $addon_collection_url = $this->resolveUrl(
+ $addon_base_url, @$addon_doc->meta->collection['href']
+ );
+ }
+
+ // Verify a link in addon back to its collection
+ $this->assertEqual(
+ $collection_url, $addon_collection_url,
+ 'Addon doc should have a reference back to collection ' .
+ $collection_url . ' == ' . $addon_collection_url
+ );
+
+ $this->assertEqual(
+ $this->nickname, @$addon_doc->meta->addedby,
+ 'addedby element should match name of the user who added it '.
+ '('.$this->nickname.'=='.(@$addon_doc->meta->addedby).')'
+ );
+
+ // Verify that the addon has submitted comments.
+ $this->assertEqual(
+ $data['comments'], @$addon_doc->meta->comments,
+ 'Comments in addon doc "' . (@$addon_doc->meta->comments) . '" '.
+ 'should match submitted comments "' . $data['comments'] . '"'
+ );
+
+ // Verify a addon details.
+ // TODO: verify more?
+ $this->assertTrue(
+ $this->addons[$guid]['Translation']['name']['string'] ==
+ @$addon_doc->name,
+ 'Name of addon in doc should match addon added'
+ );
+ // verify stats tracking codes in installation URL and learnmore URL
+ if (!empty($addon_doc->install)) {
+ $this->assertTrue(preg_match(
+ "/\?collection_id=.+&src=sharingapi/",
+ @$addon_doc->install),
+ "install URL ({$addon_doc->install}) should contain stats codes"
+ );
+ }
+ $this->assertTrue(preg_match(
+ "#addon/\d+/?\?src=sharingapi$#",
+ @$addon_doc->learnmore),
+ "learnmore link ({$addon_doc->learnmore}) should contain stats codes"
+ );
+
+ // Try changing the comments.
+ $data['comments'] = 'this has been edited! ' . $data['comments'];
+ $this->put($addon_url, array('comments' => $data['comments']));
+ $this->assertResponse(200,
+ "Attempt to edit addon should result in 200 OK");
+
+ // Re-fetch the addon, ensure the comments have been changed.
+ $addon_doc = $this->getXml($addon_url);
+ $this->assertEqual(
+ $data['comments'], (string)$addon_doc->meta->comments,
+ 'Comments in addon doc "' . (@$addon_doc->meta->comments) . '" '.
+ 'should match submitted comments "' . $data['comments'] . '"'
+ );
+
+ $data['url'] = $addon_url;
+ $test_adds[$guid] = $data;
+ }
+
+ // Now, fetch the collection document and look through its addons.
+ $collection_doc = $this->getXml($collection_url);
+ $nodes = $collection_doc->addons->addon;
+ $this->assertEqual(
+ count(array_keys($test_adds)), count($nodes),
+ 'Number of addons in the collection doc should reflect number added. ' .
+ count(array_keys($test_adds)) . '==' . count($nodes)
+ );
+
+ foreach ($nodes as $addon_node) {
+
+ $guid = (string)$addon_node->guid;
+ $data = @$test_adds[$guid];
+
+ if (empty($data)) {
+ $this->fail(
+ 'addons in collection doc should all have GUIDs '.
+ 'corresponding to addons submitted'
+ );
+ continue;
+ }
+
+ // Verify that the addon has submitted comments.
+ $this->assertEqual(
+ $data['comments'], @$addon_node->meta->comments,
+ 'Comments in addon doc "' . (@$addon_node->meta->comments) . '" '.
+ 'should match submitted comments "' . $data['comments'] . '"'
+ );
+
+ $this->assertEqual(
+ $this->nickname, @$addon_node->meta->addedby,
+ 'addedby element should match name of the user who added it '.
+ '('.$this->nickname.'=='.(@$addon_node->meta->addedby).')'
+ );
+
+ $this->assertTrue(
+ $this->addons[$guid]['Translation']['name']['string'] ==
+ @$addon_node->name,
+ 'Name of addon in doc should match addon added'
+ );
+
+ }
+
+ // Now try deleting all the addons and ensure that they're gone from
+ // the collection as individual documents.
+ foreach ($test_adds as $guid=>$data) {
+ $addon_url = $data['url'];
+ $this->delete($addon_url);
+ $this->assertResponse(410,
+ "Attempt to delete addon successfully should result in 410 Gone");
+ $this->get($addon_url);
+ $this->assertResponse(404,
+ "Attempt to get deleted addon should result in 404 Not Found");
+ }
+
+ // Finally, ensure that the addons are gone from the collection.
+ $collection_doc = $this->getXml($collection_url);
+ $nodes = $collection_doc->addon;
+ $this->assertEqual(0, count($nodes),
+ 'No addons should remain in the collection'
+ );
+
+ }
+
+ /**
+ * Ensure that Last-Modified / If-Modified-Since headers work as
+ * conditional GET to shortcircuit full responses with 304 Not Modified
+ * when there have been no changes, and to correctly return full 200 OK
+ * responses when there have been changes.
+ */
+ function testConditionalGet()
+ {
+ $this->login();
+ $doc = $this->getXml($this->service_url);
+
+ $base_url = $this->getBaseUrl($this->service_url, $doc);
+ $collections_url =
+ $this->resolveUrl($base_url, $doc->collections['href']);
+
+ $this->post($collections_url, array(
+ 'name' => 'fresh addons',
+ 'description' => 'new collection expectant for addons'
+ ));
+
+ $this->assertResponse(201,
+ "POST to collections URL should result in 201 created");
+
+ $headers = $this->getBrowserHeaders();
+ $collection_url = $headers['location'];
+
+ $collection_doc = $this->getXml($collection_url);
+
+ $collection_headers = $this->getBrowserHeaders();
+ $collection_modified = @$collection_headers['last-modified'];
+ $this->assertTrue(!empty($collection_modified),
+ 'Service doc should yield a last-modified header');
+
+ $this->setRequestHeaders(array(
+ 'If-Modified-Since: ' . date('r', strtotime($collection_modified))
+ ));
+ $resp = $this->get($collection_url);
+ $this->assertResponse(304,
+ "GET to unmodified collection doc should yield 304");
+
+ $this->setRequestHeaders(array());
+ $doc = $this->get($this->service_url);
+ $doc_headers = $this->getBrowserHeaders();
+ $doc_modified = @$doc_headers['last-modified'];
+ $this->assertTrue(!empty($doc_modified),
+ 'Service doc should yield a last-modified header');
+
+ $this->setRequestHeaders(array(
+ 'If-Modified-Since: ' . date('r', strtotime($doc_modified))
+ ));
+ $resp = $this->get($this->service_url);
+ $this->assertResponse(304,
+ "GET to service doc with unmodified collections should yield 304");
+
+ $this->put($collection_url, array(
+ 'name' => 'edited name',
+ 'description' => 'edited description',
+ 'nickname' => 'edited nickname',
+ 'listed' => 'no'
+ ));
+ $this->assertResponse(200,
+ "PUT to update a collection should result in 200 OK");
+
+ $this->setRequestHeaders(array(
+ 'If-Modified-Since: ' . date('r', strtotime($doc_modified))
+ ));
+ $resp = $this->get($this->service_url);
+ $this->assertResponse(200,
+ "GET to service doc since collection changed should yield 200 OK");
+
+ $addons_url = $this->resolveUrl(
+ $this->getBaseUrl($collection_url, $collection_doc),
+ $collection_doc->addons['href']
+ );
+
+ $test_adds = array();
+ $guids = array_slice(array_keys($this->addons), 0, 5);
+
+ foreach ($guids as $guid) {
+ $data = array(
+ 'guid' => $guid,
+ 'comments' => "these are test notes for addon {$guid} " . rand(0,100)
+ );
+ $this->post($addons_url, $data);
+ $this->assertResponse(201,
+ "POST to addons URL ({$addons_url}) should result in 201 Created");
+
+ $addon_headers = $this->getBrowserHeaders();
+ $addon_url = $addon_headers['location'];
+
+ $this->setRequestHeaders(array());
+ $addon = $this->get($addon_url);
+ $addon_headers = $this->getBrowserHeaders();
+ $addon_modified = @$addon_headers['last-modified'];
+ $this->assertTrue(!empty($addon_modified),
+ 'Addon should yield a last-modified header');
+
+ $this->setRequestHeaders(array(
+ 'If-Modified-Since: ' . date('r', strtotime($addon_modified))
+ ));
+ $resp = $this->get($addon_url);
+ $this->assertResponse(304,
+ "GET to addon doc with unmodified addon should yield 304");
+ $resp = $this->get($collection_url);
+ $this->assertResponse(304,
+ "GET to unmodified collection doc should yield 304");
+ $resp = $this->get($this->service_url);
+ $this->assertResponse(304,
+ "GET to unmodified service_doc doc should yield 304");
+
+ $this->put($addon_url, array(
+ 'comments' => 'edited comments'
+ ));
+
+ $this->setRequestHeaders(array(
+ 'If-Modified-Since: ' . date('r', strtotime($addon_modified))
+ ));
+ $resp = $this->get($addon_url);
+ $this->assertResponse(200,
+ "GET to addon doc with modified addon should yield 200");
+ $resp = $this->get($collection_url);
+ $this->assertResponse(200,
+ "GET to collection doc should yield 200");
+ $resp = $this->get($this->service_url);
+ $this->assertResponse(200,
+ "GET to service_doc doc should yield 200");
+ }
+
+ }
+
+ /**
+ * Ensure that valid collection types work.
+ */
+ function testCollectionTypes()
+ {
+ $this->login();
+ $doc = $this->getXml($this->service_url);
+
+ $base_url = $this->getBaseUrl($this->service_url, $doc);
+ $collections_url =
+ $this->resolveUrl($base_url, $doc->collections['href']);
+
+ $this->post($collections_url, array(
+ 'name' => 'fresh addons',
+ 'description' => 'new collection expectant for addons'
+ ));
+ $headers = $this->getBrowserHeaders();
+ $collection_doc = $this->getXml($headers['location']);
+ $this->assertTrue($collection_doc['type'] == 'autopublisher',
+ "Default type should be 'autopublisher'");
+
+ $this->post($collections_url, array(
+ 'name' => 'fresh addons',
+ 'description' => 'new collection expectant for addons',
+ 'type' => 'normal'
+ ));
+ $headers = $this->getBrowserHeaders();
+ $collection_doc = $this->getXml($headers['location']);
+ $this->assertTrue($collection_doc['type'] == 'normal',
+ "Type 'normal' should be allowed.");
+
+ $this->post($collections_url, array(
+ 'name' => 'fresh addons',
+ 'description' => 'new collection expectant for addons',
+ 'type' => 'editorspick'
+ ));
+ $headers = $this->getBrowserHeaders();
+ $collection_doc = $this->getXml($headers['location']);
+ $this->assertTrue($collection_doc['type'] == 'editorspick',
+ "Type 'editorspick' should be allowed.");
+
+ $this->post($collections_url, array(
+ 'name' => 'fresh addons',
+ 'description' => 'new collection expectant for addons',
+ 'type' => 'spacemonkey'
+ ));
+ $headers = $this->getBrowserHeaders();
+ $collection_doc = $this->getXml($headers['location']);
+ $this->assertTrue($collection_doc['type'] == 'autopublisher',
+ "Unknown type should result in default 'autopublisher'");
+ }
+
+ /**
+ * Bug 486125: Sharing API should accept names with apostrophes
+ */
+ public function testCollectionNamesWithApostrophesShouldBeAccepted()
+ {
+ $this->login();
+ $doc = $this->getXml($this->service_url);
+
+ $base_url = $this->getBaseUrl($this->service_url, $doc);
+ $collections_url =
+ $this->resolveUrl($base_url, $doc->collections['href']);
+
+ $this->post($collections_url, array(
+ 'name' => "Someone's collection",
+ 'description' => "This is also someone's collection"
+ ));
+
+ $this->assertResponse(201,
+ "POST to collections URL should result in 201 Created");
+
+ $headers = $this->getBrowserHeaders();
+ $collection_url = $headers['location'];
+ $collection_doc = $this->getXml($headers['location']);
+
+ $addons_url = $this->resolveUrl(
+ $this->getBaseUrl($collection_url, $collection_doc),
+ $collection_doc->addons['href']
+ );
+
+ $guids = array_slice(array_keys($this->addons), 0, 5);
+ foreach ($guids as $guid) {
+
+ $data = array(
+ 'guid' => $guid,
+ 'comments' => "these are someone's test notes for addon {$guid} " . rand(0,100)
+ );
+ $this->post($addons_url, $data);
+
+ $this->assertResponse(201,
+ "POST to collection URL ({$collection_url}) should result in 201 Created");
+
+ }
+
+ }
+
+ /**
+ * Bug 486126: Sharing API should return new resources rather than empty document
+ */
+ function testResourceCreationShouldRespondWithNewResourceData()
+ {
+
+ $this->login();
+ $doc = $this->getXml($this->service_url);
+ $base_url = $this->getBaseUrl($this->service_url, $doc);
+ $collections_url =
+ $this->resolveUrl($base_url, $doc->collections['href']);
+
+ $this->post($collections_url, array(
+ 'name' => 'fresh addons',
+ 'description' => 'new collection expectant for addons'
+ ));
+
+ $this->assertResponse(201,
+ "POST to collections URL should result in 201 created");
+ $resp_doc = simplexml_load_string($this->getBrowser()->getContent());
+ $this->assertTrue(!empty($resp_doc));
+
+ $headers = $this->getBrowserHeaders();
+ $collection_url = $headers['location'];
+ $collection_doc = $this->getXml($collection_url);
+
+ $this->assertEqual(
+ (string)$resp_doc['name'], (string)$collection_doc['name']
+ );
+
+ $addons_url = $this->resolveUrl(
+ $this->getBaseUrl($collection_url, $collection_doc),
+ $collection_doc->addons['href']
+ );
+
+ $test_adds = array();
+ $guids = array_slice(array_keys($this->addons), 0, 5);
+
+ foreach ($guids as $guid) {
+
+ $data = array(
+ 'guid' => $guid,
+ 'comments' => "these are test notes for addon {$guid} " . rand(0,100)
+ );
+ $this->post($addons_url, $data);
+
+ $this->assertResponse(201,
+ "POST to collection URL ({$collection_url}) should result in 201 Created");
+ $content = $this->getBrowser()->getContent();
+
+ $resp_doc = simplexml_load_string($content);
+ $this->assertTrue(!empty($resp_doc));
+
+ $headers = $this->getBrowserHeaders();
+ $addon_url = $headers['location'];
+
+ $addon_doc = $this->getXML($addon_url);
+
+ $this->assertEqual(
+ (string)$resp_doc->meta->comments,
+ (string)$addon_doc->meta->comments
+ );
+
+ }
+
+ }
+
+ /**
+ * Bug 486145: Auth token resource
+ */
+ function testAuthResourceShouldYieldUsableAuthToken()
+ {
+ // Try fetching the service document, but assert that auth is required.
+ $service_doc = $this->getXML($this->service_url);
+ $this->assertAuthentication('Basic');
+ $this->assertResponse(401);
+ $this->assertEqual(
+ 'unauthorized', $service_doc['reason'],
+ 'GET to service doc without auth should yield unauthorized error'
+ );
+ $this->assertTrue(
+ !empty($service_doc['href']),
+ 'Error should offer href for auth'
+ );
+
+ $auth_url = (string)$service_doc['href'];
+
+ // GET without auth should be 401 Unauthorized.
+ $auth_doc = $this->getXML($auth_url);
+ $this->assertAuthentication('Basic');
+ $this->assertResponse(401);
+
+ // Try basic auth, which should get through to a 405 Method Not Allowed
+ $this->authenticate($this->username, $this->password);
+ $doc = $this->getXml($auth_url);
+ $this->assertResponse(405);
+
+ // Try a post with basic auth and expect a token.
+ $this->authenticate($this->username, $this->password);
+ $this->post($auth_url, array());
+ $content = $this->getBrowser()->getContent();
+ $auth_doc = simplexml_load_string($content);
+ $this->assertTrue(
+ !empty($auth_doc['value']),
+ "Auth doc should offer a token"
+ );
+ $auth_token = (string)$auth_doc['value'];
+ $auth_token_url = (string)$auth_doc['href'];
+ $this->restart();
+
+ // Invalid token should result in error
+ $this->setRequestHeaders(array('X-API-Auth: THISISNOTAVALIDTOKEN'));
+ $service_doc = $this->getXML($this->service_url);
+ $this->assertResponse(401,
+ 'Invalid token should throw 401');
+ $this->restart();
+
+ // Valid token should work
+ $this->setRequestHeaders(array('X-API-Auth: ' . $auth_token));
+ $service_doc = $this->getXML($this->service_url);
+ $this->assertResponse(200,
+ 'Valid token should yield 200');
+ $this->restart();
+
+ // Valid token URL should work.
+ $this->setRequestHeaders(array('X-API-Auth: ' . $auth_token_url));
+ $service_doc = $this->getXML($this->service_url);
+ $this->assertResponse(200,
+ 'Valid token URL should yield 200');
+ $this->restart();
+
+ // Try deleting the token to invalidate it
+ $this->setRequestHeaders(array('X-API-Auth: ' . $auth_token));
+ $this->delete($auth_token_url);
+ $this->assertResponse(410,
+ 'DELETE of an auth URL should result in 410');
+ $this->restart();
+
+ // Token should no longer be accepted.
+ $this->setRequestHeaders(array('X-API-Auth: ' . $auth_token));
+ $service_doc = $this->getXML($this->service_url);
+ $this->assertResponse(401,
+ 'Token should no longer be accepted after DELETE');
+ $this->restart();
+ }
+
+ /**
+ * bug 487397: Ensure that collections have default icons.
+ */
+ function testCollectionDefaultIconUrl()
+ {
+ $expected_default_image = $this->rawURI("/img/collection.png");
+
+ // Login and create a collection.
+ $this->login();
+ $doc = $this->getXml($this->service_url);
+ $base_url = $this->getBaseUrl($this->service_url, $doc);
+ $collections_url =
+ $this->resolveUrl($base_url, $doc->collections['href']);
+
+ $this->post($collections_url, array(
+ 'name' => 'fresh addons',
+ 'description' => 'new collection expectant for addons'
+ ));
+
+ // Ensure the icon appears in the new response.
+ $resp_doc = simplexml_load_string($this->getBrowser()->getContent());
+ $this->assertEqual(
+ (string)$resp_doc['icon'],
+ $expected_default_image
+ );
+
+ // Grab the new collection and look for the icon.
+ $headers = $this->getBrowserHeaders();
+ $collection_url = $headers['location'];
+ $collection_doc = $this->getXml($collection_url);
+ $this->assertEqual(
+ (string)$collection_doc['icon'],
+ $expected_default_image
+ );
+
+ // Reload the service doc and look for the icon in the new collection.
+ $service_doc = $this->getXml($this->service_url);
+ $this->assertEqual(
+ (string)$service_doc->collections->collection[0]['icon'],
+ $expected_default_image
+ );
+ }
+
+ /**
+ * Bug 488154: Ensure that collections can have custom icons
+ */
+ function testCollectionCustomIconUrl()
+ {
+ $expected_icon_pattern = '#/images/collection_icon/\d+#';
+ $iconfile = ROOT.DS.APP_DIR.DS.WEBROOT_DIR.DS.'img'.DS.'collection.png';
+
+ // Login and create a collection.
+ $this->login();
+ $doc = $this->getXml($this->service_url);
+ $base_url = $this->getBaseUrl($this->service_url, $doc);
+ $collections_url =
+ $this->resolveUrl($base_url, $doc->collections['href']);
+
+ $this->postMultipart($collections_url, array(
+ 'name' => 'fresh addons',
+ 'description' => 'new collection expectant for addons'
+ ), array(
+ 'icon' => $iconfile // attach icon
+ ));
+
+ // Ensure the icon appears in the new response.
+ $resp_doc = simplexml_load_string($this->getBrowser()->getContent());
+ $this->assertTrue(preg_match(
+ $expected_icon_pattern,
+ (string)$resp_doc['icon']), 'custom icon in "new" response'
+ );
+
+ // Grab the new collection and look for the icon.
+ $headers = $this->getBrowserHeaders();
+ $collection_url = $headers['location'];
+ $collection_doc = $this->getXml($collection_url);
+ $this->assertTrue(preg_match(
+ $expected_icon_pattern,
+ (string)$collection_doc['icon']),
+ 'custom icon in collection details'
+ );
+
+ // Reload the service doc and look for the icon in the new collection.
+ $service_doc = $this->getXml($this->service_url);
+ $this->assertTrue(preg_match(
+ $expected_icon_pattern,
+ (string)$service_doc->collections->collection[0]['icon']),
+ 'custom icon in service doc'
+ );
+ }
+
+ /**
+ * Bug 486142: Collection subscribe / unsubscribe
+ */
+ function testSubscriptions()
+ {
+ $collections = $this->createTestCollectionsWithMoreUsers();
+
+ $collection_urls = array();
+
+ // First, login as all known test users and discover all known collections by URL.
+ foreach ($this->all_test_users as $user) {
+ $this->login($user['User']['email'], 'test');
+ $service_doc = $this->getXml($this->service_url);
+ $base_url = $this->getBaseUrl($this->service_url, $service_doc);
+ $collections_url =
+ $this->resolveUrl($base_url, $service_doc->collections['href']);
+ foreach ($service_doc->collections->children() as $node) {
+ $collection_urls[$this->resolveUrl(
+ $base_url, $node['href']
+ )] = 1;
+ }
+ }
+ $collection_urls = array_keys($collection_urls);
+
+ $this->login();
+
+ $service_doc = $this->getXml($this->service_url);
+ $base_url = $this->getBaseUrl($this->service_url, $service_doc);
+ $this->assertEqual(
+ 1, count($service_doc->collections->children()),
+ 'Main test user should only see one known collection, initially'
+ );
+ $this->assertEqual(
+ 'no', (string)$service_doc->collections->collection[0]['subscribed'],
+ 'Initial known collection should not yet be subscribed'
+ );
+
+ foreach ($collection_urls as $collection_url) {
+ $this->put($collection_url, array('subscribed' => 'yes'));
+ $this->assertResponse(200,
+ "PUT to set collection 'subscribed' flag should yield 200 OK, ".
+ "regardless of writable permission");
+ }
+
+ $service_doc = $this->getXml($this->service_url);
+ $base_url = $this->getBaseUrl($this->service_url, $service_doc);
+ $this->assertEqual(
+ 6, count($service_doc->collections->children()),
+ 'Main test user should now see 5 collections'
+ );
+
+ foreach ($service_doc->collections->collection as $collection) {
+ $this->assertEqual(
+ 'yes', (string)$collection['subscribed'],
+ 'Known collections should be subscribed now'
+ );
+ }
+
+ foreach ($collection_urls as $idx=>$collection_url) {
+ if (0 == $idx) {
+ $this->put($collection_url, array('name' => 'this should work'));
+ $this->assertResponse(200,
+ "PUT on the main test user's collection should work");
+ } else {
+ $this->put($collection_url, array('name' => 'this should not work'));
+ $this->assertResponse(403,
+ "PUT of any other properties should fail on other's collections");
+ }
+ }
+
+ foreach ($collection_urls as $collection_url) {
+ $this->put($collection_url, array('subscribed' => 'no'));
+ $this->assertResponse(200,
+ "PUT to set collection 'subscribed' flag should yield 200 OK, ".
+ "regardless of writable permission");
+ }
+
+ $service_doc = $this->getXml($this->service_url);
+ $base_url = $this->getBaseUrl($this->service_url, $service_doc);
+ $this->assertEqual(
+ 1, count($service_doc->collections->children()),
+ 'Main test user should only see one known collection after unsubscribing'
+ );
+ $this->assertEqual(
+ 'no', (string)$service_doc->collections->collection[0]['subscribed'],
+ 'Initial known collection should not yet be subscribed'
+ );
+
+
+ }
+
+ /**
+ * Bug 487427: Ensure proper comments and added-by appear for addons
+ * appearing in multiple collections
+ */
+ function testAddonCommentsAndAddedByAssociatedWithCorrectUsers()
+ {
+ $collections = $this->createTestCollectionsWithMoreUsers();
+
+ $collection_urls = array();
+
+ $addon_guids = array_keys($this->addons);
+ $addon_guid = $addon_guids[0];
+
+ foreach ($this->all_test_users as $user) {
+ $this->login($user['User']['email'], 'test');
+
+ $service_doc = $this->getXml($this->service_url);
+ $base_url = $this->getBaseUrl($this->service_url, $service_doc);
+ $collections_url = $this->resolveUrl($base_url, $service_doc->collections['href']);
+
+ $node = $service_doc->collections->collection[0];
+
+ $collection_url = $this->resolveUrl($base_url, $node['href']);
+ $collection_doc = $this->getXml($collection_url);
+
+ $addons_url = $this->resolveUrl(
+ $this->getBaseUrl($collection_url, $collection_doc),
+ $collection_doc->addons['href']
+ );
+
+ $data = array(
+ 'guid' => $addon_guid,
+ 'comments' => "notes for addon {$addon_guid} by {$user['User']['email']}"
+ );
+ $this->post($addons_url, $data);
+ }
+
+ foreach ($this->all_test_users as $user) {
+ $this->login($user['User']['email'], 'test');
+
+ $service_doc = $this->getXml($this->service_url);
+ $base_url = $this->getBaseUrl($this->service_url, $service_doc);
+ $collections_url = $this->resolveUrl($base_url, $service_doc->collections['href']);
+
+ $node = $service_doc->collections->collection[0];
+
+ $collection_url = $this->resolveUrl($base_url, $node['href']);
+ $collection_doc = $this->getXml($collection_url);
+
+ $addon = $collection_doc->addons->addon[0];
+
+ $this->assertEqual(
+ $addon->guid, $addon_guid,
+ "Addon GUID should match what was added"
+ );
+
+ $this->assertEqual(
+ $addon->meta->comments,
+ "notes for addon {$addon_guid} by {$user['User']['email']}",
+ "Addon comments should match what was added"
+ );
+
+ $user_display_name = !empty($user['User']['nickname']) ?
+ $user['User']['nickname'] :
+ "{$user['User']['firstname']} {$user['User']['lastname']}";
+ $this->assertEqual(
+ $addon->meta->addedby, $user_display_name,
+ "Addon user name should match what was added"
+ );
+
+ }
+
+ }
+
+ /**
+ * Bug 494317: Ensure that experimental addons in collections offer
+ * an <install> element.
+ */
+ function testExperimentalAddonInstallInCollections()
+ {
+ // Assemble a list of unique addon GUIDs, at least one of which is
+ // experimental.
+ $addon_guids = array(
+ // Known experimental addon in test data
+ '{A17C1C5A-04C1-11DB-9805-B632A1EF5496}',
+ // Other known addons with files available
+ 'farming@microfarmer.org',
+ 'fisher@farmerland.org',
+ 'hunter@farmerland.org',
+ );
+
+ // Login and get a handle on the collections URL
+ $this->login();
+ $doc = $this->getXml($this->service_url);
+ $base_url = $this->getBaseUrl($this->service_url, $doc);
+ $collections_url =
+ $this->resolveUrl($base_url, $doc->collections['href']);
+
+ // Create the new collection.
+ $this->post($collections_url, array(
+ 'name' => 'experiments included',
+ 'description' => 'this collection includes experimental addons'
+ ));
+ $headers = $this->getBrowserHeaders();
+ $collection_url = $headers['location'];
+ $collection_doc = $this->getXml($collection_url);
+ $addons_url = $this->resolveUrl(
+ $this->getBaseUrl($collection_url, $collection_doc),
+ $collection_doc->addons['href']
+ );
+
+ // Add the known addons to the collection.
+ foreach ($addon_guids as $guid) {
+ $data = array(
+ 'guid' => $guid,
+ 'comments' => "these are test notes for addon {$guid} " . rand(0,100)
+ );
+ $this->post($addons_url, $data);
+ }
+
+ // Now, fetch the collection document and look through its addons.
+ $collection_doc = $this->getXml($collection_url);
+ $nodes = $collection_doc->addons->addon;
+
+ // Assert that install elements exist on all addons in the collection
+ foreach ($nodes as $addon_node) {
+ $this->assertTrue(
+ !empty($addon_node->install),
+ "Addon {$addon_node->guid} in collection should have install element"
+ );
+ }
+ }
+
+ function testEmailSharing()
+ {
+ $this->fail('TODO: Test out email sharing');
+ }
+
+ function testUserRolesAuthorization()
+ {
+ $this->fail('TODO: Ensure writable flag works in collections');
+ $this->fail('TODO: Ensure editing / deletion of collections forbidden without proper roles');
+ $this->fail('TODO: Ensure adding / removing addons in collections forbidden without proper roles');
+ }
+
+ /**
+ * Set request headers for the next request.
+ */
+ function setRequestHeaders($headers) {
+ // HACK: The browser / user agent offers no way to replace headers
+ // between requests, so digging into the actual array maintained by the
+ // user agent itself.
+ $user_agent = $this->getBrowser()->_user_agent;
+ // Store any existing headers on the user_agent so things like
+ // X-AMO-TEST aren't broken.
+ if (!isset($user_agent->_original_headers)) {
+ $user_agent->_original_headers = $user_agent->_additional_headers;
+ }
+ $user_agent->_additional_headers = array_merge($user_agent->_original_headers, $headers);
+ }
+
+ /**
+ * Issue a GET request for XML at a URL
+ *
+ * @param string URL
+ * @return SimpleXML
+ */
+ function getXml($url) {
+ $this->get($url);
+ $resp_doc = simplexml_load_string($this->getBrowser()->getContent());
+ if (!$resp_doc) {
+ return $this->fail('failed to parse document at ' . $url);
+ }
+ return $resp_doc;
+ }
+
+ /**
+ * Get raw headers from the scriptable browser and parse into an assoc
+ * array.
+ */
+ function getBrowserHeaders() {
+ $headers = array();
+ foreach (split("\r\n", $this->getBrowser()->getHeaders()) as $part) {
+ if (FALSE !== ($pos = strpos($part, ': '))) {
+ $headers[strtolower(substr($part, 0, $pos))] =
+ substr($part, $pos+2, strlen($part)-($pos+2));
+ }
+ }
+ return $headers;
+ }
+
+ /**
+ * Create a set of test collections in the DB and return an array of the
+ * records created.
+ */
+ function createTestCollections()
+ {
+ $user_id = $this->test_user['User']['id'];
+ $test_collections = array(
+ array(
+ 'Collection' => array(
+ 'name' => 'Testing 1',
+ 'description' => 'first test collection',
+ 'nickname' => 'test1',
+ 'listed' => 1
+ )
+ ),
+ array(
+ 'Collection' => array(
+ 'name' => 'Testing 2',
+ 'description' => 'second test collection',
+ 'nickname' => 'test2',
+ 'listed' => 1
+ )
+ ),
+ array(
+ 'Collection' => array(
+ 'name' => 'Testing 3',
+ 'description' => 'third test collection',
+ 'nickname' => 'test3',
+ 'listed' => 1
+ )
+ )
+ );
+ foreach ($test_collections as $collection) {
+ $this->Collection->create();
+ $this->Collection->save($collection);
+ $new_id = $this->Collection->id;
+ $this->Collection->addUser(
+ $new_id, $user_id, COLLECTION_ROLE_OWNER
+ );
+ }
+ return $test_collections;
+ }
+
+ /**
+ * Create test collections, but with different owners than the main test
+ * user.
+ *
+ * @return array List of collections created in model
+ */
+ function createTestCollectionsWithMoreUsers()
+ {
+ $test_collections = array(
+ array(
+ $this->test_user,
+ array(
+ 'Collection' => array(
+ 'name' => 'Testing 0',
+ 'description' => 'zeroth test collection',
+ 'nickname' => 'test0',
+ 'listed' => 1
+ )
+ )
+ ),
+ array(
+ $this->test_user_2,
+ array(
+ 'Collection' => array(
+ 'name' => 'Testing 1',
+ 'description' => 'first test collection',
+ 'nickname' => 'test1',
+ 'listed' => 1
+ )
+ )
+ ),
+ array(
+ $this->test_user_3,
+ array(
+ 'Collection' => array(
+ 'name' => 'Testing 2',
+ 'description' => 'second test collection',
+ 'nickname' => 'test2',
+ 'listed' => 1
+ )
+ )
+ ),
+ array(
+ $this->test_user_2,
+ array(
+ 'Collection' => array(
+ 'name' => 'Testing 3',
+ 'description' => 'third test collection',
+ 'nickname' => 'test3',
+ 'listed' => 1
+ )
+ )
+ ),
+ array(
+ $this->test_user_3,
+ array(
+ 'Collection' => array(
+ 'name' => 'Testing 4',
+ 'description' => 'fourth test collection',
+ 'nickname' => 'test4',
+ 'listed' => 1
+ )
+ )
+ ),
+ array(
+ $this->test_user_4,
+ array(
+ 'Collection' => array(
+ 'name' => 'Testing 5',
+ 'description' => 'fifth test collection',
+ 'nickname' => 'test5',
+ 'listed' => 1
+ )
+ )
+ ),
+ );
+
+ $collections = array();
+ foreach ($test_collections as $item) {
+ list($user, $collection) = $item;
+ $this->Collection->create();
+ $this->Collection->save($collection);
+ $new_id = $this->Collection->id;
+ $this->Collection->addUser(
+ $new_id, $user['User']['id'], COLLECTION_ROLE_OWNER
+ );
+ $collections[] = $this->Collection->findById($new_id);
+ }
+
+ return $collections;
+ }
+
+ /**
+ * Given a set of test collections and simplexml nodes from a collection
+ * document, assert that they match.
+ *
+ * @param mixed set of test collections
+ * @param mixed set of simplexml nodes from a collection document
+ */
+ function assertExpectedCollectionNodes($test_collections, $nodes) {
+ global $app_shortnames;
+
+ $this->assertEqual(count($test_collections), count($nodes),
+ 'expected count of collections '.
+ '('.count($test_collections).'=='.count($nodes).')'
+ );
+
+ for ($i=0; $i<count($test_collections); $i++) {
+ $result = $nodes[$i];
+ $test_data = $test_collections[$i]['Collection'];
+ $test_user = $this->User->findById($this->test_user['User']['id']);
+
+ $expected = array(
+ 'name' => $test_data['name'],
+ 'description' => $test_data['description'],
+ 'creator' => isset($test_user['User']['nickname']) ?
+ $test_user['User']['nickname'] :
+ "{$test_user['User']['firstname']} {$test_user['User']['lastname']}"
+ );
+ if (isset($test_data['app'])) {
+ $expected['app'] = $test_data['app'];
+ }
+
+ foreach ($expected as $k => $v) {
+ $this->assertEqual($v, $result[$k], "{$v} == {$result[$k]}");
+ }
+
+ }
+
+ }
+
+ /**
+ * Logs in with test account info.
+ */
+ function login($username='nobody@mozilla.org', $password='test') {
+ $this->restart();
+ $path = $this->actionURI('/users/login');
+ $data = array(
+ 'data[Login][email]' => $username,
+ 'data[Login][password]' => $password
+ );
+ $this->post($path, $data);
+ $this->assertNoUnwantedText(
+ _('error_username_or_pw_wrong'),
+ 'Logged in with '.$username.' account'
+ );
+ }
+
+ /**
+ * Given a default base URL and a SimpleXML document, return a base URL.
+ */
+ function getBaseUrl($base_url, $doc) {
+ if (empty($doc)) return null;
+ $attrs = $doc->attributes(self::XML_NS);
+ if (!empty($attrs['base']))
+ $base_url = $this->resolveUrl($base_url, (string)$attrs['base']);
+ return $base_url;
+ }
+
+ /**
+ * Given a base URL and a relative URL, produce an absolute URL.
+ * see: http://us.php.net/manual/en/function.parse-url.php#76979
+ */
+ function resolveUrl($base, $url) {
+ if (!strlen($base)) return $url;
+ if (!strlen($url)) return $base;
+ if (preg_match('!^[a-z]+:!i', $url)) return $url;
+
+ $base = parse_url($base);
+ if ($url{0} == "#") {
+ $base['fragment'] = substr($url, 1);
+ return $this->unparseUrl($base);
+ }
+ unset($base['fragment']);
+ unset($base['query']);
+
+ if (substr($url, 0, 2) == "//") {
+ return $this->unparseUrl(array(
+ 'scheme'=>$base['scheme'],
+ 'path'=>substr($url,2),
+ ));
+ } else if ($url{0} == "/") {
+ $base['path'] = $url;
+ } else {
+ $path = explode('/', $base['path']);
+ $url_path = explode('/', $url);
+ array_pop($path);
+ $end = array_pop($url_path);
+ foreach ($url_path as $segment) {
+ if ($segment == '.') {
+ // skip
+ } else if ($segment == '..' && $path && $path[sizeof($path)-1] != '..') {
+ array_pop($path);
+ } else {
+ $path[] = $segment;
+ }
+ }
+ if ($end == '.') {
+ $path[] = '';
+ } else if ($end == '..' && $path && $path[sizeof($path)-1] != '..') {
+ $path[sizeof($path)-1] = '';
+ } else {
+ $path[] = $end;
+ }
+ $base['path'] = join('/', $path);
+
+ }
+ return $this->unparseUrl($base);
+ }
+
+ /**
+ * Given the results of parse_url, produce a URL.
+ * see: http://us.php.net/manual/en/function.parse-url.php#85963
+ */
+ function unparseUrl($parsed)
+ {
+ if (!is_array($parsed)) return false;
+
+ $uri = isset($parsed['scheme']) ? $parsed['scheme'].':'.((strtolower($parsed['scheme']) == 'mailto') ? '' : '//') : '';
+ $uri .= isset($parsed['user']) ? $parsed['user'].(isset($parsed['pass']) ? ':'.$parsed['pass'] : '').'@' : '';
+ $uri .= isset($parsed['host']) ? $parsed['host'] : '';
+ $uri .= isset($parsed['port']) ? ':'.$parsed['port'] : '';
+
+ if (isset($parsed['path'])) {
+ $uri .= (substr($parsed['path'], 0, 1) == '/') ?
+ $parsed['path'] : ((!empty($uri) ? '/' : '' ) . $parsed['path']);
+ }
+
+ $uri .= isset($parsed['query']) ? '?'.$parsed['query'] : '';
+ $uri .= isset($parsed['fragment']) ? '#'.$parsed['fragment'] : '';
+
+ return $uri;
+ }
+
+}
diff --git a/site/app/tests/controllers/users_controller.test.php b/site/app/tests/controllers/users_controller.test.php
new file mode 100644
index 0000000..e45e495
--- /dev/null
+++ b/site/app/tests/controllers/users_controller.test.php
@@ -0,0 +1,342 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Frederic Wenzel <fwenzel@mozilla.com> (Original Author)
+ * Michael Morgan <morgamic@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+class UsersTest extends UnitTestCase {
+
+ /**
+ * Test user data
+ */
+ var $testdata = array(
+ 'email' => 'test@example.com',
+ 'password' => 'topsecret',
+ 'confirmpw' => 'topsecret',
+ 'firstname' => 'John',
+ 'lastname' => 'Doe',
+ 'nickname' => 'Johnnie',
+ 'emailhidden' => 1,
+ 'sandboxshown' => 1,
+ 'homepage' => 'http://mozilla.org',
+ );
+
+ /**
+ * Register Test user
+ * @access private
+ */
+ function _registerTestUser() {
+ $this->controller->params['controller'] = 'Users';
+ $this->controller->data['User'] = $this->testdata;
+ $this->helper->callControllerAction($this->controller, 'register', $this);
+ return $this->controller->User->getLastInsertId();
+ }
+
+ /**
+ * Set up the users controller
+ */
+ function testLoad() {
+ $this->helper = new UnitTestHelper();
+ $this->controller = $this->helper->getController('Users', $this);
+ $this->helper->mockComponents($this->controller, $this);
+ $this->controller->User->cacheQueries = false; // important! Otherwise cake doesn't realize when we changed the user data.
+ $this->controller->User->caching = false; // important! Otherwise memcache will break stuff.
+
+ // Prevent exceptions in other parts of the world.
+ $this->controller->Amo->setReturnValue('getApplicationVersions',
+ array(1 => array(1.5, 2.0, 3.0),
+ 18 => array(1.5, 2.0, 3.0)));
+ $this->controller->params['url'] = array();
+ }
+
+ /**
+ * Will a new user show up in the user table when the registration data
+ * is entered?
+ */
+ function testRegistration() {
+ // register and send confirmation email
+ $this->controller->Email =& new MockEmailComponent();
+ $this->controller->Email->expectOnce('send', false, 'Send confirmation email');
+ $id = $this->_registerTestUser();
+ $this->controller->Email->tally();
+
+ // resend confirmation email on request
+ $this->controller->Email =& new MockEmailComponent();
+ $this->controller->Email->expectOnce('send', false, 'Resend confirmation email on user request');
+ $this->helper->callControllerAction($this->controller, 'verify', $this, array($id, 'resend'));
+ $this->controller->Email->tally();
+
+ $storeddata = $this->controller->User->findById($id);
+
+ // user created, at all?
+ $this->assertNotEqual($storeddata['User']['id'], 0, 'User creation');
+
+ // data correctly stored?
+ foreach (array_keys($this->testdata) as $field) {
+ if ($field == 'password' || $field == 'confirmpw') continue;
+ $this->assertEqual($this->testdata[$field], $storeddata['User'][$field], "Data for $field stored");
+ }
+
+ $validPassword = $this->controller->User->_checkPassword(
+ $this->testdata['password'], $storeddata['User']['password']);
+ $this->assertTrue($validPassword, "Data for password stored");
+
+ $this->assertTrue(preg_match('/^[0-9a-f]{32}$/', strtolower($storeddata['User']['confirmationcode'])), 'Creating confirmation code');
+
+ // delete user record, if it was created before
+ if ($this->controller->User->id != 0) @$this->controller->User->del();
+ }
+
+ /**
+ * Does an already taken username get rejected from re-registering?
+ */
+ function testDuplicateUserRegistration() {
+ $this->_registerTestUser();
+ // try adding the same user again
+ $this->_registerTestUser();
+
+ $usersfound = $this->controller->User->find("User.email = '{$this->testdata['email']}'");
+ $this->assertTrue(isset($usersfound['User']['id']), 'No duplicate user generation');
+
+ foreach ($usersfound as $singleuser) {
+ @$this->controller->User->del($singleuser['User']['id']);
+ }
+ }
+
+ /*
+ * Does the generated confirmation code unlock the user account?
+ */
+ function testConfimationCodeWorks() {
+ $id = $this->_registerTestUser();
+
+ $data = $this->controller->User->findById($id);
+
+ $this->helper->callControllerAction($this->controller, 'verify', $this, array($id, $data['User']['confirmationcode']));
+
+ $this->controller->User->data = null;
+ $data = $this->controller->User->findById($id);
+
+ $this->assertEqual($data['User']['confirmationcode'], '', 'Confirmation code removed after verification');
+
+ @$this->controller->User->del($id);
+ }
+
+ /*
+ * Does an invalid confirmation code not unlock the account?
+ */
+ function testInvalidConfimationCodeRejected() {
+ $this->_registerTestUser();
+ $origdata = $this->controller->User->read();
+
+ $this->helper->callControllerAction($this->controller, 'verify', $this, array($origdata['User']['id'], 'some random wrong code'));
+
+ $data = $this->controller->User->findById($origdata['User']['id']);
+
+ $this->assertEqual($data['User']['confirmationcode'],
+ $origdata['User']['confirmationcode'], 'Confirmation code not to be removed on invalid confirmation attempt');
+
+ @$this->controller->User->del($data['User']['id']);
+ }
+
+ /**
+ * Do not allow sending an additional confirmation email to a user
+ * who's already confirmed.
+ */
+ function testNoConfirmationEmailResendForConfirmedUsers() {
+ $this->controller->Email =& new MockEmailComponent();
+ $this->controller->Email->expectNever('send', 'Not sending confirmation email to confirmed user');
+ // user id is our login user and therefore confirmed
+ $this->helper->callControllerAction($this->controller, 'verify', $this, array('5', 'resend'));
+ // re-instanciate the email component so it doesn't react to later
+ // calls of send
+ $this->controller->Email =& new MockEmailComponent();
+ }
+
+ /**
+ * Can I not log in when the account was not confirmed yet?
+ */
+ function testUnconfirmedAccountLogin() {
+ // re-mock session component to clear previous expectations
+ $this->controller->Session =& new MockSessionComponent();
+ $this->_registerTestUser();
+
+ $this->controller->data = array();
+ $this->controller->data['Login']['email'] = $this->testdata['email'];
+ $this->controller->data['Login']['password'] = $this->testdata['password'];
+
+ // no session should be generated
+ $this->controller->Session->expectNever('write', 'Login with unconfirmed user account');
+ $this->helper->callControllerAction($this->controller, 'login', $this);
+ $this->controller->Session->tally();
+
+ @$this->controller->User->del($this->controller->User->getLastInsertId());
+ }
+
+ /**
+ * Can I reset the password with the right code?
+ */
+ function testPasswordResetPossible() {
+ $bill = $this->controller->User->findByEmail('bill@ms.com');
+ $oldpw = $bill['User']['password'];
+ $data['password'] = 'my_new_password';
+ $data['confirmpw'] = 'my_new_password';
+
+ // Start the reset process so we can get a valid reset code.
+ $resetCode = $this->controller->User->setResetCode($bill['User']['id']);
+
+ $this->controller->data['User'] = $data;
+ $this->helper->callControllerAction($this->controller, 'pwreset', $this, array($bill['User']['id'], $resetCode));
+
+ $newdata = $this->controller->User->find("User.email = 'bill@ms.com'");
+
+ $validPassword = $this->controller->User->_checkPassword(
+ 'my_new_password' , $newdata['User']['password']);
+ $this->assertTrue($validPassword, 'Password reset');
+
+ // reset the pw
+ $this->controller->User->id = $bill['User']['id'];
+ $this->controller->User->saveField('password', $oldpw);
+ }
+
+ /**
+ * Can I NOT reset the password with the wrong code?
+ */
+ function testPasswordResetWithIncorrectCode() {
+ $bill = $this->controller->User->findByEmail('bill@ms.com');
+ $oldpw = $bill['User']['password'];
+ $data['password'] = 'my_new_password';
+ $data['confirmpassword'] = 'my_new_password';
+
+ $this->controller->data['User'] = $data;
+ $this->helper->callControllerAction($this->controller, 'pwreset', $this, array($bill['User']['id'], md5('random, wrong password reset code')));
+
+ $newdata = $this->controller->User->findByEmail('bill@ms.com');
+ $this->assertNotEqual($newdata['User']['password'], md5('my_new_password'), 'Password reset');
+
+ $this->controller->User->id = $bill['User']['id'];
+ $this->controller->User->saveField('password', $oldpw);
+ }
+
+ /**
+ * Can I log in and out with the right password
+ * (is my session generated and destroyed?)
+ */
+ function testLoginLogoutPossible() {
+ $username = 'nobody@mozilla.org';
+ $pw = 'test';
+
+ $this->controller->data = array();
+ $this->controller->data['Login']['email'] = $username;
+ $this->controller->data['Login']['password'] = $pw;
+
+ // re-mock session component to clear previous expectations
+ $this->controller->Session =& new MockSessionComponent();
+ $this->controller->Session->expectOnce('write', false, 'Login attempt');
+ $this->helper->callControllerAction($this->controller, 'login', $this);
+ $this->controller->Session->tally();
+
+ // re-mock session component to clear previous expectations
+ $this->controller->Session =& new MockSessionComponent();
+ $this->controller->Session->expectNever('write', 'Logout');
+ $this->helper->callControllerAction($this->controller, 'logout', $this);
+ $this->controller->Session->tally();
+ }
+
+ /**
+ * Is the login rejected with the wrong password?
+ */
+ function testLoginRejectWrongPassword() {
+ $this->controller->data = array();
+ $this->controller->data['User']['email'] = 'bill@ms.com';
+ $this->controller->data['User']['password'] = 'notmypassword';
+
+ $this->helper->callControllerAction($this->controller, 'login', $this);
+ $this->assertFalse($this->controller->Session->check('User'), 'Login with wrong pw');
+ }
+
+ /**
+ * Is the login rejected for a wrong user?
+ */
+ function testLoginRejectWrongUser() {
+ $this->controller->data = array();
+ $this->controller->data['User']['email'] = 'idonotexist@example.com';
+ $this->controller->data['User']['password'] = 'mypassword';
+
+ $this->helper->callControllerAction($this->controller, 'login', $this);
+ $this->assertFalse($this->controller->Session->check('User'), 'Login with wrong user');
+ }
+
+ // @todo user editing tests
+
+ /**
+ * Test that a corresponding ARO was created with a new user account.
+ */
+ function testUserAroCreated() {
+ return false;
+ }
+
+ /**
+ * Test to see if a user actually has access to an Add-on ACO.
+ */
+ function testAddonAccess() {
+ return false;
+ }
+
+ /**
+ * Test to see if a user had edit access on the Tags ACO.
+ */
+ function testEditTagAccess() {
+ return false;
+ }
+
+ /**
+ * Test admin membership.
+ */
+ function testIsAdmin() {
+ // Grant admin rights to a test user.
+
+ // Test to see if that user is now an admin.
+ return false;
+ }
+
+ /**
+ * Test that access is denied when a user doens't have an aro->aco entry.
+ */
+ function testAccessDenied() {
+ return false;
+ }
+}
+?>
diff --git a/site/app/tests/data/base-icon.png b/site/app/tests/data/base-icon.png
new file mode 100644
index 0000000..18bd9a1
--- /dev/null
+++ b/site/app/tests/data/base-icon.png
Binary files differ
diff --git a/site/app/tests/data/extension-noinstall.xpi b/site/app/tests/data/extension-noinstall.xpi
new file mode 100755
index 0000000..24ce012
--- /dev/null
+++ b/site/app/tests/data/extension-noinstall.xpi
Binary files differ
diff --git a/site/app/tests/data/extension-works.xpi b/site/app/tests/data/extension-works.xpi
new file mode 100755
index 0000000..8abcc13
--- /dev/null
+++ b/site/app/tests/data/extension-works.xpi
Binary files differ
diff --git a/site/app/tests/data/remora-test-data.sql b/site/app/tests/data/remora-test-data.sql
new file mode 100644
index 0000000..03c2710
--- /dev/null
+++ b/site/app/tests/data/remora-test-data.sql
@@ -0,0 +1,1077 @@
+-- phpMyAdmin SQL Dump
+-- version 2.9.2
+-- http://www.phpmyadmin.net
+--
+-- Host: localhost
+-- Generation Time: Feb 12, 2007 at 10:24 PM
+-- Server version: 4.1.20
+-- PHP Version: 4.3.9
+
+SET FOREIGN_KEY_CHECKS=0;
+
+--
+-- Dumping data for table `addonevents`
+--
+
+
+--
+-- Dumping data for table `addons`
+--
+
+INSERT INTO `addons` (`id`, `guid`, `name`, `defaultlocale`, `addontype_id`, `status`, `higheststatus`, `icondata`, `icontype`, `homepage`, `description`, `summary`, `averagerating`, `weeklydownloads`, `totaldownloads`, `developercomments`, `inactive`, `trusted`, `viewsource`, `prerelease`, `adminreview`, `sitespecific`, `externalsoftware`, `eula`, `privacypolicy`, `created`, `modified`) VALUES
+(1, 'en-AU@dictionaries.addons.mozilla.org', 33, 'en-US', 3, 4, 4, NULL, '', 60, 34, 35, '5', 123, 1234, 80, 0, 0, 0, 0, 0, 0, 0, 69, 95, '2006-08-22 13:18:44', '2006-09-05 18:43:39'),
+(2, 'winfox@ms.com', 36, 'en-US', 1, 4, 4, NULL, '', 61, 37, 38, '0', 3, 3, 81, 0, 0, 0, 0, 1, 0, 0, 70, 72, '2006-08-22 13:24:42', '2006-08-22 13:24:42'),
+(3, 'winfox@ms.com', 39, 'en-US', 1, 4, 4, NULL, '', 62, 40, 41, '0', 3, 3, 82, 0, 0, 0, 0, 0, 0, 0, 71, 73, '2006-08-22 13:25:53', '2006-08-22 13:25:53'),
+(4, 'testheme@amo.org', 42, 'en-US', 2, 4, 4, NULL, '', 63, 43, 44, '3', 561370, 5712902, 83, 0, 0, 0, 0, 0, 0, 0, 89, 90, '2006-08-22 22:21:56', '2006-08-22 22:22:30'),
+(5, 'testgooglesearchplugin@amo.org', 45, 'en-US', 4, 4, 4, 0x47494638396110001000f7ca000013562930740f129f151f800b16a40022961a258f1c388c173b930025bd0436b1132ca0152aaa1333ba163fbf1c38b528268b2335992533b6243ab13137b10e2acb1331c51a32c6202ec51d42b41c49b01c5ab1226eb93160b81b5ed1195fdb155cf61f56f71563cf156bd20763e81461e11d68e7205cca265bcb2753d62f5bd8375bd62158e82260d95a68af5773bc426edb4674ca2db7403cb54448b6394cb43b55b33950b83d4fad5547b94a4db1414db34543b8504db55256b64a6284a96585d87c8fc76f9ae97e9ee97aa4d66facefcb140ece1419d11007d61f0ddc1a00d11f1ddd1812c72300ce2600cd2a00d2280fd22419db251acc2e22d6202f868fd0898fd98199dfa3a9cdaab6c2afd2fabcd7ffbfdef0cad2d4c2cefec4dbe3cad3f2c9d7ffcddcf3d3d9f9caeaf9c1f5ffd0e5ffd2e7ffddebffd7f2ffe1dfecfff8d9e0e6fceeeeffe4f6f6e5f6fde4f6ffe7f8ffe7f9ffe8fff6effff3edfff6eefff6eaf9ffe8ffffe9ffffebfffeedffffeefffdeeffffeffffff6faebf4ffeaf5ffebf7ffedfff4edf8ffe1fbffe0f8ffe6fff8e6feffe3fafeeffdffe9f0f0f8f7f1fff0fff7f5fff1f4fff3f7fff1f7fff3f0fffff1fffff2fcfdf2fffff3fffff5fbfff6fafdf7fffbf4fffff6fdfff7fffffbf5f7fff0f6fff4f4fff6f6fff1f9fff2fffff3fffff5fafff5fffff6fffff7fff8fbf4fff9f3fcfff3fcfdf7fcfff6fefff4fefff6f9fbfffbfafff8fdfff9fdfff8fffff9fffffbfffefbfffffff8fafff9fbfffaf8fff8fffffafcfffafefffafffffbfffffdf8fffcfafffdfafefff8fcfffffffcfdfffdfdfefdfffffcfffffdfffeffffffffff00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000021f904000000cb002c00000000100010000008fe0049f8a08163070f1b3a7accb891a3868c193354fc51d609519e5970d4585a34ab54ae505340cc9ad527cd1017132e28e85084cba3434e4408ab53264603347994e5097320409b51484e209a0524c21d448994cd5226a6cba354504c5cba82600c27438d083d2a054bd923454f587012f2a094b056ba2c59fa34ab95205d4652f4e1b04191305da594e922a5ac15a05c4c4af441a12197a756964a0913364b99a235543c58825100953246ca2ccdf942c60c18454d5a00229220489d59ba5a79a1c040429556514228938341c0964cca0629836566001644473eb422c40602012b7254d1e9a3054016444946f4e1c409ce0b030b2c38a890e1871b654b56268c42a44c993265ca942953764999ae4f5266cc983163c68c193366cc983163c60c8033940404003b, 'image/gif', 64, 46, 47, '5', 4294967295, 4294967295, 84, 0, 0, 0, 1, 0, 1, 0, 91, 92, '2006-08-22 22:35:59', '2006-08-22 22:35:59'),
+(6, 'iapple@apple.com', 48, 'en-US', 5, 4, 4, NULL, '', 65, 49, 50, NULL, 0, 0, 85, 0, 0, 0, 1, 0, 0, 0, 93, 94, '2006-08-23 01:24:30', '2006-08-23 01:24:30'),
+(7, 'farming@microfarmer.org', 51, 'en-US', 1, 4, 4, 0x4749463839611f003200f700008d8c8c71a9427a415ee9abaafefefe395b844c4748a6cc31c5ddabbbc7ceb5d4326c54783a6489ed312cf4b3b29048666fa542e4eebf72ae3abf2c3b81b15ab9d87f6c88a582b94169a13c86b361b8364de0edd4ecf3e6887b8cd52f35fcfdfae84646f7faf49dca3aa9bcb356767cf032266d543594c53394a4b8454931647d9ddfedce85bc408598b3a5cc38adcf3696c36fa1cb39a4a5a579b438e9b1b0aace37d2364396b877697e888f31490b0c0cb7b4b89ec932e6f2d2b1d387e8f2d47eae59546c8afdf5f4fbd8d75a7a3778b43546648afef9f8cee2bc88b95bf5908dbfda7b6ea93b4f3c2b88bf3e74b03b91bf68ddebd2fce3e3aa3a537aaa5286be3a7ab242f3f7ec6ca63d69a23a8ac13e8ebb688db968dddddd86bd4075b035e2a69b48668b6ba53a4868856cab32bad256eaeaeaaacd319ac7337fb641669f3a6da342fcecec1d16157db5417950735f7893656e8e84bb40cce3ad45648fb1d02f73ac40f5f7f98ec53d5e799ae7efe1628839f5f9f1648b6b6ca73a405f8a89bd436ba5386fa74145638dbfd8563a6c90bbd6585b84308fbc67ef312342608f44698e3e5f872c19216ba43c76b1434164898cc33ef57b77f25d59a4cb397cb7367cb44274ac42f8b9b8a8cd38e2edda78a744c8d0d97eb44db5bfd0f04d48fbfcf882bd38fbcecd567a9a8ca95080b841a0b7a4d1e49b80b7424a698f7fb9388ac4416fa33fa9415b4558785a8077ef3d39b0d035b89ba69fc182aece30536e93dee3ea77ac4a81b1588da0b850718087ba55dda5a7cacaca3e4621cdccd4618f553b2e15383128fef0effbdee0c3db5378b24479b4437bb3427cb44787b5628ac02ee9575fa1c782acc9967e6362416092a9d085e0e0e0bb707681bb37c1485af7e4e4de6e6e78a5569fc92ea9cf7ee7f0be749e35e9f2de75779266a2324363888fc331d6e5cab02e3e6ba1408cbc5f80b93af2a9aa5d6d40f0c2c0fac6c499b39efbcdc4f3f3f3b4d350fbfbfceaedf18ea2ada88293a8b3c0b3bfcff46a6291c9397db5417fb74257729699c83b5c7595b0835f8bb966e87f84ffffff21f90400000000002c000000001f0032000008ff00ff091c48b0a0c183081102306026a1c3814208083403a08d45190f131ea1c1e65f3b1d6d4c04d3a10340c683d606d09072c7401330604c909476b22081741cff757986c901bf91186b1294c28c98c05e0e1c0c90d94528412189940c1c42c3c1b40e4e0b4efa74e41f8173f2fc3db021a96bd67f981a881a526f4ab5071a4a349074f6dfb0069f609578b3c0c8830680859c25300970a2378516159820574addb420aec5591486c1b8c6750908fe67c148e51c7287d41d48204f98308504c855377a609e457e3d3428c1aef5bf77a316d828c1dbc666a1776c254061014eab44c83de4809395de693a743ad05002628200570ce044d8c63d8277efa00c96ff3ecd2808af01b2bc414a0c8d449d3ab4689d3973e040b61f06ef9c36d2c2429c3895d1514079a428104b2c2fbc50432699f0805f41f030e25902703002c92046e8120f2765286060820bbae082830679528011b5ac33461883e84245153dfc534c1d072a988988319038101f1ca0500038f998b2a222d8d8a3c50aff10420b820c6642490c31a0f1e03f487492cc2b838093c708e0b4084824552049c81936e2188308520a44001464d841822205a8300f238af481871661fe63c81921ba00a508229cf0e0078848700c3038b4904b0b8c0c42051e4ee469c80137baf024a0fa082ad0075048b0872f0600b0431e7fe8028816912239a9a57f8aa04fa60f82ff02c3218dd4da8601a9d409a91779ba930d0fd9a081c609c486b34c8cff709ac51e441c72030a8d3eea8413d42079ca12d8625bc1b6db5eb129144c3c628c04d1b450c02b914ceb852a3e08452813975c62073abfccb349245ee4cb8239da20e0efbffe2221d140ef5ef208118d18600037ab78c1020b725c5049111417f1c5c564ec32f0a688c0cb8a308db4810e0b4e3c1cf105a59492461af7dc6389254f94b371b25b306147002934b1c31ca17821c7c929a7814fcb9620834ccc337fb0851f765c12c82cffcca10ac440a7810acb45236305d20429cd440001f8d1cc3f085402b4ca2cbbacb5155b279174cd370772c33f2ba852492533e49df7174ff0a82dc1df64c05090d27e80cdc42d1cfcd3cd068c37ee78e35144e16dd75c140eb6185c68621be1605f1e8032a02b93c1e8a4934e41e2067d5079e7600be288188e6491852318c88ec1ed6aa8a1c741aa5bdeb9201008023c04c413bfc6f16b60b07beafd88f1bbf0c31b6f3cf2e4287f10015b7c83c5f65838e248f7b4df2ebef8b92f6f903814e0820b05ecb70fc4fbf0c74f85331f24044a08f8e7affffefadbe6ffff003c484000003b, 'image/gif', 66, 52, 53, '5', 44000, 1236345, 86, 0, 0, 0, 0, 0, 0, 0, 74, 75, '2006-09-28 08:56:46', '2006-10-12 12:47:00'),
+(8, 'fisher@farmerland.org', 54, 'en-US', 1, 4, 4, 0x89504e470d0a1a0a0000000d494844520000001f000000320806000000a49c00d1000000017352474200aece1ce90000000467414d410000b18f0bfc6105000000206348524d00007a26000080840000fa00000080e8000075300000ea6000003a98000017709cba513c00000643494441545847b5986d4c53671886e7eff9d725fbb11f66c9b264062d0b08455d298ab8ccccccaf0951263227b3c2fce4534007c298889b864c8d5f93a2a03360cb68075bdd8c713241a66c334b604c890a93817c0415e459efa7bef5d09eb7e7d46d27b9734edbd373bdf7fd3eef734e3b89dcdb73fff33669923f80a98007bb95eede4d6fcd8fa39e9e1e5d5f05c5576c3ad0b71f0f0fd1f8f8b8f714c0007ee985295e5558ad9a03081a3efef00175d7d6d0d8bd7b7cf1c1c1417a7ef264866e581246512153f8358401c93635b0c85bea7ca4ab8bba4f577b0670eb160d8f3ce4a8df9ef51addac3cc4c220c4003a3b3b55f932d7016347dcfd3f9c9fe0bebdbd9d72d724d103a783866ce7a8e6e3446f026af10772ad39e770dcbd3c91463b9eba6a6a6a62308464847b0ccc770be45a138e82eb33bc4cc37b4b275c77f4c66f9c0806d0f0d1362acef69f732dd79a709c30b07205f52f8c231420364cc74055359ddab98feee615d0deb8b5742d3c8686b3d3bde7787a87faf252bad05ce798df5ec3341a6d6926381efa3089aa8d8be9fbb878063bc217527fe82b7c0e062003ab75144df8787f1f5f18eefb6647322873d166b22cc9a0d8e4121e003e17d213b770af0d47cceee8c5c55103801b2d7b696eca1e8a4c2820d7b428af7b3d71eb86e34411fdddd858ea484da5f753f730386eeda7644cfe846a42e6303c18d7ba0a4e14192a5f6c96622b472ee06586055278a0deab19bbef9751edab320f3298e1eef8b3a25705ed5ab773df01008ed845c1fd323d4cd7d2f26b42816251fb6c74748c96651de46ac7fa7e96b9d65570b89974dceaa1864b2db4bfc24198ebc48c7d54159dc09d4f28980ad7d5646caeabde799d975c4610da28da2ada2d2a1f4b4c56e177fabf23a8eb6f979f46c73cdd52b5e07c8b6a4e62112db19450bbf524df4c1c872a696bfae752706deb743adb328355dd6c60555ef1e8e8e510ba3bd02687236e51cd28aac22f6c1c39d6372496989aebbab650aa690d637d75359c55dd32934e3547b08e5c0e0d0cefe9bd4f702bd632e61c738df7a2dd4d65de9a52a96b01f7055baf4410a409af73b572db047c71ea3e3a603b4271eb0ad931c08b36e6abc211b7d2b5702cc0c77f8a94c3871fdea77b83b7b9b2018f59534ccb3795d3b1fa0a2fdcfc5e99d435e658c42d62c6bec20d05183a78e975ffd85b6e3652ae7d21e5d8e7537c7e3a3b041c0da5aad1c6c7815cbb6e2ce3c252ceb1d231c0879b8cfe7054f767ae7564391d4a9bcf9868d9b61c8243b84fde7e984ed9cef37c0772ddf0ebbb9eca7e525c6a60c0f75ff4713ef6f81195357e409bce1a29d31e43abcb96524a6e315779e93107ef0197151ad60de0584a88598045dc8042077e8c5287c339e049c5913427762a3f26e379bcdeeee0e84d8925016f1e020eb0728e956055383a4ef985344a289841d35e9cea157e2060106fa6c88bec8fde166e18f6eb8bb8816029618fc28210b350d90503959c0fa1db03d79e3619c40ee7295f7a9cc767cde481943bd2b9f211b95a43d9d1309304fce7ae43e4fa3ddb4fce1b79e4abc111cfaf206eaf029e5a1545db6a6328e3dc5c9e82aad6429e6f59ffce734650edf5a2606f8cdef3bd70141ce05bce9859a8fa951b4cd47ca54d15beeb5b1315369a28dfe91ee4d55cbad87e3aa0b094953f3a273857c2e11ed163fe65ae012e6830d14e6734e5d48753863d6c82b6d68491109670d1374bf5c1d34ebc41118657a5702518f07c8747795f7bb4bdcea31cbb99b5a5268a763726cae17b1ad671ec887b639599e62d30485d0bc77ee07af30470b6cd4c902eb8e5a491e198f3f5d6085538c0be70b8cd7783856bb815e0ac733ae1700ed7906caee1562b6a80011582f3626782bed86560141694698ff0138a0b10b1c7521542c1a189a93ebd629d63ce11bbcc75f7400775f6b605adf6bfae11241a8bdf0324e0a54e0f3cd89f3ccfdc61941d4e385783238da2baa409da655b4d5ada511bcf0f27b2cddbe1e05ce63aed6434adaf98e55e0146dee31e00f1f1f1a7aff9f889d61e351274a7efcf6787c335e069d6277b718cd73eda70c24c4a6120bae0815c335c050a9018802f78fd7113a7a00997812d95b33d71bba53c56c62b3bd615bb0c8cf75130beca3dbb82f428abfa1d3a73b99c6fd7d28293c1471e0dd1bf95d632e4ff9dd5fe11d6fae27ff1392f3525fcbfb8a8de6b04fdb788de0beb39ef1ff0abfd8342070cce0000000049454e44ae426082, 'image/png', 67, 55, 56, '', 123, 41415, 87, 0, 0, 0, 0, 0, 0, 0, 76, 77, '2006-10-16 12:34:12', '2006-10-16 12:36:56'),
+(9, 'hunter@farmerland.org', 57, 'en-US', 1, 4, 4, 0x89504e470d0a1a0a0000000d494844520000001f000000320806000000a49c00d10000000467414d410000b18f0bfc610500000635494441545847cd986b4c14571886f577fd6b93fee80fd3a46952435d1b1016b5b028625353536f15a254442b65857ae52a520b05515c5b0da91a6f9545416bc05dcb5268b135c64a05addad634c152255ea814e4125490aff37ecb1977973933b336313dc99b99dd1df639ef7bbef3cd2c634919639ed7183bd69f0478b0a374fb767a67561c75747404f7a763c6c0a92ae54c3e9ef4f7d1f0f0b07a016000bffce27855e54ea7f90998850f3f7a48f76aaa69e8fe7dfef2dede5e7a61dc3886ae9e1f4a9121e3f9358409198e003012903a1f686fa77bc7abbc13b8758bfa071e71d4ef4e7d9d6e56ec63611262026d6d6dfafc60e088bbfbc7337eee5b5b5b296f79123dacf3509feb14557f9aa826a01bbf0658d7396cc0f1bd45893478e3a9aba6a62606434846b8c7c4348704ccbbcca8e0ba2caf50ffce52bfcb06afffce896002f51f6fa4e21c9d35d7828f7c9b2e1cd7f42c594cdd73e208058881e5e8a9aca2635b76d1ddcd05b4336e255d098ba1fe9c0cf51a75a63aae0d9de302ac6fa765220db634131cf77d944455d679f4435c3c833d6173a87bf2ab7c0d26e037745c9b820f7777f117c37dd7b4080665cd5d47f6f999149b5cc213c0e742e80d3c0c5c9b832366257af1e5a801c0adf69d3423650745241450e3c448d53d8ad40cd814dc37fabbb1b174232d8d56a4ed6070dcca6d644dde4ad521d38de11a956d5870a2c8d4389537ecc54e8e5cc01d96d92adcac6bd3ce7d278d6a5f9ab597c10c57e2cf8e5eaa0f97ec6753ce03ff1670c42e0aeed73742b9268271fd4cce0707876861f65eae76ec6f543f142cd8108e9bc98d5b1d547fbe8576977b78ad13337751657402a1ea85e05c13aed73eb11b659fbb1a2fa9eb3a33d94110da28da2ada2d2a1f5b0ceb2d737da7fb7b6affa771940687bcdd52131e5854d3138b68bebd845a9d47f966e2d957411b32bea068659ba1e0b4e0275b261154d56c61555cf4eae08510badb734d0e47dca29a5154855fba3872ec6f486c31a421735d7d3994bebe14c6aa6a9942c79ac359072e4cd68777743e20b8157b196b8eb5c67b703b7379297f160cd879319c2043f8e9c6cbdc36019897b68bf6b80e50dcaa42760cf0dc35f9945df59e261c8e856be158800fff1c2187f73f7a40f77b6f7365031eb3bc9816ad2da343b5e52adcf68183329d0b0d5d8b98712c57a000437bcfbf393af6969b0d94e79e43b9ee59149f9fc10e014743a96c70f1b970bdf5bb184d380acb778d7d1d03bcbfc93a1a8eeafebc7115d98f4fa67527a268e1c65c8243b84fdeb49f8eb9cef07ae3bde46da952d75cd923c5a505067cf7b900e7434f1e93a3e1435a7bd24a59ee185ae658402979c55ce5a5873c7c041cce654556ffdbfbbc9510b3008bb80185f6fc14a90d8773c0938a23687aec047e4cc6f378addbc3d147259670a1c93a998003ecbbc6be604d383a4ed9d9744a289844135f9aa00a3f103089b7531c1cb95eff765f9dcb0d045b094714168498851c672d547226846ef75c79da64103b9ca77ce5751e9f3d852752e6c9e0cad78bfccfce16fea25fdaf751e31f39a354777d3305aa77c0fb2b88dbab80a75546d2c69a18ca3c358397a0f27221af370a4fe6bae66a91c1ed43feb10a47c101befe848d85aa5fb23a8a9a2f2a7d58f23058d81045f975ca242fe5d1b9d6e3bac256f6fdd1e9e7dc170ef7881eeb8f35d782035c501f455beaa229b7368c32dda17eda501d4a42d8c245df2e30074f3ff216855b5e63b8ccb500039eeff16af3375e6d3aed55aedbc65a5f1d49db1b12e5f01df5ab3876c4bda6d24633675bf817a9165c0aaeb5f981735c36824cc1ed47ad0cc79aa73ac34dbb86db7c052c5cc3ad00679f32098773b88664712366a3a801065408ce8beb12ccc7ae0547614159eef051427101228ed8aa42283834b1c0a16e35ac3962d773ddd6798d8255ebdf5708128dc577022abcb4ce00feccadc4449311ce656b5d743a897cf5996b1919e9939a787e38910d3fe73270fad1684a2d9faaec002b1f710f80f8fcf0d3d77c3ea29507ad04dde9faebd9e1a801c0d39d2347718ed7015a7dc446bec2444cc1f55c335c030a9098402038f57014a76008e786af71f3b0574cf3c6adc8f7dc375ed9b9e9d865ae513081ca3bb998cc088fd6272e94f1ed5a5e7092dbe5c0e33efaaf32da9dca3f40fdff13ccaf9fd3f89fc19f936b60fe05f236df07683c4a5f0000000049454e44ae426082, 'image/png', 68, 58, 59, '', 4552, 522355, 88, 0, 0, 0, 0, 0, 0, 0, 78, 79, '2006-10-16 12:36:04', '2006-10-16 12:36:35'),
+(10, 'testdelicioussearchplugin@amo.org', 154, 'en-US', 4, 4, 4, 0x89504e470d0a1a0a0000000d4948445200000010000000100802000000909168360000002b49444154789c63fcffff3f0336c0c88855988109bb306e30aa81188023b41918eedebd4b1d1b46351003000df005b5235869780000000049454e44ae426082, 'image/png', NULL, NULL, 155, '5', 123, 456, NULL, 0, 0, 0, 1, 0, 1, 0, NULL, NULL, '2007-01-03 16:30:00', '2007-01-03 16:30:00'),
+(11, 'testimdbsearchplugin@amo.org', 156, 'en-US', 4, 4, 4, 0x89504e470d0a1a0a0000000d4948445200000010000000100803000000282d0f530000000467414d410000afc837058ae90000001974455874536f6674776172650041646f626520496d616765526561647971c9653c00000198504c5445ffffe4f1ebd2ffff77eed35d51504e363737ffff79f5d85ef2df5efff873f2d662fbfaf4faf4d1d2b641f3e7b6f9eebfece7d1bcb167faf6e4aba25d54544e55544e4b4b473c3c3eb5a75bf0d35afffc72e6c74d8b814b232323b8ac6865604458554de2c54f525149c0a638fbf9f2efe9d3f4d65b9e92525d5a56474541e5d389c7af49e0d5a7f4d75dfffee3efe9d2fee05ffff974e0d5a6282829e4d8abf2d55b5b594e37373b14141bfffce1f2ebd2efe9d0fae35befd35b988d524c4a46ebe5cb605b44e7ce60f7ecbefdf7de48484a625f54fffbe1c2b269fbf9e0f1ebd1f3edd2c3b86bd6c269565550cfba58f5d94df5e9b3c1b56cf2d64db2a463f2ebd3f3d65b393b3f3b3b3cd1b64af1d35ad0b549ddc356595442ffff76e5c952e7ca52eee9d2f3e8b0baac6bb3a560ecd15bffe76aa89a5bfff9dfffe762d9ce9eeee3b1fde863ffeb6acdb3483e3f42f1d55dceba60e2c753fdfdf7b8a95d302f2d47453bb2a4652c2e31fefdfab4a55fb0a45d5a5645e6e1cc938850dfd4a72f3034f9f3dae3c857f1edddb0a363f7f2dacab450fffffff97ec5af000000d84944415478da626847030001c4802e00104018020001c4d05ecce3c900047a96ee192e8ddced0001c45099c461c8c416c724c5999bc615afa50210400c7cc1368241c23ed572ea8529a909bc260001c410189053a361615ecad2a0c02aef1f690410400cfcec998e6eb2c66566224a9af912d13a0001c4e05c6010eb27ee6a2f56211a115e92570f10400cd9d26a55e52dc921e9321e7675beca590001c4d0eaa42819a66b1a65cb5cd414a3dde60d10400ced420ed65e8ca1568cfaaa8902b5cded000184e1528000c2100008200c018000c2100008300056b7608506805b900000000049454e44ae426082, 'image/png', NULL, NULL, 157, '5', 123, 456, NULL, 0, 0, 0, 1, 0, 1, 0, NULL, NULL, '2007-01-03 16:30:00', '2007-01-03 16:30:00'),
+(12, 'testwpsearchplugin@amo.org', 158, 'en-US', 4, 4, 4, 0x89504e470d0a1a0a0000000d4948445200000010000000100403000000eddde25200000030504c54450303031818182828283b3b3b4747475858586a6a6a7b7b7b838383989898a8a8a8bababac7c7c7d9d9d9e8e8e8fdfdfdf8a5180f000000734944415408d763f80f050c988caddebfdcef97de4d65f8a1fddfe95ee7bf4c86bf62ef27aec9ff97cff03ff0fc158df5bfd733fcdfd8ff93f5ff8bfd0cffbff8fe35f97f1da8fd07d75fa3fd3341e6a8be4aceef03319aabae6bf683188bb47e2b9d0731bef8fe4f02dbf5fbfcffdb4896020092a165118df9ef690000000049454e44ae426082, 'image/png', NULL, NULL, 159, '5', 123, 456, NULL, 0, 0, 0, 1, 0, 1, 0, NULL, NULL, '2007-01-03 16:30:00', '2007-01-03 16:30:00'),
+(13, 'testa9searchplugin@amo.org', 160, 'en-US', 4, 4, 4, 0x89504e470d0a1a0a0000000d494844520000001000000010080200000090916836000000097048597300000ec400000ec401952b0e1b0000014449444154789c8d52216ec340101c4bc5219122b5a03a4b0185e125e125db17c4a0ba3f84dd172a055905478b42529092cb030e24524181a573484b6ae20f5cc1a467270dc8b0f5ceecec8e0fb107efbdf73e95d65aa514000022c28fe80b442435c80e21b034c628a58e0421040e23a9cf269452d6da4ea0b5a6406b1d63048ecc6922225724d5755d9625356559cee7739cc3683442527319ef3d006bad8818634e5672ce2115dc84a7f30000d484109452cc030ce4bfbb732e84202200182ec76531c63ccf01144591d8bc6fb95cb2ccf3dc18339bcd0e93b8f44920295f8a530b343d49900768adb97dbf85b7d745ff3924a467e29c8b3fdbb896b896b85f6571bfc2e70bee9e70fb7036fb033e9e3118a3ad32fe54bc3fa2d96238c1cd148371c76b2b7c6dd06c71bf405be17afa2700d0ecf0bd39b4138693cebcd901e8092ec32faf33808c34f4eddb0000000049454e44ae426082, 'image/png', NULL, NULL, 161, '5', 123, 456, NULL, 0, 0, 0, 1, 0, 1, 0, NULL, NULL, '2007-01-03 16:30:00', '2007-01-03 16:30:00'),
+(3046, 'sl@dictionaries.addons.mozilla.org', 42824, 'en-US', 3, 4, 4, NULL, '', 42825, 42826, 42828, '3.67', 1136, 16916, 42827, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, '2007-01-28 12:09:53', '0000-00-00 00:00:00'),
+(3049, 'de-CH@dictionaries.addons.mozilla.org', 42839, 'en-US', 3, 4, 4, NULL, '', 42840, 42841, 42843, '5.00', 6346, 145972, 42842, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, '2007-01-28 12:09:53', '0000-00-00 00:00:00'),
+(3052, 'pl@dictionaries.addons.mozilla.org', 42854, 'en-US', 3, 4, 4, NULL, '', 42855, 42856, 42858, '4.17', 2544, 39899, 42857, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, '2007-01-28 12:09:53', '0000-00-00 00:00:00'),
+(3053, 'it-IT@dictionaries.addons.mozilla.org', 42859, 'en-US', 3, 4, 4, NULL, '', 42860, 42861, 42863, '4.50', 15366, 246549, 42862, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, '2007-01-28 12:09:53', '0000-00-00 00:00:00'),
+(3059, 'es-AR@dictionaries.addons.mozilla.org', 42874, 'en-US', 3, 4, 4, NULL, '', 42875, 42876, 42878, '4.00', 9750, 162708, 42877, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, '2007-01-28 12:09:53', '0000-00-00 00:00:00'),
+(3064, 'sv@dictionaries.addons.mozilla.org', 42899, 'en-US', 3, 4, 4, NULL, '', 42900, 42901, 42903, '3.40', 4014, 72544, 42902, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, '2007-01-28 12:09:53', '0000-00-00 00:00:00'),
+(3066, 'fr-FR@dictionaries.addons.mozilla.org', 42909, 'en-US', 3, 4, 4, NULL, '', 42910, 42911, 42913, '3.00', 7697, 141754, 42912, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, '2007-01-28 12:09:53', '0000-00-00 00:00:00'),
+(3075, 'nb-NO_nn-NO@dictionaries.addons.mozilla.org', 42949, 'en-US', 3, 4, 4, NULL, '', 42950, 42951, 42953, '4.60', 2167, 42420, 42952, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, '2007-01-28 12:09:53', '0000-00-00 00:00:00'),
+(3077, 'de-DE@dictionaries.addons.mozilla.org', 42959, 'en-US', 3, 4, 4, NULL, '', 42960, 42961, 42963, '2.92', 49037, 1092670, 42962, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, '2007-01-28 12:09:53', '0000-00-00 00:00:00'),
+(3079, 'de-AT@dictionaries.addons.mozilla.org', 42969, 'en-US', 3, 4, 4, NULL, '', 42970, 42971, 42973, '5.00', 19220, 407671, 42972, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, '2007-01-28 12:09:53', '0000-00-00 00:00:00'),
+(3090, 'ga-IE@dictionaries.addons.mozilla.org', 43024, 'en-US', 3, 4, 4, NULL, '', 43025, 43026, 43028, NULL, 141, 2836, 43027, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, '2007-01-28 12:09:54', '0000-00-00 00:00:00'),
+(3099, 'en-AU@dictionaries.addons.mozilla.org', 43064, 'en-US', 3, 4, 4, NULL, '', 43065, 43066, 43068, '3.67', 2040, 61450, 43067, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, '2007-01-28 12:09:54', '0000-00-00 00:00:00'),
+(3155, 'pt-PT@dictionaries.addons.mozilla.org', 43284, 'en-US', 3, 4, 4, NULL, '', 43285, 43286, 43288, '4.09', 4091, 72738, 43287, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, '2007-01-28 12:09:54', '0000-00-00 00:00:00'),
+(3257, 'pt-BR@dictionaries.addons.mozilla.org', 43664, 'en-US', 3, 4, 4, NULL, '', 43665, 43666, 43668, '2.58', 16356, 263607, 43667, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, '2007-01-28 12:09:55', '0000-00-00 00:00:00'),
+(3291, 'nl-NL@dictionaries.addons.mozilla.org', 43789, 'en-US', 3, 4, 4, NULL, '', 43790, 43791, 43793, '3.90', 9598, 188955, 43792, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, '2007-01-28 12:09:55', '0000-00-00 00:00:00'),
+(3366, 'en-GB@dictionaries.addons.mozilla.org', 44049, 'en-US', 3, 4, 4, NULL, '', 44050, 44051, 44053, '3.54', 28321, 539465, 44052, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, '2007-01-28 12:09:56', '0000-00-00 00:00:00'),
+(3369, 'ca@dictionaries.addons.mozilla.org', 44064, 'en-US', 3, 4, 4, NULL, '', 44065, 44066, 44068, '5.00', 2116, 41862, 44067, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, '2007-01-28 12:09:56', '0000-00-00 00:00:00'),
+(3386, 'hu@dictionaries.addons.mozilla.org', 44129, 'en-US', 3, 4, 4, NULL, '', 44130, 44131, 44133, '1.00', 7255, 114795, 44132, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, '2007-01-28 12:09:56', '0000-00-00 00:00:00'),
+(3390, 'ro@dictionaries.addons.mozilla.org', 44139, 'en-US', 3, 4, 4, NULL, '', 44140, 44141, 44143, '2.90', 677, 12311, 44142, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, '2007-01-28 12:09:56', '0000-00-00 00:00:00'),
+(3394, 'cs@dictionaries.addons.mozilla.org', 44154, 'en-US', 3, 4, 4, NULL, '', 44155, 44156, 44158, NULL, 5584, 107116, 44157, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, '2007-01-28 12:09:56', '0000-00-00 00:00:00'),
+(3439, 'el-GR@dictionaries.addons.mozilla.org', 44329, 'en-US', 3, 4, 4, NULL, '', 44330, 44331, 44333, '4.60', 3001, 59433, 44332, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, '2007-01-28 12:09:56', '0000-00-00 00:00:00'),
+(3445, 'fr@dictionaries.addons.mozilla.org', 44359, 'en-US', 3, 4, 4, NULL, '', 44360, 44361, 44363, '3.25', 45857, 789974, 44362, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, '2007-01-28 12:09:56', '0000-00-00 00:00:00'),
+(3451, 'el-en@dictionaries.addons.mozilla.org', 44389, 'en-US', 3, 4, 4, NULL, '', 44390, 44391, 44393, '1.50', 808, 9784, 44392, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, '2007-01-28 12:09:56', '0000-00-00 00:00:00'),
+(3497, 'en-US@dictionaries.addons.mozilla.org', 44574, 'en-US', 3, 4, 4, NULL, '', 44575, 44576, 44578, '4.92', 22847, 377010, 44577, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, '2007-01-28 12:09:57', '0000-00-00 00:00:00'),
+(3554, 'es-es@dictionaries.addons.mozilla.org', 44784, 'en-US', 3, 4, 4, NULL, '', 44785, 44786, 44788, '4.00', 26269, 425166, 44787, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, '2007-01-28 12:09:57', '0000-00-00 00:00:00'),
+(3596, 'danish@dictionaries.addons.mozilla.org', 44924, 'en-US', 3, 4, 4, NULL, '', 44925, 44926, 44928, NULL, 2532, 46285, 44927, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, '2007-01-28 12:09:57', '0000-00-00 00:00:00'),
+(3623, 'bg-BG@dictionaries.addons.mozilla.org', 45024, 'en-US', 3, 4, 4, NULL, '', 45025, 45026, 45028, '4.82', 1610, 25236, 45027, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, '2007-01-28 12:09:57', '0000-00-00 00:00:00'),
+(3627, 'hr@dictionaries.addons.mozilla.org', 45044, 'en-US', 3, 4, 4, NULL, '', 45045, 45046, 45048, '4.00', 534, 6857, 45047, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, '2007-01-28 12:09:57', '0000-00-00 00:00:00'),
+(3643, 'is@dictionaries.addons.mozilla.org', 45104, 'en-US', 3, 4, 4, NULL, '', 45105, 45106, 45108, '5.00', 152, 3311, 45107, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, '2007-01-28 12:09:58', '0000-00-00 00:00:00'),
+(3646, 'he@dictionaries.addons.mozilla.org', 45119, 'en-US', 3, 4, 4, NULL, '', 45120, 45121, 45123, '3.25', 847, 11197, 45122, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, '2007-01-28 12:09:58', '0000-00-00 00:00:00'),
+(3653, 'en-CA@dictionaries.addons.mozilla.org', 45149, 'en-US', 3, 4, 4, NULL, '', 45150, 45151, 45153, '4.71', 2349, 47363, 45152, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, '2007-01-28 12:09:58', '0000-00-00 00:00:00'),
+(3677, 'ar@dictionaries.addons.mozilla.org', 45239, 'en-US', 3, 4, 4, NULL, '', 45240, 45241, 45243, '5.00', 70, 1399, 45242, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, '2007-01-28 12:09:58', '0000-00-00 00:00:00'),
+(3684, 'eo-EO@dictionaries.addons.mozilla.org', 45274, 'en-US', 3, 4, 4, NULL, '', 45275, 45276, 45278, '2.50', 227, 3438, 45277, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, '2007-01-28 12:09:58', '0000-00-00 00:00:00'),
+(3703, 'ru@dictionaries.addons.mozilla.org', 45349, 'en-US', 3, 4, 4, NULL, '', 45350, 45351, 45353, '4.00', 1926, 26742, 45352, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, '2007-01-28 12:09:58', '0000-00-00 00:00:00'),
+(3716, 'lt@dictionaries.addons.mozilla.org', 45399, 'en-US', 3, 4, 4, NULL, '', 45400, 45401, 45403, '5.00', 267, 4075, 45402, 1, 0, 0, 0, 0, 0, 0, NULL, NULL, '2007-01-28 12:09:58', '0000-00-00 00:00:00'),
+(3737, 'cy-GB@dictionaries.addons.mozilla.org', 45504, 'en-US', 3, 4, 4, NULL, '', 45505, 45506, 45508, '2.50', 107, 1865, 45507, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, '2007-01-28 12:09:58', '0000-00-00 00:00:00'),
+(3786, 'lv-LV@dictionaries.addons.mozilla.org', 45704, 'en-US', 3, 4, 4, NULL, '', 45705, 45706, 45708, NULL, 236, 3839, 45707, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, '2007-01-28 12:09:59', '0000-00-00 00:00:00'),
+(3819, 'ro-ro@dictionaries.addons.mozilla.org', 45844, 'en-US', 3, 4, 4, NULL, '', 45845, 45846, 45848, '1.50', 0, 0, 45847, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, '2007-01-28 12:09:59', '0000-00-00 00:00:00'),
+(3826, 'fi@dictionaries.addons.mozilla.org', 45879, 'en-US', 3, 4, 4, NULL, '', 45880, 45881, 45883, '4.00', 3652, 75344, 45882, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, '2007-01-28 12:09:59', '0000-00-00 00:00:00'),
+(3956, 'hsb@dictionaries.addons.mozilla.org', 46419, 'en-US', 3, 4, 4, NULL, '', 46420, 46421, 46423, NULL, 86, 1828, 46422, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, '2007-01-28 12:10:00', '0000-00-00 00:00:00'),
+(4020, 'eu@dictionaries.addons.mozilla.org', 46684, 'en-US', 3, 4, 4, NULL, '', 46685, 46686, 46688, NULL, 275, 3126, 46687, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, '2007-01-28 12:10:01', '0000-00-00 00:00:00'),
+(4021, 'showmenubar@extensions.gijsk.com', 46692, 'en-US', 1, 4, 4, NULL, '', 46691, 46689, 46694, NULL, 0, 0, NULL, 0, 0, 1, 0, 0, 0, 0, 46690, 46693, '2007-02-11 18:18:03', '2007-02-11 19:06:44'),
+(4022, 'chromelist@extensions.gijsk.com', 46700, 'en-US', 1, 4, 4, NULL, '', 46699, 46697, 46702, NULL, 0, 0, NULL, 0, 0, 1, 1, 0, 0, 0, 46698, 46701, '2007-02-11 18:38:15', '2007-02-11 19:25:13'),
+(4023, '{A17C1C5A-04C1-11DB-9805-B632A1EF5496}', 46710, 'en-US', 1, 1, 1, 0x89504e470d0a1a0a0000000d494844520000001e0000001e0802000000b45239f50000000674524e5300ff00ff00ff37581b7d000000097048597300000b3a00000b3a01647f570d0000047249444154789cb596cb73545510c6bfaffb9c7b6726908424068687bc040a152c0ab0b02c2d848d7f937f856b376e5cb800ab70e3d62a56a26e54420984f008c110c200432633f79ed3ed62781488212cf856a76e75ff6e9fd37dbe3ab4da1888b72081bc0d2c0008f9564a0610d6136466172fcefc78ee5cb3d9fce2d4a9c3870fa9ea3ad0c4993367430831c69cf36aafb7babada7ddcbd7fbfd3e974161717e7e6e62ecdcc3cea3e7a96d3281b5bb76ddbda6e8f8d8f4f4d4d4d4f4f4f4e4e8e8e8e8e8e8e8e8d8db55a2d333b7efc1872caad566b3db51358ffd9fd70f6ac741e747abdde7aa2bfd7302fd2e6bafa7efbf6edb07c6f79eda0923c0202d8e9b6c5fc339159eabcdba2fb1a590b0b0b616969696df476f22727811133c0bf7510f88af2b5e735b216171743afb7b2367ad66c0200f08bc851c369f805b7352b060007425996af8902869cefc0f3c21b6ef6da048040c839bfd4793e653dff42c610bf51853bc82630a80600ecc5bf0805a45b069052e2af177ebb77b5353d3d1e8b400242b8940dadfaa9aeb22a45c5292212a2d4b5031e83b819c99c735de76c4e3777c410eb947bdd7e6f65d0e38db07fffbedf7f3edf6e9f5095b2154540a7068eb48a9cbcae4d2353f26c2e82664300c0dd291a682e65191daec27e2fd55516b2505d314eb43784d1b1d1ceca9dec689681c210284233482084a150126503bd7e0e0ac22d03a425831006d273f2a00c91e6226603cf8f7acb470fef0d00a6b7b55458942ac2505045ea418e51cc7c685e75ed45218401e2ee66e6a09be7e42148a3a196bd4ac8d9e04028e2483d393525004e9e3ef1f7ec5f31500596dddd63413317520542c448254448d21d22521412029b4d292349e6ec705715371b54f5ce03e30004c09e3d7b507607bd443267833bc09c0cc4707e45018183204411a3b87b5086202024b0ae4d8470d4098b9dd9c3470e3e4103f8fcd4d1b95b7329e510a5aa0c020aabcacd61ee29399f0eb81992991949b8bb28ebca2814428475aa771f9c1091e7e82ded2d6c7573ce6e20093014f2c4eb488d942014a842d463140d2409c2cc73f6228a28ab3adfebde38faf1a12763fe6ce04f9efee4dafc2551a66ca936370f818341a6d20cee0e12ee04dd7d784439595565d24107fc61b773e8f8f6e737e8f94ae48323bbe6efdc8c85ba39881819a3102e0202221095584a08a242121a558284402157fbb58c3cd8b96bc72bd000b6b4374fb4c3fcc25cd910cf48b507251c22284a09811aa04a514a2048075408a0dfafee3ebaf2e9c9632fdcfb976c65ef7b7ba6df1df9f3d28c8461a3861b22858da68628148a4285a224a091fd7e75f7f1dca92f4fbc84a2bfca1f979696afceccefdf7d3028a984c2926b24e096a0caba7ae2ab0b0b7751f63efc68ff7f21af4603c8295ffce3f2867272d3f8a658904a778f515272cbeee6837e75f9dae57def6f9fdefcce2b09ff8b1e6ae1f63f776e2eefd8beb7d50c10aa2227afab3c7bedcac689f2c0c17d6be4be063dd4f5ebb7ba0f563734379665e3c1c3e5a2297bf7ed7eeddb685de8a156567aa9aec7c6c7d619ff06e837d5bf9b052c7e957013250000000049454e44ae426082, 'image/png', 46709, 46707, 46712, NULL, 0, 0, NULL, 0, 0, 0, 0, 0, 0, 0, 46708, 46711, '2007-02-12 22:16:19', '2007-02-12 22:16:48');
+
+INSERT INTO `addons_collections` (`addon_id`, `collection_id`, `added`, `category`, `downloads`) VALUES
+(8,1,'2008-01-01 00:00:00', 1, 3);
+
+--
+-- Dumping data for table `addons_tags`
+--
+
+INSERT INTO `addons_tags` (`addon_id`, `tag_id`, `feature`) VALUES
+(4021, 1, 1),
+(4022, 1, 0),
+(2, 2, 0),
+(3, 2, 0),
+(4023, 2, 0),
+(5, 4, 0),
+(4, 7, 0),
+(1, 10, 0),
+(7, 12, 0),
+(8, 12, 0),
+(9, 12, 0),
+(4023, 12, 0),
+(7, 13, 0),
+(8, 13, 0),
+(9, 13, 0),
+(11, 14, 0),
+(10, 15, 0),
+(13, 15, 0),
+(12, 16, 0);
+
+--
+-- Dumping data for table `addons_users`
+--
+
+INSERT INTO `addons_users` (`addon_id`, `user_id`) VALUES
+(1, 1),
+(4, 1),
+(5, 1),
+(4021, 2),
+(2, 3),
+(3, 3),
+(6, 4),
+(7, 5),
+(8, 5),
+(9, 5),
+(4021, 5),
+(4022, 5),
+(4023, 5);
+
+--
+-- Dumping data for table `applications`
+--
+
+INSERT INTO `applications` (`id`, `guid`, `name`, `icondata`, `icontype`, `shortname`, `supported`, `created`, `modified`) VALUES
+(1, '{ec8030f7-c20a-464f-9b0e-13a3a9e97384}', 112, NULL, '', 113, 1, '2006-08-22 11:18:35', '2006-08-23 19:28:26'),
+(3, '{86c18b42-e466-45a9-ae7a-9b95ba6f5640}', 97, NULL, '', 104, 0, '2006-08-22 11:20:48', '2006-08-23 19:29:48'),
+(4, '{92650c4d-4b8e-4d2a-b7eb-24ecf4f6b63a}', 98, NULL, '', 105, 0, '2006-08-22 11:23:10', '2006-08-23 19:29:41'),
+(5, '{136c295a-4a5a-41cf-bf24-5cee526720d5}', 99, NULL, '', 106, 0, '2006-08-22 12:18:14', '2006-08-23 19:30:06'),
+(6, '{718e30fb-e89b-41dd-9da7-e25a45638b28}', 100, NULL, '', 107, 0, '2006-08-22 12:19:45', '2006-08-23 19:30:54'),
+(7, '{a463f10c-3994-11da-9945-000d60ca027b}', 101, NULL, '', 108, 0, '2006-08-22 12:29:15', '2006-08-23 19:30:46'),
+(8, '{3db10fab-e461-4c80-8b97-957ad5f8ea47}', 102, NULL, '', 109, 0, '2006-08-23 19:30:33', '2006-08-23 19:30:33'),
+(18, '{3550f703-e582-4d05-9a08-453d09bdfdc6}', 96, NULL, '', 103, 1, '0000-00-00 00:00:00', '2006-08-23 19:28:38');
+
+--
+-- Dumping data for table `applications_versions`
+--
+
+INSERT INTO `applications_versions` (`application_id`, `version_id`, `min`, `max`) VALUES
+(1, 1, 1, 2),
+(1, 9, 1, 2),
+(1, 28897, 6, 5),
+(1, 28898, 6, 5),
+(1, 28899, 6, 5),
+(1, 28900, 1, 2),
+(18, 28900, 3, 4),
+(1,3,1,1);
+
+--
+-- Dumping data for table `approvals`
+--
+
+INSERT INTO `approvals` (`id`, `user_id`, `reviewtype`, `action`, `addon_id`, `file_id`, `os`, `applications`, `comments`, `created`) VALUES
+(1, 5, 'nominated', 1, 4022, 25890, '', '', 'Test canned response', NOW()),
+(2, 5, 'nominated', 1, 4021, 25889, '', '', 'Foobar.', NOW()),
+(3, 5, 'nominated', 1, 4021, 25889, '', '', 'Wooo', NOW());
+
+--
+-- Dumping data for table `appversions`
+--
+
+INSERT INTO `appversions` (`id`, `application_id`, `version`, `created`, `modified`) VALUES
+(1, 1, '1.5', '2006-08-24 11:09:27', '2006-08-24 11:09:27'),
+(2, 1, '3.0a1', '2006-08-24 11:09:40', '2006-08-24 11:09:40'),
+(3, 18, '1.5', '2006-08-24 11:09:49', '2006-08-24 11:09:49'),
+(4, 18, '1.6a1', '2006-08-24 11:10:18', '2006-08-24 11:10:18'),
+(5, 1, '3.0a3', '0000-00-00 00:00:00', '0000-00-00 00:00:00'),
+(6, 1, '2.0', '0000-00-00 00:00:00', '0000-00-00 00:00:00'),
+(7, 1, '2.0.0.*', '0000-00-00 00:00:00', '0000-00-00 00:00:00'),
+(8, 18, '2.0', '0000-00-00 00:00:00', '0000-00-00 00:00:00'),
+(9, 18, '3.0a1', '0000-00-00 00:00:00', '0000-00-00 00:00:00'),
+(10, 18, '3.0a2', '0000-00-00 00:00:00', '0000-00-00 00:00:00'),
+(11, 18, '3.0a3', '0000-00-00 00:00:00', '0000-00-00 00:00:00');
+
+--
+-- Dumping data for table `blapps`
+--
+
+INSERT INTO `blapps` (`id`, `blitem_id`, `guid`, `min`, `max`, `created`, `modified`) VALUES
+(1, 1, '{ec8030f7-c20a-464f-9b0e-13a3a9e97384}', '1.5', '1.5.*', '0000-00-00 00:00:00', '0000-00-00 00:00:00'),
+(3, 1, 'toolkit@mozilla.org', '1.8', '1.8.*', '0000-00-00 00:00:00', '0000-00-00 00:00:00'),
+(4, 2, '{ec8030f7-c20a-464f-9b0e-13a3a9e97384}', '1.5', '1.5.*', '0000-00-00 00:00:00', '0000-00-00 00:00:00'),
+(5, 2, 'toolkit@mozilla.org', '1.8', '1.8.*', '0000-00-00 00:00:00', '0000-00-00 00:00:00'),
+(6, 4, '{ec8030f7-c20a-464f-9b0e-13a3a9e97384}', '1.5', '1.5.*', '0000-00-00 00:00:00', '0000-00-00 00:00:00'),
+(7, 5, NULL, '1.5', '1.5.*', '0000-00-00 00:00:00', '0000-00-00 00:00:00'),
+(18, 1, '{ec8030f7-c20a-464f-9b0e-13a3a9e97384}', '1.7', '1.7.*', '0000-00-00 00:00:00', '0000-00-00 00:00:00');
+
+--
+-- Dumping data for table `blitems`
+--
+
+INSERT INTO `blitems` (`id`, `guid`, `min`, `max`, `os`, `created`, `modified`) VALUES
+(1, 'item_1@domain', '1.0', '2.0.*', NULL, '0000-00-00 00:00:00', '0000-00-00 00:00:00'),
+(2, 'item_1@domain', '3.0', '3.0.*', NULL, '0000-00-00 00:00:00', '0000-00-00 00:00:00'),
+(3, 'item_2@domain', '3.1', '4.0.*', NULL, '0000-00-00 00:00:00', '0000-00-00 00:00:00'),
+(4, 'item_3@domain', NULL, NULL, NULL, '0000-00-00 00:00:00', '0000-00-00 00:00:00'),
+(5, 'item_4@domain', NULL, NULL, 'WINNT,Darwin', '0000-00-00 00:00:00', '0000-00-00 00:00:00'),
+(6, 'item_5@domain', NULL, NULL, NULL, '0000-00-00 00:00:00', '0000-00-00 00:00:00'),
+(7, 'item_6@domain', NULL, NULL, 'WINNT,Darwin', '0000-00-00 00:00:00', '0000-00-00 00:00:00');
+
+--
+-- Dumping data for table `blplugins`
+--
+
+INSERT INTO `blplugins` (`id`, `name`, `guid`, `min`, `max`, `os`, `xpcomabi`, `description`, `filename`, `created`, `modified`) VALUES
+(1, 'morgaplugin', '{ec8030f7-c20a-464f-9b0e-13a3a9e97384}', '1.0', '2.0', NULL, NULL, 'breaks stuff guaranteed', 'worm.exe', '0000-00-00 00:00:00', '0000-00-00 00:00:00'),
+(2, NULL, '{ec8030f7-c20a-464f-9b0e-13a3a9e97384}', '1.0', '2.0', NULL, NULL, 'some description', 'worm.exe', '0000-00-00 00:00:00', '0000-00-00 00:00:00'),
+(3, 'suckyplugin', '{ec8030f7-c20a-464f-9b0e-13a3a9e97384}', '1.0', '2.0', NULL, NULL, NULL, 'worm.exe', '0000-00-00 00:00:00', '0000-00-00 00:00:00'),
+(4, 'ubersuckyplugin', '{ec8030f7-c20a-464f-9b0e-13a3a9e97384}', '1.0', '2.0', NULL, NULL, 'some description', NULL, '0000-00-00 00:00:00', '0000-00-00 00:00:00'),
+(5, 'upyourplug', '{ec8030f7-c20a-464f-9b0e-13a3a9e97384}', '1.0', '2.0', NULL, 'x86_64-gcc3', 'some description', NULL, '0000-00-00 00:00:00', '0000-00-00 00:00:00'),
+(6, 'badplug', '{ec8030f7-c20a-464f-9b0e-13a3a9e97384}', '1.0', '2.0', 'WINNT,Darwin', NULL, 'some description', NULL, '0000-00-00 00:00:00', '0000-00-00 00:00:00');
+
+--
+-- Dumping data for table `cannedresponses`
+--
+
+INSERT INTO `cannedresponses` (`id`, `name`, `response`, `created`, `modified`) VALUES
+(1, 110, 111, '2006-11-04 13:50:22', '2006-11-04 13:50:22');
+
+--
+-- Dumping data for table `collections`
+--
+
+INSERT INTO `collections` (`id`, `uuid`, `name`, `nickname`, `description`, `created`, `application_id`) VALUES
+(1,'6e073f02-242b-b10b-5457-c406857bfa92',165, 'testo nickname', 166, NOW(), 18),
+(2,'bd31fbdd-d6f2-4c72-bbef-b2854207908a',167, 'cannoli', 168, NOW(), 1);
+
+--
+-- Dumping data for table `downloads`
+--
+
+INSERT INTO `download_counts` (`id`, `addon_id`, `count`, `date`) VALUES
+(1, 9, 0, '2008-01-01');
+
+--
+-- Dumping data for table `favorites`
+--
+
+
+--
+-- Dumping data for table `features`
+--
+
+INSERT INTO `features` (`id`, `addon_id`, `start`, `end`, `created`, `modified`, `locale`, `application_id`) VALUES
+(1, 7, '2006-10-16 13:32:31', '2012-10-16 13:32:31', '2006-10-16 13:32:31', '2006-10-16 13:32:31', NULL, 1),
+(2, 8, '2006-10-16 13:32:31', '2016-10-16 13:32:31', '2006-10-16 13:32:31', '2006-10-16 13:32:31', NULL, 1),
+(3, 9, '2006-10-16 13:32:31', '2016-10-16 13:32:31', '2006-10-16 13:32:31', '2006-10-16 13:32:31', NULL, 1),
+(4, 7, '2007-02-04 00:00:00', '2015-02-10 00:00:00', '0000-00-00 00:00:00', '0000-00-00 00:00:00', NULL, 18);
+
+--
+-- Dumping data for table `files`
+--
+
+INSERT INTO `files` (`id`, `version_id`, `platform_id`, `filename`, `size`, `hash`, `codereview`, `status`, `datestatuschanged`, `created`, `modified`) VALUES
+(1, 1, 1, 'farming.xpi', 120550, NULL, 0, 4, '0000-00-00 00:00:00', '2006-09-28 09:02:56', '2006-09-28 09:02:56'),
+(2, 2, 1, 'fishing.xpi', 23, NULL, 0, 3, '2006-10-16 00:00:00', '2006-10-16 00:00:00', '2006-10-16 00:00:00'),
+(3, 3, 6, 'hunting-windows.xpi', 632, NULL, 0, 4, '2006-10-16 00:00:00', '2006-10-16 00:00:00', '2006-10-16 00:00:00'),
+(4, 4, 1, 'google.src', 1176, NULL, 0, 0, '0000-00-00 00:00:00', '2007-01-04 16:14:41', '0000-00-00 00:00:00'),
+(5, 5, 1, 'del.icio.us.src', 683, NULL, 0, 0, '0000-00-00 00:00:00', '2007-01-04 16:14:41', '0000-00-00 00:00:00'),
+(6, 6, 1, 'IMDB.src', 1154, NULL, 0, 0, '0000-00-00 00:00:00', '2007-01-04 16:13:39', '0000-00-00 00:00:00'),
+(7, 7, 1, 'wikipedia.src', 1171, NULL, 0, 0, '0000-00-00 00:00:00', '2007-01-04 16:14:41', '0000-00-00 00:00:00'),
+(8, 8, 1, 'a9.src', 1757, NULL, 0, 0, '0000-00-00 00:00:00', '2007-01-04 16:14:08', '0000-00-00 00:00:00'),
+(9, 9, 1, 'farming2.xpi', 120, NULL, 0, 4, '2006-10-16 00:00:00', '2006-10-16 00:00:00', '2006-10-16 00:00:00'),
+(10, 3, 3, 'hunting-linux.xpi', 123, NULL, 0, 3, '2006-10-16 00:00:00', '2006-10-16 00:00:00', '2006-10-16 00:00:00'),
+(20935, 19132, 1, '_auml_rkovalnik_za_slovenski_jezik-0.1-fx+zm+tb.xpi', 1151, 'sha1:07734da324833dc716170c7cf936531944fb90c2', 0, 4, '0000-00-00 00:00:00', '2007-01-28 12:46:17', '0000-00-00 00:00:00'),
+(20945, 19160, 1, 'w_atilde_para_rterbuch_quot_deutsch_schweiz_quot_-1.0-fx+zm+tb.xpi', 347, 'sha1:c22b68dd5fc4f09fffdb7eb10d4a38e2768de057', 0, 4, '0000-00-00 00:00:00', '2007-01-28 12:46:17', '0000-00-00 00:00:00'),
+(20949, 19168, 1, 'polski_slownik_poprawnej_pisowni-0.9.20060727-fx+zm+tb.xpi', 822, 'sha1:04377b1185074e4a2242cd510ceeb328ef83edbd', 0, 4, '0000-00-00 00:00:00', '2007-01-28 12:46:18', '0000-00-00 00:00:00'),
+(20951, 19172, 1, 'dizionario_italiano-2.3_beta_2006_07_23-fx+zm+tb.xpi', 365, 'sha1:f23096699f498064d0446601075cf81f0f2ace01', 0, 4, '0000-00-00 00:00:00', '2007-01-28 12:46:18', '0000-00-00 00:00:00'),
+(20956, 19202, 1, 'diccionario_espa_atilde_plusmn_ol_argentina-1.0-fx+zm+tb.xpi', 195, 'sha1:df4a2fffc994f8acb6b3d385bf70cd9e80f05a39', 0, 4, '0000-00-00 00:00:00', '2007-01-28 12:46:18', '0000-00-00 00:00:00'),
+(20972, 19237, 1, 'svensk_r_atilde_curren_ttstavningsordlista-1.3-fx+zm+tb.xpi', 107, 'sha1:9da63908277dfb56c622f3cc9431cbd3ba6b9416', 0, 4, '0000-00-00 00:00:00', '2007-01-28 12:46:19', '0000-00-00 00:00:00'),
+(20978, 19255, 1, 'dictionnaire_myspell_en_fran_atilde_acirc_sect_ais-1.0.1-fx+zm+tb.xpi', 319, 'sha1:b5e55f03084aad1cbfdcd14e28c4189f746d54a9', 0, 4, '0000-00-00 00:00:00', '2007-01-28 12:46:20', '0000-00-00 00:00:00'),
+(21007, 19335, 1, '', 1059, '', 0, 1, '0000-00-00 00:00:00', '2007-01-28 12:46:21', '0000-00-00 00:00:00'),
+(21012, 19346, 1, '', 2534, '', 0, 1, '0000-00-00 00:00:00', '2007-01-28 12:46:21', '0000-00-00 00:00:00'),
+(21013, 19350, 1, '', 2535, '', 0, 1, '0000-00-00 00:00:00', '2007-01-28 12:46:21', '0000-00-00 00:00:00'),
+(21080, 19497, 1, '', 193, '', 0, 1, '0000-00-00 00:00:00', '2007-01-28 12:46:24', '0000-00-00 00:00:00'),
+(21081, 19500, 1, 'english_australian_dictionary-0.2-fx+zm+tb.xpi', 193, 'sha1:9864ddecad37d075aca9c5eb4832e33b4af992ec', 0, 4, '0000-00-00 00:00:00', '2007-01-28 12:46:24', '0000-00-00 00:00:00'),
+(21117, 19567, 1, 'litreoir_gaelspell_do_mhozilla-4.1-fx+zm+tb.xpi', 287, 'sha1:5ab17f7ad88e2456bd02c974b3bf7ff828241864', 0, 4, '0000-00-00 00:00:00', '2007-01-28 12:46:26', '0000-00-00 00:00:00'),
+(21246, 19841, 1, 'corrector_para_portugu_ecirc_s_europeu-20060808-fx+zm+tb.xpi', 137, 'sha1:2b62069e38ebf5dd39943249858dcedc17a80b06', 0, 4, '0000-00-00 00:00:00', '2007-01-28 12:46:32', '0000-00-00 00:00:00'),
+(21483, 20376, 1, 'deutsches_w_ouml_rterbuch_erweitert_f_uuml_r_ouml_sterreich-1.0.1-fx+zm+tb.xpi', 2535, 'sha1:5066828b2cda16f39ea2a82cdec873519344a626', 0, 4, '0000-00-00 00:00:00', '2007-01-28 12:46:43', '0000-00-00 00:00:00'),
+(21484, 20379, 1, 'deutsches_w_ouml_rterbuch-1.0.1-fx+zm+tb.xpi', 2534, 'sha1:b0c072c0d4dfb72edeb8e76dfc8d62d8526434a9', 0, 4, '0000-00-00 00:00:00', '2007-01-28 12:46:43', '0000-00-00 00:00:00'),
+(21531, 20469, 1, '', 137, '', 0, 1, '0000-00-00 00:00:00', '2007-01-28 12:46:45', '0000-00-00 00:00:00'),
+(21533, 20474, 1, '', 135, '', 0, 1, '0000-00-00 00:00:00', '2007-01-28 12:46:45', '0000-00-00 00:00:00'),
+(21612, 20631, 1, '', 501, '', 0, 1, '0000-00-00 00:00:00', '2007-01-28 12:46:49', '0000-00-00 00:00:00'),
+(21677, 20783, 1, 'nederlands_woordenboek-1.0.1-fx+tb.xpi', 501, 'sha1:d42917dd5d24f60e44200128ddab4fd3cb2932a3', 0, 4, '0000-00-00 00:00:00', '2007-01-28 12:46:52', '0000-00-00 00:00:00'),
+(21803, 21051, 1, 'norsk_bokm_aring_l_og_nynorsk_ordliste-2.0.8.1-fx+zm+tb.xpi', 1059, 'sha1:75a5b835ed8db139bf34b0441d5c2a13d15119b3', 0, 4, '0000-00-00 00:00:00', '2007-01-28 12:46:59', '0000-00-00 00:00:00'),
+(21821, 21078, 1, 'british_english_dictionary-1.19-fx+zm+tb.xpi', 244, 'sha1:25bdc01bd7a59fbdd8baf1e13e22aeda0b7b5154', 0, 4, '0000-00-00 00:00:00', '2007-01-28 12:47:00', '0000-00-00 00:00:00'),
+(21823, 21082, 1, 'pt-br_spelling_dictionary-1.0-fx+tb.xpi', 120, 'sha1:e92819979915982724f9163b31d05d1b652cea91', 0, 4, '0000-00-00 00:00:00', '2007-01-28 12:47:00', '0000-00-00 00:00:00'),
+(21833, 21098, 1, 'diccionari_catal_agrave_-0.1-fx+zm+tb.xpi', 556, 'sha1:f26ab577bb33954d8d07831607cda79907584941', 0, 4, '0000-00-00 00:00:00', '2007-01-28 12:47:00', '0000-00-00 00:00:00'),
+(21880, 21217, 1, '', 137, '', 0, 1, '0000-00-00 00:00:00', '2007-01-28 12:47:04', '0000-00-00 00:00:00'),
+(21881, 21220, 1, 'corrector_para_portugu_ecirc_s_europeu-20060914.1-fx+zm+tb.xpi', 137, 'sha1:8e6616d6082901029466329e03dd258618c3fe7a', 0, 4, '0000-00-00 00:00:00', '2007-01-28 12:47:04', '0000-00-00 00:00:00'),
+(21911, 21281, 1, 'hungarian_dictionary-1.1.1-fx+zm+tb.xpi', 1028, 'sha1:9f2cd01ca528978213dddf46e82cf945a692a63c', 0, 4, '0000-00-00 00:00:00', '2007-01-28 12:47:05', '0000-00-00 00:00:00'),
+(21918, 21303, 1, '', 212, '', 0, 1, '0000-00-00 00:00:00', '2007-01-28 12:47:05', '0000-00-00 00:00:00'),
+(21936, 21349, 1, 'czech_spell_checking_dictionary-1.0-fx+zm+tb.xpi', 1175, 'sha1:2af18b8a5c894e633fb741ebd7713de57d78fa60', 0, 4, '0000-00-00 00:00:00', '2007-01-28 12:47:06', '0000-00-00 00:00:00'),
+(21943, 21368, 1, 'romanian_dictionary-1.0.0-fx+zm+tb.xpi', 212, 'sha1:0b634f63a74a82d7beb08132e44fee8723649ed3', 0, 4, '0000-00-00 00:00:00', '2007-01-28 12:47:06', '0000-00-00 00:00:00'),
+(21944, 21371, 1, 'hungarian_dictionary-1.1.2-fx+zm+tb.xpi', 1027, 'sha1:ca5b1e5cf86c461eb8828e433ea386c1affb90b4', 0, 4, '0000-00-00 00:00:00', '2007-01-28 12:47:06', '0000-00-00 00:00:00'),
+(22041, 21559, 1, 'nederlands_woordenboek-1.0.3-fx+tb.xpi', 729, 'sha1:ef988d85b427109ddaa2edcf2a9ade5bf3456372', 0, 4, '0000-00-00 00:00:00', '2007-01-28 12:47:12', '0000-00-00 00:00:00'),
+(22103, 21717, 1, 'hungarian_dictionary-1.1.3-fx+zm+tb.xpi', 494, 'sha1:0b793009b56e75e8293211c4fa068e38abafd50b', 0, 4, '0000-00-00 00:00:00', '2007-01-28 12:47:16', '0000-00-00 00:00:00'),
+(22111, 21728, 1, 'greek_spelling_dictionary-0.7-fx+zm+tb.xpi', 1546, 'sha1:26273c18a853464ab2b7a47f0b4be91c53b17db4', 0, 4, '0000-00-00 00:00:00', '2007-01-28 12:47:16', '0000-00-00 00:00:00'),
+(22150, 21813, 1, '', 1786, '', 0, 1, '0000-00-00 00:00:00', '2007-01-28 12:47:18', '0000-00-00 00:00:00'),
+(22151, 21816, 1, 'english_-_greek_spelling_dictionary-0.2-zm+tb.xpi', 1786, 'sha1:bf5d261e26a6bbe5521122d43d9a70567c897e4d', 0, 4, '0000-00-00 00:00:00', '2007-01-28 12:47:19', '0000-00-00 00:00:00'),
+(22431, 22356, 1, 'corrector_para_portugu_ecirc_s_europeu-20060927-fx+zm+tb.xpi', 137, 'sha1:c94867c9dbe05ba9d1e896e9f3727126ed179e5b', 0, 4, '0000-00-00 00:00:00', '2007-01-28 12:47:32', '0000-00-00 00:00:00'),
+(22516, 22505, 1, 'dictionnaire_myspell_en_fran_ccedil_ais_r_eacute_forme_1990_-1.0-fx.xpi', 306, 'sha1:a95a53a5ba3dc027caf53bd42afe80d7e1ec3845', 0, 4, '0000-00-00 00:00:00', '2007-01-28 12:47:36', '0000-00-00 00:00:00'),
+(22730, 22937, 1, '', 242, '', 0, 1, '0000-00-00 00:00:00', '2007-01-28 12:47:47', '0000-00-00 00:00:00'),
+(22731, 22940, 1, 'united_states_english_dictionary-2.0.0.1-fx+zm+tb.xpi', 242, 'sha1:2ea4f616e14d40c73b808f46755c52d22fbaa1e0', 0, 4, '0000-00-00 00:00:00', '2007-01-28 12:47:47', '0000-00-00 00:00:00'),
+(22781, 23039, 1, 'united_states_english_dictionary-2.0.0.2-fx+zm+tb.xpi', 242, 'sha1:6c9add70e325383eca618cd64a806598aa4debfe', 0, 4, '0000-00-00 00:00:00', '2007-01-28 12:47:49', '0000-00-00 00:00:00'),
+(22844, 23153, 1, 'norsk_bokm_aring_l_og_nynorsk_ordliste-2.0.8.2-fx+zm+tb.xpi', 1059, 'sha1:8ac347559bd7a8acd85e9d9dd4c701cafedf7753', 0, 4, '0000-00-00 00:00:00', '2007-01-28 12:47:53', '0000-00-00 00:00:00'),
+(22942, 23355, 1, 'united_states_english_dictionary-2.0.0.3-fx+zm+tb.xpi', 242, 'sha1:b2b3cd56650eb8db81bb1e8ef2bd326c049b17f7', 0, 4, '0000-00-00 00:00:00', '2007-01-28 12:48:00', '0000-00-00 00:00:00'),
+(22961, 23399, 1, 'polski_slownik_poprawnej_pisowni-0.9.20061014-fx+zm+tb.xpi', 916, 'sha1:49d69460124998f0751034e847534bd85e29844a', 0, 4, '0000-00-00 00:00:00', '2007-01-28 12:48:01', '0000-00-00 00:00:00'),
+(23047, 23555, 1, 'diccionario_de_espa_ntilde_ol_espa_ntilde_a-1.0-fx+zm+tb.xpi', 192, 'sha1:696958a6064fc194ae6f99cd42a2cd52de104aec', 0, 4, '0000-00-00 00:00:00', '2007-01-28 12:48:05', '0000-00-00 00:00:00'),
+(23076, 23634, 1, 'litreoir_gaelspell_do_mhozilla-4.1.1-fx+zm+tb.xpi', 287, 'sha1:0555e32011f58617cf01b0945e68247e75017892', 0, 4, '0000-00-00 00:00:00', '2007-01-28 12:48:07', '0000-00-00 00:00:00'),
+(23088, 23650, 1, 'united_states_english_dictionary-2.0.0.4-fx+zm+tb.xpi', 242, 'sha1:80884866ea53c026106bbee701b52eb5a1aa9de2', 0, 4, '0000-00-00 00:00:00', '2007-01-28 12:48:07', '0000-00-00 00:00:00'),
+(23098, 23672, 1, 'united_states_english_dictionary-2.0.0.5-fx+zm+tb.xpi', 242, 'sha1:bed7232a890e38f4be1a62f5a4942452c8e29489', 0, 4, '0000-00-00 00:00:00', '2007-01-28 12:48:08', '0000-00-00 00:00:00'),
+(23160, 23818, 1, 'dizionario_italiano-3.0-fx+zm+tb.xpi', 365, 'sha1:1fc205c702c0b5de209cb62a8d07a259c6e530c1', 0, 4, '0000-00-00 00:00:00', '2007-01-28 12:48:11', '0000-00-00 00:00:00'),
+(23166, 23829, 1, 'dansk_ordbog_-_danish_dictionary-1.4.57-fx+zm+tb.xpi', 432, 'sha1:1a57c87750ace7d90c1b1ce34a3fc6ce37e0975b', 0, 4, '0000-00-00 00:00:00', '2007-01-28 12:48:12', '0000-00-00 00:00:00'),
+(23175, 23840, 1, 'united_states_english_dictionary-2.0.0.6-fx+zm+tb.xpi', 242, 'sha1:d1d58ff5e7b436c628879e201f75575bc98cbe6e', 0, 4, '0000-00-00 00:00:00', '2007-01-28 12:48:12', '0000-00-00 00:00:00'),
+(23290, 24072, 1, 'bulgarian_dictionary-2.0.0.1-fx+zm+tb.xpi', 257, 'sha1:9952ee9f70e44f5f1aae7aaa1c047d0a6f89038a', 0, 4, '0000-00-00 00:00:00', '2007-01-28 12:48:18', '0000-00-00 00:00:00'),
+(23301, 24089, 1, 'croatian_dictionary_-_hrvatski_rje_nik-1.0-fx.xpi', 724, 'sha1:0ec95973fdc560f4e78719095ff1c46a0d4399b8', 0, 4, '0000-00-00 00:00:00', '2007-01-28 12:48:18', '0000-00-00 00:00:00'),
+(23369, 24211, 1, 'icelandic_dictionary_for_firefox_2.0_spell_checker-1.0.1-fx+tb.xpi', 653, 'sha1:6732b975607dce11e1b80b6d98489a7ba5ff3f20', 0, 4, '0000-00-00 00:00:00', '2007-01-28 12:48:23', '0000-00-00 00:00:00'),
+(23403, 24276, 1, 'hebrew_spell-checking_dictionary_from_hspell_-1.0-fx+zm+tb.xpi', 802, 'sha1:cd1ea17264eabd019ff64c390f2d76fcb3578d1b', 0, 4, '0000-00-00 00:00:00', '2007-01-28 12:48:24', '0000-00-00 00:00:00'),
+(23412, 24293, 1, 'corrector_para_portugu_ecirc_s_europeu-6.10.24.0-fx+zm+tb.xpi', 137, 'sha1:f829d6a08158965332d72c2e2e9a77cee5c3a4cf', 0, 4, '0000-00-00 00:00:00', '2007-01-28 12:48:24', '0000-00-00 00:00:00'),
+(23431, 24333, 1, 'diccionario_de_espa_ntilde_ol_espa_ntilde_a-1.1-fx+zm+tb.xpi', 290, 'sha1:e4880f3911d1088dac031dfccee2171fa0e0b05c', 0, 4, '0000-00-00 00:00:00', '2007-01-28 12:48:25', '0000-00-00 00:00:00'),
+(23456, 24378, 1, '', 314, '', 0, 1, '0000-00-00 00:00:00', '2007-01-28 12:48:26', '0000-00-00 00:00:00'),
+(23463, 24391, 1, 'canadian_english_dictionary-1.0.1-fx+zm+tb.xpi', 326, 'sha1:eaf3e5fc6f232f2bcb47007770d0c55a22dda66e', 0, 4, '0000-00-00 00:00:00', '2007-01-28 12:48:27', '0000-00-00 00:00:00'),
+(23559, 24560, 1, 'arabic_spell-checking_dictionary-1.2b1-fx+zm+tb.xpi', 3509, 'sha1:1ed1e6220bb8b1374c07a864b8394a8b99300c1e', 0, 4, '0000-00-00 00:00:00', '2007-01-28 12:48:32', '0000-00-00 00:00:00'),
+(23577, 24605, 1, '', 89, '', 0, 1, '0000-00-00 00:00:00', '2007-01-28 12:48:33', '0000-00-00 00:00:00'),
+(23631, 24704, 1, 'russian_spell_dictionary-0.1-fx+zm+tb.xpi', 459, 'sha1:7e9d13319619b831dfa8195fc985a0466e01cd38', 0, 4, '0000-00-00 00:00:00', '2007-01-28 12:48:35', '0000-00-00 00:00:00'),
+(23632, 24707, 1, 'esperanta_vortaro-1.0.1-fx+zm+tb.xpi', 89, 'sha1:ab5798661ee04a139ba187f2c6f39a54e9cd1761', 0, 4, '0000-00-00 00:00:00', '2007-01-28 12:48:35', '0000-00-00 00:00:00'),
+(23670, 24779, 1, 'lietuvi_kalbos_tikrinimo_odynas-1.1+cvs20060719-fx+zm+tb.xpi', 260, 'sha1:e20c637551a531521014bc5bff66d48322bc744b', 0, 4, '0000-00-00 00:00:00', '2007-01-28 12:48:38', '0000-00-00 00:00:00'),
+(23782, 24956, 1, 'geiriadur_cymraeg-0.02-fx+zm+tb.xpi', 675, 'sha1:dd4f79c6654eaafb86cd0cf091d7482b8fff7165', 0, 4, '0000-00-00 00:00:00', '2007-01-28 12:48:45', '0000-00-00 00:00:00'),
+(24087, 25529, 1, '', 112, '', 0, 4, '0000-00-00 00:00:00', '2007-01-28 12:49:01', '0000-00-00 00:00:00'),
+(24110, 25562, 2, 'suomenkielinen_oikoluku-0.9.5-fx+tb-linux.xpi', 2313, 'sha1:86483a72e869b5bef2830ee9e10eeae76f31fd89', 0, 4, '0000-00-00 00:00:00', '2007-01-28 12:49:02', '0000-00-00 00:00:00'),
+(24194, 25562, 5, 'suomenkielinen_oikoluku-0.9.5-fx+tb-windows.xpi', 2313, 'sha1:893125fe02a94d0056fc1a4425b1e0d0b6a2c365', 0, 4, '0000-00-00 00:00:00', '2007-01-28 12:49:06', '0000-00-00 00:00:00'),
+(24352, 26012, 1, 'corrector_para_portugu_ecirc_s_europeu-6.11.16.0-fx+zm+tb.xpi', 137, 'sha1:db39ec8c8196baa42d52a37bae8930c42940b718', 0, 4, '0000-00-00 00:00:00', '2007-01-28 12:49:14', '0000-00-00 00:00:00'),
+(24499, 26294, 1, 'english_-_greek_spelling_dictionary-0.3-fx+zm+tb.xpi', 1790, 'sha1:f3c4fb09677495dcbf6372bd251a0304d26b767e', 0, 4, '0000-00-00 00:00:00', '2007-01-28 12:49:22', '0000-00-00 00:00:00'),
+(24590, 26492, 1, 'upper_sorbian_spelling_dictionary-0.0.20060327-fx+zm+tb.xpi', 158, 'sha1:e02accdc745fda4005d3fc5d078817962ce5c90a', 0, 4, '0000-00-00 00:00:00', '2007-01-28 12:49:27', '0000-00-00 00:00:00'),
+(24790, 26872, 1, 'lietuvi_kalbos_tikrinimo_odynas-1.1+cvs20061127-fx+zm+tb.xpi', 353, 'sha1:e7a841ccfb145ed2f26f002d0681c019c69f8982', 0, 4, '0000-00-00 00:00:00', '2007-01-28 12:49:37', '0000-00-00 00:00:00'),
+(24816, 26936, 1, 'latvie_scaron_u-0.7-fx+zm+tb.xpi', 789, 'sha1:beea80ae2c57e8402b82bac011d360040b757b2b', 0, 4, '0000-00-00 00:00:00', '2007-01-28 12:49:38', '0000-00-00 00:00:00'),
+(24822, 26948, 1, 'xuxen_iii_edbl-iii-fx+zm+tb.xpi', 430, 'sha1:4b429d9911f4ed03ebb97c80afe9797b3bbe3f38', 0, 4, '0000-00-00 00:00:00', '2007-01-28 12:49:38', '0000-00-00 00:00:00'),
+(24825, 26955, 1, 'suomen_kielen_oikoluku-0.9.6-fx+tb.xpi', 2390, 'sha1:00bcd162dfa886c3b319532513c71174839e4329', 0, 4, '0000-00-00 00:00:00', '2007-01-28 12:49:39', '0000-00-00 00:00:00'),
+(24902, 27076, 1, 'corrector_para_portugu_ecirc_s_europeu-6.12.07.0-fx+zm+tb.xpi', 137, 'sha1:5355839f4c8601d544058901f282c40c2bcd895d', 0, 4, '0000-00-00 00:00:00', '2007-01-28 12:49:43', '0000-00-00 00:00:00'),
+(25044, 27383, 1, 'svensk_ordlista-1.4-fx+zm+tb.xpi', 265, 'sha1:c4db97c39b8479eefefff8d4225e46834e8ce492', 0, 4, '0000-00-00 00:00:00', '2007-01-28 12:49:50', '0000-00-00 00:00:00'),
+(25117, 27512, 1, 'suomen_kielen_oikoluku-0.9.7-fx+tb.xpi', 2427, 'sha1:69ef460ac397e1f8871fbcc41cc507048224c89c', 0, 4, '0000-00-00 00:00:00', '2007-01-28 12:49:53', '0000-00-00 00:00:00'),
+(25159, 27589, 1, 'corrector_para_portugu_ecirc_s_europeu-6.12.18.0-fx+zm+tb.xpi', 137, 'sha1:88250e84827dda876a45cd26c55c25d8891773aa', 0, 4, '0000-00-00 00:00:00', '2007-01-28 12:49:55', '0000-00-00 00:00:00'),
+(25204, 27665, 1, 'upper_sorbian_spelling_dictionary-0.0.20060327.1-fx+zm+tb.xpi', 160, 'sha1:6cb8d9a5509e778612e6261b7fba319696089a3c', 0, 4, '0000-00-00 00:00:00', '2007-01-28 12:49:58', '0000-00-00 00:00:00'),
+(25319, 27876, 1, 'corrector_para_portugu_ecirc_s_europeu-6.12.26.0-fx+zm+tb.xpi', 137, 'sha1:e80c764f86306adafac3d928688cc8449718f8a3', 0, 4, '0000-00-00 00:00:00', '2007-01-28 12:50:04', '0000-00-00 00:00:00'),
+(25826, 28788, 1, 'dictionnaire_myspell_en_fran_ccedil_ais_r_eacute_forme_1990_-1.0.1-fx+zm+tb.xpi', 306, 'sha1:1b87fa5b423173013c56146213922910960f6860', 0, 4, '0000-00-00 00:00:00', '2007-01-28 12:50:30', '0000-00-00 00:00:00'),
+(25858, 28845, 1, '', 120, '', 0, 1, '0000-00-00 00:00:00', '2007-01-28 12:50:31', '0000-00-00 00:00:00'),
+(25888, 28896, 1, 'canadian_english_dictionary-1.0.2-fx+zm+tb.xpi', 326, 'sha1:ab0ac18555a6833271a24b100ceb98b473c91ae0', 0, 2, '0000-00-00 00:00:00', '2007-01-28 12:50:33', '0000-00-00 00:00:00'),
+(25889, 28897, 1, 'show_menubar-0.1-fx.xpi', 2, 'sha1:7c38bd898efa001a5c86283c55fbe5f951e4bcf9', 0, 4, '2007-02-11 19:06:44', '2007-02-11 18:18:03', '2007-02-11 19:06:44'),
+(25890, 28898, 1, 'chrome_list-0.1-fx.xpi', 25, 'sha1:f71084fffc9f4342517d7a022b78095ce9d62b81', 0, 4, '2007-02-11 18:57:54', '2007-02-11 18:38:15', '2007-02-11 18:57:54'),
+(25891, 28899, 2, 'chrome_list-0.2-fx-bsd.xpi', 49, 'sha1:06e718d1cbc54aa1f52cad732edb13c478573f7f', 0, 2, '0000-00-00 00:00:00', '2007-02-11 19:24:11', '2007-02-11 19:25:09'),
+(25892, 28900, 1, 'microdefender-1.0-fx+tb.xpi', 1, 'sha1:53d3b8f447787a8acbaff021f04b8466b65f2315', 0, 1, '0000-00-00 00:00:00', '2007-02-12 22:16:19', '2007-02-12 22:16:44'),
+(25893, 28901, 1, 'microdefender-0.9-fx+tb.xpi', 1, 'sha1:53d3b8f447787a8acbaff021f04b8466b65f2315', 0, 4, '0000-00-00 00:00:00', '2007-02-12 22:16:19', '2007-02-12 22:16:44');
+
+--
+-- Dumping data for table `groups`
+--
+
+INSERT INTO `groups` (`id`, `name`, `rules`, `created`, `modified`) VALUES
+(1, 'Admins', '*:*', '2007-02-10 13:29:03', '2007-02-10 16:57:10'),
+(2, 'Editors', 'Editors:*', '2007-02-10 16:32:21', '2007-02-10 16:32:21');
+
+--
+-- Dumping data for table `groups_users`
+--
+
+INSERT INTO `groups_users` (`group_id`, `user_id`) VALUES
+(1, 5),
+(2, 6);
+
+--
+-- Dumping data for table `platforms`
+--
+
+INSERT INTO `platforms` (`id`, `name`, `shortname`, `icondata`, `icontype`, `created`, `modified`) VALUES
+(1, 114, 115, NULL, '', '2006-08-23 19:34:28', '2006-08-23 19:34:28'),
+(2, 116, 117, NULL, '', '2006-08-23 19:34:42', '2006-08-23 19:34:42'),
+(3, 118, 119, NULL, '', '2006-08-23 19:35:05', '2006-08-23 19:35:05'),
+(4, 120, 121, NULL, '', '2006-08-23 19:35:33', '2006-08-23 19:35:33'),
+(5, 122, 123, NULL, '', '2006-08-23 19:35:49', '2006-08-23 19:35:49'),
+(6, 124, 125, NULL, '', '2006-08-23 19:36:02', '2006-08-23 19:36:02');
+
+--
+-- Dumping data for table `previews`
+--
+
+INSERT INTO `previews` (`id`, `addon_id`, `filedata`, `filetype`, `thumbdata`, `thumbtype`, `caption`, `highlight`, `created`, `modified`) VALUES
+(1, 7, 0x89504e470d0a1a0a0000000d49484452000001900000012c080200000062d57295000000097048597300000b1300000b1301009a9c180000200049444154789cecbd69931c39722dea0e44e4bed55ec52aaebdceeda791ec8d4c92e9fe7ce9834ccfaecd1d6966bad5cd6e76732992c5da322bf78c80bf0f27e1895832595c469a996eb02c1889402022b01c1c77381c7c7a7a7a7676f6e4c993e9745aabd58888889c73cc2c22c61811c179f9d18961162236ec4488884498d949222c2464392247cc2ce2d8108930192744c8c110c9f25944063142ce182621663cdd8890315684b24f2711318645c8184394b95a7cf35c0c11adfbbaf7c8edad796e2ecf30feed65ee9ff54ef16f3d12512e070a4298860a61f3550db81a661ea62fbd1abe9ea629c6ebcbe35298b2f498cb2acc21f739ef57983fe3a3635e01c8071ed998d4c96038b2363e393efee49387d1d9d9d937df7cf32ffff22f83c1a0dbed32b3732ed710d736712672c4448e859984880940c34e52c78e882c1912666121472c44cc64445b0c004b7c2b21624344ceb71beb3b30b1b124cccc446c9888844884c418c3c4cc198841d056a800b4ee28014ce8b787319c05a3dcbdb9bb4ae3734fc9f50ddca56f9bbb9acb2df70eb99a7a6badadcb3300960c6aac4b531a594c2365402605c0ca01440e4d240b61c5044484769bbb84735c0a131443f8945c51977ef89f0134fc791e1d918838112d3d32e63d73b3919d2fd2d76f2ee2b8f69bfff7378d7a3dbabcbcfce1871ffef55ffff5fcfc7c7777d75a9ba669b17ad606902a166221222666622276e41c3b223162d8039678c0c27d42424c24c2424ccc86713f91301331335bdf7a0049c6b0615e0116b10296a6a41c60510022b7b9ba217e33f06dce6d734c0858eb727e2b60959e6f0e9bc1e8366942c808237309a400585280aaf0588a3b8a3ea570837845a530a55e0a7f16e33714c22f615dc8017a0eb034cdbb668b461e57e2e96cf1d3d3d34ab5114795fff5ab2fa2f97c3e994c0683c1f5f5751cc7511485155ffa242616023c11a1ef302d5148909e85448c13117686890d1961874f006011b3b0c812eb1487845888093f0143444bc062b6860d33313922324c64848d6121e28803b0c84152ee3c77d5da0cd869fc070216c25b0128775c973e7c67e75cf826b406c28adf5e5295b700accd419b4a98610e8f4a116d1d601591a8084cfadc2290a569aa5dc8391742d2e6a34258b1347265f80bae6d081eb03275fa818035beb91e8fe7a3d168be9847711cd7ebf56eb73b9fcf3b9d4e1cc7ce070a46feb22c6949748888890d09fe0911b1b090111122678047c4222ce2006accc60316b121c3a4f827c4648cf15d1458c8860db331864984c83193354c2cb4e45f11111bb356e8d3e3ed61e836f094e347c5bbb4b6c234efcabf72578bf0749b98d2f0d696f4d6ceb98e988470b3f9aeb70256313e8ca12c608588839f0a5b0a49a527bfb0adf708594862e672c07abf9c015895d9e2aa35aa561bad56b35aad4404f6628cb5d65aabfd0a27395165792481ae6ad92252e79c132790f7c82bd449083448449c88902323e208c84429118b9018b6c28c044c640c118b73b2a455860d5bc898442c20612c6c889d7f2d638d354294a60281593f5bbf42bf2ed4106d86a4b76abe7229c32722bc2b60ad130cd70d1b9bf9d486abda864ad3bc530b2beddbcc9ca33fcabc8a7785004405a42b05b2d2bb72a2621899a2651492dd8673698194161aafd1bf6cbefa5773d4e121002cfe888065adb5d6d928b2d6424f1d1191732e4992344d9d73699a2649526c6199bc48989899c5b9f96c369b4d13979221d56011b31074f2c69021200b3968db916499131191811a9e590c9331abc732b321366c201291e021640c3320534488c558b2b110877d833c1063c2a256ab359bcd4aa512ca2f61811641e1f6051da62cdeb5a1df521964accb3f97b2d87f4a7b14dd8e9317d3dce6aee2b336c773a050cf456eb8b1f8f9b9772be619de48eb8bfdade8acb896cbed3625f37308dab60b0c2ba3c37abf9c0188ceb9344d923475ce915054ac6c6d0deb9eb7e44e969dc8643e1d0cfb29a57135624b4e96cc4898444852a29418a0631c1947224b0d15d451448bb97389186b6b354b86d2c48938c8774c345fb83411268e2363d8182203da46c424cce484a7292d52c3368e2bb131ec84209782524da7d3344d5bad561cc7711caf538a87e136acaa98be34072dcc75acaa344fed12b9e13a5741b7cff3ad6fbee16473e0ecb472ee0d6f990379814e6f270f1621c64910342500252cae6202c4ab5ab6a8a82a650d616f5cdb177e911cff7b02138027e26ca0c25046c5b62b20534c4cd3c5ec663294d835ea35b694a42961ca8f5988d2344d67ceb0892b9161224e891c131b63e22832d69093c564319ba6b55a6ca36a1451922cc83963d85ac3428b59329d2686d856a328b6968969a9be374cc63009cf27e9cd84a26aa36d3bc658e79c38073e2922b3d96c32993073afd7238f059bc12814873703d65ba14dbbee6d660f4be37339d07ac0ba4d7c7648bc2d2a6d0e456ab68172864050fcd2304d0e77c2788d51980b3f2d7755e53bd50628446a63d0f4614c885f3950fe05a7c2f0515ad1a6fc6939efc686a35c2bb9550642040245e2c8394ec53aa9388a49d254dc521623224953b770c48e22e62ab375248e49acb151ccb1154ac54c539aa536b2d55a1ac7b45824e29c356c2d93a3649ece4d6a892b11d7628aac6312728e9c18e6c872e2ec905371cc6c2a954aa512d9740958954a8588e2389e4ea7393e7f7bc8c814dc3ba6b97dcec5f87705cae2c9baf4a5311b48c4bb861c76ac83b322c1c9e5f056c0520c0ad3e4d853eec652740be12944790a5a0b67b572e1cb176b3387c53f9b205e0c7c072cb95dc69abf44988f0baf163b403e04d1c6b08dad54996bcc319994c509331bc32c24a991940cb3ad5054251333111b22cb5489a41a892432ab7232b7952a576b52a9b828724bc0322c2925734ae7261253afda7a95622b4c8e9c9013c3125b93381a4e6ca51255aab57abd5eadc669ea30f11fc73118d662b1a8542a9010d1f86eaf7af79ff96e0af80dfca834ff0d6936e4509a5b913ddd2646e34b1fb12eac6b9545480a2fe5a06a1d84dd06b014b62800ac1c30418fa95751f52a45e6e60a73d8e40a4153debe947e091f2178ed77890eeb1d03b36132380a09118c4859c8c1c28a0c13c378941d193104e3776799c89235c44ccc8e3935263536151668b844c8b01826cb1459b6c619762c29339111c3640d1189356c8c316c311bb8248f7e421091455ca6db31a0d28e5d7a6f69cacd6c4e0a425c31e63dde7033f32a3d5907619b439838e8c304f9095737b72ef6daa51cc5db0c5812e8b67210864acf9d53010d73af11a6419585a8a7a1341f791785dd2fe1bd036a24caf5a8f7ca88965450c4911312434e44c4f9da1512272e756461456ac889a42919316498d06291492a940a898811583d888890b01171224e5c4ae218ac934998441ce6078b6d37a73d5514d3f69733dda0352ce996693633a9d2630813da4f3e1660e5ce3743d2fb01562e87e0a16fd761853121450a936d00ac5cb2cd412547e5531c28a7344602b306255ce26997922ff60cbd54bdf52165f84bd81050fe1fceb0888276e364394527446a444ac222ec20c75936c610acb72c196308b52bcbb9502722422c8e9969b9c69084247569eac45a212227021307e770cec8c0f9919d02056a0858a57c275728a5f19baf6ecee796477db77702ac2c4c94c8f2a5d02665a4201793fb55561eb9a06f922123e1e34adf361c66c2349c55c3d307001605b0a2f0a42fa6d8843613a6d49f9c0d120c87b936768b82fa25bc4f40217f38c312126134565e366c66e6e5fa1a60966166369619d60a860c31096445225a8a94ab65374bac21c430f9e58644d62cf1d00931131bd86621190814099131925d734301c3a2f570f07e56ef1b2cdd371fe58319562e87dcd5dbdc95a94b3fd66cc8a4905ecf4d903c034f216015fb76296015a18a3602166d042ff24c2a0497507b15b2ad9c71bcfe842e2cd46421b037172a2da25fc2c70a68e11fccb08448d8928d4d2446489c88b3640d1b2c6616724cc6181b4591895358be5b63e3c84696c93139c7642cc7918d229b922347125963992525364e58982313556c24c62e5884194a7736c6b058b6c2c64491ad542a711ca7a9831d179619c5711ceab04a3beaba02bae5b198fe5d7350c07aa76785e739c3d75b8257984c44fc0023b912f23f36a96c34271db814a472cfcdb5378d098faee09f843e00b024900a8bb787a521810088ab21b0869815569926d03c6fd3c07e09ef1644e4431816c3b78230a5c48931a9a554d2d43887fe67580c258e1222264a0d8b61312e49172e656b38b694523277c99c2461971a97462ee134494524254b865d2a499a2c1217b1755449c5512a2c8e8559e06ecb2cc4242ed59514699a2649ea9cb3c1148f364a6558089bd715ae3bdf7c7c27b6a52dfb9de61625e04761ca100872f017e6409b3456e2ff58642515868c697d6fc4d35780a5cf7aeb39157856a8d52ac2d37b0056085b12302c9d37543cd25945f1348a37ce1b2ac30aef2a2b9f5fc287850f66584cc2e2c82d9c73328b171ccbc2a54ec490a42424269dba74e65276924ab230261611c7220b230b2396294d64324ce75319335f5e888d5c922444628d18c32e91e9249d4e9ce5459a9a51e42c272c02499285ac7189f0609c4ea789e3e1f9b989639ba64efce4a0880c0683e9740a1307edc6b9be4d593858575c38c98dc9a5c7d29cc3db89289cb8cc3d7703dcdce6b99b73c8e506600a60880158442160ad8e22e125a695918cc6986221df3e84f7e6660fdf09b0688d239adcedc56cf56a883b1cc89261a4162382429826fe856a7dac8022fd001d96101347268a4d9cb84426240b66b28cb586c224cca9b1629898524ea7247362b6c49c8a4c85fc8a406bada4298f47c4864562f26b1549284d2d1339e1f99cd2c4588e99709d8c101b12474e6c1c33899b4cc6b3599e92cce773668ea208eb9f8b6ce8364c6a3303ba3dc30a5f6c5d9eeb72dbccb03073e553524e2e0b7340e5293c15004b81290f586f690eabce9c01acb0938748514c93830329cc1ede0671c2ac3603566e421081bde916ce550694601db5c29304765b087af517add6c70fccf4210c0bf557afd5b7b776d234319121839584e43d5661b9b231d6180bd6ede03a46b5e8c618598a0f620cdc2e18274ed2e5021fc0a2085bc3d69ac81812af262022162676c28e8dea1ec2566e8c49d3d418d36ab5eaf57ac868680d9fb2d6c229183e30071940bd501c5853b699781d6cd5284c024b45bd6503530bdf734dca250214eecdbc48983807493e868b38b5ee3325231ee6670937144b0eb05cc10e8b0218caf1350e745e7a291742dc29052f7d44ee5994559f95824ef815b9f8e22768e6bf50ad0f0c28c6f76158488fbaac37eab57a4d30bbc498f803c42c57145a637939fa2b172066b24ba7c68660f5b9ec1ea2d69e41b734e47d5d596662b65641449676abc68aefc939c0428ce696635592e54a783a7cae96b22d6d7cc6875cb1e46cbb74100e73509fae1b720863d6f1af1cc3625e6aa0e08823cc21fc59440de4e4d9d6929ae5c03497610e320a19521849eb8356533165115c8a58933b4a6086ae8943c052d80a4b2fb4355566a4471dbab4cc43ad564e9f4505259766bba1108a2187d1bf04f24df7fd19967645a88a489694092dd689183236b2c698f96c3e994de2386e349ad6c2df0bd9a506878996c48a88c6a3d16836a9562aed4e278a22d87519b8c812379d4ea74952a954aab55a14c7e29c9018364cc6580bbd4b0e9e142ce03ca77424d7104511330f0683e17058a954b6b7b7a3285a2c164414c73132994c26f3f9bc52a9b4db6de8c524eb333e57c4216e8a489224c3e1703c1e57abd5adadad5aad26c13211ca020a15e069f3511916ada4425c5deaa43499e756ab5b71d147e571aaf84a6b7e7e7c1a11c2eb06c092c0a74211b064fd2ca10e429a0917f82c65b123875c61a0a0c9218410f90b007d5010910f9b25642282ff2ce7dd9346518496315f2cc4b96ab51a45d1743a1d8d46b55aad5aa91a8e5dea88480c69e330ce701c3be7aefb83cbcbcb4ea753ab37ac8d160b301d21a2c562717979351a8ddaed7614c575b6f0ca668c303b138c60caaa72af1a9ab9e7f45668a9511411d17c3ebfbebe6eb55a3b3b3b699a0e06036b6db7db8591c4743a1d0e87f57abdd56aa9e4b881b529a6a3edce66b3cbcbcb376fde74bbdd6eb75bad56178b450879a56fbee198655e0026e59ae5ec8c0aec49effd4086551ac2be5a4c5c244ae1a5d298f0d121d65056ed551acc9a853b211592826516ea0e39e7660629a0545060b9b2805772d985d9bf84770bccfc7e0c2b6ca6699a2e168b344dadb5715c31c6c4719ca6e962349a4c264992743a9d6ab52a22206279bd0f243a63a0dd5c2c16d3e9b45eafe3f596bd878d884bd3743e9fcf66b35ab5b67a6121cfabcac7e11038f002ec15499a00f17a57bd5edfd9d981ffac8b8b8b972f5f361a8d4ea753a95444a4d168586b61db45010892b753a5accf130a481f5e0f4ef4c1ad149bb24c87280b49d92a5babcf0a745219c0ca1d69a950673df1f19acf32a214b036c4bf35bcdfd0f821b971b056d105f377e179d89ed5b2416f0f65cc5cce5cc6d6b92c50d02a6ed3dd6e3f1efc7c026aea831816b2489264b158786e554195cfe7f3d168c4ccdd6eb75eaf83bc2897d1d1062dc35a823705cce51111f24c93c45a6b0c13595c8de3388aa3288ac46b8222b3749a4a44203239f6c45e49016025a2288af0b6f89070188ca2a8e683885c5d5dbd7af5aad56aedefef379b4d634ca3d168341ae092a078aa90823e1e72253e01dc939961d18a34711ce3a7bead31c6189ba33ca5fc483b4929188988d6e4ba1cfcd50d0c8bc26e52c4d077ed45b28661157bafac675892e553c5188d0c4f24a05da5f48a0a16f07aae4ccdadb7c392820e8bd7302c66463bd12fdaacd57a570ef1730868a81f612d21b0603e9f0311e6f3799aa6e3f1783e9fe331b3d96c3c1ec3e12733cfe7f3e9749a24099a0566f1b6b7b7ebf53a7e0e87c38b8b0b309a5aadda6cb670231e8693e9743a180ca228ea743a90d444a4ea43d8b1f17ae3f178381c2e160b660660552a15a8a8e6f3f97c3e37c6349bcd56ab9524c96432a956ab711c0f87c3c160301e8f9f3d7be69cabd56a488c6d3bd234edf7fbc3e110c0144551b3d9ec743acd6693992793c97038840958b3d96c341ab55a8d03b615628a3f09ab878a31ece7f2d6d7685848ec496a9e6105e7acda2e9f3ebc5acead02807b3753a30d29252b814ad9245d9840a97a3159980905d090833ccda114e3288b989a5bc89b24bb2e3a37aee4e2117252e12f1ceaf6e143191682d61cd04a44e6f339181633572a1563cc6030383f3fef76bb0097d16834994c9c57588e4623e75ca552a9d7ebd815314dd3d168349bcd902d11b75a2d2476be89cc66b37ebf5fabd5aad5ea6c36bbbebe36c66c6d6d01ad4ce092015cafdfefdfdcdc40744500602990d5eb7568a92e2f2f9f3f7fde6c368f8e8ec8032eb45a40a8abab2bc88c8bc5e2ecececeaea0a42a5b576b158c4715cad5689e8e6e6e6f5ebd783c1a05aad76bbddadadadadad2ddde64302e154448cb144a26011b6fe22c3527ec4ac5a2745ab108656b59303ac620c85b7ad392ff6ae10b0d6b5a25b322c1d5d421029dabb6b7a9dc7903285bae29d48dec94c0e954213130497358008f914bd8d619960ed8ecef36853d7abcab68a50fb0b7ead0b28c38fe3adc1f86d69405e9c73305642ab52da4544800fe75cabd5aad56a49924ca7d3d96c063a06512b8e63ccc1cd66338097b5b656ab4186d2ceecfc9619c3e1f0eaeaaad56a55ab55b018bc00a44b70b1e9740ad284fcf5adc0b99acd66afd7dbd9d9a956abce39cce2351a8d2449c0fb767777bbddae31062f0c4d397276ceedeeee4284acd7eb483f9fcf87c3e1f9f9f9e5e565a552994c26699a562a9556ab65b29eb9f4835403956352ca7a7c7a0af068c5b68264acaa777d843e287c6eee24fca938988bf4f9e75e894be38b61736f34c1eaa2104db2ef500e7f1ca893f4dcf82d4836005678e20a26112e50b916bbc95b3b4ed85c8b3f956de9e3f4cd735ffd4ba08fc5b050b2200ed56ab55eaf57abd5244966b319843e6656f513d8ca643269341a3b3b3bdd6e773a9dcee7f32449547b1dc771a7d3393c3cac542ad8de75369bcd66330096eaa4aad52a242f20489aa6d56ab5dd6e371a0d64c8cc50752d168be170a8a0837d28168bc5cdcd0de84fabd5eaf57a7b7b7bdbdbdb49924081d5ed76f7f7f799b956abb5dbed4f3ef9646767a7dfef5f5e5e56abd54aa502eeb6582c5aadd6279f7cb2b5b535994cc0b3269349bfdf8730d86834600c311c0e279349b3d90caded4d108a0ccbd38d4c8bcfcd21866c0b89712a59098bb28095bbba2e3e7c1011c1cb55c8a7de43a2c971a8b0a36a7c480043c644d9ee4d01b2acbbb46ed230f7689d0194acad960b66096fc3b0d6851cbd429987448c6e017f3ff3f0711896de0e48aa542ad56a1544890afe6a89080aac46a3d16c36dbedb63106ea76cdcd79efc610d944045b906953439e00acc964321e8f9d73ed761be425376c8ac87c3e1f8fc7101e615a351a8daeafaf2121429955afd76bb51ab466e13be0858d31bd5eafd7eb8d46234de09c83fe2b8aa25eafd7ed76019d4992bc7cf9f2c58b17954ae5d1a34751145d5f5f5f5d5d4135860fc11771469f8512127f2e4aaf94280527995af4c996e9c3cad4ab011163649e63670a08b4042670340a4e42b55a29ac697a1259dd554cc759295582359ea5e94b73a0408a5c3e3e8b47a5c4aa0858b46ac342b4c9a3034ec2316373c7e120843f73094264cce5f90bbd0a03caff43edb0707bc8148032618c56952211e8c96432512216a6141168b2c4d337dd03556700ebf53a00623c1e5b6bc1d78848b955f84468c7903e8a221025d816404894a59b8724c4561181aa0b4262a3d100902d67f5ac053a33f3783c1691cbcb4be8c886c361bfdfdfdfdf3f3939e9f57aaf5fbf8ea208f65c5110b2df653d5e0873cedf7c48854ab45aa84dad8ad028a1d83dfc798e61adf4f4e4014b44b492c31cb260416580c512eca6c9598493405725657aab304d6ef829bdba0eb0f45211adc21b5da0b182c55fc8b3747a31a45412b0b0db33acf01c417fa2b587e01b76b1cdb0f8f30928b40fb27427222002ba22580cb815f453501b61135340c3f6f6363441575757c3e110e21233630eb1d168b4dbed7abd8e897fd0a84aa5d26c3681508bc502d36ded761be465b158b4dbedfdfdfd6eb7ebbc71033e0f27fbfbfbf57a7d3c1e4fa7d3e7cf9f23b2d56a359b4dbc2aa4423cd45adbe974b6b7b7a1113b3838f8e28b2f86c3e1e9e929b460bd5ecf39d7ed76dbed76a55201613c3d3d45b3031163668032661887c36114453b3b3bbbbbbb9d4e4744767777f1b8b026684585708e619c73221d3363df467f2b922dc18559d3af6e03ac04e3b9a6d4a7eb43894817f4e60732ff02a87df2e9734480fddf5a657c18af6a26ce4ef6e9dbe6869010e66e035822848f0e2e865c86d7dd484bbfdbba33856176222ef7027cbba05f146290fed450940d737db314d17e260105fe116609a194c151442093475154ad5631eb67ad859ce89c8311d3d5d595f291e9744a5e836ead6d341a303445e5619e112803d5bbda97a3892f160be755ec18a9546500b6d56834eaf5fac5c5c5e9e9e9e5e5a531666f6feff0f0104afd2449a0d5d2ace238ee76bb954a05faa9fbf7ef3f79f2e4f9f3e7d7d7d7f7efdf570c25a246a3b1b7b7f7fcf9f367cf9e254902c1b05aad9e9c9cb45aad67cf9e7df7dd77373737511475bbddbdbdbd46a34144c6184c38b0b79f56a3300ee8c672c11311151cd1309b5c1f9012ce55cec54432dc8a280432821e0d69cdd261ec4aec0a81a6549fe5cf4d56907c0bb7d2af2b15b572e7616eeb008bb2dc2a773597c63993bbe4ca660ce96dfe48370734306d9c1c10ae501651c1a2885cbf0494dbfb332c34384876500641cc419382225c44000a38a6695aabd5d234bdb9b9198d4640282cd6bbbcbc24225dac074bd4c56281bb6097008605ab887abd9ea6e9c5c5c5703824a2e7cf9f5f5e5ec2a222142dd99b56dcdcdc5c5e5e5e5f5f6bef8ae31873976acc09d970341a8dc76388abcd66d3397779797971717173730338c3da9d7ebf1fc7f16432b9b8b800f862eab0dfefd7ebf5f97c7e7676f6ead52b2c4b04144e261368d0e6f379afd783f5bc4e7dfadeb83ccf0de0c59ac3291179c593928e0c870a74554b051973c88f988359c8707230942bb585e45e2604ac200669f2565aa54099bb54dac6f4a764955685c424a2c467991c6973daba10ce8cc90196a3e5ee274bb6eb4f96e70185842dd8d28bb72af882bf55c8951533876e6ac2a290603588f6cd75e5f3f30a22f2210c4b070d689ad5c25b336766689a11033302ed57c0114d06dd398c2160685a24057a1c0e872020d3e914537ed013c17222ec06613b20224864b09fcae59feb452232180cd84fee801c5d5d5d6986979797fa2d584b4444002fcd01e40ed9c2108c9967b31911596b61b48172535d0905bd943dfb30819d51591f208539e544ba68d27ffb32256e5dfae6097a0aa04acaf857780ccb27773588316f4da30fcae1919e97a61129110683bb805090f89c5e09d1085f1a021620ded32511c1fe4ccaadc2dd71b04283f1578c314b57a54bea94a679bfef26f0686a028b2d55e01a6f0654e459bf6016dadffb30acb0c340c1049e124a2e4a71c53bffa460f4d0e578124c02eaba167d25ad481d0c75dd1f15802987bc1a831b311b084004b16266585a04ad5354a12e817bdc4a25ae54aa22b25824222b8fbaface984f14bf4c07f126580aaeb22a1101973b9d4ea3d128b642cd165396b82bece7feeb94252d1def0071a2c87a0e25ce85fd7f055be4314e9f18260bca2f47b8f2b4a8d82af07f2e263ce6e2b33afbccf5ecc7ae4448ffd329832b0096c6a09d942edfc165a551219f42d0c2810e0b791aff02e40b877285cccb9598ec5f3278b39291265305b9cf09a5d1f0eacf17b944e4bdfd61691bc2da3aad0c93f53aa0f564cad6f7858fe660d3407d90f18b96c398d263f844a4d4c5c9e113f5c3c398628f2a3e17ea790a5a8ce62c4bb182001c61fc3a180d674e7549367b3687f42a3284f3a72658d6533c42f1a4788e9bf4b91210d5b006834ec8949d100c8b2577924310f26027a222a1f6eab50c2b77cc3d3a1c997269727ddb7f9aa872dd33ac758055fe13c139832b54e6955439149e152aaa88284d570c2b5c5668bc3d3dced5af43eea8cd1269f0ed2ef0cff5b30eccfce17658e01160466a19a05880c9beb089e7a04a3b6dae2b8660a45a1ef26d5775a07afc900000200049444154f05406584809ee638c81a92a8456b0215833cc6633b538c58c247b2a87cf296897f02c81dac218cc451ae75266b6d6186321cc420107335a68f443184573843e0ec515764b9035986ec5717c7070006d1d789909cc2015d7dcd26aac92a6c9703882985cab551b8d26161ba9d103910a83a47d92bdd6890347c901ceb2d7ce94231765018b281c031407691df332869d5b1e013a39dc1411635881d15b782187bca888832fed156051007f01ee8852517f5542640c6ec72be955cc188a046312337b8ea63f5797c2f65f5a0e1a9f4b1642db87f4d3bf8680be992bc4b706ce06f15eae4504d0a032390ca02898f0d26e9f03acb09272cc85fcd812ea7730f8e43854ee5e75d4058bf6f97c0ecd3ad62dd76ab5f1783c180c602701e3753c0b699819b301d65a955ce0183564522abfcce7b2582430cd9f4c26711cb75aad6eb7ab1382e44545fd8ab01895fd01e066b3d9cb972febf5faeeee2e164b623100123bbfb52711c186be56ab6d6f6f13d1783c1a0c06d64644dd66b3e5fd70a541e9710822a804634ca8050bb555fedbf35d4b4a18d65ad18f9640b932e5f728503e6f587a24bfde28e8b77aba8c570b06654e21fadc12b0f0333c0f0816f44aaa4370ce65e60dc38944635697c27585d039a071e6b45aaac3d25601aaa539fcac318b993fdce3288a188b01a11bd2ae88e5d06a8d157a74d1341a135262c00d6a8b0a6418f1bee994074064bfdf0754211ff8de832105d621c3b5031c78212533b75a2d104309b49ebef540b705b37b8b0e13c711115d5f5fbf79733e9d4e014940c3f3f3f3ededed83830358e1e7be54c54c66c6e3d4a0bfd1681c1d1d81128a086630c90bb38acb986f7df6ec59abd56ab73bed766b3eef1091b551bdded0d59dcea500166b8d12101d35f492b591884b92c4b915230b2026c39574c4a13c60651a983fa28131ca803d1909730e8f9e6d15f917790a430a3e592073fa459b01cb04f318b97942fde91c8149313b632854c633434c4bb18bb973c02320a66376ccabfd80393708f89209c54375524459f508821a51bb9fb3b98388bc2bc30a4901f9921511884244047b2bad7b18971bbfcc45e10c25ae2a761d6d427f525aa9cedb1cabc32cb00c159400856a08c6cc6a9efeead52b63ccdede5eabd5c28264acd4815da8122b9829dcdcdce03d1b8d46689c95240966093ce62e1916be428ddd5fbc78212277eedcd9dada9a4ea7979797b06edfddddc5472549a2eb1cbd9386d5c2403c88fd3c06d64eea0af02449c803967ad79acd66e7e7e73ffef863abd5dadbdbef745a9d4e1755005b2db5262122ec651bc7b1b54ba763699a2c1609724681636a02996b64ee18c697a55936ae305e0af3bcdae56ecfb0c27c54400b9a138ee8d5e2d5e11965b63e5463347e4d58396ed7288d219234b5605b696a436d17f45ccc196f0d9ac078974a4ab814a134946a3075f63004afcdbdf5af0adade8361052d66d9f8d411a80b5cc484650a2871ce0d0603acc5035f80dac85a0b4b2ee87d6ab51a6428d828c06409f5648ce9743aed76db39a70e1e66b319e2b7b7b7f11409442de7dc6c365b2c16f0e2b0b5b5d5ed7667b319d458709205eb8a7ebfffead5abc16000e375e71d30cc6633601cc84ead566b361bcd66338a2c440f638cb5c6394992643c1e4d2653889c4747473b3b3bf0d8050f108bc5a2dfeff7fb7d586c844aaec56281459144d4ebf576777761ead5e974eedcb9331a8dbefbeebb7ebf0fa7cc44b4b5b5b5b7b7678c79f3e6cdd3a74f5fbe7c8985df49326b365bcc2ce28cb1711ce1bbc6e331164b56abb5adadadddddbd46a3b1582caeaeaedebc7983f7198d46a3d1687777f7abafbe3a383840b596eaf8c3dacfc5e8d88709b22cb3401a954c9dce7212653894569fe44542d5ac61f592035be4e5baa2159332060d756515a1c254e9b114aa3c1862b02c012c1151fec5bc52c66b20ca2cc7d11bb5713aef678602ee9ce304c5a043f86d3ae95f551091f7b6c3528ea0def8a22882d911a418f272194609f4c08b8b0bf63e4861694944c01de400abd19d9d9d4aa5029282eee49c83460c59e9b21e0016f4faa1a64cfc0c66afd7ebf7fb93c964329960c10df929bf376fdebc79f3c61853abd560c83a1e8f9324a9542ad0ca4f2693d168747575359bcd40916ab5dac1c141a3d18ca24a9a26ce4127c54452afd7b7b6b6d2f40246a7474747fbfbfb30258da2081eb55ebf7e7d797909ca09f6042a371c0eb1b6b1d1686029f5e9e9e97ffcc77fdcbb77eff0f0703a9dfeee77bf3b3b3b7bf8f061b7db85e92c9cd59c9f9fc399579aa6af5fbf8ee3a8dd6e1bc3699ac2ebfccb972ffff8c73f8e46a3c3c3c35aad46c4878747f57a238ee3c160f0e2c58b172f5ecc66b34aa5727a7afae4c993070f1e3c7cf8b0d96cc2854ece9f8f563dbd0db0720c4b45c222c3d27b7d8c72b1d5223e4879e225592f3c6618530edac4e30d652129f753f32904243322692ed2e34e9a032f570836d80eaea8c30a9764a82fa61cdbca9d2bd2850e1e24cb55dfb523ff2585f76058b9db255833acf29ae294ae4006ae4136c1d29676bb2d22f0b8c2cc70a0ee9cbbb9b981a578bbdd9ecd6617171793c9049c4b7d138fc76318b8572a15789842bc0483301859bbddbe7bf72e9cd8cc66b3d3d3d346a3d16ab5b6b6b680713040478be976bba051f0b4678cb9b8b8b8b8b8e8f7fb607f22827710a1288a9dc3d8b8d42f74bbdd478f3ed9d9d985c3afefbefbaed3e9f47a3d3cabdfefbf79f3a6dfef63dd62b86e693c1e8fc7e3344de188f9e8e8a8d3e92449727d7dbdb5b585120633dddddd3d3a3a42a1bd7efd1a0e2a0e0e0e0683411cc7c7c7c7dbdb3bb3d9743c9ea0abc7719c24295686dfbb77cf39777afab2dfefcf66b3d16804f434c61c1c1c743a9dd96cf6fdf7dfe34decd22db54ef3a9a0b7d25eadd15529932a07b542fa7c64f16a685c222542e28acd49c16c9d826efc5e8045c189781d16f9636699740ead7231266b26aa9c8b02cb89db00963146457809786258687fb5b02522efc4b0b4c828cbf6cdd2c07745bcc95b5186fc169e82b150193de4e6e666381c763a9d838303f8937af2e40984140a6c1a202742eba415cfcc90836081a97a680e14f940340016f8d47c3eef743a272727bbbbbb30ce04b3830face974cacc878787fbfbfb575757cf9e3dbbbaba1211589c625661b15818c35114a569e47b0881cd55abb5838383e974faecd9b39f7efa693e9f1f1e1e7efef9e7878787d82c274992bb77ef82ec60e1d1c5c5c5ebd7afebf53a0ae1fefdfb77eedc71ceb5dbed76bb0d500398eeeeeefeeddffeedc3870fcfcfcfbffefaeb172f5ec471fcc9279f341a0dec33f49bdffca6dd6e3d7efcddebd753cc871a639bcde6ddbbf78e8e8ebefaea7f5d5f5f0f8723f43aac289acd668787875f7ef9e5fefe7ebbdd3e3f3faf56ab711c19b39c13c831aca0d2f310462bc0e28025add55b858d4aa12704bb5cc3d346c5ccce893e25074c0a58da148d31488f687a1b606513a8a25d02c05ae64f192b2d49532792aa600838d339c49061a98aa308649b01cbf8e5b15aa4ae4c8d152a46ffaac23b31ac62c3c55d6046582da89eb0b40e20ad4089ab9ed4a1bb21bf72109d736f6f0f2a6aec09864e7b7c7cec9cab56abc3e1f0ececcc390702727474e49c833075767696240936b351ff30a860a8c01a8dc6f6f6366c175ebf7e0d49d31b28ad8ce955addeebf5b6b7b7e1308b99efddbb777070c0ccaf5ebd027ef9e2426930bc1b4f26a3d168dc6c36f7f6f6a032ffe1871f5ebd7a05ff13d085596b5badd6f1f171a3d18044767575b5582cc01fb7b6b67abd1e26077446556409d9f8eabb77ef4551f4c30f3f0c8743203894868d46e3e8e84ea351ffe9a79f50e0c618b816a856abd0f1a193a08866b3196645ebf5fac1c1c1f1f1f1c5c505b635f3b6f26c2d2ff7b7f5f50eda85fadf085814a60718414b55da96724016c688f73311c673c6437406b0c2fc45c4bf2a608888566ed7cae0a9340638b83af720658824589a03b99503c012e78c021617dccb843c2b100f9717fdfaf63c60850c00e015bef9ba9e7b9b0efe171044e4960c8bcb02e2d58f283459e160826586502b82a4a013ea3a15e017d452a3d1086e1b743d30dcbf38e7a6d3e9d9d9d99b376f98f9f0f0b0d7ebc169fa7c3e7ff3e6cde9e9699aa6c7c7c7954a458d836125301e8fcfcfcfe13a666b6b0b1e5d5ebf7e0d8d72086da872dc3e9d4e61680ae9f5e1c38777efde252278ce811e8d08d68cd61853a9c4cec968347afefc05dce01c1d1df57a3d630cf44700a07abd2e22ea21faecececa79f7ebababac28400a635e15b55fcec2134faecd75a0e0683ebebabc160001555ad5643210386fafd7e9a26900103435c49d364369b625a83998c59ae19c22640308cd0d9005d5114c7d162b19661a1f9d00a8c947423a578a8ca9071a503b707acd2781129c618c358252381268bb29a750ec4c97508450508cb05573663e89cb336140f53e7c4ff958884aade0a5d8ce0843931c6a4a941c57af39e12c0626f0c81acf4fd39e013c5defd170c5eccfc512cdd6124098cd0e5c1681910bb804a2a651011b4d1501589c8e9e9e9d9d919dee4e8e808f1f02405af09699ac2798ba2db783cc60c20a44213b855223fe30bc385d168f4c30f3f80828d4623630c2607144f1163adbdb9b9b9b9b979f1e2c5703864e6070f1e38e746a3d1f7df7f0f91106e02432a47de24328a62f8e7fae69b6f5ebe7c8909044c6b62bae0d34f3fbdbaba829777dd32bad3e9c0c905a43f7055668e22db6c369b4de8e6dc743abdb8b8f8ed6f7ffbf2e5cbd168349fcf1e3d7a74e7ce51a3d1984ea7878787c3e1cd6f7ffbdb76bbe55c0aacf4255fd59c31062c162933f77abdcf3efb0cdec47ef8e187376fdefce10f7ff8e9a79f7676765ce00ebf383e05c7fcaaa630a5675e44019059bbd2526553aae5faf22ee046d85029034fab9c156288d85a55dbebd20209f450ab95e13980a295864b44de025839a8c22facc809b45ac639d1c5cf12b8002c15034dd67014271874bcf370f884c807a48756cbfdd59b958ac847b17437c6603b1cd879ebec12f447d0c5607b7722d2ad719819fdfffcfcfcf5ebd7a3d1a8d16840afdce974e03ae6f5ebd7fd7edf5abbb5b5757878b8b3b363adedf7fb676767171717101befddbb07c7c7b096c25ba1fab189ceab57af5ebe7c092fc9b039d8dedededede06c99acd66e05fde47e0e2fcfc62381c3e78f0e0fefdfb83c1000054a9548e8e8e1e3d7a04a32a1798cf4033b2b5b545442f5ebc78fefcf9d75f7f1dc771afd73b3a3a3a3a3a8202aed7eb3d7bf6ecf1e3c7cf9f3f27a2bb77ef420305b38966b3a96eb644a4d56adeb97374707058ab2d4d222e2f2fbffffefb8b8b7363ccc9c9c9af7ef525e46266faecb34f1f3f7efcd34f4f9acde6679f7dbab5b50f3c851d43a3514739349bcdc3c3a3e9745eafd7f7f6f68e8f8f5fbd7af5fbdffffedb6fbf15911f7ef8e1f2f272676747674e42a65606582b90ca350c5a39f0d3019fbd38a96995a915f32c07ac8043e1aecc9c20afd62d860c4bbca12c7b3c2a356e502bf9db861ccf52600a8faab612bf885d258fe068955b05baad546d0cad4d315b650c1b93eaee07086a5fad467c0ac3b93e4b01e7a2bf509ef57e0c2b876e68a368dcd0c5a0109919e64ea057908974fb060cf891df20079e8ba1a941bf454ca3d110916ab5bab3b3b3bdbd0de3296606ee0092f6f7f7b1630da6b7c27743e65096e34d9acd26acb1a06eeb743a8bc502760c954aa5dd6eefeeeec39c1d284344dbdbdbd8bc6b6b6b4b77b14e033f36e2cd47a127025244510450e8f57a10722b95cacecece6834c22dfbfbfbf03b5aafd767b379b55a41b224593073a7d3c1b617d56a05fb09b5dbad3b770ef7f7f745687f7f1fa5319d4eeaf5fae1e1419224954a5cad56f7f6f6b6b6b6209bc7719ca62e499246a36e8ca9d56a272727f3f9a2dd6e031f61f0f1f4e95358811d1c1c3c7cf8107b0549c12c880258f1f26611c23838928a8d3e12cc88c34614b0a70c6031af3a95a60ef7dfc801960819a3aaf710a4149248bbb30738bd770558444b8b53a8d8c19b8a5065569b56903773cf011619a32085b902e75c8a91ce39e78f4eb557fa870e84bba0ccf20c2b2f18e68613d47baec396f6eebf48d81291b732ac70202d1d6c15e98908148682a91f9838a4de95682e9fc562618cc126a3e22db64404b37560672282311fc22011014ac4bb70511b167d61e53e88dfd9d9817d00f36af28b88a228827b2cfd844aa5727474b8b7b74b4490012b95ca975f7ef9d9679fb1d7ca3bef1e4785263dd66ab5e3e363101f1bb897c19b3373a3d1f8e28b2f3efbec33f16607f84c74365a4e69a5c62cbfbdd56ac571648cd9dfdf6b361ffcf33ffff3fdfbf72793c9629130d368341491388ea2a8f9d9679f7ef2c9230c12b917d3328fa2e8f0f008f297ae6583da5e44f6f6f64e4e4e7ef5ab5f6d6d6da5694244c84a2b4b963a6c550c2f2126548a17008b680558aa3ecf5f0d1a0c51005e1b7a1a07da28a20cb489f7dc4005ff331c90a82cd821863cb200b06081b5f4632379317089412292a62677d51f433b2c388f331a1ff22c63d83993a6c639ab4c2b4da1ed5aeab98c31d6a6d6bbf045d049430ec4430fbbab5565b701a6bf00f062e6f7d661e530ce055bdd04834fc60359d10a117c444ddea1c14105837c61b68bfda2045558aa0adf054674c537c43be0add08d0137ba83bc4ec639976285308cf5013149924491857a8e8830e399667d045250d3d65a504818a0a9bb5409bc80a92b77ecb8036863365e5a59d685bac977cef57abdbff99bffa7d56a83af351a8dd168b4582c207a031031074a44a1cf55c562f1663e51141b63209dcce7f36ab5faf0e1c366b30955e0d1d1d1fefe1eb47b00b5829697020ccc41552812e6b6025adee9a7fcd48310f897513308f1b6efe04aea6a2a6c6bb98697ab020556590989e580452b238955c766163fab289e58b10216889bba540e1eb7b4532fc29606ad0ef1e2a109cc1a8095a126cb1836c661d8656fa9a323716995e8989deb11a56db5b4bf6c4ef03f1fdecab0ca1b69418da5312202fd5f69322d0be32795d025442494c0b53e141ab49e3467dd268b3d77e060e0b5c126146891ba4b2b7b2f57412fd225dce4737648a338a5a67ac6af58d4373181c12a11c1f81e8b5a9cf7a9804bba300052adbe217918f5df2828002466e6fdfdbd9d9d6dc4604e436469acafc592fabd3c2868a0e10706fe6021ce3033c14df3975f7e292bbbdfa57217060da5755d6c0f618c312c520e583ea5099b9b093c0285af1d369862ccbac005ce4501cbe082ba9d03cf2dd9ab226254175f34e042003059bf16ad08580a5b3a6eb9824d96f336f1384f92d4b9344da3344de1e45d19969ee7948ccab65002457d96b68410acc3a6521afeecc08b99730ceb3d5e31842a188ea3027413e65cd3a1a0b0b4bc42f4d1783fcbcb2a585150c4dac973fd41c9851f333355a529cdcab1147917029af1eaf5c47b50c83d5d3f47bc6d847e48a8e3b081272f244e036f168a7d5a96e173c5d3524cb3027675915038cc8a67b25a4aebaa89889c2395bcc03d418a416fd3348110e4312be44d9a077316ca287b8d0b577245973bcfd56031bdaf1d7e6b0be5ac3048c10d521003f5e99ee6ac443f221231480ed8a10260d1d2c94c66a3b0d0a3439aea79de819f4298314b85469a3a6340fc8da75996283566b5c7b0c296090207c6a514f86e5258dc505c7f7690f49620b2816195b6aa62dbd2d28191811a58111164ba5c1ba76c7b3759afca5afa4484f534509c87da74cee25ac8bf28e839619e1c2cf45728a1405d42decad12c2dd743afa18668398ab2e780e1fb13858648143e45d3284869bcac5cd6e00dc1adc823e02a67110129cb9567093014804ccf7d392beeacdc87633d262d195f44ab2d0ecb1fa1c55bbcba219ed70056b1cab40073dd896fcdb034b7dc60cc05fea5e95db0346f3de7ca01d672d4cce9b664c5add2c0887415547ba5f149028615f961436709d3348dc0b9108f23b40139868573cc95eb062ea187c8b0e4b3d05c5eaafc67272432bfaf0e6ba53a451163264ebf1fe7d8264bd7cdb09780c2ae48815ca301ae1a86c3e1d5d555abd5ea743a711c83f15aef1b3ee884ab16af31e180a354c564179a65bbc98afdf1528762a2c8c2510991d115ddcc1c9edb6033ae50db6dbd577809dc31e3b978b762b15b6ba26839472105e28676a9c4305f8d592841c8293b00533966245ea5c2dee11792e17a36e7fc43ca808995be7d2060859fbfeec6d210e6a6859c832ac90a89ebd27b7bae0c4889f7d297fbcc00b6c8fb78201193032c11a8d8573a2f453d257a6821ce39282198970a5665585a4790ee736c4b5f8abda4b28e6785e5b911b6fe4c504be4363aacd2a014006805d370488210b3b1dc1f16d5ec2704156e2890e9b4dad026a06e17919b9b9bd7af5fcfe773ec84aa2975d21d2b69540d147a8cc28c9e8880f4b1177f142cfc57a8a74d27e2d23449d3a576bc52a9586bac35449ca6ab7d2bc8af31c2732108abe8aa2408c3a09a17a8e4856fc4d0874f8ea208b302ec1d66a95e03778593155a62d9bac81b1f14e3fd55d6b68e2a2e664e997e98b9a291c5e6e15563797191b2ac278cd14ca80cce7231efd4633800a030071da87247bda514d428ab52506e229e8b1579966fcc4cb45c7b180a68457d96094c49ad8dc0a73cc3729e61d9509f65ad5d2c8c5fe790615b61d3c0a7a9413c65b1271cffb457969628059ec5fee702f38759baafc836d612022630ad369d4ed55814cb03adb570bc89ceccccb042c25660ba56066c564446a3d1cdcd4d9224d8d259f538d0a01311dcb300cb66b359bfdfc7aa175857203d66d38808465e58a663b27a2ee49624e970381c8d46d85ab5d56a610f6a66331c8eaeafafb11119045e787420a2c160707373039481b128ac5b61d904a689f78435064a06ae506104d86834767676b7b7b7e6f3f9c5c5f9f5f5b51a1c6c6f6fefefef63facf65e77d72308468f43bde148cc2106585eb1cc414cfc3c8e26b14555ab406bcf4def0840b8095bbfaae80159068a62c60e92b699ee2c57cc98a81bc06b034c35cc9e47010ff63810e110394f45ecfad562b0a8318c34b1c34982b444ca8fd802c91a6aa4581b9c96afda6d632e444a5ed52a0e75a08ef51d4d9f0a786b3350c6b7da30cdf4ca0fdb1d660221f9d135ca35eafc38214fa72f54d8c9b6131806523cc0c570ad86414ab0bc997b2736e3c1e5f5e5ec2bbd3743abdbabac2d23c64beb5b5b5b3b3638c190c062f5fbe84bf145d6ca88321321c0c06070707980d90a5f1e7f2d39c93d96c767ddd3f3f3f1f8d463013dddbdbdbd9d9b136babebe7efaf4e9cdcd8dced1a4695aad56a7d3e9d3a74f0783811275d80aa469fae2c58b7ebfcf7ed6b2d56aedeeee1e1f1fb7dbedc160f0fdf7dfbf79f306b6b2bd5e0f4abac1a0fffdf7df9f9e9e8239b65a2d6beddede1ea862e8d33d572fb76758c6c07bd70aaac80bb6c56c793d78ad6b1b61ca0dc7d266567aaeac6db3f23817bc3c4521a628f1d1a7e43a30af87a73046f185b2b242518705b1d1794b77bdaa6c2be0592b7f01d626ceb9284a559f858e0086e5799649d308ed308a922449160b0b1127491228b58cb1605e0b1f389812d5935c5187b01e5cd5fa5d15f2ff04db622e655821ef2804c99ec034c1b6db6d2c8e61e67ebf3f9d4ec129e02e1dcc2b49929b9b1b088ff078055352887e49926c6d6d811c8134a90b6398bf2b2ac16cddf9a9143c0513945114b5dbed9d9d9dd96c76757565ad85ff0311b9b8b8004660937a9038f2ddc339994e67d7d7d7af5ebdbabebe8ea2783299309b6ab55aadd6b0749199b1728588b0973d1c6639e7eedcb9831dadf7f6f6daedf68b172fbefffefbf3f373bf529ab6b6b660fb9e24c99b376fbefdf6db7ebf7f7272b2b3b3d3e9743a9d76a552b9b8b8fcfaeb6f5ebf7e7572727272720c8b7ca01565553365caa99250065826074a94e5595480a175e79b7f961e43ca435960cab5cae255dc78fb4e529a3e54e4f3fb021605aad2b00971819a89006d1d519eb879c022afd5b26aed80abd61a6827f02cb7b4e333b083f7dc8a60131f6aafc22a2e3613a8f3f593df360cbc0728c99f92671518166707bad226150a1d2811634cb3d9a856ab100cb1a2103bbe405f0eb8190e87b8c4cced761b4640f02280c10118876537d65a10abededed070f1eececec5c5f5fc38516c425220a35416031ed76fbce9d3b7b7b7b2f5fbe54b77677efde75cefdfef7bf7ff3e60d3cc6c0af83f14ee24564341af5fbfdd1688c16389fcf87c3d1cdcdcd683406698fe3787b7bfbcb2fbf04d10325c1c0b5bdbdfdd5575fedeeeec213711cc73ffef8e3d9d9d9d5d5d5f1f131c01143a5aa3040127776760e0f0fdbed76a3d104dcc31969afd73b3c3cc24a2035c4cde1cb6d5855a9d23d387231256d04acdc6b145b4e69644e778e04b94171dd792ef377ed4021e8e462380b58fa56b454ab2f65b7904985f7e61856ee5cd996c684be1c8c59edea5cd46779b60586856d5c60536d9573854c1f3151946158910f3a810859073c2b7893d5e48f72c3a01c967fb729e7421cff09908bf9bdd61266da659aa6ce2d775580e6086eaae0d3324992bdbdbd5aad4644d3e914950d6b72448a48a7d3b97fff3e6e87b60b8b07c1ce700e490a6260a7d3b977ef1e110d0603ac04821a1ee264a7d3e9743a203ecc5cafd77bbd1e96dd2c160bf89e0ffb27acc92f2f2f9f3e7d6a8cf9fcf3cf9d73706e076b4c38f92322d882d76ab5972f5fc2090c3c49d4eb75f8fc3b3b3b5b2c1650514d2693adadad5ffffad7bbbbbb50ae31f36432d9d9d9b97fffbe884ca7d35eaf371a8d2e2ecee7f3f9a79f7e7a7c7cfc4ffff44fd3e964777777369b7df7dd77575757bffef5afb1e01133d9543690ac03a90f042c2a801779d40831940b5856fa338cdc0c4f1f2b6c00beb73ed704d627b91cf4fd437a45d94ecb6fd3f187782dc19477a0cf62556584f19cb5a481f7a1e06d1913c1c50a5531990ad618e167668b05e74b59ea9628c1bcc2b88db2da7b8402c3a26c3b2b6bf499c19c889c4b67b3799aba385efaedec743add6ef7f9f3e7979797588eabbe2b21b241c32522b3d98c88b6b7b7e13a6e341a9d9d9d0d0603f86257bb126cf32722b55a6d6767076b7421e5b9e512dfa58200ea7c7888c72780cea875984e53ea4cb09a505c5e5e1e1e1e7ef6d967f57afda79f7e7af5ea951f1badf52e7140124f4f4f9d73bae52211c1f1d6ab57af3031ea9cdbdada3a3e3efef5af7f7de7ce9df3f3f3e7cf9f4f2613228ae3f8e1c387474747979797af5ebd7afaf4e9c5c5f97cbe383939b97ffffecece161ef1db3164e8b30000200049444154dffedfafbffee3bd7bf7befcf24b7576b84e122ccc6767e2b3e7a1bc50925e02a50fad01acf018b2a7309978630e0afa40aea58519be6bcc6d0267053a3c7d1dc3caa5cf3d37c7b07293360839dd563190675e2658c4139e87f6eef05763ad752e458bf29aac15c342d3b5364953e55689f2ac523b78e3d71ba6c1feace449a57eb8ffde950133fec7f510a973a8ade19d38d0bb54e9c7d897308aa2249961a307a8d289c85a0be7c55ac7ca4bb1f382d637ac22c6e3312858afd7abd7ebceb976bb7d78789824c993274fa047c7d638cc7c71714144400d6c0003f302c877e8db50811111d45b9019f13e216347fb68b55a506f9f9d9d1963aeaeae207842cc1491d168747979f9bbdffd4e44e6f3391cb61c1c1c6002e1f7bfff3d3e04b384272727cc6cad850a1fce1edaed363c4c5c5f5f5f5e5e9e9e9ec265f3c1c1e1ddbb776bb5da70387cf5ead5e9e969bfdf1f8f47c7c7c7f7efdf87838a70107e5fc0529bfb72b4429dae9334e96d7a744d19f6f6f7039acdeded9dd2ebf9bbbe897e48f8519215304db0a888b3d01cc25348b5b8c0b05cd618226052d8288c9ccbf82665afa5b2566db20ce60afd006f43c062af4050cb67c4a8796a88a739bc16ef77ec4f833eef11ca1816c2fac8ccddbc34bfae10d170b8984c2698ad8fe3b8dbedc217b0091613b0dfde0aeb4b408e6e6e6e4e4f4f078341ad56dbdfdfc7541a1101a49e3d7b767a7a3a9d4e1f3c78b0bbbb6b8c393f3f3f3f3f37c6c09d56abd5d2d5337068035736dbdbdbba3c08baf9bdbd3d6885c206847ba1357ffdfaf5b7df7e8b094d6cb7054f0fb55a6d3e9f3f7dfaf4f1e3c7711cc3a1282ed5ebf51f7ffcf1c993278bc5626767078e5fb065ce0f3ffcf0f5d75fc369fd679f7d064ddc7038fcfefbefbff9e69bd3d3d35aadf6e9a79ffedddffddda3478f44e4bffeebbffecffff9ff1e3f7e5ca954bff8e2f3dffce63777efde8da2082a3335c8a202f3bdc5b9c1fc2073296b2e99f5db70356c0f14f45bbdaa5ddd142c3fa9801deba0e45d216673e002b7e28d0c4bd398aca5121780acb4c48a325718a3ac8a3d2343230c8f5eab65bc3e6bc9bf708ca215db8aa2244d139d374f92e5bc217458e013d090ea3916de63989760b9981e3d84653c557096b11679962f43fa93e9dd993fcc0e4b875683b97cf67a68dd6f42e5352d5f753e457e7881df2b226a369b3b3b3b10067567f9f1782c2220655048e9047fbbddc67e5cd65ab80984e92611351a8dc3c34318b2c26aaed3e9e027aad6bff9b225359b4dd858a0a69bcde6f6f636000ea6b0070707f01c1f45d1fefe3e68205e03daa5c562b1bbbb8b784c5c42c3052f865b5b5bed765b1d63f57a3d22ea76bb8f1e3d3a3939e976bb83c10d50f2e4e4a4d96c7efae9a78f1e3d82920bab9a15f1e92d8065d7c49b1c60690928ac84a09303ac30326c3ec51b8bc9de23bc2b997a6b26b76fe1c5e76ef8642a4379e051887461198628a915410576e33500e2f5596a3fa13e705673886058605b605ed6bbf160ef0a0933f8cab6f42b148942d84a0b2e49d65547a16043b5d7470f6b1856b10ec2d6ab3383f82d2244124571b7dbed76bbc815652481f5908e2d70c0048d3baec2f7b1788701bae619c5b7bfbfbfb7b7c7cc40228875784fd54941cc547f5bccac3f8d5fe30e653c334323a0354abe32409d0e0e0ea0ed32c6a86dbab5166c0ee00e3b297c69bd5e7ff4e8d183070f28b080c7eabc7bf7eeddb97307f13055c3d2c8478f1e3d7cf810ef808fbabcbc14a19393e3a3a3432cc280307b73734344b55a6db330189eaf03ac9ca23dac65539885a4b70196f637caf6c6b0fd149bdbed2337c47f48e0b7312ccaf6612acc0c729655852c2c5762aae72a4e5084cc4b1faa0f529dba2c1dda2c571d7a0d57a43ccbdae2bce1f21caefd4386a54b4d54276b8cc1220df5b6543a25aa75adc4aac8b6b480892045fe892652983fdca73b82b5b6528943b15917426b65c0393238515816ba6c85fd4681a81ed4139462126c670fe594b236c9ba4fd1f205a6909f5706ca84251e363e7d434507e4acf9833342f506d5beaae4b17b0d1a01545ae05cf051054842bc5a6fe876b3f045a39c14449288b0a9c77c3e8fe30aa095cb42915bad635e1b008b02ca16368d4c33d928c771015c6e4f91420e12fefcf036b9e171c563d878723d96d67c4e0eef10c2520dbf2b57f8b9afa6a0e7678b42440c2d4d048c3129b3c1869845ad963129e607898897abf799fc2ada10371513d9fb834fb31e7443004dfdded4e1378625f0df18d6302c7dad5c7117ef0f34b8cbad3bb404151470631445e05fcc6cbd8f504d09f310849c7610cb12432aab33801c0c65144c0218ef268dbd2652f97948a4295b7fecb7b627bf7499b28a18804ed8b191b3dea5f9606473ce018c72df0b6b09554801498d31ce09400aad2d8e2b5e827b0b18f9f3bcea7d1dccf1ad012b778b04737fda827231b91c36c7142f157bf2470cbcd1c24063941ce9b7e7ce4bf32ca6e42c36e5e25de02e4de50f8d57b95244ac450c7c3f609de96a7b2a6b13e7a0b75ad96725c9d21ade9895ed3b7bf110edcd7a2fbec6db6729bd082701a830e9a935958b0c8ecc6c88a0055b5bcbef55811f836189c87cbe1099e90743d88156481fa5dd581fa7350a145754e20026d478444147bc9b40a42c0e74b9f3b07d84cf2d4de3bc93d25c83c31ba6de775a78355dfa5d5bbe12bcc54b4197a9cf757ead865274edf37eee39b216ee95193729d83173169880356bf5565c08b4068cc292096b2d4c1016885ea542fbe30fe0472194fc29429143e5e2c30eb9ee586c3feb1e5784b075655eccc43f8e98b1e9211119b5cff20c4b88d839ebf917fb713a3146b55a9679b95f9c8a84a58d240758bada5f023357da389c00adf059fe28e477452a25aaef14320cabb4400be7f9642292248bd96cbe58ccf5838d31d84b221c7e5d76b17898ad0ddcce50b69f843a42ca7a0d0d752814b0a1b026721fac97424d81e6ac05aa00a131218ce67437b8341e8f6f6e6e607706d7ef6ee9feb864d59eb248935d5e1f02d3baf82c78e5db5ce979ae488bd59d2b76ce221467512c5798c556551ab921fe36797e94c06be60ab96039b939652e4d31bde6b381e422a4c1eee869e0dc517916055c8cfc7c22dcfe85ba2d3d7a7d5612454b7dd66201cbac08dc4a670f815c98b3521fb936b005e3028451415246281231ff13ffbbd094f4036bf0fd1816582ed1d229f07c3c9e2c1673eb9dbae832141bb87052215101088f560d3d7922c6810062bc0909051d3ed7a6918f09367dd08fd2f4da1a42466303b77cece183829156df4df3d74b0a1cd56ad539777d7dfde4c9132c39ea76bb50e1e99b1befc7993da0eb138b10b30e92de11b0f2ce0bb5dcf86d804501b894128ae2d5754d28bcf74fc79b6e1f6ec3a4d6c56f3e86215792b70961a30d8b57f3d4e11cc97cb11305eb8168e95f1b6b0c8d5fde9f115c74b4c6736de0c42df1fb1b72c10e96b3a28cbe4308a6fe6ad87e96c7b0b4f9fd072491b7eab00a21934064694a3e994c9d4ba063463af44f15b2484b6e39119ba681d7274525d507b107141b78c243b62a46e5980e744648000d77ce6b95f88541186498595d32626610d379e1cc0b0cbb146131a5a20bad31210015c09b376fbef9e69bededed7bf7eec1810452c2190e0464f596556482b76755c5941bfa80d659587f9ca500948530addcb0a273319be38b69728deead77bd5386ef746f0e5c7205b2995515395438126c4e537c56ae6a148f42cec5810e01575db0c8d12cddf9af36b3b0d63897b18337c6581b25cb9d0d977aab9c3e8b7dc704cfd279436332ae6f4284ca3129f62cccc32e39876ac247b131f94d5e398371b7afc05b30acb23156df78a9c4592c9622a13aabb3d6622dcb643211918a0fe8e1d80e1eb3638d46a3dd6eb7db6d661e0c06979797699a621ecd04666f807f5839b55a2dd87f92276544747d7d0d0b752c1b4cd314c69f4484d740b1c2e8bcd56a31339c9a8ec7e3344d6bb55ab3d9841f88c964a21b23c2f515fc7621fd68349a4ea7954a656b6b0bebfeaeafaf5fbc78f1ead5ab7ebf0f6f10d81cb0dfef63136966ae56abdd6e77676707be2828f0bc5a0a349b8f6f05a65ca3cf9deb71c390beb9e1bc6353cb34a7f7b8eb63855c1fa37767521ff7585a2f61cdea6b6bb9852088a09223f31229783957c322c49c7ab695d7a870d9d8a933e30a4f2a7e5250f569616b4eda389ce4528a37a37fd7eadb64e91ec66b04e29857fa60630c91807760632ee51d70c0c2ccdd6e17fb39635131fcb58304c1d11dd621f6fb7d6c447c707080fda6d86b7c506aba2e1a1bb22a6972cef5fbfdc78f1fcf66b34ea7a3af8dcddcb1f3335cdc586b0f0f0f21dc9d9d9d3d7ffe1c8eab3a9d4eceaf29e0f2f2f2f2d1a347c7c7c7b3d9ecd9b3675830389fcfadb5373737d3e9b4d96cc28d5f922483c1e0d9b367bbbbbbd6dac964f2e38f3ff6fb7d3cd718737c7c5cad5661fd2f7e779f902b853aafdbc3d62d012b54a551965098ac3690dee69eb8b4c1dcb2cdbd35e5edb37ad750fcf075c75cfae2d10433894a3d4a71274c1f86d0e2a7987fee768d2c322c3d3a6f19eff55058301845518af1dbf84d39d10b307f1deab3700e994041ca785f6fe1670642685e2e06b686ac30acd340f27d9f918b3f649650ab96fd821beb37cbf19b182798d7472f85dde66030180c06d65a189763e1f1f9f939ccd68165d56a153eb046a3d168349acfe7f03c339d4ee10b7032994052634f5544643e9fdfdcdca469bab3b3038736cd66334992f3f3f31f7ffc713c1e634f63630c36611691f1780c47a9bd5e6f7b7b7b341abd79f3268ee3c3c343c0ebebd7af9f3f7fde6ab5eedcb933994c9e3d7b361a8deedcb9d36c3667b3d9643279fefc390cdcf7f6f65ebc78017f5bdd6e6f3e9fbf78f1e2ebafbfbebebe6eb55a6a8a013f13263086be8daeea163ccb149b7aaed11787c1e225cd22ace8ff594ef47183ca329ce5297f6a2655fa26a56972b8a631b9b7cdd59abfba3c8243305b9104dd04a06382cd9c7278c7c178494489df284cd3e01121b1d2172b7e48f0ce78bdb525c0ef303e499e6185c514c66455b94b8c30c1141b04b77abd0e9ea29d4afdbddcb973677b7b7b3e9f434a8233036cddfef8f1e3b3b3b37ebfbfb7b787f5c6bbbbbb9f7cf249a3d1383f3f7ff9f2e5743addd9d9b973e7ce603078f1e2853a6028562a1cd73c78f0e0e0e000ef301c0e6f6e6e20668288a9d9272aa0d3e9b4dbed870f1feeecec7cfbedb7af5ebd6a341a9f7efae9679f7d369bcdfeeddffeed77bffb1d76039ccd66e7e7e7cd66f3abafbe7af8f0e1e5e5e56f7ffbdbc78f1f773a9d870f1f1a637efae9a7adadad7ff8877f383e3e7efaf4e9d9d9d9d9d919fccfc0d66c3e9f8b108632f29e1e8a0c2b3c5fa7b15a0f588697bb0f942bdaa930bb4a05554bae0d14c36d1ad9bb34c4ffa6907ba5d2c2e100c46f790c8dfb7250589a5b3106a1c8d18ac75cad5160b7a50c0bfb4b1b639c2363ac78336cbbf4e86042b6a50bcb42ce857943dd94578fb83d8cc92de8516e6582197f11c6ee6741cced4912fbbfe5bdb7d261d11a8ca460be008005dee482ad22aad56ad307224a92643c1ef77abd5eaf77787888c935b8f414bf3a47fd918ec763f4552880a0ea567731e1c78b9f5badd56a5b5b5bfbfbfb2050588c5dabd5baddeec3870f9324b9baba828b64b09e4aa5d26ab5767676f6f6f69e3d7b061cec76bb47474793c9a45aadc28d0400ebeaeaaad168dcb973e7f3cf3f7ff9f2e51ffef007b8be825a4d84daedf6c3870fb6b6b69e3c79329bcddaedd683070fbef8e28bd96c767a7ada6834ac5db551e559a53054e45394dd3d2c1b8457ae63caa5123d86239b7680b033fc3551aa5c58c77afe74ac6addd5b06ac298b7064db9816189404924dabb437aa1faacd263f808ec87100a80880f2707739fc64b8fa93678b715e210e55557b86f7d8585170b0cab586ad9e2a000ed322f81fbb0cd8cb5a0a399e7a67e171966c64cd97c3e8744265e256ffc2a769011a87e50108854a13aecd8e47504fa9e3a1ac07eb7d96c1e1d1d9d9c9c7cf1c51790d430c187718688e028753a9daaa51c9c7fc2db9f4e4a62c6d01833994caeafaf217e42fec5c48a319c24c96834aa562b44b4b5d56b34ea9f7efae9af7ffdebd168f45ffff55f2252af37748a13bab91c1bd7ef2aeab3c250d05b91072cacd260e6bc41502853d01a9e956b2dc59862b84d9a3f93c05980d0732e60fa3b1d8bdcaac8bf36a7dff0262155c97d0b624219cd18f65375a45bb4626c563a0fb6c5debe47d9961ec339446b2d7a017b5d676eeda1096612c97740ce8229118928c6215e1422946facabb40067983fdcd21d3815454b535a5a62ed12d4a1db367e9d0a66eef055cf9f3f7ff3e60d3ee3e4e4646f6f0f1962b121e086fcca61949488c0ce0daa7dcaa27b1445b55a0dfa7ee02311351a8ddddd5d40e4f9f9b90b1c631111c8202680c187f512f4655114c1cb8d736e6f6fefabafbe9a4ea77ff8c31f7efcf1474c1afcea57bf7af4e89131a6d1683c7cf8603299fcfbbffffbc9c949bd5efbf4d34f2e2e2ee6f3f9b367cf9c73b55aadd56a753aed6a35d6699a906df17a86a531da527378edcf9735c0ab2db932c3a056592ee6e7134222f0a760551f9da329f90ae12c57fb14a01b338b776d1c56b4f34b744d76c67003dbe2f5faacacb57d1eb028bbb428db0e33b581fff0ceb7acbe4dfb12664b2717b71440a228aa562bc6b0b5368a2c330a888db17008035306c5f5bdbdbd5eaf777e7e7e7676361a8deaf5fac1c1c19d3b77b6b6b6d2348de3189ee0611e52a954a08cc7c269fc141138bd0a5f8b999bcda67abc429161e611057d7676767a7a1a45d1dededefefe3e5cdfc0fd0b1e114551abd53a3a3a6a341a7a57b7dbbd7bf76eafd773ce1d1d1dfde33ffee3e3c78f9f3c79727171d16c363ffffcf3bff99bbf393a3a1271fbfbfb7ffff77fff9ffff99f7ffce31f67b3d9fffedfff7c7878f0c73ffef1db6fbffbeebbef1a8dc683070fe03ca75eaf1319b58347b0813f90db0056816195375fca8ecce1d55c2dbf35a6b46dbc35cd9f552816d17fc331e453ebb45448e30a0b5d8bfc2b540eb017f9c266800f25bff2598512655b3a6308da15da67810d60e4feffd97bd3e6388e244dd83d22b3ee0b55000a3740821425526a75b7d4d76876766dcddeb5fdbe7f76e6c3aecd768fa9a76da5115b6cf1a60810f751f79d47c4fbe1a90c44651540e8e81e7637dc68c9429e9191114f3ceee1e18edf66de10665f11cd18da56ad18cf0aa31c88b35078aca5e273e07f1459cc4a2d3cf30bfe5086859941d7758410aeeb448045b0b823638d613d4404f4f17d1f46ab6c368b90ca6055085700cd0b1e5508ea8230c1f8938810970a05309585885798a0343c594a99cfe7c3281322d66023ee0233cfcdcd799e87cc113a8a2e0f274f581c11e31451b41289c4f2f2f2683442061da0dbd2d2522e97eff5ba994c6663636330e83313a25f65b3d9d5d5d54e07f9abb38b8bd54aa5924aa5982fbc607896327885987639734fac27d8f2f7c9a7a6e55de04ddf6f1bfbe806aa6cb1299261917a32a6b39e8c7863bcae68ca92a52da5d5f45f8efc7e68d2b625c65eace3d00e31c08a56b9c44de156b3e4ab2c59d6f9df351e56bcab48295d77acf749294dae73bc0374377b58c0440322bb1b7f7104302022b83e8868898ced1a8ebb21f49d71cfe5c862857be272631bd2910bfbfcfc3c808f8890260337817e2aa25834c67f15a96e8410f01ac5a31134a25aad96cbe520ca814a44fd7e9f88110bebfefdfb77eedc01b564e68d8d8d6ab50ab7e34c260be08b6c4ce31666a8225f5b25240bef280e58e31d34095b7c099cf114b44dcb75cef9ab90e94af80b6fafb676d125ac0abfcdca369e646164350065adf037c62f7bac8a61906db1329ccbee5cb63d0b433ed4c318db62cb0c6f4aa22dbddb2ec0b4d078a99fb0f65cfa057f28c312629ccfdde8cfb0a118d089199bc05111d55346c9b28c7dca2ca6b16e7ea175c35f14f7b1bf8d8e6c58204a36baa36613890458150e197e0b5dd556d7e17467ee6f025ac1ea0f35b352a920c01e4cf541102412495c5e2c1633994c1806c3e108841189bcc230ec767bc3e190ac3ca657dba766722eb2e0c3de63be20860abb5aa6e1e6ef996dbd0b5ce93adbe9d242a69bc4652d842d5b12fa54ac5f98666628986972a6735d06a0f62ca1b2a23c9b72ca6815ad4d0f67765bfbd5a6774e7dbd59d11aae4638733e5d74066dc81e8f4dbf13d63e9a6404315d5a5b53fb06628da2645e72fa7d4434538bce4fd67cad3d86e0b6781c4d5a7662606df05444bebf768d439f272280948cd6c733b3e3602012862a72142275341a71b4e8324ac93b16d03a94645a31bc1ab0ec3d6232ce044d82d465bf677edc2b8efe0dc8747f7ea7b6d3fccb3e7ad97e9aea953a5215cd8bdb5a1ebc79789225d99e5951939e88eb60b818740be09df18037f799863c6de9ad36edb2a1134523222218da60bf27229e8c5dcafc9d189639cdd41a8d3b39acec86848ecb61cf9edae58eae0ae1ccc69331188c61d27e226e32180c1a8d0611c19900f1b68ce828828ff9f0e62df18e002cdb5aeffb3e3251e333c0650c4aa8b910f7c4742745f8eb791e78a215409588b452e3a8d0b07c31f3c1c1c1c9c9692693b975eb3634d0d8ea56c8b4023853622d75ba81fe3db3a7ebc8bbc09e7e2cfe35fd5ed3f86523578c6d89c9e51664f930d394cdc16c31d69af0706cf9beeb4905169dce266b344911ecdb4e924861de298658170ccbee009749ec9c085f50262da5865266680816e5e472399b0ad96f4e539ab6dd694d2dc084a49442527b662e97cb488a63eb8fa6360d3e4ef30ec39e50d148f3d3e974068301ecf18b8b8b668e320625f8c6983d69341aad562b9d4e2f2f2f6381911ac789bf58598a17ffeaabaffecffff9d7c5c5c59595d552a9d4ed7661d24279cc80166b25d32035b3f5d86d91a786df2bbedd5bf7ff4dca6515f8ce6e6d5bd565fe5cf61e1b0bcc9735bf6d50a3497b1618165a38c801d896bd3591b3ec7946117972d94ccdd6fb0c71313b0d96d18531dea856c21e88998dd325e244337f3f1b967dbeef079ee72915baae934aa5e1021a862192bf63b2cc188fc6858a142e836286bf982f61800cbfa17f8d46a36eb74b44d96c56476ef14a29b31ac04e77681c3e632e6d1475ef7ebf5fafd74f4f4f91eb01739783c1a05aad22c3b3b995b66c61994c462955afd79f3f7f3e3737b7b0b090482447a32133a7d329f38e523ad96c560839188cdebc79033a6922db2026bdb9ff3430bd15b0628dd226bfe6d3f095dafddfa7bc0bfce8cfbab547a0e95644165130f4caf60bd5b32601cc9d0de4d9111d629e5c388ade77991b476c69f4e5121f4df535a335b0650f3247230353e87923442f60167038504af5fb7dc469a0c8926dc28389c8da0dcc426736ef0f180253634beb46023183532026b085c31c6ecf6e181493516c2c6636f9100d076c341af57a3d0882b9b9b952a9d46ab54e4e4eb074b1582cc2037e341ae1fe7098705dd7f3bcb3b3b33ffde94f8b8b8b77efdead542aa8cca83001a24af87e904c3a580d4e44fd7e1feb28e1446a6201daadca20f5cca67619609916661f32fbed7175fa43ff5dc96595f98e6f2fe359d3cd4345211ccc8736d752b476d5fc6943468c6d990b0d0c89c91080c66f7e5a3d3498e54499a5ec44d3a6e43a6ec7e00b9a65c1eef81cfc2366163fc22c210a6d7cf6b1ae058ee622f294450c290322894422934967b339666eb59ab55a5d6b8d100b524ae434443f475268600112d923941533034ddaedb6c9029fcd66e7e6e6b2d96cbfdf6f341a6649a752aa50282c2e2e1ac0d25a23a9bdd6ba582c6e6f6f2f2e2e3e7efcf8f9f3e7b833c2d7743a9d76bbdded768510a9542a9fcfe3056bb5dae1e161b3d9fcfaebafe1ea45a4cfce868d4613b1b4128964abd55e5cac221c58b3d9fce69b6fdaedb6e779b95c6e737313b9a3651491d5b4bf18845d0158b6986b63fb6732afbf67f94f6740df7b7bd9bbd862f5ff0b95e2b25664e3117aa58e4c4e26ea2f4f461f328022ac3c2f06b0c87209303a930d2f7601ecc247ea170e5dda5475cc86650c4064f50afb85637bb4158b0ad1f84094b0e4586b8d15ce42885eaf57abd5e06fa9a398c8f97c2e9148a652c97abdfef4e95321e4caca32c2f2e572398a30bedd6e9f9e9e8222d56ab54ea78373c230ec743a8d46a356abc1434a29954c2611e60141205aad56269341f5c199debca68ea61153a954a954aa56abd56af5e0e0c0f058f35e070707f57a1d9c2e954a21d129a0b95eaf7ffbedb7d56a757d7dbddfef7dfbedb76767e7528ae170840fe9fb7eabd542b6fa172f5e00430b8582e779b76edd42782cb2e6196250650fad364bb7bf8eddaaec966188d54c80fbfb94cbd0ffaf686b1b2bed6663148bcb9a0d4d5a45a6c5740adbbb0ab384660ed1741f58af8c0dcb5c651896c12fe32420acb9459ac253a844cc8c8270ccb10b9f8f48fc103f2c0358ccdc683486c321ccd5581bac94829e2584e8743a676767bd5e0f2c31325aa94aa5924a2583c01f0c06d96c167144c1c510330b999f7bbd1e8cf750ee302b371c0e91f72108826c369b4ea7cfcfcf6bb51a02d1f8be0f6684db22ee8db170a1e4f04a0d82e0f4f4f4c99327a7a7a7b55a0d91adf052ccdcebf5f6f6f64e4e4ea00902b6eedfbf5f2e9711306b6969697979b9582c9e9c1cbf7efddaf7837bf7de4ba7b3beef2d2c2c148b457872a552a9e5e5e5e5e5e576bbdd6ab55ebd7a25a55c5c5c4470547b10b3b7570cadd34763dff18652cd9477812bfd6558986115b19de6104d4e7ce14ce3a90031d661db3b94886cfdc96658068c8c910b48649e6eca6317cc94475b32ebe35d6ec39a7ef399e770149e9823ff4f22c2e215f86ac23a3e180c5aad16e2f071940f22d26c299148168bc56ab57aebd62dd7754e4e4e5bad16eec051a88a4aa5b2bebede683460b1761c07f1f39452a552697575b5542a3d7ffefcd9b36750c1606c2a97cbb76edd5a5a5a42d09bd8dc1fcc64081ff8ead52b24945f5d5ddddadacae57230f0773a9d7ebf0f23dad9d9d97038bc77ef1e82f995cbe55c2ef7d9679ffdfad7bf1e0e874f9e3c69b73b8b8b8bbff9cd6fb6b66eb5dbed42a190c9645ebe7c99cbe5969696fedb7ffb6fefbffffedededee79f7fbeb3b393cbe560ea52519821d39e668297fd21626c8b2d3e65b7cbe9df7fe7f267e53e7ff9ade995b16d8c6d99436296975fac72cc706ee086a2e414d28af700abae21536c2564c56d8daf83712b35311e4cf1ec879a62d87388172c2c2a2c1b867505cf328766367d14229d4e239e67ad5643089fcc3f5c00002000494441542aa4f902318147389c00d2e9f46834eaf77b304b01bf13894426932d168b52ca76bb035b8fc9964c4458d8ec384ea3d140793ccf0360a552a9c5c5c54aa5727878188621a26168ad89743a9da9542a4b4b4b26005694f8ef22910fb44266cee572d56a756b6b6b7d7d3d9bcd1e1e1e6291f3dadada83070f84105f7ef9e5d3a74f61844aa55278c73b77ee6c6e6e9e9d9df9bedfe974d6d6d6b6b7ef6c6f6f1f1d1d01b85bad16d4c0f5f57544a448a552dd6eb7dd6edb41204d139cae677bfff4701adb33f39c1b31f22ef0a0bf24db327bc4252e7e348977b63d4b47de94b895e159142111ceb1e7164dcf3299eed81a5f8d37bc9e9c858cd1ae08cb88e26c495f8b614d8b7d09dea7502840f53b3c3cf47d3f93c9643219e324c5ccc9641219658ac562afd73d39391e0c8644e3d20701c2c9f85a5f4492367e091485ac0284e1d1f62423d443d054e3a7aa9436b58c30d51cad52342643ad75a9545a5b5bab56ab4b4b4b483a5f2c168510b55aedc58b178944e2d34f3ffde8a38f98d9f7fdf3f373f3d960ed02ffc28003d7f67ebfdf6c36f7f7f7a1aed6eb759c8fe2c1cc6f3bacd9ae58a655d95f34b6b5bf224f72ab9927df8891cb6ae9af746bdbb362b4c83ec7bcbb3d6368ee4353639bb60c0e986c373e0a4484a66e261c395a5d883df62ca159e2661e8d085478aeb167692b27d6148ce252018a85e7fdd059429014c053b7dbc5845a3a9d464018a8b2854261696929954af6fbbd2008c230c0f2e07c7e3cdf974c26859086714077435c877c3e0f8d1246f47abd8e59c242a1904c26bbddee68347af5ea552a95aad71be572796161c1715c5c8e2811c6a3c2f67b408d208273b55addd8d8585e5e4638537cad7c3e0f5b58bfdf3f3c3c6466a4b700b7aa56ab9f7cf249b3d9fce28b2f7abd1ed2f37cf0c107ccfc873ffce1e1c3879d4e07514c2b950a82348c21d9f753a954b95c069d3470338d327c890d8b2d0e659f60b7daeffd35ffe6e55de03e7fe1ed1543d71568687a8ae32864e2d1d15a1188cdb028a266c604e6baae012373ab3014c6a534b67687ac061c155e6b0d3556447ceb1a36ac18eccd14432e52a914fcb06005874316112d2c2ce472b946a3beb7f766381ca652e96ab58adc0de8c0954aa5582c00c811e88e99612f771cc7f7fd66b3b9bbbbdbe9748410b064cfcfcf3373ad563b3838d8dfdf0fc310ee02ebebeb707d5a5c5c4c2693a9d4385d98552fe3fa4da7d3a5d25c10f850188d2ee9fbbe10727b7b7b65657567e7f5b367cfbff9e61bc7717abd5eb95c9e9f9f17426c6f6fe7f3f97ffff77f7ffcf8f1f1f1f12f7ff9cbadadad7c3effe2c58bafbffebadbed2e2e2eaeadad6d6f6fc3dc864461524ac4fff27d7f717111aa285923a1dd5c8ce8a9f941b33ff6156cb67523d3724de6f2d7be8d8d7fb13dd33fecca9939da69ad8460a5285ace31e19365660c79d20fcbd03d33cf1804a1c120e3e34e5620408a67e22166c12c388aecfe23f86199ce2384c8e7f3781984c76366a542224e26938944c2f73d30ac6432994ea7d3e98c109228c8e5f2ae9b48a733b80f02b38828d93d2cee44043b7a3a9dae542ad0dd30c7078f8a20f0cbe5cacaca72a15010823399cccacab2e338a954426b6dbe1111318f59613a9d5e58a804418888a6d66c9d1682f3f9d2fc7c250c835aade6fb9ee338e572797ebeb2b9b985a8f31b1b1bb55aadd56a6145e1c2c202b00cfe16ababab4b4b4b982445b8e7542a851f6b6b6b854201af607bcc52641a30156b0f957685c7f69ba676c3adde2affe97ce72fb07deb9b1a3dd1480cc894423883b151055708a1c2709c1d396aa81a58a6f545c464224da47ddf0dc3718a62223bbeab14829875188e3353c41816452d19cd5908a0159cb02c86654a1c7b8de9b7b22199236a00ae885c0ccc8c6547e634e02bc2da69ad1c671c2566381c12513e9f2f168bc06b224a2693c6a312951b5d380e6e85007b50f452a9d4fafa7ab55a1582b036080b6972b94c2e971142b86ec2cc874869588c66e6743a95c9a4b466ac97420cc288063ba3d1200cfdb9b9e26f7ef3ab2008a41c2fa9492693e974a6dbed4a29b7b6b616171781d4c836f8e0c183ededed304acbaa94ca66b31f7ef8214cfb4110241289959595e5e565e0afc97e68be996d98b0ebdce6f676f3d29607d6f417bc115b7e742ef32e6fed4632eda565f688c9c004262ea6111d455b86ad495c8448d6521233f9bea428b158180642103305811f860191012ce33fa1619211620c64a66076801a5bdf64c1c442316b26a2ebd9b0de7a021e8980563652a2caa26856895c2e2fa56426639393d2c155b8822223346c4fb80f56f0c1cbc1bc0cf01b2a64a954725d84c70fc33014621c1b0bdf0b65b7bedfb8cc524ad775984d3c2fe02fc32e0faf0bd89b00a0f8724a854a6998ba1074141c0ad0033f7b2925a6027cdf47984066c61c25b442340bd0663d6565e0abc8f9ec9d37dcea9af22e30a0bf24cfba4e85f0a4d024f60921b426ad45a4cd8d97d686a1c33c0e0e03454a2985b8cc5a6b3839eab1417dcc1230c9c4ac23ce75b1c8772643d45a0bc1420a12589a2398f9fbcc124e8b6101f6543d33db06196dad2a221a674c33806dd797e981e6cf300c8111c27252076c2ba57cdf530aa97ac6da75f4f21cc1f9188c880853159897a371a843066c71140cc756d1cd0246a28b908466a2240a77359ed68473bc795f98cf8ccb8999f434eebf31b4c285b1f9638a9894198bf4ac39c41b79ab7c0f9ef2b7b49de659d3443eea9b4c0410611aaf40d65a0b785ed378f6301482b52629432292d267a62018f73ea4c8a2a86b234a6610001604422e47bf290c15f3c5ea451b078423580a1692781c48ee87dab0ec6b6d67b0693dd9ccd6459ad778b6ce78d3daf86df764387498e85a340edc434298a5d1da861b735bfbfd4d2d4c22232172985d5fb6101140564a87f922e6068e2aa50058d8af2d572f1989d6daa4ffc173b1eed2bc2f456605f3214c95c6069c9935ff3d06d5bf677917b8cfbbb39d2951efb0b7e86b63ba20a3087fcce3a60b6e653763c7b960583435ee72c43c88486b65c03156421da5f9a1b1779726fa8e7e58b1ce3f7dc886c9e9ab84b5f8db1c8fc1aa7d1f1bfbec3be0082a148f925218d081189614bbd6ec1156e81fc3aa0cc3329815ed81f218e75fd28a142aad2c38a61e682a31bd4dc269d66068359aef3084dec85be5bb56e9dfe4d66e5ad39c2baa28fb37fe87495a5b68a2a4bc98efc32c21b6ccec795e105cc47a8a7507b654252212020598616293d291520a66a54993d6443f94617d5731f515db79c5f9f685531ddb062f8a9d699f3f0d013132c5578aa184937bde2ef65b5cf19a462e6355df7bc0bc115bde055ef32eb0aa2bce99ee3b3441118c373cacd5643cdac3703c5788c931134089287e7fad2f466ead8939d49a8842bb24c66c22859452ea705cec6b31ac99e7c4faed65575ddd9967febefe99b1aabcec721b5c0c1b8a01d6250c0b7be08c1e3f932793744d3fe50a3e35bdc7dee29b5d7d0e7d171cbc117a07d8cdbbb39dec3e97feb67f101156ec98fa544a1009adb134054909c72a612291b0d3af5ab384e33284a1d98375888c73cc25663d8994d2910e314921e93286a5af7490fdcbcbcc6ab5fe7c0b60c56426a58af6c4899745c1ae4bc76695f0e2b7d9da720545fa8126891bb1e55de038efc2d6ae8d58cdc41ae774ebb54d2bb044c19e1586c8a81a2aa5304b88f80a4a5dac34d4176aa08127dc16ce9213e90e99590a396658cc4821782d4f77f37bfa1dcc3bcfecabd377bbac2ea677be150a9899c6e9c526ec5cb6d8dcc76c63f62961ad5bc45fc6ac2e044be9460ceb5a76abd873cd77b2b73c2bfe3a5f323f78cded8dbc55be5fc5fe0d6fc71d69aae3983da6de78126588286acc44a469ec87050726ad3581615164f40ac38920596c8573a0f1a4e4c442148e26dfc6362c2105b39042fc9059c2d855336f12bbf935e980b92a767e6cffb44ce1d55b24c6980c9f8a665ec700f59d2895fdd54da92e2bf0a4621fff10df6fd8bc912be45d6037efcef6ad756537639a8577529a794311f9bb878e133a8ee3b88e52a1d65a6978608dd546837dd1a20e78d55ba9bd005e5a874a09965073488d03258f19d677822d7372ac67c684a7c0dbec9feed23405f957ef9f42ff8b3f66b22a8a288c6da59ade3a8e83b3c4d45c61ec9e5758af66b2a758f9f5942f55ac4abfebf646de2adfaf62ff4eb6b15e36fda7fd83a2f0587481802aca2aa895d28944c20f7c2cbe21262c9a1653d3e551c7015313e8a3ccc42c486b0e43c152221fe8d88bfc6d9eeea6179185ca6f653a7f11b1806a56bdbf5526e9d505b1b266037f90ad4a4da606d1965cf64a760d7f8fed8dbc55de055ef36e6ea76b2926d3addd6c8560785212111c1591835529c4d552cca49589083891dd5e8f3da2b5d6a49426e393a51431c39788f8a2fb5c9a35e78aaf1e2b746ce7cc97b46f3bddc367eea729189ab5079842c692650e598a5edc73ca18ad6cbb55341be8f0a4bf7bccf78a2ff1b7d253b381b8ef3493fa336d6fe4adf297f9107fd55bc834d98f88cf440ba70bff70adb556ca11626c2f775cc7715ca53491a6687d0f8b5069c582c94a5ac1e35584e31b068118ffd68a8560211dc7134262891dcf8c8735adbbfe8803f85b7bd7b43e655f1bab59226d55650c01795ac40c313b2534412218b3665c7e854c57daf7931f6b90bc9199f22e709977793b595704cd0a7f91952530ea5fb379962159514487318762c14a2bc14c7abc4cc5a01ec26d6aad9931c693d68a5809e1388e23a4640e8998344d302c035e97753f1b2fe81ae833f3f2e9df979d43b35087268602fb1c32a8843f6d3b14473e1d530c8b015552c2dfdd61a6ab19d665d631bec40e15abba997b7ef8f646de2a3f6e85ff0d6f4df7222266f36f42c4d8331e17013994410f441f88bcd3c7444c29c944a1407e1d49c4113f0822c061212e82980b110a81e008ae7494c092209b614db3adeb4b0ce3de8a7d575c6befbfe24c3de995cb7ce121c21386f00b6f06be96d0f54fa6e8035fb3de502df647a63fcff0782333e55d6031effef6921a9b38647702ab23902159524aa924454147b5d6639f78624d1a365e2242ec2d0475883cb6c6162e66868f91e3bad20b85109a2c3fac2b1afd5bcfb90e2ac5de73f29d67ecb49f7b494d318f91e8e2374f5a9a84187b9e596c4bc27f3d625804ee656b88362fb36df3b1ad8d98d1807329938abdc275eaea7b9c7c2337f2c3c5ee5f5a73b4337688226b0c314b662d25402d544a39523a8ea3b4c2b0ac9422ad43939682b5104a690096026011d94b76c629765848c7715dc791d2112cf8fb31ac69f6c491724411a845f36e17fba76f72754f36606182ba7014600cfb1197d9dc6aa6c4d896c12f04e1721c072a21b3804a68a702bb42a60b2cac387c28921d00fb8788f922a6aa6ff8d48dfc5965ba8145ed3ad661197b6243b5bd3e848c1f839414455b515a0b5661a849dbf19127728b8d3d4b85701c092241cc9a69c62ce13494c4facc5b65ea96b3cfa1290e15fb1d0308f33b021f61ec82e690adcdd9162bb66c588e637ec06e05457abc73fa56b6158c2c17120394c2f2008e153ef66ac2f27437a74d43124dc1933d9698abec33635f8a6641db0dd8ddc8f525d6ffa61adbc5d1a8411acaa2a4231d476a2d750449da4ac84ae3f64c82c7fef1cc242542e98d670fb556112ff1a490c44cd30ceb6a99799ab6c4a65426a6558c77d8ef8cab62c0647e83a4986052aeeb22471622bbfbbed7eb755dd7c96673c0608a20c636844f297482883ccf1f0e3d66721c1780e5388eeb26714e229148a7d33648cd2ca1b022f331731004bd5eafdbedfabe8f9c66886a1f437f13b2ddfc19839b9841414f46e03659ce449400eeb2cf67eaf6ad5ff0466e64a644ad65627ed0086067cab035c3ce23c7e1ce496b05b72122ad14398e26cd5a692184264dc4911fd6d8639e48488928e72e91204dfc5d3ddd6d5e60f620ad2b11211d03484410f8e85dc96422914830cbc9179b18ea67421802fe8d4623842a26a26eb7dbebf58ac5622291ec743af57aa350c8e572d964326147011491039b85576346a5b5f2bca0dfef0d87a3300c1122d971643a9dc966b328432e9743ee1ffc39add8da438d1e0723a57ebf7f7070f0e6cd9b5eaf877cb1885b6fbfe6f46f9b6d99df766dd888834487c8e871d9c7329fd2be334db2b01bb991eb0bac543465c3327b88b4358d08d22005432d9436b628a595d24a8d014b2bcd24983854a12662020bc34d42a51473201d37910c1c37c1ec3009f13db2e6c4ced75a0741d0ed76910939954a2125d97038ecf5bacc9ccfe7a5445ef80b5ffe1804d83dd630238a921e1291945229351c0e7bbd5e3a9dd65a799ed7e9b45d771c8034a63189282c9fa95fc771847006837ea7d3edf5ba4a294c4020467b32a94c66535c883c1a50a44da40b13e22716f5586bdd6ab5f6f7f76bb59a49226b10cd44f611e3850b8a2c024816cf8a697fd8391c0edbedf6e9e969bbdd4ea5522b2b2be572d966587635dab79d86ad1bb991ef2a5a33458911f4c45c219aa8b66d32686b319e25a5c482426625a56426ad15b3564862a1352b0e958ae613492b224d600c8ee3388e2ba423c6be9162b6a7bbade8d19445c65655b4d6beeff77a3d040b9e9b9b13420441301a0d3b9d0e45b44b6b4c5e6a43850ca05014045958136de8f0308d8b285c3a47c18885a028529530f5a494f27d1f9194813e626cb037f8257d3f68b75b83c12093c964b3996c368777ca66b3c562114a9ce17750fac230b443b09b7ca848a203c33f323c9f9f9f2712890f3ef860737333954ae14293743ab2f15fe49b34908dd7a7082b63b4a8dbedbe7cf9f2e9d3a79d4e6779793997cbcdcdcdc5781945dc2a4aed710197484662dbe66ef0eb46be8b70a412c650421b60a0f12fc016dc11d891525f8cc4269782026009a19522568a34f1d8dd61dc9895224de484a1108474568e94423a2c1dbe225ac35bed23e637fab6943208824ea7138560c74a484208737475cff34d1055a4ea437266d8aa4cd7721c279148241209c0016c72d0dd1c4702a38ceddc7442cff3f068a48c965222d10e380756de1069dff7915e0cd59ac96433990c52049a170163eaf7fba3d108590891245108e179de6834f23c4f0891cbe57cdf775db7dbed2247613e9f2722bcd17038ec743add6e1775954aa50a8542a150d05a0f06836eb7ab94ca66b3f97cbed7ebd5eb75d77591fc35c6160dfe7a9e874c3cb1558a4600d9dd6eb7dfef67329972b9ec79def9f9b9d67a7e7e1e3aef0d5addc88f22d17c574c78a6603f4812c2886aada5d4cc04d77707b38717b95475180aa51c814933c7918ec342289a354b689549ebcb9d0fb435078954cf4110349bcd6eb79b4c261d47168b45645bc07d3c6fd4edf690ea0ac084a38944024c6430180008a4944852afb51e8d46beef673269a896b0f3a1c836ef532a1c0e87e8cf894402e911a594c964322265e31503aeeb2aa5d0ab0783c1d2d252b15824a27abd3e1a8da494b95c2e91489c9e9eeeeded8d46a3f9f9f9a5a52522c2f983c100e0cbcc9d4e075af07038ecf7fbc3e1d0f3bc6fbffd1659577bbdeee1e11132ad2aa5a494d56a15451a0e87c7c7279d4ebb542aadadadb5dbeddddd37d96c666e6e0e086ed6856aad0b85c2bd7bf792c9e4ab57afac150f17ad832cb35a1004676767878787c562d1719ce170b8b3b32384401a6d9a32f3dfc88dbc4d38c6ad386201cc4ce33856765f1c071010e37f0250416383afc38c9c83e03a4c5a2bc55a6b96ac590bc9c45a48d6a4c250313b8ee33a6e423a098470b88a615dfd1eda3212837d8c46a3e170381a8d882891c8673229684f6061380a1f28d0aee17088947f6043beef03b39088d0f094e170e8385247cb2369dc3fc793652883e7f9bd5eafd3e90c06834422e1791e54d16c360b65d0d4329e856bc1c5d2e9341eddebf54cfe1bdc4d0801e84ca7d38d46636f6fafdd6e1b9b773a9d2e954a0b0b0b28702a9524621cedf7fb8d46abdd6e13512e97ebf7fbed76db7164b95c761c474a914ea73ccfebf7fbfbfbfbbeef27126e2693612bf3b3f90408deb8bebede6eb7f15ef64062ab96d8092ae7fbfe9b376fc23094522255e20d54ddc8f792abe60a8dd175d639766f356e3dcc2cb486d1598c199660a53585e468c5a4957268ac57a9c8943236a790cdb0a6ed5657bf875d0e74332871beef73e4f4845ca1264f97d63a954acdcdcdc14e0ffb5722122094e779b95cae5c2e23b73b8dcdd5d2805484e517937f611882fd002ec330741c67301880cd458b04a5310f65329962b198cbe50a8542a954ca64329d4ec78d0467a6d3e9c5c5c562b178efdebdf9f9792965b3d93c3f3f6f369b854201298cc2304ca5928944627979b9d7eb1d1d1de572b9070f1ecccdcd9d9fd70683bee3380b0b0b1b1beb8d46e3f9f3e7806c3c3a93c9f4fbc3376f760f0e0eb3d9f4ddbb774ba5722a9534f30c317b13f450e8ad93c3d9c56712422493c9b5b5b59595959d9d9d172f5eb8ae7bfffe7d40aa6d25bc911bf981725943422f8de9401ccd15820d1091521aee0b5a6b311e80496bc5d1621dadc2502821dc4422e13ae895524ac78931a9eb00d6f42518c96184461e79c791c6e20b81e5c5719c4c26034392e77948b868accee9743a170933839dd90533c5030ca207f67afd7abd1686e1c2c202a81c59a91cedb9423d8ebb2af3f9fcfcfc3cd08a887abd1e5b0161b4d6aeeb160a85f9f9f9c5c5c5743a4d44502499797575b5542a8d46a34ea7834c21994c269bcd4a2932990cd041ebd3e170c04ca552b1549a83d51f4631664ea5d2440a9caedd6e26934e2e97cd663350365594a7db08aa02463ab65cc360b4c29b1ac31f337b9ee7795ea7d3817a0beb153cda6ee4467e1499692c224218f771379d1e59cd564ad6fac2e9215a57a888484a45046f21867bb71042477cedc2abd3fcd093165f9a34c0eb49076bfb108df3bfbb7a9c45c34ce15fdcdff43133bb6fb445b85c160a85743a6d000eb88b1f3c95ce0b6c6830e8b7dbed62b1b8b9b9994824eaf57abbdd06961b8dc97864595516add08cb430f350fb4fdff70d6025128942a170fffefda5a5a54ea7f3e6cd9b66b3198e0549547dcf1bb9aeabb522d24a859ee711a9e1708884afcce370b1f57a7d67e775bd5e03476b369b52ca64326d9068dac5548f538487608ed00d47a351bd5e87720d7db3d3e9ecefef9f9e9e160a854c2603737eb15804ccdd288637f2238aeda535e60434de853dc69760da11474769be0cba457b801e210b25a5ebb80e8ffd4e899035e7adc59a0958060ee0cb0e3d339148c081426b85611f36a3643289d5d84a29cc240a21e0b2944824a0098219a1df1b6313e6fbd2e9542a950c82b4effb994c269d4e673219989652a9542e979f9b9b83b727d4a25c2e974c26cd0944944c26a574b2d96cb15808430563793299c4ac5c369b1d0e8778974c26834bf0dbac58ac56abf7efdfb77dee4ba552a150989b9b43518bc5622e97751cc1cce572653018b4dbed5eafb3bbbbd3ebf53399f4fc7c65616121994c8c46c36eb7abb55a5aaae6f30521b8d7eb3a8eb3b292832fbe94177eb64aa976bbdd6c368159ad560bb809b33aec7166dd621886a3d1683018140a85adad2d66eef57aed763b9fcfc3b8a6ffbe3db34c1bbed9fe485b53b111d19952bf629f604c8374dc2bc2e83732caee4e963310d1d898e6c4c65b9bc599e75d31261b1f4b702be37e897981442241c489443291480821b5264cf603ad60ca91520e8743d775316d5fafd731a5954e675c3791c964138964269386e70111c1c32097cb856108909a9fafb8aed3e9744e4e4e7cdf9752c24a552c161389849921c4e463a934a7b50696251209d40ed00d3638b8929b12269349bce9eaea6ab1583c3e3eded9d969b7dbc96472797979737313fc2b9d4e2f2d5573b92c10a450286a1d4a294f4f4fcfcfcf85907373736b6b6b95ca4218facd663308fca5a5a552692e9dce361ab58383835eaf37b386fbfdfecececed1d11100ebfcfc7c30182c2c2c388e83170421cd64325aeb7ebf1f8661a552c966b3954aa5d7eb1d1c1c044160afc4b647b9bf37f9cfeede7fb35b661bb03491ad1b5e3436034f7afc5b30c7fda8b5d62c380c5da1949b4824129e741c33ef782d8635fdd54d41e14205c31054a368d24a6badc3102912c7e12330f80353a094816a8d46a3d1681404018c2fa3d1d0f77df8408561a035691dc263d32ca603236bb55a98ec0b82a0dfef371a0dcff360230318799e17e1a92384c48398b9d56a8d46a376bb0dfc86412d0802d7753195098311260de00901aad5eff70f0f0fcfcfcfb3d92c542d6044ad56d35a0f87dee1e191eb26a5948341afdfefb75aad76bb934c26d3e974afd7673e83d3561886a552299d1e85a16eb5daed76bbdbeda552e96432c551ca6f8069ad563b3838e8743aa04870ad80f51d8fee76bba83722c2b700b16db7db7004c37b55ab55cc997ed7cf7d2337f23601271a372d87c230089928108190e3d5fe760c86c8313304442845411068d28e74945241106aada49061180ae93a08b7ec8009719c615d7ff88566014f454ccc092b322745b3a14288e17000139ab16a69ad7bbdde7038344ba30d95d35a8f469ed6ed5eaf27251c3da4e308c771f1e69d4ea7d168a00c4208383ac1bd1eb8a994eaf57a6118d6ebf56432e938aeeb3acc324252168263a5350bca6d7b3645fcd14cdb31f3703804b393529e9f9ff7fb7d8a0c7348557476764ee3b54461100483c180883c2f383d3d6b365b98390d8240297d7676ee382ec071341a6a4ded761be106b5e53202e2a9b5c61c02e0acd96cf67abdfdfd7d8c19666e11d5689cce300600da9452dbdbdb3706ac1bf9f30b5a9f43cc52484de3c413642561d59a840060e1b724d28284520a0b09b5d601872ca4108eeb241c272184a3f59536acabc1cb1c42278f0ddd30701b9ac7cc440cdf741373cad895010ad80f5ac1cc441abe6772569a7840898e961fbaae0b87f568390e6166addfeffb7e001e6a664699391652da9e7ad36625c284ff8800db322b72b4d6707450e3d08870915761a822cf0372c6816c9c300c1a8d26263d4dc983200c82b10b08f6d46a3ea0475bb1386095a3285403101913ac36caeb68ed373e0d4acb7ce1178613cc0482984ce9fa3db6dfa7255bf2431e7db37d07b6e60b92525a88719405221586aadfeffbfe280c9594528d27a0e0c5ae89488521b1cdb6380843ad74180466319cef7bcc2293cd1311b3241230e74fc47e31625aa4d99afda60fe34f587cd80aadc7511450844b90510c2922b6f3fd198f0cc08d0d433476301bafad336cc8801ab4bce84c812e0d7338ce49a552cc5cafd74f4f6fbab8eb00002000494441544f3b9d0ee81100cb94d0bca60141c69cc7644e6db3352b0da337e244c235a0690387f92da5c4a222213482d81834d7634d33813d8ee32875e1a512d51899a31439a93b8e63b2e60a6b35626c0f962b9a673173a3d1188d4642c419dc0d60dd6cafdcaae8776c84c314bf86f5ca62009ab41e7923683c2c0ca84da6a1270a952226a534690ec3502badc2508f214c8d46a34422595d5e553aa18943a5b42629653ce2e8f51b1cf42f63c6b7bbbd0d5886bf00b00c30199e65ab66420813f2c5286e267c82fd1b80853d98a4b38fc28d4b29d56c34f2f9fcdc5c39914c62fa5544e11fc6dd9b594673137a32cb233abcf111d7b01046356eee63be22c4304a13ac1a472dde34fec61c0d15c6d5c00682181819366afb61003a6d948c2182edb111a9a2ea1a6df406b06eb666cb570016731cb0b04d32bbae5263b053ccc83318651e344d9a3542cb840a0c2b84dd3e08422c3d1e8d3c1d41871492ed98eea6651b618b62cc3c8a1fa657447d55440df2a22f453d9c8d2f951db14044796eb4d64a85426822a1f5445f05adc00d71ade97b3409b5a684bd5eafd3ed168bc5dbb76f974a73d0a122c513ecef221cd8146019b55418c092425a03cef82b1269c1acb4e6492f27738e813f1545803077889d696fedab708e980ce4609f4f53fc0ea7d95008df2efd8381e6af57de81ceffd7b80d27016b8625c14e1ea12d6b8652e3d80c8c3d3382202392f83835a1ef799a4808e179dec1fefe79ade638ce28d442c86432e5ba0942e6e7ab3fb3e9ff340bce4cf7b37a0b8ddd2c481946030314f29e1285f0e5e671ac9cb19d98483253180aa52e62e64d774b63a2b26de1420858f98510c4040b0ee6fe1cd7ad54ca95cac26834c2641fb370a444b86800a8d624a58db637722337f297104c5501b046238f99306bef7b9ee7fb8ac428d43c8e6727b4c9fccc93da840d4c3465c3b231cee0085b0901ad83e02ff6aaa278faace83ce31a2ba33fd9b65e494ba0875a7f463fa244128eeb9026d775a51b45981a27f0508690e9508544449a991591528298a5233491e071c621524a888866ead901356ee4466ee47b481446c60096566acce6a2552e885b3ad63a356962ba56c4d1eb9c6378168d118d2df5c5062ca3fadaa2271736db012bc65028ac2581c67c1eedc77f621cd7420a21258216bad2115aabc00f7c2f0cbd4069160e9320ad482992cc8212ae2b1d291d27503a503a08432185c3c261222948eb300c852015861a515ca5c0b0a0b566965a1393d05a0bc9318b154daa72364f9c7926ea6bfafcd8b57a5231b4af9d3ee7fb89fde83fc7f9dfef92d8e5748d25fab6f0258acfd547afbfa5597680bfaeedace9e3ebab84585233d1b0cd39c68c6314c6289caf26a2300c7414b589997ddf079d905248492c98b4d23a24d2cef4e7b759d5cc16664ec31e9ea25da685442bb7a16a4d7c548a61d2e4da6e1b9e0c30194a15ff13ff8410868b098788043b92d86176a5741da1b424458eeb3209c963733b0b12d2c582cb51c8c39137f27d29643a99c8a584d4a415133123bf072186225b944b68c5516e486671e11261fad2cc9601f94e3dc7549da970fb3ed39df3fa3d3926a6315c7d93d843edf3636862dfd046d8e94ba6cb7f35f2cebc035f82dab14a86180bacddb6635b73265b13af6fbdcfcc4ffc0e6e6d43a7a94f7191e106614ed44ca88a1ae15b1ab67d7fbb6bd3c56c12e064ec9a639c9f8999483369e6717e44e7ad6de23289219a29d62c61ba089413c7c1d887b765fa90fdb6d19e71c030962c25144ec9b09791c3da11ec087684902c42224d3c5e3dc05268e18cc2f0bcd1abb7fab5d6a0deec7607032f08849009d7cda7d373f9e47c295b2ea60ab954c215723c6b6bbf94fd5e335e4a477279e5c4cf7feb69769fa71f864d6f7dca777a440ca72e3be7ad778bb5abef5486eb4b6cf8bc11baaa927f9c2a9abe7f34f08f7bb7cd4e983954caf783701c3880180c8ba7c6286d094d76bc580fb4cfb97699df72e6346cc55e4644f950c7bea0500891b4794cb71cad05b3a3d9d19c10c265e11229d23e5148a41539249c7ea84feabde7af8fbf79b2fbe2d571add1f642c58235731004a984b3b132f7d30f361fdc59beb53a5fca65d2aea3490b476860249441529ab4d20a63004f2694358bf884f8d1ccf9f627608b0bcc748ff821f737771656202d7d89924bd168292c9f7b7be089ddd634aa2b9e6ef6e08719b1cc21fb3ec619edb206166ba866ded9f2559e5112fb41663f141cf374730256237cf74ef19f29b12181232b92f1ddc1c11ff814bbaeec9d684193de0217d9d7078351bfdf1f0e47a66d5fb5b2ec326a308d6b44b308c695e527109d4b5eecfa02f395955b9ec7767d6266d62c340bcd0e91431c3005a435b3d6ac875e78dcec3f7a71f0c5c357df3c7e7d7ed64ab8b250caa753493f08ba5dafd56a0ffb2d87472937cce7d26e324d921c21124232696256143229962458489a709b325fdac6a91f022276fdc41615e871ba911f6d0c9c5e6f18fbca3632da17c295f732e709f3c968120b620fc2879c59b6cbae22228c5e579f639784c62bf327e49ac9baed12c61e67627bd0540eca7750aea84c8a7c0c8dcaf66391ac99629a931130acd168d4e974fbfdfe78e586012cbb31d92f630fe6b1df3435805c0670d3859b6ce833404acc92c87a159b3414d19a1b21a4142ca460218849b3d42cb516a49988856029846041523a81929ddee8f5ded9970fbffdf2e1abf35a73b15cbc7f6ffdfdf7d62a73b9d170747ad6383f6fb4eaa7c2ef779bf57eb737c8674905a9849348482148930e490926c144742df664c62e6139a67e2789559d11fb635d760e4d510cbbbdda3822a58c5d687f7d9a34a59943a60f33732cac98fd44f320fba1e6e8e4a83e5b620dd2dc64ba35cebcca943976fe15383b5d45339fa5a35cc2330fc5f6986630f3edf4a4db5d6cfff43b5effcc997f5254f9b157b007981f65449ceee9647d0ebbfb03b0bcd1a8d3e974fb3dcf574a2b7d35c3bae20ddf3a88cd2ce59525bf96804cc9896ccc82590a96928564c14ccc1ada1a8b903964116aa1496a129ad558ad500175bac3c3c3fab7af4ff6f66ba1d6b7b6f21b1bcb0fee6dae568b52abc160d4eb0e8e8f0e7aed463193ccea40371b9e209149055c7052499202162ccf1bfa5e27f043299c64329d4c267ddfc73a1884b2eaf7fbc562716363034b1ded464057da7a696a4860e6300c3b9d4ebbdd0e8200015a91bc36d6556662530c0b620d5a5b49611b8d46b7db1542a452290420c35a02c362c8022654a9effb9d4e476b8d983cd3706012ee6295024faa845aeb28929a461246ad359eeb795eb3d914422c2e2e22c5997959d339ebf5fad9d999941299d0cca1e937c5a1c160b0b7b7d76ab592c964a9544a4722ad1c97f63c17457824a5ec76bba7a7a7beef178bc572b96cc85d1886e7e7e7bd5e4f0891cfe7b1b8554e8636a359a979ed61607ab480fa69ef37f56fca867baa71c4ce89330d16d87d16e78351da84512935180c4e4e4e46a351a9545a5c5c346b39e8c796992ddc1c421f47b285e1701804027ecf17b384d31864b709b21ac7d52f609f7fc569531076b1d3a0ac2156d6fca0f166c06f2925d6070a3106acf19269621282586816242409a959842414c3873e54be17faa3500544e4845a7786eaf0bcb3b37fae7cbf9c4f6733c9ca5a716b7581873ddd6e70b3e51feda93008e68a7eb8c60b65994a4be992a64eabf5666fbf596f2693e9cdcdadd5d5b5d168b4bbbb7b7e7e3e1c0e9f3c79b2bfbfffe0c183fff5bffe57a552b13fbfb65439bbd2666e4d7dfabebfb7b7f7e8d1a3f3f3f372b97cefdebd0f3ef8209bcdb2c51ab4c5e3629fe6b2ca375f76381cbe7efdfaebafbfdedbdb43ffbf7dfbf6fafa7ab95c36a1c1cc53b04e15ee72dd6ef79b6fbe514a218a7ceccb0641805068fd7e3f954a21a199fd8e4681eaf7fb5f7ef9e593274f88687979b952a9b45aad172f5e2493c97ffaa77f42e8d458d3524aedededfdf6b7bf1542fccffff93fefdcb943916b4f0cc7cdb47aabd5fadffffb7f3f7af4686161e1c18307ababab2b2b2b4b4b4b5808115b0e65b77fa5d4f1f1f1bffffbbf773a9d8f3ffe389fcf9bdeeefbfeb367cf767676b2d9ecf6f6f6e6e6a6a931bb922fabfc69b8b16b26064366617ccc6e187b6573e6340e9a2667174608d1ebf5befaeaaba3a3a3bb77effeea57bf2a954a7409acfc703155318b9a0866565af9be1f0681d6aed65a297d2d86757d3e15eb69b6cc2aee3589d6b407969492f18f59826109169225b3162c84604d22ba303264094dac91b794346552eee25c616da9727cda3e69f64eeb9d878fdf9c9ed4972bb9a54a7ebe925bad56b6d7166f15f26ea7d97ef3bafee86b7f34a4ad0d9572a998a7444aba92886a678daffee3e1b7af5e178b45ad6971b14a44ed76fbf8f8b8d7eb3d79f2e4f9f3e726ed581004c8bb83488168672688580ca1660a488de7793b3b3bcf9e3df33c6f7373339bcd82e06005782a9532eba5a7ea7c6c1d47481cd39a1164b5d56a3d79f2647777b7d7eb2162e2703844f82d941611cd8cd72e88125e0179864c163284edd75a9b8088a3d1e8e8e8687f7f1f71f497979765945612c312c237eeeded1d1d1d214010f236d6ebf5e7cf9f2793c99ffce42718ac103d8d88103c8399dbedf6d3a74f8320f8e8a38f363636d093513ca514ce07cbcbe7f380bc9d9d9d2fbffc727d7dbd5028a452a952a964dbb0b05416ad2e0abfc14aa97ebf7f7272b2b3b3e379defbefbf8f5cbfb873ad567bfdfaf5cb972f171616e6e7e791a1ce44d0c5fa7c7c5f934d8aa2ac4886bd220e8799d737d939519f61182264a3b915ae3281dbf01ba95810e9d79c69abdbf88d430882e4791e02f0422d78f3e64d3299bc73e70e02f39adefd6745ae69211a2f9a612246b48699d7db8863ee388d3e31c2751d6ec5934a0af6e13f8b3a5db82fd85e5616e1ba6058639316c30fcb61d65248211c4d82590a92820413091282055633a9306096e562667b73b1d6ea375add80c2f6c87b7370727870924b278ad964c2150ba5f4671fddfeffeeadac9ced0dfedfff1bfcfef320f044ff53f1c1078e7050ecd00f4e4fce9f3f7df9cd37dfcc95e7565656efdd7b1f8a009a3280c92048b3d9dcdfdf771ca7542a55ab55d77511d1d06e55a62a8c4dc1401b7acefafaba10e2f4f4f477bffb5d3e9f072eb45aadbdbd3d2242ee0c93d51101e0813e085e88a8d0fd7e1f41b5882897cbadadad398e737474f47fffefff1d0c069f7df6d9d6d656a7d3f13caf582c82c1415968369bc964129928f3f93c900e9102a13c32336e8e80f788228d3c468787878f1e3d42646764db16568aa0838383dffffef7f57a7d6565e5d6ad5b83c1209bcd56ab55a5140a00a0f17dbf5eafb75a2d224232112c862722e42e3a3b3b43e5838e217c58b3d944456d6c6c20f83dfa27827a0b21100a9199f1468823664019251c8d46070707c7c7c78944a25aad2e2d2d217a4fb3d91c8d46fbfbfb676767888086e7b65aad56abd5ed761389c4fcfc7ca5521142743a1d84e14737c9e7f3954a050fd55a9f9f9fd7eb75c45c439c7e68b8f57afdf0f070381c96cbe58d8d8d743a8d549e08ca88308da552c9719c66b3099d6e6e6e6e65650579307bbd9ec9d70948d25a974a2550e3e3e3e34ea753281496969692c9e4fafa3a4ab8bbbb9b4aa5565656be33025d29a84f1b5bcc4e21044f2e86c161d016212e012cc834698c61d64cea64beeeccbb69cbba46d144b5e3b8d0eb233e65ff93f807619663a395055852bad24d201536912676981d22c1ec323b4c8ed00e6b21c8651d6a52611010a95c36b37d6b5ea6dc6c21b9feb2f2e6b85eabb7baddc1c8d7e76daf566fbae12839f4de272fdb3af0bfddf177df084738c3917493229154420efb83b3da79bbddc9e5f24b4b2b996c3a0882d3d3d35c2e2784c8643218cf8bc5a2ebbaad568b995fbc78b1b3b3e3ba6eb95c469c65740c201a4756210016b4f75c2e8766c7cce062737373f97cfef1e3c7fffaafff0ab39110a2dfef239069bbdd6eb7dbb95c0e9c05119357565646a3d1cb972f3dcf43ac67dff77bbd1e022ea752292965a55269369b886e7af7ee5da875e572797d7ddd75dd939393bdbdbdd3d3530cc5b95c0ea1991118369fcfb75aadb3b3b3643299c964c035f067b95c2e168bf97c1efd647f7f1fbd6e696909792189c8f3bc46a3f1ead5abbdbdbd4422b1bdbdfde0c103930ac8719cafbefaaadd6ee30eb55aedcd9b379d4e87883299ccfafa7ab55a45bbeaf57a6fdebc79fefc3938e3fafa7aa55201c6351a0d0001ee091041547e547ea3d138393929954a1f7cf041a150e876bb4747479ee70170a1190d0683c78f1fbf7efd7a7171f1c30f3f5c5959190e874747478787879ee701cbfafd3e47993af15e676767784784aefdfaebafbffdf65b2401504a150a858d8d8df9f9f9300c91fbb25eaf8361a1fe373636b2d9ecc9c9c9f1f13112d929a572b95cb3d96c341a61188204e57239703a1463381ccecfcf13513e9f7ff5ea55a3d1d8dadaba77ef1e11f9befffcf9f35aadb6b6b6b6baba7a7e7e8e742ac0bb6ab57af7ee5d22fad39ffef4e8d1a36c360bc0ba4c4ffae1c2976885460ce28818c38a615e8c46c6143d7b8f7181b18dca34a5ddd8fc6b12b38c5782b0c4b252492984238473f951492c888466c5ecb07058b36029c811ec4a912062d62e53c83a0c425f695f38c3743679e7cefcfc52f1fd7babfb47b57aaddeecf44f1bde9b83dea3a7bbbdb3d3701872df53dddeb0df538e935b98cf2caf8ab9794aa598f974efe09b674fdbedf6071f7cf0debdf790b61e8312f8b979df7abdfee4c9935c2ef7f2e5cb5aad964ea7cfcece903710ac04019731cea353a10bb55a2dd87140cb8d8a07fa002331aab1dfef63f6f7e4e4a4dbeda6d3e9858505b0fdbb77efaeacac74bbdd870f1fb6dbed5ffce217dbdbdbc81bd6eff7d1b8fbfdfef6f6b6d67a6969a9d56afdee77bf7bf8f061a552f9ecb3cfde7befbdd168f41ffff11f8f1e3d725db752a9007fc330dcddddddd9d9595a5afa2fffe5bf789ef7c5175f789ed7ebf552a9d4a3478f1a8dc6eaea6abbdd1e0c06a552697d7d1d7a68b3d93c3d3dadd7eb4b4b4b00ac76bbfdcd37dfececec944aa5adadadb5b535a42cc3cbe6f3796646e2b2fdfdfda74f9fbe79f306880005edc30f3fec743abd5eafd56ad56ab59d9d9d7ebf9f48240683c1f6f6762e97433d20422c329e188e865a0d82e0f0f0f0f9f3e7737373d56ab55028b45aada74f9f76bbdd959595bb77ef02b0fafdfe1ffff8c7c3c3c3bb77efdebb772f93c940af3c383848a7d3fd7efffcfc1cc1bb75943c180349bbdd462ab96eb7fbcffffccf4f9e3c79efbdf7eedfbf3f1a8d8071c562b1d96cd6eb75e01d11c1b42f84d8dada5a5f5f0fc370301828a5cecece40a03a9dcef9f9f9c9c9493e9ffff4d34f6fdfbebdb7b7b7b7b78728b8189000d67ff8c31fbaddeefff81fffe3bdf7de434d7ef5d5570f1f3ebc7bf7ee279f7ce2fbfed1d111d874a150585c5c842def8b2fbe78f6ecd9cacaca2f7ff94bfa7302564cc696a20b2f0ad651bc04a6ebd9b06896e99d26edc1c60d2f162ed99c66235454326666e8f9ae9bc864d2264533f385ad7d4c06a70cf0c6104fa4431d382ca5145a081684c7122bcd8a78bc6899995933691624c230acd7db83f3aecfae70d3857cea416e99b72bdd8177783e7cf2b2deeaf4f6bbada4942929943feaf4bb9c4aa4363633eb1b2297d5523251bdd97cf6e2c5a0d7dbdcdcc866b3dd6e1721038bc5e2c2c2827166711ca75eaf3f7dfab452a98461b8b6b6964ea78f8f8f9f3c7932180c5657576fddba2584a8d7ebc7c7c7b55a4d08b1b2b2b2b6b6d66ab5f6f7f7c94a29a8a33038cc0ca4431aede170b8b7b7b7b3b31304015aede6e6e67ffdafff5529f5f4e9d3c160b0b9b9797e7efefaf56b2889503d7676760e0f0f5fbf7edd6834d0379696967ef18b5f20d706e62251aaa3a3a33ffce10f4747473ffff9cf57575799b9dd6ee341e7e7e7cbcbcbd96c566b7d7272727e7ebeb6b6562e97fbfd7e3a9d5e5f5fd75abf7af5eaf8f8d844c1377379662c1c0c06bbbbbbb55aedce9d3bdbdbdb894402396b3dcf63e6d3d353f4f6c160707474b4bbbbdbed76efddbbe7baeee3c78f777777f13870cfb5b5b5f9f9f9376fde20167e3a9d2e140acd66737777f7c58b17cd66f3f8f81851f0010d688de03e40b446a3512c161f3e7cf8f0e1c36ab56a1241e1439c9c9cd4ebf55c2e97cfe789e8f4f4f4d5ab57ed761b09776bb55aad56735d370802703a58b54e4e4e161717c1b95ebe7c797070f0e0c1836ab53a1c0e01406fdebc79f3e68deffb5b5b5b5b5b5bcc7c7474f4ead5abc3c3c3939393a3a32328f2a61900be818385420109285fbe7cf9cd37dfacadadbdfffefb888e8d9bfce10f7f482693bffef5afcd3ccce9e9e9f3e7cf89a85c2e0f87c3d3d3537c1a8c88c964727171310cc3939313642f37cfbd36ec7c1f89f061826d8dcd576324b9865b83be64cac91c856052c67c7ec411a6295625a288973af213e9f57a83c12097cb65326913e2dd38b71ba882c268f8158f9d3504338fbc810a5532954ca60aaee330130ba58948069a479a46c43e1109d6acb5565a0ad7d3faf4b4f674e778efb4a39cf4ea52f9ce5665b19c4938329796730551cca89aabd2094ea544180cdaed862b58ae54938bf346dfed0d0647c727a747c7cd562b9d4a0d06837ebf2ba58339350462851104b6956c36bbb9b979fffefd4422f1f0e1c32fbef8e2ecec6c7e7e1eb9c84e4f4f1f3f7efcf2e5cb743afdb39ffd0cf61171b1a46bc6d7e5c8cb4108f1e2c58ba74f9f2aa59e3f7ffeedb7df168bc55bb76e8561f8f9e79f3f7af468636303337a0b0b0b4b4b4bccfcfaf5ebafbefa0aea003aeae6e6e6e6e6e6471f7df4fefbef0f06837abd7e7474a4b5fee31ffff8f4e9d367cf9ecdcfcf7ff8e187502bf6f7f78f8e8ecae5f29d3b773efbecb37bf7eeedeeeee672b946a3a1b54ea7d39877fb877ff8875aadf6f4e953804e2e975b5858585b5bfbf9cf7fbeb5b5057a45939e38700ed8ddddfdf2cb2ff7f6f6304a351a0d28389d4e270882c5c5c54f3ef924994c369bcdc3c34358703299ccfcfcfc2f7ff9cb5bb76eb9ae0bfdf7f4f4f4f8f8f8f4f4f4c58b172f5fbe0488241289542a65ccead0dfabd5eafafabaeffbb022fddbbffd5ba3d1f8f4d34f1f3c78804cb414c5f877acf4c383c160341a65b3d9fbf7ef039d9f3f7f0ec362ad56c328f2faf5eba3a3a35aadb6b0b080bc76ababab1f7ffcf1a79f7eea79dea3478f0e0f0ff7f6f69e3d7b363737f7d9679f81d1eceded1d1e1e1e1e1e9e9d9dc11480842fe9747a7979195597cbe53efcf0c35ffffad7b76fdf0e82e0fcfcfcf4f4f4a73ffde9af7ef52be0efef7ffffbdddddd56abb5b5b50533199c243033934aa5c2303c3b3b3b383858585840aa14331144519ccbb742c4f7135bcdb2774e78a86acd4c524a87c7be233f34870aa00a9d81a2e955300268f2e875a664c68c25a228c9a3d1a8d7eb61103315c4ac89709ac9786ad6e28c83d8f0386c31f507bd6ea793cb67f3f97494ab426bd69a15997f44447a6cbe6347e970300c8e8eea5f3fdd3b6ffbf3f3b99dedc595c5a220a7371c9dd53bc1a83d3f975a2c67132e0d42af2d285d2eeacd75b1b4488e435a2ba55bedd6f1e1e1f9e95926934ea7d230be76bb3d6686d509997ea023a0a7158bc5f5f57522cae7f383c14008b1bebe5e2c16cfcfcfcfcfcf53a9d4c6c60674c9c3c343d7751717173736366c9f6c587640f5c330047728168b483e582c166bb5dab367cf7cdf87a9ebbdf7de7bf4e8d1575f7d0503f6fbefbf5fa9544e4f4fa19c96cb65210466b290a802508b073d7cf8f0f5ebd738f9ecec6c797979696909b6ad4ea7c3ccb95ceedebd7b3ffde94fd3e974ad56c37883fe3f3f3fbfbebebeb2b2028e897c4548d1562e979797970b850245e3592693d9dcdc544ad56ab5172f5e54ab55348ff3f3f3fdfd7dcff32a95cafcfc3c942cad35ec7aa9540a730b9ee761bcc4fec5c5c54aa5b2bfbf2fa5acd56ae8b1a954eace9d3b27272722cad2d4ebf5906d0835b9b0b0f08b5ffce2ecec0c8cb2d3e96c6e6edebb77af52a998721ac0328d1f29d48077cbcbcb8b8b8b985469b7dbcf9e3d3b3a3a4aa552b76edd9291df36fa052c838b8b8b44747878787070006e9e4aa5a094119152aa5aada652a9939313c77196979701d93060a15de572b9ededed9ffffce78944021e7fbd5e0f85416f824d1346527437a426514a611ee0f6eddb302f0e0683e3e3e352a9049399c1b5697f883fab5ca85f748167621ca780355f8f61d9f672fb37450e81c0634c8a7194421d1006c0a28b90378a88709aa10f863a59f7545afb71dd2f9a290b82406be9385841aeba9ddef1c9497154a854e653e934c898261224981d668709958ea942a142a549a7d3c972b9509ecbd63a677b0787e7b5d37c3ae9b2e3f923cff3dd446a7b63f1d65241f8835ee0f9f395d4ca32ddb9cd2b2b3a9b25a23008da8d46bbd148a5120f1edcfff0a38fdaade6ef7ef7bb2fbef8e2e4e464381ca2ae4cea33d403727c158b45984bd7d6d67ef6b39ff9befff8f1e3e170f88b5ffce2f6eddbbeef7ff3cd37cf9f3f2f168bfff44ffff4e1871fc2bc8d1b0256608948a552989cf23caf542addbd7bf7f6eddb737373e7e7e752ca6eb7bbbcbcfcdffffb7f877f50b158fcf5af7ffdf1c71f4b290f0e0ec059fef11fff5129f5fbdfff1e2e94205640b1e3e3e346a38184697083845518ada2d3e9409747e74fa7d3b00d61b61ed3ffb55a0d76194c83a2f5e350a3d100d1c3dd72b9dcfdfbf7c330fcf2cb2f315df5c1071f40b9fb977ff917786f70e44c884a00bec34c6310bcd96c9e9d9d954a254c50a6d3e956abb5bbbbcbcc9f7cf2c9ddbb77777777f7f6f6e08200ec03a7ebf7fbcbcbcb1f7ef8e1ebd7af7ffbdbdfeeededbdfffefbfff88fffb8b6b64696df0933c3dbc0e80d28128ceb8542018ea3954a05da6bbfdfffe4934fb6b7b79f3f7fbeb7b797cfe7a14f90a5e69be475704180310e4ab1e779786ea150f8e94f7ffac9279fa4d3e9d3d3d3dddddd972f5fc2a30d8e26186352a994ebbafd7edff3bc442201b69bcd660b8502b2ffa26e611bc5ace2871f7ee8384ea150f8ddef7ef7e4c913c771de7befbd4aa582c9e5bf1860e949bf02db8405eb0eea9bafc9b0f4950204a1081d0146c6cd842250b3393fbeb471023281e18174c60a86cb8d1101ae28f06a1142a652c9d168a435359bed66a3ed07c179a5e6ba4e2e9797526aa5594b418e200793a19ae1f0c39ab47438974bad2d57067e90caa48ece5bfdbe474424a5a3742ae3aead543fda5abd9de644e36024c4c2addbd9db5beeca8a2e162899269f555f00002000494441542222ad54d2751717e6cb95f2cf7ef6d39ffce4e36eb703350ab9a331eb5f2814cae572a954fac94f7e52a954eaf5fae79f7f9ecfe78f8f8f6fddbaf5939ffce4bdf7defbf6db6f07830134c1fbf7ef1351bfdf7ff6ec99d67a656505233c807e3018bc79f306be08f57a7d6b6b2b91482c2c2ca4d369ccc4c16f7b7d7dbd542a799e27a5bc73e7cedededeebd7afa5941b1b1bd56ab5d3e94829e7e7e7e1c51e86e1dcdc5c3a9d8639e34f7ffa531886524aa453cb64321b1b1b8542a150280441f0ead52b7c91fdfd7dd7754ba59294b2dfefc37f726e6eaedfef2793c96eb7bbbfbf7f7c7c8c6e99c964de7befbdcdcd4df443f84c4929d7d6d6e093e5baeed2d252afd73b393969b55aa01b989fba73e74e1004e065954a259148a04bfff18f7fc4747eb55ac594423a9daed7eb5f7df555a3d1003fad56abc562f1e8e868381ca272b2d96ca9544265b65aad4c2653a954f2f93c9ca10a85423a9d4666f2fbf7effffce73f9751864accd22612898d8d0d30c1e3e3e37c3e5fad563737376bb51a2c53cf9e3deb76bb52ca42a18052150a054ce1a11998590b22828a07a85a5d5d9d9b9bc35ce1e3c78f93c9e4cb972f7777773dcffbe0830f3efef8e3dbb76f0397b3d9ecf2f2b2edfedeebf5b2d9ac10e2c1830744e479dee79f7f0e3d3a9fcfffe637bf69369bf97c7e341a7df5d557f3f3f33b3b3bbeef572a9542a180fe0b42809109a0f9faf56b66c6f4e5048efc7964face96c2c826292bbf9561d9a0c393ae5810b28c29b0f3b9ae6bbcddb01d8d469ee701a4a08ac3ee0bc7b668ec123049a2b9c09509aa0a6ad3712492bf232d2854866432c92cdaed8eef05fdcea0765ecb66d3d96c4e3aae0ed4ffcfde9b3ed9711cf7a29955bd9f7d9d7d0683c13604082ea028db9772f8fa85dfbb9fec7fd79f1c8eb0ec906449a44c900406fb36eb99397b9fdeaaf27dc8ee9e9e0d044052d2955081689cc9d35da7bbbaea57bfcccaca14808240008a4ccd4441c21080c25686e7989d465948b9b4383f09549810029886a4383228e9366b6b55af72b00dbbbeb09cc6fa65f7ca9552a3059605a6442010b0b8b4f0f9e73f6b341beb972f974a9ee3d8376fde9acd6688b8bcbccc7eedb3d9acd1685cba74e9ce9d3b6118fef6b7bffdeaabaf0cc368341a7ffff77fffc9279fd46a35cff3ae5cb9522a95f2ceb1b8b878fdfa755e502fbe51364e3f78f08051e6f3cf3fe75530868067cf9e3d7ffe7c6767a756ab5dba7429b7bccccfcf5fbd7ad5711caecd75dd8d8d0d00d8ddddbd77efded1d1d1603058595961ca73efdebdeded6d9eed1dc7999f9f67efc10f3ef8e0fefdfbcf9f3f67a6502e97bbdd6ea5526115520851ad566fddbad56eb7ebf53a430f2b29ababab6c48ded8d8e0b9eafefdfbaf5ebd628060c0e2e1b7bcbcfc8ffff88faf5ebdba7bf7eebffeebbf72f7e8743a6ca75f5b5b5b5f5fe78c905b5b5b8f1e3d621d707373f3dab56bfd7e7f6363e3bbefbe7bfcf831bb2cacacacacaeae96cbe5b9b9b9478f1ef57a3dfeaa52a92c2f2fcfcdcd351a8df1785cafd7979797d9f37e381c0e0603cbb258f3955914877c38954a25a6393b3b3bbffad5af7ef6b39fadafaf6badbffefaebdddddde170d8ebf55aad56a3d1585f5fef743acc641f3f7ecc90b1b6b6d6ed7659236b369b8c38f57abdd3e9b09f47a9547afefcf9ddbb77a594070707cf9f3f374df39ffee99f3efffcf3c78f1fffdbbffddb6432595e5ebe7dfbf6c6c6c6f2f272afd79b9b9b637b96e3385f7cf1c5eaeaeafdfbf77ffdeb5f737af09b376ffec33ffc039b26fef0873ffcea57bf222206cde5e5e56ab5bab5b5c50e2bd56af5f6eddb3ffbd9cf9acde6d6d6d6975f7e695916537eb8c0def4a394bcda62fd39c362f429ec93fcc136ac1ce673bd8fbd1379ca6266c42b324cdd4596ff864d279c8f0b00d835d4f76783c1406bcdfd92f56d76edd19a82209c4ca6520a3685a4362c216cd3b64dc7b12dd7762dd3124202b0e62bd2c0cb7cab825010c3a3651b95928304957249a3116b4c3468200114053e8541ddb35b02c81ffa7bbbd4ef7bdea267b9866183902091480b432caf2e7be592eb7a8d4643134929d7d6564dd3d05a3367e1599d07eddada1a678d662f9b9595958f3ffe986d0db55aedd34f3fe5c78ce35808d1ed763ffbec33cbb29801e564d3308c52a9c44256615867611b96effba3d1a85eaf2f2c2c6c6c6c309520a256abc564a15c2e337b65131b4fe3bc66b7b1b1b1b8b81845110fe39c8cacacac2c2c2cb0354d4ac9deeadce3e7e7e7ebf53adb6e01a052a9dcbe7d7b61616132998cc7e3dc2adce974363636d6d7d779118ae9f6dede5eee250f99e7bde3384b4b4bf57afde0e0a0d7ebf176b68585855aad4644f57a9ddd2078767cfaf4a9d67a7979f9ca952bdd6ed775dd8f3efac8719c288a4aa552abd5ba74e952bbdde6cf954ae5cb2fbfe4c4ba6c16649c623ed86834aad5aa528a97e4eaf53ac36eee4492db226cdbbe76ed9ad6fa97bffce583070f2e5dbab4b4b474e5ca95288a1e3f7e8c88d56a75696989fd9b2ccb6ab55a77efde3d3a3a62b6b8b8b858afd7ebf57a92249d4e878728af1dbbaebbb6b61604c1d75f7ffd9bdffc86378a56abd5ebd7af7ffef9e74b4b4bec44c6b9873b9dceeaea6aa552d9dede6656c87da3dbedd6ebf5300c07830111b5dbedb5b535b69902c0e1e1212f7d30576d369b8ee34c2613dff73dcf5b5858f8e8a38ff81e58715e5959f9e8a38f7227ac9f08b07218297ec0428163f510df62f3f36b0aa34f1e5a84f914bb32b31596512ce74d90a6e1e3cdf1694364d99b63de9391a315af37e7b62d002c97cb4b4b4ba5920780966d23a20091c449bd515f5dbbd46a370cc3d04aa5150b4404020d00eced804002419a26963dcbb483300cc2c89fcd288e92380ae378321a26331f2be5926dc1f8683a384c8efa50a98828b1a4214c13046aad8414ad76abde6c08344cd302224260a7f07cf989886ab51a00f090765d97378e303568369bdc80eccd8c880cdf428866b3e9791e2b0b50f00ba9d56a1f7ffc313b4c954aa5bc06c771ae5dbbc68803008c74ec6a8088bcb99788b84ea6babc37706565250c43d3342b954aa9544a92a4542a7dfcf1c74288dc1f3d0f99c21a9ceffb8661789ee7791ecf3d6cb5741c872d684f9e3c994c26b76edd626a393f3fcf2630ee2aac8a72258c4450080e03009ee7ddb97387f703baaecbcb6a90edc29152b65aaddbb76f5fbe7c999fa85aad3216dfbe7d7b7d7d3df7ece73dd85ce7d2d292e3381f7ef821d7cf4e000c9ddc5c52cae974ca7d6f7e7e7e6d6dad56abe58307b2b5722644ac590f0683c964120481ebbad7af5f672752ccdc4d4aa59294726969c9f3bc9b376ff2adf244cb3c3a5f4861d0e755f5fdfd7d36514da7d31b376efce217bff8e28b2f78565b5d5dfd977ff9177695ca7d7a3dcfcb871e17cbb2363737171616e238ae542a39430780ebd7afcfcfcfc771ec64850d7fec45911370f69bf33c6f69698977ecb32e254e6e20ff710bbd66d34fe6ebceb0f523ac12b2d343bec0c74644de796018060f155edbe2cdf7790fa063bf92144dd91cc6ca02b754ee1b81692e3ff03cafd369bbae1b86117735dbb684c452a534373757ad947ddf27cdc1f438ba6a1a23140105b02b16b0155c4a8d42f3825b12c6b10a290e290eb58a1315c768598d86bdb121db43d199a37a036c07840444022d80f7704802504a1311521a87a0f80e18aa00804d6fad568b6d5200a0b58ea288352f3e8d419c9565eed0fa64cc133eb3b8b598edb242885aadc6e0582cf980e4da8ababc699a8d46a3d8a1b9f046905395703decac70b60f303f621463674ef66b595858e0c1c695b06999ad5139d4161797d95020a59c9f9f9f9f9f3ff787f22d72790ddcbbd88276ea715815e2f65c5858385b61b1589655ad5679f992fd064ed18a1c5b1b8dc6e6e6266b79ec2d5ca954d82d2b2f7c57b66d9ffb20c50a99ea4266d2ea743a1f7ef8e1743adddcdcfcdbbffd5b56de832038f57e7952cfe352703f617a5e6c5e0060a3304f5145795e8a562a5e2b6356bbb6b6c68d501caa7fcc92b53d1102a77d3ecdb0ce05b9a219ebec99f9b76c38670316118dc763def3c11c5e08c110eeba2eafa1f2d5b95328af060881b66dd76a359e9a78edd63024a469eb41081202887410cc46a391695a96ed0451a02101505a6bd08084020501116a055a1101f2d6e2741fb426601893063aae6558c271eda812cf82208e92b0d104d2ae6dd73cd75a5a840f6ee838968e2b4b1559ad1220a649bab91dd2237d9f49f2ec04c54003e74d2fe74ace7d47e2643482b39764d6cad393c49b173c190be5dc5fc12cbf8065598b8b8b6c00caddace06487297e2edecf3b6b1c175d88d9ceeaefad81416d757575717191bdb44461f366fe8cfc81291543d5d9403a7979fdef16df4b7eb79d4ee717bff8c5c71f7f9c2449b55acde1fe6cc8c6b33f4a17c43e1427379fbcbe308bcf292114de6fb13b41a177fdb8c7332e9f44c48b84a9e8ed1856b17b156f3db74d40a67fe62e3900c09a05bfdadcad81350e4c5d2b0d6e56cff398e8b282c0a7d9b6c52edd9ee7c47114c7f1dede3e11c571542e958590aee7d6eab5244976b6b7a37ae87aae23048146244ad95b9adb35ddf27dbcd112500a0b1cdbd15a51398ab506ad341bd46ccb14c699355d22c87cdb8814e70d934232e2e6d351de6f8a7610fe4a6549e459ed85f3ae3a2b29cacfad21e762790f1385f055c5bd53795539a1cbbf2a4ea7456b421efba138ccf2630ebb3cbc73637f7ec97173173645b0f0ecaa39654ec8c59fe0aff29b2c8655c81dfab81316afca2b2f364eeea040275324f08ef4d3afbb50f2fb67c5f0d44bd1857cb7c593cfca752199455e03df52a9542ab61e64cb11bc3e98ef332dbeace293e6209b779eb38d40857c3690cd34f90332edc8671afa894d5779d167c28af0ef177f9c1ff6fb01ebd4e45cecd3540075f61d6597163622f0867e2262c58d23ab40865fe572d975590337726b48a552350c330cc3c3c343222895bc66b3d168343ccf1302abd59a61189389bfbdbd23a5acd56a8ee395cb65afecd56ab5c38383972f5e06d3607dfd120a81a0d3200d99f60b488004cc86042021820020009428a401a694808234a1b8f80d65e4206b199192ac425b158f45c4c907c6b92d7c6ab23d25f9de1a5ed3abcefdf622e14595c0f75186732b3c7bc9b920f5c34f2862e2d972aefca2467e7db9a8d1cebda573e5e7b6c9453f975f7ef6a9df96d95d247f4d6bff11a02aff21cafcc95992810c9dea556f6dc3cad12affa553bfc160c9160d1e5a4ca6c230e4e001bc80e8388e619800e4388e6d5baeeb20a2e338bc939ef7792222af9dd9b60d40991f83f4fd596e27765dd7766ccf2be9440d8f8600840200199af0c42862933b92d62a49502b4214a449a020d2420210214f3e3a4bb2a034101069210401a0407697cfb27203a2c88e7fe27c4defd24d7e9a529cf9ff683dfe4dcaf73623d3998b5858b1a9734620b3ad9d3fd64b647659e4477ffc8ef4133dddb9c73cbc82cca28f511e000bf1780813304b780bc02a32ac5cd5cc5dd57367056e653699eb42fc7236183306f19625ad155b3a72376800b02c8bada74208d7753810122fedb37dda755d001442baaec76a261138b6b3b8b8d869774d29d3353b02004e869866e622204022d0511287611c450a0118b08034700e42218900852066f27986c81c92408b14b00465295453c0127fee8075d1e56fde07deb09314cb8f5eff3b3fc2f736e02989b82019eaa933bfb7e6b77a89c5fae16498e63f5a47fade16f8118ff9aa6ebe847df68d1745f966e3b7ee37749267e546f71cb6f205a09c73b13b229f03993980edf4f9250c6daeeb5a96699a12008934a26159166f276456c50e0b9c72364912cbb42a959a6559a4124ecb0cec8145c77e589052248ce378341efbd3003480268148a04910913a664c40ac09038a1cb00467940420d2280a80c5eff84f0a58dcceaf3ffe10b0fb33293fc5e3bf3ffe498efc81d72ed8b7e35c8366f1dd0380416f3c39e71ff2a20b8104ceca73bba038b3f919cee80bb9295114c23910015f6a18c7811fb5a62451528294465a7106764a255a2bc91e0dc8504502a8f043020155a28359389d4e4111316021f766d6088a2a9e86b47d19b09088903134fdccb0f51eb0fe48e53d60fdc51cf903fb6cb2b11b4e2d809eea996c74c7b767584554a24261bb7bbe37104eae3441b648ac4f46cbce89581e89010a6b584208216410cc66b3996d3b1c903bbf240b410370bc295a0b93f5dce3ec84e96da496716118a6e3385a29d4a0b51628d8b6a733903aade26942149a740a584210a90ca40469e0c8cb7f5ac0fa21c777008e3f55f97368aef7c71fe5c82f34cf6f802781e8d8a7fcf80bc4376758451c296ab6194ca4e8c8fb542f5a8fc87f9a8189b70a6221d16b7e87fc272bb700b8bfbfd7eff79bcd56a552e56d3a5aeb3c616afa74028421b402a26c10b25607d901406b12021dc7edb48ca45a4504d25a80202240a935838e16883ae56584288008e0f89185442285401960e1ff2d36acbff2f2271fa2ef8f678fb9799a5d37729c812c7ffd316011d13b33acfc33532422ca859807602f98fdf392c31322e69ba2abd52a2b83ccce844855592104bb680741d0ebf5a434b426212451fa90c0662921a421b31ddd69dc2200901cbfb4b8779200002cd3b2cd3cc2947e6d1a54ca1d19defedbf7e57d795fdea2e4ee7578b2e4fed96fc1b0b8d079962cca5c19f31031bcff99318b0a2c0cb388a3ccd166b319a71268369bf94e08fe2a4912ad9569a65e11a6690a21b5a6388e38eb149bf085948800881a7414c75a6952dab1d3d406ec8590fde3fb4e4355645f01910620ad08511280942900694a0014a56baef238f8fd098ce26adf63d6fbf2befc08a5487a10d3045fc75408de9561c119133b6f25e33d6b711c3360b11303332c0ea90119ffe285428ee2c0fb4e79471507844b12c5281345a19492d73b3978f9603008c3088038ff82eb7942ca3889a3200a82402b4d9aa230b24c4b1a52250910159f0f01908019a166133b9214421a1200084013476b03441468804c0048e90481880049ead4d1410b89d98a21200a4d90ed763c66bc7fcc35e91fd453fe3aca9f5cfd797fbce80827dd5f8410694ca8532ff0f50cab08784561fe4b7981ccaf9fc3efeb9311fb9861f1e8e514920c677c6d18869cd24e4a19c7895263a594949cb4720a001c215ba9240c837eff683af51181333eb65194cba599ef1ff40e8230b42d5b2b1220b4d29eebcd8219abc2f913b24d0b8980103468c96c33550913802088a2289652da96e95a124002281419602109e4ad838277fd088180ece7c6ed8e67dbaad8863fddf17df9def253bf82f7c7773e9e42a11c568a23e88732ac537ff25ef37c153937a2f3571cf6248f18e3380e87da60631befbf374d733c9e4c2663d334eaf55a6e77e79d8088c841115dd7d55ab155cb75dc72a9349bfa2f5fbc0cc2a056ab9302d20444cd868ee398105088a227567ecf2884461928e507e160ec0f46d3fed1d89f0451941842da96512939d5b2dda87be5b2e579b6694871ece90e29cc31c54ab5ced3ef0033cfb2f70ce87d795fdeba605a0a7fbfa50debdcc27c8a97fc382c6f9e879d88b4d61c740100f2b0df1c3e290c43dbb6abd54aabd56ab59a00c8e9791da7d6ed76394454b95c364d6b3c1e9ba655a9549796961a8da6effb2f5ebc188d46537f0a085114f50e0e7cdf27458812082ae5b2aa560198f9a4f74994e9c3a889500b318bf54e7fbaf564efeefd275b8f5ef50e8749448223c8a8c4b3e5e242f3d60797ae5e595a596ed72a8e676924cacc5c84c81bc93551be6a29285ba3cc7d38f8ecd76fc4fbb32df91477b2ebbc2fefcb4f5f4ed02bfefb5d1956a1c2b4b0dec75a21efc211423036e5722925fb6a6196904308e1386ead56ab566bbc62c8148c0360b3719d4d4e00e8ba5eabd5ee76bba3d188133db0b14c6b1d8591218d66bd619a561846b665019066172944b66311fb39202182260ae264efc8bffb60e7d75f3efcea9b47af767b02b156ad961c3b8a92c970ace3e0a83f505a0929bc926b1a02419808d2b6382e201be5044a94793488b485f33de17f9c18fe3f5d91691c0a800bb7d4bf2fefcbdb162c1c2f3ee9f41c8988f83a867516cb8a92dc8118b2f447a66972883ede8203009c3bdb34cd72b9ccc9d30120080228f47e263ea7ea67e4e22880719c4ca7d37c9364d1709699cfa4e7956ab5eaf5ebd71ddbe90f06024008542a21221259646804420d402090140dc7fee367bbfffde583fffef2e1ee7ebf5eab5cbfba7cfdea52a35e0afda0b7d71f1cf5c7834112f9a3fe913f6acf5ca4085cc7b00c2985c135663ba28f592b13ae8b9a940adb03307339293e4b7ecc15c9dc2a59ac24b7249eade7d49b3e6b473bfbb978c3672a39fdd3f9f1f516b473efe74d84f9efbce7747fb985ed27dfe315941bb28a827767585488c1c4d625dbb61dc761e786dce2ce342a77b32a863c765db75aad20e27038340cc3340dd775eaf59a10e2f0f070341a13713e3593754c29052b95ccbc38481600562a95a5a525d7b179bfa1eb381c60cbb42c4424cabc0f78740020a2021a4d8317bb470f1e6f3f7d7ea0356eac356f5cb9f4c947ebf3dd0a69e58f67fed83fd8d9f5c7a37ad9b54107e3712c3455bc92e349cbe40a51883889e3789624b110d2b66c5e27e5e0b99ce5340cc34aa5c291e172e695b7e16b56127323e0292b983819b42f7f0567def439279f3d072f8ecaa2b58ea228084200b06debac4bf0499b2864bd10102177a62b9e79ea660a3b168ee1158e2118b26da1efcb5f48b9106bcefbe2cc949931ac1f68c6ca5dab785ce5c1fc84101c6e546bcda3d7300c265c86610881f57addf3dcc9647a747414c751abd5aed5aae5722908c2fdfd03225d2e574aa532e71731cd238ec0cbfd9e733ddab603001c667bd8ef3f7ff64c29e5baded2f262a552ad54aa8842253a4fbe411a3410a28e950ee3c40fe33051b1064a843fd3073dffc5abbed2aa5eb14be5d27cbb7179a5abc2990a434812df1f252a02a24aa92aa52d44eac7351c0e5ebe7c7974d4776c6765656569693108c2a74f9ff57abd2098ddbf7f7f7b7bfbc68dcd7ffee77f6eb59a455829e6cacedd4d2ee259909dc44cf31460e531338a12807348ca69d79693bf78168ffafde1b3674f00606d6db5d3e99ecbf500a0c0f3d2a310a789a1529ad3e2162ed75a93c8020d420661c5b883ef79d65f52c9385536207359fac5f1e215a4feee74926091f1033b0416d2c743c1d2cc75b29ec89e59ecd9c0f911d824ef38b6e7b988c8c1ff1181970e47a3f16834520a6cdbc9d340327de38d8442885ab5e6388eeb7a88e879de5cb7abe3e4e0b01785a1eb7a7cb6edd888023409424863cd201128a5b552b66db49ad5c5b9d6cb9df1a01ff48ec6fff3cdb39dde51a7539a6b97bbadea4ab7b13cd7986b36a58afdf1280c2661a88320f2fdd0302dcb364cc30480c3c3c32fbffceaf1e327b56aed6ffe4677bb5d22eaf7fb3b3b3b93c9f8eeddbb5b5b5ba669010047311c8fc7dc2c798a84625e9cd32ff8a4ae948f64de24c08c959dda987bf23ecd5c25e73712c7b1d64a6b4eb3c6abb7cc37b188560090a425d61a5cd7e1ca7d7f9624491425701c251d1021cf2649740e5f534a2589d23acd41c9499488807b0222f21a3123551445dc3d6cdb4184d92c20a2fc2938ac6b4edff2aec72d7446724a5894176bc08b25ef202ffed6bbc9ff326ac00b24a7de5dea09047031f42000221516cd78fa7d1786c5189777d09c5e150b9fc9ac8a03c848295961745dc7716c444812ce2a5cae54caa66997cb651ec6cda659abd585404e6905008ee332c6f1981742542a950a56a494422069721d776e7ebed6a8c749e4baaee77a00a07402440221b362a54e0849a2b45295b2b5bedcd9bf3a393cf21fa93d7fe63f7d317dbe2b1cd7a8946dcf36e69be50f36163ff960edd262ab6449d3b6310cc2309afabe6999d2704cc3542adcdfdbbbf7ddbd6fbef9b6d96ccecfcf5dbb768d433f674317118569a66920fafdfe8b172f0cc368369b737373191cc49c9e9ee92973d67c81424a61db0ee302b7eb6c36e384779c5b81237f0f0683fdfdfd300c4ba5f2fcfc1ce744d05a4fa7d3c160309d4e1191d38e1191699a1c5e9188a2288ea290b57b4ee03e998cb586f9f9f9c5c58552c9abd5ea9c59878d89fdfe11bbfb72c62a26d100a0350190101c4c99c6e3c9603098cd7c442c97cbad56cb75dd2008f6f6f686c381699a9d4e87b3694ca7fec1c1fe643229954a9cb2616767378aa2b9b9eec9a4126cd8ca77179cb5805cd48dcf95d319399d9cf9df4a7e0a2bdf41fe9751432e3f25493f692001c0b19b0828756f84e206b96312962153d6ce3f9061e5579d02a9e2b7ac1e72547f3e1a866159a66148cc6277712a27d3b4f2c8eea552c975bd2cad21b21bbd6dbbf9ec2d84306cc3300d0042144a6b431a956aad26eb006cf5104494a898409f983f04006995c448baead957d7caa634ca8efded42fde5f6d1d1703c09c259ac767b93e9c4bf87fac9d3ed8383a3bffbecc6071b4b204da5541485eed4ad544a8818c771afb73f1c0e6cdb6eb55ae572298aa25eefa0542a1b8628973dad55b55a69341a8e634f2623c3108f1f3f7afcf8b165d9ad56cbf77dcbb2c2302022c771a59400a4b5224276419bcd664110944adec2c282e3b8001404c17038dadbdb3d3838188d464c705cd725d2af5ebddad9d9514ad9b6351c0ee6e7e75bad561004af5ebd7af9f2a5effbf57a6d7171298aa2fdfdbd72b9b2b979a35aad0140bf7fb8b3b3d3ef0f9452443a8e93288a94d2be3f350c1945e160d047ee594051147266e62449fafd7eb7db9d9b9b2b954a42b0011e887492a8c160c8f7e3fb934aa5bab8b828a5180c06bd5e6f777777301848297ddf174212d1d6d6d68b17cfb5d69d4ec7f7a75aeb9d9dddd96c767474b8b2b2dc6e775c374d29f40ebdf47df9332908902709a5a2188fbf3bc5f5d2f02a3f90619d45b7dc6e952b83ac9840b6ba7f2e9c0981856f532187e8138590eacc35724c1459ecdad45f812043669141b80620910a89406bd08a3400107fab1395c400dad046bd64ddba3abfd86d7c787df1f9cbde7ebf3f98f8bbfdd9b39de9d3178783c3c1f3dd91653e6b34aa9d66ddc168341cc55150f64a861086340e0ef6bff9f6bbe16874e3c68dab57af6aad1cc779fefc99ebba4c2d8914222152bf7ff8dd77df95cba5070f1ef47a3dcf2b1d1d1d3e7efcc8340dc7713dcf755dd7302cc3104ae92c448f3c3aea8f46a3b9b9b946a3ced6badddd9ddffffeab8383fd72b96418c66ce6efeeee3090710a7bcff30e0efcafbffe7a6161e1533ab8540000200049444154c30f6f2589fee69bbbcf9f3f97d2b87efd9ad6eae9d327fff11fbf6cb75bf3f373954a15805ebd7af9dbdffeeefefdfbb3d9acd96ccecf2fd46ad5384e82c0e754c64f9e3ced74dadd6eb756ab26491c86611806070707cf9e3ded743a51747d6565c5711c21241144d1acdf1f3c7ffefcd1a347bbbbbb44fad2a5f5f9f9eededede93274f767777f83d86611845619244878747bffce57ff67abdcb97d7c33078fcf8511cc78ce35b5b5bcbcbcbffeb7ffdddcaca2a00689d208a2c887ed1d8716a3e87ef93e797d379928bce7c4d0d0469720000d005f6f756f2373c536792efade1a2337fba1a8af2b34f517c1127daaea0dbd389afd32c7d3f12c3fade52645eb9251e119592a60988a9373ca4e6580560e6ca269bb4725cc32cf6735e676e57660423009d284d5ae90485b0a40179e6d4ac491052331ea2d01a06835974186ab08461759bb566d50b75773c0b5ff6fc6f1ff701cdad5974d49bee1f4d7b47d3e1248871361c0e056881e83a8e94c6d1d1d1fdfb5be3f1646d75ad5a6d4ca793d168d0ebf56ab54abbdd61fb0babb1878787df7efb4dabd58ae3786161c1f34abbbbbbdf7df75d18069cae928866b3a35eafd7eff785107373dd858585c1a0ffead5b6d6fae6cd0f0000110683c1b7dfdeddd9d95d5d5d595c5c340c230882ededed9d9d9dc78f1f2ba55aade6783c7ef9f255bfdf6f34ea00b8bbbb3b9bcd5656563a9d4ea55299cd66f7efdfebf7bb4110082100c4643279f9f2c5d75f7f3d9d4eaf5fbfbeb67689d3701e1e1edebd7bf7e1c387474747376f7ee0fb53df9ff67abdeded574747474f9f3edddfdfe7ecea9d4ea75c2eb13218043ea702dddfdfd75a359bcd6eb753ad56777676fef0872f0f0f8f6edffe687e7e6e3c1e0741f0f4e9d3adad07bffded6f5dd7bd73e753d775efdebd1b04c1cf7ffeb96d5bf7efffaed7eb6d6e5e5f5959c32c2b25f7ab7c0f7e3612ce9a54e06239be56f2b6f253969ab3b69bb795bffecc3739fff567fe7435e019490e5bc42c4ae45951d3943082900881b2dd2839841d870b26cca8d6bbdab07e40c19c5465e893ba3b1468548e74227b3628e2545a51fe7cb9010f114120c88c5e8120210825a0c80c77a480b410c28ee2647bef60ebf1fecefe541aeefc5c756dad5e6bda8e6557cbd4a8fa8e492a0991c8b52dd394511452320dc3a0e4da9ee7588e0d00a3f1f8d5abeddd9ddd617fe8b8ee6ce6fbfe544a636565a5566b701c67b6df4d26d3eded1dc771d7d6d63637374dd3faeaabaf7ef7bbdf1d1c1cd46a0dc7715dd73b3838fcfaebbb0f1f3e745df7934f3eee74baa669694d51146b4d00696c9c384e86c3e1ce8ee1ba2ea78f6784dadada9a4efd76bb2d0406b3208ae2e9d4074029e5f2f2f29d3b779697575cd7a9d5ea9665093cce87c8417db8c11b8de6cd9b37af5ebdaab5be77efdeb7df7efbecd9335e27514af77abdadad07df7efbed70387cfaf4c9cecece6834dedcfc4029c56805004ae9e170381c8e0cc35c5a5abe76edead2d292ebba0707bdfdfd5e1cc71b1b1b376e6c8ec7635e3f7df56a7b369b5dbd7af56ffee66f10f13ffee39741105cbf7ec3f3bcafffe7eee1e1a1efcfb28926ed4385defa534cb45824026f20ff2397377fe48bcefce96ab808df09d2d53e1ebf08848448001a783d25b338e4a741b64048f910ff31181616ca9b9f59d41373c530138a3cb56a4178e292bc36210401c32f5bf21051108248b31002a6a9575132ea0108448d021115e9b11f3d7dd9fbc337dba349d26d97ae5d6bcfcf5709e5248a777a637fd4f74c6a2fb73fb8b634d72a87d361100da594d56ab552ad1aa6a1b5eef7073bdb3b7b7bfbb66537850cc3a8d73b9acd669ca3dcb69d24d151a4a2280ec3703c9e2845f57a736ded12003c79f2240c2321e4d2d252b55a1f0c8687878752ca76bb6ddb7692a8dddd7dd334baddeef2f232eb830050add6ae5cb9c2a6ab308c5ebddae654f244609a56b92c1b8da694623299188699240a08a4341a8dd6caca5aabd5048072b9ec7965d3b292442162922822300ccb304c4eb8bdbabaca96efc3c3a3e974d6ef0fbadd8e94e66c369b4ea74f9f3eedf707954ab9d96cefef1f44519c24c96c16f47a8796654a2947a3b1efcf94529665b7dbedfc770dc3f4fd404ad16e7738abfbf6f67614c5d3e95413b5dbed6bd7aefbbe4f444ad1d2d24aa351b71dc7f7fd384eb24ec4fae0f1348e98eb11984e5b2746ca1939db4f329e06e92ac64909e4923796634102e29825bc899cc40fad01fe6c6a3821cf3748e4727ede7c2022f2e0a59c6d71492bc1d4e255206e6fc8b08aa4e61436152594958beac9d9933853f044116928d19368780a1373f71f6e304ce1198bf68663ccce161b040248524a69886d47d61ba56add391af59ebee8f70e774a154b1856a492208afd59bcd8f6aeaeafdcbcb6ec99c9647400c96cae55efcccdb9a5120024891af407fda3be6ddb1f6c7e70f3d6ade168f89ffff99fbffffd97dbdb3bbe3fabd71bbc2d298a1240344d0b11279349af7758ad568efafd288a1617973efef813adf57ffdd77f4d26934fef7c7a69ed521cc75b5b5bf7eeddabd56a7ff7777f7bebd6ad52a9c483ab5e6f7cfcf1c7ebebebbeefdfbb77ef0f7ff88361581f7cb0393737675956bd5ebf7cf9f27038fce69b6f78d3b8269d24c96432393c3c64e0c8773b8d4693308cfb83fe783c89a228495418466118e641d4d8832149923856b3d96c341a4551349dfadd6ef7ce9d4f87c3a16559bc2774381c6e6fef68adaad52aebfea66946513c1c8e0f0f0f9bcd26222489124268ad47a351a2d4e1e1e16c160821a43454a2784704ef9f4f92442995281545316fed3af9de01a01032884efc5738ef3c3965f48c32dbd659c93bc8e9e411df46fec36ba034a7c09fbe06382be182d9cc915aa65222954f0327062f6146af78dc6aced8073fbd0debf87ecf292720e92c849da257c53321032f4404c8b7a7a4242af330e2c641c2f41f7f29a440444d4a485da958cbcbcd2056ae671decf5fdd92c0c51682242db30eb1d6fae5dbbbc5ceb5420f4273a1a7b8ed5e9763addaee37944449a4cc368b55aad56ebcecf3efbe4934f46a3d16834dad9d9614733c7714ba572b95ca9d7eb8d46fdd6ad5bed76fbe8e8e837bff94db552dddfdb5f5d5dbd7dfbf6e6e6e6e3c78f47a3916ddb9fddf9ecc30f3f24a02449eedfbf9f24a5e5e565f65a200240e2cd4fecb524a5b42dab52ad2f2e2e369bcdc160e0d84eabd5324d737979993d1ea2281a0e07c3e1f0ebafbf562a69b55a52ca1bd7af8751b4bbbbfb3ffff33f837ebfd7ebd9b6353737c7cbb58c17dc80ad566b6969a956ab97cb655ee76db7dbaeeb369b4dd33417161688a85eafb3df99ef4fc330aad7abdd4e474ab9b3b3bbbfbfa7541286e1f2d2921462737373341cbe7af5ea37bffef5d1d15110842b2b2bc16c369bf9a669f9beaf899acde66c1628a5c220ac542a9d4ec775dd62b66eb6609d54cf0a7f9df8e222f9fbf2472d0898672c6601338c22074b4d5640e9384646b86cf0e694faad6c58df8b6b674956819d9d0b5be79613279f7b0f9847e362a76d265144008a4053ce21d32f319f1f09851028a4364dc3b18d56dd81cb9d85b9d6741a47514220a4691010422c20911063321df68e741c945d6b7eae3337d7a9d6aaa6c9fb72707171f1679f7dd66cb72e5f5e775dc7b2cc0f3ed81c8f46428aa5c5c556b32911fd995fafd72e5dbaf4e9a777e238fceacbaffef087af4cd3aa94cb5f7cf1c5279f7c52afd74a256f63e3b2e779ddee1cbfbbc585c5abd7aed5aab5463377442220984ea74f9e3c79fcf8f12c086cd3fa87fffd0f1b1b57baddb9300aa2adf0e58b972f5fbd745d777e7e7e7dfdd2fcfcfc783289a260ebc1c3478f1e8dc7a3f54b97daedf6fff77ffedf9dedbd172f5e3c7cf8402b552a97979796eaf5fa783c595b5be544900050ab5537376fd8b6e5954ad7af5d5bbf748909d1dededefd7bf70f8f0e67337f6161a1dea8d76ab520084cd3f03cb7d56cd5ebf54eb703005b0f1e3c7cf8703a198f47c356abfdfffce3ff7ef56a7b7777e7974f9f11c2b5ab573ffcf0d6a54b6b5ec9731cd7300c29e5e6e66614459eebd89675edead576ab55abd7535b06020121e51d9fcd1eb9ba07054cc2e2c763794ebf29fbe3ac246beab790131dffe269aef17df21f5ec3313ffa53d770427e2c2120004d4408e2584e58e06284a410f0d8484f3a1fde19d3a21f8761bdfef23784a80bb5433c477402db18bc804864ab48c8bc0a21c7674c036aa5ed2aa494a66d52d98da941d5924b682a855a83260481511c87811fcec6c1743c1e444912945c6b6171617171a9d56c38b62da5000021c5eaeaaae779aee7359a0df645b8b4b666088340b55a2dc771ab95b2eddafed45f5d5d5dbfbcee4fa7bb3bdb87bd034db0bcb4f4c99d4f17171781a85eabdeb973c7b6ac92e7c5712c50cc75bb9fffec33db764a9e57f48327d249928461009a9697973fbb73676169110046a3e1e1e1e1fedede7034aa944a2bcbcb1b1b1b8ee3942be5380aa228dadddd23a22451ed567b6ebedb69eff8fe74d03f725d77616e7e6979d1b4ccd92ca8542a954a855bafd1a8dfbefde1d2e282699a8b8b4b0b0b0ba6615aa6258578f1e23969bdb0b0b071f972b7d3add7eab66d4fa753d3343bed76a55aad56abb359e0fbfec1c10122c671dc68d4362e5f6eb73b4a25e3f1c4759df9f9f94babab2804020461c83e7ab76fdf562a29954aa661dedcdcf483a0d56cf2b38bd4db050b68f44ee5ecd527d85a71be7dfd657fac925393537f9c909f96e005675e24ffe135e085d551c6a2d246c4c297e2d889148ea906a494ba5015be29c37a3d9ce5a8f11a4274de55df8365afa9e1dc1bd6401a386360b6ba00c073209206d200a448275a81462034a451f13cdb30c2300cc26816844112a944c54932994cc793711285a6948d4aa9b2d0aed7aacd66ab5aabba9ec7a971624d88d468352bb59a94d2342c4d8404b55addb15d4dca344d1482aaba52ad6a4d25cf0300dbb6373ff8606e7e1e34546bf576bbc38f53abd7afbb8e40e9d836110260bdd1705c0785b02d8b48eb2c367fa55cb975f3d6eaea0a0256ab690d00e0baeec6c646abd90ac3d0b1dd56ab655b36009886b1b0b0e8ba25dff74943a954aad66a80a2d56eddf9ecce952b57a434cae552b952360ca9b496286cdbd14a0380e7962e5d5a5f5a5a4244c7716cdb4114ed4ec7b2ec95d595280c0dd3ac94abd56ad5340dcb36abd50aa2706c1b00a4349616974a5e6916f8028557f22a95aa6199ddeedca79fded9b872d53464abdd12d20084cb9737a238b62c4b08bc7c799d082ccb46c4d5b54b8ab4e3d8fcfc4490e98269b8a094e5f08b6625420068b8480e90d26f021298769253128d4484e79c59942310e57220cd31d008334b10bb6fbf91fc4d6ad074fcb89c28f3acfcbc33f1dc332f92fff01a0af25c42e9eefd4c01224a9b1805698d84001a0138c39ed2a90299bfc0d4267d4cb07e98a7fb29b43a8b356f5fce31c79f225950444940442400124884ecc040707c9a20603f0f4494284d431b52820401866398dab1678194a87512a8384e200415533201353305d62aa54eab3d37dfad552a8ee3482938db33a0400289607ac6f1c3022080655b966d155bc9f34ae9d0d15a4a393fbf303fbf907fab951252785e293f8d5f946bbaaee7c2b1286dd572a55cae940156f21a54920881a669b65bed76ab9dcb8988480b81e572a55cae146f496b65dbcedada1aacbdeefd4a43da8e7d4244e47aaeebb9733077e6f4e333496b40acd6aad55af5c4d55a3baebdbab65a9010692a57cab9a4563b6e3dd3320b2d00e7cddea78404c08e59e79d2900205b3f3e969f9570797339822c320b3ce6146f2e7ffd99c7042533fe9c95bff9993f5d0d45794142c071c4090140169c4b097373169246144268c474b7ecc9218f399cbce35e42b800b0bef7c222249dbdb0805be754786efd29fe528aec2ad5a053f51889726c4644290a9b8c8510c2f24ac2b46ca7540aa32008c3284ec259a89492c22897cb25af522a976ddb14c7f7901ecfd0dfef7bf6f3b637e3d9f07e67aac9568fcf2fc230ce9523666b2be7dcc9bbc6147cb389eddc273d578e2237a8beae5036264e5d7df6159cd5495e2f3ffb430867dfecf7ca8b8b96c792b7955f782616e5e202f99b9ff9d3d520f0f4fda79293e7607a590afe12000065410219cd60529d7b51c2bb33ac53579da249e7494e235111ba0a9ff12c9c9d5a2b84026212d171d232803c3ffd997b108098242a886329b4062d98a4a629e90d325c81962962c3d69ea70d6108294dd30414b1863888a500e018ed0480a04923a2260d804824856496ab4903802612980e124d946e1d1252178329030946ab2c8c3211c96c0d54f34e62a2e355d12c423c0168a579a00b0e07ca3530647317c86c77a79641f2280d444c6f083342ca0c1e1065d67cba702d629ac484f15f67ea19bf1e28aa677c26133cbe3a53ff45aad6b11851a044e4e6cadf293f82404440de50c5af14f295a28cede4fcaa20399eeecf9c497cb39047ecc9521cf1f3f31d51a6efa1289e89441a411068ceaa7b464e220fe14f94b1097c2bf98f5e8306126f23ffe13514e5c5bb556c9f221288005aa02022910e3de43454e9512586212d29d231cc9d38f5b54c7bd18fece9fe5aec3b4639a2e3bfcf42db45d7e7b79a1f79110109047b6bb0fd9dd7060134e7e1128240240af67ac3e1c44761106ac1f1d8513000254a1381565a20080243a6295ad37e09a9710105922612a84923a0262d387c0d0a220221d21b63678b740c681eaa9c1d3ab515a000222190328308a4f0c4c0c70ec18ca8f908815c9e0222415e038ff36339c365a1e6bc06809481e20979264110201864526acabd0d51e48bad59f362f60e814181a8002c90aedda66a037060d6ecdda51e38880280873dcf38c433108394069d76f9acf764b79add70a1593209649237949f96c031a8e5724cad3317cadffcccd7c8c5dbd470eef9e7d6f056f21f5e432ecf72afa0d0d9390211480b81a40153d84295666901811845b163c946ad54293944a421f7c7d2b911eb47f3c33a833be7cb4f953326abf39609cfe356c74700a4744ece7a76ba4a48881a110d0384f463f56ce768f77084c2224444d03ad10c1352080429645a4fd64b884069a50048134a013924610a58442084009d0e7e38113b14ce7bafb9fccdcf3cdb777faab19a693d98031632f81674a28cb814ed476749cfa972ea64385903e3640a6d17dfc09b3dc20f6f8477819bf780f58e808579ec3c04040866b3b263aead740cd350bcef198972677004fc817e58a790a5f8271408517602cbcfc532e0f3f3c4f7999a875488b199df67f14e520396529a14b31e2944ceb0140148540207a3e0e9eed1b3eda1901e08038854122b5088dab64cdb341ccb900084a03509404d080441140749922842690080065ea691a009018150084c9d764fc3cd45f0f48ec79c5700a6ba5bca988e2590b2918c5c7d9f9ced7067ea3fc6119d3630424af68bf05440a113c69d33969ee265ec4048c06d99f1bd63a5ad7084fccb4c94dea438d908a71a87b2c7cc1ff62d8e67804c9c198a45e0cba110cf80ddfbe33178690281a8410ba4ac3d11411011a6de48ac82eb993fae79965df29a8d8ae68dbfa009b466a245446fc8b05e0f55799159e15894bc9ff9d4f9524ad33438946561c3731aeeddb22cd3b4785b0917ae2dbfbc6834cf2b978644890006002852394aa69ab01024304892c1343c1a47202d5e9c320d705ddbb10dc33212a506a33008c2305171a250208294422a0d9a30519a50130208911a103572584021804003bf09f68e4371726224819a0aa3eb0de129a518e9347502b0301db1402746ef1b00166436503a35fe2f1af3904974ce5f33083a894927100bf2bff18494d8e90033333a41c6aef00c601ddf46f12635a02ea22d12d1f163426636c1e2396f095859950088fc42e924932a421565efe7141b7a7f3c03f1a00b2d8999520200196069359bc489c269a012ceaf8e699087ec1fe22986957fc8ffc482f2752e90e55ff1b5f2644144264d273a310a4e4c915d8b457892d2e0f02f69be78214496df907f2ebf61ca22cc48f378d94ba2089308308d269c3e2911b70b8120104a9120aa96bc85f956a5eac589de3f38dadd1fecf5fa7e18274aa344298465d825d72db925208c952201866500625a174800a1181c73b31550b63e2c08786327102081d6041a340212a67445506e4b4242c136234c6d93849492112a1a88b811490301e7ff495f59aa0533cca5733e22105bb45394638ec4c6f2ccd6460273cecd8ee4e95f8802a540d29a23140b108528d3996248c87b2a88188734203ba3a76f368b1aa2331ecafd807500d41cec287da8dceecf12ca9a0788030561aa35f26ef734f008a5ab1369eb8180f454e2484a78823c221164da2d5f826cd965c33f1064e169310b81c99c3b534ac1e0fa81746e23252204914d25f4fe981ff3364710e90442d97044c15d8e3bab44248d89369596ecda957b606590c4e3fe0d18d6a96fb15072490e2b61180a21b2f075c4eecb3993925212511c474220071717598e68ad218e13ad4929324d8bc3b713519224442484e0c8e5f90d305499a68988711cfb533f0802d3306cd72e9552bf1ead353204109852daa6691a92a4704da3e2984bf3f56ea796106ceff5f70e8e76f607c389cf684f89f2e318941f7b8109502eb99e6d2904424c10410a02812421759ae3f9426776338606c149118934332e2905a12444e2f88244ec23c68e634c9701481088d47d8ca10c0835b1bd0c91b9210af64c100ad3b08584e99c25d28def6c1420365c42aadd20a5684180a91513412221df0301106a48bdfe30a7420225120840d28288b44010e99a1f12669047c4d5667ff04c21529ea332df4b4aab440414c780c53f9ad12638de01cb77253420a04652fc6c080241708649c6efec57d32549ca1ee18cfe9ba223a4537c0e58a918905daf51e7608c894a972b25a299ae59690da8095441eb7fcfb0ce511420a5a0024863ca917946c3b49390ce004b9aa66398c2304c2984d0993d3bdd749862cebb441c2d021665c4ca308c300c67b3194734360ca3542ab19c639cb30d2b0866e3712ca5a854aa8d46dd711cd33410c56c369bcd666118baaed76eb71cc746c4288aa6d32900789ed7683418c2204bee421901ecf7fbbfffddef5f3c7f59ad556e7e78ebd6cd9b7cab491213ebbfd95a934a120149a3515e996b749a5e18cdee3f7ef1bbbb8f5ebc3c04148d7aa5dd2a7b9e1547d1517f301a4ea683b127c26679a1dde8465a1f0dc771a20cdb0161f0c20562eaff46ec0e47a479d11f540a672ad14a219240938441208940a3e6c1cbcfa081144ff7a92282e92c0594410e37356aa5b5d2480428524e96cd3e19c9860c7d8855549199b311105010914e4fd4d9572980653a1aa4fd486995284290869480448a54a20834094489942dff0100a026ad898420c8f68331235244080a50f3c99cc891287dd68ca9e97432e51bd0400ca2e98c98b601fbd4b11f07206802242d78333f64b3714a1ad3a91c804003e57fe53f8d944dc244044488e934c10b5298a11a11290445a053a59a34697670d3c8df43e170fc39658be92ffeb51e79e6cb9356898cc913f71142603e4be964a639360341ce33582da4fc5dfdf0554266495aeb300c391533c754618dccb6ed1cb66cdb96521e1e8e767777e338999beb0a819c9b406b180e87cf9f3fdfdbdb2b97cbb76edde2040da3d1e8e5cb975114cdcfcf371a0dc33092246140648d9261eee183874f9f3e3d38e805e1acf4f499eb7a9d4eab5cae58a685d95a75d62fc932b0dd282dcdd56c9376f676befeeefe7f7f796f380a2fad2c2d76576e6e2e755be5380c7bbda3c3a3e16438762c39dfb2bbddd2683a1b0e4315c7c2300518ac9709f6ccd2bc650298542192942010048044301095a250a9440b9012008934521e8cb1407bd3c5071e7a40a009336702ad01c832d0720d4d14c65a694201021080b4ce2c5382a7350d9a3468240201a97698fe0052fad38c0f9a0089fb0d22a634510b205382619b1a304a009496421b12084502220652444c45521d9928b324a5b6b294e10169d005e7f314dc35a57bf51109538531b32d40aab6b2968d5a670a2c640a1d6627d3f16599129a1247c8931ae8cc30767c558a25a9e6c1e6ff7c3d48f3fd8b543154bc7784791fe81cce8e41f6cc98a082212ffffc577ee4e6ca0325a7f2632b47b1d110b11064eaf88d7f2fc37a3d9031c16160f27d7f369b0100a766ca5d3da7d369afd7e360e71c3ee9e8e8e8e1c387d3e9d4f727d56a657575d5b6ed284a8e8e8ebefdf6dbadadad46a351afd73737375dd71d0e878f1f3f1e8fc75aeb8d8d0d004892248a22c894c1274f9e7cfdf5d7c3e1b05aadaeacad1a86f16a7bfbd1a387376fddfcc5177f5f2e975108a5350128d29ab4618852c96e549d926b84a13f1c8d8f06932056d230ea95f2ca427373637169be2241cf66f341180ffae37036b32dc7b26da5a6a6480429500a903838331248504020011084222414d200d745d3204b40d5b34aae399a843bfbb36896086948294969018085a1c69e5a98bd409dbd806cd4814a94d6bad17416e62a5142dbbb93f1343110a440adb48184129104a56447a120ce0bc1da15331b4608419290351ac8b8005ba3080004202912a4aa65bbdd2d471a77f666813f732cac964d695ab3180693c80f3520a044916ec4c7d48086297b8714c208d2a782cc4c24504836fa10b1198850e44f9fa2ab808c28121a88a68124284e2056994e2828efe759d8ca74258419101080a0cc508a991d3545bf74490648a7263712d9d6004d0a98e009c02c1b00705a20d299caa9211d38dc6cacdc436e894b07484e43ff8a8f29b8a49202d49c9270773ca764dfbf09c37afd57acac2aa518b03ccf2b954aaeebe606758ecac6d01686a1effb4110b2552b4962df9ffabeaf1409217c7fb6bbbb7b7878e838ce6834dadfdfe74bc6e331c70e4744c330cae532a762e57b98cd66c3e1b0542a7df4f147dd6e77776fefbbefbebb77efbb76a705008ee30a61b0a5451369d086293ccf725dc3343189414a6119a66d5894a8288c7a87a3e72f0f5412564b966d99d55ab559af49d2a4943f0bfda96856ac30a1401368925250a28962d7958d9ae35aa656d81f47233f0202d7314b0e3952779b5ea356da3b98f67a611cc702b594484a4b5022b3425266862656f8794465688208828ddf3a2e79eec27c691aa89dfdc92c881d5b9254a0938a6754aa4e92d0d1309ccd022975b562972b4e92c0601885a132a51482121d6be2379708c13a2d68020d0a34a110060a891827491c87ae69ad2d55432d87c368328a1144b56c946ba5c98ca6b32489421208848addb84262000020004944415488a74300548abdedd95cc1ec292580ecac02909a0628c5484a690eaf9fe863c28219600922cb44d79428700a22d15a69623338669b6c0128dd4288c0cc8f0088b452c4d8220000040aa10190976a94062481c89b47629d804a3075c5d54c51193a5108440128b217c5f74c19434cad6ad9d227a46a4c8a93ef8ffc8633fe9b1ef08424ff1fcf2dd9296f65c3ca06cf317e312a7192d4388e0dc3701cc7755dd775d98ece7677cbb26ab5ba94726f6fafdfef0b81376edc88e31880e238dedfdf5f5858ac54aa9ca2627e7efefaf5eb96653d78f0c0f77db67f01401e520e0072b40280858585cf3fffbc5eabadaeae0d0783fd9dbdd09fcd75bb0b73f3526212c729bfd76cde50804a4a2d245896b00d6fbe5d9d6b543c2106e3f1d3a7dbe3f1e49b7b4f5aad4aab59a994ed6ebb7a65b57b7d6daee63906ea56c59e36bc20d007e324d6b110469cc4a0a35aab747dbd3ed72a87b378ebf1913f9d042148b46d53ba465cb2b1ec18235322908a95c2384934e8d8403205bbb183260021097924f3220a101291264542f2a0d240b121956b639ca08a93c00f85062db41449b55bb9bc569af8ba3f9e0e47e39203b579e7d24a6532a3c1b037f583b26b9b0645511c6b0d020c0443a021100c41404a91262d09a53450a0d2511c4e919caa2723300da95512e94418b25476a5269242ab242204d0422b3084619802114091568a8804020a34240a44d03a512a51a0b44021a55098aad0609828050090565ac78a54aa9f696e020d82d0926058d236481818699821290d5a29adb540128244ba4821d246434212049a34259cd951830443a6eab856a4925869a508c83484694a8190a84829051a38d52c02a944311b344c83771b49428d409a40e882f64b69902eb686653ed9901a07d98456a4b27f5d47068f0c41a828a1b4f5f8bfacfd2ea6586fc4b02e2a98b944254912862111315ad9b6cdf90419bf0cc3705db752a968adfbfdfef6f676bbdd5a5a5a22a27ebfcfec69341a55ab35218465596b6b6b9f7df6d96432d9dada0a82e0c68d1bb55aadd7eb99a6a994e29ca0beef736ccc5aadb6b8b8b8b8b80800beef3f7af4787f6fafdd6a2f2e2f5ebf76dd9032087c224af55344812811240280360cac79deb5cbf3e3e14485c9770fb60f4793c3c3fef6ee81615a6ec9736ca3dd2edfbab230fef8cae6fa5cd5b34b8e5b759d92391ba08e95262261084bca4ad9a85764a38a8109b50a965d091148106c19924812401018a04b16b855d3762c2053c5b18a3568428994faa868402412bca51d9104a4aef509ab754002c8402c3b46a7e9e8443bb61506b3388a5d4bcd35ad665df687d360329698d44a6279ae1c29391a0590248600c7846ac502091a0814a18624a6506b21846b49211189b4d25a81698992ed943c39f367933088c2c8b164b5623b968cc270e62b41aaea198e256ccbd41a558c714c1ac875504a93f993d2a41569ad056ad714d234509a8a308e35129886410061ac945602b46d8061494308646e29796105e3208983d03274b56408d308941221da269a0e0a9412094025a463452ab53d711c198d448601ae2da561092140cb2421adb40692521865690841a49344c7b1160865c7b24c0024ad208e359030a429a45009250a1295eab602315d764d59151cabc0e932031689051bf8f0aff598b700f329cc1856c64921b76165c690d751acb76358982e159f90e4b08799d768f1679864b102484449924ca75344701c476b1a8d86711c4b69cc6633e4956cc456abb5bebefef0e1c3dddd5dd334d7d7d7f9570cc398cd665b5b5bfffeeffffeecd9b3c5c5c59ffffce75f7cf105e7853ee8f57efbbbdfbe7cfeb2ec95ae5ebbb6b1b1de6ab7802008671a1488741fafa08cd96b4594d886b53257f77ebeb9b2d4f9eec1abadc7af5eedf68e06e3d1f4ff67efcd9fec3892fbf0ccaa3edffde67a736306038224001e4bad24ee4a56c861870fd9fe531d8ef0f7eb5f64cba1b0a55d71574b82e48200010cceb967dedd7757557e7fc8ee9e37330016e4eedafa6a598128bca9aeaeeeae232b332bf3935910d33488a3240d8370329e4ea7ef7efcde75074496299de702049151a46b0d67aeed7b35e80f0771d037049a687ea1e6a5c21242e719492388049145ba6e19ab2356371bddb98621339944a3519265dab62d20d2461b9d0312211a612b2dc018d752be0b716206131328b20422a12db1d3746fdde86e2c3784254f4f8767c7b124054a2f746a1fbe335f976a3818d72ca8b972b1512735dfb4cd781cd53d6b79a55b6fba499a255196a5fa6c909c0c13b0c45cc7afd7a44ab3c130194d75b351bbb6b6d86988a3c3e1cbe3703cd69d6ee3dab576cda183a3f1f1692c85dcecd5e6ba5eb3e903887e3f393a9aa85c2dcc79ddae2725e69aa2448d464910a68ec4f9397f7ebe6efb6e10e7fd7e60a198ebd63345cf5f8efac3d0b368aee1cfcfd59acd9a650956b84b5b4a2126a3f070afef202d765db09d71185948f5ba35df71eabeb025e4793e09d2fe280f13a30b16d59031124dd3b3163adedc7cddf39c343583413499c444d06a39ddb6df6c78644c7f101d1e4e81606db5b5dcab23eac924190e2303a2d5f25ddf0dc2f46c100d86499ce6045248591ea51200198412814e94079c150381b3c7877f98f9eb382c3a576efd3e39ac57923d364fcf3860409e53696a608ce1128e2ccfc659699a2aa53ccf731c3bcbb2e170a8b51e0c06dc789ee788d86c36979696e6e6e6c2307cfcf8f16834cab28ca5cb288a4e4e4ef6f6f6589d0f00711c4751f4f9179f3f7cf8d092f6eafafacd77de595ee9012bd78c06304ca58a603c240ad587a1244d0540a3eebdf7ee566f65f1fdf7d707a3e170181c9d064ff6c60f9f9fed1d9eed3e3f0ea6d34eabb9b9bada74cc70329d86114103103518c7b7da5d5f623c188eceb2c8b26d6137ebf59674649629a33519d04486c875e45ccbd548f36dd1a883d24280ebb9569e1b44506996651a51388e251dd7a017c5264df29a03ed8698047a1a24600c0a812805085b8a86672169610b933b5237ea9e459a4099ba63b5eb4e124804309a0442dd93cdbad419745af6da72a3567387c3204283751b00c3546b1235cf6e78560e668ca8b5a9d5fcf58d2541c9f397672ff6fa241b9bebf5e5a54e9604c361184ee36b5b4b5b9bf3754fa0c03433a1430d1fdd86bbb9d6585caca3006520c9ccd17178703812008b1d7761ce234b6a9d3a52356aeefa6a2dcbe1f46c72769a4b494dcf5f9ef3967a2ddbb552a5a228cdb5969244539a05df95627eae1e2b94229268ea3e2e2db88b1db7e109a5f4493f323ac8f32c51488464d01250b3b1db908b1d67beedd88e3dc53494aaee52a3eecc757ddf95ae0b02252a270b2ccb92db6bada5a57a140542a7bef4403ac2b26cd7a9d76ccbc224cdc3243704d2b2ce552fe71b3f1f0873813ec72faf906fff80f357725850eab07e371c564574664ba0545a5589abb14629cbb2388e1dc769b7db54ba04b2b4c806a59ee771e0f55acdafd76b4b4b4b51149f9d9d3e7dfa746f6f9f0ffed2340d824029b5b5b5f5d1471fddbd7bf7effffeefa328dadcdc640e6e7b7bfb3ffda7ff747272d2e974b6b6b600e0e1c3875f7df5d5e9d969b73b77eddab56bd7ae359a4d956bcb9679ce1a0c4de7b651a00de599568ad2cc1c8793e1681465586b75e6e7ebefbdbfeed8ebd3303d3a8deeed9e65f2c1617f1225599288344ba238344936180e26614c5e8d041028845ca263a121320406c12028228504889a8d49726d72ad3ddf5958684ee378349aee1f8fd31c9acddad252cb921806c938ce8cc95c57b69a5ead56d3460e29a5544b3016084b10a266b44604d05a8f86d193a76767fd895f93f59a3ddf6d74db35cfb54f87c1fe61f0727f90c549ade6a5497e7c3a79fcf4ecf878e0486823045176368af60e8664d4d27cd3f565bdee4c433309f22456a4559c9221440928901469a3c918e4b33604a54c96e69e676dae773656db93d164ff60d01fc461627cd759ee357a8b8d46ddc9b476a568771c296512a7599c21e9e9243a0bd2e3b3200e62d96b8336128525410a14484200a2b10438969806f9fec1e0f8740c40dd566da15d5fec341dd79af4236572c01cd046044b8a66cd751c29a53d9ce8c1d4504e4a1119f27cd9ac63b36e03507f10a6a91a8ee2d1386e36dcf94eabde708e8f87a361ec39aee73af59a6cb7fd46d39e06e1eeee5e1426ebeb4baee73d7d314a32bdbed19d9bab9d9c05466b36732d0e0391d8d792c814b6fd600034812e295909ddf1079c5fe4a77e0f1cd62c9d7a25db354bf32a82c5f60a61181251922458da3a701dd6c14b293dcf9b9b9b9b9bebeeecec6c6f6fc571321a0d9f3c79525d5a5c5cacd56a8ee3dcb871c3f3bc7ebfffedb7df6659363f3fbfb8b8383f3fef38cef6f6f6ecfba469faecd933a5d5e6c666a7d5ceb3ecf0f0d092726d7dc571bd56ab6949c16647280420e6ca445116273a4a741cc48f9e1c3dd9eb6bb4d7563bb76e2e2d2fb614619864b9ce94c984304bf3ad1b5b0bcbf3cd3c0dc3783c098344910400815218cfa6966fd5ad5a2e28cf6d695bd2f2089d20269390368496204483e8d7ec0ed49333757c347ab63f8e52dab9beb2b1b95073c57432cdb24c22d8b66359ae1012095c499e0d0220cd4d9a1953d80614960a93307bb93779b177da69c9edcdb9de427b69a92da4d83f8b1e3e1bbe7839a8bbb0b2d23104c371fcf0e9c9d9d964bdd79cd3d41f47872793dd67279e83ae67b55a4dcf77a67116c67a6a48a249149fe8e95c290960bb96635b4a83c9151923a5b06d0b142965c6e3e8ec64d23f9d4409d9aedb6c7af5ba658c1e0ca7e320b11c7b6ebeedd8b2e13b9131644c7f103e39181f1e4fa4319dba6734010269a372a50429a5b532a40d691346f9fe51b0fbe4541bf5ceb5c5f5dedcdc4233497363b46543ad2e5d4fa479767492a8d8595a685952388e653b969d13201a05ae231b0dcbf7ed5c9bc1303a3b0d068330cbf4f5ed8566ab66bb787c163c7a78dca8d536d7e7977bb5ee9c6739e2f4307cfcf4c428b5b6d1b36dfbf82c1a0ea385c556afeb3b8e64a6090b443a2a2d4f08a0b06e043e5b2cce0a1167f9883fe0bcfa037e7f1cd61bd26ccd8aed725dd7755d0e9d12862107234044dff71716167abd5eb7db0580e5e5e546a3b1b8b8f0ce3bef5cbbb699e76a3a9dcecfcf6f6d6db55aad9595950f3ffcb0d7eb3161ba7efdfaeddbb70f0f0f8d311f7ef8e1f6f6361f175e4acbcbcbd7ae5d3b3e3e3e3bebc771e2d80e0276bbedb9b9b6e37a9d4edbb62d3e07074400cc723d9926837158afb92acb4761f26cefe0d9de0992595b6a2f2eb42cc789d2fc78103cddef9b5ced6c2efdd1073babbd76188c86c3d32457207d8392802c41adbad55b68d62c3919d94198588ed56cd6fc9a3f1845e961926739a043a2385797969008a44c1aa771629456960420150791c9b256a7e1ba6e92ea388e9108c8d47d4b6b15276a1ae54a03a240d0440c508f1a65e139caea602185250931cd7594e4964003242c0160d23c4db344eb1a19a3b5ca559aa6b100698c0232008082c3d9f2ec31dae4a47344230402a2d6a4b29c941200ae6b3bae733698dcfbe6a0e14b5079b3e96d6e2d78352f8ad3308ce2603c1e07276781749c95d5c57acd575a591608895a6b956679921a32608c2d5113a82c8fc3481a54ca23630ab3560202db8043a6b25727322424d66a96e35bada69d67d1dec1f1bea09d6bcbf5463bcb3329a056b38c069d1acf26cb42146894512a4fd22c4e32061392961002b536719259522aad4010c7bde675408450fc82c2779289117b49b15f4e81394825674015e52a2de86986c9f8bfcfe9fcb3e5b05e975e59812544b669701c87b554e3f198eda4a4948d46a3d96cb2ae3dcff32ccb98904da7c1e1e1312258963537379f65e993274f38ee7196654f9e3ce136c330ec743a00a0b53e3838e06695524a293e8814421c1f1f0b219224393c3c8ae3544ae95856afb72825defae0fdbdfdbd384950a0405104b725c872331c858e251c9b6cc76db7ea9e2d8f8f27a3b3d0f7ce5cdf51a432954b21b6d7e6efdcdcd8d95874457e7a3a1e4f220d8e65d741d800680bf01dabe67b02649ca7a340d99e556bbab5869fe54a8a02d193415493241b8fc33c559da6bfb5be1064badbf6f2544da368388c6cc456a30ed2393a8bc7e3d81666bee375bbf52493a7e36c14e85c0b14168066b1132c69798e5bf75c1fa46d6bc249a80c284da2b7d4325a91c908304e72cb126bcb2d5792e74944aad79ce55e33cb5289e07bb6523a4d1411d53cdbb2c0e85c2b34066d1b8cd229a85c81635b35d7f15c99a62acbb521996b188d13adac4ed39e5f6cafaccd69c049180f2791a03c4d32a574a6b37e3f08c24c2be3dad2f3ad66c35b5b6e5b52e4696ed956142b14b2517756969b35175b4ddfb22c63c01812525a8eefd55aa012db768ca12cd7da1844614921105dc7ca0c1aa313a5922c93599ee746086c78b685a0128d68b22c8f13b424b65b3ea2f03c278e3369c96990fabedd69d7b7b7167dd7a9d7dd24d1e371e6d81ec77cccb3cc106a22cbb15ccf012194260384a5696fa1ae3af716e0032f0440e04a05d7204a33da7f129cce3f730e8b66d458b3d40a4b6110a080430882603a9d0280e338799e2749a2b566199035eefd7edfb22cd66a49291dc7d9dd7de2baae9482e30cefef1fdcbbf74d966549924829efddbb57afd785101c9714118f8e8e3efffc737648e4b7652c651418c5511004a3d1280ca234cd10856d5ba7fd93c3e383bfff87bf038446abbd75fdba00e03376811284359a26599634ead275bddbefbdb3b9b6311804c12451641c47226a21a956f7bbed56ab669b2c3a9b8c86e3304e05593e5a351416182309546686e3344ee8e95e707c32755d2b554002b334579ab4c13ca34c41a668320c0ff70740b4b8d8edad2d26ca1882413f3e3e1af5fbe9e25c5d5a4eaa457f981f1e05ae6d1c57ce2d4ad2348dcd38d028250a6948669aa254451965a473849c84462b2779781a9f0d2240b8b6d15d5eac9d9c8ee3d4bcdc1f76dafe8dada5c54e6d320a01a8d57017161aed663d4e5249381ce7d369aa8c6878b6eb629e51c347df716bbe0882388cb320508da6b7bcd0eab49d93d3f06c108d2679a359ef2d359617eb0ddfb26c717836ed0fa3fed9048c9e6f7bbd6e7b6915b28ce2548da74914a59e633baed5e9369addd6e25277380cb35c3fdf1fd7ebee52afbdb6dab2240820d0184499229365a434189208963622cd28ce945226497518e44a932dad46bdbebdbd5173e47cb799e6826802a41d09be2f951051948dc63a89f5fc9cb730df5ceab5a74136188449aaf60e27ed963737d7ea2db5058a69909d9e4ea3782aa54304044211a6ca885c2b039a20cb759a6a5d7a3e155e4d78ee4cc5ab05ce590684734f85732ee30f3a3fef07ba5802332500bf3d8775a97c96e0216285fac24784ccf8341a0d3e13acac1998e830cfc5f5f934d0b2a46559b66d475194a629e36121e26432198d4688685956ad5663c66d341a31b0df0cc6396f696859d6c2c2c2ea8a8d2811d01069ade2243c383cb22ce97a3529a52cf1798525c172923c4fa669a6446fce5e9a9bbfbe5127c22c53da6821c8e84ceb54a220a0e97874723c188d279996249a4236a5f0116d2134114d02f5e270128466ef38ea0f12db1624444e20414f238a336122b2c63acfb3fe497c789a788edd5e70daf5a60d3418464767e1d14996657643d9c3c024b99e84268829d7661ce9419027990e539319b0a440cb2232610a278334c94ca600a59da30c73310c4c106487c741abe12c2d367ddf0e22757a323d3c8ab496abab9d6643249112d2721cb75ef71325331584d3643cc9c350a1b49506a14c966b698966d3aad51da5cd7892c589ee34dd8d8db6e3bacf9e4ff68ec234a7b979bf3dd7ee2e3424e27014ee1f8f8f4fa65996b71b6eabe5d97edbab3949a2d2c13456e9243671a61ccf780d596ff9757413654d4ea7c3e3b8d582f5f5767bae0640c13409827814258e238398928c40580220d37238516825c6c060a42613ca9406a16ccb6b35175a35072d1106499442a648e6dab2411b4a7313042ab185eb51b36dd53ca7864e94c1340e8ecee228a3b59556b75d37da0ca67a38d186b4e345ae8799b17243838976f32ccd41038ea699468a53426101c802dea9f04cc002b9a104e481ea7c1098a728edb97fc80b4a7299c382b7b2747f0b0e6b965455dc56757385ff89888d46c3711c22721cc7755ddff7199c8f891195265a6c50ca060d8ee348291d87f5f58e10c2b26cd7f56a359f053da514d33866b500800d26187a945f00a840099752fabed76c346ccb3606a2308ae2285529119d1c1f4e83d82832c620000800810a410b8b8c09137d3608b3286d37fc66b3d66cfa9eef4a3451988c87c1643a8de26c1ac693284bb465d013b28eb286c2451480c6100e27f93499661964cad8ae23054e43fdf22044d05ae5da809599308ea44ce2288b722736f2c961723835841445593855b1b640d8c35064fba1d29464c6f11c29cd2854f9de48691d6799908882c1ddad69a49fbd9c90019581e3f81a6130d55116e6a9495243903d7e369412c2208d5222a24cc5e300a4d000e0fa721ae78350ed1d4e07fd4065264d75ae1109c6414ea0b4caea356a341ddbb10c096d501b1052b835cbb68422ca0d909049460747c1649290c138c9a7611627828c1d46e2f0241d8763615b5a5392646188a9b6738d47c32cc826ae9718c238514140698aa9ce73333dee27449466799666a44120e65a843159b62d484619ee9f2467c39c009254c7096ab206239566a1e724ae23884c9ca8f134cb34a53945319251790a9991790ec7a32c5463db96da4092a828822c8354e7899e1e0f13a375186441668cc16787816d6390494362ef2495d2c4a9d1068f4fc3c108a344096113ca42cf0200e72c166baf802a5f4204400651a9dc7a7fc8014a95df4cc96b2a7c570eeb1261ab0a2f5d657ea756ab753a1dc771d8be81f1ad5cd7751cc7f7fd7abd5eafd70bcae438beefdbb6e5388ee3d8b59aef38aee7b1857c8d71b1d832deb66dd775b1c4cf925763615d4da4d224b3a4239df3b057bb8f1e7df1c557a4010050b075002922b21c1496cab241900c0741cd19b7dbfee262b3ddf46c41c174dc3f1b9c9d0d8228cdc802b70eae8fe883f0c9f235b2979b208024268a330021a555ab5b48a88d194e32222db0c0c923931b204481d2cb0c0667893e0e00095158c216d245c469a626fd84806c69b9be8b48619a4fe298bf5d5a92100150a01d273a0a3309282d29a55464269199848985c2963249f5d3bd8931c692684b8928c3b13aee8f1d1bba1dcb72401d47a349faf260329d64ae6d3bb60528c96016aa4ce70446237a9141a109315740285345837166db94e4202c9b0cc58909c2d0184340022d69d996f0004daa4c32cad5205504c8588c68214a43340ecd701a01450488285008815694d0348a9431005a48900204094304204058420a044c34451305260300b64446c420d6d33066b47d00830c0f86825205c0005d02d022c071a007d3d068038802a5252580cc13338e42321a802c21a49080a23fc901404a5b20f6c71a490b2110c4789213100a10d226c0c23a060a3f692a55c858442cc2829821210299aae40f342ffbaaf85d21129508465cceeee585c9087bfe7e670eeb6dd2ec71000b80711c8761688cf13ccfb6ed56ab25a56472c642223b398f4623cb92ed76bbd3613c2c5b0811c75118865996d56a353e5b9452b2651600b05bf5ebde244de2cf3fffd5cbbdbd66a37debce9d6b9b459cd15c1943444c9bc154a6fa880052806d117886640ca4220a8f27fe706223983c4d129390af2c97d0126e0da52784076083b41410493668668735f6b735020150101843a6901a80e19588004122220331120188c27f96015009a008eb650a5854342034484404b4118bd16564162053ee410005f4007fa6002260cf5d148addf88400019a288ae1e42c15a33c49f32c23292d100eb1ff1d190d8cfa273305c3918e82d80026992690510a2ff6028162126a024286094506d332c051ae7856111a02534e54432050726427048da04ac58f118002d0308818f7151556e24480682416d0848640a3e198de02010a3406a222d28e0012fc1404d45000ed110a51c1369842a57b0e8f51c02c0b0402908055a43ce47182a2170bd82b46cb128086f154010a476860cc425e8ee5ff0888d534638cdf82b8e11f5e5ee1c3b206b0440e818264016bfba818211e2076682ff559c5eff234f66d4f095f992a05bc522a8e63220ac3300802630c435f254902000cb1c0f032699aeeefefefeded69ad969797af5fdfb62cdbf76b5996efeded3d7dfaf4e8e8a8d1687cf0c107cc8e9d9c9cbc78f1224dd3e5e5e59b376ffabeafb5564ab1161f11d936f59b6feeddbdfbc5f1f171abd3495496a96c697ea156af2549aa38a8169bbc12a1d10214f1db0b00db02cb028244c5c124069d3a0816829416d98eed082904481b50081464c8a062547c00623f416131d288368abd2b8d6341314c9a10c09204421068031a912c5ba0458c294ca038dcb714c69248046072a37959826b8902de4c13228131886001489b888c016d4abf689424889050027a36e802f24c03806d0b61031a50793e4933def91d4b38b655e0559106d01249b20b80a22853a13106d8dc416499393909c0004801888c2863d958202d10a1d16834020934c2020b091845c1180025482018290c4a6646d8d852230821a4c5be912018e10f4b552d03ff1100024a0b2cc9c749846490404a6349a062064a040164c81804633832370292464089807651c23e864404089645c8313b11883400ba16ffa191c091cc4b1904444b20083284a49174499b98ce32bbc55889082418f51a800a324954d664f0993fb8bc5808acd7a3026817094c01e00702043b3809ae4c99204b80c6e2e8150b1820a6665739acab3f7e6362ffc1e974ca348b3926cbb298268cc76321c4e2e22213ac3ccfcfcefa0f1f3e0c82603299349bcdcdcd6bbeef27493a180ceeddbbf7edb7dfcecdcd75bbdd3b77eef8be3f994c9e3d7b361e8f89686767a7b29eaf30fc9e3d7b76efdebdd178d46eb73737376ddb3e383afe6fffef7fbb73fbd69ffff99f375a2d14526b638804822dc997da6046a04c01645e402b0932121184b400245b302182140601d1183225a0abb4c870185136fe16c81ef90c9129a880b2244401a2024812545aa108284ebe0988004d81face6032506eefa53e9200a8f0f9a07223126ca6456415658c987d8e67c2411a78fc9897615e5b17bb190a1008120a575d32a0a1d2be102090214358086f7c344640a2e0518aa95470aea6985ac5ca2de12199f7401425c361b00022a5524a104584590486d58173161819bc3173e6000020004944415456b0d87c0178afe14e11888c6159e26c492cfcc609804ca14baae0c5a8ec3a2c1952c3bd5b7e5ac1a896b0b150020012a38c120804c9c36a4023338c1c06a96af91c09ac08d744608a69707ef50f3737c56f36f4e09e2c49180a0012cc3d903122f285eba022329ac094ffa090e5de9ac3baaad59a2d514a054110c771a3d1e8743a95a61c4a3c2c3668c8f37c32996459818795a6591846719c0020fb361f1f1ff7fb7ddff78320383b3b63ed3b4300aeaeaef23122abc3ac323e7b9224c3e1b0dea8ffe8e38f5656564e4e4e1e3f7a72ff9b6f16e6e78510b57a4d48a98d01a29a6bad2cb6c818400b40809485d201404849444210124900b66034445084f012c618fe0385202a4c0b8b501178bea5306781cc777088e0820e303f8504c451910167eaf376c4944754d0e3e5b68c8cad54d629b9eb6253e1d6046fe6c8248f4921b312a5a1236b854154129829684c412159d044402882b0028029d631572a246b045edea52e820a9a7d8160994249c137f2a5731d3454c411cfe5292c05778092b840e9060365dc8ba2c3010b0bc482a02018a08236219638564cc17927a0923a2395e17f8a778352b29eed64625c322a082516526f19f1c5cc0e7af19b23da72e82a269a458e3fe4450e8045ece172f21b12a2d86689b4d12a8d45b3ee2db63dd7b1728dc5512cff2b355bbf598775955a71618587c5660d6c85d06834d81681955600e0795eb7db15421c1d1d9d9e9e4a29efdcb9c3883459961d1f1fafacac349b4d96f57abddecd9b37a594df7efbed743a65b007229ac5c3aaa81500f47abd1fffd18f3bddcef6f6d6743a3d3c380ac370697171b9d71342e4794ea4559e93314dd77e6f676db53727a52584745c972324100047612f081020511138be88fc5c1223287b9f098ab8322a17cb67e7eeabef8219e275b5b5993a70b1fc352b01e0d2289614e2fc0a2f55aa546c172b17b483d9ad99369898d2e5e6f97a41740a827571e2cc343c5b521452f1acf265ae7e40d5fc1ba72794ece79547cc7c78f92517bbd4cc0ccd79095cee5e8e4ef8baa0a1976a5239aa3f10ac0bb999e9e122b4aa21210a357c9e673acfb234f55cbb53afd55c67141ae2c884056c3f13aab7401cadaee2c554112cd655f199208b7e1ce4a656abb9ae5babd5981e9d9d9dedededcdcdcdadafaf1b63fafd7e1004474747a3d1a8d96c321ed6e6e6e69ffcc99f846178fffefd300cdf7ffffd56abc52611c698388e832088a2a856ab799e57abd5d6d7d7d7d7d701208e93c7bb4ff6f70fbaddee071f7ef0de7bef59d24ae3088c063248e4d9d6c662572d762d0005a08dca95260eef2e983b9ddd9b8bffcceb49c95be4f05dea5f8dd9f9cad65edf26e0159a823384e8f222bf520857a9d8c53a3853072f5184d734f8ba423173235ecc5ff909af2b7fc3532e7ce32cc19ac9c5956e17afe95e31d3f9afabf33d06fd0f282fe33f8b927801110844ad8d10c2920d4f4a2a51df0dc00449000930e25c3180f8db9c12f2fd54b23f151e169491292a218e75e4699a8e462386976154992ccba4945114511961706969e9c68d1b8f1e3d3a3c3c647806962ef90892f1b05ebc78b1b2b2f2c77ffcc73ffde94f190fab3f18fce33ffeeae58b17beefbffbeebb3b377616161688284d6332b9008ef800c0a1560192707c7078c8c6a8ba10ee581478dbdeaf38a3ffebf3e03539bcf5ca79fb9aafcebfdfcc79db4700127cef4ff86d3fed87fcb7cecd95df8825b7c5db489ae69ee7ad2cf736d6d70516aa246108387871f9af3a377cb51dd6db4f3e46314ed334cbb22ccb2ad98d2dda95526cd70e007c989865192391c6713c1a8d88e8121e56abd5eaf57a9d4e270cc3ddddddc160c076f0c698e974babfbfbfbbbb9be7f9cd9b378928499224493effe2f3fbf7ef4b296fbcb373f3e6cd95e515ee266314225992036183313993d3701a0ecf0667fdbed1a620fcec06f68665794524c42bb203cc08036f6ee16afd575e7de553dea685b7bff7756ffee66fb950e7fb12aceff088b7a8f9e636af7eda6ff3941ff2df82600107af67b243044992d66ab59a5b5be8a6beeb02024a04827328ab4a8f85886fc3611553ff4aaa7c030180711a1825868858d1ce144a08916599effb6118c6715cafd71b8dc6d2d2126bd61f3f7efce2c58b4f3ef90400d2349d4c26799e5fbb76ede38f3fbe7bf7eedffddddf8561b8b6b606004288cdcdcdbffaabbffaa33ffaa36eb7bbb5b505000f1f3efcfaebaf4f4e4f5badf6c6e6fac6e666a3d1e020634a29ad74a17c2d1dffb55242ca5acddf585f5f989f07404de51106f7acc02ba2d955e5c5ebd419dfa9bcdafc2b1d2d7c97f22b25e7473350febe748c75b5fced6b56e59584569454d3649622c11bcb2fbec0a5067f9f9ff036ddf87d06e2773225deb266a54dfb8d2dbcaee6efaf85d9f24b25179f622aae48e4b9b26dbbd9685a966457162ace94800d120918be8709d56b7458afa45057091900b009bb528a253b0ef655c9866c9385884208dff719f4eadd77dfbd7efd7a188683c1e0e1c3877c8941af98f9dad9d9b16dbbdfefdfbf7f3f4dd33b77ee301e56afd7e3605f558aa2687777571bbdb9b9313f3fa7943a3e3eb6a4b5babae2ba5eb3d9b42c9ba8d0b781944a6914a2d168355bdddff8813fa41fd20fe9ff582202ad144a81020c01094128088511826678acefa3c36262c477092158ff9de73907dd9a4c26ac77f77d7f7171716565657e7e1e005656566ab5dacacacaad5bb7ae5dbbc62aadb9b9b99d9d9d4ea7b3b1b1f1a31ffd68696969616101003637376fdfbebdbfbfafb5fee8a38fae5fbf3e7b3858a5d5d5d56bd7ae9d9e9eb2e468db3602743addb9b9aeeb7a9deebcb46c65d83c934fa690edd4be83d0fb43fa21fd907eff89d8d3830809348166e8372c1c47a0e4b1ded6d21d6712ffc96c14c3b4335268100483c14029c596eecd66b3dd6e03004784564a31fa681004c7c7c75a6bd7757bbd9ed6fae9d3a7fd7edf755d227afefc39474b4d92646161812dda4f4f4f598bcf38f1151ed66030745d37cff3c70f1f26492aa4b02cabd7eb398e7dfbf69d83c3c324cb5b42721059004421d9bb8d3471cb442445250cfe5310fbbf67fe7b9e4eff1cd23f8561fa21bf94f332042021050a765b13c8fe3d4880a6543c14c4e7d598eef046a9902b30c11a8fc7d3e9948d1238542a1f0832ae5e9ee7a7a7a79665b19915a3213f7af4c8755d0e2491e7f9cb972fbffcf24b66d02ccbfaf5af7fcd6e83a3d1683c1e03c0c9c9c9175f7cc1a225872fe4b887ec9938998cc7e37114865996018294e2f8f8f8e0e0e0effffe6742c846b3b1bab25a1a081654dc8041b632c742c1517e17ff77213f37982ccc192b134a2443801c269e8c29da290070049e9b77b29d3b1b7c0a3445c4655344e2062443060c1962676f107c171546d8c57b940355bd6c5907cf5f97af96c6e6785ef5bc9d995f1716f3ccf05e2a989d0fb3c608df416bf59af2d7da68bd75f9776a01ca212e3a8d5e5df23dcae94d93e7adcaff79b450958399b15d992d2f9453fcd39c5bdf912103401ad8089a9769f18fb80e2f80d762ba5769b6c26ce295c9619f99ab62db2bb66f6086284dd3d3d3532cf1b0d8c1701621cbb66db68097525a9695a62963c373651603c330648c4098d924cb17032164b3d1e8b4dbb3368f611805c153dfaf6d6d6f591ccfb3b8858428dc3a4a0bf2c24b43e01b4ed0abe78a0bbf0110412209292eac70737e17d0b949341031b4bc38e7890850c8c2d3b1206d4294022c011648973053c21fc203cb2be7dc020b11cb69718160bd61fbb9920a825550c742735d7c9e28c91d952633b3f71413e3adcb5f59b32c2ca6f295f2b76fe1723922ca52715e998f5e29111cb8faadcb8b232d1e1a53967cd7f2b7aec9ecc8dbb4f0ba9abfbf16cecb4db16723078a2cda17e5523288c8ce5b053643398d5194cb52220964df3238274fbf8d0e8b55fa8c8705008c87e5ba2e2361715e21f93139635191c91957f63c0fcb08869ee771fbc61836e0e21222524a15735154870e748e1428a4949209168325b0047a76769666a95239194dd5ce48048c1b59724c457119e68481420c111b3a0800c60e61ff0f62f71d222842a15381873e93b4b9e0c3010064a80cf38cc068cd8864486983489625a1a0351cb11da9e0e3981d3a17faa8187076112cb572409573160f0e16be8ae7358a87165f0a70c552736606101119c39186665929e2c3d48a0a7c3fae6ab6fc95352f51d64be5975e185ff509affb347ca3e54755f23dca2beb627371b77bfbf27f1e2d54e5c6bc42c7726e833dbb40d805cc100ad4464b2900898cce33a5736d14430d40c9607d77b4062c1313ac66b359393c3349b22cab22460c76c5e58ee3789ec7e50cc6c0365c4ce9d84282454b3694879289fbdee9f1e3c777efded54af301030070fc6798f993ca1c1141c00ce59fd9e8f842c1a70814c8a031d2b284406d4c9a65799601a014c2711d29252218c2cafdad9ceb400086d8fc8b100583a12aad95d200c6b21d2184281f6e0a1a5bec39bc4195860054843a060076320684aa7eb5708987ac3866c019410e67f2ab23fc8a038e1fd20fe9f79d66b6c15aade1b975c7f6a4b010f0b7b274c7f2947056bb51113251a64ad3c4c25d1505fa95a9bac4daf4df92547162605222224325a70364ca7e29732a2d3f4c21641916880890880c94aef9ec1f4ca48d30c600816d4b00c8f2ecc5f3e7cf9e3d8be3746161e1e63b371616160085d106050290c4c2c8838094d65114456148447eadd66eb71160301cbe7cfec2b2adededed9a5f4389640c63491963b436ec23ca6e0d0005a757b0402c370a2144a18b2342c3382a05b54232450f088e4fcc5ffd2a4684efb0becb06f643fa21fdced2ccbceb76bacd66db753d1412085961f69b392c7c630200ad351bb8739889736e024008c140ec8cd9a094e2ca1c65870ffb187aa1ca99b7aa1ca7196bb4facd62e0a5bc7a223f5d6b2d500829002098065a6981a23c2564f551810a2f4a99bbcab120be88c8582a05212e382f53486dc5b717d4441d1f1dedeeee3e7dfa3449b2c16060b4dad9b9bed4ebd9960d004a2b6db4d606001cdbb62d2bcbd2972f5fc671bcb8b468db56cdafc551747272ecfbfef6f6368b8799ca841188c888a3fc2c22a335233aa19442b0145ce8c88c5679e9f120500096ca751433e69dc527cdce8e596d3b77052aa5d32ccbf3dc184d64a054bbcf3473657efdff4128c40beac81f0c47ff0f198e560eb997dd728d41146408cb85cce76980084427c7272f5ebc60673e402cd428bf8d2f21ccb05a7085b4bdf996721a110ffcc544d52b5dca5f995e510d677e03108199a949654cb9f39cf92fc1e8a458dc74dea4216380fb5714e0334cb186c3fedededecb972ffbfd7ebbd55a5c742793e9175f7cd1eff77ff2d34f977b2b5aab280cb33c8ba218089696163dcf4f93e4c99327676767ebebeb0245afb764b4f27dbfdea83bb6050059968dc763a594e3d8cd66d3753d0093e7599aa6499268a5a565d5ea35cfab593cba7c2e31992aad1cc7f56b35cff32cc9483966565424536aec679671d5ebc6301a358d46c3afbefaeaf1eeee6834a2427a2df5fa25e00b0fe6ecfdb383fcd6e5df83607dff165e67ac7fb104e8d5355f577ec90de02a26d4db97bfb1e63969b8b04fbf3e7f5dcddf5f0b57cb2f10ac72bf2f7bd294352b6d970121a4b084566ad0ef4f2653c77573f0be035ac3ebd22c6d12af4ad5416195aa3f4bd9d0e29f33f2a28588525a88f8bd392c4414428a323e059fca55dfc8cc16cceaa70a2d95c192ab2238e7a43837978831b2b04947474777efde9d8c272bababd7af6fb7dbeda74f9f7df3cd378787870fee3f188f46001845711c4741100821e3385e5959190c86fd7effe5cb97611832814892248a42d77594524ae5fbfb07878707799e7b9edbed7639b2ec60303c38d867a35ccff39bcdc6fcdce2dc7c1700c6e3d1c9c9c9743a35c6341acd858505d771846d97d4bb849d7ae35930532396c447e3d12f7ff9cbafbffa5a48e1fbbe310513fa5d27c90fe97798de8ec4fc53cea1b022aa0856e1b879a18e10525a96cab3e3a3c3c9643237bfd0e82e6ba30125afbd730eeb0ae5aaf86a7cb572962f97383355b752c9af5d5ee517ae9eb75995cd70355c192e955379f47585c362042b432418f5015102b370583158052f6598d300346418714d704e9739b5999c5f03183b9d88104929b5bf7ff0e0c1c376bbb5b3b3736d73d3f33dd7f53a9dceeeeeeecf7ef60f799eb5db6db6db30c6388e7b7c7cd2ed76a328ccb23ccbf2172f5e789ed768344e4f4ebffafaabe5e5956e77ce75dd2fbeb8fbf2e50b56ead9b6bdb1b1b1bcbcf2e2c5cbcf3efb2c08269b9b9b8d460300373636de7df7669eabc78f1f1d1d1db14cdd6c361145a7dd711c07800c430ecdcc78284f13afae075320e0c37412eceded1b433ffdb34fb7b7b789406b5d6a15a9b4adc0d74f8aef99a852a30140799ef0d6f7d25becbb17ce402ee5f02aa20000174a5e871ec13cd7dbd47cdd5d174f33f97d184a80398072577e8dfd4da15f7dc5532eecebaf7d7fd446733f167896e7b085e73d73de1b80860c00cc7009a22a47447e73e43832a678c3d25197bf5a109fb49ef359a0b4b12c29501a9ddfbfffcd836f1f24699eab2ccb52b26da66e9739ac8b140670c6577af6eaabea7f8724040a71e1cf4b57f92142945aa4e241e7a61cb3e59c953fcedf903557a50aab6c84cd4310d902a4e4b398e6d22bf3a2ea0c9f82885aebe170747272d2ed767776765aad1600d46af5f5f575a5d47ffdafffcfe3c78faf5fbf7eeddab556abd96eb75dd73b3b3b7bf8f01120341b8d76bb3d9d4e3ccfb36d67329ddebbf7cdf1c9e93befbc53abd55ebc781904d35eaf1704c1e3c7bbc3e14829bdbfbffff0e14344d8dcbc96abfc60ff30cbb256ab359d4e7ff18b5f9e9e9eacafaf2f2df55cd7d3da149d052804cfd762518b2b6785b34b5e8862522aa5d2345b585cfc57ffea5fbdfbeebb6f412e7e483fa4df71dadcdc703d6ff7c9d39361a8959276115df09cc39a658eaecce8822d9ae56bceafcdfc3943ce58ec34e53f0d607161c9e81863340352710563841048c4f15619268d592dac1e523e7df64d781310a5d5d2cc2b5de4c7aadb67f8a6926fa3cb8aab8b399f1b9aea1186d01893e7599e6788e0baee6c87b8ae1b04c1e9e969afd76b369befbffffed6f6b614f2fefd6feedfbf3f9d4edf7df7e6c2c2c2eaeaca071f7cb0b1b139180c2ccb9a8cc72727c79d4ed7b2e43befbc73ebd6ad172f5ebc7cb9777c7cbcb1b12e04cecfcfafacf43efdf44fb32c1b8f26711c4f2693e3e3e3ddddc783c1a0d96caeadad753a9d66b3c1c71d884825d058d519e5875f4e97385646497fab006b3fa41fd2ef21496909e4082308044885b0f4061d165dfc7da1ce2c2373a964269d336800c0fc51c53d55ff2e165ea8c01cc16bb8aa4b791519872a11b57a4ee90453d86131d80e945aaa733bacd7e4b35fc449205a96c550398c9ebabcbccca0cc59968d46a38d8df5280a3b9df6fcfcdcfbefbfffde7bef01c0743a49d3e4e4e4786363fddab56babababefbfff7ea7d3d9dfdf6b36ebd3e9340cc37abdd66c366edebcf9c1071f789ef7b39ffd6c329928a5eaf5dafafaeaeddbb7fee44ffe64381c3e7cf8703c1e6759eaba0e634cb387f9743a0982a931950437abba7ab5f6ead208028010c2b2a4d17a3299306f9f6559e57c5e55ab085cd52c97bce129b3352fbe5bd166254ae08c3072b585ab57675bbef4bb7adb37d4e7eeaa883bbe4a54e4f2d9a3f0d795bfaee69befe2c4efc0cfe5f8c188c831894519f67cf6aed217efdc68f1ea732bd8162184d6ba5a26b357f33ce7e7562a636ea7baf7523b6ccbad94e2e7566fc873402975e9cd675b9b6da77a5b7e07566413d1783c89e3582955acdff298f0b73a257c65aa5abba46f2ad9aba24ef5cc19cdd4252e60962dba705608973902ba5879f62974a9e6c5bbaa93c4d7f15617382c3eaf659e4e4ad9ed769796968c31cf9e3df37dbfd96ceeeded7df3cd3783c1e0c73ffef1c2c2c2c9c949188695997e65d5c1da222ad91fa5f234cdb22c574a2955d87f400982986599524a08542a272a905d89288aa23ccf3737377bbd1efb84efeeeedebb77eff4f4647979b95eaf530906fb663a75a9afa0e4b088f052bfb1f14a657ac297d89c65b69dea1296aa8d4a17c36fce0ea1506a671091cf642ad0472c5debab05508de92cc1e2a542440cfd5835523d1d4a350ab75359de54140a00d8c59557a9d63a4d53284f7b2a82551906f2b32ebd09942a022ee77b993440490479c2f0a379314369f783881cb880df81db17420441f0e0c183e9747aeddab5adadadea13786173539758605da66a20d84288c1e968e6b48a2b30f1e2873e7ffe7c381cfabebfbcbccce0e6fc888ac031b9e1d688683a9d4e2693e17028a55c5c5cecf57adc39c69820089e3f7f1ec7f1eaeaead6d6160f2b9b2c108014421b232e122f28496435a9aa05a2953246cb728d7fb753c2cb9cc65b6bb58460e646547f5e4ab365d57c2a6da62ee5957669f6f7656ee8ea9b5425c55a9a3913bc3aff66f3f2b5798615e552cad5d5d5dbb76f0f87c3fdfd7dcbb25aadd6b367cf1e3e7cd8ebf53ef9e4935eaff73ffec7ff38383878f0e081e33852cad3d3d3d5d5d5858585eded6dcff30683c1eeeeaed67a30185a96b5b4b4b4bcbcdc6eb7a7d3e9f3e7cf5dd73d3838705d776565a5d56aa5692aa595e72a8aa2344d2b7782b9b939cff3c230dcdfdf8fa2280882308c78b0f1e2c60bbf8972cd8c23f292af5632afba288a068301fbba773a9d5eafe7fbfea546e822834357789c57be03fb9332607f96651c8bb7d56ab55a2ddff7c51bad88f33c1f8fc7c6986eb77b4936e7378fe3384d53adb5e338f57abdfa222622ec539124491004a3d188bdf7d901a3d56a75bb5dae507d0bfff936899985ab9dc3ae6c97ba2bcff3c3c3c32ccb3a9d4eb7db05807ebffff5d75f9f9c9cb4db6dee67a644ec5252f5277fcb743a0d82a0da1d99d0789e373f3f3f373777f59d6986630200a5d4d1d1d1a3478f7abddec2c282effb554ff27cabbce5aaf2300cc7e3f1d3a74ff98b363737ab96c7e3f193274f8e8f8f8510376fdebcf444fef39563cab49bab55db8f524a29258de165febbe1b066b7c199413ae7aa2e4de257b5f05b7258951515db5915318d6926bdeaaeef9657f7f2c6b8b2b2e238cecb972f9f3d7bf6d9679ff190743a9d3b77ee6c6d6da569ea38cedededee79f7ffefcf9737696fcc94f7ec25489c10bbff9e61bdea93636363636363ef8e00329e568347afaf4e9cb972fa5941b1b1b6b6b6b2b2b2ba3d128cbb2f9f93900e03dad56abcdcdcd4d2693fbf7efb39184effbfffa5fff6b3e46ccf39cb7f4d9de7e03c9b8c4c870aa763c224ad3f4e8e8e8debd7b5f7df5d570387cfffdf7ffe37ffc8fd7ae5dbbd4daa5ad4b2955ad169c915f2e25066bdcdbdb4bd394b9c576bb7dfdfaf59d9d9dcac3f40d8997baeffb572b13d1e1e12157585e5e66d91c00aae873fce7e3c78f1f3c78d0eff7932461d4c94ea7c3486d557db818b1e937a6b7e103aa3a4110fccddffccd7038fcb7fff6df32c1caf37c6f6fafdfef5795b32c63fea86200ab70c2cc5c9f9d9d0100bbca6559d6ed767ff4a31fcdcdcdbdeeb915d5b02c8b419f388ecc2cdd6790bb3ccf1b8d06a345716ab55a88c810c16118ceb6ec791ea3995fbf7efdea13e9f54a838a8524220066af749665699aa29d6aa508cc77e0b0decc58cd16be8abdc28a7b2a0b71b6e0d2412116477eb35cd51b382c33cb40552f76a5c10b1cd6dbe7b34a31fecdd3b7d96c369bcd7abd1ec7f1e9e96910042b2b2b77eedcb973e74e25e900409aa6fd7edfb2acf7df7fff8ffff88f37363600e0c58b17676767e3f1380cc356abf5a31ffd686767e7c68d1becb37d727232180c1616166eddba75fdfa75d775f959ed76dbb22cdff7b7b6b6b4d69d4ee7f0f0707f7fffe9d3a7beefdfbe7dfbdffc9b7fc38b364dd36abfba44865e37dc6fee3796e3922479f1e2c5e79f7f1e04c15ffee55f226296656118f2b36cdbe69a3c29b984e18658e49152b2845bbd12bb910e87c3afbefa6a7777b75eaffbbecf52210b232c24b2373b1beb41c941f0d79d9e9e32cc7fb7dbf57d9fc3385119d39771229f3c79727878c8f06a376edc701c873f8d37f0e170f8f4e9d367cf9eb13cc892bbe33861181e1d1d2d2c2cb0085c5daab8b359f1aa12fc2b27b3cacd83770276e740c4388eb95008916559bd5e775d37cbb25ffffad7f7eedd6bb55a6b6b6b0cd6848849921c1c1c0441c09eb9dcb1611832a96a341afc567b7b7b5f7ef9e5d9d959ad56eb743abeef33e9e79e574a2549c2c2af1082593c6e9cbf224912561831d3c407d05c6d32999c9d9db14cc71c1637bbbfbfbfbfbf3f9d4eb91a476fe0d80e7b7b7ba3d188878fa70dbf0c3b1a5b969597094aa475463a98a518bc82f8cd9338966ea6b54680efcc615daa7f6967bec28c14e771f4d6a952ce412989e08c9e124adeb27a101606b5a559ad3100acada7df158755e905ab92d91f9d4ee7bdf7de6bb7db5996f1515da5c1751c676d6deda38f3eeaf57a52caa5a5a55eafc777cdcfcf7ff8e187611856a3d8ed76793e31850ac3b05eaff3c11f00388e333f3fcf8e96b66dafafaf23621594e8e6cd9b8ee36c6d6d552c46a51f99fd96d791aa4b3d536910664ba494bd5eef473ffad1743a7dfaf4a9d69a57e3af7ffdebafbefa2acff3f9f97966eec2304c92c475ddf5f5f5e5e5e5f178fcd9679f254972e7ce9de5e5e5a3a32336f4d75ab75aad9d9d9db5b5b52008fafdfe743a5d5959d9dada6216f2c68d1bcd66f3e4e4e4db6fbf7df8f06192249d4ea7d3e9f0272322f302676767f7eedd03805aadb6bfbfffe8d1a3e7cf9f23222b5096979799a4debb776f3a9d3e7bf6ec2ffee22f3ef8e083a5a525d6133d7efc787f7f7f3018acadad2d2c2cd4eb75fe58dff711f1b3cf3e534a7df4d1476cde319d4e7ff18b5f3c7ffedcf7fd8585055efcaeebc6717c7474140441ad565b5d5d5d5e5e6e341a59969d9e9e1e1e1e4e26131ed63b77ee10d1dffeeddffeea57bf124274bbdd2ccbb6b6b67efad39ff2427df1e2c57ff92fff25cbb28f3ffe1811ebf57a1886fffdbffff7e974fa2ffec5bfd8d9d9e135fc377ff3370707071f7df4d1a79f7eca048be951ad565b5e5e5e5858a8d56acc61351a0dfec6afbffe9a350cabababdbdbdb7373734aa98383837ebfcf50bd272727c698478f1eedeeee3a8eb3b2b2f2eebbefaeadad4da7d3c160c00b33499267cf9e3d7bf6ece9d3a7fbfbfb4c8376767694528f1f3f7ef8f0e1fdfbf78320504a9d9e9eb65a2dcbb24e4e4ef6f6f698fb5b5e5efef8e38f373636f6091dbe400000200049444154f6f6eedebd7b7272c234cef7fdf7de7bef830f3e989f9ff77d9f0add2e226296e761142649ecaadc18ad95fecd1c1622ccd6b9541fafa45716be325de1b92eebb0aa9ccaad4c5c8497297f0396f104890a66ad7ad3ab2f06df91c3ba7457c57055f1cd3637372b19be12a33ccfdbdadaf27dffa73ffd29c7d160bac0c1cd6ab5da257cfaeadea5a5a5a5a5a5d9429c517cf087b3d400004cd42eb5c0aa56ba2200969ac1cb3cd7a591ad6e99652dd92a9509eee79f7fce1c9f94f2d1a347fff37ffecf2008e6e6e6b6b7b73737379bcd6692245114c571bcb0b0301e8ffff11fff314912a65f6767675f7ef9e5fdfbf7c7e371a7d3f9f4d34f7ff2939f308522a28d8d8df5f575dbb67bbddeeaea6a18860f1e3cf8f9cf7fbeb7b7c7755aad16c75eb26d7b797979757575381c9e9e9e2649d268343ccfbb7bf7eef3e7cf9bcde6783c3e3d3dbd76eddafafa7aad5623a2d3d3d3172f5e1c1f1f73b05e0088e3f8c18307cf9e3d5b5f5ffff0c30f6fdcb8312b0d1d1e1efee7fffc9f0f0f0fbbddeead5bb700208aa25ffdea579f7df659b7db65d86e46f71e8fc7fff00ffff0fcf9f3b5b5b59ffce4274cad767777bffcf2cbbdbdbdc964628cf9f8e38febf5ba94f27ffdaffff5d77ffdd7ababab376edcc8f33c8aa2b5b535deb76ab55abfdf7ff2e4c9b56bd7daed3653cfdddd5ddff73737373904e76030f8f2cb2f9f3f7fbeb2b2528d8e6ddbad564b08b1bebe3e3f3fcfa15838081e2ba798fff23ceff0f0b0dfefdfb8718388befaeaab274f9e341a8d959515963479e740c4f1781c45d1d1d111e3d6d56a3596f24e4e4e8e8f8f8f8e8e8e8e8e58658188878787cf9f3f7ff6ecd9eeee2ec73fe623a9e170f8c5175ff0081e1d1d6d6c6c70a8f6478f1efdfce73f9f4ea7beef675956abd5e238d65adfbe7d9b1745b5e898b9cef2acf469a5df8d0e6b7655d005cba7b2ec8a06aafcf3bc72a5c00298d564550d560dccf24a330f28cf1138f11b957f998b777d4f1d16cc1cfa54075897d487a23c39eef57a7ffaa77fea38ce2cf5c1198300bcb24fbc722c2eed10bf71b05ef98157cb5f79d71b6ea9de99b7130e912b84e06022acf5fff2cb2f7ffce31fffd55ffdd5dcdcdcd3a74fc3305c5e5e0e82801168992142449eb5bbbbbb2c1e2e2d2db1ddd9dcdc9c94f2c58b17ac16f13cefe4e4e417bff8c5c1c1c1ad5bb7b6b7b7ebf57a14455f7ffdf5e9e929fb8adfbc79f3f4f4f4abafbe7af9f2e5c2c2c2fafafaeaeaeae6e6e6f5ebd789e8cb2fbfbc7bf7ae949259b98585850f3ef8e0f6eddbad568bbf4b6b3d994c58ae69b7dbb3ea70feea288aa6d3299348004892643a9df2d1d86432b16d7b616161676767341afdec673febf7fbebebeb9b9b9bababab83c1e08b2fbef8ebbffe6badb5effba3d128cff3b5b5b576bbcddcc7a79f7efae9a79fe6793e180c0e0e0e4e4f4ff7f7f75756566edfbefde77ffee7dbdbdb0c2cee38ce8d1b377676760683c1dffeeddff2219deffb376edce0e09bd5ac03802ccba6d3298be14288344d59941e8fc76b6b6b9f7cf289e338f7efdf7ff8f0a1e338dd6ef7f8f8783018bcfbeebb1f7ffcf1fefefe7038ecf57a1f7ef8217b833d7cf8f097bffce5fcfcfccd9b373dcf9b4c26df7cf3cde9e9e98d1b373ef9e493c160707878c83146bff8e28b344d373737ffc37ff80f699a8ec7e3c3c3c3300cefdebdabb53e3c3c3c383888a2686f6fefe73ffff9e3c78fcfcece8220d8dedefef8e38f59bcb87bf7eefffedfff9b8858edc582a431fcbf22a3c9683e33fc9d9d125ebdc4d7012e732bafbc0b2f851f631c94f3bc2a810b3915607baf7b8dd936e10a13f196797557c5a140a9cf82f25c7fd69c842f2d2c2c70400d3ed6c5f26c9195d02c52cdea7d67896075323d7b15678c6b2a7b858aa654ed5734f1d258fcc6819efdcc4b3d5971be00c0cb603018eceded31c62ccb2f0f1e3cf8d9cf7eb6b7b7b7b8b8b8bcbcfcf5d75f3f7ffefcfefdfbf57a7d7171b1d96cd66a350ef5363737f7c9279f341a8d070f1e0c06837ebfffd1471f7dfcf1c7a3d1e8f0f0707777f7e0e080d7eacb972fbffefaeb5aadf62fffe5bffcf8e38f01e0e8e8687f7ffff0f0b0dd6edfbc79f3dd77df9d9b9b6b341a4c533a9dcefafafaad5bb7de79e79df178fcedb7df7efbedb7abababb76edddad9d969341a7ff1177fc183c2c9b6ed46a351afd795526c07d768340acc80190e9a0f0d01c0f77d8e3ace3a9776bbbdbdbdfdfefbef0f874396bfae5fbfcea24d14452f5ebc383c3c641279787808007c0429a57cefbdf7feddbffb777ff6677f0600bffce52fbffefaeb6fbef9e6d9b3675b5b5bfffedfff7fed7df98f1cc775ff7baffa98fbdafbe2ee724991e22d8a52245bb66007c6d7b163c346022301f26bfea2c04002e41703410e20010c044162c4dfaf115b8eed28b22e1ee2b15cde7b5f73cf7457bdef0fafbba6677697a4244aa6681616b533d53dd5d5dd559f7af7fba337de7803006eddba55abd57cdf7ffdf5d7cf9f3f7ff5ead5b7de7a0b11474747e7e6e6e6e6e684ba8198ed48da97887a370882d5d555b9e8b973e7befef5af03c08f7ef4a36bd7aeadafaf572a15c7712a95cacb2fbffcda6baffdec673fbb7af5eaa14387fef88fff5868f61ffef0873ffff9cf5badd6f1e3c773b9dcf6f6f6eddbb7abd5eab7bef5adef7ce73b00f0cb5ffef2c18307b76fdfbe78f12211bdf1c61bdffffef701e0c18307fff55ffff5ab5ffdeafdf7df0fc3706c6cecb5d75e13a95ca3d1b875ebd6cececec4c4c4b973e7fef44fff5416d1d2d2d2fffccfff4c4d4d25179a4590c41405c7b23070a0aa08000c466e3183c5ec29c936b10a215236bc0c002a152aa5acbd094706231a4056bb88781524881a6696960196d0f4acd1fa5a3c8fb4d6b1c59379521456f2b7490d5ad2c007127c99050899a6f65716533896d90d7c4d5ed1f69004ac6427f668127af6eae32c7dc40921e0c0a5f792601c5b0c59059948916edebcf9939ffce4fcf9f3f97cfe7bdffbdef0f0f03befbcb3bbbb9bcbe5f2f9bc98688836607474746868687878b8d96caeaeaedeb871a3582c7eed6b5fab56ab3ff9c94fd6d6d6648f1d1a1a1a1a1a9a9f9f1f1b1bfbdffffd5fe14d84073974e89098c502402e976366c771262626840d8f671d8bc3632e971b1f1f0700516909011504811cb2fdc8f311de737373737d7dfdf6eddbc273d94dc2f3bc66b3d968342ce5552a9524558af0a4227193435a6b116089cc5164f0b3b3b3dffdee77bff18d6f6c6c6cdcbb77af5c2e6f6c6c245dfa21f6ea97a49c9d4ec76ae24441e138cef4f4f4dcdc9ce80ddaedb6686f8e1c39227cae5c5a7644c9a137363626ec61bbddbe74e9d2dada9a522a9fcf4bb7a9544acc5fe476643b11f34e00c8643256ccea388e80b81da4ec37d69665686848d2a74b8873cb4dcbfea4b55e5d5d4da7d367cf9efdc10f7e904ea7ebf5faa54b97de7befbd4b972ed97965679a685706667efc8101125973f63ba3af703fb7b5b7c8a6b407bbb4d6a4b5268aecd962eb58524a892628015884087b004b44ef0a008c09e140c0ea59c40931ec388ed6a1b54949c4c3fa541496a5aaf63d27497fd9b1097b285cbd491852db9fd81eec2bb44739415549bb7d3503b49e6554f71da7fd55f25e927711bfe2be9b4a7628bc86acb49d9d1d11afacadadddbe7d5b2c77a6a6a636373745bd25228f63c78eadaeae4a7aa413274e886e545aa6a6a6464646464747af5ebdcacca9544a74eac26366321999ee8ee3e4f3f9c9c9c9743abdb8b8288bf0f6eddbf57a5dec1b256b6fbd5e97d86ae267bebcbcfceebbef9e3e7d5aa4c8939393a3a3a3aeebb6db6d31eb3d7cf8b0445e43c4542a75e8d021a186565757efdcb92320280fb05eaf97cb65a10b2411c1f2f272bd5eb7137e787858446f924e45f84a59db22d9cce7f32fbcf0c2cccc8c90dbf97cfec68d1bbeef6f6f6f6f6e6e0ae92d885028142627273399ccd2d2d2ececace77992e29388d2e9742e97ab542a854241724d89be38f91eed788e1e3d2afd4863a3d168369b42ba2e2f2f2ba5447498cfe71dc71170145a4c16f2c6c6c67befbdb7b0b02089dcc56c9099459f383232e2799e68b78580dddede16c1192256ab553188bb79f3e6caca0a114d4d4d8d8e8e1e3f7e7c7676566b2d3275d1246c6e6e4a4a4091d369ad45413c40d123f6628dc8327692a490ddc663544b8a5d01227bc2de32905e84bbb156b6441886448461a810210814220641c42859c51f1189324a2962d644a44d2835c606012aec0599516a30a40c2199282c341329894c606919adc320104d330dc0317f1caa2a595bfa2809ebf6010a3b66774e8aed77e5c126d7bffdaded79807ae20443677f2e3d5b64b15b853c7f51204aa39c9f640fa19f6eb25409f46f446297606fd6ee781b1b1bbff9cd6fae5fbf6e8c113ae2c5175f1c1919d15adfbd7bf7debd7bb95c6e7171f1c68d1b737373621c70f8f0e1959595a5a5a5300c5f7ffdf5a9a9a92008363636d2e9f4ddbb777ffce31fd76ab5f7de7b2f9d4e1f3b766c6565e5bffffbbf979797257076b55a1d1b1b3b7cf8b068e26eddbaf5b39ffdecedb7dfae542ab29fe7723959931cdb4fc84a68369b4b4b4b6fbdf5d6d8d898d8fabff2ca2be7cf9f1771d8e2e2e2d6d6d6891327ce9d3b275498526a7c7c5c24d6f7efdf17ed0133e7f3f952a9343c3c7ce1c2859d9d9d5bb76efdf0873f94e776fbf66dd775457c6e6d1a8c31360ea5b4e4f3f913274edcb871e3dd77df5d5c5c0480f1f1f10b172e94cbe542a150ad56ed6b62e656ab552c16df7cf3cd4c2673f1e2c5c5c5c5b367cfe672391ba4170086868666676733998c00dfc0444a446d5249da6d7676360c43d1e47ef8e187aeeb361a8d858585d9d9599b17463a915455d7ae5d7bf0e0413a9d2e140ac698575e7945e8b8dddd5dd7754f9e3cb9b1b1b1b8b8f8d77ffdd71b1b1bc2dd8f8d8d7de94b5fea743a0f1e3cf89bbff91b71c010abc0af7ffdeba3a3a3cd66f3473ffad1fafafaf8f8f8c99327272727a7a7a777777765de722c1849ba4f24d7a96cb0c880cc3040612566b6b548e8b5d8da72cb49f18d453d4424d261180196522125c26359f8544a8976cf9888b6e204e16012660d318575306049f62cc38811f325302a1c28117d4a0a4b50db3259499a08635b278b059c6089077a80040dcc096a08f69036c916db7f12c82cf44bd4560b43c97b8444f48fe415a19fc5b3e311be69a0074b613d78f0e0e2c58b6118bef0c20bafbdf6da2bafbc522a956edebcb9b6b676f9f2e520083637373dcf93f5cfcc954ae585175eb87cf93200542a15d9cc0f1f3e5cad562f5dbaf4e1871f2e2f2fefecec9c3c79b2582c32b3c8ec857c90553d3d3d3d3c3c5c2e9753a9d4bbefbefbe0c183b1b1b14aa5223c66b158945c4dd96c766e6e4e6b9dcfe76bb5daf2f2f2bd7bf7565757e7e7e78f1e3dfaf2cb2fbff8e28bed767b7575f5fefdfb1b1b1b2b2b2bed76db6e278542410816a5d4d2d2d2471f7da4b516822897cb5db870a1d3e9fcc77ffcc7c58b1721b6bc1b191929954a939393421d883e616e6e4e482199a5a552e9e4c99361187ef8e1871f7cf081e338172e5c387dfa74b15894981cd648a5582c96cbe572b97cfcf87144fcf77ffff7ebd7af4f4e4e160a8543870e95cb65b9cacece0e004c4f4f1f3972449e987d3baeeb8e8e8eb65aada1a12122127a534e181d1d15fdc0cacacae2e2a258219c3c79726262220cc356ab4544622632323232333353afd75756569acde6f8f8f8cb2fbf7cecd83166aed7eb4494cd66c7c6c6b6b6b62e5dba2446b6e572797c7c7c6666667676b6d56afdf6b7bf7de79d77aad5aa78081c3972e495575e29140abffef5afdf7aeb2db1231d1b1b3b75ead4d1a347bbddeed8d898403c114d4e4ebef0c20ba3a3a389296ad901f98b7d09f76eb6c644792a10fb6639335bffd0bd8065b942410aa5486b4364749c913006a9882eb3d0ee38fd80c50068a92a0508ca2804305a0d0016529caec33082f44cc668222d1fc435cfc45645fbe1f227916151c21714f6583f33b3f897d46a3531bf16df88011a2ae9f065694fb990dc3bc7f22cdbbf3c586b0b2a4b258971727e522e2017b2b76cf168afc536c69613f2beec2624dab1542a75eedc3931bc1c1b1b5b5858909b1a1d1d7df9e597c7c7c725f72d004c4c4c944a2531ed191e1efeea57bf6a8c2997cbc29ee772b963c78e954aa58d8d0d8938383e3e3e3f3f8f88afbdf6daececac184089a25d6c172726262e5cb8303434d46ab5c4db5c3c6c64d1b65aad542af5eaabaf4e4d4d89b4be5c2e8b6d84380988c500221e3d7a5498116b5769b15b56e3dcdc5c1886478e1c1169941092c2750a6504b1d05d3c57b2d9ac1876b4db6dcff3fee00ffe40bce7e43920e2e4e4a4b069bbbbbb8838333323b6f8afbefa6abd5e9f9c9c14abced1d1d13367ce886f16337ff9cb5fdedada9a9d9d1d1e1e7ee9a59700606868687373f317bff8c5fbefbfffb5af7d6d61614168498c9d1099f9d0a143954ac522a6f42cdb52269311738d63c78e398e33363636353525a9da73b91c2266b3d96eb75ba9545e7df5d543870e55abd576bb5d2814c43f5f70cd1823b9632626268ac5e2dcdc5cabd51297fbc9c9c9a1a12111200e0f0fb7db6d794d226414ba8c88aad56aa552999d9dcde7f3c78f1f1f1919913d4c862a182a0c38c66a25917ab3b1e99f8019f03ffff33f7ff5ab5ffde33ffee3e6e6e6f0f0b0e338b1a735088ec4fc6444a7c857a7bf88264554274e940bc74da5fc388f4ef439954a599d8b3d5329e5fb1e1139ae4344aee35ac07254efb3a27d002b060e896b0e44ca188d08a954ca1873e5ca47d634462c2ac55a9afb59b0c7ac07c4de7624e29f2ce489bcd47abd2e06e89d4e470cf0441ea9e330784994b18068db939494f42f22553105b627c8626bb7dbed765b30c55e45141ab250072e972400752212bfbc591122bcf3ce3b7ffbb77feb38ce5ffee55f9e397306e2946ef0e94a72f37b52c50eacd168fce217bfb875ebd6c8c8c8e9d3a71716160614ac4ff6ba9f4fb123dfd9d9f9abbffaab1b376efcd99ffdd91ffdd11f414c317cfa97f2d4960f3e78fffffedffff7ebdffccff59b771fac37462766ffcf37defcf6fff9aa63e91d8b4d4a294b6161cfbc9388949ca9e2243749c0b29f45fce945c5f57ddf75bd542a4af325da04f92ca759c01226d6753d4450ca01044739800255fbc8b05032fd495a34b042778d18994da65229a15cf6ca6be063da5e614274cdcca231100385bb77effeec673fbb7efd7ab1587ce38d37041cebf5fafdfbf70160747434698b282cf38093bda54f6d8bb8e0c964bd73e7ce2f7ff9cba1a1a16f7ffbdb7254f670b9faaf7ef5ab1ffff8c78ee37cf7bbdf7df3cd37b5d64b4b4b6fbffdb652eacb5ffef2e4e4e4c09c96d72d7ed7128d5ecc1a2726268e1f3f7eeedc3949cb266fc77ad23d9185f159a0861d58369b7de38d374e9d3a552c16ad46ecb3bbeee753ecc84ba5d2f7bffffd6ab57afaf469697986a14a4aa150cc6432ae2bfc0400447a42c70a986c890ec64ecbe2f4670dd1d59e6201cb8d8be7f9aeebf8be2f806573110a55655b1280e55bc0123f2fa51cc488dba20300ab0fbcb0c7a6d977994ea7551cd3c3d21a07498e1e52db5f5122700ac4d4ca9d3b77de7aebadb7df7e7b7474b4542a9d3871a2582c0641b0b3b353afd745ac532a95845fb66c9755e28aec53085b61df04aa6c08aac5c5c57ffdd77f1572fac89123229eb0acdfb56bd7fee11ffe21088242a170e6cc9972b92c1686428a4bf8d366b3694536beef1b63d6d6d6de79e79dab57af76bbdd76bbadb56eb55a228766e676bb2dde6a628d090042e2d97bb7aca849046fb2cc7e722d0d2846f7b2d8f6f126f79224ab9bdc276cb77b7f25d715c6ad5eaf27c9e18195605f6b928cd589503090b0b6810394b0c9cff64e93d312faf73c48408cd58f5b7f43cbdd63ac56b657b1bf5d585820a2300c452d604768f7547b77034b03faf7dde43966bfb854906005d4dea858844647e2208a9d4fec397baf9e1c61f2ad412c0f91f158ef5159fec618f197120e91122aef3e078e78c2f4be0208ff88f0b008de989842d1ea4ef6100bec070b473118a473892988d017451e9373ccb6c4b30493d371efec4ccef54f49615921b7156c03c0eeeeaef828148b45b14bec743a8b8b8b63636332b1de7df7dddffef6b757ae5c999f9f3f74e8d0c2c2c2e4e4a478e15fbc78f1ce9d3bc698d9d9d93367cecccdcd6d6c6c5cbe7cd9f7fd3367cea4d3e98d8d0d31535e5a5a921835b95cee2b5ff9cad9b3672558a0107aa2e0bf73e7cec58b172f5fbefce52f7f39954a4591cf10b5d657af5efded6f7f2b6eb1870f1f3e76ec58369b5d5f5f7ff0e0010058099408269452dbdbdb376fde5c5a5adad9d9f9977ff9970f3ef80000c4554de6b1202cc546b3c9476ab1ccbe7d8160dbc88902098cb387ecbc4c76923cd49b0dfd2720a278b7186384894e62df40e7c99a13e2484b89dbfd69009707a02ab9e47422f46072fa2517a71cd2895860f6bac97eeced1bc3008c886229e2388e047b810852238d13001aa3edf31fb8d381670efdaa2d7ba7037b4fef5e38727c0312ed16c8a8e2d42440aa97d733be2e0144bfa284e65a3ab4d782d8bc2bf9844506afb5be73e7f6e2e2cdcdad6d63380ea763e0f1e261f581c2de0236c9e17e0799b9df975646dffb8b4fb3227f460479ec5acb831bd4be335bffc1be6da477b85fdd46f404b484b64f8c793af13608c3f0fcf9f3a74f9f16278cf5f57539cd719c9d9d1d315411c31344cc6432cd66f3e2c58befbcf38ed8284974e372b97cebd6ad9ffffce7636363c78f1fcfe7f3e222d7ed763736367cdfd75a5fbf7e5d504f3667b9f1c9c9c9af7ce52b1f7cf041b7dbbd7dfbf6850b1788486c3bb5d6dbdbdb1f7df4d1fbefbf2fb1d976777701606e6e8e990b8542a9543a7bf6ecd1a3479959cc02aad5eab56bd76edebc29d931969797c5f7757b7bdb1893cbe5cae532336f6e6e361a0da1a92d892d6e71b2490a70a8382deec0fa79e864fbe4258935fb96e45449e2ddbe47932d039f9357dc7be6c0159363db77ccfb5e6bcfaf58ebbe740fc9df02088c420c7366a09f646f9cd82406e8b2fdaf6eaf8251c2b1bede8093e7631f3db15765b7cfb5063ecbe20ac3706767bb56ab93721d27edb808480c88480ef73cf56ccf9c205ec80e722f2e58fc014011e6326b6665c3245854d23aaa950266308645871817d13ff6f270c4848cb4ecbf65d927921c589202eadd4f7c87039f3f563d481bc79e999ee7490412eb7126dae27c3e3f3f3f7ffaf4e93367ce18636eddba75e5ca15cff3767777af5cb9e2fbfe9b6fbed9ed76d7d6d69697976fdebc79fdfaf5a5a525a594c4e8a856abebebeb4110887fc6891327befad5af9e3b776e6868c8de85280d8bc5a2d567ddbc79f3d6ad5b12b8f6c183078d46636d6d4d54d4621e79f5ead542a150a9540e1f3ebcb1b171f5ead5dbb76f7b9e77f8f0e1f9f9f9a5a5a55ffef2979b9b9bdff8c637440fb8b1b1f1f6db6f0b681e3b76ece4c9935b5b5b1298b0542a552a1544cc66b38542617b7bfbc18307ad566b7474d4f33cd16f888929c4444492d8b113f489d4034be271fa4f2eaacfaefe6457897f6530ce71144f6cea9784c8ce6d7f35a81d1a00ac643beed123ed3b66886108e20c897182716004038c367d121b0421ade44c64eee55978fc7b27525a87b95ca65e6f7643ddecb06ab40c9066340062e3d3e3b0fa49138c9b70b0a9476ef4869410d5430ccaf6e158b6b11777d47e8d636389741fad282d8ee9de17b361a0b6f7298513b43751f2429f8ac2820483603f341a8dd5d5559129a4d36971e36066b1ac29168ba74e9d3a7ffefcebafbf7ef7eeddbffffbbfbf7bf76ea954dadcdc5c595979e59557fefccfffbcd3e9fcdbbffd9bf86d4874214414a584957675bb5d443c75ead45ffcc55f483036610a6460029a2323232fbdf4d2f8f8f8d5ab573ffcf0c36ab55a2c1657575725f4da4b2fbdf4877ff8872b2b2b7ff7777f275ea9b3b3b3b95ceee6cd9b8b8b8b57ae5c91885dc618093050a954befded6f8bdffcf5ebd777767698796666e69bdffca638b55dbb766d6565656c6c6c6e6e2e9fcf8bbbefe2e2a2044890f82a1253e9f0e1c362d320312af03303ac67b43609360212f5412dc9f39f10e032c73904e31a18300223012c60a905b0fac6061fe75af1ae46c6e86a75777d7d63757de3fecaf6da8e518e87a4909413fbd945703350f851043c274a4c9dc9879e5321f7954856dd23ae120e74033291817adfb2ef697bc736d0c9de5f3db2b63fb72654a2bfb3be26825f41102c2c2cbcfaeaaba954aa5c2e4f4e4e0280f50e69369b62a595c964105138afb5b53509d12b0e109231ac5c2e8bb18c445c4ca5523674a44938248868697c7c5cecb97ffad39f5eb972a5d16848ac25395f947de3e3e3beef4b0c0071b89b9b9b3b7efcf8952b572e5ebcd86ab5c414636b6b6b7474746262427e9bcfe789a8582c9e3c79f2d4a953e2fa9b4aa584851c1e1e9e9c9c3c7bf6ecfcfcbceffbbffef5af258e82f8738c8d8d9d3e7dba52a9d4ebf57abdaee2d8eafc8400cb8a8d6d7dd0d18176bb3c9267f696683ff5913c3a70c57dfb79fcf10c30777b47c2cc4460cc202595b80b12078fc44860df7e1ee7de0f785626022c4263c01a3f0a309908aa9822a0044e8cd63023d9cc83208e28075d0be3c8c80258dbdb5baeeb8506aa0d9dceb4552a25168822c34a42d0c3e55907168c4b426a8e315f9d24cd06e5f30715f8987450720c7bbf265b3e59cf49d812d2667575f5f2e5cbc22ea5d3e956ab2584521886274e9c48a552f7efdf7fefbdf74aa5d2ddbb773b9d8e387c1863d2e9f4e6e6e6dada5aa7d3595f5f17dfd4a1a1a17c3edfed76efdfbf3f3a3a7afffe7da18f52a994952ecdcccc882ed592a24110b45a2ddff76766664460b4babababebe2ec1a18ac562b55abd7bf7eec2c2c2caca8ad85e5a3f35c771262727399649196324483c007cf4d147c78e1d23a29b376f4ab85471eb65e6dddd5db10b15e72f66aed7eb122a575c67c5014d084f89d42c4eb676b57cb209b6ef94fb9490f7c5aff7a6867fe25789a36392326c1095052c42640b40167492001403163ddeb54c1cca5d6b4d88cd666ba75acfe61ae94c1d5d5fa6f7c78b87357032735f83c8ce8db11992fb4e33c64822426374ecdfd7a3c230211eb29d72428380314d3150e0f3a2b0ac22438ab039beef1f3d7af49bdffce6a14387c2302c140a3ffde94fe5e8fafafa6f7ef39bb7df7efbf2e5cb88b8b1b1313737373131914ea7efdcb973e5ca95eded6d49a0204e73ccbcbababab9b9f9cffffccf4110dcb97347228b0a65d46c36ffe99ffe697676f6ea1fbf800000200049444154f5d75f9f9d9db5a392709aad568b9973b9dcf4f4b4d6fac30f3ff47dff7bdffbdee4e4e48d1b37de7aebad1b376eb4dbedcdcdcd9999996c362b03585b5b93e8efc2df4940a8d5d5d5e5e5e51ffff8c71313132323232b2b2b128ac4dadf33b398aae6f37966fee8a38f2e5dba343434242a4bf1dd534a5dbc78f1ca952bd56af5d4a953c78f1f17924d02633d41cc7accf2bb8695cfa8367b00ebb3a8256b8e01c9050d64980909a27cce86485ad0b0414bf7b111c0a21e9c3d7ab4628d28eeb75a87bbd56a369b13c3c0307225848f170feb80c9203dd83f883ff4ece30100fa7352c8bc4d5e19fb0b3c6514d6deaf1313135ffad2976667677ff0831f889f8108a1d3e9f4e8e8e8dada1a332f2f2f8b93cad0d0d0e1c387a7a7a7cbe5f2dadada071f7c70edda3563ccd0d0d0c8c8c8c4c4840460b978f1e2d2d2d2eaea6aabd59a9a9a4aa7d3870f1f262271e00ac3f0d4a953b20b21a2306bd3d3d3a5524972babdf8e28b67ce9cf9e8a38fc4cf6b7a7a7a6464e4c68d1b972f5f164f1a8963b7b2b272eddab54b972e890f4a3e9faf542ad3d3d38ee374bbddb7df7efbfefdfbd56a55e2404a646709ab828812743c0c438942b5b6b6b6b1b1512814262626161616ce9d3b77ecd8b1ededed7bf7ee495c3a0977277c6eb3d9b42ed99f67790ac0e58b5b0b9b69e186d83021d914f3143389fd8015515802559f00b01a0d0963ef4b680d88dd640fa4b0a40bfb39d99e2c101356dcd309f6c453f6ab24761647c3c4096083cf60ac1914cb9d7e94e9cd39d843fbf4df33588314d82f36f9c0e7c7acf7ea07c522e9c48913c3c3c3d6b317004e9e3c29948844bf9440bde274562e97a7a6a62a954a3e9f7ff5d557272727c5c4bc542acdcece0a2376e1c285898909b13e078072b92c40268ac8c3870fe77239f138938288e22696c9642438c1c4c4c49ffcc99f1c3b764c2261964aa5975f7eb952a9349b4d893935333323e4d297bef4a5858505c77124a196409be33867cf9e154815f308d131e77239712b0380f1f1f16f7deb5b4b4b4b12ce6d7e7efea5975e927031e3e3e3e21196cd665f7bedb5f9f979441c1b1b935c090060b3397ccee52958f65fd4da302102f4d83a6264448c6a662244c348884c48285418ca128e000b29fa78f0551226ac288e372ab25117317c4cda1c6c87956cc4feb2b73d21b1da575c653f58f14bf2eb60c144a21d0020ea85ee7b889630ae07d579c961273f3c7e9d1cab7dbe8ee3cccfcfcfcfcf43ec044e448542e1d5575fb5cf478264da222823a2259b6f2a79c876b8b74c4c4cbcf2ca2bf2d9dafb21e2dcdcdcdcdc9ced249fcfbff9e69b6fbef9a66d3971e284c4234f160995b9f72ac6184938b6ef1864b3191a1a9218be3ff9c94f3ccf3b71e2c4f9f3e76d7c71d97b7cdfb7a1f2208e788bfb395d7f6e455ee2d300015fc45a0c26c03052246e0764c4c8ac14819190b8e7de0b51332022323d4486651216f076f90380180e6012500891624b77d8834a1803d3def681131e7ad6e0828f4124c2a3388a83fc45111d304efcabd4603cace4a8f6ad931e79145b636bad8dd1ccd172fa845b4d4cafa1dd5830ba561c088c068282ef5d33bc1f310b7b84830f2fb1bd1f03f42080e3a872c9f7927c628fd3edc3c71051c5000030343474e2c4895aad76e8d0a1fea82034e01769c7267bd0e3dfe6132f9ff8d53ff5b5e4bbb3fac468e77e22260edad201a20184fe45c13190018201626003486012471998e1115749da60cacb32ba67606040a2061b63e361c1a081425fe18359421b03cb9828b60cd900a33a0cc3c84b4822ccd8560129ec859189464c89b42e88e838c97858bd680d711dbdadbee71b2f0c48f84028c711320d626f807ddfe8c3a73b11014450153dd3f8818a49b77deed2125b6cb0527db997e5015b858e6d971f5a5d6fe2a2d1b5ecf86d94b8b837e644a61ccb5353c25093634b027ba1e47892c3b3b035303124c45a727abcf8e28ba2d61156d10e95e210e3b64f44b401761efe903fd3f2bb8695275e5b9d60b404109f64ff496da016e68e44b89e5832f259310102322132441c6044732544ef0fb9169192e966b73a2ba88d662c000302a06341240cc320086332247ac152c761f9284684c8a224b14842638cd804b9ae2b1a34093920d1afbb5ddf75bd74ba232165c4ed596ac7717ddf2552ae1bc56cc098c29295d98b8d057df0b497250440ad432254ca0560c9e628d124ec5348dc57df3d3ece741f38d3b650c2fbc41af7c64707cdaf63c818ec24d13f5a9b38dbe1de110e8c67efcf07b0092079264af869eea7afa127bc8381ce93976366716597a309d20ced50c5e32cf9dbc77cce9f6949dec5335123f6256779c2fd238070680a7a6b465a4c7c79b9320000c535da1ea4e171aed51bbf943e6d32cb8c056688f66acb37191339524282cd1bc005bb81dbf52f6091008e68ff37c600b0311a40ec2dd9711c8955602316388e13860255dd01c04a401524afb51f60456bccca5098b9d96cc825c4cc9a99e572c61842e484a3f9bef0f7f8b57d26710dc9a7947c26b01f9b36d06e678bed196217adfdaec53140588a0684c0b42dc9a91077385806dae5f4644bb2b7bd2d71ffcc3c686c7cd0153ffff2c95eee5358c793d6d6c61896974e89d8090f15f526fbd9df7c54cc17222b2ac310534f91c982893f93e80429d2064a046161808c4124368071a487878c01633e4cb67f6d34b3418b4280224772acb5012263cfab066300eddb66fbe5503daf60fb756ff09944141a65c366d994c536781611398eab1446e1651c85203528a580819412635906263ce0fe01b5d18494c966b4d6caa176bbb9b9b9b1b2bc9c2be4c3209027c20cc2a649bcad47bed72f742d04d7c38f2669baa7b83cec469ed1ba47805869431fb8d8651f1b0d109148b2ac053c4541e270ef244f8094dad74a9e5045460c723e4436594468741cf29748338bed955c51011a630801d8101233c0410b36311200105d9658baefeeee349bcd3008800d20888927b3718830fe8b84df328311c96e9c8247aa3fc89f85a764003f0b40b6f67d898d95f27dd7f753e2252721b192675214b7843ccf4342c7510012ce3c062c22662045008fd83414a974261d8661a1904ba5bc6eb7b3b9b9d6e9b6854b4d9a2600029b6716aa3e2ea87d7c041964363fe3f2fb095822d58dec75f682ce9e9a8ce9d192b130fe618005115dc63820a4372cf4112119602430ac118159132118012948d4910e91108dd108001184c580b5df980100e3e03ccc2cb260adf5eeeecef6f656a7db460424e418957af1b0b08f4f616696de60a095990fa6f063abab7d4aec35b8b768634200650c01b2361a7b37d21b541c3bcbfa2a0eb823d9f0406c18bbdd8ed63a97cd8e8f4f681d0641d068d4adae300cc3200c24977abbd531c618ad01419ec9ef7a8e7e1e7582aa42000646401e687b582def2301249f04b21eff72319918c70be8d54fc3c3fcec5e9031801825be63d6c0c0609008aca79ed815444f0465290b6041c4d733221b362832873848afbc360129005488860110fa04f9c61044e17c351b4430a091806327e7c89201081891941860450491b08d60e2e945620071d0fd9ac8b854b23a3003b73b9da01b1846119443d718c3c6c6c3b2d890c0230360856e115a25316b3f4892b5afad603e894a92a310512b15a5a5c0583b400a890d1210ab58d82663886e097a4aa83e3bac7d018bc804419799b3d9eca14333e203cccc9ee7ca20bbdd8e366137e8d66ab55ab5d6e9747518c650f854ccd7cfa6068cc3b13d33257953bfebc7fb59039601000613bf4afb4219008001053e8892478135209b58c1828809c01230020010b000ebc06c1dad6563c228b795022602660d911489d8000031038282c834d4887c1c08351879490478106045549e48664c2ccc8d9859954a67fd949ff2fd7a274024c0037c09992d098676f77c3860ed259c6cbbd6466ba394d1da10690b6a8a24f72a46527943d6540aa374aabd2c551011c683c3884f33cc83ae88aeeb168b6e1086466b916d318031a6dbf548a96e108441608c715dcfe890237b91a762be7ee680d54fa9f4cdd1c7affba8b2c72c9652fa04b7008332377c76014ba6a291c91fb50be502bd70c3144f78006390085129e548bb310c6cb40901b43106ecf3115bad48ae02001cc396c531d15f598864227201d2842eb31349d121000808bb8643c6403300818ebdf008346b8360502826430c6c1e26c3829eee4ed85e0406e5389e9fd6647cdf775d50a4009e802f61ff7c8c7bdbdb273eac908d1d2f727c8a2cf40920321a1031f9be02f2f8295b4bf4f828716c8485b12b13307310049ee7bbae9bcd642a95761884c66878b666fce7517fde80f5fb5727a4510c2ca06c8c09c300115d5722bbb2312cfa38008ce9328885ee9a54648420fd24b581f24a447e0409cf108e910c11888d03ec84614a1ba7ab5d06650c1076103a2e05a4b4a3422446a50d9240164227ec8660c851aeeb823160981361701e025518db6d45900d045bcd4c762bd546c7759452118565cb7e93ccca2df61c60e67e5b47db4f423e25d4569f60abef9819489b1a114ab6378cac3f622eb107c3c9704291332333cbae0300861913a4226224022122dff700b2beef75bba131465cd21fc7c2ed8b5dc71063a5569fbefee480f524ea6715fea2f807d6c118ed3da2d161a7d306807426934aa5c25087a1610636d4e9745bed56b3d90ab4668694e7fae95c26e3bb0e91c4a502bb5a7b76424110300383719423ca34a30d3023b347e80601b59aededdda0dee24647858ca16642f2542a93cae6dc949f55990ca6fc0095063288ccdcecb634b0e3bba9748a8d31a1616d48593a23117d4ce471b1c89f88746c180188da4080d55c7eddab858a1422f459baf7a6d57e541226cae3cccdbd20f8b0dfed17272bb6ab887fdcb34eec333c13bacc02ab6d47ee2b446ce3e44bfe18dff7b516f6feb30824f4f4d59f04629ee6f2cc025624b4ee25368f580704d43a6c351b0090cde532d96cb71b84a16170c210b6b676c26637308a9180085c9ffcb49b4ea57d2fe52914d34e360062f410799548c20e638ce3ba8e528ee39850a331a4752ae83acd96deadedac6d75366bd59d7ab71986dd90914387dc6c3a5fcaf9c3e5cc70393d54e6425a6732da71b4317edb0bc1789954269b31dae820340700160f40b3052c6044d28cf54065b239c76d925244ea21322c807e88e183655807b5c7651f0157af6664164fa13e3a0b11b5368851a064139953e3c0b5e4eb5ed95672c0f16fad5aa46747abd4d3303b9f03d6272bcf3660416cf78484c492d51b50eb90c310107cdff77d0f10954220bfdd319db0da09949f2de78a05e52806a34dd0d1ac0ca41d2fe53a9ea3645584412873408c9998d968e3885d91eb8236146a6c3655b5d6bd7933b87b9f6b1dd381edcdfada76bdd50e0d9b406b87b898766b43f9f1f1e1e1b9e9dc91b9cc540a324ec0a0390cc0f8be9ff653469b8002930876c26c92f22c42e284f6cc18639947cde8b99ee3b8400e2301e0c7cb9a2325090ab0c78a9af7e72bfb7bec45223d50b665cd5631414fd928ef723f109990c8d1defb86d8cc75601e104987510bec4927f714ccd4275c3f43f0f438e599b1d5424446b91783888a010989008049450986a362088154c8dc0e74c8942f5446c62798b95aab356bdbf566abd9ecea100ad9542ead285a594a516ca525840f488e647288481bd56ae995d56071b1f1fefbed7b2b6df66b5e61bd1edc6b04012a47b941d0d1f5c6f656b5bab6b9757f757a73672a0c4614659c09954eb71dc58c8a94434a3318a5e28cc8f1ddf5c4ca4c482ccb92e57f64dc0088c048a40015a36254f871238e0e144e947d2dac920ac3d8ba61e090d686b436083dcf61a1bc109199600f650731b5659d6cb99f9e1aa8072009ac7ef779795e9ede8200004cb2b903a0c85fa3d07391e55bf4171a1d869d763b08822e8341c0a01bd46bcd8dcdcd5abd11e8ae09bb1b7ebd52ca16733987c07755219b2a64538826e440120a3244dec5146a556bc0dd079d4b973a972f874bb7bad5c646e8df769af754b6962da4462ad9620e8d69566badadedfbbb3b5bd546fdce4aa88c47da778c3335ad224172345e3b5ce8ab637bb0c482c558f2230a3860444406b0ee6e9f444bb8f7fc01c84be0d840e3c0c91cc9c4a127c302d887ec8a2fda476d3d66dddfc3fe353fa7b09e91f2cc50588c881899200022311914bf6220204240524a29879461d09d4ea7ddee301ba51058775badfaee6eb35a379a0dab6ab5bbd9ad6d6d357299aa02934f7b33e3959472522949e98e0c800608954bca09ba667b27b8733758ba6556d6546080bcdd467bad1334f294199f1a3b323fb530ed6752cd667b6b7d7b77794dafafe8d64eb356addf5a2c96b3aa50a46c3ef68b41911e03889650961b21c68cbcd4f13ab55485369a001015115122cfd6c328acd891f520307aacd2474c694da4e2e03351201aa529a92b4ce60a36911ba74807d9a26c722470306d355027cf17ba0c135a5e8801fe19ab9f03d617b42624d6000826b20e14371ac983c0081047f48530349d4eb7d96a77ba013022b3e750319ff11cd240cd6ed0ed74abd5c6ee6e93409ba0534abb41b34ea047460a7ed64324d6c61803463b4cd86a35561f34571f00b23739a54b417bab1634579c46b3d8ad9731982967660f4f67474b06b0d5eab476ea9db5757cb0e4debca89bd5dafdfba632a247d1c9e7149331ac4554ad636bfbbe3b0536067a09be50166a1806ad76cb18f6bcb489739749795c0a6b002692ebff314a0f2b1e7ff160a2c45f3f1e6d057b24597b8f26fb7f26ebbd22c867bafcee1ff893a9398ad162d3be7324f18d672dd8fc9e048c41c0ddaed61a152960f03db790cf1a631aadcef64ead51cc355bede5fadaeed666b75e6be4bdb40fc323f9622593a23431a00e115921780818741b9b1bd5da6e7e78283536c52d6316ef72a3ebedd65473bbb4bd925b7ba0d6c7d807279f2b1532e343657f6186d6c76a59d3b876a9be5bd5cb2b9e97f6737947b9840a7af4d3c09d32223002221089d1253073a7d3e974dacd660391101d0088ee14101f4e6109d040221bf55e02cb243c071f2ac6da5fb6657a7973a2407db62b18cc02dd1b41727c49c9d4a7a97b98faccd5bf4f1416c8cd3e0d8ffd53d586198dc01618c384060c3002880d2613f4d2aa87a169b582565b6ba38854abd5ae376a7eaa44c8db1b1babab5b0c542c66373655bd5e6fec6cb9943530aa3c071d47725cc526919a35e976a7b95bab359bdef0889a3de4618ac1addebabbd1e938f546eaaebb8a7a636d359c980a8647a1501c99183d3a7f68aa3c929d9e6b6dacd7d6d73aab2b8542313331e100264d306d88349b2b1e1229c165a5773a9dcdadcd46a3ae880a85a2e338c6b48d31c00c6cf8e3cbb0300996d10479687954770928da9faa8a2ef5196d650fa7bf9e81fa3985f585ac459d6d801080c09008af101050dc7240429c13213150a821d484e43162add9a1ed9d74d6f595db69d43b8d46b6544ee7b35bdb3bebd9347453c562ae325c2e0f9753993422020321461e7dccac8d0eb40ed928974aa54c71b8c4aab8bcbabdbdc3cb6bc6f0d6f5c5dacddbbb8591edca443d5f2ccf4cad9e3f757e7e7c58bb2a5be6cdcd76a39669370958291191212332a19561c9ca965aa9c895c518d36eb71b8d46a35eef763bc5422197cda65229c2aea819040b3e959650ca1e8c7a1459d5af31d45a321480523d7a2a495b8929837d97495228098bcfeb83eae714d617b1660066466603c6301a6064048988c42c69aa801918d8a031a80d19261de866b319ea76b19cce8f0c1d9a192917f3e0a61b9a2be5d2c4e458504c4d8c1687472ba9ac8f0ab4d6c6ba2c0a09a40d3232288d0ebbbe572e4d660b6e3e3d7be4c8d6e5ebcdeb37ab8bd7cdd676a7bd4e35d3f277eb9b755d6d766f8f9d1d4a8d05da41d509834087264a3b2a1496fcc3f8b60c4014bb584ad0ed369acdededed56b30900954a259bc9388e629b1b305ee94fd29770df7e1298122f9fb8d1be977dbb4a1259b0df4694b4c67a5e3fa7b000e0d9a1b022091683444026b1384044e448e12f14162822898c49a419380875bbab1983ed9ddae850697e619a403d58afdd5ade2a978bbebbd06dee16324ebe90550e326a24408508446c226f5ea55ccf7595a342c3cd8eee847ea17ce8ece9c9f9e39b2f2ced5ebc54bd3cd5b87d676b75abd20833ddeecae6d646b3717de5eef8fcf0f8482a43caa43c27950692807a3df1537c77728b71345044a375b3d9aceeeed66b35662e168a95729908b5d6402129222288fb782c0acbe24292ace9fb9228a6c7b25aed609ff9d57ec1678c68090728ace49e13535bbd780c72c29392613dc3f5730aeb8b581b00000300068c0134ccc420b15c62c24ab3d1c840088a8088b50eba6168005b1d7deffe46ca73872ba542caa9d677d7d65732b9c2f8e8ccf6badb6e6c07413b0c3aa10b2acac10ec630233021b884be430aa9d50ad7d61be0d5b2cdc077336e3a3f397678b8688e1fa95ebdb1faf66ffdcbd7f45a15baaddd0e795c37e9c0b865bf9c8272d9cde6b4c42b57145147868d449b01d43a024745d4ed76ebf5fae6e666bbdd765d2f9fcf29528d46230c02522a9d031b7e4bcac328ac47125ffb02962d7b4e81fe438f28727592348af09c927a4e613d4ef9dd3ff02753132062e4df0d8884c842ae10232b248488082362d78574da49b555bdd5d6a60b883ac48dad86a2d5a1cad0e87069737b2b089a4395c9c9b1310e6af776571b75d36a647d4fb99ecf0c3a640042724139984af9a5623697769ab5d6d2d2c666f396cade6b7695ebcecf8cbd30379d999c69b64d6be9ae761733d09d241c759c2152a576155b9e3f594e8f4f9a7285890c18878058b2b1f6a29b02282198b4d6f57a7d7777b7d56a398e5328140a857cad56afeeeeb231b97c9e90004c445ec1a3282c660660798689737aa0c331190571ac514b25f50bad7aba409158258f5a199684b990da24fc0a8509966bc72dcc095baadff966f894d7cf29ac2f6e8d80465e2273c4211ab681ee988d3621a9309b730aa1bb530dbbdd7abb1bb2c120a4edddceb5ebf77676760d9bd9439373d3a385ac5f2d64b7d27eb7d3aced54339e9b717d03a8b5018d46a98e21d7cbe446c7d5c656f3e6d2e6e6475be5ea667ae4da6af5fe6e3d552c4e4e4d147319b5bbddbdb3a66b6d9f4d99b884c1900eb2adc0840595cfa7c7c65a857c17d9e810d9e138a9a044f32342d77501b8d96cd6aad5ededed300cb3996c2e9f03c0ededed7aa389c0d96cb65028787e8a4d4d6b0df103f92432ac47524949aa2ad93850cbff44acdde8c3de212518e0befaa0f6e7b5ad9f53585fe45a04409145b8585eb1501a0022010234cae16cd6d190dead7bf53a76bb3a34a4c8ed7679e9d6caeececee4d4f0f46425e7f9413bd0dd2e30eb50079d80353ba89898a358812a64e5f899dcf864aa5e0fd6d676b7570cacfb6df0376bcd075bb7daf7af7fb894cbb8050a53f59d8281e9b49787ee188595b4f28b696f74c81d1b73872aed744ab321648cadc544641571bac0611858da2a954a158a856c36bbbdbdbdbdbd6d982be572a954cce672402e6294c84ccaa36558823007815a126e92c5d24f7bb5843aaeb4d15a6b65309661719238a338a92709fd0b0089d4521c8bd598adfee1a930507eda6a786ee9fe85ae0998010c3033a3ac108ea3478136ac8d660e156136a34686723a0c10607bbbd56875bbdd30ec761b55a7ddea988e69ed368d0e6f2ddd5c597d90c978a343152265b401963f3446b3e6d021cae59ca9c96cfd68c771ba2b3bb9f5bb871b41214db5b48f7ecaf79cacebfa79ca5554a1b135d4a91690b2c395f4c242f6d4097766264c6703646dd8e94565e9614c1004bbbb8d66b351abd5b5d6e94c2693c974bb41abbdd96a351dc751aee3384ebbd30935bb7e3a5ae931b07c6c3bac3ddff1a043bc5f01604bdd09f10e10b1a883a597f7350268e8a7ada485884c1c8cf1a998614f59fd1cb0beb8b5e4a121f1bf33203e752c0a42e8c5e845400493f2dc91a1bcef3a1e390e6f72a7cb5dc388dd4e70efd67275637b6b6d34e53b2b2b0f1a8ddd4261225f2ca4321909db8e84a880c45d5161e87b6a6428e79d748a45fae08a77ebc128522a5f76330537950326e2904c5b059eae2ae864d855e9e9a9dc8913d963c74c69a84d4a77bb92844bc82ad18b111100866158afd7abd5aa31269fcfe7f379c7713637376bb59aeffb434343ca718cd6ad560ba09d052442453691eba37c0901e4cc8889433bfb056b22fc39b0ec25aff6d25a82bff1be61c55ecc31e56498291e803116e0e29668fc6839fde7f540fd7b589e86c7fe045e1cc77ff1e768b509d5157137048cc08c6452ae52850c6af68832beb7bbd3a8d61acd56a3de6dd76aadd595209f4f2b05a3a3c3e3e3a3c562c1f5bd68e90133026194ea462398544aa94a5ad1b036857c2edcad9141d30d4cb015b442309a5cf652a0c6879cec0c95cacee484333d69862b81eb07a1d6600c03333210c3401a2d4024d7f35dd72d140bbeef1b6d94e3a4d3e96c369b2f14b436ed760b89881412198e9738307f5c0a2b0eff0636d2ee43f1cac2ce60e2af38745fc2689f7aa665bd3be338936472083186ca1d2033f47488f0bc1ea87f0fcbd3f0d89f581d7dc4789b8eff45c71091100899d11800f61d2a173369df2b1733bbbbb5adaded6a4d351a8a8df11ccce7bc7cbe52192a57868ad96c5a2932c618048e3352210a121a0d6088bc42217b6c213736d25c5dafad6fd6d6d6db3bf56ed04600c77372b9427e64243b3ee98f8e51a9d44d3b1dc2104256080420b90ce328ef8811e41051369b4ba7339ee7a652bed6da689dcb668bf9bceffb9eef77da1dd7715426e3ba9ee3a5b1d66466cb843911e2496e544512c654c82989fc10cbf80031c1b9f5a57c8e414cf00b2c4819068cd1491b4386b531648c0e43ad5488842a54a430080024c4a27150929a014bbe0d2492d7c52c09eb0918c4c697880c802282673738cc136309d10698866788494cdc08f692ea3c0d8ffd49d6928ac21824f9cfda04c01884dd6e0783300882800d93d2cc4c0a0928e3a3836e3a95cbe7a0d3c974822e1800c3beef6532e95c2ee7f92e9bb0db090db00e3500b061c3da21c586b4d680c8466b454e2ea37c977dc72de4b29552aad90a5b5d44244ff9f99c532c9af2503b578494df8550eb50eb8001431db0c130e8763bca9830d45dc386481b6d98d95144aea314011b6334027baee32887107418b2d18e222654e2cb6334b256641019d83800608c09c23008c330d40010869ac50920b26948aa2d62bc2242444d86089591b4424a1965d828a5c45681810d3b00a08d618e1872add930381a18403333a361cdc6977d217400000537494441546837d4da388ecbc668471b6d88486b434a091ba84205008ea30040e93880df73c0fa04e0f5ac01d6b30852070016203373108608d4e974d870a843ad436020a23833b37c66cf23d7cd22e61880243b57dc6710044108b2240d1b0434da105288a1a3c848c817e68ee4dd015699ac9bcee546c61c06d606111901940a105bcae91acdedb6014d8a0d1b060c8210812425a831dab0962c7c09b32408c33071a710b036b1b9b82212173ec5868d01d66c42600d004ea7d3add71b1b1b9beb6b1b80ca512a0c438e329545d33a26492d60894295909014384a914aa4ad27e5baaee33a9ee7b98ee3ba9ee3b89eef7b9e97f27dc7f15cdff33d3f95f25dd7f53ddf7355caf71dd7715d495bef4ac27b22745c8f94f25c0f001cc70100c7113f0205c012305611314858688e127c5142000f7bc2484302daf63ff351ed9fb807ab1cf8d83da030c7891ee216664488dba1ef4cd8d30e280e6951e2198e83a2f7ce4404b0ed000090f8c2314a445fb0af4566cbde33f76f8f640b836772f4250a3e8f527334f8bef6381334c78f2579b320b77cc0c3e9b5c78fa5af250113d18b330f6db73d3cf2cc03da1fe74c49dc008c08616810a9d5d64a750d6b6606c322ee915729eeb792ab582902941cf20cc061183273188400110dc16024241622210051048e86192411069102f49452408e52408c846c9801bba1d641d88d128599286d33a0d68c8404a1525dc306204af365a2a85e80128a0e305abcc088209187015829c7188d489e4fed6ed86cb51bf55aabd90cba81e3797e269d29164b41a04bc5b212c0023b2923c0926bc48845880a41d2098252a41429e5447ca50096a35cd7554ab98ea71cc7f37dc7714979480ea28be422b9080e3319569a156b02424600420da0999140198304dd304444c791770088a014003062ecac038cbf0f80257093042cd86fad0e00d323006be04c0b58c8180b7bfb000bc1b603427263eb03a647b65bc0c2e8128380656f6d00b012b7fc70c0dab77df0a121f3c0994f2b600db64b6eba30ee219efc7d67ea837b1838dfb061441e5c2cd199cccc84210c269722c38c11a8ede999301a61af7d6fcf320693b80b64c3486c8c564af910763578be57c86773d9b4eb3acee8d8d8c953a7bef39defd66ab57cbe1079f9b1cda80bd05b6c51240a0090ac8d513b2121927200e4282aa58830067817891cd74140428588ca7104ce1049298584ca75019094a2f84ca19e50390ca091a2e9cc101a0060476c23646c02eac8b6c63e1387c43b186c39e8cc47b67ffe3df4afb4035b1ed14e80069810a2b477832d601809c1b0c84cf7505e7dcc648c38b62481e9d1edd1cf93dd26814906100d06d9480894836fe1f11fc2c7788c03d4cd81ed8f7fe613e8214ef985269e24147d66e86f078820c0d8df52af07f1ca4d4c36406493b816f460451c0d7bfdd81a20021de95948df681a532fdb600f1c077be068f785dedd1923b90d0d1968732b609e9d9b181d1f9e99182e97724ea9549e993974fe7ca7d56aa5d369794c02587b970df4528d46565111b40190a4c400792e91851400905288488ad8c44755045b027c92afc3306394edd9e1488709444a9e3e00935286192400639c5483990189e5214535243e275b684fcb41673e4efbe7df83dcef9ef6bd2d07b71b79b9f6f3600b304054f794e90849022b21e51e0426c0fd9bf76fef7d4f748bf6423280784818d707dec2e33f848ff718f7993c0f9f548f73e6a7ea419e06262689499c996c4794780f28213f21a642042792fd588a64e05a88c8142d7fc0383c688f9a89dae3de38d90fcadb44d94e9001e82177c789bb93d80c4c8c1868838a46462bbee78f94f3b95cfaff03146bb6cb57a99fac0000000049454e44ae426082, 'image/png', 0x89504e470d0a1a0a0000000d49484452000000c800000096080200000014be504e000000097048597300000b1300000b1301009a9c180000200049444154789cecbd79981cc5952f7a4e446656757555efddd5fb26b55aad1ded0ba805c2181b30020c18e30133e3198f3df6e7b1b9b6afc7331e3e2eefcdf518ee8cafafed798cb187f11bf03306592c360221c0c22c129290d4925a6a2dddaddef7adf6cc88f7c7a98a8ecaaa9604e3057b743e68456565654646fce2774e9c387112fbfafade7aeb2d00000029252242baa0046028a4440007121c0c94082850a200049408524a0494c824020340440e40d7918880c8e8b2eae2aac0189bbd11e25ca7b9ce747de5fad579ce994b321f5c4a79311fa9a07f5447f4b27e24ab500d5d77799f89b898ea09c05024debaf972a3bdbdfdbefbee3bdfb91224130888c06cb4994426984007814b00891285648c21034489cc404444ced0e00c0104e3c8900e2281833196f5a3eb2bd4c4759aaba030371734e7429e3aa83799eb88ea78755008311756e82bf55717c771e8a09312bdfcbe859482bb940e3dd7f987a823a17f70e2dfffed11834e154270ce6ddb7613830490c08051c3318e5230008608d201644c8260cc400404c118678c0170869c730ed23138030688cc05141d3afa5799789a0b7f90012f55501f211bf9b9da25b39932c9c90532d54499a8a2a6d7cbeaaf02966ddb9c73c2932abc6fe1258480f49179fe4a4a0920011918f46344741c873acf75e6f4f4a40d0e32404401c0c000474ae6a0527660004a8327158a811c9131099c2143292548d32b64b25a9c7300282929a17b65721866883a473d9baaa7eb1cfd887a001d522e78e9e30fe7d6442e60652a3b85a74cde9252123971ce096d8c31c2197db46d5bc79642a4eb297ebf828800a854f6f9ce04900020c180548bab36d27f2951740ff7f88a3d8e70101010e353098fc7629683527a2c8b034e0c47cbcbfdb64c20480e6c78281ac8b1bc26935230900eb09e5151122ca7c6e29c8f8c8cf8fd7e8fc7e38211636e62831463b90e66aa451775652ac7ccf2c53453b21134244186cd84883a5165c2cb7582ae04e95be22d521754209e781f12d8c5082220a2e11abbae869620d102c89388022472641897dce7587ec9c0f199b62131340df98536c838038902e333b22057fa73e2281c2ea523adc149aba0a0005280989999e19c33c688bd5caad07544ffca851b17f82003582eb4c17935e35cd683debb996a1100888432a94b018b732e35938b182b531b2a26239b840ea60df20bd937bf3dd1e9f922ce0609d2b8f07949034a20807004320029a4b4b9c940242cc300100071e47194881211246712659c4bc94002721d348a99942ad48f679ee9c25c26e0209b66d40749e6c7d4635dc0d872b56ce6dff3eb4497bda544e94497094f78a221c7182302a3332fa686ef37b9086051eb80e48800081201b80487734326128088c000989428a54460c8d016427226a440892235cc6868920e22bac28b33e1cf436317032cc82030c8ce58c2f5957a7a48b205038dc0547fcb39c4a51f3327898430052f65d453e328fd48ecf55efbf7f72617001602a2cd3cc283204182214ddb4e706999cc4a44e23e6f6e2222c00694b95220302624c49db8e479b68c300409d20603100dc310421886010034225d7a50115826b0ce0f2fb8d084910e2a73786ede4a23866cb43f3b19ccfcfb6e81a5f396c299ae130dc3500446d85250fe83900b014b32eef0e840421808121c2120ce6209273e23393362427064c286735d714086000868c7ac8178dce20c253200092084e8eeee565d188fc7a9bd2005b2b9180b0088d8328105e9ba12d27d5a99c00220e64c3b4e7f924f8a3c55c8d20e524a3a41d780eaab4cb528330cf9acf022a222c3cb05ac442281295381739e4824fe80a84b5e8c2a6c9abf404a011c1011241adc608c912fdd600c91316e30f29f265192fcc7303824bbdf04444551aaa054585678a9d3521761fa5c4fc7a57ec485330d58221d5298415a4cff98c95b38eb2acce2e8525f11af887407849452f9b1a43637149af74191161da147a38faa71ce4f5df87ef2dd5f1858b66d4b292d662160341ab5fcd6d0e0506565658a20180202607bfb89254b96d0a16834dadbdbdbdcdc9c34a478126184154801c2a5fe8e1d3bb664c992e1e1e16030188bc5fafafa9a9a9af47320c5589cf3d1d1d1f6f6f6cb2fbf5c8726cc61dd2baecaaa0a2f12584ace0f2c17c214985c7343a50a75439e40a3a68d042cc33012898432bc6cdb4e2412425cd402cbef512e0cac70382c8420b7d3c0c040535353595919002022cd5c0cc32083809e3f27270753167a2291f07abdaa9920c558f1785c4ae9f57a0180d48165590b172eb46d7bfffefd5bb76ef5f97cf5f5f56ae26d18065d271a8d32c67c3e1f35bace6a2e4b2b83b7d885807581c51f25329b03e282c012e75ded512a4fa4fc5e7450f9b714b068ac12b65cd425d27d90bf5fb930b0a494535353a4f2e9693b3a3a162d5a343c3c1c89441031140a2d5fbe3c1a8d9e3b770e11cbcaca727272e8993b3b3b6b6a6a7a7b7b2b2a2a94b77d7878b8bfbf9f31665996c7e3191c1cf4fbfd8d8d8dfbf7ef6f6969999e9e6e6b6babababebecec5cbf7efd3befbc63dbb66118cdcdcd96651d3e7c9873ded8d8989b9b0b290091093517b00090b1f33156d6bfbab88e640596fe315339ea2a52b7b764bacb54e14937e7159e68e812b0c8ea227865ade4ef5d2e0c2c44f4f97c85858584219672068e8c8c2c59b284737ee4c8116291e6e6e6e9e9e9e1e1e1eaea6aceb961183e9f2f140a4d4e4e2e5fbe1c520aabbfbfbfb1b1b1a8a8281a8df6f4f45456562e5cb890be6a6c6c3c71e2c4a64d9b26272769e04e4f4f5f7bedb5b66d23e29933672291482814324db3a5a505d39cf5d2c5522c7d0988180bd2380c208db12ee0e8ca2a3aaa44babb5c64acf3a8832e7829bf83cbead26d2c256a9e481fc9a88714a6df3ff0bad0ac1011002ccbf27abdba55a40af4302cc3f14d120c064f9f3edddcdc2ca5348cd918072a74757511f81426f4392089611852cab1b131446c6f6fbfe5965bfafafae88788689a26992fca36e79c4b09740748f33e70c87046e86544a93f324b5f8c070080e488cada7999aa102e3449cc548bcac6d26d799e214cf30252d3911d4ccff23eb1bd2ecc58645dd1931414142022b1d7a2458b4e9c38a1467959591963ccebf51615155996555454c4390f0402e17038180cea5eabd5ab571f3c78f0c48913cb972f8fc5621e8f87beadafaf678c5d79e5952fbffcf28a152b2a2b2bfd7eff92254b76efde5d5e5ebe6ad5aa9c9c9ce79f7f9e31d6d2d2e2f57aebeaea482928dc9081ac66a3a0e9c40c0203d0d84b4ac9581a6232790b919f87126486730b3280051a8d65024ba942f2f9a9551d3b43480fd2b313cee2f1b8cba23fcf18f8dd08eedebdfb8b5ffce25c5f33c6c87272e911a6b91cc3e1706e6eaeabcf142dcdcccce4e5e541baaf52e9538282ba268dd764cdd26f0ae99d4d68b8eaaaab94e9a693a5d4dca1a9af24634966d5288dcc2f70dd11d2c1972a70d711120526753c93ae20092947672fc29810424aa1967614c2946721e57bb76ddb4e241cb2b4e82f15e2f1782c168bc5628944821c5dbf0ddea278ac0b9ee648e81f98f8f71f3f723ec6a24e6a68685094ab2c47c2010d173aa294a3ee5ed77f483a8bc849fd45cd4145aa4d1d07cd89c0668d7420e5487797a9e8280293be4c04e9ae07c6409dec2233d0e09e0962adec8e83cd6c2ebde97554417660a591961eb02584300c432944c3701cc7b06d9bb1a42fde300cbd79d5c88cc56274b5df235791cc092cd7881f1f1f07008fc7535858a8ba1935c348ef7bfd69d5576a9edcd7d7c7182b2828282d2dedefefcfc9c9f1f97c524a8a804829cdd91f22e2cc4ce8dcb9738cb1aaaaaae2e262ddc803cd32dbb3674f6b6b2b68d0b46dbbbfbfbfbebebeb3f30c22363636a61e8dea4908e398f28fe880cc6c0a484d33610e073d4092d5084e52ca74fe121a7b6577c73b8e300c3daec649319663db36e736cd91492192a347ad5bd3b88dc7e3e4cdf9cfc0e23f2f170616000c0e0e92772a1e8f8f8d8d959494a8e98cc7e389c7e30040da90ce618ce5e4e4d000628ce5e6e6aabe3f70e0406d6d2d00f4f6f67abddef2f272cef9b163c7a4948b162df2f97ce1701811fd7e3f63a8f0f9da6bafd10ce0c89123ebd7afcfcdcd0d87c3524abaa9e338d168d4e7f3ad5fbf9e31160a8568c4070281898989ddbb77df76db6d75757554e770380c0039393e9f2f170066666668699c060c6481913a225d47cedfb204d64cb5e832e4d38105223d608bf0a42c2dce136aad9a809569d7d3904b2412cab07355e93f81967721e75385d47c131313a669124f103e62b1d8d1a3474b4a4a02810022cecccc20625e5e5e7d7dfda953a7e2f1b8d7eb6d6969397bf62c7db57af56a4879de0381c0d0d0d0f2e5cb9b9a9a00a0adadcdeff77775750180d7ebcdcbcba355c54020b06edd3a0049966c6e6e6e7f7fff962d5bc8c171ead4a9d3a74f03404e4e8ed7eb3d7bf66c5151d1aa55ab9e79e699cf7ef6b3ffe7fffc1f5a036869693977ee5c7f7fff2bafbc525d5d2984c8cfcf7ffef9e7ebebeb0dc3bce69a0f0e0e0e1e3c781011f7eeddfb4ffff44f8a6e219db021c9c112208bc1e76a2ec87074a9b2c8e632cd0496d28c3ab6484cd354361679e439e7a6692a84e91346e22d32fe7ef704961d58ba1aca3c428c327ffe7ccef9db6fbfbd7efd7acef99b6fbed9d0d03039395958584806f5c4c4444e4e4e3018d44d8165cb9645229103070ef8fdfea54b9752732c5ebc5808b164c9929d3b7746a351cbb242a110d95288cc30d8e6cd9bc3e1f0d34f3f5d5d5dbd6eddba93274fae59b3a6a2a222140a1d3972a4b9b979d3a64d645830c68a8a8a6ebef9e6a1a1a1d75e7bedda6baf1d1c1cbcf5d65bdf7aeb0dd262ab57aff9c007ae7efcf19f44a3d1f6f6f6b56bd72e58b0a0a7a7c73066d706a8aaa428534fcc102fec03d3cbae1ed5f9c3c55b19c696a60993c6bbed38c45b42018b6682a4160958fa5f82573c1effed99f3e7972cc07261282f2f6f686888ba2d168b4522914020609aa66ebc43aa3fd6ac59333535f5ce3bef7cf0831f5cb56a552814faf5af7f5d5d5dad4e387af4e8b265cb366dda74e8d021f24ee9bdc539ffc0073e909797b77fff7efa48cec383070f6ed8b0e1e69b6fdeb16347381ca6f901001c3870c0b2acfcfc7c445455523a882c5ce23c00340c8e698be5689aa60284659999062268ee56575521ddfc9f0b583047800d645bed4937b692f84af73b086563d15fd334095e2e6029ab2b168b292f97d4e6e3bf6d9c5dd8c6f2783cf5f5f59d9d9d524aafd7dbd0d02084208b8431b66eddba43870e31c6366cd880886d6d6df1789cd6863b3a3a262626aeb8e20a96f27372cee7cf9fffeaabaf32c6eaeaeaaaababc91a2b2f2f3f74e8d0fefdfbafbbeeba5dbb76c562b12bafbc529965a669363434ecd8b1030056ad5a55545474fdf5d73ffffcf3afbffefa35d75c33353595b2e160c992c59cb3e1e1e19ffce4f1fcfcfcdb6fbf0d11376edcf0f8e38fb5b66e06809c9c1cbfdf6f59564bcba28282825b6fbdf5c9279fdcb3674f6f6f2fa150c750c67464d693a2939966eca7b95855c7c9a44b295996326bfc96c814ddef409248d88ee3e8ee06cbb2e2f1b8699aa669241296699ab1584c995c04b2482442d852d5fb1de847b71f8bda487129610211e92f00505d31e56260a930187a0c2acce57a505fa95ba86f953f42ef5dae39e25d7f792a5022759159a6f98fff78eceebbef028d7af59979ea2fa7c38f3ffef8c0c0c0860d1baeb862936b02ef9ac923ce3a41c0bd1c09906175a98faefe23ee57bc25d23cf2367d2418c994f7c1656c11b014b64827d26430164bc462b168344a7fa3d1682412a1bf04539d32219d4dcf2fff593f96cef6d4cafa41d5d3d9da3d6d3107534e54c5043aaa14924819214ab2d35db8d1094355462f68159bc5d05d77fd49068cd26a4548a6fdd977df7d77ea20e827b89e51014b5549b5925ec88a30ad6fd274a2d0d616530ad11019eef8cc49a20e2f17b00c234eb63cfd55ca111175de52085335ff8deb47433db3aba5f4f2cccc0cc5ab048341cbb2f4c6559022cc8d8c8ca8a01a961ed8ce52ee4d7571652aa5fa72d6710ae9ee53d484a7c734a78813a4e620e5196b8e5981a56e3417b1651d3f2e2465226c2e4144179854e327e7845a59b7e8356c2532798b80459e77d38cc7e371cbb262b198490a320532d3342391482c16537852b7d06bf89bc2d69c8ca5da717a7a7a7a7a9aec989e9e9ef9f3e7c7e3f19c9c1caa1999c64e6a4fe6e1c387376fdeecf3f98410b40ee8f57ae9e139e75eaf37168b01402010d0d1e338895028645956201040e4b158cc711ccbb27c3e9f6ddb9148c4e3f1f8fd7e21049d9697978788b494e1f57afd7e7f22110b87c364c86752a3c28a52df8c71c6380028177626bd41ba32c50cd15b0c2e3a960b353d08d9226d149d28e5a551972184a0a51b42582291201f44cad84a10b02ccbd221a53fa6beaaa82a23b4f01bbd7abf0160651b7612405a9645cf505151415ff5f7f7070201ead4eaeaeae3c78f23a2dfeff7fbfd333333edededf3e6cdebececa4fe686e6e1e1b1b3b7efc7830185417f7fbfdab57af56fa6e7272eac8912388b868d1a28282c237df7c93ba7ce5ca95070e1c0000c6d8ead5ab0f1d3a148fc70dc3686969a9abab7bf1c51701a0b1b171f5ead5cf3df79c94b2a2a2e2ca2baf542a355334bbd000486a76fdfc4c246585545630bd676051417576bad595b6e623842384304d5bc1cbb66dcb9af53e58562c1e8f5b966959a6691a54a0b2f2d487c3611aba90314b9552eaeb0a1abcde35ce0c852aa965250000da22c818fa7cbedadada999999b6b6b6aaaaaab2b2b26030d8d5d5150a852ebffc7200181f1fafa9a9292e2e2e2929292c2c5cb366cdcccccc99336782c1203d30c16be9d2a5bb76eddab061434141c1134f3c41b348eab69e9edea9a9e9e9e9e940208f73c3b2ac0f7ef083d168341e8f4f4e4efec99ffc09b5c21b6fbcd1d4d4e4384e75757522913877eedcc68d1babaaaa10f1ecd9ce75ebd63634345896a520a2f11353ce439db1f4afb292134b77a6e890625956a92f2a90cb45063ab0327b5af747a8802d029969da3a6f5956c2b6139665c6e3718fc78ac52c8294c7635916e9c459cd383333432e2e35452000082132a94a523e86f7062cd51cba41a25421001415151517171f3972840244491fd1099b376f1e1919397af4e8962d5b306546d4d5d56dd8b061606040ad19d35d540f29bb5e0871f2e4c93beeb8a3a3a383e2fb002091489c39738634a6e338bdbdbd8cb19a9a9abbeeba6b7272b2bfbfbfb4b4f40b5ff8c2be7dfb5e78e185bff88bbff8ca57be7ce2c4899ffdec677ffbb77fab2fd0b2d40a5a06bc9236d6ecd3cea1f598b6c8ad70e652857315b2ca5cc062c9c80b3785e8eca58b3e5b246f966ddba66990214f68b22c2b1a8d1a86611896695aa66992a71e00c2e1308d7982296a3e088297fa88a9e5d1f708acb99a263f3f7f70709042af962d5b46dd6018467e7e3e35073933c95fb571e3c6d75f7f7deddab5f5f5f57bf6eca9aeae6e686850e6766d6d2d050c2e58b0800007009cf3ad5bb73efbecb38cb1152b56d4d7d78742a1eddbb72f5ebcb8b1b19131f6e4934fd6d6d66ed9b22510083cf1c4132525251ff9c8472627277ffef39f7bbddebffccbbf04807ffff77f47c4af7ffdebc458a4dd74964aff6bea7ca600e4fa08e916e705f10417825456d171e6d28f2e0e93e93e7ab26e95133565d11ba42528ec9bcc15afd7ebf546bd5eafc7e3314dd3ebf51a86e1f17888b77480a236bd10a9dc24f23d39bd66fd58ae31cdb97210709d03c8e1dbd3d3336fde3cea4597c67139c094a27115321590eb2000a800519d54a832f42da4ac6f7237b0d4ce0ebd3ea95a195a55d32ea8e349672c1d5873a1ea37052c4c9ff0cbf469a38e309769ef622fdb8eebfe2d9adf44a3d16834168944239148381c0e87c3333333333333535353c45b6ad3a27e4d5d0b0380940ec5409f5fb2fbb1309bf9c9d2cd5800f0783cae8d59fab7a4e3d40575e8406a6eafdc9beafa2cc347408b39e4e8d2fd08ba1b42619773c6b941b0516b1abae2cbb0b1189bdbae020d46176429058bf780aaccabe96521dc9bb3656a4d86c69bb290782a6adeb6b9e3085aaa36cdb865252ccb63591ecb8a9a2659f1a6528864ced33e06aeede857ca319d3211914929f4fa9ce7a1d210001ab694c462b1a9a9292a575555a976577f55afa84916a4b679a91a28673d9d494cceb53d612e08d299b4fc0700a74e9da2dd13ca605208534b84d44caaac9fe9fa9b391ef481e142d205592af3cc7725aa89327fce525697faca657b119e74f6d2c29a2dc3306ddb36cd38595796657abd1ed3b4c8fcf2783c86615039140a116f51b8845aa0d4af0c00528294b3b3d7f38b9bb194a883535353939393a5a5a5e42b4f241200402a3c1c0e33c6c8ab445bc1a8aeb66d5324bb629768344a4abda8a88828daebf5e6e6e6c6e3f16834ca392757052216151531c61cc7999e9e360ca3b8b8787a7afae9a79f0e0683656565e170d8b6edbcbc3c6a97f3404a1dd42513582e96826c632c1307734121eb997389de3de73959ffca052cd066153ac2582ac89bd6aa0dc3304d6e9a8665599c2721a5788b9a8574a26118345b64a95dd7ae479612016cc56030376fcd69bceb4f1a0e8727272783c16028143a7af46830182c2e2ea6480782c2bc79f37ef9cb5f363434e804b06cd9b2fcfc7caaf7ce9d3b0b0a0a0cc358be7c795b5b1bb5c8ba75eb3a3a3a3a3a3a82c120a41cee8585855bb66cd9b3670fd1646363632412191e1e7ef5d557376fdefcfaebaf533b6edbb6adb8b858a12733e4cdc5583887631d3424b1740f4256ae3a0f14de2d63659eefea241751e9c731e50cc39416d611464cc6b5edbe8984619a663c1e378ce43cd14ae9459e8ae8a27d759c73da78cc18a32d1b645a21a2c219a652c99de7e9b2ec5cc8ec86e2e2e29a9a1a62a6c2c2c2969696aaaaaa9e9e9ee5cb97af58b1e2cc993388989797b77efdfa79f3e671ce376cd8609ae6f4f4b48eb3d5ab576fddba3591481c3f7e7c7272726868889617d6ac5973dd75d78d8c8c7ce0031fb8f1c61bdbdada18636d6d6d1ffde8473ff4a10f1d3c7870f3e6cdb5b5b51ffff8c7c7c6c60e1c38303e3e7eeedc3972cdeb42b36ba252d56a6ac9cc302c1d7c2e0e73995f982eae1e9d4bde15aa2063b3eb5cd7d78fb33944276962236a0d5af9c84989cf97ebf7fbf3f2f20281407e7e7e41414161612139928a8b8b0b0a0a7c3e5f6e6eaecfe74bcd25bd1e8f87e6927a18346a964386240f1aaea782d9f141de0b94529aa6e9f3e5902aa499a0321e410b3057131cbd7bd4f5fd7e3f1d5fba74696b6beba953a7687ca856a34ad395692b018585509309e170ceaebe7aeb873ffce137df7cd3e7cbd11759796a8b818e9bf4567063c6359c5423b8dbe9bd9ae417948bbcb2eb348545577f2998a2c6617c766722e3dc300c9bf33871bcce55aadd88b7e823adc229f652463d240334923e7a210459f4a9fa256bcbefbefbee9d3b77ce311a92ebbba669e4e6fa1093dd43bb0b6b6b6b0f1e3c383030b079f3667a98d2d252eaddc2c24221447e7e3e6d4625cd4ddba3f3f3f31389c49b6fbe595c5c3c6fde3cc7710a0a0ae8605d5d1d3d406363e392254b7ef6b39f7577777fea539f324db3a6a6fac9279fbcf1c68f0c0f8fbcf0c20b0b172e6c6969219b540dd014336589a54c27a92cd6fa5c3dfddb43d57b964c76d49f622e36a5ae7419a0aa5df4725624606ad1dad562a9b2ee8ac39950e4a69b6f4cfab15c574fb7519000ce987b1a8f19d334963eff5205e5178094e709538b743cddcae69a25ae06966130c5f38661706ed027c698ee4bd3eb80191cc532e6b3f00702a60b8aee59957378edc9ae5761cdb66dd36ec470384cfeada9a9a9e9e9e9a9a9a95028140a85e85be50c8bc7e3e17098d488ba1ad115396ee9be8e60fd8363b37eacb9da57a9290aab8174cb40f51c4bf738b88e732dd0457dc593bb960da50dd3d1cc15c24cd3e41c95914e568461989c73cbb220157bc8b2d9492cdd60820c60cdf5f87f583257f72960d1e313e55073a90d644a21b294f3999a91e223f40e2254a166ce03801069f7521530b2564b974824c6b91d08040060787898621cd4cdd4cfa93b2135b9dbb76f5f5555156937d020a88b6118c3c3c3dddddd8cb1050b16949797a3e605350ce3d8b163ab57af4644cb9a7dfeaf7ce5bf7ffbdbdf56b0a3f83017a4f47b41fafe7ac8c2e47f3ca2fa58ff0829bfb4f24460fafa8752057a984d241251656a6dfaa16a55917ab78010021110414ac952f111d93def7a4f4c4d4d398ee3f7fb11b1a3a3a3a2a20200c85d4bf3442a9ba649bbc1a2d1682291204f04638cf833100830c628fa6c6a6a4a6de2ebe8e8989999696a6adab973e7273ef109fa564a595656168fc77ff2939fd4d6d69696963a8e3336369e9beb2f2b2b8b44228383831e8fa7aaaacaa5705df0856c696d5d2dfec727f4ec3ab674a797de324a81a4cf7266f58c6e20616ac7a86a64f2cedbb69d7ebbe4ff49c6527ca3f310492010e8ebeb1342f4f7f7135dd1e641c6587171514343c3b3cf3edbdcdc8c880d0d0df9f9f96d6d6d9c73cac7d7d7d777ead429bae0d5575fbd73e74ec330727373376fdeecf57aa9ea7575754b972efdf5af7f4d1cf6e69b6fc66231bfdfdfd2d2323232b26bd7ae6baeb9e6a59776716e20626b6bebf8f8f88e1d3b1863ab57afbeeaaaab0c2d894d26b054416ff7df591fff1e45a72e0535fda348ed9663e906314f8532eb1c46ca818c33a5af085298ca752393e137000038d7f62fbdecf7fb29a9dfe0e020adab74767652688365998c617171f1dab56b7b7b7b07070769696fe3c68de4d21d1a1aaaacac5cbc78f14f7ffa53d2f46bd7ae25fda8eaf7d24b2f1d3c78f08a2baef0f97c030303838383894462dfbe7d77dc71475d5ddda73ffd6944fcc10f3abff39defd05cb7bcbcfcde7befedeaea7aecb1c7aeb9e61ad40c3b4dcd6647d57f6571e109344251f330430b34a51ed4a774e480500d4e20538d4c4b408849fc1830778490427d6363e33befbc535050e0f17800c0e7f3ad5dbb564ad1d7d7ab8f0348a91ef279c854e24dda684f972295cab489dbb5d75ebb6ad52a1a19bb76edbae9a69b82c1e0030f3c40eb59e4ca324d331a8d76767646229194399f1c64466a63990b55a08d90ffb2f0d21f5c5f0282f485735d39426a5f024fe55c5142fb1e582a864035b5d4f7e2a6ae96f463299cba9c194489393939939393e5e5e50505058cb18a8a8a43870e8e8c8cae58b182732e84a43519b27b6cdba618e2a6a6a679f3e675777753c285929212c7c07407f10000200049444154712a2b2bbd5e2fa6e62652caa2a2a2a2a2225a6458bb76ed33cf3cf3f6db6fd7d7d7af59b366f3e6cddffffef71b1a1a56ae5cf9e8a38f0a21b66ddb168bc556ac5841cfbf70e142d09282b8947866e3fe5796aceda05b5da859f4a8d95b0a09762a8d20fd8469e9a252d7472171727266dbb68fe0eeddbbefbdf7de4c5f991223fb5a2fd37e925cc85444aa2e95fa385b63f242697e04a642662d4bf7769aa669e96a5eaf926b0ccca5fb2e416a2ec9f475a9fd1a898463db71da99180a4d8742a1e9e9997038140e8729eb6c384c1b15c3b1583c1289ead9b96cdb8ec5c5c9cede1fffe8e12c36d6f91717535d486f526588d9932fea5301962e9cb3142e19e79c60639ab3735dd3b414dad45c57815b7795b1f4384fb804a68b13971ed47a9cfa1420a9349d94964444a46016ea41445214e07222d9e02033386717d862af975dca25abaec9d447ea084bf78c93e87bdfd20bee7834f52bcc70535d02d37b10d4628ef526a5659b940d2e54e42da6fc4abad50400442e8a416c48004821b3bdfd2b2b50f48f1714977ace60ac59b5e89ad3aa8fda97690b4deaca900ee2cc9a5f920b8a0b5b3a23687cc669295008e1f3f9b8e6184f619191479454aa25d0b23c9075c32a64e3a44c846516e602990b55ca5c53b849d958b4c7d29395ab7460b92a039720f55e25b319313531d4466fd2bdae12e8e97fd50974b22de2866571ceb3b81b94e82b9a7a3d30fdf5a4e7879d8257e69c40d78014dc9819c5a1e82a2ba42ee1e93722991dca53a150a9f6968ee3e4f8bcc82432c958daaa06f931a86b623600a024cfbb2e2e24a91bbbca2ee674955d44e532ad5c5acf300cd3b42810cf30b218ecba5ed7ef059780f59b139c557f6939b40cc3204795e3385eaf37454e28936f53231b1f2015df17b3933134b34941f4d00b75b3b97aee3cfd3a9736d4dd198aab14b05c6696ee5960d95ceabfa1f6bc24b392e22df27192218b8c0995a924272787ba82ba84b3e4444a4a50f67bcc06d3f220b25960e937b8c87a4086363c0f9e748b2a6b805e567f9502169b7b4bfb25f94d09e935ea5248b211722e01a410c2b22c4afc9ca43786a954f552d9efde84b42c0fe8c0ca642c57848d8b2db2424a6797ac66bb42921ea1711eae22d1ef089720f5db14d27400b39beb39e700d2341dcb3215b0280247cec6d12497ec62362072649834de5d5da59b72b443abb8b81800c6c74773737303813c1d7ceab78cb14824128944f2f3f3fbfafa9a9b9b8f1e6d5bb76ead6eaa93e2b32ccfd4d4f4d8d81891164562353434189aef5ec1544af9da6baf0d0e0ede74d34da669d2bdc47973e4f7f6f6161717e7e4e4b8a247b4b6bb241710b2b7685d9931e4dc608c53900153af1711699a444a1917066316673ccd78d7579455e461381c1e1818a0d0abfefe7ecac24d7b1a69871aed31a21061afd74bc9b11091d69da91294963d27274719583d3d3d5eafb7b8b8d834cd6030681886949202617d3e1f22d2269f929292f1f1f18e8e8e6ddbb61986313333138bc57c3e9fcfe7a34834c330a6a7a7f3f2f214453ff3cc331d1d1d77de792725f122a1bc5c9665cdcccce4e6e6aae6b8241992d6328cd1eb972563f4ca5c4936bde39800407a33b5195f0ae18dda68581ee4861b58b41f4d7d040044aca8a8e8e9e9f1f97c15151504a3a1a111c33000a0b2b292733e3a3a1a8d460b0b0b8b8b8b2726266a6aaae93d6f24d168b4bfbf9f73ded0d0505353a3b6b30d0d0d251289cb2ebbececd9b300505050f0da6baf353636363535f5f6f652944f7979b9e338131313870e1d5abc78f1e1c38709ca9b366d1a1d1d3d7dfa745353d3891327b66eddaa388952df82c6a652ca89898983070f2e5fbefcc89123adadad14a67149ce23aae9a8cc38e39c01ccfa4b89d2104082044cfee789a1c7eb1342ccbe99dd6551b9ee515252629a26bde69476f8d7d4d478bdde5028949393535252e2f7fbababab53bd9b34fd48a98d8c8c8442a1b1b1b1f1f17142151d5fb264c9860d1b688f35a179debc795bb76e6d6868387cf8f0e8e8e8f8f8f8f8f8f8d2a54b83c1b2abaeba8a12246fdd7a95e3d8d3d3d3b5b5354b972eddb76fef962dad988a34026de64c1fe9785959596b6bebeeddbbb76cd94291f297e4dd894cce1695ad6c59a665591eafe5f1585eaf2727c7ebcbf1fa7c3e5aea9d652c32c7941274d9f294c85a085b19e6f4e203c6d8f4f4f4c4c4447d7d7dca2a023d9c81733e3c3cdcdada3a3a3a4a9bb89593dde7f35166479edab94b498e10b1a8a8e8861b6e88c562f4060a008928394700110e87e816b69d686b3b5c5252dcdbdb535b5baff044595c296f9b65591d1d1db9b9b9e5e5e5148d73faf4e9850b17669a959724aba8f91220622a49ac917cb7439244548271218437870909525f2b54d4e70296c7e3414432a11c07737373bd5e6f4141416f6f6f414141717171341a751ca7b3b3b3b2b23210081417177bbdded2d252afd75b59596918c665975dd6d6d6669a667373b3f22954575717161692c955525242a8226001c0b66ddb76edda6559d6b5d75e2ba5a4c8d579f3e685c3e1175f7cb1a5a5a5acacaca3a363d9b265454545fbf6edabab6b5095dfb3670f63ec9d77de098542f46643cbb28686861a1b1b2b2b2b0f1f3e4c59a37ec73df4072b842c49b37d917aef1f1942866112aa94ba8824129c1b8cf3e4be424ca59e520e4cf57768680867f70f424a6de9f158fa466454cb7c0a4364e3ebb342e57ed77d0aa8852f8af45cab884038a74252bb2353cf93c940cae492e9919300505c5c7cf5d557ff2e3ae58f4784e3d86363a3002052a90553698f9c44c28ec762f178221a8d8c4c26befba35ffced57ff2ccd8f45d0d3fb00002a2a2a08289c73d3e4a9b0e0a44643443ae2f1780c8393de255129e4727272288980d7ebddb76f9f10927605aab54ce55c808c77e6ba4cc8cc27569c2c5391d0904a9c44b95668cea23f54381c7ee699677e1bcdff4721126613432647351d8f46231292ce5241db54a51002ec84ad52a1066b16d88e340cc30dacd9cb6b47c80052b630003096748011d998a68128e93d4724466a03a49eb4830cb29b6eba598b1ab574572aa4984687978eadcc8f591a467b6f8ca26ee5d65346fd2599430424d3762485862a24bb66364fbdca2468db0ea5d77af3cd3723b6e3f70740a6b67fa9812ed3dfa607e99376853dd53d29379a60cc90a99dcd86160c33ab5e558ca8c10d831b866970132570ce90736086403010410ace68c580f2c7314555a8c50fe970919aef0d6717530152af06861411722d93e0259943d0052c489b6873982517e41c543c16005896954818001250ce7ade7524e953427d9e28255254853a8700a6bbcb5df10b86617083f6c49b86e9b5d0b0386326e3a6c98173c61c89532139383a24018305f97e0ffa730d44905200080006022403a979105c6b3b991f75845d243fd113b914b16a10966d738be23f9d4d5dacaf9fe0aa893e2ab2f6a2abfd7f4b5cebaa3ca2db75ac46b55e432a28eb85e689866140021004809c558599d8d2e582f5d3359a5aef330cc3340dc364a6c90d6e71e691e865dc070800091b65df343cf1dc5bcffdf22d07510008277efb75ab6fbd764379519e6971641c24200315a4011a835e647b5de44f745666a9fd272e64b83eb2543a50d77d754ed5b19e79c7cc85a94c2c5ee4f3be37c93a9c2e287af53015a34c3d3e3232e83836ba723748cd783f0fb654639164e2299db44cd3b00cc334381aa6044348c60cce19b3e30eee7cf5f08f7ef2cab296ba4fddb9d5c3e1c489b363839de3a363967482e5450250a2c30111b894108fc7295f0a259238ff93438a51cebfaa789e56cb9cc764823b93ae1863333333f4966b4ca54d8f46a3b9b9b9ae1b4929676666d46439f316945f93ea407b337f1bae5dbabee338b1582cb3927389ae25582aab19636c606020140e4b2993968afe9bb9882af3086aa2b0a53c0bb33616332dc60d8e9c03e38259028d042224e24e643aeed846ff44fcedc39da199d8075ad77ef9eedb6bce9c883dfd54b4eb0c170e93f2a9a79e7cfae9a711f1e5975ffee10f7f78d75d775df0b1a5942323230f3df4d077bffbddac6c9129ededed0f3ef8e0830f3e78f8f061c8b0de7efef39feb5c3e3030b06fdf3e1d52b66d7feb5bdf7af0c1079f7cf2c92f7de94b2323238a6c060606befad5af6665acbbefbefb9ffee99f0e1d3aa4aaad6ed1d7d7f7cd6f7e736c6c8cbefac10f7eb067cf9e0b3ec5bb15f58cd3d3d3fff88fffd8ddddfd6e7fae0380731e0e8785e3d84266598456c63b686012da5bf6a46631e06cd8b18a27263ca9776c58a6e121539d732f479303e3c86c3bee318c0f5fb5bcb36fe4f523677ef4d3973da6599203dfbff30adf23ff1aee3a6d6e5807028687479fffc52ed332376cd8a86ba843870e85c3e1a54b97d2bb99a8ce866144a3d1f2f27200c8cbcbbbe1861bfefaaffffaaffeeaaf8e1f3f3e3131416f2da013bababacacacac6c6c6bababacacbcbabaaaa1e7ae8a17befbd170082c1e0cccccce1c387737272cacaca7c3edff8f8782010181d1dede8e80080c6c6c6aeaeae1ffff8c7a6695e76d965049d871f7ef8b6db6e9352060281175e78414ad9d5d5d5d3d3535353c3391f181878e38d374a4b4b9b9a9ac6c7c78f1f3f1e0804e8c5d5c44667ce9c99376fdef0f030e7bcb8b8584af9faebaf2f5cb8b0b4b4f4dcb973dddddd67cf9e6d6969191e1eeee8e8282a2a5ab870e1debd7b6ddbf6f97c2b56ac88c562f41a07bac5ebafbf0e006bd7aeede9e9c9cbcb9b9999090683fbf7efe79caf5bb7aebdbd9d36fab6b7b73737371f387020168b2d5fbe7cd1a245afbdf6dac73ffef177054addf263a9a02983b3341b0b002863ae4cbd04817e4c077585a28c0c52b28c513234d330684ba08780651896699adcb09019c82dce4c8696c17c28111d99884e979615fcf77bb79deb1ae81d1cd9f95aef1bbb7e6df78f8c0f0e54ce5f6854d60a349e7ef6b99b6ebe29140abdf0c20ba5a5a5a4da9e7aeaa9bebe3e9fcff7fcf3cf575757575757cfccccd8b65d525272faf4697a57856559cdcdcd143973eedcb9dedede1d3b765c7ef9e5bdbdbd9ffef4a7ffe55ffee5aebbee4a2412edededafbcf2ca75d75dd7d4d4f4ad6f7d6bc992255ffce217bff18d6fd4d7d71344f6efdfffc52f7ef1bbdffdeeedb7dffeeaabafae59b3e617bff8c5a64d9b868787cf9e3d7bd965974929b76fdfbe7efd7a5a29223975ead4eeddbbabaaaa5e7ae9a5abaeba8ac0b467cf9eabaeba2a180cb6b7b74f4e4ef6f5f551b30f0d0dfde4273ff9dffffb7fbff0c20b5eaff7965b6e0180c71f7ffca9a79eeae9e979e491476a6b6bfbfbfba594131313ededed6363634343435ffdea57fffccfff3c140a9d3d7bf6e4c993a5a5a59148e4adb7de5ab76e1dad2bbcf1c61bbdbdbde3e3e39ffbdce71e7becb192921221c4d1a3479f7df6d9279f7c1200bef6b5afdd7efbed6363631e8fa7b9b9f9d65b6fbde5965b2e1e580a5e8a5f0855b6e360d6a4200429656909212841b2611894f918b47dfe0070ead4a9a54b972af795cbd7c0180c0c753736d61b864033215818588ca3650b8845f9bf3dfef4c9fef0f51f5892979b5b17c4d3793cd78747c7069b6eff2882134dc45efbf5eb850505f178d4b6ed6ddbb6d1331c3c78f08e3bee58bc78f14d37dd545d5d1d8fc79f7cf249c3306ebdf556d0cc70aadec9932777edda353e3efeca2bafdc77df7d5ffad29776ecd8919797575959f9ed6f7fbbabababbdbd7de5ca955ffef2970160e7ce9dfff22fff72e4c891fbefbf1f00fee7fffc9f5ffad297d6af5f4f03acb5b5f5631ffbd8a73ffde9582cb666cd9a9b6eba09346df2e69b6ffeebbffeebc8c84830181c1e1ef67abdf7dc73cf3ffcc33f0c0f0fb7b4b4fcd99ffdd97ffcc77f747676eed9b3e7d8b16303030394be4c4a595353d3dcdcbc63c78e9d3b77fef8c73fd695e6c4c484e338f7dc734f2814b26dfba9a79eeae8e8e8eeee2e2c2caca8a8f8d33ffdd3c3870fffec673f3b72e4c8f6eddb272727f7eeddbb7bf7ee8282020058b0600100d02079e08107b66fdf3e3131f1d77ffdd7a04d1100a0bdbd9d5216b80cca8b44956ec5d3253d1e4b660596cbc6a2355d7a25d3c4c444797939414d4a49a6250090833b168b1986e1f7fb559016b9288fb4b515151706cbca1832ce2c86a604c63d1ee491eaaad2b74fecffce0f9ef619867412375c7999333d222f5b0e5bae80dc4068726a6a6cf4cffffc5308f2fefbef8fc7e354c3e2e2e2bebe3ece795151d1473ef291bffffbbfbffffefb11f1a1871ebaefbefba8d53a3b3b63b1587171f13befbc73d96597ad5cb9726060404af9dffedb7ffbd6b7bef5f5af7f9d427deebdf7de279e78424a79f2e44929e5d8d8182d80b6b7b77b3c1e993e47ebebeb6b6f6fa70cf5b43cdad0d00000dbb66d7be491476ebdf5d62f7ff9cb5ffbdad710312727c7b6ed13274ed076bcf1f1f1f6f6f65028442fbafaea57bf7af0e0c1dede5e350c6eb9e596fbeebbefeffeeeef543f1516168e8f8f9303f9c489134343437575759d9d9df7de7befabafbeeaeab2b2b232ba3e225656567ef6b39f0580175e7801b4e08ef6f6f670385c51511108044e9e3c89888ee35c75d5554d4d4ddffbdef7e8656c454545ef0a583ac252b8429080984a0a029a9dafce53e4462f0d080402b4b36c7c7c9c3cad94c1766262a2b2b2b2afaf2f914844a351cbb2727272ce9e3d1b8d46a7a6a62627a74687c72dcba8aaae360cefc9a3ed4b972d032698c9189339a6b97ac5e28deb566ede7859ebcae62b1754e081b71a5b5af2d7ae83fc3ce4100c96b55e79655d6d2da5010f06837575759ffce4275f7df5d583070f7ee10b5fa010b1cb2fbfbcb8b8d8b6edd5ab5753fdb76fdffece3bef7cfef39fdfb871e3891327de7aebadfafafa4d9b36959494241289356bd61416160602815dbb7699a6b971e3c69ffffce7a4506ebbedb655ab563df9e4930303036bd7aea53ce41e8fc7b6ed5ffdea57939393b7dc72cbc68d1b8510070e1ca0b11e0804366edcf8e8a38f9e3871a2b5b575c58a15975f7e3963ece5975fdeb469d3ba75eb7a7a7a4e9e3cd9d8d8f8a10f7d68e9d2a53b76ec989a9a6a6d6d6d6c6c5cba74696d6dedd9b36743a1d00d37dca068a0b8b8f8b9e79ebbfefaeb7372725e7cf145afd7bb75ebd6152b563cf7dc73b158acb5b5b5aaaa8ad6e60b0b0b3ff1894f3cfef8e3c78f1f1f1b1b7bf8e1871f7df4d18e8e8ecf7ce6333e9f6fdebc795eafb7b5b5f5f1c71fefe9e9f99bbff99b0f7de843fff66fff76e2c4898d1b378642a1d75f7ffd861b6e58b972e5c30f3ffcc10f7eb0bebefe3d408aca3d3d3d274e75f50c4e6dddb236b9082d356709a627dd52612dd168343f3fbfa8a8a8bbbb9bde059f9f9f5f5b5bdbd5d5bd6ad5cafdfbf79797979ba6595f5f5f5555d5d5d575c51597536e8f3dbf7aedfa1b3e6c9a1c99b163fbcf6fbbf5a38c338912016391f8f0c8c8f0c8d8c4e4e4f4e8d0f2e2e2e9a79ef257d7d67eea53bc381f90a2323842da1c8dea29354f8faba04e40cce22592e99ec9cc73f4565347f6ecd9c339dfb871e35cd777fd5066f83f51858a672c4ffdf297bfacaaaa5ab66c993a6edbf6638f3d76edb5d7d2ab905db7732d558d8e8e7ee52b5ff17abddffce637c965e0aaa4fedbaccd323a3afacc33cf505245784f22a57ce38d3776fcf2e5378ef43ff0779fc992dc5659ee2494bc86f2ca8f8d8d151515599655555565180665e2a254cf8585858b172f668c0148d3e486c11289f8c8c8707e7e2133a51d4f780c0b99b4c1013450220321113d3eabaaa6bca8b8301c8a826c2908e45a576c04e4c00c4004100000080859767de92321f329323faa23fadf4c99eb579b376f3eff99593fba0eea5e53fdcc0f7ff8c3ae8b1b86e172ace8bf62e91b4c8a8b8b1f79e491f33c8e4b1d659e53525272cf3df764bdc20545731400801420c115e0ec3a9510669aa66ddb131313a3a3a395959552cacacacaa1a1a1b1b1b16030c8182b2b2b310c63e1c285dddddde3e3e37575758140a0bebebeaded18220f0683ebd6ad3fb0ff8094827364c89021224826054a00ced0f2fb73cb822565e565566e2e985e304c6000e0d082e8a515e3f7bf28fa5488cf9e6d469116f1b6cfe7a30098e46f0ca3aaaa4aed8ca0b0f7dcdcdc8a8a8adcdc1cce99699a959595f3e6cda7f098d292b2cacd15a6c1a4040426410a262538034363f168824990cc010040968c7f257e22ba920c00defd0b3e2fc9ef48a494a4be207d1d624e60296c01a86d1849c7a98acb63a97436ba287f29d96a8c31864c220043868c4948e65f023e3d351d9909a7de9d2149e7c9b48541018020f112b0decf525151a1dce9aae7e6cc8fa56cac582c46963be520d50d1ac6d8e4e4647e7ebea16d9ce79cbffaeaabd75d778365790867c88171268171a40cc72025306634373581745002484322204a090201019894800c40da800c24bb04acf7ad2830e96973612e1b0b34338b3c0ba6694e4e4e924f8f5e8001008ee39c3b772e1289d0d5676666c2e1b0699a52c2e4e4e4d8d818638c193c9e888f8e8d854221482a3849ffa20404940c05038920404ab005c4250a40904229c70b6c22ba24bf47514443415373aa420540b59243e1a31e8f271a8dcad416d64422110e876b6b6b6ddb1e1f1fcfcbcb3b73e68cdfef9b9818a378e89e9e1ed33443a1d0c2850b0f1c389093e39336d4d5d44804218101a2049060331697381d8a0ff58f226049512090cbbc1e87230260cac613e42ed1661f9718ecfd2e73aa422542884824e2380ee536a69757d36b55962c59e2f7fbe7cf9f9f9b9bdbd9d9b96edd1a9fcf67599eb367bb56ad5ae538cedebd7b5b5a5a4e1c6fafada9038915c13260281184008e5248d13b16fb7f77bcb1fd97afa1344c01cc8e6cbb7ed34d1fd9585992e3350c04063209c5d41e8af305255f92f78f64cfe8a70a94153e3737b7a0a0803c6f535353656565f9f9f9fdfdfd908c464d0048cb326983bc94c98052994a6e595559bda5b575727cc2118e4410888c4b9076cc16cfbf7cf0d19fbcbc6cd1bc3fbd6bab81e2ec89aef1c1bec9a1611e376b6b2a1930092ce5c742f5de625a0bbb24ef67b940e8a0949256940180de9d422ff01d1919c9cbcb334d63e9d225dddd5da15068f9f265274f768c8d8dd7d737cc9b378fa2d21a1b1b19e3ebd7addbfff6db6313e33575b52091494481b62da289442896b0051f1e89bff1f699f1e9e81557acfa8b3ffd687e8e39d83b383315932801e54f7ffab3eddb774809afbcf2eaa38f3e7acf3df71067fd67a86bae9f4a09cf3fbf93cc41fda0ebfcac3fcf3ced8f5dc85c26713ff9f9542191566a232140aa2f83c1602010c8cdf5218261f0c58b17f9fd7ebfdf5f59594df94f5b5a5a1863a6693635352142694959696b29720920102407008484904cda1fdab2bcfbdcf89bfb4ffd7fdb5f791ca1d8c73f755bebd5eb5b6c470c0f8fe4063c4383832fed7a8996f37432ddb76f5f381c5eb162452814f27abd8e634b09a66986c3e1aaaa2a29211209efdbb7cfb2ac0d1b361c3972646c6caca5a5a5b4b4f4d4a9537d7d7d0d0d0dd3d3d38b172f8ac5e2ddddddd168746c6c0c00afb8e2f2402080c8ce9e3ddbdddd5d5b5b5b5f5f0f80005208387efcf8c8c8705353536eaeff9d770ee6e6e6ae5ab5fa9d770e4e4d4d2d5ebcf8e8d1a38b162d2a2d2d515b20ff58fd6f34ae51fd0b905c7c0390785e3f1664c42babf02ce5c47279b054c00cd712d132c610b9448e684b900828d1b1413044db8ecb44bcb220ffef3e7fe3d973fd5dc3c3cfbfdef3e24b07fe63c7af9beaab867a7a0af3f238f2679e7deec61b3f12894476ed7aa1acac0c4000889ffdeca7434343b9b9fe5dbb5eacadada9acaca278acd2d292d3a7cf7ce6337f09000f3ef8606d6d4d4e4e4e341a79fbedb78b8b8b9e7df6998f7decf6175e78b1b2b2a2a8a8f01bdff8c6f6eddbc7c747ffd7ff7ab0b7b78fa2a0f6ef7ffbe4c913f3e6358c8c0c9f3e7deae597777fe2139f983f7f9e9472efdebd7bf6ec292b2bada8087efffbdf6d6a6a0a87c367cf9ef9c10f1ef9f8c7ef78e699a7972e5df2ecb3cffec33ffc5f9c73486e7411296c5173672dff419c40e5d41227b0d451965c6ea3a006092cc55c1730def5b56bd7711d523c3d4f9a5a11a39013061280a3e40860086e024a01521a3311e3873f7aeeecb9f0b5d72cc8c9f395151a868857052bc6468763b168695949241a7d6dcfaf0bf20b62f1b8e3d837df7c33ed063b78f0d09d77ded9d2d272cb2db7d4d6d6d9b6f3d453db53f15848a12e4288b3673be7cd9bd7d171ea95575eadaeae0680fefec1c2c2a2bbefbe474a89c8a40429514a340cf3aebbee06809b6fbe39180c0e0e0e3dfbec73030303870e1dbaf6da0fcd9b371f919d3ddb595353fbb18f7d0c008e1e3d7efffd0f1c3b76ecb1c71ef3f97c77dffdc96ddbb63df8e0431ffbd8c71c4772ce523da19a4e6fc3ace53f9413644a03a2049e429c64b49f0a0053ef84ce1e8fa5f0948446ba0f09b3654156a1c90a5b2960210310296053da1b44302d049ea8ad2f6deb38f4af3ffa85e1f5d82271f5fa866b2e5f32d07decb2a52d798585539313d353d37ff5d9cf01c2dffffddfc7e3092911800583e5dddde71c47949494dc78e3b6af7ffdeb0f3cf000227ef39bfff8c003ff0300a5843befbcb3b3b3f3873ffcd1cd37df7cc71d1f5fbe7cf9f3cf3f9f9beb8f46636d6d4783c1b260b0bcadedd8e8e808210c1153290f717070d0e3f17efef39f7fe4911f22e2534f6dafaaaa2c2828e8e9e96d6b3b5a5959595c5c72f4e8d1dededeb2b2e0b163c7359812d3d3ecf58f729913013840b213096812a4ca642452bbc766e3b1745101a2a825f53629155f6ab3bcd7ebcdc9f17a3c1e5a49f4782ccbf2a8f7bd1ada2b5f111198838828b1adede8e2a54b2552fa53c763e1aa150b37adbbecf20d2bd65e36bfaa08477bdb9b1aaa962d5beecbf5338615e5e59b5b375757571517152f6a59585e5eded0d870d79ffcc9ebaffffa68dbd1cf7dee73e5e54100d8b86163515111805cb56a259937cf3efb6c5767d7bdf77e69ddfab5a74f9f3eb0ffc075d75db766cdaa5028f4c61bafe70502b7defad1a79e7a6aa0bfffca2bb72c5eb2b879c10244c8cdf5ad58be7cd3c68d1e8f67cf9e3df9f9f99b366da204716b56af1e1818787bdfde9292e2ebaefbf0d33b9e7684f3e9bff80b5f8eafb9b9d9e7f32d6c5ee0cbf12d58d0c418a64c2ca9992090bdfc0771029553f6131d475a6e43c140d0603a77aef7c4a9aeeec1a9adad6b92f1586e58a6184b693a0adf0ba4242f2f2f2f2f505090eff7fbc913e1f7fb737272294d034150119864201118302ef1899f3cfed13b6e73242072d3d1d229000020004944415414221e8b0c0d0f0d8e8c4c4ecff4f50d14e5172c6a6e2a2f2fcff1e548e0f424980cc7785fb6f87f911360165894c48ff6dc8394c024f1b494f2adb7f63efdcb5ffdea9d73fff7373e733e1b4ba9339dc0d4117dd5597d7459f7880888a95929720026012570644202209a5e5f79756da0b8241a892e59b4c4e7f35b1eaf69a0001032692ba6228f4026a3b220f978a9827ef0d209bf8d13a84c050180808c9c8bb480228121204894c89260bc08cf3ba48c2a1d5b991343caf4ad5035fb5b09966492094001c01c860ef0036d67a7224ed2880700402e81239372d2014959be84b2f604a4329ebc0fa74bff454ea0b294e45700c950825421acc0a4b372719d9835ede77875afc2906b8b331dd70fb20c416d6f741261487c0380e0208b21bc76b87378d2140e9aa6e3f77b2c14d158424800e0339184835cd0fd056788129de48fdf9d5c7c83ba7e75f1f7ca7a85b9cebc98cb62ea4c75b278f70ffe5b15044040074082e4122522a0742c88d43754da28043ae4ca72ef2b04009d995c204b2f2b84198c71c6d21268abc86e640840d93d90a6a40c001977c00878f9ca15f387c6675e79edede18969c9a48946635515e3122dd3e10cd00409000251203229194864520a260502022954701803290c52ba8c4263190a81201de4e4be6712053204218540e002009904104c32092810243a28912148e17069388092018264824b90923928414ac611413a120508608c3b92920a0bb54a2e9009449436938c014729040a4826cf0185120aec905232e0424a0406924904c61c47c419b35072900ea00d696e8bdfbf486014a222194a892825931229e51fa0b25ce65cd27141aabfbfbfabababafaf4fa5e16b6b3bdadedece184364fbf71ff8d5af7e451b788e1c39c239a7b5200010427cfffbdfff7f1efed778dc0600100e023040af215ad72e181e3cf7adeffce06c67ef156be66d5959579213c368ef8a0565109f0461834824ed7ee08e7000138cc519cea08c0330292582942805d892092925a014200448943647412e5994292b4f4a2105a3cba12905a5491212002432c1b810281c00c620ce20215148708009211d09201090315b0ac18444901c1392494489829cd052300493096042a0044426010069c432291093662f0d778152700652da063206923107514848300608524a313b0b4b4af2317ebfff4974547d18243da21239033092c0c22cc0d2cd23fa28a5eceeeececbcb2b2929b12cabbbbb9b31168944f6eeddbb7ffffe582cc639dfb163c78e1d3b2626267a7a7a5e78e1053dd4ff7bdffbdeea35ab57ae5af9375ffb2a4a0064024080a808e615e59bfd034333e1786961deeac575375ebde2eb5fbcfdcfeeb87a418daf20c796099b03e3c22ece85921cd3401e2cf336d77baedc58cbc10640a43c475270400426106c9482012020c6376daa924c220303eca23c1341308816e619e412052118200710208474508221c02b13ad1bea39b2b262637173314a01202524184f3a6a04381466e10814604ac61d1092de7e251100418029b0d4679ac8a4a0d04510422272004348261000510283a4df4b204a296d860220c621caa460c0a4701873001c98ed2a17c8deef32e7660a4871d5f8f8b8d7eb2d2c2c2c2929a9a9a9a105e6bd7bf75e73cd35353535c78e1d23f577fdf5d753ea0efab98a6ef8dce73eb77ad5aa53ed27376dd8c8504a602001c1f158322fcfb361c5fc05c1e203078e7eea8bdffde4bd3fbcffdbdba742f16041cea2ea62331163124c887e7873cd073795594ed4675a053e2ccbcbe1c2e16073e670699be070611bc2611218482e6c04c964b424cfe4e030276ac0d4559bca11a31e086fdd5883e870b419861043a6741808c61ccee2880994a1d27c0344d46bca7c3f3764c2820417920b30a53045c210094b240c11371832615b3261a0638063c9b825639c45184638844af31dc30000018ec3c006663bcc16dc06e6481012194a06e8204ae9380c2463518030930e9336979209692093d2d13a4400084c5bf47dbf4bf65921a68bcb4e97520e0e0e1e3f7e3c1c0e4f4c4c5e7bed871171e3c68ddff9ce77eaebeb11717474f41bdff8462010f8e77ffe6721e577bff7dda58b966ed97285045ba2231138909a4cac5e52f3837ffefc6b7b0fb79feaded736f8ca1b27fa7a06eefbc29d931353066331e62c6c0e1e3ddece396b5e5036134980700c296a8bd88225a5cce43d7dd308100d870c0b6d96170dc74af2e481e3330c8c7c9f75dd96da98e3741cebf4a1bcb1b5e148db998aa29c1bb6d4769ce85dbf6ed1d8f8f4e464ecc0f1d186faa2f0f4cc999ed8d557af7871d73b0c732f5b5eb7f3c5c38b1aca1beb0a2231d976a47ff9a212afcf1c1c8d9e3a3dbc7c51d0f07bcf9c196a5950f5dc8bed8539ceda95f372f3bce1581ca43c7dac77416351efe8d0fcf979f3ab7dd3d3917d6d63a1044a6117f9e5f245415faef778fb407ec05753951f8f8963c706375fde120a4d0d0e450a4a0b86c742078e0c08f06032a496316120a440f63eb2b52e20692f42517ca39bea454545a150281c0e47a3d1d1d1d1eeeeee50282484686c6cd8b0613d25fd4144d334efbefbee471e7904114b4a4a1e7ef8e1871e7a0800fec7fdf737d6372c58b06074641c00011c09200167a6e36393b1279e7be3b9570fafdbb0e04f3f79edb69b3703e78cc9a19181b33ddd710064b17c1f7a0de6b1588e250dee08860e42d382f2c3c73a77be72a2a1b1c4346cceedea8aa2ba324faee1980c106d04190ac577bd74e2e0be93cb16d73952fee2e58ec1e1c8c858e897af1c8f0bd1d135f2cb578e0b74f20a723b7b4383638e444083d9c261023843e188a52de5c37d23870f9e6da8cdaf28cd45908b9a839525fec84cf8a557da7bba863d06d20aa8c52507b9ebe5a3bb5f3eb2f2b27a64685809c3140cc4c2c6b2c2029f7018075e5d11181e9979f9e5f6fedef1f9f34a5edc7de4d8b1bee605f90927fed2cb076b6b8a76efeea8aa2820ff8a1414512200a4445ba2936172bdafe5c2ef84b62caba9a9e9dcb9738cb1c2c2c2f5ebd71b86b169d3a6e5cb971716165290d6d6ad5b29bbcbd6ad5bd7ac594330a5fdd34d4d4d7bf7eedbb777ffbcc6fabb3e79a7f2b9f50d4e9d3937da3f36f3c48e1d0f3fec14160546a667ea8225b75f7f79e7d99351614866e679a0b9b1f25ca757326c6c287aedcd76e4a64009f0ffb7f7ede15155d7a36bed7326f3ca242104f2180824e1150482bc0d6f44fa7105ca43a5b456fc4a8202f5b67e5fadd8a2adf5d3aff581a5404521d7801705a480a95cf50718a40a28af8072110821ef403299bc27999973f6ba7fec73ce9ccc24407f6dbddab2982f9cc7defbecb3f73a6bafbd9e5c2600ae30e09eebde0169c995353ea606937a455f2ef77292190455c420b3000408a520481c994240488841ce5540055980402522bbcda20455d6ee27e0804c26050839caefbd5fd42fd9f93fee1d79e142c5e9a28ba5150dfdd3fb1200b2280ba92838741e409d0352211ab80f000021a9b7c369a783878f678f1e4ac4dd4976b5dd0708049c1347440221a153051fc78971000249282d193040899340264d42a98b1ebf1bd06d4e6843107ae1c205c31e4655d50f3ffc50686cbefaeaaba8288bc562397ffe822449c78e1d13cbe5e5cb97df7efb6d6353a9f39dacaabaf2c8d1c35923ef94008013675127ce150f48edfd9b5facf436f890a9401d766b5479c9a55aaf0fac891616852a3f5fec3d59544bc47d0ab4fb9137f36b56ffb9d39563c60ccab45b4e9dbe565b4bfdd2ac178a1b18b4f748ec51e9092a602554aaeb7d0186ed60ad69502f7e5171cff4c1e7cf579d395b3d6b6ad695e2ca81e9c9b1713135558d5e8fcfed8ef3234f488b292bf72aaa347182fbd3cf2b55b08dbfab9fcb2e1dfaaca4c1db72e71dee2903075d2eb95e55e5bd63887bfa8c91978b6b3f3d5979f7dd2324e0b59e564b3b28646548d7eb3b3a02eab5ea769bd5316dfa645b942550521517c7da39bf52d238fc8ea4a93312bfbe78fdf3d355d36664b5fb82274f578e1a6955d176bdc1af22abf5b613325de980a8e5aa6100d4495bf7ad874eba426337279902f3092da108b1e272b962636385a5b2cbe58c898971b95c3131710e87c3e9748ad8eea22ee86e1b20364b9c010230be73c75fbebff8813776fdadac51e6416ef1b7f6b0c1a041c9310ea9f8d2c58a6a4f077372d623cad61365e4a81232028b36a614640c88889304c80855e0321222538090319543901310da1038e3c49814042e01930838282884469cfa244725a6c49d2caa619c11c82421417b66460c27eb952bd7664c4e3b76d2d3e25310397140b400e7c848416488c45504402671ce8008192754191071a6822c2149c48144386a154105e02a49c0800171625a945e9009383215891397004828bf8018810a0840320092a10c13bc1572cd7df7ff2b7004460840848424211100c9e85ff54056f5e52f0b3e3c7ca4a8f285a757de5ca52390a3a4a4c462b1c4c7c78f1e3d5a446c3f71e2547272a2881d75f4e851229a376f5e5d5d5d4d4dcdd8b1630d1c25a23fbff66740f6939c1c9bc5cab5bcc3845c952c32c7182fe77ffbb2c20e4109a5a03d8545d964e650515298c248884083888c83ca00402194101927e012070e2ac89c8003975402420ba205891831069c7305191057901821a90c114002acbae6afaabd46c448b21257382984f2a5cbad1c5a012d87ff5619240460848ccb5c520911388870a6b2ccacc003400a0340267312ab1a00a816a6aa80010446c84005520911d12a71524851183221d14540548908540094900171890123509029401202720832143828c444322111a8ecdbb12b6484421dc7743b5204356c9d0e8f9a0c9d6d66105155d5e2e2e2be7dfb0a678ae2e2e2b163c7b6b6b61e3f7ebc77efde23478e8a8b637bf7ee45c4499326d5d4d41c3a7468ecd8b146831b376e9c38f12e007ceac9d5afbefa2a310900927a58250c7021e26116801e327120e20c099013202a5c130d09e1070fe93c8134e52181b80ec22b517cdd141466429a151900222011681a7995116a0b0d0251401403000618f2320310c274224250751d3e0128080a8016e8105021129a0512da1d8e4655450c2ba00ac401c54aa6a2781b63ab445cc714ae795a86dcbe55938e4ed50ff83f1b49fe7e4021b42342105f2bf1a005558b042a20d77bdf058f6566b0841ccbe170242626daedf6989898d8d858443c76ecd8dcb973ebeaeace9d3b979c9c8c88f3e6cddbb3674f7676b6b92900f8e94f7f8a886f6d7b6bcae4c908403c2801ccffde782200049500f0661e1db7e15b06a4ff157a69094188e04b4865ba64243cfb5718185a6700d0fce51139e742fededcdc5c5f5f3f7bf66c00983c79f22bafbcd2af5f3f22f2783c6bd6ac713a9d7ffce31f0160dd9fd68fcc1a3165ca1400ce202891ca8833c63efdf453afb7e1dfd3d0f2df160ca462042884e83367ccb0daed00c48898ae88ea44b1bac4ad9e3d7b5655558930846d6d6d353535696969443464c810a7d3b96ddb3683bcfde4273ff9d5af7e25a2e66ddebc59b4f6dbdffe76ccb8b16919e91e8f2721215e6212220021114dca9e04c20c430b30f3cd5b83dc2e708b05a00bb51221001a26eb844828712609a9c8cd25ef369b6dd8b061c5c5c582799f366d9a2449d3a74f1f3d7ab4cbe51281ed67cf9e2d9cbd66ce9c3966cc1866ca8e3464c89053274e9c3a71223d3dfda1879672600012e869e208808594f766b4c68883db05be55058c33122c0d01aa2862bc0018886596bc8709488b8a8a0cd1434747c7eeddbb45728093274f0a0bf73367ce489274f8f061215ff8faebafb76fdf6e3445244431505959f9c92747c68e1bc785c42fa4fa42c3994807d2bf0f24e2064113b748b768242de399c1101bbe0c641c849aed2a8553672063abd04d81db604c8b382141b584050d10325099bebdb8915fa180d1a3478bbcbd4ea733363656975d697f9d4ea7d3a999ba8bdc71268f42d47544463f60d7ae5d4c3f266da78ac23d2d4470090980218aed5f881c8bfd88f08d44cdaf0699e97551339c15ad09ac230c35ad996aa3d6a099d083d103869c13631856e05bbb4a7dd30ba1f1958b2911234a44008c64469a6f731766336630026a996f8559b547960ffbe2755f080010ba2f0462400c892169e63bfac26818c3916e4e05efef7fff4f1b365cba741140f81869b29d53a74e5dbb5e4344fbdfdf4f009cb4a6852d0001e79a10426b568c2032e05cd8d36b17c5737534178650c029bc4097c7ff210574e2409d7ea8cf2e2220d32c3175abf79bb8d8333d6f582432859ddea01da339b1cc9040351d83402340061069d9eb40519477de79273ada3565f2c47dfbf6cd9b37d7e9747a3c1e22183a34f3d0a143bd7af59a3163bacd16c510ae969679bdded4d4be0e87e3e2c58b44949898e476bb3d9ebaf2f2f21e3de2d3d2d2040269125a0c7d840000484fad7eaab6b6169175ba7e1bba841041070040948878e9d592d401c3c06c9a6cb044069618b812d2cc74f69530d0ce2869c6b0cea8c60dc648ec520db2440002e1c37b4d04800d0d8d478e7cba79f31b4494953572e1c2452929296e774a6c6cdc81030725493a7ffe7cfffe691b37be161f9ff0d1471fc5c6c6ecdbf7dee4c993376efcf3ac5933ebebbdf3e6cddbbd7b777272d2800103d3d2d245afc44a173956a5a5e5f9f9ffcb6a1579c86f735add00e9ff61680a853a73edab6b4f7d794978b486142f00201611d01690505206137dd2161ac6c4baaa02081b48d5f86b9431fd746a07228a9ff143ec5a8865d05bed3d0c460b11962e5dba72e58acf3f3f4ec4172c58307dfa34225e5c7cb97fff7e2b56aca8aff7f87c6d13268c5bb16285cd66bd76ada6a2a29c73ee743a44533acb1ff1488d981a4fef1446d09c75d6b868f60e378ecd058c53a380f1b7cbebe6a6c2ca845dbcc115d155e356d869976f14f9d0c83e84fa86401a7ba10d979856413690182342baa1cd7b57079d089b2060000c51fb81196d42bf6ea1bb7ba2fdd8d8d83163c61c3870a0b4b474ddba75bffef5af01a0b2b2b2acac2c2e2e4e24c5a8abab0300a7d3e9f3f9cacbcbc5ee81f4b8d0d1d1d1cf3efb6c4a4aca8e1d3b0c16b03b30eefafd7e61e07f83c2e65acdcdcd656565a5a5a5adadad61b71051f4d078bacfe70b2b16080444758fc7632e69ee5597e4d39875f1089fcff7fbdfffde68c158581a1b1bcbcacacacaca2a2a2a8c8ae6d566dbb66d57ae5c11415f84ed9d2873f6ecd9bd7bf78ae39a9a9ad75e7bcde89b887a4ca61db4b81ef0fb8973b8811c0b4c4b1be9d40bb193bb8e69ebd71d3e75de78dd1aa01e2dc262b12c5fbe7cc78e1dc78e1d5bb060c1f0e1c3df7cf3cdddbb77bb5cae175f7c312121213f3fff8b2fbe58b264c9bdf7debb77efdead5bb73ef8e083292929f1f1f14424f2a06cdbb64d96e50d1b3698336252573205e3ad3d1ecfb66ddb0e1e3cf8c9279f60e7549ac680182db4b4b4ac5dbb560cc5a2458b323333c914ee9c880a0b0b1f78e001e329858585353535cb962d33aebcf9e69bd7af5f07801123467cfffbdf370f823810b3d8256e0983de471f7df42f7ff98ba228c2523cecfb59bf7e7d4d4d4d7272b2d56afde52f7f69bc82f12225252522cd16111517175bad56f1168d8d8d151515e24d3b3a3a44ba2163eac184f4a41ba3b7b4b4b4b55900f84d0cfd22af44ecf8b0cb2a9d81ba39eea6b4a9bb002002bc0000e73c333373f1e2c5090909e2cac30f3f6cbcd2fcf9f38df4606eb79b8884e2f2e9a79f16850d337c4378dbe57301c0ed763ff3cc3367ce9c0180e79f7ffeead5abd3a64d8b8e8e962469ce9c39ab57af7ee289270a0b0b3ffcf0c32143862c5ab4a8bdbd7dc68c1949494943870eddb66ddb279f7c3260c000ce794c4c8cdbed3e70e0404747c7debd7b7bf6ec999d9dddbb77efad5bb77a3c9e279f7c1200d6af5f3f7cf8f0471e79443c7dc58a151b366c906579d9b265fdfbf78f8f8f4f4949d9bd7bf75d77dd3575ead4a3478f7ef1c5172929298f3cf2c892254b060d1a141717f7e8a38fd6d7d7e7e6e62e5fbe1c11972f5fbe69d32644ccc9c9d9b2658b78afe1c387676464c8b25c5d5dfdfaebaf5755558d1b372e3333b3a0a020313111117ff7bbdff5ecd973e6cc998cb1989898e3c78f7ff6d967d5d5d5b366cdfaeb5fff5a5050d0dadaea76bb3ffbecb3fcfc7c227aecb1c7f2f3f31b1b1b25495ab264c9dd77df2d26a2de5b1fc03825a8dcd25268305bdd95819be35668fa6e05b7d024cf342e32c656ad5ad5b3674f30510eb34750181d32568ab06fb4cbae76b9f30804022258e6b3cf3e3b6ad4a8c3870f9f3871a2478f1e76bb3d180c22e2ce9d3bebeaea7273739b9b9b0f1e3c78ecd8b1bd7bf7e6e5e5ad5ebdbaa9a9c9e5722d5cb8b0bebebeadad6dd5aa557979791f7df491aaaa4b972e5dbd7ab5e8704b4b8bcbe53268527d7dbde8b6d7eb152dcc9f3fdfe3f1646767f7efdfffe5975f26a253a74e151616262424e4e5e53dfcf0c36fbdf5567c7cfc962d5b060f1e0c000f3ffcf02bafbcb269d3a6c58b171bafd3d2d2d2dcdcdcd4d474f0e0c13befbc332f2feff8f1e3f5f5f51e8f67c58a1500f09bdffce68d37ded8b16387b0412f2828d8bc79b3206ff9f9f95bb66c118bec73cf3d2706f0c5175f6c686858b76e5d5e5edec68d1bc58338e7aa1224ae12a97218fb8688aaaa023023d89a6a0245514414d0402020a2dceaee152a916a0499d179af4ef45c900a3182b708066e1984d7c01e23837c6461f3296adb401e56d28c88dddd0580575f7d75d6ac59e3c78f5fb060416a6aea8811230e1d3a3475ead473e7ce5555556dd9b2e585175e0080f4f4f48c8c8c77de79472c1c4653d9d9d991dc92992346c43163c69c387142242d3317161d98387122223a1c8e51a346b5b4b44c9830212f2fefead5abededed7bf6ec3173d6c607939d9dbd7ffffea6a6a6a54b9782cea4cf9a356be4c89188b875eb56f383468e1c69e48136862b72548d6e3b1c0e4105f7efdfffeebbef86f5161109486cf265225214c598789d0084124f04834149920281802ccb1d1db291250011459a42550d0682d640d06a58304b922e92d02c8c346e9a73ae07a3ba113e85112a339f073acf61701291236b1e2633fe61679636acbaf9298f3ffe787373f3934f3ed9bf7ffff5ebd76fdebcd9eff703c0d2a54b9f78e289bbeebacbe7f39d397366d9b265b5b5b553a64cc9c9c941c4214386e4e6e6daedf665cb960d1c38b04f9f3e369b0d11070e1c48446bd7aeddb163c7e2c58befbefbeebcbcbc975e7a49a4debce79e7bce9e3d2b58ae091326bcf4d24b2b57aee49c272626f6eddbd762b170ce33323288c8e974ce9933272727272d2d6de5ca951919190060b7dbdd6ef7fcf9f37373731f7df4d1b4b43422cac8c8484848b0dbeda033060e8743bcdddcb973376ddaf4fefbef7fef7bdf73bbdd1d1d1d00909292f2d24b2fd9edf6152b56040281e8e8e8871e7a282727a7adad6dfefcf98f3ffe786e6e6e3018cccacacacdcdcdcdcd0580356bd69c3c7952f8248bee69bc1732cdece1c081033ffbd9cff429214962b22c33a6852eb25aadc22ed9e572391c8e9818116d345a3f8db1dbed0e873dca1a658db24ab2f64f629ae84b93807234a48e1f7f5cf8e0830fde08ad742c89c4b0afbffe5a4c64e4adeeb03392b61984cd8c64e2fa0f7ff8c337df7c53e49e8c44f1307208a694a4e6a536f214005e7bed35a1a1efb293c681c12f9a49b5b9d9b0ac74d0f97b30ae2f5ab468cf9e3d069930f394660ad45d676ed049a3b5b06e8b115ebb76edffdeb1479113fef4f2d3b211149931266c23655996248bc562b15aad22cc9add6e77381c029f84ad9fcbe58a8e8e8e8d8d75381c22f09acd6613190e4596b9ce443544246459ee8ecb31c03cf744b468d1229bcdb67dfbf68a8a8ae2e2628158911c98310d0f3cf0c0ae5dbbc495bababa7efdfaeddbb76fd6ac594b972eddb46993f88e01a0b5b575fdfaf525252500f0f39fff7cd8b061e646ba1ce848c62eaccf605aefcc2d2c5fbe3cac4a1842845156f3e899572233d1555555f84189f2e6aeeedcb9d33cc89103158634dd610ce8d86c7e44e407663e365e53362a43673c30b3026123686a57e8909888e409a0fd153f6380ba9c9e1b83c1f77cf0c107b367cf0e068385858588b87dfbf653a74e4d9b366de1c285efbdf7dea14387eebcf3ce1ffff8c7ebd6ad7be699674e9c38515d5d7df9f2e59c9c9ce79e7b2e2929898866ce9c595050306bd62c45513a3a3af2f3f34f9d3a357dfaf43163c6b4b5b5ad59b3c6e572c5c7c7efdfbfbfb4b474d5aa555eafd7eff7272626d6d6d61a71e75a5b5b0525131fe14de96518449234f32475771a5638b21d7381ee1e018000061fd249e6645c345717b81c2aa6cb8bccb366467173ddd2d252b4448be05932088b70ad84a0346128c9056f0e2064b5c0398858a0ba5037d4d7ee68a971702b58651e9a9a9a1ab7dbedf3f9ae5dbb969898f8a31ffd68c58a156bd6ac3970e0405151515e5edee6cd9b0b0b0bcf9f3f0f005eaf5784da160ca680949494499326eddab58b888e1c3982885bb66c79eaa9a7468f1e3d67ce9cb7df7e5b55d5f9f3e76fdfbefde8d1a300b072e5cacccccc1ffce007f7df7fbfdbed4e4f4f4f4f4fdfb06183f0971c376e5cd80af52d03b13732cb11d174fde6a0055104d4229d2021101247ed66b7d34744252525e72e5c2df31031490edbff7749a2ccc7669ceb92a4fde360105eafd7bb6eddbaacac2c222a2a2a7afef9e76fb08c0ad7d9c8ce23e27df7ddf78b5ffca2a6a6266c95c9cecececece7efdf5d7c5826854b9fffefb4502ec3e7dfa6465658d1831e29d77de193c7830636ce2c489fff4f7fd57823120b73e4dc27e0449e8fb88cc32eeee5c1bc57c454747d735051a822d9224756bdd60a240da1ac73988dd2211e75cd123a5706e265cdd10adbf170c323b63c60c6138bf7cf9728bc5f2eebbef9e3e7d7ad0a04163c78ebd7cf9f2b265cb525353efbdf7de8a8a8ae5cb97d7d6d6ce9f3fffbefbee134b617272b22449369b4d96e5a953a76eddba352b2baba8a828272767f0e0c19224e5e4e410516a6aeadcb9732b2b2b737373870f1fee7038186356ab55688df2f3f3131212eebffffe9933676edebcb9a0a0e0b1c71efbbb48ef770d349a2748166a740b40c728ec1e47af5fbf1e171787e56d0018725845dd5a4144c0926559d8ee399d4eb12b14dc7a4c8ccbe58a8e11d16d5d2e87c3e174ba6c369b286c481c5087b067efdcb9d310dc75075d720cd059914226e19651318c238ee437bbdc43dd8061fac31ffe306ddab4f1e3c78775a94bc1fdbf07700825010881d8dd035084059f79e88e1f3f5ef0e1279f9dad7ce1e91b06b715d50c7523e9292a48c250ca8f000008be494441545743eab7341be3aea6873a53e35bfaca0db44093f4b24b8631b2b7dde156770f8208d434364744b46cd932210132b389b7f20adf1ab8d531374a0368c948c9545fa05a97af1e39202a11279055550d0402c69430c6844454446a10023a4551144511c9bd3a3ada7dbeb6b6b636e1566f881bac56ab39eb8999950113b10906835d4e7f77dd356b6c8c5373f91bd48ddcb4475e8f6cc1780422f6ead5ab8bb1fc8e009120319c08c3446ee6329dbf406421ba242a000724242462da72d829e1adc13285c60d1800ca8c016320f68388da12662401b0e820a45942a025a2ba0bb196c02dabd56ab7db2c51b22c5b645912d99fc38ce9c4bbf9fdbe73e78a0c42720366fc36fcb7802102e791fb18d4250944d449eed069874b88c480110795a130d766044c84eb24ae6aa1f3cced221a12b5eaea4a00ce810048067dca89884815316ac9945a5c80205a611a430d143f93400a32d29647993126b43ac67700a009c1274c18af280a11288ae26df05ebd5adae06de45cf9970ff87f061031c6508f5f6a88a698111a1451e5c4413f2122a6fb1000a0b659232e33225209197186202348042a31508187716044c424465c3311b6d99d92247340b97321ae13c14e60ce626fb059c681518a74e34ce36bd1c9928aa849cb12937aeb2c1a45bba22d164b6b4b1bef1416f136fc03a0e792100c8cdd6e5755113347d2c493a86a01304c127c2350231059488d0e2ace802a01b55898cf6209a00c2421439fe28fb25b41e914ff238c8bbdde10888eaed7c40d06031429c90c235d82629911ce8c5ea0c9e23991c602eb8c1172ae619ba11f4004972bda6e4f53d5ef5268cd6f37106941a611885a5b9a7b2526b6b707546e292dad68686eb6da6d8949f13d62ec320a0e0a1131100830c66c361b0582f6805f2eb95a76e94a7d756330a040ac2335a36fd2a09460efde41496a686f89eb151fec08188f03b1188504ece8aa69721e2f0f976319a867265410815e5de153e8962431339aeab44a7b84896d078bc5722baac3db70cbc009552019491281c99d0e3ba0c5afd89ada7170567647c05f57578592ea4ee8213164c0112910253394ec366b94d21238f795e7bdf75b59fca7352d4194fd4d8d291f7f3e6a4446d69279b103d315e688714477487eed697aa62330512cbb3d48921559f7025201664c12e4ca38361f18881556b7cbddbe81490613761bb1fe49c0806440a6c56d6212932c2a041b9a1a9151479bafe44a795b4039ff655952425c8c8d8d1b31c0e6107ee872545055be38d5b27b5ff09af78bebd5be3bc68e9c371d255672eee2d9f28bf1ffa760f08f7ec86263190263cce45c0c00c0759b28c6989e0434c2e6ddc024d4edf222f92db533446058a8a92e31c6bc25011399bc0dff2020218a58a62286bc08d6a6404363abaaa0c32a8f199579adaef1444bdb679f9fb3045bedb2326a4c2690c4408d6a6b2fbef0a5fb9e7bea8aaf59f77d30b4b97268bcdd75c7c029f764dbebaa6b776cae3e5de49a3819486c218d29e3a4ed2b795353a3cfe7e3142d6e7461fe11761a6647ca3b835100420b62275cbcf970dc2657ff34200684c839ea11140855159b5b54901ce5959588c192fffb755abf64004e14ec999c00280127e25cf175343434cbc387c5ce99ddd6d7dd5251f1c1136b5e5ef5fcf3bfcf2f6d064bbfcc6b25c5b212943af9ce694a0822f27aebcbcbcb62636200b40034370f1519c65a855129f3a9991513756f23cd370c048af02217d2050624a1446069f7073d0db51919493f587ccfc90b5513278e9395a6d89ed12a06992ca1a230408b6ce52a4b1d3dea7fee7afbcadefd35fbf73baed67c5edd987fe9d263e3fb5a2c519ca11ee10542b60b4435d5d55eaf774046060018c2cb2e623798f9711e01918ba019441be64dc037309ab741002170469c8918168c1100a95116723aa5f6405b47000bff56d4d4ee2f29bd3865ca6849a696462f0057b90a68c168bb332eda77faf47fbdf7717ec1c7f6a91307fdece769bd5d77fa6b333de55459d627f30e5592817131bf2852f412555454343535a5a7a75757573735351933de058f8518c22ac1947547abc288964eb13811a31b2af56ec3bf08081850287712223039909a1a535153e9f7fb3b7cb8b7e070f65dc313a2a35c4e5bfd754fbfe424e48810e5b75b078c1d7be1ddbd2df12def9faec8dbf65f292ea997d737d1ce47589a2db18eb83b86d65a983594768510b1a4a424180ca6a5a5151717c7c5c5a5a4a49454b7889e749b6c3cf222e972ac3008e3ee5535a4c4657a96b97fe560de8610102282d8b59108cd03a4c6465bc68f1a70fa54f195cbd74b3dc1da8a9aa183fb5dbc7876c6cc6cd282f70415d916356c6806e37cef81df0e8e76f4744b00962136b5b6cc969a92b470617b8f9e14f023000222c340c07fe54ab1c3e1e8d5bbf7e5e2e2a4c44444acacac04162b7a1249b1c0a0585dae86aaaa98bdc122574633b5333698dff808ff87821e4301008890382082cc54b557ac6de2b8c1fd53e2af9696363735b6fbea264d1a9b9a9a42120b2a8acc3881d2618d8a1a3634ab478fbaafbeaebd7435d0d21e9b1ce79eb4c03164882fd61e90500d10a14ce01792d1a4a4949898e88e8e8e7ea9a9ae989896e666bbdd7ebd495f0a894815bc11111143e4c40911b9b1ad4402246400484c4249462649b24546262193001191ab8ac255550906ad369bd56a9524495839a088ef701bb1be4910fc35923f186c6a6c0a04fd0848a032647ddcce3eee4cd44358b5fb7c24d4831cacb2c4890801137ad8268e4f1f371638912cf9644b0393a1bd5d250a06785363a3a2061081736e91e5765f3b003026b5b6b44a4c220ea404190480b84c84c1a08a281111810ac2e1109121aa2a30462ae79c90137262807ece99c2254595dafda8a892df4ffe0059dbb8d3495156458e0a44455985e3a12c4b88c01803c4904debb72a39fbbf7b014f63fd7fa3050c9989aa0401320a23d4357600088575580b2064006d41944446d9b2f28a23478e00000072ad1280b65d4414e9709924fc349890adca127040c6648b0591812c11a22c5b880851222049621c50d6769e6816a8dd86ef3adcc0741011546480512306f5fd7fb0ce129839c4a7d20000000049454e44ae426082, 'image/png', 126, 0, '2006-09-28 09:00:34', '2006-09-28 09:00:34'),
+(5, 7, 0x89504e470d0a1a0a0000000d49484452000001900000012c080200000062d57295000000097048597300000b1300000b1301009a9c180000200049444154789cecbd69931c39722dea0e44e4bed55ec52aaebdceeda791ec8d4c92e9fe7ce9834ccfaecd1d6966bad5cd6e76732992c5da322bf78c80bf0f27e1895832595c469a996eb02c1889402022b01c1c77381c7c7a7a7a7676f6e4c993e9745aabd58888889c73cc2c22c61811c179f9d18961162236ec4488884498d949222c2464392247cc2ce2d8108930192744c8c110c9f25944063142ce182621663cdd8890315684b24f2711318645c8184394b95a7cf35c0c11adfbbaf7c8edad796e2ecf30feed65ee9ff54ef16f3d12512e070a4298860a61f3550db81a661ea62fbd1abe9ea629c6ebcbe35298b2f498cb2acc21f739ef57983fe3a3635e01c8071ed998d4c96038b2363e393efee49387d1d9d9d937df7cf32ffff22f83c1a0dbed32b3732ed710d736712672c4448e859984880940c34e52c78e882c1912666121472c44cc64445b0c004b7c2b21624344ceb71beb3b30b1b124cccc446c9888844884c418c3c4cc198841d056a800b4ee28014ce8b787319c05a3dcbdb9bb4ae3734fc9f50ddca56f9bbb9acb2df70eb99a7a6badadcb3300960c6aac4b531a594c2365402605c0ca01440e4d240b61c5044484769bbb84735c0a131443f8945c51977ef89f0134fc791e1d918838112d3d32e63d73b3919d2fd2d76f2ee2b8f69bfff7378d7a3dbabcbcfce1871ffef55ffff5fcfc7c7777d75a9ba669b17ad606902a166221222666622276e41c3b223162d8039678c0c27d42424c24c2424ccc86713f91301331335bdf7a0049c6b0615e0116b10296a6a41c60510022b7b9ba217e33f06dce6d734c0858eb727e2b60959e6f0e9bc1e8366942c808237309a400585280aaf0588a3b8a3ea570837845a530a55e0a7f16e33714c22f615dc8017a0eb034cdbb668b461e57e2e96cf1d3d3d34ab5114795fff5ab2fa2f97c3e994c0683c1f5f5751cc7511485155ffa242616023c11a1ef302d5148909e85448c13117686890d1961874f006011b3b0c812eb1487845888093f0143444bc062b6860d33313922324c64848d6121e28803b0c84152ee3c77d5da0cd869fc070216c25b0128775c973e7c67e75cf826b406c28adf5e5295b700accd419b4a98610e8f4a116d1d601591a8084cfadc2290a569aa5dc8391742d2e6a34258b1347265f80bae6d081eb03275fa818035beb91e8fe7a3d168be9847711cd7ebf56eb73b9fcf3b9d4e1cc7ce070a46feb22c6949748888890d09fe0911b1b090111122678047c4222ce2006accc60316b121c3a4f827c4648cf15d1458c8860db331864984c83193354c2cb4e45f11111bb356e8d3e3ed61e836f094e347c5bbb4b6c234efcabf72578bf0749b98d2f0d696f4d6ceb98e988470b3f9aeb70256313e8ca12c608588839f0a5b0a49a527bfb0adf708594862e672c07abf9c015895d9e2aa35aa561bad56b35aad4404f6628cb5d65aabfd0a27395165792481ae6ad92252e79c132790f7c82bd449083448449c88902323e208c84429118b9018b6c28c044c640c118b73b2a455860d5bc898442c20612c6c889d7f2d638d354294a60281593f5bbf42bf2ed4106d86a4b76abe7229c32722bc2b60ad130cd70d1b9bf9d486abda864ad3bc530b2beddbcc9ca33fcabc8a7785004405a42b05b2d2bb72a2621899a2651492dd8673698194161aafd1bf6cbefa5773d4e121002cfe888065adb5d6d928b2d6424f1d1191732e4992344d9d73699a2649526c6199bc48989899c5b9f96c369b4d13979221d56011b31074f2c69021200b3968db916499131191811a9e590c9331abc732b321366c201291e021640c3320534488c558b2b110877d833c1063c2a256ab359bcd4aa512ca2f61811641e1f6051da62cdeb5a1df521964accb3f97b2d87f4a7b14dd8e9317d3dce6aee2b336c773a050cf456eb8b1f8f9b9772be619de48eb8bfdade8acb896cbed3625f37308dab60b0c2ba3c37abf9c0188ceb9344d923475ce915054ac6c6d0deb9eb7e44e969dc8643e1d0cfb29a57135624b4e96cc4898444852a29418a0631c1947224b0d15d451448bb97389186b6b354b86d2c48938c8774c345fb83411268e2363d8182203da46c424cce484a7292d52c3368e2bb131ec84209782524da7d3344d5bad561cc7711caf538a87e136acaa98be34072dcc75acaa344fed12b9e13a5741b7cff3ad6fbee16473e0ecb472ee0d6f990379814e6f270f1621c64910342500252cae6202c4ab5ab6a8a82a650d616f5cdb177e911cff7b02138027e26ca0c25046c5b62b20534c4cd3c5ec663294d835ea35b694a42961ca8f5988d2344d67ceb0892b9161224e891c131b63e22832d69093c564319ba6b55a6ca36a1451922cc83963d85ac3428b59329d2686d856a328b6968969a9be374cc63009cf27e9cd84a26aa36d3bc658e79c38073e2922b3d96c32993073afd7238f059bc12814873703d65ba14dbbee6d660f4be37339d07ac0ba4d7c7648bc2d2a6d0e456ab68172864050fcd2304d0e77c2788d51980b3f2d7755e53bd50628446a63d0f4614c885f3950fe05a7c2f0515ad1a6fc6939efc686a35c2bb9550642040245e2c8394ec53aa9388a49d254dc521623224953b770c48e22e62ab375248e49acb151ccb1154ac54c539aa536b2d55a1ac7b45824e29c356c2d93a3649ece4d6a892b11d7628aac6312728e9c18e6c872e2ec905371cc6c2a954aa512d9740958954a8588e2389e4ea7393e7f7bc8c814dc3ba6b97dcec5f87705cae2c9baf4a5311b48c4bb861c76ac83b322c1c9e5f056c0520c0ad3e4d853eec652740be12944790a5a0b67b572e1cb176b3387c53f9b205e0c7c072cb95dc69abf44988f0baf163b403e04d1c6b08dad54996bcc319994c509331bc32c24a991940cb3ad5054251333111b22cb5489a41a892432ab7232b7952a576b52a9b828724bc0322c2925734ae7261253afda7a95622b4c8e9c9013c3125b93381a4e6ca51255aab57abd5eadc669ea30f11fc73118d662b1a8542a9010d1f86eaf7af79ff96e0af80dfca834ff0d6936e4509a5b913ddd2646e34b1fb12eac6b9545480a2fe5a06a1d84dd06b014b62800ac1c30418fa95751f52a45e6e60a73d8e40a4153debe947e091f2178ed77890eeb1d03b36132380a09118c4859c8c1c28a0c13c378941d193104e3776799c89235c44ccc8e3935263536151668b844c8b01826cb1459b6c619762c29339111c3640d1189356c8c316c311bb8248f7e421091455ca6db31a0d28e5d7a6f69cacd6c4e0a425c31e63dde7033f32a3d5907619b439838e8c304f9095737b72ef6daa51cc5db0c5812e8b67210864acf9d53010d73af11a6419585a8a7a1341f791785dd2fe1bd036a24caf5a8f7ca88965450c4911312434e44c4f9da1512272e756461456ac889a42919316498d06291492a940a898811583d888890b01171224e5c4ae218ac934998441ce6078b6d37a73d5514d3f69733dda0352ce996693633a9d2630813da4f3e1660e5ce3743d2fb01562e87e0a16fd761853121450a936d00ac5cb2cd412547e5531c28a7344602b306255ce26997922ff60cbd54bdf52165f84bd81050fe1fceb0888276e364394527446a444ac222ec20c75936c610acb72c196308b52bcbb9502722422c8e9969b9c69084247569eac45a212227021307e770cec8c0f9919d02056a0858a57c275728a5f19baf6ecee796477db77702ac2c4c94c8f2a5d02665a4201793fb55561eb9a06f922123e1e34adf361c66c2349c55c3d307001605b0a2f0a42fa6d8843613a6d49f9c0d120c87b936768b82fa25bc4f40217f38c312126134565e366c66e6e5fa1a60966166369619d60a860c31096445225a8a94ab65374bac21c430f9e58644d62cf1d00931131bd86621190814099131925d734301c3a2f570f07e56ef1b2cdd371fe58319562e87dcd5dbdc95a94b3fd66cc8a4905ecf4d903c034f216015fb76296015a18a3602166d042ff24c2a0497507b15b2ad9c71bcfe842e2cd46421b037172a2da25fc2c70a68e11fccb08448d8928d4d2446489c88b3640d1b2c6616724cc6181b4591895358be5b63e3c84696c93139c7642cc7918d229b922347125963992525364e58982313556c24c62e5884194a7736c6b058b6c2c64491ad542a711ca7a9831d179619c5711ceab04a3beaba02bae5b198fe5d7350c07aa76785e739c3d75b8257984c44fc0023b912f23f36a96c34271db814a472cfcdb5378d098faee09f843e00b024900a8bb787a521810088ab21b0869815569926d03c6fd3c07e09ef1644e4431816c3b78230a5c48931a9a554d2d43887fe67580c258e1222264a0d8b61312e49172e656b38b694523277c99c2461971a97462ee134494524254b865d2a499a2c1217b1755449c5512a2c8e8559e06ecb2cc4242ed59514699a2649ea9cb3c1148f364a6558089bd715ae3bdf7c7c27b6a52dfb9de61625e04761ca100872f017e6409b3456e2ff58642515868c697d6fc4d35780a5cf7aeb39157856a8d52ac2d37b0056085b12302c9d37543cd25945f1348a37ce1b2ac30aef2a2b9f5fc287850f66584cc2e2c82d9c73328b171ccbc2a54ec490a42424269dba74e65276924ab230261611c7220b230b2396294d64324ce75319335f5e888d5c922444628d18c32e91e9249d4e9ce5459a9a51e42c272c02499285ac7189f0609c4ea789e3e1f9b989639ba64efce4a0880c0683e9740a1307edc6b9be4d593858575c38c98dc9a5c7d29cc3db89289cb8cc3d7703dcdce6b99b73c8e506600a60880158442160ad8e22e125a695918cc6986221df3e84f7e6660fdf09b0688d239adcedc56cf56a883b1cc89261a4162382429826fe856a7dac8022fd001d96101347268a4d9cb84426240b66b28cb586c224cca9b1629898524ea7247362b6c49c8a4c85fc8a406bada4298f47c4864562f26b1549284d2d1339e1f99cd2c4588e99709d8c101b12474e6c1c33899b4cc6b3599e92cce773668ea208eb9f8b6ce8364c6a3303ba3dc30a5f6c5d9eeb72dbccb03073e553524e2e0b7340e5293c15004b81290f586f690eabce9c01acb0938748514c93830329cc1ede0671c2ac3603566e421081bde916ce550694601db5c29304765b087af517add6c70fccf4210c0bf557afd5b7b776d234319121839584e43d5661b9b231d6180bd6ede03a46b5e8c618598a0f620cdc2e18274ed2e5021fc0a2085bc3d69ac81812af262022162676c28e8dea1ec2566e8c49d3d418d36ab5eaf57ac868680d9fb2d6c229183e30071940bd501c5853b699781d6cd5284c024b45bd6503530bdf734dca250214eecdbc48983807493e868b38b5ee3325231ee6670937144b0eb05cc10e8b0218caf1350e745e7a291742dc29052f7d44ee5994559f95824ef815b9f8e22768e6bf50ad0f0c28c6f76158488fbaac37eab57a4d30bbc498f803c42c57145a637939fa2b172066b24ba7c68660f5b9ec1ea2d69e41b734e47d5d596662b65641449676abc68aefc939c0428ce696635592e54a783a7cae96b22d6d7cc6875cb1e46cbb74100e73509fae1b720863d6f1af1cc3625e6aa0e08823cc21fc59440de4e4d9d6929ae5c03497610e320a19521849eb8356533165115c8a58933b4a6086ae8943c052d80a4b2fb4355566a4471dbab4cc43ad564e9f4505259766bba1108a2187d1bf04f24df7fd19967645a88a489694092dd689183236b2c698f96c3e994de2386e349ad6c2df0bd9a506878996c48a88c6a3d16836a9562aed4e278a22d87519b8c812379d4ea74952a954aab55a14c7e29c9018364cc6580bbd4b0e9e142ce03ca77424d7104511330f0683e17058a954b6b7b7a3285a2c164414c73132994c26f3f9bc52a9b4db6de8c524eb333e57c4216e8a489224c3e1703c1e57abd5adadad5aad26c13211ca020a15e069f3511916ada4425c5deaa43499e756ab5b71d147e571aaf84a6b7e7e7c1a11c2eb06c092c0a74211b064fd2ca10e429a0917f82c65b123875c61a0a0c9218410f90b007d5010910f9b25642282ff2ce7dd9346518496315f2cc4b96ab51a45d1743a1d8d46b55aad5aa91a8e5dea88480c69e330ce701c3be7aefb83cbcbcb4ea753ab37ac8d160b301d21a2c562717979351a8ddaed7614c575b6f0ca668c303b138c60caaa72af1a9ab9e7f45668a9511411d17c3ebfbebe6eb55a3b3b3b699a0e06036b6db7db8591c4743a1d0e87f57abdd56aa9e4b881b529a6a3edce66b3cbcbcb376fde74bbdd6eb75bad56178b450879a56fbee198655e0026e59ae5ec8c0aec49effd4086551ac2be5a4c5c244ae1a5d298f0d121d65056ed551acc9a853b211592826516ea0e39e7660629a0545060b9b2805772d985d9bf84770bccfc7e0c2b6ca6699a2e168b344dadb5715c31c6c4719ca6e962349a4c264992743a9d6ab52a22206279bd0f243a63a0dd5c2c16d3e9b45eafe3f596bd878d884bd3743e9fcf66b35ab5b67a6121cfabcac7e11038f002ec15499a00f17a57bd5edfd9d981ffac8b8b8b972f5f361a8d4ea753a95444a4d168586b61db45010892b753a5accf130a481f5e0f4ef4c1ad149bb24c87280b49d92a5babcf0a745219c0ca1d69a950673df1f19acf32a214b036c4bf35bcdfd0f821b971b056d105f377e179d89ed5b2416f0f65cc5cce5cc6d6b92c50d02a6ed3dd6e3f1efc7c026aea831816b2489264b158786e554195cfe7f3d168c4ccdd6eb75eaf83bc2897d1d1062dc35a823705cce51111f24c93c45a6b0c13595c8de3388aa3288ac46b8222b3749a4a44203239f6c45e49016025a2288af0b6f89070188ca2a8e683885c5d5dbd7af5aad56aedefef379b4d634ca3d168341ae092a078aa90823e1e72253e01dc939961d18a34711ce3a7bead31c6189ba33ca5fc483b4929188988d6e4ba1cfcd50d0c8bc26e52c4d077ed45b28661157bafac675892e553c5188d0c4f24a05da5f48a0a16f07aae4ccdadb7c392820e8bd7302c66463bd12fdaacd57a570ef1730868a81f612d21b0603e9f0311e6f3799aa6e3f1783e9fe331b3d96c3c1ec3e12733cfe7f3e9749a24099a0566f1b6b7b7ebf53a7e0e87c38b8b0b309a5aadda6cb670231e8693e9743a180ca228ea743a90d444a4ea43d8b1f17ae3f178381c2e160b660660552a15a8a8e6f3f97c3e37c6349bcd56ab9524c96432a956ab711c0f87c3c160301e8f9f3d7be69cabd56a488c6d3bd234edf7fbc3e110c0144551b3d9ec743acd6693992793c97038840958b3d96c341ab55a8d03b615628a3f09ab878a31ece7f2d6d7685848ec496a9e6105e7acda2e9f3ebc5acead02807b3753a30d29252b814ad9245d9840a97a3159980905d090833ccda114e3288b989a5bc89b24bb2e3a37aee4e2117252e12f1ceaf6e143191682d61cd04a44e6f339181633572a1563cc6030383f3fef76bb0097d16834994c9c57588e4623e75ca552a9d7ebd815314dd3d168349bcd902d11b75a2d2476be89cc66b37ebf5fabd5aad5ea6c36bbbebe36c66c6d6d01ad4ce092015cafdfefdfdcdc40744500602990d5eb7568a92e2f2f9f3f7fde6c368f8e8ec8032eb45a40a8abab2bc88c8bc5e2ecececeaea0a42a5b576b158c4715cad5689e8e6e6e6f5ebd783c1a05aad76bbddadadadadad2ddde64302e154448cb144a26011b6fe22c3527ec4ac5a2745ab108656b59303ac620c85b7ad392ff6ae10b0d6b5a25b322c1d5d421029dabb6b7a9dc7903285bae29d48dec94c0e954213130497358008f914bd8d619960ed8ecef36853d7abcab68a50fb0b7ead0b28c38fe3adc1f86d69405e9c73305642ab52da4544800fe75cabd5aad56a49924ca7d3d96c063a06512b8e63ccc1cd66338097b5b656ab4186d2ceecfc9619c3e1f0eaeaaad56a55ab55b018bc00a44b70b1e9740ad284fcf5adc0b99acd66afd7dbd9d9a956abce39cce2351a8d2449c0fb767777bbddae31062f0c4d397276ceedeeee4284acd7eb483f9fcf87c3e1f9f9f9e5e565a552994c26699a562a9556ab65b29eb9f4835403956352ca7a7c7a0af068c5b68264acaa777d843e287c6eee24fca938988bf4f9e75e894be38b61736f34c1eaa2104db2ef500e7f1ca893f4dcf82d4836005678e20a26112e50b916bbc95b3b4ed85c8b3f956de9e3f4cd735ffd4ba08fc5b050b2200ed56ab55eaf57abd5244966b319843e6656f513d8ca643269341a3b3b3bdd6e773a9dcee7f32449547b1dc771a7d3393c3cac542ad8de75369bcd66330096eaa4aad52a242f20489aa6d56ab5dd6e371a0d64c8cc50752d168be170a8a0837d28168bc5cdcd0de84fabd5eaf57a7b7b7bdbdbdb49924081d5ed76f7f7f799b956abb5dbed4f3ef9646767a7dfef5f5e5e56abd54aa502eeb6582c5aadd6279f7cb2b5b535994cc0b3269349bfdf8730d86834600c311c0e279349b3d90caded4d108a0ccbd38d4c8bcfcd21866c0b89712a59098bb28095bbba2e3e7c1011c1cb55c8a7de43a2c971a8b0a36a7c480043c644d9ee4d01b2acbbb46ed230f7689d0194acad960b66096fc3b0d6851cbd429987448c6e017f3ff3f0711896de0e48aa542ad56a1544890afe6a89080aac46a3d16c36dbedb63106ea76cdcd79efc610d944045b906953439e00acc964321e8f9d73ed761be425376c8ac87c3e1f8fc7101e615a351a8daeafaf2121429955afd76bb51ab466e13be0858d31bd5eafd7eb8d46234de09c83fe2b8aa25eafd7ed76019d4992bc7cf9f2c58b17954ae5d1a34751145d5f5f5f5d5d4135860fc11771469f8512127f2e4aaf94280527995af4c996e9c3cad4ab011163649e63670a08b4042670340a4e42b55a29ac697a1259dd554cc759295582359ea5e94b73a0408a5c3e3e8b47a5c4aa0858b46ac342b4c9a3034ec2316373c7e120843f73094264cce5f90bbd0a03caff43edb0707bc8148032618c56952211e8c96432512216a6141168b2c4d337dd03556700ebf53a00623c1e5b6bc1d78848b955f84468c7903e8a221025d816404894a59b8724c4561181aa0b4262a3d100902d67f5ac053a33f3783c1691cbcb4be8c886c361bfdfdfdfdf3f3939e9f57aaf5fbf8ea208f65c5110b2df653d5e0873cedf7c48854ab45aa84dad8ad028a1d83dfc798e61adf4f4e4014b44b492c31cb260416580c512eca6c9598493405725657aab304d6ef829bdba0eb0f45211adc21b5da0b182c55fc8b3747a31a45412b0b0db33acf01c417fa2b587e01b76b1cdb0f8f30928b40fb27427222002ba22580cb815f453501b61135340c3f6f6363441575757c3e110e21233630eb1d168b4dbed7abd8e897fd0a84aa5d26c3681508bc502d36ded761be465b158b4dbedfdfdfd6eb7ebbc71033e0f27fbfbfbf57a7d3c1e4fa7d3e7cf9f23b2d56a359b4dbc2aa4423cd45adbe974b6b7b7a1113b3838f8e28b2f86c3e1e9e929b460bd5ecf39d7ed76dbed76a55201613c3d3d45b3031163668032661887c36114453b3b3bbbbbbb9d4e4744767777f1b8b026684585708e619c73221d3363df467f2b922dc18559d3af6e03ac04e3b9a6d4a7eb43894817f4e60732ff02a87df2e9734480fddf5a657c18af6a26ce4ef6e9dbe6869010e66e035822848f0e2e865c86d7dd484bbfdbba33856176222ef7027cbba05f146290fed450940d737db314d17e260105fe116609a194c151442093475154ad5631eb67ad859ce89c8311d3d5d595f291e9744a5e836ead6d341a303445e5619e112803d5bbda97a3892f160be755ec18a9546500b6d56834eaf5fac5c5c5e9e9e9e5e5a531666f6feff0f0104afd2449a0d5d2ace238ee76bb954a05faa9fbf7ef3f79f2e4f9f3e7d7d7d7f7efdf570c25a246a3b1b7b7f7fcf9f367cf9e254902c1b05aad9e9c9cb45aad67cf9e7df7dd77373737511475bbddbdbdbd46a34144c6184c38b0b79f56a3300ee8c672c11311151cd1309b5c1f9012ce55cec54432dc8a280432821e0d69cdd261ec4aec0a81a6549fe5cf4d56907c0bb7d2af2b15b572e7616eeb008bb2dc2a773597c63993bbe4ca660ce96dfe48370734306d9c1c10ae501651c1a2885cbf0494dbfb332c34384876500641cc419382225c44000a38a6695aabd5d234bdb9b9198d4640282cd6bbbcbc24225dac074bd4c56281bb6097008605ab887abd9ea6e9c5c5c5703824a2e7cf9f5f5e5ec2a222142dd99b56dcdcdc5c5e5e5e5f5f6bef8ae31873976acc09d970341a8dc76388abcd66d3397779797971717173730338c3da9d7ebf1fc7f16432b9b8b800f862eab0dfefd7ebf5f97c7e7676f6ead52b2c4b04144e261368d0e6f379afd783f5bc4e7dfadeb83ccf0de0c59ac3291179c593928e0c870a74554b051973c88f988359c8707230942bb585e45e2604ac200669f2565aa54099bb54dac6f4a764955685c424a2c467991c6973daba10ce8cc90196a3e5ee274bb6eb4f96e70185842dd8d28bb72af882bf55c8951533876e6ac2a290603588f6cd75e5f3f30a22f2210c4b070d689ad5c25b336766689a11033302ed57c0114d06dd398c2160685a24057a1c0e872020d3e914537ed013c17222ec06613b20224864b09fcae59feb452232180cd84fee801c5d5d5d6986979797fa2d584b4444002fcd01e40ed9c2108c9967b31911596b61b48172535d0905bd943dfb30819d51591f208539e544ba68d27ffb32256e5dfae6097a0aa04acaf857780ccb27773588316f4da30fcae1919e97a61129110683bb805090f89c5e09d1085f1a021620ded32511c1fe4ccaadc2dd71b04283f1578c314b57a54bea94a679bfef26f0686a028b2d55e01a6f0654e459bf6016dadffb30acb0c340c1049e124a2e4a71c53bffa460f4d0e578124c02eaba167d25ad481d0c75dd1f15802987bc1a831b311b084004b16266585a04ad5354a12e817bdc4a25ae54aa22b25824222b8fbaface984f14bf4c07f126580aaeb22a1101973b9d4ea3d128b642cd165396b82bece7feeb94252d1def0071a2c87a0e25ce85fd7f055be4314e9f18260bca2f47b8f2b4a8d82af07f2e263ce6e2b33afbccf5ecc7ae4448ffd329832b0096c6a09d942edfc165a551219f42d0c2810e0b791aff02e40b877285cccb9598ec5f3278b39291265305b9cf09a5d1f0eacf17b944e4bdfd61691bc2da3aad0c93f53aa0f564cad6f7858fe660d3407d90f18b96c398d263f844a4d4c5c9e113f5c3c398628f2a3e17ea790a5a8ce62c4bb182001c61fc3a180d674e7549367b3687f42a3284f3a72658d6533c42f1a4788e9bf4b91210d5b006834ec8949d100c8b2577924310f26027a222a1f6eab50c2b77cc3d3a1c997269727ddb7f9aa872dd33ac758055fe13c139832b54e6955439149e152aaa88284d570c2b5c5668bc3d3dced5af43eea8cd1269f0ed2ef0cff5b30eccfce17658e01160466a19a05880c9beb089e7a04a3b6dae2b8660a45a1ef26d5775a07afc900000200049444154f05406584809ee638c81a92a8456b0215833cc6633b538c58c247b2a87cf296897f02c81dac218cc451ae75266b6d6186321cc420107335a68f443184573843e0ec515764b9035986ec5717c7070006d1d789909cc2015d7dcd26aac92a6c9703882985cab551b8d26161ba9d103910a83a47d92bdd6890347c901ceb2d7ce94231765018b281c031407691df332869d5b1e013a39dc1411635881d15b782187bca888832fed156051007f01ee8852517f5542640c6ec72be955cc188a046312337b8ea63f5797c2f65f5a0e1a9f4b1642db87f4d3bf8680be992bc4b706ce06f15eae4504d0a032390ca02898f0d26e9f03acb09272cc85fcd812ea7730f8e43854ee5e75d4058bf6f97c0ecd3ad62dd76ab5f1783c180c602701e3753c0b699819b301d65a955ce0183564522abfcce7b2582430cd9f4c26711cb75aad6eb7ab1382e44545fd8ab01895fd01e066b3d9cb972febf5faeeee2e164b623100123bbfb52711c186be56ab6d6f6f13d1783c1a0c06d64644dd66b3e5fd70a541e9710822a804634ca8050bb555fedbf35d4b4a18d65ad18f9640b932e5f728503e6f587a24bfde28e8b77aba8c570b06654e21fadc12b0f0333c0f0816f44aaa4370ce65e60dc38944635697c27585d039a071e6b45aaac3d25601aaa539fcac318b993fdce3288a188b01a11bd2ae88e5d06a8d157a74d1341a135262c00d6a8b0a6418f1bee994074064bfdf0754211ff8de832105d621c3b5031c78212533b75a2d104309b49ebef540b705b37b8b0e13c711115d5f5fbf79733e9d4e014940c3f3f3f3ededed83830358e1e7be54c54c66c6e3d4a0bfd1681c1d1d81128a086630c90bb38acb986f7df6ec59abd56ab73bed766b3eef1091b551bdded0d59dcea500166b8d12101d35f492b591884b92c4b915230b2026c39574c4a13c60651a983fa28131ca803d1909730e8f9e6d15f917790a430a3e592073fa459b01cb04f318b97942fde91c8149313b632854c633434c4bb18bb973c02320a66376ccabfd80393708f89209c54375524459f508821a51bb9fb3b98388bc2bc30a4901f9921511884244047b2bad7b18971bbfcc45e10c25ae2a761d6d427f525aa9cedb1cabc32cb00c159400856a08c6cc6a9efeead52b63ccdede5eabd5c28264acd4815da8122b9829dcdcdce03d1b8d46689c95240966093ce62e1916be428ddd5fbc78212277eedcd9dada9a4ea7979797b06edfddddc5472549a2eb1cbd9386d5c2403c88fd3c06d64eea0af02449c803967ad79acd66e7e7e73ffef863abd5dadbdbef745a9d4e1755005b2db5262122ec651bc7b1b54ba763699a2c1609724681636a02996b64ee18c697a55936ae305e0af3bcdae56ecfb0c27c54400b9a138ee8d5e2d5e11965b63e5463347e4d58396ed7288d219234b5605b696a436d17f45ccc196f0d9ac078974a4ab814a134946a3075f63004afcdbdf5af0adade8361052d66d9f8d411a80b5cc484650a2871ce0d0603acc5035f80dac85a0b4b2ee87d6ab51a6428d828c06409f5648ce9743aed76db39a70e1e66b319e2b7b7b7f11409442de7dc6c365b2c16f0e2b0b5b5d5ed7667b319d458709205eb8a7ebfffead5abc16000e375e71d30cc6633601cc84ead566b361bcd66338a2c440f638cb5c6394992643c1e4d2653889c4747473b3b3bf0d8050f108bc5a2dfeff7fb7d586c844aaec56281459144d4ebf576777761ead5e974eedcb9331a8dbefbeebb7ebf0fa7cc44b4b5b5b5b7b7678c79f3e6cdd3a74f5fbe7c8985df49326b365bcc2ce28cb1711ce1bbc6e331164b56abb5adadadddddbd46a3b1582caeaeaedebc7983f7198d46a3d1687777f7abafbe3a383840b596eaf8c3dacfc5e8d88709b22cb3401a954c9dce7212653894569fe44542d5ac61f592035be4e5baa2159332060d756515a1c254e9b114aa3c1862b02c012c1151fec5bc52c66b20ca2cc7d11bb5713aef678602ee9ce304c5a043f86d3ae95f551091f7b6c3528ea0def8a22882d911a418f272194609f4c08b8b0bf63e4861694944c01de400abd19d9d9d4aa5029282eee49c83460c59e9b21e0016f4faa1a64cfc0c66afd7ebf7fb93c964329960c10df929bf376fdebc79f3c61853abd560c83a1e8f9324a9542ad0ca4f2693d168747575359bcd40916ab5dac1c141a3d18ca24a9a26ce4127c54452afd7b7b6b6d2f40246a7474747fbfbfb30258da2081eb55ebf7e7d797909ca09f6042a371c0eb1b6b1d1686029f5e9e9e97ffcc77fdcbb77eff0f0703a9dfeee77bf3b3b3b7bf8f061b7db85e92c9cd59c9f9fc399579aa6af5fbf8ee3a8dd6e1bc3699ac2ebfccb972ffff8c73f8e46a3c3c3c35aad46c4878747f57a238ee3c160f0e2c58b172f5ecc66b34aa5727a7afae4c993070f1e3c7cf8b0d96cc2854ece9f8f563dbd0db0720c4b45c222c3d27b7d8c72b1d5223e4879e225592f3c6618530edac4e30d652129f753f32904243322692ed2e34e9a032f570836d80eaea8c30a9764a82fa61cdbca9d2bd2850e1e24cb55dfb523ff2585f76058b9db255833acf29ae294ae4006ae4136c1d29676bb2d22f0b8c2cc70a0ee9cbbb9b981a578bbdd9ecd6617171793c9049c4b7d138fc76318b8572a15789842bc0483301859bbddbe7bf72e9cd8cc66b3d3d3d346a3d16ab5b6b6b680713040478be976bba051f0b4678cb9b8b8b8b8b8e8f7fb607f22827710a1288a9dc3d8b8d42f74bbdd478f3ed9d9d985c3afefbefbaed3e9f47a3d3cabdfefbf79f3a6dfef63dd62b86e693c1e8fc7e3344de188f9e8e8a8d3e92449727d7dbdb5b585120633dddddd3d3a3a42a1bd7efd1a0e2a0e0e0e0683411cc7c7c7c7dbdb3bb3d9743c9ea0abc7719c24295686dfbb77cf39777afab2dfefcf66b3d16804f434c61c1c1c743a9dd96cf6fdf7dfe34decd22db54ef3a9a0b7d25eadd15529932a07b542fa7c64f16a685c222542e28acd49c16c9d826efc5e8045c189781d16f9636699740ead7231266b26aa9c8b02cb89db00963146457809786258687fb5b02522efc4b0b4c828cbf6cdd2c07745bcc95b5186fc169e82b150193de4e6e666381c763a9d838303f8937af2e40984140a6c1a202742eba415cfcc90836081a97a680e14f940340016f8d47c3eef743a272727bbbbbb30ce04b3830face974cacc878787fbfbfb575757cf9e3dbbbaba1211589c625661b15818c35114a569e47b0881cd55abb5838383e974faecd9b39f7efa693e9f1f1e1e7efef9e7878787d82c274992bb77ef82ec60e1d1c5c5c5ebd7afebf53a0ae1fefdfb77eedc71ceb5dbed76bb0d500398eeeeeefeeddffeedc3870fcfcfcfbffefaeb172f5ec471fcc9279f341a0dec33f49bdffca6dd6e3d7efcddebd753cc871a639bcde6ddbbf78e8e8ebefaea7f5d5f5f0f8723f43aac289acd668787875f7ef9e5fefe7ebbdd3e3f3faf56ab711c19b39c13c831aca0d2f310462bc0e28025add55b858d4aa12704bb5cc3d346c5ccce893e25074c0a58da148d31488f687a1b606513a8a25d02c05ae64f192b2d49532792aa600838d339c49061a98aa308649b01cbf8e5b15aa4ae4c8d152a46ffaac23b31ac62c3c55d6046582da89eb0b40e20ad4089ab9ed4a1bb21bf72109d736f6f0f2a6aec09864e7b7c7cec9cab56abc3e1f0ececcc390702727474e49c833075767696240936b351ff30a860a8c01a8dc6f6f6366c175ebf7e0d49d31b28ad8ce955addeebf5b6b7b7e1308b99efddbb777070c0ccaf5ebd027ef9e2426930bc1b4f26a3d168dc6c36f7f6f6a032ffe1871f5ebd7a05ff13d085596b5badd6f1f171a3d18044767575b5582cc01fb7b6b67abd1e26077446556409d9f8eabb77ef4551f4c30f3f0c8743203894868d46e3e8e84ea351ffe9a79f50e0c618b816a856abd0f1a193a08866b3196645ebf5fac1c1c1f1f1f1c5c505b635f3b6f26c2d2ff7b7f5f50eda85fadf085814a60718414b55da96724016c688f73311c673c6437406b0c2fc45c4bf2a608888566ed7cae0a9340638b83af720658824589a03b99503c012e78c021617dccb843c2b100f9717fdfaf63c60850c00e015bef9ba9e7b9b0efe171044e4960c8bcb02e2d58f283459e160826586502b82a4a013ea3a15e017d452a3d1086e1b743d30dcbf38e7a6d3e9d9d9d99b376f98f9f0f0b0d7ebc169fa7c3e7ff3e6cde9e9699aa6c7c7c7954a458d836125301e8fcfcfcfe13a666b6b0b1e5d5ebf7e0d8d72086da872dc3e9d4e61680ae9f5e1c38777efde252278ce811e8d08d68cd61853a9c4cec968347afefc05dce01c1d1df57a3d630cf44700a07abd2e22ea21faecececa79f7ebababac28400a635e15b55fcec2134faecd75a0e0683ebebabc160001555ad5643210386fafd7e9a26900103435c49d364369b625a83998c59ae19c22640308cd0d9005d5114c7d162b19661a1f9d00a8c947423a578a8ca9071a503b707acd2781129c618c358252381268bb29a750ec4c97508450508cb05573663e89cb336140f53e7c4ff958884aade0a5d8ce0843931c6a4a941c57af39e12c0626f0c81acf4fd39e013c5defd170c5eccfc512cdd6124098cd0e5c1681910bb804a2a651011b4d1501589c8e9e9e9d9d919dee4e8e808f1f02405af09699ac2798ba2db783cc60c20a44213b855223fe30bc385d168f4c30f3f80828d4623630c2607144f1163adbdb9b9b9b9b979f1e2c5703864e6070f1e38e746a3d1f7df7f0f91106e02432a47de24328a62f8e7fae69b6f5ebe7c8909044c6b62bae0d34f3fbdbaba829777dd32bad3e9c0c905a43f7055668e22db6c369b4de8e6dc743abdb8b8f8ed6f7ffbf2e5cbd168349fcf1e3d7a74e7ce51a3d1984ea7878787c3e1cd6f7ffbdb76bbe55c0aacf4255fd59c31062c162933f77abdcf3efb0cdec47ef8e187376fdefce10f7ff8e9a79f7676765ce00ebf383e05c7fcaaa630a5675e44019059bbd2526553aae5faf22ee046d85029034fab9c156288d85a55dbebd20209f450ab95e13980a295864b44de025839a8c22facc809b45ac639d1c5cf12b8002c15034dd67014271874bcf370f884c807a48756cbfdd59b958ac847b17437c6603b1cd879ebec12f447d0c5607b7722d2ad719819fdfffcfcfcf5ebd7a3d1a8d16840afdce974e03ae6f5ebd7fd7edf5abbb5b5757878b8b3b363adedf7fb676767171717101befddbb07c7c7b096c25ba1fab189ceab57af5ebe7c092fc9b039d8dedededede06c99acd66e05fde47e0e2fcfc62381c3e78f0e0fefdfb83c1000054a9548e8e8e1e3d7a04a32a1798cf4033b2b5b545442f5ebc78fefcf9d75f7f1dc771afd73b3a3a3a3a3a8202aed7eb3d7bf6ecf1e3c7cf9f3f27a2bb77ef420305b38966b3a96eb644a4d56adeb97374707058ab2d4d222e2f2fbffffefb8b8b7363ccc9c9c9af7ef525e46266faecb34f1f3f7efcd34f4f9acde6679f7dbab5b50f3c851d43a3514739349bcdc3c3a3e9745eafd7f7f6f68e8f8f5fbd7af5fbdffffedb6fbf15911f7ef8e1f2f272676747674e42a65606582b90ca350c5a39f0d3019fbd38a96995a915f32c07ac8043e1aecc9c20afd62d860c4bbca12c7b3c2a356e502bf9db861ccf52600a8faab612bf885d258fe068955b05baad546d0cad4d315b650c1b93eaee07086a5fad467c0ac3b93e4b01e7a2bf509ef57e0c2b876e68a368dcd0c5a0109919e64ea057908974fb060cf891df20079e8ba1a941bf454ca3d110916ab5bab3b3b3bdbd0de3296606ee0092f6f7f7b1630da6b7c27743e65096e34d9acd26acb1a06eeb743a8bc502760c954aa5dd6eefeeeec39c1d284344dbdbdbd8bc6b6b6b4b77b14e033f36e2cd47a127025244510450e8f57a10722b95cacecece6834c22dfbfbfbf03b5aafd767b379b55a41b224593073a7d3c1b617d56a05fb09b5dbad3b770ef7f7f745687f7f1fa5319d4eeaf5fae1e1419224954a5cad56f7f6f6b6b6b6209bc7719ca62e499246a36e8ca9d56a272727f3f9a2dd6e031f61f0f1f4e95358811d1c1c3c7cf8107b0549c12c880258f1f26611c23838928a8d3e12cc88c34614b0a70c6031af3a95a60ef7dfc801960819a3aaf710a4149248bbb30738bd770558444b8b53a8d8c19b8a5065569b56903773cf011619a32085b902e75c8a91ce39e78f4eb557fa870e84bba0ccf20c2b2f18e68613d47baec396f6eebf48d81291b732ac70202d1d6c15e98908148682a91f9838a4de95682e9fc562618cc126a3e22db64404b37560672282311fc22011014ac4bb70511b167d61e53e88dfd9d9817d00f36af28b88a228827b2cfd844aa5727474b8b7b74b4490012b95ca975f7ef9d9679fb1d7ca3bef1e4785263dd66ab5e3e363101f1bb897c19b3373a3d1f8e28b2f3efbec33f16607f84c74365a4e69a5c62cbfbdd56ac571648cd9dfdf6b361ffcf33ffff3fdfbf72793c9629130d368341491388ea2a8f9d9679f7ef2c9230c12b917d3328fa2e8f0f008f297ae6583da5e44f6f6f64e4e4e7ef5ab5f6d6d6da5694244c84a2b4b963a6c550c2f2126548a17008b680558aa3ecf5f0d1a0c51005e1b7a1a07da28a20cb489f7dc4005ff331c90a82cd821863cb200b06081b5f4632379317089412292a62677d51f433b2c388f331a1ff22c63d83993a6c639ab4c2b4da1ed5aeab98c31d6a6d6bbf045d049430ec4430fbbab5565b701a6bf00f062e6f7d661e530ce055bdd04834fc60359d10a117c444ddea1c14105837c61b68bfda2045558aa0adf054674c537c43be0add08d0137ba83bc4ec639976285308cf5013149924491857a8e8830e399667d045250d3d65a504818a0a9bb5409bc80a92b77ecb8036863365e5a59d685bac977cef57abdbff99bffa7d56a83af351a8dd168b4582c207a031031074a44a1cf55c562f1663e51141b63209dcce7f36ab5faf0e1c366b30955e0d1d1d1fefe1eb47b00b5829697020ccc41552812e6b6025adee9a7fcd48310f897513308f1b6efe04aea6a2a6c6bb98697ab020556590989e580452b238955c766163fab289e58b10216889bba540e1eb7b4532fc29606ad0ef1e2a109cc1a8095a126cb1836c661d8656fa9a323716995e8989deb11a56db5b4bf6c4ef03f1fdecab0ca1b69418da5312202fd5f69322d0be32795d025442494c0b53e141ab49e3467dd268b3d77e060e0b5c126146891ba4b2b7b2f57412fd225dce4737648a338a5a67ac6af58d4373181c12a11c1f81e8b5a9cf7a9804bba300052adbe217918f5df2828002466e6fdfdbd9d9d6dc4604e436469acafc592fabd3c2868a0e10706fe6021ce3033c14df3975f7e292bbbdfa57217060da5755d6c0f618c312c520e583ea5099b9b093c0285af1d369862ccbac005ce4501cbe082ba9d03cf2dd9ab226254175f34e042003059bf16ad08580a5b3a6eb9824d96f336f1384f92d4b9344da3344de1e45d19969ee7948ccab65002457d96b68410acc3a6521afeecc08b99730ceb3d5e31842a188ea3027413e65cd3a1a0b0b4bc42f4d1783fcbcb2a585150c4dac973fd41c9851f333355a529cdcab1147917029af1eaf5c47b50c83d5d3f47bc6d847e48a8e3b081272f244e036f168a7d5a96e173c5d3524cb3027675915038cc8a67b25a4aebaa89889c2395bcc03d418a416fd3348110e4312be44d9a077316ca287b8d0b577245973bcfd56031bdaf1d7e6b0be5ac3048c10d521003f5e99ee6ac443f221231480ed8a10260d1d2c94c66a3b0d0a3439aea79de819f4298314b85469a3a6340fc8da75996283566b5c7b0c296090207c6a514f86e5258dc505c7f7690f49620b2816195b6aa62dbd2d28191811a58111164ba5c1ba76c7b3759afca5afa4484f534509c87da74cee25ac8bf28e839619e1c2cf45728a1405d42decad12c2dd743afa18668398ab2e780e1fb13858648143e45d3284869bcac5cd6e00dc1adc823e02a67110129cb9567093014804ccf7d392beeacdc87633d262d195f44ab2d0ecb1fa1c55bbcba219ed70056b1cab40073dd896fcdb034b7dc60cc05fea5e95db0346f3de7ca01d672d4cce9b664c5add2c0887415547ba5f149028615f961436709d3348dc0b9108f23b40139868573cc95eb062ea187c8b0e4b3d05c5eaafc67272432bfaf0e6ba53a451163264ebf1fe7d8264bd7cdb09780c2ae48815ca301ae1a86c3e1d5d555abd5ea743a711c83f15aef1b3ee884ab16af31e180a354c564179a65bbc98afdf1528762a2c8c2510991d115ddcc1c9edb6033ae50db6dbd577809dc31e3b978b762b15b6ba26839472105e28676a9c4305f8d592841c8293b00533966245ea5c2dee11792e17a36e7fc43ca808995be7d2060859fbfeec6d210e6a6859c832ac90a89ebd27b7bae0c4889f7d297fbcc00b6c8fb78201193032c11a8d8573a2f453d257a6821ce39282198970a5665585a4790ee736c4b5f8abda4b28e6785e5b911b6fe4c504be4363aacd2a014006805d370488210b3b1dc1f16d5ec2704156e2890e9b4dad026a06e17919b9b9bd7af5fcfe773ec84aa2975d21d2b69540d147a8cc28c9e8880f4b1177f142cfc57a8a74d27e2d23449d3a576bc52a9586bac35449ca6ab7d2bc8af31c2732108abe8aa2408c3a09a17a8e4856fc4d0874f8ea208b302ec1d66a95e03778593155a62d9bac81b1f14e3fd55d6b68e2a2e664e997e98b9a291c5e6e15563797191b2ac278cd14ca80cce7231efd4633800a030071da87247bda514d428ab52506e229e8b1579966fcc4cb45c7b180a68457d96094c49ad8dc0a73cc3729e61d9509f65ad5d2c8c5fe790615b61d3c0a7a9413c65b1271cffb457969628059ec5fee702f38759baafc836d612022630ad369d4ed55814cb03adb570bc89ceccccb042c25660ba56066c564446a3d1cdcd4d9224d8d259f538d0a01311dcb300cb66b359bfdfc7aa175857203d66d38808465e58a663b27a2ee49624e970381c8d46d85ab5d56a610f6a66331c8eaeafafb11119045e787420a2c160707373039481b128ac5b61d904a689f78435064a06ae506104d86834767676b7b7b7e6f3f9c5c5f9f5f5b51a1c6c6f6fefefef63facf65e77d72308468f43bde148cc2106585eb1cc414cfc3c8e26b14555ab406bcf4def0840b8095bbfaae80159068a62c60e92b699ee2c57cc98a81bc06b034c35cc9e47010ff63810e110394f45ecfad562b0a8318c34b1c34982b444ca8fd802c91a6aa4581b9c96afda6d632e444a5ed52a0e75a08ef51d4d9f0a786b3350c6b7da30cdf4ca0fdb1d660221f9d135ca35eafc38214fa72f54d8c9b6131806523cc0c570ad86414ab0bc997b2736e3c1e5f5e5ec2bbd3743abdbabac2d23c64beb5b5b5b3b3638c190c062f5fbe84bf145d6ca88321321c0c06070707980d90a5f1e7f2d39c93d96c767ddd3f3f3f1f8d463013dddbdbdbd9d9b136babebe7efaf4e9cdcd8dced1a4695aad56a7d3e9d3a74f0783811275d80aa469fae2c58b7ebfcf7ed6b2d56aedeeee1e1f1fb7dbedc160f0fdf7dfbf79f306b6b2bd5e0f4abac1a0fffdf7df9f9e9e8239b65a2d6beddede1ea862e8d33d572fb76758c6c07bd70aaac80bb6c56c793d78ad6b1b61ca0dc7d266567aaeac6db3f23817bc3c4521a628f1d1a7e43a30af87a73046f185b2b242518705b1d1794b77bdaa6c2be0592b7f01d626ceb9284a559f858e0086e5799649d308ed308a922449160b0b1127491228b58cb1605e0b1f389812d5935c5187b01e5cd5fa5d15f2ff04db622e655821ef2804c99ec034c1b6db6d2c8e61e67ebf3f9d4ec129e02e1dcc2b49929b9b1b088ff078055352887e49926c6d6d811c8134a90b6398bf2b2ac16cddf9a9143c0513945114b5dbed9d9d9dd96c76757565ad85ff0311b9b8b8004660937a9038f2ddc339994e67d7d7d7af5ebdbabebe8ea2783299309b6ab55aadd6b0749199b1728588b0973d1c6639e7eedcb9831dadf7f6f6daedf68b172fbefffefbf3f373bf529ab6b6b660fb9e24c99b376fbefdf6db7ebf7f7272b2b3b3d3e9743a9d76a552b9b8b8fcfaeb6f5ebf7e7572727272720c8b7ca01565553365caa99250065826074a94e5595480a175e79b7f961e43ca435960cab5cae255dc78fb4e529a3e54e4f3fb021605aad2b00971819a89006d1d519eb879c022afd5b26aed80abd61a6827f02cb7b4e333b083f7dc8a60131f6aafc22a2e3613a8f3f593df360cbc0728c99f92671518166707bad226150a1d2811634cb3d9a856ab100cb1a2103bbe405f0eb8190e87b8c4cced761b4640f02280c10118876537d65a10abededed070f1eececec5c5f5fc38516c425220a35416031ed76fbce9d3b7b7b7b2f5fbe54b77677efde75cefdfef7bf7ff3e60d3cc6c0af83f14ee24564341af5fbfdd1688c16389fcf87c3d1cdcdcd683406698fe3787b7bfbcb2fbf04d10325c1c0b5bdbdfdd5575fedeeeec213711cc73ffef8e3d9d9d9d5d5d5f1f131c01143a5aa3040127776760e0f0fdbed76a3d104dcc31969afd73b3c3cc24a2035c4cde1cb6d5855a9d23d387231256d04acdc6b145b4e69644e778e04b94171dd792ef377ed4021e8e462380b58fa56b454ab2f65b7904985f7e61856ee5cd996c684be1c8c59edea5cd46779b60586856d5c60536d9573854c1f3151946158910f3a810859073c2b7893d5e48f72c3a01c967fb729e7421cff09908bf9bdd61266da659aa6ce2d775580e6086eaae0d3324992bdbdbd5aad4644d3e914950d6b72448a48a7d3b97fff3e6e87b60b8b07c1ce700e490a6260a7d3b977ef1e110d0603ac04821a1ee264a7d3e9743a203ecc5cafd77bbd1e96dd2c160bf89e0ffb27acc92f2f2f9f3e7d6a8cf9fcf3cf9d73706e076b4c38f92322d882d76ab5972f5fc2090c3c49d4eb75f8fc3b3b3b5b2c1650514d2693adadad5ffffad7bbbbbb50ae31f36432d9d9d9b97fffbe884ca7d35eaf371a8d2e2ecee7f3f9a79f7e7a7c7cfc4ffff44fd3e964777777369b7df7dd77575757bffef5afb1e01133d9543690ac03a90f042c2a801779d40831940b5856fa338cdc0c4f1f2b6c00beb73ed704d627b91cf4fd437a45d94ecb6fd3f187782dc19477a0cf62556584f19cb5a481f7a1e06d1913c1c50a5531990ad618e167668b05e74b59ea9628c1bcc2b88db2da7b8402c3a26c3b2b6bf499c19c889c4b67b3799aba385efaedec743add6ef7f9f3e7979797588eabbe2b21b241c32522b3d98c88b6b7b7e13a6e341a9d9d9d0d0603f86257bb126cf32722b55a6d6767076b7421e5b9e512dfa58200ea7c7888c72780cea875984e53ea4cb09a505c5e5e1e1e1e7ef6d967f57afda79f7e7af5ea951f1badf52e7140124f4f4f9d73bae52211c1f1d6ab57af3031ea9cdbdada3a3e3efef5af7f7de7ce9df3f3f3e7cf9f4f2613228ae3f8e1c387474747979797af5ebd7afaf4e9c5c5f97cbe383939b97ffffecece161ef1db3164e8b30000200049444154dffedfafbffee3bd7bf7befcf24b7576b84e122ccc6767e2b3e7a1bc50925e02a50fad01acf018b2a7309978630e0afa40aea58519be6bcc6d0267053a3c7d1dc3caa5cf3d37c7b07293360839dd563190675e2658c4139e87f6eef05763ad752e458bf29aac15c342d3b5364953e55689f2ac523b78e3d71ba6c1feace449a57eb8ffde950133fec7f510a973a8ade19d38d0bb54e9c7d897308aa2249961a307a8d289c85a0be7c55ac7ca4bb1f382d637ac22c6e3312858afd7abd7ebceb976bb7d78789824c993274fa047c7d638cc7c71714144400d6c0003f302c877e8db50811111d45b9019f13e216347fb68b55a506f9f9d9d1963aeaeae207842cc1491d168747979f9bbdffd4e44e6f3391cb61c1c1c6002e1f7bfff3d3e04b384272727cc6cad850a1fce1edaed363c4c5c5f5f5f5e5e9e9e9ec265f3c1c1e1ddbb776bb5da70387cf5ead5e9e969bfdf1f8f47c7c7c7f7efdf87838a70107e5fc0529bfb72b4429dae9334e96d7a744d19f6f6f7039acdeded9dd2ebf9bbbe897e48f8519215304db0a888b3d01cc25348b5b8c0b05cd618226052d8288c9ccbf82665afa5b2566db20ce60afd006f43c062af4050cb67c4a8796a88a739bc16ef77ec4f833eef11ca1816c2fac8ccddbc34bfae10d170b8984c2698ad8fe3b8dbedc217b0091613b0dfde0aeb4b408e6e6e6e4e4f4f078341ad56dbdfdfc7541a1101a49e3d7b767a7a3a9d4e1f3c78b0bbbb6b8c393f3f3f3f3f37c6c09d56abd5d2d5337068035736dbdbdbba3c08baf9bdbd3d6885c206847ba1357ffdfaf5b7df7e8b094d6cb7054f0fb55a6d3e9f3f7dfaf4f1e3c7711cc3a1282ed5ebf51f7ffcf1c993278bc5626767078e5fb065ce0f3ffcf0f5d75fc369fd679f7d064ddc7038fcfefbefbff9e69bd3d3d35aadf6e9a79ffedddffddda3478f44e4bffeebbffecffff9ff1e3f7e5ca954bff8e2f3dffce63777efde8da2082a3335c8a202f3bdc5b9c1fc2073296b2e99f5db70356c0f14f45bbdaa5ddd142c3fa9801deba0e45d216673e002b7e28d0c4bd398aca5121780acb4c48a325718a3ac8a3d2343230c8f5eab65bc3e6bc9bf708ca215db8aa2244d139d374f92e5bc217458e013d090ea3916de63989760b9981e3d84653c557096b11679962f43fa93e9dd993fcc0e4b875683b97cf67a68dd6f42e5352d5f753e457e7881df2b226a369b3b3b3b10067567f9f1782c2220655048e9047fbbddc67e5cd65ab80984e92611351a8dc3c34318b2c26aaed3e9e027aad6bff9b225359b4dd858a0a69bcde6f6f636000ea6b0070707f01c1f45d1fefe3e68205e03daa5c562b1bbbb8b784c5c42c3052f865b5b5bed765b1d63f57a3d22ea76bb8f1e3d3a3939e976bb83c10d50f2e4e4a4d96c7efae9a78f1e3d82920bab9a15f1e92d8065d7c49b1c60690928ac84a09303ac30326c3ec51b8bc9de23bc2b997a6b26b76fe1c5e76ef8642a4379e051887461198628a915410576e33500e2f5596a3fa13e705673886058605b605ed6bbf160ef0a0933f8cab6f42b148942d84a0b2e49d65547a16043b5d7470f6b1856b10ec2d6ab3383f82d2244124571b7dbed76bbc815652481f5908e2d70c0048d3baec2f7b1788701bae619c5b7bfbfbfb7b7c7cc40228875784fd54941cc547f5bccac3f8d5fe30e653c334323a0354abe32409d0e0e0ea0ed32c6a86dbab5166c0ee00e3b297c69bd5e7ff4e8d183070f28b080c7eabc7bf7eeddb97307f13055c3d2c8478f1e3d7cf810ef808fbabcbc14a19393e3a3a3432cc280307b73734344b55a6db330189eaf03ac9ca23dac65539885a4b70196f637caf6c6b0fd149bdbed2337c47f48e0b7312ccaf6612acc0c729655852c2c5762aae72a4e5084cc4b1faa0f529dba2c1dda2c571d7a0d57a43ccbdae2bce1f21caefd4386a54b4d54276b8cc1220df5b6543a25aa75adc4aac8b6b480892045fe892652983fdca73b82b5b6528943b15917426b65c0393238515816ba6c85fd4681a81ed4139462126c670fe594b236c9ba4fd1f205a6909f5706ca84251e363e7d434507e4acf9833342f506d5beaae4b17b0d1a01545ae05cf051054842bc5a6fe876b3f045a39c14449288b0a9c77c3e8fe30aa095cb42915bad635e1b008b02ca16368d4c33d928c771015c6e4f91420e12fefcf036b9e171c563d878723d96d67c4e0eef10c2520dbf2b57f8b9afa6a0e7678b42440c2d4d048c3129b3c1869845ad963129e607898897abf799fc2ada10371513d9fb834fb31e7443004dfdded4e1378625f0df18d6302c7dad5c7117ef0f34b8cbad3bb404151470631445e05fcc6cbd8f504d09f310849c7610cb12432aab33801c0c65144c0218ef268dbd2652f97948a4295b7fecb7b627bf7499b28a18804ed8b191b3dea5f9606473ce018c72df0b6b09554801498d31ce09400aad2d8e2b5e827b0b18f9f3bcea7d1dccf1ad012b778b04737fda827231b91c36c7142f157bf2470cbcd1c24063941ce9b7e7ce4bf32ca6e42c36e5e25de02e4de50f8d57b95244ac450c7c3f609de96a7b2a6b13e7a0b75ad96725c9d21ade9895ed3b7bf110edcd7a2fbec6db6729bd082701a830e9a935958b0c8ecc6c88a0055b5bcbef55811f836189c87cbe1099e90743d88156481fa5dd581fa7350a145754e20026d478444147bc9b40a42c0e74b9f3b07d84cf2d4de3bc93d25c83c31ba6de775a78355dfa5d5bbe12bcc54b4197a9cf757ead865274edf37eee39b216ee95193729d83173169880356bf5565c08b4068cc292096b2d4c1016885ea542fbe30fe0472194fc29429143e5e2c30eb9ee586c3feb1e5784b075655eccc43f8e98b1e9211119b5cff20c4b88d839ebf917fb713a3146b55a9679b95f9c8a84a58d240758bada5f023357da389c00adf059fe28e477452a25aaef14320cabb4400be7f9642292248bd96cbe58ccf5838d31d84b221c7e5d76b17898ad0ddcce50b69f843a42ca7a0d0d752814b0a1b026721fac97424d81e6ac05aa00a131218ce67437b8341e8f6f6e6e607706d7ef6ee9feb864d59eb248935d5e1f02d3baf82c78e5db5ce979ae488bd59d2b76ce221467512c5798c556551ab921fe36797e94c06be60ab96039b939652e4d31bde6b381e422a4c1eee869e0dc517916055c8cfc7c22dcfe85ba2d3d7a7d5612454b7dd66201cbac08dc4a670f815c98b3521fb936b005e3028451415246281231ff13ffbbd094f4036bf0fd1816582ed1d229f07c3c9e2c1673eb9dbae832141bb87052215101088f560d3d7922c6810062bc0909051d3ed7a6918f09367dd08fd2f4da1a42466303b77cece183829156df4df3d74b0a1cd56ad539777d7dfde4c9132c39ea76bb50e1e99b1befc7993da0eb138b10b30e92de11b0f2ce0bb5dcf86d804501b894128ae2d5754d28bcf74fc79b6e1f6ec3a4d6c56f3e86215792b70961a30d8b57f3d4e11cc97cb11305eb8168e95f1b6b0c8d5fde9f115c74b4c6736de0c42df1fb1b72c10e96b3a28cbe4308a6fe6ad87e96c7b0b4f9fd072491b7eab00a21934064694a3e994c9d4ba063463af44f15b2484b6e39119ba681d7274525d507b107141b78c243b62a46e5980e744648000d77ce6b95f88541186498595d32626610d379e1cc0b0cbb146131a5a20bad31210015c09b376fbef9e69bededed7bf7eec1810452c2190e0464f596556482b76755c5941bfa80d659587f9ca500948530addcb0a273319be38b69728deead77bd5386ef746f0e5c7205b2995515395438126c4e537c56ae6a148f42cec5810e01575db0c8d12cddf9af36b3b0d63897b18337c6581b25cb9d0d977aab9c3e8b7dc704cfd279436332ae6f4284ca3129f62cccc32e39876ac247b131f94d5e398371b7afc05b30acb23156df78a9c4592c9622a13aabb3d6622dcb643211918a0fe8e1d80e1eb3638d46a3dd6eb7db6d661e0c06979797699a621ecd04666f807f5839b55a2dd87f92276544747d7d0d0b752c1b4cd314c69f4484d740b1c2e8bcd56a31339c9a8ec7e3344d6bb55ab3d9841f88c964a21b23c2f515fc7621fd68349a4ea7954a656b6b0bebfeaeafaf5fbc78f1ead5ab7ebf0f6f10d81cb0dfef63136966ae56abdd6e77676707be2828f0bc5a0a349b8f6f05a65ca3cf9deb71c390beb9e1bc6353cb34a7f7b8eb63855c1fa37767521ff7585a2f61cdea6b6bb9852088a09223f31229783957c322c49c7ab695d7a870d9d8a933e30a4f2a7e5250f569616b4eda389ce4528a37a37fd7eadb64e91ec66b04e29857fa60630c91807760632ee51d70c0c2ccdd6e17fb39635131fcb58304c1d11dd621f6fb7d6c447c707080fda6d86b7c506aba2e1a1bb22a6972cef5fbfdc78f1fcf66b34ea7a3af8dcddcb1f3335cdc586b0f0f0f21dc9d9d9d3d7ffe1c8eab3a9d4eceaf29e0f2f2f2f2d1a347c7c7c7b3d9ecd9b3675830389fcfadb5373737d3e9b4d96cc28d5f922483c1e0d9b367bbbbbbd6dac964f2e38f3ff6fb7d3cd718737c7c5cad5661fd2f7e779f902b853aafdbc3d62d012b54a551965098ac3690dee69eb8b4c1dcb2cdbd35e5edb37ad750fcf075c75cfae2d10433894a3d4a71274c1f86d0e2a7987fee768d2c322c3d3a6f19eff55058301845518af1dbf84d39d10b307f1deab3700e994041ca785f6fe1670642685e2e06b686ac30acd340f27d9f918b3f649650ab96fd821beb37cbf19b182798d7472f85dde66030180c06d65a189763e1f1f9f939ccd68165d56a153eb046a3d168349acfe7f03c339d4ee10b7032994052634f5544643e9fdfdcdca469bab3b3038736cd66334992f3f3f31f7ffc713c1e634f63630c36611691f1780c47a9bd5e6f7b7b7b341abd79f3268ee3c3c343c0ebebd7af9f3f7fde6ab5eedcb933994c9e3d7b361a8deedcb9d36c3667b3d9643279fefc390cdcf7f6f65ebc78017f5bdd6e6f3e9fbf78f1e2ebafbfbebebe6eb55a6a8a013f13263086be8daeea163ccb149b7aaed11787c1e225cd22ace8ff594ef47183ca329ce5297f6a2655fa26a56972b8a631b9b7cdd59abfba3c8243305b9104dd04a06382cd9c7278c7c178494489df284cd3e01121b1d2172b7e48f0ce78bdb525c0ef303e499e6185c514c66455b94b8c30c1141b04b77abd0e9ea29d4afdbddcb973677b7b7b3e9f434a8233036cddfef8f1e3b3b3b37ebfbfb7b787f5c6bbbbbb9f7cf249a3d1383f3f7ff9f2e5743addd9d9b973e7ce603078f1e2853a6028562a1cd73c78f0e0e0e000ef301c0e6f6e6e20668288a9d9272aa0d3e9b4dbed870f1feeecec7cfbedb7af5ebd6a341a9f7efae9679f7d369bcdfeeddffeed77bffb1d76039ccd66e7e7e7cd66f3abafbe7af8f0e1e5e5e56f7ffbdbc78f1f773a9d870f1f1a637efae9a7adadad7ff8877f383e3e7efaf4e9d9d9d9d9d919fccfc0d66c3e9f8b108632f29e1e8a0c2b3c5fa7b15a0f588697bb0f942bdaa930bb4a05554bae0d14c36d1ad9bb34c4ffa6907ba5d2c2e100c46f790c8dfb7250589a5b3106a1c8d18ac75cad5160b7a50c0bfb4b1b639c2363ac78336cbbf4e86042b6a50bcb42ce857943dd94578fb83d8cc92de8516e6582197f11c6ee6741cced4912fbbfe5bdb7d261d11a8ca460be008005dee482ad22aad56ad307224a92643c1ef77abd5eaf77787888c935b8f414bf3a47fd918ec763f4552880a0ea567731e1c78b9f5badd56a5b5b5bfbfbfb2050588c5dabd5baddeec3870f9324b9baba828b64b09e4aa5d26ab5767676f6f6f69e3d7b061cec76bb47474793c9a45aadc28d0400ebeaeaaad168dcb973e7f3cf3f7ff9f2e51ffef007b8be825a4d84daedf6c3870fb6b6b69e3c79329bcddaedd683070fbef8e28bd96c767a7ada6834ac5db551e559a53054e45394dd3d2c1b8457ae63caa5123d86239b7680b033fc3551aa5c58c77afe74ac6addd5b06ac298b7064db9816189404924dabb437aa1faacd263f808ec87100a80880f2707739fc64b8fa93678b715e210e55557b86f7d8585170b0cab586ad9e2a000ed322f81fbb0cd8cb5a0a399e7a67e171966c64cd97c3e8744265e256ffc2a769011a87e50108854a13aecd8e47504fa9e3a1ac07eb7d96c1e1d1d9d9c9c7cf1c51790d430c187718688e028753a9daaa51c9c7fc2db9f4e4a62c6d01833994caeafaf217e42fec5c48a319c24c96834aa562b44b4b5d56b34ea9f7efae9af7ffdebd168f45ffff55f2252af37748a13bab91c1bd7ef2aeab3c250d05b91072cacd260e6bc41502853d01a9e956b2dc59862b84d9a3f93c05980d0732e60fa3b1d8bdcaac8bf36a7dff0262155c97d0b624219cd18f65375a45bb4626c563a0fb6c5debe47d9961ec339446b2d7a017b5d676eeda1096612c97740ce8229118928c6215e1422946facabb40067983fdcd21d3815454b535a5a62ed12d4a1db367e9d0a66eef055cf9f3f7ff3e60d3ee3e4e4646f6f0f1962b121e086fcca61949488c0ce0daa7dcaa27b1445b55a0dfa7ee02311351a8ddddd5d40e4f9f9b90b1c631111c8202680c187f512f4655114c1cb8d736e6f6fefabafbe9a4ea77ff8c31f7efcf1474c1afcea57bf7af4e89131a6d1683c7cf8603299fcfbbffffbc9c949bd5efbf4d34f2e2e2ee6f3f9b367cf9c73b55aadd56a753aed6a35d6699a906df17a86a531da527378edcf9735c0ab2db932c3a056592ee6e7134222f0a760551f9da329f90ae12c57fb14a01b338b776d1c56b4f34b744d76c67003dbe2f5faacacb57d1eb028bbb428db0e33b581fff0ceb7acbe4dfb12664b2717b71440a228aa562bc6b0b5368a2c330a888db17008035306c5f5bdbdbd5eaf777e7e7e7676361a8deaf5fac1c1c19d3b77b6b6b6d2348de3189ee0611e52a954a08cc7c269fc141138bd0a5f8b999bcda67abc429161e611057d7676767a7a1a45d1dededefefe3e5cdfc0fd0b1e114551abd53a3a3a6a341a7a57b7dbbd7bf76eafd773ce1d1d1dfde33ffee3e3c78f9f3c79727171d16c363ffffcf3bff99bbf393a3a1271fbfbfb7ffff77fff9ffff99f7ffce31f67b3d9fffedfff7c7878f0c73ffef1db6fbffbeebbef1a8dc683070fe03ca75eaf1319b58347b0813f90db0056816195375fca8ecce1d55c2dbf35a6b46dbc35cd9f552816d17fc331e453ebb45448e30a0b5d8bfc2b540eb017f9c266800f25bff2598512655b3a6308da15da67810d60e4feffd97bd3e6388e244dd83d22b3ee0b55000a3740821425526a75b7d4d76876766dcddeb5fdbe7f76e6c3aecd768fa9a76da5115b6cf1a60810f751f79d47c4fbe1a90c44651540e8e81e7637dc68c9429e9191114f3ceee1e18edf66de10665f11cd18da56ad18cf0aa31c88b35078aca5e273e07f1459cc4a2d3cf30bfe5086859941d7758410aeeb448045b0b823638d613d4404f4f17d1f46ab6c368b90ca6055085700cd0b1e5508ea8230c1f8938810970a05309585885798a0343c594a99cfe7c3281322d66023ee0233cfcdcd799e87cc113a8a2e0f274f581c11e31451b41289c4f2f2f2683442061da0dbd2d2522e97eff5ba994c6663636330e83313a25f65b3d9d5d5d54e07f9abb38b8bd54aa5924aa5982fbc607896327885987639734fac27d8f2f7c9a7a6e55de04ddf6f1bfbe806aa6cb1299261917a32a6b39e8c7863bcae68ca92a52da5d5f45f8efc7e68d2b625c65eace3d00e31c08a56b9c44de156b3e4ab2c59d6f9df351e56bcab48295d77acf749294dae73bc0374377b58c0440322bb1b7f7104302022b83e8868898ced1a8ebb21f49d71cfe5c862857be272631bd2910bfbfcfc3c808f8890260337817e2aa25834c67f15a96e8410f01ac5a31134a25aad96cbe520ca814a44fd7e9f88110bebfefdfb77eedc01b564e68d8d8d6ab50ab7e34c260be08b6c4ce31666a8225f5b25240bef280e58e31d34095b7c099cf114b44dcb75cef9ab90e94af80b6fafb676d125ac0abfcdca369e646164350065adf037c62f7bac8a61906db1329ccbee5cb63d0b433ed4c318db62cb0c6f4aa22dbddb2ec0b4d078a99fb0f65cfa057f28c312629ccfdde8cfb0a118d089199bc05111d55346c9b28c7dca2ca6b16e7ea175c35f14f7b1bf8d8e6c58204a36baa36613890458150e197e0b5dd556d7e17467ee6f025ac1ea0f35b352a920c01e4cf541102412495c5e2c1633994c1806c3e108841189bcc230ec767bc3e190ac3ca657dba766722eb2e0c3de63be20860abb5aa6e1e6ef996dbd0b5ce93adbe9d242a69bc4652d842d5b12fa54ac5f98666628986972a6735d06a0f62ca1b2a23c9b72ca6815ad4d0f67765bfbd5a6774e7dbd59d11aae4638733e5d74066dc81e8f4dbf13d63e9a6404315d5a5b53fb06628da2645e72fa7d4434538bce4fd67cad3d86e0b6781c4d5a7662606df05444bebf768d439f272280948cd6c733b3e3602012862a72142275341a71b4e8324ac93b16d03a94645a31bc1ab0ec3d6232ce044d82d465bf677edc2b8efe0dc8747f7ea7b6d3fccb3e7ad97e9aea953a5215cd8bdb5a1ebc79789225d99e5951939e88eb60b818740be09df18037f799863c6de9ad36edb2a1134523222218da60bf27229e8c5dcafc9d189639cdd41a8d3b39acec86848ecb61cf9edae58eae0ae1ccc69331188c61d27e226e32180c1a8d0611c19900f1b68ce828828ff9f0e62df18e002cdb5aeffb3e3251e333c0650c4aa8b910f7c4742745f8eb791e78a215409588b452e3a8d0b07c31f3c1c1c1c9c9692693b975eb3634d0d8ea56c8b4023853622d75ba81fe3db3a7ebc8bbc09e7e2cfe35fd5ed3f86523578c6d89c9e51664f930d394cdc16c31d69af0706cf9beeb4905169dce266b344911ecdb4e924861de298658170ccbee009749ec9c085f50262da5865266680816e5e472399b0ad96f4e539ab6dd694d2dc084a49442527b662e97cb488a63eb8fa6360d3e4ef30ec39e50d148f3d3e974068301ecf18b8b8b668e320625f8c6983d69341aad562b9d4e2f2f2f6381911ac789bf58598a17ffeaabaffecffff9d7c5c5c59595d552a9d4ed7661d24279cc80166b25d32035b3f5d86d91a786df2bbedd5bf7ff4dca6515f8ce6e6d5bd565fe5cf61e1b0bcc9735bf6d50a3497b1618165a38c801d896bd3591b3ec7946117972d94ccdd6fb0c71313b0d96d18531dea856c21e88998dd325e244337f3f1b967dbeef079ee72915baae934aa5e1021a862192bf63b2cc188fc6858a142e836286bf982f61800cbfa17f8d46a36eb74b44d96c56476ef14a29b31ac04e77681c3e632e6d1475ef7ebf5fafd74f4f4f91eb01739783c1a05aad22c3b3b995b66c61994c462955afd79f3f7f3e3737b7b0b090482447a32133a7d329f38e523ad96c560839188cdebc79033a6922db2026bdb9ff3430bd15b0628dd226bfe6d3f095dafddfa7bc0bfce8cfbab547a0e95644165130f4caf60bd5b32601cc9d0de4d9111d629e5c388ade77991b476c69f4e5121f4df535a335b0650f3247230353e87923442f60167038504af5fb7dc469a0c8926dc28389c8da0dcc426736ef0f180253634beb46023183532026b085c31c6ecf6e181493516c2c6636f9100d076c341af57a3d0882b9b9b952a9d46ab54e4e4eb074b1582cc2037e341ae1fe7098705dd7f3bcb3b3b33ffde94f8b8b8b77efdead542aa8cca83001a24af87e904c3a580d4e44fd7e1feb28e1446a6201daadca20f5cca67619609916661f32fbed7175fa43ff5dc96595f98e6f2fe359d3cd4345211ccc8736d752b476d5fc6943468c6d990b0d0c89c91080c66f7e5a3d3498e54499a5ec44d3a6e43a6ec7e00b9a65c1eef81cfc2366163fc22c210a6d7cf6b1ae058ee622f294450c290322894422934967b339666eb59ab55a5d6b8d100b524ae434443f475268600112d923941533034ddaedb6c9029fcd66e7e6e6b2d96cbfdf6f341a6649a752aa50282c2e2e1ac0d25a23a9bdd6ba582c6e6f6f2f2e2e3e7efcf8f9f3e7b833c2d7743a9d76bbdded768510a9542a9fcfe3056bb5dae1e161b3d9fcfaebafe1ea45a4cfce868d4613b1b4128964abd55e5cac221c58b3d9fce69b6fdaedb6e779b95c6e737313b9a3651491d5b4bf18845d0158b6986b63fb6732afbf67f94f6740df7b7bd9bbd862f5ff0b95e2b25664e3117aa58e4c4e26ea2f4f461f328022ac3c2f06b0c87209303a930d2f7601ecc247ea170e5dda5475cc86650c4064f50afb85637bb4158b0ad1f84094b0e4586b8d15ce42885eaf57abd5e06fa9a398c8f97c2e9148a652c97abdfef4e95321e4caca32c2f2e572398a30bedd6e9f9e9e8222d56ab54ea78373c230ec743a8d46a356abc1434a29954c2611e60141205aad56269341f5c199debca68ea61153a954a954aa56abd56af5e0e0c0f058f35e070707f57a1d9c2e954a21d129a0b95eaf7ffbedb7d56a757d7dbddfef7dfbedb76767e7528ae170840fe9fb7eabd542b6fa172f5e00430b8582e779b76edd42782cb2e6196250650fad364bb7bf8eddaaec966188d54c80fbfb94cbd0ffaf686b1b2bed6663148bcb9a0d4d5a45a6c5740adbbb0ab384660ed1741f58af8c0dcb5c651896c12fe32420acb9459ac253a844cc8c8270ccb10b9f8f48fc103f2c0358ccdc683486c321ccd5581bac94829e2584e8743a676767bd5e0f2c31325aa94aa5924a2583c01f0c06d96c167144c1c510330b999f7bbd1e8cf750ee302b371c0e91f72108826c369b4ea7cfcfcf6bb51a02d1f8be0f6684db22ee8db170a1e4f04a0d82e0f4f4f4c99327a7a7a7b55a0d91adf052ccdcebf5f6f6f64e4e4ea00902b6eedfbf5f2e9711306b6969697979b9582c9e9c1cbf7efddaf7837bf7de4ba7b3beef2d2c2c148b457872a552a9e5e5e5e5e5e576bbdd6ab55ebd7a25a55c5c5c4470547b10b3b7570cadd34763dff18652cd9477812bfd6558986115b19de6104d4e7ce14ce3a90031d661db3b94886cfdc96658068c8c910b48649e6eca6317cc94475b32ebe35d6ec39a7ef399e770149e9823ff4f22c2e215f86ac23a3e180c5aad16e2f071940f22d26c299148168bc56ab57aebd62dd7754e4e4e5bad16eec051a88a4aa5b2bebede683460b1761c07f1f39452a552697575b5542a3d7ffefcd9b36750c1606c2a97cbb76edd5a5a5a42d09bd8dc1fcc64081ff8ead52b24945f5d5ddddadacae57230f0773a9d7ebf0f23dad9d9d97038bc77ef1e82f995cbe55c2ef7d9679ffdfad7bf1e0e874f9e3c69b73b8b8b8bbff9cd6fb6b66eb5dbed42a190c9645ebe7c99cbe5969696fedb7ffb6fefbffffedededee79f7fbeb3b393cbe560ea52519821d39e668297fd21626c8b2d3e65b7cbe9df7fe7f267e53e7ff9ade995b16d8c6d99436296975fac72cc706ee086a2e414d28af700abae21536c2564c56d8daf83712b35311e4cf1ec879a62d87388172c2c2a2c1b867505cf328766367d14229d4e239e67ad5643089fcc3f5c00002000494441542aa4f902318147389c00d2e9f46834eaf77b304b01bf13894426932d168b52ca76bb035b8fc9964c4458d8ec384ea3d140793ccf0360a552a9c5c5c54aa5727878188621a26168ad89743a9da9542a4b4b4b26005694f8ef22910fb44266cee572d56a756b6b6b7d7d3d9bcd1e1e1e6291f3dadada83070f84105f7ef9e5d3a74f61844aa55278c73b77ee6c6e6e9e9d9df9bedfe974d6d6d6b6b7ef6c6f6f1f1d1d01b85bad16d4c0f5f57544a448a552dd6eb7dd6edb41204d139cae677bfff4701adb33f39c1b31f22ef0a0bf24db327bc4252e7e348977b63d4b47de94b895e159142111ceb1e7164dcf3299eed81a5f8d37bc9e9c858cd1ae08cb88e26c495f8b614d8b7d09dea7502840f53b3c3cf47d3f93c9643219e324c5ccc9641219658ac562afd73d39391e0c8644e3d20701c2c9f85a5f4492367e091485ac0284e1d1f62423d443d054e3a7aa9436b58c30d51cad52342643ad75a9545a5b5bab56ab4b4b4b483a5f2c168510b55aedc58b178944e2d34f3ffde8a38f98d9f7fdf3f373f3d960ed02ffc28003d7f67ebfdf6c36f7f7f7a1aed6eb759c8fe2c1cc6f3bacd9ae58a655d95f34b6b5bf224f72ab9927df8891cb6ae9af746bdbb362b4c83ec7bcbb3d6368ee4353639bb60c0e986c373e0a4484a66e261c395a5d883df62ca159e2661e8d085478aeb167692b27d6148ce252018a85e7fdd059429014c053b7dbc5845a3a9d464018a8b2854261696929954af6fbbd2008c230c0f2e07c7e3cdf974c26859086714077435c877c3e0f8d1246f47abd8e59c242a1904c26bbddee68347af5ea552a95aad71be572796161c1715c5c8e2811c6a3c2f67b408d208273b55addd8d8585e5e4638537cad7c3e0f5b58bfdf3f3c3c6466a4b700b7aa56ab9f7cf249b3d9fce28b2f7abd1ed2f37cf0c107ccfc873ffce1e1c3879d4e07514c2b950a82348c21d9f753a954b95c069d3470338d327c890d8b2d0e659f60b7daeffd35ffe6e55de03e7fe1ed1543d71568687a8ae32864e2d1d15a1188cdb028a266c604e6baae012373ab3014c6a534b67687ac061c155e6b0d3556447ceb1a36ac18eccd14432e52a914fcb06005874316112d2c2ce472b946a3beb7f766381ca652e96ab58adc0de8c0954aa5582c00c811e88e99612f771cc7f7fd66b3b9bbbbdbe9748410b064cfcfcf3373ad563b3838d8dfdf0fc310ee02ebebeb707d5a5c5c4c2693a9d4385d98552fe3fa4da7d3a5d25c10f850188d2ee9fbbe10727b7b7b65657567e7f5b367cfbff9e61bc7717abd5eb95c9e9f9f17426c6f6fe7f3f97ffff77f7ffcf8f1f1f1f12f7ff9cbadadad7c3effe2c58bafbffebadbed2e2e2eaeadad6d6f6fc3dc864461524ac4fff27d7f717111aa285923a1dd5c8ce8a9f941b33ff6156cb67523d3724de6f2d7be8d8d7fb13dd33fecca9939da69ad8460a5285ace31e19365660c79d20fcbd03d33cf1804a1c120e3e34e5620408a67e22166c12c388aecfe23f86199ce2384c8e7f3781984c76366a542224e26938944c2f73d30ac6432994ea7d3e98c109228c8e5f2ae9b48a733b80f02b38828d93d2cee44043b7a3a9dae542ad0dd30c7078f8a20f0cbe5cacaca72a15010823399cccacab2e338a954426b6dbe1111318f59613a9d5e58a804418888a6d66c9d1682f3f9d2fc7c250c835aade6fb9ee338e572797ebeb2b9b985a8f31b1b1bb55aadd56a6145e1c2c202b00cfe16ababab4b4b4b982445b8e7542a851f6b6b6b854201af607bcc52641a30156b0f957685c7f69ba676c3adde2affe97ce72fb07deb9b1a3dd1480cc894423883b151055708a1c2709c1d396aa81a58a6f545c464224da47ddf0dc3718a62223bbeab14829875188e3353c41816452d19cd5908a0159cb02c86654a1c7b8de9b7b22199236a00ae885c0ccc8c6547e634e02bc2da69ad1c671c2566381c12513e9f2f168bc06b224a2693c6a312951b5d380e6e85007b50f452a9d4fafa7ab55a1582b036080b6972b94c2e971142b86ec2cc874869588c66e6743a95c9a4b466ac97420cc288063ba3d1200cfdb9b9e26f7ef3ab2008a41c2fa9492693e974a6dbed4a29b7b6b616171781d4c836f8e0c183ededed304acbaa94ca66b31f7ef8214cfb4110241289959595e5e565e0afc97e68be996d98b0ebdce6f676f3d29607d6f417bc115b7e742ef32e6fed4632eda565f688c9c004262ea6111d455b86ad495c8448d6521233f9bea428b158180642103305811f860191012ce33fa1619211620c64a66076801a5bdf64c1c442316b26a2ebd9b0de7a021e8980563652a2caa26856895c2e2fa56426639393d2c155b8822223346c4fb80f56f0c1cbc1bc0cf01b2a64a954725d84c70fc33014621c1b0bdf0b65b7bedfb8cc524ad775984d3c2fe02fc32e0faf0bd89b00a0f8724a854a6998ba1074141c0ad0033f7b2925a6027cdf47984066c61c25b442340bd0663d6565e0abc8f9ec9d37dcea9af22e30a0bf24cfba4e85f0a4d024f60921b426ad45a4cd8d97d686a1c33c0e0e03454a2985b8cc5a6b3839eab1417dcc1230c9c4ac23ce75b1c8772643d45a0bc1420a12589a2398f9fbcc124e8b6101f6543d33db06196dad2a221a674c33806dd797e981e6cf300c8111c27252076c2ba57cdf530aa97ac6da75f4f21cc1f9188c880853159897a371a843066c71140cc756d1cd0246a28b908466a2240a77359ed68473bc795f98cf8ccb8999f434eebf31b4c285b1f9638a9894198bf4ac39c41b79ab7c0f9ef2b7b49de659d3443eea9b4c0410611aaf40d65a0b785ed378f6301482b52629432292d267a62018f73ea4c8a2a86b234a6610001604422e47bf290c15f3c5ea451b078423580a1692781c48ee87dab0ec6b6d67b0693dd9ccd6459ad778b6ce78d3daf86df764387498e85a340edc434298a5d1da861b735bfbfd4d2d4c22232172985d5fb6101140564a87f922e6068e2aa50058d8af2d572f1989d6daa4ffc173b1eed2bc2f456605f3214c95c6069c9935ff3d06d5bf677917b8cfbbb39d2951efb0b7e86b63ba20a3087fcce3a60b6e653763c7b960583435ee72c43c88486b65c03156421da5f9a1b1779726fa8e7e58b1ce3f7dc886c9e9ab84b5f8db1c8fc1aa7d1f1bfbec3be0082a148f925218d081189614bbd6ec1156e81fc3aa0cc3329815ed81f218e75fd28a142aad2c38a61e682a31bd4dc269d66068359aef3084dec85be5bb56e9dfe4d66e5ad39c2baa28fb37fe87495a5b68a2a4bc98efc32c21b6ccec795e105cc47a8a7507b654252212020598616293d291520a66a54993d6443f94617d5731f515db79c5f9f685531ddb062f8a9d699f3f0d013132c5578aa184937bde2ef65b5cf19a462e6355df7bc0bc115bde055ef32eb0aa2bce99ee3b3441118c373cacd5643cdac3703c5788c931134089287e7fad2f466ead8939d49a8842bb24c66c22859452ea705cec6b31ac99e7c4faed65575ddd9967febefe99b1aabcec721b5c0c1b8a01d6250c0b7be08c1e3f932793744d3fe50a3e35bdc7dee29b5d7d0e7d171cbc117a07d8cdbbb39dec3e97feb67f101156ec98fa544a1009adb134054909c72a612291b0d3af5ab384e33284a1d98375888c73cc25663d8994d2910e314921e93286a5af7490fdcbcbcc6ab5fe7c0b60c56426a58af6c4899745c1ae4bc76695f0e2b7d9da720545fa8126891bb1e55de038efc2d6ae8d58cdc41ae774ebb54d2bb044c19e1586c8a81a2aa5304b88f80a4a5dac34d4176aa08127dc16ce9213e90e99590a396658cc4821782d4f77f37bfa1dcc3bcfecabd377bbac2ea677be150a9899c6e9c526ec5cb6d8dcc76c63f62961ad5bc45fc6ac2e044be9460ceb5a76abd873cd77b2b73c2bfe3a5f323f78cded8dbc55be5fc5fe0d6fc71d69aae3983da6de78126588286acc44a469ec87050726ad3581615164f40ac38920596c8573a0f1a4e4c442148e26dfc6362c2105b39042fc9059c2d855336f12bbf935e980b92a767e6cffb44ce1d55b24c6980c9f8a665ec700f59d2895fdd54da92e2bf0a4621fff10df6fd8bc912be45d6037efcef6ad756537639a8577529a794311f9bb878e133a8ee3b88e52a1d65a6978608dd546837dd1a20e78d55ba9bd005e5a874a09965073488d03258f19d677822d7372ac67c684a7c0dbec9feed23405f957ef9f42ff8b3f66b22a8a288c6da59ade3a8e83b3c4d45c61ec9e5758af66b2a758f9f5942f55ac4abfebf646de2adfaf62ff4eb6b15e36fda7fd83a2f0587481802aca2aa895d28944c20f7c2cbe21262c9a1653d3e551c7015313e8a3ccc42c486b0e43c152221fe8d88bfc6d9eeea6179185ca6f653a7f11b1806a56bdbf5526e9d505b1b266037f90ad4a4da606d1965cf64a760d7f8fed8dbc55de055ef36e6ea76b2926d3addd6c8560785212111c1591835529c4d552cca49589083891dd5e8f3da2b5d6a49426e393a51431c39788f8a2fb5c9a35e78aaf1e2b746ce7cc97b46f3bddc367eea729189ab5079842c692650e598a5edc73ca18ad6cbb55341be8f0a4bf7bccf78a2ff1b7d253b381b8ef3493fa336d6fe4adf297f9107fd55bc834d98f88cf440ba70bff70adb556ca11626c2f775cc7715ca53491a6687d0f8b5069c582c94a5ac1e35584e31b068118ffd68a8560211dc7134262891dcf8c8735adbbfe8803f85b7bd7b43e655f1bab59226d55650c01795ac40c313b2534412218b3665c7e854c57daf7931f6b90bc9199f22e709977793b595704cd0a7f91952530ea5fb379962159514487318762c14a2bc14c7abc4cc5a01ec26d6aad9931c693d68a5809e1388e23a4640e8998344d302c035e97753f1b2fe81ae833f3f2e9df979d43b35087268602fb1c32a8843f6d3b14473e1d530c8b015552c2dfdd61a6ab19d665d631bec40e15abba997b7ef8f646de2a3f6e85ff0d6f4df7222266f36f42c4d8331e17013994410f441f88bcd3c7444c29c944a1407e1d49c4113f0822c061212e82980b110a81e008ae7494c092209b614db3adeb4b0ce3de8a7d575c6befbfe24c3de995cb7ce121c21386f00b6f06be96d0f54fa6e8035fb3de502df647a63fcff0782333e55d6031effef6921a9b38647702ab23902159524aa924454147b5d6639f78624d1a365e2242ec2d0475883cb6c6162e66868f91e3bad20b85109a2c3fac2b1afd5bcfb90e2ac5de73f29d67ecb49f7b494d318f91e8e2374f5a9a84187b9e596c4bc27f3d625804ee656b88362fb36df3b1ad8d98d1807329938abdc275eaea7b9c7c2337f2c3c5ee5f5a73b4337688226b0c314b662d25402d544a39523a8ea3b4c2b0ac9422ad43939682b5104a690096026011d94b76c629765848c7715dc791d2112cf8fb31ac69f6c491724411a845f36e17fba76f72754f36606182ba7014600cfb1197d9dc6aa6c4d896c12f04e1721c072a21b3804a68a702bb42a60b2cac387c28921d00fb8788f922a6aa6ff8d48dfc5965ba8145ed3ad661197b6243b5bd3e848c1f839414455b515a0b5661a849dbf19127728b8d3d4b85701c092241cc9a69c62ce13494c4facc5b65ea96b3cfa1290e15fb1d0308f33b021f61ec82e690adcdd9162bb66c588e637ec06e05457abc73fa56b6158c2c17120394c2f2008e153ef66ac2f27437a74d43124dc1933d9698abec33635f8a6641db0dd8ddc8f525d6ffa61adbc5d1a8411acaa2a4231d476a2d750449da4ac84ae3f64c82c7fef1cc242542e98d670fb556112ff1a490c44cd30ceb6a99799ab6c4a65426a6558c77d8ef8cab62c0647e83a4986052aeeb22471622bbfbbed7eb755dd7c96673c0608a20c636844f297482883ccf1f0e3d66721c1780e5388eeb26714e229148a7d33648cd2ca1b022f331731004bd5eafdbedfabe8f9c66886a1f437f13b2ddfc19839b9841414f46e03659ce449400eeb2cf67eaf6ad5ff0466e64a644ad65627ed0086067cab035c3ce23c7e1ce496b05b72122ad14398e26cd5a692184264dc4911fd6d8639e48488928e72e91204dfc5d3ddd6d5e60f620ad2b11211d03484410f8e85dc96422914830cbc9179b18ea67421802fe8d4623842a26a26eb7dbebf58ac5622291ec743af57aa350c8e572d964326147011491039b85576346a5b5f2bca0dfef0d87a3300c1122d971643a9dc966b328432e9743ee1ffc39add8da438d1e0723a57ebf7f7070f0e6cd9b5eaf877cb1885b6fbfe6f46f9b6d99df766dd888834487c8e871d9c7329fd2be334db2b01bb991eb0bac543465c3327b88b4358d08d22005432d9436b628a595d24a8d014b2bcd24983854a12662020bc34d42a51473201d37910c1c37c1ec3009f13db2e6c4ced75a0741d0ed76910939954a2125d97038ecf5bacc9ccfe7a5445ef80b5ffe1804d83dd630238a921e1291945229351c0e7bbd5e3a9dd65a799ed7e9b45d771c8034a63189282c9fa95fc771847006837ea7d3edf5ba4a294c4020467b32a94c66535c883c1a50a44da40b13e22716f5586bdd6ab5f6f7f76bb59a49226b10cd44f611e3850b8a2c024816cf8a697fd8391c0edbedf6e9e969bbdd4ea5522b2b2be572d966587635dab79d86ad1bb991ef2a5a33458911f4c45c219aa8b66d32686b319e25a5c482426625a56426ad15b3564862a1352b0e958ae613492b224d600c8ee3388e2ba423c6be9162b6a7bbade8d19445c65655b4d6beeff77a3d040b9e9b9b13420441301a0d3b9d0e45b44b6b4c5e6a43850ca05014045958136de8f0308d8b285c3a47c18885a028529530f5a494f27d1f9194813e626cb037f8257d3f68b75b83c12093c964b3996c368777ca66b3c562114a9ce17750fac230b443b09b7ca848a203c33f323c9f9f9f2712890f3ef860737333954ae14293743ab2f15fe49b34908dd7a7082b63b4a8dbedbe7cf9f2e9d3a79d4e6779793997cbcdcdcdc5781945dc2a4aed710197484662dbe66ef0eb46be8b70a412c650421b60a0f12fc016dc11d891525f8cc4269782026009a19522568a34f1d8dd61dc9895224de484a1108474568e94423a2c1dbe225ac35bed23e637fab6943208824ea7138560c74a484208737475cff34d1055a4ea437266d8aa4cd7721c279148241209c0016c72d0dd1c4702a38ceddc7442cff3f068a48c965222d10e380756de1069dff7915e0cd59ac96433990c52049a170163eaf7fba3d108590891245108e179de6834f23c4f0891cbe57cdf775db7dbed2247613e9f2722bcd17038ec743add6e1775954aa50a8542a150d05a0f06836eb7ab94ca66b3f97cbed7ebd5eb75d77591fc35c6160dfe7a9e874c3cb1558a4600d9dd6eb7dfef67329972b9ec79def9f9b9d67a7e7e1e3aef0d5addc88f22d17c574c78a6603f4812c2886aada5d4cc04d77707b38717b95475180aa51c814933c7918ec342289a354b689549ebcb9d0fb435078954cf4110349bcd6eb79b4c261d47168b45645bc07d3c6fd4edf690ea0ac084a38944024c6430180008a4944852afb51e8d46beef673269a896b0f3a1c836ef532a1c0e87e8cf894402e911a594c964322265e31503aeeb2aa5d0ab0783c1d2d252b15824a27abd3e1a8da494b95c2e91489c9e9eeeeded8d46a3f9f9f9a5a52522c2f983c100e0cbcc9d4e075af07038ecf7fbc3e1d0f3bc6fbffd1659577bbdeee1e11132ad2aa5a494d56a15451a0e87c7c7279d4ebb542aadadadb5dbeddddd37d96c666e6e0e086ed6856aad0b85c2bd7bf792c9e4ab57afac150f17ad832cb35a1004676767878787c562d1719ce170b8b3b32384401a6d9a32f3dfc88dbc4d38c6ad386201cc4ce33856765f1c071010e37f0250416383afc38c9c83e03a4c5a2bc55a6b96ac590bc9c45a48d6a4c250313b8ee33a6e423a098470b88a615dfd1eda3212837d8c46a3e170381a8d882891c8673229684f6061380a1f28d0aee17088947f6043beef03b39088d0f094e170e8385247cb2369dc3fc793652883e7f9bd5eafd3e90c06834422e1791e54d16c360b65d0d4329e856bc1c5d2e9341eddebf54cfe1bdc4d0801e84ca7d38d46636f6fafdd6e1b9b773a9d2e954a0b0b0b28702a9524621cedf7fb8d46abdd6e13512e97ebf7fbed76db7164b95c761c474a914ea73ccfebf7fbfbfbfbbeef27126e2693612bf3b3f90408deb8bebede6eb7f15ef64062ab96d8092ae7fbfe9b376fc23094522255e20d54ddc8f792abe60a8dd175d639766f356e3dcc2cb486d1598c199660a53585e468c5a4957268ac57a9c8943236a790cdb0a6ed5657bf875d0e74332871beef73e4f4845ca1264f97d63a954acdcdcdc14e0ffb5722122094e779b95cae5c2e23b73b8dcdd5d2805484e517937f611882fd002ec330741c67301880cd458b04a5310f65329962b198cbe50a8542a954ca64329d4ec78d0467a6d3e9c5c5c562b178efdebdf9f9792965b3d93c3f3f6f369b854201298cc2304ca5928944627979b9d7eb1d1d1de572b9070f1ecccdcd9d9fd70683bee3380b0b0b1b1beb8d46e3f9f3e7806c3c3a93c9f4fbc3376f760f0e0eb3d9f4ddbb774ba5722a9534f30c317b13f450e8ad93c3d9c56712422493c9b5b5b59595959d9d9d172f5eb8ae7bfffe7d40aa6d25bc911bf981725943422f8de9401ccd15820d1091521aee0b5a6b311e80496bc5d1621dadc2502821dc4422e13ae895524ac78931a9eb00d6f42518c96184461e79c791c6e20b81e5c5719c4c26034392e77948b868accee9743a170933839dd90533c5030ca207f67afd7abd1686e1c2c202a81c59a91cedb9423d8ebb2af3f9fcfcfc3cd08a887abd1e5b0161b4d6aeeb160a85f9f9f9c5c5c5743a4d44502499797575b5542a8d46a34ea7834c21994c269bcd4a2932990cd041ebd3e170c04ca552b1549a83d51f4631664ea5d2440a9caedd6e26934e2e97cd663350365594a7db08aa02463ab65cc360b4c29b1ac31f337b9ee7795ea7d3817a0beb153cda6ee4467e1499692c224218f771379d1e59cd564ad6fac2e9215a57a888484a45046f21867bb71042477cedc2abd3fcd093165f9a34c0eb49076bfb108df3bfbb7a9c45c34ce15fdcdff43133bb6fb445b85c160a85743a6d000eb88b1f3c95ce0b6c6830e8b7dbed62b1b8b9b9994824eaf57abbdd06961b8dc97864595516add08cb430f350fb4fdff70d6025128942a170fffefda5a5a54ea7f3e6cd9b66b3198e0549547dcf1bb9aeabb522d24a859ee711a9e1708884afcce370b1f57a7d67e775bd5e03476b369b52ca64326d9068dac5548f538487608ed00d47a351bd5e87720d7db3d3e9ecefef9f9e9e160a854c2603737eb15804ccdd288637f2238aeda535e60434de853dc69760da11474769be0cba457b801e210b25a5ebb80e8ffd4e899035e7adc59a0958060ee0cb0e3d339148c081426b85611f36a3643289d5d84a29cc240a21e0b2944824a0098219a1df1b6313e6fbd2e9542a950c82b4effb994c269d4e673219989652a9542e979f9b9b83b727d4a25c2e974c26cd0944944c26a574b2d96cb15808430563793299c4ac5c369b1d0e8778974c26834bf0dbac58ac56abf7efdfb77dee4ba552a150989b9b43518bc5622e97751cc1cce572653018b4dbed5eafb3bbbbd3ebf53399f4fc7c65616121994c8c46c36eb7abb55a5aaae6f30521b8d7eb3a8eb3b292832fbe94177eb64aa976bbdd6c368159ad560bb809b33aec7166dd621886a3d1683018140a85adad2d66eef57aed763b9fcfc3b8a6ffbe3db34c1bbed9fe485b53b111d19952bf629f604c8374dc2bc2e83732caee4e963310d1d898e6c4c65b9bc599e75d31261b1f4b702be37e897981442241c489443291480821b5264cf603ad60ca91520e8743d775316d5fafd731a5954e675c3791c964138964269386e70111c1c32097cb856108909a9fafb8aed3e9744e4e4e7cdf9752c24a552c161389849921c4e463a934a7b50696251209d40ed00d3638b8929b12269349bce9eaea6ab1583c3e3eded9d969b7dbc96472797979737313fc2b9d4e2f2d5573b92c10a450286a1d4a294f4f4fcfcfcf85907373736b6b6b95ca4218facd663308fca5a5a552692e9dce361ab58383835eaf37b386fbfdfecececed1d11100ebfcfc7c30182c2c2c388e83170421cd64325aeb7ebf1f8661a552c966b3954aa5d7eb1d1c1c044160afc4b647b9bf37f9cfeede7fb35b661bb03491ad1b5e3436034f7afc5b30c7fda8b5d62c380c5da1949b4824129e741c33ef782d8635fdd54d41e14205c31054a368d24a6badc3102912c7e12330f80353a094816a8d46a3d1681404018c2fa3d1d0f77df8408561a035691dc263d32ca603236bb55a98ec0b82a0dfef371a0dcff360230318799e17e1a92384c48398b9d56a8d46a376bb0dfc86412d0802d7753195098311260de00901aad5eff70f0f0fcfcfcfb3d92c542d6044ad56d35a0f87dee1e191eb26a5948341afdfefb75aad76bb934c26d3e974afd7673e83d3561886a552299d1e85a16eb5daed76bbdbeda552e96432c551ca6f8069ad563b3838e8743aa04870ad80f51d8fee76bba83722c2b700b16db7db7004c37b55ab55cc997ed7cf7d2337f23601271a372d87c230089928108190e3d5fe760c86c8313304442845411068d28e74945241106aada49061180ae93a08b7ec8009719c615d7ff88566014f454ccc092b322745b3a14288e17000139ab16a69ad7bbdde7038344ba30d95d35a8f469ed6ed5eaf27251c3da4e308c771f1e69d4ea7d168a00c4208383ac1bd1eb8a994eaf57a6118d6ebf56432e938aeeb3acc324252168263a5350bca6d7b3645fcd14cdb31f3703804b393529e9f9ff7fb7d8a0c7348557476764ee3b54461100483c180883c2f383d3d6b365b98390d8240297d7676ee382ec071341a6a4ded761be106b5e53202e2a9b5c61c02e0acd96cf67abdfdfd7d8c19666e11d5689cce300600da9452dbdbdb3706ac1bf9f30b5a9f43cc52484de3c413642561d59a840060e1b724d28284520a0b09b5d601872ca4108eeb241c272184a3f59536acabc1cb1c42278f0ddd30701b9ac7cc440cdf741373cad895010ad80f5ac1cc441abe6772569a7840898e961fbaae0b87f568390e6166addfeffb7e001e6a664699391652da9e7ad36625c284ff8800db322b72b4d6707450e3d08870915761a822cf0372c6816c9c300c1a8d26263d4dc983200c82b10b08f6d46a3ea0475bb1386095a3285403101913ac36caeb68ed373e0d4acb7ce1178613cc0482984ce9fa3db6dfa7255bf2431e7db37d07b6e60b92525a88719405221586aadfeffbfe280c9594528d27a0e0c5ae89488521b1cdb6380843ad74180466319cef7bcc2293cd1311b3241230e74fc47e31625aa4d99afda60fe34f587cd80aadc7511450844b90510c2922b6f3fd198f0cc08d0d433476301bafad336cc8801ab4bce84c812e0d7338ce49a552cc5cafd74f4f6fbab8eb00002000494441544f3b9d0ee81100cb94d0bca60141c69cc7644e6db3352b0da337e244c235a0690387f92da5c4a222213482d81834d7634d33813d8ee32875e1a512d51899a31439a93b8e63b2e60a6b35626c0f962b9a673173a3d1188d4642c419dc0d60dd6cafdcaae8776c84c314bf86f5ca62009ab41e7923683c2c0ca84da6a1270a952226a534690ec3502badc2508f214c8d46a34422595d5e553aa18943a5b42629653ce2e8f51b1cf42f63c6b7bbbd0d5886bf00b00c30199e65ab66420813f2c5286e267c82fd1b80853d98a4b38fc28d4b29d56c34f2f9fcdc5c39914c62fa5544e11fc6dd9b594673137a32cb233abcf111d7b01046356eee63be22c4304a13ac1a472dde34fec61c0d15c6d5c00682181819366afb61003a6d948c2182edb111a9a2ea1a6df406b06eb666cb570016731cb0b04d32bbae5263b053ccc83318651e344d9a3542cb840a0c2b84dd3e08422c3d1e8d3c1d41871492ed98eea6651b618b62cc3c8a1fa657447d55440df2a22f453d9c8d2f951db14044796eb4d64a85426822a1f5445f05adc00d71ade97b3409b5a684bd5eafd3ed168bc5dbb76f974a73d0a122c513ecef221cd8146019b55418c092425a03cef82b1269c1acb4e6492f27738e813f1545803077889d696fedab708e980ce4609f4f53fc0ea7d95008df2efd8381e6af57de81ceffd7b80d27016b8625c14e1ea12d6b8652e3d80c8c3d3382202392f83835a1ef799a4808e179dec1fefe79ade638ce28d442c86432e5ba0942e6e7ab3fb3e9ff340bce4cf7b37a0b8ddd2c481946030314f29e1285f0e5e671ac9cb19d98483253180aa52e62e64d774b63a2b26de1420858f98510c4040b0ee6fe1cd7ad54ca95cac26834c2641fb370a444b86800a8d624a58db637722337f297104c5501b046238f99306bef7b9ee7fb8ac428d43c8e6727b4c9fccc93da840d4c3465c3b231cee0085b0901ad83e02ff6aaa278faace83ce31a2ba33fd9b65e494ba0875a7f463fa244128eeb9026d775a51b45981a27f0508690e9508544449a991591528298a5233491e071c621524a888866ead901356ee4466ee47b481446c60096566acce6a2552e885b3ad63a356962ba56c4d1eb9c6378168d118d2df5c5062ca3fadaa2271736db012bc65028ac2581c67c1eedc77f621cd7420a21258216bad2115aabc00f7c2f0cbd4069160e9320ad482992cc8212ae2b1d291d27503a503a08432185c3c261222948eb300c852015861a515ca5c0b0a0b566965a1393d05a0bc9318b154daa72364f9c7926ea6bfafcd8b57a5231b4af9d3ee7fb89fde83fc7f9dfef92d8e5748d25fab6f0258acfd547afbfa5597680bfaeedace9e3ebab84585233d1b0cd39c68c6314c6289caf26a2300c7414b589997ddf079d905248492c98b4d23a24d2cef4e7b759d5cc16664ec31e9ea25da685442bb7a16a4d7c548a61d2e4da6e1b9e0c30194a15ff13ff8410868b098788043b92d86176a5741da1b424458eeb3209c963733b0b12d2c582cb51c8c39137f27d29643a99c8a584d4a415133123bf072186225b944b68c5516e486671e11261fad2cc9601f94e3dc7549da970fb3ed39df3fa3d3926a6315c7d93d843edf3636862dfd046d8e94ba6cb7f35f2cebc035f82dab14a86180bacddb6635b73265b13af6fbdcfcc4ffc0e6e6d43a7a94f7191e106614ed44ca88a1ae15b1ab67d7fbb6bd3c56c12e064ec9a639c9f8999483369e6717e44e7ad6de23289219a29d62c61ba089413c7c1d887b765fa90fdb6d19e71c030962c25144ec9b09791c3da11ec087684902c42224d3c5e3dc05268e18cc2f0bcd1abb7fab5d6a0deec7607032f08849009d7cda7d373f9e47c295b2ea60ab954c215723c6b6bbf94fd5e335e4a477279e5c4cf7feb69769fa71f864d6f7dca777a440ca72e3be7ad778bb5abef5486eb4b6cf8bc11baaa927f9c2a9abe7f34f08f7bb7cd4e983954caf783701c3880180c8ba7c6286d094d76bc580fb4cfb97699df72e6346cc55e4644f950c7bea0500891b4794cb71cad05b3a3d9d19c10c265e11229d23e5148a41539249c7ea84feabde7af8fbf79b2fbe2d571add1f642c58235731004a984b3b132f7d30f361fdc59beb53a5fca65d2aea3490b476860249441529ab4d20a63004f2694358bf884f8d1ccf9f627608b0bcc748ff821f737771656202d7d89924bd168292c9f7b7be089ddd634aa2b9e6ef6e08719b1cc21fb3ec619edb206166ba866ded9f2559e5112fb41663f141cf374730256237cf74ef19f29b12181232b92f1ddc1c11ff814bbaeec9d684193de0217d9d7078351bfdf1f0e47a66d5fb5b2ec326a308d6b44b308c695e527109d4b5eecfa02f395955b9ec7767d6266d62c340bcd0e91431c3005a435b3d6ac875e78dcec3f7a71f0c5c357df3c7e7d7ed64ab8b250caa753493f08ba5dafd56a0ffb2d87472937cce7d26e324d921c21124232696256143229962458489a709b325fdac6a91f022276fdc41615e871ba911f6d0c9c5e6f18fbca3632da17c295f732e709f3c968120b620fc2879c59b6cbae22228c5e579f639784c62bf327e49ac9baed12c61e67627bd0540eca7750aea84c8a7c0c8dcaf66391ac99629a931130acd168d4e974fbfdfe78e586012cbb31d92f630fe6b1df3435805c0670d3859b6ce833404acc92c87a159b3414d19a1b21a4142ca460218849b3d42cb516a49988856029846041523a81929ddee8f5ded9970fbffdf2e1abf35a73b15cbc7f6ffdfdf7d62a73b9d170747ad6383f6fb4eaa7c2ef779bf57eb737c8674905a9849348482148930e490926c144742df664c62e6139a67e2789559d11fb635d760e4d510cbbbdda3822a58c5d687f7d9a34a59943a60f33732cac98fd44f320fba1e6e8e4a83e5b620dd2dc64ba35cebcca943976fe15383b5d45339fa5a35cc2330fc5f6986630f3edf4a4db5d6cfff43b5effcc997f5254f9b157b007981f65449ceee9647d0ebbfb03b0bcd1a8d3e974fb3dcf574a2b7d35c3bae20ddf3a88cd2ce59525bf96804cc9896ccc82590a96928564c14ccc1ada1a8b903964116aa1496a129ad558ad500175bac3c3c3fab7af4ff6f66ba1d6b7b6f21b1bcb0fee6dae568b52abc160d4eb0e8e8f0e7aed463193ccea40371b9e209149055c7052499202162ccf1bfa5e27f043299c64329d4c267ddfc73a1884b2eaf7fbc562716363034b1ded464057da7a696a4860e6300c3b9d4ebbdd0e8200015a91bc36d6556662530c0b620d5a5b49611b8d46b7db1542a452290420c35a02c362c8022654a9effb9d4e476b8d983cd3706012ee6295024faa845aeb28929a461246ad359eeb795eb3d914422c2e2e22c5997959d339ebf5fad9d999941299d0cca1e937c5a1c160b0b7b7d76ab592c964a9544a4722ad1c97f63c17457824a5ec76bba7a7a7beef178bc572b96cc85d1886e7e7e7bd5e4f0891cfe7b1b8554e8636a359a979ed61607ab480fa69ef37f56fca867baa71c4ce89330d16d87d16e78351da84512935180c4e4e4e46a351a9545a5c5c346b39e8c796992ddc1c421f47b285e1701804027ecf17b384d31864b709b21ac7d52f609f7fc569531076b1d3a0ac2156d6fca0f166c06f2925d6070a3106acf19269621282586816242409a959842414c3873e54be17faa3500544e4845a7786eaf0bcb3b37fae7cbf9c4f6733c9ca5a716b7581873ddd6e70b3e51feda93008e68a7eb8c60b65994a4be992a64eabf5666fbf596f2693e9cdcdadd5d5b5d168b4bbbb7b7e7e3e1c0e9f3c79b2bfbfffe0c183fff5bffe57a552b13fbfb65439bbd2666e4d7dfabebfb7b7f7e8d1a3f3f3f372b97cefdebd0f3ef8209bcdb2c51ab4c5e3629fe6b2ca375f76381cbe7efdfaebafbfdedbdb43ffbf7dfbf6fafa7ab95c36a1c1cc53b04e15ee72dd6ef79b6fbe514a218a7ceccb0641805068fd7e3f954a21a199fd8e4681eaf7fb5f7ef9e593274f88687979b952a9b45aad172f5e2493c97ffaa77f42e8d458d3524aedededfdf6b7bf1542fccffff93fefdcb943916b4f0cc7cdb47aabd5fadffffb7f3f7af4686161e1c18307ababab2b2b2b4b4b4b5808115b0e65b77fa5d4f1f1f1bffffbbf773a9d8f3ffe389fcf9bdeeefbfeb367cf767676b2d9ecf6f6f6e6e6a6a931bb922fabfc69b8b16b26064366617ccc6e187b6573e6340e9a2667174608d1ebf5befaeaaba3a3a3bb77effeea57bf2a954a7409acfc703155318b9a0866565af9be1f0681d6aed65a297d2d86757d3e15eb69b6cc2aee3589d6b407969492f18f59826109169225b3162c84604d22ba303264094dac91b794346552eee25c616da9727cda3e69f64eeb9d878fdf9c9ed4972bb9a54a7ebe925bad56b6d7166f15f26ea7d97ef3bafee86b7f34a4ad0d9572a998a7444aba92886a678daffee3e1b7af5e178b45ad6971b14a44ed76fbf8f8b8d7eb3d79f2e4f9f3e726ed581004c8bb83488168672688580ca1660a488de7793b3b3bcf9e3df33c6f7373339bcd82e06005782a9532eba5a7ea7c6c1d47481cd39a1164b5d56a3d79f2647777b7d7eb2162e2703844f82d941611cd8cd72e88125e0179864c163284edd75a9b8088a3d1e8e8e8687f7f1f71f497979765945612c312c237eeeded1d1d1d214010f236d6ebf5e7cf9f2793c99ffce42718ac103d8d88103c8399dbedf6d3a74f8320f8e8a38f363636d093513ca514ce07cbcbe7f380bc9d9d9d2fbffc727d7dbd5028a452a952a964dbb0b05416ad2e0abfc14aa97ebf7f7272b2b3b3e379defbefbf8f5cbfb873ad567bfdfaf5cb972f171616e6e7e791a1ce44d0c5fa7c7c5f934d8aa2ac4886bd220e8799d737d939519f61182264a3b915ae3281dbf01ba95810e9d79c69abdbf88d430882e4791e02f0422d78f3e64d3299bc73e70e02f39adefd6745ae69211a2f9a612246b48699d7db8863ee388d3e31c2751d6ec5934a0af6e13f8b3a5db82fd85e5616e1ba6058639316c30fcb61d65248211c4d82590a92820413091282055633a9306096e562667b73b1d6ea375add80c2f6c87b7370727870924b278ad964c2150ba5f4671fddfeffeeadac9ced0dfedfff1bfcfef320f044ff53f1c1078e7050ecd00f4e4fce9f3f7df9cd37dfcc95e7565656efdd7b1f8a009a3280c92048b3d9dcdfdf771ca7542a55ab55d77511d1d06e55a62a8c4dc1401b7acefafaba10e2f4f4f477bffb5d3e9f072eb45aadbdbd3d2242ee0c93d51101e0813e085e88a8d0fd7e1f41b5882897cbadadad398e737474f47fffefff1d0c069f7df6d9d6d656a7d3f13caf582c82c1415968369bc964129928f3f93c900e9102a13c32336e8e80f788228d3c468787878f1e3d42646764db16568aa0838383dffffef7f57a7d6565e5d6ad5b83c1209bcd56ab55a5140a00a0f17dbf5eafb75a2d224232112c862722e42e3a3b3b43e5838e217c58b3d944456d6c6c20f83dfa27827a0b21100a9199f1468823664019251c8d46070707c7c7c78944a25aad2e2d2d217a4fb3d91c8d46fbfbfb676767888086e7b65aad56abd5ed761389c4fcfc7ca5521142743a1d84e14737c9e7f3954a050fd55a9f9f9fd7eb75c45c439c7e68b8f57afdf0f070381c96cbe58d8d8d743a8d549e08ca88308da552c9719c66b3099d6e6e6e6e65650579307bbd9ec9d70948d25a974a2550e3e3e3e34ea753281496969692c9e4fafa3a4ab8bbbb9b4aa5565656be33025d29a84f1b5bcc4e21044f2e86c161d016212e012cc834698c61d64cea64beeeccbb69cbba46d144b5e3b8d0eb233e65ff93f807619663a395055852bad24d201536912676981d22c1ec323b4c8ed00e6b21c8651d6a52611010a95c36b37d6b5ea6dc6c21b9feb2f2e6b85eabb7baddc1c8d7e76daf566fbae12839f4de272fdb3af0bfddf177df084738c3917493229154420efb83b3da79bbddc9e5f24b4b2b996c3a0882d3d3d35c2e2784c8643218cf8bc5a2ebbaad568b995fbc78b1b3b3e3ba6eb95c469c65740c201a4756210016b4f75c2e8766c7cce062737373f97cfef1e3c7fffaafff0ab39110a2dfef239069bbdd6eb7dbb95c0e9c05119357565646a3d1cb972f3dcf43ac67dff77bbd1e022ea752292965a55269369b886e7af7ee5da875e572797d7ddd75dd939393bdbdbdd3d3530cc5b95c0ea1991118369fcfb75aadb3b3b3643299c964c035f067b95c2e168bf97c1efd647f7f1fbd6e696909792189c8f3bc46a3f1ead5abbdbdbd4422b1bdbdfde0c103930ac8719cafbefaaadd6ee30eb55aedcd9b379d4e87883299ccfafa7ab55a45bbeaf57a6fdebc79fefc3938e3fafa7aa55201c6351a0d0001ee091041547e547ea3d138393929954a1f7cf041a150e876bb4747479ee70170a1190d0683c78f1fbf7efd7a7171f1c30f3f5c5959190e874747478787879ee701cbfafd3e47993af15e676767784784aefdfaebafbffdf65b2401504a150a858d8d8df9f9f9300c91fbb25eaf8361a1fe373636b2d9ecc9c9c9f1f13112d929a572b95cb3d96c341a61188204e57239703a1463381ccecfcf13513e9f7ff5ea55a3d1d8dadaba77ef1e11f9befffcf9f35aadb6b6b6b6baba7a7e7e8e742ac0bb6ab57af7ee5d22fad39ffef4e8d1a36c360bc0ba4c4ffae1c2976885460ce28818c38a615e8c46c6143d7b8f7181b18dca34a5ddd8fc6b12b38c5782b0c4b252492984238473f951492c888466c5ecb07058b36029c811ec4a912062d62e53c83a0c425f695f38c3743679e7cefcfc52f1fd7babfb47b57aaddeecf44f1bde9b83dea3a7bbbdb3d3701872df53dddeb0df538e935b98cf2caf8ab9794aa598f974efe09b674fdbedf6071f7cf0debdf790b61e8312f8b979df7abdfee4c9935c2ef7f2e5cb5aad964ea7cfcece903710ac04019731cea353a10bb55a2dd87140cb8d8a07fa002331aab1dfef63f6f7e4e4a4dbeda6d3e9858505b0fdbb77efaeacac74bbdd870f1fb6dbed5ffce217dbdbdbc81bd6eff7d1b8fbfdfef6f6b6d67a6969a9d56afdee77bf7bf8f061a552f9ecb3cfde7befbdd168f41ffff11f8f1e3d725db752a9007fc330dcddddddd9d9595a5afa2fffe5bf789ef7c5175f789ed7ebf552a9d4a3478f1a8dc6eaea6abbdd1e0c06a552697d7d1d7a68b3d93c3d3dadd7eb4b4b4b00ac76bbfdcd37dfececec944aa5adadadb5b535a42cc3cbe6f3796646e2b2fdfdfda74f9fbe79f306880005edc30f3fec743abd5eafd56ad56ab59d9d9d7ebf9f48240683c1f6f6762e97433d20422c329e188e865a0d82e0f0f0f0f9f3e7737373d56ab55028b45aada74f9f76bbdd959595bb77ef02b0fafdfe1ffff8c7c3c3c3bb77efdebb772f93c940af3c383848a7d3fd7efffcfc1cc1bb75943c180349bbdd462ab96eb7fbcffffccf4f9e3c79efbdf7eedfbf3f1a8d8071c562b1d96cd6eb75e01d11c1b42f84d8dada5a5f5f0fc370301828a5cecece40a03a9dcef9f9f9c9c9493e9ffff4d34f6fdfbebdb7b7b7b7b78728b8189000d67ff8c31fbaddeefff81fffe3bdf7de434d7ef5d5570f1f3ebc7bf7ee279f7ce2fbfed1d111d874a150585c5c842def8b2fbe78f6ecd9cacaca2f7ff94bfa7302564cc696a20b2f0ad651bc04a6ebd9b06896e99d26edc1c60d2f162ed99c66235454326666e8f9ae9bc864d2264533f385ad7d4c06a70cf0c6104fa4431d382ca5145a081684c7122bcd8a78bc6899995933691624c230acd7db83f3aecfae70d3857cea416e99b72bdd8177783e7cf2b2deeaf4f6bbada4942929943feaf4bb9c4aa4363633eb1b2297d5523251bdd97cf6e2c5a0d7dbdcdcc866b3dd6e1721038bc5e2c2c2827166711ca75eaf3f7dfab452a98461b8b6b6964ea78f8f8f9f3c7932180c5657576fddba2584a8d7ebc7c7c7b55a4d08b1b2b2b2b6b6d66ab5f6f7f7c94a29a8a33038cc0ca4431aede170b8b7b7b7b3b31304015aede6e6e67ffdafff5529f5f4e9d3c160b0b9b9797e7efefaf56b2889503d7676760e0f0f5fbf7edd6834d0379696967ef18b5f20d706e62251aaa3a3a33ffce10f4747473ffff9cf57575799b9dd6ee341e7e7e7cbcbcbd96c566b7d7272727e7ebeb6b6562e97fbfd7e3a9d5e5f5fd75abf7af5eaf8f8d844c1377379662c1c0c06bbbbbbb55aedce9d3bdbdbdb894402396b3dcf63e6d3d353f4f6c160707474b4bbbbdbed76efddbbe7baeee3c78f777777f13870cfb5b5b5f9f9f9376fde20167e3a9d2e140acd66737777f7c58b17cd66f3f8f81851f0010d688de03e40b446a3512c161f3e7cf8f0e1c36ab56a1241e1439c9c9cd4ebf55c2e97cfe789e8f4f4f4d5ab57ed761b09776bb55aad56735d370802703a58b54e4e4e161717c1b95ebe7c797070f0e0c1836ab53a1c0e01406fdebc79f3e68deffb5b5b5b5b5b5bcc7c7474f4ead5abc3c3c3939393a3a32328f2a61900be818385420109285fbe7cf9cd37dfacadadbdfffefb888e8d9bfce10f7f482693bffef5afcd3ccce9e9e9f3e7cf89a85c2e0f87c3d3d3537c1a8c88c964727171310cc3939313642f37cfbd36ec7c1f89f061826d8dcd576324b9865b83be64cac91c856052c67c7ec411a6295625a288973af213e9f57a83c12097cb65326913e2dd38b71ba882c268f8158f9d3504338fbc810a5532954ca60aaee330130ba58948069a479a46c43e1109d6acb5565a0ad7d3faf4b4f674e778efb4a39cf4ea52f9ce5665b19c4938329796730551cca89aabd2094ea544180cdaed862b58ae54938bf346dfed0d0647c727a747c7cd562b9d4a0d06837ebf2ba58339350462851104b6956c36bbb9b979fffefd4422f1f0e1c32fbef8e2ecec6c7e7e1eb9c84e4f4f1f3f7efcf2e5cb743afdb39ffd0cf61171b1a46bc6d7e5c8cb4108f1e2c58ba74f9f2aa59e3f7ffeedb7df168bc55bb76e8561f8f9e79f3f7af468636303337a0b0b0b4b4b4bccfcfaf5ebafbefa0aea003aeae6e6e6e6e6e6471f7df4fefbef0f06837abd7e7474a4b5fee31ffff8f4e9d367cf9ecdcfcf7ff8e187502bf6f7f78f8e8ecae5f29d3b773efbecb37bf7eeedeeeee672b946a3a1b54ea7d39877fb877ff8875aadf6f4e953804e2e975b5858585b5bfbf9cf7fbeb5b5057a45939e38700ed8ddddfdf2cb2ff7f6f6304a351a0d28389d4e270882c5c5c54f3ef924994c369bcdc3c34358703299ccfcfcfc2f7ff9cb5bb76eb9ae0bfdf7f4f4f4f8f8f8f4f4f4c58b172f5fbe0488241289542a65ccead0dfabd5eafafabaeffbb022fddbbffd5ba3d1f8f4d34f1f3c78804cb414c5f877acf4c383c160341a65b3d9fbf7ef039d9f3f7f0ec362ad56c328f2faf5eba3a3a35aadb6b0b080bc76ababab1f7ffcf1a79f7eea79dea3478f0e0f0ff7f6f69e3d7b363737f7d9679f81d1eceded1d1e1e1e1e1e9e9d9dc11480842fe9747a7979195597cbe53efcf0c35ffffad7b76fdf0e82e0fcfcfcf4f4f4a73ffde9af7ef52be0efef7ffffbdddddd56abb5b5b50533199c243033934aa5c2303c3b3b3b383858585840aa14331144519ccbb742c4f7135bcdb2774e78a86acd4c524a87c7be233f34870aa00a9d81a2e955300268f2e875a664c68c25a228c9a3d1a8d7eb61103315c4ac89709ac9786ad6e28c83d8f0386c31f507bd6ea793cb67f3f97494ab426bd69a15997f44447a6cbe6347e970300c8e8eea5f3fdd3b6ffbf3f3b99dedc595c5a220a7371c9dd53bc1a83d3f975a2c67132e0d42af2d285d2eeacd75b1b4488e435a2ba55bedd6f1e1e1f9e95926934ea7d230be76bb3d6686d509997ea023a0a7158bc5f5f57522cae7f383c14008b1bebe5e2c16cfcfcfcfcfcf53a9d4c6c60674c9c3c343d7751717173736366c9f6c587640f5c330047728168b483e582c166bb5dab367cf7cdf87a9ebbdf7de7bf4e8d1575f7d0503f6fbefbf5fa9544e4f4fa19c96cb65210466b290a802508b073d7cf8f0f5ebd738f9ecec6c797979696909b6ad4ea7c3ccb95ceedebd7b3ffde94fd3e974ad56c37883fe3f3f3fbfbebebeb2b2028e897c4548d1562e979797970b850245e3592693d9dcdc544ad56ab5172f5e54ab55348ff3f3f3fdfd7dcff32a95cafcfc3c942cad35ec7aa9540a730b9ee761bcc4fec5c5c54aa5b2bfbf2fa5acd56ae8b1a954eace9d3b27272722cad2d4ebf5906d0835b9b0b0f08b5ffce2ecec0c8cb2d3e96c6e6edebb77af52a998721ac0328d1f29d48077cbcbcb8b8b8b985469b7dbcf9e3d3b3a3a4aa552b76edd9291df36fa052c838b8b8b44747878787070006e9e4aa5a094119152aa5aada652a9939313c77196979701d93060a15de572b9ededed9ffffce78944021e7fbd5e0f85416f824d1346527437a426514a611ee0f6eddb302f0e0683e3e3e352a9049399c1b5697f883fab5ca85f748167621ca780355f8f61d9f672fb37450e81c0634c8a7194421d1006c0a28b90378a88709aa10f863a59f7545afb71dd2f9a290b82406be9385841aeba9ddef1c9497154a854e653e934c898261224981d668709958ea942a142a549a7d3c972b9509ecbd63a677b0787e7b5d37c3ae9b2e3f923cff3dd446a7b63f1d65241f8835ee0f9f395d4ca32ddb9cd2b2b3a9b25a23008da8d46bbd148a5120f1edcfff0a38fdaade6ef7ef7bb2fbef8e2e4e464381ca2ae4cea33d403727c158b45984bd7d6d67ef6b39ff9befff8f1e3e170f88b5ffce2f6eddbbeef7ff3cd37cf9f3f2f168bfff44ffff4e1871fc2bc8d1b0256608948a552989cf23caf542addbd7bf7f6eddb737373e7e7e752ca6eb7bbbcbcfcdffffb7f877f50b158fcf5af7ffdf1c71f4b290f0e0ec059fef11fff5129f5fbdfff1e2e94205640b1e3e3e346a38184697083845518ada2d3e9409747e74fa7d3b00d61b61ed3ffb55a0d76194c83a2f5e350a3d100d1c3dd72b9dcfdfbf7c330fcf2cb2f315df5c1071f40b9fb977ff917786f70e44c884a00bec34c6310bcd96c9e9d9d954a254c50a6d3e956abb5bbbbcbcc9f7cf2c9ddbb77777777f7f6f6e08200ec03a7ebf7fbcbcbcb1f7ef8e1ebd7af7ffbdbdfeeededbdfffefbfff88fffb8b6b64696df0933c3dbc0e80d28128ceb8542018ea3954a05da6bbfdfffe4934fb6b7b79f3f7fbeb7b797cfe7a14f90a5e69be475704180310e4ab1e779786ea150f8e94f7ffac9279fa4d3e9d3d3d3dddddd972f5fc2a30d8e26186352a994ebbafd7edff3bc442201b69bcd660b8502b2ffa26e611bc5ace2871f7ee8384ea150f8ddef7ef7e4c913c771de7befbd4aa582c9e5bf1860e949bf02db8405eb0eea9bafc9b0f4950204a1081d0146c6cd842250b3393fbeb471023281e18174c60a86cb8d1101ae28f06a1142a652c9d168a435359bed66a3ed07c179a5e6ba4e2e9797526aa5594b418e200793a19ae1f0c39ab47438974bad2d57067e90caa48ece5bfdbe474424a5a3742ae3aead543fda5abd9de644e36024c4c2addbd9db5beeca8a2e162899269f555f00002000494441542222ad54d2751717e6cb95f2cf7ef6d39ffce4e36eb703350ab9a331eb5f2814cae572a954fac94f7e52a954eaf5fae79f7f9ecfe78f8f8f6fddbaf5939ffce4bdf7defbf6db6f07830134c1fbf7ef1351bfdf7ff6ec99d67a656505233c807e3018bc79f306be08f57a7d6b6b2b91482c2c2ca4d369ccc4c16f7b7d7dbd542a799e27a5bc73e7cedededeebd7afa5941b1b1bd56ab5d3e94829e7e7e7e1c51e86e1dcdc5c3a9d8639e34f7ffa531886524aa453cb64321b1b1b8542a150280441f0ead52b7c91fdfd7dd7754ba59294b2dfefc37f726e6eaedfef2793c96eb7bbbfbf7f7c7c8c6e99c964de7befbdcdcd4df443f84c4929d7d6d6e093e5baeed2d252afd73b393969b55aa01b989fba73e74e1004e065954a259148a04bfff18f7fc4747eb55ac594423a9daed7eb5f7df555a3d1003fad56abc562f1e8e868381ca272b2d96ca9544265b65aad4c2653a954f2f93c9ca10a85423a9d4666f2fbf7effffce73f9751864accd22612898d8d0d30c1e3e3e37c3e5fad563737376bb51a2c53cf9e3deb76bb52ca42a18052150a054ce1a11998590b22828a07a85a5d5d9d9b9bc35ce1e3c78f93c9e4cb972f7777773dcffbe0830f3efef8e3dbb76f0397b3d9ecf2f2b2edfedeebf5b2d9ac10e2c1830744e479dee79f7f0e3d3a9fcfffe637bf69369bf97c7e341a7df5d557f3f3f33b3b3bbeef572a9542a180fe0b42809109a0f9faf56b66c6f4e5048efc7964face96c2c826292bbf9561d9a0c393ae5810b28c29b0f3b9ae6bbcddb01d8d469ee701a4a08ac3ee0bc7b668ec123049a2b9c09509aa0a6ad3712492bf232d2854866432c92cdaed8eef05fdcea0765ecb66d3d96c4e3aae0ed4ffcfde9b3ed9711cf7a29955bd9f7d9d7d0683c13604082ea028db9772f8fa85dfbb9fec7fd79f1c8eb0ec906449a44c900406fb36eb99397b9fdeaaf27dc8ee9e9e0d044052d2955081689cc9d35da7bbbaea57bfcccaca14808240008a4ccd4441c21080c25686e7989d465948b9b4383f09549810029886a4383228e9366b6b55af72b00dbbbeb09cc6fa65f7ca9552a3059605a6442010b0b8b4f0f9e73f6b341beb972f974a9ee3d8376fde9acd6688b8bcbccc7eedb3d9acd1685cba74e9ce9d3b6118fef6b7bffdeaabaf0cc368341a7ffff77fffc9279fd46a35cff3ae5cb9522a95f2ceb1b8b878fdfa755e502fbe51364e3f78f08051e6f3cf3fe75530868067cf9e3d7ffe7c6767a756ab5dba7429b7bccccfcf5fbd7ad5711caecd75dd8d8d0d00d8ddddbd77efded1d1d1603058595961ca73efdebdeded6d9eed1dc7999f9f67efc10f3ef8e0fefdfbcf9f3f67a6502e97bbdd6ea5526115520851ad566fddbad56eb7ebf53a430f2b29ababab6c48ded8d8e0b9eafefdfbaf5ebd628060c0e2e1b7bcbcfc8ffff88faf5ebdba7bf7eebffeebbf72f7e8743a6ca75f5b5b5b5f5fe78c905b5b5b8f1e3d621d707373f3dab56bfd7e7f6363e3bbefbe7bfcf831bb2cacacacacaeae96cbe5b9b9b9478f1ef57a3dfeaa52a92c2f2fcfcdcd351a8df1785cafd7979797d9f37e381c0e0603cbb258f3955914877c38954a25a6393b3b3bbffad5af7ef6b39fadafaf6badbffefaebdddddde170d8ebf55aad56a3d1585f5fef743acc641f3f7ecc90b1b6b6d6ed7659236b369b8c38f57abdd3e9b09f47a9547afefcf9ddbb77a594070707cf9f3f374df39ffee99f3efffcf3c78f1fffdbbffddb6432595e5ebe7dfbf6c6c6c6f2f272afd79b9b9b637b96e3385f7cf1c5eaeaeafdfbf77ffdeb5f737af09b376ffec33ffc039b26fef0873ffcea57bf222206cde5e5e56ab5bab5b5c50e2bd56af5f6eddb3ffbd9cf9acde6d6d6d6975f7e695916537eb8c0def4a394bcda62fd39c362f429ec93fcc136ac1ce673bd8fbd1379ca6266c42b324cdd4596ff864d279c8f0b00d835d4f76783c1406bcdfd92f56d76edd19a82209c4ca6520a3685a4362c216cd3b64dc7b12dd7762dd3124202b0e62bd2c0cb7cab825010c3a3651b95928304957249a3116b4c3468200114053e8541ddb35b02c81ffa7bbbd4ef7bdea267b9866183902091480b432caf2e7be592eb7a8d4643134929d7d6564dd3d05a3367e1599d07eddada1a678d662f9b9595958f3ffe986d0db55aedd34f3fe5c78ce35808d1ed763ffbec33cbb29801e564d3308c52a9c44256615867611b96effba3d1a85eaf2f2c2c6c6c6c309520a256abc564a15c2e337b65131b4fe3bc66b7b1b1b1b8b81845110fe39c8cacacac2c2c2cb0354d4ac9deeadce3e7e7e7ebf53adb6e01a052a9dcbe7d7b61616132998cc7e3dc2adce974363636d6d7d779118ae9f6dede5eee250f99e7bde3384b4b4bf57afde0e0a0d7ebf176b68585855aad4644f57a9ddd2078767cfaf4a9d67a7979f9ca952bdd6ed775dd8f3efac8719c288a4aa552abd5ba74e952bbdde6cf954ae5cb2fbfe4c4ba6c16649c623ed86834aad5aa528a97e4eaf53ac36eee4492db226cdbbe76ed9ad6fa97bffce583070f2e5dbab4b4b474e5ca95288a1e3f7e8c88d56a75696989fd9b2ccb6ab55a77efde3d3a3a62b6b8b8b858afd7ebf57a92249d4e878728af1dbbaebbb6b61604c1d75f7ffd9bdffc86378a56abd5ebd7af7ffef9e74b4b4bec44c6b9873b9dceeaea6aa552d9dede6656c87da3dbedd6ebf5300c07830111b5dbedb5b535b69902c0e1e1212f7d30576d369b8ee34c2613dff73dcf5b5858f8e8a38ff81e58715e5959f9e8a38f7227ac9f08b07218297ec0428163f510df62f3f36b0aa34f1e5a84f914bb32b31596512ce74d90a6e1e3cdf1694364d99b63de9391a315af37e7b62d002c97cb4b4b4ba5920780966d23a20091c449bd515f5dbbd46a370cc3d04aa5150b4404020d00eced804002419a26963dcbb483300cc2c89fcd288e92380ae378321a26331f2be5926dc1f8683a384c8efa50a98828b1a4214c13046aad8414ad76abde6c08344cd302224260a7f07cf989886ab51a00f090765d97378e303568369bdc80eccd8c880cdf428866b3e9791e2b0b50f00ba9d56a1f7ffc313b4c954aa5bc06c771ae5dbbc68803008c74ec6a8088bcb99788b84ea6babc37706565250c43d3342b954aa9544a92a4542a7dfcf1c74288dc1f3d0f99c21a9ceffb8661789ee7791ecf3d6cb5741c872d684f9e3c994c26b76edd626a393f3fcf2630ee2aac8a72258c4450080e03009ee7ddb97387f703baaecbcb6a90edc29152b65aaddbb76f5fbe7c999fa85aad3216dfbe7d7b7d7d3df7ece73dd85ce7d2d292e3381f7ef821d7cf4e000c9ddc5c52cae974ca7d6f7e7e7e6d6dad56abe58307b2b5722644ac590f0683c964120481ebbad7af5f672752ccdc4d4aa59294726969c9f3bc9b376ff2adf244cb3c3a5f4861d0e755f5fdfd7d36514da7d31b376efce217bff8e28b2f78565b5d5dfd977ff9177695ca7d7a3dcfcb871e17cbb2363737171616e238ae542a39430780ebd7afcfcfcfc771ec64850d7fec45911370f69bf33c6f69698977ecb32e254e6e20ff710bbd66d34fe6ebceb0f523ac12b2d343bec0c74644de796018060f155edbe2cdf7790fa063bf92144dd91cc6ca02b754ee1b81692e3ff03cafd369bbae1b86117735dbb684c452a534373757ad947ddf27cdc1f438ba6a1a23140105b02b16b0155c4a8d42f3825b12c6b10a290e290eb58a1315c768598d86bdb121db43d199a37a036c07840444022d80f7704802504a1311521a87a0f80e18aa00804d6fad568b6d5200a0b58ea288352f3e8d419c9565eed0fa64cc133eb3b8b598edb242885aadc6e0582cf980e4da8ababc699a8d46a3d8a1b9f046905395703decac70b60f303f621463674ef66b595858e0c1c695b06999ad5139d4161797d95020a59c9f9f9f9f9f3ff787f22d72790ddcbbd88276ea715815e2f65c5858385b61b1589655ad5679f992fd064ed18a1c5b1b8dc6e6e6266b79ec2d5ca954d82d2b2f7c57b66d9ffb20c50a99ea4266d2ea743a1f7ef8e1743adddcdcfcdbbffd5b56de832038f57e7952cfe352703f617a5e6c5e0060a3304f5145795e8a562a5e2b6356bbb6b6c68d501caa7fcc92b53d1102a77d3ecdb0ce05b9a219ebec99f9b76c38670316118dc763def3c11c5e08c110eeba2eafa1f2d5b95328af060881b66dd76a359e9a78edd63024a469eb41081202887410cc46a391695a96ed0451a02101505a6bd08084020501116a055a1101f2d6e2741fb426601893063aae6558c271eda812cf82208e92b0d104d2ae6dd73cd75a5a840f6ee838968e2b4b1559ad1220a649bab91dd2237d9f49f2ec04c54003e74d2fe74ace7d47e2643482b39764d6cad393c49b173c190be5dc5fc12cbf8065598b8b8b6c00caddace06487297e2edecf3b6b1c175d88d9ceeaefad81416d757575717191bdb44461f366fe8cfc81291543d5d9403a7979fdef16df4b7eb79d4ee717bff8c5c71f7f9c2449b55acde1fe6cc8c6b33f4a17c43e1427379fbcbe308bcf292114de6fb13b41a177fdb8c7332e9f44c48b84a9e8ed1856b17b156f3db74d40a67fe62e3900c09a05bfdadcad81350e4c5d2b0d6e56cff398e8b282c0a7d9b6c52edd9ee7c47114c7f1dede3e11c571542e958590aee7d6eab5244976b6b7a37ae87aae23048146244ad95b9adb35ddf27dbcd112500a0b1cdbd15a51398ab506ad341bd46ccb14c699355d22c87cdb8814e70d934232e2e6d351de6f8a7610fe4a6549e459ed85f3ae3a2b29cacfad21e762790f1385f055c5bd53795539a1cbbf2a4ea7456b421efba138ccf2630ebb3cbc73637f7ec97173173645b0f0ecaa39654ec8c59fe0aff29b2c8655c81dfab81316afca2b2f364eeea040275324f08ef4d3afbb50f2fb67c5f0d44bd1857cb7c593cfca752199455e03df52a9542ab61e64cb11bc3e98ef332dbeace293e6209b779eb38d40857c3690cd34f90332edc8671afa894d5779d167c28af0ef177f9c1ff6fb01ebd4e45cecd3540075f61d6597163622f0867e2262c58d23ab40865fe572d975590337726b48a552350c330cc3c3c343222895bc66b3d168343ccf1302abd59a61189389bfbdbd23a5acd56a8ee395cb65afecd56ab5c38383972f5e06d3607dfd120a81a0d3200d99f60b488004cc86042021820020009428a401a694808234a1b8f80d65e4206b199192ac425b158f45c4c907c6b92d7c6ab23d25f9de1a5ed3abcefdf622e14595c0f75186732b3c7bc9b920f5c34f2862e2d972aefca2467e7db9a8d1cebda573e5e7b6c9453f975f7ef6a9df96d95d247f4d6bff11a02aff21cafcc95992810c9dea556f6dc3cad12affa553bfc160c9160d1e5a4ca6c230e4e001bc80e8388e619800e4388e6d5baeeb20a2e338bc939ef7792222af9dd9b60d40991f83f4fd596e27765dd7766ccf2be9440d8f8600840200199af0c42862933b92d62a49502b4214a449a020d2420210214f3e3a4bb2a034101069210401a0407697cfb27203a2c88e7fe27c4defd24d7e9a529cf9ff683dfe4dcaf73623d3998b5858b1a9734620b3ad9d3fd64b647659e4477ffc8ef4133dddb9c73cbc82cca28f511e000bf1780813304b780bc02a32ac5cd5cc5dd57367056e653699eb42fc7236183306f19625ad155b3a72376800b02c8bada74208d7753810122fedb37dda755d001442baaec76a261138b6b3b8b8d869774d29d3353b02004e869866e622204022d0511287611c450a0118b08034700e42218900852066f27986c81c92408b14b00465295453c0127fee8075d1e56fde07deb09314cb8f5eff3b3fc2f736e02989b82019eaa933bfb7e6b77a89c5fae16498e63f5a47fade16f8118ff9aa6ebe847df68d1745f966e3b7ee37749267e546f71cb6f205a09c73b13b229f03993980edf4f9250c6daeeb5a96699a12008934a26159166f276456c50e0b9c72364912cbb42a959a6559a4124ecb0cec8145c77e589052248ce378341efbd3003480268148a04910913a664c40ac09038a1cb00467940420d2280a80c5eff84f0a58dcceaf3ffe10b0fb33293fc5e3bf3ffe498efc81d72ed8b7e35c8366f1dd0380416f3c39e71ff2a20b8104ceca73bba038b3f919cee80bb9295114c23910015f6a18c7811fb5a62451528294465a7106764a255a2bc91e0dc8504502a8f043020155a28359389d4e4111316021f766d6088a2a9e86b47d19b09088903134fdccb0f51eb0fe48e53d60fdc51cf903fb6cb2b11b4e2d809eea996c74c7b767584554a24261bb7bbe37104eae3441b648ac4f46cbce89581e89010a6b584208216410cc66b3996d3b1c903bbf240b410370bc295a0b93f5dce3ec84e96da496716118a6e3385a29d4a0b51628d8b6a733903aade26942149a740a584210a90ca40469e0c8cb7f5ac0fa21c777008e3f55f97368aef7c71fe5c82f34cf6f802781e8d8a7fcf80bc4376758451c296ab6194ca4e8c8fb542f5a8fc87f9a8189b70a6221d16b7e87fc272bb700b8bfbfd7eff79bcd56a552e56d3a5aeb3c616afa74028421b402a26c10b25607d901406b12021dc7edb48ca45a4504d25a80202240a935838e16883ae56584288008e0f89185442285401960e1ff2d36acbff2f2271fa2ef8f678fb9799a5d37729c812c7ffd316011d13b33acfc33532422ca859807602f98fdf392c31322e69ba2abd52a2b83ccce844855592104bb680741d0ebf5a434b426212451fa90c0662921a421b31ddd69dc2200901cbfb4b8779200002cd3b2cd3cc2947e6d1a54ca1d19defedbf7e57d795fdea2e4ee7578b2e4fed96fc1b0b8d079962cca5c19f31031bcff99318b0a2c0cb388a3ccd166b319a71268369bf94e08fe2a4912ad9569a65e11a6690a21b5a6388e38eb149bf085948800881a7414c75a6952dab1d3d406ec8590fde3fb4e4355645f01910620ad08511280942900694a0014a56baef238f8fd098ce26adf63d6fbf2befc08a5487a10d3045fc75408de9561c119133b6f25e33d6b711c3360b11303332c0ea90119ffe285428ee2c0fb4e79471507844b12c5281345a19492d73b3978f9603008c3088038ff82eb7942ca3889a3200a82402b4d9aa230b24c4b1a52250910159f0f01908019a166133b9214421a1200084013476b03441468804c0048e90481880049ead4d1410b89d98a21200a4d90ed763c66bc7fcc35e91fd453fe3aca9f5cfd797fbce80827dd5f8410694ca8532ff0f50cab08784561fe4b7981ccaf9fc3efeb9311fb9861f1e8e514920c677c6d18869cd24e4a19c7895263a594949cb4720a001c215ba9240c837eff683af51181333eb65194cba599ef1ff40e8230b42d5b2b1220b4d29eebcd8219abc2f913b24d0b8980103468c96c33550913802088a2289652da96e95a124002281419602109e4ad838277fd088180ece7c6ed8e67dbaad8863fddf17df9def253bf82f7c7773e9e42a11c568a23e88732ac537ff25ef37c153937a2f3571cf6248f18e3380e87da60631befbf374d733c9e4c2663d334eaf55a6e77e79d8088c841115dd7d55ab155cb75dc72a9349bfa2f5fbc0cc2a056ab9302d20444cd868ee398105088a227567ecf2884461928e507e160ec0f46d3fed1d89f0451941842da96512939d5b2dda87be5b2e579b6694871ece90e29cc31c54ab5ced3ef0033cfb2f70ce87d795fdeba605a0a7fbfa50debdcc27c8a97fc382c6f9e879d88b4d61c740100f2b0df1c3e290c43dbb6abd54aabd56ab59a00c8e9791da7d6ed76394454b95c364d6b3c1e9ba655a9549796961a8da6effb2f5ebc188d46537f0a085114f50e0e7cdf27458812082ae5b2aa560198f9a4f74994e9c3a889500b318bf54e7fbaf564efeefd275b8f5ef50e8749448223c8a8c4b3e5e242f3d60797ae5e595a596ed72a8e676924cacc5c84c81bc93551be6a29285ba3cc7d38f8ecd76fc4fbb32df91477b2ebbc2fefcb4f5f4ed02bfefb5d1956a1c2b4b0dec75a21efc211423036e5722925fb6a6196904308e1386ead56ab566bbc62c8148c0360b3719d4d4e00e8ba5eabd5ee76bba3d188133db0b14c6b1d8591218d66bd619a561846b665019066172944b66311fb39202182260ae264efc8bffb60e7d75f3efcea9b47af767b02b156ad961c3b8a92c970ace3e0a83f505a0929bc926b1a02419808d2b6382e201be5044a94793488b485f33de17f9c18fe3f5d91691c0a800bb7d4bf2fefcbdb162c1c2f3ee9f41c8988f83a867516cb8a92dc8118b2f447a66972883ede8203009c3bdb34cd72b9ccc9d30120080228f47e263ea7ea67e4e22880719c4ca7d37c9364d1709699cfa4e7956ab5eaf5ebd71ddbe90f06024008542a21221259646804420d402090140dc7fee367bbfffde583fffef2e1ee7ebf5eab5cbfba7cfdea52a35e0afda0b7d71f1cf5c7834112f9a3fe913f6acf5ca4085cc7b00c2985c135663ba28f592b13ae8b9a940adb03307339293e4b7ecc15c9dc2a59ac24b7249eade7d49b3e6b473bfbb978c3672a39fdd3f9f1f516b473efe74d84f9efbce7747fb985ed27dfe315941bb28a827767585488c1c4d625dbb61dc761e786dce2ce342a77b32a863c765db75aad20e27038340cc3340dd775eaf59a10e2f0f070341a13713e3593754c29052b95ccbc38481600562a95a5a525d7b179bfa1eb381c60cbb42c4424cabc0f78740020a2021a4d8317bb470f1e6f3f7d7ea0356eac356f5cb9f4c947ebf3dd0a69e58f67fed83fd8d9f5c7a37ad9b54107e3712c3455bc92e349cbe40a51883889e3789624b110d2b66c5e27e5e0b99ce5340cc34aa5c291e172e695b7e16b56127323e0292b983819b42f7f0567def439279f3d072f8ecaa2b58ea228084200b06debac4bf0499b2864bd10102177a62b9e79ea660a3b168ee1158e2118b26da1efcb5f48b9106bcefbe2cc949931ac1f68c6ca5dab785ce5c1fc84101c6e546bcda3d7300c265c86610881f57addf3dcc9647a747414c751abd5aed5aae5722908c2fdfd03225d2e574aa532e71731cd238ec0cbfd9e733ddab603001c667bd8ef3f7ff64c29e5baded2f262a552ad54aa8842253a4fbe411a3410a28e950ee3c40fe33051b1064a843fd3073dffc5abbed2aa5eb14be5d27cbb7179a5abc2990a434812df1f252a02a24aa92aa52d44eac7351c0e5ebe7c7974d4776c6765656569693108c2a74f9ff57abd2098ddbf7f7f7b7bfbc68dcd7ffee77f6eb59a455829e6cacedd4d2ee259909dc44cf31460e531338a12807348ca69d79693bf78168ffafde1b3674f00606d6db5d3e99ecbf500a0c0f3d2a310a789a1529ad3e2162ed75a93c8020d420661c5b883ef79d65f52c9385536207359fac5f1e215a4feee74926091f1033b0416d2c743c1d2cc75b29ec89e59ecd9c0f911d824ef38b6e7b988c8c1ff1181970e47a3f16834520a6cdbc9d340327de38d8442885ab5e6388eeb7a88e879de5cb7abe3e4e0b01785a1eb7a7cb6edd888023409424863cd201128a5b552b66db49ad5c5b9d6cb9df1a01ff48ec6fff3cdb39dde51a7539a6b97bbadea4ab7b13cd7986b36a58afdf1280c2661a88320f2fdd0302dcb364cc30480c3c3c32fbffceaf1e327b56aed6ffe4677bb5d22eaf7fb3b3b3b93c9f8eeddbb5b5b5ba669010047311c8fc7dc2c798a84625e9cd32ff8a4ae948f64de24c08c959dda987bf23ecd5c25e73712c7b1d64a6b4eb3c6abb7cc37b188560090a425d61a5cd7e1ca7d7f9624491425701c251d1021cf2649740e5f534a2589d23acd41c9499488807b0222f21a3123551445dc3d6cdb4184d92c20a2fc2938ac6b4edff2aec72d7446724a5894176bc08b25ef202ffed6bbc9ff326ac00b24a7de5dea09047031f42000221516cd78fa7d1786c5189777d09c5e150b9fc9ac8a03c848295961745dc7716c444812ce2a5cae54caa66997cb651ec6cda659abd585404e6905008ee332c6f1981742542a950a56a494422069721d776e7ebed6a8c749e4baaee77a00a07402440221b362a54e0849a2b45295b2b5bedcd9bf3a393cf21fa93d7fe63f7d317dbe2b1cd7a8946dcf36e69be50f36163ff960edd262ab6449d3b6310cc2309afabe6999d2704cc3542adcdfdbbbf7ddbd6fbef9b6d96ccecfcf5dbb768d433f674317118569a66920fafdfe8b172f0cc368369b737373191cc49c9e9ee92973d67c81424a61db0ee302b7eb6c36e384779c5b81237f0f0683fdfdfd300c4ba5f2fcfc1ce744d05a4fa7d3c160309d4e1191d38e1191699a1c5e9188a2288ea290b57b4ee03e998cb586f9f9f9c5c58552c9abd5ea9c59878d89fdfe11bbfb72c62a26d100a0350190101c4c99c6e3c9603098cd7c442c97cbad56cb75dd2008f6f6f686c381699a9d4e87b3694ca7fec1c1fe643229954a9cb2616767378aa2b9b9eec9a4126cd8ca77179cb5805cd48dcf95d319399d9cf9df4a7e0a2bdf41fe9751432e3f25493f692001c0b19b0828756f84e206b96312962153d6ce3f9061e5579d02a9e2b7ac1e72547f3e1a866159a66148cc6277712a27d3b4f2c8eea552c975bd2cad21b21bbd6dbbf9ec2d84306cc3300d0042144a6b431a956aad26eb006cf5104494a898409f983f04006995c448baead957d7caa634ca8efded42fde5f6d1d1703c09c259ac767b93e9c4bf87fac9d3ed8383a3bffbecc6071b4b204da5541485eed4ad544a8818c771afb73f1c0e6cdb6eb55ae572298aa25eefa0542a1b8628973dad55b55a69341a8e634f2623c3108f1f3f7afcf8b165d9ad56cbf77dcbb2c2302022c771a59400a4b5224276419bcd664110944adec2c282e3b8001404c17038dadbdb3d3838188d464c705cd725d2af5ebddad9d9514ad9b6351c0ee6e7e75bad561004af5ebd7af9f2a5effbf57a6d7171298aa2fdfdbd72b9b2b979a35aad0140bf7fb8b3b3d3ef0f9452443a8e93288a94d2be3f350c1945e160d047ee594051147266e62449fafd7eb7db9d9b9b2b954a42b0011e887492a8c160c8f7e3fb934aa5bab8b828a5180c06bd5e6f777777301848297ddf174212d1d6d6d68b17cfb5d69d4ec7f7a75aeb9d9dddd96c767474b8b2b2dc6e775c374d29f40ebdf47df9332908902709a5a2188fbf3bc5f5d2f02a3f90619d45b7dc6e952b83ac9840b6ba7f2e9c0981856f532187e8138590eacc35724c1459ecdad45f812043669141b80620910a89406bd08a3400107fab1395c400dad046bd64ddba3abfd86d7c787df1f9cbde7ebf3f98f8bbfdd9b39de9d3178783c3c1f3dd91653e6b34aa9d66ddc168341cc55150f64a861086340e0ef6bff9f6bbe16874e3c68dab57af6aad1cc779fefc99ebba4c2d8914222152bf7ff8dd77df95cba5070f1ef47a3dcf2b1d1d1d3e7efcc8340dc7713dcf755dd7302cc3104ae92c448f3c3aea8f46a3b9b9b946a3ced6badddd9ddffffeab8383fd72b96418c66ce6efeeee3090710a7bcff30e0efcafbffe7a6161e1533ab8540000200049444154c30f6f2589fee69bbbcf9f3f97d2b87efd9ad6eae9d327fff11fbf6cb75bf3f373954a15805ebd7af9dbdffeeefefdfbb3d9acd96ccecf2fd46ad5384e82c0e754c64f9e3ced74dadd6eb756ab26491c86611806070707cf9e3ded743a51747d6565c5711c21241144d1acdf1f3c7ffefcd1a347bbbbbb44fad2a5f5f9f9eededede93274f767777f83d86611845619244878747bffce57ff67abdcb97d7c33078fcf8511cc78ce35b5b5bcbcbcbffeb7ffdddcaca2a00689d208a2c887ed1d8716a3e87ef93e797d379928bce7c4d0d0469720000d005f6f756f2373c536792efade1a2337fba1a8af2b34f517c1127daaea0dbd389afd32c7d3f12c3fade52645eb9251e119592a60988a9373ca4e6580560e6ca269bb4725cc32cf6735e676e57660423009d284d5ae90485b0a40179e6d4ac491052331ea2d01a06835974186ab08461759bb566d50b75773c0b5ff6fc6f1ff701cdad5974d49bee1f4d7b47d3e1248871361c0e056881e83a8e94c6d1d1d1fdfb5be3f1646d75ad5a6d4ca793d168d0ebf56ab54abbdd61fb0babb1878787df7efb4dabd58ae3786161c1f34abbbbbbdf7df75d18069cae928866b3a35eafd7eff785107373dd858585c1a0ffead5b6d6fae6cd0f0000110683c1b7dfdeddd9d95d5d5d595c5c340c230882ededed9d9d9dc78f1f2ba55aade6783c7ef9f255bfdf6f34ea00b8bbbb3b9bcd5656563a9d4ea55299cd66f7efdfebf7bb4110082100c4643279f9f2c5d75f7f3d9d4eaf5fbfbeb67689d3701e1e1edebd7bf7e1c387474747376f7ee0fb53df9ff67abdeded574747474f9f3edddfdfe7ecea9d4ea75c2eb13218043ea702dddfdfd75a359bcd6eb753ad56777676fef0872f0f0f8f6edffe687e7e6e3c1e0741f0f4e9d3adad07bffded6f5dd7bd73e753d775efdebd1b04c1cf7ffeb96d5bf7efffaed7eb6d6e5e5f5959c32c2b25f7ab7c0f7e3612ce9a54e06239be56f2b6f253969ab3b69bb795bffecc3739fff567fe7435e019490e5bc42c4ae45951d3943082900881b2dd2839841d870b26cca8d6bbdab07e40c19c5465e893ba3b1468548e74227b3628e2545a51fe7cb9010f114120c88c5e8120210825a0c80c77a480b410c28ee2647bef60ebf1fecefe541aeefc5c756dad5e6bda8e6557cbd4a8fa8e492a0991c8b52dd394511452320dc3a0e4da9ee7588e0d00a3f1f8d5abeddd9ddd617fe8b8ee6ce6fbfe544a636565a5566b701c67b6df4d26d3eded1dc771d7d6d63637374dd3faeaabaf7ef7bbdf1d1c1cd46a0dc7715dd73b3838fcfaebbb0f1f3e745df7934f3eee74baa669694d51146b4d00696c9c384e86c3e1ce8ee1ba2ea78f6784dadada9a4efd76bb2d0406b3208ae2e9d4074029e5f2f2f29d3b779697575cd7a9d5ea9665093cce87c8417db8c11b8de6cd9b37af5ebdaab5be77efdeb7df7efbecd9335e27514af77abdadad07df7efbed70387cfaf4c9cecece6834dedcfc4029c56805004ae9e170381c8e0cc35c5a5abe76edead2d292ebba0707bdfdfd5e1cc71b1b1b376e6c8ec7635e3f7df56a7b369b5dbd7af56ffee66f10f13ffee39741105cbf7ec3f3bcafffe7eee1e1a1efcfb28926ed4385defa534cb45824026f20ff2397377fe48bcefce96ab808df09d2d53e1ebf08848448001a783d25b338e4a741b64048f910ff31181616ca9b9f59d41373c530138a3cb56a4178e292bc36210401c32f5bf21051108248b31002a6a9575132ea0108448d021115e9b11f3d7dd9fbc337dba349d26d97ae5d6bcfcf5709e5248a777a637fd4f74c6a2fb73fb8b634d72a87d361100da594d56ab552ad1aa6a1b5eef7073bdb3b7b7bfbb66537850cc3a8d73b9acd669ca3dcb69d24d151a4a2280ec3703c9e2845f57a736ded12003c79f2240c2321e4d2d252b55a1f0c8687878752ca76bb6ddb7692a8dddd7dd334baddeef2f232eb830050add6ae5cb9c2a6ab308c5ebddae654f244609a56b92c1b8da694623299188699240a08a4341a8dd6caca5aabd5048072b9ec7965d3b292442162922822300ccb304c4eb8bdbabaca96efc3c3a3e974d6ef0fbadd8e94e66c369b4ea74f9f3eedf707954ab9d96cefef1f44519c24c96c16f47a8796654a2947a3b1efcf94529665b7dbedfc770dc3f4fd404ad16e7738abfbf6f67614c5d3e95413b5dbed6bd7aefbbe4f444ad1d2d24aa351b71dc7f7fd384eb24ec4fae0f1348e98eb11984e5b2746ca1939db4f329e06e92ac64909e4923796634102e29825bc899cc40fad01fe6c6a3821cf3748e4727ede7c2022f2e0a59c6d71492bc1d4e255206e6fc8b08aa4e61436152594958beac9d9933853f044116928d19368780a1373f71f6e304ce1198bf68663ccce161b040248524a69886d47d61ba56add391af59ebee8f70e774a154b1856a492208afd59bcd8f6aeaeafdcbcb6ec99c9647400c96cae55efcccdb9a5120024891af407fda3be6ddb1f6c7e70f3d6ade168f89ffff99fbffffd97dbdb3bbe3fabd71bbc2d298a1240344d0b11279349af7758ad568efafd288a1617973efef813adf57ffdd77f4d26934fef7c7a69ed521cc75b5b5bf7eeddabd56a7ff7777f7bebd6ad52a9c483ab5e6f7cfcf1c7ebebebbeefdfbb77ef0f7ff88361581f7cb0393737675956bd5ebf7cf9f27038fce69b6f78d3b8269d24c96432393c3c64e0c8773b8d4693308cfb83fe783c89a228495418466118e641d4d8832149923856b3d96c341a4551349dfadd6ef7ce9d4f87c3a16559bc2774381c6e6fef68adaad52aebfea66946513c1c8e0f0f0f9bcd26222489124268ad47a351a2d4e1e1e16c160821a43454a2784704ef9f4f92442995281545316fed3af9de01a01032884efc5738ef3c3965f48c32dbd659c93bc8e9e411df46fec36ba034a7c09fbe06382be182d9cc915aa65222954f0327062f6146af78dc6aced8073fbd0debf87ecf292720e92c849da257c53321032f4404c8b7a7a4242af330e2c641c2f41f7f29a440444d4a485da958cbcbcd2056ae671decf5fdd92c0c51682242db30eb1d6fae5dbbbc5ceb5420f4273a1a7b8ed5e9763addaee37944449a4cc368b55aad56ebcecf3efbe4934f46a3d16834dad9d9614733c7714ba572b95ca9d7eb8d46fdd6ad5bed76fbe8e8e837bff94db552dddfdb5f5d5dbd7dfbf6e6e6e6e3c78f47a3916ddb9fddf9ecc30f3f24a02449eedfbf9f24a5e5e565f65a200240e2cd4fecb524a5b42dab52ad2f2e2e369bcdc160e0d84eabd5324d737979993d1ea2281a0e07c3e1f0ebafbf562a69b55a52ca1bd7af8751b4bbbbfb3ffff33f837ebfd7ebd9b6353737c7cbb58c17dc80ad566b6969a956ab97cb655ee76db7dbaeeb369b4dd33417161688a85eafb3df99ef4fc330aad7abdd4e474ab9b3b3bbbfbfa7541286e1f2d2921462737373341cbe7af5ea37bffef5d1d15110842b2b2bc16c369bf9a669f9beaf899acde66c1628a5c220ac542a9d4ec775dd62b66eb6609d54cf0a7f9df8e222f9fbf2472d0898672c6601338c22074b4d5640e9384646b86cf0e694faad6c58df8b6b674956819d9d0b5be79613279f7b0f9847e362a76d265144008a4053ce21d32f319f1f09851028a4364dc3b18d56dd81cb9d85b9d6741a47514220a4691010422c20911063321df68e741c945d6b7eae3337d7a9d6aaa6c9fb72707171f1679f7dd66cb72e5f5e775dc7b2cc0f3ed81c8f46428aa5c5c556b32911fd995fafd72e5dbaf4e9a777e238fceacbaffef087af4cd3aa94cb5f7cf1c5279f7c52afd74a256f63e3b2e779ddee1cbfbbc585c5abd7aed5aab5463377442220984ea74f9e3c79fcf8f12c086cd3fa87fffd0f1b1b57baddb9300aa2adf0e58b972f5fbd745d777e7e7e7dfdd2fcfcfc783289a260ebc1c3478f1e8dc7a3f54b97daedf6fff77ffedf9dedbd172f5e3c7cf8402b552a97979796eaf5fa783c595b5be544900050ab5537376fd8b6e5954ad7af5d5bbf748909d1dededefd7bf70f8f0e67337f6161a1dea8d76ab520084cd3f03cb7d56cd5ebf54eb703005b0f1e3c7cf8703a198f47c356abfdfffce3ff7ef56a7b7777e7974f9f11c2b5ab573ffcf0d6a54b6b5ec9731cd7300c29e5e6e66614459eebd89675edead576ab55abd7535b06020121e51d9fcd1eb9ba07054cc2e2c763794ebf29fbe3ac246beab790131dffe269aef17df21f5ec3313ffa53d770427e2c2120004d4408e2584e58e06284a410f0d8484f3a1fde19d3a21f8761bdfef23784a80bb5433c477402db18bc804864ab48c8bc0a21c7674c036aa5ed2aa494a66d52d98da941d5924b682a855a83260481511c87811fcec6c1743c1e444912945c6b6171617171a9d56c38b62da5000021c5eaeaaae779aee7359a0df645b8b4b666088340b55a2dc771ab95b2eddafed45f5d5d5dbfbcee4fa7bb3bdb87bd034db0bcb4f4c99d4f17171781a85eabdeb973c7b6ac92e7c5712c50cc75bb9fffec33db764a9e57f48327d249928461009a9697973fbb73676169110046a3e1e1e1e1fedede7034aa944a2bcbcb1b1b1b8ee3942be5380aa228dadddd23a22451ed567b6ebedb69eff8fe74d03f725d77616e7e6979d1b4ccd92ca8542a954a855bafd1a8dfbefde1d2e282699a8b8b4b0b0b0ba6615aa6258578f1e23969bdb0b0b071f972b7d3add7eab66d4fa753d3343bed76a55aad56abb359e0fbfec1c10122c671dc68d4362e5f6eb73b4a25e3f1c4759df9f9f94babab2804020461c83e7ab76fdf562a29954aa661dedcdcf483a0d56cf2b38bd4db050b68f44ee5ecd527d85a71be7dfd657fac925393537f9c909f96e005675e24ffe135e085d551c6a2d246c4c297e2d889148ea906a494ba5015be29c37a3d9ce5a8f11a4274de55df8365afa9e1dc1bd6401a386360b6ba00c073209206d200a448275a81462034a451f13cdb30c2300cc26816844112a944c54932994cc793711285a6948d4aa9b2d0aed7aacd66ab5aabba9ec7a971624d88d468352bb59a94d2342c4d8404b55addb15d4dca344d1482aaba52ad6a4d25cf0300dbb6373ff8606e7e1e34546bf576bbc38f53abd7afbb8e40e9d836110260bdd1705c0785b02d8b48eb2c367fa55cb975f3d6eaea0a0256ab690d00e0baeec6c646abd90ac3d0b1dd56ab655b36009886b1b0b0e8ba25dff74943a954aad66a80a2d56eddf9ecce952b57a434cae552b952360ca9b496286cdbd14a0380e7962e5d5a5f5a5a4244c7716cdb4114ed4ec7b2ec95d595280c0dd3ac94abd56ad5340dcb36abd50aa2706c1b00a4349616974a5e6916f8028557f22a95aa6199ddeedca79fded9b872d53464abdd12d20084cb9737a238b62c4b08bc7c799d082ccb46c4d5b54b8ab4e3d8fcfc4490e98269b8a094e5f08b6625420068b8480e90d26f021298769253128d4484e79c59942310e57220cd31d008334b10bb6fbf91fc4d6ad074fcb89c28f3acfcbc33f1dc332f92fff01a0af25c42e9eefd4c01224a9b1805698d84001a0138c39ed2a90299bfc0d4267d4cb07e98a7fb29b43a8b356f5fce31c79f225950444940442400124884ecc040707c9a20603f0f4494284d431b52820401866398dab1678194a87512a8384e200415533201353305d62aa54eab3d37dfad552a8ee3482938db33a0400289607ac6f1c3022080655b966d155bc9f34ae9d0d15a4a393fbf303fbf907fab951252785e293f8d5f946bbaaee7c2b1286dd572a55cae940156f21a54920881a669b65bed76ab9dcb8988480b81e572a55cae146f496b65dbcedada1aacbdeefd4a43da8e7d4244e47aaeebb9733077e6f4e333496b40acd6aad55af5c4d55a3baebdbab65a9010692a57cab9a4563b6e3dd3320b2d00e7cddea78404c08e59e79d2900205b3f3e969f9570797339822c320b3ce6146f2e7ffd99c7042533fe9c95bff9993f5d0d45794142c071c4090140169c4b097373169246144268c474b7ecc9218f399cbce35e42b800b0bef7c222249dbdb0805be754786efd29fe528aec2ad5a053f51889726c4644290a9b8c8510c2f24ac2b46ca7540aa32008c3284ec259a89492c22897cb25af522a976ddb14c7f7901ecfd0dfef7bf6f3b637e3d9f07e67aac9568fcf2fc230ce9523666b2be7dcc9bbc6147cb389eddc273d578e2237a8beae5036264e5d7df6159cd5495e2f3ffb430867dfecf7ca8b8b96c792b7955f782616e5e202f99b9ff9d3d520f0f4fda79293e7607a590afe12000065410219cd60529d7b51c2bb33ac53579da249e7494e235111ba0a9ff12c9c9d5a2b84026212d171d232803c3ffd997b108098242a886329b4062d98a4a629e90d325c81962962c3d69ea70d6108294dd30414b1863888a500e018ed0480a04923a2260d804824856496ab4903802612980e124d946e1d1252178329030946ab2c8c3211c96c0d54f34e62a2e355d12c423c0168a579a00b0e07ca3530647317c86c77a79641f2280d444c6f083342ca0c1e1065d67cba702d629ac484f15f67ea19bf1e28aa677c26133cbe3a53ff45aad6b11851a044e4e6cadf293f82404440de50c5af14f295a28cede4fcaa20399eeecf9c497cb39047ecc9521cf1f3f31d51a6efa1289e89441a411068ceaa7b464e220fe14f94b1097c2bf98f5e8306126f23ffe13514e5c5bb556c9f221288005aa02022910e3de43454e9512586212d29d231cc9d38f5b54c7bd18fece9fe5aec3b4639a2e3bfcf42db45d7e7b79a1f79110109047b6bb0fd9dd7060134e7e1128240240af67ac3e1c44761106ac1f1d8513000254a1381565a20080243a6295ad37e09a9710105922612a84923a0262d387c0d0a220221d21b63678b740c681eaa9c1d3ab515a000222190328308a4f0c4c0c70ec18ca8f908815c9e0222415e038ff36339c365a1e6bc06809481e20979264110201864526acabd0d51e48bad59f362f60e814181a8002c90aedda66a037060d6ecdda51e38880280873dcf38c433108394069d76f9acf764b79add70a1593209649237949f96c031a8e5724cad3317cadffcccd7c8c5dbd470eef9e7d6f056f21f5e432ecf72afa0d0d9390211480b81a40153d84295666901811845b163c946ad54293944a421f7c7d2b911eb47f3c33a833be7cb4f953326abf39609cfe356c74700a4744ece7a76ba4a48881a110d0384f463f56ce768f77084c2224444d03ad10c1352080429645a4fd64b884069a50048134a013924610a58442084009d0e7e38113b14ce7bafb9fccdcf3cdb777faab19a693d98031632f81674a28cb814ed476749cfa972ea64385903e3640a6d17dfc09b3dc20f6f8477819bf780f58e808579ec3c04040866b3b263aead740cd350bcef198972677004fc817e58a790a5f8271408517602cbcfc532e0f3f3c4f7999a875488b199df67f14e520396529a14b31e2944ceb0140148540207a3e0e9eed1b3eda1901e08038854122b5088dab64cdb341ccb900084a03509404d080441140749922842690080065ea691a009018150084c9d764fc3cd45f0f48ec79c5700a6ba5bca988e2590b2918c5c7d9f9ced7067ea3fc6119d3630424af68bf05440a113c69d33969ee265ec4048c06d99f1bd63a5ad7084fccb4c94dea438d908a71a87b2c7cc1ff62d8e67804c9c198a45e0cba110cf80ddfbe33178690281a8410ba4ac3d11411011a6de48ac82eb993fae79965df29a8d8ae68dbfa009b466a245446fc8b05e0f55799159e15894bc9ff9d4f9524ad33438946561c3731aeeddb22cd3b4785b0917ae2dbfbc6834cf2b978644890006002852394aa69ab01024304892c1343c1a47202d5e9c320d705ddbb10dc33212a506a33008c2305171a250208294422a0d9a30519a50130208911a103572584021804003bf09f68e4371726224819a0aa3eb0de129a518e9347502b0301db1402746ef1b00166436503a35fe2f1af3904974ce5f33083a894927100bf2bff18494d8e90033333a41c6aef00c601ddf46f12635a02ea22d12d1f163426636c1e2396f095859950088fc42e924932a421565efe7141b7a7f3c03f1a00b2d8999520200196069359bc489c269a012ceaf8e699087ec1fe22986957fc8ffc482f2752e90e55ff1b5f2644144264d273a310a4e4c915d8b457892d2e0f02f69be78214496df907f2ebf61ca22cc48f378d94ba2089308308d269c3e2911b70b8120104a9120aa96bc85f956a5eac589de3f38dadd1fecf5fa7e18274aa344298465d825d72db925208c952201866500625a174800a1181c73b31550b63e2c08786327102081d6041a340212a67445506e4b4242c136234c6d93849492112a1a88b811490301e7ff495f59aa0533cca5733e22105bb45394638ec4c6f2ccd6460273cecd8ee4e95f8802a540d29a23140b108528d3996248c87b2a88188734203ba3a76f368b1aa2331ecafd807500d41cec287da8dceecf12ca9a0788030561aa35f26ef734f008a5ab1369eb8180f454e2484a78823c221164da2d5f826cd965c33f1064e169310b81c99c3b534ac1e0fa81746e23252204914d25f4fe981ff3364710e90442d97044c15d8e3bab44248d89369596ecda957b606590c4e3fe0d18d6a96fb15072490e2b61180a21b2f075c4eecb3993925212511c474220071717598e68ad218e13ad4929324d8bc3b713519224442484e0c8e5f90d305499a68988711cfb533f0802d3306cd72e9552bf1ead353204109852daa6691a92a4704da3e2984bf3f56ea796106ceff5f70e8e76f607c389cf684f89f2e318941f7b8109502eb99e6d2904424c10410a02812421759ae3f9426776338606c149118934332e2905a12444e2f88244ec23c68e634c9701481088d47d8ca10c0835b1bd0c91b9210af64c100ad3b08584e99c25d28def6c1420365c42aadd20a5684180a91513412221df0301106a48bdfe30a7420225120840d28288b44010e99a1f12669047c4d5667ff04c21529ea332df4b4aab440414c780c53f9ad12638de01cb77253420a04652fc6c080241708649c6efec57d32549ca1ee18cfe9ba223a4537c0e58a918905daf51e7608c894a972b25a299ae59690da8095441eb7fcfb0ce511420a5a0024863ca917946c3b49390ce004b9aa66398c2304c2984d0993d3bdd749862cebb441c2d021665c4ca308c300c67b3194734360ca3542ab19c639cb30d2b0866e3712ca5a854aa8d46dd711cd33410c56c369bcd666118baaed76eb71cc746c4288aa6d32900789ed7683418c2204bee421901ecf7fbbfffddef5f3c7f59ad556e7e78ebd6cd9b7cab491213ebbfd95a934a120149a3515e996b749a5e18cdee3f7ef1bbbb8f5ebc3c04148d7aa5dd2a7b9e1547d1517f301a4ea683b127c26679a1dde8465a1f0dc771a20cdb0161f0c20562eaff46ec0e47a479d11f540a672ad14a219240938441208940a3e6c1cbcfa081144ff7a92282e92c0594410e37356aa5b5d2480428524e96cd3e19c9860c7d8855549199b311105010914e4fd4d9572980653a1aa4fd486995284290869480448a54a20834094489942dff0100a026ad898420c8f68331235244080a50f3c99cc891287dd68ca9e97432e51bd0400ca2e98c98b601fbd4b11f07206802242d78333f64b3714a1ad3a91c804003e57fe53f8d944dc244044488e934c10b5298a11a11290445a053a59a34697670d3c8df43e170fc39658be92ffeb51e79e6cb9356898cc913f71142603e4be964a639360341ce33582da4fc5dfdf0554266495aeb300c391533c754618dccb6ed1cb66cdb96521e1e8e767777e338999beb0a819c9b406b180e87cf9f3fdfdbdb2b97cbb76edde2040da3d1e8e5cb975114cdcfcf371a0dc33092246140648d9261eee183874f9f3e3d38e805e1acf4f499eb7a9d4eab5cae58a685d95a75d62fc932b0dd282dcdd56c9376f676befeeefe7f7f796f380a2fad2c2d76576e6e2e755be5380c7bbda3c3a3e16438762c39dfb2bbddd2683a1b0e4315c7c2300518ac9709f6ccd2bc650298542192942010048044301095a250a9440b9012008934521e8cb1407bd3c5071e7a40a009336702ad01c832d0720d4d14c65a694201021080b4ce2c5382a7350d9a3468240201a97698fe0052fad38c0f9a0089fb0d22a634510b205382619b1a304a009496421b12084502220652444c45521d9928b324a5b6b294e10169d005e7f314dc35a57bf51109538531b32d40aab6b2968d5a670a2c640a1d6627d3f16599129a1247c8931ae8cc30767c558a25a9e6c1e6ff7c3d48f3fd8b543154bc7784791fe81cce8e41f6cc98a082212ffffc577ee4e6ca0325a7f2632b47b1d110b11064eaf88d7f2fc37a3d9031c16160f27d7f369b0100a766ca5d3da7d369afd7e360e71c3ee9e8e8e8e1c387d3e9d4f727d56a657575d5b6ed284a8e8e8ebefdf6dbadadad46a351afd73737375dd71d0e878f1f3f1e8fc75aeb8d8d0d004892248a22c894c1274f9e7cfdf5d7c3e1b05aadaeacad1a86f16a7bfbd1a387376fddfcc5177f5f2e975108a5350128d29ab4618852c96e549d926b84a13f1c8d8f06932056d230ea95f2ca427373637169be2241cf66f341180ffae37036b32dc7b26da5a6a6480429500a903838331248504020011084222414d200d745d3204b40d5b34aae399a843bfbb36896086948294969018085a1c69e5a98bd409dbd806cd4814a94d6bad17416e62a5142dbbb93f1343110a440adb48184129104a56447a120ce0bc1da15331b4608419290351ac8b8005ba3080004202912a4aa65bbdd2d471a77f666813f732cac964d695ab3180693c80f3520a044916ec4c7d48086297b8714c208d2a782cc4c24504836fa10b1198850e44f9fa2ab808c28121a88a68124284e2056994e2828efe759d8ca74258419101080a0cc508a991d3545bf74490648a7263712d9d6004d0a98e009c02c1b00705a20d299caa9211d38dc6cacdc436e894b07484e43ff8a8f29b8a49202d49c9270773ca764dfbf09c37afd57acac2aa518b03ccf2b954aaeebe606758ecac6d01686a1effb4110b2552b4962df9ffabeaf1409217c7fb6bbbb7b7878e838ce6834dadfdfe74bc6e331c70e4744c330cae532a762e57b98cd66c3e1b0542a7df4f147dd6e77776fefbbefbebb77efbb76a705008ee30a61b0a5451369d086293ccf725dc3343189414a6119a66d5894a8288c7a87a3e72f0f5412564b966d99d55ab559af49d2a4943f0bfda96856ac30a1401368925250a28962d7958d9ae35aa656d81f47233f0202d7314b0e3952779b5ea356da3b98f67a611cc702b594484a4b5022b3425266862656f8794465688208828ddf3a2e79eec27c691aa89dfdc92c881d5b9254a0938a6754aa4e92d0d1309ccd022975b562972b4e92c0601885a132a51482121d6be2379708c13a2d68020d0a34a110060a891827491c87ae69ad2d55432d87c368328a1144b56c946ba5c98ca6b32489421208848addb84262000020004944415488a74300548abdedd95cc1ec292580ecac02909a0628c5484a690eaf9fe863c28219600922cb44d79428700a22d15a69623338669b6c0128dd4288c0cc8f0088b452c4d8220000040aa10190976a94062481c89b47629d804a3075c5d54c51193a5108440128b217c5f74c19434cad6ad9d227a46a4c8a93ef8ffc8633fe9b1ef08424ff1fcf2dd9296f65c3ca06cf317e312a7192d4388e0dc3701cc7755dd775d98ece7677cbb26ab5ba94726f6fafdfef0b81376edc88e31880e238dedfdf5f5858ac54aa9ca2627e7efefaf5eb96653d78f0c0f77db67f01401e520e0072b40280858585cf3fffbc5eabadaeae0d0783fd9dbdd09fcd75bb0b73f3526212c729bfd76cde50804a4a2d245896b00d6fbe5d9d6b543c2106e3f1d3a7dbe3f1e49b7b4f5aad4aab59a994ed6ebb7a65b57b7d6daee63906ea56c59e36bc20d007e324d6b110469cc4a0a35aab747dbd3ed72a87b378ebf1913f9d042148b46d53ba465cb2b1ec18235322908a95c2384934e8d8403205bbb183260021097924f3220a101291264542f2a0d240b121956b639ca08a93c00f85062db41449b55bb9bc569af8ba3f9e0e47e39203b579e7d24a6532a3c1b037f583b26b9b0645511c6b0d020c0443a021100c41404a91262d09a53450a0d2511c4e919caa2723300da95512e94418b25476a5269242ab242204d0422b3084619802114091568a8804020a34240a44d03a512a51a0b44021a55098aad0609828050090565ac78a54aa9f696e020d82d0926058d236481818699821290d5a29adb540128244ba4821d246434212049a34259cd951830443a6eab856a4925869a508c83484694a8190a84829051a38d52c02a944311b344c83771b49428d409a40e882f64b69902eb686653ed9901a07d98456a4b27f5d47068f0c41a828a1b4f5f8bfacfd2ea6586fc4b02e2a98b944254912862111315ad9b6cdf90419bf0cc3705db752a968adfbfdfef6f676bbdd5a5a5a22a27ebfcfec69341a55ab35218465596b6b6b9f7df6d96432d9dada0a82e0c68d1bb55aadd7eb99a6a994e29ca0beef736ccc5aadb6b8b8b8b8b80800beef3f7af4787f6fafdd6a2f2e2f5ebf76dd9032087c224af55344812811240280360cac79deb5cbf3e3e14485c9770fb60f4793c3c3fef6ee81615a6ec9736ca3dd2edfbab230fef8cae6fa5cd5b34b8e5b759d92391ba08e95262261084bca4ad9a85764a38a8109b50a965d091148106c19924812401018a04b16b855d3762c2053c5b18a3568428994faa868402412bca51d9104a4aef509ab754002c8402c3b46a7e9e8443bb61506b3388a5d4bcd35ad665df687d360329698d44a6279ae1c29391a0590248600c7846ac502091a0814a18624a6506b21846b49211189b4d25a81698992ed943c39f367933088c2c8b164b5623b968cc270e62b41aaea198e256ccbd41a558c714c1ac875504a93f993d2a41569ad056ad714d234509a8a308e35129886410061ac945602b46d8061494308646e29796105e3208983d03274b56408d308941221da269a0e0a9412094025a463452ab53d711c198d448601ae2da561092140cb2421adb40692521865690841a49344c7b1160865c7b24c0024ad208e359030a429a45009250a1295eab602315d764d59151cabc0e932031689051bf8f0aff598b700f329cc1856c64921b76165c690d751acb76358982e159f90e4b08799d768f1679864b102484449924ca75344701c476b1a8d86711c4b69cc6633e4956cc456abb5bebefef0e1c3dddd5dd334d7d7d7f9570cc398cd665b5b5bfffeeffffeecd9b3c5c5c59ffffce75f7cf105e7853ee8f57efbbbdfbe7cfeb2ec95ae5ebbb6b1b1de6ab7802008671a1488741fafa08cd96b4594d886b53257f77ebeb9b2d4f9eec1abadc7af5eedf68e06e3d1f4ff67efcd9fec3892fbf0ccaa3edffde67a736306038224001e4bad24ee4a56c861870fd9fe531d8ef0f7eb5f64cba1b0a55d71574b82e48200010cceb967dedd7757557e7fc8ee9e37330016e4eedafa6a598128bca9aeaeeeae232b332bf3935910d33488a3240d8370329e4ea7ef7efcde75074496299de702049151a46b0d67aeed7b35e80f0771d037049a687ea1e6a5c21242e719492388049145ba6e19ab2356371bddb98621339944a3519265dab62d20d2461b9d0312211a612b2dc018d752be0b716206131328b20422a12db1d3746fdde86e2c3784254f4f8767c7b124054a2f746a1fbe335f976a3818d72ca8b972b1512735dfb4cd781cd53d6b79a55b6fba499a255196a5fa6c909c0c13b0c45cc7afd7a44ab3c130194d75b351bbb6b6d86988a3c3e1cbe3703cd69d6ee3dab576cda183a3f1f1692c85dcecd5e6ba5eb3e903887e3f393a9aa85c2dcc79ddae2725e69aa2448d464910a68ec4f9397f7ebe6efb6e10e7fd7e60a198ebd63345cf5f8efac3d0b368aee1cfcfd59acd9a650956b84b5b4a2126a3f070afef202d765db09d71185948f5ba35df71eabeb025e4793e09d2fe280f13a30b16d59031124dd3b3163adedc7cddf39c343583413499c444d06a39ddb6df6c78644c7f101d1e4e81606db5b5dcab23eac924190e2303a2d5f25ddf0dc2f46c100d86499ce6045248591ea51200198412814e94079c150381b3c7877f98f9eb382c3a576efd3e39ac57923d364fcf3860409e53696a608ce1128e2ccfc659699a2aa53ccf731c3bcbb2e170a8b51e0c06dc789ee788d86c36979696e6e6e6c2307cfcf8f16834cab28ca5cb288a4e4e4ef6f6f6589d0f00711c4751f4f9179f3f7cf8d092f6eafafacd77de595ee9012bd78c06304ca58a603c240ad587a1244d0540a3eebdf7ee566f65f1fdf7d707a3e170181c9d064ff6c60f9f9fed1d9eed3e3f0ea6d34eabb9b9bada74cc70329d86114103103518c7b7da5d5f623c188eceb2c8b26d6137ebf59674649629a33519d04486c875e45ccbd548f36dd1a883d24280ebb9569e1b44506996651a51388e251dd7a017c5264df29a03ed8698047a1a24600c0a812805085b8a86672169610b933b5237ea9e459a4099ba63b5eb4e124804309a0442dd93cdbad419745af6da72a3567387c3204283751b00c3546b1235cf6e78560e668ca8b5a9d5fcf58d2541c9f397672ff6fa241b9bebf5e5a54e9604c361184ee36b5b4b5b9bf3754fa0c03433a1430d1fdd86bbb9d6585caca3006520c9ccd17178703812008b1d7761ce234b6a9d3a52356aeefa6a2dcbe1f46c72769a4b494dcf5f9ef3967a2ddbb552a5a228cdb5969244539a05df95627eae1e2b94229268ea3e2e2db88b1db7e109a5f4493f323ac8f32c51488464d01250b3b1db908b1d67beedd88e3dc53494aaee52a3eecc757ddf95ae0b02252a270b2ccb92db6bada5a57a140542a7bef4403ac2b26cd7a9d76ccbc224cdc3243704d2b2ce552fe71b3f1f0873813ec72faf906fff80f357725850eab07e371c564574664ba0545a5589abb14629cbb2388e1dc769b7db54ba04b2b4c806a59ee771e0f55acdafd76b4b4b4b51149f9d9d3e7dfa746f6f9f0ffed2340d824029b5b5b5f5d1471fddbd7bf7effffeefa328dadcdc640e6e7b7bfb3ffda7ff747272d2e974b6b6b600e0e1c3875f7df5d5e9d969b73b77eddab56bd7ae359a4d956bcb9679ce1a0c4de7b651a00de599568ad2cc1c8793e1681465586b75e6e7ebefbdbfeed8ebd3303d3a8deeed9e65f2c1617f1225599288344ba238344936180e26614c5e8d041028845ca263a121320406c12028228504889a8d49726d72ad3ddf5958684ee378349aee1f8fd31c9acddad252cb921806c938ce8cc95c57b69a5ead56d3460e29a5544b3016084b10a266b44604d05a8f86d193a76767fd895f93f59a3ddf6d74db35cfb54f87c1fe61f0727f90c549ade6a5497e7c3a79fcf4ecf878e0486823045176368af60e8664d4d27cd3f565bdee4c433309f22456a4559c9221440928901469a3c918e4b33604a54c96e69e676dae773656db93d164ff60d01fc461627cd759ee357a8b8d46ddc9b476a568771c296512a7599c21e9e9243a0bd2e3b3200e62d96b8336128525410a14484200a2b10438969806f9fec1e0f8740c40dd566da15d5fec341dd79af4236572c01cd046044b8a66cd751c29a53d9ce8c1d4504e4a1119f27cd9ac63b36e03507f10a6a91a8ee2d1386e36dcf94eabde708e8f87a361ec39aee73af59a6cb7fd46d39e06e1eeee5e1426ebeb4baee73d7d314a32bdbed19d9bab9d9c05466b36732d0e0391d8d792c814b6fd600034812e295909ddf1079c5fe4a77e0f1cd62c9d7a25db354bf32a82c5f60a61181251922458da3a701dd6c14b293dcf9b9b9b9b9bebeeecec6c6f6fc571321a0d9f3c79525d5a5c5cacd56a8ee3dcb871c3f3bc7ebfffedb7df6659363f3fbfb8b8383f3fef38cef6f6f6ecfba469faecd933a5d5e6c666a7d5ceb3ecf0f0d092726d7dc571bd56ab6949c16647280420e6ca445116273a4a741cc48f9e1c3dd9eb6bb4d7563bb76e2e2d2fb614619864b9ce94c984304bf3ad1b5b0bcbf3cd3c0dc3783c098344910400815218cfa6966fd5ad5a2e28cf6d695bd2f2089d20269390368496204483e8d7ec0ed49333757c347ab63f8e52dab9beb2b1b95073c57432cdb24c22d8b66359ae1012095c499e0d0220cd4d9a1953d80614960a93307bb93779b177da69c9edcdb9de427b69a92da4d83f8b1e3e1bbe7839a8bbb0b2d23104c371fcf0e9c9d9d964bdd79cd3d41f47872793dd67279e83ae67b55a4dcf77a67116c67a6a48a249149fe8e95c290960bb96635b4a83c9151923a5b06d0b142965c6e3e8ec64d23f9d4409d9aedb6c7af5ba658c1e0ca7e320b11c7b6ebeedd8b2e13b9131644c7f103e39181f1e4fa4319dba6734010269a372a50429a5b532a40d691346f9fe51b0fbe4541bf5ceb5c5f5dedcdc4233497363b46543ad2e5d4fa479767492a8d8595a685952388e653b969d13201a05ae231b0dcbf7ed5c9bc1303a3b0d068330cbf4f5ed8566ab66bb787c163c7a78dca8d536d7e7977bb5ee9c6739e2f4307cfcf4c428b5b6d1b36dfbf82c1a0ea385c556afeb3b8e64a6090b443a2a2d4f08a0b06e043e5b2cce0a1167f9883fe0bcfa037e7f1cd61bd26ccd8aed725dd7755d0e9d12862107234044dff71716167abd5eb7db0580e5e5e546a3b1b8b8f0ce3bef5cbbb699e76a3a9dcecfcf6f6d6db55aad9595950f3ffcb0d7eb3161ba7efdfaeddbb70f0f0f8d311f7ef8e1f6f6361f175e4acbcbcbd7ae5d3b3e3e3e3bebc771e2d80e0276bbedb9b9b6e37a9d4edbb62d3e07074400cc723d9926837158afb92acb4761f26cefe0d9de0992595b6a2f2eb42cc789d2fc78103cddef9b5ced6c2efdd1073babbd76188c86c3d32457207d8392802c41adbad55b68d62c3919d94198588ed56cd6fc9a3f1845e961926739a043a2385797969008a44c1aa771629456960420150791c9b256a7e1ba6e92ea388e9108c8d47d4b6b15276a1ae54a03a240d0440c508f1a65e139caea602185250931cd7594e4964003242c0160d23c4db344eb1a19a3b5ca559aa6b100698c0232008082c3d9f2ec31dae4a47344230402a2d6a4b29c941200ae6b3bae733698dcfbe6a0e14b5079b3e96d6e2d78352f8ad3308ce2603c1e07276781749c95d5c57acd575a591608895a6b956679921a32608c2d5113a82c8fc3481a54ca23630ab3560202db8043a6b25727322424d66a96e35bada69d67d1dec1f1bea09d6bcbf5463bcb3329a056b38c069d1acf26cb42146894512a4fd22c4e32061392961002b536719259522aad4010c7bde675408450fc82c2779289117b49b15f4e81394825674015e52a2de86986c9f8bfcfe9fcb3e5b05e975e59812544b669701c87b554e3f198eda4a4948d46a3d96cb2ae3dcff32ccb98904da7c1e1e1312258963537379f65e993274f38ee7196654f9e3ce136c330ec743a00a0b53e3838e06695524a293e8814421c1f1f0b219224393c3c8ae3544ae95856afb72825defae0fdbdfdbd384950a0405104b725c872331c858e251c9b6cc76db7ea9e2d8f8f27a3b3d0f7ce5cdf51a432954b21b6d7e6efdcdcd8d95874457e7a3a1e4f220d8e65d741d800680bf01dabe67b02649ca7a340d99e556bbab5869fe54a8a02d193415493241b8fc33c559da6bfb5be1064badbf6f2544da368388c6cc456a30ed2393a8bc7e3d81666bee375bbf52493a7e36c14e85c0b14168066b1132c69798e5bf75c1fa46d6bc249a80c284da2b7d4325a91c908304e72cb126bcb2d5792e74944aad79ce55e33cb5289e07bb6523a4d1411d53cdbb2c0e85c2b34066d1b8cd229a85c81635b35d7f15c99a62acbb521996b188d13adac4ed39e5f6cafaccd69c049180f2791a03c4d32a574a6b37e3f08c24c2be3dad2f3ad66c35b5b6e5b52e4696ed956142b14b2517756969b35175b4ddfb22c63c01812525a8eefd55aa012db768ca12cd7da1844614921105dc7ca0c1aa313a5922c93599ee746086c78b685a0128d68b22c8f13b424b65b3ea2f03c278e3369c96990fabedd69d7b7b7167dd7a9d7dd24d1e371e6d81ec77cccb3cc106a22cbb15ccf012194260384a5696fa1ae3af716e0032f0440e04a05d7204a33da7f129cce3f730e8b66d458b3d40a4b6110a080430882603a9d0280e338799e2749a2b566199035eefd7edfb22cd66a49291dc7d9dd7de2baae9482e30cefef1fdcbbf74d966549924829efddbb57afd785101c9714118f8e8e3efffc737648e4b7652c651418c5511004a3d1280ca234cd10856d5ba7fd93c3e383bfff87bf038446abbd75fdba00e03376811284359a26599634ead275bddbefbdb3b9b6311804c12451641c47226a21a956f7bbed56ab669b2c3a9b8c86e3304e05593e5a351416182309546686e3344ee8e95e707c32755d2b554002b334579ab4c13ca34c41a668320c0ff70740b4b8d8edad2d26ca1882413f3e3e1af5fbe9e25c5d5a4eaa457f981f1e05ae6d1c57ce2d4ad2348dcd38d028250a6948669aa254451965a473849c84462b2779781a9f0d2240b8b6d15d5eac9d9c8ee3d4bcdc1f76dafe8dada5c54e6d320a01a8d57017161aed663d4e5249381ce7d369aa8c6878b6eb629e51c347df716bbe0882388cb320508da6b7bcd0eab49d93d3f06c108d2679a359ef2d359617eb0ddfb26c717836ed0fa3fed9048c9e6f7bbd6e7b6915b28ce2548da74914a59e633baed5e9369addd6e25277380cb35c3fdf1fd7ebee52afbdb6dab2240820d0184499229365a434189208963622cd28ce945226497518e44a932dad46bdbebdbd5173e47cb799e6826802a41d09be2f951051948dc63a89f5fc9cb730df5ceab5a74136188449aaf60e27ed963737d7ea2db5058a69909d9e4ea3782aa54304044211a6ca885c2b039a20cb759a6a5d7a3e155e4d78ee4cc5ab05ce590684734f85732ee30f3a3fef07ba5802332500bf3d8775a97c96e0216285fac24784ccf8341a0d3e13acac1998e830cfc5f5f934d0b2a46559b66d475194a629e36121e26432198d4688685956ad5663c66d341a31b0df0cc6396f696859d6c2c2c2ea8a8d2811d01069ade2243c383cb22ce97a3529a52cf1798525c172923c4fa669a6446fce5e9a9bbfbe5127c22c53da6821c8e84ceb54a220a0e97874723c188d279996249a4236a5f0116d2134114d02f5e270128466ef38ea0f12db1624444e20414f238a336122b2c63acfb3fe497c789a788edd5e70daf5a60d3418464767e1d14996657643d9c3c024b99e84268829d7661ce9419027990e539319b0a440cb2232610a278334c94ca600a59da30c73310c4c106487c741abe12c2d367ddf0e22757a323d3c8ab496abab9d6643249112d2721cb75ef71325331584d3643cc9c350a1b49506a14c966b698966d3aad51da5cd7892c589ee34dd8d8db6e3bacf9e4ff68ec234a7b979bf3dd7ee2e3424e27014ee1f8f8f4fa65996b71b6eabe5d97edbab3949a2d2c13456e9243671a61ccf780d596ff9757413654d4ea7c3e3b8d582f5f5767bae0640c13409827814258e238398928c40580220d37238516825c6c060a42613ca9406a16ccb6b35175a35072d1106499442a648e6dab2411b4a7313042ab185eb51b36dd53ca7864e94c1340e8ecee228a3b59556b75d37da0ca67a38d186b4e345ae8799b17243838976f32ccd41038ea699468a53426101c802dea9f04cc002b9a104e481ea7c1098a728edb97fc80b4a7299c382b7b2747f0b0e6b965455dc56757385ff89888d46c3711c22721cc7755ddff7199c8f891195265a6c50ca060d8ee348291d87f5f58e10c2b26cd7f56a359f053da514d33866b500800d26187a945f00a840099752fabed76c346ccb3606a2308ae2285529119d1c1f4e83d82832c620000800810a410b8b8c09137d3608b3286d37fc66b3d66cfa9eef4a3451988c87c1643a8de26c1ac693284bb465d013b28eb286c2451480c6100e27f93499661964cad8ae23054e43fdf22044d05ae5da809599308ea44ce2288b722736f2c961723835841445593855b1b640d8c35064fba1d29464c6f11c29cd2854f9de48691d6799908882c1ddad69a49fbd9c90019581e3f81a6130d55116e6a9495243903d7e369412c2208d5222a24cc5e300a4d000e0fa721ae78350ed1d4e07fd4065264d75ae1109c6414ea0b4caea356a341ddbb10c096d501b1052b835cbb68422ca0d909049460747c1649290c138c9a7611627828c1d46e2f0241d8763615b5a5392646188a9b6738d47c32cc826ae9718c238514140698aa9ce73333dee27449466799666a44120e65a843159b62d484619ee9f2467c39c009254c7096ab206239566a1e724ae23884c9ca8f134cb34a53945319251790a9991790ec7a32c5463db96da4092a828822c8354e7899e1e0f13a375186441668cc16787816d6390494362ef2495d2c4a9d1068f4fc3c108a344096113ca42cf0200e72c166baf802a5f4204400651a9dc7a7fc8014a95df4cc96b2a7c570eeb1261ab0a2f5d657ea756ab753a1dc771d8be81f1ad5cd7751cc7f7fd7abd5eafd70bcae438beefdbb6e5388ee3d8b59aef38aee7b1857c8d71b1d832deb66dd775b1c4cf925763615d4da4d224b3a4239df3b057bb8f1e7df1c557a4010050b075002922b21c1496cab241900c0741cd19b7dbfee262b3ddf46c41c174dc3f1b9c9d0d8228cdc802b70eae8fe883f0c9f235b2979b208024268a330021a555ab5b48a88d194e32222db0c0c923931b204481d2cb0c0667893e0e00095158c216d245c469a626fd84806c69b9be8b48619a4fe298bf5d5a92100150a01d273a0a3309282d29a55464269199848985c2963249f5d3bd8931c692684b8928c3b13aee8f1d1bba1dcb72401d47a349faf260329d64ae6d3bb60528c96016aa4ce70446237a9141a109315740285345837166db94e4202c9b0cc58909c2d0184340022d69d996f0004daa4c32cad5205504c8588c68214a43340ecd701a01450488285008815694d0348a9431005a48900204094304204058420a044c34451305260300b64446c420d6d33066b47d00830c0f86825205c0005d02d022c071a007d3d068038802a5252580cc13338e42321a802c21a49080a23fc901404a5b20f6c71a490b2110c4789213100a10d226c0c23a060a3f692a55c858442cc2829821210299aae40f342ffbaaf85d21129508465cceeee585c9087bfe7e670eeb6dd2ec71000b80711c8761688cf13ccfb6ed56ab25a56472c642223b398f4623cb92ed76bbd3613c2c5b0811c75118865996d56a353e5b9452b2651600b05bf5ebde244de2cf3fffd5cbbdbd66a37debce9d6b9b459cd15c1943444c9bc154a6fa880052806d117886640ca4220a8f27fe706223983c4d129390af2c97d0126e0da52784076083b41410493668668735f6b735020150101843a6901a80e19588004122220331120188c27f96015009a008eb650a5854342034484404b4118bd16564162053ee410005f4007fa6002260cf5d148addf88400019a288ae1e42c15a33c49f32c23292d100eb1ff1d190d8cfa273305c3918e82d80026992690510a2ff6028162126a024286094506d332c051ae7856111a02534e54432050726427048da04ac58f118002d0308818f7151556e24480682416d0848640a3e198de02010a3406a222d28e0012fc1404d45000ed110a51c1369842a57b0e8f51c02c0b0402908055a43ce47182a2170bd82b46cb128086f154010a476860cc425e8ee5ff0888d534638cdf82b8e11f5e5ee1c3b206b0440e818264016bfba818211e2076682ff559c5eff234f66d4f095f992a05bc522a8e63220ac3300802630c435f254902000cb1c0f032699aeeefefefeded69ad969797af5fdfb62cdbf76b5996efeded3d7dfaf4e8e8a8d1687cf0c107cc8e9d9c9cbc78f1224dd3e5e5e59b376ffabeafb5564ab1161f11d936f59b6feeddbdfbc5f1f171abd3495496a96c697ea156af2549aa38a8169bbc12a1d10214f1db0b00db02cb028244c5c124069d3a0816829416d98eed082904481b50081464c8a062547c00623f416131d288368abd2b8d6341314c9a10c09204421068031a912c5ba0458c294ca038dcb714c69248046072a37959826b8902de4c13228131886001489b888c016d4abf689424889050027a36e802f24c03806d0b61031a50793e4933def91d4b38b655e0559106d01249b20b80a22853a13106d8dc416499393909c0004801888c2863d958202d10a1d16834020934c2020b091845c1180025482018290c4a6646d8d852230821a4c5be912018e10f4b552d03ff1100024a0b2cc9c749846490404a6349a062064a040164c81804633832370292464089807651c23e864404089645c8313b11883400ba16ffa191c091cc4b1904444b20083284a49174499b98ce32bbc55889082418f51a800a324954d664f0993fb8bc5808acd7a3026817094c01e00702043b3809ae4c99204b80c6e2e8150b1820a6665739acab3f7e6362ffc1e974ca348b3926cbb298268cc76321c4e2e22213ac3ccfcfcefa0f1f3e0c82603299349bcdcdcd6bbeef27493a180ceeddbbf7edb7dfcecdcd75bbdd3b77eef8be3f994c9e3d7b361e8f89686767a7b29eaf30fc9e3d7b76efdebdd178d46eb73737376ddb3e383afe6fffef7fbb73fbd69ffff99f375a2d14526b638804822dc997da6046a04c01645e402b0932121184b400245b302182140601d1183225a0abb4c870185136fe16c81ef90c9129a880b2244401a2024812545aa108284ebe0988004d81face6032506eefa53e9200a8f0f9a07223126ca6456415658c987d8e67c2411a78fc9897615e5b17bb190a1008120a575d32a0a1d2be102090214358086f7c344640a2e0518aa95470aea6985ac5ca2de12199f7401425c361b00022a5524a104584590486d58173161819bc3173e6000020004944415456b0d87c0178afe14e11888c6159e26c492cfcc609804ca14baae0c5a8ec3a2c1952c3bd5b7e5ac1a896b0b150020012a38c120804c9c36a4023338c1c06a96af91c09ac08d744608a69707ef50f3737c56f36f4e09e2c49180a0012cc3d903122f285eba022329ac094ffa090e5de9ac3baaad59a2d514a054110c771a3d1e8743a95a61c4a3c2c3668c8f37c32996459818795a6591846719c0020fb361f1f1ff7fb7ddff78320383b3b63ed3b4300aeaeaef23122abc3ac323e7b9224c3e1b0dea8ffe8e38f5656564e4e4e1e3f7a72ff9b6f16e6e78510b57a4d48a98d01a29a6bad2cb6c818400b40809485d201404849444210124900b66034445084f012c618fe0385202a4c0b8b501178bea5306781cc777088e0820e303f8504c451910167eaf376c4944754d0e3e5b68c8cad54d629b9eb6253e1d6046fe6c8248f4921b312a5a1236b854154129829684c412159d044402882b0028029d631572a246b045edea52e820a9a7d8160994249c137f2a5731d3454c411cfe5292c05778092b840e9060365dc8ba2c3010b0bc482a02018a08236219638564cc17927a0923a2395e17f8a778352b29eed64625c322a082516526f19f1c5cc0e7af19b23da72e82a269a458e3fe4450e8045ece172f21b12a2d86689b4d12a8d45b3ee2db63dd7b1728dc5512cff2b355bbf598775955a71618587c5660d6c85d06834d81681955600e0795eb7db15421c1d1d9d9e9e4a29efdcb9c3883459961d1f1fafacac349b4d96f57abddecd9b37a594df7efbed743a65b007229ac5c3aaa81500f47abd1fffd18f3bddcef6f6d6743a3d3c380ac370697171b9d71342e4794ea4559e93314dd77e6f676db53727a52584745c972324100047612f081020511138be88fc5c1223287b9f098ab8322a17cb67e7eeabef8219e275b5b5993a70b1fc352b01e0d2289614e2fc0a2f55aa546c172b17b483d9ad99369898d2e5e6f97a41740a827571e2cc343c5b521452f1acf265ae7e40d5fc1ba72794ece79547cc7c78f92517bbd4cc0ccd79095cee5e8e4ef8baa0a1976a5239aa3f10ac0bb999e9e122b4aa21210a357c9e673acfb234f55cbb53afd55c67141ae2c884056c3f13aab7401cadaee2c554112cd655f199208b7e1ce4a656abb9ae5babd5981e9d9d9dedededcdcdcdadafaf1b63fafd7e1004474747a3d1a8d96c321ed6e6e6e69ffcc99f846178fffefd300cdf7ffffd56abc52611c698388e832088a2a856ab799e57abd5d6d7d7d7d7d701208e93c7bb4ff6f70fbaddee071f7ef0de7bef59d24ae3088c063248e4d9d6c662572d762d0005a08dca95260eef2e983b9ddd9b8bffcceb49c95be4f05dea5f8dd9f9cad65edf26e0159a823384e8f222bf520857a9d8c53a3853072f5184d734f8ba423173235ecc5ff909af2b7fc3532e7ce32cc19ac9c5956e17afe95e31d3f9afabf33d06fd0f282fe33f8b927801110844ad8d10c2920d4f4a2a51df0dc00449000930e25c3180f8db9c12f2fd54b23f151e169491292a218e75e4699a8e462386976154992ccba4945114511961706969e9c68d1b8f1e3d3a3c3c647806962ef90892f1b05ebc78b1b2b2f2c77ffcc73ffde94f190fab3f18fce33ffeeae58b17beefbffbeebb3b377616161688284d6332b9008ef800c0a1560192707c7078c8c6a8ba10ee581478dbdeaf38a3ffebf3e03539bcf5ca79fb9aafcebfdfcc79db4700127cef4ff86d3fed87fcb7cecd95df8825b7c5db489ae69ee7ad2cf736d6d70516aa246108387871f9af3a377cb51dd6db4f3e46314ed334cbb22ccb2ad98d2dda95526cd70e007c989865192391c6713c1a8d88e8121e56abd5eaf57a9d4e270cc3ddddddc160c076f0c698e974babfbfbfbbbb9be7f9cd9b378928499224493effe2f3fbf7ef4b296fbcb373f3e6cd95e515ee266314225992036183313993d3701a0ecf0667fdbed1a620fcec06f68665794524c42bb203cc08036f6ee16afd575e7de553dea685b7bff7756ffee66fb950e7fb12aceff088b7a8f9e636af7eda6ff3941ff2df82600107af67b243044992d66ab59a5b5be8a6beeb02024a04827328ab4a8f85886fc3611553ff4aaa7c030180711a1825868858d1ce144a08916599effb6118c6715cafd71b8dc6d2d2126bd61f3f7efce2c58b4f3ef90400d2349d4c26799e5fbb76ede38f3fbe7bf7eedffddddf8561b8b6b606004288cdcdcdbffaabbffaa33ffaa36eb7bbb5b505000f1f3efcfaebaf4f4e4f5badf6c6e6fac6e666a3d1e020634a29ad74a17c2d1dffb55242ca5acddf585f5f989f07404de51106f7acc02ba2d955e5c5ebd419dfa9bcdafc2b1d2d7c97f22b25e7473350febe748c75b5fced6b56e59584569454d3649622c11bcb2fbec0a5067f9f9ff036ddf87d06e2773225deb266a54dfb8d2dbcaee6efaf85d9f24b25179f622aae48e4b9b26dbbd9685a966457162ace94800d120918be8709d56b7458afa45057091900b009bb528a253b0ef655c9866c9385884208dff719f4eadd77dfbd7efd7a188683c1e0e1c3877c8941af98f9dad9d9b16dbbdfefdfbf7f3f4dd33b77ee301e56afd7e3605f558aa2687777571bbdb9b9313f3fa7943a3e3eb6a4b5babae2ba5eb3d9b42c9ba8d0b781944a6914a2d168355bdddff8813fa41fd20fe9ff582202ad144a81020c01094128088511826678acefa3c36262c477092158ff9de73907dd9a4c26ac77f77d7f7171716565657e7e1e005656566ab5dacacacaad5bb7ae5dbbc62aadb9b9b99d9d9d4ea7b3b1b1f1a31ffd68696969616101003637376fdfbebdbfbfafb5fee8a38fae5fbf3e7b3858a5d5d5d56bd7ae9d9e9eb2e468db3602743addb9b9aeeb7a9deebcb46c65d83c934fa690edd4be83d0fb43fa21fd907eff89d8d3830809348166e8372c1c47a0e4b1ded6d21d6712ffc96c14c3b4335268100483c14029c596eecd66b3dd6e03004784564a31fa681004c7c7c75a6bd7757bbd9ed6fae9d3a7fd7edf755d227afefc39474b4d92646161812dda4f4f4f598bcf38f1151ed66030745d37cff3c70f1f26492aa4b02cabd7eb398e7dfbf69d83c3c324cb5b42721059004421d9bb8d3471cb442445250cfe5310fbbf67fe7b9e4eff1cd23f8561fa21bf94f332042021050a765b13c8fe3d4880a6543c14c4e7d598eef046a9902b30c11a8fc7d3e9948d1238542a1f0832ae5e9ee7a7a7a79665b19915a3213f7af4c8755d0e2491e7f9cb972fbffcf24b66d02ccbfaf5af7fcd6e83a3d1683c1e03c0c9c9c9175f7cc1a225872fe4b887ec9938998cc7e37114865996018294e2f8f8f8e0e0e0effffe6742c846b3b1bab25a1a081654dc8041b632c742c1517e17ff77213f37982ccc192b134a2443801c269e8c29da290070049e9b77b29d3b1b7c0a3445c4655344e2062443060c1962676f107c171546d8c57b940355bd6c5907cf5f97af96c6e6785ef5bc9d995f1716f3ccf05e2a989d0fb3c608df416bf59af2d7da68bd75f9776a01ca212e3a8d5e5df23dcae94d93e7adcaff79b450958399b15d992d2f9453fcd39c5bdf912103401ad8089a9769f18fb80e2f80d762ba5769b6c26ce295c9619f99ab62db2bb66f6086284dd3d3d3532cf1b0d8c1701621cbb66db68097525a9695a62963c373651603c330648c4098d924cb17032164b3d1e8b4dbb3368f611805c153dfaf6d6d6f591ccfb3b8858428dc3a4a0bf2c24b43e01b4ed0abe78a0bbf0110412209292eac70737e17d0b949341031b4bc38e7890850c8c2d3b1206d4294022c011648973053c21fc203cb2be7dc020b11cb69718160bd61fbb9920a825550c742735d7c9e28c91d952633b3f71413e3adcb5f59b32c2ca6f295f2b76fe1723922ca52715e998f5e29111cb8faadcb8b232d1e1a53967cd7f2b7aec9ecc8dbb4f0ba9abfbf16cecb4db16723078a2cda17e5523288c8ce5b053643398d5194cb52220964df3238274fbf8d0e8b55fa8c8705008c87e5ba2e2361715e21f93139635191c91957f63c0fcb08869ee771fbc61836e0e21222524a15735154870e748e1428a4949209168325b0047a76769666a95239194dd5ce48048c1b59724c457119e68481420c111b3a0800c60e61ff0f62f71d222842a15381873e93b4b9e0c3010064a80cf38cc068cd8864486983489625a1a0351cb11da9e0e3981d3a17faa8187076112cb572409573160f0e16be8ae7358a87165f0a70c552736606101119c39186665929e2c3d48a0a7c3fae6ab6fc95352f51d64be5975e185ff509affb347ca3e54755f23dca2beb627371b77bfbf27f1e2d54e5c6bc42c7726e833dbb40d805cc100ad4464b2900898cce33a5736d14430d40c9607d77b4062c1313ac66b359393c3349b22cab22460c76c5e58ee3789ec7e50cc6c0365c4ce9d84282454b3694879289fbdee9f1e3c777efded54af301030070fc6798f993ca1c1141c00ce59fd9e8f842c1a70814c8a031d2b284406d4c9a65799601a014c2711d29252218c2cafdad9ceb400086d8fc8b100583a12aad95d200c6b21d2184281f6e0a1a5bec39bc4195860054843a060076320684aa7eb5708987ac3866c019410e67f2ab23fc8a038e1fd20fe9f79d66b6c15aade1b975c7f6a4b010f0b7b274c7f2947056bb51113251a64ad3c4c25d1505fa95a9bac4daf4df92547162605222224325a70364ca7e29732a2d3f4c21641916880890880c94aef9ec1f4ca48d30c600816d4b00c8f2ecc5f3e7cf9e3d8be3746161e1e63b371616160085d106050290c4c2c8838094d65114456148447eadd66eb71160301cbe7cfec2b2adededed9a5f4389640c63491963b436ec23ca6e0d0005a757b0402c370a2144a18b2342c3382a05b54232450f088e4fcc5ffd2a4684efb0becb06f643fa21fdced2ccbceb76bacd66db753d1412085961f69b392c7c630200ad351bb8739889736e024008c140ec8cd9a094e2ca1c65870ffb187aa1ca99b7aa1ca7196bb4facd62e0a5bc7a223f5d6b2d500829002098065a6981a23c2564f551810a2f4a99bbcab120be88c8582a05212e382f53486dc5b717d4441d1f1dedeeee3e7dfa3449b2c16060b4dad9b9bed4ebd9960d004a2b6db4d606001cdbb62d2bcbd2972f5fc671bcb8b468db56cdafc551747272ecfbfef6f6368b8799ca841188c888a3fc2c22a335233aa19442b0145ce8c88c5679e9f120500096ca751433e69dc527cdce8e596d3b77052aa5d32ccbf3dc184d64a054bbcf3473657efdff4128c40beac81f0c47ff0f198e560eb997dd728d41146408cb85cce76980084427c7272f5ebc60673e402cd428bf8d2f21ccb05a7085b4bdf996721a110ffcc544d52b5dca5f995e510d677e03108199a949654cb9f39cf92fc1e8a458dc74dea4216380fb5714e0334cb186c3fedededecb972ffbfd7ebbd55a5c742793e9175f7cd1eff77ff2d34f977b2b5aab280cb33c8ba218089696163dcf4f93e4c99327676767ebebeb0245afb764b4f27dbfdea83bb6050059968dc763a594e3d8cd66d3753d0093e7599aa6499268a5a565d5ea35cfab593cba7c2e31992aad1cc7f56b35cff32cc9483966565424536aec679671d5ebc6301a358d46c3afbefaeaf1eeee6834a2427a2df5fa25e00b0fe6ecfdb383fcd6e5df83607dff165e67ac7fb104e8d5355f577ec90de02a26d4db97bfb1e63969b8b04fbf3e7f5dcddf5f0b57cb2f10ac72bf2f7bd294352b6d970121a4b084566ad0ef4f2653c77573f0be035ac3ebd22c6d12af4ad5416195aa3f4bd9d0e29f33f2a28588525a88f8bd392c4414428a323e059fca55dfc8cc16cceaa70a2d95c192ab2238e7a43837978831b2b04947474777efde9d8c272bababd7af6fb7dbeda74f9f7df3cd378787870fee3f188f46001845711c4741100821e3385e5959190c86fd7effe5cb97611832814892248a42d77594524ae5fbfb07878707799e7b9edbed7639b2ec60303c38d867a35ccff39bcdc6fcdce2dc7c1700c6e3d1c9c9c9743a35c6341acd858505d771846d97d4bb849d7ae35930532396c447e3d12f7ff9cbafbffa5a48e1fbbe310513fa5d27c90fe97798de8ec4fc53cea1b022aa0856e1b879a18e10525a96cab3e3a3c3c9643237bfd0e82e6ba30125afbd730eeb0ae5aaf86a7cb572962f97383355b752c9af5d5ee517ae9eb75995cd70355c192e955379f47585c362042b432418f5015102b370583158052f6598d300346418714d704e9739b5999c5f03183b9d88104929b5bf7ff0e0c1c376bbb5b3b3736d73d3f33dd7f53a9dceeeeeeecf7ef60f799eb5db6db6db30c6388e7b7c7cd2ed76a328ccb23ccbf2172f5e789ed768344e4f4ebffafaabe5e5956e77ce75dd2fbeb8fbf2e50b56ead9b6bdb1b1b1bcbcf2e2c5cbcf3efb2c08269b9b9b8d460300373636de7df7669eabc78f1f1d1d1db14cdd6c361145a7dd711c07800c430ecdcc78284f13afae075320e0c37412eceded1b433ffdb34fb7b7b789406b5d6a15a9b4adc0d74f8aef99a852a30140799ef0d6f7d25becbb17ce402ee5f02aa20000174a5e871ec13cd7dbd47cdd5d174f33f97d184a80398072577e8dfd4da15f7dc5532eecebaf7d7fd446733f167896e7b085e73d73de1b80860c00cc7009a22a47447e73e43832a678c3d25197bf5a109fb49ef359a0b4b12c29501a9ddfbfffcd836f1f24699eab2ccb52b26da66e9739ac8b140670c6577af6eaabea7f8724040a71e1cf4b57f92142945aa4e241e7a61cb3e59c953fcedf903557a50aab6c84cd4310d902a4e4b398e6d22bf3a2ea0c9f82885aebe170747272d2ed767776765aad1600d46af5f5f575a5d47ffdafffcfe3c78faf5fbf7eeddab556abd96eb75dd73b3b3b7bf8f01120341b8d76bb3d9d4e3ccfb36d67329ddebbf7cdf1c9e93befbc53abd55ebc781904d35eaf1704c1e3c7bbc3e14829bdbfbffff0e14344d8dcbc96abfc60ff30cbb256ab359d4e7ff18b5f9e9e9eacafaf2f2df55cd7d3da149d052804cfd762518b2b6785b34b5e8862522aa5d2345b585cfc57ffea5fbdfbeebb6f412e7e483fa4df71dadcdc703d6ff7c9d39361a8959276115df09cc39a658eaecce8822d9ae56bceafcdfc3943ce58ec34e53f0d607161c9e81863340352710563841048c4f15619268d592dac1e523e7df64d781310a5d5d2cc2b5de4c7aadb67f8a6926fa3cb8aab8b399f1b9aea1186d01893e7599e6788e0baee6c87b8ae1b04c1e9e969afd76b369befbffffed6f6b614f2fefd6feedfbf3f9d4edf7df7e6c2c2c2eaeaca071f7cb0b1b139180c2ccb9a8cc72727c79d4ed7b2e43befbc73ebd6ad172f5ebc7cb9777c7cbcb1b12e04cecfcfafacf43efdf44fb32c1b8f26711c4f2693e3e3e3ddddc783c1a0d96caeadad753a9d66b3c1c71d884825d058d519e5875f4e97385646497fab006b3fa41fd2ef21496909e4082308044885b0f4061d165dfc7da1ce2c2373a964269d336800c0fc51c53d55ff2e165ea8c01cc16bb8aa4b791519872a11b57a4ee90453d86131d80e945aaa733bacd7e4b35fc449205a96c550398c9ebabcbccca0cc59968d46a38d8df5280a3b9df6fcfcdcfbefbfffde7bef01c0743a49d3e4e4e4786363fddab56babababefbfff7ea7d3d9dfdf6b36ebd3e9340cc37abdd66c366edebcf9c1071f789ef7b39ffd6c329928a5eaf5dafafaeaeddbb7fee44ffe64381c3e7cf8703c1e6759eaba0e634cb387f9743a0982a931950437abba7ab5f6ead208028010c2b2a4d17a3299306f9f6559e57c5e55ab085cd52c97bce129b3352fbe5bd166254ae08c3072b585ab57675bbef4bb7adb37d4e7eeaa883bbe4a54e4f2d9a3f0d795bfaee69befe2c4efc0cfe5f8c188c831894519f67cf6aed217efdc68f1ea732bd8162184d6ba5a26b357f33ce7e7562a636ea7baf7523b6ccbad94e2e7566fc873402975e9cd675b9b6da77a5b7e07566413d1783c89e3582955acdff298f0b73a257c65aa5abba46f2ad9aba24ef5cc19cdd4252e60962dba705608973902ba5879f62974a9e6c5bbaa93c4d7f15617382c3eaf659e4e4ad9ed769796968c31cf9e3df37dbfd96ceeeded7df3cd3783c1e0c73ffef1c2c2c2c9c949188695997e65d5c1da222ad91fa5f234cdb22c574a2955d87f400982986599524a08542a272a905d89288aa23ccf3737377bbd1efb84efeeeedebb77eff4f4647979b95eaf530906fb663a75a9afa0e4b088f052bfb1f14a657ac297d89c65b69dea1296aa8d4a17c36fce0ea1506a671091cf642ad0472c5debab05508de92cc1e2a542440cfd5835523d1d4a350ab75359de54140a00d8c59557a9d63a4d53284f7b2a82551906f2b32ebd09942a022ee77b993440490479c2f0a379314369f783881cb880df81db17420441f0e0c183e9747aeddab5adadadea13786173539758605da66a20d84288c1e968e6b48a2b30f1e2873e7ffe7c381cfabebfbcbccce0e6fc888ac031b9e1d688683a9d4e2693e17028a55c5c5cecf57adc39c69820089e3f7f1ec7f1eaeaead6d6160f2b9b2c108014421b232e122f28496435a9aa05a2953246cb728d7fb753c2cb9cc65b6bb58460e646547f5e4ab365d57c2a6da62ee5957669f6f7656ee8ea9b5425c55a9a3913bc3aff66f3f2b5798615e552cad5d5d5dbb76f0f87c3fdfd7dcbb25aadd6b367cf1e3e7cd8ebf53ef9e4935eaff73ffec7ff38383878f0e081e33852cad3d3d3d5d5d5858585eded6dcff30683c1eeeeaed67a30185a96b5b4b4b4bcbcdc6eb7a7d3e9f3e7cf5dd73d3838705d776565a5d56aa5692aa595e72a8aa2344d2b7782b9b939cff3c230dcdfdf8fa2280882308c78b0f1e2c60bbf8972cd8c23f292af5632afba288a068301fbba773a9d5eafe7fbfea546e822834357789c57be03fb9332607f96651c8bb7d56ab55a2ddff7c51bad88f33c1f8fc7c6986eb77b4936e7378fe3384d53adb5e338f57abdfa222622ec539124491004a3d188bdf7d901a3d56a75bb5dae507d0bfff936899985ab9dc3ae6c97ba2bcff3c3c3c32ccb3a9d4eb7db05807ebffff5d75f9f9c9cb4db6dee67a644ec5252f5277fcb743a0d82a0da1d99d0789e373f3f3f373777f59d6986630200a5d4d1d1d1a3478f7abddec2c282effb554ff27cabbce5aaf2300cc7e3f1d3a74ff98b363737ab96c7e3f193274f8e8f8f8510376fdebcf444fef39563cab49bab55db8f524a29258de165febbe1b066b7c199413ae7aa2e4de257b5f05b7258951515db5915318d6926bdeaaeef9657f7f2c6b8b2b2e238cecb972f9f3d7bf6d9679ff190743a9d3b77ee6c6d6da569ea38cedededee79f7ffefcf9737696fcc94f7ec25489c10bbff9e61bdea93636363636363ef8e00329e568347afaf4e9cb972fa5941b1b1b6b6b6b2b2b2ba3d128cbb2f9f93900e03dad56abcdcdcd4d2693fbf7efb39184effbfffa5fff6b3e46ccf39cb7f4d9de7e03c9b8c4c870aa763c224ad3f4e8e8e8debd7b5f7df5d570387cfffdf7ffe37ffc8fd7ae5dbbd4daa5ad4b2955ad169c915f2e25066bdcdbdb4bd394b9c576bb7dfdfaf59d9d9dcac3f40d8997baeffb572b13d1e1e12157585e5e66d91c00aae873fce7e3c78f1f3c78d0eff7932461d4c94ea7c3486d557db818b1e937a6b7e103aa3a4110fccddffccd7038fcb7fff6df32c1caf37c6f6fafdfef5795b32c63fea86200ab70c2cc5c9f9d9d0100bbca6559d6ed767ff4a31fcdcdcdbdeeb915d5b02c8b419f388ecc2cdd6790bb3ccf1b8d06a345716ab55a88c810c16118ceb6ec791ea3995fbf7efdea13e9f54a838a8524220066af749665699aa29d6aa508cc77e0b0decc58cd16be8abdc28a7b2a0b71b6e0d2412116477eb35cd51b382c33cb40552f76a5c10b1cd6dbe7b34a31fecdd3b7d96c369bcd7abd1ec7f1e9e96910042b2b2b77eedcb973e74e25e900409aa6fd7edfb2acf7df7fff8ffff88f37363600e0c58b17676767e3f1380cc356abf5a31ffd686767e7c68d1becb37d727232180c1616166eddba75fdfa75d775f959ed76dbb22cdff7b7b6b6b4d69d4ee7f0f0707f7fffe9d3a7beefdfbe7dfbdffc9b7fc38b364dd36abfba44865e37dc6fee3796e3922479f1e2c5e79f7f1e04c15ffee55f226296656118f2b36cdbe69a3c29b984e18658e49152b2845bbd12bb910e87c3afbefa6a7777b75eaffbbecf52210b232c24b2373b1beb41c941f0d79d9e9e32cc7fb7dbf57d9fc3385119d39771229f3c79727878c8f06a376edc701c873f8d37f0e170f8f4e9d367cf9eb13cc892bbe33861181e1d1d2d2c2cb0085c5daab8b359f1aa12fc2b27b3cacd83770276e740c4388eb95008916559bd5e775d37cbb25ffffad7f7eedd6bb55a6b6b6b0cd6848849921c1c1c0441c09eb9dcb1611832a96a341afc567b7b7b5f7ef9e5d9d959ad56eb743abeef33e9e79e574a2549c2c2af1082593c6e9cbf224912561831d3c407d05c6d32999c9d9db14cc71c1637bbbfbfbfbfbf3f9d4eb91a476fe0d80e7b7b7ba3d188878fa70dbf0c3b1a5b969597094aa475463a98a518bc82f8cd9338966ea6b54680efcc615daa7f6967bec28c14e771f4d6a952ce412989e08c9e124adeb27a101606b5a559ad3100acada7df158755e905ab92d91f9d4ee7bdf7de6bb7db5996f1515da5c1751c676d6deda38f3eeaf57a52caa5a5a55eafc777cdcfcf7ff8e187611856a3d8ed76793e31850ac3b05eaff3c11f00388e333f3fcf8e96b66dafafaf23621594e8e6cd9b8ee36c6d6d552c46a51f99fd96d791aa4b3d536910664ba494bd5eef473ffad1743a7dfaf4a9d69a57e3af7ffdebafbefa2acff3f9f97966eec2304c92c475ddf5f5f5e5e5e5f178fcd9679f254972e7ce9de5e5e5a3a32336f4d75ab75aad9d9d9db5b5b52008fafdfe743a5d5959d9dada6216f2c68d1bcd66f3e4e4e4db6fbf7df8f06192249d4ea7d3e9f0272322f302676767f7eedd03805aadb6bfbfffe8d1a3e7cf9f23222b5096979799a4debb776f3a9d3e7bf6ec2ffee22f3ef8e083a5a525d6133d7efc787f7f7f3018acadad2d2c2cd4eb75fe58dff711f1b3cf3e534a7df4d1476cde319d4e7ff18b5f3c7ffedcf7fd8585055efcaeebc6717c7474140441ad565b5d5d5d5e5e6e341a59969d9e9e1e1e1e4e26131ed63b77ee10d1dffeeddffeea57bf124274bbdd2ccbb6b6b67efad39ff2427df1e2c57ff92fff25cbb28f3ffe1811ebf57a1886fffdbffff7e974fa2ffec5bfd8d9d9e135fc377ff3370707071f7df4d1a79f7eca048be951ad565b5e5e5e5858a8d56acc61351a0dfec6afbffe9a350cabababdbdbdb7373734aa98383837ebfcf50bd272727c698478f1eedeeee3a8eb3b2b2f2eebbefaeadad4da7d3c160c00b33499267cf9e3d7bf6ece9d3a7fbfbfb4c8376767694528f1f3f7ef8f0e1fdfbf78320504a9d9e9eb65a2dcbb24e4e4ef6f6f698fb5b5e5efef8e38f373636f6091dbe400000200049444154f6f6eedebd7b7272c234cef7fdf7de7bef830f3e989f9ff77d9f0add2e226296e761142649ecaadc18ad95fecd1c1622ccd6b9541fafa45716be325de1b92eebb0aa9ccaad4c5c8497297f0396f104890a66ad7ad3ab2f06df91c3ba7457c57055f1cd3637372b19be12a33ccfdbdadaf27dffa73ffd29c7d160bac0c1cd6ab5da257cfaeadea5a5a5a5a5a5d9429c517cf087b3d400004cd42eb5c0aa56ba2200969ac1cb3cd7a591ad6e99652dd92a9509eee79f7fce1c9f94f2d1a347fff37ffecf2008e6e6e6b6b7b73737379bcd6692245114c571bcb0b0301e8ffff11fff314912a65f6767675f7ef9e5fdfbf7c7e371a7d3f9f4d34f7ff2939f308522a28d8d8df5f575dbb67bbddeeaea6a18860f1e3cf8f9cf7fbeb7b7c7755aad16c75eb26d7b797979757575381c9e9e9e2649d268343ccfbb7bf7eef3e7cf9bcde6783c3e3d3dbd76eddafafa7aad5623a2d3d3d3172f5e1c1f1f73b05e0088e3f8c18307cf9e3d5b5f5ffff0c30f6fdcb8312b0d1d1e1efee7fffc9f0f0f0fbbddeead5bb700208aa25ffdea579f7df659b7db65d86e46f71e8fc7fff00ffff0fcf9f3b5b5b59ffce4274cad767777bffcf2cbbdbdbdc964628cf9f8e38febf5ba94f27ffdaffff5d77ffdd7ababab376edcc8f33c8aa2b5b535deb76ab55abfdf7ff2e4c9b56bd7daed3653cfdddd5ddff73737373904e76030f8f2cb2f9f3f7fbeb2b2528d8e6ddbad564b08b1bebe3e3f3fcfa15838081e2ba798fff23ceff0f0b0dfefdfb8718388befaeaab274f9e341a8d959515963479e740c4f1781c45d1d1d111e3d6d56a3596f24e4e4e8e8f8f8f8e8e8e8e8e58658188878787cf9f3f7ff6ecd9eeee2ec73fe623a9e170f8c5175ff0081e1d1d6d6c6c70a8f6478f1efdfce73f9f4ea7beef675956abd5e238d65adfbe7d9b1745b5e898b9cef2acf469a5df8d0e6b7655d005cba7b2ec8a06aafcf3bc72a5c00298d564550d560dccf24a330f28cf1138f11b957f998b777d4f1d16cc1cfa54075897d487a23c39eef57a7ffaa77fea38ce2cf5c1198300bcb24fbc722c2eed10bf71b05ef98157cb5f79d71b6ea9de99b7130e912b84e06022acf5fff2cb2f7ffce31fffd55ffdd5dcdcdcd3a74fc3305c5e5e0e82801168992142449eb5bbbbbb2c1e2e2d2db1ddd9dcdc9c94f2c58b17ac16f13cefe4e4e417bff8c5c1c1c1ad5bb7b6b7b7ebf57a14455f7ffdf5e9e929fb8adfbc79f3f4f4f4abafbe7af9f2e5c2c2c2fafafaeaeaeae6e6e6f5ebd789e8cb2fbfbc7bf7ae949259b98585850f3ef8e0f6eddbad568bbf4b6b3d994c58ae69b7dbb3ea70feea288aa6d3299348004892643a9df2d1d86432b16d7b616161676767341afdec673febf7fbebebeb9b9b9bababab83c1e08b2fbef8ebbffe6badb5effba3d128cff3b5b5b576bbcddcc7a79f7efae9a79fe6793e180c0e0e0e4e4f4ff7f7f75756566edfbefde77ffee7dbdbdb0c2cee38ce8d1b377676760683c1dffeeddff2219deffb376edce0e09bd5ac03802ccba6d3298be14288344d59941e8fc76b6b6b9f7cf289e338f7efdf7ff8f0a1e338dd6ef7f8f8783018bcfbeebb1f7ffcf1fefefe7038ecf57a1f7ef8217b833d7cf8f097bffce5fcfcfccd9b373dcf9b4c26df7cf3cde9e9e98d1b373ef9e493c160707878c83146bff8e28b344d373737ffc37ff80f699a8ec7e3c3c3c3300cefdebdabb53e3c3c3c383888a2686f6fefe73ffff9e3c78fcfcece8220d8dedefef8e38f59bcb87bf7eefffedfff9b8858edc582a431fcbf22a3c9683e33fc9d9d125ebdc4d7012e732bafbc0b2f851f631c94f3bc2a810b3915607baf7b8dd936e10a13f196797557c5a140a9cf82f25c7fd69c842f2d2c2c70400d3ed6c5f26c9195d02c52cdea7d67896075323d7b15678c6b2a7b858aa654ed5734f1d258fcc6819efdcc4b3d5971be00c0cb603018eceded31c62ccb2f0f1e3cf8d9cf7eb6b7b7b7b8b8b8bcbcfcf5d75f3f7ffefcfefdfbf57a7d7171b1d96cd66a350ef5363737f7c9279f341a8d070f1e0c06837ebfffd1471f7dfcf1c7a3d1e8f0f0707777f7e0e080d7eacb972fbffefaeb5aadf62fffe5bffcf8e38f01e0e8e8687f7ffff0f0b0dd6edfbc79f3dd77df9d9b9b6b341a4c533a9dcefafafaad5bb7de79e79df178fcedb7df7efbedb7abababb76edddad9d969341a7ff1177fc183c2c9b6ed46a351afd795526c07d768340acc80190e9a0f0d01c0f77d8e3ace3a9776bbbdbdbdfdfefbef0f874396bfae5fbfcea24d14452f5ebc383c3c641279787808007c0429a57cefbdf7feddbffb777ff6677f0600bffce52fbffefaeb6fbef9e6d9b3675b5b5bfffedfff7fed7df98f1cc775ff7baffa98fbdafbe2ee724991e22d8a52245bb66007c6d7b163c346022301f26bfea2c04002e41703410e20010c044162c4dfaf115b8eed28b22e1ee2b15cde7b5f73cf7457bdef0fafbba6677697a4244aa6681616b533d53dd5d5dd559f7af7fba337de7803006eddba55abd57cdf7ffdf5d7cf9f3f7ff5ead5b7de7a0b11474747e7e6e6e6e6e684ba8198ed48da97887a370882d5d555b9e8b973e7befef5af03c08f7ef4a36bd7aeadafaf572a15c7712a95cacb2fbffcda6baffdec673fbb7af5eaa14387fef88fff5868f61ffef0873ffff9cf5badd6f1e3c773b9dcf6f6f6eddbb7abd5eab7bef5adef7ce73b00f0cb5ffef2c18307b76fdfbe78f12211bdf1c61bdffffef701e0c18307fff55ffff5ab5ffdeafdf7df0fc3706c6cecb5d75e13a95ca3d1b875ebd6cececec4c4c4b973e7fef44fff5416d1d2d2d2fffccfff4c4d4d25179a4590c41405c7b23070a0aa08000c466e3183c5ec29c936b10a215236bc0c002a152aa5acbd094706231a4056bb88781524881a6696960196d0f4acd1fa5a3c8fb4d6b1c59379521456f2b7490d5ad2c007127c99050899a6f65716533896d90d7c4d5ed1f69004ac6427f668127af6eae32c7dc40921e0c0a5f792601c5b0c59059948916edebcf9939ffce4fcf9f3f97cfe7bdffbdef0f0f03befbcb3bbbb9bcbe5f2f9bc98688836607474746868687878b8d96caeaeaedeb871a3582c7eed6b5fab56ab3ff9c94fd6d6d6648f1d1a1a1a1a1a9a9f9f1f1b1bfbdffffd5fe14d84073974e89098c502402e976366c771262626840d8f671d8bc3632e971b1f1f0700516909011504811cb2fdc8f311de737373737d7dfdf6eddbc273d94dc2f3bc66b3d968342ce5552a9524558af0a4227193435a6b116089cc5164f0b3b3b3dffdee77bff18d6f6c6c6cdcbb77af5c2e6f6c6c245dfa21f6ea97a49c9d4ec76ae24441e138cef4f4f4dcdc9ce80ddaedb6686f8e1c39227cae5c5a7644c9a137363626ec61bbddbe74e9d2dada9a522a9fcf4bb7a9544acc5fe476643b11f34e00c8643256ccea388e80b81da4ec37d69665686848d2a74b8873cb4dcbfea4b55e5d5d4da7d367cf9efdc10f7e904ea7ebf5faa54b97de7befbd4b972ed97965679a685706667efc8101125973f63ba3af703fb7b5b7c8a6b407bbb4d6a4b5268aecd962eb58524a892628015884087b004b44ef0a008c09e140c0ea59c40931ec388ed6a1b54949c4c3fa541496a5aaf63d27497fd9b1097b285cbd491852db9fd81eec2bb44739415549bb7d3503b49e6554f71da7fd55f25e927711bfe2be9b4a7628bc86acb49d9d1d11afacadadddbe7d5b2c77a6a6a636373745bd25228f63c78eadaeae4a7aa413274e886e545aa6a6a6464646464747af5ebdcacca9544a74eac26366321999ee8ee3e4f3f9c9c9c9743abdb8b8288bf0f6eddbf57a5dec1b256b6fbd5e97d86ae267bebcbcfceebbef9e3e7d5aa4c8939393a3a3a3aeebb6db6d31eb3d7cf8b0445e43c4542a75e8d021a186565757efdcb92320280fb05eaf97cb65a10b2411c1f2f272bd5eb7137e787858446f924e45f84a59db22d9cce7f32fbcf0c2cccc8c90dbf97cfec68d1bbeef6f6f6f6f6e6e0ae92d885028142627273399ccd2d2d2ececace77992e29388d2e9742e97ab542a854241724d89be38f91eed788e1e3d2afd4863a3d168369b42ba2e2f2f2ba5447498cfe71dc71170145a4c16f2c6c6c67befbdb7b0b02089dcc56c9099459f383232e2799e68b78580dddede16c1192256ab553188bb79f3e6caca0a114d4d4d8d8e8e1e3f7e7c7676566b2d3275d1246c6e6e4a4a4091d369ad45413c40d123f6628dc8327692a490ddc663544b8a5d01227bc2de32905e84bbb156b6441886448461a810210814220641c42859c51f1189324a2962d644a44d2835c606012aec0599516a30a40c2199282c341329894c606919adc320104d330dc0317f1caa2a595bfa2809ebf6010a3b66774e8aed77e5c126d7bffdaded79807ae20443677f2e3d5b64b15b853c7f51204aa39c9f640fa19f6eb25409f46f446297606fd6ee781b1b1bbff9cd6fae5fbf6e8c113ae2c5175f1c1919d15adfbd7bf7debd7bb95c6e7171f1c68d1b737373621c70f8f0e1959595a5a5a5300c5f7ffdf5a9a9a92008363636d2e9f4ddbb777ffce31fd76ab5f7de7b2f9d4e1f3b766c6565e5bffffbbf979797257076b55a1d1b1b3b7cf8b068e26eddbaf5b39ffdecedb7dfae542ab29fe7723959931cdb4fc84a68369b4b4b4b6fbdf5d6d8d898d8fabff2ca2be7cf9f1771d8e2e2e2d6d6d6891327ce9d3b275498526a7c7c5c24d6f7efdf17ed0133e7f3f952a9343c3c7ce1c2859d9d9d5bb76efdf0873f94e776fbf66dd775457c6e6d1a8c31360ea5b4e4f3f913274edcb871e3dd77df5d5c5c0480f1f1f10b172e94cbe542a150ad56ed6b62e656ab552c16df7cf3cd4c2673f1e2c5c5c5c5b367cfe672391ba4170086868666676733998c00dfc0444a446d5249da6d7676360c43d1e47ef8e187aeeb361a8d858585d9d9599b17463a915455d7ae5d7bf0e0413a9d2e140ac698575e7945e8b8dddd5dd7754f9e3cb9b1b1b1b8b8f8d77ffdd71b1b1bc2dd8f8d8d7de94b5fea743a0f1e3cf89bbff91b71c010abc0af7ffdeba3a3a3cd66f3473ffad1fafafaf8f8f8c99327272727a7a7a777777765de722c1849ba4f24d7a96cb0c880cc3040612566b6b548e8b5d8da72cb49f18d453d4424d261180196522125c26359f8544a8976cf9888b6e204e16012660d318575306049f62cc38811f325302a1c28117d4a0a4b50db3259499a08635b278b059c6089077a80040dcc096a08f69036c916db7f12c82cf44bd4560b43c97b8444f48fe415a19fc5b3e311be69a0074b613d78f0e0e2c58b6118bef0c20bafbdf6da2bafbc522a956edebcb9b6b676f9f2e520083637373dcf93f5cfcc954ae585175eb87cf93200542a15d9cc0f1f3e5cad562f5dbaf4e1871f2e2f2fefecec9c3c79b2582c32b3c8ec857c90553d3d3d3d3c3c5c2e9753a9d4bbefbefbe0c183b1b1b14aa5223c66b158945c4dd96c766e6e4e6b9dcfe76bb5daf2f2f2bd7bf7565757e7e7e78f1e3dfaf2cb2fbff8e28bed767b7575f5fefdfb1b1b1b2b2b2bed76db6e278542410816a5d4d2d2d2471f7da4b516822897cb5db870a1d3e9fcc77ffcc7c58b1721b6bc1b191929954a939393421d883e616e6e4e482199a5a552e9e4c99361187ef8e1871f7cf081e338172e5c387dfa74b15894981cd648a5582c96cbe572b97cfcf87144fcf77ffff7ebd7af4f4e4e160a8543870e95cb65b9cacece0e004c4f4f1f3972449e987d3baeeb8e8e8eb65aada1a12122127a534e181d1d15fdc0cacacae2e2a258219c3c79726262220cc356ab4544622632323232333353afd75756569acde6f8f8f8cb2fbf7cecd83166aed7eb4494cd66c7c6c6b6b6b62e5dba2446b6e572797c7c7c6666667676b6d56afdf6b7bf7de79d77aad5aa78081c3972e495575e29140abffef5afdf7aeb2db1231d1b1b3b75ead4d1a347bbddeed8d898403c114d4e4ebef0c20ba3a3a389296ad901f98b7d09f76eb6c644792a10fb6639335bffd0bd8065b942410aa5486b4364749c913006a9882eb3d0ee38fd80c50068a92a0508ca2804305a0d0016529caec33082f44cc668222d1fc435cfc45645fbe1f227916151c21714f6583f33b3f897d46a3531bf16df88011a2ae9f065694fb990dc3bc7f22cdbbf3c586b0b2a4b258971727e522e2017b2b76cf168afc536c69613f2beec2624dab1542a75eedc3931bc1c1b1b5b5858909b1a1d1d7df9e597c7c7c725f72d004c4c4c944a2531ed191e1efeea57bf6a8c2997cbc29ee772b963c78e954aa58d8d0d8938383e3e3e3f3f8f88afbdf6daececac184089a25d6c172726262e5cb8303434d46ab5c4db5c3c6c64d1b65aad542af5eaabaf4e4d4d89b4be5c2e8b6d84380988c500221e3d7a5498116b5769b15b56e3dcdc5c1886478e1c1169941092c2750a6504b1d05d3c57b2d9ac1876b4db6dcff3fee00ffe40bce7e43920e2e4e4a4b069bbbbbb8838333323b6f8afbefa6abd5e9f9c9c14abced1d1d13367ce886f16337ff9cb5fdedada9a9d9d1d1e1e7ee9a59700606868687373f317bff8c5fbefbfffb5af7d6d61614168498c9d1099f9d0a143954ac522a6f42cdb52269311738d63c78e398e33363636353525a9da73b91c2266b3d96eb75ba9545e7df5d543870e55abd576bb5d2814c43f5f70cd1823b9632626268ac5e2dcdc5cabd51297fbc9c9c9a1a12111200e0f0fb7db6d794d226414ba8c88aad56aa552999d9dcde7f3c78f1f1f1919913d4c862a182a0c38c66a25917ab3b1e99f8019f03ffff33f7ff5ab5ffde33ffee3e6e6e6f0f0b0e338b1a735088ec4fc6444a7c857a7bf88264554274e940bc74da5fc388f4ef439954a599d8b3d5329e5fb1e1139ae4344aee35ac07254efb3a27d002b060e896b0e44ca188d08a954ca1873e5ca47d634462c2ac55a9afb59b0c7ac07c4de7624e29f2ce489bcd47abd2e06e89d4e470cf0441ea9e330784994b18068db939494f42f22553105b627c8626bb7dbed765b30c55e45141ab250072e972400752212bfbc591122bcf3ce3b7ffbb77feb38ce5ffee55f9e397306e2946ef0e94a72f37b52c50eacd168fce217bfb875ebd6c8c8c8e9d3a71716160614ac4ff6ba9f4fb123dfd9d9f9abbffaab1b376efcd99ffdd91ffdd11f414c317cfa97f2d4960f3e78fffffedffff7ebdffccff59b771fac37462766ffcf37defcf6fff9aa63e91d8b4d4a294b6161cfbc9388949ca9e2243749c0b29f45fce945c5f57ddf75bd542a4af325da04f92ca759c01226d6753d4450ca01044739800255fbc8b05032fd495a34b042778d18994da65229a15cf6ca6be063da5e614274cdcca231100385bb77effeec673fbb7efd7ab1587ce38d37041cebf5fafdfbf70160747434698b282cf38093bda54f6d8bb8e0c964bd73e7ce2f7ff9cba1a1a16f7ffbdb7254f670b9faaf7ef5ab1ffff8c78ee37cf7bbdf7df3cd37b5d64b4b4b6fbffdb652eacb5ffef2e4e4e4c09c96d72d7ed7128d5ecc1a2726268e1f3f7eeedc3949cb266fc77ad23d9185f159a0861d58369b7de38d374e9d3a552c16ad46ecb3bbeee753ecc84ba5d2f7bffffd6ab57afaf469697986a14a4aa150cc6432ae2bfc0400447a42c70a986c890ec64ecbe2f4670dd1d59e6201cb8d8be7f9aeebf8be2f806573110a55655b1280e55bc0123f2fa51cc488dba20300ab0fbcb0c7a6d977994ea7551cd3c3d21a07498e1e52db5f5122700ac4d4ca9d3b77de7aebadb7df7e7b7474b4542a9d3871a2582c0641b0b3b353afd745ac532a95845fb66c9755e28aec53085b61df04aa6c08aac5c5c57ffdd77f1572fac89123229eb0acdfb56bd7fee11ffe21088242a170e6cc9972b92c1686428a4bf8d366b3694536beef1b63d6d6d6de79e79dab57af76bbdd76bbadb56eb55a228766e676bb2dde6a628d090042e2d97bb7aca849046fb2cc7e722d0d2846f7b2d8f6f126f79224ab9bdc276cb77b7f25d715c6ad5eaf27c9e18195605f6b928cd589503090b0b6810394b0c9cff64e93d312faf73c48408cd58f5b7f43cbdd63ac56b657b1bf5d585820a2300c452d604768f7547b77034b03faf7dde43966bfb854906005d4dea858844647e2208a9d4fec397baf9e1c61f2ad412c0f91f158ef5159fec618f197120e91122aef3e078e78c2f4be0208ff88f0b008de989842d1ea4ef6100bec070b473118a473892988d017451e9373ccb6c4b30493d371efec4ccef54f49615921b7156c03c0eeeeaef828148b45b14bec743a8b8b8b63636332b1de7df7dddffef6b757ae5c999f9f3f74e8d0c2c2c2e4e4a478e15fbc78f1ce9d3bc698d9d9d93367cecccdcd6d6c6c5cbe7cd9f7fd3367cea4d3e98d8d0d31535e5a5a921835b95cee2b5ff9cad9b3672558a0107aa2e0bf73e7cec58b172f5fbefce52f7f39954a4591cf10b5d657af5efded6f7f2b6eb1870f1f3e76ec58369b5d5f5f7ff0e0010058099408269452dbdbdb376fde5c5a5adad9d9f9977ff9970f3ef80000c4554de6b1202cc546b3c9476ab1ccbe7d8160dbc88902098cb387ecbc4c76923cd49b0dfd2720a278b7186384894e62df40e7c99a13e2484b89dbfd69009707a02ab9e47422f46072fa2517a71cd2895860f6bac97eeced1bc3008c886229e2388e047b810852238d13001aa3edf31fb8d381670efdaa2d7ba7037b4fef5e38727c0312ed16c8a8e2d42440aa97d733be2e0144bfa284e65a3ab4d782d8bc2bf9844506afb5be73e7f6e2e2cdcdad6d63380ea763e0f1e261f581c2de0236c9e17e0799b9df975646dffb8b4fb3227f460479ec5acb831bd4be335bffc1be6da477b85fdd46f404b484b64f8c793af13608c3f0fcf9f3a74f9f16278cf5f57539cd719c9d9d1d315411c31344cc6432cd66f3e2c58befbcf38ed8284974e372b97cebd6ad9ffffce7636363c78f1fcfe7f3e222d7ed763736367cdfd75a5fbf7e5d504f3667b9f1c9c9c9af7ce52b1f7cf041b7dbbd7dfbf6850b1788486c3bb5d6dbdbdb1f7df4d1fbefbf2fb1d976777701606e6e8e990b8542a9543a7bf6ecd1a3479959cc02aad5eab56bd76edebc29d931969797c5f7757b7bdb1893cbe5cae532336f6e6e361a0da1a92d892d6e71b2490a70a8382deec0fa79e864fbe4258935fb96e45449e2ddbe47932d039f9357dc7be6c0159363db77ccfb5e6bcfaf58ebbe740fc9df02088c420c7366a09f646f9cd82406e8b2fdaf6eaf8251c2b1bede8093e7631f3db15765b7cfb5063ecbe20ac3706767bb56ab93721d27edb808480c88480ef73cf56ccf9c205ec80e722f2e58fc014011e6326b6665c3245854d23aaa950266308645871817d13ff6f270c4848cb4ecbf65d927921c589202eadd4f7c87039f3f563d481bc79e999ee7490412eb7126dae27c3e3f3f3f7ffaf4e93367ce18636eddba75e5ca15cff3767777af5cb9e2fbfe9b6fbed9ed76d7d6d69697976fdebc79fdfaf5a5a525a594c4e8a856abebebeb4110887fc6891327befad5af9e3b776e6868c8de85280d8bc5a2d567ddbc79f3d6ad5b12b8f6c183078d46636d6d4d54d4621e79f5ead542a150a9540e1f3ebcb1b171f5ead5dbb76f7b9e77f8f0e1f9f9f9a5a5a55ffef2979b9b9bdff8c637440fb8b1b1f1f6db6f0b681e3b76ece4c9935b5b5b1298b0542a552a1544cc66b38542617b7bfbc18307ad566b7474d4f33cd16f888929c4444492d8b113f489d4034be271fa4f2eaacfaefe6457897f6530ce71144f6cea9784c8ce6d7f35a81d1a00ac643beed123ed3b66886108e20c897182716004038c367d121b0421ade44c64eee55978fc7b27525a87b95ca65e6f7643ddecb06ab40c9066340062e3d3e3b0fa49138c9b70b0a9476ef4869410d5430ccaf6e158b6b11777d47e8d636389741fad282d8ee9de17b361a0b6f7298513b43751f2429f8ac2820483603f341a8dd5d5559129a4d36971e36066b1ac29168ba74e9d3a7ffefcebafbf7ef7eeddbffffbbfbf7bf76ea954dadcdc5c595979e59557fefccfffbcd3e9fcdbbffd9bf86d4874214414a584957675bb5d443c75ead45ffcc55f483036610a6460029a2323232fbdf4d2f8f8f8d5ab573ffcf0c36ab55a2c1657575725f4da4b2fbdf4877ff8872b2b2b7ff7777f275ea9b3b3b3b95ceee6cd9b8b8b8b57ae5c91885dc618093050a954befded6f8bdffcf5ebd777767698796666e69bdffca638b55dbb766d6565656c6c6c6e6e2e9fcf8bbbefe2e2a2044890f82a1253e9f0e1c362d320312af03303ac67b43609360212f5412dc9f39f10e032c73904e31a18300223012c60a905b0fac6061fe75af1ae46c6e86a75777d7d63757de3fecaf6da8e518e87a4909413fbd945703350f851043c274a4c9dc9879e5321f7954856dd23ae120e74033291817adfb2ef697bc736d0c9de5f3db2b63fb72654a2bfb3be26825f41102c2c2cbcfaeaaba954aa5c2e4f4e4e0280f50e69369b62a595c964105138afb5b53509d12b0e109231ac5c2e8bb18c445c4ca5523674a44938248868697c7c5cecb97ffad39f5eb972a5d16848ac25395f947de3e3e3beef4b0c0071b89b9b9b3b7efcf8952b572e5ebcd86ab5c414636b6b6b7474746262427e9bcfe789a8582c9e3c79f2d4a953e2fa9b4aa584851c1e1e9e9c9c3c7bf6ecfcfcbceffbbffef5af258e82f8738c8d8d9d3e7dba52a9d4ebf57abdaee2d8eafc8400cb8a8d6d7dd0d18176bb3c9267f696683ff5913c3a70c57dfb79fcf10c30777b47c2cc4460cc202595b80b12078fc44860df7e1ee7de0f785626022c4263c01a3f0a309908aa9822a0044e8cd63023d9cc83208e28075d0be3c8c80258dbdb5baeeb8506aa0d9dceb4552a25168822c34a42d0c3e55907168c4b426a8e315f9d24cd06e5f30715f8987450720c7bbf265b3e59cf49d812d2667575f5f2e5cbc22ea5d3e956ab2584521886274e9c48a552f7efdf7fefbdf74aa5d2ddbb773b9d8e387c1863d2e9f4e6e6e6dada5aa7d3595f5f17dfd4a1a1a17c3edfed76efdfbf3f3a3a7afffe7da18f52a994952ecdcccc882ed592a24110b45a2ddff76766664460b4babababebe2ec1a18ac562b55abd7bf7eec2c2c2caca8ad85e5a3f35c771262727399649196324483c007cf4d147c78e1d23a29b376f4ab85471eb65e6dddd5db10b15e72f66aed7eb122a575c67c5014d084f89d42c4eb676b57cb209b6ef94fb9490f7c5aff7a6867fe25789a36392326c1095052c42640b40167492001403163ddeb54c1cca5d6b4d88cd666ba75acfe61ae94c1d5d5fa6f7c78b87357032735f83c8ce8db11992fb4e33c64822426374ecdfd7a3c230211eb29d72428380314d3150e0f3a2b0ac22438ab039beef1f3d7af49bdffce6a14387c2302c140a3ffde94fe5e8fafafa6f7ef39bb7df7efbf2e5cb88b8b1b1313737373131914ea7efdcb973e5ca95eded6d49a0204e73ccbcbababab9b9f9cffffccf4110dcb97347228b0a65d46c36ffe99ffe697676f6ea1fbf800000200049444154f5d75f9f9d9db5a392709aad568b9973b9dcf4f4b4d6fac30f3ff47dff7bdffbdee4e4e48d1b37de7aebad1b376eb4dbedcdcdcd9999996c362b03585b5b93e8efc2df4940a8d5d5d5e5e5e51ffff8c71313132323232b2b2b128ac4dadf33b398aae6f37966fee8a38f2e5dba343434242a4bf1dd534a5dbc78f1ca952bd56af5d4a953c78f1f17924d02633d41cc7accf2bb8695cfa8367b00ebb3a8256b8e01c9050d64980909a27cce86485ad0b0414bf7b111c0a21e9c3d7ab4628d28eeb75a87bbd56a369b13c3c0307225848f170feb80c9203dd83f883ff4ece30100fa7352c8bc4d5e19fb0b3c6514d6deaf1313135ffad2976667677ff0831f889f8108a1d3e9f4e8e8e8dada1a332f2f2f8b93cad0d0d0e1c387a7a7a7cbe5f2dadada071f7c70edda3563ccd0d0d0c8c8c8c4c4840460b978f1e2d2d2d2eaea6aabd59a9a9a4aa7d3870f1f262271e00ac3f0d4a953b20b21a2306bd3d3d3a5524972babdf8e28b67ce9cf9e8a38fc4cf6b7a7a7a6464e4c68d1b972f5f164f1a8963b7b2b272eddab54b972e890f4a3e9faf542ad3d3d38ee374bbddb7df7efbfefdfbd56a55e2404a646709ab828812743c0c438942b5b6b6b6b1b1512814262626161616ce9d3b77ecd8b1ededed7bf7ee495c3a0977277c6eb3d9b42ed99f67790ac0e58b5b0b9b69e186d83021d914f3143389fd8015515802559f00b01a0d0963ef4b680d88dd640fa4b0a40bfb39d99e2c101356dcd309f6c453f6ab24761647c3c4096083cf60ac1914cb9d7e94e9cd39d843fbf4df33588314d82f36f9c0e7c7acf7ea07c522e9c48913c3c3c3d6b317004e9e3c29948844bf9440bde274562e97a7a6a62a954a3e9f7ff5d557272727c5c4bc542acdcece0a2376e1c285898909b13e078072b92c40268ac8c3870fe77239f138938288e22696c9642438c1c4c4c49ffcc99f1c3b764c2261964aa5975f7eb952a9349b4d893935333323e4d297bef4a5858505c77124a196409be33867cf9e154815f308d131e77239712b0380f1f1f16f7deb5b4b4b4b12ce6d7e7efea5975e927031e3e3e3e21196cd665f7bedb5f9f979441c1b1b935c090060b3397ccee52958f65fd4da302102f4d83a6264448c6a662244c348884c48285418ca128e000b29fa78f0551226ac288e372ab25117317c4cda1c6c87956cc4feb2b73d21b1da575c653f58f14bf2eb60c144a21d0020ea85ee7b889630ae07d579c961273f3c7e9d1cab7dbe8ee3cccfcfcfcfcf43ec044e448542e1d5575fb5cf478264da222823a2259b6f2a79c876b8b74c4c4cbcf2ca2bf2d9dafb21e2dcdcdcdcdc9ced249fcfbff9e69b6fbef9a66d3971e284c4234f160995b9f72ac6184938b6ef1864b3191a1a9218be3ff9c94f3ccf3b71e2c4f9f3e76d7c71d97b7cdfb7a1f2208e788bfb395d7f6e455ee2d300015fc45a0c26c03052246e0764c4c8ac14819190b8e7de0b51332022323d4486651216f076f90380180e6012500891624b77d8834a1803d3def681131e7ad6e0828f4124c2a3388a83fc45111d304efcabd4603cace4a8f6ad931e79145b636bad8dd1ccd172fa845b4d4cafa1dd5830ba561c088c068282ef5d33bc1f310b7b84830f2fb1bd1f03f42080e3a872c9f7927c628fd3edc3c71051c5000030343474e2c4895aad76e8d0a1fea82034e01769c7267bd0e3dfe6132f9ff8d53ff5b5e4bbb3fac468e77e22260edad201a20184fe45c13190018201626003486012471998e1115749da60cacb32ba67606040a2061b63e361c1a081425fe18359421b03cb9828b60cd900a33a0cc3c84b4822ccd8560129ec859189464c89b42e88e838c97858bd680d711dbdadbee71b2f0c48f84028c711320d626f807ddfe8c3a73b11014450153dd3f8818a49b77deed2125b6cb0527db997e5015b858e6d971f5a5d6fe2a2d1b5ecf86d94b8b837e644a61ccb5353c25093634b027ba1e47892c3b3b035303124c45a727abcf8e28ba2d61156d10e95e210e3b64f44b401761efe903fd3f2bb8695275e5b9d60b404109f64ff496da016e68e44b89e5832f259310102322132441c6044732544ef0fb9169192e966b73a2ba88d662c000302a06341240cc320086332247ac152c761f9284684c8a224b14842638cd804b9ae2b1a34093920d1afbb5ddf75bd74ba232165c4ed596ac7717ddf2552ae1bc56cc098c29295d98b8d057df0b497250440ad432254ca0560c9e628d124ec5348dc57df3d3ece741f38d3b650c2fbc41af7c64707cdaf63c818ec24d13f5a9b38dbe1de110e8c67efcf07b0092079264af869eea7afa127bc8381ce93976366716597a309d20ced50c5e32cf9dbc77cce9f6949dec5335123f6256779c2fd238070680a7a6b465a4c7c79b9320000c535da1ea4e171aed51bbf943e6d32cb8c056688f66acb37191339524282cd1bc005bb81dbf52f6091008e68ff37c600b0311a40ec2dd9711c8955602316388e13860255dd01c04a401524afb51f60456bccca5098b9d96cc825c4cc9a99e572c61842e484a3f9bef0f7f8b57d26710dc9a7947c26b01f9b36d06e678bed196217adfdaec53140588a0684c0b42dc9a91077385806dae5f4644bb2b7bd2d71ffcc3c686c7cd0153ffff2c95eee5358c793d6d6c61896974e89d8090f15f526fbd9df7c54cc17222b2ac310534f91c982893f93e80429d2064a046161808c4124368071a487878c01633e4cb67f6d34b3418b4280224772acb5012263cfab066300eddb66fbe5503daf60fb756ff09944141a65c366d994c536781611398eab1446e1651c85203528a580819412635906263ce0fe01b5d18494c966b4d6caa176bbb9b9b9b1b2bc9c2be4c3209027c20cc2a649bcad47bed72f742d04d7c38f2669baa7b83cec469ed1ba47805869431fb8d8651f1b0d109148b2ac053c4541e270ef244f8094dad74a9e5045460c723e4436594468741cf29748338bed955c51011a630801d8101233c0410b36311200105d9658baefeeee349bcd3008800d20888927b3718830fe8b84df328311c96e9c8247aa3fc89f85a764003f0b40b6f67d898d95f27dd7f753e2252721b192675214b7843ccf4342c7510012ce3c062c22662045008fd83414a974261d8661a1904ba5bc6eb7b3b9b9d6e9b6854b4d9a2600029b6716aa3e2ea87d7c041964363fe3f2fb095822d58dec75f682ce9e9a8ce9d192b130fe618005115dc63820a4372cf4112119602430ac118159132118012948d4910e91108dd108001184c580b5df980100e3e03ccc2cb260adf5eeeecef6f656a7db460424e418957af1b0b08f4f616696de60a095990fa6f063abab7d4aec35b8b768634200650c01b2361a7b37d21b541c3bcbfa2a0eb823d9f0406c18bbdd8ed63a97cd8e8f4f681d0641d068d4adae300cc3200c24977abbd531c618ad01419ec9ef7a8e7e1e7582aa42000646401e687b582def2301249f04b21eff72319918c70be8d54fc3c3fcec5e9031801825be63d6c0c0609008aca79ed815444f0465290b6041c4d733221b362832873848afbc360129005488860110fa04f9c61044e17c351b4430a091806327e7c89201081891941860450491b08d60e2e945620071d0fd9ac8b854b23a3003b73b9da01b1846119443d718c3c6c6c3b2d890c0230360856e115a25316b3f4892b5afad603e894a92a310512b15a5a5c0583b400a890d1210ab58d82663886e097a4aa83e3bac7d018bc804419799b3d9eca14333e203cccc9ee7ca20bbdd8e366137e8d66ab55ab5d6e9747518c650f854ccd7cfa6068cc3b13d33257953bfebc7fb59039601000613bf4afb4219008001053e8892478135209b58c1828809c01230020010b000ebc06c1dad6563c228b795022602660d911489d8000031038282c834d4887c1c08351879490478106045549e48664c2ccc8d9859954a67fd949ff2fd7a274024c0037c09992d098676f77c3860ed259c6cbbd6466ba394d1da10690b6a8a24f72a46527943d6540aa374aabd2c551011c683c3884f33cc83ae88aeeb168b6e1086466b916d318031a6dbf548a96e108441608c715dcfe890237b91a762be7ee680d54fa9f4cdd1c7affba8b2c72c9652fa04b7008332377c76014ba6a291c91fb50be502bd70c3144f78006390085129e548bb310c6cb40901b43106ecf3115bad48ae02001cc396c531d15f598864227201d2842eb31349d121000808bb8643c6403300818ebdf008346b8360502826430c6c1e26c3829eee4ed85e0406e5389e9fd6647cdf775d50a4009e802f61ff7c8c7bdbdb273eac908d1d2f727c8a2cf40920321a1031f9be02f2f8295b4bf4f828716c8485b12b13307310049ee7bbae9bcd642a95761884c66878b666fce7517fde80f5fb5727a4510c2ca06c8c09c300115d5722bbb2312cfa38008ce9328885ee9a54648420fd24b581f24a447e0409cf108e910c11888d03ec84614a1ba7ab5d06650c1076103a2e05a4b4a3422446a50d9240164227ec8660c851aeeb823160981361701e025518db6d45900d045bcd4c762bd546c7759452118565cb7e93ccca2df61c60e67e5b47db4f423e25d4569f60abef9819489b1a114ab6378cac3f622eb107c3c9704291332333cbae0300861913a4226224022122dff700b2beef75bba131465cd21fc7c2ed8b5dc71063a5569fbefee480f524ea6715fea2f807d6c118ed3da2d161a7d306807426934aa5c25087a1610636d4e9745bed56b3d90ab4668694e7fae95c26e3bb0e91c4a502bb5a7b76424110300383719423ca34a30d3023b347e80601b59aededdda0dee24647858ca16642f2542a93cae6dc949f55990ca6fc0095063288ccdcecb634b0e3bba9748a8d31a1616d48593a23117d4ce471b1c89f88746c180188da4080d55c7eddab858a1422f459baf7a6d57e541226cae3cccdbd20f8b0dfed17272bb6ab887fdcb34eec333c13bacc02ab6d47ee2b446ce3e44bfe18dff7b516f6feb30824f4f4d59f04629ee6f2cc025624b4ee25368f580704d43a6c351b0090cde532d96cb71b84a16170c210b6b676c26637308a9180085c9ffcb49b4ea57d2fe52914d34e360062f410799548c20e638ce3ba8e528ee39850a331a4752ae83acd96deadedac6d75366bd59d7ab71986dd90914387dc6c3a5fcaf9c3e5cc70393d54e6425a6732da71b4317edb0bc1789954269b31dae820340700160f40b3052c6044d28cf54065b239c76d925244ea21322c807e88e183655807b5c7651f0157af6664164fa13e3a0b11b5368851a064139953e3c0b5e4eb5ed95672c0f16fad5aa46747abd4d3303b9f03d6272bcf3660416cf78484c492d51b50eb90c310107cdff77d0f10954220bfdd319db0da09949f2de78a05e52806a34dd0d1ac0ca41d2fe53a9ea3645584412873408c9998d968e3885d91eb8236146a6c3655b5d6bd7933b87b9f6b1dd381edcdfada76bdd50e0d9b406b87b898766b43f9f1f1e1e1b9e9dc91b9cc540a324ec0a0390cc0f8be9ff653469b8002930876c26c92f22c42e284f6cc18639947cde8b99ee3b8400e2301e0c7cb9a2325090ab0c78a9af7e72bfb7bec45223d50b665cd5631414fd928ef723f109990c8d1defb86d8cc75601e104987510bec4927f714ccd4275c3f43f0f438e599b1d5424446b91783888a010989008049450986a362088154c8dc0e74c8942f5446c62798b95aab356bdbf566abd9ecea100ad9542ead285a594a516ca525840f488e647288481bd56ae995d56071b1f1fefbed7b2b6df66b5e61bd1edc6b04012a47b941d0d1f5c6f656b5bab6b9757f757a73672a0c4614659c09954eb71dc58c8a94434a3318a5e28cc8f1ddf5c4ca4c482ccb92e57f64dc0088c048a40015a36254f871238e0e144e947d2dac920ac3d8ba61e090d686b436083dcf61a1bc109199600f650731b5659d6cb99f9e1aa8072009ac7ef779795e9ede8200004cb2b903a0c85fa3d07391e55bf4171a1d869d763b08822e8341c0a01bd46bcd8dcdcd5abd11e8ae09bb1b7ebd52ca16733987c07755219b2a64538826e440120a3244dec5146a556bc0dd079d4b973a972f874bb7bad5c646e8df769af754b6962da4462ad9620e8d69566badadedfbbb3b5bd546fdce4aa88c47da778c3335ad224172345e3b5ce8ab637bb0c482c558f2230a3860444406b0ee6e9f444bb8f7fc01c84be0d840e3c0c91cc9c4a127c302d887ec8a2fda476d3d66dddfc3fe353fa7b09e91f2cc50588c881899200022311914bf6220204240524a29879461d09d4ea7ddee301ba51058775badfaee6eb35a379a0dab6ab5bbd9ad6d6d357299aa02934f7b33e3959472522949e98e0c800608954bca09ba667b27b8733758ba6556d6546080bcdd467bad1334f294199f1a3b323fb530ed6752cd667b6b7d7b77794dafafe8d64eb356addf5a2c96b3aa50a46c3ef68b41911e03889650961b21c68cbcd4f13ab55485369a001015115122cfd6c328acd891f520307aacd2474c694da4e2e03351201aa529a92b4ce60a36911ba74807d9a26c722470306d355027cf17ba0c135a5e8801fe19ab9f03d617b42624d6000826b20e14371ac983c0081047f48530349d4eb7d96a77ba013022b3e750319ff11cd240cd6ed0ed74abd5c6ee6e93409ba0534abb41b34ea047460a7ed64324d6c61803463b4cd86a35561f34571f00b23739a54b417bab1634579c46b3d8ad9731982967660f4f67474b06b0d5eab476ea9db5757cb0e4debca89bd5dafdfba632a247d1c9e7149331ac4554ad636bfbbe3b0536067a09be50166a1806ad76cb18f6bcb489739749795c0a6b002692ebff314a0f2b1e7ff160a2c45f3f1e6d057b24597b8f26fb7f26ebbd22c867bafcee1ff893a9398ad162d3be7324f18d672dd8fc9e048c41c0ddaed61a152960f03db790cf1a631aadcef64ead51cc355bede5fadaeed666b75e6be4bdb40fc323f9622593a23431a00e115921780818741b9b1bd5da6e7e78283536c52d6316ef72a3ebedd65473bbb4bd925b7ba0d6c7d807279f2b1532e343657f6186d6c76a59d3b876a9be5bd5cb2b9e97f6737947b9840a7af4d3c09d32223002221089d1253073a7d3e974dacd660391101d0088ee14101f4e6109d040221bf55e02cb243c071f2ac6da5fb6657a7973a2407db62b18cc02dd1b41727c49c9d4a7a97b98faccd5bf4f1416c8cd3e0d8ffd53d586198dc01618c384060c3002880d2613f4d2aa87a169b582565b6ba38854abd5ae376a7eaa44c8db1b1babab5b0c542c66373655bd5e6fec6cb9943530aa3c071d47725cc526919a35e976a7b95bab359bdef0889a3de4618ac1addebabbd1e938f546eaaebb8a7a636d359c980a8647a1501c99183d3a7f68aa3c929d9e6b6dacd7d6d73aab2b8542313331e100264d306d88349b2b1e1229c165a5773a9dcdadcd46a3ae880a85a2e338c6b48d31c00c6cf8e3cbb0300996d10479687954770928da9faa8a2ef5196d650fa7bf9e81fa3985f585ac459d6d801080c09008af101050dc7240429c13213150a821d484e43162add9a1ed9d74d6f595db69d43b8d46b6544ee7b35bdb3bebd9347453c562ae325c2e0f9753993422020321461e7dccac8d0eb40ed928974aa54c71b8c4aab8bcbabdbdc3cb6bc6f0d6f5c5dacddbbb8591edca443d5f2ccf4cad9e3f757e7e7c58bb2a5be6cdcd76a39669370958291191212332a19561c9ca965aa9c895c518d36eb71b8d46a35eef763bc5422197cda65229c2aea819040b3e959650ca1e8c7a1459d5af31d45a321480523d7a2a495b8929837d97495228098bcfeb83eae714d617b1660066466603c6301a6064048988c42c69aa801918d8a031a80d19261de866b319ea76b19cce8f0c1d9a192917f3e0a61b9a2be5d2c4e458504c4d8c1687472ba9ac8f0ab4d6c6ba2c0a09a40d3232288d0ebbbe572e4d660b6e3e3d7be4c8d6e5ebcdeb37ab8bd7cdd676a7bd4e35d3f277eb9b755d6d766f8f9d1d4a8d05da41d509834087264a3b2a1496fcc3f8b60c4014bb584ad0ed369acdededed56b30900954a259bc9388e629b1b305ee94fd29770df7e1298122f9fb8d1be977dbb4a1259b0df4694b4c67a5e3fa7b000e0d9a1b022091683444026b1384044e448e12f14162822898c49a419380875bbab1983ed9ddae850697e619a403d58afdd5ade2a978bbebbd06dee16324ebe90550e326a24408508446c226f5ea55ccf7595a342c3cd8eee847ea17ce8ece9c9f9e39b2f2ced5ebc54bd3cd5b87d676b75abd20833ddeecae6d646b3717de5eef8fcf0f8482a43caa43c27950692807a3df1537c77728b71345044a375b3d9aceeeed66b35662e168a95729908b5d6402129222288fb782c0acbe24292ace9fb9228a6c7b25aed609ff9d57ec1678c68090728ace49e13535bbd780c72c29392613dc3f5730aeb8b581b00000300068c0134ccc420b15c62c24ab3d1c840088a8088b50eba6168005b1d7deffe46ca73872ba542caa9d677d7d65732b9c2f8e8ccf6badb6e6c07413b0c3aa10b2acac10ec630233021b884be430aa9d50ad7d61be0d5b2cdc077336e3a3f397678b8688e1fa95ebdb1faf66ffdcbd7f45a15baaddd0e795c37e9c0b865bf9c8272d9cde6b4c42b57145147868d449b01d43a024745d4ed76ebf5fae6e666bbdd765d2f9fcf29528d46230c02522a9d031b7e4bcac328ac47125ffb02962d7b4e81fe438f28727592348af09c927a4e613d4ef9dd3ff02753132062e4df0d8884c842ae10232b248488082362d78574da49b555bdd5d6a60b883ac48dad86a2d5a1cad0e87069737b2b089a4395c9c9b1310e6af776571b75d36a647d4fb99ecf0c3a640042724139984af9a5623697769ab5d6d2d2c666f396cade6b7695ebcecf8cbd30379d999c69b64d6be9ae761733d09d241c759c2152a576155b9e3f594e8f4f9a7285890c18878058b2b1f6a29b02282198b4d6f57a7d7777b7d56a398e5328140a857cad56afeeeeb231b97c9e90004c445ec1a3282c660660798689737aa0c331190571ac514b25f50bad7aba409158258f5a199684b990da24fc0a8509966bc72dcc095baadff966f894d7cf29ac2f6e8d80465e2273c4211ab681ee988d3621a9309b730aa1bb530dbbdd7abb1bb2c120a4edddceb5ebf77676760d9bd9439373d3a385ac5f2d64b7d27eb7d3aced54339e9b717d03a8b5018d46a98e21d7cbe446c7d5c656f3e6d2e6e6475be5ea667ae4da6af5fe6e3d552c4e4e4d147319b5bbddbdb3a66b6d9f4d99b884c1900eb2adc0840595cfa7c7c65a857c17d9e810d9e138a9a044f32342d77501b8d96cd6aad5ededed300cb3996c2e9f03c0ededed7aa389c0d96cb65028787e8a4d4d6b0df103f92432ac47524949aa2ad93850cbff44acdde8c3de212518e0befaa0f6e7b5ad9f53585fe45a04409145b8585eb1501a0022010234cae16cd6d190dead7bf53a76bb3a34a4c8ed7679e9d6caeececee4d4f0f46425e7f9413bd0dd2e30eb50079d80353ba89898a358812a64e5f899dcf864aa5e0fd6d676b7570cacfb6df0376bcd075bb7daf7af7fb894cbb8050a53f59d8281e9b49787ee188595b4f28b696f74c81d1b73872aed744ab321648cadc544641571bac0611858da2a954a158a856c36bbbdbdbdbdbd6d982be572a954cce672402e6294c84ccaa36558823007815a126e92c5d24f7bb5843aaeb4d15a6b65309661719238a338a92709fd0b0089d4521c8bd598adfee1a930507eda6a786ee9fe85ae0998010c3033a3ac108ea3478136ac8d660e156136a34686723a0c10607bbbd56875bbdd30ec761b55a7ddea988e69ed368d0e6f2ddd5c597d90c978a343152265b401963f3446b3e6d021cae59ca9c96cfd68c771ba2b3bb9f5bb871b41214db5b48f7ecaf79cacebfa79ca5554a1b135d4a91690b2c395f4c242f6d4097766264c6703646dd8e94565e9614c1004bbbb8d66b351abd5b5d6e94c2693c974bb41abbdd96a351dc751aee3384ebbd30935bb7e3a5ae931b07c6c3bac3ddff1a043bc5f01604bdd09f10e10b1a883a597f7350268e8a7ada485884c1c8cf1a998614f59fd1cb0beb8b5e4a121f1bf33203e752c0a42e8c5e845400493f2dc91a1bcef3a1e390e6f72a7cb5dc388dd4e70efd67275637b6b6d34e53b2b2b0f1a8ddd4261225f2ca4321909db8e84a880c45d5161e87b6a6428e79d748a45fae08a77ebc128522a5f76330537950326e2904c5b059eae2ae864d855e9e9a9dc8913d963c74c69a84d4a77bb92844bc82ad18b111100866158afd7abd5aa31269fcfe7f379c7713637376bb59aeffb434343ca718cd6ad560ba09d052442453691eba37c0901e4cc8889433bfb056b22fc39b0ec25aff6d25a82bff1be61c55ecc31e56498291e803116e0e29668fc6839fde7f540fd7b589e86c7fe045e1cc77ff1e768b509d5157137048cc08c6452ae52850c6af68832beb7bbd3a8d61acd56a3de6dd76aadd595209f4f2b05a3a3c3e3e3a3c562c1f5bd68e90133026194ea462398544aa94a5ad1b036857c2edcad9141d30d4cb015b442309a5cf652a0c6879cec0c95cacee484333d69862b81eb07a1d6600c03333210c3401a2d4024d7f35dd72d140bbeef1b6d94e3a4d3e96c369b2f14b436ed760b89881412198e9738307f5c0a2b0eff0636d2ee43f1cac2ce60e2af38745fc2689f7aa665bd3be338936472083186ca1d2033f47488f0bc1ea87f0fcbd3f0d89f581d7dc4789b8eff45c71091100899d11800f61d2a173369df2b1733bbbbb5adaded6a4d351a8a8df11ccce7bc7cbe52192a57868ad96c5a2932c618048e3352210a121a0d6088bc42217b6c213736d25c5dafad6fd6d6d6db3bf56ed04600c77372b9427e64243b3ee98f8e51a9d44d3b1dc2104256080420b90ce328ef8811e41051369b4ba7339ee7a652bed6da689dcb668bf9bceffb9eef77da1dd7715426e3ba9ee3a5b1d66466cb843911e2496e544512c654c82989fc10cbf80031c1b9f5a57c8e414cf00b2c4819068cd1491b4386b531648c0e43ad5488842a54a430080024c4a27150929a014bbe0d2492d7c52c09eb0918c4c697880c802282673738cc136309d10698866788494cdc08f692ea3c0d8ffd49d6928ac21824f9cfda04c01884dd6e0783300882800d93d2cc4c0a0928e3a3836e3a95cbe7a0d3c974822e1800c3beef6532e95c2ee7f92e9bb0db090db00e3500b061c3da21c586b4d680c8466b454e2ea37c977dc72de4b29552aad90a5b5d44244ff9f99c532c9af2503b578494df8550eb50eb8001431db0c130e8763bca9830d45dc386481b6d98d95144aea314011b6334027baee32887107418b2d18e222654e2cb6334b256641019d83800608c09c23008c330d40010869ac50920b26948aa2d62bc2242444d86089591b4424a1965d828a5c45681810d3b00a08d618e1872add930381a18403333a361cdc6977d217400000537494441546837d4da388ecbc668471b6d88486b434a091ba84205008ea30040e93880df73c0fa04e0f5ac01d6b30852070016203373108608d4e974d870a843ad436020a23833b37c66cf23d7cd22e61880243b57dc6710044108b2240d1b0434da105288a1a3c848c817e68ee4dd015699ac9bcee546c61c06d606111901940a105bcae91acdedb6014d8a0d1b060c8210812425a831dab0962c7c09b32408c33071a710b036b1b9b82212173ec5868d01d66c42600d004ea7d3add71b1b1b9beb6b1b80ca512a0c438e329545d33a26492d60894295909014384a914aa4ad27e5baaee33a9ee7b98ee3ba9ee3b89eef7b9e97f27dc7f15cdff33d3f95f25dd7f53ddf7355caf71dd7715d495bef4ac27b22745c8f94f25c0f001cc70100c7113f0205c012305611314858688e127c5142000f7bc2484302daf63ff351ed9fb807ab1cf8d83da030c7891ee216664488dba1ef4cd8d30e280e6951e2198e83a2f7ce4404b0ed000090f8c2314a445fb0af4566cbde33f76f8f640b836772f4250a3e8f527334f8bef6381334c78f2579b320b77cc0c3e9b5c78fa5af250113d18b330f6db73d3cf2cc03da1fe74c49dc008c08616810a9d5d64a750d6b6606c322ee915729eeb792ab582902941cf20cc061183273188400110dc16024241622210051048e86192411069102f49452408e52408c846c9801bba1d641d88d128599286d33a0d68c8404a1525dc306204af365a2a85e80128a0e305abcc088209187015829c7188d489e4fed6ed86cb51bf55aabd90cba81e3797e269d29164b41a04bc5b212c0023b2923c0926bc48845880a41d2098252a41429e5447ca50096a35cd7554ab98ea71cc7f37dc7714979480ea28be422b9080e3319569a156b02424600420da0999140198304dd304444c791770088a014003062ecac038cbf0f80257093042cd86fad0e00d323006be04c0b58c8180b7bfb000bc1b603427263eb03a647b65bc0c2e8128380656f6d00b012b7fc70c0dab77df0a121f3c0994f2b600db64b6eba30ee219efc7d67ea837b1838dfb061441e5c2cd199cccc84210c269722c38c11a8ede999301a61af7d6fcf320693b80b64c3486c8c564af910763578be57c86773d9b4eb3acee8d8d8c953a7bef39defd66ab57cbe1079f9b1cda80bd05b6c51240a0090ac8d513b2121927200e4282aa58830067817891cd74140428588ca7104ce1049298584ca75019094a2f84ca19e50390ca091a2e9cc101a0060476c23646c02eac8b6c63e1387c43b186c39e8cc47b67ffe3df4afb4035b1ed14e80069810a2b477832d601809c1b0c84cf7505e7dcc648c38b62481e9d1edd1cf93dd26814906100d06d9480894836fe1f11fc2c7788c03d4cd81ed8f7fe613e8214ef985269e24147d66e86f078820c0d8df52af07f1ca4d4c36406493b816f460451c0d7bfdd81a20021de95948df681a532fdb600f1c077be068f785dedd1923b90d0d1968732b609e9d9b181d1f9e99182e97724ea9549e993974fe7ca7d56aa5d369794c02587b970df4528d46565111b40190a4c400792e91851400905288488ad8c44755045b027c92afc3306394edd9e1488709444a9e3e00935286192400639c5483990189e5214535243e275b684fcb41673e4efbe7df83dcef9ef6bd2d07b71b79b9f6f3600b304054f794e90849022b21e51e0426c0fd9bf76fef7d4f748bf6423280784818d707dec2e33f848ff718f7993c0f9f548f73e6a7ea419e06262689499c996c4794780f28213f21a642042792fd588a64e05a88c8142d7fc0383c688f9a89dae3de38d90fcadb44d94e9001e82177c789bb93d80c4c8c1868838a46462bbee78f94f3b95cfaff03146bb6cb57a99fac0000000049454e44ae426082, 'image/png', 0x89504e470d0a1a0a0000000d49484452000000c800000096080200000014be504e000000097048597300000b1300000b1301009a9c180000200049444154789cecbd79981cc5952f7a4e446656757555efddd5fb26b55aad1ded0ba805c2181b30020c18e30133e3198f3df6e7b1b9b6afc7331e3e2eefcdf518ee8cafafed798cb187f11bf03306592c360221c0c22c129290d4925a6a2dddaddef7adf6cc88f7c7a98a8ecaaa9604e3057b743e68456565654646fce2774e9c387112fbfafade7aeb2d00000029252242baa0046028a4440007121c0c94082850a200049408524a0494c824020340440e40d7918880c8e8b2eae2aac0189bbd11e25ca7b9ce747de5fad579ce994b321f5c4a79311fa9a07f5447f4b27e24ab500d5d77799f89b898ea09c05024debaf972a3bdbdfdbefbee3bdfb91224130888c06cb4994426984007814b00891285648c21034489cc404444ced0e00c0104e3c8900e2281833196f5a3eb2bd4c4759aaba030371734e7429e3aa83799eb88ea78755008311756e82bf55717c771e8a09312bdfcbe859482bb940e3dd7f987a823a17f70e2dfffed11834e154270ce6ddb7613830490c08051c3318e5230008608d201644c8260cc400404c118678c0170869c730ed23138030688cc05141d3afa5799789a0b7f90012f55501f211bf9b9da25b39932c9c90532d54499a8a2a6d7cbeaaf02966ddb9c73c2932abc6fe1258480f49179fe4a4a0920011918f46344741c873acf75e6f4f4a40d0e32404401c0c000474ae6a0527660004a8327158a811c9131099c2143292548d32b64b25a9c7300282929a17b65721866883a473d9baaa7eb1cfd887a001d522e78e9e30fe7d6442e60652a3b85a74cde9252123971ce096d8c31c2197db46d5bc79642a4eb297ebf828800a854f6f9ce04900020c180548bab36d27f2951740ff7f88a3d8e70101010e353098fc7629683527a2c8b034e0c47cbcbfdb64c20480e6c78281ac8b1bc26935230900eb09e5151122ca7c6e29c8f8c8cf8fd7e8fc7e38211636e62831463b90e66aa451775652ac7ccf2c53453b21134244186cd84883a5165c2cb7582ae04e95be22d521754209e781f12d8c5082220a2e11abbae869620d102c89388022472641897dce7587ec9c0f199b62131340df98536c838038902e333b22057fa73e2281c2ea523adc149aba0a0005280989999e19c33c688bd5caad07544ffca851b17f82003582eb4c17935e35cd683debb996a1100888432a94b018b732e35938b182b531b2a26239b840ea60df20bd937bf3dd1e9f922ce0609d2b8f07949034a20807004320029a4b4b9c940242cc300100071e47194881211246712659c4bc94002721d348a99942ad48f679ee9c25c26e0209b66d40749e6c7d4635dc0d872b56ce6dff3eb4497bda544e94497094f78a221c7182302a3332fa686ef37b9086051eb80e48800081201b80487734326128088c000989428a54460c8d016427226a440892235cc6868920e22bac28b33e1cf436317032cc82030c8ce58c2f5957a7a48b205038dc0547fcb39c4a51f3327898430052f65d453e328fd48ecf55efbf7f72617001602a2cd3cc283204182214ddb4e706999cc4a44e23e6f6e2222c00694b95220302624c49db8e479b68c300409d20603100dc310421886010034225d7a50115826b0ce0f2fb8d084910e2a73786ede4a23866cb43f3b19ccfcfb6e81a5f396c299ae130dc3500446d85250fe83900b014b32eef0e840421808121c2120ce6209273e23393362427064c286735d714086000868c7ac8178dce20c253200092084e8eeee565d188fc7a9bd2005b2b9180b0088d8328105e9ba12d27d5a99c00220e64c3b4e7f924f8a3c55c8d20e524a3a41d780eaab4cb528330cf9acf022a222c3cb05ac442281295381739e4824fe80a84b5e8c2a6c9abf404a011c1011241adc608c912fdd600c91316e30f29f265192fcc7303824bbdf04444551aaa054585678a9d3521761fa5c4fc7a57ec485330d58221d5298415a4cff98c95b38eb2acce2e8525f11af887407849452f9b1a43637149af74191161da147a38faa71ce4f5df87ef2dd5f1858b66d4b292d662160341ab5fcd6d0e0506565658a20180202607bfb89254b96d0a16834dadbdbdbdcdc9c34a478126184154801c2a5fe8e1d3bb664c992e1e1e16030188bc5fafafa9a9a9af47320c5589cf3d1d1d1f6f6f6cb2fbf5c8726cc61dd2baecaaa0a2f12584ace0f2c17c214985c7343a50a75439e40a3a68d042cc33012898432bc6cdb4e2412425cd402cbef512e0cac70382c8420b7d3c0c040535353595919002022cd5c0cc32083809e3f27270753167a2291f07abdaa9920c558f1785c4ae9f57a0180d48165590b172eb46d7bfffefd5bb76ef5f97cf5f5f56ae26d18065d271a8d32c67c3e1f35bace6a2e4b2b83b7d885807581c51f25329b03e282c012e75ded512a4fa4fc5e7450f9b714b068ac12b65cd425d27d90bf5fb930b0a494535353a4f2e9693b3a3a162d5a343c3c1c89441031140a2d5fbe3c1a8d9e3b770e11cbcaca727272e8993b3b3b6b6a6a7a7b7b2b2a2a94b77d7878b8bfbf9f31665996c7e3191c1cf4fbfd8d8d8dfbf7ef6f6969999e9e6e6b6babababebecec5cbf7efd3befbc63dbb66118cdcdcd96651d3e7c9873ded8d8989b9b0b290091093517b00090b1f33156d6bfbab88e640596fe315339ea2a52b7b764bacb54e14937e7159e68e812b0c8ea227865ade4ef5d2e0c2c44f4f97c85858584219672068e8c8c2c59b284737ee4c8116291e6e6e6e9e9e9e1e1e1eaea6aceb961183e9f2f140a4d4e4e2e5fbe1c520aabbfbfbfb1b1b1a8a8281a8df6f4f45456562e5cb890be6a6c6c3c71e2c4a64d9b26272769e04e4f4f5f7bedb5b66d23e29933672291482814324db3a5a505d39cf5d2c5522c7d0988180bd2380c208db12ee0e8ca2a3aaa44babb5c64acf3a8832e7829bf83cbead26d2c256a9e481fc9a88714a6df3ff0bad0ac1011002ccbf27abdba55a40af4302cc3f14d120c064f9f3edddcdc2ca5348cd918072a74757511f81426f4392089611852cab1b131446c6f6fbfe5965bfafafae88788689a26992fca36e79c4b09740748f33e70c87046e86544a93f324b5f8c070080e488cada7999aa102e3449cc548bcac6d26d799e214cf30252d3911d4ccff23eb1bd2ecc58645dd1931414142022b1d7a2458b4e9c38a1467959591963ccebf51615155996555454c4390f0402e17038180cea5eabd5ab571f3c78f0c48913cb972f8fc5621e8f87beadafaf678c5d79e5952fbffcf28a152b2a2b2bfd7eff92254b76efde5d5e5ebe6ad5aa9c9c9ce79f7f9e31d6d2d2e2f57aebeaea482928dc9081ac66a3a0e9c40c0203d0d84b4ac9581a6232790b919f87126486730b3280051a8d65024ba942f2f9a9551d3b43480fd2b313cee2f1b8cba23fcf18f8dd08eedebdfb8b5ffce25c5f33c6c87272e911a6b91cc3e1706e6eaeabcf142dcdcccce4e5e541baaf52e9538282ba268dd764cdd26f0ae99d4d68b8eaaaab94e9a693a5d4dca1a9af24634966d5288dcc2f70dd11d2c1972a70d711120526753c93ae20092947672fc29810424aa1967614c2946721e57bb76ddb4e241cb2b4e82f15e2f1782c168bc5628944821c5dbf0ddea278ac0b9ee648e81f98f8f71f3f723ec6a24e6a68685094ab2c47c2010d173aa294a3ee5ed77f483a8bc849fd45cd4145aa4d1d07cd89c0668d7420e5487797a9e8280293be4c04e9ae07c6409dec2233d0e09e0962adec8e83cd6c2ebde97554417660a591961eb02584300c432944c3701cc7b06d9bb1a42fde300cbd79d5c88cc56274b5df235791cc092cd7881f1f1f07008fc7535858a8ba1935c348ef7bfd69d5576a9edcd7d7c7182b2828282d2dedefefcfc9c9f1f97c524a8a804829cdd91f22e2cc4ce8dcb9738cb1aaaaaae2e262ddc803cd32dbb3674f6b6b2b68d0b46dbbbfbfbfbebebeb3f30c22363636a61e8dea4908e398f28fe880cc6c0a484d33610e073d4092d5084e52ca74fe121a7b6577c73b8e300c3daec649319663db36e736cd91492192a347ad5bd3b88dc7e3e4cdf9cfc0e23f2f170616000c0e0e92772a1e8f8f8d8d959494a8e98cc7e389c7e30040da90ce618ce5e4e4d000628ce5e6e6aabe3f70e0406d6d2d00f4f6f67abddef2f272cef9b163c7a4948b162df2f97ce1701811fd7e3f63a8f0f9da6bafd10ce0c89123ebd7afcfcdcd0d87c3524abaa9e338d168d4e7f3ad5fbf9e31160a8568c4070281898989ddbb77df76db6d75757554e770380c0039393e9f2f170066666668699c060c6481913a225d47cedfb204d64cb5e832e4d38105223d608bf0a42c2dce136aad9a809569d7d3904b2412cab07355e93f81967721e75385d47c131313a669124f103e62b1d8d1a3474b4a4a02810022cecccc20625e5e5e7d7dfda953a7e2f1b8d7eb6d6969397bf62c7db57af56a4879de0381c0d0d0d0f2e5cb9b9a9a00a0adadcdeff77775750180d7ebcdcbcba355c54020b06edd3a0049966c6e6e6e7f7fff962d5bc8c171ead4a9d3a74f03404e4e8ed7eb3d7bf66c5151d1aa55ab9e79e699cf7ef6b3ffe7fffc1f5a036869693977ee5c7f7fff2bafbc525d5d2984c8cfcf7ffef9e7ebebeb0dc3bce69a0f0e0e0e1e3c781011f7eeddfb4ffff44f8a6e219db021c9c112208bc1e76a2ec87074a9b2c8e632cd0496d28c3ab6484cd354361679e439e7a6692a84e91346e22d32fe7ef704961d58ba1aca3c428c327ffe7ccef9db6fbfbd7efd7acef99b6fbed9d0d03039395958584806f5c4c4444e4e4e3018d44d8165cb9645229103070ef8fdfea54b9752732c5ebc5808b164c9929d3b7746a351cbb242a110d95288cc30d8e6cd9bc3e1f0d34f3f5d5d5dbd6eddba93274fae59b3a6a2a222140a1d3972a4b9b979d3a64d645830c68a8a8a6ebef9e6a1a1a1d75e7bedda6baf1d1c1cbcf5d65bdf7aeb0dd262ab57aff9c007ae7efcf19f44a3d1f6f6f6b56bd72e58b0a0a7a7c73066d706a8aaa428534fcc102fec03d3cbae1ed5f9c3c55b19c696a60993c6bbed38c45b42018b6682a4160958fa5f82573c1effed99f3e7972cc07261282f2f6f686888ba2d168b4522914020609aa66ebc43aa3fd6ac59333535f5ce3bef7cf0831f5cb56a552814faf5af7f5d5d5dad4e387af4e8b265cb366dda74e8d021f24ee9bdc539ffc0073e909797b77fff7efa48cec383070f6ed8b0e1e69b6fdeb16347381ca6f901001c3870c0b2acfcfc7c445455523a882c5ce23c00340c8e698be5689aa60284659999062268ee56575521ddfc9f0b583047800d645bed4937b692f84af73b086563d15fd334095e2e6029ab2b168b292f97d4e6e3bf6d9c5dd8c6f2783cf5f5f59d9d9d524aafd7dbd0d02084208b8431b66eddba43870e31c6366cd880886d6d6df1789cd6863b3a3a262626aeb8e20a96f27372cee7cf9fffeaabaf32c6eaeaeaaaababc91a2b2f2f3f74e8d0fefdfbafbbeeba5dbb76c562b12bafbc529965a669363434ecd8b1030056ad5a55545474fdf5d73ffffcf3afbffefa35d75c33353595b2e160c992c59cb3e1e1e19ffce4f1fcfcfcdb6fbf0d11376edcf0f8e38fb5b66e06809c9c1cbfdf6f59564bcba28282825b6fbdf5c9279fdcb3674f6f6f2fa150c750c67464d693a2939966eca7b95855c7c9a44b295996326bfc96c814ddef409248d88ee3e8ee06cbb2e2f1b8699aa669241296699ab1584c995c04b2482442d852d5fb1de847b71f8bda487129610211e92f00505d31e56260a930187a0c2acce57a505fa95ba86f953f42ef5dae39e25d7f792a5022759159a6f98fff78eceebbef028d7af59979ea2fa7c38f3ffef8c0c0c0860d1baeb862936b02ef9ac923ce3a41c0bd1c09906175a98faefe23ee57bc25d23cf2367d2418c994f7c1656c11b014b64827d26430164bc462b168344a7fa3d1682412a1bf04539d32219d4dcf2fff593f96cef6d4cafa41d5d3d9da3d6d3107534e54c5043aaa14924819214ab2d35db8d1094355462f68159bc5d05d77fd49068cd26a4548a6fdd977df7d77ea20e827b89e51014b5549b5925ec88a30ad6fd274a2d0d616530ad11019eef8cc49a20e2f17b00c234eb63cfd55ca111175de52085335ff8deb47433db3aba5f4f2cccc0cc5ab048341cbb2f4c6559022cc8d8c8ca8a01a961ed8ce52ee4d7571652aa5fa72d6710ae9ee53d484a7c734a78813a4e620e5196b8e5981a56e3417b1651d3f2e2465226c2e4144179854e327e7845a59b7e8356c2532798b80459e77d38cc7e371cbb262b198490a320532d3342391482c16537852b7d06bf89bc2d69c8ca5da717a7a7a7a7a9aec989e9e9ef9f3e7c7e3f19c9c1caa1999c64e6a4fe6e1c387376fdeecf3f98410b40ee8f57ae9e139e75eaf37168b01402010d0d1e338895028645956201040e4b158cc711ccbb27c3e9f6ddb9148c4e3f1f8fd7e21049d9697978788b494e1f57afd7e7f22110b87c364c86752a3c28a52df8c71c6380028177626bd41ba32c50cd15b0c2e3a960b353d08d9226d149d28e5a551972184a0a51b42582291201f44cad84a10b02ccbd221a53fa6beaaa82a23b4f01bbd7abf0160651b7612405a9645cf505151415ff5f7f7070201ead4eaeaeae3c78f23a2dfeff7fbfd333333edededf3e6cdebececa4fe686e6e1e1b1b3b7efc7830185417f7fbfdab57af56fa6e7272eac8912388b868d1a28282c237df7c93ba7ce5ca95070e1c0000c6d8ead5ab0f1d3a148fc70dc3686969a9abab7bf1c51701a0b1b171f5ead5cf3df79c94b2a2a2e2ca2baf542a355334bbd000486a76fdfc4c246585545630bd676051417576bad595b6e623842384304d5bc1cbb66dcb9af53e58562c1e8f5b966959a6691a54a0b2f2d487c3611aba90314b9552eaeb0a1abcde35ce0c852aa965250000da22c818fa7cbedadada999999b6b6b6aaaaaab2b2b26030d8d5d5150a852ebffc7200181f1fafa9a9292e2e2e2929292c2c5cb366cdcccccc99336782c1203d30c16be9d2a5bb76eddab061434141c1134f3c41b348eab69e9edea9a9e9e9e9e940208f73c3b2ac0f7ef083d168341e8f4f4e4efec99ffc09b5c21b6fbcd1d4d4e4384e75757522913877eedcc68d1babaaaa10f1ecd9ce75ebd63634345896a520a2f11353ce439db1f4afb292134b77a6e890625956a92f2a90cb45063ab0327b5af747a8802d029969da3a6f5956c2b6139665c6e3718fc78ac52c8294c7635916e9c459cd383333432e2e35452000082132a94a523e86f7062cd51cba41a25421001415151517171f3972840244491fd1099b376f1e1919397af4e8962d5b306546d4d5d56dd8b061606040ad19d35d540f29bb5e0871f2e4c93beeb8a3a3a383e2fb002091489c39738634a6e338bdbdbd8cb19a9a9abbeeba6b7272b2bfbfbfb4b4f40b5ff8c2be7dfb5e78e185bff88bbff8ca57be7ce2c4899ffdec677ffbb77fab2fd0b2d40a5a06bc9236d6ecd3cea1f598b6c8ad70e652857315b2ca5cc062c9c80b3785e8eca58b3e5b246f966ddba66990214f68b22c2b1a8d1a86611896695aa66992a71e00c2e1308d7982296a3e088297fa88a9e5d1f708acb99a263f3f7f70709042af962d5b46dd6018467e7e3e35073933c95fb571e3c6d75f7f7deddab5f5f5f57bf6eca9aeae6e686850e6766d6d2d050c2e58b0800007009cf3ad5bb73efbecb38cb1152b56d4d7d78742a1eddbb72f5ebcb8b1b19131f6e4934fd6d6d66ed9b22510083cf1c4132525251ff9c8472627277ffef39f7bbddebffccbbf04807ffff77f47c4af7ffdebc458a4dd74964aff6bea7ca600e4fa08e916e705f10417825456d171e6d28f2e0e93e93e7ab26e95133565d11ba42528ec9bcc15afd7ebf546bd5eafc7e3314dd3ebf51a86e1f17888b77480a236bd10a9dc24f23d39bd66fd58ae31cdb97210709d03c8e1dbd3d3336fde3cea4597c67139c094a27115321590eb2000a800519d54a832f42da4ac6f7237b0d4ce0ebd3ea95a195a55d32ea8e349672c1d5873a1ea37052c4c9ff0cbf469a38e309769ef622fdb8eebfe2d9adf44a3d16834168944239148381c0e87c3333333333333535353c45b6ad3a27e4d5d0b0380940ec5409f5fb2fbb1309bf9c9d2cd5800f0783cae8d59fab7a4e3d40575e8406a6eafdc9beafa2cc347408b39e4e8d2fd08ba1b42619773c6b941b0516b1abae2cbb0b1189bdbae020d46176429058bf780aaccabe96521dc9bb3656a4d86c69bb290782a6adeb6b9e3085aaa36cdb865252ccb63591ecb8a9a2659f1a6528864ced33e06aeede857ca319d3211914929f4fa9ce7a1d210001ab694c462b1a9a9292a575555a976577f55afa84916a4b679a91a28673d9d494cceb53d612e08d299b4fc0700a74e9da2dd13ca605208534b84d44caaac9fe9fa9b391ef481e142d205592af3cc7725aa89327fce525697faca657b119e74f6d2c29a2dc3306ddb36cd38595796657abd1ed3b4c8fcf2783c86615039140a116f51b8845aa0d4af0c00528294b3b3d7f38b9bb194a883535353939393a5a5a5e42b4f241200402a3c1c0e33c6c8ab445bc1a8aeb66d5324bb629768344a4abda8a88828daebf5e6e6e6c6e3f16834ca392757052216151531c61cc7999e9e360ca3b8b8787a7afae9a79f0e0683656565e170d8b6edbcbc3c6a97f3404a1dd42513582e96826c632c1307734121eb997389de3de73959ffca052cd066153ac2582ac89bd6aa0dc3304d6e9a8665599c2721a5788b9a8574a26118345b64a95dd7ae479612016cc56030376fcd69bceb4f1a0e8727272783c16028143a7af46830182c2e2ea6480782c2bc79f37ef9cb5f363434e804b06cd9b2fcfc7caaf7ce9d3b0b0a0a0cc358be7c795b5b1bb5c8ba75eb3a3a3a3a3a3a82c120a41cee8585855bb66cd9b3670fd1646363632412191e1e7ef5d557376fdefcfaebaf533b6edbb6adb8b858a12733e4cdc5583887631d3424b1740f4256ae3a0f14de2d63659eefea241751e9c731e50cc39416d611464cc6b5edbe8984619a663c1e378ce43cd14ae9459e8ae8a27d759c73da78cc18a32d1b645a21a2c219a652c99de7e9b2ec5cc8ec86e2e2e29a9a1a62a6c2c2c2969696aaaaaa9e9e9ee5cb97af58b1e2cc993388989797b77efdfa79f3e671ce376cd8609ae6f4f4b48eb3d5ab576fddba3591481c3f7e7c7272726868889617d6ac5973dd75d78d8c8c7ce0031fb8f1c61bdbdada18636d6d6d1ffde8473ff4a10f1d3c7870f3e6cdb5b5b51ffff8c7c7c6c60e1c38303e3e7eeedc3972cdeb42b36ba252d56a6ac9cc302c1d7c2e0e73995f982eae1e9d4bde15aa2063b3eb5cd7d78fb33944276962236a0d5af9c84989cf97ebf7fbf3f2f20281407e7e7e41414161612139928a8b8b0b0a0a7c3e5f6e6eaecfe74bcd25bd1e8f87e6927a18346a964386240f1aaea782d9f141de0b94529aa6e9f3e5902aa499a0321e410b3057131cbd7bd4f5fd7e3f1d5fba74696b6beba953a7687ca856a34ad395692b018585509309e170ceaebe7aeb873ffce137df7cd3e7cbd11759796a8b818e9bf4567063c6359c5423b8dbe9bd9ae417948bbcb2eb348545577f2998a2c6617c766722e3dc300c9bf33871bcce55aadd88b7e823adc229f652463d240334923e7a210459f4a9fa256bcbefbefbee9d3b77ce311a92ebbba669e4e6fa1093dd43bb0b6b6b6b0f1e3c383030b079f3667a98d2d252eaddc2c24221447e7e3e6d4625cd4ddba3f3f3f31389c49b6fbe595c5c3c6fde3cc7710a0a0ae8605d5d1d3d406363e392254b7ef6b39f7577777fea539f324db3a6a6fac9279fbcf1c68f0c0f8fbcf0c20b0b172e6c6969219b540dd014336589a54c27a92cd6fa5c3dfddb43d57b964c76d49f622e36a5ae7419a0aa5df4725624606ad1dad562a9b2ee8ac39950e4a69b6f4cfab15c574fb7519000ce987b1a8f19d334963eff5205e5178094e709538b743cddcae69a25ae06966130c5f38661706ed027c698ee4bd3eb80191cc532e6b3f00702a60b8aee59957378edc9ae5761cdb66dd36ec470384cfeada9a9a9e9e9e9a9a9a95028140a85e85be50c8bc7e3e17098d488ba1ad115396ee9be8e60fd8363b37eacb9da57a9290aab8174cb40f51c4bf738b88e732dd0457dc593bb960da50dd3d1cc15c24cd3e41c95914e568461989c73cbb220157bc8b2d9492cdd60820c60cdf5f87f583257f72960d1e313e55073a90d644a21b294f3999a91e223f40e2254a166ce03801069f7521530b2564b974824c6b91d08040060787898621cd4cdd4cfa93b2135b9dbb76f5f5555156937d020a88b6118c3c3c3dddddd8cb1050b16949797a3e605350ce3d8b163ab57af4644cb9a7dfeaf7ce5bf7ffbdbdf56b0a3f83017a4f47b41fafe7ac8c2e47f3ca2fa58ff0829bfb4f24460fafa8752057a984d241251656a6dfaa16a55917ab78010021110414ac952f111d93def7a4f4c4d4d398ee3f7fb11b1a3a3a3a2a20200c85d4bf3442a9ba649bbc1a2d1682291204f04638cf833100830c628fa6c6a6a4a6de2ebe8e8989999696a6adab973e7273ef109fa564a595656168fc77ff2939fd4d6d69696963a8e3336369e9beb2f2b2b8b44228383831e8fa7aaaacaa5705df0856c696d5d2dfec727f4ec3ab674a797de324a81a4cf7266f58c6e20616ac7a86a64f2cedbb69d7ebbe4ff49c6527ca3f310492010e8ebeb1342f4f7f7135dd1e641c6587171514343c3b3cf3edbdcdc8c880d0d0df9f9f96d6d6d9c73cac7d7d7d777ead429bae0d5575fbd73e74ec330727373376fdeecf57aa9ea7575754b972efdf5af7f4d1cf6e69b6fc66231bfdfdfd2d2323232b26bd7ae6baeb9e6a59776716e20626b6bebf8f8f88e1d3b1863ab57afbeeaaaab0c2d894d26b054416ff7df591fff1e45a72e0535fda348ed9663e906314f8532eb1c46ca818c33a5af085298ca752393e137000038d7f62fbdecf7fb29a9dfe0e020adab74767652688365998c617171f1dab56b7b7b7b07070769696fe3c68de4d21d1a1aaaacac5cbc78f14f7ffa53d2f46bd7ae25fda8eaf7d24b2f1d3c78f08a2baef0f97c030303838383894462dfbe7d77dc71475d5ddda73ffd6944fcc10f3abff39defd05cb7bcbcfcde7befedeaea7aecb1c7aeb9e61ad40c3b4dcd6647d57f6571e109344251f330430b34a51ed4a774e480500d4e20538d4c4b408849fc1830778490427d6363e33befbc535050e0f17800c0e7f3ad5dbb564ad1d7d7ab8f0348a91ef279c854e24dda684f972295cab489dbb5d75ebb6ad52a1a19bb76edbae9a69b82c1e0030f3c40eb59e4ca324d331a8d76767646229194399f1c64466a63990b55a08d90ffb2f0d21f5c5f0282f485735d39426a5f024fe55c5142fb1e582a864035b5d4f7e2a6ae96f463299cba9c194489393939939393e5e5e50505058cb18a8a8a43870e8e8c8cae58b182732e84a43519b27b6cdba618e2a6a6a679f3e675777753c285929212c7c07407f10000200049444154712a2b2bbd5e2fa6e62652caa2a2a2a2a2225a6458bb76ed33cf3cf3f6db6fd7d7d7af59b366f3e6cddffffef71b1a1a56ae5cf9e8a38f0a21b66ddb168bc556ac5841cfbf70e142d09282b8947866e3fe5796aceda05b5da859f4a8d95b0a09762a8d20fd8469e9a252d7472171727266dbb68fe0eeddbbefbdf7de4c5f991223fb5a2fd37e925cc85444aa2e95fa385b63f242697e04a642662d4bf7769aa669e96a5eaf926b0ccca5fb2e416a2ec9f475a9fd1a898463db71da99180a4d8742a1e9e9997038140e8729eb6c384c1b15c3b1583c1289ead9b96cdb8ec5c5c9cede1fffe8e12c36d6f91717535d486f526588d9932fea5301962e9cb3142e19e79c60639ab3735dd3b414dad45c57815b7795b1f4384fb804a68b13971ed47a9cfa1420a9349d94964444a46016ea41445214e07222d9e02033386717d862af975dca25abaec9d447ea084bf78c93e87bdfd20bee7834f52bcc70535d02d37b10d4628ef526a5659b940d2e54e42da6fc4abad50400442e8a416c48004821b3bdfd2b2b50f48f1714977ace60ac59b5e89ad3aa8fda97690b4deaca900ee2cc9a5f920b8a0b5b3a23687cc669295008e1f3f9b8e6184f619191479454aa25d0b23c9075c32a64e3a44c846516e602990b55ca5c53b849d958b4c7d29395ab7460b92a039720f55e25b319313531d4466fd2bdae12e8e97fd50974b22de2866571ceb3b81b94e82b9a7a3d30fdf5a4e7879d8257e69c40d78014dc9819c5a1e82a2ba42ee1e93722991dca53a150a9f6968ee3e4f8bcc82432c958daaa06f931a86b623600a024cfbb2e2e24a91bbbca2ee674955d44e532ad5c5acf300cd3b42810cf30b218ecba5ed7ef059780f59b139c557f6939b40cc3204795e3385eaf37454e28936f53231b1f2015df17b3933134b34941f4d00b75b3b97aee3cfd3a9736d4dd198aab14b05c6696ee5960d95ceabfa1f6bc24b392e22df27192218b8c0995a924272787ba82ba84b3e4444a4a50f67bcc06d3f220b25960e937b8c87a4086363c0f9e748b2a6b805e567f9502169b7b4bfb25f94d09e935ea5248b211722e01a410c2b22c4afc9ca43786a954f552d9efde84b42c0fe8c0ca642c57848d8b2db2424a6797ac66bb42921ea1711eae22d1ef089720f5db14d27400b39beb39e700d2341dcb3215b0280247cec6d12497ec62362072649834de5d5da59b72b443abb8b81800c6c74773737303813c1d7ceab78cb14824128944f2f3f3fbfafa9a9b9b8f1e6d5bb76ead6eaa93e2b32ccfd4d4f4d8d81891164562353434189aef5ec1544af9da6baf0d0e0ede74d34da669d2bdc47973e4f7f6f6161717e7e4e4b8a247b4b6bb241710b2b7685d9931e4dc608c53900153af1711699a444a1917066316673ccd78d7579455e461381c1e1818a0d0abfefe7ecac24d7b1a69871aed31a21061afd74bc9b11091d69da91294963d27274719583d3d3d5eafb7b8b8d834cd6030681886949202617d3e1f22d2269f929292f1f1f18e8e8e6ddbb61986313333138bc57c3e9fcfe7a34834c330a6a7a7f3f2f214453ff3cc331d1d1d77de792725f122a1bc5c9665cdcccce4e6e6aae6b8241992d6328cd1eb972563f4ca5c4936bde39800407a33b5195f0ae18dda68581ee4861b58b41f4d7d040044aca8a8e8e9e9f1f97c15151504a3a1a111c33000a0b2b292733e3a3a1a8d460b0b0b8b8b8b2726266a6aaae93d6f24d168b4bfbf9f73ded0d0505353a3b6b30d0d0d251289cb2ebbececd9b300505050f0da6baf353636363535f5f6f652944f7979b9e338131313870e1d5abc78f1e1c38709ca9b366d1a1d1d3d7dfa745353d3891327b66eddaa388952df82c6a652ca89898983070f2e5fbefcc89123adadad14a67149ce23aae9a8cc38e39c01ccfa4b89d2104082044cfee789a1c7eb1342ccbe99dd6551b9ee515252629a26bde69476f8d7d4d478bdde5028949393535252e2f7fbababab53bd9b34fd48a98d8c8c8442a1b1b1b1f1f17142151d5fb264c9860d1b688f35a179debc795bb76e6d6868387cf8f0e8e8e8f8f8f8f8f8f8d2a54b83c1b2abaeba8a12246fdd7a95e3d8d3d3d3b5b5354b972eddb76fef962dad988a34026de64c1fe9785959596b6bebeeddbbb76cd94291f297e4dd894cce1695ad6c59a665591eafe5f1585eaf2727c7ebcbf1fa7c3e5aea9d652c32c7941274d9f294c85a085b19e6f4e203c6d8f4f4f4c4c4447d7d7dca2a023d9c81733e3c3cdcdada3a3a3a4a9bb89593dde7f35166479edab94b498e10b1a8a8e8861b6e88c562f4060a008928394700110e87e816b69d686b3b5c5252dcdbdb535b5baff044595c296f9b65591d1d1db9b9b9e5e5e5148d73faf4e9850b17669a959724aba8f91220622a49ac917cb7439244548271218437870909525f2b54d4e70296c7e3414432a11c07737373bd5e6f4141416f6f6f414141717171341a751ca7b3b3b3b2b23210081417177bbdded2d252afd75b59596918c665975dd6d6d6669a667373b3f22954575717161692c955525242a8226001c0b66ddb76edda6559d6b5d75e2ba5a4c8d579f3e685c3e1175f7cb1a5a5a5acacaca3a363d9b265454545fbf6edabab6b5095dfb3670f63ec9d77de098542f46643cbb28686861a1b1b2b2b2b0f1f3e4c59a37ec73df4072b842c49b37d917aef1f1942866112aa94ba8824129c1b8cf3e4be424ca59e520e4cf57768680867f70f424a6de9f158fa466454cb7c0a4364e3ebb342e57ed77d0aa8852f8af45cab884038a74252bb2353cf93c940cae492e9919300505c5c7cf5d557ff2e3ae58f4784e3d86363a3002052a90553698f9c44c28ec762f178221a8d8c4c26befba35ffced57ff2ccd8f45d0d3fb00002a2a2a08289c73d3e4a9b0e0a44643443ae2f1780c8393de255129e4727272288980d7ebddb76f9f10927605aab54ce55c808c77e6ba4cc8cc27569c2c5391d0904a9c44b95668cea23f54381c7ee699677e1bcdff4721126613432647351d8f46231292ce5241db54a51002ec84ad52a1066b16d88e340cc30dacd9cb6b47c80052b630003096748011d998a68128e93d4724466a03a49eb4830cb29b6eba598b1ab574572aa4984687978eadcc8f591a467b6f8ca26ee5d65346fd2599430424d3762485862a24bb66364fbdca2468db0ea5d77af3cd3723b6e3f70740a6b67fa9812ed3dfa607e99376853dd53d29379a60cc90a99dcd86160c33ab5e558ca8c10d831b866970132570ce90736086403010410ace68c580f2c7314555a8c50fe970919aef0d6717530152af06861411722d93e0259943d0052c489b6873982517e41c543c16005896954818001250ce7ade7524e953427d9e28255254853a8700a6bbcb5df10b86617083f6c49b86e9b5d0b0386326e3a6c98173c61c89532139383a24018305f97e0ffa730d44905200080006022403a979105c6b3b991f75845d243fd113b914b16a10966d738be23f9d4d5dacaf9fe0aa893e2ab2f6a2abfd7f4b5cebaa3ca2db75ac46b55e432a28eb85e689866140021004809c558599d8d2e582f5d3359a5aef330cc3340dc364a6c90d6e71e691e865dc070800091b65df343cf1dc5bcffdf22d07510008277efb75ab6fbd764379519e6971641c24200315a4011a835e647b5de44f745666a9fd272e64b83eb2543a50d77d754ed5b19e79c7cc85a94c2c5ee4f3be37c93a9c2e287af53015a34c3d3e3232e83836ba723748cd783f0fb654639164e2299db44cd3b00cc334381aa6044348c60cce19b3e30eee7cf5f08f7ef2cab296ba4fddb9d5c3e1c489b363839de3a363967482e5450250a2c30111b894108fc7295f0a259238ff93438a51cebfaa789e56cb9cc764823b93ae1863333333f4966b4ca54d8f46a3b9b9b9ae1b4929676666d46439f316945f93ea407b337f1bae5dbabee338b1582cb3927389ae25582aab19636c606020140e4b2993968afe9bb9882af3086aa2b0a53c0bb33616332dc60d8e9c03e38259028d042224e24e643aeed846ff44fcedc39da199d8075ad77ef9eedb6bce9c883dfd54b4eb0c170e93f2a9a79e7cfae9a711f1e5975ffee10f7f78d75d775df0b1a5942323230f3df4d077bffbddac6c9129ededed0f3ef8e0830f3e78f8f061c8b0de7efef39feb5c3e3030b06fdf3e1d52b66d7feb5bdf7af0c1079f7cf2c92f7de94b2323238a6c060606befad5af6665acbbefbefb9ffee99f0e1d3aa4aaad6ed1d7d7f7cd6f7e736c6c8cbefac10f7eb067cf9e0b3ec5bb15f58cd3d3d3fff88fffd8ddddfd6e7fae0380731e0e8785e3d84266598456c63b686012da5bf6a46631e06cd8b18a27263ca9776c58a6e121539d732f479303e3c86c3bee318c0f5fb5bcb36fe4f523677ef4d3973da6599203dfbff30adf23ff1aee3a6d6e5807028687479fffc52ed332376cd8a86ba843870e85c3e1a54b97d2bb99a8ce866144a3d1f2f27200c8cbcbbbe1861bfefaaffffaaffeeaaf8e1f3f3e3131416f2da013bababacacacac6c6c6bababacacbcbabaaaa1e7ae8a17befbd170082c1e0cccccce1c387737272cacaca7c3edff8f8782010181d1dede8e80080c6c6c6aeaeae1ffff8c7a6695e76d965049d871f7ef8b6db6e9352060281175e78414ad9d5d5d5d3d3535353c3391f181878e38d374a4b4b9b9a9ac6c7c78f1f3f1e0804e8c5d5c44667ce9c99376fdef0f030e7bcb8b8584af9faebaf2f5cb8b0b4b4f4dcb973dddddd67cf9e6d6969191e1eeee8e8282a2a5ab870e1debd7b6ddbf6f97c2b56ac88c562f41a07bac5ebafbf0e006bd7aeede9e9c9cbcb9b9999090683fbf7efe79caf5bb7aebdbd9d36fab6b7b73737371f387020168b2d5fbe7cd1a245afbdf6dac73ffef177054addf263a9a02983b3341b0b002863ae4cbd04817e4c077585a28c0c52b28c513234d330684ba08780651896699adcb09019c82dce4c8696c17c28111d99884e979615fcf77bb79deb1ae81d1cd9f95aef1bbb7e6df78f8c0f0e54ce5f6854d60a349e7ef6b99b6ebe29140abdf0c20ba5a5a5a4da9e7aeaa9bebe3e9fcff7fcf3cf575757575757cfccccd8b65d525272faf4697a57856559cdcdcd143973eedcb9dedede1d3b765c7ef9e5bdbdbd9ffef4a7ffe55ffee5aebbee4a2412edededafbcf2ca75d75dd7d4d4f4ad6f7d6bc992255ffce217bff18d6fd4d7d71344f6efdfffc52f7ef1bbdffdeeedb7dffeeaabafae59b3e617bff8c5a64d9b868787cf9e3d7bd965974929b76fdfbe7efd7a5a29223975ead4eeddbbabaaaa5e7ae9a5abaeba8ac0b467cf9eabaeba2a180cb6b7b74f4e4ef6f5f551b30f0d0dfde4273ff9dffffb7fbff0c20b5eaff7965b6e0180c71f7ffca9a79eeae9e979e491476a6b6bfbfbfba594131313ededed6363634343435ffdea57fffccfff3c140a9d3d7bf6e4c993a5a5a59148e4adb7de5ab76e1dad2bbcf1c61bbdbdbde3e3e39ffbdce71e7becb192921221c4d1a3479f7df6d9279f7c1200bef6b5afdd7efbed6363631e8fa7b9b9f9d65b6fbde5965b2e1e580a5e8a5f0855b6e360d6a4200429656909212841b2611894f918b47dfe0070ead4a9a54b972af795cbd7c0180c0c753736d61b864033215818588ca3650b8845f9bf3dfef4c9fef0f51f5892979b5b17c4d3793cd78747c7069b6eff2882134dc45efbf5eb850505f178d4b6ed6ddbb6d1331c3c78f08e3bee58bc78f14d37dd545d5d1d8fc79f7cf249c3306ebdf556d0cc70aadec9932777edda353e3efeca2bafdc77df7d5ffad29776ecd8919797575959f9ed6f7fbbabababbdbd7de5ca955ffef2970160e7ce9dfff22fff72e4c891fbefbf1f00fee7fffc9f5ffad297d6af5f4f03acb5b5f5631ffbd8a73ffde9582cb666cd9a9b6eba09346df2e69b6ffeebbffeebc8c84830181c1e1ef67abdf7dc73cf3ffcc33f0c0f0fb7b4b4fcd99ffdd97ffcc77f747676eed9b3e7d8b16303030394be4c4a595353d3dcdcbc63c78e9d3b77fef8c73fd695e6c4c484e338f7dc734f2814b26dfba9a79eeae8e8e8eeee2e2c2caca8a8f8d33ffdd3c3870fffec673f3b72e4c8f6eddb272727f7eeddbb7bf7ee8282020058b0600100d02079e08107b66fdf3e3131f1d77ffdd7a04d1100a0bdbd9d5216b80cca8b44956ec5d3253d1e4b660596cbc6a2355d7a25d3c4c444797939414d4a49a6250090833b168b1986e1f7fb559016b9288fb4b515151706cbca1832ce2c86a604c63d1ee491eaaad2b74fecffce0f9ef619867412375c7999333d222f5b0e5bae80dc4068726a6a6cf4cffffc5308f2fefbef8fc7e354c3e2e2e2bebe3ece795151d1473ef291bffffbbfbffffefb11f1a1871ebaefbefba8d53a3b3b63b1587171f13befbc73d96597ad5cb9726060404af9dffedb7ffbd6b7bef5f5af7f9d427deebdf7de279e78424a79f2e44929e5d8d8182d80b6b7b77b3c1e993e47ebebeb6b6f6fa70cf5b43cdad0d00000dbb66d7be491476ebdf5d62f7ff9cb5ffbdad710312727c7b6ed13274ed076bcf1f1f1f6f6f65028442fbafaea57bf7af0e0c1dede5e350c6eb9e596fbeebbefeffeeeef543f1516168e8f8f9303f9c489134343437575759d9d9df7de7befabafbeeaeab2b2b232ba3e225656567ef6b39f0580175e7801b4e08ef6f6f670385c51511108044e9e3c89888ee35c75d5554d4d4ddffbdef7e8656c454545ef0a583ac252b8429080984a0a029a9dafce53e4462f0d080402b4b36c7c7c9c3cad94c1766262a2b2b2b2afaf2f914844a351cbb2727272ce9e3d1b8d46a7a6a62627a74687c72dcba8aaae360cefc9a3ed4b972d032698c9189339a6b97ac5e28deb566ede7859ebcae62b1754e081b71a5b5af2d7ae83fc3ce4100c96b55e79655d6d2da5010f06837575759ffce4275f7df5d583070f7ee10b5fa010b1cb2fbfbcb8b8d8b6edd5ab5753fdb76fdffece3bef7cfef39fdfb871e3891327de7aebadfafafa4d9b36959494241289356bd61416160602815dbb7699a6b971e3c69ffffce7a4506ebbedb655ab563df9e4930303036bd7aea53ce41e8fc7b6ed5ffdea57939393b7dc72cbc68d1b8510070e1ca0b11e0804366edcf8e8a38f9e3871a2b5b575c58a15975f7e3963ece5975fdeb469d3ba75eb7a7a7a4e9e3cd9d8d8f8a10f7d68e9d2a53b76ec989a9a6a6d6d6d6c6c5cba74696d6dedd9b36743a1d00d37dca068a0b8b8f8b9e79ebbfefaeb7372725e7cf145afd7bb75ebd6152b563cf7dc73b158acb5b5b5aaaa8ad6e60b0b0b3ff1894f3cfef8e3c78f1f1f1b1b7bf8e1871f7df4d18e8e8ecf7ce6333e9f6fdebc795eafb7b5b5f5f1c71fefe9e9f99bbff99b0f7de843fff66fff76e2c4898d1b378642a1d75f7ffd861b6e58b972e5c30f3ffcc10f7eb0bebefe3d408aca3d3d3d274e75f50c4e6dddb236b9082d356709a627dd52612dd168343f3fbfa8a8a8bbbb9bde059f9f9f5f5b5bdbd5d5bd6ad5cafdfbf79797979ba6595f5f5f5555d5d5d575c51597536e8f3dbf7aedfa1b3e6c9a1c99b163fbcf6fbbf5a38c338912016391f8f0c8c8f0c8d8c4e4e4f4e8d0f2e2e2e9a79ef257d7d67eea53bc381f90a2323842da1c8dea29354f8faba04e40cce22592e99ec9cc73f4565347f6ecd9c339dfb871e35cd777fd5066f83f51858a672c4ffdf297bfacaaaa5ab66c993a6edbf6638f3d76edb5d7d2ab905db7732d558d8e8e7ee52b5ff17abddffce637c965e0aaa4fedbaccd323a3afacc33cf505245784f22a57ce38d3776fcf2e5378ef43ff0779fc992dc5659ee2494bc86f2ca8f8d8d151515599655555565180665e2a254cf8585858b172f668c0148d3e486c11289f8c8c8707e7e2133a51d4f780c0b99b4c1013450220321113d3eabaaa6bca8b8301c8a826c2908e45a576c04e4c00c4004100000080859767de92321f329323faa23fadf4c99eb579b376f3eff99593fba0eea5e53fdcc0f7ff8c3ae8b1b86e172ace8bf62e91b4c8a8b8b1f79e491f33c8e4b1d659e53525272cf3df764bdc20545731400801420c115e0ec3a9510669aa66ddb131313a3a3a395959552cacacacaa1a1a1b1b1b16030c8182b2b2b310c63e1c285dddddde3e3e37575758140a0bebebeaded18220f0683ebd6ad3fb0ff8094827364c89021224826054a00ced0f2fb73cb822565e565566e2e985e304c6000e0d082e8a515e3f7bf28fa5488cf9e6d469116f1b6cfe7a30098e46f0ca3aaaa4aed8ca0b0f7dcdcdc8a8a8adcdc1cce99699a959595f3e6cda7f098d292b2cacd15a6c1a4040426410a262538034363f168824990cc010040968c7f257e22ba920c00defd0b3e2fc9ef48a494a4be207d1d624e60296c01a86d1849c7a98acb63a97436ba287f29d96a8c31864c220043868c4948e65f023e3d351d9909a7de9d2149e7c9b48541018020f112b0decf525151a1dce9aae7e6cc8fa56cac582c46963be520d50d1ac6d8e4e4647e7ebea16d9ce79cbffaeaabd75d778365790867c88171268171a40cc72025306634373581745002484322204a090201019894800c40da800c24bb04acf7ad2830e96973612e1b0b34338b3c0ba6694e4e4e924f8f5e8001008ee39c3b772e1289d0d5676666c2e1b0699a52c2e4e4e4d8d818638c193c9e888f8e8d854221482a3849ffa20404940c05038920404ab005c4250a40904229c70b6c22ba24bf47514443415373aa420540b59243e1a31e8f271a8dcad416d64422110e876b6b6b6ddb1e1f1fcfcbcb3b73e68cdfef9b9818a378e89e9e1ed33443a1d0c2850b0f1c389093e39336d4d5d44804218101a2049060331697381d8a0ff58f226049512090cbbc1e87230260cac613e42ed1661f9718ecfd2e73aa422542884824e2380ee536a69757d36b55962c59e2f7fbe7cf9f9f9b9bdbd9d9b96edd1a9fcf67599eb367bb56ad5ae538cedebd7b5b5a5a4e1c6fafada9038915c13260281184008e5248d13b16fb7f77bcb1fd97afa1344c01cc8e6cbb7ed34d1fd9585992e3350c04063209c5d41e8af305255f92f78f64cfe8a70a94153e3737b7a0a0803c6f535353656565f9f9f9fdfdfd908c464d0048cb326983bc94c98052994a6e595559bda5b575727cc2118e4410888c4b9076cc16cfbf7cf0d19fbcbc6cd1bc3fbd6bab81e2ec89aef1c1bec9a1611e376b6b2a1930092ce5c742f5de625a0bbb24ef67b940e8a0949256940180de9d422ff01d1919c9cbcb334d63e9d225dddd5da15068f9f265274f768c8d8dd7d737cc9b378fa2d21a1b1b19e3ebd7addbfff6db6313e33575b52091494481b62da289442896b0051f1e89bff1f699f1e9e81557acfa8b3ffd687e8e39d83b383315932801e54f7ffab3eddb774809afbcf2eaa38f3e7acf3df71067fd67a86bae9f4a09cf3fbf93cc41fda0ebfcac3fcf3ced8f5dc85c26713ff9f9542191566a232140aa2f83c1602010c8cdf5218261f0c58b17f9fd7ebfdf5f59594df94f5b5a5a1863a6693635352142694959696b29720920102407008484904cda1fdab2bcfbdcf89bfb4ffd7fdb5f791ca1d8c73f755bebd5eb5b6c470c0f8fe4063c4383832fed7a8996f37432ddb76f5f381c5eb162452814f27abd8e634b09a66986c3e1aaaa2a29211209efdbb7cfb2ac0d1b361c3972646c6caca5a5a5b4b4f4d4a9537d7d7d0d0d0dd3d3d38b172f8ac5e2ddddddd168746c6c0c00afb8e2f2402080c8ce9e3ddbdddd5d5b5b5b5f5f0f80005208387efcf8c8c8705353536eaeff9d770ee6e6e6ae5ab5fa9d770e4e4d4d2d5ebcf8e8d1a38b162d2a2d2d515b20ff58fd6f34ae51fd0b905c7c0390785e3f1664c42babf02ce5c47279b054c00cd712d132c610b9448e684b900828d1b1413044db8ecb44bcb220ffef3e7fe3d973fd5dc3c3cfbfdef3e24b07fe63c7af9beaab867a7a0af3f238f2679e7deec61b3f12894476ed7aa1acac0c4000889ffdeca7434343b9b9fe5dbb5eacadada9acaca278acd2d292d3a7cf7ce6337f09000f3ef8606d6d4d4e4e4e341a79fbedb78b8b8b9e7df6998f7decf6175e78b1b2b2a2a8a8f01bdff8c6f6eddbc7c747ffd7ff7ab0b7b78fa2a0f6ef7ffbe4c913f3e6358c8c0c9f3e7deae597777fe2139f983f7f9e9472efdebd7bf6ec292b2bada8087efffbdf6d6a6a0a87c367cf9ef9c10f1ef9f8c7ef78e699a7972e5df2ecb3cffec33ffc5f9c73486e7411296c5173672dff419c40e5d41227b0d451965c6ea3a006092cc55c1730def5b56bd7711d523c3d4f9a5a11a39013061280a3e40860086e024a01521a3311e3873f7aeeecb9f0b5d72cc8c9f395151a868857052bc6468763b168695949241a7d6dcfaf0bf20b62f1b8e3d837df7c33ed063b78f0d09d77ded9d2d272cb2db7d4d6d6d9b6f3d453db53f15848a12e4288b3673be7cd9bd7d171ea95575eadaeae0680fefec1c2c2a2bbefbe474a89c8a40429514a340cf3aebbee06809b6fbe39180c0e0e0e3dfbec73030303870e1dbaf6da0fcd9b371f919d3ddb595353fbb18f7d0c008e1e3d7efffd0f1c3b76ecb1c71ef3f97c77dffdc96ddbb63df8e0431ffbd8c71c4772ce523da19a4e6fc3ace53f9413644a03a2049e429c64b49f0a0053ef84ce1e8fa5f0948446ba0f09b3654156a1c90a5b2960210310296053da1b44302d049ea8ad2f6deb38f4af3ffa85e1f5d82271f5fa866b2e5f32d07decb2a52d798585539313d353d37ff5d9cf01c2dffffddfc7e3092911800583e5dddde71c47949494dc78e3b6af7ffdeb0f3cf000227ef39bfff8c003ff0300a5843befbcb3b3b3f3873ffcd1cd37df7cc71d1f5fbe7cf9f3cf3f9f9beb8f46636d6d4783c1b260b0bcadedd8e8e808210c1153290f717070d0e3f17efef39f7fe4911f22e2534f6dafaaaa2c2828e8e9e96d6b3b5a5959595c5c72f4e8d1dededeb2b2e0b163c7359812d3d3ecf58f729913013840b213096812a4ca642452bbc766e3b1745101a2a825f53629155f6ab3bcd7ebcdc9f17a3c1e5a49f4782ccbf2a8f7bd1ada2b5f111198838828b1adede8e2a54b2552fa53c763e1aa150b37adbbecf20d2bd65e36bfaa08477bdb9b1aaa962d5beecbf5338615e5e59b5b375757571517152f6a59585e5eded0d870d79ffcc9ebaffffa68dbd1cf7dee73e5e54100d8b86163515111805cb56a259937cf3efb6c5767d7bdf77e69ddfab5a74f9f3eb0ffc075d75db766cdaa5028f4c61bafe70502b7defad1a79e7a6aa0bfffca2bb72c5eb2b879c10244c8cdf5ad58be7cd3c68d1e8f67cf9e3df9f9f99b366da204716b56af1e1818787bdfde9292e2ebaefbf0d33b9e7684f3e9bff80b5f8eafb9b9d9e7f32d6c5ee0cbf12d58d0c418a64c2ca9992090bdfc0771029553f6131d475a6e43c140d0603a77aef7c4a9aeeec1a9adad6b92f1586e58a6184b693a0adf0ba4242f2f2f2f2f505090eff7fbc913e1f7fb737272294d034150119864201118302ef1899f3cfed13b6e73242072d3d1d229000020004944415414221e8b0c0d0f0d8e8c4c4ecff4f50d14e5172c6a6e2a2f2fcff1e548e0f424980cc7785fb6f87f911360165894c48ff6dc8394c024f1b494f2adb7f63efdcb5ffdea9d73fff7373e733e1b4ba9339dc0d4117dd5597d7459f7880888a95929720026012570644202209a5e5f79756da0b8241a892e59b4c4e7f35b1eaf69a0001032692ba6228f4026a3b220f978a9827ef0d209bf8d13a84c050180808c9c8bb480228121204894c89260bc08cf3ba48c2a1d5b991343caf4ad5035fb5b09966492094001c01c860ef0036d67a7224ed2880700402e81239372d2014959be84b2f604a4329ebc0fa74bff454ea0b294e45700c950825421acc0a4b372719d9835ede77875afc2906b8b331dd70fb20c416d6f741261487c0380e0208b21bc76b87378d2140e9aa6e3f77b2c14d158424800e0339184835cd0fd056788129de48fdf9d5c7c83ba7e75f1f7ca7a85b9cebc98cb62ea4c75b278f70ffe5b15044040074082e4122522a0742c88d43754da28043ae4ca72ef2b04009d995c204b2f2b84198c71c6d21268abc86e640840d93d90a6a40c001977c00878f9ca15f387c6675e79edede18969c9a48946635515e3122dd3e10cd00409000251203229194864520a260502022954701803290c52ba8c4263190a81201de4e4be6712053204218540e002009904104c32092810243a28912148e17069388092018264824b90923928414ac611413a120508608c3b92920a0bb54a2e9009449436938c014729040a4826cf0185120aec905232e0424a0406924904c61c47c419b35072900ea00d696e8bdfbf486014a222194a892825931229e51fa0b25ce65cd27141aabfbfbfabababafaf4fa5e16b6b3bdadedece184364fbf71ff8d5af7e451b788e1c39c239a7b5200010427cfffbdfff7f1efed778dc0600100e023040af215ad72e181e3cf7adeffce06c67ef156be66d5959579213c368ef8a0565109f0461834824ed7ee08e7000138cc519cea08c0330292582942805d892092925a014200448943647412e5994292b4f4a2105a3cba12905a5491212002432c1b810281c00c620ce20215148708009211d09201090315b0ac18444901c1392494489829cd052300493096042a0044426010069c432291093662f0d778152700652da063206923107514848300608524a313b0b4b4af2317ebfff4974547d18243da21239033092c0c22cc0d2cd23fa28a5eceeeececbcb2b2929b12cabbbbb9b31168944f6eeddbb7ffffe582cc639dfb163c78e1d3b2626267a7a7a5e78e1053dd4ff7bdffbdeea35ab57ae5af9375ffb2a4a0064024080a808e615e59bfd034333e1786961deeac575375ebde2eb5fbcfdcfeeb87a418daf20c796099b03e3c22ece85921cd3401e2cf336d77baedc58cbc10640a43c475270400426106c9482012020c6376daa924c220303eca23c1341308816e619e412052118200710208474508221c02b13ad1bea39b2b262637173314a01202524184f3a6a04381466e10814604ac61d1092de7e251100418029b0d4679ac8a4a0d04510422272004348261000510283a4df4b204a296d860220c621caa460c0a4701873001c98ed2a17c8deef32e7660a4871d5f8f8b8d7eb2d2c2c2c2929a9a9a9a105e6bd7bf75e73cd35353535c78e1d23f577fdf5d753ea0efab98a6ef8dce73eb77ad5aa53ed27376dd8c8504a602001c1f158322fcfb361c5fc05c1e203078e7eea8bdffde4bd3fbcffdbdba742f16041cea2ea62331163124c887e7873cd073795594ed4675a053e2ccbcbe1c2e16073e670699be070611bc2611218482e6c04c964b424cfe4e030276ac0d4559bca11a31e086fdd5883e870b419861043a6741808c61ccee2880994a1d27c0344d46bca7c3f3764c2820417920b30a53045c210094b240c11371832615b3261a0638063c9b825639c45184638844af31dc30000018ec3c006663bcc16dc06e6481012194a06e8204ae9380c2463518030930e9336979209692093d2d13a4400084c5bf47dbf4bf65921a68bcb4e97520e0e0e1e3f7e3c1c0e4f4c4c5e7bed871171e3c68ddff9ce77eaebeb11717474f41bdff8462010f8e77ffe6721e577bff7dda58b966ed97285045ba2231138909a4cac5e52f3837ffefc6b7b0fb79feaded736f8ca1b27fa7a06eefbc29d931353066331e62c6c0e1e3ddece396b5e5036134980700c296a8bd88225a5cce43d7dd308100d870c0b6d96170dc74af2e481e3330c8c7c9f75dd96da98e3741cebf4a1bcb1b5e148db998aa29c1bb6d4769ce85dbf6ed1d8f8f4e464ecc0f1d186faa2f0f4cc999ed8d557af7871d73b0c732f5b5eb7f3c5c38b1aca1beb0a2231d976a47ff9a212afcf1c1c8d9e3a3dbc7c51d0f07bcf9c196a5950f5dc8bed8539ceda95f372f3bce1581ca43c7dac77416351efe8d0fcf979f3ab7dd3d3917d6d63a1044a6117f9e5f245415faef778fb407ec05753951f8f8963c706375fde120a4d0d0e450a4a0b86c742078e0c08f06032a496316120a440f63eb2b52e20692f42517ca39bea454545a150281c0e47a3d1d1d1d1eeeeee50282484686c6cd8b0613d25fd4144d334efbefbee471e7904114b4a4a1e7ef8e1871e7a0800fec7fdf737d6372c58b06074641c00011c09200167a6e36393b1279e7be3b9570fafdbb0e04f3f79edb69b3703e78cc9a19181b33ddd710064b17c1f7a0de6b1588e250dee08860e42d382f2c3c73a77be72a2a1b1c4346cceedea8aa2ba324faee1980c106d04190ac577bd74e2e0be93cb16d73952fee2e58ec1e1c8c858e897af1c8f0bd1d135f2cb578e0b74f20a723b7b4383638e444083d9c261023843e188a52de5c37d23870f9e6da8cdaf28cd45908b9a839525fec84cf8a557da7bba863d06d20aa8c52507b9ebe5a3bb5f3eb2f2b27a64685809c3140cc4c2c6b2c2029f7018075e5d11181e9979f9e5f6fedef1f9f34a5edc7de4d8b1bee605f90927fed2cb076b6b8a76efeea8aa2820ff8a1414512200a4445ba2936172bdafe5c2ef84b62caba9a9e9dcb9738cb1c2c2c2f5ebd71b86b169d3a6e5cb971716165290d6d6ad5b29bbcbd6ad5bd7ac594330a5fdd34d4d4d7bf7eedbb777ffbcc6fabb3e79a7f2b9f50d4e9d3937da3f36f3c48e1d0f3fec14160546a667ea8225b75f7f79e7d99351614866e679a0b9b1f25ca757326c6c287aedcd76e4a64009f0ffb7f7ede15155d7a36bed7326f3ca242104f2180824e1150482bc0d6f44fa7105ca43a5b456fc4a8202f5b67e5fadd8a2adf5d3aff581a5404521d7801705a480a95cf50718a40a28af8072110821ef403299bc27999973f6ba7fec73ce9ccc24407f6dbddab2982f9cc7defbecb3f73a6bafbd9e5c2600ae30e09eebde0169c995353ea606937a455f2ef77292190455c420b3000408a520481c994240488841ce5540055980402522bbcda20455d6ee27e0804c26050839caefbd5fd42fd9f93fee1d79e142c5e9a28ba5150dfdd3fb1200b2280ba92838741e409d0352211ab80f000021a9b7c369a783878f678f1e4ac4dd4976b5dd0708049c1347440221a153051fc78971000249282d193040899340264d42a98b1ebf1bd06d4e6843107ae1c205c31e4655d50f3ffc50686cbefaeaaba8288bc562397ffe822449c78e1d13cbe5e5cb97df7efb6d6353a9f39dacaabaf2c8d1c35923ef94008013675127ce150f48edfd9b5facf436f890a9401d766b5479c9a55aaf0fac891616852a3f5fec3d59544bc47d0ab4fb9137f36b56ffb9d39563c60ccab45b4e9dbe565b4bfdd2ac178a1b18b4f748ec51e9092a602554aaeb7d0186ed60ad69502f7e5171cff4c1e7cf579d395b3d6b6ad695e2ca81e9c9b1713135558d5e8fcfed8ef3234f488b292bf72aaa347182fbd3cf2b55b08dbfab9fcb2e1dfaaca4c1db72e71dee2903075d2eb95e55e5bd63887bfa8c91978b6b3f3d5979f7dd2324e0b59e564b3b28646548d7eb3b3a02eab5ea769bd5316dfa645b942550521517c7da39bf52d238fc8ea4a93312bfbe78fdf3d355d36664b5fb82274f578e1a6955d176bdc1af22abf5b613325de980a8e5aa6100d4495bf7ad874eba426337279902f3092da108b1e272b962636385a5b2cbe58c898971b95c3131710e87c3e9748ad8eea22ee86e1b20364b9c010230be73c75fbebff8813776fdadac51e6416ef1b7f6b0c1a041c9310ea9f8d2c58a6a4f077372d623cad61365e4a81232028b36a614640c88889304c80855e0321222538090319543901310da1038e3c49814042e01930838282884469cfa244725a6c49d2caa619c11c82421417b66460c27eb952bd7664c4e3b76d2d3e25310397140b400e7c848416488c45504402671ce8008192754191071a6822c2149c48144386a154105e02a49c0800171625a945e9009383215891397004828bf8018810a0840320092a10c13bc1572cd7df7ff2b7004460840848424211100c9e85ff54056f5e52f0b3e3c7ca4a8f285a757de5ca52390a3a4a4c462b1c4c7c78f1e3d5a446c3f71e2547272a2881d75f4e851229a376f5e5d5d5d4d4dcdd8b1630d1c25a23fbff66740f6939c1c9bc5cab5bcc3845c952c32c7182fe77ffbb2c20e4109a5a03d8545d964e650515298c248884083888c83ca00402194101927e012070e2ac89c8003975402420ba205891831069c7305191057901821a90c114002acbae6afaabd46c448b21257382984f2a5cbad1c5a012d87ff5619240460848ccb5c520911388870a6b2ccacc003400a0340267312ab1a00a816a6aa80010446c84005520911d12a71524851183221d14540548908540094900171890123509029401202720832143828c444322111a8ecdbb12b6484421dc7743b5204356c9d0e8f9a0c9d6d66105155d5e2e2e2be7dfb0a678ae2e2e2b163c7b6b6b61e3f7ebc77efde23478e8a8b637bf7ee45c4499326d5d4d41c3a7468ecd8b146831b376e9c38f12e007ceac9d5afbefa2a310900927a58250c7021e26116801e327120e20c099013202a5c130d09e1070fe93c8134e52181b80ec22b517cdd141466429a151900222011681a7995116a0b0d0251401403000618f2320310c274224250751d3e0128080a8016e8105021129a0512da1d8e4655450c2ba00ac401c54aa6a2781b63ab445cc714ae795a86dcbe55938e4ed50ff83f1b49fe7e4021b42342105f2bf1a005558b042a20d77bdf058f6566b0841ccbe170242626daedf6989898d8d858443c76ecd8dcb973ebeaeace9d3b979c9c8c88f3e6cddbb3674f7676b6b92900f8e94f7f8a886f6d7b6bcae4c908403c2801ccffde782200049500f0661e1db7e15b06a4ff157a69094188e04b4865ba64243cfb5718185a6700d0fce51139e742fededcdc5c5f5f3f7bf66c00983c79f22bafbcd2af5f3f22f2783c6bd6ac713a9d7ffce31f0160dd9fd68fcc1a3165ca1400ce202891ca8833c63efdf453afb7e1dfd3d0f2df160ca462042884e83367ccb0daed00c48898ae88ea44b1bac4ad9e3d7b5655558930846d6d6d353535696969443464c810a7d3b96ddb3683bcfde4273ff9d5af7e25a2e66ddebc59b4f6dbdffe76ccb8b16919e91e8f2721215e6212220021114dca9e04c20c430b30f3cd5b83dc2e708b05a00bb51221001a26eb844828712609a9c8cd25ef369b6dd8b061c5c5c582799f366d9a2449d3a74f1f3d7ab4cbe51281ed67cf9e2d9cbd66ce9c3966cc1866ca8e3464c89053274e9c3a71223d3dfda1879672600012e869e208808594f766b4c68883db05be55058c33122c0d01aa2862bc0018886596bc8709488b8a8a0cd1434747c7eeddbb45728093274f0a0bf73367ce489274f8f061215ff8faebafb76fdf6e3445244431505959f9c92747c68e1bc785c42fa4fa42c3994807d2bf0f24e2064113b748b768242de399c1101bbe0c641c849aed2a8553672063abd04d81db604c8b382141b584050d10325099bebdb8915fa180d1a3478bbcbd4ea733363656975d697f9d4ea7d3a999ba8bdc71268f42d47544463f60d7ae5d4c3f266da78ac23d2d4470090980218aed5f881c8bfd88f08d44cdaf0699e97551339c15ad09ac230c35ad996aa3d6a099d083d103869c13631856e05bbb4a7dd30ba1f1958b2911234a44008c64469a6f731766336630026a996f8559b547960ffbe2755f080010ba2f0462400c892169e63bfac26818c3916e4e05efef7fff4f1b365cba741140f81869b29d53a74e5dbb5e4344fbdfdf4f009cb4a6852d0001e79a10426b568c2032e05cd8d36b17c5737534178650c029bc4097c7ff210574e2409d7ea8cf2e2220d32c3175abf79bb8d8333d6f582432859ddea01da339b1cc9040351d83402340061069d9eb40519477de79273ada3565f2c47dfbf6cd9b37d7e9747a3c1e22183a34f3d0a143bd7af59a3163bacd16c510ae969679bdded4d4be0e87e3e2c58b44949898e476bb3d9ebaf2f2f21e3de2d3d2d2040269125a0c7d840000484fad7eaab6b6169175ba7e1bba841041070040948878e9d592d401c3c06c9a6cb044069618b812d2cc74f69530d0ce2869c6b0cea8c60dc648ec520db2440002e1c37b4d04800d0d8d478e7cba79f31b4494953572e1c2452929296e774a6c6cdc81030725493a7ffe7cfffe691b37be161f9ff0d1471fc5c6c6ecdbf7dee4c993376efcf3ac5933ebebbdf3e6cddbbd7b777272d2800103d3d2d245afc44a173956a5a5e5f9f9ffcb6a1579c86f735add00e9ff61680a853a73edab6b4f7d794978b486142f00201611d01690505206137dd2161ac6c4baaa02081b48d5f86b9431fd746a07228a9ff143ec5a8865d05bed3d0c460b11962e5dba72e58acf3f3f4ec4172c58307dfa34225e5c7cb97fff7e2b56aca8aff7f87c6d13268c5bb16285cd66bd76ada6a2a29c73ee743a44533acb1ff1488d981a4fef1446d09c75d6b868f60e378ecd058c53a380f1b7cbebe6a6c2ca845dbcc115d155e356d869976f14f9d0c83e84fa86401a7ba10d979856413690182342baa1cd7b57079d089b2060000c51fb81196d42bf6ea1bb7ba2fdd8d8d83163c61c3870a0b4b474ddba75bffef5af01a0b2b2b2acac2c2e2e4e24c5a8abab0300a7d3e9f3f9cacbcbc5ee81f4b8d0d1d1d1cf3efb6c4a4aca8e1d3b0c16b03b30eefafd7e61e07f83c2e65acdcdcd656565a5a5a5adadad61b71051f4d078bacfe70b2b16080444758fc7632e69ee5597e4d39875f1089fcff7fbdfffde68c158581a1b1bcbcacacacaca2a2a2a8c8ae6d566dbb66d57ae5c11415f84ed9d2873f6ecd9bd7bf78ae39a9a9ad75e7bcde89b887a4ca61db4b81ef0fb8973b8811c0b4c4b1be9d40bb193bb8e69ebd71d3e75de78dd1aa01e2dc262b12c5fbe7cc78e1dc78e1d5bb060c1f0e1c3df7cf3cdddbb77bb5cae175f7c312121213f3fff8b2fbe58b264c9bdf7debb77efdead5bb73ef8e083292929f1f1f14424f2a06cdbb64d96e50d1b3698336252573205e3ad3d1ecfb66ddb0e1e3cf8c9279f60e7549ac680182db4b4b4ac5dbb560cc5a2458b323333c914ee9c880a0b0b1f78e001e329858585353535cb962d33aebcf9e69bd7af5f07801123467cfffbdf370f823810b3d8256e0983de471f7df42f7ff98ba228c2523cecfb59bf7e7d4d4d4d7272b2d56afde52f7f69bc82f12225252522cd16111517175bad56f1168d8d8d151515e24d3b3a3a44ba2163eac184f4a41ba3b7b4b4b4b55900f84d0cfd22af44ecf8b0cb2a9d81ba39eea6b4a9bb002002bc0000e73c333373f1e2c5090909e2cac30f3f6cbcd2fcf9f38df4606eb79b8884e2f2e9a79f16850d337c4378dbe57301c0ed763ff3cc3367ce9c0180e79f7ffeead5abd3a64d8b8e8e962469ce9c39ab57af7ee289270a0b0b3ffcf0c32143862c5ab4a8bdbd7dc68c1949494943870eddb66ddb279f7c3260c000ce794c4c8cdbed3e70e0404747c7debd7b7bf6ec999d9dddbb77efad5bb77a3c9e279f7c1200d6af5f3f7cf8f0471e79443c7dc58a151b366c906579d9b265fdfbf78f8f8f4f4949d9bd7bf75d77dd3575ead4a3478f7ef1c5172929298f3cf2c892254b060d1a141717f7e8a38fd6d7d7e7e6e62e5fbe1c11972f5fbe69d32644ccc9c9d9b2658b78afe1c387676464c8b25c5d5dfdfaebaf5755558d1b372e3333b3a0a020313111117ff7bbdff5ecd973e6cc998cb1989898e3c78f7ff6d967d5d5d5b366cdfaeb5fff5a5050d0dadaea76bb3ffbecb3fcfc7c227aecb1c7f2f3f31b1b1b25495ab264c9dd77df2d26a2de5b1fc03825a8dcd25268305bdd95819be35668fa6e05b7d024cf342e32c656ad5ad5b3674f30510eb34750181d32568ab06fb4cbae76b9f30804022258e6b3cf3e3b6ad4a8c3870f9f3871a2478f1e76bb3d180c22e2ce9d3bebeaea7273739b9b9b0f1e3c78ecd8b1bd7bf7e6e5e5ad5ebdbaa9a9c9e5722d5cb8b0bebebeadad6dd5aa557979791f7df491aaaa4b972e5dbd7ab5e8704b4b8bcbe53268527d7dbde8b6d7eb152dcc9f3fdfe3f1646767f7efdfffe5975f26a253a74e151616262424e4e5e53dfcf0c36fbdf5567c7cfc962d5b060f1e0c000f3ffcf02bafbcb269d3a6c58b171bafd3d2d2d2dcdcdcd4d474f0e0c13befbc332f2feff8f1e3f5f5f51e8f67c58a1500f09bdffce68d37ded8b16387b0412f2828d8bc79b3206ff9f9f95bb66c118bec73cf3d2706f0c5175f6c686858b76e5d5e5edec68d1bc58338e7aa1224ae12a97218fb8688aaaa023023d89a6a0245514414d0402020a2dceaee152a916a0499d179af4ef45c900a3182b708066e1984d7c01e23837c6461f3296adb401e56d28c88dddd0580575f7d75d6ac59e3c78f5fb060416a6aea8811230e1d3a3475ead473e7ce5555556dd9b2e585175e0080f4f4f48c8c8c77de79472c1c4653d9d9d991dc92992346c43163c69c387142242d3317161d98387122223a1c8e51a346b5b4b44c9830212f2fefead5abededed7bf6ec3173d6c607939d9dbd7ffffea6a6a6a54b9782cea4cf9a356be4c89188b875eb56f383468e1c69e48136862b72548d6e3b1c0e4105f7efdfffeebbef86f5161109486cf265225214c598789d0084124f04834149920281802ccb1d1db291250011459a42550d0682d640d06a58304b922e92d02c8c346e9a73ae07a3ba113e85112a339f073acf61701291236b1e2633fe61679636acbaf9298f3ffe787373f3934f3ed9bf7ffff5ebd76fdebcd9eff703c0d2a54b9f78e289bbeebacbe7f39d397366d9b265b5b5b553a64cc9c9c941c4214386e4e6e6daedf665cb960d1c38b04f9f3e369b0d11070e1c48446bd7aeddb163c7e2c58befbefbeebcbcbc975e7a49a4debce79e7bce9e3d2b58ae091326bcf4d24b2b57aee49c272626f6eddbd762b170ce33323288c8e974ce9933272727272d2d6de5ca951919190060b7dbdd6ef7fcf9f37373731f7df4d1b4b43422cac8c8484848b0dbeda033060e8743bcdddcb973376ddaf4fefbef7fef7bdf73bbdd1d1d1d00909292f2d24b2fd9edf6152b56040281e8e8e8871e7a282727a7adad6dfefcf98f3ffe786e6e6e3018cccacacacdcdcdcdcd0580356bd69c3c7952f8248bee69bc1732cdece1c081033ffbd9cff429214962b22c33a6852eb25aadc22ed9e572391c8e9818116d345a3f8db1dbed0e873dca1a658db24ab2f64f629ae84b93807234a48e1f7f5cf8e0830fde08ad742c89c4b0afbffe5a4c64e4adeeb03392b61984cd8c64e2fa0f7ff8c337df7c53e49e8c44f1307208a694a4e6a536f214005e7bed35a1a1efb293c681c12f9a49b5b9d9b0ac74d0f97b30ae2f5ab468cf9e3d069930f394660ad45d676ed049a3b5b06e8b115ebb76edffdeb1479113fef4f2d3b211149931266c23655996248bc562b15aad22cc9add6e77381c029f84ad9fcbe58a8e8e8e8d8d75381c22f09acd6613190e4596b9ce443544246459ee8ecb31c03cf744b468d1229bcdb67dfbf68a8a8ae2e2628158911c98310d0f3cf0c0ae5dbbc495bababa7efdfaeddbb76fd6ac594b972eddb46993f88e01a0b5b575fdfaf525252500f0f39fff7cd8b061e646ba1ce848c62eaccf605aefcc2d2c5fbe3cac4a1842845156f3e899572233d1555555f84189f2e6aeeedcb9d33cc89103158634dd610ce8d86c7e44e407663e365e53362a43673c30b3026123686a57e8909888e409a0fd153f6380ba9c9e1b83c1f77cf0c107b367cf0e068385858588b87dfbf653a74e4d9b366de1c285efbdf7dea14387eebcf3ce1ffff8c7ebd6ad7be699674e9c38515d5d7df9f2e59c9c9ce79e7b2e2929898866ce9c595050306bd62c45513a3a3af2f3f34f9d3a357dfaf43163c6b4b5b5ad59b3c6e572c5c7c7efdfbfbfb4b474d5aa555eafd7eff7272626d6d6d61a71e75a5b5b0525131fe14de96518449234f32475771a5638b21d7381ee1e018000061fd249e6645c345717b81c2aa6cb8bccb366467173ddd2d252b4448be05932088b70ad84a0346128c9056f0e2064b5c0398858a0ba5037d4d7ee68a971702b58651e9a9a9a1ab7dbedf3f9ae5dbb969898f8a31ffd68c58a156bd6ac3970e0405151515e5edee6cd9b0b0b0bcf9f3f0f005eaf5784da160ca680949494499326eddab58b888e1c3982885bb66c79eaa9a7468f1e3d67ce9cb7df7e5b55d5f9f3e76fdfbefde8d1a300b072e5cacccccc1ffce007f7df7fbfdbed4e4f4f4f4f4fdfb06183f0971c376e5cd80af52d03b13732cb11d174fde6a0055104d4229d2021101247ed66b7d34744252525e72e5c2df31031490edbff7749a2ccc7669ceb92a4fde360105eafd7bb6eddbaacac2c222a2a2a7afef9e76fb08c0ad7d9c8ce23e27df7ddf78b5ffca2a6a6266c95c9cecececece7efdf5d7c5826854b9fffefb4502ec3e7dfa6465658d1831e29d77de193c7830636ce2c489fff4f7fd57823120b73e4dc27e0449e8fb88cc32eeee5c1bc57c454747d735051a822d9224756bdd60a240da1ac73988dd2211e75cd123a5706e265cdd10adbf170c323b63c60c6138bf7cf9728bc5f2eebbef9e3e7d7ad0a04163c78ebd7cf9f2b265cb525353efbdf7de8a8a8ae5cb97d7d6d6ce9f3fffbefbee134b617272b22449369b4d96e5a953a76eddba352b2baba8a828272767f0e0c19224e5e4e410516a6aeadcb9732b2b2b737373870f1fee7038186356ab55688df2f3f3131212eebffffe9933676edebcb9a0a0e0b1c71efbbb48ef770d349a2748166a740b40c728ec1e47af5fbf1e171787e56d0018725845dd5a4144c0926559d8ee399d4eb12b14dc7a4c8ccbe58a8e11d16d5d2e87c3e174ba6c369b286c481c5087b067efdcb9d310dc75075d720cd059914226e19651318c238ee437bbdc43dd8061fac31ffe306ddab4f1e3c78775a94bc1fdbf07700825010881d8dd035084059f79e88e1f3f5ef0e1279f9dad7ce1e91b06b715d50c7523e9292a48c250ca8f000008be494441545743eab7341be3aea6873a53e35bfaca0db44093f4b24b8631b2b7dde156770f8208d434364744b46cd932210132b389b7f20adf1ab8d531374a0368c948c9545fa05a97af1e39202a11279055550d0402c69430c6844454446a10023a4551144511c9bd3a3ada7dbeb6b6b636e1566f881bac56ab39eb8999950113b10906835d4e7f77dd356b6c8c5373f91bd48ddcb4475e8f6cc1780422f6ead5ab8bb1fc8e009120319c08c3446ee6329dbf406421ba242a000724242462da72d829e1adc13285c60d1800ca8c016320f68388da12662401b0e820a45942a025a2ba0bb196c02dabd56ab7db2c51b22c5b645912d99fc38ce9c4bbf9fdbe73e78a0c42720366fc36fcb7802102e791fb18d4250944d449eed069874b88c480110795a130d766044c84eb24ae6aa1f3cced221a12b5eaea4a00ce810048067dca89884815316ac9945a5c80205a611a430d143f93400a32d29647993126b43ac67700a009c1274c18af280a11288ae26df05ebd5adae06de45cf9970ff87f061031c6508f5f6a88a698111a1451e5c4413f2122a6fb1000a0b659232e33225209197186202348042a31508187716044c424465c3311b6d99d92247340b97321ae13c14e60ce626fb059c681518a74e34ce36bd1c9928aa849cb12937aeb2c1a45bba22d164b6b4b1bef1416f136fc03a0e792100c8cdd6e5755113347d2c493a86a01304c127c2350231059488d0e2ace802a01b55898cf6209a00c2421439fe28fb25b41e914ff238c8bbdde10888eaed7c40d06031429c90c235d82629911ce8c5ea0c9e23991c602eb8c1172ae619ba11f4004972bda6e4f53d5ef5268cd6f37106941a611885a5b9a7b2526b6b707546e292dad68686eb6da6d8949f13d62ec320a0e0a1131100830c66c361b0582f6805f2eb95a76e94a7d756330a040ac2335a36fd2a09460efde41496a686f89eb151fec08188f03b1188504ece8aa69721e2f0f976319a867265410815e5de153e8962431339aeab44a7b84896d078bc5722baac3db70cbc009552019491281c99d0e3ba0c5afd89ada7170567647c05f57578592ea4ee8213164c0112910253394ec366b94d21238f795e7bdf75b59fca7352d4194fd4d8d291f7f3e6a4446d69279b103d315e688714477487eed697aa62330512cbb3d48921559f7025201664c12e4ca38361f18881556b7cbddbe81490613761bb1fe49c0806440a6c56d6212932c2a041b9a1a9151479bafe44a795b4039ff655952425c8c8d8d1b31c0e6107ee872545055be38d5b27b5ff09af78bebd5be3bc68e9c371d255672eee2d9f28bf1ffa760f08f7ec86263190263cce45c0c00c0759b28c6989e0434c2e6ddc024d4edf222f92db533446058a8a92e31c6bc25011399bc0dff2020218a58a62286bc08d6a6404363abaaa0c32a8f199579adaef1444bdb679f9fb3045bedb2326a4c2690c4408d6a6b2fbef0a5fb9e7bea8aaf59f77d30b4b97268bcdd75c7c029f764dbebaa6b776cae3e5de49a3819486c218d29e3a4ed2b795353a3cfe7e3142d6e7461fe11761a6647ca3b835100420b62275cbcf970dc2657ff34200684c839ea11140855159b5b54901ce5959588c192fffb755abf64004e14ec999c00280127e25cf175343434cbc387c5ce99ddd6d7dd5251f1c1136b5e5ef5fcf3bfcf2f6d064bbfcc6b25c5b212943af9ce694a0822f27aebcbcbcb62636200b40034370f1519c65a855129f3a9991513756f23cd370c048af02217d2050624a1446069f7073d0db51919493f587ccfc90b5513278e9395a6d89ed12a06992ca1a230408b6ce52a4b1d3dea7fee7afbcadefd35fbf73baed67c5edd987fe9d263e3fb5a2c519ca11ee10542b60b4435d5d55eaf774046060018c2cb2e623798f9711e01918ba019441be64dc037309ab741002170469c8918168c1100a95116723aa5f6405b47000bff56d4d4ee2f29bd3865ca6849a696462f0057b90a68c168bb332eda77faf47fbdf7717ec1c7f6a91307fdece769bd5d77fa6b333de55459d627f30e5592817131bf2852f412555454343535a5a7a75757573735351933de058f8518c22ac1947547abc288964eb13811a31b2af56ec3bf08081850287712223039909a1a535153e9f7fb3b7cb8b7e070f65dc313a2a35c4e5bfd754fbfe424e48810e5b75b078c1d7be1ddbd2df12def9faec8dbf65f292ea997d737d1ce47589a2db18eb83b86d65a983594768510b1a4a424180ca6a5a5151717c7c5c5a5a4a49454b7889e749b6c3cf222e972ac3008e3ee5535a4c4657a96b97fe560de8610102282d8b59108cd03a4c6465bc68f1a70fa54f195cbd74b3dc1da8a9aa183fb5dbc7876c6cc6cd282f70415d916356c6806e37cef81df0e8e76f4744b00962136b5b6cc969a92b470617b8f9e14f023000222c340c07fe54ab1c3e1e8d5bbf7e5e2e2a4c44444acacac04162b7a1249b1c0a0585dae86aaaa98bdc122574633b5333698dff808ff87821e4301008890382082cc54b557ac6de2b8c1fd53e2af9696363735b6fbea264d1a9b9a9a42120b2a8acc3881d2618d8a1a3634ab478fbaafbeaebd7435d0d21e9b1ce79eb4c03164882fd61e90500d10a14ce01792d1a4a4949898e88e8e8e7ea9a9ae989896e666bbdd7ebd495f0a894815bc11111143e4c40911b9b1ad4402246400484c4249462649b24546262193001191ab8ac255550906ad369bd56a9524495839a088ef701bb1be4910fc35923f186c6a6c0a04fd0848a032647ddcce3eee4cd44358b5fb7c24d4831cacb2c4890801137ad8268e4f1f371638912cf9644b0393a1bd5d250a06785363a3a2061081736e91e5765f3b003026b5b6b44a4c220ea404190480b84c84c1a08a281111810ac2e1109121aa2a30462ae79c90137262807ece99c2254595dafda8a892df4ffe0059dbb8d3495156458e0a44455985e3a12c4b88c01803c4904debb72a39fbbf7b014f63fd7fa3050c9989aa0401320a23d4357600088575580b2064006d41944446d9b2f28a23478e00000072ad1280b65d4414e9709924fc349890adca127040c6648b0591812c11a22c5b880851222049621c50d6769e6816a8dd86ef3adcc0741011546480512306f5fd7fb0ce129839c4a7d20000000049454e44ae426082, 'image/png', 126, 0, '2006-09-28 09:00:34', '2006-09-28 09:00:34');
+INSERT INTO `previews` (`id`, `addon_id`, `filedata`, `filetype`, `thumbdata`, `thumbtype`, `caption`, `highlight`, `created`, `modified`) VALUES
+(2, 8, '', '', 0x89504e470d0a1a0a0000000d49484452000000c800000096080200000014be504e000000097048597300000b1300000b1301009a9c180000200049444154789cecbd79981cc5952f7a4e446656757555efddd5fb26b55aad1ded0ba805c2181b30020c18e30133e3198f3df6e7b1b9b6afc7331e3e2eefcdf518ee8cafafed798cb187f11bf03306592c360221c0c22c129290d4925a6a2dddaddef7adf6cc88f7c7a98a8ecaaa9604e3057b743e68456565654646fce2774e9c387112fbfafade7aeb2d00000029252242baa0046028a4440007121c0c94082850a200049408524a0494c824020340440e40d7918880c8e8b2eae2aac0189bbd11e25ca7b9ce747de5fad579ce994b321f5c4a79311fa9a07f5447f4b27e24ab500d5d77799f89b898ea09c05024debaf972a3bdbdfdbefbee3bdfb91224130888c06cb4994426984007814b00891285648c21034489cc404444ced0e00c0104e3c8900e2281833196f5a3eb2bd4c4759aaba030371734e7429e3aa83799eb88ea78755008311756e82bf55717c771e8a09312bdfcbe859482bb940e3dd7f987a823a17f70e2dfffed11834e154270ce6ddb7613830490c08051c3318e5230008608d201644c8260cc400404c118678c0170869c730ed23138030688cc05141d3afa5799789a0b7f90012f55501f211bf9b9da25b39932c9c90532d54499a8a2a6d7cbeaaf02966ddb9c73c2932abc6fe1258480f49179fe4a4a0920011918f46344741c873acf75e6f4f4a40d0e32404401c0c000474ae6a0527660004a8327158a811c9131099c2143292548d32b64b25a9c7300282929a17b65721866883a473d9baaa7eb1cfd887a001d522e78e9e30fe7d6442e60652a3b85a74cde9252123971ce096d8c31c2197db46d5bc79642a4eb297ebf828800a854f6f9ce04900020c180548bab36d27f2951740ff7f88a3d8e70101010e353098fc7629683527a2c8b034e0c47cbcbfdb64c20480e6c78281ac8b1bc26935230900eb09e5151122ca7c6e29c8f8c8cf8fd7e8fc7e38211636e62831463b90e66aa451775652ac7ccf2c53453b21134244186cd84883a5165c2cb7582ae04e95be22d521754209e781f12d8c5082220a2e11abbae869620d102c89388022472641897dce7587ec9c0f199b62131340df98536c838038902e333b22057fa73e2281c2ea523adc149aba0a0005280989999e19c33c688bd5caad07544ffca851b17f82003582eb4c17935e35cd683debb996a1100888432a94b018b732e35938b182b531b2a26239b840ea60df20bd937bf3dd1e9f922ce0609d2b8f07949034a20807004320029a4b4b9c940242cc300100071e47194881211246712659c4bc94002721d348a99942ad48f679ee9c25c26e0209b66d40749e6c7d4635dc0d872b56ce6dff3eb4497bda544e94497094f78a221c7182302a3332fa686ef37b9086051eb80e48800081201b80487734326128088c000989428a54460c8d016427226a440892235cc6868920e22bac28b33e1cf436317032cc82030c8ce58c2f5957a7a48b205038dc0547fcb39c4a51f3327898430052f65d453e328fd48ecf55efbf7f72617001602a2cd3cc283204182214ddb4e706999cc4a44e23e6f6e2222c00694b95220302624c49db8e479b68c300409d20603100dc310421886010034225d7a50115826b0ce0f2fb8d084910e2a73786ede4a23866cb43f3b19ccfcfb6e81a5f396c299ae130dc3500446d85250fe83900b014b32eef0e840421808121c2120ce6209273e23393362427064c286735d714086000868c7ac8178dce20c253200092084e8eeee565d188fc7a9bd2005b2b9180b0088d8328105e9ba12d27d5a99c00220e64c3b4e7f924f8a3c55c8d20e524a3a41d780eaab4cb528330cf9acf022a222c3cb05ac442281295381739e4824fe80a84b5e8c2a6c9abf404a011c1011241adc608c912fdd600c91316e30f29f265192fcc7303824bbdf04444551aaa054585678a9d3521761fa5c4fc7a57ec485330d58221d5298415a4cff98c95b38eb2acce2e8525f11af887407849452f9b1a43637149af74191161da147a38faa71ce4f5df87ef2dd5f1858b66d4b292d662160341ab5fcd6d0e0506565658a20180202607bfb89254b96d0a16834dadbdbdbdcdc9c34a478126184154801c2a5fe8e1d3bb664c992e1e1e16030188bc5fafafa9a9a9af47320c5589cf3d1d1d1f6f6f6cb2fbf5c8726cc61dd2baecaaa0a2f12584ace0f2c17c214985c7343a50a75439e40a3a68d042cc33012898432bc6cdb4e2412425cd402cbef512e0cac70382c8420b7d3c0c040535353595919002022cd5c0cc32083809e3f27270753167a2291f07abdaa9920c558f1785c4ae9f57a0180d48165590b172eb46d7bfffefd5bb76ef5f97cf5f5f56ae26d18065d271a8d32c67c3e1f35bace6a2e4b2b83b7d885807581c51f25329b03e282c012e75ded512a4fa4fc5e7450f9b714b068ac12b65cd425d27d90bf5fb930b0a494535353a4f2e9693b3a3a162d5a343c3c1c89441031140a2d5fbe3c1a8d9e3b770e11cbcaca727272e8993b3b3b6b6a6a7a7b7b2b2a2a94b77d7878b8bfbf9f31665996c7e3191c1cf4fbfd8d8d8dfbf7ef6f6969999e9e6e6b6babababebecec5cbf7efd3befbc63dbb66118cdcdcd96651d3e7c9873ded8d8989b9b0b290091093517b00090b1f33156d6bfbab88e640596fe315339ea2a52b7b764bacb54e14937e7159e68e812b0c8ea227865ade4ef5d2e0c2c44f4f97c85858584219672068e8c8c2c59b284737ee4c8116291e6e6e6e9e9e9e1e1e1eaea6aceb961183e9f2f140a4d4e4e2e5fbe1c520aabbfbfbfb1b1b1a8a8281a8df6f4f45456562e5cb890be6a6c6c3c71e2c4a64d9b26272769e04e4f4f5f7bedb5b66d23e29933672291482814324db3a5a505d39cf5d2c5522c7d0988180bd2380c208db12ee0e8ca2a3aaa44babb5c64acf3a8832e7829bf83cbead26d2c256a9e481fc9a88714a6df3ff0bad0ac1011002ccbf27abdba55a40af4302cc3f14d120c064f9f3edddcdc2ca5348cd918072a74757511f81426f4392089611852cab1b131446c6f6fbfe5965bfafafae88788689a26992fca36e79c4b09740748f33e70c87046e86544a93f324b5f8c070080e488cada7999aa102e3449cc548bcac6d26d799e214cf30252d3911d4ccff23eb1bd2ecc58645dd1931414142022b1d7a2458b4e9c38a1467959591963ccebf51615155996555454c4390f0402e17038180cea5eabd5ab571f3c78f0c48913cb972f8fc5621e8f87beadafaf678c5d79e5952fbffcf28a152b2a2b2bfd7eff92254b76efde5d5e5ebe6ad5aa9c9c9ce79f7f9e31d6d2d2e2f57aebeaea482928dc9081ac66a3a0e9c40c0203d0d84b4ac9581a6232790b919f87126486730b3280051a8d65024ba942f2f9a9551d3b43480fd2b313cee2f1b8cba23fcf18f8dd08eedebdfb8b5ffce25c5f33c6c87272e911a6b91cc3e1706e6eaeabcf142dcdcccce4e5e541baaf52e9538282ba268dd764cdd26f0ae99d4d68b8eaaaab94e9a693a5d4dca1a9af24634966d5288dcc2f70dd11d2c1972a70d711120526753c93ae20092947672fc29810424aa1967614c2946721e57bb76ddb4e241cb2b4e82f15e2f1782c168bc5628944821c5dbf0ddea278ac0b9ee648e81f98f8f71f3f723ec6a24e6a68685094ab2c47c2010d173aa294a3ee5ed77f483a8bc849fd45cd4145aa4d1d07cd89c0668d7420e5487797a9e8280293be4c04e9ae07c6409dec2233d0e09e0962adec8e83cd6c2ebde97554417660a591961eb02584300c432944c3701cc7b06d9bb1a42fde300cbd79d5c88cc56274b5df235791cc092cd7881f1f1f07008fc7535858a8ba1935c348ef7bfd69d5576a9edcd7d7c7182b2828282d2dedefefcfc9c9f1f97c524a8a804829cdd91f22e2cc4ce8dcb9738cb1aaaaaae2e262ddc803cd32dbb3674f6b6b2b68d0b46dbbbfbfbfbebebeb3f30c22363636a61e8dea4908e398f28fe880cc6c0a484d33610e073d4092d5084e52ca74fe121a7b6577c73b8e300c3daec649319663db36e736cd91492192a347ad5bd3b88dc7e3e4cdf9cfc0e23f2f170616000c0e0e92772a1e8f8f8d8d959494a8e98cc7e389c7e30040da90ce618ce5e4e4d000628ce5e6e6aabe3f70e0406d6d2d00f4f6f67abddef2f272cef9b163c7a4948b162df2f97ce1701811fd7e3f63a8f0f9da6bafd10ce0c89123ebd7afcfcdcd0d87c3524abaa9e338d168d4e7f3ad5fbf9e31160a8568c4070281898989ddbb77df76db6d75757554e770380c0039393e9f2f170066666668699c060c6481913a225d47cedfb204d64cb5e832e4d38105223d608bf0a42c2dce136aad9a809569d7d3904b2412cab07355e93f81967721e75385d47c131313a669124f103e62b1d8d1a3474b4a4a02810022cecccc20625e5e5e7d7dfda953a7e2f1b8d7eb6d6969397bf62c7db57af56a4879de0381c0d0d0d0f2e5cb9b9a9a00a0adadcdeff77775750180d7ebcdcbcba355c54020b06edd3a0049966c6e6e6e7f7fff962d5bc8c171ead4a9d3a74f03404e4e8ed7eb3d7bf66c5151d1aa55ab9e79e699cf7ef6b3ffe7fffc1f5a036869693977ee5c7f7fff2bafbc525d5d2984c8cfcf7ffef9e7ebebeb0dc3bce69a0f0e0e0e1e3c781011f7eeddfb4ffff44f8a6e219db021c9c112208bc1e76a2ec87074a9b2c8e632cd0496d28c3ab6484cd354361679e439e7a6692a84e91346e22d32fe7ef704961d58ba1aca3c428c327ffe7ccef9db6fbfbd7efd7acef99b6fbed9d0d03039395958584806f5c4c4444e4e4e3018d44d8165cb9645229103070ef8fdfea54b9752732c5ebc5808b164c9929d3b7746a351cbb242a110d95288cc30d8e6cd9bc3e1f0d34f3f5d5d5dbd6eddba93274fae59b3a6a2a222140a1d3972a4b9b979d3a64d645830c68a8a8a6ebef9e6a1a1a1d75e7bedda6baf1d1c1cbcf5d65bdf7aeb0dd262ab57aff9c007ae7efcf19f44a3d1f6f6f6b56bd72e58b0a0a7a7c73066d706a8aaa428534fcc102fec03d3cbae1ed5f9c3c55b19c696a60993c6bbed38c45b42018b6682a4160958fa5f82573c1effed99f3e7972cc07261282f2f6f686888ba2d168b4522914020609aa66ebc43aa3fd6ac59333535f5ce3bef7cf0831f5cb56a552814faf5af7f5d5d5dad4e387af4e8b265cb366dda74e8d021f24ee9bdc539ffc0073e909797b77fff7efa48cec383070f6ed8b0e1e69b6fdeb16347381ca6f901001c3870c0b2acfcfc7c445455523a882c5ce23c00340c8e698be5689aa60284659999062268ee56575521ddfc9f0b583047800d645bed4937b692f84af73b086563d15fd334095e2e6029ab2b168b292f97d4e6e3bf6d9c5dd8c6f2783cf5f5f59d9d9d524aafd7dbd0d02084208b8431b66eddba43870e31c6366cd880886d6d6df1789cd6863b3a3a262626aeb8e20a96f27372cee7cf9fffeaabaf32c6eaeaeaaaababc91a2b2f2f3f74e8d0fefdfbafbbeeba5dbb76c562b12bafbc529965a669363434ecd8b1030056ad5a55545474fdf5d73ffffcf3afbffefa35d75c33353595b2e160c992c59cb3e1e1e19ffce4f1fcfcfcdb6fbf0d11376edcf0f8e38fb5b66e06809c9c1cbfdf6f59564bcba28282825b6fbdf5c9279fdcb3674f6f6f2fa150c750c67464d693a2939966eca7b95855c7c9a44b295996326bfc96c814ddef409248d88ee3e8ee06cbb2e2f1b8699aa669241296699ab1584c995c04b2482442d852d5fb1de847b71f8bda487129610211e92f00505d31e56260a930187a0c2acce57a505fa95ba86f953f42ef5dae39e25d7f792a5022759159a6f98fff78eceebbef028d7af59979ea2fa7c38f3ffef8c0c0c0860d1baeb862936b02ef9ac923ce3a41c0bd1c09906175a98faefe23ee57bc25d23cf2367d2418c994f7c1656c11b014b64827d26430164bc462b168344a7fa3d1682412a1bf04539d32219d4dcf2fff593f96cef6d4cafa41d5d3d9da3d6d3107534e54c5043aaa14924819214ab2d35db8d1094355462f68159bc5d05d77fd49068cd26a4548a6fdd977df7d77ea20e827b89e51014b5549b5925ec88a30ad6fd274a2d0d616530ad11019eef8cc49a20e2f17b00c234eb63cfd55ca111175de52085335ff8deb47433db3aba5f4f2cccc0cc5ab048341cbb2f4c6559022cc8d8c8ca8a01a961ed8ce52ee4d7571652aa5fa72d6710ae9ee53d484a7c734a78813a4e620e5196b8e5981a56e3417b1651d3f2e2465226c2e4144179854e327e7845a59b7e8356c2532798b80459e77d38cc7e371cbb262b198490a320532d3342391482c16537852b7d06bf89bc2d69c8ca5da717a7a7a7a7a9aec989e9e9ef9f3e7c7e3f19c9c1caa1999c64e6a4fe6e1c387376fdeecf3f98410b40ee8f57ae9e139e75eaf37168b01402010d0d1e338895028645956201040e4b158cc711ccbb27c3e9f6ddb9148c4e3f1f8fd7e21049d9697978788b494e1f57afd7e7f22110b87c364c86752a3c28a52df8c71c6380028177626bd41ba32c50cd15b0c2e3a960b353d08d9226d149d28e5a551972184a0a51b42582291201f44cad84a10b02ccbd221a53fa6beaaa82a23b4f01bbd7abf0160651b7612405a9645cf505151415ff5f7f7070201ead4eaeaeae3c78f23a2dfeff7fbfd333333edededf3e6cdebececa4fe686e6e1e1b1b3b7efc7830185417f7fbfdab57af56fa6e7272eac8912388b868d1a28282c237df7c93ba7ce5ca95070e1c0000c6d8ead5ab0f1d3a148fc70dc3686969a9abab7bf1c51701a0b1b171f5ead5cf3df79c94b2a2a2e2ca2baf542a355334bbd000486a76fdfc4c246585545630bd676051417576bad595b6e623842384304d5bc1cbb66dcb9af53e58562c1e8f5b966959a6691a54a0b2f2d487c3611aba90314b9552eaeb0a1abcde35ce0c852aa965250000da22c818fa7cbedadada999999b6b6b6aaaaaab2b2b26030d8d5d5150a852ebffc7200181f1fafa9a9292e2e2e2929292c2c5cb366cdcccccc99336782c1203d30c16be9d2a5bb76eddab061434141c1134f3c41b348eab69e9edea9a9e9e9e9e940208f73c3b2ac0f7ef083d168341e8f4f4e4efec99ffc09b5c21b6fbcd1d4d4e4384e75757522913877eedcc68d1babaaaa10f1ecd9ce75ebd63634345896a520a2f11353ce439db1f4afb292134b77a6e890625956a92f2a90cb45063ab0327b5af747a8802d029969da3a6f5956c2b6139665c6e3718fc78ac52c8294c7635916e9c459cd383333432e2e35452000082132a94a523e86f7062cd51cba41a25421001415151517171f3972840244491fd1099b376f1e1919397af4e8962d5b306546d4d5d56dd8b061606040ad19d35d540f29bb5e0871f2e4c93beeb8a3a3a383e2fb002091489c39738634a6e338bdbdbd8cb19a9a9abbeeba6b7272b2bfbfbfb4b4f40b5ff8c2be7dfb5e78e185bff88bbff8ca57be7ce2c4899ffdec677ffbb77fab2fd0b2d40a5a06bc9236d6ecd3cea1f598b6c8ad70e652857315b2ca5cc062c9c80b3785e8eca58b3e5b246f966ddba66990214f68b22c2b1a8d1a86611896695aa66992a71e00c2e1308d7982296a3e088297fa88a9e5d1f708acb99a263f3f7f70709042af962d5b46dd6018467e7e3e35073933c95fb571e3c6d75f7f7deddab5f5f5f57bf6eca9aeae6e686850e6766d6d2d050c2e58b0800007009cf3ad5bb73efbecb38cb1152b56d4d7d78742a1eddbb72f5ebcb8b1b19131f6e4934fd6d6d66ed9b22510083cf1c4132525251ff9c8472627277ffef39f7bbddebffccbbf04807ffff77f47c4af7ffdebc458a4dd74964aff6bea7ca600e4fa08e916e705f10417825456d171e6d28f2e0e93e93e7ab26e95133565d11ba42528ec9bcc15afd7ebf546bd5eafc7e3314dd3ebf51a86e1f17888b77480a236bd10a9dc24f23d39bd66fd58ae31cdb97210709d03c8e1dbd3d3336fde3cea4597c67139c094a27115321590eb2000a800519d54a832f42da4ac6f7237b0d4ce0ebd3ea95a195a55d32ea8e349672c1d5873a1ea37052c4c9ff0cbf469a38e309769ef622fdb8eebfe2d9adf44a3d16834168944239148381c0e87c3333333333333535353c45b6ad3a27e4d5d0b0380940ec5409f5fb2fbb1309bf9c9d2cd5800f0783cae8d59fab7a4e3d40575e8406a6eafdc9beafa2cc347408b39e4e8d2fd08ba1b42619773c6b941b0516b1abae2cbb0b1189bdbae020d46176429058bf780aaccabe96521dc9bb3656a4d86c69bb290782a6adeb6b9e3085aaa36cdb865252ccb63591ecb8a9a2659f1a6528864ced33e06aeede857ca319d3211914929f4fa9ce7a1d210001ab694c462b1a9a9292a575555a976577f55afa84916a4b679a91a28673d9d494cceb53d612e08d299b4fc0700a74e9da2dd13ca605208534b84d44caaac9fe9fa9b391ef481e142d205592af3cc7725aa89327fce525697faca657b119e74f6d2c29a2dc3306ddb36cd38595796657abd1ed3b4c8fcf2783c86615039140a116f51b8845aa0d4af0c00528294b3b3d7f38b9bb194a883535353939393a5a5a5e42b4f241200402a3c1c0e33c6c8ab445bc1a8aeb66d5324bb629768344a4abda8a88828daebf5e6e6e6c6e3f16834ca392757052216151531c61cc7999e9e360ca3b8b8787a7afae9a79f0e0683656565e170d8b6edbcbc3c6a97f3404a1dd42513582e96826c632c1307734121eb997389de3de73959ffca052cd066153ac2582ac89bd6aa0dc3304d6e9a8665599c2721a5788b9a8574a26118345b64a95dd7ae479612016cc56030376fcd69bceb4f1a0e8727272783c16028143a7af46830182c2e2ea6480782c2bc79f37ef9cb5f363434e804b06cd9b2fcfc7caaf7ce9d3b0b0a0a0cc358be7c795b5b1bb5c8ba75eb3a3a3a3a3a3a82c120a41cee8585855bb66cd9b3670fd1646363632412191e1e7ef5d557376fdefcfaebaf533b6edbb6adb8b858a12733e4cdc5583887631d3424b1740f4256ae3a0f14de2d63659eefea241751e9c731e50cc39416d611464cc6b5edbe8984619a663c1e378ce43cd14ae9459e8ae8a27d759c73da78cc18a32d1b645a21a2c219a652c99de7e9b2ec5cc8ec86e2e2e29a9a1a62a6c2c2c2969696aaaaaa9e9e9ee5cb97af58b1e2cc993388989797b77efdfa79f3e671ce376cd8609ae6f4f4b48eb3d5ab576fddba3591481c3f7e7c7272726868889617d6ac5973dd75d78d8c8c7ce0031fb8f1c61bdbdada18636d6d6d1ffde8473ff4a10f1d3c7870f3e6cdb5b5b51ffff8c7c7c6c60e1c38303e3e7eeedc3972cdeb42b36ba252d56a6ac9cc302c1d7c2e0e73995f982eae1e9d4bde15aa2063b3eb5cd7d78fb33944276962236a0d5af9c84989cf97ebf7fbf3f2f20281407e7e7e41414161612139928a8b8b0b0a0a7c3e5f6e6eaecfe74bcd25bd1e8f87e6927a18346a964386240f1aaea782d9f141de0b94529aa6e9f3e5902aa499a0321e410b3057131cbd7bd4f5fd7e3f1d5fba74696b6beba953a7687ca856a34ad395692b018585509309e170ceaebe7aeb873ffce137df7cd3e7cbd11759796a8b818e9bf4567063c6359c5423b8dbe9bd9ae417948bbcb2eb348545577f2998a2c6617c766722e3dc300c9bf33871bcce55aadd88b7e823adc229f652463d240334923e7a210459f4a9fa256bcbefbefbee9d3b77ce311a92ebbba669e4e6fa1093dd43bb0b6b6b6b0f1e3c383030b079f3667a98d2d252eaddc2c24221447e7e3e6d4625cd4ddba3f3f3f31389c49b6fbe595c5c3c6fde3cc7710a0a0ae8605d5d1d3d406363e392254b7ef6b39f7577777fea539f324db3a6a6fac9279fbcf1c68f0c0f8fbcf0c20b0b172e6c6969219b540dd014336589a54c27a92cd6fa5c3dfddb43d57b964c76d49f622e36a5ae7419a0aa5df4725624606ad1dad562a9b2ee8ac39950e4a69b6f4cfab15c574fb7519000ce987b1a8f19d334963eff5205e5178094e709538b743cddcae69a25ae06966130c5f38661706ed027c698ee4bd3eb80191cc532e6b3f00702a60b8aee59957378edc9ae5761cdb66dd36ec470384cfeada9a9a9e9e9e9a9a9a95028140a85e85be50c8bc7e3e17098d488ba1ad115396ee9be8e60fd8363b37eacb9da57a9290aab8174cb40f51c4bf738b88e732dd0457dc593bb960da50dd3d1cc15c24cd3e41c95914e568461989c73cbb220157bc8b2d9492cdd60820c60cdf5f87f583257f72960d1e313e55073a90d644a21b294f3999a91e223f40e2254a166ce03801069f7521530b2564b974824c6b91d08040060787898621cd4cdd4cfa93b2135b9dbb76f5f5555156937d020a88b6118c3c3c3dddddd8cb1050b16949797a3e605350ce3d8b163ab57af4644cb9a7dfeaf7ce5bf7ffbdbdf56b0a3f83017a4f47b41fafe7ac8c2e47f3ca2fa58ff0829bfb4f24460fafa8752057a984d241251656a6dfaa16a55917ab78010021110414ac952f111d93def7a4f4c4d4d398ee3f7fb11b1a3a3a3a2a20200c85d4bf3442a9ba649bbc1a2d1682291204f04638cf833100830c628fa6c6a6a4a6de2ebe8e8989999696a6adab973e7273ef109fa564a595656168fc77ff2939fd4d6d69696963a8e3336369e9beb2f2b2b8b44228383831e8fa7aaaacaa5705df0856c696d5d2dfec727f4ec3ab674a797de324a81a4cf7266f58c6e20616ac7a86a64f2cedbb69d7ebbe4ff49c6527ca3f310492010e8ebeb1342f4f7f7135dd1e641c6587171514343c3b3cf3edbdcdc8c880d0d0df9f9f96d6d6d9c73cac7d7d7d777ead429bae0d5575fbd73e74ec330727373376fdeecf57aa9ea7575754b972efdf5af7f4d1cf6e69b6fc66231bfdfdfd2d2323232b26bd7ae6baeb9e6a59776716e20626b6bebf8f8f88e1d3b1863ab57afbeeaaaab0c2d894d26b054416ff7df591fff1e45a72e0535fda348ed9663e906314f8532eb1c46ca818c33a5af085298ca752393e137000038d7f62fbdecf7fb29a9dfe0e020adab74767652688365998c617171f1dab56b7b7b7b07070769696fe3c68de4d21d1a1aaaacac5cbc78f14f7ffa53d2f46bd7ae25fda8eaf7d24b2f1d3c78f08a2baef0f97c030303838383894462dfbe7d77dc71475d5ddda73ffd6944fcc10f3abff39defd05cb7bcbcfcde7befedeaea7aecb1c7aeb9e61ad40c3b4dcd6647d57f6571e109344251f330430b34a51ed4a774e480500d4e20538d4c4b408849fc1830778490427d6363e33befbc535050e0f17800c0e7f3ad5dbb564ad1d7d7ab8f0348a91ef279c854e24dda684f972295cab489dbb5d75ebb6ad52a1a19bb76edbae9a69b82c1e0030f3c40eb59e4ca324d331a8d76767646229194399f1c64466a63990b55a08d90ffb2f0d21f5c5f0282f485735d39426a5f024fe55c5142fb1e582a864035b5d4f7e2a6ae96f463299cba9c194489393939939393e5e5e50505058cb18a8a8a43870e8e8c8cae58b182732e84a43519b27b6cdba618e2a6a6a679f3e675777753c285929212c7c07407f10000200049444154712a2b2bbd5e2fa6e62652caa2a2a2a2a2225a6458bb76ed33cf3cf3f6db6fd7d7d7af59b366f3e6cddffffef71b1a1a56ae5cf9e8a38f0a21b66ddb168bc556ac5841cfbf70e142d09282b8947866e3fe5796aceda05b5da859f4a8d95b0a09762a8d20fd8469e9a252d7472171727266dbb68fe0eeddbbefbdf7de4c5f991223fb5a2fd37e925cc85444aa2e95fa385b63f242697e04a642662d4bf7769aa669e96a5eaf926b0ccca5fb2e416a2ec9f475a9fd1a898463db71da99180a4d8742a1e9e9997038140e8729eb6c384c1b15c3b1583c1289ead9b96cdb8ec5c5c9cede1fffe8e12c36d6f91717535d486f526588d9932fea5301962e9cb3142e19e79c60639ab3735dd3b414dad45c57815b7795b1f4384fb804a68b13971ed47a9cfa1420a9349d94964444a46016ea41445214e07222d9e02033386717d862af975dca25abaec9d447ea084bf78c93e87bdfd20bee7834f52bcc70535d02d37b10d4628ef526a5659b940d2e54e42da6fc4abad50400442e8a416c48004821b3bdfd2b2b50f48f1714977ace60ac59b5e89ad3aa8fda97690b4deaca900ee2cc9a5f920b8a0b5b3a23687cc669295008e1f3f9b8e6184f619191479454aa25d0b23c9075c32a64e3a44c846516e602990b55ca5c53b849d958b4c7d29395ab7460b92a039720f55e25b319313531d4466fd2bdae12e8e97fd50974b22de2866571ceb3b81b94e82b9a7a3d30fdf5a4e7879d8257e69c40d78014dc9819c5a1e82a2ba42ee1e93722991dca53a150a9f6968ee3e4f8bcc82432c958daaa06f931a86b623600a024cfbb2e2e24a91bbbca2ee674955d44e532ad5c5acf300cd3b42810cf30b218ecba5ed7ef059780f59b139c557f6939b40cc3204795e3385eaf37454e28936f53231b1f2015df17b3933134b34941f4d00b75b3b97aee3cfd3a9736d4dd198aab14b05c6696ee5960d95ceabfa1f6bc24b392e22df27192218b8c0995a924272787ba82ba84b3e4444a4a50f67bcc06d3f220b25960e937b8c87a4086363c0f9e748b2a6b805e567f9502169b7b4bfb25f94d09e935ea5248b211722e01a410c2b22c4afc9ca43786a954f552d9efde84b42c0fe8c0ca642c57848d8b2db2424a6797ac66bb42921ea1711eae22d1ef089720f5db14d27400b39beb39e700d2341dcb3215b0280247cec6d12497ec62362072649834de5d5da59b72b443abb8b81800c6c74773737303813c1d7ceab78cb14824128944f2f3f3fbfafa9a9b9b8f1e6d5bb76ead6eaa93e2b32ccfd4d4f4d8d81891164562353434189aef5ec1544af9da6baf0d0e0ede74d34da669d2bdc47973e4f7f6f6161717e7e4e4b8a247b4b6bb241710b2b7685d9931e4dc608c53900153af1711699a444a1917066316673ccd78d7579455e461381c1e1818a0d0abfefe7ecac24d7b1a69871aed31a21061afd74bc9b11091d69da91294963d27274719583d3d3d5eafb7b8b8d834cd6030681886949202617d3e1f22d2269f929292f1f1f18e8e8e6ddbb61986313333138bc57c3e9fcfe7a34834c330a6a7a7f3f2f214453ff3cc331d1d1d77de792725f122a1bc5c9665cdcccce4e6e6aae6b8241992d6328cd1eb972563f4ca5c4936bde39800407a33b5195f0ae18dda68581ee4861b58b41f4d7d040044aca8a8e8e9e9f1f97c15151504a3a1a111c33000a0b2b292733e3a3a1a8d460b0b0b8b8b8b2726266a6aaae93d6f24d168b4bfbf9f73ded0d0505353a3b6b30d0d0d251289cb2ebbececd9b300505050f0da6baf353636363535f5f6f652944f7979b9e338131313870e1d5abc78f1e1c38709ca9b366d1a1d1d3d7dfa745353d3891327b66eddaa388952df82c6a652ca89898983070f2e5fbefcc89123adadad14a67149ce23aae9a8cc38e39c01ccfa4b89d2104082044cfee789a1c7eb1342ccbe99dd6551b9ee515252629a26bde69476f8d7d4d478bdde5028949393535252e2f7fbababab53bd9b34fd48a98d8c8c8442a1b1b1b1f1f17142151d5fb264c9860d1b688f35a179debc795bb76e6d6868387cf8f0e8e8e8f8f8f8f8f8f8d2a54b83c1b2abaeba8a12246fdd7a95e3d8d3d3d3b5b5354b972eddb76fef962dad988a34026de64c1fe9785959596b6bebeeddbbb76cd94291f297e4dd894cce1695ad6c59a665591eafe5f1585eaf2727c7ebcbf1fa7c3e5aea9d652c32c7941274d9f294c85a085b19e6f4e203c6d8f4f4f4c4c4447d7d7dca2a023d9c81733e3c3cdcdada3a3a3a4a9bb89593dde7f35166479edab94b498e10b1a8a8e8861b6e88c562f4060a008928394700110e87e816b69d686b3b5c5252dcdbdb535b5baff044595c296f9b65591d1d1db9b9b9e5e5e5148d73faf4e9850b17669a959724aba8f91220622a49ac917cb7439244548271218437870909525f2b54d4e70296c7e3414432a11c07737373bd5e6f4141416f6f6f414141717171341a751ca7b3b3b3b2b23210081417177bbdded2d252afd75b59596918c665975dd6d6d6669a667373b3f22954575717161692c955525242a8226001c0b66ddb76edda6559d6b5d75e2ba5a4c8d579f3e685c3e1175f7cb1a5a5a5acacaca3a363d9b265454545fbf6edabab6b5095dfb3670f63ec9d77de098542f46643cbb28686861a1b1b2b2b2b0f1f3e4c59a37ec73df4072b842c49b37d917aef1f1942866112aa94ba8824129c1b8cf3e4be424ca59e520e4cf57768680867f70f424a6de9f158fa466454cb7c0a4364e3ebb342e57ed77d0aa8852f8af45cab884038a74252bb2353cf93c940cae492e9919300505c5c7cf5d557ff2e3ae58f4784e3d86363a3002052a90553698f9c44c28ec762f178221a8d8c4c26befba35ffced57ff2ccd8f45d0d3fb00002a2a2a08289c73d3e4a9b0e0a44643443ae2f1780c8393de255129e4727272288980d7ebddb76f9f10927605aab54ce55c808c77e6ba4cc8cc27569c2c5391d0904a9c44b95668cea23f54381c7ee699677e1bcdff4721126613432647351d8f46231292ce5241db54a51002ec84ad52a1066b16d88e340cc30dacd9cb6b47c80052b630003096748011d998a68128e93d4724466a03a49eb4830cb29b6eba598b1ab574572aa4984687978eadcc8f591a467b6f8ca26ee5d65346fd2599430424d3762485862a24bb66364fbdca2468db0ea5d77af3cd3723b6e3f70740a6b67fa9812ed3dfa607e99376853dd53d29379a60cc90a99dcd86160c33ab5e558ca8c10d831b866970132570ce90736086403010410ace68c580f2c7314555a8c50fe970919aef0d6717530152af06861411722d93e0259943d0052c489b6873982517e41c543c16005896954818001250ce7ade7524e953427d9e28255254853a8700a6bbcb5df10b86617083f6c49b86e9b5d0b0386326e3a6c98173c61c89532139383a24018305f97e0ffa730d44905200080006022403a979105c6b3b991f75845d243fd113b914b16a10966d738be23f9d4d5dacaf9fe0aa893e2ab2f6a2abfd7f4b5cebaa3ca2db75ac46b55e432a28eb85e689866140021004809c558599d8d2e582f5d3359a5aef330cc3340dc364a6c90d6e71e691e865dc070800091b65df343cf1dc5bcffdf22d07510008277efb75ab6fbd764379519e6971641c24200315a4011a835e647b5de44f745666a9fd272e64b83eb2543a50d77d754ed5b19e79c7cc85a94c2c5ee4f3be37c93a9c2e287af53015a34c3d3e3232e83836ba723748cd783f0fb654639164e2299db44cd3b00cc334381aa6044348c60cce19b3e30eee7cf5f08f7ef2cab296ba4fddb9d5c3e1c489b363839de3a363967482e5450250a2c30111b894108fc7295f0a259238ff93438a51cebfaa789e56cb9cc764823b93ae1863333333f4966b4ca54d8f46a3b9b9b9ae1b4929676666d46439f316945f93ea407b337f1bae5dbabee338b1582cb3927389ae25582aab19636c606020140e4b2993968afe9bb9882af3086aa2b0a53c0bb33616332dc60d8e9c03e38259028d042224e24e643aeed846ff44fcedc39da199d8075ad77ef9eedb6bce9c883dfd54b4eb0c170e93f2a9a79e7cfae9a711f1e5975ffee10f7f78d75d775df0b1a5942323230f3df4d077bffbddac6c9129ededed0f3ef8e0830f3e78f8f061c8b0de7efef39feb5c3e3030b06fdf3e1d52b66d7feb5bdf7af0c1079f7cf2c92f7de94b2323238a6c060606befad5af6665acbbefbefb9ffee99f0e1d3aa4aaad6ed1d7d7f7cd6f7e736c6c8cbefac10f7eb067cf9e0b3ec5bb15f58cd3d3d3fff88fffd8ddddfd6e7fae0380731e0e8785e3d84266598456c63b686012da5bf6a46631e06cd8b18a27263ca9776c58a6e121539d732f479303e3c86c3bee318c0f5fb5bcb36fe4f523677ef4d3973da6599203dfbff30adf23ff1aee3a6d6e5807028687479fffc52ed332376cd8a86ba843870e85c3e1a54b97d2bb99a8ce866144a3d1f2f27200c8cbcbbbe1861bfefaaffffaaffeeaaf8e1f3f3e3131416f2da013bababacacacac6c6c6bababacacbcbabaaaa1e7ae8a17befbd170082c1e0cccccce1c387737272cacaca7c3edff8f8782010181d1dede8e80080c6c6c6aeaeae1ffff8c7a6695e76d965049d871f7ef8b6db6e9352060281175e78414ad9d5d5d5d3d3535353c3391f181878e38d374a4b4b9b9a9ac6c7c78f1f3f1e0804e8c5d5c44667ce9c99376fdef0f030e7bcb8b8584af9faebaf2f5cb8b0b4b4f4dcb973dddddd67cf9e6d6969191e1eeee8e8282a2a5ab870e1debd7b6ddbf6f97c2b56ac88c562f41a07bac5ebafbf0e006bd7aeede9e9c9cbcb9b9999090683fbf7efe79caf5bb7aebdbd9d36fab6b7b73737371f387020168b2d5fbe7cd1a245afbdf6dac73ffef177054addf263a9a02983b3341b0b002863ae4cbd04817e4c077585a28c0c52b28c513234d330684ba08780651896699adcb09019c82dce4c8696c17c28111d99884e979615fcf77bb79deb1ae81d1cd9f95aef1bbb7e6df78f8c0f0e54ce5f6854d60a349e7ef6b99b6ebe29140abdf0c20ba5a5a5a4da9e7aeaa9bebe3e9fcff7fcf3cf575757575757cfccccd8b65d525272faf4697a57856559cdcdcd143973eedcb9dedede1d3b765c7ef9e5bdbdbd9ffef4a7ffe55ffee5aebbee4a2412edededafbcf2ca75d75dd7d4d4f4ad6f7d6bc992255ffce217bff18d6fd4d7d71344f6efdfffc52f7ef1bbdffdeeedb7dffeeaabafae59b3e617bff8c5a64d9b868787cf9e3d7bd965974929b76fdfbe7efd7a5a29223975ead4eeddbbabaaaa5e7ae9a5abaeba8ac0b467cf9eabaeba2a180cb6b7b74f4e4ef6f5f551b30f0d0dfde4273ff9dffffb7fbff0c20b5eaff7965b6e0180c71f7ffca9a79eeae9e979e491476a6b6bfbfbfba594131313ededed6363634343435ffdea57fffccfff3c140a9d3d7bf6e4c993a5a5a59148e4adb7de5ab76e1dad2bbcf1c61bbdbdbde3e3e39ffbdce71e7becb192921221c4d1a3479f7df6d9279f7c1200bef6b5afdd7efbed6363631e8fa7b9b9f9d65b6fbde5965b2e1e580a5e8a5f0855b6e360d6a4200429656909212841b2611894f918b47dfe0070ead4a9a54b972af795cbd7c0180c0c753736d61b864033215818588ca3650b8845f9bf3dfef4c9fef0f51f5892979b5b17c4d3793cd78747c7069b6eff2882134dc45efbf5eb850505f178d4b6ed6ddbb6d1331c3c78f08e3bee58bc78f14d37dd545d5d1d8fc79f7cf249c3306ebdf556d0cc70aadec9932777edda353e3efeca2bafdc77df7d5ffad29776ecd8919797575959f9ed6f7fbbabababbdbd7de5ca955ffef2970160e7ce9dfff22fff72e4c891fbefbf1f00fee7fffc9f5ffad297d6af5f4f03acb5b5f5631ffbd8a73ffde9582cb666cd9a9b6eba09346df2e69b6ffeebbffeebc8c84830181c1e1ef67abdf7dc73cf3ffcc33f0c0f0fb7b4b4fcd99ffdd97ffcc77f747676eed9b3e7d8b16303030394be4c4a595353d3dcdcbc63c78e9d3b77fef8c73fd695e6c4c484e338f7dc734f2814b26dfba9a79eeae8e8e8eeee2e2c2caca8a8f8d33ffdd3c3870fffec673f3b72e4c8f6eddb272727f7eeddbb7bf7ee8282020058b0600100d02079e08107b66fdf3e3131f1d77ffdd7a04d1100a0bdbd9d5216b80cca8b44956ec5d3253d1e4b660596cbc6a2355d7a25d3c4c444797939414d4a49a6250090833b168b1986e1f7fb559016b9288fb4b515151706cbca1832ce2c86a604c63d1ee491eaaad2b74fecffce0f9ef619867412375c7999333d222f5b0e5bae80dc4068726a6a6cf4cffffc5308f2fefbef8fc7e354c3e2e2e2bebe3ece795151d1473ef291bffffbbfbffffefb11f1a1871ebaefbefba8d53a3b3b63b1587171f13befbc73d96597ad5cb9726060404af9dffedb7ffbd6b7bef5f5af7f9d427deebdf7de279e78424a79f2e44929e5d8d8182d80b6b7b77b3c1e993e47ebebeb6b6f6fa70cf5b43cdad0d00000dbb66d7be491476ebdf5d62f7ff9cb5ffbdad710312727c7b6ed13274ed076bcf1f1f1f6f6f65028442fbafaea57bf7af0e0c1dede5e350c6eb9e596fbeebbefeffeeeef543f1516168e8f8f9303f9c489134343437575759d9d9df7de7befabafbeeaeab2b2b232ba3e225656567ef6b39f0580175e7801b4e08ef6f6f670385c51511108044e9e3c89888ee35c75d5554d4d4ddffbdef7e8656c454545ef0a583ac252b8429080984a0a029a9dafce53e4462f0d080402b4b36c7c7c9c3cad94c1766262a2b2b2b2afaf2f914844a351cbb2727272ce9e3d1b8d46a7a6a62627a74687c72dcba8aaae360cefc9a3ed4b972d032698c9189339a6b97ac5e28deb566ede7859ebcae62b1754e081b71a5b5af2d7ae83fc3ce4100c96b55e79655d6d2da5010f06837575759ffce4275f7df5d583070f7ee10b5fa010b1cb2fbfbcb8b8d8b6edd5ab5753fdb76fdffece3bef7cfef39fdfb871e3891327de7aebadfafafa4d9b36959494241289356bd61416160602815dbb7699a6b971e3c69ffffce7a4506ebbedb655ab563df9e4930303036bd7aea53ce41e8fc7b6ed5ffdea57939393b7dc72cbc68d1b8510070e1ca0b11e0804366edcf8e8a38f9e3871a2b5b575c58a15975f7e3963ece5975fdeb469d3ba75eb7a7a7a4e9e3cd9d8d8f8a10f7d68e9d2a53b76ec989a9a6a6d6d6d6c6c5cba74696d6dedd9b36743a1d00d37dca068a0b8b8f8b9e79ebbfefaeb7372725e7cf145afd7bb75ebd6152b563cf7dc73b158acb5b5b5aaaa8ad6e60b0b0b3ff1894f3cfef8e3c78f1f1f1b1b7bf8e1871f7df4d18e8e8ecf7ce6333e9f6fdebc795eafb7b5b5f5f1c71fefe9e9f99bbff99b0f7de843fff66fff76e2c4898d1b378642a1d75f7ffd861b6e58b972e5c30f3ffcc10f7eb0bebefe3d408aca3d3d3d274e75f50c4e6dddb236b9082d356709a627dd52612dd168343f3fbfa8a8a8bbbb9bde059f9f9f5f5b5bdbd5d5bd6ad5cafdfbf79797979ba6595f5f5f5555d5d5d575c51597536e8f3dbf7aedfa1b3e6c9a1c99b163fbcf6fbbf5a38c338912016391f8f0c8c8f0c8d8c4e4e4f4e8d0f2e2e2e9a79ef257d7d67eea53bc381f90a2323842da1c8dea29354f8faba04e40cce22592e99ec9cc73f4565347f6ecd9c339dfb871e35cd777fd5066f83f51858a672c4ffdf297bfacaaaa5ab66c993a6edbf6638f3d76edb5d7d2ab905db7732d558d8e8e7ee52b5ff17abddffce637c965e0aaa4fedbaccd323a3afacc33cf505245784f22a57ce38d3776fcf2e5378ef43ff0779fc992dc5659ee2494bc86f2ca8f8d8d151515599655555565180665e2a254cf8585858b172f668c0148d3e486c11289f8c8c8707e7e2133a51d4f780c0b99b4c1013450220321113d3eabaaa6bca8b8301c8a826c2908e45a576c04e4c00c4004100000080859767de92321f329323faa23fadf4c99eb579b376f3eff99593fba0eea5e53fdcc0f7ff8c3ae8b1b86e172ace8bf62e91b4c8a8b8b1f79e491f33c8e4b1d659e53525272cf3df764bdc20545731400801420c115e0ec3a9510669aa66ddb131313a3a3a395959552cacacacaa1a1a1b1b1b16030c8182b2b2b310c63e1c285dddddde3e3e37575758140a0bebebeaded18220f0683ebd6ad3fb0ff8094827364c89021224826054a00ced0f2fb73cb822565e565566e2e985e304c6000e0d082e8a515e3f7bf28fa5488cf9e6d469116f1b6cfe7a30098e46f0ca3aaaa4aed8ca0b0f7dcdcdc8a8a8adcdc1cce99699a959595f3e6cda7f098d292b2cacd15a6c1a4040426410a262538034363f168824990cc010040968c7f257e22ba920c00defd0b3e2fc9ef48a494a4be207d1d624e60296c01a86d1849c7a98acb63a97436ba287f29d96a8c31864c220043868c4948e65f023e3d351d9909a7de9d2149e7c9b48541018020f112b0decf525151a1dce9aae7e6cc8fa56cac582c46963be520d50d1ac6d8e4e4647e7ebea16d9ce79cbffaeaabd75d778365790867c88171268171a40cc72025306634373581745002484322204a090201019894800c40da800c24bb04acf7ad2830e96973612e1b0b34338b3c0ba6694e4e4e924f8f5e8001008ee39c3b772e1289d0d5676666c2e1b0699a52c2e4e4e4d8d818638c193c9e888f8e8d854221482a3849ffa20404940c05038920404ab005c4250a40904229c70b6c22ba24bf47514443415373aa420540b59243e1a31e8f271a8dcad416d64422110e876b6b6b6ddb1e1f1fcfcbcb3b73e68cdfef9b9818a378e89e9e1ed33443a1d0c2850b0f1c389093e39336d4d5d44804218101a2049060331697381d8a0ff58f226049512090cbbc1e87230260cac613e42ed1661f9718ecfd2e73aa422542884824e2380ee536a69757d36b55962c59e2f7fbe7cf9f9f9b9bdbd9d9b96edd1a9fcf67599eb367bb56ad5ae538cedebd7b5b5a5a4e1c6fafada9038915c13260281184008e5248d13b16fb7f77bcb1fd97afa1344c01cc8e6cbb7ed34d1fd9585992e3350c04063209c5d41e8af305255f92f78f64cfe8a70a94153e3737b7a0a0803c6f535353656565f9f9f9fdfdfd908c464d0048cb326983bc94c98052994a6e595559bda5b575727cc2118e4410888c4b9076cc16cfbf7cf0d19fbcbc6cd1bc3fbd6bab81e2ec89aef1c1bec9a1611e376b6b2a1930092ce5c742f5de625a0bbb24ef67b940e8a0949256940180de9d422ff01d1919c9cbcb334d63e9d225dddd5da15068f9f265274f768c8d8dd7d737cc9b378fa2d21a1b1b19e3ebd7addbfff6db6313e33575b52091494481b62da289442896b0051f1e89bff1f699f1e9e81557acfa8b3ffd687e8e39d83b383315932801e54f7ffab3eddb774809afbcf2eaa38f3e7acf3df71067fd67a86bae9f4a09cf3fbf93cc41fda0ebfcac3fcf3ced8f5dc85c26713ff9f9542191566a232140aa2f83c1602010c8cdf5218261f0c58b17f9fd7ebfdf5f59594df94f5b5a5a1863a6693635352142694959696b29720920102407008484904cda1fdab2bcfbdcf89bfb4ffd7fdb5f791ca1d8c73f755bebd5eb5b6c470c0f8fe4063c4383832fed7a8996f37432ddb76f5f381c5eb162452814f27abd8e634b09a66986c3e1aaaa2a29211209efdbb7cfb2ac0d1b361c3972646c6caca5a5a5b4b4f4d4a9537d7d7d0d0d0dd3d3d38b172f8ac5e2ddddddd168746c6c0c00afb8e2f2402080c8ce9e3ddbdddd5d5b5b5b5f5f0f80005208387efcf8c8c8705353536eaeff9d770ee6e6e6ae5ab5fa9d770e4e4d4d2d5ebcf8e8d1a38b162d2a2d2d515b20ff58fd6f34ae51fd0b905c7c0390785e3f1664c42babf02ce5c47279b054c00cd712d132c610b9448e684b900828d1b1413044db8ecb44bcb220ffef3e7fe3d973fd5dc3c3cfbfdef3e24b07fe63c7af9beaab867a7a0af3f238f2679e7deec61b3f12894476ed7aa1acac0c4000889ffdeca7434343b9b9fe5dbb5eacadada9acaca278acd2d292d3a7cf7ce6337f09000f3ef8606d6d4d4e4e4e341a79fbedb78b8b8b9e7df6998f7decf6175e78b1b2b2a2a8a8f01bdff8c6f6eddbc7c747ffd7ff7ab0b7b78fa2a0f6ef7ffbe4c913f3e6358c8c0c9f3e7deae597777fe2139f983f7f9e9472efdebd7bf6ec292b2bada8087efffbdf6d6a6a0a87c367cf9ef9c10f1ef9f8c7ef78e699a7972e5df2ecb3cffec33ffc5f9c73486e7411296c5173672dff419c40e5d41227b0d451965c6ea3a006092cc55c1730def5b56bd7711d523c3d4f9a5a11a39013061280a3e40860086e024a01521a3311e3873f7aeeecb9f0b5d72cc8c9f395151a868857052bc6468763b168695949241a7d6dcfaf0bf20b62f1b8e3d837df7c33ed063b78f0d09d77ded9d2d272cb2db7d4d6d6d9b6f3d453db53f15848a12e4288b3673be7cd9bd7d171ea95575eadaeae0680fefec1c2c2a2bbefbe474a89c8a40429514a340cf3aebbee06809b6fbe39180c0e0e0e3dfbec73030303870e1dbaf6da0fcd9b371f919d3ddb595353fbb18f7d0c008e1e3d7efffd0f1c3b76ecb1c71ef3f97c77dffdc96ddbb63df8e0431ffbd8c71c4772ce523da19a4e6fc3ace53f9413644a03a2049e429c64b49f0a0053ef84ce1e8fa5f0948446ba0f09b3654156a1c90a5b2960210310296053da1b44302d049ea8ad2f6deb38f4af3ffa85e1f5d82271f5fa866b2e5f32d07decb2a52d798585539313d353d37ff5d9cf01c2dffffddfc7e3092911800583e5dddde71c47949494dc78e3b6af7ffdeb0f3cf000227ef39bfff8c003ff0300a5843befbcb3b3b3f3873ffcd1cd37df7cc71d1f5fbe7cf9f3cf3f9f9beb8f46636d6d4783c1b260b0bcadedd8e8e808210c1153290f717070d0e3f17efef39f7fe4911f22e2534f6dafaaaa2c2828e8e9e96d6b3b5a5959595c5c72f4e8d1dededeb2b2e0b163c7359812d3d3ecf58f729913013840b213096812a4ca642452bbc766e3b1745101a2a825f53629155f6ab3bcd7ebcdc9f17a3c1e5a49f4782ccbf2a8f7bd1ada2b5f111198838828b1adede8e2a54b2552fa53c763e1aa150b37adbbecf20d2bd65e36bfaa08477bdb9b1aaa962d5beecbf5338615e5e59b5b375757571517152f6a59585e5eded0d870d79ffcc9ebaffffa68dbd1cf7dee73e5e54100d8b86163515111805cb56a259937cf3efb6c5767d7bdf77e69ddfab5a74f9f3eb0ffc075d75db766cdaa5028f4c61bafe70502b7defad1a79e7a6aa0bfffca2bb72c5eb2b879c10244c8cdf5ad58be7cd3c68d1e8f67cf9e3df9f9f99b366da204716b56af1e1818787bdfde9292e2ebaefbf0d33b9e7684f3e9bff80b5f8eafb9b9d9e7f32d6c5ee0cbf12d58d0c418a64c2ca9992090bdfc0771029553f6131d475a6e43c140d0603a77aef7c4a9aeeec1a9adad6b92f1586e58a6184b693a0adf0ba4242f2f2f2f2f505090eff7fbc913e1f7fb737272294d034150119864201118302ef1899f3cfed13b6e73242072d3d1d229000020004944415414221e8b0c0d0f0d8e8c4c4ecff4f50d14e5172c6a6e2a2f2fcff1e548e0f424980cc7785fb6f87f911360165894c48ff6dc8394c024f1b494f2adb7f63efdcb5ffdea9d73fff7373e733e1b4ba9339dc0d4117dd5597d7459f7880888a95929720026012570644202209a5e5f79756da0b8241a892e59b4c4e7f35b1eaf69a0001032692ba6228f4026a3b220f978a9827ef0d209bf8d13a84c050180808c9c8bb480228121204894c89260bc08cf3ba48c2a1d5b991343caf4ad5035fb5b09966492094001c01c860ef0036d67a7224ed2880700402e81239372d2014959be84b2f604a4329ebc0fa74bff454ea0b294e45700c950825421acc0a4b372719d9835ede77875afc2906b8b331dd70fb20c416d6f741261487c0380e0208b21bc76b87378d2140e9aa6e3f77b2c14d158424800e0339184835cd0fd056788129de48fdf9d5c7c83ba7e75f1f7ca7a85b9cebc98cb62ea4c75b278f70ffe5b15044040074082e4122522a0742c88d43754da28043ae4ca72ef2b04009d995c204b2f2b84198c71c6d21268abc86e640840d93d90a6a40c001977c00878f9ca15f387c6675e79edede18969c9a48946635515e3122dd3e10cd00409000251203229194864520a260502022954701803290c52ba8c4263190a81201de4e4be6712053204218540e002009904104c32092810243a28912148e17069388092018264824b90923928414ac611413a120508608c3b92920a0bb54a2e9009449436938c014729040a4826cf0185120aec905232e0424a0406924904c61c47c419b35072900ea00d696e8bdfbf486014a222194a892825931229e51fa0b25ce65cd27141aabfbfbfabababafaf4fa5e16b6b3bdadedece184364fbf71ff8d5af7e451b788e1c39c239a7b5200010427cfffbdfff7f1efed778dc0600100e023040af215ad72e181e3cf7adeffce06c67ef156be66d5959579213c368ef8a0565109f0461834824ed7ee08e7000138cc519cea08c0330292582942805d892092925a014200448943647412e5994292b4f4a2105a3cba12905a5491212002432c1b810281c00c620ce20215148708009211d09201090315b0ac18444901c1392494489829cd052300493096042a0044426010069c432291093662f0d778152700652da063206923107514848300608524a313b0b4b4af2317ebfff4974547d18243da21239033092c0c22cc0d2cd23fa28a5eceeeececbcb2b2929b12cabbbbb9b31168944f6eeddbb7ffffe582cc639dfb163c78e1d3b2626267a7a7a5e78e1053dd4ff7bdffbdeea35ab57ae5af9375ffb2a4a0064024080a808e615e59bfd034333e1786961deeac575375ebde2eb5fbcfdcfeeb87a418daf20c796099b03e3c22ece85921cd3401e2cf336d77baedc58cbc10640a43c475270400426106c9482012020c6376daa924c220303eca23c1341308816e619e412052118200710208474508221c02b13ad1bea39b2b262637173314a01202524184f3a6a04381466e10814604ac61d1092de7e251100418029b0d4679ac8a4a0d04510422272004348261000510283a4df4b204a296d860220c621caa460c0a4701873001c98ed2a17c8deef32e7660a4871d5f8f8b8d7eb2d2c2c2c2929a9a9a9a105e6bd7bf75e73cd35353535c78e1d23f577fdf5d753ea0efab98a6ef8dce73eb77ad5aa53ed27376dd8c8504a602001c1f158322fcfb361c5fc05c1e203078e7eea8bdffde4bd3fbcffdbdba742f16041cea2ea62331163124c887e7873cd073795594ed4675a053e2ccbcbe1c2e16073e670699be070611bc2611218482e6c04c964b424cfe4e030276ac0d4559bca11a31e086fdd5883e870b419861043a6741808c61ccee2880994a1d27c0344d46bca7c3f3764c2820417920b30a53045c210094b240c11371832615b3261a0638063c9b825639c45184638844af31dc30000018ec3c006663bcc16dc06e6481012194a06e8204ae9380c2463518030930e9336979209692093d2d13a4400084c5bf47dbf4bf65921a68bcb4e97520e0e0e1e3f7e3c1c0e4f4c4c5e7bed871171e3c68ddff9ce77eaebeb11717474f41bdff8462010f8e77ffe6721e577bff7dda58b966ed97285045ba2231138909a4cac5e52f3837ffefc6b7b0fb79feaded736f8ca1b27fa7a06eefbc29d931353066331e62c6c0e1e3ddece396b5e5036134980700c296a8bd88225a5cce43d7dd308100d870c0b6d96170dc74af2e481e3330c8c7c9f75dd96da98e3741cebf4a1bcb1b5e148db998aa29c1bb6d4769ce85dbf6ed1d8f8f4e464ecc0f1d186faa2f0f4cc999ed8d557af7871d73b0c732f5b5eb7f3c5c38b1aca1beb0a2231d976a47ff9a212afcf1c1c8d9e3a3dbc7c51d0f07bcf9c196a5950f5dc8bed8539ceda95f372f3bce1581ca43c7dac77416351efe8d0fcf979f3ab7dd3d3917d6d63a1044a6117f9e5f245415faef778fb407ec05753951f8f8963c706375fde120a4d0d0e450a4a0b86c742078e0c08f06032a496316120a440f63eb2b52e20692f42517ca39bea454545a150281c0e47a3d1d1d1d1eeeeee50282484686c6cd8b0613d25fd4144d334efbefbee471e7904114b4a4a1e7ef8e1871e7a0800fec7fdf737d6372c58b06074641c00011c09200167a6e36393b1279e7be3b9570fafdbb0e04f3f79edb69b3703e78cc9a19181b33ddd710064b17c1f7a0de6b1588e250dee08860e42d382f2c3c73a77be72a2a1b1c4346cceedea8aa2ba324faee1980c106d04190ac577bd74e2e0be93cb16d73952fee2e58ec1e1c8c858e897af1c8f0bd1d135f2cb578e0b74f20a723b7b4383638e444083d9c261023843e188a52de5c37d23870f9e6da8cdaf28cd45908b9a839525fec84cf8a557da7bba863d06d20aa8c52507b9ebe5a3bb5f3eb2f2b27a64685809c3140cc4c2c6b2c2029f7018075e5d11181e9979f9e5f6fedef1f9f34a5edc7de4d8b1bee605f90927fed2cb076b6b8a76efeea8aa2820ff8a1414512200a4445ba2936172bdafe5c2ef84b62caba9a9e9dcb9738cb1c2c2c2f5ebd71b86b169d3a6e5cb971716165290d6d6ad5b29bbcbd6ad5bd7ac594330a5fdd34d4d4d7bf7eedbb777ffbcc6fabb3e79a7f2b9f50d4e9d3937da3f36f3c48e1d0f3fec14160546a667ea8225b75f7f79e7d99351614866e679a0b9b1f25ca757326c6c287aedcd76e4a64009f0ffb7f7ede15155d7a36bed7326f3ca242104f2180824e1150482bc0d6f44fa7105ca43a5b456fc4a8202f5b67e5fadd8a2adf5d3aff581a5404521d7801705a480a95cf50718a40a28af8072110821ef403299bc27999973f6ba7fec73ce9ccc24407f6dbddab2982f9cc7defbecb3f73a6bafbd9e5c2600ae30e09eebde0169c995353ea606937a455f2ef77292190455c420b3000408a520481c994240488841ce5540055980402522bbcda20455d6ee27e0804c26050839caefbd5fd42fd9f93fee1d79e142c5e9a28ba5150dfdd3fb1200b2280ba92838741e409d0352211ab80f000021a9b7c369a783878f678f1e4ac4dd4976b5dd0708049c1347440221a153051fc78971000249282d193040899340264d42a98b1ebf1bd06d4e6843107ae1c205c31e4655d50f3ffc50686cbefaeaaba8288bc562397ffe822449c78e1d13cbe5e5cb97df7efb6d6353a9f39dacaabaf2c8d1c35923ef94008013675127ce150f48edfd9b5facf436f890a9401d766b5479c9a55aaf0fac891616852a3f5fec3d59544bc47d0ab4fb9137f36b56ffb9d39563c60ccab45b4e9dbe565b4bfdd2ac178a1b18b4f748ec51e9092a602554aaeb7d0186ed60ad69502f7e5171cff4c1e7cf579d395b3d6b6ad695e2ca81e9c9b1713135558d5e8fcfed8ef3234f488b292bf72aaa347182fbd3cf2b55b08dbfab9fcb2e1dfaaca4c1db72e71dee2903075d2eb95e55e5bd63887bfa8c91978b6b3f3d5979f7dd2324e0b59e564b3b28646548d7eb3b3a02eab5ea769bd5316dfa645b942550521517c7da39bf52d238fc8ea4a93312bfbe78fdf3d355d36664b5fb82274f578e1a6955d176bdc1af22abf5b613325de980a8e5aa6100d4495bf7ad874eba426337279902f3092da108b1e272b962636385a5b2cbe58c898971b95c3131710e87c3e9748ad8eea22ee86e1b20364b9c010230be73c75fbebff8813776fdadac51e6416ef1b7f6b0c1a041c9310ea9f8d2c58a6a4f077372d623cad61365e4a81232028b36a614640c88889304c80855e0321222538090319543901310da1038e3c49814042e01930838282884469cfa244725a6c49d2caa619c11c82421417b66460c27eb952bd7664c4e3b76d2d3e25310397140b400e7c848416488c45504402671ce8008192754191071a6822c2149c48144386a154105e02a49c0800171625a945e9009383215891397004828bf8018810a0840320092a10c13bc1572cd7df7ff2b7004460840848424211100c9e85ff54056f5e52f0b3e3c7ca4a8f285a757de5ca52390a3a4a4c462b1c4c7c78f1e3d5a446c3f71e2547272a2881d75f4e851229a376f5e5d5d5d4d4dcdd8b1630d1c25a23fbff66740f6939c1c9bc5cab5bcc3845c952c32c7182fe77ffbb2c20e4109a5a03d8545d964e650515298c248884083888c83ca00402194101927e012070e2ac89c8003975402420ba205891831069c7305191057901821a90c114002acbae6afaabd46c448b21257382984f2a5cbad1c5a012d87ff5619240460848ccb5c520911388870a6b2ccacc003400a0340267312ab1a00a816a6aa80010446c84005520911d12a71524851183221d14540548908540094900171890123509029401202720832143828c444322111a8ecdbb12b6484421dc7743b5204356c9d0e8f9a0c9d6d66105155d5e2e2e2be7dfb0a678ae2e2e2b163c7b6b6b61e3f7ebc77efde23478e8a8b637bf7ee45c4499326d5d4d41c3a7468ecd8b146831b376e9c38f12e007ceac9d5afbefa2a310900927a58250c7021e26116801e327120e20c099013202a5c130d09e1070fe93c8134e52181b80ec22b517cdd141466429a151900222011681a7995116a0b0d0251401403000618f2320310c274224250751d3e0128080a8016e8105021129a0512da1d8e4655450c2ba00ac401c54aa6a2781b63ab445cc714ae795a86dcbe55938e4ed50ff83f1b49fe7e4021b42342105f2bf1a005558b042a20d77bdf058f6566b0841ccbe170242626daedf6989898d8d858443c76ecd8dcb973ebeaeace9d3b979c9c8c88f3e6cddbb3674f7676b6b92900f8e94f7f8a886f6d7b6bcae4c908403c2801ccffde782200049500f0661e1db7e15b06a4ff157a69094188e04b4865ba64243cfb5718185a6700d0fce51139e742fededcdc5c5f5f3f7bf66c00983c79f22bafbcd2af5f3f22f2783c6bd6ac713a9d7ffce31f0160dd9fd68fcc1a3165ca1400ce202891ca8833c63efdf453afb7e1dfd3d0f2df160ca462042884e83367ccb0daed00c48898ae88ea44b1bac4ad9e3d7b5655558930846d6d6d353535696969443464c810a7d3b96ddb3683bcfde4273ff9d5af7e25a2e66ddebc59b4f6dbdffe76ccb8b16919e91e8f2721215e6212220021114dca9e04c20c430b30f3cd5b83dc2e708b05a00bb51221001a26eb844828712609a9c8cd25ef369b6dd8b061c5c5c582799f366d9a2449d3a74f1f3d7ab4cbe51281ed67cf9e2d9cbd66ce9c3966cc1866ca8e3464c89053274e9c3a71223d3dfda1879672600012e869e208808594f766b4c68883db05be55058c33122c0d01aa2862bc0018886596bc8709488b8a8a0cd1434747c7eeddbb45728093274f0a0bf73367ce489274f8f061215ff8faebafb76fdf6e3445244431505959f9c92747c68e1bc785c42fa4fa42c3994807d2bf0f24e2064113b748b768242de399c1101bbe0c641c849aed2a8553672063abd04d81db604c8b382141b584050d10325099bebdb8915fa180d1a3478bbcbd4ea733363656975d697f9d4ea7d3a999ba8bdc71268f42d47544463f60d7ae5d4c3f266da78ac23d2d4470090980218aed5f881c8bfd88f08d44cdaf0699e97551339c15ad09ac230c35ad996aa3d6a099d083d103869c13631856e05bbb4a7dd30ba1f1958b2911234a44008c64469a6f731766336630026a996f8559b547960ffbe2755f080010ba2f0462400c892169e63bfac26818c3916e4e05efef7fff4f1b365cba741140f81869b29d53a74e5dbb5e4344fbdfdf4f009cb4a6852d0001e79a10426b568c2032e05cd8d36b17c5737534178650c029bc4097c7ff210574e2409d7ea8cf2e2220d32c3175abf79bb8d8333d6f582432859ddea01da339b1cc9040351d83402340061069d9eb40519477de79273ada3565f2c47dfbf6cd9b37d7e9747a3c1e22183a34f3d0a143bd7af59a3163bacd16c510ae969679bdded4d4be0e87e3e2c58b44949898e476bb3d9ebaf2f2f21e3de2d3d2d2040269125a0c7d840000484fad7eaab6b6169175ba7e1bba841041070040948878e9d592d401c3c06c9a6cb044069618b812d2cc74f69530d0ce2869c6b0cea8c60dc648ec520db2440002e1c37b4d04800d0d8d478e7cba79f31b4494953572e1c2452929296e774a6c6cdc81030725493a7ffe7cfffe691b37be161f9ff0d1471fc5c6c6ecdbf7dee4c993376efcf3ac5933ebebbdf3e6cddbbd7b777272d2800103d3d2d245afc44a173956a5a5e5f9f9ffcb6a1579c86f735add00e9ff61680a853a73edab6b4f7d794978b486142f00201611d01690505206137dd2161ac6c4baaa02081b48d5f86b9431fd746a07228a9ff143ec5a8865d05bed3d0c460b11962e5dba72e58acf3f3f4ec4172c58307dfa34225e5c7cb97fff7e2b56aca8aff7f87c6d13268c5bb16285cd66bd76ada6a2a29c73ee743a44533acb1ff1488d981a4fef1446d09c75d6b868f60e378ecd058c53a380f1b7cbebe6a6c2ca845dbcc115d155e356d869976f14f9d0c83e84fa86401a7ba10d979856413690182342baa1cd7b57079d089b2060000c51fb81196d42bf6ea1bb7ba2fdd8d8d83163c61c3870a0b4b474ddba75bffef5af01a0b2b2b2acac2c2e2e4e24c5a8abab0300a7d3e9f3f9cacbcbc5ee81f4b8d0d1d1d1cf3efb6c4a4aca8e1d3b0c16b03b30eefafd7e61e07f83c2e65acdcdcd656565a5a5a5adadad61b71051f4d078bacfe70b2b16080444758fc7632e69ee5597e4d39875f1089fcff7fbdfffde68c158581a1b1bcbcacacacaca2a2a2a8c8ae6d566dbb66d57ae5c11415f84ed9d2873f6ecd9bd7bf78ae39a9a9ad75e7bcde89b887a4ca61db4b81ef0fb8973b8811c0b4c4b1be9d40bb193bb8e69ebd71d3e75de78dd1aa01e2dc262b12c5fbe7cc78e1dc78e1d5bb060c1f0e1c3df7cf3cdddbb77bb5cae175f7c312121213f3fff8b2fbe58b264c9bdf7debb77efdead5bb73ef8e083292929f1f1f14424f2a06cdbb64d96e50d1b3698336252573205e3ad3d1ecfb66ddb0e1e3cf8c9279f60e7549ac680182db4b4b4ac5dbb560cc5a2458b323333c914ee9c880a0b0b1f78e001e329858585353535cb962d33aebcf9e69bd7af5f07801123467cfffbdf370f823810b3d8256e0983de471f7df42f7ff98ba228c2523cecfb59bf7e7d4d4d4d7272b2d56afde52f7f69bc82f12225252522cd16111517175bad56f1168d8d8d151515e24d3b3a3a44ba2163eac184f4a41ba3b7b4b4b4b55900f84d0cfd22af44ecf8b0cb2a9d81ba39eea6b4a9bb002002bc0000e73c333373f1e2c5090909e2cac30f3f6cbcd2fcf9f38df4606eb79b8884e2f2e9a79f16850d337c4378dbe57301c0ed763ff3cc3367ce9c0180e79f7ffeead5abd3a64d8b8e8e962469ce9c39ab57af7ee289270a0b0b3ffcf0c32143862c5ab4a8bdbd7dc68c1949494943870eddb66ddb279f7c3260c000ce794c4c8cdbed3e70e0404747c7debd7b7bf6ec999d9dddbb77efad5bb77a3c9e279f7c1200d6af5f3f7cf8f0471e79443c7dc58a151b366c906579d9b265fdfbf78f8f8f4f4949d9bd7bf75d77dd3575ead4a3478f7ef1c5172929298f3cf2c892254b060d1a141717f7e8a38fd6d7d7e7e6e62e5fbe1c11972f5fbe69d32644ccc9c9d9b2658b78afe1c387676464c8b25c5d5dfdfaebaf5755558d1b372e3333b3a0a020313111117ff7bbdff5ecd973e6cc998cb1989898e3c78f7ff6d967d5d5d5b366cdfaeb5fff5a5050d0dadaea76bb3ffbecb3fcfc7c227aecb1c7f2f3f31b1b1b25495ab264c9dd77df2d26a2de5b1fc03825a8dcd25268305bdd95819be35668fa6e05b7d024cf342e32c656ad5ad5b3674f30510eb34750181d32568ab06fb4cbae76b9f30804022258e6b3cf3e3b6ad4a8c3870f9f3871a2478f1e76bb3d180c22e2ce9d3bebeaea7273739b9b9b0f1e3c78ecd8b1bd7bf7e6e5e5ad5ebdbaa9a9c9e5722d5cb8b0bebebeadad6dd5aa557979791f7df491aaaa4b972e5dbd7ab5e8704b4b8bcbe53268527d7dbde8b6d7eb152dcc9f3fdfe3f1646767f7efdfffe5975f26a253a74e151616262424e4e5e53dfcf0c36fbdf5567c7cfc962d5b060f1e0c000f3ffcf02bafbcb269d3a6c58b171bafd3d2d2d2dcdcdcd4d474f0e0c13befbc332f2feff8f1e3f5f5f51e8f67c58a1500f09bdffce68d37ded8b16387b0412f2828d8bc79b3206ff9f9f95bb66c118bec73cf3d2706f0c5175f6c686858b76e5d5e5edec68d1bc58338e7aa1224ae12a97218fb8688aaaa023023d89a6a0245514414d0402020a2dceaee152a916a0499d179af4ef45c900a3182b708066e1984d7c01e23837c6461f3296adb401e56d28c88dddd0580575f7d75d6ac59e3c78f5fb060416a6aea8811230e1d3a3475ead473e7ce5555556dd9b2e585175e0080f4f4f48c8c8c77de79472c1c4653d9d9d991dc92992346c43163c69c387142242d3317161d98387122223a1c8e51a346b5b4b44c9830212f2fefead5abededed7bf6ec3173d6c607939d9dbd7ffffea6a6a6a54b9782cea4cf9a356be4c89188b875eb56f383468e1c69e48136862b72548d6e3b1c0e4105f7efdfffeebbef86f5161109486cf265225214c598789d0084124f04834149920281802ccb1d1db291250011459a42550d0682d640d06a58304b922e92d02c8c346e9a73ae07a3ba113e85112a339f073acf61701291236b1e2633fe61679636acbaf9298f3ffe787373f3934f3ed9bf7ffff5ebd76fdebcd9eff703c0d2a54b9f78e289bbeebacbe7f39d397366d9b265b5b5b553a64cc9c9c941c4214386e4e6e6daedf665cb960d1c38b04f9f3e369b0d11070e1c48446bd7aeddb163c7e2c58befbefbeebcbcbc975e7a49a4debce79e7bce9e3d2b58ae091326bcf4d24b2b57aee49c272626f6eddbd762b170ce33323288c8e974ce9933272727272d2d6de5ca951919190060b7dbdd6ef7fcf9f37373731f7df4d1b4b43422cac8c8484848b0dbeda033060e8743bcdddcb973376ddaf4fefbef7fef7bdf73bbdd1d1d1d00909292f2d24b2fd9edf6152b56040281e8e8e8871e7a282727a7adad6dfefcf98f3ffe786e6e6e3018cccacacacdcdcdcdcd0580356bd69c3c7952f8248bee69bc1732cdece1c081033ffbd9cff429214962b22c33a6852eb25aadc22ed9e572391c8e9818116d345a3f8db1dbed0e873dca1a658db24ab2f64f629ae84b93807234a48e1f7f5cf8e0830fde08ad742c89c4b0afbffe5a4c64e4adeeb03392b61984cd8c64e2fa0f7ff8c337df7c53e49e8c44f1307208a694a4e6a536f214005e7bed35a1a1efb293c681c12f9a49b5b9d9b0ac74d0f97b30ae2f5ab468cf9e3d069930f394660ad45d676ed049a3b5b06e8b115ebb76edffdeb1479113fef4f2d3b211149931266c23655996248bc562b15aad22cc9add6e77381c029f84ad9fcbe58a8e8e8e8d8d75381c22f09acd6613190e4596b9ce443544246459ee8ecb31c03cf744b468d1229bcdb67dfbf68a8a8ae2e2628158911c98310d0f3cf0c0ae5dbbc495bababa7efdfaeddbb76fd6ac594b972eddb46993f88e01a0b5b575fdfaf525252500f0f39fff7cd8b061e646ba1ce848c62eaccf605aefcc2d2c5fbe3cac4a1842845156f3e899572233d1555555f84189f2e6aeeedcb9d33cc89103158634dd610ce8d86c7e44e407663e365e53362a43673c30b3026123686a57e8909888e409a0fd153f6380ba9c9e1b83c1f77cf0c107b367cf0e068385858588b87dfbf653a74e4d9b366de1c285efbdf7dea14387eebcf3ce1ffff8c7ebd6ad7be699674e9c38515d5d7df9f2e59c9c9ce79e7b2e2929898866ce9c595050306bd62c45513a3a3af2f3f34f9d3a357dfaf43163c6b4b5b5ad59b3c6e572c5c7c7efdfbfbfb4b474d5aa555eafd7eff7272626d6d6d61a71e75a5b5b0525131fe14de96518449234f32475771a5638b21d7381ee1e018000061fd249e6645c345717b81c2aa6cb8bccb366467173ddd2d252b4448be05932088b70ad84a0346128c9056f0e2064b5c0398858a0ba5037d4d7ee68a971702b58651e9a9a9a1ab7dbedf3f9ae5dbb969898f8a31ffd68c58a156bd6ac3970e0405151515e5edee6cd9b0b0b0bcf9f3f0f005eaf5784da160ca680949494499326eddab58b888e1c3982885bb66c79eaa9a7468f1e3d67ce9cb7df7e5b55d5f9f3e76fdfbefde8d1a300b072e5cacccccc1ffce007f7df7fbfdbed4e4f4f4f4f4fdfb06183f0971c376e5cd80af52d03b13732cb11d174fde6a0055104d4229d2021101247ed66b7d34744252525e72e5c2df31031490edbff7749a2ccc7669ceb92a4fde360105eafd7bb6eddbaacac2c222a2a2a7afef9e76fb08c0ad7d9c8ce23e27df7ddf78b5ffca2a6a6266c95c9cecececece7efdf5d7c5826854b9fffefb4502ec3e7dfa6465658d1831e29d77de193c7830636ce2c489fff4f7fd57823120b73e4dc27e0449e8fb88cc32eeee5c1bc57c454747d735051a822d9224756bdd60a240da1ac73988dd2211e75cd123a5706e265cdd10adbf170c323b63c60c6138bf7cf9728bc5f2eebbef9e3e7d7ad0a04163c78ebd7cf9f2b265cb525353efbdf7de8a8a8ae5cb97d7d6d6ce9f3fffbefbee134b617272b22449369b4d96e5a953a76eddba352b2baba8a828272767f0e0c19224e5e4e410516a6aeadcb9732b2b2b737373870f1fee7038186356ab55688df2f3f3131212eebffffe9933676edebcb9a0a0e0b1c71efbbb48ef770d349a2748166a740b40c728ec1e47af5fbf1e171787e56d0018725845dd5a4144c0926559d8ee399d4eb12b14dc7a4c8ccbe58a8e11d16d5d2e87c3e174ba6c369b286c481c5087b067efdcb9d310dc75075d720cd059914226e19651318c238ee437bbdc43dd8061fac31ffe306ddab4f1e3c78775a94bc1fdbf07700825010881d8dd035084059f79e88e1f3f5ef0e1279f9dad7ce1e91b06b715d50c7523e9292a48c250ca8f000008be494441545743eab7341be3aea6873a53e35bfaca0db44093f4b24b8631b2b7dde156770f8208d434364744b46cd932210132b389b7f20adf1ab8d531374a0368c948c9545fa05a97af1e39202a11279055550d0402c69430c6844454446a10023a4551144511c9bd3a3ada7dbeb6b6b636e1566f881bac56ab39eb8999950113b10906835d4e7f77dd356b6c8c5373f91bd48ddcb4475e8f6cc1780422f6ead5ab8bb1fc8e009120319c08c3446ee6329dbf406421ba242a000724242462da72d829e1adc13285c60d1800ca8c016320f68388da12662401b0e820a45942a025a2ba0bb196c02dabd56ab7db2c51b22c5b645912d99fc38ce9c4bbf9fdbe73e78a0c42720366fc36fcb7802102e791fb18d4250944d449eed069874b88c480110795a130d766044c84eb24ae6aa1f3cced221a12b5eaea4a00ce810048067dca89884815316ac9945a5c80205a611a430d143f93400a32d29647993126b43ac67700a009c1274c18af280a11288ae26df05ebd5adae06de45cf9970ff87f061031c6508f5f6a88a698111a1451e5c4413f2122a6fb1000a0b659232e33225209197186202348042a31508187716044c424465c3311b6d99d92247340b97321ae13c14e60ce626fb059c681518a74e34ce36bd1c9928aa849cb12937aeb2c1a45bba22d164b6b4b1bef1416f136fc03a0e792100c8cdd6e5755113347d2c493a86a01304c127c2350231059488d0e2ace802a01b55898cf6209a00c2421439fe28fb25b41e914ff238c8bbdde10888eaed7c40d06031429c90c235d82629911ce8c5ea0c9e23991c602eb8c1172ae619ba11f4004972bda6e4f53d5ef5268cd6f37106941a611885a5b9a7b2526b6b707546e292dad68686eb6da6d8949f13d62ec320a0e0a1131100830c66c361b0582f6805f2eb95a76e94a7d756330a040ac2335a36fd2a09460efde41496a686f89eb151fec08188f03b1188504ece8aa69721e2f0f976319a867265410815e5de153e8962431339aeab44a7b84896d078bc5722baac3db70cbc009552019491281c99d0e3ba0c5afd89ada7170567647c05f57578592ea4ee8213164c0112910253394ec366b94d21238f795e7bdf75b59fca7352d4194fd4d8d291f7f3e6a4446d69279b103d315e688714477487eed697aa62330512cbb3d48921559f7025201664c12e4ca38361f18881556b7cbddbe81490613761bb1fe49c0806440a6c56d6212932c2a041b9a1a9151479bafe44a795b4039ff655952425c8c8d8d1b31c0e6107ee872545055be38d5b27b5ff09af78bebd5be3bc68e9c371d255672eee2d9f28bf1ffa760f08f7ec86263190263cce45c0c00c0759b28c6989e0434c2e6ddc024d4edf222f92db533446058a8a92e31c6bc25011399bc0dff2020218a58a62286bc08d6a6404363abaaa0c32a8f199579adaef1444bdb679f9fb3045bedb2326a4c2690c4408d6a6b2fbef0a5fb9e7bea8aaf59f77d30b4b97268bcdd75c7c029f764dbebaa6b776cae3e5de49a3819486c218d29e3a4ed2b795353a3cfe7e3142d6e7461fe11761a6647ca3b835100420b62275cbcf970dc2657ff34200684c839ea11140855159b5b54901ce5959588c192fffb755abf64004e14ec999c00280127e25cf175343434cbc387c5ce99ddd6d7dd5251f1c1136b5e5ef5fcf3bfcf2f6d064bbfcc6b25c5b212943af9ce694a0822f27aebcbcbcb62636200b40034370f1519c65a855129f3a9991513756f23cd370c048af02217d2050624a1446069f7073d0db51919493f587ccfc90b5513278e9395a6d89ed12a06992ca1a230408b6ce52a4b1d3dea7fee7afbcadefd35fbf73baed67c5edd987fe9d263e3fb5a2c519ca11ee10542b60b4435d5d55eaf774046060018c2cb2e623798f9711e01918ba019441be64dc037309ab741002170469c8918168c1100a95116723aa5f6405b47000bff56d4d4ee2f29bd3865ca6849a696462f0057b90a68c168bb332eda77faf47fbdf7717ec1c7f6a91307fdece769bd5d77fa6b333de55459d627f30e5592817131bf2852f412555454343535a5a7a75757573735351933de058f8518c22ac1947547abc288964eb13811a31b2af56ec3bf08081850287712223039909a1a535153e9f7fb3b7cb8b7e070f65dc313a2a35c4e5bfd754fbfe424e48810e5b75b078c1d7be1ddbd2df12def9faec8dbf65f292ea997d737d1ce47589a2db18eb83b86d65a983594768510b1a4a424180ca6a5a5151717c7c5c5a5a4a49454b7889e749b6c3cf222e972ac3008e3ee5535a4c4657a96b97fe560de8610102282d8b59108cd03a4c6465bc68f1a70fa54f195cbd74b3dc1da8a9aa183fb5dbc7876c6cc6cd282f70415d916356c6806e37cef81df0e8e76f4744b00962136b5b6cc969a92b470617b8f9e14f023000222c340c07fe54ab1c3e1e8d5bbf7e5e2e2a4c44444acacac04162b7a1249b1c0a0585dae86aaaa98bdc122574633b5333698dff808ff87821e4301008890382082cc54b557ac6de2b8c1fd53e2af9696363735b6fbea264d1a9b9a9a42120b2a8acc3881d2618d8a1a3634ab478fbaafbeaebd7435d0d21e9b1ce79eb4c03164882fd61e90500d10a14ce01792d1a4a4949898e88e8e8e7ea9a9ae989896e666bbdd7ebd495f0a894815bc11111143e4c40911b9b1ad4402246400484c4249462649b24546262193001191ab8ac255550906ad369bd56a9524495839a088ef701bb1be4910fc35923f186c6a6c0a04fd0848a032647ddcce3eee4cd44358b5fb7c24d4831cacb2c4890801137ad8268e4f1f371638912cf9644b0393a1bd5d250a06785363a3a2061081736e91e5765f3b003026b5b6b44a4c220ea404190480b84c84c1a08a281111810ac2e1109121aa2a30462ae79c90137262807ece99c2254595dafda8a892df4ffe0059dbb8d3495156458e0a44455985e3a12c4b88c01803c4904debb72a39fbbf7b014f63fd7fa3050c9989aa0401320a23d4357600088575580b2064006d41944446d9b2f28a23478e00000072ad1280b65d4414e9709924fc349890adca127040c6648b0591812c11a22c5b880851222049621c50d6769e6816a8dd86ef3adcc0741011546480512306f5fd7fb0ce129839c4a7d20000000049454e44ae426082, 'image/png', 127, 0, '2006-10-16 00:00:00', '2006-10-16 00:00:00');
+INSERT INTO `previews` (`id`, `addon_id`, `filedata`, `filetype`, `thumbdata`, `thumbtype`, `caption`, `highlight`, `created`, `modified`) VALUES
+(3, 9, '', '', 0x89504e470d0a1a0a0000000d49484452000000c800000096080200000014be504e000000097048597300000b1300000b1301009a9c180000200049444154789cecbd79981cc5952f7a4e446656757555efddd5fb26b55aad1ded0ba805c2181b30020c18e30133e3198f3df6e7b1b9b6afc7331e3e2eefcdf518ee8cafafed798cb187f11bf03306592c360221c0c22c129290d4925a6a2dddaddef7adf6cc88f7c7a98a8ecaaa9604e3057b743e68456565654646fce2774e9c387112fbfafade7aeb2d00000029252242baa0046028a4440007121c0c94082850a200049408524a0494c824020340440e40d7918880c8e8b2eae2aac0189bbd11e25ca7b9ce747de5fad579ce994b321f5c4a79311fa9a07f5447f4b27e24ab500d5d77799f89b898ea09c05024debaf972a3bdbdfdbefbee3bdfb91224130888c06cb4994426984007814b00891285648c21034489cc404444ced0e00c0104e3c8900e2281833196f5a3eb2bd4c4759aaba030371734e7429e3aa83799eb88ea78755008311756e82bf55717c771e8a09312bdfcbe859482bb940e3dd7f987a823a17f70e2dfffed11834e154270ce6ddb7613830490c08051c3318e5230008608d201644c8260cc400404c118678c0170869c730ed23138030688cc05141d3afa5799789a0b7f90012f55501f211bf9b9da25b39932c9c90532d54499a8a2a6d7cbeaaf02966ddb9c73c2932abc6fe1258480f49179fe4a4a0920011918f46344741c873acf75e6f4f4a40d0e32404401c0c000474ae6a0527660004a8327158a811c9131099c2143292548d32b64b25a9c7300282929a17b65721866883a473d9baaa7eb1cfd887a001d522e78e9e30fe7d6442e60652a3b85a74cde9252123971ce096d8c31c2197db46d5bc79642a4eb297ebf828800a854f6f9ce04900020c180548bab36d27f2951740ff7f88a3d8e70101010e353098fc7629683527a2c8b034e0c47cbcbfdb64c20480e6c78281ac8b1bc26935230900eb09e5151122ca7c6e29c8f8c8cf8fd7e8fc7e38211636e62831463b90e66aa451775652ac7ccf2c53453b21134244186cd84883a5165c2cb7582ae04e95be22d521754209e781f12d8c5082220a2e11abbae869620d102c89388022472641897dce7587ec9c0f199b62131340df98536c838038902e333b22057fa73e2281c2ea523adc149aba0a0005280989999e19c33c688bd5caad07544ffca851b17f82003582eb4c17935e35cd683debb996a1100888432a94b018b732e35938b182b531b2a26239b840ea60df20bd937bf3dd1e9f922ce0609d2b8f07949034a20807004320029a4b4b9c940242cc300100071e47194881211246712659c4bc94002721d348a99942ad48f679ee9c25c26e0209b66d40749e6c7d4635dc0d872b56ce6dff3eb4497bda544e94497094f78a221c7182302a3332fa686ef37b9086051eb80e48800081201b80487734326128088c000989428a54460c8d016427226a440892235cc6868920e22bac28b33e1cf436317032cc82030c8ce58c2f5957a7a48b205038dc0547fcb39c4a51f3327898430052f65d453e328fd48ecf55efbf7f72617001602a2cd3cc283204182214ddb4e706999cc4a44e23e6f6e2222c00694b95220302624c49db8e479b68c300409d20603100dc310421886010034225d7a50115826b0ce0f2fb8d084910e2a73786ede4a23866cb43f3b19ccfcfb6e81a5f396c299ae130dc3500446d85250fe83900b014b32eef0e840421808121c2120ce6209273e23393362427064c286735d714086000868c7ac8178dce20c253200092084e8eeee565d188fc7a9bd2005b2b9180b0088d8328105e9ba12d27d5a99c00220e64c3b4e7f924f8a3c55c8d20e524a3a41d780eaab4cb528330cf9acf022a222c3cb05ac442281295381739e4824fe80a84b5e8c2a6c9abf404a011c1011241adc608c912fdd600c91316e30f29f265192fcc7303824bbdf04444551aaa054585678a9d3521761fa5c4fc7a57ec485330d58221d5298415a4cff98c95b38eb2acce2e8525f11af887407849452f9b1a43637149af74191161da147a38faa71ce4f5df87ef2dd5f1858b66d4b292d662160341ab5fcd6d0e0506565658a20180202607bfb89254b96d0a16834dadbdbdbdcdc9c34a478126184154801c2a5fe8e1d3bb664c992e1e1e16030188bc5fafafa9a9a9af47320c5589cf3d1d1d1f6f6f6cb2fbf5c8726cc61dd2baecaaa0a2f12584ace0f2c17c214985c7343a50a75439e40a3a68d042cc33012898432bc6cdb4e2412425cd402cbef512e0cac70382c8420b7d3c0c040535353595919002022cd5c0cc32083809e3f27270753167a2291f07abdaa9920c558f1785c4ae9f57a0180d48165590b172eb46d7bfffefd5bb76ef5f97cf5f5f56ae26d18065d271a8d32c67c3e1f35bace6a2e4b2b83b7d885807581c51f25329b03e282c012e75ded512a4fa4fc5e7450f9b714b068ac12b65cd425d27d90bf5fb930b0a494535353a4f2e9693b3a3a162d5a343c3c1c89441031140a2d5fbe3c1a8d9e3b770e11cbcaca727272e8993b3b3b6b6a6a7a7b7b2b2a2a94b77d7878b8bfbf9f31665996c7e3191c1cf4fbfd8d8d8dfbf7ef6f6969999e9e6e6b6babababebecec5cbf7efd3befbc63dbb66118cdcdcd96651d3e7c9873ded8d8989b9b0b290091093517b00090b1f33156d6bfbab88e640596fe315339ea2a52b7b764bacb54e14937e7159e68e812b0c8ea227865ade4ef5d2e0c2c44f4f97c85858584219672068e8c8c2c59b284737ee4c8116291e6e6e6e9e9e9e1e1e1eaea6aceb961183e9f2f140a4d4e4e2e5fbe1c520aabbfbfbfb1b1b1a8a8281a8df6f4f45456562e5cb890be6a6c6c3c71e2c4a64d9b26272769e04e4f4f5f7bedb5b66d23e29933672291482814324db3a5a505d39cf5d2c5522c7d0988180bd2380c208db12ee0e8ca2a3aaa44babb5c64acf3a8832e7829bf83cbead26d2c256a9e481fc9a88714a6df3ff0bad0ac1011002ccbf27abdba55a40af4302cc3f14d120c064f9f3edddcdc2ca5348cd918072a74757511f81426f4392089611852cab1b131446c6f6fbfe5965bfafafae88788689a26992fca36e79c4b09740748f33e70c87046e86544a93f324b5f8c070080e488cada7999aa102e3449cc548bcac6d26d799e214cf30252d3911d4ccff23eb1bd2ecc58645dd1931414142022b1d7a2458b4e9c38a1467959591963ccebf51615155996555454c4390f0402e17038180cea5eabd5ab571f3c78f0c48913cb972f8fc5621e8f87beadafaf678c5d79e5952fbffcf28a152b2a2b2bfd7eff92254b76efde5d5e5ebe6ad5aa9c9c9ce79f7f9e31d6d2d2e2f57aebeaea482928dc9081ac66a3a0e9c40c0203d0d84b4ac9581a6232790b919f87126486730b3280051a8d65024ba942f2f9a9551d3b43480fd2b313cee2f1b8cba23fcf18f8dd08eedebdfb8b5ffce25c5f33c6c87272e911a6b91cc3e1706e6eaeabcf142dcdcccce4e5e541baaf52e9538282ba268dd764cdd26f0ae99d4d68b8eaaaab94e9a693a5d4dca1a9af24634966d5288dcc2f70dd11d2c1972a70d711120526753c93ae20092947672fc29810424aa1967614c2946721e57bb76ddb4e241cb2b4e82f15e2f1782c168bc5628944821c5dbf0ddea278ac0b9ee648e81f98f8f71f3f723ec6a24e6a68685094ab2c47c2010d173aa294a3ee5ed77f483a8bc849fd45cd4145aa4d1d07cd89c0668d7420e5487797a9e8280293be4c04e9ae07c6409dec2233d0e09e0962adec8e83cd6c2ebde97554417660a591961eb02584300c432944c3701cc7b06d9bb1a42fde300cbd79d5c88cc56274b5df235791cc092cd7881f1f1f07008fc7535858a8ba1935c348ef7bfd69d5576a9edcd7d7c7182b2828282d2dedefefcfc9c9f1f97c524a8a804829cdd91f22e2cc4ce8dcb9738cb1aaaaaae2e262ddc803cd32dbb3674f6b6b2b68d0b46dbbbfbfbfbebebeb3f30c22363636a61e8dea4908e398f28fe880cc6c0a484d33610e073d4092d5084e52ca74fe121a7b6577c73b8e300c3daec649319663db36e736cd91492192a347ad5bd3b88dc7e3e4cdf9cfc0e23f2f170616000c0e0e92772a1e8f8f8d8d959494a8e98cc7e389c7e30040da90ce618ce5e4e4d000628ce5e6e6aabe3f70e0406d6d2d00f4f6f67abddef2f272cef9b163c7a4948b162df2f97ce1701811fd7e3f63a8f0f9da6bafd10ce0c89123ebd7afcfcdcd0d87c3524abaa9e338d168d4e7f3ad5fbf9e31160a8568c4070281898989ddbb77df76db6d75757554e770380c0039393e9f2f170066666668699c060c6481913a225d47cedfb204d64cb5e832e4d38105223d608bf0a42c2dce136aad9a809569d7d3904b2412cab07355e93f81967721e75385d47c131313a669124f103e62b1d8d1a3474b4a4a02810022cecccc20625e5e5e7d7dfda953a7e2f1b8d7eb6d6969397bf62c7db57af56a4879de0381c0d0d0d0f2e5cb9b9a9a00a0adadcdeff77775750180d7ebcdcbcba355c54020b06edd3a0049966c6e6e6e7f7fff962d5bc8c171ead4a9d3a74f03404e4e8ed7eb3d7bf66c5151d1aa55ab9e79e699cf7ef6b3ffe7fffc1f5a036869693977ee5c7f7fff2bafbc525d5d2984c8cfcf7ffef9e7ebebeb0dc3bce69a0f0e0e0e1e3c781011f7eeddfb4ffff44f8a6e219db021c9c112208bc1e76a2ec87074a9b2c8e632cd0496d28c3ab6484cd354361679e439e7a6692a84e91346e22d32fe7ef704961d58ba1aca3c428c327ffe7ccef9db6fbfbd7efd7acef99b6fbed9d0d03039395958584806f5c4c4444e4e4e3018d44d8165cb9645229103070ef8fdfea54b9752732c5ebc5808b164c9929d3b7746a351cbb242a110d95288cc30d8e6cd9bc3e1f0d34f3f5d5d5dbd6eddba93274fae59b3a6a2a222140a1d3972a4b9b979d3a64d645830c68a8a8a6ebef9e6a1a1a1d75e7bedda6baf1d1c1cbcf5d65bdf7aeb0dd262ab57aff9c007ae7efcf19f44a3d1f6f6f6b56bd72e58b0a0a7a7c73066d706a8aaa428534fcc102fec03d3cbae1ed5f9c3c55b19c696a60993c6bbed38c45b42018b6682a4160958fa5f82573c1effed99f3e7972cc07261282f2f6f686888ba2d168b4522914020609aa66ebc43aa3fd6ac59333535f5ce3bef7cf0831f5cb56a552814faf5af7f5d5d5dad4e387af4e8b265cb366dda74e8d021f24ee9bdc539ffc0073e909797b77fff7efa48cec383070f6ed8b0e1e69b6fdeb16347381ca6f901001c3870c0b2acfcfc7c445455523a882c5ce23c00340c8e698be5689aa60284659999062268ee56575521ddfc9f0b583047800d645bed4937b692f84af73b086563d15fd334095e2e6029ab2b168b292f97d4e6e3bf6d9c5dd8c6f2783cf5f5f59d9d9d524aafd7dbd0d02084208b8431b66eddba43870e31c6366cd880886d6d6df1789cd6863b3a3a262626aeb8e20a96f27372cee7cf9fffeaabaf32c6eaeaeaaaababc91a2b2f2f3f74e8d0fefdfbafbbeeba5dbb76c562b12bafbc529965a669363434ecd8b1030056ad5a55545474fdf5d73ffffcf3afbffefa35d75c33353595b2e160c992c59cb3e1e1e19ffce4f1fcfcfcdb6fbf0d11376edcf0f8e38fb5b66e06809c9c1cbfdf6f59564bcba28282825b6fbdf5c9279fdcb3674f6f6f2fa150c750c67464d693a2939966eca7b95855c7c9a44b295996326bfc96c814ddef409248d88ee3e8ee06cbb2e2f1b8699aa669241296699ab1584c995c04b2482442d852d5fb1de847b71f8bda487129610211e92f00505d31e56260a930187a0c2acce57a505fa95ba86f953f42ef5dae39e25d7f792a5022759159a6f98fff78eceebbef028d7af59979ea2fa7c38f3ffef8c0c0c0860d1baeb862936b02ef9ac923ce3a41c0bd1c09906175a98faefe23ee57bc25d23cf2367d2418c994f7c1656c11b014b64827d26430164bc462b168344a7fa3d1682412a1bf04539d32219d4dcf2fff593f96cef6d4cafa41d5d3d9da3d6d3107534e54c5043aaa14924819214ab2d35db8d1094355462f68159bc5d05d77fd49068cd26a4548a6fdd977df7d77ea20e827b89e51014b5549b5925ec88a30ad6fd274a2d0d616530ad11019eef8cc49a20e2f17b00c234eb63cfd55ca111175de52085335ff8deb47433db3aba5f4f2cccc0cc5ab048341cbb2f4c6559022cc8d8c8ca8a01a961ed8ce52ee4d7571652aa5fa72d6710ae9ee53d484a7c734a78813a4e620e5196b8e5981a56e3417b1651d3f2e2465226c2e4144179854e327e7845a59b7e8356c2532798b80459e77d38cc7e371cbb262b198490a320532d3342391482c16537852b7d06bf89bc2d69c8ca5da717a7a7a7a7a9aec989e9e9ef9f3e7c7e3f19c9c1caa1999c64e6a4fe6e1c387376fdeecf3f98410b40ee8f57ae9e139e75eaf37168b01402010d0d1e338895028645956201040e4b158cc711ccbb27c3e9f6ddb9148c4e3f1f8fd7e21049d9697978788b494e1f57afd7e7f22110b87c364c86752a3c28a52df8c71c6380028177626bd41ba32c50cd15b0c2e3a960b353d08d9226d149d28e5a551972184a0a51b42582291201f44cad84a10b02ccbd221a53fa6beaaa82a23b4f01bbd7abf0160651b7612405a9645cf505151415ff5f7f7070201ead4eaeaeae3c78f23a2dfeff7fbfd333333edededf3e6cdebececa4fe686e6e1e1b1b3b7efc7830185417f7fbfdab57af56fa6e7272eac8912388b868d1a28282c237df7c93ba7ce5ca95070e1c0000c6d8ead5ab0f1d3a148fc70dc3686969a9abab7bf1c51701a0b1b171f5ead5cf3df79c94b2a2a2e2ca2baf542a355334bbd000486a76fdfc4c246585545630bd676051417576bad595b6e623842384304d5bc1cbb66dcb9af53e58562c1e8f5b966959a6691a54a0b2f2d487c3611aba90314b9552eaeb0a1abcde35ce0c852aa965250000da22c818fa7cbedadada999999b6b6b6aaaaaab2b2b26030d8d5d5150a852ebffc7200181f1fafa9a9292e2e2e2929292c2c5cb366cdcccccc99336782c1203d30c16be9d2a5bb76eddab061434141c1134f3c41b348eab69e9edea9a9e9e9e9e940208f73c3b2ac0f7ef083d168341e8f4f4e4efec99ffc09b5c21b6fbcd1d4d4e4384e75757522913877eedcc68d1babaaaa10f1ecd9ce75ebd63634345896a520a2f11353ce439db1f4afb292134b77a6e890625956a92f2a90cb45063ab0327b5af747a8802d029969da3a6f5956c2b6139665c6e3718fc78ac52c8294c7635916e9c459cd383333432e2e35452000082132a94a523e86f7062cd51cba41a25421001415151517171f3972840244491fd1099b376f1e1919397af4e8962d5b306546d4d5d56dd8b061606040ad19d35d540f29bb5e0871f2e4c93beeb8a3a3a383e2fb002091489c39738634a6e338bdbdbd8cb19a9a9abbeeba6b7272b2bfbfbfb4b4f40b5ff8c2be7dfb5e78e185bff88bbff8ca57be7ce2c4899ffdec677ffbb77fab2fd0b2d40a5a06bc9236d6ecd3cea1f598b6c8ad70e652857315b2ca5cc062c9c80b3785e8eca58b3e5b246f966ddba66990214f68b22c2b1a8d1a86611896695aa66992a71e00c2e1308d7982296a3e088297fa88a9e5d1f708acb99a263f3f7f70709042af962d5b46dd6018467e7e3e35073933c95fb571e3c6d75f7f7deddab5f5f5f57bf6eca9aeae6e686850e6766d6d2d050c2e58b0800007009cf3ad5bb73efbecb38cb1152b56d4d7d78742a1eddbb72f5ebcb8b1b19131f6e4934fd6d6d66ed9b22510083cf1c4132525251ff9c8472627277ffef39f7bbddebffccbbf04807ffff77f47c4af7ffdebc458a4dd74964aff6bea7ca600e4fa08e916e705f10417825456d171e6d28f2e0e93e93e7ab26e95133565d11ba42528ec9bcc15afd7ebf546bd5eafc7e3314dd3ebf51a86e1f17888b77480a236bd10a9dc24f23d39bd66fd58ae31cdb97210709d03c8e1dbd3d3336fde3cea4597c67139c094a27115321590eb2000a800519d54a832f42da4ac6f7237b0d4ce0ebd3ea95a195a55d32ea8e349672c1d5873a1ea37052c4c9ff0cbf469a38e309769ef622fdb8eebfe2d9adf44a3d16834168944239148381c0e87c3333333333333535353c45b6ad3a27e4d5d0b0380940ec5409f5fb2fbb1309bf9c9d2cd5800f0783cae8d59fab7a4e3d40575e8406a6eafdc9beafa2cc347408b39e4e8d2fd08ba1b42619773c6b941b0516b1abae2cbb0b1189bdbae020d46176429058bf780aaccabe96521dc9bb3656a4d86c69bb290782a6adeb6b9e3085aaa36cdb865252ccb63591ecb8a9a2659f1a6528864ced33e06aeede857ca319d3211914929f4fa9ce7a1d210001ab694c462b1a9a9292a575555a976577f55afa84916a4b679a91a28673d9d494cceb53d612e08d299b4fc0700a74e9da2dd13ca605208534b84d44caaac9fe9fa9b391ef481e142d205592af3cc7725aa89327fce525697faca657b119e74f6d2c29a2dc3306ddb36cd38595796657abd1ed3b4c8fcf2783c86615039140a116f51b8845aa0d4af0c00528294b3b3d7f38b9bb194a883535353939393a5a5a5e42b4f241200402a3c1c0e33c6c8ab445bc1a8aeb66d5324bb629768344a4abda8a88828daebf5e6e6e6c6e3f16834ca392757052216151531c61cc7999e9e360ca3b8b8787a7afae9a79f0e0683656565e170d8b6edbcbc3c6a97f3404a1dd42513582e96826c632c1307734121eb997389de3de73959ffca052cd066153ac2582ac89bd6aa0dc3304d6e9a8665599c2721a5788b9a8574a26118345b64a95dd7ae479612016cc56030376fcd69bceb4f1a0e8727272783c16028143a7af46830182c2e2ea6480782c2bc79f37ef9cb5f363434e804b06cd9b2fcfc7caaf7ce9d3b0b0a0a0cc358be7c795b5b1bb5c8ba75eb3a3a3a3a3a3a82c120a41cee8585855bb66cd9b3670fd1646363632412191e1e7ef5d557376fdefcfaebaf533b6edbb6adb8b858a12733e4cdc5583887631d3424b1740f4256ae3a0f14de2d63659eefea241751e9c731e50cc39416d611464cc6b5edbe8984619a663c1e378ce43cd14ae9459e8ae8a27d759c73da78cc18a32d1b645a21a2c219a652c99de7e9b2ec5cc8ec86e2e2e29a9a1a62a6c2c2c2969696aaaaaa9e9e9ee5cb97af58b1e2cc993388989797b77efdfa79f3e671ce376cd8609ae6f4f4b48eb3d5ab576fddba3591481c3f7e7c7272726868889617d6ac5973dd75d78d8c8c7ce0031fb8f1c61bdbdada18636d6d6d1ffde8473ff4a10f1d3c7870f3e6cdb5b5b51ffff8c7c7c6c60e1c38303e3e7eeedc3972cdeb42b36ba252d56a6ac9cc302c1d7c2e0e73995f982eae1e9d4bde15aa2063b3eb5cd7d78fb33944276962236a0d5af9c84989cf97ebf7fbf3f2f20281407e7e7e41414161612139928a8b8b0b0a0a7c3e5f6e6eaecfe74bcd25bd1e8f87e6927a18346a964386240f1aaea782d9f141de0b94529aa6e9f3e5902aa499a0321e410b3057131cbd7bd4f5fd7e3f1d5fba74696b6beba953a7687ca856a34ad395692b018585509309e170ceaebe7aeb873ffce137df7cd3e7cbd11759796a8b818e9bf4567063c6359c5423b8dbe9bd9ae417948bbcb2eb348545577f2998a2c6617c766722e3dc300c9bf33871bcce55aadd88b7e823adc229f652463d240334923e7a210459f4a9fa256bcbefbefbee9d3b77ce311a92ebbba669e4e6fa1093dd43bb0b6b6b6b0f1e3c383030b079f3667a98d2d252eaddc2c24221447e7e3e6d4625cd4ddba3f3f3f31389c49b6fbe595c5c3c6fde3cc7710a0a0ae8605d5d1d3d406363e392254b7ef6b39f7577777fea539f324db3a6a6fac9279fbcf1c68f0c0f8fbcf0c20b0b172e6c6969219b540dd014336589a54c27a92cd6fa5c3dfddb43d57b964c76d49f622e36a5ae7419a0aa5df4725624606ad1dad562a9b2ee8ac39950e4a69b6f4cfab15c574fb7519000ce987b1a8f19d334963eff5205e5178094e709538b743cddcae69a25ae06966130c5f38661706ed027c698ee4bd3eb80191cc532e6b3f00702a60b8aee59957378edc9ae5761cdb66dd36ec470384cfeada9a9a9e9e9e9a9a9a95028140a85e85be50c8bc7e3e17098d488ba1ad115396ee9be8e60fd8363b37eacb9da57a9290aab8174cb40f51c4bf738b88e732dd0457dc593bb960da50dd3d1cc15c24cd3e41c95914e568461989c73cbb220157bc8b2d9492cdd60820c60cdf5f87f583257f72960d1e313e55073a90d644a21b294f3999a91e223f40e2254a166ce03801069f7521530b2564b974824c6b91d08040060787898621cd4cdd4cfa93b2135b9dbb76f5f5555156937d020a88b6118c3c3c3dddddd8cb1050b16949797a3e605350ce3d8b163ab57af4644cb9a7dfeaf7ce5bf7ffbdbdf56b0a3f83017a4f47b41fafe7ac8c2e47f3ca2fa58ff0829bfb4f24460fafa8752057a984d241251656a6dfaa16a55917ab78010021110414ac952f111d93def7a4f4c4d4d398ee3f7fb11b1a3a3a3a2a20200c85d4bf3442a9ba649bbc1a2d1682291204f04638cf833100830c628fa6c6a6a4a6de2ebe8e8989999696a6adab973e7273ef109fa564a595656168fc77ff2939fd4d6d69696963a8e3336369e9beb2f2b2b8b44228383831e8fa7aaaacaa5705df0856c696d5d2dfec727f4ec3ab674a797de324a81a4cf7266f58c6e20616ac7a86a64f2cedbb69d7ebbe4ff49c6527ca3f310492010e8ebeb1342f4f7f7135dd1e641c6587171514343c3b3cf3edbdcdc8c880d0d0df9f9f96d6d6d9c73cac7d7d7d777ead429bae0d5575fbd73e74ec330727373376fdeecf57aa9ea7575754b972efdf5af7f4d1cf6e69b6fc66231bfdfdfd2d2323232b26bd7ae6baeb9e6a59776716e20626b6bebf8f8f88e1d3b1863ab57afbeeaaaab0c2d894d26b054416ff7df591fff1e45a72e0535fda348ed9663e906314f8532eb1c46ca818c33a5af085298ca752393e137000038d7f62fbdecf7fb29a9dfe0e020adab74767652688365998c617171f1dab56b7b7b7b07070769696fe3c68de4d21d1a1aaaacac5cbc78f14f7ffa53d2f46bd7ae25fda8eaf7d24b2f1d3c78f08a2baef0f97c030303838383894462dfbe7d77dc71475d5ddda73ffd6944fcc10f3abff39defd05cb7bcbcfcde7befedeaea7aecb1c7aeb9e61ad40c3b4dcd6647d57f6571e109344251f330430b34a51ed4a774e480500d4e20538d4c4b408849fc1830778490427d6363e33befbc535050e0f17800c0e7f3ad5dbb564ad1d7d7ab8f0348a91ef279c854e24dda684f972295cab489dbb5d75ebb6ad52a1a19bb76edbae9a69b82c1e0030f3c40eb59e4ca324d331a8d76767646229194399f1c64466a63990b55a08d90ffb2f0d21f5c5f0282f485735d39426a5f024fe55c5142fb1e582a864035b5d4f7e2a6ae96f463299cba9c194489393939939393e5e5e50505058cb18a8a8a43870e8e8c8cae58b182732e84a43519b27b6cdba618e2a6a6a679f3e675777753c285929212c7c07407f10000200049444154712a2b2bbd5e2fa6e62652caa2a2a2a2a2225a6458bb76ed33cf3cf3f6db6fd7d7d7af59b366f3e6cddffffef71b1a1a56ae5cf9e8a38f0a21b66ddb168bc556ac5841cfbf70e142d09282b8947866e3fe5796aceda05b5da859f4a8d95b0a09762a8d20fd8469e9a252d7472171727266dbb68fe0eeddbbefbdf7de4c5f991223fb5a2fd37e925cc85444aa2e95fa385b63f242697e04a642662d4bf7769aa669e96a5eaf926b0ccca5fb2e416a2ec9f475a9fd1a898463db71da99180a4d8742a1e9e9997038140e8729eb6c384c1b15c3b1583c1289ead9b96cdb8ec5c5c9cede1fffe8e12c36d6f91717535d486f526588d9932fea5301962e9cb3142e19e79c60639ab3735dd3b414dad45c57815b7795b1f4384fb804a68b13971ed47a9cfa1420a9349d94964444a46016ea41445214e07222d9e02033386717d862af975dca25abaec9d447ea084bf78c93e87bdfd20bee7834f52bcc70535d02d37b10d4628ef526a5659b940d2e54e42da6fc4abad50400442e8a416c48004821b3bdfd2b2b50f48f1714977ace60ac59b5e89ad3aa8fda97690b4deaca900ee2cc9a5f920b8a0b5b3a23687cc669295008e1f3f9b8e6184f619191479454aa25d0b23c9075c32a64e3a44c846516e602990b55ca5c53b849d958b4c7d29395ab7460b92a039720f55e25b319313531d4466fd2bdae12e8e97fd50974b22de2866571ceb3b81b94e82b9a7a3d30fdf5a4e7879d8257e69c40d78014dc9819c5a1e82a2ba42ee1e93722991dca53a150a9f6968ee3e4f8bcc82432c958daaa06f931a86b623600a024cfbb2e2e24a91bbbca2ee674955d44e532ad5c5acf300cd3b42810cf30b218ecba5ed7ef059780f59b139c557f6939b40cc3204795e3385eaf37454e28936f53231b1f2015df17b3933134b34941f4d00b75b3b97aee3cfd3a9736d4dd198aab14b05c6696ee5960d95ceabfa1f6bc24b392e22df27192218b8c0995a924272787ba82ba84b3e4444a4a50f67bcc06d3f220b25960e937b8c87a4086363c0f9e748b2a6b805e567f9502169b7b4bfb25f94d09e935ea5248b211722e01a410c2b22c4afc9ca43786a954f552d9efde84b42c0fe8c0ca642c57848d8b2db2424a6797ac66bb42921ea1711eae22d1ef089720f5db14d27400b39beb39e700d2341dcb3215b0280247cec6d12497ec62362072649834de5d5da59b72b443abb8b81800c6c74773737303813c1d7ceab78cb14824128944f2f3f3fbfafa9a9b9b8f1e6d5bb76ead6eaa93e2b32ccfd4d4f4d8d81891164562353434189aef5ec1544af9da6baf0d0e0ede74d34da669d2bdc47973e4f7f6f6161717e7e4e4b8a247b4b6bb241710b2b7685d9931e4dc608c53900153af1711699a444a1917066316673ccd78d7579455e461381c1e1818a0d0abfefe7ecac24d7b1a69871aed31a21061afd74bc9b11091d69da91294963d27274719583d3d3d5eafb7b8b8d834cd6030681886949202617d3e1f22d2269f929292f1f1f18e8e8e6ddbb61986313333138bc57c3e9fcfe7a34834c330a6a7a7f3f2f214453ff3cc331d1d1d77de792725f122a1bc5c9665cdcccce4e6e6aae6b8241992d6328cd1eb972563f4ca5c4936bde39800407a33b5195f0ae18dda68581ee4861b58b41f4d7d040044aca8a8e8e9e9f1f97c15151504a3a1a111c33000a0b2b292733e3a3a1a8d460b0b0b8b8b8b2726266a6aaae93d6f24d168b4bfbf9f73ded0d0505353a3b6b30d0d0d251289cb2ebbececd9b300505050f0da6baf353636363535f5f6f652944f7979b9e338131313870e1d5abc78f1e1c38709ca9b366d1a1d1d3d7dfa745353d3891327b66eddaa388952df82c6a652ca89898983070f2e5fbefcc89123adadad14a67149ce23aae9a8cc38e39c01ccfa4b89d2104082044cfee789a1c7eb1342ccbe99dd6551b9ee515252629a26bde69476f8d7d4d478bdde5028949393535252e2f7fbababab53bd9b34fd48a98d8c8c8442a1b1b1b1f1f17142151d5fb264c9860d1b688f35a179debc795bb76e6d6868387cf8f0e8e8e8f8f8f8f8f8f8d2a54b83c1b2abaeba8a12246fdd7a95e3d8d3d3d3b5b5354b972eddb76fef962dad988a34026de64c1fe9785959596b6bebeeddbbb76cd94291f297e4dd894cce1695ad6c59a665591eafe5f1585eaf2727c7ebcbf1fa7c3e5aea9d652c32c7941274d9f294c85a085b19e6f4e203c6d8f4f4f4c4c4447d7d7dca2a023d9c81733e3c3cdcdada3a3a3a4a9bb89593dde7f35166479edab94b498e10b1a8a8e8861b6e88c562f4060a008928394700110e87e816b69d686b3b5c5252dcdbdb535b5baff044595c296f9b65591d1d1db9b9b9e5e5e5148d73faf4e9850b17669a959724aba8f91220622a49ac917cb7439244548271218437870909525f2b54d4e70296c7e3414432a11c07737373bd5e6f4141416f6f6f414141717171341a751ca7b3b3b3b2b23210081417177bbdded2d252afd75b59596918c665975dd6d6d6669a667373b3f22954575717161692c955525242a8226001c0b66ddb76edda6559d6b5d75e2ba5a4c8d579f3e685c3e1175f7cb1a5a5a5acacaca3a363d9b265454545fbf6edabab6b5095dfb3670f63ec9d77de098542f46643cbb28686861a1b1b2b2b2b0f1f3e4c59a37ec73df4072b842c49b37d917aef1f1942866112aa94ba8824129c1b8cf3e4be424ca59e520e4cf57768680867f70f424a6de9f158fa466454cb7c0a4364e3ebb342e57ed77d0aa8852f8af45cab884038a74252bb2353cf93c940cae492e9919300505c5c7cf5d557ff2e3ae58f4784e3d86363a3002052a90553698f9c44c28ec762f178221a8d8c4c26befba35ffced57ff2ccd8f45d0d3fb00002a2a2a08289c73d3e4a9b0e0a44643443ae2f1780c8393de255129e4727272288980d7ebddb76f9f10927605aab54ce55c808c77e6ba4cc8cc27569c2c5391d0904a9c44b95668cea23f54381c7ee699677e1bcdff4721126613432647351d8f46231292ce5241db54a51002ec84ad52a1066b16d88e340cc30dacd9cb6b47c80052b630003096748011d998a68128e93d4724466a03a49eb4830cb29b6eba598b1ab574572aa4984687978eadcc8f591a467b6f8ca26ee5d65346fd2599430424d3762485862a24bb66364fbdca2468db0ea5d77af3cd3723b6e3f70740a6b67fa9812ed3dfa607e99376853dd53d29379a60cc90a99dcd86160c33ab5e558ca8c10d831b866970132570ce90736086403010410ace68c580f2c7314555a8c50fe970919aef0d6717530152af06861411722d93e0259943d0052c489b6873982517e41c543c16005896954818001250ce7ade7524e953427d9e28255254853a8700a6bbcb5df10b86617083f6c49b86e9b5d0b0386326e3a6c98173c61c89532139383a24018305f97e0ffa730d44905200080006022403a979105c6b3b991f75845d243fd113b914b16a10966d738be23f9d4d5dacaf9fe0aa893e2ab2f6a2abfd7f4b5cebaa3ca2db75ac46b55e432a28eb85e689866140021004809c558599d8d2e582f5d3359a5aef330cc3340dc364a6c90d6e71e691e865dc070800091b65df343cf1dc5bcffdf22d07510008277efb75ab6fbd764379519e6971641c24200315a4011a835e647b5de44f745666a9fd272e64b83eb2543a50d77d754ed5b19e79c7cc85a94c2c5ee4f3be37c93a9c2e287af53015a34c3d3e3232e83836ba723748cd783f0fb654639164e2299db44cd3b00cc334381aa6044348c60cce19b3e30eee7cf5f08f7ef2cab296ba4fddb9d5c3e1c489b363839de3a363967482e5450250a2c30111b894108fc7295f0a259238ff93438a51cebfaa789e56cb9cc764823b93ae1863333333f4966b4ca54d8f46a3b9b9b9ae1b4929676666d46439f316945f93ea407b337f1bae5dbabee338b1582cb3927389ae25582aab19636c606020140e4b2993968afe9bb9882af3086aa2b0a53c0bb33616332dc60d8e9c03e38259028d042224e24e643aeed846ff44fcedc39da199d8075ad77ef9eedb6bce9c883dfd54b4eb0c170e93f2a9a79e7cfae9a711f1e5975ffee10f7f78d75d775df0b1a5942323230f3df4d077bffbddac6c9129ededed0f3ef8e0830f3e78f8f061c8b0de7efef39feb5c3e3030b06fdf3e1d52b66d7feb5bdf7af0c1079f7cf2c92f7de94b2323238a6c060606befad5af6665acbbefbefb9ffee99f0e1d3aa4aaad6ed1d7d7f7cd6f7e736c6c8cbefac10f7eb067cf9e0b3ec5bb15f58cd3d3d3fff88fffd8ddddfd6e7fae0380731e0e8785e3d84266598456c63b686012da5bf6a46631e06cd8b18a27263ca9776c58a6e121539d732f479303e3c86c3bee318c0f5fb5bcb36fe4f523677ef4d3973da6599203dfbff30adf23ff1aee3a6d6e5807028687479fffc52ed332376cd8a86ba843870e85c3e1a54b97d2bb99a8ce866144a3d1f2f27200c8cbcbbbe1861bfefaaffffaaffeeaaf8e1f3f3e3131416f2da013bababacacacac6c6c6bababacacbcbabaaaa1e7ae8a17befbd170082c1e0cccccce1c387737272cacaca7c3edff8f8782010181d1dede8e80080c6c6c6aeaeae1ffff8c7a6695e76d965049d871f7ef8b6db6e9352060281175e78414ad9d5d5d5d3d3535353c3391f181878e38d374a4b4b9b9a9ac6c7c78f1f3f1e0804e8c5d5c44667ce9c99376fdef0f030e7bcb8b8584af9faebaf2f5cb8b0b4b4f4dcb973dddddd67cf9e6d6969191e1eeee8e8282a2a5ab870e1debd7b6ddbf6f97c2b56ac88c562f41a07bac5ebafbf0e006bd7aeede9e9c9cbcb9b9999090683fbf7efe79caf5bb7aebdbd9d36fab6b7b73737371f387020168b2d5fbe7cd1a245afbdf6dac73ffef177054addf263a9a02983b3341b0b002863ae4cbd04817e4c077585a28c0c52b28c513234d330684ba08780651896699adcb09019c82dce4c8696c17c28111d99884e979615fcf77bb79deb1ae81d1cd9f95aef1bbb7e6df78f8c0f0e54ce5f6854d60a349e7ef6b99b6ebe29140abdf0c20ba5a5a5a4da9e7aeaa9bebe3e9fcff7fcf3cf575757575757cfccccd8b65d525272faf4697a57856559cdcdcd143973eedcb9dedede1d3b765c7ef9e5bdbdbd9ffef4a7ffe55ffee5aebbee4a2412edededafbcf2ca75d75dd7d4d4f4ad6f7d6bc992255ffce217bff18d6fd4d7d71344f6efdfffc52f7ef1bbdffdeeedb7dffeeaabafae59b3e617bff8c5a64d9b868787cf9e3d7bd965974929b76fdfbe7efd7a5a29223975ead4eeddbbabaaaa5e7ae9a5abaeba8ac0b467cf9eabaeba2a180cb6b7b74f4e4ef6f5f551b30f0d0dfde4273ff9dffffb7fbff0c20b5eaff7965b6e0180c71f7ffca9a79eeae9e979e491476a6b6bfbfbfba594131313ededed6363634343435ffdea57fffccfff3c140a9d3d7bf6e4c993a5a5a59148e4adb7de5ab76e1dad2bbcf1c61bbdbdbde3e3e39ffbdce71e7becb192921221c4d1a3479f7df6d9279f7c1200bef6b5afdd7efbed6363631e8fa7b9b9f9d65b6fbde5965b2e1e580a5e8a5f0855b6e360d6a4200429656909212841b2611894f918b47dfe0070ead4a9a54b972af795cbd7c0180c0c753736d61b864033215818588ca3650b8845f9bf3dfef4c9fef0f51f5892979b5b17c4d3793cd78747c7069b6eff2882134dc45efbf5eb850505f178d4b6ed6ddbb6d1331c3c78f08e3bee58bc78f14d37dd545d5d1d8fc79f7cf249c3306ebdf556d0cc70aadec9932777edda353e3efeca2bafdc77df7d5ffad29776ecd8919797575959f9ed6f7fbbabababbdbd7de5ca955ffef2970160e7ce9dfff22fff72e4c891fbefbf1f00fee7fffc9f5ffad297d6af5f4f03acb5b5f5631ffbd8a73ffde9582cb666cd9a9b6eba09346df2e69b6ffeebbffeebc8c84830181c1e1ef67abdf7dc73cf3ffcc33f0c0f0fb7b4b4fcd99ffdd97ffcc77f747676eed9b3e7d8b16303030394be4c4a595353d3dcdcbc63c78e9d3b77fef8c73fd695e6c4c484e338f7dc734f2814b26dfba9a79eeae8e8e8eeee2e2c2caca8a8f8d33ffdd3c3870fffec673f3b72e4c8f6eddb272727f7eeddbb7bf7ee8282020058b0600100d02079e08107b66fdf3e3131f1d77ffdd7a04d1100a0bdbd9d5216b80cca8b44956ec5d3253d1e4b660596cbc6a2355d7a25d3c4c444797939414d4a49a6250090833b168b1986e1f7fb559016b9288fb4b515151706cbca1832ce2c86a604c63d1ee491eaaad2b74fecffce0f9ef619867412375c7999333d222f5b0e5bae80dc4068726a6a6cf4cffffc5308f2fefbef8fc7e354c3e2e2e2bebe3ece795151d1473ef291bffffbbfbffffefb11f1a1871ebaefbefba8d53a3b3b63b1587171f13befbc73d96597ad5cb9726060404af9dffedb7ffbd6b7bef5f5af7f9d427deebdf7de279e78424a79f2e44929e5d8d8182d80b6b7b77b3c1e993e47ebebeb6b6f6fa70cf5b43cdad0d00000dbb66d7be491476ebdf5d62f7ff9cb5ffbdad710312727c7b6ed13274ed076bcf1f1f1f6f6f65028442fbafaea57bf7af0e0c1dede5e350c6eb9e596fbeebbefeffeeeef543f1516168e8f8f9303f9c489134343437575759d9d9df7de7befabafbeeaeab2b2b232ba3e225656567ef6b39f0580175e7801b4e08ef6f6f670385c51511108044e9e3c89888ee35c75d5554d4d4ddffbdef7e8656c454545ef0a583ac252b8429080984a0a029a9dafce53e4462f0d080402b4b36c7c7c9c3cad94c1766262a2b2b2b2afaf2f914844a351cbb2727272ce9e3d1b8d46a7a6a62627a74687c72dcba8aaae360cefc9a3ed4b972d032698c9189339a6b97ac5e28deb566ede7859ebcae62b1754e081b71a5b5af2d7ae83fc3ce4100c96b55e79655d6d2da5010f06837575759ffce4275f7df5d583070f7ee10b5fa010b1cb2fbfbcb8b8d8b6edd5ab5753fdb76fdffece3bef7cfef39fdfb871e3891327de7aebadfafafa4d9b36959494241289356bd61416160602815dbb7699a6b971e3c69ffffce7a4506ebbedb655ab563df9e4930303036bd7aea53ce41e8fc7b6ed5ffdea57939393b7dc72cbc68d1b8510070e1ca0b11e0804366edcf8e8a38f9e3871a2b5b575c58a15975f7e3963ece5975fdeb469d3ba75eb7a7a7a4e9e3cd9d8d8f8a10f7d68e9d2a53b76ec989a9a6a6d6d6d6c6c5cba74696d6dedd9b36743a1d00d37dca068a0b8b8f8b9e79ebbfefaeb7372725e7cf145afd7bb75ebd6152b563cf7dc73b158acb5b5b5aaaa8ad6e60b0b0b3ff1894f3cfef8e3c78f1f1f1b1b7bf8e1871f7df4d18e8e8ecf7ce6333e9f6fdebc795eafb7b5b5f5f1c71fefe9e9f99bbff99b0f7de843fff66fff76e2c4898d1b378642a1d75f7ffd861b6e58b972e5c30f3ffcc10f7eb0bebefe3d408aca3d3d3d274e75f50c4e6dddb236b9082d356709a627dd52612dd168343f3fbfa8a8a8bbbb9bde059f9f9f5f5b5bdbd5d5bd6ad5cafdfbf79797979ba6595f5f5f5555d5d5d575c51597536e8f3dbf7aedfa1b3e6c9a1c99b163fbcf6fbbf5a38c338912016391f8f0c8c8f0c8d8c4e4e4f4e8d0f2e2e2e9a79ef257d7d67eea53bc381f90a2323842da1c8dea29354f8faba04e40cce22592e99ec9cc73f4565347f6ecd9c339dfb871e35cd777fd5066f83f51858a672c4ffdf297bfacaaaa5ab66c993a6edbf6638f3d76edb5d7d2ab905db7732d558d8e8e7ee52b5ff17abddffce637c965e0aaa4fedbaccd323a3afacc33cf505245784f22a57ce38d3776fcf2e5378ef43ff0779fc992dc5659ee2494bc86f2ca8f8d8d151515599655555565180665e2a254cf8585858b172f668c0148d3e486c11289f8c8c8707e7e2133a51d4f780c0b99b4c1013450220321113d3eabaaa6bca8b8301c8a826c2908e45a576c04e4c00c4004100000080859767de92321f329323faa23fadf4c99eb579b376f3eff99593fba0eea5e53fdcc0f7ff8c3ae8b1b86e172ace8bf62e91b4c8a8b8b1f79e491f33c8e4b1d659e53525272cf3df764bdc20545731400801420c115e0ec3a9510669aa66ddb131313a3a3a395959552cacacacaa1a1a1b1b1b16030c8182b2b2b310c63e1c285dddddde3e3e37575758140a0bebebeaded18220f0683ebd6ad3fb0ff8094827364c89021224826054a00ced0f2fb73cb822565e565566e2e985e304c6000e0d082e8a515e3f7bf28fa5488cf9e6d469116f1b6cfe7a30098e46f0ca3aaaa4aed8ca0b0f7dcdcdc8a8a8adcdc1cce99699a959595f3e6cda7f098d292b2cacd15a6c1a4040426410a262538034363f168824990cc010040968c7f257e22ba920c00defd0b3e2fc9ef48a494a4be207d1d624e60296c01a86d1849c7a98acb63a97436ba287f29d96a8c31864c220043868c4948e65f023e3d351d9909a7de9d2149e7c9b48541018020f112b0decf525151a1dce9aae7e6cc8fa56cac582c46963be520d50d1ac6d8e4e4647e7ebea16d9ce79cbffaeaabd75d778365790867c88171268171a40cc72025306634373581745002484322204a090201019894800c40da800c24bb04acf7ad2830e96973612e1b0b34338b3c0ba6694e4e4e924f8f5e8001008ee39c3b772e1289d0d5676666c2e1b0699a52c2e4e4e4d8d818638c193c9e888f8e8d854221482a3849ffa20404940c05038920404ab005c4250a40904229c70b6c22ba24bf47514443415373aa420540b59243e1a31e8f271a8dcad416d64422110e876b6b6b6ddb1e1f1fcfcbcb3b73e68cdfef9b9818a378e89e9e1ed33443a1d0c2850b0f1c389093e39336d4d5d44804218101a2049060331697381d8a0ff58f226049512090cbbc1e87230260cac613e42ed1661f9718ecfd2e73aa422542884824e2380ee536a69757d36b55962c59e2f7fbe7cf9f9f9b9bdbd9d9b96edd1a9fcf67599eb367bb56ad5ae538cedebd7b5b5a5a4e1c6fafada9038915c13260281184008e5248d13b16fb7f77bcb1fd97afa1344c01cc8e6cbb7ed34d1fd9585992e3350c04063209c5d41e8af305255f92f78f64cfe8a70a94153e3737b7a0a0803c6f535353656565f9f9f9fdfdfd908c464d0048cb326983bc94c98052994a6e595559bda5b575727cc2118e4410888c4b9076cc16cfbf7cf0d19fbcbc6cd1bc3fbd6bab81e2ec89aef1c1bec9a1611e376b6b2a1930092ce5c742f5de625a0bbb24ef67b940e8a0949256940180de9d422ff01d1919c9cbcb334d63e9d225dddd5da15068f9f265274f768c8d8dd7d737cc9b378fa2d21a1b1b19e3ebd7addbfff6db6313e33575b52091494481b62da289442896b0051f1e89bff1f699f1e9e81557acfa8b3ffd687e8e39d83b383315932801e54f7ffab3eddb774809afbcf2eaa38f3e7acf3df71067fd67a86bae9f4a09cf3fbf93cc41fda0ebfcac3fcf3ced8f5dc85c26713ff9f9542191566a232140aa2f83c1602010c8cdf5218261f0c58b17f9fd7ebfdf5f59594df94f5b5a5a1863a6693635352142694959696b29720920102407008484904cda1fdab2bcfbdcf89bfb4ffd7fdb5f791ca1d8c73f755bebd5eb5b6c470c0f8fe4063c4383832fed7a8996f37432ddb76f5f381c5eb162452814f27abd8e634b09a66986c3e1aaaa2a29211209efdbb7cfb2ac0d1b361c3972646c6caca5a5a5b4b4f4d4a9537d7d7d0d0d0dd3d3d38b172f8ac5e2ddddddd168746c6c0c00afb8e2f2402080c8ce9e3ddbdddd5d5b5b5b5f5f0f80005208387efcf8c8c8705353536eaeff9d770ee6e6e6ae5ab5fa9d770e4e4d4d2d5ebcf8e8d1a38b162d2a2d2d515b20ff58fd6f34ae51fd0b905c7c0390785e3f1664c42babf02ce5c47279b054c00cd712d132c610b9448e684b900828d1b1413044db8ecb44bcb220ffef3e7fe3d973fd5dc3c3cfbfdef3e24b07fe63c7af9beaab867a7a0af3f238f2679e7deec61b3f12894476ed7aa1acac0c4000889ffdeca7434343b9b9fe5dbb5eacadada9acaca278acd2d292d3a7cf7ce6337f09000f3ef8606d6d4d4e4e4e341a79fbedb78b8b8b9e7df6998f7decf6175e78b1b2b2a2a8a8f01bdff8c6f6eddbc7c747ffd7ff7ab0b7b78fa2a0f6ef7ffbe4c913f3e6358c8c0c9f3e7deae597777fe2139f983f7f9e9472efdebd7bf6ec292b2bada8087efffbdf6d6a6a0a87c367cf9ef9c10f1ef9f8c7ef78e699a7972e5df2ecb3cffec33ffc5f9c73486e7411296c5173672dff419c40e5d41227b0d451965c6ea3a006092cc55c1730def5b56bd7711d523c3d4f9a5a11a39013061280a3e40860086e024a01521a3311e3873f7aeeecb9f0b5d72cc8c9f395151a868857052bc6468763b168695949241a7d6dcfaf0bf20b62f1b8e3d837df7c33ed063b78f0d09d77ded9d2d272cb2db7d4d6d6d9b6f3d453db53f15848a12e4288b3673be7cd9bd7d171ea95575eadaeae0680fefec1c2c2a2bbefbe474a89c8a40429514a340cf3aebbee06809b6fbe39180c0e0e0e3dfbec73030303870e1dbaf6da0fcd9b371f919d3ddb595353fbb18f7d0c008e1e3d7efffd0f1c3b76ecb1c71ef3f97c77dffdc96ddbb63df8e0431ffbd8c71c4772ce523da19a4e6fc3ace53f9413644a03a2049e429c64b49f0a0053ef84ce1e8fa5f0948446ba0f09b3654156a1c90a5b2960210310296053da1b44302d049ea8ad2f6deb38f4af3ffa85e1f5d82271f5fa866b2e5f32d07decb2a52d798585539313d353d37ff5d9cf01c2dffffddfc7e3092911800583e5dddde71c47949494dc78e3b6af7ffdeb0f3cf000227ef39bfff8c003ff0300a5843befbcb3b3b3f3873ffcd1cd37df7cc71d1f5fbe7cf9f3cf3f9f9beb8f46636d6d4783c1b260b0bcadedd8e8e808210c1153290f717070d0e3f17efef39f7fe4911f22e2534f6dafaaaa2c2828e8e9e96d6b3b5a5959595c5c72f4e8d1dededeb2b2e0b163c7359812d3d3ecf58f729913013840b213096812a4ca642452bbc766e3b1745101a2a825f53629155f6ab3bcd7ebcdc9f17a3c1e5a49f4782ccbf2a8f7bd1ada2b5f111198838828b1adede8e2a54b2552fa53c763e1aa150b37adbbecf20d2bd65e36bfaa08477bdb9b1aaa962d5beecbf5338615e5e59b5b375757571517152f6a59585e5eded0d870d79ffcc9ebaffffa68dbd1cf7dee73e5e54100d8b86163515111805cb56a259937cf3efb6c5767d7bdf77e69ddfab5a74f9f3eb0ffc075d75db766cdaa5028f4c61bafe70502b7defad1a79e7a6aa0bfffca2bb72c5eb2b879c10244c8cdf5ad58be7cd3c68d1e8f67cf9e3df9f9f99b366da204716b56af1e1818787bdfde9292e2ebaefbf0d33b9e7684f3e9bff80b5f8eafb9b9d9e7f32d6c5ee0cbf12d58d0c418a64c2ca9992090bdfc0771029553f6131d475a6e43c140d0603a77aef7c4a9aeeec1a9adad6b92f1586e58a6184b693a0adf0ba4242f2f2f2f2f505090eff7fbc913e1f7fb737272294d034150119864201118302ef1899f3cfed13b6e73242072d3d1d229000020004944415414221e8b0c0d0f0d8e8c4c4ecff4f50d14e5172c6a6e2a2f2fcff1e548e0f424980cc7785fb6f87f911360165894c48ff6dc8394c024f1b494f2adb7f63efdcb5ffdea9d73fff7373e733e1b4ba9339dc0d4117dd5597d7459f7880888a95929720026012570644202209a5e5f79756da0b8241a892e59b4c4e7f35b1eaf69a0001032692ba6228f4026a3b220f978a9827ef0d209bf8d13a84c050180808c9c8bb480228121204894c89260bc08cf3ba48c2a1d5b991343caf4ad5035fb5b09966492094001c01c860ef0036d67a7224ed2880700402e81239372d2014959be84b2f604a4329ebc0fa74bff454ea0b294e45700c950825421acc0a4b372719d9835ede77875afc2906b8b331dd70fb20c416d6f741261487c0380e0208b21bc76b87378d2140e9aa6e3f77b2c14d158424800e0339184835cd0fd056788129de48fdf9d5c7c83ba7e75f1f7ca7a85b9cebc98cb62ea4c75b278f70ffe5b15044040074082e4122522a0742c88d43754da28043ae4ca72ef2b04009d995c204b2f2b84198c71c6d21268abc86e640840d93d90a6a40c001977c00878f9ca15f387c6675e79edede18969c9a48946635515e3122dd3e10cd00409000251203229194864520a260502022954701803290c52ba8c4263190a81201de4e4be6712053204218540e002009904104c32092810243a28912148e17069388092018264824b90923928414ac611413a120508608c3b92920a0bb54a2e9009449436938c014729040a4826cf0185120aec905232e0424a0406924904c61c47c419b35072900ea00d696e8bdfbf486014a222194a892825931229e51fa0b25ce65cd27141aabfbfbfabababafaf4fa5e16b6b3bdadedece184364fbf71ff8d5af7e451b788e1c39c239a7b5200010427cfffbdfff7f1efed778dc0600100e023040af215ad72e181e3cf7adeffce06c67ef156be66d5959579213c368ef8a0565109f0461834824ed7ee08e7000138cc519cea08c0330292582942805d892092925a014200448943647412e5994292b4f4a2105a3cba12905a5491212002432c1b810281c00c620ce20215148708009211d09201090315b0ac18444901c1392494489829cd052300493096042a0044426010069c432291093662f0d778152700652da063206923107514848300608524a313b0b4b4af2317ebfff4974547d18243da21239033092c0c22cc0d2cd23fa28a5eceeeececbcb2b2929b12cabbbbb9b31168944f6eeddbb7ffffe582cc639dfb163c78e1d3b2626267a7a7a5e78e1053dd4ff7bdffbdeea35ab57ae5af9375ffb2a4a0064024080a808e615e59bfd034333e1786961deeac575375ebde2eb5fbcfdcfeeb87a418daf20c796099b03e3c22ece85921cd3401e2cf336d77baedc58cbc10640a43c475270400426106c9482012020c6376daa924c220303eca23c1341308816e619e412052118200710208474508221c02b13ad1bea39b2b262637173314a01202524184f3a6a04381466e10814604ac61d1092de7e251100418029b0d4679ac8a4a0d04510422272004348261000510283a4df4b204a296d860220c621caa460c0a4701873001c98ed2a17c8deef32e7660a4871d5f8f8b8d7eb2d2c2c2c2929a9a9a9a105e6bd7bf75e73cd35353535c78e1d23f577fdf5d753ea0efab98a6ef8dce73eb77ad5aa53ed27376dd8c8504a602001c1f158322fcfb361c5fc05c1e203078e7eea8bdffde4bd3fbcffdbdba742f16041cea2ea62331163124c887e7873cd073795594ed4675a053e2ccbcbe1c2e16073e670699be070611bc2611218482e6c04c964b424cfe4e030276ac0d4559bca11a31e086fdd5883e870b419861043a6741808c61ccee2880994a1d27c0344d46bca7c3f3764c2820417920b30a53045c210094b240c11371832615b3261a0638063c9b825639c45184638844af31dc30000018ec3c006663bcc16dc06e6481012194a06e8204ae9380c2463518030930e9336979209692093d2d13a4400084c5bf47dbf4bf65921a68bcb4e97520e0e0e1e3f7e3c1c0e4f4c4c5e7bed871171e3c68ddff9ce77eaebeb11717474f41bdff8462010f8e77ffe6721e577bff7dda58b966ed97285045ba2231138909a4cac5e52f3837ffefc6b7b0fb79feaded736f8ca1b27fa7a06eefbc29d931353066331e62c6c0e1e3ddece396b5e5036134980700c296a8bd88225a5cce43d7dd308100d870c0b6d96170dc74af2e481e3330c8c7c9f75dd96da98e3741cebf4a1bcb1b5e148db998aa29c1bb6d4769ce85dbf6ed1d8f8f4e464ecc0f1d186faa2f0f4cc999ed8d557af7871d73b0c732f5b5eb7f3c5c38b1aca1beb0a2231d976a47ff9a212afcf1c1c8d9e3a3dbc7c51d0f07bcf9c196a5950f5dc8bed8539ceda95f372f3bce1581ca43c7dac77416351efe8d0fcf979f3ab7dd3d3917d6d63a1044a6117f9e5f245415faef778fb407ec05753951f8f8963c706375fde120a4d0d0e450a4a0b86c742078e0c08f06032a496316120a440f63eb2b52e20692f42517ca39bea454545a150281c0e47a3d1d1d1d1eeeeee50282484686c6cd8b0613d25fd4144d334efbefbee471e7904114b4a4a1e7ef8e1871e7a0800fec7fdf737d6372c58b06074641c00011c09200167a6e36393b1279e7be3b9570fafdbb0e04f3f79edb69b3703e78cc9a19181b33ddd710064b17c1f7a0de6b1588e250dee08860e42d382f2c3c73a77be72a2a1b1c4346cceedea8aa2ba324faee1980c106d04190ac577bd74e2e0be93cb16d73952fee2e58ec1e1c8c858e897af1c8f0bd1d135f2cb578e0b74f20a723b7b4383638e444083d9c261023843e188a52de5c37d23870f9e6da8cdaf28cd45908b9a839525fec84cf8a557da7bba863d06d20aa8c52507b9ebe5a3bb5f3eb2f2b27a64685809c3140cc4c2c6b2c2029f7018075e5d11181e9979f9e5f6fedef1f9f34a5edc7de4d8b1bee605f90927fed2cb076b6b8a76efeea8aa2820ff8a1414512200a4445ba2936172bdafe5c2ef84b62caba9a9e9dcb9738cb1c2c2c2f5ebd71b86b169d3a6e5cb971716165290d6d6ad5b29bbcbd6ad5bd7ac594330a5fdd34d4d4d7bf7eedbb777ffbcc6fabb3e79a7f2b9f50d4e9d3937da3f36f3c48e1d0f3fec14160546a667ea8225b75f7f79e7d99351614866e679a0b9b1f25ca757326c6c287aedcd76e4a64009f0ffb7f7ede15155d7a36bed7326f3ca242104f2180824e1150482bc0d6f44fa7105ca43a5b456fc4a8202f5b67e5fadd8a2adf5d3aff581a5404521d7801705a480a95cf50718a40a28af8072110821ef403299bc27999973f6ba7fec73ce9ccc24407f6dbddab2982f9cc7defbecb3f73a6bafbd9e5c2600ae30e09eebde0169c995353ea606937a455f2ef77292190455c420b3000408a520481c994240488841ce5540055980402522bbcda20455d6ee27e0804c26050839caefbd5fd42fd9f93fee1d79e142c5e9a28ba5150dfdd3fb1200b2280ba92838741e409d0352211ab80f000021a9b7c369a783878f678f1e4ac4dd4976b5dd0708049c1347440221a153051fc78971000249282d193040899340264d42a98b1ebf1bd06d4e6843107ae1c205c31e4655d50f3ffc50686cbefaeaaba8288bc562397ffe822449c78e1d13cbe5e5cb97df7efb6d6353a9f39dacaabaf2c8d1c35923ef94008013675127ce150f48edfd9b5facf436f890a9401d766b5479c9a55aaf0fac891616852a3f5fec3d59544bc47d0ab4fb9137f36b56ffb9d39563c60ccab45b4e9dbe565b4bfdd2ac178a1b18b4f748ec51e9092a602554aaeb7d0186ed60ad69502f7e5171cff4c1e7cf579d395b3d6b6ad695e2ca81e9c9b1713135558d5e8fcfed8ef3234f488b292bf72aaa347182fbd3cf2b55b08dbfab9fcb2e1dfaaca4c1db72e71dee2903075d2eb95e55e5bd63887bfa8c91978b6b3f3d5979f7dd2324e0b59e564b3b28646548d7eb3b3a02eab5ea769bd5316dfa645b942550521517c7da39bf52d238fc8ea4a93312bfbe78fdf3d355d36664b5fb82274f578e1a6955d176bdc1af22abf5b613325de980a8e5aa6100d4495bf7ad874eba426337279902f3092da108b1e272b962636385a5b2cbe58c898971b95c3131710e87c3e9748ad8eea22ee86e1b20364b9c010230be73c75fbebff8813776fdadac51e6416ef1b7f6b0c1a041c9310ea9f8d2c58a6a4f077372d623cad61365e4a81232028b36a614640c88889304c80855e0321222538090319543901310da1038e3c49814042e01930838282884469cfa244725a6c49d2caa619c11c82421417b66460c27eb952bd7664c4e3b76d2d3e25310397140b400e7c848416488c45504402671ce8008192754191071a6822c2149c48144386a154105e02a49c0800171625a945e9009383215891397004828bf8018810a0840320092a10c13bc1572cd7df7ff2b7004460840848424211100c9e85ff54056f5e52f0b3e3c7ca4a8f285a757de5ca52390a3a4a4c462b1c4c7c78f1e3d5a446c3f71e2547272a2881d75f4e851229a376f5e5d5d5d4d4dcdd8b1630d1c25a23fbff66740f6939c1c9bc5cab5bcc3845c952c32c7182fe77ffbb2c20e4109a5a03d8545d964e650515298c248884083888c83ca00402194101927e012070e2ac89c8003975402420ba205891831069c7305191057901821a90c114002acbae6afaabd46c448b21257382984f2a5cbad1c5a012d87ff5619240460848ccb5c520911388870a6b2ccacc003400a0340267312ab1a00a816a6aa80010446c84005520911d12a71524851183221d14540548908540094900171890123509029401202720832143828c444322111a8ecdbb12b6484421dc7743b5204356c9d0e8f9a0c9d6d66105155d5e2e2e2be7dfb0a678ae2e2e2b163c7b6b6b61e3f7ebc77efde23478e8a8b637bf7ee45c4499326d5d4d41c3a7468ecd8b146831b376e9c38f12e007ceac9d5afbefa2a310900927a58250c7021e26116801e327120e20c099013202a5c130d09e1070fe93c8134e52181b80ec22b517cdd141466429a151900222011681a7995116a0b0d0251401403000618f2320310c274224250751d3e0128080a8016e8105021129a0512da1d8e4655450c2ba00ac401c54aa6a2781b63ab445cc714ae795a86dcbe55938e4ed50ff83f1b49fe7e4021b42342105f2bf1a005558b042a20d77bdf058f6566b0841ccbe170242626daedf6989898d8d858443c76ecd8dcb973ebeaeace9d3b979c9c8c88f3e6cddbb3674f7676b6b92900f8e94f7f8a886f6d7b6bcae4c908403c2801ccffde782200049500f0661e1db7e15b06a4ff157a69094188e04b4865ba64243cfb5718185a6700d0fce51139e742fededcdc5c5f5f3f7bf66c00983c79f22bafbcd2af5f3f22f2783c6bd6ac713a9d7ffce31f0160dd9fd68fcc1a3165ca1400ce202891ca8833c63efdf453afb7e1dfd3d0f2df160ca462042884e83367ccb0daed00c48898ae88ea44b1bac4ad9e3d7b5655558930846d6d6d353535696969443464c810a7d3b96ddb3683bcfde4273ff9d5af7e25a2e66ddebc59b4f6dbdffe76ccb8b16919e91e8f2721215e6212220021114dca9e04c20c430b30f3cd5b83dc2e708b05a00bb51221001a26eb844828712609a9c8cd25ef369b6dd8b061c5c5c582799f366d9a2449d3a74f1f3d7ab4cbe51281ed67cf9e2d9cbd66ce9c3966cc1866ca8e3464c89053274e9c3a71223d3dfda1879672600012e869e208808594f766b4c68883db05be55058c33122c0d01aa2862bc0018886596bc8709488b8a8a0cd1434747c7eeddbb45728093274f0a0bf73367ce489274f8f061215ff8faebafb76fdf6e3445244431505959f9c92747c68e1bc785c42fa4fa42c3994807d2bf0f24e2064113b748b768242de399c1101bbe0c641c849aed2a8553672063abd04d81db604c8b382141b584050d10325099bebdb8915fa180d1a3478bbcbd4ea733363656975d697f9d4ea7d3a999ba8bdc71268f42d47544463f60d7ae5d4c3f266da78ac23d2d4470090980218aed5f881c8bfd88f08d44cdaf0699e97551339c15ad09ac230c35ad996aa3d6a099d083d103869c13631856e05bbb4a7dd30ba1f1958b2911234a44008c64469a6f731766336630026a996f8559b547960ffbe2755f080010ba2f0462400c892169e63bfac26818c3916e4e05efef7fff4f1b365cba741140f81869b29d53a74e5dbb5e4344fbdfdf4f009cb4a6852d0001e79a10426b568c2032e05cd8d36b17c5737534178650c029bc4097c7ff210574e2409d7ea8cf2e2220d32c3175abf79bb8d8333d6f582432859ddea01da339b1cc9040351d83402340061069d9eb40519477de79273ada3565f2c47dfbf6cd9b37d7e9747a3c1e22183a34f3d0a143bd7af59a3163bacd16c510ae969679bdded4d4be0e87e3e2c58b44949898e476bb3d9ebaf2f2f21e3de2d3d2d2040269125a0c7d840000484fad7eaab6b6169175ba7e1bba841041070040948878e9d592d401c3c06c9a6cb044069618b812d2cc74f69530d0ce2869c6b0cea8c60dc648ec520db2440002e1c37b4d04800d0d8d478e7cba79f31b4494953572e1c2452929296e774a6c6cdc81030725493a7ffe7cfffe691b37be161f9ff0d1471fc5c6c6ecdbf7dee4c993376efcf3ac5933ebebbdf3e6cddbbd7b777272d2800103d3d2d245afc44a173956a5a5e5f9f9ffcb6a1579c86f735add00e9ff61680a853a73edab6b4f7d794978b486142f00201611d01690505206137dd2161ac6c4baaa02081b48d5f86b9431fd746a07228a9ff143ec5a8865d05bed3d0c460b11962e5dba72e58acf3f3f4ec4172c58307dfa34225e5c7cb97fff7e2b56aca8aff7f87c6d13268c5bb16285cd66bd76ada6a2a29c73ee743a44533acb1ff1488d981a4fef1446d09c75d6b868f60e378ecd058c53a380f1b7cbebe6a6c2ca845dbcc115d155e356d869976f14f9d0c83e84fa86401a7ba10d979856413690182342baa1cd7b57079d089b2060000c51fb81196d42bf6ea1bb7ba2fdd8d8d83163c61c3870a0b4b474ddba75bffef5af01a0b2b2b2acac2c2e2e4e24c5a8abab0300a7d3e9f3f9cacbcbc5ee81f4b8d0d1d1d1cf3efb6c4a4aca8e1d3b0c16b03b30eefafd7e61e07f83c2e65acdcdcd656565a5a5a5adadad61b71051f4d078bacfe70b2b16080444758fc7632e69ee5597e4d39875f1089fcff7fbdfffde68c158581a1b1bcbcacacacaca2a2a2a8c8ae6d566dbb66d57ae5c11415f84ed9d2873f6ecd9bd7bf78ae39a9a9ad75e7bcde89b887a4ca61db4b81ef0fb8973b8811c0b4c4b1be9d40bb193bb8e69ebd71d3e75de78dd1aa01e2dc262b12c5fbe7cc78e1dc78e1d5bb060c1f0e1c3df7cf3cdddbb77bb5cae175f7c312121213f3fff8b2fbe58b264c9bdf7debb77efdead5bb73ef8e083292929f1f1f14424f2a06cdbb64d96e50d1b3698336252573205e3ad3d1ecfb66ddb0e1e3cf8c9279f60e7549ac680182db4b4b4ac5dbb560cc5a2458b323333c914ee9c880a0b0b1f78e001e329858585353535cb962d33aebcf9e69bd7af5f07801123467cfffbdf370f823810b3d8256e0983de471f7df42f7ff98ba228c2523cecfb59bf7e7d4d4d4d7272b2d56afde52f7f69bc82f12225252522cd16111517175bad56f1168d8d8d151515e24d3b3a3a44ba2163eac184f4a41ba3b7b4b4b4b55900f84d0cfd22af44ecf8b0cb2a9d81ba39eea6b4a9bb002002bc0000e73c333373f1e2c5090909e2cac30f3f6cbcd2fcf9f38df4606eb79b8884e2f2e9a79f16850d337c4378dbe57301c0ed763ff3cc3367ce9c0180e79f7ffeead5abd3a64d8b8e8e962469ce9c39ab57af7ee289270a0b0b3ffcf0c32143862c5ab4a8bdbd7dc68c1949494943870eddb66ddb279f7c3260c000ce794c4c8cdbed3e70e0404747c7debd7b7bf6ec999d9dddbb77efad5bb77a3c9e279f7c1200d6af5f3f7cf8f0471e79443c7dc58a151b366c906579d9b265fdfbf78f8f8f4f4949d9bd7bf75d77dd3575ead4a3478f7ef1c5172929298f3cf2c892254b060d1a141717f7e8a38fd6d7d7e7e6e62e5fbe1c11972f5fbe69d32644ccc9c9d9b2658b78afe1c387676464c8b25c5d5dfdfaebaf5755558d1b372e3333b3a0a020313111117ff7bbdff5ecd973e6cc998cb1989898e3c78f7ff6d967d5d5d5b366cdfaeb5fff5a5050d0dadaea76bb3ffbecb3fcfc7c227aecb1c7f2f3f31b1b1b25495ab264c9dd77df2d26a2de5b1fc03825a8dcd25268305bdd95819be35668fa6e05b7d024cf342e32c656ad5ad5b3674f30510eb34750181d32568ab06fb4cbae76b9f30804022258e6b3cf3e3b6ad4a8c3870f9f3871a2478f1e76bb3d180c22e2ce9d3bebeaea7273739b9b9b0f1e3c78ecd8b1bd7bf7e6e5e5ad5ebdbaa9a9c9e5722d5cb8b0bebebeadad6dd5aa557979791f7df491aaaa4b972e5dbd7ab5e8704b4b8bcbe53268527d7dbde8b6d7eb152dcc9f3fdfe3f1646767f7efdfffe5975f26a253a74e151616262424e4e5e53dfcf0c36fbdf5567c7cfc962d5b060f1e0c000f3ffcf02bafbcb269d3a6c58b171bafd3d2d2d2dcdcdcd4d474f0e0c13befbc332f2feff8f1e3f5f5f51e8f67c58a1500f09bdffce68d37ded8b16387b0412f2828d8bc79b3206ff9f9f95bb66c118bec73cf3d2706f0c5175f6c686858b76e5d5e5edec68d1bc58338e7aa1224ae12a97218fb8688aaaa023023d89a6a0245514414d0402020a2dceaee152a916a0499d179af4ef45c900a3182b708066e1984d7c01e23837c6461f3296adb401e56d28c88dddd0580575f7d75d6ac59e3c78f5fb060416a6aea8811230e1d3a3475ead473e7ce5555556dd9b2e585175e0080f4f4f48c8c8c77de79472c1c4653d9d9d991dc92992346c43163c69c387142242d3317161d98387122223a1c8e51a346b5b4b44c9830212f2fefead5abededed7bf6ec3173d6c607939d9dbd7ffffea6a6a6a54b9782cea4cf9a356be4c89188b875eb56f383468e1c69e48136862b72548d6e3b1c0e4105f7efdfffeebbef86f5161109486cf265225214c598789d0084124f04834149920281802ccb1d1db291250011459a42550d0682d640d06a58304b922e92d02c8c346e9a73ae07a3ba113e85112a339f073acf61701291236b1e2633fe61679636acbaf9298f3ffe787373f3934f3ed9bf7ffff5ebd76fdebcd9eff703c0d2a54b9f78e289bbeebacbe7f39d397366d9b265b5b5b553a64cc9c9c941c4214386e4e6e6daedf665cb960d1c38b04f9f3e369b0d11070e1c48446bd7aeddb163c7e2c58befbefbeebcbcbc975e7a49a4debce79e7bce9e3d2b58ae091326bcf4d24b2b57aee49c272626f6eddbd762b170ce33323288c8e974ce9933272727272d2d6de5ca951919190060b7dbdd6ef7fcf9f37373731f7df4d1b4b43422cac8c8484848b0dbeda033060e8743bcdddcb973376ddaf4fefbef7fef7bdf73bbdd1d1d1d00909292f2d24b2fd9edf6152b56040281e8e8e8871e7a282727a7adad6dfefcf98f3ffe786e6e6e3018cccacacacdcdcdcdcd0580356bd69c3c7952f8248bee69bc1732cdece1c081033ffbd9cff429214962b22c33a6852eb25aadc22ed9e572391c8e9818116d345a3f8db1dbed0e873dca1a658db24ab2f64f629ae84b93807234a48e1f7f5cf8e0830fde08ad742c89c4b0afbffe5a4c64e4adeeb03392b61984cd8c64e2fa0f7ff8c337df7c53e49e8c44f1307208a694a4e6a536f214005e7bed35a1a1efb293c681c12f9a49b5b9d9b0ac74d0f97b30ae2f5ab468cf9e3d069930f394660ad45d676ed049a3b5b06e8b115ebb76edffdeb1479113fef4f2d3b211149931266c23655996248bc562b15aad22cc9add6e77381c029f84ad9fcbe58a8e8e8e8d8d75381c22f09acd6613190e4596b9ce443544246459ee8ecb31c03cf744b468d1229bcdb67dfbf68a8a8ae2e2628158911c98310d0f3cf0c0ae5dbbc495bababa7efdfaeddbb76fd6ac594b972eddb46993f88e01a0b5b575fdfaf525252500f0f39fff7cd8b061e646ba1ce848c62eaccf605aefcc2d2c5fbe3cac4a1842845156f3e899572233d1555555f84189f2e6aeeedcb9d33cc89103158634dd610ce8d86c7e44e407663e365e53362a43673c30b3026123686a57e8909888e409a0fd153f6380ba9c9e1b83c1f77cf0c107b367cf0e068385858588b87dfbf653a74e4d9b366de1c285efbdf7dea14387eebcf3ce1ffff8c7ebd6ad7be699674e9c38515d5d7df9f2e59c9c9ce79e7b2e2929898866ce9c595050306bd62c45513a3a3af2f3f34f9d3a357dfaf43163c6b4b5b5ad59b3c6e572c5c7c7efdfbfbfb4b474d5aa555eafd7eff7272626d6d6d61a71e75a5b5b0525131fe14de96518449234f32475771a5638b21d7381ee1e018000061fd249e6645c345717b81c2aa6cb8bccb366467173ddd2d252b4448be05932088b70ad84a0346128c9056f0e2064b5c0398858a0ba5037d4d7ee68a971702b58651e9a9a9a1ab7dbedf3f9ae5dbb969898f8a31ffd68c58a156bd6ac3970e0405151515e5edee6cd9b0b0b0bcf9f3f0f005eaf5784da160ca680949494499326eddab58b888e1c3982885bb66c79eaa9a7468f1e3d67ce9cb7df7e5b55d5f9f3e76fdfbefde8d1a300b072e5cacccccc1ffce007f7df7fbfdbed4e4f4f4f4f4fdfb06183f0971c376e5cd80af52d03b13732cb11d174fde6a0055104d4229d2021101247ed66b7d34744252525e72e5c2df31031490edbff7749a2ccc7669ceb92a4fde360105eafd7bb6eddbaacac2c222a2a2a7afef9e76fb08c0ad7d9c8ce23e27df7ddf78b5ffca2a6a6266c95c9cecececece7efdf5d7c5826854b9fffefb4502ec3e7dfa6465658d1831e29d77de193c7830636ce2c489fff4f7fd57823120b73e4dc27e0449e8fb88cc32eeee5c1bc57c454747d735051a822d9224756bdd60a240da1ac73988dd2211e75cd123a5706e265cdd10adbf170c323b63c60c6138bf7cf9728bc5f2eebbef9e3e7d7ad0a04163c78ebd7cf9f2b265cb525353efbdf7de8a8a8ae5cb97d7d6d6ce9f3fffbefbee134b617272b22449369b4d96e5a953a76eddba352b2baba8a828272767f0e0c19224e5e4e410516a6aeadcb9732b2b2b737373870f1fee7038186356ab55688df2f3f3131212eebffffe9933676edebcb9a0a0e0b1c71efbbb48ef770d349a2748166a740b40c728ec1e47af5fbf1e171787e56d0018725845dd5a4144c0926559d8ee399d4eb12b14dc7a4c8ccbe58a8e11d16d5d2e87c3e174ba6c369b286c481c5087b067efdcb9d310dc75075d720cd059914226e19651318c238ee437bbdc43dd8061fac31ffe306ddab4f1e3c78775a94bc1fdbf07700825010881d8dd035084059f79e88e1f3f5ef0e1279f9dad7ce1e91b06b715d50c7523e9292a48c250ca8f000008be494441545743eab7341be3aea6873a53e35bfaca0db44093f4b24b8631b2b7dde156770f8208d434364744b46cd932210132b389b7f20adf1ab8d531374a0368c948c9545fa05a97af1e39202a11279055550d0402c69430c6844454446a10023a4551144511c9bd3a3ada7dbeb6b6b636e1566f881bac56ab39eb8999950113b10906835d4e7f77dd356b6c8c5373f91bd48ddcb4475e8f6cc1780422f6ead5ab8bb1fc8e009120319c08c3446ee6329dbf406421ba242a000724242462da72d829e1adc13285c60d1800ca8c016320f68388da12662401b0e820a45942a025a2ba0bb196c02dabd56ab7db2c51b22c5b645912d99fc38ce9c4bbf9fdbe73e78a0c42720366fc36fcb7802102e791fb18d4250944d449eed069874b88c480110795a130d766044c84eb24ae6aa1f3cced221a12b5eaea4a00ce810048067dca89884815316ac9945a5c80205a611a430d143f93400a32d29647993126b43ac67700a009c1274c18af280a11288ae26df05ebd5adae06de45cf9970ff87f061031c6508f5f6a88a698111a1451e5c4413f2122a6fb1000a0b659232e33225209197186202348042a31508187716044c424465c3311b6d99d92247340b97321ae13c14e60ce626fb059c681518a74e34ce36bd1c9928aa849cb12937aeb2c1a45bba22d164b6b4b1bef1416f136fc03a0e792100c8cdd6e5755113347d2c493a86a01304c127c2350231059488d0e2ace802a01b55898cf6209a00c2421439fe28fb25b41e914ff238c8bbdde10888eaed7c40d06031429c90c235d82629911ce8c5ea0c9e23991c602eb8c1172ae619ba11f4004972bda6e4f53d5ef5268cd6f37106941a611885a5b9a7b2526b6b707546e292dad68686eb6da6d8949f13d62ec320a0e0a1131100830c66c361b0582f6805f2eb95a76e94a7d756330a040ac2335a36fd2a09460efde41496a686f89eb151fec08188f03b1188504ece8aa69721e2f0f976319a867265410815e5de153e8962431339aeab44a7b84896d078bc5722baac3db70cbc009552019491281c99d0e3ba0c5afd89ada7170567647c05f57578592ea4ee8213164c0112910253394ec366b94d21238f795e7bdf75b59fca7352d4194fd4d8d291f7f3e6a4446d69279b103d315e688714477487eed697aa62330512cbb3d48921559f7025201664c12e4ca38361f18881556b7cbddbe81490613761bb1fe49c0806440a6c56d6212932c2a041b9a1a9151479bafe44a795b4039ff655952425c8c8d8d1b31c0e6107ee872545055be38d5b27b5ff09af78bebd5be3bc68e9c371d255672eee2d9f28bf1ffa760f08f7ec86263190263cce45c0c00c0759b28c6989e0434c2e6ddc024d4edf222f92db533446058a8a92e31c6bc25011399bc0dff2020218a58a62286bc08d6a6404363abaaa0c32a8f199579adaef1444bdb679f9fb3045bedb2326a4c2690c4408d6a6b2fbef0a5fb9e7bea8aaf59f77d30b4b97268bcdd75c7c029f764dbebaa6b776cae3e5de49a3819486c218d29e3a4ed2b795353a3cfe7e3142d6e7461fe11761a6647ca3b835100420b62275cbcf970dc2657ff34200684c839ea11140855159b5b54901ce5959588c192fffb755abf64004e14ec999c00280127e25cf175343434cbc387c5ce99ddd6d7dd5251f1c1136b5e5ef5fcf3bfcf2f6d064bbfcc6b25c5b212943af9ce694a0822f27aebcbcbcb62636200b40034370f1519c65a855129f3a9991513756f23cd370c048af02217d2050624a1446069f7073d0db51919493f587ccfc90b5513278e9395a6d89ed12a06992ca1a230408b6ce52a4b1d3dea7fee7afbcadefd35fbf73baed67c5edd987fe9d263e3fb5a2c519ca11ee10542b60b4435d5d55eaf774046060018c2cb2e623798f9711e01918ba019441be64dc037309ab741002170469c8918168c1100a95116723aa5f6405b47000bff56d4d4ee2f29bd3865ca6849a696462f0057b90a68c168bb332eda77faf47fbdf7717ec1c7f6a91307fdece769bd5d77fa6b333de55459d627f30e5592817131bf2852f412555454343535a5a7a75757573735351933de058f8518c22ac1947547abc288964eb13811a31b2af56ec3bf08081850287712223039909a1a535153e9f7fb3b7cb8b7e070f65dc313a2a35c4e5bfd754fbfe424e48810e5b75b078c1d7be1ddbd2df12def9faec8dbf65f292ea997d737d1ce47589a2db18eb83b86d65a983594768510b1a4a424180ca6a5a5151717c7c5c5a5a4a49454b7889e749b6c3cf222e972ac3008e3ee5535a4c4657a96b97fe560de8610102282d8b59108cd03a4c6465bc68f1a70fa54f195cbd74b3dc1da8a9aa183fb5dbc7876c6cc6cd282f70415d916356c6806e37cef81df0e8e76f4744b00962136b5b6cc969a92b470617b8f9e14f023000222c340c07fe54ab1c3e1e8d5bbf7e5e2e2a4c44444acacac04162b7a1249b1c0a0585dae86aaaa98bdc122574633b5333698dff808ff87821e4301008890382082cc54b557ac6de2b8c1fd53e2af9696363735b6fbea264d1a9b9a9a42120b2a8acc3881d2618d8a1a3634ab478fbaafbeaebd7435d0d21e9b1ce79eb4c03164882fd61e90500d10a14ce01792d1a4a4949898e88e8e8e7ea9a9ae989896e666bbdd7ebd495f0a894815bc11111143e4c40911b9b1ad4402246400484c4249462649b24546262193001191ab8ac255550906ad369bd56a9524495839a088ef701bb1be4910fc35923f186c6a6c0a04fd0848a032647ddcce3eee4cd44358b5fb7c24d4831cacb2c4890801137ad8268e4f1f371638912cf9644b0393a1bd5d250a06785363a3a2061081736e91e5765f3b003026b5b6b44a4c220ea404190480b84c84c1a08a281111810ac2e1109121aa2a30462ae79c90137262807ece99c2254595dafda8a892df4ffe0059dbb8d3495156458e0a44455985e3a12c4b88c01803c4904debb72a39fbbf7b014f63fd7fa3050c9989aa0401320a23d4357600088575580b2064006d41944446d9b2f28a23478e00000072ad1280b65d4414e9709924fc349890adca127040c6648b0591812c11a22c5b880851222049621c50d6769e6816a8dd86ef3adcc0741011546480512306f5fd7fb0ce129839c4a7d20000000049454e44ae426082, 'image/png', 128, 0, '2006-10-16 00:00:00', '2006-10-16 00:00:00');
+INSERT INTO `previews` (`id`, `addon_id`, `filedata`, `filetype`, `thumbdata`, `thumbtype`, `caption`, `highlight`, `created`, `modified`) VALUES
+(4, 4021, 0x89504e470d0a1a0a0000000d49484452000000e700000038080200000089fe788d000000017352474200aece1ce90000000467414d410000b18f0bfc6105000000206348524d00007a26000080840000fa00000080e8000075300000ea6000003a98000017709cba513c0000055049444154785eed9dbf8a144110c64f2ed213c150d048937b13cd0c7c0a9f408cd6c04c4c7c0641d0c0487c0433152e107c06033351611d69288aaaea9aeabfd33d57c722bbb33dd5bdddbffeba7ae61bbc72fcf3fd64d3bf67cf5f3f7a787fd32678e50d7be0ddfb8f37aeffbe73fbd6f9f9dde5dfb3b3aba7a7a7a5f52dd46efb3a1c0e175f3ef96baf3db08cefcb174fdfbe7975f1f5c3cf1f9ffffefa56cedb497988c2084eed5e790dbfab1fb54f1edc5c5e228eca57167cc3e9384821b5cb5a03a31edee3234940e0652be944a5708b98b5dad6274e3f6a17fe62d4ea5f59c02511aa539b3d187c0264870a2766cf9fc27a873abd21b544ff002c515939d0fc741d5f1ca13ab5c00ae81c610817c0032c524b82041679e47084e022521b6b15504e560c635d43918a1bd38a5acc10bcc7bc124c958f8a42638e2b524b069b7f8c15e05aa86b2d4f3f6247c84cc040ebf90c044c9a57c3f2da3cafe5e9a68872208f53cb4f8fe5c43c42a1d62ad41251c4908919b098838a41b078e3024a4a60875e993cc6ba86e2b8b7d6027976ad3526069db5964026eab198861aa5d142492d6a2d750d55c6a98d5ed6b5e045b8b4a4a196b07a5e010055a756d1f54b416d58f49517165d3119306608501196e4f20c218623d9c76450abefbd70f68993574caad80652584942700360c510eb1a8ad41ebb31e3e5aa46c5aa50bbc998cda2769b740e54da2a436884a3316c21b56483d281242e9fdb623178ed4eaddb15e6eb01a776be311b5c083b34cfa9756ae7eb01a776be31eb20668357e1d43ab5f3f540136af54bad465f01b95c9064742cbc8630b8d278f39a508b7d05798cea9603fe2da9c5a9dd37d9cda92504c76c8aa2ad91140e685a8c8e4ead536bbcb40fc5fe3f819364efe2969a42a3e365a676ae7bb379b3ababd68aa644ec58207e5922c0f6995048ad6e7049ea68d1a998148114d6efa275b88d57d2f85ae70e41ad5d6b8d46c7ead46677b7d1bd95147fd5719b146dc6c2cda9e5bb31cb630bb10c612b6a63562c7c1cfc539803915ac5b4b5eaf9c22e332ee424f25eed0d4da88d5df922c6454818f856acd0e858a8b540068152c91c38be1c62ae917683ac3813f44ca685cc0f22cc4da84dddbe552fdf8e5ad1b78ae123688a79ad627e85504a422cce90d80410578041e0cb6e86532bdf1922107026300d3ab57c3b05472c5acb87d6a9756ae77b02c7a9756a13a80df96ef8237a195b88792e8b8360fe48645e1154010dd0f35ab1b5d98bf250273ab563794744ca87226684c638b543501b535631a9b5171e81b0166dd880da553f4db965acfc1a428bbef698b57a60446acb2d634e6d2d3ec68c333ab5799631a7764cda6ab56a266a45f38d78ef17a8bd76efb1bff6d40381fbe9a9152d634eed9e48c5bf653fd4724b8d53ebd4a6da0456fe5f86d56b08fa6ecc6219736a9ddaded4965bc69c5aa7b637b5a9f5f1f2d5a93d1e8f7be560aedfb5595e5b0ee56a84726a174ce16f19d72ad486804009f9984d0f696a769c294e746aa317c538a383538b67c214f06537d2a94da3164b6fe8747204c8e66fa03cc87628834b62e9e5f249441a8fbaf895d8b62a732f1bb82a273ab5da0d881891043b8e236191e3857925ec5a82f37445cf10a08a1d20bbfc76a7d674db2c152c0e255fbe891863ececd5895901176f1eb08ae66d15c4a91d885a02015ff4933204fdf4ad80ab52af535b995ab2765bb6747665756a03f44eadb61b5bcd6bf96e2c9b5a656327eed8c87c10f35a72701f49ad536b12da2a8b9a07a9d803aeb545e0922dd46ec4ac22612d4239b545d4b618128fb9da034ead533b5f0f38b5f38dd9aa14edbec0a5a0b6d6834a1e67a81ed8e0099c55c75679017fda7128c8aa37a605b5ff00aa7e93b7659ef0a90000000049454e44ae426082, 'image/png', 0x89504e470d0a1a0a0000000d49484452000000c800000096080200000014be504e0000000674524e530000000000006ea607910000200049444154789ced7d777455c5daf76f9293de3b2121844e48281710a40b0a888a4a91ae5ebc2ab240bd2a16f47a111be045051b4d44e45204ae4a55aa74952245aad25220055220090102ccf7c7cc33337b9f83ebaef7bdebfbdeef757e6b09c9397b3ff3cc537fcfeccd92f1abbf01e0e0608c01e01c8cc1090e0e30c63987bc0ae09c8331665c4e9f00cc971081cfe6ae6996d5342438480be71c600067ee5ba414cecdafc4c5f243792f131f7318d773ce19e052838333385791f2c47200c020c48a9d72cec1c0c0a49e0ca09fc96000e3c244502aa9cbe44fb48eb11ae9236f01bc6cabae626421d25f9a57ee1430acc319e4654a75a701b5cdc5676a2f9cf3f3c5a53b7efc21293124a371bd06f5d3636222fd3d1e46d728b8a5490584e7e5957e1cd235f21ad2d85041598a894822fb0b439185b8f4b0b4a912c2e5d7da7cce1d32a12793928cafe495c2c1daef869e422306300606c638948d186320cb294f9a51e55c0d52065da0f62617106b41eac498362e458ede1863c2c29c3126ec01916cae6519f99b31254da58a8c54613e5a43fe47b1c8e8036e18537fce984808aa185c1a5184bbe106c6f4656ea31889cd849e8c710a0bda075d2b13098c318f4a4b4625e2a7efbe0a098b68d6a93b198933ceab2a2bf67ebfba467afdba592d0d6332759bcc246e680a80e3c76f97deb87e1d40ad4699b51a6629a78a4413ced21f92ae6692718e5dbb7f4e4d4d49ae51a3b2b2f2c79dbbd2d3d2ae5cb99299d91860660d52a9e3b0110380c54bbea9aeae06909999d1bc7916b8cc7b33db44b88a2a22438833331839b079f3d63367f2012424c6f7b8a32b058c769e11d68642babaab82c599434121811bf14a6905704e5ac93ac4c0741d5275d159a7a97328cb302aacccdcb1f6a47754895b557a8b1519374a14379351d51f80c34fde44c239e7572f5fdefaf53f0db932f58bf24efdb26dbd0f0d94a29c71ca6f1d6c4049c199bd9bbe756a6b64ae585a7a537e6146066358b376c3a953a719c3850b17162e5a62dec9994842719b59d5a452a2834c9b315b7cb2e3879f0e1c38c854c030aa65fa0fa61564a2d4cac2bc7ec3a6e3c74f9a3b87f432a34a60140c28f37bd98cab2a2dab39a9ae528499cd471548ae7c45914ab16886a3486ac6c1559da47036db1f5741c36521832f48e1524911aa14b87229b927d5a000c003e0ec89636be67d02a0eb80e1e94d5ab4ea76f7812d6b4e1dfc79d3d2b91dee1dd4b0e5ad000b0e0b6fd2a6cb919d5bd4825515e58b26ff0d40f32e3d5b76bd8b5283d815d9b26daf7ed947f65faab8984ae54a3bc4616acec0986608068f31db3200a0a0b0b0a2a232333363c2a4f7b27372d3d2525f7ef1b9356b3784868676ecd0eed5d7de7ce3b5578e1cfd75dfbe0343063f00c619585050e0d0210300ccfc74ce8913a79a376bfaf2abe34b4acb329b347e72d408804f9bf1d9fe030701d4ad93fec298a7577fbb76c5aaef004c7cebb5e8a82861b1dd3fef6dd7b6cd6d5d3a2ab557acfa76d5b76b01bc33e1f5f2f2f2e52bbf1d39e22f60f8f0e31903faf7f9f093990f0e1df4d3cedd0f0d1b34fbb32f76edd91b121cfcdee4b7f7ee3b30f3d3cf013c35fa8926198d1cc552f88ae9aaa22b93723e931dc145e08c08621c9c711566aae71a3ee2141bb227f96e859ac6319d224e575352cba89645d15376ae60d3d2cf7b3f3e06c0a6257342c22323a2e30ab28fffbc7175efc7c76c5fbe28382cbc56c32cef55e7bd35a6ef937f03b07fcb9a833b3666b5ef06a3d42b16a7ee634ee6ea12c7344d51f454df396ae4636f4f7cb74e7aedb17f1bff8f496f6cddf6436969d98449ef75e870eb90c10fe4e4e4be3de9ddc48484a8a848c6b07bf7cf0cacacacecf8899300bcf9bac0a8918f5dbb7efdd0a1239f4cff34202020a566f25dbd7a949595bd33f9838ddf6f399d9d33f6c567013cfdec8b733f9b2e541bf1d8f049ff98f2cee4297171b1f33e9fb97ec3a6dcbc33e2b227fffafc2b63c71c39724c24ffa1c3472f55557dfbddda8a8a8a575f7e61eebc05d1d151635f7cd68ff99d3c75fa5f5f2d13777df0d1f4e79e79b266720d5343ae3d47cd51f12e5924b8c1caa4d91c91215caeaf74f66b5322756ddf36927e11a380d942754f912ddeec8b0c003c1131f1591d6eff7cfcd300ca4b8bdbdd3300408ddaf5fb3df50a07ae555fa9be7205c6e4a2f69d7fea377117803b1f1eeda24aa268bf3f7ad0e877e71adba70b64fc4365a4348b2a53ba878303b1b13117cbcbabaf5d2b2a3a97949828e49c2f2e7efd8d89818181003a766c273efccbe3a367cdf8b057ef7eafbef28269a08be5e577f5ee0f60e080be7dfadc5b5858f4c2cbe34a4b4aab2e5fbea35b978080c0ba75d36ba7d50a0b0b055079e9d2fc854b56ad5e0320203040e5666c74cca4b7c773f0a2a2f30f0d1fd1afcfbd8cb1da69a9002b2c2c529e20628384f8f8f7df9d008eb2b28b09f1f169b55219d89163c7d6aeff7eefbe034624390ab50c2a10d3e3aa2ac91f195355429129b803cde85234531a014a3c4999fc66248bf4d0d1485ee132bed478c115e163e0f0949d2fd8b5e69b31d3ff05c6e64f7cc990289903e9a9dab44825161a113566fa5710ccca50c59d3d4efb41d72a4666621c46b53772c728c1c8cacc3874e848eb567f32e7aa29ef4dca6ad2b8bcb2322fef4c4e4eded9fcfc5aa929c1c14159994df2ce9cad5fafae5a2f322262f58aa54a8b975e796df2c437929393b66efb61cbd6edde061d32a8ffa8918f31c676edfe19261f8777721b5947ae30ada17e55270b1ddab79df2ee4400bf1c3c1c131dad4e043485222be9c6a3249917c15d9ce406e5e9910840d91329d8645ebb74321672ee0d8e4e6a507fc52b6982a30a266ef4048786a7d46fbc63e56200c5f9b907b6ac0d8988acb850f2c3ca2f0144c4c445c527727ee387954b8af24e15669ff861c5978d5a77884b4e6ddaf1f61d2bbf1452eab76893989a4ea54817a4165deedcb9e6eb6bd5571bb468eb687fdcf48f22165a2f313913b7641c786af41377f5eebf72d962755bc70eed76eedab37fff2f57af5e8d8e8eea737fefd75e9f7067cf3b12e2e39f1c3de28db7de9935fd037845b958f68e6eb7ad5dbfd1e3ef3971f294bfbf5fcb96cd4f9e3c5d905f5879a912409df4b49c9cdc050b970028282cbaa5554b2161f79ebdc78efd06e0daf5ebddefe85aa74efa99b3f9f3172c06d0a3fbedd1515175eba6cf5fb804c0d9b3f9a6df5b34cf3af6ebf1f90b1607040474eedc21bd769ab8abe8dcb9d4949a2121c1d4fde150986a15d76c9918bf3a8862c6918db141dd12cc3f99e807ce015cdfe403e658ccb9b38baa231ebda02a1ddcffcd379f4f48a97d2e2f1b40cdba8d8243c3fd3d01b51b3713b232da764e4cad0d20efd7c361913149697501c4d74c0b8d884ccb6876f6c43171596c8d94b0c818504c9131587a9316674f1e8d8a4f6cdeb987f862effe133512933c1e0f152c753ec5e4f0696e9e0aadf83e2222bc51a30660080a08ac995ca373a70e0505855555971312e27bdfd38b83878684a4d74e0b0b0bf7f7f38b898dae5b275d76008ec88888c68d1a2a9f356d9a79ea74767575756c4c4c9b36ad3b756857515179f162797575757676ee13231e0909092e2c3c07e0c161833c011e71d7d9fc82e2e2120061e1618306f44b4a4a0c0c0c2c2a3a07e0a16183a3a322535253b2b37301646566b468de2c3e3eae71a386e03c3dbd765555d5850b17fdfdfddbb6695db366724e4e2e80def7f44a4888378f5b69dc93bd85417f484785aac43813c638ef9037315d9a1803a822826aacb3ab30c670e952556e5e5e785840427c6c5c6c744848909f9fbf6e207421349f81511340544c2c56fd9b0a34f749ae236338f70a6c7922a772489f6a9124459c49e86773d734cf6a1a141ce43517fe1e162c5ab265eb0ef56bc7f6b70e1b3ad0e781325399e314ee95a31003b2d27fda8cd9fb0f1c0c0e0e1afed0d0e6cd9bbaef728d1b6412415c645730ea8ad761bae68bbe8b838f67151c44879c87696a80a4b9efe6f00e41f36180510ba5a873e74b5c27ef1e8f474b82e2029cc3387a754497d4dd0363abf28cce4b5946948b860be8aaaca8912a92aa190ac1f240cf2d90c21154a59cf55619973330dcd9e38e0eed6f55b7878785c1f499c3587a43a6283ab430cf15556d6000faf7bdefae5e3dfcfdfc535393bdd4f00a55337ae97cc0e97a6f87df8cc6c03ce9321662ba943b888e649ebe273923018c9aa4039fce39b54ac25e3e72d12196081bcd80cca81f0c3048b2fcd023d90c858b184364b964549985b964787b47803e6a525ba3598fb8b9b10d637cd4aed567ff867138c446101b1b13131bad4a30b47c2e42998ea34d5bb8988ab85bc9771f28c727c4195d066a637422a845b99ec7696f415610aec24eb634258ba2813e21af69814c1eb2431b5ba7ab6a747a9293df73adb182ea77e2028728ea2fc6dce170a26145ae16d1644bee413dcb556591f296c363d416126f848b624c263994265004884ef9a9e7ca5ff459291c39677604e33994ce74eee089da0ec25a304caae4795708aeaaaf510e8dc6ad67030a06c6b9e96c15e78ae78058af4156c8ba0eeea2e2872e72511ab91897e3b08a406866c965bbd39a886053914ca2a4a3c9a8464090b7a863e8034db22467a65abee24a0a1012852d1853e1496b134fd2c662e2918ec1096004310515d759a65a3eb4589157a667c5b12ea3cc124f2c1dbe775010ae6491d9cd36272fa3df9936011d9c18b59071da0bd36676c59c1c0e98fe458a624677711cdc71da14059372ab340d6d53fa492dcce587c451010efd38cf0810665a507519e84f1dd9a8adc89951144c7555484b2ee87e7e2a6aa471171d17b8a0749485593a532b41859f9e1e91d33dcb674e16573469d3b97e8b368a1f9c3971f462f1b98c369d1cf1005d011cad9061fbf245a545f9f73cfa8c6a528c71c6d8aad953a212923ade3bc874b0d1907db436a52e74672712a0bea5c1c12442142bea234d1dcce8530f74e1de88b151a67d69d42a1789970d52d14f83bda9e6c188e293467a0dd2cddd10745be246ffd00a13dd809e8f38e03023311fdd6df4a1856ee266f63123624d4348b3eb566f1438757c6a925cd16afc6ad66d78faf0be46adda9f3cb8e7f4e17dea968898f8f89434da13310fb11d70389dc1c16b35ca3ab06d9d922b95e63cb541c6c1ed1bb9ac2ea6ca5c8d13ca258c31c64db95c7e06aa989a123033536964713c8434875233a8698b8e4fccbd40a49f247c8ec940d7390dd25ccbe174a5dc9b11ec9acae88867badf504833a657e5ce2d68762fca15d5104d47541f908c8524a8ed2a6ae13ad9f586e2098ed3024e355687124d6f749b5f9dac966111d10d5bb6eb70efe0ddeb9617e59eacaa2c9f3ca2dfccb18f1fddb54dd9a9a4f0ece4117d278fe83bf989bebfedddc9c12a2f5e109f6c5bbe9081d56a98191010549c9f377944df0d5fcea605589dac964e5b93480a0ca2c5ea65391fb3ba2e41e6c325e50ac32adafccae85a80be91d142dca51557c1c0a82232e2188eb4d0267645bcf91481d612bc08324c990f51fa354ae6f88a81aa9ce2029af3c9f243c29d016f8a52d16664810c44b96d234cbca1e398ab9fe82b4e2d9eb62aade147b7b2b088e82b5597ae555f0d0e8f1833fdabeec39eb874f182dccc8d1b4ba7befee77153ff3c6e6a66bbaec20ef327bc203e292bccdfb37e0563ecfab5ea65d3df796efa572161e1db962f74a8c63435e64a05fd304b575caa7632ce38e79cf39292d2cb97af00b876ed5ad1b973151515172e5ce4726433eb84f1929333fe7273cf64e7e465e7e496955d90cbe85159570bfd70896b1622ca1763aca4b4343b27373b27d7a13be3004e9e3a7d57effeafbff50e754c6ea8c5693ffaa52083d2eae85704917355cf9514ce653da37ce05cbe4aa0fd2f7f770831ecc0cdbfb9ea164eb6e5849954429ac9e5cdb569a0972a798c2f140d701dd671c6fc063ef7fa571fbe0520bd498b1ae9f501d6f1be212b664e06509c9f975ca701e7dcdf13f0c8f80f941c177731d347753fce69c09431473320a8553006e0e369b3ba75eddca1fdad8585457f1fffd6f08787555454f6ec793b53739ab48f1e2cb89cade4c43af8c147b2329b00c8cacce8dfefbea4c424f98853a52d6874822eaf7254a7c974fdfaef3ffa64567a7adaec991f050404a8e204ce473df9dc77abbe22e6414447b1122e4ba06154b39fe83742558f564d5c06802c74d25ce266f3ac545d459625218efeac6c4ca1c01485f5dd0b9de59cfcc935bd33ca33751c70c698476d33fbe881f89a69615131ceee2023f1c4feddc35f9b0a8e5573a6e41cfd25b3dd6dab664f797ee657606cc3a2d930db96f183395ab9843ad980c12e8de364d794ae502329e94af415c6d9b76bd6959494c6c6c6f4bab3fba1c347020303ebd7afb77cf9aafbeebdbb20bf2037ef4c9b5b5a0969e16161d33f7e1fc0cc4fe7ecd8f153df3ef77ebd6cd5a5ca4b356bd6e87a5b67706cdeba3d2fef0c80f8f8b89e3d6e3f78f0d081038700f4b9bf776848081818c38007fa6edebafdd9a74757575f5bbce46ba14cfb766dd3d3d3ae5dbf3e7fc1e2d4d4942e9d3becdeb3f7d75f8f03183ca83f03e334ed0b7fcb2306e7ae4c1a0718049ccc043ad1214aaacd4ad1633c8456a3070d988a6dc9fa6bbcaba572e3e6ad502bc9b51e0ec728974b3f029e8d8b3e3d77267bc5ac77c322a25bddd13b2a2ea9fa4ad5775f7c5c7c36a7f2e2852b972fb5bf67406c52ca8a5993f38e1f061016195d23bd3e808ef70f593eeb5d0079bf1e0e0a093973f258657999983143c2c233db7503f8a6a5734bf2734b0ace2c9f35b951abf68d5ab537838fe3df9d0a7bf6b87dfb8e1f33321a2d58b474f0a007f61df8a5b4b4ecd7e3274a4bcb8202030b0a0abffe664571496954546483fa75a7cd987ddfbd779f3a9dbd7ec3a65b6e69e99ac65d3871f2f4d5ea6a7f7fff53a7b24343422a2f55aefee7ba9494e42d5b7788f7fba6cd98fdec5f473b9fdba2bca262de822f1f1c3210c0f295abfbf5bd4f7df5d3ae3d7bf7ee8f080f17f78e1af9d81f732af434ebd4a359a71e0012526ac7d4480187bfc7d3a8557b5010844644313fbf4163de14bf26a4a6c7262583f35b7adc7fe2c02e002a5cd40fd109c949697500a4376951b36ec3ac0eb703884baee59e0aa10ab8b38633e31ac618c32db7b4faf4b32fcacb2b366cdcf4fc734f2dfd6a19806ddb7f282c2c0a0f0fafa8a8484c4c6892d118c0940fa63dfde4c8575f7bb357cfee301a4a4565e513a39e01909599d1be7d5b0eecdab5a7a4b4acb4b4b459d3cc8080c056ad5adcdeb5cbf9e2e2cd5b769c3a9db372f59ada69b500ecdb7fe0b96746c32b3a1313e2c52ba92fbd3ceefcf9f31e7f7ff1ebdc790b222323870cea0fe0cebbfb8e1af99818c38cc051c9a35a31d36ed7ed8cc289c2c89870359b86f7e1aaee03aa15522012b930a7423d44ffee5468bc406ff65c456a00d3770c1e110daae383717fff0019229a6e737599bc08f00ff0346ad91e5a2dfdec5de55f9dcc16b230a99374ba5c6d480f26822a18af16794f85a4aac49f1f1edaa07e3d00a1a121cb96af06f0cbc1c3fdfadef7c147d34560a9bc0c0d09112f6d464546464545bef4f2b8c103fac5c4c6ecdeb3f7e8d1635a2b8278ce0d22dacc8b32fe8e335cb2180c72024745a10b19d47337e69421c881ce1053140c066888a2655d9dca3915d2d5caf8d087e95ed0712c19ad21d97846a2a39773ee271bb11a58d54325b7682ef749d3b1490ca55154b8eae1016292f86f4e8500664e9b3a72d433e2653d81f8b838f1fa684e4eeeacd9731f7de4c143878e3cf697876ba5a6cc983675cedcf97fffdb8bea623f3fbfda69a969b56a45474779f7c69898e8ca8acaec9cbc3367ce02080b0d8d8e8e125fbd3aee4d732aacaaba7c36bfc008282357380710111171adba3a3b27372727b766cd6472db1f6f2a54bd911ebce8faa8fbb711db66cf5745188e84a62036e9a7994a50e6fd77a742a173eb567f12126a24258687853dfa9787264e7a7fc1c2256969a92fbff02cc0ead7af2788514870705666136e4c85ad5bb7949607636013df1affcaabe34b4acb00dcd6b9e3a081fda6cd98bdfabb75d5d5570174bbad735555d58449ef0198fade24732a0c0c0c9cbf70f11be35f69d6344b445bc3860d2222225ab7162f03f2bef7f75ef4e5bfc4bdb3a67f40fdfe0f3715325efd9b332c8c9fa9ac317289de04f4028ec8736c42bdcfaecb9b7c1f2b28d0bb80eb78fe9da990d2982ee4ca9a86e91cedc2cb56ea436a26809a0aafdfb80e8e871e1c2cbb3ef95b5cb47bcf3ef10669486848dffb7b2b9ea8270f97bab2c830ad1537fde3432bca55af7f3643379a53a18f96aacb81439419626a2a1435469fdb3176b3f7b10c0aa4a742b769356fa3e306b2a1a36119cf0a99e12ca9f4a6a5732f969c03905a3fa365b7bb655d63bca2b4e4f04f9bdbf6ec63704239249b6ae8631ebd31183aa80951114dba5bd544e9426a9b44cfa8d59b57eb20d2afb6a8cce58ed7c5c242c3faf5e94df5c3952d5ed1406e65c66bfb2e37bb189557a200cef83076aa288d5edc95bf8e0150df40b5846249717969055123e12868373f6b102a7b5137a59de2ffc616b87cd1cf1c43986436e7cfe6149c3a9e714b2731b242bf5cc40196dea4f9fc4963fb3ff5eab933d93f7fbfba65d75e0018476070484afd0cea9f8a5bb8d5d6f45c1660075b5781cc692a945948d1672619b576215634171d6ac445e8cd156509ead62ab9bb74ea20290cb5638313ca706eddea4fa21dd3312ad702c9d26a5c70546bb2ac512acdc066c44c8c08137f3842cb0835fa5b5117a58730b89e12e4458c8432350b68864b56f01558ccf58b3e4877c69372030318b8075e7034663d6e92e7c0005e3ba345606070a396edd3339a6f5bbef0e08eefb3da779bfee2631565c5759bb64a1dfd8aca96a9a3075dabbe0aa07def81edef19e85042840d6d5f4598a2ef7a8e343ba0f1a617b4338cc22619acca2a1db234643845796ddbd15e9dadcc5851c984110c660ed1359aa813afd09547153d6d6ce7a190323b1c9e2051a6a6622de618acdca778c66996c1962567f259b4a89dab5568678e82aab3569e1e79643572f65a57f0aaeaaa5ca5740a0a0d03d8954b95e07862e2cca2bcd3abe77ca07c3367fc5f07bff0b6bf27e0c4fe5dd7af572b812773cb063fbb42d510635da8c2a432caac0b8ad478cdc69a30391eec68d7c055546eca760c0710b3e546345303a06fd4684617baec0d4d69d4655495e14a097223e4855ea288c4331964265f84693b6953e5410729d276d22f1501db160df561076a9c72a742184955eba8bd2b753c32a1a9d3f9a86f8a7532f70b990ef6c0b839b58a3bfe3c6ecabcb7c65cafae4e484dbff5aefeda42e20e63153371a983e90244e31277a9e72ecb3256b443181578932932728bb6b428965a3d6646b6ec6dcca81cd449540e52b5902d97abd2ab688f9328d2e00bf373f525a3f308e6f85cd115669635235ea912aa715d4f5af4258d6e4c7eeb28cf3e21cb3ca784d5a58a883c7425a246053f752e219aafe360445b553265388e45c0183b9797cdf98d845a75bc4ed83838f66dfa6ee84b93868f9b52b36ec37d9bbfd316220bfadc893a1550ab50bc880d70339e048c35b5c74cefd15e8c450c5132dac45f4c8e0c44f060de6452546d74990094e0f4ad749b71a8e7d8a4a118485f95db923caa2c94e779d2018e5050cf2d4001c998e0b76a4e11aad348629a4759ef66be905c8d33707a538134637414223d619aca6394564e7169be7cac6a83cc05a1c7a6a573c593c1a090d08c369dd21a658163dd82192585678a724e2e9f3939ab5dd7ba4d5b6d5afa79f691fd7efefe4121614dda763235360740da18a37ec7890801fab56f552a20edebf00cbdc86b185c27b5496d1d81cd0ca7aa2707e40aaf3c76b6121d4680b911477ea93dba58b7e15fefb9cabcdd21c77591a3b01b5ba31eef68598aece9aeeb7373be60f2389240ef54fa0ac8df9b0a95ee379b0a073fff1680c8d8f81ae90d84f8ba4d5ba5356edaa2cb9d0062129339e7f78f7ce9eae54b0022631392eb34f0d655d9cbd9e398834cb8a803d0bd7393c8f0907fadde63985b9b5aed4e54389aba1445853a9550ed508e80e20492314842644a73937438ded2d1a1a3e77f6272aa7a69ff39270deaddae8315afb0f61de88afce97f38a4c4ba0e029d7fab7eebb29baf458c5ffebb5361e3d61deb376f839b4f85ccecb56060a8d7ac951a74c5e575325bc825bdfca4d4d0c589ecadd25b7dc581e9138675685d0fc04f7b4f6ddf7d3c2e265c2b4c8ed1d444459b391d3170ce1f1bdaf9a9e1dd1e193377f7fed3e9a9712be68c5eb86cd7db1fae7278df3c78547e739c093200f7f568f1e60bf78bdfbb0e985c5c5a092fbec2b481d4aebdc76e5554dcb54759cf60f7ca178230eaf6c21c466386f49b89a2f5bc6721e38efff054181412121412a234f69e0a0d15a9c61b94d839e910f375dadc980ae911acdca7833b83b3a9e3072e5db567e4d87f8a5b860f681f171d562f3d11c0e9dcf3376ef0b0b0a0a4844800f985655597abd352e272ce96448607fbf9b1b28b55a9c931670aca44fd8b890a8d080fae9914edf1f8a5d58c0d0d094c880b678cd548880c0d0dba7efd46765e71787870627ca4583c3bafd8cf8fc54587e5175d640c3512228bcb2aababaf718e88f0e005cb764ef86835380e6d7c3debf671a1a1813512a30014145eb874f96a5a4a6cd1f9f288f0e073e7cb8da9903cea9e0a99722359994aab4a30a3903b8eb5dc53a1ac8b20d2ac92d5083bfd4fa9e50988efb012d1fb9f9d0ab92067bea742f35106634c4c853a11e9d534e29f26c3a67831b9b46651f09e0a8f1ccf4f4f8debd1b949d5e5eaad3b7f037057b7a68d1b240398397fcbf65dc787f569dba34b2680e5ebf67fb97cd7aa2f9e6a7ac76b0ff46e1d1116fcfeacf58ba78fe839744a79c565312c8d7b77f9c887ba1c3892fbc11b8347be3cbf57d7ac8675939e78b04b7aadf8aaaaab5367afaf9b96f0f253771d3f7d0ec0e78bb7ff7ab2f08de7ef7f60c474cef1e19b435efdc737478f17887dd4af9dd8b37326809ff69d024756a394b1a37b7160f586030bbed9b9f1cbe7defc60555868d0c79f6f74b5a4fff553a1473365d992b9b37ceaa9906b514a86ae588efaae7602752aa6cb93695e9faddd7b2a9cfecfcd8f0fe9dcbd4be6b56bd7a3a34201ccfbeac77767ac057070c3f8614f7ddabe75fd3e8f7ec2395ff5c553dfef380a203539263e26dccf8fd5ab1defda0b80656bf6f5eede7ce1b29de2d7e1033b040678d66d3e141e1e3c616cbf59f3b72c5ebefb8da92b196307378cef3f629ae15cad15801265dc650000049c494441547ae909ddbb6402d8b9f714078a8a2faed97c88014f3c74dbe61f7f0d0e0e080e0af878ce46733b7a93a6ad7499073126f3f00c6a7aa58ec19ca2940b849925a9d45321b500e96ab12a3725dd742a84f10226d420a208aba9b481df9d0a4d5ee69c0a61746b450c383dda9407c0920d035ecf0ad5edfffe54386bc156006929b1d3260c5bb272b74f2b989e6f5837a966527479e5e5a619a96439351861fabccd07378ccfea36ae7b9726e6fd1515973f9ab3312850cf34bea513d66c3e34f1a36f011cdc307ed9da7dc307742828baa05c5476a16afabccddce8442a868cfafc079b0a99f1cf01bca742a8da6b6c56bf2a20afbbe9b34263d1ffca5448da7bcb15b188f1efafb8bfe79fa6cddb74edda8d11c33a7f3867e3a5aaab2e214f8c9d67bec7f2dda6832bd6ed8f8e0a7d6954affd8772499a776ac1fb2bb16e5c7458a37a35fe3e7919634cf465681f3b9dfc479e0ad59dccd75448afd218438f6aba2e19f246ee30afa1c6bf3315bef2f43d037bb70650545cfee0d3b37b92db040eff96bf76cba103ebc60118f7eef2bc8252e6c71eeadfeec86ff9004f4e8c3a74ececf5eb3774d2039cf36d3b8f2b6d264f5f33716cbfb75fec5376b16af0a8999dda34306d7a22fbdcd2557b7e593f0e80e0e6eaab510f771d725f1b000f3e3dfbb75385cbd6eefb65fd6b009293a2b421fe905321e3577f85cf67854a5b122f1bb8aae95e2f0ce979cea9ab6c721c8c31f13ed699a24bffc1678581819ed4e418d31827b3cf39dda096a2d26b9f15c2203d1c00b62d1a7ae1c2059fff670aa2fc929cb88c664e85f41ecaff2753e1ef3f2b4c4d8e99fcea03dac09cf77d749a2a04ca9d4a0023b7684b4baaabd4739c77d86785ff6ba7424d44383d9e22ad009ccc3ed7f7d14f407126762a4c024675cad88b5cc41065b6695541957c53337d9959e0756552758ba24f2ef2879b0afd34f39095c97841df982c48b2632ad4574117711545aae040e6ae33ee6820308c4ba543e41bb88c4efdae9ca1127718827476589c3b4f05b91162529ac1deb99c60c1f94da2cad995c4df740d9510473d950a719596c6bd467dd65bf135e26839de17c92aeed24ad478e626ed5e025c91f47b458b89424f375301bf2933fb7f36152627844f7de58edfd989c5ff7d78fcfd7c7decd5a7ff274f8521c19e762d5328e4f5c020e9853a2051e75fce432fc5ac8d0f1d27628a64bae61dd713629728e332070336af2403326f99aeaff4f5266de62ead8ceb5529f61aa035b77389727006c168d51fee8d38b4723238a5952ffc17a7429fb22c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2cfe87e0ff00ace6d50371fd95d80000000049454e44ae426082, 'image/png', 46696, 0, '2007-02-11 18:24:19', '2007-02-11 18:24:19');
+
+--
+-- Dumping data for table `reviewratings`
+--
+
+
+--
+-- Dumping data for table `reviews`
+--
+
+INSERT INTO `reviews` (`id`, `version_id`, `user_id`, `reply_to`, `rating`, `title`, `body`, `editorreview`, `flag`, `sandbox`, `created`, `modified`) VALUES
+(1, 1, 1, NULL, 5, 138, 129, 0, 0, 0, '2006-11-09 17:41:39', '2006-11-09 17:41:39'),
+(2, 1, 2, NULL, 9, 130, 131, 0, 0, 0, '2006-11-09 17:41:39', '2006-11-09 17:41:39'),
+(3, 1, 3, NULL, 0, 132, 133, 0, 0, 0, '2006-11-09 17:48:09', '2006-11-09 17:48:09'),
+(4, 1, 4, NULL, 10, 134, 135, 0, 0, 0, '2006-11-09 17:48:50', '2006-11-09 17:48:50'),
+(5, 2, 5, NULL, 7, 136, 137, 0, 0, 0, '2006-11-09 18:15:51', '2006-11-09 18:15:51'),
+(6, 28898, 5, NULL, 10, 46704, 46705, 0, 0, 0, '2007-02-11 19:01:40', '2007-02-11 19:02:30'),
+(7, 1, 5, 4, NULL, 46714, 46715, 0, 0, 0, '2007-07-24 05:19:25', '2007-07-24 05:19:25');
+
+--
+-- Dumping data for table `tags`
+--
+
+INSERT INTO `tags` (`id`, `name`, `description`, `addontype_id`, `application_id`, `created`, `modified`) VALUES
+(1, 30, 17, 1, 1, '2006-08-22 12:27:42', '2006-08-22 12:51:46'),
+(2, 31, 18, 1, 1, '2006-08-22 12:35:06', '2006-08-22 12:35:06'),
+(3, 32, 19, 1, 18, '2006-08-22 12:47:47', '2006-08-22 12:47:47'),
+(4, 7, 20, 4, 1, '2006-08-22 12:48:20', '2006-08-22 12:48:20'),
+(5, 8, 21, 2, 1, '2006-08-22 12:51:07', '2006-08-22 12:51:07'),
+(6, 9, 22, 2, 1, '2006-08-22 12:51:33', '2006-08-22 12:51:33'),
+(7, 10, 23, 2, 1, '2006-08-22 22:19:58', '2006-08-22 22:19:58'),
+(8, 11, 24, 2, 18, '2006-08-22 22:20:20', '2006-08-22 22:20:20'),
+(9, 12, 25, 2, 18, '2006-08-22 22:22:56', '2006-08-22 22:22:56'),
+(10, 13, 26, 3, 1, '2006-08-26 20:10:48', '2006-09-05 16:55:42'),
+(11, 14, 27, 3, 1, '2006-09-05 17:04:19', '2006-09-05 18:40:44'),
+(12, 15, 28, 1, 1, '2006-09-28 09:00:58', '2006-09-28 09:00:58'),
+(13, 16, 29, 1, 1, '2006-09-28 09:01:16', '2006-09-28 09:01:16'),
+(14, 162, NULL, 4, 1, '2007-01-04 13:42:29', '0000-00-00 00:00:00'),
+(15, 163, NULL, 4, 1, '2007-01-04 13:42:47', '0000-00-00 00:00:00'),
+(16, 164, NULL, 4, 1, '2007-01-04 13:43:09', '0000-00-00 00:00:00');
+
+--
+-- Dumping data for table `translations`
+--
+
+INSERT INTO `translations` (`id`, `locale`, `localized_string`, `created`, `modified`) VALUES
+(7, 'de', 'Google', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(7, 'en-US', 'Google', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(8, 'de', 'Geb', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(8, 'en-US', 'Brushed Metal', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(9, 'de', 'Geb', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(9, 'en-US', 'Brushed Metal', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(10, 'de', 'Humor', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(10, 'en-US', 'Humor', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(11, 'de', 'Hell auf Dunkel', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(11, 'en-US', 'Light on dark', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(12, 'de', 'Dunkel auf Hell', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(12, 'en-US', 'Dark on Light', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(13, 'de', 'W', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(13, 'en-US', 'Dictionaries', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(14, 'de', 'Test', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(14, 'en-US', 'Test', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(15, 'de', 'Verwaltung', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(15, 'en-US', 'Organizer', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(16, 'de', 'web data (de)', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(16, 'en-US', 'Web Data', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(17, 'de', 'Tools f', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(17, 'en-US', 'Tools for developers', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(18, 'de', 'Erkl', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(18, 'en-US', 'Declare your extension as a virus by listing it under this category', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(19, 'de', 'Nachrichten in Thunderbird lesen', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(19, 'en-US', 'For reading the news in Thunderbird.', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(20, 'de', 'F', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(20, 'en-US', 'For all plugins relating to Google.', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(21, 'de', 'Jeder kopiert Safari, also brauchen wir diese Kategorie', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(21, 'en-US', 'Everyone''s copying Safari, so lets lump em all into one category.', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(22, 'de', 'Jeder kopiert Safari, also brauchen wir diese Kategorie', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(22, 'en-US', 'Everyone''s copying Safari, so lets lump em all into one category.', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(23, 'de', 'Lustige deutsche Themes', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(23, 'en-US', 'Funnay!', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(24, 'de', '(deutsch)', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(24, 'en-US', '', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(25, 'de', '(deutsch)', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(25, 'en-US', '', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(26, 'de', '', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(26, 'en-US', 'English Dictionaries', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(27, 'de', '(deutsch)', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(27, 'en-US', '', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(28, 'de', '(deutsch)', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(28, 'en-US', '', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(29, 'de', '', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(29, 'en-US', '', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(30, 'de', 'Entwickler-Tools', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(30, 'en-US', 'Developer Tools', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(31, 'de', 'Viren', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(31, 'en-US', 'Viruses', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(32, 'de', 'News-Reading', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(32, 'en-US', 'News Reading', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(33, 'en-US', 'English &#40;Australian&#41;', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(34, 'en-US', 'Are you sick of all your favo&#45;U&#45;rite colo&#45;U&#45;rful language being marked incorrect? Me too. Live no more in the world of crazy American spelling &#45; get the Australian English Dictionary :&#41;', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(35, 'en-US', 'Australian English Dictionary', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(36, 'en-US', 'Winfox', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(37, 'en-US', 'To fully integrate Firefox with windows, please install this extension. You''ll see a noticeable slowdown of Firefox and and increased crash rate. Enjoy the talking paperclip too :)', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(38, 'en-US', 'Make Firefox more like Windows.', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(39, 'en-US', 'Winfox', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(40, 'en-US', 'To fully integrate Firefox with windows, please install this extension. You''ll see a noticeable slowdown of Firefox and and increased crash rate. Enjoy the talking paperclip too :)', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(41, 'en-US', 'Make Firefox more like Windows.', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(42, 'en-US', 'Invisible', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(43, 'en-US', 'Hey, there''s an idea.. lets make every themed element white and see what users think of it. Good luck trying to change your theme back to the default!', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(44, 'en-US', 'A white theme.', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(45, 'en-US', 'Google', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(46, 'en-US', 'So what if Google is the default search engine? Lets put another one in.', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(47, 'en-US', 'Google search, mark two.', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(48, 'en-US', 'iTranslated', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(49, 'en-US', 'Get hip! This add-on will translate Firefox into apple''s new iLanguage. It doesn''t actually do that yet, but apple users all over the world are getting hyped about it. Synch it with your ipod, ichicken and stay icool.', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(50, 'en-US', '', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(51, 'de', 'MikroLandwirt', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(51, 'en-US', 'MicroFarmer', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(52, 'de', '<p>F', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(52, 'en-US', '<p>Adds MicroFormat detection and export to Firefox. Handles hCard,hCalendar and XOXO.</p>\r\n<p>\r\nWith MicroFarmer, you never have to worry about transferring your data from the web onto your portable devices.</p>\r\n\r\n<p>It''s almost as easy to use as Jetpak without the nasty hidden fees!</p><p>Also, here is some UTF-8 that may cause trouble: 中文介. But that should not affect sanitization of signs like & and ".</p>', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(53, 'de', 'Ernten Sie Mikroformate von Webseiten auf Knopfdruck.', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(53, 'en-US', 'Harvest MicroFormats from web pages with the click of a button.', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(54, 'de', 'Mikrofischer', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(54, 'en-US', 'MicroFisher', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(55, 'en-US', '<p>Adds MicroFormat detection and export to Firefox. Handles hCard,hCalendar and XOXO.</p>\r\n<p>\r\nWith MicroFarmer, you never have to worry about transferring your data from the web onto your portable devices.</p>\r\n\r\n<p>It''s almost as easy to use as Jetpak without the nasty hidden fees!</p>', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(56, 'de', 'Fangen Sie Mikrofische auf Webseiten mit nur einem Knopfdruck.', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(56, 'en-US', 'Harvest MicroFishes from web pages with the click of a button.', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(57, 'de', 'MikroJ', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(57, 'en-US', 'MicroHunter', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(58, 'en-US', '<p>Adds MicroFormat detection and export to Firefox. Handles hCard,hCalendar and XOXO.</p>\r\n<p>\r\nWith MicroFarmer, you never have to worry about transferring your data from the web onto your portable devices.</p>\r\n\r\n<p>It''s almost as easy to use as Jetpak without the nasty hidden fees!</p>', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(59, 'de', 'Jagen Sie Mikrotiere auf Webseiten mit nur einem Knopfdruck.', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(59, 'en-US', 'Harvest MicroAnimals from web pages with the click of a button.', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(60, 'en-US', 'http://justcameron.com/incoming/en&#45;au&#45;dictionary/', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(61, 'en-US', 'ms.com', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(62, 'en-US', 'ms.com', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(63, 'en-US', 'invisible.com', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(64, 'en-US', '', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(65, 'en-US', 'apple.com', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(66, 'en-US', '', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(67, 'en-US', '', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(68, 'en-US', '', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(69, 'en-US', 'GNU GENERAL PUBLIC LICENSE\r\n Version 2, June 1991\r\n\r\n Copyright (C) 1989, 1991 Free Software Foundation, Inc.,\r\n 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\r\n Everyone is permitted to copy and distribute verbatim copies\r\n of this license document, but changing it is not allowed.\r\n\r\n Preamble\r\n\r\n The licenses for most software are designed to take away your\r\nfreedom to share and change it. By contrast, the GNU General Public\r\nLicense is intended to guarantee your freedom to share and change free\r\nsoftware--to make sure the software is free for all its users. This\r\nGeneral Public License applies to most of the Free Software\r\nFoundation''s software and to any other program whose authors commit to\r\nusing it. (Some other Free Software Foundation software is covered by\r\nthe GNU Lesser General Public License instead.) You can apply it to\r\nyour programs, too.\r\n\r\n When we speak of free software, we are referring to freedom, not\r\nprice. Our General Public Licenses are designed to make sure that you\r\nhave the freedom to distribute copies of free software (and charge for\r\nthis service if you wish), that you receive source code or can get it\r\nif you want it, that you can change the software or use pieces of it\r\nin new free programs; and that you know you can do these things.\r\n\r\n To protect your rights, we need to make restrictions that forbid\r\nanyone to deny you these rights or to ask you to surrender the rights.\r\nThese restrictions translate to certain responsibilities for you if you\r\ndistribute copies of the software, or if you modify it.\r\n\r\n For example, if you distribute copies of such a program, whether\r\ngratis or for a fee, you must give the recipients all the rights that\r\nyou have. You must make sure that they, too, receive or can get the\r\nsource code. And you must show them these terms so they know their\r\nrights.\r\n\r\n We protect your rights with two steps: (1) copyright the software, and\r\n(2) offer you this license which gives you legal permission to copy,\r\ndistribute and/or modify the software.\r\n\r\n Also, for each author''s protection and ours, we want to make certain\r\nthat everyone understands that there is no warranty for this free\r\nsoftware. If the software is modified by someone else and passed on, we\r\nwant its recipients to know that what they have is not the original, so\r\nthat any problems introduced by others will not reflect on the original\r\nauthors'' reputations.\r\n\r\n Finally, any free program is threatened constantly by software\r\npatents. We wish to avoid the danger that redistributors of a free\r\nprogram will individually obtain patent licenses, in effect making the\r\nprogram proprietary. To prevent this, we have made it clear that any\r\npatent must be licensed for everyone''s free use or not licensed at all.\r\n\r\n The precise terms and conditions for copying, distribution and\r\nmodification follow.\r\n\r\n GNU GENERAL PUBLIC LICENSE\r\n TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION\r\n\r\n 0. This License applies to any program or other work which contains\r\na notice placed by the copyright holder saying it may be distributed\r\nunder the terms of this General Public License. The "Program", below,\r\nrefers to any such program or work, and a "work based on the Program"\r\nmeans either the Program or any derivative work under copyright law:\r\nthat is to say, a work containing the Program or a portion of it,\r\neither verbatim or with modifications and/or translated into another\r\nlanguage. (Hereinafter, translation is included without limitation in\r\nthe term "modification".) Each licensee is addressed as "you".\r\n\r\nActivities other than copying, distribution and modification are not\r\ncovered by this License; they are outside its scope. The act of\r\nrunning the Program is not restricted, and the output from the Program\r\nis covered only if its contents constitute a work based on the\r\nProgram (independent of having been made by running the Program).\r\nWhether that is true depends on what the Program does.\r\n\r\n 1. You may copy and distribute verbatim copies of the Program''s\r\nsource code as you receive it, in any medium, provided that you\r\nconspicuously and appropriately publish on each copy an appropriate\r\ncopyright notice and disclaimer of warranty; keep intact all the\r\nnotices that refer to this License and to the absence of any warranty;\r\nand give any other recipients of the Program a copy of this License\r\nalong with the Program.\r\n\r\nYou may charge a fee for the physical act of transferring a copy, and\r\nyou may at your option offer warranty protection in exchange for a fee.\r\n\r\n 2. You may modify your copy or copies of the Program or any portion\r\nof it, thus forming a work based on the Program, and copy and\r\ndistribute such modifications or work under the terms of Section 1\r\nabove, provided that you also meet all of these conditions:\r\n\r\n a) You must cause the modified files to carry prominent notices\r\n stating that you changed the files and the date of any change.\r\n\r\n b) You must cause any work that you distribute or publish, that in\r\n whole or in part contains or is derived from the Program or any\r\n part thereof, to be licensed as a whole at no charge to all third\r\n parties under the terms of this License.\r\n\r\n c) If the modified program normally reads commands interactively\r\n when run, you must cause it, when started running for such\r\n interactive use in the most ordinary way, to print or display an\r\n announcement including an appropriate copyright notice and a\r\n notice that there is no warranty (or else, saying that you provide\r\n a warranty) and that users may redistribute the program under\r\n these conditions, and telling the user how to view a copy of this\r\n License. (Exception: if the Program itself is interactive but\r\n does not normally print such an announcement, your work based on\r\n the Program is not required to print an announcement.)\r\n\r\nThese requirements apply to the modified work as a whole. If\r\nidentifiable sections of that work are not derived from the Program,\r\nand can be reasonably considered independent and separate works in\r\nthemselves, then this License, and its terms, do not apply to those\r\nsections when you distribute them as separate works. But when you\r\ndistribute the same sections as part of a whole which is a work based\r\non the Program, the distribution of the whole must be on the terms of\r\nthis License, whose permissions for other licensees extend to the\r\nentire whole, and thus to each and every part regardless of who wrote it.\r\n\r\nThus, it is not the intent of this section to claim rights or contest\r\nyour rights to work written entirely by you; rather, the intent is to\r\nexercise the right to control the distribution of derivative or\r\ncollective works based on the Program.\r\n\r\nIn addition, mere aggregation of another work not based on the Program\r\nwith the Program (or with a work based on the Program) on a volume of\r\na storage or distribution medium does not bring the other work under\r\nthe scope of this License.\r\n\r\n 3. You may copy and distribute the Program (or a work based on it,\r\nunder Section 2) in object code or executable form under the terms of\r\nSections 1 and 2 above provided that you also do one of the following:\r\n\r\n a) Accompany it with the complete corresponding machine-readable\r\n source code, which must be distributed under the terms of Sections\r\n 1 and 2 above on a medium customarily used for software interchange; or,\r\n\r\n b) Accompany it with a written offer, valid for at least three\r\n years, to give any third party, for a charge no more than your\r\n cost of physically performing source distribution, a complete\r\n machine-readable copy of the corresponding source code, to be\r\n distributed under the terms of Sections 1 and 2 above on a medium\r\n customarily used for software interchange; or,\r\n\r\n c) Accompany it with the information you received as to the offer\r\n to distribute corresponding source code. (This alternative is\r\n allowed only for noncommercial distribution and only if you\r\n received the program in object code or executable form with such\r\n an offer, in accord with Subsection b above.)\r\n\r\nThe source code for a work means the preferred form of the work for\r\nmaking modifications to it. For an executable work, complete source\r\ncode means all the source code for all modules it contains, plus any\r\nassociated interface definition files, plus the scripts used to\r\ncontrol compilation and installation of the executable. However, as a\r\nspecial exception, the source code distributed need not include\r\nanything that is normally distributed (in either source or binary\r\nform) with the major components (compiler, kernel, and so on) of the\r\noperating system on which the executable runs, unless that component\r\nitself accompanies the executable.\r\n\r\nIf distribution of executable or object code is made by offering\r\naccess to copy from a designated place, then offering equivalent\r\naccess to copy the source code from the same place counts as\r\ndistribution of the source code, even though third parties are not\r\ncompelled to copy the source along with the object code.\r\n\r\n 4. You may not copy, modify, sublicense, or distribute the Program\r\nexcept as expressly provided under this License. Any attempt\r\notherwise to copy, modify, sublicense or distribute the Program is\r\nvoid, and will automatically terminate your rights under this License.\r\nHowever, parties who have received copies, or rights, from you under\r\nthis License will not have their licenses terminated so long as such\r\nparties remain in full compliance.\r\n\r\n 5. You are not required to accept this License, since you have not\r\nsigned it. However, nothing else grants you permission to modify or\r\ndistribute the Program or its derivative works. These actions are\r\nprohibited by law if you do not accept this License. Therefore, by\r\nmodifying or distributing the Program (or any work based on the\r\nProgram), you indicate your acceptance of this License to do so, and\r\nall its terms and conditions for copying, distributing or modifying\r\nthe Program or works based on it.\r\n\r\n 6. Each time you redistribute the Program (or any work based on the\r\nProgram), the recipient automatically receives a license from the\r\noriginal licensor to copy, distribute or modify the Program subject to\r\nthese terms and conditions. You may not impose any further\r\nrestrictions on the recipients'' exercise of the rights granted herein.\r\nYou are not responsible for enforcing compliance by third parties to\r\nthis License.\r\n\r\n 7. If, as a consequence of a court judgment or allegation of patent\r\ninfringement or for any other reason (not limited to patent issues),\r\nconditions are imposed on you (whether by court order, agreement or\r\notherwise) that contradict the conditions of this License, they do not\r\nexcuse you from the conditions of this License. If you cannot\r\ndistribute so as to satisfy simultaneously your obligations under this\r\nLicense and any other pertinent obligations, then as a consequence you\r\nmay not distribute the Program at all. For example, if a patent\r\nlicense would not permit royalty-free redistribution of the Program by\r\nall those who receive copies directly or indirectly through you, then\r\nthe only way you could satisfy both it and this License would be to\r\nrefrain entirely from distribution of the Program.\r\n\r\nIf any portion of this section is held invalid or unenforceable under\r\nany particular circumstance, the balance of the section is intended to\r\napply and the section as a whole is intended to apply in other\r\ncircumstances.\r\n\r\nIt is not the purpose of this section to induce you to infringe any\r\npatents or other property right claims or to contest validity of any\r\nsuch claims; this section has the sole purpose of protecting the\r\nintegrity of the free software distribution system, which is\r\nimplemented by public license practices. Many people have made\r\ngenerous contributions to the wide range of software distributed\r\nthrough that system in reliance on consistent application of that\r\nsystem; it is up to the author/donor to decide if he or she is willing\r\nto distribute software through any other system and a licensee cannot\r\nimpose that choice.\r\n\r\nThis section is intended to make thoroughly clear what is believed to\r\nbe a consequence of the rest of this License.\r\n\r\n 8. If the distribution and/or use of the Program is restricted in\r\ncertain countries either by patents or by copyrighted interfaces, the\r\noriginal copyright holder who places the Program under this License\r\nmay add an explicit geographical distribution limitation excluding\r\nthose countries, so that distribution is permitted only in or among\r\ncountries not thus excluded. In such case, this License incorporates\r\nthe limitation as if written in the body of this License.\r\n\r\n 9. The Free Software Foundation may publish revised and/or new versions\r\nof the General Public License from time to time. Such new versions will\r\nbe similar in spirit to the present version, but may differ in detail to\r\naddress new problems or concerns.\r\n\r\nEach version is given a distinguishing version number. If the Program\r\nspecifies a version number of this License which applies to it and "any\r\nlater version", you have the option of following the terms and conditions\r\neither of that version or of any later version published by the Free\r\nSoftware Foundation. If the Program does not specify a version number of\r\nthis License, you may choose any version ever published by the Free Software\r\nFoundation.\r\n\r\n 10. If you wish to incorporate parts of the Program into other free\r\nprograms whose distribution conditions are different, write to the author\r\nto ask for permission. For software which is copyrighted by the Free\r\nSoftware Foundation, write to the Free Software Foundation; we sometimes\r\nmake exceptions for this. Our decision will be guided by the two goals\r\nof preserving the free status of all derivatives of our free software and\r\nof promoting the sharing and reuse of software generally.\r\n\r\n NO WARRANTY\r\n\r\n 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY\r\nFOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN\r\nOTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES\r\nPROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED\r\nOR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\r\nMERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS\r\nTO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE\r\nPROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,\r\nREPAIR OR CORRECTION.\r\n\r\n 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING\r\nWILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR\r\nREDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,\r\nINCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING\r\nOUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED\r\nTO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY\r\nYOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER\r\nPROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE\r\nPOSSIBILITY OF SUCH DAMAGES.\r\n\r\n END OF TERMS AND CONDITIONS\r\n', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(70, 'en-US', 'In exchange for the use of this extension, your soul is forfeit.', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(71, 'en-US', 'In exchange for the use of this extension, your soul is forfeit.', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(72, 'en-US', 'This extension steals all your passwords and then deletes your harddrive, don''t complain about it.', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(73, 'en-US', 'This extension steals all your passwords and then deletes your harddrive, don''t complain about it.', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(74, 'en-US', 'Welcome to Microfarmer, a Farming! company. By downloading the MicroFarmer \r\nsoftware (''MicroFarmer Software''), you agree to these software license terms \r\n(the "Software License") that supplement the MicroFarmer Terms of Service ("TOS") \r\nlocated at http://microfarmer.org/help/terms. If you disagree with any of the terms below, \r\nMicroFarmer does not grant you a license to use the MicroFarmer Software.\r\n \r\nYour registration data and certain other information about you is subject to\r\nour Privacy Policy. For more information, see our full privacy policy at\r\nhttp://microfarmer.org/help/privacy.\r\n \r\nMicroFarmer reserves the right to update and change, from time to time, this\r\nSoftware License and all documents incorporated by reference. You can always\r\nfind the most recent version of this Software License at\r\nhttp://microfarmer.org/help/firefox/bookmarks/license. MicroFarmer may change this Software License\r\nby posting a new version without notice to you. Use of the MicroFarmer Software\r\nafter such change constitutes acceptance of such changes. \r\n \r\n1. Licensed Uses and Restrictions. \r\n \r\nBy accepting the terms of this Agreement, you represent to microfarmer.org and its\r\naffiliates (collectively, "MicroFarmer") that you are at least 18 years old. The\r\nMicroFarmer Software applications, documentation, and local computer files\r\ninstalled or utilized by the installer application (collectively, the\r\n"MicroFarmer Software") are owned by MicroFarmer, or MicroFarmer''s licensors and\r\ncontent and data providers ("MicroFarmer Licensors"), and are licensed to you on\r\na worldwide (except as limited below), non-exclusive, non-sublicenseable basis\r\non the terms and conditions set forth herein. This Software License defines\r\nlegal use of the MicroFarmer Software, all updates, revisions, substitutions, and\r\nany copies of the MicroFarmer Software made by or for you. All rights not\r\nexpressly granted to you are reserved by MicroFarmer or their respective owners. \r\n \r\na. YOU MAY install and personally use the MicroFarmer Software and any updates\r\nprovided by MicroFarmer (in its sole discretion) in object code form on a\r\npersonal computer owned or controlled by you and may use the MicroFarmer Software\r\nfor your own noncommercial use or benefit. Your license to the MicroFarmer\r\nSoftware under this Software License continues until it is terminated by either\r\nparty. You may terminate the Software License by discontinuing use of all or\r\nany of the MicroFarmer Software and by destroying all your copies of the\r\napplicable MicroFarmer Software. To uninstall the MicroFarmer Software, you may\r\nuse the standard Mozilla Firefox ''Add-ons'' window. Once you\r\naccess the ''Add-ons'' window, select the ''microfarmer.org Bookmarks'' extension and click ''Uninstall''. \r\nThe MicroFarmer Software will be uninstalled and will no longer be visible when\r\nyou restart Firefox. This Software License terminates automatically\r\nif you violate any term of this Software License, MicroFarmer publicly posts a\r\nwritten notice of termination on the MicroFarmer web site, or MicroFarmer sends a\r\nwritten notice of termination to you.\r\n \r\nb. YOU MAY NOT: \r\n(i) decompile, reverse engineer, disassemble, modify, rent, lease, loan,\r\ndistribute, or create derivative works (as defined by the U.S. Copyright Act)\r\nor improvements (as defined by U.S. patent law) from the MicroFarmer Software or\r\nany portion thereof. \r\n \r\n(ii) incorporate the MicroFarmer Software into any computer chip or the firmware\r\nof a computing device manufactured by or for you. \r\n \r\n(iii) use the MicroFarmer Software in any unlawful manner, for any unlawful\r\npurpose, or in any manner inconsistent with TOS or this Software License.\r\n \r\n(iv) use the MicroFarmer Software to operate nuclear facilities, life support,\r\nor other mission critical application where human life or property may be at\r\nstake. You understand that the MicroFarmer Software is not designed for such\r\npurposes and that its failure in such cases could lead to death, personal\r\ninjury, or severe property or environmental damage for which MicroFarmer is not\r\nresponsible. \r\n \r\n(v) use or export the MicroFarmer Software in violation of applicable U.S. laws\r\nor regulations\r\n \r\n(vi) sell, lease, loan, distribute, transfer, or sublicense the MicroFarmer \r\nSoftware or access thereto or derive income from the use or provision of the\r\nMicroFarmer Software, whether for direct commercial or monetary gain or\r\notherwise, without MicroFarmer''s prior, express, written permission. \r\n \r\n2. Ownership and Relationship of Parties. \r\n \r\nThe MicroFarmer Software is protected by copyrights, trademarks, service marks,\r\ninternational treaties, and/or other proprietary rights and laws of the U.S.\r\nand other countries. You agree to abide by all applicable proprietary rights\r\nlaws and other laws, as well as any additional copyright notices or\r\nrestrictions contained in this Software License and in the TOS. MicroFarmer and\r\nMicroFarmer''s Licensors own all rights, title, and interest in and to their\r\napplicable contributions to the MicroFarmer Software. This Software License\r\ngrants you no right, title, or interest in any intellectual property owned or\r\nlicensed by MicroFarmer, including (but not limited to) the MicroFarmer Software\r\nand MicroFarmer trademarks, and creates no relationship between yourself and\r\nMicroFarmer''s Licensors, or between you and MicroFarmer other than that of\r\nMicroFarmer to licensee. \r\n \r\n3. Support and Software Updates. \r\n \r\nMicroFarmer may elect to provide you with customer support and/or software\r\nupgrades, enhancements, or modifications for the MicroFarmer Software\r\n(collectively, "Support"), in its sole discretion, and may terminate such\r\nSupport at any time without notice to you. MicroFarmer may change, suspend, or\r\ndiscontinue any aspect of the MicroFarmer Software at any time, including the\r\navailability of any MicroFarmer Software feature, database, or content. MicroFarmer\r\nmay also impose limits on certain features and services or restrict your access\r\nto parts or all of the MicroFarmer Software or the MicroFarmer web site without\r\nnotice or liability. \r\n \r\n4. Fees and Payments. \r\n \r\nMicroFarmer reserves the right to charge fees for future use of or access to the\r\nMicroFarmer Software or the MicroFarmer services and web sites (collectively,\r\n"MicroFarmer Software Services") in MicroFarmer''s sole discretion. If MicroFarmer\r\ndecides to charge for the MicroFarmer Software Services, such charges will be\r\ndisclosed to you prior. \r\n \r\n5. Disclaimer of Warranties by MicroFarmer. \r\n \r\nUSE OF THE DELICIOUS SOFTWARE AND ANY WEB PAGES OR DATA ACCESSED THROUGH THE\r\nDELICIOUS SOFTWARE IS AT YOUR SOLE RISK. \r\n \r\nANY MATERIAL OR SERVICE DOWNLOADED OR OTHERWISE OBTAINED THROUGH THE USE OF THE\r\nDELICIOUS SOFTWARE IS DONE AT YOUR OWN DISCRETION AND RISK, AND YOU WILL BE\r\nSOLELY RESPONSIBLE FOR ANY DAMAGE TO YOUR COMPUTER SYSTEM OR LOSS OF DATA THAT\r\nRESULTS FROM THE DOWNLOAD AND/OR USE OF ANY SUCH MATERIAL OR SERVICE.\r\n \r\nDELICIOUS, ITS OFFICERS, DIRECTORS, EMPLOYEES, CONTRACTORS, AGENTS, AFFILIATES,\r\nAND ASSIGNS (COLLECTIVELY, "DELICIOUS ENTITIES") AND DELICIOUS LICENSORS DO NOT\r\nREPRESENT THAT THE DELICIOUS SOFTWARE OR ANY DATA ACCESSED THEREFROM IS\r\nAPPROPRIATE OR AVAILABLE FOR USE OUTSIDE THE UNITED STATES. \r\n \r\nTHE DELICIOUS ENTITIES AND DELICIOUS LICENSORS EXPRESSLY DISCLAIM ALL\r\nWARRANTIES OF ANY KIND, WHETHER EXPRESS OR IMPLIED, RELATING TO THE DELICIOUS\r\nSOFTWARE AND ANY DATA ACCESSED THEREFROM, OR THE ACCURACY, TIMELINESS,\r\nCOMPLETENESS, OR ADEQUACY OF THE DELICIOUS SOFTWARE AND ANY DATA ACCESSED\r\nTHEREFROM, INCLUDING THE IMPLIED WARRANTIES OF TITLE, MERCHANTABILITY,\r\nSATISFACTORY QUALITY, FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. \r\n \r\nTHE DELICIOUS SOFTWARE IS NOT DESIGNED, INTENDED OR LICENSED FOR USE IN\r\nHAZARDOUS ENVIRONMENTS REQUIRING FAIL-SAFE CONTROLS, INCLUDING WITHOUT\r\nLIMITATION, THE DESIGN, CONSTRUCTION, MAINTENANCE OR OPERATION OF NUCLEAR\r\nFACILITIES, AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL,\r\nAND LIFE SUPPORT OR WEAPONS SYSTEMS. DELICIOUS SPECIFICALLY DISCLAIMS ANY\r\nEXPRESS OR IMPLIED WARRANTY OF FITNESS FOR SUCH PURPOSES.\r\n \r\nIF THE DELICIOUS SOFTWARE OR ANY DATA ACCESSED THEREFROM PROVES DEFECTIVE, YOU\r\n(AND NOT THE DELICIOUS ENTITIES OR THE DELICIOUS LICENSORS) ASSUME THE ENTIRE\r\nCOST OF ALL REPAIR OR INJURY OF ANY KIND, EVEN IF THE DELICIOUS ENTITIES OR\r\nDELICIOUS LICENSORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH A DEFECT OR\r\nDAMAGES. SOME \r\nJURISDICTIONS DO NOT ALLOW RESTRICTIONS ON IMPLIED WARRANTIES SO SOME OF THESE\r\nLIMITATIONS MAY NOT APPLY TO YOU. \r\n \r\n6. Limitation of Liability. \r\n \r\nTHE DELICIOUS ENTITIES AND DELICIOUS LICENSORS WILL NOT BE LIABLE TO YOU FOR\r\nCLAIMS AND LIABILITIES OF ANY KIND ARISING OUT OF OR IN ANY WAY RELATED TO THE\r\nUSE OF THE DELICIOUS SOFTWARE BY YOURSELF OR BY THIRD PARTIES, TO THE USE OR\r\nNON-USE OF ANY BROKERAGE FIRM OR DEALER, OR TO THE SALE OR PURCHASE OF ANY\r\nSECURITY, WHETHER SUCH CLAIMS AND LIABILITIES ARE BASED ON ANY LEGAL OR\r\nEQUITABLE THEORY. \r\n \r\nTHE DELICIOUS ENTITIES AND DELICIOUS LICENSORS ARE NOT LIABLE TO YOU FOR ANY\r\nAND ALL DIRECT, INCIDENTAL, SPECIAL, INDIRECT, OR CONSEQUENTIAL DAMAGES ARISING\r\nOUT OF OR RELATED TO ANY THIRD-PARTY SOFTWARE, ANY DATA ACCESSED THROUGH THE\r\nDELICIOUS SOFTWARE, YOUR USE OR INABILITY TO USE OR ACCESS THE DELICIOUS\r\nSOFTWARE, OR ANY DATA PROVIDED THROUGH THE DELICIOUS SOFTWARE, WHETHER SUCH\r\nDAMAGE CLAIMS ARE BROUGHT UNDER ANY THEORY OF LAW OR EQUITY. DAMAGES EXCLUDED\r\nBY THIS CLAUSE INCLUDE, WITHOUT LIMITATION, THOSE FOR LOSS OF BUSINESS PROFITS,\r\nINJURY TO PERSON OR PROPERTY, BUSINESS INTERRUPTION, LOSS OF BUSINESS OR\r\nPERSONAL INFORMATION. SOME JURISDICTIONS DO NOT ALLOW LIMITATION OF INCIDENTAL\r\nOR CONSEQUENTIAL DAMAGES SO THIS \r\nRESTRICTION MAY NOT APPLY TO YOU. \r\n \r\nINFORMATION PROVIDED THROUGH THE DELICIOUS SOFTWARE, INCLUDING STOCK QUOTES,\r\nANALYSIS, MARKET INFORMATION, NEWS, AND FINANCIAL DATA, MAY BE DELAYED,\r\nINACCURATE, OR CONTAIN ERRORS OR OMISSIONS, AND THE DELICIOUS ENTITIES AND\r\nDELICIOUS LICENSORS WILL HAVE NO LIABILITY WITH RESPECT THERETO. DELICIOUS MAY\r\nCHANGE OR DISCONTINUE ANY ASPECT OR FEATURE OF THE DELICIOUS SOFTWARE OR THE\r\nUSE OF ALL OR ANY FEATURES OR TECHNOLOGY IN THE DELICIOUS SOFTWARE AT ANY TIME\r\nWITHOUT PRIOR NOTICE TO YOU, INCLUDING, BUT NOT LIMITED TO, CONTENT, HOURS OF\r\nAVAILABILITY. \r\n \r\n7. Indemnification. \r\n \r\nYou agree to indemnify and hold the MicroFarmer Entities harmless from any claim\r\nor demand, including reasonable attorneys'' fees, made by any third party in\r\nconnection with or arising out of your use of the MicroFarmer Software, your\r\nviolation of any terms or conditions of this Software License, your violation\r\nof applicable laws, or your violation of any rights of another person or\r\nentity. \r\n \r\n8. Government End Users. \r\n \r\nIf the MicroFarmer Software and related documentation are supplied to or\r\npurchased by or on behalf of the United States Government, then the MicroFarmer\r\nSoftware is deemed to be "commercial software" as that term is used in the\r\nFederal Acquisition Regulation system. Rights of the United States shall not\r\nexceed the minimum rights set forth in FAR 52.227-19 for "restricted computer\r\nsoftware." All other terms and conditions of this Software License apply. \r\n \r\n9. Controlling Law. \r\n \r\nThis Software License and the relationship between you and MicroFarmer is\r\ngoverned by the laws of the State of California without regard to its conflict\r\nof law provisions. You and MicroFarmer agree to submit to the personal and\r\nexclusive jurisdiction of the courts located within the county of Santa Clara,\r\nCalifornia. The United Nations Convention on the International Sale of Goods\r\ndoes not apply to this Software License. \r\n \r\n10. No General Waiver; Severability. \r\n \r\nThe failure of MicroFarmer to exercise or enforce any right or provision of this\r\nSoftware License shall not constitute a waiver of such right or provision. If\r\nany provision of this Software License is found by a court of competent\r\njurisdiction to be invalid, the parties nevertheless agree that the court\r\nshould endeavor to give effect to the parties'' intentions as reflected in the\r\nprovision, and the other provisions of this Software License remain in full\r\nforce and effect. \r\n \r\n11. Complete Agreement. \r\n \r\nThis Software License and the TOS constitute the entire understanding between\r\nthe parties respecting use of the MicroFarmer Software, superseding all prior\r\nagreements between you and MicroFarmer. In the event of any conflict between the\r\nterms and conditions of this Software License and those in the TOS, the terms\r\nand conditions of this Software License will control, except to the extent that\r\nthe TOS impose additional restrictions and liabilities on your actions. In the\r\nevent of a conflict between the terms of this Software License and the TOS,\r\nthis Software License will control to the extent of such conflict. \r\n \r\n12. Surviving Provisions. \r\n \r\nSections 1.b, 2, and 4 through 12, will survive any termination of this\r\nAgreement.', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(75, 'en-US', 'At microfarmer.org, we respect the privacy of the users of our website and services and are committed to protecting it. We have created this policy to demonstrate our commitment to you and to help you understand it.\r\n\r\nPlease Note: On December 09, 2005, microfarmer.org became part of the Yahoo! network of products and services. Information collected by microfarmer.org will continue to be subject to the microfarmer.org privacy policy, posted here. To learn more about how Yahoo! uses other information not collected on microfarmer.org please see read the Yahoo! Privacy Policy.\r\n\r\nWe may collect personal information, including email addresses, when individuals register to use the microfarmer.org website and services, post a link to the microfarmer.org website or submit questions, comments or bug reports. We may also, at times, collect our users'' IP addresses and information regarding our users'' use of our website and services. We may use such IP addresses to help diagnose problems with our servers, track movement within our website and, if necessary, deny service in accordance with our Terms of Service. We may also collect information related to the referring URL, access times and browser type. Unless required by law, we will not share our users'' personal information, Internet Protocol (IP) addresses and usage information, except with their consent or in aggregate or anonymous form, with third parties.\r\n\r\nIn order to offer and provide optimized and personalized services, we use cookies to store and sometimes track information about our users. A cookie is a small amount of data that is sent to a user''s browser from a web server and is eventually stored on a user''s computer hard drive.\r\n\r\nYahoo! uses web beacons to research certain usage and activities of the Yahoo! and microfarmer.org web sites. The information collected through these web beacons is used to find out more about our users, for more accurate reporting, improve the effectiveness of our marketing, and to make microfarmer.org better. No personally identifiable information from your microfarmer.org account is collected using these web beacons.\r\n\r\nOur services give you the opportunity to opt-in to receive communications from us. We will never automatically send you information/offers you do not want. You must choose to receive them.\r\n\r\nVisit your microfarmer.org Settings to edit your profile and other information. When you''re signed in, microfarmer.org page headers will include a link to Settings. You can delete your microfarmer.org account through your Settings.\r\n\r\nProtecting the privacy of the very young is important to us. For that reason, we will not collect age information for users under 18 years.\r\n\r\nmicrofarmer.org reserves the right to modify all or some of this Privacy Policy at any time without notice. If we change our Privacy Policy, we will post a notice on our website so our users are aware of what information we collect, how we use it, and under what circumstances, if any, we disclose it. We will use information only in accordance with the Privacy Policy under which the information was collected unless we have received explicit authorization from the appropriate user(s) to do otherwise.\r\n\r\nIf you have any questions about this Privacy Policy, the practices of this website or your dealings with this microfarmer.org, you can send an e-mail, in English, to privacy@microfarmer.org.\r\n\r\nEffective Date: January 18, 2005', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(76, 'en-US', '', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(77, 'en-US', '', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(78, 'en-US', '', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(79, 'en-US', '', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(80, 'en-US', 'Please be aware that this dictionary is designed for Firefox and Thunderbird versions that are not yet released. It WILL NOT WORK with Fx or Tb 1.5.0.* (if you don''t know what version you''re using, then it won''t work.) This dictionary is targeted at developers and testers of Firefox and Thunderbird 2 Alphas and Betas - if you are not one, please do not bother downloading it.\r\n\r\nCurrently free support is not available - paid support is available at AUS$100 per second.\r\n\r\nDistributed under the GNU General Public License - see license.txt for more details.', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(81, 'en-US', 'Please be aware that after a trial period of 30 minutes, you will have to pay to use this extension.', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(82, 'en-US', 'Please be aware that after a trial period of 30 minutes, you will have to pay to use this extension.', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(83, 'en-US', 'No support is available.', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(84, 'en-US', '', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(85, 'en-US', '', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(86, 'en-US', 'Harvest MicroFormats from web pages with the click of a button.', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(87, 'en-US', '', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(88, 'en-US', '', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(89, 'en-US', '', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(90, 'en-US', '', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(91, 'en-US', '', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(92, 'en-US', '', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(93, 'en-US', '', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(94, 'en-US', '', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(95, 'en-US', '', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(96, 'en-US', 'Thunderbird', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(97, 'en-US', 'Mozilla Suite', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(98, 'en-US', 'SeaMonkey', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(99, 'en-US', 'Nvu', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(100, 'en-US', 'Sunbird', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(101, 'en-US', 'Flock', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(102, 'en-US', 'Netscape', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(103, 'en-US', 'tb', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(104, 'en-US', 'mz Suite', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(105, 'en-US', 'zm', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(106, 'en-US', 'nv', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(107, 'en-US', 'sb', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(108, 'en-US', 'fl', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(109, 'en-US', 'ns', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(110, 'en-US', 'Test', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(111, 'en-US', 'Test canned response', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(112, 'en-US', 'Firefox', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(113, 'en-US', 'fx', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(114, 'en-US', 'ALL', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(115, 'en-US', '', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(116, 'en-US', 'BSD', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(117, 'en-US', 'bsd', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(118, 'en-US', 'Linux', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(119, 'en-US', 'linux', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(120, 'en-US', 'MacOSX', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(121, 'en-US', 'mac', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(122, 'en-US', 'Solaris', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(123, 'en-US', 'solaris', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(124, 'en-US', 'Windows', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(125, 'en-US', 'win', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(126, 'en-US', 'caption caption caption', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(127, 'en-US', 'fish fish fish', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(128, 'en-US', 'hunt hunt hunt', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(129, 'en-US', 'It works but not well.', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(130, 'en-US', 'This rocks.', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(131, 'en-US', '... my mismatched socks!', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(132, 'en-US', 'Horrible!', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(133, 'en-US', 'I am with stupid and don''t know how to use this.', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(134, 'en-US', 'This is soooo cool.', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(135, 'en-US', 'This is the one and only extension you could possibly ever need! It''s so wild, if it had a few more bits I would marry it.', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(136, 'en-US', 'My add-on of choice', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(137, 'en-US', 'This is my favorite add-on.', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(138, 'en-US', 'Fine, just fine.', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(139, 'de', 'XOXO-Unterst', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(139, 'en-US', 'Just added XOXO support! Enjoy!', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(140, 'en-US', 'Added trout support.', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(141, 'en-US', 'Added support for deer.', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(154, 'en-US', 'del.icio.us', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(155, 'en-US', 'Search through most bookmarked sites.', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(156, 'en-US', 'IMDB', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(157, 'en-US', 'The Internet Movie Database.', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(158, 'en-US', 'Wikipedia', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(159, 'en-US', 'The incredible free encyclopedia.', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(160, 'en-US', 'A9', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(161, 'en-US', 'Amazon''s A9 search engine.', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(162, 'en-US', 'Arts', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(163, 'en-US', 'General', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(164, 'en-US', 'Reference', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(165, 'en-US', 'Testo Collection Name', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(166, 'en-US', 'Testo Collection Description', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(167, 'en-US', 'FF Collection Name', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(168, 'en-US', 'FF Collection Description', '2007-02-11 17:58:10', '2007-02-11 17:58:10'),
+(42824, 'en-US', 'Slovar za slovenski jezik', '2007-01-28 12:09:53', NULL),
+(42825, 'en-US', 'http://mozilla.lugos.si/', '2007-01-28 12:09:53', NULL),
+(42826, 'en-US', 'Spell-checking dictionary for the Slovene language (GNU GPL licensed)\r\n\r\nSlovar za slovenski jezik (pod licenco GNU GPL)', '2007-01-28 12:09:53', NULL),
+(42827, 'en-US', 'Ta slovar temelji na slovarju, ustvarjenim za OpenOffice.org, katerega avtorji so:\r\nAmebis, d.o.o.\r\nTomaž Erjavec\r\nAle&scaron; Ko&scaron;ir\r\nPrimož Peterlin\r\nRobert Ludvik\r\n\r\nNa voljo je za Firefox 2.0+, Thunderbird 2.0+ in SeaMonkey 1.1. Za Thunderbird 1.5 si lahko namestite (isti) slovar za Ärkovalnik z naslova http://mozilla.lugos.si/thunderbird/slovar/', '2007-01-28 12:09:53', NULL),
+(42828, 'en-US', 'Spell-checking dictionary for the Slovene language (GNU GPL licensed)\r\n\r\nSlovar za slovenski jezik (pod licenco GNU GPL)', '2007-01-28 12:09:53', NULL),
+(42839, 'en-US', 'W&ouml;rterbuch &quot;Deutsch (Schweiz)&quot;', '2007-01-28 12:09:53', NULL),
+(42840, 'en-US', '', '2007-01-28 12:09:53', NULL),
+(42841, 'en-US', 'W&ouml;rterbuch f&uuml;r die Schweizer Variante der deutschen Sprache f&uuml;r die Rechtschreibpr&uuml;fung in Mozilla-Produkten\r\n\r\n(Swiss German dictionary for spellchecking in Mozilla products)', '2007-01-28 12:09:53', NULL),
+(42842, 'en-US', '', '2007-01-28 12:09:53', NULL),
+(42843, 'en-US', 'W&ouml;rterbuch f&uuml;r die Schweizer Variante der deutschen Sprache f&uuml;r die Rechtschreibpr&uuml;fung in Mozilla-Produkten\r\n\r\n(Swiss German dictionary for spellchecking in Mozilla products)', '2007-01-28 12:09:53', NULL),
+(42854, 'en-US', 'Polski slownik poprawnej pisowni', '2007-01-28 12:09:53', NULL),
+(42855, 'en-US', 'http://www.aviary.pl/', '2007-01-28 12:09:53', NULL),
+(42856, 'en-US', 'Polski sſownik poprawnej pisowni dla Firefoksa 2.0, Thunderbirda 2.0 i SeaMonkey 1.1.\r\n\r\nPolish spellcheck dictionary for Firefox 2.0, Thunderbird 2.0 and SeaMonkey 1.1.', '2007-01-28 12:09:53', NULL),
+(42857, 'en-US', 'To rozszerzenie zawiera slownik poprawnej pisowni opracowany przez zespol kurnik.pl pod kierunkiem Marka Futregi.\r\n\r\nStrona samego slownika: http://www.kurnik.pl/slownik/ort/', '2007-01-28 12:09:53', NULL),
+(42858, 'en-US', 'Polski sſownik poprawnej pisowni dla Firefoksa 2.0, Thunderbirda 2.0 i SeaMonkey 1.1.\r\n\r\nPolish spellcheck dictionary for Firefox 2.0, Thunderbird 2.0 and SeaMonkey 1.1.', '2007-01-28 12:09:53', NULL),
+(42859, 'en-US', 'Dizionario italiano', '2007-01-28 12:09:53', NULL),
+(42860, 'en-US', 'http://www.mozillaitalia.org', '2007-01-28 12:09:53', NULL),
+(42861, 'en-US', 'Aggiunge il dizionario italiano al controllo ortografico (adds italian dictionary for spell checker).\r\n\r\nIl pacchetto si basa sulla versione 2.3beta del 23/07/2006 del dizionario italiano realizzato dal progetto Linguistico.\r\nhttp://linguistico.sf.net/wiki\r\n\r\nIl dizionario &egrave; rilasciato sotto licenza GPL (inclusa nel pacchetto all''interno della cartella Leggimi).\r\n\r\nPer Thunderbird 1.5 visitare il sito www.mozillaitalia.org', '2007-01-28 12:09:53', NULL),
+(42862, 'en-US', '', '2007-01-28 12:09:53', NULL),
+(42863, 'en-US', 'Aggiunge il dizionario italiano al controllo ortografico (adds italian dictionary for spell checker).\r\n\r\nIl pacchetto si basa sulla versione 2.3beta del 23/07/2006 del dizionario italiano realizzato dal progetto Linguistico.\r\nhttp://linguistico.sf...', '2007-01-28 12:09:53', NULL),
+(42874, 'en-US', 'Diccionario espa&ntilde;ol Argentina', '2007-01-28 12:09:53', NULL),
+(42875, 'en-US', 'http://mozilla-arg.sourceforge.net', '2007-01-28 12:09:53', NULL),
+(42876, 'en-US', 'Diccionario espa&ntilde;ol para Argentina.\r\nSpanish dictionary for Argentina.', '2007-01-28 12:09:53', NULL),
+(42877, 'en-US', '', '2007-01-28 12:09:53', NULL),
+(42878, 'en-US', 'Diccionario espa&ntilde;ol para Argentina.\r\nSpanish dictionary for Argentina.', '2007-01-28 12:09:53', NULL),
+(42899, 'en-US', 'Svensk ordlista', '2007-01-28 12:09:53', NULL),
+(42900, 'en-US', '', '2007-01-28 12:09:53', NULL),
+(42901, 'en-US', 'En svensk r&auml;ttstavningsordlista f&ouml;r Firefox, Thunderbird och Seamonkey.\r\n\r\nSwedish spellchecking dictionary for Firefox, Thunderbird and Seamonkey.', '2007-01-28 12:09:53', NULL),
+(42902, 'en-US', '', '2007-01-28 12:09:53', NULL),
+(42903, 'en-US', 'En svensk r&auml;ttstavningsordlista f&ouml;r Firefox, Thunderbird och Seamonkey.\r\n\r\nSwedish spellchecking dictionary for Firefox, Thunderbird and Seamonkey.', '2007-01-28 12:09:53', NULL),
+(42909, 'en-US', 'Dictionnaire MySpell en Fran&ccedil;ais', '2007-01-28 12:09:53', NULL),
+(42910, 'en-US', '', '2007-01-28 12:09:53', NULL),
+(42911, 'en-US', 'Dictionnaire MySpell en Fran&ccedil;ais, pour Firefox 2.', '2007-01-28 12:09:53', NULL),
+(42912, 'en-US', '', '2007-01-28 12:09:53', NULL),
+(42913, 'en-US', 'Dictionnaire MySpell en Fran&ccedil;ais, pour Firefox 2.', '2007-01-28 12:09:53', NULL),
+(42949, 'en-US', 'Norsk Bokm&aring;l og Nynorsk ordliste', '2007-01-28 12:09:53', NULL),
+(42950, 'en-US', 'http://firefox.no', '2007-01-28 12:09:53', NULL),
+(42951, 'en-US', 'Norsk Bokm&aring;l og Nynorsk ordliste for Mozilla Firefox, Mozilla Thunderbird og SeaMonkey\r\n\r\nNorwegian Bokm&aring;l and Nynorsk dictionaries for Mozilla Firefox, Mozilla Thunderbird and SeaMonkey.', '2007-01-28 12:09:53', NULL),
+(42952, 'en-US', '', '2007-01-28 12:09:53', NULL),
+(42953, 'en-US', 'Norsk Bokm&aring;l og Nynorsk ordliste for Mozilla Firefox, Mozilla Thunderbird og SeaMonkey\r\n\r\nNorwegian Bokm&aring;l and Nynorsk dictionaries for Mozilla Firefox, Mozilla Thunderbird and SeaMonkey.', '2007-01-28 12:09:53', NULL),
+(42959, 'en-US', 'Deutsches W&ouml;rterbuch', '2007-01-28 12:09:53', NULL),
+(42960, 'en-US', '', '2007-01-28 12:09:53', NULL),
+(42961, 'en-US', 'Deutsches W&ouml;rterbuch (neue Rechtschreibung) f&uuml;r die Rechtschreibpr&uuml;fung in Mozilla-Produkten\r\n\r\n(German dictionary for spellchecking in Mozilla products)', '2007-01-28 12:09:53', NULL),
+(42962, 'en-US', '', '2007-01-28 12:09:53', NULL),
+(42963, 'en-US', 'Deutsches W&ouml;rterbuch (neue Rechtschreibung) f&uuml;r die Rechtschreibpr&uuml;fung in Mozilla-Produkten\r\n\r\n(German dictionary for spellchecking in Mozilla products)', '2007-01-28 12:09:53', NULL),
+(42969, 'en-US', 'Deutsches W&ouml;rterbuch, erweitert f&uuml;r &Ouml;sterreich', '2007-01-28 12:09:53', NULL),
+(42970, 'en-US', '', '2007-01-28 12:09:53', NULL),
+(42971, 'en-US', 'Deutsches W&ouml;rterbuch (neue Rechtschreibung), erweitert mit &ouml;sterreichischen W&ouml;rtern, f&uuml;r die Rechtschreibpr&uuml;fung in Mozilla-Produkten\r\n\r\n(German dictionary for spellchecking in Mozilla products, extended with Austrian words)', '2007-01-28 12:09:53', NULL),
+(42972, 'en-US', '', '2007-01-28 12:09:53', NULL),
+(42973, 'en-US', 'Deutsches W&ouml;rterbuch (neue Rechtschreibung), erweitert mit &ouml;sterreichischen W&ouml;rtern, f&uuml;r die Rechtschreibpr&uuml;fung in Mozilla-Produkten\r\n\r\n(German dictionary for spellchecking in Mozilla products, extended with Austrian words)', '2007-01-28 12:09:53', NULL),
+(43024, 'en-US', 'Litreoir GaelSpell do Mhozilla', '2007-01-28 12:09:54', NULL),
+(43025, 'en-US', 'http://borel.slu.edu/ispell/', '2007-01-28 12:09:54', NULL),
+(43026, 'en-US', 'Litreoir saor in aisce don Ghaeilge, cruthaithe ag Kevin Scannell.\r\n\r\nA free Irish spellchecker. ', '2007-01-28 12:09:54', NULL),
+(43027, 'en-US', '', '2007-01-28 12:09:54', NULL),
+(43028, 'en-US', 'Litreoir saor in aisce don Ghaeilge, cruthaithe ag Kevin Scannell.\r\n\r\nA free Irish spellchecker. ', '2007-01-28 12:09:54', NULL),
+(43064, 'en-US', 'English (Australian) Dictionary', '2007-01-28 12:09:54', NULL),
+(43065, 'en-US', 'http://justcameron.com/incoming/en-au-dictionary/', '2007-01-28 12:09:54', NULL),
+(43066, 'en-US', 'Are you sick of all your favo-U-rite colo-U-rful language being marked incorrect? Me too. Live no more in the world of crazy American spelling - get the Australian English Dictionary :)', '2007-01-28 12:09:54', NULL),
+(43067, 'en-US', 'Please be aware that this dictionary WILL NOT WORK with Fx or Tb 1.5.0.* (use Help -&gt; About Firefox to check what version you are using.) \r\n\r\nIf you are using an earlier version of Thunderbird, you can download more dictionaries through Tools -&gt; Options -&gt; Composition -&gt; Spelling -&gt; \r\nDownload More Dictionaries.\r\n\r\nCurrently free support is not available - paid support is available at AUS$100 per second.\r\n\r\nDistributed under the GNU General Public License - see license.txt for more details.', '2007-01-28 12:09:54', NULL),
+(43068, 'en-US', 'Are you sick of all your favo-U-rite colo-U-rful language being marked incorrect? Me too. Live no more in the world of crazy American spelling - get the Australian English Dictionary :)', '2007-01-28 12:09:54', NULL),
+(43284, 'en-US', 'Corrector para Portugu&ecirc;s Europeu', '2007-01-28 12:09:54', NULL),
+(43285, 'en-US', 'http://firefox.ansol.org/user-cgi/moin.cgi/', '2007-01-28 12:09:54', NULL),
+(43286, 'en-US', 'European Portuguese (pt-PT) Dictionary', '2007-01-28 12:09:54', NULL),
+(43287, 'en-US', '', '2007-01-28 12:09:54', NULL),
+(43288, 'en-US', 'European Portuguese (pt-PT) Dictionary', '2007-01-28 12:09:54', NULL),
+(43664, 'en-US', 'Verifica&ccedil;&atilde;o ortogr&aacute;fica pt-BR', '2007-01-28 12:09:55', NULL),
+(43665, 'en-US', 'http://br.mozdev.org/projeto/ortografia/', '2007-01-28 12:09:55', NULL),
+(43666, 'en-US', 'Dicion&aacute;rio portugu&ecirc;s brasileiro para o verificador ortogr&aacute;fico integrado do Firefox 2, Thunderbird 2 e SeaMonkey 1.1.', '2007-01-28 12:09:55', NULL),
+(43667, 'en-US', '', '2007-01-28 12:09:55', NULL),
+(43668, 'en-US', 'Dicion&aacute;rio portugu&ecirc;s brasileiro para o verificador ortogr&aacute;fico integrado do Firefox 2, Thunderbird 2 e SeaMonkey 1.1.', '2007-01-28 12:09:55', NULL),
+(43789, 'en-US', 'Nederlands Woordenboek', '2007-01-28 12:09:55', NULL),
+(43790, 'en-US', 'http://www.mozilla-nl.org', '2007-01-28 12:09:55', NULL),
+(43791, 'en-US', 'Dutch dictionary for spellchecking in Mozilla products.\r\n\r\nNederlands woordenboek voor spellingscontrole in Mozilla producten.', '2007-01-28 12:09:55', NULL),
+(43792, 'en-US', '', '2007-01-28 12:09:55', NULL),
+(43793, 'en-US', 'Dutch dictionary for spellchecking in Mozilla products.\r\n\r\nNederlands woordenboek voor spellingscontrole in Mozilla producten.', '2007-01-28 12:09:55', NULL),
+(44049, 'en-US', 'British English Dictionary', '2007-01-28 12:09:56', NULL),
+(44050, 'en-US', '', '2007-01-28 12:09:56', NULL),
+(44051, 'en-US', 'This extension packages David Bartlett''s British English Dictionary R1.19 for Firefox, Thunderbird and SeaMonkey.', '2007-01-28 12:09:56', NULL),
+(44052, 'en-US', 'Note that Spellchecking dictionaries for Thunderbird 1.5 are available at http://dictionaries.mozdev.org/installation.html', '2007-01-28 12:09:56', NULL),
+(44053, 'en-US', 'This extension packages David Bartlett''s British English Dictionary R1.19 for Firefox, Thunderbird and SeaMonkey.', '2007-01-28 12:09:56', NULL),
+(44064, 'en-US', 'Diccionari catal&agrave;', '2007-01-28 12:09:56', NULL),
+(44065, 'en-US', 'http://softcatala.org/wiki/Thunderbird:Corrector_ortogr%C3%A0fic', '2007-01-28 12:09:56', NULL),
+(44066, 'en-US', 'Free Catalan-Valencian spelling dictionary.\r\nDiccionari ortogr&agrave;fic lliure de la llengua catalana.', '2007-01-28 12:09:56', NULL),
+(44067, 'en-US', '', '2007-01-28 12:09:56', NULL),
+(44068, 'en-US', 'Free Catalan-Valencian spelling dictionary.\r\nDiccionari ortogr&agrave;fic lliure de la llengua catalana.', '2007-01-28 12:09:56', NULL),
+(44129, 'en-US', 'Hungarian Dictionary', '2007-01-28 12:09:56', NULL),
+(44130, 'en-US', '', '2007-01-28 12:09:56', NULL),
+(44131, 'en-US', 'This extension is based on L&aacute;szl&oacute; N&eacute;meth''s Hungarian Dictionary version 1.1.1 ( July 2006. ), working with Firefox 2 and above, Thunderbird and SeaMonkey.', '2007-01-28 12:09:56', NULL),
+(44132, 'en-US', '', '2007-01-28 12:09:56', NULL),
+(44133, 'en-US', 'This extension is based on L&aacute;szl&oacute; N&eacute;meth''s Hungarian Dictionary version 1.1.1 ( July 2006. ), working with Firefox 2 and above, Thunderbird and SeaMonkey.', '2007-01-28 12:09:56', NULL),
+(44139, 'en-US', 'Romanian Dictionary', '2007-01-28 12:09:56', NULL),
+(44140, 'en-US', '', '2007-01-28 12:09:56', NULL),
+(44141, 'en-US', 'This extension is based on L. Constantin''s Romanian Dictionary version January 2006., working with Firefox, Thunderbird and SeaMonkey.', '2007-01-28 12:09:56', NULL),
+(44142, 'en-US', '', '2007-01-28 12:09:56', NULL),
+(44143, 'en-US', 'This extension is based on L. Constantin''s Romanian Dictionary version January 2006., working with Firefox, Thunderbird and SeaMonkey.', '2007-01-28 12:09:56', NULL),
+(44154, 'en-US', 'Czech spell checking dictionary', '2007-01-28 12:09:56', NULL),
+(44155, 'en-US', 'http://www.czilla.cz/doplnky/kontrola-pravopisu/', '2007-01-28 12:09:56', NULL),
+(44156, 'en-US', 'Czech spell checking dictionary for Mozilla applications is based on the OpenOffice.org dictionary that is based on the Ispell dictionary created by Petr Kol&aacute;Å¿. The ascii version was creted using the perl script by JindÅ¿ich MakoviÄka.', '2007-01-28 12:09:56', NULL),
+(44157, 'en-US', '', '2007-01-28 12:09:56', NULL),
+(44158, 'en-US', 'Czech spell checking dictionary for Mozilla applications is based on the OpenOffice.org dictionary that is based on the Ispell dictionary created by Petr Kol&aacute;Å¿. The ascii version was creted using the perl script by JindÅ¿ich MakoviÄka.', '2007-01-28 12:09:56', NULL),
+(44329, 'en-US', 'Greek Spelling dictionary', '2007-01-28 12:09:56', NULL),
+(44330, 'en-US', 'http://elspell.math.upatras.gr/', '2007-01-28 12:09:56', NULL),
+(44331, 'en-US', 'Greek spellchecking dictionary for Mozilla applications is based on the OpenOffice.org dictionary that is based on the Ispell dictionary created by Evripidis Papakostas and Steve Stavropoulos and licensed under GPL/MPL/LGPL', '2007-01-28 12:09:56', NULL),
+(44332, 'en-US', '', '2007-01-28 12:09:56', NULL),
+(44333, 'en-US', 'Greek spellchecking dictionary for Mozilla applications is based on the OpenOffice.org dictionary that is based on the Ispell dictionary created by Evripidis Papakostas and Steve Stavropoulos and licensed under GPL/MPL/LGPL', '2007-01-28 12:09:56', NULL),
+(44359, 'en-US', 'Dictionnaire MySpell en Fran&ccedil;ais (r&eacute;forme 1990)', '2007-01-28 12:09:56', NULL),
+(44360, 'en-US', '', '2007-01-28 12:09:56', NULL),
+(44361, 'en-US', 'Dictionnaire MySpell en Fran&ccedil;ais, r&eacute;forme 1990, pour Firefox 2.', '2007-01-28 12:09:56', NULL),
+(44362, 'en-US', '', '2007-01-28 12:09:56', NULL),
+(44363, 'en-US', 'Dictionnaire MySpell en Fran&ccedil;ais, r&eacute;forme 1990, pour Firefox 2.', '2007-01-28 12:09:56', NULL),
+(44389, 'en-US', 'English - Greek Spelling dictionary', '2007-01-28 12:09:56', NULL),
+(44390, 'en-US', '', '2007-01-28 12:09:56', NULL),
+(44391, 'en-US', 'English-Greek spell-checking dictionary for Firefox, Mozilla thunderbird and Seamonkey mail for easier spell checking in bilingual text.If you need better spelling results try the respective stand-alone dictionaries.\r\n', '2007-01-28 12:09:56', NULL),
+(44392, 'en-US', '', '2007-01-28 12:09:56', NULL),
+(44393, 'en-US', 'English-Greek spell-checking dictionary for Firefox, Mozilla thunderbird and Seamonkey mail for easier spell checking in bilingual text.If you need better spelling results try the respective stand-alone dictionaries.\r\n', '2007-01-28 12:09:56', NULL),
+(44574, 'en-US', 'United States English Dictionary', '2007-01-28 12:09:57', NULL),
+(44575, 'en-US', 'http://www.blogzilla.info/spellchecker/', '2007-01-28 12:09:57', NULL),
+(44576, 'en-US', 'English United States (en-US) spellchecking dictionary.\r\n\r\nThis extension packages a subset of the original\r\nEnglish wordlist created by Kevin Atkinson for Pspell \r\nand Aspell and thus is covered by his original \r\nLGPL license. The affix file is a heavily modified\r\nversion of the original english.aff file which was\r\nreleased as part of Geoff Kuenning''s Ispell and as \r\nsuch is covered by his BSD license.\r\n\r\nThanks to both authors for their wonderful work.', '2007-01-28 12:09:57', NULL),
+(44577, 'en-US', 'This spellchecker is for Fx 2 (all languages excluding en-US) only, because Fx 1.5.0.* doesn''t support a direct spellchecking. If you want to add this functionality to your copy of Fx 1.5.0.* you must install SpellBound extension: http://spellbound.sourceforge.net/install\r\n\r\nFor Thunderbird 1.5 look at http://dictionaries.mozdev.org/installation.html\r\nThunderbird 2 en-US doesn''t need to install this spellchecker.\r\n\r\nI would remember to everybody that this extension provides only an United States English spellchecker, so if you''re instead looking for a British English spellchecker, you can get it from https://addons.mozilla.org/firefox/3366/\r\n\r\nPlease, _DO NOT_ ask for support here. If you need support, post your question to http://forums.mozillazine.org or to http://forum.mozillaitalia.org', '2007-01-28 12:09:57', NULL),
+(44578, 'en-US', 'English United States (en-US) spellchecking dictionary.\r\n\r\nThis extension packages a subset of the original\r\nEnglish wordlist created by Kevin Atkinson for Pspell \r\nand Aspell and thus is covered by his original \r\nLGPL license. The affix file is...', '2007-01-28 12:09:57', NULL),
+(44784, 'en-US', 'Diccionario de Espa&ntilde;ol/Espa&ntilde;a', '2007-01-28 12:09:57', NULL),
+(44785, 'en-US', '', '2007-01-28 12:09:57', NULL),
+(44786, 'en-US', 'Diccionario de Espa&ntilde;ol/Espa&ntilde;a (for use with Firefox 2.0, Thunderbird 2.0a1 and SeaMonkey 1.1a)\r\n\r\nLa versi&oacute;n 1.1 se corresponde con el empaquetado de la versi&oacute;n 0.1 del diccionario de OpenOffice.org disponible en http://ftp.services.openoffice.org/pub/OpenOffice.org/contrib/dictionaries/es_ES.zip, desarrollado inicialmente por Santiago Bosio y ligeramente modificado.\r\nSupone una mejora importante sobre la versi&oacute;n anterior.\r\n\r\nRelease 1.1 is the repackaging of the release 0.1 of the dictionary available at http://ftp.services.openoffice.org/pub/OpenOffice.org/contrib/dictionaries/es_ES.zip, initially developed by Santiago Bosio and slightly modified.\r\nIt''s a very important upgrade over the previous version.', '2007-01-28 12:09:57', NULL),
+(44787, 'en-US', 'Please, read the compatibility information before complaining or ranting about compatibility issues.', '2007-01-28 12:09:57', NULL),
+(44788, 'en-US', 'Diccionario de Espa&ntilde;ol/Espa&ntilde;a (for use with Firefox 2.0, Thunderbird 2.0a1 and SeaMonkey 1.1a)\r\n\r\nLa versi&oacute;n 1.1 se corresponde con el empaquetado de la versi&oacute;n 0.1 del diccionario de OpenOffice.org disponible en...', '2007-01-28 12:09:57', NULL),
+(44924, 'en-US', 'Dansk ordbog - Danish Dictionary', '2007-01-28 12:09:57', NULL),
+(44925, 'en-US', 'http://da.speling.org/', '2007-01-28 12:09:57', NULL),
+(44926, 'en-US', 'Dansk ordbog til Firefox 2.0 og Thunderbird 2.0.\r\n\r\nDen Store Danske Ordliste udgivet af SSLUG.\r\n\r\nThe Comprehensive Danish Dictionary by SSLUG.', '2007-01-28 12:09:57', NULL),
+(44927, 'en-US', '', '2007-01-28 12:09:57', NULL),
+(44928, 'en-US', 'Dansk ordbog til Firefox 2.0 og Thunderbird 2.0.\r\n\r\nDen Store Danske Ordliste udgivet af SSLUG.\r\n\r\nThe Comprehensive Danish Dictionary by SSLUG.', '2007-01-28 12:09:57', NULL),
+(45024, 'en-US', 'Bulgarian Dictionary', '2007-01-28 12:09:57', NULL),
+(45025, 'en-US', 'http://moz.emyto.net/spellchecker/', '2007-01-28 12:09:57', NULL),
+(45026, 'en-US', 'Bulgarian (bg-BG) spellchecking dictionary', '2007-01-28 12:09:57', NULL),
+(45027, 'en-US', '', '2007-01-28 12:09:57', NULL),
+(45028, 'en-US', 'Bulgarian (bg-BG) spellchecking dictionary', '2007-01-28 12:09:57', NULL),
+(45044, 'en-US', 'Croatian Dictionary - Hrvatski RjeÄnik', '2007-01-28 12:09:57', NULL),
+(45045, 'en-US', '', '2007-01-28 12:09:57', NULL),
+(45046, 'en-US', 'Croatian spell checking dictionary for Firefox 2.0 is based on the OpenOffice.org Croatian dictionary (hrvatski) created by Denis Lackovic (delacko@linux.hr) and licensed under LGPL/SISSL', '2007-01-28 12:09:57', NULL),
+(45047, 'en-US', '', '2007-01-28 12:09:57', NULL),
+(45048, 'en-US', 'Croatian spell checking dictionary for Firefox 2.0 is based on the OpenOffice.org Croatian dictionary (hrvatski) created by Denis Lackovic (delacko@linux.hr) and licensed under LGPL/SISSL', '2007-01-28 12:09:57', NULL),
+(45104, 'en-US', 'Icelandic dictionary for Firefox 2.0 spell checker', '2007-01-28 12:09:58', NULL),
+(45105, 'en-US', 'www.kalfur.com', '2007-01-28 12:09:58', NULL),
+(45106, 'en-US', 'Icelandic dictionary for Firefox 2.0 spell checker', '2007-01-28 12:09:58', NULL),
+(45107, 'en-US', '', '2007-01-28 12:09:58', NULL),
+(45108, 'en-US', 'Icelandic dictionary for Firefox 2.0 spell checker', '2007-01-28 12:09:58', NULL),
+(45119, 'en-US', 'Hebrew spell-checking dictionary (from HSpell)', '2007-01-28 12:09:58', NULL),
+(45120, 'en-US', 'http://ivrix.org.il/projects/spell-checker/', '2007-01-28 12:09:58', NULL),
+(45121, 'en-US', 'Hebrew spell-checking dictionary for Firefox and Thunderbird. Generated from data of the HSpell project version 1.0, and distributed freely under the GPL.', '2007-01-28 12:09:58', NULL),
+(45122, 'en-US', 'The Hebrew dictionary is rather big, and slow to load; worse, Firefox may freeze for few seconds while it is loading.\r\nThis is due to Hebrew having plenty inflections for most words.\r\n\r\nThe dictionary is taken from HSpell, the free Hebrew spell-checker, by Nadav Har''El and Dan Kenigsberg.', '2007-01-28 12:09:58', NULL),
+(45123, 'en-US', 'Hebrew spell-checking dictionary for Firefox and Thunderbird. Generated from data of the HSpell project version 1.0, and distributed freely under the GPL.', '2007-01-28 12:09:58', NULL),
+(45149, 'en-US', 'Canadian English Dictionary', '2007-01-28 12:09:58', NULL),
+(45150, 'en-US', 'http://www2.cs.uregina.ca/~schmpaul/firefox/', '2007-01-28 12:09:58', NULL),
+(45151, 'en-US', 'For some reason, Mozilla doesn''t have a Canadian localization team, but I know that even the British dictionary doesn''t quite cut it for the truly patriotic. This extension adds Canadian English to the spell check languages available under the latest Mozilla products.\r\n\r\nSee my homepage for information about the public domain word lists, and for a quick guide on how to use spelling in Firefox 2.0\r\n\r\nA Canadian dictionary for Thunderbird 1.5 and Mozilla Suite is available here:\r\nhttp://www.mozilla.com/en-US/thunderbird/dictionaries.html\r\n\r\nIf you have any questions or problems, please send me an email.', '2007-01-28 12:09:58', NULL),
+(45152, 'en-US', '', '2007-01-28 12:09:58', NULL),
+(45153, 'en-US', 'For some reason, Mozilla doesn''t have a Canadian localization team, but I know that even the British dictionary doesn''t quite cut it for the truly patriotic. This extension adds Canadian English to the spell check languages available under the...', '2007-01-28 12:09:58', NULL),
+(45239, 'en-US', 'Arabic spell-checking dictionary', '2007-01-28 12:09:58', NULL),
+(45240, 'en-US', 'https://sourceforge.net/projects/arabic-spell/', '2007-01-28 12:09:58', NULL),
+(45241, 'en-US', 'Arabic spell-checking dictionary for Firefox and Thunderbird. Generated by Google''s Ethan Bradford and Gokalp Yapici from data of the Tim Buckwalter Arabic Morphological Analyzer v1.0.\r\n\r\nNote: this extension is slow to load, and may freeze Firefox for few seconds. It takes some 50Mb of RAM when running.', '2007-01-28 12:09:58', NULL),
+(45242, 'en-US', '', '2007-01-28 12:09:58', NULL),
+(45243, 'en-US', 'Arabic spell-checking dictionary for Firefox and Thunderbird. Generated by Google''s Ethan Bradford and Gokalp Yapici from data of the Tim Buckwalter Arabic Morphological Analyzer v1.0.\r\n\r\nNote: this extension is slow to load, and may freeze...', '2007-01-28 12:09:58', NULL),
+(45274, 'en-US', 'Esperanta Vortaro', '2007-01-28 12:09:58', NULL),
+(45275, 'en-US', 'http://www.myjavaserver.com/~eiriarte/', '2007-01-28 12:09:58', NULL),
+(45276, 'en-US', 'English:\r\nThis is an Esperanto dictionary for Mozilla Firefox. It''s based on the Esperanto dictionary for OpenOffice.org. Here is the original note in that dictionary:\r\n\r\nEsperanto:\r\nÄ¿i tio estas Esperanta vortaro por Mozilla Firefox. Ä¿i estas bazita sur la Esperanta literumilo por OpenOffice.org. Jen la originala noto en tiu literumilo:\r\n\r\n---\r\nPriskribo\r\n\r\nÄ¿i tio estas esperanta literumilo por OpenOffice.org en la MySpell-formato. Ä¿i estas kreita surbaze de la literumilo por ISpell fare de Sergio Pokrovskij. En la MySpell-formaton tradukis Dmitri Gabinski.\r\n\r\nDisvastigo\r\n\r\nÄ¿i tiu literumilo estas disvastigata laÅ­ la GNU-a Äenerala publika permesilo (Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA).\r\n\r\nThis spellchecker is available on the terms of GNU General Public License (Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA).\r\n', '2007-01-28 12:09:58', NULL),
+(45277, 'en-US', '', '2007-01-28 12:09:58', NULL),
+(45278, 'en-US', 'English:\r\nThis is an Esperanto dictionary for Mozilla Firefox. It''s based on the Esperanto dictionary for OpenOffice.org. Here is the original note in that dictionary:\r\n\r\nEsperanto:\r\nĿi tio estas Esperanta vortaro por Mozilla Firefox. Ŀi estas...', '2007-01-28 12:09:58', NULL),
+(45349, 'en-US', 'Russian spellchecking dictionary with IO support', '2007-01-28 12:09:58', NULL),
+(45350, 'en-US', 'http://www.mozilla-russia.org', '2007-01-28 12:09:58', NULL),
+(45351, 'en-US', 'Russian spellchecking dictionary with IO support.\r\nBased on dictionary package created for MySpell spell checker by Alexander Lebedev.\r\n\r\nСловаѿѿ подгоѿовлен в ѿамкаѿ подпѿоекѿа OpenOffice:Lingucomponent:Spell Checking / Dictionaries. Содеѿжимое Ñѿого ÑÐ»Ð¾Ð²Ð°Ñ¿Ñ Ð½Ð¸Ñ¿ÐµÐ¼ не оѿлиѿаеѿÑÑ Ð¾Ñ¿ оѿѿогѿаѿиѿеÑкого ÑловаѿÑ, ѿазѿабоѿанного Ð´Ð»Ñ ispell ÐлекÑандѿом пебедевѿм. по Ñѿѿи, Ñѿо ѿоѿ же Ñловаѿѿ, в коѿоѿом набоѿ Ñлов и affix-ѿайл пѿедÑѿавленѿ в виде, пѿигодном Ð´Ð»Ñ Ð¾Ð±Ñ¿Ð°Ð±Ð¾Ñ¿ÐºÐ¸ myspell. пѿи Ñбоѿке наÑѿоÑѿего пакеѿа иÑполѿзован набоѿ Ñлов и affix-ѿайл из пакеѿа rus-ispell.tar.gz веѿÑии 0.99f4, Ñодеѿжаѿего Ñвѿѿе 122 Ñ¿Ñ¿ÑÑÑ¿ базовѿѿ Ñлов и более 1.168 миллиона Ñловоѿоѿм. пѿи подгоѿовке affix-ѿайла Ñ¿Ñ¿ÑÑкого ÑÐ»Ð¾Ð²Ð°Ñ¿Ñ Ð´Ð»Ñ MySpell пѿинÑли ѿѿаÑѿие Ðнаѿолий пиѿÑанов, ÐлекÑандѿ ', '2007-01-28 12:09:58', NULL),
+(45352, 'en-US', '', '2007-01-28 12:09:58', NULL),
+(45353, 'en-US', 'Russian spellchecking dictionary with IO support.\r\nBased on dictionary package created for MySpell spell checker by Alexander Lebedev.\r\n\r\nСловаѿѿ подгоѿовлен в ѿамкаѿ подпѿоекѿа OpenOffice:Lingucomponent:Spell...', '2007-01-28 12:09:58', NULL),
+(45399, 'en-US', 'Lithuanian spellchecking dictionary &ndash; Lietuvių kalbos ra&scaron;ybos tikrinimo žodynas', '2007-01-28 12:09:58', NULL),
+(45400, 'en-US', 'http://files.akl.lt/ispell-lt/', '2007-01-28 12:09:58', NULL),
+(45401, 'en-US', 'Lithuanian spellchecking dictionary for Mozilla applications. Contains dictionaries created by ispell-lt project (http://files.akl.lt/ispell-lt/).\r\n\r\nLietuvių kalbos ra&scaron;ybos tikrinimo žodynas Mozilla programoms. Supakuotas i&scaron; ispell-lt (http://files.akl.lt/ispell-lt/) projekto sukurtų žodynų.', '2007-01-28 12:09:58', NULL),
+(45402, 'en-US', '', '2007-01-28 12:09:58', NULL),
+(45403, 'en-US', 'Lithuanian spellchecking dictionary for Mozilla applications. Contains dictionaries created by ispell-lt project (http://files.akl.lt/ispell-lt/).\r\n\r\nLietuvių kalbos ra&scaron;ybos tikrinimo žodynas Mozilla programoms. Supakuotas i&scaron...', '2007-01-28 12:09:58', NULL),
+(45504, 'en-US', 'Geiriadur Cymraeg', '2007-01-28 12:09:58', NULL),
+(45505, 'en-US', '', '2007-01-28 12:09:58', NULL),
+(45506, 'en-US', 'Welsh-language dictionary. Source files taken from OpenOffice, under GPL, and copyright Canolfan Bedwyr, University of Wales, Bangor.', '2007-01-28 12:09:58', NULL),
+(45507, 'en-US', '', '2007-01-28 12:09:58', NULL),
+(45508, 'en-US', 'Welsh-language dictionary. Source files taken from OpenOffice, under GPL, and copyright Canolfan Bedwyr, University of Wales, Bangor.', '2007-01-28 12:09:58', NULL),
+(45704, 'en-US', 'Latvie&scaron;u valodas pareizrakstÄ«bas pÄrbaudes vÄrdnÄ«ca', '2007-01-28 12:09:59', NULL),
+(45705, 'en-US', 'http://openoffice-lv.sourceforge.net/openoffice.html', '2007-01-28 12:09:59', NULL),
+(45706, 'en-US', 'Latvian spellcheck dictionary', '2007-01-28 12:09:59', NULL),
+(45707, 'en-US', '', '2007-01-28 12:09:59', NULL),
+(45708, 'en-US', 'Latvian spellcheck dictionary', '2007-01-28 12:09:59', NULL),
+(45844, 'en-US', 'Glosar rom&acirc;nesc / Rom&acirc;nia', '2007-01-28 12:09:59', NULL),
+(45845, 'en-US', '', '2007-01-28 12:09:59', NULL),
+(45846, 'en-US', 'Glosar rom&acirc;nesc / Rom&acirc;nia', '2007-01-28 12:09:59', NULL),
+(45847, 'en-US', 'Glosar rom&acirc;nesc / Rom&acirc;nia (for use with Firefox 2.0, Thunderbird 2.0a1 and SeaMonkey 1.1a).\r\n\r\nRelease 1.0 is the repackaging of the Romanian dictionary available at http://ftp.services.openoffice.org/pub/OpenOffice.org/contrib/dictionaries/ro_RO.zip, initially developed by Mihai Budiu and slightly modified.\r\n\r\nThanks to tnarik, the author of the Spanish dictionary:\r\nthis glossary was made by replacing some text and files in his release. ', '2007-01-28 12:09:59', NULL),
+(45848, 'en-US', 'Glosar rom&acirc;nesc / Rom&acirc;nia', '2007-01-28 12:09:59', NULL),
+(45879, 'en-US', 'Suomen kielen oikoluku', '2007-01-28 12:09:59', NULL),
+(45880, 'en-US', 'http://www.mozilla.fi/wiki/Suomen_kielen_oikoluku', '2007-01-28 12:09:59', NULL),
+(45881, 'en-US', ' * * * * * * * * * * * * * * * * * *\r\nHUOM HUOM!:Laajennuksen piirteiden takia Firefox ja Thunderbird t&auml;ytyy k&auml;ynnist&auml;&auml; laajennuksen j&auml;lkeen KAHDESTI ennen kuin oikolukusanasto toimii.\r\n * * * * * * * * * * * * * * * * * *\r\n\r\nLUE MY&Ouml;S SEURAAVA KAPPALE!\r\n\r\nSamoin Firefox ja Thunderbird t&auml;ytyy k&auml;ynnist&auml;&auml; ohjelmap&auml;ivityksen tai mink&auml; tahansa laajennuksen asennuksen, p&auml;ivityksen tai poistamisen j&auml;lkeen kahdesti, jotta oikoluku on j&auml;lleen toiminnassa. Lue lis&auml;tietoja kotisivulta.\r\n\r\nLaajennus k&auml;ytt&auml;&auml; oletuksena suljetun l&auml;hdekoodin (ilmaista) Soikko-oikolukijaa, mutta tukee my&ouml;s avoimen l&auml;hdekoodin Voikko-oikolukijaa. Lue lis&auml;tietoja laajennuksen kotisivulta.\r\n\r\nLaajennus toimii vain Thunderbird 2.0:n esiversioilla. Thunderbirdin 1.5.x versiolle on oikoluku t&auml;m&auml;n laajennuksen kotisivulla.\r\n\r\nLaajennus on ik&auml;v&auml; kyll&auml; saatavilla vain Windowsille ja Linuxille.\r\n\r\n---\r\n\r\nFinnish Spellchecker using the (closed source, but free) Soikko spellchecker. This extension also supports the open source Voikko spellchecker if it is installed on the system.\r\n\r\nTo work, this extension requires a DOUBLE RESTART of Firefox/Thunderbird every time an extension or the program itself is installed, updated or removed. Including this extension.\r\n\r\nThis extension is unfortunately available only for Windows and Linux.', '2007-01-28 12:09:59', NULL),
+(45882, 'en-US', '', '2007-01-28 12:09:59', NULL),
+(45883, 'en-US', ' * * * * * * * * * * * * * * * * * *\r\nHUOM HUOM!:Laajennuksen piirteiden takia Firefox ja Thunderbird t&auml;ytyy k&auml;ynnist&auml;&auml; laajennuksen j&auml;lkeen KAHDESTI ennen kuin oikolukusanasto toimii.\r\n * * * * * * * * * * * * * * * * *...', '2007-01-28 12:09:59', NULL),
+(46419, 'en-US', 'Upper Sorbian spelling dictionary', '2007-01-28 12:10:00', NULL),
+(46420, 'en-US', '', '2007-01-28 12:10:00', NULL),
+(46421, 'en-US', 'Upper Sorbian dictionary for use with the Mozilla spellchecker.\r\n\r\nSÅ¿ownik hornjoserb&scaron;Ä¿iny - prawopisna korektura za Mozilla.\r\n\r\nUpstream author: Prof. Dr. Eduard Werner\r\nLicense: GNU General Public License (version 2 or later)', '2007-01-28 12:10:00', NULL),
+(46422, 'en-US', 'Upper Sorbian is a minority language spoken in Upper Lusatia (Saxony) in the eastern part of Germany.', '2007-01-28 12:10:00', NULL),
+(46423, 'en-US', 'Upper Sorbian dictionary for use with the Mozilla spellchecker.\r\n\r\nSÅ¿ownik hornjoserb&scaron;Ä¿iny - prawopisna korektura za Mozilla.\r\n\r\nUpstream author: Prof. Dr. Eduard Werner\r\nLicense: GNU General Public License (version 2 or later)', '2007-01-28 12:10:00', NULL),
+(46684, 'en-US', 'Xuxen III EDBL', '2007-01-28 12:10:01', NULL),
+(46685, 'en-US', '', '2007-01-28 12:10:01', NULL),
+(46686, 'en-US', 'Xuxen III EDBL euskarazko hiztegia. Basque dictionary.', '2007-01-28 12:10:01', NULL),
+(46687, 'en-US', '', '2007-01-28 12:10:01', NULL),
+(46688, 'en-US', 'Xuxen III EDBL euskarazko hiztegia. Basque dictionary.', '2007-01-28 12:10:01', NULL),
+(46689, 'en-US', 'Adds a context menu entry to show the menubar. This is really cool!', '2007-02-11 18:18:48', '2007-02-11 18:35:32'),
+(46690, 'en-US', '', '2007-02-11 18:18:48', NULL),
+(46691, 'de', 'http://www.gijsk.com/', '2007-02-11 18:22:17', '2007-02-11 18:35:33'),
+(46691, 'en-US', 'http://www.gijsk.com/', '2007-02-11 18:18:48', '2007-02-11 18:35:32'),
+(46692, 'de', 'Erschein menu', '2007-02-11 18:22:17', '2007-02-11 18:35:33'),
+(46692, 'en-US', 'Show Menubar', '2007-02-11 18:18:48', '2007-02-11 18:35:32'),
+(46693, 'en-US', '', '2007-02-11 18:18:48', NULL),
+(46694, 'de', 'Macht ein context-menu item dass die menubar anzeige. Or something.', '2007-02-11 18:22:17', '2007-02-11 18:35:33'),
+(46694, 'en-US', 'Adds a context menu entry to show the menubar.', '2007-02-11 18:18:48', '2007-02-11 18:35:32'),
+(46695, 'en-US', '', '2007-02-11 18:20:30', NULL),
+(46696, 'de', 'Zeige Menu Bar', '2007-02-11 18:24:19', NULL),
+(46696, 'en-US', 'Show Menu Bar', '2007-02-11 18:24:19', NULL),
+(46697, 'de', 'Lets you take a peek at the files under the hood of your Firefox installation and profile', '2007-02-11 18:40:03', '2007-02-11 19:25:13'),
+(46697, 'en-US', 'Lets you take a peek at the files under the hood of your Firefox installation and profile', '2007-02-11 19:24:26', '2007-02-11 19:25:13'),
+(46698, 'de', '', '2007-02-11 18:40:03', '2007-02-11 18:49:14'),
+(46698, 'en-US', '', '2007-02-11 19:24:26', NULL),
+(46699, 'de', 'http://www.gijsk.com/', '2007-02-11 18:40:03', '2007-02-11 19:25:13'),
+(46699, 'en-US', 'http://www.gijsk.com/', '2007-02-11 19:24:26', '2007-02-11 19:25:13'),
+(46700, 'de', 'Chrome List', '2007-02-11 18:40:03', '2007-02-11 19:25:13'),
+(46700, 'en-US', 'Chrome List', '2007-02-11 19:24:26', '2007-02-11 19:25:13'),
+(46701, 'de', '', '2007-02-11 18:40:03', '2007-02-11 18:49:14'),
+(46701, 'en-US', '', '2007-02-11 19:24:26', NULL),
+(46702, 'de', 'Lets you take a peek at the files under the hood of your Firefox installation and profile', '2007-02-11 18:40:03', '2007-02-11 19:25:13'),
+(46702, 'en-US', 'Lets you take a peek at the files under the hood of your Firefox installation and profile', '2007-02-11 19:24:26', '2007-02-11 19:25:13'),
+(46703, 'de', '', '2007-02-11 18:49:18', NULL),
+(46704, 'en-US', 'Wooo', '2007-02-11 19:01:40', '2007-02-11 19:02:30'),
+(46705, 'en-US', 'Baaaaaa!', '2007-02-11 19:01:40', '2007-02-11 19:02:30'),
+(46706, 'en-US', 'Fooobar', '2007-02-11 19:25:09', '2007-02-11 19:25:13'),
+(46707, 'en-US', 'Defend your firefox installation from tikbalangs! It really works!', '2007-02-12 22:16:36', '2007-02-12 22:16:48'),
+(46708, 'en-US', '', '2007-02-12 22:16:36', '2007-02-12 22:16:48'),
+(46709, 'en-US', 'http://addons.mozilla.org', '2007-02-12 22:16:36', '2007-02-12 22:16:48'),
+(46710, 'en-US', 'MicroDefender', '2007-02-12 22:16:36', '2007-02-12 22:16:48'),
+(46711, 'en-US', '', '2007-02-12 22:16:36', '2007-02-12 22:16:48'),
+(46712, 'en-US', 'pew pew, pew pew', '2007-02-12 22:16:36', '2007-02-12 22:16:48'),
+(46713, 'de', '', '2007-02-12 22:16:48', NULL),
+(46713, 'en-US', 'This version adds significantly more pew', '2007-02-12 22:16:44', '2007-02-12 22:16:48'),
+(46713, 'es-ES', '', '2007-02-12 22:16:48', NULL),
+(46713, 'fr', '', '2007-02-12 22:16:48', NULL),
+(46713, 'ja', '', '2007-02-12 22:16:48', NULL),
+(46713, 'ko', '', '2007-02-12 22:16:48', NULL),
+(46713, 'ru', '', '2007-02-12 22:16:48', NULL),
+(46713, 'sk', '', '2007-02-12 22:16:49', NULL),
+(46714, 'en-US', 'Not true!', '2007-07-24 05:19:25', NULL),
+(46715, 'en-US', 'Of course this is not right. Actually, my extension sucks.', '2007-07-24 05:19:25', NULL);
+
+--
+-- Dumping data for table `translations_seq`
+--
+
+INSERT INTO `translations_seq` (`id`) VALUES
+(46715);
+
+
+--
+-- Dumping data for table `userevents`
+--
+
+
+--
+-- Dumping data for table `users`
+--
+
+INSERT INTO `users` (`id`, `email`, `password`, `firstname`, `lastname`, `nickname`, `emailhidden`, `sandboxshown`, `homepage`, `confirmationcode`, `created`, `modified`, `notes`) VALUES
+(1, 'testing@justcameron.com', 'testing', 'Cameron', 'R', '', 0, 0, '', 'logmein', '2006-08-22 00:07:32', '2006-09-05 00:26:01', 'First user! woot!'),
+(2, 'fligtar@gmail.com', '098f6bcd4621d373cade4e832627b4f6', 'Justin', 'Scott', 'fligtar', 1, 0, 'http://www.fligtar.com', '2312', '2006-08-22 00:13:05', '2006-09-05 16:45:46', '123'),
+(3, 'bill@ms.com', '8f4047e3233b39e4444e1aef240e80aa', 'Bill', 'Gates', '', 1, 0, 'microsoft.com', 'confirm', '2006-08-22 11:08:45', '2006-08-22 11:08:45', NULL),
+(4, 'steve@apple.com', 'ipod', 'Steve', 'Jobs', '', 0, 0, 'apple.com', 'confirmed', '2006-08-23 01:21:07', '2006-08-23 01:21:07', NULL),
+(5, 'nobody@mozilla.org', '098f6bcd4621d373cade4e832627b4f6', 'Andrei', 'Hajdukewycz', 'Sancus', 0, 1, 'http://www.eve-online.com', '', '2006-09-28 08:57:24', '2007-02-12 22:15:49', NULL),
+(6, 'editor@test', '098f6bcd4621d373cade4e832627b4f6', 'editor', 'editor', 'editor', 0, 0, NULL, '', '0000-00-00 00:00:00', '0000-00-00 00:00:00', NULL),
+(7, 'user@test', '098f6bcd4621d373cade4e832627b4f6', 'user', 'user', 'user', 0, 0, NULL, '', '0000-00-00 00:00:00', '0000-00-00 00:00:00', NULL),
+(8, 'sandbox@test', '098f6bcd4621d373cade4e832627b4f6', 'sandbox', 'sandbox', 'sandbox', 0, 1, NULL, '', '0000-00-00 00:00:00', '0000-00-00 00:00:00', NULL),
+(9, 'nobody@addons.mozilla.org', '098f6bcd4621d373cade4e832627b4f6', 'nobody', 'nobody', 'nobody', 0, 1, NULL, '', '0000-00-00 00:00:00', '0000-00-00 00:00:00', NULL);
+
+--
+-- Dumping data for table `versions`
+--
+
+INSERT INTO `versions` (`id`, `addon_id`, `version`, `approvalnotes`, `releasenotes`, `created`, `modified`) VALUES
+(1, 7, '1.0', 'Thanks for reviewing this!', 139, '2006-03-28 09:02:34', '2006-10-12 12:47:45'),
+(2, 8, '1.0.4c', NULL, 140, '2006-10-16 17:08:33', '2006-10-16 17:08:55'),
+(3, 9, '1.0.1b', NULL, 141, '2006-10-16 17:10:01', '2006-10-16 17:10:01'),
+(4, 5, '0.1', NULL, NULL, '2007-01-04 10:49:38', '0000-00-00 00:00:00'),
+(5, 10, '0.1', NULL, NULL, '2007-01-04 10:49:38', '0000-00-00 00:00:00'),
+(6, 11, '0.1', NULL, NULL, '2007-01-04 10:50:05', '0000-00-00 00:00:00'),
+(7, 12, '0.1', NULL, NULL, '2007-01-04 10:50:05', '0000-00-00 00:00:00'),
+(8, 13, '0.1', NULL, NULL, '2007-01-04 10:50:16', '0000-00-00 00:00:00'),
+(9, 7, '1.02a', NULL, 139, '2006-09-28 09:02:34', '2006-10-12 12:47:45'),
+(19132, 3046, '0.1', '', 56114, '2006-07-27 00:31:55', '2006-07-27 18:08:03'),
+(19160, 3049, '1.0', '', 56124, '2006-07-27 07:15:52', '2006-07-27 18:09:18'),
+(19168, 3052, '0.9.20060727', '', 56128, '2006-07-27 08:47:04', '2006-07-27 18:09:19'),
+(19172, 3053, '2.3_beta_2006_07_23', '', 56130, '2006-07-27 09:08:00', '2006-07-27 18:09:20'),
+(19202, 3059, '1.0', '', 56135, '2006-07-27 13:06:06', '2006-07-27 18:09:22'),
+(19237, 3064, '1.3', '', 56151, '2006-07-28 07:32:12', '2006-07-28 12:51:09'),
+(19255, 3066, '1.0.1', '', 56156, '2006-07-28 12:43:39', '2006-07-28 12:52:05'),
+(19335, 3075, '2.0.8', '', 56185, '2006-07-30 05:14:57', '2006-08-21 12:32:49'),
+(19346, 3077, '1.0', '', 56190, '2006-07-30 08:15:28', '2006-08-21 12:32:54'),
+(19350, 3079, '1.0', '', 56191, '2006-07-30 08:19:02', '2006-08-21 12:32:55'),
+(19497, 3099, '0.1', '', 56257, '2006-08-02 11:06:51', '2006-08-02 12:30:43'),
+(19500, 3099, '0.2', '', 56258, '2006-08-02 11:19:39', '2006-08-12 02:46:24'),
+(19567, 3090, '4.1', '', 56293, '2006-08-04 07:56:38', '2006-08-04 13:15:17'),
+(19841, 3155, '20060808', '', 56419, '2006-08-12 02:41:14', '2006-08-12 05:59:28'),
+(20376, 3079, '1.0.1', '', 56653, '2006-08-24 14:33:42', '2006-08-24 20:51:56'),
+(20379, 3077, '1.0.1', '', 56654, '2006-08-24 14:35:07', '2006-08-24 20:51:57'),
+(20469, 3155, '20060824', '', 56701, '2006-08-27 16:30:01', '2006-09-12 07:17:07'),
+(20474, 3257, '2.0b2', '', 56703, '2006-08-27 20:11:20', '2006-09-02 02:54:06'),
+(20631, 3291, '1.0', '', 56782, '2006-09-01 03:39:51', '2006-09-05 03:10:21'),
+(20783, 3291, '1.0.1', '', 56847, '2006-09-05 03:31:51', '2006-09-07 17:29:20'),
+(21051, 3075, '2.0.8.1', '', 56972, '2006-09-11 11:51:00', '2006-09-12 06:13:34'),
+(21078, 3366, '1.19', '', 56990, '2006-09-12 02:11:22', '2006-09-12 07:33:23'),
+(21082, 3257, '1.0', '', 56992, '2006-09-12 02:47:37', '2006-09-12 07:33:24'),
+(21098, 3369, '0.1', '', 57002, '2006-09-12 16:48:29', '2006-09-12 17:36:23'),
+(21217, 3155, '20060914', '', 57047, '2006-09-14 13:49:45', '2006-09-14 13:59:34'),
+(21220, 3155, '20060914.1', '', 57048, '2006-09-14 14:44:34', '2006-09-14 23:38:38'),
+(21281, 3386, '1.1.1', '', 57077, '2006-09-15 17:17:12', '2006-09-16 07:06:43'),
+(21303, 3390, '#genid1', '', 57084, '2006-09-16 02:50:40', '2006-09-17 02:40:21'),
+(21349, 3394, '1.0', '', 57101, '2006-09-16 17:06:03', '2006-09-17 01:32:28'),
+(21368, 3390, '1.0.0', '', 57108, '2006-09-17 03:56:15', '2006-09-17 04:35:44'),
+(21371, 3386, '1.1.2', '', 57109, '2006-09-17 03:58:54', '2006-09-17 04:35:45'),
+(21559, 3291, '1.0.3', '', 57205, '2006-09-21 00:43:51', '2006-09-21 06:28:21'),
+(21717, 3386, '1.1.3', '', 57267, '2006-09-24 03:15:28', '2006-09-24 12:37:57'),
+(21728, 3439, '0.7', '', 57274, '2006-09-24 09:02:12', '2006-09-24 12:37:59'),
+(21813, 3451, '0.1', '', 57313, '2006-09-26 04:12:09', '2006-09-27 16:36:17'),
+(21816, 3451, '0.2', '', 57314, '2006-09-26 04:45:38', '2006-10-06 09:55:38'),
+(22356, 3155, '20060927', '', 57593, '2006-09-28 14:49:50', '2006-10-03 01:33:50'),
+(22505, 3445, '1.0', '', 57677, '2006-09-30 06:13:55', '2006-09-30 06:15:50'),
+(22937, 3497, '2.0', '', 57890, '2006-10-05 12:04:33', '2006-10-05 20:08:06'),
+(22940, 3497, '2.0.0.1', '', 57891, '2006-10-05 12:12:48', '2006-10-06 01:47:20'),
+(23039, 3497, '2.0.0.2', '', 57941, '2006-10-07 09:30:38', '2006-10-11 03:42:51'),
+(23153, 3075, '2.0.8.2', '', 58004, '2006-10-09 06:27:30', '2006-10-09 11:25:32'),
+(23355, 3497, '2.0.0.3', '', 58096, '2006-10-13 01:17:37', '2006-10-13 07:44:34'),
+(23399, 3052, '0.9.20061014', '', 58115, '2006-10-14 05:05:23', '2006-10-19 02:11:17'),
+(23555, 3554, '1.0', '', 58198, '2006-10-17 11:44:25', '2006-10-19 06:24:06'),
+(23634, 3090, '4.1.1', '', 58227, '2006-10-18 12:57:40', '2006-10-22 03:19:21'),
+(23650, 3497, '2.0.0.4', '', 58239, '2006-10-18 17:07:57', '2006-10-19 01:45:44'),
+(23672, 3497, '2.0.0.5', '', 58249, '2006-10-19 04:03:51', '2006-10-19 13:27:23'),
+(23818, 3053, '3.0', '', 58309, '2006-10-21 01:25:30', '2006-10-21 09:19:56'),
+(23829, 3596, '1.4.57', '', 58315, '2006-10-21 05:49:52', '2006-10-21 09:19:58'),
+(23840, 3497, '2.0.0.6', '', 58324, '2006-10-21 08:37:01', '2006-10-21 09:24:22'),
+(24072, 3623, '2.0.0.1', '', 58439, '2006-10-24 02:40:25', '2006-10-24 06:52:35'),
+(24089, 3627, '1.0', '', 58450, '2006-10-24 06:37:17', '2006-10-24 08:22:21'),
+(24211, 3643, '1.0.1', '', 58516, '2006-10-25 03:34:42', '2006-10-25 23:53:03'),
+(24276, 3646, '1.0', '', 58549, '2006-10-25 11:22:26', '2006-10-26 08:20:36'),
+(24293, 3155, '6.10.24.0', '', 58557, '2006-10-25 14:41:59', '2006-10-26 08:20:39'),
+(24333, 3554, '1.1', '', 58576, '2006-10-26 01:02:28', '2006-10-26 08:20:39'),
+(24378, 3653, '1.0.0', '', 58601, '2006-10-26 10:03:55', '2006-10-26 12:38:53'),
+(24391, 3653, '1.0.1', '', 58608, '2006-10-26 12:35:52', '2006-10-27 01:13:54'),
+(24560, 3677, '1.2b1', '', 58704, '2006-10-29 02:47:34', '2006-10-29 04:25:54'),
+(24605, 3684, '1.0', '', 58722, '2006-10-29 12:16:50', '2006-10-30 03:49:50'),
+(24704, 3703, '0.1', '', 58776, '2006-10-30 12:55:25', '2006-10-30 16:08:13'),
+(24707, 3684, '1.0.1', '', 58777, '2006-10-30 13:47:31', '2006-10-30 16:08:13'),
+(24779, 3716, '1.1+cvs20060719', '', 58815, '2006-10-31 14:40:11', '2006-10-31 14:43:22'),
+(24956, 3737, '0.02', '', 58927, '2006-11-02 08:19:26', '2006-11-03 00:19:27'),
+(25529, 3819, '1.0', '', 59230, '2006-11-08 14:45:06', '2006-11-09 10:30:31'),
+(25562, 3826, '0.9.5', '', 59253, '2006-11-09 13:36:13', '2006-11-11 09:57:46'),
+(26012, 3155, '6.11.16.0', '', 59491, '2006-11-16 14:48:43', '2006-11-16 16:22:14'),
+(26294, 3451, '0.3', '', 59637, '2006-11-22 09:14:00', '2006-11-26 07:53:28'),
+(26492, 3956, '0.0.20060327', '', 59726, '2006-11-25 16:24:33', '2006-11-26 12:03:10'),
+(26872, 3716, '1.1+cvs20061127', '', 59925, '2006-12-03 03:50:06', '2006-12-04 08:10:32'),
+(26936, 3786, '0.7', '', 59951, '2006-12-04 03:45:10', '2006-12-04 08:15:24'),
+(26948, 4020, 'III', '', 59957, '2006-12-04 09:21:00', '2006-12-05 08:19:06'),
+(26955, 3826, '0.9.6', '', 59960, '2006-12-04 11:04:43', '2006-12-05 07:34:47'),
+(27076, 3155, '6.12.07.0', '', 60036, '2006-12-07 16:06:37', '2006-12-08 15:10:03'),
+(27383, 3064, '1.4', '', 60178, '2006-12-14 10:15:52', '2006-12-18 11:42:17'),
+(27512, 3826, '0.9.7', '', 60251, '2006-12-17 22:14:20', '2006-12-17 23:00:09'),
+(27589, 3155, '6.12.18.0', '', 60293, '2006-12-19 15:31:23', '2006-12-20 21:43:01'),
+(27665, 3956, '0.0.20060327.1', '', 60337, '2006-12-20 18:40:45', '2006-12-20 21:43:03'),
+(27876, 3155, '6.12.26.0', '', 60450, '2006-12-26 15:45:45', '2007-01-11 12:03:27'),
+(28788, 3445, '1.0.1', '', 60949, '2007-01-20 13:50:05', '2007-01-20 13:53:39'),
+(28845, 3257, '1.0.0.1', '', 60980, '2007-01-21 20:59:42', '2007-01-21 23:16:43'),
+(28896, 3653, '1.0.2', '', 61010, '2007-01-23 07:31:31', '2007-01-23 07:31:31'),
+(28897, 4021, '0.1', '', 46695, '2007-02-11 18:18:03', '2007-02-11 18:20:30'),
+(28898, 4022, '0.1', '', 46703, '2007-02-11 18:38:15', '2007-02-11 18:49:18'),
+(28899, 4022, '0.2', '', 46706, '2007-02-11 19:24:11', '2007-02-11 19:25:13'),
+(28900, 4023, '1.0', '', 46713, '2007-02-12 22:16:19', '2007-02-12 22:16:49'),
+(28901, 4023, '0.9', '', 46713, '2007-02-12 22:16:19', '2007-02-20 22:16:49');
+
+--
+-- Set up the materialized views for search
+--
+INSERT INTO `text_search_summary`
+SELECT a.id AS id,
+`tr_name`.locale AS locale,
+a.addontype_id AS addontype,
+a.status AS status,
+a.inactive AS inactive,
+a.averagerating AS averagerating,
+a.weeklydownloads AS weeklydownloads,
+`tr_name`.localized_string AS name,
+`tr_summary`.localized_string AS summary,
+`tr_description`.localized_string AS description
+FROM addons AS a
+LEFT JOIN translations AS `tr_name` ON (`tr_name`.id = a.`name`)
+LEFT JOIN translations AS `tr_summary` ON (`tr_summary`.id = a.`summary` AND `tr_name`.locale = `tr_summary`.locale)
+LEFT JOIN translations AS `tr_description` ON (`tr_description`.id = a.`description` AND `tr_name`.locale = `tr_description`.locale)
+WHERE `tr_name`.locale IS NOT NULL
+AND
+(`tr_name`.localized_string IS NOT NULL
+OR `tr_summary`.localized_string IS NOT NULL
+OR `tr_description`.localized_string IS NOT NULL)
+ORDER BY a.id ASC, locale DESC;
+
+CREATE TEMPORARY TABLE `most_recent_version` (
+ `addon_id` int(11) NOT NULL,
+ `created` DATETIME NOT NULL
+) DEFAULT CHARSET=utf8;
+
+INSERT INTO `most_recent_version`
+SELECT DISTINCT addon_id, MAX(created)
+FROM versions
+GROUP BY addon_id;
+
+
+INSERT INTO `versions_summary`
+SELECT DISTINCT v.addon_id, v.id, av.application_id, v.created, v.modified, av.min, av.max
+FROM (most_recent_version AS mrv NATURAL JOIN versions AS v) LEFT JOIN applications_versions AS av
+ON (av.version_id = v.id );
+
+DROP TABLE `most_recent_version`;
+
+DELETE FROM `collections_search_summary`;
+
+INSERT INTO `collections_search_summary`
+SELECT `c`.`id` AS `id`,
+ `tr_name`.`locale` AS `locale`,
+ `tr_name`.`localized_string` AS `name`,
+ `tr_description`.`localized_string` AS `description`
+FROM `collections` AS `c`
+LEFT JOIN `translations` AS `tr_name` ON (`tr_name`.`id` = `c`.`name`)
+LEFT JOIN `translations` AS `tr_description`
+ ON (`tr_description`.`id` = `c`.`description` AND `tr_name`.`locale` = `tr_description`.`locale`)
+WHERE `tr_name`.`locale` IS NOT NULL AND (
+ `tr_name`.`localized_string` IS NOT NULL
+ OR `tr_description`.`localized_string` IS NOT NULL
+)
+ORDER BY `c`.`id` ASC, `locale` DESC;
+
+--
+-- Insert new data above materialized views
+--
+
+SET FOREIGN_KEY_CHECKS=1;
diff --git a/site/app/tests/data/remora-test-log.log b/site/app/tests/data/remora-test-log.log
new file mode 100644
index 0000000..295c350
--- /dev/null
+++ b/site/app/tests/data/remora-test-log.log
@@ -0,0 +1,27 @@
+10.177.10.176 addons.mozilla.org - [25/Nov/2008:11:59:40 -0800] "GET /en-US/firefox/collections/success?i=3677,3369,7,8,6 HTTP/1.1" 200 0 "https://addons.mozilla.org/en-US/firefox/collections/interactive/" "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.0.4) Gecko/2008102920 Firefox/3.0.4" "__utma=xxx; __utmb=yyy;"
+10.28.10.131 addons.mozilla.org - [25/Nov/2008:11:59:40 -0800] "GET /update/VersionCheck.php?reqVersion=1&id=it-IT@dictionaries.addons.mozilla.org&version=3.1&maxAppVersion=3.1b2pre&status=userEnabled&appID={ec8030f7-c20a-464f-9b0e-13a3a9e97384}&appVersion=2.0.0.18&appOS=WINNT&appABI=x86-msvc HTTP/1.1" 200 0 "-" "Mozilla/5.0 (Windows; U; Windows NT 5.1; fr; rv:1.8.1.18) Gecko/20081029 Firefox/2.0.0.18" "dloadday=10.10.10.228.122000000501228"
+10.85.10.74 addons.mozilla.org - [25/Nov/2008:11:59:40 -0800] "GET /update/VersionCheck.php?reqVersion=1&id={B13721C7-F507-4982-B2E5-502A71474FED}&version=2.2.0.70&maxAppVersion=2.*&status=userDisabled&appID={ec8030f7-c20a-464f-9b0e-13a3a9e97384}&appVersion=2.0.0.18&appOS=WINNT&appABI=x86-msvc HTTP/1.1" 200 0 "-" "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.18) Gecko/20081029 Firefox/2.0.0.18" "dloadday=10.85.10.128.121500000042560;"
+10.171.10.37 addons.mozilla.org - [25/Nov/2008:11:59:40 -0800] "GET /update/VersionCheck.php?reqVersion=1&id={847b3a00-7ab1-11d4-8f02-006008948af5}&version=0.95.6&maxAppVersion=2.0.0.*&status=userEnabled&appID={3550f703-e582-4d05-9a08-453d09bdfdc6}&appVersion=2.0.0.18&appOS=Linux&appABI=x86-gcc3 HTTP/1.1" 200 0 "-" "Mozilla/5.0 (X11; U; Linux i686 (x86_64); de; rv:1.8.1.18) Gecko/20081105 Thunderbird/2.0.0.18" "-"
+63.245.213.1 addons.mozilla.org - [25/Nov/2008:11:59:40 -0800] "GET /en-US/firefox/downloads/file/5/fishing.xpi HTTP/1.1" 302 0 "https://addons.mozilla.org/en-US/firefox/addon/220" "Mozilla/5.0 (Windows; U; Windows NT 5.1; hu; rv:1.9.0.4) Gecko/2008102920 Firefox/3.0.4" "-"
+59.151.50.1 addons.mozilla.org - [25/Nov/2008:11:59:40 -0800] "GET /en-US/firefox/downloads/file/8/fishing.xpi HTTP/1.1" 302 0 "https://addons.mozilla.org/en-US/firefox/addon/220" "Mozilla/5.0 (Windows; U; Windows NT 5.1; hu; rv:1.9.0.4) Gecko/2008102920 Firefox/3.0.4" "-"
+10.95.10.242 addons.mozilla.org - [25/Nov/2008:11:59:40 -0800] "GET /update/VersionCheck.php?reqVersion=1&id={55bb8164-71be-11dc-8314-0800200c9a66}&version=1.01&maxAppVersion=2.0.0.*&status=userEnabled&appID={ec8030f7-c20a-464f-9b0e-13a3a9e97384}&appVersion=2.0.0.18&appOS=WINNT&appABI=x86-msvc HTTP/1.1" 200 0 "-" "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.18) Gecko/20081029 Firefox/2.0.0.18" "-"
+10.110.10.98 addons.mozilla.org - [25/Nov/2008:11:59:40 -0800] "GET /blocklist/2/%7Bec8030f7-c20a-464f-9b0e-13a3a9e97384%7D/3.0.4/Firefox/2008102920/WINNT_x86-msvc/ja/release/Windows_NT%205.1/default/default/ HTTP/1.1" 200 0 "-" "Mozilla/5.0 (Windows; U; Windows NT 5.1; ja; rv:1.9.0.4) Gecko/2008102920 Firefox/3.0.4" "dloadday=10.194.10.112.120000005042695"
+10.56.10.195 addons.mozilla.org - [24/Nov/2008:11:59:40 -0800] "GET /es-ES/firefox/downloads/file/1/farming.xpi HTTP/1.1" 302 0 "-" "Mozilla/5.0 (Windows; U; Windows NT 5.1; es-ES; rv:1.9.0.4) Gecko/2008102920 Firefox/3.0.4" "__utma=xxx;"
+10.56.10.195 addons.mozilla.org - [25/Nov/2008:11:59:40 -0800] "GET /es-ES/firefox/downloads/file/1/farming.xpi HTTP/1.1" 302 0 "-" "Mozilla/5.0 (Windows; U; Windows NT 5.1; es-ES; rv:1.9.0.4) Gecko/2008102920 Firefox/3.0.4" "__utma=xxx;"
+10.46.10.195 addons.mozilla.org - [25/Nov/2008:11:59:40 -0800] "GET /es-ES/firefox/downloads/file/1/farming.xpi HTTP/1.1" 302 0 "-" "Mozilla/5.0 (Windows; U; Windows NT 5.1; es-ES; rv:1.9.0.4) Gecko/2008102920 Firefox/3.0.4" "__utma=xxx;"
+10.46.10.195 addons.mozilla.org - [25/Nov/2008:11:59:40 -0800] "GET /es-ES/firefox/downloads/file/1/farming.xpi HTTP/1.1" 302 0 "-" "Mozilla/5.0 (Windows; U; Windows NT 5.1; es-ES; rv:1.9.0.4) Gecko/2008102920 Firefox/3.0.4" "__utma=xxx;"
+10.2.10.226 addons.mozilla.org - [25/Nov/2008:11:59:40 -0800] "GET /en-US/firefox/downloads/file/2/fishing.xpi HTTP/1.1" 302 0 "https://addons.mozilla.org/en-US/firefox/addon/220" "Mozilla/5.0 (Windows; U; Windows NT 5.1; hu; rv:1.9.0.4) Gecko/2008102920 Firefox/3.0.4" "-"
+10.10.10.10 this is a broken log entry
+10.104.10.202 addons.mozilla.org - [25/Nov/2008:11:59:40 -0800] "GET /en-US/firefox/downloads/file/4/myfirefox-2.0.0.10-fx.jar HTTP/1.1" 302 0 "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1) ; Embedded Web Browser" "-"
+10.64.10.123 addons.mozilla.org - [25/Nov/2008:11:59:40 -0800] "GET /de/downloads/file/5/opendownload-1.0.0-fx.xpi HTTP/1.1" 302 0 "-" "Mozilla/5.0 (X11; U; Linux i686; de; rv:1.9.0.4) Gecko/2008111317 Ubuntu/8.04 (hardy) Firefox/3.0.4" "__utma=xxx;"
+10.76.10.167 addons.mozilla.org - [25/Nov/2008:11:59:40 -0800] "GET /zh-CN/firefox/downloads/file/7/fast_video_download-1.6.1-fx.xpi HTTP/1.1" 302 0 "-" "Mozilla/5.0 (Windows; U; Windows NT 6.0; zh-CN; rv:1.9.0.4) Gecko/2008102920 Firefox/3.0.4" "__utma=xxx;"
+10.62.10.10 addons.mozilla.org - [25/Nov/2008:11:59:56 -0800] "GET /img/arr-prev.png HTTP/1.1" 200 0 "https://addons.mozilla.org/css/style.min.css?19906" "Mozilla/5.0 (Macintosh; U; Intel Mac OS X; en-US; rv:1.8.1.12) Gecko/20080201 Firefox/2.0.0.12" ""
+10.194.10.99 addons.mozilla.org - [25/Nov/2008:11:59:40 -0800] "GET /en-US/firefox/images/addon_icon/8381/1219703818 HTTP/1.1" 200 0 "https://addons.mozilla.org/en-US/thunderbird/search?q=&cat=1,50&show=100&page=3" "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.0.4) Gecko/2008102920 Firefox/3.0.4" "dloadday=10.206.10.215.121641000000203; __utma=xxx;"
+10.132.10.107 addons.mozilla.org - [25/Nov/2008:11:59:40 -0800] "GET /img//ratings/1stars.png HTTP/1.1" 200 0 "https://addons.mozilla.org/en-US/firefox/addon/636" "Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.0.4) Gecko/2008102920 Firefox/3.0.4" "__utma=xxx;"
+10.97.10.45 addons.mozilla.org - [25/Nov/2008:11:59:45 -0800] "GET /en-US/firefox/collections/success?i=7,8 HTTP/1.1" 200 0 "https://addons.mozilla.org/en-US/firefox/collections/interactive/" "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.0.4) Gecko/2008102920 Firefox/3.0.4" "__utma=xxx;"
+10.119.10.149 addons.mozilla.org - [25/Nov/2008:11:59:48 -0800] "GET /en-US/firefox/collections/success?i=6,7,9 HTTP/1.1" 200 4294967295 "https://addons.mozilla.org/en-US/firefox/collections/interactive/" "Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.0.4) Gecko/2008102920 Firefox/3.0.4" "dloadday=10.119.10.149.122230000003322; __utma=xxx; __utmb=xxx; __utmc=xxx;"
+10.119.10.189 addons.mozilla.org - [25/Nov/2008:11:59:48 -0800] "GET /en-US/firefox/collections/success?i=6,7,9 HTTP/1.1" 200 0 "https://addons.mozilla.org/en-US/firefox/collections/interactive/" "Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.0.4) Gecko/2008102920 Firefox/3.0.4" "dloadday=10.119.10.149.122000000383322; __utma=xxx;"
+10.194.10.154 addons.mozilla.org - [25/Nov/2008:11:59:56 -0800] "GET /en-US/firefox/collections/success?i=1 HTTP/1.1" 200 0 "-" "Mozilla/5.0 (Windows; U; Windows NT 6.0; en-GB; rv:1.9.0.4) Gecko/2008102920 Firefox/3.0.4" "coll_restarted=yes; __utma=xxx;"
+10.212.10.173 addons.mozilla.org - [25/Nov/2008:11:59:56 -0800] "GET /img/app-icons/firefox.png HTTP/1.1" 200 0 "https://addons.mozilla.org/en-US/firefox/browse/type:7" "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.0.1) Gecko/2008070208 Firefox/3.0.1" "__utma=xxx;"
+10.42.10.183 addons.mozilla.org - [25/Nov/2008:11:59:56 -0800] "GET /js/jquery.addons.min.js?19777 HTTP/1.1" 200 0 "https://addons.mozilla.org/en-US/firefox/recommended" "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-GB; rv:1.9.0.4) Gecko/2008102920 Firefox/3.0.4" ""
+10.56.10.195 addons.mozilla.org - [25/Nov/2008:11:59:56 -0800] "GET /img/favicon.ico HTTP/1.1" 200 0 "-" "Mozilla/5.0 (Windows; U; Windows NT 5.1; es-ES; rv:1.9.0.4) Gecko/2008102920 Firefox/3.0.4" ""
diff --git a/site/app/tests/data/resized-icon.png b/site/app/tests/data/resized-icon.png
new file mode 100644
index 0000000..5a8ddab
--- /dev/null
+++ b/site/app/tests/data/resized-icon.png
Binary files differ
diff --git a/site/app/tests/data/test-install.rdf b/site/app/tests/data/test-install.rdf
new file mode 100644
index 0000000..559a4dc
--- /dev/null
+++ b/site/app/tests/data/test-install.rdf
@@ -0,0 +1,34 @@
+<?xml version="1.0"?>
+
+<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:em="http://www.mozilla.org/2004/em-rdf#">
+
+ <Description about="urn:mozilla:install-manifest">
+ <em:id>{B17C1C5A-04B1-11DB-9804-B622A1EF5496}</em:id>
+ <em:version>1.0</em:version>
+ <em:type>2</em:type>
+ <em:name>Test Extension</em:name>
+ <em:description>Test description of the test extension.</em:description>
+ <em:homepageURL>http://addons.mozilla.org</em:homepageURL>
+ <em:creator>Justin Scott</em:creator>
+
+ <!-- Mozilla Firefox -->
+ <em:targetApplication>
+ <Description>
+ <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
+ <em:minVersion>1.5</em:minVersion>
+ <em:maxVersion>3.0a1</em:maxVersion>
+ </Description>
+ </em:targetApplication>
+
+ <!-- Mozilla Thunderbird -->
+ <em:targetApplication>
+ <Description>
+ <em:id>{3550f703-e582-4d05-9a08-453d09bdfdc6}</em:id>
+ <em:minVersion>1.5</em:minVersion>
+ <em:maxVersion>1.6a1</em:maxVersion>
+ </Description>
+ </em:targetApplication>
+
+ </Description>
+</RDF>
diff --git a/site/app/tests/database.test.php b/site/app/tests/database.test.php
new file mode 100644
index 0000000..be5378e
--- /dev/null
+++ b/site/app/tests/database.test.php
@@ -0,0 +1,154 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Justin Scott <fligtar@mozilla.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/**
+ * Tests Database Selection
+ * If you're looking for database connectivity, that's in installation.test.php, silly.
+ * Note: all of these tests have to go through hurdles to not set the actual
+ * constants, as once set, constants can't be changed or unset.
+ */
+
+class DatabaseTest extends UnitTestCase {
+ var $default_config = array(
+ 0 => array(
+ 'DB_HOST' => '',
+ 'DB_NAME' => '',
+ 'DB_USER' => '',
+ 'DB_PASS' => '',
+ 'DB_WEIGHT' => 0
+ )
+ );
+
+ var $populated_config = array(
+ 0 => array(
+ 'DB_HOST' => 'localhost',
+ 'DB_PORT' => 3306,
+ 'DB_NAME' => 'shadow1',
+ 'DB_USER' => 'root',
+ 'DB_PASS' => '',
+ 'DB_WEIGHT' => .75
+ ),
+ 1 => array(
+ 'DB_HOST' => 'localhost',
+ 'DB_PORT' => 3306,
+ 'DB_NAME' => 'shadow2',
+ 'DB_USER' => 'root',
+ 'DB_PASS' => '',
+ 'DB_WEIGHT' => .25
+ )
+ );
+
+ function testDefaults() {
+ // Test that the default configuration will not cause SHADOW_* to be set
+ $shadow = select_shadow_database($this->default_config, false);
+ $this->assertTrue(empty($shadow), 'Default shadow db config does not cause SHADOW constants to be set');
+ }
+
+ function testPopulated() {
+ // Test that with populated config, one database will be returned
+ $shadow = select_shadow_database($this->populated_config, false);
+ $this->assertFalse(empty($shadow), 'Populated shadow db config returns 1 database');
+ }
+
+ function testFallback() {
+ global $shadow_databases;
+ $db = ConnectionManager::getInstance();
+ @$db->getDataSource('shadow');
+ // Bunch of errors when disconnecting, so not disconnecting!
+ //$db->_dataSources['shadow']->disconnect();
+
+ // Save to restore after test
+ $orig_shadow_databases = $shadow_databases;
+ $original_config = $db->_dataSources['shadow']->config;
+
+ ///////////////////////////////////////////////////////////////////////
+ // Fallback with 1 bad db
+ $shadow_databases = $this->populated_config;
+ $this->_setToRealDatabase($shadow_databases[1]);
+ $this->_updateShadowConfig($db->_dataSources['shadow'], $shadow_databases[0]);
+
+ @$db->_dataSources['shadow']->connect();
+
+ // We told it to use shadow db 1, but we *should* get shadow db 2 back
+ // because db 1 is bad and db 2 is good
+ $this->assertTrue(($db->_dataSources['shadow']->config['database'] == $shadow_databases[1]['DB_NAME']), 'Fallback to shadow database 2 when shadow database 1 is down');
+ $this->assertFalse(defined('SHADOW_DISABLED'), 'Shadow databases are still enabled');
+ //$db->_dataSources['shadow']->disconnect();
+
+ // Reset
+ $db->config->shadow = $original_config;
+
+ ///////////////////////////////////////////////////////////////////////
+ // Fallback with all bad db's
+ $shadow_databases = $this->populated_config;
+ $this->_updateShadowConfig($db->_dataSources['shadow'], $shadow_databases[0]);
+ @$db->_dataSources['shadow']->connect();
+
+ // We told it to use shadow db 1, but we *should* get SHADOW_DISABLED back
+ // because all shadow db's are bad
+ $this->assertTrue(defined('SHADOW_DISABLED'), 'Disabled shadow databases because all shadows are down');
+
+ //$db->_dataSources['shadow']->disconnect();
+
+ // Restore real database config back to original
+ $shadow_databases = $orig_shadow_databases;
+ $db->_dataSources['shadow']->config = $original_config;
+ }
+
+ /**
+ * Sets a shadow config to be a real database connection
+ */
+ function _setToRealDatabase(&$shadow) {
+ $shadow['DB_HOST'] = DB_HOST;
+ $shadow['DB_PORT'] = DB_PORT;
+ $shadow['DB_NAME'] = DB_NAME;
+ $shadow['DB_USER'] = DB_USER;
+ $shadow['DB_PASS'] = DB_PASS;
+ }
+
+ /**
+ * Updates the db's shadow config
+ */
+ function _updateShadowConfig(&$db, $new) {
+ $db->config['host'] = $new['DB_HOST'];
+ $db->config['login'] = $new['DB_USER'];
+ $db->config['password'] = $new['DB_PASS'];
+ $db->config['database'] = $new['DB_NAME'];
+ }
+}
+?>
diff --git a/site/app/tests/facebook-selenium b/site/app/tests/facebook-selenium
new file mode 100644
index 0000000..9c6edbd
--- /dev/null
+++ b/site/app/tests/facebook-selenium
@@ -0,0 +1,359 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>facebook-selenium</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">facebook-selenium</td></tr>
+</thead><tbody>
+<tr>
+ <td>verifyTextPresent</td>
+ <td>Recommendation</td>
+ <td></td>
+</tr>
+<tr>
+ <td>clickAndWait</td>
+ <td>//a[@href='http://apps.facebook.com/add-ons/invite?ref=sb']</td>
+ <td></td>
+</tr>
+<tr>
+ <td>clickAndWait</td>
+ <td>skip</td>
+ <td></td>
+</tr>
+<tr>
+ <td>clickAndWait</td>
+ <td>link=FAQ</td>
+ <td></td>
+</tr>
+<tr>
+ <td>verifyTextPresent</td>
+ <td>Frequently Asked Questions</td>
+ <td></td>
+</tr>
+<tr>
+ <td>clickAndWait</td>
+ <td>//a[@href='http://apps.facebook.com/add-ons/home']</td>
+ <td></td>
+</tr>
+<tr>
+ <td>clickAndWait</td>
+ <td>link=Desktop Wallpaper</td>
+ <td></td>
+</tr>
+<tr>
+ <td>verifyText</td>
+ <td>link=800 x 600</td>
+ <td>800 x 600</td>
+</tr>
+<tr>
+ <td>verifyText</td>
+ <td>link=1024 x 768</td>
+ <td>1024 x 768</td>
+</tr>
+<tr>
+ <td>verifyText</td>
+ <td>link=1280 x 1024</td>
+ <td>1280 x 1024</td>
+</tr>
+<tr>
+ <td>verifyText</td>
+ <td>link=1440 x 900</td>
+ <td>1440 x 900</td>
+</tr>
+<tr>
+ <td>verifyText</td>
+ <td>link=1680 x 1050</td>
+ <td>1680 x 1050</td>
+</tr>
+<tr>
+ <td>verifyText</td>
+ <td>link=1920 x 1200</td>
+ <td>1920 x 1200</td>
+</tr>
+<tr>
+ <td>clickAndWait</td>
+ <td>//a[@href='http://apps.facebook.com/add-ons/home']</td>
+ <td></td>
+</tr>
+<tr>
+ <td>clickAndWait</td>
+ <td>link=Find out more!</td>
+ <td></td>
+</tr>
+<tr>
+ <td>clickAndWait</td>
+ <td>link=Back to home</td>
+ <td></td>
+</tr>
+<tr>
+ <td>clickAndWait</td>
+ <td>link=Browse Add-ons</td>
+ <td></td>
+</tr>
+<tr>
+ <td>open</td>
+ <td>add-ons/browse/sort:popular/cat:all/type:1</td>
+ <td></td>
+</tr>
+<tr>
+ <td>open</td>
+ <td>add-ons/browse/sort:popular/cat:all/type:2</td>
+ <td></td>
+</tr>
+<tr>
+ <td>open</td>
+ <td>add-ons/browse/sort:popular/cat:all/type:friends</td>
+ <td></td>
+</tr>
+<tr>
+ <td>open</td>
+ <td>add-ons/browse/sort:popular/cat:all/type:none/page:2</td>
+ <td></td>
+</tr>
+<tr>
+ <td>select</td>
+ <td>sort</td>
+ <td>label=Name</td>
+</tr>
+<tr>
+ <td>clickAndWait</td>
+ <td>//input[@value='Update']</td>
+ <td></td>
+</tr>
+<tr>
+ <td>select</td>
+ <td>cat</td>
+ <td>label=Extensions: Alerts & Updates</td>
+</tr>
+<tr>
+ <td>clickAndWait</td>
+ <td>//input[@value='Update']</td>
+ <td></td>
+</tr>
+<tr>
+ <td>select</td>
+ <td>cat</td>
+ <td>label=Extensions: Bookmarks</td>
+</tr>
+<tr>
+ <td>clickAndWait</td>
+ <td>//input[@value='Update']</td>
+ <td></td>
+</tr>
+<tr>
+ <td>select</td>
+ <td>cat</td>
+ <td>label=Extensions: Download Management</td>
+</tr>
+<tr>
+ <td>clickAndWait</td>
+ <td>//input[@value='Update']</td>
+ <td></td>
+</tr>
+<tr>
+ <td>select</td>
+ <td>cat</td>
+ <td>label=Extensions: Feeds, News & Blogging</td>
+</tr>
+<tr>
+ <td>clickAndWait</td>
+ <td>//input[@value='Update']</td>
+ <td></td>
+</tr>
+<tr>
+ <td>select</td>
+ <td>cat</td>
+ <td>label=Extensions: Interface Customizations</td>
+</tr>
+<tr>
+ <td>clickAndWait</td>
+ <td>//input[@value='Update']</td>
+ <td></td>
+</tr>
+<tr>
+ <td>select</td>
+ <td>cat</td>
+ <td>label=Extensions: Language Tools</td>
+</tr>
+<tr>
+ <td>clickAndWait</td>
+ <td>//input[@value='Update']</td>
+ <td></td>
+</tr>
+<tr>
+ <td>select</td>
+ <td>cat</td>
+ <td>label=Extensions: Other</td>
+</tr>
+<tr>
+ <td>clickAndWait</td>
+ <td>//input[@value='Update']</td>
+ <td></td>
+</tr>
+<tr>
+ <td>select</td>
+ <td>cat</td>
+ <td>label=Extensions: Photos, Music & Videos</td>
+</tr>
+<tr>
+ <td>clickAndWait</td>
+ <td>//input[@value='Update']</td>
+ <td></td>
+</tr>
+<tr>
+ <td>select</td>
+ <td>cat</td>
+ <td>label=Extensions: Privacy & Security</td>
+</tr>
+<tr>
+ <td>clickAndWait</td>
+ <td>//input[@value='Update']</td>
+ <td></td>
+</tr>
+<tr>
+ <td>select</td>
+ <td>cat</td>
+ <td>label=Extensions: Search Tools</td>
+</tr>
+<tr>
+ <td>clickAndWait</td>
+ <td>//input[@value='Update']</td>
+ <td></td>
+</tr>
+<tr>
+ <td>select</td>
+ <td>cat</td>
+ <td>label=Extensions: Social & Communication</td>
+</tr>
+<tr>
+ <td>clickAndWait</td>
+ <td>//input[@value='Update']</td>
+ <td></td>
+</tr>
+<tr>
+ <td>select</td>
+ <td>cat</td>
+ <td>label=Extensions: Web Development</td>
+</tr>
+<tr>
+ <td>clickAndWait</td>
+ <td>//input[@value='Update']</td>
+ <td></td>
+</tr>
+<tr>
+ <td>select</td>
+ <td>cat</td>
+ <td>label=Themes: Animals</td>
+</tr>
+<tr>
+ <td>clickAndWait</td>
+ <td>//input[@value='Update']</td>
+ <td></td>
+</tr>
+<tr>
+ <td>select</td>
+ <td>cat</td>
+ <td>label=Themes: Compact</td>
+</tr>
+<tr>
+ <td>clickAndWait</td>
+ <td>//input[@value='Update']</td>
+ <td></td>
+</tr>
+<tr>
+ <td>select</td>
+ <td>cat</td>
+ <td>label=Themes: Large</td>
+</tr>
+<tr>
+ <td>clickAndWait</td>
+ <td>//input[@value='Update']</td>
+ <td></td>
+</tr>
+<tr>
+ <td>select</td>
+ <td>cat</td>
+ <td>label=Themes: Miscellaneous</td>
+</tr>
+<tr>
+ <td>clickAndWait</td>
+ <td>//input[@value='Update']</td>
+ <td></td>
+</tr>
+<tr>
+ <td>select</td>
+ <td>cat</td>
+ <td>label=Themes: Modern</td>
+</tr>
+<tr>
+ <td>clickAndWait</td>
+ <td>//input[@value='Update']</td>
+ <td></td>
+</tr>
+<tr>
+ <td>select</td>
+ <td>cat</td>
+ <td>label=Themes: Nature</td>
+</tr>
+<tr>
+ <td>clickAndWait</td>
+ <td>//input[@value='Update']</td>
+ <td></td>
+</tr>
+<tr>
+ <td>select</td>
+ <td>cat</td>
+ <td>label=Themes: OS Integration</td>
+</tr>
+<tr>
+ <td>clickAndWait</td>
+ <td>//input[@value='Update']</td>
+ <td></td>
+</tr>
+<tr>
+ <td>select</td>
+ <td>cat</td>
+ <td>label=Themes: Retro</td>
+</tr>
+<tr>
+ <td>clickAndWait</td>
+ <td>//input[@value='Update']</td>
+ <td></td>
+</tr>
+<tr>
+ <td>select</td>
+ <td>cat</td>
+ <td>label=Themes: Sports</td>
+</tr>
+<tr>
+ <td>clickAndWait</td>
+ <td>//input[@value='Update']</td>
+ <td></td>
+</tr>
+<tr>
+ <td>select</td>
+ <td>sort</td>
+ <td>label=Highest Rated</td>
+</tr>
+<tr>
+ <td>select</td>
+ <td>cat</td>
+ <td>label=Extensions: Web Development</td>
+</tr>
+<tr>
+ <td>clickAndWait</td>
+ <td>//input[@value='Update']</td>
+ <td></td>
+</tr>
+<tr>
+ <td>open</td>
+ <td>add-ons/view/138?ref=afnv</td>
+ <td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/site/app/tests/global.test.php b/site/app/tests/global.test.php
new file mode 100644
index 0000000..5d636eb
--- /dev/null
+++ b/site/app/tests/global.test.php
@@ -0,0 +1,50 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * Justin Scott <fligtar@gmail.com>.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+class GlobalTest extends UnitTestCase {
+
+ /**
+ WARNING: These tests will be run before EVERY single and group test
+ */
+
+ //Make sure there are no PHP errors
+ function testNoErrors() {
+ $this->assertNoErrors();
+ }
+}
+
+?> \ No newline at end of file
diff --git a/site/app/tests/groups.php b/site/app/tests/groups.php
new file mode 100644
index 0000000..bb4bb28
--- /dev/null
+++ b/site/app/tests/groups.php
@@ -0,0 +1,90 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * Justin Scott <fligtar@gmail.com>.
+ *
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Mike Morgan <morgamic@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+$_GET['groups'] = array(
+ 0 => array(
+ 'name' => 'Controllers',
+ 'description' => 'All controller tests',
+ 'cases' => array(
+ 'controllers/*'
+ )
+ ),
+ 1 => array(
+ 'name' => 'Components',
+ 'description' => 'All component tests',
+ 'cases' => array(
+ 'controllers/components/*'
+ )
+ ),
+ 2 => array(
+ 'name' => 'Services',
+ 'description' => 'All non-Cake backend services',
+ 'cases' => array(
+ 'services/*'
+ )
+ ),
+ 3 => array(
+ 'name' => 'Models',
+ 'description' => 'All model tests',
+ 'cases' => array(
+ 'models/*'
+ )
+ ),
+ 4 => array(
+ 'name' => 'Views',
+ 'description' => 'All view tests',
+ 'cases' => array(
+ 'views/*'
+ )
+ ),
+ 5 => array(
+ 'name' => 'Developers',
+ 'description' => 'Developer CP tests',
+ 'cases' => array(
+ 'controllers/developers_controller.test.php',
+ 'controllers/components/amo.test.php',
+ 'controllers/components/developers.test.php',
+ 'controllers/components/error.test.php',
+ 'controllers/components/rdf.test.php',
+ 'controllers/components/src.test.php',
+ 'views/developers/*'
+ )
+ ),
+);
+?>
diff --git a/site/app/tests/installation.test.php b/site/app/tests/installation.test.php
new file mode 100644
index 0000000..be4e419
--- /dev/null
+++ b/site/app/tests/installation.test.php
@@ -0,0 +1,220 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * Justin Scott <fligtar@gmail.com>.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Frederic Wenzel <fwenzel@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+class InstallationTest extends UnitTestCase {
+
+ /**
+ * Tests directory permissions
+ */
+ function testPermissions() {
+ $this->assertTrue(is_writable(CACHE), 'Permissions: '.CACHE.' writable');
+ $this->assertTrue(is_writable(REPO_PATH), 'Permissions: '.REPO_PATH.' writable');
+ $this->assertTrue(is_writable(REPO_PATH.'/temp'), 'Permissions: '.REPO_PATH.'/temp writable');
+ $this->assertTrue(is_writable(REPO_PATH.'/extracted'), 'Permissions: '.REPO_PATH.'/extracted writable');
+ $this->assertTrue(is_writable(TEST_DATA), 'Permissions: '.TEST_DATA.' writable');
+ if (defined('PUBLIC_STAGING_PATH')) {
+ $this->assertTrue(is_writable(PUBLIC_STAGING_PATH), 'Permissions: '.PUBLIC_STAGING_PATH.' writable');
+ }
+ }
+
+ /**
+ * Tests Apache and modules
+ */
+ function testApache() {
+ $this->assertTrue((strpos(apache_get_version(), 'Apache/2') !== false), 'Apache: Version 2');
+ $this->assertTrue(in_array('mod_rewrite', apache_get_modules()), 'Apache: Module mod_rewrite');
+ }
+
+ /**
+ * Tests PHP and extensions
+ */
+ function testPHP() {
+ $this->assertTrue((4 <= phpversion() && phpversion() < 6), 'PHP: Version '.phpversion());
+ $this->assertTrue(extension_loaded('gettext'), 'PHP: Extension gettext');
+ $this->assertTrue(extension_loaded('gd'), 'PHP: Extension gd');
+
+ $this->assertTrue(function_exists('mb_strlen'), 'PHP: mb_strlen is available');
+ $this->assertTrue(function_exists('mb_substr'), 'PHP: mb_substr is available');
+ $this->assertTrue(function_exists('mb_strrpos'), 'PHP: mb_strrpos is available');
+ $this->assertTrue(in_array('sha512', hash_algos()), 'PHP: sha512 is available');
+
+ $_memlimit_wanted = '16M';
+ $_memlimit_actual = $this->_return_bytes(ini_get('memory_limit'));
+ $this->assertTrue($_memlimit_actual >= $this->_return_bytes($_memlimit_wanted), "PHP's memory limit has to be larger or equal {$_memlimit_wanted}");
+ }
+
+ /**
+ * return bytes from php.ini shorthand notation such as "8M"
+ */
+ function _return_bytes($val) {
+ $val = trim($val);
+ $last = strtolower(substr($val, -1));
+ switch($last) {
+ // The 'G' modifier is available since PHP 5.1.0
+ case 'g':
+ $val *= 1024;
+ case 'm':
+ $val *= 1024;
+ case 'k':
+ $val *= 1024;
+ }
+ return $val;
+ }
+
+ /**
+ * Tests for PEAR and required modules
+ */
+ function testPear() {
+ $this->assertTrue(include_once('PEAR.php'), 'PEAR: PEAR');
+ $this->assertTrue(include_once('Archive/Zip.php'), 'PEAR: Module Archive_Zip');
+ }
+
+ /**
+ * Tests DB connections
+ */
+ function testDB() {
+ $db = ConnectionManager::getInstance();
+
+ //If the specific config is not even in the database file, we need to fail or PHP will have a fatal error.
+ if ($connected = @$db->getDataSource('default')) {
+ $this->assertTrue($connected->isConnected(), 'Database: default');
+
+ // Data in `addontypes`?
+ $r = $connected->fetchRow('SELECT count(*) as count FROM `addontypes`');
+ $this->assertTrue($r[0]['count']>0,'Data in `addontypes` exists.');
+ unset($r);
+
+ // Data in `translations`?
+ $r = $connected->fetchRow('SELECT count(*) as count FROM `translations`');
+ $this->assertTrue($r[0]['count']>0,'Data in `translations` exists.');
+ unset($r);
+ }
+ else {
+ $this->fail('Database: default - Your database configuration file is not up to date. Please re-copy the default.');
+ }
+ if ($connected = @$db->getDataSource('shadow')) {
+ $this->assertTrue($connected->isConnected(), 'Database: shadow');
+
+ // Data in `addontypes`?
+ $r = $connected->fetchRow('SELECT count(*) as count FROM `addontypes`');
+ $this->assertTrue($r[0]['count']>0,'Data in `addontypes` exists.');
+ unset($r);
+
+ // Data in `translations`?
+ $r = $connected->fetchRow('SELECT count(*) as count FROM `translations`');
+ $this->assertTrue($r[0]['count']>0,'Data in `translations` exists.');
+ unset($r);
+ }
+ else {
+ $this->fail('Database: shadow - Your database configuration file is not up to date. Please re-copy the default.');
+ }
+ if ($connected = $db->getDataSource('test')) {
+ $this->assertTrue($connected->isConnected(), 'Database: test');
+
+ // Data in `addontypes`?
+ $r = $connected->fetchRow('SELECT count(*) as count FROM `addontypes`');
+ $this->assertTrue($r[0]['count']>0,'Data in `addontypes` exists.');
+ unset($r);
+
+ // Data in `translations`?
+ $r = $connected->fetchRow('SELECT count(*) as count FROM `translations`');
+ $this->assertTrue($r[0]['count']>0,'Data in `translations` exists.');
+ unset($r);
+
+ // Test data in `addons`?
+ $r = $connected->fetchRow('SELECT count(*) as count FROM `addons`');
+ $this->assertTrue($r[0]['count']>0,'Test data in `addons` exists.');
+ unset($r);
+
+ // Test data in `addons_tags`?
+ $r = $connected->fetchRow('SELECT count(*) as count FROM `addons_tags`');
+ $this->assertTrue($r[0]['count']>0,'Test data in `addons_tags` exists.');
+ unset($r);
+
+ // Test data in `addons_users`?
+ $r = $connected->fetchRow('SELECT count(*) as count FROM `addons_users`');
+ $this->assertTrue($r[0]['count']>0,'Test data in `addons_users` exists.');
+ unset($r);
+
+ // Test data in `applications`?
+ $r = $connected->fetchRow('SELECT count(*) as count FROM `applications`');
+ $this->assertTrue($r[0]['count']>0,'Test data in `applications` exists.');
+ unset($r);
+
+ // Test data in `appversions`?
+ $r = $connected->fetchRow('SELECT count(*) as count FROM `appversions`');
+ $this->assertTrue($r[0]['count']>0,'Test data in `appversions` exists.');
+ unset($r);
+
+ // Test data in `files`?
+ $r = $connected->fetchRow('SELECT count(*) as count FROM `files`');
+ $this->assertTrue($r[0]['count']>0,'Test data in `files` exists.');
+ unset($r);
+
+ // Test data in `platforms`?
+ $r = $connected->fetchRow('SELECT count(*) as count FROM `platforms`');
+ $this->assertTrue($r[0]['count']>0,'Test data in `platforms` exists.');
+ unset($r);
+
+ // Test data in `previews`?
+ $r = $connected->fetchRow('SELECT count(*) as count FROM `previews`');
+ $this->assertTrue($r[0]['count']>0,'Test data in `previews` exists.');
+ unset($r);
+
+ // Test data in `tags`?
+ $r = $connected->fetchRow('SELECT count(*) as count FROM `tags`');
+ $this->assertTrue($r[0]['count']>0,'Test data in `tags` exists.');
+ unset($r);
+
+ // Test data in `users`?
+ $r = $connected->fetchRow('SELECT count(*) as count FROM `users`');
+ $this->assertTrue($r[0]['count']>0,'Test data in `users` exists.');
+ unset($r);
+
+ // Test data in `versions`?
+ $r = $connected->fetchRow('SELECT count(*) as count FROM `versions`');
+ $this->assertTrue($r[0]['count']>0,'Test data in `versions` exists.');
+ unset($r);
+ }
+ else {
+ $this->fail('Database: test - Your database configuration file is not up to date. Please re-copy the default.');
+ }
+ }
+
+}
+?>
diff --git a/site/app/tests/languageConfig.test.php b/site/app/tests/languageConfig.test.php
new file mode 100644
index 0000000..8586133
--- /dev/null
+++ b/site/app/tests/languageConfig.test.php
@@ -0,0 +1,291 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Wil Clouser <wclouser@mozilla.com> (Original Author)
+ * Justin Scott <fligtar@gmail.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+include_once APP_PATH.'config/bootstrap.php';
+
+class LanguageConfigTest extends WebTestHelper {
+
+ var $language_config;
+
+ function setUp()
+ {
+ // From bootstrap.php
+ global $valid_languages, $supported_languages;
+
+ $this->language_config = new LANGUAGE_CONFIG($valid_languages, $supported_languages, false);
+
+ }
+
+ /**
+ * Walk through our languages array and make sure all the language files exist.
+ */
+ function testLangFilesExist()
+ {
+ global $valid_languages;
+
+ $text_domain = $this->language_config->text_domain;
+
+ foreach ($valid_languages as $lang => $map) {
+ // So, gettext() has some logic built into it. If the current lang is
+ // set to, say, 'en-US' but there is no 'en-US' directory, it will fall
+ // back to 'en' (if it exists). We'll emulate this behavior here.
+
+ // First file we'll look for
+ $lang_file = "{$text_domain}/{$map}/LC_MESSAGES/messages.mo";
+
+ if (file_exists($lang_file)) {
+ //it's there, we're good to go.
+ continue;
+ }
+
+ // Check to see if our lang is a utf locale, and fallback on the non-utf map
+ // if the initial map has failed.
+ if (strpos($map,'.utf8')!==false) {
+ $buf = split('\.',$map);
+
+ if (file_exists("{$text_domain}/{$buf[0]}/LC_MESSAGES/messages.mo")) {
+ // Our utf-> non-utf fallback works, yay.
+ continue;
+ }
+ }
+
+ // Is a default lang always 2 characters, or should we look for a dash?
+ $map2 = substr($lang,0,2);
+
+ if (file_exists("{$text_domain}/{$map2}/LC_MESSAGES/messages.mo")) {
+ // Our fallback works, yay.
+ continue;
+ }
+
+ // Bad things
+ $this->fail("Couldn't find language file for ( {$lang} ) - looked for ( {$map} ) and ( {$map2} ).");
+ }
+
+ }
+
+ /**
+ * Our msgids should conform to the AMO L10n standards. Details at
+ * https://wiki.mozilla.org/Update:Remora_Localization#L10n_standards
+ *
+ * We'll only check en-US here, but the others are built off en-US so it should be a good indicator.
+ */
+ function testLangFileIsValid() {
+ $_language_file = "{$this->language_config->text_domain}/en_US/LC_MESSAGES/messages.po";
+
+ $_language_file_contents = file_get_contents($_language_file);
+
+ // If this test fails there is a string with spaces in it which is most likely an English string or
+ // sentence. This should be fixed before merging en-US -> all locales
+ $this->assertEqual(preg_match('/^msgid\ ".*?\ .*?"$/m', $_language_file_contents), 0);
+ }
+
+ /**
+ * Checks and makes sure index pages will load with all valid languages
+ */
+ function testLocalizedPagesLoad()
+ {
+ global $valid_languages;
+
+ $this->WebTestCase("Localized Pages aren't 404's Test :)");
+ foreach ($valid_languages as $lang => $mapping) {
+ $this->getPath($this->rawPath("/{$lang}"));
+ $this->assertResponse(array('200','301','302'), "Loading " . $this->rawPath("/{$lang}"));
+ }
+
+ // something to note, if cake is *not* in production mode (DEBUG != 0) the pages
+ // that don't exist actually come back with a 200 code instead of 404, which
+ // means this test will only pass in production. :-/ -- clouserw
+ $this->getAction("/xx-YY/");
+ if (DEBUG == 0)
+ $this->assertResponse(array('404'));
+ else
+ $this->assertResponse(array('200'));
+ }
+
+ /**
+ * Make sure we can detect languages from the URL
+ */
+ function testDetectCurrentLanguage()
+ {
+ $_temp = $_SERVER['QUERY_STRING'];
+
+ $_SERVER['QUERY_STRING'] = '';
+
+ // First part of the test is to try it with nothing - we should get back the default language.
+ $this->assertEqual($this->language_config->detectCurrentLanguage(), $this->language_config->default_language);
+
+ // While we're here, try it with the lang in $_GET
+ $_GET['lang'] = 'de';
+ $this->assertEqual($this->language_config->detectCurrentLanguage(), 'de');
+ unset($_GET['lang']);
+
+ // Next we'll try it with a language that doesn't exist:
+ $_SERVER['QUERY_STRING'] = 'url=xx-YY/addon/1';
+ $this->assertEqual($this->language_config->detectCurrentLanguage(), $this->language_config->default_language);
+
+ // And finally, with one that does exist:
+ $_SERVER['QUERY_STRING'] = 'url=fr/addon/1';
+ $this->assertEqual($this->language_config->detectCurrentLanguage(), 'fr');
+
+ // we'll put this back
+ $_SERVER['QUERY_STRING'] = $_temp;
+ }
+
+ /**
+ * Make sure the current language is set
+ */
+ function testGetCurrentLanguage()
+ {
+ // This isn't much of a test, but really, there isn't much to test. We can't
+ // use assertNotNull because the WebTestCase class doesn't have it :(
+ $this->assertNotEqual($this->language_config->getCurrentLanguage(), null);
+ }
+
+ /**
+ * Make sure we can set languages
+ */
+ function testSetCurrentLanguage()
+ {
+ // Try it with a bad language - should return false
+ $this->assertFalse($this->language_config->setCurrentLanguage(array('xx_YY')));
+
+
+ // Try it with a good language - should return true
+ $this->assertTrue($this->language_config->setCurrentLanguage(array('en-US')));
+ }
+
+ /**
+ * Test language setting via $_GET['lang'] arg passed by footer form.
+ * This is actually done in bootstrap, but this was a relevant place to put it.
+ */
+ function testBootstrapLanguageRedirect() {
+ global $valid_languages;
+
+ $this->WebTestCase("Testing that bootstrap allows users to choose a language.");
+ $this->_browser->skipParse = True;
+ foreach ($valid_languages as $lang => $mapping) {
+ // Bootstrap will do one redirect to switch lang.
+ $this->setMaximumRedirects(1);
+
+ // Check that $_GET overrides the rest of the URL
+ $path = $this->actionPath("/?lang={$lang}");
+ $this->getPath($path);
+
+ // If we pass a valid language, our page should redirect us.
+ // and should also have the correct URL.
+ $this->assertPattern('/lang="'.$lang.'"/', "Language {$lang} set for {$path}.");
+
+ // Bootstrap will do two redirects for app and lang if neither are present.
+ $this->setMaximumRedirects(2);
+
+ $path = $this->rawPath("/?lang={$lang}");
+ $this->getPath($path);
+
+ // If we pass a valid language, our page should redirect us.
+ // and should also have the correct URL.
+ $this->assertPattern('/lang="'.$lang.'"/', "Language {$lang} set for {$path}.");
+
+ // Bootstrap should only do one redirect if there's an app present, but no lang
+ $this->setMaximumRedirects(1);
+
+ $path = $this->rawPath("/firefox/?lang={$lang}");
+ $this->getPath($path);
+ // If we pass a valid language, our page should redirect us.
+ // and should also have the correct URL.
+ $this->assertPattern('/lang="'.$lang.'"/', "Language {$lang} set for {$path}.");
+
+ }
+
+ // If we pass an unknown language, there should be a redirect to a detected lang
+ $this->setMaximumRedirects(1);
+ $this->getPath($this->actionPath("")."/browse?lang=carebears");
+ $this->assertResponse('200','Redirect to detected language for bogus language');
+ }
+
+ /**
+ * Is the Accept-Language Request Header correctly interpreted?
+ */
+ function testRegularAcceptHeader() {
+ $this->addHeader('Accept-Language: en-us;q=0.7, de');
+ $this->getPath($this->rawPath('/firefox'));
+ $pattern = '#Alle Rechte vorbehalten#';
+ $this->assertPattern($pattern, 'Accept-language handler picks right locale according to score');
+ }
+
+ /**
+ * Is the AL header ignored if the URL contains a locale?
+ */
+ function testURLLocaleIgnoresALHeader() {
+ $this->addHeader('Accept-Language: de');
+ $this->getPath($this->rawPath('/en-US/firefox/'));
+ $pattern = '#All rights reserved#';
+ $this->assertPattern($pattern, 'Accept-language is ignored when URL contains locale');
+ }
+
+ /**
+ * Is 'de-de' in the AL header correctly resolved to 'de'?
+ */
+ function testALUnsharpMatching() {
+ $this->addHeader('Accept-Language: de-de, en-us;q=0.3');
+ $this->getPath($this->rawPath(''));
+ $pattern = '#Alle Rechte vorbehalten#';
+ $this->assertPattern($pattern, 'Accept-language handler resolves de-de to de');
+ }
+
+ /**
+ * Does a malformed AL header lead to a correct fallback?
+ */
+ function testMalformedALIgnored() {
+ $this->addHeader('Accept-Language: some,thing-very;very,,malform,ed!');
+ $this->getPath($this->actionPath('/browse'));
+ $pattern = '#All rights reserved#';
+ $this->assertPattern($pattern, 'Malformed Accept-language leads to fallback');
+ }
+
+ /**
+ * Do we fall back to the default when the langs requested are not supported?
+ */
+ function testUnsupportedALFallback() {
+ $this->addHeader('Accept-Language: xx-yy, xx;q=0.5');
+ $this->getPath($this->actionPath(''));
+ $pattern = '#All rights reserved#';
+ $this->assertPattern($pattern, 'Unsupported AL header request falls back to default');
+ }
+}
+?>
diff --git a/site/app/tests/models/addon.test.php b/site/app/tests/models/addon.test.php
new file mode 100644
index 0000000..0f59c7e
--- /dev/null
+++ b/site/app/tests/models/addon.test.php
@@ -0,0 +1,17 @@
+<?php
+
+class AddonModelTest extends UnitTestCase {
+
+ function AddonModelTest() {
+ loadModel('Addon');
+ $this->Addon = new Addon();
+ }
+
+ function testGetAddonsForAuthors() {
+ $this->assertEqual($this->Addon->getAddonsForAuthors(array(4)),
+ array(6));
+ $this->assertEqual(sort($this->Addon->getAddonsForAuthors(array(1, 3))),
+ array(1, 2, 3, 4, 5));
+ }
+}
+?>
diff --git a/site/app/tests/models/app_model.test.php b/site/app/tests/models/app_model.test.php
new file mode 100644
index 0000000..950d27c
--- /dev/null
+++ b/site/app/tests/models/app_model.test.php
@@ -0,0 +1,158 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Frederic Wenzel <fwenzel@mozilla.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/**
+ * These tests are for behavior that's common to all models.
+ */
+class App_ModelTest extends UnitTestCase {
+
+ function App_ModelTest() {
+ loadModel('Addon');
+ }
+
+ /**
+ * Check if default field handling works as expected
+ */
+ function testDefaultFields() {
+ $_id = 7;
+ $this->Addon = new Addon();
+
+ $this->assertFalse(empty($this->Addon->default_fields), 'Addon model needs some default fields defined');
+
+ // now do a default fetch and make sure the default fields and only
+ // those are returned
+ $addon = $this->Addon->findById($_id);
+ foreach ($this->Addon->default_fields as $field) {
+ if (false !== $_field = strstr($field, '.')) {
+ // get raw field name
+ $_field = substr($_field, 1);
+ $_field = trim($_field, '`');
+ } else {
+ $_field = $field;
+ }
+
+ // translated field or regular field?
+ if (in_array($_field, $this->Addon->translated_fields))
+ $_model = 'Translation';
+ else
+ $_model = 'Addon';
+
+ $_wasreturned = array_key_exists($_field, $addon[$_model]);
+ $this->assertTrue($_wasreturned, 'Default field "'.$_field.'" is returned');
+
+ if ($_wasreturned) {
+ // remove the field so that we can detect excessive returns later
+ unset($addon[$_model][$_field]);
+ }
+ }
+
+ $this->assertTrue(empty($addon['Addon']) && (!isset($addon['Translation']) || empty($addon['Translation'])), 'No excessive retrieval beyond list of default fields');
+ }
+
+ /**
+ * Test extended field validation
+ */
+ function testExtendedValidation() {
+ $testdata = array(
+ 'ValidationModel' => array(
+ 'testfield' => 'do not fail'
+ ));
+
+ // validation function should be called once
+ $vmodel = &new TallyValidationModel();
+ $vmodel->expectOnce('clean_testfield', array($testdata['ValidationModel']['testfield']));
+ $vmodel->invalidFields($testdata);
+ $vmodel->tally();
+
+ // now instanciate the real model and check if validationErrors is amended correctly
+ $vmodel = &new MockValidationModel();
+ $vmodel->invalidFields($testdata);
+ $this->assertTrue(empty($vmodel->validationErrors), 'valid field does not cause extended validation error');
+
+ $vmodel = &new MockValidationModel();
+ $testdata['ValidationModel']['testfield'] = 'fail';
+ $vmodel->invalidFields($testdata);
+ $this->assertFalse(empty($vmodel->validationErrors), 'invalid field causes extended validation error');
+ }
+
+ /**
+ * Test field validation for bulk translations
+ */
+ function testTranslationValidation() {
+ $testdata = array(
+ 'testfield' => array(
+ 'en-US' => 'okay',
+ 'ab-CD' => 'fail',
+ 'de' => 'okay'
+ )
+ );
+
+ // validation function should be called at least once
+ $vmodel = &new TallyValidationModel();
+ $vmodel->expectAtLeastOnce('clean_testfield');
+ $vmodel->expectMaximumCallCount('clean_testfield', count($testdata['testfield'])); // do not "over-validate"
+ $vmodel->validateTranslations($testdata);
+ $vmodel->tally();
+
+ // invalid translations should fail
+ $vmodel = &new MockValidationModel();
+ $res = $vmodel->validateTranslations($testdata);
+ $this->assertFalse($res, 'invalid translation leads to extended validation error');
+
+ // valid translations should not fail
+ $vmodel = &new MockValidationModel();
+ unset($testdata['testfield']['ab-CD']); // remove invalid data
+ $res = $vmodel->validateTranslations($testdata);
+ $this->assertTrue($res, '(only) valid translations should not lead to extended validation error');
+ }
+}
+
+class ValidationModel extends AppModel {
+ var $name = 'ValidationModel';
+ var $validate = array('testfield' => VALID_NOT_EMPTY);
+ var $translated_fields = array('testfield');
+ /**
+ * extended validation function: invalidates testfield iff it equals "fail"
+ */
+ function clean_testfield($input) {
+ if ($input == 'fail') $this->invalidate('testfield');
+ }
+}
+Mock::generatePartial('ValidationModel', 'TallyValidationModel', array('clean_testfield'));
+Mock::generatePartial('ValidationModel', 'MockValidationModel', array());
+?>
diff --git a/site/app/tests/models/collection.test.php b/site/app/tests/models/collection.test.php
new file mode 100644
index 0000000..fa31ebb
--- /dev/null
+++ b/site/app/tests/models/collection.test.php
@@ -0,0 +1,60 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ *
+ * Contributor(s):
+ * Jeff Balogh <jbalogh@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+class CollectionModelTest extends UnitTestCase {
+
+ function CollectionModelTest() {
+ loadModel('Collection');
+ $this->Collection = new Collection();
+ }
+
+ function testLimits() {
+ $name_limit = Collection::MAX_NAME_LENGTH;
+ $desc_limit = Collection::MAX_DESC_LENGTH;
+ $name = str_pad('', $name_limit + 1, '*');
+ $description = str_pad('', $desc_limit + 1, '*');
+
+ $saved = $this->Collection->save(array('name' => $name,
+ 'description' => $description));
+ $this->assertFalse($saved);
+
+ $errors = $this->Collection->validationErrors;
+ $this->assertEqual($errors['name'],
+ sprintf(___('collection_name_limit'), $name_limit));
+ $this->assertEqual($errors['description'],
+ sprintf(___('collection_description_limit'), $desc_limit));
+ }
+}
+?>
diff --git a/site/app/tests/models/collection_promos.test.php b/site/app/tests/models/collection_promos.test.php
new file mode 100644
index 0000000..24e9cfb
--- /dev/null
+++ b/site/app/tests/models/collection_promos.test.php
@@ -0,0 +1,66 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ *
+ * Contributor(s):
+ * Wil Clouser <wclouser@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+class CollectionPromoModelTest extends UnitTestCase {
+
+ function CollectionPromoModelTest() {
+ loadModel('CollectionPromo');
+ $this->CollectionPromo = new CollectionPromo();
+ $this->CollectionPromo->cacheQueries = false;
+ }
+
+ function testPromoteCollection() {
+ $this->assertEqual(array(), $this->CollectionPromo->execute('SELECT * FROM collection_promos'));
+ // All locales
+ $this->assertNotIdentical(false, $this->CollectionPromo->promoteCollection(1,1,''));
+ // German
+ $this->assertNotIdentical(false, $this->CollectionPromo->promoteCollection(1,1,'de'));
+ $this->assertEqual(2, count($this->CollectionPromo->execute('SELECT * FROM collection_promos')));
+ }
+ function testFindAll() {
+ $_ret = $this->CollectionPromo->findAll();
+ $this->assertEqual(array('all','de'), array_keys($_ret));
+ $this->assertEqual('Testo Collection Name', $_ret['all'][1][1]);
+ }
+ function testDemoteCollection() {
+ $this->assertEqual(2, count($this->CollectionPromo->execute('SELECT * FROM collection_promos')));
+ // All locales
+ $this->assertNotIdentical(false, $this->CollectionPromo->demoteCollection(1,1,''));
+ // German
+ $this->assertNotIdentical(false, $this->CollectionPromo->demoteCollection(1,1,'de'));
+ $this->assertEqual(array(), $this->CollectionPromo->execute('SELECT * FROM collection_promos'));
+ }
+}
+?>
diff --git a/site/app/tests/models/memcaching_model.test.php b/site/app/tests/models/memcaching_model.test.php
new file mode 100644
index 0000000..f2035c3
--- /dev/null
+++ b/site/app/tests/models/memcaching_model.test.php
@@ -0,0 +1,289 @@
+<?php /* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Frederic Wenzel <fwenzel@mozilla.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/**
+ * This tests if the Model interface to Memcached works as expected.
+ */
+
+class MemcachingModelTest extends UnitTestCase {
+ var $Cache; // holds the cache object
+ var $testdata = array('User' => array(
+ 'username' => 'johndoe',
+ 'firstname' => 'John',
+ 'lastname' => 'Doe',
+ 'email' => 'johndoe@example.com'));
+ // for object caching: identification array, arbitrary
+ var $identifier = array('my_test_data', 1234, array('some', 'more', 'info'));
+
+ /**
+ * Constructor
+ */
+ function MemcachingModelTest() {
+ loadModel('Memcaching');
+ }
+
+ /**
+ * On load, load the memcache object, if the config says it should work.
+ * Also set up an empty mem cache for each test.
+ */
+ function setUp() {
+ if (!QUERY_CACHE) {
+ $this->pass('Memcached caching is not activated.');
+ return;
+ }
+
+ if (!$this->Cache) {
+ // Memcache extension exists
+ $this->assertTrue(class_exists('Memcache'), 'Memcache extension is installed');
+
+ // Memcaching model is instanciable and connects to server
+ $this->Cache = new Memcaching();
+ $this->assertTrue($this->Cache->memcacheConnected, 'Memcaching model is instanciable and connects to server');
+ }
+ $this->Cache->flush();
+ }
+
+ function testSet() {
+ if (!QUERY_CACHE) return;
+ $this->assertTrue($this->Cache->set('testdata', $this->testdata), 'storing something in the memcache');
+ }
+
+ function testGet() {
+ if (!QUERY_CACHE) return;
+ $this->Cache->set('testdata', $this->testdata);
+ $this->assertEqual($this->Cache->get('testdata'), $this->testdata, 'retrieving something from the memcache');
+ }
+
+ function testAdd() {
+ if (!QUERY_CACHE) return;
+ $this->assertTrue($this->Cache->add('testdata', $this->testdata), 'add() something new to the memcache');
+ $this->assertFalse($this->Cache->add('testdata', array()), 'add() does not overwrite an existing key in the memcache');
+ }
+
+ function testReplace() {
+ if (!QUERY_CACHE) return;
+ $this->Cache->set('testdata', $this->testdata);
+ $this->assertTrue($this->Cache->replace('testdata', array('something', 'else')), 'replace() replaces existing data in the memcache');
+ $this->assertFalse($this->Cache->replace('doesntexist', $this->testdata), 'replace() does not add a key that did not exist before');
+ }
+
+ function testDelete() {
+ if (!QUERY_CACHE) return;
+ $this->Cache->set('testdata', $this->testdata);
+ $this->assertTrue($this->Cache->delete('testdata'), 'deleting existing data out of the memcache succeeds');
+ $this->assertFalse($this->Cache->get('testdata'), 'deleting actually works');
+ $this->assertFalse($this->Cache->delete('cantdeletethis'), 'deleting nonexistant data returns false');
+ }
+
+ function testFlush() {
+ if (!QUERY_CACHE) return;
+ $this->Cache->set('testdata', $this->testdata);
+ $this->assertTrue($this->Cache->flush(), 'flushing the cache succeeds');
+ $this->assertFalse($this->Cache->get('testdata'), 'flushing the cache actually works');
+ }
+
+ /**
+ * This test was added to make sure empty result sets are stored just
+ * like every other piece of data.
+ */
+ function testStoreAndRetrieveEmpty() {
+ if (!QUERY_CACHE) return;
+ // storing an empty array in the memcache...
+ $this->assertTrue($this->Cache->set('emptydata', array()), 'storing an empty array succeeds');
+
+ // ... and retrieving it
+ $_retrieved = $this->Cache->get('emptydata');
+ $this->assertTrue(is_array($_retrieved) && empty($_retrieved), 'retrieving an empty array from the memcache works');
+ }
+
+ /**
+ * Here we want to verify that when someone calls findAll() or query()
+ * they still get unique results by $model->name.
+ */
+ function testUniqueRecordsByModelName() {
+ if (!QUERY_CACHE) return;
+ loadmodel('Addontype');
+ loadmodel('Platform');
+
+ // Load test models.
+ $model1 =& new Addontype();
+ $model2 =& new Platform();
+
+ // Do one callback to load the cache.
+ $model1->findAll(null, null, null, null, null, -1);
+ $model2->findAll(null, null, null, null, null, -1);
+
+ // Perform a second callback to see what the cache spits out the serialize.
+ $addontypes = serialize($model1->findAll(null, null, null, null, null, -1));
+ $platforms = serialize($model2->findAll(null, null, null, null, null, -1));
+
+ $this->assertNotEqual($addontypes, $platforms, 'Addontypes and Platforms differed by model name when pulled from cache by findAll().');
+ }
+
+ /**
+ * Test that we can get extended stats.
+ */
+ function testGetExtendedStats() {
+ if (!QUERY_CACHE) return;
+ $this->assertIsA($this->Cache->getExtendedStats(),'array');
+ }
+
+ /**
+ * Check if memcache-ing does not store query errors
+ */
+ function testMemcacheNoErrors() {
+ if (!QUERY_CACHE) return;
+
+ loadmodel('Addon');
+ $this->Addon = new Addon();
+
+ // replace Memcaching object by mock object to catch unwanted calls
+ Mock::generate('MyMemcaching');
+ $this->Addon->Cache = new MockMyMemcaching();
+ // assert that the model does not try to store the invalid result to memcache
+ $this->Addon->Cache->expectNever('set', 'invalid query should not be cached');
+
+ $invalidquery = 'SELECT something invalid'; // SELECT query that'll fail
+
+ // execute invalid query
+ @$this->Addon->query($invalidquery);
+ }
+
+ /* * * Tests for object caching * * */
+
+ /**
+ * Test the generation of a cache key
+ */
+ function testGenerateCacheKey() {
+ if (!QUERY_CACHE) return;
+
+ // make a second, different identifier array
+ $ident2 = $this->identifier;
+ array_pop($ident2);
+ $ident2[] = 'something else';
+
+ $key1 = $this->Cache->_generateCacheKey($this->identifier);
+ $key2 = $this->Cache->_generateCacheKey($ident2);
+ $this->assertFalse(empty($key1) || empty($key2), '_generateCacheKey() generating nonempty cache keys');
+
+ $this->assertNotEqual($key1, $key2, 'different cache keys for different identifiers');
+ }
+
+ /**
+ * Try to write, then read an object through the object caching interface,
+ * including writing to an expiration list.
+ */
+ function testReadWriteCacheObject() {
+ if (!QUERY_CACHE) return;
+
+ Mock::generatePartial('Memcaching', 'Mock_testRWCacheObj', array('set', 'get',
+ '_generateCacheKey', '_addObjectToExpirationList'));
+ $mockCache =& new Mock_testRWCacheObj();
+
+ // mock a known cache key
+ $_mock_cachekey = 'amo_unittest_cachekey';
+ $mockCache->setReturnValue('_generateCacheKey', $_mock_cachekey, array($this->identifier));
+
+ // assertions for writing
+ $mockCache->setReturnValue('set', true);
+ $mockCache->expectOnce('set', array($_mock_cachekey, $this->testdata, '*', '*'),
+ 'storing object in cache');
+
+ // assertions for reading
+ $mockCache->expectOnce('get', array($_mock_cachekey), 'reading object back from cache');
+
+ // assertions for expiration lists
+ $_expiration_lists = array('addon' => array(1, 2));
+ $startlist = array('amo_unittest_existing_cachekey');
+ $mockCache->expectCallCount('_addObjectToExpirationList', 2);
+
+ // write an object to the cache
+ $mockCache->writeCacheObject($this->identifier, $this->testdata, $_expiration_lists);
+
+ // read the same object back
+ $mockCache->readCacheObject($this->identifier);
+
+
+ // count calls
+ $mockCache->tally();
+ }
+
+ /**
+ * Test marking/flushing of expiration lists
+ */
+ function testExpirationListFlush() {
+ if (!QUERY_CACHE) return;
+
+ // generate empty flush list
+ global $flush_lists;
+ $flush_lists = array();
+
+ Mock::generatePartial('Memcaching', 'Mock_testExpListFlush', array('get', 'delete'));
+ $this->Cache =& new Mock_testExpListFlush();
+
+ // add list ids to flush list
+ $this->Cache->markListForFlush('list 1');
+ $this->Cache->markListForFlush('list 2');
+ $this->assertEqual(count($flush_lists), 2, 'adding items to cache flush list');
+
+ // prepare a list, then have it flushed from memcache
+ $flush_lists = array('list1', 'list2');
+ $testlist1 = array('foo1', 'bar1');
+ $testlist2 = array('foo2', 'bar2');
+ $this->Cache->setReturnValue('get', $testlist1, array('list1'));
+ $this->Cache->setReturnValue('get', $testlist2, array('list2'));
+ // assert that the lists are going to be read
+ $this->Cache->expectCallCount('get', 2);
+ // ... and emptied (6 times: 2 times 2 objects in the lists, plus the lists themselves)
+ $this->Cache->expectCallCount('delete', 6);
+
+ $this->Cache->flushMarkedLists();
+
+ $this->Cache->tally();
+ }
+
+}
+
+/**
+ * Mock memcache object
+ */
+class MyMemcaching {
+ function get() {}
+ function set() {}
+}
+
+?>
diff --git a/site/app/tests/models/memcaching_web.test.php b/site/app/tests/models/memcaching_web.test.php
new file mode 100644
index 0000000..a1ef5c6
--- /dev/null
+++ b/site/app/tests/models/memcaching_web.test.php
@@ -0,0 +1,112 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Frederic Wenzel <fwenzel@mozilla.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/**
+ * These Memcache tests are web tests so we can test how locale/
+ * app changes affect caching
+ */
+
+class MemcachingWebTest extends WebTestHelper {
+ var $id = 7;
+ var $Cache; // holds the cache object
+
+ function MemcachingWebTest() {
+ loadModel('Memcaching');
+ loadModel('Addon');
+ }
+
+ /**
+ * Flush the cache before the test
+ */
+ function setUp() {
+ if (!QUERY_CACHE) {
+ $this->pass('Memcached caching is not activated.');
+ return;
+ }
+ if (!$this->Cache) {
+ // Memcache extension exists
+ $this->assertTrue(class_exists('Memcache'), 'Memcache extension is installed');
+
+ // Memcaching model is instanciable and connects to server
+ $this->Cache = new Memcaching();
+ $this->assertTrue($this->Cache->memcacheConnected, 'Memcaching model is instanciable and connects to server');
+ }
+ $this->Cache->flush();
+ }
+
+ /**
+ * Make sure caching pays attention to LANG
+ */
+ function testCachingRespectsLANG() {
+ if (!QUERY_CACHE) return;
+
+ // get German and English Addon data to compare with
+ $this->Addon = new Addon();
+ $this->Addon->caching = false;
+ $this->Addon->cacheQueries = false;
+ $no_controller = null;
+ $this->Addon->setLang('de', $no_controller);
+ $german = $this->Addon->findById($this->id);
+ $this->Addon->setLang('en-US', $no_controller);
+ $english = $this->Addon->findById($this->id);
+ // if the names are the same, this won't work...
+ $this->assertNotEqual($german['Translation']['name']['string'], $english['Translation']['name']['string'], "English and German Strings of Addon #{$this->id} have to differ for cache test to work");
+
+ $_uri = $this->actionURI("/addon/" . $this->id);
+ $_en_uri = str_replace('/'.LANG.'/', '/en-US/', $_uri);
+ $_de_uri = str_replace('/'.LANG.'/', '/de/', $_uri);
+
+ // fetch the German page (this should get cached)
+ $this->get($_de_uri);
+ // check if it contains the German name
+ $this->assertText($german['Translation']['name']['string'], 'German page contains German Addon name');
+ // and, it obviously shouldn't have the English name
+ $this->assertNoText($english['Translation']['name']['string'], 'German page does not contain English Addon name');
+
+ // fetch the English page
+ $this->get($_en_uri);
+ // check if it contains the German name (in which case we incorrectly
+ // got a cache hit)
+ $this->assertNoText($german['Translation']['name']['string'], 'English page must not contain German Addon name');
+ // but it should have the English name
+ $this->assertText($english['Translation']['name']['string'], 'English page contains English Addon name');
+
+ }
+
+}
+?>
diff --git a/site/app/tests/models/translation_model.test.php b/site/app/tests/models/translation_model.test.php
new file mode 100644
index 0000000..ebb3c77
--- /dev/null
+++ b/site/app/tests/models/translation_model.test.php
@@ -0,0 +1,130 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Wil Clouser <wclouser@mozilla.com> (Original Author)
+ * Frederic Wenzel <fwenzel@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/**
+ * This does not actually test the Translation MODEL, however
+ * it tests if dynamically adding the translations to cake queries
+ * works correctly.
+ */
+class TranslationTest extends UnitTestCase {
+
+ var $addon_id = 7;
+ var $translation;
+
+ function TranslationTest() {
+ loadModel('Addon');
+ }
+
+ function setUp()
+ {
+ $this->Tag =& new Tag();
+ }
+
+ /**
+ * Make sure our data is rearranged correctly
+ */
+ function testAfterFind()
+ {
+
+ $_all_data = $this->Tag->findAll();
+
+ // General check - make sure we got data back
+ $this->assertEqual($_all_data[0]['Translation']['name']['string'], 'Developer Tools');
+
+ // Since en-US == LANG, this should be empty
+ $this->assertEqual($_all_data[0]['Translation']['name']['locale_html'], '');
+
+ // If we could override LANG, I'd make sure our fallbacks were working
+ // (ie. we request de, but only en-US is available). People are anxious to see
+ // this code though, so I'm committing. -- clouserw
+
+ }
+
+ /**
+ * If we store a translation first and then remove it, does fallback
+ * still work as expected?
+ */
+ function testFallBackWithEmptyTranslations() {
+ $_id = $this->addon_id;
+
+ $this->Addon = new Addon();
+ $this->Addon->caching = false;
+ $this->Addon->cacheQueries = false;
+ $this->Addon->setLang('de');
+ $oldAddonData = $this->Addon->find(array('Addon.id'=>$_id));
+ // did we get a German name?
+ $this->assertEqual($oldAddonData['Translation']['name']['locale'], 'de', 'Localized string fetching works');
+
+ $emptyData = array('Addon' => array(
+ 'id' => $_id,
+ 'name' => ''));
+
+ // replace it by an empty name
+ $_res = $this->Addon->save($emptyData, false, array('id','name'));
+ $this->assertTrue($_res, 'Storing an empty translation succeeds');
+
+ // re-fetch it and test if fallback works
+ $newAddonData = $this->Addon->find(array('Addon.id'=>$_id));
+ $this->assertFalse(empty($newAddonData['Translation']['name']['string']), 'Re-fetched string is not empty');
+ $this->assertNotEqual($newAddonData['Translation']['name']['string'], $oldAddonData['Translation']['name']['string'], 'Re-fetched string is different');
+ $this->assertNotEqual($newAddonData['Translation']['name']['locale'], 'de', 'Fallback locale is different as expected');
+
+ // fix the changed name
+ $_restoredata = array('Addon' => array(
+ 'id' => $_id,
+ 'name' => $oldAddonData['Translation']['name']['string']));
+ $_res = $this->Addon->save($_restoredata, null, array('id','name'));
+ $this->assertTrue($_res, 'Restoring the previous translation succeeds');
+
+ $newestAddonData = $this->Addon->find(array('Addon.id'=>$_id));
+ $this->assertEqual($oldAddonData['Translation']['name']['string'], $newestAddonData['Translation']['name']['string'], 'Saved string is correct');
+ $this->assertEqual($oldAddonData['Translation']['name']['locale'], 'de', 'Saved locale is correct');
+ }
+
+ /**
+ * Make sure findCount() doesn't get hosed by the whole translation stuff
+ */
+ function testFindCountTransactionResistant() {
+ $this->Addon = new Addon();
+ $addoncount = $this->Addon->findCount(array('Addon.id'=>$this->addon_id));
+ $this->assertTrue($addoncount > 0, 'findCount is resistant to translation code');
+ }
+
+}
+?>
diff --git a/site/app/tests/models/user.test.php b/site/app/tests/models/user.test.php
new file mode 100644
index 0000000..19ee3b1
--- /dev/null
+++ b/site/app/tests/models/user.test.php
@@ -0,0 +1,115 @@
+<?php
+
+/**
+ * Helper to return a "User" with the $password.
+ */
+function _user($password) {
+ return array('password' => $password);
+}
+
+
+class UserModelTest extends UnitTestCase {
+
+ function UserModelTest() {
+ loadModel('User');
+ $this->User = new User();
+ // RUN THE QUERY, CAKE.
+ $this->User->cacheQueries = False;
+ }
+
+ /* Make sure the helper works. */
+ function test_user(){
+ $password = 'yar';
+ $user = _user($password);
+ $this->assertEqual($user['password'], $password);
+ }
+
+ function testCheckPassword() {
+ $this->assertFalse($this->User->checkPassword(_user(''), ''),
+ "Users with empty passwords never pass.");
+
+ $raw = 'foo';
+ $encrypted = $this->User->createPassword($raw);
+ $this->assertTrue($this->User->checkPassword(_user($encrypted), $raw),
+ "Valid password works.");
+ $this->assertFalse($this->User->checkPassword(_user($encrypted), 'bar'),
+ "Non-matching passwords don't pass.");
+
+ }
+
+ function test_md5Update() {
+
+ // Check updating a user with an existing md5 password.
+ $id = 555;
+ $raw = 'foo';
+ $md5password = md5($raw);
+ $this->User->execute("INSERT INTO users (id, password)
+ VALUES ({$id}, '{$md5password}')");
+ $newUser = $this->User->findById($id);
+
+ $this->assertTrue($this->User->checkPassword($newUser['User'], $raw),
+ "The password checks out with md5.");
+
+ // TODO: will caching be affected in production?
+ $this->User->caching = False;
+ $updatedUser = $this->User->findById($id);
+ $newPassword = $updatedUser['User']['password'];
+ $this->assertTrue($this->User->_checkPassword($raw, $newPassword),
+ "The old md5 password was updated.");
+
+ $this->User->del($id);
+ }
+
+ function test_checkPassword() {
+ $raw = 'foo';
+ $encrypted = $this->User->createPassword($raw);
+ $this->assertTrue($this->User->_checkPassword($raw, $encrypted));
+ $this->assertFalse($this->User->_checkPassword('', $encrypted));
+ }
+
+ function testGetHexDigest() {
+ $algo = 'sha512';
+ $salt = 'foo';
+ $password = 'bar';
+ $this->assertEqual($this->User->getHexDigest($algo, $salt, $password),
+ hash($algo, $salt.$password));
+ }
+
+ function testCreatePassword() {
+ $algo = 'sha512';
+ $rawPassword = 'bla';
+ $password = $this->User->createPassword($rawPassword);
+
+ list($hashedAlgo, $hashedSalt, $hashedPassword) = split('\$', $password);
+ $this->assertEqual($algo, $hashedAlgo);
+ $this->assertEqual($this->User->getHexDigest($algo, $hashedSalt, $rawPassword),
+ $hashedPassword);
+ }
+
+ function testResetCode() {
+ $id = 555;
+ $this->User->execute("INSERT INTO users(id) VALUES ({$id})");
+
+ $this->User->setResetCode($id);
+ $user = $this->User->findById($id);
+
+ $this->assertTrue(!empty($user['User']['resetcode']), "The resetcode was set");
+
+ list($expire_date, ) = split(' ', $user['User']['resetcode_expires']);
+ $expires = date('Y-m-d', strtotime(PASSWORD_RESET_EXPIRES.' days'));
+ $this->assertTrue($expire_date == $expires,
+ 'The resetcode expires in '.PASSWORD_RESET_EXPIRES.' days.');
+
+ $this->assertTrue($this->User->checkResetCode($id, $user['User']['resetcode']),
+ "The resetcode validates.");
+ $this->assertFalse($this->User->checkResetCode($id, 'bla'), "Invalid resetcode fails.");
+
+ $this->User->execute("UPDATE users SET resetcode_expires='0000-00-00 00:00:00'
+ WHERE id={$id}");
+ $this->assertFalse($this->User->checkResetCode($id, $user['User']['resetcode']),
+ "An expired resetcode doesn't work.");
+
+ $this->User->del($id);
+ }
+}
+?>
diff --git a/site/app/tests/multiapp.test.php b/site/app/tests/multiapp.test.php
new file mode 100644
index 0000000..af6269e
--- /dev/null
+++ b/site/app/tests/multiapp.test.php
@@ -0,0 +1,80 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla Corporation (shaver@mozilla.com).
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+class MultiAppTest extends WebTestHelper {
+ function testRedirectWhenNoAppProvided() {
+ $this->setMaximumRedirects(0);
+ $this->get($this->rawURI('/' . LANG . '/'));
+ $this->assertResponse('302', 'redirected to include app: %s');
+ $this->assertHeader('Location', $this->actionURI('/'));
+ }
+
+ /**
+ * Test if we redirect for Seamonkey based on User Agent string
+ */
+ function testRedirectForSeamonkey() {
+ global $app_shortnames;
+
+ $this->setMaximumRedirects(0);
+ // pretend we are running SeaMonkey
+ $this->addHeader('User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9a6pre) Gecko/20070625 SeaMonkey/2.0a1pre');
+ $this->get($this->rawURI('/' . LANG . '/'));
+ // redirected to seamonkey subpage?
+ $this->assertResponse(302);
+ $seamonkey_short = array_search(APP_SEAMONKEY, $app_shortnames);
+ $this->assertTrue($seamonkey_short !== false, 'seamonkey short name found');
+ $this->assertHeader('Location', new PatternExpectation("/{$seamonkey_short}/"));
+ }
+
+ function nyi_testAppNameInTitle() {
+ $this->setMaximumRedirects(0);
+ $this->get($this->rawPath("/en-US/thunderbird/"));
+ }
+
+ function nyi_testRecommendedList() {
+
+ }
+
+ function nyi_testAddonTypeList() {
+
+ }
+
+ function nyi_testSwitchingLanguagePreservesApp() {
+
+ }
+}
+?>
diff --git a/site/app/tests/oldUrls.test.php b/site/app/tests/oldUrls.test.php
new file mode 100644
index 0000000..ff7412b
--- /dev/null
+++ b/site/app/tests/oldUrls.test.php
@@ -0,0 +1,88 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla Corporation (shaver@mozilla.com).
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Frederic Wenzel <fwenzel@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+class OldUrlsTest extends WebTestHelper {
+ var $apps = array("firefox", "thunderbird", "sunbird", "seamonkey");
+
+ function testAddonId() {
+ foreach ($this->apps as $app) {
+ $path = $this->rawPath("/{$app}/9/");
+ $this->getPath($path);
+ $this->assertPattern('/MicroHunter/', 'Legacy support for /' . $app . '/$addonId/ (' . $path . ')');
+ }
+ }
+
+ function testAddonIdIsRedirect() {
+ foreach ($this->apps as $app) {
+ $this->setMaximumRedirects(0);
+ $this->getPath($this->rawPath("/{$app}/9/"));
+ $this->assertHeader('Location', $this->rawURI("/{$app}/addon/9"));
+ }
+ }
+
+ function testAuthorId() {
+ foreach ($this->apps as $app) {
+ $path = $this->rawPath("/{$app}/5/author");
+ $this->getPath($path);
+ $this->assertPattern('/User Profile/', 'Legacy support for /' . $app . '/$authorId/author/ (' . $path . ')');
+ }
+ }
+
+ function testAuthorIdIsRedirect() {
+ foreach ($this->apps as $app) {
+ $this->setMaximumRedirects(0);
+ $this->getPath($this->rawPath("/{$app}/5/author"));
+ $this->assertHeader('Location', $this->rawURI("/{$app}/user/5"));
+ }
+ }
+
+ function testLegacyRSSFeeds() {
+ $addontypes = array('extensions', 'themes');
+ $sortorders = array('popular', 'updated', 'rated');
+ foreach ($this->apps as $app) {
+ foreach ($addontypes as $type) {
+ foreach ($sortorders as $order) {
+ $path = $this->rawPath("/rss/{$app}/{$type}/{$order}");
+ $this->getPath($path);
+ $this->assertPattern('/rss version="2.0"/', "Legacy support for {$path}");
+ }
+ }
+ }
+ }
+}
+?>
diff --git a/site/app/tests/search.html b/site/app/tests/search.html
new file mode 100644
index 0000000..e4a8600
--- /dev/null
+++ b/site/app/tests/search.html
@@ -0,0 +1,467 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head profile="http://selenium-ide.openqa.org/profiles/test-case">
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+<link rel="selenium.base" href="http://preview.addons.mozilla.org" />
+<title>search</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">search</td></tr>
+</thead><tbody>
+<tr>
+ <td>open</td>
+ <td>/en-US/firefox/search?q=foxytunes&amp;cat=all</td>
+ <td></td>
+</tr>
+<tr>
+ <td>verifyElementPresent</td>
+ <td>link=FoxyTunes</td>
+ <td></td>
+</tr>
+<tr>
+ <td>open</td>
+ <td>/en-US/firefox/search?q=foxytunes&amp;cat=all&amp;as=true&amp;vfuz=true&amp;appid=1&amp;lver=1.0&amp;hver=1.0&amp;atype=0&amp;pid=0&amp;lup=&amp;pp=20&amp;sort=</td>
+ <td></td>
+</tr>
+<tr>
+ <td>verifyTextNotPresent</td>
+ <td>FoxyTunes</td>
+ <td></td>
+</tr>
+<tr>
+ <td>open</td>
+ <td>/en-US/firefox/search?q=foxytunes&amp;cat=all&amp;as=true&amp;vfuz=true&amp;appid=1&amp;lver=1.0&amp;hver=1.5&amp;atype=0&amp;pid=0&amp;lup=&amp;pp=20&amp;sort=</td>
+ <td></td>
+</tr>
+<tr>
+ <td>verifyElementPresent</td>
+ <td>link=FoxyTunes</td>
+ <td></td>
+</tr>
+<tr>
+ <td>open</td>
+ <td>/en-US/firefox/search?q=foxytunes&amp;cat=all&amp;as=true&amp;vfuz=true&amp;appid=1&amp;lver=1.0&amp;hver=2.0&amp;atype=0&amp;pid=0&amp;lup=&amp;pp=20&amp;sort=</td>
+ <td></td>
+</tr>
+<tr>
+ <td>verifyElementPresent</td>
+ <td>link=FoxyTunes</td>
+ <td></td>
+</tr>
+<tr>
+ <td>open</td>
+ <td>/en-US/firefox/search?q=foxytunes&amp;cat=all&amp;as=true&amp;vfuz=true&amp;appid=1&amp;lver=1.0&amp;hver=3.0&amp;atype=0&amp;pid=0&amp;lup=&amp;pp=20&amp;sort=</td>
+ <td></td>
+</tr>
+<tr>
+ <td>verifyElementPresent</td>
+ <td>link=FoxyTunes</td>
+ <td></td>
+</tr>
+<tr>
+ <td>open</td>
+ <td>/en-US/firefox/search?q=foxytunes&amp;cat=all&amp;as=true&amp;vfuz=true&amp;appid=1&amp;lver=1.0&amp;hver=3.1&amp;atype=0&amp;pid=0&amp;lup=&amp;pp=20&amp;sort=</td>
+ <td></td>
+</tr>
+<tr>
+ <td>verifyElementPresent</td>
+ <td>link=FoxyTunes</td>
+ <td></td>
+</tr>
+<tr>
+ <td>open</td>
+ <td>/en-US/firefox/search?q=foxytunes&amp;cat=all&amp;as=true&amp;vfuz=true&amp;appid=1&amp;lver=1.0&amp;hver=any&amp;atype=0&amp;pid=0&amp;lup=&amp;pp=20&amp;sort=</td>
+ <td></td>
+</tr>
+<tr>
+ <td>verifyElementPresent</td>
+ <td>link=FoxyTunes</td>
+ <td></td>
+</tr>
+<tr>
+ <td>open</td>
+ <td>/en-US/firefox/search?q=foxytunes&amp;cat=all&amp;as=true&amp;vfuz=true&amp;appid=1&amp;lver=1.5&amp;hver=any&amp;atype=0&amp;pid=0&amp;lup=&amp;pp=20&amp;sort=</td>
+ <td></td>
+</tr>
+<tr>
+ <td>verifyElementPresent</td>
+ <td>link=FoxyTunes</td>
+ <td></td>
+</tr>
+<tr>
+ <td>open</td>
+ <td>/en-US/firefox/search?q=foxytunes&amp;cat=all&amp;as=true&amp;vfuz=true&amp;appid=1&amp;lver=2.0&amp;hver=any&amp;atype=0&amp;pid=0&amp;lup=&amp;pp=20&amp;sort=</td>
+ <td></td>
+</tr>
+<tr>
+ <td>verifyElementPresent</td>
+ <td>link=FoxyTunes</td>
+ <td></td>
+</tr>
+<tr>
+ <td>open</td>
+ <td>/en-US/firefox/search?q=foxytunes&amp;cat=all&amp;as=true&amp;vfuz=true&amp;appid=1&amp;lver=3.0&amp;hver=any&amp;atype=0&amp;pid=0&amp;lup=&amp;pp=20&amp;sort=</td>
+ <td></td>
+</tr>
+<tr>
+ <td>verifyElementPresent</td>
+ <td>link=FoxyTunes</td>
+ <td></td>
+</tr>
+<tr>
+ <td>open</td>
+ <td>/en-US/firefox/search?q=foxytunes&amp;cat=all&amp;as=true&amp;vfuz=true&amp;appid=1&amp;lver=3.1&amp;hver=any&amp;atype=0&amp;pid=0&amp;lup=&amp;pp=20&amp;sort=</td>
+ <td></td>
+</tr>
+<tr>
+ <td>verifyTextPresent</td>
+ <td>No results found.</td>
+ <td></td>
+</tr>
+<tr>
+ <td>open</td>
+ <td>/en-US/firefox/search?q=foxytunes&amp;cat=all&amp;as=true&amp;vfuz=true&amp;appid=1&amp;lver=any&amp;hver=any&amp;atype=0&amp;pid=0&amp;lup=&amp;pp=20&amp;sort=</td>
+ <td></td>
+</tr>
+<tr>
+ <td>verifyElementPresent</td>
+ <td>link=FoxyTunes</td>
+ <td></td>
+</tr>
+<tr>
+ <td>open</td>
+ <td>/en-US/firefox/search?q=foxytunes&amp;cat=all&amp;as=true&amp;vfuz=true&amp;appid=1&amp;lver=any&amp;hver=any&amp;atype=1&amp;pid=0&amp;lup=&amp;pp=20&amp;sort=</td>
+ <td></td>
+</tr>
+<tr>
+ <td>verifyElementPresent</td>
+ <td>link=FoxyTunes</td>
+ <td></td>
+</tr>
+<tr>
+ <td>open</td>
+ <td>/en-US/firefox/search?q=foxytunes&amp;cat=all&amp;as=true&amp;vfuz=true&amp;appid=1&amp;lver=any&amp;hver=any&amp;atype=2&amp;pid=0&amp;lup=&amp;pp=20&amp;sort=</td>
+ <td></td>
+</tr>
+<tr>
+ <td>verifyTextNotPresent</td>
+ <td>FoxyTunes</td>
+ <td></td>
+</tr>
+<tr>
+ <td>open</td>
+ <td>/en-US/firefox/search?q=foxytunes&amp;cat=all&amp;as=true&amp;vfuz=true&amp;appid=1&amp;lver=any&amp;hver=any&amp;atype=3&amp;pid=0&amp;lup=&amp;pp=20&amp;sort=</td>
+ <td></td>
+</tr>
+<tr>
+ <td>verifyTextPresent</td>
+ <td>No results found.</td>
+ <td></td>
+</tr>
+<tr>
+ <td>open</td>
+ <td>/en-US/firefox/search?q=foxytunes&amp;cat=all&amp;as=true&amp;vfuz=true&amp;appid=1&amp;lver=any&amp;hver=any&amp;atype=4&amp;pid=0&amp;lup=&amp;pp=20&amp;sort=</td>
+ <td></td>
+</tr>
+<tr>
+ <td>verifyTextPresent</td>
+ <td>No results found.</td>
+ <td></td>
+</tr>
+<tr>
+ <td>open</td>
+ <td>/en-US/firefox/search?q=foxytunes&amp;cat=all&amp;as=true&amp;vfuz=true&amp;appid=1&amp;lver=any&amp;hver=any&amp;atype=5&amp;pid=0&amp;lup=&amp;pp=20&amp;sort=</td>
+ <td></td>
+</tr>
+<tr>
+ <td>verifyTextPresent</td>
+ <td>No results found.</td>
+ <td></td>
+</tr>
+<tr>
+ <td>open</td>
+ <td>/en-US/firefox/search?q=foxytunes&amp;cat=all&amp;as=true&amp;vfuz=true&amp;appid=1&amp;lver=any&amp;hver=any&amp;atype=5&amp;pid=3&amp;lup=&amp;pp=20&amp;sort=</td>
+ <td></td>
+</tr>
+<tr>
+ <td>verifyTextPresent</td>
+ <td>No results found.</td>
+ <td></td>
+</tr>
+<tr>
+ <td>open</td>
+ <td>/en-US/firefox/search?q=foxytunes&amp;cat=all&amp;as=true&amp;vfuz=true&amp;appid=1&amp;lver=any&amp;hver=any&amp;atype=1&amp;pid=3&amp;lup=&amp;pp=20&amp;sort=</td>
+ <td></td>
+</tr>
+<tr>
+ <td>verifyElementPresent</td>
+ <td>link=FoxyTunes</td>
+ <td></td>
+</tr>
+<tr>
+ <td>open</td>
+ <td>/en-US/firefox/search?q=foxytunes&amp;cat=all&amp;as=true&amp;vfuz=true&amp;appid=1&amp;lver=any&amp;hver=any&amp;atype=1&amp;pid=4&amp;lup=&amp;pp=20&amp;sort=</td>
+ <td></td>
+</tr>
+<tr>
+ <td>verifyElementPresent</td>
+ <td>link=FoxyTunes</td>
+ <td></td>
+</tr>
+<tr>
+ <td>open</td>
+ <td>/en-US/firefox/search?q=foxytunes&amp;cat=all&amp;as=true&amp;vfuz=true&amp;appid=1&amp;lver=any&amp;hver=any&amp;atype=1&amp;pid=2&amp;lup=&amp;pp=20&amp;sort=</td>
+ <td></td>
+</tr>
+<tr>
+ <td>verifyElementPresent</td>
+ <td>link=FoxyTunes</td>
+ <td></td>
+</tr>
+<tr>
+ <td>open</td>
+ <td>/en-US/firefox/search?q=foxytunes&amp;cat=all&amp;as=true&amp;vfuz=true&amp;appid=1&amp;lver=any&amp;hver=any&amp;atype=1&amp;pid=1&amp;lup=&amp;pp=20&amp;sort=</td>
+ <td></td>
+</tr>
+<tr>
+ <td>verifyElementPresent</td>
+ <td>link=FoxyTunes</td>
+ <td></td>
+</tr>
+<tr>
+ <td>open</td>
+ <td>/en-US/firefox/search?q=Open+IT+online&amp;cat=all&amp;as=true&amp;vfuz=true&amp;appid=1&amp;lver=any&amp;hver=any&amp;atype=1&amp;pid=1&amp;lup=&amp;pp=20&amp;sort=</td>
+ <td></td>
+</tr>
+<tr>
+ <td>verifyElementPresent</td>
+ <td>link=Open IT Online</td>
+ <td></td>
+</tr>
+<tr>
+ <td>open</td>
+ <td>/en-US/firefox/search?q=Open+IT+online&amp;cat=all&amp;as=true&amp;vfuz=true&amp;appid=1&amp;lver=3.1&amp;hver=any&amp;atype=1&amp;pid=1&amp;lup=&amp;pp=20&amp;sort=</td>
+ <td></td>
+</tr>
+<tr>
+ <td>verifyTextPresent</td>
+ <td>No results found.</td>
+ <td></td>
+</tr>
+<tr>
+ <td>open</td>
+ <td>/en-US/firefox/search?q=Open+IT+online&amp;cat=all&amp;as=true&amp;vfuz=true&amp;appid=1&amp;lver=1.0&amp;hver=1.5&amp;atype=1&amp;pid=1&amp;lup=&amp;pp=20&amp;sort=</td>
+ <td></td>
+</tr>
+<tr>
+ <td>verifyElementPresent</td>
+ <td>link=Open IT Online</td>
+ <td></td>
+</tr>
+<tr>
+ <td>open</td>
+ <td>/en-US/firefox/search?q=ie+tab&amp;cat=all</td>
+ <td></td>
+</tr>
+<tr>
+ <td>verifyElementPresent</td>
+ <td>link=IE Tab</td>
+ <td></td>
+</tr>
+<tr>
+ <td>open</td>
+ <td>/en-US/firefox/search?q=noscript&amp;cat=1%2C4</td>
+ <td></td>
+</tr>
+<tr>
+ <td>verifyElementPresent</td>
+ <td>link=NoScript</td>
+ <td></td>
+</tr>
+<tr>
+ <td>open</td>
+ <td>/en-US/firefox/search?q=noscript&amp;cat=1%2C12</td>
+ <td></td>
+</tr>
+<tr>
+ <td>verifyElementPresent</td>
+ <td>link=NoScript</td>
+ <td></td>
+</tr>
+<tr>
+ <td>open</td>
+ <td>/en-US/firefox/search?q=adblock&amp;cat=all</td>
+ <td></td>
+</tr>
+<tr>
+ <td>verifyElementPresent</td>
+ <td>link=Adblock</td>
+ <td></td>
+</tr>
+<tr>
+ <td>verifyElementPresent</td>
+ <td>link=Adblock Plus Filter Uploader</td>
+ <td></td>
+</tr>
+<tr>
+ <td>verifyElementPresent</td>
+ <td>link=Adblock Plus</td>
+ <td></td>
+</tr>
+<tr>
+ <td>open</td>
+ <td>/en-US/firefox/search?q=tab+mix+plus&amp;cat=all</td>
+ <td></td>
+</tr>
+<tr>
+ <td>verifyElementPresent</td>
+ <td>link=Tab Mix Plus</td>
+ <td></td>
+</tr>
+<tr>
+ <td>open</td>
+ <td>/en-US/firefox/search?q=gmail+notifier&amp;cat=all</td>
+ <td></td>
+</tr>
+<tr>
+ <td>verifyElementPresent</td>
+ <td>link=Gmail Notifier</td>
+ <td></td>
+</tr>
+<tr>
+ <td>open</td>
+ <td>/en-US/firefox/search?q=gmail+notifier&amp;cat=all</td>
+ <td></td>
+</tr>
+<tr>
+ <td>verifyElementPresent</td>
+ <td>link=Gmail Notifier</td>
+ <td></td>
+</tr>
+<tr>
+ <td>verifyElementPresent</td>
+ <td>link=Better Gmail</td>
+ <td></td>
+</tr>
+<tr>
+ <td>verifyElementPresent</td>
+ <td>link=WebMail Notifier</td>
+ <td></td>
+</tr>
+<tr>
+ <td>verifyElementPresent</td>
+ <td>link=GMail Checker</td>
+ <td></td>
+</tr>
+<tr>
+ <td>open</td>
+ <td>/en-US/seamonkey/search?q=nightly+tester+tools&amp;cat=all</td>
+ <td></td>
+</tr>
+<tr>
+ <td>verifyElementPresent</td>
+ <td>link=Nightly Tester Tools</td>
+ <td></td>
+</tr>
+<tr>
+ <td>open</td>
+ <td>/en-US/seamonkey/search?q=nightly+tester+tools&amp;cat=all&amp;as=true&amp;vfuz=true&amp;appid=59&amp;lver=2.0&amp;hver=2.0&amp;atype=0&amp;pid=0&amp;lup=&amp;pp=20&amp;sort=</td>
+ <td></td>
+</tr>
+<tr>
+ <td>verifyElementNotPresent</td>
+ <td>link=Nightly Tester Tools</td>
+ <td></td>
+</tr>
+<tr>
+ <td>open</td>
+ <td>/en-US/seamonkey/search?q=nightly+tester+tools&amp;cat=all&amp;as=true&amp;vfuz=true&amp;appid=59&amp;lver=1.0&amp;hver=2.0&amp;atype=0&amp;pid=0&amp;lup=&amp;pp=20&amp;sort=</td>
+ <td></td>
+</tr>
+<tr>
+ <td>verifyElementPresent</td>
+ <td>link=Nightly Tester Tools</td>
+ <td></td>
+</tr>
+<tr>
+ <td>open</td>
+ <td>/en-US/seamonkey/search?q=nightly+tester+tools&amp;cat=all&amp;as=true&amp;vfuz=true&amp;appid=59&amp;lver=2.0&amp;hver=2.0&amp;atype=0&amp;pid=0&amp;lup=&amp;pp=20&amp;sort=</td>
+ <td></td>
+</tr>
+<tr>
+ <td>verifyElementNotPresent</td>
+ <td>link=Nightly Tester Tools</td>
+ <td></td>
+</tr>
+<tr>
+ <td>open</td>
+ <td>/en-US/firefox/search?q=IE+taB&amp;cat=all</td>
+ <td></td>
+</tr>
+<tr>
+ <td>verifyElementPresent</td>
+ <td>link=IE Tab</td>
+ <td></td>
+</tr>
+<tr>
+ <td>open</td>
+ <td>/en-US/firefox/search?q=yahoo!&amp;cat=all</td>
+ <td></td>
+</tr>
+<tr>
+ <td>verifyElementPresent</td>
+ <td>link=Yahoo! Toolbar</td>
+ <td></td>
+</tr>
+<tr>
+ <td>verifyElementPresent</td>
+ <td>link=Yahoo! Media Player Plug-in (Beta)</td>
+ <td></td>
+</tr>
+<tr>
+ <td>verifyElementPresent</td>
+ <td>link=Yahoo! Mail Notifier</td>
+ <td></td>
+</tr>
+<tr>
+ <td>verifyElementPresent</td>
+ <td>link=Yahoo! Mail Extra</td>
+ <td></td>
+</tr>
+<tr>
+ <td>open</td>
+ <td>/en-US/thunderbird/search?q=lightning&amp;cat=all</td>
+ <td></td>
+</tr>
+<tr>
+ <td>verifyElementPresent</td>
+ <td>link=Lightning</td>
+ <td></td>
+</tr>
+<tr>
+ <td>verifyElementPresent</td>
+ <td>link=Mozilla Calendar Project</td>
+ <td></td>
+</tr>
+<tr>
+ <td>open</td>
+ <td>/en-US/firefox/search?q=better&amp;cat=all</td>
+ <td></td>
+</tr>
+<tr>
+ <td>verifyElementPresent</td>
+ <td>link=Better Gmail</td>
+ <td></td>
+</tr>
+<tr>
+ <td>verifyElementPresent</td>
+ <td>link=Better Gmail 2</td>
+ <td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/site/app/tests/services/bin/maintenance.test.php b/site/app/tests/services/bin/maintenance.test.php
new file mode 100644
index 0000000..359c18d
--- /dev/null
+++ b/site/app/tests/services/bin/maintenance.test.php
@@ -0,0 +1,53 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is The Mozilla Foundation.
+ *
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Mike Morgan <morgamic@mozilla.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+class MaintenanceServiceTest extends UnitTestCase {
+
+ /**
+ * Sets up required modules.
+ */
+ function setUp() {
+ }
+
+ /**
+ * Make sure there are no PHP errors.
+ */
+ function testNoErrors() {
+ $this->assertNoErrors();
+ }
+}
+?>
diff --git a/site/app/tests/services/bin/parse_logs/count_downloads.test.php b/site/app/tests/services/bin/parse_logs/count_downloads.test.php
new file mode 100644
index 0000000..3def4ca
--- /dev/null
+++ b/site/app/tests/services/bin/parse_logs/count_downloads.test.php
@@ -0,0 +1,160 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is The Mozilla Foundation.
+ *
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Wil Clouser <wclouser@mozilla.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+require_once ROOT.'/../bin/parse_logs/log_parser.class.php';
+
+// Uses LogParserTest::_getTestData(). NOTE: for some reason this means all the LogParser tests run
+// when this class is tested to...
+require_once TESTS.'/services/bin/parse_logs/log_parser.test.php';
+
+class CountDownloadsServiceTest extends UnitTestCase {
+
+ /**
+ * Sets up default vars and required modules.
+ */
+ function setUp() {
+
+ // It's stupid we have to hardcode this here but that's the way things are written...
+ $config = array('user' => TEST_DB_USER, 'pass' => TEST_DB_PASS, 'host' => TEST_DB_HOST, 'name' => TEST_DB_NAME);
+
+ $db = new Database($config, $config);
+
+ $this->cd = new Count_Downloads($db);
+
+ }
+
+ function testCleanIPs() {
+
+ $this->_addFakeCountedIps();
+
+ $this->cd->cleanIPs(strtotime('now'));
+
+ // Make sure it removed an element
+ $this->assertTrue(count($this->cd->countedIPs), 3);
+
+ // Make sure it removed the right one
+ $this->assertFalse(array_key_exists('0.0.0.0', $this->cd->countedIPs));
+ }
+
+ function testCount() {
+
+ $this->_resetCountData();
+
+ // Make sure data is zeroed to begin with
+ $this->assertEqual($this->cd->totalCounted, 0);
+ $this->assertEqual($this->cd->totalSkipped['blacklist'], 0);
+ $this->assertTrue(empty($this->cd->counts['totdown']));
+ $this->assertTrue(empty($this->cd->counts['perday']));
+ $this->assertTrue(empty($this->cd->counts['collections_and_addons']));
+
+ $this->_countTestData();
+
+ // Check a few numbers to make sure we're adding properly
+ $this->assertEqual($this->cd->totalCounted, 23);
+ $this->assertEqual($this->cd->totalSkipped['blacklist'], 1);
+ $this->assertEqual($this->cd->counts['totdown'][7], 8);
+ $this->assertEqual($this->cd->counts['totdown'][10], 2);
+ $this->assertEqual($this->cd->counts['perday'][6]['2008-11-25'], 3);
+ $this->assertEqual($this->cd->counts['perday'][3369]['2008-11-25'], 1);
+ $this->assertEqual($this->cd->counts['collections_and_addons'][1]['total'], 4);
+ $this->assertEqual($this->cd->counts['collections_and_addons'][1]['addon_ids'][3677], 1);
+ $this->assertEqual($this->cd->counts['collections_and_addons'][1]['addon_ids'][8], 2);
+
+ }
+
+ function testLogFileParsedCallback() {
+
+ $this->_resetCountData();
+
+ $_total_total = mysql_fetch_array($this->cd->db->read("SELECT totaldownloads FROM addons WHERE id=7"));
+ $_collection_total = mysql_fetch_array($this->cd->db->read("SELECT downloads from collections WHERE id=1"));
+ $_addons_collection_total = mysql_fetch_array($this->cd->db->read("SELECT downloads from addons_collections WHERE addon_id=8 and collection_id=1"));
+
+ // We have to do this cheesy hack because there is no UNIQUE constraint on the addon_id and date columns.
+ $_result = $this->cd->db->read("SELECT count FROM download_counts WHERE addon_id=9 AND date='2008-11-25'");
+ $_daily_total = 0;
+ while ($row = mysql_fetch_array($_result)) {
+ $_daily_total +=$row[0];
+ }
+
+ $this->_countTestData();
+
+ $this->cd->logfileParsedCallback();
+
+ $_new_total_total = mysql_fetch_array($this->cd->db->read("SELECT totaldownloads FROM addons WHERE id=7"));
+ $_new_collection_total = mysql_fetch_array($this->cd->db->read("SELECT downloads from collections WHERE id=1"));
+ $_new_addons_collection_total = mysql_fetch_array($this->cd->db->read("SELECT downloads from addons_collections WHERE addon_id=8 and collection_id=1"));
+
+ // We have to do this cheesy hack because there is no UNIQUE constraint on the addon_id and date columns.
+ $_result = $this->cd->db->read("SELECT count FROM download_counts WHERE addon_id=9 AND date='2008-11-25'");
+ $_new_daily_total = 0;
+ while ($row = mysql_fetch_array($_result)) {
+ $_new_daily_total +=$row[0];
+ }
+
+ $this->assertEqual($_total_total[0]+8, $_new_total_total[0]);
+ $this->assertEqual($_daily_total[0], $_new_daily_total[0]);
+ $this->assertEqual($_collection_total[0]+4, $_new_collection_total[0]);
+ $this->assertEqual($_addons_collection_total[0]+2, $_new_addons_collection_total[0]);
+
+ }
+
+ function _countTestData() {
+ $_data = LogParserTest::_getTestData();
+ foreach (explode("\n", $_data) as $line) {
+ $details = log_parser::parseLine($line);
+ $this->cd->count($details);
+ }
+ }
+
+ function _resetCountData() {
+ $this->cd->count['totdown'] = array();
+ $this->cd->count['perday'] = array();
+ $this->cd->count['collections_and_addons'] = array();
+ }
+
+ function _addFakeCountedIps() {
+ $this->cd->countedIPs = array(
+ '0.0.0.0' => strtotime('-40 seconds'),
+ '127.0.0.1' => strtotime('-20 seconds'),
+ '255.255.255.255' => strtotime('-10 seconds'),
+ '10.0.0.0' => strtotime('now')
+ );
+ }
+}
+?>
diff --git a/site/app/tests/services/bin/parse_logs/log_parser.test.php b/site/app/tests/services/bin/parse_logs/log_parser.test.php
new file mode 100644
index 0000000..3c43fdb
--- /dev/null
+++ b/site/app/tests/services/bin/parse_logs/log_parser.test.php
@@ -0,0 +1,107 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is The Mozilla Foundation.
+ *
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Wil Clouser <wclouser@mozilla.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+require_once ROOT.'/../bin/parse_logs/log_parser.class.php';
+
+class LogParserTest extends UnitTestCase {
+
+ function testParseLine() {
+ $_count = 0;
+ $_data = $this->_getTestData();
+
+ foreach (explode("\n", $_data) as $line) {
+
+ $lineDetails = log_parser::parseLine($line);
+
+ if (!is_array($lineDetails))
+ continue;
+
+ // Versioncheck.php example
+ if($lineDetails['ip'] == '10.28.10.131') {
+ $_count++;
+
+ $this->assertEqual($lineDetails['type'], 'updatepings');
+
+ $this->assertEqual($lineDetails['addon']['appOS'], 'WINNT');
+ }
+
+ // /$lang/firefox/downloads/ example
+ if($lineDetails['ip'] == '10.56.10.195') {
+ $_count++;
+
+ $this->assertEqual($lineDetails['type'], 'downloads');
+
+ $this->assertEqual($lineDetails['fileid'], 1);
+ }
+
+ // /$lang/downloads/file/ example
+ if($lineDetails['ip'] == '10.64.10.123') {
+ $_count++;
+
+ $this->assertEqual($lineDetails['type'], 'downloads');
+
+ $this->assertEqual($lineDetails['fileid'], 5);
+ }
+
+ // /$lang/firefox/collections/ example
+ if($lineDetails['ip'] == '10.119.10.189') {
+ $_count++;
+
+ $this->assertEqual($lineDetails['type'], 'collections');
+
+ $this->assertEqual(array_diff(array(6, 7, 9), $lineDetails['addon_ids']), array());
+ }
+
+
+ }
+
+ // The above assertions check that details of matches are correct but they don't check that all the matches were there. $_count has been keeping track
+ $this->assertEqual($_count, 5, "Identify all URLs we need for statistics tracking. (Found {$_count})");
+
+ }
+
+ function testGetLineDetails() {
+ // Tested in testParseLine()
+ }
+
+ function _getTestData() {
+ return file_get_contents(TEST_DATA.'/remora-test-log.log');
+ }
+
+}
+?>
diff --git a/site/app/tests/services/bin/update-hashes.test.php b/site/app/tests/services/bin/update-hashes.test.php
new file mode 100644
index 0000000..fdc8e12
--- /dev/null
+++ b/site/app/tests/services/bin/update-hashes.test.php
@@ -0,0 +1,53 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is The Mozilla Foundation.
+ *
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Mike Morgan <morgamic@mozilla.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+class UpdateHashesServiceTest extends UnitTestCase {
+
+ /**
+ * Sets up required modules.
+ */
+ function setUp() {
+ }
+
+ /**
+ * Make sure there are no PHP errors.
+ */
+ function testNoErrors() {
+ $this->assertNoErrors();
+ }
+}
+?>
diff --git a/site/app/tests/services/blocklist.test.php b/site/app/tests/services/blocklist.test.php
new file mode 100644
index 0000000..0a55884
--- /dev/null
+++ b/site/app/tests/services/blocklist.test.php
@@ -0,0 +1,357 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is The Mozilla Foundation.
+ *
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Mike Morgan <morgamic@mozilla.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/**
+ * This class tests the blocklist service. The purpose of the blocklist service
+ * is to tell clients which add-ons are forbidden.
+ *
+ * The blocklist delivered as client-read RDF documents. This class mainly
+ * tests the RDF output for validity and accuracy based on corresponding
+ * database contents.
+ *
+ * An example URI (wrapped for readability):
+ * https://addons.mozilla.org/blocklist.php?
+ * reqVersion=1&
+ * appGuid={ec8030f7-c20a-464f-9b0e-13a3a9e97384}&
+ * appVersion=2.0
+ */
+
+class BlocklistServiceTest extends UnitTestCase {
+
+ var $_args;
+ var $_data;
+ var $_pluginData;
+
+ function BlocklistServiceTest() {
+ $this->UnitTestCase('Services->Blocklist');
+ loadModel('Blitem');
+ loadModel('Blapp');
+ loadModel('Blplugin');
+ }
+
+ /**
+ * Sets up default vars and required modules.
+ */
+ function setUp() {
+
+ // Load RDF component.
+ loadComponent('Rdf');
+
+ $this->_args = array(
+ 'reqVersion'=>'1',
+ 'appGuid'=>'{ec8030f7-c20a-464f-9b0e-13a3a9e97384}',
+ 'appVersion'=>'1.5'
+ );
+
+ $model =& new Blitem();
+ $this->_data = $model->findAll();
+
+ $pl =& new Blplugin();
+ $this->_pluginData = $pl->findAll();
+ }
+
+ /**
+ * Build a blocklist URI based on _args.
+ * @param array $args URI arguments
+ * @return string resulting URI
+ */
+ function _buildUri($args=array()) {
+ $_buf = array();
+ foreach ($args as $key=>$val) {
+ $_buf[] = $key.'='.$val;
+ }
+ return SERVICE_URL.'/blocklist.php?test=1&'.implode('&',$_buf);
+ }
+
+ /**
+ * Retrieve XML document based on _args.
+ * @param array $args URI arguments
+ * @return string resulting XML document as a string
+ */
+ function _getXml($args=array()) {
+ return trim(file_get_contents($this->_buildUri($args)));
+ }
+
+ /**
+ * Returns a boolean saying whether or not the XML passed was parsable.
+ * @param string $xml an XML document
+ * @return boolean true if parsable, false if not
+ */
+ function _isParsable($xml) {
+ $rdf = new Rdf_parser();
+ $rdf->rdf_parser_create(null);
+ $rdf->rdf_set_user_data($data);
+ $rdf->rdf_set_statement_handler(array('RdfComponent', 'mfStatementHandler'));
+ $rdf->rdf_set_base("");
+
+ return $rdf->rdf_parse($xml, strlen($xml), true);
+ }
+
+ /**
+ * Make sure there are no PHP errors.
+ */
+ function testNoErrors() {
+ $this->assertNoErrors();
+ }
+
+ /**
+ * No blocklist exists for maligned values. Assert in each of
+ * these cases that the resulting RDF is parsable.
+ */
+ function testNoBlocklistForBadInputs() {
+
+ foreach ($this->_args as $key=>$val) {
+
+ // Only tests reqVersion and appGuid because appVersion is not required.
+ if ($key != 'appVersion') {
+
+ // Store args in a temp array so we can fudge it up.
+ $_tmp = $this->_args;
+
+ // We want to mess up a value on purpose.
+ $_tmp[$key] = '/?:LIKJPO(&O(*&_)(*_)(!*@#K';
+
+ // Get the XML for a malformed URI.
+ $_xml = $this->_getXml($_tmp);
+
+ // The resulting document should be parsable.
+ $this->assertTrue($this->_isParsable($_xml), 'Document still parsable when '.$key.'='.$_tmp[$key]);
+
+ // The resulting document should not contain blocklist items.
+ $this->assertNoPattern('/.*emItems.*/', $_xml, 'No blocklist items were found.');
+ }
+ }
+ }
+
+ /**
+ * No blocklist exists for missing values. Assert in each of
+ * these cases that the resulting RDF is parsable.
+ */
+ function testNoBlocklistForMissingInputs() {
+
+ foreach ($this->_args as $key=>$val) {
+
+ // Store args in a temp array so we can fudge it up.
+ $_tmp = $this->_args;
+
+ // We want to mess up a value on purpose.
+ $_tmp[$key] = '';
+
+ // Get the XML for a malformed URI.
+ $_xml = $this->_getXml($_tmp);
+
+ // The resulting document should be parsable.
+ $this->assertTrue($this->_isParsable($_xml), 'Document still parsable when '.$key.' is empty.');
+
+ // The resulting document should not contain blocklist items.
+ $this->assertNoPattern('/.*emItems.*/', $_xml, 'No blocklist items were found.');
+ }
+ }
+
+ /**
+ * Test that our expected test results are coming back.
+ */
+ function testBlocklistItemsExist() {
+
+ // Get our test case XML.
+ $_xml = $this->_getXml($this->_args);
+
+ // The resulting document should be parsable.
+ $this->assertTrue($this->_isParsable($_xml), 'Document is parsable when blocklist items exist.');
+
+ // Next, test
+ $pattern = preg_quote(' <emItem id="'.$this->_data[0]['Blitem']['guid'].'">','/');
+ $this->assertPattern('/.*'.$pattern.'.*/', $_xml, $this->_data[0]['Blitem']['guid'] . ' found in blocklist XML.');
+
+ $pattern = preg_quote(' <emItem id="'.$this->_data[2]['Blitem']['guid'].'">','/');
+ $this->assertPattern('/.*'.$pattern.'.*/', $_xml, $this->_data[2]['Blitem']['guid'] . ' found in blocklist XML.');
+
+ $pattern = preg_quote(' <emItem id="'.$this->_data[3]['Blitem']['guid'].'">','/');
+ $this->assertPattern('/.*'.$pattern.'.*/', $_xml, $this->_data[3]['Blitem']['guid'] . ' found in blocklist XML.');
+
+ $pattern = preg_quote(' <emItem id="'.$this->_data[4]['Blitem']['guid'].'" os="'.$this->_data[4]['Blitem']['os'].'">','/');
+ $this->assertPattern('/.*'.$pattern.'.*/', $_xml, $this->_data[4]['Blitem']['guid'] . ' found in blocklist XML.');
+
+ $pattern = preg_quote(' <emItem id="'.$this->_data[5]['Blitem']['guid'].'"/>','/');
+ $this->assertPattern('/.*'.$pattern.'.*/', $_xml, $this->_data[5]['Blitem']['guid'] . ' found in blocklist XML.');
+
+ $pattern = preg_quote(' <versionRange minVersion="'.$this->_data[0]['Blitem']['min'].'" maxVersion="'.$this->_data[0]['Blitem']['max'].'">','/');
+ $this->assertPattern('/.*'.$pattern.'.*/', $_xml, 'minVersion="'.$this->_data[0]['Blitem']['min'].'" maxVersion="'.$this->_data[0]['Blitem']['max'].'" found in blocklist XML.');
+
+ $pattern = preg_quote(' <targetApplication id="'.$this->_data[0]['Blapp'][0]['guid'].'">','/');
+ $this->assertPattern('/.*'.$pattern.'.*/', $_xml, 'id="'.$this->_data[0]['Blapp'][0]['guid'].'"found in blocklist XML.');
+
+ $pattern = preg_quote(' <versionRange minVersion="'.$this->_data[0]['Blapp'][0]['min'].'" maxVersion="'.$this->_data[0]['Blapp'][0]['max'].'"/>','/');
+ $this->assertPattern('/.*'.$pattern.'.*/', $_xml, 'minVersion="'.$this->_data[0]['Blapp'][0]['min'].'" maxVersion="'.$this->_data[0]['Blapp'][0]['max'].'" found in blocklist XML.');
+
+ $pattern = preg_quote(' <versionRange minVersion="'.$this->_data[1]['Blitem']['min'].'" maxVersion="'.$this->_data[1]['Blitem']['max'].'">','/');
+ $this->assertPattern('/.*'.$pattern.'.*/', $_xml, 'minVersion="'.$this->_data[1]['Blitem']['min'].'" maxVersion="'.$this->_data[1]['Blitem']['max'].'" found in blocklist XML.');
+
+ $pattern = preg_quote(' <versionRange minVersion="'.$this->_data[2]['Blitem']['min'].'" maxVersion="'.$this->_data[2]['Blitem']['max'].'"/>','/');
+ $this->assertPattern('/.*'.$pattern.'.*/', $_xml, 'minVersion="'.$this->_data[2]['Blitem']['min'].'" maxVersion="'.$this->_data[2]['Blitem']['max'].'" found in blocklist XML.');
+
+ $pattern = preg_quote(' <match name="name" exp="'.$this->_pluginData[0]['Blplugin']['name'].'"/>','/');
+ $this->assertPattern('/.*'.$pattern.'.*/', $_xml, 'exp="'.$this->_pluginData[0]['Blplugin']['name'].'" found in blocklist XML.');
+
+ $pattern = preg_quote(' <match name="description" exp="'.$this->_pluginData[0]['Blplugin']['description'].'"/>','/');
+ $this->assertPattern('/.*'.$pattern.'.*/', $_xml, 'exp="'.$this->_pluginData[0]['Blplugin']['description'].'" found in blocklist XML.');
+
+ $pattern = preg_quote(' <match name="filename" exp="'.$this->_pluginData[0]['Blplugin']['filename'].'"/>','/');
+ $this->assertPattern('/.*'.$pattern.'.*/', $_xml, 'exp="'.$this->_pluginData[0]['Blplugin']['filename'].'" found in blocklist XML.');
+ }
+
+ /**
+ * No blocklist exists for missing values. Assert in each of
+ * these cases that the resulting RDF is parsable.
+ */
+ function testPluginItemsVersionCheck() {
+
+ // Store args in a temp array so we can fudge it up.
+ $_tmp = $this->_args;
+
+ // Test a version that is too low (outside lower bound of range).
+ $_tmp['appVersion'] = '0.1';
+ $_xml = $this->_getXml($_tmp);
+ $this->assertTrue($this->_isParsable($_xml), 'Document still parsable when version is too low ('.$_tmp['appVersion'].').');
+ $this->assertNoPattern('/.*pluginItems.*/', $_xml, 'No plugin items were found when version is too low ('.$_tmp['appVersion'].').');
+
+ // Test a version that is too high (outside upper bound of range).
+ $_tmp['appVersion'] = '8.0';
+ $_xml = $this->_getXml($_tmp);
+ $this->assertTrue($this->_isParsable($_xml), 'Document still parsable when version is too high ('.$_tmp['appVersion'].').');
+ $this->assertNoPattern('/.*pluginItems.*/', $_xml, 'No plugin items were found when version is too high ('.$_tmp['appVersion'].').');
+
+ // Test a valid version.
+ $_tmp['appVersion'] = '1.5';
+ $_xml = $this->_getXml($_tmp);
+ $this->assertTrue($this->_isParsable($_xml), 'Document still parsable when version is valid ('.$_tmp['appVersion'].').');
+ $this->assertPattern('/.*pluginItems.*/', $_xml, 'Plugin items were found when version is valid ('.$_tmp['appVersion'].').');
+ }
+
+ /**
+ * Make sure there aren't null match elements in blocklist entries that have
+ * NULL values in the database.
+ */
+ function testNoNullOrEmptyMatchElements() {
+
+ // Store args in a temp array so we can fudge it up.
+ $_tmp = $this->_args;
+
+ $_xml = $this->_getXml($_tmp);
+
+ $this->assertTrue($this->_isParsable($_xml), 'Document is parsable for match elements test.');
+ $this->assertNoPattern('/.*<match name="name"\/>.*/', $_xml, '"name" match element without an exp attribute should not exist.');
+ $this->assertNoPattern('/.*<match name="description"\/>.*/', $_xml, '"description" match element without an exp attribute should not exist.');
+ $this->assertNoPattern('/.*<match name="filename"\/>.*/', $_xml, '"filename" match element without an exp attribute should not exist.');
+
+ $this->assertNoPattern('/.*<match name="name" exp=""\/>.*/', $_xml, '"name" match element with an empty exp attribute should not exist.');
+ $this->assertNoPattern('/.*<match name="description" exp=""\/>.*/', $_xml, '"description" match element with an empty exp attribute should not exist.');
+ $this->assertNoPattern('/.*<match name="filename" exp=""\/>.*/', $_xml, '"filename" match element with an empty exp attribute should not exist.');
+ }
+
+ /**
+ * Test that OS and XPCOMABI information can be displayed successfully.
+ */
+ function testOsAndXpcomabi() {
+ $_tmp = $this->_args;
+
+ $_xml = $this->_getXml($_tmp);
+
+ $this->assertTrue($this->_isParsable($_xml), 'Document still parsable when we have items and pluginitems with os/xpcomabi data.');
+
+ $pattern = preg_quote(' <emItem id="'.$this->_data[4]['Blitem']['guid'].'" os="'.$this->_data[4]['Blitem']['os'].'">','/');
+ $this->assertPattern('/.*'.$pattern.'.*/', $_xml, $this->_data[4]['Blitem']['guid'] . ' has os info for '.$this->_data[4]['Blitem']['os'].' (multi-dimensional emItem).');
+
+ $pattern = preg_quote(' <emItem id="'.$this->_data[6]['Blitem']['guid'].'" os="'.$this->_data[6]['Blitem']['os'].'"/>','/');
+ $this->assertPattern('/.*'.$pattern.'.*/', $_xml, $this->_data[6]['Blitem']['guid'] . ' has os info for '.$this->_data[6]['Blitem']['os'].' (one-line emItem).');
+
+ $pattern = preg_quote(' <pluginItem xpcomabi="'.$this->_pluginData[4]['Blplugin']['xpcomabi'].'">','/');
+ $this->assertPattern('/.*'.$pattern.'.*/', $_xml, 'exp="'.$this->_pluginData[4]['Blplugin']['name'].'" found in blocklist XML with xpcomabi info for '.$this->_pluginData[4]['Blplugin']['xpcomabi'].'.');
+
+ $pattern = preg_quote(' <pluginItem os="'.$this->_pluginData[5]['Blplugin']['os'].'">','/');
+ $this->assertPattern('/.*'.$pattern.'.*/', $_xml, 'exp="'.$this->_pluginData[5]['Blplugin']['name'].'" found in blocklist XML with os info for '.$this->_pluginData[5]['Blplugin']['os'].'.');
+ }
+
+ /**
+ * Tests that versionRanges are correctly included in pluginItems in the v3
+ * schema.
+ */
+ function testPluginVersionRange() {
+ $_tmp = $this->_args;
+ $_xml = $this->_getXml($_tmp);
+
+ $this->assertTrue($this->_isParsable($_xml), 'Schema 1 document is parsable for plugin versionRange tests.');
+ $this->assertNoPattern('/<pluginItems>.*versionRange.*<\/pluginItems>/s', $_xml, 'No versionRanges exist in schema 1 result.');
+
+ $_tmp['reqVersion'] = '2';
+ $_xml = $this->_getXml($_tmp);
+
+ $this->assertTrue($this->_isParsable($_xml), 'Schema 2 document is parsable for plugin versionRange tests.');
+ $this->assertNoPattern('/<pluginItems>.*versionRange.*<\/pluginItems>/s', $_xml, 'No versionRanges exist in schema 2 result.');
+
+ $_tmp['reqVersion'] = '3';
+ $_xml = $this->_getXml($_tmp);
+
+ $this->assertTrue($this->_isParsable($_xml), 'Schema 3 document is parsable for plugin versionRange tests.');
+ $this->assertPattern('/<pluginItems>.*versionRange.*<\/pluginItems>/s', $_xml, 'versionRanges exist in schema 3 result.');
+
+ $matches = array();
+ preg_match_all('/<pluginItem.*?<\/pluginItem>/s', $_xml, $matches);
+ $this->assertEqual(count($matches[0]), 6, 'Should have been 6 plugin items, actually saw ' . count($matches[0]));
+ foreach ($matches[0] as $pluginItem) {
+ $this->assertPattern('/<versionRange\s+minVersion="1.0"\s+maxVersion="2.0"\s*\/>/', $pluginItem, 'versionRange for plugin item should have contained the right versions.');
+ }
+
+ $_tmp['appVersion'] = '0.1';
+ $_xml = $this->_getXml($_tmp);
+
+ $this->assertPattern('/.*pluginItems.*/', $_xml, 'Should always include pluginItems in version 3 schema regardless of version being too low.');
+ $matches = array();
+ preg_match_all('/<pluginItem.*?<\/pluginItem>/s', $_xml, $matches);
+ $this->assertEqual(count($matches[0]), 6, 'Should have been 6 plugin items when using a version that is too high, actually saw ' . count($matches[0]));
+
+ $_tmp['appVersion'] = '8.0';
+ $_xml = $this->_getXml($_tmp);
+
+ $this->assertPattern('/.*pluginItems.*/', $_xml, 'Should always include pluginItems in version 3 schema regardless of version being too high.');
+ $matches = array();
+ preg_match_all('/<pluginItem.*?<\/pluginItem>/s', $_xml, $matches);
+ $this->assertEqual(count($matches[0]), 6, 'Should have been 6 plugin items when using a version that is too high, actually saw ' . count($matches[0]));
+ }
+}
+?>
diff --git a/site/app/tests/services/pfs.test.php b/site/app/tests/services/pfs.test.php
new file mode 100644
index 0000000..25acf8b
--- /dev/null
+++ b/site/app/tests/services/pfs.test.php
@@ -0,0 +1,282 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is The Mozilla Foundation.
+ *
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Mike Morgan <morgamic@mozilla.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/**
+ * This class tests the Plugin Finder Service (PFS).
+ *
+ * PFS serves RDF data to requesting clients via the pfs.datasource.url pref.
+ *
+ * Incoming URL example (wrapped for readability):
+ * https://pfs.mozilla.org/PluginFinderService.php?
+ * mimetype=application/x-shockwave-flash
+ * &appID={ec8030f7-c20a-464f-9b0e-13a3a9e97384}
+ * &appVersion=2007020307
+ * &clientOS=Windows%20XP
+ * &chromeLocale=en-US
+ */
+
+class PluginFinderServiceTest extends UnitTestCase {
+
+ var $_args;
+
+ function PluginFinderServiceTest() {
+ $this->UnitTestCase('Services->PluginFinderService');
+ }
+
+ /**
+ * Sets up default vars and required modules.
+ */
+ function setUp() {
+
+ // Load RDF component.
+ loadComponent('Rdf');
+
+ $this->_args = array(
+ 'mimetype'=>'application/x-shockwave-flash',
+ 'appID'=>'{ec8030f7-c20a-464f-9b0e-13a3a9e97384}',
+ 'appVersion'=>'2007020307',
+ 'clientOS'=>'Windows%20XP',
+ 'chromeLocale'=>'en-US'
+ );
+ }
+
+ /**
+ * Make sure there are no PHP errors.
+ */
+ function testNoErrors() {
+ $this->assertNoErrors();
+ }
+
+ /**
+ * No plugin data exists for maligned values. Assert in each of
+ * these cases that the resulting RDF is parsable.
+ */
+ function testNoPluginDataForBadInputs() {
+
+ foreach ($this->_args as $key=>$val) {
+
+ // Store args in a temp array so we can fudge it up.
+ $_tmp = $this->_args;
+
+ // We want to mess up a value on purpose.
+ $_tmp[$key] = '/?:LIKJPO(&O(*&_)(*_)(!*@#K';
+
+ // Get the XML for a malformed URI.
+ $_xml = $this->_getXml($_tmp);
+
+ // The resulting document should be parsable.
+ $this->assertTrue($this->_isParsable($_xml), 'Document still parsable when '.$key.'='.$_tmp[$key]);
+ }
+ }
+
+ /**
+ * No plugin data exists for missing values. Assert in each of
+ * these cases that the resulting RDF is parsable.
+ */
+ function testNoPluginDataForMissingInputs() {
+
+ foreach ($this->_args as $key=>$val) {
+
+ // Store args in a temp array so we can fudge it up.
+ $_tmp = $this->_args;
+
+ // We want to mess up a value on purpose.
+ $_tmp[$key] = '';
+
+ // Get the XML for a malformed URI.
+ $_xml = $this->_getXml($_tmp);
+
+ // The resulting document should be parsable.
+ $this->assertTrue($this->_isParsable($_xml), 'Document still parsable when '.$key.' is empty.');
+ }
+ }
+
+ /**
+ * Test that Flash comes back as expected when passed the appropriate
+ * args.
+ */
+ function testPluginDataFound() {
+ $_xml = $this->_getXml($this->_args);
+
+ // The resulting document should be parsable.
+ $this->assertTrue($this->_isParsable($_xml), 'Document parsable when Flash plugin data was requested.');
+
+ $this->assertPattern('/.*Adobe Flash Player.*/',$_xml,'Plugin name exists in XML.');
+ $this->assertPattern('/.*'.preg_quote('application/x-shockwave-flash','/').'.*/',$_xml,'Plugin mime-type exists in XML.');
+ $this->assertPattern('/.*{4cfaef8a-a6c9-41a0-8e6f-967eb8f49143}.*/',$_xml,'Plugin GUID exists in XML.');
+ $this->assertPattern('/.*'.preg_quote('http://fpdownload.macromedia.com/get/flashplayer/xpi/current/flashplayer-win.xpi','/').'.*/',$_xml,'XPILocation exists in XML.');
+ $this->assertPattern('/.*'.preg_quote('http://www.adobe.com/go/getflashplayer','/').'.*/',$_xml,'ManualInstallationURL exists in XML.');
+ $this->assertPattern('/.*'.preg_quote('http://www.adobe.com/go/eula_flashplayer','/').'.*/',$_xml,'licenseURL exists in XML.');
+ }
+
+
+ /**
+ * Test that no XPI is offered for Flash on any platform for Firefox 3.
+ */
+ function testNoXPIForFirefox3() {
+ $_xml = $this->_getXml(
+ array(
+ 'mimetype'=>'application/x-shockwave-flash',
+ 'appID'=>'{ec8030f7-c20a-464f-9b0e-13a3a9e97384}',
+ 'appVersion'=>'2007020307',
+ 'appRelease'=>'3.0',
+ 'clientOS'=>'Windows%20NT%206.0',
+ 'chromeLocale'=>'en-US'
+ )
+ );
+ $this->assertNoPattern('/.*'.preg_quote('http://fpdownload.macromedia.com/get/flashplayer/xpi/current/flashplayer-win.xpi','/').'.*/',$_xml,'No Flash XPI offered for Firefox 3 on Vista.');
+
+ $_xml = $this->_getXml(
+ array(
+ 'mimetype'=>'application/x-shockwave-flash',
+ 'appID'=>'{ec8030f7-c20a-464f-9b0e-13a3a9e97384}',
+ 'appVersion'=>'2007020307',
+ 'appRelease'=>'3.0',
+ 'clientOS'=>'Linux%20i686',
+ 'chromeLocale'=>'en-US'
+ )
+ );
+ $this->assertNoPattern('/.*'.preg_quote('http://fpdownload.macromedia.com/get/flashplayer/xpi/current/flashplayer-linux.xpi','/').'.*/',$_xml,'No Flash XPI offered for Firefox 3 on Linux.');
+
+ $_xml = $this->_getXml(
+ array(
+ 'mimetype'=>'application/x-shockwave-flash',
+ 'appID'=>'{ec8030f7-c20a-464f-9b0e-13a3a9e97384}',
+ 'appVersion'=>'2007020307',
+ 'appRelease'=>'3.0',
+ 'clientOS'=>'Intel%20Mac%20OS%20X%2010.5',
+ 'chromeLocale'=>'en-US'
+ )
+ );
+ $this->assertNoPattern('/.*'.preg_quote('http://fpdownload.macromedia.com/get/flashplayer/xpi/current/flashplayer-mac.xpi','/').'.*/',$_xml,'No Flash XPI offered for Firefox 3 on Intel Mac OS X.');
+ }
+
+ /**
+ * Test that XPIs are offered for Flash on Firefox 2.
+ */
+ function testXPIForFirefox2() {
+ $_xml = $this->_getXml(
+ array(
+ 'mimetype'=>'application/x-shockwave-flash',
+ 'appID'=>'{ec8030f7-c20a-464f-9b0e-13a3a9e97384}',
+ 'appVersion'=>'2007020307',
+ 'appRelease'=>'2.0',
+ 'clientOS'=>'Windows%20NT%205.0',
+ 'chromeLocale'=>'en-US'
+ )
+ );
+ $this->assertPattern('/.*'.preg_quote('http://fpdownload.macromedia.com/get/flashplayer/xpi/current/flashplayer-win.xpi','/').'.*/',$_xml,'Flash XPI offered for Firefox 2 on XP.');
+
+ $_xml = $this->_getXml(
+ array(
+ 'mimetype'=>'application/x-shockwave-flash',
+ 'appID'=>'{ec8030f7-c20a-464f-9b0e-13a3a9e97384}',
+ 'appVersion'=>'2007020307',
+ 'appRelease'=>'2.0',
+ 'clientOS'=>'Windows%20NT%206.0',
+ 'chromeLocale'=>'en-US'
+ )
+ );
+ $this->assertNoPattern('/.*'.preg_quote('flashplayer-win.xpi','/').'.*/',$_xml,'Flash XPI _NOT_ offered for Firefox 2 on Vista.');
+ $this->assertNoPattern('/.*'.preg_quote('http://www.adobe.com/go/eula_flashplayer','/').'.*/',$_xml,'Flash licenseURL _NOT_ offered for Firefox 2 on Vista.');
+
+ $_xml = $this->_getXml(
+ array(
+ 'mimetype'=>'application/x-shockwave-flash',
+ 'appID'=>'{ec8030f7-c20a-464f-9b0e-13a3a9e97384}',
+ 'appVersion'=>'2007020307',
+ 'appRelease'=>'2.0',
+ 'clientOS'=>'Linux%20i686',
+ 'chromeLocale'=>'en-US'
+ )
+ );
+ $this->assertPattern('/.*'.preg_quote('http://fpdownload.macromedia.com/get/flashplayer/xpi/current/flashplayer-linux.xpi','/').'.*/',$_xml,'Flash XPI offered for Firefox 2 on Linux.');
+
+ $_xml = $this->_getXml(
+ array(
+ 'mimetype'=>'application/x-shockwave-flash',
+ 'appID'=>'{ec8030f7-c20a-464f-9b0e-13a3a9e97384}',
+ 'appVersion'=>'2007020307',
+ 'appRelease'=>'2.0',
+ 'clientOS'=>'Intel%20Mac%20OS%20X%2010.5',
+ 'chromeLocale'=>'en-US'
+ )
+ );
+ $this->assertPattern('/.*'.preg_quote('http://fpdownload.macromedia.com/get/flashplayer/xpi/current/flashplayer-mac.xpi','/').'.*/',$_xml,'Flash XPI offered for Firefox 2 on Intel Mac OS X.');
+ }
+
+
+ /**
+ * Build a PFS URI based on _args.
+ * @param array $args URI arguments
+ * @return string resulting URI
+ */
+ function _buildUri($args=array()) {
+ $_buf = array();
+ foreach ($args as $key=>$val) {
+ $_buf[] = $key.'='.$val;
+ }
+ return SERVICE_URL.'/pfs.php?'.implode('&',$_buf);
+ }
+
+ /**
+ * Retrieve XML document based on _args.
+ * @param array $args update URI arguments
+ * @return string resulting XML document as a string
+ */
+ function _getXml($args=array()) {
+ return trim(file_get_contents($this->_buildUri($args)));
+ }
+
+ /**
+ * Returns a boolean saying whether or not the XML passed was parsable.
+ * @param string $xml an XML document
+ * @return boolean true if parsable, false if not
+ */
+ function _isParsable($xml) {
+ $rdf = new Rdf_parser();
+ $rdf->rdf_parser_create(null);
+ $rdf->rdf_set_user_data($data);
+ $rdf->rdf_set_statement_handler(array('RdfComponent', 'mfStatementHandler'));
+ $rdf->rdf_set_base("");
+
+ return $rdf->rdf_parse($xml, strlen($xml), true);
+ }
+
+}
+?>
diff --git a/site/app/tests/services/update.test.php b/site/app/tests/services/update.test.php
new file mode 100644
index 0000000..edd3957
--- /dev/null
+++ b/site/app/tests/services/update.test.php
@@ -0,0 +1,418 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is The Mozilla Foundation.
+ *
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Mike Morgan <morgamic@mozilla.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/**
+ * This class tests the update service. The purpose of the update service
+ * is to notify clients when an add-on has an available update.
+ *
+ * Updates are delivered as client-read RDF documents. This class mainly
+ * tests the RDF output for validity and accuracy based on corresponding
+ * database contents.
+ *
+ * An example URI (wrapped for readability):
+ * https://addons.mozilla.org/update/VersionCheck.php?
+ * reqVersion=1&
+ * id={19503e42-ca3c-4c27-b1e2-9cdb2170ee34}&
+ * version=1.0&
+ * maxAppVersion=2.0&
+ * status={on}&
+ * appID={ec8030f7-c20a-464f-9b0e-13a3a9e97384}&
+ * appVersion=2.0&
+ * appOS=Linux&
+ * appABI=1
+ */
+
+// Require update function file.
+require_once(APP.'webroot/services/functions.php');
+
+class UpdateServiceTest extends WebTestHelper {
+
+ var $_args;
+ var $_noUpdatesXml;
+
+ function UpdateServiceTest() {
+ $this->WebTestCase('Services->Update');
+ loadModel('Addon');
+ loadModel('Version');
+ }
+
+ /**
+ * Sets up default vars and required modules.
+ */
+ function setUp() {
+
+ // Load RDF component.
+ loadComponent('Rdf');
+
+ $this->_args = array(
+ 'reqVersion'=>'1',
+ 'id'=>'{11111111-1111-1111-1111-111111111111}',
+ 'version'=>'1.0',
+ 'maxAppVersion'=>'1.0',
+ 'status'=>'on',
+ 'appID'=>'{11111111-1111-1111-1111-111111111111}',
+ 'appVersion'=>'1.0',
+ 'appOS'=>'Linux',
+ 'appABI'=>'1',
+ 'test'=>'1'
+ );
+
+ $this->_noUpdatesXml=<<<NoUpdateXml
+<?xml version="1.0"?>
+<RDF:RDF xmlns:RDF="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:em="http://www.mozilla.org/2004/em-rdf#"></RDF:RDF>
+NoUpdateXml;
+
+ $this->id = 7;
+ $this->model =& new Addon();
+ $this->versionModel =& new Version();
+ $this->data = $this->model->find("Addon.id=$this->id", null , null , 2);
+ $this->data['Version'] = $this->versionModel->findAll("Version.addon_id=$this->id", null, "Version.created DESC", 0);
+ }
+
+ /**
+ * Retrieve XML document based on _args.
+ * @param array $args update URI arguments
+ * @return string resulting XML document as a string
+ */
+ function _getXml($args=array()) {
+ // Use the test db.
+ $args['test'] = 1;
+ return $this->get(SERVICE_URL.'/update.php',$args);
+ }
+
+ /**
+ * Returns a boolean saying whether or not the XML passed was parsable.
+ * @param string $xml an XML document
+ * @return boolean true if parsable, false if not
+ */
+ function _isParsable($xml) {
+ $rdf = new Rdf_parser();
+ $rdf->rdf_parser_create(null);
+ $rdf->rdf_set_user_data($data);
+ $rdf->rdf_set_statement_handler(array('RdfComponent', 'mfStatementHandler'));
+ $rdf->rdf_set_base("");
+
+ return $rdf->rdf_parse($xml, strlen($xml), true);
+ }
+
+ /**
+ * No update exists for maligned values. Assert in each of
+ * these cases that the resulting RDF is a "no updates" RDF.
+ *
+ * The "no updates" RDF should be parsable.
+ */
+ function testNoUpdateForBadInputs() {
+
+ foreach ($this->_args as $key=>$val) {
+
+ // Store args in a temp array so we can fudge it up.
+ $_tmp = $this->_args;
+
+ // We want to mess up a value on purpose.
+ $_tmp[$key] = '/?:LIKJPO(&O(*&_)(*_)(!*@#K';
+
+ // Get the XML for a malformed URI.
+ $_xml = $this->_getXml($_tmp);
+
+ // The resulting document should be parsable.
+ $this->assertTrue($this->_isParsable($_xml), 'Document still parsable when '.$key.'='.$_tmp[$key]);
+
+ // The resulting document should be equal to our no updates xml.
+ $this->assertEqual($this->_noUpdatesXml, $_xml, 'No update was offered.');
+ }
+ }
+
+ /**
+ * No update exists for missing values. Assert in each of
+ * these cases that the resulting RDF is a "no updates" RDF.
+ *
+ * The "no updates" RDF should be parsable.
+ */
+ function testNoUpdateForMissingInputs() {
+
+ foreach ($this->_args as $key=>$val) {
+
+ // Store args in a temp array so we can fudge it up.
+ $_tmp = $this->_args;
+
+ // We want to mess up a value on purpose.
+ $_tmp[$key] = '';
+
+ // Get the XML for a malformed URI.
+ $_xml = $this->_getXml($_tmp);
+
+ // The resulting document should be parsable.
+ $this->assertTrue($this->_isParsable($_xml), 'Document still parsable when '.$key.' is empty.');
+
+ // The resulting document should be equal to our no updates xml.
+ $this->assertEqual($this->_noUpdatesXml, $_xml, 'No update was offered.');
+ }
+ }
+
+ /**
+ * There should be no update for a platform that is not compatible.
+ */
+ function testNoUpdateForIncompatiblePlatform() {
+
+ // Store args in a temp array so we can fudge it up.
+ $_tmp = $this->_args;
+
+ // We want to mess up a value on purpose.
+ $_tmp['appOS'] = 'OS/2 Warp';
+
+ // Get the XML for a malformed URI.
+ $_xml = $this->_getXml($_tmp);
+
+ // The resulting document should be parsable.
+ $this->assertTrue($this->_isParsable($_xml), 'Document still parsable when appOS is '.$_tmp['appOS'].'.');
+
+ // The resulting document should be equal to our no updates xml.
+ $this->assertEqual($this->_noUpdatesXml, $_xml, 'No update was offered.');
+ }
+
+ /**
+ * No update for an incompatible application version.
+ */
+ function testNoUpdateForIncompatibleApplicationVersion() {
+
+ // Store args in a temp array so we can fudge it up.
+ $_tmp = $this->_args;
+
+ // We want to mess up a value on purpose.
+ $_tmp['appVersion'] = '1.1';
+
+ // Get the XML for a malformed URI.
+ $_xml = $this->_getXml($_tmp);
+
+ // The resulting document should be parsable.
+ $this->assertTrue($this->_isParsable($_xml), 'Document still parsable when appVersion is '.$_tmp['appVersion'].'.');
+
+ // The resulting document should be equal to our no updates xml.
+ $this->assertEqual($this->_noUpdatesXml, $_xml, 'No update was offered.');
+ }
+
+ /**
+ * Test to see that an update exists for an arbitrarily old version (v0.0).
+ *
+ * An update should be offered if the requesting client's version is older
+ * or equal to the newest version in the database.
+ */
+ function testUpdateExistsForOldOrEqualVersion() {
+
+ $this->_args = array(
+ 'reqVersion'=>'1',
+ 'id'=>'farming@microfarmer.org',
+ 'version'=>'0.1',
+ 'maxAppVersion'=>'1.0',
+ 'status'=>'on',
+ 'appID'=>'{ec8030f7-c20a-464f-9b0e-13a3a9e97384}',
+ 'appVersion'=>'1.5',
+ 'appOS'=>'WINNT',
+ 'appABI'=>'1');
+
+ // Get the XML for the default arguments.
+ $_xml = $this->_getXml($this->_args);
+
+ // The resulting document should be parsable.
+ $this->assertTrue($this->_isParsable($_xml), 'Document still parsable when appVersion is '.$this->_args['appVersion'].'.');
+
+ // The resulting document should give us an update. We should test to see if the update was delivered.
+ // To do this, we will test elements that should be in the resulting data.
+ $this->assertPattern("/.*{$this->data['Addon']['guid']}.*/", "GUID {$this->data['Addon']['guid']} found in update XML.");
+
+ $this->assertPattern("/.*{$this->data['Version'][0]['Version']['version']}.*/", "Latest version ({$this->data['Version'][0]['Version']['version']}) found in update XML.");
+
+ $_fileUrl = FILES_HOST . '/' . $this->data['Addon']['id'] . '/' . $this->data['Version'][0]['File'][0]['filename'];
+ UnitTestCase::assertPattern('/.*'.preg_quote($_fileUrl, '/').'.*/', $_xml, "File URL {$_fileUrl} found in update XML.");
+
+ $wantedPattern = '#{ec8030f7-c20a-464f-9b0e-13a3a9e97384}#';
+ $this->assertPattern($wantedPattern, 'Application GUID found in update XML.');
+ }
+
+ /**
+ * Tests to make sure that updates are still available for a
+ * platform-specific add-on.
+ *
+ * Our test case in this case is an add-on only available for Solaris.
+ *
+ * I also fudged the appOS to verify that it works for a fuzzy match not
+ * exact match.
+ */
+ function testUpdateExistsForPlatformSpecificAddon() {
+
+ $this->_args = array(
+ 'reqVersion'=>'1',
+ 'id'=>'hunter@farmerland.org',
+ 'version'=>'0.1',
+ 'maxAppVersion'=>'1.0',
+ 'status'=>'on',
+ 'appID'=>'{ec8030f7-c20a-464f-9b0e-13a3a9e97384}',
+ 'appVersion'=>'1.5',
+ 'appOS'=>'SunOs',
+ 'appABI'=>'1');
+
+ // Get custom add-on data.
+ $buf = $this->model->find("Addon.id=9", null , null , 2);
+ $buf['Version'] = $this->versionModel->findAll("Version.addon_id=9", null, "Version.created DESC", 0);
+
+ // Get the XML for the default arguments.
+ $_xml = $this->_getXml($this->_args);
+
+ // The resulting document should be parsable.
+ $this->assertTrue($this->_isParsable($_xml), 'Document still parsable when appVersion is '.$this->_args['appVersion'].'.');
+
+ // The resulting document should give us an update. We should test to see if the update was delivered.
+ // To do this, we will test elements that should be in the resulting data.
+ $this->assertPattern("/.*{$buf['Addon']['guid']}.*/", "GUID {$buf['Addon']['guid']} found in update XML.");
+
+ $this->assertPattern("/.*{$buf['Version'][0]['Version']['version']}.*/", "Latest version ({$buf['Version'][0]['Version']['version']}) found in update XML.");
+
+ $_fileUrl = FILES_HOST . '/' . $buf['Addon']['id'] . '/' . $buf['Version'][0]['File'][0]['filename'];
+ UnitTestCase::assertPattern('/.*'.preg_quote($_fileUrl, '/').'.*/', $_xml, "File URL {$_fileUrl} found in update XML.");
+
+ $wantedPattern = '#{ec8030f7-c20a-464f-9b0e-13a3a9e97384}#';
+ $this->assertPattern($wantedPattern, 'Application GUID found in update XML.');
+ }
+
+
+
+ /**
+ * Test that we don't get an update for a sandbox version not in the DB
+ */
+ function testNoUpdateForSandbox() {
+ $this->_args = array(
+ 'reqVersion'=>'1',
+ 'id'=>'{A17C1C5A-04C1-11DB-9805-B632A1EF5496}',
+ 'version'=>'0.1',
+ 'maxAppVersion'=>'1.0',
+ 'status'=>'userEnabled',
+ 'appID'=>'{ec8030f7-c20a-464f-9b0e-13a3a9e97384}',
+ 'appVersion'=>'1.5',
+ 'appOS'=>'WINNT',
+ 'appABI'=>'x86-msvc');
+
+ // Get the XML for the default arguments.
+ $_xml = $this->_getXml($this->_args);
+
+ // The resulting document should be parsable.
+ $this->assertTrue($this->_isParsable($_xml), 'Document still parsable for sandbox add-on '.$this->_args['id'].'.');
+
+ // The resulting document should be equal to our no updates xml.
+ $this->assertEqual($this->_noUpdatesXml, $_xml, 'No update was offered for sandbox add-on.');
+ }
+
+ /**
+ * Test that we get version compat info for a sandbox version in the DB
+ */
+ function testCompatInfoForSandbox() {
+ $this->_args = array(
+ 'reqVersion'=>'1',
+ 'id'=>'{A17C1C5A-04C1-11DB-9805-B632A1EF5496}',
+ 'version'=>'1.0',
+ 'maxAppVersion'=>'1.0',
+ 'status'=>'userEnabled',
+ 'appID'=>'{ec8030f7-c20a-464f-9b0e-13a3a9e97384}',
+ 'appVersion'=>'1.5',
+ 'appOS'=>'WINNT',
+ 'appABI'=>'x86-msvc');
+
+ // Get the XML for the default arguments.
+ $_xml = $this->_getXml($this->_args);
+
+ // The resulting document should be parsable.
+ $this->assertTrue($this->_isParsable($_xml), 'Document still parsable for sandbox add-on '.$this->_args['id'].'.');
+
+ // Make sure result has same version
+ $this->assertPattern("/.*<em:version>1\.0<\/em:version>.*/", 'Version 1.0 returned compat info');
+
+ // Make sure result has correct minVersion
+ $this->assertPattern("/.*<em:minVersion>1.5<\/em:minVersion>.*/", 'minVersion returned 1.5');
+
+ // Make sure result has correct maxVersion
+ $this->assertPattern("/.*<em:maxVersion>3\.0a1<\/em:maxVersion>.*/", 'maxVersion returned 3.0a1');
+ }
+
+ /**
+ * Test that we don't get a file that is in the sandbox in the update for a public add-on.
+ */
+ function testNoSandboxFileForPublicAddon() {
+ $this->data = $this->model->find("Addon.id=4023", null , null , 2);
+ $this->data['Version'] = $this->versionModel->findAll("Version.addon_id=4023", null, "Version.created DESC", 0);
+
+ // Get the XML for the default arguments.
+ $_xml = $this->_getXml($this->_args);
+
+ // The resulting document should be parsable.
+ $this->assertTrue($this->_isParsable($_xml), 'Document still parsable for sandbox add-on '.$this->_args['id'].'.');
+
+ // Assert that the sandbox file is not present.
+ $_fileUrl = FILES_HOST . '/' . FILES_URL . '/' . $this->data['Version'][0]['File'][0]['id'];
+ $this->assertNoPattern('/.*'.preg_quote($_fileUrl, '/').'.*/', "Sandbox file {$_fileUrl} not found in update XML.");
+ }
+
+ /**
+ * Test that no upate is offered for an inactive add-on.
+ */
+ function xfail_testNoUpdateForInactiveAddon() {
+ // Replace this with ID of an inactive addon.
+ // There currently isn't SQL in there for it, but will add it post release.
+ $this->data = $this->model->find("Addon.id=4023", null , null , 2);
+ $this->data['Version'] = $this->versionModel->findAll("Version.addon_id=4023", null, "Version.created DESC", 0);
+
+ // Get the XML for the default arguments.
+ $_xml = $this->_getXml($this->_args);
+
+ // The resulting document should be parsable.
+ $this->assertTrue($this->_isParsable($_xml), 'Document still parsable for inactive add-on '.$this->_args['id'].'.');
+
+ // The resulting document should be equal to our no updates xml.
+ $this->assertEqual($this->_noUpdatesXml, $_xml, 'No update was offered for an inactive add-on.');
+ }
+
+ /**
+ * Test the results of get_os_id() for common platforms.
+ */
+ function testPlatforms() {
+ $this->assertEqual(get_os_id('Linux'),PLATFORM_LINUX,'Linux detection works.');
+ $this->assertEqual(get_os_id('FreeBSD'),PLATFORM_BSD,'BSD detection works.');
+ $this->assertEqual(get_os_id('Darwin'),PLATFORM_MAC,'OS X detection works (Darwin).');
+ $this->assertEqual(get_os_id('WINNT'),PLATFORM_WIN,'Windows detection works.');
+ $this->assertEqual(get_os_id('SunOs'),PLATFORM_SUN,'Solaris detection works.');
+ }
+}
+?>
diff --git a/site/app/tests/testSuite.html b/site/app/tests/testSuite.html
new file mode 100644
index 0000000..0dc0073
--- /dev/null
+++ b/site/app/tests/testSuite.html
@@ -0,0 +1,10 @@
+<table>
+<tr>
+<td>Test suite for the whole application</td>
+</tr>
+<tr>
+<td><a target="testFrame" href="amo-selenium.html" >amo-selenium</a></td>
+</tr>
+<td><a target="testFrame" href="search.html" >search</a></td>
+</tr>
+</table> \ No newline at end of file
diff --git a/site/app/tests/test_helper_unit.php b/site/app/tests/test_helper_unit.php
new file mode 100644
index 0000000..f88f691
--- /dev/null
+++ b/site/app/tests/test_helper_unit.php
@@ -0,0 +1,316 @@
+<?php
+/**
+* Original file from http://cakephp.org/pastes/show/8803bd09150cb65cc7da63f92cdbc828
+* Modifications by Justin Scott <fligtar@gmail.com>
+*/
+
+class UnitTestHelper
+{
+ var $previouslyCalled = array(); //called actions go here once called once
+
+ /**
+ * Loops through the $uses array of a Controller and mocks all used Models
+ * and also allows additional methods for them to be pased via $params, (as
+ * well as to set names for the generated mocks).
+ *
+ * @param unknown_type $Controller
+ * @param mixed $testCase
+ * @param unknown_type $params
+ */
+ function mockModels(&$Controller, &$testCase, $params = array())
+ {
+ if ($Controller->uses===false)
+ {
+ $model = Inflector::singularize($Controller->name);
+
+ /**
+ * If our uses array is empty CakePHP will always assume a default model.
+ * So let's check if it exists.
+ */
+ $testCase->assertTrue(class_exists(strtolower($model)), 'Model "'.$model.'" exists');
+
+ return;
+ }
+
+ /**
+ * If we have Models to mock let's loop throw them
+ */
+ if (is_array($Controller->uses))
+ {
+ foreach ($Controller->uses as $model)
+ {
+ /**
+ * Check if the Models we use exist (CakePHP automatically includes them for us)
+ */
+ $modelExists = $testCase->assertTrue(class_exists(strtolower($model)), 'Model "'.$model.'" exists');
+
+ if ($modelExists)
+ {
+ /**
+ * If we have customized Model Mocks to generate, set the vars for it
+ */
+ if (isset($params[$model]['name']))
+ $class = $params[$model]['name'];
+ else
+ $class = false;
+
+ if (isset($params[$model]['methods']))
+ $methods = $params[$model]['methods'];
+ else
+ $methods = false;
+
+ /**
+ * Create the Model Mock
+ */
+ Mock::generate($model, $class, $methods);
+
+ /**
+ * Add the Mock to the Controller
+ */
+ $mockModel = 'Mock'.$model;
+ $Controller->{$model} =& new $mockModel;
+ }
+ }
+ }
+ }
+
+ /**
+ * Loads the components for a controller
+ * @param unknown_type $controller
+ * @param unkown-type $testCase
+ */
+ function mockComponents(&$controller, &$testCase) {
+ if(is_array($controller->components)) {
+ foreach($controller->components as $component) {
+ loadComponent($component);
+ $componentClass = $component.'Component';
+ $testCase->assertTrue(class_exists($componentClass), 'Component "'.$component.'" exists');
+ Mock::generate($componentClass, false, false);
+ $mockComponent = 'Mock'.$componentClass;
+ $controller->{$component} =& new $mockComponent;
+ /*if(method_exists($controller->{$component}, 'startup')) {
+ $controller->{$component}->startup($controller);
+ call_user_func(array($componentClass, 'startup'), $controller);
+ }*/
+ }
+ }
+ }
+
+ /**
+ * Returns a fully initialized Controller
+ *
+ * @param unknown_type $controller
+ * @param unknown_type $testCase
+ * @param unknown_type $app
+ * @return unknown
+ */
+ function getController($controller, &$testCase, $app = 'app')
+ {
+ $this->loadController($controller, $testCase, $app);
+
+ $className = $controller.'Controller';
+
+ // intercept flash() and redirect() calls from Controller
+ if (!class_exists('Mock'.$className)) {
+ eval(' class Mock'.$className.' extends '.$className.' {
+ function flash($msg,$url,$pause=1) {}
+ function redirect($url,$status=null) {}
+ }');
+ }
+
+ $mockControllerName = 'Mock'.$className;
+
+ $Controller =& new $mockControllerName();
+ $Controller->constructClasses();
+ return $Controller;
+ }
+
+ /**
+ * Calls a Controller action and returns the function return value or the output
+ * if existing.
+ *
+ * @param object $Controller
+ * @param string $action
+ * @param object $testCase
+ * @param array $params
+ * @param string $app
+ * @return mixed
+ */
+ function callControllerAction(&$Controller, $action, &$testCase, $params = array(), $app = 'app')
+ {
+ $methods = get_class_methods($Controller);
+
+ //Cut down on spam
+ if (!array_key_exists($Controller->name, $this->previouslyCalled) || (array_key_exists($Controller->name, $this->previouslyCalled) && !in_array($action, $this->previouslyCalled[$Controller->name]))) {
+ $testCase->assertTrue(in_array($action, $methods), $Controller->name.'Controller::'.$action.'() exists');
+ $this->previouslyCalled[$Controller->name][] = $action;
+ }
+
+ if (!is_array($params))
+ $params = array();
+
+ $Controller->action = $action;
+
+ /**
+ * By creating our own AppError class we can catch Object::cakeError() calls and
+ * output them so we can throw an exception later on!
+ */
+ if (!class_exists('AppError'))
+ {
+ eval('class AppError
+ {
+ function AppError($method)
+ {
+ echo "error:$method";
+ }
+ }');
+ }
+
+ ob_start();
+ $return = call_user_func_array(array(&$Controller, $action), $params);
+ $output = @ob_get_clean();
+
+ if ($Controller->autoRender)
+ {
+ ob_start();
+ $Controller->render();
+ $output = @ob_get_clean();
+ }
+
+ /*
+ * @TODO This is ugly:
+ * Print SimpleTest error messages if there were any in the output.
+ */
+ $outputarray = explode("\n", $output);
+ $outputarray = preg_grep('/^<div class="(pass|fail)">.*<\/div>$/', $outputarray);
+ foreach ($outputarray as $errorline)
+ print $errorline."\n";
+
+ /**
+ * When running our TestCase rendering an action might causes some error notices
+ * from the Sessions object that is trying to send headers.
+ *
+ * Since there is nothing we can do to prevent those, we are going to filter them
+ * out and add the $realErrors back into the queue later on.
+ */
+ $queue = &SimpleTest::getContext()->get('SimpleErrorQueue');
+ $realErrors = array();
+
+ while ($error = $queue->extract())
+ {
+ if (!preg_match('/headers already sent/i', $error[1]))
+ {
+ $realErrors[] = $error;
+ break;
+ }
+ }
+
+ /**
+ * Add the real errors back to the queue
+ */
+ foreach ($realErrors as $error)
+ {
+ call_user_func_array(array(&$queue, 'add'), $error);
+ }
+
+ $match = null;
+ if (preg_match('/^error:(.+)$/', $output, $match))
+ {
+ trigger_error('CakePHP Error: '.$match[1], E_USER_WARNING);
+ }
+
+ if (empty($output))
+ return $return;
+ else
+ return $output;
+ }
+
+ /**
+ * Loads a controller named $controller. If the User passes an instance of the $testCase
+ * that this call is being made from, an automatic assertion for the existence of this
+ * Controller happens.
+ *
+ * @param string $controller
+ * @param object $testCase
+ * @param string $app
+ */
+ function loadController($controller, &$testCase, $app = 'app')
+ {
+ // do not try to load a "dummy" controller.
+ if ($controller == 'Dummy') return;
+
+ $controllerFile = CONTROLLERS.strtolower($controller).'_controller.php';
+ $controllerExists = file_exists($controllerFile);
+
+ $testCase->assertTrue($controllerExists, 'Load Controller "'.$controller.'Controller"');
+
+ if ($controllerExists)
+ loadController($controller);
+ }
+
+ /**
+ * Log ourselves in (i.e. mock the session component results)
+ */
+ function login(&$controller) {
+ $userdata = array(
+ 'id' => 5,
+ 'email' => 'nobody@mozilla.org',
+ 'password' => '098f6bcd4621d373cade4e832627b4f6',
+ 'firstname' => 'Andrei',
+ 'lastname' => 'Hajdukewycz',
+ 'nickname' => 'Sancus',
+ 'emailhidden' => 0,
+ 'homepage' => 'http://www.worldofwarcraft.com',
+ 'confirmationcode' => '',
+ 'created' => '2006-09-28 08:57:24',
+ 'modified' => '2006-09-28 08:57:24'
+ );
+ $controller->Session->setReturnValue('read', $userdata, 'User');
+ }
+
+ /**
+ * Log out
+ */
+ function logout(&$controller) {
+ $controller->Session->setReturnvalue('read', null, 'User');
+ }
+
+ /**
+ * Compares two arrays to see if they contain the same values. Returns TRUE or FALSE.
+ * useful for determining if a record or block of data was modified (perhaps by user input)
+ * prior to setting a "date_last_updated" or skipping updating the db in the case of no change.
+ *
+ * From some random comment on php.net!
+ *
+ * @param array $a1
+ * @param array $a2
+ * @return boolean
+ */
+ function array_compare_recursive($a1, $a2)
+ {
+ if (!(is_array($a1) and (is_array($a2)))) return false;
+
+ if (!count($a1) == count($a2)) {
+ return false; // arrays don't have same number of entries
+ }
+
+ foreach ($a1 as $key => $val) {
+ if (!array_key_exists($key, $a2)) {
+ // uncomparable array keys don't match
+ return false;
+
+ } elseif (is_array($val) and is_array($a2[$key])) {
+ // if both entries are arrays then compare recursive
+ if (!$this->array_compare_recursive($val,$a2[$key])) return false;
+
+ } elseif (!($val === $a2[$key])) {
+ // compare entries must be of same type.
+ return false;
+ }
+ }
+ return true; // $a1 === $a2
+ }
+
+}
+
+?>
diff --git a/site/app/tests/test_helper_web.php b/site/app/tests/test_helper_web.php
new file mode 100644
index 0000000..81ec63f
--- /dev/null
+++ b/site/app/tests/test_helper_web.php
@@ -0,0 +1,244 @@
+<?php
+
+class WebTestHelper extends WebTestCase {
+
+ function before($method) {
+ // The test browser is created in parent::before.
+ parent::before($method);
+ $this->addHeader('X-Amo-Test: damn right');
+ }
+
+ /* Compute protocol and hostname prefix, no trailing slash. */
+ function hostPrefix() {
+ $http = (!empty($_SERVER["HTTP_MOZ_REQ_METHOD"]) && $_SERVER["HTTP_MOZ_REQ_METHOD"] == 'HTTPS') ? 'https://' : 'http://';
+ $uriBase = $http . $_SERVER['HTTP_HOST'];
+ return $uriBase;
+ }
+
+ /**
+ * The default SimpleBrowser tries to parse all responses, even when
+ * they're not HTML. That fails. We need a better browser.
+ *
+ * Creates a new default web browser object.
+ * Will be cleared at the end of the test method.
+ */
+ function &createBrowser() {
+ $browser =& new BetterBrowser();
+ return $browser;
+ }
+
+ /* Compute the URI for the given action, accounting for us possibly not
+ * being at the root of the web space.
+ */
+ function actionURI($action) {
+ /**
+ If HTTP_MOZ_REQ_METHOD indicates this was requested via https://,
+ use that, otherwise default to http://
+ */
+ return $this->hostPrefix() . $this->actionPath($action);
+ }
+
+ /* As above, but just the local path and not a complete URI. */
+ function actionPath($action) {
+ return preg_replace('/\/tests.*/', $action, setUri());
+ }
+
+ /* Return a URI computed from the installation base, without locale or app. */
+
+ function rawURI($path) {
+ return $this->hostPrefix() . $this->rawPath($path);
+ }
+
+ /* As above, but just the local path and not a complete URI. */
+ function rawPath($path) {
+ return preg_replace('/\/' . LANG . '\/' . APP_SHORTNAME . '\/tests.*/', $path, setUri());
+ }
+
+ /* Make a GET for the given action, accounting for us possibly not being at
+ * the root of the web space.
+ */
+ function getAction($action) {
+ $this->get($this->actionURI($action));
+ }
+
+ /* GET a fully-specified local URI path (needs to include site prefix if any). */
+ function getPath($path) {
+ $this->get($this->hostPrefix() . $path);
+ }
+
+ /**
+ * Logs in with test account info.
+ */
+ function login() {
+ $username = 'nobody@mozilla.org';
+ $password = 'test';
+
+ $path = $this->actionURI('/users/login');
+ $data = array(
+ 'data[Login][email]' => $username,
+ 'data[Login][password]' => $password
+ );
+
+ $this->post($path, $data);
+ $this->assertNoUnwantedText(_('error_username_or_pw_wrong'), 'Logged in with test account');
+ }
+
+ /**
+ * Check if the retrieved XML document is well-formed/trivially parsable
+ * (no DTD validity for now)
+ */
+ function checkXML() {
+ $browser = $this->getBrowser();
+ $data = $browser->getContent();
+ $xmlparser = xml_parser_create();
+ return (xml_parse($xmlparser, $data, true) == 1);;
+ }
+
+ /**
+ * Check that there is a link like <a href=$href>$text</a>.
+ */
+ function assertLinkLocation($href, $text) {
+ phpQuery::newDocument($this->_browser->getContent());
+ $q = pq("a[href$={$href}");
+ $msg = htmlentities("<a href='{$href}'>{$text}</a> exists");
+ $this->assertEqual($q->text(), $text, $msg);
+ }
+
+ /**
+ * Check that the element $q has the attributes in the $attrs array.
+ * $q can be a phpquery object or a selector string.
+ */
+ function assertAttrs($q, $attrs, $msg) {
+ if (is_string($q)) {
+ phpQuery::newDocument($this->_browser->getContent());
+ $q = pq($q);
+ }
+ foreach ($attrs as $attr => $val) {
+ $this->assertEqual($q->attr($attr), $val, $msg);
+ }
+ }
+
+ /* Helper to normalize whitespace in a string. */
+ function _norm($x) {
+ return implode(' ', preg_split('/\s+/', trim($x)));
+ }
+
+ /* Assert that the strings have the same content, ignoring whitespace. */
+ function assertEquiv($a, $b, $msg=null) {
+ $this->assertEqual($this->_norm($a), $this->_norm($b));
+ }
+
+ function delete($url, $parameters = false) {
+ return $this->_failOnError($this->_browser->delete($url, $parameters));
+ }
+
+ function put($url, $parameters = false) {
+ return $this->_failOnError($this->_browser->put($url, $parameters));
+ }
+
+ function postMultipart($url, $parameters = false, $files = false) {
+ return $this->_failOnError($this->_browser->postMultipart($url, $parameters, $files));
+ }
+}
+
+class BetterBrowser extends SimpleBrowser {
+
+ /**
+ * Overrides _buildPage to only parse responses when the Content Type
+ * looks like HTML.
+ */
+ function &_buildPage($response) {
+ $headers = $response->getHeaders()->getRaw();
+ if (preg_match('#^Content-Type: (text/html|application/xhtml+xml)#m', $headers)) {
+ $page =& parent::_buildPage($response);
+ } else {
+ $page =& new SimplePage($response);
+ }
+ return $page;
+ }
+
+ /* Define $this->_browser->skipParse to avoid the HTML parsing overhead. */
+ function &_fetch($url, $encoding, $depth=0) {
+ if (isset($this->skipParse)) {
+ $response = &$this->_user_agent->fetchResponse($url, $encoding);
+ $page = new SimplePage($response);
+ return $page;
+ } else {
+ return parent::_fetch($url, $encoding, $depth);
+ }
+ }
+
+ function delete($url, $parameters = false) {
+ if (! is_object($url)) {
+ $url = new SimpleUrl($url);
+ }
+ if ($this->getUrl()) {
+ $url = $url->makeAbsolute($this->getUrl());
+ }
+ return $this->_load($url, new SimpleDeleteEncoding($parameters));
+ }
+
+ function put($url, $parameters = false) {
+ if (! is_object($url)) {
+ $url = new SimpleUrl($url);
+ }
+ if ($this->getUrl()) {
+ $url = $url->makeAbsolute($this->getUrl());
+ }
+ return $this->_load($url, new SimplePutEncoding($parameters));
+ }
+
+ /**
+ * Multipart POST request. May contain file attachments.
+ * @param string $url target URL
+ * @param array $parameters array of POST parameters
+ * @param array $files further POST parameters of type key => path to file to attach
+ */
+ function postMultipart($url, $parameters = false, $files = false) {
+ if (! is_object($url)) {
+ $url = new SimpleUrl($url);
+ }
+ if ($this->getUrl()) {
+ $url = $url->makeAbsolute($this->getUrl());
+ }
+ // prepare multipart encoding
+ $encoding = new SimpleMultipartEncoding($parameters);
+ // attach files if needed
+ if (!empty($files) && is_array($files)) {
+ foreach($files as $k => &$f) {
+ if (! file_exists($f)) continue;
+ $encoding->attach(
+ $k,
+ implode('', file($f)),
+ basename($f));
+ }
+ }
+
+ return $this->_load($url, $encoding);
+ }
+}
+
+/**
+ * Bundle of URL parameters for a DELETE request.
+ */
+class SimpleDeleteEncoding extends SimpleGetEncoding {
+ function SimpleDeleteEncoding($query = false) {
+ $this->SimpleGetEncoding($query);
+ }
+ function getMethod() {
+ return 'DELETE';
+ }
+}
+
+/**
+ * Bundle of URL parameters for a PUT request.
+ */
+class SimplePutEncoding extends SimplePostEncoding {
+ function SimplePutEncoding($query = false) {
+ $this->SimplePostEncoding($query);
+ }
+ function getMethod() {
+ return 'PUT';
+ }
+}
+?>
diff --git a/site/app/tests/test_manager.php b/site/app/tests/test_manager.php
new file mode 100644
index 0000000..01428ef
--- /dev/null
+++ b/site/app/tests/test_manager.php
@@ -0,0 +1,190 @@
+<?php
+/* SVN FILE: $Id: test_manager.php,v 1.1.1.1 2006/08/14 23:54:57 sancus%off.net Exp $ */
+/**
+ * Short description for file.
+ *
+ * Long description for file
+ *
+ * PHP versions 4 and 5
+ *
+ * CakePHP Test Suite <https://trac.cakephp.org/wiki/Developement/TestSuite>
+ * Copyright (c) 2006, Larry E. Masters Shorewood, IL. 60431
+ * Author(s): Larry E. Masters aka PhpNut <phpnut@gmail.com>
+ * Justin Scott aka fligtar <fligtar@gmail.com>
+ * Mike Shaver aka the_decider <shaver@mozilla.org>
+ *
+ * Portions modifiied from WACT Test Suite
+ * Author(s): Harry Fuecks
+ * Jon Ramsey
+ * Jason E. Sweat
+ * Franco Ponticelli
+ * Lorenzo Alberton
+ *
+ * Licensed under The Open Group Test Suite License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @author Larry E. Masters aka PhpNut <phpnut@gmail.com>
+ * @copyright Copyright (c) 2006, Larry E. Masters Shorewood, IL. 60431
+ * @link http://www.phpnut.com/projects/
+ * @package tests
+ * @subpackage tests.lib
+ * @since CakePHP Test Suite v 1.0.0.0
+ * @version $Revision: 1.1.1.1 $
+ * @modifiedby $LastChangedBy: dho $
+ * @lastmodified $Date: 2006/08/14 23:54:57 $
+ * @license http://www.opensource.org/licenses/opengroup.php The Open Group Test Suite License
+ */
+/**
+ * Short description for class.
+ *
+ * @package tests
+ * @subpackage tests.lib
+ * @since CakePHP Test Suite v 1.0.0.0
+ */
+
+DATABASE_CONFIG::useTestConfig();
+
+class TestManager {
+ var $_testExtension = array('.test.php', '.test.thtml', '.test.thtml.php');
+
+ function runAllTests(&$reporter) {
+ $manager =& new TestManager();
+
+ $testCases =& $manager->_getTestFileList(TESTS);
+
+ $test =& new GroupTest('All Test Cases');
+
+ foreach ($testCases as $testCase) {
+ $test->addTestFile($testCase);
+ }
+
+ $test->run($reporter);
+ }
+
+ function runDirectory($directory, &$reporter) {
+ $manager =& new TestManager();
+
+ $testCases =& $manager->_getTestFileList(TESTS.$directory);
+
+ $test =& new GroupTest('Directory Test: '.$directory);
+
+ foreach ($testCases as $testCase) {
+ $test->addTestFile($testCase);
+ }
+
+ $test->run($reporter);
+ }
+
+ function runGroup($group, &$reporter) {
+
+ $manager =& new TestManager();
+
+ $testCases =& $group['cases'];
+
+ $test =& new GroupTest('Group Test: '.$group['name']);
+
+ foreach ($testCases as $testCase) {
+ if (strpos($testCase, '*') !== false) {
+ $testCase = str_replace('/*', '', $testCase);
+ $dirCases = $manager->_getTestFileList(TESTS.$testCase);
+ foreach ($dirCases as $dirCase) {
+ $test->addTestFile($dirCase);
+ }
+ }
+ else {
+ $test->addTestFile(TESTS.$testCase);
+ }
+ }
+
+ $test->addTestFile(TESTS.'global.test.php');
+
+ $test->run($reporter);
+ }
+
+ function runTestCase($testCaseFile, &$reporter) {
+ $manager =& new TestManager();
+
+ $testCaseFileWithPath = TESTS.$testCaseFile;
+ if (! file_exists($testCaseFileWithPath)) {
+ trigger_error("Test case {$testCaseFile} cannot be found", E_USER_ERROR);
+ }
+ $test =& new GroupTest("Test Case: " . $testCaseFile);
+ $test->addTestFile($testCaseFileWithPath);
+ if ($testCaseFile != 'global.test.php') {
+ $test->addTestFile(TESTS.'global.test.php');
+ }
+ $test->run($reporter);
+ }
+
+ function addTestCasesFromDirectory(&$groupTest, $directory = '.') {
+ $manager =& new TestManager();
+ $testCases =& $manager->_getTestFileList($directory);
+ foreach ($testCases as $testCase) {
+ $groupTest->addTestFile($testCase);
+ }
+ }
+
+ function &getTestCaseList($directory = '') {
+ if (empty($directory)) {
+ $directory = TESTS;
+ }
+ $manager =& new TestManager();
+ $testCases =& $manager->_getTestCaseList($directory);
+
+ sort($testCases);
+ return $testCases;
+ }
+
+ function &_getTestCaseList($directory = '.') {
+ $fileList =& $this->_getTestFileList($directory);
+ $testCases = array();
+ foreach ($fileList as $testCaseFile) {
+ $testCases[$testCaseFile] = str_replace($directory . DS, '', $testCaseFile);
+ }
+ return $testCases;
+ }
+
+ function &_getTestFileList($directory = '.') {
+ $return = $this->_getRecursiveFileList($directory, array(&$this, '_isTestCaseFile'));
+ return $return;
+ }
+
+ function &_getRecursiveFileList($directory = '.', $fileTestFunction) {
+ $dh = opendir($directory);
+ if (! is_resource($dh)) {
+ trigger_error("Couldn't open {$directory}", E_USER_ERROR);
+ }
+
+ $fileList = array();
+ while ($file = readdir($dh)) {
+ $filePath = $directory . DIRECTORY_SEPARATOR . $file;
+ if (0 === strpos($file, '.')) {
+ continue;
+ }
+
+ if (is_dir($filePath)) {
+ $fileList = array_merge($fileList, $this->_getRecursiveFileList($filePath, $fileTestFunction));
+ }
+ if ($fileTestFunction[0]->$fileTestFunction[1]($file)) {
+ $fileList[] = $filePath;
+ }
+ }
+ closedir($dh);
+ return $fileList;
+ }
+
+ function _isTestCaseFile($file) {
+ foreach ($this->_testExtension as $extension) {
+ if ($this->_hasExpectedExtension($file, $extension)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ function _hasExpectedExtension($file, $extension) {
+ return $extension == strtolower(substr($file, (0 - strlen($extension))));
+ }
+}
+?>
diff --git a/site/app/tests/views/addons/dictionaries.test.php b/site/app/tests/views/addons/dictionaries.test.php
new file mode 100644
index 0000000..3bf686b
--- /dev/null
+++ b/site/app/tests/views/addons/dictionaries.test.php
@@ -0,0 +1,71 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Frederic Wenzel <fwenzel@mozilla.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+class AddonDictionariesTest extends WebTestHelper {
+
+ function AddonDictionariesTest() {
+ $this->WebTestCase("Views->Addons->Dictionaries Tests");
+ }
+
+ function setUp() {
+ $this->getAction('/browse/type:'.ADDON_DICT);
+
+ global $TestController;
+ $this->helper = new UnitTestHelper();
+ $this->controller = $this->helper->getController('Addons', $this);
+ $this->controller->base = $TestController->base;
+ }
+
+ function testRemoraPage() {
+ // just checks if the page works or not
+ $this->assertWantedPattern('/Mozilla Add-ons/i', "pattern detected");
+ }
+
+ function testDicts() {
+ }
+
+ /**
+ * There was a bug (376461) about locale codes getting html-encoded, which shouldn't happen
+ */
+ //function testLocaleCode() {
+ // $pattern = "#addDictionary\(\s*'de-DE',.*\)#";
+ // $this->assertPattern($pattern, htmlentities($pattern));
+ //} // -CP addDictionary( javascript no longer exists.
+
+}
+?>
diff --git a/site/app/tests/views/addons/display.test.php b/site/app/tests/views/addons/display.test.php
new file mode 100644
index 0000000..abaa42f
--- /dev/null
+++ b/site/app/tests/views/addons/display.test.php
@@ -0,0 +1,222 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Andrei Hajdukewycz <sancus@off.net> (Original Author)
+ * Frederic Wenzel <fwenzel@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+class AddonTest extends WebTestHelper {
+
+ function AddonTest() {
+ $this->WebTestCase("Views->Addons->Display Tests");
+ loadModel('Addon');
+ loadModel('Tag');
+ loadModel('Version');
+ }
+
+ function setUp() {
+ $this->id = 7;//$_GET['id'];
+
+ $model =& new Addon();
+ $model->caching = false;
+
+ $tagModel =& new Tag();
+ $tagModel->caching = false;
+
+ $versionModel =& new Version();
+ $versionModel->caching = false;
+
+ $this->data = $model->find("Addon.id=$this->id", null , null , 2);
+ $this->data['Version'] = $versionModel->findAll("Version.addon_id=$this->id", null, "Version.created DESC", 0);
+ //get tag l10n data
+ foreach ($this->data['Tag'] as $tagkey => $tagvalue) {
+ if ($tagkey == 0)
+ $related_tag_query = "Tag.id='${tagvalue['id']}'";
+ else
+ $related_tag_query = $related_tag_query . " OR Tag.id ='${tagvalue['id']}'";
+ }
+ $this->tagData = $tagModel->findAll($related_tag_query);
+
+ $this->getAction("/addon/" . $this->id);
+
+ global $TestController;
+ $this->helper = new UnitTestHelper();
+ $this->controller = $this->helper->getController('Addons', $this);
+ $this->controller->base = $TestController->base;
+ loadComponent('Image');
+ $this->controller->Image =& new ImageComponent();
+ $this->controller->Image->startup($this->controller);
+ }
+
+ function testRemoraPage() {
+ //just checks if the page works or not
+ $this->assertWantedPattern('/Mozilla Add-ons/i', "pattern detected");
+ }
+
+ function testDisplay() {
+ // Title
+ $this->title = sprintf(_('addons_display_pagetitle'), $this->data['Translation']['name']['string']). ' :: '.sprintf(_('addons_home_pagetitle'), APP_PRETTYNAME);
+ $this->assertTitle($this->title);
+ // Author
+ $username = $this->data['User'][0]['nickname'];
+ $userid = $this->data['User'][0]['id'];
+ $this->actionPath = $this->actionPath("");
+ $this->authorPattern = "@<h4 class=\"author\">by +<a href=\"{$this->actionPath}/user/{$userid}\" class=\"profileLink\">{$username}</a> ?</h4>@";
+ $this->assertWantedPattern($this->authorPattern, htmlentities($this->authorPattern));
+
+ //@TODO Size: Figure out some way to use the Number Helper in this test
+ //$this->wantedPattern = "#<span>\(" . $this->data['Version'][0]['File'][0]['size'] . "KB\)</span>#";
+ //$this->assertWantedPattern($this->wantedPattern, htmlentities($this->wantedPattern));
+
+ // tags
+ foreach ($this->tagData as $tag) {
+ $this->wantedPattern = "@<li><a href=\"[^\"]+\"( )*>" . $tag['Translation']['name']['string'] . "</a></li>@";
+ $this->assertWantedPattern($this->wantedPattern, htmlentities($this->wantedPattern));
+ }
+ // are reviews displayed?
+ $this->wantedPattern = "@"._('addons_display_header_reviews')."@";
+ $this->assertWantedPattern($this->wantedPattern, htmlentities($this->wantedPattern));
+
+ $this->wantedPattern = "@It works but not well.@";
+ $this->assertWantedPattern($this->wantedPattern, htmlentities($this->wantedPattern));
+ }
+
+ function testVersion() {
+ $this->getAction("/addon/" . $this->id);
+ phpQuery::newDocument($this->_browser->getContent());
+
+ // Check the version detail area.
+ $version_link = pq('h5#version-detail a');
+ $version = $this->data['Version'][0]['Version']['version'];
+ $this->assertEqual($version_link->text(), sprintf(_('addon_display_header_version'), $version));
+ $link = sprintf('addons/versions/%s#version-%s', $this->id, $version);
+ $this->assertEqual($version_link->attr('href'), $this->controller->url($link));
+
+ $span = pq('h5#version-detail span');
+ $created = strtotime($this->data['Version'][0]['Version']['created']);
+ $this->assertEqual($span->attr('title'), strftime(_('datetime'), $created));
+ $this->assertEquiv($span->text(), '— '.strftime(_('date'), $created));
+
+ $notes = $this->data['Version'][0]['Translation']['releasenotes']['string'];
+ $this->assertEquiv(pq('#release-notes')->text(), $notes);
+
+ // check the version at the top title
+ $this->wantedPattern = "#" . $this->data['Version'][0]['Version']['version'] . "#";
+ $this->assertWantedPattern($this->wantedPattern, htmlentities($this->wantedPattern));
+
+ // check if previous versions link is displayed
+ $link = $this->controller->url('addons/versions/'.$this->id);
+ $text = ___('addons_display_see_all_versions');
+ $this->assertLinkLocation($link, $text);
+ }
+
+ function testIcon() {
+ $this->getAction("/addon/" . $this->id);
+ phpQuery::newDocument($this->_browser->getContent());
+
+ $img = pq('#addon-summary .name img.addon-icon');
+ $this->assertEqual($img->attr('src'), $this->controller->Image->getAddonIconURL($this->id));
+ }
+
+ function testPreviewsWithMoreImages() {
+ // Check the preview images for addon 7. It has 2 in total.
+ $this->getAction("/addon/" . $this->id);
+ phpQuery::newDocument($this->_browser->getContent());
+ $previews = $this->controller->Preview->findAllByAddonId($this->id,
+ array('id', 'addon_id', 'caption'),
+ 'highlight desc');
+
+ // Check the main preview image.
+ $this->checkImage($previews[0], '.preview-img a', '.preview-img img');
+
+ // Check the More Images section.
+ $this->assertEqual(pq('#addon-info h4:first')->text(), ___('addons_display_more_images'));
+ $this->checkImage($previews[1], '.addon-images li a', '.addon-images li a img');
+
+ //$this->getAction("/addon/" . $this->id);
+ }
+
+ function testPreviewsWithoutMoreImages() {
+ // Addon 9 only has one preview image.
+ $id = 9;
+ $this->getAction("/addon/" . $id);
+ phpQuery::newDocument($this->_browser->getContent());
+ $previews = $this->controller->Preview->findAllByAddonId($id,
+ array('id', 'addon_id', 'caption'),
+ 'highlight desc');
+ // Check the main preview image.
+ $this->checkImage($previews[0], '.preview-img a', '.preview-img img');
+ // No More Images section.
+ $this->assertNotEqual(pq('#addon-info h4:first')->text(), ___('addons_display_more_images'));
+ $this->assertEqual(pq('#addon-info .addon-images')->size(), 0);
+ }
+
+ function testPreviewsDefaultImage() {
+ // Addon 4022 only has no preview images.
+ $id = 4022;
+ $this->getAction("/addon/" . $id);
+ phpQuery::newDocument($this->_browser->getContent());
+ $this->assertEqual(pq('.preview-img img')->attr('src'), $this->controller->base.'/img/no-preview.png');
+ // No More Images section.
+ $this->assertNotEqual(pq('#addon-info h4:first')->text(), ___('addons_display_more_images'));
+ $this->assertEqual(pq('#addon-info .addon-images')->size(), 0);
+ }
+
+ function checkImage($preview, $link_selector, $image_selector) {
+ list($thumb, $full, $caption) = $this->_previewData($preview);
+ $link = pq($link_selector);
+ $image = pq($image_selector);
+ $this->assertEqual($link->attr('href'), $full);
+ $this->assertEqual($link->attr('title'), $caption);
+ $this->assertEqual($image->attr('src'), $thumb);
+ }
+
+ function _previewData($preview) {
+ $thumb = $this->controller->Image->getPreviewURL($preview['Preview']['id']);
+ $full = $this->controller->Image->getPreviewURL($preview['Preview']['id'], 'full');
+ $caption = $preview['Translation']['caption']['string'];
+ return array($thumb, $full, $caption);
+ }
+
+ /**
+ * bug 412580 was a bug about some UTF-8 characters breaking out HTML sanitization.
+ * Make sure this does not happen anymore.
+ */
+ function testSanitization() {
+ $this->wantedPattern = '@sanitization of signs like &amp; and &quot;@';
+ $this->assertWantedPattern($this->wantedPattern, htmlentities($this->wantedPattern));
+ }
+}
+?>
diff --git a/site/app/tests/views/addons/home.test.php b/site/app/tests/views/addons/home.test.php
new file mode 100644
index 0000000..351ce0e
--- /dev/null
+++ b/site/app/tests/views/addons/home.test.php
@@ -0,0 +1,111 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Andrei Hajdukewycz <sancus@off.net> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+class AddonHomeTest extends WebTestHelper {
+
+ function AddonHomeTest() {
+ $this->WebTestCase("Views->Addons->Home Tests");
+ }
+
+ function setUp() {
+
+ $this->getAction("");
+
+ global $TestController;
+ loadComponent('Image');
+ $this->Image =& new ImageComponent();
+ $this->Image->startup($TestController);
+ }
+
+ function testRemoraHome() {
+ //just checks if the page works or not
+ $this->assertWantedPattern('/Mozilla Add-ons/i', "pattern detected");
+ }
+
+ function testTitle() {
+ $this->title = sprintf(_('addons_home_pagetitle'), APP_PRETTYNAME);
+ $this->assertTitle($this->title);
+ }
+
+ function testAddons() {
+ $homepage = $this->_browser->getContent();
+ $homepage = explode("\n", $homepage);
+
+ $addon = 0;
+ foreach ($homepage as $line) {
+ if ($line = strstr($line, "/addon/")) {
+ $line = strip_tags($line);
+ sscanf($line, "/addon/%d\" >%s", $this->addonid[$addon], $this->addonName[$addon]);
+ $addon++;
+ break;//in 3.2 test only get the first one since now do have many featured addon (in 3.0 only 1)
+ }
+ }
+ $this->assertEqual($addon, 1);
+ }
+ function testLoadData() {
+ foreach ($this->addonid as $addon_id) {
+ if ($addon_id == $this->addonid[0]) {
+ $select_string = "Addon.id = $addon_id";
+ }
+ else
+ $select_string = $select_string . " OR Addon.id = $addon_id";
+ }
+ $this->model =& new Addon();
+ $this->model->caching = false;
+ $this->assertTrue($this->addon_data = $this->model->findAll($select_string, null, null, 3, null, 1));
+ }
+
+ function testAddonNames() {
+
+ foreach ($this->addon_data as $addon_data) {
+ $this->assertTrue(in_array($addon_data['Translation']['name']['string'], $this->addonName));
+ }
+ }
+ function testAuthors() {
+ foreach ($this->addon_data as $addon_data) {
+ $wantedPattern = "#>" . $addon_data['User'][0]['firstname'] ." ".$addon_data['User'][0]['lastname'] . "</a></h5>#";
+ $this->assertWantedPattern($wantedPattern, htmlentities($wantedPattern));
+ }
+ }
+
+ function xFailIcon() {
+ $wantedPattern = "#<img src=\"" . $this->Image->getAddonIconURL($this->addonid[0]) . "\" alt=\"" . $this->addon_data[0]['Addon']['name'] . "\" />#";
+ $this->assertWantedPattern($wantedPattern, htmlentities($wantedPattern));
+ }
+}
+?>
diff --git a/site/app/tests/views/addons/plugins.test.php b/site/app/tests/views/addons/plugins.test.php
new file mode 100644
index 0000000..67b4fcf
--- /dev/null
+++ b/site/app/tests/views/addons/plugins.test.php
@@ -0,0 +1,91 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Mike Morgan <morgamic@mozilla.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+class AddonPluginsTest extends WebTestHelper {
+
+ function AddonPluginsTest() {
+ $this->WebTestCase("Views->Addons->Plugins Tests");
+ }
+
+ function setUp() {
+ $this->getAction('/browse/type:'.ADDON_PLUGIN);
+
+ global $TestController;
+ $this->helper = new UnitTestHelper();
+ $this->controller = $this->helper->getController('Addons', $this);
+ $this->controller->base = $TestController->base;
+ }
+
+ function testRemoraPage() {
+ // just checks if the page works or not
+ $this->assertWantedPattern('/Mozilla Add-ons/i', "pattern detected");
+ }
+
+ function testPlugins() {
+ $this->title = _('addons_plugins_pagetitle') .' :: '. sprintf(_('addons_home_pagetitle'), APP_PRETTYNAME);
+ $this->assertTitle($this->title);
+
+ $pattern = '#<span>'.sprintf(_('addons_plugins_main_header'), APP_PRETTYNAME).'</span>#';
+ $this->assertPattern($pattern, htmlentities($pattern));
+
+ $pattern = '#<p class="first">'._('addons_plugins_main_description').'</p>#';
+ $this->assertPattern($pattern, htmlentities($pattern));
+
+ $pattern = '#<p class="first">'._('addons_plugins_by').'#';
+ $this->assertPattern($pattern, htmlentities($pattern));
+
+ $pattern = '#'._('addons_plugins_for_windows').'<br>#';
+ $this->assertPattern($pattern, htmlentities($pattern));
+
+ $pattern = '#'._('addons_plugins_for_linux').'<br>#';
+ $this->assertPattern($pattern, htmlentities($pattern));
+
+ $pattern = '#'._('addons_plugins_for_macosx').'<br>#';
+ $this->assertPattern($pattern, htmlentities($pattern));
+
+ $pattern = '#'._('addons_plugins_support_documentation').'#';
+ $this->assertPattern($pattern, htmlentities($pattern));
+
+ $pattern = '#<h2>'._('addons_plugins_looking_for_plugin').'#';
+ $this->assertPattern($pattern, htmlentities($pattern));
+
+ $pattern = '#<p class="first">'.sprintf(_('addons_plugins_looking_for_more'),'<a href="http://plugindoc.mozdev.org">PluginDoc</a>').'</p>#';
+ $this->assertPattern($pattern, htmlentities($pattern));
+ }
+}
+?>
diff --git a/site/app/tests/views/addons/policy.test.php b/site/app/tests/views/addons/policy.test.php
new file mode 100644
index 0000000..2996f39
--- /dev/null
+++ b/site/app/tests/views/addons/policy.test.php
@@ -0,0 +1,106 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Andrei Hajdukewycz <sancus@off.net> (Original Author)
+ *
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+class PolicyTest extends WebTestHelper {
+
+ function PolicyTest() {
+ $this->WebTestCase("Views->Addons->Privacy Policy/EULA Tests");
+ }
+
+ function setUp() {
+ $this->id = 7;//$_GET['id'];
+ $this->actionPath = $this->actionPath("");
+ $model =& new Addon();
+ $model->caching = false;
+ $this->data = $model->find("Addon.id=$this->id", null , null , 2);
+ }
+
+ function testPrivacyPolicy() {
+ //get display page and test policy link
+ $this->getAction("/addon/" . $this->id);
+
+ $this->wantedPattern = "@<a href=\"{$this->actionPath}/addons/policy/0/{$this->id}\" >This add-on has a privacy policy.</a>@";
+ $this->assertWantedPattern($this->wantedPattern, htmlentities($this->wantedPattern));
+
+ //get policy page and test page contents
+ $this->getAction("/addons/policy/0/" . $this->id);
+ $privacypolicy = nl2br($this->data['Translation']['privacypolicy']['string']);
+ $privacypolicy = substr($privacypolicy, -22);
+ $this->wantedPattern = "^{$privacypolicy}^";
+ $this->assertWantedPattern($this->wantedPattern, htmlentities($this->wantedPattern));
+
+ //add-on name
+ $this->wantedPattern = "@<h3 class=\"name\">[\s]*{$this->data['Translation']['name']['string']}[\s]*</h3>@";
+ $this->assertWantedPattern($this->wantedPattern, htmlentities($this->wantedPattern));
+
+ //author user data
+ foreach ($this->data['User'] as $user) {
+ $username = $user['nickname'];
+ $usertitle = _('addons_display_author_title');
+ $this->wantedPattern = "@<h4 class=\"author\"> by <a href=\"{$this->actionPath}/user/{$user['id']}\" class=\"profileLink\">{$username}</a></h4>@";
+ $this->assertWantedPattern($this->wantedPattern, htmlentities($this->wantedPattern));
+ }
+ }
+
+ function testEULA() {
+
+ //get EULA page
+ $this->getAction("/addons/policy/0/{$this->id}/{$this->data['Version'][0]['File'][0]['id']}");
+
+ //name and version
+ $this->wantedPattern = "@<h3 class=\"name\">[\s]*{$this->data['Translation']['name']['string']} *{$this->data['Version'][0]['version']}[\s]*</h3>@";
+ $this->assertWantedPattern($this->wantedPattern, htmlentities($this->wantedPattern));
+
+ //get policy page and test page contents
+ $eula = nl2br($this->data['Translation']['eula']['string']);
+ $eula = substr($eula, 0, 22);
+ $this->wantedPattern = "^{$eula}^";
+ $this->assertWantedPattern($this->wantedPattern, htmlentities($this->wantedPattern));
+
+ //author user data @TODO: Fix multiple author stuff when we add that
+ foreach ($this->data['User'] as $user) {
+ $username = $user['nickname'];
+ $usertitle = _('addons_display_author_title');
+ $this->wantedPattern = "@<h4 class=\"author\"> by <a href=\"{$this->actionPath}/user/{$user['id']}\" class=\"profileLink\">{$username}</a></h4>@";
+ $this->assertWantedPattern($this->wantedPattern, htmlentities($this->wantedPattern));
+ }
+
+ }
+}
+?>
diff --git a/site/app/tests/views/addons/previews.test.php b/site/app/tests/views/addons/previews.test.php
new file mode 100644
index 0000000..6fa4ace
--- /dev/null
+++ b/site/app/tests/views/addons/previews.test.php
@@ -0,0 +1,83 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Frederic Wenzel <fwenzel@mozilla.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+class AddonPreviewsTest extends WebTestHelper {
+ var $addonid = 7;
+
+ function AddonPreviewsTest() {
+ $this->WebTestCase("Views->Addons->Preview Images Tests");
+ }
+
+ function setUp() {
+ $this->getAction("/addons/previews/{$this->addonid}");
+
+ global $TestController;
+ $this->helper = new UnitTestHelper();
+ $this->controller = $this->helper->getController('Addons', $this);
+ $this->controller->base = $TestController->base;
+ }
+
+ function testRemoraPage() {
+ // just checks if the page works or not
+ $this->assertWantedPattern('/Mozilla Add-ons/i', "pattern detected");
+ }
+
+ function testPreviews() {
+ $addon = $this->controller->Addon->findById($this->addonid);
+
+ // Title
+ $this->title = sprintf(_('addons_previews_pagetitle'), $addon['Translation']['name']['string']) .' :: '. sprintf(_('addons_home_pagetitle'), APP_PRETTYNAME);
+ $this->assertTitle($this->title);
+
+ // Header
+ $pattern = '#'.sprintf(_('addons_previews_pagetitle'), $addon['Translation']['name']['string']).'#';
+ $this->assertPattern($pattern, htmlentities($pattern));
+
+ // preview pic
+ $pattern = '#<a href="[^"]*/images/preview/'.$this->addonid.'/1" '
+ .'rel="lightbox\[previews\]" '
+ .'title="[^"]*">'
+ .'<img src="[^"]*/images/addon_preview/'.$this->addonid.'/1"'
+ .' alt="" ></a>#';
+ $this->assertPattern($pattern, htmlentities($pattern));
+
+ // link back
+ $this->assertLink(sprintf(_('addon_review_a_back_to_addon_x'), $addon['Translation']['name']['string']), 'link back to addon page');
+ }
+}
+?>
diff --git a/site/app/tests/views/addons/rss/parserss.test.php b/site/app/tests/views/addons/rss/parserss.test.php
new file mode 100644
index 0000000..21d36b7
--- /dev/null
+++ b/site/app/tests/views/addons/rss/parserss.test.php
@@ -0,0 +1,77 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla Corporation
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Frederic Wenzel <fwenzel@mozilla.com> (Original Developer)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+class ParseRSSTest extends WebTestHelper {
+ var $feeds = array();
+
+ function ParseRSSTest() {
+ $this->WebTestCase("Views->Search->RSS Parsing Tests");
+ $this->feeds = array(
+ '/addons/rss/newest', // @todo needs a page and a uniform feed URL
+ '/recommended/format:rss',
+ '/browse/type:'.ADDON_EXTENSION.'/format:rss',
+ '/browse/type:'.ADDON_THEME.'/format:rss',
+ '/browse/type:'.ADDON_SEARCH.'/format:rss',
+ '/browse/type:'.ADDON_EXTENSION.'/cat:12/format:rss',
+ '/browse/type:'.ADDON_EXTENSION.'/cat:all/format:rss',
+ '/browse/type:'.ADDON_EXTENSION.'/cat:all/sort:name/format:rss',
+ '/browse/type:'.ADDON_EXTENSION.'/cat:all/sort:popular/format:rss',
+ '/browse/type:'.ADDON_EXTENSION.'/cat:all/sort:updated/format:rss',
+ '/browse/type:'.ADDON_EXTENSION.'/cat:all/sort:rated/format:rss',
+ '/browse/type:'.ADDON_EXTENSION.'/cat:all/sort:newest/format:rss',
+ '/addons/versions/7/format:rss',
+ '/reviews/display/7/format:rss',
+ );
+ }
+
+ function setUp() {
+ }
+
+ function testRSSParsing() {
+ // do a simple parse test for all feeds listed above.
+ foreach ($this->feeds as $feed) {
+ $this->getAction($feed);
+ $this->assertWantedPattern("/rss version/", "correct template for ".htmlspecialchars($feed));
+ $this->assertWantedPattern("/<item>/", "some results were found");
+ $this->assertTrue($this->checkXML(), 'XML validation');
+ $this->restart();
+ }
+ }
+}
+
+?>
diff --git a/site/app/tests/views/addons/searchengines.test.php b/site/app/tests/views/addons/searchengines.test.php
new file mode 100644
index 0000000..23e6cff
--- /dev/null
+++ b/site/app/tests/views/addons/searchengines.test.php
@@ -0,0 +1,93 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Frederic Wenzel <fwenzel@mozilla.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+class AddonSearchenginesTest extends WebTestHelper {
+
+ function AddonSearchenginesTest() {
+ $this->WebTestCase("Views->Addons->Searchengines Tests");
+ }
+
+ function setUp() {
+ $this->getAction("/browse/type:".ADDON_SEARCH);
+
+ global $TestController;
+ $this->helper = new UnitTestHelper();
+ $this->controller = $this->helper->getController('Addons', $this);
+ $this->controller->base = $TestController->base;
+ }
+
+ function testRemoraPage() {
+ // just checks if the page works or not
+ $this->assertWantedPattern('/Mozilla Add-ons/i', "pattern detected");
+ }
+
+ function testSearchengines() {
+ // Title
+ $this->title = _('addons_searchengines_pagetitle') .' :: '. sprintf(_('addons_home_pagetitle'), APP_PRETTYNAME);
+ $this->assertTitle($this->title);
+
+ /* // addSearchEngine + correct URLs
+ $pattern = '#window.sidebar.addSearchEngine\([\s]*'
+ .'"'.FULL_BASE_URL.$this->controller->base.'/'.LANG.'/'.APP_SHORTNAME.'/'.FILES_URL.'/'.'"\+fileid\+"/"\+basename\+".src",[\s]*'
+ .'"'.FULL_BASE_URL.$this->controller->base.'/'.LANG.'/'.APP_SHORTNAME.'/images/addon_icon/"\+addonid\+"/"\+basename\+"."\+ext,[\s]*'
+ .'name,[\s]*cat[\s]*\);'
+ .'#m';
+ $this->assertPattern($pattern, htmlentities($pattern)); javascript no longer in source cpollett*/
+
+ /* // two headers
+ $pattern = '#<span>'._('addons_searchengines_title').'</span>#';
+ $this->assertPattern($pattern, htmlentities($pattern));
+ $pattern = '#<h1>'._('addons_searchengines_additional_resources').'</h1>#';
+ $this->assertPattern($pattern, htmlentities($pattern));
+
+ // search engine link
+ $this->assertLink('IMDB', 'IMDB search plugin link');
+
+ // onclick attribute
+ $pattern = '#onclick="addEngine\([^\)]+\); return false;"#';
+ $this->assertPattern($pattern, htmlentities($pattern));
+
+ // additional resources links
+ $pattern = '#<a.*href="http://developer.mozilla.org/.*" >.+</a>#';
+ $this->assertPattern($pattern, htmlentities($pattern));
+ $pattern = '#<a.*href="http://mycroft.mozdev.org/" >.+</a>#';
+ $this->assertPattern($pattern, htmlentities($pattern)); --these checks no longer exist current page cpollett*/
+
+ }
+}
+?>
diff --git a/site/app/tests/views/addons/versions.test.php b/site/app/tests/views/addons/versions.test.php
new file mode 100644
index 0000000..dedff88
--- /dev/null
+++ b/site/app/tests/views/addons/versions.test.php
@@ -0,0 +1,125 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Frederic Wenzel <fwenzel@mozilla.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+class AddonVersionsTest extends WebTestHelper {
+ var $addonid = null;
+
+ function AddonVersionsTest() {
+ $this->WebTestCase("Views->Addons->Previous Versions Tests");
+ }
+
+ function setUp() {
+ $this->getAction("/addons/versions/{$this->addonid}");
+
+ global $TestController;
+ $this->helper = new UnitTestHelper();
+ $this->controller = $this->helper->getController('Addons', $this);
+ $this->controller->base = $TestController->base;
+
+ // disable query caching so devcp changes are visible immediately
+ foreach ($this->controller->uses as $_model) {
+ $this->controller->$_model->caching = false;
+ }
+
+ }
+}
+
+/**
+ * Tests for a regular, enabled add-on's previous versions page
+ */
+class AddonEnabledVersionsTest extends AddonVersionsTest {
+ var $addonid = 7;
+
+ function testRemoraPage() {
+ // just checks if the page works or not
+ $this->assertWantedPattern('/Mozilla Add-ons/i', "pattern detected");
+ }
+
+ function testRssLink() {
+ // RSS feed linked in header?
+ $pattern = '#<link rel="alternate" type="application/rss\+xml" title="[^"]*" href="[\w\d-_/]*/addons/versions/[\d]+/format:rss">#';
+ $this->assertPattern($pattern, htmlentities($pattern));
+ }
+
+ function testPreviews() {
+ $addon = $this->controller->Addon->findById($this->addonid);
+
+ // "Careful" warning
+ $pattern = '#<h3>'._('addons_versions_careful').'</h3>#';
+ $this->assertPattern($pattern, htmlentities($pattern));
+ $pattern = '#<p>'._('addons_versions_careful_introduction').'</p>#';
+ $this->assertPattern($pattern, htmlentities($pattern));
+
+ // Version strings for all versions
+ foreach ($addon['Version'] as $version) {
+ $pattern = "@<h3>Version " . $version['version'] . ' <span title="' . strftime(_('datetime'), strtotime($version['created'])) . '">&mdash; ' . strftime(_('date'), strtotime($version['created'])) . "</span> &mdash; .*</h3>@";
+ $this->assertPattern($pattern, htmlentities($pattern));
+ }
+
+ // link back
+ $this->assertLink(sprintf(_('addon_review_a_back_to_addon_x'), $addon['Translation']['name']['string']), 'link back to addon page');
+ }
+
+ /**
+ * Test if "version-1.0"-style anchor IDs are present so people can
+ * use it as a permalink to a specific version.
+ */
+ function testPermaLinkAnchors() {
+ $addon = $this->controller->Addon->findById($this->addonid);
+
+ foreach($addon['Version'] as $version) {
+ $pattern = '#<div +[^>]*id="version-'.$version['version'].'"[^>]*>#';
+ $this->assertPattern($pattern, htmlentities($pattern));
+ }
+ }
+}
+
+/**
+ * Tests for a disabled add-on's versions page
+ */
+class AddonDisabledVersionsTest extends AddonVersionsTest {
+ var $addonid = 3716;
+
+ /**
+ * Test if version page is _not_ shown for disabled add-ons
+ */
+ function testDisabledAddonVersionsPage() {
+ $this->assertText(___('error_addon_notfound'), "disabled add-on's versions page");
+ }
+}
+?>
diff --git a/site/app/tests/views/admin/addons_status.test.php b/site/app/tests/views/admin/addons_status.test.php
new file mode 100644
index 0000000..a85d26d
--- /dev/null
+++ b/site/app/tests/views/admin/addons_status.test.php
@@ -0,0 +1,27 @@
+<?php
+
+class AdminAddonsStatusTest extends WebTestHelper {
+
+ function AdminConfigTest() {
+ $this->WebTestCase('Views->Admin->Addons Status Test');
+ }
+
+ function setUp() {
+ $this->login();
+ $this->getAction('/admin/addons?q=[7]');
+ }
+
+ function testRemoraPage() {
+ $this->assertWantedPattern('/Mozilla Add-ons/i', 'pattern detected');
+ $this->assertResponse('200');
+ }
+
+ /**
+ * There should be links for each version of the addon.
+ */
+ function testVersionLinks() {
+ $this->assertLinkLocation('/editors/review/9', '9');
+ $this->assertLinkLocation('/editors/review/1', '1');
+ }
+}
+?>
diff --git a/site/app/tests/views/admin/serverstatus.test.php b/site/app/tests/views/admin/serverstatus.test.php
new file mode 100644
index 0000000..b54d86d
--- /dev/null
+++ b/site/app/tests/views/admin/serverstatus.test.php
@@ -0,0 +1,98 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Mike Morgan <morgamic@mozilla.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+class AdminServerStatusTest extends WebTestHelper {
+
+ function AdminServerStatusTest() {
+ $this->WebTestCase("Views->Admin->Server Status Test");
+
+ loadModel('Memcaching');
+ }
+
+ function setUp() {
+ $this->cache =& new Memcaching();
+
+ $this->login();
+ $this->getAction('/admin/serverstatus/');
+ }
+
+ function testRemoraPage() {
+ $this->assertWantedPattern('/Mozilla Add-ons/i', "pattern detected");
+ $this->assertResponse('200');
+ }
+
+ function testMemcacheStatus() {
+ if (defined('QUERY_CACHE') && QUERY_CACHE) {
+
+ if ($_data = $this->cache->getExtendedStats()) {
+
+ foreach ($_data as $server=>$stats) {
+ $pattern = '#<h3>'.$server.'</h3>#';
+ $this->assertWantedPattern($pattern, htmlentities($pattern));
+
+ if (!empty($stats) && is_array($stats)) {
+ $pattern = '#<li>Gets: [0-9]+</li>#';
+ $this->assertWantedPattern($pattern, htmlentities($pattern));
+
+ $pattern = '#<li>Misses: [0-9]+</li>#';
+ $this->assertWantedPattern($pattern, htmlentities($pattern));
+
+ $pattern = '#<li>Total Gets: [0-9]+</li>#';
+ $this->assertWantedPattern($pattern, htmlentities($pattern));
+
+ $pattern = '#<li>Hit %: [0-9]+.[0-9]+</li>#';
+ $this->assertWantedPattern($pattern, htmlentities($pattern));
+
+ $pattern = '#<li>Quota %: [0-9]+.[0-9]+</li>#';
+ $this->assertWantedPattern($pattern, htmlentities($pattern));
+
+ foreach ($stats as $key=>$val) {
+ $pattern = "/{$key}: [0-9]+/";
+ $this->assertWantedPattern($pattern, htmlentities($pattern));
+ }
+ }
+ }
+ }
+ } else {
+ $pattern = '#<p>Memcache is not enabled \(QUERY_CACHE is false\)\.</p>#';
+ $this->assertWantedPattern($pattern, htmlentities($pattern));
+ }
+ }
+
+}
+?>
diff --git a/site/app/tests/views/developers/add.test.php b/site/app/tests/views/developers/add.test.php
new file mode 100644
index 0000000..504b14f
--- /dev/null
+++ b/site/app/tests/views/developers/add.test.php
@@ -0,0 +1,62 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * Justin Scott <fligtar@gmail.com>.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+class DevelopersAddTest extends WebTestHelper {
+
+ function setUp() {
+ //Developer pages require login
+ $this->login();
+
+ $this->getAction('/developers/add/');
+
+ global $TestController;
+ }
+
+ function testRemoraPage() {
+ //just checks if the page works or not
+ $this->assertWantedPattern('/Submit/i', 'Header detected');
+ }
+
+ function testDisplay() {
+ // Title
+ //$this->assertTitle('Edit Add-on');
+
+ //Check fields
+
+ }
+}
+?>
diff --git a/site/app/tests/views/developers/edit.test.php b/site/app/tests/views/developers/edit.test.php
new file mode 100644
index 0000000..bded1f3
--- /dev/null
+++ b/site/app/tests/views/developers/edit.test.php
@@ -0,0 +1,94 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * Justin Scott <fligtar@gmail.com>.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Frederic Wenzel <fwenzel@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+class DevelopersEditTest extends WebTestHelper {
+ var $id;
+ var $model;
+ var $data;
+ var $de_data;
+
+ function setUp() {
+ //Developer pages require login
+ $this->login();
+
+ $this->id = 7;
+ loadModel('Addon');
+ $this->model =& new Addon();
+ $this->model->id = $this->id;
+ // fetch English and German data
+ $this->model->useLang = 'en-US';
+ $this->data = $this->model->find("Addon.id=$this->id", null , null , 2);
+ unset($this->data['Translation']['developercomments']);
+
+ $this->model->useLang = 'de';
+ $this->de_data = $this->model->find("Addon.id=$this->id", null , null , 2);
+ unset($this->de_data['Translation']['developercomments']);
+
+ $this->getAction("/developers/edit/" . $this->id);
+
+ global $TestController;
+ }
+
+ function testRemoraPage() {
+ //just checks if the page works or not
+ $this->assertWantedPattern('/Edit/i', 'Header detected');
+ }
+
+ function testDisplay() {
+ // Title
+ $this->assertTitle('Developer Tools :: Firefox Add-ons');
+
+ //Check fields
+ $this->assertWantedPattern('/\<option value="12" +selected="selected"\>Organizer\<\/option\>/', 'Tag selected');
+
+ $this->assertText($this->data['User'][0]['firstname'].' '.$this->data['User'][0]['lastname'].' ['.$this->data['User'][0]['email'].']', 'Author populated');
+
+ //Localized fields
+ foreach ($this->data['Translation'] as $field => $translation) {
+ $fieldName = ucwords(strtolower($field));
+ $this->assertFieldById('Addon'.$fieldName.'_en_US', strval($translation['string']), $fieldName.' field (en-US) populated: %s');
+ if ($this->de_data['Translation'][$field]['locale'] == 'de') {
+ $this->assertFieldById('Addon'.$fieldName.'_de', $this->de_data['Translation'][$field]['string'], $fieldName.' field (de) populated: %s');
+ }
+ }
+
+
+
+ }
+}
+?>
diff --git a/site/app/tests/views/developers/editversion.test.php b/site/app/tests/views/developers/editversion.test.php
new file mode 100644
index 0000000..1654b2e
--- /dev/null
+++ b/site/app/tests/views/developers/editversion.test.php
@@ -0,0 +1,84 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * Justin Scott <fligtar@gmail.com>.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+class DevelopersEditVersionTest extends WebTestHelper {
+ var $id;
+ var $model;
+
+ function setUp() {
+ //Developer pages require login
+ $this->login();
+
+ $this->id = 1;
+ $this->model =& new Version();
+ $this->model->caching = false; // Make sure caching is off.
+ $this->model->id = $this->id;
+ $this->getAction('/developers/editversion/' . $this->id);
+ }
+
+ function testRemoraPage() {
+ //just checks if the page works or not
+ $this->assertWantedPattern('/Edit/i', 'Header detected');
+ }
+
+ function testDisplay() {
+ // Title
+ $this->assertTitle('Developer Tools :: Firefox Add-ons', 'Title populated: %s');
+
+ //Check fields
+ $this->model->useLang = 'en-US';
+ $this->data = $this->model->find("Version.id={$this->id}", null , null , 2);
+ $this->assertFieldByName('data[Version][releasenotes][en-US]', htmlentities($this->data['Translation']['releasenotes']['string']),
+ 'Version Notes (en-US) field populated: %s');
+
+ $this->model->useLang = 'de';
+ $this->data = $this->model->find("Version.id={$this->id}", null , null , 2);
+ $this->assertFieldByName('data[Version][releasenotes][de]', htmlentities($this->data['Translation']['releasenotes']['string']),
+ 'Version Notes (de) field populated: %s');
+
+ $this->assertField('data[Version][approvalnotes]', $this->data['Version']['approvalnotes'], 'Version Approval Notes field populated: %s');
+
+ $this->assertText($this->data['File'][0]['size'].' KB', 'File size listing detected');
+
+ phpQuery::newDocument($this->_browser->getContent());
+ $platform = pq('#files-table option:first');
+ $this->assertAttrs($platform, array('value' => 1, 'selected' => 'selected'),
+ 'ALL platform is selected: %s');
+ $this->assertEqual($platform->text(), 'ALL', 'ALL platform is selected: %s');
+ }
+}
+?>
diff --git a/site/app/tests/views/developers/index.test.php b/site/app/tests/views/developers/index.test.php
new file mode 100644
index 0000000..784947f
--- /dev/null
+++ b/site/app/tests/views/developers/index.test.php
@@ -0,0 +1,69 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * Justin Scott <fligtar@gmail.com>.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+class DevelopersIndexTest extends WebTestHelper {
+
+ function setUp() {
+ //Developer pages require login
+ $this->login();
+
+ $this->getAction("/developers/index/");
+
+ global $TestController;
+ }
+
+ function testRemoraPage() {
+ //just checks if the page works or not
+ $this->assertWantedPattern('/My Add-ons/i', 'Header detected');
+ }
+
+ function testDisplay() {
+ // Title
+ //$this->assertTitle('Edit Add-on');
+
+ //Check fields
+ //$this->assertLink('Version 1.02a', 'Version link found: %s');
+
+ }
+
+ /* function testPreviews() {
+ $this->assertLink("Add Preview", "link to add preview");
+ $pattern = '|editpreview/7/1"[^>]*><img src="' . $this->actionPath("/images/addon_preview/7/1") . '">|';
+ $this->assertPattern($pattern, "show preview image inline with link to edit");
+ }*/
+}
+?>
diff --git a/site/app/tests/views/elements/install.test.php b/site/app/tests/views/elements/install.test.php
new file mode 100644
index 0000000..c4d10ff
--- /dev/null
+++ b/site/app/tests/views/elements/install.test.php
@@ -0,0 +1,91 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Andrei Hajdukewycz <sancus@off.net> (Original Author)
+ *
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+class InstallTest extends WebTestHelper {
+
+ function InstallTest() {
+ $this->WebTestCase("Views->Elements->Install Element Tests");
+ }
+
+ function setUp() {
+ $this->id = 7;
+ $this->actionPath = $this->actionPath("");
+ loadModel('Addon');
+ $model =& new Addon();
+ $model->caching = false;
+ $this->data = $model->find("Addon.id=$this->id", null , null , 2);
+ }
+
+ function testDisplayInstall() {
+ //get display page and test eula link
+ $this->getAction("/addon/" . $this->id);
+ $installMessage = sprintf(_('a_install'), "", "");
+ if (!empty($this->data['Translation']['eula']['string'])) {
+ // install link
+ $this->wantedPattern = "@<p class=\"install-button platform-ALL\">\s*<a href=\"{$this->actionPath}/@";
+ /* suspect action not quite right for this test to work as originally was below:
+ /downloads/file/{$this->id}/[^\"]+\" +id=\"installTrigger\d+\" +addonName=\"[^\"]+\"[^>]*><span><span><span><strong>Accept and Install</strong></span></span></span></a></p>*/
+ $this->assertWantedPattern($this->wantedPattern, htmlentities($this->wantedPattern));
+ // anti-xss platform link script
+ $this->wantedPattern = "@<script type=\"text/javascript\">setTimeout\(function\(\) {fixPlatformLinks\('\d+', document.getElementById\('installTrigger\d+'\).getAttribute\('addonName'\)\);addCompatibilityHints\([^)]+\);},0\);</script>@";
+ $this->assertWantedPattern($this->wantedPattern, htmlentities($this->wantedPattern));
+ }
+
+ // test remaining things on the policy page
+ $this->getAction("/addons/policy/0/{$this->id}/{$this->data['Version'][0]['File'][0]['id']}");
+ $installMessage = _('a_eula_install');
+
+ //test filenames matches with database
+ $this->wantedPattern = "@<a href=\"{$this->actionPath}/downloads/latest/{$this->id}/addon-{$this->id}-latest.xpi\"@";
+ $this->assertWantedPattern($this->wantedPattern, "install url matches: ".htmlentities($this->wantedPattern));
+
+ //test add-on name matches in install trigger
+ $this->wantedPattern = "@addonName=\"{$this->data['Translation']['name']['string']}\"@";
+ $this->assertWantedPattern($this->wantedPattern, "Add-on name matches: {$this->data['Translation']['name']['string']}");
+
+ //test add-on icon link for install trigger
+ $this->wantedPattern = "@addonIcon=\"{$this->actionPath}/images/addon_icon/{$this->id}/\d{10}\"@";
+ $this->assertWantedPattern($this->wantedPattern, htmlentities($this->wantedPattern));
+
+ //test add-on hash matches with db @TODO: Download file and verify hash
+ $this->wantedPattern = "@addonHash=\"{$this->data['Version'][0]['File'][0]['hash']}\"@";
+ $this->assertWantedPattern($this->wantedPattern, "Addon Hash Match: {$this->data['Version'][0]['File'][0]['hash']}");
+ }
+}
+?>
diff --git a/site/app/tests/views/helpers/addons_html.test.php b/site/app/tests/views/helpers/addons_html.test.php
new file mode 100644
index 0000000..a6fa122
--- /dev/null
+++ b/site/app/tests/views/helpers/addons_html.test.php
@@ -0,0 +1,118 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * Frederic Wenzel <fwenzel@mozilla.com>
+ *
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+class AddonsHtmlHelperTest extends UnitTestCase {
+
+ var $html = null; // the helper
+
+ function setUp() {
+
+
+ static $tags;
+ loadHelper('AddonsHtml');
+ loadModel('Addon');
+ $this->Addon = new Addon();
+ $this->html =& new AddonsHtmlHelper();
+ $this->html->webroot = '';
+ $this->html->here = '';
+ $this->html->base = 'http://example.com/mybase';
+ $this->html->plugin = '';
+ $this->html->params = array('controller' => 'controller');
+ if (empty($tags)) $tags = $this->html->loadConfig();
+ $this->html->tags = $tags;
+ }
+
+ function tearDown() {
+ unset($this->html);
+ }
+
+ /**
+ * is link generated with locale?
+ */
+ function testLinkLocale() {
+ $expected = '!<a href="http://example.com/mybase/'.LANG.'/'.APP_SHORTNAME.'/browse"( )*>foo</a>!';
+ $result = $this->html->link('foo', '/browse');
+ $this->assertTrue(preg_match($expected, $result), 'link generation with locale');
+ }
+
+ /**
+ * is link generated without locale?
+ */
+ function testLinkNoLocale() {
+ $expected = '!<a href="http://example.com/mybase/'.APP_SHORTNAME.'/browse"( )*>foo</a>!';
+ $result = $this->html->linkNoLocale('foo', '/browse');
+ $this->assertTrue(preg_match($expected, $result), 'link generation without locale');
+ }
+
+ /**
+ * is link generated without locale and app?
+ */
+ function testLinkNoLocaleNoApp() {
+ $expected = '!<a href="http://example.com/mybase/browse"( )*>foo</a>!';
+ $result = $this->html->linkNoLocaleNoApp('foo', '/browse');
+ $this->assertTrue(preg_match($expected, $result), 'link generation without locale or app');
+ }
+
+ /**
+ * sanitized strings can be reverted
+ */
+ function testUnsanitize() {
+ $test = '&lt;a href=&quot;addons.mozilla.org&quot;&gt;Mozilla&#039;s addon website &#40;AMO&#41;&lt;/a&gt;. &#43;/&#45;3.1&#37;. &amp;amp;';
+ $expected = '<a href="addons.mozilla.org">Mozilla\'s addon website (AMO)</a>. +/-3.1%. &amp;';
+ $result = $this->html->unsanitize($test);
+ $this->assertEqual($expected, $result, 'sanitized strings can be reverted');
+ }
+
+ function testTruncate() {
+ $this->assertEqual('abc', $this->html->truncateChars(5, 'abc'));
+ $this->assertEqual('abcde', $this->html->truncateChars(5, 'abcde'));
+ $this->assertEqual('ab...', $this->html->truncateChars(5, 'abcdef'));
+ }
+
+ /**
+ * Tests that an addon that has the addons_tags.feature = 1 is shown as featured
+ */
+ function testRecommendedFlag() {
+ $addon = $this->Addon->getListAddons(4021, array(STATUS_PUBLIC), '', true);
+ $addon = $addon[0];
+ $result = $this->html->flag($addon);
+ phpQuery::newDocument($result);
+ $this->assertEqual(pq('h5.flag a')->text(), 'recommended', 'Category recommended and recommended addons are flagged as recommended');
+ }
+}
+?>
diff --git a/site/app/tests/views/helpers/localization.test.php b/site/app/tests/views/helpers/localization.test.php
new file mode 100644
index 0000000..1ccb4a1
--- /dev/null
+++ b/site/app/tests/views/helpers/localization.test.php
@@ -0,0 +1,53 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * Wil Clouser <clouserw@mozilla.com>
+ *
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+class LocalizationHelperTest extends UnitTestCase {
+
+
+ function setUp() {
+
+ loadHelper('Localization');
+
+ }
+
+ function testJsLocalization() {
+
+ }
+
+}
+?>
diff --git a/site/app/tests/views/helpers/statistics.test.php b/site/app/tests/views/helpers/statistics.test.php
new file mode 100644
index 0000000..11753f8
--- /dev/null
+++ b/site/app/tests/views/helpers/statistics.test.php
@@ -0,0 +1,66 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * Jeff Balogh <jbalogh@mozilla.com>
+ *
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+class StatisticsHelperTest extends UnitTestCase {
+
+ function setUp() {
+ loadHelper('Statistics');
+ $this->statistics =& new StatisticsHelper();
+ }
+
+ function _span($color, $number) {
+ return "<span style='color: {$color}'>".$number."</span>";
+ }
+
+ function test_colored_percentage() {
+ $key = 'num';
+ $a[$key] = 1.233;
+ $this->assertEqual($this->statistics->colored_percentage($a, $key),
+ $this->_span('green', '+1.23%'));
+ $a[$key] = -1.233;
+ $this->assertEqual($this->statistics->colored_percentage($a, $key),
+ $this->_span('red', '-1.23%'));
+ $a[$key] = 0;
+ $this->assertEqual($this->statistics->colored_percentage($a, $key),
+ '0');
+
+ $this->assertEqual($this->statistics->colored_percentage($a, 'invalid'),
+ '0');
+ }
+}
+?>
diff --git a/site/app/tests/views/images/show.test.php b/site/app/tests/views/images/show.test.php
new file mode 100644
index 0000000..ba41ac7
--- /dev/null
+++ b/site/app/tests/views/images/show.test.php
@@ -0,0 +1,116 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Wil Clouser <wclouser@mozilla.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+class ImageViewTest extends WebTestHelper {
+
+
+ function ImageTest() {
+ $this->WebTestCase("Views->Image->Show Tests");
+ }
+
+ function imageVerify($url, $mimetype) {
+ $this->get($url);
+ $this->assertResponse('200');
+ $imageinfo = getimagesize($url);
+ $imagetype = image_type_to_mime_type($imageinfo[2]);
+ $this->assertMime($mimetype);
+ }
+ function testAddonIconValid() {
+ $model =& new Addon();
+ $model->caching = false;
+ $id=7;//$_GET['id'];
+
+ $data = $model->find("Addon.id=$id", array('icontype'), null , 2);
+ $mimetype = $data['Addon']['icontype'];
+ $url = $this->actionURI("/images/addon_icon/" . $id);
+
+ $this->imageVerify($url, $mimetype);
+ }
+ function testPreviewValid() {
+ $model =& new Addon();
+ $model->bindFully();
+ $model->caching = false;
+ $id=7;//$_GET['id'];
+
+ $data = $model->find("Addon.id=$id", null , null , 2);
+ $mimetype = $data['Preview'][0]['thumbtype'];
+ $url = $this->actionURI("/images/addon_preview/$id/1");
+
+ $this->imageVerify($url, $mimetype);
+ }
+
+ function xfail_testPreviewLargeValid() {
+ $model =& new Addon();
+ $model->bindFully();
+ $model->caching = false;
+ $id=7;//$_GET['id'];
+
+ $data = $model->find("Addon.id=$id", null , null , 2);
+ $filename = $data['Preview'][0]['filename'];
+ $mimetype = $data['Preview'][0]['filetype'];
+ $url = $this->actionURI("/images/preview/" . $filename);
+
+ $this->imageVerify($filename, $url, $mimetype);
+ }
+ function xfail_testApplicationIconValid() {
+ $model =& new Application();
+ $model->caching = false;
+ $id=7;//$_GET['id'];
+
+ $data = $model->find("Application.id=$id", null , null , 2);
+ $filename = $data['Application']['icon'];
+ $mimetype = $data['Application']['icontype'];
+ $url = $this->actionURI("/images/application_icon/" . $filename);
+
+ $this->imageVerify($filename, $url, $mimetype);
+ }
+ function xfail_testPlatformIconValid() {
+ $model =& new Platform();
+ $model->caching = false;
+ $id=7;//$_GET['id'];
+
+ $data = $model->find("Platform.id=$id", null , null , 2);
+ $filename = $data['Platform']['icon'];
+ $mimetype = $data['Platform']['icontype'];
+ $url = $this->actionURI("/images/platform_icon/" . $filename);
+
+ $this->imageVerify($filename, $url, $mimetype);
+ }
+
+}
+?>
diff --git a/site/app/tests/views/reviews/add.test.php b/site/app/tests/views/reviews/add.test.php
new file mode 100644
index 0000000..86ccaba
--- /dev/null
+++ b/site/app/tests/views/reviews/add.test.php
@@ -0,0 +1,75 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Frederic Wenzel <fwenzel@mozilla.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+class ReviewsAddTest extends WebTestHelper {
+
+ function ReviewsAddTest() {
+ $this->WebTestCase("Views->Reviews->Add Reviews Test");
+ }
+
+ function setUp() {
+ $this->login(); // logged in users only
+
+ $this->id = 7;
+ $model =& new Addon();
+ $model->id = $this->id;
+ $this->data = $model->find("Addon.id=$this->id", null , null , 2);
+ $this->getAction("/reviews/add/" . $this->id);
+ }
+
+ function testRemoraPage() {
+ //just checks if the page works or not
+ $this->assertWantedPattern('/Mozilla Add-ons/i', "pattern detected");
+ }
+
+ function testReviews() {
+ // Title
+ $this->title = sprintf(_('addon_review_pagetitle'), $this->data['Translation']['name']['string']).' :: '.sprintf(_('addons_home_pagetitle'), APP_PRETTYNAME);
+ $this->assertTitle($this->title);
+
+ // add review form
+ $myPattern = '#<form action="[^"]+reviews/add/'.$this->id.'[^"]*" method="post" [^>]+>#';
+ $this->assertWantedPattern($myPattern, htmlentities($myPattern));
+
+ // submit button
+ $myPattern = '#<input type="submit" class="amo-submit" value="'._('addon_review_add_submit').'" >#';
+ $this->assertWantedPattern($myPattern, htmlentities($myPattern));
+ }
+
+}
+?>
diff --git a/site/app/tests/views/reviews/display.test.php b/site/app/tests/views/reviews/display.test.php
new file mode 100644
index 0000000..60f6190
--- /dev/null
+++ b/site/app/tests/views/reviews/display.test.php
@@ -0,0 +1,75 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Frederic Wenzel <fwenzel@mozilla.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+class AddonReviewsTest extends WebTestHelper {
+
+ function AddonReviewsTest() {
+ $this->WebTestCase("Views->Addons->Reviews Test");
+ }
+
+ function setUp() {
+ $this->id = 7;
+ $model =& new Addon();
+ $model->id = $this->id;
+ $this->data = $model->find("Addon.id=$this->id", null , null , 2);
+ $this->getAction("/reviews/display/" . $this->id);
+ }
+
+ function testRemoraPage() {
+ //just checks if the page works or not
+ $this->assertWantedPattern('/Mozilla Add-ons/i', "pattern detected");
+ }
+
+ function testReviews() {
+ // Title
+ $this->title = sprintf(_('addon_review_pagetitle'), $this->data['Translation']['name']['string']).' :: '.sprintf(_('addons_home_pagetitle'), APP_PRETTYNAME);
+ $this->assertTitle($this->title);
+
+ // Header
+ $myPattern = '#<h1>Reviews for MicroFarmer</h1>#';
+ $this->assertWantedPattern($myPattern, htmlentities($myPattern));
+
+ // single review
+ $myPattern = '#<h3>Fine, just fine.</h3>#';
+ $this->assertWantedPattern($myPattern, htmlentities($myPattern));
+ $myPattern = '#It works but not well.#';
+ $this->assertWantedPattern($myPattern, htmlentities($myPattern));
+ }
+
+}
+?>
diff --git a/site/app/tests/views/search/index.test.php b/site/app/tests/views/search/index.test.php
new file mode 100644
index 0000000..5197c4c
--- /dev/null
+++ b/site/app/tests/views/search/index.test.php
@@ -0,0 +1,57 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Mike Shaver <shaver@mozilla.org> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+class SearchResultTest extends WebTestHelper {
+
+ function SearchResultTest() {
+ $this->WebTestCase("Views->Search->Results Display Tests");
+ }
+
+ function testBasicResults() {
+ $this->getAction("/search/?q=the");
+ $this->assertNoUnwantedPattern("/"._('search_nothing_found')."/", "No results found.");
+ $this->assertFieldById('query', 'the', "previous query pre-populated");
+ }
+
+ function testUTF8Exploit() {
+ $this->getAction("/search?q=%C0%22%20onmouseover=alert(/xss/.source)%20\&cat=all");
+ $this->assertWantedPattern('/&quot; onmouseover=alert&#40;\/xss\/\.source&#41; \\\\/i', 'UTF-8 exploit not found');
+ }
+}
+
+?>
diff --git a/site/app/tests/views/search/rss/index.test.php b/site/app/tests/views/search/rss/index.test.php
new file mode 100644
index 0000000..397853f
--- /dev/null
+++ b/site/app/tests/views/search/rss/index.test.php
@@ -0,0 +1,57 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Frederic Wenzel <fwenzel@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+class SearchRSSTest extends WebTestHelper {
+
+ function SearchRSSTest() {
+ $this->WebTestCase("Views->Search->Search RSS Tests");
+ }
+
+ function setUp() {
+ $this->getAction("/search/rss/?q=the");
+ }
+
+ function testRSSResults() {
+ $this->assertWantedPattern("/rss version/", "correct template");
+
+ $this->assertWantedPattern("/<item>/", "some results were found");
+ $this->assertTrue($this->checkXML(), 'XML validation');
+ }
+}
+
+?>
diff --git a/site/app/tests/views/users/pwreset.test.php b/site/app/tests/views/users/pwreset.test.php
new file mode 100644
index 0000000..d0c5c0f
--- /dev/null
+++ b/site/app/tests/views/users/pwreset.test.php
@@ -0,0 +1,32 @@
+<?php
+
+class PwresetTest extends WebTestHelper {
+
+ function PwresetTest() {
+ $this->WebTestCase("Views->Users->pwreset Tests");
+ }
+
+ function setUp() {
+ $this->helper = new UnitTestHelper();
+ $this->controller = $this->helper->getController('Users', $this);
+
+ $id = 5;
+ $this->resetcode = $this->controller->User->setResetCode($id);
+ $this->getAction("/users/pwreset/{$id}/".$this->resetcode);
+ }
+
+ function testRemoraPage() {
+ // just checks if the page works or not
+ $this->assertWantedPattern('/Mozilla Add-ons/i', "pattern detected");
+ }
+
+ function testEmbeddedResetCode() {
+ $this->assertNoPattern("@users/login\?to=.*{$this->resetcode}@", 'Embedded in login link?');
+ $this->assertNoPattern("@advanced-search-toggle.*{$this->resetcode}@", 'Embedded in advanced search toggle?');
+ }
+
+ function testCacheHeader() {
+ $this->assertHeader('Cache-Control', 'no-store, must-revalidate, post-check=0, pre-check=0, private, max-age=0');
+ $this->assertHeader('Pragma', 'private');
+ }
+}
diff --git a/site/app/views/addons.php b/site/app/views/addons.php
new file mode 100644
index 0000000..8bf704b
--- /dev/null
+++ b/site/app/views/addons.php
@@ -0,0 +1,111 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Frederic Wenzel <fwenzel@mozilla.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+class AddonsView extends View
+{
+ var $caching = QUERY_CACHE; // query caching enabled?
+
+ // add to the next array any elements you want cached. The array after the => are default query string parameters to add to the renderElement parameters
+ // (this was mainly done so that the calls to advanced search wouldn't need to be rewritten from the code from before element caching,
+ // the hard case are query strings parameters used to toggle advanced search when JS is off ).
+ var $cacheableElts = array("search" => array('adv', 'nor'), "categories" => array());
+
+ var $helpers = array('AddonsHtml');
+
+ function __construct(&$controller) {
+ if ($this->caching) {
+ loadModel('Memcaching');
+ $this->Cache = new Memcaching();
+ }
+ return parent::__construct($controller);
+ }
+
+ /**
+ * loads helpers as defined by the regular View class, but replaces
+ * the original HtmlHelper by our custom AddonsHtmlHelper
+ */
+ function &_loadHelpers(&$loaded, $helpers) {
+ $helpers[] = 'AddonsHtml';
+ $helpers[] = 'Javascript';
+ $loaded = parent::_loadHelpers($loaded, $helpers);
+
+ $loaded['Html'] =& $loaded['AddonsHtml']; // replace Html helper
+
+ return $loaded;
+ }
+
+ /**
+ * generate a cache key for memcaching queries
+ * @param string additional key uniqueness factors (SQL query etc)
+ */
+ function _cachekey($key = '', $params) {
+ // attach some unique factors to the key
+ $key .= LANG.':'.APP_ID.':';
+ foreach ($params as $k => $v){
+ $key .= $k.serialize($v);
+ }
+ return MEMCACHE_PREFIX.md5($key);
+ }
+
+ function renderElement($name, $params = array()) {
+ if ($this->caching && array_key_exists($name, $this->cacheableElts)) {
+
+ // see comment by definition of cacheableElts above. This adds default query string parameters to the $params array
+ foreach ($this->cacheableElts[$name] as $query_param) {
+ if (isset($this->controller->params['url'][$query_param]) && !isset($params[$query_param]) ) {
+ $params[$query_param] = $this->controller->params['url'][$query_param];
+ }
+ }
+
+ $cachekey = $this->_cachekey('element:'.$name, $params);
+ if ($cached = $this->Cache->get($cachekey)) {
+ return $cached;
+ }
+ }
+
+ $result = parent::renderElement($name, $params);
+
+ if ($this->caching && !empty($cachekey)) {
+ // cache it if it's not yet cached
+ $res = $this->Cache->set($cachekey, $result);
+ }
+ // and return the result
+ return $result;
+ }
+}
+?>
diff --git a/site/app/views/addons/ajaxy.thtml b/site/app/views/addons/ajaxy.thtml
new file mode 100644
index 0000000..fb1c7fa
--- /dev/null
+++ b/site/app/views/addons/ajaxy.thtml
@@ -0,0 +1,42 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Jeff Balogh <jbalogh@mozilla.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+$this->layout = null;
+
+echo $this->renderElement('amo2009/homepage_addon_listing');
+?>
diff --git a/site/app/views/addons/browse.thtml b/site/app/views/addons/browse.thtml
new file mode 100644
index 0000000..7c5f80f
--- /dev/null
+++ b/site/app/views/addons/browse.thtml
@@ -0,0 +1,75 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Andrei Hajdukewycz <sancus@off.net> (Original Author)
+ * Frederic Wenzel <fwenzel@mozilla.com>
+ * Wil Clouser <clouserw@mozilla.com>
+ * Mike Morgan <morgamic@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+$this->viewVars['bodyclass'] = 'inverse';
+$this->layout = 'amo2009';
+?>
+
+<div class="section" id="browse">
+ <div class="stand-alone-options">
+ <?=$this->renderElement('amo2009/categories')?>
+ <?php
+ if (!empty($type) && array_key_exists('Tag', $this_tag))
+ echo $this->renderElement('amo2009/search', array('category' =>
+ array($type, $this_tag['Tag']['id'])));
+ else
+ echo $this->renderElement('amo2009/search');
+ ?>
+ </div>
+ <div class="primary full" role="main">
+ <h2><?=$subpagetitle?></h2>
+
+ <h3><?=sprintf(ngettext('addon_list_category_totalcount',
+ 'addon_list_category_totalcount', $paging['total']),
+ $paging['total'])?></h3>
+ <div class="featured listing" id="addon-listing">
+ <?php
+ echo $this->renderElement('amo2009/addon_list_options', array('paging' => $paging));
+ foreach ($addons as $val) {
+ echo $this->renderElement('amo2009/homepage_addon', array('addon' => $val));
+ }
+ ?>
+ </div>
+
+ <?=$this->renderElement('amo2009/pagination');?>
+ </div><!-- /primary -->
+
+</div><!-- /section -->
diff --git a/site/app/views/addons/browse_thumbs.thtml b/site/app/views/addons/browse_thumbs.thtml
new file mode 100644
index 0000000..a5c029e
--- /dev/null
+++ b/site/app/views/addons/browse_thumbs.thtml
@@ -0,0 +1,148 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Frederic Wenzel <fwenzel@mozilla.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+$this->viewVars['bodyclass'] = 'browse_thumbs';
+$this->layout = 'amo2009';
+?>
+
+<div class="stand-alone-options">
+ <?=$this->renderElement('amo2009/categories')?>
+ <?php
+ if (!empty($type) && !empty($this_tag) && array_key_exists('Tag', $this_tag))
+ echo $this->renderElement('amo2009/search', array('category' =>
+ array($type, $this_tag['Tag']['id'])));
+ else
+ echo $this->renderElement('amo2009/search');
+ ?>
+</div>
+
+<div class="secondary">
+ <div class="highlight" id="thumb-subcategories">
+ <h3><?=___('general_addontype_theme_plural', 'Themes')?></h3>
+ <ul class="subcategories">
+ <li<?= ($this_tag == FALSE) ? ' class="selected"' : '' ?>><?=$html->link(
+ 'All',
+ "/browse/type:{$type}/cat:all?sort={$sort_by}"
+ )?>
+ <span class="items"><?=$all_total?></span>
+ </li>
+ <?php foreach ($subcats as $subcat): ?>
+ <?php
+ $params = 'sort=' . $sort_by;
+ if ($show_exp)
+ $params .= '&exp=on';
+ if ($show_limit)
+ $params .= '&show=' . $show_limit;
+ ?>
+ <li class="sub<?= ($this_tag['Tag']['id'] == $subcat['Tag']['id']) ? ' selected' : '' ?>"><?=$html->link(
+ $subcat['Translation']['name']['string'],
+ "/browse/type:{$subcat['Tag']['addontype_id']}/cat:{$subcat['Tag']['id']}?{$params}"
+ )?>
+ <span class="items"><?=(isset($subcat_totals[$subcat['Tag']['id']]) ? $subcat_totals[$subcat['Tag']['id']] : 0) ?></span>
+ </li>
+ <?php endforeach; ?>
+ </ul>
+ </div>
+</div>
+
+<div class="primary" role="main">
+
+ <?php if ( empty($this_tag)): ?>
+ <h2><?=___('themes_landing_browse_themes', 'Browse Themes')?></h2>
+ <?php else: ?>
+ <h2><?=$this_tag['Translation']['name']['string']?></h2>
+ <?php endif ?>
+
+ <h3><?=sprintf(ngettext('addon_list_category_totalcount',
+ 'addon_list_category_totalcount', $paging['total']),
+ $paging['total'])?></h3>
+ <div class="featured listing" id="addon-listing">
+ <?= $this->renderElement('amo2009/addon_list_options', array('paging' => $paging)) ?>
+
+ <ul class="thumbs clearfix">
+ <?php
+ foreach ($addons as $addon) {
+ $addonID = $addon['Addon']['id'];
+ $addonName = $addon['Translation']['name']['string'];
+
+ $prevPath = $this->controller->Image->getHighlightedPreviewURL($addon['Addon']['id']);
+ $iconPath = $this->controller->Image->getAddonIconURL($addon['Addon']['id']);
+
+ $_alt = sprintf(_('img_preview_of'),$addonName);
+ $previmg = '<img src="'.$prevPath.'" alt="'.$_alt.'" title="'.$_alt.'"/>';
+ $previmg = $html->link($previmg, "/addon/{$addonID}");
+ ?>
+ <li class="thumb <?=$html->extraClass($addon)?>">
+ <div class="thumb_item">
+ <div class="img"><?=$previmg?></div>
+ <h4 class="name"><?=$html->link("$addonName", "/addon/{$addonID}");?></h4>
+ <?=$html->flag($addon)?>
+ <p class="meta">
+ <?php if ($sort_by == 'updated'): ?>
+ <?php
+ $_update_string = (_('addon_detail_last_updated') == 'addon_detail_last_updated') ? 'Updated %s' : _('addon_detail_last_updated');
+ $_version_date = (isset($addon['Addon']['datestatuschanged']) ? $addon['Addon']['datestatuschanged'] : $addon['Version'][0]['created']);
+ echo sprintf($_update_string, strftime(_('date'), strtotime($_version_date)));
+ ?>
+ <?php elseif ($sort_by == 'popular'): ?>
+ <em><?=$html->number_format($addon['Addon']['weeklydownloads'], 0)?></em>
+ <?php
+ echo ___('addon_downloads_weekly', _('addon_downloads'));
+ ?>
+ <?php else: ?>
+ <?=$this->renderElement('stars',array('rating' => $addon['Addon']['averagerating']))?>
+ <?php if ($addon['Addon']['totalreviews'] > 0): ?>
+ <a href="<?= $html->url('/addon/'.$addon['Addon']['id'].'#reviews') ?>"><?=
+ sprintf(ngettext('feature_reviews','feature_reviews',
+ $addon['Addon']['totalreviews']), $addon['Addon']['totalreviews'])
+ ?></a>
+ <?php endif ?>
+ <?php endif ?>
+ </p>
+ </div>
+ </li>
+ <?php
+ }
+ ?>
+ </ul>
+
+ </div>
+
+ <?=$this->renderElement('amo2009/pagination');?>
+
+</div><!-- /primary -->
diff --git a/site/app/views/addons/category_landing.thtml b/site/app/views/addons/category_landing.thtml
new file mode 100644
index 0000000..db0764c
--- /dev/null
+++ b/site/app/views/addons/category_landing.thtml
@@ -0,0 +1,178 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Andrei Hajdukewycz <sancus@off.net> (Original Author)
+ * Wil Clouser <clouserw@mozilla.com>
+ * Frederic Wenzel <fwenzel@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+$this->viewVars['bodyclass'] = 'inverse category_landing';
+$this->layout = 'amo2009';
+
+$curr_tag_name = $this_tag['Translation']['name']['string'];
+$curr_tag_desc = $this_tag['Translation']['description']['string'];
+
+$nameLimit = 40;
+$summaryLimit = 70;
+?>
+<div class="stand-alone-options">
+ <?=$this->renderElement('amo2009/categories')?>
+ <?=$this->renderElement('amo2009/search')?>
+</div>
+
+<div class="primary" role="main">
+
+ <h2><?php echo $curr_tag_name ?></h2>
+
+ <div id="featured_addons" class="clearfix">
+ <ul>
+ <?php foreach ($featured_addons as $addon): ?>
+
+ <li class="addon_block_wrapper">
+ <div class="addon_block item">
+ <h4 class="name"><a href="<?=$html->url("/addon/{$addon['Addon']['id']}")?>"><?php echo $html->truncateChars(28, $addon['Translation']['name']['string'], true) ?></a></h4>
+ <p class="authors"><?=_('addons_home_by')?> <?=$html->linkUsersFromModel($addon['User'], 2,"/addon/{$addon['Addon']['id']}#authors" );?></p>
+ <p class="summary"><?php echo $html->truncateChars($summaryLimit, $addon['Translation']['summary']['string'], true) ?></p>
+ <div class="preview"><a href="<?=$html->url("/addon/{$addon['Addon']['id']}")?>"><img src="<?php echo $this->controller->Image->getHighlightedPreviewURL($addon['Addon']['id']);?>" alt="" /></a></div>
+ <p class="rating"><?=$this->renderElement('amo2009/stars',array('rating' => $addon['Addon']['averagerating']))?></p>
+ <?php
+ $addonIconPath = $this->controller->Image->getAddonIconURL($addon['Addon']['id']);
+ $addonID = $addon['Addon']['id'];
+ $addonName = $addon['Translation']['name']['string'];
+ $hasVersion = (isset($addon['Version']) && !empty($addon['Version']));
+ $addonVersion = ($hasVersion ? $addon['Version'][0]['version'] : '');
+ $hasFiles = ($hasVersion && !empty($addon['File']));
+ if ($hasFiles) {
+ $addonFiles = $addon['File'];
+ $addonEULA = $addon['Translation']['eula']['string'];
+
+
+ $addonCreators = $addon['User'];
+ $addonSummary = $addon['Translation']['summary']['string'];
+
+ // prepare preview image
+ if (isset($addonPreviewPath) && !empty($addonPreviewPath)) {
+ $_alt = sprintf(_('img_preview_of'),$addonName);
+ $previmg = '<img src="'.$addonPreviewPath.'" '
+ .'alt="'.$_alt.'" title="'.$_alt.'"/>';
+ $previmg = '<p class="preview-img">'
+ .$html->link($previmg, "/addon/{$addonID}").'</p>';
+ } else
+ $previmg = '';
+ // prepare icon
+ if (isset($addonIconPath) && !empty($addonIconPath))
+ $icon = '<img src="'.$addonIconPath.'" class="icon" alt=""/>';
+ else
+ $icon = '';
+
+ // prepare categories
+ if (!empty($addon['Tag'])) {
+ $categories = $this->renderElement('addon_categories', array('tags' => $addon['Tag']));
+ } else
+ $categories = '';
+
+ // prepare summary
+ if (!isset($addonSummary) || empty($addonSummary))
+ $addonSummary = '&nbsp;';
+
+ $_install_render_options = array(
+ 'addonIconPath' => $addonIconPath,
+ 'addonName' => $addonName,
+ 'addonId' => $addonID,
+ 'addonFiles' => $addonFiles,
+ 'addonEULA' => $addonEULA,
+ 'addonStatus' => $addon['Addon']['status'],
+ 'is_latest' => ($addon['Addon']['status'] == STATUS_PUBLIC),
+ 'addonType' => $addon['Addon']['addontype_id'],
+ 'compatible_apps' => $addon['compatible_apps'],
+ 'allPlatforms' => $platforms,
+ 'buttonType' => 'small',
+ 'showInstructions' => false
+ );
+ echo $this->renderElement('amo2009/install', $_install_render_options);
+
+ }
+ ?>
+ </div>
+ </li>
+ <?php endforeach ?>
+ </ul>
+ </div>
+
+ <div id="new_addons" class="addons_column clearfix">
+ <h3><span><?= ___('addons_recently_added') ?></span></h3>
+ <ul>
+ <?php foreach ($new_addons as $idx=>$addon): ?>
+ <li class="<?= (0 == ($idx % 2)) ? 'odd' : 'even' ?>"><a href="<?=$html->url("/addon/{$addon['id']}")?>">
+ <img class="icon" src="<?php echo $addon['icon_url']?>" width="32" height="32" alt="" />
+ <span class="name"><?php echo $html->truncateChars($nameLimit, $addon['name'], true) ?></span>
+ <span class="meta created">
+ added <?php echo strftime('%m/%d/%Y', strtotime($addon['created'])) ?>
+ </span>
+ </a></li>
+ <?php endforeach ?>
+ </ul>
+ <p class="view-all"><?=$html->link(___('view_recently_added').' »',"/browse/type:{$type_id}/cat:{$cat_id}?sort=newest")?></p>
+ </div>
+
+ <div id="popular_addons" class="addons_column clearfix">
+ <h3><span><?=___('addons_top_downloads') ?></span></h3>
+ <ul>
+ <?php foreach ($popular_addons as $idx=>$addon): ?>
+ <li class="<?= (0 == ($idx % 2)) ? 'odd' : 'even' ?>"><a href="<?=$html->url("/addon/{$addon['id']}")?>">
+ <img class="icon" src="<?php echo $addon['icon_url']?>" width="32" height="32" alt="" />
+ <span class="name"><?php echo $html->truncateChars($nameLimit, $addon['name'], true) ?></span>
+ <span class="meta downloads"><?php echo $html->number_format($addon['weeklydownloads']) ?> <?= _('addon_downloads_weekly') ?></span>
+ </a></li>
+ <?php endforeach ?>
+ </ul>
+ <p class="view-all"><?=$html->link(___('view_top_downloads').' »',"/browse/type:{$type_id}/cat:{$cat_id}?sort=popular")?></p>
+ </div>
+
+ <div id="updated_addons" class="addons_column last clearfix">
+ <h3><span><?=___('addons_top_rated') ?></span></h3>
+ <ul>
+ <?php foreach ($updated_addons as $idx=>$addon): ?>
+ <li class="<?= (0 == ($idx % 2)) ? 'odd' : 'even' ?>"><a href="<?=$html->url("/addon/{$addon['id']}")?>">
+ <img class="icon" src="<?php echo $addon['icon_url']?>" width="32" height="32" alt="" />
+ <span class="name"><?php echo $html->truncateChars($nameLimit, $addon['name'], true) ?></span>
+ <span class="meta rating"><?=$this->renderElement('amo2009/stars',array('rating' => $addon['averagerating']))?></span>
+ </a></li>
+ <?php endforeach ?>
+ </ul>
+ <p class="view-all"><?=$html->link(___('view_top_rated').' »',"/browse/type:{$type_id}/cat:{$cat_id}?sort=rated")?></p>
+ </div>
+
+</div>
diff --git a/site/app/views/addons/dictionaries.thtml b/site/app/views/addons/dictionaries.thtml
new file mode 100644
index 0000000..da197e8
--- /dev/null
+++ b/site/app/views/addons/dictionaries.thtml
@@ -0,0 +1,111 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Frederic Wenzel <fwenzel@mozilla.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+global $native_languages, $experimental_status, $browser_apps;
+
+// "Download" or "Install"?
+$install_text = array();
+if (in_array(APP_ID, $browser_apps)) {
+ $install_text[ADDON_DICT] = _('langtools_install_dictionary');
+ $install_text[ADDON_LPAPP] = _('langtools_install_langpack');
+} else {
+ $install_text[ADDON_DICT] = _('langtools_download_dictionary');
+ $install_text[ADDON_LPAPP] = _('langtools_download_langpack');
+}
+
+$this->viewVars['bodyclass'] = 'inverse';
+$this->layout = 'amo2009';
+?>
+<div class="section">
+ <div class="stand-alone-options">
+ <?=$this->renderElement('amo2009/categories')?>
+ <?=$this->renderElement('amo2009/search'); ?>
+ </div>
+
+ <?php /* list of dictionaries and language packs */ ?>
+ <div class="featured"><div class="featured-inner">
+ <div id="dictionaries">
+ <h3><?=_('langtools_header_dicts_and_langpacks')?></h3>
+
+ <table summary="<?=_('langtools_a11y_tablesummary')?>">
+ <thead>
+ <tr>
+ <th scope="col" colspan="2"><?=_('langtools_tableheader_language')?></th>
+ <th scope="col"><?=_('langtools_tableheader_dictionary')?></th>
+ <th scope="col"><?=_('langtools_tableheader_langpack')?></th>
+ </tr>
+ </thead>
+ <tbody>
+ <?php
+ $even = true; // styling even/odd lines differently
+ foreach ($dicts as $locale => $localedata):
+ ?>
+ <tr<?=($even ? ' class="alt"' : '')?>>
+ <?php if (!empty($localedata['localname'])): ?>
+ <th scope="row"><?=$localedata['displayname']?></th>
+ <td lang="<?=$locale?>"><?=$localedata['localname']?></td>
+ <?php else: ?>
+ <th scope="row" colspan="2"><?=$localedata['displayname']?></th>
+ <?php endif; ?>
+ <?php
+ // list all dictionaries and language packs for this target locale
+ foreach(array(ADDON_DICT, ADDON_LPAPP) as $type) {
+ echo "<td>\n";
+ foreach($localedata[$type] as $addon) {
+ echo '<p>';
+ echo $html->link($install_text[$type], "/addon/{$addon['Addon']['id']}");
+ echo ' ('.sprintf(_('size_kb'), $addon['File'][0]['size']).')';
+ if (!empty($addon['Addon']['locale_disambiguation']))
+ echo "<br/>({$addon['Addon']['locale_disambiguation']})";
+ echo "</p>\n";
+ }
+ echo "</td>\n";
+ }
+ ?>
+ </tr>
+ <?php
+ $even = !$even;
+ endforeach;
+ ?>
+ </tbody>
+ </table>
+ </div><!-- /#dictionaries -->
+ </div></div><!-- /featured -->
+
+
+</div><!-- /.section -->
diff --git a/site/app/views/addons/display.thtml b/site/app/views/addons/display.thtml
new file mode 100644
index 0000000..32a81ff
--- /dev/null
+++ b/site/app/views/addons/display.thtml
@@ -0,0 +1,521 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Andrei Hajdukewycz <sancus@off.net> (Original Author)
+ * Mike Morgan <morgamic@mozilla.com>
+ * Frederic Wenzel <fwenzel@mozilla.com>
+ * Justin Scott <fligtar@gmail.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+?>
+
+<?php
+ if (empty($addonIconPath))
+ $addonIconPath = ($addon['Addon']['addontype_id'] == ADDON_THEME ? $html->urlImage(DEFAULT_THEME_ICON) : $html->urlImage(DEFAULT_ADDON_ICON));
+?>
+
+<div class="stand-alone-options">
+
+ <?=$this->renderElement('amo2009/categories')?>
+
+ <?=$this->renderElement('amo2009/search')?>
+
+ </div>
+
+<div class="primary" role="main">
+ <?php
+ if (!empty($coll_addon_added)) {
+ echo $this->renderElement('notification', array(
+ 'type' => 'success',
+ 'msg' => sprintf(___('addons_display_collection_publish_success'),
+ $addon['Translation']['name']['string'],
+ $html->link($coll_addon_added['Translation']['name']['string'],
+ "/collection/{$coll_addon_added['Collection']['uuid']}")
+ )
+ ));
+ }
+ ?>
+ <h2 <?=$addon['Translation']['name']['locale_html']?> class="addon"><img src="<?=$addonIconPath?>" class="icon" alt="" /><span><?=$addon['Translation']['name']['string']?> <?=($hasversion?$addon['Version'][0]['Version']['version']:'')?></span></h2>
+ <h4 class="author"><?=_('addons_home_by')?> <?= $html->linkUsersFromModel($addon['User'], 0); ?></h4>
+ <div id="addon-summary" class="addon <?=$html->extraClass($addon)?>">
+
+
+ <?php if (count($previews) > 0) {
+ $shown = 0;
+ $_js_string = '';
+
+ $thumb = $this->controller->Image->getPreviewURL($previews[0]['Preview']['id']);
+ $full = $this->controller->Image->getPreviewURL($previews[0]['Preview']['id'], 'full');
+ $caption = $previews[0]['Translation']['caption']['string'];
+ // Lightbox supports HTML in their captions, but we strip it
+ // out in the dev cp.
+ ?>
+
+ <p class="preview-img">
+ <a class="screenshot" rel="jquery-lightbox" href="<?=$full?>" title="<?=$caption?>">
+ <img src="<?=$thumb?>" alt=""/>
+ </a>
+ </p>
+ <?php } else { ?>
+ <p class="preview-img">
+ <img src="<?=$html->urlImage('no-preview.png')?>" alt="" width="200" height="150" />
+ </p>
+ <?php } ?>
+<p class="desc"<?=$addon['Translation']['summary']['locale_html']?>><?=nl2br($addon['Translation']['summary']['string'])?> </p>
+
+
+ <h4 class="hidden"><?=_('addons_display_categories')?></h4>
+ <?=$this->renderElement('addon_categories', array('tags' => $relatedTags)); ?>
+
+ <? if ($hasversion): ?>
+ <p class="updated">
+ <?php
+ echo sprintf(___('addon_detail_last_updated'), strftime(_('date'), strtotime($addon['Version'][0]['Version']['created'])));
+ ?>
+ </p>
+ <? endif; ?>
+
+ <?php
+ if ($hasversion) {
+
+ $flags = array($html->byStatus($addon, array('experimental' => 'experimental',
+ 'recommended' => 'recommended',
+ 'default' => 'default')));
+
+ global $experimental_status;
+ if (isset($addonStatus) && in_array($addonStatus, $experimental_status)) {
+ $flags[] = 'experimental';
+ }
+
+ $addon['File'] = $addon['Version'][0]['File']; //install.thtml expects this
+
+ echo $this->renderElement('amo2009/install', array(
+ 'flags' => $flags,
+ 'buttonClass' => 'significant',
+ 'buttonSize' => '16x16',
+ 'addon' => $addon
+ ));
+
+ if (!empty($addon['Translation']['privacypolicy']['string'])) {
+ echo '<div class="privacypolicy">';
+ echo $html->link(_('addons_display_has_privacy'), "/addons/policy/0/{$addon['Addon']['id']}");
+ echo '</div>';
+ }
+ }
+ ?>
+
+
+ <p class="rating">
+ <?=$this->renderElement('amo2009/reviews', array('addon' => $addon))?>
+ </p>
+
+
+ <p class="stats">
+ <?php
+ echo '<em>'.$html->number_format($addon['Addon']['weeklydownloads'], 0).'</em> '.___('addon_downloads_weekly');
+ echo '<br /><em>'.$html->number_format($addon['Addon']['totaldownloads'], 0).'</em> '._('addon_downloads_total');
+ ?>
+ </p>
+
+
+ <div class="share-this">
+ <a class="share button" href="#">
+ <?php echo ___('addons_share_button_text', 'Share this') ?>
+ </a>
+
+ <div class="share-networks">
+ <ul>
+ <?php foreach ($link_sharing_services as $l_name => $l_details) :?>
+ <li class="<?= $l_name ?>"><p>
+ <?php $share_url = str_replace('/addon/', '/addon/share/', $_SERVER['REQUEST_URI']) ?>
+ <a class="uniquify" target="_blank" href="<?php echo $share_url . '?service=' . $l_name ?>"><?php
+ // Escaping here because these details came via set()
+ echo htmlentities($l_details['label'], ENT_COMPAT, 'UTF-8')
+ ?></a>
+ </p></li>
+ <?php endforeach ?>
+ </ul>
+ </div>
+
+ </div>
+ </div>
+ <div id="addon-info" class="featured listing">
+ <div class="featured-inner">
+
+ <? if (count($previews) > 1): // Only show this if there are 2 or more images. ?>
+ <div class="item">
+ <h5><?=_('addons_display_more_images')?></h5>
+
+ <?php
+ $shown = 0;
+ $_js_string = '';
+
+ foreach ($previews as $preview):
+
+ // Skip the first one, which is the preview.
+ if ($shown < 1) {
+ $shown++;
+ continue;
+ }
+
+ $thumb = $this->controller->Image->getPreviewURL($preview['Preview']['id']);
+ $full = $this->controller->Image->getPreviewURL($preview['Preview']['id'], 'full');
+ $caption = $preview['Translation']['caption']['string'];
+ // Lightbox supports HTML in their captions, but we strip it
+ // out in the dev cp.
+ $_js_string .= empty($_js_string) ? "['{$full}','{$caption}']" : ", ['{$full}','{$caption}']";
+ $shown++;
+ ?>
+
+ <a class="screenshot thumbnail" rel="jquery-lightbox" href="<?=$full?>" title="<?=$caption?>"><img src="<?=$thumb?>" alt="" /></a>
+
+ <? endforeach; ?>
+ </div>
+ <? endif; ?>
+
+
+
+ <div class="item">
+ <h5><?=_('addons_display_long_description')?></h5>
+ <p<?=$addon['Translation']['description']['locale_html']?>><?=nl2br($addon['Translation']['description']['string'])?></p>
+ </div>
+ <div class="item">
+ <?=$this->renderElement('app_compatibility', array('compatible_apps' => $compatible_apps)) ?>
+
+ <div id="addon_app_compatibility" ><?php
+ // link to complete version history
+ if ($hasversion) {
+ echo $html->link(___('addons_display_see_all_versions'),
+ "/addons/versions/{$addon['Addon']['id']}", array('class'=>'view'));
+ }
+ ?></div>
+ </div>
+
+
+ <?php
+ /* Homepage URL link */
+ if (!empty($addon['Translation']['homepage']['string'])): ?>
+ <div class="item">
+ <?php echo '<h5 id="homepage">'.___('addons_display_header_homepage').'</h5>'; ?>
+ <p><?=$html->link($addon['Translation']['homepage']['string'])?></p>
+ </div>
+
+
+ <?php endif; // h4:Homepage ?>
+
+ <?php /* License */
+ if ($hasversion && isset($addon['Version'][0]['Version']['license_id'])):
+ $license_id = $addon['Version'][0]['Version']['license_id'];
+ $version_id = $addon['Version'][0]['Version']['id'];
+ $license_name = $this->controller->License->getName($license_id);
+ $license_link = $html->link($license_name,
+ '/versions/license/'.$version_id);
+ ?>
+ <div class="item">
+ <h5 id="license">
+ <?=___('addons_display_header_license')?>
+ <a href="<?=$html->url('/pages/developer_faq')?>">
+ <?=___('addons_display_a_license_what')?>
+ </a>
+ </h5>
+ <p><?=$license_link?></p>
+ </div>
+ <?php endif; ?>
+
+ <?php
+ $has_supportemail = !empty($addon['Translation']['supportemail']['string']);
+ $has_supporturl = !empty($addon['Translation']['supporturl']['string']);
+ if ($has_supportemail || $has_supporturl): ?>
+ <div class="item">
+ <?php echo '<h5 id="support">'.___('addons_display_header_support').'</h5>'; ?>
+
+ <?php
+ /* Support email/URL link */
+ if ($has_supportemail && $has_supporturl) {
+ // both support email and support URL present
+ ?>
+ <p>
+ <?=sprintf(_('addons_display_paragraph_supportinfoemailurl'),
+ $html->link($addon['Translation']['supporturl']['string']),
+ $link->email($addon['Translation']['supportemail']['string']));?>
+ </p>
+ <?php
+ } else if ($has_supporturl) {
+ // support URL only
+ ?>
+ <p>
+ <?=sprintf(_('addons_display_paragraph_supportinfourl'),
+ $html->link($addon['Translation']['supporturl']['string']));?>
+ </p>
+ <?php
+ } else if ($has_supportemail) {
+ // support email only
+ ?>
+ <p>
+ <?=sprintf(_('addons_display_paragraph_supportinfoemail'),
+ $link->email($addon['Translation']['supportemail']['string']));?>
+ </p>
+ <?php } ?>
+ </div>
+ <?php endif; // h4:Support ?>
+
+ <div id="addon-advanced" class="item">
+ <h5><?=_('addons_display_advanced_details')?></h5>
+
+ <?php if (!empty($addon['Translation']['developercomments']['string'])) { ?>
+ <h5><?=_('addons_display_header_developer_comments')?></h5>
+ <p<?=$addon['Translation']['developercomments']['locale_html']?>>
+ <?=nl2br($addon['Translation']['developercomments']['string'])?>
+ </p>
+ <?php } ?>
+
+ <?php if ($hasversion):
+ $_version_data = array(
+ 'addonid' => $addon['Addon']['id'],
+ 'version' => $addon['Version'][0]['Version']['version'],
+ 'created' => $addon['Version'][0]['Version']['created'],
+ 'fileSize' => $addon['Version'][0]['File'][0]['size']
+ );
+ ?>
+ <h5 id="version-detail">
+ <?=$this->renderElement('addon_version_detail', $_version_data)?>
+ </h5>
+ <p id="release-notes" <?=$addon['Version'][0]['Translation']['releasenotes']['locale_html']?>>
+ <?=nl2br($addon['Version'][0]['Translation']['releasenotes']['string'])?>
+ </p>
+ <p>
+ <?php
+ $additionalLinks = array();
+ if ($addon['Addon']['viewsource'] == 1 && $this->controller->Session->check('User')) {
+ $additionalLinks[] = $html->link(_('addons_display_view_source'), "/files/browse/{$addon['Version'][0]['File'][0]['id']}");
+ }
+ if ($addon['Addon']['publicstats'] == 1) {
+ $additionalLinks[] = $html->link(_('addons_display_view_stats'), "/statistics/addon/{$addon['Addon']['id']}");
+ }
+
+ if (!empty($additionalLinks)) {
+ echo implode($additionalLinks, ' | ');
+ }
+ ?>
+ </p>
+ <? endif; ?>
+</div>
+ </div></div>
+
+ <?php if (!empty($reviews)): ?>
+ <h3 id="reviews"><?=_('addons_display_header_reviews')?></h3>
+ <div class="article">
+
+ <?php
+ foreach ($reviews as $rev_no => $review):
+ $review['Translation'] = (array_key_exists(LANG, $review['Translation']) ?
+ $review['Translation'][LANG] : current($review['Translation']));
+ ?>
+
+ <div id="review-<?=$rev_no?>" class="hreview">
+ <?php if (!empty($review['Translation']['title']['string'])): ?>
+ <h5><?=$review['Translation']['title']['string']?></h5>
+ <?php endif; ?>
+ <p class="description"><?=$review['Translation']['body']['string']?></p>
+ <p>
+ <?=$this->renderElement('amo2009/stars',array('rating' => $review['Review']['rating']));?>
+ <?php
+ echo sprintf(___('addon_reviewed_by_u_on_d'),
+ $html->linkUserFromModel($review['User']),
+ strftime(_('date'), strtotime($review['Review']['created'])));
+ ?>
+ </p>
+ </div>
+
+ <?php
+ endforeach;
+ ?>
+ <? echo '<p>'.$html->link(sprintf(_('addons_display_see_all_reviews'), $review_count), '/reviews/display/'.$addon['Addon']['id'], array('class'=>'more-info')).'</p>'; ?>
+
+ </div>
+ <?php endif; ?>
+
+</div>
+<div class="secondary" role="secondary">
+
+ <?php if(empty($isAuthor)) { ?>
+ <div class="highlight">
+ <form id="form-review" action="<?=$html->url('/reviews/add/'.$addon['Addon']['id'])?>" method="post">
+ <?=$html->hiddenSession() ?>
+ <h3><?=_('addons_display_what_do_you_think')?></h3>
+ <?php if(!$loggedIn) { ?>
+ <p class="login">(<?php echo $html->link(_('header_navlink_login'), $html->login_url());?>)</p>
+ <?php } ?>
+ <p><input type="hidden" name="data[Review][id]" value="" id="ReviewId"/></p>
+ <p><input type="hidden" name="data[Review][title]" value=" " id="ReviewTitle"/></p>
+
+ <h4><?=_('addons_display_rate_it')?></h4>
+
+ <?php if(!$loggedIn) { ?>
+ <p class="stars stars-0">&nbsp;</p>
+ <?php } else {?>
+
+ <select id="review-rating" name="data[Review][rating]">
+ <option></option>
+ <option value="1" class="worst">*</option>
+ <option value="2" class="bad">**</option>
+
+ <option value="3" class="fair">***</option>
+ <option value="4" class="good">****</option>
+ <option value="5" class="best">*****</option>
+ </select>
+ <?php } ?>
+
+ <?=$html->tagErrorMsg('Review/rating', _('error_review_rating_required')) ?>
+ <p><textarea name="data[Review][body]" cols="30" rows="6" id="short-review" <?php if(!$loggedIn) { ?>disabled="disabled" class="disabled" <?php } ?>></textarea></p>
+ <p>
+ <a href="<?=$html->url('/reviews/add/'.$addon['Addon']['id'])?>"><?=_('addons_display_detailed_review')?></a>
+ <button <?php if(!$loggedIn) { ?>disabled="disabled" <?php } ?> ><?=___('addons_display_review_submit')?></button>
+ </p>
+
+
+ <div id="addons-display-review-etiquette">
+ <p>
+ <?php echo ___('addons_display_review_etiquette'); ?>
+ </p>
+ <?php
+ if ($has_supportemail || $has_supporturl) {
+ echo '<p>'.sprintf(___('addons_display_review_see_support'), '#support').'</p>';
+ }
+ ?>
+ <p><?=sprintf(___('addons_display_review_guidelines_link', '<a href="%s">Review Guidelines</a>'), $html->url('/pages/review_guide')) ?></p>
+ </div>
+ </form>
+ </div>
+ <?php } ?>
+
+
+
+<div class="highlight">
+
+ <?php
+ if (is_array($relatedTags)) {
+ foreach ($relatedTags as $tag) {
+ echo $html->link(sprintf(_('addons_display_see_all_addons'),$tag['Translation']['name']['string']), '/browse/' . "type:" . $tag['Tag']['addontype_id'] . '/' . "cat:" . $tag['Tag']['id'], array('class' => 'more-info')) . "\n";
+ }
+ }
+ ?>
+
+ <?php if (count($authorAddons) > 1): ?>
+ <h4 class="other-author-addons"><?=sprintf(n___('addons_display_other_addons_by', 'addons_display_other_addons_by', count($addon['User'])),
+ $html->linkUsersFromModel($addon['User'], 0));?>
+ </h4>
+ <div class="prose">
+ <ul>
+ <?php
+ if (count($authorAddons) > 3) {
+ echo '<form id="addons-author-addons" method="get" action="">';
+ echo '<select id="addons-author-addons-select" name="addons-author-addons-select" onchange="this.form.submit()">';
+ echo $this->renderElement('addon_author_addons', array('tag' => 'option'));
+ echo '</select>';
+ echo '<input class="hidden" type="submit" value="'._('addons_author_addons_submit').'"/>';
+ echo '</form>';
+ } else {
+ echo $this->renderElement('addon_author_addons', array('tag' => 'li'));
+ }
+ ?>
+ </ul>
+ </div>
+
+ <?php endif; ?>
+
+</div>
+<!-- /#more-addons-->
+
+ <div class="highlight collections-add prose">
+ <h3><?=___('addons_display_header_collections')?></h3>
+
+ <?php if (empty($pop_collections)): ?>
+ <p><?=___('addons_display_nocollections')?></p>
+ <?php else: ?>
+ <ul>
+ <?php foreach($pop_collections as &$_coll): ?>
+ <li><?=$link->collection($_coll)?></li>
+ <?php endforeach; ?>
+ <?php if (($_othercolls = $collection_count - count($pop_collections)) > 0): ?>
+ <li>
+ <?=sprintf(n___('addons_display_collections_more', 'addons_display_collections_more', $_othercolls), $_othercolls)?>
+ </li>
+
+ <?php endif; ?>
+ </ul>
+ <?php endif; ?>
+ <?php if ($loggedIn): ?>
+ <form action="<?= $html->url('/collections/addtocollection') ?>" method="post" id="coll_publish">
+ <div>
+ <h3><label for="publish_to"><?=___('addons_display_collection_add')?></label></h3>
+ <?=$html->link(___('addons_display_collection_whatsthis'), '/collections/')?>
+ <?=$html->hiddenSession() ?>
+ <input name="data[addon_id]" type="hidden" value="<?= $addon['Addon']['id'] ?>" />
+ <select name="data[collection_uuid]" id="publish_to">
+ <option value="" selected="selected"><?=___('addons_display_collection_add_select_one')?></option>
+ <?php foreach ($userCollections as $collection): ?>
+ <option value="<?=$collection['Collection']['uuid'] ?>"><?=$collection['Translation']['name']['string'] ?></option>
+ <?php endforeach; ?>
+ <option value="new"><?=___('addons_display_collection_add_new')?></option>
+ </select>
+ <button><?=___('addons_display_collection_add_submit')?></button>
+ </div>
+ </form>
+ <?php endif; ?>
+ </div>
+
+
+</div>
+<script type="text/javascript" charset="utf-8">
+ $(function(){
+ addons_display.init({
+ jsonURL: '<?=$html->url('/collections/json')?>',
+ collViewURL: '<?=$html->url('/collection/')?>',
+ loggedIn: <?=(int)$loggedIn?>
+ });
+ $("a[rel=jquery-lightbox]").lightBox({
+ overlayOpacity: 0.6,
+ imageBlank: "<?= $html->urlImage('jquery-lightbox/lightbox-blank.gif') ?>",
+ imageLoading: "<?= $html->urlImage('jquery-lightbox/lightbox-ico-loading.gif')?>",
+ imageBtnClose: "<?= $html->urlImage('jquery-lightbox/close.png')?>",
+ imageBtnPrev: "<?= $html->urlImage('jquery-lightbox/goleft.png')?>",
+ imageBtnNext: "<?= $html->urlImage('jquery-lightbox/goright.png')?>",
+ containerResizeSpeed: 350
+ });
+
+ });
+</script>
+<!-- /#content -->
+
diff --git a/site/app/views/addons/home.thtml b/site/app/views/addons/home.thtml
new file mode 100644
index 0000000..7d79eb0
--- /dev/null
+++ b/site/app/views/addons/home.thtml
@@ -0,0 +1,180 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Andrei Hajdukewycz <sancus@off.net> (Original Author)
+ * Frederic Wenzel <fwenzel@mozilla.com>
+ * Mike Morgan <morgamic@mozilla.com>
+ * Wil Clouser <clouserw@mozilla.com>
+ * l.m.orchard <lorchard@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+// Pass a CSS class for the body tag up to the layout.
+$this->viewVars['bodyclass'] = 'home';
+?>
+
+<?php ob_start() ?>
+ <?= $javascript->link('amo2009/home.js') ?>
+<?php $this->viewVars['head_extra'] = ob_get_clean() ?>
+
+<?php /* Display locale-formatted site stats, if available (bug 492998). */ ?>
+<?php ob_start() ?>
+ <?php $lc = localeconv(); ?>
+ <ul class="stats">
+ <?php if (!empty($stats_downloaded)): ?>
+ <li><?=sprintf(
+ n___('addons_home_stats_downloaded', 'addons_home_stats_downloaded', $stats_downloaded),
+ $html->number_format($stats_downloaded, 0)
+ )?></li>
+ <?php endif ?>
+ <?php if (!empty($stats_inuse)): ?>
+ <li><?=sprintf(
+ n___('addons_home_stats_inuse', 'addons_home_stats_inuse', $stats_inuse),
+ $html->number_format($stats_inuse, 0)
+ )?></li>
+ <?php endif ?>
+ </ul>
+<?php $this->viewVars['header_extra'] = ob_get_clean() ?>
+
+<div class="secondary" role="complementary">
+ <?=$this->renderElement('amo2009/categories', array('clickable_header'=>FALSE))?>
+
+ <?php /*
+ TODO: Enable this when there's content for developer center, leaving it for
+ the markup example
+ */ ?>
+ <?php if (false): ?>
+ <div class="highlight">
+ <h3>Create a Firefox Add-on</h3>
+ <p>
+ Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do
+ eiusmod tempor incididunt ut labore et dolore magna aliqua.
+ </p>
+ <p><strong><a href="#">Visit the Developer Center</a></strong></p>
+ </div>
+ <?php endif ?>
+
+</div>
+
+<div class="primary" role="main">
+
+ <?=$this->renderElement('amo2009/search')?>
+
+ <? if(APP_ID == APP_FIREFOX): ?>
+ <?=$this->renderElement('amo2009/teaser_collections', array(
+ 'teaser_collection_promos' => $teaser_collection_promos,
+ 'promoted_collections' => $promoted_collections
+ ))?>
+ <? endif; ?>
+
+ <h2><?=___('addons_home_browse_title', 'Browse Add-ons')?></h2>
+ <div class="primary">
+ <div class="featured show-<?=$featured_type?> listing" id="featured">
+ <div class="featured-inner">
+ <div class="listing-header">
+ <ul>
+ <li<?= ('recommended'==$featured_type) ? ' class="selected"' : '' ?>>
+ <a href="?featured=recommended#featured"><?=___('addons_home_browse_recommended', 'Recommended')?></a></li>
+ <li<?= ('popular'==$featured_type) ? ' class="selected"' : '' ?>>
+ <a href="?featured=popular#featured"><?=___('addons_home_browse_popular', 'Popular')?></a></li>
+ <li<?= ('added'==$featured_type) ? ' class="selected"' : '' ?>>
+ <a href="?featured=added#featured"><?=___('addons_home_browse_new', 'Just Added')?></a></li>
+ <li<?= ('updated'==$featured_type) ? ' class="selected"' : '' ?>>
+ <a href="?featured=updated#featured"><?=___('addons_home_browse_updated', 'Updated')?></a></li>
+ </ul>
+ </div>
+ <div class="addon-listing">
+ <?=$this->renderElement('amo2009/homepage_addon_listing')?>
+ </div>
+ <script type="text/javascript">
+ $(document).ready(function(){
+ $('.listing-header a').click(function(e){
+ e.preventDefault();
+ var link = $(this);
+ link.addClass('loading');
+ $('.listing-header .selected').removeClass('selected');
+ link.parent().addClass('selected');
+ $.get('<?=$html->url('/addons/ajaxy')?>' + link.attr('href'),
+ function(content){
+ $('.addon-listing').html(content);
+ link.removeClass('loading');
+ });
+ });
+ });
+ </script>
+ </div>
+ </div>
+ </div>
+
+ <div class="secondary">
+ <img class="pull-right" src="<?=$html->url('/img/amo2009/illustrations/logo-collections-100x125.png', null, false, false)?>" alt=""/>
+ <h3><a href="<?=$html->url('/collections')?>"><?=___('addons_home_collections','Collections')?></a>
+ <span class="new indicator"><?=___('addons_home_new_indicator', 'NEW!')?></span></h3>
+ <p><?=___('addons_home_collections_intro', '
+ Collections are a way for you to categorize, mix, match and mingle
+ add-ons. Subscribe to collections created by other users or create your
+ own.
+ ')?></p>
+
+ <?php if (!empty($popular_collections)): ?>
+ <h4><?=___('addons_home_collection_popular_title', 'Popular Collections')?></h4>
+ <?php foreach ($popular_collections as $c): ?>
+ <div class="item">
+ <h5>
+ <img class="icon" src="<?=$c['icon_url']?>" width="32" height="32" alt="<?=$c['name']?>"/>
+ <?=$link->collection(array(
+ 'Collection' => array('uuid'=>$c['uuid'], 'nickname'=>$c['nickname']),
+ 'Translation' => array('name'=>array('string'=>$c['name']))
+ ))?>
+ <span><?=_('addons_home_by')?> <?=$html->linkUsersFromModel($c['authors'], null);?></span>
+ </h5>
+ <blockquote cite="#">
+ <p><?=$html->truncateChars(200, $c['description'])?></p>
+ </blockquote>
+ <div class="meta">
+ <span class="addons"><?=sprintf(
+ n___('addons_home_collections_addon_count','addons_home_collections_addon_count',$c['addons_count']),
+ $c['addons_count']
+ )?></span>
+ <span class="subscribers"><?=sprintf(
+ n___('addons_home_collections_subscribers','addons_home_collections_subscribers',$c['subscribers']),
+ $c['subscribers'])
+ ?></span>
+ </div>
+ </div>
+ <?php endforeach ?>
+ <?php endif ?>
+ <p><a class="more-info" href="<?=$html->url('/collections')?>"><?=___('addons_home_collections_all', 'View All Collections')?></a></p>
+ </div>
+</div>
diff --git a/site/app/views/addons/plugins.thtml b/site/app/views/addons/plugins.thtml
new file mode 100644
index 0000000..c6c2a64
--- /dev/null
+++ b/site/app/views/addons/plugins.thtml
@@ -0,0 +1,141 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Mike Morgan <morgamic@mozilla.com> (Original Author)
+ * Wil Clouser <clouserw@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+/**
+ * @TODO l10n for text -- holding off to see if this is the final design.
+ * We will most likely move to a dynamic version of this page pulling from the database.
+ */
+
+$this->layout='amo2009';
+
+?>
+
+<div class="secondary" role="complementary">
+ <?=$this->renderElement('amo2009/categories')?>
+</div>
+
+<div class="primary" role="main">
+ <?=$this->renderElement('amo2009/search')?>
+
+ <div class="featured listing">
+ <div class="featured-inner">
+ <div class="listing-header">
+ <p><?=_('addons_plugins_main_description')?></p>
+ </div> <!-- listing-header -->
+
+<div class="item">
+ <h2><a href="http://www.adobe.com/products/reader/">Adobe Reader</a></h2>
+ <p><?=_('addons_plugins_by')?> <a href="http://www.adobe.com/">Adobe</a></p>
+ <p>For viewing and printing Adobe Portable Document Format (PDF)</p>
+ <div class="install install-container"><p class="install-button">
+ <a class="button positive" href="http://www.adobe.com/products/acrobat/readstep2.html"> <img src="/remora/site/img/amo2009/icons/buttons/plus-green-8x9.gif" alt=""><?=sprintf(_('a_download'),'')?></a></p>
+ </div>
+ <div class="baseline"><p><img src="<?=$html->url('/img/plugins/faq_small.png',false,false,false)?>" class="faq" height="16" width="16" alt="" ><?=_('addons_plugins_support_documentation')?> <a href="http://plugindoc.mozdev.org/windows.html#Acrobat">Windows</a>, <a href="http://plugindoc.mozdev.org/linux.html#Acrobat">Linux</a>, <a href="http://plugindoc.mozdev.org/OSX.html#Acrobat">Mac OS X</a> | <a href="http://plugindoc.mozdev.org/faqs/acroread.html">Acrobat Reader FAQ</a></p></div>
+</div>
+
+<div class="item">
+ <h2><a href="http://www.adobe.com/products/flashplayer/">Adobe Flash Player</a></h2>
+ <p><?=_('addons_plugins_by')?> <a href="http://www.adobe.com/">Adobe</a></p>
+ <p>Adobe Flash Player is the universal rich client for delivering effective Adobe Flash experiences across desktops and devices.</p>
+ <div class="install install-container"><p class="install-button">
+ <a class="button positive" href="http://www.adobe.com/go/getflashplayer"><img src="/remora/site/img/amo2009/icons/buttons/plus-green-8x9.gif" alt=""><?=sprintf(_('a_download'),'')?></a></p>
+ </div>
+ <div class="baseline"><p><img src="<?=$html->url('/img/plugins/faq_small.png',false,false,false)?>" class="faq" height="16" width="16" alt="" ><?=_('addons_plugins_support_documentation')?> <a href="http://plugindoc.mozdev.org/windows.html#Flash">Windows</a>, <a href="http://plugindoc.mozdev.org/linux.html#Flash">Linux</a>, <a href="http://plugindoc.mozdev.org/OSX.html#Flash">Mac OS X</a> | <a href="http://plugindoc.mozdev.org/faqs/flash.html">Flash Player FAQ</a></p></div>
+</div>
+
+<div class="item">
+ <h2><a href="http://www.java.com/en/about/">Java</a></h2>
+ <p><?=_('addons_plugins_by')?> <a href="http://www.sun.com/">Sun Microsystems</a></p>
+ <p>The Java Runtime Environment enables your computer to run applications and applets that use Java technology.</p>
+ <div class="install install-container"><p class="install-button">
+ <a class="button positive" href="http://www.java.com/en/download/"><img src="/remora/site/img/amo2009/icons/buttons/plus-green-8x9.gif" alt=""><?=sprintf(_('a_download'),'')?></a></p>
+ </div>
+ <div class="baseline"><p><img src="<?=$html->url('/img/plugins/faq_small.png',false,false,false)?>" class="faq" height="16" width="16" alt="" ><?=_('addons_plugins_support_documentation')?> <a href="http://plugindoc.mozdev.org/windows.html#Java">Windows</a>, <a href="http://plugindoc.mozdev.org/linux.html#Java">Linux</a>, <a href="http://plugindoc.mozdev.org/OSX.html#Java">Mac OS X</a> | <a href="http://plugindoc.mozdev.org/faqs/java.html">Java Plugin FAQ</a></p></div>
+</div>
+
+<div class="item">
+ <h2><a href="http://www.apple.com/quicktime/">QuickTime</a></h2>
+ <p><?=_('addons_plugins_by')?> <a href="http://www.apple.com/">Apple</a></p>
+ <p>QuickTime Player is an easy-to-use application for playing, interacting with or viewing video, audio, VR or graphics files.</p>
+ <div class="install install-container"><p class="install-button">
+ <a class="button positive" href="http://www.apple.com/quicktime/download/"><img src="/remora/site/img/amo2009/icons/buttons/plus-green-8x9.gif" alt=""><?=sprintf(_('a_download'),'')?></a></p>
+ </div>
+ <div class="baseline"><p><img src="<?=$html->url('/img/plugins/faq_small.png',false,false,false)?>" class="faq" height="16" width="16" alt="" ><?=_('addons_plugins_support_documentation')?> <a href="http://plugindoc.mozdev.org/windows.html#Quicktime">Windows</a>, <a href="http://plugindoc.mozdev.org/OSX.html#Quicktime">Mac OS X</a></p></div>
+</div>
+
+<div class="item">
+ <h2><a href="http://www.real.com/player/">RealPlayer</a></h2>
+ <p><?=_('addons_plugins_by')?> <a href="http://www.realnetworks.com/">Real Networks</a></p>
+ <p>RealPlayer enables your computer to play streaming RealVideo and RealAudio.</p>
+ <div class="install install-container">
+ <p class="install-button"><a class="button positive" href="http://www.real.com/R/RC.040104freeplayer.def...R/forms.real.com/real/realone/realone.html?type=eva1&amp;rppr=rnwk&amp;src=040104freeplayer"><img src="/remora/site/img/amo2009/icons/buttons/plus-green-8x9.gif" alt=""><?=_('addons_plugins_for_windows')?> Version 11</a></p>
+ <p class="install-button"><a class="button positive" href="http://www.real.com/linux/"><img src="/remora/site/img/amo2009/icons/buttons/plus-green-8x9.gif" alt=""><?=_('addons_plugins_for_linux')?> Version 10</a></p>
+ <p class="install-button"><a class="button positive" href="http://www.real.com/R/RC.040104freeplayer.def...R/forms.real.com/real/realone/mac.html?rppr=rnwk&amp;src=040104freeplayer"><img src="/remora/site/img/amo2009/icons/buttons/plus-green-8x9.gif" alt=""><?=_('addons_plugins_for_macosx')?> Version 10</a></p>
+ </div>
+ <div class="baseline"><p><img src="<?=$html->url('/img/plugins/faq_small.png',false,false,false)?>" class="faq" height="16" width="16" alt="" ><?=_('addons_plugins_support_documentation')?> <a href="http://plugindoc.mozdev.org/windows.html#RealOne">Windows</a>, <a href="http://plugindoc.mozdev.org/linux.html#RealPlayer">Linux</a>, <a href="http://plugindoc.mozdev.org/OSX.html#RealOne">Mac OS X</a></p></div>
+</div>
+
+
+<div class="item">
+ <h2><a href="http://www.adobe.com/products/shockwaveplayer/">Shockwave</a></h2>
+ <p><?=_('addons_plugins_by')?> <a href="http://www.adobe.com/">Adobe</a></p>
+ <p>Shockwave Player displays Web content that has been created by Adobe Director.</p>
+ <div class="install install-container"><p class="install-button">
+ <a class="button positive" href="http://www.adobe.com/shockwave/download/"><img src="/remora/site/img/amo2009/icons/buttons/plus-green-8x9.gif" alt=""><?=sprintf(_('a_download'),'')?></a></p>
+ </div>
+ <div class="baseline"><p><img src="<?=$html->url('/img/plugins/faq_small.png',false,false,false)?>" class="faq" height="16" width="16" alt="" ><?=_('addons_plugins_support_documentation')?> <a href="http://plugindoc.mozdev.org/windows.html#Shockwave">Windows</a>, <a href="http://plugindoc.mozdev.org/OSX.html#Shockwave">Mac OS X</a></p></div>
+</div>
+
+<div class="item">
+ <h2><a href="http://www.microsoft.com/windows/windowsmedia/default.aspx">Windows Media Player</a></h2>
+ <p><?=_('addons_plugins_by')?> <a href="http://www.microsoft.com/">Microsoft</a></p>
+ <p>Windows Media Player lets you play streaming audio, video, animations, and multimedia presentations on the web.</p>
+ <div class="install install-container">
+ <p class="install-button"><a class="button positive" href="http://port25.technet.com/pages/windows-media-player-firefox-plugin-download.aspx"><img src="/remora/site/img/amo2009/icons/buttons/plus-green-8x9.gif" alt=""><?=_('addons_plugins_for_windows')?> Vers. 11 (XP, Vista)</a></p>
+ <p class="install-button"><a class="button positive" href="http://www.microsoft.com/windows/windowsmedia/9series/player.aspx"><img src="/remora/site/img/amo2009/icons/buttons/plus-green-8x9.gif" alt=""><?=_('addons_plugins_for_windows')?> Vers. 9 (98 SE, ME, 2000)</a></p>
+ <p class="install-button"><a class="button positive" href="http://www.microsoft.com/windows/windowsmedia/player/mac/default.aspx"><img src="/remora/site/img/amo2009/icons/buttons/plus-green-8x9.gif" alt=""><?=_('addons_plugins_for_macosx')?> Version 9 or QuickTime Components</a></p>
+ </div>
+ <div class="baseline"><p><img src="<?=$html->url('/img/plugins/faq_small.png',false,false,false)?>" class="faq" height="16" width="16" alt="" ><?=_('addons_plugins_support_documentation')?> <a href="http://plugindoc.mozdev.org/windows.html#WMP">Windows</a>, <a href="http://plugindoc.mozdev.org/OSX.html#WMP">Mac OS X</a></p></div>
+</div>
+
+ </div> <!-- featured-inner -->
+<h2><?=_('addons_plugins_looking_for_plugin')?></h2>
+
+<p><?=sprintf(_('addons_plugins_looking_for_more'),'<a href="http://plugindoc.mozdev.org">PluginDoc</a>')?></p>
+ </div> <!-- featured listing -->
+ </div> <!-- primary -->
diff --git a/site/app/views/addons/policy.thtml b/site/app/views/addons/policy.thtml
new file mode 100644
index 0000000..b3a136b
--- /dev/null
+++ b/site/app/views/addons/policy.thtml
@@ -0,0 +1,122 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Andrei Hajdukewycz <sancus@off.net> (Original Author)
+ * Mike Morgan <morgamic@mozilla.com>
+ * Frederic Wenzel <fwenzel@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+if (empty($policy))
+ $policy_index = 'eula';
+else
+ $policy_index = 'privacypolicy';
+?>
+
+<div class="secondary" role="complementary">
+ <?=$this->renderElement('amo2009/categories')?>
+</div>
+
+<div id="content" class="primary prose" role="main">
+
+ <h2 class="name"<?=$addon['Translation']['name']['locale_html']?>>
+ <?=$addon['Translation']['name']['string']?><?php if (empty($policy)) {?> <?=$addon['Version'][0]['Version']['version']?><? }?>
+ </h2>
+
+ <h3 class="author"> <?=_('addons_home_by')?> <?=$html->linkUsersFromModel($addon['User'], 0);?></h3>
+
+ <?php if (empty($policy)) {?>
+ <div class="addon-policy-tagline">
+ <p<?=$addon['Translation']['name']['locale_html']?>><?=sprintf(_('addons_policy_eula_require'), $addon['Translation']['name']['string']);?></p>
+ </div>
+ <?php }?>
+
+ <textarea readonly="readonly" cols="80" rows="20"<?=$addon['Translation'][$policy_index]['locale_html']?>><?=$addon['Translation'][$policy_index]['string']?></textarea>
+
+ <?php if (empty($policy)): ?>
+ <div id="addon-summary" class="condensed <?=$html->extraClass($addon)?>">
+ <?
+ global $browser_apps;
+ if (!in_array(APP_ID, $browser_apps)) {
+ $buttonMessage = ___('a_eula_download');
+ } else {
+ $buttonMessage = _('a_eula_install');
+ }
+ if (array_key_exists('collection_id', $_GET) && $this->controller->Collection->isValidUUID($_GET['collection_id'])) {
+ $_collection_uuid = $_GET['collection_id'];
+ } else {
+ $_collection_uuid = '';
+ }
+
+ $_install_render_options = array(
+ 'addon' => $addon,
+ 'addonFiles' => $addon['Version'][0]['File'],
+ 'compatible_apps' => array(),
+ 'collection_uuid' => $_collection_uuid,
+ 'addonEULA' => '', // override a EULA if it exists since this page is pulling double duty
+ 'is_latest' => $is_latest,
+ 'platforms' => $platforms,
+ 'buttonMessage' => $buttonMessage,
+ 'is_eula_page' => true
+ );
+ echo $this->renderElement('amo2009/install', $_install_render_options);
+ ?>
+ </div>
+ <!-- /.addon-summary -->
+
+ <p class="policy-link"><?=$html->link(_('a_cancel_installation'), "/addon/{$addon['Addon']['id']}");?></p>
+ <?php endif;?>
+
+ <p class="policy-link"><?=$html->link(sprintf(_('addon_review_a_back_to_addon_x'), $addon['Translation']['name']['string']), '/addon/'.$addon['Addon']['id']); ?></p>
+</div>
+<!-- /#primary -->
+
+<script type="text/javascript">
+$( function() {
+ if (window.location.href.match(/confirmed/)) {
+ var bt = $("div#content").find('.install-button a');
+ var href = $(bt).attr('href');
+ if (href)
+ if (href.match(/collection_id/)) {
+ $(bt).attr('href', href + "&confirmed");
+ } else {
+ $(bt).attr('href', href + "?confirmed");
+ }
+
+ var onclick = $(bt).attr('onclick');
+ if (onclick && onclick.match(/\.xml'\);$/))
+ $(bt).attr('onclick', onclick.replace(/\.xml'\);$/, ".xml?confirmed');"));
+ }
+ });
+</script>
diff --git a/site/app/views/addons/previews.thtml b/site/app/views/addons/previews.thtml
new file mode 100644
index 0000000..dd601d2
--- /dev/null
+++ b/site/app/views/addons/previews.thtml
@@ -0,0 +1,62 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Andrei Hajdukewycz <sancus@off.net> (Original Author)
+ * Wil Clouser <clouserw@mozilla.com>
+ * Frederic Wenzel <fwenzel@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+?>
+<div id="sidebar">
+<?=$this->renderElement('sidebar')?>
+</div>
+
+<div id="content">
+
+<? foreach ($previews as $preview): ?>
+<div class="corner-box">
+ <?php
+ $thumb = $this->controller->Image->getPreviewURL($preview['Preview']['id']);
+ $full = $this->controller->Image->getPreviewURL($preview['Preview']['id'], 'full');
+ $caption = $preview['Translation']['caption']['string'];
+ ?>
+ <h3><?=$caption?></h3>
+ <a href="<?=$full?>" rel="lightbox[previews]" title="<?=$caption?>"><img src="<?=$thumb?>" alt="" /></a>
+</div>
+<br/>
+<? endforeach; ?>
+
+<p><?=$html->link(sprintf(_('addon_review_a_back_to_addon_x'), $addon['Translation']['name']['string']), "/addon/{$addon['Addon']['id']}");?></p>
+
+</div>
diff --git a/site/app/views/addons/recommended.thtml b/site/app/views/addons/recommended.thtml
new file mode 100644
index 0000000..ab27e5a
--- /dev/null
+++ b/site/app/views/addons/recommended.thtml
@@ -0,0 +1,64 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Frederic Wenzel <fwenzel@mozilla.com> (Original Author)
+ * Wil Clouser <clouserw@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+$this->layout = 'amo2009';
+
+?>
+
+<div class="secondary" role="complementary">
+ <?=$this->renderElement('amo2009/categories')?>
+</div>
+
+<div class="primary" role="main">
+ <?=$this->renderElement('amo2009/search')?>
+ <div>
+ <?=_('addons_recommended_introduction')?>
+ </div>
+ <div class="featured listing">
+ <div class="featured-inner">
+ <div class="listing-header">
+ </div> <!-- listing-header -->
+<?php
+foreach ($addons as $addon) {
+ echo $this->renderElement('amo2009/homepage_addon', array('group'=>'recommended', 'addon' => $addon));
+}
+?>
+ </div> <!-- featured-inner -->
+ </div> <!-- featured listing -->
+</div> <!-- primary -->
diff --git a/site/app/views/addons/rss/addons.thtml b/site/app/views/addons/rss/addons.thtml
new file mode 100644
index 0000000..33328d7
--- /dev/null
+++ b/site/app/views/addons/rss/addons.thtml
@@ -0,0 +1,66 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Frederic Wenzel <fwenzel@mozilla.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+if (!isset($sort_by)) $sort_by = '';
+foreach ($addons as $addon):
+ if (!empty($addon['Version'])) {
+ // prepare version string
+ $version = $addon['Version'][0]['version'];
+ // prepare publication timestamp
+ $created = ($sort_by=='updated' ? $addon['Addon']['datestatuschanged'] : $addon['Version'][0]['created']);
+ $pubdate = $time->toRss($created);
+ // permalink to changelog/history page
+ $permalink = SITE_URL.$html->url("/addons/versions/{$addon['Addon']['id']}#version-{$version}");;
+ } else {
+ $version = '';
+ $pubdate = '';
+ $permalink = '';
+ }
+
+ // render rss feed item
+ echo $this->renderElement('rss_listitem', array(
+ 'title' => $addon['Translation']['name']['string'].' '.$version,
+ 'url' => SITE_URL.$html->url('/addon/'.$addon['Addon']['id']),
+ 'description' => $addon['Translation']['summary']['string'],
+ 'author' => $addon['User'][0]['firstname'].' '.$addon['User'][0]['lastname'],
+ 'pubDate' => $pubdate,
+ 'permalink' => $permalink
+ ));
+
+endforeach;
+?>
diff --git a/site/app/views/addons/rss/categories.thtml b/site/app/views/addons/rss/categories.thtml
new file mode 100644
index 0000000..718592f
--- /dev/null
+++ b/site/app/views/addons/rss/categories.thtml
@@ -0,0 +1,50 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Frederic Wenzel <fwenzel@mozilla.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+foreach ($tagList as $cat) {
+ $caturl = SITE_URL.$html->url("/browse/type:{$type}/cat:{$cat['Tag']['id']}");
+ echo $this->renderElement('rss_listitem', array(
+ 'title' => $cat['Translation']['name']['string'],
+ 'url' => $caturl,
+ 'description' =>$cat['Translation']['description']['string'],
+ 'author' => '',
+ 'pubDate' => $time->toRss($cat['Tag']['created']),
+ 'permalink' => $caturl
+ ));
+}
+?>
diff --git a/site/app/views/addons/rss/searchengines.thtml b/site/app/views/addons/rss/searchengines.thtml
new file mode 100644
index 0000000..6adf5a0
--- /dev/null
+++ b/site/app/views/addons/rss/searchengines.thtml
@@ -0,0 +1,48 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Frederic Wenzel <fwenzel@mozilla.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+foreach ($engines as $se) {
+ echo $this->renderElement('rss_listitem', array(
+ 'title' => $se['name'],
+ 'url' => SITE_URL.$html->url("/browse/type:".ADDON_SEARCH),
+ 'description' => $se['summary'],
+ 'author' => '',
+ 'pubDate' => $time->toRss($se['created'])
+ ));
+}
+?>
diff --git a/site/app/views/addons/rss/versions.thtml b/site/app/views/addons/rss/versions.thtml
new file mode 100644
index 0000000..017777d
--- /dev/null
+++ b/site/app/views/addons/rss/versions.thtml
@@ -0,0 +1,60 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Frederic Wenzel <fwenzel@mozilla.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+foreach ($versions as $version):
+ // prepare version string
+ if (!empty($version['Version']))
+ $itemversion = $version['Version']['version'] .' - '. strftime(_('date'), strtotime($version['Version']['created']));
+ else
+ $itemversion = '';
+
+ // prepare publication timestamp
+ $pubdate = (!empty($version['Version']['created'])) ? $time->toRss($version['Version']['created']) : '';
+
+ // render rss feed item
+ echo $this->renderElement('rss_listitem', array(
+ 'title' => $addon['Translation']['name']['string'].' '.$itemversion,
+ 'url' => SITE_URL.$html->url('/addons/versions/'.$addon['Addon']['id']),
+ 'description' => $version['Translation']['releasenotes']['string'],
+ 'author' => $addon['User'][0]['firstname'].' '.$addon['User'][0]['lastname'],
+ 'pubDate' => $pubdate,
+ 'permalink' => SITE_URL.$html->url("/addons/versions/{$addon['Addon']['id']}#version-{$version['Version']['version']}")
+ ));
+
+endforeach;
+?>
diff --git a/site/app/views/addons/searchengines.thtml b/site/app/views/addons/searchengines.thtml
new file mode 100644
index 0000000..77d6032
--- /dev/null
+++ b/site/app/views/addons/searchengines.thtml
@@ -0,0 +1,95 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Frederic Wenzel <fwenzel@mozilla.com> (Original Author)
+ * Wil Clouser <clouserw@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+$this->layout = 'amo2009';
+
+?>
+ <div class="stand-alone-options">
+ <?=$this->renderElement('amo2009/categories', array('clickable_header' => true, 'category' => 'x'))?>
+ <?=$this->renderElement('amo2009/search', array('category'=>array(ADDON_SEARCH, 0)))?>
+ </div><!-- /.stand-alone-options -->
+
+ <div class="primary" role="main">
+
+ <noscript>
+ <?=$this->renderElement('notification', array('type' => 'error', 'description' => _('addons_searchengines_error_nojavascript'))); ?>
+ </noscript>
+ <div class="featured show-recommended listing" id="featured">
+ <div class="featured-inner">
+ <div class="listing-header">
+ <ul>
+ <li class="selected"><a href="?featured=recommended#featured"><?=___('addons_home_browse_recommended', 'Recommended')?></a></li>
+ </ul>
+ </div>
+ <?php foreach ($featureAddons as $id => $addon): ?>
+ <?= $this->renderElement('amo2009/homepage_addon', array(
+ 'group' => 'recommended', 'addon' => $addon
+ )) ?>
+ <?php endforeach; ?>
+ <div class="recommended listing-footer"> </div>
+ </div>
+ </div>
+
+</div><!-- /.primary -->
+
+<div class="secondary" role="complementary">
+
+ <h3 class="compact"><?=$html->link(_('search_landing_browse_search_engines'), "/browse/type:".ADDON_SEARCH."/cat:all?sort=name", array('class'=>'view'))?></h3>
+
+ <ul class="highlight">
+ <li><?=$html->link(_('search_landing_all_search_engines'),
+ "/browse/type:".ADDON_SEARCH."/cat:all?sort=name", array('class' => 'category'))?></li>
+ <?php foreach ($subcats as $subcat): ?>
+ <li class="sub-category"><?=$html->link($subcat['Translation']['name']['string'],
+ "/browse/type:{$subcat['Tag']['addontype_id']}/cat:{$subcat['Tag']['id']}?sort=name", array('class' => 'category'))?></li>
+ <?php endforeach; ?>
+ </ul>
+
+ <h3 class="clear"><?=___('addons_searchengines_additional_resources')?></h3>
+ <div class="article prose compact">
+ <ul>
+ <li><?=$html->link(sprintf(_('category_extra_see_all'), $this_tag['Translation']['name']['string']), "/browse/type:{$this_tag['Tag']['addontype_id']}/cat:{$this_tag['Tag']['id']}?sort=name", array('class'=>'view'))?></li>
+ <li><?=sprintf(___('addons_searchengines_more'), $html->link(___('addons_searchengines_mycroft_link'), 'http://mycroft.mozdev.org/'))?></li>
+ <li><?=sprintf(___('addons_searchengines_learn_howto'),
+ $html->link(___('addons_searchengines_makeyourown_link'), 'http://developer.mozilla.org'.___('addons_searchengines_makeyourown_href')),
+ $html->link(___('addons_searchengines_devmo_link'), 'http://developer.mozilla.org/'))?></li>
+ </ul>
+ </div>
+ <div class="article prose highlight"> <?=_('addons_searchengines_thanks')?> </div>
+</div><!-- /.secondary -->
diff --git a/site/app/views/addons/share.thtml b/site/app/views/addons/share.thtml
new file mode 100644
index 0000000..9cfad8d
--- /dev/null
+++ b/site/app/views/addons/share.thtml
@@ -0,0 +1,24 @@
+<?php
+
+ $url = FULL_BASE_URL . $html->url("/addon/{$addon_id}");
+
+ $description = $html->truncateChars(250, $description);
+
+ $title = $share_title;
+
+ // Grab the URL template for the link sharing service and fill in the
+ // placeholders with the strings composed above.
+ $link_data = compact('url', 'title', 'description');
+ foreach ($link_data as $name => $value) {
+ $service_url = str_replace(
+ '{'.strtoupper($name).'}',
+ rawurlencode($value),
+ $service_url
+ );
+ }
+
+ // Finally, bounce the user off to the populated sharing URL.
+ header('HTTP/1.1 302 Found');
+ header('Location: ' . $service_url);
+ exit;
+?>
diff --git a/site/app/views/addons/themes_landing.thtml b/site/app/views/addons/themes_landing.thtml
new file mode 100644
index 0000000..f6af812
--- /dev/null
+++ b/site/app/views/addons/themes_landing.thtml
@@ -0,0 +1,75 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Frederic Wenzel <fwenzel@mozilla.com> (Original Author)
+ * Wil Clouser <wclouser@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+$this->layout = 'amo2009';
+
+?>
+ <div class="stand-alone-options">
+ <?=$this->renderElement('amo2009/categories', array('clickable_header' => true, 'category' => 'x'))?>
+ <?=$this->renderElement('amo2009/search', array('category'=>array(ADDON_THEME, 0)))?>
+ </div><!-- /.stand-alone-options -->
+
+<div class="primary" role="main">
+ <?php if (!empty($featureAddons)): ?>
+ <div class="featured show-recommended listing" id="featured">
+ <div class="featured-inner">
+ <div class="listing-header">
+ <ul>
+ <li class="selected"><a href="?featured=recommended#featured"><?=___('addons_home_browse_recommended', 'Recommended')?></a></li>
+ </ul>
+ </div>
+ <?php foreach ($featureAddons as $id => $addon): ?>
+ <?= $this->renderElement('amo2009/homepage_addon', array( 'group' => 'recommended', 'addon' => $addon)) ?>
+ <?php endforeach; ?>
+ <div class="recommended listing-footer"> </div>
+ </div>
+ </div>
+ <?php endif; /* !empty($featureAddons) */ ?>
+</div><!-- /.primary -->
+
+<div class="secondary" role="navigation">
+ <h3 class="compact"><?=$html->link(_('themes_landing_browse_themes'), "/browse/type:".ADDON_THEME."/cat:all?sort=name", array('class'=>'view'))?></h3>
+
+ <ul class="highlight">
+ <li><?=$html->link(_('themes_landing_all_themes'), "/browse/type:".ADDON_THEME."/cat:all?sort=name")?></li>
+ <?php foreach ($subcats as $subcat): ?>
+ <li class="sub-category"><?=$html->link($subcat['Translation']['name']['string'], "/browse/type:{$subcat['Tag']['addontype_id']}/cat:{$subcat['Tag']['id']}?sort=name", array('class' => 'category'))?></li>
+ <?php endforeach; ?>
+ </ul>
+</div><!-- /.secondary -->
diff --git a/site/app/views/addons/versions.thtml b/site/app/views/addons/versions.thtml
new file mode 100644
index 0000000..231756a
--- /dev/null
+++ b/site/app/views/addons/versions.thtml
@@ -0,0 +1,144 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Frederic Wenzel <fwenzel@mozilla.com> (Original Author)
+ * Justin Scott <fligtar@gmail.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+$this->viewVars['bodyclass'] = 'inverse';
+$this->layout = 'amo2009';
+
+$addonIconPath = $this->controller->Image->getAddonIconURL($addon['Addon']['id']);
+?>
+<div class="section" id="version-history">
+ <div class="stand-alone-options">
+ <?=$this->renderElement('amo2009/categories')?>
+ <?=$this->renderElement('amo2009/search')?>
+ </div>
+ <div class="primary" role="main">
+ <?=$this->renderElement('amo2009/breadcrumbs')?>
+
+ <h2><?=$subpagetitle?></h2>
+
+ <div id="latest-version-container" class="featured listing"
+ style="display:none;">
+ </div>
+
+ <?php
+ echo $this->renderElement('notification', array(
+ 'type' => 'warning',
+ 'msg' => ___('addons_versions_careful'),
+ 'description' => ___('addons_versions_careful_introduction')
+ ));
+ ?>
+
+ <div class="featured listing">
+ <?php
+ foreach ($versions as $version):
+ $_version_data = array(
+ 'addonid' => $addon['Addon']['id'],
+ 'version' => $version['Version']['version'],
+ 'created' => $version['Version']['created'],
+ 'fileSize' => $version['File'][0]['size'],
+ 'license_id' => $version['Version']['license_id']
+ );
+
+ $addon['File'] = $version['File'];
+ $addon['compatible_apps'] = $version['Compatibility'];
+
+ // determine add-on flags
+ global $experimental_status;
+ $flags = array();
+ if (in_array($version['File'][0]['status'], $experimental_status))
+ $flags[] = 'experimental';
+ ?>
+ <div class="item oldversion <?=implode(' ', $flags)?>" id="version-<?=$_version_data['version']?>">
+ <?=$this->renderElement('amo2009/install', array(
+ 'flags' => $flags,
+ 'addon' => $addon,
+ 'is_latest' => false
+ ))?>
+ <h3><?=$this->renderElement('amo2009/addon_version_detail', $_version_data)?></h3>
+
+ <?=$this->renderElement('app_compatibility', array('compatible_apps' => $version['Compatibility'])); ?>
+
+ <p<?=$version['Translation']['releasenotes']['locale_html']?>>
+ <?=nl2br($version['Translation']['releasenotes']['string'])?></p>
+
+ <?php
+ $show_license = isset($_version_data['license_id']);
+ $show_source = $addon['Addon']['viewsource'] == 1 && $this->controller->Session->check('User');
+ if ($show_license || $show_source) {
+ echo '<ul class="legal">';
+
+ if ($show_license) {
+ $license_name = $this->controller->License->getName($_version_data['license_id']);
+ $license_link = $html->link($license_name, '/versions/license/'.$version['Version']['id']);
+ echo '<li class="license">'
+ .___('addons_display_header_license').' '
+ .$license_link
+ .'</li>';
+ }
+
+ if ($show_source) {
+ echo '<li class="source">'
+ .$html->link(_('addons_display_view_source'),
+ "/files/browse/{$version['File'][0]['id']}")
+ .'</li>';
+ }
+ echo '</ul>';
+ }
+
+ ?>
+
+ </div>
+ <?php endforeach; ?>
+ </div><!-- /listing -->
+
+ <p><?=$html->link(sprintf(_('addon_review_a_back_to_addon_x'), $addon['Translation']['name']['string']), "/addon/{$addon['Addon']['id']}");?></p>
+
+ </div><!-- primary -->
+
+</div><!-- /section -->
+<script type="text/javascript">
+ $(document).ready(function() {
+ if (gIsFirefox) {
+ addons_history.init();
+ addons_history.createLatestVersionElement("<?php
+ echo addslashes(___('addon_versions_getlatestversion'))
+ ?>", "<?=addslashes(APP_PRETTYNAME)?>");
+ }
+ });
+</script>
diff --git a/site/app/views/admin/addons.thtml b/site/app/views/admin/addons.thtml
new file mode 100644
index 0000000..c961d8f
--- /dev/null
+++ b/site/app/views/admin/addons.thtml
@@ -0,0 +1,65 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * Justin Scott <fligtar@gmail.com>.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+?>
+<div id="content">
+ <?=$this->renderElement('developers/adminmenu');?>
+
+ <div id="content-main">
+ <h3>Add-on Manager</h3>
+ <form method="get">
+ <br><br>
+ <div>
+ <label>Search Add-ons:
+ <input type="text" name="q" id="addon-name"></label>
+ <input type="submit" value="Find Add-on">
+ </div><br>
+ <p><i>Enter at least 4 characters of an add-on's name for auto-completion, or enter an add-on ID in brackets (e.g. [2848])</i></p>
+
+ <script language="JavaScript" type="text/javascript">
+ $(document).ready(function() {
+ $('#addon-name').autocomplete("<?=$html->url('/admin/addonLookup')?>",
+ {
+ minChars: 4,
+ formatItem: function(row) { return '<b>' + row[0] + '</b><br><i>' + row[1] + '</i>'; },
+ formatResult: function(row) { return row[2]; }
+ });
+ });
+ </script>
+
+ </form>
+ </div>
+</div>
diff --git a/site/app/views/admin/addons_status.thtml b/site/app/views/admin/addons_status.thtml
new file mode 100644
index 0000000..4c1f122
--- /dev/null
+++ b/site/app/views/admin/addons_status.thtml
@@ -0,0 +1,85 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * Justin Scott <fligtar@gmail.com>.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+?>
+<div id="content">
+ <?=$this->renderElement('developers/adminmenu');?>
+
+ <div id="content-main">
+ <h3>Manage Add-on '<?=$addon['Translation']['name']['string']?>'</h3>
+ <?php
+ echo $html->formTag('/admin/addons/status/'.$addon['Addon']['id']);
+ echo $html->link('Public Listing', '/addon/'.$addon['Addon']['id']);
+ echo ' | '.$html->link('Edit Add-on', '/developers/addon/edit/'.$addon['Addon']['id']);
+ echo '<br />Add-on status: ';
+ echo $html->selectTag('Addon/status', $addonStatuses, $addon['Addon']['status'], null, null, false);
+ echo ' | Highest status: ';
+ echo $html->selectTag('Addon/higheststatus', $addonStatuses, $addon['Addon']['higheststatus'], null, null, false);
+
+ if (!empty($addon['Version'])) {
+ echo '<ul>';
+ foreach ($addon['Version'] as $version) {
+ $version_link = $html->link("{$version['id']}", '/editors/review/'.$version['id']);
+ echo "<li>Version {$version_link}: {$version['version']}
+ <span class='version-date-created'>".strftime(___('datetime'), strtotime($version['created']))."</span></li>";
+ if (!empty($version['File'])) {
+ echo '<ul>';
+ foreach ($version['File'] as $file) {
+ echo "<li> File ".$html->link($file['File']['id'], '/files/browse/'.$file['File']['id']).": {$platforms[$file['Platform']['id']]} - ";
+ echo $html->hidden('File/id][', array('value' => $file['File']['id']));
+ echo $html->selectTag('File/status][', $fileStatuses, $file['File']['status'], null, null, false);
+ echo ' | '.$html->link('Recalc Hash', '/admin/addons/hash/'.$addon['Addon']['id'].'/'.$file['File']['id'], array('title' => $file['File']['hash']));
+ if ($file['File']['status'] == STATUS_PUBLIC) {
+ if (defined('PUBLIC_STAGING_PATH') && file_exists(PUBLIC_STAGING_PATH.'/'.$addon['Addon']['id'].'/'.$file['File']['filename'])) {
+ echo ' | Copied';
+ }
+ else {
+ echo ' | Not Copied';
+ }
+ }
+ echo '</li>';
+ }
+ echo '</ul>';
+ }
+ }
+ echo '</ul>';
+ }
+ echo $html->submit('Update Statuses');
+ ?>
+ </form>
+ <?=$html->link('Back to Add-on Manager...', '/admin/addons')?>
+ </div>
+</div>
diff --git a/site/app/views/admin/addontypes_edit.thtml b/site/app/views/admin/addontypes_edit.thtml
new file mode 100644
index 0000000..a573a55
--- /dev/null
+++ b/site/app/views/admin/addontypes_edit.thtml
@@ -0,0 +1,58 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * Justin Scott <fligtar@gmail.com>.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+?>
+<div id="content">
+ <?=$this->renderElement('developers/adminmenu');?>
+
+ <div id="content-main">
+ <h3>Edit Add-on Type '<?=$addontype['Translation']['name']['string']?>'</h3>
+ <?php
+ if (!empty($errors['main'])) {
+ echo '<div class="error">'.$errors['main'].'</div>';
+ }
+ echo $html->formTag('/admin/addontypes/edit/'.$addontype['Addontype']['id']);
+ ?>
+ <div id="developersForm">
+ <?=$this->renderElement('developers/localebox')?>
+ <div class="buttonBox">
+ <?=$html->submit('Update Add-on Type')?>
+ </div>
+ </div>
+ </form>
+ <?=$html->link('Back to Add-on Type Manager', '/admin/addontypes')?>
+ </div>
+</div>
diff --git a/site/app/views/admin/applications.thtml b/site/app/views/admin/applications.thtml
new file mode 100644
index 0000000..5a3d1a5
--- /dev/null
+++ b/site/app/views/admin/applications.thtml
@@ -0,0 +1,82 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * Justin Scott <fligtar@gmail.com>.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+?>
+<div id="content">
+ <?=$this->renderElement('developers/adminmenu');?>
+
+ <div id="content-main">
+ <h3>Application Manager</h3>
+ <?php
+ if (!empty($errors['main'])) {
+ echo '<div class="error">'.$errors['main'].'</div>';
+ }
+
+ if (!empty($applications)) {
+ foreach ($applications as $application) {
+ $aid = $application['Application']['id'];
+ echo '<div class="groupItem">';
+ echo $html->formTag('/admin/applications/versions/'.$aid);
+ echo '<h3>'.$application['Translation']['name']['string'].' ('.$application['Translation']['shortname']['string'].')</h3>';
+ echo 'GUID: '.$application['Application']['guid'];
+ echo ' | Supported: '.(($application['Application']['supported'] == 1) ? 'Yes' : 'No');
+ echo ' | '.$html->link('Edit Application', '/admin/applications/edit/'.$aid);
+ echo '<div>';
+ echo '<label for="app'.$aid.'_remove">Remove Version:</label>';
+ echo '<select id="app'.$aid.'_remove" name="app'.$aid.'_remove">';
+ echo '<option value="">Current Versions</option>';
+ foreach ($application['Appversions'] as $appversion) {
+ echo "<option value=\"{$appversion['Appversion']['id']}\">{$appversion['Appversion']['version']}</option>";
+ }
+ echo '</select>';
+ echo $html->submit('Remove Version', array('name' => 'remove'));
+ ?>
+ </div>
+ <div>
+ <label for="app<?=$aid?>_new">Add Version:</label>
+ <input type="text" id="app<?=$aid?>_new" name="app<?=$aid?>_new" size="10"/>
+ <?=$html->submit('Add Version', array('name' => 'add'))?>
+ </div>
+ </form>
+ </div>
+ <?php
+ }
+ }
+ ?>
+ </form>
+ <?=$html->link('Create Application', '/admin/applications/create')?>
+ </div>
+</div>
diff --git a/site/app/views/admin/applications_create.thtml b/site/app/views/admin/applications_create.thtml
new file mode 100644
index 0000000..6baeeeb
--- /dev/null
+++ b/site/app/views/admin/applications_create.thtml
@@ -0,0 +1,66 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * Justin Scott <fligtar@gmail.com>.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+?>
+<div id="content">
+ <?=$this->renderElement('developers/adminmenu');?>
+
+ <div id="content-main">
+ <h3>Create Application</h3>
+ <?php
+ if (!empty($errors['main'])) {
+ echo '<div class="error">'.$errors['main'].'</div>';
+ }
+ echo $html->formTag('/admin/applications/create');
+ ?>
+ <div id="developersForm">
+ <div>
+ <label for="ApplicationGuid">Application GUID</label>
+ <?=$html->input('Application/guid', array('size' => '40'))?>
+ </div>
+ <div>
+ <?=$html->checkbox('Application/supported')?>
+ <label for="ApplicationSupported" class="nofloat">Supported Application?</label>
+ </div>
+ <?=$this->renderElement('developers/localebox')?>
+ <div class="buttonBox">
+ <?=$html->submit('Create Application')?>
+ </div>
+ </div>
+ </form>
+ <?=$html->link('Back to Application Manager', '/admin/applications')?>
+ </div>
+</div>
diff --git a/site/app/views/admin/applications_edit.thtml b/site/app/views/admin/applications_edit.thtml
new file mode 100644
index 0000000..35ed5df
--- /dev/null
+++ b/site/app/views/admin/applications_edit.thtml
@@ -0,0 +1,66 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * Justin Scott <fligtar@gmail.com>.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+?>
+<div id="content">
+ <?=$this->renderElement('developers/adminmenu');?>
+
+ <div id="content-main">
+ <h3>Edit Application '<?=$application['Translation']['name']['string']?>'</h3>
+ <?php
+ if (!empty($errors['main'])) {
+ echo '<div class="error">'.$errors['main'].'</div>';
+ }
+ echo $html->formTag('/admin/applications/edit/'.$application['Application']['id']);
+ ?>
+ <div id="developersForm">
+ <div>
+ <label for="ApplicationGuid">Application GUID</label>
+ <?=$html->input('Application/guid', array('value' => $application['Application']['guid'], 'size' => '40'))?>
+ </div>
+ <div>
+ <?=$html->checkbox('Application/supported', null, array('checked' => $application['Application']['supported']))?>
+ <label for="ApplicationSupported" class="nofloat">Supported Application?</label>
+ </div>
+ <?=$this->renderElement('developers/localebox')?>
+ <div class="buttonBox">
+ <?=$html->submit('Update Application')?>
+ </div>
+ </div>
+ </form>
+ <?=$html->link('Back to Application Manager', '/admin/applications')?>
+ </div>
+</div>
diff --git a/site/app/views/admin/collections.thtml b/site/app/views/admin/collections.thtml
new file mode 100644
index 0000000..5e128b1
--- /dev/null
+++ b/site/app/views/admin/collections.thtml
@@ -0,0 +1,46 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Wil Clouser <wclouser@mozilla.com> (Original Developer)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+?>
+<div id="content">
+ <?=$this->renderElement('developers/adminmenu');?>
+
+ <div id="content-main">
+ <h3>Collections Manager</h3>
+ <ul>
+ <li><?=$html->link('Modify the front page promotion box','/admin/collections/promobox')?></li>
+ </ul>
+ </div>
+</div>
diff --git a/site/app/views/admin/collections_promobox.thtml b/site/app/views/admin/collections_promobox.thtml
new file mode 100644
index 0000000..380b35b
--- /dev/null
+++ b/site/app/views/admin/collections_promobox.thtml
@@ -0,0 +1,112 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Wil Clouser <wclouser@mozilla.com> (Original Developer)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+ global $app_shortnames;
+
+ foreach ($titles_and_taglines as $num => $tnt) {
+ $formatted_taglines[$num] = $tnt['title'];
+ }
+
+?>
+
+<script type="text/javascript">
+ var autocompleteurl = '<?php echo $html->url('/admin/collectionLookup?s=4'); ?>';
+</script>
+
+<div id="content">
+ <?=$this->renderElement('developers/adminmenu');?>
+
+ <div id="content-main">
+ <noscript><div class="error-notice">You must enable JavaScript to use this page.</div></noscript>
+
+ <h3>Collections PromoBox Manager</h3>
+ <p>This page manages the collections that appear in the promotion box on the front page of the site. A maximum of 6 collections
+ will be shown on the front page, if more exist for a locale they will be randomly chosen. Collections specified for a locale
+ are given priority over collections specified for all locales.</p>
+
+ <? if (!empty($errors['main'])): ?>
+ <?echo $this->renderElement('notification', array('msg' => $errors['main'], 'type' => 'error')); ?>
+ <? endif; ?>
+
+ <? if (isset($changeSuccess) && $changeSuccess): ?>
+ <?echo $this->renderElement('notification', array('msg' => 'Changes Saved', 'type' => 'success')); ?>
+ <? endif; ?>
+
+ <h4>Add a New Collection</h4>
+ <?=$html->formTag('/admin/collections/promobox', 'post', array('id' => 'collection-promobox-add-form-all')); ?>
+ <?=$html->input('Collection/name', array('id' => 'collection-new', 'size' => 40));?>
+ <?=$html->simpleSelectTag('locale', $locales, null, array(), array(), false);?>
+ <?=$html->simpleSelectTag('titletagline', $formatted_taglines, null, array(), array(), false);?>
+ <input type="hidden" name="action" value="add" />
+ <?=$html->submit('Add Collection');?>
+ </form>
+
+ <hr />
+
+ <? foreach ($locales as $locale => $english_name): ?>
+ <? if (array_key_exists($locale, $promoted_collections)): ?>
+ <h4><?=$english_name?> (<?=$locale?>)</h4>
+ <ul>
+ <? foreach ($promoted_collections[$locale] as $tnt => $collections): ?>
+ <? foreach ($collections as $collection_id => $collection): ?>
+ <li>
+ <?=$html->formTag('/admin/collections/promobox', 'post', array('id' => 'collection-promobox-delete-form-all')); ?>
+ <?echo $html->submitImage('developers/delete.png', array('title'=> 'Remove', 'alt' => 'Remove')); ?>
+ <?=$html->image("developers/".array_search($collection['application_id'], $app_shortnames).".png")?>
+ (<?=$titles_and_taglines[$tnt]['title']?>) <?=$collection['name']?>
+ <input type="hidden" name="target" value="<?=$collection_id?>--<?=$tnt?>--<?=$locale?>" />
+ <input type="hidden" name="action" value="delete" />
+ </form>
+ </li>
+ <? endforeach; ?>
+ <? endforeach; ?>
+ </ul>
+ <? endif; ?>
+ <? endforeach; ?>
+
+ <script type="text/javascript">
+ $(document).ready(function() {
+ function formatItem(row) {
+ return '<b>' + row[0] + '</b> (' + row[2].substr(5) + ')<br><i>' + row[1] + '</i>';
+ }
+ function formatResult(row) {
+ return row[0] + ' [' + row[1].substr(4) + ']';
+ }
+ $('#collection-new').autocomplete("<?=$html->url('/admin/collectionLookup')?>", { minChars: 4, formatItem: formatItem, formatResult: formatResult });
+ });
+ </script>
+ </div>
+</div>
diff --git a/site/app/views/admin/config.thtml b/site/app/views/admin/config.thtml
new file mode 100644
index 0000000..dae0079
--- /dev/null
+++ b/site/app/views/admin/config.thtml
@@ -0,0 +1,142 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * Justin Scott <fligtar@gmail.com>.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+?>
+<div id="content">
+ <?=$this->renderElement('developers/adminmenu');?>
+
+ <div id="content-main">
+ <h3>Site Config</h3>
+ <?php
+ if (!empty($errors['main'])) {
+ echo '<div class="error">'.$errors['main'].'</div>';
+ }
+ echo $html->formTag('/admin/config');
+ echo $html->hidden('Session/rand', array('value' => $rand));
+ ?>
+ <div id="developersForm">
+ <h4>General</h4>
+ <div>
+ <label>Site Notice</label>
+ <div class="description">Banner that will appear at the top of every page. Default: Empty</div>
+ <?=$html->textarea('Config/site_notice', array('cols' => 50, 'rows' => 3, 'value' => $config['site_notice']))?>
+ </div>
+
+ <h4>Disable Functionality</h4>
+ <div>
+ <label>Submissions Disabled</label>
+ <div class="description">Disable add-on uploads/submissions. Default: No</div>
+ <label class="normal">
+ <input type="radio" name="data[Config][submissions_disabled]" value="0"<?=($config['submissions_disabled'] == 0) ? ' checked="checked"' : ''?>>
+ &nbsp;No
+ </label>
+ <label class="normal">
+ <input type="radio" name="data[Config][submissions_disabled]" value="1"<?=($config['submissions_disabled'] == 1) ? ' checked="checked"' : ''?>>
+ &nbsp;Yes
+ </label>
+ </div>
+ <div>
+ <label>Queues Disabled</label>
+ <div class="description">Disable all review queues. Default: No</div>
+ <label class="normal">
+ <input type="radio" name="data[Config][queues_disabled]" value="0"<?=($config['queues_disabled'] == 0) ? ' checked="checked"' : ''?>>
+ &nbsp;No
+ </label>
+ <label class="normal">
+ <input type="radio" name="data[Config][queues_disabled]" value="1"<?=($config['queues_disabled'] == 1) ? ' checked="checked"' : ''?>>
+ &nbsp;Yes
+ </label>
+ </div>
+ <div>
+ <label>Search Disabled</label>
+ <div class="description">Disable searching the site. Default: No</div>
+ <label class="normal">
+ <input type="radio" name="data[Config][search_disabled]" value="0"<?=($config['search_disabled'] == 0) ? ' checked="checked"' : ''?>>
+ &nbsp;No
+ </label>
+ <label class="normal">
+ <input type="radio" name="data[Config][search_disabled]" value="1"<?=($config['search_disabled'] == 1) ? ' checked="checked"' : ''?>>
+ &nbsp;Yes
+ </label>
+ </div>
+ <div>
+ <label>Statistics Disabled</label>
+ <div class="description">Disable the Statistics Dashboard. Default: No</div>
+ <label class="normal">
+ <input type="radio" name="data[Config][stats_disabled]" value="0"<?=($config['stats_disabled'] == 0) ? ' checked="checked"' : ''?>>
+ &nbsp;No
+ </label>
+ <label class="normal">
+ <input type="radio" name="data[Config][stats_disabled]" value="1"<?=($config['stats_disabled'] == 1) ? ' checked="checked"' : ''?>>
+ &nbsp;Yes
+ </label>
+ </div>
+ <div>
+ <label>API Disabled</label>
+ <div class="description">Disable the API. Default: No</div>
+ <label class="normal">
+ <input type="radio" name="data[Config][api_disabled]" value="0" <?=($config['api_disabled'] == 0) ? 'checked="checked"' : ''?>>
+ &nbsp;No
+ </label>
+ <label class="normal">
+ <input type="radio" name="data[Config][api_disabled]" value="1" <?=($config['api_disabled'] == 1) ? 'checked="checked"' : ''?>>
+ &nbsp;Yes
+ </label>
+ </div>
+
+
+ <h4>Special Events</h4>
+ <div>
+ <label>Firefox Notice Version</label>
+ <div class="description">If an add-on is submitted with a Firefox maxVersion lower than this, a notice will be displayed. Default: Empty</div>
+ <label class="normal">
+ <input type="text" name="data[Config][firefox_notice_version]" value="<?=$config['firefox_notice_version']?>">
+ </label>
+ </div>
+ <div>
+ <label>Firefox Notice URL</label>
+ <div class="description">URL displayed in the Firefox Version Notice text. Default: Empty</div>
+ <label class="normal">
+ <input type="text" name="data[Config][firefox_notice_url]" value="<?=$config['firefox_notice_url']?>">
+ </label>
+ </div>
+ <div class="buttonBox">
+ <?=$html->submit('Update Config')?>
+ </div>
+ </div>
+ </form>
+ </div>
+</div>
diff --git a/site/app/views/admin/config_login.thtml b/site/app/views/admin/config_login.thtml
new file mode 100644
index 0000000..cfda590
--- /dev/null
+++ b/site/app/views/admin/config_login.thtml
@@ -0,0 +1,61 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * Justin Scott <fligtar@gmail.com>.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+?>
+<div id="content">
+ <?=$this->renderElement('developers/adminmenu');?>
+
+ <div id="content-main">
+ <h3>Site Config</h3>
+ <?php
+ if (!empty($errors['main'])) {
+ echo '<div class="error">'.$errors['main'].'</div>';
+ }
+ echo $html->formTag('/admin/config');
+ ?>
+ <div id="developersForm">
+ <p>For security reasons, you must re-authenticate yourself to continue.</p>
+ <div>
+ <label>Password</label>
+ <?=$html->password('User/password')?>
+ </div>
+ <div class="buttonBox">
+ <?=$html->submit('Proceed')?>
+ </div>
+ </div>
+ </form>
+ </div>
+</div>
diff --git a/site/app/views/admin/features.thtml b/site/app/views/admin/features.thtml
new file mode 100644
index 0000000..0eaed0c
--- /dev/null
+++ b/site/app/views/admin/features.thtml
@@ -0,0 +1,130 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Wil Clouser <wclouser@mozilla.com> (Original Developer)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+?>
+<div id="content">
+ <?=$this->renderElement('developers/adminmenu');?>
+
+ <div id="content-main">
+ <h3>Feature Manager</h3>
+ <?php
+ if (!empty($errors['main'])) {
+ echo '<div class="error">'.$errors['main'].'</div>';
+ }
+
+ // Filter form
+ echo '<div>';
+ echo $html->formTag('/admin/features', 'get');
+
+ echo '<label for="locale">Locale:</label>';
+ echo '<select id="userlang" name="userlang">';
+ echo '<option value="Unspecified">Unspecified</option>';
+ foreach ($locales as $locale => $code) {
+ $_selected = ($locale == USERLANG) ? ' selected="yes" ' : '';
+ echo "<option value=\"{$locale}\" {$_selected}>{$locale}</option>";
+ }
+ echo '</select>';
+
+ echo '<label for="applications">Application:</label>';
+ echo '<select id="userapp" name="userapp">';
+ foreach ($applications as $application) {
+ $_selected = ($application['Application']['id'] == USERAPP) ? ' selected="yes" ' : '';
+ echo "<option value=\"{$application['Application']['id']}\" {$_selected}>{$application['Translation']['name']['string']}</option>";
+ }
+ echo '</select>';
+
+ echo $html->submit('Filter', array('name' => 'filter'));
+
+ echo '</form>';
+ echo '</div>';
+
+ // Features list
+ if (!empty($features)) {
+ foreach ($features as $feature) {
+
+ $fid = $feature['Feature']['id'];
+ echo '<div class="groupItem">';
+ echo $html->formTag('/admin/features/update/'.$fid);
+ echo '<h3>'.$html->link($feature['Addon']['name'], '/addon/'.$feature['Feature']['addon_id']).'</h3>';
+ echo '<div>';
+ echo '<label for="feature'.$fid.'_startdate">Start Date:</label>';
+ echo '<input type="text" id="feature'.$fid.'_startdate" name="feature'.$fid.'_startdate" value="'.$feature['Feature']['start'].'"><br />';
+ echo '<label for="feature'.$fid.'_enddate">End Date:</label>';
+ echo '<input type="text" id="feature'.$fid.'_enddate" name="feature'.$fid.'_enddate" value="'.$feature['Feature']['end'].'"><br />';
+ echo $html->submit('Save', array('name' => 'save'));
+ echo $html->submit('Remove', array('name' => 'remove'));
+ echo '</div>';
+ echo '</form>';
+ echo "</div>\n";
+ }
+ }
+ ?>
+
+ <div>
+ <h3>Create Feature</h3>
+ <?php echo $html->formTag('/admin/features/create'); ?>
+ <div id="developersForm">
+ <div>
+ <label for="addon-name">Add-on Name</label>
+ <input type="text" name="q" id="addon-name">
+ <p><i>Enter at least 4 characters or an add-on id in brackets, eg. [2848].</i></p>
+ </div>
+ <div>
+ <label for="FeatureStart">Start Date</label>
+ <?=$html->input('Feature/start', array('size' => '50'))?>
+ <p><i>(yyyy-mm-dd or blank for NOW())</i></p>
+ </div>
+ <div>
+ <label for="FeatureEnd">End Date (yyyy-mm-dd)</label>
+ <?=$html->input('Feature/end', array('size' => '50'))?>
+ <p><i>(yyyy-mm-dd or blank for NOW()+6 months)</i></p>
+ </div>
+ <script language="JavaScript" type="text/javascript">
+ $(document).ready(function() {
+ $('#addon-name').autocomplete("<?=$html->url('/admin/addonLookup?s=4')?>",
+ {
+ minChars: 4,
+ formatItem: function(row) { return '<b>' + row[0] + '</b><br><i>' + row[1] + '</i>'; },
+ formatResult: function(row) { return row[2]; }
+ });
+ });
+ </script>
+ <?=$html->submit('Add', array('name' => 'add'))?>
+ </div>
+ </form>
+ </div>
+
+ </div>
+</div>
diff --git a/site/app/views/admin/flagged_queue.thtml b/site/app/views/admin/flagged_queue.thtml
new file mode 100644
index 0000000..7e6a5dc
--- /dev/null
+++ b/site/app/views/admin/flagged_queue.thtml
@@ -0,0 +1,96 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * Justin Scott <fligtar@gmail.com>.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Wil Clouser <clouserw@gmail.com>
+ * Frederic Wenzel <fwenzel@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+?>
+<div id="content">
+ <?=$this->renderElement('developers/adminmenu');?>
+
+ <div id="content-main">
+ <h3>Flagged Add-ons</h3>
+<?php
+ if (!empty($unflagged))
+ echo '<div class="greenNotice"><b>'.$unflagged.'</b> add-ons unflagged.</div>';
+ echo $html->formTag('/admin/flagged');
+?>
+<table width="100%" id="flagged">
+ <tr class="queueHeader">
+ <td>&nbsp;</td>
+ <td><?=_('editors_th_addon')?></td>
+ <td>Review</td>
+ <td>Flagged on</td>
+ <td>Flagged by</td>
+ <td>Comments</td>
+ </tr>
+<?php
+if (!empty($addons)):
+ $i = 0;
+ foreach ($addons as &$addon):
+?>
+ <tr<?=(++$i % 2 ? '' : ' class="even"')?>>
+ <td><input type="checkbox" name="data[Addon][unflag][]" value="<?=$addon['Addon']['id']?>"/></td>
+ <td><?=sprintf('%1$s %2$s', $html->link($addon['Translation']['name']['string'], '/admin/addons/status/'.$addon['Addon']['id'])
+ , (!empty($addon['Version'])?' '.$addon['Version']['version']:''))?></td>
+
+ <?php if (!empty($addon['Version'])): ?>
+ <td><?=$html->link($html->image('developers/admin_review.png', 'width="16" height="16" alt="review version"'),
+ '/editors/review/'.$addon['Version']['id'], array('title'=>'review flagged add-on version'))?></td>
+ <?php else: ?>
+ <td>&nbsp;</td>
+ <?php endif; ?>
+
+ <?php if (!empty($addon['Approval'])): ?>
+ <td><?=$addon['Approval']['created']?></td>
+ <td><?=$addon['User']['firstname'].' '.$addon['User']['lastname']?></td>
+ <td><?=$addon['Approval']['comments']?></td>
+ <?php else: ?>
+ <td colspan="3">&nbsp;</td>
+ <?php endif; ?>
+ </tr>
+<?php endforeach; ?>
+</table>
+<p><input type="submit" value="Unflag Selected Add-ons"/></p>
+
+<?php else: ?>
+ <tr><td colspan=8 class="emptyQueue"><?=_('editors_notice_none_found')?></td></tr>
+</table>
+
+<?php endif; ?>
+
+ </form>
+ </div> <!-- corner-box -->
+</div> <!-- content-right -->
diff --git a/site/app/views/admin/groups.thtml b/site/app/views/admin/groups.thtml
new file mode 100644
index 0000000..5d757c0
--- /dev/null
+++ b/site/app/views/admin/groups.thtml
@@ -0,0 +1,93 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * Justin Scott <fligtar@gmail.com>.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+?>
+<div id="content">
+ <?=$this->renderElement('developers/adminmenu');?>
+
+ <div id="content-main">
+ <h3>Group Manager</h3>
+ <?php
+ if (!empty($errors['main'])) {
+ echo '<div class="error">'.$errors['main'].'</div>';
+ }
+
+ if (!empty($groups)) {
+ foreach ($groups as $group) {
+ $gid = $group['Group']['id'];
+ echo '<div class="groupItem">';
+ echo $html->formTag('/admin/groups/members/'.$gid);
+ echo '<h3>'.$group['Group']['name'].'</h3>';
+ echo 'Rules: '.$group['Group']['rules'];
+ echo ' | Members: '.count($group['User']);
+ if ($gid != 1) {
+ echo ' | '.$html->link('Edit Group', '/admin/groups/edit/'.$gid);
+ }
+ echo '<div>';
+ echo '<label for="group'.$gid.'_remove">Remove Member:</label>';
+ echo '<select id="group'.$gid.'_remove" name="group'.$gid.'_remove">';
+ echo '<option>Current Members</option>';
+ foreach ($group['User'] as $user) {
+ echo "<option value=\"{$user['id']}\">{$user['firstname']} {$user['lastname']} [{$user['email']}]</option>";
+ }
+ echo '</select>';
+ echo $html->submit('Remove Member', array('name' => 'remove'));
+ ?>
+ </div>
+ <div>
+ <label>Add Member:
+ <input type="text" id="group<?=$gid?>_new" name="group<?=$gid?>_new"/></label>
+ <input type="submit" id="group<?=$gid?>_submit" name="add" value="Add Member">
+ </div>
+ <script language="JavaScript" type="text/javascript">
+ $(document).ready(function() {
+ $('#group<?=$gid?>_new').autocomplete("<?=$html->url('/admin/userLookup')?>",
+ {
+ minChars: 4,
+ formatItem: function(row) { return '<b>' + row[0] + '</b><br><i>' + row[1] + '</i>'; }
+ });
+ });
+ </script>
+ </form>
+ </div>
+ <?php
+ }
+ }
+ ?>
+ </form>
+ <?=$html->link('Create Group', '/admin/groups/create')?>
+ </div>
+</div>
diff --git a/site/app/views/admin/groups_create.thtml b/site/app/views/admin/groups_create.thtml
new file mode 100644
index 0000000..4c0d5fd
--- /dev/null
+++ b/site/app/views/admin/groups_create.thtml
@@ -0,0 +1,65 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * Justin Scott <fligtar@gmail.com>.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+?>
+<div id="content">
+ <?=$this->renderElement('developers/adminmenu');?>
+
+ <div id="content-main">
+ <h3>Create Group</h3>
+ <?php
+ if (!empty($errors['main'])) {
+ echo '<div class="error">'.$errors['main'].'</div>';
+ }
+ echo $html->formTag('/admin/groups/create');
+ ?>
+ <div id="developersForm">
+ <div>
+ <label>Group Name</label>
+ <?=$html->input('Group/name')?>
+ </div>
+ <div>
+ <label>Access Rules</label>
+ <?=$html->input('Group/rules')?>
+ </div>
+ <div class="buttonBox">
+ <?=$html->submit('Create Group')?>
+ </div>
+ </div>
+ </form>
+ <?=$html->link('Back to Group Manager', '/admin/groups')?>
+ </div>
+</div>
diff --git a/site/app/views/admin/groups_edit.thtml b/site/app/views/admin/groups_edit.thtml
new file mode 100644
index 0000000..7e8c6a6
--- /dev/null
+++ b/site/app/views/admin/groups_edit.thtml
@@ -0,0 +1,67 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * Justin Scott <fligtar@gmail.com>.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+?>
+<div id="content">
+ <?=$this->renderElement('developers/adminmenu');?>
+
+ <div id="content-main">
+ <h3>Edit Group '<?=$group['Group']['name']?>'</h3>
+
+ <?php
+ if (!empty($errors['main'])) {
+ echo '<div class="error">'.$errors['main'].'</div>';
+ }
+ echo $html->formTag('/admin/groups/edit/'.$group['Group']['id']);
+ ?>
+ <div id="developersForm">
+ <div>
+ <label>Group Name</label>
+ <?=$html->input('Group/name', array('value' => (!empty($group['Group']['name']) ? $group['Group']['name'] : '')))?>
+ </div>
+ <div>
+ <label>Access Rules</label>
+ <?=$html->input('Group/rules', array('value' => (!empty($group['Group']['rules']) ? $group['Group']['rules'] : '')))?>
+ </div>
+ <div class="buttonBox">
+ <?=$html->submit('Update Group')?>
+ <?=$html->submit('Delete Group', array('name' => 'delete', 'class' => 'cancel', 'onClick' => 'return confirm(\'Are you SURE you wish to delete this group? Please cancel. :(\');'))?>
+ </div>
+ </div>
+ </form>
+ <?=$html->link('Back to Group Manager', '/admin/groups')?>
+ </div>
+</div>
diff --git a/site/app/views/admin/lists.thtml b/site/app/views/admin/lists.thtml
new file mode 100644
index 0000000..33b21cf
--- /dev/null
+++ b/site/app/views/admin/lists.thtml
@@ -0,0 +1,49 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * Justin Scott <fligtar@gmail.com>.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+?>
+<div id="content">
+ <?=$this->renderElement('developers/adminmenu');?>
+
+ <div id="content-main">
+ <h3>List Manager</h3>
+ <ul>
+ <li><h2><?=$html->link('Categories', '/admin/tags')?></h2></li>
+ <li><h2><?=$html->link('Platforms', '/admin/platforms')?></h2></li>
+ <li><h2><?=$html->link('Responses', '/admin/responses')?></h2></li>
+ </ul>
+ </div>
+</div>
diff --git a/site/app/views/admin/log_details.thtml b/site/app/views/admin/log_details.thtml
new file mode 100644
index 0000000..f210b47
--- /dev/null
+++ b/site/app/views/admin/log_details.thtml
@@ -0,0 +1,51 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * Justin Scott <fligtar@gmail.com>.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+?>
+<div id="content">
+ <?=$this->renderElement('developers/adminmenu');?>
+
+ <div id="content-main">
+ <h3>Log Entry Details</h3>
+ <?=$html->link('Back to Log', '/admin/logs')?>
+ <pre>
+ <?php
+ $notes = unserialize($entry['Eventlog']['notes']);
+ print_r($notes);
+ ?>
+ </pre>
+ </div>
+</div>
diff --git a/site/app/views/admin/logs.thtml b/site/app/views/admin/logs.thtml
new file mode 100644
index 0000000..7cf05f4
--- /dev/null
+++ b/site/app/views/admin/logs.thtml
@@ -0,0 +1,97 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * Justin Scott <fligtar@gmail.com>.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+?>
+<div id="content">
+ <?=$this->renderElement('developers/adminmenu');?>
+
+ <div id="content-main">
+ <h3>Log Viewer</h3>
+ <?=$html->formTag('/admin/logs')?>
+ Filter by type/action:
+ <select name="data[Eventlog][filter]">
+ <option value=""></option>
+ <option>admin:*</option>
+ <option>admin:addon_status</option>
+ <option>admin:addontype_edit</option>
+ <option>admin:application_create</option>
+ <option>admin:application_edit</option>
+ <option>admin:appversion_create</option>
+ <option>admin:appversion_delete</option>
+ <option>admin:file_recalchash</option>
+ <option>admin:group_create</option>
+ <option>admin:group_delete</option>
+ <option>admin:group_edit</option>
+ <option>admin:group_addmember</option>
+ <option>admin:group_removemember</option>
+ <option>admin:platform_create</option>
+ <option>admin:platform_delete</option>
+ <option>admin:platform_edit</option>
+ <option>admin:response_create</option>
+ <option>admin:response_delete</option>
+ <option>admin:response_edit</option>
+ <option>admin:tag_create</option>
+ <option>admin:tag_delete</option>
+ <option>admin:tag_edit</option>
+ <option>admin:user_edit</option>
+ <option>editor:*</option>
+ <option>editor:review_approve</option>
+ <option>editor:review_delete</option>
+ <option>l10n:*</option>
+ <option>l10n:update_addontypes</option>
+ <option>l10n:update_applications</option>
+ <option>l10n:update_platforms</option>
+ <option>l10n:update_tags</option>
+ <option>security:*</option>
+ <option>security:modify_locked_group</option>
+ <option>security:modify_other_locale</option>
+ <option>security:reauthentication_failure</option>
+ <option>user:*</option>
+ <option>user:group_associated</option>
+ </select>
+ <?=$html->submit('Filter')?>
+ </form>
+ <?php
+ if (!empty($logs)) {
+ echo '<ul>';
+ foreach ($logs as $log) {
+ echo "<li>[{$log['time']}] {$log['entry']}</li>";
+ }
+ echo '</ul>';
+ }
+ ?>
+ </div>
+</div>
diff --git a/site/app/views/admin/platforms.thtml b/site/app/views/admin/platforms.thtml
new file mode 100644
index 0000000..17bbe8d
--- /dev/null
+++ b/site/app/views/admin/platforms.thtml
@@ -0,0 +1,55 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * Justin Scott <fligtar@gmail.com>.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+?>
+<div id="content">
+ <?=$this->renderElement('developers/adminmenu');?>
+
+ <div id="content-main">
+ <h3>Platform Manager</h3>
+ <?php
+ if (!empty($platforms)) {
+ foreach ($platforms as $platform) {
+ echo '<div class="groupItem">';
+ echo '<h3>'.$platform['Translation']['name']['string'].' ('.$platform['Translation']['shortname']['string'].')</h3>';
+ echo $html->link('Edit Platform', '/admin/platforms/edit/'.$platform['Platform']['id']);
+ echo '</div>';
+ }
+ }
+ echo $html->link('Create Platform', '/admin/platforms/create');
+ ?>
+ </div>
+</div>
diff --git a/site/app/views/admin/platforms_create.thtml b/site/app/views/admin/platforms_create.thtml
new file mode 100644
index 0000000..fd53f1a
--- /dev/null
+++ b/site/app/views/admin/platforms_create.thtml
@@ -0,0 +1,58 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * Justin Scott <fligtar@gmail.com>.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+?>
+<div id="content">
+ <?=$this->renderElement('developers/adminmenu');?>
+
+ <div id="content-main">
+ <h3>Create Platform</h3>
+ <?php
+ if (!empty($errors['main'])) {
+ echo '<div class="error">'.$errors['main'].'</div>';
+ }
+ echo $html->formTag('/admin/platforms/create');
+ ?>
+ <div id="developersForm">
+ <?=$this->renderElement('developers/localebox')?>
+ <div class="buttonBox">
+ <?=$html->submit('Create Platform')?>
+ </div>
+ </div>
+ </form>
+ <?=$html->link('Back to Platform Manager', '/admin/platforms')?>
+ </div>
+</div>
diff --git a/site/app/views/admin/platforms_edit.thtml b/site/app/views/admin/platforms_edit.thtml
new file mode 100644
index 0000000..e38ca2b
--- /dev/null
+++ b/site/app/views/admin/platforms_edit.thtml
@@ -0,0 +1,59 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * Justin Scott <fligtar@gmail.com>.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+?>
+<div id="content">
+ <?=$this->renderElement('developers/adminmenu');?>
+
+ <div id="content-main">
+ <h3>Edit Platform '<?=$platform['Translation']['name']['string']?>'</h3>
+ <?php
+ if (!empty($errors['main'])) {
+ echo '<div class="error">'.$errors['main'].'</div>';
+ }
+ echo $html->formTag('/admin/platforms/edit/'.$platform['Platform']['id']);
+ ?>
+ <div id="developersForm">
+ <?=$this->renderElement('developers/localebox')?>
+ <div class="buttonBox">
+ <?=$html->submit('Update Platform')?>
+ <?=$html->submit('Delete Platform', array('name' => 'delete', 'class' => 'cancel', 'onClick' => 'return confirm(\'Are you SURE you wish to delete this platform?\');'))?>
+ </div>
+ </div>
+ </form>
+ <?=$html->link('Back to Platform Manager', '/admin/platforms')?>
+ </div>
+</div>
diff --git a/site/app/views/admin/responses.thtml b/site/app/views/admin/responses.thtml
new file mode 100644
index 0000000..b5fa144
--- /dev/null
+++ b/site/app/views/admin/responses.thtml
@@ -0,0 +1,56 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * Justin Scott <fligtar@gmail.com>.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+?>
+<div id="content">
+ <?=$this->renderElement('developers/adminmenu');?>
+
+ <div id="content-main">
+ <h3>Canned Response Manager</h3>
+ <?php
+ if (!empty($responses)) {
+ foreach ($responses as $response) {
+ echo '<div class="groupItem">';
+ echo '<h3>'.$response['Translation']['name']['string'].'</h3>';
+ echo $response['Translation']['response']['string'];
+ echo '<br>'.$html->link('Edit Response', '/admin/responses/edit/'.$response['Cannedresponse']['id']);
+ echo '</div>';
+ }
+ }
+ echo $html->link('Create Response', '/admin/responses/create');
+ ?>
+ </div>
+</div>
diff --git a/site/app/views/admin/responses_create.thtml b/site/app/views/admin/responses_create.thtml
new file mode 100644
index 0000000..8f0476d
--- /dev/null
+++ b/site/app/views/admin/responses_create.thtml
@@ -0,0 +1,58 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * Justin Scott <fligtar@gmail.com>.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+?>
+<div id="content">
+ <?=$this->renderElement('developers/adminmenu');?>
+
+ <div id="content-main">
+ <h3>Create Canned Response</h3>
+ <?php
+ if (!empty($errors['main'])) {
+ echo '<div class="error">'.$errors['main'].'</div>';
+ }
+ echo $html->formTag('/admin/responses/create');
+ ?>
+ <div id="developersForm">
+ <?=$this->renderElement('developers/localebox')?>
+ <div class="buttonBox">
+ <?=$html->submit('Create Response')?>
+ </div>
+ </div>
+ </form>
+ <?=$html->link('Back to Response Manager', '/admin/responses')?>
+ </div>
+</div>
diff --git a/site/app/views/admin/responses_edit.thtml b/site/app/views/admin/responses_edit.thtml
new file mode 100644
index 0000000..b9a152f
--- /dev/null
+++ b/site/app/views/admin/responses_edit.thtml
@@ -0,0 +1,59 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * Justin Scott <fligtar@gmail.com>.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+?>
+<div id="content">
+ <?=$this->renderElement('developers/adminmenu');?>
+
+ <div id="content-main">
+ <h3>Edit Canned Response '<?=$response['Translation']['name']['string']?>'</h3>
+ <?php
+ if (!empty($errors['main'])) {
+ echo '<div class="error">'.$errors['main'].'</div>';
+ }
+ echo $html->formTag('/admin/responses/edit/'.$response['Cannedresponse']['id']);
+ ?>
+ <div id="developersForm">
+ <?=$this->renderElement('developers/localebox')?>
+ <div class="buttonBox">
+ <?=$html->submit('Edit Response')?>
+ <?=$html->submit('Delete Response', array('name' => 'delete', 'class' => 'cancel', 'onClick' => 'return confirm(\'Are you SURE you wish to delete this response?\');'))?>
+ </div>
+ </div>
+ </form>
+ <?=$html->link('Back to Response Manager', '/admin/responses')?>
+ </div>
+</div>
diff --git a/site/app/views/admin/serverstatus.thtml b/site/app/views/admin/serverstatus.thtml
new file mode 100644
index 0000000..8360f75
--- /dev/null
+++ b/site/app/views/admin/serverstatus.thtml
@@ -0,0 +1,101 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Mike Morgan <morgamic@mozilla.com> (Original Author)
+ * Justin Scott <fligtar@gmail.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+?>
+<div id="content">
+ <?=$this->renderElement('developers/adminmenu');?>
+
+ <div id="content-main">
+ <h3>Memcache Status</h3>
+
+<?php
+if (defined('QUERY_CACHE') && QUERY_CACHE) {
+ foreach ($data['memcache'] as $server=>$stats) {
+ echo '<div class="corner-box">';
+ echo "<h3>{$server}</h3>";
+ if (!empty($stats) && is_array($stats)) {
+ echo '<ul>';
+ echo '<li>Gets: '.$stats['get_hits'].'</li>';
+ echo '<li>Misses: '.$stats['get_misses'].'</li>';
+ echo '<li>Total Gets: '.($stats['get_hits']+$stats['get_misses']).'</li>';
+ echo '<li>Hit %: '.$stats['get_hits']*100/($stats['get_hits']+$stats['get_misses']).'</li>';
+ echo '<li>Quota %: '.$stats['bytes']*100/$stats['limit_maxbytes'].'</li>';
+ echo '</ul>';
+ echo '<ul>';
+ foreach ($stats as $key=>$val) {
+ echo "<li>{$key}: {$val}</li>";
+ }
+ echo '</ul>';
+ } else {
+ echo "<ul><li>Failed to connect to {$server}</li></ul>";
+ }
+ echo '</div>';
+ }
+} else {
+ echo '<p>Memcache is not enabled (QUERY_CACHE is false).</p>';
+}
+?>
+
+
+ <h3>Memcache Flush</h3>
+ <p>Use this to expire all memcache entries. Please use this responsibly.</p>
+ <form action="<?=$html->url('/admin/serverflush',false)?>" method="post">
+ <?=$html->hiddenSession() ?>
+ <p><input type="submit" name="submit" value="Flush Me Baby" class="memcacheflush"/></p>
+ </form>
+
+ <script type="text/javascript">
+ $('.memcacheflush').click(function(){
+ return confirm('Are you sure you want to flush memcache?');
+ });
+ </script>
+
+
+ <h3>SVN Revision</h3>
+ <p>
+<?php
+ if (defined('REVISION')) {
+ echo REVISION;
+ } else {
+ echo 'Not available.';
+ }
+
+?>
+ </p>
+ </div>
+</div>
diff --git a/site/app/views/admin/summary.thtml b/site/app/views/admin/summary.thtml
new file mode 100644
index 0000000..30c8c46
--- /dev/null
+++ b/site/app/views/admin/summary.thtml
@@ -0,0 +1,125 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * Justin Scott <fligtar@gmail.com>.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+?>
+<div id="content">
+ <?=$this->renderElement('developers/adminmenu');?>
+
+ <div id="content-main">
+ <h3>Admin Summary</h3>
+ <table class="stats">
+ <tr>
+ <td class="heading" colspan=2>Most Translations</td>
+ </tr>
+ <?php
+ foreach ($topLocales as $topLocale) {
+ echo '<tr>';
+ echo '<td class="title">'.$topLocale['translations']['locale'].'</td>';
+ echo '<td class="value">'.$topLocale[0]['total'].'</td>';
+ echo '</tr>';
+ }
+ ?>
+ </table>
+
+ <table class="stats">
+ <tr>
+ <td class="heading" colspan=2>Last 24 Hours</td>
+ </tr>
+ <tr>
+ <td class="title">New Add-ons</td>
+ <td class="value"><?=$last24['newAddons'][0][0]['COUNT(*)']?></td>
+ </tr>
+ <tr>
+ <td class="title">Updated Add-ons</td>
+ <td class="value"><?=$last24['updatedAddons'][0][0]['COUNT(*)']?></td>
+ </tr>
+ <tr>
+ <td class="title">New Versions</td>
+ <td class="value"><?=$last24['versions'][0][0]['COUNT(*)']?></td>
+ </tr>
+ <tr>
+ <td class="title">New Users</td>
+ <td class="value"><?=$last24['users'][0][0]['COUNT(*)']?></td>
+ </tr>
+ <tr>
+ <td class="title">New Reviews</td>
+ <td class="value"><?=$last24['reviews'][0][0]['COUNT(*)']?></td>
+ </tr>
+ </table>
+
+ <table class="stats">
+ <tr>
+ <td class="heading" colspan=2>Total Counts</td>
+ </tr>
+ <tr>
+ <td class="title">Extensions</td>
+ <td class="value"><?=$count['extensions'][0][0]['COUNT(*)']?></td>
+ </tr>
+ <tr>
+ <td class="title">Themes</td>
+ <td class="value"><?=$count['themes'][0][0]['COUNT(*)']?></td>
+ </tr>
+ <tr>
+ <td class="title">Dictionaries</td>
+ <td class="value"><?=$count['dictionaries'][0][0]['COUNT(*)']?></td>
+ </tr>
+ <tr>
+ <td class="title">Search Plugins</td>
+ <td class="value"><?=$count['searchengines'][0][0]['COUNT(*)']?></td>
+ </tr>
+ <tr>
+ <td class="title">Current Sessions</td>
+ <td class="value"><?=$count['activeSessions'][0][0]['COUNT(*)']?></td>
+ </tr>
+ </table>
+ <br>
+ <table width="100%" class="log">
+ <tr>
+ <td class="heading" colspan=2>Recent Admin Activity</td>
+ </tr>
+ <?php
+ if (!empty($logs)) {
+ foreach ($logs as $log) {
+ echo '<tr>';
+ echo '<td class="value" style="font-size: 80%;">'.$log['time'].'</td>';
+ echo '<td class="title">'.$log['entry'].'</td>';
+ echo '</tr>';
+ }
+ }
+ ?>
+ </table>
+ </div>
+</div>
diff --git a/site/app/views/admin/tags.thtml b/site/app/views/admin/tags.thtml
new file mode 100644
index 0000000..5aa620c
--- /dev/null
+++ b/site/app/views/admin/tags.thtml
@@ -0,0 +1,59 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * Justin Scott <fligtar@gmail.com>.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+?>
+<div id="content">
+ <?=$this->renderElement('developers/adminmenu');?>
+
+ <div id="content-main">
+ <h3>Category Manager</h3>
+ <?php
+ if (!empty($tags)) {
+ foreach ($tags as $tag) {
+ echo '<div class="groupItem">';
+ echo '<h3>'.$tag['Translation']['name']['string'].'</h3>';
+ echo $tag['Translation']['description']['string'];
+ echo '<br>Application: '.$tag['application'];
+ echo ' | Add-on type: '.$tag['addontype'];
+ echo ' | Add-on Count: '.$tag['count'];
+ echo ' | '.$html->link('Edit Category', '/admin/tags/edit/'.$tag['Tag']['id']);
+ echo '</div>';
+ }
+ }
+ echo $html->link('Create Category', '/admin/tags/create');
+ ?>
+ </div>
+</div>
diff --git a/site/app/views/admin/tags_create.thtml b/site/app/views/admin/tags_create.thtml
new file mode 100644
index 0000000..c95a1cf
--- /dev/null
+++ b/site/app/views/admin/tags_create.thtml
@@ -0,0 +1,66 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * Justin Scott <fligtar@gmail.com>.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+?>
+<div id="content">
+ <?=$this->renderElement('developers/adminmenu');?>
+
+ <div id="content-main">
+ <h3>Create Category</h3>
+ <?php
+ if (!empty($errors['main'])) {
+ echo '<div class="error">'.$errors['main'].'</div>';
+ }
+ echo $html->formTag('/admin/tags/create');
+ ?>
+ <div id="developersForm">
+ <div>
+ <label for="TagApplicationId">Application</label>
+ <?=$html->selectTag('Tag/application_id', $applications, null, null, null, false)?>
+ </div>
+ <div>
+ <label for="TagAddontypeId">Add-on Type</label>
+ <?=$html->selectTag('Tag/addontype_id', $addontypes, null, null, null, false)?>
+ </div>
+ <?=$this->renderElement('developers/localebox')?>
+ <div class="buttonBox">
+ <?=$html->submit('Create Category')?>
+ </div>
+ </div>
+ </form>
+ <?=$html->link('Back to Category Manager', '/admin/tags')?>
+ </div>
+</div>
diff --git a/site/app/views/admin/tags_edit.thtml b/site/app/views/admin/tags_edit.thtml
new file mode 100644
index 0000000..e252282
--- /dev/null
+++ b/site/app/views/admin/tags_edit.thtml
@@ -0,0 +1,71 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * Justin Scott <fligtar@gmail.com>.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+?>
+<div id="content">
+ <?=$this->renderElement('developers/adminmenu');?>
+
+ <div id="content-main">
+ <h3>Edit Category '<?=$tag['Translation']['name']['string']?>'</h3>
+ <?php
+ if (!empty($errors['main'])) {
+ echo '<div class="error">'.$errors['main'].'</div>';
+ }
+ echo $html->formTag('/admin/tags/edit/'.$tag['Tag']['id']);
+ ?>
+ <div id="developersForm">
+ <div>
+ <label for="TagApplicationId">Application</label>
+ <?=$html->selectTag('Tag/application_id', $applications, $tag['Tag']['application_id'], null, null, false)?>
+ </div>
+ <div>
+ <label for="TagAddontypeId">Add-on Type</label>
+ <?=$html->selectTag('Tag/addontype_id', $addontypes, $tag['Tag']['addontype_id'], null, null, false)?>
+ </div>
+ <div>
+ <label for="TagWeightId">Category Weight (<small>sort-order</small>)</label>
+ <?=$html->input('Tag/weight', array('value' => $tag['Tag']['weight']))?>
+ </div>
+ <?=$this->renderElement('developers/localebox')?>
+ <div class="buttonBox">
+ <?=$html->submit('Update Category')?>
+ <?=$html->submit('Delete Category', array('name' => 'delete', 'class' => 'cancel', 'onClick' => 'return confirm(\'Are you SURE you wish to delete this category?\');'))?>
+ </div>
+ </div>
+ </form>
+ <?=$html->link('Back to Category Manager', '/admin/tags')?>
+ </div>
+</div>
diff --git a/site/app/views/admin/userlookup.thtml b/site/app/views/admin/userlookup.thtml
new file mode 100644
index 0000000..ac4bc10
--- /dev/null
+++ b/site/app/views/admin/userlookup.thtml
@@ -0,0 +1,10 @@
+<?php
+header('Content-type: text/plain');
+define('NO_MICROTIME', true);
+
+if (count($results) > 0) {
+ foreach ($results as $result) {
+ echo "{$result}\n";
+ }
+}
+?>
diff --git a/site/app/views/admin/users.thtml b/site/app/views/admin/users.thtml
new file mode 100644
index 0000000..87a9a6d
--- /dev/null
+++ b/site/app/views/admin/users.thtml
@@ -0,0 +1,65 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Justin Scott <fligtar@mozilla.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+?>
+<div id="content">
+ <?=$this->renderElement('developers/adminmenu');?>
+
+ <div id="content-main">
+ <h3>User Manager</h3>
+ <form method="get">
+ <br><br>
+ <div>
+ <label>Search Users:
+ <input type="text" name="q" id="user"></label>
+ <input type="submit" name="Find User">
+ </div><br>
+ <p><i>Enter at least 4 characters of the user's e-mail address for auto-completion.</i></p>
+
+ <script language="JavaScript" type="text/javascript">
+ function formatItem(row) {
+ return '<b>' + row[0] + '</b><br><i>' + row[1] + '</i>';
+ }
+
+ $(document).ready(function() {
+ $('#user').autocomplete("<?=$html->url('/admin/userLookup')?>", { minChars: 4, formatItem: formatItem });
+ });
+ </script>
+
+ </form>
+ </div>
+</div>
diff --git a/site/app/views/admin/users_edit.thtml b/site/app/views/admin/users_edit.thtml
new file mode 100644
index 0000000..ae76037
--- /dev/null
+++ b/site/app/views/admin/users_edit.thtml
@@ -0,0 +1,148 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Justin Scott <fligtar@mozilla.com> (Original Author)
+ * Frederic Wenzel <fwenzel@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+
+/* Prepare translation box element */
+// Retrieve language arrays from bootstrap.
+global $valid_languages, $native_languages;
+foreach (array_keys($valid_languages) as $key) {
+ $languages[$key] = $native_languages[$key]['native'];
+}
+ksort($languages);
+$this->translationBox = array(
+ 'defaultLocale' => LANG,
+ 'languages' => $languages,
+ 'table' => 'User',
+ 'loaded' => false
+);
+?>
+<div id="content">
+ <?=$this->renderElement('developers/adminmenu');?>
+
+ <div id="content-main">
+ <h3>Edit User '<?=$user['User']['email']?>'</h3>
+ <?php
+ if (!empty($errors['main'])) {
+ echo '<div class="error">'.$errors['main'].'</div>';
+ }
+ echo $html->formTag('/admin/users/'.$user['User']['id']);
+ ?>
+ <div id="developersForm">
+ <div>
+ <label>User ID</label>
+ <?=$html->link($user['User']['id'], "/user/{$user['User']['id']}")?>
+ </div>
+ <div>
+ <label for="UserEmail">E-mail Address</label>
+ <?=$html->input('User/email', array('value' => $user['User']['email']))?>
+ </div>
+ <div>
+ <label for="UserFirstname"><?=_('user_form_firstname')?></label>
+ <?=$html->input('User/firstname', array('value' => $user['User']['firstname'])) ?>
+ <?=$html->tagErrorMsg('User/firstname', _('error_field_required'))?>
+ </div>
+ <div>
+ <label for="UserLastname"><?=_('user_form_lastname')?></label>
+ <?=$html->input('User/lastname', array('value' => $user['User']['lastname'])) ?>
+ <?=$html->tagErrorMsg('User/lastname', _('error_field_required'))?>
+ </div>
+ <div>
+ <label for="UserNickname"><?=_('user_form_nickname')?></label>
+ <?=$html->input('User/nickname', array('value' => $user['User']['nickname'])) ?>
+ <?=$html->tagErrorMsg('User/nickname', _('error_user_nickname_notunique'))?>
+ </div>
+ <div>
+ <label for="UserEmailhidden"><?=_('user_form_hideemail')?></label>
+ <?=$html->checkBox('User/emailhidden', null, array('checked' => ($user['User']['emailhidden'] ? 'checked' : false), 'value' => 1)) ?>
+ </div>
+ <div>
+ <label for="UserSandboxshown"><?=_('user_form_showsandbox')?></label>
+ <?=$html->checkBox('User/sandboxshown', null, array('checked' => ($user['User']['sandboxshown'] ? 'checked' : false), 'value' => 1)) ?>
+ </div>
+ <div>
+ <label for="UserHomepage"><?=_('user_form_homepage')?></label>
+ <?=$html->input('User/homepage', array('value' => $user['User']['homepage'])) ?>
+ <?=$html->tagErrorMsg('User/homepage', _('error_invalid_url'))?>
+ </div>
+
+ <div>
+ <?php
+ echo $this->renderElement('translationbox', array(
+ 'field' => 'bio',
+ 'translations' => $translations['bio'],
+ 'height' => '100',
+ 'maxLength' => '500',
+ 'displayName' => ___('user_form_bio'),
+ 'description' => ___('user_form_bio_description'),
+ ));
+ ?>
+ </div>
+
+ <div>
+ <label for="UserConfirmationCode">Confirmation Code</label>
+ <?=$html->input('User/confirmationcode', array('value' => $user['User']['confirmationcode'])) ?>
+ </div>
+
+ <div>
+ <label for="UserNotes">Notes</label>
+ <?=$html->textarea('User/notes', array('value' => $user['User']['notes'], 'cols' => 60, 'rows' => 3)) ?>
+ </div>
+
+ <div class="buttonBox">
+ <?=$html->submit('Update User')?>
+ </div>
+ </div>
+ </form>
+
+ <div class="corner-box">
+ <h3>Delete User '<?=$user['User']['email']?>'</h3>
+ <?=$html->formTag('/admin/users/'.$user['User']['id'].'/delete');?>
+ <div class="amo-form">
+ <p>
+ <input type="radio" name="deletetype" value="all" id="deletetype_all" />&nbsp;<label for="deletetype_all"><strong>Delete</strong> user and <strong>remove</strong> all their reviews/ratings (must not be an add-on author)</label><br/>
+ <input type="radio" name="deletetype" value="anon" id="deletetype_anon" />&nbsp;<label for="deletetype_anon">Make user <strong>anonymous</strong> and <strong>keep</strong> their reviews/ratings</label>
+ </p>
+ <p><?=$html->submit('Delete user account now'); ?></p>
+ </div>
+ </form>
+ </div>
+
+ <p><?=$html->link('Back to User Manager', '/admin/users')?></p>
+ </div>
+</div>
diff --git a/site/app/views/admin/variables.thtml b/site/app/views/admin/variables.thtml
new file mode 100644
index 0000000..22809b9
--- /dev/null
+++ b/site/app/views/admin/variables.thtml
@@ -0,0 +1,57 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * Wil Clouser <wclouser@mozilla.com>.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+?>
+<div id="content">
+ <?=$this->renderElement('developers/adminmenu');?>
+
+ <div id="content-main">
+ <h3>Constants</h3>
+ <div>
+ <?php
+ foreach ($constants as $var => $val) {
+ if ($val === true) {
+ $val = '<em>true</em>';
+ }
+ if ($val === false) {
+ $val = '<em>false</em>';
+ }
+ echo "<b>{$var}</b>: {$val}<br />";
+ }
+ ?>
+ </div>
+ </div>
+</div>
diff --git a/site/app/views/api/addon.thtml b/site/app/views/api/addon.thtml
new file mode 100644
index 0000000..7482805
--- /dev/null
+++ b/site/app/views/api/addon.thtml
@@ -0,0 +1,44 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Laura Thomson <lthomson@mozilla.com> (Original Author)
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+ if (isset($error)) { ?>
+ <error><?php echo ($error); ?></error>
+<?php
+ } else {
+ include 'api_addon.thtml';
+ }
+
+?>
diff --git a/site/app/views/api/api_addon.thtml b/site/app/views/api/api_addon.thtml
new file mode 100644
index 0000000..a1dcf4c
--- /dev/null
+++ b/site/app/views/api/api_addon.thtml
@@ -0,0 +1,167 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Laura Thomson <lthomson@mozilla.com> (Original Author)
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+ if (empty($addonIconPath)) {
+ $addonIconPath = ($addon['Addon']['addontype_id'] == ADDON_THEME ? $html->urlImage(DEFAULT_THEME_ICON) : $html->urlImage(DEFAULT_ADDON_ICON));
+ }
+
+ $amo = 'https://addons.mozilla.org';
+?>
+<addon>
+ <?php
+ // Allow some additional content to be injected into the addon element by
+ // the including template.
+ if (isset($addon_pre)) echo $addon_pre;
+ ?>
+ <name><?php echo $addon['Translation']['name']['string']; ?></name>
+ <type id='<?php echo $addon['Addon']['addontype_id']; ?>'><?php echo Addontype::getName($addon['Addon']['addontype_id']); ?></type>
+ <guid><?php echo $addon['Addon']['guid']; ?></guid>
+ <version><?php echo $addon['install_version']; ?></version>
+ <status id='<?php echo $addon['Addon']['status']; ?>'><?php if ($addon['Addon']['status'] == STATUS_PUBLIC) {
+ echo rtrim(_('a_header_public'));
+ } else {
+ echo rtrim(_('a_header_sandbox'));
+ }
+ ?></status>
+ <authors>
+<?php
+ foreach ($addon['User'] as $author) {
+ $authorName = (!empty($author['nickname'])) ? $author['nickname'] : $author['firstname'].' '.$author['lastname'];
+?>
+ <author><?php echo $authorName; ?></author>
+<?php
+ }
+?> </authors>
+ <summary><?php echo $addon['Translation']['summary']['string']; ?></summary>
+ <description><?php echo $addon['Translation']['description']['string']; ?></description>
+ <icon><?php if (isset($addon['Icon'])) {
+ echo $amo.$addon['Icon'];
+ } else {
+ $addonIconPath = ($addon['Addon']['addontype_id'] == ADDON_THEME ? $html->urlImage(DEFAULT_THEME_ICON) : $html->urlImage(DEFAULT_ADDON_ICON));
+ echo $amo.$addonIconPath;
+ } ?></icon>
+ <compatible_applications>
+<?php
+ foreach ($addon['Compatible_apps'] as $app) {
+ $name = $app_names[$app['Application']['application_id']];
+?>
+ <application>
+ <name><?php echo $name; ?></name>
+ <application_id><?php echo $app['Application']['application_id']; ?></application_id>
+ <min_version><?php echo $app['Min_Version']['version']; ?></min_version>
+ <max_version><?php echo $app['Max_Version']['version']; ?></max_version>
+<?php
+ if ($api_version > 1) { ?>
+ <appID><?php echo $guids[$name]; ?></appID>
+ <?php } ?>
+ </application>
+ <?php
+ }
+?> </compatible_applications>
+<?php if ($api_version >0 ) { ?>
+ <all_compatible_os>
+ <?php foreach ($addon['all_compatible_os'] as $os) {
+ ?><os><?php
+ echo
+ $os_translation[$os['Translation']['name']['string']];
+ ?></os><?php
+ }
+ ?>
+ </all_compatible_os>
+ <?php } else { ?>
+ <compatible_os><?php echo $addon['Platforms']['Translation']['name']['string']; ?></compatible_os>
+ <?php } ?>
+ <eula><?php echo $addon['Translation']['eula']['string'];?></eula>
+ <thumbnail><?php echo $amo.$addon['Thumbnail']; ?></thumbnail>
+ <rating><?php
+ $rating ='';
+ if (isset($addon['Addon']['averagerating'])) {
+ $rating = $addon['Addon']['averagerating'];
+ if ($api_version < 1) {
+ // we need to double the rating since the addons mgr expects it to
+ // be out of 10 and we have halved everything in the db
+ $rating *= 2;
+ }
+ // round rating to match stars in AMO
+ $rating = ceil($rating);
+ }
+ echo $rating;
+ ?></rating>
+<?php
+// get rid of reviews for now
+/*
+ <reviews url='<?php echo $amo
+ .'/reviews/display/'.$addon['Addon']['id']; ?>'>
+ <?php
+ if (count($addon['Reviews'])) {
+ foreach($addon['Reviews'] as $review) { ?>
+ <review>
+ <id><?php echo $review['Review']['id'];?></id>
+ <version_id><?php echo $review['Review']['version_id'];?></version_id>
+ <created><?php echo $review['Review']['created'];?></created>
+ <rating><?php echo $review['Review']['rating'];?></rating>
+ <user>
+ <id><?php echo $review['User']['id'];?></id>
+ <nickname><?php echo $review['User']['nickname'];?></nickname>
+ <firstname><?php echo $review['User']['firstname'];?></firstname>
+ <lastname><?php echo $review['User']['lastname'];?></lastname>
+ </user>
+ <title locale='<?php echo $review['Translation']['title']['locale'];?>'><?php echo $review['Translation']['title']['string'];?></title>
+ <body locale='<?php echo $review['Translation']['body']['locale'];?>'><?php echo $review['Translation']['body']['string'];?></body>
+ </review>
+ <?php }
+ }?>
+ </reviews>
+*/ ?>
+ <learnmore><?php echo $amo.'/addon/'.$addon['Addon']['id']; ?>?src=api</learnmore>
+<?php if ($api_version > 0 ) {
+ foreach($addon['fileinfo'] as $file) {?>
+ <install hash='<?php echo $file['File']['hash'];?>'
+ os='<?php echo $os_translation[$file['Platform']['apiname']]; ?>'><?php
+ echo $amo.'/downloads/file/'.$file['File']['id'].'/'
+ .$file['File']['filename']; ?></install>
+ <?php }
+ } else { ?>
+ <install hash='<?php echo $addon['File']['hash'];?>'><?php echo $amo.'/downloads/file/'.$addon['File']['id'].'/'.$addon['File']['filename']; ?>?src=api</install>
+<?php
+} ?>
+<?php
+ // Allow some additional content to be injected into the addon element by
+ // the including template.
+ if (isset($addon_post)) echo $addon_post;
+?>
+</addon>
diff --git a/site/app/views/api/collections_feed.thtml b/site/app/views/api/collections_feed.thtml
new file mode 100644
index 0000000..3e856ff
--- /dev/null
+++ b/site/app/views/api/collections_feed.thtml
@@ -0,0 +1,153 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * l.m.orchard <lorchard@mozilla.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+if (isset($error)) { ?>
+<error><?php echo ($error); ?></error>
+<?php
+} else {
+?>
+<collection>
+ <id><?php echo $feed_id ?></id>
+ <name><?php echo $feed_name ?></name>
+ <description><?php echo $feed_description ?></description>
+ <closed><?php echo $feed_closed ?></closed>
+ <site><?php echo SITE_URL . $html->url( '/collection/display/' . $feed_id ) ?></site>
+ <addons>
+<?php
+ foreach ($addonsdata as $addon) {
+
+ if (empty($addonIconPath)) {
+ $addonIconPath = ($addon['addontype_id'] == ADDON_THEME ? $html->urlImage(DEFAULT_THEME_ICON) : $html->urlImage(DEFAULT_ADDON_ICON));
+ }
+
+ $amo = 'https://addons.mozilla.org';
+?>
+<addon>
+ <meta>
+ <added><?php echo $addon['collection_added'] ?></added>
+ <comments><?php echo $addon['collection_comments'] ?></comments>
+ </meta>
+ <categories>
+ <?php foreach ($addon['tags'] as $tag): ?>
+ <category id="<?php echo $tag['id'] ?>"><?php echo $tag['name'] ?></category>
+ <?php endforeach ?>
+ </categories>
+ <name><?php echo $addon['name']; ?></name>
+ <type id='<?php echo $addon['addontype_id']; ?>'><?php echo $addon['addontype_name']; ?></type>
+ <guid><?php echo $addon['guid']; ?></guid>
+ <version><?php echo $addon['install_version']; ?></version>
+ <status id='<?php echo $addon['status']; ?>'><?php
+ if ($addon['status'] == STATUS_PUBLIC) {
+ echo rtrim(_('a_header_public'));
+ } else {
+ echo rtrim(_('a_header_sandbox'));
+ }
+ ?></status>
+ <authors>
+<?php
+ foreach ($addon['users'] as $author) {
+ $authorName = (!empty($author['nickname'])) ? $author['nickname'] : $author['firstname'].' '.$author['lastname'];
+?>
+ <author><?php echo $authorName; ?></author>
+<?php
+ }
+?> </authors>
+ <summary><?php echo $addon['summary']; ?></summary>
+ <description><?php echo $addon['description']; ?></description>
+ <icon><?php
+ if ($addon['icon']) {
+ echo $amo.$addon['icon'];
+ } else {
+ $addonIconPath = ($addon['addontype_id'] == ADDON_THEME ? $html->urlImage(DEFAULT_THEME_ICON) : $html->urlImage(DEFAULT_ADDON_ICON));
+ echo $amo.$addonIconPath;
+ }
+ ?></icon>
+ <compatible_applications>
+ <?php
+ foreach ($addon['compatible_apps'] as $app) {
+ ?>
+ <application>
+ <name><?php echo $app['name']; ?></name>
+ <application_id><?php echo $app['id']; ?></application_id>
+ <min_version><?php echo $app['min_version']; ?></min_version>
+ <max_version><?php echo $app['max_version']; ?></max_version>
+<?php
+ if ($api_version > 1) { ?>
+ <appID><?php echo $app['guid']; ?></appID>
+ <?php } ?>
+ </application>
+ <?php
+ }
+?> </compatible_applications>
+<?php if ($api_version >0 ) { ?>
+ <all_compatible_os>
+ <?php foreach ($addon['all_compatible_os'] as $os) {
+ ?><os><?php echo $os ?></os>
+ <?php } ?>
+ </all_compatible_os>
+ <?php } ?>
+ <eula><?php echo $addon['eula'];?></eula>
+ <thumbnail><?php echo $amo.$addon['thumbnail']; ?></thumbnail>
+ <rating><?php
+ $rating ='';
+ if (isset($addon['averagerating'])) {
+ $rating = $addon['averagerating'];
+ if ($api_version < 1) {
+ // we need to double the rating since the addons mgr expects it to
+ // be out of 10 and we have halved everything in the db
+ $rating *= 2;
+ }
+ // round rating to match stars in AMO
+ $rating = ceil($rating);
+ }
+ echo $rating;
+ ?></rating>
+ <learnmore><?php echo $amo.'/addon/'.$addon['id']; ?></learnmore>
+<?php if ($api_version > 0 ) {
+ foreach($addon['fileinfo'] as $file) {?>
+ <install hash='<?php echo $file['hash']; ?>' os='<?php echo $file['os']; ?>'><?php
+ echo $amo.'/downloads/file/'.$file['id'].'/'.$file['filename']; ?></install>
+ <?php }
+} ?>
+</addon>
+
+<?php
+ }
+ ?>
+ </addons>
+</collection>
+<?php } ?>
diff --git a/site/app/views/api/cumulative_downloads.thtml b/site/app/views/api/cumulative_downloads.thtml
new file mode 100644
index 0000000..104598d
--- /dev/null
+++ b/site/app/views/api/cumulative_downloads.thtml
@@ -0,0 +1,47 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Laura Thomson <lthomson@mozilla.com> (Original Author)
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+ if (isset($error)) { ?>
+ <error><?php echo ($error); ?></error>
+<?php
+ } else {
+ $http = (isset($_SERVER['HTTPS']) ? 'https': 'http') . '://';
+?>
+<cumulative_downloads>
+ <id><?php echo $id; ?></id>
+ <downloads><?php echo $downloads; ?></downloads>
+</cumulative_downloads>
+<?php } ?>
diff --git a/site/app/views/api/get_language_packs.thtml b/site/app/views/api/get_language_packs.thtml
new file mode 100644
index 0000000..d711ce6
--- /dev/null
+++ b/site/app/views/api/get_language_packs.thtml
@@ -0,0 +1,52 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Laura Thomson <lthomson@mozilla.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+if (isset($error)) { ?>
+ <error><?php echo ($error); ?></error>
+<?php
+} else {
+ $http = (isset($_SERVER['HTTPS']) ? 'https': 'http') . '://';
+?>
+<addons>
+<?php
+ foreach ($addonsdata as $addon) {
+ $addon_pre = '<target_locale>'.$addon['Addon']['target_locale']."</target_locale>\n";
+ include 'api_addon.thtml';
+ }
+?>
+</addons>
+<?php } ?>
diff --git a/site/app/views/api/list_addons.thtml b/site/app/views/api/list_addons.thtml
new file mode 100644
index 0000000..b70b0e0
--- /dev/null
+++ b/site/app/views/api/list_addons.thtml
@@ -0,0 +1,50 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Laura Thomson <lthomson@mozilla.com> (Original Author)
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+if (isset($error)) { ?>
+ <error><?php echo ($error); ?></error>
+<?php
+} else {
+ $http = (isset($_SERVER['HTTPS']) ? 'https': 'http') . '://';
+?>
+<addons>
+<?php
+ foreach ($addonsdata as $addon) {
+ include 'api_addon.thtml';
+ }
+?>
+</addons>
+<?php } ?>
diff --git a/site/app/views/api/search.thtml b/site/app/views/api/search.thtml
new file mode 100644
index 0000000..05a0ddf
--- /dev/null
+++ b/site/app/views/api/search.thtml
@@ -0,0 +1,57 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Laura Thomson <lthomson@mozilla.com> (Original Author)
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+ if (isset($error)) { ?>
+ <error><?php echo ($error); ?></error>
+<?php
+ } else {
+ $http = (isset($_SERVER['HTTPS']) ? 'https': 'http') . '://';
+?>
+<searchresults <?php if ($api_version > 0) { echo "total_results = '$total_results'"; } ?> >
+<?php
+ foreach ($addonsdata as $addon) {
+ // testing for dummies is an optimization hack for b3
+ // so search can get the numbers right
+ // this will not occur in api_versions > 0
+ if ($addon != 'dummy') {
+ include 'api_addon.thtml';
+ } else {
+ ?><addon /><?php
+ }
+ }
+?>
+</searchresults>
+<?php } ?>
diff --git a/site/app/views/api/update_pings.thtml b/site/app/views/api/update_pings.thtml
new file mode 100644
index 0000000..d3810c0
--- /dev/null
+++ b/site/app/views/api/update_pings.thtml
@@ -0,0 +1,90 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Laura Thomson <lthomson@mozilla.com> (Original Author)
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+ if (isset($error)) { ?>
+ <error><?php echo ($error); ?></error>
+<?php
+ } else {
+ $http = (isset($_SERVER['HTTPS']) ? 'https': 'http') . '://';
+
+?>
+<update_pings>
+ <id><?php echo $id; ?></id>
+ <period><?php echo $period; ?></period>
+ <enddate><?php echo $querydate; ?></enddate>
+ <total_count><?php echo $total_count; ?></total_count>
+ <version_counts>
+ <?php foreach ($version_counts as $version => $count ) { ?>
+ <version>
+ <version_number><?php echo $version; ?></version_number>
+ <count><?php echo $count; ?></count>
+ </version>
+ <?php } ?>
+ </version_counts>
+ <status_counts>
+ <?php foreach ($status_counts as $status => $count ) { ?>
+ <status_count>
+ <status><?php echo $status; ?></status>
+ <count><?php echo $count; ?></count>
+ </status_count>
+ <?php } ?>
+ </status_counts>
+ <application_counts>
+ <?php foreach ($application_counts as $application => $details ) { ?>
+ <application_count>
+ <application><?php echo !empty($app_names[$application]) ? $app_names[$application] : 'Unknown'; ?></application>
+ <guid><?php echo $application; ?></guid>
+ <?php
+ foreach ($details as $version => $count) {
+ ?><version>
+ <version_number><?php echo $version;?></version_number>
+ <count><?php echo $count; ?></count>
+ </version>
+ <?php }
+ ?>
+ </application_count>
+ <?php } ?>
+ </application_counts>
+ <os_counts>
+ <?php foreach ($os_counts as $os => $count ) { ?>
+ <os_count>
+ <os><?php echo $os; ?></os>
+ <count><?php echo $count; ?></count>
+ </os_count>
+ <?php } ?>
+ </os_counts>
+</update_pings>
+<?php } ?>
diff --git a/site/app/views/collections/add.thtml b/site/app/views/collections/add.thtml
new file mode 100644
index 0000000..40b25b3
--- /dev/null
+++ b/site/app/views/collections/add.thtml
@@ -0,0 +1,124 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Ryan Doherty <rdoherty@mozilla.com>
+ * Frederic Wenzel <fwenzel@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+?>
+<div class="section">
+ <div class="stand-alone-options">
+ <?=$this->renderElement('amo2009/search');?>
+ <?=$this->renderElement('amo2009/categories');?>
+ </div>
+ <div id="collections-add" class="primary" role="main">
+ <?=$this->renderElement('amo2009/breadcrumbs')?>
+ <h2><?=___('collections_add_header')?></h2>
+
+ <p><?=___('collections_add_intro')?></p>
+
+ <?php
+ if (!empty($form_errors)) {
+ echo $this->renderElement('notification', array(
+ 'msg' => ___('error_formerrors'),
+ 'type' => 'error'
+ ));
+ }
+ ?>
+
+ <form action="<?=$html->entities($html->url())?>" method="post" id="collections">
+ <?=$html->hiddenSession() ?>
+
+ <fieldset>
+ <div>
+ <h3><label for="CollectionName"><?=___('collections_edit_formfield_name')?></label></h3>
+ <p><?=___('collections_edit_formfield_name_description')?></p>
+ <?=$html->input('Collection/name');?>
+ <?=$html->tagErrorMsg('Collection/name', ___('collections_edit_form_error_name')) ?>
+ </div>
+
+ <div>
+ <h3><label for="CollectionDescription"><?=___('collections_edit_formfield_description')?></label></h3>
+ <p><?=___('collections_edit_formfield_description_description')?></p>
+ <?=$html->textarea('Collection/description', array('cols'=>50, 'rows'=>5));?>
+ <?=$html->tagErrorMsg('Collection/description', ___('collections_edit_form_error_description')) ?>
+ </div>
+
+ <div>
+ <h3><label><?=___('collections_edit_formfield_listed')?></label></h3>
+ <p><?=___('collections_edit_formfield_listed_description')?></p>
+ <?=$html->radio('Collection/listed', array(
+ true => '<label for="listed_1">'.___('collections_edit_formfield_listed_true').'</label>',
+ false => '<label for="listed_0">'.___('collections_edit_formfield_listed_false').'</label>'
+ ), '<br/>', array('value' => true)
+ )?>
+ </div>
+
+ <div id="firstaddons">
+ <h3><label for="addonname"><?=___('collections_add_formfield_firstaddons')?></label></h3>
+ <p><?=sprintf(___('collections_add_formfield_addons_description'),
+ ___('collections_add_submit'))?></p>
+ <label for="addonname"><?=___('collections_edit_formfield_addons')?></label>
+ <input type="text" name="q" id="addonname"/>
+
+ <div id="selectedaddons">
+ <h3><?=___('collections_add_header_selectedaddons')?></h3>
+ <ul></ul>
+ </div>
+ </div>
+
+ <div>
+ <label><?=$html->submit(___('collections_add_submit'), array('class'=>'submit-button'))?></label>
+ </div>
+ </fieldset>
+ </form>
+
+ <script type="text/javascript">
+ $(document).ready(function() {
+ collections_add.init({
+ lookup_url: '<?=$html->url('/collections/addonLookup')?>'
+ });
+ <?php
+ // add pre-selected add-ons
+ foreach ($initial_addons as &$_addon): ?>
+ collections_add.addAddon(['<?=$_addon['name']?>', '<?=$_addon['id']?>', '<?=$_addon['preview']?>']);
+ <?php endforeach; ?>
+ });
+ </script>
+ </div><!-- /main -->
+
+ <?=$this->renderElement('amo2009/collector_info_secondary', array('showCreateLink' => false, 'showSecondBox' => false));?>
+
+</div><!-- /section -->
diff --git a/site/app/views/collections/ajax/addon_lookup.thtml b/site/app/views/collections/ajax/addon_lookup.thtml
new file mode 100644
index 0000000..1d20e8a
--- /dev/null
+++ b/site/app/views/collections/ajax/addon_lookup.thtml
@@ -0,0 +1,49 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Frederic Wenzel <fwenzel@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+
+header('Content-type: text/plain');
+
+if (!empty($addons)) {
+ foreach ($addons as &$addon) {
+ $name = str_replace('|', '&#124;', $addon['Translation']['name']['string']);
+ if (empty($addon['Addon']['iconpath']))
+ $addon['Addon']['iconpath'] = ($addon['Addon']['addontype_id'] == ADDON_THEME ? $html->urlImage(DEFAULT_THEME_ICON) : $html->urlImage(DEFAULT_ADDON_ICON));
+ echo "{$name}|{$addon['Addon']['id']}|{$addon['Addon']['iconpath']}\n";
+ }
+}
diff --git a/site/app/views/collections/detail.thtml b/site/app/views/collections/detail.thtml
new file mode 100644
index 0000000..41aee0a
--- /dev/null
+++ b/site/app/views/collections/detail.thtml
@@ -0,0 +1,205 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Jeff Balogh <jbalogh@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+
+ * ***** END LICENSE BLOCK ***** */
+
+$this->viewVars['bodyclass'] = 'inverse';
+$this->layout = 'amo2009';
+
+$c = $collection['Collection'];
+?>
+
+<div class="section">
+ <div class="stand-alone-options">
+ <?=$this->renderElement('amo2009/categories')?>
+ <?=$this->renderElement('amo2009/search')?>
+ </div>
+ <div class="primary" role="main">
+ <?=$this->renderElement('amo2009/breadcrumbs')?>
+ <h2>
+ <img class="icon" alt=""
+ src="<?=$this->controller->Image->getCollectionIconUrl($c['id'])?>" />
+ <?=$collection['Translation']['name']['string']?>
+ </h2>
+ <?php
+ $uuid = $collection['Collection']['uuid'];
+ if (!empty($collection_created)) {
+ echo $this->renderElement('notification', array(
+ 'msg' => ___('collections_detail_created_msg'),
+ 'description' => sprintf(___('collections_detail_created_desc'),
+ $html->url('/collections/edit/'.$uuid),
+ $html->link(SITE_URL.$html->rootUrl('/collection/'.$uuid),
+ '/collection/'.$uuid)),
+ 'type' => 'success'
+ ));
+ }
+ ?>
+ <div class="featured">
+ <div class="featured-inner object-lead">
+ <div class="meta">
+ <ul>
+ <?php if ($this->controller->Session->check('User')): ?>
+ <li>
+ <?php
+ $params = array('collection' => $collection,
+ 'is_subscribed' => $is_subscribed,
+ 'buttonClass' => 'neutral prominent',
+ 'withImage' => true);
+ ?>
+ <?=$this->renderElement('amo2009/collection_add_form', $params)?>
+ </li>
+ <script type="text/javascript">
+ <?=$this->renderElement('amo2009/collections_js_init')?>
+ </script>
+ </li>
+ <?php else: ?>
+ <li>
+ <?=sprintf(___('collections_detail_login'),
+ $html->url($html->login_url()))?>
+ </li>
+ <?php endif; ?>
+ <li class="subscribers">
+ <?php $subscribers = $c['subscribers']; ?>
+ <?=sprintf(n___('addons_home_collections_subscribers',
+ 'addons_home_collections_subscribers',
+ $subscribers),
+ $subscribers);?>
+ </li>
+ <li>
+ <?php if ($atleast_manager): ?>
+ <a href="<?=$html->url('/collections/edit/'.$c['uuid'])?>">
+ <?=sprintf(___('collections_detail_manage'))?>
+ </a>
+ <?php endif; ?>
+ </ul>
+ </div> <!-- meta -->
+ <h3><?=___('collections_detail_header_about')?></h3>
+ <p><?=$collection['Translation']['description']['string']?></p>
+ <div class="object-info">
+ <p>
+ <?=sprintf(___('collections_detail_info_created'),
+ $html->linkUsersFromModel($collection['Users']))?>
+ </p>
+ <p>
+ <?=___('collections_detail_info_updated')?>
+ <?=strftime(___('date'), strtotime($c['modified']))?>
+ </p>
+ </div>
+ </div> <!-- featured-inner -->
+ </div> <!-- featured -->
+ <div class="separated-listing">
+ <h3>
+ <?php $count = count($collection['Addon']); ?>
+ <?=sprintf(n___('collections_detail_header_count', 'collections_detail_header_count',
+ $count),
+ $count)?>
+ </h3>
+ <form class="item-sort" method="get" action="">
+ <div>
+ <label for="sortby"><?=___('collections_index_label_sortby')?></label>
+ <select id="sortby" name="sortby">
+ <?php foreach($sort_options as $value => $text): ?>
+ <?php $selected = ($value == $sortby) ? 'selected="selected"' : ''; ?>
+ <option value="<?=$value?>" <?=$selected?>><?=$text?></option>
+ <?php endforeach; ?>
+ </select>
+ <button><?=___('collections_index_button_go')?></button>
+ </div>
+ </form>
+ <?php foreach ($addons as $addon): ?>
+ <?php $a = $addon['Addon']; ?>
+ <div class="item">
+ <!-- TODO: a11y ordering -->
+ <h4>
+ <a href="<?=$html->url('/addon/'.$a['id'])?>">
+ <?=$addon['Translation']['name']['string']?>
+ </a>
+ <span>
+ <?=sprintf(___('collections_index_header_created'),
+ $html->linkUsersFromModel($addon['User']))?>
+ </span>
+ </h4>
+ <div class="item-info">
+ <?php
+ $params = array(
+ 'addon' => $addon,
+ 'buttonClass' => 'auxillary',
+ 'collection_uuid' => $c['uuid']
+ );
+ ?>
+ <?=$this->renderElement('amo2009/install', $params)?>
+ <p class="downloads">
+ <?php $downloads = $a['weeklydownloads']; ?>
+ <?=sprintf(n___('collections_detail_weekly_downloads',
+ 'collections_detail_weekly_downloads',
+ $downloads),
+ '<strong>'.$html->number_format($downloads).'</strong>')?>
+ </p>
+ <p class="review">
+ <?=$this->renderElement('amo2009/reviews', array('addon' => $addon))?>
+ </p>
+ </div> <!-- item-info -->
+ <a href="<?=$html->url('/addon/'.$a['id'])?>">
+ <img class="icon" alt=""
+ src="<?=$this->controller->Image->getAddonIconUrl($a['id'])?>" />
+ </a>
+ <blockquote>
+ <p>
+ <?=$addon['Translation']['summary']['string']?>
+ </p>
+ <p>
+ <a href="<?=$html->url('/addon/'.$a['id'])?>">
+ <?=___('collections_detail_a_learn')?>
+ </a>
+ </p>
+ <?php
+ if (!empty($a['comment'])) {
+ echo '<blockquote class="publisher-comment">';
+ echo '<p>'.nl2br($a['comment']).'</p>';
+ echo '<p class="by">'.sprintf(___('addon_reviewed_by_u_on_d'),
+ $html->linkUserFromModel($a['publisher']),
+ strftime(_('date'), strtotime($a['dateadded']))).'</p>';
+ echo '</blockquote>';
+ }
+ ?>
+ </blockquote>
+ </div> <!-- item -->
+ <?php endforeach; ?>
+ </div> <!-- separated-listing -->
+ <?=$this->renderElement('amo2009/pagination');?>
+ </div> <!-- primary -->
+ <?=$this->renderElement('amo2009/collector_info_secondary')?>
+</div>
diff --git a/site/app/views/collections/edit.thtml b/site/app/views/collections/edit.thtml
new file mode 100644
index 0000000..1ac769f
--- /dev/null
+++ b/site/app/views/collections/edit.thtml
@@ -0,0 +1,347 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Ryan Doherty <rdoherty@mozilla.com>
+ * Frederic Wenzel <fwenzel@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+
+/* Prepare translation box element */
+// Retrieve language arrays from bootstrap.
+global $valid_languages, $native_languages;
+foreach (array_keys($valid_languages) as $key) {
+ $languages[$key] = $native_languages[$key]['native'];
+}
+ksort($languages);
+$this->translationBox = array(
+ 'defaultLocale' => LANG,
+ 'languages' => $languages,
+ 'table' => 'Collection',
+ 'loaded' => false
+);
+
+?>
+<div class="section">
+ <div class="stand-alone-options">
+ <?=$this->renderElement('amo2009/search');?>
+ <?=$this->renderElement('amo2009/categories');?>
+ </div>
+
+ <div id="collections-edit" class="primary" role="main">
+ <?=$this->renderElement('amo2009/breadcrumbs')?>
+
+ <form action="<?=$html->entities($html->url())?>" method="post" id="collections" enctype="multipart/form-data">
+ <?=$html->hiddenSession()?>
+
+ <h2><?=sprintf(___('collections_edit_header'), $this->data['Collection']['Translation']['name']['string'])?></h2>
+
+ <?php
+ if (!empty($collection_saved)) {
+ echo $this->renderElement('notification', array(
+ 'type' => 'success',
+ 'msg' => ___('collections_edit_saved_success'),
+ 'description' => ___('collections_edit_saved_nextstep').' '
+ .$html->link(SITE_URL.$html->url($collection_url), $collection_url),
+ 'htmlattributes' => array('id' => 'saved_success')
+ ));
+ echo <<<JS
+ <script type="text/javascript">/* <![CDATA[ */
+ $(document).ready(function() {
+ bandwagonRefreshEvent();
+ });
+ /* ]]> */</script>
+JS;
+ } elseif (!empty($form_errors)) {
+ echo $this->renderElement('notification', array(
+ 'type' => 'error',
+ 'msg' => ___('error_formerrors')
+ ));
+ }
+ echo $this->renderElement('notification', array(
+ 'type' => 'warning',
+ 'msg' => ___('collections_edit_delete_warning'),
+ 'description' => sprintf(___('collections_edit_delete_upon_submit'),
+ ___('collections_edit_submit_deletecollection'),
+ ___('collections_edit_tabheader_advanced')),
+ 'htmlattributes' => array(
+ 'id' => 'delete-warning',
+ 'style' => 'display:none'
+ )
+ ));
+ ?>
+
+ <div id="coll-edit" class="flora">
+ <ul class="tabs-nav">
+ <?php if ($atleast_manager): ?>
+ <li><a href="#details"><span><?=___('collections_edit_tabheader_details')?></span></a></li>
+ <li><a href="#permissions"><span><?=___('collections_edit_tabheader_permissions')?></span></a></li>
+ <?php endif; ?>
+ <li><a href="#addons"><span><?=___('collections_edit_tabheader_addons')?></span></a></li>
+ <?php if ($atleast_manager): ?>
+ <li><a href="#advanced"><span><?=___('collections_edit_tabheader_advanced')?></span></a></li>
+ <?php endif; ?>
+ </ul>
+
+ <?php if ($atleast_manager): ?>
+ <div id="details">
+ <div>
+ <?php
+ echo $this->renderElement('translationbox', array(
+ 'field' => 'name',
+ 'translations' => $translations['name'],
+ 'height' => '25',
+ 'maxLength' => '50',
+ 'displayName' => ___('collections_edit_formfield_name'),
+ 'description' => ___('collections_edit_formfield_name_description'),
+ ));
+ ?>
+ <?=$html->tagErrorMsg('Collection/name', ___('collections_edit_form_error_name')) ?>
+ </div>
+
+ <div>
+ <?php
+ echo $this->renderElement('translationbox', array(
+ 'field' => 'description',
+ 'translations' => $translations['description'],
+ 'height' => '100',
+ 'maxLength' => '200',
+ 'displayName' => ___('collections_edit_formfield_description'),
+ 'description' => ___('collections_edit_formfield_description_description'),
+ ));
+ ?>
+ <?=$html->tagErrorMsg('Collection/description', ___('collections_edit_form_error_description')) ?>
+ </div>
+
+ <div>
+ <h4><label for="CollectionNickname"><?=___('collections_edit_formfield_nickname')?></label></h4>
+ <p><?=___('collections_edit_formfield_nickname_description')?></p>
+ <p>
+ <?=SITE_URL.$html->url('/collection/', true, false, false)
+ .$html->input('Collection/nickname', array('maxlength'=>30, 'value'=>$this->data['Collection']['Collection']['nickname']));?>
+ <input type="button" value="<?=___('collections_edit_check_nickname')?>" style="display:none" id="nick-avail" />
+ <?=$html->image('ajax_loading.gif', array('style'=>'display:none', 'width'=>15, 'height'=>15, 'alt'=>'searching'))?>
+ <span class="available" style="display:none"><?=___('collections_edit_nickname_available')?></span>
+ <span class="taken error_message" style="display:none"><?=___('collections_edit_nickname_taken')?></span>
+ </p>
+ <?=$html->tagErrorMsg('Collection/nickname', ___('collections_edit_form_error_nickname')) ?>
+ </div>
+
+ <div id="icon">
+ <h4><label for="CollectionIcon"><?=___('collections_edit_formfield_icon')?></label></h4>
+ <p><?=___('collections_edit_formfield_icon_description')?></p>
+
+ <?php if (!empty($this->data['Collection']['Collection']['icontype'])): ?>
+ <img src="<?=$iconurl?>" alt="Icon"/>
+ <?php endif;?>
+ <input id="CollectionIcon" type="file" name="icon"/>
+ <span class="toberemoved" style="display:none"><?=sprintf(___('collections_edit_icon_toberemoved'), ___('collections_edit_submit'))?></span>
+ <a href="#" class="cancel" style="display:none"><?=___('collections_edit_icon_cancel')?></a>
+
+ <noscript>
+ <p>
+ <input id="IconDeleteNoScript" type="checkbox" name="data[Icon][delete]"/> <label for="IconDeleteNoScript"><?=___('collections_edit_icon_delete')?></label>
+ </p>
+ </noscript>
+ <span class="replaceremove" style="display:none">
+ <a href="#" id="icon_replace"><?=___('collections_edit_icon_replace')?></a> |
+ <a href="#" id="icon_remove"><?=___('collections_edit_icon_delete')?></a>
+ </span>
+ <?=$html->tagErrorMsg('Collection/icon', ___('collections_edit_form_error_icon')) ?>
+ </div>
+ </div>
+
+ <div id="permissions">
+ <noscript><h3><?=___('collections_edit_header_permissions')?></h3></noscript>
+ <div>
+ <fieldset>
+ <h4><?=___('collections_edit_formfield_listed')?></h4>
+ <p><?=___('collections_edit_formfield_listed_description')?></p>
+ <?=$html->radio('Collection/listed', array(
+ true => '<label for="listed_1">'.___('collections_edit_formfield_listed_true').'</label>',
+ false => '<label for="listed_0">'.___('collections_edit_formfield_listed_false').'</label>'
+ ), '<br/>', array('value'=>$this->data['Collection']['Collection']['listed']));
+ ?>
+ </fieldset>
+ </div>
+
+ <div>
+ <fieldset>
+ <h4><?=___('collections_edit_formfield_publishers')?></h4>
+ <p><?=___('collections_edit_formfield_publishers_description')?></p>
+ <?=$html->radio('Publishers/p_onlyme', array(
+ true => '<label for="p_onlyme_1">'.___('collections_edit_formfield_users_onlyme').'</label>',
+ false => '<label for="p_onlyme_0">'.___('collections_edit_formfield_users_otherusers').'</label>'
+ ), '<br/>', array('value'=>(int)empty($publishers_noscript)));
+ ?>
+ <div id="publishers" class="jsonly">
+ <ul></ul>
+ <label for="PublishersAdd"><?=___('collections_edit_formfield_users_add')?></label><br/>
+ <?=$html->input('Publishers/add')?> <input type="button" value="<?=___('collections_edit_formfield_users_submit')?>" />
+ <?=$html->image('ajax_loading.gif', array('style'=>'display:none', 'width'=>15, 'height'=>15, 'alt'=>'searching'))?>
+ </div>
+ <noscript><div>
+ <?=$html->input('Publishers/new')?> <label for="PublishersNew"><?=___('collections_edit_formfield_users_new_noscript')?></label><br/>
+ <?=$html->selectTag('Publishers/delete', $publishers_noscript, null, array('size'=>3, 'multiple'=>'multiple'), null, false)?> <label for="PublishersDelete"><?=___('collections_edit_formfield_users_delete_noscript')?></label>
+ </div></noscript>
+ </fieldset>
+ </div>
+
+ <div>
+ <fieldset>
+ <h4><?=___('collections_edit_formfield_managers')?></h4>
+ <p><?=___('collections_edit_formfield_managers_description')?></p>
+ <?=$html->radio('Managers/m_onlyme', array(
+ true => '<label for="m_onlyme_1">'.___('collections_edit_formfield_users_onlyme').'</label>',
+ false => '<label for="m_onlyme_0">'.___('collections_edit_formfield_users_otherusers').'</label>'
+ ), '<br/>', array('value'=>(int)empty($managers_noscript)));
+ ?>
+ <div id="managers" class="jsonly">
+ <ul></ul>
+ <label for="ManagersAdd"><?=___('collections_edit_formfield_users_add')?></label><br/>
+ <?=$html->input('Managers/add')?> <input type="button" value="<?=___('collections_edit_formfield_users_submit')?>" />
+ <?=$html->image('ajax_loading.gif', array('style'=>'display:none', 'width'=>15, 'height'=>15, 'alt'=>'searching'))?>
+ </div>
+ <noscript><div>
+ <?=$html->input('Managers/new')?> <label for="ManagersNew"><?=___('collections_edit_formfield_users_new_noscript')?></label><br/>
+ <?=$html->selectTag('Managers/delete', $managers_noscript, null, array('size'=>3, 'multiple'=>'multiple'), null, false)?> <label for="ManagersDelete"><?=___('collections_edit_formfield_users_delete_noscript')?></label>
+ </div></noscript>
+ </fieldset>
+ </div>
+ </div>
+ <?php endif; // at least manager ?>
+
+ <div id="addons">
+ <noscript><h3><?=___('collections_edit_header_addons')?></h3></noscript>
+ <p class="jsonly"><?=___('collections_edit_addons_description')?> <?=___('collections_edit_addons_description_publish_detailspage')?></p>
+ <noscript><p><?=___('collections_edit_addons_description_noscript')?> <?=___('collections_edit_addons_description_publish_detailspage')?></p></noscript>
+ <label for="addonname" class="jsonly"><?=___('collections_edit_formfield_addons')?></label> <input type="text" name="q" id="addonname"/>
+ <input type="button" onclick="return false;" value="<?=___('collections_edit_addons_submit')?>" id="addon-add" class="jsonly" />
+ <hr/>
+ <noscript><div>
+ <h3><?=___('collections_edit_header_addons_current')?></h3>
+ <?=$html->selectTag('Addons/delete', $addons_noscript, null, array('size'=>6, 'multiple'=>'multiple'), null, false)?>
+ <label for="AddonsDelete"><?=___('collections_edit_addons_delete_noscript')?></label>
+ </div></noscript>
+ <div id="currentaddons" class="jsonly">
+ <h3><?=___('collections_edit_header_addons_current')?></h3>
+ <div class="coll-addon" id="addon-new" style="display:none">
+ <p><img src="" alt=""/><span class="name"></span><span class="added"><?=___('collections_edit_addons_listitem_added')?></span></p>
+ <a href="#" class="removeaddon"><?=___('collections_edit_addons_listitem_remove')?></a>
+ <blockquote title="publishercomment"></blockquote>
+ <a href="#" class="addlink"><?=___('collections_edit_addons_listitem_comment_add')?></a>
+ <div class="editdelete">
+ <a href="#" class="editlink"><?=___('collections_edit_addons_listitem_comment_edit')?></a> |
+ <a href="#" class="deletelink"><?=___('collections_edit_addons_listitem_comment_delete')?></a>
+ </div>
+ <div class="editbox">
+ <textarea cols="50" rows="5"></textarea>
+ <input type="button" value="<?=___('collections_edit_addons_listitem_comment_submit')?>"/>
+ <p><?=___('collections_edit_addons_listitem_comment_note')?></p>
+ </div>
+ </div>
+ </div>
+ </div>
+
+ <?php if ($atleast_manager): ?>
+ <div id="advanced">
+ <noscript><h3><?=___('collections_edit_header_advanced')?></h3></noscript>
+ <fieldset>
+ <h4><?=___('collections_edit_formfield_application')?></h4>
+ <p><?=___('collections_edit_formfield_application_description')?></p>
+ <?=$html->selectTag('Collection/application_id', $appoptions, $this->data['Collection']['Collection']['application_id'], null, null, false);?>
+ </fieldset>
+
+ <?php if ($isadmin): ?>
+ <fieldset>
+ <h4><?=___('collections_edit_formfield_collectiontype')?></h4>
+ <?=$html->selectTag('Collection/collection_type', $collection_types, $this->data['Collection']['Collection']['collection_type'], null, null, false);?>
+ </fieldset>
+ <?php endif; ?>
+
+ <?php if ($atleast_owner): ?>
+ <fieldset>
+ <h4><?=___('collections_edit_formfield_deletecollection')?></h4>
+ <p><?=___('collections_edit_formfield_deletecollection_description')?></p>
+ <input id="delete-coll" type="button" class="jsonly" name="data[action]" value="<?=___('collections_edit_submit_deletecollection')?>"/>
+ <div id="delete-confirm">
+ <div><input id="delete-coll-noscript" type="checkbox" name="data[action]" value="delete-coll"/> <label for="delete-coll-noscript"><?=___('collections_edit_confirm_deletecollection')?></label></div>
+ <p><?=sprintf(___('collections_edit_confirm_deletecollection_description'), ___('collections_edit_submit'))?></p>
+ </div>
+ </fieldset>
+ <?php endif; // at least owner ?>
+ </div>
+ <?php endif; // at least manager ?>
+
+ </div><!-- /tabs -->
+ <div><input type="submit" id="submitbutton" value="<?=___('collections_edit_submit')?>"/></div>
+ </form>
+
+ <script type="text/javascript">
+ //<![CDATA[
+ var collURL = '<?=$html->url('/collections')?>'
+ var jsonURL = '<?=$html->url('/collections/json')?>';
+ var imageURL = '<?=$html->url('/img', true, false, false)?>';
+ var collection_id = <?=$this->data['Collection']['Collection']['id']?>;
+ $(document).ready(function() {
+ collections_edit.init();
+ <?php
+ foreach ($addons as &$addon) {
+ echo sprintf("collections_edit.addon_show('%s','%s','%s','%s','%s','%s', %s, %s);\n",
+ $addon['AddonCollection']['addon_id'], // id
+ addslashes($html->unsanitize($addon['Addon']['Translation']['name']['string'])), // name
+ $this->controller->Image->getAddonIconURL($addon['AddonCollection']['addon_id']), // iconurl
+ strftime(_('date'), strtotime($html->unsanitize($addon['AddonCollection']['added']))), // add date
+ $html->linkUserFromModel($addon['User']), // publisher
+ preg_replace('/\n/', '<br/>', $addon['Translation']['comments']['string']), // comment
+ (($atleast_manager || $addon['User']['id'] == $user['id']) ? 1 : 0), // editable
+ 0 // insert at the end
+ );
+ }
+ foreach (array('publishers', 'managers') as $role) {
+ $rolearray = "{$role}_noscript";
+ foreach ($$rolearray as $id => &$user) {
+ echo sprintf("collections_edit.user_add('%s','%s','%s');\n",
+ $role, $id, $user);
+ }
+ }
+ ?>
+ });
+ //]]>
+ </script>
+ </div><!-- /main -->
+
+ <?=$this->renderElement('amo2009/collector_info_secondary', array('showCreateLink' => false, 'showSecondBox' => false));?>
+
+</div>
diff --git a/site/app/views/collections/install.thtml b/site/app/views/collections/install.thtml
new file mode 100644
index 0000000..6e06b2f
--- /dev/null
+++ b/site/app/views/collections/install.thtml
@@ -0,0 +1,149 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Frederic Wenzel <fwenzel@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+if (!$is_ajax):
+?>
+<div id="content" class="collections">
+<div id="content-main">
+
+<p class="amo-plug">
+ Want even more add-ons?<br/>
+ <?=$html->link('Check out all Firefox Add-ons', '/');?>
+</p>
+
+<h1>Fashion my Firefox</h1>
+<h2>You asked to install the following items:</h2>
+<?php else: // AJAX action ?>
+<h2>You asked to install the following items:</h2>
+<h2 style="display:none">The following add-ons that you have selected have license agreements:</h2>
+<?php endif; ?>
+
+<form action="" method="post" id="installform">
+<ul class="addon-listing addon-install-listing">
+ <?php
+ foreach ($addons as $val) {
+ $iconPath = $this->controller->Image->getAddonIconURL($val['Addon']['id']);
+ echo $this->renderElement('collections_install_item', array(
+ 'addon' => $val,
+ 'addonIconPath' => $iconPath
+ ));
+ }
+ ?>
+</ul>
+<div class="installsubmit"><input type="submit" value="Cancel" class="cancel"/><input type="submit" value="Next" class="submit"/></div>
+</form>
+
+<?php if (!$is_ajax): ?>
+</div><!-- /#content-main -->
+</div><!-- /#content -->
+<?php endif; ?>
+
+<script type="text/javascript">
+// <![CDATA[
+ $(document).ready(function() {
+ var platform = getPlatformName();
+ $('li.inst-addon .desc').children('p,input').filter(':not(.platform-ALL,.platform-'+platform+')').remove();
+
+ var showEULAs = function() {return ($('li.inst-addon.eula input.install:checked').length>0);};
+ $('input.install').attr('checked', 'true')
+ .change(function(){
+ $('.installsubmit input.submit').attr('disabled', ($('input.install:checked').length == 0))
+ .attr('value', showEULAs()?'Next':'Install');
+ })
+ .change();
+
+ $('#installform .installsubmit input.submit').click(function() {
+ if (!showEULAs()) return true;
+ $('#installdialog > h2').toggle();
+ $('input.install:not(:checked)').each(function(){$('#addon-'+$(this).attr('value')).hide();});
+ $('li.inst-addon.noeula').hide();
+ $('li.inst-addon div.eula').show()
+ .siblings().hide();
+ $('.installsubmit input.submit').attr('value', 'Install')
+ .unbind();
+ return false;
+ });
+
+ $('#installform').submit(function() {
+ var installcount = 0; var signedcount = 0;
+ var unsigned = {}; var signed = {};
+ var installed = new Array();
+ $('input.install:checked').each(function() {
+ var id = $(this).attr('value');
+ var addon = $('#addon-'+id);
+
+ if (addon.find('.eula input[type=radio][value=no]').attr('checked')==true) return true;
+
+ installed[installcount] = id;
+
+ var name = addon.find('h4').text();
+ var url = addon.find('.desc p').text();
+ var icon = addon.find('img.icon').attr('src');
+ var hash = addon.find('input[name=hash]').attr('value');
+
+ var newaddon = {
+ URL: url,
+ IconURL: icon,
+ Hash: hash,
+ toString: function() { return this.URL; }
+ };
+ if ($(this).hasClass('unsigned') || signedcount++ == 0) {
+ // unsigned and first signed one in one batch
+ unsigned[name] = newaddon;
+ } else {
+ // all other signed ones in separate batch
+ signed[name] = newaddon;
+ }
+ installcount++;
+ });
+ if (installcount > 0) {
+ InstallTrigger.install(unsigned, function(url,status){
+ if (status==0) window.location = '<?=$html->url('success')?>?i='+installed.join(',');return true;});
+ if (signedcount > 1) {
+ for (k in signed) {
+ var instaddon = {};
+ instaddon[k] = signed[k];
+ InstallTrigger.install(instaddon);
+ }
+ }
+ }
+ return false;
+ });
+ });
+// ]]>
+</script>
diff --git a/site/app/views/collections/interactive.thtml b/site/app/views/collections/interactive.thtml
new file mode 100644
index 0000000..bcff029
--- /dev/null
+++ b/site/app/views/collections/interactive.thtml
@@ -0,0 +1,164 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Frederic Wenzel <fwenzel@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+// categories and descriptions
+$categories = array(
+ 6 => array('name' => 'Finder and Seeker',
+ 'desc' => "I want to make finding information on the Web simpler and more relevant to me."),
+ 5 => array('name' => 'Social Butterfly',
+ 'desc' => "I love social networks! I keep track of friends and family, share photos, organize events, and am always looking for ways to stay connected."),
+ 1 => array('name' => 'Shutterbug',
+ 'desc' => "I love to view and share pictures and videos online."),
+ 4 => array('name' => 'Digital Pack Rat',
+ 'desc' => "I want a hassle-free way to keep track of my favorite sites, bookmarks, blogs and, well, everything!"),
+ 9 => array('name' => 'Rock Star',
+ 'desc' => "Music and the Web go together like rock stars and leather -- I love to listen while I surf, work, email or research online."),
+ 7 => array('name' => 'Decorator',
+ 'desc' => "I decorate my room, my office, even myself! So why not decorate my browser?"),
+ 3 => array('name' => 'Shopaholic',
+ 'desc' => "I love to shop online and am always looking for ways to take advantage of great online deals."),
+ 2 => array('name' => 'News Junkie',
+ 'desc' => "I want to know what’s happening in the world as it happens. And the weather helps me plan my week -- temperature, please!"),
+ 8 => array('name' => 'Executive Assistant',
+ 'desc' => "I need a better way to make lists and organize myself (no more sticky notes!).")
+);
+?>
+<div id="page">
+
+<div id="page-title" class="fyf">
+<h1><img src="<?=$html->urlImage('fyf/fyf_header.png')?>" alt="Fashion Your Firefox" /></h1></div>
+</div>
+
+<div id="content" class="collections">
+<div id="content-main" class="full">
+
+<div id="fashion-blurb">
+ <p>You spend more time online than on the road, but you probably think more
+ about avoiding traffic than enjoying the best of the Web.</p>
+ <p>So, why not customize your Firefox for the things you really love to do?
+ Take your browser from simple to spectacular.</p>
+ <p>Firefox add-ons are little extras that allow you to add a personal touch
+ to your browser. Select your favorites from the categories below to
+ accessorize your Web!</p>
+<hr />
+</div>
+
+<noscript>
+<div class="error-notice">
+ <h3>JavaScript required</h3>
+ <p>This wizard only works with JavaScript enabled. Please
+ <a href="http://support.mozilla.com/kb/JavaScript">switch on JavaScript</a>,
+ then reload this page.</p>
+</div>
+</noscript>
+
+<div class="error-notice" id="fx3-warning" style="display:none">
+ <h3>You need Firefox 3 to Fashion Your Firefox!</h3>
+ <p>The add-ons in the Fashion Your Firefox collection require the
+ latest version of Firefox.<br/>Please upgrade to Firefox 3 –
+ the fastest, safest, and smartest Firefox yet.
+ <a href="http://firefox.com" target="_blank">Learn more.</a></p>
+</div>
+
+<form action="<?=$html->url('/collections/install')?>" method="post" id="collectionform">
+<div id="wizard" class="ui-accordion-container">
+ <?php
+ $catcount = 0;
+ foreach ($categories as $catid => $catinfo):
+ ?>
+ <div class="cat-header <?=(($catcount++)==0?'first':'')?>">
+ <h3><?=$catinfo['name']?></h3>
+ <p>"<?=$catinfo['desc']?>"</p>
+ </div>
+ <ul class="addon-listing">
+ <?php
+ foreach ($addons[$catid] as $val) {
+ $prevPath = $this->controller->Image->getHighlightedPreviewURL($val['Addon']['id']);
+ $iconPath = $this->controller->Image->getAddonIconURL($val['Addon']['id']);
+ echo $this->renderElement('collections_interactive_addon', array(
+ 'addon' => $val,
+ 'addonIconPath' => $iconPath,
+ 'addonPreviewPath' => $prevPath,
+ ));
+ }
+ ?>
+ </ul>
+ <?php endforeach; ?>
+</div><!-- /#wizard -->
+<div class="installsubmit"><input type="image" value="Install my Add-ons!" src="<?=$html->urlImage('fyf/installsubmit.png')?>"></div>
+<div id="installdialog" class="jqmWindow" style="display:none">Please wait...</div>
+</form>
+
+<p class="faq">
+ Need help?<br/>
+ <?=$html->link('Read the FAQ.', '/pages/fashionyourfirefox_faq');?>
+</p>
+
+</div><!-- /#content-main -->
+</div><!-- /#content -->
+</div><!-- /#page -->
+
+<script type="text/javascript">
+// <![CDATA[
+ $(document).ready(function() {
+ $('.collections').collection({'installUrl':"<?=$html->url('install/ajax')?>"});
+
+ $('#wizard').accordion({
+ autoHeight: false,
+ active: false,
+ header: 'div.cat-header',
+ alwaysOpen: false,
+ change: function(e,data){if (data.newHeader.length>0) $('html,body').animate({scrollTop: data.newHeader.offset().top}, 500);}
+ });
+
+ /* sniff Fx3 */
+ var uapattern = /(?:Firefox|Minefield|Shiretoko|Iceweasel)\/(.*)(?:\s|$)/;
+ var ua = navigator.userAgent;
+ var uamatch = uapattern.exec(ua);
+ if (uamatch == null || uamatch[1].substr(0,1)!="3") {
+ $('.add-button').addClass('upgrade');
+ $('.add-button>:not(p)').hide();
+ $('.add-button p').show();
+ $('.installsubmit').hide();
+
+ $('#fx3-warning').show();
+ }
+ });
+
+// ]]>
+</script>
diff --git a/site/app/views/collections/json.thtml b/site/app/views/collections/json.thtml
new file mode 100644
index 0000000..3c885cc
--- /dev/null
+++ b/site/app/views/collections/json.thtml
@@ -0,0 +1,14 @@
+<?php
+if (!defined('NO_MICROTIME'))
+ define('NO_MICROTIME', true);
+
+if (!empty($encapsulate)) {
+ echo '<div id="json">';
+ $listing->json($json, null, true);
+ echo '</div>';
+}
+else {
+ header('Content-type: text/plain');
+ $listing->json($json, null);
+}
+?>
diff --git a/site/app/views/collections/listing.thtml b/site/app/views/collections/listing.thtml
new file mode 100644
index 0000000..a335278
--- /dev/null
+++ b/site/app/views/collections/listing.thtml
@@ -0,0 +1,104 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Jeff Balogh <jbalogh@mozilla.com>
+ * Frederic Wenzel <fwenzel@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+$this->viewVars['bodyclass'] = 'inverse';
+$this->layout = 'amo2009';
+?>
+
+<div class="section">
+ <div class="stand-alone-options">
+ <?=$this->renderElement('amo2009/categories')?>
+ <?=$this->renderElement('amo2009/search')?>
+ </div>
+ <div class="primary" role="main">
+ <?=$this->renderElement('amo2009/breadcrumbs')?>
+ <h2><?=___('collections_index_header_collections')?></h2>
+ <?php if (!empty($collection_deleted)): ?>
+ <?=$this->renderElement('notification', array(
+ 'type' => 'success',
+ 'msg' => ___('collections_success_delete')
+ ));?>
+ <script type="text/javascript">/* <![CDATA[ */
+ $(document).ready(function() {
+ bandwagonRefreshEvent();
+ });
+ /* ]]> */</script>
+ <?php endif; ?>
+ <div class="featured listing">
+ <div class="featured-inner">
+ <div class="listing-header">
+ <ul>
+ <?php foreach ($tabs as $tab): ?>
+ <?php $class = ($tab['href'] == $selected) ? 'class="selected"' : ''; ?>
+ <li <?=$class?>>
+ <a href="<?=$html->url('/collections/'.$tab['href'])?>">
+ <?=$tab['text']?>
+ </a>
+ </li>
+ <?php endforeach; ?>
+ </ul>
+ <?=$this->renderElement('amo2009/collections_sort_form')?>
+ </div> <!-- listing-header -->
+ <script type="text/javascript">
+ <?=$this->renderElement('amo2009/collections_js_init')?>
+ </script>
+ <?php if (count($collections) === 0 && isset($filler)): ?>
+ <div class="item">
+ <?php /* Fligtar is super picky about the whitespace here. */ ?>
+ <br/><?=$filler?><br/>
+ </div>
+ <?php endif; ?>
+ <?php
+ $user = $this->controller->Session->read('User');
+ foreach ($collections as $collection) {
+ echo $this->renderElement('amo2009/collection_listing_item',
+ array('collection' => $collection,
+ 'user' => $user));
+ }
+ ?>
+ </div> <!-- featured-inner -->
+ <?php if (count($collections) > 0): ?>
+ <div class="listing-footer">
+ <?=$this->renderElement('amo2009/pagination');?>
+ </div>
+ <?php endif; ?>
+ </div> <!-- featured listing -->
+ </div> <!-- primary -->
+ <?=$this->renderElement('amo2009/collector_info_secondary')?>
+</div>
diff --git a/site/app/views/collections/rss/collection.thtml b/site/app/views/collections/rss/collection.thtml
new file mode 100644
index 0000000..08937fc
--- /dev/null
+++ b/site/app/views/collections/rss/collection.thtml
@@ -0,0 +1,66 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Frederic Wenzel <fwenzel@mozilla.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+if (!isset($sort_by)) $sort_by = '';
+foreach ($addons as $addon):
+ if (!empty($addon['Version'])) {
+ // prepare version string
+ $version = $addon['Version'][0]['version'];
+ // prepare publication timestamp
+ $created = $addon['Addon']['dateadded'];
+ $pubdate = $time->toRss($created);
+ // permalink to changelog/history page
+ $permalink = SITE_URL.$html->url("/addons/versions/{$addon['Addon']['id']}#version-{$version}");;
+ } else {
+ $version = '';
+ $pubdate = '';
+ $permalink = '';
+ }
+
+ // render rss feed item
+ echo $this->renderElement('rss_listitem', array(
+ 'title' => $addon['Translation']['name']['string'].' '.$version,
+ 'url' => SITE_URL.$html->url('/addon/'.$addon['Addon']['id']),
+ 'description' => $addon['Translation']['summary']['string'],
+ 'author' => $addon['User'][0]['firstname'].' '.$addon['User'][0]['lastname'],
+ 'pubDate' => $pubdate,
+ 'permalink' => $permalink
+ ));
+
+endforeach;
+?>
diff --git a/site/app/views/collections/subscribe.thtml b/site/app/views/collections/subscribe.thtml
new file mode 100644
index 0000000..43ebbc2
--- /dev/null
+++ b/site/app/views/collections/subscribe.thtml
@@ -0,0 +1,116 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Frederic Wenzel <fwenzel@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+$this->layout = ($is_ajax ? null : 'amo2009');
+
+if (!$is_ajax):
+?>
+<div class="section">
+ <div class="stand-alone-options">
+ <?php
+ echo $this->renderElement('amo2009/search');
+ echo $this->renderElement('amo2009/categories');
+ ?>
+ </div>
+ <div class="primary" role="main">
+ <?=$this->renderElement('amo2009/breadcrumbs');?>
+
+<?php endif; /* /!is_ajax */ ?>
+ <div class="featured">
+ <div class="featured-inner object-lead">
+ <?php
+ if ($this->action == 'subscribe') {
+ if (!empty($success)) {
+ echo $this->renderElement('notification', array(
+ 'type' => 'success',
+ 'msg' => sprintf(___('collections_subscribe_success'),
+ $collection['Translation']['name']['string']),
+ 'description' => sprintf(___('collections_subscribe_success_desc'),
+ $html->url('/collections/favorites'),
+ ___('collections_index_li_favorites'),
+ $html->url('/pages/collector_features'))
+ ));
+ } else {
+ echo $this->renderElement('notification', array(
+ 'type' => 'error',
+ 'msg' => ___('collections_subscribe_error')
+ ));
+ }
+
+ } elseif ($this->action == 'unsubscribe') {
+ if (!empty($success)) {
+ echo $this->renderElement('notification', array(
+ 'type' => 'success',
+ 'msg' => sprintf(___('collections_unsubscribe_success'),
+ $collection['Translation']['name']['string'])
+ ));
+ } else {
+ echo $this->renderElement('notification', array(
+ 'type' => 'error',
+ 'msg' => ___('collections_unsubscribe_error')
+ ));
+ }
+ }
+ ?>
+
+ <div class="footer">
+ <?=$html->link(___('collections_subscribe_button_close'), '/collections',
+ array('class' => 'button close-button'));?>
+ <div class="bother">
+ <input type="checkbox" id="bothersome" name="bothersome">
+ <label for="bothersome">
+ <?=___('collections_subscribe_label_bothersome')?>
+ </label>
+ </div>
+ </div>
+
+ <script type="text/javascript">
+ $(document).ready(function() {
+ $('#subscribe_ajax .close-button a').click(function(e) {
+ // TODO: trigger lightbox closing function
+ e.preventDefault();
+ });
+ bandwagonRefreshEvent();
+ });
+ </script>
+ </div>
+ </div> <!-- featured -->
+
+<?php if (!$is_ajax): ?>
+ </div>
+</div>
+<?php endif; ?>
diff --git a/site/app/views/collections/success.thtml b/site/app/views/collections/success.thtml
new file mode 100644
index 0000000..7fbb694
--- /dev/null
+++ b/site/app/views/collections/success.thtml
@@ -0,0 +1,108 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Frederic Wenzel <fwenzel@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+?>
+<div id="page">
+<div id="content" class="collections">
+<div id="content-main" class="full">
+
+<div id="successpage">
+ <h1><img src="<?=$html->urlImage('fyf/addonguy-success.png')?>" alt="Add-on Guy" /><img src="<?=$html->urlImage('fyf/fashioned.png')?>" alt="You've Fashioned Your Firefox!" /></h1>
+
+ <p>After a quick re-start of your Firefox browser, you'll be ready to start using the add-ons you've selected.</p>
+</div>
+
+<div id="firstrun">
+ <div class="welcome">
+ <h1>Welcome to</h1>
+ <img src="<?=$html->urlImage('fyf/fyf_header.png')?>" alt="Fashion Your Firefox" />
+ </div>
+
+ <p>Thanks for trying the Fashion Your Fox collection! Now your Firefox is tailored exactly to your needs and interests.</p>
+
+ <?php
+ if (!empty($addons)):
+ ?>
+ <div class="box">
+ <h3>Your Add-ons</h3>
+ <p>You've successfully installed the following add-ons:</p>
+ <ul>
+ <?php foreach ($addons as $addon): ?>
+ <li><?=$addon['Translation']['name']['string'];?></li>
+ <?php endforeach; ?>
+ </ul>
+ </div>
+ <?php endif; ?>
+ <div class="box">
+ <h3>Getting started</h3>
+ <p>Your add-ons will appear in different places around the, bottom,
+ or even the Tools menu of your browser. Some may open a new tab with
+ useful information... just close it after you've had a look.</p>
+ </div>
+ <div class="box">
+ <h3>Need help?</h3>
+ <p>For more information about how Fashion Your Firefox works, visit the
+ <?=$html->link('FAQ', '/pages/fashionyourfirefox_faq');?>. You can also
+ <?=$html->link('search the main add-ons site', '/');?> for details on a
+ specific add-on, or
+ <?=$html->link('visit our support site', 'http://support.mozilla.com/en-US/kb/Customizing+Firefox+with+add-ons')?>
+ for more about add-ons in general.
+ </p>
+ </div>
+</div>
+
+</div><!-- /#content-main -->
+</div><!-- /#content -->
+</div><!-- /#page -->
+
+<script type="text/javascript">
+// <![CDATA[
+ $(document).ready(function() {
+ if (document.cookie.indexOf('coll_restarted=yes') == -1) {
+ // pre-restart
+ var date = new Date();
+ date.setTime(date.getTime()+(24*60*60*1000)); // one day
+ $('#firstrun').hide();
+ document.cookie = 'coll_restarted=yes; expires='+date.toUTCString();
+ } else {
+ // post-restart
+ $('#successpage').hide();
+ document.cookie = 'coll_restarted=yes;';
+ }
+ });
+// ]]>
+</script>
diff --git a/site/app/views/compatibility/dashboard.thtml b/site/app/views/compatibility/dashboard.thtml
new file mode 100644
index 0000000..bfc3595
--- /dev/null
+++ b/site/app/views/compatibility/dashboard.thtml
@@ -0,0 +1,165 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Justin Scott <fligtar@mozilla.com> (Original Author)
+ * Wil Clouser <wclouser@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+$this->viewVars['bodyclass'] = 'inverse';
+
+?>
+<div id="content" class="primary prose" style="min-height: 400px;">
+ <div id="compat-home-nav">
+ <a href="#" onclick="compatibility.viewHome(); return false;"><?=___('compatibility_dashboard_main_link', 'Back to Main')?></a>
+ </div>
+ <div class="compat-box">
+ <div id="compat-intro">
+ <h2><?=$html->image('wordmarks/firefox-'.$version.'.png', array('alt' => APP_PRETTYNAME." {$version}"))?><br /><?=___('compatibility_dashboard_center_header', 'Add-on Compatibility Center')?></h2>
+ <p><?=sprintf(___('compatibility_dashboard_intro', 'Be prepared for the release of %1$s with the tools and information available for the %2$s Add-ons community found below.'), APP_PRETTYNAME." {$version}", APP_PRETTYNAME)?></p>
+ <ul>
+ <li id="nav-report"><a href="<?=$html->url('/compatibility/report/'.$version)?>" onclick="compatibility.viewReport(); return false;"><?=___('compatibility_view_report', 'View Compatibility Report')?></a></li>
+ <li id="nav-developers"><a href="<?=$html->url('/compatibility/developers/'.$version)?>" onclick="compatibility.viewDeveloperInfo(); return false;"><?=___('compatibility_developer_info', 'Information for Add-on Developers')?></a></li>
+ <li id="nav-users"><a href="<?=$html->url('/compatibility/users/'.$version)?>" onclick="compatibility.viewEndUserInfo(); return false;"><?=___('compatibility_user_info', 'Information for Add-on Users')?></a></li>
+ </ul>
+
+ </div>
+
+ <div id="report-intro">
+ <div class="header">
+ <div class="title">
+ <?=$html->image('wordmarks/firefox-'.$version.'_small.png', array('alt' => APP_PRETTYNAME." {$version}"))?><?=___('compatibility_report_title', 'Add-on Compatibility Report')?>
+ </div>
+ </div>
+ <p class="intro"><?=sprintf(___('compatibility_report_intro', 'Of the %1$s add-ons that make up 95&#37; of add-on usage known to Mozilla, <b>%2$s&#37;</b> are currently considered compatible with the latest builds of %3$s.'), $html->number_format($totals['addons95']), round($percentages[COMPAT_LATEST]), APP_PRETTYNAME." {$version}")?></p>
+ <div id="overall-compat">
+ <div id="overall-compat-bar">
+ <div class="compat-other" style="width: <?=$percentages[COMPAT_OTHER]?>%;"><?=($percentages[COMPAT_OTHER] >= 5 ? round($percentages[COMPAT_OTHER]).'%': '')?></div>
+ <div class="compat-alpha" style="width: <?=$percentages[COMPAT_ALPHA]?>%;"><?=($percentages[COMPAT_ALPHA] >= 5 ? round($percentages[COMPAT_ALPHA]).'%': '')?></div>
+ <div class="compat-beta" style="width: <?=$percentages[COMPAT_BETA]?>%;"><?=($percentages[COMPAT_BETA] >= 5 ? round($percentages[COMPAT_BETA]).'%': '')?></div>
+ <div class="compat-latest" style="width: <?=$percentages[COMPAT_LATEST]?>%;"><?=($percentages[COMPAT_LATEST] >= 5 ? round($percentages[COMPAT_LATEST]).'%': '')?></div>
+ </div>
+
+ <div id="overall-compat-legend">
+ <div class="legend-box">
+ <div class="color-square compat-other"></div>
+ <p><b><?=___('compatibility_report_legend_other', 'Other Versions')?></b><br /><?=sprintf(___('compatibility_report_legend_other_description', 'Add-ons not compatible with any version of %1$s'), APP_PRETTYNAME." {$version}")?></p>
+ </div>
+ <div class="legend-box">
+ <div class="color-square compat-alpha"></div>
+ <p><b><?=___('compatibility_report_legend_alpha', 'Alpha Versions')?></b><br /><?=sprintf(___('compatibility_report_legend_alpha_description', 'Add-ons compatible with an alpha version of %1$s'), APP_PRETTYNAME." {$version}")?></p>
+ </div>
+ <div class="legend-box">
+ <div class="color-square compat-beta"></div>
+ <p><b><?=___('compatibility_report_legend_beta', 'Beta Versions')?></b><br /><?=sprintf(___('compatibility_report_legend_beta_description', 'Add-ons compatible with a beta version or release candidate of %1$s'), APP_PRETTYNAME." {$version}")?></p>
+ </div>
+ <div class="legend-box">
+ <div class="color-square compat-latest"></div>
+ <p><b><?=___('compatibility_report_legend_latest', 'Latest Version')?></b><br /><?=sprintf(___('compatibility_report_legend_latest_description', 'Add-ons up-to-date with the latest builds of %1$s'), APP_PRETTYNAME." {$version}")?></p>
+ </div>
+ </div>
+ </div>
+
+ <div class="details-link"><a href="#" onclick="compatibility.viewReportDetails();"><?=___('compatibility_report_detailed_link', 'View Detailed Report')?></a></div>
+ </div>
+
+ <div id="report-details">
+ <div class="header">
+ <div class="title">
+ <?=$html->image('wordmarks/firefox-'.$version.'_small.png', array('alt' => APP_PRETTYNAME." {$version}"))?><?=___('compatibility_dashboard_report', 'Add-on Compatibility Report')?>
+ </div>
+ </div>
+ <div class="loading"><?=___('compatibility_dashboard_loading', 'Loading data...')?></div>
+ <div id="report-details-data"></div>
+ </div>
+
+ <div id="developers-intro">
+ <div class="header">
+ <div class="title">
+ <?=$html->image('wordmarks/firefox-'.$version.'_small.png', array('alt' => APP_PRETTYNAME." {$version}"))?><?=___('compatibility_developer_info', 'Information for Add-on Developers')?>
+ </div>
+ </div>
+ <br />
+ <a href="https://developer.mozilla.org/En/Updating_extensions_for_<?=APP_PRETTYNAME." {$version}"?>"><?=$html->image('mdc-logo.png', array('class' => 'rightalign', 'alt' => ___('compatibility_developers_mdclogo_alt', 'Mozilla Developer Center Logo')))?></a>
+ <?=$localization->includeLocalPage('compatibility_developer_tips', array(
+ APP_PRETTYNAME." {$version}",
+ APP_PRETTYNAME."_{$version}",
+ APP_PRETTYNAME." {$version}",
+ APP_PRETTYNAME."_{$version}",
+ $html->url('/developers')
+ ))?>
+
+ <?php if ($loggedin): ?>
+ <div class="details-link"><a href="#" onclick="compatibility.viewDeveloperDetails();"><?=___('compatibility_developers_check_status', 'Check Status of My Add-ons')?></a></div>
+ <?php else: ?>
+ <p class="login"><?=sprintf(___('compatibility_developers_login_first', 'If you have add-ons hosted on Mozilla Add-ons, <a href="%1$s">please login</a> to analyze the status of your add-ons for %2$s.'), $html->url($html->login_url()), APP_PRETTYNAME." {$version}")?></p>
+ <?php endif; ?>
+ </div>
+
+ <div id="developers-details">
+ <div class="header">
+ <div class="title">
+ <?=$html->image('wordmarks/firefox-'.$version.'_small.png', array('alt' => APP_PRETTYNAME." {$version}"))?><?=___('compatibility_developers_results', 'Add-on Status Check Results')?>
+ </div>
+ </div>
+
+ <div class="loading"><?=___('compatibility_developers_retrieving', 'Retrieving status of hosted add-ons...')?></div>
+ <div id="developers-details-data"></div>
+ </div>
+
+ <div id="users-intro">
+ <div class="header">
+ <div class="title">
+ <?=$html->image('wordmarks/firefox-'.$version.'_small.png', array('alt' => APP_PRETTYNAME." {$version}"))?><?=___('compatibility_user_info', 'Information for Add-on Users')?>
+ </div>
+ </div>
+ <br />
+ <?=$localization->includeLocalPage('compatibility_user_tips', array(
+ APP_PRETTYNAME." {$version}",
+ APP_PRETTYNAME,
+ APP_PRETTYNAME,
+ APP_PRETTYNAME." {$version}",
+ APP_PRETTYNAME." {$version}",
+ $html->url('/'),
+ APP_PRETTYNAME
+ ))?>
+ </div>
+ </div>
+</div>
+
+<script type="text/javascript">
+var detailsURL = '<?=$html->url('/compatibility/report/'.$version.'/ajax')?>';
+var developerStatusURL = '<?=$html->url('/compatibility/developers/'.$version.'/ajax')?>';
+var version = '<?=$version?>';
+</script>
diff --git a/site/app/views/compatibility/developers.thtml b/site/app/views/compatibility/developers.thtml
new file mode 100644
index 0000000..45af4ee
--- /dev/null
+++ b/site/app/views/compatibility/developers.thtml
@@ -0,0 +1,82 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Justin Scott <fligtar@mozilla.com> (Original Author)
+ * Wil Clouser <wclouser@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+if ($format != 'ajax') {
+$this->viewVars['bodyclass'] = 'inverse';
+?>
+<div id="content" class="primary prose" style="min-height: 400px;">
+ <h2><?=___('compatibility_developer_info', 'Information for Add-on Developers')?></h2>
+ <?=$localization->includeLocalPage('compatibility_developer_tips', array(
+ APP_PRETTYNAME." {$version}",
+ APP_PRETTYNAME."_{$version}",
+ APP_PRETTYNAME." {$version}",
+ APP_PRETTYNAME."_{$version}",
+ $html->url('/developers')
+ ))?>
+<?php
+}
+if ($loggedin) {
+ if ($format != 'ajax') {
+ echo '<h2>'.___('compatibility_developers_results', 'Add-on Status Check Results').'</h2>';
+ }
+
+ if (!empty($addons)) {
+ echo '<ul class="developer-addons">';
+ foreach ($addons as $addon_id => $addon) {
+ echo '<li>';
+ echo '<div class="appversion compat-'.$addon['grade'].'">'.$addon['appversion'].'</div>';
+ echo '<div class="addon-details">';
+ echo '<span class="name">'.$addon['name'].'</span>';
+ echo '<span class="details">'.sprintf(___('compatibility_developers_user_count', '%1$s %2$s users (%3$s&#37; of total)'), $html->number_format($addon['versionCount'], 0), APP_PRETTYNAME." {$version}", $addon['percentage']);
+ echo '&nbsp;&middot;&nbsp;<a href="'.$html->url('/developers/versions/edit/'.$addon['latestVersion']).'">'.___('compatibility_developers_adjust_maxversion', 'Adjust maxVersion without uploading').'</a></span>';
+ echo '</div>';
+ echo '</li>';
+ }
+ echo '</ul>';
+ }
+ else {
+ echo '<p class="login">'.___('compatibility_developers_no_addons', 'You do not have any add-ons hosted on Mozilla Add-ons.').'</p>';
+ }
+}
+else {
+ echo '<p class="login">'.sprintf(__('compatibility_developers_login_first', 'If you have add-ons hosted on Mozilla Add-ons, <a href="%1$s">please login</a> to analyze the status of your add-ons for %2$s.'), $html->url($html->login_url()), APP_PRETTYNAME." {$version}").'</p>';
+}
+?>
+<?php if ($format != 'ajax'): ?>
+</div>
+<?php endif; ?>
diff --git a/site/app/views/compatibility/report.thtml b/site/app/views/compatibility/report.thtml
new file mode 100644
index 0000000..f84024f
--- /dev/null
+++ b/site/app/views/compatibility/report.thtml
@@ -0,0 +1,74 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Justin Scott <fligtar@mozilla.com> (Original Author)
+ * Wil Clouser <wclouser@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+if ($format != 'ajax'):
+$this->viewVars['bodyclass'] = 'inverse';
+?>
+<div id="content" class="primary prose" style="min-height: 400px;">
+ <h2><?=___('compatibility_dashboard_report', 'Add-on Compatibility Report')?></h2>
+<?php endif; ?>
+ <p class="intro"><?=___('compatibility_report_detail_intro', 'The add-ons below make up 95% of add-on usage known to Mozilla and are ordered by their usage size.')?></p>
+ <table id="compat-report">
+ <tbody>
+ <?php
+ $bar_width = 400;
+ $bar_current_width = 0;
+ $i = 0;
+ foreach ($addons as $addon) {
+ $class = $addon['classification'];
+
+ echo '<tr'.($i > 5000 ? ' style="display: none;"' : '').'>';
+ echo '<td class="name"><a href="'.$html->url('/addon/'.$addon['id']).'" target="_blank">'.$addon['name'].'</a></td>';
+ echo '<td><span class="maxversion compat-'.$class.'">'.$addon['maxversion'].'</span></td>';
+ $width = ceil($bar_width * $addon['percentage']);
+ echo '<td class="bar">';
+ echo '<div class="bar">';
+ echo '<div class="used-bar" style="width: '.$bar_current_width.'px;"></div>';
+ echo '<div class="new-bar compat-'.$class.'" style="width: '.$width.'px;"></div>';
+ echo '</div>';
+ echo '</td>';
+ echo '</tr>';
+ $bar_current_width += $width;
+ $i++;
+ }
+ ?>
+ </tbody>
+ </table>
+<?php if ($format != 'ajax'): ?>
+</div>
+<?php endif; ?>
diff --git a/site/app/views/compatibility/users.thtml b/site/app/views/compatibility/users.thtml
new file mode 100644
index 0000000..b214dad
--- /dev/null
+++ b/site/app/views/compatibility/users.thtml
@@ -0,0 +1,52 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Justin Scott <fligtar@mozilla.com> (Original Author)
+ * Wil Clouser <wclouser@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+$this->viewVars['bodyclass'] = 'inverse';
+?>
+<div id="content" class="primary prose" style="min-height: 400px;">
+ <h2><?=___('compatibility_user_info', 'Information for Add-on Users')?></h2>
+ <?=$localization->includeLocalPage('compatibility_user_tips', array(
+ APP_PRETTYNAME." {$version}",
+ APP_PRETTYNAME,
+ APP_PRETTYNAME,
+ APP_PRETTYNAME." {$version}",
+ APP_PRETTYNAME." {$version}",
+ $html->url('/'),
+ APP_PRETTYNAME
+ ))?>
+</div>
diff --git a/site/app/views/developers/addon_edit.thtml b/site/app/views/developers/addon_edit.thtml
new file mode 100644
index 0000000..5e0d147
--- /dev/null
+++ b/site/app/views/developers/addon_edit.thtml
@@ -0,0 +1,57 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Justin Scott <fligtar@mozilla.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+?>
+<div id="content">
+ <?=$this->renderElement('developers/sidebar', array('addons' => $all_addons, 'extra' => 'developers/editbox'));?>
+
+ <div id="content-main">
+ <?=$this->renderElement('developers/addonheader', array('title' => sprintf(___('devcp_title_edit_addon'), $addon_name), 'addon_id' => $addon_id));?>
+
+ <dl id="edit-listing" class="actionbar">
+ <dt class="edit-authors"><?=$html->link(___('devcp_edit_dt_manage_authors'), "/developers/addon/edit/{$addon_id}/authors")?></dt>
+ <dd><?=___('devcp_edit_dd_manage_authors')?></dd>
+ <dt class="edit-categories"><?=$html->link(___('devcp_edit_dt_manage_categories'), "/developers/addon/edit/{$addon_id}/categories")?></dt>
+ <dd><?=___('devcp_edit_dd_manage_categories')?></dd>
+ <dt class="edit-descriptions"><?=$html->link(___('devcp_edit_dt_manage_descriptions'), "/developers/addon/edit/{$addon_id}/descriptions")?></dt>
+ <dd><?=___('devcp_edit_dd_manage_description')?></dd>
+ <dt class="edit-properties"><?=$html->link(___('devcp_edit_dt_manage_properties'), "/developers/addon/edit/{$addon_id}/properties")?></dt>
+ <dd><?=___('devcp_edit_dd_manage_properties')?></dd>
+ </dl>
+
+ </div>
+</div>
diff --git a/site/app/views/developers/addon_edit_authors.thtml b/site/app/views/developers/addon_edit_authors.thtml
new file mode 100644
index 0000000..86dda99
--- /dev/null
+++ b/site/app/views/developers/addon_edit_authors.thtml
@@ -0,0 +1,118 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Justin Scott <fligtar@mozilla.com> (Original Author)
+ * Frederic Wenzel <fwenzel@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+?>
+<div id="content">
+ <?=$this->renderElement('developers/sidebar', array('addons' => $all_addons, 'extra' => 'developers/editbox'));?>
+
+ <div id="content-main" class="<?=($author_role >= AUTHOR_ROLE_OWNER ? 'privs' : 'no-privs')?>">
+ <?=$this->renderElement('developers/addonheader', array('title' => sprintf(___('devcp_title_edit_addon'), $addon_name), 'addon_id' => $addon_id));?>
+ <?php
+ if (!empty($success)) {
+ echo '<div class="notice-success rounded">'.___('devcp_notice_changes_saved').'</div>';
+ }
+ ?>
+ <h2><?=___('devcp_edit_authors_header_manage')?></h2>
+
+ <?=$this->renderElement('noscript')?>
+ <?=$this->renderElement('developers/rolecheck')?>
+ <form id="addon-edit-authors-form" action="" method="post">
+ <?=$html->hiddenSession();?>
+
+ <div class="graybox field rounded spaced">
+ <h4><?=___('devcp_edit_authors_header_current')?></h4>
+ <table id="author-table" class="pretty-table">
+ <thead><tr>
+ <th></th>
+ <th><?=___('devcp_edit_authors_th_author')?></th>
+ <th><?=___('devcp_edit_authors_th_role')?></th>
+ <th><?=___('devcp_edit_authors_th_listed')?></th>
+ <th></th>
+ </tr></thead>
+ <tbody></tbody>
+ </table>
+ <div class="save-changes rounded">
+ <strong><?=___('devcp_notice_unsaved_changes')?></strong> <?=___('devcp_edit_authors_click_save')?>
+ </div>
+ <div class="add-button-container"><a href="#add-author" onclick="addon_edit_authors.showAddForm();" class="add-button rounded"><?=___('devcp_edit_authors_add_author')?></a></div>
+ </div>
+ </form>
+
+ <div id="empty-authors" class="notice-error rounded" style="display:none"><span><?=___('devcp_error_empty_authors', 'Your add-on must have at least one owner.')?></span></div>
+ <div class="action-button-container centered"><a href="#" id="submit" onclick="addon_edit_authors.save(); return false;" class="action-button rounded"><?=___('devcp_edit_authors_update_author')?></a></div>
+ <br />
+
+ <div id="add-author" class="graybox rounded spaced field" style="display: none;">
+ <h4><?=___('devcp_edit_authors_add_author')?></h4>
+ <br />
+ <p><label><?=___('devcp_edit_authors_add_email')?> <input id="add-email" type="text" size="40" /></label></p>
+ <div id="add-error" class="rounded"></div>
+
+ <p><?=___('devcp_edit_authors_select_role')?></p>
+ <ul>
+ <li><label><input id="add-role-owner" type="radio" name="role" checked="checked" />&nbsp;</strong><?=___('devcp_edit_authors_label_owner')?></label></li>
+ <li><label><input id="add-role-developer" type="radio" name="role" />&nbsp;</strong><?=___('devcp_edit_authors_label_developer')?></label></li>
+ <li><label><input id="add-role-viewer" type="radio" name="role" />&nbsp;</strong><?=___('devcp_edit_authors_label_viewer')?></label></li>
+ </ul>
+
+ <p><label><input id="add-listed" type="checkbox" checked="checked" />&nbsp;<?=___('devcp_edit_authors_label_add_listed')?></label></p>
+
+ <table><tr><td>
+ <div id="add-author-button" class="add-button-container"><a href="#author-table" onclick="return addon_edit_authors.checkAddForm();" class="add-button rounded bigger"><?=___('devcp_edit_authors_add_author_button')?></a></div>
+ </td><td valign="middle">
+ <div id="add-loading"><?=$html->image('ajax_loading.gif', array('alt' => 'Loading'))?>&nbsp;<?=___('devcp_edit_authors_add_loading')?></div>
+ </td></tr></table>
+ </div>
+ </div>
+</div>
+<script type="text/javascript">
+var jsonURL = '<?=$html->url('/developers/json')?>';
+var imageURL = '<?=$html->url('/img', true, false, false)?>';
+var profileURL = '<?=$html->url('/user')?>';
+
+$(document).ready(function() {
+<?php
+ if (!empty($authors)) {
+ foreach ($authors as $author) {
+ echo "addon_edit_authors.addAuthor({$author['User']['id']}, '{$author['User']['firstname']} {$author['User']['lastname']} ({$author['User']['email']})', {$author['addons_users']['role']}, ".($author['addons_users']['listed'] == 1 ? 'true' : 'false').");\n";
+ }
+ }
+?>
+
+});
+</script>
diff --git a/site/app/views/developers/addon_edit_categories.thtml b/site/app/views/developers/addon_edit_categories.thtml
new file mode 100644
index 0000000..4950629
--- /dev/null
+++ b/site/app/views/developers/addon_edit_categories.thtml
@@ -0,0 +1,107 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Justin Scott <fligtar@mozilla.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+?>
+<div id="content">
+ <?=$this->renderElement('developers/sidebar', array('addons' => $all_addons, 'extra' => 'developers/editbox'));?>
+
+ <div id="content-main" class="<?=($author_role >= AUTHOR_ROLE_DEV ? 'privs' : 'no-privs')?>">
+ <?=$this->renderElement('developers/addonheader', array('title' => sprintf(___('devcp_title_edit_addon'), $addon_name), 'addon_id' => $addon_id));?>
+ <?php
+ if (!empty($success)) {
+ echo '<div class="notice-success rounded">'.___('devcp_notice_changes_saved').'</div>';
+ }
+ ?>
+ <h2><?=___('devcp_edit_categories_header_manage')?></h2>
+ <?=$this->renderElement('noscript')?>
+ <?=$this->renderElement('developers/rolecheck')?>
+ <?php
+ if (!empty($sortedTags)) {
+ echo '<form id="addon-edit-categories-form" action="" method="post">';
+ echo $html->hiddenSession();
+ foreach ($sortedTags as $application_id => $tags) {
+ $otherSelected = !empty($otherTags[$application_id]) && in_array($otherTags[$application_id], $currentTags);
+
+ echo '<div class="edit-categories-box field graybox rounded spaced app-'.$application_id.'">';
+ echo '<h4 style="border-bottom: none;">'.$html->image('app-icons/'.strtolower($applications[$application_id]).'_small.png', array('alt' => $applications[$application_id]));
+ echo sprintf(___('devcp_edit_categories_header_application'), $applications[$application_id]).'</h4>';
+ if (!empty($tags)) {
+ echo '<p>'.sprintf(___('devcp_edit_categories_select_application_categories'), $applications[$application_id]).':</p>';
+ echo '<table style="width: 100%;"><tr><td style="width: 50%;">';
+ for ($i = 1; $i <= 3; $i++) {
+ $selected = false;
+ echo '<label>'.sprintf(___('devcp_edit_categories_label_category_num'), $i).':&nbsp;';
+ echo '<select name="data[Tag]['.$application_id.'][]"'.($otherSelected ? ' disabled="disabled"' : '').'>';
+ echo '<option value="" style="color: gray;">'.___('devcp_edit_authors_option_empty').'</option>';
+ foreach ($tags as $tag_id => $tag_name) {
+ if ($otherTags[$application_id] == $tag_id)
+ continue;
+
+ echo '<option value="'.$tag_id.'"';
+ if (in_array($tag_id, $currentTags) && !$selected) {
+ echo ' selected="selected"';
+ unset($currentTags[array_search($tag_id, $currentTags)]);
+ $selected = true;
+ }
+ echo ' onmouseover="addon_edit_categories.updateDescription('.$application_id.', \''.$html->entities('<strong>'.$tag_name.'</strong><br />'.$html->entities($tagDescriptions[$tag_id])).'\');"';
+ echo '>'.$html->entities($tag_name).'</option>'."\n";
+ }
+ echo '</select></label>';
+ }
+ if (!empty($otherTags[$application_id])) {
+ echo '<label onmouseover="addon_edit_categories.updateDescription('.$application_id.', \''.$html->entities('<strong>'.$sortedTags[$application_id][$otherTags[$application_id]].'</strong><br />'.___('devcp_edit_categories_other')).'\');">';
+ echo '<input type="checkbox" name="data[Tag]['.$application_id.'][]" value="'.$otherTags[$application_id].'" onclick="addon_edit_categories.toggleDropdowns(this, '.$application_id.');"'.($otherSelected ? ' checked="checked"' : '').' />&nbsp;';
+ echo ___('devcp_edit_categories_does_not_fit');
+ echo '</label>';
+ }
+ echo '</td><td id="edit-categories-descriptions'.$application_id.'" class="edit-categories-descriptions">'.___('devcp_edit_categories_hover').'</td></tr></table>';
+ }
+ else {
+ echo '<p>'.___('devcp_edit_categories_none_available').'</p>';
+ }
+ echo '</div>';
+ }
+
+ echo '<div class="action-button-container centered"><a href="#" onclick="addon_edit_categories.save(); return false;" class="action-button rounded">'.___('devcp_edit_categories_button_update').'</a></div>';
+ echo '</form>';
+ }
+ else {
+ echo '<p>'.___('devcp_edit_categories_none_available').'</p>';
+ }
+ ?>
+ </div>
+</div>
diff --git a/site/app/views/developers/addon_edit_descriptions.thtml b/site/app/views/developers/addon_edit_descriptions.thtml
new file mode 100644
index 0000000..2dcbd2e
--- /dev/null
+++ b/site/app/views/developers/addon_edit_descriptions.thtml
@@ -0,0 +1,119 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Justin Scott <fligtar@mozilla.com> (Original Author)
+ * Frederic Wenzel <fwenzel@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+?>
+<div id="content">
+ <?=$this->renderElement('developers/sidebar', array('addons' => $all_addons, 'extra' => 'developers/editbox'));?>
+
+ <div id="content-main" class="edit-addon <?=($author_role >= AUTHOR_ROLE_DEV ? 'privs' : 'no-privs')?>">
+ <?=$this->renderElement('developers/addonheader', array('title' => sprintf(___('devcp_title_edit_addon'), $addon_name), 'addon_id' => $addon_id));?>
+ <?php
+ if (!empty($success)) {
+ echo '<div class="notice-success rounded">'.___('devcp_notice_changes_saved').'</div>';
+ }
+ ?>
+
+ <h2><?=___('devcp_edit_descriptions_header')?></h2>
+ <?=$this->renderElement('noscript')?>
+ <?=$this->renderElement('developers/rolecheck')?>
+ <form id="addon-edit-descriptions-form" action="" method="post">
+ <?=$html->hiddenSession();?>
+ <?php
+ // Retrieve language arrays from bootstrap.
+ global $valid_languages, $native_languages;
+ foreach (array_keys($valid_languages) as $key) {
+ $languages[$key] = $native_languages[$key]['native'];
+ }
+ ksort($languages);
+
+ $this->translationBox = array(
+ 'defaultLocale' => $addon['Addon']['defaultlocale'],
+ 'languages' => $languages,
+ 'table' => 'Addon',
+ 'loaded' => false
+ );
+
+ // Summary
+ echo $this->renderElement('translationbox', array(
+ 'field' => 'summary',
+ 'translations' => $translations['summary'],
+ 'height' => '60',
+ 'maxLength' => '250',
+ 'displayName' => ___('devcp_edit_descriptions_transbox_summary_name'),
+ 'description' => ___('devcp_edit_descriptions_transbox_summary_description'),
+ ));
+
+ // Description
+ echo $this->renderElement('translationbox', array(
+ 'field' => 'description',
+ 'translations' => $translations['description'],
+ 'displayName' => ___('devcp_edit_descriptions_transbox_description_name'),
+ 'description' => ___('devcp_edit_descriptions_transbox_description_description'),
+ ));
+
+ // Developer Comments
+ echo $this->renderElement('translationbox', array(
+ 'field' => 'developercomments',
+ 'translations' => $translations['developercomments'],
+ 'displayName' => ___('devcp_edit_descriptions_transbox_comments_name'),
+ 'description' => ___('devcp_edit_descriptions_transbox_comments_description'),
+ ));
+
+ // EULA
+ echo $this->renderElement('translationbox', array(
+ 'field' => 'eula',
+ 'translations' => $translations['eula'],
+ 'height' => '200',
+ 'displayName' => ___('devcp_edit_descriptions_transbox_eula_name'),
+ 'description' => ___('devcp_edit_descriptions_transbox_eula_description'),
+ ));
+
+ // Privacy Policy
+ echo $this->renderElement('translationbox', array(
+ 'field' => 'privacypolicy',
+ 'translations' => $translations['privacypolicy'],
+ 'height' => '200',
+ 'displayName' => ___('devcp_edit_descriptions_transbox_privacy_name'),
+ 'description' => ___('devcp_edit_descriptions_transbox_privacy_description'),
+ ));
+ ?>
+ <div id="edit-error" class="error" style="display: none;"><?=___('devcp_edit_description_correct_error')?></div>
+ <div class="action-button-container centered" style="width: 600px;"><a href="#" onclick="addon_edit_descriptions.save(); return false;" class="action-button rounded"><?=___('devcp_edit_description_button_update')?></a></div>
+ </form>
+ </div>
+</div>
diff --git a/site/app/views/developers/addon_edit_properties.thtml b/site/app/views/developers/addon_edit_properties.thtml
new file mode 100644
index 0000000..d408527
--- /dev/null
+++ b/site/app/views/developers/addon_edit_properties.thtml
@@ -0,0 +1,215 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Justin Scott <fligtar@mozilla.com> (Original Author)
+ * Frederic Wenzel <fwenzel@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+?>
+<div id="content">
+ <?=$this->renderElement('developers/sidebar', array('addons' => $all_addons, 'extra' => 'developers/editbox'));?>
+
+ <div id="content-main" class="<?=($author_role >= AUTHOR_ROLE_DEV ? 'privs' : 'no-privs')?>">
+ <?=$this->renderElement('developers/addonheader', array('title' => sprintf(___('devcp_title_edit_addon'), $addon_name), 'addon_id' => $addon_id));?>
+ <?php
+ if (!empty($success)) {
+ echo '<div class="notice-success rounded">'.___('devcp_notice_changes_saved').'</div>';
+ }
+ if (!empty($errors)) {
+ echo '<div class="notice-error rounded">'.___('devcp_notice_changes_error').'</div>';
+ }
+ ?>
+ <h2><?=___('devcp_edit_properties_header')?></h2>
+ <?=$this->renderElement('noscript')?>
+ <?=$this->renderElement('developers/rolecheck')?>
+ <form id="addon-edit-properties-form" action="" method="post" enctype="multipart/form-data">
+ <?=$html->hiddenSession();?>
+ <?php
+ // Retrieve language arrays from bootstrap.
+ global $valid_languages, $native_languages;
+ foreach (array_keys($valid_languages) as $key) {
+ $languages[$key] = $native_languages[$key]['native'];
+ }
+ ksort($languages);
+
+ $this->translationBox = array(
+ 'defaultLocale' => $addon['Addon']['defaultlocale'],
+ 'languages' => $languages,
+ 'table' => 'Addon',
+ 'loaded' => false
+ );
+
+ // Name
+ echo $this->renderElement('translationbox', array(
+ 'field' => 'name',
+ 'translations' => $translations['name'],
+ 'type' => 'textbox',
+ 'displayName' => ___('devcp_edit_properties_transbox_name_name'),
+ 'description' => ___('devcp_edit_properties_transbox_name_description'),
+ ));
+ ?>
+
+ <div class="field graybox rounded spaced" style="width: 600px;">
+ <h4><?=___('devcp_edit_properties_header_default_locale')?></h4>
+ <p><?=___('devcp_edit_properties_default_locale')?></p>
+ <select name="data[Addon][defaultlocale]">
+ <?php
+ // Retrieve language arrays from bootstrap.
+ global $valid_languages, $native_languages;
+ foreach (array_keys($valid_languages) as $key) {
+ $languages[$key] = $native_languages[$key]['native'];
+ }
+ ksort($languages);
+
+ foreach ($languages as $lang_key => $lang_name) {
+ echo '<option value="'.$lang_key.'"'.($addon['Addon']['defaultlocale'] == $lang_key ? ' selected="selected"' : '').'>'.$lang_name.' ('.$lang_key.')</option>';
+ }
+ ?>
+ </select>
+
+ </div>
+
+ <div class="field graybox rounded spaced<?=(!empty($errors['icon']) ? ' errors' : '')?>" style="width: 600px;">
+ <h4><?=___('devcp_edit_properties_header_icon')?></h4>
+ <?=(!empty($errors['icon']) ? '<div class="error-message">'.$errors['icon'].'</div>' : '')?>
+ <p><?=sprintf(___('devcp_edit_properties_icon'), implode(', ', $this->controller->Developers->imageExtensions))?></p>
+ <table width="100%" id="edit-properties-icon-table">
+ <tr>
+ <th style="width: 20%;"><?=___('devcp_edit_properties_current_icon')?></th>
+ <th><?=___('devcp_edit_properties_new_icon')?></th>
+ </tr>
+ <tr>
+ <td style="text-align: center;">
+ <?php
+ $addonIconPath = $this->controller->Image->getAddonIconURL($addon_id);
+ echo '<img id="addon-icon" src="'.$addonIconPath.'" alt="" />';
+ if (!empty($addon['Addon']['icontype'])) {
+ echo '<div id="delete-icon-area" class="require-privs"><a href="#" onclick="addon_edit_properties.deleteIcon(); return false;">'.___('devcp_edit_properties_remove_icon').'</a></div>';
+ echo '<div id="undelete-icon-area" style="display: none;">'.sprintf(___('devcp_edit_properties_undelete'), 'href="#" onclick="addon_edit_properties.undeleteIcon(); return false;"').'</div>';
+ echo '<input id="delete-icon" type="hidden" name="data[Addon][deleteIcon]" value="0" />';
+ }
+ ?>
+ </td>
+ <td><input type="file" name="data[Addon][icon]" /></td>
+ </tr>
+ </table>
+ </div>
+
+ <?php
+ // Homepage
+ echo $this->renderElement('translationbox', array(
+ 'field' => 'homepage',
+ 'translations' => $translations['homepage'],
+ 'type' => 'textbox',
+ 'displayName' => ___('devcp_edit_properties_transbox_homepage_name'),
+ 'description' => ___('devcp_edit_properties_transbox_homepage_description'),
+ ));
+
+ // Support Email
+ echo $this->renderElement('translationbox', array(
+ 'field' => 'supportemail',
+ 'translations' => $translations['supportemail'],
+ 'type' => 'textbox',
+ 'displayName' => ___('devcp_edit_properties_transbox_supportemail_name'),
+ 'description' => ___('devcp_edit_properties_transbox_supportemail_description'),
+ ));
+
+ // Support URL
+ echo $this->renderElement('translationbox', array(
+ 'field' => 'supporturl',
+ 'translations' => $translations['supporturl'],
+ 'type' => 'textbox',
+ 'displayName' => ___('devcp_edit_properties_transbox_supporturl_name'),
+ 'description' => ___('devcp_edit_properties_transbox_supporturl_description'),
+ ));
+ ?>
+
+ <div class="field graybox rounded spaced" style="width: 600px;">
+ <h4><?=___('devcp_edit_properties_header_other_settings')?></h4>
+ <h5><?=___('devcp_edit_properties_header_view_source')?></h5>
+ <p class="smallmargin"><?=___('devcp_edit_properties_view_source')?></p>
+ <label class="indented"><input type="radio" name="data[Addon][viewsource]" value="1" <?=($addon['Addon']['viewsource'] == 0 ? '' : 'checked="checked"')?>/>&nbsp;<?=___('devcp_edit_properties_view_source_allow')?></label>
+ <label class="indented"><input type="radio" name="data[Addon][viewsource]" value="0" <?=($addon['Addon']['viewsource'] == 0 ? 'checked="checked"' : '')?>/>&nbsp;<?=___('devcp_edit_properties_view_source_do_not_allow')?></label>
+
+ <?php if ($addon['Addon']['addontype_id'] != ADDON_SEARCH): ?>
+ <h5><?=___('devcp_edit_properties_header_flags')?></h5>
+ <p class="smallmargin"><?=___('devcp_edit_properties_flags')?></p>
+ <label class="indented"><input type="checkbox" name="data[Addon][prerelease]" value="1" <?=($addon['Addon']['prerelease'] == 1 ? 'checked="checked"' : '')?>/>&nbsp;<?=_('devcp_edit_label_prerelease')?></label>
+ <label class="indented"><input type="checkbox" name="data[Addon][sitespecific]" value="1" <?=($addon['Addon']['sitespecific'] == 1 ? 'checked="checked"' : '')?>/>&nbsp;<?=_('devcp_edit_label_sitespecific')?></label>
+ <label class="indented"><input type="checkbox" name="data[Addon][externalsoftware]" value="1" <?=($addon['Addon']['externalsoftware'] == 1 ? 'checked="checked"' : '')?> />&nbsp;<?=_('devcp_edit_label_externalsoftware')?></label>
+ <label class="indented"><input type="checkbox" name="data[Addon][binary]" value="1" <?=($addon['Addon']['binary'] == 1 ? 'checked="checked"' : '')?> />&nbsp;<?=___('devcp_edit_properties_label_binary')?></label>
+
+ <h5><?=___('devcp_edit_properties_header_guid')?></h5>
+ <p class="smallmargin"><?=___('devcp_edit_properties_guid')?></p>
+ <label class="indented"><tt><?=$addon['Addon']['guid']?></tt></label>
+ <?php endif; ?>
+ </div>
+
+ <?php if ($this->controller->SimpleAcl->actionAllowed('Admin', 'ConfigureAnyAddon', $this->controller->Session->read('User'))): ?>
+ <div class="field graybox rounded spaced" style="width: 600px;">
+ <h4><?=___('devcp_edit_properties_header_admin_settings')?></h4>
+ <h5><?=___('devcp_edit_properties_header_trusted')?></h5>
+ <p class="smallmargin"><?=___('devcp_edit_properties_trusted')?></p>
+ <label class="indented"><input type="radio" name="data[Addon][trusted]" value="1" <?=($addon['Addon']['trusted'] == 1 ? 'checked="checked"' : '')?>/>&nbsp;<?=___('devcp_edit_properties_label_trusted')?></label>
+ <label class="indented"><input type="radio" name="data[Addon][trusted]" value="0" <?=($addon['Addon']['trusted'] == 1 ? '' : 'checked="checked"')?>/>&nbsp;<?=___('devcp_edit_properties_label_not_trusted')?></label>
+ <h5><?=___('devcp_edit_properties_header_addon_type')?></h5>
+ <select name="data[Addon][addontype_id]">
+ <?php
+ if (!empty($addontypes)) {
+ foreach ($addontypes as $addontype_id => $addontype_name) {
+ echo '<option value="'.$addontype_id.'"'.($addon['Addon']['addontype_id'] == $addontype_id ? ' selected="selected"' : '').'>'.$addontype_name.'</option>';
+ }
+ }
+ ?>
+ </select>
+
+ <h5><?=___('devcp_edit_properties_header_guid')?></h5>
+ <p class="smallmargin"><?=___('devcp_edit_properties_change_guid')?></p>
+ <input type="text" name="data[Addon][guid]" value="<?=$addon['Addon']['guid']?>" size="50" />
+
+ <?php if (in_array($addon['Addon']['addontype_id'], array(ADDON_DICT, ADDON_LPAPP))): ?>
+ <h5><?=_('devcp_edit_label_target_locale')?></h5>
+ <p class="smallmargin">Only applicable to dictionaries and language packs, this identifies the language and, optionally, region that this add-on is written for. Examples: en-US, fr, and de-AT</p>
+ <label><input type="text" name="data[Addon][target_locale]" value="<?=$html->entities($addon['Addon']['target_locale'])?>" /></label>
+ <h5><?=_('devcp_edit_label_locale_disambiguation')?></h5>
+ <p class="smallmargin">Only applicable to dictionaries and language packs, this is a short identifier to differentiate this add-on from other similar add-ons (for example, different dialects). This field is not required. Please limit the length of the field to a few short words.</p>
+ <label><input type="text" name="data[Addon][locale_disambiguation]" value="<?=$html->entities($addon['Addon']['locale_disambiguation'])?>" /></label>
+ <?php endif; ?>
+ </div>
+ <?php endif; ?>
+
+ <div class="action-button-container centered" style="width: 600px;"><a href="#" onclick="addon_edit_properties.save(); return false;" class="action-button rounded"><?=___('devcp_edit_properties_button_update')?></a></div>
+ </form>
+ </div>
+</div>
diff --git a/site/app/views/developers/addon_status.thtml b/site/app/views/developers/addon_status.thtml
new file mode 100644
index 0000000..eced95d
--- /dev/null
+++ b/site/app/views/developers/addon_status.thtml
@@ -0,0 +1,196 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Justin Scott <fligtar@mozilla.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+?>
+<div id="content">
+ <?=$this->renderElement('developers/sidebar', array('addons' => $all_addons, 'extra' => 'developers/editbox'));?>
+
+ <div id="content-main" class="<?=($author_role >= AUTHOR_ROLE_DEV ? 'privs' : 'no-privs')?>">
+ <?=$this->renderElement('developers/addonheader', array('title' => sprintf(___('devcp_addon_status_title'), $addon_name), 'addon_id' => $addon_id));?>
+ <?php
+ if (!empty($success)) {
+ echo '<div class="notice-success rounded"><span>'.___('devcp_notice_changes_saved').'</div>';
+ }
+ if (!empty($errors)) {
+ echo '<div class="notice-error rounded"><span>'.___('devcp_notice_changes_error').'</div>';
+ }
+ ?>
+ <?=$this->renderElement('noscript')?>
+ <?=$this->renderElement('developers/rolecheck')?>
+ <form id="status-form" action="" method="post" enctype="multipart/form-data">
+ <?=$html->hiddenSession();?>
+
+ <div class="field graybox rounded spaced">
+ <h4 class="status"><?=sprintf(___('devcp_addon_status_header'), '<span class="status-'.$addon['Addon']['status'].'">'.$statuses[$addon['Addon']['status']].'</span>')?></h4>
+ <p>
+ <?php
+ function status_span($i, $status) { return '<span class="status-'.$i.'">'.$status.'</span>'; }
+ // Add-on Status
+ $sandbox = status_span(STATUS_SANDBOX, ___('devcp_addon_status_sandbox'));
+ $public = status_span(STATUS_PUBLIC, ___('devcp_addon_status_public'));
+ switch ($addon['Addon']['status']) {
+ case STATUS_NULL:
+ echo ___('devcp_addon_status_switch_incomplete');
+ break;
+
+ case STATUS_SANDBOX:
+ ___('devcp_addon_status_switch_sandbox');
+ break;
+
+ case STATUS_NOMINATED:
+ ___('devcp_addon_status_switch_sandbox');
+ echo '</p><p>';
+ echo sprintf(___('devcp_addon_status_switch_nominated'), $nominationCount);
+ break;
+
+ case STATUS_PENDING:
+ echo sprintf(___('devcp_addon_status_switch_pending'), 'amo-editors@mozilla.org');
+ break;
+
+ case STATUS_PUBLIC:
+ ___('devcp_addon_status_switch_public');
+ break;
+
+ case STATUS_DISABLED:
+ echo sprintf(___('devcp_addon_status_switch_disabled'), 'amo-admins@mozilla.org');
+ break;
+ }
+ ?>
+ </p>
+
+ <?php
+ if ($addon['Addon']['status'] == STATUS_NULL) {
+ echo '<h5>'.___('devcp_addon_status_header_criteria').'</h5>';
+ echo '<ul class="criteria">';
+ echo '<li class="'.($criteria['name'] ? 'pass' : 'fail').'">'.___('devcp_addon_status_criteria_name').'</li>';
+ echo '<li class="'.($criteria['summary'] ? 'pass' : 'fail').'">'.___('devcp_addon_status_criteria_summary').'</li>';
+ echo '<li class="'.($criteria['description'] ? 'pass' : 'fail').'">'.___('devcp_addon_status_criteria_description').'</li>';
+ echo '<li class="'.($criteria['category'] ? 'pass' : 'fail').'">'.___('devcp_addon_status_criteria_category').'</li>';
+ echo '</ul>';
+
+ $completionEnabled = false;
+ if ($criteria['name'] && $criteria['summary'] && $criteria['description'] && $criteria['category']) {
+ $completionEnabled = true;
+ echo '<p>'.sprintf(___('devcp_addon_status_completion_enabled'), $sandbox).'</p>';
+ }
+ else {
+ echo '<p>'.sprintf(___('devcp_addon_status_completion_disabled'), $sandbox).'</p>';
+ }
+ }
+
+ $nominationEnabled = false;
+ if ($addon['Addon']['status'] == STATUS_SANDBOX || $addon['Addon']['higheststatus'] < STATUS_PUBLIC) {
+ echo '<h5>'.___('devcp_addon_status_header_nomination').'</h5>';
+ echo '<ul class="criteria">';
+ echo '<li class="'.($criteria['previews'] ? 'pass' : 'fail').'">'.___('devcp_addon_status_criteria_preview').'</li>';
+ echo '<li class="'.($criteria['prerelease'] ? 'pass' : 'fail').'">'.___('devcp_addon_status_criteria_prerelease').'</li>';
+ echo '</ul>';
+
+ if ((!in_array($addon['Addon']['addontype_id'], array(ADDON_EXTENSION, ADDON_THEME)) || $criteria['previews']) && $criteria['prerelease']) {
+ $nominationEnabled = true;
+ echo '<p>'.___('devcp_addon_status_nominate_enabled').'</p>';
+ }
+ else {
+ echo '<p>'.___('devcp_addon_status_nominate_disabled').'</p>';
+ }
+ }
+
+ // Actions
+ $actions = '';
+ if ($addon['Addon']['status'] == STATUS_NULL && $completionEnabled === true) {
+ $actions .= '<tr><td class="action"><a href="'.$html->url("/developers/addon/status/{$addon_id}/complete").'" class="complete add-button rounded">'.___('devcp_addon_status_action_complete').'</a></td>';
+ $actions .= '<td class="description">'.___('devcp_addon_status_action_complete_description').'</td></tr>';
+ }
+ if ($addon['Addon']['status'] == STATUS_SANDBOX && $nominationEnabled === true) {
+ $actions .= '<tr><td class="action"><a href="'.$html->url("/developers/addon/status/{$addon_id}/nominate").'" class="nominate add-button rounded">'.___('devcp_addon_status_action_nominate').'</a></td>';
+ $actions .= '<td class="description">'.___('devcp_addon_status_action_nominate_description').'</td></tr>';
+ }
+ if ($addon['Addon']['status'] == STATUS_PUBLIC) {
+ $actions .= '<tr><td class="action"><a href="'.$html->url("/developers/addon/status/{$addon_id}/sandbox").'" class="to-sandbox add-button rounded">'.___('devcp_addon_status_action_move').'</a></td>';
+ $actions .= '<td class="description">'.___('devcp_addon_status_action_move_description').'</td></tr>';
+ }
+ if ($addon['Addon']['status'] == STATUS_SANDBOX && $addon['Addon']['higheststatus'] == STATUS_PUBLIC) {
+ $actions .= '<tr><td class="action"><a href="'.$html->url("/developers/addon/status/{$addon_id}/public").'" class="to-public add-button rounded">'.___('devcp_addon_status_action_public').'</a></td>';
+ $actions .= '<td class="description">'.___('devcp_addon_status_action_public_description').'</td></tr>';
+ }
+
+ if (!empty($actions)) {
+ echo '<h5>'.___('devcp_addon_status_header_actions').'</h5>';
+ echo '<table class="actions"><tbody>';
+ echo $actions;
+ echo '</tbody></table>';
+ }
+ ?>
+ </div>
+
+ <div class="field graybox rounded spaced">
+ <p>
+ <?php
+ if ($addon['Addon']['inactive'] == 1) {
+ echo '<h4 class="status">'.___('devcp_addon_status_header_inactive').'</h4>';
+ echo ___('devcp_addon_status_inactive');
+ }
+ else {
+ echo '<h4 class="status">'.___('devcp_addon_status_header_active').'</h4>';
+ echo ___('devcp_addon_status_active');
+ }
+ ?>
+ </p>
+ <h5><?=___('devcp_addon_status_header_actions')?></h5>
+ <table class="actions"><tbody>
+ <?php
+ if ($addon['Addon']['inactive'] == 1) {
+ echo '<tr><td class="action"><a href="'.$html->url("/developers/addon/status/{$addon_id}/active").'" class="make-active add-button rounded">'.___('devcp_addon_status_action_activate').'</a></td>';
+ echo '<td class="description">'.___('devcp_addon_status_action_activate_description').'</tr>';
+ }
+ else {
+ echo '<tr><td class="action"><a href="'.$html->url("/developers/addon/status/{$addon_id}/inactive").'" class="make-inactive add-button rounded">'.___('devcp_addon_status_action_deactivate').'</td>';
+ echo '<td class="description">'.___('devcp_addon_status_action_deactivate_description').'</tr>';
+ }
+ ?>
+ </tbody></table>
+ </div>
+
+ <?php if ($addon['Addon']['trusted'] == 1): ?>
+ <div class="field graybox rounded spaced">
+ <h4 class="status"><?=___('devcp_addon_status_header_trusted')?></h4>
+ <p><?=___('devcp_addon_status_trusted')?></p>
+ </div>
+ <?php endif; ?>
+ </form>
+ </div>
+</div>
diff --git a/site/app/views/developers/addon_status_confirm.thtml b/site/app/views/developers/addon_status_confirm.thtml
new file mode 100644
index 0000000..fb3f6a3
--- /dev/null
+++ b/site/app/views/developers/addon_status_confirm.thtml
@@ -0,0 +1,80 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Justin Scott <fligtar@mozilla.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+?>
+<div id="content">
+ <?=$this->renderElement('developers/sidebar', array('addons' => $all_addons, 'extra' => 'developers/editbox'));?>
+
+ <div id="content-main" class="<?=($author_role >= AUTHOR_ROLE_DEV ? 'privs' : 'no-privs')?>">
+ <?=$this->renderElement('developers/addonheader', array('title' => sprintf(___('devcp_addon_status_title'), $addon_name), 'addon_id' => $addon_id));?>
+ <?=$this->renderElement('noscript')?>
+ <?=$this->renderElement('developers/rolecheck')?>
+ <form id="status-form" name="status-form" action="" method="post">
+ <?=$html->hiddenSession();?>
+ <input type="hidden" name="confirmed" value="true" />
+ <div class="graybox field rounded">
+ <h4><?=___('devcp_status_confirm_header_sure')?></h4>
+ <p>
+ <?php
+ switch ($subaction) {
+ case 'inactive':
+ echo ___('devcp_status_confirm_inactive').'</p><p>'.___('devcp_status_confirm_inactive_sure');
+ break;
+
+ case 'active':
+ echo ___('devcp_status_confirm_active').'</p><p>'.___('devcp_status_confirm_active_sure');
+ break;
+
+ case 'sandbox':
+ echo ___('devcp_status_confirm_sandbox').'</p><p>'.___('devcp_status_confirm_sandbox_sure');
+ break;
+
+ case 'public':
+ echo ___('devcp_status_confirm_public').'</p><p>'.___('devcp_status_confirm_public_sure');
+ break;
+ }
+ ?>
+ </p>
+ <div style="text-align: center;">
+ <a href="#" onclick="addon_status.confirm(); return false;" class="complete add-button rounded"><?=___('devcp_status_confirm_yes')?></a>&nbsp;&nbsp;
+ <a href="<?=$html->url("/developers/addon/status/{$addon_id}/")?>" class="button rounded"><?=___('devcp_status_confirm_no')?></a>
+ </div>
+ </div>
+ </form>
+
+ </div>
+</div> \ No newline at end of file
diff --git a/site/app/views/developers/addon_status_nominate.thtml b/site/app/views/developers/addon_status_nominate.thtml
new file mode 100644
index 0000000..2373732
--- /dev/null
+++ b/site/app/views/developers/addon_status_nominate.thtml
@@ -0,0 +1,69 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Justin Scott <fligtar@mozilla.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+?>
+<div id="content">
+ <?=$this->renderElement('developers/sidebar', array('addons' => $all_addons, 'extra' => 'developers/editbox'));?>
+
+ <div id="content-main" class="<?=($author_role >= AUTHOR_ROLE_DEV ? 'privs' : 'no-privs')?>">
+ <?=$this->renderElement('developers/addonheader', array('title' => sprintf(___('devcp_addon_status_title'), $addon_name), 'addon_id' => $addon_id));?>
+ <?php
+ if (!empty($errors)) {
+ echo '<div class="notice-error rounded">'.___('devcp_status_nominate_error_notice').'</div>';
+ }
+ ?>
+ <?=$this->renderElement('noscript')?>
+ <?=$this->renderElement('developers/rolecheck')?>
+ <form id="status-form" name="status-form" action="" method="post">
+ <?=$html->hiddenSession();?>
+ <input type="hidden" name="confirmed" value="true" />
+ <div class="graybox field rounded">
+ <h4><?=___('devcp_status_nominate_header')?></h4>
+
+ <?=$localization->includeLocalPage('nomination', array($html->url('/pages/policy')))?>
+
+ <div style="text-align: center;">
+ <textarea cols="70" rows="5" name="data[Addon][nominationmessage]"><?=(!empty($addon['Addon']['nominationmessage']) ? $addon['Addon']['nominationmessage'] : '')?></textarea>
+ <div><a href="#" onclick="addon_status.confirm(); return false;" class="nominate add-button rounded"><?=sprintf(_('devcp_nominate_submit_nominate'), $addon_name)?></a><br />
+ <a href="<?=$html->url("/developers/addon/status/{$addon_id}/")?>"><?=___('devcp_nominate_cancel')?></a>
+ </div>
+ </div>
+ </div>
+ </form>
+
+ </div>
+</div> \ No newline at end of file
diff --git a/site/app/views/developers/dashboard.thtml b/site/app/views/developers/dashboard.thtml
new file mode 100644
index 0000000..2fba02b
--- /dev/null
+++ b/site/app/views/developers/dashboard.thtml
@@ -0,0 +1,118 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * Justin Scott <fligtar@gmail.com>.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Frederic Wenzel <fwenzel@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+?>
+<div id="content">
+ <?=$this->renderElement('developers/sidebar', array('addons' => $all_addons));?>
+
+ <div id="content-main">
+ <h3><?= ___('devcp_dashboard_header_main') ?></h3>
+
+ <div id="summary">
+ <?php
+ if (!empty($addons)) {
+ foreach ($addons as $addon) {
+ $addon_id = $addon['Addon']['id'];
+ $addonIconPath = $this->controller->Image->getAddonIconURL($addon_id);
+ ?>
+ <div id="addon-<?=$addon_id?>" class="addon sub">
+ <div class="addon-container">
+ <?php
+ echo '<h4><a href="'.$html->url('/addon/'.$addon_id).'">';
+ echo '<img src="'.$addonIconPath.'" alt="'.$addon['Translation']['name']['string'].'" />';
+ echo $addon['Translation']['name']['string'].'</a></h4>';
+
+ if ($addon['Addon']['status'] != STATUS_DISABLED) {
+ $latestVersion = !empty($addon['Version'][0]) ? $addon['Version'][0] : 0;
+
+ echo '<ul class="actionbar index-actions">';
+ // Edit Add-on
+ echo '<li class="edit"><a href="'.$html->url('/developers/addon/edit/'.$addon_id).'" class="view">'._('devcp_actionbar_link_edit').'</a>';
+ echo '<span class="action-details">'.sprintf(___('devcp_dashboard_last_edited'), strftime(_('date'), strtotime($addon['Addon']['modified']))).'</span></li>';
+ // Change Status
+ echo '<li class="status"><a href="'.$html->url('/developers/addon/status/'.$addon_id).'" class="view">'.___('devcp_dashboard_change_status').'</a>';
+ $active = $addon['Addon']['inactive'] == 1 ? ___('devcp_dashboard_inactive') : ___('devcp_dashboard_active');
+ echo '<span class="action-details">'.sprintf(___('devcp_dashboard_addontype_status'), $addontypes[$addon['Addon']['addontype_id']],
+ '<span class="inactive-'.$addon['Addon']['inactive'].'">'.$active.'</span>',
+ '<span class="status-'.$addon['Addon']['status'].'">'.$statuses[$addon['Addon']['status']].'</span>').'</span></li>';
+ // Statistics Dashboard
+ echo '<li class="statistics"><a href="'.$html->url('/statistics/addon/'.$addon_id).'" class="view">'._('devcp_actionbar_link_stats').'</a>';
+ echo '<span class="action-details stats">';
+ echo sprintf(_('devcp_statsbar_total_downloads'), $html->number_format($addon['Addon']['totaldownloads'], 0));
+ echo '&nbsp;&middot;&nbsp;';
+ echo sprintf(_('devcp_statsbar_weekly_downloads'), $html->number_format($addon['Addon']['weeklydownloads'], 0));
+ echo '&nbsp;&middot;&nbsp;';
+ echo sprintf(_('devcp_statsbar_adu'), $html->number_format($addon['Addon']['updatepings'], 0));
+ echo '</span></li>';
+ // Versions and Files
+ echo '<li class="versions"><a href="'.$html->url('/developers/versions/'.$addon_id).'" class="view">'.___('devcp_dashboard_versions').'</a>';
+ echo '<span class="action-details">';
+ if (!empty($latestVersion)) {
+ echo _('devcp_summary_lastversion').' '.$html->link($latestVersion['version'], '/developers/versions/edit/'.$latestVersion['id']).' ('.$this->controller->Amo->describeVersionStatus($latestVersion['File']).')';
+ if ($addon['Addon']['inactive'] != 1) {
+ echo '&nbsp;&middot;&nbsp;';
+ }
+ }
+ if ($addon['Addon']['inactive'] != 1) {
+ echo '<a href="'.$html->url('/developers/versions/add/'.$addon_id).'">'.___('devcp_dashboard_versions_new').'</a>';
+ }
+ echo '</span></li>';
+ echo '</ul>';
+ }
+ else {
+ // Admin Disabled Add-on
+ echo '<p>'.sprintf(___('devcp_dashboard_disabled_status'), '<span class ="'.STATUS_DISABLED.'">'.$statuses[STATUS_DISABLED].'</span>').'</p>';
+ echo '<p>'.sprintf(___('devcp_dashboard_disabled_questions'), 'amo-admins@mozilla.org').'</p>';
+ }
+ ?>
+ </div>
+ <div class="vex"><span><!-- bottom edge --></span></div>
+ </div>
+ <?php
+ }
+ }
+ else {
+ echo '<div class="graybox rounded">';
+ echo '<h4>'.___('devcp_dashboard_header_welcome').'</h4>';
+ echo '<p>'.___('devcp_dashboard_learn').'</p>';
+ echo '<div style="text-align: center;"><a href="'.$html->url('/developers/addon/submit').'" class="action-button rounded">'.___('devcp_dashboard_start').'</a></div>';
+ echo '</div>';
+ }
+ ?>
+ </div>
+ </div> <!-- content-main -->
+</div> <!-- content -->
diff --git a/site/app/views/developers/discuss.thtml b/site/app/views/developers/discuss.thtml
new file mode 100644
index 0000000..914ee4b
--- /dev/null
+++ b/site/app/views/developers/discuss.thtml
@@ -0,0 +1,85 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/e
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * Frederic Wenzel <fwenzel@mozilla.com>.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+?>
+<div id="content">
+ <?=$this->renderElement('developers/sidebar', array('addons' => $all_addons));?>
+
+ <div id="content-main">
+
+ <h3><?=sprintf(___('devcp_discuss_pagetitle', 'Provide More Information For the Add-on Review of %1$s'), $addonName)?></h3>
+
+
+ <p><?=sprintf(___('devcp_discuss_intro', 'A Mozilla Add-ons Editor requested further '
+ .'information from you regarding version %2$s of your add-on %1$s.'), $addonName, $versionno)?></p>
+
+ <div class="corner-box">
+ <p><?=$inforequest['Approval']['comments']?></p>
+ <cite>
+ <?=sprintf(___('devcp_discuss_writtenby', 'written by %1$s on %2$s'), $html->linkUserFromModel($inforequest['User']), strftime(_('datetime'), strtotime($inforequest['Approval']['created'])))?>
+ </cite>
+ </div>
+
+ <?php if (!empty($replies)): ?>
+ <h4><?=___('devcp_discuss_allreplies_header', 'Replies')?></h4>
+ <?php foreach ($replies as &$reply): ?>
+ <div class="corner-box">
+ <p><?=$reply['Approval']['comments']?></p>
+ <cite>
+ <?=sprintf(___('devcp_discuss_writtenby', 'written by %1$s on %2$s'), $html->linkUserFromModel($reply['User']), strftime(_('datetime'), strtotime($reply['Approval']['created'])))?>
+ </cite>
+ </div>
+ <?php endforeach; ?>
+ <?php endif; ?>
+
+ <h4><?=___('devcp_discuss_addreply_header', 'Add Reply')?></h4>
+ <?php if (!empty($error)): ?>
+ <div class="error-notice"><p><?=sprintf(___('devcp_discuss_error_notice', 'There was an error saving your reply. Please contact %1$s about the issue.'), $link->email('amo-editors@mozilla.org'))?></p></div>
+ <?php elseif (!empty($success)): ?>
+ <div><p><?=___('devcp_discuss_success_message', 'Your reply was successfully saved. The other participants of the discussion will be notified by email.')?></p></div>
+ <?php else: ?>
+ <?=$html->formTag()?>
+ <div id="commentsbox">
+ <?=$html->textarea('Approval/comments', array('cols' => '70', 'rows' => '5', 'id' => 'comments', 'class' => 'input'))?>
+ </div>
+ <div id="finish">
+ <?=$html->submit(___('devcp_discuss_submit_reply', 'Submit Reply'), array('id' => 'submit'))?>
+ </div>
+ </form>
+ <?php endif; ?>
+
+ </div> <!-- content-main -->
+</div> <!-- content -->
diff --git a/site/app/views/developers/json.thtml b/site/app/views/developers/json.thtml
new file mode 100644
index 0000000..c856e36
--- /dev/null
+++ b/site/app/views/developers/json.thtml
@@ -0,0 +1,14 @@
+<?php
+if (!defined('NO_MICROTIME'))
+ define('NO_MICROTIME', true);
+
+if (!empty($encapsulate)) {
+ echo '<div id="json">';
+ $listing->json($json, null, true);
+ echo '</div>';
+}
+else {
+ header('Content-type: text/plain');
+ $listing->json($json, null);
+}
+?> \ No newline at end of file
diff --git a/site/app/views/developers/previews.thtml b/site/app/views/developers/previews.thtml
new file mode 100644
index 0000000..e229be3
--- /dev/null
+++ b/site/app/views/developers/previews.thtml
@@ -0,0 +1,129 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Justin Scott <fligtar@mozilla.com> (Original Author)
+ * Frederic Wenzel <fwenzel@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+?>
+<div id="content">
+ <?=$this->renderElement('developers/sidebar', array('addons' => $all_addons, 'extra' => 'developers/editbox'));?>
+
+ <div id="content-main" class="<?=($author_role >= AUTHOR_ROLE_DEV ? 'privs' : 'no-privs')?>">
+ <?=$this->renderElement('developers/addonheader', array('title' => sprintf(___('devcp_previews_title'), $addon_name), 'addon_id' => $addon_id));?>
+ <?php
+ if (!empty($messages['success'])) {
+ echo '<div class="notice-success rounded"><span>'.___('devcp_previews_notice_success').'</span><br /><ul><li>'.implode('</li><li>', $messages['success']).'</li></ul></div>';
+ }
+ if (!empty($messages['errors'])) {
+ echo '<div class="notice-error rounded"><span>'.___('devcp_previews_notice_error').'</span><br /><ul><li>'.implode('</li><li>', $messages['errors']).'</li></ul></div>';
+ }
+
+ echo $this->renderElement('noscript');
+ echo $this->renderElement('developers/rolecheck');
+ echo '<form id="previews-form" action="" method="post" enctype="multipart/form-data">';
+ echo $html->hiddenSession();
+
+ if (!empty($previews)) {
+ echo '<p>'.___('devcp_previews_p_screenshots').'</p>';
+ // Retrieve language arrays from bootstrap.
+ global $valid_languages, $native_languages;
+ foreach (array_keys($valid_languages) as $key) {
+ $languages[$key] = $native_languages[$key]['native'];
+ }
+ ksort($languages);
+ $this->controller->Image->getHighlightedPreviewURL(2848);
+ $this->translationBox = array(
+ 'defaultLocale' => $addon['Addon']['defaultlocale'],
+ 'languages' => $languages,
+ 'table' => 'Preview',
+ 'loaded' => false
+ );
+
+ foreach ($previews as &$preview) {
+ ?>
+ <div class="preview-box graybox rounded spaced field">
+ <table style="width: 100%;"><tr><td style="width: 200px; text-align: center; vertical-align: top;">
+ <img src="<?=$this->controller->Image->getPreviewURL($preview['Preview']['id'])?>/0" alt="<?=___('devcp_previews_thumbnail')?>" />
+ </td><td style="vertical-align: top;">
+ <h5 style="margin-top: 0; margin-bottom: 2px;"><?=___('devcp_previews_header_caption')?></h5>
+ <?php
+ echo $this->renderElement('translationbox', array(
+ 'field' => 'caption',
+ 'id' => $preview['Preview']['id'],
+ 'translations' => !empty($translations[$preview['Preview']['id']]['caption']) ? $translations[$preview['Preview']['id']]['caption'] : array(),
+ 'height' => '60',
+ 'graybox' => false
+ ));
+ ?>
+
+ <table style="width: 100%; padding-top: 10px;"><tr><td>
+ <label><input type="radio" name="data[Preview][highlight]" value="<?=$preview['Preview']['id']?>" style="vertical-align: top;"<?=($preview['Preview']['highlight'] == 1 ? ' checked="checked"' : '')?>/>
+ <?=___('devcp_previews_label_default')?></label>
+ </td><td class="preview-buttons">
+ <a href="#" onclick="previews.showReplaceBox(this); return false;" class="edit-button rounded"><?=___('devcp_previews_a_replace')?></a>&nbsp;
+ <a href="#" onclick="previews.deletePreview(this); return false;" class="remove-button rounded"><?=___('devcp_previews_a_delete')?></a>
+ </td></tr></table>
+
+ <div class="replace-preview" style="display: none;">
+ <label><?=___('devcp_previews_label_new')?>
+ <input type="file" name="data[Preview][New][<?=$preview['Preview']['id']?>]" /></label>
+ <p><?=sprintf(___('devcp_previews_click_update'), 'href="#" onclick="previews.cancelReplace(this); return false;"')?></p>
+ </div>
+
+ </td></tr></table>
+ <input type="hidden" class="delete" name="data[Preview][Delete][<?=$preview['Preview']['id']?>]" value="false" />
+ <div class="error-message"><?=sprintf(___('devcp_previews_error_message'), 'href="#" onclick="previews.cancelDelete(this); return false;"')?></div>
+ </div>
+ <?php
+ }
+ }
+ ?>
+
+ <div id="add-preview-box" class="graybox rounded spaced field" style="<?=(!empty($previews) ? 'display: none;' : '')?>">
+ <h4><?=___('devcp_previews_add_new')?></h4>
+ <p><?=sprintf(___('devcp_previews_add_select'), implode(', ', $this->controller->Developers->imageExtensions))?></p>
+ <div id="new-preview-container">
+ <label class="new-preview"><?=___('devcp_previews_label_upload')?><input type="file" name="data[Preview][New][]" size="40" /></label>
+ </div>
+ <div class="add-button-container"><a href="#" onclick="previews.addUploadBox(); return false;" class="add-button rounded"><?=___('devcp_previews_a_another')?></a></div>
+ <div class="preview-add-button-description"><?=___('devcp_previews_click_below')?></div>
+ </div>
+
+ <div class="add-button-container" style="<?=(empty($previews) ? 'display: none;' : '')?>"><a href="#add-preview-box" onclick="previews.showAddBox(this);" class="add-button rounded"><?=___('devcp_previews_add_new')?></a></div>
+
+ <div class="action-button-container centered"><a href="#" onclick="previews.save(); return false;" class="action-button rounded"><?=___('devcp_previews_a_update')?></a></div>
+ </form>
+ </div>
+</div>
diff --git a/site/app/views/developers/uploader.thtml b/site/app/views/developers/uploader.thtml
new file mode 100644
index 0000000..579d814
--- /dev/null
+++ b/site/app/views/developers/uploader.thtml
@@ -0,0 +1,186 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Justin Scott <fligtar@mozilla.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+?>
+<div id="content">
+ <?php
+ $params = array('addons' => $all_addons);
+ if ($type != 'new') {
+ $params['extra'] = 'developers/editbox';
+ }
+ echo $this->renderElement('developers/sidebar', $params);
+
+ echo '<div id="content-main" class="'.($type != 'new' && $author_role < AUTHOR_ROLE_DEV ? 'no-privs' : 'privs').'">';
+
+ if ($type == 'new') {
+ $title = ___('devcp_uploader_title_submit');
+ $addon_id = 0;
+ }
+ elseif ($type == 'update') {
+ $title = sprintf(___('devcp_uploader_title_update'), $addon_name);
+ }
+ elseif ($type == 'file') {
+ $title = sprintf(___('devcp_uploader_title_file'), $addon_name, $version);
+ }
+ echo $this->renderElement('developers/addonheader', array('title' => $title, 'addon_id' => $addon_id));
+ ?>
+ <?=$this->renderElement('noscript')?>
+ <?=$this->renderElement('developers/rolecheck')?>
+ <div id="submission-area" class="rounded graybox">
+ <?php if ($type == 'new'): ?>
+ <div id="step-intro">
+ <h3><?=___('devcp_uploader_header_how')?></h3>
+ <?=___('devcp_uploader_how')?>
+ <div style="text-align: center;"><a href="#" onclick="upload.showAgreement(); return false;" class="action-button rounded"><?=___('devcp_uploader_a_start')?></a></div>
+ </div> <!-- /#step-intro -->
+ <?php endif; ?>
+ <?php $showAgreement = ($type == 'new' || !$hasAgreement); ?>
+ <?php if ($showAgreement): ?>
+ <div id="step-agreement" <?=($type != 'new' ? 'style="display:block"' : '')?>>
+ <p><?=_('devcp_review_agreement_please')?></p>
+ <?=$localization->includeLocalPage('developer_agreement',array($html->url('/pages/developer_faq')))?>
+
+ <?php
+ list($licenses, $trans) = $this->controller->Developers->getLicenses();
+ echo $this->renderElement('developers/license_picker',
+ array('licenses' => $licenses));
+ ?>
+ <input type="button" value="<?=___('devcp_uploader_button_agree')?>"
+ id="accept-agreement" disabled="true" onclick="upload.acceptAgreement()"/>
+ <?php
+ // Retrieve language arrays from bootstrap.
+ global $valid_languages, $native_languages;
+ foreach (array_keys($valid_languages) as $key) {
+ $languages[$key] = $native_languages[$key]['native'];
+ }
+ ksort($languages);
+
+ $this->translationBox = array(
+ 'defaultLocale' => LANG,
+ 'languages' => $languages,
+ 'table' => 'License',
+ 'loaded' => false
+ );
+ echo $this->renderElement('developers/license_translationbox',
+ array('translations' => $trans,
+ 'fieldname' => 'text'));
+ ?>
+ <script type="text/javascript">
+ $(document).ready(function($){
+ $('#license-name').change(function() {
+ if ($('#license-name').val() == 'null')
+ $('#accept-agreement').attr('disabled', 'true');
+ else
+ $('#accept-agreement').removeAttr('disabled');
+ });
+ $('#license-name').change();
+ });
+ </script>
+ </div> <!-- /#step-agreement -->
+ <?php endif; ?>
+
+ <div id="file-upload"<?=($showAgreement ? ' style="display: none;"' : '')?>>
+ <h3><?=___('devcp_uploader_header_upload')?></h3>
+ <p><?=___('devcp_uploader_p_upload')?>
+ <br />
+ <form id="upload-form" method="post" enctype="multipart/form-data" action="<?=$html->url('/developers/json/fileupload/'.$type)?>" target="upload-frame" onsubmit="return upload.uploadFile();">
+ <?=$html->hiddenSession();?>
+ <?=(!empty($addon_id) ? '<input type="hidden" name="data[Addon][id]" value="'.$addon_id.'" />' : '')?>
+ <?=(!empty($version_id) ? '<input type="hidden" name="data[Version][id]" value="'.$version_id.'" />' : '')?>
+ <label><?=___('devcp_uploader_label_upload_field')?><input id="upload-field" type="file" name="file" /></label><br />
+ <?=___('devcp_uploader_label_platformtype')?>&nbsp;&nbsp;<label><input type="radio" name="platformtype" onclick="upload.platformAll();" checked />&nbsp;<?=___('devcp_uploader_platformtype_all')?></label>&nbsp;&nbsp;
+ <label><input type="radio" name="platformtype" onclick="upload.platformSpecific();" />&nbsp;<?=___('devcp_uploader_platformtype_specific')?></label>
+ <?php
+ $platforms = $this->controller->Platform->getNames();
+ foreach ($platforms as $platform_id => $platform_name) {
+ if ($platform_id == PLATFORM_ALL) continue;
+ echo '&nbsp;&nbsp;<label class="specific-platforms disabled"><input type="checkbox" name="data[File][platform_id][]" value="'.$platform_id.'" disabled="disabled" />'.$platform_name.'</label>';
+ }
+ ?>
+ <div class="submit">
+ <input type="submit" value="<?=___('devcp_input_upload_file')?>" class="require-privs" />
+ </div>
+ <div id="upload-loading"><?=$html->image('ajax_loading.gif')?>&nbsp;<?=___('devcp_uploader_ajax_loading')?></div>
+ </form>
+ <div id="upload-error" class="redbox-tr"><div class="redbox-tl">
+ <div id="upload-error-content">
+ <h4><?=___('devcp_uploader_header_error')?></h4>
+ <p id="upload-error-text" class="smallmargin"></p>
+ <p class="smallmargin"><?=___('devcp_uploader_error_correct')?></p>
+ </div>
+ <div class="redbox-br"><div class="redbox-bl"></div></div>
+ </div></div>
+ </div><!-- /#file-upload -->
+
+ </div><!-- /#submission-area -->
+
+ <div id="upload-success" class="greenbox-tr"><div class="greenbox-tl">
+ <?php if ($type == 'new'): ?>
+ <div id="addon-created-content">
+ <h3><?=___('devcp_uploader_header_created')?>
+ <div id="created-results">
+ <?=sprintf(___('devcp_uploader_created_results'), 'href="'.$html->url('/developers/addon/status/').'" id="status-link"')?>
+ <div class="action-button-container centered"><a id="complete-link" href="<?=$html->url('/developers/addon/edit/')?>" class="action-button rounded"><?=___('devcp_uploader_button_edit')?></a></div>
+ <div style="text-align: center;"><a href="<?=$html->url('/developers')?>"><?=___('devcp_uploader_button_later')?></a></div>
+ </div>
+ </div><!-- /#addon-created-content -->
+ <?php elseif ($type == 'update'): ?>
+ <div id="version-created-content">
+ <h3><?=sprintf(___('devcp_uploader_header_update_created'), '<span id="new-version-number"></span>')?></h3>
+ <div id="created-results">
+ <p><?=sprintf(___('devcp_uploader_p_update_created'), '<span id="new-file-status"></span>')?></p>
+ <p id="pending-message"><?=sprintf(___('devcp_uploader_p_pending_version'), '<span id="queue-count"></span>', 'href="https://wiki.mozilla.org/Update:Editors"')?></p>
+ <p><?=sprintf(___('devcp_uploader_p_update_version'), '/developers/versions/edit/', '/developers/addon/status/'.$addon_id)?>
+ <div class="action-button-container centered"><a id="complete-link" href="<?=$html->url('/developers/versions/edit/')?>" class="action-button rounded"><?=___('devcp_uploader_button_release')?></a></div>
+ </div>
+ </div><!-- /#version-created-content -->
+ <?php elseif ($type == 'file'): ?>
+ <div id="file-created-content">
+ <h3><?=___('devcp_uploader_header_file_added')?></h3>
+ <div id="created-results">
+ <p><?=sprintf(___('devcp_uploader_file_created'), $version, '<span id="new-file-status"></span>')?></p>
+ <p id="pending-message"><?=sprintf(___('devcp_uploader_p_pending_file'), '<span id="queue-count"></span>', 'href="https://wiki.mozilla.org/Update:Editors"')?></p>
+ <p><?=sprintf(___('devcp_uploader_p_update_file'), '/developers/versions/edit/', '/developers/addon/status/'.$addon_id)?>
+ </div>
+ </div><!-- /#file-created-content -->
+ <?php endif; ?>
+ <div class="greenbox-br"><div class="greenbox-bl"></div></div>
+ </div></div><!-- /#addon-created -->
+</div><!-- /#content-main -->
+</div><!-- /#content -->
+
+<iframe id="upload-frame" name="upload-frame" src="" onload="iframeLoaded();" style="display: none;"></iframe>
diff --git a/site/app/views/developers/versions.thtml b/site/app/views/developers/versions.thtml
new file mode 100644
index 0000000..d3bed4a
--- /dev/null
+++ b/site/app/views/developers/versions.thtml
@@ -0,0 +1,94 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Justin Scott <fligtar@mozilla.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+?>
+<div id="content">
+ <?=$this->renderElement('developers/sidebar', array('addons' => $all_addons, 'extra' => 'developers/editbox'));?>
+
+ <div id="content-main" class="<?=($author_role >= AUTHOR_ROLE_DEV ? 'privs' : 'no-privs')?>">
+ <?=$this->renderElement('developers/addonheader', array('title' => sprintf(___('devcp_title_edit_addon'), $addon_name), 'addon_id' => $addon_id));?>
+ <?php
+ if (!empty($deleteSuccess)) {
+ echo '<div class="notice-success rounded"><span>'.sprintf(___('devcp_versions_notice_success'), $deletedVersion).'</span></div>';
+ }
+ ?>
+ <h2><?=___('devcp_versions_header_manage')?></h2>
+ <?=$this->renderElement('noscript')?>
+ <?=$this->renderElement('developers/rolecheck')?>
+ <div class="graybox spaced rounded">
+ <table id="versions-table" class="pretty-table">
+ <?php
+ echo '<tr>';
+ echo '<th style="width: 25%;">'.___('devcp_versions_th_version').'</th>';
+ echo '<th style="width: 30%;">'.___('devcp_versions_th_status').'</th>';
+ echo '<th style="width: 30%;">'.___('devcp_versions_th_created').'</th>';
+ echo '<th style="width: 15%;"></th>';
+ echo '</tr>';
+ if (!empty($versions)) {
+ $i = 0;
+ foreach ($versions as $version) {
+ echo '<tr'.($i % 2 == 0 ? ' class="alt"' : '').'>';
+ echo '<td><a href="'.$html->url('/developers/versions/edit/'.$version['Version']['id']).'">'.sprintf(_('devcp_details_version'), $version['Version']['version']).'</a></td>';
+ echo '<td>'.$this->controller->Amo->describeVersionStatus($version['File']).'</td>';
+ echo '<td>'.strftime(_('date'), strtotime($version['Version']['created'])).'</td>';
+ echo '<td class="delete-area version-delete-area">';
+ if (empty($version['File'])) {
+ echo '<div class="inline-delete-button uses-button">';
+ echo '<a href="#" onclick="versions.deleteVersion(this); return false;" class="remove-button rounded trigger">'.___('devcp_versions_a_remove').'</a>';
+ echo '<div class="inline-delete-box">';
+ echo '<p>'.___('devcp_versions_p_remove').'</p><br />';
+ echo '<p><a href="'.$html->url('/developers/versions/delete/'.$version['Version']['id']).'" class="remove-button rounded">'.___('devcp_versions_a_empty').'</a>&nbsp;&nbsp;';
+ echo '<a href="#" onclick="versions.cancelDelete(this); return false;" class="button rounded">'.___('devcp_versions_a_cancel').'</a></p>';
+ echo '</div></div>';
+ }
+ else {
+ echo '<a href="'.$html->url('/developers/versions/delete/'.$version['Version']['id']).'">'.$html->image('developers/delete.png', array('alt' => ___('devcp_versions_a_delete'), 'title' => ___('devcp_versions_a_delete'))).'</a>';
+ }
+ echo '</td>';
+ echo '</tr>';
+ $i++;
+ }
+ }
+ else {
+ echo '<tr><td colspan="3" style="text-align: center;"><i>'.___('devcp_versions_no_versions').'</i></td></tr>';
+ }
+ ?>
+ </table>
+<div class="add-button-container"><a href="<?=$html->url("/developers/versions/add/{$addon_id}")?>" class="add-button rounded"><?=___('devcp_versions_add')?></a></div>
+ </div>
+ </div>
+</div> \ No newline at end of file
diff --git a/site/app/views/developers/versions_delete.thtml b/site/app/views/developers/versions_delete.thtml
new file mode 100644
index 0000000..c1d7d67
--- /dev/null
+++ b/site/app/views/developers/versions_delete.thtml
@@ -0,0 +1,63 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Justin Scott <fligtar@mozilla.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+?>
+<div id="content">
+ <?=$this->renderElement('developers/sidebar', array('addons' => $all_addons, 'extra' => 'developers/editbox'));?>
+
+ <div id="content-main">
+ <?=$this->renderElement('developers/addonheader', array('title' => sprintf(___('devcp_title_edit_addon'), $addon_name), 'addon_id' => $addon_id));?>
+ <?=$this->renderElement('noscript')?>
+ <form id="versions-delete-form" action="" method="post">
+ <?=$html->hiddenSession();?>
+ <div class="graybox rounded">
+ <h4><?=sprintf(___('devcp_versions_delete_header'), $version['Version']['version'])?></h4>
+ <p class="smallmargin"><?=sprintf(___('devcp_versions_delete_sure'), $version['Version']['version'])?></p>
+ <p><?=___('devcp_versions_delete_also')?></p>
+ <ul>
+ <li><?=sprintf(n___('devcp_versions_delete_reviews', 'devcp_versions_delete_reviews', count($version['Review'])), count($version['Review']))?></li>
+ <li><?=sprintf(n___('devcp_versions_delete_files', 'devcp_versions_delete_files', count($version['File'])), count($version['File']))?></li>
+ </ul>
+ <div>
+ <a href="#" onclick="versions_delete.confirm(); return false;" class="remove-button rounded"><?=___('devcp_versions_delete_a_delete')?></a>
+ <input type="hidden" name="confirmDelete" value="1"/>&nbsp;&nbsp;
+ <a href="<?=$html->url('/developers/versions/'.$addon_id)?>" class="button rounded"><?=___('devcp_versions_delete_a_cancel')?></a>
+ </div>
+ </div>
+ </form>
+ </div>
+</div>
diff --git a/site/app/views/developers/versions_edit.thtml b/site/app/views/developers/versions_edit.thtml
new file mode 100644
index 0000000..cc6bc7f
--- /dev/null
+++ b/site/app/views/developers/versions_edit.thtml
@@ -0,0 +1,262 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Justin Scott <fligtar@mozilla.com> (Original Author)
+ * Frederic Wenzel <fwenzel@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+?>
+<div id="content">
+ <?=$this->renderElement('developers/sidebar', array('addons' => $all_addons, 'extra' => 'developers/editbox'));?>
+
+ <div id="content-main" class="<?=($author_role >= AUTHOR_ROLE_DEV ? 'privs' : 'no-privs')?>">
+ <?=$this->renderElement('developers/addonheader', array('title' => sprintf(___('devcp_title_edit_addon'), $addon_name), 'addon_id' => $addon_id));?>
+ <?php
+ if (!empty($success)) {
+ echo '<div class="notice-success rounded">'.___('devcp_notice_changes_saved').'</div>';
+ }
+ if (!empty($errors)) {
+ echo '<div class="notice-error rounded">'.___('devcp_notice_changes_error').'</div>';
+ }
+ ?>
+ <h2><?=sprintf(___('devcp_versions_edit_header_manage'), $version['Version']['version'])?></h2>
+ <?=$this->renderElement('noscript')?>
+ <?=$this->renderElement('developers/rolecheck')?>
+ <form id="versions-edit-form" action="" method="post">
+ <?=$html->hiddenSession();?>
+ <?php
+ // Retrieve language arrays from bootstrap.
+ global $valid_languages, $native_languages;
+ foreach (array_keys($valid_languages) as $key) {
+ $languages[$key] = $native_languages[$key]['native'];
+ }
+ ksort($languages);
+
+ $this->translationBox = array(
+ 'defaultLocale' => $addon['Addon']['defaultlocale'],
+ 'languages' => $languages,
+ 'table' => 'Version',
+ 'loaded' => false
+ );
+
+ echo '<div class="graybox rounded spaced field">';
+ echo '<h4>'.___('devcp_versions_edit_header_file').'</h4>';
+ if (!empty($version['File'])) {
+ echo '<table id="files-table" class="pretty-table">';
+ echo '<thead><tr>';
+ echo '<th>'.___('devcp_versions_edit_th_file').'</th>';
+ echo '<th>'.___('devcp_versions_edit_th_platform').'</th>';
+ echo '<th>'.___('devcp_versions_edit_th_size').'</th>';
+ echo '<th>'.___('devcp_versions_edit_th_status').'</th>';
+ echo '<th style="width: 25px;"></th>';
+ echo '</tr></thead><tbody>';
+ $i = 0;
+ foreach ($version['File'] as $file) {
+ echo '<tr'.($i % 2 == 0 ? ' class="alt"' : '').'>';
+ echo '<td>';
+ echo '<input type="hidden" name="data[File]['.$file['id'].'][delete]" value="0" class="delete"/>';
+ echo '<a href="'.$html->urlFile($file['id'], $file['filename']).'" class="filelink">'.$file['filename'].'</a></td>';
+ echo '<td><select name="data[File]['.$file['id'].'][platform_id]">';
+ foreach ($platforms as $platform_id => $platform_name) {
+ echo '<option value="'.$platform_id.'"'.($file['platform_id'] == $platform_id ? ' selected="selected"' : '').'>'.$platform_name.'</option>';
+ }
+ echo '</select></td>';
+ echo '<td>'.sprintf(_('size_kb'), $file['size']).'</td>';
+ echo '<td>'.$statuses[$file['status']].'</td>';
+ echo '<td><div class="inline-delete-button uses-image">';
+ echo '<a href="#" onclick="versions_edit.deleteVersion(this); return false;">'.$html->image('developers/delete.png', array('alt' => ___('devcp_versions_edit_img_delete'), 'title' => ___('devcp_versions_edit_img_delete'))).'</a>';
+ echo '<div class="inline-delete-box">';
+ echo '<p>'.___('devcp_versions_edit_delete_sure').'</p><br />';
+ echo '<p><a href="#" onclick="versions_edit.confirmDelete(this); return false;" class="remove-button rounded">'.___('devcp_versions_edit_a_delete').'</a>&nbsp;&nbsp;';
+ echo '<a href="#" onclick="versions_edit.cancelDelete(this); return false;" class="button rounded">'.___('devcp_versions_edit_a_cancel').'</a></p>';
+ echo '</div>';
+ echo '</div></td>';
+ echo '</tr>';
+ $i++;
+ }
+ echo '</tbody></table>';
+ }
+ else {
+ echo '<p><i>'.___('devcp_versions_edit_no_files').'</i></p>';
+ }
+ echo '<div class="save-changes rounded">'.___('devcp_versions_edit_unsaved_files').'</div>';
+ echo '<div class="add-button-container"><a href="'.$html->url("/developers/versions/addfile/{$version['Version']['id']}").'" class="add-button rounded">'.___('devcp_versions_edit_add').'</a></div>';
+ echo '</div>';
+
+ // Compatible applications (hidden for search engines)
+ if ($addon['Addon']['addontype_id'] != ADDON_SEARCH) {
+ echo '<div class="graybox rounded spaced field">';
+ echo '<h4>'.___('devcp_versions_edit_header_compat').'</h4>';
+ echo '<p>'.sprintf(___('devcp_versions_edit_adjust'), 'href="'.$html->url('/pages/appversions').'"').'</p>';
+
+ echo '<table id="edit-versions-targetapps-table" class="pretty-table"><tbody>';
+ $i = 0;
+ if (!empty($targetApps)) {
+ foreach ($targetApps as $application_id => $versions) {
+ echo '<tr class="'.$application_id.($i % 2 == 0 ? ' alt' : '').'">';
+ echo '<td>'.$html->image('developers/'.strtolower($applications[$application_id]).'.png', array('alt' => $applications[$application_id], 'class' => 'compat-icon')).'</td>';
+ echo '<td class="appname">';
+ echo '<input type="hidden" name="data[Application]['.$application_id.'][delete]" value="0" class="delete"/>';
+ echo $applications[$application_id].'</td>';
+ echo '<td><select name="data[Application]['.$application_id.'][min]">';
+ if (!empty($possibleVersions[$application_id])) {
+ foreach ($possibleVersions[$application_id] as $possibleVersion_id => $possibleVersion) {
+ if (strpos($possibleVersion, '*') === false) {
+ echo '<option value="'.$possibleVersion_id.'"'.($versions['min'] == $possibleVersion_id ? ' selected="selected"' : '').'>'.$possibleVersion.'</option>';
+ }
+ }
+ }
+ echo '</select>';
+ echo '&nbsp;&mdash;&nbsp;';
+ echo '<select name="data[Application]['.$application_id.'][max]">';
+ if (!empty($possibleVersions[$application_id])) {
+ foreach ($possibleVersions[$application_id] as $possibleVersion_id => $possibleVersion) {
+ echo '<option value="'.$possibleVersion_id.'"'.($versions['max'] == $possibleVersion_id ? ' selected="selected"' : '').'>'.$possibleVersion.'</option>';
+ }
+ }
+ echo '</select></td>';
+ echo '<td style="width: 25px;">';
+ echo '<div class="inline-delete-button uses-image">';
+ echo '<a href="#" onclick="versions_edit.deleteVersion(this); return false;">'.$html->image('developers/delete.png', array('alt' => ___('devcp_versions_edit_remove_compat'), 'title' => ___('devcp_versions_edit_remove_compat'))).'</a>';
+ echo '<div class="inline-delete-box">';
+ echo '<p>'.___('devcp_versions_edit_compat_sure').'</p><br />';
+ echo '<p><a href="#" onclick="versions_edit.confirmDelete(this); return false;" class="remove-button rounded">'.___('devcp_versions_edit_a_remove_app').'</a>&nbsp;&nbsp;';
+ echo '<a href="#" onclick="versions_edit.cancelDelete(this); return false;" class="button rounded">'.___('devcp_versions_edit_a_cancel').'</a></p>';
+ echo '</div>';
+ echo '</div></td>';
+
+ echo '</tr>';
+ $i++;
+ }
+ }
+ echo '</tbody></table>';
+ echo '<div class="save-changes rounded">'.___('devcp_versions_edit_unsaved_compat').'</div>';
+ echo '<div class="add-button-container" style="width: 60%; margin: 10px auto 0;"><a href="#" onclick="versions_edit.showAppPicker(); return false;" class="add-button rounded">'.___('devcp_versions_edit_a_new_app').'</a>';
+ echo '<span id="new-app-picker"><select onchange="versions_edit.addApplication(this);">';
+ echo '<option value="">'.___('devcp_versions_edit_select_app').'</option>';
+ foreach ($applications as $application_id => $application_name) {
+ echo '<option value="'.$application_id.'">'.$application_name.'</option>';
+ }
+ echo '</select>';
+ echo '</span></div>';
+ echo '</div>';
+ }
+
+ // Version Notes
+ echo $this->renderElement('translationbox', array(
+ 'field' => 'releasenotes',
+ 'translations' => $translations['releasenotes'],
+ 'height' => '130',
+ 'width' => 'inherit',
+ 'displayName' => ___('devcp_versions_edit_transbox_releasenotes_name'),
+ 'description' => ___('devcp_versions_edit_transbox_releasenotes_description'),
+ ));
+ ?>
+
+ <!-- Source Code License -->
+ <div class="graybox rounded spaced field">
+ <h4><?=___('devcp_versions_edit_header_license')?></h4>
+ <p><?=___('devcp_versions_edit_license_description')?></p>
+ <?php
+ list($licenses, $trans) = $this->controller->Developers->getLicenses($version['Version']['id']);
+ echo $this->renderElement('developers/license_picker',
+ array('licenses' => $licenses));
+ echo $this->renderElement('developers/license_translationbox',
+ array('translations' => $trans,
+ // The transbox wraps fieldname with []
+ 'fieldname' => 'License][text'));
+ ?>
+ </div>
+
+ <div class="graybox rounded spaced field">
+ <h4><?=___('devcp_versions_edit_header_approval')?></h4>
+ <?php
+ if (!empty($version['File'])) {
+ echo '<ul>';
+ foreach ($version['File'] as $file) {
+ echo '<li>'.sprintf(___('devcp_versions_edit_li_file'), $file['id'], $platforms[$file['platform_id']], strftime(_('date'), strtotime($file['created'])), $statuses[$file['status']], strftime(_('date'), strtotime($file['datestatuschanged']))).'</li>';
+ }
+ echo '</ul>';
+ }
+ echo '<h5>'.___('devcp_versions_edit_header_notes').'</h5>';
+ echo '<p class="smallmargin">'.___('devcp_versions_edit_optional').'</p>';
+ echo '<textarea name="data[Version][approvalnotes]" cols="" rows="" style="width: 100%; height: 70px;" class="rounded">'.$version['Version']['approvalnotes'].'</textarea>';
+ echo '</div>';
+ ?>
+
+ <div class="action-button-container centered"><a href="#" onclick="versions_edit.save(); return false;" class="action-button rounded"><?=___('devcp_versions_edit_update')?></a></div>
+ </form>
+ </div>
+</div>
+
+<?php
+/**
+ * Data for dynamically adding applications on the page
+ */
+// Array of application names so they can be added
+if ($addon['Addon']['addontype_id'] != ADDON_SEARCH) {
+ echo '<script type="text/javascript">';
+ echo 'var application_names = {';
+ foreach ($applications as $application_id => $application_name) {
+ echo $application_id.': "'.$application_name.'", ';
+ }
+ echo '};';
+ echo 'var imageBase = \''.$html->url('/img/developers', true, false, false).'\'';
+ echo '</script>';
+
+ // Dropdowns for all applications so they can be added. This must be
+ // outside of the <form>
+ foreach ($applications as $application_id => $application_name) {
+ echo '<div id="app'.$application_id.'-dropdowns" style="display: none;">';
+ echo '<select name="data[Application]['.$application_id.'][min]">';
+ if (!empty($possibleVersions[$application_id])) {
+ foreach ($possibleVersions[$application_id] as $possibleVersion_id => $possibleVersion) {
+ if (strpos($possibleVersion, '*') === false) {
+ echo '<option value="'.$possibleVersion_id.'">'.$possibleVersion.'</option>';
+ }
+ }
+ }
+ echo '</select>';
+ echo '&nbsp;&mdash;&nbsp;';
+ echo '<select name="data[Application]['.$application_id.'][max]">';
+ if (!empty($possibleVersions[$application_id])) {
+ foreach ($possibleVersions[$application_id] as $possibleVersion_id => $possibleVersion) {
+ echo '<option value="'.$possibleVersion_id.'">'.$possibleVersion.'</option>';
+ }
+ }
+ echo '</select>';
+ echo '</div>';
+ }
+}
+?>
diff --git a/site/app/views/downloads/file.thtml b/site/app/views/downloads/file.thtml
new file mode 100644
index 0000000..d0e6ea5
--- /dev/null
+++ b/site/app/views/downloads/file.thtml
@@ -0,0 +1,45 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Andrei Hajdukewycz <sancus@off.net> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+header("Content-type: application/x-xpinstall");
+
+if (!empty($attachment) && $attachment)
+ header("Content-Disposition: attachment; filename=\"{$fileName}\"");
+
+header("Content-Length: " . filesize($fileLoc));
+$html->readfile_chunked($fileLoc);
+?> \ No newline at end of file
diff --git a/site/app/views/editors/ajax/addon_and_author_lookup.thtml b/site/app/views/editors/ajax/addon_and_author_lookup.thtml
new file mode 100644
index 0000000..aa1062c
--- /dev/null
+++ b/site/app/views/editors/ajax/addon_and_author_lookup.thtml
@@ -0,0 +1,12 @@
+<?php
+header('Content-type: text/plain');
+if (!defined('NO_MICROTIME')) {
+ define('NO_MICROTIME', true);
+}
+
+if (count($addonsAndEmails) > 0) {
+ foreach ($addonsAndEmails as $row) {
+ echo str_replace('|', '&#124;', $row)."\n";
+ }
+}
+?>
diff --git a/site/app/views/editors/ajax/appversion_lookup.thtml b/site/app/views/editors/ajax/appversion_lookup.thtml
new file mode 100644
index 0000000..d45b9d9
--- /dev/null
+++ b/site/app/views/editors/ajax/appversion_lookup.thtml
@@ -0,0 +1,44 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Scott McCammon <smccammon@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+
+header('Content-type: text/plain');
+echo "<option value=\"\"></option>";
+foreach ($appversions as &$av) {
+ echo "<option value=\"{$av['id']}\">{$av['version']}</option>";
+}
diff --git a/site/app/views/editors/ajax/json.thtml b/site/app/views/editors/ajax/json.thtml
new file mode 100644
index 0000000..9e18a29
--- /dev/null
+++ b/site/app/views/editors/ajax/json.thtml
@@ -0,0 +1,7 @@
+<?php
+if (!defined('NO_MICROTIME'))
+ define('NO_MICROTIME', true);
+
+header('Content-type: text/plain');
+echo $javascript->object($json);
+?>
diff --git a/site/app/views/editors/email/inforequest_plain.thtml b/site/app/views/editors/email/inforequest_plain.thtml
new file mode 100644
index 0000000..6d99f11
--- /dev/null
+++ b/site/app/views/editors/email/inforequest_plain.thtml
@@ -0,0 +1,13 @@
+A Mozilla Add-ons Editor requested further information from you regarding version <?=$info['version']?> of your add-on <?=$info['name']?>.
+
+<?=$info['reviewer']?> wrote:
+
+"<?=$info['comments']?>"
+
+Please go to <?=FULL_BASE_URL.$html->url("/developers/discuss/{$info['infoid']}", true, true, false)?> to reply.
+
+
+If you have further questions, please e-mail amo-editors@mozilla.org or join #addons on irc.mozilla.org.
+
+Mozilla Add-ons
+<?=SITE_URL?>
diff --git a/site/app/views/editors/email/inforequest_reply_plain.thtml b/site/app/views/editors/email/inforequest_reply_plain.thtml
new file mode 100644
index 0000000..4a3d859
--- /dev/null
+++ b/site/app/views/editors/email/inforequest_reply_plain.thtml
@@ -0,0 +1,11 @@
+<?=$info['sender']?> has commented on version <?=$info['version']?> of the add-on <?=$info['name']?>:
+
+"<?=$info['comments']?>"
+
+Please go to <?=FULL_BASE_URL.$html->url("/developers/discuss/{$info['infoid']}", true, true, false)?> if you would like to reply.
+
+
+If you have further questions, please e-mail amo-editors@mozilla.org or join #addons on irc.mozilla.org.
+
+Mozilla Add-ons
+<?=SITE_URL?>
diff --git a/site/app/views/editors/email/nominated/public_plain.thtml b/site/app/views/editors/email/nominated/public_plain.thtml
new file mode 100644
index 0000000..15afe4f
--- /dev/null
+++ b/site/app/views/editors/email/nominated/public_plain.thtml
@@ -0,0 +1,17 @@
+Congratulations! Your nominated add-on, <?=$info['name']?>, has been reviewed by a Mozilla Add-ons editor who approved your add-on to be public.
+
+Your most recent version (<?=$info['version']?>) has also been made public.
+
+You can view your public add-on now at: http://addons.mozilla.org/addon/<?=$info['id']?>
+
+
+Review Information:
+Reviewer: <?=$info['reviewer']?>
+
+Comments: <?=$info['comments']?>
+
+
+If you have questions about this review, please e-mail amo-editors@mozilla.org or join #addons on irc.mozilla.org.
+
+Mozilla Add-ons
+http://addons.mozilla.org
diff --git a/site/app/views/editors/email/nominated/sandbox_plain.thtml b/site/app/views/editors/email/nominated/sandbox_plain.thtml
new file mode 100644
index 0000000..61ceb37
--- /dev/null
+++ b/site/app/views/editors/email/nominated/sandbox_plain.thtml
@@ -0,0 +1,12 @@
+Your nominated add-on, <?=$info['name']?>, has been reviewed by a Mozilla Add-ons editor who decided to retain your add-on in the sandbox.
+
+Review Information:
+Reviewer: <?=$info['reviewer']?>
+
+Comments: <?=$info['comments']?>
+
+
+If you have questions about this review, please e-mail amo-editors@mozilla.org or join #addons on irc.mozilla.org.
+
+Mozilla Add-ons
+http://addons.mozilla.org
diff --git a/site/app/views/editors/email/notify_update_plain.thtml b/site/app/views/editors/email/notify_update_plain.thtml
new file mode 100644
index 0000000..5694fd3
--- /dev/null
+++ b/site/app/views/editors/email/notify_update_plain.thtml
@@ -0,0 +1,19 @@
+Dear editor,
+
+An add-on you previously reviewed was just updated.
+
+
+Add-on Information:
+
+Name: <?=$info['name']?>
+URL: <?=FULL_BASE_URL.$html->url("/addon/{$info['id']}")?>
+
+Version Number: <?=$info['version']?>
+Review Link: <?=FULL_BASE_URL.$html->url("/editors/review/{$info['versionid']}")?>
+
+
+Thanks!
+Mozilla Add-ons
+<?=SITE_URL?>
+
+This is a one-time notification sent to you because you requested a follow up email regarding queue activity for <?=$info['name']?>. There is no need to unsubscribe if you don't wish to receive further mail.
diff --git a/site/app/views/editors/email/pending/public_plain.thtml b/site/app/views/editors/email/pending/public_plain.thtml
new file mode 100644
index 0000000..724c883
--- /dev/null
+++ b/site/app/views/editors/email/pending/public_plain.thtml
@@ -0,0 +1,20 @@
+The following files of <?=$info['name']?> <?=$info['version']?> have been made public by a Mozilla Add-ons editor:
+
+<?php
+ foreach ($info['files'] as $file) {
+ echo $file."\n";
+ }
+?>
+
+Review Information:
+Reviewer: <?=$info['reviewer']?>
+
+Tested on <?=$info['os']?> with <?=$info['apps']?>
+
+Comments: <?=$info['comments']?>
+
+
+If you have questions about this review, please e-mail amo-editors@mozilla.org or join #addons on irc.mozilla.org.
+
+Mozilla Add-ons
+http://addons.mozilla.org
diff --git a/site/app/views/editors/email/pending/sandbox_plain.thtml b/site/app/views/editors/email/pending/sandbox_plain.thtml
new file mode 100644
index 0000000..c174a62
--- /dev/null
+++ b/site/app/views/editors/email/pending/sandbox_plain.thtml
@@ -0,0 +1,15 @@
+The following files of <?=$info['name']?> <?=$info['version']?> have been retained in the sandbox by a Mozilla Add-ons editor:
+
+
+Review Information:
+Reviewer: <?=$info['reviewer']?>
+
+Tested on <?=$info['os']?> with <?=$info['apps']?>
+
+Comments: <?=$info['comments']?>
+
+
+If you have questions about this review, please e-mail amo-editors@mozilla.org or join #addons on irc.mozilla.org.
+
+Mozilla Add-ons
+http://addons.mozilla.org
diff --git a/site/app/views/editors/email/superreview_plain.thtml b/site/app/views/editors/email/superreview_plain.thtml
new file mode 100644
index 0000000..1579a8b
--- /dev/null
+++ b/site/app/views/editors/email/superreview_plain.thtml
@@ -0,0 +1,19 @@
+Dear Superheroes,
+
+An editor has requested super-review of the following add-on due to security, copyright, or other administrative concerns.
+
+Please open your plethora of knowledge and wield your mighty administrative sword of decision making in the general vicinity of:
+
+<?=$info['name']?> - http://addons.mozilla.org/addon/<?=$info['id']?>
+
+
+Review Information:
+Reviewer: <?=$info['reviewer']?>
+
+Comments: <?=$info['comments']?>
+
+
+Love,
+
+Mozilla Add-ons
+http://addons.mozilla.org
diff --git a/site/app/views/editors/featured.thtml b/site/app/views/editors/featured.thtml
new file mode 100644
index 0000000..38348b0
--- /dev/null
+++ b/site/app/views/editors/featured.thtml
@@ -0,0 +1,134 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Wil Clouser <clouserw@mozilla.com> (Original Author)
+ * Frederic Wenzel <fwenzel@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+// This is some ugly view code
+?>
+<script type="text/javascript">
+ // Need to generate outside of a .js file so cake/ajax can use it
+ var autocompleteurl = '<?php echo $html->url('/admin/addonLookup?s=4'); ?>';
+ var featuredurl = '<?php echo $html->url('/editors/featured'); ?>';
+ var addonurl = '<?php echo $html->url('/addon'); ?>';
+ var imageurl = '<?php echo $html->urlImage(''); ?>';
+
+ var featureaddfailure = '<?php echo _('editors_featured_addon_add_failure'); ?>';
+ var featureeditfailure = '<?php echo _('editors_featured_addon_edit_failure'); ?>';
+ var featureeditsuccess = '<?php echo _('editors_featured_addon_edit_success'); ?>';
+ var featureremovefailure = '<?php echo _('editors_featured_addon_remove_failure'); ?>';
+ var addedinvalidlocale = '<?php echo _('editors_featured_addon_invalid_locale'); ?>';
+ var featureeditsubmit = '<?php echo _('editors_featured_edit_feature_submit'); ?>';
+</script>
+
+<div id="content">
+ <?=$this->renderElement('developers/editorsmenu');?>
+
+ <div id="content-main">
+ <table width="100%" id="features">
+ <tr class="queueHeader">
+ <td><?=_('editors_th_addon')?></td>
+ <td><?=_('editors_th_locales')?></td>
+ </tr>
+<?php
+ $current_type = 0;
+ foreach ($tags as $tag) :
+
+ if ($tag['Tag']['addontype_id'] != $current_type) {
+ echo '<tr class="featureTypeHeader '.preg_replace('/[^A-Za-z0-9]/','',strtolower($addontypes[$tag['Tag']['addontype_id']])).'"><th colspan="2">'.$html->image('developers/'.strtolower($applications[$tag['Tag']['application_id']]).'.png', array('title' => $applications[$tag['Tag']['application_id']])).' '.$addontypes[$tag['Tag']['addontype_id']].'</th></tr>';
+ $current_type = $tag['Tag']['addontype_id'];
+ }
+
+ echo '<tr class="featureHeader '.preg_replace('/[^A-Za-z0-9]/','',strtolower($addontypes[$tag['Tag']['addontype_id']])).'"><th colspan="2"><span lang="'.$tag['Translation']['name']['locale'].'">'.$tag['Translation']['name']['string'].'</span></th></tr>';
+
+ $_class = preg_replace('/[^A-Za-z0-9]/','',strtolower($addontypes[$tag['Tag']['addontype_id']]));
+ if (array_key_exists($tag['Tag']['id'], $addons_by_tag) && !empty($addons_by_tag[$tag['Tag']['id']])) {
+ $zebra = 0;
+ foreach ($addons_by_tag[$tag['Tag']['id']] as $addon):
+ $_evenodd = ($zebra++ % 2 == 0 ? ' even' : ' odd');
+ ?>
+ <tr class="<?=$_class.$_evenodd?>" id="feature-<?=$tag['Tag']['id']?>-<?=$addon['Addon']['id']?>">
+ <td>
+ <?php
+ echo $html->formTag('/editors/featured/remove', 'post',
+ array('id' => 'feature-remove-form-'.$tag['Tag']['id'].'-'.$addon['Addon']['id'],
+ 'onsubmit' => 'removeFeature('.$tag['Tag']['id'].','.$addon['Addon']['id'].'); return false;'));
+ echo $html->submitImage('/developers/delete.png',
+ array('title'=>_('editors_featured_remove_feature'),
+ 'alt' => _('editors_featured_remove_feature'),
+ 'class' => 'featureremove',
+ 'id' => 'delete-'.$tag['Tag']['id'].'-'.$addon['Addon']['id']));
+ echo $html->hidden('Tag/id', array('value' => $tag['Tag']['id']));
+ echo $html->hidden('Addon/id', array('value' => $addon['Addon']['id']));
+ echo '&nbsp;';
+ echo $html->link($addon['Translation']['name']['string'], '/addon/'.$addon['Addon']['id']);
+ ?>
+ </form>
+ </td>
+ <td>
+ <?php
+ echo $html->formTag('/editors/featured/edit', 'post', array('id' => 'feature-edit-form-'.$tag['Tag']['id'].'-'.$addon['Addon']['id'], 'onsubmit' => 'editFeatureSubmit('.$tag['Tag']['id'].','.$addon['Addon']['id'].'); return false;'));
+ echo $html->hidden('Tag/id', array('value' => $tag['Tag']['id']));
+ echo $html->hidden('Addon/id', array('value' => $addon['Addon']['id']));
+ echo $html->input('AddonTag/feature_locales', array('id' => "edit-addon-locales-{$tag['Tag']['id']}-{$addon['Addon']['id']}", 'size' => 40, 'value' => $addon['AddonTag'][0]['feature_locales']));
+ echo $html->submit(_('editors_featured_edit_feature_submit'), array('id' => 'edit-feature-submit-'.$tag['Tag']['id'].'-'.$addon['Addon']['id']));
+ ?>
+ </form>
+ </td>
+ </tr>
+ <?php
+ endforeach;
+ }
+
+ echo '<tr class="'.$_class.' even" id="feature-add-tr-form-'.$tag['Tag']['id'].'"><td>';
+ echo $html->formTag('/editors/featured/add', 'post', array('id' => 'feature-add-form-'.$tag['Tag']['id'], 'onsubmit' => 'addFeatureSubmit('.$tag['Tag']['id'].'); return false;'));
+ echo $html->hidden('Tag/id', array('value' => $tag['Tag']['id']));
+ echo $html->submitImage('developers/add.png',
+ array('title' => _('editors_featured_add_feature'),
+ 'alt' => _('editors_featured_add_feature'),
+ 'class' => 'featureadd',
+ 'id' => 'add-'.$tag['Tag']['id'],
+ )).'&nbsp;';
+ echo '<input type="text" name="data[Addon][id]" id="new-addon-id-'.$tag['Tag']['id'].'" onfocus="prepAutocomplete('.$tag['Tag']['id'].');" size="40" />';
+ echo '<noscript>'.$html->submit(_('editors_featured_add_feature_submit'), array('id' => 'new-feature-submit-'.$tag['Tag']['id'])).'</noscript>';
+ echo '</form></td>';
+ echo '<td><span id="edit-feature-message-'.$tag['Tag']['id'].'"></span></td></tr>'; // use the extra space for messages
+
+ endforeach;
+?>
+ </table>
+ </div>
+</div>
diff --git a/site/app/views/editors/logs.thtml b/site/app/views/editors/logs.thtml
new file mode 100644
index 0000000..7609442
--- /dev/null
+++ b/site/app/views/editors/logs.thtml
@@ -0,0 +1,63 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * Justin Scott <fligtar@gmail.com>.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+?>
+<div id="content">
+ <?=$this->renderElement('developers/editorsmenu');?>
+
+ <div id="content-main">
+ <h3><?=_('editorcp_logs_page_heading')?></h3>
+ <?=$html->formTag('/editors/logs')?>
+ <?=_('editorcp_logs_filter_by')?>:
+ <select name="data[Eventlog][filter]">
+ <option value=""></option>
+ <option>editor:*</option>
+ <option>editor:review_approve</option>
+ <option>editor:review_delete</option>
+ </select>
+ <?=$html->submit(_('editorcp_logs_button_filter'))?>
+ </form>
+ <?php
+ if (!empty($logs)) {
+ echo '<ul>';
+ foreach ($logs as $log) {
+ echo "<li>[{$log['time']}] {$log['entry']}</li>";
+ }
+ echo '</ul>';
+ }
+ ?>
+ </div>
+</div>
diff --git a/site/app/views/editors/performance_charts.thtml b/site/app/views/editors/performance_charts.thtml
new file mode 100644
index 0000000..8f1cbcd
--- /dev/null
+++ b/site/app/views/editors/performance_charts.thtml
@@ -0,0 +1,156 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * Justin Scott <fligtar@gmail.com>.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Scott McCammon <smccammon@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+?>
+<div id="content">
+ <?=$this->renderElement('developers/editorsmenu');?>
+
+ <div id="content-main">
+ <?=$this->renderElement('developers/performanceheader');?>
+
+ <h3 class="performanceHeader collapsible expanded"><span><?=___('editorcp_performance_month_activity', 'Activity By Month')?></span></h3>
+ <div id="byMonthChart" style="width:600px;height:300px"></div>
+
+ <h3 class="performanceHeader collapsible expanded"><span><?=___('editorcp_performance_category_breakdown', 'Category Breakdown')?></span></h3>
+ <div>
+ <form id="performanceFilter" action="<?=$html->url()?>" method="get">
+ <div>
+ <select name="month">
+ <?php foreach ($monthSelect as $key=>$val): ?>
+ <option value="<?=$key?>"<?=($key == $month ? ' selected="selected"' : '')?>><?=$val?></option>
+ <?php endforeach;?>
+ </select>
+ <select name="year">
+ <?php for ($i=0; $i<5; $i++): $val = date('Y') - $i; ?>
+ <option value="<?=$val?>"<?=($val == $year ? ' selected="selected"' : '')?>><?=$val?></option>
+ <?php endfor;?>
+ </select>
+ <?php if ($showUserLookup): ?>
+ <input type="hidden" name="user" value="<?=$user['User']['email']?>" />
+ <?php endif; ?>
+ <?=$html->submit(_('editorcp_reviewlog_button_filter'))?>
+ </div>
+ </form>
+ <h4><?=$userName?> - <?=$pieTitleDate?></h4>
+ <div class="performancePieContainer">
+ <div id="byCatUserChart"></div>
+ <div id="performanceUserLegend"></div>
+ </div>
+ <h4><?=___('editorcp_performance_column_teamaverage', 'Team Average')?> - <?=$pieTitleDate?></h4>
+ <div class="performancePieContainer">
+ <div id="byCatTeamChart"></div>
+ <div id="performanceTeamLegend"></div>
+ </div>
+ </div>
+
+ </div>
+</div>
+<script type="text/javascript">
+// <![CDATA[
+ $(document).ready(function() {
+ editors_performance.init();
+
+ var ticks = [<?=$monthlyTicksJS?>];
+ var d1 = [<?=$monthlyUserPointsJS?>];
+ var d2 = [<?=$monthlyTeamPointsJS?>];
+
+ $.plot($('#byMonthChart'), [
+ { label: '<?=$userName?>', data: d1, color:'#0066cc'},
+ { label: '<?=___('editorcp_performance_column_teamaverage', 'Team Average')?>', data: d2, color:'#cc3333'}
+ ], {
+ lines: { show: true },
+ points: { show: true },
+ xaxis: { ticks: ticks },
+ grid: { backgroundColor: "#fffaff", hoverable: true }
+ });
+
+ var previousPoint = null;
+ $('#byMonthChart').bind('plothover', function (event, pos, item) {
+ if (item) {
+ if (previousPoint != item.datapoint) {
+ previousPoint = item.datapoint;
+ $('#chartTip').remove();
+ var y = item.datapoint[1].toFixed(2);
+ editors_performance.showChartTooltip(item.pageX, item.pageY, '' + y);
+ }
+ }
+ else {
+ $('#chartTip').remove();
+ previousPoint = null;
+ }
+ });
+
+ // pie chart data
+ var sliceColors = [<?=$sliceColorsJS?>];
+ var sliceLabels = [<?=$sliceLabelsJS?>];
+ var userPieData = [<?=$userPieDataJS?>];
+ var teamPieData = [<?=$teamPieDataJS?>];
+
+ // draw user pie chart
+ $('#byCatUserChart').sparkline(userPieData, {
+ type:'pie',
+ height:200,
+ sliceColors:sliceColors
+ });
+
+ // draw team pie chart
+ $('#byCatTeamChart').sparkline(teamPieData, {
+ type:'pie',
+ height:200,
+ sliceColors:sliceColors
+ });
+
+ // sums for legend percentage calculations
+ var userSum = 0;
+ $.each(userPieData, function(i, val) {
+ userSum += val;
+ });
+ var teamSum = 0;
+ $.each(teamPieData, function(i, val) {
+ teamSum += val;
+ });
+
+ // create legend for each pie chart
+ $.each(sliceLabels, function(i, val) {
+ $('#performanceUserLegend').append(editors_performance.pieLegendEntry(
+ sliceColors[i], val, userPieData[i], userSum, 'userSlice'+i));
+ $('#performanceTeamLegend').append(editors_performance.pieLegendEntry(
+ sliceColors[i], val, teamPieData[i], teamSum, 'teamSlice'+i));
+ });
+ });
+// ]]>
+</script>
diff --git a/site/app/views/editors/performance_table.thtml b/site/app/views/editors/performance_table.thtml
new file mode 100644
index 0000000..8f12bdf
--- /dev/null
+++ b/site/app/views/editors/performance_table.thtml
@@ -0,0 +1,141 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * Justin Scott <fligtar@gmail.com>.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Scott McCammon <smccammon@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+?>
+<div id="content">
+ <?=$this->renderElement('developers/editorsmenu');?>
+
+ <div id="content-main">
+ <?=$this->renderElement('developers/performanceheader');?>
+
+ <form id="performanceFilter" action="<?=$html->url()?>" method="get">
+ <div>
+ <?php
+ echo sprintf(_('editorcp_reviewlog_entries_between'),
+ '<input type="text" id="start" name="start" value="'.$startDate.'" size="11" onfocus="clearInput(this)"/>',
+ '<input type="text" id="end" name="end" value="'.$endDate.'" size="11" onfocus="clearInput(this)"/>');
+ echo "&nbsp;&nbsp;";
+ echo $html->submit(_('editorcp_reviewlog_button_filter'));
+ if ($showUserLookup) {
+ echo '<input type="hidden" name="user" value="'.$user['User']['email'].'"/>';
+ }
+ ?>
+
+ </div>
+ </form>
+
+ <h3 id="reviewTotals" class="performanceHeader collapsible expanded"><span><?=sprintf(___('editorcp_performance_totals', 'Total Reviews: %1$s &nbsp;&nbsp;Team Average: %2$s'), $myTotal, sprintf('%.2f', $teamAverage))?></span></h3>
+ <?php if (empty($myApprovals)): ?>
+ <div><p><?=_('editorcp_reviewlog_none_found')?></p></div>
+ <?php else: ?>
+ <table id="historyTable">
+ <thead title="<?=___('editorcp_performance_multisort_tip', 'Shift-click to sort by multiple columns')?>">
+ <tr>
+ <th><?=_('editorcp_reviewlog_column_date')?></th>
+ <th><?=_('editorcp_reviewlog_column_addon')?></th>
+ <th><?=___('editorcp_performance_column_application', 'Application')?></th>
+ <th><?=___('editorcp_performance_column_category', 'Category')?></th>
+ <th><?=_('editorcp_reviewlog_column_action')?></th>
+ </tr>
+ </thead>
+ <tbody>
+ <?php
+ foreach ($myApprovals as $k => $approval) {
+ echo '<tr>';
+ echo "<td>{$approval['Approval']['created']}</td>";
+ echo '<td>'.$html->link($approval['Addon']['Translation']['name']['string'], '/editors/review/'.$approval['File']['version_id']).'</td>';
+ echo "<td>{$approval['Approval']['applications']}</td>";
+ echo "<td>{$addonTypes[$approval['Addon']['Addon']['addontype_id']]}</td>";
+ echo '<td>';
+ if ($approval['Approval']['reviewtype'] == 'nominated') {
+ if ($approval['Approval']['action'] == STATUS_PUBLIC) {
+ echo _('editors_review_history_nominated_approved');
+ }
+ elseif ($approval['Approval']['action'] == STATUS_SANDBOX) {
+ echo _('editors_review_history_nominated_denied');
+ }
+ elseif ($approval['Approval']['action'] == STATUS_NOMINATED) {
+ echo _('editors_review_history_nominated_adminreview');
+ }
+ }
+ elseif ($approval['Approval']['reviewtype'] == 'pending') {
+ if ($approval['Approval']['action'] == STATUS_PUBLIC) {
+ echo _('editors_review_history_pending_approved');
+ }
+ elseif ($approval['Approval']['action'] == STATUS_SANDBOX) {
+ echo _('editors_review_history_pending_denied');
+ }
+ elseif ($approval['Approval']['action'] == STATUS_PENDING) {
+ echo _('editors_review_history_pending_adminreview');
+ }
+ }
+ echo '</td>';
+ echo '</tr>';
+ }
+ ?>
+ </tbody>
+ </table>
+ <?php endif; ?>
+
+ <h3 id="weeklyTotals" class="performanceHeader collapsible expanded"><span><?=___('editorcp_performance_weekly_heading', 'Weekly Totals')?></span></h3>
+ <table id="weeklyTable">
+ <tr>
+ <th><?=___('editorcp_performance_column_week', 'Week')?></th>
+ <th class="numeric"><?=___('editorcp_performance_column_total', 'Total')?></th>
+ <th class="numeric"><?=___('editorcp_performance_column_teamaverage', 'Team Average')?></th>
+ </tr>
+ <?php
+ foreach ($weeklyTotals as $k => $week) {
+ echo '<tr>';
+ echo "<td>".sprintf(___('editorcp_performance_date_range', '%1$s to %2$s'), date('Y-m-d', $week['from']), date('Y-m-d', $week['to']))."</td>";
+ echo "<td class=\"numeric\">{$week['myTotal']}</td>";
+ echo sprintf('<td class="numeric">%0.2f</td>', $week['teamAverage']);
+ echo '</tr>';
+ }
+ ?>
+ </table>
+
+ <h3 id="monthToDateTotals" class="performanceHeader"><span><?=sprintf(___('editorcp_performance_mtd_totals', 'Month To Date Total: %1$s &nbsp;&nbsp;Team Average: %2$s'), $myMtdTotal, sprintf('%.2f', $teamMtdAverage))?></span></h3>
+
+ <h3 id="yearToDateTotals" class="performanceHeader"><span><?=sprintf(___('editorcp_performance_ytd_totals', 'Year To Date Total: %1$s &nbsp;&nbsp;Team Average: %2$s'), $myYtdTotal, sprintf('%.2f', $teamYtdAverage))?></span></h3>
+ </div>
+</div>
+<script type="text/javascript">
+// <![CDATA[
+ $(document).ready(function() { editors_performance.init(); });
+// ]]>
+</script>
diff --git a/site/app/views/editors/queue.thtml b/site/app/views/editors/queue.thtml
new file mode 100644
index 0000000..8f57ed7
--- /dev/null
+++ b/site/app/views/editors/queue.thtml
@@ -0,0 +1,191 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * Justin Scott <fligtar@gmail.com>.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Wil Clouser <clouserw@gmail.com>
+ * Frederic Wenzel <fwenzel@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+?>
+<div id="content">
+<?=$this->renderElement('developers/editorsmenu');?>
+<?=$this->renderElement('developers/editorsqueue');?>
+
+<div id="filterBox">
+<?=$html->formTag("/editors/queue/{$mode}", 'post');?>
+ <div id="filterHeader">&darr;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<?=_('editors_filter_queue')?>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&darr;</div>
+ <?php if ($filtered == true) { ?><div id="sessionNotice"><?=_('editors_notice_filter_session')?></div><?php } ?>
+ <div id="filterTable" <?=($filterChanged == false ? ' style="display: none;"' : '')?>>
+ <div class="group left">
+ <div>
+ <label for="FilterAddonOrAuthor"><?=___('editors_queue_filter_label_addon', 'Add-on or Author Email')?></label>
+ <?=$html->input('Filter/AddonOrAuthor', array('value'=>$addonOrAuthor))?>
+ </div>
+
+ <div>
+ <label for="FilterApplication"><?=___('editors_queue_filter_label_application', 'Application')?></label>
+ <?=$html->selectTag('Filter/Application', $applications, $selected['Application'], null, null, true)?>
+ </div>
+
+ <div>
+ <label for="FilterMaxVersion"><?=___('editors_queue_filter_label_maxversion', 'Max. Version')?></label>
+ <?=$html->selectTag('Filter/MaxVersion', $maxVersions, $selected['MaxVersion'], null, null, true)?>
+ </div>
+
+ <div>
+ <label for="FilterSubmissionAge"><?=___('editors_queue_filter_label_submissionage', 'Age of Submission (days)')?></label>
+ <?=$html->selectTag('Filter/SubmissionAge', $submissionAges, $selected['SubmissionAge'], null, null, true)?>
+ </div>
+ </div>
+ <div class="group">
+ <div>
+ <label for="FilterAddontype"><?=___('editors_queue_filter_label_addontypes', 'Add-on Types')?></label><br/>
+ <?=$html->selectTag('Filter/Addontype', $addontypes, $selected['Addontype'], array('multiple' => 'multiple', 'size' => 5), null, false)?>
+ </div>
+ </div>
+ <div class="group">
+ <div>
+ <label for="FilterPlatform"><?=___('editors_queue_filter_label_platforms', 'Platforms')?></label><br/>
+ <?=$html->selectTag('Filter/Platform', $platforms, $selected['Platform'], array('multiple' => 'multiple', 'size' => 5), null, false)?>
+ </div>
+ </div>
+ <div class="buttons">
+ <?=$html->submit(_('editors_queue_submit_filter'), array('name' => 'filter'));?>
+ <?=$html->submit(_('editors_queue_submit_clean'), array('name' => 'clear'))?>
+ </div>
+ </div>
+</form>
+<?php if ($filtered): ?>
+ <div>
+ <?=sprintf(n___('editors_queue_filter_result_count','editors_queue_filter_result_count', $filteredCount, 'Results of Your Filtered Search: <strong>%d</strong> Add-ons'), $filteredCount)?>
+ </div>
+<?php endif; ?>
+</div>
+<table width="100%">
+ <tr class="queueHeader">
+ <td><?php
+ $sorturl = "/editors/queue/{$mode}?sort=name";
+ $sortimg = '';
+ if ($sortBy == 'name') {
+ if ($sortDir == 'ASC') {
+ $sortimg = $html->image('developers/arrow_up.png', array('title' => ___('editors_th_sort_ascending', 'ascending sort')));
+ $sorturl .= '&dir=desc';
+
+ } else {
+ $sortimg = $html->image('developers/arrow_down.png', array('title' => ___('editors_th_sort_descending', 'descending sort')));
+ $sorturl .= '&dir=asc';
+ }
+ }
+ echo $html->link(___('editors_th_addon'), $sorturl);
+ echo $sortimg;
+ ?></td>
+ <td><?php
+ $sorturl = "/editors/queue/{$mode}?sort=type";
+ $sortimg = '';
+ if ($sortBy == 'type') {
+ if ($sortDir == 'ASC') {
+ $sortimg = $html->image('developers/arrow_up.png', array('title' => ___('editors_th_sort_ascending', 'ascending sort')));
+ $sorturl .= '&dir=desc';
+
+ } else {
+ $sortimg = $html->image('developers/arrow_down.png', array('title' => ___('editors_th_sort_descending', 'descending sort')));
+ $sorturl .= '&dir=asc';
+ }
+ }
+ echo $html->link(___('editors_th_addontype'), $sorturl);
+ echo $sortimg;
+ ?></td>
+ <?php
+ $apps = array('Firefox', 'Thunderbird', 'Mozilla', 'SeaMonkey', 'Sunbird');
+ foreach ($apps as $app) {
+ echo '<td>'.$html->image('developers/'.strtolower($app).'.png', array('title' => sprintf(_('editors_queue_app_compatibility'), $app))).'</td>';
+ }
+ ?>
+ <td><?php
+ $sorturl = "/editors/queue/{$mode}?sort=age";
+ $sortimg = '';
+ if ($sortBy == 'age') {
+ if ($sortDir == 'ASC') {
+ // age sort is actually on a timestamp, so age direction is opposite
+ $sortimg = $html->image('developers/arrow_down.png', array('title' => ___('editors_th_sort_descending', 'descending sort')));
+ $sorturl .= '&dir=desc';
+
+ } else {
+ $sortimg = $html->image('developers/arrow_up.png', array('title' => ___('editors_th_sort_ascending', 'ascending sort')));
+ $sorturl .= '&dir=asc';
+ }
+ }
+ echo $html->link(___('editors_th_nomination_age'), $sorturl);
+ echo $sortimg;
+ ?></td>
+ <td><?=_('editors_th_additional_info')?></td>
+ </tr>
+<?php
+ if (!empty($addons)) {
+ $num = (($paging['page']-1) * $paging['show']) + 1;
+ foreach ($addons as $addon) {
+ echo '<tr'.($num % 2 == 1 ? ' bgcolor="#eeeeff"' : '').'>';
+ echo '<td>'.$html->link($addon['Translation']['name']['string'].' '.$addon['Version']['version'], "/editors/review/{$addon['Version']['id']}?num={$num}").'</td>';
+ echo '<td>'.$addontypes[$addon['Addon']['addontype_id']].'</td>';
+ foreach ($apps as $app) {
+ if (!empty($addon['targetApps'][$app])) {
+ echo '<td>'.$html->image('developers/'.strtolower($app).'.png', array('title' => $app.' '.$addon['targetApps'][$app]['min'].' - '.$addon['targetApps'][$app]['max'])).'</td>';
+ }
+ else {
+ echo '<td>&nbsp;</td>';
+ }
+ }
+ echo '<td>'.(($mode == 'nominated') ? $addon['nominationage'] : $addon['age']).'</td>';
+ echo '<td>'.(!empty($addon['notes']) ? implode('; ', $addon['notes']) : '').'</td>';
+ echo '</tr>';
+ $num++;
+ }
+ echo '</table>';
+ echo $this->renderElement('pagination');
+ }
+ else {
+ echo '<tr><td colspan=8 class="emptyQueue">'._('editors_notice_none_found').'</td></tr>';
+ echo '</table>';
+ }
+?>
+<div id="helpfulLinks">
+<?=_('editors_helpful_links').': '.$html->link(_('editors_link_policy'), '/pages/policy').' | '.$html->link(_('editors_link_guide'), 'http://wiki.mozilla.org/Update:Editors')?>
+</div>
+</div>
+<script type="text/javascript">
+// <![CDATA[
+ var addonAutocompleteUrl = '<?=$html->url("/editors/addonAndAuthorLookup/{$mode}")?>';
+ var appversionLookupUrl = '<?=$html->url('/editors/appversionLookup/')?>';
+ $(document).ready(function() { editors_queue.init(); });
+// ]]>
+</script>
diff --git a/site/app/views/editors/review.thtml b/site/app/views/editors/review.thtml
new file mode 100644
index 0000000..f3cb36f
--- /dev/null
+++ b/site/app/views/editors/review.thtml
@@ -0,0 +1,327 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * Justin Scott <fligtar@gmail.com>.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Frederic Wenzel <fwenzel@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+?>
+<div id="content">
+ <?=$this->renderElement('developers/editorsmenu');?>
+ <?php if ($queueRank): ?>
+ <div class="reviewnav">
+ <?php
+ if ($filtered) {
+ echo sprintf(___('editors_review_rank_in_queue_filtered', '<strong># %1$s</strong> of %2$s in queue (filtered)'), $queueRank, $filteredCount);
+ } else {
+ echo sprintf(___('editors_review_rank_in_queue'), $queueRank, $filteredCount);
+ }
+ ?><br/>
+ <?php if ($queueRank > 1) echo $html->link(___('editors_review_previous_link'), "/editors/queue/{$reviewType}?num=".($queueRank-1)); ?>
+ <?php if ($queueRank < $count[$reviewType]) echo $html->link(___('editors_review_next_link'), "/editors/queue/{$reviewType}?num=".($queueRank+1)); ?>
+ </div>
+ <?php endif; ?>
+
+<a name="top"></a>
+<h3 class="reviewheader"><?=sprintf(_('editors_review_header_review'), $addon['Translation']['name']['string'].' '.$version['Version']['version'])?></h3>
+<?php
+ if (!empty($errors['main'])) {
+ echo '<div class="error">'.$errors['main'].'</div>';
+ }
+?>
+<div id="headerbox">
+ <div id="header1" class="headerboxes">
+ <div>
+ <span class="sectionTitle"><?=_('editors_review_header_authors')?></span>
+ <ul id="authors">
+ <?php
+ if (!empty($addon['User'])) {
+ foreach ($addon['User'] as $user) {
+ echo '<li>'.$html->linkUserFromModel($user).'</li>';
+ }
+ }
+ ?>
+ </ul>
+ </div>
+ </div>
+ <div id="header2" class="headerboxes">
+ <div>
+ <span class="sectionTitle"><?=_('editors_review_header_categories')?></span>
+ <ul id="categorylist">
+ <?php
+ if (!empty($addon['Tags'])) {
+ foreach ($addon['Tags'] as $tag) {
+ echo '<li '.$tag['Translation']['name']['locale_html'].'>'.$tag['Translation']['name']['string'].'</li>';
+ }
+ }
+ ?>
+ </ul>
+ </div>
+ </div>
+ <div id="header3" class="headerboxes">
+ <span class="sectionTitle"><?=_('editors_review_header_compatibility')?></span>
+ <ul id="compatibility">
+ <?php
+ if (!empty($addon['targetApps'])) {
+ $apps = array('Firefox', 'Thunderbird', 'Mozilla', 'Sunbird');
+ foreach ($addon['targetApps'] as $app => $val) {
+ echo '<li>';
+ if (in_array($app, $apps)) {
+ echo $html->image('developers/'.strtolower($app).'.png');
+ }
+ else {
+ echo $html->image('developers/spacer.png');
+ }
+ echo "{$app} {$val['min']} - {$val['max']}</li>";
+ }
+ }
+ ?>
+ </ul>
+ </div>
+</div>
+<br class="clear">
+<?=$html->formTag('/editors/review/'.$version['Version']['id'], 'post')?>
+<div id="filesbox">
+ <span id="filesTitle"><?=_('editors_review_header_files')?></span>
+ <ul id="files">
+ <?php
+ if (!empty($version['File'])) {
+ foreach ($version['File'] as $file) {
+ if ($version['pendingCount'] == 1) {
+ $checked = 'checked';
+ }
+ else {
+ $checked = 'false';
+ }
+
+ echo '<li>';
+ echo $html->checkbox('Approval/File][', null, array('value' => $file['id'], 'class' => 'fileCheckbox', 'checked' => $checked, 'disabled' => $file['disabled'], 'onClick' => 'selectedFile();'));
+ echo '&nbsp;<b>'.$html->link($platforms[$file['platform_id']], '/downloads/file/'.$file['id'].'/'.$file['filename'], array('onClick' => $this->controller->Amo->installTrigger($addon['Addon']['addontype_id'], FULL_BASE_URL.$html->url('/downloads/file/'.$file['id'].'/'.$file['filename']), $addon['Translation']['name']['string'].' '.$version['Version']['version'], '', $file['hash']).' return false;')).'</b>';
+ echo ' - '.$approval[$file['status']].' ('.$file['created'].')';
+ echo ' - '.$html->link(_('editors_review_file_viewcontents_link'), '/files/browse/'.$file['id'].'/1');
+ if ($has_public && $addontype != ADDON_SEARCH) {
+ //if (count($addon['Version']) > 1) {
+ echo ' - '.$html->link(_('editors_review_file_diff_link'), '/files/diff/'.$file['id'].'/');
+ }
+ echo '</li>';
+ }
+ }
+ ?>
+ </ul>
+ <span id="multipleNotice" style="display: none;"><?=___('editors_review_mulitple_notice')?></span>
+</div>
+<br class="clear">
+<div id="links">
+ <span id="overview_link"><?=$html->link(___('editors_review_a_item_overview'), '/addon/'.$addon['Addon']['id'])?></span>
+ <span id="history_link"><a href="#history"><?=___('editors_review_a_item_history')?></a></span>
+ <span id="previews_link"><a href="#previews"><?=___('editors_review_a_previews')?></a></span>
+ <?=(!empty($addon['Addon']['homepage'])) ? '<span id="homepage_link">'.$html->link(___('editors_review_a_item_homepage'), $addon['Addon']['homepage']).'</span>' : ''?>
+ <?=($this->controller->SimpleAcl->actionAllowed('Admin', 'EditAnyAddon', $this->controller->Session->read('User'))) ? '<span id="edit_link">'.$html->link(___('editors_review_a_edit_item'), '/developers/edit/'.$addon['Addon']['id']).'</span>' : ''?>
+</div>
+<div id="form">
+ <?php
+ echo $html->hidden('Approval/ActionField', array('id' => 'actionField'));
+ echo $html->hidden('Approval/Type', array('value' => $reviewType));
+ ?>
+ <div id="actionbox">
+ <span id="public" class="action_color" onClick="selectAction('public');"><?=$html->image('developers/public-bw.png', array('id' => 'publicIcon')).' '._('editors_review_action_public')?></span>
+ <span id="sandbox" class="action_color" onClick="selectAction('sandbox');"><?=$html->image('developers/sandbox-bw.png', array('id' => 'sandboxIcon')).' '._('editors_review_action_sandbox')?></span>
+ <span id="info" class="action_color" onClick="selectAction('info');"><?=$html->image('developers/info-bw.png', array('id' => 'infoIcon')).' '.___('editors_review_action_info')?></span>
+ <span id="superreview" class="action_color" onClick="selectAction('superreview');"><?=$html->image('developers/superreview-bw.png', array('id' => 'superreviewIcon')).' '._('editors_review_action_request_superreview')?></span>
+ </div>
+ <div id="actiondetails">
+ <?php
+ if ($reviewType == 'pending') {
+ echo '<div id="details-public" style="display: none;">';
+ echo _('editors_review_details_pending_public');
+ echo '</div>';
+ echo '<div id="details-sandbox" style="display: none;">';
+ echo _('editors_review_details_pending_sandbox');
+ echo '</div>';
+ }
+ elseif ($reviewType == 'nominated') {
+ echo '<div id="details-public" style="display: none;">';
+ echo _('editors_review_details_nominated_public');
+ echo '</div>';
+ echo '<div id="details-sandbox" style="display: none;">';
+ echo _('editors_review_details_nominated_sandbox');
+ echo '</div>';
+ }
+ ?>
+ <div id="details-info" style="display: none;">
+ <?=___('editors_review_details_info_request')?>
+ </div>
+ <div id="details-superreview" style="display: none;">
+ <?=_('editors_review_details_superreview');?>
+ </div>
+ </div>
+ <div id="subform" style="display: none;">
+ <div id="commentsbox">
+ <?=_('editors_review_label_comments')?>
+ <?=$html->textarea('Approval/comments', array('cols' => '70', 'rows' => '5', 'id' => 'comments', 'class' => 'input'))?>
+ </div>
+ <?php
+ if (!empty($cannedresponses)) {
+ echo '<div id="canned">';
+ echo _('editors_review_label_cannedresponse').' ';
+ echo $html->selectTag('Approval/CannedResponse', $cannedresponses, null, array("onChange" => "document.getElementById('comments').value = this.value;", 'class' => 'input'));
+ echo '</div>';
+ }
+ if ($reviewType == 'pending') {
+ ?>
+ <div id="testing">
+ <div id="os">
+ <?=_('editors_review_label_operating_systems')?>
+ <?=$html->input('Approval/os', array('class' => 'input', 'size' => '30'))?>
+ </div>
+ <div id="apps">
+ <?=_('editors_review_label_applications')?>
+ <?=$html->input('Approval/applications', array('class' => 'input', 'size' => '30'))?>
+ </div>
+ </div>
+ <?
+ }
+ ?>
+ <div id="subscribe">
+ <?php
+ $_subscribetext = ___('editors_review_update_notify_once');
+ echo $html->checkbox('Approval/subscribe', $_subscribetext);
+ ?>
+ <label for="ApprovalSubscribe"><?=$_subscribetext?></label>
+ </div>
+ <div id="finish">
+ <?=$html->submit(_('editors_review_submit_process_action'), array('id' => 'process', 'onClick' => 'return validateReview(\''.$reviewType.'\');'))?>
+ </div>
+ </div>
+</div>
+</form>
+<div id="notes">
+<?php
+if (!empty($addon['Addon']['nominationmessage'])) {
+ echo '<div class="highlighted">';
+ echo '<h3>'._('editors_review_header_nominationmessage').'</h3>';
+ echo '<div id="nominationMessage">';
+ echo nl2br($addon['Addon']['nominationmessage']);
+ echo '</div>';
+ echo '</div>';
+}
+if (!empty($version['Version']['approvalnotes'])) {
+ echo '<h3>'._('editors_review_header_reviewernotes').'</h3>';
+ echo '<div id="reviewNotes">';
+ echo nl2br($version['Version']['approvalnotes']);
+ echo '</div>';
+}
+if (!empty($addon['Translation']['summary']['string'])) {
+ echo '<h3>'._('editors_review_header_summary').'</h3>';
+ echo '<div id="summary" '.$addon['Translation']['summary']['locale_html'].'>';
+ echo nl2br($addon['Translation']['summary']['string']);
+ echo '</div>';
+}
+if (!empty($addon['Translation']['description']['string'])) {
+ echo '<h3>'._('editors_review_header_description').'</h3>';
+ echo '<div id="description" '.$addon['Translation']['description']['locale_html'].'>';
+ echo nl2br($addon['Translation']['description']['string']);
+ echo '</div>';
+}
+if (!empty($version['Translation']['releasenotes']['string'])) {
+ echo '<h3>'._('editors_review_header_versionnotes').'</h3>';
+ echo '<div id="versionNotes" '.$version['Translation']['releasenotes']['locale_html'].'>';
+ echo nl2br($version['Translation']['releasenotes']['string']);
+ echo '</div>';
+}
+if (!empty($addon['Translation']['eula']['string'])) {
+ echo '<h3>'._('editors_review_header_eula').'</h3>';
+ echo '<div id="EULA" '.$addon['Translation']['eula']['locale_html'].'>';
+ echo nl2br($addon['Translation']['eula']['string']);
+ echo '</div>';
+}
+if (!empty($addon['Translation']['privacypolicy']['string'])) {
+ echo '<h3>'._('editors_review_header_privacy').'</h3>';
+ echo '<div id="privacyPolicy" '.$addon['Translation']['privacypolicy']['locale_html'].'>';
+ echo nl2br($addon['Translation']['privacypolicy']['string']);
+ echo '</div>';
+}
+if (!empty($addon['Translation']['developercomments']['string'])) {
+ echo '<h3>'._('editors_review_header_devcomments').'</h3>';
+ echo '<div id="developerComments" '.$addon['Translation']['developercomments']['locale_html'].'>';
+ echo nl2br($addon['Translation']['developercomments']['string']);
+ echo '</div>';
+}
+?>
+</div>
+<div id="history">
+ <div class="sectionHeader">
+ <div class="name"><a name="history"></a><?=_('editors_review_header_itemhistory')?></div>
+ <div class="top"><a href="#top"><?=_('editors_review_link_pagetop')?></a></div>
+ </div>
+ <br class="clear">
+ <table id="historyTable">
+ <tr id="headerRow">
+ <td><?=_('editors_review_th_version_file')?></td>
+ <td><?=_('editors_review_th_date')?></td>
+ <td><?=_('editors_review_th_reviewer')?></td>
+ <td><?=_('editors_review_th_action')?></td>
+ <td><?=_('editors_review_th_comments')?></td>
+ </tr>
+ <?php
+ if (!empty($history)) {
+ foreach ($history as &$hist) {
+ echo $this->renderElement('developers/editors_review_history_item', array('hist'=>$hist));
+ }
+ }
+ else {
+ echo '<tr><td id="notFound" colspan="5">'._('editors_review_history_nonefound').'</td></tr>';
+ }
+ ?>
+ </table>
+</div>
+<br class="clear">
+<div id="previews">
+ <div class="sectionHeader">
+ <div class="name"><a name="previews"></a><?=_('editors_review_header_previews')?></div>
+ <div class="top"><a href="#top"><?=_('editors_review_link_pagetop')?></a></div>
+ </div>
+ <br class="clear">
+ <?php
+ if (!empty($addon['Preview'])) {
+ foreach ($addon['Preview'] as $preview) {
+ $previewUrl = $this->controller->Image->getPreviewURL($preview['id']);
+ echo '<img src="'.$previewUrl.'" border=0>&nbsp;&nbsp;';
+ }
+ } else {
+ echo _('editors_review_previews_notfound');
+ }
+ ?>
+</div>
+
+</div>
diff --git a/site/app/views/editors/reviewlog.thtml b/site/app/views/editors/reviewlog.thtml
new file mode 100644
index 0000000..4fc5aa2
--- /dev/null
+++ b/site/app/views/editors/reviewlog.thtml
@@ -0,0 +1,114 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * Justin Scott <fligtar@gmail.com>.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+?>
+<div id="content">
+ <?=$this->renderElement('developers/editorsmenu');?>
+
+ <div id="content-main">
+ <h3><?=_('editorcp_reviewlog_page_heading')?></h3>
+ <form action="<?=$html->url()?>" method="get">
+ <?php
+ echo sprintf(_('editorcp_reviewlog_entries_between'),
+ '<input type="text" id="start" name="start" value="'.$startdate.'" size="11" onFocus="clearInput(this)"/>',
+ '<input type="text" id="end" name="end" value="'.$enddate.'" size="11" onFocus="clearInput(this)"/>');
+ echo '&nbsp;&nbsp;';
+ echo $html->submit(_('editorcp_reviewlog_button_filter'));
+ ?>
+ </form>
+
+ <table id="historyTable">
+ <tr id="headerRow">
+ <td><?=_('editorcp_reviewlog_column_date')?></td>
+ <td><?=_('editorcp_reviewlog_column_addon')?></td>
+ <td><?=_('editorcp_reviewlog_column_editor')?></td>
+ <td><?=_('editorcp_reviewlog_column_action')?></td>
+ <td>&nbsp;</td>
+ </tr>
+ <?php
+ if (!empty($approvals)) {
+ foreach ($approvals as $k => $approval) {
+ echo '<tr id="reviewEntry_'.$k.'">';
+ echo "<td>{$approval['Approval']['created']}</td>";
+ echo '<td>'.$html->link($approval['Addon']['Translation']['name']['string'], '/editors/review/'.$approval['File']['version_id']).'</td>';
+ echo "<td>{$approval['User']['firstname']} {$approval['User']['lastname']}</td>";
+ echo '<td>';
+ if ($approval['Approval']['reviewtype'] == 'nominated') {
+ if ($approval['Approval']['action'] == STATUS_PUBLIC) {
+ echo _('editors_review_history_nominated_approved');
+ }
+ elseif ($approval['Approval']['action'] == STATUS_SANDBOX) {
+ echo _('editors_review_history_nominated_denied');
+ }
+ elseif ($approval['Approval']['action'] == STATUS_NOMINATED) {
+ echo _('editors_review_history_nominated_adminreview');
+ }
+ }
+ elseif ($approval['Approval']['reviewtype'] == 'pending') {
+ if ($approval['Approval']['action'] == STATUS_PUBLIC) {
+ echo _('editors_review_history_pending_approved');
+ }
+ elseif ($approval['Approval']['action'] == STATUS_SANDBOX) {
+ echo _('editors_review_history_pending_denied');
+ }
+ elseif ($approval['Approval']['action'] == STATUS_PENDING) {
+ echo _('editors_review_history_pending_adminreview');
+ }
+ }
+ echo '</td>';
+ echo '<td>';
+ echo $html->link(_('editorcp_reviewlog_comments_show'), 'javascript:void(0);', array('onClick' => 'showComments('.$k.');', 'id' => 'reviewShow_'.$k));
+ echo $html->link(_('editorcp_reviewlog_comments_hide'), 'javascript:void(0);', array('onClick' => 'hideComments('.$k.');', 'style' => 'display: none;', 'id' => 'reviewHide_'.$k));
+ echo '</td>';
+ echo '</tr>';
+ echo '<tr id="reviewComment_'.$k.'" style="display: none;">';
+ echo '<td class="reviewComment" colspan=5>'.nl2br($approval['Approval']['comments']).'</td>';
+ echo '</tr>';
+ }
+ }
+ else {
+ echo '<tr>';
+ echo '<td colspan=4 align="center">'._('editorcp_reviewlog_none_found').'</td>';
+ echo '</tr>';
+ }
+ //pr($approvals);
+
+ ?>
+ </table>
+
+ <? if (!empty($approvals)) echo $this->renderElement('pagination');?>
+ </div>
+</div>
diff --git a/site/app/views/editors/reviews_queue.thtml b/site/app/views/editors/reviews_queue.thtml
new file mode 100644
index 0000000..b077db0
--- /dev/null
+++ b/site/app/views/editors/reviews_queue.thtml
@@ -0,0 +1,122 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * Justin Scott <fligtar@gmail.com>.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Wil Clouser <clouserw@gmail.com>
+ * Frederic Wenzel <fwenzel@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+?>
+<div id="content">
+ <?=$this->renderElement('developers/editorsmenu');?>
+ <?=$this->renderElement('developers/editorsqueue');?>
+
+<div class="reviews">
+<?php
+ if (!empty($reviews)) {
+ echo $html->formTag('/editors/queue/reviews');
+
+ foreach ($reviews as $review) {
+ $review['Translation'] = (array_key_exists(LANG, $review['Translation']) ?
+ $review['Translation'][LANG] : current($review['Translation']));
+?>
+ <div class="corner-box">
+ <h3><?=$html->link($review['Addon']['Translation']['name']['string'], '/addons/display/'.$review['Addon']['Addon']['id']).
+ ': '.$review['Translation']['title']['string']?> (<?=$review['Translation']['title']['locale']?>)</h3>
+
+ <div class="reviewed-on"><?= sprintf(_('addon_reviewed_on_x_rated_y'), $html->linkUserFromModel($review['User']), strftime(_('date'), strtotime($review['Review']['created'])), $review['Review']['rating'])?></div>
+ <?=nl2br($review['Translation']['body']['string'])?>
+
+ <? /* Developer reply? */
+ if (!empty($review['Review']['reply_to'])):
+ $replyto = $review['Review']['reply_to'];
+ $replyto['Translation'] = (array_key_exists(LANG, $replyto['Translation']) ?
+ $replyto['Translation'][LANG] : current($replyto['Translation']));
+ ?>
+ <div class="review-reply">
+ <h3><?=_('editors_reviews_in_reply_to')?> <?=$replyto['Translation']['title']['string']?></h3>
+ <div class="reviewed-on"><?= sprintf(_('addon_reviewed_on_x_rated_y'), $html->linkUserFromModel($replyto['User']), strftime(_('date'), strtotime($replyto['Review']['created'])), $replyto['Review']['rating'])?></div>
+ <?=nl2br($replyto['Translation']['body']['string'])?>
+ </div>
+ <? endif; ?>
+
+ <?php /* List out the review flags selected by users */ ?>
+ <?php if ($flags = @$reviews_flags[$review['Review']['id']]): ?>
+ <ul class="review-flags">
+
+ <?php foreach ($flags as $flag_name => $count): ?>
+ <?php /* Skip the 'other' flag until the end */ ?>
+ <?php if ($flag_name == 'review_flag_reason_other') continue ?>
+ <li><?php echo $review_flag_reasons[$flag_name] ?></li>
+ <?php endforeach ?>
+
+ <?php /* If there are 'other' flags, list out the freeform notes supplied by users */ ?>
+ <?php if ($notes = @$reviews_flags_notes[$review['Review']['id']]): ?>
+ <li>
+ <span><?php echo $review_flag_reasons['review_flag_reason_other'] ?></span>
+ <ul class="review-flags-notes">
+ <?php foreach ($notes as $note): ?>
+ <li><span class="note"><?php echo $note ?></span></li>
+ <?php endforeach; ?>
+ </ul>
+ </li>
+ <?php endif; ?>
+
+ </ul>
+ <? endif; ?>
+
+ </ul>
+ <div class="reviewAction">
+ <b><?=_('editors_reviews_header_action')?></b>:&nbsp;
+ <input type="radio" name="data[Reviews][review<?=$review['Review']['id']?>]" value="skip" checked id="skip<?=$review['Review']['id']?>">
+ <label for="skip<?=$review['Review']['id']?>"><?=_('editors_reviews_action_skip')?></label>
+ <input type="radio" name="data[Reviews][review<?=$review['Review']['id']?>]" value="approve" id="approve<?=$review['Review']['id']?>">
+ <label for="approve<?=$review['Review']['id']?>"><?=___('editors_reviews_action_keep', 'Remove flags; keep review')?></label>
+ <input type="radio" name="data[Reviews][review<?=$review['Review']['id']?>]" value="delete" id="deny<?=$review['Review']['id']?>">
+ <label for="deny<?=$review['Review']['id']?>"><?=___('editors_reviews_action_delete_review', 'Delete review')?></label>
+ </div>
+ </div>
+<?
+ }
+ echo $html->submit(_('editors_reviews_submit_process_reviews'));
+ echo '</form>';
+
+ echo $this->renderElement('pagination');
+ }
+ else {
+ echo '<div class="emptyQueue">'._('editors_reviews_queue_empty').'</div>';
+ }
+?>
+</div>
+
+</div>
diff --git a/site/app/views/editors/summary.thtml b/site/app/views/editors/summary.thtml
new file mode 100644
index 0000000..334fc2c
--- /dev/null
+++ b/site/app/views/editors/summary.thtml
@@ -0,0 +1,108 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * Justin Scott <fligtar@gmail.com>.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+?>
+<div id="content">
+ <?=$this->renderElement('developers/editorsmenu');?>
+
+ <div id="content-main">
+ <h3><?=_('editorcp_summary_page_heading')?></h3>
+ <table class="stats">
+ <tr>
+ <td class="heading" colspan=2><?=_('editorcp_summary_totalreviews_heading')?></td>
+ </tr>
+ <?php
+ if (!empty($totalReviews)) {
+ foreach ($totalReviews as $totalReview) {
+ echo '<tr>';
+ echo '<td class="title">'.$totalReview['users']['firstname'].' '.$totalReview['users']['lastname'].'</td>';
+ echo '<td class="value">'.$totalReview[0]['total'].'</td>';
+ echo '</tr>';
+ }
+ }
+ ?>
+ </table>
+
+ <table class="stats">
+ <tr>
+ <td class="heading" colspan=2><?=_('editorcp_summary_monthreviews_heading')?></td>
+ </tr>
+ <?php
+ if (!empty($monthReviews)) {
+ foreach ($monthReviews as $monthReview) {
+ echo '<tr>';
+ echo '<td class="title">'.$monthReview['users']['firstname'].' '.$monthReview['users']['lastname'].'</td>';
+ echo '<td class="value">'.$monthReview[0]['total'].'</td>';
+ echo '</tr>';
+ }
+ }
+ ?>
+ </table>
+
+ <table class="stats">
+ <tr>
+ <td class="heading" colspan=2><?=_('editorcp_summary_neweditors_heading')?></td>
+ </tr>
+ <?php
+ if (!empty($newEditors)) {
+ foreach ($newEditors as $newEditor) {
+ echo '<tr>';
+ echo '<td class="title">'.$newEditor['users']['firstname'].' '.$newEditor['users']['lastname'].'</td>';
+ $newEditor['eventlog']['created'] = split(' ', $newEditor['eventlog']['created']);
+ echo '<td class="value">'.$newEditor['eventlog']['created'][0].'</td>';
+ echo '</tr>';
+ }
+ }
+ ?>
+ </table>
+ <br>
+ <table width="100%" class="log">
+ <tr>
+ <td class="heading" colspan=2><?=_('editorcp_summary_recentactivity_heading')?></td>
+ </tr>
+ <?php
+ if (!empty($logs)) {
+ foreach ($logs as $log) {
+ echo '<tr>';
+ echo '<td class="value" style="font-size: 80%;">'.$log['time'].'</td>';
+ echo '<td class="title">'.$log['entry'].'</td>';
+ echo '</tr>';
+ }
+ }
+ ?>
+ </table>
+ </div>
+</div>
diff --git a/site/app/views/elements/addon_author_addons.thtml b/site/app/views/elements/addon_author_addons.thtml
new file mode 100644
index 0000000..5b915f4
--- /dev/null
+++ b/site/app/views/elements/addon_author_addons.thtml
@@ -0,0 +1,65 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Jeff Balogh <jbalogh@mozilla.com (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+
+/**
+ * This element uses the following local variables:
+ * - $tag (either 'option' or 'li'; what kind of elements to output)
+ * - $addon (the current addon being displayed)
+ * - $authorAddons (list of other addons by the authors)
+ */
+
+foreach ($authorAddons as $authorAddon) {
+ $id = $authorAddon['Addon']['id'];
+ // Truncating at 25 because that lines the select box up with the natural
+ // border of the page layout.
+ $name = $html->truncateChars(25, $authorAddon['Translation']['name']['string']);
+
+ $nicknames = array();
+ foreach ($authorAddon['User'] as $user)
+ $nicknames[] = empty($user['nickname']) ? $user['firstname'].' '.$user['lastname'] : $user['nickname'];
+ $title = implode(', ', $nicknames);
+
+ if ($tag == 'li' && $id != $addon['Addon']['id']) {
+ echo "<li><a href='{$html->url('/addon/'.$id)}' title='{$title}'>{$name}</a></li>";
+ } else if ($tag == 'option') {
+ $selected = $id == $addon['Addon']['id'] ? 'selected="selected"' : '';
+ echo "<option value='{$id}' title='{$title}' {$selected}>{$name}</option>";
+ }
+}
+?>
diff --git a/site/app/views/elements/addon_categories.thtml b/site/app/views/elements/addon_categories.thtml
new file mode 100644
index 0000000..96d0e2b
--- /dev/null
+++ b/site/app/views/elements/addon_categories.thtml
@@ -0,0 +1,75 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Frederic Wenzel <fwenzel@mozilla.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+
+/**
+ * This element uses the following local variables:
+ * - $tags (a Tag model-style result set)
+ */
+?>
+<ul class="addon-cats">
+<?php
+// show top-level category for non-extension add-ons
+if (!empty($tags)) {
+ switch ($tags[0]['Tag']['addontype_id']) {
+ case ADDON_DICT:
+ case ADDON_LPAPP:
+ $li = $html->link(___('nav_category_dicts_langpacks'), '/browse/type:'.ADDON_DICT);
+ break;
+ case ADDON_THEME:
+ $li = $html->link(___('nav_category_themes'), '/browse/type:'.ADDON_THEME);
+ break;
+ default:
+ $li = '';
+ }
+ if ($li) echo "<li>{$li}</li>\n";
+}
+
+// regular category list
+$c = 0;
+foreach ($tags as $_tag) {
+ if (0 == $c++)
+ echo '<li class="first">';
+ else
+ echo '<li>';
+ echo $html->link($_tag['Translation']['name']['string'],
+ "/browse/type:{$_tag['Tag']['addontype_id']}/cat:{$_tag['Tag']['id']}")
+ ."</li>\n";
+}
+?>
+</ul>
diff --git a/site/app/views/elements/addon_discussionheader.thtml b/site/app/views/elements/addon_discussionheader.thtml
new file mode 100644
index 0000000..1dd3fae
--- /dev/null
+++ b/site/app/views/elements/addon_discussionheader.thtml
@@ -0,0 +1,87 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Frederic Wenzel <fwenzel@mozilla.com> (Original Author)
+ * Wil Clouser <clouserw@mozilla.com>
+ * Mike Shaver <shaver@mozilla.com>
+ * Mike Morgan <morgamic@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/**
+ * This element uses the following local variables:
+ * - $addon (Addon model-style array, containing 'Addon' and
+ * (optionally) 'Version', 'File', 'Tag' sub-arrays)
+ * - $addonIconPath (optional)
+ * - $addonPreviewPath (optional)
+ */
+
+$addonID = $addon['Addon']['id'];
+$addonName = $addon['Translation']['name']['string'];
+$hasVersion = (isset($addon['Version']) && !empty($addon['Version']));
+$addonVersion = ($hasVersion ? $addon['Version'][0]['version'] : '');
+$addonCreators = $addon['User'];
+$addonSummary = $addon['Translation']['summary']['string'];
+
+// is addon recommended or experimental?
+
+
+// prepare preview image
+if (isset($addonPreviewPath) && !empty($addonPreviewPath)) {
+ $_alt = sprintf(_('img_preview_of'),$addonName);
+ $previmg = '<img src="'.$addonPreviewPath.'" '
+ .'alt="'.$_alt.'" title="'.$_alt.'"/>';
+ $previmg = '<p class="preview-img">'
+ .$html->link($previmg, "/addon/{$addonID}").'</p>';
+} else
+ $previmg = '';
+// prepare icon
+if (isset($addonIconPath) && !empty($addonIconPath))
+ $icon = '<img src="'.$addonIconPath.'" class="icon" alt=""/>';
+else
+ $icon = '';
+
+// prepare summary
+if (!isset($addonSummary) || empty($addonSummary))
+ $addonSummary = '&nbsp;';
+?>
+
+<div class="addon">
+ <div class="irk">
+ <h3 class="name discussions"><?=$html->link("$icon $addonName", "/addon/{$addonID}");?></h3>
+ <h4 class="author discussions"> <?=_('addons_home_by')?> <?=$html->linkUsersFromModel($addonCreators, null, "/addon/{$addonID}#authors")?></h4>
+ <p class="desc"><?=$addonSummary?></p>
+ </div>
+ <div class="vex"><span><!-- bottom edge --></span></div>
+</div>
diff --git a/site/app/views/elements/addon_list_options.thtml b/site/app/views/elements/addon_list_options.thtml
new file mode 100644
index 0000000..16d571e
--- /dev/null
+++ b/site/app/views/elements/addon_list_options.thtml
@@ -0,0 +1,110 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Frederic Wenzel <fwenzel@mozilla.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/**
+ * This element uses the following local variables:
+ * - $paging -- paging options array (from the pagination component)
+ */
+
+$sortorders = array(
+ 'name' => _('list_sortby_name'),
+ 'updated' => _('list_sortby_date'),
+ 'popular' => _('list_sortby_downloads'),
+ 'rated' => _('list_sortby_rating')
+ );
+
+// make sort order links
+$sortlinks = array();
+
+// get base URL for sort links
+$sortbase = preg_replace(array('@^.*'.APP_SHORTNAME.'@', '@/sort:[^/?]+@'), '', $this->here);
+
+// prepare sort order buttons
+foreach ($sortorders as $sortkey => $prettystring) {
+ if ($paging['sortBy'] == $sortkey)
+ $sortlinks[] = '<li><button type="submit" name="sort" value="'
+ .$sortkey.'" id="order-'.$sortkey.'" class="current"><strong>'
+ .$prettystring.'</strong></button></li>'."\n";
+ else
+ $sortlinks[] = '<li><button type="submit" name="sort" value="'
+ .$sortkey.'" id="order-'.$sortkey.'"><span>'.$prettystring
+ .'</span></button></li>'."\n";
+}
+?>
+<script type="text/javascript">
+function submit_options() {
+ var optionform = document.getElementById('form-listcontrol');
+ /* preserve sort order */
+ var sortorder = document.createElement('input');
+ sortorder.setAttribute('type', 'hidden');
+ sortorder.setAttribute('name', 'sort');
+ sortorder.setAttribute('value', '<?=$paging['sortBy']?>');
+ optionform.appendChild(sortorder);
+ optionform.submit();
+ return true;
+}
+</script>
+
+<form id="form-listcontrol" method="get" action="<?=$html->url($sortbase)?>">
+ <p id="per-page">
+ <label for="show-perpage">
+ <select id="show-perpage" name="show" onchange="submit_options();">
+ <?php
+ foreach($this->controller->Pagination->resultsPerPage as $_perpage) {
+ echo "<option".($_perpage==$paging['show'] ? ' selected="selected"' : '')
+ .">{$_perpage}</option>\n";
+ }
+ ?>
+ </select>
+ <?=_('addon_list_perpage')?></label>
+ </p>
+
+ <ul id="order-by">
+ <li id="order-label"><?=_('addon_list_sortby')?></li>
+ <?=implode('', $sortlinks)?>
+ </ul>
+
+ <p id="experimental">
+ <label for="show-exp"><input type="checkbox" id="show-exp"
+ name="exp"<?=($show_exp?' checked':'')?> onChange="submit_options();"/>
+ <?=_('addons_options_show_experimental')?></label>
+ </p>
+
+ <div><button type="submit" name="sort" value="<?=$paging['sortBy']?>"
+ id="options-submit" class="hidden"><?=_('addons_options_submit')?></button></div>
+</form>
diff --git a/site/app/views/elements/addon_listitem.thtml b/site/app/views/elements/addon_listitem.thtml
new file mode 100644
index 0000000..cd68b71
--- /dev/null
+++ b/site/app/views/elements/addon_listitem.thtml
@@ -0,0 +1,129 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Frederic Wenzel <fwenzel@mozilla.com> (Original Author)
+ * Wil Clouser <clouserw@mozilla.com>
+ * Mike Shaver <shaver@mozilla.com>
+ * Mike Morgan <morgamic@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/**
+ * This element uses the following local variables:
+ * - $addon (Addon model-style array, containing 'Addon' and
+ * (optionally) 'Version', 'File', 'Tag' sub-arrays)
+ * - $addonIconPath (optional)
+ * - $addonPreviewPath (optional)
+ */
+
+$addonID = $addon['Addon']['id'];
+$addonName = $addon['Translation']['name']['string'];
+$hasVersion = (isset($addon['Version']) && !empty($addon['Version']));
+$addonVersion = ($hasVersion ? $addon['Version'][0]['version'] : '');
+$hasFiles = ($hasVersion && !empty($addon['File']));
+if ($hasFiles) {
+ $addonFiles = $addon['File'];
+ $addonEULA = $addon['Translation']['eula']['string'];
+} else {
+ return;
+}
+
+$addonCreators = $addon['User'];
+$addonSummary = $addon['Translation']['summary']['string'];
+
+// prepare preview image
+if (isset($addonPreviewPath) && !empty($addonPreviewPath)) {
+ $_alt = sprintf(_('img_preview_of'),$addonName);
+ $previmg = '<img src="'.$addonPreviewPath.'" '
+ .'alt="'.$_alt.'" title="'.$_alt.'"/>';
+ $previmg = '<p class="preview-img">'
+ .$html->link($previmg, "/addon/{$addonID}").'</p>';
+} else
+ $previmg = '';
+// prepare icon
+if (isset($addonIconPath) && !empty($addonIconPath))
+ $icon = '<img src="'.$addonIconPath.'" class="icon" alt=""/>';
+else
+ $icon = '';
+
+// prepare categories
+if (!empty($addon['Tag'])) {
+ $categories = $this->renderElement('addon_categories', array('tags' => $addon['Tag']));
+} else
+ $categories = '';
+
+// prepare summary
+if (!isset($addonSummary) || empty($addonSummary))
+ $addonSummary = '&nbsp;';
+
+$_install_render_options = array(
+ 'addonIconPath' => $addonIconPath,
+ 'addonName' => $addonName,
+ 'addonId' => $addonID,
+ 'addonFiles' => $addonFiles,
+ 'addonEULA' => $addonEULA,
+ 'addonStatus' => $addon['Addon']['status'],
+ 'is_latest' => ($addon['Addon']['status'] == STATUS_PUBLIC),
+ 'addonType' => $addon['Addon']['addontype_id'],
+ 'compatible_apps' => $addon['compatible_apps'],
+ 'allPlatforms' => $platforms,
+ );
+$installbutton = $this->renderElement('install', $_install_render_options);
+
+?>
+
+<li class="addon <?=$html->extraClass($addon)?>">
+ <div class="irk">
+ <h3 class="name"><?=$html->link("$icon $addonName", "/addon/{$addonID}");?></h3>
+ <h4 class="author"> <?=_('addons_home_by')?> <?=$html->linkUsersFromModel($addonCreators, null, "/addon/{$addonID}#authors")?></h4>
+ <?=$html->flag($addon)?>
+ <?=$previmg ?>
+ <p class="rating"><?=$this->renderElement('stars',array('rating' => $addon['Addon']['averagerating']))?><?php if ($addon['Addon']['totalreviews'] > 0) { ?> <a href="<?=$html->url('/addon/'.$addon['Addon']['id'].'#reviews')?>"><?=sprintf(ngettext('feature_reviews','feature_reviews', $addon['Addon']['totalreviews']), $addon['Addon']['totalreviews'])?></a><?php } ?></p>
+ <span class="stats">
+ <em><?=$html->number_format($addon['Addon']['weeklydownloads'], 0)?></em>
+ <?php echo ___('addon_downloads_weekly'); ?>
+ </span>
+ <?=$categories?>
+ <p class="desc"><?=$addonSummary?></p>
+ <?=$installbutton?>
+ <p class="updated">
+ <?php
+ $_update_string = ___('addon_detail_last_updated');
+ $_version_date = (isset($addon['Addon']['datestatuschanged']) ? $addon['Addon']['datestatuschanged'] : $addon['Version'][0]['created']);
+ echo sprintf($_update_string, strftime(_('date'), strtotime($_version_date)));
+ ?>
+ </p>
+ </div>
+ <div class="vex"><span><!-- bottom edge --></span></div>
+</li>
diff --git a/site/app/views/elements/addon_version_detail.thtml b/site/app/views/elements/addon_version_detail.thtml
new file mode 100644
index 0000000..6c61f61
--- /dev/null
+++ b/site/app/views/elements/addon_version_detail.thtml
@@ -0,0 +1,54 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Frederic Wenzel <fwenzel@mozilla.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+
+/**
+ * This element uses the following local variables:
+ * - $addonid
+ * - $version
+ * - $created
+ * - $fileSize -- default ''
+ */
+
+$created = strtotime(str_replace('&#45;', '-', $created));
+if (!isset($fileSize) || false === $fileSize = $localization->localFileSize($fileSize)) $fileSize = '';
+?>
+<?=$html->link(sprintf(_('addon_display_header_version'), $version), "/addons/versions/{$addonid}#version-{$version}",
+ array('title'=>___('addon_version_permalink', 'Permanent link to this version')))?>
+ <span title="<?=strftime(_('datetime'), $created)?>">&mdash;
+ <?=strftime(_('date'), $created)?></span> &mdash; <?=$fileSize?>
diff --git a/site/app/views/elements/amo2009/addon_list_options.thtml b/site/app/views/elements/amo2009/addon_list_options.thtml
new file mode 100644
index 0000000..4a3ba2e
--- /dev/null
+++ b/site/app/views/elements/amo2009/addon_list_options.thtml
@@ -0,0 +1,120 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Frederic Wenzel <fwenzel@mozilla.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/**
+ * This element uses the following local variables:
+ * - $paging -- paging options array (from the pagination component)
+ */
+
+$sortorders = array(
+ 'name' => _('list_sortby_name'),
+ 'updated' => _('list_sortby_date'),
+ 'popular' => _('list_sortby_downloads'),
+ 'rated' => _('list_sortby_rating')
+ );
+
+// get base URL for sort links and form
+$sortbase = preg_replace(array('@^.*'.APP_SHORTNAME.'@', '@/sort:[^/?]+@'), '', $this->here);
+
+?>
+<script type="text/javascript">
+function submit_options(sortby) {
+ var optionform = document.getElementById('form-listcontrol');
+ /* preserve sort order */
+ var sortorder = document.createElement('input');
+ sortorder.setAttribute('type', 'hidden');
+ sortorder.setAttribute('name', 'sort');
+ if (!sortby) {
+ sortorder.setAttribute('value', '<?=$paging['sortBy']?>');
+ } else {
+ sortorder.setAttribute('value', sortby);
+ }
+ optionform.appendChild(sortorder);
+ optionform.submit();
+ return true;
+}
+$(document).ready(function() {
+ $('#addon-list-options ul li a').click(function(e) {
+ var sortkey = $(this).attr('id').substring(6); // remove "order-"
+ submit_options(sortkey);
+ e.preventDefault();
+ return true;
+ });
+});
+</script>
+
+<div id="addon-list-options" class="listing-header">
+ <form id="form-listcontrol" method="get" action="<?=$html->url($sortbase)?>">
+ <ul>
+ <li id="order-label"><?=_('addon_list_sortby')?></li>
+ <?php foreach ($sortorders as $sortkey => $prettystring): ?>
+ <li<?= ($paging['sortBy'] == $sortkey ? ' class="selected"' : '') ?>>
+ <?= $html->link($prettystring, "{$sortbase}?sort={$sortkey}", array(
+ 'id' => "order-{$sortkey}"
+ ))?>
+ </li>
+ <?php endforeach; ?>
+ <li class="perpage">
+ <div>
+ <label for="show-perpage">
+ <select id="show-perpage" name="show" onchange="submit_options();">
+ <?php
+ foreach($this->controller->Pagination->resultsPerPage as $_perpage) {
+ echo "<option".($_perpage==$paging['show'] ? ' selected="selected"' : '')
+ .">{$_perpage}</option>\n";
+ }
+ ?>
+ </select>
+ <?=_('addon_list_perpage')?></label>
+ </div>
+ <div>
+ <label for="show-exp"><input type="checkbox" id="show-exp"
+ name="exp"<?=($show_exp?' checked':'')?> onChange="submit_options();"/>
+ <?=_('addons_options_show_experimental')?></label>
+ </div>
+ <noscript>
+ <div>
+ <button type="submit" name="sort" value="<?=$paging['sortBy']?>"
+ id="options-submit"><?=_('addons_options_submit')?></button>
+ </div>
+ </noscript>
+ </li>
+ </ul>
+
+ </form>
+</div>
diff --git a/site/app/views/elements/amo2009/addon_version_detail.thtml b/site/app/views/elements/amo2009/addon_version_detail.thtml
new file mode 100644
index 0000000..8498ce5
--- /dev/null
+++ b/site/app/views/elements/amo2009/addon_version_detail.thtml
@@ -0,0 +1,53 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Frederic Wenzel <fwenzel@mozilla.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+
+/**
+ * This element uses the following local variables:
+ * - $addonid
+ * - $version
+ * - $created
+ * - $fileSize -- default ''
+ */
+
+$created = strtotime(str_replace('&#45;', '-', $created));
+if (!isset($fileSize) || false === $fileSize = $localization->localFileSize($fileSize)) $fileSize = '';
+?>
+<?=$html->link(sprintf(_('addon_display_header_version'), $version), "/addons/versions/{$addonid}#version-{$version}",
+ array('title'=>___('addon_version_permalink', 'Permanent link to this version')))?>
+ &mdash; <?=strftime(_('date'), $created)?> &mdash; <?=$fileSize?>
diff --git a/site/app/views/elements/amo2009/breadcrumbs.thtml b/site/app/views/elements/amo2009/breadcrumbs.thtml
new file mode 100644
index 0000000..923160b
--- /dev/null
+++ b/site/app/views/elements/amo2009/breadcrumbs.thtml
@@ -0,0 +1,58 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Frederic Wenzel <fwenzel@mozilla.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/**
+ * Breadcrumbs element
+ * Displays breadcrumbs defined in the controller
+ *
+ * See views/collections/subscribe.thtml for sample usage
+ *
+ * Required parameters:
+ * - $breadcrumbs - array('breadcrumb title' => '/cake-relative/url')
+ *
+ * Optional parameters:
+ * - (none)
+ */
+?>
+<?php if (!empty($breadcrumbs)): ?>
+<ol class="breadcrumbs">
+ <?php foreach($breadcrumbs as $title => $url): ?>
+ <li><?=$html->link($title, $url)?></li>
+ <?php endforeach; ?>
+</ol>
+<?php endif; ?>
diff --git a/site/app/views/elements/amo2009/categories.thtml b/site/app/views/elements/amo2009/categories.thtml
new file mode 100644
index 0000000..6b8bddb
--- /dev/null
+++ b/site/app/views/elements/amo2009/categories.thtml
@@ -0,0 +1,84 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Mike Morgan <morgamic@mozilla.com> (Original Developer)
+ * Frederic Wenzel <fwenzel@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+?>
+<div class="categories">
+ <h3 title="<?=_('categories_header_title')?>">
+ <?php if (isset($clickable_header) && (FALSE === $clickable_header)): ?>
+ <span><?=_('categories_header')?></span>
+ <?php else: ?>
+ <a href="#categoriesdropdown" aria-haspopup="true"><?=_('categories_header')?></a>
+ <?php endif ?>
+ </h3>
+ <ul id="categoriesdropdown">
+ <li>
+ <ul>
+ <?php foreach ($AmoTags as $_tag): ?>
+ <?php if (0===$_tag['cat'] && ADDON_PLUGIN!==$_tag['type']) continue ?>
+ <?php
+ $_url = "/browse/type:{$_tag['type']}".
+ ($_tag['cat']!=0 ? "/cat:{$_tag['cat']}" : '');
+ ?>
+ <li>
+ <?= $html->link($html->entities($_tag['name']), $_url) ?>
+ <?php if (isset($_tag['count'])): ?>
+ <span class="items"><?= $html->entities($_tag['count']) ?></span>
+ <?php endif ?>
+ </li>
+ <?php endforeach ?>
+ </ul>
+ </li>
+ <li>
+ <ul>
+ <li>
+ <?= $html->link(___('addons_home_collections','Collections'), '/collections/') ?>
+ </li>
+ <?php foreach ($AmoTags as $_tag): ?>
+ <?php if (0!==$_tag['cat'] || ADDON_PLUGIN===$_tag['type']) continue ?>
+ <?php
+ $_url = "/browse/type:{$_tag['type']}".
+ ($_tag['cat']!=0 ? "/cat:{$_tag['cat']}" : '');
+ ?>
+ <li>
+ <?= $html->link($html->entities($_tag['name']), $_url) ?>
+ </li>
+ <?php endforeach ?>
+ </ul>
+ </li>
+ </ul>
+</div>
diff --git a/site/app/views/elements/amo2009/collection_add_form.thtml b/site/app/views/elements/amo2009/collection_add_form.thtml
new file mode 100644
index 0000000..fd96533
--- /dev/null
+++ b/site/app/views/elements/amo2009/collection_add_form.thtml
@@ -0,0 +1,75 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Jeff Balogh <jbalogh@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/**
+ * Required arguments:
+ * $collection: a Collection array
+ * $is_subscribed: whether the user is subscribed to $collection
+ * $buttonClass: CSS classes to add to the button element
+ * $withImage: whether images should be added to the button
+ */
+
+if ($is_subscribed) {
+ $buttonClass .= ' fav';
+ $action = $this->controller->Collection->getUnsubscribeUrl();
+ $text = ___('collections_detail_button_remove');
+} else {
+ $action = $this->controller->Collection->getSubscribeUrl();
+ $text = ___('collections_detail_button_add');
+}
+
+if ($withImage) {
+ $button = $is_subscribed ? 'minus' : 'plus';
+ $image = $html->image("/amo2009/icons/buttons/{$button}-orange-16x16.gif");
+ $buttonContent = $image . $text;
+} else {
+ $buttonContent = $text;
+}
+
+?>
+
+<form class="favourite" method="post" action="<?=$html->url($action)?>">
+ <div>
+ <?=$html->hiddenSession()?>
+ <input value="<?=$collection['Collection']['uuid']?>"
+ type="hidden" name="uuid" />
+ <button class="<?=$buttonClass?>">
+ <?=$buttonContent?>
+ </button>
+ </div>
+</form>
diff --git a/site/app/views/elements/amo2009/collection_listing_item.thtml b/site/app/views/elements/amo2009/collection_listing_item.thtml
new file mode 100644
index 0000000..65c9d47
--- /dev/null
+++ b/site/app/views/elements/amo2009/collection_listing_item.thtml
@@ -0,0 +1,95 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Jeff Balogh <jbalogh@mozilla.com>
+ * Frederic Wenzel <fwenzel@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+
+/* Required:
+ * $collection
+ * $user
+ */
+?>
+<div class="item">
+ <div class="item-info">
+ <ul>
+ <li class="addons">
+ <?php $count = $collection['Collection']['addonCount']; ?>
+ <?=sprintf(n___('addons_home_collections_addon_count',
+ 'addons_home_collections_addon_count',
+ $count),
+ $count);?>
+ </li>
+ <li class="subscribers">
+ <?php $subscribers = $collection['Collection']['subscribers']; ?>
+ <?=sprintf(n___('addons_home_collections_subscribers',
+ 'addons_home_collections_subscribers',
+ $subscribers),
+ $subscribers);?>
+ </li>
+ <?php if ($this->controller->Session->check('User')): ?>
+ <li>
+ <?php
+ $fav = $this->controller->Collection->isSubscribed(
+ $collection['Collection']['id'], $user['id']);
+ $params = array('collection' => $collection,
+ 'is_subscribed' => $fav,
+ 'buttonClass' => 'add-to-fav',
+ 'withImage' => false);
+ ?>
+ <?=$this->renderElement('amo2009/collection_add_form', $params)?>
+ </li>
+ <?php endif; ?>
+ </ul>
+ </div> <!-- item-info -->
+ <h3>
+ <?php $link = $this->controller->Collection->getDetailUrl($collection); ?>
+ <a href="<?=$html->url($link)?>">
+ <?=$collection['Translation']['name']['string']?>
+ </a>
+ <span>
+ <?=sprintf(___('collections_index_header_created'),
+ $html->linkUsersFromModel($collection['Users']))?>
+ </span>
+ <a href="<?=$html->url($link)?>">
+ <img class="icon" alt=""
+ src="<?=$this->controller->Image->getCollectionIconUrl($collection['Collection']['id'])?>" />
+ </a>
+ </h3>
+ <blockquote>
+ <p><?=$collection['Translation']['description']['string']?></p>
+ </blockquote>
+</div> <!-- item -->
diff --git a/site/app/views/elements/amo2009/collections_js_init.thtml b/site/app/views/elements/amo2009/collections_js_init.thtml
new file mode 100644
index 0000000..7e1a73e
--- /dev/null
+++ b/site/app/views/elements/amo2009/collections_js_init.thtml
@@ -0,0 +1,76 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Jeff Balogh <jbalogh@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* Optional:
+ * $addButtonSize: defaults to '16x16'
+ * $removeButtonSize: defaults to '16x16'
+ * $loadingButtonSize: defaults to '16x16'
+ */
+if (!isset($addButtonSize)) {
+ $addButtonSize = '16x16';
+}
+if (!isset($removeButtonSize)) {
+ $removeButtonSize = '16x16';
+}
+if (!isset($loadingButtonSize)) {
+ $loadingButtonSize = '16x16';
+}
+?>
+
+$(document).ready(function(){
+ var c = collections;
+
+ c.subscribe_url = '<?=$html->url($this->controller->Collection->getSubscribeUrl(true))?>';
+ c.unsubscribe_url = '<?=$html->url($this->controller->Collection->getUnsubscribeUrl(true))?>';
+
+ c.adding_img = '<?=$html->rootUrl("/img/amo2009/icons/white-loading-{$loadingButtonSize}.gif")?>';
+ c.adding_text = '<?=addcslashes(___('collections_detail_js_adding'), "'")?>';
+
+ c.removing_img = '<?=$html->rootUrl("/img/amo2009/icons/white-loading-{$loadingButtonSize}.gif")?>';
+ c.removing_text = '<?=addcslashes(___('collections_detail_js_removing'), "'")?>';
+
+ c.add_img = '<?=$html->rootUrl("/img/amo2009/icons/buttons/plus-orange-{$addButtonSize}.gif")?>';
+ c.add_text = '<?=addcslashes(___('collections_detail_button_add'), "'")?>';
+
+ c.remove_img = '<?=$html->rootUrl("/img/amo2009/icons/buttons/minus-orange-{$removeButtonSize}.gif")?>';
+ c.remove_text = '<?=addcslashes(___('collections_detail_button_remove'), "'")?>';
+
+ c.cookie_path = '<?=$html->rootUrl('/')?>';
+
+ collections.init();
+});
diff --git a/site/app/views/elements/amo2009/collections_sidebar_whatare.thtml b/site/app/views/elements/amo2009/collections_sidebar_whatare.thtml
new file mode 100644
index 0000000..7ca7248
--- /dev/null
+++ b/site/app/views/elements/amo2009/collections_sidebar_whatare.thtml
@@ -0,0 +1,47 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Frederic Wenzel <fwenzel@mozilla.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+?>
+<div class="highlight">
+ <h3><?=___('collections_whatare_header')?></h3>
+
+ <p class="teaser-img"><?=$html->image('amo2009/illustrations/logo-collections-download-146x159.png',
+ array('alt'=>'Collections Download Illustration', 'width'=>146, 'height'=>159))?></p>
+ <p><?=___('collections_whatare_text')?></p>
+ <p><?=$html->link(___('collections_whatare_learnmore'), '/pages/collector_faq',
+ array('class'=>'more-info'))?></p>
+</div>
diff --git a/site/app/views/elements/amo2009/collections_sort_form.thtml b/site/app/views/elements/amo2009/collections_sort_form.thtml
new file mode 100644
index 0000000..b618534
--- /dev/null
+++ b/site/app/views/elements/amo2009/collections_sort_form.thtml
@@ -0,0 +1,57 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Jeff Balogh <jbalogh@mozilla.com>
+ * Frederic Wenzel <fwenzel@mozilla.com>
+ * Scott McCammon <smccammon@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+?>
+<form class="item-sort" method="get" action="">
+ <div>
+<?php if (isset($query)): ?>
+ <input type="hidden" name="q" value="<?=$query?>" />
+ <input type="hidden" name="cat" value="collections" />
+ <input type="hidden" name="pp" value="<?=$pp?>" />
+<?php endif; ?>
+ <label for="sortby2"><?=___('collections_index_label_sortby')?></label>
+ <select id="sortby2" name="sortby">
+ <?php foreach ($sort_opts as $value => $opt): ?>
+ <?php $selected = ($value == $sortby) ? 'selected="selected"' : ''; ?>
+ <option value="<?=$value?>" <?=$selected?>><?=$opt['text']?></option>
+ <?php endforeach; ?>
+ </select>
+ <button><?=___('collections_index_button_go')?></button>
+ </div>
+</form>
diff --git a/site/app/views/elements/amo2009/collector_info_secondary.thtml b/site/app/views/elements/amo2009/collector_info_secondary.thtml
new file mode 100644
index 0000000..e9bea92
--- /dev/null
+++ b/site/app/views/elements/amo2009/collector_info_secondary.thtml
@@ -0,0 +1,76 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Jeff Balogh <jbalogh@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+$showFirstBox = isset($showFirstBox) ? $showFirstBox : true;
+$showCreateLink = isset($showCreateLink) ? $showCreateLink : true;
+$showSecondBox = isset($showSecondBox) ? $showSecondBox : true;
+?>
+
+<div class="secondary" role="complementary">
+ <? if ($showFirstBox): ?>
+ <div class="highlight">
+ <h3><?=___('collections_index_header_what')?></h3>
+ <p><?=___('collections_index_p_what_are')?></p>
+ <? if ($showCreateLink): ?>
+ <p>
+ <a class="more-info" href="<?=$html->url('/collections/add')?>">
+ <?=___('collections_index_a_create')?>
+ </a>
+ </p>
+ <? endif; ?>
+ </div>
+ <? endif; ?>
+ <? if ($showSecondBox): ?>
+ <div class="highlight">
+ <h3><?=___('collections_index_header_collector')?></h3>
+ <p class="teaser-img">
+ <a href="<?=$html->url('/pages/collector')?>">
+ <img alt="" src="<?=$html->url('/img/amo2009/illustrations/logo-collections-download-146x159.png',
+ false, false, false)?>" />
+ </a>
+ </p>
+ <p><?=___('collections_index_p_collector')?></p>
+ <p>
+ <a class="more-info" href="<?=$html->url('/pages/collector')?>">
+ <?=___('collections_index_a_check_out')?>
+ </a>
+ </p>
+ </div>
+ <? endif; ?>
+</div> <!-- secondary -->
+
diff --git a/site/app/views/elements/amo2009/collector_sidebar_download.thtml b/site/app/views/elements/amo2009/collector_sidebar_download.thtml
new file mode 100644
index 0000000..9113591
--- /dev/null
+++ b/site/app/views/elements/amo2009/collector_sidebar_download.thtml
@@ -0,0 +1,55 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Jeff Balogh <jbalogh@mozilla.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+?>
+
+<p class="teaser-img">
+ <img src="<?=$html->url('/img/amo2009/illustrations/logo-collections-download-146x159.png',
+ false, false, false)?>"
+ alt="<?=___('collector_features_img_logo')?>" />
+</p>
+<div id="download-box" class="highlight">
+ <h4><?=___('collector_features_heading_download')?></h4>
+ <?php
+ $assoc = array('compatible_apps', 'files', 'latest_version', 'list_details');
+ $addon = $this->controller->Addon->getAddon(COLLECTOR_ID, $assoc);
+ $params = array('addon' => $addon,
+ 'buttonSize' => '16x16',
+ 'buttonClass' => 'significant');
+ echo $this->renderElement('amo2009/install', $params);
+ ?>
+</div>
diff --git a/site/app/views/elements/amo2009/homepage_addon.thtml b/site/app/views/elements/amo2009/homepage_addon.thtml
new file mode 100644
index 0000000..6fc1f5a
--- /dev/null
+++ b/site/app/views/elements/amo2009/homepage_addon.thtml
@@ -0,0 +1,130 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Mike Morgan <morgamic@mozilla.com> (Original Author)
+ * Frederic Wenzel <fwenzel@mozilla.com>
+ * l.m.orchard <lorchard@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+?>
+<?php
+$addonIconPath = $this->controller->Image->getAddonIconURL($addon['Addon']['id']);
+$addonThumbPath = $this->controller->Image->getHighlightedPreviewURL($addon['Addon']['id']);
+$addonName = $addon['Translation']['name']['string'];
+$addonSummary = $addon['Translation']['summary']['string'];
+$addonId = $addon['Addon']['id'];
+$addonFiles = $addon['File'];
+$addonEULA = $addon['Translation']['eula']['string'];
+$addonStatus = $addon['Addon']['status'];
+$addonAuthors = $addon['User'];
+$addonTags = $addon['Tag'];
+$addonWeeklyDownloads = $addon['Addon']['weeklydownloads'];
+$allPlatforms = $platforms;
+$compatible_apps = $addon['compatible_apps'];
+$addonType = $addon['Addon']['addontype_id'];
+$addonRating = $addon['Addon']['averagerating'];
+$addonReviews = $addon['Addon']['totalreviews'];
+$addonVersionCreated = $addon['Version'][0]['created'];
+
+// Bug 444817: limit length of addon descriptions in feature elements.
+$desc_limit = 250;
+if (mb_strlen($addonSummary) > $desc_limit) {
+ // If the addon summary exceeds the display limit, cut it off before the
+ // last space-delimited word in the string and add an ellipsis linking to
+ // the full detail page. Would use TextHelper::truncate() here, but need
+ // mb_* string functions.
+
+ // mb_substr is used twice here, because mb_strrpos doesn't support
+ // offset in PHP 5.1.6 - first chop down to char limit, then chop down
+ // to end of last space-delimited word.
+ $addonSummary = mb_substr($addonSummary, 0, $desc_limit);
+ $addonSummary = mb_substr($addonSummary, 0, mb_strrpos($addonSummary, ' ')) .
+ ' <a href="'.$html->url("/addon/{$addonId}").'">...</a>';
+}
+
+// prepare alt and title text for preview image
+$_alt = sprintf(_('img_preview_of'), $addonName);
+
+$flags = array($html->byStatus($addon, array('experimental' => 'experimental',
+ 'recommended' => 'recommended',
+ 'default' => 'default')));
+$group = isset($group) ? $group : '';
+if (!empty($group)) {
+ $flags[] = $group;
+}
+
+// is addon experimental?
+global $experimental_status;
+if (isset($addonStatus) && in_array($addonStatus, $experimental_status)) {
+ $flags[] = 'experimental';
+}
+?>
+<div class="<?=join(' ', $flags)?> item">
+ <?=$this->renderElement('amo2009/install', array(
+ 'flags' => $flags,
+ 'addon' => $addon
+ ))?>
+ <h3>
+ <a title="<?=___('addons_title_tooltip') ?>" href="<?=$html->url("/addon/{$addonId}")?>"><?=$addonName?></a>
+ <span title="<?=___('addons_author_tooltip') ?>"><?=_('addons_home_by')?> <?=$html->linkUsersFromModel($addonAuthors, 0);?></span>
+ </h3>
+ <img src="<?=$addonIconPath?>" width="32" height="32" alt="<?=$_alt?>" title="<?=$_alt?>" class="icon"/>
+ <blockquote cite="#"><p><?=$addonSummary?></p></blockquote>
+ <div class="meta">
+ <?=$this->renderElement('amo2009/reviews', array('addon' => $addon))?>
+ <span class="downloads"><strong><?=$html->number_format($addonWeeklyDownloads, 0)?></strong> <?=___('addon_downloads_weekly')?></span>
+ </div>
+</div>
+
+<?php if (false): ?>
+<? if (!empty($flag)) echo '<h6 class="flag">'.$flag.'</h6>'; ?>
+<?php if (isset($addonFiles)): ?>
+
+<p class="updated">
+ <?php echo sprintf(___('addon_detail_last_updated'), strftime(_('date'), strtotime($addonVersionCreated))); ?>
+</p>
+
+<?=$this->renderElement('install',array(
+ 'addonType' => $addonType
+))?>
+<?php else: ?>
+<p class="learn-more"><?=$html->link(_('feature_learnmore'), "/addon/{$addonId}",
+ array('class'=>'view', 'title'=>sprintf(_('feature_learnmore_about_addon'), $addonName)))?></p>
+<?php endif; ?>
+
+<?php if(!empty($addonTags)): ?>
+<p class="more-from"><?=_('feature_view_more_from_category')?> <a href="<?=$html->url('/browse/type:'.$addonType.'/cat:'.$addonTags[0]['Tag']['id'])?>" class="view"><?=$addonTags[0]['Translation']['name']['string']?></a></p>
+<?php endif; ?>
+
+<?php endif ?>
diff --git a/site/app/views/elements/amo2009/homepage_addon_listing.thtml b/site/app/views/elements/amo2009/homepage_addon_listing.thtml
new file mode 100644
index 0000000..fcede5e
--- /dev/null
+++ b/site/app/views/elements/amo2009/homepage_addon_listing.thtml
@@ -0,0 +1,76 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * l.m.orchard <lorchard@mozilla.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+foreach ($featured_addons as $addon) {
+ echo $this->renderElement('amo2009/homepage_addon', array(
+ 'group' => $featured_type, 'addon' => $addon
+ ));
+}
+?>
+
+<?php if ('popular' == $featured_type): ?>
+<div class="popular listing-footer">
+ <a href="<?=$html->url('/browse/type:1/cat:all/format:rss?sort=popular')?>"
+ class="subscribe"><?=___('addons_home_browse_subscribe','Subscribe')?></a>
+ <a href="<?=$html->url("/browse/type:1/cat:all?sort=popular")?>" class="more-info"
+ title="<?=_('addons_home_view_all_popular_title')?>"><?=_('addons_home_view_all_popular_title')?></a>
+</div>
+<?php elseif ('added' == $featured_type): ?>
+<div class="added listing-footer">
+ <a href="<?=$html->url('/browse/type:1/cat:all/format:rss?sort=newest')?>"
+ class="subscribe"><?=___('addons_home_browse_subscribe','Subscribe')?></a>
+ <a href="<?=$html->url("/browse/type:1/cat:all?sort=newest")?>" class="more-info"
+ title="<?=_('addons_home_view_all_newest_title')?>"><?=_('addons_home_view_all_newest_title')?></a>
+</div>
+<?php elseif ('updated' == $featured_type): ?>
+<div class="updated listing-footer">
+ <a href="<?=$html->url('/browse/type:1/cat:all/format:rss?sort=updated')?>"
+ class="subscribe"><?=___('addons_home_browse_subscribe','Subscribe')?></a>
+ <a href="<?=$html->url("/browse/type:1/cat:all?sort=updated")?>" class="more-info"
+ title="<?=_('addons_home_view_all_updated_title')?>"><?=_('addons_home_view_all_updated_title')?></a>
+</div>
+<?php else: ?>
+<div class="recommended listing-footer">
+ <a href="<?=$html->url('/recommended/format:rss')?>"
+ class="subscribe"><?=___('addons_home_browse_subscribe','Subscribe')?></a>
+ <a href="<?=$html->url('/recommended')?>" class="more-info"
+ title="<?=_('addons_home_view_all_recommended_title')?>"><?=_('addons_home_view_all_recommended_title')?></a>
+</div>
+<?php endif ?>
+
+
diff --git a/site/app/views/elements/amo2009/install.thtml b/site/app/views/elements/amo2009/install.thtml
new file mode 100644
index 0000000..e938571
--- /dev/null
+++ b/site/app/views/elements/amo2009/install.thtml
@@ -0,0 +1,401 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * l.m.orchard <lorchard@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/**
+ * Required:
+ * $addon with Translation and File bound
+ * $this->controller->Platform or $platforms
+ * $this->controller->Image
+ *
+ * Optional:
+ * $flags: defaults to [], could contain 'recommended' or 'experimental'
+ * $buttonSize: defaults to '8x9'
+ * $buttonClass: defaults to ''
+ *
+ * This element accepts the following as overrides or instead of $addon:
+ * - $addonIconPath
+ * - $addonName
+ * - $addonId
+ * - $addonFiles
+ * - $is_latest -- link to "download/latest" shortcut (default false)
+ * - $addonEULA
+ * - $addonStatus
+ * - $allPlatforms - There should only be one platform in the list when this is used on the eula view.
+ * - $addonType - default ADDON_EXTENSION
+ * - $collection_uuid - if this add-on download is collection related, this will set a tracking code in the download ID. default null
+ * - $buttonMessage - default 'a_install'
+ * - $showInstructions - Show install instructions for Thunderbird or Seamonkey, defaults to true
+ */
+
+if (isset($addon)) {
+ if (!isset($addonIconPath))
+ $addonIconPath = $this->controller->Image->getAddonIconURL($addon['Addon']['id']);
+ if (!isset($addonName))
+ $addonName = $addon['Translation']['name']['string'];
+ if (!isset($addonId))
+ $addonId = $addon['Addon']['id'];
+ if (!isset($addonFiles))
+ $addonFiles = $addon['File'];
+ if (!isset($addonEULA))
+ $addonEULA = $addon['Translation']['eula']['string'];
+ if (!isset($addonStatus))
+ $addonStatus = $addon['Addon']['status'];
+ if (!isset($is_latest))
+ $is_latest = ($addonStatus == STATUS_PUBLIC);
+ if (!isset($compatible_apps))
+ $compatible_apps = $addon['compatible_apps'];
+ if (!isset($addonType))
+ $addonType = $addon['Addon']['addontype_id'];
+}
+
+$compatible_app_ids = array();
+foreach ($compatible_apps as $var => $val) {
+ $compatible_app_ids[] = $val['Application']['application_id'];
+}
+
+if (!isset($platforms)) {
+ $this->controller->Platform->unbindFully();
+ $platforms = $this->controller->Platform->findAll();
+}
+
+if (!isset($flags)) {
+ $flags = array();
+}
+
+if (!isset($buttonSize)) {
+ $buttonSize = '8x9';
+}
+
+if (!isset($buttonClass)) {
+ $buttonClass = '';
+}
+
+?>
+<?php
+global $browser_apps, $experimental_status, $valid_status;
+
+/* prepare add-on type */
+if (!isset($addonType)) $addonType = ADDON_EXTENSION;
+
+if (!isset($showInstructions)) $showInstructions = true;
+
+/* logged in users can install experimental add-ons */
+$loggedin = $this->controller->Session->check('User');
+
+/* use "latest public file" permalink if this is the latest version. Defaults to false. */
+if (!isset($is_latest)) $is_latest = false;
+
+/* "Install" for browser apps, "Download" for non-browser apps */
+if (!isset($buttonMessage)) {
+ if (!in_array(APP_ID, $browser_apps) || !in_array(APP_ID, $compatible_app_ids)) {
+ $buttonMessage = _('a_download');
+ } else {
+ $buttonMessage = sprintf(_('install_button_text'), APP_PRETTYNAME, "%s");
+ }
+}
+
+
+/* Prepare addon icons */
+if (empty($addonIconPath)) {
+ switch ($addonType) {
+ case ADDON_THEME:
+ $addonIconPath = $html->urlImage(DEFAULT_THEME_ICON);
+ break;
+ default:
+ $addonIconPath = $html->urlImage(DEFAULT_ADDON_ICON);
+ break;
+ }
+}
+
+if (count($addonFiles) < 1) {
+ // This should never happen - this would mean the file didn't exist.
+ echo '<p class="install-button">'._('install_error_addon_not_found').'</p>';
+
+} else {
+
+ // The same add-on can now appear more than once on the same page.
+ // Add a unique id suffix to keep IDs unique.
+ $uniqueId = '-' . dechex(mt_rand());
+
+ $versionId = $addonFiles[0]['version_id'] . $uniqueId;
+
+ echo '<div id="install-'.$versionId.'" class="install install-container">';
+ foreach ($addonFiles as $file) {
+ // never display files with invalid statuses (bug 427176)
+ if (!in_array($file['status'], $valid_status)) continue;
+
+ // Used for echoing values in our loop
+ $_platform_name = '';
+ $_class_platform_string = '';
+ $_install_platform_string = '';
+
+ // ugh...
+ foreach ($platforms as $platform) {
+ // We found a matching platform
+ if ($platform['Platform']['id'] == $file['platform_id']) {
+ $_platform_name = $platform['Translation']['name']['string'];
+ }
+ }
+
+ if (!empty($_platform_name)) {
+ $_class_platform_string = "platform-{$_platform_name}";
+ if ($_platform_name != "ALL") {// special case
+ $_install_platform_string = "($_platform_name)";
+ }
+ }
+
+ // run the right javascript action for the addon type in question
+ $installTriggerName = "installTrigger" . $file['id'] . $uniqueId;
+
+ if ($addonType != ADDON_SEARCH) {
+ /* install for search */
+ if (in_array(APP_ID, $browser_apps)) {
+ // prepare link options for browser apps
+ $linkOptions = array(
+ 'id' => $installTriggerName,
+ 'title' => sprintf(_('install_button_title'), $addonName, APP_PRETTYNAME),
+ 'addonName' => $addonName,
+ 'addonIcon' => $addonIconPath,
+ 'addonHash' => $file['hash'],
+ 'jsInstallMethod' => 'browser_app_addon_install',
+ );
+ } else {
+ // prepare link options for non-browser apps
+ $linkOptions = array('id' => $installTriggerName,
+ 'title'=>sprintf(_('install_download'),$addonName));
+ }
+ } else {
+ /* prepare link options for search engines */
+ $linkOptions = array(
+ 'id' => $installTriggerName,
+ 'title' => sprintf(_('install_button_title'), $addonName, APP_PRETTYNAME),
+ 'engineURL' => FULL_BASE_URL . $html->urlFile($file['id'], $file['filename'], @$collection_uuid),
+ // search engines use a special install method
+ 'jsInstallMethod' => 'search_engine_install',
+ );
+ }
+
+ $linkOptions['class'] = 'button positive ' . $buttonClass;
+ ?>
+
+ <?php
+ $install_button_image = '<img src="'.$html->url(
+ "/img/amo2009/icons/buttons/plus-green-{$buttonSize}.gif", null, false, false
+ ).'" alt="" />';
+ $install_button_html = '';
+ if (empty($addonEULA)) {
+ // wipe disallowed characters off the displayed filename
+ $addon_filename = $html->entities(preg_replace(
+ INVALID_FILENAME_CHARS, '_', $html->unsanitize($file['filename'])));
+
+ // if this is the latest public version, use perma-URL. Otherwise, link directly to file.
+ $linktitle = $install_button_image.'<span class="install-button-text">'.sprintf(_('a_download'),$_install_platform_string).'</span>';
+ if ($is_latest && $file['status'] == STATUS_PUBLIC) {
+ $latest_permalink = "/downloads/latest/{$addonId}";
+ if ($file['platform_id'] != PLATFORM_ALL) $latest_permalink .= "/platform:{$file['platform_id']}";
+
+ $file_id = $this->controller->File->getLatestFileByAddonId($addonId);
+ $file_data = $this->controller->File->findById($file_id);
+ $path_info = pathinfo($file_data['File']['filename']);
+
+ $latest_permalink .= "/addon-${addonId}-latest.".$path_info['extension'];
+
+ if (!empty($collection_uuid)) $latest_permalink .= "?collection_id={$collection_uuid}";
+
+ $install_button_html .= $html->link($linktitle, $latest_permalink, $linkOptions);
+ } else {
+ $install_button_html .= $html->linkFile($file['id'], $linktitle, null,
+ $linkOptions, false, $addon_filename, @$collection_uuid);
+ }
+ } else {
+ $eula_attributes = array('id' => $installTriggerName,
+ 'class' => $linkOptions['class'],
+ 'addonName' => $addonName,
+ 'title' => sprintf(_('install_button_title'), $addonName, APP_PRETTYNAME),
+ 'isEULAPageLink' => 'true');
+
+ $link_url = "/addons/policy/0/{$addonId}/{$file['id']}";
+
+ if (!empty($collection_uuid)) $link_url .= "?collection_id={$collection_uuid}";
+
+ $install_button_html .= $html->link(
+ $install_button_image.'<span class="install-button-text">'.sprintf(_('a_download'),$_install_platform_string).'</span>',
+ $link_url,
+ $eula_attributes, false, false);
+ }
+
+ /**
+ * For logged-in users or public add-ons, show the standard install button.
+ */
+ if ($loggedin || !in_array($file['status'], $experimental_status) || (isset($is_eula_page) && isset($_GET['confirmed']))):
+ ?>
+ <p class="install-button <?=$_class_platform_string?>">
+ <?= $install_button_html ?>
+ </p>
+ <?php
+ /**
+ * For sandbox add-ons, show a frozen version of the standard install button.
+ * Users unfreeze the button client-side by checking a confirmation box.
+ * Non-JS users must unfreeze by logging in.
+ */
+ else:
+ ?>
+ <div class="exp-loggedout">
+ <div class="exp-confirm-install" style="display: none">
+ <div class="exp-desc">
+ <strong class="compatmsg">
+ <input type="checkbox" name="confirm-<?= $addonId ?>" />
+ <?= sprintf(___('install_button_confirm_exp_install'), $html->url('/pages/faq#experimental-addons')) ?>
+ </strong>
+ </div>
+ </div>
+
+ <p class="install-button <?=$_class_platform_string?>" style="display: none">
+ <?= $install_button_html ?>
+ </p>
+
+ <noscript>
+ <p class="install-button <?=$_class_platform_string?>">
+ <?php
+ $login_url = $html->login_url('/'.LANG.'/'.APP_SHORTNAME."/addon/{$addonId}", false);
+ $attributes = array('id' => $installTriggerName,
+ 'addonName' => $addonName,
+ 'title' => sprintf(_('install_button_title'), $addonName, APP_PRETTYNAME));
+ echo $html->link('<span><span><span><strong>'
+ .sprintf(_('a_download'),$_install_platform_string)
+ .'</strong></span></span></span>',
+ $login_url, $attributes, false, false);
+
+ $exp_addon_url = "/pages/faq#experimental-addons";
+ ?>
+ </p>
+ <?= sprintf(___('install_a_login_to_install'), $html->url($login_url), $html->url($exp_addon_url)); ?>
+ </noscript>
+ </div>
+ <?php endif; ?>
+ <script type="text/javascript">
+ installVersusDownloadCheck("<?=$installTriggerName?>", "<?=sprintf($buttonMessage, $_install_platform_string) ?>", "<?=sprintf(_('a_download'), $_install_platform_string)?>");
+ </script>
+ <?php
+ }
+ ?>
+
+ <?php if (in_array('recommended', $flags)) { ?>
+ <strong><?=___('addon_listitem_flag_recommended')?></strong>
+ <?php } else if (in_array('experimental', $flags) && $loggedin) { ?>
+ <strong><?=_('addon_listitem_flag_experimental')?></strong>
+ <?php }
+
+ // If we're looking at thunderbird pages, and there is no EULA, show the TB
+ // install instructions. Bug 401272 fixed the button so it downloads instead of
+ // installs, but it doesn't hurt to have these instructions still.
+ if (empty($addonEULA) && $showInstructions && (APP_ID == APP_THUNDERBIRD || APP_ID == APP_SUNBIRD)):
+ $installPopupName = "install-popup-" . $versionId;
+ if (APP_ID == APP_THUNDERBIRD):
+ $installTitle = _('addons_install_in_thunderbird_title');
+ $installBody = _('addons_install_in_thunderbird');
+ elseif (APP_ID == APP_SUNBIRD):
+ $installTitle = _('addons_install_in_sunbird_title');
+ $installBody = _('addons_install_in_sunbird');
+ endif;
+ ?>
+ <div class="app_install">
+ <div id="<?= $installPopupName ?>" class="app_install-popup-container">
+ <div class="app_install-popup">
+ <div class="app_install-popup-inner">
+ <h3><?= $installTitle ?></h3>
+ <?= $installBody ?>
+ </div>
+ </div>
+ </div>
+ </div>
+
+ <script type="text/javascript">
+ <?php
+ foreach ($addonFiles as $file):
+ $installTriggerName = "installTrigger" . $file['id'] . $uniqueId;
+ ?>
+ initDownloadPopup("<?=$installTriggerName?>", "<?=$installPopupName?>");
+ <?php
+ endforeach;
+ ?>
+ </script>
+ <?php
+ endif;
+ ?>
+ </div>
+
+ <?php
+ // Show platform-specific install buttons only, except on version history page
+ $versionsPage = ($this->name == 'Addons' && $this->action == 'versions');
+ echo '<script type="text/javascript">'.
+ 'setTimeout(function() {';
+ echo "initExpConfirm('{$versionId}');";
+ if (!$versionsPage) {
+ echo "fixPlatformLinks('{$versionId}', document.getElementById('{$installTriggerName}').getAttribute('addonName'));";
+ }
+
+ // show add-on compatibility hints for Firefox
+ if (APP_ID == APP_FIREFOX && !empty($compatible_apps)) {
+ $fromVer = $toVer = null;
+ foreach ($compatible_apps as $app) {
+ if ($app['Application']['application_id'] == APP_FIREFOX) {
+ $fromVer = $app['Min_Version']['version'];
+ $toVer = $app['Max_Version']['version'];
+ }
+ }
+ if ($fromVer && $toVer) {
+ if (!$versionsPage) {
+ // show "ignore" link for logged in users only
+ $_loggedin = $this->controller->Session->check('User');
+ echo "addCompatibilityHints('{$addonId}', '{$versionId}', "
+ ."'{$fromVer}', '{$toVer}', '{$_loggedin}');";
+ } else {
+ // allow determining latest compatible version for version history page
+ echo "addons_history.addVersion('{$versionId}','{$fromVer}','{$toVer}');";
+ }
+ }
+
+ }
+ echo "},0);".
+ '</script>';
+ ?>
+
+<?php
+}
+?>
diff --git a/site/app/views/elements/amo2009/pagination.thtml b/site/app/views/elements/amo2009/pagination.thtml
new file mode 100644
index 0000000..dd03402
--- /dev/null
+++ b/site/app/views/elements/amo2009/pagination.thtml
@@ -0,0 +1,51 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Jeff Balogh <jbalogh@mozilla.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+ ?>
+
+<?php if($pagination->setPaging($paging)):
+ $prev = $pagination->prevPage(___('amo2009_pagination_previous_page'), false);
+ $next = $pagination->nextPage(___('amo2009_pagination_next_page'), false);
+ $pages = $pagination->pageNumbers();
+?>
+ <ol class="pagination">
+ <li><?=$prev?></li>
+ <?=$pages?>
+ <li><?=$next?></li>
+ </ol>
+ <!-- TODO: per page -->
+<?php endif; ?>
diff --git a/site/app/views/elements/amo2009/reviews.thtml b/site/app/views/elements/amo2009/reviews.thtml
new file mode 100644
index 0000000..65c9599
--- /dev/null
+++ b/site/app/views/elements/amo2009/reviews.thtml
@@ -0,0 +1,55 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Jeff Balogh <jbalogh@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/**
+ * Required:
+ * $addon: an Addon object
+ */
+
+$rating = $addon['Addon']['averagerating'];
+$reviews = $addon['Addon']['totalreviews'];
+$addon_id = $addon['Addon']['id'];
+?>
+
+<?=$this->renderElement('amo2009/stars',array('rating' => $rating))?>
+<?php if ($reviews > 0): ?>
+ <a href="<?=$html->url('/addon/'.$addon_id.'#reviews')?>">
+ <?=sprintf(n___('feature_reviews', 'feature_reviews', $reviews),
+ '<strong>'.$reviews.'</strong>')?>
+ </a>
+<?php endif; ?>
diff --git a/site/app/views/elements/amo2009/search.thtml b/site/app/views/elements/amo2009/search.thtml
new file mode 100644
index 0000000..1596895
--- /dev/null
+++ b/site/app/views/elements/amo2009/search.thtml
@@ -0,0 +1,414 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Mike Morgan <morgamic@mozilla.com> (Original Author)
+ * Cameron Roy <licensing@justcameron.com>
+ * Frederic Wenzel <fwenzel@mozilla.com>
+ * Chris Pollett <cpollett@gmail.com>
+ * l.m.orchard <lorchard@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+?>
+<?php
+/**
+ * This element uses the following local variables:
+ * $query: query string to be displayed in the text box, defaults to "search for add-ons"
+ * $category: category ID to be selected
+ */
+
+// set-up arrays for advance search select tags
+// also set-up default values (or use previous search params) for each advance-search field
+global $app_shortnames, $app_prettynames;
+$applications = array();
+foreach ($app_shortnames as $name => $key) {
+ $applications[$key] = $app_prettynames[$name];
+}
+if (!isset($appid)) {
+ $appid = APP_ID;
+}
+
+$min_display_version_by_app = array( // eventually this information should be kept in DB
+ APP_FIREFOX => "1.0",
+ APP_THUNDERBIRD => "1.0",
+ APP_SEAMONKEY => "1.0",
+ APP_SUNBIRD => "0.2"
+);
+
+$new_versions = array();
+foreach ($app_shortnames as $n => $k) {
+// AmoVersions is from controller->beforeRender()
+ if (!empty($AmoVersions[$k])) foreach ($AmoVersions[$k] as $version) {
+ $versions_parts = explode(".", $version);
+ $second_part = (isset($versions_parts[1])) ? ".".intval($versions_parts[1]) : "";
+ if (!isset($min_display_version_by_app[$k])
+ || $min_display_version_by_app[$k] <= $versions_parts[0].$second_part ) {
+
+ if ($k != APP_FIREFOX || !in_array($versions_parts[0].$second_part, array('1.4','3.1'))) { // yuck. Baz didn't like FF 1.4. Nick didn't like FF 3.1.
+ $new_versions[$k][] = $versions_parts[0].$second_part;
+ }
+ }
+ }
+ if (!empty($new_versions[$k]))
+ $new_versions[$k] = array_unique($new_versions[$k]);
+}
+$versions = $new_versions;
+
+if(!isset($lver)) {
+ $lver = "";
+}
+
+if(!isset($hver)) {
+ $hver = "";
+}
+
+// AmoPlatforms is from controller->beforeRender()
+array_shift($AmoPlatforms); // get rid of PLATFORM_ALL
+$platforms = array_merge(array(PLATFORM_ANY => ___('advanced_search_form_any_type')), $AmoPlatforms); //add semantically happy PLATFORM_ANY
+$pid = 0;
+if (isset($this->params['url']['pid'])
+ && in_array($this->params['url']['pid'], array_keys($platforms))) {
+
+ $pid = $this->params['url']['pid'];
+}
+
+// AmoAddonTypes is from controller->beforeRender()
+// for now we want to get rid of Plugin and Language packs since the former
+// goes to a static page and the latter is empty
+array_pop($AmoAddonTypes);
+array_pop($AmoAddonTypes);
+$addon_types = array_merge(array(ADDON_ANY => ___('advanced_search_form_any_type')), $AmoAddonTypes);
+if (!isset($atype)) {
+ $atype = ADDON_ANY;
+}
+
+$page_arr = $this->controller->Pagination->resultsPerPage;
+$pages = array();
+foreach ($page_arr as $page) {
+ $pages[$page] = $page;
+}
+
+if (!isset($pp)) {
+ $pp = $this->controller->Pagination->show;
+}
+
+$updates = array(
+ "" => ___('advanced_search_form_any_time'),
+ '- INTERVAL 1 DAY' => ___('advanced_search_form_past_day'),
+ '- INTERVAL 1 WEEK' => ___('advanced_search_form_past_week'),
+ '- INTERVAL 1 MONTH' => ___('advanced_search_form_past_month'),
+ '- INTERVAL 3 MONTH' => ___('advanced_search_form_past_3_months'),
+ '- INTERVAL 6 MONTH' => ___('advanced_search_form_past_6_months'),
+ '- INTERVAL 1 YEAR' => ___('advanced_search_form_past_year')
+);
+
+$lup = "";
+if (isset($this->params['url']['lup'])
+ && in_array($this->params['url']['lup'], array_keys($updates))) {
+
+ $lup = $this->params['url']['lup'];
+}
+
+$sort_orders = array(
+ '' => ___('advanced_search_form_keyword_match'),
+ 'newest' => ___('advanced_search_form_newest'),
+ 'name' => ___('advanced_search_form_name'),
+ 'averagerating' => ___('advanced_search_form_rating'),
+ 'weeklydownloads' => ___('advanced_search_form_popularity')
+);
+if (!isset($sort)) {
+ $sort = "";
+}
+
+
+// handles toggling advanced search form when JS not enabled
+
+$toggle_uri = $_SERVER['REQUEST_URI'];
+
+if (isset($this->params['url']['adv']) || isset($this->params['url']['as'])) {
+ $toggle_uri = str_replace("adv=", "nor=", $toggle_uri);
+ $toggle_uri = str_replace("as=", "nor=", $toggle_uri);
+ $two_form = "";
+} else {
+ $toggle_uri = str_replace("nor=", "adv=", $toggle_uri);
+ $delim = (stristr($toggle_uri,"?")) ? "&" : "?";
+ if(!stristr($toggle_uri, "adv=")) { $toggle_uri .= "{$delim}adv=true"; }
+ $two_form = "</form><form method=\"get\" action=\"\" id=\"hidden-form\" class=\"asclosed\">";
+}
+$toggle_uri = htmlspecialchars($toggle_uri);
+
+// collection search flag
+if (!isset($collectionSearch))
+ $collectionSearch = false;
+
+// prepare query string
+if (!isset($query) || !is_string($query))
+ $query = '';
+
+// prepare selected category, "all" if not set
+if (!isset($category)) $category = array(0, 0);
+?>
+<div class="search-form expanded-search-form">
+ <form method="get" action="<?=$html->url("/search")?>" id="search-form">
+ <div class="basic" id="search-query">
+ <label for="query" class="query-label" title="<?=___('search_form_tooltip')?>"><?=($collectionSearch ? ___('search_form_default_text_collections', 'search for collections') : ___('search_form_default_text'))?></label>
+ <input id="query" type="text" title="search" name="q" value="<?=$query?>" />
+ <label for="cat"><?=___('search_form_within')?></label>
+ <select name="cat" id="cat">
+ <option class="cat-all" value="all"<?=(!$collectionSearch && $category[0]==0 ? ' selected="selected"' : '')?>><?=_('search_form_all_addons')?></option>
+
+ <?php foreach ($AmoTags as $tag): ?>
+ <?php
+ // skip "plugins" as it is a static page at the moment and thus
+ // cannot be searched here
+ if ($tag['type'] == ADDON_PLUGIN) continue;
+
+ if ($category[0] == $tag['type'] && ($category[1]==$tag['cat'] || $tag['cat']==0))
+ $sel = ' selected="selected"';
+ else
+ $sel = '';
+ ?>
+ <option value="<?=$tag['type'].','.$tag['cat']?>"<?=$sel?>><?=$html->entities($tag['name'])?></option>
+ <?php endforeach; ?>
+
+ <option class="cat-all" value="collections"<?=($collectionSearch ? ' selected="selected"' : '')?>><?=___('search_form_all_collections', 'all collections')?></option>
+ </select>
+ <button type="submit"><img src="<?=$html->url('/img/amo2009/blank.gif', null, false, false)?>" alt="<?= ___('search_form_submit_tooltip') ?>"/></button>
+ </div>
+
+ <?=$two_form; ?>
+
+ <div class="advanced" id="advanced-search">
+ <fieldset class="important">
+ <input type="hidden" name="as" value="true" />
+ <input type="hidden" id="vfuz" name="vfuz" value="false" />
+
+ <div class="container application">
+ <label for="appid"><?=___('advanced_search_form_application', 'Application'); ?></label>
+ <?php $html->simpleSelectTag('appid', $applications, $appid, array(), array(), false)?>
+ </div>
+
+ <div class="container">
+ <label for="lver"><?=___('advanced_search_form_version', 'version'); ?></label>
+ <span id="lver-td"><input name="lver" type="text" size="5" maxlength="10" value="<?=$lver ?>" /></span>
+ </div>
+
+ <div class="container">
+ <label for="hver"><?=___('advanced_search_form_to', 'to'); ?></label>
+ <span id="hver-td"><input name="hver" type="text" size="5" maxlength="10" value="<?=$hver ?>" /></span>
+ </div>
+
+ </fieldset>
+
+ <fieldset class="subsidiary">
+ <div class="container">
+ <label for="atype"><?=___('advanced_search_form_type', 'Type'); ?></label>
+ <?php $html->simpleSelectTag('atype', $addon_types, $atype, array(), array(), false); ?>
+ </div>
+ <div class="container">
+ <label for="pp"><?=___('advanced_search_form_perpage', 'Per Page'); ?></label>
+ <?php $html->simpleSelectTag('pp', $pages, $pp, array(), array(), false); ?>
+ </div>
+ <div class="container">
+ <label for="pid"><?=___('advanced_search_form_platform', 'Platform'); ?></label>
+ <?php $html->simpleSelectTag('pid', $platforms, $pid, array(), array(), false); ?>
+ </div>
+ <div class="container">
+ <label for="sort"><?=___('advanced_search_form_sortby', 'Sort By'); ?></label>
+ <?php $html->simpleSelectTag('sort', $sort_orders, $sort, array(), array(), false); ?>
+ </div>
+ <div class="container">
+ <label for="lup"><?=___('advanced_search_form_lastupdate', 'Last Updated'); ?></label>
+ <?php $html->simpleSelectTag('lup', $updates, $lup, array(), array(), false); ?>
+ </div>
+ </fieldset>
+ </div>
+
+ <div id="advanced-link" title="<?=___('advanced_search_form_toggle_tooltip');?>"><a href="?advancedsearch=<?=!$advancedSearch; ?>"><?= ___('advanced_search_form') ?></a></div>
+ </form>
+ <div id="search-bubble-inner"></div>
+
+</div>
+
+<script type="text/javascript">
+// <![CDATA[
+
+<?php
+ echo "versions = new Array();\n";
+ foreach($versions as $application_id => $ver_array) {
+ echo "versions[{$application_id}] = {";
+ foreach ($ver_array as $version) {
+ if($version !="") {
+ echo "\"{$version}\": \"{$version}\", ";
+ }
+ }
+ echo "'".___('advanced_search_form_any_version')."' : 'any' };\n";
+ }
+
+ // to get default version value set up correctly needed to do after $appid, $lver and $hver set-up above in this element
+ // that's why this code is not in mozilla.thtml
+
+ //we re-set these up for the JS case (originally did non-JS case)
+
+ $oldver = $lver;
+ $lver = ($lver == "") ? "'any'" : '"'.$lver.'"' ;
+ $hver = ($hver == "") ? "'any'" : '"'.$hver.'"' ;
+
+ // JS to do browser detection to determine default low range to be current browser if applicable
+?>
+
+ var current_app_id = 0;
+ var uapattern = /Mozilla.*(?:Firefox|Minefield|Shiretoko|GranParadiso|BonEcho|Iceweasel)\/([^\s]*).*$/;
+ var ua = navigator.userAgent;
+ var uamatch = uapattern.exec(ua);
+ if (uamatch != null) {
+ version = uamatch[1].split(".");
+ low_appversion = version[0]+"."+parseInt(version[1]);
+ current_app_id = <?=APP_FIREFOX ?>;
+ }
+
+ uapattern = /Mozilla.*(?:SeaMonkey|Iceape)\/([^\s]*).*$/;
+ ua = navigator.userAgent;
+ uamatch = uapattern.exec(ua);
+ if (uamatch != null) {
+ version = uamatch[1].split(".");
+ low_appversion = version[0]+"."+parseInt(version[1]);
+ current_app_id = <?=APP_SEAMONKEY ?>;
+ }
+
+ default_low = ( ('<?=$oldver ?>' == '-1' || '<?=$oldver?>' == '') && current_app_id == <?=APP_ID; ?>) ? low_appversion : <?=$lver ?>;
+
+ <?php
+ /*
+ Replace the non-JS textfields with select's. Since we only approximately list version names in the dropdown, we want to use fuzzy version
+ matching on server. Add a hidden field to indicate this.
+ */
+ ?>
+
+ $("#lver-td input").remove();
+ $("#hver-td input").remove();
+
+ var verArr = versions[<?= $appid ?>];
+
+ $("#vfuz").val(true);
+
+ var lverSel = document.createElement("select");
+ lverSel.id = "lver";
+ lverSel.name = "lver";
+ $("#lver-td").append(lverSel);
+ replaceOptions("#lver", verArr, default_low);
+
+ var hverSel = document.createElement("select");
+ hverSel.id = "hver";
+ hverSel.name = "hver";
+ $("#hver-td").append(hverSel);
+ replaceOptions("#hver", verArr, <?=$hver ?>);
+
+ $("#appid").change(function () {
+ selected_app_id = $("#appid option:selected").attr("value");
+ default_low = (selected_app_id == current_app_id) ? low_appversion : 'any';
+ verArr = versions[selected_app_id];
+ replaceOptions("#lver", verArr, default_low);
+ replaceOptions("#hver", verArr, 'any');
+ });
+
+ <?php // JS for toggling advanced versus normal search. ?>
+ var adv = $('#advanced-search');
+ var advLink = $('#advanced-link a');
+ advLink.isHidden = true;
+ advLink.attr('href', '#'); // for ie6-7
+ advLink.click(function(e) {
+ if (advLink.isHidden) {
+ adv.appendTo("#search-form");
+ advLink.addClass("asopen");
+ advLink.removeClass("asclosed");
+ advLink.isHidden = false;
+ } else {
+ adv.appendTo("#hidden-form");
+ advLink.addClass("asclosed");
+ advLink.removeClass("asopen");
+ advLink.isHidden = true;
+ }
+ e.preventDefault();
+ return true;
+ });
+
+ <?php
+ // to handle js-less case when a advanced query is sent there is one form,
+ // so have to add back hidden form for js-aware case.
+ if (isset($this->params['url']['as'])): ?>
+ hiddenForm = document.createElement("form");
+ hiddenForm.id = "hidden-form";
+ var searchBubble = document.getElementById("search-bubble-inner");
+ searchBubble.appendChild(hiddenForm);
+ $("#hidden-form").addClass("asclosed");
+ $("#advanced-search").appendTo("#hidden-form");
+ advLink.click();
+ <?php endif; ?>
+
+ $(document).ready(function() {
+ var q = $("#query");
+ var l = $("#search-query label[for=query]");
+ var c = $("#cat");
+ l.show();
+ if ( q.val() == "<?=_('search_form_default_text')?>"){ //initially q is set to search add-ons text for javascriptless browsing
+ q.val('');
+ }
+ if ( q.val() != "") { // if field has any value...
+ l.hide(); // hide the label
+ };
+ l.click(function() { // for browsers with unclickable labels
+ q.focus();
+ });
+ q.focus(function() { // when field gains focus...
+ l.hide(); // hide the label
+ });
+ q.blur(function() { // when field loses focus...
+ if ( q.val() == "" ) { // if field is empty...
+ l.show(); // show the label again, else do nothing (label remains hidden)
+ };
+ });
+ c.change(function() {
+ if (c.val() == "collections") {
+ l.text("<?=___('search_form_default_text_collections', 'search for collections')?>");
+ // most advanced fields do not apply to collection search
+ $('select:not(#appid,#pp),input', $('#advanced-search')).attr('disabled', 'disabled');
+ } else {
+ l.text("<?=_('search_form_default_text')?>");
+ $('select,input', $('#advanced-search')).attr('disabled', '');
+ }
+ });
+ c.change();
+ });
+ // ]]>
+</script>
diff --git a/site/app/views/elements/amo2009/stars.thtml b/site/app/views/elements/amo2009/stars.thtml
new file mode 100644
index 0000000..3c0b4b9
--- /dev/null
+++ b/site/app/views/elements/amo2009/stars.thtml
@@ -0,0 +1,59 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Ryan Doherty <rdoherty@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/**
+ * Required:
+ * $rating: average rating from 0-5
+ */
+if (is_numeric($rating) && $rating > 0) {
+ if ($rating > 5) {
+ $stars = ceil($rating/2);
+ } else {
+ $stars = ceil($rating);
+ }
+ $msg = sprintf(_('stars_rated_x_outof_5'), $stars);
+ ?>
+ <span class="stars stars-<?=$stars?>" title="<?=$msg?>">
+ <?=$msg?>
+ </span>
+ <?php
+} else {
+ ?>
+ <?=_('stars_not_yet_rated')?>
+ <?php
+}
diff --git a/site/app/views/elements/amo2009/teaser_collections.thtml b/site/app/views/elements/amo2009/teaser_collections.thtml
new file mode 100644
index 0000000..783f66f
--- /dev/null
+++ b/site/app/views/elements/amo2009/teaser_collections.thtml
@@ -0,0 +1,122 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * l.m.orchard <lorchard@mozilla.com> (Original Author)
+ * Ryan Doherty <rdoherty@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+?>
+
+<div class="section-teaser featured">
+ <div class="featured-inner">
+ <div class="teaser-header">
+ <ol>
+ <li><a href="#t-introduction"><?=___('addons_home_introduction_name','Introduction')?></a></li>
+ <?php foreach($teaser_collections_categories as $id => $tc): ?>
+ <?php if(isset($teaser_collection_promos[$id])): ?>
+ <li><a href="#t-<?=$tc['title']?>"><?=$tc['title']?></a></li>
+ <?php endif; ?>
+ <?php endforeach ?>
+ </ol>
+ </div>
+ <ol class="teaser-items">
+ <li id="t-introduction">
+ <h2><?=___('addons_home_introduction_header','What are Add-ons?')?></h2>
+
+ <div class="column-wrapper">
+ <div class="first column">
+ <h3><img src="<?=$html->url('/img/amo2009/illustrations/extras.gif', null, false, false)?>" alt="Extras" /></h3>
+ <p><?=___('addons_home_introduction_extras',
+ '<strong>Over 5000 free extras</strong> that let you to customize and extend Firefox to meet your needs.')?></p>
+ </div>
+
+ <div class="column">
+ <h3><img src="<?=$html->url('/img/amo2009/illustrations/themes.gif', null, false, false)?>" alt="Themes" /></h3>
+ <p><?=___('addons_home_introduction_themes',
+ 'Toolbars, themes and search providers that <strong>help you perform common tasks.</strong>')?></p>
+ </div>
+
+ <div class="column">
+ <h3><img src="<?=$html->url('/img/amo2009/illustrations/install.gif', null, false, false)?>" alt="Install" /></h3>
+ <p><?=___('addons_home_introduction_install',
+ '<strong>Easy to install</strong>, get notified when updates are available.')?></p>
+ </div>
+ </div>
+
+ </li>
+
+ <?php foreach($teaser_collections_categories as $id => $tc): ?>
+ <?php if(isset($teaser_collection_promos[$id])): ?>
+ <li id="t-<?=$tc['title']?>" class="addon-view">
+ <h2><?=$tc['tagline']?></h2>
+
+ <?php foreach ($teaser_collection_promos[$id] as $idx=>$addon): ?>
+ <?php if ($idx>=3) break; ?>
+ <? $flags = array($html->byStatus($addon, array('experimental' => 'experimental', 'recommended' => 'recommended', 'default' => 'default'))); ?>
+ <div class="<?=(0==$idx)?'first ':''?>column">
+ <div class="column-inner item <?=join(' ', $flags)?>">
+ <img src="<?=$this->controller->Image->getAddonIconURL($addon['Addon']['id'])?>"
+ alt="<?=$addon['Translation']['name']['string']?>"
+ width="32" height="32" class="icon" />
+ <h3><a title="<?=___('addons_title_tooltip') ?>"
+ href="<?=$html->url("/addon/{$addon['Addon']['id']}")?>"><?=$addon['Translation']['name']['string']?></a></h3>
+ <p><?=$html->truncateChars(80, $addon['Translation']['summary']['string'], true)?></p>
+ <p>
+ <?=$this->renderElement('amo2009/install', array(
+ 'flags' => $flags,
+ 'addon' => $addon
+ ))?>
+ </p>
+ </div>
+ </div>
+ <?php endforeach ?>
+
+ <?php if (!empty($promoted_collections[$id]['Collection']['uuid'])): ?>
+ <?php $collection = $promoted_collections[$id];?>
+ <p class="lead"><?=sprintf(
+ ___('addons_home_introduction_collection_link',
+ 'Like these? Find more add-ons in %1$s.'),
+ $link->collection(array(
+ 'Collection' => array('uuid'=>$collection['Collection']['uuid'], 'nickname'=>$collection['Collection']['nickname']),
+ 'Translation' => array('name'=>array('string'=>$collection['Translation']['name']['string']))
+ ))
+ )?></p>
+ <?php endif; ?>
+ </li>
+ <?php endif; ?>
+ <?php endforeach ?>
+
+ </ol>
+ </div>
+</div>
diff --git a/site/app/views/elements/app_chooser.thtml b/site/app/views/elements/app_chooser.thtml
new file mode 100644
index 0000000..f1cb175
--- /dev/null
+++ b/site/app/views/elements/app_chooser.thtml
@@ -0,0 +1,54 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Frederic Wenzel <fwenzel@mozilla.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+global $app_shortnames, $app_prettynames;
+$applist = array();
+foreach (array_keys($app_shortnames) as $_app) {
+ // pulling fennec from app_chooser until it has proper support for the web site
+ if ($app_shortnames[$_app] == APP_ID || $app_shortnames[$_app] == APP_FENNEC) continue; // don't show current app or fennec
+ $applist[] = '<li id="app-'.$_app.'"><a href="'.$html->url("/$_app/",false,true,false).'">'.$app_prettynames[$_app].'</a></li>';
+}
+?>
+<div id="other-apps" class="highlight" title="<?=___('other_apps_tooltip');?>">
+ <h3><?=_('addons_home_other_applications')?></h3>
+ <ul id="nav-apps">
+ <?php foreach ($applist as $_app): ?>
+ <?=$_app?>
+ <?php endforeach; ?>
+ </ul>
+</div>
diff --git a/site/app/views/elements/app_compatibility.thtml b/site/app/views/elements/app_compatibility.thtml
new file mode 100644
index 0000000..d47ffd5
--- /dev/null
+++ b/site/app/views/elements/app_compatibility.thtml
@@ -0,0 +1,61 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Frederic Wenzel <fwenzel@mozilla.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+
+/**
+ * This element uses the following local variables:
+ * - compatible_apps array provided by Version->getCompatibleApps
+ */
+
+global $app_prettynames, $app_shortnames;
+
+?>
+<div class="app_compat">
+ <h5><?=_('addons_display_workswith')?></h5>
+ <ul>
+ <?
+ foreach($compatible_apps as $app):
+ $shortname = array_search($app['Application']['application_id'], $app_shortnames);
+ ?>
+ <li>
+ <?=$app_prettynames[$shortname]?>:
+ <?=$app['Min_Version']['version']?> &ndash; <?=$app['Max_Version']['version']?>
+ </li>
+ <? endforeach; ?>
+ </ul>
+</div>
diff --git a/site/app/views/elements/categories.thtml b/site/app/views/elements/categories.thtml
new file mode 100644
index 0000000..e7cbd53
--- /dev/null
+++ b/site/app/views/elements/categories.thtml
@@ -0,0 +1,99 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Mike Morgan <morgamic@mozilla.com> (Original Developer)
+ * Frederic Wenzel <fwenzel@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/**
+ * This element uses the following local variables:
+ * - $highlight: category to be highlighted. Format: array(addontype_id, cat_id)
+ * a cat_id of 0 means "no sub-category"=global landing page.
+ */
+
+global $hybrid_categories;
+?>
+
+<div id="categories">
+ <h3 title="<?=_('categories_header_title')?>"><span><?=_('categories_header')?></span></h3>
+
+ <?php
+ if (isset($highlight) && !empty($highlight)) {
+ // find current category in category list
+ $highlight_cat = array();
+ foreach ($AmoTags as $_tag) {
+ if ($_tag['type'] == $highlight[0] &&
+ ($_tag['cat'] == $highlight[1] || $_tag['cat'] == 0)) {
+ $highlight_cat = $_tag;
+ break;
+ }
+ }
+
+ // if found, show top-level category highlight
+ if (!empty($highlight_cat)) {
+
+ echo "<p>";
+ $_url = "/browse/type:{$highlight_cat['type']}";
+ if ($highlight_cat['cat'] != 0) // category not empty
+ $_url .= "/cat:{$highlight_cat['cat']}";
+
+ echo $html->link($highlight_cat['name'], $_url,
+ array('title'=>_('categories_current_title')));
+
+ // when appropriate, show sub-category
+ if ($highlight_cat['cat'] == 0 && $highlight[1] != 0
+ && isset($this_tag)) {
+ echo "<br/>&lfloor;&nbsp;"; // sub-category marker
+
+ echo $html->link($this_tag['Translation']['name']['string'],
+ $_url."/cat:{$this_tag['Tag']['id']}",
+ array('title'=>_('categories_current_title')));
+ }
+ echo "</p>";
+ }
+
+ }
+ ?>
+
+ <ul id='cat-list'>
+ <?php
+
+ foreach ($AmoTags as $_tag) {
+ $_url = "/browse/type:{$_tag['type']}".($_tag['cat']!=0 ? "/cat:{$_tag['cat']}" : '');
+ echo '<li>'.$html->link($html->entities($_tag['name']), $_url)."</li>\n";
+ }
+ ?>
+ </ul>
+</div>
diff --git a/site/app/views/elements/collections_install_item.thtml b/site/app/views/elements/collections_install_item.thtml
new file mode 100644
index 0000000..f7a91b5
--- /dev/null
+++ b/site/app/views/elements/collections_install_item.thtml
@@ -0,0 +1,87 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Frederic Wenzel <fwenzel@mozilla.com> (Original Author)
+ * Wil Clouser <clouserw@mozilla.com>
+ * Mike Shaver <shaver@mozilla.com>
+ * Mike Morgan <morgamic@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/**
+ * This element uses the following local variables:
+ * - $addon (Addon model-style array, containing 'Addon' and
+ * (optionally) 'Version', 'File', 'Tag' sub-arrays)
+ * - $addonIconPath (optional)
+ * - $addonPreviewPath (optional)
+ */
+
+$addonID = $addon['Addon']['id'];
+$addonName = $addon['Translation']['name']['string'];
+$addonEULA = $addon['Translation']['eula']['string'];
+$hasEULA = (!empty($addonEULA));
+
+// prepare icon
+if (isset($addonIconPath) && !empty($addonIconPath))
+ $icon = '<img src="'.$addonIconPath.'" class="icon" alt=""/>';
+else
+ $icon = '';
+
+?>
+
+<li class="list-addon inst-addon <?=($hasEULA?'eula':'noeula')?>" id="addon-<?=$addonID?>">
+ <?=$icon?>
+ <div class="desc">
+ <h4><?=$addonName?></h4>
+<?php
+ // display filename for each platform
+ foreach ($addon['File'] as $file) {
+ if (!($_platform_name = $platforms[$file['platform_id']])) continue;
+ $_class_platform_string = "platform-{$_platform_name}";
+ echo '<p class="'.$_class_platform_string.'">'.$html->urlFile($file['id'], $file['filename'])."</p>\n";
+ echo '<input class="'.$_class_platform_string.'" type="hidden" name="hash" value="'.$file['hash'].'"/>'."\n";
+ }
+?>
+ </div>
+ <div class="add-button">
+ <input id="inst-check-<?=$addonID?>" type="checkbox" value="<?=$addonID?>" name="addon[]" class="install <?=($addon['Addon']['signed_xpi']?'signed':'unsigned')?>"/>
+ <label class="add" for="inst-check-<?=$addonID?>">Include in install</label>
+ </div>
+ <div class="eula" style="display:none">
+ <p><strong><?=$addonName?>:</strong> <a href="#" onclick="$('#addon-<?=$addonID?> .eula-text').toggle();return false;">Read License Agreement</a></p>
+ <p class="eula-text" style="display:none"><?=nl2br($addonEULA)?></p>
+ <input type="radio" name="eula-<?=$addonID?>" id="eula-yes-<?=$addonID?>" value="yes" checked/> <label for="eula-yes-<?=$addonID?>">I accept the terms of the license agreement.</label><br/>
+ <input type="radio" name="eula-<?=$addonID?>" id="eula-no-<?=$addonID?>" value="no"/> <label for="eula-no-<?=$addonID?>">I do NOT accept the terms of the license agreement.</label>
+ </div>
+</li>
diff --git a/site/app/views/elements/collections_interactive_addon.thtml b/site/app/views/elements/collections_interactive_addon.thtml
new file mode 100644
index 0000000..eb8edbb
--- /dev/null
+++ b/site/app/views/elements/collections_interactive_addon.thtml
@@ -0,0 +1,100 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Frederic Wenzel <fwenzel@mozilla.com> (Original Author)
+ * Wil Clouser <clouserw@mozilla.com>
+ * Mike Shaver <shaver@mozilla.com>
+ * Mike Morgan <morgamic@mozilla.com>
+ * Ryan Doherty <rdoherty@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/**
+ * This element uses the following local variables:
+ * - $addon (Addon model-style array, containing 'Addon' and
+ * (optionally) 'Version', 'File', 'Tag' sub-arrays)
+ * - $addonIconPath (optional)
+ * - $addonPreviewPath (optional)
+ */
+
+$addonID = $addon['Addon']['id'];
+$addonName = $addon['Translation']['name']['string'];
+$addonSummary = $addon['Translation']['summary']['string'];
+
+if(isset($showDate) && $showDate == true) {
+ $addonDateAdded = $addon['Addon']['dateadded'];
+}
+
+
+// prepare preview image
+if (isset($addonPreviewPath) && !empty($addonPreviewPath)) {
+ $_alt = sprintf(_('img_preview_of'),$addonName);
+ $previmg = '<img src="'.$addonPreviewPath.'" '
+ .'alt="'.$_alt.'" title="'.$_alt.'"/>';
+ $previmg = '<div class="preview-img">'
+ .$html->link($previmg, "/addon/{$addonID}").'</div>';
+} else
+ $previmg = '';
+// prepare icon
+if (isset($addonIconPath) && !empty($addonIconPath))
+ $icon = '<img src="'.$addonIconPath.'" class="icon" alt=""/>';
+else
+ $icon = '';
+
+// prepare summary
+if (!isset($addonSummary) || empty($addonSummary))
+ $addonSummary = '&nbsp;';
+?>
+
+<li class="list-addon coll-addon" id="coll-addon-<?=$addonID?>">
+ <?=$previmg?>
+ <div class="item-desc">
+ <h4><?=$html->link("$icon <span>$addonName</span>", "/addon/{$addonID}");?></h4>
+ <?php if(isset($showDate) && $showDate == true){ ?>
+ <p class="date-added"><?php echo sprintf(_('collections_interactive_addon_added'), strftime(_('date'), strtotime($addonDateAdded))); ?></p>
+ <?php } ?>
+
+ <p class="desc"><?=$addonSummary?> <?=$html->link('Learn more...', "/addon/{$addonID}")?></p>
+
+ <div class="add-button">
+ <input id="check-<?=$addonID?>" type="checkbox" value="<?=$addonID?>" name="addon[]" class="want"/>
+ <label class="add" for="check-<?=$addonID?>">I want this add-on!</label>
+ <p style="display:none"><a href="http://firefox.com" target="_blank">Upgrade to Firefox 3</a> to use this add-on.</p>
+ </div>
+ <div id="done-<?=$addonID?>" class="done-box">
+ Done choosing add-ons?<br/>
+ <a href="#installsubmit" class="installlink">Click here to install them.</a>
+ </div>
+ </div>
+</li>
diff --git a/site/app/views/elements/developers/actionbar.thtml b/site/app/views/elements/developers/actionbar.thtml
new file mode 100644
index 0000000..0420f06
--- /dev/null
+++ b/site/app/views/elements/developers/actionbar.thtml
@@ -0,0 +1,54 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Justin Scott <fligtar@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+?>
+<div class="action-bar actionbar <?=(!empty($disabled) && $disabled == 1 ? 'inactive' : 'active')?>">
+ <ul>
+ <?php if (!empty($revamp) && $revamp === true): ?>
+ <li class="edit"><a href="<?=$html->url('/developers/addon/edit/'.$addon_id)?>" class="view"><?=_('devcp_actionbar_link_edit')?></a></li>
+ <li class="status"><a href="<?=$html->url('/developers/addon/status/'.$addon_id)?>" class="view">Change Status</a></li>
+ <li class="statistics"><a href="<?=$html->url('/statistics/addon/'.$addon_id)?>" class="view"><?=_('devcp_actionbar_link_stats')?></a></li>
+ <li class="versions"><a href="<?=$html->url('/developers/versions/'.$addon_id)?>" class="view">Versions and Files</a></li>
+ <?php else: ?>
+ <li class="details active-only"><a href="<?=$html->url('/developers/details/'.$addon_id)?>" class="view"><?=_('devcp_actionbar_link_details')?></a></li>
+ <li class="displaypage active-only"><a href="<?=$html->url('/addon/'.$addon_id)?>" class="view">View Listing</a></li>
+ <li class="statistics"><a href="<?=$html->url('/statistics/addon/'.$addon_id)?>" class="view"><?=_('devcp_actionbar_link_stats')?></a></li>
+ <li class="edit"><a href="<?=$html->url('/developers/edit/'.$addon_id)?>" class="view"><?=_('devcp_actionbar_link_edit')?></a></li>
+ <li class="versions-add active-only"><a href="<?=$html->url('/developers/add/'.$addon_id)?>" class="view"><?=_('devcp_actionbar_link_newversion')?></a></li>
+ <?php endif; ?>
+ </ul>
+</div>
diff --git a/site/app/views/elements/developers/additem.thtml b/site/app/views/elements/developers/additem.thtml
new file mode 100644
index 0000000..95451ca
--- /dev/null
+++ b/site/app/views/elements/developers/additem.thtml
@@ -0,0 +1,80 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * Justin Scott <fligtar@gmail.com>.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Frederic Wenzel <fwenzel@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+?>
+<div id="sidebar">
+ <div id="categories">
+ <h3><span><?=_('devcp_additem_sidebar_title')?></span></h3>
+
+ <ul id="cat-list">
+<?php
+ $items = array(
+ 1 => _('devcp_additem_step1_link'),
+ 2 => _('devcp_additem_step2_link'),
+ 3 => _('devcp_additem_step3_link'),
+ 4 => _('devcp_additem_step4_link'),
+ 5 => _('devcp_additem_step5_link')
+ );
+ if ($newAddon == true) {
+ $items[0] = _('devcp_additem_step0_newlink');
+ ksort($items);
+ }
+ foreach ($items as $number => $item) {
+ echo '<li';
+ if ($step == $number) {
+ if (!empty($errors['main'])) {
+ echo ' class="error"';
+ }
+ else {
+ echo ' class="selected"';
+ }
+ }
+ echo '><span>'.$item.'</span></li>';
+ }
+?>
+ </ul>
+
+ </div>
+
+<?php
+ if ($step > 0 && $step < 5) {
+ echo '<div id="submissionHelp">';
+ echo $html->link(_('devcp_additem_submissionhelp_link'), '/pages/submissionhelp#step'.$step, array('target' => '_blank', 'title' => _('devcp_additem_linktitle_opensin_newwindow')));
+ echo '</div>';
+ }
+?>
+</div>
diff --git a/site/app/views/elements/developers/addonheader.thtml b/site/app/views/elements/developers/addonheader.thtml
new file mode 100644
index 0000000..65702df
--- /dev/null
+++ b/site/app/views/elements/developers/addonheader.thtml
@@ -0,0 +1,46 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Justin Scott <fligtar@mozilla.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+$addonIconPath = $this->controller->Image->getAddonIconURL($addon_id);
+
+echo '<h1>';
+echo '<img src="'.$addonIconPath.'" style="vertical-align: middle; padding-right: 5px;" alt="" />';
+echo $title;
+echo '</h1>';
+
+?> \ No newline at end of file
diff --git a/site/app/views/elements/developers/adminmenu.thtml b/site/app/views/elements/developers/adminmenu.thtml
new file mode 100644
index 0000000..5208464
--- /dev/null
+++ b/site/app/views/elements/developers/adminmenu.thtml
@@ -0,0 +1,97 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * Justin Scott <fligtar@gmail.com>.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+?>
+<div id="sidebar">
+ <div id="categories">
+ <h3><span>Admin Tools</span></h3>
+
+ <ul id="cat-list">
+ <li<?=($page == 'summary') ? ' class="selected"' : ''?>><?=$html->link('Admin Summary', '/admin/summary')?></li>
+ <?php if ($this->controller->SimpleAcl->actionAllowed('Admin', 'addons', $this->controller->Session->read('User'))): ?>
+ <li<?=($page == 'addons') ? ' class="selected"' : ''?>><?=$html->link('Add-on Manager', '/admin/addons')?></li>
+ <?php endif;
+ if ($this->controller->SimpleAcl->actionAllowed('Admin', 'applications', $this->controller->Session->read('User'))): ?>
+ <li<?=($page == 'applications') ? ' class="selected"' : ''?>><?=$html->link('Application Manager', '/admin/applications')?></li>
+ <?php endif;
+ if ($this->controller->SimpleAcl->actionAllowed('Admin', 'collections', $this->controller->Session->read('User'))): ?>
+ <li<?=($page == 'collections') ? ' class="selected"' : ''?>><?=$html->link('Collections Manager', '/admin/collections')?></li>
+ <?php endif;
+ if ($this->controller->SimpleAcl->actionAllowed('Editors', '%', $this->controller->Session->read('User'))): ?>
+ <li><?=$html->link('Editor Tools', '/editors')?></li>
+ <?php endif;
+ if ($this->controller->SimpleAcl->actionAllowed('Admin', 'features', $this->controller->Session->read('User'))): ?>
+ <li<?=($page == 'features') ? ' class="selected"' : ''?>><?=$html->link('Feature Manager', '/admin/features')?></li>
+ <?php endif;
+ if ($this->controller->SimpleAcl->actionAllowed('Admin', 'flagged', $this->controller->Session->read('User'))): ?>
+ <li<?=($page == 'flagged') ? ' class="selected"' : ''?>><?=$html->link("Flagged Add-ons ({$flaggedCount})", '/admin/flagged')?></li>
+ <?php endif;
+ if ($this->controller->SimpleAcl->actionAllowed('Admin', 'groups', $this->controller->Session->read('User'))): ?>
+ <li<?=($page == 'groups') ? ' class="selected"' : ''?>><?=$html->link('Group Manager', '/admin/groups')?></li>
+ <?php endif;
+ if ($this->controller->SimpleAcl->actionAllowed('Admin', 'lists', $this->controller->Session->read('User'))): ?>
+ <li<?=($page == 'lists' && empty($subpage)) ? ' class="selected"' : ''?>><?=$html->link('List Manager', '/admin/lists')?></li>
+ <?php if ($page == 'lists'): ?>
+ <li class="indented<?=($subpage == 'tags') ? ' selected' : ''?>"><?=$html->link('Categories', '/admin/tags')?></li>
+ <li class="indented<?=($subpage == 'platforms') ? ' selected' : ''?>"><?=$html->link('Platforms', '/admin/platforms')?></li>
+ <li class="indented<?=($subpage == 'responses') ? ' selected' : ''?>"><?=$html->link('Responses', '/admin/responses')?></li>
+ <?php endif; ?>
+ <?php endif;
+ if ($this->controller->SimpleAcl->actionAllowed('Localizers', '%', $this->controller->Session->read('User'))): ?>
+ <li><?=$html->link('Localizer Tools', '/localizers')?></li>
+ <?php endif;
+ if ($this->controller->SimpleAcl->actionAllowed('Admin', 'logs', $this->controller->Session->read('User'))): ?>
+ <li<?=($page == 'logs') ? ' class="selected"' : ''?>><?=$html->link('Log Viewer', '/admin/logs')?></li>
+ <?php endif;
+ if ($this->controller->SimpleAcl->actionAllowed('Admin', 'serverstatus', $this->controller->Session->read('User'))): ?>
+ <li<?=($page == 'serverstatus') ? ' class="selected"' : ''?>><?=$html->link('Server Status', '/admin/serverstatus')?></li>
+ <?php endif;
+ if ($this->controller->SimpleAcl->actionAllowed('Admin', 'config', $this->controller->Session->read('User'))): ?>
+ <li<?=($page == 'config') ? ' class="selected"' : ''?>><?=$html->link('Site Config', '/admin/config')?></li>
+ <?php endif;
+ if ($this->controller->SimpleAcl->actionAllowed('Admin', 'variables', $this->controller->Session->read('User'))): ?>
+ <li<?=($page == 'variables') ? ' class="selected"' : ''?>><?=$html->link('Site Variables', '/admin/variables')?></li>
+ <?php endif;
+ if ($this->controller->SimpleAcl->actionAllowed('Admin', 'ViewAnyStats', $this->controller->Session->read('User'))): ?>
+ <li><?=$html->link('Statistics Dashboard', '/statistics')?></li>
+ <?php endif;
+ if ($this->controller->SimpleAcl->actionAllowed('Admin', 'users', $this->controller->Session->read('User'))): ?>
+ <li<?=($page == 'users') ? ' class="selected"' : ''?>><?=$html->link('User Manager', '/admin/users')?></li>
+ <?php endif; ?>
+ <li><?=$html->link('Back to Main', '/')?></li>
+ </ul>
+ </div>
+</div>
diff --git a/site/app/views/elements/developers/editbox.thtml b/site/app/views/elements/developers/editbox.thtml
new file mode 100644
index 0000000..530bab1
--- /dev/null
+++ b/site/app/views/elements/developers/editbox.thtml
@@ -0,0 +1,62 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Justin Scott <fligtar@mozilla.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+?>
+<div class="pitch">
+ <h4><?=$html->link($addon_name, '/developers/dashboard#addon-'.$addon_id)?></h4>
+ <ul class="actionbar">
+ <li class="displaypage"><?=$html->link(___('devcp_editbox_view_listing'), "/addon/{$addon_id}/")?></li>
+ <li class="edit<?=($action == 'edit' ? ' selected' : '')?>"><?=$html->link(___('devcp_editbox_edit_addon'), "/developers/addon/edit/{$addon_id}/")?></li>
+ <?php if ($action == 'edit'): ?>
+ <li class="container"><ul>
+ <li class="edit-authors<?=($subaction == 'authors' ? ' selected' : '')?>"><?=$html->link(___('devcp_editbox_authors'), "/developers/addon/edit/{$addon_id}/authors")?></li>
+ <li class="edit-categories<?=($subaction == 'categories' ? ' selected' : '')?>"><?=$html->link(___('devcp_editbox_categories'), "/developers/addon/edit/{$addon_id}/categories")?></li>
+ <li class="edit-descriptions<?=($subaction == 'descriptions' ? ' selected' : '')?>"><?=$html->link(___('devcp_editbox_descriptions'), "/developers/addon/edit/{$addon_id}/descriptions")?></li>
+ <li class="edit-properties<?=($subaction == 'properties' ? ' selected' : '')?>"><?=$html->link(___('devcp_editbox_properties'), "/developers/addon/edit/{$addon_id}/properties")?></li>
+ </ul></li>
+ <?php endif; ?>
+ <li class="status<?=($action == 'status' ? ' selected' : '')?>"><?=$html->link(___('devcp_editbox_change_status'), "/developers/addon/status/{$addon_id}/")?></li>
+ <li class="statistics"><?=$html->link(___('devcp_editbox_statistics_dashboard'), "/statistics/addon/{$addon_id}/")?></li>
+ <li class="versions<?=($action == 'versions' ? ' selected' : '')?>"><?=$html->link(___('devcp_editbox_versions'), "/developers/versions/{$addon_id}/")?></li>
+ <?php if ($action == 'versions'): ?>
+ <li class="container"><ul>
+ <li class="versions-add<?=($subaction == 'add' ? ' selected' : '')?>"><?=$html->link(___('devcp_editbox_new_version'), "/developers/versions/add/{$addon_id}")?></li>
+ </ul></li>
+ <?php endif; ?>
+ <li class="previews<?=($action == 'previews' ? ' selected' : '')?>"><?=$html->link(___('devcp_editbox_screenshots'), "/developers/previews/{$addon_id}/")?></li>
+ </ul>
+</div> \ No newline at end of file
diff --git a/site/app/views/elements/developers/editors_review_history_item.thtml b/site/app/views/elements/developers/editors_review_history_item.thtml
new file mode 100644
index 0000000..349ab62
--- /dev/null
+++ b/site/app/views/elements/developers/editors_review_history_item.thtml
@@ -0,0 +1,101 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * Frederic Wenzel <fwenzel@mozilla.com>.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/**
+ * This element uses the following local variables:
+ * - $hist -- review history item
+ */
+if (!empty($hist['Approval']['reply_to']))
+ $trclass="class=\"hidden reply_to_{$hist['Approval']['reply_to']}\"";
+else
+ $trclass="";
+?>
+
+<tr <?=$trclass?>>
+ <td><?php if (!empty($hist['Version'])) echo "{$hist['Version']['version']} ({$platforms[$hist['File']['platform_id']]})"?></td>
+ <td><?=$hist['Approval']['created']?></td>
+ <td><?=$html->linkEmail($hist['User']['firstname'].' '.$hist['User']['lastname'], $hist['User']['email'])?></td>
+ <td>
+ <?php
+ if ($hist['Approval']['reviewtype'] == 'nominated') {
+ if ($hist['Approval']['action'] == STATUS_PUBLIC) {
+ echo _('editors_review_history_nominated_approved');
+ }
+ elseif ($hist['Approval']['action'] == STATUS_SANDBOX) {
+ echo _('editors_review_history_nominated_denied');
+ }
+ elseif ($hist['Approval']['action'] == STATUS_NOMINATED) {
+ echo _('editors_review_history_nominated_adminreview');
+ }
+ }
+ elseif ($hist['Approval']['reviewtype'] == 'pending') {
+ if ($hist['Approval']['action'] == STATUS_PUBLIC) {
+ echo _('editors_review_history_pending_approved');
+ }
+ elseif ($hist['Approval']['action'] == STATUS_SANDBOX) {
+ echo _('editors_review_history_pending_denied');
+ }
+ elseif ($hist['Approval']['action'] == STATUS_PENDING) {
+ echo _('editors_review_history_pending_adminreview');
+ }
+ }
+ elseif ($hist['Approval']['reviewtype'] == 'info') {
+ if (empty($hist['Approval']['reply_to']))
+ echo ___('editors_review_history_info_request', 'Information Request');
+ else
+ echo ___('editors_review_history_info_reply', 'Reply');
+ }
+ ?>
+ </td>
+ <td><?=nl2br($hist['Approval']['comments'])?></td>
+</tr>
+<?php if ($hist['Approval']['reviewtype'] == 'info' && empty($hist['Approval']['reply_to'])
+ && !empty($hist['replies'])):?>
+<tr>
+ <td colspan="5">
+ <?=$html->link(sprintf(n___('editors_review_history_show_hide_replies',
+ 'editors_review_history_show_hide_replies', count($hist['replies']),
+ 'Show/Hide Replies (%1$s)'), count($hist['replies'])), "#",
+ array('onclick'=>"$('tr.reply_to_{$hist['Approval']['id']}').toggle();return false;"))?></td>
+</tr>
+<?php
+// show all replies
+foreach ($hist['replies'] as &$reply) {
+ echo $this->renderElement('developers/editors_review_history_item', array('hist'=>$reply));
+}
+?>
+<?php endif; ?>
diff --git a/site/app/views/elements/developers/editorsmenu.thtml b/site/app/views/elements/developers/editorsmenu.thtml
new file mode 100644
index 0000000..472ec1a
--- /dev/null
+++ b/site/app/views/elements/developers/editorsmenu.thtml
@@ -0,0 +1,66 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * Justin Scott <fligtar@gmail.com>.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+if (empty($page)) {
+ $page = '';
+}
+if (empty($mode)) {
+ if (!empty($reviewType)) {
+ $mode = $reviewType;
+ }
+ else {
+ $mode = '';
+ }
+}
+?>
+
+<div id="sidebar">
+ <div id="categories">
+ <h3><span><?=_('editorcp_menu_title')?></span></h3>
+
+ <ul id="cat-list">
+ <li<?=($page == 'summary') ? ' class="selected"' : ''?>><?=$html->link(_('editorcp_menu_summary_link'), '/editors/summary')?></li>
+ <li<?=($mode == 'reviews') ? ' class="selected"' : ''?>><?=$html->link(sprintf(ngettext('devcp_editorsqueue_moderatedreviews', 'devcp_editorsqueue_moderatedreviews', $count['reviews']), $count['reviews']), '/editors/queue/reviews')?></li>
+ <li<?=($mode == 'pending') ? ' class="selected"' : ''?>><?=$html->link(sprintf(ngettext('devcp_editorsqueue_pendingupdates', 'devcp_editorsqueue_pendingupdates', $count['pending']), $count['pending']), '/editors/queue/pending')?></li>
+ <li<?=($mode == 'nominated') ? ' class="selected"' : ''?>><?=$html->link(sprintf(ngettext('devcp_editorsqueue_nominated', 'devcp_editorsqueue_nominated', $count['nominated']), $count['nominated']), '/editors/queue/nominated')?></li>
+ <li<?=($mode == 'featured') ? ' class="selected"' : ''?>><?=$html->link(_('devcp_editorsqueue_featured'), '/editors/featured')?></li>
+ <li<?=($page == 'logs') ? ' class="selected"' : ''?>><?=$html->link(_('editorcp_menu_eventlog_link'), '/editors/logs')?></li>
+ <li<?=($page == 'reviewlog') ? ' class="selected"' : ''?>><?=$html->link(_('editorcp_menu_reviewlog_link'), '/editors/reviewlog')?></li>
+ <li<?=($page == 'performance') ? ' class="selected"' : ''?>><?=$html->link(___('editorcp_menu_performance_link', 'Performance'), '/editors/performance')?></li>
+ <li><?=$html->link(_('editorcp_menu_mainpage_link'), '/')?></li>
+ </ul>
+ </div>
+</div>
diff --git a/site/app/views/elements/developers/editorsqueue.thtml b/site/app/views/elements/developers/editorsqueue.thtml
new file mode 100644
index 0000000..d3cb2cd
--- /dev/null
+++ b/site/app/views/elements/developers/editorsqueue.thtml
@@ -0,0 +1,46 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * Justin Scott <fligtar@gmail.com>.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Frederic Wenzel <fwenzel@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+?>
+<table id="tabTable">
+ <tr>
+ <td id="spacer"></h1></td>
+ <td id="reviews"><div class="tab<?=($mode == 'reviews') ? ' selected' : ''?>"><a href="<?=$html->url('/editors/queue/reviews')?>"><?=sprintf(ngettext('devcp_editorsqueue_moderatedreviews', 'devcp_editorsqueue_moderatedreviews', $count['reviews']), $count['reviews'])?></a></div></td>
+ <td id="pending"><div class="tab<?=($mode == 'pending') ? ' selected' : ''?>"><a href="<?=$html->url('/editors/queue/pending')?>"><?=sprintf(ngettext('devcp_editorsqueue_pendingupdates', 'devcp_editorsqueue_pendingupdates', $count['pending']), $count['pending'])?></a></div></td>
+ <td id="nominated"><div class="tab<?=($mode == 'nominated') ? ' selected' : ''?>"><a href="<?=$html->url('/editors/queue/nominated')?>"><?=sprintf(ngettext('devcp_editorsqueue_nominated', 'devcp_editorsqueue_nominated', $count['nominated']), $count['nominated'])?></a></div></td>
+ </tr>
+</table>
diff --git a/site/app/views/elements/developers/license_picker.thtml b/site/app/views/elements/developers/license_picker.thtml
new file mode 100644
index 0000000..c829723
--- /dev/null
+++ b/site/app/views/elements/developers/license_picker.thtml
@@ -0,0 +1,49 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ *
+ * Contributor(s):
+ * Jeff Balogh <jbalogh@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/**
+ * Required parameters:
+ * - $licenses: array to populate options (value => array(name, selected))
+ */
+?>
+<select id="license-name" name="data[License][name]">
+<?php
+ foreach ($licenses as $val => $license) {
+ $selected = $license['selected'] ? 'selected="selected"' : '';
+ echo "<option value='{$val}' ${selected}>{$license['name']}</option>";
+ }
+?>
+</select>
diff --git a/site/app/views/elements/developers/license_translationbox.thtml b/site/app/views/elements/developers/license_translationbox.thtml
new file mode 100644
index 0000000..9ff9919
--- /dev/null
+++ b/site/app/views/elements/developers/license_translationbox.thtml
@@ -0,0 +1,62 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ *
+ * Contributor(s):
+ * Jeff Balogh <jbalogh@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/**
+ * Required parameters:
+ * - $translations: array mapping (license picker values => locales)
+ * - $fieldname: name of the translation box field
+ */
+$boxes = array();
+// Create all the HTML strings, but store them in JSON.
+// We use jQuery to create and manipulate the DOM elements later.
+foreach($translations as $name => $locale) {
+ $boxes[$name] = $this->renderElement('translationbox', array(
+ 'field' => $fieldname,
+ 'type' => 'textarea',
+ 'translations' => $locale['text'],
+ 'height' => '130',
+ 'width' => 'inherit',
+ 'graybox' => false));
+}
+?>
+<!-- We slide the translation box into this div. -->
+<div id="license-translationbox"></div>
+<script type="text/javascript">
+ $(document).ready(function() {
+ var license_trans = <?=$javascript->object($boxes)?>;
+ license_picker.init(license_trans);
+ });
+</script>
diff --git a/site/app/views/elements/developers/localebox.thtml b/site/app/views/elements/developers/localebox.thtml
new file mode 100644
index 0000000..6a52e9d
--- /dev/null
+++ b/site/app/views/elements/developers/localebox.thtml
@@ -0,0 +1,98 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * Justin Scott <fligtar@gmail.com>.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Frederic Wenzel <fwenzel@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+if (!empty($step)) {
+ echo '<div id="translationBox">';
+}
+else {
+ echo '<div class="breaklessDivider"></div>';
+ echo '<div id="translationBox">';
+ echo '<h3>'._('devcp_localebox_header_localizedfields').'</h3>';
+}
+?>
+ <div id="localeIntro">
+ <?=sprintf(_('devcp_localebox_intro'), $localebox['defaultLocale'])?>
+ </div>
+
+ <div id="locale-box">
+ <?php
+ foreach ($localebox['languages'] as $locale => $language) {
+ echo '<span onClick="showLocale(\''.str_replace('-', '_', $locale).'\', this);" title="'.$language.'"'.
+ (($locale == $localebox['defaultLocale']) ? 'id="defaultLocaleSpan" class="selected"' : '').'>'.$locale.'</span>';
+ }
+ ?>
+ </div>
+
+<?php
+ foreach ($localebox['languages'] as $locale => $language) {
+ $localeClass = str_replace('-', '_', $locale);
+?>
+ <div id="locale_<?=$localeClass?>" <?=($locale != $localebox['defaultLocale']) ? 'style="display: none;"' : ''?>>
+ <input type="hidden" name="data[Locales][]" value="<?=$locale?>">
+ <h3><?=html_entity_decode($language).' ['.$locale.']'?></h3>
+ <?php
+ foreach ($localebox['localizedFields'] as $localizedField) {
+ $field = $localizedField['model'].'/'.$localizedField['field'].'][';
+ $id = $localizedField['model'].ucwords($localizedField['field']).'_'.$localeClass;
+ $localizedField['attributes']['value'] = (!empty($localebox['info'][$locale][$localizedField['field']]) ? $localebox['info'][$locale][$localizedField['field']] : '');
+ $localizedField['attributes']['id'] = $id;
+
+ echo '<div>';
+ switch ($localizedField['type']) {
+ case 'textarea':
+ echo '<label for="'.$id.'">'.$localizedField['display'].'</label>';
+ echo $html->textarea($field, $localizedField['attributes']);
+ break;
+ case 'input':
+ $localizedField['attributes']['value'] = htmlentities($localizedField['attributes']['value'], ENT_QUOTES, 'UTF-8');
+ echo '<label for="'.$id.'">'.$localizedField['display'].'</label>';
+ echo $html->input($field, $localizedField['attributes']);
+ break;
+ }
+ echo '</div>';
+ }
+ ?>
+ </div>
+<?php
+ }
+?>
+</div>
+
+<script language="JavaScript" style="text/javascript">
+ var previousLocale = '<?=str_replace('-', '_', $localebox['defaultLocale'])?>';
+ var previousSpan = document.getElementById('defaultLocaleSpan');
+</script>
diff --git a/site/app/views/elements/developers/localizermenu.thtml b/site/app/views/elements/developers/localizermenu.thtml
new file mode 100644
index 0000000..bde2620
--- /dev/null
+++ b/site/app/views/elements/developers/localizermenu.thtml
@@ -0,0 +1,70 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * Justin Scott <fligtar@gmail.com>.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+?>
+<div id="sidebar">
+ <div id="categories">
+ <h3><span>Localizer Tools</span></h3>
+
+ <ul id="cat-list">
+ <li<?=($page == 'summary') ? ' class="selected"' : ''?>><?=$html->link('Localizer Summary', '/localizers/summary')?></li>
+ <li<?=($page == 'applications') ? ' class="selected"' : ''?>><?=$html->link('Applications', '/localizers/applications')?></li>
+ <li<?=($page == 'tags') ? ' class="selected"' : ''?>><?=$html->link('Categories', '/localizers/tags')?></li>
+ <?php if ($this->controller->SimpleAcl->actionAllowed('Admin', 'lists', $this->controller->Session->read('User'))): ?>
+ <li<?=($page == 'platforms') ? ' class="selected"' : ''?>><?=$html->link('Platforms', '/localizers/platforms')?></li>
+ <?php endif; ?>
+ <li<?=($page == 'gettext') ? ' class="selected"' : ''?>><?=$html->link('Gettext', '/localizers/gettext')?></li>
+ <li<?=($page == 'pages') ? ' class="selected"' : ''?>><?=$html->link('Pages', '/localizers/pages')?></li>
+ <li<?=($page == 'logs') ? ' class="selected"' : ''?>><?=$html->link(USERLANG.' Log', '/localizers/logs')?></li>
+ <li><?=$html->link('Back to Main', '/')?></li>
+ </ul>
+ </div>
+
+ <div>
+ <form>
+ <select name="userlang" onChange="this.form.submit();">
+ <?php
+ global $native_languages, $valid_languages;
+ foreach ($valid_languages as $key => $language) {
+ echo '<option value="'.$key.'" '.($key == USERLANG ? 'selected' : '').'>'
+ .$native_languages[$key]['native'].'</option>';
+ }
+ ?>
+ </select>
+ </form>
+ </div>
+
+</div>
diff --git a/site/app/views/elements/developers/myaddons.thtml b/site/app/views/elements/developers/myaddons.thtml
new file mode 100644
index 0000000..708db07
--- /dev/null
+++ b/site/app/views/elements/developers/myaddons.thtml
@@ -0,0 +1,82 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * Justin Scott <fligtar@gmail.com>.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Frederic Wenzel <fwenzel@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+?>
+<div id="sidebar">
+
+ <?php
+ if (!empty($extra)) {
+ echo $this->renderElement($extra, array('addon_id' => $addon_id));
+ }
+ ?>
+
+ <div id="categories" class="secondary-item-list">
+
+ <?php if (!$this->controller->Session->check('User')): ?>
+ <h4><?=$html->link(_('header_navlink_login'), $html->login_url())?></h4>
+ <?php else: ?>
+ <h4><?=$html->link(_('devcp_myaddons_link'), '/developers/index')?></h4>
+ <ul id="cat-list">
+ <?php
+ if (!empty($addons)) {
+ foreach ($addons as $id => $name) {
+ echo '<li class="indented">';
+ echo $html->link($name, '/developers/details/'.$id, array('class' => 'addons'));
+ echo '</li>';
+ }
+ }
+ ?>
+ </ul>
+ </div>
+
+ <div class="secondary-item-list">
+ <h4><span><?=_('devcp_myaddons_title')?></span></h4>
+ <ul class="">
+ <li><?=$html->link(_('devcp_myaddons_submitaddon_link'), '/developers/add')?></li>
+ <li><?=$html->link(_('devcp_myaddons_statistics_link'), '/statistics')?></li>
+ <?php if ($this->controller->SimpleAcl->actionAllowed('Editors', '*', $this->controller->Session->read('User'))): ?>
+ <li><?=$html->link(_('devcp_myaddons_editorcp_link'), '/editors')?></li>
+ <?php endif;
+ if ($this->controller->SimpleAcl->actionAllowed('Admin', '%', $this->controller->Session->read('User'))): ?>
+ <li><?=$html->link(_('devcp_myaddons_admincp_link'), '/admin')?></li>
+ <?php endif; ?>
+ <li><?=$html->link(_('devcp_myaddons_mainpage_link'), '/')?></li>
+ </ul>
+ <?php endif; ?>
+
+ </div>
+</div>
diff --git a/site/app/views/elements/developers/performanceheader.thtml b/site/app/views/elements/developers/performanceheader.thtml
new file mode 100644
index 0000000..ad5a0a1
--- /dev/null
+++ b/site/app/views/elements/developers/performanceheader.thtml
@@ -0,0 +1,64 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * Justin Scott <fligtar@gmail.com>.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Frederic Wenzel <fwenzel@mozilla.com>
+ * Scott McCammon <smccammon@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+?>
+<div id="performance-header">
+<?php if ($showUserLookup): ?>
+ <div id="performanceUserSelect">
+ <form action="<?=$html->url()?>" method="get">
+ <div>
+ <select name="user" id="performanceUser">
+ <?php if (!in_array($user['User']['email'], $editors)): ?>
+ <option value="<?=$user['User']['email']?>" selected="selected"><?=$user['User']['email']?></option>
+ <?php endif; ?>
+ <?php foreach ($editors as $editor): ?>
+ <option value="<?=$editor?>"<?=($editor==$user['User']['email'] ? ' selected="selected"': '')?>><?=$editor?></option>
+ <?php endforeach; ?>
+ </select>
+ </div>
+ </form>
+ </div>
+<?php endif; ?>
+ <h3><?=sprintf(___('editorcp_performance_page_heading', 'Performance Report For %1$s'), $userName)?></h3>
+ <table id="tabTable">
+ <tr>
+ <td id="details"><div class="tab<?=($mode == '') ? ' selected' : ''?>"><a href="<?=$html->url('/editors/performance'.($showUserLookup ? "?user={$user['User']['email']}" : ''))?>">Details</a></div></td>
+ <td id="charts"><div class="tab<?=($mode == 'charts') ? ' selected' : ''?>"><a href="<?=$html->url('/editors/performance/charts'.($showUserLookup ? "?user={$user['User']['email']}" : ''))?>">Charts</a></div></td>
+ </tr>
+ </table>
+</div>
diff --git a/site/app/views/elements/developers/rolecheck.thtml b/site/app/views/elements/developers/rolecheck.thtml
new file mode 100644
index 0000000..93d46f7
--- /dev/null
+++ b/site/app/views/elements/developers/rolecheck.thtml
@@ -0,0 +1,46 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Justin Scott <fligtar@mozilla.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+if (empty($required_role) || (!empty($required_role) && $author_role < $required_role)):
+?>
+ <div class="notice no-privs-box rounded">
+ <?=___('devcp_rolecheck_no_privs')?>
+ </div>
+<?php
+endif;
+?> \ No newline at end of file
diff --git a/site/app/views/elements/developers/sidebar.thtml b/site/app/views/elements/developers/sidebar.thtml
new file mode 100644
index 0000000..2f4bc15
--- /dev/null
+++ b/site/app/views/elements/developers/sidebar.thtml
@@ -0,0 +1,77 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * Justin Scott <fligtar@gmail.com>.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Frederic Wenzel <fwenzel@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+?>
+<div id="sidebar">
+
+ <?php
+ if (!empty($extra)) {
+ echo $this->renderElement($extra, array('addon_id' => $addon_id));
+ }
+ ?>
+
+ <div id="categories">
+ <h3><span><?=_('devcp_myaddons_title')?></span></h3>
+
+ <ul id="cat-list">
+ <?php if ($this->controller->Session->check('User')): ?>
+ <li><?=$html->link(___('devcp_sidebar_a_dashboard'), '/developers/dashboard')?></li>
+ <?php
+ if (!empty($addons)) {
+ foreach ($addons as $addon_id => $addon_name) {
+ echo '<li class="indented">';
+ echo '<a href="'.$html->url('/developers/dashboard#addon-'.$addon_id).'">'.$addon_name.'</a>';
+ echo '</li>';
+ }
+ }
+ ?>
+ <li><?=$html->link(_('devcp_myaddons_submitaddon_link'), '/developers/addon/submit')?></li>
+ <li><?=$html->link(_('devcp_myaddons_statistics_link'), '/statistics')?></li>
+ <?php if ($this->controller->SimpleAcl->actionAllowed('Editors', '*', $this->controller->Session->read('User'))): ?>
+ <li><?=$html->link(_('devcp_myaddons_editorcp_link'), '/editors')?></li>
+ <?php endif;
+ if ($this->controller->SimpleAcl->actionAllowed('Admin', '%', $this->controller->Session->read('User'))): ?>
+ <li><?=$html->link(_('devcp_myaddons_admincp_link'), '/admin')?></li>
+ <?php endif; ?>
+ <li><?=$html->link(_('devcp_myaddons_mainpage_link'), '/')?></li>
+ <?php else: ?>
+ <li><?=$html->link(_('header_navlink_login'), $html->login_url())?></li>
+ <?php endif; ?>
+ </ul>
+
+ </div>
+</div>
diff --git a/site/app/views/elements/developers/statsbar.thtml b/site/app/views/elements/developers/statsbar.thtml
new file mode 100644
index 0000000..2530a5c
--- /dev/null
+++ b/site/app/views/elements/developers/statsbar.thtml
@@ -0,0 +1,47 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Justin Scott <fligtar@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+?>
+<div class="stats">
+<?php
+ echo sprintf(_('devcp_statsbar_total_downloads'), $html->number_format($addon['totaldownloads'], 0));
+ echo '&nbsp;&middot;&nbsp;';
+ echo sprintf(_('devcp_statsbar_weekly_downloads'), $html->number_format($addon['weeklydownloads'], 0));
+ echo '&nbsp;&middot;&nbsp;';
+ echo sprintf(_('devcp_statsbar_adu'), $html->number_format($addon['updatepings'], 0));
+?>
+</div>
diff --git a/site/app/views/elements/extendfirefox.thtml b/site/app/views/elements/extendfirefox.thtml
new file mode 100644
index 0000000..69d99fe
--- /dev/null
+++ b/site/app/views/elements/extendfirefox.thtml
@@ -0,0 +1,11 @@
+<?php
+if (false) {
+?>
+
+<div id="extendfirefox">
+<a href="http://labs.mozilla.com/contests/extendfirefox/?utm_source=amo&utm_medium=banner&utm_content=468x60&utm_campaign=0710extendffxcontest" title="Extend Firefox Contest"><?=$html->image('extendfirefox/extendfirefox-small.jpg', array('alt'=>'Extend Firefox Contest','height'=>60,'width'=>468))?></a>
+</div>
+
+<?php
+}
+?>
diff --git a/site/app/views/elements/feature.thtml b/site/app/views/elements/feature.thtml
new file mode 100644
index 0000000..2f43bcb
--- /dev/null
+++ b/site/app/views/elements/feature.thtml
@@ -0,0 +1,129 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Mike Morgan <morgamic@mozilla.com> (Original Author)
+ * Frederic Wenzel <fwenzel@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+?>
+<?php
+/**
+ * This element is used on the front page and can also be used on browse and
+ * category pages. It in turn calls the install element, which works its own
+ * magic for install boxes.
+ *
+ * This element uses the following local variables:
+ * - $addonIconPath
+ * - $addonThumbPath
+ * - $addonName
+ * - $addonSummary
+ * - $addonId
+ * - $addonFiles
+ * - $addonEULA
+ * - $addonStatus
+ * - $addonAuthors
+ * - $addonRating
+ * - $addonReviews
+ * - $addonTags
+ * - $addonWeeklyDownloads
+ * - $allPlatforms - There should only be one platform in the list when this is used on the eula view.
+ * - $compatible_apps
+ * - $addonType - default ADDON_EXTENSION
+ * - $buttonMessage - default 'a_install'
+ *
+ */
+
+// Bug 444817: limit length of addon descriptions in feature elements.
+$desc_limit = 250;
+if (mb_strlen($addonSummary) > $desc_limit) {
+ // If the addon summary exceeds the display limit, cut it off before the
+ // last space-delimited word in the string and add an ellipsis linking to
+ // the full detail page. Would use TextHelper::truncate() here, but need
+ // mb_* string functions.
+
+ // mb_substr is used twice here, because mb_strrpos doesn't support
+ // offset in PHP 5.1.6 - first chop down to char limit, then chop down
+ // to end of last space-delimited word.
+ $addonSummary = mb_substr($addonSummary, 0, $desc_limit);
+ $addonSummary = mb_substr($addonSummary, 0, mb_strrpos($addonSummary, ' ')) .
+ ' <a href="'.$html->url("/addon/{$addonId}").'">...</a>';
+}
+
+// prepare alt and title text for preview image
+$_alt = sprintf(_('img_preview_of'), $addonName);
+
+// is addon recommended or experimental?
+global $experimental_status;
+if (isset($addonStatus) && in_array($addonStatus, $experimental_status))
+ $flag = _('addon_listitem_flag_experimental');
+else
+ $flag = '';
+?>
+
+<h4 class="name" title="<?=___('addons_title_tooltip') ?>"><a href="<?=$html->url("/addon/{$addonId}")?>"><img src="<?=$addonIconPath?>" width="32" height="32" alt="" class="icon"/><?=$addonName?></a></h4>
+<h5 class="author" title="<?=___('addons_author_tooltip') ?>"><?=_('addons_home_by')?> <?=$html->linkUsersFromModel($addonAuthors, 0);?></h5>
+<? if (!empty($flag)) echo '<h6 class="flag">'.$flag.'</h6>'; ?>
+<p class="preview-img"><a href="<?=$html->url("/addon/{$addonId}")?>"><img src="<?=$addonThumbPath?>" alt="<?=$_alt?>" title="<?=$_alt?>"/></a></p>
+<p class="desc"><?=$addonSummary?></p>
+<p class="rating"><?=$this->renderElement('stars',array('rating' => $addonRating))?><?php if ($addonReviews > 0) { ?> <a href="<?=$html->url('/addon/'.$addonId.'#reviews')?>"><?=sprintf(ngettext('feature_reviews','feature_reviews', $addonReviews), $addonReviews)?></a><?php } ?></p>
+<p class="stats"><em><?=$html->number_format($addonWeeklyDownloads, 0)?></em>
+<?php echo ___('addon_downloads_weekly'); ?>
+</p>
+<?php if (isset($addonFiles)): ?>
+
+<p class="updated">
+ <?php echo sprintf(___('addon_detail_last_updated'), strftime(_('date'), strtotime($addonVersionCreated))); ?>
+</p>
+
+<?=$this->renderElement('install',array(
+ 'addonIconPath' => $addonIconPath,
+ 'addonName' => $addonName,
+ 'addonId' => $addonId,
+ 'addonFiles' => $addonFiles,
+ 'addonEULA' => $addonEULA,
+ 'addonStatus' => $addonStatus,
+ 'is_latest' => ($addonStatus == STATUS_PUBLIC),
+ 'compatible_apps' => $compatible_apps,
+ 'allPlatforms' => $allPlatforms,
+ 'addonType' => $addonType
+))?>
+<?php else: ?>
+<p class="learn-more"><?=$html->link(_('feature_learnmore'), "/addon/{$addonId}",
+ array('class'=>'view', 'title'=>sprintf(_('feature_learnmore_about_addon'), $addonName)))?></p>
+<?php endif; ?>
+
+<?php if(!empty($addonTags)): ?>
+<p class="more-from"><?=_('feature_view_more_from_category')?> <a href="<?=$html->url('/browse/type:'.$addonType.'/cat:'.$addonTags[0]['Tag']['id'])?>" class="view"><?=$addonTags[0]['Translation']['name']['string']?></a></p>
+<?php endif; ?>
+
diff --git a/site/app/views/elements/footer.thtml b/site/app/views/elements/footer.thtml
new file mode 100644
index 0000000..9b2f9a6
--- /dev/null
+++ b/site/app/views/elements/footer.thtml
@@ -0,0 +1,82 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Andrei Hajdukewycz <sancus@off.net> (Original Author)
+ * Justin Scott <fligtar@gmail.com>
+ * Wil Clouser <clouserw@mozilla.com>
+ * Mike Morgan <morgamic@mozilla.com>
+ * Frederic Wenzel <fwenzel@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+?>
+
+<!-- start #footer -->
+<div id="footer">
+
+<?php if (!isset($suppressLanguageSelector) || !$suppressLanguageSelector): ?>
+<form id="footer-lang-form" method="get" action="">
+ <p>
+ <label for="language"><?=_('footer_other_languages')?></label>
+ <select id="language" name="lang" dir="ltr" onchange="this.form.submit()">
+ <?php
+ // Retrieve language arrays from bootstrap.
+ global $supported_languages, $native_languages;
+ foreach (array_keys($supported_languages) as $key) {
+ echo '<option value="'.$key.'" '.($key == LANG ? 'selected="selected"' : '').'>'
+ .$native_languages[$key]['native'].'</option>'."\n";
+ }
+ ?>
+ </select>
+ <input class="hidden" type="submit" value="<?=_('footer_lang_form_lang_submit_go')?>"/>
+ </p>
+</form>
+<?php endif; ?>
+
+<div id="footer-legal">
+ <p id="copyright"><?=_('footer_copyright')?> <span title="<?=php_uname('n')?>">&#169;</span> 2005&#8211;<?=date('Y')?> Mozilla. <?=_('footer_all_rights_reserved')?></p>
+ <ul id="nav-legal">
+ <li><?=$html->link(_('footer_privacy_policy'), '/pages/privacy');?></li>
+ <li><a href="http://www.mozilla.com/<?=LANG?>/about/legal.html"><?=_('footer_legal_notices')?></a></li>
+ <?php if (!isset($suppressCredits) || !$suppressCredits): ?><li><?=$html->link(_('footer_credits'), '/pages/credits')?></li><?php endif; ?>
+ <li><?=$html->link(___('footer_a_about'), '/pages/about')?></li>
+ <li><?=$html->link('<abbr title="'.___('footer_abbr_faq').'">'.___('footer_a_faq').'</abbr>', '/pages/faq')?></li>
+ <li><a href="http://blog.mozilla.com/addons"><?=___('footer_a_blog')?></a></li>
+ </ul>
+ <p id="footer-disclaimer"><?=_('footer_disclaimer')?></p>
+</div>
+
+
+</div>
+<!-- end #footer -->
+
diff --git a/site/app/views/elements/header.thtml b/site/app/views/elements/header.thtml
new file mode 100644
index 0000000..9147b7d
--- /dev/null
+++ b/site/app/views/elements/header.thtml
@@ -0,0 +1,165 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Mike Morgan <morgamic@mozilla.com>
+ * Justin Scott <fligtar@gmail.com>
+ * Frederic Wenzel <fwenzel@mozilla.com>
+ * Wil Clouser <clouserw@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+?>
+<ul id="nav-access">
+ <li><a href="#content">Skip to main content</a></li>
+ <li><a href="#search-form">Skip to search form</a></li>
+ <li><a href="#categories">Skip to categories menu</a></li>
+ <li><a href="#other-apps">Skip to other applications menu</a></li>
+</ul>
+
+
+<?php
+ if (empty($addonStatus))
+ $addonStatus = STATUS_PUBLIC;
+ if ($this->controller->name == "Search")
+ $url_format = "?status=%s";
+ else
+ $url_format = "/status:%s";
+ if (isset($addonStatus) && $addonStatus == STATUS_SANDBOX) {
+ $homeText = _('a_header_sandbox');
+ $homeLink = "/addons/home/status:" . STATUS_SANDBOX;
+ }
+ else {
+ $homeText = _('header_navlink_addons');
+ $homeLink = "/";
+ }
+
+ $publicUrl = $this->action;
+ if (isset($this->params['pass']) && is_array($this->params['pass'])) {
+ foreach ($this->params['pass'] as $arg) {
+ $parts = explode(':', $arg);
+ if (low($parts[0]) != "status")
+ $publicUrl = $publicUrl . "/{$arg}";
+ }
+ }
+ $sandboxUrl = $publicUrl . sprintf($url_format, STATUS_SANDBOX);
+ $sandboxUrl = $html->link(_('a_header_sandbox'), $sandboxUrl);
+ $publicUrl = $html->link(_('a_header_public'), $publicUrl);
+
+ if(isset($sandboxAccess) && $sandboxAccess && $this->controller->action != 'display') {
+ if ($addonStatus == STATUS_SANDBOX)
+ $sandboxLink = "$publicUrl | "._('a_header_sandbox');
+ else
+ $sandboxLink = _('a_header_public')." | $sandboxUrl";
+ }
+
+ switch (APP_SHORTNAME) {
+ case 'firefox':
+ $main_header = _('header_main_firefox_header');
+ break;
+ case 'seamonkey':
+ $main_header = _('header_main_seamonkey_header');
+ break;
+ case 'sunbird':
+ $main_header = _('header_main_sunbird_header');
+ break;
+ case 'thunderbird':
+ $main_header = _('header_main_thunderbird_header');
+ break;
+ default:
+ $main_header = _('header_main_header');
+ break;
+ }
+?>
+
+<div id="branding">
+ <h4 id="moz"><a href="http://www.mozilla.com/<?=LANG?>/" title="mozilla.com" accesskey="1"><?=$html->image('template/moz-com-logo.png', array('alt' => 'Mozilla Corporation', 'title' => 'Mozilla Corporation', 'height' => '38', 'width' => '89'))?></a></h4>
+
+<?php if (isset($bigHeader) && $bigHeader) { ?>
+ <div id="page-title" class="<?=APP_SHORTNAME?>">
+ <!-- Default header -->
+ <div>
+ <h1><a href="<?=$html->url('/')?>" title="<?=sprintf(_('header_home_tooltip'), APP_PRETTYNAME)?>">
+ <?php echo $html->image('app-icons/'.APP_SHORTNAME.'.png', array('alt' => $main_header)); ?>
+ <?=$main_header?></a></h1>
+ <p class="page-intro"><?=$bigHeaderText?></p>
+ </div>
+ </div>
+<?php } else { ?>
+
+ <div id="page-title" class="sub-page <?=LAYOUT_NAME?>">
+ <!-- Header for sub-pages -->
+ <div>
+ <h1><a href="<?=$html->url('/')?>" title="<?=sprintf(_('header_home_tooltip'), APP_PRETTYNAME)?>">
+ <?php echo $html->image('app-icons/'.LAYOUT_NAME.'.png', array('alt' => $main_header)); ?>
+ <?php
+ if (LAYOUT_NAME == 'generic' || LAYOUT_NAME == 'developers') {
+ echo 'Mozilla Add-ons</a></h1>';
+ if (!empty($subpagetitle)) {
+ echo '<h2>'.$subpagetitle.'</h2>';
+ }
+ }
+ else {
+ // Not perfect l10n, but better than hardcoded English
+ echo $main_header.(isset($subpagetitle) ? ": <span>{$subpagetitle}</span>" : '').'</a></h1>';
+ }
+ ?>
+ </div>
+ </div>
+
+<?php } ?>
+
+ <ul id="nav-user">
+ <?php
+ if ($this->controller->Session->check('User')) {
+ $user = $this->controller->Session->read('User');
+ echo '<li>' . $html->link(_('header_navlink_myaccount'), '/users/edit', array('title' => $user['email'])) . '</li>' . "\n";
+ echo '<li>' . $html->link(_('sidebar_navlink_developer_tools'), '/developers') . '</li>' . "\n";
+ if ($this->controller->SimpleAcl->actionAllowed('Editors', '%', $this->controller->Session->read('User'))) {
+ echo '<li>' . $html->link(_('sidebar_navlink_editor_tools'), '/editors') .'</li>' . "\n";
+ }
+ if ($this->controller->SimpleAcl->actionAllowed('Localizers', '%', $this->controller->Session->read('User'))) {
+ echo '<li>' . $html->link('Localizer Tools', '/localizers') . '</li>' . "\n";
+ }
+ if ($this->controller->SimpleAcl->actionAllowed('Admin', '%', $this->controller->Session->read('User'))) {
+ echo '<li>' . $html->link(_('sidebar_navlink_admin_tools'), '/admin') . '</li>' . "\n";
+ }
+ echo '<li>' . $html->link(_('header_navlink_logout'), $html->logout_url()) . '</li>' . "\n";
+ } else {
+ echo '<li>' . $html->link(_('header_navlink_register'), '/users/register') . '</li> ' . "\n";
+ echo '<li>' . $html->link(_('header_navlink_login'), $html->login_url()) . '</li>' . "\n";
+ }
+ ?>
+ </ul>
+
+</div><!-- /#branding -->
+
diff --git a/site/app/views/elements/install.thtml b/site/app/views/elements/install.thtml
new file mode 100644
index 0000000..1f9e80a
--- /dev/null
+++ b/site/app/views/elements/install.thtml
@@ -0,0 +1,303 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Andrei Hajdukewycz <sancus@off.net> (Original Author)
+ * Mike Morgan <morgamic@mozilla.com>
+ * Frederic Wenzel <fwenzel@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+?>
+<?php
+/**
+ * This element uses the following local variables:
+ * - $addonIconPath
+ * - $addonName
+ * - $addonId
+ * - $addonFiles
+ * - $is_latest -- link to "download/latest" shortcut (default false)
+ * - $addonEULA
+ * - $addonStatus
+ * - $allPlatforms - There should only be one platform in the list when this is used on the eula view.
+ * - $addonType - default ADDON_EXTENSION
+ * - $collection_uuid - if this add-on download is collection related, this will set a tracking code in the download ID. default null
+ * - $buttonMessage - default 'a_install'
+ * - $showInstructions - Show install instructions for Thunderbird or Seamonkey, defaults to true
+ */
+global $browser_apps, $experimental_status, $valid_status;
+
+/* prepare add-on type */
+if (!isset($addonType)) $addonType = ADDON_EXTENSION;
+
+if (!isset($showInstructions)) $showInstructions = true;
+
+/* logged in users can install experimental add-ons */
+$loggedin = $this->controller->Session->check('User');
+
+/* use "latest public file" permalink if this is the latest version. Defaults to false. */
+if (!isset($is_latest)) $is_latest = false;
+
+/* "Install" for browser apps, "Download" for non-browser apps */
+if (!isset($buttonMessage)) {
+ if (!in_array(APP_ID, $browser_apps)) {
+ $buttonMessage = _('a_download');
+ } else {
+ $buttonMessage = sprintf(_('install_button_text'), APP_PRETTYNAME, "%s");
+ }
+}
+
+
+/* Prepare addon icons */
+if (empty($addonIconPath)) {
+ switch ($addonType) {
+ case ADDON_THEME:
+ $addonIconPath = $html->urlImage(DEFAULT_THEME_ICON);
+ break;
+ default:
+ $addonIconPath = $html->urlImage(DEFAULT_ADDON_ICON);
+ break;
+ }
+}
+
+if (count($addonFiles) < 1) {
+ // This should never happen - this would mean the file didn't exist.
+ echo '<p class="install-button">'._('install_error_addon_not_found').'</p>';
+
+} else {
+
+ $versionId = $addonFiles[0]['version_id'];
+
+ // If we're looking at thunderbird pages, and there is no EULA, show the TB
+ // install instructions. Bug 401272 fixed the button so it downloads instead of
+ // installs, but it doesn't hurt to have these instructions still.
+ if (APP_ID == APP_THUNDERBIRD && empty($addonEULA) && $showInstructions) {
+ echo '<div class="app_install">';
+ echo '<h3>'._('addons_install_in_thunderbird_title').'</h3>';
+ echo _('addons_install_in_thunderbird');
+ echo '</div>';
+ }
+ if (APP_ID == APP_SUNBIRD && empty($addonEULA) && $showInstructions) {
+ echo '<div class="app_install">';
+ echo '<h3>'._('addons_install_in_sunbird_title').'</h3>';
+ echo _('addons_install_in_sunbird');
+ echo '</div>';
+ }
+
+ echo '<div id="install-'.$versionId.'" class="install-container">';
+ foreach ($addonFiles as $file) {
+ // never display files with invalid statuses (bug 427176)
+ if (!in_array($file['status'], $valid_status)) continue;
+
+ // Used for echoing values in our loop
+ $_platform_name = '';
+ $_class_platform_string = '';
+ $_install_platform_string = '';
+
+ // ugh...
+ foreach ($platforms as $platform) {
+ // We found a matching platform
+ if ($platform['Platform']['id'] == $file['platform_id']) {
+ $_platform_name = $platform['Translation']['name']['string'];
+ }
+ }
+
+ if (!empty($_platform_name)) {
+ $_class_platform_string = "platform-{$_platform_name}";
+ if ($_platform_name != "ALL") {// special case
+ $_install_platform_string = "($_platform_name)";
+ }
+ }
+
+ // run the right javascript action for the addon type in question
+ $installTriggerName = "installTrigger" . $file['id'];
+
+ if ($addonType != ADDON_SEARCH) {
+ /* install for search */
+ if (in_array(APP_ID, $browser_apps)) {
+ // prepare link options for browser apps
+ $linkOptions = array(
+ 'id' => $installTriggerName,
+ 'title' => sprintf(_('install_button_title'), $addonName, APP_PRETTYNAME),
+ 'addonName' => $addonName,
+ 'addonIcon' => $addonIconPath,
+ 'addonHash' => $file['hash'],
+ 'jsInstallMethod' => 'browser_app_addon_install',
+ );
+ } else {
+ // prepare link options for non-browser apps
+ $linkOptions = array('id' => $installTriggerName,
+ 'title'=>sprintf(_('install_download'),$addonName));
+ }
+ } else {
+ /* prepare link options for search engines */
+ $linkOptions = array(
+ 'id' => $installTriggerName,
+ 'title' => sprintf(_('install_button_title'), $addonName, APP_PRETTYNAME),
+ 'engineURL' => FULL_BASE_URL . $html->urlFile($file['id'], $file['filename'], @$collection_uuid),
+ // search engines use a special install method
+ 'jsInstallMethod' => 'search_engine_install',
+ );
+ }
+ ?>
+
+ <?php
+ $install_button_html = '';
+ if (empty($addonEULA)) {
+ // wipe disallowed characters off the displayed filename
+ $addon_filename = $html->entities(preg_replace(
+ INVALID_FILENAME_CHARS, '_', $html->unsanitize($file['filename'])));
+
+ // if this is the latest public version, use perma-URL. Otherwise, link directly to file.
+ $linktitle = '<span><span><span><strong>'.sprintf(_('a_download'),$_install_platform_string).'</strong></span></span></span>';
+ if ($is_latest && $file['status'] == STATUS_PUBLIC) {
+ $latest_permalink = "/downloads/latest/{$addonId}";
+ if ($file['platform_id'] != PLATFORM_ALL) $latest_permalink .= "/platform:{$file['platform_id']}";
+
+ $file_id = $this->controller->File->getLatestFileByAddonId($addonId);
+ $file_data = $this->controller->File->findById($file_id);
+ $path_info = pathinfo($file_data['File']['filename']);
+
+ $latest_permalink .= "/addon-${addonId}-latest.".$path_info['extension'];
+
+ if (!empty($collection_uuid)) $latest_permalink .= "?collection_id={$collection_uuid}";
+
+ $install_button_html .= $html->link($linktitle, $latest_permalink, $linkOptions);
+ } else {
+ $install_button_html .= $html->linkFile($file['id'], $linktitle, null,
+ $linkOptions, false, $addon_filename, @$collection_uuid);
+ }
+ } else {
+ $eula_attributes = array('id' => $installTriggerName,
+ 'addonName' => $addonName,
+ 'title' => sprintf(_('install_button_title'), $addonName, APP_PRETTYNAME),
+ 'isEULAPageLink' => 'true');
+ $install_button_html .= $html->link('<span><span><span><strong>'
+ .sprintf(_('a_download'),$_install_platform_string)
+ .'</strong></span></span></span>',
+ "/addons/policy/0/{$addonId}/{$file['id']}",
+ $eula_attributes, false, false);
+ }
+
+ /**
+ * For logged-in users or public add-ons, show the standard install button.
+ */
+ if ($loggedin || !in_array($file['status'], $experimental_status) || (isset($is_eula_page) && isset($_GET['confirmed']))):
+ ?>
+ <p class="install-button <?=$_class_platform_string?>">
+ <?= $install_button_html ?>
+ </p>
+ <?php
+ /**
+ * For sandbox add-ons, show a frozen version of the standard install button.
+ * Users unfreeze the button client-side by checking a confirmation box.
+ * Non-JS users must unfreeze by logging in.
+ */
+ else:
+ ?>
+ <div class="exp-loggedout install">
+ <div class="exp-confirm-install" style="display: none">
+ <input type="checkbox" name="confirm-<?= $addonId ?>" />
+ <div class="exp-desc">
+ <label for="exp-confirm-install-checkbox-<?=$addonId?>"></label>
+ <span><?= sprintf(___('install_button_confirm_exp_install'), $html->url('/pages/faq#experimental-addons')) ?></span>
+ </div>
+ </div>
+
+ <p class="install-button <?=$_class_platform_string?>" style="display: none">
+ <?= $install_button_html ?>
+ </p>
+
+ <noscript>
+ <p class="install-button <?=$_class_platform_string?>">
+ <?php
+ $login_url = $html->login_url('/'.LANG.'/'.APP_SHORTNAME."/addon/{$addonId}", false);
+ $attributes = array('id' => $installTriggerName,
+ 'addonName' => $addonName,
+ 'title' => sprintf(_('install_button_title'), $addonName, APP_PRETTYNAME));
+ echo $html->link('<span><span><span><strong>'
+ .sprintf(_('a_download'),$_install_platform_string)
+ .'</strong></span></span></span>',
+ $login_url, $attributes, false, false);
+
+ $exp_addon_url = "/pages/faq#experimental-addons";
+ ?>
+ </p>
+ <?= sprintf(___('install_a_login_to_install'), $html->url($login_url), $html->url($exp_addon_url)); ?>
+ </noscript>
+ </div>
+ <?php endif; ?>
+ <script type="text/javascript">
+ installVersusDownloadCheck("<?=$installTriggerName?>", "<?=sprintf($buttonMessage, $_install_platform_string) ?>", "<?=sprintf(_('a_download'), $_install_platform_string)?>");
+ </script>
+ <?php
+ }
+ echo "</div>";
+
+ // show all add-on versions for all platforms on the
+ // "all versions" page
+ // This script will detect which install button should show, and hide the rest
+ echo '<script type="text/javascript">'.
+ 'setTimeout(function() {';
+ echo "initExpConfirm('{$versionId}');";
+ $versionsPage = false;
+ if (!($this->name == 'Addons' && $this->action == 'versions')) {
+ echo "fixPlatformLinks('{$versionId}', document.getElementById('{$installTriggerName}').getAttribute('addonName'));";
+ } else {
+ $versionsPage = true;
+ }
+
+ // show add-on compatibility hints for Firefox
+ if (APP_ID == APP_FIREFOX && !empty($compatible_apps)) {
+ $fromVer = $toVer = null;
+ foreach ($compatible_apps as $app) {
+ if ($app['Application']['application_id'] == APP_FIREFOX) {
+ $fromVer = $app['Min_Version']['version'];
+ $toVer = $app['Max_Version']['version'];
+ }
+ }
+ if ($fromVer && $toVer) {
+ // show "ignore" link for logged in users only
+ $_loggedin = $this->controller->Session->check('User');
+ echo "addCompatibilityHints('{$addonId}', '{$versionId}', "
+ ."'{$fromVer}', '{$toVer}', '{$_loggedin}', '{$versionsPage}');";
+ }
+
+ }
+ echo "},0);".
+ '</script>';
+ ?>
+
+
+<?php
+}
+?>
diff --git a/site/app/views/elements/noscript.thtml b/site/app/views/elements/noscript.thtml
new file mode 100644
index 0000000..0b847dd
--- /dev/null
+++ b/site/app/views/elements/noscript.thtml
@@ -0,0 +1,43 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Justin Scott <fligtar@mozilla.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+?>
+<noscript>
+ <div class="notice noscript rounded">
+ <span>JavaScript is required to use this page.</span><br />Please enable it before continuing.
+ </div>
+</noscript> \ No newline at end of file
diff --git a/site/app/views/elements/notification.thtml b/site/app/views/elements/notification.thtml
new file mode 100644
index 0000000..2bbeb1f
--- /dev/null
+++ b/site/app/views/elements/notification.thtml
@@ -0,0 +1,83 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Frederic Wenzel <fwenzel@mozilla.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/**
+ * Notification element
+ * Element for rendering a message to the user, usually towards the top of a page
+ *
+ * See views/addons/display.thtml for sample usage
+ *
+ * Required parameters:
+ * - (none), though $msg and/or $description make sense
+ *
+ * Optional parameters:
+ * - $type - type of notification - notification (default), info, success, warning, error
+ * - $msg - (short) message to be displayed in <h2> tags
+ * - $description - (longer) description text.
+ * - $htmlattributes - array (attribute=>value) with any html attributes to be
+ * added to the notification box
+ */
+
+if (empty($type) || !in_array($type, array('notification', 'info', 'success', 'warning', 'error')))
+ $type = 'notification';
+
+// prepare html attributes
+if (empty($htmlattributes)) $htmlattributes = array();
+if (isset($htmlattributes['class']))
+ $htmlattributes['class'] .= " notification-box {$type}";
+else
+ $htmlattributes['class'] = "notification-box {$type}";
+
+$_attributes = array();
+foreach($htmlattributes as $k => $v) {
+ $_attributes[] = "{$k}=\"{$v}\"";
+}
+$_attributes_string = implode(' ', $_attributes);
+
+
+?>
+<div <?=$_attributes_string?>>
+<?php
+if (!empty($msg)) {
+ echo "<h2>{$msg}</h2>\n";
+}
+if (!empty($description)) {
+ echo "<div>{$description}</div>\n";
+}
+?>
+</div>
diff --git a/site/app/views/elements/pagination.thtml b/site/app/views/elements/pagination.thtml
new file mode 100644
index 0000000..3745806
--- /dev/null
+++ b/site/app/views/elements/pagination.thtml
@@ -0,0 +1,71 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Frederic Wenzel <fwenzel@mozilla.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/**
+ * This element uses the following local variables:
+ * $countstring: (localized) string to wrap total results in, default "%s"
+ * $show_perpage: boolean (default true) show "results per page" links
+ */
+
+if (!isset($countstring))
+ $countstring = '';
+?>
+<div class="pagination">
+<?php
+if($pagination->setPaging($paging)):
+
+ $prev = $pagination->prevPage(_('pagination_previous_page'), false);
+ $next = $pagination->nextPage(_('pagination_next_page'), false);
+
+ $pages = $pagination->pageNumbers();
+?>
+ <ul class="pages">
+ <li class="prev"><?=$prev?></li>
+ <?=$pages?>
+ <li class="next"><?=$next?></li>
+ </ul>
+ <?php if (!empty($countstring)):?>
+ <p class="count"><?=$countstring?></p>
+ <?php endif; ?>
+ <?php if (!isset($show_perpage) || !$show_perpage): ?>
+ <p class="perpage">
+ <?=$pagination->resultsPerPage('').' '._('addon_list_perpage');?>
+ </p>
+ <?php endif; /* show "per page"? */ ?>
+<?php endif; /* paginated results? */ ?>
+</div>
diff --git a/site/app/views/elements/pitch.thtml b/site/app/views/elements/pitch.thtml
new file mode 100644
index 0000000..b7c96f0
--- /dev/null
+++ b/site/app/views/elements/pitch.thtml
@@ -0,0 +1,81 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Frederic Wenzel <fwenzel@mozilla.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/**
+ * This element uses the following local variables:
+ * (none)
+ */
+
+// display appropriate links for browser/non-browser apps
+global $browser_apps;
+if (in_array(APP_ID, $browser_apps)) {
+ $pitch_links = array(
+ '/browse/type:'.ADDON_THEME.'/cat:all?sort=name' => _('sidebar_pitch_theme'),
+ '/browse/type:'.ADDON_SEARCH.'/cat:all?sort=name' => _('sidebar_pitch_search'),
+ '/browse/type:'.ADDON_DICT => _('sidebar_pitch_dictionary')
+ );
+} else {
+ $pitch_links = array(
+ '/browse/type:'.ADDON_THEME.'/cat:all?sort=name' => _('sidebar_pitch_theme'),
+ '/browse/type:'.ADDON_DICT => _('sidebar_pitch_dictionary')
+ );
+}
+
+?>
+<div class="pitch">
+ <h3><?=_('sidebar_pitch_looking_for')?></h3>
+ <ul>
+ <?php foreach ($pitch_links as $_url => $_text): ?>
+ <li><a href="<?=$html->url($_url)?>"><?=$_text?></a></li>
+ <?php endforeach; ?>
+ </ul>
+ <?php
+ // RSS links the hard way, bug 426541
+ $subscribeHeader = ___('sidebar_pitch_subscribe_to');
+ $newestLink = ___('sidebar_pitch_newest_addons');
+ $updatedLink = ___('sidebar_pitch_updated_addons');
+ $featuredLink = ___('sidebar_pitch_featured_addons');
+ ?>
+ <br/>
+ <h3><?=$subscribeHeader?></h3>
+ <ul class="naked">
+ <li><a href="<?=$html->url('/browse/type:1/cat:all/format:rss?sort=newest')?>"><img src="<?=$html->url('/img/tinyRss.png', null, false, false)?>" alt=""/></a> <a href="<?=$html->url('/browse/type:1/cat:all/format:rss?sort=newest')?>"><?=$newestLink?></a></li>
+ <li><a href="<?=$html->url('/browse/type:1/cat:all/format:rss?sort=updated')?>"><img src="<?=$html->url('/img/tinyRss.png', null, false, false)?>" alt=""/></a> <a href="<?=$html->url('/browse/type:1/cat:all/format:rss?sort=updated')?>"><?=$updatedLink?></a></li>
+ <li><a href="<?=$html->url('/recommended/format:rss')?>"><img src="<?=$html->url('/img/tinyRss.png', null, false, false)?>" alt=""/></a> <a href="<?=$html->url('/recommended/format:rss')?>"><?=$featuredLink?></a></li>
+ </ul>
+</div>
diff --git a/site/app/views/elements/recaptcha.thtml b/site/app/views/elements/recaptcha.thtml
new file mode 100644
index 0000000..cade4a9
--- /dev/null
+++ b/site/app/views/elements/recaptcha.thtml
@@ -0,0 +1,95 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Frederic Wenzel <fwenzel@mozilla.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+// note that this element requires the current controller to import the
+// Recaptcha component.
+
+if (isset($this->controller->Recaptcha) && $this->controller->Recaptcha->enabled):
+ $shortlang = explode('-', LANG, 2);
+ $shortlang = $shortlang[0];
+ // @XXX we should provide help for all languages, not just the ones Recaptcha supports
+ if (!in_array($shortlang, array('en', 'nl', 'fr', 'de', 'pt', 'ru', 'es', 'tr')))
+ $shortlang = 'en';
+
+ // pick Recaptcha API server based on SSL/non-SSL status
+ if (isset($_SERVER['HTTPS']) && !empty($_SERVER['HTTPS']))
+ $recaptcha_server = 'https://api-secure.recaptcha.net';
+ else
+ $recaptcha_server = 'http://api.recaptcha.net';
+?>
+ <script type="text/javascript">
+ var RecaptchaOptions = {
+ theme : 'custom',
+ custom_theme_widget : 'recaptcha_widget',
+ lang : '<?=$shortlang?>'
+ };
+ </script>
+
+ <div id="recaptcha_widget" style="display:none">
+ <?php /* image captcha text */ ?>
+ <div class="recaptcha_description recaptcha_only_if_image"><?=___('recaptcha_enter_both_words',
+ 'Please enter <strong>both words</strong> below, <strong>separated by a space</strong>.')?></div>
+ <div class="recaptcha_refresh recaptcha_only_if_image">
+ <?=sprintf(___('recaptcha_hardtoread_text', 'If this is hard to read, you '
+ .'can <a href="%1$s">try different words</a> or <a href="%2$s">listen '
+ .'to something</a> instead.'), 'javascript:Recaptcha.reload()',
+ "javascript:Recaptcha.switch_type('audio')")?>
+ </div>
+ <?php /* audio captcha text */ ?>
+ <div class="recaptcha_description recaptcha_only_if_audio"><?=___('recaptcha_enter_whatyouhear',
+ 'Please type what you hear.')?></div>
+ <div class="recaptcha_refresh recaptcha_only_if_audio">
+ <?=sprintf(___('recaptcha_hardtohear_text', 'If this is hard to understand, '
+ .'you can <a href="%1$s">listen to something else</a> or <a href="%2$s">'
+ .'switch back to text</a>.'), 'javascript:Recaptcha.reload()',
+ "javascript:Recaptcha.switch_type('image')")?>
+ </div>
+ <div id="recaptcha_image"></div>
+ <div class="recaptcha_response"><?=___('recaptcha_enter_here', 'Enter your answer here:')?>
+ <input type="text" id="recaptcha_response_field" name="recaptcha_response_field"/></div>
+ </div>
+ <script type="text/javascript" src="<?=$recaptcha_server?>/challenge?k=<?=RECAPTCHA_PUBLIC_KEY?>&lang=<?=$shortlang?>"></script>
+
+ <noscript>
+ <iframe src="<?=$recaptcha_server?>/noscript?k=<?=RECAPTCHA_PUBLIC_KEY?>&lang=<?=$shortlang?>"
+ height="300" width="500" frameborder="0"></iframe><br>
+ <textarea name="recaptcha_challenge_field" rows="3" cols="40"></textarea>
+ <input type="hidden" name="recaptcha_response_field" value="manual_challenge">
+ </noscript>
+
+<?php endif; ?>
diff --git a/site/app/views/elements/rss_listitem.thtml b/site/app/views/elements/rss_listitem.thtml
new file mode 100644
index 0000000..e73a5d8
--- /dev/null
+++ b/site/app/views/elements/rss_listitem.thtml
@@ -0,0 +1,60 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Frederic Wenzel <fwenzel@mozilla.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+
+/**
+ * This element uses the following local variables:
+ * - $title
+ * - $url
+ * - $description
+ * - $author
+ * - $pubDate
+ * - $permalink = guid, optional
+ * - $isPermaLink, bool, optional, default false (if true, news readers link to $permalink, otherwise to $url)
+ */
+
+?>
+
+<item>
+ <title><?=$title?></title>
+ <link><?=$url?></link>
+ <description><?=$description?></description>
+ <author><?=$author?></author>
+ <pubDate><?=$pubDate?></pubDate>
+ <?php if (isset($permalink)): ?><guid isPermaLink="<?=(isset($isPermaLink)&&$isPermaLink)?'true':'false'?>"><?=$permalink?></guid><?php endif; ?>
+</item>
diff --git a/site/app/views/elements/search.thtml b/site/app/views/elements/search.thtml
new file mode 100644
index 0000000..755af51
--- /dev/null
+++ b/site/app/views/elements/search.thtml
@@ -0,0 +1,325 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Mike Morgan <morgamic@mozilla.com> (Original Author)
+ * Cameron Roy <licensing@justcameron.com>
+ * Frederic Wenzel <fwenzel@mozilla.com>
+ * Chris Pollett <cpollett@gmail.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+?>
+<?php
+/**
+ * This element uses the following local variables:
+ * $query: query string to be displayed in the text box, defaults to "search for add-ons"
+ * $category: category ID to be selected
+ */
+
+// set-up arrays for advance search select tags
+// also set-up default values (or use previous search params) for each advance-search field
+global $app_shortnames, $app_prettynames;
+$applications = array();
+foreach ($app_shortnames as $name => $key) {
+ $applications[$key] = $app_prettynames[$name];
+}
+if (!isset($appid)) {
+ $appid = APP_ID;
+}
+
+$min_display_version_by_app = array( // eventually this information should be kept in DB
+ APP_FIREFOX => "1.0",
+ APP_THUNDERBIRD => "1.0",
+ APP_SEAMONKEY => "1.0",
+ APP_SUNBIRD => "0.2"
+);
+
+$new_versions = array();
+foreach ($app_shortnames as $n => $k) {
+// AmoVersions is from controller->beforeRender()
+ if (!empty($AmoVersions[$k])) foreach ($AmoVersions[$k] as $version) {
+ $versions_parts = explode(".", $version);
+ $second_part = (isset($versions_parts[1])) ? ".".intval($versions_parts[1]) : "";
+ if (!isset($min_display_version_by_app[$k])
+ || $min_display_version_by_app[$k] <= $versions_parts[0].$second_part ) {
+
+ if ($k != APP_FIREFOX || !in_array($versions_parts[0].$second_part, array('1.4','3.1'))) { // yuck. Baz didn't like FF 1.4. Nick didn't like FF 3.1.
+ $new_versions[$k][] = $versions_parts[0].$second_part;
+ }
+ }
+ }
+ if (!empty($new_versions[$k]))
+ $new_versions[$k] = array_unique($new_versions[$k]);
+}
+$versions = $new_versions;
+
+if(!isset($lver)) {
+ $lver = "";
+}
+
+if(!isset($hver)) {
+ $hver = "";
+}
+
+// AmoPlatforms is from controller->beforeRender()
+array_shift($AmoPlatforms); // get rid of PLATFORM_ALL
+$platforms = array_merge(array(PLATFORM_ANY => ___('advanced_search_form_any_type')), $AmoPlatforms); //add semantically happy PLATFORM_ANY
+$pid = 0;
+if (isset($this->params['url']['pid'])
+ && in_array($this->params['url']['pid'], array_keys($platforms))) {
+
+ $pid = $this->params['url']['pid'];
+}
+
+// AmoAddonTypes is from controller->beforeRender()
+// for now we want to get rid of Plugin and Language packs since the former
+// goes to a static page and the latter is empty
+array_pop($AmoAddonTypes);
+array_pop($AmoAddonTypes);
+$addon_types = array_merge(array(ADDON_ANY => ___('advanced_search_form_any_type')), $AmoAddonTypes);
+if (!isset($atype)) {
+ $atype = ADDON_ANY;
+}
+
+$page_arr = $this->controller->Pagination->resultsPerPage;
+$pages = array();
+foreach ($page_arr as $page) {
+ $pages[$page] = $page;
+}
+
+if (!isset($pp)) {
+ $pp = $this->controller->Pagination->show;
+}
+
+$updates = array(
+ "" => ___('advanced_search_form_any_time'),
+ '- INTERVAL 1 DAY' => ___('advanced_search_form_past_day'),
+ '- INTERVAL 1 WEEK' => ___('advanced_search_form_past_week'),
+ '- INTERVAL 1 MONTH' => ___('advanced_search_form_past_month'),
+ '- INTERVAL 3 MONTH' => ___('advanced_search_form_past_3_months'),
+ '- INTERVAL 6 MONTH' => ___('advanced_search_form_past_6_months'),
+ '- INTERVAL 1 YEAR' => ___('advanced_search_form_past_year')
+);
+
+$lup = "";
+if (isset($this->params['url']['lup'])
+ && in_array($this->params['url']['lup'], array_keys($updates))) {
+
+ $lup = $this->params['url']['lup'];
+}
+
+$sort_orders = array(
+ '' => ___('advanced_search_form_keyword_match'),
+ 'newest' => ___('advanced_search_form_newest'),
+ 'name' => ___('advanced_search_form_name'),
+ 'averagerating' => ___('advanced_search_form_rating'),
+ 'weeklydownloads' => ___('advanced_search_form_popularity')
+);
+if (!isset($sort)) {
+ $sort = "";
+}
+
+
+// handles toggling advanced search form when JS not enabled
+
+$toggle_uri = $_SERVER['REQUEST_URI'];
+
+if (isset($this->params['url']['adv']) || isset($this->params['url']['as'])) {
+ $toggle_uri = str_replace("adv=", "nor=", $toggle_uri);
+ $toggle_uri = str_replace("as=", "nor=", $toggle_uri);
+ $two_form = "";
+} else {
+ $toggle_uri = str_replace("nor=", "adv=", $toggle_uri);
+ $delim = (stristr($toggle_uri,"?")) ? "&" : "?";
+ if(!stristr($toggle_uri, "adv=")) { $toggle_uri .= "{$delim}adv=true"; }
+ $two_form = "</form><form method=\"get\" action=\"\" id=\"hidden-form\" class=\"asclosed\">";
+}
+$toggle_uri = htmlspecialchars($toggle_uri);
+
+// prepare query string
+if (!isset($query) || !is_string($query))
+ $query = _('search_form_default_text');
+
+// prepare selected category, "all" if not set
+if (!isset($category)) $category = array(0, 0);
+?>
+<div id="search-element">
+<div id="search-bubble-outer">
+<div id="search-bubble-inner"></div>
+<form id="search-form" method="get" action="<?=$html->url("/search")?>">
+ <fieldset id="standard-search">
+ <legend>Standard Search</legend>
+
+ <span id="search-query"><label for="query" title="<?=___('search_form_tooltip')?>"><?=___('search_form_default_text')?></label>
+ <input type="text" id="query" name="q" value="<?=$query?>"/></span>
+ <label for="category"><?=___('search_form_within')?></label>
+ <select id="category" name="cat">
+ <option value="all"<?=($category[0]==0 ? ' selected="selected"' : '')?>><?=_('search_form_all_addons')?></option>
+ <?php
+ // AmoVersions is from controller->beforeRender()
+ foreach ($AmoTags as $tag):
+ // skip "plugins" as it is a static page at the moment and thus
+ // cannot be searched here
+ if ($tag['type'] == ADDON_PLUGIN) continue;
+
+ if ($category[0] == $tag['type'] && ($category[1]==$tag['cat'] || $tag['cat']==0))
+ $sel = ' selected="selected"';
+ else
+ $sel = '';
+ ?>
+ <option value="<?=$tag['type'].','.$tag['cat']?>"<?=$sel?>><?=$html->entities($tag['name'])?></option>
+ <?php endforeach; ?>
+ </select><?=$html->submit(" ", array('id'=>'my-submit', 'title' => ___('search_form_submit_tooltip'))); ?>
+ </fieldset>
+ <?=$two_form; ?>
+ <fieldset id="advanced-search" >
+ <legend>Advanced Search</legend>
+ <fieldset id="search-application">
+ <input type="hidden" name="as" value="true" />
+ <input type="hidden" id="vfuz" name="vfuz" value="false" />
+ <table>
+ <tr>
+ <td><?=___('advanced_search_form_application'); ?>:</td>
+ <td><?php $html->simpleSelectTag('appid', $applications, $appid, array(), array(), false)?></td>
+ <td><?=___('advanced_search_form_version'); ?></td><td id="lver-td">
+ <input name="lver" type="text" size="5" maxlength="10" value="<?=$lver ?>" /></td>
+ <td><?=___('advanced_search_form_to'); ?></td><td id="hver-td">
+ <input name="hver" type="text" size="5" maxlength="10" value="<?=$hver ?>" /></td>
+ </tr>
+ </table>
+ </fieldset>
+ <fieldset id="search-platform">
+ <table>
+ <tr><td><?=___('advanced_search_form_type'); ?>:</td><td><?php $html->simpleSelectTag('atype', $addon_types, $atype, array(), array(), false); ?></td></tr>
+ <tr><td><?=___('advanced_search_form_platform'); ?>:</td><td><?php $html->simpleSelectTag('pid', $platforms, $pid, array(), array(), false); ?></td></tr>
+ <tr><td><?=___('advanced_search_form_lastupdate'); ?>:</td><td><?php $html->simpleSelectTag('lup', $updates, $lup, array(), array(), false); ?></td></tr>
+ </table>
+ </fieldset>
+ <fieldset id="search-output">
+ <table>
+ <tr><td><?=___('advanced_search_form_perpage'); ?>:</td><td><?php $html->simpleSelectTag('pp', $pages, $pp, array(), array(), false); ?></td></tr>
+ <tr><td><?=___('advanced_search_form_sortby'); ?>:</td><td><?php $html->simpleSelectTag('sort', $sort_orders, $sort, array(), array(), false); ?></td></tr>
+ </table>
+ </fieldset>
+ </fieldset>
+</form>
+</div>
+<div id="advanced-search-toggle" title="<?=___('advanced_search_form_toggle_tooltip');?>">
+ <div></div>
+ <span id="toggle-outer"><span id="toggle-inner"><!--[if IE]>&nbsp;<![endif]--></span><a id="advanced-search-toggle-link" href="<?=$toggle_uri; ?>" class="asclosed"><?php echo ___('advanced_search_form'); ?></a></span>
+</div>
+</div>
+<script type="text/javascript">
+// <![CDATA[
+
+<?php
+ echo "versions = new Array();\n";
+ foreach($versions as $application_id => $ver_array) {
+ echo "versions[{$application_id}] = {";
+ foreach ($ver_array as $version) {
+ if($version !="") {
+ echo "\"{$version}\": \"{$version}\", ";
+ }
+ }
+ echo "'".___('advanced_search_form_any_version')."' : 'any' };\n";
+ }
+
+ // to get default version value set up correctly needed to do after $appid, $lver and $hver set-up above in this element
+ // that's why this code is not in mozilla.thtml
+
+ //we re-set these up for the JS case (originally did non-JS case)
+
+ $oldver = $lver;
+ $lver = ($lver == "") ? "'any'" : '"'.$lver.'"' ;
+ $hver = ($hver == "") ? "'any'" : '"'.$hver.'"' ;
+
+ // JS to do browser detection to determine default low range to be current browser if applicable
+?>
+
+ var current_app_id = 0;
+ var uapattern = /Mozilla.*(?:Firefox|Minefield|Shiretoko|GranParadiso|BonEcho|Iceweasel)\/([^\s]*).*$/;
+ var ua = navigator.userAgent;
+ var uamatch = uapattern.exec(ua);
+ if (uamatch != null) {
+ version = uamatch[1].split(".");
+ low_appversion = version[0]+"."+parseInt(version[1]);
+ current_app_id = <?=APP_FIREFOX ?>;
+ }
+
+ uapattern = /Mozilla.*(?:SeaMonkey|Iceape)\/([^\s]*).*$/;
+ ua = navigator.userAgent;
+ uamatch = uapattern.exec(ua);
+ if (uamatch != null) {
+ version = uamatch[1].split(".");
+ low_appversion = version[0]+"."+parseInt(version[1]);
+ current_app_id = <?=APP_SEAMONKEY ?>;
+ }
+
+ default_low = ('<?=$oldver ?>' == '' && current_app_id == <?=APP_ID; ?>) ? low_appversion : <?=$lver ?>;
+
+ <?php
+ /*
+ Replace the non-JS textfields with select's. Since we only approximately list version names in the dropdown, we want to use fuzzy version
+ matching on server. Add a hidden field to indicate this.
+ */
+ ?>
+
+ $("#lver-td input").remove();
+ $("#hver-td input").remove();
+
+ var verArr = versions[<?= $appid ?>];
+
+ $("#vfuz").val(true);
+
+ var lverSel = document.createElement("select");
+ lverSel.id = "lver";
+ lverSel.name = "lver";
+ $("#lver-td").append(lverSel);
+ replaceOptions("#lver", verArr, default_low);
+
+ var hverSel = document.createElement("select");
+ hverSel.id = "hver";
+ hverSel.name = "hver";
+ $("#hver-td").append(hverSel);
+ replaceOptions("#hver", verArr, <?=$hver ?>);
+
+ $("#appid").change(function () {
+ selected_app_id = $("#appid option:selected").attr("value");
+ default_low = (selected_app_id == current_app_id) ? low_appversion : 'any';
+ verArr = versions[selected_app_id];
+ replaceOptions("#lver", verArr, default_low);
+ replaceOptions("#hver", verArr, 'any');
+ });
+
+ // ]]>
+</script>
diff --git a/site/app/views/elements/search_mini.thtml b/site/app/views/elements/search_mini.thtml
new file mode 100644
index 0000000..be88204
--- /dev/null
+++ b/site/app/views/elements/search_mini.thtml
@@ -0,0 +1,72 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Ryan Doherty <rdoherty@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+?>
+
+<?php
+// prepare query string
+if (!isset($query) || !is_string($query))
+ $query = _('search_form_default_text');
+?>
+
+<div id="search-mini">
+ <form id="" method="get" action="<?=$html->url("/search")?>">
+ <span id="search-query">
+ <label for="query" title="<?=___('search_form_tooltip')?>"><?=___('search_form_default_text')?></label>
+ <input type="text" id="query" name="q" value="<?=$query?>"/>
+ </span>
+ <label for="category"><?=___('search_form_within')?></label>
+ <select id="category" name="cat">
+ <option value="all"<?=($category[0]==0 ? ' selected="selected"' : '')?>><?=_('search_form_all_addons')?></option>
+ <?php
+ // AmoVersions is from controller->beforeRender()
+ foreach ($AmoTags as $tag):
+ // skip "plugins" as it is a static page at the moment and thus
+ // cannot be searched here
+ if ($tag['type'] == ADDON_PLUGIN) continue;
+
+ if ($category[0] == $tag['type'] && ($category[1]==$tag['cat'] || $tag['cat']==0))
+ $sel = ' selected="selected"';
+ else
+ $sel = '';
+ ?>
+ <option value="<?=$tag['type'].','.$tag['cat']?>"<?=$sel?>><?=$html->entities($tag['name'])?></option>
+ <?php endforeach; ?>
+ </select>
+ <button type="submit" id="search-mini-submit"><?= _('search'); ?></button>
+ </form>
+</div> \ No newline at end of file
diff --git a/site/app/views/elements/sidebar.thtml b/site/app/views/elements/sidebar.thtml
new file mode 100644
index 0000000..593e9a0
--- /dev/null
+++ b/site/app/views/elements/sidebar.thtml
@@ -0,0 +1,57 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Mike Morgan <morgamic@mozilla.com> (Original Author)
+ * Frederic Wenzel <fwenzel@mozilla.com>
+ * Justin Scott <fligtar@gmail.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/**
+ * This element uses the following local variables:
+ * - $highlight tag array of category to be highlighted
+ * - $pitch - (bool, default: false) add MDC tutorial stuff
+ */
+
+if (!isset($highlight)) $highlight = null;
+if (!isset($pitch)) $pitch = false;
+?>
+
+<div id="sidebar">
+
+<?=$this->renderElement('categories', array('highlight'=>$highlight))?>
+
+<?php if ($pitch) echo $this->renderElement('pitch'); ?>
+
+</div><!-- /#sidebar -->
diff --git a/site/app/views/elements/stars.thtml b/site/app/views/elements/stars.thtml
new file mode 100644
index 0000000..ef71844
--- /dev/null
+++ b/site/app/views/elements/stars.thtml
@@ -0,0 +1,67 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Mike Morgan <morgamic@mozilla.com> (Original Developer)
+ * Frederic Wenzel <fwenzel@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+?>
+<?php
+ /**
+ * This element uses the following local variables:
+ * - $addonRating - averagerating from an addon record, must be numeric
+ */
+
+if (is_numeric($rating) && $rating > 0) {
+
+ if ($rating > 5) {
+ $stars = ceil($rating/2);
+ } else {
+ $stars = ceil($rating);
+ }
+
+$msg = sprintf(_('stars_rated_x_outof_5'), $stars);
+?>
+
+<img src="<?=$html->urlImage("/ratings/{$stars}stars.png")?>" width="68" height="12" alt="" title="<?=$msg?>"/>
+
+<?php
+} else {
+?>
+
+<?=_('stars_not_yet_rated')?>
+
+<?php
+}
+?>
diff --git a/site/app/views/elements/translationbox.thtml b/site/app/views/elements/translationbox.thtml
new file mode 100644
index 0000000..f72f876
--- /dev/null
+++ b/site/app/views/elements/translationbox.thtml
@@ -0,0 +1,158 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Justin Scott <fligtar@mozilla.com> (Original Author)
+ * Frederic Wenzel <fwenzel@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/**
+ * Translation Box
+ * Element for rendering a translation box with tabs for the locales. Requires
+ * $this->translationBox be set with defaultLocale, languages, table, and loaded.
+ *
+ * See app/views/developers/addon_edit_descriptions.thtml for sample usage
+ *
+ * Required parameters:
+ * - $field - name of the field
+ * - $translations - array in form of 'en-US' => 'Translation'
+ *
+ * Optional parameters:
+ * - $id - the db id of the object if multiple will be on the same page
+ * - $type - type of field - textbox or textarea (default)
+ * - $width - width of the field, defaults to 600px
+ * - $height - height of the field, defaults to 20 for textboxes and 100 for textareas
+ * - $maxLength - maximum number of characters for a field
+ * - $displayName - the name of the field for the header
+ * - $description - description of the field
+ * - $graybox - whether to display in a graybox
+ * - $extraclass - extra content for the class attribute of the enclosing div
+ */
+
+if (!isset($graybox) || $graybox === true) {
+ echo '<div class="translation-box graybox rounded spaced" style="width: '.(!empty($width) ? $width : '600px').';">';
+} else {
+ echo '<div class="translation-box'.(isset($extraclass)?' '.$extraclass:'').'">';
+}
+ echo (!empty($displayName) ? '<h4><a href="#" title="'.___('devcp_transbox_a_title_help').'" onclick="translation_box.showHelp(this); return false;">'.$html->image('developers/help.png', array('alt' => ___('devcp_transbox_alt_help'))).'</a>'.$displayName.' </h4>' : '');
+ echo (!empty($description) ? "<p>{$description}</p>" : '');
+ ?>
+ <div class="translation-row">
+ <div class="translation-tabs">
+ <?php
+ // Make sure default locale is present
+ if (!array_key_exists($this->translationBox['defaultLocale'], $translations)) {
+ $translations[$this->translationBox['defaultLocale']] = '';
+ }
+
+ foreach ($translations as $locale => $translation) {
+ echo '<div class="translation-tab'.($this->translationBox['defaultLocale'] == $locale ? ' selected' : '').'" onclick="translation_box.switchLocale(this, \''.$locale.'\');" title="'.$this->translationBox['languages'][$locale].'">';
+ echo $locale.'</div>';
+ }
+ ?>
+ </div>
+ <div class="translation-button"><?=$html->image('developers/tab_add.png', array('onclick' => 'translation_box.addTab(this);', 'alt' => ___('devcp_transbox_img_add_trans'), 'title' => ___('devcp_transbox_img_add_trans')))?></div>
+ <div class="translation-button remove" style="display: none;"><?=$html->image('developers/tab_delete.png', array('onclick' => 'translation_box.confirmRemove(this);', 'alt' => ___('devcp_transbox_img_remove_trans'), 'title' => ___('devcp_transbox_img_remove_trans')))?></div>
+ </div>
+ <div class="translation-area" table="<?=$this->translationBox['table']?>" field="<?=$field?>" defaultLocale="<?=$this->translationBox['defaultLocale']?>"<?=(!empty($id) ? ' itemID="'.$id.'"' : '')?>>
+ <?php
+ foreach ($translations as $locale => $translation) {
+ $fieldName = "data[{$this->translationBox['table']}]".(!empty($id) ? "[{$id}]" : '')."[{$field}][{$locale}]";
+
+ if (empty($type) || $type == 'textarea') {
+ echo '<textarea class="input '.$locale.($this->translationBox['defaultLocale'] == $locale ? ' selected' : '').'" name="'.$fieldName.'" cols="" rows="" style="height: '.(!empty($height) ? $height : '100').'px;"'.(!empty($maxLength) ? ' maxlength="'.$maxLength.'" onkeyup="translation_box.checkLength(this, '.$maxLength.');" onchange="translation_box.checkLength(this, '.$maxLength.');"' : '').'>'.$translation.'</textarea>';
+ }
+ elseif ($type == 'textbox') {
+ echo '<input type="text" class="input '.$locale.($this->translationBox['defaultLocale'] == $locale ? ' selected' : '').'" name="'.$fieldName.'" value="'.$html->entities($translation).'" style="height: '.(!empty($height) ? $height : '20').'px;" '.(!empty($maxLength) ? ' maxlength="'.$maxLength.'"' : '').' />';
+ }
+
+ if (!empty($maxLength)) {
+ echo '<div class="translation-maxlength '.$locale.($this->translationBox['defaultLocale'] == $locale ? ' selected' : '').'">'.$html->image('developers/exclamation.png', array('alt' => '')).sprintf(___('devcp_transbox_chars_used'), '<span>'.strlen($translation).'</span>', $maxLength).'</div>';
+ }
+ }
+ ?>
+ </div>
+
+</div>
+
+<?php if (!$this->translationBox['loaded']): ?>
+<div class="translation-newlocale-container">
+ <div class="translation-newlocale new selected">
+ <div class="padded">
+ <?=___('devcp_transbox_select_locale')?>
+ <select>
+ <?php
+ foreach ($this->translationBox['languages'] as $code => $name) {
+ echo '<option value="'.$code.'">'.$name.' ('.$code.')</option>';
+ }
+ ?>
+ </select>
+ <div class="buttons">
+ <input type="button" value="<?=___('devcp_transbox_input_add_locale')?>" onclick="translation_box.addLocale(this, false);" />
+ <input type="button" value="<?=___('devcp_transbox_input_add_all')?>" onclick="translation_box.addLocale(this, true);" />
+ <input type="button" value="<?=___('devcp_transbox_input_cancel')?>" onclick="translation_box.cancelAdd(this);" />
+ </div>
+ </div>
+ </div>
+</div>
+<div class="translation-deletelocale-container">
+ <div class="translation-deletelocale">
+ <div class="padded">
+ <?=___('devcp_transbox_delete_sure')?>
+ <div class="buttons">
+ <input type="button" value="<?=___('devcp_transbox_input_delete')?>" onclick="translation_box.removeLocale(this);" />
+ <input type="button" value="<?=___('devcp_transbox_input_cancel')?>" onclick="translation_box.cancelRemove(this);" />
+ </div>
+ </div>
+ </div>
+</div>
+<div class="translation-help-container">
+ <div class="translation-help bluebox-tr"><div class="bluebox-tl">
+ <div class="padded">
+ <h4><?=sprintf(___('devcp_transbox_help_header_tabs'), $this->translationBox['defaultLocale'])?></h4>
+ <p><?=___('devcp_transbox_help_transbox')?></p>
+ <h4><?=___('devcp_transbox_help_header_what')?></h4>
+ <p><?=___('devcp_transbox_help_if')?>
+ <div style="text-align: right;"><a href="#" onclick="translation_box.hideHelp(this); return false;"><?=___('devcp_transbox_help_hide')?></a></div>
+ </div>
+ <div class="bluebox-br"><div class="bluebox-bl"></div></div>
+ </div></div>
+</div>
+<div class="translation-error-container">
+ <div class="translation-error error-message rounded"></div>
+</div>
+<?php
+ $this->translationBox['loaded'] = true;
+ endif;
+?>
diff --git a/site/app/views/errors/error401.thtml b/site/app/views/errors/error401.thtml
new file mode 100644
index 0000000..cb2763e
--- /dev/null
+++ b/site/app/views/errors/error401.thtml
@@ -0,0 +1,55 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Mike Morgan <morgamic@mozilla.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+?>
+
+<? $this->controller->disableCache(); ?>
+<? $this->layout='mozilla'; // use regular layout ?>
+
+<div id="content">
+ <?=$this->renderElement('search')?>
+ <?=$this->renderElement('sidebar', array('pitch' => true))?>
+ <?=$this->renderElement('app_chooser')?>
+
+ <div id="content-main">
+
+<h1><?=_('error_access_denied')?></h1>
+<br/>
+<p><?=_('error_access_denied_message')?></p>
+
+ </div>
+</div>
diff --git a/site/app/views/errors/error404.thtml b/site/app/views/errors/error404.thtml
new file mode 100644
index 0000000..42a3a09
--- /dev/null
+++ b/site/app/views/errors/error404.thtml
@@ -0,0 +1,75 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Frederic Wenzel <fwenzel@mozilla.com> (Original Author)
+ * Wil Clouser <wclouser@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+$this->controller->disableCache();
+//if ($_SERVER['SERVER_NAME'] == 'services.addons.mozilla.org') {
+if ($_SERVER['SERVER_NAME'] == 'localhost') {
+// services 404s need to return XML
+ $this->layout = 'rest';
+ ?>
+ <error>404</error>
+ <?php
+} else {
+
+$this->layout='amo2009'; // use regular layout
+?>
+<div class="secondary" role="complementary">
+ <?=$this->renderElement('amo2009/categories')?>
+</div>
+
+<div class="primary prose" role="main">
+ <?=$this->renderElement('amo2009/search')?>
+
+<div class="error-notice">
+
+<?php
+ loadHelper('Localization');
+ $localization =& new LocalizationHelper();
+ loadHelper('AddonsHtml');
+ $html =& new AddonsHtmlHelper();
+
+ echo $localization->includeLocalPage('error404',
+ array($html->url('/recommended'),
+ $html->url('/search'),
+ $html->url('/')));
+?>
+</div>
+
+</div>
+<?php } ?>
diff --git a/site/app/views/errors/missing_controller.thtml b/site/app/views/errors/missing_controller.thtml
new file mode 120000
index 0000000..addca8f
--- /dev/null
+++ b/site/app/views/errors/missing_controller.thtml
@@ -0,0 +1 @@
+error404.thtml \ No newline at end of file
diff --git a/site/app/views/facebook/admin.thtml b/site/app/views/facebook/admin.thtml
new file mode 100644
index 0000000..e6d739f
--- /dev/null
+++ b/site/app/views/facebook/admin.thtml
@@ -0,0 +1,80 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Justin Scott <fligtar@mozilla.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+?>
+<style>
+ .body {
+ padding: 10px;
+ }
+ h1 {
+ border-bottom: 1px solid #d8dfea;
+ margin: 5px 10px;
+ padding-bottom: 2px;
+ font-size: 13px;
+ color: #333333;
+ }
+</style>
+
+<div class="body">
+<?php
+ if ($action == '') {
+ echo '<h1>Admin</h1>';
+ echo '<li><a href="'.FB_URL.'/admin/flushCache">Flush Cache</a></li>';
+ echo '<li><a href="'.FB_URL.'/admin/activeUsers">Active User Stats</a></li>';
+ }
+ elseif ($action == 'flushCache') {
+ echo '<h1>Admin: Flush Cache</h1>';
+ foreach ($urls as $url) {
+ echo "Flushed {$url}<br>";
+ }
+ }
+ elseif ($action == 'activeUsers') {
+ echo '<h1>Admin: Active User Stats</h1>';
+ echo "Active users in the last 1 day: {$activeUsers['last_1d']}<br>";
+ echo "Active users in the last 1 hour: {$activeUsers['last_1h']}<br>";
+ echo "Active users in the last 10 minutes: {$activeUsers['last_10m']}<br>";
+ echo "Active users in the last 5 minutes: {$activeUsers['last_5m']}<br>";
+ echo "Active users in the last 1 minute: {$activeUsers['last_1m']}<br>";
+ echo "Active users in the last 30 seconds: {$activeUsers['last_30s']}<br>";
+ echo "Active users in the last 1 second: {$activeUsers['last_1s']}<br><br>";
+ echo "Users that added app in the last 1 day: {$activeUsers['add_1d']}<br><br>";
+ echo "Users that removed app in the last 1 day: {$activeUsers['remove_1d']}<br><br>";
+ echo "Total current users: <span id=\"total\">{$activeUsers['total']}</span><br><br>";
+ echo "Total ever users: <span id=\"ever\">{$activeUsers['ever']}</span>";
+ }
+?>
+</div> \ No newline at end of file
diff --git a/site/app/views/facebook/browse.thtml b/site/app/views/facebook/browse.thtml
new file mode 100644
index 0000000..801aee6
--- /dev/null
+++ b/site/app/views/facebook/browse.thtml
@@ -0,0 +1,88 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Justin Scott <fligtar@mozilla.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+?>
+
+<div class="sort_box">
+ <form action="<?=FB_URL?>/browse/type:<?=$current['type']?>" method="get">
+ Sort by:
+ <select name="sort">
+ <?php
+ $sorting = array('popular' => 'Most Popular',
+ 'rated' => 'Highest Rated',
+ 'name' => 'Name');
+ foreach ($sorting as $sortVal => $sortOption) {
+ echo '<option value="'.$sortVal.'"';
+ if ($current['sort'] == $sortVal)
+ echo ' selected';
+ echo '>'.$sortOption.'</option>';
+ }
+ ?>
+ </select>
+ <span class="pipe">|</span>
+ Category:
+ <select name="cat">
+ <?php
+ foreach ($tags as $tagVal => $tagOption) {
+ echo '<option value="'.$tagVal.'"';
+ if ($tagVal == $current['cat'])
+ echo ' selected';
+ echo '>'.$tagOption.'</option>';
+ }
+ ?>
+ </select>&nbsp;&nbsp;
+ <input type="submit" value="Update" class="inputbutton">
+ </form>
+</div>
+
+<div class="bar clearfix summary_bar filter_tab_bar">
+ <div>
+ <ul class="tabs">
+ <li<?=($current['type'] == 'none' ? ' class="current"' : '')?>><a href="<?=FB_URL?>/browse/sort:<?=$current['sort']?>/cat:<?=$current['cat']?>">All results</a></li>
+ <?=($count['extensions'] > 0 ? (($count['extensions'] == 1) ? '<li'.($current['type'] == ADDON_EXTENSION ? ' class="current"' : '').'><a href="'.FB_URL.'/browse/sort:'.$current['sort'].'/cat:'.$current['cat'].'/type:'.ADDON_EXTENSION.'">1 extension</a></li>' : '<li'.($current['type'] == ADDON_EXTENSION ? ' class="current"' : '').'><a href="'.FB_URL.'/browse/sort:'.$current['sort'].'/cat:'.$current['cat'].'/type:'.ADDON_EXTENSION.'">'.$count['extensions'].' extensions</a></li>') : '<li class="empty"><span>No extensions</span></li>')?>
+ <?=($count['themes'] > 0 ? (($count['themes'] == 1) ? '<li'.($current['type'] == ADDON_THEME ? ' class="current"' : '').'><a href="'.FB_URL.'/browse/sort:'.$current['sort'].'/cat:'.$current['cat'].'/type:'.ADDON_THEME.'">1 theme</a></li>' : '<li'.($current['type'] == ADDON_THEME ? ' class="current"' : '').'><a href="'.FB_URL.'/browse/sort:'.$current['sort'].'/cat:'.$current['cat'].'/type:'.ADDON_THEME.'">'.$count['themes'].' themes</a></li>') : '<li class="empty"><span>No themes</span></li>')?>
+ <?=($count['friends'] > 0 ? '<li'.($current['type'] == 'friends' ? ' class="current"' : '').'><a href="'.FB_URL.'/browse/sort:'.$current['sort'].'/cat:'.$current['cat'].'/type:friends">'.$count['friends'].' from friends</a></li>' : '<li class="empty"><span>None from friends</span></li>')?>
+ </ul>
+ </div>
+ <?=$facebook->pageNumbers($current, $count)?>
+</div>
+
+<?=$facebook->listAddons($addons)?>
+
+<div class="bar clearfix footer_bar">
+ <?=$facebook->pageNumbers($current, $count)?>
+</div> \ No newline at end of file
diff --git a/site/app/views/facebook/faq.thtml b/site/app/views/facebook/faq.thtml
new file mode 100644
index 0000000..80b7157
--- /dev/null
+++ b/site/app/views/facebook/faq.thtml
@@ -0,0 +1,122 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Justin Scott <fligtar@mozilla.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+?>
+<style>
+ .body {
+ padding: 10px;
+ }
+ h1 {
+ border-bottom: 1px solid #d8dfea;
+ margin: 5px 10px;
+ padding-bottom: 2px;
+ font-size: 13px;
+ color: #333333;
+ }
+ .entry {
+ margin: 0px 20px;
+ margin-top: 10px;
+ padding-bottom: 5px;
+ border-bottom: 1px solid #eeeeee;
+ }
+ .question {
+ font-weight: bold;
+ }
+ .answer {
+ text-indent: 20px;
+ margin-top: 5px;
+ }
+</style>
+
+<div class="body">
+ <h1>Frequently Asked Questions</h1>
+
+ <div class="entry">
+ <div class="question">What exactly is an add-on, and why should I download one?</div>
+ <div class="answer">Add-ons let you Rock Your Firefox by adding new features or changing the appearance of your Firefox.
+ For example, you can give your browser a whole new look with specially created themes.
+ Or you can try add-ons that will enhance listening to music, simplify photo sharing, block popup ads, and more.</div>
+ </div>
+
+ <div class="entry">
+ <div class="question">What is the difference between putting an add-on on my favorites list and actually installing the add-on for my Firefox?</div>
+ <div class="answer">Marking an add-on as a favorite lets your friends know that you use and recommend the add-on, but does not automatically install it.
+ Similarly, installing an add-on does not automatically mark it as a favorite.</div>
+ </div>
+
+ <div class="entry">
+ <div class="question">I want to show my favorite add-ons on my profile. How do I do this?</div>
+ <div class="answer">Clicking "Add to Favorites" on an add-on's display page will add it to your favorites and make it appear in your Facebook profile.</div>
+ </div>
+
+ <div class="entry">
+ <div class="question">How do I share a cool add-on with my friends? (i.e. Can I invite people to add something?)</div>
+ <div class="answer">You can use the Share button on an addon's display page to share that add-on with a specific friend or post it on your profile.
+ You'll also be able to send add-ons as attachments in wall posts and messages very soon, so they can Rock their Firefox.</div>
+ </div>
+
+ <div class="entry">
+ <div class="question">I've installed an add-on. What's my next step to actually start using it?</div>
+ <div class="answer">Once you install an add-on, you'll need to restart Firefox for it to take effect.
+ If the add-on doesn't seem to have installed properly, go the Add-ons Manager in the Firefox tools menu to learn more.</div>
+ </div>
+
+ <div class="entry">
+ <div class="question">Is this application secure? Are these add-ons certified by Mozilla?</div>
+ <div class="answer">The add-ons listed in Rock Your Firefox were not made by Mozilla (unless otherwise noted).
+ It's best to check with the author of the add-on (listed next to each add-on description) for any support requests.</div>
+ </div>
+
+ <div class="entry">
+ <div class="question">Why do I need Firefox to use this Facebook application?</div>
+ <div class="answer">This application lets you Rock Your Firefox!
+ Only Firefox gives you the chance to customize nearly every aspect of your browser.
+ Find out what Firefox add-ons your friends are using and discover new favorites on your own.</div>
+ </div>
+
+ <div class="entry">
+ <div class="question">Where can I find more information about Firefox extensions and themes?</div>
+ <div class="answer">You can submit and learn more about creating add-ons for Firefox at <a href="http://addons.mozilla.org">Mozilla Add-ons</a>.
+ Submitting your add-on in the <a href="http://addons.mozilla.org/developers">Developer Control Panel</a> there will enable it to be listed in Rock Your Firefox.</div>
+ </div>
+
+ <div class="entry">
+ <div class="question">Where can I report a bug or enhancement request with this application?</div>
+ <div class="answer">If you think you've found an issue with this application, or if you'd like to request a new feature,
+ please do so in Mozilla's <a href="https://bugzilla.mozilla.org/enter_bug.cgi?product=addons.mozilla.org&component=Facebook%20Application&op_sys=All&rep_platform=All">Bugzilla</a>.</div>
+ </div>
+</div> \ No newline at end of file
diff --git a/site/app/views/facebook/favorites.thtml b/site/app/views/facebook/favorites.thtml
new file mode 100644
index 0000000..87658ec
--- /dev/null
+++ b/site/app/views/facebook/favorites.thtml
@@ -0,0 +1,147 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Justin Scott <fligtar@mozilla.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+?>
+<div class="favorites">
+ <div class='subtabs clearfix'>
+ <div class="tab<?=($action == 'mine' ? '' : ' unselected')?>"><a href="<?=FB_URL?>/favorites/mine">My Favorites</a></div>
+ <div class="tab<?=($action == 'friends' ? ' selected' : ' unselected')?>"><a href="<?=FB_URL?>/favorites/friends">Friend Favorites</a></div>
+ <? /* <div class="tab<?=($action == 'networks' ? '' : ' unselected')?>"><a href="<?=FB_URL?>/favorites/networks">Network Favorites</a></div> */ ?>
+ <?=($action == 'addon' ? '<div class="tab"><a href="'.FB_URL.'/favorites/addon/'.$addon['Addon']['id'].'">Add-on Details</a></div>' : '')?>
+ <?=($action == 'user' ? '<div class="tab"><a href="'.FB_URL.'/favorites/user/'.$user_id.'">User Favorites</a></div>' : '')?>
+ </div>
+
+ <?php
+ if (!empty($addons)) {
+ if ($action == 'mine') {
+ echo '<div style="padding: 0 25px;"><table class="myfavorites" cellspacing=0 cellpadding=0>';
+ foreach ($addons as $addon) {
+ echo '<tr>';
+ echo '<td class="info"><a href="'.FB_URL.'/view/'.$addon['addons']['id'].'">'.$addon['translations']['name'].'</a></td>';
+ echo '<td class="imported">'.($addon['facebook_favorites']['imported'] == 1 ? 'Imported' : '').'</td>';
+ ?>
+ <td class="remove">
+ <a href="<?=FB_URL.'/favorite/remove/'.$addon['addons']['id']?>" onClick="removeFavorite(this, '<?=$addon['addons']['id']?>'); return false;">Remove</a>
+ </td>
+ </tr>
+ <?php
+ }
+ echo '</table></div>';
+ ?>
+ <script>
+ <!--
+ var addon_id = 0;
+
+ function removeFavorite(link, id) {
+ addon_id = id;
+ new Dialog(Dialog.DIALOG_CONTEXTUAL).
+ setContext(link).
+ showChoice('Remove Favorite?', 'Are you sure you wish to remove this add-on from your list of favorites?', 'Yes, remove it.', 'No, keep it.').
+ onconfirm = function() { document.setLocation('<?=FB_URL.'/favorite/remove/'?>' + addon_id); };
+ }
+ //-->
+ </script>
+ <?php
+ }
+ elseif ($action == 'friends') {
+ echo '<div class="bar clearfix summary_bar" style="padding-top: 0px;">';
+ $start = ($current['page'] - 1) * RESULTS_PER_PAGE + 1;
+ $end = $start + RESULTS_PER_PAGE - 1;
+ if ($end > $count['total'])
+ $end = $count['total'];
+ echo "<div class=\"summary\">Displaying results <b>{$start}-{$end}</b> of <b>{$count['total']}</b></div>";
+ echo $facebook->pageNumbers($current, $count, 'favorites/friends');
+ echo '</div>';
+ echo $facebook->listAddonsOfFriends($addons);
+ echo '<div class="bar clearfix footer_bar">';
+ echo $facebook->pageNumbers($current, $count, 'favorites/friends');
+ echo '</div>';
+ }
+ elseif ($action == 'user') {
+ echo '<div class="bar clearfix summary_bar">';
+ $start = ($current['page'] - 1) * RESULTS_PER_PAGE + 1;
+ $end = $start + RESULTS_PER_PAGE - 1;
+ if ($end > $count['total'])
+ $end = $count['total'];
+ echo '<div class="summary">';
+ echo "Displaying results <b>{$start}-{$end}</b> of <b>{$count['total']}</b>";
+ echo '<span class="pipe">|</span>';
+ echo '<a href="http://www.facebook.com/profile.php?id='.$user_id.'">Back to <fb:name uid="'.$user_id.'" possessive="true" linked="false" /> profile</a>';
+ echo '</div>';
+ echo $facebook->pageNumbers($current, $count, 'favorites/user/'.$user_id);
+ echo '</div>';
+ echo $facebook->listAddonsOfFriends($addons);
+ echo '<div class="bar clearfix footer_bar">';
+ echo $facebook->pageNumbers($current, $count, 'favorites/user/'.$user_id);
+ echo '</div>';
+ }
+ }
+ elseif ($action == 'addon') {
+ echo '<div style="padding: 5px 20px;"><a href="'.FB_URL.'/view/'.$addon['Addon']['id'].'">Back to '.$addon['Translation']['name']['string'].'</a></div>';
+ echo '<div style="padding: 0px 20px;">';
+ if ($view == 'all') {
+ echo $facebook->peopleBox($friends, 600, 1, array(
+ 'title' => "Friends That Recommend {$addon['Translation']['name']['string']}",
+ 'addon_id' => $addon['Addon']['id'],
+ 'showFriendCount' => true,
+ 'friendCount' => count($friends),
+ 'seeAllURL' => FB_URL.'/favorites/addon/'.$addon['Addon']['id'].'/friends'
+ ));
+ echo '<br>';
+ echo $facebook->peopleBox($all, 600, 2, array(
+ 'title' => "Everyone That Recommends {$addon['Translation']['name']['string']}",
+ 'addon_id' => $addon['Addon']['id'],
+ 'showAllCount' => true,
+ 'allCount' => count($all),
+ ));
+ }
+ elseif ($view == 'friends') {
+ echo $facebook->peopleBox($friends, 600, 100, array(
+ 'title' => "All Friends That Recommend {$addon['Translation']['name']['string']}",
+ 'addon_id' => $addon['Addon']['id'],
+ 'showFriendCount' => true,
+ 'friendCount' => count($friends),
+ ));
+ }
+ echo '</div>';
+ echo '<div style="padding: 5px 20px;"><a href="'.FB_URL.'/view/'.$addon['Addon']['id'].'">Back to '.$addon['Translation']['name']['string'].'</a></div>';
+ }
+ else {
+ echo '<div class="nofavorites">No favorites yet!</div>';
+ }
+ ?>
+</div> \ No newline at end of file
diff --git a/site/app/views/facebook/home.thtml b/site/app/views/facebook/home.thtml
new file mode 100644
index 0000000..eb0e641
--- /dev/null
+++ b/site/app/views/facebook/home.thtml
@@ -0,0 +1,194 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Justin Scott <fligtar@mozilla.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+?>
+<style>
+ .body {
+ padding: 10px;
+ margin-right: 186px;
+ }
+ h1.fbheader {
+ border-bottom: 1px solid #d8dfea;
+ margin: 5px 10px;
+ padding-bottom: 2px;
+ font-size: 13px;
+ color: #333333;
+ }
+ .newsfeed {
+ margin: 0px 10px;
+ margin-top: 10px;
+ }
+ .ryf_sidebar {
+ float: right;
+ padding-top: 5px;
+ width: 186px;
+ background-color: #f7f7f7;
+ border-left: 1px solid #e9e9e9;
+ border-bottom: 1px solid #e9e9e9;
+ }
+ .sidebar_header {
+ margin: 0px 5px;
+ padding: 3px 5px 4px 5px;
+ background-color: #e9e9e9;
+ font-size:11px;
+ color:#333;
+ }
+ .sidebar_item {
+ padding: 8px 10px 15px 10px;
+ }
+ .otherinfo {
+ list-style-type: none;
+ margin: 0px;
+ padding-left: 5px;
+ }
+ .newsfeed .story {
+ padding-bottom: 10px;
+ color: #333333;
+ }
+ .newsfeed .story .title {
+ font-weight: bold;
+ color: #666666;
+ }
+ .newsfeed .story .story_icon {
+ padding-right: 5px;
+ vertical-align: middle;
+ float: left;
+ }
+ .newsfeed .fullstory {
+ border-top: 1px solid #d8dfea;
+ border-bottom: 1px solid #d8dfea;
+ margin-left: 22px;
+ padding: 5px 0;
+ }
+ .newsfeed .fullstory_title {
+ font-weight: bold;
+ }
+ .newsfeed .fullstory_body {
+ padding: 5px;
+ }
+ .newsfeed .with_preview {
+ min-height: 75px;
+ }
+ .newsfeed .fullstory_icon {
+ padding-top: 5px;
+ }
+ .newsfeed .story_text {
+ margin-left: 20px;
+ }
+ .newsfeed .nostories {
+ font-size: 110%;
+ color: #666666;
+ text-align: center;
+ }
+ .sharebutton {
+ padding: 0 10px 10px 10px;
+ }
+</style>
+
+<div class="ryf_sidebar">
+<?php if (!$this->controller->_usingSupportedBrowser()): ?>
+ <h1 class="sidebar_header" style="color: #dd3c10;">Unsupported Browser</h1>
+ <div class="sidebar_item">
+ The add-ons in Rock Your Firefox are meant to work with <a href="http://www.mozilla.com/en-US/firefox/?ref=facebookapp">Mozilla Firefox</a> and may not work in your browser.
+ </div>
+<?php endif; ?>
+ <h1 class="sidebar_header">Import Add-ons</h1>
+ <div class="sidebar_item">
+ You can now import the add-ons you already have installed in Firefox to your favorites list. <a href="<?=FB_URL?>/import?ref=sb">Find out more!</a>
+ </div>
+ <?php if (!empty($newAddonCount)): ?>
+ <h1 class="sidebar_header">Something New?</h1>
+ <div class="sidebar_item">
+ <?=$newAddonCount?>
+ </div>
+ <?php endif; ?>
+ <h1 class="sidebar_header">Other Information</h1>
+ <div class="sidebar_item">
+ <ul class="otherinfo">
+ <li>&raquo;&nbsp;<a href="<?=FB_URL?>/invite?ref=sb">Invite Friends</a></li>
+ <li>&raquo;&nbsp;<a href="<?=FB_URL?>/faq?ref=sb">FAQ</a></li>
+ <li>&raquo;&nbsp;<a href="<?=FB_URL?>/wallpaper?ref=sb">Desktop Wallpaper</a></li>
+ <li>&raquo;&nbsp;<a href="<?=FB_URL?>/updatenotes?ref=sb">Update Notes</a></li>
+ </ul>
+ </div>
+ <div class="sharebutton">
+ <fb:share-button class="meta">
+ <meta name="title" content="Rock Your Firefox" />
+ <meta name="description" content="Rock Your Firefox was created so that you can personalize, customize, and essentially rock out your browser and then share your add-ons with your friends! Make Firefox your own with extensions, themes, plug-ins, and more." />
+ <meta name="medium" content="application" />
+ <link rel="target_url" href="http://www.rockyourfirefox.com" />
+ <link rel="image_src" href="<?=FB_IMAGE_SITE?>/img/facebook/rockyourfirefox-75x70.png" />
+ </fb:share-button>
+ </div>
+</div>
+
+<div class="body">
+ <h1 class="fbheader">Welcome<?=((!empty($justAdded) && $justAdded == true) ? '' : ' back')?>, <fb:name uid="<?=$fbUser?>" firstnameonly="true" useyou="false" shownetwork="false" linked="false" />!</h1>
+ <div class="newsfeed">
+ <?php
+ if (!empty($newsfeed)) {
+ foreach ($newsfeed as $story) {
+ echo '<div class="story">';
+ echo '<img src="'.FB_IMAGE_SITE.'/img/facebook/newsfeed/'.$story['icon'].'" class="story_icon'.($story['type'] == 'fullstory' ? ' fullstory_icon' : '').'">';
+ if ($story['type'] == 'fullstory') {
+ echo '<div class="fullstory">';
+ echo '<div class="fullstory_title">'.$story['story'].'</div>';
+ if (!empty($story['image'])) {
+ echo '<a href="'.$story['image_url'].'"><img src="'.$story['image'].'" align="right" width="100" height="75"></a>';
+ }
+ echo '<div class="fullstory_body'.(!empty($story['image']) ? ' with_preview' : '').'">'.$story['body'].'</div>';
+ echo '</div>';
+ }
+ else {
+ echo '<div class="story_text">';
+ echo $story['story'];
+ echo '</div>';
+ }
+ echo '</div>';
+ }
+ }
+ else {
+ ?>
+ <div class="nostories">
+ Once you add some favorite add-ons and have friends using Rock Your Firefox, stories of interest will appear here.<br><br>
+ Stories include friends' recent favorite additions, new versions of your favorite add-ons, and recommendations of new add-ons based on your friends' favorites.
+ </div>
+ <?php
+ }
+ ?>
+ </div>
+</div> \ No newline at end of file
diff --git a/site/app/views/facebook/import.thtml b/site/app/views/facebook/import.thtml
new file mode 100644
index 0000000..298e1bd
--- /dev/null
+++ b/site/app/views/facebook/import.thtml
@@ -0,0 +1,245 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Justin Scott <fligtar@mozilla.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+?>
+<script language="JavaScript" type="text/javascript" src="../../../../js/__utm.js"></script>
+<style type="text/css">
+ body, table, td, div {
+ font-family: "lucida grande", tahoma, verdana, arial, sans-serif;
+ font-size: 11px;
+ }
+ .dialog {
+ width: 600px;
+ margin: 0 auto;
+ border: 10px solid #d8dfea;
+ }
+ #content p {
+ text-align: center;
+ }
+ .dialog .frame {
+ border: 1px solid #3b5998;
+ padding: 10px;
+ }
+ .dialog h1 {
+ border-bottom: 1px solid #d8dfea;
+ margin: 5px 10px;
+ padding-bottom: 2px;
+ font-size: 13px;
+ color: #333333;
+ }
+ .pipe {
+ color: gray;
+ }
+ a {
+ color: #3b5998;
+ text-decoration: none;
+ }
+ a:hover {
+ text-decoration: underline;
+ }
+ #actions {
+ text-align: center;
+ }
+ .dh_new_media_shell {
+ background: url('<?=FB_IMAGE_SITE?>/img/facebook/new_media_button_active.gif') no-repeat bottom -30px;
+ margin: 5px 200px;
+ }
+ .dh_new_media {
+ float: left;
+ display: block;
+ color: #777;
+ text-decoration: none;
+ background: url('<?=FB_IMAGE_SITE?>/img/facebook/new_media_button.gif') no-repeat;
+ }
+ .dh_new_media .tr {
+ background: url('<?=FB_IMAGE_SITE?>/img/facebook/new_media_button.gif') no-repeat top right;
+ }
+ .dh_new_media .bl {
+ background: url('<?=FB_IMAGE_SITE?>/img/facebook/new_media_button.gif') no-repeat bottom left;
+ }
+ .dh_new_media .br {
+ background: url('<?=FB_IMAGE_SITE?>/img/facebook/new_media_button.gif') no-repeat bottom right;
+ }
+ .dh_new_media span {
+ color: #333;
+ font-size: 11px;
+ font-weight: bold;
+ display: block;
+ padding: 3px 9px 5px 22px;
+ text-shadow: white 0px 1px 1px;
+ background: url('<?=FB_IMAGE_SITE?>/img/facebook/new_media_button_plus.gif') no-repeat 9px center;
+ }
+ .dh_new_media:hover {
+ text-decoration: underline;
+ }
+ .dh_new_media:active,
+ .dh_new_media:active .tr,
+ .dh_new_media:active .bl,
+ .dh_new_media:active .br {
+ background-image: url('<?=FB_IMAGE_SITE?>/img/facebook/new_media_button_active.gif');
+ }
+ #addons {
+ margin: 0px 20px;
+ }
+ #addons .disabled {
+ color: gray;
+ }
+ .inputbutton {
+ border-top: 1px solid #d9dfea;
+ border-left: 1px solid #d9dfea;
+ border-right: 1px solid #0e1f5b;
+ border-bottom: 1px solid #0e1f5b;
+ color: #ffffff;
+ font-size: 11px;
+ font-family: "lucida grande",tahoma,verdana,arial,sans-serif;
+ text-align: center;
+ background-color: #3b5998;
+ }
+ .step {
+ clear: both;
+ border-left: 2px solid lightgray;
+ border-bottom: 1px solid lightgray;
+ padding-top: 10px;
+ padding-bottom: 10px;
+ padding-left: 25px;
+ margin-top: 10px;
+ }
+ .step h2 {
+ margin: 5px 10px;
+ padding-bottom: 2px;
+ font-size: 12px;
+ color: #3b5998;
+ margin-left: -10px;
+ }
+ #step1 {
+ height: 130px;
+ }
+ #step2 {
+ height: 241px;
+ }
+ #continue {
+ text-align: center;
+ padding: 15px;
+ }
+</style>
+
+<?php
+if ($action == 'results') {
+ if (!empty($detected)) {
+?>
+ <div id="content" class="dialog">
+ <div class="frame">
+ <h1>Detect Installed Add-ons</h1>
+ <p>Select the add-ons below that you'd like to add to your list of favorite add-ons.<br><a href="#" onClick="document.getElementById('missing-addons').style.display=''; this.style.display='none';">Why are some of my add-ons missing?</a></p>
+ <p id="missing-addons" style="display: none;">If some of your installed add-ons aren't detected, it's probably because they are not hosted on <a href="http://addons.mozilla.org">Mozilla Add-ons</a>. Only add-ons hosted on <a href="http://addons.mozilla.org">Mozilla Add-ons</a> can be detected and listed in Rock Your Firefox.</p>
+ <form action="<?=SITE_URL.$html->url('/facebookinstall/import/'.$fbUserSession.'/favorites')?>" method="post" id="form">
+ <table id="addons" width="100%">
+ <tr><td width="50%" valign="top">
+ <?php
+ $i = 0;
+ $firstColumn = ceil(count($detected) / 2);
+ foreach ($detected as $addon) {
+ if ($i == $firstColumn)
+ echo '</td><td width="50%" valign="top">';
+ echo '<div class="item'.($addon['facebook_detected']['disabled'] == 1 ? ' disabled' : '').'">';
+ echo '<label><input type="checkbox" name="addons['.$addon['addons']['id'].']" value="1"';
+ if ($addon['facebook_detected']['disabled'] != 1)
+ echo ' checked';
+ if ($this->controller->FacebookFavorite->isFavorite($fbUser, $addon['addons']['id'], true))
+ echo ' disabled="disabled"';
+ echo '>';
+ echo "<b>{$addon['translations']['localized_string']}</b>";
+ if ($addon['facebook_detected']['disabled'] == 1)
+ echo ' (Disabled in Browser)';
+ if ($this->controller->FacebookFavorite->isFavorite($fbUser, $addon['addons']['id'], true))
+ echo ' (Already Added)';
+ echo '</label></div>';
+ $i++;
+ }
+ ?>
+ </td></tr>
+ </table>
+ <div id="actions">
+ <div class="dh_new_media_shell"><a href="#" onClick="document.getElementById('form').submit();" class="dh_new_media"><div class="tr"><div class="bl"><div class="br"><span>Add Selected to Favorites</span></div></div></div></a></div>
+ <br><br>
+ <a href="<?=FB_URL?>">Cancel</a> <span class="pipe">|</span>
+ <a href="<?=SITE_URL.$html->url('/facebookinstall/import/'.$fbUserSession)?>">Re-scan</a>
+ </div>
+ </form>
+ </div>
+ </div>
+<?php } else { ?>
+ <div id="content" class="dialog">
+ <div class="frame">
+ <h1>Detect Installed Add-ons</h1>
+ <p>No installed add-ons could be detected. If you have add-ons installed, please make sure cookies are enabled and go back to <a href="<?=SITE_URL.$html->url('/facebookinstall/import/'.$fbUserSession)?>">follow the steps again</a>.</p>
+ </div>
+ </div>
+<?php
+ }
+}
+else {
+?>
+ <div id="content" class="dialog">
+ <div class="frame">
+ <h1>Detect Installed Add-ons</h1>
+ <p>Rock Your Firefox can attempt to detect add-ons currently installed in your browser. Just follow the steps below to provide the necessary information.
+ <br><a href="#" onClick="document.getElementById('how-it-works').style.display=''; this.style.display='none';">How does this work?</a></p>
+ <p id="how-it-works" style="display: none;">A cookie has been placed on your computer that will be read when you check your add-ons for updates and record the add-ons that you check for updates.</p>
+ <div id="step1" class="step">
+ <img src="<?=FB_IMAGE_SITE?>/img/facebook/detect-step1.png" align="right">
+ <h2>Step 1</h2>
+ <div>In Firefox, open the <b>Tools</b> menu and click <b>Add-ons</b> to open the Add-on Manager.</div>
+ </div>
+ <div id="step2" class="step">
+ <img src="<?=FB_IMAGE_SITE?>/img/facebook/detect-step2.png" align="right">
+ <h2>Step 2</h2>
+ <div>Click <b>Find Updates</b> in the bottom left. If you'd also like to detect installed themes, switch to the Themes panel and click Find Updates there as well.</div>
+ </div>
+ <div id"step3" class="step">
+ <h2>Step 3</h2>
+ When Firefox is finished checking for updates, close the Add-ons Manager and click <b>Continue</b> below.
+ <div id="continue">
+ <input type="button" class="inputbutton" onClick="window.location='<?=SITE_URL.'/facebookinstall/import/'.$fbUserSession.'/results'?>';" value="Continue"><br>
+ <a href="<?=FB_URL?>">Cancel</a>
+ </div>
+ </div>
+ </div>
+ </div>
+<?php
+}
+?> \ No newline at end of file
diff --git a/site/app/views/facebook/import_info.thtml b/site/app/views/facebook/import_info.thtml
new file mode 100644
index 0000000..79adc17
--- /dev/null
+++ b/site/app/views/facebook/import_info.thtml
@@ -0,0 +1,91 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Justin Scott <fligtar@mozilla.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+?>
+<style>
+ .body {
+ padding: 10px;
+ }
+ h1 {
+ border-bottom: 1px solid #d8dfea;
+ margin: 5px 10px;
+ padding-bottom: 2px;
+ font-size: 13px;
+ color: #333333;
+ }
+ .info {
+ margin: 0px 20px;
+ margin-top: 10px;
+ }
+ .info p {
+ font-size: 110%;
+ }
+ .detect {
+ font-weight: bold;
+ font-size: 14px;
+ padding: 5px;
+ }
+ .disabled {
+ color: gray;
+ }
+ .unsupported {
+ color: red;
+ padding: 5px;
+ }
+</style>
+
+<div class="body">
+ <h1>Import Add-ons</h1>
+
+ <div class="info">
+ <p>If you have add-ons already installed in Firefox, now it's easy to automatically detect and import them to your favorite add-ons list.
+ By following 3 simple steps, you'll be able to see a list of your installed add-ons and select your favorites.
+ After you've imported them, anytime you install new add-ons you can simply come back and re-scan for your new add-ons.</p>
+
+ <p>Get started by clicking Detect My Add-ons below!</p>
+
+ <div style="text-align: center;">
+ <?php if ($this->controller->_usingSupportedBrowser()): ?>
+ <div class="detect"><a href="<?=FB_INSTALL_SITE.$html->url('/facebookinstall/import/'.$key)?>">Detect My Add-ons</a></div>
+ <?php else: ?>
+ <div class="detect disabled">Detect My Add-ons</div>
+ <div class="unsupported">This ability is only available to Firefox users. You are using an unsupported browser.</div>
+ <?php endif; ?>
+ <div><a href="<?=FB_URL?>/home">Back to home</a></div>
+ </div>
+ </div>
+</div> \ No newline at end of file
diff --git a/site/app/views/facebook/install.thtml b/site/app/views/facebook/install.thtml
new file mode 100644
index 0000000..3a01bef
--- /dev/null
+++ b/site/app/views/facebook/install.thtml
@@ -0,0 +1,183 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Justin Scott <fligtar@mozilla.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+$filename = SITE_URL.$this->controller->base.'/'.FILES_URL.'/'.$file['File']['id'].'/'.preg_replace(INVALID_FILENAME_CHARS, '_', $file['File']['filename']);
+?>
+<script language="JavaScript" type="text/javascript">
+function goBack(name, result){
+ history.back();
+}
+
+function install() {
+ if (document.referrer.match(/^https?:\/\/[^\/]*\.mozilla\.(com|org)\/?.*/) ||
+ document.referrer.match(/^https?:\/\/apps\.facebook\.com\/?.*/)) {
+
+ var params = {
+ "<?=$addon['Translation']['name']['string']?>": {
+ URL: '<?=$filename?>',
+ <?=(!empty($addon['Addon']['icontype']) ? "IconURL: '".$this->controller->Image->getAddonIconURL($addon['Addon']['id'])."'," : '')?>
+ Hash: '<?=$file['File']['hash']?>',
+ toString: function () { return this.URL; }
+ }
+ };
+ InstallTrigger.install(params, goBack);
+ }
+ else {
+ window.location = 'http://addons.mozilla.org';
+ }
+}
+
+<?php
+ // Only automatically install if no EULA
+ if (empty($addon['Translation']['eula']['string'])) {
+ echo 'install();';
+ }
+?>
+</script>
+<script language="JavaScript" type="text/javascript" src="../../../../js/__utm.js"></script>
+<style type="text/css">
+ .dialog {
+ width: 600px;
+ height: 172px;
+ margin: 0 auto;
+ font-family: "lucida grande", tahoma, verdana, arial, sans-serif;
+ font-size: 11px;
+ border: 10px solid #d8dfea;
+ }
+ #content p {
+ text-align: center;
+ }
+ .eula {
+ height: 450px;
+ }
+ .dialog .frame {
+ border: 1px solid #3b5998;
+ padding: 10px;
+ height: 150px;
+ }
+ .dialog .eula {
+ height: 428px;
+ }
+ .dialog h1 {
+ border-bottom: 1px solid #d8dfea;
+ margin: 5px 10px;
+ padding-bottom: 2px;
+ font-size: 13px;
+ color: #333333;
+ }
+ #return {
+ font-size: 120%;
+ }
+ a {
+ color: #3b5998;
+ text-decoration: none;
+ }
+ a:hover {
+ text-decoration: underline;
+ }
+ #actions {
+ text-align: center;
+ }
+ .policy-area {
+ width: 100%;
+ height: 285px;
+ }
+ .confirm_button {
+ padding: 10px 0;
+ }
+ .install_button {
+ width: 11em;
+ }
+ .accept_button {
+ width: 15em;
+ }
+ .confirm_button a {
+ float: left;
+ display: block;
+ background: url('<?=FB_IMAGE_SITE?>/img/facebook/confirm_button.gif') no-repeat top left;
+ font-size: 13px;
+ font-weight: bold;
+ color: #d8dfea;
+ cursor: pointer;
+ }
+ .confirm_button div {
+ background: url('<?=FB_IMAGE_SITE?>/img/facebook/confirm_button.gif') no-repeat top right;
+ }
+ .confirm_button div div {
+ background-position: bottom left;
+ }
+ .confirm_button div div div {
+ background-position: bottom right;
+ padding: 0px 0px 0px 10px;
+ }
+ .confirm_button span {
+ display: block;
+ padding: 4px 10px 5px 22px;
+ background: url('<?=FB_IMAGE_SITE?>/img/facebook/confirm_button_extension.gif') no-repeat left center;
+ color: #FFF;
+ }
+ .confirm_button a:active,
+ .confirm_button a:active div {
+ background-image: url('<?=FB_IMAGE_SITE?>/img/facebook/confirm_button_active.gif');
+ }
+</style>
+
+<?php if (!empty($addon['Translation']['eula']['string'])): ?>
+ <div id="content" class="dialog eula">
+ <div class="frame eula">
+ <h1><?=$addon['Translation']['name']['string']?> License Agreement</h1>
+ <p><?=$addon['Translation']['name']['string']?> requires that you accept the following End-User License Agreement before installation can proceed:</p>
+ <textarea class="policy-area" readonly>
+ <?=$addon['Translation']['eula']['string']?>
+ </textarea>
+ <div id="actions">
+ <div id="confirm_button" class="confirm_button accept_button" style="margin: 0 auto;"><a href="<?=$filename?>" onclick="install(); return false;"><div><div><div><span>Accept and Install</span></div></div></div></a></div>
+ <br><br><a href="<?=FB_URL?>/view/<?=$addon['Addon']['id']?>" onclick="goBack(); return false;" id="return">Cancel Installation and Return</a>
+ </div>
+<?php else: ?>
+ <div id="content" class="dialog">
+ <div class="frame">
+ <h1>Installing <?=$addon['Translation']['name']['string']?></h1>
+ <p>You should be prompted for installation of <?=$addon['Translation']['name']['string']?> momentarily. If you are not prompted, please click "Install Now" below to begin installation.</p>
+ <div id="actions">
+ <div id="confirm_button" class="confirm_button install_button" style="margin: 0 auto;"><a href="<?=$filename?>" onclick="install(); return false;"><div><div><div><span>Install Now</span></div></div></div></a></div>
+ <br><br><a href="<?=FB_URL?>/view/<?=$addon['Addon']['id']?>" onclick="goBack(); return false;" id="return">Return to Add-on</a>
+ </div>
+<?php endif; ?>
+
+ </div>
+</div>
diff --git a/site/app/views/facebook/invite.thtml b/site/app/views/facebook/invite.thtml
new file mode 100644
index 0000000..3e99fe6
--- /dev/null
+++ b/site/app/views/facebook/invite.thtml
@@ -0,0 +1,51 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Justin Scott <fligtar@mozilla.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+$nextURL = urlencode('?ref=invitation');
+$api = FB_API_KEY;
+
+$fbml = <<<FBML
+Rock Your Firefox allows us to share our favorite Firefox add-ons with each other and discover new ways to customize Firefox.
+Add the application and start adding add-ons to your favorites list! If you don't use any add-ons, now's the perfect time to start!
+<fb:req-choice url="http://www.facebook.com/add.php?api_key=$api&next=$nextURL" label="Rock My Firefox!" />
+FBML;
+?>
+
+<fb:request-form type="Browser Add-ons" action="<?=FB_URL?>" method="post" content="<?=htmlentities($fbml)?>" invite="true">
+ <fb:multi-friend-selector max="20" actiontext="Invite friends to Rock their Firefox!" showborder="true" rows="3" exclude_ids="<?=$exclude?>" />
+</fb:request-form> \ No newline at end of file
diff --git a/site/app/views/facebook/outage.thtml b/site/app/views/facebook/outage.thtml
new file mode 100644
index 0000000..ac1b3f7
--- /dev/null
+++ b/site/app/views/facebook/outage.thtml
@@ -0,0 +1,79 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Justin Scott <fligtar@mozilla.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+?>
+<style>
+ .body {
+ background: url('<?=SITE_URL?>/img/facebook/outage.png') no-repeat;
+ height: 335px;
+ }
+ .outage-notice {
+ font-size: 22px;
+ font-weight: bold;
+ color: #bd1d01;
+ margin-left: 285px;
+ margin-right: 20px;
+ text-align: center;
+ padding-top: 50px;
+ }
+ .outage-details {
+ margin-left: 320px;
+ margin-right: 20px;
+ font-size: 15px;
+ color: #bd1d01;
+ text-align: center;
+ padding-top: 20px;
+ }
+ .outage-alternative {
+ font-size: 12px;
+ text-align: center;
+ margin-top: 100px;
+ }
+</style>
+
+<div class="body">
+ <div class="outage-notice">
+ Rock Your Firefox is currently unavailable due to high volume of users.
+ </div>
+ <div class="outage-details">
+ We'll be up and running again shortly.<br>Thanks for your patience!
+ </div>
+ <div class="outage-alternative">
+ In the meantime, check out all the other great ways that you can listen to music, check the weather, upload photos, block stuff you don't like,
+ and do whatever you like to do best on the web with <a href="http://addons.mozilla.org">Firefox Add-ons</a>.
+ </div>
+</div> \ No newline at end of file
diff --git a/site/app/views/facebook/search.thtml b/site/app/views/facebook/search.thtml
new file mode 100644
index 0000000..f37fe1e
--- /dev/null
+++ b/site/app/views/facebook/search.thtml
@@ -0,0 +1,65 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Justin Scott <fligtar@mozilla.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+$facebook->globalURLAdditional = "?q={$q}";
+?>
+
+<div class="sort_box">
+ <form action="<?=FB_URL?>/search" method="get">
+ Searching for
+ <input value="<?=$q?>" class="inputtext inputsearch" type="search" size=40 name="q" />&nbsp;&nbsp;
+ <input type="submit" value="Search" class="inputbutton">
+ </form>
+</div>
+
+<div class="bar clearfix summary_bar filter_tab_bar">
+ <div>
+ <ul class="tabs">
+ <li<?=($current['type'] == 'none' ? ' class="current"' : '')?>><a href="<?=FB_URL."/search?q={$q}"?>">All results</a></li>
+ <?=($count['extensions'] > 0 ? (($count['extensions'] == 1) ? '<li'.($current['type'] == ADDON_EXTENSION ? ' class="current"' : '').'><a href="'.FB_URL.'/search/type:'.ADDON_EXTENSION.'?q='.$q.'">1 extension</a></li>' : '<li'.($current['type'] == ADDON_EXTENSION ? ' class="current"' : '').'><a href="'.FB_URL.'/search/type:'.ADDON_EXTENSION.'?q='.$q.'">'.$count['extensions'].' extensions</a></li>') : '<li class="empty"><span>No extensions</span></li>')?>
+ <?=($count['themes'] > 0 ? (($count['themes'] == 1) ? '<li'.($current['type'] == ADDON_THEME ? ' class="current"' : '').'><a href="'.FB_URL.'/search/type:'.ADDON_THEME.'?q='.$q.'">1 theme</a></li>' : '<li'.($current['type'] == ADDON_THEME ? ' class="current"' : '').'><a href="'.FB_URL.'/search/type:'.ADDON_THEME.'?q='.$q.'">'.$count['themes'].' themes</a></li>') : '<li class="empty"><span>No themes</span></li>')?>
+ <? /* ($count['friends'] > 0 ? '<li'.($current['type'] == 'friends' ? ' class="current"' : '').'><a href="'.FB_URL.'/search/type:friends?q='.$q.'">'.$count['friends'].' from friends</a></li>' : '<li class="empty"><span>None from friends</span></li>') */ ?>
+ </ul>
+ </div>
+ <?=$facebook->pageNumbers($current, $count, 'search')?>
+</div>
+
+<?=$facebook->listAddons($addons)?>
+
+<div class="bar clearfix footer_bar">
+ <?=$facebook->pageNumbers($current, $count, 'search')?>
+</div> \ No newline at end of file
diff --git a/site/app/views/facebook/share.thtml b/site/app/views/facebook/share.thtml
new file mode 100644
index 0000000..fe02f32
--- /dev/null
+++ b/site/app/views/facebook/share.thtml
@@ -0,0 +1,70 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Justin Scott <fligtar@mozilla.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+if ($action == 'form') {
+ echo '<input type="hidden" name="url" value="'.SITE_URL.'/facebook/share/submit">';
+
+ if (!empty($favorites)) {
+ echo 'Select a favorite add-on to share: ';
+ echo '<select name="addon_id">';
+ foreach ($favorites as $favorite) {
+ echo '<option value="'.$favorite['addons']['id'].'">'.$favorite['translations']['name'].'</option>';
+ }
+ echo '</select>';
+ }
+ else {
+ echo 'You do not have any favorite add-ons to share with this user. <a href="'.FB_URL.'?ref=attach">Why not add some?</a>';
+ }
+}
+elseif ($action == 'submit') {
+ if (empty($error)) {
+ if ($addon['previewCount'] > 0) {
+ echo '<fb:wall-attachment-img src="'.FB_IMAGE_SITE.'/images/addon_preview/'.$addon['Addon']['id'].'/1" />';
+ echo '<a href="'.FB_URL.'/view/'.$addon['Addon']['id'].'?ref=attach"><img src="'.FB_IMAGE_SITE.'/images/addon_preview/'.$addon['Addon']['id'].'/1" align="right" border="0" width="100"></a>';
+ }
+ else {
+ echo '<fb:wall-attachment-img src="'.FB_IMAGE_SITE.'/img/facebook/no-preview-thumb.png" />';
+ }
+ echo '<h2><a href="'.FB_URL.'/view/'.$addon['Addon']['id'].'?ref=attach">'.$addon['Translation']['name']['string'].'</a></h2>';
+ echo $addon['Translation']['summary']['string'];
+ }
+ else {
+ echo $error;
+ }
+}
+?> \ No newline at end of file
diff --git a/site/app/views/facebook/updatenotes.thtml b/site/app/views/facebook/updatenotes.thtml
new file mode 100644
index 0000000..0893bc9
--- /dev/null
+++ b/site/app/views/facebook/updatenotes.thtml
@@ -0,0 +1,121 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Justin Scott <fligtar@mozilla.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+?>
+<style>
+ .body {
+ padding: 10px;
+ }
+ h1 {
+ border-bottom: 1px solid #d8dfea;
+ margin: 5px 10px;
+ padding-bottom: 2px;
+ font-size: 13px;
+ color: #333333;
+ }
+ h2 {
+ font-weight: bold;
+ font-size: 12px;
+ }
+ h2 span.date {
+ color: gray;
+ padding-left: 10px;
+ font-size: 10px;
+ }
+ .updates {
+ margin: 0px 20px;
+ margin-top: 10px;
+ }
+ .credits {
+ text-align: center;
+ font-style: italic;
+ }
+</style>
+
+<div class="body">
+ <h1>Update Notes</h1>
+
+ <div class="updates">
+ <div class="update">
+ <h2>0.6<span class="date">December 6, 2007</span></h2>
+ <ul>
+ <li>Feed stories now use templates</li>
+ <li>Add-ons can now be attached to wall posts and messages</li>
+ </ul>
+ </div>
+ <div class="update">
+ <h2>0.5<span class="date">September 28, 2007</span></h2>
+ <ul>
+ <li><a href="<?=FB_URL?>/invite?ref=un">Invitation tool</a> - invite your friends to Rock their Firefox!</li>
+ <li>Full size previews can now be viewed by clicking on the preview thumbnail</li>
+ <li>Newsfeed stories when friends add the application</li>
+ <li>Favorite removal confirmation dialog</li>
+ <li><a href="https://bugzilla.mozilla.org/buglist.cgi?query_format=advanced&product=addons.mozilla.org&component=Facebook+Application&target_milestone=RYF-0.5">Full list of fixed bugs</a></li>
+ </ul>
+ </div>
+ <div class="update">
+ <h2>0.4<span class="date">August 31, 2007</span></h2>
+ <ul>
+ <li>New homepage with add-on newsfeed</li>
+ <li>Ability to detect and import installed add-ons as favorites</li>
+ <li><a href="https://bugzilla.mozilla.org/buglist.cgi?query_format=advanced&product=addons.mozilla.org&component=Facebook+Application&target_milestone=RYF-0.4">Full list of fixed bugs</a></li>
+ </ul>
+ </div>
+ <div class="update">
+ <h2>0.3<span class="date">August 13, 2007</span></h2>
+ <ul>
+ <li><a href="<?=FB_URL?>/updatenotes">Update Notes</a> Page</li>
+ <li><a href="<?=FB_URL?>/wallpaper">Desktop Wallpaper</a> Page</li>
+ <li>Favorite indicator now shown in browse and search results</li>
+ <li>Long summaries are now properly trimmed</li>
+ <li>Friends' names now link to their favorite add-ons instead of their profile</li>
+ <li><a href="https://bugzilla.mozilla.org/buglist.cgi?query_format=advanced&product=addons.mozilla.org&component=Facebook+Application&target_milestone=RYF-0.3">Full list of fixed bugs</a></li>
+ </ul>
+ </div>
+ <div class="update">
+ <h2>0.2<span class="date">August 2, 2007</span></h2>
+ <ul>
+ <li>Initial public launch</li>
+ </ul>
+ </div>
+ </div>
+
+ <div class="credits">Some icons used in Rock Your Firefox are from the
+ <a href="http://www.famfamfam.com/lab/icons/silk/">famfamfam Silk Icon Set</a>,
+ licensed under a <a href="http://creativecommons.org/licenses/by/2.5/">Creative
+ Commons Attribution 2.5 License</a>.</div>
+</div> \ No newline at end of file
diff --git a/site/app/views/facebook/view.thtml b/site/app/views/facebook/view.thtml
new file mode 100644
index 0000000..2c732eb
--- /dev/null
+++ b/site/app/views/facebook/view.thtml
@@ -0,0 +1,265 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Justin Scott <fligtar@mozilla.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+?>
+<div id="content" class="clearfix">
+ <div class="grayheader clearfix">
+ <div class="left_side">
+ <?php if (!empty($addon['Addon']['icontype'])): ?>
+ <img src="<?=FB_IMAGE_SITE?>/images/addon_icon/<?=$addon['Addon']['id']?>" width=32 height=32 style="float: left; padding-right: 10px;">
+ <?php endif; ?>
+ <h2><?=$addon['Translation']['name']['string'].' '.$addon['Version'][0]['version']?></h2>
+ <p>by <?=implode($addon_authors, ', ')?></p>
+ </div>
+ <div class="right_side" style="width: inherit;">
+ <?php if ($isFavorite): ?>
+ <div style="float: left;">
+ <a href="<?=FB_URL?>/favorites/mine"><img src="<?=FB_IMAGE_SITE?>/img/facebook/medal.png" border=0 alt="Favorite Add-on" title="Favorite Add-on. Click to manage favorites."></a>
+ </div>
+ <?php else: ?>
+ <div class="dh_new_media_shell" style="float: left;"><a href="<?=FB_URL?>/favorite/add/<?=$addon['Addon']['id']?>/addon" class="dh_new_media"><div class="tr"><div class="bl"><div class="br"><span>Add to Favorites</span></div></div></div></a></div>
+ <?php endif; ?>
+ </div>
+ </div>
+ <div class="two_column profile clearfix">
+ <div class="left">
+ <?php if (!empty($addon['Translation']['privacypolicy']['string'])): ?>
+ <div id="privacypolicy" class="red" style="display: none;">
+ <div class="header"><div style="float: right;"><a href="#" clicktohide="privacypolicy">hide</a></div><h2>Privacy Policy</h2></div>
+ <div class="box clearfix description"><?=nl2br($addon['Translation']['privacypolicy']['string'])?></div>
+ </div>
+ <?php endif; ?>
+ <div class="header"><h2>Summary</h2></div>
+ <div class="box clearfix description"><?=nl2br($addon['Translation']['summary']['string'])?></div>
+ <div class="header"><h2>Description</h2></div>
+ <div class="box clearfix description"><?=nl2br($addon['Translation']['description']['string'])?></div>
+ <?php if (!empty($addon['Translation']['developercomments']['string'])): ?>
+ <div class="header"><h2>Developer Comments</h2></div>
+ <div class="box clearfix description"><?=nl2br($addon['Translation']['developercomments']['string'])?></div>
+ <?php endif;
+ if (!empty($version['Translation']['releasenotes']['string'])): ?>
+ <div class="header"><h2>Version Notes</h2></div>
+ <div class="box clearfix description"><?=nl2br($version['Translation']['releasenotes']['string'])?></div>
+ <?php endif; ?>
+ </div>
+ <div class="right">
+ <div class="picture" style="text-align: center;">
+ <?php
+ if ($previewCount > 0) {
+ ?>
+ <a href="#" onclick="var dialog = new Dialog().showMessage(preview_dialog_header, preview_dialog, 'Close'); resetDialog(); return false;">
+ <img src="<?=FB_IMAGE_SITE.'/images/addon_preview/'.$addon['Addon']['id']?>/1" alt="<?=htmlentities($addon['Translation']['name']['string'])?>" title="Click for more previews">
+ </a>
+ <img src="<?=FB_IMAGE_SITE?>/img/ajax_loading.gif" style="display: none;">
+ <fb:js-string var="preview_dialog">
+ <div style="text-align: center;">
+ <img id="preview_image" src="<?=FB_IMAGE_SITE.'/images/preview/'.$addon['Addon']['id']?>/1" style="max-width: 420px;" alt="<?=htmlentities($addon['Translation']['name']['string'])?>">
+ <div id="preview_caption"><?=$previewCaptions[0][0]['caption']?></div>
+ </div>
+ </fb:js-string>
+ <fb:js-string var="preview_dialog_header">
+ <div><?=$addon['Translation']['name']['string']?></div>
+ <table width="100%"><tr>
+ <td width="50%">Preview <span id="preview_counter" style="padding: 0; display: inline;">1</span> of <?=$previewCount?></td>
+ <td width="50%" align="right" style="text-align: right;">
+ <a href="#" style="display: none; color: white;" id="preview_previous" onClick="previousPreview(); return false;">&laquo; Previous</a>
+ <span id="preview_pipe" style="padding: 0; display: none;">&nbsp;|&nbsp;</span>
+ <a href="#" style="color: white;" id="preview_next" onClick="nextPreview(); return false;">Next &raquo;</a>
+ </td>
+ </tr></table>
+ </fb:js-string>
+ <script>
+ <!--
+ var currentPreview = 1;
+ var totalPreviews = <?=$previewCount?>;
+ var previewCaptions = {
+ <?php
+ if (!empty($previewCaptions)) {
+ $p = 1;
+ foreach ($previewCaptions as $previewCaption) {
+ echo "{$p}: '".addslashes($previewCaption[0]['caption'])."',\n";
+ $p++;
+ }
+ }
+ ?>
+ };
+
+ // Advance to next preview
+ function nextPreview() {
+ if (currentPreview != totalPreviews) {
+ currentPreview++;
+ updatePreview();
+ updateControls();
+ }
+ }
+
+ // Go to previous preview
+ function previousPreview() {
+ if (currentPreview != 1) {
+ currentPreview--;
+ updatePreview();
+ updateControls();
+ }
+ }
+
+ // Update preview counter, image src, and caption to current preview
+ function updatePreview() {
+ document.getElementById('preview_image').setSrc('<?=FB_IMAGE_SITE?>/img/ajax_loading.gif');
+ document.getElementById('preview_counter').setTextValue('' + currentPreview + '');
+ document.getElementById('preview_image').setSrc('<?=FB_IMAGE_SITE.'/images/preview/'.$addon['Addon']['id']?>/' + currentPreview);
+ document.getElementById('preview_caption').setTextValue(previewCaptions[currentPreview]);
+ }
+
+ // Update the next/previous links and pipe appropriately
+ function updateControls() {
+ document.getElementById('preview_pipe').setStyle('display', 'inline');
+
+ if (currentPreview == totalPreviews) {
+ document.getElementById('preview_next').setStyle('display', 'none');
+ document.getElementById('preview_pipe').setStyle('display', 'none');
+ }
+ else
+ document.getElementById('preview_next').setStyle('display', '');
+
+ if (currentPreview == 1) {
+ document.getElementById('preview_previous').setStyle('display', 'none');
+ document.getElementById('preview_pipe').setStyle('display', 'none');
+ }
+ else
+ document.getElementById('preview_previous').setStyle('display', '');
+ }
+
+ // Reset dialog to first preview
+ function resetDialog() {
+ currentPreview = 1;
+ updatePreview();
+ updateControls();
+ }
+ //-->
+ </script>
+ <?php
+ }
+ else
+ echo '<img src="'.FB_IMAGE_SITE.'/img/facebook/no-preview.png" alt="'.htmlentities($addon['Translation']['name']['string']).'">';
+ ?>
+ </div>
+ <?php
+ if (!$this->controller->_usingSupportedBrowser()) {
+ echo '<div style="text-align: center;"><a href="http://www.mozilla.com/en-US/firefox/?ref=facebookapp"><img src="'.SITE_URL.'/img/facebook/non-firefox-box.png" border=0></a></div>';
+ }
+ else {
+ if (strpos($_SERVER['HTTP_USER_AGENT'], 'Win') !== false)
+ $platform = PLATFORM_WIN;
+ elseif (strpos($_SERVER['HTTP_USER_AGENT'], 'Mac') !== false)
+ $platform = PLATFORM_MAC;
+ else
+ $platform = PLATFORM_LINUX;
+
+ // Go through each file and if the platform is supported, use it
+ if (!empty($version['File'])) {
+ foreach ($version['File'] as $file) {
+ if ($file['platform_id'] == PLATFORM_ALL || $file['platform_id'] == $platform) {
+ $file_id = $file['id'];
+ }
+ }
+
+ if (!empty($file_id)) {
+ ?>
+ <div class="installbox">
+ <div id="confirm_button" class="confirm_button" style="margin: 0 auto;">
+ <a href="<?=FB_INSTALL_SITE?>/facebookinstall/install/<?=$file_id?>"><div><div><div><span>Install Now</span></div></div></div></a>
+ </div>
+ </div>
+ <?php
+ }
+ else {
+ echo '<div style="text-align: center;">Not available for this platform.</div>';
+ }
+ }
+ }
+ ?>
+ <br>
+ <div class="profileActions clearfix">
+ <?=(!empty($addon['Translation']['privacypolicy']['string']) ? '<a href="#" clicktotoggle="privacypolicy">Privacy Policy</a>' : '')?>
+ <?=(!empty($addon['Translation']['homepage']['string']) ? '<a href="'.$addon['Translation']['homepage']['string'].'" target="_blank">Add-on Homepage</a>' : '')?>
+ <a href="https://addons.mozilla.org/addon/<?=$addon['Addon']['id']?>">Mozilla Add-ons Listing</a>
+ </div>
+
+ <div class="header"><h2>Recommended By</h2></div>
+ <?php
+ if (!empty($addon['allRecommended'])) {
+ echo '<div class="box_subhead">';
+ echo '<div class="box_subtitle">';
+ echo '<a href="'.FB_URL.'/favorites/addon/'.$addon['Addon']['id'].'/all">'.count($addon['allRecommended']).' '.(count($addon['allRecommended']) == 1 ? 'person' : 'people').'</a>, ';
+ echo '<a href="'.FB_URL.'/favorites/addon/'.$addon['Addon']['id'].'/friends">'.$addon['friendRecommended'].' '.($addon['friendRecommended'] == 1 ? 'friend' : 'friends').'</a>';
+ echo '</div>';
+ echo '<div class="box_actions"><a href="'.FB_URL.'/favorites/addon/'.$addon['Addon']['id'].'">See All</a></div>';
+ echo '</div>';
+ }
+ else {
+ echo '<div class="box_nopeople">No one yet. <a href="'.FB_URL.'/favorite/add/'.$addon['Addon']['id'].'">Be the first!</a></div>';
+ }
+ ?>
+ <div class="guests clearfix">
+ <table class="people_table" cellspacing="2" cellpadding="0" border="0" height="100%">
+ <tr>
+ <?php
+ for ($i = 0; $i < 3; $i++) {
+ if (!empty($addon['allRecommended'][$i])) {
+ echo '<td width="34%"><fb:profile-pic uid="'.$addon['allRecommended'][$i]['FacebookFavorite']['fb_user'].'" linked="yes"/><br><fb:if-can-see uid="'.$addon['allRecommended'][$i]['FacebookFavorite']['fb_user'].'"><fb:userlink uid="'.$addon['allRecommended'][$i]['FacebookFavorite']['fb_user'].'" /><fb:else>Anonymous</fb:else></fb:if-can-see></td>';
+ }
+ }
+ ?>
+ </tr>
+ </table>
+ </div>
+ <div style="text-align: center; padding: 10px;">
+ <fb:share-button class="meta">
+ <meta name="title" content="<?=htmlentities($addon['Translation']['name']['string'])?>" />
+ <meta name="description" content="<?=htmlentities($addon['Translation']['summary']['string'])?>" />
+ <link rel="target_url" href="<?=FB_URL?>/view/<?=$addon['Addon']['id']?>" />
+ <?php
+ for ($p = 1; $p <= $previewCount; $p++) {
+ echo '<link rel="image_src" href="'.FB_IMAGE_SITE.'/images/addon_preview/'.$addon['Addon']['id'].'/'.$p.'" />';
+ }
+ ?>
+ </fb:share-button>
+ </div>
+ <br>
+ </div> <!-- right -->
+ </div> <!-- two column -->
+</div> <!-- content --> \ No newline at end of file
diff --git a/site/app/views/facebook/wallpaper.thtml b/site/app/views/facebook/wallpaper.thtml
new file mode 100644
index 0000000..a6f22af
--- /dev/null
+++ b/site/app/views/facebook/wallpaper.thtml
@@ -0,0 +1,71 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Justin Scott <fligtar@mozilla.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+?>
+<style>
+ .body {
+ padding: 10px;
+ }
+ h1 {
+ border-bottom: 1px solid #d8dfea;
+ margin: 5px 10px;
+ padding-bottom: 2px;
+ font-size: 13px;
+ color: #333333;
+ }
+ .wallpaper {
+ margin: 0px 20px;
+ margin-top: 10px;
+ }
+</style>
+
+<div class="body">
+ <h1>Desktop Wallpaper</h1>
+
+ <div class="wallpaper">
+ Rock your desktop with official Rock Your Firefox desktop wallpaper! Just click on a resolution below, right click on the image, and select "Set As Desktop Background..."
+ <img src="<?=FB_IMAGE_SITE?>/img/facebook/wallpaper/rock_firefox_preview.png" align="left" style="padding: 20px;">
+ <ul style="padding: 10px; margin-top: 20px;">
+ <li><a href="<?=FB_IMAGE_SITE?>/img/facebook/wallpaper/rock_firefox_800x600.jpg">800 x 600</a></li>
+ <li><a href="<?=FB_IMAGE_SITE?>/img/facebook/wallpaper/rock_firefox_1024x768.jpg">1024 x 768</a></li>
+ <li><a href="<?=FB_IMAGE_SITE?>/img/facebook/wallpaper/rock_firefox_1280x1024.jpg">1280 x 1024</a></li>
+ <li><a href="<?=FB_IMAGE_SITE?>/img/facebook/wallpaper/rock_firefox_1440x900.jpg">1440 x 900</a></li>
+ <li><a href="<?=FB_IMAGE_SITE?>/img/facebook/wallpaper/rock_firefox_1680x1050.jpg">1680 x 1050</a></li>
+ <li><a href="<?=FB_IMAGE_SITE?>/img/facebook/wallpaper/rock_firefox_1920x1200.jpg">1920 x 1200</a></li>
+ </ul>
+ </div>
+</div> \ No newline at end of file
diff --git a/site/app/views/files/browse.thtml b/site/app/views/files/browse.thtml
new file mode 100644
index 0000000..766eb00
--- /dev/null
+++ b/site/app/views/files/browse.thtml
@@ -0,0 +1,75 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * Justin Scott <fligtar@gmail.com>.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+?>
+<html xmlns="http://www.w3.org/1999/xhtml" version="-//W3C//DTD XHTML 1.1//EN" xml:lang="en">
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
+ <?=$html->css('filebrowser')?>
+ <?=$javascript->link('filebrowser')?>
+ <?=$javascript->link('listing')?>
+ <?=$javascript->link('scriptaculous/prototype')?>
+ <?=$javascript->link('scriptaculous/scriptaculous.js')?>
+ <title><?=sprintf(___('file_browser_title', '%s :: File Browser :: %s Add-ons'), $addonname, APP_PRETTYNAME)?></title>
+</head>
+<body>
+ <?
+$files['dir'] = 1;
+$files['filename'] = 'extension.xpi';
+?>
+<iframe id="fileBrowser" src="<?=$html->url(isset($is_diff)?'/files/diff/'.$id.'?compare='.$startfile:'/files/browse/'.$id.'/?view='.$startfile)?>" border="0"></iframe>
+<div id="fileContents">
+ <div id="fileHeader">
+ <?=$html->image('template/moz-com-logo.png')?>
+ </div>
+ <div id="fileListing">
+ <ul class="fileList">
+ <?=$listing->listFiles($files, $id, isset($is_diff))?>
+ </ul>
+ </div>
+ <div id="fileFooter">
+ <?=($review == 1) ? $html->link(___('file_browser_link_review', 'Back to Review'), '/editors/review/'.$version) :
+ $html->link(___('file_browser_link_addon', 'Back to Add-on'), '/addon/'.$addon)?>
+ &nbsp;&middot;&nbsp;
+ <?=$html->link(___('file_browser_link_expand_all', 'Expand All'), 'javascript: void(0);', array('onClick' => 'expandNodes();'))?>&nbsp;&middot;&nbsp;
+ <?=$html->link(___('file_browser_toggle_expand_collapse', '+/-'), 'javascript: void(0);', array('onClick' => 'toggleFileListing();', 'id' => 'fileControl'))?>&nbsp;&nbsp;
+ </div>
+</div>
+<script language="JavaScript" type="text/javascript">
+ new Draggable('fileContents', {handle:'fileHeader'});
+</script>
+</body>
+</html>
diff --git a/site/app/views/files/view.thtml b/site/app/views/files/view.thtml
new file mode 100644
index 0000000..9f9a9ef
--- /dev/null
+++ b/site/app/views/files/view.thtml
@@ -0,0 +1,51 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * Justin Scott <fligtar@gmail.com>.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Frederic Wenzel <fwenzel@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+echo $html->css('diff', 'stylesheet', array('media'=>'all'))."\n";
+echo '<span style="font-weight: bold; font-size: 12px; font-family: verdana, sans-serif;">'.$filename.'</span>';
+echo '<pre>';
+if (is_array($contents)) {
+ foreach ($contents as $line) {
+ echo $line;
+ }
+}
+else {
+ echo $contents;
+}
+echo '</pre>';
+?>
diff --git a/site/app/views/groups/add.thtml b/site/app/views/groups/add.thtml
new file mode 100644
index 0000000..760a5f6
--- /dev/null
+++ b/site/app/views/groups/add.thtml
@@ -0,0 +1,60 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Mike Morgan <morgamic@mozilla.com> (Original Developer)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+?>
+<h2>New Group</h2>
+
+<form action="<?php echo $html->url('/groups/add'); ?>" method="post">
+<?=$html->hiddenSession() ?>
+<div class="required">
+ <label for="GroupName" class="amo-label-small">Name</label>
+ <?php echo $html->input('Group/name', array('size' => '60'));?>
+ <?php echo $html->tagErrorMsg('Group/name', 'Please enter the Name.');?>
+</div>
+<div class="required">
+ <label for="GroupRules" class="amo-label-small">Rules</label>
+ <?php echo $html->textarea('Group/rules', array('cols'=>60, 'rows'=>10)); ?>
+ <?php echo $html->tagErrorMsg('Group/rules', 'Please check the format of your rules entry.');?>
+</div>
+<div class="submit">
+ <?php echo $html->submit('Add');?>
+</div>
+</form>
+
+<ul class="actions">
+<li><?php echo $html->link('List Groups', '/groups/index')?></li>
+</ul>
diff --git a/site/app/views/groups/edit.thtml b/site/app/views/groups/edit.thtml
new file mode 100644
index 0000000..d1e9092
--- /dev/null
+++ b/site/app/views/groups/edit.thtml
@@ -0,0 +1,59 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Mike Morgan <morgamic@mozilla.com> (Original Developer)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+?>
+<h2>Edit Group</h2>
+<form action="<?php echo $html->url('/groups/edit/'.$html->tagValue('Group/id')); ?>" method="post" class="amo-form corner-box">
+<?=$html->hiddenSession() ?>
+<div class="required">
+ <label for="GroupName" class="amo-label-small">Name</label>
+ <?php echo $html->input('Group/name', array('size' => '60'));?>
+ <?php echo $html->tagErrorMsg('Group/name', 'Please enter the Name.');?>
+</div>
+<div class="required">
+ <label for="GroupRules" class="amo-label-small">Rules</label>
+ <?php echo $html->textarea('Group/rules', array('cols'=>60, 'rows'=>10)); ?>
+ <?php echo $html->tagErrorMsg('Group/rules', 'Please check the format of your rules entry.');?>
+</div>
+<?php echo $html->hidden('Group/id')?>
+<div class="submit">
+ <?php echo $html->submit('Save');?>
+</div>
+</form>
+<ul class="actions">
+<li><?php echo $html->link('List Groups', '/groups/index')?></li>
+</ul>
diff --git a/site/app/views/groups/index.thtml b/site/app/views/groups/index.thtml
new file mode 100644
index 0000000..9469887
--- /dev/null
+++ b/site/app/views/groups/index.thtml
@@ -0,0 +1,69 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Mike Morgan <morgamic@mozilla.com> (Original Developer)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+?>
+<div class="groups">
+<h2>List Groups</h2>
+
+<table class="dalvay-table">
+<tr>
+ <th>Id</th>
+ <th>Name</th>
+ <th>Rules</th>
+ <th>Created</th>
+ <th>Modified</th>
+ <th>Actions</th>
+</tr>
+<?php foreach ($groups as $group): ?>
+<tr>
+ <td><?php echo $group['Group']['id']; ?></td>
+ <td><?php echo $group['Group']['name']; ?></td>
+ <td><?php echo $group['Group']['rules']; ?></td>
+ <td><?php echo $group['Group']['created']; ?></td>
+ <td><?php echo $group['Group']['modified']; ?></td>
+ <td nowrap>
+ <?php echo $html->link('Edit','/groups/edit/' . $group['Group']['id'])?>
+ <?php echo $html->link('Delete','/groups/delete/' . $group['Group']['id'], null, 'Are you sure you want to delete id ' . $group['Group']['id'])?>
+ </td>
+</tr>
+<?php endforeach; ?>
+</table>
+
+<ul class="actions">
+ <li><?php echo $html->link('New Group', '/groups/add'); ?></li>
+</ul>
+</div>
diff --git a/site/app/views/helpers/addons_html.php b/site/app/views/helpers/addons_html.php
new file mode 100644
index 0000000..e996a82
--- /dev/null
+++ b/site/app/views/helpers/addons_html.php
@@ -0,0 +1,600 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * Frederic Wenzel <fwenzel@mozilla.com> .
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Wil Clouser <clouserw@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+require_once(LIBS.DS.'view'.DS.'helpers'.DS.'html.php');
+
+/**
+ * Extends the cake Html helper in order to make urls including locales
+ */
+class AddonsHtmlHelper extends HtmlHelper
+{
+ /**
+ * Add the locale to the URLs?
+ */
+ var $addLocale = true;
+
+ /**
+ * Add the application to the URLs?
+ */
+ var $addApplication = true;
+
+ var $doctype = 'html4-trans';
+
+ /**
+ * Overrides the HTMLHelper's formTag to handle AMO CSRF stuff in a way not involving cookies Bug427974
+ */
+ function formTag($target = null, $type = 'post', $htmlAttributes = array()) {
+ $ret = HtmlHelper::formTag($target, $type, $htmlAttributes);
+ $ret .= $this->hiddenSession();
+ return $ret;
+ }
+
+ /**
+ * Adds a hidden form variable to do session/token checking to handle
+ * AMO CSRF stuff in a way not involving cookies (bug 427974)
+ *
+ * WARNING: $this->controller->Session not always defined when this method
+ * called so using $_SESSION
+ * For example, this happens when editng settings on the statistics dashboard.
+ *
+ * @see AppController::checkCSRF
+ */
+ function hiddenSession() {
+ if (isset($_SESSION['User']['id'])) {
+ $id = $_SESSION['User']['id'];
+ } else {
+ return ""; // no session so bail.
+ }
+
+ $current_epoch = (int)(time()/CAKE_SESSION_TIMEOUT);
+
+ return sprintf('<div class="hsession"><input type="hidden" '
+ .'name="sessionCheck" value="%s" /></div>',
+ md5(session_id().$id.$current_epoch));
+ }
+
+ /**
+ * same as link(), but no locale info added to base URL
+ */
+ function linkNoLocale($title, $url = null, $htmlAttributes = null, $confirmMessage = false, $escapeTitle = false, $return = false) {
+ // switch off adding of locales for this
+ $oldAddLocale = $this->addLocale;
+ $this->addLocale = false;
+ $ret = $this->link($title, $url, $htmlAttributes, $confirmMessage, $escapeTitle, $return);
+
+ // switch locale handling back on
+ $this->addLocale = $oldAddLocale;
+ return $ret;
+ }
+
+ function linkNoLocaleNoApp($title, $url = null, $htmlAttributes = null, $confirmMessage = false, $escapeTitle = false, $return = false) {
+ // switch off adding of locales for this
+ $_oldAddLocale = $this->addLocale;
+ $_oldAddApplication = $this->addApplication;
+ $this->addLocale = $this->addApplication = false;
+
+ $ret = $this->link($title, $url, $htmlAttributes, $confirmMessage, $escapeTitle, $return);
+
+ // switch locale handling back on
+ $this->addLocale = $_oldAddLocale;
+ $this->addApplication = $_oldAddApplication;
+ return $ret;
+ }
+
+ function link($title, $url = null, $htmlAttributes = null, $confirmMessage = false, $escapeTitle = false, $return = false) {
+ return parent::link($title, $url, $htmlAttributes, $confirmMessage, $escapeTitle, $return);
+ }
+
+ /**
+ * creates an <a href> link to a file
+ */
+ function linkFile($fileId, $title, $path, $htmlAttributes = array(), $return = false, $filename = null, $collection_id = null) {
+ if (strpos($path, '://')!==false) {
+ $url = $path;
+ } else {
+ $url = $this->webroot;
+ // Rewrite base address to include locale, if applicable
+ if ($this->addLocale) {
+ $url .= LANG;
+ }
+ // Rewrite base address to include application name, if applicable
+ if ($this->addApplication) {
+ $url .= '/'.APP_SHORTNAME;
+ }
+ $url .= '/' . FILES_URL . "/{$fileId}";
+
+ // optionally add file name for Save As to work correctly
+ if (!empty($filename))
+ $url .= "/$filename";
+
+ // optionally add a collection stats code to the URL
+ if (!empty($collection_id))
+ $url .= "?collection_id={$collection_id}";
+ }
+ return $this->output(sprintf($this->tags['link'], $url, $this->parseHtmlOptions($htmlAttributes, null, '', ' '), $title), $return);
+ }
+ /**
+ * returns the url to $fileId
+ */
+ function urlFile($fileId, $filename = null, $collection_id = null) {
+ $url = $this->base . '/';
+ $url .= LANG;
+ $url .= '/'.APP_SHORTNAME;
+ $url .= '/' . FILES_URL . "/{$fileId}";
+
+ //optionally add file name for Save As to work correctly
+ if (!empty($filename))
+ $url .= "/$filename";
+
+ // optionally add a collection stats code to the URL
+ if (!empty($collection_id))
+ $url .= "?collection_id={$collection_id}";
+
+ return $url;
+ }
+
+ function urlImage($filename) {
+ $base = $this->url('/', true, false, false);
+
+ $imgpath = $base . IMAGES_URL . $filename;
+
+ return $imgpath;
+ }
+ /**
+ * Link to a user's profile, using their nickname if present and first+last if not.
+ */
+ function linkUser($userId, $first, $last, $nickname = null, $params = array('class' => 'profileLink')) {
+ if (empty($nickname))
+ $nickname = $first . ' ' . $last;
+ return $this->link($nickname, '/user/' . $userId, $params);
+ }
+
+ /**
+ * Link to a user's profile given a user model result array
+ */
+ function linkUserFromModel($userModel, $params = array('class'=>'profileLink')) {
+ if ($userModel['nickname'] == 'Deleted User') // XXX slightly ugly way of determining a deleted user
+ $nickname = ___('user_deleted_nickname', 'Deleted User');
+ else
+ $nickname = $userModel['nickname'];
+ return $this->linkUser($userModel['id'], $userModel['firstname'],
+ $userModel['lastname'], $nickname, $params);
+ }
+
+ /**
+ * Link to a list of users, using a model result set
+ * @param array usersModel model array with multiple users
+ * @param int maxUsers show this many users before writing "and others" (0 = no limit)
+ * @param string moreLink URL to link to on "and others"
+ * @param array params additional link parameters for the author links
+ */
+ function linkUsersFromModel($usersModel, $maxUsers = null,
+ $moreLink = null, $params = array('class'=>'profileLink')) {
+
+ if (!is_int($maxUsers) || $maxUsers < 0) $maxUsers = 2;
+
+ if ($maxUsers > 0) {
+ $showOthers = (count($usersModel)>$maxUsers);
+ $usersModel = array_slice($usersModel, 0, $maxUsers);
+ } else {
+ $showOthers = false;
+ }
+
+ $text = @implode(", ", array_map(array(&$this, 'linkUserFromModel'), $usersModel));
+
+ if ($showOthers) {
+ $text .= ', ';
+ $_linktext = _('other_users');
+ if ($moreLink)
+ $text .= $this->link($_linktext, $moreLink);
+ else
+ $text .= $_linktext;
+ }
+ return $text;
+ }
+
+ /**
+ * Helper for getting a URL without application and locale.
+ */
+ function rootUrl($url = null) {
+ return $this->url($url, false, false, false);
+ }
+
+ /**
+ * locale and application aware url generator function
+ */
+ function url($url = null, $return = false, $addLocale = true, $addApplication = true) {
+ $oldbase = $this->base;
+
+ if (!empty($this->plugin)) {
+ $newbase = strip_plugin($this->base, $this->plugin);
+ } else {
+ $newbase = $this->base;
+ }
+
+ // Rewrite base address to include locale, if applicable
+ if ($addLocale && $this->addLocale) {
+ $newbase .= '/'.LANG;
+ }
+
+ // Don't add the application/layout if url goes to an other_layout controller
+ global $other_layouts;
+ $parts = explode('/', $url);
+ if (count($parts) > 1) {
+ $controller = !empty($parts[0]) ? $parts[0] : $parts[1];
+ }
+ if (!empty($controller) && array_key_exists($controller, $other_layouts)) {
+ $addApplication = false;
+ }
+
+ // Rewrite base address to include application name, if applicable
+ if ($addApplication && $this->addApplication) {
+ $newbase .= '/'.APP_SHORTNAME;
+ }
+
+ if (!empty($this->plugin)) {
+ $newbase .= '/'.$this->plugin;
+ }
+
+ $this->base = $newbase;
+ $ret = parent::url($url, $return, true);
+
+ $this->base = $oldbase;
+ return $ret;
+ }
+
+ /**
+ * (Cake-relative) URL to login page, including return-to parameter
+ */
+ function login_url($target = null, $add_get_parameters = true, $logout = false) {
+ if (!empty($target)) {
+ $_forward_to = $target;
+ } else {
+ // Shouldn't see anything weird here, because it has to be a valid cake url
+ $_forward_to = empty($this->params['url']['url']) ? '' : $this->params['url']['url'];
+ }
+ $get_params = array();
+
+ if ($add_get_parameters) {
+ // add GET parameters
+ foreach($this->params['url'] as $_key => $_param)
+ if ($_key != 'url') $get_params[] = "{$_key}={$_param}";
+ if (!empty($get_params)) $_forward_to .= '?'.implode('&',$get_params);
+ }
+
+ if(!isset($this->params['url']['to'])) {
+ $_forward_to = urlencode($_forward_to); // urlencode entities in the parameters
+ } else {
+ $_forward_to = urlencode($this->params['url']['to']);
+ }
+
+ $_forward_to = '?to='.$_forward_to;
+ return '/users/log'.(!$logout?'in':'out').$_forward_to;
+ }
+
+ /**
+ * (Cake-relative) URL to logout page, including return-to parameter
+ */
+ function logout_url($target = null, $add_get_parameters = true) {
+ return $this->login_url($target, $add_get_parameters, true);
+ }
+
+ /**
+ * wrapper for htmlentities, quote-safe.
+ */
+ function entities($unsafe) {
+ return htmlentities($unsafe, ENT_QUOTES, 'UTF-8');
+ }
+
+ /**
+ * un-apply cakePHP's Sanitize::html
+ * use this to recover initial strings from publish()ed data
+ *
+ * @param String pubdata a string that was html-encoded by the publish() function
+ * @return un-sanitized string
+ */
+ function unsanitize($pubdata) {
+ global $unsanitize_patterns;
+ // apply tag replacements backwards, then return
+ return preg_replace($unsanitize_patterns['patterns'], $unsanitize_patterns['replacements'], $pubdata);
+ }
+
+ /**
+ * for echoing files without blowing the memory limit
+ */
+ function readfile_chunked($filename) {
+ $chunk = 1*(1024*1024);
+ $buffer = '';
+ $fh = fopen($filename, 'rb');
+ if (!$fh) {
+ return false;
+ }
+ while (!feof($fh)) {
+ $buffer = fread($fh, $chunk);
+ echo $buffer;
+ ob_flush();
+ flush();
+ }
+ $status = fclose($fh);
+
+ return $status;
+ }
+
+ /**
+ * Change Cake's default from escaping fields with HTML entities
+ * to requiring explicit instructions via the 'escape' parameter
+ *
+ * See line 984 of real HtmlHelper.
+ */
+ function _parseAttributes($options, $exclude = null, $insertBefore = ' ', $insertAfter = null) {
+ if (empty($options)) {
+ $options = array();
+ }
+
+ if (!is_array($options) || !array_key_exists('escape', $options)) {
+ $options['escape'] = false;
+ }
+
+ return parent::_parseAttributes($options, $exclude, $insertBefore, $insertAfter);
+ }
+
+ /**
+ * Replace '\n' by actual line break character (to be used with gettext
+ * strings, which return '\n' in plain text)
+ *
+ * @param string $text Text to replace line breaks in
+ * @param bool $br replace by HTML <br/> tags instead
+ */
+ function lineBreaks($text, $br = false) {
+ if ($br)
+ return str_replace('\n', '<br/>', $text);
+ else
+ return str_replace('\n', "\n", $text);
+ }
+
+ /**
+ * Creates an image input widget (backported from Cake 1.2's form helper)
+ *
+ * @param string $path Path to the image file, relative to the webroot/img/ directory.
+ * @param array $options Array of HTML attributes.
+ * @return string HTML submit image element
+ */
+ function submitImage($path, $options = array()) {
+ if (strpos($path, '://')) {
+ $url = $path;
+ } else {
+ $url = $this->webroot . $this->themeWeb . IMAGES_URL . $path;
+ }
+ return $this->output(sprintf($this->tags['submitimage'], $url, $this->_parseAttributes($options, null, '', ' ')));
+ }
+
+ /**
+ * Create an HTML select tag. Behaves exactly like CakePHP's html->selectTag(),
+ * but it allows simpler name attributes than Cake's Model/Field style.
+ */
+ function simpleSelectTag($fieldName, $optionElements, $selected = null, $selectAttr = array(), $optionAttr = null, $showEmpty = true, $return = false) {
+ $result = $this->selectTag('Re/Place', $optionElements, $selected, $selectAttr, $optionAttr, $showEmpty, true);
+ $result = str_replace(array('data[Re][Place]', 'RePlace'), $fieldName, $result);
+
+ if ($return)
+ return $result;
+ else
+ echo $result;
+ }
+
+ /**
+ * multibyte-safe number_format function.
+ * Uses regular php number_format with "safe" placeholders, then replaces
+ * them by their actual (possibly multi-byte) counterparts.
+ */
+ function number_format($number, $num_decimal_places = 0) {
+ $localeconv = localeconv();
+ $placeholders = array('@', '~');
+ $actual = array($localeconv['decimal_point'], $localeconv['thousands_sep']);
+
+ // format number with placeholders
+ $formatted = number_format($number, $num_decimal_places,
+ $placeholders[0], $placeholders[1]);
+
+ // replace by localized characters
+ $formatted = str_replace($placeholders, $actual, $formatted);
+
+ return $formatted;
+ }
+
+ /**
+ * Returns a formatted SELECT element.
+ *
+ * Bug 458329: Cake's selectTag() helper doesn't properly
+ * escape quotes or line breaks for use as option
+ * values. So, it's done here in an overridden version
+ *
+ * @param string $fieldName Name attribute of the SELECT
+ * @param array $optionElements Array of the OPTION elements (as 'value'=>'Text' pairs) to be used in the SELECT element
+ * @param mixed $selected Selected option
+ * @param array $selectAttr Array of HTML options for the opening SELECT element
+ * @param array $optionAttr Array of HTML options for the enclosed OPTION elements
+ * @param boolean $show_empty If true, the empty select option is shown
+ * @param boolean $return Whether this method should return a value
+ * @return string Formatted SELECT element
+ * @access public
+ */
+ function selectTag($fieldName, $optionElements, $selected = null, $selectAttr = array(), $optionAttr = null, $showEmpty = true, $return = false) {
+ $this->setFormTag($fieldName);
+ if ($this->tagIsInvalid($this->model, $this->field)) {
+ if (isset($selectAttr['class']) && trim($selectAttr['class']) != "") {
+ $selectAttr['class'] .= ' form_error';
+ } else {
+ $selectAttr['class'] = 'form_error';
+ }
+ }
+ if (!isset($selectAttr['id'])) {
+ $selectAttr['id'] = $this->model . Inflector::camelize($this->field);
+ }
+
+ if (!is_array($optionElements)) {
+ return null;
+ }
+
+ if (!isset($selected)) {
+ $selected = $this->tagValue($fieldName);
+ }
+
+ if (isset($selectAttr) && array_key_exists("multiple", $selectAttr)) {
+ $select[] = sprintf($this->tags['selectmultiplestart'], $this->model, $this->field, $this->parseHtmlOptions($selectAttr));
+ } else {
+ $select[] = sprintf($this->tags['selectstart'], $this->model, $this->field, $this->parseHtmlOptions($selectAttr));
+ }
+
+ if ($showEmpty == true) {
+ $select[] = sprintf($this->tags['selectempty'], $this->parseHtmlOptions($optionAttr));
+ }
+
+ foreach ($optionElements as $name => $title) {
+ $optionsHere = $optionAttr;
+
+ if (($selected != null) && ($selected == $name)) {
+ $optionsHere['selected'] = 'selected';
+ } elseif (is_array($selected) && in_array($name, $selected)) {
+ $optionsHere['selected'] = 'selected';
+ }
+
+ // HTML-escape the option value, even the line breaks
+ $name = h($name);
+ $name = str_replace("\n", '&#10;', $name);
+ $name = str_replace("\r", '&#13;', $name);
+
+ $select[] = sprintf($this->tags['selectoption'], $name, $this->parseHtmlOptions($optionsHere), h($title));
+ }
+
+ $select[] = sprintf($this->tags['selectend']);
+ return $this->output(implode("\n", $select), $return);
+ }
+
+ function truncateChars($length, $string, $onSpaces = false) {
+ if (mb_strlen($string) <= $length) {
+ return $string;
+ } else {
+ if($onSpaces) {
+ $string = mb_substr($string, 0, $length-3);
+ $sub = mb_substr($string, 0, mb_strrpos($string, ' '));
+ } else {
+ $sub = mb_substr($string, 0, $length - 3);
+ }
+ return $sub.'...';
+ }
+ }
+
+ /**
+ * Returns the value of $statusMap according to the status of $addon.
+ *
+ * @param array $addon Addon object
+ * @param array $statusMap assoc array with keys 'experimental',
+ * 'recommended', and 'default'
+ */
+ function byStatus($addon, $statusMap) {
+ global $experimental_status;
+ if (in_array($addon['Addon']['status'], $experimental_status)) {
+ return $statusMap['experimental'];
+ } elseif ((isset($addon['Addon']['recommended']) && $addon['Addon']['recommended']) || $this->isFeatured($addon))
+ {
+ return $statusMap['recommended'];
+ } else {
+ return $statusMap['default'];
+ }
+ }
+
+ function extraClass($addon, $default='') {
+ return $this->byStatus($addon, array('experimental' => 'exp',
+ 'recommended' => 'rec',
+ 'default' => $default));
+ }
+
+ /**
+ * Returns true or false if the addon is featured
+ *
+ * @param array $addon Addon object
+ * @return boolean True/false if addon is featured
+ */
+ function isFeatured($addon) {
+ $featured = false;
+
+ foreach($addon['AddonTag'] as $tag) {
+ if($tag['feature'] == 1) {
+ $featured = true;
+ break;
+ }
+ }
+ return $featured;
+ }
+
+ function flag($addon, $default='') {
+ $flag = $this->byStatus($addon, array(
+ 'experimental' => $this->link(___('addon_listitem_flag_experimental'),
+ '/pages/faq#experimental-addons'),
+ 'recommended' => $this->link(___('addon_listitem_flag_recommended'),
+ '/pages/faq#recommended-addons'),
+ 'default' => $default
+ ));
+ if (!empty($flag)) {
+ return '<h5 class="flag">'.$flag.'</h5>';
+ } else {
+ return '';
+ }
+ }
+
+ /**
+ * This is copied from cake, but with less fail.
+ *
+ * If $model->validationErrors[$field] is 1, we'll show $default_text.
+ * This is for backwards compat with $model->invalidate.
+ *
+ * If $model->validationErrors[$field] is a string, we'll use that as
+ * the error message.
+ */
+ function tagErrorMsg($field, $text) {
+ $this->setFormTag($field);
+ if ($error = $this->tagIsInvalid($this->model, $this->field)) {
+ $msg = is_string($error) ? $error : $text;
+ return sprintf('<div class="error_message">%s</div>', $msg);
+ } else {
+ return null;
+ }
+ }
+}
+?>
diff --git a/site/app/views/helpers/facebook.php b/site/app/views/helpers/facebook.php
new file mode 100644
index 0000000..a089a29
--- /dev/null
+++ b/site/app/views/helpers/facebook.php
@@ -0,0 +1,258 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Justin Scott <fligtar@mozilla.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+class FacebookHelper extends Helper {
+ var $helpers = array('Html');
+
+ var $globalURLAdditional = '';
+ var $pagesString = '';
+
+ function listAddons($addons) {
+ echo '<div class="results" style="background-color: #f7f7f7; padding: 10px;">';
+
+ if (!empty($addons)) {
+ foreach ($addons as $addon) {
+ echo '<div class="resultitem" style="border: 1px solid #cccccc; background-color: white; padding: 5px; height: 75px; margin-bottom: 5px;">';
+ echo '<a href="'.FB_URL.'/view/'.$addon['Addon']['id'].'">';
+ if ($addon['previewCount'] > 0)
+ echo '<img src="'.FB_IMAGE_SITE.'/images/addon_preview/'.$addon['Addon']['id'].'/1" width=100 height=75 border=0 style="float: left; padding-right: 5px;" alt="'.htmlentities($addon['Translation']['name']['string']).'">';
+ else
+ echo '<img src="'.FB_IMAGE_SITE.'/img/facebook/no-preview-thumb.png" width=100 height=75 border=0 style="float: left; padding-right: 5px;" alt="'.htmlentities($addon['Translation']['name']['string']).'">';
+ echo '</a>';
+ echo '<div>';
+ echo '<div style="font-weight: bold; font-size: 120%;">';
+ if ($this->view->controller->FacebookFavorite->isFavorite($this->view->controller->fbUser, $addon['Addon']['id'], true)) {
+ echo '<img src="'.FB_IMAGE_SITE.'/img/facebook/smallMedal.png" style="padding-right: 5px;" alt="You recommend this add-on" title="You recommend this add-on">';
+ }
+ echo '<a href="'.FB_URL.'/view/'.$addon['Addon']['id'].'">'.$addon['Translation']['name']['string'].'</a></div>';
+ echo '<div>'.$this->view->controller->_trimSummary($addon['Translation']['summary']['string']).'</div>';
+ if (!empty($addon['FacebookFavorite'])) {
+ $users = array();
+ if (count($addon['FacebookFavorite']) > 3) {
+ $users = array('<a href="'.FB_URL.'/favorites/addon/'.$addon['Addon']['id'].'">'.count($addon['FacebookFavorite']).' friends</a>');
+ }
+ else {
+ foreach ($addon['FacebookFavorite'] as $favUser) {
+ $users[] = '<a href="'.FB_URL.'/favorites/user/'.$favUser['FacebookFavorite']['fb_user'].'"><fb:name uid="'.$favUser['FacebookFavorite']['fb_user'].'" shownetwork="false" linked="false" /></a>';
+ }
+ }
+ echo '<div style="padding-top: 5px;"><span style="color: gray;">Recommended by:</span> '.implode(', ', $users).'</div>';
+ }
+ echo '</div>';
+ echo '</div>';
+ }
+ }
+ else {
+ echo '<div class="noresults">No add-ons found. Please try different criteria.</div>';
+ }
+
+ echo '</div>';
+ }
+
+ function listAddonsOfFriends($addons) {
+ echo '<div class="results" style="background-color: #f7f7f7; padding: 10px;">';
+
+ if (!empty($addons)) {
+ foreach ($addons as $addon) {
+ echo '<div class="resultitem" style="border: 1px solid #cccccc; background-color: white; padding: 5px; height: 75px; margin-bottom: 5px;">';
+ echo '<a href="'.FB_URL.'/view/'.$addon['addons']['id'].'">';
+ if ($addon[0]['pcount'] > 0)
+ echo '<img src="'.FB_IMAGE_SITE.'/images/addon_preview/'.$addon['addons']['id'].'/1" width=100 height=75 border=0 style="float: left; padding-right: 5px;" alt="'.htmlentities($addon['translations_name']['name']).'">';
+ else
+ echo '<img src="'.FB_IMAGE_SITE.'/img/facebook/no-preview-thumb.png" width=100 height=75 border=0 style="float: left; padding-right: 5px;" alt="'.htmlentities($addon['translations_name']['name']).'">';
+ echo '</a>';
+ echo '<div>';
+ echo '<div style="font-weight: bold; font-size: 120%;">';
+ if ($this->view->controller->FacebookFavorite->isFavorite($this->view->controller->fbUser, $addon['addons']['id'], true)) {
+ echo '<img src="'.FB_IMAGE_SITE.'/img/facebook/smallMedal.png" style="padding-right: 5px;" alt="You recommend this add-on" title="You recommend this add-on">';
+ }
+ echo '<a href="'.FB_URL.'/view/'.$addon['addons']['id'].'">'.$addon['translations_name']['name'].'</a></div>';
+ echo '<div>'.$this->view->controller->_trimSummary($addon['translations_summary']['summary']).'</div>';
+ if (!empty($addon[0]['friends'])) {
+ $users = array();
+ if ($addon[0]['fcount'] > 3) {
+ $users = array('<a href="'.FB_URL.'/favorites/addon/'.$addon['addons']['id'].'/friends">'.$addon[0]['fcount'].' friends</a>');
+ }
+ else {
+ $favUsers = explode(',', $addon[0]['friends']);
+ foreach ($favUsers as $favUser) {
+ $users[] = '<fb:userlink uid="'.$favUser.'" shownetwork="false" />';
+ }
+ }
+ echo '<div style="padding-top: 5px;"><span style="color: gray;">Recommended by:</span> '.implode(', ', $users).'</div>';
+ }
+ echo '</div>';
+ echo '</div>';
+ }
+ }
+ else {
+ echo '<div class="noresults">No add-ons found. Please try different criteria.</div>';
+ }
+
+ echo '</div>';
+ }
+
+ function pageNumbers($current, $count, $action = 'browse') {
+ if ($count['pages'] < 2) {
+ return;
+ }
+
+ echo '<ul class="pagerpro" id="pag_nav_links">';
+
+ if (empty($this->pagesString)) {
+ $pagesString = '';
+ $pagenumber = '<li><a href="'.$this->buildURL($action, $current, 'page', 'page:%1$s').'">%1$s</a></li>';
+ if ($current['page'] != 1)
+ $pagesString .= '<li><a href="'.$this->buildURL($action, $current, 'page', 'page:'.($current['page'] - 1)).'">Prev</a></li>';
+ if ($current['page'] == $count['pages'] && $count['pages'] >= 5)
+ $pagesString .= sprintf($pagenumber, $current['page'] - 4);
+ if (($count['pages'] - $current['page']) <= 1 && ($count['pages'] - $current['page']) >= 0 && $count['pages'] >= 5)
+ $pagesString .= sprintf($pagenumber, $current['page'] - 3);
+ if ($current['page'] > 2)
+ $pagesString .= sprintf($pagenumber, $current['page'] - 2);
+ if ($current['page'] > 1)
+ $pagesString .= sprintf($pagenumber, $current['page'] - 1);
+ if ($count['pages'] > 0)
+ $pagesString .= '<li class="current"><a href="'.$this->buildURL($action, $current).'">'.$current['page'].'</a></li>';
+ if (($current['page'] + 1) <= $count['pages'])
+ $pagesString .= sprintf($pagenumber, $current['page'] + 1);
+ if (($current['page'] + 2) <= $count['pages'])
+ $pagesString .= sprintf($pagenumber, $current['page'] + 2);
+ if ($current['page'] <= 2 && $count['pages'] >= ($current['page'] + 3))
+ $pagesString .= sprintf($pagenumber, $current['page'] + 3);
+ if ($current['page'] == 1 && $count['pages'] >= 5)
+ $pagesString .= sprintf($pagenumber, $current['page'] + 4);
+ if ($current['page'] < $count['pages'])
+ $pagesString .= '<li><a href="'.$this->buildURL($action, $current, 'page', 'page:'.($current['page'] + 1)).'">Next</a></li>';
+
+ $this->pagesString = $pagesString;
+ }
+
+ echo $this->pagesString;
+ echo '</ul>';
+ }
+
+ function buildURL($action, $current, $excludedParams = '', $additional = '') {
+ if (!is_array($excludedParams)) {
+ if (empty($excludedParams))
+ $excludedParams = array();
+ else
+ $excludedParams = array($excludedParams);
+ }
+
+ $url = FB_URL.'/'.$action;
+
+ $params = array('sort', 'cat', 'type', 'page');
+
+ foreach ($params as $param) {
+ if (!empty($current[$param]) && !in_array($param, $excludedParams)) {
+ $url .= "/{$param}:{$current[$param]}";
+ }
+ }
+
+ if (!empty($additional)) {
+ $url .= "/{$additional}";
+ }
+ if (!empty($this->globalURLAdditional)) {
+ $url .= "/{$this->globalURLAdditional}";
+ }
+
+ return $url;
+ }
+
+ function peopleBox($facebook_users, $width = 200, $rows = 1, $params = array()) {
+ $perRow = floor($width / 70);
+ $totalShown = $perRow * $rows;
+
+ echo '<div style="width: '.$width.'px;">';
+ echo '<div class="header"><h2>'.(!empty($params['title']) ? $params['title'] : 'Recommended By').'</h2></div>';
+
+ if (!empty($facebook_users)) {
+ echo '<div class="box_subhead">';
+ echo '<div class="box_subtitle">';
+ if (!empty($params['showAllCount']) && $params['showAllCount'] == true) {
+ if (!empty($params['viewAllURL']))
+ echo '<a href="'.$params['viewAllURL'].'">';
+ if ($totalShown < $params['allCount'])
+ echo $totalShown.' of ';
+ echo $params['allCount'].' '.($params['allCount'] == 1 ? 'person' : 'people');
+ if (!empty($params['viewAllURL']))
+ echo '</a>';
+ if (!empty($params['showFriendCount']) && $params['showFriendCount'] == true)
+ echo ', ';
+ }
+ if (!empty($params['showFriendCount']) && $params['showFriendCount'] == true) {
+ if (!empty($params['viewFriendURL']))
+ echo '<a href="'.$params['viewFriendURL'].'">';
+ if ($totalShown < $params['friendCount'])
+ echo $totalShown.' of ';
+ echo $params['friendCount'].' '.($params['friendCount'] == 1 ? 'friend' : 'friends');
+ if (!empty($params['viewFriendURL']))
+ echo '</a>';
+ }
+ echo '</div>';
+ if (!empty($params['seeAllURL']))
+ echo '<div class="box_actions"><a href="'.$params['seeAllURL'].'">See All</a></div>';
+ echo '</div>';
+
+ echo '<div class="guests clearfix">';
+ echo '<table class="people_table" cellspacing="2" cellpadding="0">';
+ $total = 0;
+ for ($r = 0; $r < $rows; $r++) {
+ if (count($facebook_users) > $total) {
+ echo '<tr>';
+ for ($i = 0; $i < $perRow; $i++) {
+ if (!empty($facebook_users[$total])) {
+ echo '<td style="text-align: center; width: 70px;"><fb:profile-pic uid="'.$facebook_users[$total].'" linked="yes"/><br><fb:if-can-see uid="'.$facebook_users[$total].'"><fb:userlink uid="'.$facebook_users[$total].'" /><fb:else>Anonymous</fb:else></fb:if-can-see></td>';
+ }
+ $total++;
+ }
+ echo '</tr>';
+ }
+ }
+ echo '</table>';
+ echo '</div>';
+ }
+ else {
+ echo '<div class="box_nopeople">No one yet. <a href="'.FB_URL.'/favorite/add/'.$params['addon_id'].'">Be the first!</a></div>';
+ }
+ echo '</div>';
+ }
+
+}
+?>
diff --git a/site/app/views/helpers/link.php b/site/app/views/helpers/link.php
new file mode 100644
index 0000000..e42d1d6
--- /dev/null
+++ b/site/app/views/helpers/link.php
@@ -0,0 +1,75 @@
+<?php
+/*
+* This helper builds links to all parts of the site that aren't covered
+* by function-specific components/helpers
+*/
+class LinkHelper extends Helper
+{
+ var $helpers = array('Html');
+
+ function addonDisplay($name, $addon="", $attributes="") {
+ $link = $this->Html->link($name, "/addon/$addon", $attributes);
+ return $this->output($link);
+ }
+
+ function addonBrowse($tag="", $attributes="", $name="") {
+ if (empty($name)) {
+ $link = $this->Html->link($tag, "/browse/" . $tag, $attributes);
+ }
+ else {
+ $link = $this->Html->link($name, "/browse/" . $tag, $attributes);
+ }
+
+ return $this->output($link);
+ }
+
+ /**
+ * Make an email link that displays the real email by javascript
+ * including noscript fallback for spam protection.
+ * Relies on emailLink from addons.js.
+ *
+ * @param string Email address to link to
+ * @param string js_id (Unique) Javascript ID for the email field
+ * @param sting spanclass CSS class to give to email string
+ */
+ function email($email = '', $js_id = '', $spanclass = 'email') {
+ if (!$email) return false;
+ if (!$js_id) $js_id = md5($email); // ugly but unique.
+
+ $noscriptemail = str_replace(array('@', '.'), array(' at ', ' dot '), $email);
+
+ // unsanitize and re-encode email so html entities are not shown in plain text by javascript code
+ $email = addslashes($this->Html->unsanitize($email));
+ $emailparts = explode('@', $email, 2);
+
+ $o = '<span id="'.$js_id.'" class="'.$spanclass.'">'.$noscriptemail."</span>\n"
+ . "<script language=\"JavaScript\">"
+ . "emailLink('{$js_id}', '{$emailparts[0]}', '{$emailparts[1]}');"
+ . "</script>\n";
+
+ return $this->output($o);
+ }
+
+ /**
+ * Create a link to a collection.
+ * @param array $coll Collection (from collection model)
+ * @param string $app (optional) application to link to, defaults to current app
+ */
+ function collection($coll, $app = null) {
+ if (empty($coll)) return false;
+
+ $url = '/collection/';
+ if (!empty($coll['Collection']['nickname']))
+ $url .= $coll['Collection']['nickname'];
+ else
+ $url .= $coll['Collection']['uuid'];
+
+ if (!empty($app)) {
+ return $this->Html->linkNoLocaleNoApp($coll['Translation']['name']['string'],
+ sprintf('/%s/%s%s', LANG, $app, $url));
+ } else {
+ return $this->Html->link($coll['Translation']['name']['string'], $url);
+ }
+ }
+}
+?>
diff --git a/site/app/views/helpers/listing.php b/site/app/views/helpers/listing.php
new file mode 100644
index 0000000..33bceb1
--- /dev/null
+++ b/site/app/views/helpers/listing.php
@@ -0,0 +1,105 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * Justin Scott <fligtar@gmail.com>.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+class ListingHelper extends Helper
+{
+ var $helpers = array('Html');
+
+ function listFiles($files, $id, $is_diff = false, $n = 0) {
+ $output = '';
+ $modified = '';
+
+ if (array_key_exists('changed', $files) && $files['changed'])
+ $modified = ' modified';
+
+ if (!empty($files)) {
+ if ($files['dir'] == 1 || $n == 0) {
+ if ($n != 0) {
+ $class = str_replace('/', '_', $files['path']);
+ $output .= '<li class="directory'.$modified.'">'.$this->Html->link($files['filename'], 'javascript: void(0);', array("onClick" => "toggleNode('{$class}');")).'</li>';
+ $output .= '<ul class="'.$class.'" style="display: none;">';
+ }
+
+ foreach ($files as $file => $item) {
+ if ($file != 'path' && $file != 'dir' && $file != 'filename' && $file != 'changed') {
+ $output .= $this->listFiles($item, $id, $is_diff, $n+1);
+ }
+ }
+
+ if ($n != 0) {
+ $output .= '</ul>';
+ }
+ }
+ elseif ($is_diff) {
+ $files['path'] = urlencode($files['path']);
+ $output .= '<li class="file'.$modified.'">'.$this->Html->link($files['filename'], 'javascript: void(0);', array('onClick' => "viewFile('".$this->Html->url('/files/diff')."/{$id}/?compare={$files['path']}');")).'</li>';
+ }
+ else {
+ $files['path'] = urlencode($files['path']);
+ $output .= '<li class="file">'.$this->Html->link($files['filename'], 'javascript: void(0);', array('onClick' => "viewFile('".$this->Html->url('/files/browse')."/{$id}/?view={$files['path']}');")).'</li>';
+ }
+ }
+
+ if ($n == 0) {
+ return $this->output($output);
+ }
+ else {
+ return $output;
+ }
+ }
+
+ function json($json, $tab = 0, $encode = false) {
+ echo "{\n";
+ if (!empty($json)) {
+ foreach ($json as $key => $value) {
+ echo str_repeat("\t", $tab)."\"{$key}\": ";
+ if (is_array($value))
+ $this->json($value, $tab + 1, $encode);
+ else
+ if (is_numeric($value) && strpos($value, '.') === false)
+ echo "{$value},\n";
+ elseif ($encode)
+ echo '"'.urlencode($value).'",'."\n";
+ else
+ echo "'".preg_replace('/\n/', '\n', addslashes($value))."',\n";
+ }
+ }
+ echo str_repeat("\t", $tab).'}'.($tab == 0 ? '' : ',')."\n";
+ }
+
+}
+?>
diff --git a/site/app/views/helpers/localization.php b/site/app/views/helpers/localization.php
new file mode 100644
index 0000000..886a730
--- /dev/null
+++ b/site/app/views/helpers/localization.php
@@ -0,0 +1,68 @@
+<?php
+/**
+ *
+ */
+class LocalizationHelper extends Helper
+{
+
+ /**
+ * Outputs localized strings in the header for use in javascript functions stored in .js files
+ * @param array $localizations the localized strings
+ * @return string
+ */
+ function jsLocalization($localizations) {
+ if (!empty($localizations)) {
+ $array = array();
+ foreach ($localizations as $key => $value) {
+ $array[] = "$key:'$value'";
+ }
+
+ $return = '<script language="JavaScript" type="text/javascript">';
+ $return .= 'var localized = {'.implode(', ', $array).'};';
+ $return .= '</script>';
+
+ return $return;
+ }
+ else {
+ return '';
+ }
+ }
+
+ /**
+ * include a static, localized page from
+ * /locale/{LANG}/pages/$name.thtml
+ * falls back to default_language if page is not localized in LANG,
+ * returns '' if no page is found there either.
+ * @param string name name of the page snippet (without .thtml)
+ * @param array replacements uses vsprintf() to replace parts of the snippet
+ * @return string
+ */
+ function includeLocalPage($name, $replacements = array()) {
+ $page_path = APP.'locale'.DS.'%s'.DS.'pages'.DS.$name.'.thtml';
+ if (file_exists(sprintf($page_path, str_replace('-','_',LANG)))) {
+ $page = sprintf($page_path, str_replace('-','_',LANG));
+ } elseif (file_exists(sprintf($page_path, 'en_US'))) {
+ $page = sprintf($page_path, 'en_US');
+ } else {
+ return ''; // no luck!
+ }
+ return vsprintf(file_get_contents($page), $replacements);
+ }
+
+ /**
+ * format a file size (Kilobytes) in the local number format
+ * @param float file size in kilobytes
+ * @param int decimals
+ * @return string localized file size, false in case of error
+ */
+ function localFileSize($size = null, $decimals = 0) {
+ if (!is_numeric($size)) return false;
+
+ loadHelper('AddonsHtml');
+ $html = new AddonsHtmlHelper();
+ $formatted_no = $html->number_format($size, $decimals);
+
+ return sprintf(_('size_kb'), $formatted_no);
+ }
+}
+?>
diff --git a/site/app/views/helpers/pagination.php b/site/app/views/helpers/pagination.php
new file mode 100644
index 0000000..3bb2243
--- /dev/null
+++ b/site/app/views/helpers/pagination.php
@@ -0,0 +1,527 @@
+<?php
+/**
+ * Pagination Helper, responsible for managing the LINKS required for pagination.
+ * ALL parameters are specified in the component.
+ */
+class PaginationHelper extends Helper
+{
+/**
+ * Options to be passed to ajax links if used
+ *
+ * @var array
+ * @access public
+ */
+ var $ajaxLinkOptions = array();
+/**
+ * Placeholder for the link style - defined in/by the component
+ *
+ * @var boolean
+ * @access private
+ */
+ var $style = 'html';
+/**
+ * Placeholder for the parameter style - defined in/by the component
+ *
+ * @var boolean
+ * @access private
+ */
+ var $paramStyle = 'get';
+/**
+ * Placeholder for the pagination details
+ *
+ * @var array
+ * @access private
+ */
+ var $_pageDetails = array();
+/**
+ * Helpers
+ *
+ * @var array
+ * @access private
+ */
+ var $helpers = array("Html","Ajax");
+
+/**
+ * Sets the default pagination options. Fails if the value $paging is not set
+ *
+ * @param array $paging an array detailing the page options
+ * @return boolean
+ */
+ function setPaging($paging)
+ {
+ if (empty($paging)) {return false;}
+ $this->_pageDetails = $paging;
+ $this->_pageDetails['previousPage'] = ($paging['page']>1) ? $this->_pageDetails['page']-1 : '';
+ $this->_pageDetails['nextPage'] = ($paging['page'] < $this->_pageDetails['pageCount']) ? $this->_pageDetails['page']+1 : '';
+
+ $this->url = $this->_pageDetails['url'];
+
+ $getParams = $this->params['url'];
+ unset($getParams['url']);
+ $this->getParams = $getParams;
+
+ $this->showLimits = $this->_pageDetails['showLimits'];
+ $this->style = isset($this->_pageDetails['style'])?$this->_pageDetails['style']:$this->style;
+
+ if (($this->_pageDetails['maxPages'] % 2)==0) // need odd number of page links
+ {
+ $this->_pageDetails['maxPages'] = $this->_pageDetails['maxPages']-1;
+ }
+
+ $this->maxPages = $this->_pageDetails['maxPages'];
+ $this->pageSpan = ($this->_pageDetails['maxPages']-1)/2;
+
+ return true;
+ }
+
+/**
+* Displays the list of pages for the given parameters.
+*
+* @param string text to display before limits
+* @param string display a separate between limits
+* @param boolean whether to escape the title or not
+* @return unknown the html string for modifying the number of results per page
+**/
+ function resultsPerPage($t="Results per page: ", $separator=" ",$escapeTitle=true)
+ {
+ if (empty($this->_pageDetails)) { return false; }
+ if ( !empty($this->_pageDetails['pageCount']) )
+ {
+ if(is_array($this->_pageDetails['resultsPerPage']))
+ {
+ $OriginalValue = $this->_pageDetails['show'];
+ $t .= $separator;
+ foreach($this->_pageDetails['resultsPerPage'] as $value)
+ {
+ if($OriginalValue == $value)
+ {
+ $t .= '<em>'.$value.'</em>'.$separator;
+ }
+ else
+ {
+ $this->_pageDetails['show'] = $value;
+ $t .= $this->_generateLink($value,1,$escapeTitle).$separator;
+ }
+ }
+ $this->_pageDetails['show'] = $OriginalValue;
+ }
+ return $t;
+ }
+ return false;
+ }
+
+ function resultsPerPageSelect($t="Results per page: ")
+ {
+ if (empty($this->_pageDetails)) { return false; }
+ if ( !empty($this->_pageDetails['pageCount']) )
+ {
+ $Options = array();
+ if(is_array($this->_pageDetails['resultsPerPage']))
+ {
+ foreach($this->_pageDetails['resultsPerPage'] as $value)
+ {
+ $Options[$value] = $value;
+ }
+ }
+ return $t.$this->Html->selectTag("pagination/show", $Options, $this->_pageDetails['show'], NULL, NULL,FALSE);
+ }
+ return false;
+ }
+
+/**
+* Displays info of the current result set
+*
+* @param string
+* @param string
+* @param string
+* @param string
+* @return unknown the html string for the current result set.
+**/
+ function result($t = "%s items") {
+ if (empty($this->_pageDetails))
+ return false;
+
+ if (!empty($this->_pageDetails['pageCount'])) {
+ $t = sprintf($t, $this->_pageDetails['total']);
+ return $t;
+ }
+ return false;
+ }
+/**
+* Returns a list of page numbers separated by $separator
+*
+* @param boolean
+* @return string html for the list of page numbers
+**/
+ function pageNumbers($escapeTitle=true)
+ {
+ if (empty($this->_pageDetails) || $this->_pageDetails['pageCount'] == 1) {
+ // single page result
+ return '';
+ }
+ $total = $this->_pageDetails['pageCount'];
+ $max = $this->maxPages;
+ $span = $this->pageSpan;
+ $spacer = '<li class="skip">&#8230;</li>';
+
+ if ($total<$max) {
+ $upperLimit = min($total,($span*2+1));
+ $lowerLimit = 1;
+ } elseif ($this->_pageDetails['page']<($span+1)) {
+ $lowerLimit = 1;
+ $upperLimit = min($total,($span*2+1));
+ } elseif ($this->_pageDetails['page']>($total-$span)) {
+ $upperLimit = $total;
+ $lowerLimit = max(1,$total-$span*2);
+ } else {
+ $upperLimit = min ($total,$this->_pageDetails['page']+$span);
+ $lowerLimit = max (1,($this->_pageDetails['page']-$span));
+ }
+
+ $t = array();
+ if (($lowerLimit<>1) && ($this->showLimits)) {
+ $lowerLimit = $lowerLimit+1;
+ $t[] = '<li>'.$this->_generateLink(1,1,$escapeTitle).'</li>';
+ $t[] = $spacer;
+ }
+
+ if (($upperLimit<>$total) && ($this->showLimits))
+ $dottedUpperLimit = true;
+ else
+ $dottedUpperLimit = false;
+
+ if (($upperLimit<>$total) && ($this->showLimits))
+ $upperLimit = $upperLimit-1;
+
+ for ($i = $lowerLimit; $i <= $upperLimit; $i++) {
+ $class = ($i == $this->_pageDetails['page']) ? 'class="selected"' : '';
+ $text = "<li {$class}>".$this->_generateLink($i,$i,$escapeTitle).'</li>';
+ $t[] = $text;
+ }
+ if ($dottedUpperLimit) {
+ $t[] = $spacer;
+ $t[] = '<li>'.$this->_generateLink($this->_pageDetails['pageCount'],
+ $this->_pageDetails['pageCount'],$escapeTitle).'</li>';
+ }
+
+ $t = implode("\n", $t);
+ return $t;
+ }
+
+/**
+* Displays a link to the previous page, where the page doesn't exist then
+* display the $text
+*
+* @param string $text - text display: defaults to next
+* @return string html for link/text for previous item
+**/
+ function prevPage($text='prev',$escapeTitle=true)
+ {
+ if (empty($this->_pageDetails)) { return false; }
+ if ( !empty($this->_pageDetails['previousPage']) )
+ {
+ return $this->_generateLink($text,$this->_pageDetails['previousPage'],$escapeTitle,'prev');
+ }
+ return '';
+ }
+
+/**
+* Displays a link to the next page, where the page doesn't exist then
+* display the $text
+*
+* @param string $text - text to display: defaults to next
+* @return string html for link/text for next item
+**/
+ function nextPage($text='next',$escapeTitle=true)
+ {
+ if (empty($this->_pageDetails)) { return false; }
+ if (!empty($this->_pageDetails['nextPage']))
+ {
+ return $this->_generateLink($text,$this->_pageDetails['nextPage'],$escapeTitle,'next');
+ }
+ return '';
+ }
+
+/**
+* Displays a link to the first page
+* display the $text
+*
+* @param string $text - text to display: defaults to next
+* @return string html for link/text for next item
+**/
+ function firstPage($text='first',$escapeTitle=true)
+ {
+ if (empty($this->_pageDetails)) { return false; }
+ if ($this->_pageDetails['page']<>1)
+ {
+ return $this->_generateLink($text,1,$escapeTitle);
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+/**
+* Displays a link to the last page
+* display the $text
+*
+* @param string $text - text to display: defaults to next
+* @return string html for link/text for next item
+**/
+ function lastPage($text='last',$escapeTitle=true)
+ {
+ if (empty($this->_pageDetails)) { return false; }
+ if ($this->_pageDetails['page']<>$this->_pageDetails['pageCount'])
+ {
+ return $this->_generateLink($text,$this->_pageDetails['pageCount'],$escapeTitle);
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+
+/**
+* Generate link to sort the results by the given value
+*
+* @param string field to sort by
+* @param string title for link defaults to $value
+* @param string model to sort by - uses the default model class if absent
+* @param boolean escape title
+* @param string text to append to links to indicate sorted ASC
+* @param string text to append to links to indicate sorted DESC
+* @return string html for link to modify sort order
+**/
+ function sortBy ($value, $title=NULL, $Model=NULL,$escapeTitle=true,$upText=" ^",$downText=" v")
+ {
+ if (empty($this->_pageDetails)) { return false; }
+ $title = $title?$title:ucfirst($value);
+ $value = strtolower($value);
+ $Model = $Model?$Model:$this->_pageDetails['Defaults']['sortByClass'];
+
+ $OriginalSort = $this->_pageDetails['sortBy'];
+ $OriginalModel = $this->_pageDetails['sortByClass'];
+ $OriginalDirection = $this->_pageDetails['direction'];
+ //echo "does $value = $OriginalSort<br>";
+ //echo "does '$Model' = '$OriginalModel'<br>";
+
+ if (($value==$OriginalSort)&&($Model==$OriginalModel))
+ {
+ if (up($OriginalDirection)=="DESC")
+ {
+ $this->_pageDetails['direction'] = "ASC";
+ $title .= $upText;
+ }
+ else
+ {
+ $this->_pageDetails['direction'] = "DESC";
+ $title .= $downText;
+ }
+ }
+ else
+ {
+ if ($Model)
+ {
+ $this->_pageDetails['sortByClass'] = $Model;
+ //echo "page details model class set to ".$this->_pageDetails['sortByClass']."<br>";
+ }
+ else
+ {
+ $this->_pageDetails['sortByClass'] = NULL;
+ }
+ $this->_pageDetails['sortBy'] = $value;
+ }
+ $link = $this->_generateLink ($title,1,$escapeTitle);
+ $this->_pageDetails['sortBy'] = $OriginalSort;
+ $this->_pageDetails['sortByClass'] = $OriginalModel;
+ $this->_pageDetails['direction'] = $OriginalDirection;
+ return $link;
+ }
+
+/**
+* Generate a select box for options to sort results
+*
+* @param array array of text strings, formatted as "Field::Direction::Class".
+* @param string prefix text
+* @param string text to append to links to indicate sorted ASC
+* @param string text to append to links to indicate sorted DESC
+* @return unknown the html string for the select box for selecting sort order
+**/
+ function sortBySelect($sortFields, $t="Sort By: ",$upText=" ^",$downText=" v", $selectAttr = array(), $optionAttr = array())
+ {
+ if (empty($this->_pageDetails)) { return false; }
+ if ( !empty($this->_pageDetails['pageCount']) )
+ {
+ $OriginalValue = $this->_pageDetails['sortBy']."::".$this->_pageDetails['direction']."::".$this->_pageDetails['sortByClass'];
+ if(is_array($sortFields))
+ {
+ foreach($sortFields as $value)
+ {
+ $Vals = Array();
+ $Vals = explode("::",$value);
+ if (isset($Vals[2]))
+ {
+ $DisplayVal = $Vals[2]." ";
+ }
+ else
+ {
+ $DisplayVal = "";
+ }
+ //$DisplayVal .= $Vals[0];
+ if (up($Vals[1])=="ASC")
+ {
+ $DisplayVal .= $downText;
+ }
+ else
+ {
+ $DisplayVal .= $upText;
+ }
+ $Options[$value] = $DisplayVal;
+ }
+ return $t.$this->Html->selectTag("pagination/sortByComposite", $Options, $OriginalValue, $selectAttr, $optionAttr, false);
+ }
+ }
+ return false;
+ }
+
+
+/**
+* Internal method to generate links based upon passed parameters.
+*
+* @param string title for link
+* @param string page the page number
+* @param boolean escape title
+* @param string the div to be updated by AJAX updates
+* @return string html for link
+**/
+ function _generateLink ($title,$page=NULL,$escapeTitle,$rel=null)
+ {
+ $url = $this->_generateUrl($page);
+ $AjaxDivUpdate = $this->_pageDetails['ajaxDivUpdate'];
+ if ($this->style=="ajax")
+ {
+ $options = am($this->ajaxLinkOptions,
+ array(
+ "update" => $this->_pageDetails['ajaxDivUpdate']
+ )
+ );
+ if (isset($this->_pageDetails['ajaxFormId']))
+ {
+ $id = 'link' . intval(rand());
+ $return = $this->Html->link(
+ $title,
+ $url,
+ array('id' => $id, 'onclick'=>" return false;"),
+ NULL,
+ $escapeTitle
+ );
+ $options['with'] = "Form.serialize('{$this->_pageDetails['ajaxFormId']}')";
+ $options['url'] = $url;
+ $return .= $this->Ajax->Javascript->event("'$id'", "click", $this->Ajax->remoteFunction($options));
+ return $return;
+ }
+ else
+ {
+ // @TODO make ajax helper locale-aware and change this part accordingly if needed
+ return $this->Ajax->link(
+ $title,
+ $url,
+ $options,
+ NULL,
+ NULL,
+ $escapeTitle
+ );
+ }
+ }
+ else
+ {
+ return $this->Html->linkNoLocaleNoApp(
+ $title,
+ $url,
+ isset($rel) ? array('rel' => $rel) : NULL,
+ NULL,
+ $escapeTitle
+ );
+ }
+ }
+
+ function _generateUrl ($page=NULL)
+ {
+ $getParams = $this->getParams; // Import any other pre-existing get parameters
+ if ($this->_pageDetails['paramStyle']=="pretty")
+ {
+ $pageParams=$this->_pageDetails['importParams'];
+ }
+ $pageParams['show'] = $this->_pageDetails['show'];
+ $pageParams['sortBy'] = $this->_pageDetails['sortBy'];
+ $pageParams['direction'] = $this->_pageDetails['direction'];
+ $pageParams['page'] = $page?$page:$this->_pageDetails['page'];
+ if (isset($this->_pageDetails['sortByClass']))
+ {
+ $pageParams['sortByClass'] = $this->_pageDetails['sortByClass'];
+ }
+ $getString = array();
+ $prettyString = array();
+ if ($this->_pageDetails['paramStyle']=="get")
+ {
+ $getParams = am($getParams,$pageParams);
+ }
+ else
+ {
+ foreach($pageParams as $key => $value)
+ {
+ if (isset($this->_pageDetails['Defaults'][$key]))
+ {
+ if (up($this->_pageDetails['Defaults'][$key])<>up($value))
+ {
+ $prettyString[] = "$key{$this->_pageDetails['paramSeperator']}$value";
+ }
+ }
+ else
+ {
+ $prettyString[] = "$key{$this->_pageDetails['paramSeperator']}$value";
+ }
+ }
+ }
+ foreach($getParams as $key => $value)
+ {
+ if ($this->_pageDetails['paramStyle']=="get")
+ {
+ if (isset($this->_pageDetails['Defaults'][$key]))
+ {
+ if ($key == 'show' || (up($this->_pageDetails['Defaults'][$key])<>up($value)))
+ {
+ $getString[] = "$key=$value";
+ }
+ }
+ else
+ {
+ $getString[] = "$key=$value";
+ }
+ }
+ else
+ {
+ $getString[] = "$key=$value";
+ }
+ }
+ $url = $this->url;
+ if ($prettyString)
+ {
+ $prettyString = implode ("/", $prettyString);
+ $url .= $prettyString;
+ }
+ if ($getString)
+ {
+ $getString = implode ("&", $getString);
+ $url .= "?".$getString;
+ }
+
+ // Escape url to prevent XSS
+ $this->view->controller->_sanitizeArray($url);
+
+ return $url;
+ }
+}
+?>
diff --git a/site/app/views/helpers/statistics.php b/site/app/views/helpers/statistics.php
new file mode 100644
index 0000000..e65cce2
--- /dev/null
+++ b/site/app/views/helpers/statistics.php
@@ -0,0 +1,34 @@
+<?php
+
+class StatisticsHelper extends Helper {
+
+ var $helpers = array('Html');
+
+ /**
+ * Formats $array[$member] using number_format.
+ * If the member isn't set, outputs a 0.
+ */
+ function number_format($array, $member) {
+ if (empty($array[$member])) {
+ return 0;
+ } else {
+ return $this->Html->number_format($array[$member]);
+ }
+ }
+
+ function colored_percentage($array, $member) {
+ if (empty($array[$member])) {
+ return 0;
+ } else {
+ $num = $array[$member];
+ if ($num > 0)
+ $color = 'green';
+ else if ($num < 0)
+ $color = 'red';
+ else
+ $color = 'blue';
+ return "<span style='color: {$color}'>".sprintf('%+.2f%%', $num).'</span>';
+ }
+ }
+}
+?>
diff --git a/site/app/views/images/show.thtml b/site/app/views/images/show.thtml
new file mode 100644
index 0000000..bb28d98
--- /dev/null
+++ b/site/app/views/images/show.thtml
@@ -0,0 +1,40 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Andrei Hajdukewycz <sancus@off.net> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+header("Content-type: $mimetype");
+echo $imagedata;
+?>
diff --git a/site/app/views/layouts/ajax_with_css.thtml b/site/app/views/layouts/ajax_with_css.thtml
new file mode 100644
index 0000000..119b787
--- /dev/null
+++ b/site/app/views/layouts/ajax_with_css.thtml
@@ -0,0 +1,87 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Andrei Hajdukewycz <sancus@off.net> (Original Author)
+ * Mike Morgan <morgamic@mozilla.com>
+ * Justin Scott <fligtar@gmail.com>
+ * Frederic Wenzel <fwenzel@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" version="-//W3C//DTD XHTML 1.1//EN" xml:lang="<?=LANG?>" lang="<?=LANG?>" dir="<?=TEXTDIR?>">
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
+ <base target="_top">
+ <?=$html->css('rustico')?>
+ <link rel="search" type="application/opensearchdescription+xml" href="<?=$html->url('/AMOSearch.xml', null, false)?>" title="Mozilla Add-ons" />
+ <link rel="shortcut icon" href="<?=$html->url('/img/favicon.ico', null, false)?>" type="image/x-icon" />
+ <?php
+ if (!empty($cssAdd)) {
+ foreach ($cssAdd as $css) {
+ $url = $html->css($css);
+ echo "{$url}\n";
+ }
+ }
+ if (!empty($rssAdd)) {
+ foreach ($rssAdd as $rss) {
+ if (is_array($rss)) {
+ $rssurl = $rss[0];
+ $rsstitle = $rss[1];
+ } else {
+ $rssurl = $rss;
+ $rsstitle = 'RSS';
+ }
+ echo '<link rel="alternate" type="application/rss+xml" title="'.$rsstitle.'" href="'.$html->url($rssurl).'"/>'."\n";
+ }
+ }
+ if (!empty($jsAdd)) {
+ foreach ($jsAdd as $js) {
+ $jslink = $javascript->link($js);
+ echo "{$jslink}\n";
+ }
+ }
+ if (!empty($jsLocalization) && is_object($localization)) {
+ echo $localization->jsLocalization($jsLocalization);
+ }
+ ?>
+ <title><?=$title_for_layout?></title>
+</head>
+
+<body id="mozilla-com">
+
+<?=$content_for_layout ?>
+
+</body>
+</html>
diff --git a/site/app/views/layouts/amo2009.thtml b/site/app/views/layouts/amo2009.thtml
new file mode 100644
index 0000000..c1aa4ce
--- /dev/null
+++ b/site/app/views/layouts/amo2009.thtml
@@ -0,0 +1,370 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Andrei Hajdukewycz <sancus@off.net> (Original Author)
+ * Mike Morgan <morgamic@mozilla.com>
+ * Justin Scott <fligtar@gmail.com>
+ * Frederic Wenzel <fwenzel@mozilla.com>
+ * Brian Krausz <brian@nerdlife.net>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+// Using revision # in url in production to prevent the file from being cached
+// forever
+if(defined('SITE_STATE') && (SITE_STATE == 'production' || SITE_STATE == 'staging')) {
+ $jsParams = '?'.JS_REVISION;
+ $cssParams = '?'.CSS_REVISION;
+} else {
+ //To prevent caching in development, change the url on each request
+ $jsParams = '?'.time();
+ $cssParams = '?'.time();
+}
+?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" lang="<?=LANG?>" dir="<?=TEXTDIR?>"
+ class="html-<?=TEXTDIR?> <?=APP_SHORTNAME?>">
+<head>
+ <title><?=$html->entities($title_for_layout)?></title>
+
+ <link rel="shortcut icon" type="image/x-icon"
+ href="<?=$html->url('/img/favicon.ico', null, false, false)?>" />
+
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
+ <meta name="MSSmartTagsPreventParsing" content="true"/>
+ <meta name="Copyright" content="(c) 2005-<?php echo date('Y'); ?> Mozilla. All rights reserved."/>
+ <meta http-equiv="imagetoolbar" content="no"/>
+ <meta name="Rating" content="General"/>
+
+ <link rel="search" type="application/opensearchdescription+xml" title="Mozilla Add-ons"
+ href="<?=$html->url('/AMOSearch.xml', null, false, false)?>" />
+
+ <?php if (isset($addon['Addon']['addontype_id']) && ($addon['Addon']['addontype_id'] == ADDON_SEARCH)) : ?>
+ <link rel="search" type="application/opensearchdescription+xml"
+ href="<?=$html->urlFile($addon['Version'][0]['File'][0]['id'], $addon['Version'][0]['File'][0]['filename'])?>"
+ locale="<?=$addon['Translation']['name']['locale']?>" title="<?=$addon['Translation']['name']['string']?>"/>
+ <?php endif ?>
+
+ <?php if(defined('SITE_STATE') && (SITE_STATE == 'production' || SITE_STATE == 'staging')): ?>
+ <?= str_replace('.css','.css'.$cssParams,$html->css('amo2009/style.min', 'stylesheet', array('media'=>'all'), true)) ?>
+ <?php else: ?>
+ <?= $html->css('amo2009/main', 'stylesheet', array('media'=>'screen,projection,tv')) ?>
+ <?= $html->css('amo2009/slimbox2', 'stylesheet', array('media'=>'screen,projection,tv')) ?>
+ <?= $html->css('amo2009/main-mozilla', 'stylesheet', array('media'=>'screen,projection,tv')) ?>
+ <?= $html->css('amo2009/legacy', 'stylesheet', array('media'=>'screen,projection,tv')) ?>
+ <?php endif ?>
+
+ <!--[if IE]>
+ <?= $html->css('amo2009/ie', 'stylesheet', array('media'=>'screen,projection,tv')) ?>
+ <![endif]-->
+ <!--[if IE 7]>
+ <?= $html->css('amo2009/ie7', 'stylesheet', array('media'=>'screen,projection,tv')) ?>
+ <![endif]-->
+ <!--[if IE 6]>
+ <?= $html->css('amo2009/ie6', 'stylesheet', array('media'=>'screen,projection,tv')) ?>
+ <![endif]-->
+
+ <?php
+ if (!empty($cssAdd)) {
+ foreach ($cssAdd as $css) {
+ $url = $html->css($css);
+ echo "{$url}\n";
+ }
+ }
+ ?>
+
+ <?php
+ if (!empty($rssAdd)) foreach ($rssAdd as $rss) {
+ if (is_array($rss)) {
+ $rssurl = $rss[0];
+ $rsstitle = $rss[1];
+ } else {
+ $rssurl = $rss;
+ $rsstitle = 'RSS';
+ }
+ echo '<link rel="alternate" type="application/rss+xml" title="'.$rsstitle.'" href="'.$html->url($rssurl).'"/>'."\n";
+ }
+
+ // Pre-script-inclusion JS
+ if (!empty($prescriptJS)) { ?>
+ <script type="text/javascript"><?=$prescriptJS?></script>
+ <?php }
+
+ if (empty($suppressUrchin)) {
+ echo $javascript->link('__utm.js');
+ }
+
+ echo $javascript->linkOut($html->url('/pages/js_constants'))."\n";
+
+ if (!isset($suppressJQuery) || !$suppressJQuery) {
+ if(defined('SITE_STATE') && (SITE_STATE == 'production' || SITE_STATE == 'staging')) {
+ echo $javascript->link('amo2009/amo2009.min.js'.$jsParams)."\n";
+ } else {
+ // TODO: Stick this list somewhere shared with bin/build.py?
+ echo $javascript->link('jquery-compressed.js')."\n";
+ echo $javascript->link('jquery.cookie.js')."\n";
+ echo $javascript->link('amo2009/global.js')."\n";
+ echo $javascript->link('amo2009/slimbox2.js')."\n";
+ echo $javascript->link('amo2009/addons.js');
+ echo $javascript->link('amo2009/global-mozilla.js')."\n";
+ }
+ }
+
+ if (!empty($jsAdd)) {
+ foreach ($jsAdd as $js) {
+ $js = $js;
+ $jslink = $javascript->link($js);
+ echo "{$jslink}\n";
+ }
+ }
+
+ if (!empty($jsLocalization) && is_object($localization)) {
+ echo $localization->jsLocalization($jsLocalization);
+ }
+
+ if ($this->controller->name == 'Addons' && $this->action == 'display') {
+ ?>
+ <script type="text/javascript">
+ // <![CDATA[
+ $(document).ready(function() {
+ var etiquette_box = $("#addons-display-review-etiquette").hide();
+ $("#short-review").focus(function() { etiquette_box.show("fast"); } );
+ });
+
+ // This function toggles an element\'s text between two values
+ jQuery.fn.textToggle = function(text1, text2) {
+ jQuery(this).text( ( jQuery(this).text() == text1 ? text2 : text1 ) );
+ };
+
+ // ]]>
+ </script>
+ <?php
+ }
+ ?>
+ <script type="text/javascript">// <![CDATA[
+ $(document).ready(function() {
+ $(".hidden").hide(); // hide anything that should be hidden
+
+ if (typeof __utmSetVar == 'function') {
+ <?php if ($this->controller->Session->check('User')): ?>
+ __utmSetVar("Loggedin");
+ <?php else: ?>
+ __utmSetVar("Loggedout");
+ <?php endif; ?>
+ }
+ });
+ // ]]></script>
+
+ <?php if (isset($head_extra)) echo $head_extra; ?>
+ <?php if($advancedSearch): ?>
+ <style type="text/css" media="screen">
+ .expanded-search-form .advanced {
+ display: block;
+ }
+ </style>
+ <?php endif; ?>
+</head>
+
+<body id="mozilla-com" class="html-<?=TEXTDIR?> <?=APP_SHORTNAME?> <?= ($this->controller->Session->check('User')) ? 'user-login' : 'user-anon' ?><?= isset($bodyclass) ? ' ' . $bodyclass : '' ?>">
+
+ <ul id="nav-access" role="navigation">
+ <li><a href="#content"><?=___('header_navaccess_main_content', 'Skip to main content')?></a></li>
+ <li><a href="#search-form"><?=___('header_navaccess_search_form', 'Skip to search form')?></a></li>
+ <li><a href="#categories"><?=___('header_navaccess_categories_menu', 'Skip to categories menu')?></a></li>
+ <li><a href="#other-apps"><?=___('header_navaccess_applications_menu', 'Skip to other applications menu')?></a></li>
+ </ul>
+
+ <?php if (is_object($this->controller->Config) && $this->controller->Config->getValue('site_notice') != ''): ?>
+ <div id="site-notice"><p><?= $this->controller->Config->getValue('site_notice') ?></p></div>
+ <?php endif ?>
+
+ <div class="section">
+ <div id="header" role="banner">
+ <?php
+ switch (APP_SHORTNAME) {
+ case 'firefox':
+ $main_header = sprintf(
+ ___('header_main_firefox_header_with_logo', 'Add-ons <em>for</em> <img src="%1$s" alt="Firefox" /> Firefox'),
+ $html->url('/img/amo2009/app-icons/firefox.png', null, false, false)
+ );
+ break;
+ case 'seamonkey':
+ $main_header = sprintf(
+ ___('header_main_seamonkey_header_with_logo', 'Add-ons <em>for</em> <img src="%1$s" alt="Seamonkey" /> Seamonkey'),
+ $html->url('/img/amo2009/app-icons/seamonkey.png', null, false, false)
+ );
+ break;
+ case 'sunbird':
+ $main_header = sprintf(
+ ___('header_main_sunbird_header_with_logo', 'Add-ons <em>for</em> <img src="%1$s" alt="Sunbird" /> Sunbird'),
+ $html->url('/img/amo2009/app-icons/sunbird.png', null, false, false)
+ );
+ break;
+ case 'thunderbird':
+ $main_header = sprintf(
+ ___('header_main_thunderbird_header_with_logo', 'Add-ons <em>for</em> <img src="%1$s" alt="Thunderbird" /> Thunderbird'),
+ $html->url('/img/amo2009/app-icons/thunderbird.png', null, false, false)
+ );
+ break;
+ default:
+ $main_header = sprintf(
+ ___('header_main_header_with_logo', 'Add-ons <img src="%1$s" alt="Add-ons" />'),
+ $html->url('/img/amo2009/app-icons/generic.png', null, false, false)
+ );
+ break;
+ }
+ ?>
+ <p id="title"><a href="<?=$html->url('/')?>" title="<?=sprintf(_('header_home_tooltip'), APP_PRETTYNAME)?>"><?= $main_header ?></a></p>
+ <p id="brand"><a href="http://www.mozilla.com/<?=LANG?>/" title="<?=___('header_brand_name', 'Mozilla')?>" accesskey="1"><?=___('header_brand_name', 'Mozilla')?></a></p>
+
+ <?php if (isset($header_extra)) echo $header_extra ?>
+
+ <div id="aux-nav" role="navigation">
+
+ <ul id="other-apps" class="change" title="<?=___('other_apps_tooltip');?>">
+ <li>
+ <a href="#" class="controller"><?=_('addons_home_other_applications')?></a>
+ <ul><?php
+ global $app_shortnames, $app_prettynames;
+ $applist = array();
+ foreach (array_keys($app_shortnames) as $_app) {
+ // pulling fennec from app_chooser until it has proper support for the web site
+ if ($app_shortnames[$_app] == APP_ID || $app_shortnames[$_app] == APP_FENNEC)
+ continue; // don't show current app or fennec
+ ?>
+ <li id="app-<?=$_app?>" class="<?=$_app?>">
+ <a href="<?=$html->url("/$_app/",false,true,false)?>"><?=$app_prettynames[$_app]?></a>
+ </li>
+ <?php
+ }
+ ?></ul>
+ </li>
+ </ul>
+
+ <?php if (!$this->controller->Session->check('User')): ?>
+ <p class="context">
+ <?= sprintf(
+ ___('header_navlink_register_or_login', '<a href="%1$s">Register</a> or <a href="%2$s">Log in</a>'),
+ $html->url('/users/register', false), $html->url($html->login_url())
+ ) ?>
+ </p>
+ <?php
+ else:
+ $tools_links = array();
+ $user = $this->controller->Session->read('User');
+ $tools_links[] = $html->link(_('sidebar_navlink_developer_tools'), '/developers');
+ if ($this->controller->SimpleAcl->actionAllowed('Editors', '%', $this->controller->Session->read('User')))
+ $tools_links[] = $html->link(_('sidebar_navlink_editor_tools'), '/editors');
+ if ($this->controller->SimpleAcl->actionAllowed('Localizers', '%', $this->controller->Session->read('User')))
+ $tools_links[] = $html->link('Localizer Tools', '/localizers');
+ if ($this->controller->SimpleAcl->actionAllowed('Admin', '%', $this->controller->Session->read('User')))
+ $tools_links[] = $html->link(_('sidebar_navlink_admin_tools'), '/admin');
+
+ if (count($tools_links) > 1):
+ ?>
+ <ul class="tools">
+ <li>
+ <a href="#" class="controller"><?=___('header_navlink_tools', 'Tools')?></a>
+ <ul>
+ <?php foreach ($tools_links as $_tl): ?>
+ <li><?=$_tl?></li>
+ <?php endforeach; ?>
+ </ul>
+ </li>
+ </ul>
+ <?php else: ?>
+ <p class="context">
+ <?=$tools_links[0]?>
+ </p>
+ <?php endif; // more than one tools link ?>
+ <p class="context">
+ <span class="greeting"><?=(!empty($welcomeName) ? sprintf(_('sidebar_navlink_welcome_name'), $welcomeName) : _('sidebar_navlink_welcome'))?></span>
+ <?= $html->link(_('header_navlink_myaccount'), '/users/edit', array('class'=>'settings','title' => $user['email'])) ?>
+ <?= $html->link(_('header_navlink_logout'), $html->logout_url()) ?>
+ </p>
+ <?php endif; // logged in ?>
+
+ </div>
+ </div>
+
+ <?=$content_for_layout ?>
+
+</div> <!-- /.container -->
+
+<div id="footer" role="contentinfo">
+ <div class="section">
+ <div class="primary">
+
+ <?php if (!isset($suppressLanguageSelector) || !$suppressLanguageSelector): ?>
+ <form class="languages" method="get" action="">
+ <label for="language"><?=_('footer_other_languages')?></label>
+ <select id="language" name="lang" dir="ltr" onchange="this.form.submit()">
+ <?php
+ // Retrieve language arrays from bootstrap.
+ global $supported_languages, $native_languages;
+ foreach (array_keys($supported_languages) as $key) {
+ echo '<option value="'.$key.'" '.($key == LANG ? 'selected="selected"' : '').'>'
+ .$native_languages[$key]['native'].'</option>'."\n";
+ }
+ ?>
+ </select>
+ <button><?=_('footer_lang_form_lang_submit_go')?></button>
+ </form>
+ <?php endif; ?>
+
+ <p><strong><?=_('footer_copyright')?> <span title="<?=php_uname('n')?>">&#169;</span> 2005&#8211;<?=date('Y')?> Mozilla.</strong> <?=_('footer_all_rights_reserved')?></p>
+ <ul>
+ <li><?=$html->link(_('footer_privacy_policy'), '/pages/privacy');?></li>
+ <li><a href="http://www.mozilla.com/<?=LANG?>/about/legal.html"><?=_('footer_legal_notices')?></a></li>
+ <?php if (!isset($suppressCredits) || !$suppressCredits): ?><li><?=$html->link(_('footer_credits'), '/pages/credits')?></li><?php endif; ?>
+ <li><?=$html->link(___('footer_a_about'), '/pages/about')?></li>
+ <li><?=$html->link('<abbr title="'.___('footer_abbr_faq').'">'.___('footer_a_faq').'</abbr>', '/pages/faq')?></li>
+ <li><a href="http://blog.mozilla.com/addons"><?=___('footer_a_blog')?></a></li>
+ </ul>
+
+ <p class="disclaimer"><?=_('footer_disclaimer')?></p>
+ </div>
+ <div class="secondary">
+ <img src="<?=$html->url('/img/amo2009/illustrations/logo-add-ons-half.png', null, false, false)?>" alt="" />
+ </div>
+ </div> <!-- /.section -->
+</div> <!-- /#footer -->
+
+<?php
+if(defined('REVISION')) {
+ echo '<!-- r'.REVISION.' -->';
+}
+?>
+ </body>
+</html>
diff --git a/site/app/views/layouts/facebook.thtml b/site/app/views/layouts/facebook.thtml
new file mode 100644
index 0000000..244d981
--- /dev/null
+++ b/site/app/views/layouts/facebook.thtml
@@ -0,0 +1,98 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Justin Scott <fligtar@mozilla.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+if (empty($page)) {
+ $page = '';
+}
+?>
+<fb:ref url="<?=SITE_URL?>/css/facebook.php" />
+
+<div class="page">
+ <div class="page-header">
+ <img src="<?=FB_IMAGE_SITE?>/img/facebook/rockyourfirefox-header.png" height="80" width="646" alt="Rock Your Firefox">
+ </div>
+
+<?php
+ if (!empty($errorMessage)) {
+ echo "<fb:error><fb:message>{$errorTitle}</fb:message>{$errorMessage}</fb:error>";
+ }
+ if (!empty($successMessage)) {
+ echo "<fb:success><fb:message>{$successTitle}</fb:message>{$successMessage}</fb:success>";
+ }
+?>
+ <div class="search">
+ <form action="<?=FB_URL?>/search" method="get">
+ <span>Search Add-ons:</span>&nbsp;
+ <input class="inputtext inputsearch" type="search" name="q">
+ </form>
+ </div>
+
+ <fb:tabs>
+ <fb:tab-item title="Home" href="<?=FB_URL?>/home" <?=($page == 'home' ? 'selected="true" ' : '')?>/>
+ <fb:tab-item title="Browse Add-ons" href="<?=FB_URL?>/browse" <?=($page == 'browse' ? 'selected="true" ' : '')?>/>
+ <fb:tab-item title="Favorite Add-ons" href="<?=FB_URL?>/favorites" <?=($page == 'favorites' ? 'selected="true" ' : '')?>/>
+ <?php if ($page == 'search'): ?>
+ <fb:tab-item title="Search Results" href="<?=FB_URL?>/search" selected="true" />
+ <?php endif;
+ if ($page == 'view'): ?>
+ <fb:tab-item title="Add-on Details" href="<?=FB_URL?>/view/<?=$id?>" selected="true" />
+ <?php endif;
+ if ($page == 'faq'): ?>
+ <fb:tab-item title="FAQ" href="<?=FB_URL?>/faq" selected="true" />
+ <?php endif;
+ if ($page == 'updatenotes'): ?>
+ <fb:tab-item title="Update Notes" href="<?=FB_URL?>/updatenotes" selected="true" />
+ <?php endif;
+ if ($page == 'wallpaper'): ?>
+ <fb:tab-item title="Wallpaper" href="<?=FB_URL?>/wallpaper" selected="true" />
+ <?php endif;
+ if ($page == 'import'): ?>
+ <fb:tab-item title="Import" href="<?=FB_URL?>/import" selected="true" />
+ <?php endif; ?>
+ </fb:tabs>
+
+ <div class="content">
+ <?=$content_for_layout?>
+ </div>
+
+ <div class="page-footer">
+ Mozilla is providing links to these applications as a courtesy, and makes no representations regarding the applications or any information related there to.
+ <span title="<?=php_uname('n')?>">Use</span> of this service is subject to the Mozilla <a href="https://addons.mozilla.org/en-US/firefox/pages/privacy">Privacy Policy</a> and <a href="http://www.mozilla.com/en-US/about/legal.html">Legal Notices</a>.
+ </div>
+
+</div>
+
diff --git a/site/app/views/layouts/mozilla.thtml b/site/app/views/layouts/mozilla.thtml
new file mode 100644
index 0000000..380b2d0
--- /dev/null
+++ b/site/app/views/layouts/mozilla.thtml
@@ -0,0 +1,349 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Andrei Hajdukewycz <sancus@off.net> (Original Author)
+ * Mike Morgan <morgamic@mozilla.com>
+ * Justin Scott <fligtar@gmail.com>
+ * Frederic Wenzel <fwenzel@mozilla.com>
+ * Brian Krausz <brian@nerdlife.net>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html lang="<?=LANG?>" dir="<?=TEXTDIR?>" xmlns="http://www.w3.org/1999/xhtml">
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
+ <meta name="MSSmartTagsPreventParsing" content="true"/>
+ <meta name="Copyright" content="(c) 2005-<?php echo date('Y'); ?> Mozilla. All rights reserved."/>
+ <meta http-equiv="imagetoolbar" content="no"/>
+ <meta name="Rating" content="General"/>
+
+<?php
+
+ //Using revision # in url in production to prevent the file from being cached forever
+ if(defined('SITE_STATE') && (SITE_STATE == 'production' || SITE_STATE == 'staging')) {
+ $jsParams = '?'.JS_REVISION;
+ $cssParams = '?'.CSS_REVISION;
+ } else {
+ //To prevent caching in development, change the url on each request
+ $jsParams = '?'.time();
+ $cssParams = '?'.time();
+ }
+
+
+ if(defined('SITE_STATE') && (SITE_STATE == 'production' || SITE_STATE == 'staging')) {
+ echo str_replace('.css','.css'.$cssParams,$html->css('style.min', 'stylesheet', array('media'=>'all'), true))."\n";
+ }
+ else {
+ echo $html->css('type', 'stylesheet', array('media'=>'all'))."\n";
+ echo $html->css('color', 'stylesheet', array('media'=>'all'))."\n";
+ echo $html->css('screen', 'stylesheet', array('media'=>'screen,projection'))."\n";
+ echo $html->css('print', 'stylesheet', array('media'=>'print'))."\n";
+ }
+
+ echo '<!--[if IE]>'.$html->css('ie', 'stylesheet', array('media'=>'screen,projection'))."<![endif]-->\n";
+ echo '<!--[if lte IE 6]>'.$html->css('ie6', 'stylesheet', array('media'=>'screen,projection'))."<![endif]-->\n";
+ echo $html->css('remora', 'stylesheet', array('media'=>'screen,projection'))."\n";
+ if (!empty($cssAdd)) {
+ foreach ($cssAdd as $css) {
+ $url = $html->css($css);
+ echo "{$url}\n";
+ }
+ }
+?>
+
+ <link rel="search" type="application/opensearchdescription+xml" href="<?=$html->url('/AMOSearch.xml', null, false, false)?>" title="Mozilla Add-ons"/>
+ <?php if (isset($addon) && ($addon['Addon']['addontype_id'] == ADDON_SEARCH)) : ?>
+ <link rel="search" type="application/opensearchdescription+xml" href="<?=$html->urlFile($addon['Version'][0]['File'][0]['id'], $addon['Version'][0]['File'][0]['filename'])?>" locale="<?=$addon['Translation']['name']['locale']?>" title="<?=$addon['Translation']['name']['string']?>"/>
+ <?php endif; ?>
+ <link rel="shortcut icon" href="<?=$html->url('/img/favicon.ico', null, false, false)?>" type="image/x-icon"/>
+ <?php
+
+ if (!empty($rssAdd)) {
+ foreach ($rssAdd as $rss) {
+ if (is_array($rss)) {
+ $rssurl = $rss[0];
+ $rsstitle = $rss[1];
+ } else {
+ $rssurl = $rss;
+ $rsstitle = 'RSS';
+ }
+ echo '<link rel="alternate" type="application/rss+xml" title="'.$rsstitle.'" href="'.$html->url($rssurl).'"/>'."\n";
+ }
+ }
+ // Pre-script-inclusion JS
+ if (!empty($prescriptJS)) {
+ echo '<script type="text/javascript">'.$prescriptJS.'</script>';
+ }
+
+ if (empty($suppressUrchin)) {
+ echo $javascript->link('__utm.js');
+ }
+
+
+ echo $javascript->linkOut($html->url('/pages/js_constants'))."\n";
+
+ if (!isset($suppressJQuery) || !$suppressJQuery) {
+ if(defined('SITE_STATE') && (SITE_STATE == 'production' || SITE_STATE == 'staging')) {
+ echo $javascript->link('jquery.addons.min.js'.$jsParams)."\n";
+ } else {
+ echo $javascript->link('jquery-compressed.js');
+ echo $javascript->link('addons.js');
+ }
+
+ if (isset($includeSlimbox) && $includeSlimbox) {
+ echo $html->css('slimbox/slimbox');
+ echo $javascript->link('mootools/mootools-release-1.11.js'). "\n";
+ echo $javascript->link('slimbox/slimbox.js') . "\n";
+ }
+ }
+
+ if (!empty($jsAdd)) {
+ foreach ($jsAdd as $js) {
+ $js = $js;
+ $jslink = $javascript->link($js);
+ echo "{$jslink}\n";
+ }
+ }
+
+ if (!empty($jsLocalization) && is_object($localization)) {
+ echo $localization->jsLocalization($jsLocalization);
+ }
+
+
+ if ($this->controller->name == 'Addons' && $this->action == 'display') {
+
+ echo $javascript->link('jquery-ui/ui.lightbox.js') . "\n";
+ echo $html->css('jquery-lightbox', 'stylesheet', array('media'=>'screen,projection'))."\n";
+
+ echo '<script type="text/javascript">
+ // <![CDATA[
+
+ $(document).ready(function() {
+ $("a[rel*=jquery-lightbox]").lightBox({
+ overlayOpacity: 0.6,
+ imageBlank: "'.$html->url('/img/jquery-lightbox/lightbox-blank.gif', null, false, false).'",
+ imageLoading: "'.$html->url('/img/jquery-lightbox/lightbox-ico-loading.gif', null, false, false).'",
+ imageBtnClose: "'.$html->url('/img/jquery-lightbox/close.png', null, false, false).'",
+ imageBtnPrev: "'.$html->url('/img/jquery-lightbox/goleft.png', null, false, false).'",
+ imageBtnNext: "'.$html->url('/img/jquery-lightbox/goright.png', null, false, false).'",
+ containerResizeSpeed: 350
+ });
+
+ var etiquette_box = $("#addons-display-review-etiquette").hide();
+ $("#short-review").focus(function() { etiquette_box.show("fast"); } );
+ });
+
+ // This function toggles an element\'s text between two values
+ jQuery.fn.textToggle = function(text1, text2) {
+ jQuery(this).text( ( jQuery(this).text() == text1 ? text2 : text1 ) );
+ };
+
+ // ]]>
+ </script>';
+ }
+
+ ?>
+ <script type="text/javascript">
+ // <![CDATA[
+
+ $(document).ready(function() {
+ $(".hidden").hide(); // hide anything that should be hidden
+ $("#other-apps").addClass("collapsed js"); // collapse other apps menu
+
+ var q = $("#query");
+ var l = $("#search-query label");
+ l.show();
+ if ( q.val() == "<?=_('search_form_default_text')?>"){ //initially q is set to search add-ons text for javascriptless browsing
+ q.val('');
+ }
+ if ( q.val() != "") { // if field has any value...
+ l.hide(); // hide the label
+ };
+ l.click(function() { // for browsers with unclickable labels
+ q.focus();
+ });
+ q.focus(function() { // when field gains focus...
+ l.hide(); // hide the label
+ });
+ q.blur(function() { // when field loses focus...
+ if ( q.val() == "" ) { // if field is empty...
+ l.show(); // show the label again, else do nothing (label remains hidden)
+ };
+ });
+
+ // JS for toggling advanced versus normal search.
+ var adv = $("#advanced-search");
+ var advLink = $("#advanced-search-toggle a");
+ advLink.isHidden = true;
+ $('#advanced-search-toggle-link').attr('href', '#'); // for ie6-7
+ advLink.click(function() {
+ if(advLink.isHidden == true) {
+ adv.appendTo("#search-form");
+ advLink.addClass("asopen");
+ advLink.removeClass("asclosed");
+ advLink.isHidden = false;
+ } else {
+ adv.appendTo("#hidden-form");
+ advLink.addClass("asclosed");
+ advLink.removeClass("asopen");
+ advLink.isHidden = true;
+ }
+ return false;
+ });
+
+ <?php //to handle js-less case when a advanced query is sent there is one form, so have to add back hidden
+ // form for js-aware case.
+ if(isset($this->params['url']['as'])) { ?>
+ hiddenForm = document.createElement("form");
+ hiddenForm.id = "hidden-form";
+ var searchBubble = document.getElementById("search-bubble-inner");
+ searchBubble.appendChild(hiddenForm);
+ $("#hidden-form").addClass("asclosed");
+ $("#advanced-search").appendTo("#hidden-form");
+ advLink.click();
+ <?php } ?>
+
+ if (typeof __utmSetVar == 'function') {
+<?php if ($this->controller->Session->check('User')): ?>
+ __utmSetVar("Loggedin");
+<?php else: ?>
+ __utmSetVar("Loggedout");
+<?php endif; ?>
+ }
+
+<?php if(isset($content_wide) && $content_wide): ?>
+ if ( $(window).width() > 1000 ) {
+ $("#content").addClass("wide");
+ };
+
+ $(window).resize(function() {
+ if ( $(window).width() > 1000 ) {
+ $("#content").addClass("wide");
+ }
+ else if ( $(window).width() < 1000 ) {
+ $("#content").removeClass("wide");
+ }
+ });
+<?php endif; ?>
+
+ $("#other-apps h3").click(function() {
+ $("#other-apps").toggleClass("collapsed");
+ $(this).blur();
+ $(document).click(function(e) {
+ // Prevent weird delay when clicking on the links
+ var node = e.target;
+ while (node && !node.id) {
+ node = node.offsetParent;
+ }
+
+ if (!node || node.id != 'other-apps') {
+ $("#other-apps").addClass("collapsed");
+ }
+ });
+ return false;
+ });
+
+ }); // end dom ready
+
+<?php if (!empty($collapse_categories) && $collapse_categories == true): ?>
+ // Without JS, content leaves space for the category menu.
+ // With JS, the category menu collapses and the content spreads.
+ $(document).ready(function() {
+ $("#categories").addClass("collapsed"); // collapse categories menu
+ $("#content-main").addClass("full"); // make the content spread to the full width
+ $("#categories.collapsed h3").click(function() {
+ $("#cat-list").toggleClass("visible");
+ $(this).toggleClass("open");
+ $(document).click(function(e) {
+ var node = e.target;
+ while (node && !node.id) {
+ node = node.offsetParent;
+ }
+ if (!node || (node.id != 'categories' && node.id != 'cat-list')) {
+ $("#cat-list").removeClass("visible");
+ $("#categories.collapsed h3").removeClass("open");
+ }
+ });
+ });
+ });
+<?php endif; ?>
+
+ // ]]>
+ </script>
+
+
+
+
+ <title><?=$html->entities($title_for_layout)?></title>
+</head>
+
+
+<body id="mozilla-com" class="<?="html-".TEXTDIR?>">
+
+<?php
+if (is_object($this->controller->Config) && $this->controller->Config->getValue('site_notice') != '') {
+ echo '<div id="site-notice"><p>'.$this->controller->Config->getValue('site_notice').'</p></div>';
+}
+
+if (!(isset($suppressHeader) && $suppressHeader))
+ echo $this->renderElement('header');
+?>
+
+<?=$content_for_layout ?>
+
+<?php
+echo $this->renderElement('footer');
+
+if(defined('REVISION')) {
+ echo '<!-- r'.REVISION.' -->';
+}
+?>
+
+<?php if ($this->controller->name == 'Addons' &&
+ (in_array($this->action, array('home', 'browse', 'category_landing'))) ): ?>
+<script type="text/javascript">
+ if ($('.slider_widget').length > 0) {
+ $('.slider_widget').slider({
+ 'prev_img_src': '<?=$html->urlImage("slider-prev.gif")?>',
+ 'prev_disabled_img_src': '<?=$html->urlImage("slider-prev-disabled.gif")?>',
+ 'next_img_src': '<?=$html->urlImage("slider-next.gif")?>',
+ 'next_disabled_img_src': '<?=$html->urlImage("slider-next-disabled.gif")?>'
+ });
+ }
+</script>
+<?php endif; ?>
+
+</body>
+</html>
diff --git a/site/app/views/layouts/rest.thtml b/site/app/views/layouts/rest.thtml
new file mode 100644
index 0000000..be4004a
--- /dev/null
+++ b/site/app/views/layouts/rest.thtml
@@ -0,0 +1,42 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Laura Thomson <lthomson@mozilla.com> (Original Author)
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+ $this->controller->forceCache();
+ header('Content-type: text/xml');
+ echo '<?xml version="1.0" encoding="utf-8" ?>';
+ echo $content_for_layout;
+?>
diff --git a/site/app/views/layouts/rss.thtml b/site/app/views/layouts/rss.thtml
new file mode 100644
index 0000000..e0b9232
--- /dev/null
+++ b/site/app/views/layouts/rss.thtml
@@ -0,0 +1,15 @@
+<?php header('Content-type: text/xml'); ?>
+<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/">
+ <channel>
+ <title><?=$rss_title?></title>
+ <link><?='http'.(!empty($_SERVER['HTTPS'])?'s':'').'://'.$_SERVER['SERVER_NAME'].$html->url('/');?></link>
+ <description><?=$rss_description ?></description>
+ <language><?=strtolower(LANG) ?></language>
+ <pubDate><?=$time->toRss(gmmktime()) ?></pubDate>
+ <docs>http://blogs.law.harvard.edu/tech/rss</docs>
+ <generator>Mozilla Add-ons</generator>
+
+ <?php echo $content_for_layout; ?>
+
+ </channel>
+</rss>
diff --git a/site/app/views/layouts/tests.thtml b/site/app/views/layouts/tests.thtml
new file mode 100644
index 0000000..d538ad2
--- /dev/null
+++ b/site/app/views/layouts/tests.thtml
@@ -0,0 +1,36 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" version="-//W3C//DTD XHTML 1.1//EN" xml:lang="en">
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
+ <title>AMO Tests</title>
+ <?=$html->css('tests')?>
+ <?=$html->css('admin')?>
+ <?=$javascript->link('jquery-compressed.js')?>
+ <?=$javascript->link('jquery.autocomplete.pack.js')?>
+ <?=$javascript->link('listing')?>
+</head>
+<body>
+ <div class="menu">
+ <span class="title">AMO 'Project Remora' Test Suite</span>
+ <span class="items">
+ <?=$html->link('Tests Main', '/tests')?> |
+ <?=$html->link('Run All Tests', '/tests/all')?> |
+ <?php
+ $tests = $this->controller->Session->read('Tests');
+ $referer = urlencode(str_replace('url=', '', $_SERVER['QUERY_STRING']));
+ $referer = str_replace(LANG, '', $referer);
+ $referer = str_replace(APP_SHORTNAME, '', $referer);
+ $referer = str_replace('//', '/', $referer);
+ if ($tests['Passes'] === false) {
+ echo $html->link('Turn Passes ON', '/tests/passes/on/?r='.$referer);
+ }
+ else {
+ echo $html->link('Turn Passes OFF', '/tests/passes/off/?r='.$referer);
+ }
+ ?>
+ <?=(!empty($svn)) ? ' | '.$svn : ''?>
+ </span>
+ </div>
+ <?php echo $content_for_layout; ?>
+</body>
+</html>
diff --git a/site/app/views/localizers/applications.thtml b/site/app/views/localizers/applications.thtml
new file mode 100644
index 0000000..fbbbe56
--- /dev/null
+++ b/site/app/views/localizers/applications.thtml
@@ -0,0 +1,74 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific USERLANGuage governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * Justin Scott <fligtar@gmail.com>.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+?>
+<div id="content">
+ <?=$this->renderElement('developers/localizermenu');?>
+
+ <div id="content-main">
+ <h3>Application Localization for <?=USERLANG?></h3>
+ <?php
+ if (!$writeAccess) {
+ echo '<div class="error">You do not have write access to this locale. You can look, but won\'t be able to make any changes.</div>';
+ }
+ echo $html->formTag('/localizers/applications');
+ if (!empty($applications)) {
+ foreach ($applications['en-US'] as $k => $application) {
+ $id = $applications['en-US'][$k]['Application']['id'];
+ echo '<table class="translatedSection">';
+ echo '<tr>';
+ echo '<th width="5%">ID '.$id.'</th>';
+ echo '<th width="50%">en-US</th>';
+ echo '<th width="45%">'.USERLANG.'</th>';
+ echo '</tr>';
+ echo '<tr>';
+ echo '<td class="field">Name</td>';
+ echo '<td class="enus">'.$applications['en-US'][$k]['Translation']['name']['string'].'</td>';
+ echo '<td class="localized">'.$html->input("Application/{$id}][name", array('value' => ($applications[USERLANG][$k]['Translation']['name']['locale'] != 'en-US' ? $applications[USERLANG][$k]['Translation']['name']['string'] : ''), 'size' => 40)).'</td>';
+ echo '</tr>';
+ echo '<tr>';
+ echo '<td class="field">Short Name</td>';
+ echo '<td class="enus">'.$applications['en-US'][$k]['Translation']['shortname']['string'].'</td>';
+ echo '<td class="localized">'.$html->input("Application/{$id}][shortname", array('value' => ($applications[USERLANG][$k]['Translation']['shortname']['locale'] != 'en-US' ? $applications[USERLANG][$k]['Translation']['shortname']['string'] : ''), 'size' => 40)).'</td>';
+ echo '</tr>';
+ echo '</table>';
+ }
+ }
+ echo $html->submit('Update Translations');
+ ?>
+ </form>
+ </div>
+</div>
diff --git a/site/app/views/localizers/gettext.thtml b/site/app/views/localizers/gettext.thtml
new file mode 100644
index 0000000..e68299a
--- /dev/null
+++ b/site/app/views/localizers/gettext.thtml
@@ -0,0 +1,66 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * Justin Scott <fligtar@gmail.com>.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+?>
+<div id="content">
+ <?=$this->renderElement('developers/localizermenu');?>
+
+ <div id="content-main">
+ <h3>Gettext Information</h3>
+ <?php
+ echo $html->link('en-US file', 'http://svn.mozilla.org/addons/trunk/site/app/locale/en_US/LC_MESSAGES/messages.po');
+ echo ' | ';
+ echo $html->link(USERLANG.' file', "http://svn.mozilla.org/addons/trunk/site/app/locale/{$userlang}/LC_MESSAGES/messages.po");
+ echo '<br>';
+ $translated = $total - count($untranslated);
+ $percent = ceil(($translated / $total) * 100);
+ echo "<b>".USERLANG." Translated Strings: {$translated} / {$total} ({$percent}%)</b>";
+ ?>
+ <p>The following <?=count($untranslated)?> strings are the same as their en-US translations and have been considered untranslated:</p>
+ <?php
+ if (!empty($untranslated)) {
+ echo '<ul>';
+ foreach ($untranslated as $key => $string) {
+ echo "<li><b>{$key}</b> - {$string}</li>";
+ }
+ echo '</ul>';
+ }
+ else {
+ echo '<i>None</i>';
+ }
+ ?>
+ </div>
+</div>
diff --git a/site/app/views/localizers/logs.thtml b/site/app/views/localizers/logs.thtml
new file mode 100644
index 0000000..9d13800
--- /dev/null
+++ b/site/app/views/localizers/logs.thtml
@@ -0,0 +1,53 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * Justin Scott <fligtar@gmail.com>.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+?>
+<div id="content">
+ <?=$this->renderElement('developers/localizermenu');?>
+
+ <div id="content-main">
+ <h3>Log Viewer for <?=USERLANG?></h3>
+ <?php
+ if (!empty($logs)) {
+ echo '<ul>';
+ foreach ($logs as $log) {
+ echo "<li>[{$log['time']}] {$log['entry']}</li>";
+ }
+ echo '</ul>';
+ }
+ ?>
+ </div>
+</div>
diff --git a/site/app/views/localizers/pages.thtml b/site/app/views/localizers/pages.thtml
new file mode 100644
index 0000000..a556d2b
--- /dev/null
+++ b/site/app/views/localizers/pages.thtml
@@ -0,0 +1,87 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * Justin Scott <fligtar@gmail.com>.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+?>
+<div id="content">
+ <?=$this->renderElement('developers/localizermenu');?>
+
+ <div id="content-main">
+ <h3>Localized Pages</h3>
+ <table class="stats">
+ <tr>
+ <td class="heading" colspan=4>Translated Strings</td>
+ </tr>
+ <tr>
+ <th>Page Name</th>
+ <th>Display URL</th>
+ <th>SVN</th>
+ <th>Status</th>
+ </tr>
+ <?php
+ foreach ($pages as $page) {
+ echo '<tr>';
+ echo "<td>{$page['page']}</td>";
+ echo '<td>'.(!empty($page['url']) ? $html->link($page['url'], $page['url']) : 'Not Available').'</td>';
+ echo '<td>'.$html->link('SVN', "http://svn.mozilla.org/addons/trunk/site/app/locale/en_US/pages/{$page['page']}").'</td>';
+ echo '<td'.($page['exists'] ? ' class="translated">TRANSLATED</td>' : ' class="notTranslated">NOT TRANSLATED</td>').'</td>';
+ echo '</tr>';
+ }
+ ?>
+ </table>
+
+ <table class="stats">
+ <tr>
+ <td class="heading" colspan=4>Translated Images</td>
+ </tr>
+ <tr>
+ <th>Image Name</th>
+ <th>Display URL</th>
+ <th>SVN</th>
+ <th>Status</th>
+ </tr>
+ <?php
+ foreach ($images as $image) {
+ echo '<tr>';
+ echo "<td>{$image['image']}</td>";
+ echo '<td>'.(!empty($image['url']) ? $html->link($image['url'], $image['url']) : 'Not Available').'</td>';
+ echo '<td>'.$html->link('SVN', "http://svn.mozilla.org/addons/trunk/site/app/locale/en_US/images/{$image['image']}").'</td>';
+ echo '<td'.($image['exists'] ? ' class="translated">TRANSLATED</td>' : ' class="notTranslated">NOT TRANSLATED</td>').'</td>';
+ echo '</tr>';
+ }
+ ?>
+ </table>
+ </div>
+</div>
diff --git a/site/app/views/localizers/platforms.thtml b/site/app/views/localizers/platforms.thtml
new file mode 100644
index 0000000..c13aab6
--- /dev/null
+++ b/site/app/views/localizers/platforms.thtml
@@ -0,0 +1,74 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific USERLANGuage governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * Justin Scott <fligtar@gmail.com>.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+?>
+<div id="content">
+ <?=$this->renderElement('developers/localizermenu');?>
+
+ <div id="content-main">
+ <h3>Platform Localization for <?=USERLANG?></h3>
+ <?php
+ if (!$writeAccess) {
+ echo '<div class="error">You do not have write access to this locale. You can look, but won\'t be able to make any changes.</div>';
+ }
+ echo $html->formTag('/localizers/platforms');
+ if (!empty($platforms)) {
+ foreach ($platforms['en-US'] as $k => $platform) {
+ $id = $platforms['en-US'][$k]['Platform']['id'];
+ echo '<table class="translatedSection">';
+ echo '<tr>';
+ echo '<th width="5%">ID '.$id.'</th>';
+ echo '<th width="50%">en-US</th>';
+ echo '<th width="45%">'.USERLANG.'</th>';
+ echo '</tr>';
+ echo '<tr>';
+ echo '<td class="field">Name</td>';
+ echo '<td class="enus">'.$platforms['en-US'][$k]['Translation']['name']['string'].'</td>';
+ echo '<td class="localized">'.$html->input("Platform/{$id}][name", array('value' => ($platforms[USERLANG][$k]['Translation']['name']['locale'] != 'en-US' ? $platforms[USERLANG][$k]['Translation']['name']['string'] : ''), 'size' => 40)).'</td>';
+ echo '</tr>';
+ echo '<tr>';
+ echo '<td class="field">Short Name</td>';
+ echo '<td class="enus">'.$platforms['en-US'][$k]['Translation']['shortname']['string'].'</td>';
+ echo '<td class="localized">'.$html->input("Platform/{$id}][shortname", array('value' => ($platforms[USERLANG][$k]['Translation']['shortname']['locale'] != 'en-US' ? $platforms[USERLANG][$k]['Translation']['shortname']['string'] : ''), 'size' => 40)).'</td>';
+ echo '</tr>';
+ echo '</table>';
+ }
+ }
+ echo $html->submit('Update Translations');
+ ?>
+ </form>
+ </div>
+</div>
diff --git a/site/app/views/localizers/summary.thtml b/site/app/views/localizers/summary.thtml
new file mode 100644
index 0000000..e3bf193
--- /dev/null
+++ b/site/app/views/localizers/summary.thtml
@@ -0,0 +1,85 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * Justin Scott <fligtar@gmail.com>.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+?>
+<div id="content">
+ <?=$this->renderElement('developers/localizermenu');?>
+
+ <div id="content-main">
+ <h3>Localization Summary</h3>
+ <table class="stats">
+ <tr>
+ <td class="heading" colspan=2>Translated Dynamic Strings</td>
+ </tr>
+ <tr><td><table width="100%">
+ <?php
+ global $native_languages;
+ $middle = ceil(count($localeStats)/2);
+ $i = 0;
+ foreach ($localeStats as $locale => $localeStat) {
+ if ($i == $middle) {
+ echo '</table></td><td><table width="100%" style="border-left: 1px solid gray;">';
+ }
+
+ echo '<tr>';
+ echo '<td class="title">'.$native_languages[$locale]['native'].' ('.$locale.')</td>';
+ $percent = ceil(($localeStat[0][0]['COUNT(*)'] / $localeStats['en-US'][0][0]['COUNT(*)']) * 100);
+ echo '<td class="value">'.$localeStat[0][0]['COUNT(*)'].' / '.$localeStats['en-US'][0][0]['COUNT(*)'].' ('.$percent.'%)</td>';
+ echo '</tr>';
+ $i++;
+ }
+ ?>
+ </table></td></tr>
+ <tr><td colspan=4>See the <?=$html->link('Pages', '/localizers/pages')?> and <?=$html->link('Gettext', '/localizers/gettext')?> sections for additional statistics.</td></tr>
+ </table>
+
+ <table width="100%" class="log">
+ <tr>
+ <td class="heading" colspan=2>Recent Localization Activity</td>
+ </tr>
+ <?php
+ if (!empty($logs)) {
+ foreach ($logs as $log) {
+ echo '<tr>';
+ echo '<td class="value" style="font-size: 80%;">'.$log['time'].'</td>';
+ echo '<td class="title">'.$log['entry'].'</td>';
+ echo '</tr>';
+ }
+ }
+ ?>
+ </table>
+ </div>
+</div>
diff --git a/site/app/views/localizers/tags.thtml b/site/app/views/localizers/tags.thtml
new file mode 100644
index 0000000..72a82fb
--- /dev/null
+++ b/site/app/views/localizers/tags.thtml
@@ -0,0 +1,74 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific USERLANGuage governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * Justin Scott <fligtar@gmail.com>.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+?>
+<div id="content">
+ <?=$this->renderElement('developers/localizermenu');?>
+
+ <div id="content-main">
+ <h3>Tag Localization for <?=USERLANG?></h3>
+ <?php
+ if (!$writeAccess) {
+ echo '<div class="error">You do not have write access to this locale. You can look, but won\'t be able to make any changes.</div>';
+ }
+ echo $html->formTag('/localizers/tags');
+ if (!empty($tags)) {
+ foreach ($tags['en-US'] as $k => $tag) {
+ $id = $tags['en-US'][$k]['Tag']['id'];
+ echo '<table class="translatedSection">';
+ echo '<tr>';
+ echo '<th width="5%">ID '.$id.'</th>';
+ echo '<th width="50%">en-US</th>';
+ echo '<th width="45%">'.USERLANG.'</th>';
+ echo '</tr>';
+ echo '<tr>';
+ echo '<td class="field">Name</td>';
+ echo '<td class="enus">'.$tags['en-US'][$k]['Translation']['name']['string'].'</td>';
+ echo '<td class="localized">'.$html->input("Tag/{$id}][name", array('value' => ($tags[USERLANG][$k]['Translation']['name']['locale'] != 'en-US' ? $tags[USERLANG][$k]['Translation']['name']['string'] : ''), 'size' => 40)).'</td>';
+ echo '</tr>';
+ echo '<tr>';
+ echo '<td class="field">Description</td>';
+ echo '<td class="enus">'.$tags['en-US'][$k]['Translation']['description']['string'].'</td>';
+ echo '<td class="localized">'.$html->textarea("Tag/{$id}][description", array('value' => ($tags[USERLANG][$k]['Translation']['description']['locale'] != 'en-US' ? $tags[USERLANG][$k]['Translation']['description']['string'] : ''), 'cols' => 34, 'rows' => 3)).'</td>';
+ echo '</tr>';
+ echo '</table>';
+ }
+ }
+ echo $html->submit('Update Translations');
+ ?>
+ </form>
+ </div>
+</div>
diff --git a/site/app/views/pages/about.thtml b/site/app/views/pages/about.thtml
new file mode 100644
index 0000000..4c7befc
--- /dev/null
+++ b/site/app/views/pages/about.thtml
@@ -0,0 +1,49 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ *
+ * Contributor(s):
+ * Jeff Balogh <jbalogh@mozilla.com> (Original Author)
+ * Wil Clouser <wclouser@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+$this->layout = 'amo2009';
+?>
+
+<div class="secondary" role="complementary">
+ <?=$this->renderElement('amo2009/categories')?>
+</div>
+
+<div class="primary prose" role="main">
+ <?=$this->renderElement('amo2009/search')?>
+
+ <?=$localization->includeLocalPage('about')?>
+</div>
diff --git a/site/app/views/pages/appversions.thtml b/site/app/views/pages/appversions.thtml
new file mode 100644
index 0000000..d719204
--- /dev/null
+++ b/site/app/views/pages/appversions.thtml
@@ -0,0 +1,96 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * Justin Scott <fligtar@gmail.com>.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Wil Clouser <wclouser@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+$this->layout = 'amo2009';
+
+loadModel('Application');
+loadComponent('Versioncompare');
+
+$applicationModel =& new Application();
+$versionCompare =& new VersioncompareComponent();
+
+$applicationModel->unbindModel(array('hasAndBelongsToMany' => array('Version'), 'hasMany' => array('Tag')));
+$applications = $applicationModel->findAll('Application.supported=1', null, null, null, null, 2);
+
+foreach ($applications as $application) {
+ if (empty($versions[$application['Application']['id']]['guid'])) {
+ $versions[$application['Application']['id']]['guid'] = $application['Application']['guid'];
+ $versions[$application['Application']['id']]['name'] = $application['Translation']['name']['string'];
+ }
+
+ if (!empty($application['Appversion'])) {
+ $appversions = array();
+ //Change array structure for sorting
+ foreach ($application['Appversion'] as $appversion) {
+ $appversions[]['Appversion']['version'] = $appversion['version'];
+ }
+ $versionCompare->sortAppversionArray($appversions);
+
+ foreach ($appversions as $appversion) {
+ $versions[$application['Application']['id']]['versions'][] = $appversion['Appversion']['version'];
+ }
+ }
+}
+?>
+
+<div class="secondary" role="complementary">
+ <?=$this->renderElement('amo2009/categories')?>
+</div>
+
+<div class="primary prose" role="main">
+ <?=$this->renderElement('amo2009/search')?>
+
+<?php
+ echo '<h1>'._('pages_appversions_header').'</h1>';
+ echo '<p>'._('pages_appversions_intro').'</p>';
+ foreach ($versions as $version) {
+ echo '<div>';
+ echo '<h3>'.
+ $html->image('app-icons/'.strtolower($version['name']).'_small.png', array('style' => 'vertical-align: middle; padding-right: 10px;')).
+ '<b>'.$version['name'].'</b></h3>';
+ echo '<ul>';
+ echo '<li>'._('pages_appversions_guid').': '.$version['guid'].'</li>';
+ echo '<li>'._('pages_appversions_versions').': '.implode(', ', $version['versions']);
+ echo '</ul>';
+ echo '</div>';
+ }
+
+ echo '<p>'.sprintf(_('pages_appversions_required_files'), $html->link(_('pages_appversions_required_files_link'), 'http://developer.mozilla.org/en/docs/Install_Manifests')).'</p>';
+?>
+
+</div>
diff --git a/site/app/views/pages/collector.thtml b/site/app/views/pages/collector.thtml
new file mode 100644
index 0000000..9d29de4
--- /dev/null
+++ b/site/app/views/pages/collector.thtml
@@ -0,0 +1,70 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ *
+ * Contributor(s):
+ * Wil Clouser <wclouser@mozilla.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+$this->layout = 'amo2009';
+
+$addon = $this->controller->Addon->getAddon(COLLECTOR_ID, array('compatible_apps', 'files', 'latest_version', 'list_details'));
+$params = array('addon' => $addon,
+ 'buttonSize' => '16x16',
+ 'buttonClass' => 'significant');
+$_install_button = $this->renderElement('amo2009/install', $params);
+
+$_breadcrumbs = array(
+ sprintf(___('addons_home_pagetitle'), APP_PRETTYNAME) => '/',
+ ___('collections_breadcrumb') => '/collections'
+);
+
+?>
+
+<div class="stand-alone-options">
+ <?php
+ echo $this->renderElement('amo2009/search');
+ echo $this->renderElement('amo2009/categories');
+ ?>
+</div>
+
+<div class="primary" role="main">
+ <?=$this->renderElement('amo2009/breadcrumbs', array('breadcrumbs' => $_breadcrumbs))?>
+ <?=$localization->includeLocalPage('collector',array(
+ 'install_button' => $_install_button,
+ 'href_collector_features' => $html->url('/pages/collector_features'),
+ 'href_collector_faq' => $html->url('/pages/collector_faq'),
+ ))?>
+</div>
+
+<div class="secondary" role="complementary">
+ <?=$html->image('amo2009/illustrations/logo-collections-220x270.png', array('alt' => ___('collector_features_img_logo'), 'class' => 'scale'))?>
+</div>
diff --git a/site/app/views/pages/collector_faq.thtml b/site/app/views/pages/collector_faq.thtml
new file mode 100644
index 0000000..b462f92
--- /dev/null
+++ b/site/app/views/pages/collector_faq.thtml
@@ -0,0 +1,66 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ *
+ * Contributor(s):
+ * Wil Clouser <wclouser@mozilla.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+$this->layout = 'amo2009';
+?>
+<div class="section">
+ <div class="stand-alone-options">
+ <?php
+ echo $this->renderElement('amo2009/search');
+ echo $this->renderElement('amo2009/categories');
+ ?>
+ </div>
+ <div class="primary" role="main">
+ <?php
+ $breadcrumbs = array(
+ sprintf(___('addons_home_pagetitle'), APP_PRETTYNAME) => '/',
+ ___('collections_breadcrumb') => '/collections'
+ );
+ ?>
+ <?=$this->renderElement('amo2009/breadcrumbs', array('breadcrumbs' => $breadcrumbs))?>
+ <?=$localization->includeLocalPage('collector_faq', array($html->url('/users/register'), $html->url('/collections')))?>
+ </div>
+ <div id="collector-sidebar" class="secondary" role="complementary">
+ <?=$this->renderElement('amo2009/collector_sidebar_download')?>
+ <ul>
+ <li>
+ <a href="<?=$html->url('/pages/collector')?>">
+ <?=___('collector_features_a_home')?>
+ </a>
+ </li>
+ </ul>
+ </div>
+</div>
diff --git a/site/app/views/pages/collector_features.thtml b/site/app/views/pages/collector_features.thtml
new file mode 100644
index 0000000..2eba280
--- /dev/null
+++ b/site/app/views/pages/collector_features.thtml
@@ -0,0 +1,77 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Jeff Balogh <jbalogh@mozilla.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+$this->layout = 'amo2009';
+?>
+
+
+
+<div class="section">
+ <div class="stand-alone-options">
+ <?php
+ echo $this->renderElement('amo2009/search');
+ echo $this->renderElement('amo2009/categories');
+ ?>
+ </div>
+ <div class="primary" role="main">
+ <?php
+ $breadcrumbs = array(
+ sprintf(___('addons_home_pagetitle'), APP_PRETTYNAME) => '/',
+ ___('collections_breadcrumb') => '/collections'
+ );
+ ?>
+ <?=$this->renderElement('amo2009/breadcrumbs', array('breadcrumbs' => $breadcrumbs))?>
+ <?=$localization->includeLocalPage('collector_features',
+ $html->url('/collections'))?>
+ </div>
+ <div id="collector-sidebar" class="secondary" role="complementary">
+ <?=$this->renderElement('amo2009/collector_sidebar_download')?>
+ <ul>
+ <li>
+ <a href="<?=$html->url('/pages/collector')?>">
+ <?=___('collector_features_a_home')?>
+ </a>
+ </li>
+ <li>
+ <a href="<?=$html->url('/pages/collector_faq')?>">
+ <?=___('footer_abbr_faq')?>
+ </a>
+ </li>
+ </ul>
+ </div>
+</div>
diff --git a/site/app/views/pages/collector_firstrun.thtml b/site/app/views/pages/collector_firstrun.thtml
new file mode 100644
index 0000000..c4d05f8
--- /dev/null
+++ b/site/app/views/pages/collector_firstrun.thtml
@@ -0,0 +1,119 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Jeff Balogh <jbalogh@mozilla.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+$this->layout = 'amo2009';
+
+$breadcrumbs = array(
+ sprintf(___('addons_home_pagetitle'), APP_PRETTYNAME) => '/',
+ ___('collections_breadcrumb') => '/collections'
+);
+ // This code is a bit ugly because we need to work within the constraints of the pages controller.
+ // Build the collection menu here because we have access to the controllers we need.
+ $_collection_menu = '';
+ $_favorite_button = '';
+ $collections = $this->controller->Collection->getEditorPicks(5);
+ /* Need these variables to show the Add to Favorites buttons */
+ $user = $this->controller->Session->read('User');
+ $subscribe_url = $html->url('/collections/subscribe/ajax');
+
+ foreach ($collections as $collection) {
+ $c = $collection['Collection'];
+ $uuid = $c['uuid'];
+ $_favorite_button = '<div class="collector-firstrun-favorite favourite"> </div>'; // default is no button
+
+ if ($this->controller->Session->check('User')) {
+ $fav = $this->controller->Collection->isSubscribed($c['id'], $user['id']);
+ if ($fav) {
+ continue;
+ }
+ $text = ___('collections_detail_button_add');
+ $_favorite_button = <<<FAVORITE_BUTTON
+ <form class="collector-firstrun-favorite favourite" method="post" action="{$subscribe_url}">
+ <div>
+ {$html->hiddenSession()}
+ <input value="{$uuid}" type="hidden" name="uuid" />
+ <button class="neutral auxillary">
+ {$html->image("amo2009/icons/buttons/plus-orange-8x9.gif", array('alt' => ''))}
+ {$text}
+ </button>
+ </div>
+ </form>
+FAVORITE_BUTTON;
+ }
+
+ $_collection_menu .= <<<COLLECTION_GROUP
+ <li>
+ <h5>
+ <img src="{$this->controller->Image->getCollectionIconUrl($collection['Collection']['id'])}" class="icon" alt="" />
+ {$html->link($collection['Translation']['name']['string'], $this->controller->Collection->getDetailUrl($collection))}
+ </h5>
+ {$_favorite_button}
+ </li>
+COLLECTION_GROUP;
+ }
+?>
+<div class="section">
+
+ <div class="stand-alone-options">
+ <?php
+ echo $this->renderElement('amo2009/search');
+ echo $this->renderElement('amo2009/categories');
+ ?>
+ </div>
+
+ <div class="primary" role="main">
+ <?=$this->renderElement('amo2009/breadcrumbs', array('breadcrumbs' => $breadcrumbs))?>
+ <script type="text/javascript">
+ <?=$this->renderElement('amo2009/collections_js_init', array(
+ 'addButtonSize' => '8x9',
+ 'removeButtonSize' => '8x9',
+ 'loadingButtonSize' => '8x8'))?>
+ </script>
+ <?=$localization->includeLocalPage('collector_firstrun', array(
+ $html->url('/pages/collector_features'),
+ $html->url('/pages/collector_faq'),
+ $_collection_menu,
+ $html->url('/collections')
+ ))?>
+ </div>
+
+ <div class="secondary" role="complementary">
+ <?=$html->image('amo2009/illustrations/logo-collections-220x270.png', array( 'class' => 'scale', 'alt' => ___('collector_features_img_logo')))?>
+ </div>
+
+</div>
diff --git a/site/app/views/pages/credits.thtml b/site/app/views/pages/credits.thtml
new file mode 100644
index 0000000..d8d05e5
--- /dev/null
+++ b/site/app/views/pages/credits.thtml
@@ -0,0 +1,144 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Justin Scott <fligtar@mozilla.com> (Original Author)
+ * Wil Clouser <wclouser@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+$this->layout = 'amo2009';
+
+loadModel('Group');
+$groupModel =& new Group();
+
+$groups = $groupModel->findAll();
+
+global $valid_languages, $native_languages;
+
+$developers = array();
+$localizers = array();
+$editors = array();
+$past_developers = array();
+$other_contributors = array();
+
+foreach ($groups as $group) {
+ if (strpos($group['Group']['rules'], 'Localizers') !== false) {
+ $rules = explode(':', $group['Group']['rules']);
+
+ if (array_key_exists($rules[1], $valid_languages)) {
+ foreach ($group['User'] as $user) {
+ $localizers["{$user['firstname']} {$user['lastname']}"] = $html->link("{$user['firstname']} {$user['lastname']}", "/user/{$user['id']}")." ({$native_languages[$rules[1]]['native']})";
+ }
+ }
+ }
+ elseif ($group['Group']['name'] == 'Editors' || $group['Group']['name'] == 'Senior Editors') {
+ foreach ($group['User'] as $user) {
+ $editors["{$user['firstname']} {$user['lastname']}"] = $html->link("{$user['firstname']} {$user['lastname']}", "/user/{$user['id']}");
+ }
+ }
+ elseif ($group['Group']['name'] == 'Past Developers') {
+ foreach ($group['User'] as $user) {
+ $past_developers["{$user['firstname']} {$user['lastname']}"] = $html->link("{$user['firstname']} {$user['lastname']}", "/user/{$user['id']}");
+ }
+ }
+ elseif ($group['Group']['name'] == 'Developers') {
+ foreach ($group['User'] as $user) {
+ $developers["{$user['firstname']} {$user['lastname']}"] = $html->link("{$user['firstname']} {$user['lastname']}", "/user/{$user['id']}");
+ }
+ }
+ elseif ($group['Group']['name'] == 'Other Contributors') {
+ foreach ($group['User'] as $user) {
+ $other_contributors["{$user['firstname']} {$user['lastname']}"] = $html->link("{$user['firstname']} {$user['lastname']}", "/user/{$user['id']}");
+ }
+ }
+}
+ksort($developers);
+ksort($localizers);
+ksort($editors);
+ksort($past_developers);
+ksort($other_contributors);
+?>
+<div class="secondary" role="complementary">
+ <?=$this->renderElement('amo2009/categories')?>
+</div>
+
+<div class="primary prose" role="main">
+ <?=$this->renderElement('amo2009/search')?>
+
+<?=_('credits_intro')?>
+<br/><br/>
+<div class="corner-box">
+<?php
+ echo '<h4>'._('credits_section_developers').'</h4>';
+ echo implode(', ', $developers);
+?>
+</div>
+<div class="corner-box">
+<?php
+ echo '<h4>'._('credits_section_localizers').'</h4>';
+ echo implode(', ', $localizers);
+?>
+</div>
+<div class="corner-box">
+<?php
+ echo '<h4>'._('credits_section_editors').'</h4>';
+ echo implode(', ', $editors);
+?>
+</div>
+<div class="corner-box">
+<?php
+ echo '<h4>'._('credits_section_other_contributors').'</h4>';
+ echo implode(', ', $other_contributors);
+?>
+</div>
+<div class="corner-box">
+<?php
+ echo '<h4>'._('credits_section_past_developers').'</h4>';
+ echo implode(', ', $past_developers);
+?>
+</div>
+<div class="corner-box">
+<?php
+ echo '<h4>'._('credits_section_software').'</h4>';
+?>
+ <ul>
+ <li><?=_('credits_software_famfamfam')?></li>
+ <li><?=___('credits_software_timeplot', 'Some pages use elements of <a href="http://www.simile-widgets.org/timeplot/">Timeplot</a>, licensed under a <a href="http://simile.mit.edu/license.html">BSD License</a>.')?></li>
+ </ul>
+</div>
+
+<br/>
+<?=sprintf(_('credits_contributing'), $html->link(_('credits_contributing_wikipage'), 'http://wiki.mozilla.org/Update'))?>
+
+</div>
diff --git a/site/app/views/pages/developer_faq.thtml b/site/app/views/pages/developer_faq.thtml
new file mode 100644
index 0000000..9b4a40b
--- /dev/null
+++ b/site/app/views/pages/developer_faq.thtml
@@ -0,0 +1,48 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ *
+ * Contributor(s):
+ * Jeff Balogh <jbalogh@mozilla.com> (Original Author)
+ * Wil Clouser <wclouser@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+$this->layout = 'amo2009';
+?>
+
+<div class="secondary" role="complementary">
+ <?=$this->renderElement('amo2009/categories')?>
+</div>
+
+<div class="primary prose" role="main">
+ <?=$this->renderElement('amo2009/search')?>
+ <?=$localization->includeLocalPage('developer_faq')?>
+</div>
diff --git a/site/app/views/pages/faq.thtml b/site/app/views/pages/faq.thtml
new file mode 100644
index 0000000..1133b08
--- /dev/null
+++ b/site/app/views/pages/faq.thtml
@@ -0,0 +1,52 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Mike Morgan <morgamic@mozilla.com> (Original Author)
+ * Wil Clouser <wclouser@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+$this->layout = 'amo2009';
+?>
+
+<div class="secondary" role="complementary">
+ <?=$this->renderElement('amo2009/categories')?>
+</div>
+
+<div class="primary prose" role="main">
+ <?=$this->renderElement('amo2009/search')?>
+
+ <?=$localization->includeLocalPage('faq')?>
+
+</div>
diff --git a/site/app/views/pages/fashionyourfirefox_faq.thtml b/site/app/views/pages/fashionyourfirefox_faq.thtml
new file mode 100644
index 0000000..a39708d
--- /dev/null
+++ b/site/app/views/pages/fashionyourfirefox_faq.thtml
@@ -0,0 +1,51 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Frederic Wenzel <fwenzel@mozilla.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+$this->layout = 'mozilla';
+?>
+<div id="page">
+
+<div id="branding">
+ <h2>Fashion Your Firefox</h2>
+ <div id="page-title" class="faqs fyf">
+ <h1><img src="<?=$html->urlImage('fyf/faq_header.png')?>" alt="FAQs" /></a></h1>
+ </div>
+
+<?=$localization->includeLocalPage('fashion_faq')?>
+
+</div> <!-- END page -->
diff --git a/site/app/views/pages/js_constants.js.thtml b/site/app/views/pages/js_constants.js.thtml
new file mode 100644
index 0000000..aca2ea9
--- /dev/null
+++ b/site/app/views/pages/js_constants.js.thtml
@@ -0,0 +1,108 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Frederic Wenzel <fwenzel@mozilla.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+// Used for firefox version numbers
+vendor('product-details/firefoxDetails.class');
+
+/**
+ * Java Script Constants to be imported into javascript files
+ * to be used for things like paths, not isAdmin ;)
+ */
+header('Content-Type: application/x-javascript');
+$this->layout = null; // no layout!
+
+?>
+var BASEDIR = "<?=$html->url('/', null, false, false) ?>";
+var LANG = "<?=LANG?>";
+var APP_ID = "<?=APP_ID?>";
+var APP_SHORTNAME = "<?=APP_SHORTNAME?>";
+var APP_PRETTYNAME = "<?=APP_PRETTYNAME?>";
+var LATEST_FIREFOX_VERSION = '<?=LATEST_FIREFOX_VERSION?>';
+var LATEST_FIREFOX_DEVEL_VERSION = '<?=LATEST_FIREFOX_DEVEL_VERSION?>';
+var APP_FIREFOX = '<?=APP_FIREFOX?>';
+var APP_SEAMONKEY = '<?=APP_SEAMONKEY?>';
+var APP_THUNDERBIRD = '<?=APP_THUNDERBIRD?>';
+var APP_SUNBIRD = '<?=APP_SUNBIRD?>';
+var APP_FENNEC = '<?=APP_FENNEC?>';
+<?php /* generic constants */ ?>
+var KEYCODE_ENTER = 13;
+<?php
+$constants = array(
+ 'addOnNotAvailableForPlatform' => ___('addon_not_available_for_platform'),
+ 'error_opensearch_unsupported' => ___('addons_searchengines_error_mozilla_browser_required'),
+
+ /* Fallback from 3/19/08 */
+ 'app_compat_update_firefox' => ___('app_compat_update_firefox'),
+ 'app_compat_try_old_version' => ___('app_compat_try_old_version'),
+ 'app_compat_older_firefox_only' => ___('app_compat_older_firefox_only'),
+ 'app_compat_unreleased_version' => ___('app_compat_unreleased_version'),
+ 'app_compat_older_version_or_ignore_check' => ___('app_compat_older_version_or_ignore_check'),
+
+ /* developers.js */
+ 'devcp_js_upload_alert' => ___('devcp_js_upload_alert'),
+ 'addons_status_public' => ___('addons_status_public'),
+ 'addons_status_sandbox' => ___('addons_status_sandbox'),
+ 'addons_status_pending' => ___('addons_status_pending'),
+ 'devcp_js_img_move_down' => ___('devcp_js_img_move_down'),
+ 'devcp_js_img_move_up' => ___('devcp_js_img_move_up'),
+ 'devcp_js_option_owner' => ___('devcp_js_option_owner'),
+ 'devcp_js_option_developer' => ___('devcp_js_option_developer'),
+ 'devcp_js_option_viewer' => ___('devcp_js_option_viewer'),
+ 'devcp_js_input_list_author' => ___('devcp_js_input_list_author'),
+ 'devcp_js_sure_remove' => ___('devcp_js_sure_remove'),
+ 'devcp_js_remove_author' => ___('devcp_js_remove_author'),
+ 'devcp_js_a_cancel' => ___('devcp_js_a_cancel'),
+ 'devcp_js_add_email' => ___('devcp_js_add_email'),
+ 'devcp_js_img_remove_compat' => ___('devcp_js_img_remove_compat'),
+ 'devcp_js_license_select' => ___('devcp_js_license_select'),
+ 'devcp_js_license_text' => ___('devcp_js_license_text'),
+
+ /* Fallback from 4/14/08 */
+ 'app_compat_ignore_check' => ___('app_compat_ignore_check'),
+
+ // collections
+ 'collections_edit_submit' => ___('collections_edit_submit'),
+ 'collections_edit_submit_deletecollection' => ___('collections_edit_submit_deletecollection'),
+
+ /* addons display page */
+ 'addons_display_collection_publish_success' => ___('addons_display_collection_publish_success')
+);
+
+foreach ($constants as $var_name => $l10n_string) {
+ echo sprintf('var %s = "%s";'."\n", $var_name, addslashes($l10n_string));
+}
diff --git a/site/app/views/pages/policy.thtml b/site/app/views/pages/policy.thtml
new file mode 100644
index 0000000..23c93ca
--- /dev/null
+++ b/site/app/views/pages/policy.thtml
@@ -0,0 +1,53 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Frederic Wenzel <fwenzel@mozilla.com> (Original Author)
+ * Justin Scott <fligtar@gmail.com>
+ * Wil Clouser <wclouser@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+$this->layout = 'amo2009';
+?>
+
+<div class="secondary" role="complementary">
+ <?=$this->renderElement('amo2009/categories')?>
+</div>
+
+<div class="primary prose" role="main">
+ <?=$this->renderElement('amo2009/search')?>
+
+ <?=$localization->includeLocalPage('policy', array($html->link(_('pages_policy_sandbox_link'), '/pages/sandbox')))?>
+
+</div>
diff --git a/site/app/views/pages/privacy.thtml b/site/app/views/pages/privacy.thtml
new file mode 100644
index 0000000..23d072a
--- /dev/null
+++ b/site/app/views/pages/privacy.thtml
@@ -0,0 +1,53 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Frederic Wenzel <fwenzel@mozilla.com> (Original Author)
+ * Wil Clouser <wclouser@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+$this->layout = 'amo2009';
+?>
+
+<div class="secondary" role="complementary">
+ <?=$this->renderElement('amo2009/categories')?>
+</div>
+
+<div class="primary prose" role="main">
+ <?=$this->renderElement('amo2009/search')?>
+
+ <?=$localization->includeLocalPage('privacy')?>
+
+</div>
+
diff --git a/site/app/views/pages/review_guide.thtml b/site/app/views/pages/review_guide.thtml
new file mode 100644
index 0000000..8ddd885
--- /dev/null
+++ b/site/app/views/pages/review_guide.thtml
@@ -0,0 +1,53 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Frederic Wenzel <fwenzel@mozilla.com> (Original Author)
+ * Wil Clouser <wclouser@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+$this->layout = 'amo2009';
+?>
+
+<div class="secondary" role="complementary">
+ <?=$this->renderElement('amo2009/categories')?>
+</div>
+
+<div class="primary prose" role="main">
+ <?=$this->renderElement('amo2009/search')?>
+
+ <?=$localization->includeLocalPage('reviewguide')?>
+
+</div>
+
diff --git a/site/app/views/pages/robots.txt.thtml b/site/app/views/pages/robots.txt.thtml
new file mode 100644
index 0000000..29e090a
--- /dev/null
+++ b/site/app/views/pages/robots.txt.thtml
@@ -0,0 +1,66 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Frederic Wenzel <fwenzel@mozilla.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+$this->layout = null;
+header('Content-Type: text/plain');
+?>
+# robots.txt file for Mozilla Add-ons, addons.mozilla.org
+User-agent: *
+<?php
+/* default: allow access to all pages on prod, disallow on preview */
+if (!defined('SITE_STATE') || (SITE_STATE == 'production')):?>
+Allow: /
+<?php else: ?>
+Disallow: /
+<?php
+endif;
+
+global $supported_languages, $app_shortnames;
+foreach ($supported_languages as $lang => $loc) {
+ foreach ($app_shortnames as $app => $aid) {
+ /* block access to all user info pages, on all locales and apps */
+ echo "Disallow: ".$html->url("/{$lang}/{$app}/user/\n", true, false, false);
+ echo "Disallow: ".$html->url("/{$lang}/{$app}/users/info/\n", true, false, false);
+ echo "Disallow: ".$html->url("/{$lang}/{$app}/users/pwreset/\n", true, false, false);
+ /* do not index search */
+ echo "Disallow: ".$html->url("/{$lang}/{$app}/search/\n", true, false, false);
+ /* do not index share links */
+ echo "Disallow: ".$html->url("/{$lang}/{$app}/addon/share/\n", true, false, false);
+ }
+}
+?>
diff --git a/site/app/views/pages/sandbox.thtml b/site/app/views/pages/sandbox.thtml
new file mode 100644
index 0000000..734e8b6
--- /dev/null
+++ b/site/app/views/pages/sandbox.thtml
@@ -0,0 +1,53 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Frederic Wenzel <fwenzel@mozilla.com> (Original Author)
+ * Justin Scott <fligtar@gmail.com>
+ * Wil Clouser <wclouser@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+$this->layout = 'amo2009';
+?>
+
+<div class="secondary" role="complementary">
+ <?=$this->renderElement('amo2009/categories')?>
+</div>
+
+<div class="primary prose" role="main">
+ <?=$this->renderElement('amo2009/search')?>
+
+ <?=$localization->includeLocalPage('sandbox', array('<img src="'.$html->url('/images/localized_image/sandbox-review.png').'">'))?>
+
+</div>
diff --git a/site/app/views/pages/submissionhelp.thtml b/site/app/views/pages/submissionhelp.thtml
new file mode 100644
index 0000000..e615b0f
--- /dev/null
+++ b/site/app/views/pages/submissionhelp.thtml
@@ -0,0 +1,53 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Frederic Wenzel <fwenzel@mozilla.com> (Original Author)
+ * Justin Scott <fligtar@gmail.com>
+ * Wil Clouser <wclouser@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+$this->layout = 'amo2009';
+?>
+
+<div class="secondary" role="complementary">
+ <?=$this->renderElement('amo2009/categories')?>
+</div>
+
+<div class="primary prose" role="main">
+ <?=$this->renderElement('amo2009/search')?>
+
+ <?=$localization->includeLocalPage('submission_help', array($html->url('/pages/policy')))?>
+
+</div>
diff --git a/site/app/views/previews/add.thtml b/site/app/views/previews/add.thtml
new file mode 100644
index 0000000..6cfdb3f
--- /dev/null
+++ b/site/app/views/previews/add.thtml
@@ -0,0 +1,68 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * Justin Scott <fligtar@gmail.com>.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Frederic Wenzel <fwenzel@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+?>
+<div id="content">
+ <?=$this->renderElement('developers/myaddons', array('addons' => $all_addons));?>
+
+ <div id="content-main">
+ <h3><?=_('devcp_previews_header_add')?></h3>
+ <div class="addonName"><?=$addon['Translation']['name']['string']?></div>
+ <p><?=_('devcp_previews_filetype_info')?></p>
+ <?php
+ if (!empty($errors['main'])) {
+ echo '<div class="error">'.$errors['main'].'</div>';
+ }
+ echo $html->formTag('/previews/add/'.$id, 'post', array('enctype'=>'multipart/form-data'));
+ ?>
+ <div id="developersForm">
+ <div>
+ <label for="PreviewFile"><?=_('devcp_previews_label_file')?></label>
+ <?=$html->file('Preview/File')?>
+ </div>
+ <div>
+ <?=$html->checkbox('Preview/highlight', null, $highlightCheckbox)?>
+ <label for="PreviewHighlight" class="nofloat"><?=_('devcp_previews_label_makedefault')?></label>
+ </div>
+ <?=$this->renderElement('developers/localebox')?>
+ <div class="buttonBox">
+ <?=$html->submit(_('devcp_previews_submit_upload'))?>
+ </div>
+ </div> <!-- developersForm -->
+ </form>
+ </div> <!-- corner-box -->
+</div> <!-- content-right -->
diff --git a/site/app/views/previews/edit.thtml b/site/app/views/previews/edit.thtml
new file mode 100644
index 0000000..b02726b
--- /dev/null
+++ b/site/app/views/previews/edit.thtml
@@ -0,0 +1,60 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * Justin Scott <fligtar@gmail.com>.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Frederic Wenzel <fwenzel@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+?>
+<div id="content">
+ <?=$this->renderElement('developers/myaddons', array('addons' => $all_addons));?>
+
+ <div id="content-main">
+ <h3><?=_('devcp_previews_header_edit')?></h3>
+ <div class="addonName"><?=$addon['Translation']['name']['string']?></div>
+ <?=$html->formTag('/previews/edit/'.$id, 'post')?>
+ <div id="developersForm">
+ <img src="<?=$previewUrl?>">
+ <div>
+ <?=$html->checkbox('Preview/highlight', null, $highlightCheckbox)?>
+ <label for="PreviewHighlight" class="nofloat"><?=_('devcp_previews_label_makedefault')?></label>
+ </div>
+ <?=$this->renderElement('developers/localebox')?>
+ <div class="buttonBox">
+ <?=$html->submit(_('devcp_previews_submit_edit'))?>
+ <?=$html->submit(_('devcp_previews_submit_delete'), array('name' => 'delete', 'class' => 'cancel', 'onClick' => 'return confirm(\''._('devcp_previews_submit_delete_confirm').'\');'))?>
+ </div>
+ </div> <!-- developersForm -->
+ </form>
+ </div>
+</div>
diff --git a/site/app/views/reviews/add.thtml b/site/app/views/reviews/add.thtml
new file mode 100644
index 0000000..1e20e47
--- /dev/null
+++ b/site/app/views/reviews/add.thtml
@@ -0,0 +1,121 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Frederic Wenzel <fwenzel@mozilla.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+$this->viewVars['bodyclass'] = 'review_add';
+$this->layout = 'amo2009';
+?>
+<div class="secondary" role="complementary">
+ <?=$this->renderElement('amo2009/categories')?>
+</div>
+
+<div class="primary prose" role="main">
+ <?=$this->renderElement('amo2009/search')?>
+
+ <div id="content-main">
+
+<h2><?=sprintf((@$this->data['Review']['id'] > 0) ? _('addon_review_edit_title') : _('addon_review_add_title'), $addon['Translation']['name']['string']); ?></h2>
+<? $reviewRating = @$this->data['Review']['rating']; ?>
+<?php echo sprintf(___('review_guidelines_short'), $html->url("/addon/{$addon['Addon']['id']}#support"), $html->url('/pages/review_guide')); ?>
+
+<? // if this is a developer reply, show the original review
+if (!empty($reply_to)) {
+ echo "<p>"._('addon_review_in_reply_to')."</p>";
+ ?>
+ <div class="corner-box">
+ <h3><?=$reply_to['Translation']['title']['string']?></h3>
+
+ <div class="reviewed-on">
+ <?= sprintf(_('addon_reviewed_on_x_rated_y'), $html->linkUserFromModel($reply_to['User']), strftime(_('date'), strtotime($reply_to['Review']['created'])), $reply_to['Review']['rating'])?>
+ </div>
+ <?=nl2br($reply_to['Translation']['body']['string'])?>
+ </div>
+<? } ?>
+
+<? if (isset($errorMessage)):?>
+<div class="amo-form-error"><?= _('error_formerrors')?></div>
+<p></p>
+<? endif;?>
+
+<form action="<?=$html->entities($html->url())?>" method="post" class="amo-form corner-box" id="long-review">
+ <?=$html->hiddenSession() ?>
+ <?=$html->hidden('Review/id'); ?>
+ <div>
+ <label class="amo-label-large" for="ReviewTitle"><?=_('addon_review_add_title_field')?></label>
+ <?=$html->input('Review/title');?>
+ <?=$html->tagErrorMsg('Review/title', _('error_field_required'))?>
+ </div>
+ <? if (empty($reply_to)): ?>
+ <div>
+
+ <label class="amo-label-large rating" for="ReviewRating"><?=_('addon_review_add_rating_field')?></label>
+ <div class="stars degrade">
+ <p><input class="star" type="radio" name="data[Review][rating]" value="1" title="<?=_('addons_display_hate_it')?>"
+ <?php if($reviewRating == 1) { ?> checked="checked"<?php } ?>/> <?=_('addons_display_hate_it')?></p>
+ <p><input class="star" type="radio" name="data[Review][rating]" value="2" title="<?=_('addons_display_dont_like_it')?>"
+ <?php if($reviewRating == 2) { ?> checked="checked"<?php } ?>/> <?=_('addons_display_dont_like_it')?></p>
+ <p><input class="star" type="radio" name="data[Review][rating]" value="3" title="<?=_('addons_display_like_it')?>"
+ <?php if($reviewRating == 3) { ?> checked="checked"<?php } ?>/> <?=_('addons_display_like_it')?></p>
+ <p><input class="star" type="radio" name="data[Review][rating]" value="4" title="<?=_('addons_display_really_like_it')?>"
+ <?php if($reviewRating == 4) { ?> checked="checked"<?php } ?>/> <?=_('addons_display_really_like_it')?></p>
+ <p><input class="star" type="radio" name="data[Review][rating]" value="5" title="<?=_('addons_display_love_it')?>"
+ <?php if($reviewRating == 5) { ?> checked="checked"<?php } ?>/> <?=_('addons_display_love_it')?></p>
+ </div>
+ <?=$html->tagErrorMsg('Review/rating', _('error_review_rating_required'))?>
+ </div>
+ <? endif; ?>
+ <div>
+ <label class="amo-label-large" for="ReviewBody"><?=_('addon_review_add_review_field')?></label>
+ <?=$html->textarea('Review/body', array('cols'=>50, 'rows'=>5));?>
+ <?=$html->tagErrorMsg('Review/body', _('error_field_required'))?>
+ </div>
+ <p></p>
+ <?=$html->submit(_('addon_review_add_submit'), array('class'=>'amo-submit'))?>
+</form>
+
+<div class="divider"><hr></div>
+
+<ul>
+ <li><?= $html->link(sprintf(_('addon_review_a_back_to_reviews'), $addon['Translation']['name']['string']), '/reviews/display/'.$addon['Addon']['id']); ?></li>
+ <li><?= $html->link(sprintf(_('addon_review_a_back_to_addon_x'), $addon['Translation']['name']['string']), '/addon/'.$addon['Addon']['id']); ?></li>
+</ul>
+
+ </div>
+ </div>
+ <script type="text/javascript" charset="utf-8">
+ $(function(){ $('.stars').rating(); });
+ </script>
diff --git a/site/app/views/reviews/delete.thtml b/site/app/views/reviews/delete.thtml
new file mode 100644
index 0000000..89a2bf6
--- /dev/null
+++ b/site/app/views/reviews/delete.thtml
@@ -0,0 +1,68 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * Justin Scott <fligtar@gmail.com>.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Wil Clouser <clouserw@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+$this->layout = 'amo2009';
+?>
+
+<div class="secondary" role="complementary">
+ <?=$this->renderElement('amo2009/categories')?>
+</div>
+
+<div class="primary" role="main">
+ <?=$this->renderElement('amo2009/search')?>
+
+ <h2><?=_('addon_review_delete_header')?></h2><br>
+
+ <div class="article">
+ <h3><?=$html->link($review['Addon']['Translation']['name']['string'], '/addons/display/'.$review['Addon']['Addon']['id']).
+ ': '.$review['Translation']['title']['string']?></h3>
+ <div>
+ <?= sprintf(_('addon_reviewed_on_x_rated_y'), $html->linkUserFromModel($review['User']), strftime(_('date'), strtotime($review['Review']['created'])), $review['Review']['rating'])?>
+ </div>
+ <?=$review['Translation']['body']['string']?>
+
+ <?=$html->formTag("/reviews/delete/{$review['Review']['id']}")?>
+ </div>
+ <div class="item">
+ <div align="center">
+ <?=_('addon_review_confirm_delete')?><br>
+ <input type="submit" name="no" value="<?=_('addon_review_confirm_no')?>">
+ <input type="submit" name="yes" value="<?=_('addon_review_confirm_yes')?>">
+ </div>
+ </form>
+ </div>
+</div>
diff --git a/site/app/views/reviews/display.thtml b/site/app/views/reviews/display.thtml
new file mode 100644
index 0000000..200aac5
--- /dev/null
+++ b/site/app/views/reviews/display.thtml
@@ -0,0 +1,238 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Frederic Wenzel <fwenzel@mozilla.com> (Original Author)
+ * Wil Clouser <clouserw@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+if ($loggedin) {
+ $_review_flag_this = ___('review_flag_this', 'Report this review');
+ $_review_flag_this_titletip = ___('review_flag_this_titletip', 'Is this review inappropriate, inaccurate or spam? Click here to flag it for editor review.');
+}
+$bare = isset($_GET['bare']) ? ( $_GET['bare'] == 1 ) : FALSE;
+?>
+<?php if (!$bare): ?>
+<?php $this->layout = 'amo2009'; ?>
+<div class="secondary" role="complementary">
+ <?=$this->renderElement('amo2009/categories')?>
+</div>
+
+<div id="content-main" class="primary" role="main">
+ <?=$this->renderElement('amo2009/search')?>
+
+<h2><?=sprintf(_('reviews_header'), $addon['Translation']['name']['string']);?></h2>
+<?php else: ?>
+<div class="other-reviews">
+<?php endif ?>
+
+<?php
+foreach ($reviews as $review):
+ $review_id = $review['Review']['id'];
+ $review['Translation'] = (array_key_exists(LANG, $review['Translation']) ?
+ $review['Translation'][LANG] : current($review['Translation']));
+?>
+ <div class="item review" id="review-<?=$review['Review']['id']?>">
+ <h3><?=$review['Translation']['title']['string']?></h3>
+
+ <div class="reviewed-on">
+ <?=$this->renderElement('amo2009/stars',array('rating' => $review['Review']['rating']))?>
+ <?php
+ echo sprintf(___('addon_reviewed_by_u_on_d'),
+ $html->linkUserFromModel($review['User']),
+ strftime(_('date'), strtotime($review['Review']['created'])));
+ ?>
+ <?=($isAuthor || $isAdmin) ? '['.$html->link(_('addon_review_author_reply_link'), "/reviews/reply/{$review['Review']['id']}").']' : '' ?>
+ <?=($canDelete) ? '['.$html->link(_('addon_review_admin_delete'), "/reviews/delete/{$review['Review']['id']}").']' : ''?>
+
+ <?php /* Show either the review moderation form, or display a
+ thank you message if this user already has flagged this review. */ ?>
+ <?php if ($loggedin): ?>
+ <?php
+ $review_flag_name = isset($reviews_flagged[$review_id]) ?
+ $reviews_flagged[$review_id]['flag_name'] : '';
+ ?>
+ <?php if ($review_flag_name): ?>
+
+ <?php /* If there's already a flag for this review from this
+ user, re-display the thank you message without a flag
+ form. */ ?>
+ <p class="flag-thanks"><?php echo ___('review_flag_success',
+ 'Thanks; this review has been flagged for editor approval.') ?></p>
+
+ <?php else: ?>
+
+ <?php echo $html->formTag('/reviews/flag', 'post',
+ array('id' => "flag-{$review['Review']['id']}",
+ 'class' => 'flag')); ?>
+ <span class="reason">
+ <span class="error"></span>
+ <select id="data[ReviewsModerationFlag][flag_name]"
+ name="data[ReviewsModerationFlag][flag_name]">
+ <option value=""> - <?php echo _('review_flag_reason_instructions') ?> - </option>
+ <?php foreach ($review_flag_reasons as $reason=>$label): ?>
+ <option value="<?php echo $reason ?>"><?php echo $label ?></option>
+ <?php endforeach ?>
+ </select>
+ </span>
+ <?php
+ echo $html->hidden('Review/id',
+ array('value'=>$review_id, 'class'=>'ReviewId'));
+ echo $html->input('ReviewsModerationFlag/flag_notes',
+ array('type'=>'text', 'size'=>'50', 'maxsize'=>'100', 'value'=>'', 'class'=>'FlagNotes hide-with-js'));
+ echo $html->submit($_review_flag_this,
+ array('title'=>$_review_flag_this_titletip, 'class'=>'FlagSubmit hide-with-js'));
+ ?>
+ </form>
+
+ <?php endif; ?>
+ <?php endif; ?>
+
+ </div>
+ <?=nl2br($review['Translation']['body']['string'])?>
+
+ <?php if ($other_count = @($reviews_others_counts[$review['Review']['id']])): ?>
+ <?php /* Construct the link to reveal previous reviews by this user. */ ?>
+ <div class="others-by-user" id="others-by-user-<?=$review['Review']['id']?>">
+ <?php $r_user = $review['User'] ?>
+ <?=$html->link(
+ sprintf(
+ ngettext('addon_review_others_by_user',
+ 'addon_review_others_by_user', $other_count),
+ $other_count,
+ $r_user['nickname'] ? $r_user['nickname'] :
+ $r_user['firstname'] . ' ' . $r_user['lastname']
+ ),
+ '/reviews/display/'.$addon['Addon']['id'].'?user_id='.$review['User']['id']
+ ) ?>
+ </div>
+ <?php endif ?>
+
+ </div>
+
+ <? if ($other_count = @($reviews_others_counts[$review['Review']['id']])): ?>
+ <div class="others-by-user-load" id="others-by-user-load-<?=$review['Review']['id']?>">
+ </div>
+ <? endif ?>
+
+ <? // developer reply?
+ if (!empty($review['Review']['reply'])):
+ $reply = $review['Review']['reply'];
+ $reply['Translation'] = (array_key_exists(LANG, $reply['Translation']) ?
+ $reply['Translation'][LANG] : current($reply['Translation']));
+ $reply_id = $reply['Review']['id'];
+ ?>
+ <div class="review review-reply" id="review-<?=$reply['Review']['id']?>">
+ <h3><?=_('addon_review_reply_prefix') .' '. $reply['Translation']['title']['string']?></h3>
+
+ <div class="reviewed-on">
+ <?=sprintf(_('addon_review_reply_on_x_by_y'), $html->linkUserFromModel($reply['User']), strftime(_('date'), strtotime($reply['Review']['created']))) ?>
+ <?=($canDelete) ? '['.$html->link(_('addon_review_admin_delete'), "/reviews/delete/{$reply['Review']['id']}").']' : ''?>
+
+ <?php /* Show either the review moderation form, or display a
+ thank you message if this user already has flagged this review. */ ?>
+ <?php if ($loggedin): ?>
+ <?php
+ $review_flag_name = isset($reviews_flagged[$reply_id]) ?
+ $reviews_flagged[$reply_id]['flag_name'] : '';
+ ?>
+ <?php if ($review_flag_name): ?>
+
+ <?php /* If there's already a flag for this review from this
+ user, re-display the thank you message without a flag
+ form. */ ?>
+ <p class="flag-thanks"><?php echo ___('review_flag_success',
+ 'Thanks; this review has been flagged for editor approval.') ?></p>
+
+ <?php else: ?>
+
+ <?php echo $html->formTag('/reviews/flag', 'post',
+ array('id' => "flag-{$reply_id}", 'class' => 'flag')); ?>
+ <span class="reason">
+ <span class="error"></span>
+ <select id="data[ReviewsModerationFlag][flag_name]"
+ name="data[ReviewsModerationFlag][flag_name]">
+ <option value=""> - <?php echo _('review_flag_reason_instructions') ?> - </option>
+ <?php foreach ($review_flag_reasons as $reason=>$label): ?>
+ <option value="<?php echo $reason ?>"><?php echo $label ?></option>
+ <?php endforeach ?>
+ </select>
+ </span>
+ <?php
+ echo $html->hidden('Review/id',
+ array('value'=>$reply_id, 'class'=>'ReviewId'));
+ echo $html->input('ReviewsModerationFlag/flag_notes',
+ array('type'=>'text', 'size'=>'50', 'maxsize'=>'100', 'value'=>'', 'class'=>'FlagNotes hide-with-js'));
+ echo $html->submit($_review_flag_this,
+ array('title'=>$_review_flag_this_titletip, 'class'=>'FlagSubmit hide-with-js'));
+ ?>
+ </form>
+
+ <?php endif; ?>
+ <?php endif; ?>
+
+ </div>
+ <?=nl2br($reply['Translation']['body']['string'])?>
+ </div>
+ <? endif; ?>
+<? endforeach; ?>
+
+<?php if (!$bare): ?>
+<? if (!empty($reviews)) echo $this->renderElement('amo2009/pagination');?>
+<div class="clearboth"> <hr /> </div>
+
+<ul>
+ <li><?=$html->link(sprintf(_('addon_review_a_back_to_addon_x'), $addon['Translation']['name']['string']), '/addon/'.$addon['Addon']['id']); ?></li>
+ <?
+ if (empty($isAuthor)) {
+ if (!empty($hasreview)) {
+ $add_or_edit = _('addons_display_edit_review');
+ } else {
+ $add_or_edit = _('addons_display_add_review');
+ }
+ echo '<li>'.$html->link($add_or_edit, '/reviews/add/'.$addon['Addon']['id']).'</li>';
+ }
+ ?>
+</ul>
+
+<?php /* reviews javascript for ajax actions and the like */ ?>
+<script type="text/javascript">
+var flagurl = '<?=$html->url('/reviews/flag')?>';
+</script>
+<?php echo $javascript->link('reviews')."\n"; ?>
+ </div>
+</div>
+<?php else: ?>
+</div>
+<?php endif ?>
diff --git a/site/app/views/reviews/flag.thtml b/site/app/views/reviews/flag.thtml
new file mode 100644
index 0000000..3106ac3
--- /dev/null
+++ b/site/app/views/reviews/flag.thtml
@@ -0,0 +1,67 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Frederic Wenzel <fwenzel@mozilla.com> (Original Author)
+ * Wil Clouser <clouserw@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+if (!empty($ajaxreply)):
+ echo "<strong>{$msg}</strong>";
+else:
+ $this->layout = 'amo2009';
+?>
+<div class="secondary" role="complementary">
+ <?=$this->renderElement('amo2009/categories')?>
+</div>
+
+<div class="primary" role="main">
+ <?=$this->renderElement('amo2009/search')?>
+
+<?php if (empty($addon)): ?>
+ <?=$this->renderElement('notification', array('msg' => $msg));?>
+ <p><?=$html->link(_('link_return_to_front_page'), '/')?></p>
+<?php else: ?>
+ <h2><?=sprintf(_('reviews_header'), $addon['Translation']['name']['string']);?></h2>
+ <?=$this->renderElement('notification', array('msg' => $msg));?>
+
+ <ul>
+ <li><?= $html->link(sprintf(_('addon_review_a_back_to_reviews'), $addon['Translation']['name']['string']), '/reviews/display/'.$addon['Addon']['id']); ?></li>
+ <li><?=$html->link(sprintf(_('addon_review_a_back_to_addon_x'), $addon['Translation']['name']['string']), '/addon/'.$addon['Addon']['id']); ?></li>
+ </ul>
+<?php endif; // if addon found ?>
+
+ </div>
+</div>
+<?php endif; // if ajax ?>
diff --git a/site/app/views/reviews/review_added.thtml b/site/app/views/reviews/review_added.thtml
new file mode 100644
index 0000000..5b2e608
--- /dev/null
+++ b/site/app/views/reviews/review_added.thtml
@@ -0,0 +1,60 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Frederic Wenzel <fwenzel@mozilla.com> (Original Author)
+ * Wil Clouser <clouserw@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+$this->layout = 'amo2009';
+?>
+
+<div class="secondary" role="complementary">
+ <?=$this->renderElement('amo2009/categories')?>
+</div>
+
+<div class="primary" role="main">
+ <?=$this->renderElement('amo2009/search')?>
+
+ <h2><?=sprintf(_('reviews_header'), $addon['Translation']['name']['string']);?></h2>
+ <?=$this->renderElement('notification', array('type' => 'success', 'msg' => _('addon_review_saved_successfully')));?>
+ <? if (isset($moderated) && $moderated)
+ $this->renderElement('notification', array('type' => 'notification', 'msg' => _('addon_review_in_moderation'))); ?>
+
+<ul>
+ <li><?= $html->link(sprintf(_('addon_review_a_back_to_reviews'), $addon['Translation']['name']['string']), '/reviews/display/'.$addon['Addon']['id']); ?></li>
+ <li><?=$html->link(sprintf(_('addon_review_a_back_to_addon_x'), $addon['Translation']['name']['string']), '/addon/'.$addon['Addon']['id']); ?></li>
+</ul>
+
+</div>
diff --git a/site/app/views/reviews/rss/reviews.thtml b/site/app/views/reviews/rss/reviews.thtml
new file mode 100644
index 0000000..23959e8
--- /dev/null
+++ b/site/app/views/reviews/rss/reviews.thtml
@@ -0,0 +1,52 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Frederic Wenzel <fwenzel@mozilla.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+foreach ($reviews as $review) {
+ // display preferably the current language, or any present one otherwise
+ $review['Translation'] = (array_key_exists(LANG, $review['Translation']) ?
+ $review['Translation'][LANG] : current($review['Translation']));
+
+ echo $this->renderElement('rss_listitem', array(
+ 'title' => $review['Translation']['title']['string'],
+ 'url' => SITE_URL.$html->url("/reviews/display/{$addon['Addon']['id']}"),
+ 'description' => $review['Translation']['body']['string'],
+ 'author' => '',
+ 'pubDate' => $time->toRss($review['Review']['created'])
+ ));
+}
+?>
diff --git a/site/app/views/search/collections.thtml b/site/app/views/search/collections.thtml
new file mode 100644
index 0000000..9c27194
--- /dev/null
+++ b/site/app/views/search/collections.thtml
@@ -0,0 +1,82 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Jeff Balogh <jbalogh@mozilla.com>
+ * Frederic Wenzel <fwenzel@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+$this->viewVars['bodyclass'] = 'inverse';
+$this->layout = 'amo2009';
+?>
+
+<div class="section">
+ <div class="stand-alone-options">
+ <?=$this->renderElement('amo2009/categories')?>
+ <?=$this->renderElement('amo2009/search')?>
+ </div>
+ <div class="primary" role="main">
+ <?=$this->renderElement('amo2009/breadcrumbs')?>
+ <h2><?=___('search_collections_header', 'Collection Search Results')?></h2>
+ <div class="featured listing">
+ <div class="featured-inner">
+ <div class="listing-header">
+ <?=$this->renderElement('amo2009/collections_sort_form')?>
+ </div> <!-- listing-header -->
+ <script type="text/javascript">
+ <?=$this->renderElement('amo2009/collections_js_init')?>
+ </script>
+ <?php if (count($collections) === 0): ?>
+ <div class="item">
+ <p class="addon-search-message"><?=_('search_nothing_found')?></p>
+ </div>
+ <?php endif; ?>
+ <?php
+ $user = $this->controller->Session->read('User');
+ foreach ($collections as $collection) {
+ echo $this->renderElement('amo2009/collection_listing_item',
+ array('collection' => $collection,
+ 'user' => $user));
+ }
+ ?>
+ </div> <!-- featured-inner -->
+ <?php if (count($collections) > 0): ?>
+ <div class="listing-footer">
+ <?=$this->renderElement('amo2009/pagination');?>
+ </div>
+ <?php endif; ?>
+ </div> <!-- featured listing -->
+ </div> <!-- primary -->
+ <?=$this->renderElement('amo2009/collector_info_secondary')?>
+</div>
diff --git a/site/app/views/search/index.thtml b/site/app/views/search/index.thtml
new file mode 100644
index 0000000..619790d
--- /dev/null
+++ b/site/app/views/search/index.thtml
@@ -0,0 +1,75 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Frederic Wenzel <fwenzel@mozilla.com> (Original Author)
+ * Wil Clouser <wclouser@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+$this->viewVars['bodyclass'] = 'inverse';
+$this->layout = 'amo2009';
+
+?>
+<div class="section">
+ <div class="stand-alone-options">
+ <?=$this->renderElement('amo2009/categories')?>
+ <?=$this->renderElement('amo2009/search', array('query'=>$search_terms,
+ 'category'=>$category, 'appid'=>$appid, 'atype'=>$atype, 'lup'=>"$lup",
+ 'pid'=>$pid, 'sort'=>$sort, 'hver'=>$hver, 'lver'=>$lver, 'vfuz'=>$vfuz, 'pp'=>$pp))?>
+ </div>
+ <?php // TODO Remove style when new search design is implemented; bug 482857 ?>
+ <div class="primary" style="width:100%;">
+ <?=$this->renderElement('amo2009/breadcrumbs')?>
+
+ <div class="featured listing">
+ <div class="featured-inner">
+ <div class="listing-header">
+ <?php if (empty($search_results)): ?>
+ <p class="addon-search-message"><?=_('search_nothing_found')?></p>
+ <?php endif; ?>
+ </div> <!-- listing-header -->
+ <?php
+ foreach ($search_results as $var => $val) {
+ echo $this->renderElement('amo2009/homepage_addon', array('addon' => $val));
+ }
+ ?>
+ </div> <!-- featured-inner -->
+ <?php if (count($search_results) > 0): ?>
+ <div class="listing-footer">
+ <?=$this->renderElement('amo2009/pagination');?>
+ </div>
+ <?php endif; ?>
+ </div> <!-- featured listing -->
+ </div> <!-- primary -->
+</div><!-- /#section -->
diff --git a/site/app/views/search/rss/index.thtml b/site/app/views/search/rss/index.thtml
new file mode 100644
index 0000000..25c6fa8
--- /dev/null
+++ b/site/app/views/search/rss/index.thtml
@@ -0,0 +1,26 @@
+<?php
+foreach ($search_results as $var => $val):
+ // prepare version string
+ if (!empty($val['Version']))
+ $version = $val['Version'][0]['version'] .' - '. strftime(_('date'), strtotime($val['Version'][0]['created']));
+ else
+ $version = '';
+
+ // prepare absolute url of addons
+ $absurl = 'http'.(!empty($_SERVER['HTTPS'])?'s':'').'://'.$_SERVER['SERVER_NAME'].$html->url('/addon/'.$val['Addon']['id']);
+
+ // prepare publication timestamp
+ $pubdate = (!empty($val['Version'])) ? $time->toRss($val['Version']['0']['created']) : '';
+?>
+
+<item>
+ <title><?=$val['Translation']['name']['string'].' '.$version ?></title>
+ <link><?=$absurl ?></link>
+ <description><?=$this->controller->Sanitize->html($val['Translation']['summary']['string'])?></description>
+ <author><?=$val['User'][0]['firstname'].' '.$val['User'][0]['lastname']?></author>
+ <pubDate><?=$pubdate ?></pubDate>
+</item>
+
+<?php
+endforeach;
+?>
diff --git a/site/app/views/sharing_api/addon.thtml b/site/app/views/sharing_api/addon.thtml
new file mode 100644
index 0000000..3a94172
--- /dev/null
+++ b/site/app/views/sharing_api/addon.thtml
@@ -0,0 +1,134 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Laura Thomson <lthomson@mozilla.com> (Original Author)
+ * l.m.orchard <lorchard@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+if (empty($addonIconPath)) {
+ $addonIconPath = ($addon['addontype_id'] == ADDON_THEME ? $html->urlImage(DEFAULT_THEME_ICON) : $html->urlImage(DEFAULT_ADDON_ICON));
+}
+?>
+
+<addon<?php if (isset($base_url)): ?> xml:base="<?php echo $base_url ?>"<?php else: ?> href="<?php echo 'addons/'.rawurlencode($addon['guid']) ?>/"<?php endif ?>>
+ <meta>
+ <added><?php echo $addon['collection_added'] ?></added>
+ <addedby><?php echo $addon['collection_addedby'] ?></addedby>
+ <comments><?php echo $addon['collection_comments'] ?></comments>
+ <?php if (isset($base_url)): ?><collection href=".." /><?php endif ?>
+ </meta>
+ <categories>
+ <?php foreach ($addon['tags'] as $tag): ?>
+ <category id="<?php echo $tag['id'] ?>"><?php echo $tag['name'] ?></category>
+ <?php endforeach ?>
+ </categories>
+ <name><?php echo $addon['name']; ?></name>
+ <type id='<?php echo $addon['addontype_id']; ?>'><?php echo $addon['addontype_name']; ?></type>
+ <guid><?php echo $addon['guid']; ?></guid>
+ <version><?php echo $addon['install_version']; ?></version>
+ <status id='<?php echo $addon['status']; ?>'><?php
+ if ($addon['status'] == STATUS_PUBLIC) {
+ echo rtrim(_('a_header_public'));
+ } else {
+ echo rtrim(_('a_header_sandbox'));
+ }
+ ?></status>
+ <authors>
+<?php
+ foreach ($addon['users'] as $author) {
+ $authorName = (!empty($author['nickname'])) ? $author['nickname'] : $author['firstname'].' '.$author['lastname'];
+?>
+ <author><?php echo $authorName; ?></author>
+<?php
+ }
+?> </authors>
+ <summary><?php echo $addon['summary']; ?></summary>
+ <description><?php echo $addon['description']; ?></description>
+ <icon><?php
+ if ($addon['icon']) {
+ echo SITE_URL.$addon['icon'];
+ } else {
+ $addonIconPath = ($addon['addontype_id'] == ADDON_THEME ? $html->urlImage(DEFAULT_THEME_ICON) : $html->urlImage(DEFAULT_ADDON_ICON));
+ echo SITE_URL.$addonIconPath;
+ }
+ ?></icon>
+ <compatible_applications>
+ <?php
+ foreach ($addon['compatible_apps'] as $app) {
+ ?>
+ <application>
+ <name><?php echo $app['name']; ?></name>
+ <application_id><?php echo $app['id']; ?></application_id>
+ <min_version><?php echo $app['min_version']; ?></min_version>
+ <max_version><?php echo $app['max_version']; ?></max_version>
+<?php
+ if ($api_version > 1) { ?>
+ <appID><?php echo $app['guid']; ?></appID>
+ <?php } ?>
+ </application>
+ <?php
+ }
+?> </compatible_applications>
+<?php if ($api_version >0 ) { ?>
+ <all_compatible_os>
+ <?php foreach ($addon['all_compatible_os'] as $os) {
+ ?><os><?php echo $os ?></os>
+ <?php } ?>
+ </all_compatible_os>
+ <?php } ?>
+ <eula><?php echo $addon['eula'];?></eula>
+ <thumbnail><?php echo SITE_URL.$addon['thumbnail']; ?></thumbnail>
+ <rating><?php
+ $rating ='';
+ if (isset($addon['averagerating'])) {
+ $rating = $addon['averagerating'];
+ if ($api_version < 1) {
+ // we need to double the rating since the addons mgr expects it to
+ // be out of 10 and we have halved everything in the db
+ $rating *= 2;
+ }
+ // round rating to match stars in AMO
+ $rating = ceil($rating);
+ }
+ echo $rating;
+ ?></rating>
+ <learnmore><?php echo SITE_URL."/addon/{$addon['id']}?src=sharingapi"; ?></learnmore>
+<?php if ($api_version > 0 ) {
+ foreach($addon['fileinfo'] as $file) {?>
+ <install hash='<?php echo $file['hash']; ?>' os='<?php echo $file['os']; ?>'><?php
+ echo SITE_URL.$html->urlFile($file['id'], $file['filename'], $collection_uuid).'&amp;src=sharingapi'; ?></install>
+ <?php }
+} ?>
+</addon>
diff --git a/site/app/views/sharing_api/auth_token.thtml b/site/app/views/sharing_api/auth_token.thtml
new file mode 100644
index 0000000..fdc306b
--- /dev/null
+++ b/site/app/views/sharing_api/auth_token.thtml
@@ -0,0 +1,42 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * l.m.orchard <lorchard@mozilla.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+?>
+
+<token xmlns="http://addons.mozilla.org/"
+ value="<?php echo $value ?>"
+ href="<?php echo $url ?>" />
diff --git a/site/app/views/sharing_api/collection_detail.thtml b/site/app/views/sharing_api/collection_detail.thtml
new file mode 100644
index 0000000..3b09167
--- /dev/null
+++ b/site/app/views/sharing_api/collection_detail.thtml
@@ -0,0 +1,68 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * l.m.orchard <lorchard@mozilla.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+$c = array_pop($collections);
+?>
+
+<collection xmlns="http://addons.mozilla.org/"
+ xml:base="<?php echo $base_url ?>"
+ name="<?php echo $c['name'] ?>"
+ icon="<?php echo $c['icon'] ?>"
+ type="<?php echo $c['type'] ?>"
+ description="<?php echo $c['description'] ?>"
+ app="<?php echo $c['app']?>"
+ creator="<?php echo $c['creator'] ?>"
+ listed="<?php echo $c['listed'] ?>" writable="<?php echo $c['writable'] ?>" subscribed="<?php echo $c['subscribed'] ?>"
+ lastmodified="<?php echo $c['lastmodified'] ?>">
+
+ <links xml:base="<?php echo $site_base_url ?>">
+ <link id="view" href="<?php echo 'collections/view/' . $c['uuid'] ?>" />
+ <link id="subscribe" href="<?php echo 'collections/subscribe/' . $c['uuid'] ?>" />
+ <link id="unsubscribe" href="<?php echo 'collections/unsubscribe/' . $c['uuid'] ?>" />
+ </links>
+
+ <addons href="addons/">
+ <?php unset($base_url); ?>
+ <?php if (!empty($c['addons'])) foreach ($c['addons'] as $addon): ?>
+
+ <?php include 'addon.thtml'; ?>
+ <?php endforeach ?>
+
+ </addons>
+
+</collection>
diff --git a/site/app/views/sharing_api/collections.thtml b/site/app/views/sharing_api/collections.thtml
new file mode 100644
index 0000000..1334d53
--- /dev/null
+++ b/site/app/views/sharing_api/collections.thtml
@@ -0,0 +1,61 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * l.m.orchard <lorchard@mozilla.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+?>
+
+<collections xmlns="http://addons.mozilla.org/"
+ xml:base="<?php echo $base_url ?>">
+ <?php foreach($collections as $c): ?>
+
+ <collection href="<?php echo $c['uuid'] ?>"
+ name="<?php echo $c['name'] ?>"
+ icon="<?php echo $c['icon'] ?>"
+ type="<?php echo $c['type'] ?>"
+ description="<?php echo $c['description'] ?>"
+ app="<?php echo $c['app']?>"
+ creator="<?php echo $c['creator'] ?>"
+ listed="<?php echo $c['listed'] ?>" writable="<?php echo $c['writable'] ?>" subscribed="<?php echo $c['subscribed'] ?>"
+ lastmodified="<?php echo $c['lastmodified'] ?>">
+ <links xml:base="<?php echo $site_base_url ?>">
+ <link id="view" href="<?php echo 'collections/view/' . $c['uuid'] ?>" />
+ <link id="subscribe" href="<?php echo 'collections/subscribe/' . $c['uuid'] ?>" />
+ <link id="unsubscribe" href="<?php echo 'collections/unsubscribe/' . $c['uuid'] ?>" />
+ </links>
+ </collection>
+ <?php endforeach ?>
+
+</collections>
diff --git a/site/app/views/sharing_api/email/recommend_email_plain.thtml b/site/app/views/sharing_api/email/recommend_email_plain.thtml
new file mode 100644
index 0000000..ab161b9
--- /dev/null
+++ b/site/app/views/sharing_api/email/recommend_email_plain.thtml
@@ -0,0 +1,23 @@
+<?php
+$recommendation_url = 'https://addons.mozilla.org'.$html->url('/addon/'.$addon['Addon']['id']);
+
+?>
+<?=$senderemail?> wants you to know about the <?=$addon['Translation']['name']['string']?> add-on for Mozilla Firefox.
+
+<?php if (!empty($message)): ?>
+Comments from sender: <?=$message?>
+
+<?php endif; ?>
+
+Information about <?=$addon['Translation']['name']['string']?>:
+<?=$addon['Translation']['summary']['string']?>
+
+<?=$recommendation_url?>
+
+---
+
+Add-ons are third party enhancements to Firefox that add new features or modify existing functionality. You can learn more about add-ons at the Firefox Add-ons website: https://addons.mozilla.org .
+
+---
+
+Sent by Firefox Add-ons on behalf of <?=$senderemail?>
diff --git a/site/app/views/sharing_api/empty.thtml b/site/app/views/sharing_api/empty.thtml
new file mode 100644
index 0000000..920b133
--- /dev/null
+++ b/site/app/views/sharing_api/empty.thtml
@@ -0,0 +1,40 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * l.m.orchard <lorchard@mozilla.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* This space left intentionally blank: */
+?>
diff --git a/site/app/views/sharing_api/error.thtml b/site/app/views/sharing_api/error.thtml
new file mode 100644
index 0000000..c3870b2
--- /dev/null
+++ b/site/app/views/sharing_api/error.thtml
@@ -0,0 +1,44 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * l.m.orchard <lorchard@mozilla.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+?>
+
+<error xmlns="http://addons.mozilla.org/"
+ reason="<?php echo $reason ?>"
+ <?php if (isset($details)): ?>details="<?php echo $details ?>"<?php endif ?>
+ <?php if (isset($href)): ?>href="<?php echo $href ?>"<?php endif ?>
+/>
diff --git a/site/app/views/sharing_api/options.thtml b/site/app/views/sharing_api/options.thtml
new file mode 100644
index 0000000..39008b6
--- /dev/null
+++ b/site/app/views/sharing_api/options.thtml
@@ -0,0 +1,40 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * l.m.orchard <lorchard@mozilla.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+?>
+
+<options xmlns="http://addons.mozilla.org/" methods="<?php echo join(', ', $methods) ?>" />
diff --git a/site/app/views/sharing_api/service_doc.thtml b/site/app/views/sharing_api/service_doc.thtml
new file mode 100644
index 0000000..9537463
--- /dev/null
+++ b/site/app/views/sharing_api/service_doc.thtml
@@ -0,0 +1,66 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * l.m.orchard <lorchard@mozilla.com> (Original Author)
+ * Frederic Wenzel <fwenzel@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+?>
+
+<sharing xmlns="http://addons.mozilla.org/" xml:base="<?php echo $base_url ?>">
+ <email href="email" />
+ <collections href="collections/">
+ <?php foreach($collections as $c): ?>
+
+ <collection
+ href="collections/<?php echo $c['uuid'] ?>/"
+ name="<?php echo $c['name'] ?>"
+ icon="<?php echo $c['icon'] ?>"
+ type="<?php echo $c['type'] ?>"
+ description="<?php echo $c['description'] ?>"
+ app="<?php echo $c['app']?>"
+ creator="<?php echo $c['creator'] ?>"
+ listed="<?php echo $c['listed'] ?>" writable="<?php echo $c['writable'] ?>" subscribed="<?php echo $c['subscribed'] ?>"
+ lastmodified="<?php echo $c['lastmodified'] ?>">
+ <links xml:base="<?php echo $site_base_url ?>">
+ <link id="view" href="<?php echo 'collections/view/' . $c['uuid'] ?>" />
+ <link id="subscribe" href="<?php echo 'collections/subscribe/' . $c['uuid'] ?>" />
+ <link id="unsubscribe" href="<?php echo 'collections/unsubscribe/' . $c['uuid'] ?>" />
+ </links>
+ <addons href="collections/<?php echo $c['uuid'] ?>/addons/" />
+ </collection>
+ <?php endforeach ?>
+
+ </collections>
+</sharing>
diff --git a/site/app/views/statistics/addon.thtml b/site/app/views/statistics/addon.thtml
new file mode 100644
index 0000000..f05abad
--- /dev/null
+++ b/site/app/views/statistics/addon.thtml
@@ -0,0 +1,271 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Justin Scott <fligtar@mozilla.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+echo '<div id="content">';
+ if ($this->controller->Config->getValue('stats_updating')) {
+ echo '<div class="warning"><div>'._('statistics_notice_data_updating').'</div></div>';
+ }
+ if (isset($_GET['settings'])) {
+ echo '<div class="notice-updated">'._('statistics_notice_settings_updated').'</div>';
+ }
+?>
+ <div class="article">
+ <div class="bluebox-tr"><div class="bluebox-tl">
+ <div id="statistics-header">
+ <div id="statistics-controls">
+ <?php
+ if (!empty($all_addons)) {
+ echo _('statistics_addon_switch').':';
+ echo $html->selectTag('Addon/id', $all_addons, $addon_id, array('onChange' => 'changeAddon(this);'), null, false).'<br>';
+ }
+ ?>
+ <span id="statistics-links">
+ <?=$html->link(_('statistics_addon_developertools_link'), '/developers')?> |
+ <?=$html->link(_('statistics_addon_dashboard_link'), '/statistics')?> |
+ <a href="#" onclick="$('#helpbox').toggle(); return false;"><?=_('statistics_help_link')?></a>
+ </span>
+ </div>
+ <div>
+ <img id="addon-icon" src="<?=$addonIcon?>" alt="<?=$addon_name?> Icon">
+ <h3 id="addon-title"><?=sprintf(_('statistics_title_addon_stats'), $addon_name)?></h3>
+ </div>
+ </div>
+
+ <div id="helpbox" style="display: none;">
+ <?=$localization->includeLocalPage('statistics_help')?>
+ <a href="#" onclick="$('#helpbox').hide(); return false;"><?=_('statistics_help_close_link')?></a>
+ </div>
+
+ <?php if ($stats['totaldownloads'] > 0): ?>
+ <div id="plot-options" style="display: none;">
+ <div id="plot-selector-area"></div>
+ <div id="plot-selection">
+ <div id="weeks-legend">
+ <div class="plot-legend">
+ <div class="colorbox" style="background-color: #CC6666;"></div>
+ <div id="week1-selection" class="plot-name"><select class="template">
+ <option>--</option>
+ </select></div>
+ </div>
+ <div class="plot-legend">
+ <div class="colorbox" style="background-color: #6666CC;"></div>
+ <div id="week2-selection" class="plot-name"><select class="template">
+ <option>--</option>
+ </select></div>
+ </div>
+ </div>
+ <div id="summary-legend">
+ <div class="plot-legend">
+ <div class="colorbox" style="background-color: #33AAFF;"></div>
+ <div class="plot-name"><?=_('statistics_plot_legend_downloads')?></div>
+ </div>
+ <div class="plot-legend">
+ <div class="colorbox" style="background-color: #EE3322;"></div>
+ <div class="plot-name"><?=_('statistics_plot_legend_adu')?></div>
+ </div>
+ </div>
+ </div>
+ <div id="options-area">
+ <?=$html->image('stats/cog.png', array('id' => 'options-cog', 'style' => 'display: none;', 'alt' => ''));?>
+ <div id="summary-options">
+ <div id="zoom-in" class="zoom-button" onclick="Plots.summary.zoomIn();" title="<?=_('statistics_plot_options_zoomin_title')?>">
+ <?=$html->image('stats/zoom_in.png', array('alt' => _('statistics_plot_options_zoomin_alt')))?>
+ </div>
+ <div id="zoom-out" class="zoom-button" onclick="Plots.summary.zoomOut();" title="<?=_('statistics_plot_options_zoomout_title')?>">
+ <?=$html->image('stats/zoom_out.png', array('alt' => _('statistics_plot_options_zoomout_alt')))?>
+ </div>
+ </div>
+ </div>
+ </div>
+
+ <div id="timeplot-container">
+ <div id="not-enough-data" class="warning" style="display: none;"><div>
+ <?=_('statistics_notice_data_insufficient')?>
+ </div></div>
+
+ <noscript>
+ <div class="warning"><div>
+ <?=_('statistics_notice_nojavascript')?>
+ </div></div>
+ </noscript>
+ </div>
+
+ <?php elseif (!$this->controller->Config->getValue('stats_disabled')): ?>
+ <div class="warning"><div>
+ <?=_('statistics_notice_data_none')?>
+ </div></div>
+ <?php endif; ?>
+
+ <?php if ($this->controller->Config->getValue('stats_disabled')): ?>
+ <div class="warning"><div>
+ <?=_('statistics_notice_disabled')?>
+ </div></div>
+ <?php endif; ?>
+
+ <div class="bluebox-br"><div class="bluebox-bl"></div></div>
+ </div></div></div>
+
+<br />
+
+<?php if (!$this->controller->Config->getValue('stats_disabled') || $this->controller->SimpleAcl->actionAllowed('*', '*', $this->controller->Session->read('User'))): ?>
+<div class="greenbox-tr"><div class="greenbox-tl">
+ <div id="stats-table-container">
+ <table width="100%" cellpadding="5" id="stats_overview">
+ <tr>
+ <td class="biglabel" valign="middle" style="width: 30%;">
+ <?=_('statistics_summary_downloads_total')?>
+ <div class="date"><?=sprintf(_('statistics_summary_downloads_total_sincedate'), strftime(_('statistics_date_shortmonthwithyear'), strtotime($addon['Addon']['created'])))?></div>
+ </td>
+ <td class="bigvalue" style="width: 19%;"><?=$statistics->number_format($stats, 'totaldownloads')?></td>
+ <td class="spacer" style="width: 2%;"></td>
+ <td class="biglabel" valign="middle" style="width: 30%;">
+ <?=_('statistics_summary_updatepings_total')?>
+ <div class="date">
+ <?php
+ if (!empty($stats['last_updatepings_date']))
+ echo sprintf(_('statistics_summary_updatepings_total_ondate'), strftime(_('statistics_date_weekdayshortmonth'), strtotime($stats['last_updatepings_date'])));
+ else
+ echo _('statistics_summary_nodata');
+ ?>
+ </div>
+ </td>
+ <td class="bigvalue" style="width: 19%;"><?=$statistics->number_format($stats, 'last_updatepings')?></td>
+ </tr>
+ <tr>
+ <td class="label">
+ <?=_('statistics_summary_downloads_lastcount')?>
+ <div class="date"><?=(!empty($stats['last_downloads_date']) ? strftime(_('statistics_date_weekdayshortmonth'), strtotime($stats['last_downloads_date'])) : '')?></div>
+ </td>
+ <td class="value"><?=$statistics->number_format($stats, 'last_downloads')?></td>
+ <td class="spacer"></td>
+ <td class="label">
+ <?=_('statistics_summary_updatepings_changefromprevious')?>
+ <div class="date">
+ <?php
+ if (!empty($stats['previous_updatepings']))
+ echo sprintf(_('statistics_summary_updatepings_changefromprevious_ondate'), $html->number_format($stats['previous_updatepings'], 0), strftime(_('statistics_date_shortmonth'), strtotime($stats['previous_updatepings_date'])));
+ else
+ echo _('statistics_summary_nodata');
+ ?>
+ </div>
+ </td>
+ <td class="value">
+ <?=$statistics->colored_percentage($stats, 'updateping_change')?>
+ </td>
+ </tr>
+ <tr>
+ <td class="label"><?=_('statistics_summary_downloads_average')?></td>
+ <td class="value"><?=$statistics->number_format($stats, 'avg_downloads')?></td>
+ <td class="spacer"></td>
+ <td class="label"><?=_('statistics_summary_updatepings_average')?></td>
+ <td class="value"><?=$statistics->number_format($stats, 'avg_updatepings')?></td>
+ </tr>
+ <tr>
+ <td class="label"><?=_('statistics_summary_downloads_lastweek')?></td>
+ <td class="value"><?=$statistics->number_format($stats, 'weeklydownloads')?></td>
+ <td class="spacer"></td>
+ <td class="label">
+ <?=___('statistics_summary_updatepings_weekly_average')?>
+ <div class="date">
+ <?=sprintf(___('statistics_summary_updatepings_weekly_change'),
+ $statistics->colored_percentage($stats, 'weekly_updatepings_change'))
+ ?>
+ </div>
+ </td>
+ <td class="value">
+ <?=$statistics->number_format($stats, 'weekly_updatepings')?>
+ </td>
+ </tr>
+ </table>
+ </div>
+ <div class="greenbox-br"><div class="greenbox-bl"></div></div>
+</div></div>
+<?php endif; ?>
+
+<div id="stats-table">
+
+ <a href="#" class="download"><? echo ___('statistics_js_download_csv', 'View this table in CSV format') ?></a>
+
+ <table class="template">
+ <thead>
+ <tr class="header">
+ <th>--</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr class="row">
+ <td class="col"></td>
+ </tr>
+ </tbody>
+ </table>
+</div>
+
+ <div id="settings">
+ <?php
+ if ($addon['Addon']['publicstats'] == 1) {
+ echo _('statistics_settings_currently_public');
+ echo '&nbsp;'.$html->image('stats/lock_open.png', array('alt' => _('statistics_settings_unlocked_alt')));
+ }
+ else {
+ echo _('statistics_settings_currently_private');
+ echo '&nbsp;'.$html->image('stats/lock.png', array('alt' => _('statistics_settings_locked_alt')));
+ }
+
+ echo '<br>';
+ if ($this->controller->Amo->checkOwnership($addon_id, null, true))
+ echo $html->link(_('statistics_settings_change_link'), '/statistics/settings/'.$addon_id);
+ elseif ($addon['Addon']['publicstats'] != 1)
+ echo '<span class="confidential">'._('statistics_settings_confidential').'</span>';
+ ?>
+ </div>
+
+</div>
+<script type="text/javascript">
+ var addonID = '<?=$addon_id?>';
+ var addonName = '<?=$addon_name?>';
+ var statsURL = '<?=$html->url('/statistics/')?>';
+
+ <?php if ($stats['totaldownloads'] > 0): ?>
+ $(document).ready(function() {
+ $('#plot-options').show();
+ plotSelection.loadSummary();
+ plotSelection.addPlotSelector();
+ plotSelection.addGroupBySelector();
+ });
+ <?php endif; ?>
+</script>
diff --git a/site/app/views/statistics/csv.thtml b/site/app/views/statistics/csv.thtml
new file mode 100644
index 0000000..57a6fc4
--- /dev/null
+++ b/site/app/views/statistics/csv.thtml
@@ -0,0 +1,23 @@
+<?php
+if (!defined('NO_MICROTIME'))
+ define('NO_MICROTIME', true);
+header('Content-type: text/plain');
+
+echo "# addons.mozilla.org Statistics for add-on {$addon_id}\n";
+echo "#\n";
+echo "# Generated ".date('r')."\n";
+echo "# from ".SITE_URL.$html->url("/statistics/csv/{$addon_id}/{$plot}")."\n";
+echo "#\n";
+echo "# This data is provided \"AS IS\" and is subject to Mozilla's Legal Disclaimers\n";
+echo "# and Limitations policy, available at http://www.mozilla.com/en-US/about/legal.html.\n";
+echo "#\n";
+
+if (!empty($csv)) {
+ $heading = implode(array_keys($csv[0]), ';');
+ echo "# Fields: [{$heading}]";
+ foreach ($csv as $values) {
+ echo "\n".implode($values, ',');
+ }
+}
+
+?> \ No newline at end of file
diff --git a/site/app/views/statistics/index.thtml b/site/app/views/statistics/index.thtml
new file mode 100644
index 0000000..5b40a4d
--- /dev/null
+++ b/site/app/views/statistics/index.thtml
@@ -0,0 +1,103 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Justin Scott <fligtar@mozilla.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+echo '<h1>'._('statistics_index_title').'</h1>';
+
+echo '<div class="secondary" role="complementary">';
+ echo $this->renderElement('developers/myaddons', array('addons' => $addons));
+echo '</div>';
+
+echo '<div class="primary">';
+
+ echo '<div id="content-main" class="article">';
+ echo '<h4>Current Review Queue Stats:</h4>';
+ echo '<ul>';
+ echo '<li>'.$dailyStats['nomination'].' add-ons currently nominated to become public</li>';
+ echo '<li>'.$dailyStats['pending'].' files currently pending review</li>';
+ echo '<li>'.$dailyStats['flagged'].' add-ons flagged for admin review</li>';
+ echo '<li>'.$dailyStats['reviews'].' user reviews currently flagged</li>';
+ echo '</ul>';
+
+ echo '<h4>Daily Totals for '.$dailyStats['after'].' thru '.$dailyStats['before'].':</h4>';
+ echo '<ul>';
+ echo '<li>'.$dailyStats['dailyAddons'].' new add-ons ('.$dailyStats['totalAddons'].' total)</li>';
+ echo '<li>'.$dailyStats['dailyVersions'].' new add-on versions</li>';
+ echo '<li>'.$dailyStats['dailyUsers'].' new user accounts total</li>';
+ echo '<li>'.$dailyStats['dailyReviews'].' new user reviews</li>';
+ echo '<li>'.$dailyStats['dailyImages'].' new preview images</li>';
+ echo '<li>'.$dailyStats['dailyDownloads'].' add-on downloads yesterday</li>';
+ echo '</ul>';
+ echo '</div>';
+
+ echo '<h3>Add-on statistics</h3>';
+ echo '<div class="featured prose">';
+ echo '<div class="featured-inner article">';
+ if (!empty($addons)) {
+ echo '<p>'._('statistics_index_myaddons').':</p>';
+ echo '<ul>';
+ foreach ($addons as $id => $addon) {
+ echo '<li>'.$html->link($addon, '/statistics/addon/'.$id).'</li>';
+ }
+ echo '</ul>';
+ }
+
+ if (!empty($otherAddons)) {
+ echo '<p>';
+ if (!empty($addons)) {
+ if ($this->controller->SimpleAcl->actionAllowed('Admin', 'ViewAnyStats', $this->controller->Session->read('User')))
+ echo _('statistics_index_anotheraddon').':';
+ else
+ echo _('statistics_index_anotheraddon_public').':';
+ }
+ else {
+ if ($this->controller->SimpleAcl->actionAllowed('Admin', 'ViewAnyStats', $this->controller->Session->read('User')))
+ echo _('statistics_index_selectaddon').':';
+ else
+ echo _('statistics_index_selectaddon_public').':';
+ }
+ echo '</p>';
+
+ echo $html->formTag('/statistics/', 'get');
+ echo $html->selectTag('Addon/id', $otherAddons, null, array('onChange' => 'changeAddon(this);'));
+ echo '<noscript><input type="submit" value="'._('statistics_index_view_button').'"></noscript>';
+ echo '</form>';
+ }
+ echo '</div>';
+ echo '</div>';
+ ?>
+ </div>
diff --git a/site/app/views/statistics/json.thtml b/site/app/views/statistics/json.thtml
new file mode 100644
index 0000000..c8d9312
--- /dev/null
+++ b/site/app/views/statistics/json.thtml
@@ -0,0 +1,7 @@
+<?php
+if (!defined('NO_MICROTIME'))
+ define('NO_MICROTIME', true);
+header('Content-type: text/plain');
+
+$listing->json($json);
+?> \ No newline at end of file
diff --git a/site/app/views/statistics/rss/summary.thtml b/site/app/views/statistics/rss/summary.thtml
new file mode 100644
index 0000000..ffb278c
--- /dev/null
+++ b/site/app/views/statistics/rss/summary.thtml
@@ -0,0 +1,76 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Justin Scott <fligtar@mozilla.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+$summary = '<b>'._('statistics_summary_downloads_heading').'</b><br />';
+$summary .= _('statistics_summary_downloads_total').' ('.sprintf(_('statistics_summary_downloads_total_sincedate'), strftime(_('statistics_date_shortmonthwithyear'), strtotime($addon['Addon']['created']))).'): '.$statistics->number_format($stats, 'totaldownloads').'<br />';
+$summary .= _('statistics_summary_downloads_lastcount').(!empty($stats['last_downloads_date']) ? ' ('.strftime(_('statistics_date_weekdayshortmonth'), strtotime($stats['last_downloads_date'])).')' : '').': '.$statistics->number_format($stats, 'last_downloads').'<br />';
+$summary .= _('statistics_summary_downloads_average').': '.$statistics->number_format($stats, 'avg_downloads').'<br />';
+$summary .= _('statistics_summary_downloads_lastweek').': '.$statistics->number_format($stats, 'weeklydownloads').'<br /><br />';
+
+$summary .= '<b>'._('statistics_summary_updatepings_heading').'</b><br />';
+$summary .= _('statistics_summary_updatepings_total').' (';
+if (!empty($stats['last_updatepings_date']))
+ $summary .= sprintf(_('statistics_summary_updatepings_total_ondate'), strftime(_('statistics_date_weekdayshortmonth'), strtotime($stats['last_updatepings_date'])));
+else
+ $summary .= _('statistics_summary_nodata');
+$summary .= '): '.$statistics->number_format($stats, 'last_updatepings').'<br />';
+$summary .= _('statistics_summary_updatepings_changefromprevious').' (';
+if (!empty($stats['previous_updatepings']))
+ $summary .= sprintf(_('statistics_summary_updatepings_changefromprevious_ondate'), $html->number_format($stats['previous_updatepings'], 0), strftime(_('statistics_date_shortmonth'), strtotime($stats['previous_updatepings_date'])));
+else
+ $summary .= _('statistics_summary_nodata');
+$summary .= '): ';
+$summary .= $statistics->colored_percentage($stats, 'updateping_change');
+$summary .= '<br />';
+$summary .= _('statistics_summary_updatepings_average').': '.$statistics->number_format($stats, 'avg_updatepings').'<br />';
+$summary .= ___('statistics_summary_updatepings_weekly_average').': '.$statistics->number_format($stats, 'weekly_updatepings');
+$summary .= ' ('.sprintf(___('statistics_summary_updatepings_weekly_change'),
+ $statistics->colored_percentage($stats, 'weekly_updatepings_change')).')';
+
+$today = mktime(0, 0, 0, date('m'), date('d'), date('Y'));
+
+echo $this->renderElement('rss_listitem', array(
+ 'title' => sprintf(_('statistics_rss_title_statsfordate'), strftime(_('statistics_rss_title_fulldate'))),
+ 'url' => SITE_URL.$html->url('/statistics/addon/'.$addon['Addon']['id']),
+ 'description' => "<![CDATA[{$summary}]]>",
+ 'author' => 'Mozilla Add-ons',
+ 'pubDate' => $time->toRss($today),
+ 'permalink' => SITE_URL.$html->url('/statistics/addon/'.$addon['Addon']['id']).'/'.date('Ymd', $today)
+ ));
+
+?>
diff --git a/site/app/views/statistics/settings.thtml b/site/app/views/statistics/settings.thtml
new file mode 100644
index 0000000..549ad64
--- /dev/null
+++ b/site/app/views/statistics/settings.thtml
@@ -0,0 +1,61 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Justin Scott <fligtar@mozilla.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+?>
+<div class="secondary" role="complementary">
+ <?=$this->renderElement('developers/myaddons', array('addons' => $all_addons));?>
+</div>
+
+<div class="primary prose">
+
+ <div id="content-main" class="article settings-content">
+ <h3><?=sprintf(_('statistics_settings_title'), $addon['Translation']['name']['string'])?></h3><br>
+ <?=$html->formTag('/statistics/settings/'.$addon['Addon']['id'], 'post');?>
+ <h4><?=_('statistics_settings_access_heading')?></h4>
+ <p><?=_('statistics_settings_access_description')?></p>
+ <ul class="options">
+ <li><label><input type="radio" name="data[Addon][publicstats]" value="0"<?=($addon['Addon']['publicstats'] != 1 ? ' checked' : '')?>> <?='<b>'._('statistics_settings_access_private').'</b> - '._('statistics_settings_access_private_description')?></label></li>
+ <li><label><input type="radio" name="data[Addon][publicstats]" value="1"<?=($addon['Addon']['publicstats'] == 1 ? ' checked' : '')?>> <?='<b>'._('statistics_settings_access_public').'</b> - '._('statistics_settings_access_public_description')?></label></li>
+ </ul>
+
+ <div class="buttons">
+ <input type="submit" name="submit" value="<?=_('statistics_settings_save_button')?>"><br>
+ <?=$html->link(_('statistics_settings_return_link'), '/statistics/addon/'.$addon['Addon']['id'])?>
+ </div>
+ </form>
+ </div>
+</div>
diff --git a/site/app/views/statistics/xml.thtml b/site/app/views/statistics/xml.thtml
new file mode 100644
index 0000000..2426633
--- /dev/null
+++ b/site/app/views/statistics/xml.thtml
@@ -0,0 +1,15 @@
+<?php
+if (!defined('NO_MICROTIME'))
+ define('NO_MICROTIME', true);
+header('Content-type: text/xml');
+
+echo '<?xml version="1.0" encoding="UTF-8"?>';
+echo '<data>';
+
+if (!empty($xml)) {
+ echo implode($xml, "\n");
+}
+
+echo '</data>';
+
+?> \ No newline at end of file
diff --git a/site/app/views/tests/case.thtml b/site/app/views/tests/case.thtml
new file mode 100644
index 0000000..0eb4a1c
--- /dev/null
+++ b/site/app/views/tests/case.thtml
@@ -0,0 +1,3 @@
+<?php
+ echo $output;
+?>
diff --git a/site/app/views/tests/discover.thtml b/site/app/views/tests/discover.thtml
new file mode 100644
index 0000000..5dd5b67
--- /dev/null
+++ b/site/app/views/tests/discover.thtml
@@ -0,0 +1,11 @@
+<?php
+
+echo '<?xml version="1.0" ?><cases>';
+
+$testlist = TestManager::getTestCaseList();
+foreach ($testlist as $k=>$testcase) {
+ echo " <case>{$testcase}</case>\n";
+}
+
+echo '</cases>';
+?>
diff --git a/site/app/views/tests/group.thtml b/site/app/views/tests/group.thtml
new file mode 100644
index 0000000..0eb4a1c
--- /dev/null
+++ b/site/app/views/tests/group.thtml
@@ -0,0 +1,3 @@
+<?php
+ echo $output;
+?>
diff --git a/site/app/views/tests/index.thtml b/site/app/views/tests/index.thtml
new file mode 100644
index 0000000..b9c6d21
--- /dev/null
+++ b/site/app/views/tests/index.thtml
@@ -0,0 +1,131 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * Justin Scott <fligtar@gmail.com>.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+?>
+<?
+// deactivate locales in URLs for this page
+$html->addLocale = false;
+?>
+<br>
+<div align="center">
+<form>
+ <input type="text" id="test-search" name="case" />
+ <input type="submit" value="Test Case">
+</form>
+</div>
+<script language="JavaScript" type="text/javascript">
+ $(document).ready(function() {
+ $('#test-search').autocomplete("<?=$html->url('/tests/search')?>", { minChars: 4 });
+ });
+ $('#test-search').focus();
+</script>
+<table width="100%" cellspacing=0 cellpadding=2>
+ <tr>
+ <td valign="top">
+ <p>Available Test Cases: (<a href="javascript:void(0);" onClick="expandNodes();">Expand All</a>)</p>
+ <ul class="testlist">
+ <?php
+ $testlist = TestManager::getTestCaseList();
+
+ foreach ($testlist as $k=>$testCase) {
+ $nodes = explode('/', $testCase, 3);
+ if (!empty($testlist[$k+1])) {
+ $nextNodes = explode('/', $testlist[$k+1], 3);
+ }
+
+ for ($i = -1; $i <= 3; $i++) {
+ if (empty($previousNodes[$i])) {
+ $previousNodes[$i] = '';
+ }
+ if (empty($nodes[$i])) {
+ $nodes[$i] = '';
+ }
+ if (empty($nextNodes[$i])) {
+ $nextNodes[$i] = '';
+ }
+ }
+
+ foreach ($nodes as $n => $node) {
+ if ($previousNodes[$n] != $node && !empty($node)) {
+ if ($previousNodes[$n-1] != $nodes[$n-1]) {
+ echo '<ul class="'.$nodes[$n-1].'" style="display: none;">';
+ }
+
+ if (strpos($node, '.') !== false) {
+ echo '<li class="file"><a href="?case='.urlencode($testCase).'">'.$node.'</a></li>';
+ }
+ else {
+ $directory = '';
+ for ($i = 0; $i <= $n; $i++) {
+ $dirNode = $nodes[$i];
+ if (strpos($dirNode, '.') === false && !empty($dirNode)) {
+ $directory .= $dirNode.'/';
+ }
+ }
+
+ echo '<li class="directory"><a href="javascript:void(0);" onClick="toggleNode(\''.$node.'\');">'.$node.'</a>&nbsp;<a class="rundirectory" href="?directory='.urlencode($directory).'" title="Run Directory">&radic;</a></li>';
+ }
+
+ if ($nextNodes[$n-1] != $nodes[$n-1]) {
+ echo '</ul>';
+ }
+ }
+ }
+ $previousNodes = $nodes;
+ }
+ ?>
+ </ul>
+ </td>
+ <td valign="top">
+ <p>Available Group Tests:</p>
+ <ul class="testlist">
+ <?php
+ foreach($_GET['groups'] as $groupid => $group) {
+ $count = 0;
+ foreach($group['cases'] as $case) {
+ if (strpos($case, '*') !== false) {
+ $count += count(TestManager::getTestCaseList(TESTS.str_replace('/*', '', $case)));
+ }
+ else {
+ $count++;
+ }
+ }
+ echo '<li><a href="'.$html->url('/tests/group/'.$groupid).'">'.$group['name'].'</a> ['.$count.'] ('.$group['description'].')</li>';
+ }
+ ?>
+ </ul>
+ </td>
+ </tr></table>
diff --git a/site/app/views/tests/search.thtml b/site/app/views/tests/search.thtml
new file mode 100644
index 0000000..ac4bc10
--- /dev/null
+++ b/site/app/views/tests/search.thtml
@@ -0,0 +1,10 @@
+<?php
+header('Content-type: text/plain');
+define('NO_MICROTIME', true);
+
+if (count($results) > 0) {
+ foreach ($results as $result) {
+ echo "{$result}\n";
+ }
+}
+?>
diff --git a/site/app/views/users/activatefirst.thtml b/site/app/views/users/activatefirst.thtml
new file mode 100644
index 0000000..ed5a464
--- /dev/null
+++ b/site/app/views/users/activatefirst.thtml
@@ -0,0 +1,53 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Frederic Wenzel <fwenzel@mozilla.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+?>
+
+<div class="secondary" role="complementary">
+ <?=$this->renderElement('amo2009/categories')?>
+</div>
+
+<div class="primary" role="main">
+ <?=$this->renderElement('amo2009/search')?>
+
+ <?=$this->renderElement('notification', array('type' => 'error', 'msg' => _('error_user_unconfirmed')));?>
+ <br/>
+ <p><?=sprintf(_('user_register_click_confirm_link'), $email, APP_PRETTYNAME)?></p>
+ <br/>
+ <p><?=sprintf(_('user_register_resend_confirmation_link'), $html->link(_('user_register_confirmation_link_text'), "/users/verify/{$userid}/resend"))?></p>
+
+</div>
diff --git a/site/app/views/users/delete.thtml b/site/app/views/users/delete.thtml
new file mode 100644
index 0000000..046fa9c
--- /dev/null
+++ b/site/app/views/users/delete.thtml
@@ -0,0 +1,139 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Frederic Wenzel <fwenzel@mozilla.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+?>
+
+
+<div class="secondary" role="complementary">
+ <?=$this->renderElement('amo2009/categories')?>
+</div>
+
+<div class="primary" role="main">
+ <?=$this->renderElement('amo2009/search')?>
+
+<?php if (isset($success) && $success): ?>
+<?=$this->renderElement('notification', array('type' => 'success',
+'msg' => ___('user_del_header_farewell', 'Farewell!'),
+'description' => sprintf(___('user_del_account_deleted', 'Your user account %1$s '
+ .'has been successfully deleted. If you want to come back some time, '
+ .'you can re-register on the <a href="%2$s">user registration page</a>.')
+ , $useremail, $html->url('/users/register')))); ?>
+ <p><?=$html->link(_('link_return_to_front_page'), '/');?></p>
+
+<?php else: ?>
+ <?php if (!empty($deleteerror)){
+ switch ($deleteerror) {
+ case 'addons':
+ echo '<p>';
+ echo $this->renderElement('notification',
+ array('type' => 'error',
+ 'description' => sprintf(___('user_del_error_addons', 'You cannot delete your '
+ .'account if you are listed as an <a href="%1$s"> author of any '
+ .'add-ons</a>. To delete your account, please have another person '
+ .'in your development group delete you from the list of authors '
+ .'for your add-ons. Afterwards you will be able to delete your account '
+ .'here.'), $html->url("/user/{$userid}"))));
+ echo '</p>';
+ echo sprintf(___('user_del_error_addons_more_questions', 'If you '
+ .'have additional questions, please contact %1$s for assistance.'),
+ $link->email('amo-editors@mozilla.org'));
+ break;
+ case 'checkbox':
+ echo $this->renderElement('notification',
+ array('type' => 'error',
+ 'description' => ___('user_del_error_checkbox', 'You need to check the box "I '
+ .'understand..." before we can delete your account.')));
+ break;
+ case 'password':
+ echo $this->renderElement('notification',
+ array('type' => 'error',
+ 'description' => ___('user_del_error_password', 'Please enter your password '
+ .'correctly in order to perform this step.')));
+ break;
+ case 'unknown':
+ default:
+ echo $this->renderElement('notification',
+ array('type' => 'error',
+ 'description' => sprintf(___('user_del_error_unknown', 'An unknown error occured '
+ .'deleting your account. Please contact %1$s with the issue and '
+ .'we will delete it for you. We apologize for the inconvenience.'),
+ $link->email('amo-admins@mozilla.org'))));
+ break;
+ }
+ }
+ ?>
+
+ <h1><?php echo sprintf(___('user_del_header_delete_account', 'Delete User Account %s'), $useremail)?></h1>
+
+ <p><?=___('user_del_community_sad', 'The Mozilla Add-ons community is sad to see you go.')?></p>
+
+ <p><?php sprintf(___('user_del_specific_problem_editors', 'If you have a '
+ .'specific problem we may help you with, please do not delete your account '
+ .'now, but contact us at %1$s and we will do our best to assist you in '
+ .'solving it.'), $link->email('amo-editors@mozilla.org'))?></p>
+
+ <div class="highlight">
+ <h2><?=___('user_del_header_confirm_deletion', 'Confirm account deletion')?></h2>
+
+ <p><?=___('user_del_permanently_removed_means', 'By clicking "delete" your '
+ .'account is going to be <strong>permanently removed</strong>. That means:')?>
+ <ul>
+ <li><?=___('user_del_nologin', 'You will not be able to log into Mozilla Add-ons anymore.')?></li>
+ <li><?=___('user_del_reviews_anonymized', 'Your reviews and ratings will '
+ .'not be deleted, but they will no longer be associated with you.')?></li>
+ </ul>
+ </p>
+ <form action="<?=$html->entities($html->url())?>" method="post" class="amo-form">
+ <?=$html->hiddenSession() ?>
+ <div>
+ <label class="amo-label-large" for="UserPassword"><?=___('user_del_confirm_password', 'Confirm Password')?></label>
+ <?=$html->password('User/password', array('autocomplete'=>'off')) ?>
+ <?=$html->tagErrorMsg('User/password', _('error_wrong_password'))?>
+ </div>
+
+ <p>
+ <?=$html->checkBox('User/reallydelete') ?>
+ <label for="UserReallydelete"><?=___('user_del_understand_permanent',
+ 'I understand that this step cannot be undone.')?></label>
+ </p>
+
+ <p><?=$html->submit(___('user_del_deletenow', 'Delete my user account now')); ?></p>
+ </form>
+ </div>
+ <p><?=$html->link(_('link_return_to_front_page'), '/');?></p>
+<?php endif; ?>
+</div>
diff --git a/site/app/views/users/edit.thtml b/site/app/views/users/edit.thtml
new file mode 100644
index 0000000..008b34a
--- /dev/null
+++ b/site/app/views/users/edit.thtml
@@ -0,0 +1,216 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Frederic Wenzel <fwenzel@mozilla.com> (Original Author)
+ * Wil Clouser <clouserw@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+
+/* Prepare translation box element */
+// Retrieve language arrays from bootstrap.
+global $valid_languages, $native_languages;
+foreach (array_keys($valid_languages) as $key) {
+ $languages[$key] = $native_languages[$key]['native'];
+}
+ksort($languages);
+$this->translationBox = array(
+ 'defaultLocale' => LANG,
+ 'languages' => $languages,
+ 'table' => 'User',
+ 'loaded' => false
+);
+?>
+
+<div class="secondary" role="complementary">
+ <?=$this->renderElement('amo2009/categories')?>
+</div>
+
+<div class="primary" role="main">
+ <?=$this->renderElement('amo2009/search')?>
+
+<?php
+// show confirmation message?
+if (isset($confirmation_page) && $confirmation_page):
+?>
+
+ <?echo $this->renderElement('notification', array('type' => 'success', 'msg' => $confirmation_message))?>
+
+ <?php if (isset($newemail) && $newemail): ?>
+ <?echo $this->renderElement('notification', array('type' => 'success', 'description' => sprintf(___('user_edit_confirm_email_sent'), $newemail)));?>
+ <?php endif; ?>
+
+ <p><?=$html->link(___('link_return_to_front_page'), '/')?></p>
+
+<?php
+else:
+// show "edit" form
+?>
+<?php if(isset($errorMessage)): ?>
+ <?echo $this->renderElement('notification', array('type' => 'error', 'msg' => _('error_formerrors')));?>
+<p></p>
+<?php endif; ?>
+
+
+<h1><?php printf(_('user_form_editprofile'), $this->data['User']['email']); ?></h1>
+
+<form action="<?=$html->entities($html->url())?>" method="post" class="amo-form">
+ <?=$html->hiddenSession() ?>
+
+<div id="tabbed-editor" class="flora">
+ <ul class="tabs-nav">
+ <li><a href="#profile-user"><span><?=___('user_tab_profile', 'User Profile');?></span></a></li>
+ <li><a href="#profile-collections"><span><?=___('user_tab_collections');?></span></a></li>
+ <li><a href="#profile-notifications"><span><?=___('user_tab_notifications');?></span></a></li>
+ <li><a href="#profile-change-pw-email"><span><?=_('user_change_password_or_email'); ?></span></a></li>
+ <li><a href="#profile-other"><span><?=___('user_form_otheractions');?></span></a></li>
+ </ul>
+
+ <div id="profile-user">
+ <h3 class="hidden"><?=___('user_tab_profile', 'User Profile');?></h3>
+ <div class="line">
+ <label class="amo-label-large" for="UserFirstname"><?=_('user_form_firstname')?></label>
+ <?=$html->input('User/firstname') ?>
+ <?=$html->tagErrorMsg('User/firstname', _('error_field_required'))?>
+ <?=___('user_required_firstlast_or_nickname', 'A first name, last name or nickname is required.')?>
+ </div>
+ <div class="line">
+ <label class="amo-label-large" for="UserLastname"><?=_('user_form_lastname')?></label>
+ <?=$html->input('User/lastname') ?>
+ <?=$html->tagErrorMsg('User/lastname', _('error_field_required'))?>
+ </div>
+ <div class="line">
+ <label class="amo-label-large" for="UserNickname"><?=_('user_form_nickname')?></label>
+ <?=$html->input('User/nickname') ?>
+ <?=$html->tagErrorMsg('User/nickname', _('error_user_nickname_notunique'))?>
+ </div>
+ <div class="line">
+ <label class="amo-label-large" for="UserEmailhidden"><?=_('user_form_hideemail')?></label>
+ <?=$html->checkBox('User/emailhidden') ?>
+ </div>
+ <div class="line">
+ <label class="amo-label-large" for="UserHomepage"><?=_('user_form_homepage')?></label>
+ <?=$html->input('User/homepage') ?>
+ <?=$html->tagErrorMsg('User/homepage', _('error_invalid_url'))?>
+ </div>
+ <div class="line">
+ <?php
+ echo $this->renderElement('translationbox', array(
+ 'field' => 'bio',
+ 'translations' => $translations['bio'],
+ 'height' => '100',
+ 'maxLength' => '500',
+ 'displayName' => ___('user_form_bio'),
+ 'description' => ___('user_form_bio_description'),
+ ));
+ ?>
+ </div>
+ </div>
+
+ <div id="profile-collections">
+ <h3 class="hidden"><?=___('user_tab_collections');?></h3>
+ <div class="line">
+ <?=$html->checkbox('User/display_collections') ?>
+ <label for="UserDisplayCollections"><?=___('user_form_display_collections')?></label>
+ </div>
+ <div class="line">
+ <?=$html->checkbox('User/display_collections_fav') ?>
+ <label for="UserDisplayCollectionsFav"><?=___('user_form_display_collections_fav')?></label>
+ </div>
+ </div>
+
+ <div id="profile-notifications">
+ <h3 class="hidden"><?=___('user_tab_notifications', 'Notifications');?></h3>
+ <?php if (empty($userAddons)): ?>
+ <p><?=___('user_notifications_none_available', 'There are currently no notifications available for you to configure.')?></p>
+ <?php else: ?>
+ <p><?=___('user_notifications_select_topics', 'From time to time, Mozilla may send you email about upcoming releases and add-on events. Please select the topics you are interested in below:')?></p>
+ <ul>
+ <li><label for="UserNotifycompat"><?=$html->checkbox('User/notifycompat')?>&nbsp;<?=___('user_notifications_item_compat', 'Add-on Compatibility (strongly recommended)')?></label></li>
+ <li><label for="UserNotifyevents"><?=$html->checkbox('User/notifyevents')?>&nbsp;<?=___('user_notifications_item_events', 'Upcoming events and contests')?></li>
+ </ul>
+
+ <p><?=___('user_notifications_specific_contact', 'Mozilla reserves the right to contact you individually about specific concerns with your hosted add-ons.')?></p>
+ <?php endif; ?>
+ </div>
+
+ <div id="profile-change-pw-email">
+ <h3><?=_('user_change_password'); ?></h3>
+ <div class="line">
+ <label class="amo-label-large" for="UserPassword"><?=_('user_form_oldpassword')?></label>
+ <?=$html->password('User/password', array('autocomplete'=>'off')) ?>
+ <?=$html->tagErrorMsg('User/password', _('error_wrong_password'))?>
+ </div>
+ <div class="line">
+ <label class="amo-label-large" for="UserNewpassword"><?=_('user_form_newpassword')?></label>
+ <?=$html->password('User/newpassword', array('autocomplete'=>'off')) ?>
+ <?=$html->tagErrorMsg('User/newpassword', 'error_field_required')?>
+ </div>
+ <div class="line">
+ <label class="amo-label-large" for="UserConfirmpw"><?=_('user_form_confirmpassword')?></label>
+ <?=$html->password('User/confirmpw', array('autocomplete'=>'off')) ?>
+ <?=$html->tagErrorMsg('User/confirmpw', _('error_user_confirmpw_nomatch'))?>
+ </div>
+ <h3><?=___('user_change_email', 'Change Email Address');?></h3>
+ <div class="line">
+ <label class="amo-label-large" for="UserEmail"><?=_('user_form_email')?></label>
+ <?=$html->input('User/email') ?>
+ <?php if (isset($error_email_notunique))
+ echo '<div class="error_message">'._('error_user_email_notunique').'</div>';
+ elseif (isset($error_email_empty))
+ echo '<div class="error_message">'._('error_field_required').'</div>';
+ else
+ echo $html->tagErrorMsg('User/email', _('error_email_invalid'));
+ ?>
+ </div>
+ </div>
+
+ <div id="profile-other">
+ <h3 class="hidden"><?=___('user_form_otheractions', 'Other Actions');?></h3>
+ <p><?=$html->link(___('user_edit_delete_user', 'Delete user account'), '/users/delete');?></p>
+ </div>
+</div>
+
+ <?=$html->submit(_('user_form_submit_edit'), array('class'=>'amo-submit')); ?>
+</form>
+
+<?php endif; /* end of form vs. confirmation */ ?>
+
+</div>
+
+<script type="text/javascript">
+ $(document).ready(function(){
+ $("#tabbed-editor > ul").tabs();
+ });
+</script>
diff --git a/site/app/views/users/email/confirm_plain.thtml b/site/app/views/users/email/confirm_plain.thtml
new file mode 100644
index 0000000..0e0460b
--- /dev/null
+++ b/site/app/views/users/email/confirm_plain.thtml
@@ -0,0 +1,8 @@
+<?
+$confirmurl = SITE_URL.$html->url('/users/verify/'.$userid.'/'
+ .$data['User']['confirmationcode'], true);
+
+// the whole email is localized.
+echo $html->lineBreaks(sprintf(_('user_email_confirm_account_nopass'),
+ $confirmurl, APP_PRETTYNAME));
+?>
diff --git a/site/app/views/users/email/emailchange_plain.thtml b/site/app/views/users/email/emailchange_plain.thtml
new file mode 100644
index 0000000..4a1a852
--- /dev/null
+++ b/site/app/views/users/email/emailchange_plain.thtml
@@ -0,0 +1,7 @@
+<?php
+$confirmurl = SITE_URL.$html->url('/users/emailchange/'.$userid.'?code='
+ .urlencode($changecode), true);
+
+echo $html->lineBreaks(sprintf(___('user_email_confirm_emailchange'), $confirmurl, APP_PRETTYNAME));
+
+?>
diff --git a/site/app/views/users/email/pwreset_plain.thtml b/site/app/views/users/email/pwreset_plain.thtml
new file mode 100644
index 0000000..39b9071
--- /dev/null
+++ b/site/app/views/users/email/pwreset_plain.thtml
@@ -0,0 +1,6 @@
+<?
+$reseturl = SITE_URL.$html->url('/users/pwreset/'.$data['User']['id']
+ .'/'.$resetcode, true);
+
+echo $html->lineBreaks(sprintf(_('user_email_pwreset'), $reseturl, APP_PRETTYNAME));
+?>
diff --git a/site/app/views/users/emailchange.thtml b/site/app/views/users/emailchange.thtml
new file mode 100644
index 0000000..9f91a53
--- /dev/null
+++ b/site/app/views/users/emailchange.thtml
@@ -0,0 +1,60 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Frederic Wenzel <fwenzel@mozilla.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+?>
+
+<div class="secondary" role="complementary">
+ <?=$this->renderElement('amo2009/categories')?>
+</div>
+
+<div class="primary" role="main">
+ <?=$this->renderElement('amo2009/search')?>
+
+<?php
+$_user_emailchange_success = ___('user_emailchange_success');
+$_user_emailchange_successful_description = sprintf(___('user_emailchange_successful_description'), $newemail);
+$_user_emailchange_error = ___('user_emailchange_error');
+$_link_return_to_front_page = ___('link_return_to_front_page');
+
+if (!isset($errormsg)): ?>
+<?=$this->renderElement('notification', array('type' => 'success', 'msg' => $_user_emailchange_success, 'description' => $_user_emailchange_successful_description))?>
+<?php else: ?>
+<?=$this->renderElement('notification', array('type' => 'error', 'msg' => $_user_emailchange_error, 'description' => $errormsg))?>
+<?php endif; ?>
+ <p><?=$html->link($_link_return_to_front_page, '/')?></p>
+
+</div>
diff --git a/site/app/views/users/info.thtml b/site/app/views/users/info.thtml
new file mode 100644
index 0000000..659abb6
--- /dev/null
+++ b/site/app/views/users/info.thtml
@@ -0,0 +1,172 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Frederic Wenzel <fwenzel@mozilla.com> (Original Author)
+ * Wil Clouser <clouserw@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+?>
+
+<div class="secondary" role="complementary">
+ <?=$this->renderElement('amo2009/categories')?>
+</div>
+
+<div class="primary" role="main">
+ <?=$this->renderElement('amo2009/search')?>
+
+ <h3><?=_('users_info_author_profile')?></h3>
+ <dl>
+ <? if (!empty($profile['User']['firstname']) || !empty($profile['User']['lastname'])): ?>
+ <dt><?=_('users_info_author_name')?></dt>
+ <dd><?=$profile['User']['firstname']?> <?=$profile['User']['lastname']?></dd>
+ <? endif; ?>
+
+ <? if (!empty($profile['User']['nickname'])): ?>
+ <dt><?=_('users_info_nickname')?></dt>
+ <dd><?=$profile['User']['nickname']?></dd>
+ <? endif; ?>
+
+ <? if (!empty($profile['User']['homepage'])): ?>
+ <dt><?=_('users_info_homepage')?></dt>
+ <dd><?=$html->link($profile['User']['homepage'], $profile['User']['homepage'])?></dd>
+ <? endif; ?>
+
+ <? if ($profile['User']['emailhidden'] == 0): ?>
+ <dt><?=_('users_info_email')?></dt>
+ <dd><?=$link->email($profile['User']['email'])?></dd>
+ <? endif; ?>
+
+ <?php if ($profile['Translation']['bio']['string']): ?>
+ <dt><?=___('users_info_aboutme')?></dt>
+ <dd><?=nl2br($profile['Translation']['bio']['string'])?></dd>
+ <?php endif; ?>
+
+ <dt><?=sprintf(_('user_info_usersince'), APP_PRETTYNAME)?></dt>
+ <dd><?=strftime(_('date'), strtotime($profile['User']['created']))?></dd>
+
+ </dl>
+
+<?php
+ if ($this->controller->SimpleAcl->actionAllowed('Admin', 'users', $this->controller->Session->read('User'))) {
+ echo $html->link('Edit User', "/admin/users/{$profile['User']['id']}");
+ }
+?>
+
+<?php
+ if ($profile['User']['firstname'] == '' && $profile['User']['lastname'] == '') {
+ $displayName = $profile['User']['nickname'];
+ } else {
+ $displayName = $profile['User']['firstname'].' '.$profile['User']['lastname'];
+ }
+?>
+
+<?php if (!empty($addons)): ?>
+<div>
+<h3><?=sprintf(_('users_info_addons_by_user'), $displayName)?></h3>
+<dl>
+<?
+ global $app_shortnames;
+ foreach($addons as &$addon):
+ if (array_key_exists('Tag', $addon) && !empty($addon['Tag'])) {
+ $_application = array_search($addon['Tag'][0]['application_id'], $app_shortnames);
+ } else {
+ $_application = 'firefox';
+ }
+?>
+ <dt><?=$html->linkNoLocaleNoApp($addon['Translation']['name']['string'], '/'.LANG."/{$_application}/addon/{$addon['Addon']['id']}")?></dt>
+ <dd><?=$addon['Translation']['summary']['string']?></dd>
+<? endforeach; ?>
+</dl>
+</div>
+<?php endif; ?>
+
+<?php if (!empty($reviews)): ?>
+<div>
+<h3><?=sprintf(___('users_info_reviews_by_user', 'Reviews by %s'), $displayName)?></h3>
+<dl>
+ <?php
+ global $app_shortnames;
+ foreach ($reviews as &$review):
+ if (!empty($review['Addon']['compatible_apps'])) {
+ $_application = array_search($review['Addon']['compatible_apps'][0]['Application']['application_id'], $app_shortnames);
+ } else {
+ $_application = 'firefox';
+ }
+ ?>
+ <dt><?= $html->linkNoLocaleNoApp($review['Addon']['Translation']['name']['string'],
+ '/'.LANG."/{$_application}/addon/{$review['Addon']['Addon']['id']}"); ?></dt>
+ <dd><?=$review['Translation']['body']['string']?></dd>
+ <? endforeach; ?>
+</dl>
+</div>
+<?php endif; ?>
+
+<?php if (!empty($coll)): ?>
+<div>
+<h3><?=sprintf(___('users_info_collections_by_user'), $displayName)?></h3>
+<dl>
+ <?php
+ global $app_shortnames;
+ foreach ($coll as &$c):
+ ?>
+ <dt><?= $html->linkNoLocaleNoApp($c['Translation']['name']['string'],
+ sprintf('/%s/%s/collection/%s', LANG, array_search($c['Collection']['application_id'], $app_shortnames),
+ empty($c['Collection']['nickname'])?$c['Collection']['uuid']:$c['Collection']['nickname'])); ?>
+ </dt>
+ <dd><?=$c['Translation']['description']['string']?></dd>
+ <? endforeach; ?>
+</dl>
+</div>
+<?php endif; ?>
+
+<?php if (!empty($coll_fav)): ?>
+<div>
+<h3><?=___('users_info_fav_collections_by_user')?></h3>
+<dl>
+ <?php
+ global $app_shortnames;
+ foreach ($coll_fav as &$c):
+ ?>
+ <dt><?= $html->linkNoLocaleNoApp($c['Translation']['name']['string'],
+ sprintf('/%s/%s/collection/%s', LANG, array_search($c['Collection']['application_id'], $app_shortnames),
+ empty($c['Collection']['nickname'])?$c['Collection']['uuid']:$c['Collection']['nickname'])); ?>
+ </dt>
+ <dd><?=$c['Translation']['description']['string']?></dd>
+ <? endforeach; ?>
+</dl>
+</div>
+<?php endif; ?>
+
+</div>
+<!-- /#.primary -->
diff --git a/site/app/views/users/login.thtml b/site/app/views/users/login.thtml
new file mode 100644
index 0000000..a3c6e83
--- /dev/null
+++ b/site/app/views/users/login.thtml
@@ -0,0 +1,105 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Frederic Wenzel <fwenzel@mozilla.com> (Original Author)
+ * Wil Clouser <clouserw@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+?>
+
+<div class="secondary" role="complementary">
+ <?=$this->renderElement('amo2009/categories')?>
+</div>
+
+<div class="primary" role="main">
+ <?=$this->renderElement('amo2009/search')?>
+
+<?php
+ //banner warning messages for display
+ if(isset($_GET['m'])) {
+ switch ($_GET['m']) {
+ case 1:
+ $warn_msg = sprintf(_('users_login_sandbox_display_warning'), '/pages/policy');
+ break;
+ case 2:
+ $warn_msg = sprintf(_('users_login_sandbox_page_warning'), '/pages/policy');
+ break;
+ default:
+ $warn_msg = null;
+ }
+ }
+ if (!empty($warn_msg))
+ echo $this->renderElement('notification', array('type' => 'info', 'description' => $warn_msg));
+?>
+
+<?php if ($loginerror)
+ echo $this->renderElement('notification', array('type' => 'error', 'description' => _('error_username_or_pw_wrong')));
+?>
+<p></p>
+<form action="<?=$html->entities($html->url())?>" method="post" class="amo-form highlight">
+ <?=$html->hiddenSession() ?>
+ <div>
+ <?
+ $redir = (isset($_GET['to'])) ? urldecode($_GET['to']) : urldecode(@$this->data['Login']['referer']);
+ $redir = $html->entities($redir);
+ $redir = html_entity_decode($redir);
+ echo $html->hidden('Login/referer', array('value' => $redir));
+ ?>
+ </div>
+ <div class="container">
+ <label class="amo-label-large" for="LoginEmail"><?=_('user_form_email')?></label>
+ <?=$html->input('Login/email') ?>
+ </div>
+ <div class="container">
+ <label class="amo-label-large" for="LoginPassword"><?=_('user_form_password')?></label>
+ <?=$html->password('Login/password') ?>
+ </div>
+ <div class="container">
+ <?=$html->input('Login/remember', array('type' => 'checkbox', 'value' => '1', 'class' => 'amo-remember'))?>
+ <label for="LoginRemember"><?=___('user_form_remember_me')?></label>
+ </div>
+ <div class="container">
+ <?=$html->submit(_('user_form_submit_login'), array('class'=>'amo-submit')); ?>
+ </div>
+</form>
+<script type="text/javascript" charset="utf-8">
+ // focus email field
+ $(document).ready(function() { $('#LoginEmail').focus(); });
+</script>
+
+<ul>
+ <li><?= $html->link(_('user_login_register_link'), '/users/register'); ?></li>
+ <li><?= $html->link(_('user_pwreset_link'), '/users/pwreset',null,null,false); ?></li>
+</ul>
+</div><!-- /.primary -->
diff --git a/site/app/views/users/pwreset.thtml b/site/app/views/users/pwreset.thtml
new file mode 100644
index 0000000..b9962c0
--- /dev/null
+++ b/site/app/views/users/pwreset.thtml
@@ -0,0 +1,87 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Frederic Wenzel <fwenzel@mozilla.com> (Original Author)
+ * Wil Clouser <clouserw@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+?>
+<div class="secondary" role="complementary">
+ <?=$this->renderElement('amo2009/categories')?>
+</div>
+
+<div class="primary" role="main">
+ <?=$this->renderElement('amo2009/search')?>
+
+<?php if(!isset($email)): ?>
+
+<form action="<?=$html->entities($html->url())?>" method="post" class="amo-form corner-box">
+ <?=$html->hiddenSession() ?>
+ <div class="container">
+ <label class="amo-label-large" for="UserEmail"><?=_('user_form_email')?></label>
+ <?=$html->input('User/email') ?>
+ <?=$html->tagErrorMsg('User/email', _('error_user_notfound'))?>
+ </div>
+ <div class="container">
+ <?=$html->submit(_('user_pwreset_submit_sendlink'), array('class'=>'amo-submit')); ?>
+ </div>
+</form>
+<?php
+
+else:
+
+?>
+<h1><?php echo sprintf(_('user_pwreset_for_email'), $email); ?></h1>
+<p></p>
+
+<form action="<?=$html->entities($html->url())?>" method="post" class="amo-form corner-box">
+ <?=$html->hiddenSession() ?>
+
+ <div class="container">
+ <label class="amo-label-large" for="UserPassword"><?=_('user_form_newpassword')?></label>
+ <?=$html->password('User/password') ?>
+ <?=$html->tagErrorMsg('User/password', _('error_field_required'))?>
+ </div>
+ <div class="container">
+ <label class="amo-label-large" for="UserConfirmpw"><?=_('user_form_confirmpassword')?></label>
+ <?=$html->password('User/confirmpw') ?>
+ <?=$html->tagErrorMsg('User/confirmpw', _('error_user_confirmpw_nomatch'))?>
+ </div>
+ <div class="container">
+ <?=$html->submit(_('user_pwreset_submit_changepw'), array('class'=>'amo-submit'));?>
+ </div>
+</form>
+<?php endif; ?>
+
+</div>
diff --git a/site/app/views/users/register.thtml b/site/app/views/users/register.thtml
new file mode 100644
index 0000000..6872360
--- /dev/null
+++ b/site/app/views/users/register.thtml
@@ -0,0 +1,117 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Frederic Wenzel <fwenzel@mozilla.com> (Original Author)
+ * Wil Clouser <clouserw@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+?>
+
+<div class="secondary" role="complementary">
+ <?=$this->renderElement('amo2009/categories')?>
+</div>
+
+<div class="primary" role="main">
+ <?=$this->renderElement('amo2009/search')?>
+
+ <div>
+ <h1><?= ___('user_register_welcome_header') ?></h1>
+ <?= sprintf(___('user_register_details'), 'http://www.mozilla.com/about/legal.html', $html->url('/pages/privacy')) ?>
+ </div>
+
+<?php if(isset($errorMessage)): ?>
+<?=$this->renderElement('notification', array('type' => 'error', 'msg' => _('error_formerrors')));?>
+<p></p>
+<?php
+endif;
+?>
+
+<form action="<?=$html->entities($html->url())?>" method="post" class="amo-form">
+ <?=$html->hiddenSession() ?>
+ <div class="container">
+ <label class="amo-label-large" for="UserEmail"><?=_('user_form_email')?></label>
+ <?=$html->input('User/email') ?>
+ <?=(isset($error_email_notunique)) ? '<div class="error_message">'._('error_user_email_notunique').'</div>' : $html->tagErrorMsg('User/email', _('error_email_invalid'))?>
+ </div>
+ <div class="container">
+ <label class="amo-label-large" for="UserPassword"><?=_('user_form_password')?></label>
+ <?=$html->password('User/password') ?>
+ <?=$html->tagErrorMsg('User/password', _('error_field_required'))?>
+ </div>
+ <div class="container">
+ <label class="amo-label-large" for="UserConfirmpw"><?=_('user_form_confirmpassword')?></label>
+ <?=$html->password('User/confirmpw') ?>
+ <?=$html->tagErrorMsg('User/confirmpw', _('error_user_confirmpw_nomatch'))?>
+ </div>
+ <div class="container">
+ <label class="amo-label-large" for="UserFirstname"><?=_('user_form_firstname')?></label>
+ <?=$html->input('User/firstname') ?>
+ <?=$html->tagErrorMsg('User/firstname', _('error_field_required'))?>
+ <?=___('user_required_firstlast_or_nickname', 'A first name, last name or nickname is required.')?>
+ </div>
+ <div class="container">
+ <label class="amo-label-large" for="UserLastname"><?=_('user_form_lastname')?></label>
+ <?=$html->input('User/lastname') ?>
+ <?=$html->tagErrorMsg('User/lastname', _('error_field_required'))?>
+ </div>
+ <div class="container">
+ <label class="amo-label-large" for="UserNickname"><?=_('user_form_nickname')?></label>
+ <?=$html->input('User/nickname') ?>
+ <?=$html->tagErrorMsg('User/nickname', _('error_user_nickname_notunique'))?>
+ </div>
+ <div class="container">
+ <label class="amo-label-large" for="UserEmailhidden"><?=_('user_form_hideemail')?></label>
+ <?=$html->checkBox('User/emailhidden')?>
+ </div>
+ <div class="container">
+ <label class="amo-label-large" for="UserHomepage"><?=_('user_form_homepage')?></label>
+ <?=$html->input('User/homepage') ?>
+ <?=$html->tagErrorMsg('User/homepage', _('error_invalid_url'))?>
+ </div>
+<?php if (isset($this->controller->Recaptcha) && $this->controller->Recaptcha->enabled): ?>
+ <div class="container">
+ <div class="amo-label-large">
+ <label for="recaptcha_response_field"><?=___('recaptcha_label', 'Are you human?')?></label><br/>
+ <span id="recaptcha_whatsthis"><a href="javascript:Recaptcha.showhelp()"><?=___('recaptcha_whatsthis', "What's this?")?></a></span>
+ </div>
+ <div class="amo-form-indent"><?=$this->renderElement('recaptcha')?></div>
+ <?=$html->tagErrorMsg('User/captcha', ___('error_invalid_captcha', 'Invalid captcha, please try again!'))?>
+ </div>
+<?php endif; ?>
+ <div class="container">
+ <?=$html->submit(_('user_form_submit_register'), array('class'=>'amo-submit')); ?>
+ </div>
+</form>
+
+</div>
diff --git a/site/app/views/users/register_complete.thtml b/site/app/views/users/register_complete.thtml
new file mode 100644
index 0000000..f709972
--- /dev/null
+++ b/site/app/views/users/register_complete.thtml
@@ -0,0 +1,54 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Frederic Wenzel <fwenzel@mozilla.com> (Original Author)
+ * Wil Clouser <clouserw@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+?>
+<div class="secondary" role="complementary">
+ <?=$this->renderElement('amo2009/categories')?>
+</div>
+
+<div class="primary" role="main">
+ <?=$this->renderElement('amo2009/search')?>
+
+ <?=$this->renderElement('notification', array('type' => 'success', 'msg' => _('user_register_congratulations')));?>
+
+ <p><?=sprintf(_('user_register_confirm_email_sent'), $data['User']['email'])?></p>
+
+ <p><?=sprintf(_('user_register_welcome'), $html->link(sprintf(_('user_register_amo_link'), APP_PRETTYNAME), '/'))?></p>
+
+ </div>
+</div>
diff --git a/site/app/views/versions/license.thtml b/site/app/views/versions/license.thtml
new file mode 100644
index 0000000..c8edf18
--- /dev/null
+++ b/site/app/views/versions/license.thtml
@@ -0,0 +1,57 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ *
+ * Contributor(s):
+ * Jeff Balogh <jbalogh@mozilla.com> (Original Author)
+ * Frederic Wenzel <fwenzel@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+?>
+<div class="secondary" role="complementary">
+ <?=$this->renderElement('amo2009/categories')?>
+</div>
+<div class="stand-alone-options">
+ <?=$this->renderElement('amo2009/search')?>
+</div>
+
+<div id="version-license" class="primary prose" role="main">
+ <?php
+ $addon_id = $version['Version']['addon_id'];
+ $version_id = $version['Version']['id'];
+ $version_name = $version['Version']['version'];
+ $addon_link = $html->link($addon['Translation']['name']['string'], '/addon/'.$addon_id);
+ $version_link = $html->link($version_name, '/addons/versions/'.$addon_id.'#version-'.$version_name);
+ $header = sprintf(___('versions_license_header_source'), $addon_link, $version_link);
+ ?>
+ <h2<?=$addon['Translation']['name']['locale_html']?>><?=$header?></h2>
+
+ <pre><?=$license_text?></pre>
+</div>
diff --git a/site/app/views/versions/update_info.thtml b/site/app/views/versions/update_info.thtml
new file mode 100644
index 0000000..70159f8
--- /dev/null
+++ b/site/app/views/versions/update_info.thtml
@@ -0,0 +1,56 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Justin Scott <fligtar@mozilla.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+header('Content-type: application/xhtml+xml');
+define('NO_MICROTIME', true);
+?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html lang="<?=LANG?>" dir="<?=TEXTDIR?>" xmlns="http://www.w3.org/1999/xhtml">
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
+ <title></title>
+</head>
+
+<body>
+ <p><?php
+ // <br/> isn't allowed by the client, so we use <p>s
+ $updateInfo = str_replace("\n", '</p><p>', $updateInfo);
+ echo $updateInfo;
+ ?></p>
+</body>
+</html> \ No newline at end of file
diff --git a/site/app/webroot/.htaccess b/site/app/webroot/.htaccess
new file mode 100644
index 0000000..63862b3
--- /dev/null
+++ b/site/app/webroot/.htaccess
@@ -0,0 +1,70 @@
+<IfModule mod_rewrite.c>
+ RewriteEngine On
+
+ # Rewrites for services, since using .htaccess broke them.
+ RewriteRule ^update/VersionCheck.php(.*)$ services/update.php$1 [L]
+ RewriteRule ^plugins/PluginFinderService.php(.*)$ services/pfs.php$1 [L]
+ RewriteRule ^blocklist/1/([^/]+)/([^/]+)[/]{0,1}$ services/blocklist.php?reqVersion=1&appGuid=$1&appVersion=$2 [L]
+ RewriteRule ^blocklist/([23])/([^/]+)/([^/]+)/(.+)$ services/blocklist.php?reqVersion=$1&appGuid=$2&appVersion=$3&params=$4 [L]
+
+ # robots.txt, generated by cake
+ RewriteRule ^robots.txt$ en-US/firefox/pages/robots.txt [L]
+
+ # take that, shitty https: handling!
+ RewriteCond %{HTTP:Moz-Req-Method} ^HTTPS$ [NC]
+ RewriteRule ^.*$ - [env=HTTPS:on,env=force-no-vary:hellsyes]
+ # discussions are no more, woo!
+ RewriteRule ^(.*)?discussions(/.*)?$ /$1 [R=permanent,L]
+ # The old v1 urls used query strings.
+ # I can't be bothered with any of it except the id=$addon part.
+ # We have to be careful to avoid matching vid=$version
+ # Example old urls
+ # /extensions/moreinfo.php?application=thunderbird&id=123
+ # /extensions/moreinfo.php?id=123
+ # /themes/moreinfo.php?id=321
+ # /themes/moreinfo.php?id=321&vid=1234
+ # /themes/moreinfo.php?vid=1234&id=321
+ # with ssl
+ RewriteCond %{HTTP:Moz-Req-Method} ^HTTPS$ [NC]
+ RewriteCond %{QUERY_STRING} (^|&)id=([0-9]+)(&|$)
+ RewriteRule ^(extensions|themes)/moreinfo.php$ https://%{SERVER_NAME}/firefox/addon/%2 [R=permanent,L]
+ # without ssl
+ RewriteCond %{QUERY_STRING} (^|&)id=([0-9]+)(&|$)
+ RewriteRule ^(extensions|themes)/moreinfo.php$ /firefox/addon/%2 [R=permanent,L]
+ # Handle the trickier v2 URLs
+ # /firefox/$addon
+ # with ssl
+ RewriteCond %{HTTP:Moz-Req-Method} ^HTTPS$ [NC]
+ RewriteRule ^(firefox|thunderbird|sunbird|seamonkey)/(\d+)/?$ https://%{SERVER_NAME}/$1/addon/$2 [QSA,R=permanent,L]
+ # without ssl
+ RewriteRule ^(firefox|thunderbird|sunbird|seamonkey)/(\d+)/?$ /$1/addon/$2 [QSA,R=permanent,L]
+ # /firefox/$user/author/
+ # with ssl
+ RewriteCond %{HTTP:Moz-Req-Method} ^HTTPS$ [NC]
+ RewriteRule ^(firefox|thunderbird|sunbird|seamonkey)/(\d+)/author/?$ https://%{SERVER_NAME}/$1/user/$2 [QSA,R=permanent,L]
+ # without ssl
+ RewriteRule ^(firefox|thunderbird|sunbird|seamonkey)/(\d+)/author/?$ /$1/user/$2 [QSA,R=permanent,L]
+ # legacy RSS feeds
+ # with ssl
+ RewriteCond %{HTTP:Moz-Req-Method} ^HTTPS$ [NC]
+ RewriteRule ^rss/(firefox|thunderbird|sunbird|seamonkey)/extensions/(popular|updated|rated|newest)/?$ https://%{SERVER_NAME}/$1/browse/type:1/cat:all/sort:$2/format:rss [R=permanent,L]
+ RewriteCond %{HTTP:Moz-Req-Method} ^HTTPS$ [NC]
+ RewriteRule ^rss/(firefox|thunderbird|sunbird|seamonkey)/themes/(popular|updated|rated|newest)/?$ https://%{SERVER_NAME}/$1/browse/type:2/cat:all/sort:$2/format:rss [R=permanent,L]
+ # without ssl
+ RewriteRule ^rss/(firefox|thunderbird|sunbird|seamonkey)/extensions/(popular|updated|rated|newest)/?$ /$1/browse/type:1/cat:all/sort:$2/format:rss [R=permanent,L]
+ RewriteRule ^rss/(firefox|thunderbird|sunbird|seamonkey)/themes/(popular|updated|rated|newest)/?$ /$1/browse/type:2/cat:all/sort:$2/format:rss [R=permanent,L]
+
+ # do everything else cakey
+ RewriteCond %{REQUEST_FILENAME} !-d
+ RewriteCond %{REQUEST_FILENAME} !-f
+ RewriteRule ^(.*)$ index.php?url=$1 [QSA,L]
+</IfModule>
+
+<FilesMatch "(jquery.addons.min.js|style.min.css|\.(gif|jpe?g|png))$">
+ ExpiresActive On
+ ExpiresDefault "access plus 10 years"
+</FilesMatch>
+
+# Added to fix our favicon
+AddType image/x-icon ico
+
diff --git a/site/app/webroot/AMOSearch.xml b/site/app/webroot/AMOSearch.xml
new file mode 100644
index 0000000..1feba30
--- /dev/null
+++ b/site/app/webroot/AMOSearch.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<OpenSearchDescription xmlns="http://a9.com/-/spec/opensearch/1.1/">
+ <ShortName>Mozilla Add-ons</ShortName>
+ <Url type="text/html"
+ method="get"
+ template="http://addons.mozilla.org/search/?q={searchTerms}">
+ </Url>
+ <Image height="16" width="16">data:image/x-icon;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8%2F9hAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz%0D%0AAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAKoSURB%0D%0AVDiNjZNLaJRnFIaf75vvy2UGTWr8NYkxl0IFUYkNXSSZQNWFWlxIEVy1FLLo0i4adddVXRnS4kJw%0D%0AYxci2GaRTWlSFGKFGRXNmFBF62VMO4TENBdjMv9k5p%2F%2FOy4SLzgqHs7yPc95eTlHiQjvqniPbVYR%0D%0AzuBoR%2BFQDEvId4neIPNCY945DayNVff%2F8NUvn9XXNJMv5hhKnTvYP3ymHmj%2FIMBSbmHjjP8fycxv%0D%0A%2BMEzGqtatUI1vK7R7wM4J32XUv3Li%2Fl5imGBkbtXlsMw%2FPF1jXozg3iP3aM0Z8XRBFDr1fl7Og9E%0D%0AnTguXx30p%2F6fjAIozb%2Fi6C4BdB2z6QOfH27ZUFNL0QUELs%2Ftycs4J2zdGEerCADTM1P8df3PxyUZ%0D%0AiKPF8zyGHpwGFLC6QCCRuYA4QQQ6mw4hjhYT77GN2qiBWFnV5sXc0xMAgfKx5foVYKURB2vLPbxo%0D%0AM8auODE6ws%2FfH%2B77dHtjhxp5OHzywpWf%2FIIsRk25Rq0CRFY4UVNNndkmqZFRf3YuWaYUS0aE3RP5%0D%0AMXX3%2FiCOgu3Y1WYfL90sdSDgxRoYTY5mZ2anjwC%2FAqEBdM4tMJ4dwYs1YiOGSBkYrVHqlQNxoC34%0D%0AOV8BdxK9gQ%2Bguo7bwdYdrXu92nU6nR7Pzc%2FPSXxfazTj30IpRaWpIqbX4UQoBDkWJlRwLzVeLBTy%0D%0AGs2UcUX5duzvsfPqNpvDovQhnBIdELGaWFk1hclYmLx2fxmFbNm5qXJNvdi2DQ1WAsO1P%2F5petsh%0D%0Ayf6v25gJ0nxUUUeiP531s%2FkvAcor7MDOL2pjz3JzVKpqUoMTpb8QsSqdeTT98fomjyDv8LP5aKI3%0D%0AuAgQP2orCkGAVRVMZxbQhnQJIAzkm3s3Js6GSfkEQEd4%2Bbpa8%2BTW71P1ANqoB65I93OA2DgV%2BZ%2Bo%0D%0AmgAAAABJRU5ErkJggg%3D%3D</Image>
+ <OutputEncoding>UTF-8</OutputEncoding>
+ <InputEncoding>UTF-8</InputEncoding>
+</OpenSearchDescription>
diff --git a/site/app/webroot/css.php b/site/app/webroot/css.php
new file mode 100644
index 0000000..0b1f811
--- /dev/null
+++ b/site/app/webroot/css.php
@@ -0,0 +1,101 @@
+<?php
+/* SVN FILE: $Id: css.php,v 1.1.1.1 2006/08/14 23:54:57 sancus%off.net Exp $ */
+/**
+ * Short description for file.
+ *
+ * Long description for file
+ *
+ * PHP versions 4 and 5
+ *
+ * CakePHP : Rapid Development Framework <http://www.cakephp.org/>
+ * Copyright (c) 2006, Cake Software Foundation, Inc.
+ * 1785 E. Sahara Avenue, Suite 490-204
+ * Las Vegas, Nevada 89104
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright Copyright (c) 2006, Cake Software Foundation, Inc.
+ * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP Project
+ * @package cake
+ * @subpackage cake.app.webroot
+ * @since CakePHP v 0.2.9
+ * @version $Revision: 1.1.1.1 $
+ * @modifiedby $LastChangedBy: phpnut $
+ * @lastmodified $Date: 2006/08/14 23:54:57 $
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+/**
+ * Enter description here...
+ */
+ require(CONFIGS . 'paths.php');
+ require(CAKE . 'basics.php');
+ require(LIBS . 'folder.php');
+ require(LIBS . 'file.php');
+ require(LIBS . 'legacy.php');
+/**
+ * Enter description here...
+ *
+ * @param unknown_type $path
+ * @param unknown_type $name
+ * @return unknown
+ */
+ function make_clean_css($path, $name) {
+ require(VENDORS . 'csspp' . DS . 'csspp.php');
+ $data =file_get_contents($path);
+ $csspp =new csspp();
+ $output=$csspp->compress($data);
+ $ratio =100 - (round(strlen($output) / strlen($data), 3) * 100);
+ $output=" /* file: $name, ratio: $ratio% */ " . $output;
+ return $output;
+ }
+/**
+ * Enter description here...
+ *
+ * @param unknown_type $path
+ * @param unknown_type $content
+ * @return unknown
+ */
+ function write_css_cache($path, $content) {
+ if (!is_dir(dirname($path))) {
+ mkdir(dirname($path));
+ }
+ $cache=new File($path);
+ return $cache->write($content);
+ }
+
+ if (preg_match('|\.\.|', $url) || !preg_match('|^ccss/(.+)$|i', $url, $regs)) {
+ die('Wrong file name.');
+ }
+
+ $filename = 'css/' . $regs[1];
+ $filepath = CSS . $regs[1];
+ $cachepath = CACHE . 'css' . DS . str_replace(array('/','\\'), '-', $regs[1]);
+
+ if (!file_exists($filepath)) {
+ die('Wrong file name.');
+ }
+
+ if (file_exists($cachepath)) {
+ $templateModified=filemtime($filepath);
+ $cacheModified =filemtime($cachepath);
+
+ if ($templateModified > $cacheModified) {
+ $output=make_clean_css($filepath, $filename);
+ write_css_cache($cachepath, $output);
+ } else {
+ $output = file_get_contents($cachepath);
+ }
+ } else {
+ $output=make_clean_css($filepath, $filename);
+ write_css_cache($cachepath, $output);
+ }
+
+ header("Date: " . date("D, j M Y G:i:s ", $templateModified) . 'GMT');
+ header("Content-Type: text/css");
+ header("Expires: " . gmdate("D, j M Y H:i:s", time() + DAY) . " GMT");
+ header("Cache-Control: cache"); // HTTP/1.1
+ header("Pragma: cache"); // HTTP/1.0
+ print $output;
+?>
diff --git a/site/app/webroot/css/admin.css b/site/app/webroot/css/admin.css
new file mode 100644
index 0000000..0c6b211
--- /dev/null
+++ b/site/app/webroot/css/admin.css
@@ -0,0 +1,67 @@
+/* admin/groups */
+div.groupItem {
+ border: 1px solid lightgray;
+ padding: 5px;
+ margin-bottom: 20px;
+ -moz-border-radius: 10px;
+}
+div.groupItem label {
+ margin-right: 10px;
+}
+
+/* autocomplete plugin */
+.ac_input {
+ width: 400px;
+}
+.ac_results {
+ padding: 0px;
+ border: 1px solid WindowFrame;
+ background-color: Window;
+ overflow-x: hidden;
+ overflow-y: auto;
+ max-height: 400px;
+}
+
+.ac_results ul {
+ width: 100%;
+ list-style-position: outside;
+ list-style: none;
+ padding: 0;
+ margin: 0;
+}
+
+.ac_results iframe {
+ display:none;/*sorry for IE5*/
+ display/**/:block;/*sorry for IE5*/
+ position:absolute;
+ top:0;
+ left:0;
+ z-index:-1;
+ filter:mask();
+ width:3000px;
+ height:3000px;
+}
+
+.ac_results li {
+ margin: 0px;
+ padding: 2px 5px;
+ cursor: pointer;
+ display: block;
+ width: 100%;
+ font: menu;
+ font-size: 12px;
+ overflow: hidden;
+}
+.ac_loading {
+ background : url('../img/ajax_loading.gif') right center no-repeat;
+}
+.ac_over {
+ background-color: Highlight;
+ color: HighlightText;
+}
+
+/* admin/addons */
+.version-date-created {
+ font-size: 80%;
+ color: #555;
+}
diff --git a/site/app/webroot/css/amo2009/ie.css b/site/app/webroot/css/amo2009/ie.css
new file mode 100644
index 0000000..55c2a85
--- /dev/null
+++ b/site/app/webroot/css/amo2009/ie.css
@@ -0,0 +1,53 @@
+/*
+Internet Explorer fixes
+Original Author: Richard Rutter, clearleft.com
+*/
+
+body {
+ font-size: 87.5%; /* assume 16px by default and transform to 14px */
+}
+
+form fieldset .container {
+ top: -0.692em; /* fudge to deal with IE fieldset margin/padding */
+}
+
+.button /* fixes buttons looking squiffy in IE7 */ {
+ display: block;
+ float: left;
+}
+
+#footer .secondary img {
+ width: auto;
+}
+
+.expanded-search-form .advanced {
+ padding-top: 1em;
+}
+
+/** Search form **/
+.search-form .basic {
+ min-height: 3em;
+}
+/** END Search form **/
+
+/** add-on details page **/
+.addon-cats li {
+ padding: 0 .5em;
+ margin: 0;
+ border-left: 1px solid #444;
+}
+.addon-cats li.first {
+ padding-left: 0;
+ border-left: none;
+}
+.addon-cats li:after {
+ content: "";
+}
+
+.highlight .more-info {
+ /* More categories links */
+ clear: left;
+ display: block;
+ float: none;
+}
+/** END add-on details page **/
diff --git a/site/app/webroot/css/amo2009/ie6.css b/site/app/webroot/css/amo2009/ie6.css
new file mode 100644
index 0000000..7418ef7
--- /dev/null
+++ b/site/app/webroot/css/amo2009/ie6.css
@@ -0,0 +1,25 @@
+#title img,
+img.scale {
+ behavior: url(iepngfix.htc);
+}
+
+.section,
+.column-wrapper,
+.article,
+.notification .aux,
+.highlight,
+.section-teaser .teaser-header,
+.section-teaser .prev,
+.section-teaser .next,
+ol.numbered li,
+.secondary-item-list,
+form.addon-feedback div.container,
+.listing-header,
+.listing-footer,
+.listing .item,
+.separated-listing .item,
+.object-lead,
+.object-lead .button-wrapper,
+.screenshot.thumbnail {
+ zoom:1;
+}
diff --git a/site/app/webroot/css/amo2009/ie7.css b/site/app/webroot/css/amo2009/ie7.css
new file mode 100644
index 0000000..6aed756
--- /dev/null
+++ b/site/app/webroot/css/amo2009/ie7.css
@@ -0,0 +1,3 @@
+.inverse .primary {
+ padding-top: 95px;
+}
diff --git a/site/app/webroot/css/amo2009/iepngfix.htc b/site/app/webroot/css/amo2009/iepngfix.htc
new file mode 100644
index 0000000..3d9c8b5
--- /dev/null
+++ b/site/app/webroot/css/amo2009/iepngfix.htc
@@ -0,0 +1,73 @@
+<public:component>
+<public:attach event="onpropertychange" onevent="doFix()" />
+
+<script type="text/javascript">
+
+// IE5.5+ PNG Alpha Fix v1.0RC4
+// (c) 2004-2005 Angus Turnbull http://www.twinhelix.com
+
+// This is licensed under the CC-GNU LGPL, version 2.1 or later.
+// For details, see: http://creativecommons.org/licenses/LGPL/2.1/
+
+
+// This must be a path to a blank image. That's all the configuration you need.
+if (typeof blankImg == 'undefined') {
+ var blankImg = '/img/blank.gif';
+}
+
+var f = 'DXImageTransform.Microsoft.AlphaImageLoader';
+
+function filt(s, m) {
+ if (filters[f]) {
+ filters[f].enabled = s ? true : false;
+ if (s) with (filters[f]) {
+ src = s;
+ sizingMethod = m;
+ }
+ } else if (s) {
+ style.filter = 'progid:'+f+'(src="'+s+'",sizingMethod="'+m+'")';
+ }
+}
+
+function doFix() {
+ // Assume IE7 is OK.
+ if (!/MSIE (5\.5|6\.)/.test(navigator.userAgent) || (event && !/(background|src)/.test(event.propertyName))) {
+ return;
+ }
+
+ var bgImg = currentStyle.backgroundImage || style.backgroundImage;
+
+ if (tagName == 'IMG' || tagName == 'INPUT') {
+ if ((/\.png$/i).test(src)) {
+ if (currentStyle.width == 'auto' && currentStyle.height == 'auto') {
+ style.width = offsetWidth + 'px';
+ }
+ filt(src, 'scale');
+ src = blankImg;
+ } else if (src.indexOf(blankImg) < 0) {
+ filt();
+ }
+ } else if (bgImg && bgImg != 'none') {
+ if (bgImg.match(/^url[("']+(.*\.png)[)"']+$/i)) {
+ var s = RegExp.$1;
+ if (currentStyle.width == 'auto' && currentStyle.height == 'auto') {
+ style.width = offsetWidth + 'px';
+ }
+ style.backgroundImage = 'none';
+ filt(s, 'crop');
+ // IE link fix.
+ for (var n = 0; n < childNodes.length; n++) {
+ if (childNodes[n].style) {
+ childNodes[n].style.position = 'relative';
+ }
+ }
+ } else {
+ filt();
+ }
+ }
+}
+
+doFix();
+
+</script>
+</public:component> \ No newline at end of file
diff --git a/site/app/webroot/css/amo2009/legacy.css b/site/app/webroot/css/amo2009/legacy.css
new file mode 100644
index 0000000..5f505c9
--- /dev/null
+++ b/site/app/webroot/css/amo2009/legacy.css
@@ -0,0 +1,7 @@
+/**
+ * Legacy CSS styles carried over from the pre-AMO-2009 theme.
+ */
+
+#nav-access {
+ display: none;
+}
diff --git a/site/app/webroot/css/amo2009/main-mozilla.css b/site/app/webroot/css/amo2009/main-mozilla.css
new file mode 100644
index 0000000..ea00ebc
--- /dev/null
+++ b/site/app/webroot/css/amo2009/main-mozilla.css
@@ -0,0 +1,2112 @@
+/**
+ * Mozilla-local tweaks to ClearLeft sourced main.css
+ */
+#header #title img {
+ height: 75px
+}
+.firefox #header #title strong {
+ color: #D64203;
+}
+
+.with-js .hide-with-js { display: none }
+.show-with-js { display: none }
+.with-js .show-with-js { display: block }
+.clearboth { clear: both; }
+
+/**
+ * This is a wtf I found on the collector_features page. If your page looks
+ * like
+ * <div class=primary />
+ * <div class=secondary />
+ * then the default clear: both on .secondary will put .secondary content
+ * *under* .primary, not beside. It works if you put the .secondary div first
+ * in your code, but that's wrong.
+ */
+.secondary {
+ clear: left;
+}
+
+.categories ul {
+ padding: 1em;
+}
+
+#search-query .query-label {
+ color: #000;
+ position: absolute;
+ left: 2.5em;
+ display: none;
+}
+.hasJS #search-query .query-label {
+ display: block;
+}
+
+.html-rtl #search-query .query-label {
+ left: auto;
+ right: 2.5em;
+}
+
+.primary.full,
+.secondary.full {
+ width: 100%;
+}
+
+/** addon listings */
+#addon-list-options ul {
+ float: none;
+ margin: 0 1em;
+}
+#addon-list-options ul li {
+ margin: 0 .5em;
+}
+#addon-list-options ul li.perpage {
+ float: right;
+}
+.html-rtl #addon-list-options ul li.perpage {
+ float: left;
+}
+#addon-list-options ul li.perpage div {
+ display: block;
+ line-height: 2em;
+}
+
+/**
+ * Fix for bug 494070. The default width is 50%. I'm assuming
+ * pagination will have most of the line, so we can give it more space.
+ * Only tested on collections listing and detail pages.
+ */
+ol.pagination {
+ width: 70%;
+}
+
+/* clearleft's category padding is 20px */
+li.sub-category {
+ padding-left:30px
+}
+
+.html-rtl li.sub-category {
+ padding-left: 0;
+ padding-right: 30px;
+}
+
+p.install-button {
+ margin: 0;
+}
+.experimental .install-container {
+ min-width: 10em;
+ margin: 0.3em;
+}
+.install strong.compatmsg {
+ padding-bottom: 0.5em;
+}
+.experimental .install .exp-confirm-install {
+}
+.experimental .install .exp-desc {
+}
+
+.teaser-items .item .install {
+ float: left;
+}
+
+.html-rtl .teaser-items .item .install {
+ float: right;
+}
+
+.section-teaser #t-mozilla_shopping {
+ background-image: url(../../img/amo2009/illustrations/shopping-online.jpg);
+}
+.html-rtl .section-teaser #t-mozilla_shopping {
+ background-image: url(../../img/amo2009/illustrations/shopping-online-rtl.jpg);
+}
+.section-teaser .item {
+ margin: 0;
+ padding-top: 1em;
+}
+
+.hasJS .section-teaser .teaser-header {
+ position: relative;
+}
+
+.hasJS .section-teaser .featured-inner {
+ padding-bottom: 3em;
+}
+
+.section-teaser .slideshow-controls {
+ margin:-38px 0 0;
+}
+.section-teaser .addon-view .column {
+ width: 31%;
+}
+.section-teaser .addon-view .lead {
+ padding-top: 1em;
+ margin-bottom: 1em;
+ margin-left: 4.5em;
+}
+.html-rtl .section-teaser .addon-view .lead {
+ margin-left: auto;
+ margin-right: 4.5em;
+}
+
+.section-teaser .addon-view h3 {
+ margin-bottom: 0.2em;
+}
+
+.section-teaser .teaser-header ol li {
+ margin-right: 3.4em;
+}
+
+.hasJS .section-teaser .window {
+ position: relative;
+}
+
+.hasJS .section-teaser .window .teaser-items {
+ position: absolute;
+}
+
+.html-rtl.hasJS .section-teaser .window ol.teaser-items {
+ direction: rtl;
+ left: auto;
+ right: 0;
+}
+
+.html-rtl .column {
+ float: right;
+ margin-left: 0;
+ margin-right: 2%;
+}
+.html-rtl .section-teaser .column {
+ border-left: none;
+ border-right: 1px dotted #A4CFDE;
+}
+.html-rtl .first {
+ margin-right: 0;
+}
+.html-rtl .section-teaser .first {
+ border-right: none;
+}
+.html-rtl .section-teaser .addon-view {
+ background-position: left bottom;
+}
+.html-rtl .section-teaser .addon-view .column {
+ border: none;
+ text-align: right;
+}
+.html-rtl .section-teaser .addon-view .column-inner {
+ padding-left: 0;
+ padding-right: 55px;
+}
+.html-rtl .section-teaser .column p, .html-rtl .section-teaser .column h3 {
+ margin-left: 0;
+ margin-right: 1em;
+}
+.html-rtl .section-teaser .column p.install-button {
+ margin-right: 0;
+}
+.html-rtl .section-teaser .teaser-header ol li {
+ margin-left: 5em;
+ margin-right: 0;
+ float: right;
+}
+.html-rtl .section-teaser .teaser-header ol li:last-child {
+ margin-left: 0;
+}
+.html-rtl .section-teaser .prev,
+.html-rtl .section-teaser .next {
+ right: auto;
+ left: 8px;
+ background-position: 0 0;
+}
+.html-rtl .section-teaser .prev {
+ left: auto;
+ right: 8px;
+ background-position: 0 -150px;
+}
+.html-rtl .section-teaser .active.next {
+ background-position: 0 -50px;
+}
+.html-rtl .section-teaser .active.prev {
+ background-position: 0 -200px;
+}
+.html-rtl .section-teaser .active.next:focus,
+.html-rtl .section-teaser .active.next:hover {
+ background-position: 0 -100px;
+}
+.html-rtl .section-teaser .active.prev:focus,
+.html-rtl .section-teaser .active.prev:hover {
+ background-position: 0 -250px;
+}
+
+/* Translation Box Element */
+.graybox {
+ background-color: #FAFDFE;
+ border: 1px solid #C8E8F3;
+ padding: 15px;
+}
+.graybox.errors {
+ background-color: #FFA5A5;
+}
+.graybox.spaced {
+ margin-bottom: 10px;
+}
+.rounded {
+ -moz-border-radius: 6px;
+ -webkit-border-radius: 6px;
+ border-radius: 6px;
+}
+.translation-box h4 {
+ border-bottom: 1px solid #2D3B58;
+}
+.translation-box h4 img {
+ float: right;
+ margin-top: 3px;
+}
+.html-rtl .translation-box h4 img {
+ float: left;
+}
+.translation-box .translation-button img {
+ cursor: pointer;
+ float: left;
+ background-color: #EEEEEE;
+ border: 1px solid #EEEEEE;
+ border-bottom: none;
+ padding: 2px 5px 3px;
+ margin: 5px 0 0 10px;
+ height: 1.5em;
+ -moz-border-radius-topleft: 6px;
+ -moz-border-radius-topright: 6px;
+ -webkit-border-top-left-radius: 6px;
+ -webkit-border-top-right-radius: 6px;
+}
+.html-rtl .translation-box .translation-button img {
+ float: right;
+ margin: 5px 10px 0 0;
+}
+.translation-box .translation-button.remove img {
+ float: right;
+}
+.html-rtl .translation-box .translation-button.remove img {
+ float: left;
+}
+.translation-box .translation-button img:hover {
+ background-color: #E4F3FA;
+}
+.translation-box .translation-tab {
+ float: left;
+ margin-right: 2px;
+ background-color: #DDDDDD;
+ text-align: center;
+ padding: 5px;
+ -moz-border-radius-topleft: 6px;
+ -moz-border-radius-topright: 6px;
+ -webkit-border-top-left-radius: 6px;
+ -webkit-border-top-right-radius: 6px;
+ width: 3.1em;
+ height: 1.5em;
+ cursor: pointer;
+ border-bottom: 1px solid #FFFFFF;
+}
+.html-rtl .translation-box .translation-tab {
+ float: right;
+ margin-right: auto;
+ margin-left: 2px;
+}
+.translation-box .translation-tab.selected {
+ border: 1px solid #1D587F;
+ background-color: #DDDDFF;
+ border-bottom: none;
+ color: #1D587F;
+}
+.translation-box .translation-tab:hover {
+ text-decoration: underline;
+}
+.translation-box .translation-area {
+ clear: both;
+ margin: 0;
+}
+.translation-box .translation-maxlength {
+ text-align: right;
+ display: none;
+}
+.html-rtl .translation-box .translation-maxlength {
+ text-align: left;
+}
+.translation-box .translation-maxlength.selected {
+ display: block;
+}
+.translation-box .translation-maxlength img {
+ display: none;
+}
+.translation-box .translation-maxlength.over {
+ color: #CC3333;
+}
+.translation-box .translation-maxlength.over img {
+ display: inline;
+ vertical-align: middle;
+}
+.translation-box .translation-maxlength span {
+ font-weight: bold;
+}
+.translation-box .input {
+ border: 1px solid #1D587F;
+ margin: 0;
+ -moz-border-radius-bottomleft: 6px;
+ -moz-border-radius-bottomright: 6px;
+ -webkit-border-bottom-left-radius: 6px;
+ -webkit-border-bottom-right-radius: 6px;
+ width: 100%;
+ display: none;
+}
+.translation-box .input.selected {
+ display: block;
+}
+.translation-newlocale-container,
+.translation-deletelocale-container,
+.translation-help-container,
+.translation-error-container {
+ display: none;
+}
+.translation-newlocale,
+.translation-deletelocale {
+ border: 1px solid #1D587F;
+ margin: 0;
+ -moz-border-radius-bottomleft: 6px;
+ -moz-border-radius-bottomright: 6px;
+ -webkit-border-bottom-left-radius: 6px;
+ -webkit-border-bottom-right-radius: 6px;
+ width: 100%;
+ height: 100px;
+ display: none;
+}
+.translation-deletelocale.textarea {
+ position: absolute;
+ z-index: 10;
+}
+.translation-newlocale.selected,
+.translation-deletelocale {
+ display: block;
+}
+.translation-newlocale .padded,
+.translation-deletelocale .padded,
+.translation-help .padded {
+ padding: 15px;
+}
+.translation-newlocale .buttons,
+.translation-deletelocale .buttons {
+ text-align: center;
+ margin: 10px;
+}
+.translation-help {
+ background-color: #FFFFFF;
+ margin-bottom: 10px;
+ width: 630px;
+ display: none;
+}
+.graybox .error-message {
+ background: transparent url('../../img/developers/exclamation.png') no-repeat 5px 50%;
+ color: red;
+ padding: 5px 0 5px 30px;
+}
+.html-rtl .graybox .error-message {
+ background-position: 100% 50%;
+ padding: 5px 25px 5px 0;
+}
+
+
+/** Notification Box Element */
+.notification-box {
+ display: block;
+ padding: 10px;
+ margin: 10px 0;
+ border: 1px solid #021437;
+ -moz-border-radius: 8px;
+ -webkit-border-radius: 8px;
+ border-radius: 8px;
+ background-color: #C8E8F3;
+}
+.notification-box.error {
+ border-color: #C63717;
+ background-color: #FFA5A5;
+}
+.notification-box h2 {
+ margin: 0;
+ padding: 10px 0 0 60px;
+ font-size: 130%;
+ line-height: 1.5em;
+ min-height: 38px;
+ color: #444444;
+ background: url(../../img/amo2009/notifications/sprite.png) no-repeat top left;
+}
+.html-rtl .notification-box h2 {
+ padding-left: 0;
+ padding-right: 60px;
+ background-position: top right;
+}
+.notification-box.notification h2 {
+ padding: 0;
+ min-height: 0;
+ background: none;
+}
+.notification-box.info h2 {
+ background-position: 0 -348px;
+}
+.html-rtl .notification-box.info h2 {
+ background-position: right -348px;
+}
+.notification-box.success h2 {
+ background-position: 0 -546px;
+}
+.html-rtl .notification-box.success h2 {
+ background-position: right -546px;
+}
+.notification-box.warning h2 {
+ background-position: 0 -744px;
+}
+.html-rtl .notification-box.warning h2 {
+ background-position: right -744px;
+}
+.notification-box.error h2 {
+ color: #C63717;
+ background-position: 0 -150px;
+}
+.html-rtl .notification-box.error h2 {
+ background-position: right -150px;
+}
+
+/** jQuery UI tabs */
+.ui-tabs-hide {
+ display: none !important;
+}
+.ui-tabs-nav {
+ list-style: none;
+ margin: 0;
+ padding: 0 0 0 3px;
+}
+.ui-tabs-nav:after { /* clearing without presentational markup, IE gets extra treatment */
+ display: block;
+ clear: both;
+ content: " ";
+}
+.ui-tabs-nav li {
+ float: left;
+ margin: 0 0 0 2px;
+ font-weight: bold;
+}
+.ui-tabs-nav a, .ui-tabs-nav a span {
+ float: left; /* fixes dir=ltr problem and other quirks IE */
+ padding: 0 12px;
+ background-color: #26395A;
+}
+.ui-tabs-nav a {
+ margin: 5px 0 0; /* position: relative makes opacity fail for disabled tab in IE */
+ padding-left: 0;
+ background-position: 100% 0;
+ text-decoration: none;
+ white-space: nowrap; /* @ IE 6 */
+ outline: 0; /* @ Firefox, prevent dotted border after click */
+}
+.ui-tabs-nav a:link, .ui-tabs-nav a:visited {
+ color: #fff;
+}
+.ui-tabs-nav .ui-tabs-selected a {
+ position: relative;
+ top: 1px;
+ z-index: 2;
+ margin-top: 0;
+ background-position: 100% -23px;
+}
+.ui-tabs-nav a span {
+ padding-top: 1px;
+ padding-right: 0;
+ height: 20px;
+ background-position: 0 0;
+ line-height: 20px;
+}
+.ui-tabs-nav .ui-tabs-selected a span {
+ padding-top: 0;
+ height: 27px;
+ background-position: 0 -23px;
+ line-height: 27px;
+}
+.ui-tabs-nav .ui-tabs-selected a:link, .ui-tabs-nav .ui-tabs-selected a:visited,
+.ui-tabs-nav .ui-tabs-disabled a:link, .ui-tabs-nav .ui-tabs-disabled a:visited { /* @ Opera, use pseudo classes otherwise it confuses cursor... */
+ cursor: text;
+}
+.ui-tabs-nav a:hover, .ui-tabs-nav a:focus, .ui-tabs-nav a:active,
+.ui-tabs-nav .ui-tabs-unselect a:hover, .ui-tabs-nav .ui-tabs-unselect a:focus, .ui-tabs-nav .ui-tabs-unselect a:active { /* @ Opera, we need to be explicit again here now... */
+ cursor: pointer;
+}
+.ui-tabs-disabled {
+ opacity: .4;
+ filter: alpha(opacity=40);
+}
+.ui-tabs-nav .ui-tabs-disabled a:link, .ui-tabs-nav .ui-tabs-disabled a:visited {
+ color: #000;
+}
+.ui-tabs-panel {
+ border: 1px solid #26395A;
+ padding: 10px;
+ _background: #fff; /* declare background color for container to avoid distorted fonts in IE while fading */
+}
+/*.ui-tabs-loading em {
+ padding: 0 0 0 20px;
+ background: url(loading.gif) no-repeat 0 50%;
+}*/
+/* Additional IE specific bug fixes... */
+* html .ui-tabs-nav { /* auto clear @ IE 6 & IE 7 Quirks Mode */
+ display: inline-block;
+}
+*:first-child+html .ui-tabs-nav { /* auto clear @ IE 7 Standards Mode - do not group selectors, otherwise IE 6 will ignore complete rule (because of the unknown + combinator)... */
+ display: inline-block;
+}
+
+
+/** Collections Pages */
+
+form.favourite button {
+ text-align: left;
+}
+
+.html-rtl form.favourite button {
+ text-align: right;
+}
+
+blockquote.publisher-comment {
+ border-left: 3px solid #C9E8F3;
+ margin-left: 2em;
+ padding-left: 1em;
+}
+blockquote.publisher-comment p {
+ margin: 0;
+}
+blockquote.publisher-comment p.by {
+ font-style: italic;
+}
+
+/* Collections Add and Edit: common styles */
+.collections-page .submit-button {
+ margin-top: 1em;
+}
+.collections-page .error_message {
+ color: red;
+ font-weight: bold;
+}
+
+/* Collections Add and Edit: add-on autocomplete */
+.collections-page .ac_input {
+ width: 400px;
+}
+.collections-page .ac_results {
+ padding: 0px;
+ border: 1px solid WindowFrame;
+ background-color: Window;
+ overflow-x: hidden;
+ overflow-y: auto;
+ max-height: 400px;
+}
+
+.collections-page .ac_results ul {
+ width: 100%;
+ list-style-position: outside;
+ list-style: none;
+ padding: 0;
+ margin: 0;
+}
+
+.collections-page .ac_results iframe {
+ display:none;/*sorry for IE5*/
+ display/**/:block;/*sorry for IE5*/
+ position:absolute;
+ top:0;
+ left:0;
+ z-index:-1;
+ filter:mask();
+ width:3000px;
+ height:3000px;
+}
+
+.collections-page .ac_results li {
+ margin: 0px;
+ padding: 2px 5px;
+ cursor: pointer;
+ display: block;
+ width: 100%;
+ font: menu;
+ font-size: 12px;
+ overflow: hidden;
+}
+.collections-page .ac_results li img {
+ margin-right: .5em;
+ vertical-align: middle;
+}
+.collections-page .ac_loading {
+ background-image: url('../../img/ajax_loading.gif');
+ background-position: right center;
+ background-repeat: no-repeat;
+}
+.collections-page .ac_over {
+ background-color: Highlight;
+ color: HighlightText;
+}
+
+/* Collections: "add" page */
+#collections-add #addonname {
+ width: 250px;
+}
+#collections-add #selectedaddons {
+ width: 80%;
+ overflow: auto;
+ max-height: 300px;
+}
+#collections-add #selectedaddons > ul {
+ -moz-column-count: 2;
+}
+#collections-add #selectedaddons ul li {
+ -moz-border-radius: 8px;
+ -webkit-border-radius: 8px;
+ border-radius: 8px;
+ line-height: 32px;
+ padding: 5px;
+}
+#collections-add #selectedaddons ul li.flash {
+ background-color: #C8E8F3;
+}
+#collections-add #selectedaddons ul li img {
+ vertical-align: middle;
+ margin-right: .5em;
+}
+
+#collections-add #firstaddons,
+#collections-add #selectedaddons {
+ display: none; /* shown with JS */
+}
+
+/* Collections: "edit" page */
+#collections-edit .jsonly {
+ display: none;
+}
+#collections-edit .error, #collections-edit .error_message {
+ color: #f00;
+}
+#collections-edit .coll-addon {
+ padding-bottom: 10px;
+ margin-bottom: 10px;
+ border-bottom: solid 1px #C8E8F3;
+}
+#collections-edit .coll-addon blockquote {
+ overflow-x: scroll;
+}
+
+#collections-edit .coll-addon img {
+ vertical-align:middle;
+ margin-right: .5em;
+}
+#collections-edit .coll-addon .name {
+ font-weight: bold;
+}
+#collections-edit .coll-addon .added {
+ float: right;
+ font-style: italic;
+}
+#collections-edit .coll-addon a.removeaddon {
+ float: right;
+}
+#collections-edit .coll-addon .editbox {
+ clear: both;
+}
+#collections-edit .coll-addon .editbox textarea {
+ margin-bottom: .5em;
+}
+#collections-edit input#submitbutton {
+ margin: 10px;
+}
+
+/** END collections pages */
+
+/** Collection add module **/
+.collections-add.prose {
+ margin: 0;
+}
+
+.collections-add.prose ul {
+ margin-left: 1em;
+}
+
+.collections-add.prose ul li {
+ margin-bottom: 0;
+}
+
+/** END Collection add module **/
+
+/** Add to collection module **/
+
+#publish_to {
+ width: 100%;
+}
+
+/** END add to collection module **/
+
+/* Search Pages */
+p.addon-search-message {
+ margin-top:2em;
+ color: #777777;
+ font-size: 180%;
+ font-weight: bold;
+ text-align:center;
+ padding-bottom: .5em;
+}
+/** END Search Pages */
+
+/** Add-on display page additions **/
+h2 span {
+ position:relative;
+ top: -0.35em;
+}
+
+h4.author {
+ position:relative;
+ left:51px;
+ top:-25px;
+ font-weight: normal;
+}
+
+.html-rtl h4.author {
+ left: auto;
+ right: 51px;
+}
+
+h4.author a {
+ font-weight: bold;
+}
+
+.hidden {
+ position: absolute;
+ top: -100000px;
+}
+
+.addon-cats {
+ margin: 0;
+}
+
+.addon-cats li {
+ display: inline;
+}
+
+.addon-cats li:after {
+ content: " | ";
+}
+
+.addon-cats li:last-child:after {
+ content: "";
+}
+
+#addon-summary {
+ margin-left: 240px;
+ position: relative;
+ min-height: 270px;
+ z-index: 101; /** prevents sharing network dropdown from showing up behind preview thumbnails **/
+}
+
+.html-rtl #addon-summary {
+ margin-left: 0;
+ margin-right: 240px;
+}
+
+#addon-summary.condensed {
+ margin-left: 5px;
+ min-height: 30px;
+}
+
+.html-rtl #addon-summary.condensed {
+ margin-left: 0;
+ margin-right: 5px;
+}
+
+#addon-summary .stats {
+ margin: 0;
+ float: none;
+ text-align: left;
+ color: #6FB727;
+}
+
+.html-rtl #addon-summary .stats {
+ text-align: right;
+}
+
+#addon-summary .stats em {
+ font-style: normal;
+ font-weight: bold;
+}
+
+.preview-img {
+ left:-260px;
+ padding:0 0 0 20px;
+ position:absolute;
+ top:0;
+}
+
+.html-rtl .preview-img {
+ left: auto;
+ right: -260px;
+ padding-left: 0;
+ padding-right: 20px;
+}
+
+.updated {
+ color: #666; /* evil */
+}
+
+#addon-summary .rating {
+ left:-240px;
+ top: 160px;
+ position: absolute;
+ font-weight: bold;
+}
+
+.html-rtl #addon-summary .rating {
+ left: auto;
+ right: -240px;
+}
+
+#addon-summary .share-this {
+ clear:left;
+ float:left;
+ left:-240px;
+ position:absolute;
+ width:200px;
+ top: 230px;
+}
+
+.html-rtl #addon-summary .share-this {
+ clear: right;
+ float: right;
+ left: auto;
+ right: -240px;
+}
+
+#addon-summary .stats {
+ position: absolute;
+ left: -240px;
+ top: 180px;
+}
+
+.html-rtl #addon-summary .stats {
+ left: auto;
+ right: -240px;
+}
+
+#addon-summary .install {
+ float: left;
+ text-align: center;
+ -webkit-border-radius: 11px;
+ -moz-border-radius: 11px;
+ border-radius: 11px;
+ padding: 0 3px 3px 3px;
+}
+
+.html-rtl #addon-summary .install {
+ float: right;
+}
+
+#addon-summary .unavailable {
+ border: 1px solid #D2E7EE;
+ padding: 0.3em;
+ width: 10em;
+ background-color: #FFFFFF;
+ color: #666666;
+}
+
+#addon-summary.rec .install {
+ background-color: #efe;
+ border: 1px solid #2a2;
+ padding-top:4px;
+ margin-bottom:3px;
+}
+
+#addon-summary.exp .install{
+ background-color: #fee;
+ border: 1px solid #f66;
+ padding-top:4px;
+ margin-bottom:3px;
+}
+
+#addon-summary .install strong {
+ display: block;
+ font-weight: normal;
+ font-size: 0.85em;
+ line-height: 1em;
+ color: #000;
+ text-shadow: #FFFFFF 1px 1px 1px;
+ clear: left;
+}
+
+.html-rtl #addon-summary .install strong {
+ clear: right;
+}
+
+.share-networks {
+ z-index: 100; /** prevents sharing network dropdown from showing up behind preview thumbnails **/
+}
+
+.featured h4 {
+ clear: both;
+}
+
+#addon-info .item {
+ padding: 1em;
+}
+
+#addon-info a {
+ font-weight: bold;
+}
+
+.app_compat ul {
+ margin: 0;
+}
+
+.prose ul li {
+ margin-left: 1em;
+}
+
+.html-rtl .prose ul li {
+ margin-left: 0;
+ margin-right: 1em;
+}
+
+.privacypolicy {
+ clear: both;
+ font-weight: bold;
+}
+
+.policy-link {
+ clear: both;
+}
+
+.highlight.collections-add p {
+ margin-bottom: 1em;
+}
+
+/* addons "old versions" page */
+#version-history .listing .item.oldversion {
+ padding-left: 1em;
+}
+
+#version-history .oldversion ul.legal li {
+ padding-left: 20px;
+}
+#version-history .oldversion ul.legal li.license {
+ background: url(../../img/amo2009/icons/script_code_red.png) left no-repeat;
+}
+#version-history .oldversion ul.legal li.source {
+ background: url(../../img/amo2009/icons/page_code.png) left no-repeat;
+}
+
+/* addons "source license" page */
+#version-license pre {
+ max-height: 400px;
+ overflow-y: scroll;
+ background-color: #fff;
+ padding: 1em 2em;
+ -moz-border-radius: 8px;
+}
+
+/** END Add-on display page additions **/
+
+/** Review box **/
+#form-review .login, #form-review h3 {
+ display: inline;
+}
+
+#form-review h4, #form-review .selectReplacement {
+ float: left;
+}
+
+.html-rtl #form-review h4, .html-rtl #form-review .selectReplacement {
+ float: right;
+}
+
+#form-review .selectReplacement, #form-review .stars {
+ margin: 4px 0 0 5px;
+ clear: none;
+}
+
+#form-review .stars {
+ margin: 1px 0 0 5px;
+ height: 12px;
+}
+
+.html-rtl #form-review .selectReplacement, .html-rtl #form-review .stars {
+ margin-left: 0;
+ margin-right: 5px;
+}
+
+#form-review a {
+ font-weight: bold;
+}
+
+#form-review button {
+ float: right;
+}
+
+.html-rtl #form-review button {
+ float: left;
+}
+
+#form-review p {
+ clear: both;
+}
+
+/** END Review box **/
+
+/** Highlight styles **/
+.highlight a {
+ font-weight: bold;
+}
+
+.highlight .prose {
+ margin: 0;
+}
+
+.highlight .other-author-addons {
+ padding: 1em 0 0 0;
+ margin: 0;
+ clear: left;
+ font-weight: normal;
+}
+.html-rtl .highlight .other-author-addons {
+ clear: right;
+}
+
+.highlight h3 label {
+ font-weight: normal;
+}
+
+/** END Highlight styles **/
+
+/** Category dropdown/search container tweaks **/
+
+.stand-alone-options {
+ z-index: 500; /** fixes issue with category dropdown menu appearing *behind* addon detail page images (stacking context bug) **/
+}
+
+/** END Category dropdown/search container tweaks **/
+
+/** Header tweaks **/
+#header {
+ z-index: 600;
+}
+
+/** END header tweaks **/
+
+/* Get Satisfaction widget */
+div#gsfn_list_widget img { border: none; }
+div#gsfn_list_widget { float:right; font-size: 12px; width: 250px; border: 6px solid #DDD; padding: 5px 5px 25px 20px; margin: 5px 5px 10px 10px;}
+div#gsfn_list_widget a.widget_title { color: #000; display: block; margin-bottom: 10px; font-weight: bold; }
+div#gsfn_list_widget .powered_by { margin-top: 8px; padding-top: 8px; border-top: 1px solid #DDD; }
+div#gsfn_list_widget .powered_by a { color: #333; font-size: 90%; }
+div#gsfn_list_widget div#gsfn_content { }
+div#gsfn_list_widget div#gsfn_content li { text-align:left; margin-bottom:6px; }
+div#gsfn_list_widget div#gsfn_content a.gsfn_link { line-height: 1; }
+div#gsfn_list_widget div#gsfn_content span.time { font-size: 90%; padding-left: 3px; }
+div#gsfn_list_widget div#gsfn_content p.gsfn_summary { margin-top: 2px }
+/** END Get Satisfaction widget */
+
+/* pages/submissionhelp */
+ul.submissionHelp li span.required {
+ font-weight: bold;
+}
+ul.submissionHelp li span.optional {
+ font-style: italic;
+}
+/* END pages/submissionhelp */
+
+/* pages/collector_firstrun */
+form.collector-firstrun-favorite, div.collector-firstrun-favorite {
+ margin-bottom: 1.5em;
+}
+div.collector-firstrun-favorite {
+ clear:both;
+}
+/* END pages/collector_firstrun */
+
+/* Plug-ins browse page */
+.item .baseline img.faq {margin: 0 5px 0 0; float: left;}
+.html-rtl .item .baseline img.faq {margin: 0 0 0 5px; float: right;}
+/* END Plug-ins browse page */
+
+
+/* =Reviews Page */
+
+.review .others-by-user { font-style: italic; display: block; margin-top: 0.5em; font-size: 0.85em }
+.review .others-by-user a { padding-left: 22px; }
+.review .others-by-user a.loading { background: transparent url(../../img/ajax_loading.gif) no-repeat 2px top }
+.review h2 { margin-bottom: 2px;}
+.review h3 { margin-bottom: 2px;}
+
+.review .hsession { display: inline; }
+.review .reviewed-on { font-size: .8em; margin: .4em 0; }
+
+.others-by-user-load { padding-left: 3em; }
+
+.review-reply { margin-left: 3em; }
+
+.review p.flag-thanks, .review-reply p.flag-thanks { font-weight: bold }
+.review form.flag, .review-reply form.flag { display: block; padding-bottom: 1em }
+.review form.flag label, .review-reply form.flag label { display: block; font-weight: bold }
+.review form.flag .error { color:#f00; }
+
+.with-js .review p.flag-thanks, .with-js .review-reply p.flag-thanks { display: inline }
+.with-js .review form.flag, .with-js .review-reply form.flag { display: inline }
+.with-js .review form.flag label, .with-js .review-reply form.flag label { display: none; }
+
+.review .flag span.loading, .review-reply .flag span.loading { padding-left: 22px; background: transparent url(../../img/ajax_loading.gif) no-repeat 2px top }
+
+/* END =Reviews Page */
+
+.html-rtl .new, .html-rtl .listing-header li {
+ unicode-bidi: embed;
+}
+
+.search-form .basic button img {
+ width: 9px;
+ height: 18px;
+ background-image: url(../../img/amo2009/icons/buttons/go-green.gif);
+}
+.html-rtl .search-form .basic button img {
+ background-image: url(../../img/amo2009/icons/buttons/go-green_rtl.gif);
+}
+
+.html-rtl #advanced-link {
+ right: auto;
+ left: 30px;
+}
+.html-rtl #advanced-link a:link,
+.html-rtl #advanced-link a:visited,
+.html-rtl #advanced-link a:hover,
+.html-rtl #advanced-link a:focus,
+.html-rtl #advanced-link a:active {
+ padding-left: 20px;
+ padding-right: 1em;
+ background-position: 5% -591px;
+}
+.html-rtl .expanded #advanced-link a:link,
+.html-rtl .expanded #advanced-link a:visited,
+.html-rtl .expanded #advanced-link a:hover,
+.html-rtl .expanded #advanced-link a:focus,
+.html-rtl .expanded #advanced-link a:active {
+ background-position: 5% -641px;
+}
+
+.html-rtl .meta .subscribers,
+.html-rtl .meta .addons {
+ float: right;
+}
+.html-rtl .item {
+ clear: right;
+}
+
+/* RTL support for the aux-nav box */
+.html-rtl #aux-nav p.context {
+ float: left;
+ padding-right: auto;
+ padding-left: 1em;
+ right: auto;
+ left: 0;
+}
+.html-rtl.hasJS #aux-nav ul {
+ float: left;
+ padding-right: auto;
+ padding-left: 1em;
+}
+.html-rtl #aux-nav span.greeting {
+ margin-right: auto;
+ margin-left: 1em;
+}
+.html-rtl #aux-nav .settings {
+ margin-right: auto;
+ margin-left: 1em;
+}
+.html-rtl #aux-nav ul.change {
+ padding: 0;
+}
+.html-rtl.hasJS #aux-nav ul.change {
+ background-position: top left;
+ border-right: none;
+ border-left: 3px solid transparent;
+}
+.html-rtl #aux-nav ul.change li {
+ margin-left: auto;
+ margin-right: 1em;
+}
+.html-rtl.hasJS #aux-nav ul.change li {
+ background-position: top right;
+ margin-left: 0;
+ margin-right: 0;
+}
+.html-rtl #aux-nav ul.change li li {
+ background-position: top right;
+}
+.html-rtl.hasJS #aux-nav .change li ul li {
+ text-align: right;
+}
+.html-rtl.hasJS #aux-nav .change li ul li a {
+ background-position: top right;
+ padding-left: 0.3em;
+ padding-right: 45px;
+}
+.html-rtl.hasJS #aux-nav .change li ul li.firefox a {
+ background-position: 95% 0;
+}
+.html-rtl.hasJS #aux-nav .change li ul li.thunderbird a {
+ background-position: 95% -50px;
+}
+.html-rtl.hasJS #aux-nav .change li ul li.sunbird a {
+ background-position: 95% -100px;
+}
+.html-rtl.hasJS #aux-nav .change li ul li.seamonkey a {
+ background-position: 95% -150px;
+}
+.html-rtl.hasJS #aux-nav ul.change a.controller:link,
+.html-rtl.hasJS #aux-nav ul.change a.controller:visited,
+.html-rtl.hasJS #aux-nav ul.change a.controller:focus,
+.html-rtl.hasJS #aux-nav ul.change a.controller:hover,
+.html-rtl.hasJS #aux-nav ul.change a.controller:active {
+ padding-left: 20px;
+ padding-right: 1em;
+ background-position: 5% -65px;
+}
+.html-rtl.hasJS #aux-nav ul.change a.controller:focus,
+.html-rtl.hasJS #aux-nav ul.change a.controller:hover,
+.html-rtl.hasJS #aux-nav ul.change a.controller:active {
+ background-position: 5% -105px;
+}
+.html-rtl.hasJS #aux-nav ul.change ul {
+ right: auto;
+ left: -3px;
+ border-right: none;
+ border-left: 3px solid #A2C2D7;
+}
+.html-rtl #aux-nav ul.tools {
+ padding: 0;
+}
+.html-rtl.hasJS #aux-nav ul.tools {
+ margin: 0;
+ border-right: none;
+ border-left: 3px solid transparent;
+}
+.html-rtl #aux-nav ul.tools li {
+ margin-left: auto;
+ margin-right: 1em;
+}
+.html-rtl.hasJS #aux-nav ul.tools li {
+ margin-left: auto;
+ margin-right: 0;
+}
+.html-rtl #aux-nav ul.tools li li {
+ background-position: top right;
+}
+.html-rtl.hasJS #aux-nav .tools li ul li {
+ text-align: right;
+ margin: 0;
+ padding-left: 0.3em;
+ padding-right: 1em;
+}
+.html-rtl.hasJS #aux-nav ul.tools a.controller:link,
+.html-rtl.hasJS #aux-nav ul.tools a.controller:visited,
+.html-rtl.hasJS #aux-nav ul.tools a.controller:focus,
+.html-rtl.hasJS #aux-nav ul.tools a.controller:hover,
+.html-rtl.hasJS #aux-nav ul.tools a.controller:active {
+ padding-left: 20px;
+ padding-right: 1em;
+ background-position: 5% -65px;
+}
+.html-rtl.hasJS #aux-nav ul.tools a.controller:focus,
+.html-rtl.hasJS #aux-nav ul.tools a.controller:hover,
+.html-rtl.hasJS #aux-nav ul.tools a.controller:active {
+ background-position: 5% -105px;
+}
+.html-rtl.hasJS #aux-nav ul.tools ul {
+ right: auto;
+ left: -3px;
+ border-right: none;
+ border-left: 3px solid #A2C2D7;
+}
+.html-rtl.hasJS #aux-nav ul.expanded {
+ border-right: none;
+ border-left: 3px solid #A2C2D7;
+}
+
+/** Frozen button styles **/
+.exp-loggedout .button.positive:link,
+.exp-loggedout .button.positive:visited,
+.exp-loggedout .button.positive:hover,
+.exp-loggedout .button.positive:active {
+ background: none #555;
+ border-color: #999;
+ cursor: default;
+ opacity: 0.3;
+ filter: (opacity=30);
+}
+
+.exp-loggedout .button.positive:link img,
+.exp-loggedout .button.positive:visited img,
+.exp-loggedout .button.positive:hover img,
+.exp-loggedout .button.positive:active img {
+ border-right: 1px solid #999;
+}
+
+/** END Frozen button styles **/
+
+/** Adding focus outline to buttons **/
+a:focus.button {
+ outline-color: #73B9FF;
+}
+
+a:focus.button.neutral {
+ outline-color: #E5A365;
+}
+
+a:focus.button.positive {
+ outline-color: #8CC553;
+}
+
+a:focus.button.negative {
+ outline-color: #EC7F82;
+}
+
+.item h3, .item h4 {
+ overflow: visible;
+}
+
+/** END Adding focus outlines to buttons **/
+
+
+/** Search form **/
+
+.html-rtl .search-form .basic input,
+.search-form .basic input {
+ text-indent: 0;
+ width: 40%;
+}
+
+.search-form .basic input {
+ padding-left: 2em;
+}
+
+.html-rtl .search-form .basic input {
+ padding-left: 0;
+ padding-right: 2em;
+}
+
+/** END Search form **/
+
+/** Installation instruction overlays (bug 495124) **/
+
+.item .install .app_install {
+ position: relative;
+ width: 1px;
+ margin: 0 auto;
+}
+
+.app_install-popup-container {
+ display: none;
+ position: relative;
+ width: 1px;
+ z-index: 1000;
+}
+
+.app_install-popup {
+ position: absolute;
+ left: -15em;
+ top: .5em;
+ width: 32em;
+ background: #fbfefb;
+ border: 4px solid #b4e4b4;
+ -webkit-border-radius: 5px;
+ -moz-border-radius: 5px;
+ border-radius: 5px;
+ text-align: left;
+}
+
+.html-rtl .app_install-popup {
+ text-align: right;
+}
+
+.app_install-popup-inner {
+ padding: 1em;
+ border: 1px solid #256350;
+ -webkit-border-radius: 3px;
+ -moz-border-radius: 3px;
+ border-radius: 3px;
+}
+
+.app_install-popup h3 {
+ margin-top: 0;
+}
+
+.app_install-popup ol,
+.app_install-popup p {
+ margin-top: 1.5em;
+ margin-bottom: 0;
+}
+
+.html-rtl .app_install-popup ol {
+ margin-left: 0;
+ margin-right: 2em;
+}
+
+.html-rtl .app_install-popup ol {
+ margin-top: 1.5em;
+ margin-bottom: 0;
+}
+
+.app_install-popup .close {
+ font-weight: bold;
+ text-align: right;
+}
+
+.html-rtl .app_install-popup .close {
+ text-align: left;
+}
+/** END Installation instruction overlays **/
+
+/** Advanced search form **/
+.expanded-search-form .advanced {
+ display: none;
+ padding: 1em;
+}
+
+.search-form fieldset {
+ margin: 0;
+}
+/** END Advanced search form **/
+
+/**
+ * Review add page styles.
+ */
+.review_add .stars {
+ /* override the general .stars style in main.css */
+ background: transparent;
+ float: none;
+ margin: 0;
+ text-indent: 0;
+ width: auto;
+}
+
+.review_add .review-body-label {
+}
+.review_add #ReviewBody {
+ width: 65%;
+}
+
+.stars input {
+ margin: 0 4px;
+}
+
+.stars {
+ zoom:1;
+}
+
+.stars .cancel,
+.stars .star{
+ float: left;
+ width: 12px;
+ height: 14px;
+ overflow: hidden;
+ text-indent: -999em;
+ cursor: pointer;
+}
+
+.html-rtl .stars .star,
+.html-rtl .stars .cancel {
+ float:right;
+}
+
+.stars .cancel a,
+.stars .cancel a {
+ background: url(../../img/ratings_images.gif) no-repeat;
+}
+
+.stars .star a,
+.stars .star a {
+ background: url(../../img/ratings_images.gif) no-repeat;
+}
+
+.stars.cancel a,
+.stars .star a,
+.stars .cancel a,
+.stars .star a {
+ display: block;
+ width: 100%;
+ height: 100%;
+ background-position: 0 -25px;
+ border:1 solid #FF0000;
+}
+
+.stars .cancel a,
+.stars.cancel a {
+ background-position: 0 2px;
+}
+
+.stars div.star_hover a,
+.stars div.star_hover a {
+ background-position: 0 -38px;
+}
+
+.stars div.cancel_on a,
+.stars div.cancel_on a {
+ background-position: 0 -11px;
+}
+
+.stars div.star_on a,
+.stars div.star_on a {
+ background-position: 0 -38px;
+}
+
+.stars:after {
+ content:".";clear:both;display:block;visibility:hidden;height:0;overflow:hidden;
+}
+
+/**
+ * Category landing page styles.
+ */
+.category_landing .search-form {
+ margin-bottom: 0;
+}
+.category_landing .primary {
+ width: 100%;
+}
+.category_landing .primary h2 {
+}
+.category_landing #footer .primary {
+ width: 73.47%;
+}
+#featured_addons {
+ z-index: 2;
+ position: relative;
+}
+#featured_addons ul {
+ list-style-type: none;
+ margin: 0; padding: 0;
+}
+#featured_addons ul li {
+ display: block;
+ float: left;
+ margin: 0; padding: 0 8px 8px 0;
+}
+.html-rtl #featured_addons ul li {
+ float: right;
+ padding: 0 0 8px 8px;
+}
+#featured_addons ul li.addon_block_wrapper {
+ width: 32%;
+}
+#featured_addons ul li div.item {
+ margin: 0;
+ padding: 0;
+}
+#featured_addons ul li div.item .unavailable {
+ width: 90%;
+}
+#featured_addons ul li div.addon_block
+{
+ display: block;
+ position: relative;
+ background: #f9f9f9 url(../../img/sprite.png?20090430) no-repeat scroll left -968px;
+ width: 100%;
+ height: 200px;
+ overflow: hidden;
+ border: 1px solid #ececec;
+ -moz-border-radius-topleft: 8px;
+ -moz-border-radius-topright: 8px;
+ -moz-border-radius-bottomleft: 8px;
+ -moz-border-radius-bottomright: 8px;
+ -webkit-border-top-left-radius: 8px;
+ -webkit-border-top-right-radius: 8px;
+ -webkit-border-bottom-left-radius: 8px;
+ -webkit-border-bottom-right-radius: 8px;
+ border-top-right-radius: 8px;
+ border-top-left-radius: 8px;
+ border-bottom-right-radius: 8px;
+ border-bottom-left-radius: 8px;
+ padding: 0 0 0 0px;
+}
+#featured_addons ul li div.addon_block .name {
+ font-size: 138%;
+ margin: 8px 155px 0px 0;
+ padding: 0 0 0 8px;
+ line-height: 1.25em;
+}
+.html-rtl #featured_addons ul li div.addon_block .name {
+ margin: 8px 0 0 155px;
+ padding: 0 8px 0 0;
+}
+#featured_addons ul li div.addon_block .name a {
+ color: black;
+ text-decoration: none;
+}
+
+#featured_addons ul li div.addon_block .preview {
+ position: absolute;
+ top: 8px; right: 9px;
+}
+.html-rtl #featured_addons ul li div.addon_block .preview {
+ right: auto;
+ left: 9px;
+}
+#featured_addons ul li div.addon_block .preview img {
+ width: 138px;
+}
+
+#featured_addons ul li div.addon_block .summary {
+ font-size: 93%;
+ line-height: 1.5em;
+ margin: 0px 149px 0px 0px;
+ padding: 0 0 0 8px;
+ max-height: 4.5em;
+ overflow: hidden;
+}
+.html-rtl #featured_addons ul li div.addon_block .summary {
+ margin: 0 0 0 149px;
+ padding: 0 8px 0 0;
+}
+
+#featured_addons ul li div.addon_block .authors {
+ font-size: 100%;
+ line-height: 1.5em;
+ margin: 0 145px 0 0;
+ padding: 0 0 0 8px;
+ color: #2363a5;
+}
+.html-rtl #featured_addons ul li div.addon_block .authors {
+ margin: 0 0 0 145px;
+ padding: 0 8px 0 0;
+}
+#featured_addons ul li div.addon_block .authors a {
+ text-decoration: none;
+}
+#featured_addons ul li div.addon_block .rating {
+ font-size: 10px;
+ overflow: hidden;
+ margin: 2px 0 0 0;
+ padding: 0 0 0 8px;
+}
+.html-rtl #featured_addons ul li div.addon_block .rating {
+ padding: 0 8px 0 0;
+}
+.rating span {
+ display: block;
+ background: transparent url(../../img/ratings/5stars.png) no-repeat scroll top left;
+ width: 68px; height: 12px;
+ text-indent: -1000em;
+}
+.rating .stars-1 {
+ background-image: url(../../img/ratings/1stars.png)
+}
+.rating .stars-2 {
+ background-image: url(../../img/ratings/2stars.png)
+}
+.rating .stars-3 {
+ background-image: url(../../img/ratings/3stars.png)
+}
+.rating .stars-4 {
+ background-image: url(../../img/ratings/4stars.png)
+}
+.rating .stars-5 {
+ background-image: url(../../img/ratings/5stars.png)
+}
+
+
+#featured_addons div.addon_block .install-container {
+ position: absolute;
+ left: 7px;
+ bottom: 7px;
+}
+.html-rtl #featured_addons div.addon_block .install-container {
+ left: auto;
+ right: 7px;
+}
+.category_landing .primary div.addons_column {
+ float: left;
+ padding: 0 9px 8px 0;
+ width: 32%;
+}
+.html-rtl .category_landing .primary div.addons_column {
+ float: right;
+ padding: 0 0 8px 9px;
+}
+
+.category_landing .primary div.addons_column.last {
+ float: left;
+ padding: 0 0 8px 0;
+}
+.html-rtl .category_landing .primary div.addons_column.last {
+ float: right;
+}
+
+.category_landing .primary div.addons_column h3 {
+ background: #acacac;
+ -moz-border-radius-topleft: 8px;
+ -moz-border-radius-topright: 8px;
+ -webkit-border-top-left-radius: 8px;
+ -webkit-border-top-right-radius: 8px;
+ border-top-right-radius: 8px;
+ border-top-left-radius: 8px;
+ margin: 0px;
+ font-family: "Trebuchet MS",Helvetica,"Helvetica Neue",Arial,sans-serif;
+ line-height: 1.6em;
+}
+.category_landing .primary div.addons_column h3 span {
+ padding: 0 8px 0 8px;
+ text-transform: uppercase;
+ font-size: 14px;
+ color: #fff;
+ font-weight: bold;
+}
+.category_landing .primary div.addons_column ul {
+ list-style: none;
+ margin: 0;
+ padding: 0;
+}
+.category_landing .primary div.addons_column ul li {
+ position: relative;
+ border-left: 1px solid #c9c8c9;
+ border-right: 1px solid #c9c8c9;
+ margin: 0;
+
+}
+.category_landing .primary div.addons_column ul li.odd {
+}
+.category_landing .primary div.addons_column ul li.even {
+ background: #f0efef;
+}
+.category_landing .primary div.addons_column ul li a {
+ height: 50px;
+ display: block;
+ text-decoration: none;
+ border: 1px solid transparent;
+ background: transparent url(../../img/sprite.png?20090602) no-repeat scroll right -2001px;
+}
+.html-rtl .category_landing .primary div.addons_column ul li a {
+ background-position: -363px -558px;
+}
+.category_landing .primary div.addons_column ul li a:hover {
+ border-top: 1px solid #000;
+ border-left: 1px solid #000;
+ border-bottom: 1px solid #000;
+ background: transparent url(../../img/sprite.png?20090602) no-repeat scroll right -2051px;
+}
+.html-rtl .category_landing .primary div.addons_column ul li a:hover {
+ border-left: 1px solid transparent;
+ border-right: 1px solid #000;
+ background-position: -363px -670px;
+}
+.category_landing .primary div.addons_column ul li a img.icon {
+ position: absolute;
+ top: 6px; left: 6px;
+}
+.html-rtl .category_landing .primary div.addons_column ul li a img.icon {
+ left: auto;
+ right: 6px;
+}
+.category_landing .primary div.addons_column ul li a .name {
+ display: block;
+ padding: 4px 15px 0 0;
+ margin-left: 52px;
+ color: #000;
+ font-size: 116%;
+ line-height: 1.25em;
+ height: 1.25em;
+ overflow: hidden;
+}
+.html-rtl .category_landing .primary div.addons_column ul li a .name {
+ padding: 4px 0 0 15px;
+ margin-left: 0;
+ margin-right: 52px;
+}
+
+.category_landing .primary div.addons_column ul li a .rating {
+ margin-left: 42px;
+ padding: 0 0 4px 0;
+ display: block;
+}
+.html-rtl .category_landing .primary div.addons_column ul li a .rating {
+ margin-left: 0;
+ margin-right: 42px;
+ padding: 0 8px 0 0;
+}
+
+.category_landing .primary div.addons_column ul li a .meta {
+ display: block;
+ margin-left: 52px;
+ font-size: 93%;
+ color: #777;
+ position: absolute;
+ bottom: 6px;
+}
+.html-rtl .category_landing .primary div.addons_column ul li a .meta {
+ margin-left: 0;
+ margin-right: 52px;
+}
+
+.category_landing .primary div.addons_column .view-all {
+ color: #fff;
+ font-weight: bold;
+ background: #acacac;
+ -moz-border-radius-bottomleft: 8px;
+ -moz-border-radius-bottomright: 8px;
+ -webkit-border-bottom-left-radius: 8px;
+ -webkit-border-bottom-right-radius: 8px;
+ border-bottom-right-radius: 8px;
+ border-bottom-left-radius: 8px;
+ padding: 2px 0 2px 9px;
+
+}
+.html-rtl .category_landing .primary div.addons_column .view-all {
+ padding: 2px 9px 2px 0;
+}
+
+.category_landing .primary div.addons_column .view-all a:link,
+.category_landing .primary div.addons_column .view-all a:visited,
+.category_landing .primary div.addons_column .view-all a:hover,
+.category_landing .primary div.addons_column .view-all a:active {
+ color: #fff;
+ text-decoration: none;
+ font-size: 93%;
+}
+
+.category_landing .primary div.addons_column .view-all a:hover {
+ text-decoration: underline;
+}
+
+.clearfix:after {
+ content: ".";
+ display: block;
+ clear: both;
+ visibility: hidden;
+ line-height: 0;
+ height: 0;
+}
+
+.clearfix {
+ display: inline-block;
+}
+
+html[xmlns] .clearfix {
+ display: block;
+}
+
+* html .clearfix {
+ height: 1%;
+}
+
+/* Modal collection subscription box, based on jqModal styling. */
+.modal-subscription {
+ display: none;
+ position: fixed;
+ top: 17%;
+ left: 50%;
+ margin-left: -20em;
+ width: 40em;
+}
+
+/* Turn off notification box colors. */
+.modal-subscription .notification-box {
+ background: none;
+ border: none;
+}
+
+/* The long description. */
+.modal-subscription .notification-box div {
+ margin-left: 60px; /* the offset from the icon */
+ padding-bottom: .5em;
+ border-bottom: 2px dotted #b4dfee;
+}
+
+/* The short message. */
+.modal-subscription .notification-box h2 {
+ margin-bottom: 0.5em;
+}
+
+.modal-subscription .footer {
+ margin-left: 5.3em; /* offset to match the text indent */
+ margin-top: -0.5em;
+}
+
+.modal-subscription .bother {
+ float: right;
+ padding-right: 10px; /* matches the notification element */
+}
+
+.modal-subscription .bother label {
+ font-weight: normal;
+}
+
+.jqmOverlay {
+ background-color: #000;
+}
+
+/** END Modal collection box. */
+
+/*** =Dictionaries ***/
+#dictionaries { background-color: #f7fafc; border: 1px solid #eef1f3; -moz-border-radius: 6px; -webkit-border-radius: 6px; border-radius: 6px; }
+#dictionaries th, #dictionaries td { border-bottom: 1px solid #eee; }
+#dictionaries tbody tr.alt th, #dictionaries tbody tr.alt td { background-color: #fff; }
+#dictionaries { clear: both; padding: 10px 15px; }
+#dictionaries table { width: 100%; }
+#dictionaries th, #dictionaries td { padding: 6px 12px; }
+#dictionaries tbody th { font-weight: bold; }
+/*** END =Dictionaries ***/
+
+/* Search engines & Themes Landing pages */
+.secondary h3.compact {
+ margin-bottom: 12px;
+}
+.compact {
+ margin: 0px;
+}
+/* END Search engines & Themes Landing pages */
+
+/** Footer language selector **/
+#language {
+ margin: 0 0.5em 0 0;
+}
+/** END Footer language selector **/
+
+/*** =Browse Thumbs ***/
+.browse_thumbs .primary h2 {
+ margin-bottom: 0;
+}
+.browse_thumbs .primary h3 {
+ margin-top: 0;
+}
+.browse_thumbs .featured {
+ background: transparent;
+}
+.browse_thumbs ul.thumbs {
+ margin: 0;
+ padding: 0;
+}
+.browse_thumbs ul.thumbs li.thumb {
+ width: 24.5%;
+ float: left;
+}
+.browse_thumbs ul.thumbs li.thumb div.thumb_item {
+ display: block;
+ position: relative;
+ margin: 6px 4px 6px 4px;
+ background: #f9f9f9 url(../../img/sprite.png?20090430) no-repeat scroll left -968px;
+ height: 220px;
+ overflow: hidden;
+ border: 1px solid #ececec;
+ -moz-border-radius-topleft: 8px;
+ -moz-border-radius-topright: 8px;
+ -moz-border-radius-bottomleft: 8px;
+ -moz-border-radius-bottomright: 8px;
+ -webkit-border-top-left-radius: 8px;
+ -webkit-border-top-right-radius: 8px;
+ -webkit-border-bottom-left-radius: 8px;
+ -webkit-border-bottom-right-radius: 8px;
+ border-top-right-radius: 8px;
+ border-top-left-radius: 8px;
+ border-bottom-right-radius: 8px;
+ border-bottom-left-radius: 8px;
+ padding: 0 0 0 0px;
+}
+.browse_thumbs ul.thumbs li.thumb .flag {
+ position: absolute;
+ top: 2px;
+ left: 8px;
+ padding: 0px;
+ font-size: 80%;
+}
+.html-rtl .browse_thumbs ul.thumbs li.thumb .flag {
+ left: auto;
+ right: 8px;
+}
+.browse_thumbs ul.thumbs li.rec div.thumb_item .flag {
+}
+.browse_thumbs ul.thumbs li.rec div.thumb_item .flag a {
+ color: #360;
+}
+.browse_thumbs ul.thumbs li.rec div.thumb_item {
+ background-color: #efe;
+}
+.browse_thumbs ul.thumbs li.exp div.thumb_item .flag {
+}
+.browse_thumbs ul.thumbs li.exp div.thumb_item .flag a {
+ color: #900;
+}
+.browse_thumbs ul.thumbs li.exp div.thumb_item {
+ background-color: #fee;
+}
+.browse_thumbs ul.thumbs li.thumb .name {
+ margin: 8px 0px 0px 0;
+ padding: 0 0 0 8px;
+ line-height: 1.25em;
+ margin: 0; padding: 0;
+ position: absolute;
+ bottom: 2em;
+ left: 10px;
+}
+.html-rtl .browse_thumbs ul.thumbs li.thumb .name {
+ left: auto;
+ right: 10px;
+}
+.browse_thumbs ul.thumbs li.thumb .name a {
+ color: #000;
+}
+.browse_thumbs ul.thumbs li.thumb .meta {
+ margin: 0; padding: 0;
+ font-size: 93%;
+ color: #777;
+ position: absolute;
+ bottom: 4px;
+ left: 10px;
+}
+.html-rtl .browse_thumbs ul.thumbs li.thumb .meta {
+ left: auto;
+ right: 10px;
+}
+.browse_thumbs ul.thumbs li.thumb div.thumb_item .img {
+ text-align: center;
+ border:1px solid #CCCCCC;
+ margin: 1.5em 8px 0 8px;
+ overflow: hidden;
+}
+.browse_thumbs ul.thumbs li.thumb div.thumb_item .img img {
+ height: 135px;
+}
+.browse_thumbs .search-form {
+ margin-bottom: 0;
+}
+.browse_thumbs .secondary {
+ clear: both;
+}
+.browse_thumbs .subcategories li {
+ margin: 0.2em;
+}
+.browse_thumbs .subcategories li.sub {
+ margin-left: 1em;
+}
+.browse_thumbs .subcategories li.selected {
+ -moz-border-radius: 3px;
+ -webkit-border-radius: 3px;
+ border-radius: 3px;
+ border: 1px solid #001133;
+ background-color: #223355;
+ padding: 0 3px 0 3px;
+}
+.browse_thumbs .subcategories li.selected a {
+ color: #fff;
+}
+.subcategories .items {
+ color: white;
+ background-color: #94BFCE;
+ -moz-border-radius: 7px;
+ -webkit-border-radius: 7px;
+ border-radius: 7px;
+ margin-left: 0.1em;
+ padding: 1px 5px;
+ font-size: 0.856em;
+ font-weight: normal;
+}
+/*** END =Browse Thumbs ***/
diff --git a/site/app/webroot/css/amo2009/main.css b/site/app/webroot/css/amo2009/main.css
new file mode 100644
index 0000000..14efb64
--- /dev/null
+++ b/site/app/webroot/css/amo2009/main.css
@@ -0,0 +1,4049 @@
+/* @group General styles */
+/*
+Harmonise v1.3
+Resets styles then adds basic typographical styling.
+Use as a starting point upon which to build more CSS.
+By Clearleft.com
+*/
+
+/* @group Reset */
+
+/* Based on http://meyerweb.com/eric/tools/css/reset/ */
+/* v1.0 | 20080212 */
+
+html, body, div, span, applet, object, iframe,
+h1, h2, h3, h4, h5, h6, p, blockquote, pre,
+a, abbr, acronym, address, big, cite, code,
+del, dfn, em, font, img, ins, kbd, q, s, samp,
+small, strike, strong, sub, sup, tt, var,
+b, u, i, center,
+dl, dt, dd, ol, ul, li,
+fieldset, form, label, legend,
+table, caption, tbody, tfoot, thead, tr, th, td {
+ margin: 0;
+ padding: 0;
+ border: 0;
+ font-size: 100%;
+ vertical-align: baseline;
+ background: transparent;
+}
+
+ul {
+ list-style: none;
+}
+blockquote, q {
+ quotes: none;
+}
+blockquote:before, blockquote:after,
+q:before, q:after {
+ content: '';
+ content: none;
+}
+
+/* tables may still need 'cellspacing="0"' in the markup */
+table {
+ border-collapse: collapse;
+ border-spacing: 0;
+}
+
+/* @end */
+
+html {
+ background-color: #fafdfe;
+ background-image: url(../../img/amo2009/bg/body.jpg);
+ background-position: top center;
+ background-repeat: no-repeat;
+}
+
+body {
+ margin: 0 auto;
+ color:#444444;
+ font-size:13px;
+ line-height:1.538em; /* Baseline grid of 20px */
+ background-image: url(../../img/amo2009/bg/header-border.png);
+ background-repeat: repeat-x;
+ background-position: top left;
+ position: relative;
+ min-width: 780px;
+}
+
+/* for pages without a header or footer */
+body.min {
+ background-image: none;
+ padding-top: 3em;
+ padding-bottom: 2em;
+}
+
+a:link,
+button.link span {
+ color: #0055EE;
+ text-decoration: none;
+}
+a:visited {
+ color: #003595;
+ text-decoration: none;
+}
+a:hover,
+a:focus,
+button.link:hover,
+button.link:focus span {
+ color: #003595;
+ text-decoration: underline;
+}
+a:active,
+button.link:active span {
+ color: #003595;
+ text-decoration: underline;
+}
+
+/* @group Font families */
+
+body,
+#title,
+.categories h3,
+.item h3,
+.section-teaser .addon-view h3 {
+ font-family: "helvetica neue", arial, helvetica, sans-serif;
+}
+
+h2,
+h3,
+#title em,
+.highlight h2,
+.highlight h3,
+.stats strong,
+h4.step {
+ font-family: georgia, serif;
+}
+
+pre, code, kbd, tt, samp, tt {
+ font-family: "andale mono", monospace;
+}
+
+/* @end */
+
+/* @group Headings */
+
+/* size headings using classic scale of 16, 18, 24, 36 */
+
+h1 {
+ font-size: 2.571em /* 36px */;
+ line-height:1em /* 36px */;
+ margin-top:0.1667em /* 6px */;
+ margin-bottom:0.5833em /* 21px */;
+}
+h2 {
+ font-size:2.154em /* 28px */;
+ font-weight:normal;
+ line-height:1em /* 28px */;
+ margin-top:0.5em /* 42px */;
+ margin-bottom:0.5em /* 14px */;
+ color:#C63717;
+}
+h3 {
+ color:#011234;
+ font-size:1.385em /* 18px */;
+ font-weight:normal;
+ line-height:1.111em /* 20px */;
+ margin-top:1.556em /* 28px */;
+ margin-bottom:0.778em /* 14px */;
+}
+h4 {
+ color:#223355;
+ font-size:1em /* 13px */;
+}
+h5, h6 {
+ font-size:1em /* 13px */;
+}
+
+/* @end */
+
+/* @group Lists */
+
+.prose ul,
+ul.xoxo,
+ul.xoxo ul {
+/* unordered lists more often DON'T require bullets except in extended bits of writing. Where bullets are required apply the .prose class to a container, or apply directly with .xoxo */
+ list-style-type: square;
+ margin-left: 1.5em; /* 21px */
+}
+
+.prose ul li,
+ul.xoxo li,
+ul.xoxo ul li {
+ margin-bottom: 0.5em;
+}
+
+ol { /* ordered lists usually DO require (numbered) bullets */
+ list-style-type: decimal;
+ margin-left: 2em; /* 26px */
+}
+
+dt {
+ font-weight: bold;
+ margin-top: 1.5em; /* 19.5px */
+}
+
+ul ul, ol ol, ol ul, ul ol {
+ margin-bottom: 0;
+}
+
+/* @end */
+
+/* @group Tables */
+
+table {
+ border-bottom: 1px solid #666;
+}
+
+caption {
+ font-weight: bold;
+ padding-bottom: 0.539em; /* 7px */
+ font-size:1.231em; /* 16px */
+}
+
+thead th {
+ border-top: 1px solid #666;
+ border-bottom: 3px solid #666;
+ padding-top: 0;
+ padding-bottom: 0.539em; /* 7px */
+}
+
+tbody {
+ border-top: 3px solid #666; /* not rendered in IE6/7 */
+}
+
+tbody tr th, tbody tr td {
+ border-top: 1px solid #ddd;
+}
+
+th, td {
+ text-align: left;
+ padding: 0.308em 0.537em 0.214em 0.231em; /* 4px 7px 3px 7px */
+}
+
+/* @end */
+
+/* @group Blockquotes */
+
+blockquote {
+ font-style: italic;
+ margin:0 1.5em 1.5em 1.5em; /* 19.5px */
+}
+
+p+p+blockquote {
+ margin-top: 1.5em /* 19.5px */;
+}
+
+blockquote cite, blockquote em {
+ font-style: normal;
+}
+
+/* @end */
+
+/* @group Other styling */
+
+p, ul, ol, dl, address, table, pre, form, fieldset {
+ font-size: 1em /* 14px */;
+ margin-bottom: 1.5em; /* 21px */
+}
+
+address {
+ font-style: normal;
+}
+
+ins {
+ text-decoration: underline;
+}
+
+del {
+ text-decoration: line-through;
+}
+
+/* @end */
+
+
+/* @end */
+
+/* @group Helper styles */
+
+/* @group Forms */
+
+/* @group Containers */
+
+form .container {
+ margin-bottom: 1.5em; /* 19.5px */
+}
+
+
+/* @group Fieldsets */
+
+fieldset {
+ border: 1px solid #ccc;
+ padding: 0 1.5em 1em 1.5em; /* 0 19.5px 13px 19.5px */
+}
+
+legend {
+ font-weight: bold;
+}
+
+form fieldset .container {
+ margin-top: 1em; /* 13px */
+ margin-bottom:0;
+ position: relative;
+}
+
+/* @end */
+
+/* @end */
+
+/* @group Labels */
+
+label {
+ font-weight: bold;
+ cursor: pointer;
+}
+
+.meta-label {
+ font-weight: bold;
+ margin-bottom: 0;
+}
+
+.multi-container label,
+.radio-container label,
+.checkbox-container label {
+ font-weight: normal;
+}
+
+.radio-container label,
+.checkbox-container label {
+ display: block;
+}
+
+.compact label {
+ display: inline;
+}
+
+/* @end */
+
+/* @group Meta */
+
+form .help {
+ display: block;
+ color: #777;
+ font-style: normal;
+ font-size: 0.923em; /* 12px */
+}
+
+/* @end */
+
+/* @group Form controls */
+
+input, textarea, select, button {
+ font-family: inherit;
+ font-size: 1em;
+ line-height: inherit;
+}
+
+select {
+ background-color: #fff; /* fixes bug in Opera which inherits bgcolor from container */
+}
+
+
+button {
+ overflow: visible;
+ cursor: pointer;
+}
+
+textarea,
+input[type='text'],
+input[type='password'],
+select {
+ border-width: 1px;
+ border-style: solid;
+ border-top-color: #999;
+ border-left-color: #999;
+ border-bottom-color: #ccc;
+ border-right-color: #ccc;
+ padding: 0 1px 1px 1px;
+}
+
+textarea:focus,
+input[type='text']:focus,
+input[type='password']:focus,
+select:focus {
+ border-color: #888;
+ outline: 1px solid #ffffaa;
+}
+
+input.short {
+ width: 4em;
+}
+
+input.medium, textarea.medium {
+ width: 12em;
+}
+
+input.long, textarea.long {
+ width: 30em;
+}
+
+textarea {
+ width: 99%;
+ display: block;
+}
+
+.button-container input {
+ font-weight: bold;
+}
+
+.button-container input.cancel {
+ font-weight: normal;
+}
+
+button.link {
+ border: 0;
+ padding: 0;
+ background-color: #fff;
+ font-weight: normal;
+ cursor: pointer;
+ width: auto;
+ overflow: visible;
+}
+
+/* accessibility feature, resize check and radio inputs */
+.radio-container input,
+.checkbox-container input {
+ width: 1em;
+ height: 1em;
+}
+
+/* @end */
+
+/* @end */
+
+/* @group Stars */
+
+.stars {
+ text-indent:-5000px;
+ background-image: url(../../img/amo2009/icons/stars.png);
+ background-position: 0 50%;
+ background-repeat: no-repeat;
+ margin-right: 0.5em;
+ width: 63px;
+ display: block;
+ float: left;
+}
+.stars-4 {
+ background-position: -13px 50%;
+}
+.stars-3 {
+ background-position: -26px 50%;
+}
+.stars-2 {
+ background-position: -39px 50%;
+}
+.stars-1 {
+ background-position: -52px 50%;
+}
+.stars-0 {
+ background-position: -65px 50%;
+}
+
+/* @group star select replacement */
+
+select.replaced {
+ display: none;
+}
+.selectReplacement {
+ cursor: pointer;
+ list-style: none;
+ position: relative;
+ width: 65px;
+ height: 12px;
+ margin: 0;
+ padding:0;
+ background-image:url("../../img/amo2009/icons/starselect.gif");
+ background-position: -65px 0;
+ background-repeat: no-repeat;
+ overflow: hidden;
+}
+.selectReplacement li {
+ display: inline;
+ margin: 0;
+ padding: 0;
+}
+.selectReplacement li a:link,
+.selectReplacement li a:visited,
+.selectReplacement li a:hover,
+.selectReplacement li a:active,
+.selectReplacement li a:focus {
+ display: block;
+ position: absolute;
+ width: 13px;
+ height: 12px;
+ text-indent: -9999px;
+ overflow: hidden;
+ left: 0;
+}
+ul.worst {
+ background-position: -52px 0;
+}
+ul.bad {
+ background-position: -39px 0;
+}
+ul.fair {
+ background-position: -26px 0;
+}
+ul.good {
+ background-position: -13px 0;
+}
+ul.best {
+ background-position: 0 0;
+}
+.selectReplacement li.worst a:link,
+.selectReplacement li.worst a:visited,
+.selectReplacement li.worst a:hover,
+.selectReplacement li.worst a:active,
+.selectReplacement li.worst a:focus {
+ left: 0;
+ z-index: 6;
+}
+.selectReplacement li.bad a:link,
+.selectReplacement li.bad a:visited,
+.selectReplacement li.bad a:hover,
+.selectReplacement li.bad a:focus,
+.selectReplacement li.bad a:active {
+ left: 13px;
+ z-index: 5;
+}
+.selectReplacement li.fair a:link,
+.selectReplacement li.fair a:visited,
+.selectReplacement li.fair a:hover,
+.selectReplacement li.fair a:focus,
+.selectReplacement li.fair a:active {
+ left: 26px;
+ z-index: 4;
+}
+.selectReplacement li.good a:link,
+.selectReplacement li.good a:visited,
+.selectReplacement li.good a:hover,
+.selectReplacement li.good a:focus,
+.selectReplacement li.good a:active {
+ left: 39px;
+ z-index: 3;
+}
+.selectReplacement li.best a:link,
+.selectReplacement li.best a:visited,
+.selectReplacement li.best a:hover,
+.selectReplacement li.best a:focus,
+.selectReplacement li.best a:active {
+ left: 52px;
+ z-index: 2;
+}
+.selectReplacement li a:hover,
+.selectReplacement li a:focus,
+.selectReplacement li a:active {
+ background-position: left top;
+ background-repeat: repeat-x;
+ background-image:url("../../img/amo2009/icons/starselect_single.gif");
+ left: 0;
+}
+
+.selectReplacement li.worst a:hover,
+.selectReplacement li.worst a:focus,
+.selectReplacement li.worst a:active {
+ width: 13px;
+ left: 0;
+}
+.selectReplacement li.bad a:hover,
+.selectReplacement li.bad a:focus,
+.selectReplacement li.bad a:active{
+ width: 26px;
+ left: 0;
+}
+.selectReplacement li.fair a:hover,
+.selectReplacement li.fair a:focus,
+.selectReplacement li.fair a:active{
+ width: 39px;
+ left: 0;
+}
+.selectReplacement li.good a:hover,
+.selectReplacement li.good a:focus,
+.selectReplacement li.good a:active{
+ width: 52px;
+ left: 0;
+}
+.selectReplacement li.best a:hover,
+.selectReplacement li.best a:focus,
+.selectReplacement li.best a:active {
+ width: 65px;
+ left: 0;
+}
+
+/* @end */
+
+/* @end */
+
+/* @group indicators */
+
+.downloads {
+ color: #390;
+ clear: both;
+}
+
+.subscribe,
+.addons,
+.collections,
+.subscribers,
+.category,
+.tags,
+.share,
+.digg,
+.delicious,
+.facebook,
+.friendfeed,
+.myspace {
+ background-image: url(../../img/amo2009/icons/icons.png);
+ background-repeat: no-repeat;
+ padding-left: 20px;
+}
+
+.subscribe {
+ background-position: 0 2px;
+}
+
+.share {
+ background-position: 0 -100px;
+}
+
+.addons {
+ background-position: 0 -200px;
+ padding-bottom: 7px;
+}
+.collections {
+ background-position: 0 -300px;
+}
+.subscribers {
+ background-position: 0 -400px;
+ padding-bottom: 7px;
+}
+.category {
+ background-position: 0 -503px;
+}
+.tags {
+ background-position: 0 -600px;
+}
+.digg {
+ background-position: 0 -900px;
+}
+.delicious {
+ background-position: 0 -1000px;
+}
+.facebook {
+ background-position: 0 -1100px;
+}
+.friendfeed {
+ background-position: 0 -1200px;
+}
+.myspace {
+ background-position: 0 -1300px;
+}
+
+h3 span.new {
+ padding: 0.2em 0.5em;
+ background-color: #305083;
+ color: white;
+ -moz-border-radius: 8px;
+ -webkit-border-radius: 8px;
+ border-radius: 8px;
+ background-image: url(../../img/amo2009/bg/heading-dark-blue.jpg);
+ background-repeat: repeat-x;
+ background-position: bottom left;
+ border: 1px solid #021437;
+ text-transform: uppercase;
+ font-size: 0.611em;
+}
+
+/* @end */
+
+/* @group hReviews */
+
+.hreview {
+ border-bottom: 1px dotted #B5D9E5;
+ padding: 0.5em 0 1em 0;
+ margin-bottom: 0.5em;
+}
+
+.hreview p {
+ margin-bottom: 0;
+}
+
+.hreview:last-child {
+ border-bottom: none;
+}
+
+/* @end */
+
+/* @group More Info */
+
+.more-info,
+.more-info:link,
+.more-info:visited,
+.more-info:hover,
+.more-info:focus,
+.more-info:active {
+ font-weight: bold;
+ float: right;
+ background-image: url(../../img/amo2009/icons/arrows.gif);
+ background-repeat: no-repeat;
+ background-position:right -153px;
+ padding-right: 1em;
+ color: #0055EE;
+}
+
+.more-info:hover,
+.more-info:focus,
+.more-info:active {
+ background-position:right -203px;
+ color: #003595;
+}
+
+/* @end */
+
+/* @group Generic Image Styles */
+
+.pull-left {
+ margin-right: 1em;
+ float: left;
+}
+.html-rtl .pull-left {
+ margin-right: auto;
+ margin-left: 1em;
+ float: right;
+}
+.pull-right {
+ margin-left: 1em;
+ float: right;
+}
+.html-rtl .pull-right {
+ margin-left: auto;
+ margin-right: 1em;
+ float: left;
+}
+.teaser-img {
+ text-align: center;
+ display: block;
+}
+img.icon {
+ background-color: #fff;
+ -webkit-border-radius: 4px;
+ -moz-border-radius: 4px;
+ border-radius: 4px;
+ padding: 4px;
+}
+
+h5 img.icon,
+h2 img.icon {
+ float: left;
+ margin-right: 10px;
+}
+h2 img.icon {
+ position: relative;
+ top: -0.2em;
+}
+img.avatar {
+ border: 3px solid #FFFFFF;
+}
+
+img.photo-large {
+ padding: 5px;
+ background-color: #FFFFFF;
+ width: 200px;
+ max-width: 99.9%;
+ border: none;
+ border-bottom: 1px solid #B5D9E5;
+ border-right: 1px solid #B5D9E5;
+}
+
+.screenshot.thumbnail {
+ border: 3px solid #C9E8F3;
+ float: left;
+ margin-right: 1em;
+ margin-bottom: 1em;
+ height: 150px;
+ width: 200px;
+}
+
+.screenshot.thumbnail img {
+ display: block;
+}
+
+.hasJS .screenshot.thumbnail {
+ position: relative;
+}
+
+.hasJS .screenshot.thumbnail .img-control {
+ position: absolute;
+ top: -10px;
+ right: -10px;
+ width: 18px;
+ height: 18px;
+ overflow: hidden;
+}
+
+img.scale {
+ width: 100%;
+}
+
+/* @end */
+
+/* @group Buttons */
+
+a:link.button,
+a:visited.button,
+a:hover.button,
+a:focus.button,
+a:active.button,
+button,input[type=submit] {
+ background-image: url(../../img/amo2009/bg/button-blue.jpg);
+ background-color:#73B9FF;
+ background-position:center center;
+ background-repeat:repeat-x;
+ padding:0 0.6em 0 0.5em;
+ -moz-border-radius: 13px;
+ -webkit-border-radius: 8px;
+ border-radius: 10px;
+ color:#FFFFFF;
+ font-family:helvetica, arial, sans-serif;
+ text-decoration:none;
+ font-size:1em;
+ text-shadow:-1px -1px 1px #196CF2;
+ white-space:nowrap;
+ overflow:visible;
+ cursor:pointer;
+ border:1px solid #258BFF;
+ margin:0.3em 0;
+ vertical-align:middle;
+}
+
+a:link.button img,
+a:visited.button img,
+a:hover.button img,
+a:focus.button img,
+a:active.button img,
+button img {
+ vertical-align:middle;
+ padding:0;
+ margin:0;
+ border-left:none;
+ border-top:none;
+ border-bottom:none;
+ border-right:1px solid #3399FF;
+ margin:0 0.6em 0.25em 0;
+ padding:0.1em 0.5em 0.1em 0;
+}
+
+a:link.auxillary,
+a:visited.auxillary,
+a:hover.auxillary,
+a:focus.auxillary,
+a:active.auxillary,
+button.auxillary {
+ font-size:0.923em;
+ padding:0.15em 1em 0.1em 0.7em;
+}
+
+a:link.prominent,
+a:visited.prominent,
+a:hover.prominent,
+a:focus.prominent,
+a:active.prominent,
+button.prominent {
+ font-size:1.2em;
+ -moz-border-radius: 13px;
+ -webkit-border-radius: 11px;
+ border-radius: 13px;
+}
+
+a:link.significant,
+a:visited.significant,
+a:hover.significant,
+a:focus.significant,
+a:active.significant,
+button.significant {
+ font-size:1.2em;
+ -moz-border-radius: 16px;
+ -webkit-border-radius: 14px;
+ border-radius: 16px;
+ font-weight: bold;
+ padding:0.4em 0.8em 0.3em 0.5em;
+ line-height: 2em;
+}
+
+a:link.significant img,
+a:visited.significant img,
+a:hover.significant img,
+a:focus.significant img,
+a:active.significant img,
+button.significant img {
+ /* padding:0 0.4em 0.2em 0.2em; */
+ /* margin-right: 0.4em; */
+ margin-bottom:0.4em;
+ margin-right:0.6em;
+ padding:0.4em 0.6em 0.2em 0.2em;
+}
+
+a:link.button.neutral,
+a:visited.button.neutral,
+a:hover.button.neutral,
+a:focus.button.neutral,
+a:active.button.neutral,
+button.neutral {
+ background-color:#E5A365;
+ background-image: url(../../img/amo2009/bg/button-orange.jpg);
+ border:1px solid #CB7E42;
+ text-shadow:-1px -1px 1px #BF6524;
+}
+
+a:link.button.neutral img,
+a:visited.button.neutral img,
+a:hover.button.neutral img,
+a:focus.button.neutral img,
+a:active.button.neutral img,
+button.neutral img {
+ border-right:1px solid #DD7711;
+}
+
+a:link.button.positive,
+a:visited.button.positive,
+a:hover.button.positive,
+a:focus.button.positive,
+a:active.button.positive,
+button.positive {
+ background-color:#8CC553;
+ background-image: url(../../img/amo2009/bg/button-green.jpg);
+ border: 1px solid #488F03;
+ text-shadow:-1px -1px 1px #7BAB29;
+}
+
+a:link.button.positive img,
+a:visited.button.positive img,
+a:hover.button.positive img,
+a:focus.button.positive img,
+a:active.button.positive img,
+button.positive img {
+ border-right:1px solid #55AA00;
+}
+
+a:link.negative,
+a:visited.negative,
+a:hover.negative,
+a:focus.negative,
+a:active.negative,
+button.negative {
+ background-color:#EC7F82;
+ background-image: url(../../img/amo2009/bg/button-red.jpg);
+ border: 1px solid #CF2F1E;
+}
+
+a:link.negative img,
+a:visited.negative img,
+a:hover.negative img,
+a:focus.negative img,
+a:active.negative img,
+button.negative img {
+ border-right:1px solid #E54C4F;
+}
+
+
+/* @end */
+
+/* @group Add To Favourites */
+
+button.add-to-fav {
+ margin: 0;
+ padding: 0.5em 0 0.2em 19px;
+ background: none;
+ background-image: url(../../img/amo2009/icons/fav-off.gif);
+ background-position: left center;
+ background-repeat: no-repeat;
+ -moz-border-radius: 0;
+ border:none;
+ color: #0055EE;
+ cursor:pointer;
+ text-shadow:none;
+ white-space: normal;
+ font-size: 0.923em;
+ font-weight: bold;
+}
+
+button.add-to-fav.fav {
+ color: #CC0000;
+ background-image: url(../../img/amo2009/icons/fav-on.gif);
+}
+
+form button.add-to-fav:hover,
+form button.add-to-fav:focus {
+ color: black;
+}
+
+form button.add-to-fav.loading-fav,
+form button.add-to-fav.loading-fav:hover,
+form button.add-to-fav.loading-fav:focus,
+form button.add-to-fav.loading-fav:active {
+ color: #A4A5A5;
+ background-image: url(../../img/amo2009/icons/orange-loading.gif);
+}
+
+/*.favourite {
+ background-image: url(../../img/amo2009/icons/icons.png);
+ background-repeat: no-repeat;
+ background-position: 0 -700px;
+ padding-left: 20px;
+ padding-bottom: 7px;
+ cursor: pointer;
+}
+.favourite-loading {
+ background-image: url(../../img/amo2009/icons/orange-loading.gif);
+ background-position: 0 0;
+}
+
+.favourite-added {
+ background-image: url(../../img/amo2009/icons/icons.png);
+ background-position: 0 -800px;
+ color: #D11F1F;
+} */
+
+form.favourite {
+ margin: 0;
+}
+
+/* @end */
+
+.privacy-policy {
+ margin-left: 1em;
+ margin-top: 0.5em;
+}
+
+.prose {
+ margin: 1em;
+}
+.primary.prose {
+ margin: 0;
+}
+
+.intro {
+ font-size: 1.23em; /* 16px */
+ line-height: 1.375; /* 22px */
+ color: #84898A;
+}
+.accessibility-only {
+ display:block;
+ float:left;
+ height:1px;
+ overflow:hidden;
+ text-indent:-5000px;
+ width:1px;
+}
+
+/* @end */
+
+/* @group Page structure */
+
+.section {
+ width: 90%;
+ overflow: hidden;
+ padding: 0 2%;
+ margin: 0 auto;
+ max-width: 90em;
+ min-width: 20em;
+ position: relative;
+ min-height: 30em;
+}
+
+/* @group Header */
+
+#header {
+ position: relative;
+ padding: 1px 0 0 0;
+}
+
+/* @group Title */
+
+#title {
+ font-size: 3.231em; /* 42px */
+ color: #223355;
+ font-weight: bold;
+ margin-top: 1.2em;
+ margin-bottom: 0.4em;
+ line-height: 0.8;
+}
+
+#title a:link,
+#title a:visited,
+#title a:hover,
+#title a:focus,
+#title a:active {
+ color: #223355;
+ text-decoration: none;
+ background: none;
+}
+
+#title em {
+ color: #445577;
+ font-weight: normal;
+ font-style: italic;
+}
+
+#title img {
+ vertical-align: middle;
+ position: relative;
+ top: -0.1em;
+}
+
+/* @end */
+
+/* @group Brand */
+
+#brand {
+ position: absolute;
+ top: 4px;
+ left: 0;
+ margin: 0;
+}
+
+#brand a:link,
+#brand a:visited,
+#brand a:hover,
+#brand a:focus,
+#brand a:active {
+ background-image: url(../../img/amo2009/tab-mozilla.png);
+ background-position: top left;
+ background-repeat: no-repeat;
+ width: 90px;
+ height: 31px;
+ overflow: hidden;
+ display: block;
+ text-indent: -5000px;
+}
+
+/* @end */
+
+/* @group Stats */
+
+.stats {
+ font-size: 0.923em;
+ text-align: right;
+ margin: -4.8em 1em 0 0;
+ padding: 0;
+ float: right;
+ color: #223355;
+}
+
+.hasJS .stats {
+ margin: -8em 0 0 0;
+}
+.stats li {
+ padding: 0.1em 0;
+ line-height: 1.2em;
+
+}
+
+.hasJS .stats li {
+ border-bottom: 1px dotted #94BFCE;
+ padding: 0.2em 0;
+ line-height: 1.25em;
+}
+
+.stats li:last-child {
+ border-bottom: none;
+}
+
+.stats strong {
+ color: #C63717;
+ font-size: 1.33em;
+ font-weight: normal;
+}
+
+/* @end */
+
+/* @group Aux nav */
+
+#aux-nav {
+ position: absolute;
+ top: 5px;
+ right: 0;
+ margin: 0 0 0 100px;
+ font-size: 0.923em;
+ padding: 0;
+ text-align: right;
+ color: #757778;
+}
+
+#aux-nav p.context {
+ display: block;
+ float: right;
+ padding-top: 0.7em;
+ padding-right: 1em;
+ position: absolute;
+ top: 5px;
+ right: 0;
+}
+
+.hasJS #aux-nav p.context {
+ position: static;
+}
+
+#aux-nav ul {
+ display: block;
+ padding-top: 0.7em;
+ z-index: 1;
+}
+
+.hasJS #aux-nav ul {
+ float: right;
+ padding-right: 1em;
+}
+
+#aux-nav span.greeting {
+ margin-right: 1em;
+}
+
+#aux-nav .settings {
+ margin-right: 1em;
+}
+
+#aux-nav a:link,
+#aux-nav a:visited,
+#aux-nav a:hover,
+#aux-nav a:focus,
+#aux-nav a:active {
+ /*margin-left: 1em;*/
+ font-weight: bold;
+ white-space: nowrap;
+}
+
+/* #aux-nav a.change:link,
+#aux-nav a.change:visited,
+#aux-nav a.change:hover,
+#aux-nav a.change:focus,
+#aux-nav a.change:active {
+ background-image: url(../../img/amo2009/bg/border-header-user-options.gif);
+ background-repeat: no-repeat;
+ background-position: top left;
+ display: block;
+ padding-top: 0.7em;
+ padding-left: 1em;
+ float: right;
+}
+
+#aux-nav .tools {
+ margin: 0 1em;
+} */
+
+/* @group Change */
+
+#aux-nav ul.change {
+ margin: 2.5em 0 0 0;
+ padding: 0;
+}
+
+.hasJS #aux-nav ul.change {
+ background-image: url(../../img/amo2009/bg/border-header-user-options.gif);
+ background-repeat: no-repeat;
+ background-position: top right;
+ margin-top: 0;
+ border-right: 3px solid transparent;
+ position: relative;
+}
+
+#aux-nav ul.change li {
+ display: inline;
+ margin-left: 1em;
+}
+
+.hasJS #aux-nav ul.change li {
+ background-image: url(../../img/amo2009/bg/border-header-user-options.gif);
+ background-repeat: no-repeat;
+ background-position: top left;
+ display: block;
+ margin-left: 0;
+}
+
+#aux-nav ul.change li li {
+ background-image: none;
+ background-repeat: no-repeat;
+ background-position: top left;
+}
+
+.hasJS #aux-nav .change li ul li {
+ background-color: #FFFFFF;
+ background-image: url(../../img/amo2009/bg/header-dropdown.png);
+ background-repeat: repeat-x;
+ background-position: top left;
+ border-top: 1px solid #D0EBF4;
+ width: 11em;
+ text-align: left;
+ margin: 0;
+ padding: 0;
+}
+
+.hasJS #aux-nav .change li ul li a {
+ background-repeat: no-repeat;
+ background-position: top left;
+ display: block;
+ margin: 0;
+ padding: 0.3em 0.3em 0.3em 45px;
+}
+
+.hasJS #aux-nav .change li ul li.firefox a {
+ background-image: url(../../img/amo2009/icons/logos-applications.gif);
+ background-repeat: no-repeat;
+ background-position: 1em 0;
+}
+.hasJS #aux-nav .change li ul li.thunderbird a {
+ background-image: url(../../img/amo2009/icons/logos-applications.gif);
+ background-repeat: no-repeat;
+ background-position: 1em -50px;
+ top: 24px;
+}
+.hasJS #aux-nav .change li ul li.sunbird a {
+ background-image: url(../../img/amo2009/icons/logos-applications.gif);
+ background-repeat: no-repeat;
+ background-position: 1em -100px;
+}
+.hasJS #aux-nav .change li ul li.seamonkey a {
+ background-image: url(../../img/amo2009/icons/logos-applications.gif);
+ background-repeat: no-repeat;
+ background-position: 1em -150px;
+}
+
+
+#aux-nav ul.change a.controller:link,
+#aux-nav ul.change a.controller:visited,
+#aux-nav ul.change a.controller:focus,
+#aux-nav ul.change a.controller:hover,
+#aux-nav ul.change a.controller:active {
+ padding: 0.7em 1em 0 1em;
+ cursor:default;
+ color: #333333;
+ text-decoration: none;
+}
+
+.hasJS #aux-nav ul.change a.controller:link,
+.hasJS #aux-nav ul.change a.controller:visited,
+.hasJS #aux-nav ul.change a.controller:focus,
+.hasJS #aux-nav ul.change a.controller:hover,
+.hasJS #aux-nav ul.change a.controller:active {
+ padding: 0.7em 20px 0.5em 1em;
+ display: block;
+ cursor:pointer;
+ color: #0055EE;
+ background-image: url(../../img/amo2009/icons/arrows.gif);
+ background-repeat: no-repeat;
+ background-position: 95% -65px;
+}
+
+.hasJS #aux-nav ul.change a.controller:focus,
+.hasJS #aux-nav ul.change a.controller:hover,
+.hasJS #aux-nav ul.change a.controller:active {
+ text-decoration: underline;
+ color: #003595;
+ background-position: 95% -105px;
+}
+
+#aux-nav ul.change ul {
+ display: inline;
+}
+
+.hasJS #aux-nav ul.change ul {
+ display: none;
+ position: absolute;
+ right: -3px;
+ padding: 0;
+ border-right: 3px solid #A2C2D7;
+ border-bottom: 3px solid #A2C2D7;
+}
+
+/* @end */
+
+/* @group Tools */
+
+#aux-nav ul.tools {
+ margin: -0.5em 0 0 0;
+ padding: 0;
+ background-image: none;
+}
+
+.hasJS #aux-nav ul.tools {
+ margin: 0;
+ position: relative;
+ border-right: 3px solid transparent;
+}
+
+#aux-nav ul.tools li {
+ background-image: none;
+ display: inline;
+ margin-left: 1em;
+}
+
+.hasJS #aux-nav ul.tools li {
+ display: block;
+ margin-left: 0;
+}
+
+#aux-nav ul.tools li li {
+ background-image: none;
+ background-repeat: no-repeat;
+ background-position: top left;
+}
+
+.hasJS #aux-nav .tools li ul li {
+ background-color: #FFFFFF;
+ background-image: url(../../img/amo2009/bg/header-dropdown.png);
+ background-repeat: repeat-x;
+ background-position: top left;
+ border-top: 1px solid #D0EBF4;
+ width: 10em;
+ text-align: left;
+ margin: 0;
+ padding: 0.3em 0.3em 0.3em 1em;
+}
+
+#aux-nav ul.tools a.controller:link,
+#aux-nav ul.tools a.controller:visited,
+#aux-nav ul.tools a.controller:focus,
+#aux-nav ul.tools a.controller:hover,
+#aux-nav ul.tools a.controller:active {
+ padding: 0.7em 1em 0 1em;
+ cursor:default;
+ color: #333333;
+ text-decoration: none;
+}
+
+.hasJS #aux-nav ul.tools a.controller:link,
+.hasJS #aux-nav ul.tools a.controller:visited,
+.hasJS #aux-nav ul.tools a.controller:focus,
+.hasJS #aux-nav ul.tools a.controller:hover,
+.hasJS #aux-nav ul.tools a.controller:active {
+ padding: 0.7em 20px 0.5em 1em;
+ display: block;
+ cursor:pointer;
+ color: inherit;
+ text-decoration: inherit;
+ color: #0055EE;
+ background-image: url(../../img/amo2009/icons/arrows.gif);
+ background-repeat: no-repeat;
+ background-position: 95% -65px;
+}
+
+.hasJS #aux-nav ul.tools a.controller:focus,
+.hasJS #aux-nav ul.tools a.controller:hover,
+.hasJS #aux-nav ul.tools a.controller:active {
+ color: #003595;
+ text-decoration: underline;
+ background-position: 95% -105px;
+}
+
+#aux-nav ul.tools ul {
+ display: inline;
+}
+
+.hasJS #aux-nav ul.tools ul {
+ display: none;
+ position: absolute;
+ right: -3px;
+ padding: 0;
+ border-right: 3px solid #A2C2D7;
+ border-bottom: 3px solid #A2C2D7;
+}
+
+/* @end */
+
+.hasJS #aux-nav .expanded .controller {
+ background-color: #FFFFFF;
+ padding-bottom: 1em;
+}
+
+.hasJS #aux-nav ul.expanded {
+ border-right: 3px solid #A2C2D7;
+}
+
+/* @end */
+
+/* @end */
+
+/* @group Footer */
+
+#footer {
+ background-image: url(../../img/amo2009/bg/footer.png);
+ background-repeat: repeat-x;
+ background-position: 0 50px;
+ clear: both;
+ padding-bottom: 1em;
+}
+#footer .section {
+ min-height: 0;
+}
+#footer .primary {
+ float: left;
+ padding-top: 70px;
+ background-image: url(../../img/amo2009/logo-mozilla.gif);
+ background-repeat: no-repeat;
+ background-position: 0 70px;
+ clear: none;
+}
+#footer .secondary {
+ float: right;
+ text-align: right;
+ clear: none;
+}
+#footer .secondary img {
+ max-width: 190px;
+ width: 100%;
+}
+#footer p {
+ margin-bottom: 0;
+ margin-left: 60px;
+ margin-right: 1em;
+}
+#footer ul {
+ font-size: 0.846em;
+ line-height: 1.273;
+ margin-top: 0.3em;
+ padding: 0;
+ margin-left: 60px;
+ margin-right: 1.273em;
+}
+#footer ul li {
+ display: inline;
+ margin-right: 1em;
+}
+#footer .disclaimer {
+ font-size: 0.846em;
+ line-height: 1.273;
+ color: #666666;
+ margin-right: 1.273em;
+}
+
+#footer .languages {
+ float: right;
+ margin: 0;
+}
+
+/* @end */
+
+/* @group Layout constructs */
+
+.primary {
+ width: 73.47%;
+ float: right;
+ clear: right;
+ display: inline;
+}
+.secondary {
+ width: 24.49%;
+ float: left;
+ clear: both;
+ display: inline;
+}
+
+.primary .primary {
+ width: 63.889%;
+ float: left;
+ clear: none;
+}
+
+.primary .secondary {
+ margin-bottom: 2em;
+ width: 33.333%;
+ float: right;
+ clear: none;
+}
+
+/* @group Inverse layout */
+
+.inverse .primary {
+ float: left;
+ clear: left;
+}
+.inverse .secondary {
+ float: right;
+ clear: right;
+}
+.inverse .primary .primary {
+ float: left;
+ clear: none;
+}
+.section .inverse .primary {
+ float: right;
+ clear: none;
+}
+.inverse .primary .secondary {
+ float: right;
+ clear: none;
+}
+.section .inverse .secondary {
+ float: left;
+ clear: none;
+}
+
+/* @end */
+
+.column-wrapper {
+ overflow: hidden;
+}
+
+.column {
+ float: left;
+ width: 32%;
+ display: inline;
+ margin-left: 2%;
+}
+
+.first {
+ margin-left: 0;
+}
+
+/* @end */
+
+
+/* @end */
+
+/* @group Page Components */
+
+.secondary fieldset {
+ border: none;
+ padding: 0;
+}
+
+.secondary select#add-to-collection {
+ width: 100%;
+ margin: 0.5em 0;
+}
+
+.secondary li a:link,
+.secondary li a:visited,
+.secondary li a:hover,
+.secondary li a:focus,
+.secondary li a:active {
+ font-weight: bold;
+}
+
+/* @group Featured */
+
+.featured {
+ border: 4px solid #B5D9E5;
+ background-color: #B5D9E5;
+ -webkit-border-radius: 5px;
+ -moz-border-radius: 5px;
+ border-radius: 5px;
+ margin-bottom: 2em;
+ clear: both;
+}
+.featured-inner {
+ background-color: #fff;
+ border: 1px solid #2E5186;
+ -webkit-border-radius: 3px;
+ -moz-border-radius: 3px;
+ border-radius: 3px;
+}
+
+/* @end */
+
+/* @group Article */
+
+.article {
+ background-color: #fff;
+ border: 1px solid #C9E8F3;
+ -webkit-border-radius: 3px;
+ -moz-border-radius: 3px;
+ border-radius: 3px;
+ padding: 1em;
+ overflow: hidden;
+}
+.secondary .article {
+ margin-bottom: 1em;
+}
+
+.article h4 {
+ clear: both;
+ margin-bottom: 0.3em;
+}
+
+.article img .screenshot {
+ margin-top: 1em;
+ margin-right: 2em;
+}
+
+.article a:link,
+.article a:visited,
+.article a:hover,
+.article a:focus,
+.article a:active {
+ font-weight: bold;
+}
+
+.article ul.further-navigation {
+ border-top: none;
+ padding-top: 0;
+ margin-bottom: 0;
+}
+
+/* @end */
+
+/* @group Notification */
+
+.notification {
+ background-color: #FFFFFF;
+ border: 1px solid #C8E8F3;
+ -moz-border-radius: 5px;
+ -webkit-border-radius: 5px;
+ border-radius: 5px;
+ padding: 1em;
+ color: #444444;
+ margin-bottom: 2em;
+ position: relative;
+}
+
+.notification h3 {
+ font-style: italic;
+ font-weight: normal;
+ line-height: 1.5em;
+ color: #223355;
+ margin-top: 0;
+}
+
+.notification .continue {
+ margin:0.5em 0 0 1em;
+}
+
+.notification .continue a:link,
+.notification .continue a:visited,
+.notification .continue a:hover,
+.notification .continue a:focus,
+.notification .continue a:active {
+ font-size: 1.5em;
+}
+
+.notification .suggestion {
+ float: right;
+ text-align: right;
+}
+
+.notification .suggestion p {
+ margin: 0;
+ color: #666666;
+ font-weight: bold;
+}
+.notification .aux {
+ overflow: hidden;
+ width: 100%;
+}
+
+.toggle-help,
+.toggle-info .close {
+ display: none;
+}
+
+.hasJS .toggle-help,
+.hasJS .toggle-info .close {
+ display: block;
+}
+
+.hasJS .toggle-info .close {
+ font-size: 0.769em;
+ position: absolute;
+ top: 1em;
+ right: 0.5em;
+}
+
+.notification .toggle-info {
+ color: #666666;
+ font-size:1.385em;
+ line-height: 1.375em;
+ position: relative;
+}
+
+.notification .toggle-info p {
+ margin-bottom: 0;
+ margin-top: 1em;
+}
+
+.hasJS .notification .toggle-info {
+ clear: both;
+ font-weight: normal;
+ position: absolute;
+ right: 0;
+ font-size: 1em;
+ clear:both;
+ width: 24.3%;
+ background-image: url(../../img/amo2009/icons/pointer.gif);
+ background-repeat: no-repeat;
+ background-position: 95% 4px;
+ padding-top: 10px;
+}
+
+.hasJS .primary .notification .toggle-info {
+ width: 33.2%;
+}
+.hasJS .primary .object-lead .toggle-info {
+ width: 100%;
+}
+
+.hasJS .notification .toggle-info p {
+ margin-top: 0;
+ background-color: white;
+ padding: 1em;
+ border: 1px solid #2E5186;
+ -moz-border-radius:5px;
+ -webkit-border-radius:5px;
+ border-radius:5px;
+}
+
+
+/* @end */
+
+/* @group Highlights */
+
+.highlight {
+ background-color: #C8E8F3;
+ -moz-border-radius: 5px;
+ -webkit-border-radius: 5px;
+ border-radius: 5px;
+ padding: 1em;
+ color: #444444;
+ overflow: hidden;
+ margin-bottom: 1em;
+}
+
+.highlight h2,
+.highlight h3 {
+ margin-top: 0;
+ color: #011234;
+ font-size: 1.385em;
+ font-weight: normal;
+}
+
+.highlight h4 {
+ margin-bottom:1em;
+}
+
+.highlight p {
+ margin-bottom: 0;
+ margin-top: 1em;
+}
+
+.highlight img.avatar {
+ float: right;
+ margin-left: 1em;
+ margin-bottom: 1em;
+}
+
+.highlight .more-info {
+ float: left;
+}
+
+.highlight a.button {
+ margin-top: 0.5em;
+}
+
+.highlight .further-navigation {
+ border-top: 1px dotted #A5C9D5;
+ margin-bottom: 0;
+}
+
+.highlight .further-navigation .more-info {
+ float: right;
+}
+
+/* @end */
+
+/* @group Top search and cat bar */
+
+/* @group Categories list */
+
+.categories {
+ background-color: #C8E8F3;
+ color: #444444;
+ -moz-border-radius: 5px;
+ -webkit-border-radius: 5px;
+ border-radius: 5px;
+ width: 24.49%;
+ float: left;
+ margin-bottom: 1em;
+}
+
+.categories h3 a:link,
+.categories h3 a:visited,
+.categories h3 a:hover,
+.categories h3 a:focus,
+.categories h3 a:active {
+ color: white;
+ text-decoration: none;
+}
+
+/* putting back the focus outline */
+.categories h3 a:focus {
+ outline: 1px dotted white;
+}
+
+.secondary .categories {
+ width: 100%;
+ float: none;
+}
+
+.categories h2,
+.categories h3 {
+ margin: 0;
+ padding: 0.79em 0.8em; /* 10px 13px*/
+ background-color: #305083;
+ color: white;
+ -moz-border-radius: 5px;
+ -webkit-border-radius: 5px;
+ border-radius: 5px;
+ font-size: 1.231em;
+ background-image: url(../../img/amo2009/bg/heading-dark-blue.jpg);
+ background-repeat: repeat-x;
+ background-position: bottom left;
+ border: 1px solid #021437;
+ font-weight: normal;
+}
+
+
+.categories ul {
+ padding: 1em 0.5em 1em 1em;
+ margin: 0;
+ font-weight: bold;
+}
+
+.categories ul ul {
+ padding: 0 0 1em 0;
+ margin: 0;
+ font-weight: bold;
+}
+
+.categories ul ul li {
+ margin: 0.2em;
+}
+
+.categories ul li:first-child ul {
+ border-bottom: 1px dotted #94BFCE;
+ margin-bottom: 0.8em;
+ padding-bottom: 0.8em;
+}
+
+.categories .items {
+ color: white;
+ background-color: #94BFCE;
+ -moz-border-radius: 7px;
+ -webkit-border-radius: 7px;
+ border-radius: 7px;
+ margin-left: 0.1em;
+ padding: 1px 5px;
+ font-size: 0.856em;
+ font-weight: normal;
+}
+.html-rtl .categories .items {
+ unicode-bidi: embed;
+}
+
+/* @group With Javascript */
+.hasJS .stand-alone-options {
+ position: relative;
+}
+.hasJS .dropdown-categories {
+ z-index: 99;
+ position: absolute;
+ left: 0;
+ top: 0;
+ /*width: 23.4%;*/
+}
+.hasJS .dropdown-categories>ul {
+ display: none;
+}
+.hasJS .dropdown-categories img {
+ position: absolute;
+ left: 10px;
+ top: 10px;
+}
+.hasJS .dropdown-categories ul ul {
+ display: block;
+ position: static;
+}
+.hasJS .dropdown-categories h2,
+.hasJS .dropdown-categories h3 {
+ cursor: pointer;
+ position: relative;
+ padding-left: 35px;
+}
+
+/* @end */
+
+
+/* @end */
+
+/* @group Search Form */
+
+
+.search-form {
+ margin-bottom: 2em;
+ width: 73.47%;
+ float: right;
+ position: relative;
+ padding: 0 0 1.5em 0;
+}
+.primary .search-form {
+ width: 100%;
+ float: none;
+}
+.search-form form {
+ margin: 0;
+}
+.search-form .basic {
+ background-image: url(../../img/amo2009/bg/heading-dark-blue.jpg);
+ background-repeat: repeat-x;
+ background-position: bottom left;
+ border: 1px solid #021437;
+ margin: 0;
+ background-color: #305083;
+ color: white;
+ -moz-border-radius: 5px;
+ -webkit-border-radius: 5px;
+ border-radius: 5px;
+ font-size: 1.231em;
+ white-space:nowrap;
+ display: block;
+ overflow:hidden;
+ position: relative;
+}
+
+.search-form .basic * {
+ vertical-align: middle;
+}
+
+.search-form .basic button {
+ position: absolute;
+ top:0.06em;
+ right: 1%;
+ -moz-border-radius-bottomleft:5px;
+ -moz-border-radius-bottomright:5px;
+ -moz-border-radius-topleft:5px;
+ -moz-border-radius-topright:5px;
+ background-color:#6FB727;
+ background-image:url(../../img/amo2009/bg/button-green.jpg);
+ background-position:left center;
+ background-repeat:repeat-x;
+ border:1px solid #B9D999;
+ color:white;
+ line-height:0;
+ width: 5%;
+ display: block;
+ float: left;
+ text-align: center;
+ padding:0.3em 0;
+ /* padding:0.3em 0.6em 0.3em 0.75em; */
+}
+
+.search-form .basic button img {
+ vertical-align: top;
+ margin: 0;
+ padding: 0;
+ display: inline;
+ border-right: none;
+}
+
+.search-form .basic button p span {
+ text-indent: -5000px;
+}
+
+.search-form .basic label {
+ font-weight: normal;
+ width: 10%;
+ text-align: center;
+ display: block;
+ float: left;
+ padding-top: 0.7em;
+}
+
+.search-form .basic input{
+ border: 1px solid #CCCCCC;
+ outline: 1px solid #011234;
+ margin:0.35em 0 0.35em 1.4%;
+ background-image: url(../../img/amo2009/icons/magnifying-glass.gif);
+ background-repeat: no-repeat;
+ background-position: 0.1em center;
+ background-color: white;
+ padding:0.3em 0;
+ text-indent: 2em;
+ width:45%;
+ display: block;
+ float: left;
+}
+
+.search-form .basic select {
+ border: 1px solid #CCCCCC;
+ outline: 1px solid #011234;
+ margin:0.35em 0;
+ color: #444444;
+ padding:0.23em 0;
+ width: 35%;
+ float:left;
+}
+.search-form .basic option {
+ color: black;
+ text-indent: 10px;
+ padding-left: 5px;
+}
+.search-form .basic option.cat-all {
+ color: #444444;
+ text-indent: 0;
+ font-weight: bold;
+}
+.search-form .basic textarea:focus,
+.search-form .basic input[type='text']:focus,
+.search-form .basic input[type='password']:focus,
+.search-form .basic select:focus {
+ border: 1px solid #999;
+ outline: 1px solid black;
+}
+
+#advanced-link {
+ position: absolute;
+ bottom: 0;
+ right: 30px;
+ margin: 0;
+}
+#advanced-link a:link,
+#advanced-link a:visited,
+#advanced-link a:hover,
+#advanced-link a:focus,
+#advanced-link a:active {
+ display: block;
+ padding: 0 20px 0.1em 1em;
+ font-size: 0.923em;
+ font-weight: bold;
+ color: white;
+ -moz-border-radius: 0 0 5px 5px;
+ -webkit-border-radius: 5px;
+ border-radius: 0 0 5px 5px;
+ border: 1px solid #021437;
+ border-top: none;
+ /*background-color: #223355;*/
+ background-color: #26395A;
+ background-image: url(../../img/amo2009/icons/arrows.gif);
+ background-position: 95% -591px;
+ background-repeat: no-repeat;
+}
+
+.expanded #advanced-link a:link,
+.expanded #advanced-link a:visited,
+.expanded #advanced-link a:hover,
+.expanded #advanced-link a:focus,
+.expanded #advanced-link a:active {
+ background-position: 95% -641px;
+}
+
+/* @group Expanded search form */
+
+.search-form .advanced {
+ display: none;
+}
+.expanded-search-form .advanced {
+ display: block;
+ padding-top: 1px;
+ margin: 0 5px;
+ background-color: #EAF6FA;
+ border-color: #223355;
+ border-style: solid;
+ border-width: 0 5px 5px 5px;
+ -moz-border-radius: 0 0 5px 5px;
+ -webkit-border-bottom-left-radius: 5px;
+ -webkit-border-bottom-right-radius: 5px;
+ border-radius: 0 0 5px 5px;
+}
+.search-form fieldset {
+ border: none;
+ margin: 1em;
+ padding: 0;
+}
+.search-form fieldset:first-child {
+ border-bottom: 1px dotted #A4CFDE;
+ padding-bottom: 1em;
+}
+
+/* @group Subsidiary */
+
+.search-form .subsidiary {
+ margin-top: 0;
+ border: none;
+}
+.search-form .subsidiary .container {
+ width: 48%;
+ float: left;
+ display: inline;
+}
+.search-form .subsidiary label {
+ width: 35%;
+ display: block;
+ float: left;
+ font-weight: bold;
+}
+.search-form .subsidiary select,
+.search-form .subsidiary input {
+ width: 40%;
+}
+
+/* @end */
+
+/* @group Important */
+
+.search-form .important {
+ margin-bottom: 0;
+}
+.search-form .important div {
+ display: inline;
+ white-space: nowrap;
+}
+.search-form .important select,
+.search-form .important input {
+ margin: 0 0.5em;
+}
+.search-form .important .application label {
+ font-weight: bold;
+ display: block;
+ float: left;
+ width: 16.8%;
+}
+.search-form .important .application select,
+.search-form .important .application input {
+ margin: 0 1em 0 0;
+}
+
+/* @end */
+
+
+/* @end */
+/* @end */
+
+/* @end */
+
+/* @group Homepage teaser */
+
+.hasJS .section-teaser .featured-inner {
+ padding-bottom: 5em;
+ position: relative;
+}
+
+/* @group Teaser Header */
+
+.section-teaser .teaser-header {
+ background-image: url(../../img/amo2009/bg/listing-footer.gif);
+ background-position: top left;
+ background-repeat: repeat-x;
+ -webkit-border-top-right-radius: 3px;
+ -webkit-border-top-left-radius: 3px;
+ -moz-border-radius: 3px 3px 0 0;
+ border-radius: 3px 3px 0 0;
+ width: 100%;
+ overflow: hidden;
+}
+
+.hasJS .section-teaser .teaser-header {
+ -webkit-border-top-right-radius: 0;
+ -webkit-border-top-left-radius: 0;
+ -webkit-border-bottom-right-radius: 3px;
+ -webkit-border-bottom-left-radius: 3px;
+ -moz-border-radius: 0 0 3px 3px;
+ border-radius: 0 0 3px 3px;
+ position: absolute;
+ bottom: 0;
+ left: 0;
+}
+.section-teaser .teaser-header ol {
+ margin: 0;
+ padding: 0 45px;
+ list-style-type: none;
+}
+
+.hasJS .section-teaser .teaser-header ol {
+ border-top: 1px solid #AEC3CF;
+}
+
+.section-teaser .teaser-header ol li {
+ margin: 0 2.1em 0.5em 0;
+ padding: 0.5em 0 0 0;
+ float: left;
+ white-space: nowrap;
+ position: relative;
+ top: -1px;
+}
+
+.section-teaser .teaser-header ol li:first-child {
+ margin-left: 0;
+}
+
+.section-teaser .teaser-header ol li:last-child {
+ margin-right: 0;
+}
+
+.section-teaser .teaser-header a:link,
+.section-teaser .teaser-header a:visited,
+.section-teaser .teaser-header a:hover,
+.section-teaser .teaser-header a:focus,
+.section-teaser .teaser-header a:active {
+ color: #54647E;
+ text-decoration: none;
+ font-size: 0.923em;
+ font-weight: bold;
+}
+
+.section-teaser .teaser-header a:hover,
+.section-teaser .teaser-header a:focus,
+.section-teaser .teaser-header a:active {
+ color: #223355;
+}
+
+.section-teaser .teaser-header li.selected {
+ background-image: url(../../img/amo2009/bg/panel-selected.png);
+ background-repeat: no-repeat;
+ background-position: center top;
+}
+
+/* @end */
+
+.teaser-items {
+ margin: 0;
+ padding: 0;
+ list-style-type: none;
+}
+
+.teaser-items li {
+ margin: 0;
+ padding: 0;
+}
+
+/* @group Next and previous icons */
+
+.slideshow-controls {
+ margin: 0;
+}
+
+.section-teaser .prev,
+.section-teaser .next {
+ display: block;
+ position: absolute;
+ overflow: hidden;
+ cursor: pointer;
+ text-decoration: none;
+ text-indent: -5000px;
+ bottom: 1.6em;
+ left: 8px;
+ width: 27px;
+ height: 27px;
+ background-image: url(../../img/amo2009/icons/arrows-scroller.png);
+ background-position: 0 0;
+ background-repeat: no-repeat;
+}
+
+.section-teaser .next {
+ left: auto;
+ right: 8px;
+ background-position: 0 -150px;
+}
+
+.section-teaser .active.prev {
+ background-position: 0 -50px;
+}
+
+.section-teaser .active.next {
+ background-position: 0 -200px;
+}
+
+.section-teaser .active.prev:focus,
+.section-teaser .active.prev:hover {
+ background-position: 0 -100px;
+}
+
+.section-teaser .active.next:focus,
+.section-teaser .active.next:hover {
+ background-position: 0 -250px;
+}
+
+/* @end */
+
+/* @group Slideshow Window with Javascript */
+
+.hasJS .section-teaser .window {
+ overflow: hidden;
+ direction: ltr;
+}
+
+.hasJS .section-teaser .window ol.teaser-items {
+ margin: 0;
+ padding: 0;
+ width: 50000px;
+ overflow: hidden;
+ position: relative;
+ left: 0;
+ direction: ltr;
+}
+
+.hasJS .section-teaser .window ol.teaser-items li {
+ float: left;
+ margin: 0;
+ padding: 0;
+}
+
+.hasJS .section-teaser .window .more-info {
+ background-position:right -155px;
+}
+
+/* @end */
+
+/* @group Teaser internals */
+
+.section-teaser .column-wrapper {
+ margin: 0 1em;
+}
+
+.section-teaser h2 {
+ margin-left: 0.619em;
+ margin-right: 0.619em;
+ font-size: 1.615em;
+ line-height: 0.952em;
+}
+
+.section-teaser .column {
+ border-left: 1px dotted #A4CFDE;
+ text-align: center;
+ width: 31.5%;
+}
+
+.section-teaser .column p,
+.section-teaser .column h3 {
+ margin-left: 1em;
+}
+
+.section-teaser .first {
+ border-left: none;
+}
+
+.section-teaser .addon-view {
+ background-position: bottom right;
+ background-repeat: no-repeat;
+}
+
+.section-teaser .addon-view .lead {
+ clear: both;
+ margin-left: 1em;
+ margin-right: 1em;
+}
+
+.section-teaser .addon-view .more-info {
+ float: none;
+}
+
+.section-teaser .addon-view .column {
+ border:none;
+ text-align: left;
+ width: 25%;
+}
+
+.section-teaser .addon-view .column-inner {
+ padding: 1em 0 1em 55px;
+ position: relative;
+}
+
+.section-teaser .addon-view .icon {
+ position: absolute;
+ top: 1em;
+ left: 10px;
+}
+
+.section-teaser .addon-view h3 {
+ margin-top: 0;
+ font-weight: bold;
+ font-size: 1em;
+ line-height: 1.25em;
+}
+
+.section-teaser .addon-view p,
+.section-teaser .addon-view h3 {
+ margin-left: 0;
+ margin-right: 0;
+ line-height: 1.23em;
+}
+
+div.section-teaser .column .button {
+ white-space: nowrap;
+ margin: 0;
+ margin-right: 1%;
+ margin-left: 0.7%;
+}
+
+div.section-teaser .column .button * {
+ white-space: nowrap;
+}
+
+/* @group Section BG images */
+
+.section-teaser #t-entertainment {
+ /*background-image: url(../../img/amo2009/illustrations/entertainment.jpg);*/
+}
+.section-teaser #t-shopping {
+ background-image: url(../../img/amo2009/illustrations/shopping-online.jpg);
+}
+.section-teaser #t-music {
+ /*background-image: url(../../img/amo2009/illustrations/music.jpg);*/
+}
+.section-teaser #t-socialising {
+ /*background-image: url(../../img/amo2009/illustrations/socialising.jpg);*/
+}
+.section-teaser #t-news {
+ /*background-image: url(../../img/amo2009/illustrations/news.jpg);*/
+}
+.section-teaser #t-search {
+ /*background-image: url(../../img/amo2009/illustrations/search.jpg);*/
+}
+
+/* @end */
+
+/* @end */
+
+/* @end */
+
+/* @group Steps */
+
+ol.numbered {
+ margin-left: 0;
+ list-style-type: none;
+}
+
+ol.numbered li {
+ position: relative;
+ margin-bottom: 1em;
+ overflow: hidden;
+ min-height:35px;
+ padding-left: 50px;
+}
+
+h4.step {
+ position: absolute;
+ left: 0;
+ top: 0;
+ background-image: url(../../img/amo2009/icons/step.png);
+ background-repeat: no-repeat;
+ background-position: left top;
+ color: #FFFFFF;
+ font-size:1.6em;
+ font-weight:lighter;
+ padding:5px 13px 15px;
+}
+
+/* @end */
+
+/* @group Pagination */
+
+ol.pagination {
+ width: 50%;
+ margin-bottom: 2em;
+ margin-left: 0;
+ float: left;
+ line-height: 2em;
+}
+.listing-footer ol.pagination {
+ margin-bottom: 0;
+}
+ol.pagination li {
+ display: inline;
+ list-style: none;
+}
+ol.pagination li a {
+ padding: 0.3em 0.7em;
+ font-weight: bold;
+}
+ol.pagination span {
+ font-weight: bold;
+ padding: 0.3em 0.7em;
+}
+ol.pagination a[rel~="prev"],
+ol.pagination span.prev {
+ background-image: url(../../img/amo2009/icons/arrows.gif);
+ background-repeat: no-repeat;
+ background-position: 5px -420px;
+ color: #0055EE;
+ padding-right:0.7em;
+ padding-left: 15px;
+}
+ol.pagination a[rel~="next"],
+ol.pagination span.next {
+ background-image: url(../../img/amo2009/icons/arrows.gif);
+ background-repeat: no-repeat;
+ background-position: 92% -340px;
+ color: #0055EE;
+ padding-left:0.7em;
+ padding-right: 15px;
+}
+ol.pagination span.prev {
+ color: #666;
+ background-position: 5px -540px;
+}
+ol.pagination span.next {
+ color: #666;
+ background-position: 92% -500px;
+}
+ol.pagination li.selected a:link,
+ol.pagination li.selected a:visited,
+ol.pagination li.selected a:hover,
+ol.pagination li.selected a:focus,
+ol.pagination li.selected a:active {
+ -webkit-border-radius: 3px;
+ -moz-border-radius: 3px;
+ border-radius: 3px;
+ background-color: #223355;
+ color: white;
+}
+ol.pagination li a:hover,
+ol.pagination li a:focus,
+ol.pagination li a:active {
+ background-color: #BDDDE8;
+ /*color: #223355;*/
+ -webkit-border-radius: 3px;
+ -moz-border-radius: 3px;
+ border-radius: 3px;
+ text-decoration: none;
+}
+
+/* @end */
+
+/* @group Share This */
+
+.share-this {
+ width: 200px;
+ clear:left;
+ float:left;
+}
+
+.share-networks {
+ background-image: url(../../img/amo2009/icons/pointer.gif);
+ background-repeat: no-repeat;
+ background-position:30px top;
+ padding-top: 7px;
+}
+
+.share-networks ul {
+ border: 1px solid #2E5186;
+ -moz-border-radius:5px;
+ -webkit-border-radius:5px;
+ border-radius:5px;
+ padding: 1em;
+ background-color: #FFFFFF;
+ padding:1em 1em 0;
+}
+
+.share-networks li {
+ margin-bottom:0.5em;
+}
+
+
+
+/* @end */
+
+/* @group Addon list */
+
+.secondary-item-list {
+ background-color: #fff;
+ border: 1px solid #C9E8F3;
+ -webkit-border-radius: 3px;
+ -moz-border-radius: 3px;
+ border-radius: 3px;
+ padding: 1em;
+ overflow: hidden;
+}
+.secondary-item-list ul {
+ margin: 0.5em 0 0 0;
+ padding: 0;
+}
+
+.secondary-item-list ul li {
+ margin: 0;
+ padding: 0;
+}
+
+.secondary-item-list ul li a {
+ margin: 0 0 0.8em 0;
+ padding: 0 0 0 25px;
+ display: block;
+ line-height: 1.25;
+}
+/* @end */
+
+/* @group Breadcrumbs */
+
+ol.breadcrumbs {
+ font-weight: bold;
+ margin-bottom: 1.3em;
+ font-size: 0.846em;
+ margin-left: 0;
+ clear: both;
+}
+
+ol.breadcrumbs li {
+ display: inline;
+ background-image: url(../../img/amo2009/icons/buttons/breadcrumb.gif);
+ background-repeat: no-repeat;
+ background-position: top right;
+ padding-right: 1em;
+}
+
+ol.breadcrumbs li:last-child {
+ background-image: none;
+ padding-right: 0;
+}
+
+/* @end */
+
+/* @group Feedback Form */
+
+form.addon-feedback {
+ width: 50%;
+ float: left;
+ margin-right: 1.5em;
+ margin-top: 1em;
+}
+
+form.addon-feedback textarea {
+ width: 80%;
+ background-color: #E3F3F9;
+ float: right;
+ min-height:140px;
+}
+form.addon-feedback select {
+ background-color: #E3F3F9;
+ margin-left: 1%;
+}
+form.addon-feedback label {
+ float: left;
+ clear: both;
+ width: 18%;
+ margin-bottom: 1em;
+}
+
+form.addon-feedback button {
+ display: block;
+ margin-top: 1em;
+ clear: both;
+}
+
+form.addon-feedback div.container {
+ clear: both;
+ margin-bottom: 0.5em;
+ overflow: hidden;
+}
+
+/* @end */
+
+/* @group Listing */
+
+.listing {
+ margin-bottom: 1em;
+}
+
+/* @group Listing - Header */
+
+.listing-header {
+ background-color: #F0F8FC;
+ background-image: url(../../img/amo2009/bg/listing-header.gif);
+ background-repeat: repeat-x;
+ background-position: bottom left;
+ border-bottom: 1px solid #A5BFCE;
+ -webkit-border-top-right-radius: 3px;
+ -webkit-border-top-left-radius: 3px;
+ -moz-border-radius: 3px 3px 0 0;
+ border-radius: 3px 3px 0 0;
+ padding: 0.1em 0 0.1em 0.25em;
+ overflow: hidden;
+}
+.listing-header ul {
+ margin-bottom: 0;
+ float: left;
+}
+.listing-header li {
+ line-height: 2.5;
+ display: inline;
+ margin: 0 0.25em;
+}
+.listing-header li a {
+ color: #223355;
+ font-weight: bold;
+ text-decoration: none;
+ border: 1px solid transparent;
+ -webkit-border-radius: 3px;
+ -moz-border-radius: 3px;
+ border-radius: 3px;
+ padding: 0.3em 0.8em;
+ white-space: nowrap;
+}
+.listing-header li a:hover,
+.listing-header li a:focus {
+ background-color: #BBDCE8;
+}
+.listing-header li.selected a:link,
+.listing-header li.selected a:visited,
+.listing-header li.selected a:hover,
+.listing-header li.selected a:focus,
+.listing-header li.selected a:active {
+ color: #fff;
+ background-color: #223355;
+ border-color: #001133;
+ border-width: 1px 0 0 1px;
+}
+
+/* @group Item sort form */
+
+.item-sort {
+ margin:0.2em 0.5em 0 0.5em;
+ text-align:right;
+ white-space:nowrap;
+ float: right;
+}
+
+
+
+/* @end */
+
+/* @end */
+
+/* @group Listing - Footer */
+
+.listing-footer {
+ background-color: #FFFFFF;
+ background-image: url(../../img/amo2009/bg/listing-footer.gif);
+ background-repeat: repeat-x;
+ background-position: left top;
+ border-top: 1px solid #A5BFCE;
+ -webkit-border-bottom-right-radius: 3px;
+ -webkit-border-bottom-left-radius: 3px;
+ -moz-border-radius: 0 0 3px 3px;
+ border-radius: 0 0 3px 3px;
+ margin-top: -1px;
+ position: relative;
+ z-index: 10;
+ overflow: hidden;
+ padding:0.3em 1em 0.5em;
+}
+.listing-footer a {
+ font-weight: bold;
+}
+.listing-footer .subscribe,
+.listing-footer .pagination {
+ float: left;
+}
+
+.listing-footer .subscribe {
+ margin-top: 0.3em;
+}
+
+.listing-footer .more-info {
+ margin-top: 0.3em;
+}
+
+
+/* @end */
+
+/* @group Items */
+
+.item {
+ margin: 1.2em 0;
+ padding-top:1px;
+}
+.item blockquote {
+ font-style: normal;
+ margin: 0;
+}
+.item blockquote p {
+ margin-bottom: 0.5em;
+}
+
+/* @group Headings */
+
+.item h5 {
+ font-size: 1.167em; /* 14px */
+ margin-top: 0.5em;
+ margin-bottom: 0.2em;
+}
+.item h3,
+.item h4 {
+ font-size: 1.385em; /* 18px */
+ font-weight: bold;
+ line-height: 1em;
+ margin-top: 0;
+ margin-bottom: 0.778em;
+ overflow: hidden;
+}
+.item h3 span,
+.item h4 span {
+ font-size: 0.667em; /* 13px */
+ font-weight: normal;
+ display:block;
+}
+.item h5 span {
+ font-size: 0.857em;
+ font-weight:normal;
+ white-space: nowrap;
+}
+
+/* @end */
+
+/* @group Item information */
+
+.item .meta {
+ font-size: 0.923em; /* 12px */
+ border-top: 1px dotted #B5D9E5;
+ padding-top: 0.3em;
+}
+.item .meta .addons {
+ margin-right: 1em;
+}
+.html-rtl .item .meta .addons {
+ margin-right: auto;
+ margin-left: 1em;
+}
+
+.item .downloads {
+ margin-left: 1em;
+}
+.html-rtl .item .downloads {
+ margin-left: auto;
+ margin-right: 1em;
+}
+
+/* @group Item info (aligned Right) */
+
+.item-info {
+ float: right;
+ width: 13em;
+ padding-left:2%;
+ margin-left: 2%;
+}
+
+.item .item-info {
+ border-left: 1px dotted #B4DFEE;
+ /*margin-bottom: -50em;
+ padding-bottom: 50em;*/
+}
+.item-info ul {
+ list-style-type: none;
+}
+
+/* @end */
+
+/* @group Install Information */
+
+.item .install {
+ float: right;
+ text-align: center;
+ -webkit-border-radius: 11px;
+ -moz-border-radius: 11px;
+ border-radius: 11px;
+ padding: 0 3px 3px 3px;
+ margin-left: 0.5em;
+}
+
+.item .unavailable {
+ border: 1px solid #D2E7EE;
+ padding: 0.3em;
+ width: 10em;
+ background-color: #FFFFFF;
+ color: #666666;
+}
+
+.recommended .install {
+ background-color: #efe;
+ border: 1px solid #2a2;
+}
+
+.experimental .install{
+ background-color: #fee;
+ border: 1px solid #f66;
+}
+
+.item .install strong {
+ display: block;
+ font-weight: normal;
+ font-size: 0.85em;
+ line-height: 1em;
+ color: #000;
+ text-shadow: #FFFFFF 1px 1px 1px;
+ clear: left;
+}
+
+/* @end */
+
+
+
+/* @end */
+
+/* @group Listing and seperated items */
+.separated-listing h3 {
+ float: left;
+ margin-top: 0;
+}
+
+.html-rtl .separated-listing h3 {
+ float: right;
+}
+
+.separated-listing .item h3 {
+ float: none;
+}
+
+.separated-listing form.item-sort {
+ float: right;
+ margin-top: -0.2em;
+}
+
+.html-rtl .separated-listing form.item-sort {
+ float: left;
+}
+
+.separated-listing .item .item-info {
+ border: none;
+ margin-bottom: 2em;
+}
+
+.separated-listing .item .item-info p {
+ margin: 0;
+}
+
+.separated-listing .item .downloads {
+ margin: 0;
+}
+
+.separated-listing blockquote {
+ margin-right: 11em;
+}
+
+.separated-listing .item-info p:first-child {
+ margin-bottom: 1em;
+}
+
+.listing .item,
+.separated-listing .item {
+ padding: 1em 1em 1em 52px;
+ position: relative;
+ background-color: #FFFFFF;
+ overflow: hidden;
+ clear: both;
+}
+.separated-listing .item {
+ border: 1px solid #C9E8F3;
+ margin: 0 0 1em 0;
+ -moz-border-radius:3px;
+ -webkit-border-radius: 3px;
+ border-radius:3px;
+}
+
+.listing .item {
+ border-bottom: 1px solid #D6E9F0;
+ background-image: url(../../img/amo2009/bg/listing-item.png);
+ background-repeat: repeat-x;
+ background-position: left bottom;
+ margin: 0 0 0 0;
+}
+
+.listing .item img.icon,
+.separated-listing .item img.icon {
+ position: absolute;
+ top: 0.5em;
+ left: 7px;
+}
+
+/* @group Item variations */
+
+.listing .recommended,
+.separated-listing .recommended {
+ background-image: url(../../img/amo2009/bg/listing-item-yellow.png);
+ border-color: #fc9;
+}
+.recommended .meta {
+ border-color: #fc9;
+}
+
+.listing .experimental,
+.separated-listing .experimental {
+ background-image: url(../../img/amo2009/bg/listing-item-red.png);
+ border-color: #fcc;
+}
+.experimental .meta {
+ border-color: #fcc;
+}
+
+/* @end */
+
+/* @end */
+
+/* @end */
+
+/* @end */
+
+/* @group Object Lead */
+
+.object-lead {
+ padding: 1em;
+ margin: 0;
+ background-image: url(../../img/amo2009/bg/listing-item.png);
+ background-repeat: repeat-x;
+ background-position: left bottom;
+ overflow: hidden;
+ position: relative;
+}
+
+.object-lead img.avatar {
+ border: 3px solid #C8E8F3;
+ width: 128px;
+ height: 128px;
+ float: left;
+ margin-right: 1em;
+}
+
+.object-lead form {
+ margin:0;
+}
+
+.object-lead h3 {
+ margin-top: 0;
+}
+
+.object-lead .meta {
+ float: right;
+ width: 18em;
+ padding-left: 2%;
+ margin: 2em 2% 0 0;
+ margin-left: 1em;
+ border-left: 1px dotted #B4DFEE;
+}
+
+.html-rtl .object-lead .meta {
+ float: left;
+ padding-left: auto;
+ padding-right: 2%;
+ margin-left: 2%;
+ margin-right: 1em;
+ border-left: none;
+ border-right: 1px dotted #B4DFEE;
+}
+
+.object-lead .object-info p {
+ margin: 0;
+}
+
+.object-lead .user-role {
+ position: absolute;
+ top: 1em;
+ right:0;
+ background-image:url(../../img/amo2009/icons/developer.png);
+ background-position: left center;
+ background-repeat: no-repeat;
+ padding: 0.3em 1.18em 0.3em 35px;
+ text-transform: uppercase;
+ font-size: 0.846em;
+}
+
+.object-lead .notification {
+ background-color: #C8E8F3;
+ border: none;
+ margin-top: 2em;
+ margin-bottom: 1em;
+}
+
+.object-lead .button-wrapper {
+ float: left;
+ margin-top:0.5em;
+ overflow: hidden;
+}
+
+/* @group Object Content */
+
+.object-content {
+ margin-left: 220px;
+}
+
+.vcard .object-content {
+ margin-left: 150px;
+}
+
+.object-lead table,
+.object-lead tbody {
+ border-top: none;
+ border-bottom: none;
+}
+
+.object-lead table {
+ width: 100%;
+ margin-top: 1em;
+}
+
+.object-lead table tr th {
+ width: 20%;
+}
+
+.object-lead table tr td,
+.object-lead table tr th {
+ border-top: 1px dotted #A5C9D5;
+ border-bottom: none;
+}
+
+.object-lead table tr:first-child td,
+.object-lead table tr:first-child th {
+ border-top: none;
+}
+
+/* @end */
+
+
+
+/* @end */
+
+/* @group Person Info table */
+
+table.person-info th,
+table.person-info td {
+ display: block;
+}
+
+table.person-info td {
+ border-top:none;
+ margin: 0;
+ padding: 0.1em 0 0.3em 0;
+}
+
+table.person-info th {
+ border-top:1px dotted #A5C9D5;
+ margin: 0;
+ padding: 0.3em 0 0 0;
+}
+
+table.person-info tr:first-child th {
+ border-top: none;
+}
+
+table.person-info tbody {
+ border-top:none;
+}
+
+table.person-info {
+ border-bottom:none;
+}
+
+table.person-info a:link,
+table.person-info a:visited,
+table.person-info a:hover,
+table.person-info a:focus,
+table.person-info a:active {
+ font-weight: bold;
+}
+
+/* @end */
+
+/* @group Collection Columns */
+
+
+.article-wrapper {
+ margin-bottom: 1em;
+ clear: both;
+}
+
+.article-wrapper .article {
+ padding-bottom: 0;
+}
+
+.article-wrapper h3 {
+ margin-top: 0;
+}
+
+/* @end */
+
+/* @group Further Navigation */
+
+ul.further-navigation {
+ border-top: 1px dotted #B4DFEE;
+ padding-top: 1em;
+ margin-top: 1.5em;
+}
+
+ul.further-navigation li {
+ display: inline;
+ padding-right: 1em;
+}
+
+ul.further-navigation li a {
+ font-weight: bold;
+}
+
+/* @end */
+
+/* @end */
+
+/* @group Overrides */
+
+/* @group RL languages */
+
+
+
+/* class on the html element in order to work with arabic etc */
+
+.html-rtl {
+ text-align: right;
+ direction: rtl
+}
+
+.html-rtl .primary {
+ float: left;
+ clear: left;
+}
+.html-rtl .secondary {
+ float: right;
+ clear: right;
+}
+.html-rtl .primary .primary {
+ float: right;
+ clear: none;
+}
+.html-rtl .primary .secondary {
+ float: left;
+ clear: none;
+}
+
+/* @group Helper Styles */
+
+/* @group Generic Image Styles */
+
+
+
+/* @end */
+
+/* @group More Info */
+
+.html-rtl .more-info {
+ float: left;
+}
+.html-rtl .more-info,
+.html-rtl .more-info:link,
+.html-rtl .more-info:visited,
+.html-rtl .more-info:hover,
+.html-rtl .more-info:focus,
+.html-rtl .more-info:active {
+background-position:left -253px;
+padding-right:0;
+padding-left: 1em;
+}
+
+.html-rtl .more-info:hover,
+.html-rtl .more-info:focus,
+.html-rtl .more-info:active {
+background-position:left -303px;
+}
+.html-rtl .hasJS .item a.show-expanded {
+ float: left;
+}
+
+.html-rtl .highlight .more-info {
+ float: right;
+}
+
+.html-rtl .highlight .further-navigation .more-info {
+ float: left;
+}
+
+.html-rtl.hasJS .section-teaser .window .more-info {
+ background-position:left -155px;
+}
+
+.html-rtl .section-teaser .addon-view .more-info {
+ float: none;
+}
+
+/* @end */
+
+/* @group Icon Indicators */
+
+.html-rtl .subscribe {
+ background-position: right 2px;
+ padding: 0 20px 0 0;
+}
+
+.html-rtl .share {
+ background-position: right -100px;
+ padding: 0 20px 0 0;
+ float: right;
+}
+
+.html-rtl .addons {
+ background-position: right -200px;
+ padding: 0 20px 7px 0;
+}
+.html-rtl .collections {
+ background-position: right -300px;
+ padding: 0 20px 0 0;
+}
+.html-rtl .subscribers {
+ background-position: right -400px;
+ padding: 0 20px 7px 0;
+}
+.html-rtl .category {
+ background-position: right -500px;
+ padding: 0 20px 0 0;
+}
+.html-rtl .tags {
+ background-position: right -600px;
+ padding: 0 20px 0 0;
+}
+.html-rtl .digg {
+ background-position: right -900px;
+ padding: 0 20px 0 0;
+}
+.html-rtl .delicious {
+ background-position: right -1000px;
+ padding: 0 20px 0 0;
+}
+.html-rtl .facebook {
+ background-position: right -1100px;
+ padding: 0 20px 0 0;
+}
+.html-rtl .friendfeed {
+ background-position: right -1200px;
+ padding: 0 20px 0 0;
+}
+.html-rtl .myspace {
+ background-position: right -1300px;
+ padding: 0 20px 0 0;
+}
+
+.html-rtl li.subscribe,
+.html-rtl li.share,
+.html-rtl li.addons,
+.html-rtl li.collections,
+.html-rtl li.subscribers,
+.html-rtl li.category,
+.html-rtl li.tags,
+.html-rtl li.digg,
+.html-rtl li.delicious,
+.html-rtl li.facebook,
+.html-rtl li.friendfeed,
+.html-rtl li.myspace,
+.html-rtl a.subscribe,
+.html-rtl a.share,
+.html-rtl a.addons,
+.html-rtl a.collections,
+.html-rtl a.subscribers,
+.html-rtl a.category,
+.html-rtl a.tags,
+.html-rtl a.digg,
+.html-rtl a.delicious,
+.html-rtl a.facebook,
+.html-rtl a.friendfeed,
+.html-rtl a.myspace {
+ padding-right:20px;
+ text-align: right;
+}
+
+.html-rtl .stars {
+ text-indent:-5000px;
+}
+
+/* @end */
+
+/* @end */
+
+/* @group Inverse layout */
+
+.html-rtl .inverse .primary {
+ float: right;
+ clear: right;
+}
+.html-rtl .inverse .secondary {
+ float: left;
+ clear: left;
+}
+.html-rtl .inverse .primary .primary {
+ float: right;
+ clear: none;
+}
+.html-rtl .section .inverse .primary {
+ float: left;
+ clear: none;
+}
+.html-rtl .inverse .primary .secondary {
+ float: left;
+ clear: none;
+}
+.html-rtl .section .inverse .secondary {
+ float: right;
+ clear: none;
+}
+
+
+/* @end */
+
+/* @group Header */
+
+.html-rtl #header #title {
+ direction: ltr;
+ text-align: right;
+}
+
+/* @group Stats */
+
+.html-rtl .stats {
+ text-align: left;
+ float: left;
+}
+
+.html-rtl .stats li {
+ overflow: hidden;
+}
+
+.html-rtl .stats strong {
+ float: right;
+ margin-left: 0.5em;
+}
+
+.html-rtl .stats span {
+ float: right;
+}
+
+.html-rtl ol.breadcrumbs {
+ margin-bottom: 2em;
+}
+
+.html-rtl ol.breadcrumbs li {
+ float: right;
+ background-position:left -47px;
+ padding-right:0;
+ padding-left:1em;
+}
+
+/* @end */
+
+/* @group Brand */
+
+.html-rtl #brand {
+ left: auto;
+ right: 0;
+}
+
+.html-rtl #brand a:link,
+.html-rtl #brand a:visited,
+.html-rtl #brand a:hover,
+.html-rtl #brand a:focus,
+.html-rtl #brand a:active {
+ background-position: top right;
+ text-indent: -5000px;
+}
+
+/* @end */
+
+/* @group Aux nav */
+
+.html-rtl #aux-nav {
+ right: auto;
+ left: 0;
+ margin: 0 100px 0 0;
+ text-align: left;
+ background-position: top left;
+}
+
+/*
+
+.html-rtl #aux-nav a:link,
+.html-rtl #aux-nav a:visited,
+.html-rtl #aux-nav a:hover,
+.html-rtl #aux-nav a:focus,
+.html-rtl #aux-nav a:active {
+ margin-left: 1em;
+}
+
+.html-rtl #aux-nav a.change:link,
+.html-rtl #aux-nav a.change:visited,
+.html-rtl #aux-nav a.change:hover,
+.html-rtl #aux-nav a.change:focus,
+.html-rtl #aux-nav a.change:active {
+ background-position: top right;
+ padding-left: 0;
+ padding-right: 1em;
+ float: left;
+ margin-left: 0;
+ margin-right: 1em;
+}
+*/
+
+/* @end */
+
+/* @end */
+
+/* @group Footer */
+
+.html-rtl #footer .primary {
+ float: right;
+ background-position: right 70px;
+}
+.html-rtl #footer .secondary {
+ float: left;
+ text-align: left;
+}
+.html-rtl #footer p {
+ margin-right: 60px;
+ margin-left: 1em;
+}
+.html-rtl #footer ul {
+ margin-right: 60px;
+ margin-left: 1.273em;
+}
+.html-rtl #footer ul li {
+ display: inline;
+ margin-right: 0;
+ margin-left: 1em;
+}
+.html-rtl #footer .disclaimer {
+ margin-left: 1.273em;
+ margin-right: 60px;
+}
+
+.html-rtl #footer .languages {
+ float: left;
+}
+
+.html-rtl .stars {
+ float: right;
+ margin-left: 0.5em;
+ margin-right: 0;
+}
+
+.html-rtl h5 img.icon,
+.html-rtl h2 img.icon {
+ float: right;
+ margin-right:0;
+ margin-left: 10px;
+}
+
+/* @end */
+
+/* @group Components */
+
+/* @group Further Navigation */
+
+.html-rtl ul.further-navigation li {
+ padding-right: 0;
+ padding-left: 1em;
+}
+
+/* @end */
+
+/* @group Star Select Replacement */
+
+.html-rtl .selectReplacement {
+ float: right;
+}
+
+/* @end */
+
+/* @group Steps */
+
+.html-rtl h4.step {
+ left: auto;
+ right: 0;
+}
+
+.html-rtl ol.numbered li {
+ padding-left:0;
+ padding-right:50px;
+}
+
+/* @end */
+
+/* @group Privacy Policy */
+
+.html-rtl .privacy-policy {
+ display: block;
+}
+
+/* @end */
+
+/* @group Homepage teaser */
+
+.html-rtl .section-teaser .slideshow-controls {
+ direction: rtl;
+}
+
+
+/* @end */
+
+/* @group Tables */
+
+.html-rtl table tr td,
+.html-rtl table tr th {
+ text-align: right;
+}
+
+/* @end */
+
+/* @group Pagination */
+
+.html-rtl ol.pagination {
+ float: right;
+}
+
+.html-rtl ol.pagination li {
+ float: right;
+}
+
+.html-rtl ol.pagination span.next,
+.html-rtl ol.pagination a[rel~="next"] {
+ background-position:left -420px;
+ padding-left: 1em;
+ padding-right: 0.4em;
+}
+
+.html-rtl ol.pagination span.prev,
+.html-rtl ol.pagination a[rel~="prev"] {
+ background-position:right -340px;
+ padding-right: 1em;
+ padding-left: 0.4em;
+}
+
+.html-rtl ol.pagination span.prev {
+ background-position: 92% -500px;
+}
+.html-rtl ol.pagination span.next {
+ background-position: 5px -540px;
+}
+
+/* @end */
+
+/* @group SearchForm */
+
+.html-rtl .hasJS .dropdown-categories {
+ left: auto;
+ right: 0;
+}
+
+.html-rtl .hasJS .dropdown-categories img {
+ position: absolute;
+ left: auto;
+ right: 10px;
+ top: 12px;
+}
+
+.html-rtl .hasJS .dropdown-categories h2,
+.html-rtl .hasJS .dropdown-categories h3 {
+ padding-right: 35px;
+ padding-left: 0;
+}
+
+.html-rtl .search-form {
+ float: left;
+}
+
+.html-rtl .secondary .search-form {
+ float: none;
+}
+
+.html-rtl .search-form .subsidiary .container {
+ float: right;
+}
+
+.html-rtl .search-form .important .application select,
+.html-rtl .search-form .important .application input {
+ margin: 0;
+}
+
+.html-rtl .search-form .basic input {
+ background-position:right center;
+ margin-right: 1.4%;
+ margin-left: 0;
+}
+
+.html-rtl .search-form .basic label,
+.html-rtl .search-form .basic select,
+.html-rtl .search-form .basic input,
+.html-rtl .search-form .basic button {
+ float: right;
+}
+
+.html-rtl .search-form .basic button {
+ left: 1.4%;
+ right: auto;
+}
+
+.html-rtl .search-form .important .application label,
+.html-rtl .search-form .subsidiary label {
+ float: right;
+}
+
+.html-rtl form.addon-feedback label {
+ float: right;
+}
+
+.html-rtl form.addon-feedback textarea {
+ float: left;
+}
+
+/* @end */
+
+/* @group Share This */
+
+.html-rtl .share-networks {
+ background-position:160px top;
+ clear:both;
+}
+
+.html-rtl .share-this {
+ clear: right;
+ float: right;
+}
+
+
+/* @end */
+
+/* @group Feedback Form */
+
+.html-rtl form.addon-feedback {
+ float: right;
+ margin-right: 0;
+ margin-left: 1.5em;
+}
+
+/* @end */
+
+/* @group Meta */
+
+
+.html-rtl .meta .subscribers {
+ background-position: right -400px;
+ float: left;
+}
+
+.html-rtl .meta .addons {
+ background-position: right -200px;
+ float: left;
+
+}
+
+/* @end */
+
+
+
+/* @group Buttons */
+
+.html-rtl a:link.button img,
+.html-rtl a:visited.button img,
+.html-rtl a:hover.button img,
+.html-rtl a:focus.button img,
+.html-rtl a:active.button img,
+.html-rtl button img {
+ border-right:none;
+ border-left:1px solid #3399FF;
+ margin-right:0;
+ margin-left: 0.7em;
+ padding-right:0.2em;
+ padding-left: 0.4em;
+}
+
+.html-rtl a:link.negative img,
+.html-rtl a:visited.negative img,
+.html-rtl a:hover.negative img,
+.html-rtl a:focus.negative img,
+.html-rtl a:active.negative img,
+.html-rtl button.negative img {
+ border-right:none;
+ border-left:1px solid #E54C4F;
+}
+
+.html-rtl a:link.button.positive img,
+.html-rtl a:visited.button.positive img,
+.html-rtl a:hover.button.positive img,
+.html-rtl a:focus.button.positive img,
+.html-rtl a:active.button.positive img,
+.html-rtl button.positive img {
+ border-right:none;
+ border-left:1px solid #55AA00;
+}
+
+.html-rtl a:link.button.neutral img,
+.html-rtl a:visited.button.neutral img,
+.html-rtl a:hover.button.neutral img,
+.html-rtl a:focus.button.neutral img,
+.html-rtl a:active.button.neutral img,
+.html-rtl button.neutral img {
+ border-right:none;
+ border-left:1px solid #DD7711;
+}
+
+.html-rtl .search-form button img {
+ border-left: none;
+}
+
+.html-rtl button.add-to-fav {
+ background-position: right;
+ float: right;
+ padding:0.5em 19px 0.2em 0px;
+}
+
+/* @end */
+
+/* @group Listing */
+
+/* @group Listing - Header */
+
+.html-rtl .listing-header .item-sort {
+ float: left;
+}
+
+.html-rtl .listing-header ul {
+ float: right;
+}
+
+/* @end */
+
+
+
+/* @group Listing - Footer */
+
+.html-rtl .listing-footer .subscribe {
+ float: right;
+ margin-left: 1em;
+}
+
+.html-rtl .listing-footer .subscribe,
+.html-rtl .pagination {
+ float: right;
+}
+
+/* @end */
+
+/* @group Listing items */
+
+.html-rtl .listing .item,
+.html-rtl .separated-listing .item {
+padding:1em 52px 1em 1em;
+}
+
+.html-rtl .item .install {
+ float: left;
+ margin-left: 0;
+ margin-right: 0.5em;
+}
+.html-rtl .item img.icon {
+ left: auto;
+ right: 7px;
+}
+
+.html-rtl .item .downloads {
+ margin-left: 0;
+ margin-right: 1em;
+}
+
+.html-rtl .item-info {
+ float: left;
+ border-left:none;
+ border-right:1px dotted #B4DFEE;
+ margin-left:0;
+ margin-left:2%;
+ padding-left: 0;
+ padding-right:2%;
+ margin-right: 2%;
+}
+
+.html-rtl .item-info ul {
+ text-align: left;
+}
+
+.html-rtl .item .thumbnail {
+ float: right;
+ margin-left:1em;
+ margin-right:0;
+}
+
+.html-rtl .screenshot.thumbnail {
+ float: right;
+ margin-right: 0;
+ margin-left: 1em;
+}
+
+.html-rtl .separated-listing blockquote {
+ margin-right:0;
+ margin-left:11em;
+}
+
+/* @end */
+/* @end */
+
+/* @group Object Lead */
+
+.html-rtl .object-lead .user-role {
+ background-position:right center;
+ left:160px;
+ right: inherit;
+ padding:0.3em 35px 0.3em 1.18em;
+}
+
+.html-rtl .object-content {
+ margin-right:0;
+ margin-left:220px;
+}
+
+/* @end */
+
+
+
+/* @end */
+/* @end */
+
+/* @group Different Applications */
+
+.firefox h2 {
+ color: #C63717;
+}
+.firefox #aux-nav .change li.firefox {
+ display: none;
+}
+
+.thunderbird h2 {
+ color: #105399;
+}
+.thunderbird #aux-nav .change li.thunderbird {
+ display: none;
+}
+
+.sunbird h2 {
+ color: #007940;
+}
+.sunbird #aux-nav .change li.sunbird {
+ display: none;
+}
+
+.seamonkey h2 {
+ color: #1408E5;
+}
+.seamonkey #aux-nav .change li.seamonkey {
+ display: none;
+}
+
+
+/* @end */
+
+/* @end */
+
+
+
+
+
+
+
+
+
+
+
diff --git a/site/app/webroot/css/amo2009/slimbox2.css b/site/app/webroot/css/amo2009/slimbox2.css
new file mode 100755
index 0000000..526e00c
--- /dev/null
+++ b/site/app/webroot/css/amo2009/slimbox2.css
@@ -0,0 +1,83 @@
+/* SLIMBOX */
+
+#lbOverlay {
+ position: fixed;
+ z-index: 9999;
+ left: 0;
+ top: 0;
+ width: 100%;
+ height: 100%;
+ background-color: #000;
+ cursor: pointer;
+}
+
+#lbCenter, #lbBottomContainer {
+ position: absolute;
+ z-index: 9999;
+ overflow: hidden;
+ background-color: #fff;
+}
+
+.lbLoading {
+ background: #fff url(../../img/amo2009/lightbox/loading.gif) no-repeat center;
+}
+
+#lbImage {
+ position: absolute;
+ left: 0;
+ top: 0;
+ border: 10px solid #fff;
+ background-repeat: no-repeat;
+}
+
+#lbPrevLink, #lbNextLink {
+ display: block;
+ position: absolute;
+ top: 0;
+ width: 50%;
+ outline: none;
+}
+
+#lbPrevLink {
+ left: 0;
+}
+
+#lbPrevLink:hover {
+ background: transparent url(../../img/amo2009/lightbox/prevlabel.gif) no-repeat 0 15%;
+}
+
+#lbNextLink {
+ right: 0;
+}
+
+#lbNextLink:hover {
+ background: transparent url(../../img/amo2009/lightbox/nextlabel.gif) no-repeat 100% 15%;
+}
+
+#lbBottom {
+ font-family: Verdana, Arial, Geneva, Helvetica, sans-serif;
+ font-size: 10px;
+ color: #666;
+ line-height: 1.4em;
+ text-align: left;
+ border: 10px solid #fff;
+ border-top-style: none;
+}
+
+#lbCloseLink {
+ display: block;
+ float: right;
+ width: 66px;
+ height: 22px;
+ background: transparent url(../../img/amo2009/lightbox/closelabel.gif) no-repeat center;
+ margin: 5px 0;
+ outline: none;
+}
+
+#lbCaption, #lbNumber {
+ margin-right: 71px;
+}
+
+#lbCaption {
+ font-weight: bold;
+}
diff --git a/site/app/webroot/css/base.template.css b/site/app/webroot/css/base.template.css
new file mode 100644
index 0000000..3188d84
--- /dev/null
+++ b/site/app/webroot/css/base.template.css
@@ -0,0 +1,95 @@
+/* mozilla.org MezzoTan DevMo Template Styles
+ *
+ */
+
+/* Link Navigation */
+
+ #tNavTop,
+ #tNavBottom {
+ list-style: none;
+ text-align: right;
+ }
+ #tNavTop > li,
+ #tNavBottom > li {
+ display: block;
+ }
+ #tNavTop:before,
+ #tNavBottom:after {
+ clear: both;
+ }
+
+ #tNavTop a[rel="prev"],
+ #tNavBottom a[rel="prev"] {
+ float: left;
+ text-align: left;
+ }
+
+ #tNavTop a[rel="toc"] {
+ display: block;
+ text-align: center;
+ }
+
+ #tNavTop a[rel="next"],
+ #tNavBottom a[rel="next"] {
+ float: right;
+ }
+
+/* Footer */
+
+ .tLicense {
+ font-size: smaller;
+ }
+
+ #mBody {
+ clear: both;
+ padding: 0 0 1em 0;
+ }
+
+ #side {
+ float: left;
+ width: 23%;
+ margin-bottom: 1em;
+ margin-top: 1em;
+ }
+
+ #mainContent {
+ float: right;
+ width: 74%;
+ margin-bottom: 3em;
+ }
+ .nomenu #mainContent {
+ float: none;
+ width: 100%;
+ }
+ .bodyleft {
+ float: right !important;
+ width: 74% !important;
+ }
+ #mainContent.right {
+ float: left;
+ width: 62%;
+ margin-bottom: 2em;
+ }
+
+ #side.right {
+ float: right;
+ width: 35%;
+ margin-bottom: 2em;
+ margin-top: 0;
+ }
+
+/* Sidebar */
+
+ #getcd {
+ margin: 1em 0 0 45px;
+ }
+
+/*accessibility tweaks*/
+ .skipLink {
+ position: absolute;
+ left: -999px;
+ width: 990px;
+ }
+ hr.hide {
+ display: none;
+ }
diff --git a/site/app/webroot/css/browse.css b/site/app/webroot/css/browse.css
new file mode 100644
index 0000000..3f0c902
--- /dev/null
+++ b/site/app/webroot/css/browse.css
@@ -0,0 +1,280 @@
+div#frame {
+ font-family:Arial, Helvetica, Verdana, sans-serif;
+ font-size:12px;
+ color:#000;
+}
+
+a#developer {
+ color:#999;
+ font-weight:bold;
+ font-size:11px;
+}
+a#browseList {
+ color:#999;
+ text-decoration:none;
+ font-weight:bold;
+ font-size:14px;
+}
+div#addons {
+ width:572px;
+ float:left;
+ position:relative;
+ margin-top:0px;
+ padding-right:15px;
+ background:url('/images/sidebarBackground.gif') repeat-y 539px;
+}
+div#addons h3#featured {
+ font-size:13px;
+ color:#666;
+ border-bottom:1px solid #bbb;
+}
+
+div#addons h3#browsing {
+ font-size:15px;
+ color:#444;
+ margin-bottom:0px;
+}
+div#addons span#browsing {
+ font-size:12px;
+ font-style:italic;
+ color:#666;
+}
+div#addons div#primaryAddon {
+ width:570px;
+ min-height:160px;
+ padding-bottom:20px;
+ border:1px solid #E8E8E8;
+ background-color:#F8F8F8;
+}
+div#primaryAddon div#primaryIcons {
+ width:40px;
+ float:left;
+ margin-top:10px;
+ margin-left:10px;
+
+}
+div#primaryAddon div#primaryDesc {
+ margin-top:10px;
+ margin-left:50px;
+ width:300px;
+}
+
+div#primaryAddon img#primaryImage {
+ margin-top:10px;
+ margin-right:10px;
+ float:right;
+ border:1px solid #E8E8E8;
+}
+div#primaryAddon div#reviewIcon {
+ margin-top:10px;
+ clear:left;
+ float:left;
+ margin-left:8px;
+ margin-right:5px;
+}
+
+div#primaryAddon div#reviewDesc {
+margin-top:30px;
+font-style:italic;
+width:560px;
+}
+div#primaryAddon span#reviewAuthor {
+ color:#AAA;
+ font-weight:bold;
+ font-size:12px;
+ font-style:normal;
+}
+div#primaryDesc span#recentVersion {
+ color:#AAA;
+ margin-top:5px;
+ font-weight:bold;
+
+}
+div#primaryDesc img#recentVersion {
+ margin-top:5px;
+
+}
+div#addons div#secondaryAddon {
+ clear:left;
+ padding: 10px 10px 0px 10px;
+ margin: 10px 0px 0px 0px;
+ width: 260px;
+ border:1px solid #E8E8E8;
+ background-color:#F8F8F8;
+}
+div#addons div#tertiaryAddon {
+ padding: 10px 10px 0px 10px;
+ margin: 10px 0px 0px 0px;
+ float:right;
+ width: 260px;
+ border:1px solid #E8E8E8;
+ background-color:#F8F8F8;
+}
+div#addons h3#secondary {
+ margin-bottom:0px;
+
+ margin-top:5px;
+ font-size:13px;
+}
+div#addons div#greatAddons {
+ width:600;
+ font-size:11px;
+ font-weight:bold;
+}
+div#addons img#secondaryIcon {
+ display: inline;
+ margin-left:2px;
+}
+div#addons p#secondaryText {
+ margin-top:10px;
+}
+div#greatAddons h3#great {
+
+ font-size:13px;
+ margin-bottom:5px;
+ color:#666;
+ border-bottom:1px solid #bbb;
+}
+h2#addonName {
+ width:379px;
+
+ font-size:20px;
+ font-weight:bold;
+ line-height:1;
+ margin:0px;
+ padding:0px;
+}
+ h2#addonName span#version {
+ font-weight:normal;
+ color:#888;
+ font-size:12px;
+ line-height:1;
+ }
+
+span#developer {
+ font-size:10px;
+ font-weight:bold;
+ line-height:1;
+ color:#666;
+}
+
+span#tagline {
+ color:#555;
+}
+
+ div.versionNotes h3 {
+ font-size:12px;
+ font-weight:bold;
+ margin:0px;
+ padding:0px;
+ }
+ div.versionNotes h3 span {
+ font-weight:normal;
+ color:#acacac;
+ }
+
+div#sidebar {
+
+ float:right;
+ line-height:1.5;
+ font-size:11px;
+ width:140px;
+ min-height:500px;
+ padding-left:20px;
+ border-left:1px solid #ccc;
+}
+ div#sidebar h3 {
+ margin:0px 0px 4px 0px;
+ padding:0px 0px 5px 0px;
+
+ float:left;
+ font-weight:bold;
+ font-size:12px;
+ color:#444;
+
+ border-bottom:1px solid #ccc;
+ }
+ div#sidebar img#subscribe {
+ float:left;
+ margin-right:5px;
+ }
+ div#sidebar h3#subscribe {
+ float:left;
+
+ color:#666;
+ font-weight:bold;
+ font-size:9px;
+ border-bottom:0px;
+ margin-bottom:15px;
+ }
+ div#sidebar h3#browsing {
+ border-bottom:0px;
+ }
+ div#sidebar h3#categories {
+ margin-top:15px;
+ }
+ div#sidebar span#categories {
+ float:left;
+ font-weight:bold;
+ font-size:11px;
+ margin-left:12px;
+ }
+
+
+ div.review {
+ clear:right;
+ overflow:auto;
+ width:240px;
+ margin-bottom:15px;
+
+ font-size:11px;
+ color:#666;
+ }
+ div.review div.score {
+ float:left;
+ clear:left;
+
+ padding:3px 5px 1px 5px;
+ margin-right:8px;
+
+ font-size:20px;
+ color:#555;
+
+ background-color:#ddd;
+ }
+ div.review div.score span {
+ color:#aaa;
+ }
+
+ div.review span.review {
+ display:block;
+
+ width:150px;
+ float:left;
+ clear:right;
+ }
+
+ div.review a {
+ font-size:13px;
+ color:#666;
+ font-weight:bold;
+ }
+
+ div.review a.profileLink {
+ font-size:11px;
+ color:#666;
+ font-weight:normal;
+ }
+
+ a.reviewLink {
+ margin-left:45px;
+ }
+
+ div#sidebar ul {
+ margin:0px;
+ padding:0px 0px 0px 18px;
+ }
+ div#sidebar ul li {
+ margin-bottom:6px;
+ }
+
diff --git a/site/app/webroot/css/cake.generic.css b/site/app/webroot/css/cake.generic.css
new file mode 100644
index 0000000..51e97f2
--- /dev/null
+++ b/site/app/webroot/css/cake.generic.css
@@ -0,0 +1,225 @@
+*{
+margin:0;
+padding:0;
+}
+
+body{
+font-family:"frutiger linotype","lucida grande",helvetica,arial,sans-serif;
+font-size:76%;
+text-align:center;
+color:#333;
+}
+
+/*
+* General Style Info
+*/
+
+a{
+color:#003d4c;
+text-decoration:underline;
+}
+a:hover{
+color:#003d4c;
+text-decoration:none;
+}
+
+a img{
+border:none;
+}
+
+h1, h2, h3, h4{
+font-weight:normal;
+}
+
+h1{
+color: #003d4c;
+padding:0.3em 0;
+}
+
+h2{
+color:#c6c65b;
+padding-top: 1em;
+margin:0.3em 0;
+}
+
+h3{
+color:#c6c65b;
+padding-top:0.5em;
+}
+
+h4{
+color:#c6c65b;
+padding-top:0.5em;
+font-weight:normal;
+}
+
+em {
+ font-size: 12px;
+}
+
+ul, li {
+margin: 0 12px;
+}
+
+/*
+* Layout
+*/
+
+#container{
+text-align:left;
+}
+
+#amo-header{
+padding: 4px 20px;
+}
+
+#content{
+clear:both;
+padding: 10px 40px;
+background-color: #fff;
+color: #333;
+line-height: 18px;
+}
+#footer{
+clear:both;
+padding: 6px 10px;
+text-align: right;
+}
+
+/* tables */
+table {
+ width: 100%;
+ border-top: 1px solid #ccc;
+ border-left: 1px solid #ccc;
+ border-bottom: 1px solid #ccc;
+ color:#333;
+ background-color: #fff;
+ clear:both;
+ padding: 0;
+ margin: 0 0 2em 0;
+ white-space: normal;
+}
+th {
+ background-color: #e2e2e2;
+ border-top: 1px solid #fff;
+ border-left: 1px solid #fff;
+ border-right: 1px solid #003d4c;
+ border-bottom: 1px solid #003d4c;
+ text-align: center;
+ padding:1px;
+}
+table tr td {
+ border-right: 1px solid #ddd;
+ padding:4px 4px;
+ vertical-align:top;
+ text-align: center;
+}
+table tr.altRow td {
+ background: #f4f4f4;
+}
+#cakeSqlLog td {
+ text-align: left;
+ padding: 4px 8px;
+ background: #fff;
+ border-bottom: 2px solid #ccc;
+}
+
+/* scaffold show */
+
+
+div.related {
+ clear:both;
+ display:block;
+}
+dl {
+ line-height:2em;
+ margin:0em 1em;
+ float:left;
+ width: 400px;
+}
+dt {
+ font-weight: bold;
+ vertical-align:top;
+}
+dd {
+ margin-left:10em;
+ margin-top:-2em;
+ vertical-align:top;
+}
+
+/* notices and errors */
+
+#flashMessage{
+color:#300;
+background:#ffe;
+border:1px solid #060;
+margin:10px;
+padding:10px;
+}
+
+.error, error_message {
+ color:#900;
+ font-size: 18px;
+ background-color: #fff;
+ margin: 8px 4px;
+}
+.error em {
+ font-size: 18px;
+ color: #003d4c;
+}
+
+.notice {
+ color: #656565;
+ font-size: 14px;
+ background-color: #f4f4f4;
+ padding: 4px;
+ display:block;
+}
+
+.tip {
+ color: #e32000;
+ background-color: #ddd;
+}
+
+form div{
+vertical-align: text-top;
+margin-left: 2em;
+margin-bottom:1em;
+}
+label {
+display: block;
+float:left;
+width: 140px;
+}
+input,textarea {
+clear: both;
+display:block;
+}
+select {
+vertical-align: text-top;
+}
+.required{
+color:#222;
+font-weight:bold;
+}
+
+.optional{
+color:#666;
+}
+
+.submit {
+ clear: both;
+ margin-top: 18px;
+ margin-left: 140px;
+}
+
+
+/* action links */
+ul.actions {
+ float:left;
+ margin-left: 10px;
+ width: 200px;
+}
+ul.actions li {
+ margin-top: 4px;
+}
diff --git a/site/app/webroot/css/collection-style.css b/site/app/webroot/css/collection-style.css
new file mode 100644
index 0000000..bdae198
--- /dev/null
+++ b/site/app/webroot/css/collection-style.css
@@ -0,0 +1,240 @@
+body {
+ background: url(../img/fyf/bg.png) repeat-x;
+ background-color: #fff;
+ font: 85%/1.4 verdana, helvetica, arial, sans-serif;
+ color: #26709e;
+}
+
+#page {
+ width: 942px;
+ margin: 0 auto;
+}
+
+#branding {
+ padding-top: 20px;
+}
+
+#branding h1 {
+ float: left;
+ margin-top: 30px;
+}
+
+#page-title.fyf {
+ padding-top: 25px;
+ height: 6em;
+ background: none;
+}
+
+#content {
+ font-size: 0.9em;
+ min-height: 0;
+}
+
+.cat-header:hover {
+ background: url(../img/fyf/collection-bg.png) repeat-x;
+ cursor: pointer;
+}
+
+#content-main ul, #content-main li {
+ margin-bottom: 0;
+}
+
+.cat-header h3 {
+ color: #af1717;
+ font-weight: bold;
+}
+
+.cat-header:hover {
+ cursor: pointer;
+}
+
+#fashion-blurb hr {
+ background: url(../img/fyf/addonguy-large.png) no-repeat right top;
+ border: 0;
+ width: 269px;
+ height: 354px;
+ z-index: 50;
+ position: absolute;
+ right: 20px;
+ top: -100px;
+}
+
+#fashion-blurb p {
+ font-size: 1.2em;
+ width: 580px;
+ color: #333;
+}
+
+form#collectionform {
+ border-top: 2px solid #ddd;
+ padding-top: 15px;
+ z-index: 1;
+}
+
+.addon-listing {
+ background: url(../img/fyf/collection-bg2.png) repeat-x 0 bottom;
+}
+
+.cat-header {
+ padding: 10px 10px 10px 15px;
+ border-top: 3px solid #ddd;
+}
+
+.cat-header.first {
+ border-top: 0;
+}
+
+.preview-img {
+ float: left;
+ padding: 0 10px 0 0;
+ width: 200px;
+}
+
+.item-desc {
+ margin-left: 160px;
+}
+
+#branding h2 {
+ text-indent: -5000px;
+ background: url(../img/fyf/addonguy-head.png) no-repeat;
+ width: 219px;
+ height: 164px;
+ float: right;
+}
+
+#branding h3 {
+ text-indent: -5000px;
+ background: url(../img/fyf/faq_subheader.png) no-repeat;
+ width: 305px;
+ height: 27px;
+ clear: both;
+ float: left;
+ margin-top: -20px;
+}
+
+#content-main {
+ clear: left;
+ float: left;
+ margin: 15px 0 45px 0;
+ padding-top: 10px;
+}
+
+#content-main dt {
+ font-weight: bold;
+ margin-top: 20px;
+}
+
+#content-main dt {
+ font-weight: bold;
+}
+
+#content-main dd {
+ margin: 6px 0 0 0;
+}
+
+#content-main.faq ul li {
+ list-style-type: disc;
+ margin: 0 15px;
+}
+
+#successpage h1 img {
+ vertical-align: middle;
+ margin: 0 10px;
+}
+
+#successpage > p,
+#firstrun > p {
+ font-size: 120%;
+ color: #434141;
+ margin: 2em 0;
+}
+
+#firstrun {
+ background: url(../img/fyf/addonguy-success.png) no-repeat right top;
+}
+
+#firstrun .welcome h1 {
+ font-weight: normal;
+ font-size: 220%;
+ margin-left: 110px;
+ color: #fff;
+}
+
+#firstrun .welcome img {
+ margin-top: -25px;
+}
+
+#firstrun > p {
+ margin-right: 180px;
+ padding-bottom: 40px;
+}
+
+#firstrun .box {
+ border-top: #ccc solid 2px;
+ width: 240px;
+ float: left;
+ padding: 8px;
+ margin: 0 10px;
+ font-size: 110%;
+}
+
+#firstrun .box h3 {
+ color: #d00000;
+ margin-bottom: .5em;
+}
+
+#firstrun .box p,
+#firstrun .box li {
+ color: #434141;
+}
+
+#footer {
+ clear: left;
+ background: url(../img/fyf/footer-bg.png) repeat-x;
+ padding: 4px 0 20px 0;
+}
+
+#footer-legal {
+ width: 942px;
+ margin: 0 auto;
+ padding-top: 10px;
+ font-size: .7em;
+ color: #9d9d9d;
+ text-align: center;
+}
+
+#legal-links {
+ display: block;
+}
+
+#legal-links a {
+ margin-right: 6px;
+}
+
+#footer-legal p {
+ margin-bottom: 10px;
+}
+
+a {
+ color: #26709e;
+ text-decoration: none;
+}
+
+a:visited {
+ color: #26709e;
+}
+
+a:hover {
+ color: #000;
+ text-decoration: underline;
+ padding-bottom: 1px;
+}
+
+#footer a {
+ text-decoration: underline;
+}
+
+#footer a:hover {
+ border: 0;
+ text-decoration: none;
+}
diff --git a/site/app/webroot/css/color.css b/site/app/webroot/css/color.css
new file mode 100644
index 0000000..2ae6eac
--- /dev/null
+++ b/site/app/webroot/css/color.css
@@ -0,0 +1,327 @@
+/*----------------------------------------------------------------------------
+Color CSS file for Addons.mozilla.org
+Created by Craig Cook - focalcurve.com
+ on December 30, 2007
+
+Color Reference
+
+Body text (almost black): #333
+Links (medium blue): #1d587f
+Visited links (blue-gray): #748d9e
+Headings (dark blue): #2d3b58
+Box border (light blue-gray): #d8dcdf
+Special box border (dark blue): #5d6c8c
+-----------------------------------------------------------------------------*/
+
+/*** =General elements ***/
+body { background: #fff; color: #333; }
+a:link { color: #1d587f; }
+a:visited { color: #748d9e; }
+a:active, a:hover, a:focus { color: #000000; }
+
+a.view { background: transparent url("../img/sprite.png?20090430") 100% -247px no-repeat; }
+.html-ltr a.view:hover { background-position: 100% -301px; }
+.html-rtl a.view { background-position: 100% -486px; }
+.html-rtl a.view:hover { background-position: 100% -540px; }
+
+h3, h4, h5, h6 { color: #2d3b58; }
+
+td, th { border-bottom: 1px solid #eee; }
+thead th { color: #555; }
+
+input, button, select, textarea { color: inherit; }
+a img { border: none; }
+
+div.error-notice { background: #fffefa url("../img/warning.png") 10px 10px no-repeat; border: 1px solid #eee; -moz-border-radius: 6px; -webkit-border-radius: 6px; border-radius: 6px; }
+
+/*** =Site-notice ***/
+#site-notice { background: #ffe; border-bottom: 2px solid #ccc; }
+
+/*** =Access nav ***/
+#nav-access a:active, #nav-access a:focus { color: #000; background: #fff; border: 1px solid #475470; outline: 0; }
+
+/*** =Header ***/
+h4#moz a { background: transparent url("../img/sprite-alpha.png") no-repeat 0 -1px; }
+h4#moz a:hover, h1#moz a:active, h1#moz a:focus { background-position: 0 -51px; }
+
+/* =Page title */
+#page-title { background: transparent url("../img/brandbanner-bg.png") 0 40% repeat-x; }
+#page-title p.page-intro { color: #354a4f; }
+
+#page-title.firefox h1, #page-title.firefox h1 a { color: #bd1d01; } /* red */
+#page-title.thunderbird h1, #page-title.thunderbird h1 a { color: #0b4190; } /* blue */
+#page-title.fennec h1, #page-title.fennec h1 a { color: #0b4190; } /* blue */
+#page-title.seamonkey h1, #page-title.seamonkey h1 a { color: #3f38a3; } /* purple */
+#page-title.sunbird h1, #page-title.sunbird h1 a { color: #337b5a; } /* green */
+#page-title.generic h1, #page-title.generic h1 a { color: #bd1d01; } /* red */
+#page-title.developers h1, #page-title.developers h1 a { color: #bd1d01; } /* red */
+#page-title h2 { color: #2D3B58; }
+
+/* =User nav */
+.html-ltr #nav-user li { border-left: 1px solid #666; }
+.html-rtl #nav-user li { border-right: 1px solid #666; }
+#nav-user li:first-child { border-left: 0; }
+#nav-user li:first-child { border-right: 0; }
+
+#nav-user a:link { color: #000; }
+#nav-user a:visited { color: #666; }
+#nav-user a:hover, #nav-user a:active, #nav-user a:focus { color: #000; }
+
+/* =Other Applications */
+#other-apps { background-color: #b3deee; border: 1px solid #90c8dd; -moz-border-radius: 6px; -webkit-border-radius: 6px; border-radius: 6px; }
+#other-apps h3 { color: #4d757b; }
+
+#other-apps.js h3 { border-bottom: 1px solid #90c8dd; -moz-border-radius: 6px; -webkit-border-radius: 6px; border-radius: 6px; }
+#other-apps.js h3 { background: transparent url("../img/sprite.png?20090430") 4px -262px no-repeat; }
+.html-rtl #other-apps.js h3 { background-position: 14px -262px; }
+
+#other-apps.js h3:hover { background-color: #c5e3ee; }
+#nav-apps a { color: #1f0084; background-repeat: no-repeat; background-position: 0 50%; }
+#nav-apps a:hover, #nav-apps a:active, #nav-apps a:focus { color: #1d587f; }
+.html-ltr #other-apps.js #nav-apps #app-seamonkey a { background: url("../img/sprite-alpha.png") -465px 0 no-repeat;}
+.html-rtl #other-apps.js #nav-apps #app-seamonkey a { background: url("../img/sprite-alpha.png") -390px 0 no-repeat;}
+
+.html-ltr #other-apps.js #nav-apps #app-sunbird a { background: url("../img/sprite-alpha.png") -616px 0 no-repeat;}
+.html-rtl #other-apps.js #nav-apps #app-sunbird a { background: url("../img/sprite-alpha.png") -541px 0 no-repeat; }
+
+.html-ltr #other-apps.js #nav-apps #app-thunderbird a { background: url("../img/sprite-alpha.png") -766px 0 no-repeat; }
+.html-rtl #other-apps.js #nav-apps #app-thunderbird a { background: url("../img/sprite-alpha.png") -691px 0 no-repeat; }
+
+.html-ltr #other-apps.js #nav-apps #app-fennec a { background: url("../img/sprite-alpha.png") -766px 0 no-repeat; }
+.html-rtl #other-apps.js #nav-apps #app-fennec a { background: url("../img/sprite-alpha.png") -691px 0 no-repeat; }
+
+.html-ltr #other-apps.js #nav-apps #app-firefox a { background: url("../img/sprite-alpha.png") -321px 0 no-repeat; }
+.html-rtl #other-apps.js #nav-apps #app-firefox a { background: url("../img/sprite-alpha.png") -246px 0 no-repeat; }
+
+.html-ltr #other-apps.collapsed h3 { border-bottom: 0; background-position: 6px -320px; }
+.html-rtl #other-apps.collapsed h3 { border-bottom: 0; background-position: 16px -320px; }
+
+/*** =Search form ***/
+#search-bubble-outer { background: transparent url("../img/sprite.png?20090430") right top no-repeat; }
+#search-bubble-inner { background: transparent url("../img/sprite.png?20090430") left top no-repeat; }
+#search-form li { color: #666; }
+.html-ltr #search-form #query { background: #fff url("../img/sprite.png?20090430") -977px -686px no-repeat; }
+.html-rtl #search-form #query { background: #fff url("../img/sprite.png?20090430") 100% -686px no-repeat; }
+#search-form #search-category label { color: #426a13; }
+.html-ltr #search-form #my-submit { background: url("../img/sprite-alpha.png") -120px 0 no-repeat; }
+.html-ltr #search-form #my-submit:hover { background-position: -157px 0;}
+.html-rtl #search-form #my-submit { background: url("../img/sprite-alpha.png") -120px -40px no-repeat; }
+.html-rtl #search-form #my-submit:hover { background: url("../img/sprite-alpha.png") -157px -40px no-repeat;}
+
+#advanced-search {background-color: #e6e6e6; border: 1px solid #68B41C; }
+#advanced-search-toggle {background: url("../img/sprite.png?20090430") right -68px no-repeat; }
+#advanced-search-toggle div {background: transparent url("../img/sprite.png?20090430") left -68px no-repeat;}
+#advanced-search-toggle a {color: black; text-decoration: none; padding:1px 3px 1px 3px;}
+.html-ltr #advanced-search-toggle a.asclosed { background: url("../img/sprite.png?20090430") right -354px no-repeat;}
+.html-ltr #advanced-search-toggle a.asopen { background: url("../img/sprite.png?20090430") right -369px no-repeat;}
+.html-rtl #advanced-search-toggle a.asclosed {background: url("../img/sprite.png?20090430") -989px -354px no-repeat;}
+.html-rtl #advanced-search-toggle a.asopen { background: url("../img/sprite.png?20090430") -989px -369px no-repeat;}
+#advanced-search-toggle #toggle-outer {background: url("../img/sprite.png?20090430") right -87px no-repeat; }
+#advanced-search-toggle #toggle-inner {background: url("../img/sprite.png?20090430") -861px -87px no-repeat; }
+
+/*** =Footer ***/
+#footer { color: #888; padding: 1em 0; background: transparent url("../img/foot-bg.png") repeat-x; }
+#footer a:link, #footer a:visited { color: #777; }
+#footer a:hover, #footer a:active, #footer a:focus { color: #000; }
+
+/*** =Extra content ***/
+#content-extra .extra { border: 1px solid #d8dcdf; -moz-border-radius: 6px; -webkit-border-radius: 6px; border-radius: 6px; }
+
+/*** =Categories ***/
+#categories h3 { background: #79be1b url("../img/sprite.png?20090430") -104px -106px no-repeat; border-bottom: 1px solid #abe071; }
+#categories h3 span { color: #426a13; background: transparent url("../img/sprite.png?20090430") -230px -106px no-repeat; }
+#categories.collapsed h3 { background-position: 0 -106px; }
+#categories.collapsed h3.open { background-position: -26px -106px; }
+
+#categories, #categories.collapsed #cat-list { background-color: #f6f6f6; border: 1px solid #d8dcdf; border-width: 0 1px 1px; }
+#categories, #categories.collapsed #cat-list { /* redundancy compensates for varying browser support */
+ -moz-border-radius-bottomright: 6px;
+ -moz-border-radius-bottomleft: 6px;
+ -webkit-border-bottom-right-radius: 6px;
+ -webkit-border-bottom-left-radius: 6px;
+ border-bottom-right-radius: 6px;
+ border-bottom-left-radius: 6px;
+}
+#cat-list { border-top: 1px solid #e8e6e6; }
+#cat-list li { border-bottom: 3px double #e8e6e6; }
+#cat-list a { background: #f4f2f2 url("../img/cat-link.png") repeat-x left top; }
+#categories a:link { color: #4e4e4e; }
+#categories a:visited { color: #777; }
+#categories a:hover, #categories a:active, #categories a:focus { color: #1d587f; background: #f1f0f0 url("../img/cat-link.png") repeat-x left -100px; }
+
+#categories.collapsed h3 span { background-position: -242px -106px; }
+#categories.collapsed h3:hover { color: #4f7f17; background-position: -52px -106px; }
+#categories.collapsed h3.open:hover { background-position: -78px -106px; }
+#categories.collapsed h3:hover span { background-position: -533px -106px; }
+#categories p { border-top: 1px solid #e8e6e6; }
+
+
+
+/*** =Add-on boxes ***/
+.addon { border-left: 1px solid #d8dcdf; background: transparent url("../img/sprite.png?20090430") right -1256px no-repeat; }
+.addon .vex { background: transparent url("../img/sprite.png?20090430") right bottom no-repeat; }
+.addon .vex span { background: transparent url("../img/sprite.png?20090430") left bottom no-repeat; }
+.addon .preview-img { background: transparent url("../img/sprite.png?20090430") left -1256px no-repeat; }
+.addon .stats em { color: #d54601; }
+.addon .flag { border: 1px solid #ccc; border-width: 0 1px 1px 0; }
+#addon-listing .addon .vex { background: transparent url("../img/sprite.png?20090430") no-repeat right bottom; }
+
+/* =Secondary featured add-ons */
+.sub .irk { background: transparent url("../img/sprite.png?20090430") left -1256px no-repeat; }
+.sub .preview-img { background-image: none; }
+
+/* =Recommended add-ons */
+.rec { background: url("../img/rec-tr.png") no-repeat right top; border-left-color: #c1e1c1; }
+.rec .preview-img { background: transparent url("../img/rec-tl.png") left top no-repeat; }
+.rec .flag { background: #f8f8f7 url("../img/rec-flag.png") no-repeat; }
+.rec .vex { background-image: url("../img/rec-br.png"); }
+.rec .vex span { background-image: url("../img/rec-bl.png"); }
+.rec .flag a { color: #360; text-decoration: none; }
+
+/* =Experimental add-ons */
+.exp { background: url("../img/exp-tr.png") no-repeat right top; border-left-color: #e3c1c1; }
+.exp .preview-img { background: transparent url("../img/exp-tl.png") left top no-repeat; }
+.exp .flag { background: #f8f8f7 url("../img/exp-flag.png") no-repeat; }
+.exp .flag a { color: #900; text-decoration: none; }
+.exp .vex { background-image: url("../img/exp-br.png"); }
+.exp .vex span { background-image: url("../img/exp-bl.png"); }
+
+/* =Listing items */
+#addon-listing .more li { border-right: 1px solid #666; }
+#addon-listing .more li:last-child { border: 0; }
+
+/*** =Install button ***/
+.install-button a { color: #062445; background: #7cc11c url("../img/sprite.png?20090430") 100% -730px no-repeat; }
+.install-button a span { background: transparent url("../img/installbtn-edges.png") left bottom no-repeat; }
+.install-button a span span { background: transparent url("../img/installbtn-edges.png") right bottom no-repeat; }
+.install-button a span span span { background: transparent url("../img/installbtn-edges.png") left top no-repeat; }
+.install-button a span span span strong { background: transparent url("../img/installbtn-edges.png") right top no-repeat; }
+
+.install-button a:hover, .install-button a:focus, .install-button a:active { color: #0a3b73; background-color: #9dd34c; background-position: 100% -860px; }
+
+/* In listings - general add-ons */
+.install-button a span,
+.install-button a span span,
+.install-button a span span span,
+.install-button a span span span strong { background-image: url("../img/installbtn-edges-list.png"); }
+
+/* In listings - experimental add-ons */
+.exp .install-button a span,
+.exp .install-button a span span,
+.exp .install-button a span span span,
+.exp .install-button a span span span strong { background-image: url("../img/installbtn-edges-exp.png"); }
+
+/* In listings - recommended add-ons */
+#addon-listing .rec .install-button a span,
+#addon-listing .rec .install-button a span,
+#addon-listing .rec .install-button a span span,
+#addon-listing .rec .install-button a span span,
+#addon-listing .rec .install-button a span span span,
+#addon-listing .rec .install-button a span span span,
+#addon-listing .rec .install-button a span span span strong { background-image: url("../img/installbtn-edges-rec.png"); }
+
+/* Experimental add-ons - while logged out */
+#content-main .exp-loggedout, #content .exp-loggedout,
+#content-main .exp-confirmed { border: 1px solid #d8d8d8; background: #fff; -moz-border-radius: 6px; -webkit-border-radius: 6px; border-radius: 6px; }
+#content-main .exp-loggedout .install-button a, #content .exp-loggedout .install-button a { color: #aaa; background-color: #fff; background-position: 100% -995px; }
+#content-main .exp-loggedout .install-button a span, #content .exp-loggedout .install-button a span,
+#content-main .exp-loggedout .install-button a span span, #content .exp-loggedout .install-button a span span,
+#content-main .exp-loggedout .install-button a span span span, #content .exp-loggedout .install-button a span span span,
+#content-main .exp-loggedout .install-button a span span span strong, #content .exp-loggedout .install-button a span span span strong { background-image: url("../img/installbtn-edges-dis.png"); }
+#content-main .exp-loggedout .install-button a:hover, #content .exp-loggedout .install-button a:hover { background-color: #f3f3f3; background-position: 100% -1125px; }
+
+/* Unavailable add-ons */
+#content-main .install-container .not-avail { padding: 5px 10px; float: left; color: #666; border: 1px solid #d8d8d8; background: #fff; -moz-border-radius: 6px; -webkit-border-radius: 6px; border-radius: 6px; }
+
+/*** =Pitch ***/
+.pitch { background-color: #f8f8f8; border: 1px solid #e4f3fa; -moz-border-radius: 6px; -webkit-border-radius: 6px; border-radius: 6px; }
+.pitch h3 { color: #042253; }
+
+/*** =Landing pages ***/
+#recommended { background: #f2f8fd; border: 1px solid #e9f1f8; -moz-border-radius: 6px; -webkit-border-radius: 6px; border-radius: 6px; }
+#recommended .addon { background: #fff url("../img/landrec-tr.png") no-repeat top right; }
+#recommended .addon .preview-img { background: url("../img/landrec-tl.png") no-repeat top left; }
+#recommended .addon .vex { background-image: url("../img/landrec-br.png"); }
+#recommended .vex span { background-image: url("../img/landrec-bl.png"); }
+
+#content.landing #secondaries .exp .irk { background-image: url("../img/exp-tl.png"); }
+#content.landing #secondaries .sub .vex { background-image: url("../img/addon-br.png"); }
+#content.landing #secondaries .exp .vex { background-image: url("../img/exp-br.png"); }
+#content.landing #secondaries .exp .preview-img { background-image: none; }
+
+#content.landing .more-addons { border: 1px solid #5d6c8c; -moz-border-radius: 6px; -webkit-border-radius: 6px; border-radius: 6px; }
+
+.browse-list a { background: #fafafa; border: 1px solid #e8e6e6; -moz-border-radius: 6px; -webkit-border-radius: 6px; border-radius: 6px; }
+.browse-list a:hover { background-color: #f1f0f0; border-color: #e1dfdf; }
+
+/*** =Dictionaries ***/
+#dictionaries { background-color: #f7fafc; border: 1px solid #eef1f3; -moz-border-radius: 6px; -webkit-border-radius: 6px; border-radius: 6px; }
+#dictionaries th, #dictionaries td { border-bottom: 1px solid #eee; }
+#dictionaries tbody tr.alt th, #dictionaries tbody tr.alt td { background-color: #fff; }
+
+/*** =Detail page ***/
+.addon-cats li { border-left: 1px solid #666; }
+.addon-cats li:first-child { border-left: 0; }
+#addon-info, #addon-advanced { border: 1px solid #d8dcdf; -moz-border-radius: 6px; -webkit-border-radius: 6px; border-radius: 6px; }
+.addon-images a img { border: 1px solid #1d587f; }
+.addon-reviews li, .addon-versions li { border-top: 1px solid #d8dcdf; }
+#addon-info .addon-reviews li { background-color: #f7fafc; border: 1px solid #eef1f3; -moz-border-radius: 6px; -webkit-border-radius: 6px; border-radius: 6px; }
+
+#addon-advanced h5 { border-top: 1px solid #d8dcdf; }
+
+/* =Version History Page */
+#latest-version { border: 1px solid #5d6c8c; -moz-border-radius: 6px; -webkit-border-radius: 6px; border-radius: 6px; }
+div.oldversion { -moz-border-radius: 6px; -webkit-border-radius: 6px; border-radius: 6px; }
+
+/* =Review form */
+#form-review { background-color: #f8f8f8; border: 1px solid #e4f3fa; -moz-border-radius: 6px; -webkit-border-radius: 6px; border-radius: 6px; }
+
+/* =reCaptchas */
+#recaptcha_image { border: 1px solid #d8dcdf; }
+
+/* =Star rating */
+#rate-it legend span { color: #042758; }
+/*
+ul.star-rating { background: #fff; padding: 3px 5px; border: 1px solid #edbe97; -moz-border-radius: 6px; -webkit-border-radius: 6px; border-radius: 6px; }
+*/
+
+/* =More add-ons */
+.more-addons h3 a.view { background: transparent url("../img/sprite.png?20090430") 100% -387px no-repeat; }
+.html-ltr .more-addons h3 a.view:hover { background-position: 100% -437px; }
+.html-rtl .more-addons h3 a.view { background-position: 100% -597px; }
+.html-rtl .more-addons h3 a.view:hover { background-position: 100% -647px; }
+
+/*** =Pagination ***/
+.pagination { background-color: #f7fafc; border: 1px solid #eef1f3; -moz-border-radius: 6px; -webkit-border-radius: 6px; border-radius: 6px; }
+.pages a { border: 1px solid #fff; }
+.pages a:hover { background-color: #ccf29b; border-color: #bbde92; }
+.pages .selected a { background-color: #ccf29b; border: 1px solid #83c53f; text-decoration: none; font-weight: bold; color: black; }
+.pages .prev a { background: transparent url("../img/arr-prev.png") 0 50% no-repeat; }
+.pages .prev a:hover { background-color: #ccf29b; }
+.pages .next a { background: transparent url("../img/arr-next.png") 100% 50% no-repeat; }
+.pages .next a:hover { background-color: #ccf29b; }
+
+/*** =Listing control bar ***/
+#form-listcontrol { background: #f2f8fd; border: 1px solid #e9eff4; -moz-border-radius: 6px; -webkit-border-radius: 6px; border-radius: 6px; }
+#order-by button { color: #7598b5; background-color: #fff; border: 1px solid #89a8c1; -moz-border-radius: 6px; -webkit-border-radius: 6px; border-radius: 6px; }
+#order-by button:hover { background-color: #e9eff4; color: #496377; }
+#order-by button.current, #order-by button.current:hover { background-color: #89a8c1; color: #fff; }
+#form-listcontrol #experimental label { background: #fff; border: 1px solid #933; color: #933; -moz-border-radius: 5px; -webkit-border-radius: 5px; border-radius: 5px; }
+
+/*** =Thumbnail browser layout */
+#thumb-subcategories ul { -moz-border-radius-bottomleft:6px; -moz-border-radius-bottomright:6px; border-color:#D8DCDF; border-style:solid; border-width:0pt 1px 1px; }
+#thumb-subcategories ul li { border-top:1px solid #E8E6E6; }
+
+#thumb-subcategories a:link { color: #4e4e4e; }
+#thumb-subcategories a:visited { color: #777; }
+#thumb-subcategories a:hover, #thumb-subcategories a:active, #thumb-subcategories a:focus { background: #F2F8Fd }
+#thumb-subcategories li.selected a:link, #thumb-subcategories li.selected a:visited { background-color:#89A8C1; color:#FFFFFF; }
+
+#thumb-browser .thumbs li.thumb { background: transparent url(../img/sprite.png?20090430) no-repeat scroll right -1256px; }
+#thumb-browser .thumbs li.thumb div.wrapper { background: transparent url(../img/sprite.png?20090430) no-repeat scroll left -1256px; }
+#thumb-browser .thumbs li.exp { background: transparent url(../img/exp-tr.png) no-repeat scroll right top; }
+#thumb-browser .thumbs li.exp div.wrapper { background: transparent url(../img/exp-tl.png) no-repeat scroll left top; }
+#thumb-browser .thumbs li.thumb .vex { background:transparent url(../img/sprite.png?20090430) no-repeat scroll right bottom; }
+#thumb-browser .thumbs li.thumb .vex span { background:transparent url(../img/sprite.png?20090430) no-repeat scroll left bottom; width: 10px; height: 10px; float: left;}
+#thumb-browser .thumbs li.exp .vex { background:transparent url(../img/exp-br.png) no-repeat scroll right bottom; }
+#thumb-browser .thumbs li.exp .vex span { background:transparent url(../img/exp-bl.png) no-repeat scroll left bottom; }
diff --git a/site/app/webroot/css/compatibility.css b/site/app/webroot/css/compatibility.css
new file mode 100644
index 0000000..8ee240d
--- /dev/null
+++ b/site/app/webroot/css/compatibility.css
@@ -0,0 +1,274 @@
+.compat-box {
+ border: 2px solid #666666;
+ -moz-border-radius: 15px;
+ -webkit-border-radius: 15px;
+ width: 650px;
+ margin: 20px auto;
+ padding: 20px;
+ height: 360px;
+ background: transparent url('../img/puzzle-corner.png') no-repeat bottom right;
+}
+
+.compat-box .header .title img {
+ vertical-align: middle;
+ margin-right: 10px;
+}
+
+.compat-box .header .title {
+ font-size: 1.1em;
+ color: #666666;
+ font-weight: bold;
+
+}
+
+.compat-box .loading {
+ font-size: 1.3em;
+ margin-top: 50px;
+ text-align: center;
+}
+.compat-box .footer {
+ display: none;
+ text-align: right;
+ font-style: italic;
+}
+
+#compat-intro h2 {
+ text-align: center;
+ font-size: 1.5em;
+}
+#compat-intro p {
+ width: 80%;
+ margin: 10px auto;
+}
+#compat-intro ul {
+ margin: 0;
+ padding: 0;
+}
+#compat-intro ul li {
+ list-style: none;
+ margin: 0;
+ padding: 0;
+}
+
+#compat-intro ul li a {
+ border: 1px solid #666666;
+ color: #666666;
+ padding: 5px 10px;
+ margin: 15px auto;
+ display: block;
+ text-decoration: none;
+ font-size: 1.3em;
+ -moz-border-radius: 6px;
+ -webkit-border-radius: 6px;
+ width: 25em;
+ background: #FFFFFF url('../img/slider-next-disabled.gif') no-repeat 98% 50%;
+}
+#compat-intro ul li a:hover {
+ background-image: url('../img/slider-next.gif');
+ color: #2D3B58;
+ border-color: #2D3B58;
+}
+
+#compat-home-nav {
+ display: none;
+ border: 1px solid #666666;
+ border-bottom: none;
+ float: right;
+ margin-right: 155px;
+ padding: 0 7px;
+ -moz-border-radius: 6px 6px 0 0;
+ -webkit-border-radius: 6px 6px 0 0;
+}
+#compat-home-nav a {
+ text-decoration: none;
+}
+
+
+#report-intro,
+#report-details,
+#report-details-data,
+#developers-intro,
+#developers-details,
+#developers-details-data,
+#users-intro {
+ display: none;
+}
+
+#report-details-data,
+#developers-details-data {
+ overflow-y: auto;
+ overflow-x: hidden;
+ height: 350px;
+}
+
+#report-intro .intro {
+ margin: 15px 10px;
+}
+
+.details-link {
+ text-align: center;
+ clear: both;
+ font-size: 1.2em;
+ font-weight: bold;
+ padding: 10px;
+}
+
+#report-intro .details-link a:link,
+#report-intro .details-link a:visited,
+#report-intro .details-link a:hover {
+ color: #666666;
+}
+
+/* Overall Compat Bar */
+#overall-compat-bar {
+ width: 600px;
+ height: 100px;
+ border: 2px solid #666666;
+ margin: 0 auto;
+ background-color: #FFFFFF;
+ overflow: hidden;
+}
+#overall-compat-bar div {
+ height: 100px;
+ float: left;
+ color: #FFFFFF;
+ text-align: center;
+ line-height: 8em;
+ font-weight: bold;
+}
+
+#overall-compat-legend {
+ height: 120px;
+}
+
+#overall-compat-legend .legend-box {
+ border: 2px solid #CCCCCC;
+ background-color: #EEEEEE;
+ -moz-border-radius: 6px;
+ -webkit-border-radius: 6px;
+ float: left;
+ width: 150px;
+ min-height: 100px;
+ margin: 10px 4px;
+}
+
+#overall-compat-legend .color-square {
+ width: 15px;
+ height: 100px;
+ -moz-border-radius-bottomleft: 3px;
+ -moz-border-radius-topleft: 3px;
+ -webkit-border-top-left-radius: 3px;
+ -webkit-border-bottom-left-radius: 3px;
+ float: left;
+}
+
+#overall-compat-legend p {
+ margin: 0 2px 2px 18px;
+}
+
+
+/* Add-on Details Report */
+#compat-report {
+ width: 100%;
+}
+#compat-report td {
+ height: 20px;
+ vertical-align: middle;
+}
+#compat-report .maxversion {
+ color: #FFFFFF;
+ display: block;
+ width: 6em;
+ text-align: center;
+ -moz-border-radius: 6px;
+ -webkit-border-radius: 6px;
+ margin: 0 0 0 auto;
+}
+
+#compat-report td.bar {
+ width: 400px;
+ max-width: 400px;
+}
+#compat-report div.bar {
+ border: 1px solid #666666;
+ background-color: #FFFFFF;
+ height: 20px;
+ overflow: hidden;
+}
+#compat-report div.used-bar {
+ background-color: #DDDDDD;
+ height: 20px;
+ float: left;
+}
+#compat-report div.new-bar {
+ height: 20px;
+ float: left;
+}
+
+.compat-latest {
+ background-color: #339900;
+}
+.compat-beta {
+ background-color: #99CC99;
+}
+.compat-alpha {
+ background-color: #FFCC66;
+}
+.compat-other {
+ background-color: #999999;
+}
+
+/* Developer Info */
+.developer-addons {
+ padding: 0;
+ margin: 0;
+}
+.developer-addons li {
+ margin: 10px 0;
+ padding: 0;
+ list-style: none;
+ font-size: 15px;
+}
+.developer-addons li div.addon-details {
+ border: 2px solid #666666;
+ -moz-border-radius: 6px;
+ -moz-border-radius-topleft: 0;
+ -webkit-border-radius: 6px;
+ -webkit-border-top-left-radius: 0;
+ margin-left: 93px;
+ padding: 0 5px;
+ background-color: #FFFFFF;
+}
+.developer-addons li div.appversion {
+ color: white;
+ text-align: center;
+ float: left;
+ width: 85px;
+ padding: 3px;
+ border: 2px solid #666666;
+ -moz-border-radius-topleft: 6px;
+ -moz-border-radius-bottomleft: 6px;
+ -webkit-border-top-left-radius: 6px;
+ -webkit-border-bottom-left-radius: 6px;
+}
+.developer-addons li .name {
+ display: block;
+}
+.developer-addons li .details {
+ font-size: 13px;
+}
+
+.rightalign {
+ float: right;
+ margin: 0 0 10px 10px;
+}
+
+.login {
+ font-size: 1.1em;
+ font-style: italic;
+ margin-top: 10px;
+}
+
+ul.tips {
+ font-size: 1.2em;
+} \ No newline at end of file
diff --git a/site/app/webroot/css/developers.css b/site/app/webroot/css/developers.css
new file mode 100644
index 0000000..6bd440a
--- /dev/null
+++ b/site/app/webroot/css/developers.css
@@ -0,0 +1,1179 @@
+.html-rtl th,
+.html-rtl td {
+ text-align: right;
+}
+
+.graybox {
+ background-color: #F7FAFC;
+ border: 1px solid #EEF1F3;
+ padding: 15px;
+}
+.graybox.errors {
+ background-color: #FFA5A5;
+}
+
+.rounded {
+ -moz-border-radius: 6px;
+ -webkit-border-radius: 6px;
+ border-radius: 6px;
+}
+
+.action-button-container {
+ margin: 5px 0;
+}
+.action-button-container.centered,
+.add-button-container.centered {
+ text-align: center;
+}
+.action-button {
+ border: 1px solid #5D6C8C;
+ padding: 5px 10px;
+ background: #FFFFFF url('../img/arr-view-big.png') no-repeat scroll 98% 3px;
+ padding-right: 30px;
+ font-size: 110%;
+ color: #5D6C8C;
+}
+.html-rtl .action-button {
+ background-image: url('../img/arr-view-rtl-big.png');
+ background-position: 2% 3px;
+ padding-right: auto;
+ padding-left: 30px;
+}
+a.action-button {
+ text-decoration: none;
+}
+a.action-button:hover {
+ background-position: 98% -295px;
+ color: #2D3B58;
+}
+.html-rtl a.action-button:hover {
+ background-position: 2% -295px;
+}
+.action-button.disabled {
+ background: #EEEEEE url('../img/developers/privileges.png') no-repeat 96% 50%;
+ border-color: gray;
+ color: gray;
+ cursor: default;
+}
+.html-rtl .action-button.disabled {
+ background-position: 4% 50%;
+}
+a.action-button.disabled:hover {
+ color: gray;
+ background-position: 96% 50%;
+}
+.html-rtl a.action-button.disabled:hover {
+ background-position: 4% 50%;
+}
+
+.index-actions {
+ margin: 15px 0 0 30px;
+ padding: 0;
+ list-style: none;
+}
+.html-rtl .index-actions {
+ margin: 15px 30px 0 0;
+}
+.index-actions li {
+ padding-left: 20px;
+ font-weight: bold;
+}
+.html-rtl .index-actions li {
+ padding-left: auto;
+ padding-right: 20px;
+}
+.action-details {
+ margin-left: 10px;
+ font-weight: normal;
+}
+.html-rtl .action-details {
+ margin-left: auto;
+ margin-right: 10px;
+}
+
+.add-button-container {
+ margin-top: 10px;
+}
+.add-button,
+.remove-button,
+.edit-button {
+ background: #FFFFFF url('../img/developers/add.png') no-repeat 5px 50%;
+ padding: 3px 5px 3px 25px;
+ border: 1px solid #5D6C8C;
+ white-space: nowrap;
+}
+.html-rtl .add-button,
+.html-rtl .remove-button,
+.html-rtl .edit-button {
+ background-position: 100% 50%;
+ padding: 3px 20px 3px 5px;
+}
+.button {
+ background-color: #FFFFFF;
+ border: 1px solid #5D6C8C;
+ padding: 3px 5px;
+}
+a.add-button,
+a.remove-button,
+a.edit-button,
+a.button {
+ text-decoration: none;
+ color: #1D587F;
+}
+.add-button.bigger {
+ padding: 5px 10px 5px 30px;
+ font-size: 105%;
+ border: 1px solid #5D6C8C;
+}
+.html-rtl .add-button.bigger {
+ padding: 5px 25px 5px 10px;
+}
+.edit-button {
+ background-image: url('../img/developers/pencil.png');
+ border: 1px solid #FFCC66;
+}
+.remove-button {
+ background-image: url('../img/developers/delete.png');
+ border: 1px solid #FFA5A5;
+}
+a.remove-button:hover {
+ color: #CC3333;
+}
+a.add-button:hover,
+a.edit-button:hover,
+a.button:hover {
+ border-color: #1D587F;
+ color: #1D587F;
+ text-decoration: underline;
+}
+
+#dev-agreement {
+ background-color: #EEEEEE;
+ margin: 0 5% 10px;
+ padding: 10px;
+ max-height: 300px;
+ overflow: auto;
+ border: 1px solid #AAA;
+ font-size: 85%;
+}
+#license-disclosure {
+ font-size: 95%;
+}
+
+#step-agreement,
+#upload-success,
+#upload-loading,
+#upload-error {
+ display: none;
+}
+
+#upload-error {
+ margin-top: 10px;
+}
+#upload-error-content,
+#addon-created-content,
+#version-created-content,
+#file-created-content {
+ padding: 5px 10px;
+}
+
+#file-upload .disabled {
+ color: gray;
+}
+
+#file-upload .submit {
+ margin: 5px;
+ padding: 10px;
+ text-align: center;
+ width: 322px;
+}
+#file-upload .submit input {
+ font-weight: bold;
+}
+
+.greenbox-tr {
+ background: transparent url('../img/rec-tr.png') top right no-repeat;
+}
+.greenbox-tl {
+ background: transparent url('../img/rec-tl.png') top left no-repeat;
+}
+.greenbox-bl {
+ background: transparent url('../img/rec-bl.png') bottom left no-repeat;
+ height: 10px;
+}
+.greenbox-br {
+ background: transparent url('../img/rec-br.png') bottom right no-repeat;
+ height: 10px;
+}
+
+.bluebox-tr {
+ background: transparent url('../img/addon-tr.png') top right no-repeat;
+}
+.bluebox-tl {
+ background: transparent url('../img/addon-tl.png') top left no-repeat;
+}
+.bluebox-bl {
+ background: transparent url('../img/addon-bl.png') bottom left no-repeat;
+ height: 10px;
+}
+.bluebox-br {
+ background: transparent url('../img/addon-br.png') bottom right no-repeat;
+ height: 10px;
+}
+
+.redbox-tr {
+ background: transparent url('../img/exp-tr.png') top right no-repeat;
+}
+.redbox-tl {
+ background: transparent url('../img/exp-tl.png') top left no-repeat;
+}
+.redbox-bl {
+ background: transparent url('../img/exp-bl.png') bottom left no-repeat;
+ height: 10px;
+}
+.redbox-br {
+ background: transparent url('../img/exp-br.png') bottom right no-repeat;
+ height: 10px;
+}
+
+button, input[type="submit"] {
+ cursor: default;
+}
+
+p {
+ padding-top: 10px;
+}
+
+
+/* edit */
+#edit-listing dt {
+ padding-left: 25px;
+ min-height: 20px;
+}
+.html-rtl #edit-listing dt {
+ padding-left: auto;
+ padding-right: 25px;
+}
+#edit-listing dd {
+ padding-left: 20px;
+ padding-bottom: 10px;
+}
+.html-rtl #edit-listing dd {
+ padding-left: auto;
+ padding-right: 20px;
+}
+.pitch ul {
+ margin: 0;
+ list-style: none;
+}
+.pitch .actionbar li {
+ padding-left: 23px;
+ margin-top: 5px;
+}
+.html-rtl .pitch .actionbar li {
+ padding-left: auto;
+ padding-right: 23px;
+}
+.pitch .actionbar li.container {
+ padding-left: 0;
+ margin-top: 0;
+}
+.html-rtl .pitch .actionbar li.container {
+ padding-right: 0;
+}
+.pitch .actionbar ul li {
+ margin-left: 15px;
+}
+.html-rtl .pitch .actionbar ul li {
+ margin-left: auto;
+ margin-right: 15px;
+}
+.pitch .actionbar li.selected {
+ font-weight: bold;
+}
+.pitch hr {
+ border: none;
+ border-bottom: 1px solid #EEEEEE;
+}
+.pitch h4 {
+ border-bottom: 1px solid #EEEEEE;
+}
+.pitch h4 a {
+ text-decoration: none;
+ color: #2D3B58;
+}
+
+.actionbar.inactive li.active-only {
+ display: none;
+}
+
+.actionbar .displaypage {
+ background: transparent url('../img/developers/actionbar/displaypage.png') no-repeat 0% 50%;
+}
+.actionbar .details {
+ background: transparent url('../img/developers/actionbar/details.png') no-repeat 0% 50%;
+}
+.actionbar .edit {
+ background: transparent url('../img/developers/actionbar/edit.png') no-repeat 0% 50%;
+}
+.actionbar .edit-properties {
+ background: transparent url('../img/developers/actionbar/edit_properties.png') no-repeat 0% 50%;
+}
+.actionbar .edit-descriptions {
+ background: transparent url('../img/developers/actionbar/edit_descriptions.png') no-repeat 0% 50%;
+}
+.actionbar .edit-categories {
+ background: transparent url('../img/developers/actionbar/edit_categories.png') no-repeat 0% 50%;
+}
+.actionbar .edit-authors {
+ background: transparent url('../img/developers/actionbar/edit_authors.png') no-repeat 0% 50%;
+}
+.actionbar .status {
+ background: transparent url('../img/developers/actionbar/status.png') no-repeat 0% 50%;
+}
+.actionbar .statistics {
+ background: transparent url('../img/developers/actionbar/stats.png') no-repeat 0% 50%;
+}
+.actionbar .versions {
+ background: transparent url('../img/developers/actionbar/versions.png') no-repeat 0% 50%;
+}
+.actionbar .versions-add {
+ background: transparent url('../img/developers/actionbar/versions_add.png') no-repeat 0% 50%;
+}
+.actionbar .previews {
+ background: transparent url('../img/developers/actionbar/previews.png') no-repeat 0% 50%;
+}
+.html-rtl .actionbar .displaypage,
+.html-rtl .actionbar .details,
+.html-rtl .actionbar .edit,
+.html-rtl .actionbar .edit-properties,
+.html-rtl .actionbar .edit-descriptions,
+.html-rtl .actionbar .edit-categories,
+.html-rtl .actionbar .edit-authors,
+.html-rtl .actionbar .status,
+.html-rtl .actionbar .statistics,
+.html-rtl .actionbar .versions,
+.html-rtl .actionbar .versions-add,
+.html-rtl .actionbar .previews {
+ background-position: 100% 50%;
+}
+
+.edit-categories-descriptions {
+ border-left: 1px solid #CCCCCC;
+}
+.html-rtl .edit-categories-descriptions {
+ border-left-width: 0;
+ border-right: 1px solid #CCCCCC;
+}
+
+#add-author-button .add-button {
+ background-image: url('../img/developers/edit_authors_add.png');
+}
+
+#add-author ul {
+ list-style: none;
+}
+#add-author p {
+ padding-top: 0;
+}
+#author-table {
+ width: 100%;
+}
+#author-table th {
+ font-weight: bold;
+}
+
+.save-changes {
+ display: none;
+ background: transparent url('../img/developers/exclamation.png') no-repeat 5px 50%;
+ padding: 5px 0 5px 30px;
+ border: 1px solid #5D6C8C;
+ margin: 5px;
+}
+.html-rtl .save-changes {
+ background-position: 100% 50%;
+ padding: 5px 25px 5px 0;
+}
+#add-author p {
+ margin-bottom: 5px;
+}
+#add-author #add-error {
+ background: transparent url('../img/developers/exclamation.png') no-repeat 5px 50%;
+ color: #CC3333;
+ padding: 5px 0 5px 30px;
+ display: none;
+}
+.html-rtl #add-author #add-error {
+ background-position: 100% 50%;
+ padding: 5px 25px 5px 0;
+}
+#add-author #add-loading {
+ display: none;
+}
+
+.edit-categories-box h4 img {
+ vertical-align: middle;
+ margin-right: 10px;
+}
+.html-rtl .edit-categories-box h4 img {
+ margin-right: auto;
+ margin-left: 10px;
+}
+
+#edit-properties-icon-table th {
+ color: #2D3B58;
+ font-size: 110%;
+}
+#edit-properties-icon-table td {
+ vertical-align: top;
+}
+#edit-properties-icon-table #addon-icon.deleted {
+ opacity: .25;
+ filter: alpha(opacity=25);
+}
+
+#edit-versions-targetapps-table {
+ width: 60%;
+ margin: 0 auto;
+}
+#edit-versions-targetapps-table .appname {
+ font-weight: bold;
+ color: #2D3B58;
+}
+
+#edit-versions-targetapps-table .inline-delete-button img {
+ padding-top: 4px;
+}
+#new-app-picker {
+ padding-left: 20px;
+ display: none;
+}
+.html-rtl #new-app-picker {
+ padding-left: auto;
+ padding-right: 20px;
+}
+
+table .inline-delete-button img {
+ padding-bottom: 4px;
+}
+
+a.filelink {
+ background: transparent url('../img/developers/versions_link.png') no-repeat left;
+ padding-left: 20px;
+}
+.html-rtl a.filelink {
+ background-position: right;
+ padding-left: auto;
+ padding-right: 20px;
+}
+
+#files-table .inline-delete-box .remove-button {
+ background-image: url('../img/developers/versions_delete.png');
+}
+#edit-versions-targetapps-table .inline-delete-box .remove-button {
+ background-image: url('../img/developers/versions_compat_remove.png');
+}
+#author-table .inline-delete-box .remove-button {
+ background-image: url('../img/developers/edit_authors_delete.png');
+}
+
+/* Previews */
+.replace-preview {
+ margin: 10px 0;
+ padding: 10px 5px;
+ background-color: #FFFFFF;
+ border-top: 1px solid #EEEEEE;
+ border-bottom: 1px solid #EEEEEE;
+}
+.replace-preview input {
+ margin-left: 20px;
+}
+.html-rtl .replace-preview input {
+ margin-left: auto;
+ margin-right: 20px;
+}
+#content-main .replace-preview p {
+ margin-bottom: 0;
+}
+#add-preview-box .add-button {
+ background-image: url('../img/developers/preview_add.png');
+}
+.preview-buttons {
+ text-align: right;
+}
+.html-rtl .preview-buttons {
+ text-align: left;
+}
+.preview-add-button-description {
+ text-align: right;
+}
+.html-rtl .preview-add-button-description {
+ text-align: left;
+}
+
+/* Change Status Page */
+div.status {
+ font-size: 115%;
+}
+h4.status span {
+ font-weight: bold;
+}
+.status-0 {
+ color: gray;
+}
+.status-1,
+.status-2,
+.status-3 {
+ color: navy;
+}
+.status-4 {
+ color: green;
+}
+.status-5 {
+ color: red;
+}
+
+.inactive-0 {
+ color: green;
+}
+.inactive-1 {
+ color: red;
+}
+
+.actions {
+ width: 100%;
+}
+.actions .action {
+ text-align: left;
+ vertical-align: middle;
+ min-width: 25%;
+ padding-bottom: 5px;
+}
+.html-rtl .actions .action {
+ text-align: right;
+}
+.actions .description {
+ color: #5D6C8C;
+}
+
+.nominate.add-button {
+ background-image: url('../img/developers/status_nominate.png');
+}
+.complete.add-button {
+ background-image: url('../img/developers/tick.png');
+}
+.make-active.add-button {
+ background-image: url('../img/developers/status_active.png');
+}
+.make-inactive.add-button {
+ background-image: url('../img/developers/status_inactive.png');
+}
+
+.to-sandbox.add-button {
+ background-image: url('../img/developers/arrow_down.png');
+}
+.to-public.add-button {
+ background-image: url('../img/developers/arrow_up.png');
+}
+
+.criteria {
+ margin-left: 10px;
+}
+.html-rtl .criteria {
+ margin-left: auto;
+ margin-right: 10px;
+}
+.criteria li {
+ list-style: none;
+ padding-left: 20px;
+}
+.html-rtl .criteria li {
+ padding-left: auto;
+ padding-right: 20px;
+}
+.criteria .pass {
+ background: url('../img/developers/tick.png') no-repeat left center;
+}
+.criteria .fail {
+ background: url('../img/developers/cross.png') no-repeat left center;
+}
+.criteria .meh {
+ background: url('../img/developers/asterisk_yellow.png') no-repeat left center;
+}
+.html-rtl .criteria .pass,
+.html-rtl .criteria .fail,
+.html-rtl .criteria .meh {
+ background-position: right center;
+}
+
+.pretty-table {
+ width: 100%;
+}
+.pretty-table th {
+ color: #555555;
+}
+.pretty-table td img,
+.pretty-table td {
+ vertical-align: middle;
+}
+.pretty-table td,
+.pretty-table th {
+ padding: 5px;
+}
+.pretty-table .alt td {
+ background-color: #FFFFFF;
+ border-top: 1px solid #EEEEEE;
+ border-bottom: 1px solid #EEEEEE;
+}
+
+.inline-delete-button {
+ border: 1px solid transparent;
+ border-bottom: none;
+}
+.inline-delete-button.uses-image.open {
+ background-color: #FFA5A5;
+ text-align: center;
+ border: 1px solid #CC3333;
+ border-bottom: none;
+ -moz-border-radius: 6px 6px 0 0;
+ -webkit-border-top-left-radius: 6px;
+ -webkit-border-top-right-radius: 6px;
+ border-radius: 6px 6px 0 0;
+}
+.inline-delete-button.uses-button.open .remove-button.trigger {
+ background-color: #FFA5A5;
+ border: 1px solid #CC3333;
+ -moz-border-radius: 6px 6px 0 0;
+ -webkit-border-bottom-left-radius: 0;
+ -webkit-border-bottom-right-radius: 0;
+ border-radius: 6px 6px 0 0;
+}
+.inline-delete-box {
+ position: absolute;
+ z-index: 10;
+ display: none;
+ margin-left: -378px;
+ padding: 10px;
+ width: 380px;
+ color: #2D3B58;
+ background-color: #FFA5A5;
+ border: 1px solid #CC3333;
+ -moz-border-radius: 6px 0 6px 6px;
+ -webkit-border-radius: 6px;
+ -webkit-border-top-right-radius: 0;
+ border-radius: 6px 0 6px 6px;
+}
+.html-rtl .inline-delete-box {
+ margin-left: auto;
+ margin-right: -378px;
+ -moz-border-radius: 0 6px 6px 6px;
+ -webkit-border-radius: 6px;
+ -webkit-border-top-left-radius: 0;
+ border-radius: 0 6px 6px 6px;
+}
+.uses-button .inline-delete-box {
+ right: 0;
+ margin: 2px 22px 0 0;
+ width: 50%;
+}
+.html-rtl .uses-button .inline-delete-box {
+ right: auto;
+ left: 0;
+ margin: 2px 0 0 22px;
+}
+.inline-delete-box p {
+ margin: 0 !important;
+ padding: 0;
+ text-align: center;
+}
+.inline-delete-box .remove-button {
+ border-color: #CC3333;
+ color: #2D3B58;
+}
+.inline-delete-box .button {
+ color: #2D3B58;
+}
+
+.graybox.spaced {
+ margin-bottom: 10px;
+}
+.field h4 {
+ border-bottom: 1px solid #2D3B58;
+}
+.field h5 {
+ font-weight: bold;
+ margin-top: 1em;
+ font-size: 110%;
+}
+.field label {
+ display: block;
+ margin-bottom: 3px;
+}
+.field ul {
+ list-style-type: disc;
+ margin-top: 10px;
+}
+.field textarea {
+ border: 1px solid #1D587F;
+}
+#content-main p.smallmargin {
+ margin: .5em 0;
+ padding: 0;
+}
+p.indented,
+label.indented {
+ text-indent: 2em;
+}
+
+.preview-box .error-message {
+ display: none;
+ background-image: url('../img/developers/preview_delete.png');
+}
+.preview-box.errors .error-message {
+ display: block;
+}
+
+.notice-success {
+ border: 1px solid green;
+ background: lightgreen url('../img/stats/tick.png') no-repeat 5px 50%;
+ margin-bottom: 5px;
+ padding: 5px 5px 5px 30px;
+}
+.html-rtl .notice-success {
+ background-position: 100% 50%;
+ padding: 5px 25px 5px 5px;
+}
+.notice-success span {
+ font-weight: bold;
+}
+
+.notice-error {
+ border: 1px solid red;
+ background: #FFA5A5 url('../img/developers/exclamation.png') no-repeat 5px 50%;
+ margin-bottom: 5px;
+ padding: 5px 5px 5px 30px;
+}
+.html-rtl .notice-error {
+ background-position: 100% 50%;
+ padding: 5px 25px 5px 5px;
+}
+.notice-error span {
+ font-weight: bold;
+}
+
+#content-main .notice-success ul,
+#content-main .notice-error ul,
+#content-main .notice-success li,
+#content-main .notice-error li {
+ margin-bottom: 0;
+}
+
+.notice {
+ background-color: #FFFF99;
+ border: 1px solid gray;
+ padding: 5px;
+ margin-bottom: 5px;
+}
+.notice span {
+ font-weight: bold;
+}
+
+.notice.noscript {
+ padding-left: 30px;
+ background: #FFFF99 url('../img/developers/noscript.png') no-repeat 5px 50%;
+}
+.html-rtl .notice.noscript {
+ padding-left: auto;
+ padding-right: 30px;
+ background-position: 100% 50%;
+}
+
+.notice.no-privs-box {
+ padding-left: 30px;
+ background: #FFFF99 url('../img/developers/privileges.png') no-repeat 5px 50%;
+ display: none;
+}
+.html-rtl .notice.no-privs-box {
+ padding-left: auto;
+ padding-right: 30px;
+ background-position: 100% 50%;
+}
+
+#content-main.no-privs .no-privs-box {
+ display: block;
+}
+#content-main.no-privs .inline-delete-button,
+#content-main.no-privs .add-button,
+#content-main.no-privs .action-button,
+#content-main.no-privs .delete-area,
+#content-main.no-privs .translation-button,
+#content-main.no-privs .require-privs,
+#content-main.no-privs .edit-button,
+#content-main.no-privs .remove-button {
+ display: none;
+}
+.version-delete-area {
+ text-align: right;
+}
+.html-rtl .version-delete-area {
+ text-align: left;
+}
+
+#content-main.no-privs input,
+#content-main.no-privs select,
+#content-main.no-privs textarea {
+ background-color: #EEEEEE;
+}
+
+/* Developers Global */
+div.error {
+ background: #ffa5a5;
+ border: 1px solid red;
+ text-align: center;
+ font-weight: bold;
+ padding: 5px;
+ margin: 5px 0 5px 0;
+}
+div.error_message {
+ color: red;
+ font-weight: bold;
+}
+.form_error {
+ background: #ffa5a5;
+ border: 1px solid red;
+}
+
+/* developers/index */
+/* 3.2 new */
+.sub div { background: none; }
+.sub div.addon-container { background: transparent url("../img/addon-tl.png") left top no-repeat; }
+.sub div { margin: 0; padding: 0; }
+.sub div.addon-container { margin-left: -1px; padding: 14px 20px 8px; }
+.sub .vex { left: 0; }
+.html-rtl .sub .vex { left: 0; }
+
+#summary h4 img {
+ float: left;
+ padding-right: 10px;
+}
+.html-rtl #summary h4 img {
+ float: right;
+ padding-right: auto;
+ padding-left: 10px;
+}
+#summary p {
+ padding: 5px;
+ clear: left;
+}
+.html-rtl #summary p {
+ clear: right;
+}
+
+/*** =Extra content ***/
+.action-bar {
+ float: right;
+ width: 180px;
+ margin-bottom: 1em;
+ border: 1px solid #d8dcdf;
+ -moz-border-radius: 6px;
+ -webkit-border-radius: 6px;
+ border-radius: 6px;
+}
+.html-rtl .action-bar {
+ float: left;
+}
+.action-bar ul {
+ margin: 10px !important;
+ list-style: none;
+}
+.action-bar ul li {
+ padding-left: 20px;
+}
+.html-rtl .action-bar ul li {
+ padding-left: auto;
+ padding-right: 20px;
+}
+
+.addon-details h3 img {
+ vertical-align: middle;
+}
+
+#contentWindow {
+ width: 100%;
+ height: 500px;
+ overflow: auto;
+ border: none;
+}
+div.disabled {
+ color: gray !important;
+}
+.addonHeader {
+ cursor: pointer;
+ font-size: 16px;
+}
+div.summaryBar {
+ border: 1px solid #eee;
+ white-space: nowrap;
+}
+.summaryBar img {
+ vertical-align: middle;
+ border: 0px;
+ margin-left: 10px;
+}
+.html-rtl .summaryBar img {
+ margin-left: auto;
+ margin-right: 10px;
+}
+.summaryBar div {
+ /* IE hack */
+ zoom: 1;
+ display: inline;
+}
+.summaryBar div {
+ display: table-cell;
+ vertical-align: middle;
+ padding: 5px;
+ line-height: 2;
+ font-size: 12px;
+}
+.summaryBar .downloadcount {
+ line-height: 1;
+ font-size: 12px;
+ max-height: 35px;
+}
+.summaryBar .downloadcount span {
+ font-size: 10px;
+}
+.summaryBar a:link,
+.summaryBar a:visited,
+.summaryBar a:active {
+ text-decoration: none;
+}
+
+/* developers/add */
+div.notice {
+ background-color: #FFFF99;
+ padding: 5px;
+}
+div.greenNotice {
+ background-color: #CCFFCC;
+ padding: 5px;
+}
+#developersForm {
+ padding-left: 15px;
+}
+.html-rtl #developersForm {
+ padding-left: auto;
+ padding-right: 15px;
+}
+#submissionHelp {
+ text-align: center;
+}
+.corner-box h1,
+.corner-box h2,
+.corner-box h3,
+.corner-box h4,
+.corner-box h5 {
+ color: #3c475b;
+}
+#developersForm div {
+ margin-top: 15px;
+}
+#developersForm label {
+ border-bottom: 1px dashed #eee;
+ float: left;
+ width: 14em;
+}
+.html-rtl #developersForm label {
+ float: right;
+}
+#developersForm ul.rightlist li {
+ list-style: none;
+ padding-left: 11em;
+}
+.html-rtl #developersForm ul.rightlist li {
+ padding-left: auto;
+ padding-right: 11em;
+}
+#developersForm ul.rightlist li:first-child {
+ padding-left: 0;
+}
+.html-rtl #developersForm ul.rightlist li:first-child {
+ padding-left: auto;
+ padding-right: 0;
+}
+#developersForm div div.platforms label {
+ float: left;
+ border: none;
+ font-style: italic;
+ width: 14em;
+ text-align: right;
+}
+.html-rtl #developersForm div div.platforms label {
+ float: right;
+ text-align: left;
+}
+#developersForm label.nofloat {
+ float: none;
+ margin-left: 10px;
+ border: none;
+}
+.html-rtl #developersForm label.nofloat {
+ margin-left: auto;
+ margin-right: 10px;
+}
+#developersForm label.normal {
+ float: none;
+ border: none;
+}
+#developersForm div.description {
+ font-style: italic;
+ margin-left: 14em;
+}
+.html-rtl #developersForm div.description {
+ margin-left: auto;
+ margin-right: 14em;
+}
+#developersForm .spaced {
+ margin-left: 14em;
+}
+.html-rtl #developersForm .spaced {
+ margin-left: auto;
+ margin-right: 14em;
+}
+#developersForm input.vmiddle {
+ vertical-align: middle;
+}
+#developersForm input,
+#developersForm select,
+#developersForm textarea {
+ margin-left: 5px;
+}
+.html-rtl #developersForm input,
+.html-rtl #developersForm select,
+.html-rtl #developersForm textarea {
+ margin-left: left;
+ margin-right: 5px;
+}
+#developersForm select {
+ border: 1px solid #eee;
+}
+#developersForm h3 {
+ font-weight: bold;
+}
+div.addonName {
+ padding-left: 20px;
+ font-size: 14px;
+ font-style: italic;
+}
+div.addonName {
+ padding-left: auto;
+ padding-right: 20px;
+}
+.buttonBox input {
+ margin: 10px;
+}
+.buttonBox input:hover {
+}
+.buttonBox input[type=button] {
+ cursor: pointer;
+}
+.buttonBox .cancel:hover {
+}
+#tagDescription {
+ vertical-align: top;
+ padding-left: 20px;
+}
+.html-rtl #tagDescription {
+ padding-left: auto;
+ padding-right: 20px;
+}
+#afterDescription {
+ clear: both;
+ padding-top: 15px;
+}
+#developersForm div.breaklessDivider {
+ height: 15px;
+ background: #fff url(../img/divider.gif) no-repeat scroll center;
+ border: 0;
+ margin-top: 15px;
+}
+#developerAgreement blockquote {
+ margin: 10px 25px;
+}
+#agreementButtons {
+ text-align: center;
+}
+#agreementButtons input {
+ padding: 2px;
+}
+#AddonAddontypeId {
+ width: 10em;
+}
+/* localebox element */
+#locale-box {
+ background: url(../img/developers/locale-background-selected.png) repeat-x;
+ height: 1.5em;
+ width: 100%;
+ margin: 0;
+ padding-bottom: .5em;
+ line-height: normal;
+ height: 65px;
+}
+#locale-box span {
+ background: url(../img/developers/locale-background-selected.png) repeat-x;
+ float: left;
+ text-align: center;
+ font-weight: bold;
+ cursor: pointer;
+ width: 4em;
+ padding: .4em;
+ border-right: 1px solid #eee;
+}
+#locale-box span {
+ float: right;
+ border-right-width: 0;
+ border-left: 1px solid #eee;
+}
+#locale-box span:hover,
+#locale-box span.selected {
+ background: url(../img/developers/locale-background-hover.png) repeat-x;
+}
+
+/* developers/editversion */
+#targetApps select {
+ width: 100%;
+}
+#fileList,
+#targetApps {
+ margin: 0 0;
+}
+#targetApps td.separator,
+#fileList td.separator {
+ padding: 0 15px;
+}
+#license-translationbox {
+ margin-top: 1em;
+}
+
+/* developers/tshirtrequest */
+#tshirtRequestForm {
+ padding-left: 15px;
+}
+.html-rtl #tshirtRequestForm {
+ padding-left: auto;
+ padding-right: 15px;
+}
+
+#tshirtRequestForm div {
+ margin-top: 15px;
+}
+
+#requestTShirtButton {
+ margin-left: 14em;
+}
+.html-rtl #requestTShirtButton {
+ margin-left: auto;
+ margin-right: 14em;
+}
+
diff --git a/site/app/webroot/css/diff.css b/site/app/webroot/css/diff.css
new file mode 100644
index 0000000..fe6d629
--- /dev/null
+++ b/site/app/webroot/css/diff.css
@@ -0,0 +1,2 @@
+span.diff-remove { background-color: #FFFFAA; }
+span.diff-add { background-color: #CCFFCC; }
diff --git a/site/app/webroot/css/editors.css b/site/app/webroot/css/editors.css
new file mode 100644
index 0000000..0c25025
--- /dev/null
+++ b/site/app/webroot/css/editors.css
@@ -0,0 +1,477 @@
+/* Editors Global */
+div.error {
+ background: #ffa5a5;
+ border: 1px solid red;
+ text-align: center;
+ font-weight: bold;
+ padding: 5px;
+ margin: 5px 0 5px 0;
+}
+div.error_message {
+ color: red;
+ font-weight: bold;
+}
+.form_error {
+ background: #ffa5a5;
+ border: 1px solid red;
+}
+/* editors/queue */
+#tabTable {
+ width: 100%;
+ margin-top: 17px;
+}
+#tabTable #spacer { width: 25%;
+ border-bottom: 1px solid black;
+}
+#tabTable #pending,
+#tabTable #nominated,
+#tabTable #reviews {
+ border-bottom: 1px solid black;
+ text-align: right;
+ vertical-align: bottom;
+}
+#tabTable .tab {
+ padding: 5px;
+ cursor: pointer;
+ font-weight: bold;
+}
+#tabTable .selected {
+ background-color: #eeeeee;
+}
+.queueHeader td{
+ font-weight: bold;
+ border-bottom: 1px solid #888;
+}
+#reviewSuccess {
+ background: #b8f3c4;
+ border: 1px solid green;
+ text-align: center;
+ font-weight: bold;
+ padding: 5px;
+ margin: 5px 0 5px 0;
+}
+
+#filterBox {
+ border: 1px solid #eeeeee;
+ background: #ffffee;
+ text-align: center;
+}
+#filterHeader {
+ font-weight: bold;
+ border-bottom: 1px dashed #eeeeee;
+ cursor: pointer;
+}
+#filterTable {
+ width: 100%;
+ margin: 0 auto;
+ padding-bottom: 10px;
+}
+#filterTable div.group {
+ display: -moz-inline-box;
+ display: inline-block;
+ margin: 10px;
+}
+#filterTable div.left {
+ text-align: left;
+}
+#filterTable div.left div {
+ margin: 5px 0;
+}
+#filterTable div.left label {
+ float: left;
+ width: 150px;
+}
+#filterTable div.buttons {
+ clear: both;
+}
+input#FilterAddonOrAuthor {
+ width:250px;
+}
+#sessionNotice {
+ text-align: center;
+ font-style: italic;
+ font-size: 10px;
+}
+.emptyQueue {
+ text-align: center;
+}
+#helpfulLinks {
+ text-align: right;
+}
+
+/* editors/review */
+.reviewnav {
+ float: right;
+ display: block;
+ min-width: 200px;
+ text-align:center;
+ margin-right:20px;
+}
+.reviewnav a {
+ padding: .5em;
+ margin-top: .5em;
+}
+.reviewheader {
+ margin-top: 50px;
+}
+.headerboxes {
+ width: 31%;
+ float: left;
+}
+#header2 {
+ border-right: 1px solid #888;
+ border-left: 1px solid #888;
+}
+#header2, #header3 {
+ padding-left: 5px;
+}
+
+#headerbox ul {
+ margin-top: 0;
+}
+#headerbox li, #files {
+ list-style: none;
+ margin-left: 0;
+ text-indent: -2em;
+}
+#authors li:before {
+ content: "\00BB \0020";
+}
+#categorylist li:before {
+ content: "\00BB \0020";
+}
+#files li:before {
+ content: "\00BB \0020";
+}
+#compatibility img {
+ margin-right: 5px;
+ vertical-align: middle;
+}
+#notes h3 {
+ font-weight: bold;
+ font-size: 14px;
+}
+#notes div {
+ margin: 10px;
+}
+#notes .highlighted {
+ margin: 0;
+ margin-bottom: 10px;
+ padding: 10px;
+ border: 1px solid gray;
+}
+.fileCheckbox {
+ vertical-align: middle;
+}
+#multipleNotice {
+ color: red;
+ font-weight: bold;
+}
+#links {
+ text-align: center;
+}
+#links span {
+ font-weight: bold;
+ padding: 4px 0 6px 28px;
+ margin-left: 10px;
+}
+#links #overview_link {
+ margin-left: 0px;
+ background: url('../img/developers/overview.png') no-repeat;
+}
+#links #history_link {
+ background: url('../img/developers/history.png') no-repeat;
+}
+#links #previews_link {
+ background: url('../img/developers/previews.png') no-repeat;
+}
+#links #homepage_link {
+ background: url('../img/developers/homepage.png') no-repeat;
+}
+#links #edit_link {
+ background: url('../img/edit.png') no-repeat;
+}
+#form {
+ margin: 15px 50px;
+ border: 1px solid #999;
+ background: #eeeeee;
+ text-align: center;
+}
+#form img {
+ border: 0;
+ vertical-align: middle;
+}
+#subform div {
+ margin: 5px 0;
+}
+#commentsbox {
+ padding: 5px;
+}
+#comments {
+ padding: 5px;
+ vertical-align: top;
+}
+#actionbox {
+ padding: 5px;
+}
+.action_color {
+ cursor: pointer;
+ font-weight: bold;
+ padding: 5px;
+ color: black;
+}
+.action_bw {
+ cursor: pointer;
+ font-weight: bold;
+ padding: 5px;
+ color: gray;
+}
+.input {
+ font-size: 12px;
+ font-family: verdana, sans-serif;
+ border: 1px dashed #999;
+}
+#os {
+ float: left;
+ width: 49%;
+}
+#apps {
+ float: right;
+ width: 49%;
+}
+#process {
+ margin: 5px;
+ font-weight: bold;
+ vertical-align: middle;
+}
+.sectionHeader .name {
+ text-align: left;
+ float: left;
+ width: 75%;
+ font-weight: bold;
+ font-size: 15px;
+}
+.sectionHeader .top {
+ text-align: right;
+ float: left;
+ width: 24%;
+}
+.clear {
+ clear: both;
+}
+#historyTable {
+ width: 100%;
+}
+#historyTable #headerRow td {
+ font-weight: bold;
+ border-bottom: 1px solid gray;
+}
+#historyTable #notFound {
+ font-style: italic;
+ text-align: center;
+}
+.sectionTitle {
+ font-variant: small-caps;
+}
+#filesTitle {
+ font-weight: bold;
+}
+
+/* editors/reviews_queue.thtml */
+.review-reply {
+ margin: .5em 0 0 3em;
+}
+
+.reviewAction {
+ margin-top: 5px;
+}
+.reviewAction input {
+ vertical-align: bottom;
+}
+
+/* editors/reviewlog */
+.reviewEntryActive {
+ background-color: #eeeeee;
+}
+.reviewComment {
+ background-color: #ddddff;
+ margin-bottom: 20px;
+}
+
+/* editors/featured */
+table#features tr td {
+ padding-left: 10px;
+}
+table#features tr.featureHeader,
+table#features tr.queueHeader {
+ text-align:left;
+ padding-left:0px;
+
+}
+table#features tr.featureTypeHeader {
+ text-align: right;
+}
+table#features tr td input[type=text] {
+ width:80%;
+}
+
+table#features tr.extension {
+ background-color: #d1ffff;
+}
+table#features tr.extension.even,
+table#features tr.extension.odd {
+ background-color: #eaffff;
+}
+table#features tr td img.featureadd,
+table#features tr td img.featureremove {
+ padding: 2px 3px 2px 2px;
+}
+table#features tr.theme {
+ background-color: #ffe5d1;
+}
+table#features tr.theme.even,
+table#features tr.theme.odd {
+ background-color: #ffefef;
+}
+table#features tr.searchengine {
+ background-color: #ffffd0;
+}
+table#features tr.searchengine.even,
+table#features tr.searchengine.odd {
+ background-color: #ffffef;
+}
+div.autocomplete {
+ position:absolute;
+ width:250px;
+ background-color:white;
+ border:1px solid #888;
+ margin:0px;
+ padding:0px;
+}
+div.autocomplete ul {
+ list-style-type:none;
+ margin:0px;
+ padding:0px;
+}
+div.autocomplete ul li.selected { background-color: #ffb;}
+div.autocomplete ul li {
+ overflow:hidden;
+ list-style-type:none;
+ display:block;
+ margin:0;
+ padding:2px;
+ height:16px;
+ cursor:pointer;
+ text-align: left;
+}
+.success {
+ padding-left:5px;
+ color: #060;
+}
+.failure {
+ padding-left:5px;
+ color: #f33;
+}
+/* flagged add-ons */
+table#flagged tr.even { background-color: #eeeeff; }
+
+/* editors/performance */
+form#performanceFilter > div {
+ margin: 5px;
+}
+input#user {
+ width: 250px;
+}
+.performanceHeader {
+ margin-top: 20px;
+ margin-bottom: 10px;
+ padding-left: 24px;
+ font-size: 160%;
+ color: #426a13;
+ background: #abe071 url('../img/sprite.png?20090430') 0px 0px no-repeat;
+ border-bottom: 1px solid #79be1b;
+}
+.performanceHeader.collapsible span {
+ display: block;
+ margin-left: -17px;
+ padding-left: 17px;
+ background: transparent url('../img/sprite.png?20090430') 0px -318px no-repeat;
+}
+.performanceHeader.collapsible.expanded span {
+ background-position: 0px -261px;
+}
+#historyTable th {
+ font-weight: bold;
+ border-bottom: 1px solid gray;
+}
+#weeklyTable th {
+ font-weight: bold;
+ border-bottom: 1px solid gray;
+}
+th.numeric {
+ text-align: right;
+}
+td.numeric {
+ text-align: right;
+}
+th.headerSort {
+ cursor: pointer;
+ background-image: url('../img/developers/sort-bg.gif');
+ background-repeat: no-repeat;
+ background-position: center right;
+ padding-right: 20px;
+ background-color: #e6eeee;
+}
+th.headerSortDown {
+ background-image: url('../img/developers/sort-asc.gif');
+ background-color: #ccccff;
+}
+th.headerSortUp {
+ background-image: url('../img/developers/sort-desc.gif');
+ background-color: #ccccff;
+}
+#tabTable #details,
+#tabTable #charts {
+ border-bottom: 1px solid black;
+ text-align: left;
+ vertical-align: bottom;
+}
+.html-rtl #tabTable #details,
+.html-rtl #tabTable #charts {
+ text-align: right;
+}
+#performanceUserSelect {
+ float:right;
+}
+.html-rtl #performanceUserSelect {
+ float:left;
+}
+.performancePieContainer {
+ height: 200px;
+ margin: 10px 5px;
+}
+#byCatTeamChart,
+#byCatUserChart {
+ width: 200px;
+ float: left;
+ clear: left;
+}
+.html-rtl #byCatTeamChart,
+.html-rtl #byCatUserChart {
+ float: right;
+ clear: left;
+}
+#performanceTeamLegend,
+#performanceUserLegend {
+ float: left;
+ margin: 0 10px;
+}
+#performanceTeamLegend div,
+#performanceUserLegend div {
+ margin: 0.2em;
+ padding: 0 0.2em;
+}
+.html-rtl #performanceTeamLegend,
+.html-rtl #performanceUserLegend {
+ float: right;
+}
diff --git a/site/app/webroot/css/f8.css b/site/app/webroot/css/f8.css
new file mode 100644
index 0000000..ed61920
--- /dev/null
+++ b/site/app/webroot/css/f8.css
@@ -0,0 +1,91 @@
+#container {
+ max-width: none;
+ padding-left: 20px;
+ padding-right: 20px;
+}
+#f8_body {
+ width: 100%;
+}
+#addonbox {
+ float: left;
+ width: 75%;
+}
+#addonsidebar {
+ margin-left: 75%;
+}
+ul.browselist {
+ list-style: none;
+ padding-left: 10px;
+ margin-top: 0px;
+}
+div.divider {
+ height: 15px;
+ background: #fff url(../img/divider.gif) no-repeat scroll center;
+ border: 0;
+ margin-top: 5px;
+}
+
+#filterbox,
+#filterbox select,
+#filterbox input {
+ font-size: 12px;
+}
+#filterbox input {
+ vertical-align: middle;
+}
+#filterbox {
+ padding-bottom: 5px;
+}
+
+ul.browselist li.selected {
+ font-weight: bold;
+}
+#addonlist div.addon {
+ padding-bottom: 5px;
+}
+#addonlist div.addon div.name {
+
+}
+#addonlist div.addon div.summary {
+ font-size: 10px;
+}
+
+#addonwindow {
+ background: url('../img/f8_box.png') no-repeat;
+ position: absolute;
+ top: 20%;
+ left: 20%;
+ height: 320px;
+ width: 340px;
+ padding: 10px;
+}
+#addonwindow .name {
+ font-weight: bold;
+ font-size: 14px;
+}
+#addonwindow .authors {
+ font-size: 12px;
+}
+#addonwindow .details {
+ font-size: 12px;
+ padding-top: 5px;
+}
+#addonwindow img {
+ vertical-align: middle;
+ line-height: 5;
+}
+#addoninstall {
+ margin: 0px 55px;
+ padding: 15px 0px;
+}
+#add_fav {
+ padding-left: 10px;
+ background: url('../img/smallMedal.png') no-repeat center left;
+}
+div.samelevel div.left {
+ text-align: left;
+ float: left;
+}
+div.samelevel div.right {
+ text-align: right;
+}
diff --git a/site/app/webroot/css/facebook.php b/site/app/webroot/css/facebook.php
new file mode 100644
index 0000000..a99336a
--- /dev/null
+++ b/site/app/webroot/css/facebook.php
@@ -0,0 +1,411 @@
+<?php
+/* This is a special stylesheet for use with Facebook's FBML. It should not be
+ included on any other page. */
+
+include_once('../../config/config.php');
+?>
+<!--
+ Due to Facebook bug, we can only use classes - not ids.
+ Due to Facebook bug, only one url() can be referenced in a single style tag.
+ Due to Facebook bug, I could not enclose "style" in the previous line.
+ Due to Facebook bug, the first style is a dummy so that background URLs are not mismatched.
+-->
+<style>
+ .dummy {
+ background: url('<?=FB_IMAGE_SITE?>/img/facebook/new_media_button_active.gif');
+ }
+
+ /* Browse/search results */
+ .sort_box {
+ background-color: #f7f7f7;
+ padding: 5px 15px;
+ }
+ .filter_tab_bar {
+ padding-left: 10px;
+ border-top: 1px solid #d8dfea;
+ }
+ .filter_tab_bar div {
+ padding: 0;
+ }
+ .filter_tab_bar div ul.tabs {
+ border-left: 1px solid #d8dfea;
+ border-bottom: 0px;
+ float: left;
+ list-style: none;
+ margin: 0px;
+ padding: 0px;
+ }
+ .filter_tab_bar div ul.tabs li {
+ border-right: 1px solid #d8dfea;
+ float: left;
+ margin: 0px;
+ padding: 3px 0px 4px 0px;
+ }
+ .filter_tab_bar div ul.tabs li a {
+ border-bottom: 2px solid white;
+ padding: 3px 6px 2px 6px;
+ font-weight: normal;
+ }
+ .filter_tab_bar div ul.tabs li.current a {
+ border-bottom: 2px solid #6d84b4;
+ padding: 3px 6px 3px 6px;
+ font-weight: bold;
+ }
+ .filter_tab_bar div ul.tabs li a:hover {
+ background: #ebeff4;
+ border-bottom: 1px solid #ebeff4;
+ padding-bottom: 3px;
+ text-decoration: none;
+ }
+ .filter_tab_bar div ul.tabs li.current a:hover {
+ background: none;
+ border-bottom: 2px solid #6d84b4;
+ color: #3b5998;
+ padding: 3px 6px 3px 6px;
+ }
+ .filter_tab_bar div ul.tabs li.empty {
+ padding: 3px 6px 3px 6px;
+ color: #666666;
+ }
+ .filter_tab_bar div ul.tabs li.empty a:hover {
+ background: none;
+ border: none;
+ }
+ .noresults {
+ padding: 25px 0;
+ text-align: center;
+ color: gray;
+ }
+
+ /* Add-on view profile page */
+ .profile {
+ margin: 0px;
+ padding: 0px 10px 0px;
+ }
+ .profile .left {
+ padding: 0px;
+ width: 415px;
+ }
+ .profile .right {
+ padding: 0px 0px 0px 10px;
+ width: 200px;
+ }
+ .header {
+ margin: 0px;
+ padding: 2px 8px;
+ background: #D8DFEA;
+ border-top: solid 1px #3B5998;
+ }
+ .header h2 {
+ font-size: 11px;
+ font-weight: bold;
+ color: #3B5998;
+ }
+ .red .header {
+ background: #FFCCCC;
+ border-top: solid 1px #990000;
+ }
+ .red .header h2,
+ .red .header a {
+ color: #990000;
+ }
+ .profile .box {
+ margin: 0px;
+ padding: 10px 8px 15px 8px;
+ overflow: visible;
+ }
+ .profile .box h4 {
+ margin-top: 1px;
+ margin-left: 0px;
+ margin-bottom: 0;
+ padding-left: 0px;
+ }
+ .profile .darklink {
+ color: #555;
+ }
+ .profile .fallback {
+ background: #f7f7f7;
+ border-top: solid 1px #ccc;
+ border-bottom: solid 1px #D8DFEA;
+ color: gray;
+ padding: 15px 0px 15px 0px;
+ text-align: center;
+ }
+ .profile .people_table {
+ margin: 0px;
+ padding: 0px;
+ }
+ .profile .people_table td {
+ width: 62px;
+ vertical-align: middle;
+ text-align: center;
+ padding: 0px 0px 5px;
+ }
+ .profile .people_table table {
+ height: 100%;
+ }
+ .profile .people_table table td.image {
+ padding-bottom: 0px;
+ font-size: 1px;
+ line-height: 1px;
+ }
+ .profile .people_table table td.name div {
+ width: 60px;
+ }
+ .profile .see_all {
+ margin: 5px 0px 0px;
+ }
+ .box_subhead {
+ color: #444;
+ padding: 2px 8px 2px 8px;
+ border-top: solid 1px #ccc;
+ overflow: hidden;
+ background: #eee;
+ }
+ .box_subhead .box_subtitle {
+ float: left;
+ }
+ .box_subhead .box_actions {
+ float: right;
+ }
+ .box_nopeople {
+ color: #444;
+ padding: 20px 0;
+ border-top: solid 1px #ccc;
+ overflow: hidden;
+ background: #eee;
+ text-align: center;
+ }
+</style>
+<style type="text/css">
+ /* Add-on profile gray bar and add to favorite button */
+ .grayheader .dh_new_media_shell {
+ float: right;
+ background: url('<?=FB_IMAGE_SITE?>/img/facebook/new_media_button_active.gif') no-repeat bottom;
+ margin: 7px 0px 0px;
+ }
+</style>
+<style type="text/css">
+ .grayheader .dh_new_media {
+ float: left;
+ display: block;
+ color: #777;
+ text-decoration: none;
+ background: url('<?=FB_IMAGE_SITE?>/img/facebook/new_media_button.gif') no-repeat;
+ }
+</style>
+<style type="text/css">
+ .grayheader .dh_new_media .tr {
+ background: url('<?=FB_IMAGE_SITE?>/img/facebook/new_media_button.gif') no-repeat top right;
+ }
+</style>
+<style type="text/css">
+ .grayheader .dh_new_media .bl {
+ background: url('<?=FB_IMAGE_SITE?>/img/facebook/new_media_button.gif') no-repeat bottom left;
+ }
+</style>
+<style type="text/css">
+ .grayheader .dh_new_media .br {
+ background: url('<?=FB_IMAGE_SITE?>/img/facebook/new_media_button.gif') no-repeat bottom right;
+ }
+</style>
+<style type="text/css">
+ .grayheader .dh_new_media span {
+ color: #333;
+ font-size: 11px;
+ font-weight: bold;
+ display: block;
+ padding: 3px 9px 5px 22px;
+ text-shadow: white 0px 1px 1px;
+ background: url('<?=FB_IMAGE_SITE?>/img/facebook/new_media_button_plus.gif') no-repeat 9px center;
+ }
+</style>
+<style type="text/css">
+ .grayheader .remove {
+ background: url('<?=FB_IMAGE_SITE?>/img/facebook/icon_remove.gif') no-repeat;
+ padding-left: 15px;
+ }
+</style>
+<style type="text/css">
+ .grayheader .dh_new_media:hover {
+ text-decoration: underline;
+ }
+ .grayheader .dh_new_media:active,
+ .grayheader .dh_new_media:active .tr,
+ .grayheader .dh_new_media:active .bl,
+ .grayheader .dh_new_media:active .br {
+ background-image: url('<?=FB_IMAGE_SITE?>/img/facebook/new_media_button_active.gif');
+ }
+
+ /* profile action buttons */
+ .profileActions {
+ margin: 0px;
+ padding: 10px 0px;
+ background: white;
+ z-index: 999;
+ }
+ .profileActions a {
+ border-bottom: 1px solid #D8DFEA;
+ display: block;
+ width: 187px;
+ margin: 0px;
+ padding: 2px 3px 2px 9px;
+ }
+ .profileActions a:hover {
+ color: white;
+ background: #3B5998;
+ text-decoration: none;
+ }
+</style>
+<style type="text/css">
+ /* install now button */
+ .confirm_button a {
+ float: left;
+ display: block;
+ background: url('<?=FB_IMAGE_SITE?>/img/facebook/confirm_button.gif') no-repeat top left;
+ font-size: 13px;
+ font-weight: bold;
+ color: #d8dfea;
+ cursor: pointer;
+ }
+</style>
+<style type="text/css">
+ .installbox {
+ padding: 10px;
+ margin-left: 15%;
+ }
+ .confirm_button div {
+ background: url('<?=FB_IMAGE_SITE?>/img/facebook/confirm_button.gif') no-repeat top right;
+ }
+</style>
+<style type="text/css">
+ .confirm_button div div {
+ background-position: bottom left;
+ }
+ .confirm_button div div div {
+ background-position: bottom right;
+ padding: 0px 0px 0px 10px;
+ }
+ .confirm_button span {
+ display: block;
+ padding: 4px 10px 5px 22px;
+ background: url('<?=FB_IMAGE_SITE?>/img/facebook/confirm_button_extension.gif') no-repeat left center;
+ color: #FFF;
+ }
+</style>
+<style type="text/css">
+ .confirm_button a:active,
+ .confirm_button a:active div {
+ background-image: url('<?=FB_IMAGE_SITE?>/img/facebook/confirm_button_active.gif');
+ }
+</style>
+<style type="text/css">
+ /* Favorites Page */
+ .subtabs {
+ display: block;
+ margin: 0px 0px 0px -7px;
+ padding: 10px 25px 0px 25px;
+ border-bottom: solid 1px #ccc;
+ }
+ .subtabs .tab {
+ margin: 0px 7px -1px 0px;
+ border: solid 1px #ccc;
+ border-bottom: solid 1px #ffffff;
+ z-index: 10;
+ position: relative;
+ padding: 5px 7px 4px;
+ color: #555555;
+ float: left;
+ line-height: 13px;
+ font-size: 13px;
+ font-weight: bold;
+ }
+ .subtabs .tab a {
+ color: #555555;
+ }
+ .subtabs .unselected {
+ border: solid 1px #dedede;
+ border-bottom: solid 1px #ccc;
+ color: #888888;
+ font-size: 11px;
+ }
+ .subtabs .unselected a {
+ color: #888888;
+ }
+ .subtabs .unselected:hover {
+ cursor: pointer;
+ color: #3B5998;
+ text-decoration: underline;
+ }
+ table.myfavorites {
+ width: 100%;
+ }
+ table.myfavorites td {
+ padding-top: 7px;
+ padding-bottom: 7px;
+ vertical-align: middle;
+ border-bottom: solid 1px #ddd;
+ }
+ table.myfavorites td.info {
+ margin: 0px;
+ padding: 0px 20px 0px 5px;
+ width: 50%;
+ font-size: 13px;
+ font-weight: bold;
+ color: #555;
+ }
+ table.myfavorites td.imported {
+ width: 30%;
+ color: gray;
+ }
+ table.myfavorites td.remove {
+ width: 20%;
+ }
+ .favorites .remove a {
+ background: url('<?=FB_IMAGE_SITE?>/img/facebook/icon_remove.gif') no-repeat;
+ padding-left: 15px;
+ }
+ .favorites div.nofavorites {
+ text-align: center;
+ padding: 30px 0;
+ color: gray;
+ font-size: 13px;
+ }
+</style>
+<style>
+ /* Layout */
+ body {
+ font-family: verdana, sans-serif;
+ }
+ .content {
+ min-height: 300px;
+ }
+ .page-header {
+ margin: 0px;
+ height: 80px;
+ }
+ .search {
+ float: right;
+ padding-right: 15px;
+ color:#555;
+ }
+ .search input {
+ font-size: 11px;
+ width: 100px;
+ padding-left: 17px;
+ margin-left: 2px;
+ }
+ .tabs {
+ margin-top: 5px;
+ }
+ .page-footer {
+ border-top: 1px solid #3b5998;
+ padding: 5px;
+ color: #666666;
+ text-align: center;
+ clear: both;
+ }
+ .page-footer a {
+ color: #333333;
+ }
+</style>
diff --git a/site/app/webroot/css/filebrowser.css b/site/app/webroot/css/filebrowser.css
new file mode 100644
index 0000000..f94c1be
--- /dev/null
+++ b/site/app/webroot/css/filebrowser.css
@@ -0,0 +1,68 @@
+/* reviewers/browse */
+#fileBrowser {
+ width: 100%;
+ height: 99%;
+ border: 1px dashed black;
+}
+#fileContents {
+ position: absolute;
+ width: 300px;
+ top: 25px;
+ right: 30px;
+ background: #F7F8F8;
+ border: 1px solid black;
+}
+#fileHeader {
+ height: 38px;
+ position: relative;
+ border-bottom: 1px solid #A1A6B1;
+ background: #33415D url("../img/template/header-background.png") top repeat-x;
+ z-index: 1;
+ text-align: center;
+ cursor: move;
+}
+#fileFooter {
+ text-align: right;
+ font-size: 12px;
+ font-family: verdana, sans-serif;
+}
+#fileFooter a:link {
+ text-decoration: none;
+ color: #999;
+}
+#fileFooter a:visited {
+ text-decoration: none;
+ color: #999;
+}
+#fileListing {
+ max-height: 200px;
+ overflow: auto;
+ font-size: 12px;
+ font-family: verdana, sans-serif;
+}
+.fileList li {
+ list-style: none;
+ margin-left: 0;
+ text-indent: -1em;
+}
+.fileList li.modified {
+ font-style: italic;
+}
+.fileList li.directory:before {
+ content: "\00BB \0020";
+}
+.fileList li.file:before {
+ content: "\203A \0020";
+ margin-right: 2px;
+}
+
+.fileList li.directory a:link {
+ text-decoration: none;
+ color: black;
+ font-weight: bold;
+}
+.fileList li.directory a:visited {
+ text-decoration: none;
+ color: black;
+ font-weight: bold;
+}
diff --git a/site/app/webroot/css/forms.css b/site/app/webroot/css/forms.css
new file mode 100644
index 0000000..0c091e4
--- /dev/null
+++ b/site/app/webroot/css/forms.css
@@ -0,0 +1,74 @@
+.amo-form > div {
+ margin: 1em 0;
+}
+
+.amo-submit {
+}
+
+.amo-submit:hover {
+}
+
+.amo-cancel {
+}
+
+.amo-label-large, .amo-label-medium, .amo-label-small {
+ border-bottom: 1px dashed #eee;
+ float: left;
+ clear:left;
+}
+
+.amo-label-large {
+ width: 14em;
+}
+
+.amo-label-medium {
+ width: 10em;
+}
+
+.amo-label-small {
+ width: 8em;
+}
+
+.amo-label-xsmall {
+ width: 6em;
+}
+
+.amo-form-error {
+ background-color: #eee;
+ border: 1px dashed #c66;
+ color: #c00;
+ margin: 5px 0;
+ padding: .5em;
+}
+
+.amo-form div.error_message {
+ color: #c00;
+ display: block;
+ margin: 0;
+ padding-bottom: 1em;
+}
+
+
+.amo-form div.amo-form-indent {
+ margin-left: 14em;
+}
+
+.html-rtl .amo-form div.amo-form-indent {
+ margin-left: auto;
+ margin-right: 14em;
+}
+
+.amo-remember {
+ margin-left: 12.2em;
+}
+
+.html-rtl .amo-remember {
+ margin-left: auto;
+ margin-right: 12.2em;
+}
+
+.html-rtl .amo-label-large, .html-rtl .amo-label-medium, .html-rtl .amo-label-small {
+ float: right;
+}
+
+
diff --git a/site/app/webroot/css/frame.css b/site/app/webroot/css/frame.css
new file mode 100644
index 0000000..c02411b
--- /dev/null
+++ b/site/app/webroot/css/frame.css
@@ -0,0 +1,28 @@
+#frame {
+ width:750px;
+ text-align: left;
+ margin: 0 auto;
+}
+
+#main {
+ margin: 0 18px;
+ position:relative;
+}
+
+a:active,a:hover,a:link,a:visited {
+ color:#5069a1;
+}
+
+a.secondary:active,a.secondary:hover,a.secondary:link,a.secondary:visited {
+ color:#93a3c6;
+}
+/* FROM EXISTING AMO... */
+
+.disclaimer {
+ text-align: center;
+ color: #ccc;
+ font-size: x-small;
+ width: 600px;
+ margin-left: auto;
+ margin-right: auto;
+}
diff --git a/site/app/webroot/css/ie.css b/site/app/webroot/css/ie.css
new file mode 100644
index 0000000..35f561e
--- /dev/null
+++ b/site/app/webroot/css/ie.css
@@ -0,0 +1,64 @@
+/*----------------------------------------------------------------------------
+CSS file for all versions of IE for Addons.mozilla.org
+Created by Craig Cook - focalcurve.com
+ on November 20, 2007
+-----------------------------------------------------------------------------*/
+
+/* I can hasLayout */
+#content-main, .addon .vex, .addon .secondary-container { zoom: 1; }
+#categories h3, #categories h3 span { zoom: 1; }
+#categories a, #categories p { zoom: 1; }
+#addon-info, #addon-advanced { zoom: 1; }
+.install-button, .pagination, .addon-reviews, .addon-versions { zoom: 1; }
+.browse-list a, #dictionaries { zoom: 1; }
+.collections li.coll-addon { zoom: 1; }
+
+/* Conflicts with container padding in spite of being positioned out of normal flow. */
+.main .vex { width: 100%; position: static; padding: 0 20px 0 240px; margin: 0 -20px -10px -240px; }
+.main .vex span { position: relative; left: -240px; }
+.sub .vex { padding: 0 20px; left: -1px; }
+.sub .vex span { margin-left: -20px; }
+
+#addon-summary .vex { width: 100%; left: 240px; bottom: 0; padding: 0 20px 0 240px; margin: 0 -20px 0 -240px; }
+#addon-summary .vex span { position: relative; left: -240px; }
+
+#addon-listing .addon .vex { width: 100%; left: 0; padding: 0 240px; margin: 0 -240px 0 0; }
+#addon-listing .addon .vex span { position: relative; left: -240px; }
+
+/* Some special rules for the side-by-side floats. */
+#content.wide #recommended .addon { padding-left: 25%; width: 22%; }
+#content.wide #recommended .addon .name { width: 80%; }
+#content.wide #recommended .addon .vex { padding: 0; }
+#content.wide #recommended .addon .vex span { left: 0; margin-right: 10px; }
+
+/* Size adjustements */
+.html-ltr #search-element {left: 18%}
+#search-form #search-submit { width: 4em; }
+#addon-listing .exp .exp-loggedout,
+#addon-listing .exp .exp-confirmed { width: 160px; }
+#rate-it legend span { left: -6px; }
+
+#content.landing #content-extra { width: 21%; }
+#content.landing-with-slider #content-extra { width: 24%; }
+.browse-list { padding-bottom: 15px; }
+#content.landing.browse #content-extra { width: 48%; }
+#content.landing-with-slider #secondaries .sub { width: 31.0%; margin-right: 2.5%; }
+
+/* Position adjustments */
+.html-ltr #search-form { left: 18%; }
+#advanced-search-toggle { top: -5px; }
+#advanced-search-toggle div { position: relative; top: 2px; height: 4px }
+#advanced-search-toggle #toggle-inner { background-position-y: -88px; padding-left: 0; }
+#page-title { z-index: 1; }
+#nav-user { position: relative; }
+#nav-access { z-index: 99; }
+#order-by #order-label { float: left; }
+
+/* Padding adjustments */
+#order-by button { padding: 4px 2px; }
+#order-by #order-label { padding: 8px 2px; }
+
+/* Type adjustments */
+#language { font-size: 95%; }
+
+.install-button a strong { cursor: pointer; }
diff --git a/site/app/webroot/css/ie6.css b/site/app/webroot/css/ie6.css
new file mode 100644
index 0000000..5e31336
--- /dev/null
+++ b/site/app/webroot/css/ie6.css
@@ -0,0 +1,125 @@
+/*----------------------------------------------------------------------------
+CSS file for IE6 for Addons.mozilla.org
+Created by Craig Cook - focalcurve.com
+ on November 20, 2007
+-----------------------------------------------------------------------------*/
+
+/* I can hasLayout */
+#branding, #page-title h1, div.error-notice { zoom: 1; }
+#other-apps.js #nav-apps li { zoom: 1; }
+#content, #content-main, #content-extra, #recommended, #secondaries, #form-listcontrol { zoom: 1; }
+.addon, .install-button, .install-button a { zoom: 1; }
+#addon-info, #addon-advanced, #form-review, .latest-version { zoom: 1; }
+
+/* There are various icky bugs related to padding with percentages. Avoid this
+ by removing the padding and shifting the box outside of its parent. */
+#content.main-page #content-main,
+#content.detail-page #content-main,
+#content.detail-page #content-main.full,
+#content.reviews-page #content-main,
+#content.reviews-page #content-main.full,
+#content.versions-page #content-main,
+#content.versions-page #content-main.full { padding-right: 0; }
+#content-main #content-extra { right: -33%; }
+
+/* More percentage padding bugs, so the side-by-side liquid floats fail badly. Degrading to the natural layout instead. */
+#content.wide #recommended .addon { padding-left: 240px; width: auto; }
+#content.wide #recommended .addon .name { width: auto; }
+#content.wide #recommended .addon .preview-img { width: auto; overflow: visible; }
+#content #recommended .addon .vex,
+#content.wide #recommended .addon .vex { position: absolute; right: -260px; padding-left: 0; left: 0; width: auto; margin: 0; }
+#content #recommended .addon .vex span,
+#content.wide #recommended .addon .vex span { padding-left: 0; margin-left: 0; left: -1px; width: auto; }
+#content.wide #recommended #feature1 { float: none; margin-bottom: 1em; }
+#content.wide #recommended #feature2 { float: none; }
+
+/* Alternative 8-bit images since IE6 doesn't support alpha-transparent 24-bit PNGs. */
+h4#moz a { background-image: url("../img/moz-tab-ie.png"); }
+div.error-notice { background-image: url("../img/warning-ie.png"); }
+
+/* Aaron Gustafson's Image Image Replacement - Inline image is replaced by background. See http://old.easy-designs.net/articles/iIR/ */
+#page-title h1 img { display: block; text-indent: -999em; padding-top: 105px; width: 110px; height: 0; overflow: hidden; background-repeat: no-repeat; }
+#page-title.firefox h1 img { background-image: url("../img/app-icons/firefox-ie.png"); }
+#page-title.thunderbird h1 img { background-image: url("../img/app-icons/thunderbird-ie.png"); }
+#page-title.sunbird h1 img { background-image: url("../img/app-icons/sunbird-ie.png"); }
+#page-title.seamonkey h1 img { background-image: url("../img/app-icons/seamonkey-ie.png"); }
+
+/* Bottom edges - IE7 needs different rules than IE6 so we'll override the previous style sheets */
+.addon .vex { padding: 0; }
+.addon .vex span { margin-left: 0; }
+#addon-listing .addon .vex, #addon-summary .vex, .main .vex { padding: 0; }
+#addon-listing .addon .vex span, .main .vex span { margin-left: 0; }
+#addon-summary .vex span, .main .vex span { margin-left: 1px; }
+.sub .vex { padding: 0; left: 1px; }
+.sub .vex span { margin-left: 0; }
+
+.main .vex { width: 100%; position: absolute; padding: 0; margin: 0; }
+.main .vex span { position: relative; left: 0; }
+
+#addon-summary .vex { width: 100%; left: -1px; bottom: 0; padding: 0; margin: 0; }
+#addon-summary .vex span { position: relative; left: -1px; }
+
+#addon-listing .addon .vex { width: 100%; left: -1px; padding: 0 220px; margin: 0; }
+#addon-listing .addon .vex span { position: relative; left: -220px; }
+
+/* IE6 doesn't shrinkwrap the float, so removing the border makes it look better */
+#addon-summary .exp-loggedout,
+#addon-summary .exp-confirmed { border: 0; padding: 0; }
+
+/* Lose the left border because IE6 doesn't support :first-child */
+#nav-user li, .addon-cats li, #addon-listing .more li { border: 0; padding-left: 0; }
+
+/* Fix weird positioning */
+.sub .flag { margin-left: 20px; }
+
+#content.landing.browse #secondaries #feature2 { margin-right: 0; }
+#content.landing.languages #secondaries #feature3 { margin-right: 0; }
+
+#content.landing.languages #secondaries { margin-bottom: 1.5em; }
+
+/* Color adjustments */
+.exp-loggedout .install-button a:hover,
+.exp-confirmed .install-button a:hover { color: #aaa; }
+
+/* Position and margin adjustments */
+.sub .irk, .addon .vex span { margin-left: 0; position: relative; left: -1px; }
+.main .vex span, #addon-listing .vex span { left: 0; }
+.addon .vex { margin-left: -1px; margin-bottom: -1px; }
+#other-apps.js #nav-apps { margin-top: 10px; }
+#content.landing #secondaries #feature5 { margin-right: 0; }
+#content.landing-with-slider #secondaries .addon { width: 28%; }
+#content.landing #secondaries .sub .flag { left: -20px; }
+#content.landing-with-slider #content-extra { width: 24%; margin-right: .25%; float: right; }
+#content.landing #content-extra { width: 22%; margin-right: .25%; float: right; }
+#form-listcontrol #per-page.hidden { left: -999em; }
+.addon .name img { left: -44px; }
+#form-review #review-submit { margin-bottom: 0; }
+#recommended { float: none; zoom: 1; }
+
+/* Size and padding adjustements */
+#content { height: 800px; } /* acts like min-height */
+.addon { height: 170px; } /* acts like min-height */
+#page-title div { padding-left: 120px; }
+#content-extra { width: 29%; }
+#search-form { height: 54px; }
+#content #sidebar { width: 17.5%; }
+#categories.collapsed #cat-list a:active { width: 150px; }
+.main .vex, #addon-listing .addon .vex, #addon-summary .vex { padding-right: 261px; }
+#categories.collapsed #cat-list.visible { width: auto; margin: 0; }
+
+#recommended { padding: 0 10px 10px; width: auto; }
+#addon-summary, #recommended .addon { height: 220px; }
+.sub .preview-img { width: 100%; }
+#content.landing #secondaries .sub .irk { padding-top: 2.2em; }
+#order-by button { padding: 4px 2px; }
+#form-listcontrol { padding: 8px 200px; width: auto; }
+#form-review { padding-bottom: 0; }
+#content.landing.browse #content-extra { width: 47%; }
+
+#thumb-subcategories { width: 17.5% }
+#thumb-subcategories ul li a, #thumb-subcategories ul li span { zoom: 1; }
+#thumb-browser #form-listcontrol { padding:8px 12% 8px 14%; }
+#thumb-browser #order-by button { font-size: 98% }
+#thumb-browser .thumbs { list-style-type:none; margin-left: 20%; }
+#thumb-browser .thumbs li.thumb .vex { height: 8px; margin-top: -10px }
+#thumb-browser .thumbs li.thumb .vex span { height: 8px; margin-left:0px; }
diff --git a/site/app/webroot/css/images/arrow.gif b/site/app/webroot/css/images/arrow.gif
new file mode 100644
index 0000000..965b0aa
--- /dev/null
+++ b/site/app/webroot/css/images/arrow.gif
Binary files differ
diff --git a/site/app/webroot/css/images/container_bg.gif b/site/app/webroot/css/images/container_bg.gif
new file mode 100755
index 0000000..fed97a9
--- /dev/null
+++ b/site/app/webroot/css/images/container_bg.gif
Binary files differ
diff --git a/site/app/webroot/css/images/logo.gif b/site/app/webroot/css/images/logo.gif
new file mode 100755
index 0000000..0d0cf00
--- /dev/null
+++ b/site/app/webroot/css/images/logo.gif
Binary files differ
diff --git a/site/app/webroot/css/images/nav_bg.gif b/site/app/webroot/css/images/nav_bg.gif
new file mode 100755
index 0000000..4b320be
--- /dev/null
+++ b/site/app/webroot/css/images/nav_bg.gif
Binary files differ
diff --git a/site/app/webroot/css/images/nav_item_bg.gif b/site/app/webroot/css/images/nav_item_bg.gif
new file mode 100755
index 0000000..d106c10
--- /dev/null
+++ b/site/app/webroot/css/images/nav_item_bg.gif
Binary files differ
diff --git a/site/app/webroot/css/jquery-lightbox.css b/site/app/webroot/css/jquery-lightbox.css
new file mode 100644
index 0000000..fe73a31
--- /dev/null
+++ b/site/app/webroot/css/jquery-lightbox.css
@@ -0,0 +1,102 @@
+/**
+ * jQuery lightBox plugin
+ * This jQuery plugin was inspired and based on Lightbox 2 by Lokesh Dhakar (http://www.huddletogether.com/projects/lightbox2/)
+ * and adapted to me for use like a plugin from jQuery.
+ * @name jquery-lightbox-0.4.css
+ * @author Leandro Vieira Pinho - http://leandrovieira.com
+ * @version 0.4
+ * @date November 17, 2007
+ * @category jQuery plugin
+ * @copyright (c) 2007 Leandro Vieira Pinho (leandrovieira.com)
+ * @license CC Attribution-No Derivative Works 2.5 Brazil - http://creativecommons.org/licenses/by-nd/2.5/br/deed.en_US
+ * @example Visit http://leandrovieira.com/projects/jquery/lightbox/ for more informations about this jQuery plugin
+ */
+#jquery-overlay {
+ position: absolute;
+ top: 0;
+ left: 0;
+ z-index: 900;
+ width: 100%;
+ height: 500px;
+}
+#jquery-lightbox {
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 100%;
+ z-index: 901;
+ text-align: center;
+ line-height: 0;
+}
+#jquery-lightbox a img { border: none; }
+#lightbox-container-image-box {
+ position: relative;
+ background-color: #fff;
+ width: 250px;
+ height: 250px;
+ margin: 0 auto;
+}
+#lightbox-container-image { padding: 10px; }
+#lightbox-loading {
+ position: absolute;
+ top: 40%;
+ left: 0%;
+ height: 25%;
+ width: 100%;
+ text-align: center;
+ line-height: 0;
+}
+#lightbox-nav {
+ position: absolute;
+ top: 0;
+ left: 0;
+ height: 100%;
+ width: 100%;
+ z-index: 10;
+}
+#lightbox-container-image-box > #lightbox-nav { left: 0; }
+#lightbox-nav a { outline: none;}
+#lightbox-nav-btnPrev, #lightbox-nav-btnNext {
+ width: 49%;
+ height: 100%;
+ zoom: 1;
+ display: block;
+}
+#lightbox-nav-btnPrev {
+ left: 0;
+ float: left;
+}
+#lightbox-nav-btnNext {
+ right: 0;
+ float: right;
+}
+#lightbox-container-image-data-box {
+ font: 10px Verdana, Helvetica, sans-serif;
+ background-color: #fff;
+ margin: 0 auto;
+ line-height: 1.4em;
+ overflow: hidden;
+ width: 100%;
+ padding: 0 10px 0;
+}
+#lightbox-container-image-data {
+ padding: 0 10px;
+ color: #666;
+}
+#lightbox-container-image-data #lightbox-image-details {
+ width: 70%;
+ float: left;
+ text-align: left;
+}
+#lightbox-image-details-caption { font-weight: bold; }
+#lightbox-image-details-currentNumber {
+ display: block;
+ clear: left;
+ padding-bottom: 1.0em;
+}
+#lightbox-secNav-btnClose {
+ width: 66px;
+ float: right;
+ padding-bottom: 0.7em;
+}
+
diff --git a/site/app/webroot/css/jquery-ui/dark/dark.css b/site/app/webroot/css/jquery-ui/dark/dark.css
new file mode 100644
index 0000000..a5ae559
--- /dev/null
+++ b/site/app/webroot/css/jquery-ui/dark/dark.css
@@ -0,0 +1,11 @@
+.dark { background:#111; color:snow; font:10pt Calibri, Arial, sans-serif; }
+.dark a, a.dark { color:#68D; outline:none; }
+.dark a:visited, a.dark:visited { color:#D66; }
+.dark a:hover, a.dark:hover { color:#FFF; }
+.dark fieldset { border:1px solid #282828; }
+.dark legend { color:#CCC; font:.8em Verdana, san-serif; }
+.dark button, button.dark, .dark input, input.dark { padding:2px 4px; font:.9em Consolas, Verdana, san-serif; }
+.dark textarea, textarea.dark { padding:2px 4px; font:.9em Consolas, Courier New, san-serif; width:20em; height:5em; overflow:auto; }
+.dark select, select.dark { padding:3px 0 3px 4px; font:.9em Verdana, san-serif; }
+.dark label { font-weight:bold; }
+
diff --git a/site/app/webroot/css/jquery-ui/dark/dark.form.css b/site/app/webroot/css/jquery-ui/dark/dark.form.css
new file mode 100644
index 0000000..9be8c9a
--- /dev/null
+++ b/site/app/webroot/css/jquery-ui/dark/dark.form.css
@@ -0,0 +1,192 @@
+.dark .ui-form-hide { position:absolute; left:-2000em; }
+
+
+/*( fieldset )*/
+.dark .ui-form-fieldset,
+.dark.ui-form-fieldset {
+ display:block;
+ border:1px solid #333;
+ padding:0;
+}
+.dark .ui-form-fieldset,
+.dark.ui-form-fieldset {
+ margin-top:1.6em;
+}
+.dark fieldset.ui-form {
+ margin:0;
+ border:1px solid #111;
+ color:snow;
+}
+.dark fieldset.ui-form { background:#181818; }
+.dark .ui-form-legend,
+.dark.ui-form-legend {
+ display:block;
+ text-align:left;
+ border:1px solid #333;
+ background:#222;
+ margin:-1.05em 0 0 0;
+}
+.dark legend.ui-form {
+ display:block;
+ color:snow;
+ font-weight:bold;
+ background:#222;
+ border-top:1px dotted #282828;
+ border-bottom:1px dotted #282828;
+ margin:-1px 2px;
+ padding:0 2px 2px;
+}
+
+
+/*( inputs )*/
+.dark .ui-form-text,
+.dark .ui-form-password,
+.dark.ui-form-text,
+.dark.ui-form-password {
+ border:1px solid #333;
+ padding:2px 0 3px;
+}
+
+.dark .ui-form-textarea,
+.dark.ui-form-textarea {
+ display:block;
+ border:1px solid #333;
+ padding:0;
+}
+.dark .ui-form-textarea .ui-form-inner,
+.dark.ui-form-textarea .ui-form-inner {
+ display:block;
+ border:1px solid #111;
+ overflow:hidden;
+}
+.dark .ui-form-text.focus,
+.dark .ui-form-password.focus,
+.dark .ui-form-textarea.focus,
+.dark.ui-form-text.focus,
+.dark.ui-form-password.focus,
+.dark.ui-form-textarea.focus {
+ border:1px solid #444;
+}
+
+.dark .ui-form-text input,
+.dark .ui-form-password input,
+.dark textarea.ui-form {
+ margin:0;
+ border:1px solid #111;
+ background:#222; color:snow;
+}
+.dark textarea.ui-form { border:none; }
+.dark .ui-form-text input:focus,
+.dark .ui-form-password input:focus,
+.dark textarea.ui-form:focus { background:#1D1D1D; }
+
+
+/*( buttons )*/
+.dark .ui-form-buttons,
+.dark.ui-form-buttons {
+ display:block; float:left;
+ height:40px;
+ background:url(dark.form.png) left -40px;
+ border:none;
+ color:#CCC;
+ padding-left:25px;
+ margin:0 4px;
+}
+.dark .ui-form-buttons .ui-form-inner,
+.dark.ui-form-buttons .ui-form-inner {
+ display:block; float:left;
+ height:40px;
+ background:url(dark.form.png) right -40px;
+ margin-right:-5px;
+ padding-right:5px;
+}
+.dark .ui-form-buttons .ui-form,
+.dark.ui-form-buttons .ui-form {
+ background:transparent;
+ border:none;
+ color:#DDD;
+ padding:9px 25px 10px 25px;
+ *padding:9px 15px 10px 15px;
+ margin-left:-25px;
+}
+.dark .ui-form-buttons.hover,
+.dark.ui-form-buttons.hover {
+ background-position:left -80px;
+}
+.dark .ui-form-buttons.hover .ui-form-inner,
+.dark.ui-form-buttons.hover .ui-form-inner {
+ background-position:right -80px;
+}
+.dark .ui-form-buttons.hover .ui-form,
+.dark.ui-form-buttons.hover .ui-form {
+ color:#FFF;
+}
+.dark .ui-form-buttons.focus,
+.dark.ui-form-buttons.focus {
+ background-position:left -80px;
+}
+.dark .ui-form-buttons.focus .ui-form-inner,
+.dark.ui-form-buttons.focus .ui-form-inner {
+ background-position:right -80px;
+}
+.dark .ui-form-buttons.focus .ui-form,
+.dark.ui-form-buttons.focus .ui-form {
+ color:#FFF;
+}
+.dark .ui-form-buttons.active,
+.dark.ui-form-buttons.active {
+ background-position:left -120px;
+}
+.dark .ui-form-buttons.active .ui-form-inner,
+.dark.ui-form-buttons.active .ui-form-inner {
+ background-position:right -120px;
+}
+.dark .ui-form-buttons.active .ui-form,
+.dark.ui-form-buttons.active .ui-form {
+ background-position:right -120px;
+}
+
+
+/*( checkbox )*/
+.dark .ui-form-checkbox {
+ background:url(dark.form.png) -221px 0;
+ padding:2px 0 1px 0;
+}
+.dark .ui-form-checkbox .ui-form-content {
+ padding:0 7px 1px 7px;
+ color:#222;
+ cursor:default;
+}
+.dark .ui-form-checkbox.hover,
+.dark .ui-form-checkbox.focus,
+.dark .ui-form-checkbox.active {
+ background-position: -221px -20px;
+}
+.dark .ui-form-checkbox.selected .ui-form-inner {
+ background:url(dark.form.png) -201px -2px;
+}
+
+
+/*( radio )*/
+.dark .ui-form-radio {
+ padding:2px 1px;
+ background:url(dark.form.png) -1px -1px;
+}
+.dark .ui-form-radio .ui-form-content {
+ padding:1px 6px 1px 7px;
+ *padding:0 6px 0 7px;
+ color:#222;
+ cursor:default;
+}
+.dark .ui-form-radio.hover,
+.dark .ui-form-radio.focus,
+.dark .ui-form-radio.active {
+ background-position: -1px -21px;
+}
+.dark .ui-form-radio.selected .ui-form-inner {
+ background:url(dark.form.png) -22px -3px;
+}
+.dark .ui-form-radio.selected .ui-form-content {
+ color:#CDD6E7;
+}
+
diff --git a/site/app/webroot/css/jquery-ui/dark/dark.form.png b/site/app/webroot/css/jquery-ui/dark/dark.form.png
new file mode 100644
index 0000000..ec28222
--- /dev/null
+++ b/site/app/webroot/css/jquery-ui/dark/dark.form.png
Binary files differ
diff --git a/site/app/webroot/css/jquery-ui/dark/dark.menu.css b/site/app/webroot/css/jquery-ui/dark/dark.menu.css
new file mode 100644
index 0000000..e31b7dd
--- /dev/null
+++ b/site/app/webroot/css/jquery-ui/dark/dark.menu.css
@@ -0,0 +1,9 @@
+.ui-menu-toolbar {background:#222; font:10pt Verdana;}
+.ui-menu-toolbar-button {border:1px solid #DDD; background:#000;}
+.ui-menu-toolbar-button:hover {border:1px solid #CCC; background:#333; }
+.ui-menu-toolbar-button a {color:#fff;}
+.ui-menu-items {background:#000; border:1px solid #CCC; opacity:0.95; font:10pt Verdana; min-width:80px; *width:80px;}
+.ui-menu-item a { color:#fff; }
+.ui-menu-item-parent { }
+.ui-menu-item-disabled {color: #aaa; background: transparent;}
+.ui-context-header {color: #fff;} \ No newline at end of file
diff --git a/site/app/webroot/css/jquery-ui/dark/dark.modal.css b/site/app/webroot/css/jquery-ui/dark/dark.modal.css
new file mode 100644
index 0000000..141fc58
--- /dev/null
+++ b/site/app/webroot/css/jquery-ui/dark/dark.modal.css
@@ -0,0 +1,93 @@
+.dark .ui-modal .top.pane,
+.dark.ui-modal .top.pane {
+ position: relative;
+ cursor:move;
+}
+
+.dark .ui-modal .top.pane .ui-modal-title-bar,
+.dark.ui-modal .top.pane .ui-modal-title-bar {
+ background:#333;
+ color:snow;
+ padding:2px 4px;
+ border-bottom:1px solid #333;
+ font-weight:bold;
+ font-size:1.1em;
+}
+
+.dark .ui-modal .top.pane .ui-modal-buttons-right,
+.dark.ui-modal .top.pane .ui-modal-buttons-right {
+ position: absolute;
+ right: 5px;
+}
+
+.dark .ui-modal .top.pane .ui-modal-button-close,
+.dark.ui-modal .top.pane .ui-modal-button-close {
+ font:10pt Verdana;
+ font-weight:bold;
+ color:snow;
+ cursor:pointer;
+}
+
+.dark .ui-modal .middle.pane,
+.dark.ui-modal .middle.pane {
+ position:relative;
+ height: 100%;
+ background:#222;
+ padding-top:4px;
+}
+.dark .ui-modal .middle.pane .center.pane,
+.dark.ui-modal .middle.pane .center.pane{
+ position:relative;
+ overflow: auto;
+ height: 100%;
+ margin:0 4px;
+ background:#111;
+ color:snow;
+}
+.dark .ui-modal.noOverflow .middle.pane .center.pane,
+.dark.ui-modal.noOverflow .middle.pane .center.pane{
+ overflow: visible;
+}
+
+.dark .ui-modal .middle.pane .left.pane,
+.dark.ui-modal .middle.pane .left.pane {
+ position: absolute;
+ top: 0px;
+ left: 0px;
+ border-left:1px solid #333;
+ height:100%;
+ width: 2px;
+}
+
+.dark .ui-modal .middle.pane .right.pane,
+.dark.ui-modal .middle.pane .right.pane {
+ position: absolute;
+ top: 0px;
+ right: 0px;
+ border-right:1px solid #333;
+ height:100%;
+ width: 2px;
+ cursor:e-resize;
+}
+
+.dark .ui-modal .bottom.pane,
+.dark.ui-modal .bottom.pane {
+ position: relative;
+ height:3px;
+ background:#222;
+ border:1px solid #333;
+ border-top:none;
+ cursor:s-resize;
+}
+
+
+.dark .ui-modal .bottom.pane .ui-modal-resize-se,
+.dark.ui-modal .bottom.pane .ui-modal-resize-se {
+ position: absolute;
+ bottom:-1px;
+ right:-1px;
+ height:4px;
+ width:4px;
+ cursor:se-resize;
+}
+
diff --git a/site/app/webroot/css/jquery-ui/dark/dark.tabs.css b/site/app/webroot/css/jquery-ui/dark/dark.tabs.css
new file mode 100644
index 0000000..85383b2
--- /dev/null
+++ b/site/app/webroot/css/jquery-ui/dark/dark.tabs.css
@@ -0,0 +1,73 @@
+@media projection, screen { .ui-tabs-hide { display:none; } }
+@media print { .ui-tabs-nav { display: none; } }
+
+.dark .ui-tabs-nav,
+.dark.ui-tabs-nav {
+ padding-left:6px;
+ border-bottom:1px solid #333;
+ float:left;
+ width:99%;
+ margin:0;
+}
+.dark .ui-tabs-nav li,
+.dark.ui-tabs-nav li {
+ list-style:none;
+ float:left;
+ }
+.dark .ui-tabs-nav a,
+.dark.ui-tabs-nav a {
+ display:block;
+ padding:2px 0 1px;
+ text-decoration:none!important;
+ border:1px solid #444;
+ margin:1px 1px 0 0;
+ font:9pt Verdana;
+ color:#FFF;
+ background:#444;
+}
+.dark .ui-tabs-nav span,
+.dark.ui-tabs-nav span {
+ padding:2px 13px 2px;
+ color:#FFF;
+ background:#333;
+}
+.dark .ui-tabs-nav a:hover,
+.dark .ui-tabs-nav a:hover span,
+.dark.ui-tabs-nav a:hover,
+.dark.ui-tabs-nav a:hover span {
+ border-color:#181818;
+ color:#FFF;
+ background:#111;
+ }
+.dark .ui-tabs-nav .ui-tabs-selected a,
+.dark.ui-tabs-nav .ui-tabs-selected a {
+ background:#222;
+ border-color:#333;
+}
+.dark .ui-tabs-nav .ui-tabs-selected a span,
+.dark.ui-tabs-nav .ui-tabs-selected a span {
+ margin-bottom:0;
+ color:#FFF;
+ background:#181818;
+ border-bottom:1px solid #181818;
+ cursor:default;
+ }
+.dark .ui-tabs-nav .ui-tabs-disabled a,
+.dark .ui-tabs-nav .ui-tabs-disabled a span,
+.dark.ui-tabs-nav .ui-tabs-disabled a,
+.dark.ui-tabs-nav .ui-tabs-disabled a span {
+ background:#161616;
+ color:#333;
+ border-color:#161616;
+ cursor:default;
+}
+.dark .ui-tabs-container {
+ background:#181818;
+ border-bottom:1px solid #222;
+ clear:both;
+ padding:10px 10px 8px 10px;
+ *padding-top:3px;
+ *margin-top:-24px;
+ clear:left;
+}
+
diff --git a/site/app/webroot/css/jquery-ui/dark/dark.tree.css b/site/app/webroot/css/jquery-ui/dark/dark.tree.css
new file mode 100644
index 0000000..a5c0f68
--- /dev/null
+++ b/site/app/webroot/css/jquery-ui/dark/dark.tree.css
@@ -0,0 +1,61 @@
+body.dark { font:11pt Calibri; background:#111; color:snow; }
+
+.dark .ui-tree-nodes * { outline:none; }
+.dark .ui-tree-nodes {
+ position:relative;
+ list-style: none;
+ margin:0;
+ padding:0;
+ margin-left:0;
+ padding-left:0.8em;
+}
+
+.dark .ui-tree-node {
+ margin:0;
+ padding:0;
+ cursor: default;
+}
+
+.dark .ui-tree-node-text {
+ text-decoration:none;
+ color:snow;
+ padding:0 .3em;
+}
+
+.dark .ui-tree-node-selected > .ui-tree-node-text {
+ background: #448;
+}
+
+.dark .ui-tree-node-button {
+ border: 1px solid #222;
+ padding-left:1px;
+ color: #666;
+ font:7pt Courier New,monospace;
+ margin-top: 0.5em;
+ position: absolute;
+ left: 0.2em;
+ width: 0.7em;
+ height: 0.8em;
+ line-height: 0.8em;
+ text-decoration: none;
+ display:none;
+}
+
+.dark .ui-tree-node-expanded > .ui-tree-node-button {
+ background: #181818;
+ display:block;
+}
+
+.dark .ui-tree-node-collapsed > .ui-tree-node-button {
+ background: #222;
+ display:block;
+}
+
+.dark .ui-tree-node-moving > .ui-tree-node-button {
+ background: #282828;
+}
+
+.dark .ui-tree-node-moving > .ui-tree-node-text {
+ background: #474; color:#FFF;
+}
+
diff --git a/site/app/webroot/css/jquery-ui/flora/flora.accordion.css b/site/app/webroot/css/jquery-ui/flora/flora.accordion.css
new file mode 100644
index 0000000..4bee951
--- /dev/null
+++ b/site/app/webroot/css/jquery-ui/flora/flora.accordion.css
@@ -0,0 +1,12 @@
+ul.ui-accordion-container { margin: 0; padding: 0; list-style-type: none; }
+ul.ui-accordion-container li { position: relative; margin: 0; margin-bottom: 2px; padding: 0; background-image: url(i/accordion-left.png); background-repeat: no-repeat; }
+ul.ui-accordion-container li a.ui-accordion-link { display: block; padding-left: 5px; margin-right: 3px; height: 28px; background-image: url(i/accordion-middle.png); color: #000; text-decoration: none; line-height: 28px; }
+ul.ui-accordion-container li div.ui-accordion-right { background-image: url(i/accordion-right.png); position: absolute; top: 0px; right: 0px; height: 28px; width: 3px; }
+
+ul.ui-accordion-container li:hover { background-image: url(i/accordion-left-over.png); }
+ul.ui-accordion-container li:hover a.ui-accordion-link { background-image: url(i/accordion-middle-over.png); }
+ul.ui-accordion-container li:hover div.ui-accordion-right { background-image: url(i/accordion-right-over.png); }
+
+ul.ui-accordion-container li.active { background-image: url(i/accordion-left-act.png); }
+ul.ui-accordion-container li.active a.ui-accordion-link { background-image: url(i/accordion-middle-act.png); }
+ul.ui-accordion-container li.active div.ui-accordion-right { background-image: url(i/accordion-right-act.png); } \ No newline at end of file
diff --git a/site/app/webroot/css/jquery-ui/flora/flora.all.css b/site/app/webroot/css/jquery-ui/flora/flora.all.css
new file mode 100644
index 0000000..fed27de
--- /dev/null
+++ b/site/app/webroot/css/jquery-ui/flora/flora.all.css
@@ -0,0 +1,9 @@
+@import "flora.css";
+@import "flora.shadow.css";
+@import "flora.resizable.css";
+@import "flora.slider.css";
+@import "flora.accordion.css";
+@import "flora.tabs.css";
+@import "flora.dialog.css";
+@import "flora.tablesorter.css";
+@import "flora.calendar.css";
diff --git a/site/app/webroot/css/jquery-ui/flora/flora.calendar.css b/site/app/webroot/css/jquery-ui/flora/flora.calendar.css
new file mode 100644
index 0000000..dedcf0c
--- /dev/null
+++ b/site/app/webroot/css/jquery-ui/flora/flora.calendar.css
@@ -0,0 +1,167 @@
+/* Main Style Sheet for jQuery Calendar */
+#calendar_div, .calendar_inline {
+ font-family: Arial, Helvetica, sans-serif;
+ font-size: 14px;
+ padding: 0;
+ margin: 0;
+ background: #ddd;
+}
+#calendar_div {
+ display: none;
+ border: 1px solid #FF9900;
+ z-index: 10; /*must have*/
+}
+#calendar_div, .calendar_control, .calendar_links, .calendar_header, .calendar {
+ width: 185px;
+}
+.calendar_inline {
+ float: left;
+ display: block;
+ border: 0;
+}
+.calendar_dialog {
+ padding: 5px !important;
+ border: 4px ridge #ddd !important;
+}
+button.calendar_trigger {
+ width: 25px;
+}
+img.calendar_trigger {
+ margin: 2px;
+ vertical-align: middle;
+}
+.calendar_prompt {
+ float: left;
+ width: 181px;
+ padding: 2px;
+ background: #ddd;
+ color: #000;
+}
+* html .calendar_prompt {
+ width: 185px;
+}
+.calendar_control, .calendar_links, .calendar_header, .calendar {
+ clear: both;
+ float: left;
+ color: #fff;
+}
+.calendar_control {
+ background: #FF9900;
+}
+.calendar_links {
+ background: #E0F4D7;
+}
+.calendar_control, .calendar_links {
+ font-weight: bold;
+ font-size: 80%;
+ letter-spacing: 1px;
+}
+.calendar_links label { /* disabled links */
+ padding: 2px 5px;
+ color: #888;
+}
+.calendar_clear, .calendar_prev {
+ float: left;
+}
+.calendar_current {
+ float: left;
+ width: 35%;
+ text-align: center;
+}
+.calendar_close, .calendar_next {
+ float: right;
+}
+.calendar_header {
+ background: #83C948;
+ text-align: center;
+ font-weight: bold;
+}
+.calendar_header select {
+ background: #83C948;
+ color: #000;
+ border: 0px;
+ font-weight: bold;
+}
+.calendar {
+ background: #ccc;
+ text-align: center;
+ font-size: 100%;
+}
+.calendar a {
+ display: block;
+ width: 100%;
+}
+.calendar .calendar_titleRow {
+ background: #B1DB87;
+ color: #000 !important;
+}
+.calendar .calendar_daysRow {
+ background: #FFF;
+ color: #666;
+}
+.calendar .calendar_daysCell {
+ color: #000;
+ border: 1px solid #ddd;
+}
+#calendar .calendar_daysCell a{
+ display: block;
+}
+.calendar .calendar_weekEndCell {
+ background: #E0F4D7;
+}
+.calendar .calendar_daysCellOver {
+ background: #fff;
+ border: 1px solid #777;
+}
+.calendar .calendar_unselectable {
+ color: #888;
+}
+.calendar_today {
+ background: #ccc !important;
+}
+.calendar_currentDay {
+ background: #999 !important;
+}
+
+/* ________ CALENDAR LINKS _______
+
+** Reset link properties and then override them with !important */
+#calendar_div a, .calendar_inline a {
+ cursor: pointer;
+ margin: 0;
+ padding: 0;
+ background: none;
+ color: #000;
+}
+.calendar_inline .calendar_links a {
+ padding: 0 5px !important;
+}
+.calendar_control a, .calendar_links a {
+ padding: 2px 5px !important;
+ color: #000 !important;
+}
+.calendar_titleRow a {
+ color: #000 !important;
+}
+.calendar_control a:hover {
+ /*background: #fdd !important;*/
+ color: #333 !important;
+}
+.calendar_links a:hover, .calendar_titleRow a:hover {
+ background: #FFF !important;
+ color: #333 !important;
+}
+
+/* ___________ IE6 IFRAME FIX ________ */
+
+.calendar_cover {
+ display: none; /*sorry for IE5*/
+ display/**/: block; /*sorry for IE5*/
+ position: absolute; /*must have*/
+ z-index: -1; /*must have*/
+ filter: mask(); /*must have*/
+ top: -4px; /*must have*/
+ left: -4px; /*must have*/
+ width: 193px; /*must have to match width and borders*/
+ height: 200px; /*must have to match maximum height*/
+}
diff --git a/site/app/webroot/css/jquery-ui/flora/flora.css b/site/app/webroot/css/jquery-ui/flora/flora.css
new file mode 100644
index 0000000..c301680
--- /dev/null
+++ b/site/app/webroot/css/jquery-ui/flora/flora.css
@@ -0,0 +1,2 @@
+.ui-wrapper { border: 1px solid #50A029; }
+.ui-wrapper input, .ui-wrapper textarea { border: 0; }
diff --git a/site/app/webroot/css/jquery-ui/flora/flora.dialog.css b/site/app/webroot/css/jquery-ui/flora/flora.dialog.css
new file mode 100644
index 0000000..43dcec6
--- /dev/null
+++ b/site/app/webroot/css/jquery-ui/flora/flora.dialog.css
@@ -0,0 +1,86 @@
+/* This file skins dialog */
+
+.flora .ui-dialog,
+.flora.ui-dialog {
+ background-color: #e6f7d4;
+}
+
+.flora .ui-dialog .ui-dialog-titlebar,
+.flora.ui-dialog .ui-dialog-titlebar {
+ border-bottom: 1px solid #d8d2aa;
+ background: #ff9900 url(i/dialog-title.gif) repeat-x;
+ padding: 0px;
+ cursor: move;
+ height: 28px;
+ _height: 29px;
+}
+
+.flora .ui-dialog .ui-dialog-titlebar-close,
+.flora.ui-dialog .ui-dialog-titlebar-close {
+ width: 16px;
+ height: 16px;
+ background: url(i/dialog-titlebar-close.png) no-repeat;
+ position:absolute;
+ top: 6px;
+ right: 7px;
+ cursor: default;
+}
+
+.flora .ui-dialog .ui-dialog-titlebar-close-hover,
+.flora.ui-dialog .ui-dialog-titlebar-close-hover {
+ background: url(i/dialog-titlebar-close-hover.png) no-repeat;
+}
+
+.flora .ui-dialog .ui-dialog-title,
+.flora.ui-dialog .ui-dialog-title {
+ margin-left: 5px;
+ color: white;
+ font-weight: bold;
+ position: relative;
+ top: 7px;
+ left: 4px;
+}
+
+.flora .ui-dialog .ui-dialog-content,
+.flora.ui-dialog .ui-dialog-content {
+ margin: 1.2em;
+}
+
+.flora .ui-dialog .ui-dialog-buttonpane,
+.flora.ui-dialog .ui-dialog-buttonpane {
+ position: absolute;
+ bottom: 8px;
+ right: 12px;
+ width: 100%;
+ text-align: right;
+}
+
+.flora .ui-dialog .ui-dialog-buttonpane button,
+.flora.ui-dialog .ui-dialog-buttonpane button {
+ margin: 6px;
+}
+
+/* Dialog handle styles */
+.flora .ui-dialog .ui-resizable-n,
+.flora.ui-dialog .ui-resizable-n { cursor: n-resize; height: 6px; width: 100%; top: 0px; left: 0px; background: transparent url(i/dialog-n.gif) repeat scroll center top; }
+
+.flora .ui-dialog .ui-resizable-s,
+.flora.ui-dialog .ui-resizable-s { cursor: s-resize; height: 8px; width: 100%; bottom: 0px; left: 0px; background: transparent url(i/dialog-s.gif) repeat scroll center top; }
+
+.flora .ui-dialog .ui-resizable-e,
+.flora.ui-dialog .ui-resizable-e { cursor: e-resize; width: 7px; right: 0px; top: 0px; height: 100%; background: transparent url(i/dialog-e.gif) repeat scroll right center; }
+
+.flora .ui-dialog .ui-resizable-w,
+.flora.ui-dialog .ui-resizable-w { cursor: w-resize; width: 7px; left: 0px; top: 0px; height: 100%; background: transparent url(i/dialog-w.gif) repeat scroll right center; }
+
+.flora .ui-dialog .ui-resizable-se,
+.flora.ui-dialog .ui-resizable-se { cursor: se-resize; width: 9px; height: 9px; right: 0px; bottom: 0px; background: transparent url(i/dialog-se.gif); }
+
+.flora .ui-dialog .ui-resizable-sw,
+.flora.ui-dialog .ui-resizable-sw { cursor: sw-resize; width: 9px; height: 9px; left: 0px; bottom: 0px; background: transparent url(i/dialog-sw.gif); }
+
+.flora .ui-dialog .ui-resizable-nw,
+.flora.ui-dialog .ui-resizable-nw { cursor: nw-resize; width: 9px; height: 29px; left: 0px; top: 0px; background: transparent url(i/dialog-nw.gif); }
+
+.flora .ui-dialog .ui-resizable-ne,
+.flora.ui-dialog .ui-resizable-ne { cursor: ne-resize; width: 9px; height: 29px; right: 0px; top: 0px; background: transparent url(i/dialog-ne.gif); }
diff --git a/site/app/webroot/css/jquery-ui/flora/flora.menu.css b/site/app/webroot/css/jquery-ui/flora/flora.menu.css
new file mode 100644
index 0000000..6d2dd21
--- /dev/null
+++ b/site/app/webroot/css/jquery-ui/flora/flora.menu.css
@@ -0,0 +1,8 @@
+.ui-menu-toolbar {z-index:500; list-style:none;}
+.ui-menu-toolbar-button {float:left; padding:4px 20px; cursor:pointer;}
+.ui-menu-toolbar-button:hover {}
+.ui-menu-toolbar-button a {text-decoration:none;}
+.ui-menu-items {display:none; padding:0; z-index:500; list-style:none; padding:1px 4px; min-width:80px; *width:80px;}
+.ui-menu-item a { text-decoration:none;}
+.ui-menu-item-parent { background: url('i/menu-submenu.gif') no-repeat center right; }
+.ui-menu-item-disabled {} \ No newline at end of file
diff --git a/site/app/webroot/css/jquery-ui/flora/flora.resizable.css b/site/app/webroot/css/jquery-ui/flora/flora.resizable.css
new file mode 100644
index 0000000..5e30c0c
--- /dev/null
+++ b/site/app/webroot/css/jquery-ui/flora/flora.resizable.css
@@ -0,0 +1,20 @@
+/* This file skins resizables */
+
+.ui-resizable { position: relative; }
+
+/* Global handle styles */
+.ui-resizable-handle { position: absolute; display: none; font-size: 0.1px; }
+.ui-resizable .ui-resizable-handle { display: block; }
+body .ui-resizable-disabled .ui-resizable-handle { display: none; } /* use 'body' to make it more specific (css order) */
+body .ui-resizable-autohide .ui-resizable-handle { display: none; } /* use 'body' to make it more specific (css order) */
+
+.ui-resizable-n { cursor: n-resize; height: 6px; width: 100%; top: 0px; left: 0px; background: transparent url(i/resizable-n.gif) repeat scroll center top; }
+.ui-resizable-s { cursor: s-resize; height: 6px; width: 100%; bottom: 0px; left: 0px; background: transparent url(i/resizable-s.gif) repeat scroll center top; }
+
+.ui-resizable-e { cursor: e-resize; width: 6px; right: 0px; top: 0px; height: 100%; background: transparent url(i/resizable-e.gif) repeat scroll right center; }
+.ui-resizable-w { cursor: w-resize; width: 6px; left: 0px; top: 0px; height: 100%; background: transparent url(i/resizable-w.gif) repeat scroll right center; }
+
+.ui-resizable-se { cursor: se-resize; width: 9px; height: 9px; right: 0px; bottom: 0px; background: transparent url(i/resizable-se.gif); }
+.ui-resizable-sw { cursor: sw-resize; width: 9px; height: 9px; left: 0px; bottom: 0px; background: transparent url(i/resizable-sw.gif); }
+.ui-resizable-nw { cursor: nw-resize; width: 9px; height: 9px; left: 0px; top: 0px; background: transparent url(i/resizable-nw.gif); }
+.ui-resizable-ne { cursor: ne-resize; width: 9px; height: 9px; right: 0px; top: 0px; background: transparent url(i/resizable-ne.gif); } \ No newline at end of file
diff --git a/site/app/webroot/css/jquery-ui/flora/flora.shadow.css b/site/app/webroot/css/jquery-ui/flora/flora.shadow.css
new file mode 100644
index 0000000..6c08d44
--- /dev/null
+++ b/site/app/webroot/css/jquery-ui/flora/flora.shadow.css
@@ -0,0 +1,33 @@
+/*
+.ui-shadow {
+background:transparent url(i/shadow.png) no-repeat scroll right bottom;
+height: 100px;
+margin: 10px;
+position: relative;
+}
+
+.ui-shadow-ne {
+background:transparent url(i/shadow.png) no-repeat scroll right top;
+width: 6px;
+height: 6px;
+position: absolute;
+top: -6px;
+right: 0px;
+}
+
+.ui-shadow-sw {
+background:transparent url(i/shadow.png) no-repeat scroll left bottom;
+width: 6px;
+height: 6px;
+position: absolute;
+bottom: 0px;
+left: -6px;
+}
+*/
+
+
+
+
+.ui-shadow { position:relative; }
+.ui-shadow-color { background:#030; position:absolute; } /* Can be overidden via js */
+
diff --git a/site/app/webroot/css/jquery-ui/flora/flora.slider.css b/site/app/webroot/css/jquery-ui/flora/flora.slider.css
new file mode 100644
index 0000000..b04ace9
--- /dev/null
+++ b/site/app/webroot/css/jquery-ui/flora/flora.slider.css
@@ -0,0 +1,8 @@
+/* This file skins sliders */
+
+.ui-slider-handle { position: absolute; height: 23px; width: 12px; top: 0px; left: 0px; background-image: url(i/slider-handle.gif); }
+.ui-slider-disabled .ui-slider-handle { opacity: 0.5; filter: alpha(opacity=50); }
+
+/* Default slider backgrounds */
+.ui-slider-1 { width: 200px; height: 23px; position: relative; background-image: url(i/slider-bg-1.png); background-repeat: no-repeat; background-position: center center; }
+.ui-slider-2 { width: 200px; height: 23px; position: relative; background-image: url(i/slider-bg-2.png); background-repeat: no-repeat; background-position: center center; } \ No newline at end of file
diff --git a/site/app/webroot/css/jquery-ui/flora/flora.tablesorter.css b/site/app/webroot/css/jquery-ui/flora/flora.tablesorter.css
new file mode 100644
index 0000000..7d805a7
--- /dev/null
+++ b/site/app/webroot/css/jquery-ui/flora/flora.tablesorter.css
@@ -0,0 +1,40 @@
+/* This file skins tableSorter */
+
+table.tablesorter {
+ font-family:arial;
+ background-color: #CDCDCD;
+ margin:10px 0pt 15px;
+ font-size: 8pt;
+ width: 100%;
+ text-align: left;
+}
+table.tablesorter thead tr th, table.tablesorter tfoot tr th {
+ background-color: #B1DB87;
+ border: 1px solid #FFF;
+ font-size: 8pt;
+ padding: 4px;
+}
+table.tablesorter thead tr .header {
+ background-image: url(i/bg.gif);
+ background-repeat: no-repeat;
+ background-position: center right;
+ cursor: pointer;
+}
+table.tablesorter tbody td {
+ color: #3D3D3D;
+ padding: 4px;
+ background-color: #FFF;
+ vertical-align: top;
+}
+table.tablesorter tbody tr.odd td {
+ background-color:#E0F4D7;
+}
+table.tablesorter thead tr .headerSortUp {
+ background-image: url(i/asc.gif);
+}
+table.tablesorter thead tr .headerSortDown {
+ background-image: url(i/desc.gif);
+}
+table.tablesorter thead tr .headerSortDown, table.tablesorter thead tr .headerSortUp {
+background-color: #83C948;
+}
diff --git a/site/app/webroot/css/jquery-ui/flora/flora.tabs.css b/site/app/webroot/css/jquery-ui/flora/flora.tabs.css
new file mode 100644
index 0000000..19c5994
--- /dev/null
+++ b/site/app/webroot/css/jquery-ui/flora/flora.tabs.css
@@ -0,0 +1,111 @@
+@import "flora.css";
+
+/* Caution! Ensure accessibility in print and other media types... */
+@media projection, screen { /* Use class for showing/hiding tab content, so that visibility can be better controlled in different media types... */
+ .ui-tabs-hide {
+ display: none !important;
+ }
+}
+
+/* Hide useless elements in print layouts... */
+@media print {
+ .ui-tabs-nav {
+ display: none;
+ }
+}
+
+/* Skin */
+.ui-tabs-nav, .ui-tabs-panel {
+ font-family: "Trebuchet MS", Trebuchet, Verdana, Helvetica, Arial, sans-serif;
+ font-size: 12px;
+}
+.ui-tabs-nav {
+ list-style: none;
+ margin: 0;
+ padding: 0 0 0 3px;
+}
+.html-rtl .ui-tabs-nav {
+ padding: 0 3px 0 0;
+}
+.ui-tabs-nav:after { /* clearing without presentational markup, IE gets extra treatment */
+ display: block;
+ clear: both;
+ content: " ";
+}
+.ui-tabs-nav li {
+ float: left;
+ margin: 0 0 0 2px;
+ font-weight: bold;
+}
+.html-rtl .ui-tabs-nav li {
+ float: right;
+ margin: 0 2px 0 0;
+}
+.ui-tabs-nav a, .ui-tabs-nav a span {
+ float: left; /* fixes dir=ltr problem and other quirks IE */
+ padding: 0 12px;
+ background: url(i/tabs.png) no-repeat;
+}
+.ui-tabs-nav a {
+ margin: 5px 0 0; /* position: relative makes opacity fail for disabled tab in IE */
+ padding-left: 0;
+ background-position: 100% 0;
+ text-decoration: none;
+ white-space: nowrap; /* @ IE 6 */
+ outline: 0; /* @ Firefox, prevent dotted border after click */
+}
+.ui-tabs-nav a:link, .ui-tabs-nav a:visited {
+ color: #fff;
+}
+.ui-tabs-nav .ui-tabs-selected a {
+ position: relative;
+ top: 1px;
+ z-index: 2;
+ margin-top: 0;
+ background-position: 100% -23px;
+}
+.ui-tabs-nav a span {
+ padding-top: 1px;
+ padding-right: 0;
+ height: 20px;
+ background-position: 0 0;
+ line-height: 20px;
+}
+.ui-tabs-nav .ui-tabs-selected a span {
+ padding-top: 0;
+ height: 27px;
+ background-position: 0 -23px;
+ line-height: 27px;
+}
+.ui-tabs-nav .ui-tabs-selected a:link, .ui-tabs-nav .ui-tabs-selected a:visited,
+.ui-tabs-nav .ui-tabs-disabled a:link, .ui-tabs-nav .ui-tabs-disabled a:visited { /* @ Opera, use pseudo classes otherwise it confuses cursor... */
+ cursor: text;
+}
+.ui-tabs-nav a:hover, .ui-tabs-nav a:focus, .ui-tabs-nav a:active,
+.ui-tabs-nav .ui-tabs-unselect a:hover, .ui-tabs-nav .ui-tabs-unselect a:focus, .ui-tabs-nav .ui-tabs-unselect a:active { /* @ Opera, we need to be explicit again here now... */
+ cursor: pointer;
+}
+.ui-tabs-disabled {
+ opacity: .4;
+ filter: alpha(opacity=40);
+}
+.ui-tabs-nav .ui-tabs-disabled a:link, .ui-tabs-nav .ui-tabs-disabled a:visited {
+ color: #000;
+}
+.ui-tabs-panel {
+ border: 1px solid #519e2d;
+ padding: 10px;
+ background: #fff; /* declare background color for container to avoid distorted fonts in IE while fading */
+}
+/*.ui-tabs-loading em {
+ padding: 0 0 0 20px;
+ background: url(loading.gif) no-repeat 0 50%;
+}*/
+
+/* Additional IE specific bug fixes... */
+* html .ui-tabs-nav { /* auto clear @ IE 6 & IE 7 Quirks Mode */
+ display: inline-block;
+}
+*:first-child+html .ui-tabs-nav { /* auto clear @ IE 7 Standards Mode - do not group selectors, otherwise IE 6 will ignore complete rule (because of the unknown + combinator)... */
+ display: inline-block;
+}
diff --git a/site/app/webroot/css/jquery-ui/flora/i/accordion-left-act.png b/site/app/webroot/css/jquery-ui/flora/i/accordion-left-act.png
new file mode 100644
index 0000000..bf6ee99
--- /dev/null
+++ b/site/app/webroot/css/jquery-ui/flora/i/accordion-left-act.png
Binary files differ
diff --git a/site/app/webroot/css/jquery-ui/flora/i/accordion-left-over.png b/site/app/webroot/css/jquery-ui/flora/i/accordion-left-over.png
new file mode 100644
index 0000000..66378e0
--- /dev/null
+++ b/site/app/webroot/css/jquery-ui/flora/i/accordion-left-over.png
Binary files differ
diff --git a/site/app/webroot/css/jquery-ui/flora/i/accordion-left.png b/site/app/webroot/css/jquery-ui/flora/i/accordion-left.png
new file mode 100644
index 0000000..13344fc
--- /dev/null
+++ b/site/app/webroot/css/jquery-ui/flora/i/accordion-left.png
Binary files differ
diff --git a/site/app/webroot/css/jquery-ui/flora/i/accordion-middle-act.png b/site/app/webroot/css/jquery-ui/flora/i/accordion-middle-act.png
new file mode 100644
index 0000000..cecf4f1
--- /dev/null
+++ b/site/app/webroot/css/jquery-ui/flora/i/accordion-middle-act.png
Binary files differ
diff --git a/site/app/webroot/css/jquery-ui/flora/i/accordion-middle-over.png b/site/app/webroot/css/jquery-ui/flora/i/accordion-middle-over.png
new file mode 100644
index 0000000..251ad11
--- /dev/null
+++ b/site/app/webroot/css/jquery-ui/flora/i/accordion-middle-over.png
Binary files differ
diff --git a/site/app/webroot/css/jquery-ui/flora/i/accordion-middle.png b/site/app/webroot/css/jquery-ui/flora/i/accordion-middle.png
new file mode 100644
index 0000000..5238fd4
--- /dev/null
+++ b/site/app/webroot/css/jquery-ui/flora/i/accordion-middle.png
Binary files differ
diff --git a/site/app/webroot/css/jquery-ui/flora/i/accordion-right-act.png b/site/app/webroot/css/jquery-ui/flora/i/accordion-right-act.png
new file mode 100644
index 0000000..1fa4792
--- /dev/null
+++ b/site/app/webroot/css/jquery-ui/flora/i/accordion-right-act.png
Binary files differ
diff --git a/site/app/webroot/css/jquery-ui/flora/i/accordion-right-over.png b/site/app/webroot/css/jquery-ui/flora/i/accordion-right-over.png
new file mode 100644
index 0000000..d676dad
--- /dev/null
+++ b/site/app/webroot/css/jquery-ui/flora/i/accordion-right-over.png
Binary files differ
diff --git a/site/app/webroot/css/jquery-ui/flora/i/accordion-right.png b/site/app/webroot/css/jquery-ui/flora/i/accordion-right.png
new file mode 100644
index 0000000..543991a
--- /dev/null
+++ b/site/app/webroot/css/jquery-ui/flora/i/accordion-right.png
Binary files differ
diff --git a/site/app/webroot/css/jquery-ui/flora/i/asc.gif b/site/app/webroot/css/jquery-ui/flora/i/asc.gif
new file mode 100644
index 0000000..7415786
--- /dev/null
+++ b/site/app/webroot/css/jquery-ui/flora/i/asc.gif
Binary files differ
diff --git a/site/app/webroot/css/jquery-ui/flora/i/bg.gif b/site/app/webroot/css/jquery-ui/flora/i/bg.gif
new file mode 100644
index 0000000..fac668f
--- /dev/null
+++ b/site/app/webroot/css/jquery-ui/flora/i/bg.gif
Binary files differ
diff --git a/site/app/webroot/css/jquery-ui/flora/i/desc.gif b/site/app/webroot/css/jquery-ui/flora/i/desc.gif
new file mode 100644
index 0000000..3b30b3c
--- /dev/null
+++ b/site/app/webroot/css/jquery-ui/flora/i/desc.gif
Binary files differ
diff --git a/site/app/webroot/css/jquery-ui/flora/i/dialog-e.gif b/site/app/webroot/css/jquery-ui/flora/i/dialog-e.gif
new file mode 100644
index 0000000..3b8b521
--- /dev/null
+++ b/site/app/webroot/css/jquery-ui/flora/i/dialog-e.gif
Binary files differ
diff --git a/site/app/webroot/css/jquery-ui/flora/i/dialog-n.gif b/site/app/webroot/css/jquery-ui/flora/i/dialog-n.gif
new file mode 100644
index 0000000..c00727d
--- /dev/null
+++ b/site/app/webroot/css/jquery-ui/flora/i/dialog-n.gif
Binary files differ
diff --git a/site/app/webroot/css/jquery-ui/flora/i/dialog-ne.gif b/site/app/webroot/css/jquery-ui/flora/i/dialog-ne.gif
new file mode 100644
index 0000000..ab9c38e
--- /dev/null
+++ b/site/app/webroot/css/jquery-ui/flora/i/dialog-ne.gif
Binary files differ
diff --git a/site/app/webroot/css/jquery-ui/flora/i/dialog-nw.gif b/site/app/webroot/css/jquery-ui/flora/i/dialog-nw.gif
new file mode 100644
index 0000000..e934073
--- /dev/null
+++ b/site/app/webroot/css/jquery-ui/flora/i/dialog-nw.gif
Binary files differ
diff --git a/site/app/webroot/css/jquery-ui/flora/i/dialog-s.gif b/site/app/webroot/css/jquery-ui/flora/i/dialog-s.gif
new file mode 100644
index 0000000..d5f6b99
--- /dev/null
+++ b/site/app/webroot/css/jquery-ui/flora/i/dialog-s.gif
Binary files differ
diff --git a/site/app/webroot/css/jquery-ui/flora/i/dialog-se.gif b/site/app/webroot/css/jquery-ui/flora/i/dialog-se.gif
new file mode 100644
index 0000000..186a864
--- /dev/null
+++ b/site/app/webroot/css/jquery-ui/flora/i/dialog-se.gif
Binary files differ
diff --git a/site/app/webroot/css/jquery-ui/flora/i/dialog-sw.gif b/site/app/webroot/css/jquery-ui/flora/i/dialog-sw.gif
new file mode 100644
index 0000000..025dfda
--- /dev/null
+++ b/site/app/webroot/css/jquery-ui/flora/i/dialog-sw.gif
Binary files differ
diff --git a/site/app/webroot/css/jquery-ui/flora/i/dialog-title.gif b/site/app/webroot/css/jquery-ui/flora/i/dialog-title.gif
new file mode 100644
index 0000000..156c59b
--- /dev/null
+++ b/site/app/webroot/css/jquery-ui/flora/i/dialog-title.gif
Binary files differ
diff --git a/site/app/webroot/css/jquery-ui/flora/i/dialog-titlebar-close-hover.png b/site/app/webroot/css/jquery-ui/flora/i/dialog-titlebar-close-hover.png
new file mode 100644
index 0000000..67c1303
--- /dev/null
+++ b/site/app/webroot/css/jquery-ui/flora/i/dialog-titlebar-close-hover.png
Binary files differ
diff --git a/site/app/webroot/css/jquery-ui/flora/i/dialog-titlebar-close.png b/site/app/webroot/css/jquery-ui/flora/i/dialog-titlebar-close.png
new file mode 100644
index 0000000..cec974c
--- /dev/null
+++ b/site/app/webroot/css/jquery-ui/flora/i/dialog-titlebar-close.png
Binary files differ
diff --git a/site/app/webroot/css/jquery-ui/flora/i/dialog-w.gif b/site/app/webroot/css/jquery-ui/flora/i/dialog-w.gif
new file mode 100644
index 0000000..931ff4a
--- /dev/null
+++ b/site/app/webroot/css/jquery-ui/flora/i/dialog-w.gif
Binary files differ
diff --git a/site/app/webroot/css/jquery-ui/flora/i/menu-submenu.gif b/site/app/webroot/css/jquery-ui/flora/i/menu-submenu.gif
new file mode 100644
index 0000000..77647d8
--- /dev/null
+++ b/site/app/webroot/css/jquery-ui/flora/i/menu-submenu.gif
Binary files differ
diff --git a/site/app/webroot/css/jquery-ui/flora/i/resizable-e.gif b/site/app/webroot/css/jquery-ui/flora/i/resizable-e.gif
new file mode 100644
index 0000000..7acf248
--- /dev/null
+++ b/site/app/webroot/css/jquery-ui/flora/i/resizable-e.gif
Binary files differ
diff --git a/site/app/webroot/css/jquery-ui/flora/i/resizable-n.gif b/site/app/webroot/css/jquery-ui/flora/i/resizable-n.gif
new file mode 100644
index 0000000..59110f6
--- /dev/null
+++ b/site/app/webroot/css/jquery-ui/flora/i/resizable-n.gif
Binary files differ
diff --git a/site/app/webroot/css/jquery-ui/flora/i/resizable-ne.gif b/site/app/webroot/css/jquery-ui/flora/i/resizable-ne.gif
new file mode 100644
index 0000000..515a3f8
--- /dev/null
+++ b/site/app/webroot/css/jquery-ui/flora/i/resizable-ne.gif
Binary files differ
diff --git a/site/app/webroot/css/jquery-ui/flora/i/resizable-nw.gif b/site/app/webroot/css/jquery-ui/flora/i/resizable-nw.gif
new file mode 100644
index 0000000..665f318
--- /dev/null
+++ b/site/app/webroot/css/jquery-ui/flora/i/resizable-nw.gif
Binary files differ
diff --git a/site/app/webroot/css/jquery-ui/flora/i/resizable-s.gif b/site/app/webroot/css/jquery-ui/flora/i/resizable-s.gif
new file mode 100644
index 0000000..da2fb35
--- /dev/null
+++ b/site/app/webroot/css/jquery-ui/flora/i/resizable-s.gif
Binary files differ
diff --git a/site/app/webroot/css/jquery-ui/flora/i/resizable-se.gif b/site/app/webroot/css/jquery-ui/flora/i/resizable-se.gif
new file mode 100644
index 0000000..6c258ef
--- /dev/null
+++ b/site/app/webroot/css/jquery-ui/flora/i/resizable-se.gif
Binary files differ
diff --git a/site/app/webroot/css/jquery-ui/flora/i/resizable-sw.gif b/site/app/webroot/css/jquery-ui/flora/i/resizable-sw.gif
new file mode 100644
index 0000000..2fd8de4
--- /dev/null
+++ b/site/app/webroot/css/jquery-ui/flora/i/resizable-sw.gif
Binary files differ
diff --git a/site/app/webroot/css/jquery-ui/flora/i/resizable-w.gif b/site/app/webroot/css/jquery-ui/flora/i/resizable-w.gif
new file mode 100644
index 0000000..34b875b
--- /dev/null
+++ b/site/app/webroot/css/jquery-ui/flora/i/resizable-w.gif
Binary files differ
diff --git a/site/app/webroot/css/jquery-ui/flora/i/shadow.png b/site/app/webroot/css/jquery-ui/flora/i/shadow.png
new file mode 100644
index 0000000..4c58c7f
--- /dev/null
+++ b/site/app/webroot/css/jquery-ui/flora/i/shadow.png
Binary files differ
diff --git a/site/app/webroot/css/jquery-ui/flora/i/slider-bg-1.png b/site/app/webroot/css/jquery-ui/flora/i/slider-bg-1.png
new file mode 100644
index 0000000..b7d806e
--- /dev/null
+++ b/site/app/webroot/css/jquery-ui/flora/i/slider-bg-1.png
Binary files differ
diff --git a/site/app/webroot/css/jquery-ui/flora/i/slider-bg-2.png b/site/app/webroot/css/jquery-ui/flora/i/slider-bg-2.png
new file mode 100644
index 0000000..8b24cf0
--- /dev/null
+++ b/site/app/webroot/css/jquery-ui/flora/i/slider-bg-2.png
Binary files differ
diff --git a/site/app/webroot/css/jquery-ui/flora/i/slider-handle.gif b/site/app/webroot/css/jquery-ui/flora/i/slider-handle.gif
new file mode 100644
index 0000000..9b89f26
--- /dev/null
+++ b/site/app/webroot/css/jquery-ui/flora/i/slider-handle.gif
Binary files differ
diff --git a/site/app/webroot/css/jquery-ui/flora/i/tabs.gif b/site/app/webroot/css/jquery-ui/flora/i/tabs.gif
new file mode 100644
index 0000000..d964894
--- /dev/null
+++ b/site/app/webroot/css/jquery-ui/flora/i/tabs.gif
Binary files differ
diff --git a/site/app/webroot/css/jquery-ui/flora/i/tabs.png b/site/app/webroot/css/jquery-ui/flora/i/tabs.png
new file mode 100644
index 0000000..8018e41
--- /dev/null
+++ b/site/app/webroot/css/jquery-ui/flora/i/tabs.png
Binary files differ
diff --git a/site/app/webroot/css/jquery-ui/light/light.css b/site/app/webroot/css/jquery-ui/light/light.css
new file mode 100644
index 0000000..14482cb
--- /dev/null
+++ b/site/app/webroot/css/jquery-ui/light/light.css
@@ -0,0 +1,11 @@
+.light { background:#FFF; color:#111; font:10pt Verdana, Arial, sans-serif; }
+.light a, a.light { color:#46C; outline:none; }
+.light a:visited, a.light:visited { color:#C44; }
+.light a:hover, a.light:hover { color:#000; }
+.light fieldset { border:1px solid #CCC; }
+.light legend { color:#555; font:.8em Verdana, san-serif; }
+.light button, button.light, .light input, input.light { padding:2px 4px; font:.9em Consolas, Verdana, san-serif; }
+.light textarea, textarea.light { padding:2px 4px; font:.9em Consolas, Courier New, san-serif; width:20em; height:5em; overflow:auto; }
+.light select, select.light { padding:3px 0 3px 4px; font:.9em Verdana, san-serif; }
+.light label { font-weight:bold; }
+
diff --git a/site/app/webroot/css/jquery-ui/light/light.form.css b/site/app/webroot/css/jquery-ui/light/light.form.css
new file mode 100644
index 0000000..da10142
--- /dev/null
+++ b/site/app/webroot/css/jquery-ui/light/light.form.css
@@ -0,0 +1,45 @@
+.light .ui-form-textarea,
+.light.ui-form-textarea,
+.light .ui-form-fieldset,
+.light.ui-form-fieldset {
+ display:block;
+ border:1px solid #CCC;
+ padding:0;
+}
+.light .ui-form-fieldset,
+.light.ui-form-fieldset {
+ margin-top:1.6em;
+}
+.light textarea.ui-form,
+.light fieldset.ui-form {
+ margin:0;
+ border:1px solid #FFF;
+}
+.light textarea.ui-form { background:#F3F3F3; }
+.light fieldset.ui-form { background:#F6F6F6; }
+.light .ui-form-textarea.focus,
+.light.ui-form-textarea.focus {
+ border:1px solid #AAA;
+}
+.light textarea.ui-form:focus {
+ background:#F5F5F5;
+}
+.light .ui-form-legend,
+.light.ui-form-legend {
+ display:block;
+ text-align:left;
+ border:1px solid #CCC;
+ background:#F4F4F4;
+ margin:-1.05em 0 0 0;
+}
+.light legend.ui-form {
+ display:block;
+ font-weight:bold;
+ background:#F4F4F4;
+ border-top:1px dotted #EEE;
+ border-bottom:1px dotted #EEE;
+ margin:-1px 2px;
+ padding:0 2px 2px;
+}
+
+
diff --git a/site/app/webroot/css/jquery-ui/light/light.menu.css b/site/app/webroot/css/jquery-ui/light/light.menu.css
new file mode 100644
index 0000000..dab7af0
--- /dev/null
+++ b/site/app/webroot/css/jquery-ui/light/light.menu.css
@@ -0,0 +1,8 @@
+.ui-menu-toolbar {background:#222; font:10pt Verdana;}
+.ui-menu-toolbar-button {border:1px solid #DDD; background:#FFF;}
+.ui-menu-toolbar-button:hover {border:1px solid #CCC; background:#EEE; }
+.ui-menu-toolbar-button a {color:#000;}
+.ui-menu-items {background:#FFF; border:1px solid #CCC; opacity:0.95; font:10pt Verdana; min-width:80px; *width:80px;}
+.ui-menu-item a { color:#000; }
+.ui-menu-item-parent { }
+.ui-menu-item-disabled {color: #aaa; background: transparent;} \ No newline at end of file
diff --git a/site/app/webroot/css/jquery-ui/light/light.modal.css b/site/app/webroot/css/jquery-ui/light/light.modal.css
new file mode 100644
index 0000000..246b800
--- /dev/null
+++ b/site/app/webroot/css/jquery-ui/light/light.modal.css
@@ -0,0 +1,91 @@
+.light .ui-modal .top.pane,
+.light.ui-modal .top.pane {
+ position: relative;
+ cursor:move;
+}
+
+.light .ui-modal .top.pane .ui-modal-title-bar,
+.light.ui-modal .top.pane .ui-modal-title-bar {
+ background:#333;
+ color:snow;
+ padding:2px 4px;
+ border-bottom:1px solid #000;
+ font-weight:bold;
+}
+
+.light .ui-modal .top.pane .ui-modal-buttons-right,
+.light.ui-modal .top.pane .ui-modal-buttons-right {
+ position: absolute;
+ right: 5px;
+}
+
+.light .ui-modal .top.pane .ui-modal-button-close,
+.light.ui-modal .top.pane .ui-modal-button-close {
+ font:10pt Verdana;
+ font-weight:bold;
+ color:snow;
+ cursor:pointer;
+}
+
+.light .ui-modal .middle.pane,
+.light.ui-modal .middle.pane {
+ position:relative;
+ height: 100%;
+ background:#F3F3F3;
+ padding-top:4px;
+}
+.light .ui-modal .middle.pane .center.pane,
+.light.ui-modal .middle.pane .center.pane{
+ position:relative;
+ overflow: auto;
+ height: 100%;
+ margin:0 4px;
+ background:#FFF;
+}
+.light .ui-modal.noOverflow .middle.pane .center.pane,
+.light.ui-modal.noOverflow .middle.pane .center.pane{
+ overflow: visible;
+}
+
+.light .ui-modal .middle.pane .left.pane,
+.light.ui-modal .middle.pane .left.pane {
+ position: absolute;
+ top: 0px;
+ left: 0px;
+ border-left:1px solid #DDD;
+ height:100%;
+ width: 2px;
+}
+
+.light .ui-modal .middle.pane .right.pane,
+.light.ui-modal .middle.pane .right.pane {
+ position: absolute;
+ top: 0px;
+ right: 0px;
+ border-right:1px solid #DDD;
+ height:100%;
+ width: 2px;
+ cursor:e-resize;
+}
+
+.light .ui-modal .bottom.pane,
+.light.ui-modal .bottom.pane {
+ position: relative;
+ height:3px;
+ background:#F3F3F3;
+ border:1px solid #DDD;
+ border-top:none;
+ cursor:s-resize;
+}
+
+
+.light .ui-modal .bottom.pane .ui-modal-resize-se,
+.light.ui-modal .bottom.pane .ui-modal-resize-se {
+ position: absolute;
+ bottom:-1px;
+ right:-1px;
+ height:4px;
+ width:4px;
+ cursor:se-resize;
+}
+
diff --git a/site/app/webroot/css/jquery-ui/light/light.tabs.css b/site/app/webroot/css/jquery-ui/light/light.tabs.css
new file mode 100644
index 0000000..8d55b22
--- /dev/null
+++ b/site/app/webroot/css/jquery-ui/light/light.tabs.css
@@ -0,0 +1,71 @@
+@media projection, screen { .ui-tabs-hide { display:none; } }
+@media print { .ui-tabs-nav { display: none; } }
+
+.light .ui-tabs-nav,
+.light.ui-tabs-nav {
+ padding-left:6px;
+ border-bottom:1px solid #444;
+ float:left;
+ width:99%;
+ margin:0;
+}
+.light .ui-tabs-nav li,
+.light.ui-tabs-nav li {
+ list-style:none;
+ float:left;
+}
+.light .ui-tabs-nav a,
+.light.ui-tabs-nav a {
+ display:block;
+ padding:2px 0 1px;
+ text-decoration:none!important;
+ border:1px solid #444;
+ margin:1px 1px 0 0;
+ font:9pt Verdana;
+ color:#FFF;
+ background:#444;
+}
+.light .ui-tabs-nav span,
+.light.ui-tabs-nav span {
+ padding:2px 13px 2px;
+ color:#FFF;
+ background:#444;
+}
+.light .ui-tabs-nav a:hover,
+.light .ui-tabs-nav a:hover span,
+.light.ui-tabs-nav a:hover,
+.light.ui-tabs-nav a:hover span {
+ border-color:#222;
+ color:#FFF;
+ background:#222;
+ }
+.light .ui-tabs-nav .ui-tabs-selected a,
+.light.ui-tabs-nav .ui-tabs-selected a {
+ background:#AAA;
+ border-color:#666;
+}
+.light .ui-tabs-nav .ui-tabs-selected a span,
+.light.ui-tabs-nav .ui-tabs-selected a span {
+ margin-bottom:0;
+ color:#000;
+ background:snow;
+ border-bottom:1px solid #FFF;
+ cursor:default;
+ }
+.light .ui-tabs-nav .ui-tabs-disabled a,
+.light .ui-tabs-nav .ui-tabs-disabled a span,
+.light.ui-tabs-nav .ui-tabs-disabled a,
+.light.ui-tabs-nav .ui-tabs-disabled a span {
+ background:#EEE;
+ color:#BBB;
+ border-color:#DDD;
+ cursor:default;
+}
+.light .ui-tabs-container {
+ clear:both;
+ padding:10px 10px 8px 10px;
+ *padding-top:3px;
+ *margin-top:-24px;
+ clear:left;
+}
+
diff --git a/site/app/webroot/css/jquery-ui/light/light.tree.css b/site/app/webroot/css/jquery-ui/light/light.tree.css
new file mode 100644
index 0000000..c8fd0a9
--- /dev/null
+++ b/site/app/webroot/css/jquery-ui/light/light.tree.css
@@ -0,0 +1,61 @@
+body.light { font:10pt Verdana; background:#FFF; color:#111; }
+
+.light .ui-tree-nodes * { outline:none; }
+.light .ui-tree-nodes {
+ position:relative;
+ list-style: none;
+ margin:0;
+ padding:0;
+ margin-left:0;
+ padding-left:0.8em;
+}
+
+.light .ui-tree-node {
+ margin:0;
+ padding:0;
+ cursor: default;
+}
+
+.light .ui-tree-node-text {
+ text-decoration:none;
+ color:#222;
+ padding:0 .3em;
+}
+
+.light .ui-tree-node-selected > .ui-tree-node-text {
+ background: #EEE;
+}
+
+.light .ui-tree-node-button {
+ border: 1px solid #CCC;
+ padding-left:1px;
+ color: #666;
+ font:7pt Courier New,monospace;
+ margin-top: 0.4em;
+ position: absolute;
+ left: 0.2em;
+ width: 0.7em;
+ height: 0.8em;
+ line-height: 0.8em;
+ text-decoration: none;
+ display:none;
+}
+
+.light .ui-tree-node-expanded > .ui-tree-node-button {
+ background: #EEE;
+ display:block;
+}
+
+.light .ui-tree-node-collapsed > .ui-tree-node-button {
+ background: #DDD;
+ display:block;
+}
+
+.light .ui-tree-node-moving > .ui-tree-node-button {
+ background: #DDD;
+}
+
+.light .ui-tree-node-moving > .ui-tree-node-text {
+ background: #DDD;
+}
+
diff --git a/site/app/webroot/css/localizers.css b/site/app/webroot/css/localizers.css
new file mode 100644
index 0000000..ee81a39
--- /dev/null
+++ b/site/app/webroot/css/localizers.css
@@ -0,0 +1,66 @@
+/* Global */
+div.error {
+ background: #ffa5a5;
+ border: 1px solid red;
+ text-align: center;
+ font-weight: bold;
+ padding: 5px;
+ margin: 5px 0 5px 0;
+}
+
+/* summary */
+table.stats {
+ float: none;
+ width: 100%;
+}
+table.log {
+ float: none;
+}
+
+table.stats td.title {
+ width: 13em;
+ font-weight: bold;
+}
+table.stats td.value {
+ width: 7em;
+}
+
+/* pages */
+table.stats th {
+ text-align: left;
+}
+table.stats td.translated {
+ color: green;
+}
+table.stats td.notTranslated {
+ color: red;
+}
+
+/* other */
+table.translatedSection {
+ width: 100%;
+}
+table.translatedSection th {
+ border-bottom: 1px solid gray;
+}
+table.translatedSection td {
+ padding: 5px;
+ font-size: 80%;
+ vertical-align: top;
+}
+table.translatedSection td.field {
+ font-weight: bold;
+}
+table.translatedSection td.enus {
+ border-left: 1px solid gray;
+}
+table.translatedSection td.localized {
+ border-left: 1px solid gray;
+}
+table.translatedSection input {
+ width: 100%;
+}
+table.translatedSection textarea {
+ width: 100%;
+ height: 8em;
+}
diff --git a/site/app/webroot/css/print.css b/site/app/webroot/css/print.css
new file mode 100644
index 0000000..a355142
--- /dev/null
+++ b/site/app/webroot/css/print.css
@@ -0,0 +1,52 @@
+/*----------------------------------------------------------------------------
+Print CSS file for Addons.mozilla.org
+Created by Craig Cook - focalcurve.com
+ on December 28, 2007
+-----------------------------------------------------------------------------*/
+
+/* =Hidden elements */
+#nav-access, h1, #nav-user, #search-form, #other-apps { display: none; }
+#sidebar, #footer-lang-form, .pitch, .extra .view-all { display: none; }
+.install-button, .exp-loggedout, .learn-more, .more-from { display: none; }
+#form-review, .pagination, #form-listcontrol { display: none; }
+
+/* =Body */
+body { font: 12pt/1.5 "Helvetica Neue", Helvetica, Arial, sans-serif; padding: 0 .25in; background-color: #fff; color: #000; }
+h2, h3, h4, h5, h6 { font-family: Georgia, "Times New Roman", Times, serif; margin-bottom: .25em; }
+h2 { font-size: 15pt; }
+h3 { font-size: 14pt; }
+h4, h5, h6 { font-size: 100%; }
+a img { border: none; }
+
+#page-title { height: 120px; }
+#page-title h2 { position: relative; padding-left: 125px; }
+#page-title h2 img { position: absolute; top: 0; left: 0; }
+#page-title p.page-intro { color: #666; padding-left: 125px; font-size: 90%; }
+
+.addon { border: 1px solid #ccc; padding: .5em 1em .5em 240px; margin-bottom: 1em; position: relative; }
+.addon .preview-img { position: absolute; top: .5em; left: 1em; }
+.author { margin-top: 0; }
+.name a, .author a { text-decoration: none; }
+.name a:after, .author a:after, .extra a:after, #nav-legal a:after { content: " [" attr(href) "] "; font-size: 90%; }
+.addon .flag { position: absolute; top: -1px; right: -1px; margin: 0; padding: .2em 1em; border: 3px double #000; }
+.rec .flag { color: #360; }
+.exp .flag { color: #900; }
+
+#content-main { padding-right: 35%; position: relative; }
+#content-extra { width: 30%; position: absolute; right: 0; top: 0; }
+
+#content.search #content-main, #content.category #content-main { padding-right: 0; }
+
+.extra ul { margin-left: 0; }
+
+#footer { color: #666; font-size: 90%; margin-top: 1em; border-top: 3px double #ccc; }
+
+.addon-images { list-style: none; margin: 0 0 1em; padding: 0; }
+.addon-images li { display: inline; margin-right: 10px; }
+.addon-images a img { vertical-align: top; margin-bottom: 10px; }
+
+.addon-reviews { list-style: none; margin: 0 0 1em; padding: 0; }
+.addon-reviews li { border: 1px solid #ccc; padding: .5em 1em; margin-bottom: 1em; }
+.addon-reviews blockquote { margin: 0; }
+
+#addon-listing { list-style: none; margin: 0; padding: 0; }
diff --git a/site/app/webroot/css/remora.css b/site/app/webroot/css/remora.css
new file mode 100644
index 0000000..3c098e5
--- /dev/null
+++ b/site/app/webroot/css/remora.css
@@ -0,0 +1,177 @@
+/* remora-specific changes to focalcurve CSS */
+
+/* Listing items */
+#addon-listing .rating { display: inline; vertical-align: middle; }
+#addon-listing .addon-cats { display: inline; }
+
+/* Search page */
+#content.search p.addon-search-message { margin-top:2em; color: #777777; font-size: 180%; font-weight: bold; text-align:center; }
+
+/* Sidebar item indentation */
+#sidebar ul li.indented, .sidebar-right ul li.indented { text-indent: 10px; }
+
+/* Sidebar items without links need love too */
+#cat-list span { display: block; padding: .5em 10px; }
+
+/* Sidebar item selection */
+#cat-list li.selected { background-color: #99CC66; }
+#cat-list li.selected a { background: #99CC66; }
+
+/* Add-on Summary */
+#addon-summary .stats { position: absolute; left: 20px; top: 19em; margin: 1em 0; text-align: center; }
+#addon-summary .privacypolicy { clear: both; padding-top: .5em; }
+
+/* Details Page */
+#addon-info h4.version-link { margin: 2em 0; }
+
+#addon-info h4.version-link a.view { background: transparent url("../img/sprite.png?20090430") 100% -387px no-repeat; }
+.html-ltr #addon-info h4.version-link a.view:hover { background-position: 100% -437px; }
+.html-rtl #addon-info h4.version-link a.view { background-position: 100% -597px; }
+.html-rtl #addon-info h4.version-link a.view:hover { background-position: 100% -647px; }
+#addon-info h4.version-link a.view { padding-right: 30px; padding-bottom: 2px; text-decoration: none; }
+
+/* Install Box Outer */
+.sub div.install-container { padding: 0; margin: 0; }
+.sub div.secondary-container { background: transparent url("../img/sprite.png?20090430") left -1256px no-repeat; }
+
+/* Footer */
+ul#nav-legal { margin:0; }
+
+/* Make h1 and h2 in content-main actually useful */
+#content-main h1, #content-main h2, #content h1, #content h2 { color: #2D3B58; font-size: 140%; font-weight: bold; margin: 5px 0; }
+#content-main h2, #content h2 { font-size: 120%; }
+
+/* error page */
+.error-notice { margin: 0 auto; padding: 10px 80px 20px 80px; background: url(../img/warning.png) 20px 20px no-repeat; min-height: 48px; }
+
+/* right sidebar */
+.sidebar-content h3 { margin: 0 -1px; padding-left: 6px; font-size: 120%; background: #79be1b url("../img/sprite.png?20090430") -217px -106px no-repeat; border-bottom: 1px solid #abe071; }
+.sidebar-content h3 span { display: block; padding: 8px 4px; color: #426a13; background: transparent url("../img/sprite.png?20090430") -342px -106px no-repeat; }
+.sidebar-content { margin-bottom: 1em; position: relative; z-index: 5; padding-bottom: 6px; background-color: #f6f6f6; border: 1px solid #d8dcdf; border-width: 0 1px 1px; }
+.sidebar-content { -moz-border-radius-bottomright: 6px; -moz-border-radius-bottomleft: 6px; -webkit-border-bottom-right-radius: 6px; -webkit-border-bottom-left-radius: 6px; border-bottom-right-radius: 6px; border-bottom-left-radius: 6px; }
+.sidebar-list { margin-left: 0; list-style: none; border-top: 1px solid #e8e6e6; }
+.sidebar-list li { padding-right: 1px; border-bottom: 3px double #e8e6e6; }
+.sidebar-list a { display: block; padding: .5em 10px; background: #f4f2f2 url("../img/cat-link.png") top repeat-x; }
+.sidebar-content a:link { color: #4e4e4e; text-decoration: none; }
+.sidebar-content a:visited { color: #777; text-decoration: none; }
+.sidebar-content a:hover, .sidebar-content a:active, .sidebar-content a:focus { color: #1d587f; background: #f1f0f0 url("../img/cat-linkhover.png") top repeat-x; }
+.sidebar-right { float: right; width: 18%; }
+
+/* rss */
+.rss-link { padding-left: 16px; background: url(../img/tinyRss.png) no-repeat left; }
+.rss-container img { float: left; }
+
+/* addon policy pages */
+#addon-summary.addon-policy { padding-left: 0; }
+div#content-policy { margin: 0 0 2em 44px; }
+.policy-area { margin-bottom: 2em ;}
+#policy-tl { position: absolute; left: -1px; top: 0; padding: 18px 0 0 20px; background: transparent url("../img/sprite.png?20090430") left -1256px no-repeat; height: 10px; width: 10px; }
+
+/* options bar on listing pages */
+#form-listcontrol #options-submit { position: absolute; top:15px; right:-30px; }
+
+/* Search box */
+#search-form #search-submit { position: absolute; top: 25px; right:-30px; }
+
+/* corner box */
+html[dir='rtl'] .corner-box {
+ background: url(../img/rustico/right-top-corner-box.jpg) top right no-repeat;
+ margin: 0 0 10px 0;
+ padding: 12px 12px 12px 15px;
+}
+
+html[dir='ltr'] .corner-box {
+ background: url(../img/rustico/left-top-corner-box.jpg) top left no-repeat;
+ margin: 0 0 10px 0;
+ padding: 12px 0 12px 15px;
+}
+
+.corner-box h2, h3 {
+ margin-top: 0;
+}
+
+/* reviews pages */
+.corner-box.review-reply { margin-left: 2em; }
+form.flag { display: inline; }
+
+#addon-listing .addon-cats {
+ display: block;
+ margin: .2em 0 .5em 0;
+}
+
+.naked {
+ list-style-type: none;
+ margin-left: .5em;
+}
+
+.clear {
+ clear: both;
+}
+
+/* anti-CSRF hidden session code */
+div.hsession { display: none; }
+
+/* Edit user profile tabs */
+#tabbed-editor ul,
+#tabbed-editor li {
+ margin: 0;
+}
+#profile-notifications ul {
+ margin: 0 0 1.5em 2em;
+}
+#tabbed-editor .ui-tabs-nav,
+#tabbed-editor .ui-tabs-panel {
+ font-family: inherit;
+ font-size: inherit;
+}
+#tabbed-editor .line {
+ margin: 10px 0;
+}
+#tabbed-editor .tabs-nav {
+ display: none;
+}
+#tabbed-editor .ui-tabs-nav {
+ display: block;
+}
+
+
+/* FAQ styling */
+
+dl.faq dt {
+ margin: 1em 0 0 0;
+}
+
+dl.faq dd {
+ margin-top: 0.5em;
+}
+
+dl.faq dt:target {
+ color: #df731b;
+}
+
+
+/* Developer Agreement */
+#dev-agreement ul {
+ list-style-type: disc;
+}
+
+/* Version License */
+#version-license {
+ background-color: #EEE;
+ border: 1px solid #AAA;
+ max-width: 600px;
+ max-height: 400px;
+ overflow: auto;
+}
+
+/* Get Satisfaction */
+div#gsfn_list_widget img { border: none; }
+div#gsfn_list_widget { float:right; font-size: 12px; width: 250px; border: 6px solid #DDD; padding: 5px 5px 25px 20px; margin: 5px 5px 10px 10px;}
+div#gsfn_list_widget a.widget_title { color: #000; display: block; margin-bottom: 10px; font-weight: bold; }
+div#gsfn_list_widget .powered_by { margin-top: 8px; padding-top: 8px; border-top: 1px solid #DDD; }
+div#gsfn_list_widget .powered_by a { color: #333; font-size: 90%; }
+div#gsfn_list_widget div#gsfn_content { }
+div#gsfn_list_widget div#gsfn_content li { text-align:left; margin-bottom:6px; }
+div#gsfn_list_widget div#gsfn_content a.gsfn_link { line-height: 1; }
+div#gsfn_list_widget div#gsfn_content span.time { font-size: 90%; padding-left: 3px; }
+div#gsfn_list_widget div#gsfn_content p.gsfn_summary { margin-top: 2px }
diff --git a/site/app/webroot/css/rustico.content.css b/site/app/webroot/css/rustico.content.css
new file mode 100644
index 0000000..2382e8d
--- /dev/null
+++ b/site/app/webroot/css/rustico.content.css
@@ -0,0 +1,558 @@
+/* mozilla.org Rustico Theme Content Styles
+ * Design by silverorange
+ * Markup Reference classes organized by fantasai
+ */
+
+/* Suggested order:
+ * display
+ * list-style
+ * position
+ * float
+ * clear
+ * width
+ * height
+ * margin
+ * padding
+ * border
+ * background
+ * color
+ * font
+ * text-decoration
+ * text-align
+ * vertical-align
+ * white-space
+ * other text
+ * content
+ *
+ */
+
+/* TOC:
+ Body
+ Random HTML Styles
+ Forms
+ General Structure
+ Navigation
+ Quotations
+ Comments and Other Asides
+ Emphasis
+ Computers - General
+ Code
+ Examples and Figures
+ Q and A (FAQ)
+ Tables
+ Meta
+*/
+
+/* Random HTML Styles */
+
+ hr {
+ height: 1px;
+ background-color: #000;
+ color: #000;
+ margin: 2em 0;
+ }
+
+ .hide { display: none; }
+
+ ul.spaced li, ol.spaced li {
+ margin-bottom: 0.5em;
+ }
+
+/* General Structure */
+ body, td, th, input { /* redundant rules for bad browsers */
+ font-family: verdana, sans-serif;
+ font-size: x-small;
+ voice-family: "\"}\"";
+ voice-family: inherit;
+ font-size: small;
+ }
+
+ h1, h2, h3, h4, h5, h6 {
+ margin: 1em 0 0.2em 0;
+ font-family: arial, verdana, sans-serif;
+ }
+ li h1, li h2, li h3, li h4, li h5, li h6 {
+ border: none;
+ }
+
+ #header h1 { border: 0; }
+
+ h1 { font-size: 160%; font-weight: normal; }
+ h2 { font-size: 150%; font-weight: normal; }
+ h3 { font-size: 120%; }
+ h4 { font-size: 100%; }
+ h5 { font-size: 90%; }
+ h6 { font-size: 90%; border: 0; }
+
+/* Navigation */
+
+ :link { color: #039; }
+ :visited { color: #636; }
+ :link:hover, :visited:hover { color: #333; }
+ :link:active, :link:active { color: #000; }
+
+/* Quotations */
+
+
+/* Comments and other Asides */
+ #main-feature {
+ margin-top: -24px;
+ background: #EFF3F7 url("/images/template/feature-back.png") bottom repeat-x;
+ }
+
+ #main-feature h2 {
+ margin: 10px 0 0 0;
+ border: none;
+ }
+
+ #main-feature p.product-intro {
+ margin: 0 0 10px 0;
+ line-height: 145%;
+ color: #414D66;
+ }
+
+ #main-feature .feature-contents {
+ padding: 15px 50px 65px 50px;
+ position: relative; /* this is required to absolutely position contained elements */
+ background: url("/images/home/feature-sun.png") bottom right no-repeat;
+ }
+
+ #main-feature .feature-contents { height: 250px; }
+ body>#main-feature .feature-contents { height: auto; min-height: 260px; }
+
+ #main-feature .brief-feature { height: auto !important; min-height: 10px !important; }
+ * html #main-feature .brief-feature { padding-bottom: 5px !important }
+
+ /* this hack is required for IE6 */
+ /* Hides from IE-mac \*/
+ * html #main-feature { height: 1%;}
+ /* End hide from IE-mac */
+
+ #main-feature a.download-link {
+ display: block;
+ padding: 0 0 12px 0;
+ margin-bottom: 0.2em;
+ text-decoration: none;
+ color: #256504;
+ width: 285px;
+ margin-left: -8px;
+ }
+
+ #main-feature a.download-firefox {
+ background: url("/images/template/download-firefox.png") 0 100% no-repeat;
+ }
+
+ #main-feature a.download-thunderbird {
+ background: url("/images/template/download-thunderbird.png") 0 100% no-repeat;
+ }
+
+ #main-feature .brief-feature a.download-firefox {
+ background: url("/images/template/download-firefox-white.png") 0 100% no-repeat;
+ margin-right: 40px;
+ margin-left: 0;
+ }
+
+ #main-feature a.download-link span {
+ display: block;
+ padding: 9px 10px 0 58px;
+ min-height: 43px;
+ } * html #main-feature a.download-link span { height: 43px; }
+
+ #main-feature a.download-firefox span {
+ background: url("/images/template/download-firefox.png") 0 0 no-repeat;
+ }
+
+ #main-feature a.download-thunderbird span {
+ background: url("/images/template/download-thunderbird.png") 0 0 no-repeat;
+ }
+
+ #main-feature .brief-feature a.download-firefox span {
+ background: url("/images/template/download-firefox-white.png") 0 0 no-repeat;
+ }
+
+
+ #main-feature a.download-link strong {
+ font: 140% sans-serif;
+ letter-spacing: -0.02em;
+ text-decoration: underline;
+ color: #256504;
+ }
+
+ #main-feature a.download-link em {
+ font-style: normal;
+ color: #367D10;
+ letter-spacing: 0;
+ display: block;
+ padding-top: 3px;
+ font-size: 85%;
+ }
+
+ #main-feature a.download-link:hover, #main-feature a.download-link:hover span, #main-feature a.download-link:hover strong {
+ color: #143802;
+ cursor: pointer; /* need for IE6 */
+ background-position: 100% 100%;
+ }
+
+ #main-feature a.download-link:hover span {
+ background-position: 100% 0;
+ }
+
+ #main-feature .download-info {
+ font-size: 85%;
+ color: #666;
+ padding: 0;
+ }
+
+ #main-feature .download-other {
+ font-size: 85%;
+ color: #515F78;
+ padding-left: 8px;
+ }
+
+ .brief-feature .home-download {
+ float: right;
+ }
+
+ #main-feature .product-image {
+ float: right;
+ margin-left: 1.5em;
+ margin-top: 1em;
+ }
+
+ #main-feature h2, #main-feature h3, #main-feature h4 {
+ border: none;
+ }
+
+ .note {
+ color: #666;
+ font-style: normal;
+ }
+
+ .first {
+ margin-top: 0;
+ }
+
+ .remark {
+ color: #666;
+ }
+
+ .sidenote {
+ border: #666;
+ }
+
+ .key-point:before {
+ line-height: 0.1;
+ font-size: 1px;
+ background: transparent url("/images/box/key-point_tr.gif") no-repeat top right;
+ margin: -15px -15px 0 -15px;
+ height: 15px;
+ display: block;
+ border: none;
+ content: url("/images/box/key-point_tl.gif");
+ }
+ .key-point {
+ background: #e4ecec url("/images/box/key-point_back.gif") right repeat-y;
+ padding: 15px;
+ margin-bottom: 1em;
+ } * html .key-point { height: 1px; }
+ .key-point:after {
+ display: block;
+ clear: both;
+ padding-top: 15px;
+ line-height: 0.1;
+ font-size: 1px;
+ content: url("/images/box/key-point_bl.gif");
+ margin: -15px;
+ height: 8px;
+ background: transparent url("/images/box/key-point_br.gif") scroll no-repeat bottom right ;
+ }
+
+ .key-point h2, .key-point h3, .key-point h4, .key-point h5 {
+ border: none;
+ margin-top: 0;
+ color: #4C5C5C;
+ }
+
+ .news dt {
+ font-weight: normal;
+ color: #666;
+ }
+ .news dt a {
+ font-weight: bold;
+ }
+
+ ul.compact {
+ margin-left: 0;
+ padding-left: 20px;
+ }
+
+/* Emphasis */
+
+/* Computers - General */
+
+ kbd {
+ margin: 0.1em;
+ padding: 0.1em;
+ border: 1px #ccc;
+ }
+
+ kbd.command,
+ code.command {
+ color: #6B5839;
+ }
+
+/* Code */
+
+ pre.code {
+ background: #EEECF6;
+ }
+
+ code > em,
+ code > strong,
+ pre.code > em,
+ pre.code > strong {
+ font-style: normal;
+ }
+
+/* Examples and Figures */
+
+ div.example {
+ border-color: #554FA0;
+ }
+ div.example:before {
+ color: #666;
+ }
+
+/* Q and A (FAQ) */
+
+ol.faq li a {
+ text-decoration: none;
+ border-bottom: 1px dotted #6C98EE;
+}
+
+ol.faq li a:hover {
+ border-color: #039;
+}
+
+
+/* Tables */
+ table {
+ border-collapse: collapse;
+ border: none;
+ margin: 1em 0;
+ }
+
+ th {
+ background: #ddd;
+ padding: 5px;
+ text-align: left;
+ }
+
+ tr.table-title th {
+ font: 130% sans-serif;
+ font-weight: normal;
+ background: #666;
+ color: #fff;
+ border-top: 1px solid #666;
+ padding: 0.5em 10px;
+ text-align: center;
+ }
+
+ td {
+ font-size: 85%;
+ padding: 5px;
+ text-align: left;
+ }
+
+ table.data thead th {
+ background: #e4ecec;
+ empty-cells: hide;
+ }
+
+ table.data th,
+ table.data td {
+ border: 1px solid #ccc;
+ font-size: 100%;
+ line-height: 130%;
+ }
+
+ tr.odd {
+ background: #F5F5F5;
+ }
+
+/* Meta */
+
+ address {
+ color: #666;
+ }
+
+/* Product Specific CSS */
+
+ .productlist img.product-logo {
+ float: left;
+ margin: 0 10px 1em 0;
+ }
+
+ .productlist h3 {
+ border: none;
+ clear: left;
+ }
+
+ .productlist p {
+ margin: 0.2em 0 2em 0;
+ }
+
+ .key-point h1, .key-point h3 {
+ margin: 0;
+ }
+
+ #product-desc h2 {
+ text-indent: -700em;
+ height: 25px;
+ line-height: 2px;
+ font-size: 2px;
+ }
+
+ #product-desc p {
+ padding-left: 170px;
+ }
+
+ #product-desc ul, #key-desc {
+ padding-left: 190px;
+ margin-bottom: 0;
+ }
+
+ #product-side, #key-side {
+ margin-left: 65%;
+ }
+
+ #product-side ul, #key-side ul {
+ margin-left: 0;
+ padding-bottom: 0;
+ padding-left: 20px;
+ }
+
+ #product-side li, #key-side {
+ padding-bottom: 0.2em;
+ }
+
+ #product-desc, #key-desc {
+ padding: 40px 0 25px 0;
+ color: #4C5C5C;
+ width: 60%;
+ float: left;
+ line-height: 140%;
+ }
+
+ #key-desc {
+ padding: 0;
+ }
+
+ #key-side {
+ color: #4C5C5C;
+ }
+
+ .product-firefox {
+ background: url("../../images/product-firefox-screen.png") no-repeat;
+ }
+ .product-thunderbird {
+ background: url("../../images/product-thunderbird-screen.png") no-repeat;
+ }
+
+ #product-side .download h3 {
+ color: #1D9101;
+ font-weight: bold;
+ margin: 0;
+ font-size: 140%;
+ }
+
+ .download h3 :link,
+ .download h3 :visited,
+ .download h3 :link:active, .download h3 :visited:active {
+ color: #1D9101;
+ }
+
+ .download h3 :link:hover, .download h3 :visited:hover {
+ color: #156B01;
+ }
+
+ .download li {
+ padding: 0;
+ margin: 0;
+ }
+ .download ul {
+ margin-top: 0;
+ margin-bottom: 0;
+ padding-bottom: 0;
+ }
+ .other {
+ padding-top: 3px;
+ }
+ .other a:link, .other a:visited { color: #515F78; }
+ .other a:hover { color: #000; }
+
+ .configParent {
+ display: block;
+ font-size: 85%;
+ }
+
+
+/* Lists */
+
+dl {
+ margin-top: 0;
+}
+
+dt {
+ font-weight: bold;
+}
+
+dd {
+ margin: 0.2em 0 1em 1em;
+}
+
+/* Simple Logo Boxes */
+
+.firefox-logo, .thunderbird-logo {
+ padding-left: 72px;
+ min-height: 70px;
+ margin-bottom: 1em;
+ display: block; /* so this can be used for links */
+}
+
+* html .firefox-logo, * html .thunderbird-logo { height: 70px; } /* min-height for IE */
+
+.firefox-logo h2, .firefox-logo h3, .firefox-logo h4, .thunderbird-logo h2, .thunderbird-logo h3, .thunderbird-logo h4 {
+ border-bottom: none;
+}
+
+.firefox-logo {
+ background: url("/images/firefox-logo-64x64.png") no-repeat;
+}
+
+.thunderbird-logo {
+ background: url("/images/thunderbird-logo-64x64.png") no-repeat;
+}
+
+
+/* Firefox Page Styles */
+
+.product-thumb {
+ display: block;
+ margin: 15px 0;
+ padding-bottom: 75px;
+ text-decoration: none;
+}
+
+.product-thumb strong {
+ text-decoration: underline;
+}
+
+.thumb-firefox-tabs { background: url("/images/firefox-tabbedbrowsing-thumb.png") 0 1.8em no-repeat; }
+.thumb-firefox-live { background: url("/images/firefox-livebookmarks-thumb.png") 0 1.8em no-repeat; }
+.thumb-firefox-search { background: url("/images/firefox-searchbar-thumb.png") 0 1.8em no-repeat; }
+
+.firefox-awards {
+ margin-top: 1em;
+ text-align: center;
+}
diff --git a/site/app/webroot/css/rustico.css b/site/app/webroot/css/rustico.css
new file mode 100644
index 0000000..8e6d632
--- /dev/null
+++ b/site/app/webroot/css/rustico.css
@@ -0,0 +1,1165 @@
+/* General Structure */
+/* copied from Mozilla.com */
+
+body, td, th, input { /* redundant rules for bad browsers */
+ font-family: verdana, sans-serif;
+ font-size: x-small;
+ voice-family: "\"}\"";
+ voice-family: inherit;
+ font-size: small;
+}
+
+body {
+ background: #fff;
+ color: #333;
+ min-width: 610px;
+ margin: 0 0 1em 0;
+ padding: 0; /* need for Opera */
+}
+
+h1, h2, h3, h4, h5, h6 {
+ font-family: arial, verdana, sans-serif;
+ margin: 1em 0 0.2em 0;
+}
+
+li h1, li h2, li h3, li h4, li h5, li h6 {
+ border: none;
+}
+
+img {
+ border: 0;
+}
+
+#header h1 { border: 0; }
+
+h1 { font-size: 160%; font-weight: normal; }
+h2 { font-size: 150%; font-weight: normal; }
+h3 { font-size: 120%; }
+h4 { font-size: 100%; }
+h5 { font-size: 90%; }
+h6 { font-size: 90%; border: 0; }
+
+/* Navigation */
+
+:link { color: #039; }
+:visited { color: #636; }
+:link:hover, :visited:hover { color: #333; }
+:link:active, :link:active { color: #000; }
+
+/* header copied from Mozilla.com */
+
+#header {
+ background: #33415d url("../img/rustico/header/header-background.png") top repeat-x;
+ position: relative;
+ height: 38px;
+ padding: 0 50px;
+ border-bottom: 1px solid #a1a6b1;
+ z-index: 1;
+}
+
+#header div {
+ position: relative;
+ max-width: 900px;
+ margin: 0 auto;
+}
+
+#header h1 { margin: 0 720px 0 0; }
+
+#header h1 img {
+ font-weight: bold;
+ color: #7f7c45;
+}
+
+#header ul {
+ position: absolute;
+ top: 0;
+ right: 0;
+ list-style: none;
+ margin: 0;
+ padding: 0;
+ border-left: 1px solid #576178;
+ border-right: 1px solid #1f2635;
+} * html #header ul { right: 50px; }
+
+#header li {
+ float: left;
+ margin: 0;
+ padding: 0;
+}
+
+#header ul span, #header ul a:link, #header ul a:visited {
+ display: block;
+ float: left;
+ padding: 10px 15px;
+ text-decoration: none;
+ border-right: 1px solid #576178;
+ border-left: 1px solid #1f2635;
+ color: #dee0e5;
+ height: 36px;
+ voice-family: "\"}\"";
+ voice-family: inherit;
+ height: 16px;
+} #ignored {}
+
+#header ul li span,
+#header ul li a.current,
+#header ul li a:hover {
+ background: #475470;
+ color: #fff;
+ text-decoration: underline;
+}
+
+#header ul li span,
+#header ul li a.current {
+ text-decoration: none;
+}
+
+#site_notice {
+ border: 1px dashed salmon;
+ padding: 5px;
+ margin: 2px;
+}
+
+/* page title */
+
+#page-title {
+ background: url("../img/rustico/common/bg-header-thin.jpg") repeat-x 50% 0;
+}
+
+#page-title div, #container {
+ max-width: 900px;
+ margin: 0 auto;
+ padding: 25px 50px;
+}
+
+#container { padding-top: 0; }
+
+#page-title div {
+ background: url("../img/rustico/common/firefox-addons-hdr.jpg") no-repeat 70% 0;
+ height: 120px;
+} body>#page-title div { height: auto; min-height: 120px; }
+
+#page-title div h2 {
+ margin: 0;
+ padding-top: 0px;
+ border: 0;
+ font-size: 280%;
+ font-weight: bold;
+ color: #bd1d01;
+}
+
+#page-title.thunderbird div h2 {
+ color: #0a4e96;
+}
+
+#page-title div h2 img {
+ border: 0;
+ vertical-align: middle;
+}
+
+#page-title p {
+ font-weight: bold;
+ color: #3C475B;
+ margin: 0 0 10px 61px;
+ padding-left: 1em;
+ width: 50%;
+}
+
+/* Override right margin for rtl langs */
+#page-title div h2, #page-title div p{
+ margin-right:500px;
+}
+
+/* page title for sub-pages */
+
+#page-title.sub-page {
+ background: url("../img/rustico/common/bg-header-small.jpg") repeat-x 50% -5px;
+}
+
+#page-title.sub-page div {
+ background: none;
+ height: 40px;
+ padding-top: 10px;
+ padding-bottom: 10px;
+} body>#page-title.sub-page div { height: auto; min-height: 40px; }
+
+#page-title.sub-page div h2 {
+ font-size: 160%; }
+
+#page-title.sub-page div h2 span {
+ font-weight: normal;
+}
+
+#page-title.sub-page div h2, #page-title.sub-page div p{
+ margin-right:0px; /*rtl fix*/
+}
+
+
+/* content */
+/* content-right -- for use when content is on the right, with sidebar-left */
+
+#content-right,
+#content {
+ color: #3c475b;
+ line-height: 150%;
+ margin-left: 180px;
+}
+
+#content-right hr,
+#content hr {
+ margin: 2em;
+}
+
+#content-right h3,
+#content h3 {
+ font-weight: normal;
+}
+
+
+/* content-left */
+
+#content-left {
+ color: #3c475b;
+ line-height: 150%;
+ margin-right: 180px;
+}
+
+#content-left hr {
+ margin: 2em;
+}
+
+#content-left h3 {
+ font-weight: normal;
+}
+
+/* front page features */
+
+.frontpage-intro {
+ margin-top: 0;
+}
+
+#top-extensions,
+.front-recommended {
+ float: left;
+ width: 45%;
+ margin-right: 4%;
+}
+
+#home-intro h2 {
+ font-weight: bold;
+}
+
+#home-rec-link img {
+ border: none;
+ float: right;
+ text-decoration: none;
+ margin-left: 10px;
+}
+
+.front-recommended img {
+ float: right;
+ margin: 0 20px;
+}
+
+.newest-extensions h3,
+.top-extensions h3,
+.front-recommended h3 {
+ padding-top: 5px;
+}
+
+.frontpage-welcome {
+ margin: 0 0 1em 0;
+}
+
+/* browse features */
+
+.rss-subscribe {
+float:left;
+margin-top:2px;
+margin-right:5px;
+}
+.secondary-addon {
+ width: 45%;
+}
+.float-right {
+ float: right;
+}
+.float-left {
+ float: left;
+}
+/* addon features */
+
+.divider-bottom,
+.bookmarkaddon-feature {
+ background: url(../img/rustico/addons/firefox-featured-divider.png) no-repeat bottom center;
+ margin-bottom: 1.5em;
+ padding-bottom: 10px;
+}.divider-bottom,
+.bookmarkaddon-feature {
+ background: url(../img/rustico/addons/firefox-featured-divider.png) no-repeat bottom center;
+ margin-bottom: 1.5em;
+ padding-bottom: 10px;
+}
+
+#primary-feature {
+ margin-top: 2em;
+}
+
+.addon-feature h2 {
+ font-weight: bold;
+ margin: 0 0 5px 0;
+}
+
+.eula {
+ font-size: 75%;
+}
+
+.addon-feature h2 span {
+ font-weight: normal;
+ font-size: 80%;
+}
+
+.addon-feature h3,
+.bookmarkaddon-feature h3 {
+ margin: 0 0 10px 0;
+}
+
+.addon-feature h4,
+.bookmarkaddon-feature h4 {
+ margin: 0 0 10px 0;
+}
+
+.addon-feature h4 span,
+.bookmarkaddon-feature h4 span {
+ font-weight: normal;
+}
+
+.addon-feature h1 span {
+ font-size: small;
+}
+
+.addon-feature h1 span.author {
+ font-size: smaller;
+}
+
+.addon-feature .search-result-image {
+ float: right;
+ margin: 10px 0 5px 10px;
+}
+
+.addon-feature .addon-feature-image,
+.bookmarkaddon-feature .addon-feature-image {
+ float: right;
+ margin: 0 0 5px 5px;
+}
+
+.preview-image a {
+ text-decoration: none;
+ text-align: center;
+ display: block;
+ font-size: smaller;
+}
+.preview-image a.hide {
+ display: none;
+}
+
+
+.addon-display .preview-image {
+ float: right;
+}
+
+.addon-display .version-and-date {
+ font-size: smaller;
+}
+
+.addon-feature .addon-feature-text { }
+.bookmarkaddon-feature .addon-feature-text { margin-left: 190px; }
+
+.addon-feature a, .bookmarkaddon-feature a { color: #f7941d; }
+.addon-feature a:visited, .bookmarkaddon-feature a:visited { color: #f7941d; }
+.addon-feature a:hover, .bookmarkaddon-feature a:hover { color: #333; }
+
+.addon-feature .addon-feature-header { min-height: 55px; }
+.addon-feature .addon-feature-header .addon-feature-icon{ float: left; margin-right: 7px; }
+.addon-feature .addon-feature-header .addon-feature-name { margin: 0; padding: 4px 0; }
+.addon-feature .addon-feature-header .addon-feature-developer { margin: 0; padding: 0; }
+.addon-feature .addon-feature-tagline { margin: 0; padding: 0; font-style: italic;}
+
+.recommended a, .recommended a:visited { color: #f7941d; }
+.recommended a:hover { color: #333; }
+
+.bookmarkstitle {
+ background: url(../img/rustico/bookmarks/firefox-bm-puzzle-ico.png) no-repeat top left;
+ height: 27px;
+ padding: 5px 0 0 35px;
+}
+
+/* App compatibility info */
+.app_compat ul {
+ list-style: none;
+ margin: .5em 0;
+ padding: 0 0 0 1em;
+}
+.app_compat .appicon {
+ vertical-align: middle;
+ margin: 0 .5em 0 0;
+}
+
+/* App install info (for thunderbird) */
+.app_install {
+ background-color: #dfd;
+ border: 1px dashed #bdb;
+ margin: 1em;
+ padding: .5em;
+}
+
+/* install button */
+.install-button,
+p.install-button {
+ width: 230px;
+ margin: 0;
+}
+
+span.install-button-text {
+ padding-right: 30px;
+}
+
+.install-button a:link span.install-green-button,
+.install-button a:visited span.install-green-button,
+.install-button a:hover span.install-green-button,
+.install-button a:active span.install-green-button {
+ background: url(../img/rustico/install-button.png) no-repeat bottom left;
+ display: block;
+ min-height: 20px;
+ padding: 10px;
+}
+* html .install-button a:link span.install-green-button,
+* html .install-button a:visited span.install-green-button,
+* html .install-button a:hover span.install-green-button,
+* html .install-button a:active span.install-green-button { height: 20px; }
+
+.install-button a:link,
+.install-button a:visited,
+.install-button a:hover,
+.install-button a:active {
+ background: #a8ed2d url(../img/rustico/install-button.png) no-repeat top left;
+ display: block;
+ color: #005825;
+ text-decoration: none;
+}
+
+.install-button a:hover span.install-green-button,
+.install-button a:active span.install-green-button {
+ background: url(../img/rustico/install-button.png) no-repeat bottom right;
+}
+
+.install-button a:hover,
+.install-button a:active {
+ background: #89dc29 url(../img/rustico/install-button.png) no-repeat top right;
+ color: #000;
+ cursor: pointer;
+}
+
+/* corner box */
+
+.corner-box {
+ background: url(../img/rustico/left-top-corner-box.jpg) top left no-repeat;
+ margin: 0 0 10px 0;
+ padding: 12px 0 12px 15px;
+}
+
+.corner-box h2, h3 {
+ margin-top: 0;
+}
+
+/* search box */
+
+.search-container img {
+ float: left;
+}
+
+.search-container h3 {
+ margin-left: 40px;
+ padding-top: 5px;
+}
+
+#extensions-search {
+ margin-top: 1.5em;
+}
+
+#extensions-search .keywords {
+ width: 40%;
+}
+
+#hide-search-options,
+#search-options {
+ display: none;
+}
+
+#search-results .desc p {
+ margin-bottom: 0px;
+}
+
+#search-results h2 {
+ font-weight: bold;
+}
+
+#search-results h2 span {
+ font-weight: normal;
+ font-size: 80%;
+}
+
+#pages #next-page {
+ float: right;
+}
+
+/* various lists */
+
+.category-block {
+ overflow: hidden;
+}
+
+.category-list {
+ margin-top: 1em;
+ padding: 0 1em;
+ min-width: 150px;
+ border-left: 1px solid #eee;
+ font-weight: bold;
+ font-size: .9em;
+ float: left;
+}
+
+.compact-list {
+ font-size: 80%;
+ font-weight: bold;
+ min-width: 40%;
+ float: left;
+}
+
+.category-list ul,
+.compact-list ul {
+ margin: 0;
+ padding: 0;
+}
+
+.category-list ul li,
+.compact-list ul li {
+ list-style: none;
+}
+
+.category-list a:link,
+.category-list a:visited,
+.compact-list a:link,
+.compact-list a:visited {
+ text-decoration: none;
+}
+
+.compact-list span {
+ font-size: smaller;
+}
+
+/* menu box */
+
+.menu-box {
+ background: url(../img/rustico/menu-box/menu-box-top.png) top left no-repeat;
+ font-weight: bold;
+ margin-bottom: 15px;
+ width: 160px;
+}
+
+.menu-box ul {
+ background: url(../img/rustico/menu-box/menu-box-bottom.png) bottom left no-repeat;
+ list-style-type: none;
+ margin: 0;
+ padding: 4px 0;
+}
+
+.menu-box ul li a:link,
+.menu-box ul li a:visited,
+.menu-box ul li span,
+.menu-box ul.allmenu li {
+ display: block;
+ width: 136px;
+ margin: 0;
+ padding: 8px 12px;
+ text-decoration: none;
+}
+
+.menu-box ul li {
+ background: url(../img/rustico/menu-box/menu-box-background.png) 0 0 no-repeat;
+}
+
+.menu-box ul li span,
+.menu-box ul li.selected {
+ background: url(../img/rustico/menu-box/menu-box-background.png) -400px 0 no-repeat;
+}
+
+.menu-box ul li a:hover,
+.menu-box ul li a:active,
+.menu-box ul li.error {
+ background: url(../img/rustico/menu-box/menu-box-background.png) -200px 0 no-repeat;
+}
+
+.menu-box ul li.indented {
+ text-indent: 1em;
+}
+
+/* footer */
+
+#doc-links a,
+#switch-links a,
+#tool-links a {
+ padding: 0 1em;
+}
+
+#footer {
+ background: url(../img/rustico/footer/disclaimer.png) top repeat-x;
+ clear: both;
+ color: #888;
+ font-size: smaller;
+ margin: 0;
+ padding: 11px 0;
+ text-align: center;
+}
+
+#footer-contents {
+ margin: 0 auto;
+ width: 850px;
+}
+
+#footer ul {
+ margin: 1.5em 0;
+}
+
+#footer ul li {
+ display: inline;
+ margin: 0 0.5em;
+}
+
+#footer-addons-menu {
+ font-size: 110%;
+ padding: 0;
+}
+
+#footer-addons-menu li {
+ white-space: nowrap;
+ padding: 10px 0 5px 25px;
+}
+
+#footer-addons-menu li.firefox { background: url(../img/rustico/footer/footer-icon-firefox.png) no-repeat center left; }
+#footer-addons-menu li.thunderbird { background: url(../img/rustico/footer/footer-icon-thunderbird.png) no-repeat center left; }
+#footer-addons-menu li.mozilla { background: url(../img/rustico/footer/footer-icon-mozilla.png) no-repeat center left; }
+
+#footer-disclaimer {
+ clear: both;
+ padding-top: 10px;
+}
+
+#footer-contents form {
+ float: right;
+}
+
+#footer-contents form select {
+ font-size: inherit;
+}
+
+#footer-legal {
+ float: left;
+ text-align: left;
+}
+
+#footer-legal p {
+ margin: 0;
+ padding: 0;
+}
+
+.clearfix:after {
+ content: ".";
+ display: block;
+ height: 0;
+ clear: both;
+ visibility: hidden;
+}
+
+.clearfix {display: block;}
+
+/* Hides from IE-mac \*/
+* html .clearfix {height: 1%;}
+.clearfix {display: block;}
+/* End hide from IE-mac */
+
+/* fixes clears for right-floats only.
+ * use in a div that contains right floats
+ * that doesn't have to clear the left sidebar.
+ */
+.clearfix-right:after {
+ content: ".";
+ display: block;
+ height: 0;
+ clear: right;
+ visibility: hidden;
+}
+
+.clearfix-right {display: inline-block;}
+
+/* Hides from IE-mac \*/
+* html .clearfix-right {height: 1%;}
+.clearfix-right {display: block;}
+/* End hide from IE-mac */
+
+table {
+ border-collapse: collapse;
+ border: none;
+ margin: 1em 0;
+}
+
+table.dalvay-table {
+ border-collapse: separate;
+}
+
+table.dalvay-table thead th {
+ background: none;
+}
+
+table.dalvay-table thead td,
+table.dalvay-table thead th {
+ background: #f9fafa url(../img/dalvay/table/header.png) top repeat-x;
+ border: 0;
+}
+
+table.dalvay-table thead .top-left {
+ background: url(../img/dalvay/table/top-left.png) top left no-repeat;
+}
+
+table.dalvay-table thead .top-right {
+ background: url(../img/dalvay/table/top-right.png) top right no-repeat;
+}
+
+td.left { border-left: 1px solid #d7d7d7; }
+td.right { border-right: 1px solid #d7d7d7; }
+
+table.dalvay-table tfoot td {
+ background: #f9fafa url(../img/dalvay/table/footer.png) bottom repeat-x;
+ border: 0;
+}
+
+table.dalvay-table tfoot .bottom-left {
+ background: url(../img/dalvay/table/bottom-left.png) bottom left no-repeat;
+}
+
+table.dalvay-table tfoot .bottom-right {
+ background: url(../img/dalvay/table/bottom-right.png) bottom right no-repeat;
+}
+
+table.dalvay-table tfoot td { height: 12px; }
+
+
+table.dalvay-table tr.odd td { background: #fff; }
+table.dalvay-table tr.even td { background: #eee; }
+table.dalvay-table tr:target td { background: yellow; }
+table.dalvay-table td.curVersion { font-weight: bold; }
+table.dalvay-table td.nya { text-align: center; }
+
+table.dalvay-table td,
+table.dalvay-table th {
+ margin: 0;
+ padding: 0.5em;
+}
+
+table.dalvay-table td.dl,
+table.dalvay-table th.dl {
+ white-space: nowrap;
+}
+
+table.dalvay-table th {
+ text-align: left;
+}
+
+/* search engines */
+
+.front-section {
+ width: 220px;
+ padding: 5px 0 5px 25px;
+ float: left;
+ color: #666;
+}
+
+#switch-links {
+ text-align: right;
+ padding-left: 5em;
+}
+
+#switch-links .switch-tb,
+#switch-links .switch-suite {
+ padding: 1px 0 1px 30px;
+ font-size: 100%;
+ background: #fff 9px 0 no-repeat;
+}
+
+/* ported from cavendish */
+
+.item {
+ border: #D2D6D6 1px solid;
+ padding-left: 5px;
+ padding-right: 6px;
+ MARGIN-bottom: 10px;
+ -moz-border-radius: 10px;
+}
+
+.item a {
+ color: #00129c;
+ text-decoration: none;
+}
+.item a:visited {
+ color: #00129c;
+ text-decoration: none;
+}
+.item a:hover {
+ color: #fc5900;
+}
+
+.item h2 {
+ margin-top: 0.2em;
+}
+
+.iconbar {
+ padding-right: 15px;
+ float: left;
+ width: auto;
+ height: 34px;
+}
+
+.iconbar img {
+ float:left;
+}
+
+.iconbar a {
+ text-decoration: none;
+}
+
+/* user comments */
+
+div.averagerating {
+ float:right;
+ font-size:85%;
+ font-weight:bold;
+}
+
+div.usercomment {
+ border-top: 1px solid #eee;
+}
+
+p.commenttext {
+ margin-left: 2em;
+}
+
+p.commentmeta {
+ font-size: smaller;
+}
+
+.pages {
+ color: #999;
+ font-weight: bold;
+ height: 2em;
+}
+
+.next {
+ border-left: 1px solid #000;
+ display: inline;
+ padding-left: 5px;
+}
+
+.prev {
+ display: inline;
+}
+
+#comments-sort {
+ float: right;
+}
+
+/* breadcrumbs */
+
+#breadcrumbs { padding: 0 50px; }
+#breadcrumbs #breadcrumbs_container { max-width: 900px; margin: 0 auto; }
+#breadcrumbs {
+ background: #F7F8F8 url("../img/template/breadcrumbs-background.png") bottom repeat-x;
+ padding-top: 6px;
+ padding-bottom: 6px;
+ font-size: 85%;
+ color: #999;
+}
+
+#breadcrumbs a:link,
+#breadcrumbs a:visited {
+ color: #666;
+}
+
+#breadcrumbs a:hover,
+#breadcrumbs a:active {
+ color: #333;
+}
+
+#breadcrumbs form.searchbox {
+ display: inline;
+ vertical-align: top;
+ font-size: inherit;
+}
+
+#breadcrumbs form.searchbox input.query {
+ width: 10em;
+ font-size: inherit;
+ border-width: 1px;
+}
+#breadcrumbs form.searchbox input.submit {
+ font-size: inherit;
+ border-width: 1px;
+}
+
+
+/* rss */
+
+.rss-link-list {
+ list-style-type: none;
+ margin: 0;
+ padding: 0;
+}
+.rss-link {
+ margin: .4em 10px .8em 0;
+ padding-left: 16px;
+ background: url(../img/tinyRss.png) no-repeat left;
+ float: left;
+}
+.rss-container img {
+ float: left;
+}
+.rss-container h3 {
+ margin-left: 28px;
+ padding-top: 1px;
+}
+
+/* reviews in addon display sidebar */
+
+div.review {
+ clear:right;
+ overflow:auto;
+ width:240px;
+ margin-bottom:15px;
+ font-size:11px;
+ color:#666;
+}
+
+div.review div.score {
+ float:left;
+ clear:left;
+ padding:3px 5px 1px 5px;
+ margin-right:8px;
+ font-size:20px;
+ color:#555;
+ background-color:#ddd;
+}
+
+div.review div.score span {
+ color:#aaa;
+}
+
+div.review span.review {
+ display:block;
+ width:150px;
+ float:left;
+ clear:right;
+}
+
+div.review a {
+ font-size:13px;
+ color:#666;
+ font-weight:bold;
+}
+
+div.review a.profileLink {
+ font-size:11px;
+ color:#666;
+ font-weight:normal;
+}
+
+a.reviewLink {
+ margin-left:45px;
+}
+
+div.reviewed-on {
+ font-size: .8em;
+ margin: .4em 0;
+}
+
+/* hr as suggested in http://www.sovavsiti.cz/css/hr.html */
+
+.divider {
+ height: 15px;
+ background: #fff url(../img/divider.gif) no-repeat scroll center;
+ border: 0;
+ clear: both;
+ margin: 0 0 10px 0;
+}
+.divider hr {
+ display: none;
+}
+
+/* addons display page: reviews part */
+
+.reviews {
+ font-size: .9em;
+ float: left;
+ min-width: 45%;
+}
+
+.reviews ul {
+ padding: 0 0 0 2em;
+}
+
+.review {
+ display: block;
+ margin: 0 0 1em .5em;
+}
+
+.review a {
+ font-weight: bold;
+}
+
+.review .reviewtitle {
+ font-weight: bold;
+}
+
+/* reviews page */
+div.review-reply {
+ margin-left: 3em;
+}
+
+/* sidebar (left) */
+#sidebar-left,
+#sidebar {
+ float: left;
+ font-size: 80%;
+ width: 160px;
+}
+
+#sidebar-left .corner-box ul,
+#sidebar .corner-box ul {
+ margin: 0;
+ padding: 0 12px;
+}
+
+/* sidebar right */
+#sidebar-right {
+ float: right;
+ font-size: 80%;
+ width: 160px;
+}
+
+#sidebar-right .corner-box ul {
+ margin: 0;
+ padding: 0 12px;
+}
+
+/* addons as listitems (search etc) */
+
+.addon-listitem {
+ margin: 0 0 1em 0;
+}
+
+.addon-listitem .icon {
+ float: left;
+ margin-right: .6em;
+}
+
+.addon-listitem .preview-image {
+ float: right;
+}
+
+.addon-listitem .version-simple {
+ display: none;
+}
+
+.addon-listitem .addon-titleby {
+ margin: 0 0 7px 0;
+}
+
+.addon-listitem .addon-titleby h2.addonname {
+ font-weight: bold;
+ padding: 4px 0 0 0;
+}
+
+.addon-listitem .addon-titleby .developer {
+}
+
+.addon-listitem .addon-desc .tagline {
+ margin: 5px 0 7px 0;
+}
+
+.addon-listitem .addon-desc .version {
+ font-size: .9em;
+ background: url(../img/version.png) no-repeat left;
+ line-height: 16px;
+ padding-left: 20px;
+}
+
+.addon-listitems-options {
+ margin: 0 0 1em 0;
+ padding: 0;
+ width: 100%;
+}
+
+.addon-listitems-options span {
+ margin: 0 .3em;
+}
+
+.addon-listitems-options span.selected {
+ font-weight: bold;
+}
+
+/* error page */
+.error-notice {
+ margin: 0 auto;
+ padding: 10px 80px 20px 80px;
+ background: url(../img/warning.png) 20px 20px no-repeat;
+ min-height: 48px; /* So the image will show completely, even if the error is short*/
+}
+
+/* policies */
+
+.policy-area {
+ width: 100%;
+ height: 30em;
+}
+
+/* styles for js actions */
+
+.js-action {
+ color: #f7941d;
+ cursor: pointer;
+ text-decoration: underline;
+}
+
+/* search page styles */
+
+.addon-search-message {
+ padding-bottom: .5em;
+}
+
+.addon-search-message span {
+ font-weight: bold;
+}
+
+/* pages/submissionhelp */
+ul.submissionHelp li span.required {
+ font-weight: bold;
+}
+ul.submissionHelp li span.optional {
+ font-style: italic;
+}
+
+#extendfirefox {
+ margin-bottom: 15px;
+}
+
+#extendfirefox a {
+ text-decoration: none;
+}
diff --git a/site/app/webroot/css/rustico.template.css b/site/app/webroot/css/rustico.template.css
new file mode 100644
index 0000000..4559803
--- /dev/null
+++ b/site/app/webroot/css/rustico.template.css
@@ -0,0 +1,292 @@
+body {
+ margin: 0 0 1em 0;
+ padding: 0; /* need for Opera */
+ background: #fff;
+ color: #333;
+ min-width: 610px;
+}
+
+form { margin: 0; }
+img { border: 0; }
+
+
+/* Core site element widths */
+
+/*#header, #breadcrumbs, #content, #footer {
+ max-width: 1000px;
+ margin: 0 auto;
+}*/
+
+#header { padding: 0 50px; }
+#header ul { right: 0; }
+* html #header ul { right: 50px; }
+#breadcrumbs { padding: 0 50px; }
+#content { padding: 0 50px; }
+#footer { padding: 0 20px; margin: 0 50px; }
+
+#header div, #content, #breadcrumbs_container, #footer, #main-feature .feature-contents {
+ max-width: 900px; margin: 0 auto;
+}
+
+#header div { position: relative; }
+
+/* header */
+
+#header {
+ height: 38px;
+ position: relative;
+ border-bottom: 1px solid #A1A6B1;
+ background: #33415D url("../img/template/header-background.png") top repeat-x;
+ z-index: 1;
+}
+
+#header h1 { margin: 0; }
+
+#header h1 img {
+ font-weight: bold;
+ color: #7f7c45;
+}
+
+#header ul {
+ padding: 0;
+ margin: 0;
+ list-style: none;
+ border-left: 1px solid #576178;
+ border-right: 1px solid #1f2635;
+ position: absolute;
+ top: 0;
+}
+
+#header li {
+ float: left;
+ padding: 0;
+ margin: 0;
+}
+
+#header ul a:link, #header ul a:visited {
+ display: block;
+ float: left;
+ padding: 10px 15px;
+ text-decoration: none;
+ border-right: 1px solid #576178;
+ border-left: 1px solid #1f2635;
+ color: #dee0e5;
+ height: 36px;
+ voice-family: "\"}\"";
+ voice-family: inherit;
+ height: 16px;
+} #ignored {}
+
+#header ul li a:hover {
+ background: #475470;
+ color: #fff;
+ text-decoration: underline;
+}
+
+#header ul li span,
+#header ul li a.current,
+#header ul li a:hover {
+ background: #475470;
+ color: #fff;
+ text-decoration: underline;
+}
+
+#header ul li span,
+#header ul li a.current {
+ text-decoration: none;
+}
+
+/* breadcrumbs */
+
+#breadcrumbs {
+ background: #F7F8F8 url("../img/template/breadcrumbs-background.png") bottom repeat-x;
+ padding-top: 4px;
+ padding-bottom: 30px;
+ font-size: 85%;
+ color: #999;
+}
+
+#breadcrumbs a:link,
+#breadcrumbs a:visited {
+ color: #666;
+}
+
+#breadcrumbs a:hover,
+#breadcrumbs a:active {
+ color: #333;
+}
+
+
+/* content */
+
+#content {
+ background: #fff;
+}
+
+/* Sidebar */
+
+#nav:before {
+ line-height: 0.1;
+ font-size: 1px;
+ background: transparent url("../img/template/menu_tr.gif") no-repeat top right;
+ margin: 0;
+ height: 9px;
+ display: block;
+ border-bottom: 1px solid #ddd;
+ content: url("../img/template/box/key-point_tl.gif");
+}
+#nav {
+ background: #E0E9E9 url("../img/template/menu_back.gif") right repeat-y;
+}
+#nav:after {
+ display: block;
+ padding-top: 0;
+ line-height: 0.1;
+ font-size: 1px;
+ content: url("../img/template/box/key-point_bl.gif");
+ margin: 0 0 0 0;
+ height: 8px;
+ background: transparent url("../img/template/menu_br.gif") scroll no-repeat bottom right ;
+ border-top: 1px solid #fff;
+}
+
+#nav, #nav ul {
+ margin: 0;
+ padding: 0;
+ list-style: none;
+}
+#nav {
+ margin-bottom: 1em;
+}
+#nav li {
+ display: inline;
+ padding: 0;
+ margin: 0;
+}
+
+#nav li span { /* used for un-linked menu items */
+ display: block;
+ padding: 6px 10px;
+ font-weight: bold;
+ color: #666;
+}
+#nav li span#configParent, #nav li span #configuration {
+ display: inline;
+ font-weight: normal;
+ padding: 0;
+}
+
+#nav li a {
+ display: block;
+ padding: 8px 10px;
+ text-decoration: none;
+ background: #EDF2F2;
+ border-bottom: 1px solid #ddd;
+ border-top: 1px solid #fff;
+ border-right: 1px solid #ddd;
+}
+#nav li a:hover {
+ background: #E0E9E9;
+}
+
+#nav li li span { /* used for un-linked menu items */
+ padding: 4px 8px 4px 20px;
+}
+
+#nav li li a {
+ padding: 6px 8px 6px 20px;
+}
+
+#oN {
+ background-color: #E0E9E9;
+}
+#oN:hover {
+ background-color: #C6DCDC;
+}
+
+
+/* footer */
+
+#footer {
+ clear: both;
+ margin-top: 3em;
+ margin-bottom: 1em;
+ color: #888;
+ padding: 25px 50px;
+ text-align: center;
+}
+
+#footer-contents {
+ padding: 0;
+ border-top: 1px solid #C9D0E0;
+}
+
+#footer ul#footer-menu {
+ position: relative;
+ top: -0.8em;
+ margin: 0 1em 0 1em;
+ padding: 0;
+ list-style-type: none;
+}
+
+#footer ul#footer-menu li {
+ display: inline;
+ background: #fff;
+ margin: 0 1em;
+}
+
+#footer ul#footer-menu li a {
+ margin: 0 1em;
+ white-space: nowrap;
+}
+
+#footer p {
+ margin: 0.3em;
+ clear: both;
+}
+
+#footer .site-tools {
+ display: none;
+}
+
+.small-print {
+ font-size: 85%;
+ color: #888;
+}
+
+.small-print a:link,
+.small-print a:visited {
+ color: #888;
+}
+
+.small-print a:hover,
+.small-print a:active {
+ color: #333;
+}
+
+#locales {
+ margin: 0 auto 1.5em auto;
+ width: 610px;
+ line-height: 160%;
+}
+
+#locales p {
+ display: inline;
+ margin: 0;
+ padding: 0 0.3em 0 0;
+}
+
+#locales ul {
+ display: inline;
+ margin: 0;
+ padding: 0;
+}
+
+#locales li {
+ padding: 0 0.3em 0 0;
+ display: inline;
+}
+
+#locales li a {
+ white-space: nowrap;
+}
diff --git a/site/app/webroot/css/sandbox_rustico.css b/site/app/webroot/css/sandbox_rustico.css
new file mode 100644
index 0000000..0339bb4
--- /dev/null
+++ b/site/app/webroot/css/sandbox_rustico.css
@@ -0,0 +1,27 @@
+#breadcrumbs {
+ background: #F7F8F8 url("../img/sandbox.png") bottom repeat;
+}
+.install-button a:link span.install-green-button,
+.install-button a:visited span.install-green-button,
+.install-button a:hover span.install-green-button,
+.install-button a:active span.install-green-button {
+ background: url(../img/rustico/install-button-red.png) no-repeat bottom left;
+}
+
+.install-button a:link,
+.install-button a:visited,
+.install-button a:hover,
+.install-button a:active {
+ background: url(../img/rustico/install-button-red.png) no-repeat top left;
+}
+
+.install-button a:hover span.install-green-button,
+.install-button a:active span.install-green-button {
+ background: url(../img/rustico/install-button-red.png) no-repeat bottom right;
+}
+
+.install-button a:hover,
+.install-button a:active {
+ background: url(../img/rustico/install-button-red.png) no-repeat top right;
+
+} \ No newline at end of file
diff --git a/site/app/webroot/css/screen.css b/site/app/webroot/css/screen.css
new file mode 100644
index 0000000..0e640d6
--- /dev/null
+++ b/site/app/webroot/css/screen.css
@@ -0,0 +1,1826 @@
+/*----------------------------------------------------------------------------
+Standards-Compliant Layout CSS file for Addons.mozilla.org
+Created by Craig Cook - focalcurve.com
+ on November 20, 2007
+-----------------------------------------------------------------------------*/
+
+
+/*** =Reset defaults ***/
+html, body, div, span, object, iframe,
+h1, h2, h3, h4, h5, h6, p, blockquote, pre,
+a, abbr, acronym, address, code,
+del, dfn, em, img, q, dl, dt, dd, ol, ul, li,
+fieldset, form, label, legend,
+table, caption, tbody, tfoot, thead, tr, th, td {
+ margin: 0;
+ padding: 0;
+ border: 0;
+}
+
+/* Tables still need 'cellspacing="0"' in the markup. */
+table { border-collapse: separate; border-spacing: 0; }
+
+/*** =General elements ***/
+body { min-width: 770px; }
+
+ol, ul { margin-left: 2em; }
+blockquote { margin: 0 3em 1em; }
+dd { margin-left: 2em; }
+td, th { padding: 2px 6px; }
+
+a.view { padding-right: 10px; }
+button, input[type="submit"] { cursor: pointer; }
+
+h2 { margin-bottom: .5em; }
+
+div.error-notice { margin: 0; min-height: 48px; margin-bottom: 1.5em; padding: 10px 10px 0 70px; }
+
+.with-js .hide-with-js { display: none }
+.show-with-js { display: none }
+.with-js .show-with-js { display: block }
+
+/*** =Site-notice ***/
+#site-notice { width: 80%; padding: 5px 10%; }
+
+/*** =Access nav ***/
+#nav-access { position: absolute; top: -10em; margin: 0 auto; width: 100%; }
+#nav-access a:active, #nav-access a:focus { position: absolute; top: 11em; width: 18em; z-index: 2;}
+.html-ltr #nav-access a:active, .html-ltr #nav-access a:focus { left: 50%; margin-left: -8em;}
+.html-rtl #nav-access a:active, .html-rtl #nav-access a:focus { right: 50%; margin-right: -8em;}
+
+
+/*** =Header ***/
+#branding { position: relative; }
+
+h4#moz { position: absolute; top: 10px; margin: 0; z-index: 1; }
+.html-rtl h4#moz {left: 0px; }
+.html-rtl h4#moz img {position: relative; left: -10px; }
+
+h4#moz a { display: block; height: 44px; width: 100px; padding-left: 10px;}
+
+/* =Page title */
+#page-title { height: 13em; }
+
+#page-title div { max-width: 900px; margin: 0 auto;}
+.html-ltr #page-title div {padding: 25px 105px 0;}
+.html-rtl #page-title div {position:relative; left:-70px; padding: 25px 0 0 0;}
+
+#page-title h1 { position: relative; }
+.html-ltr #page-title h1 {padding: 10px 0 5px 125px; }
+.html-rtl #page-title h1 {padding: 10px 320px 5px 0; }
+
+#page-title h1 img { position: absolute; top: 0; }
+.html-ltr #page-title h1 img{left: 0;}
+.html-rtl #page-title h1 img {right: 200px;}
+
+#page-title h2 { position: relative; }
+.html-ltr #page-title h2 { margin: -5px 0 5px 175px; }
+.html-rtl #page-title h2 { margin: -5px 370px 5px 0; }
+
+#page-title p.page-intro { margin-bottom: 0; width: 42em; max-width: 650px; }
+.html-ltr #page-title p.page-intro {padding-left: 125px;}
+.html-rtl #page-title p.page-intro {padding-right: 320px;}
+
+
+/* =User nav */
+#nav-user { max-width: 900px; min-width: 770px;}
+.html-ltr #nav-user { margin: -1.75em auto 0; padding: 0 50px;}
+.html-rtl #nav-user { margin: 0em auto 0; padding: 0 0 0 50px;}
+
+#nav-user li { display: inline;}
+.html-ltr #nav-user li { padding-left: 1em; margin-right: .5em; }
+.html-rtl #nav-user li { padding-right: 1em; margin-left: .5em; }
+
+.html-ltr #nav-user li:first-child { border-left: 0; padding-left: 0; }
+.html-rtl #nav-user li:first-child { border-right: 0; padding-right: 0;}
+
+
+/* =Other Applications */
+#other-apps { position: absolute; top: -9.65em; z-index: 5;}
+.html-ltr #other-apps {right: 50px; padding: 6px 10px 0; }
+.html-rtl #other-apps {right: 50px; padding: 6px 10px 0; }
+
+#other-apps.js { width: 12em; padding-bottom: 6px; }
+
+#other-apps h3 { margin-right: 20px; }
+
+#other-apps.js h3 { float: none; cursor: pointer; }
+.html-ltr #other-apps.js h3 {margin: -6px -10px; padding: 6px 15px 6px 20px; }
+.html-rtl #other-apps.js h3 {margin: -6px -10px; padding: 6px 15px 6px 20px; }
+
+#nav-apps { margin-top: .1em; }
+.html-ltr #nav-apps { margin-left: 0;}
+.html-rtl #nav-apps { margin-right: 0;}
+
+.html-ltr #nav-apps li { margin-right: 10px; }
+.html-rtl #nav-apps li { margin-left: 10px; }
+
+#other-apps.js #nav-apps { margin-top: 1em; }
+#other-apps.js #nav-apps li { display: block; margin-right: 0; }
+.html-ltr #other-apps.js #nav-apps li { margin-right: 0; }
+.html-rtl #other-apps.js #nav-apps li { margin-left: 0; }
+
+#other-apps.js #nav-apps a { display: block; line-height: 35px; }
+.html-ltr #other-apps.js #nav-apps a { padding-left: 40px; }
+.html-rtl #other-apps.js #nav-apps a { padding-right: 40px; }
+
+#other-apps.collapsed #nav-apps { position: absolute; }
+.html-ltr #other-apps.collapsed #nav-apps { left: -999em; }
+.html-rtl #other-apps.collapsed #nav-apps { right: -999em; }
+
+#other-apps.collapsed #nav-apps a:active, #other-apps.collapsed #nav-apps a:focus { position: absolute; top: 0; }
+.html-ltr #other-apps.collapsed #nav-apps a:active, .html-ltr #other-apps.collapsed #nav-apps a:focus { left: -999em; }
+.html-rtl #other-apps.collapsed #nav-apps a:active, .html-rtl #other-apps.collapsed #nav-apps a:focus { right: -999em; }
+
+/*** =Search form ***/
+#search-element { position: relative; width: 80%;}
+.html-ltr #search-element {left: 190px; }
+.html-rtl #search-element {left: 0}
+
+#search-bubble-inner { height: 71px; margin:0; padding: 0; width: 6px; float: left; }
+.html-ltr #standard-search { padding: 20px 4px 15px 14px;}
+.html-rtl #standard-search { padding: 20px 20px 15px 4px;}
+
+#search-bubble-outer legend { display: none; }
+#search-form ol { margin: 0; padding: 0; }
+#search-form #search-query { width: 55%; }
+
+#search-form #search-query label, #search-mini #search-query label { display: none; } /* label is hidden by default when JS isn't available */
+#search-mini #search-query label { font-style: italic; color: #46651f;}
+#search-form #search-query label, #search-mini #search-query label { position: absolute; top: 20px; }
+#search-mini #search-query label {top: 2px;}
+.html-ltr #search-form #search-query label { left: 17px; padding: .2em 5px .2em 30px; }
+.html-rtl #search-form #search-query label { right: 17px; padding: .2em 30px .2em 5px; }
+
+
+#search-form #query { width: 42%;}
+.html-ltr #search-form #query { padding: .2em 5px .2em 24px;}
+.html-rtl #search-form #query { padding: .2em 24px .2em 5px;}
+
+#search-form #category { width: 36%; padding: .2em 0; }
+#search-form #category option { min-width: 14em; }
+
+
+#search-form #search-query input, #search-form #category option { height: 21px; -ms-box-sizing:content-box; -moz-box-sizing:content-box; -webkit-box-sizing:content-box; box-sizing:content-box; }
+
+#search-form #my-submit { width:37px; height: 38px; border: 0px; margin-left: 9px; }
+
+/*** =Advanced Search Form ***/
+#advanced-search { margin: -2px 0 0 0; padding: .1in .25in 0 .25in; }
+form.asclosed {display: none;}
+#search-application { padding-bottom: .1in}
+#advanced-search-toggle {position: relative; top:-2px}
+.html-ltr #advanced-search-toggle {text-align: right;}
+.html-rtl #advanced-search-toggle {text-align: left; direction: ltr;}
+#advanced-search-toggle div { width:6px; height: 6px; float: left; }
+#advanced-search-toggle #toggle-inner { padding-left: 3px;}
+.html-ltr #advanced-search-toggle #toggle-outer { margin: 0 .25in .1in 0; padding-right: 4px;}
+.html-ltr #advanced-search-toggle a { padding-right: .15in }
+.html-rtl #advanced-search-toggle #toggle-outer { margin: 0 0 .1in .25in; padding-right: 4px;}
+.html-rtl #advanced-search-toggle a { padding-left: .15in}
+
+.html-ltr #search-application td {padding-right: .2in}
+.html-rtl #search-application td {padding-left: .2in}
+.html-rtl #advanced-search td { text-align: right;}
+
+.html-ltr #search-platform {float: left; margin-bottom: 1.5em; margin-right: 1in;}
+.html-rtl #search-platform {float: right; margin-bottom: 1.5em; margin-left: 1in;}
+
+/*** =Mini search form ***/
+#search-mini {
+ display: inline;
+ float: right;
+ border: 1px solid #8cb956;
+ -moz-border-radius: 6px;
+ -webkit-border-radius: 6px;
+ border-radius: 6px;
+ background: #91ce43 url('../img/sprite.png?20090430') no-repeat right -23px;
+ padding: 5px;
+ position: relative;
+ -moz-box-shadow: 2px 2px 3px -1px #888888;
+ -webkit-box-shadow: 2px 2px 3px -1px #888888;
+ box-shadow: 2px 2px 3px -1px #888888;
+}
+
+.html-rtl #search-mini {
+ float: left;
+ -moz-box-shadow: -2px 2px 3px -1px #888888;
+ -webkit-box-shadow: -2px 2px 3px -1px #888888;
+ box-shadow: -2px 2px 3px -1px #888888;
+}
+
+#search-mini #category {
+ font-size: 113%;
+ max-width:250px;
+}
+
+.html-ltr #search-mini #search-query label { left: 9px; padding: 0.39em 15px 0.2em 5px;}
+.html-rtl #search-mini #search-query label { right: 9px; padding: 0.39em 5px 0.2em 15px;}
+
+#search-mini-submit {
+ border: 1px solid #6d9041;
+ background: url('../img/sprite.png?20090430') no-repeat right -23px;
+ -moz-border-radius: 3px;
+ -webkit-border-radius: 3px;
+ border-radius: 3px;
+ padding: 2px 9px;
+ vertical-align: top;
+ margin: 0 0 0 3px;
+ -moz-box-shadow: 2px 2px 3px -1px #888888;
+ -webkit-box-shadow: 2px 2px 3px -1px #888888;
+ box-shadow: 2px 2px 3px -1px #888888;
+}
+
+/*** =Footer ***/
+#footer { position: relative; width: 100%; clear: both; padding: 1em 0; min-width: 770px;}
+#footer-lang-form { position: relative; max-width: 900px; min-width: 770px;}
+.html-ltr #footer-lang-form {padding: 0 50px; margin: 0 auto;}
+.html-rtl #footer-lang-form {padding: 0 0 0 50px; margin: 0 0;}
+
+.html-ltr #footer-lang-form p { position: absolute; right: 50px; }
+.html-rtl #footer-lang-form p { position: absolute; left: 50px; }
+
+#footer-legal { max-width: 900px; margin: 0 auto; padding: 0 50px; min-width: 770px;}
+#copyright { margin-bottom: 0; }
+#nav-legal li { display: inline; margin-right: .5em; }
+#footer-disclaimer { margin-top: 1em; }
+
+/*** =Content layout ***/
+#content { clear: both; position: relative; padding: 1em 50px; max-width: 950px; margin: 0 auto 1em; min-width: 770px; min-height:1000px; }
+#content-main { position: relative; margin-left: 190px; min-height: 50em; }
+#content.main-page #content-main,
+#content.detail-page #content-main,
+#content.reviews-page #content-main,
+#content.versions-page #content-main { width: 60%; padding-right: 20%; }
+#content-main.full { margin-left: 0; }
+#content.detail-page #content-main.full,
+#content.reviews-page #content-main.full,
+#content.versions-page #content-main.full { width: 75%; padding-right: 25%; }
+#secondaries .sub { width: 48%; }
+#secondaries #feature3 { float: right; }
+#secondaries #feature2 { float: left; }
+
+#content #sidebar { position: absolute; left: 50px; top: 1em; width: 170px; }
+
+/*** =Extra content ***/
+#content-extra { position: absolute; right: 0; top: 0; width: 23%; }
+
+#content-extra .extra { margin-bottom: .1em; padding: 5px 12px;}
+
+#content-extra h3 { margin-bottom: .1em; }
+.html-ltr #content-extra ul { margin: 0 0 0 10px;}
+.html-rtl #content-extra ul { margin: 0 10px 0 0; }
+#content-extra ul li {margin: 0; padding:0;}
+#content-extra ul li span {font-size: 8pt;}
+#content-extra p.view-all { margin-bottom: .5em; }
+.html-rtl #content-extra p.view-all {margin-right: 4px}
+/*** =Categories ***/
+
+#categories { margin-bottom: 1em; position: relative; z-index: 5; }
+#categories h3 { margin: 0 -1px; padding-left: 6px; }
+#categories.collapsed h3 { padding-left: 18px; }
+#categories h3 span { display: block; padding: 8px 4px; }
+
+#categories, #categories.collapsed #cat-list { padding-bottom: 6px; }
+#categories.collapsed h3 span { text-indent: 4px; padding-left: 0; }
+#cat-list { margin-left: 0; }
+#cat-list li { padding-right: 1px; }
+#cat-list a, #cat-list span { display: block; padding: .5em 10px; }
+
+#categories.collapsed h3 { cursor: pointer; }
+#categories p { margin: 0 -1px -6px; padding: .6em 10px; }
+#categories.collapsed #cat-list { position: absolute; left: -999em; top: -999em; }
+.html-rtl #categories.collapsed #cat-list {position: absolute; left: 999em; top: -999em;}
+#categories.collapsed #cat-list.visible { margin: 0 -1px; width: 100%; left: 0; top: 3.35em; height: auto; overflow: visible; z-index: 99; }
+#categories.collapsed #cat-list a:active, #categories.collapsed #cat-list a:focus { position: absolute; left: 999em; top: 1002.4em; width: 85%; }
+#categories.collapsed #cat-list.visible a:active, #categories.collapsed #cat-list.visible a:focus { position: static; width: auto; }
+
+
+
+/*** =Content-main, general styles ***/
+#content-main p, #content-main ul, #content-main ol { margin-bottom: 1.25em; }
+#content-main li { margin-bottom: .5em; }
+#content-main li ul, #content-main li ol { margin-left: 15px; }
+
+/*** =Add-on boxes ***/
+.addon { position: relative; min-height: 160px; padding: 18px 20px 10px; margin-bottom: 1.6em; }
+.addon .vex { height: 10px; width: 100%; position: absolute; left: 0; bottom: 0;}
+.addon .vex span { display: block; height: 10px; margin-left: -1px; width: 10px; float: left;}
+.addon .name { padding-left: 44px; position: relative; }
+.addon .name img { position: absolute; left: 0; }
+.addon .author { margin: 0 0 1.25em 44px; }
+.addon .preview-img { position: absolute; left: -1px; top: 0; padding: 18px 0 0 20px; width:200px; height:150px; overflow:hidden;}
+.addon .flag { position: absolute; left: -1px; top: 0; padding: 5px 10px 3px 10px; z-index: 5; }
+.addon .baseline img.faq {margin: 0 5px 0 0; float: left;}
+.rec, .exp { min-height: 170px; }
+.rec .preview-img, .exp .preview-img { padding: 2.5em 0 0 20px; }
+.updated { font-size: 75%; color:#666; }
+
+/* =Primary featured add-on */
+.main { padding-left: 240px; min-height: 220px; }
+.main .rating { position: absolute; left: 20px; top: 180px; width: 200px; }
+.main .stats { position: absolute; left: 20px; top: 180px; width: 200px; margin-top: 2em; }
+
+/* =Secondary featured add-ons */
+.sub { position: relative; padding: 0; }
+.sub .irk { margin-left: -1px; padding: 14px 20px 8px; margin-right: 4px; }
+.sub .vex { padding: 0; left: 0; }
+.sub .name { margin-bottom: 0; }
+.sub .preview-img { position: static; padding: 0;}
+.sub .rating { position: static; width: 40%; padding-right: 10%; float: left; }
+.sub .rating img { display: block; }
+.sub .more-from { clear: both; }
+
+/* =Listing items */
+#content-main #addon-listing { margin-left: 0; }
+#addon-listing .addon { padding: 18px 240px 10px; margin-bottom: 1em; }
+#addon-listing .preview-img { position: absolute; left: -1px; top: 0;}
+#addon-listing .rating { display: inline; margin-right: 2em; }
+#addon-listing .stats { display: inline; margin-right: 2em; }
+#addon-listing .more { display: inline; margin: 0; padding: 0; }
+#addon-listing .more li { display: inline; margin: 0 10px 0 0; padding: 0 15px 0 0; }
+#addon-listing .desc { margin-top: .5em; }
+
+/*** =Install button ***/
+.install-button:after, .install-container:after {content:".";clear:both;display:block;visibility:hidden;height:0;overflow:hidden;} /* clear floats */
+.install-button a { float: left; cursor: pointer; max-width: 290px;}
+.html-rtl .install-button a { float: right; }
+.install-button a * { display: block; float: left; position: relative; }
+.html-rtl .install-button a * { float: right; }
+.install-button a span { padding: 0 0 0 6px; }
+.install-button a span span { padding: 0 0 8px 0; }
+.install-button a span span span { left: -6px; padding: 0 0 6px 0; }
+.install-button a span span span strong { right: -6px; padding: 10px 45px 0 6px; }
+.install-button a span span span strong img {padding: 0 6px 0 0;}
+
+#addon-listing .install-container { position: absolute; right: 0; top: 20px; max-width: 180px; padding: 0 15px; }
+#addon-listing .install-container .install-button { margin-bottom: .5em; float: right; }
+#addon-listing .addon p.updated { position: absolute; right: 0; bottom: 5px; max-width: 180px; padding: 0 15px; }
+
+#addon-listing .exp .exp-loggedout,
+#addon-listing .exp .exp-confirmed { float: right; }
+#addon-listing .exp .exp-loggedout .install-button,
+#addon-listing .exp .exp-confirmed .install-button { float: none; }
+
+.exp-loggedout, .exp-confirmed { float: left; padding: 5px 5px 3px 8px; }
+.html-rtl .exp-loggedout, .html-rtl .exp-confirmed { float: right; padding: 5px 8px 3px 5px; }
+.exp-loggedout .install-button,
+.exp-confirmed .install-button { margin-top: 3px; margin-right: -3px; }
+.html-rtl .exp-loggedout .install-button,
+.html-rtl .exp-confirmed .install-button { margin-right: 0; margin-left: -3px; }
+.exp-loggedout .install-button a { cursor: default; }
+#content-main .exp-loggedout p.install-button,
+#content-main .exp-confirmed p.install-button { margin-bottom: 0; }
+
+.exp-confirm-install input { float: left; }
+.html-rtl .exp-confirm-install input { float: right; }
+.exp-confirm-install .exp-desc { float: right; width: 85%; padding: 0px 0px 5px 0px; }
+.html-rtl .exp-confirm-install .exp-desc { float: left; }
+
+/*** =Pitch ***/
+.pitch { margin-bottom: 1em; padding: 10px; }
+.pitch h3, .pitch p { margin-bottom: 1em; }
+.html-rtl .pitch ul { padding-right: 15px;}
+.pitch h3 img { float: left; margin: -4px 10px 0 0; }
+
+/*** =Landing pages ***/
+#recommended { padding: 0 1% 10px; width: 98%; float: left; margin-bottom: 1em; }
+#recommended .addon { float: none; }
+
+#content.wide #recommended .addon { width: 20%; padding-left: 26.5%; min-width: 100px; margin-bottom: 0; }
+#content.wide #recommended .addon .preview-img { width: 45%; }
+#content.wide #recommended #feature1 { float: left; }
+#content.wide #recommended #feature2 { float: right; }
+
+#content.landing #secondaries { float: left; }
+#content.landing #secondaries .sub { float: left; width: 30.5%; margin-right: 2.5%; }
+#content.landing-with-slider #secondaries .sub { float: left; width: 31.5%; margin-right: 2.5%; }
+#content.landing-with-slider #secondaries #feature8 { margin-right: 0; }
+#content.landing #secondaries .sub .irk { padding-top: 2.2em; }
+#content.landing #secondaries .sub .vex { padding-top: 0; }
+#content.landing #secondaries .exp .preview-img { padding: 0;}
+#content.landing #secondaries .addon .preview-img { padding: 0; width:180px;}
+
+#content.landing-with-slider #secondaries .sub { float: left; width: 31.5%; margin-right: 2.5%; }
+#content.landing-with-slider #secondaries #feature8 { margin-right: 0; }
+
+/* Without a recommended box */
+#content.landing #secondaries { width: 77%; }
+#content.landing #content-extra { width: 23%; }
+#content.landing-with-slider #secondaries { width: 100%; }
+#content.landing-with-slider #content-extra { width: 25%; position: absolute; top: 0; right: 0; }
+#content.landing-with-slider #content-main { position: relative }
+#content.landing-with-slider #recommended { float: none; position: relative; left: 0%; width: 71%; }
+.html-rtl #content.landing-with-slider #recommended { float: left; }
+#content.landing-with-slider #recommended #slider .item_set .addon { float: left; width: 308px; padding-left: 240px }
+#content.landing-with-slider #recommended #slider { background-color: #fff; margin-bottom: 0 }
+
+/* When there is a recommended box...
+#content.landing #secondaries { width: 76%; padding-left: 1%; }
+#content.landing #content-extra { width: 22%; margin-right: 1%; }
+*/
+
+#content.landing #content-extra { position: static; float: right; }
+#content.landing-with-slider #content-extra { position: absolute; float: none; }
+#content.landing.languages #content-extra { margin-right: 0; }
+#content.landing .more-addons { margin: 0 0 1em; padding: 6px 10px 0; }
+
+#content.landing.browse #secondaries { width: 50%; }
+#content.landing.browse #secondaries .sub { width: 47%; }
+#content.landing.browse #secondaries #feature4 { margin-right: 0; }
+#content.landing.browse #content-extra { width: 47%; }
+#content.browse .more-addons h3 a.view { display: inline; }
+
+.browse-list { list-style: none; margin: 0; width: 100%; overflow: auto; }
+.browse-list li { width: 48%; margin: 0 0 3px 1%; float: left; }
+.browse-list a { display: block; padding: 3px 5px; }
+
+#content.landing.languages .sub { width: 23.75%; margin-right: 2%; float: left; }
+#content.landing.languages #feature3 { margin-right: 0; }
+
+/*** =Dictionaries ***/
+#dictionaries { margin-top: 1.5em; clear: both; padding: 10px 15px; }
+#dictionaries table { width: 100%; }
+#dictionaries th, #dictionaries td { padding: 6px 12px; }
+
+/*** =Detail page ***/
+#addon-summary { padding-left: 240px; min-height: 270px; }
+#addon-summary .name { margin-bottom: 0; }
+#addon-summary .preview-img { position: absolute; left: -1px; top: 0; padding: 18px 0 0 20px;}
+#addon-summary.exp .preview-img, #addon-summary.rec .preview-img { padding-top: 2.5em; }
+#addon-summary .rating img { }
+#addon-summary .rating { position: absolute; left: 20px; top: 180px; width: 200px; text-align: center; line-height: 14px }
+#content-main #addon-summary .stats { position: absolute; text-align: center; left: 20px; top: 202px; width: 200px; margin-top: 3.5em; }
+
+#addon-summary .link-sharing { position: absolute; left: 60px; top: 218px; font-size: 0.75em; }
+#addon-summary .link-sharing .badge { }
+#addon-summary .link-sharing .badge .button { display: block;color: #062445; background: #7cc11c url("../img/sprite.png?20090430") -800px -730px no-repeat; }
+#addon-summary .link-sharing .badge .button a { display: block; padding: 0 8px 8px 0; background: transparent url(../img/installbtn-edges.png) no-repeat scroll right bottom; }
+#addon-summary .link-sharing .badge .button a span { display: block; text-align: center; font-weight: bold; padding: 2px 0 0 2px; background: transparent url(../img/installbtn-edges-list.png) no-repeat scroll left top; }
+
+#addon-summary .link-sharing .share-button { padding: 0; margin: 0; width: 100px; }
+#addon-summary .link-sharing .share-button:after, .install-container:after {content:".";clear:both;display:block;visibility:hidden;height:0;overflow:hidden;}
+#addon-summary .link-sharing .share-button a { float: left; cursor: pointer; max-width: 290px; text-decoration: none; }
+#addon-summary .link-sharing .share-button a * { display: block; float: left; position: relative; }
+#addon-summary .link-sharing .share-button a span { padding: 0 0 0 6px; }
+#addon-summary .link-sharing .share-button a span span { padding: 0 0 8px 0; }
+#addon-summary .link-sharing .share-button a span span span { left: -6px; padding: 0 0 0 0; }
+#addon-summary .link-sharing .share-button a span span span strong { width: 90px; text-align: center; right: -6px; padding: 0 18px 0 6px; }
+#addon-summary .link-sharing .share-button a span span span strong img {padding: 0 6px 0 0;}
+
+#addon-summary .link-sharing .share-button a { color: #062445; background: #7cc11c url("../img/sprite.png?20090430") -800px -730px no-repeat; }
+#addon-summary .link-sharing .share-button a span { background: transparent url("../img/installbtn-edges.png") left bottom no-repeat; }
+#addon-summary .link-sharing .share-button a span span { background: transparent url("../img/installbtn-edges.png") right bottom no-repeat; }
+#addon-summary .link-sharing .share-button a span span span { background: transparent url("../img/installbtn-edges.png") left top no-repeat; }
+#addon-summary .link-sharing .share-button a span span span strong { background: transparent url("../img/installbtn-edges.png") right top no-repeat; }
+
+#addon-summary .link-sharing .share-button a:hover, .install-button a:focus, .install-button a:active { color: #0a3b73; background-color: #9dd34c; background-position: -800px -860px; }
+
+#addon-summary .link-sharing .badge .counter { display: block; position: relative; padding-right: 4px; text-align: center; top: -4px; }
+
+#addon-summary .link-sharing .choices { display: none; position: absolute; z-index: 9999; left: -120px; top: 12px; width: 360px; background: transparent url(../img/box-pointer-top.png) center top no-repeat; padding-top: 12px; }
+#addon-summary .link-sharing .choices div { margin: 0; padding: 1em; background-color: #f8f8f8; border: 1px solid #657b86; -moz-border-radius: 6px; -webkit-border-radius: 6px; border-radius: 6px; }
+#addon-summary .link-sharing .choices ul { list-style: none; margin: 0; }
+#addon-summary .link-sharing .choices ul li { width: 50%; float: left; }
+#addon-summary .link-sharing .choices ul li p { padding: 0.25em; margin: 0 0.25em 0 0 }
+#addon-summary .link-sharing .choices ul li p a { font-weight: bold; display:block; height: 20px; text-decoration: none; padding-left: 22px; background: transparent url(../img/favicons/digg.gif) left top no-repeat }
+#addon-summary .link-sharing .choices ul li.digg p a { background-image: url(../img/favicons/digg.gif); }
+#addon-summary .link-sharing .choices ul li.facebook p a { background-image: url(../img/favicons/facebook.gif); }
+#addon-summary .link-sharing .choices ul li.delicious p a { background-image: url(../img/favicons/delicious.gif); }
+#addon-summary .link-sharing .choices ul li.myspace p a { background-image: url(../img/favicons/myspace.gif); }
+#addon-summary .link-sharing .choices ul li.friendfeed p a { background-image: url(../img/favicons/friendfeed.gif); }
+#addon-summary .link-sharing .choices ul li.reddit p a { background-image: url(../img/favicons/reddit.gif); }
+
+
+.addon-cats { margin-left: 0; }
+.addon-cats li { display: inline; padding-left: 1em; margin-right: .5em; }
+.addon-cats li:first-child { padding-left: 0; }
+
+#addon-info, #addon-advanced { padding: 8px 15px; margin-bottom: 1em; }
+.html-ltr #addon_app_compatibility {position:relative; top: .6em; padding-left: 22em; font-weight:bold}
+.html-rtl #addon_app_compatibility {position:relative; top: .6em; padding-right: 22em; font-weight:bold}
+.html-ltr #addon-info .app_compat {float: left}
+.html-rtl #addon-info .app_compat {float: right}
+#addon-info h4 { font-size: 147%; }
+
+.addon-images { margin: 1em auto 1.5em; }
+.addon-images li { display: inline; margin-right: 10px; }
+.addon-images a img { margin-bottom: 10px; }
+
+#addon-advanced { position: relative; }
+#addon-advanced h5 { margin-top: 1em; }
+
+/* =Reviews Page */
+#content .addon-reviews { margin-left: 0; }
+#content .addon-reviews blockquote { margin: 0; }
+#content .addon-reviews li { padding: 8px 10px; }
+#content .addon-reviews .cite { font-size: 95%; margin-bottom: 0; }
+
+#content-extra ul.nav-addon { list-style: none; margin-left: 0; padding-left: 0; }
+
+#content .review .others-by-user { font-style: italic; display: block; margin-top: 0.5em; font-size: 0.85em }
+#content .review .others-by-user a { padding-left: 22px; }
+#content .review .others-by-user a.loading { background: transparent url(../img/ajax_loading.gif) no-repeat 2px top }
+
+#content .others-by-user-load { padding-left: 3em; }
+
+#content .review-reply { margin-left: 3em; }
+
+#content .review p.flag-thanks, #content .review-reply p.flag-thanks { font-weight: bold }
+#content .review form.flag, #content .review-reply form.flag { display: block; padding-bottom: 1em }
+#content .review form.flag label, #content .review-reply form.flag label { display: block; font-weight: bold }
+
+.with-js #content .review p.flag-thanks, .with-js #content .review-reply p.flag-thanks { display: inline }
+.with-js #content .review form.flag, .with-js #content .review-reply form.flag { display: inline }
+.with-js #content .review form.flag label, .with-js #content .review-reply form.flag label { display: none; }
+
+#content .review .flag span.loading, #content .review-reply .flag span.loading { padding-left: 22px; background: transparent url(../img/ajax_loading.gif) no-repeat 2px top }
+
+#content ul.review-flags { padding: 1em 1em 0.5em 1em; list-style-type: square }
+#content ul.review-flags li { font-weight: bold; }
+#content ul.review-flags-notes { padding: 0.25em 0.5em; list-style-type: disc }
+#content ul.review-flags-notes li { font-weight: normal; }
+#content ul.review-flags-notes .note { font-style: italic }
+
+/* =Version History Page */
+#latest-version { width: 96%; float: left; margin-bottom: 1.5em; padding: 8px 2%; }
+#latest-version h3 { float: left; }
+#latest-version .install-button { float: right; margin-bottom: 0; }
+#content .addon-versions { margin-left: 0; padding-left: 0; list-style: none; }
+#content .addon-versions li { padding: 8px 10px 0; }
+#content .addon-versions h3 { margin-bottom: .5em; }
+
+/* For romanticized version - These rules will probably go away */
+#content .version-details, #content .version-links { list-style: none; margin-left: 0; padding-left: 0; }
+#content .version-details li, #content .version-links li { padding: 0; border: 0; }
+#content .version-links li { margin-bottom: .25em; }
+#content .version-details em, #content .version-links em { font-style: normal; color: #888; }
+
+/* =Review miniform */
+#form-review { position: relative; margin-bottom: 1em; padding: 10px; }
+#form-review textarea { width: 98%; margin: 0 auto .5em; }
+#form-review #review-submit { width: 100%; clear: both; margin-top: -1.5em; }
+#form-review .disabled {background: #eee;}
+#form-review h3 {display:inline;}
+#form-review .login {display:inline; font-size: 92%;}
+#form-review .login a:link, #form-review .login a:visited {text-decoration:none;}
+.html-ltr #form-review #review-submit { float: left;}
+.html-rtl #form-review #review-submit { float: right;}
+.html-ltr #form-review #review-submit input { float: right; }
+.html-rtl #form-review #review-submit input { float: left; }
+
+/* =reCaptchas */
+#recaptcha_image { margin: .5em 0; }
+
+/* =Star rating */
+
+#rate-it {
+ margin-bottom: 1em;
+}
+
+#rate-it h4 {
+ float:left;
+ width: 6em;
+ font-size: 110%;
+}
+
+.html-rtl #form-review #rate-it h4 {
+ float:right;
+}
+
+#rate-it .stars {
+ display:block;
+ float:left;
+ width: 90px;
+ margin: 0.3em 0 0 0;
+}
+
+#form-review #rate-it .degrade {
+ margin-left: 0;
+ width: 145px;
+}
+
+#form-review #rate-it .degrade p {
+ margin: .2em 0;
+}
+
+#rate-it .rating {
+ cursor: pointer;
+ margin: 2em;
+ clear: both;
+ display: block;
+}
+#rate-it .rating:after {
+ content: '.';
+ display: block;
+ height: 0;
+ width: 0;
+ clear: both;
+ visibility: hidden;
+}
+
+#long-review .stars {
+ margin: 0;
+}
+
+#long-review .degrade {
+ margin-left: 14em;
+}
+
+#long-review .stars p {
+ margin: 0.2em 0;
+}
+
+#long-review .rating {
+ margin: 1em 0;
+}
+
+/* =Base star styles*/
+.stars input {
+ margin: 0 4px;
+}
+
+.stars {
+ zoom:1;
+}
+
+.stars .cancel,
+.stars .star{
+ float: left;
+ width: 12px;
+ height: 14px;
+ overflow: hidden;
+ text-indent: -999em;
+ cursor: pointer;
+}
+
+.html-rtl .stars .star,
+.html-rtl .stars .cancel {
+ float:right;
+}
+
+.stars .cancel a,
+.stars .cancel a {
+ background: url(../img/ratings_images.gif) no-repeat;
+}
+
+.stars .star a,
+.stars .star a {
+ background: url(../img/ratings_images.gif) no-repeat;
+}
+
+.stars.cancel a,
+.stars .star a,
+.stars .cancel a,
+.stars .star a {
+ display: block;
+ width: 100%;
+ height: 100%;
+ background-position: 0 -25px;
+ border:1 solid #FF0000;
+}
+
+.stars .cancel a,
+.stars.cancel a {
+ background-position: 0 2px;
+}
+
+.stars div.star_hover a,
+.stars div.star_hover a {
+ background-position: 0 -38px;
+}
+
+.stars div.cancel_on a,
+.stars div.cancel_on a {
+ background-position: 0 -11px;
+}
+
+.stars div.star_on a,
+.stars div.star_on a {
+ background-position: 0 -38px;
+}
+
+.stars:after {
+ content:".";clear:both;display:block;visibility:hidden;height:0;overflow:hidden;
+}
+
+/* =Publish to collection from display page */
+#publish_to option:first-child {
+ display:none;
+}
+
+/* =More add-ons */
+.more-addons { padding: 10px; }
+.more-addons h3 a.view { display: block; padding-right: 30px; padding: .2em 30px .2em 0; }
+.more-addons h4 { margin-top: 1.5em; }
+#content.landing #content-extra .more-addons ul { margin-left: 0; }
+
+/*** =Pagination ***/
+.pagination { padding: 8px 10px 0; margin-top: 1em; }
+.pages { margin: 0; float: left; }
+.pages li { display: inline; margin: 0 2px; }
+.pages a { padding: 3px 6px; }
+.pages .prev a { padding-left: 15px; }
+.pages .next a { padding-right: 15px; }
+#content-main .pagination p.count { margin-bottom: 0; }
+.pagination p.perpage em, .pagination .perpage a { margin: 0; }
+
+/*** =Listing control bar ***/
+#form-listcontrol { position: relative; margin-bottom: 1em; padding: 8px 20% 8px 18%; }
+#form-listcontrol p, #form-listcontrol ul { margin: 0; }
+#form-listcontrol #per-page { position: absolute; top: 8px; left: 10px; padding-top: 6px; }
+#order-by li { display: inline; margin: 0 2px; }
+#order-by button { cursor: pointer; padding: 8px 2px; width: 18.5%; }
+#order-by button.current, #order-by button.current:hover { cursor: default; }
+#form-listcontrol #experimental { position: absolute; top: 8px; right: 10px; width: 140px; }
+#form-listcontrol #experimental label { display: block; cursor: pointer; padding: 4px 0 4px 30px; }
+#form-listcontrol #experimental label input { position: absolute; left: 6px; top: 20%; }
+
+
+/*** =Developer addon add agreement ***/
+#developerAgreement ul { list-style-type: disc; margin-top: 5px;}
+
+/*** =Thumbnail browser layout */
+#thumb-subcategories { position: absolute; left: 50px; top: 7.125em; width: 170px; }
+#thumb-subcategories ul { list-style-type: none; margin: 0; padding: 0; padding-bottom:6px; margin-bottom:1em; position:relative; }
+#thumb-subcategories ul li { padding-right:1px; overflow: hidden; }
+#thumb-subcategories ul li a, #thumb-subcategories ul li span { display: block; font-size: 95%; padding: .25em 10px; }
+
+#thumb-subcategories a:link, #thumb-subcategories a:visited { text-decoration: none; }
+
+#thumb-browser .thumbs { list-style-type:none; margin-left: 23%; }
+#thumb-browser .thumbs li.thumb { position: relative; width: 170px; margin-right: 10px; display: inline; float: left; text-align: center; }
+#thumb-browser .thumbs li.thumb div.wrapper { padding: 1.75em 9px 0px 9px; margin: 0 5px 0 0; }
+#thumb-browser .thumbs li.thumb div.wrapper div.item { width: 150px; }
+
+#thumb-browser .thumbs li.thumb div.img { border: 1px solid #ccc; background: #fff; height: 112px; overflow: hidden; }
+#thumb-browser .thumbs li.thumb div.img img { width: 150px; }
+#thumb-browser .thumbs li.thumb h3 { font-size: 115%; line-height: 115%; height: 2.25em; overflow: hidden; padding-top: 0.5em; margin-bottom: 0.5em; }
+#thumb-browser .thumbs li.thumb .flag { position: absolute; top: 0; left: 0; padding: 0 6px; }
+#thumb-browser .thumbs li.thumb p.meta { margin-bottom: 0; padding: 0; height: 3.5em; overflow: hidden; }
+#thumb-browser .thumbs li.thumb .vex { text-align: left; height: 8px; }
+#thumb-browser .thumbs li.thumb .vex span { display:block; height: 8px; margin-left:0px; }
+
+#thumb-browser #form-listcontrol { margin-left: 20%; padding: 8px 12% 8px 15%; }
+#thumb-browser #form-listcontrol #order-by button { white-space: nowrap; width: 16.5% }
+
+#slider { margin-bottom: 18px; width: 100%; background:transparent url(../img/sprite.png?20090430) no-repeat scroll left -1256px; }
+#slider .inner { background:transparent url(../img/sprite.png?20090430) no-repeat scroll right -1256px; width: 100%; }
+#slider .viewport { position: relative; width: 100%; overflow: hidden; }
+#slider .item_set { width: 6000px; }
+#slider .item_set .addon { float: left; width: 308px; }
+#slider .item_set li.addon { list-style: none; }
+#slider .item_set .addon .preview-img { background: transparent url(../img/sprite.png?20090430) no-repeat 1px -1256px }
+#slider .item_set .addon { background: none; border-left: none }
+#slider .item_set .addon .install-container { height: 85px; }
+#slider .item_set .addon .install-button { padding-top: 1.75em; padding-left: .5em; }
+#slider .item_set .addon .exp-loggedout .install-button,
+#slider .item_set .addon .exp-confirmed .install-button { padding-top: 0; padding-left: 0; }
+#slider .item_set .addon .count { border-top:1px solid #CCCCCC; bottom:4px; height:35px; margin-left:-240px; position:absolute; }
+#slider .controls { border-top: 1px solid #ccc; width: 100%; }
+#slider .controls_inner { font-size: 140%; text-align: center; padding-top: 6px; border-left: 1px solid #ccc; border-right: 1px solid #ccc }
+#slider .controls a { text-decoration: none; padding: 0 0.5em; }
+#slider .controls a img { border: none; vertical-align: top }
+#slider .vex { background: transparent url("../img/sprite.png?20090430") right bottom no-repeat; width: 100%; }
+.html-rtl #slider .vex { direction: ltr; }
+#slider .vex span { background: transparent url("../img/sprite.png?20090430") left bottom no-repeat; height: 10px; display: block; width: 10px; }
+
+
+/* translation box */
+.graybox {
+ background-color: #F7FAFC;
+ border: 1px solid #EEF1F3;
+ padding: 15px;
+}
+.graybox.errors {
+ background-color: #FFA5A5;
+}
+.graybox.spaced {
+ margin-bottom: 10px;
+}
+.rounded {
+ -moz-border-radius: 6px;
+ -webkit-border-radius: 6px;
+ border-radius: 6px;
+}
+.translation-box h4 {
+ border-bottom: 1px solid #2D3B58;
+}
+.translation-box h4 img {
+ float: right;
+ margin-top: 3px;
+}
+.html-rtl .translation-box h4 img {
+ float: left;
+}
+.translation-box .translation-button img {
+ cursor: pointer;
+ float: left;
+ background-color: #EEEEEE;
+ border: 1px solid #EEEEEE;
+ border-bottom: none;
+ padding: 2px 5px 3px;
+ margin: 5px 0 0 10px;
+ height: 1.5em;
+ -moz-border-radius-topleft: 6px;
+ -moz-border-radius-topright: 6px;
+ -webkit-border-top-left-radius: 6px;
+ -webkit-border-top-right-radius: 6px;
+}
+.html-rtl .translation-box .translation-button img {
+ float: right;
+ margin: 5px 10px 0 0;
+}
+.translation-box .translation-button.remove img {
+ float: right;
+}
+.html-rtl .translation-box .translation-button.remove img {
+ float: left;
+}
+.translation-box .translation-button img:hover {
+ background-color: #E4F3FA;
+}
+.translation-box .translation-tab {
+ float: left;
+ margin-right: 2px;
+ background-color: #DDDDDD;
+ text-align: center;
+ padding: 5px;
+ -moz-border-radius-topleft: 6px;
+ -moz-border-radius-topright: 6px;
+ -webkit-border-top-left-radius: 6px;
+ -webkit-border-top-right-radius: 6px;
+ width: 3.1em;
+ height: 1.5em;
+ cursor: pointer;
+ border-bottom: 1px solid #FFFFFF;
+}
+.html-rtl .translation-box .translation-tab {
+ float: right;
+ margin-right: auto;
+ margin-left: 2px;
+}
+.translation-box .translation-tab.selected {
+ border: 1px solid #1D587F;
+ background-color: #DDDDFF;
+ border-bottom: none;
+ color: #1D587F;
+}
+.translation-box .translation-tab:hover {
+ text-decoration: underline;
+}
+.translation-box .translation-area {
+ clear: both;
+ margin: 0;
+}
+.translation-box .translation-maxlength {
+ text-align: right;
+ display: none;
+}
+.html-rtl .translation-box .translation-maxlength {
+ text-align: left;
+}
+.translation-box .translation-maxlength.selected {
+ display: block;
+}
+.translation-box .translation-maxlength img {
+ display: none;
+}
+.translation-box .translation-maxlength.over {
+ color: #CC3333;
+}
+.translation-box .translation-maxlength.over img {
+ display: inline;
+ vertical-align: middle;
+}
+.translation-box .translation-maxlength span {
+ font-weight: bold;
+}
+.translation-box .input {
+ border: 1px solid #1D587F;
+ margin: 0;
+ -moz-border-radius-bottomleft: 6px;
+ -moz-border-radius-bottomright: 6px;
+ -webkit-border-bottom-left-radius: 6px;
+ -webkit-border-bottom-right-radius: 6px;
+ width: 100%;
+ display: none;
+}
+.translation-box .input.selected {
+ display: block;
+}
+.translation-newlocale-container,
+.translation-deletelocale-container,
+.translation-help-container,
+.translation-error-container {
+ display: none;
+}
+.translation-newlocale,
+.translation-deletelocale {
+ border: 1px solid #1D587F;
+ margin: 0;
+ -moz-border-radius-bottomleft: 6px;
+ -moz-border-radius-bottomright: 6px;
+ -webkit-border-bottom-left-radius: 6px;
+ -webkit-border-bottom-right-radius: 6px;
+ width: 100%;
+ height: 100px;
+ display: none;
+}
+.translation-deletelocale.textarea {
+ position: absolute;
+ z-index: 10;
+}
+.translation-newlocale.selected,
+.translation-deletelocale {
+ display: block;
+}
+.translation-newlocale .padded,
+.translation-deletelocale .padded,
+.translation-help .padded {
+ padding: 15px;
+}
+.translation-newlocale .buttons,
+.translation-deletelocale .buttons {
+ text-align: center;
+ margin: 10px;
+}
+.translation-help {
+ background-color: #FFFFFF;
+ margin-bottom: 10px;
+ width: 630px;
+ display: none;
+}
+.graybox .error-message {
+ background: transparent url('../img/developers/exclamation.png') no-repeat 5px 50%;
+ color: red;
+ padding: 5px 0 5px 30px;
+}
+.html-rtl .graybox .error-message {
+ background-position: 100% 50%;
+ padding: 5px 25px 5px 0;
+}
+
+
+/** Collections normal view **/
+#content .addon-listing .date-added {
+ margin: 0;
+ float: right;
+}
+
+#content .coll-addon .preview-img {
+ margin: 0;
+}
+
+.collections .nav {
+ list-style-type: none;
+ margin: 0;
+ padding: 0;
+ float: right;
+}
+
+.collections .nav:after {
+ float: left;
+}
+
+.collections .nav li {
+ float: left;
+ margin: 5px;
+}
+
+.collections .collections-web li.coll-addon {
+ margin: 0;
+}
+
+/* bandwagon collections: interactive collections template */
+.collections p.amo-plug {
+ float: right;
+ -moz-border-radius: 7px;
+ border: 1px solid #d8dcdf;
+ padding: 5px;
+}
+
+.collections #content-main h1 {
+ font-size: 200%;
+}
+
+.collections .cat-name {
+ margin-left: .3em;
+}
+
+.collections .cat-header h3 {
+ background: transparent url(../img/fyf/triangle-right.png) scroll no-repeat left 5px;
+ padding-left: 20px;
+ margin-right: .4em;
+}
+
+.collections .cat-header.selected h3 {
+ background: transparent url(../img/fyf/triangle-down.png) scroll no-repeat left 5px;
+}
+
+.collections #content-main .cat-header p {
+ margin: 0;
+ margin-left: 20px;
+ padding-right: 5px;
+}
+
+.collections ul.addon-listing {
+ padding: 0;
+ margin: 0;
+}
+
+.collections ul.addon-install-listing {
+ max-height: 30em;
+ overflow: auto;
+}
+
+.collections li.list-addon:after,.collections .coll-addon .preview-img:after,.collections .nav:after,#collectionform:after {
+ content: '.';
+ clear: both;
+ display: block;
+ line-height: 0;
+ visibility: hidden;
+ width: 0;
+ height: 0;
+}
+
+.collections li.coll-addon {
+ margin: .2em 2em .2em 2em;
+ padding: .5em 0;
+ border-top: 1px solid #ccc;
+}
+
+.collections li.inst-addon {
+ margin: .5em 0;
+ padding: .5em;
+}
+
+.collections .coll-addon .preview-img {
+ max-width: 12em;
+ float: left;
+ clear: both;
+}
+
+.collections .coll-addon .preview-img img {
+ float: left;
+ clear: both;
+ margin: .5em 1em 0 0;
+ max-width: 12em;
+ max-height: 9em;
+}
+
+.collections .list-addon h4 {
+ color: #2d3b58;
+ font-size: 140%;
+}
+
+.collections .inst-addon .desc h4 {
+ width: auto;
+ float: none;
+}
+
+.collections .list-addon .desc {
+ width: 81%;
+ margin: .2em 0 0 0;
+ float: left;
+}
+
+.collections .list-addon img.icon {
+ float: left;
+ margin-right: .5em;
+ vertical-align: middle;
+}
+
+.collections .inst-addon .desc {
+ float: left;
+ width: auto;
+ margin: 0;
+}
+
+.collections .inst-addon .desc p {
+ font-size: 90%;
+ float: left;
+}
+
+.collections .coll-addon h4 a {
+ text-decoration: none;
+}
+
+.collections .list-addon .add-button,.collections .coll-addon .done-box {
+ -moz-border-radius: 7px;
+ padding: 5px 10px;
+ float: right;
+}
+
+.collections .list-addon .add-button,.collections .coll-addon .done-box {
+ min-width: 160px;
+}
+
+.collections .list-addon .done-box {
+ display: none;
+ clear: right;
+}
+
+.collections .list-addon .add-button {
+ background: transparent url(../img/installbtn-bg.png) repeat-x top left;
+}
+
+.collections .coll-addon .add-button {
+ font-weight: bold;
+}
+
+.collections .inst-addon .add-button {
+ margin: 1em 1em 0 2em;
+ min-width: 15%;
+}
+
+.collections .add-button .add,.collections .add-button input {
+ vertical-align: middle;
+ cursor: pointer;
+}
+
+.collections .add-button .add {
+ color: #062445;
+}
+
+.collections .add-button.upgrade {
+ background: #fff;
+ border: 1px solid #d8dcdf;
+ font-size: 125%;
+}
+
+.collections #content-main .add-button p {
+ margin: 0;
+ font-weight: normal;
+}
+
+.collections .done-box {
+ margin-top: .5em;
+ border: 1px solid #d8dcdf;
+}
+
+.collections .installsubmit {
+ margin: 1em 0;
+ float: right;
+}
+
+.collections .installsubmit input {
+ font-size: 120%;
+ margin: 0 .5em;
+}
+
+.collections .faq {
+ float: right;
+ text-align: right;
+}
+
+/* jqModal base Styling courtesy of Brice Burgess <bhb@iceburg.net> */
+
+/* The Window's CSS z-index value is respected (takes priority). If none is supplied,
+ the Window's z-index value will be set to 3000 by default (via jqModal.js). */
+.jqmWindow {
+ display: none;
+ position: fixed;
+ top: 17%;
+ left: 50%;
+ margin-left: -400px;
+ width: 800px;
+ background-color: #efefef;
+ color: #333;
+ border: 1px solid black;
+ padding: 12px;
+}
+
+.jqmOverlay {
+ background-color: #000;
+}
+
+
+
+/* Background iframe styling for IE6. Prevents ActiveX bleed-through (<select> form elements, etc.) */
+* iframe.jqm {
+ position: absolute;
+ top: 0;
+ left: 0;
+ z-index: -1;
+ width: expression(this.parentNode.offsetWidth+'px');
+ height: expression(this.parentNode.offsetHeight+'px');
+}
+* html .jqmWindow {
+ position: absolute;
+ top: expression((document.documentElement.scrollTop || document.body.scrollTop)+Math.round(17 *(document.documentElement.offsetHeight || document.body.clientHeight) / 100)+'px');
+}
+
+#content.landing {
+ width: 995px;
+}
+
+#content.landing .crumbs a {
+ color: #5086b6;
+}
+#content.landing .categories {
+ position: relative;
+ clear: both;
+ border: none;
+ z-index: 3000;
+}
+
+#content.landing .categories h3 {
+ display: inline;
+ font-size: 189%;
+ padding:0 0 0 10px
+}
+.html-rtl #content.landing .categories h3 {
+ padding: 0 10px 0 0;
+}
+
+#content.landing .categories .selection .current {
+ font-size: 250%;
+ padding: 0;
+ margin: 5px 0 0 0;
+ font-weight: normal;
+ display: inline;
+ padding: 0 3px 0 0;
+
+}
+.html-rtl #content.landing .categories .selection .current {
+ padding: 0 0 0 3px;
+}
+#content.landing .categories .selection .current a {
+ text-decoration: none;
+ color: #5086b6;
+ background: none;
+ display: inline;
+ padding: 0;
+
+}
+#content.landing .categories .selection .current a:hover {
+ color: #000;
+
+}
+#content.landing .categories .selection .current .all {
+ display: inline;
+ padding: 4px;
+ background: url('../img/sprite.png?20090430') left -444px no-repeat;
+
+}
+#content.landing .categories .selection .current a:hover .all {
+ background: url('../img/sprite.png?20090430') left -498px no-repeat;
+}
+
+#content.landing .categories.open .current a .all {
+ background: url('../img/sprite.png?20090430') left -498px no-repeat;
+}
+
+#content.landing .categories h3.featured_title {
+ float: left;
+ font-size: 24px;
+ padding: 0 0 0 0.5em; margin: 0;
+}
+#content.landing .categories h3.featured_title span {
+ font-size: 20px;
+}
+#content.landing .categories .selections {
+ background-color: #fff;
+ width: 410px;
+ list-style: none;
+ margin: 0;
+ padding: 6px;
+ -moz-box-shadow: 4px 7px 7px 2px #888888;
+ -webkit-box-shadow: 4px 7px 7px 2px #888888;
+ box-shadow: 4px 7px 7px 2px #888888;
+}
+.html-rtl #content.landing .categories .selections {
+ -moz-box-shadow: -4px 7px 7px 2px #888888;
+ -webkit-box-shadow: -4px 7px 7px 2px #888888;
+ box-shadow: -4px 7px 7px 2px #888888;
+}
+
+#content.landing .categories.degrade .selections {
+ border-left: 1px solid #888888;
+ border-right: 1px solid #888888;
+ border-bottom: 1px solid #888888;
+}
+
+#content.landing .categories.closed .selections {
+ position: absolute;
+ top: -1000px;
+ left: -100000px;
+}
+.html-rtl #content.landing .categories.closed .selections {
+ left: auto;
+ right: -100000px;
+}
+
+#content.landing .categories.open .selections {
+ position: absolute;
+ left: -3px;
+ top: 3.3em;
+ z-index: 999;
+ -moz-column-count: 2;
+ column-count: 2;
+}
+.html-rtl #content.landing .categories.open .selections {
+ left: auto;
+ right: -3px;
+}
+
+#content.landing .categories.open h2.current {
+ -moz-box-shadow: 2px 2px 7px 0 #888888;
+ -webkit-box-shadow: 2px 2px 7px 0 #888888;
+ box-shadow: 2px 2px 7px 0 #888888;
+ margin: 2px 0 -3px -3px;
+ padding: 3px;
+}
+.html-rtl #content.landing .categories.open h2.current {
+ -moz-box-shadow: -2px 2px 7px 0 #888888;
+ -webkit-box-shadow: -2px 2px 7px 0 #888888;
+ box-shadow: -2px 2px 7px 0 #888888;
+ margin: 2px -3px -3px 0;
+ padding: 3px;
+}
+
+#content.landing .categories.open.degrade {
+ margin: 0 0 12px 0;
+}
+
+#content.landing .categories.open.degrade h2.current {
+ border-top: 1px solid #888888;
+ border-left: 1px solid #888888;
+ border-right: 1px solid #888888;
+ margin: 5px -2px 5px -3px;
+}
+
+#content.landing .categories.open.degrade .header {
+ background:#888888 none repeat scroll 0 0;
+ display:block;
+ height:1px;
+ left:273px;
+ line-height:0;
+ position:absolute;
+ top:39px;
+ padding: 0;
+}
+
+#content.landing .categories.open .current a {
+ color: #000000;
+}
+
+#content.landing .categories .selections li {
+ border: none;
+ padding: 0;
+}
+#content.landing .categories .selections li a {
+ display: block;
+ padding: 1px 1px 1px 5px;
+ margin: 0 4px 0 0;
+ text-decoration: none;
+ color: #000;
+ background: none;
+}
+.html-rtl #content.landing .categories .selections li a {
+ padding: 1px 5px 1px 1px;
+ margin: 0 0 0 4px;
+}
+#content.landing .categories .selections li a:hover {
+ background: #ddd;
+}
+#content.landing .search {
+ /* TODO */
+ display: none;
+}
+#featured_addons {
+ width: 995px;
+ z-index: 2;
+ position: relative;
+}
+#featured_addons ul {
+ list-style-type: none;
+ margin: 0; padding: 0;
+}
+#featured_addons ul li {
+ display: block;
+ float: left;
+ margin: 0; padding: 0 8px 8px 0;
+}
+.html-rtl #featured_addons ul li {
+ float: right;
+ padding: 0 0 8px 8px;
+}
+#featured_addons ul li div.addon_block
+{
+ display: block;
+ position: relative;
+ background: #f9f9f9 url(../img/sprite.png?20090430) no-repeat scroll left -968px;
+ width: 299px;
+ height: 200px;
+ overflow: hidden;
+ border: 1px solid #ececec;
+ -moz-border-radius-topleft: 8px;
+ -moz-border-radius-topright: 8px;
+ -moz-border-radius-bottomleft: 8px;
+ -moz-border-radius-bottomright: 8px;
+ -webkit-border-top-left-radius: 8px;
+ -webkit-border-top-right-radius: 8px;
+ -webkit-border-bottom-left-radius: 8px;
+ -webkit-border-bottom-right-radius: 8px;
+ border-top-right-radius: 8px;
+ border-top-left-radius: 8px;
+ border-bottom-right-radius: 8px;
+ border-bottom-left-radius: 8px;
+ padding: 0 0 0 9px;
+}
+.html-rtl #featured_addons ul li div.addon_block {
+ padding: 0 9px 0 0;
+}
+#featured_addons ul li div.addon_block .name {
+ font-size: 138%;
+ margin: 8px 155px 0px 0;
+ line-height: 1.25em;
+}
+.html-rtl #featured_addons ul li div.addon_block .name {
+ margin: 8px 0 0 155px;
+}
+#featured_addons ul li div.addon_block .name a {
+ color: black;
+ text-decoration: none;
+}
+
+#featured_addons ul li div.addon_block .preview {
+ position: absolute;
+ top: 8px; right: 9px;
+}
+.html-rtl #featured_addons ul li div.addon_block .preview {
+ right: auto;
+ left: 9px;
+}
+#featured_addons ul li div.addon_block .preview img {
+ width: 138px;
+}
+
+#featured_addons ul li div.addon_block .summary {
+ font-size: 93%;
+ line-height: 1.5em;
+ margin: 0px 149px 0px 0px;
+ max-height: 4.5em;
+ overflow: hidden;
+}
+.html-rtl #featured_addons ul li div.addon_block .summary {
+ margin: 0 0 0 149px;
+}
+
+#featured_addons ul li div.addon_block .authors {
+ font-size: 100%;
+ line-height: 1.5em;
+ margin: 0 145px 0 0;
+ color: #2363a5;
+}
+.html-rtl #featured_addons ul li div.addon_block .authors {
+ margin: 0 0 0 145px;
+}
+#featured_addons ul li div.addon_block .authors a {
+ text-decoration: none;
+ /*
+ white-space: nowrap;
+ */
+}
+#featured_addons ul li div.addon_block .rating {
+ font-size: 10px;
+ overflow: hidden;
+ margin: 2px 0 0 0;
+}
+.rating span {
+ display: block;
+ background: transparent url(../img/ratings/5stars.png) no-repeat scroll top left;
+ width: 68px; height: 12px;
+ text-indent: -1000em;
+}
+span.rating-1 {
+ background-image: url(../img/ratings/1stars.png)
+}
+span.rating-2 {
+ background-image: url(../img/ratings/2stars.png)
+}
+span.rating-3 {
+ background-image: url(../img/ratings/3stars.png)
+}
+span.rating-4 {
+ background-image: url(../img/ratings/4stars.png)
+}
+span.rating-5 {
+ background-image: url(../img/ratings/5stars.png)
+}
+
+#featured_addons div.addon_block .install-container {
+ position: absolute;
+ left: 7px;
+ bottom: 7px;
+}
+.html-rtl #featured_addons div.addon_block .install-container {
+ left: auto;
+ right: 7px;
+}
+
+#featured_addons div.addon_block .install-container .install-button a {
+ background-position: 100% -736px;
+}
+
+#featured_addons div.addon_block .install-container .exp-loggedout .install-button a {
+ background-position:100% -1002px;
+}
+
+#featured_addons div.addon_block .install-container .install-button a span span {
+ padding:0 0 8px;
+}
+
+#featured_addons div.addon_block .install-container .install-button a span span span strong {
+ padding:3px 45px 0 6px;
+}
+
+#featured_addons div.addon_block .install-container .install-button a span span span {
+ padding: 0;
+}
+
+#featured_addons div.addon_block .install-container .install-button a:hover, .install-button a:focus,
+#featured_addons div.addon_block .install-container .install-button a:active {
+ color: #0a3b73; background-color: #9dd34c; background-position: 100% -866px;
+}
+
+#featured_addons div.addon_block .install-container .exp-loggedout .install-button a:hover,
+#featured_addons div.addon_block .install-container .exp-loggedout .install-button a:hover {
+ background-color: #f3f3f3; background-position: 100% -1132px;
+ color: #aaa;
+}
+
+#content.landing div.addons_column {
+ float: left;
+ padding: 0 9px 8px 0;
+}
+.html-rtl #content.landing div.addons_column {
+ float: right;
+ padding: 0 0 8px 9px;
+}
+
+#content.landing div.addons_column.last {
+ float: left;
+ padding: 0 0 8px 0;
+}
+#content.landing div.addons_column.last {
+ float: right;
+}
+
+#content.landing div.addons_column h3 {
+ background: #acacac;
+ width: 309px;
+ -moz-border-radius-topleft: 8px;
+ -moz-border-radius-topright: 8px;
+ -webkit-border-top-left-radius: 8px;
+ -webkit-border-top-right-radius: 8px;
+ border-top-right-radius: 8px;
+ border-top-left-radius: 8px;
+}
+#content.landing div.addons_column h3 span {
+ padding: 0 8px 0 8px;
+ text-transform: uppercase;
+ font-size: 14px;
+ color: #fff;
+ font-weight: bold;
+}
+#content.landing div.addons_column ul {
+ width: 309px;
+ list-style: none;
+ margin: 0;
+ padding: 0;
+}
+#content.landing div.addons_column ul li {
+ position: relative;
+ border-left: 1px solid #c9c8c9;
+ border-right: 1px solid #c9c8c9;
+ margin: 0;
+
+}
+#content.landing div.addons_column ul li.odd {
+}
+#content.landing div.addons_column ul li.even {
+ background: #f0efef;
+}
+#content.landing div.addons_column ul li a {
+ height: 44px;
+ display: block;
+ text-decoration: none;
+ border: 1px solid transparent;
+ background: transparent url(../img/sprite.png?20090430) no-repeat scroll 287px -558px;
+}
+.html-rtl #content.landing div.addons_column ul li a {
+ background-position: -363px -558px;
+}
+#content.landing div.addons_column ul li a:hover {
+ border-top: 1px solid #000;
+ border-left: 1px solid #000;
+ border-bottom: 1px solid #000;
+ background: transparent url(../img/sprite.png?20090430) no-repeat scroll 287px -670px;
+}
+.html-rtl #content.landing div.addons_column ul li a:hover {
+ border-left: 1px solid transparent;
+ border-right: 1px solid #000;
+ background-position: -363px -670px;
+}
+#content.landing div.addons_column ul li a img.icon {
+ position: absolute;
+ top: 6px; left: 6px;
+}
+.html-rtl #content.landing div.addons_column ul li a img.icon {
+ left: auto;
+ right: 6px;
+}
+#content.landing div.addons_column ul li a .name {
+ display: block;
+ padding: 4px 15px 0 0;
+ margin-left: 46px;
+ color: #000;
+ font-size: 116%;
+ line-height: 1.25em;
+ height: 1.25em;
+ overflow: hidden;
+}
+.html-rtl #content.landing div.addons_column ul li a .name {
+ padding: 4px 0 0 15px;
+ margin-left: 0;
+ margin-right: 46px;
+}
+
+#content.landing div.addons_column ul li a .rating {
+ margin-left: 46px;
+ display: block;
+}
+.html-rtl #content.landing div.addons_column ul li a .rating {
+ margin-left: 0;
+ margin-right: 46px;
+}
+
+#content.landing div.addons_column ul li a .meta {
+ display: block;
+ margin-left: 46px;
+ font-size: 93%;
+ color: #777;
+ position: absolute;
+ bottom: 6px;
+}
+.html-rtl #content.landing div.addons_column ul li a .meta {
+ margin-left: 0;
+ margin-right: 46px;
+}
+
+#content.landing div.addons_column .view-all {
+ color: #fff;
+ font-weight: bold;
+ background: #acacac;
+ -moz-border-radius-bottomleft: 8px;
+ -moz-border-radius-bottomright: 8px;
+ -webkit-border-bottom-left-radius: 8px;
+ -webkit-border-bottom-right-radius: 8px;
+ border-bottom-right-radius: 8px;
+ border-bottom-left-radius: 8px;
+ padding: 2px 0 2px 9px;
+
+}
+.html-rtl #content.landing div.addons_column .view-all {
+ padding: 2px 9px 2px 0;
+}
+
+#content.landing div.addons_column .view-all a:link,
+#content.landing div.addons_column .view-all a:visited,
+#content.landing div.addons_column .view-all a:hover,
+#content.landing div.addons_column .view-all a:active {
+ color: #fff;
+ text-decoration: none;
+ font-size: 93%;
+}
+
+#content.landing div.addons_column .view-all a:hover {
+ text-decoration: underline;
+}
+
+.clearfix:after {
+ content: ".";
+ display: block;
+ clear: both;
+ visibility: hidden;
+ line-height: 0;
+ height: 0;
+}
+
+.clearfix {
+ display: inline-block;
+}
+
+html[xmlns] .clearfix {
+ display: block;
+}
+
+* html .clearfix {
+ height: 1%;
+}
+
+/* notification box element */
+.notification-box {
+ border: 1px solid;
+ display: block;
+ padding: 10px;
+}
+.notification-box.warning {
+ border-color: red;
+ background-color: #FFA5A5;
+}
+
+/* Bandwagon: "add" page */
+.collections #addonname {
+ width: 200px;
+}
+.collections #selectedaddons {
+ width: 80%;
+ overflow: auto;
+ max-height: 300px;
+}
+.collections #selectedaddons > ul {
+ -moz-column-count: 2;
+}
+.collections #firstaddons {
+ display: none; /* shown with JS */
+}
+
+/* Bandwagon: add-on autocomplete */
+.ac_input {
+ width: 400px;
+}
+.ac_results {
+ padding: 0px;
+ border: 1px solid WindowFrame;
+ background-color: Window;
+ overflow-x: hidden;
+ overflow-y: auto;
+ max-height: 400px;
+}
+
+.ac_results ul {
+ width: 100%;
+ list-style-position: outside;
+ list-style: none;
+ padding: 0;
+ margin: 0;
+}
+
+.ac_results iframe {
+ display:none;/*sorry for IE5*/
+ display/**/:block;/*sorry for IE5*/
+ position:absolute;
+ top:0;
+ left:0;
+ z-index:-1;
+ filter:mask();
+ width:3000px;
+ height:3000px;
+}
+
+.ac_results li {
+ margin: 0px;
+ padding: 2px 5px;
+ cursor: pointer;
+ display: block;
+ width: 100%;
+ font: menu;
+ font-size: 12px;
+ overflow: hidden;
+}
+.ac_loading {
+ background : url('../img/ajax_loading.gif') right center no-repeat;
+}
+.ac_over {
+ background-color: Highlight;
+ color: HighlightText;
+}
+/** collections edit page */
+#coll-edit .jsonly {
+ display: none;
+}
+#coll-edit .error, #coll-edit .error_message {
+ color: #f00;
+}
+#coll-edit .coll-addon {
+ padding-bottom: 10px;
+ margin-bottom: 10px;
+ border-bottom: solid 1px #ddd;
+}
+#coll-edit .coll-addon .name {
+ font-weight: bold;
+}
+#coll-edit .coll-addon .added {
+ float: right;
+ font-style: italic;
+}
+#coll-edit .coll-addon a.removeaddon {
+ float: right;
+}
+#collections input#submitbutton {
+ margin: 10px;
+}
diff --git a/site/app/webroot/css/simile/bundle.css b/site/app/webroot/css/simile/bundle.css
new file mode 100644
index 0000000..ebb1d50
--- /dev/null
+++ b/site/app/webroot/css/simile/bundle.css
@@ -0,0 +1,269 @@
+.timeline-ether-marker-bottom {
+ width: 5em;
+ height: 1.5em;
+ border-left: 1px solid #aaa;
+ padding-left: 2px;
+ color: #aaa;
+}
+
+.timeline-ether-marker-bottom-emphasized {
+ width: 5em;
+ height: 2em;
+ border-left: 1px solid #aaa;
+ padding-left: 2px;
+ color: black;
+}
+
+.timeline-ether-marker-top {
+ width: 5em;
+ height: 1.5em;
+ border-left: 1px solid #aaa;
+ padding-left: 2px;
+ color: #aaa;
+}
+
+.timeline-ether-marker-top-emphasized {
+ width: 5em;
+ height: 2em;
+ border-left: 1px solid #aaa;
+ padding-left: 2px;
+ color: black;
+}
+
+
+.timeline-ether-marker-right {
+ width: 5em;
+ height: 1.5em;
+ border-top: 1px solid #aaa;
+ padding-top: 2px;
+ color: #aaa;
+}
+
+.timeline-ether-marker-right-emphasized {
+ width: 7em;
+ height: 1.5em;
+ border-top: 1px solid #aaa;
+ padding-top: 2px;
+ color: black;
+}
+.timeline-ether-marker-left {
+ width: 5em;
+ height: 1.5em;
+ border-top: 1px solid #aaa;
+ padding-top: 2px;
+ color: #aaa;
+}
+
+.timeline-ether-marker-left-emphasized {
+ width: 7em;
+ height: 1.5em;
+ border-top: 1px solid #aaa;
+ padding-top: 2px;
+ color: black;
+}
+.timeline-duration-event {
+ position: absolute;
+ overflow: hidden;
+ border: 1px solid blue;
+}
+
+.timeline-instant-event2 {
+ position: absolute;
+ overflow: hidden;
+ border-left: 1px solid blue;
+ padding-left: 2px;
+}
+
+.timeline-instant-event {
+ position: absolute;
+ overflow: hidden;
+}
+
+.timeline-event-bubble-title {
+ font-weight: bold;
+ border-bottom: 1px solid #888;
+ margin-bottom: 0.5em;
+}
+
+.timeline-event-bubble-body {
+}
+
+.timeline-event-bubble-wiki {
+ margin: 0.5em;
+ text-align: right;
+ color: #A0A040;
+}
+.timeline-event-bubble-wiki a {
+ color: #A0A040;
+}
+
+.timeline-event-bubble-time {
+ color: #aaa;
+}
+
+.timeline-event-bubble-image {
+ float: right;
+ padding-left: 5px;
+ padding-bottom: 5px;
+}
+
+.timeline-container {
+ position: relative;
+ overflow: hidden;
+}
+
+.timeline-copyright {
+ position: absolute;
+ bottom: 0px;
+ left: 0px;
+ z-index: 1000;
+ cursor: pointer;
+}
+
+.timeline-message-container {
+ position: absolute;
+ top: 30%;
+ left: 35%;
+ right: 35%;
+ z-index: 1000;
+ display: none;
+}
+.timeline-message {
+ font-size: 120%;
+ font-weight: bold;
+ text-align: center;
+}
+.timeline-message img {
+ vertical-align: middle;
+}
+
+.timeline-band {
+ position: absolute;
+ background: #eee;
+ z-index: 10;
+}
+
+.timeline-band-inner {
+ position: relative;
+ width: 100%;
+ height: 100%;
+}
+
+.timeline-band-input {
+ position: absolute;
+ width: 1em;
+ height: 1em;
+ overflow: hidden;
+ z-index: 0;
+}
+.timeline-band-input input{
+ width: 0;
+}
+
+.timeline-band-layer {
+ position: absolute;
+ width: 100%;
+ height: 100%;
+}
+
+.timeline-band-layer-inner {
+ position: relative;
+ width: 100%;
+ height: 100%;
+}
+
+.timeplot-container {
+ overflow: hidden;
+ position: relative;
+ /*height: 200px;*/
+ border: 1px solid #ccc;
+ padding: 12px 14px;
+}
+
+.timeplot-copyright {
+ position: absolute;
+ top: 0px;
+ left: 0px;
+ z-index: 1000;
+ cursor: pointer;
+}
+
+.timeplot-message-container {
+ position: absolute;
+ top: 30%;
+ left: 35%;
+ right: 35%;
+ max-width: 400px;
+ z-index: 1000;
+ display: none;
+}
+.timeplot-message {
+ font-size: 120%;
+ font-weight: bold;
+ text-align: center;
+}
+.timeplot-message img {
+ vertical-align: middle;
+}
+
+.timeplot-div {
+ position: absolute;
+}
+
+.timeplot-grid-label {
+ font-size: 9px;
+}
+
+.timeplot-event-box {
+ cursor: pointer;
+}
+
+.timeplot-event-box-highlight {
+ border: 1px solid #FFB03B;
+}
+
+.timeplot-valueflag {
+ display: none;
+ border: 1px solid #FFB02D;
+ padding: 2px 4px;
+ text-align: center;
+ background-color: #FFE57F;
+ font-weight: bold;
+ z-index: 1000;
+}
+
+.timeplot-valueflag-line {
+ display: none;
+ width: 14px;
+ height: 14px;
+ z-index: 1000;
+}
+
+.timeplot-timeflag {
+ display: none;
+ border: 1px solid #FFB02D;
+ padding: 2px 4px;
+ text-align: center;
+ background-color: #FFE57F;
+ font-weight: bold;
+ z-index: 1000;
+}
+
+.timeplot-timeflag-triangle {
+ display: none;
+ width: 11px;
+ height: 6px;
+ z-index: 1001;
+}
+
+.timeplot-valueflag-pole {
+ display: none;
+ border-left: 1px solid #FFB02D;
+ z-index: 999;
+}
+
+.timeplot-lens {
+ display: none;
+ border: 1px solid #FFB02D;
+ z-index: 998;
+}
diff --git a/site/app/webroot/css/simile/ethers.css b/site/app/webroot/css/simile/ethers.css
new file mode 100755
index 0000000..7d1671d
--- /dev/null
+++ b/site/app/webroot/css/simile/ethers.css
@@ -0,0 +1,63 @@
+.timeline-ether-marker-bottom {
+ width: 5em;
+ height: 1.5em;
+ border-left: 1px solid #aaa;
+ padding-left: 2px;
+ color: #aaa;
+}
+
+.timeline-ether-marker-bottom-emphasized {
+ width: 5em;
+ height: 2em;
+ border-left: 1px solid #aaa;
+ padding-left: 2px;
+ color: black;
+}
+
+.timeline-ether-marker-top {
+ width: 5em;
+ height: 1.5em;
+ border-left: 1px solid #aaa;
+ padding-left: 2px;
+ color: #aaa;
+}
+
+.timeline-ether-marker-top-emphasized {
+ width: 5em;
+ height: 2em;
+ border-left: 1px solid #aaa;
+ padding-left: 2px;
+ color: black;
+}
+
+
+.timeline-ether-marker-right {
+ width: 5em;
+ height: 1.5em;
+ border-top: 1px solid #aaa;
+ padding-top: 2px;
+ color: #aaa;
+}
+
+.timeline-ether-marker-right-emphasized {
+ width: 7em;
+ height: 1.5em;
+ border-top: 1px solid #aaa;
+ padding-top: 2px;
+ color: black;
+}
+.timeline-ether-marker-left {
+ width: 5em;
+ height: 1.5em;
+ border-top: 1px solid #aaa;
+ padding-top: 2px;
+ color: #aaa;
+}
+
+.timeline-ether-marker-left-emphasized {
+ width: 7em;
+ height: 1.5em;
+ border-top: 1px solid #aaa;
+ padding-top: 2px;
+ color: black;
+}
diff --git a/site/app/webroot/css/simile/events.css b/site/app/webroot/css/simile/events.css
new file mode 100755
index 0000000..68e7581
--- /dev/null
+++ b/site/app/webroot/css/simile/events.css
@@ -0,0 +1,45 @@
+.timeline-duration-event {
+ position: absolute;
+ overflow: hidden;
+ border: 1px solid blue;
+}
+
+.timeline-instant-event2 {
+ position: absolute;
+ overflow: hidden;
+ border-left: 1px solid blue;
+ padding-left: 2px;
+}
+
+.timeline-instant-event {
+ position: absolute;
+ overflow: hidden;
+}
+
+.timeline-event-bubble-title {
+ font-weight: bold;
+ border-bottom: 1px solid #888;
+ margin-bottom: 0.5em;
+}
+
+.timeline-event-bubble-body {
+}
+
+.timeline-event-bubble-wiki {
+ margin: 0.5em;
+ text-align: right;
+ color: #A0A040;
+}
+.timeline-event-bubble-wiki a {
+ color: #A0A040;
+}
+
+.timeline-event-bubble-time {
+ color: #aaa;
+}
+
+.timeline-event-bubble-image {
+ float: right;
+ padding-left: 5px;
+ padding-bottom: 5px;
+} \ No newline at end of file
diff --git a/site/app/webroot/css/simile/timeline.css b/site/app/webroot/css/simile/timeline.css
new file mode 100755
index 0000000..04ef2e4
--- /dev/null
+++ b/site/app/webroot/css/simile/timeline.css
@@ -0,0 +1,65 @@
+.timeline-container {
+ position: relative;
+ overflow: hidden;
+}
+
+.timeline-copyright {
+ position: absolute;
+ bottom: 0px;
+ left: 0px;
+ z-index: 1000;
+ cursor: pointer;
+}
+
+.timeline-message-container {
+ position: absolute;
+ top: 30%;
+ left: 35%;
+ right: 35%;
+ z-index: 1000;
+ display: none;
+}
+.timeline-message {
+ font-size: 120%;
+ font-weight: bold;
+ text-align: center;
+}
+.timeline-message img {
+ vertical-align: middle;
+}
+
+.timeline-band {
+ position: absolute;
+ background: #eee;
+ z-index: 10;
+}
+
+.timeline-band-inner {
+ position: relative;
+ width: 100%;
+ height: 100%;
+}
+
+.timeline-band-input {
+ position: absolute;
+ width: 1em;
+ height: 1em;
+ overflow: hidden;
+ z-index: 0;
+}
+.timeline-band-input input{
+ width: 0;
+}
+
+.timeline-band-layer {
+ position: absolute;
+ width: 100%;
+ height: 100%;
+}
+
+.timeline-band-layer-inner {
+ position: relative;
+ width: 100%;
+ height: 100%;
+}
+
diff --git a/site/app/webroot/css/simile/timeplot.css b/site/app/webroot/css/simile/timeplot.css
new file mode 100755
index 0000000..a029f5e
--- /dev/null
+++ b/site/app/webroot/css/simile/timeplot.css
@@ -0,0 +1,95 @@
+.timeplot-container {
+ overflow: hidden;
+ position: relative;
+ /*height: 200px;*/
+ border: 1px solid #ccc;
+ padding: 12px 14px;
+}
+
+.timeplot-copyright {
+ position: absolute;
+ top: 0px;
+ left: 0px;
+ z-index: 1000;
+ cursor: pointer;
+}
+
+.timeplot-message-container {
+ position: absolute;
+ top: 30%;
+ left: 35%;
+ right: 35%;
+ max-width: 400px;
+ z-index: 1000;
+ display: none;
+}
+.timeplot-message {
+ font-size: 120%;
+ font-weight: bold;
+ text-align: center;
+}
+.timeplot-message img {
+ vertical-align: middle;
+}
+
+.timeplot-div {
+ position: absolute;
+}
+
+.timeplot-grid-label {
+ font-size: 9px;
+}
+
+.timeplot-event-box {
+ cursor: pointer;
+}
+
+.timeplot-event-box-highlight {
+ border: 1px solid #FFB03B;
+}
+
+.timeplot-valueflag {
+ display: none;
+ border: 1px solid #FFB02D;
+ padding: 2px 4px;
+ text-align: center;
+ background-color: #FFE57F;
+ font-weight: bold;
+ z-index: 1000;
+}
+
+.timeplot-valueflag-line {
+ display: none;
+ width: 14px;
+ height: 14px;
+ z-index: 1000;
+}
+
+.timeplot-timeflag {
+ display: none;
+ border: 1px solid #FFB02D;
+ padding: 2px 4px;
+ text-align: center;
+ background-color: #FFE57F;
+ font-weight: bold;
+ z-index: 1000;
+}
+
+.timeplot-timeflag-triangle {
+ display: none;
+ width: 11px;
+ height: 6px;
+ z-index: 1001;
+}
+
+.timeplot-valueflag-pole {
+ display: none;
+ border-left: 1px solid #FFB02D;
+ z-index: 999;
+}
+
+.timeplot-lens {
+ display: none;
+ border: 1px solid #FFB02D;
+ z-index: 998;
+}
diff --git a/site/app/webroot/css/slimbox/close.png b/site/app/webroot/css/slimbox/close.png
new file mode 100644
index 0000000..a39bbcf
--- /dev/null
+++ b/site/app/webroot/css/slimbox/close.png
Binary files differ
diff --git a/site/app/webroot/css/slimbox/closelabel.gif b/site/app/webroot/css/slimbox/closelabel.gif
new file mode 100644
index 0000000..87b4f8b
--- /dev/null
+++ b/site/app/webroot/css/slimbox/closelabel.gif
Binary files differ
diff --git a/site/app/webroot/css/slimbox/goleft.png b/site/app/webroot/css/slimbox/goleft.png
new file mode 100644
index 0000000..50f63d8
--- /dev/null
+++ b/site/app/webroot/css/slimbox/goleft.png
Binary files differ
diff --git a/site/app/webroot/css/slimbox/goright.png b/site/app/webroot/css/slimbox/goright.png
new file mode 100644
index 0000000..8a8d3ef
--- /dev/null
+++ b/site/app/webroot/css/slimbox/goright.png
Binary files differ
diff --git a/site/app/webroot/css/slimbox/loading.gif b/site/app/webroot/css/slimbox/loading.gif
new file mode 100644
index 0000000..f864d5f
--- /dev/null
+++ b/site/app/webroot/css/slimbox/loading.gif
Binary files differ
diff --git a/site/app/webroot/css/slimbox/nextlabel.gif b/site/app/webroot/css/slimbox/nextlabel.gif
new file mode 100644
index 0000000..7c66121
--- /dev/null
+++ b/site/app/webroot/css/slimbox/nextlabel.gif
Binary files differ
diff --git a/site/app/webroot/css/slimbox/prevlabel.gif b/site/app/webroot/css/slimbox/prevlabel.gif
new file mode 100644
index 0000000..0641876
--- /dev/null
+++ b/site/app/webroot/css/slimbox/prevlabel.gif
Binary files differ
diff --git a/site/app/webroot/css/slimbox/slimbox.css b/site/app/webroot/css/slimbox/slimbox.css
new file mode 100644
index 0000000..59a5d59
--- /dev/null
+++ b/site/app/webroot/css/slimbox/slimbox.css
@@ -0,0 +1,108 @@
+/* SLIMBOX */
+
+#lbOverlay {
+ position: absolute;
+ left: 0;
+ width: 100%;
+ background-color: #000;
+ cursor: pointer;
+}
+
+#lbCenter, #lbBottomContainer {
+ position: absolute;
+ left: 50%;
+ overflow: hidden;
+ background-color: #aaa;
+}
+
+.lbLoading {
+ background: #fff url(loading.gif) no-repeat center;
+}
+
+#lbImage {
+ position: absolute;
+ left: 0;
+ top: 0;
+ background-repeat: no-repeat;
+ background-position: center;
+ padding: 0px;
+}
+
+#lbPrevLink, #lbNextLink {
+ display: block;
+ position: absolute;
+ top: 0;
+ width: 50%;
+ outline: none;
+}
+
+#lbPrevLink {
+ left: 0;
+}
+
+#lbPrevLink:hover {
+ background: transparent url(goleft.png) no-repeat 0% 48%;
+}
+
+#lbNextLink {
+ right: 0;
+}
+
+#lbNextLink:hover {
+ background: transparent url(goright.png) no-repeat 100% 48%;
+}
+
+#lbBottom {
+ font-family: Verdana, Arial, Geneva, Helvetica, sans-serif;
+ font-size: 10px;
+ color: #666;
+ line-height: 1.4em;
+ text-align: left;
+ padding: 0px;
+ padding-top:5px;
+}
+
+#lbCloseLink {
+ display: block;
+ float: right;
+ width: 66px;
+ height: 36px;
+ background: transparent url(close.png) no-repeat center;
+ margin: 5px 0;
+}
+
+#lbCaption, #lbNumber {
+ padding-left:5px;
+ margin-right: 71px;
+ color:#111;
+}
+
+#lbCaption {
+ font-weight: bold;
+}
+
+/* Begin Mozilla Additions */
+#lbPreviewContainerContainer {
+ width: 100%;
+ border-top: 3px solid #555;
+ border-bottom: 3px solid #555;
+ background-color: #ccc;
+
+}
+#lbPreviewContainer {
+ width: 100%;
+ height: 75px;
+ margin: 5px auto 5px auto;
+}
+#lbPreviewContainer img {
+ border: 1px solid #000;
+ width: 65px;
+ height: 65px;
+ padding: 2px 2px 2px 2px;
+ margin: 2px 2px 2px 2px;
+}
+#lbPreviewContainer img.active {
+ border: 1px solid #e35200;
+ width: 65px;
+ height: 65px;
+}
diff --git a/site/app/webroot/css/stats/dropdowns.css b/site/app/webroot/css/stats/dropdowns.css
new file mode 100755
index 0000000..a9ddc2c
--- /dev/null
+++ b/site/app/webroot/css/stats/dropdowns.css
@@ -0,0 +1,408 @@
+.plot-dropdown {
+ border: 2px solid #D8DCDF;
+ -moz-border-radius: 6px;
+ -webkit-border-radius: 6px;
+ float: left;
+ height: 12px;
+ width: 153px;
+ padding: 2px;
+ z-index: 12;
+ margin: 2px 5px;
+}
+.html-rtl .plot-dropdown {
+ float: right;
+}
+.plot-dropdown.menu-open {
+ -moz-border-radius-bottomright: 0px;
+ -webkit-border-bottom-right-radius: 0px;
+}
+.plot-dropdown a {
+ text-decoration: none;
+ color: #333333;
+ cursor: pointer;
+}
+.plot-dropdown .colorbox,
+.plot-legend .colorbox {
+ width: 10px;
+ height: 10px;
+ background: #ddddff;
+ border: 1px solid gray;
+ float: left;
+}
+.html-rtl .plot-dropdown .colorbox,
+.html-rtl .plot-legend .colorbox {
+ float: right;
+}
+.plot-dropdown .colorbox.removable:hover {
+ background: gray url('../../img/stats/x.png') no-repeat top left !important;
+}
+.plot-dropdown:hover,
+.plot-dropdown ul:hover {
+ border-color: #99CC99;
+}
+.plot-dropdown .selected {
+ background: transparent url('../../img/arr-otherapps-open.png') no-repeat 98% 50%;
+ float: left;
+ width: 92%;
+ margin-top: -3px;
+ height: 18px;
+}
+.html-rtl .plot-dropdown .selected {
+ float: right;
+ background-position: 2% 50%;
+}
+.plot-dropdown .selected .selected-text {
+ float: left;
+ padding-left: 5px;
+ width: 85%;
+ overflow: hidden;
+ height: 17px;
+}
+.html-rtl .plot-dropdown .selected .selected-text {
+ float: right;
+ padding-left: auto;
+ padding-right: 5px;
+}
+.plot-dropdown .selected .selected-prefix {
+ font-size: 10px;
+ color: #006600;
+}
+.plot-dropdown .selected .selected-name {
+ padding-left: 2px;
+}
+.html-rtl .plot-dropdown .selected .selected-name {
+ padding-left: 0;
+ padding-right: 2px;
+}
+.plot-dropdown ul {
+ display: none;
+ position: absolute;
+ list-style: none;
+ padding: 0;
+ margin: 14px 0 0 13px;
+ background-color: #FFFFFF;
+ border: 2px solid #D8DCDF;
+ -moz-border-radius: 6px;
+ -webkit-border-radius: 6px;
+ width: 140px;
+ z-index: 1100;
+}
+.plot-dropdown ul.scrolling {
+ max-height: 250px;
+ overflow: auto;
+}
+.plot-dropdown ul.level1 {
+ -moz-border-radius-topleft: 0px;
+ -moz-border-radius-topright: 0px;
+ -webkit-border-top-left-radius: 0px;
+ -webkit-border-top-right-radius: 0px;
+}
+.plot-dropdown ul.level2 {
+ margin-left: 155px;
+ margin-top: 30px;
+}
+.plot-dropdown ul.level3 {
+ margin-left: 297px;
+ margin-top: 47px;
+}
+.plot-dropdown ul li a {
+ display: block;
+ overflow: hidden;
+ padding-left: 2px;
+}
+.plot-dropdown ul li a.active-item {
+ background-color: #D8DCDF;
+}
+.plot-dropdown ul li a:hover {
+ background-color: #D8DCDF;
+}
+.plot-dropdown .none {
+ color: #D8DCDF;
+}
+.plot-dropdown a:hover .none {
+ color: #FFFFFF;
+}
+.plot-dropdown .submenu a {
+ background: transparent url('../../img/arr-otherapps-closed.png') 128px 50% no-repeat;
+}
+.plot-dropdown .menu-divider {
+ border: 1px solid #D8DCDF;
+}
+.plot-dropdown ul:hover .menu-divider {
+ border: 1px solid #99CC99;
+}
+
+
+.plot-dropdown.toggle ul {
+ margin-left: -4px;
+ width: 157px;
+}
+.plot-dropdown.toggle ul li a {
+ min-height: 18px;
+}
+.plot-dropdown.toggle ul a .item-toggle-icon {
+ float: left;
+ width: 20px;
+ height: 18px;
+}
+.plot-dropdown.toggle ul a .item-name {
+ padding-left: 22px;
+ display: block;
+}
+.plot-dropdown.toggle ul li.checked a .item-toggle-icon {
+ background: url('../../img/stats/tick.png') center center no-repeat;
+}
+
+.plot-dropdown.toggle ul li.count a .item-toggle-icon {
+ width: 10px;
+ height: 10px;
+ border: 1px solid gray;
+ background: none;
+ margin: 4px;
+}
+.plot-dropdown.toggle ul li.checked.count a .item-toggle-icon {
+ background: #000000;
+}
+
+.plot-dropdown.toggle ul li.events-firefox a .item-toggle-icon {
+ background: url('../../img/developers/firefox.png') center center no-repeat;
+ opacity: .3;
+}
+.plot-dropdown.toggle ul li.checked.events-firefox a .item-toggle-icon {
+ opacity: 1;
+}
+.plot-dropdown.toggle ul li.events-thunderbird a .item-toggle-icon {
+ background: url('../../img/developers/thunderbird.png') center center no-repeat;
+ opacity: .3;
+}
+.plot-dropdown.toggle ul li.checked.events-thunderbird a .item-toggle-icon {
+ opacity: 1;
+}
+.plot-dropdown.toggle ul li.events-addon a .item-toggle-icon {
+ opacity: .3;
+ background: none;
+ text-align: center;
+}
+.plot-dropdown.toggle ul li.checked.events-addon a .item-toggle-icon {
+ opacity: 1;
+ background: none;
+}
+.plot-dropdown.toggle ul li.add-plot a .item-toggle-icon {
+ background: url('../../img/stats/chart_curve_add.png') center center no-repeat;
+}
+.plot-dropdown.toggle ul li.resize a .item-toggle-icon {
+ background: transparent url('../../img/icn-expand.png') 4px 3px no-repeat;
+}
+.plot-dropdown.toggle ul li.checked.resize a .item-toggle-icon {
+ background: transparent url('../../img/icn-collapse.png') 4px 3px no-repeat;
+}
+.plot-dropdown.toggle ul li.rss a .item-toggle-icon {
+ background: url('../../img/stats/rss16x16.png') center center no-repeat;
+}
+.plot-dropdown.toggle ul li.csv a .item-toggle-icon {
+ background: url('../../img/stats/page_white_go.png') center center no-repeat;
+}
+
+
+.plot-dropdown.big-menu {
+ height: 20px;
+ font-size: 15px;
+ width: 165px;
+}
+.plot-dropdown.big-menu.menu-open,
+.plot-dropdown.toggle.menu-open {
+ -moz-border-radius-bottomright: 0px;
+ -moz-border-radius-bottomleft: 0px;
+ -webkit-border-bottom-right-radius: 0px;
+ -webkit-border-bottom-left-radius: 0px;
+}
+.plot-dropdown.big-menu .selected {
+ width: 100%;
+ margin-top: -1px;
+ height: 23px;
+}
+.plot-dropdown.big-menu .selected .selected-text {
+ height: 22px;
+}
+.plot-dropdown.big-menu ul {
+ width: 169px;
+ margin: 22px 0 0 -4px;
+}
+.html-rtl .plot-dropdown.big-menu ul {
+ margin-left: 0;
+ margin-right: -4px;
+}
+.plot-dropdown.big-menu ul li a {
+ padding-left: 8px;
+}
+.html-rtl .plot-dropdown.big-menu ul li a {
+ padding-left: 0;
+ padding-right: 8px;
+}
+.plot-dropdown.big-menu ul li.indented a {
+ padding-left: 23px;
+}
+.html-rtl .plot-dropdown.big-menu ul li.indented a {
+ padding-left: 0;
+ padding-right: 23px;
+}
+
+#options.plot-dropdown {
+ width: 35px;
+ padding: 4px;
+}
+#options.plot-dropdown .selected .selected-text {
+ padding: 0;
+}
+#options.plot-dropdown .selected {
+ width: 96%;
+}
+#options.plot-dropdown ul {
+ margin-left: -120px;
+}
+
+#group-by-selector {
+ width: 163px;
+ white-space: nowrap;
+}
+#group-by-selector .selected {
+ width: 98%;
+}
+#group-by-selector_group-by-selection-menu {
+ padding: 0 0.5em 0 0.5em;
+ width: auto;
+}
+
+
+#plot-options #plot-selector-area {
+ width: 180px;
+ float: left;
+}
+.html-rtl #plot-options #plot-selector-area {
+ float: right;
+}
+#plot-options #options-area {
+ width: 100px;
+ float: right;
+}
+.html-rtl #plot-options #options-area {
+ float: left;
+}
+#plot-options #plot-selection {
+ width: 620px;
+ float: left;
+}
+.html-rtl #plot-options #plot-selection {
+ float: right;
+}
+
+#plot-options .options {
+ float: right;
+}
+
+#weeks-legend {
+ display: none;
+ border: 2px solid #D8DCDF;
+ -moz-border-radius: 6px;
+ -webkit-border-radius: 6px;
+ float: left;
+ margin-left: 160px;
+}
+
+#summary-legend {
+ border: 2px solid #D8DCDF;
+ -moz-border-radius: 6px;
+ -webkit-border-radius: 6px;
+ float: left;
+ margin-left: 120px;
+}
+.html-rtl #summary-legend {
+ float: right;
+ margin-left: auto;
+ margin-right: 120px;
+}
+.plot-legend .colorbox {
+ margin: 2px;
+}
+.plot-legend {
+ float: left;
+ padding: 2px;
+}
+.html-rtl .plot-legend {
+ float: right;
+}
+.plot-legend .plot-name {
+ float: left;
+ margin: -2px 10px 0 2px;
+}
+.html-rtl .plot-legend .plot-name {
+ float: right;
+ margin-left: 10px;
+ margin-right: 2px;
+}
+
+#summary-options {
+ border: 2px solid #D8DCDF;
+ -moz-border-radius: 6px;
+ -webkit-border-radius: 6px;
+ float: right;
+}
+.html-rtl #summary-options {
+ float: left;
+}
+.zoom-button {
+ float: left;
+ width: 16px;
+ height: 16px;
+ background-color: #EEEEEE;
+ padding: 2px 3px;
+ cursor: pointer;
+}
+.zoom-button:hover {
+ background-color: #99CC99;
+}
+.zoom-button.disabled {
+ opacity: .2;
+ cursor: default;
+}
+.zoom-button.disabled:hover {
+ background-color: #EEEEEE;
+}
+#zoom-in {
+ -moz-border-radius-topleft: 4px;
+ -moz-border-radius-bottomleft: 4px;
+ -webkit-border-top-left-radius: 4px;
+ -webkit-border-bottom-left-radius: 4px;
+ border-right: 1px solid #D8DCDF;
+}
+#zoom-out {
+ -moz-border-radius-topright: 4px;
+ -moz-border-radius-bottomright: 4px;
+ -webkit-border-top-right-radius: 4px;
+ -webkit-border-bottom-right-radius: 4px;
+}
+
+.plot-button {
+ -moz-border-radius: 6px;
+ -webkit-border-radius: 6px;
+ background-color: #D8DCDF;
+ float: left;
+ padding: 2px 5px;
+ cursor: pointer;
+}
+.plot-button:hover {
+ background-color: #99CC99 !important;
+}
+
+#timeplot-container {
+ min-height: 174px;
+ clear: both;
+}
+.timeplot-container {
+ height: 150px;
+}
+.timeplot {
+ height: 150px;
+ border: none !important;
+}
+
diff --git a/site/app/webroot/css/stats/stats.css b/site/app/webroot/css/stats/stats.css
new file mode 100755
index 0000000..16f2097
--- /dev/null
+++ b/site/app/webroot/css/stats/stats.css
@@ -0,0 +1,279 @@
+.template { display: none; }
+
+#content {
+ width: 948px;
+ margin-left:auto;
+ margin-right:auto;
+}
+.section {
+ width: 950px;
+}
+
+#stats-table {
+ display: none;
+ width: 948px;
+ overflow: auto;
+ margin: 1em 0 1em 0;
+}
+#stats-table a.download{
+ padding: 1em 0em 1.5em 0em;
+ font-weight: bold;
+ display: block;
+}
+#stats-table-instance {
+}
+#stats-table-instance thead {
+ background-color: #E4F8E0;
+}
+#stats-table-instance thead tr {
+}
+#stats-table-instance thead tr th {
+ color: #333;
+ padding: 0.25em 1em 0.25em 1em;
+ font-weight: bold;
+ border-right: 2px solid #ccc;
+ border-top: 1px solid #333;
+ border-bottom: 1px solid #333;
+}
+#stats-table-instance thead tr th.first {
+ border-left: 1px solid #000;
+}
+#stats-table-instance thead tr th.last {
+ border-right: 1px solid #000;
+}
+#stats-table-instance tbody {
+}
+#stats-table-instance tbody tr.odd {
+ background-color: #ededed;
+}
+#stats-table-instance tbody tr.even {
+}
+#stats-table-instance tbody tr td {
+ padding: 0.25em 1em 0.25em 1em;
+ border-right: 2px solid #ccc;
+}
+#stats-table-instance tbody tr td.first {
+ font-weight: bold;
+ border-left: 1px solid #000;
+}
+#stats-table-instance tbody tr td.last {
+ border-right: 1px solid #000;
+}
+#stats-table-instance tbody tr.last td {
+ border-bottom: 1px solid #000;
+}
+
+.greenbox-tr {
+ background: transparent url('../../img/rec-tr.png') top right no-repeat;
+}
+.greenbox-tl {
+ background: transparent url('../../img/rec-tl.png') top left no-repeat;
+}
+.greenbox-bl {
+ background: transparent url('../../img/rec-bl.png') bottom left no-repeat;
+ height: 10px;
+}
+.greenbox-br {
+ background: transparent url('../../img/rec-br.png') bottom right no-repeat;
+ height: 10px;
+}
+
+.bluebox-tr {
+ background: transparent url('../../img/addon-tr.png') top right no-repeat;
+}
+.bluebox-tl {
+ background: transparent url('../../img/addon-tl.png') top left no-repeat;
+}
+.bluebox-bl {
+ background: transparent url('../../img/addon-bl.png') bottom left no-repeat;
+ height: 10px;
+}
+.bluebox-br {
+ background: transparent url('../../img/addon-br.png') bottom right no-repeat;
+ height: 10px;
+}
+
+body {
+ line-height: normal;
+}
+td, th {
+ border: none;
+}
+
+.warning {
+ background: transparent url('../../img/warning.png') no-repeat 20px 50%;
+ border: 1px solid gray;
+ -moz-border-radius: 30px;
+ -webkit-border-radius: 30px;
+ height: 48px;
+ margin: 0 20px 10px 20px;
+ padding: 5px 20px 5px 100px;
+}
+.html-rtl .warning {
+ background-position: 810px 50%;
+ padding-left: 20px;
+ padding-right: 80px;
+}
+.warning div {
+ display: table-cell;
+ height: 48px;
+ vertical-align: middle;
+}
+
+#helpbox {
+ margin: 5px auto;
+ border: 1px solid gray;
+ width: 75%;
+ padding: 10px;
+}
+
+#addon_header h2 {
+ padding-top: 5px;
+}
+
+#stats_menu span.type {
+ color: #666666;
+}
+#stats_menu .selected {
+ border-bottom: 1px dotted navy;
+}
+#tabs p {
+ margin: 0px;
+ text-indent: 10px;
+}
+#tabs h3 {
+ border-bottom: 1px solid black;
+}
+#tabs h4 {
+ font-weight: bold;
+ font-size: 14px;
+}
+#tabs h4 a {
+ color: navy;
+ text-decoration: none;
+}
+#tabs h4 a:hover {
+ text-decoration: underline;
+}
+
+.cal_updatepings {
+ background-color: #DDDDFF;
+}
+
+#stats-table-container {
+ padding: 10px;
+}
+#stats_table {
+ margin: 0 auto;
+}
+#stats_table .header td {
+ font-weight: bold;
+}
+#stats_table .value {
+
+}
+
+#stats_overview td {
+ vertical-align: middle;
+}
+#stats_overview .label {
+ font-size: 120%;
+ border-bottom: 1px dashed gray;
+}
+#stats_overview .value {
+ font-size: 130%;
+ text-align: right;
+ border-bottom: 1px dashed gray;
+}
+.html-rtl #stats_overview .value {
+ text-align: left;
+}
+#stats_overview .biglabel {
+ font-weight: bold;
+ font-size: 120%;
+ border-top: 1px solid black;
+ border-bottom: 1px solid black;
+}
+#stats_overview .bigvalue {
+ font-weight: bold;
+ font-size: 24px;
+ text-align: right;
+ border-top: 1px solid black;
+ border-bottom: 1px solid black;
+}
+.html-rtl #stats_overview .bigvalue {
+ text-align: left;
+}
+#stats_overview .date {
+ text-indent: 2em;
+ color: gray;
+ font-size: 10px;
+}
+
+#nodata .inpie {
+ position: absolute;
+ top: 140px;
+ font-weight: bold;
+ font-size: 14px;
+ width: 100%;
+ padding-left: 10px;
+}
+#nodata .outofpie {
+ position: absolute;
+ text-align: center;
+ bottom: 0px;
+ width: 100%;
+}
+
+#settings {
+ text-align: right;
+ padding-top: 10px;
+}
+.html-rtl #settings {
+ text-align: left;
+}
+#settings .confidential {
+ color: red;
+ font-weight: bold;
+}
+
+.settings-content ul {
+ list-style: none;
+}
+.settings-content .buttons {
+ text-align: center;
+}
+.notice-updated {
+ border: 1px solid green;
+ background: lightgreen url('../../img/stats/tick.png') no-repeat 5px 50%;
+ margin-bottom: 5px;
+ padding: 5px 5px 5px 30px;
+}
+
+#statistics-header {
+ min-height: 32px;
+ padding: 10px;
+}
+#statistics-controls {
+ text-align: right;
+ float: right;
+}
+.html-rtl #statistics-controls {
+ text-align: left;
+ float: left;
+}
+#statistics-links {
+ font-size: 10px;
+}
+#statistics-header #addon-icon {
+ padding-right: 5px;
+ float: left;
+}
+.html-rtl #statistics-header #addon-icon {
+ padding-right: auto;
+ padding-left: 5px;
+ float: right;
+}
+#statistics-header #addon-title {
+ line-height: 2;
+}
diff --git a/site/app/webroot/css/style.min.css b/site/app/webroot/css/style.min.css
new file mode 100644
index 0000000..f931e3c
--- /dev/null
+++ b/site/app/webroot/css/style.min.css
@@ -0,0 +1 @@
+html,body,div,span,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,code,del,dfn,em,img,q,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption,tbody,tfoot,thead,tr,th,td{font-weight:inherit;font-style:inherit;font-size:100%;font-family:inherit;vertical-align:baseline;}caption,th,td{text-align:left;font-weight:400;}blockquote:before,blockquote:after,q:before,q:after{content:"";}blockquote,q{quotes:"" "";}form ol,form ul{list-style:none;}input,button,select,textarea{font-family:inherit;font-size:inherit;color:inherit;}body{font:62.5%/1.6 Verdana,"Trebuchet MS",sans-serif;}a:link{text-decoration:underline;}h1,h2,h3,h4,h5,h6,caption,#rate-it legend{font-family:"Trebuchet MS",Helvetica,"Helvetica Neue",Arial,sans-serif;}h2{font-weight:bold;font-size:140%;}h3,caption{font-size:140%;}h4,#rate-it legend{font-size:125%;}dt{font-weight:bold;}thead th{font-size:95%;}#site-notice{font-size:110%;}#nav-access{list-style:none;font-size:115%;}#nav-access a:active,#nav-access a:focus{text-align:center;}h4#moz{font-weight:bold;font-size:130%;}#page-title h1{font-weight:bold;font-size:300%;line-height:1.2;}#page-title h1 a{text-decoration:none;}#page-title h2{font-size:220%;}#page-title p.page-intro{line-height:1.25;font-size:125%;font-weight:bold;}#nav-user{text-align:right;font-size:115%;}#nav-user a:link,#nav-user a:visited{text-decoration:none;}#nav-user a:hover,#nav-user a:active,#nav-user a:focus{text-decoration:underline;}#other-apps h3{font-size:100%;}#nav-apps{list-style:none;font:bold 110% "Trebuchet MS",Helvetica,"Helvetica Neue",Arial,sans-serif;}#other-apps.js #nav-apps{font-size:130%;}#nav-apps a{text-decoration:none;}#search-form{font-size:100%;}#search-form #search-query label,#search-form #query,#search-form #category{font-size:140%;}#search-form #search-category{white-space:nowrap;}#nav-legal{list-style:none;}#footer-disclaimer{text-align:center;}#content{font-size:120%;}#content-extra h3{font-size:110%;}#content-extra .nav-addon h3{font-size:130%;}#content-extra ul{font-size:98%;}#content-extra p.view-all{text-align:right;}#categories h3{font-size:120%;}#cat-list{list-style:none;}#categories a:link,#categories a:visited{text-decoration:none;}#categories p{line-height:1.4;}.addon .name{font-size:180%;line-height:1.2;font-weight:normal;}.addon .author{font-size:100%;}.addon .name a,.addon .author a{text-decoration:none;}.addon .name a:hover,.addon .author a:hover{text-decoration:underline;}.addon .rating,.addon .stats,.addon .updated{font-size:95%;}.addon .stats em{font-style:normal;}.addon .more-from{font-size:90%;}.addon .flag{font-size:100%;line-height:1;}.main .name{font-size:200%;}.sub .name{font-size:150%;}.sub .preview-img{text-align:center;}.sub .desc{font-size:98%;}#addon-listing{list-style:none;}#addon-listing .author{font-size:100%;}#addon-listing .more{list-style:none;font-size:95%;}.install-button{font:bold 120% "Trebuchet MS",Helvetica,"Helvetica Neue",Arial,sans-serif;}.install-button a{text-decoration:none;}.exp-loggedout,.exp-confirmed{font-size:90%;}.exp-loggedout .install-button a,.exp-confirmed .install-button a{font-size:110%;text-align:left;}.pitch h3{font-size:100%;font-weight:bold;line-height:1.2;}.pitch h3 a{text-decoration:none;}.pitch p{font-size:95%;}#recommended .name{font-size:160%;}#content.landing #secondaries .sub .flag{font-size:95%;}#content.landing .more-addons h3{font-size:130%;}#content.landing .more-addons ul{list-style:none;}#content.browse .more-addons h3{text-align:center;}.browse-list a{text-decoration:none;font-weight:bold;}#dictionaries tbody th{font-weight:bold;}#addon-summary .name{font-size:200%;}.addon-cats{list-style:none;font-size:95%;}.addon-cats a:link,.addon-cats a:visited{text-decoration:none;}.addon-cats a:hover,.addon-cats a:active,.addon-cats a:focus{text-decoration:underline;}.addon-images,.addon-reviews{list-style:none;}.addon-images a img{vertical-align:top;}.addon-reviews .cite{font-size:95%;}#license a{font-size:70%;}.oldversion .license a{font-size:80%;}#form-review #review-submit{font-size:90%;}#recaptcha_whatsthis{font-size:90%;}.more-addons h3{line-height:1.3;}.more-addons h3 a.view{text-decoration:none;}.more-addons h4{font-size:100%;}.pages{list-style:none;text-align:left;}.pagination p.count,.pagination p.perpage{text-align:right;}#form-listcontrol{font-family:"Trebuchet MS",Helvetica,"Helvetica Neue",sans-serif;}#form-listcontrol #per-page{font-size:110%;font-weight:bold;}#order-by button{text-align:center;}#form-listcontrol #experimental label{font-size:95%;line-height:1.1;}body{background:#fff;color:#333;}a:link{color:#1d587f;}a:visited{color:#748d9e;}a:active,a:hover,a:focus{color:#000;}a.view{background:transparent url("../img/sprite.png?20090430") 100% -247px no-repeat;}.html-ltr a.view:hover{background-position:100% -301px;}.html-rtl a.view{background-position:100% -486px;}.html-rtl a.view:hover{background-position:100% -540px;}h3,h4,h5,h6{color:#2d3b58;}td,th{border-bottom:1px solid #eee;}thead th{color:#555;}input,button,select,textarea{color:inherit;}a img{border:none;}div.error-notice{background:#fffefa url("../img/warning.png") 10px 10px no-repeat;border:1px solid #eee;-moz-border-radius:6px;-webkit-border-radius:6px;border-radius:6px;}#site-notice{background:#ffe;border-bottom:2px solid #ccc;}#nav-access a:active,#nav-access a:focus{color:#000;background:#fff;border:1px solid #475470;outline:0;}h4#moz a{background:transparent url("../img/sprite-alpha.png") no-repeat 0 -1px;}h4#moz a:hover,h1#moz a:active,h1#moz a:focus{background-position:0 -51px;}#page-title{background:transparent url("../img/brandbanner-bg.png") 0 40% repeat-x;}#page-title p.page-intro{color:#354a4f;}#page-title.firefox h1,#page-title.firefox h1 a{color:#bd1d01;}#page-title.thunderbird h1,#page-title.thunderbird h1 a{color:#0b4190;}#page-title.fennec h1,#page-title.fennec h1 a{color:#0b4190;}#page-title.seamonkey h1,#page-title.seamonkey h1 a{color:#3f38a3;}#page-title.sunbird h1,#page-title.sunbird h1 a{color:#337b5a;}#page-title.generic h1,#page-title.generic h1 a{color:#bd1d01;}#page-title.developers h1,#page-title.developers h1 a{color:#bd1d01;}#page-title h2{color:#2D3B58;}.html-ltr #nav-user li{border-left:1px solid #666;}.html-rtl #nav-user li{border-right:1px solid #666;}#nav-user li:first-child{border-left:0;}#nav-user li:first-child{border-right:0;}#nav-user a:link{color:#000;}#nav-user a:visited{color:#666;}#nav-user a:hover,#nav-user a:active,#nav-user a:focus{color:#000;}#other-apps{background-color:#b3deee;border:1px solid #90c8dd;-moz-border-radius:6px;-webkit-border-radius:6px;border-radius:6px;}#other-apps h3{color:#4d757b;}#other-apps.js h3{border-bottom:1px solid #90c8dd;-moz-border-radius:6px;-webkit-border-radius:6px;border-radius:6px;}#other-apps.js h3{background:transparent url("../img/sprite.png?20090430") 4px -262px no-repeat;}.html-rtl #other-apps.js h3{background-position:14px -262px;}#other-apps.js h3:hover{background-color:#c5e3ee;}#nav-apps a{color:#1f0084;background-repeat:no-repeat;background-position:0 50%;}#nav-apps a:hover,#nav-apps a:active,#nav-apps a:focus{color:#1d587f;}.html-ltr #other-apps.js #nav-apps #app-seamonkey a{background:url("../img/sprite-alpha.png") -465px 0 no-repeat;}.html-rtl #other-apps.js #nav-apps #app-seamonkey a{background:url("../img/sprite-alpha.png") -390px 0 no-repeat;}.html-ltr #other-apps.js #nav-apps #app-sunbird a{background:url("../img/sprite-alpha.png") -616px 0 no-repeat;}.html-rtl #other-apps.js #nav-apps #app-sunbird a{background:url("../img/sprite-alpha.png") -541px 0 no-repeat;}.html-ltr #other-apps.js #nav-apps #app-thunderbird a{background:url("../img/sprite-alpha.png") -766px 0 no-repeat;}.html-rtl #other-apps.js #nav-apps #app-thunderbird a{background:url("../img/sprite-alpha.png") -691px 0 no-repeat;}.html-ltr #other-apps.js #nav-apps #app-fennec a{background:url("../img/sprite-alpha.png") -766px 0 no-repeat;}.html-rtl #other-apps.js #nav-apps #app-fennec a{background:url("../img/sprite-alpha.png") -691px 0 no-repeat;}.html-ltr #other-apps.js #nav-apps #app-firefox a{background:url("../img/sprite-alpha.png") -321px 0 no-repeat;}.html-rtl #other-apps.js #nav-apps #app-firefox a{background:url("../img/sprite-alpha.png") -246px 0 no-repeat;}.html-ltr #other-apps.collapsed h3{border-bottom:0;background-position:6px -320px;}.html-rtl #other-apps.collapsed h3{border-bottom:0;background-position:16px -320px;}#search-bubble-outer{background:transparent url("../img/sprite.png?20090430") right top no-repeat;}#search-bubble-inner{background:transparent url("../img/sprite.png?20090430") left top no-repeat;}#search-form li{color:#666;}.html-ltr #search-form #query{background:#fff url("../img/sprite.png?20090430") -977px -686px no-repeat;}.html-rtl #search-form #query{background:#fff url("../img/sprite.png?20090430") 100% -686px no-repeat;}#search-form #search-category label{color:#426a13;}.html-ltr #search-form #my-submit{background:url("../img/sprite-alpha.png") -120px 0 no-repeat;}.html-ltr #search-form #my-submit:hover{background-position:-157px 0;}.html-rtl #search-form #my-submit{background:url("../img/sprite-alpha.png") -120px -40px no-repeat;}.html-rtl #search-form #my-submit:hover{background:url("../img/sprite-alpha.png") -157px -40px no-repeat;}#advanced-search{background-color:#e6e6e6;border:1px solid #68B41C;}#advanced-search-toggle{background:url("../img/sprite.png?20090430") right -68px no-repeat;}#advanced-search-toggle div{background:transparent url("../img/sprite.png?20090430") left -68px no-repeat;}#advanced-search-toggle a{color:black;text-decoration:none;padding:1px 3px 1px 3px;}.html-ltr #advanced-search-toggle a.asclosed{background:url("../img/sprite.png?20090430") right -354px no-repeat;}.html-ltr #advanced-search-toggle a.asopen{background:url("../img/sprite.png?20090430") right -369px no-repeat;}.html-rtl #advanced-search-toggle a.asclosed{background:url("../img/sprite.png?20090430") -989px -354px no-repeat;}.html-rtl #advanced-search-toggle a.asopen{background:url("../img/sprite.png?20090430") -989px -369px no-repeat;}#advanced-search-toggle #toggle-outer{background:url("../img/sprite.png?20090430") right -87px no-repeat;}#advanced-search-toggle #toggle-inner{background:url("../img/sprite.png?20090430") -861px -87px no-repeat;}#footer{color:#888;padding:1em 0;background:transparent url("../img/foot-bg.png") repeat-x;}#footer a:link,#footer a:visited{color:#777;}#footer a:hover,#footer a:active,#footer a:focus{color:#000;}#content-extra .extra{border:1px solid #d8dcdf;-moz-border-radius:6px;-webkit-border-radius:6px;border-radius:6px;}#categories h3{background:#79be1b url("../img/sprite.png?20090430") -104px -106px no-repeat;border-bottom:1px solid #abe071;}#categories h3 span{color:#426a13;background:transparent url("../img/sprite.png?20090430") -230px -106px no-repeat;}#categories.collapsed h3{background-position:0 -106px;}#categories.collapsed h3.open{background-position:-26px -106px;}#categories,#categories.collapsed #cat-list{background-color:#f6f6f6;border:1px solid #d8dcdf;border-width:0 1px 1px;}#categories,#categories.collapsed #cat-list{-moz-border-radius-bottomright:6px;-moz-border-radius-bottomleft:6px;-webkit-border-bottom-right-radius:6px;-webkit-border-bottom-left-radius:6px;border-bottom-right-radius:6px;border-bottom-left-radius:6px;}#cat-list{border-top:1px solid #e8e6e6;}#cat-list li{border-bottom:3px double #e8e6e6;}#cat-list a{background:#f4f2f2 url("../img/cat-link.png") repeat-x left top;}#categories a:link{color:#4e4e4e;}#categories a:visited{color:#777;}#categories a:hover,#categories a:active,#categories a:focus{color:#1d587f;background:#f1f0f0 url("../img/cat-link.png") repeat-x left -100px;}#categories.collapsed h3 span{background-position:-242px -106px;}#categories.collapsed h3:hover{color:#4f7f17;background-position:-52px -106px;}#categories.collapsed h3.open:hover{background-position:-78px -106px;}#categories.collapsed h3:hover span{background-position:-533px -106px;}#categories p{border-top:1px solid #e8e6e6;}.addon{border-left:1px solid #d8dcdf;background:transparent url("../img/sprite.png?20090430") right -1256px no-repeat;}.addon .vex{background:transparent url("../img/sprite.png?20090430") right bottom no-repeat;}.addon .vex span{background:transparent url("../img/sprite.png?20090430") left bottom no-repeat;}.addon .preview-img{background:transparent url("../img/sprite.png?20090430") left -1256px no-repeat;}.addon .stats em{color:#d54601;}.addon .flag{border:1px solid #ccc;border-width:0 1px 1px 0;}#addon-listing .addon .vex{background:transparent url("../img/sprite.png?20090430") no-repeat right bottom;}.sub .irk{background:transparent url("../img/sprite.png?20090430") left -1256px no-repeat;}.sub .preview-img{background-image:none;}.rec{background:url("../img/rec-tr.png") no-repeat right top;border-left-color:#c1e1c1;}.rec .preview-img{background:transparent url("../img/rec-tl.png") left top no-repeat;}.rec .flag{background:#f8f8f7 url("../img/rec-flag.png") no-repeat;}.rec .vex{background-image:url("../img/rec-br.png");}.rec .vex span{background-image:url("../img/rec-bl.png");}.rec .flag a{color:#360;text-decoration:none;}.exp{background:url("../img/exp-tr.png") no-repeat right top;border-left-color:#e3c1c1;}.exp .preview-img{background:transparent url("../img/exp-tl.png") left top no-repeat;}.exp .flag{background:#f8f8f7 url("../img/exp-flag.png") no-repeat;}.exp .flag a{color:#900;text-decoration:none;}.exp .vex{background-image:url("../img/exp-br.png");}.exp .vex span{background-image:url("../img/exp-bl.png");}#addon-listing .more li{border-right:1px solid #666;}#addon-listing .more li:last-child{border:0;}.install-button a{color:#062445;background:#7cc11c url("../img/sprite.png?20090430") 100% -730px no-repeat;}.install-button a span{background:transparent url("../img/installbtn-edges.png") left bottom no-repeat;}.install-button a span span{background:transparent url("../img/installbtn-edges.png") right bottom no-repeat;}.install-button a span span span{background:transparent url("../img/installbtn-edges.png") left top no-repeat;}.install-button a span span span strong{background:transparent url("../img/installbtn-edges.png") right top no-repeat;}.install-button a:hover,.install-button a:focus,.install-button a:active{color:#0a3b73;background-color:#9dd34c;background-position:100% -860px;}.install-button a span,.install-button a span span,.install-button a span span span,.install-button a span span span strong{background-image:url("../img/installbtn-edges-list.png");}.exp .install-button a span,.exp .install-button a span span,.exp .install-button a span span span,.exp .install-button a span span span strong{background-image:url("../img/installbtn-edges-exp.png");}#addon-listing .rec .install-button a span,#addon-listing .rec .install-button a span,#addon-listing .rec .install-button a span span,#addon-listing .rec .install-button a span span,#addon-listing .rec .install-button a span span span,#addon-listing .rec .install-button a span span span,#addon-listing .rec .install-button a span span span strong{background-image:url("../img/installbtn-edges-rec.png");}#content-main .exp-loggedout,#content .exp-loggedout,#content-main .exp-confirmed{border:1px solid #d8d8d8;background:#fff;-moz-border-radius:6px;-webkit-border-radius:6px;border-radius:6px;}#content-main .exp-loggedout .install-button a,#content .exp-loggedout .install-button a{color:#aaa;background-color:#fff;background-position:100% -995px;}#content-main .exp-loggedout .install-button a span,#content .exp-loggedout .install-button a span,#content-main .exp-loggedout .install-button a span span,#content .exp-loggedout .install-button a span span,#content-main .exp-loggedout .install-button a span span span,#content .exp-loggedout .install-button a span span span,#content-main .exp-loggedout .install-button a span span span strong,#content .exp-loggedout .install-button a span span span strong{background-image:url("../img/installbtn-edges-dis.png");}#content-main .exp-loggedout .install-button a:hover,#content .exp-loggedout .install-button a:hover{background-color:#f3f3f3;background-position:100% -1125px;}#content-main .install-container .not-avail{padding:5px 10px;float:left;color:#666;border:1px solid #d8d8d8;background:#fff;-moz-border-radius:6px;-webkit-border-radius:6px;border-radius:6px;}.pitch{background-color:#f8f8f8;border:1px solid #e4f3fa;-moz-border-radius:6px;-webkit-border-radius:6px;border-radius:6px;}.pitch h3{color:#042253;}#recommended{background:#f2f8fd;border:1px solid #e9f1f8;-moz-border-radius:6px;-webkit-border-radius:6px;border-radius:6px;}#recommended .addon{background:#fff url("../img/landrec-tr.png") no-repeat top right;}#recommended .addon .preview-img{background:url("../img/landrec-tl.png") no-repeat top left;}#recommended .addon .vex{background-image:url("../img/landrec-br.png");}#recommended .vex span{background-image:url("../img/landrec-bl.png");}#content.landing #secondaries .exp .irk{background-image:url("../img/exp-tl.png");}#content.landing #secondaries .sub .vex{background-image:url("../img/addon-br.png");}#content.landing #secondaries .exp .vex{background-image:url("../img/exp-br.png");}#content.landing #secondaries .exp .preview-img{background-image:none;}#content.landing .more-addons{border:1px solid #5d6c8c;-moz-border-radius:6px;-webkit-border-radius:6px;border-radius:6px;}.browse-list a{background:#fafafa;border:1px solid #e8e6e6;-moz-border-radius:6px;-webkit-border-radius:6px;border-radius:6px;}.browse-list a:hover{background-color:#f1f0f0;border-color:#e1dfdf;}#dictionaries{background-color:#f7fafc;border:1px solid #eef1f3;-moz-border-radius:6px;-webkit-border-radius:6px;border-radius:6px;}#dictionaries th,#dictionaries td{border-bottom:1px solid #eee;}#dictionaries tbody tr.alt th,#dictionaries tbody tr.alt td{background-color:#fff;}.addon-cats li{border-left:1px solid #666;}.addon-cats li:first-child{border-left:0;}#addon-info,#addon-advanced{border:1px solid #d8dcdf;-moz-border-radius:6px;-webkit-border-radius:6px;border-radius:6px;}.addon-images a img{border:1px solid #1d587f;}.addon-reviews li,.addon-versions li{border-top:1px solid #d8dcdf;}#addon-info .addon-reviews li{background-color:#f7fafc;border:1px solid #eef1f3;-moz-border-radius:6px;-webkit-border-radius:6px;border-radius:6px;}#addon-advanced h5{border-top:1px solid #d8dcdf;}#latest-version{border:1px solid #5d6c8c;-moz-border-radius:6px;-webkit-border-radius:6px;border-radius:6px;}div.oldversion{-moz-border-radius:6px;-webkit-border-radius:6px;border-radius:6px;}#form-review{background-color:#f8f8f8;border:1px solid #e4f3fa;-moz-border-radius:6px;-webkit-border-radius:6px;border-radius:6px;}#recaptcha_image{border:1px solid #d8dcdf;}#rate-it legend span{color:#042758;}.more-addons h3 a.view{background:transparent url("../img/sprite.png?20090430") 100% -387px no-repeat;}.html-ltr .more-addons h3 a.view:hover{background-position:100% -437px;}.html-rtl .more-addons h3 a.view{background-position:100% -597px;}.html-rtl .more-addons h3 a.view:hover{background-position:100% -647px;}.pagination{background-color:#f7fafc;border:1px solid #eef1f3;-moz-border-radius:6px;-webkit-border-radius:6px;border-radius:6px;}.pages a{border:1px solid #fff;}.pages a:hover{background-color:#ccf29b;border-color:#bbde92;}.pages .selected a{background-color:#ccf29b;border:1px solid #83c53f;text-decoration:none;font-weight:bold;color:black;}.pages .prev a{background:transparent url("../img/arr-prev.png") 0 50% no-repeat;}.pages .prev a:hover{background-color:#ccf29b;}.pages .next a{background:transparent url("../img/arr-next.png") 100% 50% no-repeat;}.pages .next a:hover{background-color:#ccf29b;}#form-listcontrol{background:#f2f8fd;border:1px solid #e9eff4;-moz-border-radius:6px;-webkit-border-radius:6px;border-radius:6px;}#order-by button{color:#7598b5;background-color:#fff;border:1px solid #89a8c1;-moz-border-radius:6px;-webkit-border-radius:6px;border-radius:6px;}#order-by button:hover{background-color:#e9eff4;color:#496377;}#order-by button.current,#order-by button.current:hover{background-color:#89a8c1;color:#fff;}#form-listcontrol #experimental label{background:#fff;border:1px solid #933;color:#933;-moz-border-radius:5px;-webkit-border-radius:5px;border-radius:5px;}#thumb-subcategories ul{-moz-border-radius-bottomleft:6px;-moz-border-radius-bottomright:6px;border-color:#D8DCDF;border-style:solid;border-width:0 1px 1px;}#thumb-subcategories ul li{border-top:1px solid #E8E6E6;}#thumb-subcategories a:link{color:#4e4e4e;}#thumb-subcategories a:visited{color:#777;}#thumb-subcategories a:hover,#thumb-subcategories a:active,#thumb-subcategories a:focus{background:#F2F8Fd;}#thumb-subcategories li.selected a:link,#thumb-subcategories li.selected a:visited{background-color:#89A8C1;color:#FFF;}#thumb-browser .thumbs li.thumb{background:transparent url(../img/sprite.png?20090430) no-repeat scroll right -1256px;}#thumb-browser .thumbs li.thumb div.wrapper{background:transparent url(../img/sprite.png?20090430) no-repeat scroll left -1256px;}#thumb-browser .thumbs li.exp{background:transparent url(../img/exp-tr.png) no-repeat scroll right top;}#thumb-browser .thumbs li.exp div.wrapper{background:transparent url(../img/exp-tl.png) no-repeat scroll left top;}#thumb-browser .thumbs li.thumb .vex{background:transparent url(../img/sprite.png?20090430) no-repeat scroll right bottom;}#thumb-browser .thumbs li.thumb .vex span{background:transparent url(../img/sprite.png?20090430) no-repeat scroll left bottom;width:10px;height:10px;float:left;}#thumb-browser .thumbs li.exp .vex{background:transparent url(../img/exp-br.png) no-repeat scroll right bottom;}#thumb-browser .thumbs li.exp .vex span{background:transparent url(../img/exp-bl.png) no-repeat scroll left bottom;}@media screen,projection{html,body,div,span,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,code,del,dfn,em,img,q,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption,tbody,tfoot,thead,tr,th,td{margin:0;padding:0;border:0;}table{border-collapse:separate;border-spacing:0;}body{min-width:770px;}ol,ul{margin-left:2em;}blockquote{margin:0 3em 1em;}dd{margin-left:2em;}td,th{padding:2px 6px;}a.view{padding-right:10px;}button,input[type="submit"]{cursor:pointer;}h2{margin-bottom:.5em;}div.error-notice{margin:0;min-height:48px;margin-bottom:1.5em;padding:10px 10px 0 70px;}.with-js .hide-with-js{display:none;}.show-with-js{display:none;}.with-js .show-with-js{display:block;}#site-notice{width:80%;padding:5px 10%;}#nav-access{position:absolute;top:-10em;margin:0 auto;width:100%;}#nav-access a:active,#nav-access a:focus{position:absolute;top:11em;width:18em;z-index:2;}.html-ltr #nav-access a:active,.html-ltr #nav-access a:focus{left:50%;margin-left:-8em;}.html-rtl #nav-access a:active,.html-rtl #nav-access a:focus{right:50%;margin-right:-8em;}#branding{position:relative;}h4#moz{position:absolute;top:10px;margin:0;z-index:1;}.html-rtl h4#moz{left:0;}.html-rtl h4#moz img{position:relative;left:-10px;}h4#moz a{display:block;height:44px;width:100px;padding-left:10px;}#page-title{height:13em;}#page-title div{max-width:900px;margin:0 auto;}.html-ltr #page-title div{padding:25px 105px 0;}.html-rtl #page-title div{position:relative;left:-70px;padding:25px 0 0 0;}#page-title h1{position:relative;}.html-ltr #page-title h1{padding:10px 0 5px 125px;}.html-rtl #page-title h1{padding:10px 320px 5px 0;}#page-title h1 img{position:absolute;top:0;}.html-ltr #page-title h1 img{left:0;}.html-rtl #page-title h1 img{right:200px;}#page-title h2{position:relative;}.html-ltr #page-title h2{margin:-5px 0 5px 175px;}.html-rtl #page-title h2{margin:-5px 370px 5px 0;}#page-title p.page-intro{margin-bottom:0;width:42em;max-width:650px;}.html-ltr #page-title p.page-intro{padding-left:125px;}.html-rtl #page-title p.page-intro{padding-right:320px;}#nav-user{max-width:900px;min-width:770px;}.html-ltr #nav-user{margin:-1.75em auto 0;padding:0 50px;}.html-rtl #nav-user{margin:0 auto 0;padding:0 0 0 50px;}#nav-user li{display:inline;}.html-ltr #nav-user li{padding-left:1em;margin-right:.5em;}.html-rtl #nav-user li{padding-right:1em;margin-left:.5em;}.html-ltr #nav-user li:first-child{border-left:0;padding-left:0;}.html-rtl #nav-user li:first-child{border-right:0;padding-right:0;}#other-apps{position:absolute;top:-9.65em;z-index:5;}.html-ltr #other-apps{right:50px;padding:6px 10px 0;}.html-rtl #other-apps{right:50px;padding:6px 10px 0;}#other-apps.js{width:12em;padding-bottom:6px;}#other-apps h3{margin-right:20px;}#other-apps.js h3{float:none;cursor:pointer;}.html-ltr #other-apps.js h3{margin:-6px -10px;padding:6px 15px 6px 20px;}.html-rtl #other-apps.js h3{margin:-6px -10px;padding:6px 15px 6px 20px;}#nav-apps{margin-top:.1em;}.html-ltr #nav-apps{margin-left:0;}.html-rtl #nav-apps{margin-right:0;}.html-ltr #nav-apps li{margin-right:10px;}.html-rtl #nav-apps li{margin-left:10px;}#other-apps.js #nav-apps{margin-top:1em;}#other-apps.js #nav-apps li{display:block;margin-right:0;}.html-ltr #other-apps.js #nav-apps li{margin-right:0;}.html-rtl #other-apps.js #nav-apps li{margin-left:0;}#other-apps.js #nav-apps a{display:block;line-height:35px;}.html-ltr #other-apps.js #nav-apps a{padding-left:40px;}.html-rtl #other-apps.js #nav-apps a{padding-right:40px;}#other-apps.collapsed #nav-apps{position:absolute;}.html-ltr #other-apps.collapsed #nav-apps{left:-999em;}.html-rtl #other-apps.collapsed #nav-apps{right:-999em;}#other-apps.collapsed #nav-apps a:active,#other-apps.collapsed #nav-apps a:focus{position:absolute;top:0;}.html-ltr #other-apps.collapsed #nav-apps a:active,.html-ltr #other-apps.collapsed #nav-apps a:focus{left:-999em;}.html-rtl #other-apps.collapsed #nav-apps a:active,.html-rtl #other-apps.collapsed #nav-apps a:focus{right:-999em;}#search-element{position:relative;width:80%;}.html-ltr #search-element{left:190px;}.html-rtl #search-element{left:0;}#search-bubble-inner{height:71px;margin:0;padding:0;width:6px;float:left;}.html-ltr #standard-search{padding:20px 4px 15px 14px;}.html-rtl #standard-search{padding:20px 20px 15px 4px;}#search-bubble-outer legend{display:none;}#search-form ol{margin:0;padding:0;}#search-form #search-query{width:55%;}#search-form #search-query label,#search-mini #search-query label{display:none;}#search-mini #search-query label{font-style:italic;color:#46651f;}#search-form #search-query label,#search-mini #search-query label{position:absolute;top:20px;}#search-mini #search-query label{top:2px;}.html-ltr #search-form #search-query label{left:17px;padding:.2em 5px .2em 30px;}.html-rtl #search-form #search-query label{right:17px;padding:.2em 30px .2em 5px;}#search-form #query{width:42%;}.html-ltr #search-form #query{padding:.2em 5px .2em 24px;}.html-rtl #search-form #query{padding:.2em 24px .2em 5px;}#search-form #category{width:36%;padding:.2em 0;}#search-form #category option{min-width:14em;}#search-form #search-query input,#search-form #category option{height:21px;-ms-box-sizing:content-box;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box;}#search-form #my-submit{width:37px;height:38px;border:0;margin-left:9px;}#advanced-search{margin:-2px 0 0 0;padding:.1in .25in 0 .25in;}form.asclosed{display:none;}#search-application{padding-bottom:.1in;}#advanced-search-toggle{position:relative;top:-2px;}.html-ltr #advanced-search-toggle{text-align:right;}.html-rtl #advanced-search-toggle{text-align:left;direction:ltr;}#advanced-search-toggle div{width:6px;height:6px;float:left;}#advanced-search-toggle #toggle-inner{padding-left:3px;}.html-ltr #advanced-search-toggle #toggle-outer{margin:0 .25in .1in 0;padding-right:4px;}.html-ltr #advanced-search-toggle a{padding-right:.15in;}.html-rtl #advanced-search-toggle #toggle-outer{margin:0 0 .1in .25in;padding-right:4px;}.html-rtl #advanced-search-toggle a{padding-left:.15in;}.html-ltr #search-application td{padding-right:.2in;}.html-rtl #search-application td{padding-left:.2in;}.html-rtl #advanced-search td{text-align:right;}.html-ltr #search-platform{float:left;margin-bottom:1.5em;margin-right:1in;}.html-rtl #search-platform{float:right;margin-bottom:1.5em;margin-left:1in;}#search-mini{display:inline;float:right;border:1px solid #8cb956;-moz-border-radius:6px;-webkit-border-radius:6px;border-radius:6px;background:#91ce43 url('../img/sprite.png?20090430') no-repeat right -23px;padding:5px;position:relative;-moz-box-shadow:2px 2px 3px -1px #888;-webkit-box-shadow:2px 2px 3px -1px #888;box-shadow:2px 2px 3px -1px #888;}.html-rtl #search-mini{float:left;-moz-box-shadow:-2px 2px 3px -1px #888;-webkit-box-shadow:-2px 2px 3px -1px #888;box-shadow:-2px 2px 3px -1px #888;}#search-mini #category{font-size:113%;max-width:250px;}.html-ltr #search-mini #search-query label{left:9px;padding:.39em 15px .2em 5px;}.html-rtl #search-mini #search-query label{right:9px;padding:.39em 5px .2em 15px;}#search-mini-submit{border:1px solid #6d9041;background:url('../img/sprite.png?20090430') no-repeat right -23px;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;padding:2px 9px;vertical-align:top;margin:0 0 0 3px;-moz-box-shadow:2px 2px 3px -1px #888;-webkit-box-shadow:2px 2px 3px -1px #888;box-shadow:2px 2px 3px -1px #888;}#footer{position:relative;width:100%;clear:both;padding:1em 0;min-width:770px;}#footer-lang-form{position:relative;max-width:900px;min-width:770px;}.html-ltr #footer-lang-form{padding:0 50px;margin:0 auto;}.html-rtl #footer-lang-form{padding:0 0 0 50px;margin:0;}.html-ltr #footer-lang-form p{position:absolute;right:50px;}.html-rtl #footer-lang-form p{position:absolute;left:50px;}#footer-legal{max-width:900px;margin:0 auto;padding:0 50px;min-width:770px;}#copyright{margin-bottom:0;}#nav-legal li{display:inline;margin-right:.5em;}#footer-disclaimer{margin-top:1em;}#content{clear:both;position:relative;padding:1em 50px;max-width:950px;margin:0 auto 1em;min-width:770px;min-height:1000px;}#content-main{position:relative;margin-left:190px;min-height:50em;}#content.main-page #content-main,#content.detail-page #content-main,#content.reviews-page #content-main,#content.versions-page #content-main{width:60%;padding-right:20%;}#content-main.full{margin-left:0;}#content.detail-page #content-main.full,#content.reviews-page #content-main.full,#content.versions-page #content-main.full{width:75%;padding-right:25%;}#secondaries .sub{width:48%;}#secondaries #feature3{float:right;}#secondaries #feature2{float:left;}#content #sidebar{position:absolute;left:50px;top:1em;width:170px;}#content-extra{position:absolute;right:0;top:0;width:23%;}#content-extra .extra{margin-bottom:.1em;padding:5px 12px;}#content-extra h3{margin-bottom:.1em;}.html-ltr #content-extra ul{margin:0 0 0 10px;}.html-rtl #content-extra ul{margin:0 10px 0 0;}#content-extra ul li{margin:0;padding:0;}#content-extra ul li span{font-size:8pt;}#content-extra p.view-all{margin-bottom:.5em;}.html-rtl #content-extra p.view-all{margin-right:4px;}#categories{margin-bottom:1em;position:relative;z-index:5;}#categories h3{margin:0 -1px;padding-left:6px;}#categories.collapsed h3{padding-left:18px;}#categories h3 span{display:block;padding:8px 4px;}#categories,#categories.collapsed #cat-list{padding-bottom:6px;}#categories.collapsed h3 span{text-indent:4px;padding-left:0;}#cat-list{margin-left:0;}#cat-list li{padding-right:1px;}#cat-list a,#cat-list span{display:block;padding:.5em 10px;}#categories.collapsed h3{cursor:pointer;}#categories p{margin:0 -1px -6px;padding:.6em 10px;}#categories.collapsed #cat-list{position:absolute;left:-999em;top:-999em;}.html-rtl #categories.collapsed #cat-list{position:absolute;left:999em;top:-999em;}#categories.collapsed #cat-list.visible{margin:0 -1px;width:100%;left:0;top:3.35em;height:auto;overflow:visible;z-index:99;}#categories.collapsed #cat-list a:active,#categories.collapsed #cat-list a:focus{position:absolute;left:999em;top:1002.4em;width:85%;}#categories.collapsed #cat-list.visible a:active,#categories.collapsed #cat-list.visible a:focus{position:static;width:auto;}#content-main p,#content-main ul,#content-main ol{margin-bottom:1.25em;}#content-main li{margin-bottom:.5em;}#content-main li ul,#content-main li ol{margin-left:15px;}.addon{position:relative;min-height:160px;padding:18px 20px 10px;margin-bottom:1.6em;}.addon .vex{height:10px;width:100%;position:absolute;left:0;bottom:0;}.addon .vex span{display:block;height:10px;margin-left:-1px;width:10px;float:left;}.addon .name{padding-left:44px;position:relative;}.addon .name img{position:absolute;left:0;}.addon .author{margin:0 0 1.25em 44px;}.addon .preview-img{position:absolute;left:-1px;top:0;padding:18px 0 0 20px;width:200px;height:150px;overflow:hidden;}.addon .flag{position:absolute;left:-1px;top:0;padding:5px 10px 3px 10px;z-index:5;}.addon .baseline img.faq{margin:0 5px 0 0;float:left;}.rec,.exp{min-height:170px;}.rec .preview-img,.exp .preview-img{padding:2.5em 0 0 20px;}.updated{font-size:75%;color:#666;}.main{padding-left:240px;min-height:220px;}.main .rating{position:absolute;left:20px;top:180px;width:200px;}.main .stats{position:absolute;left:20px;top:180px;width:200px;margin-top:2em;}.sub{position:relative;padding:0;}.sub .irk{margin-left:-1px;padding:14px 20px 8px;margin-right:4px;}.sub .vex{padding:0;left:0;}.sub .name{margin-bottom:0;}.sub .preview-img{position:static;padding:0;}.sub .rating{position:static;width:40%;padding-right:10%;float:left;}.sub .rating img{display:block;}.sub .more-from{clear:both;}#content-main #addon-listing{margin-left:0;}#addon-listing .addon{padding:18px 240px 10px;margin-bottom:1em;}#addon-listing .preview-img{position:absolute;left:-1px;top:0;}#addon-listing .rating{display:inline;margin-right:2em;}#addon-listing .stats{display:inline;margin-right:2em;}#addon-listing .more{display:inline;margin:0;padding:0;}#addon-listing .more li{display:inline;margin:0 10px 0 0;padding:0 15px 0 0;}#addon-listing .desc{margin-top:.5em;}.install-button:after,.install-container:after{content:".";clear:both;display:block;visibility:hidden;height:0;overflow:hidden;}.install-button a{float:left;cursor:pointer;max-width:290px;}.html-rtl .install-button a{float:right;}.install-button a *{display:block;float:left;position:relative;}.html-rtl .install-button a *{float:right;}.install-button a span{padding:0 0 0 6px;}.install-button a span span{padding:0 0 8px 0;}.install-button a span span span{left:-6px;padding:0 0 6px 0;}.install-button a span span span strong{right:-6px;padding:10px 45px 0 6px;}.install-button a span span span strong img{padding:0 6px 0 0;}#addon-listing .install-container{position:absolute;right:0;top:20px;max-width:180px;padding:0 15px;}#addon-listing .install-container .install-button{margin-bottom:.5em;float:right;}#addon-listing .addon p.updated{position:absolute;right:0;bottom:5px;max-width:180px;padding:0 15px;}#addon-listing .exp .exp-loggedout,#addon-listing .exp .exp-confirmed{float:right;}#addon-listing .exp .exp-loggedout .install-button,#addon-listing .exp .exp-confirmed .install-button{float:none;}.exp-loggedout,.exp-confirmed{float:left;padding:5px 5px 3px 8px;}.html-rtl .exp-loggedout,.html-rtl .exp-confirmed{float:right;padding:5px 8px 3px 5px;}.exp-loggedout .install-button,.exp-confirmed .install-button{margin-top:3px;margin-right:-3px;}.html-rtl .exp-loggedout .install-button,.html-rtl .exp-confirmed .install-button{margin-right:0;margin-left:-3px;}.exp-loggedout .install-button a{cursor:default;}#content-main .exp-loggedout p.install-button,#content-main .exp-confirmed p.install-button{margin-bottom:0;}.exp-confirm-install input{float:left;}.html-rtl .exp-confirm-install input{float:right;}.exp-confirm-install .exp-desc{float:right;width:85%;padding:0 0 5px 0;}.html-rtl .exp-confirm-install .exp-desc{float:left;}.pitch{margin-bottom:1em;padding:10px;}.pitch h3,.pitch p{margin-bottom:1em;}.html-rtl .pitch ul{padding-right:15px;}.pitch h3 img{float:left;margin:-4px 10px 0 0;}#recommended{padding:0 1% 10px;width:98%;float:left;margin-bottom:1em;}#recommended .addon{float:none;}#content.wide #recommended .addon{width:20%;padding-left:26.5%;min-width:100px;margin-bottom:0;}#content.wide #recommended .addon .preview-img{width:45%;}#content.wide #recommended #feature1{float:left;}#content.wide #recommended #feature2{float:right;}#content.landing #secondaries{float:left;}#content.landing #secondaries .sub{float:left;width:30.5%;margin-right:2.5%;}#content.landing-with-slider #secondaries .sub{float:left;width:31.5%;margin-right:2.5%;}#content.landing-with-slider #secondaries #feature8{margin-right:0;}#content.landing #secondaries .sub .irk{padding-top:2.2em;}#content.landing #secondaries .sub .vex{padding-top:0;}#content.landing #secondaries .exp .preview-img{padding:0;}#content.landing #secondaries .addon .preview-img{padding:0;width:180px;}#content.landing-with-slider #secondaries .sub{float:left;width:31.5%;margin-right:2.5%;}#content.landing-with-slider #secondaries #feature8{margin-right:0;}#content.landing #secondaries{width:77%;}#content.landing #content-extra{width:23%;}#content.landing-with-slider #secondaries{width:100%;}#content.landing-with-slider #content-extra{width:25%;position:absolute;top:0;right:0;}#content.landing-with-slider #content-main{position:relative;}#content.landing-with-slider #recommended{float:none;position:relative;left:0;width:71%;}.html-rtl #content.landing-with-slider #recommended{float:left;}#content.landing-with-slider #recommended #slider .item_set .addon{float:left;width:308px;padding-left:240px;}#content.landing-with-slider #recommended #slider{background-color:#fff;margin-bottom:0;}#content.landing #content-extra{position:static;float:right;}#content.landing-with-slider #content-extra{position:absolute;float:none;}#content.landing.languages #content-extra{margin-right:0;}#content.landing .more-addons{margin:0 0 1em;padding:6px 10px 0;}#content.landing.browse #secondaries{width:50%;}#content.landing.browse #secondaries .sub{width:47%;}#content.landing.browse #secondaries #feature4{margin-right:0;}#content.landing.browse #content-extra{width:47%;}#content.browse .more-addons h3 a.view{display:inline;}.browse-list{list-style:none;margin:0;width:100%;overflow:auto;}.browse-list li{width:48%;margin:0 0 3px 1%;float:left;}.browse-list a{display:block;padding:3px 5px;}#content.landing.languages .sub{width:23.75%;margin-right:2%;float:left;}#content.landing.languages #feature3{margin-right:0;}#dictionaries{margin-top:1.5em;clear:both;padding:10px 15px;}#dictionaries table{width:100%;}#dictionaries th,#dictionaries td{padding:6px 12px;}#addon-summary{padding-left:240px;min-height:270px;}#addon-summary .name{margin-bottom:0;}#addon-summary .preview-img{position:absolute;left:-1px;top:0;padding:18px 0 0 20px;}#addon-summary.exp .preview-img,#addon-summary.rec .preview-img{padding-top:2.5em;}#addon-summary .rating{position:absolute;left:20px;top:180px;width:200px;text-align:center;line-height:14px;}#content-main #addon-summary .stats{position:absolute;text-align:center;left:20px;top:202px;width:200px;margin-top:3.5em;}#addon-summary .link-sharing{position:absolute;left:60px;top:218px;font-size:.75em;}#addon-summary .link-sharing .badge .button{display:block;color:#062445;background:#7cc11c url("../img/sprite.png?20090430") -800px -730px no-repeat;}#addon-summary .link-sharing .badge .button a{display:block;padding:0 8px 8px 0;background:transparent url(../img/installbtn-edges.png) no-repeat scroll right bottom;}#addon-summary .link-sharing .badge .button a span{display:block;text-align:center;font-weight:bold;padding:2px 0 0 2px;background:transparent url(../img/installbtn-edges-list.png) no-repeat scroll left top;}#addon-summary .link-sharing .share-button{padding:0;margin:0;width:100px;}#addon-summary .link-sharing .share-button:after,.install-container:after{content:".";clear:both;display:block;visibility:hidden;height:0;overflow:hidden;}#addon-summary .link-sharing .share-button a{float:left;cursor:pointer;max-width:290px;text-decoration:none;}#addon-summary .link-sharing .share-button a *{display:block;float:left;position:relative;}#addon-summary .link-sharing .share-button a span{padding:0 0 0 6px;}#addon-summary .link-sharing .share-button a span span{padding:0 0 8px 0;}#addon-summary .link-sharing .share-button a span span span{left:-6px;padding:0;}#addon-summary .link-sharing .share-button a span span span strong{width:90px;text-align:center;right:-6px;padding:0 18px 0 6px;}#addon-summary .link-sharing .share-button a span span span strong img{padding:0 6px 0 0;}#addon-summary .link-sharing .share-button a{color:#062445;background:#7cc11c url("../img/sprite.png?20090430") -800px -730px no-repeat;}#addon-summary .link-sharing .share-button a span{background:transparent url("../img/installbtn-edges.png") left bottom no-repeat;}#addon-summary .link-sharing .share-button a span span{background:transparent url("../img/installbtn-edges.png") right bottom no-repeat;}#addon-summary .link-sharing .share-button a span span span{background:transparent url("../img/installbtn-edges.png") left top no-repeat;}#addon-summary .link-sharing .share-button a span span span strong{background:transparent url("../img/installbtn-edges.png") right top no-repeat;}#addon-summary .link-sharing .share-button a:hover,.install-button a:focus,.install-button a:active{color:#0a3b73;background-color:#9dd34c;background-position:-800px -860px;}#addon-summary .link-sharing .badge .counter{display:block;position:relative;padding-right:4px;text-align:center;top:-4px;}#addon-summary .link-sharing .choices{display:none;position:absolute;z-index:9999;left:-120px;top:12px;width:360px;background:transparent url(../img/box-pointer-top.png) center top no-repeat;padding-top:12px;}#addon-summary .link-sharing .choices div{margin:0;padding:1em;background-color:#f8f8f8;border:1px solid #657b86;-moz-border-radius:6px;-webkit-border-radius:6px;border-radius:6px;}#addon-summary .link-sharing .choices ul{list-style:none;margin:0;}#addon-summary .link-sharing .choices ul li{width:50%;float:left;}#addon-summary .link-sharing .choices ul li p{padding:.25em;margin:0 .25em 0 0;}#addon-summary .link-sharing .choices ul li p a{font-weight:bold;display:block;height:20px;text-decoration:none;padding-left:22px;background:transparent url(../img/favicons/digg.gif) left top no-repeat;}#addon-summary .link-sharing .choices ul li.digg p a{background-image:url(../img/favicons/digg.gif);}#addon-summary .link-sharing .choices ul li.facebook p a{background-image:url(../img/favicons/facebook.gif);}#addon-summary .link-sharing .choices ul li.delicious p a{background-image:url(../img/favicons/delicious.gif);}#addon-summary .link-sharing .choices ul li.myspace p a{background-image:url(../img/favicons/myspace.gif);}#addon-summary .link-sharing .choices ul li.friendfeed p a{background-image:url(../img/favicons/friendfeed.gif);}#addon-summary .link-sharing .choices ul li.reddit p a{background-image:url(../img/favicons/reddit.gif);}.addon-cats{margin-left:0;}.addon-cats li{display:inline;padding-left:1em;margin-right:.5em;}.addon-cats li:first-child{padding-left:0;}#addon-info,#addon-advanced{padding:8px 15px;margin-bottom:1em;}.html-ltr #addon_app_compatibility{position:relative;top:.6em;padding-left:22em;font-weight:bold;}.html-rtl #addon_app_compatibility{position:relative;top:.6em;padding-right:22em;font-weight:bold;}.html-ltr #addon-info .app_compat{float:left;}.html-rtl #addon-info .app_compat{float:right;}#addon-info h4{font-size:147%;}.addon-images{margin:1em auto 1.5em;}.addon-images li{display:inline;margin-right:10px;}.addon-images a img{margin-bottom:10px;}#addon-advanced{position:relative;}#addon-advanced h5{margin-top:1em;}#content .addon-reviews{margin-left:0;}#content .addon-reviews blockquote{margin:0;}#content .addon-reviews li{padding:8px 10px;}#content .addon-reviews .cite{font-size:95%;margin-bottom:0;}#content-extra ul.nav-addon{list-style:none;margin-left:0;padding-left:0;}#content .review .others-by-user{font-style:italic;display:block;margin-top:.5em;font-size:.85em;}#content .review .others-by-user a{padding-left:22px;}#content .review .others-by-user a.loading{background:transparent url(../img/ajax_loading.gif) no-repeat 2px top;}#content .others-by-user-load{padding-left:3em;}#content .review-reply{margin-left:3em;}#content .review p.flag-thanks,#content .review-reply p.flag-thanks{font-weight:bold;}#content .review form.flag,#content .review-reply form.flag{display:block;padding-bottom:1em;}#content .review form.flag label,#content .review-reply form.flag label{display:block;font-weight:bold;}.with-js #content .review p.flag-thanks,.with-js #content .review-reply p.flag-thanks{display:inline;}.with-js #content .review form.flag,.with-js #content .review-reply form.flag{display:inline;}.with-js #content .review form.flag label,.with-js #content .review-reply form.flag label{display:none;}#content .review .flag span.loading,#content .review-reply .flag span.loading{padding-left:22px;background:transparent url(../img/ajax_loading.gif) no-repeat 2px top;}#content ul.review-flags{padding:1em 1em .5em 1em;list-style-type:square;}#content ul.review-flags li{font-weight:bold;}#content ul.review-flags-notes{padding:.25em .5em;list-style-type:disc;}#content ul.review-flags-notes li{font-weight:normal;}#content ul.review-flags-notes .note{font-style:italic;}#latest-version{width:96%;float:left;margin-bottom:1.5em;padding:8px 2%;}#latest-version h3{float:left;}#latest-version .install-button{float:right;margin-bottom:0;}#content .addon-versions{margin-left:0;padding-left:0;list-style:none;}#content .addon-versions li{padding:8px 10px 0;}#content .addon-versions h3{margin-bottom:.5em;}#content .version-details,#content .version-links{list-style:none;margin-left:0;padding-left:0;}#content .version-details li,#content .version-links li{padding:0;border:0;}#content .version-links li{margin-bottom:.25em;}#content .version-details em,#content .version-links em{font-style:normal;color:#888;}#form-review{position:relative;margin-bottom:1em;padding:10px;}#form-review textarea{width:98%;margin:0 auto .5em;}#form-review #review-submit{width:100%;clear:both;margin-top:-1.5em;}#form-review .disabled{background:#eee;}#form-review h3{display:inline;}#form-review .login{display:inline;font-size:92%;}#form-review .login a:link,#form-review .login a:visited{text-decoration:none;}.html-ltr #form-review #review-submit{float:left;}.html-rtl #form-review #review-submit{float:right;}.html-ltr #form-review #review-submit input{float:right;}.html-rtl #form-review #review-submit input{float:left;}#recaptcha_image{margin:.5em 0;}#rate-it{margin-bottom:1em;}#rate-it h4{float:left;width:6em;font-size:110%;}.html-rtl #form-review #rate-it h4{float:right;}#rate-it .stars{display:block;float:left;width:90px;margin:.3em 0 0 0;}#form-review #rate-it .degrade{margin-left:0;width:145px;}#form-review #rate-it .degrade p{margin:.2em 0;}#rate-it .rating{cursor:pointer;margin:2em;clear:both;display:block;}#rate-it .rating:after{content:'.';display:block;height:0;width:0;clear:both;visibility:hidden;}#long-review .stars{margin:0;}#long-review .degrade{margin-left:14em;}#long-review .stars p{margin:.2em 0;}#long-review .rating{margin:1em 0;}.stars input{margin:0 4px;}.stars{zoom:1;}.stars .cancel,.stars .star{float:left;width:12px;height:14px;overflow:hidden;text-indent:-999em;cursor:pointer;}.html-rtl .stars .star,.html-rtl .stars .cancel{float:right;}.stars .cancel a,.stars .cancel a{background:url(../img/ratings_images.gif) no-repeat;}.stars .star a,.stars .star a{background:url(../img/ratings_images.gif) no-repeat;}.stars.cancel a,.stars .star a,.stars .cancel a,.stars .star a{display:block;width:100%;height:100%;background-position:0 -25px;border:1 solid #F00;}.stars .cancel a,.stars.cancel a{background-position:0 2px;}.stars div.star_hover a,.stars div.star_hover a{background-position:0 -38px;}.stars div.cancel_on a,.stars div.cancel_on a{background-position:0 -11px;}.stars div.star_on a,.stars div.star_on a{background-position:0 -38px;}.stars:after{content:".";clear:both;display:block;visibility:hidden;height:0;overflow:hidden;}#publish_to option:first-child{display:none;}.more-addons{padding:10px;}.more-addons h3 a.view{display:block;padding-right:30px;padding:.2em 30px .2em 0;}.more-addons h4{margin-top:1.5em;}#content.landing #content-extra .more-addons ul{margin-left:0;}.pagination{padding:8px 10px 0;margin-top:1em;}.pages{margin:0;float:left;}.pages li{display:inline;margin:0 2px;}.pages a{padding:3px 6px;}.pages .prev a{padding-left:15px;}.pages .next a{padding-right:15px;}#content-main .pagination p.count{margin-bottom:0;}.pagination p.perpage em,.pagination .perpage a{margin:0;}#form-listcontrol{position:relative;margin-bottom:1em;padding:8px 20% 8px 18%;}#form-listcontrol p,#form-listcontrol ul{margin:0;}#form-listcontrol #per-page{position:absolute;top:8px;left:10px;padding-top:6px;}#order-by li{display:inline;margin:0 2px;}#order-by button{cursor:pointer;padding:8px 2px;width:18.5%;}#order-by button.current,#order-by button.current:hover{cursor:default;}#form-listcontrol #experimental{position:absolute;top:8px;right:10px;width:140px;}#form-listcontrol #experimental label{display:block;cursor:pointer;padding:4px 0 4px 30px;}#form-listcontrol #experimental label input{position:absolute;left:6px;top:20%;}#developerAgreement ul{list-style-type:disc;margin-top:5px;}#thumb-subcategories{position:absolute;left:50px;top:7.125em;width:170px;}#thumb-subcategories ul{list-style-type:none;margin:0;padding:0;padding-bottom:6px;margin-bottom:1em;position:relative;}#thumb-subcategories ul li{padding-right:1px;overflow:hidden;}#thumb-subcategories ul li a,#thumb-subcategories ul li span{display:block;font-size:95%;padding:.25em 10px;}#thumb-subcategories a:link,#thumb-subcategories a:visited{text-decoration:none;}#thumb-browser .thumbs{list-style-type:none;margin-left:23%;}#thumb-browser .thumbs li.thumb{position:relative;width:170px;margin-right:10px;display:inline;float:left;text-align:center;}#thumb-browser .thumbs li.thumb div.wrapper{padding:1.75em 9px 0 9px;margin:0 5px 0 0;}#thumb-browser .thumbs li.thumb div.wrapper div.item{width:150px;}#thumb-browser .thumbs li.thumb div.img{border:1px solid #ccc;background:#fff;height:112px;overflow:hidden;}#thumb-browser .thumbs li.thumb div.img img{width:150px;}#thumb-browser .thumbs li.thumb h3{font-size:115%;line-height:115%;height:2.25em;overflow:hidden;padding-top:.5em;margin-bottom:.5em;}#thumb-browser .thumbs li.thumb .flag{position:absolute;top:0;left:0;padding:0 6px;}#thumb-browser .thumbs li.thumb p.meta{margin-bottom:0;padding:0;height:3.5em;overflow:hidden;}#thumb-browser .thumbs li.thumb .vex{text-align:left;height:8px;}#thumb-browser .thumbs li.thumb .vex span{display:block;height:8px;margin-left:0;}#thumb-browser #form-listcontrol{margin-left:20%;padding:8px 12% 8px 15%;}#thumb-browser #form-listcontrol #order-by button{white-space:nowrap;width:16.5%;}#slider{margin-bottom:18px;width:100%;background:transparent url(../img/sprite.png?20090430) no-repeat scroll left -1256px;}#slider .inner{background:transparent url(../img/sprite.png?20090430) no-repeat scroll right -1256px;width:100%;}#slider .viewport{position:relative;width:100%;overflow:hidden;}#slider .item_set{width:6000px;}#slider .item_set .addon{float:left;width:308px;}#slider .item_set li.addon{list-style:none;}#slider .item_set .addon .preview-img{background:transparent url(../img/sprite.png?20090430) no-repeat 1px -1256px;}#slider .item_set .addon{background:none;border-left:none;}#slider .item_set .addon .install-container{height:85px;}#slider .item_set .addon .install-button{padding-top:1.75em;padding-left:.5em;}#slider .item_set .addon .exp-loggedout .install-button,#slider .item_set .addon .exp-confirmed .install-button{padding-top:0;padding-left:0;}#slider .item_set .addon .count{border-top:1px solid #CCC;bottom:4px;height:35px;margin-left:-240px;position:absolute;}#slider .controls{border-top:1px solid #ccc;width:100%;}#slider .controls_inner{font-size:140%;text-align:center;padding-top:6px;border-left:1px solid #ccc;border-right:1px solid #ccc;}#slider .controls a{text-decoration:none;padding:0 .5em;}#slider .controls a img{border:none;vertical-align:top;}#slider .vex{background:transparent url("../img/sprite.png?20090430") right bottom no-repeat;width:100%;}.html-rtl #slider .vex{direction:ltr;}#slider .vex span{background:transparent url("../img/sprite.png?20090430") left bottom no-repeat;height:10px;display:block;width:10px;}.graybox{background-color:#F7FAFC;border:1px solid #EEF1F3;padding:15px;}.graybox.errors{background-color:#FFA5A5;}.graybox.spaced{margin-bottom:10px;}.rounded{-moz-border-radius:6px;-webkit-border-radius:6px;border-radius:6px;}.translation-box h4{border-bottom:1px solid #2D3B58;}.translation-box h4 img{float:right;margin-top:3px;}.html-rtl .translation-box h4 img{float:left;}.translation-box .translation-button img{cursor:pointer;float:left;background-color:#EEE;border:1px solid #EEE;border-bottom:none;padding:2px 5px 3px;margin:5px 0 0 10px;height:1.5em;-moz-border-radius-topleft:6px;-moz-border-radius-topright:6px;-webkit-border-top-left-radius:6px;-webkit-border-top-right-radius:6px;}.html-rtl .translation-box .translation-button img{float:right;margin:5px 10px 0 0;}.translation-box .translation-button.remove img{float:right;}.html-rtl .translation-box .translation-button.remove img{float:left;}.translation-box .translation-button img:hover{background-color:#E4F3FA;}.translation-box .translation-tab{float:left;margin-right:2px;background-color:#DDD;text-align:center;padding:5px;-moz-border-radius-topleft:6px;-moz-border-radius-topright:6px;-webkit-border-top-left-radius:6px;-webkit-border-top-right-radius:6px;width:3.1em;height:1.5em;cursor:pointer;border-bottom:1px solid #FFF;}.html-rtl .translation-box .translation-tab{float:right;margin-right:auto;margin-left:2px;}.translation-box .translation-tab.selected{border:1px solid #1D587F;background-color:#DDF;border-bottom:none;color:#1D587F;}.translation-box .translation-tab:hover{text-decoration:underline;}.translation-box .translation-area{clear:both;margin:0;}.translation-box .translation-maxlength{text-align:right;display:none;}.html-rtl .translation-box .translation-maxlength{text-align:left;}.translation-box .translation-maxlength.selected{display:block;}.translation-box .translation-maxlength img{display:none;}.translation-box .translation-maxlength.over{color:#C33;}.translation-box .translation-maxlength.over img{display:inline;vertical-align:middle;}.translation-box .translation-maxlength span{font-weight:bold;}.translation-box .input{border:1px solid #1D587F;margin:0;-moz-border-radius-bottomleft:6px;-moz-border-radius-bottomright:6px;-webkit-border-bottom-left-radius:6px;-webkit-border-bottom-right-radius:6px;width:100%;display:none;}.translation-box .input.selected{display:block;}.translation-newlocale-container,.translation-deletelocale-container,.translation-help-container,.translation-error-container{display:none;}.translation-newlocale,.translation-deletelocale{border:1px solid #1D587F;margin:0;-moz-border-radius-bottomleft:6px;-moz-border-radius-bottomright:6px;-webkit-border-bottom-left-radius:6px;-webkit-border-bottom-right-radius:6px;width:100%;height:100px;display:none;}.translation-deletelocale.textarea{position:absolute;z-index:10;}.translation-newlocale.selected,.translation-deletelocale{display:block;}.translation-newlocale .padded,.translation-deletelocale .padded,.translation-help .padded{padding:15px;}.translation-newlocale .buttons,.translation-deletelocale .buttons{text-align:center;margin:10px;}.translation-help{background-color:#FFF;margin-bottom:10px;width:630px;display:none;}.graybox .error-message{background:transparent url('../img/developers/exclamation.png') no-repeat 5px 50%;color:red;padding:5px 0 5px 30px;}.html-rtl .graybox .error-message{background-position:100% 50%;padding:5px 25px 5px 0;}#content .addon-listing .date-added{margin:0;float:right;}#content .coll-addon .preview-img{margin:0;}.collections .nav{list-style-type:none;margin:0;padding:0;float:right;}.collections .nav:after{float:left;}.collections .nav li{float:left;margin:5px;}.collections .collections-web li.coll-addon{margin:0;}.collections p.amo-plug{float:right;-moz-border-radius:7px;border:1px solid #d8dcdf;padding:5px;}.collections #content-main h1{font-size:200%;}.collections .cat-name{margin-left:.3em;}.collections .cat-header h3{background:transparent url(../img/fyf/triangle-right.png) scroll no-repeat left 5px;padding-left:20px;margin-right:.4em;}.collections .cat-header.selected h3{background:transparent url(../img/fyf/triangle-down.png) scroll no-repeat left 5px;}.collections #content-main .cat-header p{margin:0;margin-left:20px;padding-right:5px;}.collections ul.addon-listing{padding:0;margin:0;}.collections ul.addon-install-listing{max-height:30em;overflow:auto;}.collections li.list-addon:after,.collections .coll-addon .preview-img:after,.collections .nav:after,#collectionform:after{content:'.';clear:both;display:block;line-height:0;visibility:hidden;width:0;height:0;}.collections li.coll-addon{margin:.2em 2em .2em 2em;padding:.5em 0;border-top:1px solid #ccc;}.collections li.inst-addon{margin:.5em 0;padding:.5em;}.collections .coll-addon .preview-img{max-width:12em;float:left;clear:both;}.collections .coll-addon .preview-img img{float:left;clear:both;margin:.5em 1em 0 0;max-width:12em;max-height:9em;}.collections .list-addon h4{color:#2d3b58;font-size:140%;}.collections .inst-addon .desc h4{width:auto;float:none;}.collections .list-addon .desc{width:81%;margin:.2em 0 0 0;float:left;}.collections .list-addon img.icon{float:left;margin-right:.5em;vertical-align:middle;}.collections .inst-addon .desc{float:left;width:auto;margin:0;}.collections .inst-addon .desc p{font-size:90%;float:left;}.collections .coll-addon h4 a{text-decoration:none;}.collections .list-addon .add-button,.collections .coll-addon .done-box{-moz-border-radius:7px;padding:5px 10px;float:right;}.collections .list-addon .add-button,.collections .coll-addon .done-box{min-width:160px;}.collections .list-addon .done-box{display:none;clear:right;}.collections .list-addon .add-button{background:transparent url(../img/installbtn-bg.png) repeat-x top left;}.collections .coll-addon .add-button{font-weight:bold;}.collections .inst-addon .add-button{margin:1em 1em 0 2em;min-width:15%;}.collections .add-button .add,.collections .add-button input{vertical-align:middle;cursor:pointer;}.collections .add-button .add{color:#062445;}.collections .add-button.upgrade{background:#fff;border:1px solid #d8dcdf;font-size:125%;}.collections #content-main .add-button p{margin:0;font-weight:normal;}.collections .done-box{margin-top:.5em;border:1px solid #d8dcdf;}.collections .installsubmit{margin:1em 0;float:right;}.collections .installsubmit input{font-size:120%;margin:0 .5em;}.collections .faq{float:right;text-align:right;}.jqmWindow{display:none;position:fixed;top:17%;left:50%;margin-left:-400px;width:800px;background-color:#efefef;color:#333;border:1px solid black;padding:12px;}.jqmOverlay{background-color:#000;}* iframe.jqm{position:absolute;top:0;left:0;z-index:-1;width:expression(this.parentNode.offsetWidth+'px');height:expression(this.parentNode.offsetHeight+'px');}* html .jqmWindow{position:absolute;top:expression((document.documentElement.scrollTop || document.body.scrollTop)+Math.round(17 *(document.documentElement.offsetHeight || document.body.clientHeight) / 100)+'px');}#content.landing{width:995px;}#content.landing .crumbs a{color:#5086b6;}#content.landing .categories{position:relative;clear:both;border:none;z-index:3000;}#content.landing .categories h3{display:inline;font-size:189%;padding:0 0 0 10px;}.html-rtl #content.landing .categories h3{padding:0 10px 0 0;}#content.landing .categories .selection .current{font-size:250%;padding:0;margin:5px 0 0 0;font-weight:normal;display:inline;padding:0 3px 0 0;}.html-rtl #content.landing .categories .selection .current{padding:0 0 0 3px;}#content.landing .categories .selection .current a{text-decoration:none;color:#5086b6;background:none;display:inline;padding:0;}#content.landing .categories .selection .current a:hover{color:#000;}#content.landing .categories .selection .current .all{display:inline;padding:4px;background:url('../img/sprite.png?20090430') left -444px no-repeat;}#content.landing .categories .selection .current a:hover .all{background:url('../img/sprite.png?20090430') left -498px no-repeat;}#content.landing .categories.open .current a .all{background:url('../img/sprite.png?20090430') left -498px no-repeat;}#content.landing .categories h3.featured_title{float:left;font-size:24px;padding:0 0 0 .5em;margin:0;}#content.landing .categories h3.featured_title span{font-size:20px;}#content.landing .categories .selections{background-color:#fff;width:410px;list-style:none;margin:0;padding:6px;-moz-box-shadow:4px 7px 7px 2px #888;-webkit-box-shadow:4px 7px 7px 2px #888;box-shadow:4px 7px 7px 2px #888;}.html-rtl #content.landing .categories .selections{-moz-box-shadow:-4px 7px 7px 2px #888;-webkit-box-shadow:-4px 7px 7px 2px #888;box-shadow:-4px 7px 7px 2px #888;}#content.landing .categories.degrade .selections{border-left:1px solid #888;border-right:1px solid #888;border-bottom:1px solid #888;}#content.landing .categories.closed .selections{position:absolute;top:-1000px;left:-100000px;}.html-rtl #content.landing .categories.closed .selections{left:auto;right:-100000px;}#content.landing .categories.open .selections{position:absolute;left:-3px;top:3.3em;z-index:999;-moz-column-count:2;column-count:2;}.html-rtl #content.landing .categories.open .selections{left:auto;right:-3px;}#content.landing .categories.open h2.current{-moz-box-shadow:2px 2px 7px 0 #888;-webkit-box-shadow:2px 2px 7px 0 #888;box-shadow:2px 2px 7px 0 #888;margin:2px 0 -3px -3px;padding:3px;}.html-rtl #content.landing .categories.open h2.current{-moz-box-shadow:-2px 2px 7px 0 #888;-webkit-box-shadow:-2px 2px 7px 0 #888;box-shadow:-2px 2px 7px 0 #888;margin:2px -3px -3px 0;padding:3px;}#content.landing .categories.open.degrade{margin:0 0 12px 0;}#content.landing .categories.open.degrade h2.current{border-top:1px solid #888;border-left:1px solid #888;border-right:1px solid #888;margin:5px -2px 5px -3px;}#content.landing .categories.open.degrade .header{background:#888 none repeat scroll 0 0;display:block;height:1px;left:273px;line-height:0;position:absolute;top:39px;padding:0;}#content.landing .categories.open .current a{color:#000;}#content.landing .categories .selections li{border:none;padding:0;}#content.landing .categories .selections li a{display:block;padding:1px 1px 1px 5px;margin:0 4px 0 0;text-decoration:none;color:#000;background:none;}.html-rtl #content.landing .categories .selections li a{padding:1px 5px 1px 1px;margin:0 0 0 4px;}#content.landing .categories .selections li a:hover{background:#ddd;}#content.landing .search{display:none;}#featured_addons{width:995px;z-index:2;position:relative;}#featured_addons ul{list-style-type:none;margin:0;padding:0;}#featured_addons ul li{display:block;float:left;margin:0;padding:0 8px 8px 0;}.html-rtl #featured_addons ul li{float:right;padding:0 0 8px 8px;}#featured_addons ul li div.addon_block{display:block;position:relative;background:#f9f9f9 url(../img/sprite.png?20090430) no-repeat scroll left -968px;width:299px;height:200px;overflow:hidden;border:1px solid #ececec;-moz-border-radius-topleft:8px;-moz-border-radius-topright:8px;-moz-border-radius-bottomleft:8px;-moz-border-radius-bottomright:8px;-webkit-border-top-left-radius:8px;-webkit-border-top-right-radius:8px;-webkit-border-bottom-left-radius:8px;-webkit-border-bottom-right-radius:8px;border-top-right-radius:8px;border-top-left-radius:8px;border-bottom-right-radius:8px;border-bottom-left-radius:8px;padding:0 0 0 9px;}.html-rtl #featured_addons ul li div.addon_block{padding:0 9px 0 0;}#featured_addons ul li div.addon_block .name{font-size:138%;margin:8px 155px 0 0;line-height:1.25em;}.html-rtl #featured_addons ul li div.addon_block .name{margin:8px 0 0 155px;}#featured_addons ul li div.addon_block .name a{color:black;text-decoration:none;}#featured_addons ul li div.addon_block .preview{position:absolute;top:8px;right:9px;}.html-rtl #featured_addons ul li div.addon_block .preview{right:auto;left:9px;}#featured_addons ul li div.addon_block .preview img{width:138px;}#featured_addons ul li div.addon_block .summary{font-size:93%;line-height:1.5em;margin:0 149px 0 0;max-height:4.5em;overflow:hidden;}.html-rtl #featured_addons ul li div.addon_block .summary{margin:0 0 0 149px;}#featured_addons ul li div.addon_block .authors{font-size:100%;line-height:1.5em;margin:0 145px 0 0;color:#2363a5;}.html-rtl #featured_addons ul li div.addon_block .authors{margin:0 0 0 145px;}#featured_addons ul li div.addon_block .authors a{text-decoration:none;}#featured_addons ul li div.addon_block .rating{font-size:10px;overflow:hidden;margin:2px 0 0 0;}.rating span{display:block;background:transparent url(../img/ratings/5stars.png) no-repeat scroll top left;width:68px;height:12px;text-indent:-1000em;}span.rating-1{background-image:url(../img/ratings/1stars.png);}span.rating-2{background-image:url(../img/ratings/2stars.png);}span.rating-3{background-image:url(../img/ratings/3stars.png);}span.rating-4{background-image:url(../img/ratings/4stars.png);}span.rating-5{background-image:url(../img/ratings/5stars.png);}#featured_addons div.addon_block .install-container{position:absolute;left:7px;bottom:7px;}.html-rtl #featured_addons div.addon_block .install-container{left:auto;right:7px;}#featured_addons div.addon_block .install-container .install-button a{background-position:100% -736px;}#featured_addons div.addon_block .install-container .exp-loggedout .install-button a{background-position:100% -1002px;}#featured_addons div.addon_block .install-container .install-button a span span{padding:0 0 8px;}#featured_addons div.addon_block .install-container .install-button a span span span strong{padding:3px 45px 0 6px;}#featured_addons div.addon_block .install-container .install-button a span span span{padding:0;}#featured_addons div.addon_block .install-container .install-button a:hover,.install-button a:focus,#featured_addons div.addon_block .install-container .install-button a:active{color:#0a3b73;background-color:#9dd34c;background-position:100% -866px;}#featured_addons div.addon_block .install-container .exp-loggedout .install-button a:hover,#featured_addons div.addon_block .install-container .exp-loggedout .install-button a:hover{background-color:#f3f3f3;background-position:100% -1132px;color:#aaa;}#content.landing div.addons_column{float:left;padding:0 9px 8px 0;}.html-rtl #content.landing div.addons_column{float:right;padding:0 0 8px 9px;}#content.landing div.addons_column.last{float:left;padding:0 0 8px 0;}#content.landing div.addons_column.last{float:right;}#content.landing div.addons_column h3{background:#acacac;width:309px;-moz-border-radius-topleft:8px;-moz-border-radius-topright:8px;-webkit-border-top-left-radius:8px;-webkit-border-top-right-radius:8px;border-top-right-radius:8px;border-top-left-radius:8px;}#content.landing div.addons_column h3 span{padding:0 8px 0 8px;text-transform:uppercase;font-size:14px;color:#fff;font-weight:bold;}#content.landing div.addons_column ul{width:309px;list-style:none;margin:0;padding:0;}#content.landing div.addons_column ul li{position:relative;border-left:1px solid #c9c8c9;border-right:1px solid #c9c8c9;margin:0;}#content.landing div.addons_column ul li.even{background:#f0efef;}#content.landing div.addons_column ul li a{height:44px;display:block;text-decoration:none;border:1px solid transparent;background:transparent url(../img/sprite.png?20090430) no-repeat scroll 287px -558px;}.html-rtl #content.landing div.addons_column ul li a{background-position:-363px -558px;}#content.landing div.addons_column ul li a:hover{border-top:1px solid #000;border-left:1px solid #000;border-bottom:1px solid #000;background:transparent url(../img/sprite.png?20090430) no-repeat scroll 287px -670px;}.html-rtl #content.landing div.addons_column ul li a:hover{border-left:1px solid transparent;border-right:1px solid #000;background-position:-363px -670px;}#content.landing div.addons_column ul li a img.icon{position:absolute;top:6px;left:6px;}.html-rtl #content.landing div.addons_column ul li a img.icon{left:auto;right:6px;}#content.landing div.addons_column ul li a .name{display:block;padding:4px 15px 0 0;margin-left:46px;color:#000;font-size:116%;line-height:1.25em;height:1.25em;overflow:hidden;}.html-rtl #content.landing div.addons_column ul li a .name{padding:4px 0 0 15px;margin-left:0;margin-right:46px;}#content.landing div.addons_column ul li a .rating{margin-left:46px;display:block;}.html-rtl #content.landing div.addons_column ul li a .rating{margin-left:0;margin-right:46px;}#content.landing div.addons_column ul li a .meta{display:block;margin-left:46px;font-size:93%;color:#777;position:absolute;bottom:6px;}.html-rtl #content.landing div.addons_column ul li a .meta{margin-left:0;margin-right:46px;}#content.landing div.addons_column .view-all{color:#fff;font-weight:bold;background:#acacac;-moz-border-radius-bottomleft:8px;-moz-border-radius-bottomright:8px;-webkit-border-bottom-left-radius:8px;-webkit-border-bottom-right-radius:8px;border-bottom-right-radius:8px;border-bottom-left-radius:8px;padding:2px 0 2px 9px;}.html-rtl #content.landing div.addons_column .view-all{padding:2px 9px 2px 0;}#content.landing div.addons_column .view-all a:link,#content.landing div.addons_column .view-all a:visited,#content.landing div.addons_column .view-all a:hover,#content.landing div.addons_column .view-all a:active{color:#fff;text-decoration:none;font-size:93%;}#content.landing div.addons_column .view-all a:hover{text-decoration:underline;}.clearfix:after{content:".";display:block;clear:both;visibility:hidden;line-height:0;height:0;}.clearfix{display:inline-block;}html[xmlns] .clearfix{display:block;}* html .clearfix{height:1%;}.notification-box{border:1px solid;display:block;padding:10px;}.notification-box.warning{border-color:red;background-color:#FFA5A5;}.collections #addonname{width:200px;}.collections #selectedaddons{width:80%;overflow:auto;max-height:300px;}.collections #selectedaddons>ul{-moz-column-count:2;}.collections #firstaddons{display:none;}.ac_input{width:400px;}.ac_results{padding:0;border:1px solid WindowFrame;background-color:Window;overflow-x:hidden;overflow-y:auto;max-height:400px;}.ac_results ul{width:100%;list-style-position:outside;list-style:none;padding:0;margin:0;}.ac_results iframe{display:none;display:block;position:absolute;top:0;left:0;z-index:-1;filter:mask();width:3000px;height:3000px;}.ac_results li{margin:0;padding:2px 5px;cursor:pointer;display:block;width:100%;font:menu;font-size:12px;overflow:hidden;}.ac_loading{background:url('../img/ajax_loading.gif') right center no-repeat;}.ac_over{background-color:Highlight;color:HighlightText;}#coll-edit .jsonly{display:none;}#coll-edit .error,#coll-edit .error_message{color:#f00;}#coll-edit .coll-addon{padding-bottom:10px;margin-bottom:10px;border-bottom:solid 1px #ddd;}#coll-edit .coll-addon .name{font-weight:bold;}#coll-edit .coll-addon .added{float:right;font-style:italic;}#coll-edit .coll-addon a.removeaddon{float:right;}#collections input#submitbutton{margin:10px;}}@media print{#nav-access,h1,#nav-user,#search-form,#other-apps{display:none;}#sidebar,#footer-lang-form,.pitch,.extra .view-all{display:none;}.install-button,.exp-loggedout,.learn-more,.more-from{display:none;}#form-review,.pagination,#form-listcontrol{display:none;}body{font:12pt/1.5 "Helvetica Neue",Helvetica,Arial,sans-serif;padding:0 .25in;background-color:#fff;color:#000;}h2,h3,h4,h5,h6{font-family:Georgia,"Times New Roman",Times,serif;margin-bottom:.25em;}h2{font-size:15pt;}h3{font-size:14pt;}h4,h5,h6{font-size:100%;}a img{border:none;}#page-title{height:120px;}#page-title h2{position:relative;padding-left:125px;}#page-title h2 img{position:absolute;top:0;left:0;}#page-title p.page-intro{color:#666;padding-left:125px;font-size:90%;}.addon{border:1px solid #ccc;padding:.5em 1em .5em 240px;margin-bottom:1em;position:relative;}.addon .preview-img{position:absolute;top:.5em;left:1em;}.author{margin-top:0;}.name a,.author a{text-decoration:none;}.name a:after,.author a:after,.extra a:after,#nav-legal a:after{content:" [" attr(href) "] ";font-size:90%;}.addon .flag{position:absolute;top:-1px;right:-1px;margin:0;padding:.2em 1em;border:3px double #000;}.rec .flag{color:#360;}.exp .flag{color:#900;}#content-main{padding-right:35%;position:relative;}#content-extra{width:30%;position:absolute;right:0;top:0;}#content.search #content-main,#content.category #content-main{padding-right:0;}.extra ul{margin-left:0;}#footer{color:#666;font-size:90%;margin-top:1em;border-top:3px double #ccc;}.addon-images{list-style:none;margin:0 0 1em;padding:0;}.addon-images li{display:inline;margin-right:10px;}.addon-images a img{vertical-align:top;margin-bottom:10px;}.addon-reviews{list-style:none;margin:0 0 1em;padding:0;}.addon-reviews li{border:1px solid #ccc;padding:.5em 1em;margin-bottom:1em;}.addon-reviews blockquote{margin:0;}#addon-listing{list-style:none;margin:0;padding:0;}} \ No newline at end of file
diff --git a/site/app/webroot/css/summary.css b/site/app/webroot/css/summary.css
new file mode 100644
index 0000000..c317209
--- /dev/null
+++ b/site/app/webroot/css/summary.css
@@ -0,0 +1,26 @@
+/* summary */
+table.stats {
+ padding: 5px;
+ float: left;
+ margin-right: 20px;
+}
+table.log {
+ padding: 5px;
+ float: left;
+}
+table.stats td.heading,
+table.log td.heading {
+ background: #ddddff;
+ font-weight: bold;
+ text-align: center;
+}
+table.stats td.title {
+ width: 10em;
+ border-bottom: 1px solid gray;
+}
+table.stats td.value {
+ background: #eeeeee;
+ width: 4em;
+ text-align: center;
+ border-bottom: 1px solid gray;
+} \ No newline at end of file
diff --git a/site/app/webroot/css/tests.css b/site/app/webroot/css/tests.css
new file mode 100644
index 0000000..1a272a8
--- /dev/null
+++ b/site/app/webroot/css/tests.css
@@ -0,0 +1,136 @@
+body {
+ font-family: Verdana;
+ font-size: 12px;
+}
+div.groupdivider {
+ border-bottom: 1px solid black;
+ margin-top: 5px;
+ height: 20px;
+}
+
+div.groupdivider div.header {
+ font-weight: bold;
+ font-size: 14px;
+ float: left;
+ width: 49%;
+}
+div.groupdivider div.victim {
+ float: right;
+ width: 49%;
+ text-align: right;
+}
+
+div.pass {
+ background: #CCFFCC;
+}
+span.pass {
+ color: green;
+ font-weight: bold;
+}
+
+div.fail {
+ background: #FFCCCC;
+}
+span.fail {
+ color: red;
+ font-weight: bold;
+}
+
+a:link {
+ color: black;
+}
+a:visited {
+ color: gray;
+}
+a:active {
+ color: black;
+}
+a:hover {
+ text-decoration: none;
+}
+
+.menu {
+ border-bottom: 1px solid black;
+}
+.name {
+ font-size: 14px;
+ font-weight: bold;
+ color: navy;
+}
+.title {
+ font-size: 20px;
+ font-weight: bold;
+}
+.getit {
+ font-size: 8px;
+}
+.items {
+ float: right;
+ font-weight: bold;
+}
+.items a:link {
+ text-decoration: none;
+}
+.items a:visited {
+ color: black;
+ text-decoration: none;
+}
+.items a:active {
+ color: black;
+ text-decoration: none;
+}
+.items a:hover {
+ color: gray;
+ text-decoration: none;
+}
+.items .svn {
+ color: navy;
+}
+
+.testlist li {
+ list-style: none;
+ margin-left: 0;
+ text-indent: -1em;
+}
+.testlist li.directory:before {
+ content: "\00BB \0020";
+}
+.testlist li.file:before {
+ content: "\203A \0000";
+ margin-right: 2px;
+}
+
+.testlist li.directory a:link {
+ text-decoration: none;
+ color: black;
+ font-weight: bold;
+}
+.testlist li.directory a:visited {
+ text-decoration: none;
+ color: black;
+ font-weight: bold;
+}
+
+div.autocomplete {
+ position:absolute;
+ width:250px;
+ background-color:white;
+ border:1px solid #888;
+ margin:0px;
+ padding:0px;
+}
+div.autocomplete ul {
+ list-style-type:none;
+ margin:0px;
+ padding:0px;
+}
+div.autocomplete ul li.selected { background-color: #ffb;}
+div.autocomplete ul li {
+ list-style-type:none;
+ display:block;
+ margin:0;
+ padding:2px;
+ height:16px;
+ cursor:pointer;
+ text-align: left;
+}
diff --git a/site/app/webroot/css/thickbox.css b/site/app/webroot/css/thickbox.css
new file mode 100644
index 0000000..9da58e8
--- /dev/null
+++ b/site/app/webroot/css/thickbox.css
@@ -0,0 +1,129 @@
+/* ----------------------------------------------------------------------------------------------------------------*/
+/* ---------->>> global settings needed for thickbox <<<-----------------------------------------------------------*/
+/* ----------------------------------------------------------------------------------------------------------------*/
+/* *{padding: 0; margin: 0;} */
+
+html, body {
+min-height: 100%;
+/* height: auto !important; */
+height: 100%
+}
+
+/* ----------------------------------------------------------------------------------------------------------------*/
+/* ---------->>> thickbox specific link and font settings <<<------------------------------------------------------*/
+/* ----------------------------------------------------------------------------------------------------------------*/
+#TB_window {
+ font: 12px Arial, Helvetica, sans-serif;
+ color: #333333;
+}
+
+#TB_secondLine {
+ font: 10px Arial, Helvetica, sans-serif;
+ color:#666666;
+}
+
+#TB_window a:link {color: #666666;}
+#TB_window a:visited {color: #666666;}
+#TB_window a:hover {color: #000;}
+#TB_window a:active {color: #666666;}
+#TB_window a:focus{color: #666666;}
+
+/* ----------------------------------------------------------------------------------------------------------------*/
+/* ---------->>> thickbox settings <<<-----------------------------------------------------------------------------*/
+/* ----------------------------------------------------------------------------------------------------------------*/
+#TB_overlay {
+ position: absolute;
+ z-index:100;
+ top: 0px;
+ left: 0px;
+ background-color:#000;
+ -moz-opacity: 0.6;
+ opacity: 0.6;
+}
+
+#TB_window {
+ position: absolute;
+ background: #ffffff;
+ z-index: 102;
+ color:#000000;
+ display:none;
+ border: 4px solid #525252;
+ text-align:left;
+}
+
+#TB_window img {
+ display:block;
+ margin: 15px 0 0 15px;
+ border-right: 1px solid #ccc;
+ border-bottom: 1px solid #ccc;
+ border-top: 1px solid #666;
+ border-left: 1px solid #666;
+}
+
+#TB_caption{
+ height:25px;
+ padding:7px 30px 10px 25px;
+ float:left;
+}
+
+#TB_closeWindow{
+ height:25px;
+ padding:11px 25px 10px 0;
+ float:right;
+}
+
+#TB_closeAjaxWindow{
+ padding:5px 10px 7px 0;
+ margin-bottom:1px;
+ text-align:right;
+ float:right;
+}
+
+#TB_ajaxWindowTitle{
+ float:left;
+ padding:7px 0 5px 10px;
+ margin-bottom:1px;
+}
+
+#TB_title{
+ background-color:#e8e8e8;
+ height:27px;
+}
+
+#TB_ajaxContent{
+ clear:both;
+ padding:2px 15px 15px 15px;
+ overflow:auto;
+ text-align:left;
+ line-height:1.4em;
+}
+
+#TB_ajaxContent p{
+ padding:5px 0px 5px 0px;
+}
+
+#TB_load{
+ position: absolute;
+ display:none;
+ height:100px;
+ width:100px;
+ z-index:101;
+}
+
+#TB_HideSelect{
+ z-index:99;
+ position:absolute;
+ top: 0;
+ left: 0;
+ background-color:#fff;
+ border:none;
+ -moz-opacity: 0;
+ opacity: 0;
+}
+
+#TB_iframeContent{
+ clear:both;
+ border:none;
+ margin-bottom:-1px;
+ margin-top:1px;
+}
diff --git a/site/app/webroot/css/type.css b/site/app/webroot/css/type.css
new file mode 100644
index 0000000..f6eaa8a
--- /dev/null
+++ b/site/app/webroot/css/type.css
@@ -0,0 +1,176 @@
+/*----------------------------------------------------------------------------
+Typography CSS file for Addons.mozilla.org
+Created by Craig Cook - focalcurve.com
+ on December 30, 2007
+-----------------------------------------------------------------------------*/
+
+/*** =Reset defaults ***/
+html, body, div, span, object, iframe,
+h1, h2, h3, h4, h5, h6, p, blockquote, pre,
+a, abbr, acronym, address, code,
+del, dfn, em, img, q, dl, dt, dd, ol, ul, li,
+fieldset, form, label, legend,
+table, caption, tbody, tfoot, thead, tr, th, td {
+ font-weight: inherit;
+ font-style: inherit;
+ font-size: 100%;
+ font-family: inherit;
+ vertical-align: baseline;
+}
+
+/* Tables still need 'cellspacing="0"' in the markup. */
+caption, th, td { text-align: left; font-weight:400; }
+
+/* Remove possible quote marks (") from <q>, <blockquote>. */
+blockquote:before, blockquote:after, q:before, q:after { content: ""; }
+blockquote, q { quotes: "" ""; }
+
+form ol, form ul { list-style: none; }
+input, button, select, textarea { font-family: inherit; font-size: inherit; color: inherit; }
+
+/*** =General elements ***/
+body { font: 62.5%/1.6 Verdana, "Trebuchet MS", sans-serif; }
+a:link { text-decoration: underline; }
+
+h1, h2, h3, h4, h5, h6, caption, #rate-it legend { font-family: "Trebuchet MS", Helvetica, "Helvetica Neue", Arial, sans-serif; }
+
+h2 { font-weight: bold; font-size: 140%; }
+h3, caption { font-size: 140%; }
+h4, #rate-it legend { font-size: 125%; }
+
+dt { font-weight: bold; }
+thead th { font-size: 95%; }
+
+/*** =Site-notice ***/
+#site-notice { font-size: 110%; }
+
+/*** =Access nav ***/
+#nav-access { list-style: none; font-size: 115%; }
+#nav-access a:active, #nav-access a:focus { text-align: center; }
+
+/*** =Header ***/
+h4#moz { font-weight: bold; font-size: 130%; }
+
+/* =Page title */
+#page-title h1 { font-weight: bold; font-size: 300%; line-height: 1.2; }
+#page-title h1 a { text-decoration: none; }
+#page-title h2 { font-size: 220%; }
+#page-title p.page-intro { line-height: 1.25; font-size: 125%; font-weight: bold; }
+
+/* =User nav */
+#nav-user { text-align: right; font-size: 115%; }
+#nav-user a:link, #nav-user a:visited { text-decoration: none; }
+#nav-user a:hover, #nav-user a:active, #nav-user a:focus { text-decoration: underline; }
+
+/* =Other Applications */
+#other-apps h3 { font-size: 100%; }
+#nav-apps { list-style: none; font: bold 110% "Trebuchet MS", Helvetica, "Helvetica Neue", Arial, sans-serif; }
+#other-apps.js #nav-apps { font-size: 130%; }
+#nav-apps a { text-decoration: none; }
+
+/*** =Search form ***/
+#search-form { font-size: 100%; }
+#search-form #search-query label, #search-form #query, #search-form #category { font-size: 140%; }
+#search-form #search-category { white-space: nowrap; }
+
+/*** =Footer ***/
+#nav-legal { list-style: none; }
+#footer-disclaimer { text-align: center; }
+
+/*** =Content ***/
+#content { font-size: 120%; }
+
+/*** =Extra content ***/
+#content-extra h3 { font-size: 110%; }
+#content-extra .nav-addon h3 { font-size: 130%; }
+#content-extra ul { font-size: 98%; }
+#content-extra p.view-all { text-align: right; }
+
+/*** =Categories ***/
+#categories h3 { font-size: 120%; }
+#cat-list { list-style: none; }
+#categories a:link, #categories a:visited { text-decoration: none; }
+#categories p { line-height: 1.4; }
+
+
+
+/*** =Add-on boxes ***/
+.addon .name { font-size: 180%; line-height: 1.2; font-weight: normal; }
+.addon .author { font-size: 100%; }
+.addon .name a, .addon .author a { text-decoration: none; }
+.addon .name a:hover, .addon .author a:hover { text-decoration: underline; }
+.addon .rating, .addon .stats, .addon .updated { font-size: 95%; }
+.addon .stats em { font-style: normal; }
+.addon .more-from { font-size: 90%; }
+.addon .flag { /*text-transform: uppercase;*/ font-size: 100%; line-height: 1; }
+
+/* =Primary featured add-on */
+.main .name { font-size: 200%; }
+
+/* =Secondary featured add-ons */
+.sub .name { font-size: 150%; }
+.sub .preview-img { text-align: center; }
+.sub .desc { font-size: 98%; }
+
+/* =Listing items */
+#addon-listing { list-style: none; }
+#addon-listing .author { font-size: 100%; }
+#addon-listing .more { list-style: none; font-size: 95%; }
+
+/*** =Install button ***/
+.install-button { font: bold 120% "Trebuchet MS", Helvetica, "Helvetica Neue", Arial, sans-serif; }
+.install-button a { text-decoration: none; }
+.exp-loggedout, .exp-confirmed { font-size: 90%; }
+.exp-loggedout .install-button a,
+.exp-confirmed .install-button a { font-size: 110%; text-align: left; }
+
+/*** =Pitch ***/
+.pitch h3 { font-size: 100%; font-weight: bold; line-height: 1.2; }
+.pitch h3 a { text-decoration: none; }
+.pitch p { font-size: 95%; }
+
+/*** =Landing pages ***/
+#recommended .name { font-size: 160%; }
+#content.landing #secondaries .sub .flag { font-size: 95%; }
+#content.landing .more-addons h3 { font-size: 130%; }
+#content.landing .more-addons ul { list-style: none; }
+#content.browse .more-addons h3 { text-align: center; }
+.browse-list a { text-decoration: none; font-weight: bold; }
+#dictionaries tbody th { font-weight: bold; }
+
+/*** =Detail page ***/
+#addon-summary .name { font-size: 200%; }
+.addon-cats { list-style: none; font-size: 95%; }
+.addon-cats a:link, .addon-cats a:visited { text-decoration: none; }
+.addon-cats a:hover, .addon-cats a:active, .addon-cats a:focus { text-decoration: underline; }
+.addon-images, .addon-reviews { list-style: none; }
+.addon-images a img { vertical-align: top; }
+.addon-reviews .cite { font-size: 95%; }
+#license a { font-size: 70%; }
+.oldversion .license a { font-size: 80%; }
+
+/* =Review form */
+#form-review #review-submit { font-size: 90%; }
+
+/* =reCaptchas */
+#recaptcha_whatsthis { font-size: 90% }
+
+/* =Star rating */
+/*ul.star-rating { list-style: none; }*/
+
+/* =More add-ons */
+.more-addons h3 { line-height: 1.3; }
+.more-addons h3 a.view { text-decoration: none; }
+.more-addons h4 { font-size: 100%; }
+
+/*** =Pagination ***/
+.pages { list-style: none; text-align: left; }
+.pagination p.count, .pagination p.perpage { text-align: right; }
+
+/*** =Listing control bar ***/
+#form-listcontrol { font-family: "Trebuchet MS", Helvetica, "Helvetica Neue", sans-serif; }
+#form-listcontrol #per-page { font-size: 110%; font-weight: bold; }
+#order-by button { text-align: center; }
+#form-listcontrol #experimental label { font-size: 95%; line-height: 1.1; }
+
+
diff --git a/site/app/webroot/disabled.php b/site/app/webroot/disabled.php
new file mode 100644
index 0000000..152a20d
--- /dev/null
+++ b/site/app/webroot/disabled.php
@@ -0,0 +1,90 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html lang="en-US" dir="ltr">
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+ <link rel="stylesheet" type="text/css" href="/css/rustico.css" />
+ <link rel="shortcut icon" href="/img/favicon.ico" type="image/x-icon" />
+
+ <title>addons.mozilla.org temporarily disabled</title>
+
+ <style type="text/css">
+ div#content {
+ font-weight:bold;
+ margin-left: auto;
+ margin-right:auto;
+ width:400px;
+ padding: 20px;
+ }
+ </style>
+</head>
+
+
+<body id="mozilla-com">
+
+<div id="header">
+ <div>
+
+ <h1><a href="http://www.mozilla.com/en-US" title="mozilla.com" accesskey="1"><img src="/img/template/moz-com-logo.png" alt="Mozilla Corporation" title="Mozilla Corporation" height="38" width="89" border="0" /></a></h1>
+ <ul>
+ <li id="menu-products"><a href="http://www.mozilla.com/products/?flang=en-US">Products</a></li>
+ <li id="menu-extensions"><a href="/en-US/firefox/" class="current">Add-ons</a></li>
+ <li id="menu-support"><a href="http://www.mozilla.com/support/?flang=en-US">Support</a></li>
+ <li id="menu-developers"><a href="http://www.mozilla.com/developers/?flang=en-US">Developers</a></li>
+ <li id="menu-about"><a href="http://www.mozilla.com/about/?flang=en-US">About</a></li>
+
+ </ul>
+ </div>
+</div>
+
+<div id="breadcrumbs">
+ <div id="breadcrumbs_container">
+
+ </div>
+</div>
+
+<div id="container">
+
+<div id="content">
+
+<div class="frontpage-welcome">
+</div>
+<div class="corner-box" id="home-intro">
+
+<p>addons.mozilla.org is currently disabled. We're sorry for any inconvenience and
+we're working on fixing it as fast as we can. Thanks for your patience.</p>
+ <p>-- the AMO team</p>
+</div>
+
+<!-- end #content -->
+</div>
+
+
+
+<!-- end #container -->
+
+</div>
+
+<!-- start #footer -->
+<div id="footer">
+<div id="footer-contents">
+
+<div id="footer-legal">
+ <p>Copyright &#169; 2005&#8211;2007 Mozilla. All rights reserved.</p>
+ <p>
+ <a href="http://www.mozilla.com/en-US/about/legal.html">Legal Notices</a>
+ </p>
+</div>
+
+<div id="footer-disclaimer">
+ <p>Mozilla is providing links to these applications as a courtesy, and makes no representations regarding the applications or any information related there to. Any questions, complaints or claims regarding the applications must be directed to the appropriate software vendor.</p>
+</div>
+
+</div>
+<!-- end #footer-contents -->
+
+</div>
+<!-- end #footer -->
+
+
+</body>
+</html>
diff --git a/site/app/webroot/ebay/ebay-extension/eBay32x32.png b/site/app/webroot/ebay/ebay-extension/eBay32x32.png
new file mode 100644
index 0000000..07de3c9
--- /dev/null
+++ b/site/app/webroot/ebay/ebay-extension/eBay32x32.png
Binary files differ
diff --git a/site/app/webroot/ebay/ebay-extension/ebay-0.9.6.5.xpi b/site/app/webroot/ebay/ebay-extension/ebay-0.9.6.5.xpi
new file mode 100644
index 0000000..b29e6dd
--- /dev/null
+++ b/site/app/webroot/ebay/ebay-extension/ebay-0.9.6.5.xpi
Binary files differ
diff --git a/site/app/webroot/ebay/ebay-extension/ebay_extension.html b/site/app/webroot/ebay/ebay-extension/ebay_extension.html
new file mode 100644
index 0000000..d1da634
--- /dev/null
+++ b/site/app/webroot/ebay/ebay-extension/ebay_extension.html
@@ -0,0 +1,31 @@
+<html>
+<script language="JavaScript" type="text/javascript" src="../../js/__utm.js"></script>
+<script type="text/javascript">
+ function install() {
+ if (document.referrer.match(/^https?:\/\/[^\/]*\.mozilla\.com\/?.*/) ||
+ document.referrer.match(/^https?:\/\/[^\/]*\.ebay\.(co\.uk|fr|de)\/?.*/)
+ ) {
+ var params = {
+ /* Hash must be updated anytime the file changes or users won't be able to install */
+ 'Firefox Companion for eBay': {
+ URL: 'http://releases.mozilla.org/pub/mozilla.org/addons/5202/firefox_companion_for_ebay-1.6.6-fx-win.xpi',
+ IconURL: 'eBay32x32.png',
+ Hash: 'sha1:3d89ec5586bd224bc80d7bd669873bb98f09755c',
+ toString: function () { return this.URL; }
+ }
+ };
+ InstallTrigger.install(params, goBack);
+ } else {
+ window.location.href='http://addons.mozilla.org/';
+ }
+ }
+
+ function goBack() {
+ history.back();
+ }
+</script>
+
+<body onload="install()">
+</body>
+</html>
+
diff --git a/site/app/webroot/ebay/ebay-extension/update.rdf b/site/app/webroot/ebay/ebay-extension/update.rdf
new file mode 100644
index 0000000..3f13881
--- /dev/null
+++ b/site/app/webroot/ebay/ebay-extension/update.rdf
@@ -0,0 +1,26 @@
+<?xml version="1.0"?>
+<RDF:RDF xmlns:RDF="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:em="http://www.mozilla.org/2004/em-rdf#">
+ <RDF:Description about="urn:mozilla:extension:{62760FD6-B943-48C9-AB09-F99C6FE96088}">
+ <em:updates>
+ <RDF:Seq>
+ <RDF:li resource="urn:mozilla:extension:{62760FD6-B943-48C9-AB09-F99C6FE96088}:1.0"/>
+ </RDF:Seq>
+ </em:updates>
+ <em:version>1.0</em:version>
+ <em:updateLink>http://releases.mozilla.org/pub/mozilla.org/addons/5202/firefox_companion_for_ebay-1.6.6-fx-win.xpi</em:updateLink>
+ <em:updateHash>sha1:3d89ec5586bd224bc80d7bd669873bb98f09755c</em:updateHash>
+ </RDF:Description>
+ <RDF:Description about="urn:mozilla:extension:{62760FD6-B943-48C9-AB09-F99C6FE96088}:1.0">
+ <em:version>1.0</em:version>
+ <em:targetApplication>
+ <Description>
+ <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
+ <em:minVersion>2.0</em:minVersion>
+ <em:maxVersion>2.0.0.*</em:maxVersion>
+ <em:updateLink>http://releases.mozilla.org/pub/mozilla.org/addons/5202/firefox_companion_for_ebay-1.6.6-fx-win.xpi</em:updateLink>
+ <em:updateHash>sha1:3d89ec5586bd224bc80d7bd669873bb98f09755c</em:updateHash>
+ </Description>
+ </em:targetApplication>
+ </RDF:Description>
+</RDF:RDF>
+
diff --git a/site/app/webroot/files/10/del.icio.us.src b/site/app/webroot/files/10/del.icio.us.src
new file mode 100644
index 0000000..7b18a86
--- /dev/null
+++ b/site/app/webroot/files/10/del.icio.us.src
@@ -0,0 +1,26 @@
+<!-- del.icio.us search plugin
+ Author: Alessandro Macilenti
+ Email: alessandro.macilenti@gmail.com
+ Created on: June 15th, 2005
+-->
+
+<search name="del.icio.us tag"
+ description="A plugin to search del.icio.us tags"
+ action="http://del.icio.us/tag/"
+ searchForm="http://del.icio.us/tag/"
+ method="GET"
+ version="7.1"
+>
+ <input name="tags" user="">
+ <interpret
+ resultListStart="delMain"
+ resultListEnd="/html"
+ resultItemStart="delPost"
+ resultItemEnd="/div"
+ >
+</search>
+<browser
+ update="http://mycroft.mozdev.org/update.php/id0/del.icio.us.src"
+ updateicon="http://mycroft.mozdev.org/update.php/id0/del.icio.us.png"
+ updateCheckDays="7"
+> \ No newline at end of file
diff --git a/site/app/webroot/files/11/IMDB.src b/site/app/webroot/files/11/IMDB.src
new file mode 100644
index 0000000..c1d329c
--- /dev/null
+++ b/site/app/webroot/files/11/IMDB.src
@@ -0,0 +1,47 @@
+# Mozilla Search Plugin for IMDB - The Internet Movie Database
+#
+# by Aaron Bronow <adwb.no-ip.com>
+# Original source by Yoav Ben-Yaar <yoav_by at hotmail dot com>
+# Last updated: 20 April, 2004 by Aaron Bronow <adwb.no-ip.com>
+#
+
+<SEARCH
+ version = "7.1"
+ name = "IMDB"
+ description = "IMDB Movie Search"
+ method = "GET"
+ action = "http://www.imdb.com/find"
+ searchForm = "http://www.imdb.com/"
+>
+
+<INPUT NAME="q" user>
+<INPUT NAME="sourceid" VALUE="mozilla-search">
+
+
+# searching all
+<INTERPRET
+ browserResultType = "result"
+ resultListStart = "Matches"
+ resultListEnd = '</table>'
+ resultItemStart = "<td "
+ resultItemEnd = "</td>"
+>
+
+# searching specific results
+<INTERPRET
+ browserResultType = "result"
+ resultListStart = "<H1>"
+ resultListEnd = '<p class="footer" align="center">'
+ resultItemStart = "<LI>"
+ resultItemEnd = "</LI>"
+>
+
+</SEARCH>
+
+
+<BROWSER
+ alsomatch = "http://www.imdb.com/find http://www.imdb.com/Find http://us.imdb.com/find http://us.imdb.com/Find"
+ update = "http://mycroft.mozdev.org/plugins/IMDB.src"
+ updateIcon = "http://mycroft.mozdev.org/plugins/IMDB.png"
+ updateCheckDays = "3"
+> \ No newline at end of file
diff --git a/site/app/webroot/files/12/wikipedia.src b/site/app/webroot/files/12/wikipedia.src
new file mode 100644
index 0000000..d0fb01a
--- /dev/null
+++ b/site/app/webroot/files/12/wikipedia.src
@@ -0,0 +1,43 @@
+# Mozilla search plugin for English Wikipedia en.wikipedia.org
+# by Carey Evans <carey.evans@gmail.com>.
+# http://carey.geek.nz/code/wikipedia-searchplugin/
+# This file is released into the public domain.
+# Thanks: Michael Franz, Dwayne C. Litzenberger.
+#
+# Version: 1.4.2 (2005-07-27)
+# Country: WW
+# Language: en
+
+<search
+ version="7.1"
+ name="Wikipedia (EN)"
+ description="English Wikipedia"
+ sourceTextEncoding="0"
+ method="GET"
+ action="http://en.wikipedia.org/wiki/Special:Search"
+ queryCharset="UTF-8"
+ searchForm="http://en.wikipedia.org/"
+>
+
+<input name="search" user>
+<input name="fulltext" value="fulltext">
+<input name="sourceid" value="mozilla-search">
+
+<interpret
+ browserResultType="result"
+ charset="UTF-8"
+ language="en"
+ resultListStart="<div id='results'></div>"
+ resultListEnd="<hr/>"
+ resultItemStart="<li style='padding-bottom: 1em'>"
+ resultItemEnd="</li>"
+>
+
+</search>
+
+<browser
+ alsomatch="http://en.wikipedia.org/w/index.php?title=Special:Search"
+ update="http://mycroft.mozdev.org/update.php/id0/wikipedia.src"
+ updateicon="http://mycroft.mozdev.org/update.php/id0/wikipedia.png"
+ updateCheckDays="7"
+> \ No newline at end of file
diff --git a/site/app/webroot/files/13/a9.src b/site/app/webroot/files/13/a9.src
new file mode 100644
index 0000000..7079e2a
--- /dev/null
+++ b/site/app/webroot/files/13/a9.src
@@ -0,0 +1,75 @@
+# Status: working beta
+# Mozilla/Netscape 6+ plugin for A9.com
+# by Christian Gosselin <chr_gosselin@yahoo.ca>
+#
+# Created: April 14, 2004
+# Last updated: April 24, 2004
+# Updated by: Paul Millar (dazzle@edazzle.net)
+#
+# Updated:
+# Now displays web, (if open), and book results, (if open), and Search history if logged in.
+
+<search
+ version="7.1"
+ name="A9"
+ description="A9.com Search - Web Results and Search Inside The Book"
+ action="http://a9.com/"
+ searchForm="http://a9.com/"
+ queryEncoding="UTF-8"
+ queryCharset="UTF-8"
+ method="GET" >
+
+<input name="q" user>
+<input name="sourceid" value="mozilla-search">
+
+<interpret
+
+ browserResultType="result"
+
+ resultListStart="<a onclick="return collapseColumn(event)" href="?a=cw" class="wl-b">Web Results </a>"
+ resultListEnd="<a href="/-/company/help.jsp#websearch" class="about">About</a>"
+
+ resultItemStart="<div style="margin-bottom: 1em;" align="left">"
+ resultItemEnd="</div>"
+
+>
+
+<interpret
+
+ browserResultType="result"
+
+ resultListStart="<span id="bookPageMsg"></span>"
+ resultListEnd=" <td align="right"><a href="/-/company/help.jsp#booksearch" class="about">About</a>"
+ resultItemStart="<a class="r-a""
+ resultsItemEnd="</a>"
+
+>
+
+<interpret
+
+ browserResultType="result"
+
+ resultListStart="<ul>"
+ resultListEnd="</ul>"
+ resultItemStart="<li>"
+ resultsItemEnd="</li>"
+
+>
+
+<interpret
+
+ browserResultType="result"
+
+ resultListStart="Searches within:"
+ resultListEnd="<td></td><td>"
+ resultItemStart="<td align="left">"
+ resultsItemEnd="</a>"
+
+>
+</search>
+
+<browser
+ update="http://mycroft.mozdev.org/plugins/a9.src"
+ updateIcon="http://mycroft.mozdev.org/plugins/a9.png"
+ updateCheckDays="3"
+>
diff --git a/site/app/webroot/files/3677/arabic_spell-checking_dictionary-1.2b1-fx+zm+tb.xpi b/site/app/webroot/files/3677/arabic_spell-checking_dictionary-1.2b1-fx+zm+tb.xpi
new file mode 100644
index 0000000..ba38392
--- /dev/null
+++ b/site/app/webroot/files/3677/arabic_spell-checking_dictionary-1.2b1-fx+zm+tb.xpi
Binary files differ
diff --git a/site/app/webroot/files/4023/microdefender-1.0-fx+tb.xpi b/site/app/webroot/files/4023/microdefender-1.0-fx+tb.xpi
new file mode 100644
index 0000000..6b4bbdf
--- /dev/null
+++ b/site/app/webroot/files/4023/microdefender-1.0-fx+tb.xpi
Binary files differ
diff --git a/site/app/webroot/files/5/google.src b/site/app/webroot/files/5/google.src
new file mode 100644
index 0000000..89a1e6f
--- /dev/null
+++ b/site/app/webroot/files/5/google.src
@@ -0,0 +1,48 @@
+# Mycroft Search Plugin for Mozilla, Firebird, Netscape 6+, Beonix browsers
+# Mycroft Homepage: http://mycroft.mozdev.org
+
+# SearchSite: Google (www.google.com)
+# Based on GoogleUK originally written by amitp@google.com, wolfgang.schroedl@gmx.net & juliusross@mac.com
+# Status: Working Full
+#
+# Country: WW
+# Language: en
+# Category: General
+#
+# Original Author: amitp+mozilla@google.com
+# Last updated December 14, 2005 (CC, TIDY)
+
+<search
+ version = "7.1"
+ name="Google US"
+ description="Google Search"
+ method="GET"
+ action="http://www.google.com/search"
+ searchform="http://www.google.com"
+ queryCharset="UTF-8"
+>
+
+<input name="q" user>
+<input name="le" value="en">
+<input name="btnG" value="Google+Search">
+<input name="sourceid" value="Mozilla-search">
+
+<inputnext name="start" factor="20">
+<inputprev>
+
+<interpret
+ browserResultType="result"
+ charset = "UTF-8"
+ resultListStart="<!--a-->"
+ resultListEnd="<!--z-->"
+ resultItemStart="<!--m-->"
+ resultItemEnd="<!--n-->"
+>
+
+</search>
+
+<BROWSER
+ update="http://mycroft.mozdev.org/update.php/id2/google.src"
+ updateIcon="http://mycroft.mozdev.org/update.php/id2/google.gif"
+ updateCheckDays="7"
+> \ No newline at end of file
diff --git a/site/app/webroot/files/7/farming.xpi b/site/app/webroot/files/7/farming.xpi
new file mode 100644
index 0000000..cb07fa4
--- /dev/null
+++ b/site/app/webroot/files/7/farming.xpi
Binary files differ
diff --git a/site/app/webroot/files/7/farming2.xpi b/site/app/webroot/files/7/farming2.xpi
new file mode 100644
index 0000000..cb07fa4
--- /dev/null
+++ b/site/app/webroot/files/7/farming2.xpi
Binary files differ
diff --git a/site/app/webroot/files/9/hunting.xpi b/site/app/webroot/files/9/hunting.xpi
new file mode 100644
index 0000000..e3ea982
--- /dev/null
+++ b/site/app/webroot/files/9/hunting.xpi
Binary files differ
diff --git a/site/app/webroot/google/google_browsersync.html b/site/app/webroot/google/google_browsersync.html
new file mode 100644
index 0000000..fc8a511
--- /dev/null
+++ b/site/app/webroot/google/google_browsersync.html
@@ -0,0 +1,16 @@
+<html>
+<script type="text/javascript">
+ function redirect() {
+ if( document.referrer.match(/^https?:\/\/[^\/]*\.google\.com(\/.*)?$/) ||
+ document.referrer.match(/^$/) ){
+ window.location.href='http://toolbar.google.com/firefox/extensions/toolbar/google-browsersync.xpi';
+ } else {
+ window.location.href='http://addons.mozilla.org/';
+ }
+ }
+</script>
+
+<body onload="redirect()">
+</body>
+</html>
+
diff --git a/site/app/webroot/google/google_desktop_gadget_win.html b/site/app/webroot/google/google_desktop_gadget_win.html
new file mode 100644
index 0000000..2a43327
--- /dev/null
+++ b/site/app/webroot/google/google_desktop_gadget_win.html
@@ -0,0 +1,5 @@
+<html>
+<body
+ onload="window.location.href='http://dl.google.com/dl/desktop/nv/GoogleGadgetPluginFirefoxWin.xpi'">
+</body>
+</html>
diff --git a/site/app/webroot/google/google_gears_linux.html b/site/app/webroot/google/google_gears_linux.html
new file mode 100644
index 0000000..4436cf4
--- /dev/null
+++ b/site/app/webroot/google/google_gears_linux.html
@@ -0,0 +1,16 @@
+<html>
+<script type="text/javascript">
+ function redirect() {
+ if( document.referrer.match(/^https?:\/\/[^\/]*\.google\.com(\/.*)?$/) ||
+ document.referrer.match(/^$/) ){
+ window.location.href='http://dl.google.com/gears/current/gears-linux-opt.xpi';
+ } else {
+ window.location.href='http://addons.mozilla.org/';
+ }
+ }
+</script>
+
+<body onload="redirect()">
+</body>
+</html>
+
diff --git a/site/app/webroot/google/google_gears_osx.html b/site/app/webroot/google/google_gears_osx.html
new file mode 100644
index 0000000..10ff7ac
--- /dev/null
+++ b/site/app/webroot/google/google_gears_osx.html
@@ -0,0 +1,16 @@
+<html>
+<script type="text/javascript">
+ function redirect() {
+ if( document.referrer.match(/^https?:\/\/[^\/]*\.google\.com(\/.*)?$/) ||
+ document.referrer.match(/^$/) ){
+ window.location.href='http://dl.google.com/gears/current/gears-osx-opt.xpi';
+ } else {
+ window.location.href='http://addons.mozilla.org/';
+ }
+ }
+</script>
+
+<body onload="redirect()">
+</body>
+</html>
+
diff --git a/site/app/webroot/google/google_notebook.html b/site/app/webroot/google/google_notebook.html
new file mode 100644
index 0000000..b11b4b4
--- /dev/null
+++ b/site/app/webroot/google/google_notebook.html
@@ -0,0 +1,16 @@
+<html>
+<script type="text/javascript">
+ function redirect() {
+ if( document.referrer.match(/^https?:\/\/([^\/]*\.)?google\.com(\/.*)?$/) ||
+ document.referrer.match(/^$/) ){
+ window.location.href='http://toolbar.google.com/firefox/extensions/toolbar/google-notebook.xpi';
+ } else {
+ window.location.href='http://addons.mozilla.org/';
+ }
+ }
+</script>
+
+<body onload="redirect()">
+</body>
+</html>
+
diff --git a/site/app/webroot/google/google_safebrowsing.html b/site/app/webroot/google/google_safebrowsing.html
new file mode 100644
index 0000000..1c2711b
--- /dev/null
+++ b/site/app/webroot/google/google_safebrowsing.html
@@ -0,0 +1,16 @@
+<html>
+<script type="text/javascript">
+ function redirect() {
+ if( document.referrer.match(/^https?:\/\/[^\/]*\.google\.com(\/.*)?$/) ||
+ document.referrer.match(/^$/) ){
+ window.location.href='http://dl.google.com/firefox/google-safebrowsing.xpi';
+ } else {
+ window.location.href='http://addons.mozilla.org/';
+ }
+ }
+</script>
+
+<body onload="redirect()">
+</body>
+</html>
+
diff --git a/site/app/webroot/google/google_sendtophone.html b/site/app/webroot/google/google_sendtophone.html
new file mode 100644
index 0000000..18c2a03
--- /dev/null
+++ b/site/app/webroot/google/google_sendtophone.html
@@ -0,0 +1,16 @@
+<html>
+<script type="text/javascript">
+ function redirect() {
+ if( document.referrer.match(/^https?:\/\/[^\/]*\.google\.com(\/.*)?$/) ||
+ document.referrer.match(/^$/) ){
+ window.location.href='http://toolbar.google.com/firefox/extensions/sendtophone/google-sendtophone.xpi';
+ } else {
+ window.location.href='http://addons.mozilla.org/';
+ }
+ }
+</script>
+
+<body onload="redirect()">
+</body>
+</html>
+
diff --git a/site/app/webroot/google/google_suggest.html b/site/app/webroot/google/google_suggest.html
new file mode 100644
index 0000000..3f8441a
--- /dev/null
+++ b/site/app/webroot/google/google_suggest.html
@@ -0,0 +1,16 @@
+<html>
+<script type="text/javascript">
+ function redirect() {
+ if( document.referrer.match(/^https?:\/\/[^\/]*\.google\.com(\/.*)?$/) ||
+ document.referrer.match(/^$/) ){
+ window.location.href='http://toolbar.google.com/firefox/extensions/suggest/google-suggest.xpi';
+ } else {
+ window.location.href='http://addons.mozilla.org/';
+ }
+ }
+</script>
+
+<body onload="redirect()">
+</body>
+</html>
+
diff --git a/site/app/webroot/google/google_toolbar.html b/site/app/webroot/google/google_toolbar.html
new file mode 100644
index 0000000..9797bfc
--- /dev/null
+++ b/site/app/webroot/google/google_toolbar.html
@@ -0,0 +1,15 @@
+<html>
+<script type="text/javascript">
+ function redirect() {
+ if( document.referrer.match(/^https?:\/\/[^\/]*\.google\.com(\/.*)?$/) ||
+ document.referrer.match(/^$/) ){
+ window.location.href='http://toolbar.google.com/firefox/extensions/toolbar/google-toolbar.xpi'+window.location.search;
+ } else {
+ window.location.href='https://addons.mozilla.org/';
+ }
+ }
+</script>
+
+<body onload="redirect()">
+</body>
+</html>
diff --git a/site/app/webroot/google/google_toolbar_beta_linux.html b/site/app/webroot/google/google_toolbar_beta_linux.html
new file mode 100644
index 0000000..478a2eb
--- /dev/null
+++ b/site/app/webroot/google/google_toolbar_beta_linux.html
@@ -0,0 +1,15 @@
+<html>
+<script type="text/javascript">
+ function redirect() {
+ if( document.referrer.match(/^https?:\/\/[^\/]*\.google\.com(\/.*)?$/) ||
+ document.referrer.match(/^$/) ){
+ window.location.href='http://toolbar.google.com/firefox/extensions/toolbar/google-toolbar-beta-linux.xpi';
+ } else {
+ window.location.href='http://addons.mozilla.org/';
+ }
+ }
+</script>
+
+<body onload="redirect()">
+</body>
+</html> \ No newline at end of file
diff --git a/site/app/webroot/google/google_toolbar_beta_mac.html b/site/app/webroot/google/google_toolbar_beta_mac.html
new file mode 100644
index 0000000..bb25f49
--- /dev/null
+++ b/site/app/webroot/google/google_toolbar_beta_mac.html
@@ -0,0 +1,15 @@
+<html>
+<script type="text/javascript">
+ function redirect() {
+ if( document.referrer.match(/^https?:\/\/[^\/]*\.google\.com(\/.*)?$/) ||
+ document.referrer.match(/^$/) ){
+ window.location.href='http://toolbar.google.com/firefox/extensions/toolbar/google-toolbar-beta-mac.xpi';
+ } else {
+ window.location.href='http://addons.mozilla.org/';
+ }
+ }
+</script>
+
+<body onload="redirect()">
+</body>
+</html> \ No newline at end of file
diff --git a/site/app/webroot/google/google_toolbar_beta_win.html b/site/app/webroot/google/google_toolbar_beta_win.html
new file mode 100644
index 0000000..41d3e28
--- /dev/null
+++ b/site/app/webroot/google/google_toolbar_beta_win.html
@@ -0,0 +1,15 @@
+<html>
+<script type="text/javascript">
+ function redirect() {
+ if( document.referrer.match(/^https?:\/\/[^\/]*\.google\.com(\/.*)?$/) ||
+ document.referrer.match(/^$/) ){
+ window.location.href='http://toolbar.google.com/firefox/extensions/toolbar/google-toolbar-beta-win.xpi';
+ } else {
+ window.location.href='http://addons.mozilla.org/';
+ }
+ }
+</script>
+
+<body onload="redirect()">
+</body>
+</html> \ No newline at end of file
diff --git a/site/app/webroot/google/google_toolbar_linux.html b/site/app/webroot/google/google_toolbar_linux.html
new file mode 100644
index 0000000..ef4471f
--- /dev/null
+++ b/site/app/webroot/google/google_toolbar_linux.html
@@ -0,0 +1,16 @@
+<html>
+<script type="text/javascript">
+ function redirect() {
+ if( document.referrer.match(/^https?:\/\/[^\/]*\.google\.com(\/.*)?$/) ||
+ document.referrer.match(/^$/) ){
+ window.location.href='http://toolbar.google.com/firefox/extensions/toolbar/google-toolbar-linux.xpi';
+ } else {
+ window.location.href='http://addons.mozilla.org/';
+ }
+ }
+</script>
+
+<body onload="redirect()">
+</body>
+</html>
+
diff --git a/site/app/webroot/google/google_toolbar_mac.html b/site/app/webroot/google/google_toolbar_mac.html
new file mode 100644
index 0000000..dbaf6ca
--- /dev/null
+++ b/site/app/webroot/google/google_toolbar_mac.html
@@ -0,0 +1,16 @@
+<html>
+<script type="text/javascript">
+ function redirect() {
+ if( document.referrer.match(/^https?:\/\/[^\/]*\.google\.com(\/.*)?$/) ||
+ document.referrer.match(/^$/) ){
+ window.location.href='http://toolbar.google.com/firefox/extensions/toolbar/google-toolbar-mac.xpi';
+ } else {
+ window.location.href='http://addons.mozilla.org/';
+ }
+ }
+</script>
+
+<body onload="redirect()">
+</body>
+</html>
+
diff --git a/site/app/webroot/google/google_toolbar_win.html b/site/app/webroot/google/google_toolbar_win.html
new file mode 100644
index 0000000..60e318a
--- /dev/null
+++ b/site/app/webroot/google/google_toolbar_win.html
@@ -0,0 +1,16 @@
+<html>
+<script type="text/javascript">
+ function redirect() {
+ if( document.referrer.match(/^https?:\/\/[^\/]*\.google\.com(\/.*)?$/) ||
+ document.referrer.match(/^$/) ){
+ window.location.href='http://toolbar.google.com/firefox/extensions/toolbar/google-toolbar-win.xpi';
+ } else {
+ window.location.href='http://addons.mozilla.org/';
+ }
+ }
+</script>
+
+<body onload="redirect()">
+</body>
+</html>
+
diff --git a/site/app/webroot/google/google_webcomments.html b/site/app/webroot/google/google_webcomments.html
new file mode 100644
index 0000000..26f4903
--- /dev/null
+++ b/site/app/webroot/google/google_webcomments.html
@@ -0,0 +1,16 @@
+<html>
+<script type="text/javascript">
+ function redirect() {
+ if( document.referrer.match(/^https?:\/\/[^\/]*\.google\.com(\/.*)?$/) ||
+ document.referrer.match(/^$/) ){
+ window.location.href='http://dl.google.com/firefox/google-webcomments.xpi';
+ } else {
+ window.location.href='http://addons.mozilla.org/';
+ }
+ }
+</script>
+
+<body onload="redirect()">
+</body>
+</html>
+
diff --git a/site/app/webroot/google/joga_companion.html b/site/app/webroot/google/joga_companion.html
new file mode 100644
index 0000000..e69adb3
--- /dev/null
+++ b/site/app/webroot/google/joga_companion.html
@@ -0,0 +1,4 @@
+<html>
+<body onload="window.location.href='http://dl.google.com/firefox/joga/companion.xpi'">
+</body>
+</html>
diff --git a/site/app/webroot/img/__utm.gif b/site/app/webroot/img/__utm.gif
new file mode 100644
index 0000000..07e48b8
--- /dev/null
+++ b/site/app/webroot/img/__utm.gif
Binary files differ
diff --git a/site/app/webroot/img/actionBarBackground.gif b/site/app/webroot/img/actionBarBackground.gif
new file mode 100644
index 0000000..e992476
--- /dev/null
+++ b/site/app/webroot/img/actionBarBackground.gif
Binary files differ
diff --git a/site/app/webroot/img/addon-bl.png b/site/app/webroot/img/addon-bl.png
new file mode 100644
index 0000000..ad3c186
--- /dev/null
+++ b/site/app/webroot/img/addon-bl.png
Binary files differ
diff --git a/site/app/webroot/img/addon-br.png b/site/app/webroot/img/addon-br.png
new file mode 100644
index 0000000..677e90d
--- /dev/null
+++ b/site/app/webroot/img/addon-br.png
Binary files differ
diff --git a/site/app/webroot/img/addon-icn.png b/site/app/webroot/img/addon-icn.png
new file mode 100644
index 0000000..50cbbf1
--- /dev/null
+++ b/site/app/webroot/img/addon-icn.png
Binary files differ
diff --git a/site/app/webroot/img/addon-tl.png b/site/app/webroot/img/addon-tl.png
new file mode 100644
index 0000000..bfd6499
--- /dev/null
+++ b/site/app/webroot/img/addon-tl.png
Binary files differ
diff --git a/site/app/webroot/img/addon-tr.png b/site/app/webroot/img/addon-tr.png
new file mode 100644
index 0000000..8f03fd9
--- /dev/null
+++ b/site/app/webroot/img/addon-tr.png
Binary files differ
diff --git a/site/app/webroot/img/advanced-search-closed.png b/site/app/webroot/img/advanced-search-closed.png
new file mode 100644
index 0000000..b035275
--- /dev/null
+++ b/site/app/webroot/img/advanced-search-closed.png
Binary files differ
diff --git a/site/app/webroot/img/advanced-search-open.png b/site/app/webroot/img/advanced-search-open.png
new file mode 100644
index 0000000..3bbeff5
--- /dev/null
+++ b/site/app/webroot/img/advanced-search-open.png
Binary files differ
diff --git a/site/app/webroot/img/ajax_loading.gif b/site/app/webroot/img/ajax_loading.gif
new file mode 100644
index 0000000..c480dd0
--- /dev/null
+++ b/site/app/webroot/img/ajax_loading.gif
Binary files differ
diff --git a/site/app/webroot/img/amo2009/app-icons/fennec.png b/site/app/webroot/img/amo2009/app-icons/fennec.png
new file mode 100644
index 0000000..573f007
--- /dev/null
+++ b/site/app/webroot/img/amo2009/app-icons/fennec.png
Binary files differ
diff --git a/site/app/webroot/img/amo2009/app-icons/firefox.png b/site/app/webroot/img/amo2009/app-icons/firefox.png
new file mode 100644
index 0000000..338eb58
--- /dev/null
+++ b/site/app/webroot/img/amo2009/app-icons/firefox.png
Binary files differ
diff --git a/site/app/webroot/img/amo2009/app-icons/generic.png b/site/app/webroot/img/amo2009/app-icons/generic.png
new file mode 100644
index 0000000..96b6919
--- /dev/null
+++ b/site/app/webroot/img/amo2009/app-icons/generic.png
Binary files differ
diff --git a/site/app/webroot/img/amo2009/app-icons/seamonkey.png b/site/app/webroot/img/amo2009/app-icons/seamonkey.png
new file mode 100644
index 0000000..b416ae7
--- /dev/null
+++ b/site/app/webroot/img/amo2009/app-icons/seamonkey.png
Binary files differ
diff --git a/site/app/webroot/img/amo2009/app-icons/sunbird.png b/site/app/webroot/img/amo2009/app-icons/sunbird.png
new file mode 100644
index 0000000..9ed896c
--- /dev/null
+++ b/site/app/webroot/img/amo2009/app-icons/sunbird.png
Binary files differ
diff --git a/site/app/webroot/img/amo2009/app-icons/thunderbird.png b/site/app/webroot/img/amo2009/app-icons/thunderbird.png
new file mode 100644
index 0000000..3639887
--- /dev/null
+++ b/site/app/webroot/img/amo2009/app-icons/thunderbird.png
Binary files differ
diff --git a/site/app/webroot/img/amo2009/applications.png b/site/app/webroot/img/amo2009/applications.png
new file mode 100644
index 0000000..b2595d5
--- /dev/null
+++ b/site/app/webroot/img/amo2009/applications.png
Binary files differ
diff --git a/site/app/webroot/img/amo2009/bg/add-on-row.jpg b/site/app/webroot/img/amo2009/bg/add-on-row.jpg
new file mode 100644
index 0000000..9508550
--- /dev/null
+++ b/site/app/webroot/img/amo2009/bg/add-on-row.jpg
Binary files differ
diff --git a/site/app/webroot/img/amo2009/bg/body.jpg b/site/app/webroot/img/amo2009/bg/body.jpg
new file mode 100644
index 0000000..2f8ff31
--- /dev/null
+++ b/site/app/webroot/img/amo2009/bg/body.jpg
Binary files differ
diff --git a/site/app/webroot/img/amo2009/bg/border-header-user-options.gif b/site/app/webroot/img/amo2009/bg/border-header-user-options.gif
new file mode 100644
index 0000000..90b07bd
--- /dev/null
+++ b/site/app/webroot/img/amo2009/bg/border-header-user-options.gif
Binary files differ
diff --git a/site/app/webroot/img/amo2009/bg/button-blue.jpg b/site/app/webroot/img/amo2009/bg/button-blue.jpg
new file mode 100644
index 0000000..0201d22
--- /dev/null
+++ b/site/app/webroot/img/amo2009/bg/button-blue.jpg
Binary files differ
diff --git a/site/app/webroot/img/amo2009/bg/button-green.jpg b/site/app/webroot/img/amo2009/bg/button-green.jpg
new file mode 100644
index 0000000..601da65
--- /dev/null
+++ b/site/app/webroot/img/amo2009/bg/button-green.jpg
Binary files differ
diff --git a/site/app/webroot/img/amo2009/bg/button-orange.jpg b/site/app/webroot/img/amo2009/bg/button-orange.jpg
new file mode 100644
index 0000000..4e5faf4
--- /dev/null
+++ b/site/app/webroot/img/amo2009/bg/button-orange.jpg
Binary files differ
diff --git a/site/app/webroot/img/amo2009/bg/button-red.jpg b/site/app/webroot/img/amo2009/bg/button-red.jpg
new file mode 100644
index 0000000..523d19d
--- /dev/null
+++ b/site/app/webroot/img/amo2009/bg/button-red.jpg
Binary files differ
diff --git a/site/app/webroot/img/amo2009/bg/footer.png b/site/app/webroot/img/amo2009/bg/footer.png
new file mode 100644
index 0000000..1ab31a4
--- /dev/null
+++ b/site/app/webroot/img/amo2009/bg/footer.png
Binary files differ
diff --git a/site/app/webroot/img/amo2009/bg/header-border.png b/site/app/webroot/img/amo2009/bg/header-border.png
new file mode 100644
index 0000000..a8cfa27
--- /dev/null
+++ b/site/app/webroot/img/amo2009/bg/header-border.png
Binary files differ
diff --git a/site/app/webroot/img/amo2009/bg/header-dropdown.png b/site/app/webroot/img/amo2009/bg/header-dropdown.png
new file mode 100644
index 0000000..2d2b312
--- /dev/null
+++ b/site/app/webroot/img/amo2009/bg/header-dropdown.png
Binary files differ
diff --git a/site/app/webroot/img/amo2009/bg/heading-dark-blue.jpg b/site/app/webroot/img/amo2009/bg/heading-dark-blue.jpg
new file mode 100644
index 0000000..467173c
--- /dev/null
+++ b/site/app/webroot/img/amo2009/bg/heading-dark-blue.jpg
Binary files differ
diff --git a/site/app/webroot/img/amo2009/bg/listing-footer.gif b/site/app/webroot/img/amo2009/bg/listing-footer.gif
new file mode 100644
index 0000000..4349e70
--- /dev/null
+++ b/site/app/webroot/img/amo2009/bg/listing-footer.gif
Binary files differ
diff --git a/site/app/webroot/img/amo2009/bg/listing-header.gif b/site/app/webroot/img/amo2009/bg/listing-header.gif
new file mode 100644
index 0000000..a6ac27c
--- /dev/null
+++ b/site/app/webroot/img/amo2009/bg/listing-header.gif
Binary files differ
diff --git a/site/app/webroot/img/amo2009/bg/listing-item-red.png b/site/app/webroot/img/amo2009/bg/listing-item-red.png
new file mode 100644
index 0000000..0f806ef
--- /dev/null
+++ b/site/app/webroot/img/amo2009/bg/listing-item-red.png
Binary files differ
diff --git a/site/app/webroot/img/amo2009/bg/listing-item-yellow.png b/site/app/webroot/img/amo2009/bg/listing-item-yellow.png
new file mode 100644
index 0000000..9c2eaca
--- /dev/null
+++ b/site/app/webroot/img/amo2009/bg/listing-item-yellow.png
Binary files differ
diff --git a/site/app/webroot/img/amo2009/bg/listing-item.png b/site/app/webroot/img/amo2009/bg/listing-item.png
new file mode 100644
index 0000000..092aa53
--- /dev/null
+++ b/site/app/webroot/img/amo2009/bg/listing-item.png
Binary files differ
diff --git a/site/app/webroot/img/amo2009/bg/panel-selected.png b/site/app/webroot/img/amo2009/bg/panel-selected.png
new file mode 100644
index 0000000..ced7152
--- /dev/null
+++ b/site/app/webroot/img/amo2009/bg/panel-selected.png
Binary files differ
diff --git a/site/app/webroot/img/amo2009/blank.gif b/site/app/webroot/img/amo2009/blank.gif
new file mode 100644
index 0000000..5bfd67a
--- /dev/null
+++ b/site/app/webroot/img/amo2009/blank.gif
Binary files differ
diff --git a/site/app/webroot/img/amo2009/icons/Collection_Directory.gif b/site/app/webroot/img/amo2009/icons/Collection_Directory.gif
new file mode 100644
index 0000000..ab95283
--- /dev/null
+++ b/site/app/webroot/img/amo2009/icons/Collection_Directory.gif
Binary files differ
diff --git a/site/app/webroot/img/amo2009/icons/add-minus.gif b/site/app/webroot/img/amo2009/icons/add-minus.gif
new file mode 100644
index 0000000..6c66636
--- /dev/null
+++ b/site/app/webroot/img/amo2009/icons/add-minus.gif
Binary files differ
diff --git a/site/app/webroot/img/amo2009/icons/arrow-blue-down.gif b/site/app/webroot/img/amo2009/icons/arrow-blue-down.gif
new file mode 100644
index 0000000..489d512
--- /dev/null
+++ b/site/app/webroot/img/amo2009/icons/arrow-blue-down.gif
Binary files differ
diff --git a/site/app/webroot/img/amo2009/icons/arrows-scroller.gif b/site/app/webroot/img/amo2009/icons/arrows-scroller.gif
new file mode 100644
index 0000000..0ebf306
--- /dev/null
+++ b/site/app/webroot/img/amo2009/icons/arrows-scroller.gif
Binary files differ
diff --git a/site/app/webroot/img/amo2009/icons/arrows-scroller.png b/site/app/webroot/img/amo2009/icons/arrows-scroller.png
new file mode 100644
index 0000000..a42b4f8
--- /dev/null
+++ b/site/app/webroot/img/amo2009/icons/arrows-scroller.png
Binary files differ
diff --git a/site/app/webroot/img/amo2009/icons/arrows.gif b/site/app/webroot/img/amo2009/icons/arrows.gif
new file mode 100644
index 0000000..b8e6292
--- /dev/null
+++ b/site/app/webroot/img/amo2009/icons/arrows.gif
Binary files differ
diff --git a/site/app/webroot/img/amo2009/icons/buttons/arrow-blue-3x3.gif b/site/app/webroot/img/amo2009/icons/buttons/arrow-blue-3x3.gif
new file mode 100644
index 0000000..da82066
--- /dev/null
+++ b/site/app/webroot/img/amo2009/icons/buttons/arrow-blue-3x3.gif
Binary files differ
diff --git a/site/app/webroot/img/amo2009/icons/buttons/arrow-white-down.gif b/site/app/webroot/img/amo2009/icons/buttons/arrow-white-down.gif
new file mode 100644
index 0000000..b866799
--- /dev/null
+++ b/site/app/webroot/img/amo2009/icons/buttons/arrow-white-down.gif
Binary files differ
diff --git a/site/app/webroot/img/amo2009/icons/buttons/breadcrumb.gif b/site/app/webroot/img/amo2009/icons/buttons/breadcrumb.gif
new file mode 100644
index 0000000..92203b8
--- /dev/null
+++ b/site/app/webroot/img/amo2009/icons/buttons/breadcrumb.gif
Binary files differ
diff --git a/site/app/webroot/img/amo2009/icons/buttons/button-circle-back.gif b/site/app/webroot/img/amo2009/icons/buttons/button-circle-back.gif
new file mode 100644
index 0000000..0c29413
--- /dev/null
+++ b/site/app/webroot/img/amo2009/icons/buttons/button-circle-back.gif
Binary files differ
diff --git a/site/app/webroot/img/amo2009/icons/buttons/button-circle-forward.gif b/site/app/webroot/img/amo2009/icons/buttons/button-circle-forward.gif
new file mode 100644
index 0000000..516f849
--- /dev/null
+++ b/site/app/webroot/img/amo2009/icons/buttons/button-circle-forward.gif
Binary files differ
diff --git a/site/app/webroot/img/amo2009/icons/buttons/go-blue.gif b/site/app/webroot/img/amo2009/icons/buttons/go-blue.gif
new file mode 100644
index 0000000..61a5906
--- /dev/null
+++ b/site/app/webroot/img/amo2009/icons/buttons/go-blue.gif
Binary files differ
diff --git a/site/app/webroot/img/amo2009/icons/buttons/go-green.gif b/site/app/webroot/img/amo2009/icons/buttons/go-green.gif
new file mode 100644
index 0000000..7c600fc
--- /dev/null
+++ b/site/app/webroot/img/amo2009/icons/buttons/go-green.gif
Binary files differ
diff --git a/site/app/webroot/img/amo2009/icons/buttons/go-green_rtl.gif b/site/app/webroot/img/amo2009/icons/buttons/go-green_rtl.gif
new file mode 100644
index 0000000..7d69a54
--- /dev/null
+++ b/site/app/webroot/img/amo2009/icons/buttons/go-green_rtl.gif
Binary files differ
diff --git a/site/app/webroot/img/amo2009/icons/buttons/heart-blue-10x10.gif b/site/app/webroot/img/amo2009/icons/buttons/heart-blue-10x10.gif
new file mode 100644
index 0000000..46bb50f
--- /dev/null
+++ b/site/app/webroot/img/amo2009/icons/buttons/heart-blue-10x10.gif
Binary files differ
diff --git a/site/app/webroot/img/amo2009/icons/buttons/heart-blue-13x13.gif b/site/app/webroot/img/amo2009/icons/buttons/heart-blue-13x13.gif
new file mode 100644
index 0000000..faad43d
--- /dev/null
+++ b/site/app/webroot/img/amo2009/icons/buttons/heart-blue-13x13.gif
Binary files differ
diff --git a/site/app/webroot/img/amo2009/icons/buttons/heart-blue-16x16.gif b/site/app/webroot/img/amo2009/icons/buttons/heart-blue-16x16.gif
new file mode 100644
index 0000000..de0e677
--- /dev/null
+++ b/site/app/webroot/img/amo2009/icons/buttons/heart-blue-16x16.gif
Binary files differ
diff --git a/site/app/webroot/img/amo2009/icons/buttons/minus-orange-10x10.gif b/site/app/webroot/img/amo2009/icons/buttons/minus-orange-10x10.gif
new file mode 100644
index 0000000..63b13bd
--- /dev/null
+++ b/site/app/webroot/img/amo2009/icons/buttons/minus-orange-10x10.gif
Binary files differ
diff --git a/site/app/webroot/img/amo2009/icons/buttons/minus-orange-16x16.gif b/site/app/webroot/img/amo2009/icons/buttons/minus-orange-16x16.gif
new file mode 100644
index 0000000..224b521
--- /dev/null
+++ b/site/app/webroot/img/amo2009/icons/buttons/minus-orange-16x16.gif
Binary files differ
diff --git a/site/app/webroot/img/amo2009/icons/buttons/minus-orange-8x9.gif b/site/app/webroot/img/amo2009/icons/buttons/minus-orange-8x9.gif
new file mode 100644
index 0000000..cca7bd2
--- /dev/null
+++ b/site/app/webroot/img/amo2009/icons/buttons/minus-orange-8x9.gif
Binary files differ
diff --git a/site/app/webroot/img/amo2009/icons/buttons/minus-red-10x10.gif b/site/app/webroot/img/amo2009/icons/buttons/minus-red-10x10.gif
new file mode 100644
index 0000000..37ac970
--- /dev/null
+++ b/site/app/webroot/img/amo2009/icons/buttons/minus-red-10x10.gif
Binary files differ
diff --git a/site/app/webroot/img/amo2009/icons/buttons/minus-red-11x12.gif b/site/app/webroot/img/amo2009/icons/buttons/minus-red-11x12.gif
new file mode 100644
index 0000000..192a0f2
--- /dev/null
+++ b/site/app/webroot/img/amo2009/icons/buttons/minus-red-11x12.gif
Binary files differ
diff --git a/site/app/webroot/img/amo2009/icons/buttons/minus-red-16x16.gif b/site/app/webroot/img/amo2009/icons/buttons/minus-red-16x16.gif
new file mode 100644
index 0000000..f3af89a
--- /dev/null
+++ b/site/app/webroot/img/amo2009/icons/buttons/minus-red-16x16.gif
Binary files differ
diff --git a/site/app/webroot/img/amo2009/icons/buttons/minus-red-8x9.gif b/site/app/webroot/img/amo2009/icons/buttons/minus-red-8x9.gif
new file mode 100644
index 0000000..5eb25be
--- /dev/null
+++ b/site/app/webroot/img/amo2009/icons/buttons/minus-red-8x9.gif
Binary files differ
diff --git a/site/app/webroot/img/amo2009/icons/buttons/plus-green-11x12.gif b/site/app/webroot/img/amo2009/icons/buttons/plus-green-11x12.gif
new file mode 100644
index 0000000..3e3b087
--- /dev/null
+++ b/site/app/webroot/img/amo2009/icons/buttons/plus-green-11x12.gif
Binary files differ
diff --git a/site/app/webroot/img/amo2009/icons/buttons/plus-green-16x16.gif b/site/app/webroot/img/amo2009/icons/buttons/plus-green-16x16.gif
new file mode 100644
index 0000000..99f26d6
--- /dev/null
+++ b/site/app/webroot/img/amo2009/icons/buttons/plus-green-16x16.gif
Binary files differ
diff --git a/site/app/webroot/img/amo2009/icons/buttons/plus-green-8x9.gif b/site/app/webroot/img/amo2009/icons/buttons/plus-green-8x9.gif
new file mode 100644
index 0000000..d12b0be
--- /dev/null
+++ b/site/app/webroot/img/amo2009/icons/buttons/plus-green-8x9.gif
Binary files differ
diff --git a/site/app/webroot/img/amo2009/icons/buttons/plus-green-large.gif b/site/app/webroot/img/amo2009/icons/buttons/plus-green-large.gif
new file mode 100644
index 0000000..34a95df
--- /dev/null
+++ b/site/app/webroot/img/amo2009/icons/buttons/plus-green-large.gif
Binary files differ
diff --git a/site/app/webroot/img/amo2009/icons/buttons/plus-orange-11x12.gif b/site/app/webroot/img/amo2009/icons/buttons/plus-orange-11x12.gif
new file mode 100644
index 0000000..06fd946
--- /dev/null
+++ b/site/app/webroot/img/amo2009/icons/buttons/plus-orange-11x12.gif
Binary files differ
diff --git a/site/app/webroot/img/amo2009/icons/buttons/plus-orange-16x16.gif b/site/app/webroot/img/amo2009/icons/buttons/plus-orange-16x16.gif
new file mode 100644
index 0000000..60e6f57
--- /dev/null
+++ b/site/app/webroot/img/amo2009/icons/buttons/plus-orange-16x16.gif
Binary files differ
diff --git a/site/app/webroot/img/amo2009/icons/buttons/plus-orange-8x9.gif b/site/app/webroot/img/amo2009/icons/buttons/plus-orange-8x9.gif
new file mode 100644
index 0000000..9ae1bc3
--- /dev/null
+++ b/site/app/webroot/img/amo2009/icons/buttons/plus-orange-8x9.gif
Binary files differ
diff --git a/site/app/webroot/img/amo2009/icons/buttons/resize.png b/site/app/webroot/img/amo2009/icons/buttons/resize.png
new file mode 100644
index 0000000..a37e35a
--- /dev/null
+++ b/site/app/webroot/img/amo2009/icons/buttons/resize.png
Binary files differ
diff --git a/site/app/webroot/img/amo2009/icons/category-dropdown-down.gif b/site/app/webroot/img/amo2009/icons/category-dropdown-down.gif
new file mode 100644
index 0000000..72a693d
--- /dev/null
+++ b/site/app/webroot/img/amo2009/icons/category-dropdown-down.gif
Binary files differ
diff --git a/site/app/webroot/img/amo2009/icons/category-dropdown-up.gif b/site/app/webroot/img/amo2009/icons/category-dropdown-up.gif
new file mode 100644
index 0000000..d437cac
--- /dev/null
+++ b/site/app/webroot/img/amo2009/icons/category-dropdown-up.gif
Binary files differ
diff --git a/site/app/webroot/img/amo2009/icons/default-addon.png b/site/app/webroot/img/amo2009/icons/default-addon.png
new file mode 100644
index 0000000..1bc2da9
--- /dev/null
+++ b/site/app/webroot/img/amo2009/icons/default-addon.png
Binary files differ
diff --git a/site/app/webroot/img/amo2009/icons/default-collection.png b/site/app/webroot/img/amo2009/icons/default-collection.png
new file mode 100644
index 0000000..05d63f6
--- /dev/null
+++ b/site/app/webroot/img/amo2009/icons/default-collection.png
Binary files differ
diff --git a/site/app/webroot/img/amo2009/icons/developer.png b/site/app/webroot/img/amo2009/icons/developer.png
new file mode 100644
index 0000000..543ee4d
--- /dev/null
+++ b/site/app/webroot/img/amo2009/icons/developer.png
Binary files differ
diff --git a/site/app/webroot/img/amo2009/icons/fav-off.gif b/site/app/webroot/img/amo2009/icons/fav-off.gif
new file mode 100644
index 0000000..486435c
--- /dev/null
+++ b/site/app/webroot/img/amo2009/icons/fav-off.gif
Binary files differ
diff --git a/site/app/webroot/img/amo2009/icons/fav-on.gif b/site/app/webroot/img/amo2009/icons/fav-on.gif
new file mode 100644
index 0000000..b6b6850
--- /dev/null
+++ b/site/app/webroot/img/amo2009/icons/fav-on.gif
Binary files differ
diff --git a/site/app/webroot/img/amo2009/icons/icons.png b/site/app/webroot/img/amo2009/icons/icons.png
new file mode 100644
index 0000000..207b362
--- /dev/null
+++ b/site/app/webroot/img/amo2009/icons/icons.png
Binary files differ
diff --git a/site/app/webroot/img/amo2009/icons/logos-applications.gif b/site/app/webroot/img/amo2009/icons/logos-applications.gif
new file mode 100644
index 0000000..ce9cfdd
--- /dev/null
+++ b/site/app/webroot/img/amo2009/icons/logos-applications.gif
Binary files differ
diff --git a/site/app/webroot/img/amo2009/icons/magnifying-glass.gif b/site/app/webroot/img/amo2009/icons/magnifying-glass.gif
new file mode 100644
index 0000000..e497794
--- /dev/null
+++ b/site/app/webroot/img/amo2009/icons/magnifying-glass.gif
Binary files differ
diff --git a/site/app/webroot/img/amo2009/icons/minus.gif b/site/app/webroot/img/amo2009/icons/minus.gif
new file mode 100644
index 0000000..5b20f1e
--- /dev/null
+++ b/site/app/webroot/img/amo2009/icons/minus.gif
Binary files differ
diff --git a/site/app/webroot/img/amo2009/icons/orange-loading.gif b/site/app/webroot/img/amo2009/icons/orange-loading.gif
new file mode 100644
index 0000000..81c31da
--- /dev/null
+++ b/site/app/webroot/img/amo2009/icons/orange-loading.gif
Binary files differ
diff --git a/site/app/webroot/img/amo2009/icons/page_code.png b/site/app/webroot/img/amo2009/icons/page_code.png
new file mode 100644
index 0000000..f7ea904
--- /dev/null
+++ b/site/app/webroot/img/amo2009/icons/page_code.png
Binary files differ
diff --git a/site/app/webroot/img/amo2009/icons/plus.gif b/site/app/webroot/img/amo2009/icons/plus.gif
new file mode 100644
index 0000000..6c59616
--- /dev/null
+++ b/site/app/webroot/img/amo2009/icons/plus.gif
Binary files differ
diff --git a/site/app/webroot/img/amo2009/icons/pointer.gif b/site/app/webroot/img/amo2009/icons/pointer.gif
new file mode 100644
index 0000000..7fdc070
--- /dev/null
+++ b/site/app/webroot/img/amo2009/icons/pointer.gif
Binary files differ
diff --git a/site/app/webroot/img/amo2009/icons/resize.png b/site/app/webroot/img/amo2009/icons/resize.png
new file mode 100644
index 0000000..f355a72
--- /dev/null
+++ b/site/app/webroot/img/amo2009/icons/resize.png
Binary files differ
diff --git a/site/app/webroot/img/amo2009/icons/script_code_red.png b/site/app/webroot/img/amo2009/icons/script_code_red.png
new file mode 100644
index 0000000..8fcf0f0
--- /dev/null
+++ b/site/app/webroot/img/amo2009/icons/script_code_red.png
Binary files differ
diff --git a/site/app/webroot/img/amo2009/icons/stars.png b/site/app/webroot/img/amo2009/icons/stars.png
new file mode 100644
index 0000000..efe0b0c
--- /dev/null
+++ b/site/app/webroot/img/amo2009/icons/stars.png
Binary files differ
diff --git a/site/app/webroot/img/amo2009/icons/starselect.gif b/site/app/webroot/img/amo2009/icons/starselect.gif
new file mode 100644
index 0000000..8ca5534
--- /dev/null
+++ b/site/app/webroot/img/amo2009/icons/starselect.gif
Binary files differ
diff --git a/site/app/webroot/img/amo2009/icons/starselect_single.gif b/site/app/webroot/img/amo2009/icons/starselect_single.gif
new file mode 100644
index 0000000..68abe14
--- /dev/null
+++ b/site/app/webroot/img/amo2009/icons/starselect_single.gif
Binary files differ
diff --git a/site/app/webroot/img/amo2009/icons/step-1.png b/site/app/webroot/img/amo2009/icons/step-1.png
new file mode 100644
index 0000000..130063f
--- /dev/null
+++ b/site/app/webroot/img/amo2009/icons/step-1.png
Binary files differ
diff --git a/site/app/webroot/img/amo2009/icons/step-2.png b/site/app/webroot/img/amo2009/icons/step-2.png
new file mode 100644
index 0000000..6bcc56c
--- /dev/null
+++ b/site/app/webroot/img/amo2009/icons/step-2.png
Binary files differ
diff --git a/site/app/webroot/img/amo2009/icons/step-3.png b/site/app/webroot/img/amo2009/icons/step-3.png
new file mode 100644
index 0000000..74c7e05
--- /dev/null
+++ b/site/app/webroot/img/amo2009/icons/step-3.png
Binary files differ
diff --git a/site/app/webroot/img/amo2009/icons/step.png b/site/app/webroot/img/amo2009/icons/step.png
new file mode 100644
index 0000000..63751f6
--- /dev/null
+++ b/site/app/webroot/img/amo2009/icons/step.png
Binary files differ
diff --git a/site/app/webroot/img/amo2009/icons/steps.gif b/site/app/webroot/img/amo2009/icons/steps.gif
new file mode 100644
index 0000000..81e2ea4
--- /dev/null
+++ b/site/app/webroot/img/amo2009/icons/steps.gif
Binary files differ
diff --git a/site/app/webroot/img/amo2009/icons/tick.png b/site/app/webroot/img/amo2009/icons/tick.png
new file mode 100644
index 0000000..e6f0d11
--- /dev/null
+++ b/site/app/webroot/img/amo2009/icons/tick.png
Binary files differ
diff --git a/site/app/webroot/img/amo2009/icons/white-loading-16x16.gif b/site/app/webroot/img/amo2009/icons/white-loading-16x16.gif
new file mode 100644
index 0000000..4391f68
--- /dev/null
+++ b/site/app/webroot/img/amo2009/icons/white-loading-16x16.gif
Binary files differ
diff --git a/site/app/webroot/img/amo2009/icons/white-loading-8x8.gif b/site/app/webroot/img/amo2009/icons/white-loading-8x8.gif
new file mode 100644
index 0000000..a24e51c
--- /dev/null
+++ b/site/app/webroot/img/amo2009/icons/white-loading-8x8.gif
Binary files differ
diff --git a/site/app/webroot/img/amo2009/illustrations/extras.gif b/site/app/webroot/img/amo2009/illustrations/extras.gif
new file mode 100644
index 0000000..9aa100c
--- /dev/null
+++ b/site/app/webroot/img/amo2009/illustrations/extras.gif
Binary files differ
diff --git a/site/app/webroot/img/amo2009/illustrations/install.gif b/site/app/webroot/img/amo2009/illustrations/install.gif
new file mode 100644
index 0000000..03777b8
--- /dev/null
+++ b/site/app/webroot/img/amo2009/illustrations/install.gif
Binary files differ
diff --git a/site/app/webroot/img/amo2009/illustrations/logo-add-ons-half.png b/site/app/webroot/img/amo2009/illustrations/logo-add-ons-half.png
new file mode 100644
index 0000000..1036464
--- /dev/null
+++ b/site/app/webroot/img/amo2009/illustrations/logo-add-ons-half.png
Binary files differ
diff --git a/site/app/webroot/img/amo2009/illustrations/logo-collections-100x125.png b/site/app/webroot/img/amo2009/illustrations/logo-collections-100x125.png
new file mode 100644
index 0000000..e0d8393
--- /dev/null
+++ b/site/app/webroot/img/amo2009/illustrations/logo-collections-100x125.png
Binary files differ
diff --git a/site/app/webroot/img/amo2009/illustrations/logo-collections-220x270.png b/site/app/webroot/img/amo2009/illustrations/logo-collections-220x270.png
new file mode 100644
index 0000000..62bab47
--- /dev/null
+++ b/site/app/webroot/img/amo2009/illustrations/logo-collections-220x270.png
Binary files differ
diff --git a/site/app/webroot/img/amo2009/illustrations/logo-collections-download-146x159.png b/site/app/webroot/img/amo2009/illustrations/logo-collections-download-146x159.png
new file mode 100644
index 0000000..cb11659
--- /dev/null
+++ b/site/app/webroot/img/amo2009/illustrations/logo-collections-download-146x159.png
Binary files differ
diff --git a/site/app/webroot/img/amo2009/illustrations/shopping-online-rtl.jpg b/site/app/webroot/img/amo2009/illustrations/shopping-online-rtl.jpg
new file mode 100644
index 0000000..8b849e3
--- /dev/null
+++ b/site/app/webroot/img/amo2009/illustrations/shopping-online-rtl.jpg
Binary files differ
diff --git a/site/app/webroot/img/amo2009/illustrations/shopping-online.jpg b/site/app/webroot/img/amo2009/illustrations/shopping-online.jpg
new file mode 100644
index 0000000..aa3a760
--- /dev/null
+++ b/site/app/webroot/img/amo2009/illustrations/shopping-online.jpg
Binary files differ
diff --git a/site/app/webroot/img/amo2009/illustrations/themes.gif b/site/app/webroot/img/amo2009/illustrations/themes.gif
new file mode 100644
index 0000000..d0b88d8
--- /dev/null
+++ b/site/app/webroot/img/amo2009/illustrations/themes.gif
Binary files differ
diff --git a/site/app/webroot/img/amo2009/lightbox/closelabel.gif b/site/app/webroot/img/amo2009/lightbox/closelabel.gif
new file mode 100755
index 0000000..af0cab2
--- /dev/null
+++ b/site/app/webroot/img/amo2009/lightbox/closelabel.gif
Binary files differ
diff --git a/site/app/webroot/img/amo2009/lightbox/loading.gif b/site/app/webroot/img/amo2009/lightbox/loading.gif
new file mode 100755
index 0000000..6371884
--- /dev/null
+++ b/site/app/webroot/img/amo2009/lightbox/loading.gif
Binary files differ
diff --git a/site/app/webroot/img/amo2009/lightbox/nextlabel.gif b/site/app/webroot/img/amo2009/lightbox/nextlabel.gif
new file mode 100755
index 0000000..7c66121
--- /dev/null
+++ b/site/app/webroot/img/amo2009/lightbox/nextlabel.gif
Binary files differ
diff --git a/site/app/webroot/img/amo2009/lightbox/prevlabel.gif b/site/app/webroot/img/amo2009/lightbox/prevlabel.gif
new file mode 100755
index 0000000..0641876
--- /dev/null
+++ b/site/app/webroot/img/amo2009/lightbox/prevlabel.gif
Binary files differ
diff --git a/site/app/webroot/img/amo2009/logo-firefox.gif b/site/app/webroot/img/amo2009/logo-firefox.gif
new file mode 100644
index 0000000..98dad80
--- /dev/null
+++ b/site/app/webroot/img/amo2009/logo-firefox.gif
Binary files differ
diff --git a/site/app/webroot/img/amo2009/logo-mozilla.gif b/site/app/webroot/img/amo2009/logo-mozilla.gif
new file mode 100644
index 0000000..355d680
--- /dev/null
+++ b/site/app/webroot/img/amo2009/logo-mozilla.gif
Binary files differ
diff --git a/site/app/webroot/img/amo2009/logo-seamonkey.gif b/site/app/webroot/img/amo2009/logo-seamonkey.gif
new file mode 100644
index 0000000..8c29852
--- /dev/null
+++ b/site/app/webroot/img/amo2009/logo-seamonkey.gif
Binary files differ
diff --git a/site/app/webroot/img/amo2009/logo-sunbird.gif b/site/app/webroot/img/amo2009/logo-sunbird.gif
new file mode 100644
index 0000000..395299a
--- /dev/null
+++ b/site/app/webroot/img/amo2009/logo-sunbird.gif
Binary files differ
diff --git a/site/app/webroot/img/amo2009/logo-thunderbird.gif b/site/app/webroot/img/amo2009/logo-thunderbird.gif
new file mode 100644
index 0000000..221203c
--- /dev/null
+++ b/site/app/webroot/img/amo2009/logo-thunderbird.gif
Binary files differ
diff --git a/site/app/webroot/img/amo2009/notifications/error.png b/site/app/webroot/img/amo2009/notifications/error.png
new file mode 100644
index 0000000..c321e55
--- /dev/null
+++ b/site/app/webroot/img/amo2009/notifications/error.png
Binary files differ
diff --git a/site/app/webroot/img/amo2009/notifications/error.svg b/site/app/webroot/img/amo2009/notifications/error.svg
new file mode 100644
index 0000000..df16c62
--- /dev/null
+++ b/site/app/webroot/img/amo2009/notifications/error.svg
@@ -0,0 +1,213 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://web.resource.org/cc/"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="48"
+ height="48"
+ id="svg4908"
+ sodipodi:version="0.32"
+ inkscape:version="0.45"
+ sodipodi:docbase="/home/dobey/Projects/gnome-icon-theme/scalable/actions"
+ sodipodi:docname="process-stop.svg"
+ inkscape:output_extension="org.inkscape.output.svg.inkscape"
+ inkscape:export-filename="/home/andreas/project/gnome-icon-theme/scalable/actions/process-stop.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ version="1.0">
+ <defs
+ id="defs4910">
+ <radialGradient
+ gradientTransform="matrix(1.349881,0,0,1.349881,-3.498814,-1.810859)"
+ gradientUnits="userSpaceOnUse"
+ r="9.7183542"
+ fy="4.9892726"
+ fx="9.6893959"
+ cy="4.9892726"
+ cx="9.6893959"
+ id="radialGradient5177"
+ xlink:href="#linearGradient5171"
+ inkscape:collect="always" />
+ <radialGradient
+ gradientTransform="matrix(2.417917,0,0,2.417917,-14.17917,-4.903184)"
+ gradientUnits="userSpaceOnUse"
+ r="9.7785711"
+ fy="3.458019"
+ fx="10"
+ cy="3.458019"
+ cx="10"
+ id="radialGradient5157"
+ xlink:href="#linearGradient5151"
+ inkscape:collect="always" />
+ <radialGradient
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.928125,0,0,0.3143011,0.7718789,12.358015)"
+ r="9.0598059"
+ fy="18.022524"
+ fx="10.739184"
+ cy="18.022524"
+ cx="10.739184"
+ id="radialGradient5145"
+ xlink:href="#linearGradient5139"
+ inkscape:collect="always" />
+ <linearGradient
+ id="linearGradient5139"
+ inkscape:collect="always">
+ <stop
+ id="stop5141"
+ offset="0"
+ style="stop-color:black;stop-opacity:1;" />
+ <stop
+ id="stop5143"
+ offset="1"
+ style="stop-color:black;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient5151"
+ inkscape:collect="always">
+ <stop
+ id="stop5153"
+ offset="0"
+ style="stop-color:white;stop-opacity:1;" />
+ <stop
+ id="stop5155"
+ offset="1"
+ style="stop-color:white;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient5171">
+ <stop
+ id="stop5173"
+ offset="0"
+ style="stop-color:#fe3a00;stop-opacity:1" />
+ <stop
+ id="stop5175"
+ offset="1"
+ style="stop-color:#c00;stop-opacity:1;" />
+ </linearGradient>
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="5.6568542"
+ inkscape:cx="35.649059"
+ inkscape:cy="26.052211"
+ inkscape:current-layer="g7001"
+ showgrid="false"
+ inkscape:grid-bbox="true"
+ inkscape:document-units="px"
+ showguides="true"
+ inkscape:guide-bbox="true"
+ inkscape:window-width="1674"
+ inkscape:window-height="970"
+ inkscape:window-x="0"
+ inkscape:window-y="25"
+ width="48px"
+ height="48px" />
+ <metadata
+ id="metadata4913">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title>Stop Process</dc:title>
+ <dc:date>December 2006</dc:date>
+ <dc:creator>
+ <cc:Agent>
+ <dc:title>Jakub Steiner</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ <dc:contributor>
+ <cc:Agent>
+ <dc:title>Andreas Nilsson</dc:title>
+ </cc:Agent>
+ </dc:contributor>
+ <cc:license
+ rdf:resource="http://creativecommons.org/licenses/GPL/2.0/" />
+ <dc:subject>
+ <rdf:Bag>
+ <rdf:li>stop</rdf:li>
+ <rdf:li>halt</rdf:li>
+ </rdf:Bag>
+ </dc:subject>
+ </cc:Work>
+ <cc:License
+ rdf:about="http://creativecommons.org/licenses/GPL/2.0/">
+ <cc:permits
+ rdf:resource="http://web.resource.org/cc/Reproduction" />
+ <cc:permits
+ rdf:resource="http://web.resource.org/cc/Distribution" />
+ <cc:requires
+ rdf:resource="http://web.resource.org/cc/Notice" />
+ <cc:permits
+ rdf:resource="http://web.resource.org/cc/DerivativeWorks" />
+ <cc:requires
+ rdf:resource="http://web.resource.org/cc/ShareAlike" />
+ <cc:requires
+ rdf:resource="http://web.resource.org/cc/SourceCode" />
+ </cc:License>
+ </rdf:RDF>
+ </metadata>
+ <g
+ id="layer1"
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer">
+ <g
+ inkscape:label="Layer 1"
+ id="g7001"
+ transform="matrix(1.4566048,0,0,1.4455352,0.4112881,1.2324709)">
+ <path
+ transform="matrix(1.5155468,0,0,1.2299034,-8.1425489e-2,4.9987359)"
+ d="M 19.79899 18.022524 A 9.0598059 3.0935922 0 1 1 1.6793785,18.022524 A 9.0598059 3.0935922 0 1 1 19.79899 18.022524 z"
+ sodipodi:ry="3.0935922"
+ sodipodi:rx="9.0598059"
+ sodipodi:cy="18.022524"
+ sodipodi:cx="10.739184"
+ id="path5137"
+ style="opacity:1;color:#000000;fill:url(#radialGradient5145);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+ sodipodi:type="arc" />
+ <path
+ transform="matrix(1.4472753,0,0,1.4583582,1.7215589,1.7135444)"
+ d="M 19.25 9.625 A 9.25 9.25 0 1 1 0.75,9.625 A 9.25 9.25 0 1 1 19.25 9.625 z"
+ sodipodi:ry="9.25"
+ sodipodi:rx="9.25"
+ sodipodi:cy="9.625"
+ sodipodi:cx="10"
+ id="path4262"
+ style="opacity:1;color:#000000;fill:url(#radialGradient5177);fill-opacity:1;fill-rule:nonzero;stroke:#a40000;stroke-width:0.47435912;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:type="arc"
+ style="opacity:0.35393258;color:#000000;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:url(#radialGradient5157);stroke-width:0.49999994;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+ id="path5149"
+ sodipodi:cx="10"
+ sodipodi:cy="9.625"
+ sodipodi:rx="9.25"
+ sodipodi:ry="9.25"
+ d="M 19.25 9.625 A 9.25 9.25 0 1 1 0.75,9.625 A 9.25 9.25 0 1 1 19.25 9.625 z"
+ transform="matrix(1.373056,0,0,1.3835706,2.4637512,2.4333749)" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path5159"
+ d="M 11.045351,10.561853 L 21.343271,20.938632"
+ style="opacity:1;color:#000000;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:2.06745481;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
+ <path
+ style="opacity:1;color:#000000;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:2.06745505;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+ d="M 21.343273,10.526816 L 11.015248,20.938631"
+ id="path5161"
+ sodipodi:nodetypes="cc" />
+ </g>
+ </g>
+</svg>
diff --git a/site/app/webroot/img/amo2009/notifications/info.png b/site/app/webroot/img/amo2009/notifications/info.png
new file mode 100644
index 0000000..2b9baa2
--- /dev/null
+++ b/site/app/webroot/img/amo2009/notifications/info.png
Binary files differ
diff --git a/site/app/webroot/img/amo2009/notifications/info.svg b/site/app/webroot/img/amo2009/notifications/info.svg
new file mode 100644
index 0000000..f97cb5c
--- /dev/null
+++ b/site/app/webroot/img/amo2009/notifications/info.svg
@@ -0,0 +1,218 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://web.resource.org/cc/"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ id="svg1"
+ sodipodi:version="0.32"
+ inkscape:version="0.45"
+ width="48"
+ height="48"
+ sodipodi:docbase="/home/dobey/Projects/gnome-icon-theme/scalable/emblems"
+ sodipodi:docname="emblem-generic.svg"
+ inkscape:output_extension="org.inkscape.output.svg.inkscape"
+ version="1.0">
+ <defs
+ id="defs3">
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient5300">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop5302" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop5304" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient5224">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop5226" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop5228" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5224"
+ id="radialGradient5230"
+ cx="14.5"
+ cy="26.6875"
+ fx="14.5"
+ fy="26.6875"
+ r="10"
+ gradientTransform="matrix(1,0,0,0.29375,0,18.848047)"
+ gradientUnits="userSpaceOnUse" />
+ <filter
+ inkscape:collect="always"
+ id="filter5296"
+ x="-0.09814655"
+ width="1.1962931"
+ y="-0.33411592"
+ height="1.6682318">
+ <feGaussianBlur
+ inkscape:collect="always"
+ stdDeviation="0.81788793"
+ id="feGaussianBlur5298" />
+ </filter>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5300"
+ id="radialGradient5306"
+ cx="29.77438"
+ cy="7.0922189"
+ fx="29.77438"
+ fy="7.0922189"
+ r="25.380436"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.2469896,0,0,2.2469896,-37.128341,-8.8439229)" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5224"
+ id="radialGradient5330"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.29375,0,18.848047)"
+ cx="14.5"
+ cy="26.6875"
+ fx="14.5"
+ fy="26.6875"
+ r="10" />
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#ededed"
+ borderopacity="1"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="1"
+ inkscape:cx="30.695085"
+ inkscape:cy="10.571945"
+ inkscape:window-width="826"
+ inkscape:window-height="790"
+ gridspacingx="0.50000000mm"
+ gridspacingy="0.50000000mm"
+ showgrid="false"
+ inkscape:grid-bbox="false"
+ inkscape:window-x="348"
+ inkscape:window-y="229"
+ inkscape:current-layer="svg1"
+ borderlayer="true"
+ inkscape:showpageshadow="false"
+ width="48px"
+ height="48px">
+ <inkscape:grid
+ type="xygrid"
+ id="grid5308" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata4">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title>Emblem Urgent</dc:title>
+ <dc:creator>
+ <cc:Agent>
+ <dc:title>Jakub Steiner</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ <dc:contributor>
+ <cc:Agent>
+ <dc:title>Andreas Nilsson</dc:title>
+ </cc:Agent>
+ </dc:contributor>
+ <cc:license
+ rdf:resource="http://creativecommons.org/licenses/GPL/2.0/" />
+ <dc:subject>
+ <rdf:Bag>
+ <rdf:li>generic</rdf:li>
+ </rdf:Bag>
+ </dc:subject>
+ </cc:Work>
+ <cc:License
+ rdf:about="http://creativecommons.org/licenses/GPL/2.0/">
+ <cc:permits
+ rdf:resource="http://web.resource.org/cc/Reproduction" />
+ <cc:permits
+ rdf:resource="http://web.resource.org/cc/Distribution" />
+ <cc:requires
+ rdf:resource="http://web.resource.org/cc/Notice" />
+ <cc:permits
+ rdf:resource="http://web.resource.org/cc/DerivativeWorks" />
+ <cc:requires
+ rdf:resource="http://web.resource.org/cc/ShareAlike" />
+ <cc:requires
+ rdf:resource="http://web.resource.org/cc/SourceCode" />
+ </cc:License>
+ </rdf:RDF>
+ </metadata>
+ <path
+ sodipodi:type="arc"
+ style="opacity:0.53012048;color:#000000;fill:url(#radialGradient5230);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;filter:url(#filter5296);enable-background:accumulate"
+ id="path4645"
+ sodipodi:cx="14.5"
+ sodipodi:cy="26.6875"
+ sodipodi:rx="10"
+ sodipodi:ry="2.9375"
+ d="M 24.5,26.6875 A 10,2.9375 0 1 1 4.5,26.6875 A 10,2.9375 0 1 1 24.5,26.6875 z"
+ transform="matrix(2.1570145,0,0,2.155398,-7.8468552,-16.33814)" />
+ <path
+ transform="matrix(1.3478975,0,0,1.3468874,3.8853414,6.4889877)"
+ d="M 24.5,26.6875 A 10,2.9375 0 1 1 4.5,26.6875 A 10,2.9375 0 1 1 24.5,26.6875 z"
+ sodipodi:ry="2.9375"
+ sodipodi:rx="10"
+ sodipodi:cy="26.6875"
+ sodipodi:cx="14.5"
+ id="path5328"
+ style="opacity:0.80120482;color:#000000;fill:url(#radialGradient5330);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;filter:url(#filter5296);enable-background:accumulate"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:type="arc"
+ style="fill:#73d216;fill-opacity:1;fill-rule:evenodd;stroke:#4e9a06;stroke-width:1.37804782;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ id="path907"
+ sodipodi:cx="29.392656"
+ sodipodi:cy="29.207693"
+ sodipodi:rx="29.010935"
+ sodipodi:ry="29.010935"
+ d="M 58.403591,29.207693 A 29.010935,29.010935 0 1 1 0.3817215,29.207693 A 29.010935,29.010935 0 1 1 58.403591,29.207693 z"
+ transform="matrix(0.7238447,0,0,0.7274883,2.1828126,2.3568607)" />
+ <path
+ sodipodi:type="arc"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1pt;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ id="path2159"
+ sodipodi:cx="31.760445"
+ sodipodi:cy="29.319231"
+ sodipodi:rx="18.624397"
+ sodipodi:ry="18.624397"
+ d="M 50.384842,29.319231 A 18.624397,18.624397 0 1 1 13.136047,29.319231 A 18.624397,18.624397 0 1 1 50.384842,29.319231 z"
+ transform="matrix(0.7596079,0,0,0.7590386,-0.4103397,1.051346)" />
+ <path
+ sodipodi:type="arc"
+ style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:url(#radialGradient5306);stroke-width:1.21160841;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="path1552"
+ sodipodi:cx="29.77438"
+ sodipodi:cy="30.352861"
+ sodipodi:rx="24.175779"
+ sodipodi:ry="24.175779"
+ d="M 53.950159,30.352861 A 24.175779,24.175779 0 1 1 5.5986004,30.352861 A 24.175779,24.175779 0 1 1 53.950159,30.352861 z"
+ transform="matrix(0.8254302,0,0,0.8252681,-1.1457884,-1.4441229)" />
+ <path
+ id="text2450"
+ d="M 32.06445,20.438116 L 26.569808,23.31648 L 32.06445,26.211481 L 30.799016,28.557435 L 25.271076,25.496051 L 25.271076,31.219506 L 22.407197,31.219506 L 22.407197,25.496051 L 16.895899,28.557435 L 15.630474,26.211481 L 21.158417,23.31648 L 15.630474,20.438116 L 16.895899,18.092164 L 22.407197,21.120271 L 22.407197,15.396818 L 25.271076,15.396818 L 25.271076,21.120271 L 30.799016,18.092164 L 32.06445,20.438116"
+ style="font-size:12px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;line-height:100%;writing-mode:lr-tb;text-anchor:start;fill:#4e9a06;fill-opacity:1;stroke:#4e9a06;stroke-width:0.99999988px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;font-family:Bitstream Vera Sans Mono" />
+</svg>
diff --git a/site/app/webroot/img/amo2009/notifications/sprite.png b/site/app/webroot/img/amo2009/notifications/sprite.png
new file mode 100644
index 0000000..d97fb41
--- /dev/null
+++ b/site/app/webroot/img/amo2009/notifications/sprite.png
Binary files differ
diff --git a/site/app/webroot/img/amo2009/notifications/success.png b/site/app/webroot/img/amo2009/notifications/success.png
new file mode 100644
index 0000000..e23c940
--- /dev/null
+++ b/site/app/webroot/img/amo2009/notifications/success.png
Binary files differ
diff --git a/site/app/webroot/img/amo2009/notifications/success.svg b/site/app/webroot/img/amo2009/notifications/success.svg
new file mode 100644
index 0000000..c3ef44f
--- /dev/null
+++ b/site/app/webroot/img/amo2009/notifications/success.svg
@@ -0,0 +1,270 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://web.resource.org/cc/"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ id="svg1"
+ sodipodi:version="0.32"
+ inkscape:version="0.45"
+ width="48"
+ height="48"
+ sodipodi:docbase="/home/dobey/Projects/gnome-icon-theme/scalable/emblems"
+ sodipodi:docname="emblem-default.svg"
+ inkscape:output_extension="org.inkscape.output.svg.inkscape"
+ version="1.0">
+ <defs
+ id="defs3">
+ <linearGradient
+ id="linearGradient5237">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop5239" />
+ <stop
+ id="stop5247"
+ offset="0.5"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ <stop
+ style="stop-color:#9c9c9c;stop-opacity:1"
+ offset="1"
+ id="stop5241" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient5226">
+ <stop
+ style="stop-color:#63b512;stop-opacity:1;"
+ offset="0"
+ id="stop5229" />
+ <stop
+ id="stop5245"
+ offset="0.16030352"
+ style="stop-color:#58a30e;stop-opacity:1;" />
+ <stop
+ id="stop5235"
+ offset="0.66008514"
+ style="stop-color:#366b04;stop-opacity:1" />
+ <stop
+ style="stop-color:#87ea25;stop-opacity:1"
+ offset="1"
+ id="stop5231" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient5300">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop5302" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop5304" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient5224">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop5226" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop5228" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5224"
+ id="radialGradient5230"
+ cx="14.5"
+ cy="26.6875"
+ fx="14.5"
+ fy="26.6875"
+ r="10"
+ gradientTransform="matrix(1,0,0,0.29375,0,18.848047)"
+ gradientUnits="userSpaceOnUse" />
+ <filter
+ inkscape:collect="always"
+ id="filter5296"
+ x="-0.09814655"
+ width="1.1962931"
+ y="-0.33411592"
+ height="1.6682318">
+ <feGaussianBlur
+ inkscape:collect="always"
+ stdDeviation="0.81788793"
+ id="feGaussianBlur5298" />
+ </filter>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5300"
+ id="radialGradient5306"
+ cx="29.77438"
+ cy="7.0922189"
+ fx="29.77438"
+ fy="7.0922189"
+ r="25.380436"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.2469896,0,0,2.2469896,-37.128341,-8.8439229)" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5224"
+ id="radialGradient5330"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.29375,0,18.848047)"
+ cx="14.5"
+ cy="26.6875"
+ fx="14.5"
+ fy="26.6875"
+ r="10" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5226"
+ id="radialGradient5233"
+ cx="29.392656"
+ cy="18.898249"
+ fx="29.392656"
+ fy="18.898249"
+ r="29.699959"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.5354369,0,0,1.5485894,-15.737913,-10.36738)" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5237"
+ id="radialGradient5243"
+ cx="22.9375"
+ cy="16.305218"
+ fx="22.9375"
+ fy="16.305218"
+ r="15.5625"
+ gradientTransform="matrix(1.5301205,0,0,1.6745294,-12.159639,-11.709817)"
+ gradientUnits="userSpaceOnUse" />
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#ededed"
+ borderopacity="1"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="1"
+ inkscape:cx="39.269655"
+ inkscape:cy="17.441445"
+ inkscape:window-width="826"
+ inkscape:window-height="790"
+ gridspacingx="0.50000000mm"
+ gridspacingy="0.50000000mm"
+ showgrid="false"
+ inkscape:grid-bbox="false"
+ inkscape:window-x="461"
+ inkscape:window-y="278"
+ inkscape:current-layer="svg1"
+ borderlayer="true"
+ inkscape:showpageshadow="false"
+ width="744.09449px"
+ height="1052.3622px">
+ <inkscape:grid
+ type="xygrid"
+ id="grid5308" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata4">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title>Emblem Urgent</dc:title>
+ <dc:creator>
+ <cc:Agent>
+ <dc:title>Jakub Steiner</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ <dc:contributor>
+ <cc:Agent>
+ <dc:title>Andreas Nilsson</dc:title>
+ </cc:Agent>
+ </dc:contributor>
+ <cc:license
+ rdf:resource="http://creativecommons.org/licenses/GPL/2.0/" />
+ <dc:subject>
+ <rdf:Bag>
+ <rdf:li>generic</rdf:li>
+ </rdf:Bag>
+ </dc:subject>
+ </cc:Work>
+ <cc:License
+ rdf:about="http://creativecommons.org/licenses/GPL/2.0/">
+ <cc:permits
+ rdf:resource="http://web.resource.org/cc/Reproduction" />
+ <cc:permits
+ rdf:resource="http://web.resource.org/cc/Distribution" />
+ <cc:requires
+ rdf:resource="http://web.resource.org/cc/Notice" />
+ <cc:permits
+ rdf:resource="http://web.resource.org/cc/DerivativeWorks" />
+ <cc:requires
+ rdf:resource="http://web.resource.org/cc/ShareAlike" />
+ <cc:requires
+ rdf:resource="http://web.resource.org/cc/SourceCode" />
+ </cc:License>
+ </rdf:RDF>
+ </metadata>
+ <path
+ sodipodi:type="arc"
+ style="opacity:0.53012048;color:#000000;fill:url(#radialGradient5230);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;filter:url(#filter5296);enable-background:accumulate"
+ id="path4645"
+ sodipodi:cx="14.5"
+ sodipodi:cy="26.6875"
+ sodipodi:rx="10"
+ sodipodi:ry="2.9375"
+ d="M 24.5,26.6875 A 10,2.9375 0 1 1 4.5,26.6875 A 10,2.9375 0 1 1 24.5,26.6875 z"
+ transform="matrix(2.1570145,0,0,2.155398,-7.8468552,-16.33814)" />
+ <path
+ transform="matrix(1.3478975,0,0,1.3468874,3.8853414,6.4889877)"
+ d="M 24.5,26.6875 A 10,2.9375 0 1 1 4.5,26.6875 A 10,2.9375 0 1 1 24.5,26.6875 z"
+ sodipodi:ry="2.9375"
+ sodipodi:rx="10"
+ sodipodi:cy="26.6875"
+ sodipodi:cx="14.5"
+ id="path5328"
+ style="opacity:0.80120482;color:#000000;fill:url(#radialGradient5330);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;filter:url(#filter5296);enable-background:accumulate"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:type="arc"
+ style="fill:url(#radialGradient5233);fill-opacity:1;fill-rule:evenodd;stroke:#316203;stroke-width:1.37804781999999992;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ id="path907"
+ sodipodi:cx="29.392656"
+ sodipodi:cy="29.207693"
+ sodipodi:rx="29.010935"
+ sodipodi:ry="29.010935"
+ d="M 58.403591,29.207693 A 29.010935,29.010935 0 1 1 0.3817215,29.207693 A 29.010935,29.010935 0 1 1 58.403591,29.207693 z"
+ transform="matrix(0.7238447,0,0,0.7274883,2.1828126,2.3568607)" />
+ <path
+ sodipodi:type="arc"
+ style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:url(#radialGradient5306);stroke-width:1.21160841;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="path1552"
+ sodipodi:cx="29.77438"
+ sodipodi:cy="30.352861"
+ sodipodi:rx="24.175779"
+ sodipodi:ry="24.175779"
+ d="M 53.950159,30.352861 A 24.175779,24.175779 0 1 1 5.5986004,30.352861 A 24.175779,24.175779 0 1 1 53.950159,30.352861 z"
+ transform="matrix(0.8254302,0,0,0.8252681,-1.1457884,-1.4441229)" />
+ <path
+ style="opacity:1;color:#000000;fill:url(#radialGradient5243);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="M 12.875,24.625 L 25.375,36.625 L 44,20.625 C 43.253602,16.729371 41.57038,13.679873 39.8125,11.0625 L 25.125,23.75 L 20.375,18.5 L 12.875,24.625 z"
+ id="path5222"
+ sodipodi:nodetypes="ccccccc" />
+ <path
+ style="opacity:1;color:#000000;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#549910;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="M 40.21875,10.8125 C 41.930961,13.346411 43.59334,15.979986 44.40625,20.3125"
+ id="path5224"
+ sodipodi:nodetypes="cc" />
+</svg>
diff --git a/site/app/webroot/img/amo2009/notifications/warning.png b/site/app/webroot/img/amo2009/notifications/warning.png
new file mode 100644
index 0000000..022a9a0
--- /dev/null
+++ b/site/app/webroot/img/amo2009/notifications/warning.png
Binary files differ
diff --git a/site/app/webroot/img/amo2009/notifications/warning.svg b/site/app/webroot/img/amo2009/notifications/warning.svg
new file mode 100644
index 0000000..5a4245b
--- /dev/null
+++ b/site/app/webroot/img/amo2009/notifications/warning.svg
@@ -0,0 +1,221 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://web.resource.org/cc/"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ id="svg1"
+ sodipodi:version="0.32"
+ inkscape:version="0.45"
+ width="48"
+ height="48"
+ sodipodi:docbase="/home/dobey/Projects/gnome-icon-theme/scalable/emblems"
+ sodipodi:docname="emblem-important.svg"
+ version="1.0"
+ inkscape:output_extension="org.inkscape.output.svg.inkscape">
+ <defs
+ id="defs3">
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient2806">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop2808" />
+ <stop
+ style="stop-color:black;stop-opacity:0;"
+ offset="1"
+ id="stop2810" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient2796">
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="0"
+ id="stop2798" />
+ <stop
+ style="stop-color:#dfdfdf;stop-opacity:1;"
+ offset="1"
+ id="stop2800" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient2788">
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="0"
+ id="stop2790" />
+ <stop
+ style="stop-color:white;stop-opacity:0;"
+ offset="1"
+ id="stop2792" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient2778">
+ <stop
+ style="stop-color:#ff0202;stop-opacity:1;"
+ offset="0"
+ id="stop2780" />
+ <stop
+ style="stop-color:#b20000;stop-opacity:1;"
+ offset="1"
+ id="stop2782" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2778"
+ id="radialGradient2784"
+ cx="30.323671"
+ cy="13.380429"
+ fx="30.323671"
+ fy="13.380429"
+ r="29.755747"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.531919,0,0,1.531919,-16.12973,-7.117303)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2788"
+ id="linearGradient2794"
+ x1="-0.36309087"
+ y1="29.207693"
+ x2="59.148404"
+ y2="29.207693"
+ gradientUnits="userSpaceOnUse" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2796"
+ id="radialGradient2802"
+ cx="31.760437"
+ cy="22.226139"
+ fx="31.760437"
+ fy="22.226139"
+ r="18.624397"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.316528,0,0,1.316528,-10.05306,-9.280346)" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2806"
+ id="radialGradient2812"
+ cx="25.25"
+ cy="39.75"
+ fx="25.25"
+ fy="39.75"
+ r="17.25"
+ gradientTransform="matrix(1,0,0,0.333333,0,26.5)"
+ gradientUnits="userSpaceOnUse" />
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666"
+ borderopacity="0.23529412"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="1"
+ inkscape:cx="40.138787"
+ inkscape:cy="11.506498"
+ inkscape:window-width="1097"
+ inkscape:window-height="956"
+ gridspacingx="0.50000000mm"
+ gridspacingy="0.50000000mm"
+ showgrid="false"
+ inkscape:grid-bbox="false"
+ inkscape:window-x="391"
+ inkscape:window-y="65"
+ inkscape:current-layer="svg1"
+ width="48px"
+ height="48px"
+ inkscape:showpageshadow="false" />
+ <metadata
+ id="metadata4">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title>Emblem Urgent</dc:title>
+ <dc:creator>
+ <cc:Agent>
+ <dc:title>Jakub Steiner</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ <dc:contributor>
+ <cc:Agent>
+ <dc:title>Andreas Nilsson</dc:title>
+ </cc:Agent>
+ </dc:contributor>
+ <cc:license
+ rdf:resource="http://creativecommons.org/licenses/GPL/2.0/" />
+ </cc:Work>
+ <cc:License
+ rdf:about="http://creativecommons.org/licenses/GPL/2.0/">
+ <cc:permits
+ rdf:resource="http://web.resource.org/cc/Reproduction" />
+ <cc:permits
+ rdf:resource="http://web.resource.org/cc/Distribution" />
+ <cc:requires
+ rdf:resource="http://web.resource.org/cc/Notice" />
+ <cc:permits
+ rdf:resource="http://web.resource.org/cc/DerivativeWorks" />
+ <cc:requires
+ rdf:resource="http://web.resource.org/cc/ShareAlike" />
+ <cc:requires
+ rdf:resource="http://web.resource.org/cc/SourceCode" />
+ </cc:License>
+ </rdf:RDF>
+ </metadata>
+ <path
+ sodipodi:type="arc"
+ style="opacity:0.64432989;color:black;fill:url(#radialGradient2812);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+ id="path2804"
+ sodipodi:cx="25.25"
+ sodipodi:cy="39.75"
+ sodipodi:rx="17.25"
+ sodipodi:ry="5.75"
+ d="M 42.5 39.75 A 17.25 5.75 0 1 1 8,39.75 A 17.25 5.75 0 1 1 42.5 39.75 z"
+ transform="matrix(1.15942,0,0,1.507246,-3.775362,-22.16304)" />
+ <path
+ sodipodi:type="arc"
+ style="fill:url(#radialGradient2784);fill-opacity:1.0;fill-rule:evenodd;stroke:#a40000;stroke-width:1.48962476;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ id="path907"
+ sodipodi:cx="29.392656"
+ sodipodi:cy="29.207693"
+ sodipodi:rx="29.010935"
+ sodipodi:ry="29.010935"
+ d="M 58.403591 29.207693 A 29.010935 29.010935 0 1 1 0.3817215,29.207693 A 29.010935 29.010935 0 1 1 58.403591 29.207693 z"
+ transform="matrix(0.67131,0,0,0.67131,5.222369,3.418373)" />
+ <path
+ sodipodi:type="arc"
+ style="fill:url(#radialGradient2802);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1pt;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ id="path2159"
+ sodipodi:cx="31.760445"
+ sodipodi:cy="29.319231"
+ sodipodi:rx="18.624397"
+ sodipodi:ry="18.624397"
+ d="M 50.384842 29.319231 A 18.624397 18.624397 0 1 1 13.136047,29.319231 A 18.624397 18.624397 0 1 1 50.384842 29.319231 z"
+ transform="matrix(0.780964,0,0,0.780964,0.172888,-0.147684)" />
+ <path
+ id="text1299"
+ d="M 23.270741,31.644037 C 23.270738,31.139201 23.454793,30.697468 23.822909,30.318838 C 24.201533,29.929696 24.643266,29.735123 25.148108,29.73512 C 25.663458,29.735123 26.110449,29.924437 26.489083,30.303061 C 26.867705,30.681694 27.057018,31.128685 27.057027,31.644037 C 27.057018,32.148877 26.862445,32.59061 26.473307,32.969238 C 26.094673,33.337348 25.65294,33.521403 25.148108,33.521403 C 24.664301,33.521403 24.227826,33.33209 23.838685,32.953462 C 23.460053,32.564314 23.270738,32.127843 23.270741,31.644037"
+ style="font-size:19.83371353px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:100%;writing-mode:lr-tb;text-anchor:start;fill:#a63434;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Dutch801 SWM" />
+ <path
+ id="path1591"
+ d="M 22.990601,14.858179 C 22.936763,14.605777 22.896388,14.348101 22.869477,14.085146 C 22.856012,13.822228 22.849284,13.559292 22.849288,13.296337 C 22.849284,12.602205 23.044429,12.076333 23.434724,11.718718 C 23.838466,11.35063 24.41717,11.166573 25.170838,11.166553 C 25.95141,11.166573 26.543572,11.34537 26.947327,11.702942 C 27.364524,12.060557 27.573127,12.591688 27.573137,13.296337 C 27.573127,13.559292 27.559669,13.822228 27.532762,14.085146 C 27.519295,14.348101 27.492379,14.600519 27.452012,14.842402 L 25.493834,27.289811 L 24.666154,27.289811 L 22.990601,14.858179"
+ style="font-size:19.83371353px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:100%;writing-mode:lr-tb;text-anchor:start;fill:#a63434;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Dutch801 SWM" />
+ <path
+ transform="matrix(0.629301,0,0,0.629301,6.457116,4.64535)"
+ d="M 58.403591 29.207693 A 29.010935 29.010935 0 1 1 0.3817215,29.207693 A 29.010935 29.010935 0 1 1 58.403591 29.207693 z"
+ sodipodi:ry="29.010935"
+ sodipodi:rx="29.010935"
+ sodipodi:cy="29.207693"
+ sodipodi:cx="29.392656"
+ id="path2786"
+ style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient2794);stroke-width:1.58906469;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;opacity:0.37628866"
+ sodipodi:type="arc" />
+</svg>
diff --git a/site/app/webroot/img/amo2009/site-images/add-on-abp.gif b/site/app/webroot/img/amo2009/site-images/add-on-abp.gif
new file mode 100644
index 0000000..c9e523d
--- /dev/null
+++ b/site/app/webroot/img/amo2009/site-images/add-on-abp.gif
Binary files differ
diff --git a/site/app/webroot/img/amo2009/site-images/add-on-ebay.gif b/site/app/webroot/img/amo2009/site-images/add-on-ebay.gif
new file mode 100644
index 0000000..dd31baf
--- /dev/null
+++ b/site/app/webroot/img/amo2009/site-images/add-on-ebay.gif
Binary files differ
diff --git a/site/app/webroot/img/amo2009/site-images/add-on-icon-games.gif b/site/app/webroot/img/amo2009/site-images/add-on-icon-games.gif
new file mode 100644
index 0000000..db2ad2c
--- /dev/null
+++ b/site/app/webroot/img/amo2009/site-images/add-on-icon-games.gif
Binary files differ
diff --git a/site/app/webroot/img/amo2009/site-images/add-on-icon-pdf.gif b/site/app/webroot/img/amo2009/site-images/add-on-icon-pdf.gif
new file mode 100644
index 0000000..5d694d0
--- /dev/null
+++ b/site/app/webroot/img/amo2009/site-images/add-on-icon-pdf.gif
Binary files differ
diff --git a/site/app/webroot/img/amo2009/site-images/add-on-retail.gif b/site/app/webroot/img/amo2009/site-images/add-on-retail.gif
new file mode 100644
index 0000000..31b4597
--- /dev/null
+++ b/site/app/webroot/img/amo2009/site-images/add-on-retail.gif
Binary files differ
diff --git a/site/app/webroot/img/amo2009/site-images/add-on-yapta.gif b/site/app/webroot/img/amo2009/site-images/add-on-yapta.gif
new file mode 100644
index 0000000..a71243b
--- /dev/null
+++ b/site/app/webroot/img/amo2009/site-images/add-on-yapta.gif
Binary files differ
diff --git a/site/app/webroot/img/amo2009/site-images/avatar-128x128.jpg b/site/app/webroot/img/amo2009/site-images/avatar-128x128.jpg
new file mode 100644
index 0000000..0d1dca7
--- /dev/null
+++ b/site/app/webroot/img/amo2009/site-images/avatar-128x128.jpg
Binary files differ
diff --git a/site/app/webroot/img/amo2009/site-images/avatar-developer-128x128.jpg b/site/app/webroot/img/amo2009/site-images/avatar-developer-128x128.jpg
new file mode 100644
index 0000000..b4419de
--- /dev/null
+++ b/site/app/webroot/img/amo2009/site-images/avatar-developer-128x128.jpg
Binary files differ
diff --git a/site/app/webroot/img/amo2009/site-images/avatar-developer-200x200.jpg b/site/app/webroot/img/amo2009/site-images/avatar-developer-200x200.jpg
new file mode 100644
index 0000000..f1a31ea
--- /dev/null
+++ b/site/app/webroot/img/amo2009/site-images/avatar-developer-200x200.jpg
Binary files differ
diff --git a/site/app/webroot/img/amo2009/site-images/avatar-developer-32x32.jpg b/site/app/webroot/img/amo2009/site-images/avatar-developer-32x32.jpg
new file mode 100644
index 0000000..e33bb3e
--- /dev/null
+++ b/site/app/webroot/img/amo2009/site-images/avatar-developer-32x32.jpg
Binary files differ
diff --git a/site/app/webroot/img/amo2009/site-images/avatar-developer-64x64.jpg b/site/app/webroot/img/amo2009/site-images/avatar-developer-64x64.jpg
new file mode 100644
index 0000000..5c3b531
--- /dev/null
+++ b/site/app/webroot/img/amo2009/site-images/avatar-developer-64x64.jpg
Binary files differ
diff --git a/site/app/webroot/img/amo2009/site-images/collection-music.gif b/site/app/webroot/img/amo2009/site-images/collection-music.gif
new file mode 100644
index 0000000..7af4d2d
--- /dev/null
+++ b/site/app/webroot/img/amo2009/site-images/collection-music.gif
Binary files differ
diff --git a/site/app/webroot/img/amo2009/site-images/collection-travellers.gif b/site/app/webroot/img/amo2009/site-images/collection-travellers.gif
new file mode 100644
index 0000000..dc3777f
--- /dev/null
+++ b/site/app/webroot/img/amo2009/site-images/collection-travellers.gif
Binary files differ
diff --git a/site/app/webroot/img/amo2009/site-images/collection-web-developers.gif b/site/app/webroot/img/amo2009/site-images/collection-web-developers.gif
new file mode 100644
index 0000000..cf22f6e
--- /dev/null
+++ b/site/app/webroot/img/amo2009/site-images/collection-web-developers.gif
Binary files differ
diff --git a/site/app/webroot/img/amo2009/site-images/plus-green-small.gif b/site/app/webroot/img/amo2009/site-images/plus-green-small.gif
new file mode 100644
index 0000000..913006e
--- /dev/null
+++ b/site/app/webroot/img/amo2009/site-images/plus-green-small.gif
Binary files differ
diff --git a/site/app/webroot/img/amo2009/site-images/screenshot-addon-example-01.jpg b/site/app/webroot/img/amo2009/site-images/screenshot-addon-example-01.jpg
new file mode 100644
index 0000000..a34e8b3
--- /dev/null
+++ b/site/app/webroot/img/amo2009/site-images/screenshot-addon-example-01.jpg
Binary files differ
diff --git a/site/app/webroot/img/amo2009/site-images/screenshot-addon-example-02.jpg b/site/app/webroot/img/amo2009/site-images/screenshot-addon-example-02.jpg
new file mode 100644
index 0000000..a34e8b3
--- /dev/null
+++ b/site/app/webroot/img/amo2009/site-images/screenshot-addon-example-02.jpg
Binary files differ
diff --git a/site/app/webroot/img/amo2009/site-images/screenshot-addon-example-03.jpg b/site/app/webroot/img/amo2009/site-images/screenshot-addon-example-03.jpg
new file mode 100644
index 0000000..1c82a01
--- /dev/null
+++ b/site/app/webroot/img/amo2009/site-images/screenshot-addon-example-03.jpg
Binary files differ
diff --git a/site/app/webroot/img/amo2009/site-images/screenshot-addon-example-04.jpg b/site/app/webroot/img/amo2009/site-images/screenshot-addon-example-04.jpg
new file mode 100644
index 0000000..799df0b
--- /dev/null
+++ b/site/app/webroot/img/amo2009/site-images/screenshot-addon-example-04.jpg
Binary files differ
diff --git a/site/app/webroot/img/amo2009/site-images/screenshot-addon-example-05.jpg b/site/app/webroot/img/amo2009/site-images/screenshot-addon-example-05.jpg
new file mode 100644
index 0000000..90491d3
--- /dev/null
+++ b/site/app/webroot/img/amo2009/site-images/screenshot-addon-example-05.jpg
Binary files differ
diff --git a/site/app/webroot/img/amo2009/site-images/thumbnail-large-screenshot-pdf.jpg b/site/app/webroot/img/amo2009/site-images/thumbnail-large-screenshot-pdf.jpg
new file mode 100644
index 0000000..e671c6e
--- /dev/null
+++ b/site/app/webroot/img/amo2009/site-images/thumbnail-large-screenshot-pdf.jpg
Binary files differ
diff --git a/site/app/webroot/img/amo2009/site-images/thumbnail-large-screenshot.gif b/site/app/webroot/img/amo2009/site-images/thumbnail-large-screenshot.gif
new file mode 100644
index 0000000..4375435
--- /dev/null
+++ b/site/app/webroot/img/amo2009/site-images/thumbnail-large-screenshot.gif
Binary files differ
diff --git a/site/app/webroot/img/amo2009/site-images/thumbnail-screenshot.jpg b/site/app/webroot/img/amo2009/site-images/thumbnail-screenshot.jpg
new file mode 100644
index 0000000..cd68f8b
--- /dev/null
+++ b/site/app/webroot/img/amo2009/site-images/thumbnail-screenshot.jpg
Binary files differ
diff --git a/site/app/webroot/img/amo2009/tab-mozilla.png b/site/app/webroot/img/amo2009/tab-mozilla.png
new file mode 100644
index 0000000..4f64913
--- /dev/null
+++ b/site/app/webroot/img/amo2009/tab-mozilla.png
Binary files differ
diff --git a/site/app/webroot/img/app-icons/developers.png b/site/app/webroot/img/app-icons/developers.png
new file mode 100644
index 0000000..96b6919
--- /dev/null
+++ b/site/app/webroot/img/app-icons/developers.png
Binary files differ
diff --git a/site/app/webroot/img/app-icons/fennec-header.png b/site/app/webroot/img/app-icons/fennec-header.png
new file mode 100644
index 0000000..573f007
--- /dev/null
+++ b/site/app/webroot/img/app-icons/fennec-header.png
Binary files differ
diff --git a/site/app/webroot/img/app-icons/fennec_small.png b/site/app/webroot/img/app-icons/fennec_small.png
new file mode 100644
index 0000000..3047be5
--- /dev/null
+++ b/site/app/webroot/img/app-icons/fennec_small.png
Binary files differ
diff --git a/site/app/webroot/img/app-icons/firefox-header.png b/site/app/webroot/img/app-icons/firefox-header.png
new file mode 100644
index 0000000..25e92e3
--- /dev/null
+++ b/site/app/webroot/img/app-icons/firefox-header.png
Binary files differ
diff --git a/site/app/webroot/img/app-icons/firefox-ie.png b/site/app/webroot/img/app-icons/firefox-ie.png
new file mode 100644
index 0000000..f0d720f
--- /dev/null
+++ b/site/app/webroot/img/app-icons/firefox-ie.png
Binary files differ
diff --git a/site/app/webroot/img/app-icons/firefox-other.png b/site/app/webroot/img/app-icons/firefox-other.png
new file mode 100644
index 0000000..3fb8550
--- /dev/null
+++ b/site/app/webroot/img/app-icons/firefox-other.png
Binary files differ
diff --git a/site/app/webroot/img/app-icons/firefox-sm.png b/site/app/webroot/img/app-icons/firefox-sm.png
new file mode 100644
index 0000000..ea2ba3e
--- /dev/null
+++ b/site/app/webroot/img/app-icons/firefox-sm.png
Binary files differ
diff --git a/site/app/webroot/img/app-icons/firefox.png b/site/app/webroot/img/app-icons/firefox.png
new file mode 100644
index 0000000..338eb58
--- /dev/null
+++ b/site/app/webroot/img/app-icons/firefox.png
Binary files differ
diff --git a/site/app/webroot/img/app-icons/firefox_small.png b/site/app/webroot/img/app-icons/firefox_small.png
new file mode 100644
index 0000000..740a13a
--- /dev/null
+++ b/site/app/webroot/img/app-icons/firefox_small.png
Binary files differ
diff --git a/site/app/webroot/img/app-icons/generic.png b/site/app/webroot/img/app-icons/generic.png
new file mode 100644
index 0000000..96b6919
--- /dev/null
+++ b/site/app/webroot/img/app-icons/generic.png
Binary files differ
diff --git a/site/app/webroot/img/app-icons/mozilla_small.png b/site/app/webroot/img/app-icons/mozilla_small.png
new file mode 100644
index 0000000..caa8d37
--- /dev/null
+++ b/site/app/webroot/img/app-icons/mozilla_small.png
Binary files differ
diff --git a/site/app/webroot/img/app-icons/seamonkey-header.png b/site/app/webroot/img/app-icons/seamonkey-header.png
new file mode 100644
index 0000000..65137ed
--- /dev/null
+++ b/site/app/webroot/img/app-icons/seamonkey-header.png
Binary files differ
diff --git a/site/app/webroot/img/app-icons/seamonkey-ie.png b/site/app/webroot/img/app-icons/seamonkey-ie.png
new file mode 100644
index 0000000..f4a33cc
--- /dev/null
+++ b/site/app/webroot/img/app-icons/seamonkey-ie.png
Binary files differ
diff --git a/site/app/webroot/img/app-icons/seamonkey-other.png b/site/app/webroot/img/app-icons/seamonkey-other.png
new file mode 100644
index 0000000..c306f76
--- /dev/null
+++ b/site/app/webroot/img/app-icons/seamonkey-other.png
Binary files differ
diff --git a/site/app/webroot/img/app-icons/seamonkey.png b/site/app/webroot/img/app-icons/seamonkey.png
new file mode 100644
index 0000000..b416ae7
--- /dev/null
+++ b/site/app/webroot/img/app-icons/seamonkey.png
Binary files differ
diff --git a/site/app/webroot/img/app-icons/seamonkey_small.png b/site/app/webroot/img/app-icons/seamonkey_small.png
new file mode 100644
index 0000000..0320ee8
--- /dev/null
+++ b/site/app/webroot/img/app-icons/seamonkey_small.png
Binary files differ
diff --git a/site/app/webroot/img/app-icons/sunbird-header.png b/site/app/webroot/img/app-icons/sunbird-header.png
new file mode 100644
index 0000000..691d36a
--- /dev/null
+++ b/site/app/webroot/img/app-icons/sunbird-header.png
Binary files differ
diff --git a/site/app/webroot/img/app-icons/sunbird-ie.png b/site/app/webroot/img/app-icons/sunbird-ie.png
new file mode 100644
index 0000000..ddb1277
--- /dev/null
+++ b/site/app/webroot/img/app-icons/sunbird-ie.png
Binary files differ
diff --git a/site/app/webroot/img/app-icons/sunbird-other.png b/site/app/webroot/img/app-icons/sunbird-other.png
new file mode 100644
index 0000000..dfe29bb
--- /dev/null
+++ b/site/app/webroot/img/app-icons/sunbird-other.png
Binary files differ
diff --git a/site/app/webroot/img/app-icons/sunbird.png b/site/app/webroot/img/app-icons/sunbird.png
new file mode 100644
index 0000000..9ed896c
--- /dev/null
+++ b/site/app/webroot/img/app-icons/sunbird.png
Binary files differ
diff --git a/site/app/webroot/img/app-icons/sunbird_small.png b/site/app/webroot/img/app-icons/sunbird_small.png
new file mode 100644
index 0000000..404491b
--- /dev/null
+++ b/site/app/webroot/img/app-icons/sunbird_small.png
Binary files differ
diff --git a/site/app/webroot/img/app-icons/thunderbird-header.png b/site/app/webroot/img/app-icons/thunderbird-header.png
new file mode 100644
index 0000000..4b12ed4
--- /dev/null
+++ b/site/app/webroot/img/app-icons/thunderbird-header.png
Binary files differ
diff --git a/site/app/webroot/img/app-icons/thunderbird-ie.png b/site/app/webroot/img/app-icons/thunderbird-ie.png
new file mode 100644
index 0000000..c4dac7a
--- /dev/null
+++ b/site/app/webroot/img/app-icons/thunderbird-ie.png
Binary files differ
diff --git a/site/app/webroot/img/app-icons/thunderbird-other.png b/site/app/webroot/img/app-icons/thunderbird-other.png
new file mode 100644
index 0000000..81a6ff7
--- /dev/null
+++ b/site/app/webroot/img/app-icons/thunderbird-other.png
Binary files differ
diff --git a/site/app/webroot/img/app-icons/thunderbird.png b/site/app/webroot/img/app-icons/thunderbird.png
new file mode 100644
index 0000000..3639887
--- /dev/null
+++ b/site/app/webroot/img/app-icons/thunderbird.png
Binary files differ
diff --git a/site/app/webroot/img/app-icons/thunderbird_small.png b/site/app/webroot/img/app-icons/thunderbird_small.png
new file mode 100644
index 0000000..6f04373
--- /dev/null
+++ b/site/app/webroot/img/app-icons/thunderbird_small.png
Binary files differ
diff --git a/site/app/webroot/img/arr-next.png b/site/app/webroot/img/arr-next.png
new file mode 100644
index 0000000..994ea37
--- /dev/null
+++ b/site/app/webroot/img/arr-next.png
Binary files differ
diff --git a/site/app/webroot/img/arr-otherapps-closed.png b/site/app/webroot/img/arr-otherapps-closed.png
new file mode 100644
index 0000000..5770576
--- /dev/null
+++ b/site/app/webroot/img/arr-otherapps-closed.png
Binary files differ
diff --git a/site/app/webroot/img/arr-otherapps-open.png b/site/app/webroot/img/arr-otherapps-open.png
new file mode 100644
index 0000000..b035275
--- /dev/null
+++ b/site/app/webroot/img/arr-otherapps-open.png
Binary files differ
diff --git a/site/app/webroot/img/arr-prev.png b/site/app/webroot/img/arr-prev.png
new file mode 100644
index 0000000..670cfa4
--- /dev/null
+++ b/site/app/webroot/img/arr-prev.png
Binary files differ
diff --git a/site/app/webroot/img/arr-rtl-view.png b/site/app/webroot/img/arr-rtl-view.png
new file mode 100644
index 0000000..e78b555
--- /dev/null
+++ b/site/app/webroot/img/arr-rtl-view.png
Binary files differ
diff --git a/site/app/webroot/img/arr-view-big.png b/site/app/webroot/img/arr-view-big.png
new file mode 100644
index 0000000..11d1913
--- /dev/null
+++ b/site/app/webroot/img/arr-view-big.png
Binary files differ
diff --git a/site/app/webroot/img/arr-view-bigo.png b/site/app/webroot/img/arr-view-bigo.png
new file mode 100644
index 0000000..0e7fad6
--- /dev/null
+++ b/site/app/webroot/img/arr-view-bigo.png
Binary files differ
diff --git a/site/app/webroot/img/arr-view-o.png b/site/app/webroot/img/arr-view-o.png
new file mode 100644
index 0000000..6d26341
--- /dev/null
+++ b/site/app/webroot/img/arr-view-o.png
Binary files differ
diff --git a/site/app/webroot/img/arr-view-rtl-big.png b/site/app/webroot/img/arr-view-rtl-big.png
new file mode 100644
index 0000000..6c30078
--- /dev/null
+++ b/site/app/webroot/img/arr-view-rtl-big.png
Binary files differ
diff --git a/site/app/webroot/img/arr-view-rtl-bigo.png b/site/app/webroot/img/arr-view-rtl-bigo.png
new file mode 100644
index 0000000..8060aee
--- /dev/null
+++ b/site/app/webroot/img/arr-view-rtl-bigo.png
Binary files differ
diff --git a/site/app/webroot/img/arr-view-rtl-o.png b/site/app/webroot/img/arr-view-rtl-o.png
new file mode 100644
index 0000000..c3f1571
--- /dev/null
+++ b/site/app/webroot/img/arr-view-rtl-o.png
Binary files differ
diff --git a/site/app/webroot/img/arr-view.png b/site/app/webroot/img/arr-view.png
new file mode 100644
index 0000000..0d33057
--- /dev/null
+++ b/site/app/webroot/img/arr-view.png
Binary files differ
diff --git a/site/app/webroot/img/bigRss.png b/site/app/webroot/img/bigRss.png
new file mode 100644
index 0000000..ba0fde7
--- /dev/null
+++ b/site/app/webroot/img/bigRss.png
Binary files differ
diff --git a/site/app/webroot/img/box-pointer-top.png b/site/app/webroot/img/box-pointer-top.png
new file mode 100644
index 0000000..d7f451c
--- /dev/null
+++ b/site/app/webroot/img/box-pointer-top.png
Binary files differ
diff --git a/site/app/webroot/img/brandbanner-bg.png b/site/app/webroot/img/brandbanner-bg.png
new file mode 100644
index 0000000..278d4af
--- /dev/null
+++ b/site/app/webroot/img/brandbanner-bg.png
Binary files differ
diff --git a/site/app/webroot/img/build-icn.png b/site/app/webroot/img/build-icn.png
new file mode 100644
index 0000000..4314bf0
--- /dev/null
+++ b/site/app/webroot/img/build-icn.png
Binary files differ
diff --git a/site/app/webroot/img/buttonbg-dis.png b/site/app/webroot/img/buttonbg-dis.png
new file mode 100644
index 0000000..a94a0f2
--- /dev/null
+++ b/site/app/webroot/img/buttonbg-dis.png
Binary files differ
diff --git a/site/app/webroot/img/buttonbg-exp.png b/site/app/webroot/img/buttonbg-exp.png
new file mode 100644
index 0000000..d356a2c
--- /dev/null
+++ b/site/app/webroot/img/buttonbg-exp.png
Binary files differ
diff --git a/site/app/webroot/img/buttonbg-rec.png b/site/app/webroot/img/buttonbg-rec.png
new file mode 100644
index 0000000..51e95c1
--- /dev/null
+++ b/site/app/webroot/img/buttonbg-rec.png
Binary files differ
diff --git a/site/app/webroot/img/buttonbg-search.png b/site/app/webroot/img/buttonbg-search.png
new file mode 100644
index 0000000..ee4040f
--- /dev/null
+++ b/site/app/webroot/img/buttonbg-search.png
Binary files differ
diff --git a/site/app/webroot/img/buttonbg.png b/site/app/webroot/img/buttonbg.png
new file mode 100644
index 0000000..365a30c
--- /dev/null
+++ b/site/app/webroot/img/buttonbg.png
Binary files differ
diff --git a/site/app/webroot/img/cake.power.png b/site/app/webroot/img/cake.power.png
new file mode 100644
index 0000000..699ef80
--- /dev/null
+++ b/site/app/webroot/img/cake.power.png
Binary files differ
diff --git a/site/app/webroot/img/cat-link.png b/site/app/webroot/img/cat-link.png
new file mode 100644
index 0000000..ad68464
--- /dev/null
+++ b/site/app/webroot/img/cat-link.png
Binary files differ
diff --git a/site/app/webroot/img/cat-linkhover.png b/site/app/webroot/img/cat-linkhover.png
new file mode 100644
index 0000000..17e25a6
--- /dev/null
+++ b/site/app/webroot/img/cat-linkhover.png
Binary files differ
diff --git a/site/app/webroot/img/cathead-closed.png b/site/app/webroot/img/cathead-closed.png
new file mode 100644
index 0000000..bb4c460
--- /dev/null
+++ b/site/app/webroot/img/cathead-closed.png
Binary files differ
diff --git a/site/app/webroot/img/cathead-open.png b/site/app/webroot/img/cathead-open.png
new file mode 100644
index 0000000..6002850
--- /dev/null
+++ b/site/app/webroot/img/cathead-open.png
Binary files differ
diff --git a/site/app/webroot/img/cathead.png b/site/app/webroot/img/cathead.png
new file mode 100644
index 0000000..57cdc4c
--- /dev/null
+++ b/site/app/webroot/img/cathead.png
Binary files differ
diff --git a/site/app/webroot/img/collection.png b/site/app/webroot/img/collection.png
new file mode 100644
index 0000000..6525a90
--- /dev/null
+++ b/site/app/webroot/img/collection.png
Binary files differ
diff --git a/site/app/webroot/img/community.png b/site/app/webroot/img/community.png
new file mode 100644
index 0000000..11b18c9
--- /dev/null
+++ b/site/app/webroot/img/community.png
Binary files differ
diff --git a/site/app/webroot/img/default_icon.png b/site/app/webroot/img/default_icon.png
new file mode 100644
index 0000000..50cbbf1
--- /dev/null
+++ b/site/app/webroot/img/default_icon.png
Binary files differ
diff --git a/site/app/webroot/img/developers/actionbar/details.png b/site/app/webroot/img/developers/actionbar/details.png
new file mode 100755
index 0000000..abcd936
--- /dev/null
+++ b/site/app/webroot/img/developers/actionbar/details.png
Binary files differ
diff --git a/site/app/webroot/img/developers/actionbar/displaypage.png b/site/app/webroot/img/developers/actionbar/displaypage.png
new file mode 100755
index 0000000..c6ea7f2
--- /dev/null
+++ b/site/app/webroot/img/developers/actionbar/displaypage.png
Binary files differ
diff --git a/site/app/webroot/img/developers/actionbar/edit.png b/site/app/webroot/img/developers/actionbar/edit.png
new file mode 100755
index 0000000..b6cb0ec
--- /dev/null
+++ b/site/app/webroot/img/developers/actionbar/edit.png
Binary files differ
diff --git a/site/app/webroot/img/developers/actionbar/edit_addon.png b/site/app/webroot/img/developers/actionbar/edit_addon.png
new file mode 100755
index 0000000..b6cb0ec
--- /dev/null
+++ b/site/app/webroot/img/developers/actionbar/edit_addon.png
Binary files differ
diff --git a/site/app/webroot/img/developers/actionbar/edit_authors.png b/site/app/webroot/img/developers/actionbar/edit_authors.png
new file mode 100755
index 0000000..c88b945
--- /dev/null
+++ b/site/app/webroot/img/developers/actionbar/edit_authors.png
Binary files differ
diff --git a/site/app/webroot/img/developers/actionbar/edit_categories.png b/site/app/webroot/img/developers/actionbar/edit_categories.png
new file mode 100755
index 0000000..2a9f626
--- /dev/null
+++ b/site/app/webroot/img/developers/actionbar/edit_categories.png
Binary files differ
diff --git a/site/app/webroot/img/developers/actionbar/edit_descriptions.png b/site/app/webroot/img/developers/actionbar/edit_descriptions.png
new file mode 100755
index 0000000..291bfc7
--- /dev/null
+++ b/site/app/webroot/img/developers/actionbar/edit_descriptions.png
Binary files differ
diff --git a/site/app/webroot/img/developers/actionbar/edit_properties.png b/site/app/webroot/img/developers/actionbar/edit_properties.png
new file mode 100755
index 0000000..47b75a4
--- /dev/null
+++ b/site/app/webroot/img/developers/actionbar/edit_properties.png
Binary files differ
diff --git a/site/app/webroot/img/developers/actionbar/previews.png b/site/app/webroot/img/developers/actionbar/previews.png
new file mode 100755
index 0000000..184860d
--- /dev/null
+++ b/site/app/webroot/img/developers/actionbar/previews.png
Binary files differ
diff --git a/site/app/webroot/img/developers/actionbar/stats.png b/site/app/webroot/img/developers/actionbar/stats.png
new file mode 100755
index 0000000..01e933a
--- /dev/null
+++ b/site/app/webroot/img/developers/actionbar/stats.png
Binary files differ
diff --git a/site/app/webroot/img/developers/actionbar/status.png b/site/app/webroot/img/developers/actionbar/status.png
new file mode 100755
index 0000000..124c991
--- /dev/null
+++ b/site/app/webroot/img/developers/actionbar/status.png
Binary files differ
diff --git a/site/app/webroot/img/developers/actionbar/versions.png b/site/app/webroot/img/developers/actionbar/versions.png
new file mode 100755
index 0000000..41da991
--- /dev/null
+++ b/site/app/webroot/img/developers/actionbar/versions.png
Binary files differ
diff --git a/site/app/webroot/img/developers/actionbar/versions_add.png b/site/app/webroot/img/developers/actionbar/versions_add.png
new file mode 100755
index 0000000..ae43690
--- /dev/null
+++ b/site/app/webroot/img/developers/actionbar/versions_add.png
Binary files differ
diff --git a/site/app/webroot/img/developers/actionbar_add.png b/site/app/webroot/img/developers/actionbar_add.png
new file mode 100755
index 0000000..ae43690
--- /dev/null
+++ b/site/app/webroot/img/developers/actionbar_add.png
Binary files differ
diff --git a/site/app/webroot/img/developers/actionbar_detailed.png b/site/app/webroot/img/developers/actionbar_detailed.png
new file mode 100755
index 0000000..abcd936
--- /dev/null
+++ b/site/app/webroot/img/developers/actionbar_detailed.png
Binary files differ
diff --git a/site/app/webroot/img/developers/actionbar_disable.png b/site/app/webroot/img/developers/actionbar_disable.png
new file mode 100755
index 0000000..f4f6be5
--- /dev/null
+++ b/site/app/webroot/img/developers/actionbar_disable.png
Binary files differ
diff --git a/site/app/webroot/img/developers/actionbar_edit.png b/site/app/webroot/img/developers/actionbar_edit.png
new file mode 100755
index 0000000..b6cb0ec
--- /dev/null
+++ b/site/app/webroot/img/developers/actionbar_edit.png
Binary files differ
diff --git a/site/app/webroot/img/developers/actionbar_enable.png b/site/app/webroot/img/developers/actionbar_enable.png
new file mode 100755
index 0000000..6187b15
--- /dev/null
+++ b/site/app/webroot/img/developers/actionbar_enable.png
Binary files differ
diff --git a/site/app/webroot/img/developers/actionbar_nominate.png b/site/app/webroot/img/developers/actionbar_nominate.png
new file mode 100755
index 0000000..dcade0d
--- /dev/null
+++ b/site/app/webroot/img/developers/actionbar_nominate.png
Binary files differ
diff --git a/site/app/webroot/img/developers/actionbar_stats.png b/site/app/webroot/img/developers/actionbar_stats.png
new file mode 100755
index 0000000..01e933a
--- /dev/null
+++ b/site/app/webroot/img/developers/actionbar_stats.png
Binary files differ
diff --git a/site/app/webroot/img/developers/actionbar_viewpublic.png b/site/app/webroot/img/developers/actionbar_viewpublic.png
new file mode 100755
index 0000000..c6ea7f2
--- /dev/null
+++ b/site/app/webroot/img/developers/actionbar_viewpublic.png
Binary files differ
diff --git a/site/app/webroot/img/developers/add.png b/site/app/webroot/img/developers/add.png
new file mode 100644
index 0000000..6332fef
--- /dev/null
+++ b/site/app/webroot/img/developers/add.png
Binary files differ
diff --git a/site/app/webroot/img/developers/admin_review.png b/site/app/webroot/img/developers/admin_review.png
new file mode 100644
index 0000000..cff65d7
--- /dev/null
+++ b/site/app/webroot/img/developers/admin_review.png
Binary files differ
diff --git a/site/app/webroot/img/developers/arrow_down.png b/site/app/webroot/img/developers/arrow_down.png
new file mode 100755
index 0000000..2c4e279
--- /dev/null
+++ b/site/app/webroot/img/developers/arrow_down.png
Binary files differ
diff --git a/site/app/webroot/img/developers/arrow_up.png b/site/app/webroot/img/developers/arrow_up.png
new file mode 100755
index 0000000..1ebb193
--- /dev/null
+++ b/site/app/webroot/img/developers/arrow_up.png
Binary files differ
diff --git a/site/app/webroot/img/developers/asterisk_yellow.png b/site/app/webroot/img/developers/asterisk_yellow.png
new file mode 100755
index 0000000..bab7cc9
--- /dev/null
+++ b/site/app/webroot/img/developers/asterisk_yellow.png
Binary files differ
diff --git a/site/app/webroot/img/developers/cross.png b/site/app/webroot/img/developers/cross.png
new file mode 100755
index 0000000..1514d51
--- /dev/null
+++ b/site/app/webroot/img/developers/cross.png
Binary files differ
diff --git a/site/app/webroot/img/developers/delete.png b/site/app/webroot/img/developers/delete.png
new file mode 100644
index 0000000..08f2493
--- /dev/null
+++ b/site/app/webroot/img/developers/delete.png
Binary files differ
diff --git a/site/app/webroot/img/developers/edit.png b/site/app/webroot/img/developers/edit.png
new file mode 100755
index 0000000..0ec896f
--- /dev/null
+++ b/site/app/webroot/img/developers/edit.png
Binary files differ
diff --git a/site/app/webroot/img/developers/edit_authors_add.png b/site/app/webroot/img/developers/edit_authors_add.png
new file mode 100755
index 0000000..deae99b
--- /dev/null
+++ b/site/app/webroot/img/developers/edit_authors_add.png
Binary files differ
diff --git a/site/app/webroot/img/developers/edit_authors_delete.png b/site/app/webroot/img/developers/edit_authors_delete.png
new file mode 100755
index 0000000..acbb563
--- /dev/null
+++ b/site/app/webroot/img/developers/edit_authors_delete.png
Binary files differ
diff --git a/site/app/webroot/img/developers/exclamation.png b/site/app/webroot/img/developers/exclamation.png
new file mode 100755
index 0000000..c37bd06
--- /dev/null
+++ b/site/app/webroot/img/developers/exclamation.png
Binary files differ
diff --git a/site/app/webroot/img/developers/extension.png b/site/app/webroot/img/developers/extension.png
new file mode 100644
index 0000000..cb6ce8d
--- /dev/null
+++ b/site/app/webroot/img/developers/extension.png
Binary files differ
diff --git a/site/app/webroot/img/developers/firefox.png b/site/app/webroot/img/developers/firefox.png
new file mode 100644
index 0000000..ad62606
--- /dev/null
+++ b/site/app/webroot/img/developers/firefox.png
Binary files differ
diff --git a/site/app/webroot/img/developers/help.png b/site/app/webroot/img/developers/help.png
new file mode 100755
index 0000000..5c87017
--- /dev/null
+++ b/site/app/webroot/img/developers/help.png
Binary files differ
diff --git a/site/app/webroot/img/developers/history.png b/site/app/webroot/img/developers/history.png
new file mode 100755
index 0000000..0d2c9d6
--- /dev/null
+++ b/site/app/webroot/img/developers/history.png
Binary files differ
diff --git a/site/app/webroot/img/developers/homepage.png b/site/app/webroot/img/developers/homepage.png
new file mode 100755
index 0000000..94e01af
--- /dev/null
+++ b/site/app/webroot/img/developers/homepage.png
Binary files differ
diff --git a/site/app/webroot/img/developers/homepage_small.png b/site/app/webroot/img/developers/homepage_small.png
new file mode 100644
index 0000000..de7f7f5
--- /dev/null
+++ b/site/app/webroot/img/developers/homepage_small.png
Binary files differ
diff --git a/site/app/webroot/img/developers/info-bw.png b/site/app/webroot/img/developers/info-bw.png
new file mode 100644
index 0000000..ade8c8f
--- /dev/null
+++ b/site/app/webroot/img/developers/info-bw.png
Binary files differ
diff --git a/site/app/webroot/img/developers/info-color.png b/site/app/webroot/img/developers/info-color.png
new file mode 100644
index 0000000..1236c56
--- /dev/null
+++ b/site/app/webroot/img/developers/info-color.png
Binary files differ
diff --git a/site/app/webroot/img/developers/locale-background-hover.png b/site/app/webroot/img/developers/locale-background-hover.png
new file mode 100644
index 0000000..86c48ae
--- /dev/null
+++ b/site/app/webroot/img/developers/locale-background-hover.png
Binary files differ
diff --git a/site/app/webroot/img/developers/locale-background-selected.png b/site/app/webroot/img/developers/locale-background-selected.png
new file mode 100644
index 0000000..69d31f2
--- /dev/null
+++ b/site/app/webroot/img/developers/locale-background-selected.png
Binary files differ
diff --git a/site/app/webroot/img/developers/locale-background.png b/site/app/webroot/img/developers/locale-background.png
new file mode 100644
index 0000000..80a3b19
--- /dev/null
+++ b/site/app/webroot/img/developers/locale-background.png
Binary files differ
diff --git a/site/app/webroot/img/developers/mozilla.png b/site/app/webroot/img/developers/mozilla.png
new file mode 100644
index 0000000..bbe7e98
--- /dev/null
+++ b/site/app/webroot/img/developers/mozilla.png
Binary files differ
diff --git a/site/app/webroot/img/developers/new.png b/site/app/webroot/img/developers/new.png
new file mode 100644
index 0000000..3744c3f
--- /dev/null
+++ b/site/app/webroot/img/developers/new.png
Binary files differ
diff --git a/site/app/webroot/img/developers/noscript.png b/site/app/webroot/img/developers/noscript.png
new file mode 100755
index 0000000..0491954
--- /dev/null
+++ b/site/app/webroot/img/developers/noscript.png
Binary files differ
diff --git a/site/app/webroot/img/developers/overview.png b/site/app/webroot/img/developers/overview.png
new file mode 100755
index 0000000..1c79230
--- /dev/null
+++ b/site/app/webroot/img/developers/overview.png
Binary files differ
diff --git a/site/app/webroot/img/developers/pencil.png b/site/app/webroot/img/developers/pencil.png
new file mode 100755
index 0000000..0bfecd5
--- /dev/null
+++ b/site/app/webroot/img/developers/pencil.png
Binary files differ
diff --git a/site/app/webroot/img/developers/preview_add.png b/site/app/webroot/img/developers/preview_add.png
new file mode 100755
index 0000000..fc5d613
--- /dev/null
+++ b/site/app/webroot/img/developers/preview_add.png
Binary files differ
diff --git a/site/app/webroot/img/developers/preview_delete.png b/site/app/webroot/img/developers/preview_delete.png
new file mode 100755
index 0000000..c260e1d
--- /dev/null
+++ b/site/app/webroot/img/developers/preview_delete.png
Binary files differ
diff --git a/site/app/webroot/img/developers/preview_edit.png b/site/app/webroot/img/developers/preview_edit.png
new file mode 100755
index 0000000..0aa4cc6
--- /dev/null
+++ b/site/app/webroot/img/developers/preview_edit.png
Binary files differ
diff --git a/site/app/webroot/img/developers/previews.png b/site/app/webroot/img/developers/previews.png
new file mode 100755
index 0000000..5a1bd5b
--- /dev/null
+++ b/site/app/webroot/img/developers/previews.png
Binary files differ
diff --git a/site/app/webroot/img/developers/privileges.png b/site/app/webroot/img/developers/privileges.png
new file mode 100755
index 0000000..4ec1a92
--- /dev/null
+++ b/site/app/webroot/img/developers/privileges.png
Binary files differ
diff --git a/site/app/webroot/img/developers/public-bw.png b/site/app/webroot/img/developers/public-bw.png
new file mode 100755
index 0000000..5358c73
--- /dev/null
+++ b/site/app/webroot/img/developers/public-bw.png
Binary files differ
diff --git a/site/app/webroot/img/developers/public-color.png b/site/app/webroot/img/developers/public-color.png
new file mode 100755
index 0000000..8b51d3d
--- /dev/null
+++ b/site/app/webroot/img/developers/public-color.png
Binary files differ
diff --git a/site/app/webroot/img/developers/sandbox-bw.png b/site/app/webroot/img/developers/sandbox-bw.png
new file mode 100755
index 0000000..22b7ecd
--- /dev/null
+++ b/site/app/webroot/img/developers/sandbox-bw.png
Binary files differ
diff --git a/site/app/webroot/img/developers/sandbox-color.png b/site/app/webroot/img/developers/sandbox-color.png
new file mode 100755
index 0000000..a6e1254
--- /dev/null
+++ b/site/app/webroot/img/developers/sandbox-color.png
Binary files differ
diff --git a/site/app/webroot/img/developers/seamonkey.png b/site/app/webroot/img/developers/seamonkey.png
new file mode 100644
index 0000000..3f5c112
--- /dev/null
+++ b/site/app/webroot/img/developers/seamonkey.png
Binary files differ
diff --git a/site/app/webroot/img/developers/sort-asc.gif b/site/app/webroot/img/developers/sort-asc.gif
new file mode 100644
index 0000000..7415786
--- /dev/null
+++ b/site/app/webroot/img/developers/sort-asc.gif
Binary files differ
diff --git a/site/app/webroot/img/developers/sort-bg.gif b/site/app/webroot/img/developers/sort-bg.gif
new file mode 100644
index 0000000..fac668f
--- /dev/null
+++ b/site/app/webroot/img/developers/sort-bg.gif
Binary files differ
diff --git a/site/app/webroot/img/developers/sort-desc.gif b/site/app/webroot/img/developers/sort-desc.gif
new file mode 100644
index 0000000..3b30b3c
--- /dev/null
+++ b/site/app/webroot/img/developers/sort-desc.gif
Binary files differ
diff --git a/site/app/webroot/img/developers/spacer.png b/site/app/webroot/img/developers/spacer.png
new file mode 100644
index 0000000..3b69954
--- /dev/null
+++ b/site/app/webroot/img/developers/spacer.png
Binary files differ
diff --git a/site/app/webroot/img/developers/status_active.png b/site/app/webroot/img/developers/status_active.png
new file mode 100755
index 0000000..6187b15
--- /dev/null
+++ b/site/app/webroot/img/developers/status_active.png
Binary files differ
diff --git a/site/app/webroot/img/developers/status_inactive.png b/site/app/webroot/img/developers/status_inactive.png
new file mode 100755
index 0000000..f4f6be5
--- /dev/null
+++ b/site/app/webroot/img/developers/status_inactive.png
Binary files differ
diff --git a/site/app/webroot/img/developers/status_nominate.png b/site/app/webroot/img/developers/status_nominate.png
new file mode 100755
index 0000000..dcade0d
--- /dev/null
+++ b/site/app/webroot/img/developers/status_nominate.png
Binary files differ
diff --git a/site/app/webroot/img/developers/sunbird.png b/site/app/webroot/img/developers/sunbird.png
new file mode 100644
index 0000000..a86263d
--- /dev/null
+++ b/site/app/webroot/img/developers/sunbird.png
Binary files differ
diff --git a/site/app/webroot/img/developers/superreview-bw.png b/site/app/webroot/img/developers/superreview-bw.png
new file mode 100755
index 0000000..a86fc42
--- /dev/null
+++ b/site/app/webroot/img/developers/superreview-bw.png
Binary files differ
diff --git a/site/app/webroot/img/developers/superreview-color.png b/site/app/webroot/img/developers/superreview-color.png
new file mode 100755
index 0000000..c626925
--- /dev/null
+++ b/site/app/webroot/img/developers/superreview-color.png
Binary files differ
diff --git a/site/app/webroot/img/developers/tab_add.png b/site/app/webroot/img/developers/tab_add.png
new file mode 100755
index 0000000..d3b9936
--- /dev/null
+++ b/site/app/webroot/img/developers/tab_add.png
Binary files differ
diff --git a/site/app/webroot/img/developers/tab_delete.png b/site/app/webroot/img/developers/tab_delete.png
new file mode 100755
index 0000000..100da2f
--- /dev/null
+++ b/site/app/webroot/img/developers/tab_delete.png
Binary files differ
diff --git a/site/app/webroot/img/developers/theme.png b/site/app/webroot/img/developers/theme.png
new file mode 100644
index 0000000..1d8c4c3
--- /dev/null
+++ b/site/app/webroot/img/developers/theme.png
Binary files differ
diff --git a/site/app/webroot/img/developers/thunderbird.png b/site/app/webroot/img/developers/thunderbird.png
new file mode 100644
index 0000000..7a43c1d
--- /dev/null
+++ b/site/app/webroot/img/developers/thunderbird.png
Binary files differ
diff --git a/site/app/webroot/img/developers/tick.png b/site/app/webroot/img/developers/tick.png
new file mode 100755
index 0000000..a9925a0
--- /dev/null
+++ b/site/app/webroot/img/developers/tick.png
Binary files differ
diff --git a/site/app/webroot/img/developers/update.png b/site/app/webroot/img/developers/update.png
new file mode 100644
index 0000000..f833434
--- /dev/null
+++ b/site/app/webroot/img/developers/update.png
Binary files differ
diff --git a/site/app/webroot/img/developers/versions_compat_add.png b/site/app/webroot/img/developers/versions_compat_add.png
new file mode 100755
index 0000000..28c2175
--- /dev/null
+++ b/site/app/webroot/img/developers/versions_compat_add.png
Binary files differ
diff --git a/site/app/webroot/img/developers/versions_compat_remove.png b/site/app/webroot/img/developers/versions_compat_remove.png
new file mode 100755
index 0000000..cd305ec
--- /dev/null
+++ b/site/app/webroot/img/developers/versions_compat_remove.png
Binary files differ
diff --git a/site/app/webroot/img/developers/versions_delete.png b/site/app/webroot/img/developers/versions_delete.png
new file mode 100755
index 0000000..d9c3376
--- /dev/null
+++ b/site/app/webroot/img/developers/versions_delete.png
Binary files differ
diff --git a/site/app/webroot/img/developers/versions_link.png b/site/app/webroot/img/developers/versions_link.png
new file mode 100755
index 0000000..445c188
--- /dev/null
+++ b/site/app/webroot/img/developers/versions_link.png
Binary files differ
diff --git a/site/app/webroot/img/divider.gif b/site/app/webroot/img/divider.gif
new file mode 100644
index 0000000..d6250d4
--- /dev/null
+++ b/site/app/webroot/img/divider.gif
Binary files differ
diff --git a/site/app/webroot/img/download.gif b/site/app/webroot/img/download.gif
new file mode 100644
index 0000000..0c68d5b
--- /dev/null
+++ b/site/app/webroot/img/download.gif
Binary files differ
diff --git a/site/app/webroot/img/edit.png b/site/app/webroot/img/edit.png
new file mode 100755
index 0000000..0ec896f
--- /dev/null
+++ b/site/app/webroot/img/edit.png
Binary files differ
diff --git a/site/app/webroot/img/email.gif b/site/app/webroot/img/email.gif
new file mode 100644
index 0000000..2bc4fd0
--- /dev/null
+++ b/site/app/webroot/img/email.gif
Binary files differ
diff --git a/site/app/webroot/img/exp-bl.png b/site/app/webroot/img/exp-bl.png
new file mode 100644
index 0000000..442386c
--- /dev/null
+++ b/site/app/webroot/img/exp-bl.png
Binary files differ
diff --git a/site/app/webroot/img/exp-br.png b/site/app/webroot/img/exp-br.png
new file mode 100644
index 0000000..5c0e758
--- /dev/null
+++ b/site/app/webroot/img/exp-br.png
Binary files differ
diff --git a/site/app/webroot/img/exp-flag.png b/site/app/webroot/img/exp-flag.png
new file mode 100644
index 0000000..3e792c7
--- /dev/null
+++ b/site/app/webroot/img/exp-flag.png
Binary files differ
diff --git a/site/app/webroot/img/exp-tl.png b/site/app/webroot/img/exp-tl.png
new file mode 100644
index 0000000..062dd6e
--- /dev/null
+++ b/site/app/webroot/img/exp-tl.png
Binary files differ
diff --git a/site/app/webroot/img/exp-tr.png b/site/app/webroot/img/exp-tr.png
new file mode 100644
index 0000000..b41540d
--- /dev/null
+++ b/site/app/webroot/img/exp-tr.png
Binary files differ
diff --git a/site/app/webroot/img/extendfirefox/extendfirefox-large.jpg b/site/app/webroot/img/extendfirefox/extendfirefox-large.jpg
new file mode 100644
index 0000000..d5d8814
--- /dev/null
+++ b/site/app/webroot/img/extendfirefox/extendfirefox-large.jpg
Binary files differ
diff --git a/site/app/webroot/img/extendfirefox/extendfirefox-small.jpg b/site/app/webroot/img/extendfirefox/extendfirefox-small.jpg
new file mode 100644
index 0000000..e073dbc
--- /dev/null
+++ b/site/app/webroot/img/extendfirefox/extendfirefox-small.jpg
Binary files differ
diff --git a/site/app/webroot/img/extendfirefox/extendfirefox3.png b/site/app/webroot/img/extendfirefox/extendfirefox3.png
new file mode 100644
index 0000000..b47e191
--- /dev/null
+++ b/site/app/webroot/img/extendfirefox/extendfirefox3.png
Binary files differ
diff --git a/site/app/webroot/img/extension.png b/site/app/webroot/img/extension.png
new file mode 100755
index 0000000..50cbbf1
--- /dev/null
+++ b/site/app/webroot/img/extension.png
Binary files differ
diff --git a/site/app/webroot/img/facebook/confirm_button.gif b/site/app/webroot/img/facebook/confirm_button.gif
new file mode 100644
index 0000000..fa75502
--- /dev/null
+++ b/site/app/webroot/img/facebook/confirm_button.gif
Binary files differ
diff --git a/site/app/webroot/img/facebook/confirm_button_active.gif b/site/app/webroot/img/facebook/confirm_button_active.gif
new file mode 100644
index 0000000..e06a24c
--- /dev/null
+++ b/site/app/webroot/img/facebook/confirm_button_active.gif
Binary files differ
diff --git a/site/app/webroot/img/facebook/confirm_button_extension.gif b/site/app/webroot/img/facebook/confirm_button_extension.gif
new file mode 100644
index 0000000..8e5f832
--- /dev/null
+++ b/site/app/webroot/img/facebook/confirm_button_extension.gif
Binary files differ
diff --git a/site/app/webroot/img/facebook/detect-step1.png b/site/app/webroot/img/facebook/detect-step1.png
new file mode 100644
index 0000000..87c84f0
--- /dev/null
+++ b/site/app/webroot/img/facebook/detect-step1.png
Binary files differ
diff --git a/site/app/webroot/img/facebook/detect-step2.png b/site/app/webroot/img/facebook/detect-step2.png
new file mode 100644
index 0000000..56de6f1
--- /dev/null
+++ b/site/app/webroot/img/facebook/detect-step2.png
Binary files differ
diff --git a/site/app/webroot/img/facebook/facebook_header.png b/site/app/webroot/img/facebook/facebook_header.png
new file mode 100644
index 0000000..58fb72f
--- /dev/null
+++ b/site/app/webroot/img/facebook/facebook_header.png
Binary files differ
diff --git a/site/app/webroot/img/facebook/icon_remove.gif b/site/app/webroot/img/facebook/icon_remove.gif
new file mode 100644
index 0000000..c542749
--- /dev/null
+++ b/site/app/webroot/img/facebook/icon_remove.gif
Binary files differ
diff --git a/site/app/webroot/img/facebook/medal.png b/site/app/webroot/img/facebook/medal.png
new file mode 100644
index 0000000..1917323
--- /dev/null
+++ b/site/app/webroot/img/facebook/medal.png
Binary files differ
diff --git a/site/app/webroot/img/facebook/new_media_button.gif b/site/app/webroot/img/facebook/new_media_button.gif
new file mode 100644
index 0000000..d5d5a03
--- /dev/null
+++ b/site/app/webroot/img/facebook/new_media_button.gif
Binary files differ
diff --git a/site/app/webroot/img/facebook/new_media_button_active.gif b/site/app/webroot/img/facebook/new_media_button_active.gif
new file mode 100644
index 0000000..eace4ed
--- /dev/null
+++ b/site/app/webroot/img/facebook/new_media_button_active.gif
Binary files differ
diff --git a/site/app/webroot/img/facebook/new_media_button_plus.gif b/site/app/webroot/img/facebook/new_media_button_plus.gif
new file mode 100644
index 0000000..ed9f2c4
--- /dev/null
+++ b/site/app/webroot/img/facebook/new_media_button_plus.gif
Binary files differ
diff --git a/site/app/webroot/img/facebook/newsfeed/addedfavorite.png b/site/app/webroot/img/facebook/newsfeed/addedfavorite.png
new file mode 100644
index 0000000..6fcb706
--- /dev/null
+++ b/site/app/webroot/img/facebook/newsfeed/addedfavorite.png
Binary files differ
diff --git a/site/app/webroot/img/facebook/newsfeed/extension.png b/site/app/webroot/img/facebook/newsfeed/extension.png
new file mode 100755
index 0000000..cb6ce8d
--- /dev/null
+++ b/site/app/webroot/img/facebook/newsfeed/extension.png
Binary files differ
diff --git a/site/app/webroot/img/facebook/newsfeed/lightning.png b/site/app/webroot/img/facebook/newsfeed/lightning.png
new file mode 100755
index 0000000..9680afd
--- /dev/null
+++ b/site/app/webroot/img/facebook/newsfeed/lightning.png
Binary files differ
diff --git a/site/app/webroot/img/facebook/newsfeed/newversion.png b/site/app/webroot/img/facebook/newsfeed/newversion.png
new file mode 100644
index 0000000..f7a4c8e
--- /dev/null
+++ b/site/app/webroot/img/facebook/newsfeed/newversion.png
Binary files differ
diff --git a/site/app/webroot/img/facebook/newsfeed/recommendation.png b/site/app/webroot/img/facebook/newsfeed/recommendation.png
new file mode 100644
index 0000000..8fb45c0
--- /dev/null
+++ b/site/app/webroot/img/facebook/newsfeed/recommendation.png
Binary files differ
diff --git a/site/app/webroot/img/facebook/no-preview-thumb.png b/site/app/webroot/img/facebook/no-preview-thumb.png
new file mode 100644
index 0000000..daa308a
--- /dev/null
+++ b/site/app/webroot/img/facebook/no-preview-thumb.png
Binary files differ
diff --git a/site/app/webroot/img/facebook/no-preview.png b/site/app/webroot/img/facebook/no-preview.png
new file mode 100644
index 0000000..3a631ce
--- /dev/null
+++ b/site/app/webroot/img/facebook/no-preview.png
Binary files differ
diff --git a/site/app/webroot/img/facebook/non-firefox-box.png b/site/app/webroot/img/facebook/non-firefox-box.png
new file mode 100644
index 0000000..62bc35e
--- /dev/null
+++ b/site/app/webroot/img/facebook/non-firefox-box.png
Binary files differ
diff --git a/site/app/webroot/img/facebook/outage.png b/site/app/webroot/img/facebook/outage.png
new file mode 100644
index 0000000..5f3b334
--- /dev/null
+++ b/site/app/webroot/img/facebook/outage.png
Binary files differ
diff --git a/site/app/webroot/img/facebook/rockyourfirefox-75x70.png b/site/app/webroot/img/facebook/rockyourfirefox-75x70.png
new file mode 100644
index 0000000..3d2952e
--- /dev/null
+++ b/site/app/webroot/img/facebook/rockyourfirefox-75x70.png
Binary files differ
diff --git a/site/app/webroot/img/facebook/rockyourfirefox-header.png b/site/app/webroot/img/facebook/rockyourfirefox-header.png
new file mode 100644
index 0000000..478f876
--- /dev/null
+++ b/site/app/webroot/img/facebook/rockyourfirefox-header.png
Binary files differ
diff --git a/site/app/webroot/img/facebook/rockyourfirefox-intro.png b/site/app/webroot/img/facebook/rockyourfirefox-intro.png
new file mode 100644
index 0000000..18618d9
--- /dev/null
+++ b/site/app/webroot/img/facebook/rockyourfirefox-intro.png
Binary files differ
diff --git a/site/app/webroot/img/facebook/smallMedal.png b/site/app/webroot/img/facebook/smallMedal.png
new file mode 100644
index 0000000..a5a5f72
--- /dev/null
+++ b/site/app/webroot/img/facebook/smallMedal.png
Binary files differ
diff --git a/site/app/webroot/img/facebook/wallpaper/rock_firefox_1024x768.jpg b/site/app/webroot/img/facebook/wallpaper/rock_firefox_1024x768.jpg
new file mode 100644
index 0000000..cbd8ad4
--- /dev/null
+++ b/site/app/webroot/img/facebook/wallpaper/rock_firefox_1024x768.jpg
Binary files differ
diff --git a/site/app/webroot/img/facebook/wallpaper/rock_firefox_1280x1024.jpg b/site/app/webroot/img/facebook/wallpaper/rock_firefox_1280x1024.jpg
new file mode 100644
index 0000000..bc96692
--- /dev/null
+++ b/site/app/webroot/img/facebook/wallpaper/rock_firefox_1280x1024.jpg
Binary files differ
diff --git a/site/app/webroot/img/facebook/wallpaper/rock_firefox_1440x900.jpg b/site/app/webroot/img/facebook/wallpaper/rock_firefox_1440x900.jpg
new file mode 100644
index 0000000..b9f7895
--- /dev/null
+++ b/site/app/webroot/img/facebook/wallpaper/rock_firefox_1440x900.jpg
Binary files differ
diff --git a/site/app/webroot/img/facebook/wallpaper/rock_firefox_1680x1050.jpg b/site/app/webroot/img/facebook/wallpaper/rock_firefox_1680x1050.jpg
new file mode 100644
index 0000000..1a2dea8
--- /dev/null
+++ b/site/app/webroot/img/facebook/wallpaper/rock_firefox_1680x1050.jpg
Binary files differ
diff --git a/site/app/webroot/img/facebook/wallpaper/rock_firefox_1920x1200.jpg b/site/app/webroot/img/facebook/wallpaper/rock_firefox_1920x1200.jpg
new file mode 100644
index 0000000..453401c
--- /dev/null
+++ b/site/app/webroot/img/facebook/wallpaper/rock_firefox_1920x1200.jpg
Binary files differ
diff --git a/site/app/webroot/img/facebook/wallpaper/rock_firefox_800x600.jpg b/site/app/webroot/img/facebook/wallpaper/rock_firefox_800x600.jpg
new file mode 100644
index 0000000..8cc8199
--- /dev/null
+++ b/site/app/webroot/img/facebook/wallpaper/rock_firefox_800x600.jpg
Binary files differ
diff --git a/site/app/webroot/img/facebook/wallpaper/rock_firefox_preview.png b/site/app/webroot/img/facebook/wallpaper/rock_firefox_preview.png
new file mode 100644
index 0000000..84921f3
--- /dev/null
+++ b/site/app/webroot/img/facebook/wallpaper/rock_firefox_preview.png
Binary files differ
diff --git a/site/app/webroot/img/farmer.gif b/site/app/webroot/img/farmer.gif
new file mode 100644
index 0000000..53fa41f
--- /dev/null
+++ b/site/app/webroot/img/farmer.gif
Binary files differ
diff --git a/site/app/webroot/img/farmer.png b/site/app/webroot/img/farmer.png
new file mode 100644
index 0000000..a3fd1b3
--- /dev/null
+++ b/site/app/webroot/img/farmer.png
Binary files differ
diff --git a/site/app/webroot/img/farming_slice.png b/site/app/webroot/img/farming_slice.png
new file mode 100644
index 0000000..a3a0d33
--- /dev/null
+++ b/site/app/webroot/img/farming_slice.png
Binary files differ
diff --git a/site/app/webroot/img/farming_thumb1.gif b/site/app/webroot/img/farming_thumb1.gif
new file mode 100644
index 0000000..0057c8f
--- /dev/null
+++ b/site/app/webroot/img/farming_thumb1.gif
Binary files differ
diff --git a/site/app/webroot/img/farming_thumb1.png b/site/app/webroot/img/farming_thumb1.png
new file mode 100644
index 0000000..ae95f6e
--- /dev/null
+++ b/site/app/webroot/img/farming_thumb1.png
Binary files differ
diff --git a/site/app/webroot/img/favicon.ico b/site/app/webroot/img/favicon.ico
new file mode 100644
index 0000000..c85a481
--- /dev/null
+++ b/site/app/webroot/img/favicon.ico
Binary files differ
diff --git a/site/app/webroot/img/favicons/delicious.gif b/site/app/webroot/img/favicons/delicious.gif
new file mode 100644
index 0000000..a136dd1
--- /dev/null
+++ b/site/app/webroot/img/favicons/delicious.gif
Binary files differ
diff --git a/site/app/webroot/img/favicons/digg.gif b/site/app/webroot/img/favicons/digg.gif
new file mode 100644
index 0000000..089f4f2
--- /dev/null
+++ b/site/app/webroot/img/favicons/digg.gif
Binary files differ
diff --git a/site/app/webroot/img/favicons/facebook.gif b/site/app/webroot/img/favicons/facebook.gif
new file mode 100644
index 0000000..90a8e02
--- /dev/null
+++ b/site/app/webroot/img/favicons/facebook.gif
Binary files differ
diff --git a/site/app/webroot/img/favicons/friendfeed.gif b/site/app/webroot/img/favicons/friendfeed.gif
new file mode 100644
index 0000000..edcc727
--- /dev/null
+++ b/site/app/webroot/img/favicons/friendfeed.gif
Binary files differ
diff --git a/site/app/webroot/img/favicons/myspace.gif b/site/app/webroot/img/favicons/myspace.gif
new file mode 100644
index 0000000..8e56437
--- /dev/null
+++ b/site/app/webroot/img/favicons/myspace.gif
Binary files differ
diff --git a/site/app/webroot/img/favicons/reddit.gif b/site/app/webroot/img/favicons/reddit.gif
new file mode 100644
index 0000000..8a4963f
--- /dev/null
+++ b/site/app/webroot/img/favicons/reddit.gif
Binary files differ
diff --git a/site/app/webroot/img/featured-bg.png b/site/app/webroot/img/featured-bg.png
new file mode 100644
index 0000000..6147842
--- /dev/null
+++ b/site/app/webroot/img/featured-bg.png
Binary files differ
diff --git a/site/app/webroot/img/foot-bg.png b/site/app/webroot/img/foot-bg.png
new file mode 100644
index 0000000..df8ff3f
--- /dev/null
+++ b/site/app/webroot/img/foot-bg.png
Binary files differ
diff --git a/site/app/webroot/img/footer.gif b/site/app/webroot/img/footer.gif
new file mode 100644
index 0000000..2799b45
--- /dev/null
+++ b/site/app/webroot/img/footer.gif
Binary files differ
diff --git a/site/app/webroot/img/fyf/addonguy-head.png b/site/app/webroot/img/fyf/addonguy-head.png
new file mode 100644
index 0000000..8da5bb1
--- /dev/null
+++ b/site/app/webroot/img/fyf/addonguy-head.png
Binary files differ
diff --git a/site/app/webroot/img/fyf/addonguy-large.png b/site/app/webroot/img/fyf/addonguy-large.png
new file mode 100644
index 0000000..08a100f
--- /dev/null
+++ b/site/app/webroot/img/fyf/addonguy-large.png
Binary files differ
diff --git a/site/app/webroot/img/fyf/addonguy-success.png b/site/app/webroot/img/fyf/addonguy-success.png
new file mode 100644
index 0000000..c8646d4
--- /dev/null
+++ b/site/app/webroot/img/fyf/addonguy-success.png
Binary files differ
diff --git a/site/app/webroot/img/fyf/addonguy.png b/site/app/webroot/img/fyf/addonguy.png
new file mode 100644
index 0000000..e5d8825
--- /dev/null
+++ b/site/app/webroot/img/fyf/addonguy.png
Binary files differ
diff --git a/site/app/webroot/img/fyf/bg.png b/site/app/webroot/img/fyf/bg.png
new file mode 100644
index 0000000..0f05d8e
--- /dev/null
+++ b/site/app/webroot/img/fyf/bg.png
Binary files differ
diff --git a/site/app/webroot/img/fyf/collection-bg.png b/site/app/webroot/img/fyf/collection-bg.png
new file mode 100644
index 0000000..7e05552
--- /dev/null
+++ b/site/app/webroot/img/fyf/collection-bg.png
Binary files differ
diff --git a/site/app/webroot/img/fyf/collection-bg2.png b/site/app/webroot/img/fyf/collection-bg2.png
new file mode 100644
index 0000000..a849dff
--- /dev/null
+++ b/site/app/webroot/img/fyf/collection-bg2.png
Binary files differ
diff --git a/site/app/webroot/img/fyf/faq_header.png b/site/app/webroot/img/fyf/faq_header.png
new file mode 100644
index 0000000..7a47aba
--- /dev/null
+++ b/site/app/webroot/img/fyf/faq_header.png
Binary files differ
diff --git a/site/app/webroot/img/fyf/faq_subheader.png b/site/app/webroot/img/fyf/faq_subheader.png
new file mode 100644
index 0000000..afe7efc
--- /dev/null
+++ b/site/app/webroot/img/fyf/faq_subheader.png
Binary files differ
diff --git a/site/app/webroot/img/fyf/fashioned.png b/site/app/webroot/img/fyf/fashioned.png
new file mode 100644
index 0000000..30f1b45
--- /dev/null
+++ b/site/app/webroot/img/fyf/fashioned.png
Binary files differ
diff --git a/site/app/webroot/img/fyf/footer-bg.png b/site/app/webroot/img/fyf/footer-bg.png
new file mode 100644
index 0000000..73489b2
--- /dev/null
+++ b/site/app/webroot/img/fyf/footer-bg.png
Binary files differ
diff --git a/site/app/webroot/img/fyf/fyf_header.png b/site/app/webroot/img/fyf/fyf_header.png
new file mode 100644
index 0000000..c8e889f
--- /dev/null
+++ b/site/app/webroot/img/fyf/fyf_header.png
Binary files differ
diff --git a/site/app/webroot/img/fyf/installbtn-bg.png b/site/app/webroot/img/fyf/installbtn-bg.png
new file mode 100644
index 0000000..3063fd3
--- /dev/null
+++ b/site/app/webroot/img/fyf/installbtn-bg.png
Binary files differ
diff --git a/site/app/webroot/img/fyf/installsubmit.png b/site/app/webroot/img/fyf/installsubmit.png
new file mode 100644
index 0000000..72d4596
--- /dev/null
+++ b/site/app/webroot/img/fyf/installsubmit.png
Binary files differ
diff --git a/site/app/webroot/img/fyf/triangle-down.png b/site/app/webroot/img/fyf/triangle-down.png
new file mode 100644
index 0000000..31e472d
--- /dev/null
+++ b/site/app/webroot/img/fyf/triangle-down.png
Binary files differ
diff --git a/site/app/webroot/img/fyf/triangle-right.png b/site/app/webroot/img/fyf/triangle-right.png
new file mode 100644
index 0000000..4336197
--- /dev/null
+++ b/site/app/webroot/img/fyf/triangle-right.png
Binary files differ
diff --git a/site/app/webroot/img/gear.png b/site/app/webroot/img/gear.png
new file mode 100644
index 0000000..cb37155
--- /dev/null
+++ b/site/app/webroot/img/gear.png
Binary files differ
diff --git a/site/app/webroot/img/gearwrench.png b/site/app/webroot/img/gearwrench.png
new file mode 100644
index 0000000..4489001
--- /dev/null
+++ b/site/app/webroot/img/gearwrench.png
Binary files differ
diff --git a/site/app/webroot/img/header.jpg b/site/app/webroot/img/header.jpg
new file mode 100644
index 0000000..8369da0
--- /dev/null
+++ b/site/app/webroot/img/header.jpg
Binary files differ
diff --git a/site/app/webroot/img/icn-collapse.png b/site/app/webroot/img/icn-collapse.png
new file mode 100644
index 0000000..3182e4c
--- /dev/null
+++ b/site/app/webroot/img/icn-collapse.png
Binary files differ
diff --git a/site/app/webroot/img/icn-expand.png b/site/app/webroot/img/icn-expand.png
new file mode 100644
index 0000000..d39cf5b
--- /dev/null
+++ b/site/app/webroot/img/icn-expand.png
Binary files differ
diff --git a/site/app/webroot/img/install-button-dis.png b/site/app/webroot/img/install-button-dis.png
new file mode 100644
index 0000000..7e1d0bd
--- /dev/null
+++ b/site/app/webroot/img/install-button-dis.png
Binary files differ
diff --git a/site/app/webroot/img/install-button-exp.png b/site/app/webroot/img/install-button-exp.png
new file mode 100644
index 0000000..b7b7422
--- /dev/null
+++ b/site/app/webroot/img/install-button-exp.png
Binary files differ
diff --git a/site/app/webroot/img/install-button-rec.png b/site/app/webroot/img/install-button-rec.png
new file mode 100644
index 0000000..c52b4c9
--- /dev/null
+++ b/site/app/webroot/img/install-button-rec.png
Binary files differ
diff --git a/site/app/webroot/img/install-button-search.png b/site/app/webroot/img/install-button-search.png
new file mode 100644
index 0000000..9e0df41
--- /dev/null
+++ b/site/app/webroot/img/install-button-search.png
Binary files differ
diff --git a/site/app/webroot/img/install-button.png b/site/app/webroot/img/install-button.png
new file mode 100644
index 0000000..9bab8c0
--- /dev/null
+++ b/site/app/webroot/img/install-button.png
Binary files differ
diff --git a/site/app/webroot/img/install.gif b/site/app/webroot/img/install.gif
new file mode 100644
index 0000000..525e0f7
--- /dev/null
+++ b/site/app/webroot/img/install.gif
Binary files differ
diff --git a/site/app/webroot/img/installbtn-bg-dis.png b/site/app/webroot/img/installbtn-bg-dis.png
new file mode 100644
index 0000000..e1ab85a
--- /dev/null
+++ b/site/app/webroot/img/installbtn-bg-dis.png
Binary files differ
diff --git a/site/app/webroot/img/installbtn-bg.png b/site/app/webroot/img/installbtn-bg.png
new file mode 100644
index 0000000..3063fd3
--- /dev/null
+++ b/site/app/webroot/img/installbtn-bg.png
Binary files differ
diff --git a/site/app/webroot/img/installbtn-edges-dis.png b/site/app/webroot/img/installbtn-edges-dis.png
new file mode 100644
index 0000000..d14a50e
--- /dev/null
+++ b/site/app/webroot/img/installbtn-edges-dis.png
Binary files differ
diff --git a/site/app/webroot/img/installbtn-edges-exp.png b/site/app/webroot/img/installbtn-edges-exp.png
new file mode 100644
index 0000000..63bce42
--- /dev/null
+++ b/site/app/webroot/img/installbtn-edges-exp.png
Binary files differ
diff --git a/site/app/webroot/img/installbtn-edges-list.png b/site/app/webroot/img/installbtn-edges-list.png
new file mode 100644
index 0000000..7b01e82
--- /dev/null
+++ b/site/app/webroot/img/installbtn-edges-list.png
Binary files differ
diff --git a/site/app/webroot/img/installbtn-edges-rec.png b/site/app/webroot/img/installbtn-edges-rec.png
new file mode 100644
index 0000000..f1a3fae
--- /dev/null
+++ b/site/app/webroot/img/installbtn-edges-rec.png
Binary files differ
diff --git a/site/app/webroot/img/installbtn-edges-search.png b/site/app/webroot/img/installbtn-edges-search.png
new file mode 100644
index 0000000..559f136
--- /dev/null
+++ b/site/app/webroot/img/installbtn-edges-search.png
Binary files differ
diff --git a/site/app/webroot/img/installbtn-edges.png b/site/app/webroot/img/installbtn-edges.png
new file mode 100644
index 0000000..0b4e038
--- /dev/null
+++ b/site/app/webroot/img/installbtn-edges.png
Binary files differ
diff --git a/site/app/webroot/img/jquery-lightbox/close.png b/site/app/webroot/img/jquery-lightbox/close.png
new file mode 100644
index 0000000..a39bbcf
--- /dev/null
+++ b/site/app/webroot/img/jquery-lightbox/close.png
Binary files differ
diff --git a/site/app/webroot/img/jquery-lightbox/goleft.png b/site/app/webroot/img/jquery-lightbox/goleft.png
new file mode 100644
index 0000000..50f63d8
--- /dev/null
+++ b/site/app/webroot/img/jquery-lightbox/goleft.png
Binary files differ
diff --git a/site/app/webroot/img/jquery-lightbox/goright.png b/site/app/webroot/img/jquery-lightbox/goright.png
new file mode 100644
index 0000000..8a8d3ef
--- /dev/null
+++ b/site/app/webroot/img/jquery-lightbox/goright.png
Binary files differ
diff --git a/site/app/webroot/img/jquery-lightbox/lightbox-blank.gif b/site/app/webroot/img/jquery-lightbox/lightbox-blank.gif
new file mode 100644
index 0000000..1d11fa9
--- /dev/null
+++ b/site/app/webroot/img/jquery-lightbox/lightbox-blank.gif
Binary files differ
diff --git a/site/app/webroot/img/jquery-lightbox/lightbox-ico-loading.gif b/site/app/webroot/img/jquery-lightbox/lightbox-ico-loading.gif
new file mode 100644
index 0000000..4f1429c
--- /dev/null
+++ b/site/app/webroot/img/jquery-lightbox/lightbox-ico-loading.gif
Binary files differ
diff --git a/site/app/webroot/img/landrec-bl.png b/site/app/webroot/img/landrec-bl.png
new file mode 100644
index 0000000..752b221
--- /dev/null
+++ b/site/app/webroot/img/landrec-bl.png
Binary files differ
diff --git a/site/app/webroot/img/landrec-br.png b/site/app/webroot/img/landrec-br.png
new file mode 100644
index 0000000..cab542c
--- /dev/null
+++ b/site/app/webroot/img/landrec-br.png
Binary files differ
diff --git a/site/app/webroot/img/landrec-tl.png b/site/app/webroot/img/landrec-tl.png
new file mode 100644
index 0000000..ac79992
--- /dev/null
+++ b/site/app/webroot/img/landrec-tl.png
Binary files differ
diff --git a/site/app/webroot/img/landrec-tr.png b/site/app/webroot/img/landrec-tr.png
new file mode 100644
index 0000000..4f94c0d
--- /dev/null
+++ b/site/app/webroot/img/landrec-tr.png
Binary files differ
diff --git a/site/app/webroot/img/loadingAnimation.gif b/site/app/webroot/img/loadingAnimation.gif
new file mode 100644
index 0000000..92c5c30
--- /dev/null
+++ b/site/app/webroot/img/loadingAnimation.gif
Binary files differ
diff --git a/site/app/webroot/img/mdc-logo.png b/site/app/webroot/img/mdc-logo.png
new file mode 100644
index 0000000..72b7831
--- /dev/null
+++ b/site/app/webroot/img/mdc-logo.png
Binary files differ
diff --git a/site/app/webroot/img/moz-tab-ie.png b/site/app/webroot/img/moz-tab-ie.png
new file mode 100644
index 0000000..86189b2
--- /dev/null
+++ b/site/app/webroot/img/moz-tab-ie.png
Binary files differ
diff --git a/site/app/webroot/img/moz-tab.png b/site/app/webroot/img/moz-tab.png
new file mode 100644
index 0000000..af8054d
--- /dev/null
+++ b/site/app/webroot/img/moz-tab.png
Binary files differ
diff --git a/site/app/webroot/img/no-preview.png b/site/app/webroot/img/no-preview.png
new file mode 100644
index 0000000..7d54b75
--- /dev/null
+++ b/site/app/webroot/img/no-preview.png
Binary files differ
diff --git a/site/app/webroot/img/plugins/faq_small.png b/site/app/webroot/img/plugins/faq_small.png
new file mode 100755
index 0000000..12f9554
--- /dev/null
+++ b/site/app/webroot/img/plugins/faq_small.png
Binary files differ
diff --git a/site/app/webroot/img/plugins/install.png b/site/app/webroot/img/plugins/install.png
new file mode 100755
index 0000000..6270bf3
--- /dev/null
+++ b/site/app/webroot/img/plugins/install.png
Binary files differ
diff --git a/site/app/webroot/img/plugins/linux_icon.png b/site/app/webroot/img/plugins/linux_icon.png
new file mode 100644
index 0000000..307af74
--- /dev/null
+++ b/site/app/webroot/img/plugins/linux_icon.png
Binary files differ
diff --git a/site/app/webroot/img/plugins/macosx_icon.png b/site/app/webroot/img/plugins/macosx_icon.png
new file mode 100644
index 0000000..cbd870d
--- /dev/null
+++ b/site/app/webroot/img/plugins/macosx_icon.png
Binary files differ
diff --git a/site/app/webroot/img/plugins/windows_icon.png b/site/app/webroot/img/plugins/windows_icon.png
new file mode 100644
index 0000000..e3594e4
--- /dev/null
+++ b/site/app/webroot/img/plugins/windows_icon.png
Binary files differ
diff --git a/site/app/webroot/img/preview-img.png b/site/app/webroot/img/preview-img.png
new file mode 100644
index 0000000..ac543f4
--- /dev/null
+++ b/site/app/webroot/img/preview-img.png
Binary files differ
diff --git a/site/app/webroot/img/puzzle-corner.png b/site/app/webroot/img/puzzle-corner.png
new file mode 100644
index 0000000..3efc745
--- /dev/null
+++ b/site/app/webroot/img/puzzle-corner.png
Binary files differ
diff --git a/site/app/webroot/img/quotationmark.gif b/site/app/webroot/img/quotationmark.gif
new file mode 100644
index 0000000..25dc0bd
--- /dev/null
+++ b/site/app/webroot/img/quotationmark.gif
Binary files differ
diff --git a/site/app/webroot/img/ratings/1stars.png b/site/app/webroot/img/ratings/1stars.png
new file mode 100644
index 0000000..b43fc51
--- /dev/null
+++ b/site/app/webroot/img/ratings/1stars.png
Binary files differ
diff --git a/site/app/webroot/img/ratings/2stars.png b/site/app/webroot/img/ratings/2stars.png
new file mode 100644
index 0000000..bcd38a1
--- /dev/null
+++ b/site/app/webroot/img/ratings/2stars.png
Binary files differ
diff --git a/site/app/webroot/img/ratings/3stars.png b/site/app/webroot/img/ratings/3stars.png
new file mode 100644
index 0000000..2606645
--- /dev/null
+++ b/site/app/webroot/img/ratings/3stars.png
Binary files differ
diff --git a/site/app/webroot/img/ratings/4stars.png b/site/app/webroot/img/ratings/4stars.png
new file mode 100644
index 0000000..e5ffc78
--- /dev/null
+++ b/site/app/webroot/img/ratings/4stars.png
Binary files differ
diff --git a/site/app/webroot/img/ratings/5stars.png b/site/app/webroot/img/ratings/5stars.png
new file mode 100644
index 0000000..95ce668
--- /dev/null
+++ b/site/app/webroot/img/ratings/5stars.png
Binary files differ
diff --git a/site/app/webroot/img/ratings_images.gif b/site/app/webroot/img/ratings_images.gif
new file mode 100644
index 0000000..6396d53
--- /dev/null
+++ b/site/app/webroot/img/ratings_images.gif
Binary files differ
diff --git a/site/app/webroot/img/rec-bl.png b/site/app/webroot/img/rec-bl.png
new file mode 100644
index 0000000..894afd2
--- /dev/null
+++ b/site/app/webroot/img/rec-bl.png
Binary files differ
diff --git a/site/app/webroot/img/rec-br.png b/site/app/webroot/img/rec-br.png
new file mode 100644
index 0000000..45d2c5a
--- /dev/null
+++ b/site/app/webroot/img/rec-br.png
Binary files differ
diff --git a/site/app/webroot/img/rec-flag.png b/site/app/webroot/img/rec-flag.png
new file mode 100644
index 0000000..33f4dbb
--- /dev/null
+++ b/site/app/webroot/img/rec-flag.png
Binary files differ
diff --git a/site/app/webroot/img/rec-tl.png b/site/app/webroot/img/rec-tl.png
new file mode 100644
index 0000000..7d8e8c4
--- /dev/null
+++ b/site/app/webroot/img/rec-tl.png
Binary files differ
diff --git a/site/app/webroot/img/rec-tr.png b/site/app/webroot/img/rec-tr.png
new file mode 100644
index 0000000..c88af46
--- /dev/null
+++ b/site/app/webroot/img/rec-tr.png
Binary files differ
diff --git a/site/app/webroot/img/recommended_medal.gif b/site/app/webroot/img/recommended_medal.gif
new file mode 100644
index 0000000..6d7b4af
--- /dev/null
+++ b/site/app/webroot/img/recommended_medal.gif
Binary files differ
diff --git a/site/app/webroot/img/remora2.png b/site/app/webroot/img/remora2.png
new file mode 100644
index 0000000..2842b13
--- /dev/null
+++ b/site/app/webroot/img/remora2.png
Binary files differ
diff --git a/site/app/webroot/img/rustico/addons/firefox-addons-mglass-ico.png b/site/app/webroot/img/rustico/addons/firefox-addons-mglass-ico.png
new file mode 100644
index 0000000..0d87672
--- /dev/null
+++ b/site/app/webroot/img/rustico/addons/firefox-addons-mglass-ico.png
Binary files differ
diff --git a/site/app/webroot/img/rustico/addons/firefox-addons-puzzle-ico.png b/site/app/webroot/img/rustico/addons/firefox-addons-puzzle-ico.png
new file mode 100644
index 0000000..8499963
--- /dev/null
+++ b/site/app/webroot/img/rustico/addons/firefox-addons-puzzle-ico.png
Binary files differ
diff --git a/site/app/webroot/img/rustico/bookmarks/firefox-bm-divider.png b/site/app/webroot/img/rustico/bookmarks/firefox-bm-divider.png
new file mode 100644
index 0000000..8b598d5
--- /dev/null
+++ b/site/app/webroot/img/rustico/bookmarks/firefox-bm-divider.png
Binary files differ
diff --git a/site/app/webroot/img/rustico/bookmarks/firefox-bm-puzzle-ico.png b/site/app/webroot/img/rustico/bookmarks/firefox-bm-puzzle-ico.png
new file mode 100644
index 0000000..15188a6
--- /dev/null
+++ b/site/app/webroot/img/rustico/bookmarks/firefox-bm-puzzle-ico.png
Binary files differ
diff --git a/site/app/webroot/img/rustico/bookmarks/firefox-bm-ss-01.jpg b/site/app/webroot/img/rustico/bookmarks/firefox-bm-ss-01.jpg
new file mode 100644
index 0000000..c951cf6
--- /dev/null
+++ b/site/app/webroot/img/rustico/bookmarks/firefox-bm-ss-01.jpg
Binary files differ
diff --git a/site/app/webroot/img/rustico/bookmarks/firefox-bm-ss-02.jpg b/site/app/webroot/img/rustico/bookmarks/firefox-bm-ss-02.jpg
new file mode 100644
index 0000000..1455cfd
--- /dev/null
+++ b/site/app/webroot/img/rustico/bookmarks/firefox-bm-ss-02.jpg
Binary files differ
diff --git a/site/app/webroot/img/rustico/bookmarks/firefox-bm-ss-03.jpg b/site/app/webroot/img/rustico/bookmarks/firefox-bm-ss-03.jpg
new file mode 100644
index 0000000..7a0dd0c
--- /dev/null
+++ b/site/app/webroot/img/rustico/bookmarks/firefox-bm-ss-03.jpg
Binary files differ
diff --git a/site/app/webroot/img/rustico/bookmarks/firefox-bm-ss-04.jpg b/site/app/webroot/img/rustico/bookmarks/firefox-bm-ss-04.jpg
new file mode 100644
index 0000000..2d3940a
--- /dev/null
+++ b/site/app/webroot/img/rustico/bookmarks/firefox-bm-ss-04.jpg
Binary files differ
diff --git a/site/app/webroot/img/rustico/bookmarks/firefox-bm-ss-05.jpg b/site/app/webroot/img/rustico/bookmarks/firefox-bm-ss-05.jpg
new file mode 100644
index 0000000..818e827
--- /dev/null
+++ b/site/app/webroot/img/rustico/bookmarks/firefox-bm-ss-05.jpg
Binary files differ
diff --git a/site/app/webroot/img/rustico/common/addons-title.png b/site/app/webroot/img/rustico/common/addons-title.png
new file mode 100644
index 0000000..1dda50b
--- /dev/null
+++ b/site/app/webroot/img/rustico/common/addons-title.png
Binary files differ
diff --git a/site/app/webroot/img/rustico/common/bg-header-small.jpg b/site/app/webroot/img/rustico/common/bg-header-small.jpg
new file mode 100644
index 0000000..278502d
--- /dev/null
+++ b/site/app/webroot/img/rustico/common/bg-header-small.jpg
Binary files differ
diff --git a/site/app/webroot/img/rustico/common/bg-header-thin.jpg b/site/app/webroot/img/rustico/common/bg-header-thin.jpg
new file mode 100644
index 0000000..860878c
--- /dev/null
+++ b/site/app/webroot/img/rustico/common/bg-header-thin.jpg
Binary files differ
diff --git a/site/app/webroot/img/rustico/common/firefox-addons-hdr.jpg b/site/app/webroot/img/rustico/common/firefox-addons-hdr.jpg
new file mode 100644
index 0000000..5f513fa
--- /dev/null
+++ b/site/app/webroot/img/rustico/common/firefox-addons-hdr.jpg
Binary files differ
diff --git a/site/app/webroot/img/rustico/featured/firefox-featured-divider.png b/site/app/webroot/img/rustico/featured/firefox-featured-divider.png
new file mode 100644
index 0000000..c3aea1a
--- /dev/null
+++ b/site/app/webroot/img/rustico/featured/firefox-featured-divider.png
Binary files differ
diff --git a/site/app/webroot/img/rustico/featured/firefox-featured-hb-mid.jpg b/site/app/webroot/img/rustico/featured/firefox-featured-hb-mid.jpg
new file mode 100644
index 0000000..6aaf26a
--- /dev/null
+++ b/site/app/webroot/img/rustico/featured/firefox-featured-hb-mid.jpg
Binary files differ
diff --git a/site/app/webroot/img/rustico/featured/firefox-featured-hb-top.jpg b/site/app/webroot/img/rustico/featured/firefox-featured-hb-top.jpg
new file mode 100644
index 0000000..55cea2c
--- /dev/null
+++ b/site/app/webroot/img/rustico/featured/firefox-featured-hb-top.jpg
Binary files differ
diff --git a/site/app/webroot/img/rustico/featured/firefox-featured-mglass.png b/site/app/webroot/img/rustico/featured/firefox-featured-mglass.png
new file mode 100644
index 0000000..9d1eb55
--- /dev/null
+++ b/site/app/webroot/img/rustico/featured/firefox-featured-mglass.png
Binary files differ
diff --git a/site/app/webroot/img/rustico/featured/firefox-featured-ss-01.jpg b/site/app/webroot/img/rustico/featured/firefox-featured-ss-01.jpg
new file mode 100644
index 0000000..9731f89
--- /dev/null
+++ b/site/app/webroot/img/rustico/featured/firefox-featured-ss-01.jpg
Binary files differ
diff --git a/site/app/webroot/img/rustico/featured/firefox-featured-ss-02.jpg b/site/app/webroot/img/rustico/featured/firefox-featured-ss-02.jpg
new file mode 100644
index 0000000..7e3a8c3
--- /dev/null
+++ b/site/app/webroot/img/rustico/featured/firefox-featured-ss-02.jpg
Binary files differ
diff --git a/site/app/webroot/img/rustico/featured/firefox-featured-ss-03.jpg b/site/app/webroot/img/rustico/featured/firefox-featured-ss-03.jpg
new file mode 100644
index 0000000..69b2379
--- /dev/null
+++ b/site/app/webroot/img/rustico/featured/firefox-featured-ss-03.jpg
Binary files differ
diff --git a/site/app/webroot/img/rustico/featured/firefox-featured-title.png b/site/app/webroot/img/rustico/featured/firefox-featured-title.png
new file mode 100644
index 0000000..8641b60
--- /dev/null
+++ b/site/app/webroot/img/rustico/featured/firefox-featured-title.png
Binary files differ
diff --git a/site/app/webroot/img/rustico/firefox-featured-divider.png b/site/app/webroot/img/rustico/firefox-featured-divider.png
new file mode 100644
index 0000000..c3aea1a
--- /dev/null
+++ b/site/app/webroot/img/rustico/firefox-featured-divider.png
Binary files differ
diff --git a/site/app/webroot/img/rustico/footer/disclaimer.png b/site/app/webroot/img/rustico/footer/disclaimer.png
new file mode 100644
index 0000000..df8ff3f
--- /dev/null
+++ b/site/app/webroot/img/rustico/footer/disclaimer.png
Binary files differ
diff --git a/site/app/webroot/img/rustico/footer/footer-icon-firefox.png b/site/app/webroot/img/rustico/footer/footer-icon-firefox.png
new file mode 100644
index 0000000..821fe6a
--- /dev/null
+++ b/site/app/webroot/img/rustico/footer/footer-icon-firefox.png
Binary files differ
diff --git a/site/app/webroot/img/rustico/footer/footer-icon-mozilla.png b/site/app/webroot/img/rustico/footer/footer-icon-mozilla.png
new file mode 100644
index 0000000..778e927
--- /dev/null
+++ b/site/app/webroot/img/rustico/footer/footer-icon-mozilla.png
Binary files differ
diff --git a/site/app/webroot/img/rustico/footer/footer-icon-thunderbird.png b/site/app/webroot/img/rustico/footer/footer-icon-thunderbird.png
new file mode 100644
index 0000000..def58ef
--- /dev/null
+++ b/site/app/webroot/img/rustico/footer/footer-icon-thunderbird.png
Binary files differ
diff --git a/site/app/webroot/img/rustico/header/header-background.png b/site/app/webroot/img/rustico/header/header-background.png
new file mode 100644
index 0000000..4327861
--- /dev/null
+++ b/site/app/webroot/img/rustico/header/header-background.png
Binary files differ
diff --git a/site/app/webroot/img/rustico/header/moz-com-logo.png b/site/app/webroot/img/rustico/header/moz-com-logo.png
new file mode 100644
index 0000000..cb0ba06
--- /dev/null
+++ b/site/app/webroot/img/rustico/header/moz-com-logo.png
Binary files differ
diff --git a/site/app/webroot/img/rustico/install-button-red.png b/site/app/webroot/img/rustico/install-button-red.png
new file mode 100644
index 0000000..146f21b
--- /dev/null
+++ b/site/app/webroot/img/rustico/install-button-red.png
Binary files differ
diff --git a/site/app/webroot/img/rustico/install-button.png b/site/app/webroot/img/rustico/install-button.png
new file mode 100644
index 0000000..fdd7430
--- /dev/null
+++ b/site/app/webroot/img/rustico/install-button.png
Binary files differ
diff --git a/site/app/webroot/img/rustico/left-top-corner-box.jpg b/site/app/webroot/img/rustico/left-top-corner-box.jpg
new file mode 100644
index 0000000..94b904c
--- /dev/null
+++ b/site/app/webroot/img/rustico/left-top-corner-box.jpg
Binary files differ
diff --git a/site/app/webroot/img/rustico/menu-box/menu-box-background.png b/site/app/webroot/img/rustico/menu-box/menu-box-background.png
new file mode 100644
index 0000000..8f0fc48
--- /dev/null
+++ b/site/app/webroot/img/rustico/menu-box/menu-box-background.png
Binary files differ
diff --git a/site/app/webroot/img/rustico/menu-box/menu-box-bottom.png b/site/app/webroot/img/rustico/menu-box/menu-box-bottom.png
new file mode 100644
index 0000000..5714f7a
--- /dev/null
+++ b/site/app/webroot/img/rustico/menu-box/menu-box-bottom.png
Binary files differ
diff --git a/site/app/webroot/img/rustico/menu-box/menu-box-top.png b/site/app/webroot/img/rustico/menu-box/menu-box-top.png
new file mode 100644
index 0000000..ed6269b
--- /dev/null
+++ b/site/app/webroot/img/rustico/menu-box/menu-box-top.png
Binary files differ
diff --git a/site/app/webroot/img/rustico/right-top-corner-box.jpg b/site/app/webroot/img/rustico/right-top-corner-box.jpg
new file mode 100644
index 0000000..c6a3ff3
--- /dev/null
+++ b/site/app/webroot/img/rustico/right-top-corner-box.jpg
Binary files differ
diff --git a/site/app/webroot/img/sandbox.png b/site/app/webroot/img/sandbox.png
new file mode 100644
index 0000000..a759a18
--- /dev/null
+++ b/site/app/webroot/img/sandbox.png
Binary files differ
diff --git a/site/app/webroot/img/search-bg.png b/site/app/webroot/img/search-bg.png
new file mode 100644
index 0000000..96d7b07
--- /dev/null
+++ b/site/app/webroot/img/search-bg.png
Binary files differ
diff --git a/site/app/webroot/img/search-icn.png b/site/app/webroot/img/search-icn.png
new file mode 100644
index 0000000..39be111
--- /dev/null
+++ b/site/app/webroot/img/search-icn.png
Binary files differ
diff --git a/site/app/webroot/img/search-left-bottom.png b/site/app/webroot/img/search-left-bottom.png
new file mode 100644
index 0000000..6219b99
--- /dev/null
+++ b/site/app/webroot/img/search-left-bottom.png
Binary files differ
diff --git a/site/app/webroot/img/search-left-tab.png b/site/app/webroot/img/search-left-tab.png
new file mode 100755
index 0000000..31becb7
--- /dev/null
+++ b/site/app/webroot/img/search-left-tab.png
Binary files differ
diff --git a/site/app/webroot/img/search-left.png b/site/app/webroot/img/search-left.png
new file mode 100644
index 0000000..16f800f
--- /dev/null
+++ b/site/app/webroot/img/search-left.png
Binary files differ
diff --git a/site/app/webroot/img/search-right-bottom.png b/site/app/webroot/img/search-right-bottom.png
new file mode 100644
index 0000000..14340a0
--- /dev/null
+++ b/site/app/webroot/img/search-right-bottom.png
Binary files differ
diff --git a/site/app/webroot/img/search-right-tab.png b/site/app/webroot/img/search-right-tab.png
new file mode 100755
index 0000000..045e927
--- /dev/null
+++ b/site/app/webroot/img/search-right-tab.png
Binary files differ
diff --git a/site/app/webroot/img/search-right.png b/site/app/webroot/img/search-right.png
new file mode 100644
index 0000000..5f5500f
--- /dev/null
+++ b/site/app/webroot/img/search-right.png
Binary files differ
diff --git a/site/app/webroot/img/searchBarBackground.gif b/site/app/webroot/img/searchBarBackground.gif
new file mode 100644
index 0000000..5fe5e56
--- /dev/null
+++ b/site/app/webroot/img/searchBarBackground.gif
Binary files differ
diff --git a/site/app/webroot/img/sidebarBackground.gif b/site/app/webroot/img/sidebarBackground.gif
new file mode 100644
index 0000000..3f95817
--- /dev/null
+++ b/site/app/webroot/img/sidebarBackground.gif
Binary files differ
diff --git a/site/app/webroot/img/sidebarHighlight.gif b/site/app/webroot/img/sidebarHighlight.gif
new file mode 100644
index 0000000..bdcb408
--- /dev/null
+++ b/site/app/webroot/img/sidebarHighlight.gif
Binary files differ
diff --git a/site/app/webroot/img/slider-next-disabled.gif b/site/app/webroot/img/slider-next-disabled.gif
new file mode 100644
index 0000000..32f0541
--- /dev/null
+++ b/site/app/webroot/img/slider-next-disabled.gif
Binary files differ
diff --git a/site/app/webroot/img/slider-next.gif b/site/app/webroot/img/slider-next.gif
new file mode 100644
index 0000000..04ca93d
--- /dev/null
+++ b/site/app/webroot/img/slider-next.gif
Binary files differ
diff --git a/site/app/webroot/img/slider-prev-disabled.gif b/site/app/webroot/img/slider-prev-disabled.gif
new file mode 100644
index 0000000..beb0132
--- /dev/null
+++ b/site/app/webroot/img/slider-prev-disabled.gif
Binary files differ
diff --git a/site/app/webroot/img/slider-prev.gif b/site/app/webroot/img/slider-prev.gif
new file mode 100644
index 0000000..ad583b9
--- /dev/null
+++ b/site/app/webroot/img/slider-prev.gif
Binary files differ
diff --git a/site/app/webroot/img/softwareIcon.png b/site/app/webroot/img/softwareIcon.png
new file mode 100644
index 0000000..96be315
--- /dev/null
+++ b/site/app/webroot/img/softwareIcon.png
Binary files differ
diff --git a/site/app/webroot/img/sprite-alpha.png b/site/app/webroot/img/sprite-alpha.png
new file mode 100644
index 0000000..8894ac5
--- /dev/null
+++ b/site/app/webroot/img/sprite-alpha.png
Binary files differ
diff --git a/site/app/webroot/img/sprite.png b/site/app/webroot/img/sprite.png
new file mode 100644
index 0000000..7506210
--- /dev/null
+++ b/site/app/webroot/img/sprite.png
Binary files differ
diff --git a/site/app/webroot/img/stats/chart_curve_add.png b/site/app/webroot/img/stats/chart_curve_add.png
new file mode 100755
index 0000000..f9e2050
--- /dev/null
+++ b/site/app/webroot/img/stats/chart_curve_add.png
Binary files differ
diff --git a/site/app/webroot/img/stats/cog.png b/site/app/webroot/img/stats/cog.png
new file mode 100755
index 0000000..67de2c6
--- /dev/null
+++ b/site/app/webroot/img/stats/cog.png
Binary files differ
diff --git a/site/app/webroot/img/stats/lock.png b/site/app/webroot/img/stats/lock.png
new file mode 100755
index 0000000..2ebc4f6
--- /dev/null
+++ b/site/app/webroot/img/stats/lock.png
Binary files differ
diff --git a/site/app/webroot/img/stats/lock_open.png b/site/app/webroot/img/stats/lock_open.png
new file mode 100755
index 0000000..a471765
--- /dev/null
+++ b/site/app/webroot/img/stats/lock_open.png
Binary files differ
diff --git a/site/app/webroot/img/stats/page_white_go.png b/site/app/webroot/img/stats/page_white_go.png
new file mode 100755
index 0000000..7e62a92
--- /dev/null
+++ b/site/app/webroot/img/stats/page_white_go.png
Binary files differ
diff --git a/site/app/webroot/img/stats/rss16x16.png b/site/app/webroot/img/stats/rss16x16.png
new file mode 100755
index 0000000..54c2532
--- /dev/null
+++ b/site/app/webroot/img/stats/rss16x16.png
Binary files differ
diff --git a/site/app/webroot/img/stats/tick.png b/site/app/webroot/img/stats/tick.png
new file mode 100755
index 0000000..a9925a0
--- /dev/null
+++ b/site/app/webroot/img/stats/tick.png
Binary files differ
diff --git a/site/app/webroot/img/stats/x.png b/site/app/webroot/img/stats/x.png
new file mode 100755
index 0000000..41c6771
--- /dev/null
+++ b/site/app/webroot/img/stats/x.png
Binary files differ
diff --git a/site/app/webroot/img/stats/zoom_in.png b/site/app/webroot/img/stats/zoom_in.png
new file mode 100755
index 0000000..cdf0a52
--- /dev/null
+++ b/site/app/webroot/img/stats/zoom_in.png
Binary files differ
diff --git a/site/app/webroot/img/stats/zoom_out.png b/site/app/webroot/img/stats/zoom_out.png
new file mode 100755
index 0000000..07bf98a
--- /dev/null
+++ b/site/app/webroot/img/stats/zoom_out.png
Binary files differ
diff --git a/site/app/webroot/img/template/body-background.png b/site/app/webroot/img/template/body-background.png
new file mode 100644
index 0000000..a3e7842
--- /dev/null
+++ b/site/app/webroot/img/template/body-background.png
Binary files differ
diff --git a/site/app/webroot/img/template/breadcrumbs-background.png b/site/app/webroot/img/template/breadcrumbs-background.png
new file mode 100644
index 0000000..e5ab6ac
--- /dev/null
+++ b/site/app/webroot/img/template/breadcrumbs-background.png
Binary files differ
diff --git a/site/app/webroot/img/template/download-firefox-white.png b/site/app/webroot/img/template/download-firefox-white.png
new file mode 100644
index 0000000..3ce7131
--- /dev/null
+++ b/site/app/webroot/img/template/download-firefox-white.png
Binary files differ
diff --git a/site/app/webroot/img/template/download-firefox.png b/site/app/webroot/img/template/download-firefox.png
new file mode 100644
index 0000000..2780485
--- /dev/null
+++ b/site/app/webroot/img/template/download-firefox.png
Binary files differ
diff --git a/site/app/webroot/img/template/download-store-promo-2.png b/site/app/webroot/img/template/download-store-promo-2.png
new file mode 100644
index 0000000..d00b1ac
--- /dev/null
+++ b/site/app/webroot/img/template/download-store-promo-2.png
Binary files differ
diff --git a/site/app/webroot/img/template/download-store-promo.png b/site/app/webroot/img/template/download-store-promo.png
new file mode 100644
index 0000000..6b42af4
--- /dev/null
+++ b/site/app/webroot/img/template/download-store-promo.png
Binary files differ
diff --git a/site/app/webroot/img/template/download-thunderbird.png b/site/app/webroot/img/template/download-thunderbird.png
new file mode 100644
index 0000000..2bd38f6
--- /dev/null
+++ b/site/app/webroot/img/template/download-thunderbird.png
Binary files differ
diff --git a/site/app/webroot/img/template/feature-back.png b/site/app/webroot/img/template/feature-back.png
new file mode 100644
index 0000000..5bd2c94
--- /dev/null
+++ b/site/app/webroot/img/template/feature-back.png
Binary files differ
diff --git a/site/app/webroot/img/template/firefox-15-headline.png b/site/app/webroot/img/template/firefox-15-headline.png
new file mode 100644
index 0000000..ec852dc
--- /dev/null
+++ b/site/app/webroot/img/template/firefox-15-headline.png
Binary files differ
diff --git a/site/app/webroot/img/template/firefox-awards-2006-jan.png b/site/app/webroot/img/template/firefox-awards-2006-jan.png
new file mode 100644
index 0000000..0247952
--- /dev/null
+++ b/site/app/webroot/img/template/firefox-awards-2006-jan.png
Binary files differ
diff --git a/site/app/webroot/img/template/firefox-livebookmarks-thumb.png b/site/app/webroot/img/template/firefox-livebookmarks-thumb.png
new file mode 100644
index 0000000..5093677
--- /dev/null
+++ b/site/app/webroot/img/template/firefox-livebookmarks-thumb.png
Binary files differ
diff --git a/site/app/webroot/img/template/firefox-logo-64x64.png b/site/app/webroot/img/template/firefox-logo-64x64.png
new file mode 100644
index 0000000..0dde487
--- /dev/null
+++ b/site/app/webroot/img/template/firefox-logo-64x64.png
Binary files differ
diff --git a/site/app/webroot/img/template/firefox-screen-mac.png b/site/app/webroot/img/template/firefox-screen-mac.png
new file mode 100644
index 0000000..edd7c07
--- /dev/null
+++ b/site/app/webroot/img/template/firefox-screen-mac.png
Binary files differ
diff --git a/site/app/webroot/img/template/firefox-screen-windows.png b/site/app/webroot/img/template/firefox-screen-windows.png
new file mode 100644
index 0000000..5be9bb3
--- /dev/null
+++ b/site/app/webroot/img/template/firefox-screen-windows.png
Binary files differ
diff --git a/site/app/webroot/img/template/firefox-screen.png b/site/app/webroot/img/template/firefox-screen.png
new file mode 100644
index 0000000..5be9bb3
--- /dev/null
+++ b/site/app/webroot/img/template/firefox-screen.png
Binary files differ
diff --git a/site/app/webroot/img/template/firefox-searchbar-thumb.png b/site/app/webroot/img/template/firefox-searchbar-thumb.png
new file mode 100644
index 0000000..e8a735c
--- /dev/null
+++ b/site/app/webroot/img/template/firefox-searchbar-thumb.png
Binary files differ
diff --git a/site/app/webroot/img/template/firefox-tabbedbrowsing-thumb.png b/site/app/webroot/img/template/firefox-tabbedbrowsing-thumb.png
new file mode 100644
index 0000000..070a5fc
--- /dev/null
+++ b/site/app/webroot/img/template/firefox-tabbedbrowsing-thumb.png
Binary files differ
diff --git a/site/app/webroot/img/template/go-to-home.png b/site/app/webroot/img/template/go-to-home.png
new file mode 100644
index 0000000..31b443d
--- /dev/null
+++ b/site/app/webroot/img/template/go-to-home.png
Binary files differ
diff --git a/site/app/webroot/img/template/header-background.png b/site/app/webroot/img/template/header-background.png
new file mode 100644
index 0000000..4327861
--- /dev/null
+++ b/site/app/webroot/img/template/header-background.png
Binary files differ
diff --git a/site/app/webroot/img/template/ico-osx-uni.png b/site/app/webroot/img/template/ico-osx-uni.png
new file mode 100644
index 0000000..0d26623
--- /dev/null
+++ b/site/app/webroot/img/template/ico-osx-uni.png
Binary files differ
diff --git a/site/app/webroot/img/template/ico-osx.png b/site/app/webroot/img/template/ico-osx.png
new file mode 100644
index 0000000..938a218
--- /dev/null
+++ b/site/app/webroot/img/template/ico-osx.png
Binary files differ
diff --git a/site/app/webroot/img/template/ico-tux.png b/site/app/webroot/img/template/ico-tux.png
new file mode 100644
index 0000000..c51a0b4
--- /dev/null
+++ b/site/app/webroot/img/template/ico-tux.png
Binary files differ
diff --git a/site/app/webroot/img/template/ico-win.png b/site/app/webroot/img/template/ico-win.png
new file mode 100644
index 0000000..7ffcea7
--- /dev/null
+++ b/site/app/webroot/img/template/ico-win.png
Binary files differ
diff --git a/site/app/webroot/img/template/menu_back.gif b/site/app/webroot/img/template/menu_back.gif
new file mode 100644
index 0000000..0afde1e
--- /dev/null
+++ b/site/app/webroot/img/template/menu_back.gif
Binary files differ
diff --git a/site/app/webroot/img/template/menu_bl.gif b/site/app/webroot/img/template/menu_bl.gif
new file mode 100644
index 0000000..545fef1
--- /dev/null
+++ b/site/app/webroot/img/template/menu_bl.gif
Binary files differ
diff --git a/site/app/webroot/img/template/menu_br.gif b/site/app/webroot/img/template/menu_br.gif
new file mode 100644
index 0000000..d88a5a8
--- /dev/null
+++ b/site/app/webroot/img/template/menu_br.gif
Binary files differ
diff --git a/site/app/webroot/img/template/menu_tl.gif b/site/app/webroot/img/template/menu_tl.gif
new file mode 100644
index 0000000..2709e23
--- /dev/null
+++ b/site/app/webroot/img/template/menu_tl.gif
Binary files differ
diff --git a/site/app/webroot/img/template/menu_tr.gif b/site/app/webroot/img/template/menu_tr.gif
new file mode 100644
index 0000000..0ceb90e
--- /dev/null
+++ b/site/app/webroot/img/template/menu_tr.gif
Binary files differ
diff --git a/site/app/webroot/img/template/moz-com-logo.png b/site/app/webroot/img/template/moz-com-logo.png
new file mode 100644
index 0000000..cb0ba06
--- /dev/null
+++ b/site/app/webroot/img/template/moz-com-logo.png
Binary files differ
diff --git a/site/app/webroot/img/template/mozilla-16.png b/site/app/webroot/img/template/mozilla-16.png
new file mode 100644
index 0000000..769c636
--- /dev/null
+++ b/site/app/webroot/img/template/mozilla-16.png
Binary files differ
diff --git a/site/app/webroot/img/template/page-background.png b/site/app/webroot/img/template/page-background.png
new file mode 100644
index 0000000..306c061
--- /dev/null
+++ b/site/app/webroot/img/template/page-background.png
Binary files differ
diff --git a/site/app/webroot/img/template/product-firefox-screen.png b/site/app/webroot/img/template/product-firefox-screen.png
new file mode 100644
index 0000000..44674c8
--- /dev/null
+++ b/site/app/webroot/img/template/product-firefox-screen.png
Binary files differ
diff --git a/site/app/webroot/img/template/product-thunderbird-screen.png b/site/app/webroot/img/template/product-thunderbird-screen.png
new file mode 100644
index 0000000..951f612
--- /dev/null
+++ b/site/app/webroot/img/template/product-thunderbird-screen.png
Binary files differ
diff --git a/site/app/webroot/img/template/releasenotes-firefox.png b/site/app/webroot/img/template/releasenotes-firefox.png
new file mode 100644
index 0000000..8f54138
--- /dev/null
+++ b/site/app/webroot/img/template/releasenotes-firefox.png
Binary files differ
diff --git a/site/app/webroot/img/template/releasenotes-thunderbird.png b/site/app/webroot/img/template/releasenotes-thunderbird.png
new file mode 100644
index 0000000..4ef5842
--- /dev/null
+++ b/site/app/webroot/img/template/releasenotes-thunderbird.png
Binary files differ
diff --git a/site/app/webroot/img/template/rss.png b/site/app/webroot/img/template/rss.png
new file mode 100644
index 0000000..1aee30f
--- /dev/null
+++ b/site/app/webroot/img/template/rss.png
Binary files differ
diff --git a/site/app/webroot/img/template/store-firefox-backpack.png b/site/app/webroot/img/template/store-firefox-backpack.png
new file mode 100644
index 0000000..d779fbd
--- /dev/null
+++ b/site/app/webroot/img/template/store-firefox-backpack.png
Binary files differ
diff --git a/site/app/webroot/img/template/store-firefox-cds.png b/site/app/webroot/img/template/store-firefox-cds.png
new file mode 100644
index 0000000..cf69c5e
--- /dev/null
+++ b/site/app/webroot/img/template/store-firefox-cds.png
Binary files differ
diff --git a/site/app/webroot/img/template/store-firefox-visor.png b/site/app/webroot/img/template/store-firefox-visor.png
new file mode 100644
index 0000000..a01baeb
--- /dev/null
+++ b/site/app/webroot/img/template/store-firefox-visor.png
Binary files differ
diff --git a/site/app/webroot/img/template/store-thunderbird-tshirt.png b/site/app/webroot/img/template/store-thunderbird-tshirt.png
new file mode 100644
index 0000000..98fa07b
--- /dev/null
+++ b/site/app/webroot/img/template/store-thunderbird-tshirt.png
Binary files differ
diff --git a/site/app/webroot/img/template/survey-title.png b/site/app/webroot/img/template/survey-title.png
new file mode 100644
index 0000000..5e8a342
--- /dev/null
+++ b/site/app/webroot/img/template/survey-title.png
Binary files differ
diff --git a/site/app/webroot/img/template/thunderbird-headline.png b/site/app/webroot/img/template/thunderbird-headline.png
new file mode 100644
index 0000000..b1fe30a
--- /dev/null
+++ b/site/app/webroot/img/template/thunderbird-headline.png
Binary files differ
diff --git a/site/app/webroot/img/template/thunderbird-logo-64x64.png b/site/app/webroot/img/template/thunderbird-logo-64x64.png
new file mode 100644
index 0000000..26b965e
--- /dev/null
+++ b/site/app/webroot/img/template/thunderbird-logo-64x64.png
Binary files differ
diff --git a/site/app/webroot/img/template/thunderbird-screen-mac.png b/site/app/webroot/img/template/thunderbird-screen-mac.png
new file mode 100644
index 0000000..550d5e7
--- /dev/null
+++ b/site/app/webroot/img/template/thunderbird-screen-mac.png
Binary files differ
diff --git a/site/app/webroot/img/template/thunderbird-screen-windows.png b/site/app/webroot/img/template/thunderbird-screen-windows.png
new file mode 100644
index 0000000..bdd4298
--- /dev/null
+++ b/site/app/webroot/img/template/thunderbird-screen-windows.png
Binary files differ
diff --git a/site/app/webroot/img/template/title-firefox.png b/site/app/webroot/img/template/title-firefox.png
new file mode 100644
index 0000000..be95d63
--- /dev/null
+++ b/site/app/webroot/img/template/title-firefox.png
Binary files differ
diff --git a/site/app/webroot/img/template/title-thunderbird.png b/site/app/webroot/img/template/title-thunderbird.png
new file mode 100644
index 0000000..6ee7754
--- /dev/null
+++ b/site/app/webroot/img/template/title-thunderbird.png
Binary files differ
diff --git a/site/app/webroot/img/template/warning.png b/site/app/webroot/img/template/warning.png
new file mode 100644
index 0000000..dedde9a
--- /dev/null
+++ b/site/app/webroot/img/template/warning.png
Binary files differ
diff --git a/site/app/webroot/img/theme.png b/site/app/webroot/img/theme.png
new file mode 100755
index 0000000..3d644ac
--- /dev/null
+++ b/site/app/webroot/img/theme.png
Binary files differ
diff --git a/site/app/webroot/img/thumbnail.png b/site/app/webroot/img/thumbnail.png
new file mode 100644
index 0000000..59c9a65
--- /dev/null
+++ b/site/app/webroot/img/thumbnail.png
Binary files differ
diff --git a/site/app/webroot/img/tinyRss.png b/site/app/webroot/img/tinyRss.png
new file mode 100644
index 0000000..628a839
--- /dev/null
+++ b/site/app/webroot/img/tinyRss.png
Binary files differ
diff --git a/site/app/webroot/img/version.png b/site/app/webroot/img/version.png
new file mode 100644
index 0000000..35cb557
--- /dev/null
+++ b/site/app/webroot/img/version.png
Binary files differ
diff --git a/site/app/webroot/img/warning-ie.png b/site/app/webroot/img/warning-ie.png
new file mode 100644
index 0000000..e08c861
--- /dev/null
+++ b/site/app/webroot/img/warning-ie.png
Binary files differ
diff --git a/site/app/webroot/img/warning.png b/site/app/webroot/img/warning.png
new file mode 100644
index 0000000..dedde9a
--- /dev/null
+++ b/site/app/webroot/img/warning.png
Binary files differ
diff --git a/site/app/webroot/img/wordmarks/firefox-3.0.png b/site/app/webroot/img/wordmarks/firefox-3.0.png
new file mode 100644
index 0000000..88cec31
--- /dev/null
+++ b/site/app/webroot/img/wordmarks/firefox-3.0.png
Binary files differ
diff --git a/site/app/webroot/img/wordmarks/firefox-3.0_small.png b/site/app/webroot/img/wordmarks/firefox-3.0_small.png
new file mode 100644
index 0000000..8f8ed15
--- /dev/null
+++ b/site/app/webroot/img/wordmarks/firefox-3.0_small.png
Binary files differ
diff --git a/site/app/webroot/img/wordmarks/firefox-3.5.png b/site/app/webroot/img/wordmarks/firefox-3.5.png
new file mode 100644
index 0000000..a227732
--- /dev/null
+++ b/site/app/webroot/img/wordmarks/firefox-3.5.png
Binary files differ
diff --git a/site/app/webroot/img/wordmarks/firefox-3.5_small.png b/site/app/webroot/img/wordmarks/firefox-3.5_small.png
new file mode 100644
index 0000000..af9b83c
--- /dev/null
+++ b/site/app/webroot/img/wordmarks/firefox-3.5_small.png
Binary files differ
diff --git a/site/app/webroot/index.php b/site/app/webroot/index.php
new file mode 100644
index 0000000..fb213c0
--- /dev/null
+++ b/site/app/webroot/index.php
@@ -0,0 +1,87 @@
+<?php
+/* SVN FILE: $Id: index.php,v 1.2 2006/08/15 03:12:10 sancus%off.net Exp $ */
+/**
+ * Short description for file.
+ *
+ * Long description for file
+ *
+ * PHP versions 4 and 5
+ *
+ * CakePHP : Rapid Development Framework <http://www.cakephp.org/>
+ * Copyright (c) 2006, Cake Software Foundation, Inc.
+ * 1785 E. Sahara Avenue, Suite 490-204
+ * Las Vegas, Nevada 89104
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright Copyright (c) 2006, Cake Software Foundation, Inc.
+ * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP Project
+ * @package cake
+ * @subpackage cake.app.webroot
+ * @since CakePHP v 0.2.9
+ * @version $Revision: 1.2 $
+ * @modifiedby $LastChangedBy: phpnut $
+ * @lastmodified $Date: 2006/08/15 03:12:10 $
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+/**
+ * Do not change
+ */
+ if (!defined('DS')) {
+ define('DS', DIRECTORY_SEPARATOR);
+ }
+/**
+ * These defines should only be edited if you have cake installed in
+ * a directory layout other than the way it is distributed.
+ * Each define has a commented line of code that explains what you would change.
+ *
+ */
+ if (!defined('ROOT')) {
+ //define('ROOT', 'FULL PATH TO DIRECTORY WHERE APP DIRECTORY IS LOCATED DO NOT ADD A TRAILING DIRECTORY SEPARATOR';
+ //You should also use the DS define to seperate your directories
+ define('ROOT', dirname(dirname(dirname(__FILE__))));
+ }
+ if (!defined('APP_DIR')) {
+ //define('APP_DIR', 'DIRECTORY NAME OF APPLICATION';
+ define('APP_DIR', 'app');
+ }
+/**
+ * This only needs to be changed if the cake installed libs are located
+ * outside of the distributed directory structure.
+ */
+ if (!defined('CAKE_CORE_INCLUDE_PATH')) {
+ //define ('CAKE_CORE_INCLUDE_PATH', FULL PATH TO DIRECTORY WHERE CAKE CORE IS INSTALLED DO NOT ADD A TRAILING DIRECTORY SEPARATOR';
+ //You should also use the DS define to seperate your directories
+ define('CAKE_CORE_INCLUDE_PATH', ROOT);
+ }
+///////////////////////////////
+//DO NOT EDIT BELOW THIS LINE//
+///////////////////////////////
+ if (!defined('WEBROOT_DIR')) {
+ define('WEBROOT_DIR', basename(dirname(__FILE__)));
+ }
+ if (!defined('WWW_ROOT')) {
+ define('WWW_ROOT', dirname(__FILE__) . DS);
+ }
+ if (!defined('CORE_PATH')) {
+ if (function_exists('ini_set')) {
+ ini_set('include_path', ini_get('include_path') . PATH_SEPARATOR . CAKE_CORE_INCLUDE_PATH . PATH_SEPARATOR . ROOT . DS . APP_DIR . DS);
+ define('APP_PATH', null);
+ define('CORE_PATH', null);
+ } else {
+ define('APP_PATH', ROOT . DS . APP_DIR . DS);
+ define('CORE_PATH', CAKE_CORE_INCLUDE_PATH . DS);
+ }
+ }
+ require CORE_PATH . 'cake' . DS . 'bootstrap.php';
+ if (isset($_GET['url']) && $_GET['url'] === 'favicon.ico') {
+ } else {
+ $Dispatcher=new Dispatcher();
+ $Dispatcher->dispatch($url);
+ }
+ if (DEBUG && !defined('NO_MICROTIME')) {
+ echo "<!-- " . round(getMicrotime() - $TIME_START, 4) . "s -->";
+ }
+?>
diff --git a/site/app/webroot/js/__utm.js b/site/app/webroot/js/__utm.js
new file mode 100644
index 0000000..f65a7c8
--- /dev/null
+++ b/site/app/webroot/js/__utm.js
@@ -0,0 +1,488 @@
+//-- Urchin Tracking Module 6.1 (UTM 6.1) $Revision: 1.1 $
+//-- Copyright 2004 Urchin Software Corporation, All Rights Reserved.
+
+//-- Urchin On Demand Settings ONLY
+var _uacct=""; // set up the Urchin Account
+var _userv=0; // service mode (0=local,1=remote,2=both)
+
+//-- UTM User Settings
+var _ufsc=1; // set client info flag (1=on|0=off)
+var _udn="addons.mozilla.org"; // (auto|none|domain) set the domain name for cookies
+var _uhash="on"; // (on|off) unique domain hash for cookies
+var _utimeout="1800"; // set the inactive session timeout in seconds
+var _ugifpath="/img/__utm.gif"; // set the web path to the __utm.gif file
+var _utsp="|"; // transaction field separator
+var _uflash=1; // set flash version detect option (1=on|0=off)
+var _utitle=1; // set the document title detect option (1=on|0=off)
+
+//-- UTM Campaign Tracking Settings
+var _uctm=1; // set campaign tracking module (1=on|0=off)
+var _ucto="15768000"; // set timeout in seconds (6 month default)
+var _uccn="utm_campaign"; // name
+var _ucmd="utm_medium"; // medium (cpc|cpm|link|email|organic)
+var _ucsr="utm_source"; // source
+var _uctr="utm_term"; // term/keyword
+var _ucct="utm_content"; // content
+var _ucid="utm_id"; // id number
+var _ucno="utm_nooverride"; // don't override
+
+//-- Auto/Organic Sources and Keywords
+var _uOsr=new Array();
+var _uOkw=new Array();
+_uOsr[0]="google"; _uOkw[0]="q";
+_uOsr[1]="yahoo"; _uOkw[1]="p";
+_uOsr[2]="msn"; _uOkw[2]="q";
+_uOsr[3]="aol"; _uOkw[3]="query";
+_uOsr[4]="lycos"; _uOkw[4]="query";
+_uOsr[5]="ask"; _uOkw[5]="q";
+_uOsr[6]="altavista"; _uOkw[6]="q";
+_uOsr[7]="search"; _uOkw[7]="q";
+_uOsr[8]="netscape"; _uOkw[8]="query";
+_uOsr[9]="earthlink"; _uOkw[9]="q";
+_uOsr[10]="cnn"; _uOkw[10]="query";
+_uOsr[11]="looksmart"; _uOkw[11]="key";
+_uOsr[12]="about"; _uOkw[12]="terms";
+_uOsr[13]="excite"; _uOkw[13]="qkw";
+_uOsr[14]="mamma"; _uOkw[14]="query";
+_uOsr[15]="alltheweb"; _uOkw[15]="q";
+_uOsr[16]="gigablast"; _uOkw[16]="q";
+_uOsr[17]="voila"; _uOkw[17]="kw";
+_uOsr[18]="virgilio"; _uOkw[18]="qs";
+_uOsr[19]="teoma"; _uOkw[19]="q";
+
+//-- Auto/Organic Keywords to Ignore
+var _uOno=new Array();
+//_uOno[0]="urchin";
+//_uOno[1]="urchin.com";
+//_uOno[2]="www.urchin.com";
+
+//-- Referral domains to Ignore
+var _uRno=new Array();
+//_uRno[0]=".urchin.com";
+
+//-- **** Don't modify below this point ***
+var _uff,_udh,_udt,_udo="",_uu,_ufns=0,_uns=0,_ur="-",_ufno=0,_ust=0,_ujv="-",_ubd=document,_udl=_ubd.location,_uwv="6.1";
+var _ugifpath2="http://service.urchin.com/__utm.gif";
+if (_udl.protocol=="https:") _ugifpath2="https://service.urchin.com/__utm.gif";
+function urchinTracker(page) {
+ if (_udl.protocol=="file:") return;
+ if (_uff && (!page || page=="")) return;
+ var a,b,c,v,x="",s="",f=0;
+ var nx=" expires=Sun, 18 Jan 2038 00:00:00 GMT;";
+ var dc=_ubd.cookie;
+ _udh=_uDomain();
+ _uu=Math.round(Math.random()*2147483647);
+ _udt=new Date();
+ _ust=Math.round(_udt.getTime()/1000);
+ a=dc.indexOf("__utma="+_udh);
+ b=dc.indexOf("__utmb="+_udh);
+ c=dc.indexOf("__utmc="+_udh);
+ if (_udn && _udn!="") { _udo=" domain="+_udn+";"; }
+ if (_utimeout && _utimeout!="") {
+ x=new Date(_udt.getTime()+(_utimeout*1000));
+ x=" expires="+x.toGMTString()+";";
+ }
+ s=_udl.search;
+ if(s && s!="" && s.indexOf("__utma=")>=0) {
+ a=_uGC(s,"__utma=","&");
+ b=_uGC(s,"__utmb=","&");
+ c=_uGC(s,"__utmc=","&");
+ if (a!="-" && b!="-" && c!="-") f=1;
+ else if(a!="-") f=2;
+ }
+ if(f==1) {
+ _ubd.cookie="__utma="+a+"; path=/;"+nx;
+ _ubd.cookie="__utmb="+b+"; path=/;"+x;
+ _ubd.cookie="__utmc="+c+"; path=/;";
+ } else if (f==2) {
+ a=_uFixA(s,"&",_ust);
+ _ubd.cookie="__utma="+a+"; path=/;"+nx;
+ _ubd.cookie="__utmb="+_udh+"; path=/;"+x;
+ _ubd.cookie="__utmc="+_udh+"; path=/;";
+ _ufns=1;
+ } else if (a>=0 && b>=0 && c>=0) {
+ _ubd.cookie="__utmb="+_udh+"; path=/;"+x+_udo;
+ } else {
+ if (a>=0) a=_uFixA(_ubd.cookie,";",_ust);
+ else a=_udh+"."+_uu+"."+_ust+"."+_ust+"."+_ust+".1";
+ _ubd.cookie="__utma="+a+"; path=/;"+nx+_udo;
+ _ubd.cookie="__utmb="+_udh+"; path=/;"+x+_udo;
+ _ubd.cookie="__utmc="+_udh+"; path=/;"+_udo;
+ _ufns=1;
+ }
+ if (s && s!="" && s.indexOf("__utmv=")>=0) {
+ if ((v=_uGC(s,"__utmv=","&"))!="-") {
+ _ubd.cookie="__utmv="+unescape(v)+"; path=/;"+nx+_udo;
+ }
+ }
+ _uInfo(page);
+ _ufns=0;
+ _ufno=0;
+ _uff=1;
+}
+urchinTracker();
+function _uInfo(page) {
+ var p,s="",pg=_udl.pathname+_udl.search;
+ if (page && page!="") pg=escape(page);
+ _ur=_ubd.referrer;
+ if (!_ur || _ur=="") { _ur="-"; }
+ else {
+ p=_ur.indexOf(_ubd.domain);
+ if ((p>=0) && (p<=8)) { _ur="0"; }
+ if (_ur.indexOf("[")==0 && _ur.lastIndexOf("]")==(_ur.length-1)) { _ur="-"; }
+ }
+ s+="&utmn="+_uu;
+ if (_ufsc) s+=_uBInfo(page);
+ if (_uctm && (!page || page=="")) s+=_uCInfo();
+ if (_utitle && _ubd.title && _ubd.title!="") s+="&utmdt="+escape(_ubd.title);
+ if (_udl.hostname && _udl.hostname!="") s+="&utmhn="+escape(_udl.hostname);
+ if (!page || page=="") s+="&utmr="+_ur;
+ s+="&utmp="+pg;
+ if (_userv==0 || _userv==2) {
+ var i=new Image(1,1);
+ i.src=_ugifpath+"?"+"utmwv="+_uwv+s;
+ i.onload=function() {_uVoid();}
+ }
+ if (_userv==1 || _userv==2) {
+ var i2=new Image(1,1);
+ i2.src=_ugifpath2+"?"+"utmwv="+_uwv+s+"&utmac="+_uacct+"&utmcc="+_uGCS();
+ i2.onload=function() { _uVoid(); }
+ }
+ return;
+}
+function _uVoid() { return; }
+function _uCInfo() {
+ if (!_ucto || _ucto=="") { _ucto="15768000"; }
+ var c="",t="-",t2="-",o=0,cs=0,cn=0;i=0;
+ var s=_udl.search;
+ var z=_uGC(s,"__utmz=","&");
+ var x=new Date(_udt.getTime()+(_ucto*1000));
+ var dc=_ubd.cookie;
+ x=" expires="+x.toGMTString()+";";
+ if (z!="-") { _ubd.cookie="__utmz="+unescape(z)+"; path=/;"+x+_udo; return ""; }
+ z=dc.indexOf("__utmz="+_udh);
+ if (z>-1) { z=_uGC(dc,"__utmz="+_udh,";"); }
+ else { z="-"; }
+ t=_uGC(s,_ucid+"=","&");
+ t2=_uGC(s,_ucsr+"=","&");
+ if ((t!="-" && t!="") || (t2!="-" && t2!="")) {
+ if (t!="-" && t!="") { c+="utmcid="+_uEC(t); if (t2!="-" && t2!="") c+="|utmcsr="+_uEC(t2);
+ } else { if (t2!="-" && t2!="") c+="utmcsr="+_uEC(t2); }
+ t=_uGC(s,_uccn+"=","&");
+ if (t!="-" && t!="") c+="|utmccn="+_uEC(t);
+ else c+="|utmccn=(not+set)";
+ t=_uGC(s,_ucmd+"=","&");
+ if (t!="-" && t!="") c+="|utmcmd="+_uEC(t);
+ else c+="|utmcmd=(not+set)";
+ t=_uGC(s,_uctr+"=","&");
+ if (t!="-" && t!="") c+="|utmctr="+_uEC(t);
+ else { t=_uOrg(1); if (t!="-" && t!="") c+="|utmctr="+_uEC(t); }
+ t=_uGC(s,_ucct+"=","&");
+ if (t!="-" && t!="") c+="|utmcct="+_uEC(t);
+ t=_uGC(s,_ucno+"=","&");
+ if (t=="1") o=1;
+ if (z!="-" && o==1) return "";
+ }
+ if (c=="-" || c=="") { c=_uOrg(); if (z!="-" && _ufno==1) return ""; }
+ if (c=="-" || c=="") { if (_ufns==1) c=_uRef(); if (z!="-" && _ufno==1) return ""; }
+ if (c=="-" || c=="") {
+ if (z=="-" && _ufns==1) { c="utmccn=(direct)|utmcsr=(direct)|utmcmd=(none)"; }
+ if (c=="-" || c=="") return "";
+ }
+ if (z!="-") {
+ i=z.indexOf(".");
+ if (i>-1) i=z.indexOf(".",i+1);
+ if (i>-1) i=z.indexOf(".",i+1);
+ if (i>-1) i=z.indexOf(".",i+1);
+ t=z.substring(i+1,z.length);
+ if (t.toLowerCase()==c.toLowerCase()) cs=1;
+ t=z.substring(0,i);
+ if ((i=t.lastIndexOf(".")) > -1) {
+ t=t.substring(i+1,t.length);
+ cn=(t*1);
+ }
+ }
+ if (cs==0 || _ufns==1) {
+ t=_uGC(dc,"__utma="+_udh,";");
+ if ((i=t.lastIndexOf(".")) > 9) {
+ _uns=t.substring(i+1,t.length);
+ _uns=(_uns*1);
+ }
+ cn++;
+ if (_uns==0) _uns=1;
+ _ubd.cookie="__utmz="+_udh+"."+_ust+"."+_uns+"."+cn+"."+c+"; path=/; "+x+_udo;
+ }
+ if (cs==0 || _ufns==1) return "&utmcn=1";
+ else return "&utmcr=1";
+}
+function _uRef() {
+ if (_ur=="0" || _ur=="" || _ur=="-") return "";
+ var i=0,h,k,n;
+ if ((i=_ur.indexOf("://"))<0) return "";
+ h=_ur.substring(i+3,_ur.length);
+ if (h.indexOf("/") > -1) {
+ k=h.substring(h.indexOf("/"),h.length);
+ if (k.indexOf("?") > -1) k=k.substring(0,k.indexOf("?"));
+ h=h.substring(0,h.indexOf("/"));
+ }
+ h=h.toLowerCase();
+ n=h;
+ if ((i=n.indexOf(":")) > -1) n=n.substring(0,i);
+ for (var ii=0;ii<_uRno.length;ii++) {
+ if ((i=n.indexOf(_uRno[ii].toLowerCase())) > -1 && n.length==(i+_uRno[ii].length)) { _ufno=1; break; }
+ }
+ if (h.indexOf("www.")==0) h=h.substring(4,h.length);
+ return "utmccn=(referral)|utmcsr="+_uEC(h)+"|"+"utmcct="+_uEC(k)+"|utmcmd=referral";
+}
+function _uOrg(t) {
+ if (_ur=="0" || _ur=="" || _ur=="-") return "";
+ var i=0,h,k;
+ if ((i=_ur.indexOf("://")) < 0) return "";
+ h=_ur.substring(i+3,_ur.length);
+ if (h.indexOf("/") > -1) {
+ h=h.substring(0,h.indexOf("/"));
+ }
+ for (var ii=0;ii<_uOsr.length;ii++) {
+ if (h.indexOf(_uOsr[ii]) > -1) {
+ if ((i=_ur.indexOf("?"+_uOkw[ii]+"=")) > -1 || (i=_ur.indexOf("&"+_uOkw[ii]+"=")) > -1) {
+ k=_ur.substring(i+_uOkw[ii].length+2,_ur.length);
+ if ((i=k.indexOf("&")) > -1) k=k.substring(0,i);
+ for (var yy=0;yy<_uOno.length;yy++) {
+ if (_uOno[yy].toLowerCase()==k.toLowerCase()) { _ufno=1; break; }
+ }
+ if (t) return _uEC(k);
+ else return "utmccn=(organic)|utmcsr="+_uEC(_uOsr[ii])+"|"+"utmctr="+_uEC(k)+"|utmcmd=organic";
+ }
+ }
+ }
+ return "";
+}
+function _uBInfo(page) {
+ var sr="-",sc="-",ul="-",fl="-",je=1;
+ var n=navigator;
+ if (self.screen) {
+ sr=screen.width+"x"+screen.height;
+ sc=screen.colorDepth+"-bit";
+ } else if (self.java) {
+ var j=java.awt.Toolkit.getDefaultToolkit();
+ var s=j.getScreenSize();
+ sr=s.width+"x"+s.height;
+ }
+ if (_ujv=="-" && (!page || page=="")) {
+ for (var i=5;i>=0;i--) {
+ var t="<script language='JavaScript1."+i+"'>_ujv='1."+i+"';</script>";
+ _ubd.write(t);
+ if (_ujv!="-") break;
+ }
+ }
+ if (n.language) { ul=n.language.toLowerCase(); }
+ else if (n.browserLanguage) { ul=n.browserLanguage.toLowerCase(); }
+ je=n.javaEnabled()?1:0;
+ if (_uflash) fl=_uFlash();
+ return "&utmsr="+sr+"&utmsc="+sc+"&utmul="+ul+"&utmje="+je+"&utmjv="+_ujv+"&utmfl="+fl;
+}
+function __utmSetTrans() {
+ var e;
+ if (_ubd.getElementById) e=_ubd.getElementById("utmtrans");
+ else if (_ubd.utmform && _ubd.utmform.utmtrans) e=_ubd.utmform.utmtrans;
+ if (!e) return;
+ var l=e.value.split("UTM:");
+ var i,i2,c;
+ if (_userv==0 || _userv==2) i=new Array();
+ if (_userv==1 || _userv==2) { i2=new Array(); c=_uGCS(); }
+
+ for (var ii=0;ii<l.length;ii++) {
+ l[ii]=_uTrim(l[ii]);
+ if (l[ii].charAt(0)!='T' && l[ii].charAt(0)!='I') continue;
+ var r=Math.round(Math.random()*2147483647);
+ if (!_utsp || _utsp=="") _utsp="|";
+ var f=l[ii].split(_utsp),s="";
+ if (f[0].charAt(0)=='T') {
+ s="&utmt=tran"+"&utmn="+r;
+ f[1]=_uTrim(f[1]); if(f[1]&&f[1]!="") s+="&utmtid="+escape(f[1]);
+ f[2]=_uTrim(f[2]); if(f[2]&&f[2]!="") s+="&utmtst="+escape(f[2]);
+ f[3]=_uTrim(f[3]); if(f[3]&&f[3]!="") s+="&utmtto="+escape(f[3]);
+ f[4]=_uTrim(f[4]); if(f[4]&&f[4]!="") s+="&utmttx="+escape(f[4]);
+ f[5]=_uTrim(f[5]); if(f[5]&&f[5]!="") s+="&utmtsp="+escape(f[5]);
+ f[6]=_uTrim(f[6]); if(f[6]&&f[6]!="") s+="&utmtci="+escape(f[6]);
+ f[7]=_uTrim(f[7]); if(f[7]&&f[7]!="") s+="&utmtrg="+escape(f[7]);
+ f[8]=_uTrim(f[8]); if(f[8]&&f[8]!="") s+="&utmtco="+escape(f[8]);
+ } else {
+ s="&utmt=item"+"&utmn="+r;
+ f[1]=_uTrim(f[1]); if(f[1]&&f[1]!="") s+="&utmtid="+escape(f[1]);
+ f[2]=_uTrim(f[2]); if(f[2]&&f[2]!="") s+="&utmipc="+escape(f[2]);
+ f[3]=_uTrim(f[3]); if(f[3]&&f[3]!="") s+="&utmipn="+escape(f[3]);
+ f[4]=_uTrim(f[4]); if(f[4]&&f[4]!="") s+="&utmiva="+escape(f[4]);
+ f[5]=_uTrim(f[5]); if(f[5]&&f[5]!="") s+="&utmipr="+escape(f[5]);
+ f[6]=_uTrim(f[6]); if(f[6]&&f[6]!="") s+="&utmiqt="+escape(f[6]);
+ }
+ if (_userv==0 || _userv==2) {
+ i[ii]=new Image(1,1);
+ i[ii].src=_ugifpath+"?"+"utmwv="+_uwv+s;
+ i[ii].onload=function() { _uVoid(); }
+ }
+ if (_userv==1 || _userv==2) {
+ i2[ii]=new Image(1,1);
+ i2[ii].src=_ugifpath2+"?"+"utmwv="+_uwv+s+"&utmac="+_uacct+"&utmcc="+c;
+ i2[ii].onload=function() { _uVoid(); }
+ }
+ }
+ return;
+}
+function _uFlash() {
+ var f="-",n=navigator;
+ if (n.plugins && n.plugins.length) {
+ for (var ii=0;ii<n.plugins.length;ii++) {
+ if (n.plugins[ii].name.indexOf('Shockwave Flash')!=-1) {
+ f=n.plugins[ii].description.split('Shockwave Flash ')[1];
+ break;
+ }
+ }
+ } else if (window.ActiveXObject) {
+ for (var ii=10;ii>=2;ii--) {
+ try {
+ var fl=eval("new ActiveXObject('ShockwaveFlash.ShockwaveFlash."+ii+"');");
+ if (fl) { f=ii + '.0'; break; }
+ }
+ catch(e) {}
+ }
+ }
+ return f;
+}
+function __utmLinker(l) {
+ var p,a="-",b="-",c="-",z="-",v="-";
+ var dc=_ubd.cookie;
+ if (l && l!="") {
+ if (dc) {
+ a=_uGC(dc,"__utma="+_udh,";");
+ b=_uGC(dc,"__utmb="+_udh,";");
+ c=_uGC(dc,"__utmc="+_udh,";");
+ z=_uGC(dc,"__utmz="+_udh,";");
+ v=_uGC(dc,"__utmv="+_udh,";");
+ p="__utma="+a+"&__utmb="+b+"&__utmc="+c+"&__utmz="+escape(z)+"&__utmv="+escape(v);
+ }
+ if (p) {
+ if (l.indexOf("?")<=-1) { document.location=l+"?"+p; }
+ else { document.location=l+"&"+p; }
+ } else { document.location=l; }
+ }
+}
+function __utmLinkPost(f) {
+ var p,a="-",b="-",c="-",z="-",v="-";
+ var dc=_ubd.cookie;
+ if (!f || !f.action) return;
+ if (dc) {
+ a=_uGC(dc,"__utma="+_udh,";");
+ b=_uGC(dc,"__utmb="+_udh,";");
+ c=_uGC(dc,"__utmc="+_udh,";");
+ z=_uGC(dc,"__utmz="+_udh,";");
+ v=_uGC(dc,"__utmv="+_udh,";");
+ p="__utma="+a+"&__utmb="+b+"&__utmc="+c+"&__utmz="+escape(z)+"&__utmv="+escape(v);
+ }
+ if (p) {
+ if (f.action.indexOf("?")<=-1) f.action+="?"+p;
+ else f.action+="&"+p;
+ }
+ return;
+}
+function __utmSetVar(v) {
+ if (!v || v=="") return;
+ var r=Math.round(Math.random() * 2147483647);
+ _ubd.cookie="__utmv="+_udh+"."+escape(v)+"; path=/; expires=Sun, 18 Jan 2038 00:00:00 GMT;"+_udo;
+ var s="&utmt=var&utmn="+r;
+ if (_userv==0 || _userv==2) {
+ var i=new Image(1,1);
+ i.src=_ugifpath+"?"+"utmwv="+_uwv+s;
+ i.onload=function() { _uVoid(); }
+ }
+ if (_userv==1 || _userv==2) {
+ var i2=new Image(1,1);
+ i2.src=_ugifpath2+"?"+"utmwv="+_uwv+s+"&utmac="+_uacct+"&utmcc="+_uGCS();
+ i2.onload=function() { _uVoid(); }
+ }
+}
+function _uGCS() {
+ var t,c="",dc=_ubd.cookie;
+ if ((t=_uGC(dc,"__utma="+_udh,";"))!="-") c+=escape("__utma="+t+";+");
+ if ((t=_uGC(dc,"__utmb="+_udh,";"))!="-") c+=escape("__utmb="+t+";+");
+ if ((t=_uGC(dc,"__utmc="+_udh,";"))!="-") c+=escape("__utmc="+t+";+");
+ if ((t=_uGC(dc,"__utmz="+_udh,";"))!="-") c+=escape("__utmz="+t+";+");
+ if ((t=_uGC(dc,"__utmv="+_udh,";"))!="-") c+=escape("__utmv="+t+";");
+ if (c.charAt(c.length-1)=="+") c=c.substring(0,c.length-1);
+ return c;
+}
+function _uGC(l,n,s) {
+ if (!l || l=="" || !n || n=="" || !s || s=="") return "-";
+ var i,i2,i3,c="-";
+ i=l.indexOf(n);
+ i3=n.indexOf("=")+1;
+ if (i > -1) {
+ i2=l.indexOf(s,i); if (i2 < 0) { i2=l.length; }
+ c=l.substring((i+i3),i2);
+ }
+ return c;
+}
+function _uDomain() {
+ if (!_udn || _udn=="" || _udn=="none") { _udn=""; return 1; }
+ if (_udn=="auto") {
+ var d=_ubd.domain;
+ if (d.substring(0,4)=="www.") {
+ d=d.substring(4,d.length);
+ }
+ _udn=d;
+ }
+ if (_uhash=="off") return 1;
+ return _uHash(_udn);
+}
+function _uHash(d) {
+ if (!d || d=="") return 1;
+ var h=0,g=0;
+ for (var i=d.length-1;i>=0;i--) {
+ var c=parseInt(d.charCodeAt(i));
+ h=((h << 6) & 0xfffffff) + c + (c << 14);
+ if ((g=h & 0xfe00000)!=0) h=(h ^ (g >> 21));
+ }
+ return h;
+}
+function _uFixA(c,s,t) {
+ if (!c || c=="" || !s || s=="" || !t || t=="") return "-";
+ var a=_uGC(c,"__utma="+_udh,s);
+ var lt=0,i=0;
+ if ((i=a.lastIndexOf(".")) > 9) {
+ _uns=a.substring(i+1,a.length);
+ _uns=(_uns*1)+1;
+ a=a.substring(0,i);
+ if ((i=a.lastIndexOf(".")) > 7) {
+ lt=a.substring(i+1,a.length);
+ a=a.substring(0,i);
+ }
+ if ((i=a.lastIndexOf(".")) > 5) {
+ a=a.substring(0,i);
+ }
+ a+="."+lt+"."+t+"."+_uns;
+ }
+ return a;
+}
+function _uTrim(s) {
+ if (!s || s=="") return "";
+ while ((s.charAt(0)==' ') || (s.charAt(0)=='\n') || (s.charAt(0,1)=='\r')) s=s.substring(1,s.length);
+ while ((s.charAt(s.length-1)==' ') || (s.charAt(s.length-1)=='\n') || (s.charAt(s.length-1)=='\r')) s=s.substring(0,s.length-1);
+ return s;
+}
+
+function _uEC(s) {
+ var n="";
+ if (!s || s=="") return "";
+ for (var i=0;i<s.length;i++) {if (s.charAt(i)==" ") n+="+"; else n+=s.charAt(i);}
+ return n;
+}
+
+function __utmVisitorCode() {
+ var r=0,t=0,i=0,i2=0,m=31;
+ var a=_uGC(_ubd.cookie,"__utma="+_udh,";");
+ if ((i=a.indexOf(".",0))<0) return;
+ if ((i2=a.indexOf(".",i+1))>0) r=a.substring(i+1,i2); else return "";
+ if ((i=a.indexOf(".",i2+1))>0) t=a.substring(i2+1,i); else return "";
+ var c=new Array('A','B','C','D','E','F','G','H','J','K','L','M','N','P','R','S','T','U','V','W','X','Y','Z','1','2','3','4','5','6','7','8','9');
+ return c[r>>28&m]+c[r>>23&m]+c[r>>18&m]+c[r>>13&m]+"-"+c[r>>8&m]+c[r>>3&m]+c[((r&7)<<2)+(t>>30&3)]+c[t>>25&m]+c[t>>20&m]+"-"+c[t>>15&m]+c[t>>10&m]+c[t>>5&m]+c[t&m];
+}
diff --git a/site/app/webroot/js/__utm.min.js b/site/app/webroot/js/__utm.min.js
new file mode 100644
index 0000000..5b9ab8c
--- /dev/null
+++ b/site/app/webroot/js/__utm.min.js
@@ -0,0 +1 @@
+var _uacct="";var _userv=0;var _ufsc=1;var _udn="addons.mozilla.org";var _uhash="on";var _utimeout="1800";var _ugifpath="/img/__utm.gif";var _utsp="|";var _uflash=1;var _utitle=1;var _uctm=1;var _ucto="15768000";var _uccn="utm_campaign";var _ucmd="utm_medium";var _ucsr="utm_source";var _uctr="utm_term";var _ucct="utm_content";var _ucid="utm_id";var _ucno="utm_nooverride";var _uOsr=new Array();var _uOkw=new Array();_uOsr[0]="google";_uOkw[0]="q";_uOsr[1]="yahoo";_uOkw[1]="p";_uOsr[2]="msn";_uOkw[2]="q";_uOsr[3]="aol";_uOkw[3]="query";_uOsr[4]="lycos";_uOkw[4]="query";_uOsr[5]="ask";_uOkw[5]="q";_uOsr[6]="altavista";_uOkw[6]="q";_uOsr[7]="search";_uOkw[7]="q";_uOsr[8]="netscape";_uOkw[8]="query";_uOsr[9]="earthlink";_uOkw[9]="q";_uOsr[10]="cnn";_uOkw[10]="query";_uOsr[11]="looksmart";_uOkw[11]="key";_uOsr[12]="about";_uOkw[12]="terms";_uOsr[13]="excite";_uOkw[13]="qkw";_uOsr[14]="mamma";_uOkw[14]="query";_uOsr[15]="alltheweb";_uOkw[15]="q";_uOsr[16]="gigablast";_uOkw[16]="q";_uOsr[17]="voila";_uOkw[17]="kw";_uOsr[18]="virgilio";_uOkw[18]="qs";_uOsr[19]="teoma";_uOkw[19]="q";var _uOno=new Array();var _uRno=new Array();var _uff,_udh,_udt,_udo="",_uu,_ufns=0,_uns=0,_ur="-",_ufno=0,_ust=0,_ujv="-",_ubd=document,_udl=_ubd.location,_uwv="6.1";var _ugifpath2="http://service.urchin.com/__utm.gif";if(_udl.protocol=="https:"){_ugifpath2="https://service.urchin.com/__utm.gif"}function urchinTracker(C){if(_udl.protocol=="file:"){return }if(_uff&&(!C||C=="")){return }var G,E,D,H,F="",J="",B=0;var A=" expires=Sun, 18 Jan 2038 00:00:00 GMT;";var I=_ubd.cookie;_udh=_uDomain();_uu=Math.round(Math.random()*2147483647);_udt=new Date();_ust=Math.round(_udt.getTime()/1000);G=I.indexOf("__utma="+_udh);E=I.indexOf("__utmb="+_udh);D=I.indexOf("__utmc="+_udh);if(_udn&&_udn!=""){_udo=" domain="+_udn+";"}if(_utimeout&&_utimeout!=""){F=new Date(_udt.getTime()+(_utimeout*1000));F=" expires="+F.toGMTString()+";"}J=_udl.search;if(J&&J!=""&&J.indexOf("__utma=")>=0){G=_uGC(J,"__utma=","&");E=_uGC(J,"__utmb=","&");D=_uGC(J,"__utmc=","&");if(G!="-"&&E!="-"&&D!="-"){B=1}else{if(G!="-"){B=2}}}if(B==1){_ubd.cookie="__utma="+G+"; path=/;"+A;_ubd.cookie="__utmb="+E+"; path=/;"+F;_ubd.cookie="__utmc="+D+"; path=/;"}else{if(B==2){G=_uFixA(J,"&",_ust);_ubd.cookie="__utma="+G+"; path=/;"+A;_ubd.cookie="__utmb="+_udh+"; path=/;"+F;_ubd.cookie="__utmc="+_udh+"; path=/;";_ufns=1}else{if(G>=0&&E>=0&&D>=0){_ubd.cookie="__utmb="+_udh+"; path=/;"+F+_udo}else{if(G>=0){G=_uFixA(_ubd.cookie,";",_ust)}else{G=_udh+"."+_uu+"."+_ust+"."+_ust+"."+_ust+".1"}_ubd.cookie="__utma="+G+"; path=/;"+A+_udo;_ubd.cookie="__utmb="+_udh+"; path=/;"+F+_udo;_ubd.cookie="__utmc="+_udh+"; path=/;"+_udo;_ufns=1}}}if(J&&J!=""&&J.indexOf("__utmv=")>=0){if((H=_uGC(J,"__utmv=","&"))!="-"){_ubd.cookie="__utmv="+unescape(H)+"; path=/;"+A+_udo}}_uInfo(C);_ufns=0;_ufno=0;_uff=1}urchinTracker();function _uInfo(D){var E,C="",F=_udl.pathname+_udl.search;if(D&&D!=""){F=escape(D)}_ur=_ubd.referrer;if(!_ur||_ur==""){_ur="-"}else{E=_ur.indexOf(_ubd.domain);if((E>=0)&&(E<=8)){_ur="0"}if(_ur.indexOf("[")==0&&_ur.lastIndexOf("]")==(_ur.length-1)){_ur="-"}}C+="&utmn="+_uu;if(_ufsc){C+=_uBInfo(D)}if(_uctm&&(!D||D=="")){C+=_uCInfo()}if(_utitle&&_ubd.title&&_ubd.title!=""){C+="&utmdt="+escape(_ubd.title)}if(_udl.hostname&&_udl.hostname!=""){C+="&utmhn="+escape(_udl.hostname)}if(!D||D==""){C+="&utmr="+_ur}C+="&utmp="+F;if(_userv==0||_userv==2){var A=new Image(1,1);A.src=_ugifpath+"?utmwv="+_uwv+C;A.onload=function(){_uVoid()}}if(_userv==1||_userv==2){var B=new Image(1,1);B.src=_ugifpath2+"?utmwv="+_uwv+C+"&utmac="+_uacct+"&utmcc="+_uGCS();B.onload=function(){_uVoid()}}return }function _uVoid(){return }function _uCInfo(){if(!_ucto||_ucto==""){_ucto="15768000"}var E="",I="-",B="-",A=0,C=0,G=0;i=0;var J=_udl.search;var D=_uGC(J,"__utmz=","&");var F=new Date(_udt.getTime()+(_ucto*1000));var H=_ubd.cookie;F=" expires="+F.toGMTString()+";";if(D!="-"){_ubd.cookie="__utmz="+unescape(D)+"; path=/;"+F+_udo;return""}D=H.indexOf("__utmz="+_udh);if(D>-1){D=_uGC(H,"__utmz="+_udh,";")}else{D="-"}I=_uGC(J,_ucid+"=","&");B=_uGC(J,_ucsr+"=","&");if((I!="-"&&I!="")||(B!="-"&&B!="")){if(I!="-"&&I!=""){E+="utmcid="+_uEC(I);if(B!="-"&&B!=""){E+="|utmcsr="+_uEC(B)}}else{if(B!="-"&&B!=""){E+="utmcsr="+_uEC(B)}}I=_uGC(J,_uccn+"=","&");if(I!="-"&&I!=""){E+="|utmccn="+_uEC(I)}else{E+="|utmccn=(not+set)"}I=_uGC(J,_ucmd+"=","&");if(I!="-"&&I!=""){E+="|utmcmd="+_uEC(I)}else{E+="|utmcmd=(not+set)"}I=_uGC(J,_uctr+"=","&");if(I!="-"&&I!=""){E+="|utmctr="+_uEC(I)}else{I=_uOrg(1);if(I!="-"&&I!=""){E+="|utmctr="+_uEC(I)}}I=_uGC(J,_ucct+"=","&");if(I!="-"&&I!=""){E+="|utmcct="+_uEC(I)}I=_uGC(J,_ucno+"=","&");if(I=="1"){A=1}if(D!="-"&&A==1){return""}}if(E=="-"||E==""){E=_uOrg();if(D!="-"&&_ufno==1){return""}}if(E=="-"||E==""){if(_ufns==1){E=_uRef()}if(D!="-"&&_ufno==1){return""}}if(E=="-"||E==""){if(D=="-"&&_ufns==1){E="utmccn=(direct)|utmcsr=(direct)|utmcmd=(none)"}if(E=="-"||E==""){return""}}if(D!="-"){i=D.indexOf(".");if(i>-1){i=D.indexOf(".",i+1)}if(i>-1){i=D.indexOf(".",i+1)}if(i>-1){i=D.indexOf(".",i+1)}I=D.substring(i+1,D.length);if(I.toLowerCase()==E.toLowerCase()){C=1}I=D.substring(0,i);if((i=I.lastIndexOf("."))>-1){I=I.substring(i+1,I.length);G=(I*1)}}if(C==0||_ufns==1){I=_uGC(H,"__utma="+_udh,";");if((i=I.lastIndexOf("."))>9){_uns=I.substring(i+1,I.length);_uns=(_uns*1)}G++;if(_uns==0){_uns=1}_ubd.cookie="__utmz="+_udh+"."+_ust+"."+_uns+"."+G+"."+E+"; path=/; "+F+_udo}if(C==0||_ufns==1){return"&utmcn=1"}else{return"&utmcr=1"}}function _uRef(){if(_ur=="0"||_ur==""||_ur=="-"){return""}var B=0,D,A,E;if((B=_ur.indexOf("://"))<0){return""}D=_ur.substring(B+3,_ur.length);if(D.indexOf("/")>-1){A=D.substring(D.indexOf("/"),D.length);if(A.indexOf("?")>-1){A=A.substring(0,A.indexOf("?"))}D=D.substring(0,D.indexOf("/"))}D=D.toLowerCase();E=D;if((B=E.indexOf(":"))>-1){E=E.substring(0,B)}for(var C=0;C<_uRno.length;C++){if((B=E.indexOf(_uRno[C].toLowerCase()))>-1&&E.length==(B+_uRno[C].length)){_ufno=1;break}}if(D.indexOf("www.")==0){D=D.substring(4,D.length)}return"utmccn=(referral)|utmcsr="+_uEC(D)+"|utmcct="+_uEC(A)+"|utmcmd=referral"}function _uOrg(C){if(_ur=="0"||_ur==""||_ur=="-"){return""}var B=0,E,A;if((B=_ur.indexOf("://"))<0){return""}E=_ur.substring(B+3,_ur.length);if(E.indexOf("/")>-1){E=E.substring(0,E.indexOf("/"))}for(var D=0;D<_uOsr.length;D++){if(E.indexOf(_uOsr[D])>-1){if((B=_ur.indexOf("?"+_uOkw[D]+"="))>-1||(B=_ur.indexOf("&"+_uOkw[D]+"="))>-1){A=_ur.substring(B+_uOkw[D].length+2,_ur.length);if((B=A.indexOf("&"))>-1){A=A.substring(0,B)}for(var F=0;F<_uOno.length;F++){if(_uOno[F].toLowerCase()==A.toLowerCase()){_ufno=1;break}}if(C){return _uEC(A)}else{return"utmccn=(organic)|utmcsr="+_uEC(_uOsr[D])+"|utmctr="+_uEC(A)+"|utmcmd=organic"}}}}return""}function _uBInfo(F){var A="-",G="-",E="-",I="-",H=1;var B=navigator;if(self.screen){A=screen.width+"x"+screen.height;G=screen.colorDepth+"-bit"}else{if(self.java){var C=java.awt.Toolkit.getDefaultToolkit();var K=C.getScreenSize();A=K.width+"x"+K.height}}if(_ujv=="-"&&(!F||F=="")){for(var D=5;D>=0;D--){var J="<script language='JavaScript1."+D+"'>_ujv='1."+D+"';<\/script>";_ubd.write(J);if(_ujv!="-"){break}}}if(B.language){E=B.language.toLowerCase()}else{if(B.browserLanguage){E=B.browserLanguage.toLowerCase()}}H=B.javaEnabled()?1:0;if(_uflash){I=_uFlash()}return"&utmsr="+A+"&utmsc="+G+"&utmul="+E+"&utmje="+H+"&utmjv="+_ujv+"&utmfl="+I}function __utmSetTrans(){var F;if(_ubd.getElementById){F=_ubd.getElementById("utmtrans")}else{if(_ubd.utmform&&_ubd.utmform.utmtrans){F=_ubd.utmform.utmtrans}}if(!F){return }var B=F.value.split("UTM:");var D,C,G;if(_userv==0||_userv==2){D=new Array()}if(_userv==1||_userv==2){C=new Array();G=_uGCS()}for(var H=0;H<B.length;H++){B[H]=_uTrim(B[H]);if(B[H].charAt(0)!="T"&&B[H].charAt(0)!="I"){continue}var A=Math.round(Math.random()*2147483647);if(!_utsp||_utsp==""){_utsp="|"}var E=B[H].split(_utsp),I="";if(E[0].charAt(0)=="T"){I="&utmt=tran&utmn="+A;E[1]=_uTrim(E[1]);if(E[1]&&E[1]!=""){I+="&utmtid="+escape(E[1])}E[2]=_uTrim(E[2]);if(E[2]&&E[2]!=""){I+="&utmtst="+escape(E[2])}E[3]=_uTrim(E[3]);if(E[3]&&E[3]!=""){I+="&utmtto="+escape(E[3])}E[4]=_uTrim(E[4]);if(E[4]&&E[4]!=""){I+="&utmttx="+escape(E[4])}E[5]=_uTrim(E[5]);if(E[5]&&E[5]!=""){I+="&utmtsp="+escape(E[5])}E[6]=_uTrim(E[6]);if(E[6]&&E[6]!=""){I+="&utmtci="+escape(E[6])}E[7]=_uTrim(E[7]);if(E[7]&&E[7]!=""){I+="&utmtrg="+escape(E[7])}E[8]=_uTrim(E[8]);if(E[8]&&E[8]!=""){I+="&utmtco="+escape(E[8])}}else{I="&utmt=item&utmn="+A;E[1]=_uTrim(E[1]);if(E[1]&&E[1]!=""){I+="&utmtid="+escape(E[1])}E[2]=_uTrim(E[2]);if(E[2]&&E[2]!=""){I+="&utmipc="+escape(E[2])}E[3]=_uTrim(E[3]);if(E[3]&&E[3]!=""){I+="&utmipn="+escape(E[3])}E[4]=_uTrim(E[4]);if(E[4]&&E[4]!=""){I+="&utmiva="+escape(E[4])}E[5]=_uTrim(E[5]);if(E[5]&&E[5]!=""){I+="&utmipr="+escape(E[5])}E[6]=_uTrim(E[6]);if(E[6]&&E[6]!=""){I+="&utmiqt="+escape(E[6])}}if(_userv==0||_userv==2){D[H]=new Image(1,1);D[H].src=_ugifpath+"?utmwv="+_uwv+I;D[H].onload=function(){_uVoid()}}if(_userv==1||_userv==2){C[H]=new Image(1,1);C[H].src=_ugifpath2+"?utmwv="+_uwv+I+"&utmac="+_uacct+"&utmcc="+G;C[H].onload=function(){_uVoid()}}}return }function _uFlash(){var f="-",n=navigator;if(n.plugins&&n.plugins.length){for(var ii=0;ii<n.plugins.length;ii++){if(n.plugins[ii].name.indexOf("Shockwave Flash")!=-1){f=n.plugins[ii].description.split("Shockwave Flash ")[1];break}}}else{if(window.ActiveXObject){for(var ii=10;ii>=2;ii--){try{var fl=eval("new ActiveXObject('ShockwaveFlash.ShockwaveFlash."+ii+"');");if(fl){f=ii+".0";break}}catch(e){}}}}return f}function __utmLinker(D){var F,C="-",A="-",H="-",G="-",E="-";var B=_ubd.cookie;if(D&&D!=""){if(B){C=_uGC(B,"__utma="+_udh,";");A=_uGC(B,"__utmb="+_udh,";");H=_uGC(B,"__utmc="+_udh,";");G=_uGC(B,"__utmz="+_udh,";");E=_uGC(B,"__utmv="+_udh,";");F="__utma="+C+"&__utmb="+A+"&__utmc="+H+"&__utmz="+escape(G)+"&__utmv="+escape(E)}if(F){if(D.indexOf("?")<=-1){document.location=D+"?"+F}else{document.location=D+"&"+F}}else{document.location=D}}}function __utmLinkPost(E){var F,C="-",A="-",H="-",G="-",D="-";var B=_ubd.cookie;if(!E||!E.action){return }if(B){C=_uGC(B,"__utma="+_udh,";");A=_uGC(B,"__utmb="+_udh,";");H=_uGC(B,"__utmc="+_udh,";");G=_uGC(B,"__utmz="+_udh,";");D=_uGC(B,"__utmv="+_udh,";");F="__utma="+C+"&__utmb="+A+"&__utmc="+H+"&__utmz="+escape(G)+"&__utmv="+escape(D)}if(F){if(E.action.indexOf("?")<=-1){E.action+="?"+F}else{E.action+="&"+F}}return }function __utmSetVar(A){if(!A||A==""){return }var E=Math.round(Math.random()*2147483647);_ubd.cookie="__utmv="+_udh+"."+escape(A)+"; path=/; expires=Sun, 18 Jan 2038 00:00:00 GMT;"+_udo;var D="&utmt=var&utmn="+E;if(_userv==0||_userv==2){var B=new Image(1,1);B.src=_ugifpath+"?utmwv="+_uwv+D;B.onload=function(){_uVoid()}}if(_userv==1||_userv==2){var C=new Image(1,1);C.src=_ugifpath2+"?utmwv="+_uwv+D+"&utmac="+_uacct+"&utmcc="+_uGCS();C.onload=function(){_uVoid()}}}function _uGCS(){var B,C="",A=_ubd.cookie;if((B=_uGC(A,"__utma="+_udh,";"))!="-"){C+=escape("__utma="+B+";+")}if((B=_uGC(A,"__utmb="+_udh,";"))!="-"){C+=escape("__utmb="+B+";+")}if((B=_uGC(A,"__utmc="+_udh,";"))!="-"){C+=escape("__utmc="+B+";+")}if((B=_uGC(A,"__utmz="+_udh,";"))!="-"){C+=escape("__utmz="+B+";+")}if((B=_uGC(A,"__utmv="+_udh,";"))!="-"){C+=escape("__utmv="+B+";")}if(C.charAt(C.length-1)=="+"){C=C.substring(0,C.length-1)}return C}function _uGC(A,G,E){if(!A||A==""||!G||G==""||!E||E==""){return"-"}var C,D,B,F="-";C=A.indexOf(G);B=G.indexOf("=")+1;if(C>-1){D=A.indexOf(E,C);if(D<0){D=A.length}F=A.substring((C+B),D)}return F}function _uDomain(){if(!_udn||_udn==""||_udn=="none"){_udn="";return 1}if(_udn=="auto"){var A=_ubd.domain;if(A.substring(0,4)=="www."){A=A.substring(4,A.length)}_udn=A}if(_uhash=="off"){return 1}return _uHash(_udn)}function _uHash(D){if(!D||D==""){return 1}var B=0,C=0;for(var A=D.length-1;A>=0;A--){var E=parseInt(D.charCodeAt(A));B=((B<<6)&268435455)+E+(E<<14);if((C=B&266338304)!=0){B=(B^(C>>21))}}return B}function _uFixA(F,E,D){if(!F||F==""||!E||E==""||!D||D==""){return"-"}var B=_uGC(F,"__utma="+_udh,E);var A=0,C=0;if((C=B.lastIndexOf("."))>9){_uns=B.substring(C+1,B.length);_uns=(_uns*1)+1;B=B.substring(0,C);if((C=B.lastIndexOf("."))>7){A=B.substring(C+1,B.length);B=B.substring(0,C)}if((C=B.lastIndexOf("."))>5){B=B.substring(0,C)}B+="."+A+"."+D+"."+_uns}return B}function _uTrim(A){if(!A||A==""){return""}while((A.charAt(0)==" ")||(A.charAt(0)=="\n")||(A.charAt(0,1)=="\r")){A=A.substring(1,A.length)}while((A.charAt(A.length-1)==" ")||(A.charAt(A.length-1)=="\n")||(A.charAt(A.length-1)=="\r")){A=A.substring(0,A.length-1)}return A}function _uEC(B){var C="";if(!B||B==""){return""}for(var A=0;A<B.length;A++){if(B.charAt(A)==" "){C+="+"}else{C+=B.charAt(A)}}return C}function __utmVisitorCode(){var F=0,D=0,C=0,E=0,A=31;var B=_uGC(_ubd.cookie,"__utma="+_udh,";");if((C=B.indexOf(".",0))<0){return }if((E=B.indexOf(".",C+1))>0){F=B.substring(C+1,E)}else{return""}if((C=B.indexOf(".",E+1))>0){D=B.substring(E+1,C)}else{return""}var G=new Array("A","B","C","D","E","F","G","H","J","K","L","M","N","P","R","S","T","U","V","W","X","Y","Z","1","2","3","4","5","6","7","8","9");return G[F>>28&A]+G[F>>23&A]+G[F>>18&A]+G[F>>13&A]+"-"+G[F>>8&A]+G[F>>3&A]+G[((F&7)<<2)+(D>>30&3)]+G[D>>25&A]+G[D>>20&A]+"-"+G[D>>15&A]+G[D>>10&A]+G[D>>5&A]+G[D&A]}; \ No newline at end of file
diff --git a/site/app/webroot/js/addons.js b/site/app/webroot/js/addons.js
new file mode 100644
index 0000000..ec3b2f6
--- /dev/null
+++ b/site/app/webroot/js/addons.js
@@ -0,0 +1,1830 @@
+/* Addons display js */
+var gPlatform = PLATFORM_WINDOWS;
+var gLatestVersionID = null; //latest version ID of any compatible addon for versions page.
+var gLatestAddonVersion = null; //addon version of latest compatible addon for versions page.
+var gLatestAppVersion = null; //application version of latest compatible addon for versions page.
+
+var PLATFORM_OTHER = 0;
+var PLATFORM_WINDOWS = 1;
+var PLATFORM_LINUX = 2;
+var PLATFORM_MACOSX = 3;
+var PLATFORM_MAC = 4;
+
+if (navigator.platform.indexOf("Win32") != -1)
+ gPlatform = PLATFORM_WINDOWS;
+else if (navigator.platform.indexOf("Linux") != -1)
+ gPlatform = PLATFORM_LINUX;
+else if (navigator.userAgent.indexOf("Mac OS X") != -1)
+ gPlatform = PLATFORM_MACOSX;
+else if (navigator.userAgent.indexOf("MSIE 5.2") != -1)
+ gPlatform = PLATFORM_MACOSX;
+else if (navigator.platform.indexOf("Mac") != -1)
+ gPlatform = PLATFORM_MAC;
+else
+ gPlatform = PLATFORM_OTHER;
+
+function getPlatformName()
+{
+ if (gPlatform == PLATFORM_WINDOWS)
+ return "Windows";
+ if (gPlatform == PLATFORM_LINUX)
+ return "Linux";
+ if (gPlatform == PLATFORM_MACOSX)
+ return "MacOSX";
+ return "Unknown";
+}
+
+function getInstallURL(aEvent) {
+ // The event target might be the link itself or one of its children
+ var target = aEvent.target;
+ while (target && !target.href)
+ target = target.parentNode;
+
+ return target && target.href;
+}
+
+function checkMatchUserAgentAppId() {
+ var uapattern = /(?:Firefox|Minefield|Shiretoko|GranParadiso|BonEcho|Iceweasel)/;
+ var ua = navigator.userAgent;
+ var uamatch = uapattern.exec(ua);
+
+ if( uamatch !=null && APP_ID == 1) return true;
+
+ uapattern = /(SeaMonkey|Iceape)/;
+ ua = navigator.userAgent;
+ uamatch = uapattern.exec(ua);
+ if( uamatch !=null && APP_ID == 59) return true;
+
+ return false;
+
+}
+
+/**
+ * Install an add-on into the current browser-type application
+ * (mostly: Firefox, SeaMonkey)
+ */
+function install( aEvent, extName, iconURL, extHash) {
+
+ if (aEvent.altKey || !window.InstallTrigger || !checkMatchUserAgentAppId())
+ return true;
+
+ var url = getInstallURL(aEvent);
+
+ if (url) {
+
+ var params = new Array();
+
+ params[extName] = {
+ URL: url,
+ IconURL: iconURL,
+ toString: function () { return this.URL; }
+ };
+
+ // Only add the Hash param if it exists.
+ //
+ // We optionally add this to params[] because installTrigger
+ // will still try to compare a null hash as long as the var is set.
+ if (extHash) {
+ params[extName].Hash = extHash;
+ }
+
+ InstallTrigger.install(params);
+
+ return false;
+ }
+ return true;
+}
+
+/**
+ * Install a search engine (opensearch)
+ * Returns false in case of success (sic!) because that will keep the file link
+ * from being followed.
+ */
+function addEngine(engineURL) {
+ if (window.external && ("AddSearchProvider" in window.external)) {
+ window.external.AddSearchProvider(engineURL);
+ return false;
+ } else {
+ alert(error_opensearch_unsupported);
+ return true;
+ }
+}
+
+/**
+ * Detect which install button should show, and hide the rest
+ */
+function fixPlatformLinks(versionID, name) {
+ if (gPlatform == PLATFORM_OTHER) return true; // only hide something if we were able to detect platforms
+ var platform = getPlatformName();
+ var outer = $("#install-"+ versionID);
+ var installs = outer.find("p.install-button");
+
+ // hide incompatible installs
+ var others = installs.not(".platform-ALL,.platform-"+platform);
+ others.hide();
+ others.each(function() {
+ var expParents = $(this).parents('.exp-loggedout, .exp-confirmed');
+ if ($(expParents).length)
+ $(expParents).hide();
+ else
+ $(this).hide();
+ });
+
+
+ if (installs.length == others.length) {
+ outer.find(".exp-loggedout").hide();
+ outer.append($('<p class="not-avail"></p>').append(sprintf(addOnNotAvailableForPlatform, name, platform)));
+ }
+
+ return true;
+}
+
+/**
+* Used to select between the string Add to App and Download depending on whether Firefox is the UA
+*/
+function installVersusDownloadCheck(triggerID, installString, downloadString)
+{
+ var buttonMessage = installString;
+ var uapattern = /Mozilla.*(Firefox|Minefield|Shiretoko|GranParadiso|BonEcho|SeaMonkey|Iceweasel|Iceape)\/.*$/;
+ var ua = navigator.userAgent;
+ var uamatch = uapattern.exec(ua);
+ if (!uamatch || uamatch.length < 2 || !checkMatchUserAgentAppId()) // not a Firefox-like browser
+ buttonMessage = downloadString;
+ $("#" + triggerID + " strong").text(buttonMessage);
+}
+
+/**
+ * Provide hints on install buttons for add-ons incompatible with the
+ * currently used browser.
+ *
+ * It has the side-effect that the first time it is called on a page and doesn't need to add hints, it will
+ * set gLatestVersion to the passed versionID
+ *
+ * @param int addonID
+ * @param int versionID
+ * @param string fromVer minimum compatible Firefox version
+ * @param string toVer maximum compatible Firefox version
+ * @param bool showVersionLink offer a link to the user which will remove the compatibility hint (and allow them to download the add-on)
+ * @param bool versionsPage whether the user is viewing /addons/versions/$id . Why is this here instead of just not calling
+ * addCompatibilityHints() if we don't want it in /views/addons/versions.thtml?
+ */
+function addCompatibilityHints(addonID, versionID, fromVer, toVer, showVersionLink, versionsPage) {
+ var uapattern = /Mozilla.*(?:Firefox|Minefield|Shiretoko|GranParadiso|BonEcho|Iceweasel)\/([^\s]*).*$/;
+ var ua = navigator.userAgent;
+ var uamatch = uapattern.exec(ua);
+ if (!uamatch || uamatch.length < 2) return true;
+
+ var outer = $("#install-"+ versionID);
+
+ var version = uamatch[1];
+ var vc = new VersionCompare();
+ if (vc.compareVersions(version, fromVer)<0)
+ var needUpgrade = true;
+ else if(vc.compareVersions(version, toVer)>0)
+ var needUpgrade = false;
+ else { //check if this is the first time on the page we have a platform and version compatitble addon
+ if( gLatestVersionID == null) {
+ var installs = outer.find("p.install-button");
+ if (installs.find(".platform-ALL") || installs.find(".platform-"+gPlatform)) {
+ gLatestVersionID = versionID;
+ var tmpAddonVersion = outer.prev().prev().prev();
+ gLatestAddonVersion = tmpAddonVersion.clone();
+ gLatestApplicationVersion = version;
+ }
+ }
+ return true;
+ }
+
+ if(versionsPage) return true;
+
+ var links = outer.find("p:visible a"); // find visible install boxes
+ if (links.length == 0) return true; // nothing to do
+
+ // duplicate button and hide original (to be able to restore it later)
+ var cloned = outer.clone();
+ cloned.attr('id', 'orig-'+ versionID);
+ cloned.hide();
+ outer.after(cloned);
+
+ // wrap and gray out buttons
+ // skip experimental confirmation dialogs
+ $(links).each(function () {
+
+ var exp_confirm = $(this).parents('.exp-loggedout');
+ if (exp_confirm.length) {
+ $(exp_confirm).find('.exp-confirm-install').hide();
+ return;
+ }
+
+ // gray out button
+ var mydiv = document.createElement('div');
+ mydiv.setAttribute('class', 'exp-loggedout');
+ outer.wrapInner(mydiv);
+ });
+
+ // remove link
+ var url = links.attr('href');
+ links.removeAttr("href");
+ links.removeAttr("onClick");
+ links.removeAttr("title");
+ links.css('cursor', 'default');
+ links.parent().css('float', 'none');
+ // freeze button
+ links.attr('frozen', 'true');
+
+ // determine "all versions" page url
+ if (url.indexOf('downloads') > 0)
+ url = url.substring(0, url.indexOf('downloads'));
+ else if (url.indexOf('addons') > 0)
+ url = url.substring(0, url.indexOf('addons'));
+ url = url+'addons/versions/'+addonID;
+
+
+ if (needUpgrade && showVersionLink) {
+ links.parent().after(sprintf(app_compat_older_version_or_ignore_check, url, "removeCompatibilityHint("+versionID+");return false;"));
+ } else if (!needUpgrade && showVersionLink) {
+ links.parent().after('<br /><a href="#" onclick="removeCompatibilityHint(\''+versionID+'\');return false;">' +app_compat_ignore_check+ '</a>');
+ links.parent().after(app_compat_older_firefox_only);
+ } else if (!needUpgrade) {
+ links.parent().after(app_compat_older_firefox_only);
+ } else {
+ links.parent().after(sprintf(app_compat_try_old_version, url));
+ }
+
+ if (needUpgrade) {
+ if (vc.compareVersions(fromVer, LATEST_FIREFOX_DEVEL_VERSION)>=0) {
+ links.parent().after(sprintf("<strong>" + app_compat_unreleased_version + "</strong><br />", 'http://www.mozilla.com/' + LANG + '/firefox/all-beta.html#' + LANG, LATEST_FIREFOX_DEVEL_VERSION));
+ }else if (vc.compareVersions(fromVer, LATEST_FIREFOX_VERSION)<0) {
+ links.parent().after(sprintf("<strong>" + app_compat_update_firefox + "</strong><br />", 'http://www.mozilla.com/' + LANG + '/firefox/all.html#' + LANG, LATEST_FIREFOX_VERSION));
+ }
+ }
+
+ return true;
+}
+
+/**
+ * Remove "incompatible" message for given version ID, by restoring the
+ * original button.
+ */
+function removeCompatibilityHint(versionID) {
+ // find all hidden install buttons
+ var orig = $('#orig-' + versionID);
+ // remove compatibility hints
+ orig.prev().remove();
+ // show original buttons
+ orig.attr('id', 'install-'+versionID);
+
+ orig.show();
+
+ return true;
+}
+
+/**
+ * This function is used on the addon version page to create an element
+ * at the top of the page with the most recent compatible version of an addon
+ */
+function createLatestVersionElement(get_latest_version_text, app) {
+ var container = $("#latest-version-container");
+ container.wrapInner("<p>" + sprintf(get_latest_version_text, app, gLatestApplicationVersion) + "</p>");
+ container.append(gLatestAddonVersion);
+ var installButton = $("#install-"+ gLatestVersionID);
+ var cloned = installButton.clone();
+ cloned.attr('id', 'install-0'+ gLatestVersionID); // prepend 0 to this version id to make unique
+ container.append(cloned);
+ container.attr('id', 'latest-version');
+ fixPlatformLinks("0"+ gLatestVersionID, ""); // show only one platform when dealing with most recent compatible app.
+}
+
+/**
+ * replaces options in a select drop-down (used for advanced search)
+ * @param select_id - the id of the select tag to replace the options of
+ * @param opt_array - array of options to use
+ * @param selected - which option will be marked as selected
+ *
+ */
+function replaceOptions( select_id , opt_array, selected) {
+ $(select_id + " > *").remove();
+
+ for( opt in opt_array) {
+ sel_text = "";
+ val = opt_array[opt];
+ opt_obj = document.createElement("option");
+ if( val == selected) {opt_obj.selected = "selected";}
+ opt_obj.value = val;
+ opt_obj.appendChild(document.createTextNode(opt));
+ $(select_id).append(opt_obj);
+ }
+}
+
+/**
+ * replace noscript email by an actual link
+ * @param obj id of email node
+ * @param lp local part
+ * @param hp host part
+ */
+function emailLink(obj, lp, hp) {
+ var cont = document.getElementById(obj);
+ var em = lp +'@'+ hp;
+ var a = document.createElement('a');
+ a.setAttribute('href', 'mailto:'+em);
+ a.appendChild(document.createTextNode(em));
+ cont.replaceChild(a, cont.lastChild);
+}
+
+var translation_box = {
+ switchLocale: function(tab, locale) {
+ var translationBox = $(tab).parent().parent().parent();
+ if (translationBox.find('.translation-deletelocale').size() > 0) {
+ return;
+ }
+ translationBox.find('.selected').removeClass('selected');
+ $(tab).addClass('selected');
+ translationBox.find('.' + locale).addClass('selected');
+ this.checkDeleteButton(translationBox);
+ translationBox.find('.translation-area .input.selected').trigger('onchange');
+ translationBox.find('.' + locale).focus();
+ },
+
+ checkDeleteButton: function(translationBox) {
+ var defaultLocale = translationBox.find('.translation-area').attr('defaultLocale');
+ var selectedLocale = translationBox.find('.translation-tab.selected').text();
+ if (selectedLocale == defaultLocale || selectedLocale == '') {
+ translationBox.find('.translation-button.remove').hide();
+ }
+ else {
+ translationBox.find('.translation-button.remove').show();
+ }
+ },
+
+ checkLength: function(field, max) {
+ var translationBox = $(field).parent().parent();
+ translationBox.find('.translation-maxlength.selected span').text(field.value.length);
+
+ if (field.value.length > max) {
+ translationBox.find('.translation-maxlength.selected').addClass('over');
+ translationBox.addClass('errors');
+ }
+ else {
+ translationBox.find('.translation-maxlength.selected').removeClass('over');
+
+ if (translationBox.find('.translation-area .over').size() == 0) {
+ translationBox.removeClass('errors');
+ }
+ }
+ },
+
+ addTab: function(button) {
+ var translationBox = $(button).parent().parent().parent();
+ if (translationBox.find('.translation-deletelocale').size() > 0) {
+ return;
+ }
+
+ if (translationBox.find('.translation-tab').hasClass('new')) {
+ translationBox.find('.selected').removeClass('selected');
+ translationBox.find('.new').addClass('selected');
+ return;
+ }
+
+ var tab = '<div class="translation-tab selected new" onclick="translation_box.switchLocale(this, \'new\');"></div>';
+ translationBox.find('.selected').removeClass('selected');
+ translationBox.find('.translation-tabs').append(tab);
+ translationBox.find('.translation-area').append($('.translation-newlocale-container').html());
+
+ // Remove existing translations from available dropdown
+ translationBox.find('.translation-tab:not(.new)').each(function(index, item) {
+ translationBox.find('.translation-newlocale select option[value="' + $(item).text() + '"]').remove();
+ });
+ this.checkDeleteButton(translationBox);
+ },
+
+ addLocale: function(button, addToAll) {
+ var translationBox = $(button).parent().parent().parent().parent().parent();
+ var thisBox = translationBox;
+ if (addToAll == true) {
+ translationBox = translationBox.parent();
+ }
+
+ var locale = thisBox.find('select').val();
+ var localeName = thisBox.find('select option:selected').text();
+
+ var tab = '<div class="translation-tab selected" title="' + localeName + '" onclick="translation_box.switchLocale(this, \'' + locale + '\');">' + locale + '</div>';
+
+ translationBox.find('.input.' + locale + '.deleted').remove();
+ translationBox.find('.translation-area:not(:has(.' + locale + '))').each(function(index, item) {
+ var itemID = $(item).attr('itemID');
+ var field = 'data[' + $(item).attr('table') + ']' + (itemID != null ? '[' + itemID + ']' : '') + '[' + $(item).attr('field') + '][' + locale + ']';
+ $(item).parent().find('.selected').removeClass('selected');
+
+ var fieldType = $(item).find('.input')[0].tagName.toLowerCase();
+ var style = $(item).find('.input').attr('style');
+
+ if (fieldType == 'textarea') {
+ var fieldHTML = '<textarea class="input ' + locale + ' selected" name="' + field + '" style="' + style + '"';
+ var maxLength = $(item).find('.input').attr('maxLength');
+ if (maxLength) {
+ fieldHTML += ' maxLength="' + maxLength + '" onkeyup="translation_box.checkLength(this, ' + maxLength + ');" onchange="translation_box.checkLength(this, ' + maxLength + ');"';
+ var afterHTML = '<div class="translation-maxlength ' + locale + ' selected">' + $(item).find('.translation-maxlength').html() + '</div>';
+ }
+ fieldHTML += '></textarea>';
+ }
+ else if (fieldType == 'input') {
+ var fieldHTML = '<input type="text" class="input ' + locale + ' selected" value="" name="' + field + '" style="' + style + '" />';
+ var afterHTML = '';
+ }
+ $(item).append(fieldHTML).append(afterHTML);
+ translationBox.find('.translation-area .input.selected').trigger('onchange');
+
+ $(item).parent().find('.translation-tabs').append(tab);
+ });
+
+ thisBox.find('.new').remove();
+ this.checkDeleteButton(translationBox);
+ thisBox.find('.translation-area .selected').focus();
+ },
+
+ confirmRemove: function(button) {
+ var translationBox = $(button).parent().parent().parent();
+
+ if (translationBox.find('.translation-deletelocale').size() > 0) {
+ return;
+ }
+
+ translationBox.find('.translation-area .input.selected').hide();
+
+ translationBox.find('.translation-area .input:first').before($('.translation-deletelocale-container').html());
+ translationBox.find('.translation-deletelocale').css('width', translationBox.css('width'));
+ },
+
+ removeLocale: function(button) {
+ var translationBox = $(button).parent().parent().parent().parent().parent();
+ var locale = translationBox.find('.translation-row .selected').text();
+ translationBox.find('.translation-tab:contains(' + locale + ')').remove();
+ translationBox.find('.translation-area .input.' + locale).val('');
+ translationBox.find('.translation-area .input.' + locale).addClass('deleted');
+ translationBox.find('.translation-area .input.' + locale).removeClass('selected');
+
+ translationBox.find('.translation-maxlength.' + locale).remove();
+
+ translationBox.find('.translation-deletelocale').remove();
+ translationBox.find('.translation-area .input').removeClass('confirm-delete');
+
+ var defaultLocale = translationBox.find('.translation-area').attr('defaultLocale');
+ translationBox.find('.translation-tab:contains(' + defaultLocale + ')').addClass('selected');
+ translationBox.find('.translation-area .' + defaultLocale).addClass('selected');
+ this.checkDeleteButton(translationBox);
+ },
+
+ cancelRemove: function(button) {
+ var translationBox = $(button).parent().parent().parent().parent().parent();
+ translationBox.find('.translation-deletelocale').remove();
+ translationBox.find('.translation-area .input').removeClass('confirm-delete');
+ translationBox.find('.translation-area .input.selected').show();
+ translationBox.find('.translation-area .input.selected').focus();
+ },
+
+ cancelAdd: function(button) {
+ var translationBox = $(button).parent().parent().parent().parent().parent();
+ translationBox.find('.translation-tabs .new').remove();
+ translationBox.find('.translation-newlocale').remove();
+
+ var defaultLocale = translationBox.find('.translation-area').attr('defaultLocale');
+ translationBox.find('.translation-tab:contains(' + defaultLocale + ')').addClass('selected');
+ translationBox.find('.translation-area .' + defaultLocale).addClass('selected');
+ this.checkDeleteButton(translationBox);
+ },
+
+ showHelp: function(button) {
+ var translationBox = $(button).parent().parent();
+ if (translationBox.prev('.translation-help').size() > 0) {
+ return;
+ }
+ translationBox.before($('.translation-help-container').html());
+ translationBox.prev('.translation-help').slideDown('slow');
+ },
+
+ hideHelp: function(button) {
+ var helpBox = $(button).parent().parent().parent().parent();
+ helpBox.slideUp('normal', function() {
+ helpBox.remove();
+ });
+ }
+};
+
+/**
+ * sprintf() implementation for Javascript
+ * adapted from public domain code initially published at:
+ * http://jan.moesen.nu/code/javascript/sprintf-and-printf-in-javascript/
+ */
+function sprintf()
+{
+ if (!arguments || arguments.length < 1 || !RegExp) {
+ return null;
+ }
+ var str = arguments[0];
+ var re = /([^%]*)%((\d+)\$)?('.|0|\x20)?(-)?(\d+)?(\.\d+)?(%|b|c|d|u|f|o|s|x|X)(.*)/;
+ var a = b = [], numSubstitutions = 0, numMatches = 0;
+
+ while ((a = re.exec(str))) {
+ var leftpart = a[1], pPos = a[3], pPad = a[4], pJustify = a[5];
+ var pMinLength = a[6], pPrecision = a[7], pType = a[8];
+ var rightPart = a[9];
+
+ numMatches++;
+ if (pType == '%') {
+ subst = '%';
+ } else {
+ if (pPos == '') {
+ numSubstitutions++;
+ pPos = numSubstitutions;
+ }
+ if (parseInt(pPos) >= arguments.length) {
+ alert('Error! Not enough function arguments (' + (arguments.length - 1)
+ + ', excluding the string)\n'
+ + 'for the number of substitution parameters in string ('
+ + numSubstitutions + ' so far).');
+ }
+ var param = arguments[parseInt(pPos)];
+ var pad = '';
+ if (pPad && pPad.substr(0,1) == "'")
+ pad = leftpart.substr(1,1);
+ else if (pPad)
+ pad = pPad;
+ var justifyRight = true;
+ if (pJustify && pJustify === "-") justifyRight = false;
+ var minLength = -1;
+ if (pMinLength) minLength = parseInt(pMinLength);
+ var precision = -1;
+ if (pPrecision && pType == 'f')
+ precision = parseInt(pPrecision.substring(1));
+ var subst = param;
+
+ switch (pType) {
+ case 'b':
+ subst = parseInt(param).toString(2);
+ break;
+ case 'c':
+ subst = String.fromCharCode(parseInt(param));
+ break;
+ case 'd':
+ subst = parseInt(param) ? parseInt(param) : 0;
+ break;
+ case 'u':
+ subst = Math.abs(param);
+ break;
+ case 'f':
+ subst = (precision > -1)
+ ? Math.round(parseFloat(param) * Math.pow(10, precision))
+ / Math.pow(10, precision)
+ : parseFloat(param);
+ break;
+ case 'o':
+ subst = parseInt(param).toString(8);
+ break;
+ case 's':
+ subst = param;
+ break;
+ case 'x':
+ subst = ('' + parseInt(param).toString(16)).toLowerCase();
+ break;
+ case 'X':
+ subst = ('' + parseInt(param).toString(16)).toUpperCase();
+ break;
+ }
+ var padLeft = minLength - subst.toString().length;
+ if (padLeft > 0) {
+ var arrTmp = new Array(padLeft+1);
+ var padding = arrTmp.join(pad?pad:" ");
+ } else {
+ var padding = "";
+ }
+ }
+ str = leftpart + padding + subst + rightPart;
+ }
+ return str;
+}
+
+/*
+ ### jQuery Star Rating Plugin v2.0 - 2008-03-12 ###
+ By Diego A, http://www.fyneworks.com, diego@fyneworks.com
+ - v2 by Keith Wood, http://keith-wood.name/, kbwood@virginbroadband.com.au
+
+ Project: http://plugins.jquery.com/project/MultipleFriendlyStarRating
+ Website: http://www.fyneworks.com/jquery/star-rating/
+
+ This is a modified version of the star rating plugin from:
+ http://www.phpletter.com/Demo/Jquery-Star-Rating-Plugin/
+*/
+// ORIGINAL COMMENTS:
+/*************************************************
+ This is hacked version of star rating created by <a href="http://php.scripts.psu.edu/rja171/widgets/rating.php">Ritesh Agrawal</a>
+ It thansform a set of radio type input elements to star rating type and remain the radio element name and value,
+ so could be integrated with your form. It acts as a normal radio button.
+ modified by : Logan Cai (cailongqun[at]yahoo.com.cn)
+ website:www.phpletter.com
+************************************************/
+
+
+/*# AVOID COLLISIONS #*/
+;if(jQuery) (function($){
+/*# AVOID COLLISIONS #*/
+
+$.fn.rating = function(settings) {
+ settings = $.extend({
+ cancel: '', // advisory title for the 'cancel' link
+ cancelValue: 0, // value to submit when user click the 'cancel' link
+ required: false, // disables the 'cancel' button so user can only select one of the specified values
+ readOnly: false // disable rating plugin interaction/ values cannot be changed
+ }, settings || {});
+
+ var container = this;
+
+ // multiple star ratings on one page
+ var groups = {};
+
+ // plugin events
+ var event = {
+ fill: function(n, el, style){ // fill to the current mouse position.
+ this.drain(n);
+ $(el).prevAll('.star').andSelf().addClass( style || 'star_hover' );
+ },
+ drain: function(n) { // drain all the stars.
+ $(groups[n].valueElem).siblings('.star').
+ removeClass('star_on').removeClass('star_hover');
+ },
+ reset: function(n){ // Reset the stars to the default index.
+ if (!$(groups[n].currentElem).is('.cancel')) {
+ $(groups[n].currentElem).prevAll('.star').andSelf().addClass('star_on');
+ }
+ },
+ click: function(n, el) { // Selected a star or cancelled
+ groups[n].currentElem = el;
+ var curValue = $(el).children('a').text();
+ // Set value
+ $(groups[n].valueElem).val(curValue);
+ // Update display
+ event.drain(n);
+ event.reset(n);
+ // callback function, as requested here: http://plugins.jquery.com/node/1655
+ if(settings.callback) settings.callback.apply(groups[n].valueElem, [curValue, el]);
+ }
+ };
+
+ // loop through each matched element
+
+ var radioButtons = $(this).find('input[type=radio]');
+
+ $(this).empty();
+ $(this).removeClass('degrade');
+
+ radioButtons.each(function(i){
+ // grouping:
+ var n = this.name;
+
+ if(!groups[n]) groups[n] = {count: 0};
+ i = groups[n].count;
+ groups[n].count++;
+
+ // Things to do with the first element...
+ if(i == 0){
+ // Accept readOnly setting from 'disabled' property
+ settings.readOnly = $(this).attr('disabled') || settings.readOnly;
+ // Create value element (disabled if readOnly)
+ groups[n].valueElem = $('<input type="hidden" name="' + n + '" value=""' + (settings.readOnly ? ' disabled="disabled"' : '') + '>');
+ // Insert value element into form
+ $(container).append(groups[n].valueElem);
+
+ if(settings.readOnly || settings.required){
+ // DO NOT display 'cancel' button
+ }
+ else{
+
+
+ }
+ }; // if (i == 0) (first element)
+
+ // insert rating option right after preview element
+ eStar = $('<div class="star"><a title="' + (this.title || this.value) + '">' + this.value + '</a></div>');
+ $(container).append(eStar);
+
+ if(settings.readOnly){
+ // Mark star as readOnly so user can customize display
+ $(eStar).addClass('star_readonly');
+ }
+ else{
+ // Attach mouse events
+ $(eStar)
+ .mouseover(function(){ event.drain(n); event.fill(n, this); })
+ .mouseout(function(){ event.drain(n); event.reset(n); })
+ .click(function(){ event.click(n, this); });
+ };
+
+ //if(console) console.log(['###', n, this.checked, groups[n].initial]);
+ if(this.checked) groups[n].currentElem = eStar;
+
+
+
+ // reset display if last element
+ if(i + 1 == this.length) event.reset(n);
+
+ }); // each element
+
+
+
+ // initialize groups...
+ for(n in groups)//{ not needed, save a byte!
+ if(groups[n].currentElem){
+ event.fill(n, groups[n].currentElem, 'star_on');
+ $(groups[n].valueElem).val($(groups[n].currentElem).children('a').text());
+ }
+ //}; not needed, save a byte!
+
+ return this; // don't break the chain...
+};
+
+
+
+/*# AVOID COLLISIONS #*/
+})(jQuery);
+/*# AVOID COLLISIONS #*/
+
+
+function VersionCompare() {
+ /**
+ * Mozilla-style version numbers comparison in Javascript
+ * (JS-translated version of PHP versioncompare component)
+ * @return -1: a<b, 0: a==b, 1: a>b
+ */
+ this.compareVersions = function(a,b) {
+ var al = a.split('.');
+ var bl = b.split('.');
+
+ for (var i=0; i<al.length || i<bl.length; i++) {
+ var ap = (i<al.length ? al[i] : null);
+ var bp = (i<bl.length ? bl[i] : null);
+
+ var r = this.compareVersionParts(ap,bp);
+ if (r != 0)
+ return r;
+ }
+
+ return 0;
+ }
+
+ /**
+ * helper function: compare a single version part
+ */
+ this.compareVersionParts = function(ap,bp) {
+ var avp = this.parseVersionPart(ap);
+ var bvp = this.parseVersionPart(bp);
+
+ var r = this.cmp(avp['numA'],bvp['numA']);
+ if (r) return r;
+
+ r = this.strcmp(avp['strB'],bvp['strB']);
+ if (r) return r;
+
+ r = this.cmp(avp['numC'],bvp['numC']);
+ if (r) return r;
+
+ return this.strcmp(avp['extraD'],bvp['extraD']);
+ }
+
+ /**
+ * helper function: parse a version part
+ */
+ this.parseVersionPart = function(p) {
+ if (p == '*') {
+ return {
+ 'numA' : Number.MAX_VALUE,
+ 'strB' : '',
+ 'numC' : 0,
+ 'extraD' : ''
+ };
+ }
+
+ var pattern = /^([-\d]*)([^-\d]*)([-\d]*)(.*)$/;
+ var m = pattern.exec(p);
+
+ var r = {
+ 'numA' : parseInt(m[1]),
+ 'strB' : m[2],
+ 'numC' : parseInt(m[3]),
+ 'extraD' : m[4]
+ };
+
+ if (r['strB'] == '+') {
+ r['numA']++;
+ r['strB'] = 'pre';
+ }
+
+ return r;
+ }
+
+ /**
+ * helper function: compare numeric version parts
+ */
+ this.cmp = function(an,bn) {
+ if (isNaN(an)) an = 0;
+ if (isNaN(bn)) bn = 0;
+
+ if (an < bn)
+ return -1;
+
+ if (an > bn)
+ return 1;
+
+ return 0;
+ }
+
+ /**
+ * helper function: compare string version parts
+ */
+ this.strcmp = function(as,bs) {
+ if (as == bs)
+ return 0;
+
+ // any string comes *before* the empty string
+ if (as == '')
+ return 1;
+
+ if (bs == '')
+ return -1;
+
+ // normal string comparison for non-empty strings (like strcmp)
+ if (as < bs)
+ return -1;
+ else if(as > bs)
+ return 1;
+ else
+ return 0;
+ }
+}
+
+/**
+ * jQuery slider plugin - 2008-07-07
+ * lorchard@mozilla.com
+ */
+
+/*# AVOID COLLISIONS #*/
+;if(jQuery) (function($){
+/*# AVOID COLLISIONS #*/
+
+$.fn.slider = function(settings) {
+ var $slider = arguments.callee.support;
+ new $slider(this[0].id, settings);
+ return this;
+}
+
+$.fn.slider.support = function(slider_id, options) {
+ this.init(slider_id, options);
+};
+
+$.fn.slider.support.prototype = function() {
+
+ return {
+
+ /**
+ * Wire up the scroll events.
+ */
+ init: function(slider_id, options) {
+ this.options = $.extend({
+ duration: 250,
+ prev_img_src: '/img/slider-prev.gif',
+ prev_disabled_img_src: '/img/slider-prev-disabled.gif',
+ next_img_src: '/img/slider-next.gif',
+ next_disabled_img_src: '/img/slider-next-disabled.gif'
+ }, options || {});
+
+ this.slider_id = slider_id;
+ this.slider_sel = '#' + slider_id;
+
+ this._resize_timer = null;
+
+ var that = this;
+ $(window).unload(function() { return that.onUnload(); });
+ $(window).resize(function() { return that.onResize(); });
+ $(document).ready(function() { return that.onReady(); });
+ },
+
+ /**
+ * Perform scroller initialization on page readiness
+ */
+ onReady: function() {
+ this.items = $(this.slider_sel + ' .item');
+ this.item_idx = 0;
+
+ var that = this;
+ $(this.slider_sel + ' .controls .prev').click(function(e) {
+ return that.onClickPrev(e)
+ });
+ $(this.slider_sel + ' .controls .next').click(function(e) {
+ return that.onClickNext(e)
+ });
+
+ this.onResize();
+ },
+
+ /**
+ * Unload some resources on page unload, being superstitous about a
+ * memory leak.
+ */
+ onUnload: function() {
+ delete this.items;
+ },
+
+ /**
+ * React to browser resizing, with a delayed timer to prevent lots of
+ * overlapping calls.
+ */
+ onResize: function() {
+ var that = this;
+ if (this._resize_timer)
+ clearTimeout(this._resize_timer);
+ this._resize_timer = window.setTimeout(function() {
+ that._doResize();
+ }, 50);
+ },
+
+ /**
+ * Perform the actual work of readjusting after resize.
+ */
+ _doResize: function() {
+ var slider = $(this.slider_sel);
+ var viewport = slider.select('.viewport')[0];
+
+ $(this.slider_sel + ' .addon').width(viewport.offsetWidth - 260);
+ this.revealSelectedItem(15);
+ },
+
+ /**
+ * React to "prev" button click.
+ */
+ onClickPrev: function(e) {
+ if ( (this.item_idx - 1) < 0 ) return false;
+ this.item_idx--;
+ return this.changeSelectedItem();
+ },
+
+ /**
+ * React to "next" button click.
+ */
+ onClickNext: function(e) {
+ if ( (this.item_idx + 1) >= this.items.length ) return false;
+ this.item_idx++;
+ return this.changeSelectedItem();
+ },
+
+ /**
+ * Update the selected item, item number, and button display states.
+ */
+ changeSelectedItem: function() {
+ this.updateItemNumber();
+ this.updateButtonStates();
+ this.revealSelectedItem();
+ return false;
+ },
+
+ /**
+ * Update the number displayed indicating current item.
+ */
+ updateItemNumber: function() {
+ $(this.slider_sel + ' .controls .index').text( this.item_idx + 1 );
+ },
+
+ /**
+ * Update the enabled / disabled images for the next / prev buttons.
+ */
+ updateButtonStates: function() {
+ var img_p = $(this.slider_sel + ' .controls .prev img')[0];
+ if ( this.item_idx == 0 ) {
+ img_p.src = this.options.prev_disabled_img_src;
+ } else {
+ img_p.src = this.options.prev_img_src;
+ }
+
+ var img_n = $(this.slider_sel + ' .controls .next img')[0];
+ if ( this.item_idx == this.items.length - 1 ) {
+ img_n.src = this.options.next_disabled_img_src;
+ } else {
+ img_n.src = this.options.next_img_src;
+ }
+ },
+
+ /**
+ * Reveal the selected item with an animation.
+ */
+ revealSelectedItem: function(delay) {
+ if (!delay) delay = this.options.slide_duration;
+ $(this.slider_sel + ' .viewport').animate({
+ scrollLeft: this.items[ this.item_idx ].offsetLeft
+ }, delay)
+ },
+
+ EOF: null // I hate trailing comma errors.
+ };
+}();
+
+/*# AVOID COLLISIONS #*/
+})(jQuery);
+/*# AVOID COLLISIONS #*/
+
+/*# AVOID COLLISIONS #*/
+;if(jQuery) (function($){
+/*# AVOID COLLISIONS #*/
+
+$.fn.collection = function(options) {
+ options = $.extend({
+ 'shoppingCart':false
+ }, options || {});
+
+ var installUrl = options.installUrl;
+
+ $('input.want').change(function() {
+ $('#done-'+$(this).attr('value')).slideToggle('fast');
+ $('.installsubmit input').attr('disabled', ($('input.want:checked').length == 0))
+ });
+ $('input.want:checked').each(function() {
+ $('#done-'+$(this).attr('value')).show();
+ });
+ $('.installsubmit input').attr('disabled', ($('input.want:checked').length == 0))
+
+ var confirmInstall = function() {
+ $.post(installUrl, $('input.want:checked').serialize(),
+ function(data,status){
+ $('#installdialog').html(data)
+ .jqmAddClose('#installdialog .installsubmit input.cancel')
+ .show();
+ });
+ };
+ $('#installdialog').jqm({onShow: confirmInstall,
+ trigger: '#collectionform .installsubmit input,a.installlink',
+ overlay: 80});
+ $(document).keypress(function(e){if (e.keyCode == 27) $('#installdialog').jqmHide();}) // esc
+}
+/*# AVOID COLLISIONS #*/
+})(jQuery);
+/*# AVOID COLLISIONS #*/
+
+function confirmExpInstall(div) {
+ $(div).removeClass('exp-loggedout');
+ $(div).addClass('exp-confirmed');
+ var bt = $(div).find('.install-button a');
+
+ var href = $(bt).attr('href');
+ if (href && href.match(/(policy|\.xml|\.xpi|\.jar)/)) {
+ if (href.match(/collection_id/)) {
+ href += '&confirmed';
+ } else {
+ href += '?confirmed';
+ }
+ $(bt).attr('href', href);
+ }
+
+ var tmp = $(bt).attr('engineURL');
+ if (tmp && tmp.match(/\.xml/)) {
+ if (tmp.match(/collection_id/)) {
+ tmp += "&confirmed";
+ } else {
+ tmp += "?confirmed";
+ }
+ $(bt).attr('engineURL', tmp);
+ }
+
+ $(bt).removeAttr('frozen');
+}
+
+function unconfirmExpInstall(div) {
+ $(div).removeClass('exp-confirmed');
+ $(div).addClass('exp-loggedout');
+ var bt = $(div).find('.install-button a');
+
+ var href = $(bt).attr('href');
+ if (href) {
+ href = href.replace(/\?confirmed/, '').replace(/&confirmed/,'');
+ $(bt).attr('href', href);
+ }
+ var tmp = $(bt).attr('engineURL');
+ if (tmp) {
+ tmp = tmp.replace(/\?confirmed/, '').replace(/&confirmed/,'');
+ $(bt).attr('engineURL', tmp);
+ }
+
+ $(bt).attr('frozen', 'true');
+}
+
+$(document).ready(function() {
+ $('.exp-confirm-install input').each(function () {
+ var div = $(this).parents('.exp-loggedout, .exp-confirmed');
+ if (this.checked)
+ confirmExpInstall(div);
+ else
+ unconfirmExpInstall(div);
+ });
+ $('.exp-confirm-install input').change(function (e) {
+ var div = $(this).parents('.exp-loggedout, .exp-confirmed');
+ if (this.checked) {
+ confirmExpInstall(div);
+ } else {
+ unconfirmExpInstall(div);
+ }
+ });
+});
+function initExpConfirm(versionId) {
+ var outer = $('#install-'+ versionId);
+ $(outer).find('.exp-confirm-install').show();
+ $(outer).find('.exp-loggedout .install-button').show();
+}
+
+/**
+ * jQuery rollover reveal widget
+ * lorchard@mozilla.com
+ *
+ * Example markup:
+ * <div id="foo">
+ * <a href="#" class="activator">Hover me</a>
+ * <div class="to-reveal">This content will appear</div>
+ * </div>
+ * <script>
+ * $('#foo').rolloverReveal({
+ * reveal_delay: 1000, dismiss_delay: 2000
+ * })
+ * </script>
+ *
+ * Whenever the activator element is hovered, the to-reveal content will appear
+ * after a short delay. If the mouse leaves the activator or revealed content,
+ * the content will disappear after a short delay unless the mouse returns.
+ *
+ * Clicking on a link within the revealed content will dismiss the content.
+ */
+;if(jQuery) (function($){
+
+ $.fn.rolloverReveal = function(options) {
+ var $cls = arguments.callee.support;
+ $.each(this, function() { new $cls(this, options) });
+ return this;
+ }
+
+ $.fn.rolloverReveal.support = function(el, options) {
+ this.init(el, options);
+ };
+
+ $.fn.rolloverReveal.support.prototype = function() {
+
+ var option_defaults = {
+ reveal_delay: 250,
+ dismiss_delay: 1000,
+ enable_rollover: true
+ };
+
+ return {
+ // Delayed execution timers.
+ timers: {},
+
+ /** Set up the object instance and event handlers for this widget. */
+ init: function(el, options) {
+ var that = this;
+ this.options = $.extend({}, option_defaults, options);
+
+ this.root = $(el);
+ this.to_reveal = this.root.find('.to-reveal');
+
+ // Wire up the event handlers for significant elements of
+ // the widget.
+ this.root
+ .find('.activator')
+ .click(function() { that.toggle(); return false; })
+ .mouseover(function() {
+ if (!that.options.enable_rollover) return;
+ that.schedule('reveal'); that.cancel('dismiss');
+ })
+ .mouseout(function() {
+ if (!that.options.enable_rollover) return;
+ that.cancel('reveal'); that.schedule('dismiss');
+ })
+ .end()
+ .find('.to-reveal')
+ .mouseover(function() { that.cancel('dismiss'); })
+ .mouseout(function() { that.schedule('dismiss'); })
+ .end()
+ .find('.to-reveal a')
+ .click(function() { that.dismiss(); return true; })
+ .mouseover(function() { that.cancel('dismiss'); })
+ .mouseout(function() { that.schedule('dismiss'); })
+ .end();
+ },
+
+ /** Reveal the hidden content */
+ reveal: function() {
+ this.to_reveal.show().addClass('revealed');
+ },
+
+ /** Determine whether the hidden content is revealed */
+ revealStatus: function() {
+ return this.to_reveal.hasClass('revealed');
+ },
+
+ /** Dismiss the hidden content */
+ dismiss: function() {
+ this.to_reveal.hide().removeClass('revealed');
+ },
+
+ /** Determine whether the hidden content is hidden */
+ dismissStatus: function() {
+ return !this.to_reveal.hasClass('revealed');
+ },
+
+ /** Toggle the hide/show of the content */
+ toggle: function() {
+ return (this.revealStatus()) ?
+ this.dismiss() : this.reveal();
+ },
+
+ /** Schedule delayed execution of the given action. */
+ schedule: function(action) {
+ var that = this;
+ // Skip if the action is already in effect.
+ if (this[action+'Status']()) return;
+ // De-bounce any existing running timer.
+ this.cancel(action);
+ // Schedule a call to the given action.
+ this.timers[action] = setTimeout(function() {
+ that[action]();
+ }, this.options[action + '_delay']);
+ },
+
+ /** Cancel delayed execution of the given action. */
+ cancel: function(action) {
+ if (this.timers[action])
+ clearTimeout(this.timers[action]);
+ },
+
+ EOF:null
+ };
+ }();
+
+})(jQuery);
+
+/**
+ * jQuery utility for PHP's nl2br equivalent in JavaScript,
+ * along with the inverse method br2nl
+ * fwenzel@mozilla.com
+ */
+;if(jQuery) (function($){
+ $.nl2br = function(input) {
+ return input.replace(/\n/g, '<br/>');
+ }
+ $.br2nl = function(input) {
+ return input.replace(RegExp('<br\s*/?>', 'g'), "\n");
+ }
+})(jQuery);
+
+/**
+ * jQuery plugin to delay execution of a callback by x milliseconds
+ * fwenzel@mozilla.com
+ */
+;if(jQuery) (function($){
+ $.fn.delay = function(msec, callback) {
+ return this.each(function() {
+ $(this).animate({opacity: 1.0}, msec, callback);
+ });
+ }
+})(jQuery);
+
+/**
+ * jQuery plugin to fade out, then remove an element
+ * fwenzel@mozilla.com
+ */
+;if(jQuery) (function($){
+ $.fn.fadeRemove = function() {
+ return this.each(function() {
+ $(this).fadeOut('normal', function(){
+ $(this).remove();
+ });
+ });
+ }
+})(jQuery);
+
+
+// make a call to Urchin, for tracking download button clicks
+function urchinDownloadTrackingEvent(path_to_download) {
+ urchinTracker(path_to_download); // actual
+// alert(path_to_download); // debug
+}
+
+// attach a mousedown handler for Urchin, see urchinDownloadTrackingEvent()
+function installButtonAttachUrchin(button) {
+ // don't attach urchin to buttons that just link to a EULA page
+ if($(button).attr('isEULAPageLink')) return false;
+
+ $(button).mousedown(function (e) {
+ if ($(this).attr('frozen') == 'true') return false;
+ urchinDownloadTrackingEvent($(this).attr('href'));
+ });
+}
+
+// attach javascript install methods to an install button
+// e.g. install(), addEngine()
+function installButtonAttachInstallMethod(button) {
+
+ var method = $(button).attr('jsInstallMethod');
+
+ $(button).click(function (e) {
+ if ($(this).attr('frozen') == 'true') return false;
+
+ if (method == 'browser_app_addon_install')
+ return install(e, $(this).attr('addonName'), $(this).attr('addonIcon'), $(this).attr('addonHash'));
+ else if (method == 'search_engine_install')
+ return addEngine($(this).attr('engineURL'));
+ });
+}
+
+$(document).ready(function() {
+ $('p.install-button a').each(function () {
+ installButtonAttachUrchin(this);
+ installButtonAttachInstallMethod(this);
+ });
+});
+
+/**
+ * bandwagon: fire a custom refresh event for bandwagon extension
+ * @return void
+ */
+function bandwagonRefreshEvent() {
+ var bandwagonSubscriptionsRefreshEvent = document.createEvent("Events");
+ bandwagonSubscriptionsRefreshEvent.initEvent("bandwagonRefresh", true, false);
+ document.dispatchEvent(bandwagonSubscriptionsRefreshEvent);
+}
+
+/** Collections edit page **/
+var collections_edit = {
+ /**
+ * initialize collections edit page
+ */
+ init: function() {
+ $('#coll-edit .jsonly').show();
+
+ this.tabs_init();
+ this.nickname_init();
+ this.icon_init();
+ this.user_init();
+ this.addon_init();
+ this.addon_comment_init();
+
+ $('#delete-coll').click(function(){ // delete button
+ $(this).hide();
+ $('#delete-confirm').show();
+ });
+ $('#delete-coll-noscript').change(function() {
+ if ($(this).is(':checked')) {
+ $('#delete-warning').fadeIn();
+ $('#submitbutton').val(collections_edit_submit_deletecollection);
+ } else {
+ $('#delete-warning').fadeOut();
+ $('#submitbutton').val(collections_edit_submit);
+ }
+ });
+ $('#saved_success').delay(10000, function(){$(this).fadeRemove()}); // "saved" success message
+ },
+
+ /**
+ * initialize tabbed layout
+ */
+ tabs_init: function() {
+ $("#coll-edit > ul")
+ .tabs()
+ .bind('tabsselect', function(e, ui, tab) {
+ window.location.hash = '#'+$(tab.panel).attr('id');
+ });
+ },
+
+ /**
+ * initialize nickname check UI
+ */
+ nickname_init: function() {
+ this.nickname_old = $('#CollectionNickname').val(); // save original nickname
+ $('#nick-avail').click(this.nickname_check);
+ $('#CollectionNickname')
+ .blur(this.nickname_check)
+ .keypress(function(e) {
+ if (e.which == KEYCODE_ENTER) {
+ collections_edit.nickname_check();
+ e.preventDefault();
+ }
+ })
+ .keyup(function(e) {
+ if (e.which!=KEYCODE_ENTER) {
+ collections_edit.nickname_checked = false;
+ collections_edit.nickname_showButton();
+ }
+ });
+ },
+ /**
+ * check if a nickname is already taken
+ */
+ nickname_check: function() {
+ if (collections_edit.nickname_checked)
+ return true;
+ else
+ collections_edit.nickname_checked = true;
+
+ var name = $.trim($('#CollectionNickname').val());
+ $('#CollectionNickname').val(name);
+ if (name == collections_edit.nickname_old) { // nickname unchanged
+ collections_edit.nickname_showLabel('available');
+ return true;
+ }
+ if (name.length > 0) {
+ $('#CollectionNickname').siblings('img').show();
+ $.getJSON(jsonURL+'/nickname', {nickname: name}, function(data) {
+ $('#CollectionNickname').siblings('img').hide();
+ $('#nick-avail').hide();
+ if (data.nickname) $('#CollectionNickname').val(data.nickname);
+ if (data.error) {
+ var msg = $('<span class="error">'+data.error_message+'</span>');
+ msg.insertAfter($('#CollectionNickname'));
+ msg.delay(3000, function() {
+ $(this).fadeRemove();
+ collections_edit.nickname_checked = false;
+ collections_edit.nickname_showButton();
+ });
+ $('#CollectionNickname').select();
+ } else {
+ collections_edit.nickname_showLabel(data.taken ? 'taken' : 'available');
+ }
+ });
+ } else {
+ $('#nick-avail')
+ .hide()
+ .siblings('span').hide();
+ }
+ return true;
+ },
+ /**
+ * show nickname check result
+ */
+ nickname_showLabel: function(classname) {
+ $('#nick-avail')
+ .hide()
+ .siblings('span').hide()
+ .filter('.'+classname).show();
+ },
+ /**
+ * show/hide button to initiate nickname check
+ */
+ nickname_showButton: function() {
+ $('#nick-avail').siblings('span').hide();
+ if ($('#CollectionNickname').val().length > 0) {
+ $('#nick-avail').show();
+ } else {
+ $('#nick-avail').hide();
+ }
+ },
+
+ /**
+ * Initialize icon upload UI
+ */
+ icon_init: function() {
+ $('#icon_replace').click(this.icon_replace);
+ $('#icon_remove').click(this.icon_delete);
+ $('#icon>a.cancel').click(this.icon_reset);
+ this.icon_reset();
+ },
+ /**
+ * initialize/reset icon upload UI
+ */
+ icon_reset: function() {
+ var icondiv = $('#icon');
+ if (icondiv.children('img').length == 0) return false;
+ icondiv.children('input:file,.toberemoved,.cancel').hide();
+ icondiv.children('.replaceremove').show();
+ $('#IconDelete').remove();
+ return false;
+ },
+ /**
+ * remove icon
+ */
+ icon_delete: function() {
+ var icondiv = $('#icon');
+ if (icondiv.children('img').length == 0) return false;
+ icondiv.children('input:file,.replaceremove').hide();
+ icondiv.children('.cancel,.toberemoved').show();
+ if ($('#IconDelete').length == 0)
+ icondiv.append('<input type="hidden" id="IconDelete" name="data[Icon][delete]" value="1"/>');
+ return false;
+ },
+ /**
+ * replace an existing icon
+ */
+ icon_replace: function() {
+ var icondiv = $('#icon');
+ if (icondiv.children('img').length == 0) return false;
+ icondiv.children('input:file,.cancel').show();
+ icondiv.children('.replaceremove,.toberemoved').hide();
+ return false;
+ },
+
+ /**
+ * initialize addon-related UI
+ */
+ addon_init: function() {
+ $('#addonname').autocomplete(collURL+'/addonLookup', {
+ minChars: 2,
+ max: 0,
+ formatItem: function(row) { return '<img src="' + row[2] + '"/>&nbsp;' + row[0]; },
+ formatResult: function(row) { return row[0]+' ['+row[1]+']'; },
+ extraParams: { timestamp: null }
+ });
+ $('#addonname').keypress(function(e){
+ if (e.which == KEYCODE_ENTER) {
+ $('#addon-add').click();
+ return false;
+ }
+ return true;
+ });
+
+ $('#addon-add').click(function() {
+ var name = /\[(\d+)\]/.exec($('#addonname').val());
+ if (undefined == name || name.length != 2) return false;
+ collections_edit.addon_add(name[1]);
+ return true;
+ }); // button
+ },
+ /**
+ * show an add-on in the UI
+ */
+ addon_show: function(id, name, iconurl, date, publisher, comment, editable, ontop) {
+ var div = $('<div class="coll-addon" id="addon-'+id+'"/>');
+ var tpl = $('#addon-new'); // template
+
+ var idfield = tpl.children('input:hidden').clone();
+ idfield.val(id);
+ div.append(idfield);
+
+ var p = tpl.children('p').clone();
+ p.find('img').attr('src', iconurl);
+ p.find('.name').text(name);
+ p.find('.added').html(sprintf(p.find('.added').text(), date, publisher));
+ div.append(p);
+ if (editable) div.append(tpl.children('.removeaddon').clone(true));
+ if (!ontop) {
+ $('#currentaddons').append(div);
+ } else {
+ $('#currentaddons #addon-new').after(div);
+ }
+ collections_edit.addon_comment_show(id, comment, editable);
+ $('#currentaddons').show();
+ },
+ /**
+ * add a new add-on to this collection
+ */
+ addon_add: function(id) {
+ $.post(jsonURL+'/addon/add', {
+ sessionCheck: $('#collections>div.hsession>input[name=sessionCheck]').val(),
+ collection_id: collection_id,
+ addon_id: id
+ }, function(data) {
+ if (data.error) {
+ var msg = $('<span class="error">'+data.error_message+'</span>');
+ $('#addon-add').after(msg);
+ msg.delay(2000, function(){ $(this).fadeRemove(); });
+ $('#addonname').select();
+ } else {
+ collections_edit.addon_show(data.id, data.name, data.iconURL,
+ data.date, data.publisher, '', 1, 1);
+ $('#addonname').val('');
+ }
+ return true;
+ }, 'json');
+ },
+ /**
+ * remove an add-on from the collection
+ */
+ addon_delete: function() {
+ var idstring = $(this).parent().attr('id');
+ var id = idstring.substr(idstring.lastIndexOf('-')+1);
+ $.post(jsonURL+'/addon/del', {
+ sessionCheck: $('#collections>div.hsession>input[name=sessionCheck]').val(),
+ collection_id: collection_id,
+ addon_id: id
+ }, function(data) {
+ if (data.error) {
+ alert(data.error_message);
+ } else {
+ $('#addon-'+data.id).fadeRemove();
+ if ($('#currentaddons').children('div:visible').length==0) $('#currentaddons').hide();
+ }
+ return true;
+ }, 'json');
+ return false;
+ },
+
+ /**
+ * initialize comment-related UI
+ */
+ addon_comment_init: function() {
+ var tpl = $('#addon-new');
+ tpl.children('a.removeaddon').click(this.addon_delete);
+ tpl.children('a.addlink').click(this.addon_comment_add);
+ tpl.find('a.editlink').click(this.addon_comment_edit);
+ tpl.find('a.deletelink').click(function() {
+ var container = $(this).parent().parent();
+ var idstring = container.attr('id');
+ var addonid = idstring.substr(idstring.lastIndexOf('-')+1);
+ collections_edit.addon_comment_save(addonid, '');
+ return false;
+ });
+ tpl.find('.editbox>input:button').click(function() { // save
+ var comment = $(this).siblings('textarea').val();
+ var container = $(this).parent().parent();
+ var idstring = container.attr('id');
+ var addonid = idstring.substr(idstring.lastIndexOf('-')+1);
+ collections_edit.addon_comment_save(addonid, comment);
+ return false;
+ });
+ },
+ /**
+ * show a publisher comment in the UI
+ */
+ addon_comment_show: function(addonid, comment, editable) {
+ var div = $('#addon-'+addonid);
+ var tpl = $('#addon-new');
+ if (comment.length > 0) {
+ div.append(tpl.children('blockquote').clone().html($.nl2br(comment)));
+ if (editable) div.append(tpl.children('.editdelete').clone(true));
+ } else {
+ if (editable) div.append(tpl.children('.addlink').clone(true));
+ }
+ },
+ /**
+ * add a new publisher comment in the UI
+ */
+ addon_comment_add: function() {
+ var editbox = $('#addon-new>.editbox').clone(true);
+ $(this).parent().append(editbox);
+ $(this).remove();
+ editbox.children('textarea').focus();
+ return false;
+ },
+ /**
+ * edit an existing publisher comment in the UI
+ */
+ addon_comment_edit: function() {
+ var comment = $(this).parent().siblings('blockquote');
+ var editbox = $('#addon-new>.editbox').clone(true);
+ editbox.children('textarea').html($.br2nl(comment.html()));
+ $(this).parent().parent().append(editbox);
+ $(this).parent().remove();
+ comment.remove();
+ editbox.children('textarea').select();
+ return false;
+ },
+ /**
+ * save/remove a publisher comment
+ */
+ addon_comment_save: function(addonid, comment) {
+ $.post(jsonURL+'/addon/savecomment', {
+ sessionCheck: $('#collections>div.hsession>input[name=sessionCheck]').val(),
+ collection_id: collection_id,
+ addon_id: addonid,
+ comment: comment
+ }, function(data) {
+ var addonid = /addon_id=(\d+)/.exec(this.data)[1];
+ var container = $('#addon-'+addonid);
+ if (data.error) {
+ var msg = $('<div class="error">'+data.error_message+'</div>');
+ container.append(msg);
+ msg.delay(2000, function(){ $(this).fadeRemove(); });
+ } else {
+ container.children('blockquote,.addlink,.editdelete,.editbox').remove();// wipe old UI
+ collections_edit.addon_comment_show(addonid, data.comment, true); // show comment
+ }
+ return true;
+ }, 'json');
+ },
+
+ /**
+ * initialize user-related UI
+ */
+ user_init: function() {
+ $('#publishers>input:text,#managers>input:text').keypress(function(e) {
+ if (e.which == KEYCODE_ENTER) {
+ $(this).siblings('input:button').click();
+ return false;
+ }
+ return true;
+ });
+ $('#publishers>input:button,#managers>input:button').click(collections_edit.user_check);
+ },
+ /**
+ * add a user to this collection
+ */
+ user_check: function() {
+ var role = $(this).parent().attr('id');
+ var email = $('#'+role+'>:text').val();
+ if (email.length==0) return;
+
+ $(this).siblings('img').show();
+ $.post(jsonURL+'/user/add', {
+ sessionCheck: $('#collections>div.hsession>input[name=sessionCheck]').val(),
+ collection_id: collection_id,
+ role: role,
+ email: email
+ }, function(data) {
+ var role = /role=(\w+)/.exec(this.data)[1];
+ $('#'+role+'>img').hide();
+ if (data.error) {
+ var msg = $('<li class="error">'+data.error_message+'</li>');
+ $('#'+role+'>ul').append(msg);
+ msg.delay(2000, function(){ $(this).fadeRemove(); });
+ $('#'+role+'>input:text').select();
+ } else {
+ collections_edit.user_add(role, data.id, data.email);
+ $('#'+role+'>input:text').val('').focus();
+ }
+ return true;
+ }, 'json');
+ },
+ /**
+ * show a user in this collection's user list
+ */
+ user_add: function(role, id, email) {
+ $('#'+role).siblings('input:radio[value=0]').attr('checked', 'checked');
+ $('#'+role+'>ul').append('<li>'
+ +'<input type="hidden" name="'+role+'[]" value="'+id+'"/>'
+ +email+' <a href="#" onclick="collections_edit.user_remove(this);return false;">Remove</a>'
+ +'</li>');
+ },
+ /**
+ * remove a user from this collection
+ */
+ user_remove: function(link) {
+ var id = $(link).siblings('input:hidden').val();
+ $.post(jsonURL+'/user/del', {
+ sessionCheck: $('#collections>div.hsession>input[name=sessionCheck]').val(),
+ role: $(link).parent().parent().parent().attr('id'),
+ collection_id: collection_id,
+ user_id: id
+ }, function(data) {
+ var role = /role=(\w+)/.exec(this.data)[1];
+ if (data.error) {
+ var msg = $('<li class="error">'+data.error_message+'</li>');
+ $('#'+role+'>ul').append(msg);
+ msg.delay(2000, function(){ $(this).fadeRemove(); });
+ $('#'+role+'>input:text').select();
+ } else {
+ $('#'+role+' input:hidden[value='+data.id+']').parent().fadeRemove();
+ }
+ return true;
+ }, 'json');
+ }
+}
+
+/** Addons Display page */
+var addons_display = {
+ /**
+ * initialization
+ */
+ init: function(options) {
+ this.options = options;
+ $('.stars').rating({readOnly:(!options.loggedIn)});
+ $('.rollover-reveal').rolloverReveal({ enable_rollover: false });
+
+ $('#coll_publish input:submit').click(this.coll_publish);
+ },
+
+ /**
+ * publish an add-on to a collection
+ */
+ coll_publish: function() {
+ var coll_uuid = $('#coll_publish option:selected').val();
+ if (!coll_uuid)
+ return false;
+ else if (coll_uuid == 'new')
+ return true;
+ var addon_id = $('#coll_publish input[name=\'data[addon_id]\']').val();
+
+ $.post(addons_display.options.jsonURL+'/addon/add', {
+ sessionCheck: $('#coll_publish div.hsession>input[name=sessionCheck]').val(),
+ collection_uuid: coll_uuid,
+ addon_id: addon_id
+ }, function(data) {
+ if (data.error) {
+ var msg = $('<div class="error">'+data.error_message+'</div>');
+ $('#coll_publish>input:submit').after(msg);
+ msg.delay(3000, function(){ $(this).fadeRemove(); });
+ } else {
+ var coll_uuid = $('#coll_publish option:selected');
+ var msg = $('<div>'
+ +sprintf(addons_display_collection_publish_success,
+ data.name, '<a href="'
+ +addons_display.options.collViewURL+coll_uuid.val()
+ +'">'+coll_uuid.text()+'</a>')
+ +'</div>');
+ $('#coll_publish input:submit').after(msg);
+ msg.delay(10000, function(){ $(this).fadeRemove(); });
+ coll_uuid.remove();
+ }
+ }, 'json');
+ return false;
+ }
+}
diff --git a/site/app/webroot/js/amo-bundle.js b/site/app/webroot/js/amo-bundle.js
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/site/app/webroot/js/amo-bundle.js
@@ -0,0 +1 @@
+
diff --git a/site/app/webroot/js/amo2009/addons.js b/site/app/webroot/js/amo2009/addons.js
new file mode 100644
index 0000000..34573e2
--- /dev/null
+++ b/site/app/webroot/js/amo2009/addons.js
@@ -0,0 +1,1972 @@
+/** Constants **/
+var PLATFORM_OTHER = 0;
+var PLATFORM_WINDOWS = 1;
+var PLATFORM_LINUX = 2;
+var PLATFORM_MACOSX = 3;
+var PLATFORM_MAC = 4;
+var UA_PATTERN_FIREFOX = /Mozilla.*(Firefox|Minefield|Namoroka|Shiretoko|GranParadiso|BonEcho|Iceweasel)\/([^\s]*).*$/;
+var UA_PATTERN_SEAMONKEY = /Mozilla.*(SeaMonkey|Iceape)\/([^\s]*).*$/;
+
+/** Global Variables **/
+
+// determine browser platform
+if (navigator.platform.indexOf("Win32") != -1)
+ gPlatform = PLATFORM_WINDOWS;
+else if (navigator.platform.indexOf("Linux") != -1)
+ gPlatform = PLATFORM_LINUX;
+else if (navigator.userAgent.indexOf("Mac OS X") != -1)
+ gPlatform = PLATFORM_MACOSX;
+else if (navigator.userAgent.indexOf("MSIE 5.2") != -1)
+ gPlatform = PLATFORM_MACOSX;
+else if (navigator.platform.indexOf("Mac") != -1)
+ gPlatform = PLATFORM_MAC;
+else
+ gPlatform = PLATFORM_OTHER;
+
+// determine browser type and version
+gIsFirefox = false;
+gIsSeaMonkey = false;
+gBrowserVersion = null;
+
+var ua = navigator.userAgent;
+var uamatch = UA_PATTERN_FIREFOX.exec(ua);
+if (uamatch && uamatch.length == 3) { // Firefox-like browser
+ gIsFirefox = true;
+ gBrowserVersion = uamatch[2];
+} else {
+ var uamatch = UA_PATTERN_SEAMONKEY.exec(ua);
+ if (uamatch && uamatch.length == 3) { // SeaMonkey-like browser
+ gIsSeaMonkey = true;
+ gBrowserVersion = uamatch[2];
+ }
+}
+
+/** Functions **/
+function getPlatformName()
+{
+ if (gPlatform == PLATFORM_WINDOWS)
+ return "Windows";
+ if (gPlatform == PLATFORM_LINUX)
+ return "Linux";
+ if (gPlatform == PLATFORM_MACOSX)
+ return "MacOSX";
+ return "Unknown";
+}
+
+function getInstallURL(aEvent) {
+ // The event target might be the link itself or one of its children
+ var target = aEvent.target;
+ while (target && !target.href)
+ target = target.parentNode;
+
+ return target && target.href;
+}
+
+function checkMatchUserAgentAppId() {
+ var uapattern = /(?:Firefox|Minefield|Shiretoko|GranParadiso|BonEcho|Iceweasel)/;
+ var ua = navigator.userAgent;
+ var uamatch = uapattern.exec(ua);
+
+ if( uamatch !=null && APP_ID == 1) return true;
+
+ uapattern = /(SeaMonkey|Iceape)/;
+ ua = navigator.userAgent;
+ uamatch = uapattern.exec(ua);
+ if( uamatch !=null && APP_ID == 59) return true;
+
+ return false;
+
+}
+
+/**
+ * Install an add-on into the current browser-type application
+ * (mostly: Firefox, SeaMonkey)
+ */
+function install( aEvent, extName, iconURL, extHash) {
+
+ if (aEvent.altKey || !window.InstallTrigger || !checkMatchUserAgentAppId())
+ return true;
+
+ var url = getInstallURL(aEvent);
+
+ if (url) {
+
+ var params = new Array();
+
+ params[extName] = {
+ URL: url,
+ IconURL: iconURL,
+ toString: function () { return this.URL; }
+ };
+
+ // Only add the Hash param if it exists.
+ //
+ // We optionally add this to params[] because installTrigger
+ // will still try to compare a null hash as long as the var is set.
+ if (extHash) {
+ params[extName].Hash = extHash;
+ }
+
+ InstallTrigger.install(params);
+
+ return false;
+ }
+ return true;
+}
+
+/**
+ * Install a search engine (opensearch)
+ * Returns false in case of success (sic!) because that will keep the file link
+ * from being followed.
+ */
+function addEngine(engineURL) {
+ if (window.external && ("AddSearchProvider" in window.external)) {
+ window.external.AddSearchProvider(engineURL);
+ return false;
+ } else {
+ alert(error_opensearch_unsupported);
+ return true;
+ }
+}
+
+/**
+ * Detect which install button should show, and hide the rest
+ */
+function fixPlatformLinks(versionID, name) {
+ if (gPlatform == PLATFORM_OTHER) return true; // only hide something if we were able to detect platforms
+ var platform = getPlatformName();
+ var outer = $("#install-"+ versionID);
+ var installs = outer.find("p.install-button");
+
+ // hide incompatible installs
+ var others = installs.not(".platform-ALL,.platform-"+platform);
+ others.hide();
+ others.each(function() {
+ var expParents = $(this).parents('.exp-loggedout, .exp-confirmed');
+ if ($(expParents).length)
+ $(expParents).hide();
+ else
+ $(this).hide();
+ });
+
+
+ if (installs.length == others.length) {
+ outer.find(".exp-loggedout").hide();
+ outer.addClass('unavailable').empty().prepend('<strong class="compatmsg">'+sprintf(addOnNotAvailableForPlatform, name, platform)+'</strong>');
+ }
+
+ return true;
+}
+
+/**
+* Used to select between the string Add to App and Download depending on whether Firefox is the UA
+*/
+function installVersusDownloadCheck(triggerID, installString, downloadString)
+{
+ var buttonMessage = installString;
+ var uapattern = /Mozilla.*(Firefox|Minefield|Namoroka|Shiretoko|GranParadiso|BonEcho|SeaMonkey|Iceweasel|Iceape)\/.*$/;
+ var ua = navigator.userAgent;
+ var uamatch = uapattern.exec(ua);
+ var mustDownload = (!uamatch || uamatch.length < 2 || !checkMatchUserAgentAppId()) // not a Firefox-like browser
+ if (mustDownload)
+ buttonMessage = downloadString;
+ $("#" + triggerID + " strong").text(buttonMessage);
+ $("#" + triggerID + " .install-button-text").text(buttonMessage);
+}
+
+/**
+* Initializes the download instructions popup
+*/
+function initDownloadPopup(triggerID, popupID)
+{
+ var container = $("#"+popupID).parents(".app_install");
+
+ function positionPopup(e) {
+ var offset = container.offset();
+ $("#"+popupID)
+ .remove()
+ .appendTo("body")
+ .css({ position: 'absolute', left: offset.left, top: offset.top })
+ .show();
+ }
+
+ $("#"+triggerID).click(positionPopup);
+
+ var dd = new DropdownArea();
+ dd.trigger = $("#"+triggerID);
+ dd.target = ("#"+popupID+" .app_install-popup");
+ dd.targetParent = ("#"+popupID);
+ dd.preventDefault = false;
+ dd.showSpeed = 600;
+ dd.hideSpeed = 300;
+ dd.init();
+}
+
+/**
+ * Provide hints on install buttons for add-ons incompatible with the
+ * currently used browser.
+ *
+ * @param int addonID
+ * @param int versionID
+ * @param string fromVer minimum compatible Firefox version
+ * @param string toVer maximum compatible Firefox version
+ * @param bool showVersionLink offer a link to the user which will remove the compatibility hint (and allow them to download the add-on)
+ */
+function addCompatibilityHints(addonID, versionID, fromVer, toVer, showVersionLink) {
+ var uapattern = /Mozilla.*(?:Firefox|Minefield|Shiretoko|GranParadiso|BonEcho|Iceweasel)\/([^\s]*).*$/;
+ var ua = navigator.userAgent;
+ var uamatch = uapattern.exec(ua);
+ if (!uamatch || uamatch.length < 2) return true;
+
+ var outer = $("#install-"+ versionID);
+
+ var version = uamatch[1];
+ var vc = new VersionCompare();
+ if (vc.compareVersions(version, fromVer)<0)
+ var needUpgrade = true;
+ else if(vc.compareVersions(version, toVer)>0)
+ var needUpgrade = false;
+ else {
+ return true;
+ }
+
+ var links = outer.find("p:visible a"); // find visible install boxes
+ if (links.length == 0) return true; // nothing to do
+
+ // duplicate button and hide original (to be able to restore it later)
+ var cloned = outer.clone();
+ cloned.attr('id', 'orig-'+ versionID);
+ cloned.hide();
+
+ outer.addClass('unavailable');
+ outer.find(".exp-confirm-install").hide();
+ outer.after(cloned);
+
+ // remove link
+ var url = links.attr('href');
+ links.removeAttr("href");
+ links.removeAttr("onClick");
+ links.removeAttr("title");
+ links.css('cursor', 'default');
+ links.parent().css('float', 'none');
+ // freeze button
+ links.attr('frozen', 'true');
+
+ // determine "all versions" page url
+ if (url.indexOf('downloads') > 0)
+ url = url.substring(0, url.indexOf('downloads'));
+ else if (url.indexOf('addons') > 0)
+ url = url.substring(0, url.indexOf('addons'));
+ url = url+'addons/versions/'+addonID;
+
+ var l_parent = links.parent();
+ links.remove();
+
+ if (needUpgrade && showVersionLink) {
+ l_parent.after(
+ '<strong class="compatmsg">'+
+ sprintf(app_compat_older_version_or_ignore_check, url, "removeCompatibilityHint("+versionID+");return false;")+
+ '</strong>'
+ );
+ } else if (!needUpgrade && showVersionLink) {
+ l_parent
+ .after('<strong class="compatmsg">'+app_compat_older_firefox_only+'</strong>'
+ +'<strong class="compatmsg">'
+ +'<a href="#" onclick="removeCompatibilityHint(\''+versionID+'\');return false;">' +app_compat_ignore_check+ '</a>'
+ +'</strong>');
+ } else if (!needUpgrade) {
+ l_parent.after(
+ '<strong class="compatmsg">'+
+ app_compat_older_firefox_only+
+ '</strong>'
+ );
+ } else {
+ l_parent.after(
+ '<strong class="compatmsg">'+
+ sprintf(app_compat_try_old_version, url)+
+ '</strong>'
+ );
+ }
+
+ if (needUpgrade) {
+ if (vc.compareVersions(fromVer, LATEST_FIREFOX_DEVEL_VERSION)>=0) {
+ l_parent.after(sprintf('<strong class="compatmsg">' + app_compat_unreleased_version + "</strong>", 'http://www.mozilla.com/' + LANG + '/firefox/all-beta.html#' + LANG, LATEST_FIREFOX_DEVEL_VERSION));
+ }else if (vc.compareVersions(fromVer, LATEST_FIREFOX_VERSION)<0) {
+ l_parent.after(sprintf('<strong class="compatmsg">' + app_compat_update_firefox + "</strong>", 'http://www.mozilla.com/' + LANG + '/firefox/all.html#' + LANG, LATEST_FIREFOX_VERSION));
+ }
+ }
+
+ return true;
+}
+
+/**
+ * Remove "incompatible" message for given version ID, by restoring the
+ * original button.
+ */
+function removeCompatibilityHint(versionID) {
+ // find all hidden install buttons
+ var orig = $('#orig-' + versionID);
+ // remove compatibility hints
+ orig.prev().remove();
+ // show original buttons
+ orig.attr('id', 'install-'+versionID);
+
+ orig.show();
+
+ return true;
+}
+
+/**
+ * replaces options in a select drop-down (used for advanced search)
+ * @param select_id - the id of the select tag to replace the options of
+ * @param opt_array - array of options to use
+ * @param selected - which option will be marked as selected
+ *
+ */
+function replaceOptions( select_id , opt_array, selected) {
+ $(select_id + " > *").remove();
+
+ for( opt in opt_array) {
+ sel_text = "";
+ val = opt_array[opt];
+ opt_obj = document.createElement("option");
+ if( val == selected) {opt_obj.selected = "selected";}
+ opt_obj.value = val;
+ opt_obj.appendChild(document.createTextNode(opt));
+ $(select_id).append(opt_obj);
+ }
+}
+
+/**
+ * replace noscript email by an actual link
+ * @param obj id of email node
+ * @param lp local part
+ * @param hp host part
+ */
+function emailLink(obj, lp, hp) {
+ var cont = document.getElementById(obj);
+ var em = lp +'@'+ hp;
+ var a = document.createElement('a');
+ a.setAttribute('href', 'mailto:'+em);
+ a.appendChild(document.createTextNode(em));
+ cont.replaceChild(a, cont.lastChild);
+}
+
+var translation_box = {
+ switchLocale: function(tab, locale) {
+ var translationBox = $(tab).parent().parent().parent();
+ if (translationBox.find('.translation-deletelocale').size() > 0) {
+ return;
+ }
+ translationBox.find('.selected').removeClass('selected');
+ $(tab).addClass('selected');
+ translationBox.find('.' + locale).addClass('selected');
+ this.checkDeleteButton(translationBox);
+ translationBox.find('.translation-area .input.selected').trigger('onchange');
+ translationBox.find('.' + locale).focus();
+ },
+
+ checkDeleteButton: function(translationBox) {
+ var defaultLocale = translationBox.find('.translation-area').attr('defaultLocale');
+ var selectedLocale = translationBox.find('.translation-tab.selected').text();
+ if (selectedLocale == defaultLocale || selectedLocale == '') {
+ translationBox.find('.translation-button.remove').hide();
+ }
+ else {
+ translationBox.find('.translation-button.remove').show();
+ }
+ },
+
+ checkLength: function(field, max) {
+ var translationBox = $(field).parent().parent();
+ translationBox.find('.translation-maxlength.selected span').text(field.value.length);
+
+ if (field.value.length > max) {
+ translationBox.find('.translation-maxlength.selected').addClass('over');
+ translationBox.addClass('errors');
+ }
+ else {
+ translationBox.find('.translation-maxlength.selected').removeClass('over');
+
+ if (translationBox.find('.translation-area .over').size() == 0) {
+ translationBox.removeClass('errors');
+ }
+ }
+ },
+
+ addTab: function(button) {
+ var translationBox = $(button).parent().parent().parent();
+ if (translationBox.find('.translation-deletelocale').size() > 0) {
+ return;
+ }
+
+ if (translationBox.find('.translation-tab').hasClass('new')) {
+ translationBox.find('.selected').removeClass('selected');
+ translationBox.find('.new').addClass('selected');
+ return;
+ }
+
+ var tab = '<div class="translation-tab selected new" onclick="translation_box.switchLocale(this, \'new\');"></div>';
+ translationBox.find('.selected').removeClass('selected');
+ translationBox.find('.translation-tabs').append(tab);
+ translationBox.find('.translation-area').append($('.translation-newlocale-container').html());
+
+ // Remove existing translations from available dropdown
+ translationBox.find('.translation-tab:not(.new)').each(function(index, item) {
+ translationBox.find('.translation-newlocale select option[value="' + $(item).text() + '"]').remove();
+ });
+ this.checkDeleteButton(translationBox);
+ },
+
+ addLocale: function(button, addToAll) {
+ var translationBox = $(button).parent().parent().parent().parent().parent();
+ var thisBox = translationBox;
+ if (addToAll == true) {
+ translationBox = translationBox.parent();
+ }
+
+ var locale = thisBox.find('select').val();
+ var localeName = thisBox.find('select option:selected').text();
+
+ var tab = '<div class="translation-tab selected" title="' + localeName + '" onclick="translation_box.switchLocale(this, \'' + locale + '\');">' + locale + '</div>';
+
+ translationBox.find('.input.' + locale + '.deleted').remove();
+ translationBox.find('.translation-area:not(:has(.' + locale + '))').each(function(index, item) {
+ var itemID = $(item).attr('itemID');
+ var field = 'data[' + $(item).attr('table') + ']' + (itemID != null ? '[' + itemID + ']' : '') + '[' + $(item).attr('field') + '][' + locale + ']';
+ $(item).parent().find('.selected').removeClass('selected');
+
+ var fieldType = $(item).find('.input')[0].tagName.toLowerCase();
+ var style = $(item).find('.input').attr('style');
+
+ if (fieldType == 'textarea') {
+ var fieldHTML = '<textarea class="input ' + locale + ' selected" name="' + field + '" style="' + style + '"';
+ var maxLength = $(item).find('.input').attr('maxLength');
+ if (maxLength) {
+ fieldHTML += ' maxLength="' + maxLength + '" onkeyup="translation_box.checkLength(this, ' + maxLength + ');" onchange="translation_box.checkLength(this, ' + maxLength + ');"';
+ var afterHTML = '<div class="translation-maxlength ' + locale + ' selected">' + $(item).find('.translation-maxlength').html() + '</div>';
+ }
+ fieldHTML += '></textarea>';
+ }
+ else if (fieldType == 'input') {
+ var fieldHTML = '<input type="text" class="input ' + locale + ' selected" value="" name="' + field + '" style="' + style + '" />';
+ var afterHTML = '';
+ }
+ $(item).append(fieldHTML).append(afterHTML);
+ translationBox.find('.translation-area .input.selected').trigger('onchange');
+
+ $(item).parent().find('.translation-tabs').append(tab);
+ });
+
+ thisBox.find('.new').remove();
+ this.checkDeleteButton(translationBox);
+ thisBox.find('.translation-area .selected').focus();
+ },
+
+ confirmRemove: function(button) {
+ var translationBox = $(button).parent().parent().parent();
+
+ if (translationBox.find('.translation-deletelocale').size() > 0) {
+ return;
+ }
+
+ translationBox.find('.translation-area .input.selected').hide();
+
+ translationBox.find('.translation-area .input:first').before($('.translation-deletelocale-container').html());
+ translationBox.find('.translation-deletelocale').css('width', translationBox.css('width'));
+ },
+
+ removeLocale: function(button) {
+ var translationBox = $(button).parent().parent().parent().parent().parent();
+ var locale = translationBox.find('.translation-row .selected').text();
+ translationBox.find('.translation-tab:contains(' + locale + ')').remove();
+ translationBox.find('.translation-area .input.' + locale).val('');
+ translationBox.find('.translation-area .input.' + locale).addClass('deleted');
+ translationBox.find('.translation-area .input.' + locale).removeClass('selected');
+
+ translationBox.find('.translation-maxlength.' + locale).remove();
+
+ translationBox.find('.translation-deletelocale').remove();
+ translationBox.find('.translation-area .input').removeClass('confirm-delete');
+
+ var defaultLocale = translationBox.find('.translation-area').attr('defaultLocale');
+ translationBox.find('.translation-tab:contains(' + defaultLocale + ')').addClass('selected');
+ translationBox.find('.translation-area .' + defaultLocale).addClass('selected');
+ this.checkDeleteButton(translationBox);
+ },
+
+ cancelRemove: function(button) {
+ var translationBox = $(button).parent().parent().parent().parent().parent();
+ translationBox.find('.translation-deletelocale').remove();
+ translationBox.find('.translation-area .input').removeClass('confirm-delete');
+ translationBox.find('.translation-area .input.selected').show();
+ translationBox.find('.translation-area .input.selected').focus();
+ },
+
+ cancelAdd: function(button) {
+ var translationBox = $(button).parent().parent().parent().parent().parent();
+ translationBox.find('.translation-tabs .new').remove();
+ translationBox.find('.translation-newlocale').remove();
+
+ var defaultLocale = translationBox.find('.translation-area').attr('defaultLocale');
+ translationBox.find('.translation-tab:contains(' + defaultLocale + ')').addClass('selected');
+ translationBox.find('.translation-area .' + defaultLocale).addClass('selected');
+ this.checkDeleteButton(translationBox);
+ },
+
+ showHelp: function(button) {
+ var translationBox = $(button).parent().parent();
+ if (translationBox.prev('.translation-help').size() > 0) {
+ return;
+ }
+ translationBox.before($('.translation-help-container').html());
+ translationBox.prev('.translation-help').slideDown('slow');
+ },
+
+ hideHelp: function(button) {
+ var helpBox = $(button).parent().parent().parent().parent();
+ helpBox.slideUp('normal', function() {
+ helpBox.remove();
+ });
+ }
+};
+
+/**
+ * sprintf() implementation for Javascript
+ * adapted from public domain code initially published at:
+ * http://jan.moesen.nu/code/javascript/sprintf-and-printf-in-javascript/
+ */
+function sprintf()
+{
+ if (!arguments || arguments.length < 1 || !RegExp) {
+ return null;
+ }
+ var str = arguments[0];
+ var re = /([^%]*)%((\d+)\$)?('.|0|\x20)?(-)?(\d+)?(\.\d+)?(%|b|c|d|u|f|o|s|x|X)(.*)/;
+ var a = b = [], numSubstitutions = 0, numMatches = 0;
+
+ while ((a = re.exec(str))) {
+ var leftpart = a[1], pPos = a[3], pPad = a[4], pJustify = a[5];
+ var pMinLength = a[6], pPrecision = a[7], pType = a[8];
+ var rightPart = a[9];
+
+ numMatches++;
+ if (pType == '%') {
+ subst = '%';
+ } else {
+ if (pPos == '') {
+ numSubstitutions++;
+ pPos = numSubstitutions;
+ }
+ if (parseInt(pPos) >= arguments.length) {
+ alert('Error! Not enough function arguments (' + (arguments.length - 1)
+ + ', excluding the string)\n'
+ + 'for the number of substitution parameters in string ('
+ + numSubstitutions + ' so far).');
+ }
+ var param = arguments[parseInt(pPos)];
+ var pad = '';
+ if (pPad && pPad.substr(0,1) == "'")
+ pad = leftpart.substr(1,1);
+ else if (pPad)
+ pad = pPad;
+ var justifyRight = true;
+ if (pJustify && pJustify === "-") justifyRight = false;
+ var minLength = -1;
+ if (pMinLength) minLength = parseInt(pMinLength);
+ var precision = -1;
+ if (pPrecision && pType == 'f')
+ precision = parseInt(pPrecision.substring(1));
+ var subst = param;
+
+ switch (pType) {
+ case 'b':
+ subst = parseInt(param).toString(2);
+ break;
+ case 'c':
+ subst = String.fromCharCode(parseInt(param));
+ break;
+ case 'd':
+ subst = parseInt(param) ? parseInt(param) : 0;
+ break;
+ case 'u':
+ subst = Math.abs(param);
+ break;
+ case 'f':
+ subst = (precision > -1)
+ ? Math.round(parseFloat(param) * Math.pow(10, precision))
+ / Math.pow(10, precision)
+ : parseFloat(param);
+ break;
+ case 'o':
+ subst = parseInt(param).toString(8);
+ break;
+ case 's':
+ subst = param;
+ break;
+ case 'x':
+ subst = ('' + parseInt(param).toString(16)).toLowerCase();
+ break;
+ case 'X':
+ subst = ('' + parseInt(param).toString(16)).toUpperCase();
+ break;
+ }
+ var padLeft = minLength - subst.toString().length;
+ if (padLeft > 0) {
+ var arrTmp = new Array(padLeft+1);
+ var padding = arrTmp.join(pad?pad:" ");
+ } else {
+ var padding = "";
+ }
+ }
+ str = leftpart + padding + subst + rightPart;
+ }
+ return str;
+}
+
+/*
+ ### jQuery Star Rating Plugin v2.0 - 2008-03-12 ###
+ By Diego A, http://www.fyneworks.com, diego@fyneworks.com
+ - v2 by Keith Wood, http://keith-wood.name/, kbwood@virginbroadband.com.au
+
+ Project: http://plugins.jquery.com/project/MultipleFriendlyStarRating
+ Website: http://www.fyneworks.com/jquery/star-rating/
+
+ This is a modified version of the star rating plugin from:
+ http://www.phpletter.com/Demo/Jquery-Star-Rating-Plugin/
+*/
+// ORIGINAL COMMENTS:
+/*************************************************
+ This is hacked version of star rating created by <a href="http://php.scripts.psu.edu/rja171/widgets/rating.php">Ritesh Agrawal</a>
+ It thansform a set of radio type input elements to star rating type and remain the radio element name and value,
+ so could be integrated with your form. It acts as a normal radio button.
+ modified by : Logan Cai (cailongqun[at]yahoo.com.cn)
+ website:www.phpletter.com
+************************************************/
+
+
+/*# AVOID COLLISIONS #*/
+;if(jQuery) (function($){
+/*# AVOID COLLISIONS #*/
+
+$.fn.rating = function(settings) {
+ settings = $.extend({
+ cancel: '', // advisory title for the 'cancel' link
+ cancelValue: 0, // value to submit when user click the 'cancel' link
+ required: false, // disables the 'cancel' button so user can only select one of the specified values
+ readOnly: false // disable rating plugin interaction/ values cannot be changed
+ }, settings || {});
+
+ var container = this;
+
+ // multiple star ratings on one page
+ var groups = {};
+
+ // plugin events
+ var event = {
+ fill: function(n, el, style){ // fill to the current mouse position.
+ this.drain(n);
+ $(el).prevAll('.star').andSelf().addClass( style || 'star_hover' );
+ },
+ drain: function(n) { // drain all the stars.
+ $(groups[n].valueElem).siblings('.star').
+ removeClass('star_on').removeClass('star_hover');
+ },
+ reset: function(n){ // Reset the stars to the default index.
+ if (!$(groups[n].currentElem).is('.cancel')) {
+ $(groups[n].currentElem).prevAll('.star').andSelf().addClass('star_on');
+ }
+ },
+ click: function(n, el) { // Selected a star or cancelled
+ groups[n].currentElem = el;
+ var curValue = $(el).children('a').text();
+ // Set value
+ $(groups[n].valueElem).val(curValue);
+ // Update display
+ event.drain(n);
+ event.reset(n);
+ // callback function, as requested here: http://plugins.jquery.com/node/1655
+ if(settings.callback) settings.callback.apply(groups[n].valueElem, [curValue, el]);
+ }
+ };
+
+ // loop through each matched element
+
+ var radioButtons = $(this).find('input[type=radio]');
+
+ $(this).empty();
+ $(this).removeClass('degrade');
+
+ radioButtons.each(function(i){
+ // grouping:
+ var n = this.name;
+
+ if(!groups[n]) groups[n] = {count: 0};
+ i = groups[n].count;
+ groups[n].count++;
+
+ // Things to do with the first element...
+ if(i == 0){
+ // Accept readOnly setting from 'disabled' property
+ settings.readOnly = $(this).attr('disabled') || settings.readOnly;
+ // Create value element (disabled if readOnly)
+ groups[n].valueElem = $('<input type="hidden" name="' + n + '" value=""' + (settings.readOnly ? ' disabled="disabled"' : '') + '>');
+ // Insert value element into form
+ $(container).append(groups[n].valueElem);
+
+ if(settings.readOnly || settings.required){
+ // DO NOT display 'cancel' button
+ }
+ else{
+
+
+ }
+ }; // if (i == 0) (first element)
+
+ // insert rating option right after preview element
+ eStar = $('<div class="star"><a title="' + (this.title || this.value) + '">' + this.value + '</a></div>');
+ $(container).append(eStar);
+
+ if(settings.readOnly){
+ // Mark star as readOnly so user can customize display
+ $(eStar).addClass('star_readonly');
+ }
+ else{
+ // Attach mouse events
+ $(eStar)
+ .mouseover(function(){ event.drain(n); event.fill(n, this); })
+ .mouseout(function(){ event.drain(n); event.reset(n); })
+ .click(function(){ event.click(n, this); });
+ };
+
+ //if(console) console.log(['###', n, this.checked, groups[n].initial]);
+ if(this.checked) groups[n].currentElem = eStar;
+
+
+
+ // reset display if last element
+ if(i + 1 == this.length) event.reset(n);
+
+ }); // each element
+
+
+
+ // initialize groups...
+ for(n in groups)//{ not needed, save a byte!
+ if(groups[n].currentElem){
+ event.fill(n, groups[n].currentElem, 'star_on');
+ $(groups[n].valueElem).val($(groups[n].currentElem).children('a').text());
+ }
+ //}; not needed, save a byte!
+
+ return this; // don't break the chain...
+};
+
+
+
+/*# AVOID COLLISIONS #*/
+})(jQuery);
+/*# AVOID COLLISIONS #*/
+
+
+function VersionCompare() {
+ /**
+ * Mozilla-style version numbers comparison in Javascript
+ * (JS-translated version of PHP versioncompare component)
+ * @return -1: a<b, 0: a==b, 1: a>b
+ */
+ this.compareVersions = function(a,b) {
+ var al = a.split('.');
+ var bl = b.split('.');
+
+ for (var i=0; i<al.length || i<bl.length; i++) {
+ var ap = (i<al.length ? al[i] : null);
+ var bp = (i<bl.length ? bl[i] : null);
+
+ var r = this.compareVersionParts(ap,bp);
+ if (r != 0)
+ return r;
+ }
+
+ return 0;
+ }
+
+ /**
+ * helper function: compare a single version part
+ */
+ this.compareVersionParts = function(ap,bp) {
+ var avp = this.parseVersionPart(ap);
+ var bvp = this.parseVersionPart(bp);
+
+ var r = this.cmp(avp['numA'],bvp['numA']);
+ if (r) return r;
+
+ r = this.strcmp(avp['strB'],bvp['strB']);
+ if (r) return r;
+
+ r = this.cmp(avp['numC'],bvp['numC']);
+ if (r) return r;
+
+ return this.strcmp(avp['extraD'],bvp['extraD']);
+ }
+
+ /**
+ * helper function: parse a version part
+ */
+ this.parseVersionPart = function(p) {
+ if (p == '*') {
+ return {
+ 'numA' : Number.MAX_VALUE,
+ 'strB' : '',
+ 'numC' : 0,
+ 'extraD' : ''
+ };
+ }
+
+ var pattern = /^([-\d]*)([^-\d]*)([-\d]*)(.*)$/;
+ var m = pattern.exec(p);
+
+ var r = {
+ 'numA' : parseInt(m[1]),
+ 'strB' : m[2],
+ 'numC' : parseInt(m[3]),
+ 'extraD' : m[4]
+ };
+
+ if (r['strB'] == '+') {
+ r['numA']++;
+ r['strB'] = 'pre';
+ }
+
+ return r;
+ }
+
+ /**
+ * helper function: compare numeric version parts
+ */
+ this.cmp = function(an,bn) {
+ if (isNaN(an)) an = 0;
+ if (isNaN(bn)) bn = 0;
+
+ if (an < bn)
+ return -1;
+
+ if (an > bn)
+ return 1;
+
+ return 0;
+ }
+
+ /**
+ * helper function: compare string version parts
+ */
+ this.strcmp = function(as,bs) {
+ if (as == bs)
+ return 0;
+
+ // any string comes *before* the empty string
+ if (as == '')
+ return 1;
+
+ if (bs == '')
+ return -1;
+
+ // normal string comparison for non-empty strings (like strcmp)
+ if (as < bs)
+ return -1;
+ else if(as > bs)
+ return 1;
+ else
+ return 0;
+ }
+}
+
+/**
+ * jQuery slider plugin - 2008-07-07
+ * lorchard@mozilla.com
+ */
+
+/*# AVOID COLLISIONS #*/
+;if(jQuery) (function($){
+/*# AVOID COLLISIONS #*/
+
+$.fn.slider = function(settings) {
+ var $slider = arguments.callee.support;
+ new $slider(this[0].id, settings);
+ return this;
+}
+
+$.fn.slider.support = function(slider_id, options) {
+ this.init(slider_id, options);
+};
+
+$.fn.slider.support.prototype = function() {
+
+ return {
+
+ /**
+ * Wire up the scroll events.
+ */
+ init: function(slider_id, options) {
+ this.options = $.extend({
+ duration: 250,
+ prev_img_src: '/img/slider-prev.gif',
+ prev_disabled_img_src: '/img/slider-prev-disabled.gif',
+ next_img_src: '/img/slider-next.gif',
+ next_disabled_img_src: '/img/slider-next-disabled.gif'
+ }, options || {});
+
+ this.slider_id = slider_id;
+ this.slider_sel = '#' + slider_id;
+
+ this._resize_timer = null;
+
+ var that = this;
+ $(window).unload(function() { return that.onUnload(); });
+ $(window).resize(function() { return that.onResize(); });
+ $(document).ready(function() { return that.onReady(); });
+ },
+
+ /**
+ * Perform scroller initialization on page readiness
+ */
+ onReady: function() {
+ this.items = $(this.slider_sel + ' .item');
+ this.item_idx = 0;
+
+ var that = this;
+ $(this.slider_sel + ' .controls .prev').click(function(e) {
+ return that.onClickPrev(e)
+ });
+ $(this.slider_sel + ' .controls .next').click(function(e) {
+ return that.onClickNext(e)
+ });
+
+ this.onResize();
+ },
+
+ /**
+ * Unload some resources on page unload, being superstitous about a
+ * memory leak.
+ */
+ onUnload: function() {
+ delete this.items;
+ },
+
+ /**
+ * React to browser resizing, with a delayed timer to prevent lots of
+ * overlapping calls.
+ */
+ onResize: function() {
+ var that = this;
+ if (this._resize_timer)
+ clearTimeout(this._resize_timer);
+ this._resize_timer = window.setTimeout(function() {
+ that._doResize();
+ }, 50);
+ },
+
+ /**
+ * Perform the actual work of readjusting after resize.
+ */
+ _doResize: function() {
+ var slider = $(this.slider_sel);
+ var viewport = slider.select('.viewport')[0];
+
+ $(this.slider_sel + ' .addon').width(viewport.offsetWidth - 260);
+ this.revealSelectedItem(15);
+ },
+
+ /**
+ * React to "prev" button click.
+ */
+ onClickPrev: function(e) {
+ if ( (this.item_idx - 1) < 0 ) return false;
+ this.item_idx--;
+ return this.changeSelectedItem();
+ },
+
+ /**
+ * React to "next" button click.
+ */
+ onClickNext: function(e) {
+ if ( (this.item_idx + 1) >= this.items.length ) return false;
+ this.item_idx++;
+ return this.changeSelectedItem();
+ },
+
+ /**
+ * Update the selected item, item number, and button display states.
+ */
+ changeSelectedItem: function() {
+ this.updateItemNumber();
+ this.updateButtonStates();
+ this.revealSelectedItem();
+ return false;
+ },
+
+ /**
+ * Update the number displayed indicating current item.
+ */
+ updateItemNumber: function() {
+ $(this.slider_sel + ' .controls .index').text( this.item_idx + 1 );
+ },
+
+ /**
+ * Update the enabled / disabled images for the next / prev buttons.
+ */
+ updateButtonStates: function() {
+ var img_p = $(this.slider_sel + ' .controls .prev img')[0];
+ if ( this.item_idx == 0 ) {
+ img_p.src = this.options.prev_disabled_img_src;
+ } else {
+ img_p.src = this.options.prev_img_src;
+ }
+
+ var img_n = $(this.slider_sel + ' .controls .next img')[0];
+ if ( this.item_idx == this.items.length - 1 ) {
+ img_n.src = this.options.next_disabled_img_src;
+ } else {
+ img_n.src = this.options.next_img_src;
+ }
+ },
+
+ /**
+ * Reveal the selected item with an animation.
+ */
+ revealSelectedItem: function(delay) {
+ if (!delay) delay = this.options.slide_duration;
+ $(this.slider_sel + ' .viewport').animate({
+ scrollLeft: this.items[ this.item_idx ].offsetLeft
+ }, delay)
+ },
+
+ EOF: null // I hate trailing comma errors.
+ };
+}();
+
+/*# AVOID COLLISIONS #*/
+})(jQuery);
+/*# AVOID COLLISIONS #*/
+
+/*# AVOID COLLISIONS #*/
+;if(jQuery) (function($){
+/*# AVOID COLLISIONS #*/
+
+$.fn.collection = function(options) {
+ options = $.extend({
+ 'shoppingCart':false
+ }, options || {});
+
+ var installUrl = options.installUrl;
+
+ $('input.want').change(function() {
+ $('#done-'+$(this).attr('value')).slideToggle('fast');
+ $('.installsubmit input').attr('disabled', ($('input.want:checked').length == 0))
+ });
+ $('input.want:checked').each(function() {
+ $('#done-'+$(this).attr('value')).show();
+ });
+ $('.installsubmit input').attr('disabled', ($('input.want:checked').length == 0))
+
+ var confirmInstall = function() {
+ $.post(installUrl, $('input.want:checked').serialize(),
+ function(data,status){
+ $('#installdialog').html(data)
+ .jqmAddClose('#installdialog .installsubmit input.cancel')
+ .show();
+ });
+ };
+ $('#installdialog').jqm({onShow: confirmInstall,
+ trigger: '#collectionform .installsubmit input,a.installlink',
+ overlay: 80});
+ $(document).keypress(function(e){if (e.keyCode == 27) $('#installdialog').jqmHide();}) // esc
+}
+/*# AVOID COLLISIONS #*/
+})(jQuery);
+/*# AVOID COLLISIONS #*/
+
+function confirmExpInstall(div) {
+ $(div).removeClass('exp-loggedout');
+ $(div).addClass('exp-confirmed');
+ var bt = $(div).find('.install-button a');
+
+ var href = $(bt).attr('href');
+ if (href && href.match(/(policy|\.xml|\.xpi|\.jar)/)) {
+ if (href.match(/collection_id/)) {
+ href += '&confirmed';
+ } else {
+ href += '?confirmed';
+ }
+ $(bt).attr('href', href);
+ }
+
+ var tmp = $(bt).attr('engineURL');
+ if (tmp && tmp.match(/\.xml$/)) {
+ if (tmp.match(/collection_id/)) {
+ tmp += "&confirmed";
+ } else {
+ tmp += "?confirmed";
+ }
+ $(bt).attr('engineURL', tmp);
+ }
+
+ $(bt).removeAttr('frozen');
+}
+
+function unconfirmExpInstall(div) {
+ $(div).removeClass('exp-confirmed');
+ $(div).addClass('exp-loggedout');
+ var bt = $(div).find('.install-button a');
+
+ var href = $(bt).attr('href');
+ if (href) {
+ href = href.replace(/\?confirmed/, '').replace(/&confirmed/,'');
+ $(bt).attr('href', href);
+ }
+ var tmp = $(bt).attr('engineURL');
+ if (tmp) {
+ tmp = tmp.replace(/\?confirmed/, '').replace(/&confirmed/,'');
+ $(bt).attr('engineURL', tmp);
+ }
+
+ $(bt).attr('frozen', 'true');
+}
+
+$(document).ready(function() {
+ $('.exp-confirm-install input').each(function () {
+ var div = $(this).parents('.exp-loggedout, .exp-confirmed');
+ if (this.checked)
+ confirmExpInstall(div);
+ else
+ unconfirmExpInstall(div);
+ });
+ $('.exp-confirm-install input').change(function (e) {
+ var div = $(this).parents('.exp-loggedout, .exp-confirmed');
+ if (this.checked) {
+ confirmExpInstall(div);
+ } else {
+ unconfirmExpInstall(div);
+ }
+ });
+});
+function initExpConfirm(versionId) {
+ var outer = $('#install-'+ versionId);
+ $(outer).find('.exp-confirm-install').show();
+ $(outer).find('.exp-loggedout .install-button').show();
+}
+
+/**
+ * jQuery rollover reveal widget
+ * lorchard@mozilla.com
+ *
+ * Example markup:
+ * <div id="foo">
+ * <a href="#" class="activator">Hover me</a>
+ * <div class="to-reveal">This content will appear</div>
+ * </div>
+ * <script>
+ * $('#foo').rolloverReveal({
+ * reveal_delay: 1000, dismiss_delay: 2000
+ * })
+ * </script>
+ *
+ * Whenever the activator element is hovered, the to-reveal content will appear
+ * after a short delay. If the mouse leaves the activator or revealed content,
+ * the content will disappear after a short delay unless the mouse returns.
+ *
+ * Clicking on a link within the revealed content will dismiss the content.
+ */
+;if(jQuery) (function($){
+
+ $.fn.rolloverReveal = function(options) {
+ var $cls = arguments.callee.support;
+ $.each(this, function() { new $cls(this, options) });
+ return this;
+ }
+
+ $.fn.rolloverReveal.support = function(el, options) {
+ this.init(el, options);
+ };
+
+ $.fn.rolloverReveal.support.prototype = function() {
+
+ var option_defaults = {
+ reveal_delay: 250,
+ dismiss_delay: 1000,
+ enable_rollover: true
+ };
+
+ return {
+ // Delayed execution timers.
+ timers: {},
+
+ /** Set up the object instance and event handlers for this widget. */
+ init: function(el, options) {
+ var that = this;
+ this.options = $.extend({}, option_defaults, options);
+
+ this.root = $(el);
+ this.to_reveal = this.root.find('.to-reveal');
+
+ // Wire up the event handlers for significant elements of
+ // the widget.
+ this.root
+ .find('.activator')
+ .click(function() { that.toggle(); return false; })
+ .mouseover(function() {
+ if (!that.options.enable_rollover) return;
+ that.schedule('reveal'); that.cancel('dismiss');
+ })
+ .mouseout(function() {
+ if (!that.options.enable_rollover) return;
+ that.cancel('reveal'); that.schedule('dismiss');
+ })
+ .end()
+ .find('.to-reveal')
+ .mouseover(function() { that.cancel('dismiss'); })
+ .mouseout(function() { that.schedule('dismiss'); })
+ .end()
+ .find('.to-reveal a')
+ .click(function() { that.dismiss(); return true; })
+ .mouseover(function() { that.cancel('dismiss'); })
+ .mouseout(function() { that.schedule('dismiss'); })
+ .end();
+ },
+
+ /** Reveal the hidden content */
+ reveal: function() {
+ this.to_reveal.show().addClass('revealed');
+ },
+
+ /** Determine whether the hidden content is revealed */
+ revealStatus: function() {
+ return this.to_reveal.hasClass('revealed');
+ },
+
+ /** Dismiss the hidden content */
+ dismiss: function() {
+ this.to_reveal.hide().removeClass('revealed');
+ },
+
+ /** Determine whether the hidden content is hidden */
+ dismissStatus: function() {
+ return !this.to_reveal.hasClass('revealed');
+ },
+
+ /** Toggle the hide/show of the content */
+ toggle: function() {
+ return (this.revealStatus()) ?
+ this.dismiss() : this.reveal();
+ },
+
+ /** Schedule delayed execution of the given action. */
+ schedule: function(action) {
+ var that = this;
+ // Skip if the action is already in effect.
+ if (this[action+'Status']()) return;
+ // De-bounce any existing running timer.
+ this.cancel(action);
+ // Schedule a call to the given action.
+ this.timers[action] = setTimeout(function() {
+ that[action]();
+ }, this.options[action + '_delay']);
+ },
+
+ /** Cancel delayed execution of the given action. */
+ cancel: function(action) {
+ if (this.timers[action])
+ clearTimeout(this.timers[action]);
+ },
+
+ EOF:null
+ };
+ }();
+
+})(jQuery);
+
+/**
+ * jQuery utility for PHP's nl2br equivalent in JavaScript,
+ * along with the inverse method br2nl
+ * fwenzel@mozilla.com
+ */
+;if(jQuery) (function($){
+ $.nl2br = function(input) {
+ return input.replace(/\n/g, '<br/>');
+ }
+ $.br2nl = function(input) {
+ return input.replace(RegExp('<br\s*/?>', 'g'), "\n");
+ }
+})(jQuery);
+
+/**
+ * jQuery plugin to delay execution of a callback by x milliseconds
+ * fwenzel@mozilla.com
+ */
+;if(jQuery) (function($){
+ $.fn.delay = function(msec, callback) {
+ return this.each(function() {
+ $(this).animate({opacity: 1.0}, msec, callback);
+ });
+ }
+})(jQuery);
+
+/**
+ * jQuery containing some simple UI extensions
+ * fwenzel@mozilla.com
+ */
+;if(jQuery) (function($){
+ /**
+ * fade out, then remove an element
+ */
+ $.fn.fadeRemove = function() {
+ return this.each(function() {
+ $(this).fadeOut('normal', function(){
+ $(this).remove();
+ });
+ });
+ }
+})(jQuery);
+
+
+// make a call to Urchin, for tracking download button clicks
+function urchinDownloadTrackingEvent(path_to_download) {
+ urchinTracker(path_to_download); // actual
+// alert(path_to_download); // debug
+}
+
+// attach a mousedown handler for Urchin, see urchinDownloadTrackingEvent()
+function installButtonAttachUrchin(button) {
+ // don't attach urchin to buttons that just link to a EULA page
+ if($(button).attr('isEULAPageLink')) return false;
+
+ $(button).mousedown(function (e) {
+ if ($(this).attr('frozen') == 'true') return false;
+ urchinDownloadTrackingEvent($(this).attr('href'));
+ });
+}
+
+// attach javascript install methods to an install button
+// e.g. install(), addEngine()
+function installButtonAttachInstallMethod(button) {
+
+ var method = $(button).attr('jsInstallMethod');
+
+ $(button).click(function (e) {
+ if ($(this).attr('frozen') == 'true') return false;
+
+ if (method == 'browser_app_addon_install')
+ return install(e, $(this).attr('addonName'), $(this).attr('addonIcon'), $(this).attr('addonHash'));
+ else if (method == 'search_engine_install')
+ return addEngine($(this).attr('engineURL'));
+ });
+}
+
+$(document).ready(function() {
+ $('p.install-button a').each(function () {
+ installButtonAttachUrchin(this);
+ installButtonAttachInstallMethod(this);
+ });
+});
+
+/**
+ * bandwagon: fire a custom refresh event for bandwagon extension
+ * @return void
+ */
+function bandwagonRefreshEvent() {
+ var bandwagonSubscriptionsRefreshEvent = document.createEvent("Events");
+ bandwagonSubscriptionsRefreshEvent.initEvent("bandwagonRefresh", true, false);
+ document.dispatchEvent(bandwagonSubscriptionsRefreshEvent);
+}
+
+/** Collections add page **/
+var collections_add = {
+ /**
+ * initialize collections add page
+ */
+ init: function(options) {
+ this.options = options;
+
+ $('#addonname').autocomplete(this.options.lookup_url, {
+ minChars: 2,
+ max: 0,
+ formatItem: function(row) { return '<img src="' + row[2] + '"/>' + row[0]; },
+ extraParams: { timestamp: null }
+ });
+ $('#addonname').result(function(event,data) {
+ collections_add.addAddon(data);
+ $(this).val('');
+ });
+ $('#firstaddons').show();
+ },
+
+ addAddon: function(data) {
+ var newid = 'addon-'+data[1];
+ if ($('#'+newid).size() > 0) {
+ $('#'+newid)
+ .attr('checked', true)
+ .parent()
+ .addClass('flash')
+ .delay(3000, function() {
+ $(this).removeClass('flash');
+ });
+ return true;
+ }
+ $('#selectedaddons').children('ul:first').append(
+ '<li>'+
+ '<input type="checkbox" name="addons[]" value="'+data[1]+'" id="addon-'+data[1]+'" checked="true"/>'+
+ '<label for="addon-'+data[1]+'"><img src="'+data[2]+'"/>&nbsp;'+data[0]+'</label><li>'
+ );
+ $('#selectedaddons').show();
+ return true;
+ }
+}
+
+/** Collections edit page **/
+var collections_edit = {
+ /**
+ * initialize collections edit page
+ */
+ init: function() {
+ $('#coll-edit .jsonly').show();
+
+ this.tabs_init();
+ this.nickname_init();
+ this.icon_init();
+ this.user_init();
+ this.addon_init();
+ this.addon_comment_init();
+
+ // delete button
+ $('#delete-confirm').hide();
+ $('#delete-coll').click(function() {
+ $(this).hide();
+ $('#delete-confirm').show();
+ });
+ $('#delete-coll-noscript').change(function() {
+ if ($(this).is(':checked')) {
+ $('#delete-warning').fadeIn();
+ $('#submitbutton').val(collections_edit_submit_deletecollection);
+ } else {
+ $('#delete-warning').fadeOut();
+ $('#submitbutton').val(collections_edit_submit);
+ }
+ });
+ $('#saved_success').delay(10000, function(){$(this).fadeRemove()}); // "saved" success message
+ },
+
+ /**
+ * initialize tabbed layout
+ */
+ tabs_init: function() {
+ $("#coll-edit > ul")
+ .tabs()
+ .bind('tabsselect', function(e, ui, tab) {
+ window.location.hash = '#'+$(tab.panel).attr('id');
+ });
+ },
+
+ /**
+ * initialize nickname check UI
+ */
+ nickname_init: function() {
+ this.nickname_old = $('#CollectionNickname').val(); // save original nickname
+ $('#nick-avail').click(this.nickname_check);
+ $('#CollectionNickname')
+ .blur(this.nickname_check)
+ .keypress(function(e) {
+ if (e.which == KEYCODE_ENTER) {
+ collections_edit.nickname_check();
+ e.preventDefault();
+ }
+ })
+ .keyup(function(e) {
+ if (e.which!=KEYCODE_ENTER) {
+ collections_edit.nickname_checked = false;
+ collections_edit.nickname_showButton();
+ }
+ });
+ },
+ /**
+ * check if a nickname is already taken
+ */
+ nickname_check: function() {
+ if (collections_edit.nickname_checked)
+ return true;
+ else
+ collections_edit.nickname_checked = true;
+
+ var name = $.trim($('#CollectionNickname').val());
+ $('#CollectionNickname').val(name);
+ if (name == collections_edit.nickname_old) { // nickname unchanged
+ collections_edit.nickname_showLabel('available');
+ return true;
+ }
+ if (name.length > 0) {
+ $('#CollectionNickname').siblings('img').show();
+ $.getJSON(jsonURL+'/nickname', {nickname: name}, function(data) {
+ $('#CollectionNickname').siblings('img').hide();
+ $('#nick-avail').hide();
+ if (data.nickname) $('#CollectionNickname').val(data.nickname);
+ if (data.error) {
+ var msg = $('<span class="error">'+data.error_message+'</span>');
+ msg.insertAfter($('#CollectionNickname'));
+ msg.delay(3000, function() {
+ $(this).fadeRemove();
+ collections_edit.nickname_checked = false;
+ collections_edit.nickname_showButton();
+ });
+ $('#CollectionNickname').select();
+ } else {
+ collections_edit.nickname_showLabel(data.taken ? 'taken' : 'available');
+ }
+ });
+ } else {
+ $('#nick-avail')
+ .hide()
+ .siblings('span').hide();
+ }
+ return true;
+ },
+ /**
+ * show nickname check result
+ */
+ nickname_showLabel: function(classname) {
+ $('#nick-avail')
+ .hide()
+ .siblings('span').hide()
+ .filter('.'+classname).show();
+ },
+ /**
+ * show/hide button to initiate nickname check
+ */
+ nickname_showButton: function() {
+ $('#nick-avail').siblings('span').hide();
+ if ($('#CollectionNickname').val().length > 0) {
+ $('#nick-avail').show();
+ } else {
+ $('#nick-avail').hide();
+ }
+ },
+
+ /**
+ * Initialize icon upload UI
+ */
+ icon_init: function() {
+ $('#icon_replace').click(this.icon_replace);
+ $('#icon_remove').click(this.icon_delete);
+ $('#icon>a.cancel').click(this.icon_reset);
+ this.icon_reset();
+ },
+ /**
+ * initialize/reset icon upload UI
+ */
+ icon_reset: function() {
+ var icondiv = $('#icon');
+ if (icondiv.children('img').length == 0) return false;
+ icondiv.children('input:file,.toberemoved,.cancel').hide();
+ icondiv.children('.replaceremove').show();
+ $('#IconDelete').remove();
+ return false;
+ },
+ /**
+ * remove icon
+ */
+ icon_delete: function() {
+ var icondiv = $('#icon');
+ if (icondiv.children('img').length == 0) return false;
+ icondiv.children('input:file,.replaceremove').hide();
+ icondiv.children('.cancel,.toberemoved').show();
+ if ($('#IconDelete').length == 0)
+ icondiv.append('<input type="hidden" id="IconDelete" name="data[Icon][delete]" value="1"/>');
+ return false;
+ },
+ /**
+ * replace an existing icon
+ */
+ icon_replace: function() {
+ var icondiv = $('#icon');
+ if (icondiv.children('img').length == 0) return false;
+ icondiv.children('input:file,.cancel').show();
+ icondiv.children('.replaceremove,.toberemoved').hide();
+ return false;
+ },
+
+ /**
+ * initialize addon-related UI
+ */
+ addon_init: function() {
+ $('#addonname').autocomplete(collURL+'/addonLookup', {
+ minChars: 2,
+ max: 0,
+ formatItem: function(row) { return '<img src="' + row[2] + '"/>&nbsp;' + row[0]; },
+ formatResult: function(row) { return row[0]+' ['+row[1]+']'; },
+ extraParams: { timestamp: null }
+ });
+ $('#addonname').keypress(function(e){
+ if (e.which == KEYCODE_ENTER) {
+ $('#addon-add').click();
+ return false;
+ }
+ return true;
+ });
+
+ $('#addon-add').click(function() {
+ var name = /\[(\d+)\]/.exec($('#addonname').val());
+ if (undefined == name || name.length != 2) return false;
+ collections_edit.addon_add(name[1]);
+ return true;
+ }); // button
+ },
+ /**
+ * show an add-on in the UI
+ */
+ addon_show: function(id, name, iconurl, date, publisher, comment, editable, ontop) {
+ var div = $('<div class="coll-addon" id="addon-'+id+'"/>');
+ var tpl = $('#addon-new'); // template
+
+ var idfield = tpl.children('input:hidden').clone();
+ idfield.val(id);
+ div.append(idfield);
+
+ var p = tpl.children('p').clone();
+ p.find('img').attr('src', iconurl);
+ p.find('.name').text(name);
+ p.find('.added').html(sprintf(p.find('.added').text(), date, publisher));
+ div.append(p);
+ if (editable) div.append(tpl.children('.removeaddon').clone(true));
+ if (!ontop) {
+ $('#currentaddons').append(div);
+ } else {
+ $('#currentaddons #addon-new').after(div);
+ }
+ collections_edit.addon_comment_show(id, comment, editable);
+ $('#currentaddons').show();
+ },
+ /**
+ * add a new add-on to this collection
+ */
+ addon_add: function(id) {
+ $.post(jsonURL+'/addon/add', {
+ sessionCheck: $('#collections>div.hsession>input[name=sessionCheck]').val(),
+ collection_id: collection_id,
+ addon_id: id
+ }, function(data) {
+ if (data.error) {
+ var msg = $('<span class="error">'+data.error_message+'</span>');
+ $('#addon-add').after(msg);
+ msg.delay(2000, function(){ $(this).fadeRemove(); });
+ $('#addonname').select();
+ } else {
+ collections_edit.addon_show(data.id, data.name, data.iconURL,
+ data.date, data.publisher, '', 1, 1);
+ $('#addonname').val('');
+ }
+ return true;
+ }, 'json');
+ },
+ /**
+ * remove an add-on from the collection
+ */
+ addon_delete: function() {
+ var idstring = $(this).parent().attr('id');
+ var id = idstring.substr(idstring.lastIndexOf('-')+1);
+ $.post(jsonURL+'/addon/del', {
+ sessionCheck: $('#collections>div.hsession>input[name=sessionCheck]').val(),
+ collection_id: collection_id,
+ addon_id: id
+ }, function(data) {
+ if (data.error) {
+ alert(data.error_message);
+ } else {
+ $('#addon-'+data.id).fadeRemove();
+ if ($('#currentaddons').children('div:visible').length==0) $('#currentaddons').hide();
+ }
+ return true;
+ }, 'json');
+ return false;
+ },
+
+ /**
+ * initialize comment-related UI
+ */
+ addon_comment_init: function() {
+ var tpl = $('#addon-new');
+ tpl.children('a.removeaddon').click(this.addon_delete);
+ tpl.children('a.addlink').click(this.addon_comment_add);
+ tpl.find('a.editlink').click(this.addon_comment_edit);
+ tpl.find('a.deletelink').click(function() {
+ var container = $(this).parent().parent();
+ var idstring = container.attr('id');
+ var addonid = idstring.substr(idstring.lastIndexOf('-')+1);
+ collections_edit.addon_comment_save(addonid, '');
+ return false;
+ });
+ tpl.find('.editbox>input:button').click(function() { // save
+ var comment = $(this).siblings('textarea').val();
+ var container = $(this).parent().parent();
+ var idstring = container.attr('id');
+ var addonid = idstring.substr(idstring.lastIndexOf('-')+1);
+ collections_edit.addon_comment_save(addonid, comment);
+ return false;
+ });
+ },
+ /**
+ * show a publisher comment in the UI
+ */
+ addon_comment_show: function(addonid, comment, editable) {
+ var div = $('#addon-'+addonid);
+ var tpl = $('#addon-new');
+ if (comment.length > 0) {
+ div.append(tpl.children('blockquote').clone().html($.nl2br(comment)));
+ if (editable) div.append(tpl.children('.editdelete').clone(true));
+ } else {
+ if (editable) div.append(tpl.children('.addlink').clone(true));
+ }
+ },
+ /**
+ * add a new publisher comment in the UI
+ */
+ addon_comment_add: function() {
+ var editbox = $('#addon-new>.editbox').clone(true);
+ $(this).parent().append(editbox);
+ $(this).remove();
+ editbox.children('textarea').focus();
+ return false;
+ },
+ /**
+ * edit an existing publisher comment in the UI
+ */
+ addon_comment_edit: function() {
+ var comment = $(this).parent().siblings('blockquote');
+ var editbox = $('#addon-new>.editbox').clone(true);
+ editbox.children('textarea').html($.br2nl(comment.html()));
+ $(this).parent().parent().append(editbox);
+ $(this).parent().remove();
+ comment.remove();
+ editbox.children('textarea').select();
+ return false;
+ },
+ /**
+ * save/remove a publisher comment
+ */
+ addon_comment_save: function(addonid, comment) {
+ $.post(jsonURL+'/addon/savecomment', {
+ sessionCheck: $('#collections>div.hsession>input[name=sessionCheck]').val(),
+ collection_id: collection_id,
+ addon_id: addonid,
+ comment: comment
+ }, function(data) {
+ var addonid = /addon_id=(\d+)/.exec(this.data)[1];
+ var container = $('#addon-'+addonid);
+ if (data.error) {
+ var msg = $('<div class="error">'+data.error_message+'</div>');
+ container.append(msg);
+ msg.delay(2000, function(){ $(this).fadeRemove(); });
+ } else {
+ container.children('blockquote,.addlink,.editdelete,.editbox').remove();// wipe old UI
+ collections_edit.addon_comment_show(addonid, data.comment, true); // show comment
+ }
+ return true;
+ }, 'json');
+ },
+
+ /**
+ * initialize user-related UI
+ */
+ user_init: function() {
+ $('#publishers>input:text,#managers>input:text').keypress(function(e) {
+ if (e.which == KEYCODE_ENTER) {
+ $(this).siblings('input:button').click();
+ return false;
+ }
+ return true;
+ });
+ $('#publishers>input:button,#managers>input:button').click(collections_edit.user_check);
+ },
+ /**
+ * add a user to this collection
+ */
+ user_check: function() {
+ var role = $(this).parent().attr('id');
+ var email = $('#'+role+'>:text').val();
+ if (email.length==0) return;
+
+ $(this).siblings('img').show();
+ $.post(jsonURL+'/user/add', {
+ sessionCheck: $('#collections>div.hsession>input[name=sessionCheck]').val(),
+ collection_id: collection_id,
+ role: role,
+ email: email
+ }, function(data) {
+ var role = /role=(\w+)/.exec(this.data)[1];
+ $('#'+role+'>img').hide();
+ if (data.error) {
+ var msg = $('<li class="error">'+data.error_message+'</li>');
+ $('#'+role+'>ul').append(msg);
+ msg.delay(2000, function(){ $(this).fadeRemove(); });
+ $('#'+role+'>input:text').select();
+ } else {
+ collections_edit.user_add(role, data.id, data.email);
+ $('#'+role+'>input:text').val('').focus();
+ }
+ return true;
+ }, 'json');
+ },
+ /**
+ * show a user in this collection's user list
+ */
+ user_add: function(role, id, email) {
+ $('#'+role).siblings('input:radio[value=0]').attr('checked', 'checked');
+ $('#'+role+'>ul').append('<li>'
+ +'<input type="hidden" name="'+role+'[]" value="'+id+'"/>'
+ +email+' <a href="#" onclick="collections_edit.user_remove(this);return false;">Remove</a>'
+ +'</li>');
+ },
+ /**
+ * remove a user from this collection
+ */
+ user_remove: function(link) {
+ var id = $(link).siblings('input:hidden').val();
+ $.post(jsonURL+'/user/del', {
+ sessionCheck: $('#collections>div.hsession>input[name=sessionCheck]').val(),
+ role: $(link).parent().parent().parent().attr('id'),
+ collection_id: collection_id,
+ user_id: id
+ }, function(data) {
+ var role = /role=(\w+)/.exec(this.data)[1];
+ if (data.error) {
+ var msg = $('<li class="error">'+data.error_message+'</li>');
+ $('#'+role+'>ul').append(msg);
+ msg.delay(2000, function(){ $(this).fadeRemove(); });
+ $('#'+role+'>input:text').select();
+ } else {
+ $('#'+role+' input:hidden[value='+data.id+']').parent().fadeRemove();
+ }
+ return true;
+ }, 'json');
+ }
+}
+
+/** Addons Display page */
+var addons_display = {
+ /**
+ * initialization
+ */
+ init: function(options) {
+ this.options = options;
+ $('#form-review .stars').rating({readOnly:(!options.loggedIn)});
+ $('.rollover-reveal').rolloverReveal({ enable_rollover: false });
+
+ $('#coll_publish button').click(this.coll_publish);
+ },
+
+ /**
+ * publish an add-on to a collection
+ */
+ coll_publish: function() {
+ var coll_uuid = $('#coll_publish option:selected').val();
+ if (!coll_uuid)
+ return false;
+ else if (coll_uuid == 'new')
+ return true;
+ var addon_id = $('#coll_publish input[name=\'data[addon_id]\']').val();
+
+ $.post(addons_display.options.jsonURL+'/addon/add', {
+ sessionCheck: $('#coll_publish div.hsession>input[name=sessionCheck]').val(),
+ collection_uuid: coll_uuid,
+ addon_id: addon_id
+ }, function(data) {
+ if (data.error) {
+ var msg = $('<div class="error">'+data.error_message+'</div>');
+ $('#coll_publish>button').after(msg);
+ msg.delay(3000, function(){ $(this).fadeRemove(); });
+ } else {
+ var coll_uuid = $('#coll_publish option:selected');
+ var msg = $('<div>'
+ +sprintf(addons_display_collection_publish_success,
+ data.name, '<a href="'
+ +addons_display.options.collViewURL+coll_uuid.val()
+ +'">'+coll_uuid.text()+'</a>')
+ +'</div>');
+ $('#coll_publish button').after(msg);
+ msg.delay(10000, function(){ $(this).fadeRemove(); });
+ coll_uuid.remove();
+ }
+ }, 'json');
+ return false;
+ }
+}
+
+/** Addons Version History Page */
+var addons_history = {
+ latestVersionID: null, // latest compatible version ID
+ vc: null, // version compare object
+ versions: new Array(),
+
+ init: function() {
+ this.vc = new VersionCompare();
+ },
+
+ /**
+ * Add a version (compatible with Firefox) to the list of versions
+ */
+ addVersion: function(versionid, fromVer, toVer) {
+ this.versions[this.versions.length] = [versionid, fromVer, toVer];
+ },
+
+ /**
+ * Find the latest known compatible version for the current app
+ */
+ findLatestCompatibleVersion: function() {
+ var success = false;
+ for (var i = 0; i < this.versions.length; i++) {
+ var v = this.versions[i];
+ if (v < this.latestVersionID) continue;
+
+ if (this.vc.compareVersions(gBrowserVersion, v[1]) > 0
+ && this.vc.compareVersions(gBrowserVersion, v[2]) < 0) {
+ var installbuttons = $('#install-'+v[0]).find('.platform-ALL,.platform-'+getPlatformName(gPlatform));
+ if (installbuttons.size() > 0) {
+ this.latestVersionID = v[0];
+ success = true;
+ }
+ }
+ }
+ return success;
+ },
+
+ /**
+ * Create an element with the most recent compatible version of an addon
+ * @returns bool success
+ */
+ createLatestVersionElement: function(get_latest_version_text, app) {
+ var found = this.findLatestCompatibleVersion();
+ if (!found) return false;
+
+ var container = $('#latest-version-container');
+ var newid = 'install-latest-'+ this.latestVersionID; // new unique ID
+
+ var installButtonOrig = $('#install-'+this.latestVersionID);
+
+ // make a version info box
+ var wrapper = $('<div></div>');
+ var titletext = "<h3>" + sprintf(get_latest_version_text, app, gBrowserVersion) + "</h3>"
+ var verinfo = installButtonOrig.siblings('h3').clone().html();
+ var installButton =
+ installButtonOrig.clone()
+ .attr('id', newid);
+ wrapper
+ .attr('class', installButtonOrig.parent().attr('class'))
+ .append(titletext)
+ .append(installButton)
+ .append(verinfo);
+ container
+ .append(wrapper)
+ .attr('id', 'latest-version');
+
+ fixPlatformLinks('latest-'+this.latestVersionID, ''); // show only the relevant platform
+ container.show();
+ return true;
+ }
+}
diff --git a/site/app/webroot/js/amo2009/collections.js b/site/app/webroot/js/amo2009/collections.js
new file mode 100644
index 0000000..cfe3949
--- /dev/null
+++ b/site/app/webroot/js/amo2009/collections.js
@@ -0,0 +1,107 @@
+var collections = {};
+/**
+ * These members need to be set on the collections object:
+ * subscribe_url
+ * unsubscribe_url
+ * adding_text
+ * removing_text
+ * add_text
+ * remove_text
+ *
+ * Optional:
+ * adding_img
+ * removing_img
+ * remove_img
+ * add_img
+ */
+
+collections.init = function(){
+
+ var sum = function(arr) {
+ var ret = 0;
+ $.each(arr, function(_, i) { ret += i; });
+ return ret;
+ };
+
+ /* We don't want the button to shrink when the contents
+ * inside change. */
+ var maintain_width = function(b) {
+ var w = sum($.map(['width', 'padding-left', 'padding-right',
+ 'border-left-width', 'border-right-width'],
+ function(w){ return parseFloat(b.css(w)); })
+ );
+ b.css('min-width', w);
+ };
+
+ var modal = function(content) {
+ if ($.cookie('collections-leave-me-alone'))
+ return;
+
+ var e = $('<div class="modal-subscription">' + content + '</div>');
+ e.appendTo(document.body).jqm().jqmAddClose('a.close-button').jqmShow();
+ e.find('#bothersome').change(function(){
+ // Leave me alone for 1 year (doesn't handle leap years).
+ $.cookie('collections-leave-me-alone', true,
+ {expires: 365, path: c.cookie_path});
+ e.jqmHide();
+ });
+ };
+
+ var c = collections;
+
+ var f = $('form.item-sort');
+ f.find('select').change(function(){ this.form.submit(); });
+ f.find('button').hide();
+
+ /* Hijack form.favourite for some ajax fun. */
+ $('form.favourite').submit(function(event){
+ event.preventDefault();
+
+ // `this` is the form.
+ var fav_button = $(this).find('button');
+ var previous = fav_button.html();
+ var is_fav = fav_button.hasClass('fav');
+
+ /* Kind should be in ['adding', 'removing', 'add', 'remove'] */
+ var button = function(kind) {
+ var text = c[kind + '_text'];
+ /* The listing page doesn't have an inline image, detail page does. */
+ if (fav_button.find('img').length) {
+ var img = c[kind + '_img'];
+ fav_button.html('<img src="' + img + '"/>' + text);
+ } else {
+ fav_button.html(text);
+ }
+ };
+
+ maintain_width(fav_button);
+ fav_button.addClass('loading-fav').attr('disabled', 'disabled');
+ button(is_fav ? 'removing' : 'adding');
+ maintain_width(fav_button);
+
+ $.ajax({
+ type: "POST",
+ data: $(this).serialize(),
+ url: is_fav ? c.unsubscribe_url : c.subscribe_url,
+ success: function(content){
+ if (is_fav) {
+ fav_button.removeClass('fav');
+ button('add');
+ } else{
+ modal(content);
+ fav_button.addClass('fav');
+ button('remove');
+ }
+ // Holla back at the extension.
+ bandwagonRefreshEvent();
+ },
+ error: function(){
+ fav_button.html(previous);
+ },
+ complete: function(){
+ fav_button.attr('disabled', '');
+ fav_button.removeClass('loading-fav');
+ }
+ });
+ });
+};
diff --git a/site/app/webroot/js/amo2009/global-mozilla.js b/site/app/webroot/js/amo2009/global-mozilla.js
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/site/app/webroot/js/amo2009/global-mozilla.js
diff --git a/site/app/webroot/js/amo2009/global.js b/site/app/webroot/js/amo2009/global.js
new file mode 100644
index 0000000..19e0912
--- /dev/null
+++ b/site/app/webroot/js/amo2009/global.js
@@ -0,0 +1,343 @@
+(function($) {
+ window.Slideshow = function() {
+ this.itemTotal = 0;
+ this.currentItem = 1;
+ this.itemWidth = 0;
+
+ // Set these properties when you instantiate an instance of this object.
+ this.speed = 300; // the speed in milliseconds of the animation
+
+ this.itemContainer = ''; // the selector for the element containing the items.
+ this.wrapperElement = ''; // the tagName that will wrap the itemContainer.
+ this.wrapperClass = ''; //the classname of the element that will wrap the itemContainer.
+ this.controlsMarkup = ''; // the markup for the controls.
+ this.leftController = ''; // the selector for the left controller.
+ this.rightContorller = ''; // the selector for the right controller.
+ this.activeClass = ''; // the classname to indicate that a controller is active.
+ this.container = ''; //the complete container for all of the slideshow
+ this.interval = null;
+ this.scroll = true;
+ };
+ Slideshow.prototype.init = function() {
+ this.itemTotal = parseInt($(this.itemContainer+'>li').length,10);
+ if (this.itemTotal <= 1) {
+ return;
+ }
+
+ $(this.itemContainer).wrap('<'+this.wrapperElement+' class="'+this.wrapperClass+'"></'+this.wrapperElement+'>');
+ this.itemWidth = this.getItemWidth();
+ // applying controls to 2nd parent rather than 1st fixes stacking context issue in FF2
+ $($(this.itemContainer).parents()[1]).append(this.controlsMarkup);
+ $(this.itemContainer+'>li').width(this.itemWidth+'px');
+
+ this.checkControls();
+
+ var self = this;
+ $(self.leftController).live('click', function() {
+ if ($(this).hasClass(self.activeClass)) {
+ self.moveToItem(self.currentItem-1);
+ }
+ self.scroll = false;
+ return false;
+ });
+
+ $(self.rightController).live('click', function() {
+ if ($(this).hasClass(self.activeClass)) {
+ self.moveToItem(self.currentItem+1);
+ }
+ self.scroll = false;
+ return false;
+ });
+
+ $(self.container).mouseenter(function() {
+ clearInterval(self.interval);
+ });
+
+ $(self.container).mouseleave(function() {
+ self.autoRotate();
+ })
+
+ self.autoRotate();
+
+ $(window).resize(function() {
+ self.itemWidth = self.getItemWidth();
+ $(self.itemContainer+'>li').width(self.itemWidth+'px');
+ self.popToItem(self.currentItem);
+ });
+ };
+
+ Slideshow.prototype.autoRotate = function() {
+ if(this.scroll) {
+ var that = this; //closure due to setInterval's 'this' refers to window, not the current 'this'
+ this.interval = setInterval(function() {
+ if(that.currentItem != that.itemTotal) {
+ that.moveToItem(that.currentItem+1);
+ } else {
+ that.moveToItem(1);
+ }
+ }, 8000);
+ }
+ };
+
+ Slideshow.prototype.getItemWidth = function() {
+ return $(this.itemContainer).parents('.'+this.wrapperClass).width();
+ };
+ Slideshow.prototype.popToItem = function(itemNumber) {
+ if (!$(this.itemContainer).parents('.'+this.wrapperClass+' :animated').length) {
+ var endpoint = (itemNumber-1) * this.itemWidth * -1;
+ $(this.itemContainer).css({'left':(endpoint+'px')});
+ this.currentItem = itemNumber;
+ this.checkControls();
+ }
+ };
+ Slideshow.prototype.moveToItem = function(itemNumber) {
+ if (!$(this.itemContainer).parents('.'+this.wrapperClass+' :animated').length) {
+ var endpoint = (itemNumber-1) * this.itemWidth * -1;
+ $(this.itemContainer).animate({'left':(endpoint+'px')},this.speed);
+ this.currentItem = itemNumber;
+ this.checkControls();
+ }
+ };
+ Slideshow.prototype.checkControls = function() {
+ if (this.currentItem == 1) {
+ $(this.leftController).removeClass(this.activeClass);
+ } else {
+ $(this.leftController).addClass(this.activeClass);
+ }
+ if (this.currentItem == this.itemTotal) {
+ $(this.rightController).removeClass(this.activeClass);
+ } else {
+ $(this.rightController).addClass(this.activeClass);
+ }
+ };
+
+ // slidey dropdown area
+ window.DropdownArea = function() {
+ this.trigger = null;
+ this.target = '';
+ this.targetParent = '';
+ this.callbackFunction = function(){};
+ this.preventDefault = true;
+ this.showSpeed = 200;
+ this.hideSpeed = 200;
+ };
+ DropdownArea.prototype.bodyclick = function(e) {
+ // this will get fired on click of body, we need to close the dropdown
+ if (this.bodyWatching) {
+ if (!
+ ($(e.target).get(0) == $(this.targetParent).get(0) ||
+ $(e.target).parents(this.targetParent).length)
+ ) {
+ this.hide();
+ }
+
+ }
+ }
+ DropdownArea.prototype.hide = function() {
+ var self = this;
+ $(self.targetParent).removeClass('expanded');
+ $(self.target).slideUp(self.hideSpeed, function() {
+ //unbind bodyclick
+ self.bodyWatching = false;
+ });
+ }
+ DropdownArea.prototype.show = function() {
+ var self = this;
+ $(self.targetParent).addClass('expanded');
+ $(self.target).slideDown(self.showSpeed, function() {
+ self.bodyWatching = true;
+ });
+ }
+ DropdownArea.prototype.init = function() {
+ // advanced dropdown
+ $(this.target).hide();
+ var self = this;
+ if (this.trigger) {
+ this.trigger.click(
+ function(e) {
+ if(! $(self.target+':animated').length) {
+ if ($(self.target+':visible').length){
+ self.hide();
+ } else {
+ self.callbackFunction();
+ self.show();
+ }
+ }
+ $(self.target).trigger('click');
+ return !self.preventDefault;
+ }
+ );
+ // if box now showing bind bodyclick
+ $('body').bind("click", function(e) {
+ self.bodyclick(e);
+ });
+ }
+ };
+})(jQuery);
+
+jQuery(function($) {
+ // Add the class "hasJS" to the body element.
+ $('body').addClass('hasJS');
+
+ // Greys out the favourites icon when it is clicked
+ $(".item-info li.favourite").click(function () {
+ var self = this;
+ $(self).addClass("favourite-loading");
+ setTimeout(function() {
+ $(self).addClass("favourite-added");
+ },2000);
+ });
+
+ function selectReplacement(obj) {
+ obj.className += ' replaced';
+ var ul = document.createElement('ul');
+ ul.className = 'selectReplacement';
+ var opts = obj.options;
+ for (var i=0; i<opts.length; i++) {
+ var selectedOpt;
+ if (opts[i].selected) {
+ selectedOpt = i;
+ break;
+ } else {
+ selectedOpt = 0;
+ }
+ }
+ for (var i=0; i<opts.length; i++) {
+ var li = document.createElement('li');
+ var link = document.createElement('a');
+ li.appendChild(link);
+ li.className = opts[i].className;
+ link.selIndex = opts[i].index;
+ link.selectID = obj.id;
+ link.setAttribute('href','#');
+ link.onclick = function() {
+ selectMe(this);
+ return false;
+ }
+ if (i == selectedOpt) {
+ ul.className = 'selectReplacement '+opts[i].className;
+ }
+ ul.appendChild(li);
+ }
+ obj.parentNode.insertBefore(ul,obj);
+ }
+ function selectMe(obj) {
+ setVal(obj.selectID, obj.selIndex);
+ var list = obj.parentNode.parentNode;
+ list.className = 'selectReplacement '+obj.parentNode.className;
+ }
+ function setVal(objID, selIndex) {
+ var obj = document.getElementById(objID);
+ obj.selectedIndex = selIndex;
+ }
+ if (document.getElementById('review-rating')) {
+ selectReplacement(document.getElementById('review-rating'));
+ }
+
+ // Categories dropdown only on pages where it is not in secondary
+ if($('.categories').parents('.secondary').length == 0) {
+ var categories = new DropdownArea();
+ // add class to style differently
+ $('.categories').addClass('dropdown-categories');
+
+ // set up images for dropdown
+ var categoryContainer = $('.categories :first-child')[0];
+ if (categoryContainer) {
+ var clickableCategories = $(categoryContainer);
+ clickableCategories.prepend('<img src="/img/amo2009/icons/category-dropdown-down.gif" alt="" /> ');
+
+ // stop the accidental selection during double click
+ clickableCategories.each(function(){
+ this.onselectstart = function () { return false; }
+ this.onmousedown = function () { return false; }
+ });
+
+ // set up variables for object
+ categories.trigger = clickableCategories; // node
+ categories.target = '.categories>ul'; // reference
+ categories.targetParent = '.categories'; // reference
+ categories.callbackFunction = function() {
+ if($('.categories>ul:visible').length){
+ $('.categories img').attr('src', '/img/amo2009/icons/category-dropdown-down.gif');
+ } else {
+ $('.categories img').attr('src', '/img/amo2009/icons/category-dropdown-up.gif');
+ }
+ };
+
+ // initialise dropdown area
+ categories.init();
+ }
+ }
+
+
+ // advanced form dropdown
+ var advancedForm = new DropdownArea();
+ // set up variables for object
+ advancedForm.trigger = ($('#advanced-link a')); // node
+ advancedForm.target = ('.advanced'); // reference
+ advancedForm.targetParent = ('.search-form'); // reference
+ advancedForm.init();
+
+ // tools dropdown in auxillary menu
+ var toolsDropdown = new DropdownArea();
+ // set up variables for object
+ toolsDropdown.trigger = ($('ul.tools .controller')); // node
+ toolsDropdown.target = ('ul.tools ul'); // reference
+ toolsDropdown.targetParent = ('ul.tools'); // reference
+ toolsDropdown.init();
+
+ // change dropdown in auxillary menu
+ var changeDropdown = new DropdownArea();
+ // set up variables for object
+ changeDropdown.trigger = ($('ul.change .controller')); // node
+ changeDropdown.target = ('ul.change ul'); // reference
+ changeDropdown.targetParent = ('ul.change'); // reference
+ changeDropdown.init();
+
+ // share dropdown
+ var shareDropdown = new DropdownArea();
+ // set up variables for object
+ shareDropdown.trigger = ($('.share-this a.share')); // node
+ shareDropdown.target = ('.share-this .share-networks'); // reference
+ shareDropdown.targetParent = ('.share-this'); // reference
+ shareDropdown.init();
+
+ // notification dropdown
+ var notificationHelpDropdown = new DropdownArea();
+ // set up variables for object
+ notificationHelpDropdown.trigger = ($('.notification .toggle-help')); // node
+ notificationHelpDropdown.target = ('.notification .toggle-info'); // reference
+ notificationHelpDropdown.targetParent = ('.notification'); // reference
+ notificationHelpDropdown.init();
+ $('.notification .toggle-info').append('<a href="#" class="close">close</a>')
+ $('.notification a.close').click(function() {
+ notificationHelpDropdown.hide();
+ return false;
+ })
+
+ // listing where interaction is inline
+ $('.home .listing div:first').addClass('interactive');
+
+ function tabClickFactory(className) {
+ return function(){
+ $(this).parents('ul').find('li').removeClass('selected');
+ $($(this).parents('li')[0]).addClass('selected');
+ $(this).parents('.listing').attr('class','featured listing');
+ $(this).parents('.listing').addClass(className);
+ return false;
+ }
+ }
+ $(".home a[href^='#recommended']").click(tabClickFactory('show-recommended'));
+ $(".home a[href^='#popular']").click(tabClickFactory('show-popular'));
+ $(".home a[href^='#added']").click(tabClickFactory('show-added'));
+ $(".home a[href^='#updated']").click(tabClickFactory('show-updated'));
+
+ $('a.screenshot.thumbnail').append('<img src="/img/amo2009/icons/resize.png" alt="click to expand image" class="img-control"/>')
+
+});
+
+jQuery(window).load(function() {
+ // Crazyweird fix lets us style abbr using CSS in IE
+ // - do NOT run onDomReady, must be onload
+ document.createElement('abbr');
+});
diff --git a/site/app/webroot/js/amo2009/home.js b/site/app/webroot/js/amo2009/home.js
new file mode 100644
index 0000000..d5aafcf
--- /dev/null
+++ b/site/app/webroot/js/amo2009/home.js
@@ -0,0 +1,66 @@
+jQuery(function($) {
+ // A special slideshow that updates the teaser 'selected' list item
+ function HeaderSlideshow() {
+ Slideshow.call(this);
+ }
+ HeaderSlideshow.prototype = new Slideshow();
+ HeaderSlideshow.prototype.moveToItem = function(itemNumber) {
+ Slideshow.prototype.moveToItem.call(this, itemNumber);
+ $('.section-teaser .teaser-header li').removeClass('selected');
+ $('.section-teaser .teaser-header li').eq(itemNumber - 1).addClass('selected');
+ };
+
+ var homepageSlider = new HeaderSlideshow();
+ homepageSlider.itemContainer = '.teaser-items';
+ homepageSlider.wrapperElement = 'div';
+ homepageSlider.wrapperClass = 'window';
+ homepageSlider.controlsMarkup = (
+ '<p class="slideshow-controls">' +
+ '<a href="#" class="prev" rel="prev">Previous</a>' +
+ '<a href="#" class="next" rel="next">Next</a></p>'
+ );
+ homepageSlider.leftController = '.section-teaser a[rel="prev"]';
+ homepageSlider.rightController = '.section-teaser a[rel="next"]';
+ homepageSlider.activeClass = 'active';
+ homepageSlider.container = '.section-teaser .featured-inner';
+ homepageSlider.init();
+
+ //Move the list of promo categories below the controls to allow all content to expand
+ $('.teaser-header').insertBefore(".slideshow-controls");
+
+ var headerListItems = $('.section-teaser .teaser-header li a');
+
+ headerListItems.click(function() {
+ headerListItems.parent('li').removeClass('selected');
+ $(this).parent('li').addClass('selected');
+ homepageSlider.moveToItem(headerListItems.index(this) + 1);
+ homepageSlider.scroll = false;
+ return false;
+ });
+
+ // Select the first one
+ $('.section-teaser .teaser-header li').eq(0).addClass('selected');
+
+ if ($(document.body).hasClass('user-login')) {
+ // If the user login detected, switch to the second item to skip intro.
+ homepageSlider.moveToItem(2);
+ } else {
+ // Show the intro to anon users for 5 visits, then switch to second item.
+ var SEEN_COOKIE = 'amo_home_promo_seen',
+ MAX_SEEN = 5,
+ times_seen = parseInt($.cookie(SEEN_COOKIE));
+ if (!times_seen) times_seen = 0;
+
+ if (times_seen >= MAX_SEEN) {
+ // If the intro has been seen enough times, skip it.
+ homepageSlider.moveToItem(2);
+ } else {
+ // Otherwise, count another appearance and stash in a cookie.
+ $.cookie(SEEN_COOKIE, times_seen + 1, {
+ path: '/',
+ expires: (new Date()).getTime() + ( 1000 * 60 * 60 * 24 * 365 )
+ });
+ }
+ }
+
+});
diff --git a/site/app/webroot/js/amo2009/jquery-1.3.2.min.js b/site/app/webroot/js/amo2009/jquery-1.3.2.min.js
new file mode 100644
index 0000000..b1ae21d
--- /dev/null
+++ b/site/app/webroot/js/amo2009/jquery-1.3.2.min.js
@@ -0,0 +1,19 @@
+/*
+ * jQuery JavaScript Library v1.3.2
+ * http://jquery.com/
+ *
+ * Copyright (c) 2009 John Resig
+ * Dual licensed under the MIT and GPL licenses.
+ * http://docs.jquery.com/License
+ *
+ * Date: 2009-02-19 17:34:21 -0500 (Thu, 19 Feb 2009)
+ * Revision: 6246
+ */
+(function(){var l=this,g,y=l.jQuery,p=l.$,o=l.jQuery=l.$=function(E,F){return new o.fn.init(E,F)},D=/^[^<]*(<(.|\s)+>)[^>]*$|^#([\w-]+)$/,f=/^.[^:#\[\.,]*$/;o.fn=o.prototype={init:function(E,H){E=E||document;if(E.nodeType){this[0]=E;this.length=1;this.context=E;return this}if(typeof E==="string"){var G=D.exec(E);if(G&&(G[1]||!H)){if(G[1]){E=o.clean([G[1]],H)}else{var I=document.getElementById(G[3]);if(I&&I.id!=G[3]){return o().find(E)}var F=o(I||[]);F.context=document;F.selector=E;return F}}else{return o(H).find(E)}}else{if(o.isFunction(E)){return o(document).ready(E)}}if(E.selector&&E.context){this.selector=E.selector;this.context=E.context}return this.setArray(o.isArray(E)?E:o.makeArray(E))},selector:"",jquery:"1.3.2",size:function(){return this.length},get:function(E){return E===g?Array.prototype.slice.call(this):this[E]},pushStack:function(F,H,E){var G=o(F);G.prevObject=this;G.context=this.context;if(H==="find"){G.selector=this.selector+(this.selector?" ":"")+E}else{if(H){G.selector=this.selector+"."+H+"("+E+")"}}return G},setArray:function(E){this.length=0;Array.prototype.push.apply(this,E);return this},each:function(F,E){return o.each(this,F,E)},index:function(E){return o.inArray(E&&E.jquery?E[0]:E,this)},attr:function(F,H,G){var E=F;if(typeof F==="string"){if(H===g){return this[0]&&o[G||"attr"](this[0],F)}else{E={};E[F]=H}}return this.each(function(I){for(F in E){o.attr(G?this.style:this,F,o.prop(this,E[F],G,I,F))}})},css:function(E,F){if((E=="width"||E=="height")&&parseFloat(F)<0){F=g}return this.attr(E,F,"curCSS")},text:function(F){if(typeof F!=="object"&&F!=null){return this.empty().append((this[0]&&this[0].ownerDocument||document).createTextNode(F))}var E="";o.each(F||this,function(){o.each(this.childNodes,function(){if(this.nodeType!=8){E+=this.nodeType!=1?this.nodeValue:o.fn.text([this])}})});return E},wrapAll:function(E){if(this[0]){var F=o(E,this[0].ownerDocument).clone();if(this[0].parentNode){F.insertBefore(this[0])}F.map(function(){var G=this;while(G.firstChild){G=G.firstChild}return G}).append(this)}return this},wrapInner:function(E){return this.each(function(){o(this).contents().wrapAll(E)})},wrap:function(E){return this.each(function(){o(this).wrapAll(E)})},append:function(){return this.domManip(arguments,true,function(E){if(this.nodeType==1){this.appendChild(E)}})},prepend:function(){return this.domManip(arguments,true,function(E){if(this.nodeType==1){this.insertBefore(E,this.firstChild)}})},before:function(){return this.domManip(arguments,false,function(E){this.parentNode.insertBefore(E,this)})},after:function(){return this.domManip(arguments,false,function(E){this.parentNode.insertBefore(E,this.nextSibling)})},end:function(){return this.prevObject||o([])},push:[].push,sort:[].sort,splice:[].splice,find:function(E){if(this.length===1){var F=this.pushStack([],"find",E);F.length=0;o.find(E,this[0],F);return F}else{return this.pushStack(o.unique(o.map(this,function(G){return o.find(E,G)})),"find",E)}},clone:function(G){var E=this.map(function(){if(!o.support.noCloneEvent&&!o.isXMLDoc(this)){var I=this.outerHTML;if(!I){var J=this.ownerDocument.createElement("div");J.appendChild(this.cloneNode(true));I=J.innerHTML}return o.clean([I.replace(/ jQuery\d+="(?:\d+|null)"/g,"").replace(/^\s*/,"")])[0]}else{return this.cloneNode(true)}});if(G===true){var H=this.find("*").andSelf(),F=0;E.find("*").andSelf().each(function(){if(this.nodeName!==H[F].nodeName){return}var I=o.data(H[F],"events");for(var K in I){for(var J in I[K]){o.event.add(this,K,I[K][J],I[K][J].data)}}F++})}return E},filter:function(E){return this.pushStack(o.isFunction(E)&&o.grep(this,function(G,F){return E.call(G,F)})||o.multiFilter(E,o.grep(this,function(F){return F.nodeType===1})),"filter",E)},closest:function(E){var G=o.expr.match.POS.test(E)?o(E):null,F=0;return this.map(function(){var H=this;while(H&&H.ownerDocument){if(G?G.index(H)>-1:o(H).is(E)){o.data(H,"closest",F);return H}H=H.parentNode;F++}})},not:function(E){if(typeof E==="string"){if(f.test(E)){return this.pushStack(o.multiFilter(E,this,true),"not",E)}else{E=o.multiFilter(E,this)}}var F=E.length&&E[E.length-1]!==g&&!E.nodeType;return this.filter(function(){return F?o.inArray(this,E)<0:this!=E})},add:function(E){return this.pushStack(o.unique(o.merge(this.get(),typeof E==="string"?o(E):o.makeArray(E))))},is:function(E){return !!E&&o.multiFilter(E,this).length>0},hasClass:function(E){return !!E&&this.is("."+E)},val:function(K){if(K===g){var E=this[0];if(E){if(o.nodeName(E,"option")){return(E.attributes.value||{}).specified?E.value:E.text}if(o.nodeName(E,"select")){var I=E.selectedIndex,L=[],M=E.options,H=E.type=="select-one";if(I<0){return null}for(var F=H?I:0,J=H?I+1:M.length;F<J;F++){var G=M[F];if(G.selected){K=o(G).val();if(H){return K}L.push(K)}}return L}return(E.value||"").replace(/\r/g,"")}return g}if(typeof K==="number"){K+=""}return this.each(function(){if(this.nodeType!=1){return}if(o.isArray(K)&&/radio|checkbox/.test(this.type)){this.checked=(o.inArray(this.value,K)>=0||o.inArray(this.name,K)>=0)}else{if(o.nodeName(this,"select")){var N=o.makeArray(K);o("option",this).each(function(){this.selected=(o.inArray(this.value,N)>=0||o.inArray(this.text,N)>=0)});if(!N.length){this.selectedIndex=-1}}else{this.value=K}}})},html:function(E){return E===g?(this[0]?this[0].innerHTML.replace(/ jQuery\d+="(?:\d+|null)"/g,""):null):this.empty().append(E)},replaceWith:function(E){return this.after(E).remove()},eq:function(E){return this.slice(E,+E+1)},slice:function(){return this.pushStack(Array.prototype.slice.apply(this,arguments),"slice",Array.prototype.slice.call(arguments).join(","))},map:function(E){return this.pushStack(o.map(this,function(G,F){return E.call(G,F,G)}))},andSelf:function(){return this.add(this.prevObject)},domManip:function(J,M,L){if(this[0]){var I=(this[0].ownerDocument||this[0]).createDocumentFragment(),F=o.clean(J,(this[0].ownerDocument||this[0]),I),H=I.firstChild;if(H){for(var G=0,E=this.length;G<E;G++){L.call(K(this[G],H),this.length>1||G>0?I.cloneNode(true):I)}}if(F){o.each(F,z)}}return this;function K(N,O){return M&&o.nodeName(N,"table")&&o.nodeName(O,"tr")?(N.getElementsByTagName("tbody")[0]||N.appendChild(N.ownerDocument.createElement("tbody"))):N}}};o.fn.init.prototype=o.fn;function z(E,F){if(F.src){o.ajax({url:F.src,async:false,dataType:"script"})}else{o.globalEval(F.text||F.textContent||F.innerHTML||"")}if(F.parentNode){F.parentNode.removeChild(F)}}function e(){return +new Date}o.extend=o.fn.extend=function(){var J=arguments[0]||{},H=1,I=arguments.length,E=false,G;if(typeof J==="boolean"){E=J;J=arguments[1]||{};H=2}if(typeof J!=="object"&&!o.isFunction(J)){J={}}if(I==H){J=this;--H}for(;H<I;H++){if((G=arguments[H])!=null){for(var F in G){var K=J[F],L=G[F];if(J===L){continue}if(E&&L&&typeof L==="object"&&!L.nodeType){J[F]=o.extend(E,K||(L.length!=null?[]:{}),L)}else{if(L!==g){J[F]=L}}}}}return J};var b=/z-?index|font-?weight|opacity|zoom|line-?height/i,q=document.defaultView||{},s=Object.prototype.toString;o.extend({noConflict:function(E){l.$=p;if(E){l.jQuery=y}return o},isFunction:function(E){return s.call(E)==="[object Function]"},isArray:function(E){return s.call(E)==="[object Array]"},isXMLDoc:function(E){return E.nodeType===9&&E.documentElement.nodeName!=="HTML"||!!E.ownerDocument&&o.isXMLDoc(E.ownerDocument)},globalEval:function(G){if(G&&/\S/.test(G)){var F=document.getElementsByTagName("head")[0]||document.documentElement,E=document.createElement("script");E.type="text/javascript";if(o.support.scriptEval){E.appendChild(document.createTextNode(G))}else{E.text=G}F.insertBefore(E,F.firstChild);F.removeChild(E)}},nodeName:function(F,E){return F.nodeName&&F.nodeName.toUpperCase()==E.toUpperCase()},each:function(G,K,F){var E,H=0,I=G.length;if(F){if(I===g){for(E in G){if(K.apply(G[E],F)===false){break}}}else{for(;H<I;){if(K.apply(G[H++],F)===false){break}}}}else{if(I===g){for(E in G){if(K.call(G[E],E,G[E])===false){break}}}else{for(var J=G[0];H<I&&K.call(J,H,J)!==false;J=G[++H]){}}}return G},prop:function(H,I,G,F,E){if(o.isFunction(I)){I=I.call(H,F)}return typeof I==="number"&&G=="curCSS"&&!b.test(E)?I+"px":I},className:{add:function(E,F){o.each((F||"").split(/\s+/),function(G,H){if(E.nodeType==1&&!o.className.has(E.className,H)){E.className+=(E.className?" ":"")+H}})},remove:function(E,F){if(E.nodeType==1){E.className=F!==g?o.grep(E.className.split(/\s+/),function(G){return !o.className.has(F,G)}).join(" "):""}},has:function(F,E){return F&&o.inArray(E,(F.className||F).toString().split(/\s+/))>-1}},swap:function(H,G,I){var E={};for(var F in G){E[F]=H.style[F];H.style[F]=G[F]}I.call(H);for(var F in G){H.style[F]=E[F]}},css:function(H,F,J,E){if(F=="width"||F=="height"){var L,G={position:"absolute",visibility:"hidden",display:"block"},K=F=="width"?["Left","Right"]:["Top","Bottom"];function I(){L=F=="width"?H.offsetWidth:H.offsetHeight;if(E==="border"){return}o.each(K,function(){if(!E){L-=parseFloat(o.curCSS(H,"padding"+this,true))||0}if(E==="margin"){L+=parseFloat(o.curCSS(H,"margin"+this,true))||0}else{L-=parseFloat(o.curCSS(H,"border"+this+"Width",true))||0}})}if(H.offsetWidth!==0){I()}else{o.swap(H,G,I)}return Math.max(0,Math.round(L))}return o.curCSS(H,F,J)},curCSS:function(I,F,G){var L,E=I.style;if(F=="opacity"&&!o.support.opacity){L=o.attr(E,"opacity");return L==""?"1":L}if(F.match(/float/i)){F=w}if(!G&&E&&E[F]){L=E[F]}else{if(q.getComputedStyle){if(F.match(/float/i)){F="float"}F=F.replace(/([A-Z])/g,"-$1").toLowerCase();var M=q.getComputedStyle(I,null);if(M){L=M.getPropertyValue(F)}if(F=="opacity"&&L==""){L="1"}}else{if(I.currentStyle){var J=F.replace(/\-(\w)/g,function(N,O){return O.toUpperCase()});L=I.currentStyle[F]||I.currentStyle[J];if(!/^\d+(px)?$/i.test(L)&&/^\d/.test(L)){var H=E.left,K=I.runtimeStyle.left;I.runtimeStyle.left=I.currentStyle.left;E.left=L||0;L=E.pixelLeft+"px";E.left=H;I.runtimeStyle.left=K}}}}return L},clean:function(F,K,I){K=K||document;if(typeof K.createElement==="undefined"){K=K.ownerDocument||K[0]&&K[0].ownerDocument||document}if(!I&&F.length===1&&typeof F[0]==="string"){var H=/^<(\w+)\s*\/?>$/.exec(F[0]);if(H){return[K.createElement(H[1])]}}var G=[],E=[],L=K.createElement("div");o.each(F,function(P,S){if(typeof S==="number"){S+=""}if(!S){return}if(typeof S==="string"){S=S.replace(/(<(\w+)[^>]*?)\/>/g,function(U,V,T){return T.match(/^(abbr|br|col|img|input|link|meta|param|hr|area|embed)$/i)?U:V+"></"+T+">"});var O=S.replace(/^\s+/,"").substring(0,10).toLowerCase();var Q=!O.indexOf("<opt")&&[1,"<select multiple='multiple'>","</select>"]||!O.indexOf("<leg")&&[1,"<fieldset>","</fieldset>"]||O.match(/^<(thead|tbody|tfoot|colg|cap)/)&&[1,"<table>","</table>"]||!O.indexOf("<tr")&&[2,"<table><tbody>","</tbody></table>"]||(!O.indexOf("<td")||!O.indexOf("<th"))&&[3,"<table><tbody><tr>","</tr></tbody></table>"]||!O.indexOf("<col")&&[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"]||!o.support.htmlSerialize&&[1,"div<div>","</div>"]||[0,"",""];L.innerHTML=Q[1]+S+Q[2];while(Q[0]--){L=L.lastChild}if(!o.support.tbody){var R=/<tbody/i.test(S),N=!O.indexOf("<table")&&!R?L.firstChild&&L.firstChild.childNodes:Q[1]=="<table>"&&!R?L.childNodes:[];for(var M=N.length-1;M>=0;--M){if(o.nodeName(N[M],"tbody")&&!N[M].childNodes.length){N[M].parentNode.removeChild(N[M])}}}if(!o.support.leadingWhitespace&&/^\s/.test(S)){L.insertBefore(K.createTextNode(S.match(/^\s*/)[0]),L.firstChild)}S=o.makeArray(L.childNodes)}if(S.nodeType){G.push(S)}else{G=o.merge(G,S)}});if(I){for(var J=0;G[J];J++){if(o.nodeName(G[J],"script")&&(!G[J].type||G[J].type.toLowerCase()==="text/javascript")){E.push(G[J].parentNode?G[J].parentNode.removeChild(G[J]):G[J])}else{if(G[J].nodeType===1){G.splice.apply(G,[J+1,0].concat(o.makeArray(G[J].getElementsByTagName("script"))))}I.appendChild(G[J])}}return E}return G},attr:function(J,G,K){if(!J||J.nodeType==3||J.nodeType==8){return g}var H=!o.isXMLDoc(J),L=K!==g;G=H&&o.props[G]||G;if(J.tagName){var F=/href|src|style/.test(G);if(G=="selected"&&J.parentNode){J.parentNode.selectedIndex}if(G in J&&H&&!F){if(L){if(G=="type"&&o.nodeName(J,"input")&&J.parentNode){throw"type property can't be changed"}J[G]=K}if(o.nodeName(J,"form")&&J.getAttributeNode(G)){return J.getAttributeNode(G).nodeValue}if(G=="tabIndex"){var I=J.getAttributeNode("tabIndex");return I&&I.specified?I.value:J.nodeName.match(/(button|input|object|select|textarea)/i)?0:J.nodeName.match(/^(a|area)$/i)&&J.href?0:g}return J[G]}if(!o.support.style&&H&&G=="style"){return o.attr(J.style,"cssText",K)}if(L){J.setAttribute(G,""+K)}var E=!o.support.hrefNormalized&&H&&F?J.getAttribute(G,2):J.getAttribute(G);return E===null?g:E}if(!o.support.opacity&&G=="opacity"){if(L){J.zoom=1;J.filter=(J.filter||"").replace(/alpha\([^)]*\)/,"")+(parseInt(K)+""=="NaN"?"":"alpha(opacity="+K*100+")")}return J.filter&&J.filter.indexOf("opacity=")>=0?(parseFloat(J.filter.match(/opacity=([^)]*)/)[1])/100)+"":""}G=G.replace(/-([a-z])/ig,function(M,N){return N.toUpperCase()});if(L){J[G]=K}return J[G]},trim:function(E){return(E||"").replace(/^\s+|\s+$/g,"")},makeArray:function(G){var E=[];if(G!=null){var F=G.length;if(F==null||typeof G==="string"||o.isFunction(G)||G.setInterval){E[0]=G}else{while(F){E[--F]=G[F]}}}return E},inArray:function(G,H){for(var E=0,F=H.length;E<F;E++){if(H[E]===G){return E}}return -1},merge:function(H,E){var F=0,G,I=H.length;if(!o.support.getAll){while((G=E[F++])!=null){if(G.nodeType!=8){H[I++]=G}}}else{while((G=E[F++])!=null){H[I++]=G}}return H},unique:function(K){var F=[],E={};try{for(var G=0,H=K.length;G<H;G++){var J=o.data(K[G]);if(!E[J]){E[J]=true;F.push(K[G])}}}catch(I){F=K}return F},grep:function(F,J,E){var G=[];for(var H=0,I=F.length;H<I;H++){if(!E!=!J(F[H],H)){G.push(F[H])}}return G},map:function(E,J){var F=[];for(var G=0,H=E.length;G<H;G++){var I=J(E[G],G);if(I!=null){F[F.length]=I}}return F.concat.apply([],F)}});var C=navigator.userAgent.toLowerCase();o.browser={version:(C.match(/.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/)||[0,"0"])[1],safari:/webkit/.test(C),opera:/opera/.test(C),msie:/msie/.test(C)&&!/opera/.test(C),mozilla:/mozilla/.test(C)&&!/(compatible|webkit)/.test(C)};o.each({parent:function(E){return E.parentNode},parents:function(E){return o.dir(E,"parentNode")},next:function(E){return o.nth(E,2,"nextSibling")},prev:function(E){return o.nth(E,2,"previousSibling")},nextAll:function(E){return o.dir(E,"nextSibling")},prevAll:function(E){return o.dir(E,"previousSibling")},siblings:function(E){return o.sibling(E.parentNode.firstChild,E)},children:function(E){return o.sibling(E.firstChild)},contents:function(E){return o.nodeName(E,"iframe")?E.contentDocument||E.contentWindow.document:o.makeArray(E.childNodes)}},function(E,F){o.fn[E]=function(G){var H=o.map(this,F);if(G&&typeof G=="string"){H=o.multiFilter(G,H)}return this.pushStack(o.unique(H),E,G)}});o.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(E,F){o.fn[E]=function(G){var J=[],L=o(G);for(var K=0,H=L.length;K<H;K++){var I=(K>0?this.clone(true):this).get();o.fn[F].apply(o(L[K]),I);J=J.concat(I)}return this.pushStack(J,E,G)}});o.each({removeAttr:function(E){o.attr(this,E,"");if(this.nodeType==1){this.removeAttribute(E)}},addClass:function(E){o.className.add(this,E)},removeClass:function(E){o.className.remove(this,E)},toggleClass:function(F,E){if(typeof E!=="boolean"){E=!o.className.has(this,F)}o.className[E?"add":"remove"](this,F)},remove:function(E){if(!E||o.filter(E,[this]).length){o("*",this).add([this]).each(function(){o.event.remove(this);o.removeData(this)});if(this.parentNode){this.parentNode.removeChild(this)}}},empty:function(){o(this).children().remove();while(this.firstChild){this.removeChild(this.firstChild)}}},function(E,F){o.fn[E]=function(){return this.each(F,arguments)}});function j(E,F){return E[0]&&parseInt(o.curCSS(E[0],F,true),10)||0}var h="jQuery"+e(),v=0,A={};o.extend({cache:{},data:function(F,E,G){F=F==l?A:F;var H=F[h];if(!H){H=F[h]=++v}if(E&&!o.cache[H]){o.cache[H]={}}if(G!==g){o.cache[H][E]=G}return E?o.cache[H][E]:H},removeData:function(F,E){F=F==l?A:F;var H=F[h];if(E){if(o.cache[H]){delete o.cache[H][E];E="";for(E in o.cache[H]){break}if(!E){o.removeData(F)}}}else{try{delete F[h]}catch(G){if(F.removeAttribute){F.removeAttribute(h)}}delete o.cache[H]}},queue:function(F,E,H){if(F){E=(E||"fx")+"queue";var G=o.data(F,E);if(!G||o.isArray(H)){G=o.data(F,E,o.makeArray(H))}else{if(H){G.push(H)}}}return G},dequeue:function(H,G){var E=o.queue(H,G),F=E.shift();if(!G||G==="fx"){F=E[0]}if(F!==g){F.call(H)}}});o.fn.extend({data:function(E,G){var H=E.split(".");H[1]=H[1]?"."+H[1]:"";if(G===g){var F=this.triggerHandler("getData"+H[1]+"!",[H[0]]);if(F===g&&this.length){F=o.data(this[0],E)}return F===g&&H[1]?this.data(H[0]):F}else{return this.trigger("setData"+H[1]+"!",[H[0],G]).each(function(){o.data(this,E,G)})}},removeData:function(E){return this.each(function(){o.removeData(this,E)})},queue:function(E,F){if(typeof E!=="string"){F=E;E="fx"}if(F===g){return o.queue(this[0],E)}return this.each(function(){var G=o.queue(this,E,F);if(E=="fx"&&G.length==1){G[0].call(this)}})},dequeue:function(E){return this.each(function(){o.dequeue(this,E)})}});
+/*
+ * Sizzle CSS Selector Engine - v0.9.3
+ * Copyright 2009, The Dojo Foundation
+ * Released under the MIT, BSD, and GPL Licenses.
+ * More information: http://sizzlejs.com/
+ */
+(function(){var R=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?/g,L=0,H=Object.prototype.toString;var F=function(Y,U,ab,ac){ab=ab||[];U=U||document;if(U.nodeType!==1&&U.nodeType!==9){return[]}if(!Y||typeof Y!=="string"){return ab}var Z=[],W,af,ai,T,ad,V,X=true;R.lastIndex=0;while((W=R.exec(Y))!==null){Z.push(W[1]);if(W[2]){V=RegExp.rightContext;break}}if(Z.length>1&&M.exec(Y)){if(Z.length===2&&I.relative[Z[0]]){af=J(Z[0]+Z[1],U)}else{af=I.relative[Z[0]]?[U]:F(Z.shift(),U);while(Z.length){Y=Z.shift();if(I.relative[Y]){Y+=Z.shift()}af=J(Y,af)}}}else{var ae=ac?{expr:Z.pop(),set:E(ac)}:F.find(Z.pop(),Z.length===1&&U.parentNode?U.parentNode:U,Q(U));af=F.filter(ae.expr,ae.set);if(Z.length>0){ai=E(af)}else{X=false}while(Z.length){var ah=Z.pop(),ag=ah;if(!I.relative[ah]){ah=""}else{ag=Z.pop()}if(ag==null){ag=U}I.relative[ah](ai,ag,Q(U))}}if(!ai){ai=af}if(!ai){throw"Syntax error, unrecognized expression: "+(ah||Y)}if(H.call(ai)==="[object Array]"){if(!X){ab.push.apply(ab,ai)}else{if(U.nodeType===1){for(var aa=0;ai[aa]!=null;aa++){if(ai[aa]&&(ai[aa]===true||ai[aa].nodeType===1&&K(U,ai[aa]))){ab.push(af[aa])}}}else{for(var aa=0;ai[aa]!=null;aa++){if(ai[aa]&&ai[aa].nodeType===1){ab.push(af[aa])}}}}}else{E(ai,ab)}if(V){F(V,U,ab,ac);if(G){hasDuplicate=false;ab.sort(G);if(hasDuplicate){for(var aa=1;aa<ab.length;aa++){if(ab[aa]===ab[aa-1]){ab.splice(aa--,1)}}}}}return ab};F.matches=function(T,U){return F(T,null,null,U)};F.find=function(aa,T,ab){var Z,X;if(!aa){return[]}for(var W=0,V=I.order.length;W<V;W++){var Y=I.order[W],X;if((X=I.match[Y].exec(aa))){var U=RegExp.leftContext;if(U.substr(U.length-1)!=="\\"){X[1]=(X[1]||"").replace(/\\/g,"");Z=I.find[Y](X,T,ab);if(Z!=null){aa=aa.replace(I.match[Y],"");break}}}}if(!Z){Z=T.getElementsByTagName("*")}return{set:Z,expr:aa}};F.filter=function(ad,ac,ag,W){var V=ad,ai=[],aa=ac,Y,T,Z=ac&&ac[0]&&Q(ac[0]);while(ad&&ac.length){for(var ab in I.filter){if((Y=I.match[ab].exec(ad))!=null){var U=I.filter[ab],ah,af;T=false;if(aa==ai){ai=[]}if(I.preFilter[ab]){Y=I.preFilter[ab](Y,aa,ag,ai,W,Z);if(!Y){T=ah=true}else{if(Y===true){continue}}}if(Y){for(var X=0;(af=aa[X])!=null;X++){if(af){ah=U(af,Y,X,aa);var ae=W^!!ah;if(ag&&ah!=null){if(ae){T=true}else{aa[X]=false}}else{if(ae){ai.push(af);T=true}}}}}if(ah!==g){if(!ag){aa=ai}ad=ad.replace(I.match[ab],"");if(!T){return[]}break}}}if(ad==V){if(T==null){throw"Syntax error, unrecognized expression: "+ad}else{break}}V=ad}return aa};var I=F.selectors={order:["ID","NAME","TAG"],match:{ID:/#((?:[\w\u00c0-\uFFFF_-]|\\.)+)/,CLASS:/\.((?:[\w\u00c0-\uFFFF_-]|\\.)+)/,NAME:/\[name=['"]*((?:[\w\u00c0-\uFFFF_-]|\\.)+)['"]*\]/,ATTR:/\[\s*((?:[\w\u00c0-\uFFFF_-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,TAG:/^((?:[\w\u00c0-\uFFFF\*_-]|\\.)+)/,CHILD:/:(only|nth|last|first)-child(?:\((even|odd|[\dn+-]*)\))?/,POS:/:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^-]|$)/,PSEUDO:/:((?:[\w\u00c0-\uFFFF_-]|\\.)+)(?:\((['"]*)((?:\([^\)]+\)|[^\2\(\)]*)+)\2\))?/},attrMap:{"class":"className","for":"htmlFor"},attrHandle:{href:function(T){return T.getAttribute("href")}},relative:{"+":function(aa,T,Z){var X=typeof T==="string",ab=X&&!/\W/.test(T),Y=X&&!ab;if(ab&&!Z){T=T.toUpperCase()}for(var W=0,V=aa.length,U;W<V;W++){if((U=aa[W])){while((U=U.previousSibling)&&U.nodeType!==1){}aa[W]=Y||U&&U.nodeName===T?U||false:U===T}}if(Y){F.filter(T,aa,true)}},">":function(Z,U,aa){var X=typeof U==="string";if(X&&!/\W/.test(U)){U=aa?U:U.toUpperCase();for(var V=0,T=Z.length;V<T;V++){var Y=Z[V];if(Y){var W=Y.parentNode;Z[V]=W.nodeName===U?W:false}}}else{for(var V=0,T=Z.length;V<T;V++){var Y=Z[V];if(Y){Z[V]=X?Y.parentNode:Y.parentNode===U}}if(X){F.filter(U,Z,true)}}},"":function(W,U,Y){var V=L++,T=S;if(!U.match(/\W/)){var X=U=Y?U:U.toUpperCase();T=P}T("parentNode",U,V,W,X,Y)},"~":function(W,U,Y){var V=L++,T=S;if(typeof U==="string"&&!U.match(/\W/)){var X=U=Y?U:U.toUpperCase();T=P}T("previousSibling",U,V,W,X,Y)}},find:{ID:function(U,V,W){if(typeof V.getElementById!=="undefined"&&!W){var T=V.getElementById(U[1]);return T?[T]:[]}},NAME:function(V,Y,Z){if(typeof Y.getElementsByName!=="undefined"){var U=[],X=Y.getElementsByName(V[1]);for(var W=0,T=X.length;W<T;W++){if(X[W].getAttribute("name")===V[1]){U.push(X[W])}}return U.length===0?null:U}},TAG:function(T,U){return U.getElementsByTagName(T[1])}},preFilter:{CLASS:function(W,U,V,T,Z,aa){W=" "+W[1].replace(/\\/g,"")+" ";if(aa){return W}for(var X=0,Y;(Y=U[X])!=null;X++){if(Y){if(Z^(Y.className&&(" "+Y.className+" ").indexOf(W)>=0)){if(!V){T.push(Y)}}else{if(V){U[X]=false}}}}return false},ID:function(T){return T[1].replace(/\\/g,"")},TAG:function(U,T){for(var V=0;T[V]===false;V++){}return T[V]&&Q(T[V])?U[1]:U[1].toUpperCase()},CHILD:function(T){if(T[1]=="nth"){var U=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(T[2]=="even"&&"2n"||T[2]=="odd"&&"2n+1"||!/\D/.test(T[2])&&"0n+"+T[2]||T[2]);T[2]=(U[1]+(U[2]||1))-0;T[3]=U[3]-0}T[0]=L++;return T},ATTR:function(X,U,V,T,Y,Z){var W=X[1].replace(/\\/g,"");if(!Z&&I.attrMap[W]){X[1]=I.attrMap[W]}if(X[2]==="~="){X[4]=" "+X[4]+" "}return X},PSEUDO:function(X,U,V,T,Y){if(X[1]==="not"){if(X[3].match(R).length>1||/^\w/.test(X[3])){X[3]=F(X[3],null,null,U)}else{var W=F.filter(X[3],U,V,true^Y);if(!V){T.push.apply(T,W)}return false}}else{if(I.match.POS.test(X[0])||I.match.CHILD.test(X[0])){return true}}return X},POS:function(T){T.unshift(true);return T}},filters:{enabled:function(T){return T.disabled===false&&T.type!=="hidden"},disabled:function(T){return T.disabled===true},checked:function(T){return T.checked===true},selected:function(T){T.parentNode.selectedIndex;return T.selected===true},parent:function(T){return !!T.firstChild},empty:function(T){return !T.firstChild},has:function(V,U,T){return !!F(T[3],V).length},header:function(T){return/h\d/i.test(T.nodeName)},text:function(T){return"text"===T.type},radio:function(T){return"radio"===T.type},checkbox:function(T){return"checkbox"===T.type},file:function(T){return"file"===T.type},password:function(T){return"password"===T.type},submit:function(T){return"submit"===T.type},image:function(T){return"image"===T.type},reset:function(T){return"reset"===T.type},button:function(T){return"button"===T.type||T.nodeName.toUpperCase()==="BUTTON"},input:function(T){return/input|select|textarea|button/i.test(T.nodeName)}},setFilters:{first:function(U,T){return T===0},last:function(V,U,T,W){return U===W.length-1},even:function(U,T){return T%2===0},odd:function(U,T){return T%2===1},lt:function(V,U,T){return U<T[3]-0},gt:function(V,U,T){return U>T[3]-0},nth:function(V,U,T){return T[3]-0==U},eq:function(V,U,T){return T[3]-0==U}},filter:{PSEUDO:function(Z,V,W,aa){var U=V[1],X=I.filters[U];if(X){return X(Z,W,V,aa)}else{if(U==="contains"){return(Z.textContent||Z.innerText||"").indexOf(V[3])>=0}else{if(U==="not"){var Y=V[3];for(var W=0,T=Y.length;W<T;W++){if(Y[W]===Z){return false}}return true}}}},CHILD:function(T,W){var Z=W[1],U=T;switch(Z){case"only":case"first":while(U=U.previousSibling){if(U.nodeType===1){return false}}if(Z=="first"){return true}U=T;case"last":while(U=U.nextSibling){if(U.nodeType===1){return false}}return true;case"nth":var V=W[2],ac=W[3];if(V==1&&ac==0){return true}var Y=W[0],ab=T.parentNode;if(ab&&(ab.sizcache!==Y||!T.nodeIndex)){var X=0;for(U=ab.firstChild;U;U=U.nextSibling){if(U.nodeType===1){U.nodeIndex=++X}}ab.sizcache=Y}var aa=T.nodeIndex-ac;if(V==0){return aa==0}else{return(aa%V==0&&aa/V>=0)}}},ID:function(U,T){return U.nodeType===1&&U.getAttribute("id")===T},TAG:function(U,T){return(T==="*"&&U.nodeType===1)||U.nodeName===T},CLASS:function(U,T){return(" "+(U.className||U.getAttribute("class"))+" ").indexOf(T)>-1},ATTR:function(Y,W){var V=W[1],T=I.attrHandle[V]?I.attrHandle[V](Y):Y[V]!=null?Y[V]:Y.getAttribute(V),Z=T+"",X=W[2],U=W[4];return T==null?X==="!=":X==="="?Z===U:X==="*="?Z.indexOf(U)>=0:X==="~="?(" "+Z+" ").indexOf(U)>=0:!U?Z&&T!==false:X==="!="?Z!=U:X==="^="?Z.indexOf(U)===0:X==="$="?Z.substr(Z.length-U.length)===U:X==="|="?Z===U||Z.substr(0,U.length+1)===U+"-":false},POS:function(X,U,V,Y){var T=U[2],W=I.setFilters[T];if(W){return W(X,V,U,Y)}}}};var M=I.match.POS;for(var O in I.match){I.match[O]=RegExp(I.match[O].source+/(?![^\[]*\])(?![^\(]*\))/.source)}var E=function(U,T){U=Array.prototype.slice.call(U);if(T){T.push.apply(T,U);return T}return U};try{Array.prototype.slice.call(document.documentElement.childNodes)}catch(N){E=function(X,W){var U=W||[];if(H.call(X)==="[object Array]"){Array.prototype.push.apply(U,X)}else{if(typeof X.length==="number"){for(var V=0,T=X.length;V<T;V++){U.push(X[V])}}else{for(var V=0;X[V];V++){U.push(X[V])}}}return U}}var G;if(document.documentElement.compareDocumentPosition){G=function(U,T){var V=U.compareDocumentPosition(T)&4?-1:U===T?0:1;if(V===0){hasDuplicate=true}return V}}else{if("sourceIndex" in document.documentElement){G=function(U,T){var V=U.sourceIndex-T.sourceIndex;if(V===0){hasDuplicate=true}return V}}else{if(document.createRange){G=function(W,U){var V=W.ownerDocument.createRange(),T=U.ownerDocument.createRange();V.selectNode(W);V.collapse(true);T.selectNode(U);T.collapse(true);var X=V.compareBoundaryPoints(Range.START_TO_END,T);if(X===0){hasDuplicate=true}return X}}}}(function(){var U=document.createElement("form"),V="script"+(new Date).getTime();U.innerHTML="<input name='"+V+"'/>";var T=document.documentElement;T.insertBefore(U,T.firstChild);if(!!document.getElementById(V)){I.find.ID=function(X,Y,Z){if(typeof Y.getElementById!=="undefined"&&!Z){var W=Y.getElementById(X[1]);return W?W.id===X[1]||typeof W.getAttributeNode!=="undefined"&&W.getAttributeNode("id").nodeValue===X[1]?[W]:g:[]}};I.filter.ID=function(Y,W){var X=typeof Y.getAttributeNode!=="undefined"&&Y.getAttributeNode("id");return Y.nodeType===1&&X&&X.nodeValue===W}}T.removeChild(U)})();(function(){var T=document.createElement("div");T.appendChild(document.createComment(""));if(T.getElementsByTagName("*").length>0){I.find.TAG=function(U,Y){var X=Y.getElementsByTagName(U[1]);if(U[1]==="*"){var W=[];for(var V=0;X[V];V++){if(X[V].nodeType===1){W.push(X[V])}}X=W}return X}}T.innerHTML="<a href='#'></a>";if(T.firstChild&&typeof T.firstChild.getAttribute!=="undefined"&&T.firstChild.getAttribute("href")!=="#"){I.attrHandle.href=function(U){return U.getAttribute("href",2)}}})();if(document.querySelectorAll){(function(){var T=F,U=document.createElement("div");U.innerHTML="<p class='TEST'></p>";if(U.querySelectorAll&&U.querySelectorAll(".TEST").length===0){return}F=function(Y,X,V,W){X=X||document;if(!W&&X.nodeType===9&&!Q(X)){try{return E(X.querySelectorAll(Y),V)}catch(Z){}}return T(Y,X,V,W)};F.find=T.find;F.filter=T.filter;F.selectors=T.selectors;F.matches=T.matches})()}if(document.getElementsByClassName&&document.documentElement.getElementsByClassName){(function(){var T=document.createElement("div");T.innerHTML="<div class='test e'></div><div class='test'></div>";if(T.getElementsByClassName("e").length===0){return}T.lastChild.className="e";if(T.getElementsByClassName("e").length===1){return}I.order.splice(1,0,"CLASS");I.find.CLASS=function(U,V,W){if(typeof V.getElementsByClassName!=="undefined"&&!W){return V.getElementsByClassName(U[1])}}})()}function P(U,Z,Y,ad,aa,ac){var ab=U=="previousSibling"&&!ac;for(var W=0,V=ad.length;W<V;W++){var T=ad[W];if(T){if(ab&&T.nodeType===1){T.sizcache=Y;T.sizset=W}T=T[U];var X=false;while(T){if(T.sizcache===Y){X=ad[T.sizset];break}if(T.nodeType===1&&!ac){T.sizcache=Y;T.sizset=W}if(T.nodeName===Z){X=T;break}T=T[U]}ad[W]=X}}}function S(U,Z,Y,ad,aa,ac){var ab=U=="previousSibling"&&!ac;for(var W=0,V=ad.length;W<V;W++){var T=ad[W];if(T){if(ab&&T.nodeType===1){T.sizcache=Y;T.sizset=W}T=T[U];var X=false;while(T){if(T.sizcache===Y){X=ad[T.sizset];break}if(T.nodeType===1){if(!ac){T.sizcache=Y;T.sizset=W}if(typeof Z!=="string"){if(T===Z){X=true;break}}else{if(F.filter(Z,[T]).length>0){X=T;break}}}T=T[U]}ad[W]=X}}}var K=document.compareDocumentPosition?function(U,T){return U.compareDocumentPosition(T)&16}:function(U,T){return U!==T&&(U.contains?U.contains(T):true)};var Q=function(T){return T.nodeType===9&&T.documentElement.nodeName!=="HTML"||!!T.ownerDocument&&Q(T.ownerDocument)};var J=function(T,aa){var W=[],X="",Y,V=aa.nodeType?[aa]:aa;while((Y=I.match.PSEUDO.exec(T))){X+=Y[0];T=T.replace(I.match.PSEUDO,"")}T=I.relative[T]?T+"*":T;for(var Z=0,U=V.length;Z<U;Z++){F(T,V[Z],W)}return F.filter(X,W)};o.find=F;o.filter=F.filter;o.expr=F.selectors;o.expr[":"]=o.expr.filters;F.selectors.filters.hidden=function(T){return T.offsetWidth===0||T.offsetHeight===0};F.selectors.filters.visible=function(T){return T.offsetWidth>0||T.offsetHeight>0};F.selectors.filters.animated=function(T){return o.grep(o.timers,function(U){return T===U.elem}).length};o.multiFilter=function(V,T,U){if(U){V=":not("+V+")"}return F.matches(V,T)};o.dir=function(V,U){var T=[],W=V[U];while(W&&W!=document){if(W.nodeType==1){T.push(W)}W=W[U]}return T};o.nth=function(X,T,V,W){T=T||1;var U=0;for(;X;X=X[V]){if(X.nodeType==1&&++U==T){break}}return X};o.sibling=function(V,U){var T=[];for(;V;V=V.nextSibling){if(V.nodeType==1&&V!=U){T.push(V)}}return T};return;l.Sizzle=F})();o.event={add:function(I,F,H,K){if(I.nodeType==3||I.nodeType==8){return}if(I.setInterval&&I!=l){I=l}if(!H.guid){H.guid=this.guid++}if(K!==g){var G=H;H=this.proxy(G);H.data=K}var E=o.data(I,"events")||o.data(I,"events",{}),J=o.data(I,"handle")||o.data(I,"handle",function(){return typeof o!=="undefined"&&!o.event.triggered?o.event.handle.apply(arguments.callee.elem,arguments):g});J.elem=I;o.each(F.split(/\s+/),function(M,N){var O=N.split(".");N=O.shift();H.type=O.slice().sort().join(".");var L=E[N];if(o.event.specialAll[N]){o.event.specialAll[N].setup.call(I,K,O)}if(!L){L=E[N]={};if(!o.event.special[N]||o.event.special[N].setup.call(I,K,O)===false){if(I.addEventListener){I.addEventListener(N,J,false)}else{if(I.attachEvent){I.attachEvent("on"+N,J)}}}}L[H.guid]=H;o.event.global[N]=true});I=null},guid:1,global:{},remove:function(K,H,J){if(K.nodeType==3||K.nodeType==8){return}var G=o.data(K,"events"),F,E;if(G){if(H===g||(typeof H==="string"&&H.charAt(0)==".")){for(var I in G){this.remove(K,I+(H||""))}}else{if(H.type){J=H.handler;H=H.type}o.each(H.split(/\s+/),function(M,O){var Q=O.split(".");O=Q.shift();var N=RegExp("(^|\\.)"+Q.slice().sort().join(".*\\.")+"(\\.|$)");if(G[O]){if(J){delete G[O][J.guid]}else{for(var P in G[O]){if(N.test(G[O][P].type)){delete G[O][P]}}}if(o.event.specialAll[O]){o.event.specialAll[O].teardown.call(K,Q)}for(F in G[O]){break}if(!F){if(!o.event.special[O]||o.event.special[O].teardown.call(K,Q)===false){if(K.removeEventListener){K.removeEventListener(O,o.data(K,"handle"),false)}else{if(K.detachEvent){K.detachEvent("on"+O,o.data(K,"handle"))}}}F=null;delete G[O]}}})}for(F in G){break}if(!F){var L=o.data(K,"handle");if(L){L.elem=null}o.removeData(K,"events");o.removeData(K,"handle")}}},trigger:function(I,K,H,E){var G=I.type||I;if(!E){I=typeof I==="object"?I[h]?I:o.extend(o.Event(G),I):o.Event(G);if(G.indexOf("!")>=0){I.type=G=G.slice(0,-1);I.exclusive=true}if(!H){I.stopPropagation();if(this.global[G]){o.each(o.cache,function(){if(this.events&&this.events[G]){o.event.trigger(I,K,this.handle.elem)}})}}if(!H||H.nodeType==3||H.nodeType==8){return g}I.result=g;I.target=H;K=o.makeArray(K);K.unshift(I)}I.currentTarget=H;var J=o.data(H,"handle");if(J){J.apply(H,K)}if((!H[G]||(o.nodeName(H,"a")&&G=="click"))&&H["on"+G]&&H["on"+G].apply(H,K)===false){I.result=false}if(!E&&H[G]&&!I.isDefaultPrevented()&&!(o.nodeName(H,"a")&&G=="click")){this.triggered=true;try{H[G]()}catch(L){}}this.triggered=false;if(!I.isPropagationStopped()){var F=H.parentNode||H.ownerDocument;if(F){o.event.trigger(I,K,F,true)}}},handle:function(K){var J,E;K=arguments[0]=o.event.fix(K||l.event);K.currentTarget=this;var L=K.type.split(".");K.type=L.shift();J=!L.length&&!K.exclusive;var I=RegExp("(^|\\.)"+L.slice().sort().join(".*\\.")+"(\\.|$)");E=(o.data(this,"events")||{})[K.type];for(var G in E){var H=E[G];if(J||I.test(H.type)){K.handler=H;K.data=H.data;var F=H.apply(this,arguments);if(F!==g){K.result=F;if(F===false){K.preventDefault();K.stopPropagation()}}if(K.isImmediatePropagationStopped()){break}}}},props:"altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode metaKey newValue originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),fix:function(H){if(H[h]){return H}var F=H;H=o.Event(F);for(var G=this.props.length,J;G;){J=this.props[--G];H[J]=F[J]}if(!H.target){H.target=H.srcElement||document}if(H.target.nodeType==3){H.target=H.target.parentNode}if(!H.relatedTarget&&H.fromElement){H.relatedTarget=H.fromElement==H.target?H.toElement:H.fromElement}if(H.pageX==null&&H.clientX!=null){var I=document.documentElement,E=document.body;H.pageX=H.clientX+(I&&I.scrollLeft||E&&E.scrollLeft||0)-(I.clientLeft||0);H.pageY=H.clientY+(I&&I.scrollTop||E&&E.scrollTop||0)-(I.clientTop||0)}if(!H.which&&((H.charCode||H.charCode===0)?H.charCode:H.keyCode)){H.which=H.charCode||H.keyCode}if(!H.metaKey&&H.ctrlKey){H.metaKey=H.ctrlKey}if(!H.which&&H.button){H.which=(H.button&1?1:(H.button&2?3:(H.button&4?2:0)))}return H},proxy:function(F,E){E=E||function(){return F.apply(this,arguments)};E.guid=F.guid=F.guid||E.guid||this.guid++;return E},special:{ready:{setup:B,teardown:function(){}}},specialAll:{live:{setup:function(E,F){o.event.add(this,F[0],c)},teardown:function(G){if(G.length){var E=0,F=RegExp("(^|\\.)"+G[0]+"(\\.|$)");o.each((o.data(this,"events").live||{}),function(){if(F.test(this.type)){E++}});if(E<1){o.event.remove(this,G[0],c)}}}}}};o.Event=function(E){if(!this.preventDefault){return new o.Event(E)}if(E&&E.type){this.originalEvent=E;this.type=E.type}else{this.type=E}this.timeStamp=e();this[h]=true};function k(){return false}function u(){return true}o.Event.prototype={preventDefault:function(){this.isDefaultPrevented=u;var E=this.originalEvent;if(!E){return}if(E.preventDefault){E.preventDefault()}E.returnValue=false},stopPropagation:function(){this.isPropagationStopped=u;var E=this.originalEvent;if(!E){return}if(E.stopPropagation){E.stopPropagation()}E.cancelBubble=true},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=u;this.stopPropagation()},isDefaultPrevented:k,isPropagationStopped:k,isImmediatePropagationStopped:k};var a=function(F){var E=F.relatedTarget;while(E&&E!=this){try{E=E.parentNode}catch(G){E=this}}if(E!=this){F.type=F.data;o.event.handle.apply(this,arguments)}};o.each({mouseover:"mouseenter",mouseout:"mouseleave"},function(F,E){o.event.special[E]={setup:function(){o.event.add(this,F,a,E)},teardown:function(){o.event.remove(this,F,a)}}});o.fn.extend({bind:function(F,G,E){return F=="unload"?this.one(F,G,E):this.each(function(){o.event.add(this,F,E||G,E&&G)})},one:function(G,H,F){var E=o.event.proxy(F||H,function(I){o(this).unbind(I,E);return(F||H).apply(this,arguments)});return this.each(function(){o.event.add(this,G,E,F&&H)})},unbind:function(F,E){return this.each(function(){o.event.remove(this,F,E)})},trigger:function(E,F){return this.each(function(){o.event.trigger(E,F,this)})},triggerHandler:function(E,G){if(this[0]){var F=o.Event(E);F.preventDefault();F.stopPropagation();o.event.trigger(F,G,this[0]);return F.result}},toggle:function(G){var E=arguments,F=1;while(F<E.length){o.event.proxy(G,E[F++])}return this.click(o.event.proxy(G,function(H){this.lastToggle=(this.lastToggle||0)%F;H.preventDefault();return E[this.lastToggle++].apply(this,arguments)||false}))},hover:function(E,F){return this.mouseenter(E).mouseleave(F)},ready:function(E){B();if(o.isReady){E.call(document,o)}else{o.readyList.push(E)}return this},live:function(G,F){var E=o.event.proxy(F);E.guid+=this.selector+G;o(document).bind(i(G,this.selector),this.selector,E);return this},die:function(F,E){o(document).unbind(i(F,this.selector),E?{guid:E.guid+this.selector+F}:null);return this}});function c(H){var E=RegExp("(^|\\.)"+H.type+"(\\.|$)"),G=true,F=[];o.each(o.data(this,"events").live||[],function(I,J){if(E.test(J.type)){var K=o(H.target).closest(J.data)[0];if(K){F.push({elem:K,fn:J})}}});F.sort(function(J,I){return o.data(J.elem,"closest")-o.data(I.elem,"closest")});o.each(F,function(){if(this.fn.call(this.elem,H,this.fn.data)===false){return(G=false)}});return G}function i(F,E){return["live",F,E.replace(/\./g,"`").replace(/ /g,"|")].join(".")}o.extend({isReady:false,readyList:[],ready:function(){if(!o.isReady){o.isReady=true;if(o.readyList){o.each(o.readyList,function(){this.call(document,o)});o.readyList=null}o(document).triggerHandler("ready")}}});var x=false;function B(){if(x){return}x=true;if(document.addEventListener){document.addEventListener("DOMContentLoaded",function(){document.removeEventListener("DOMContentLoaded",arguments.callee,false);o.ready()},false)}else{if(document.attachEvent){document.attachEvent("onreadystatechange",function(){if(document.readyState==="complete"){document.detachEvent("onreadystatechange",arguments.callee);o.ready()}});if(document.documentElement.doScroll&&l==l.top){(function(){if(o.isReady){return}try{document.documentElement.doScroll("left")}catch(E){setTimeout(arguments.callee,0);return}o.ready()})()}}}o.event.add(l,"load",o.ready)}o.each(("blur,focus,load,resize,scroll,unload,click,dblclick,mousedown,mouseup,mousemove,mouseover,mouseout,mouseenter,mouseleave,change,select,submit,keydown,keypress,keyup,error").split(","),function(F,E){o.fn[E]=function(G){return G?this.bind(E,G):this.trigger(E)}});o(l).bind("unload",function(){for(var E in o.cache){if(E!=1&&o.cache[E].handle){o.event.remove(o.cache[E].handle.elem)}}});(function(){o.support={};var F=document.documentElement,G=document.createElement("script"),K=document.createElement("div"),J="script"+(new Date).getTime();K.style.display="none";K.innerHTML=' <link/><table></table><a href="/a" style="color:red;float:left;opacity:.5;">a</a><select><option>text</option></select><object><param/></object>';var H=K.getElementsByTagName("*"),E=K.getElementsByTagName("a")[0];if(!H||!H.length||!E){return}o.support={leadingWhitespace:K.firstChild.nodeType==3,tbody:!K.getElementsByTagName("tbody").length,objectAll:!!K.getElementsByTagName("object")[0].getElementsByTagName("*").length,htmlSerialize:!!K.getElementsByTagName("link").length,style:/red/.test(E.getAttribute("style")),hrefNormalized:E.getAttribute("href")==="/a",opacity:E.style.opacity==="0.5",cssFloat:!!E.style.cssFloat,scriptEval:false,noCloneEvent:true,boxModel:null};G.type="text/javascript";try{G.appendChild(document.createTextNode("window."+J+"=1;"))}catch(I){}F.insertBefore(G,F.firstChild);if(l[J]){o.support.scriptEval=true;delete l[J]}F.removeChild(G);if(K.attachEvent&&K.fireEvent){K.attachEvent("onclick",function(){o.support.noCloneEvent=false;K.detachEvent("onclick",arguments.callee)});K.cloneNode(true).fireEvent("onclick")}o(function(){var L=document.createElement("div");L.style.width=L.style.paddingLeft="1px";document.body.appendChild(L);o.boxModel=o.support.boxModel=L.offsetWidth===2;document.body.removeChild(L).style.display="none"})})();var w=o.support.cssFloat?"cssFloat":"styleFloat";o.props={"for":"htmlFor","class":"className","float":w,cssFloat:w,styleFloat:w,readonly:"readOnly",maxlength:"maxLength",cellspacing:"cellSpacing",rowspan:"rowSpan",tabindex:"tabIndex"};o.fn.extend({_load:o.fn.load,load:function(G,J,K){if(typeof G!=="string"){return this._load(G)}var I=G.indexOf(" ");if(I>=0){var E=G.slice(I,G.length);G=G.slice(0,I)}var H="GET";if(J){if(o.isFunction(J)){K=J;J=null}else{if(typeof J==="object"){J=o.param(J);H="POST"}}}var F=this;o.ajax({url:G,type:H,dataType:"html",data:J,complete:function(M,L){if(L=="success"||L=="notmodified"){F.html(E?o("<div/>").append(M.responseText.replace(/<script(.|\s)*?\/script>/g,"")).find(E):M.responseText)}if(K){F.each(K,[M.responseText,L,M])}}});return this},serialize:function(){return o.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?o.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||/select|textarea/i.test(this.nodeName)||/text|hidden|password|search/i.test(this.type))}).map(function(E,F){var G=o(this).val();return G==null?null:o.isArray(G)?o.map(G,function(I,H){return{name:F.name,value:I}}):{name:F.name,value:G}}).get()}});o.each("ajaxStart,ajaxStop,ajaxComplete,ajaxError,ajaxSuccess,ajaxSend".split(","),function(E,F){o.fn[F]=function(G){return this.bind(F,G)}});var r=e();o.extend({get:function(E,G,H,F){if(o.isFunction(G)){H=G;G=null}return o.ajax({type:"GET",url:E,data:G,success:H,dataType:F})},getScript:function(E,F){return o.get(E,null,F,"script")},getJSON:function(E,F,G){return o.get(E,F,G,"json")},post:function(E,G,H,F){if(o.isFunction(G)){H=G;G={}}return o.ajax({type:"POST",url:E,data:G,success:H,dataType:F})},ajaxSetup:function(E){o.extend(o.ajaxSettings,E)},ajaxSettings:{url:location.href,global:true,type:"GET",contentType:"application/x-www-form-urlencoded",processData:true,async:true,xhr:function(){return l.ActiveXObject?new ActiveXObject("Microsoft.XMLHTTP"):new XMLHttpRequest()},accepts:{xml:"application/xml, text/xml",html:"text/html",script:"text/javascript, application/javascript",json:"application/json, text/javascript",text:"text/plain",_default:"*/*"}},lastModified:{},ajax:function(M){M=o.extend(true,M,o.extend(true,{},o.ajaxSettings,M));var W,F=/=\?(&|$)/g,R,V,G=M.type.toUpperCase();if(M.data&&M.processData&&typeof M.data!=="string"){M.data=o.param(M.data)}if(M.dataType=="jsonp"){if(G=="GET"){if(!M.url.match(F)){M.url+=(M.url.match(/\?/)?"&":"?")+(M.jsonp||"callback")+"=?"}}else{if(!M.data||!M.data.match(F)){M.data=(M.data?M.data+"&":"")+(M.jsonp||"callback")+"=?"}}M.dataType="json"}if(M.dataType=="json"&&(M.data&&M.data.match(F)||M.url.match(F))){W="jsonp"+r++;if(M.data){M.data=(M.data+"").replace(F,"="+W+"$1")}M.url=M.url.replace(F,"="+W+"$1");M.dataType="script";l[W]=function(X){V=X;I();L();l[W]=g;try{delete l[W]}catch(Y){}if(H){H.removeChild(T)}}}if(M.dataType=="script"&&M.cache==null){M.cache=false}if(M.cache===false&&G=="GET"){var E=e();var U=M.url.replace(/(\?|&)_=.*?(&|$)/,"$1_="+E+"$2");M.url=U+((U==M.url)?(M.url.match(/\?/)?"&":"?")+"_="+E:"")}if(M.data&&G=="GET"){M.url+=(M.url.match(/\?/)?"&":"?")+M.data;M.data=null}if(M.global&&!o.active++){o.event.trigger("ajaxStart")}var Q=/^(\w+:)?\/\/([^\/?#]+)/.exec(M.url);if(M.dataType=="script"&&G=="GET"&&Q&&(Q[1]&&Q[1]!=location.protocol||Q[2]!=location.host)){var H=document.getElementsByTagName("head")[0];var T=document.createElement("script");T.src=M.url;if(M.scriptCharset){T.charset=M.scriptCharset}if(!W){var O=false;T.onload=T.onreadystatechange=function(){if(!O&&(!this.readyState||this.readyState=="loaded"||this.readyState=="complete")){O=true;I();L();T.onload=T.onreadystatechange=null;H.removeChild(T)}}}H.appendChild(T);return g}var K=false;var J=M.xhr();if(M.username){J.open(G,M.url,M.async,M.username,M.password)}else{J.open(G,M.url,M.async)}try{if(M.data){J.setRequestHeader("Content-Type",M.contentType)}if(M.ifModified){J.setRequestHeader("If-Modified-Since",o.lastModified[M.url]||"Thu, 01 Jan 1970 00:00:00 GMT")}J.setRequestHeader("X-Requested-With","XMLHttpRequest");J.setRequestHeader("Accept",M.dataType&&M.accepts[M.dataType]?M.accepts[M.dataType]+", */*":M.accepts._default)}catch(S){}if(M.beforeSend&&M.beforeSend(J,M)===false){if(M.global&&!--o.active){o.event.trigger("ajaxStop")}J.abort();return false}if(M.global){o.event.trigger("ajaxSend",[J,M])}var N=function(X){if(J.readyState==0){if(P){clearInterval(P);P=null;if(M.global&&!--o.active){o.event.trigger("ajaxStop")}}}else{if(!K&&J&&(J.readyState==4||X=="timeout")){K=true;if(P){clearInterval(P);P=null}R=X=="timeout"?"timeout":!o.httpSuccess(J)?"error":M.ifModified&&o.httpNotModified(J,M.url)?"notmodified":"success";if(R=="success"){try{V=o.httpData(J,M.dataType,M)}catch(Z){R="parsererror"}}if(R=="success"){var Y;try{Y=J.getResponseHeader("Last-Modified")}catch(Z){}if(M.ifModified&&Y){o.lastModified[M.url]=Y}if(!W){I()}}else{o.handleError(M,J,R)}L();if(X){J.abort()}if(M.async){J=null}}}};if(M.async){var P=setInterval(N,13);if(M.timeout>0){setTimeout(function(){if(J&&!K){N("timeout")}},M.timeout)}}try{J.send(M.data)}catch(S){o.handleError(M,J,null,S)}if(!M.async){N()}function I(){if(M.success){M.success(V,R)}if(M.global){o.event.trigger("ajaxSuccess",[J,M])}}function L(){if(M.complete){M.complete(J,R)}if(M.global){o.event.trigger("ajaxComplete",[J,M])}if(M.global&&!--o.active){o.event.trigger("ajaxStop")}}return J},handleError:function(F,H,E,G){if(F.error){F.error(H,E,G)}if(F.global){o.event.trigger("ajaxError",[H,F,G])}},active:0,httpSuccess:function(F){try{return !F.status&&location.protocol=="file:"||(F.status>=200&&F.status<300)||F.status==304||F.status==1223}catch(E){}return false},httpNotModified:function(G,E){try{var H=G.getResponseHeader("Last-Modified");return G.status==304||H==o.lastModified[E]}catch(F){}return false},httpData:function(J,H,G){var F=J.getResponseHeader("content-type"),E=H=="xml"||!H&&F&&F.indexOf("xml")>=0,I=E?J.responseXML:J.responseText;if(E&&I.documentElement.tagName=="parsererror"){throw"parsererror"}if(G&&G.dataFilter){I=G.dataFilter(I,H)}if(typeof I==="string"){if(H=="script"){o.globalEval(I)}if(H=="json"){I=l["eval"]("("+I+")")}}return I},param:function(E){var G=[];function H(I,J){G[G.length]=encodeURIComponent(I)+"="+encodeURIComponent(J)}if(o.isArray(E)||E.jquery){o.each(E,function(){H(this.name,this.value)})}else{for(var F in E){if(o.isArray(E[F])){o.each(E[F],function(){H(F,this)})}else{H(F,o.isFunction(E[F])?E[F]():E[F])}}}return G.join("&").replace(/%20/g,"+")}});var m={},n,d=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]];function t(F,E){var G={};o.each(d.concat.apply([],d.slice(0,E)),function(){G[this]=F});return G}o.fn.extend({show:function(J,L){if(J){return this.animate(t("show",3),J,L)}else{for(var H=0,F=this.length;H<F;H++){var E=o.data(this[H],"olddisplay");this[H].style.display=E||"";if(o.css(this[H],"display")==="none"){var G=this[H].tagName,K;if(m[G]){K=m[G]}else{var I=o("<"+G+" />").appendTo("body");K=I.css("display");if(K==="none"){K="block"}I.remove();m[G]=K}o.data(this[H],"olddisplay",K)}}for(var H=0,F=this.length;H<F;H++){this[H].style.display=o.data(this[H],"olddisplay")||""}return this}},hide:function(H,I){if(H){return this.animate(t("hide",3),H,I)}else{for(var G=0,F=this.length;G<F;G++){var E=o.data(this[G],"olddisplay");if(!E&&E!=="none"){o.data(this[G],"olddisplay",o.css(this[G],"display"))}}for(var G=0,F=this.length;G<F;G++){this[G].style.display="none"}return this}},_toggle:o.fn.toggle,toggle:function(G,F){var E=typeof G==="boolean";return o.isFunction(G)&&o.isFunction(F)?this._toggle.apply(this,arguments):G==null||E?this.each(function(){var H=E?G:o(this).is(":hidden");o(this)[H?"show":"hide"]()}):this.animate(t("toggle",3),G,F)},fadeTo:function(E,G,F){return this.animate({opacity:G},E,F)},animate:function(I,F,H,G){var E=o.speed(F,H,G);return this[E.queue===false?"each":"queue"](function(){var K=o.extend({},E),M,L=this.nodeType==1&&o(this).is(":hidden"),J=this;for(M in I){if(I[M]=="hide"&&L||I[M]=="show"&&!L){return K.complete.call(this)}if((M=="height"||M=="width")&&this.style){K.display=o.css(this,"display");K.overflow=this.style.overflow}}if(K.overflow!=null){this.style.overflow="hidden"}K.curAnim=o.extend({},I);o.each(I,function(O,S){var R=new o.fx(J,K,O);if(/toggle|show|hide/.test(S)){R[S=="toggle"?L?"show":"hide":S](I)}else{var Q=S.toString().match(/^([+-]=)?([\d+-.]+)(.*)$/),T=R.cur(true)||0;if(Q){var N=parseFloat(Q[2]),P=Q[3]||"px";if(P!="px"){J.style[O]=(N||1)+P;T=((N||1)/R.cur(true))*T;J.style[O]=T+P}if(Q[1]){N=((Q[1]=="-="?-1:1)*N)+T}R.custom(T,N,P)}else{R.custom(T,S,"")}}});return true})},stop:function(F,E){var G=o.timers;if(F){this.queue([])}this.each(function(){for(var H=G.length-1;H>=0;H--){if(G[H].elem==this){if(E){G[H](true)}G.splice(H,1)}}});if(!E){this.dequeue()}return this}});o.each({slideDown:t("show",1),slideUp:t("hide",1),slideToggle:t("toggle",1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"}},function(E,F){o.fn[E]=function(G,H){return this.animate(F,G,H)}});o.extend({speed:function(G,H,F){var E=typeof G==="object"?G:{complete:F||!F&&H||o.isFunction(G)&&G,duration:G,easing:F&&H||H&&!o.isFunction(H)&&H};E.duration=o.fx.off?0:typeof E.duration==="number"?E.duration:o.fx.speeds[E.duration]||o.fx.speeds._default;E.old=E.complete;E.complete=function(){if(E.queue!==false){o(this).dequeue()}if(o.isFunction(E.old)){E.old.call(this)}};return E},easing:{linear:function(G,H,E,F){return E+F*G},swing:function(G,H,E,F){return((-Math.cos(G*Math.PI)/2)+0.5)*F+E}},timers:[],fx:function(F,E,G){this.options=E;this.elem=F;this.prop=G;if(!E.orig){E.orig={}}}});o.fx.prototype={update:function(){if(this.options.step){this.options.step.call(this.elem,this.now,this)}(o.fx.step[this.prop]||o.fx.step._default)(this);if((this.prop=="height"||this.prop=="width")&&this.elem.style){this.elem.style.display="block"}},cur:function(F){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==null)){return this.elem[this.prop]}var E=parseFloat(o.css(this.elem,this.prop,F));return E&&E>-10000?E:parseFloat(o.curCSS(this.elem,this.prop))||0},custom:function(I,H,G){this.startTime=e();this.start=I;this.end=H;this.unit=G||this.unit||"px";this.now=this.start;this.pos=this.state=0;var E=this;function F(J){return E.step(J)}F.elem=this.elem;if(F()&&o.timers.push(F)&&!n){n=setInterval(function(){var K=o.timers;for(var J=0;J<K.length;J++){if(!K[J]()){K.splice(J--,1)}}if(!K.length){clearInterval(n);n=g}},13)}},show:function(){this.options.orig[this.prop]=o.attr(this.elem.style,this.prop);this.options.show=true;this.custom(this.prop=="width"||this.prop=="height"?1:0,this.cur());o(this.elem).show()},hide:function(){this.options.orig[this.prop]=o.attr(this.elem.style,this.prop);this.options.hide=true;this.custom(this.cur(),0)},step:function(H){var G=e();if(H||G>=this.options.duration+this.startTime){this.now=this.end;this.pos=this.state=1;this.update();this.options.curAnim[this.prop]=true;var E=true;for(var F in this.options.curAnim){if(this.options.curAnim[F]!==true){E=false}}if(E){if(this.options.display!=null){this.elem.style.overflow=this.options.overflow;this.elem.style.display=this.options.display;if(o.css(this.elem,"display")=="none"){this.elem.style.display="block"}}if(this.options.hide){o(this.elem).hide()}if(this.options.hide||this.options.show){for(var I in this.options.curAnim){o.attr(this.elem.style,I,this.options.orig[I])}}this.options.complete.call(this.elem)}return false}else{var J=G-this.startTime;this.state=J/this.options.duration;this.pos=o.easing[this.options.easing||(o.easing.swing?"swing":"linear")](this.state,J,0,1,this.options.duration);this.now=this.start+((this.end-this.start)*this.pos);this.update()}return true}};o.extend(o.fx,{speeds:{slow:600,fast:200,_default:400},step:{opacity:function(E){o.attr(E.elem.style,"opacity",E.now)},_default:function(E){if(E.elem.style&&E.elem.style[E.prop]!=null){E.elem.style[E.prop]=E.now+E.unit}else{E.elem[E.prop]=E.now}}}});if(document.documentElement.getBoundingClientRect){o.fn.offset=function(){if(!this[0]){return{top:0,left:0}}if(this[0]===this[0].ownerDocument.body){return o.offset.bodyOffset(this[0])}var G=this[0].getBoundingClientRect(),J=this[0].ownerDocument,F=J.body,E=J.documentElement,L=E.clientTop||F.clientTop||0,K=E.clientLeft||F.clientLeft||0,I=G.top+(self.pageYOffset||o.boxModel&&E.scrollTop||F.scrollTop)-L,H=G.left+(self.pageXOffset||o.boxModel&&E.scrollLeft||F.scrollLeft)-K;return{top:I,left:H}}}else{o.fn.offset=function(){if(!this[0]){return{top:0,left:0}}if(this[0]===this[0].ownerDocument.body){return o.offset.bodyOffset(this[0])}o.offset.initialized||o.offset.initialize();var J=this[0],G=J.offsetParent,F=J,O=J.ownerDocument,M,H=O.documentElement,K=O.body,L=O.defaultView,E=L.getComputedStyle(J,null),N=J.offsetTop,I=J.offsetLeft;while((J=J.parentNode)&&J!==K&&J!==H){M=L.getComputedStyle(J,null);N-=J.scrollTop,I-=J.scrollLeft;if(J===G){N+=J.offsetTop,I+=J.offsetLeft;if(o.offset.doesNotAddBorder&&!(o.offset.doesAddBorderForTableAndCells&&/^t(able|d|h)$/i.test(J.tagName))){N+=parseInt(M.borderTopWidth,10)||0,I+=parseInt(M.borderLeftWidth,10)||0}F=G,G=J.offsetParent}if(o.offset.subtractsBorderForOverflowNotVisible&&M.overflow!=="visible"){N+=parseInt(M.borderTopWidth,10)||0,I+=parseInt(M.borderLeftWidth,10)||0}E=M}if(E.position==="relative"||E.position==="static"){N+=K.offsetTop,I+=K.offsetLeft}if(E.position==="fixed"){N+=Math.max(H.scrollTop,K.scrollTop),I+=Math.max(H.scrollLeft,K.scrollLeft)}return{top:N,left:I}}}o.offset={initialize:function(){if(this.initialized){return}var L=document.body,F=document.createElement("div"),H,G,N,I,M,E,J=L.style.marginTop,K='<div style="position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;"><div></div></div><table style="position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;" cellpadding="0" cellspacing="0"><tr><td></td></tr></table>';M={position:"absolute",top:0,left:0,margin:0,border:0,width:"1px",height:"1px",visibility:"hidden"};for(E in M){F.style[E]=M[E]}F.innerHTML=K;L.insertBefore(F,L.firstChild);H=F.firstChild,G=H.firstChild,I=H.nextSibling.firstChild.firstChild;this.doesNotAddBorder=(G.offsetTop!==5);this.doesAddBorderForTableAndCells=(I.offsetTop===5);H.style.overflow="hidden",H.style.position="relative";this.subtractsBorderForOverflowNotVisible=(G.offsetTop===-5);L.style.marginTop="1px";this.doesNotIncludeMarginInBodyOffset=(L.offsetTop===0);L.style.marginTop=J;L.removeChild(F);this.initialized=true},bodyOffset:function(E){o.offset.initialized||o.offset.initialize();var G=E.offsetTop,F=E.offsetLeft;if(o.offset.doesNotIncludeMarginInBodyOffset){G+=parseInt(o.curCSS(E,"marginTop",true),10)||0,F+=parseInt(o.curCSS(E,"marginLeft",true),10)||0}return{top:G,left:F}}};o.fn.extend({position:function(){var I=0,H=0,F;if(this[0]){var G=this.offsetParent(),J=this.offset(),E=/^body|html$/i.test(G[0].tagName)?{top:0,left:0}:G.offset();J.top-=j(this,"marginTop");J.left-=j(this,"marginLeft");E.top+=j(G,"borderTopWidth");E.left+=j(G,"borderLeftWidth");F={top:J.top-E.top,left:J.left-E.left}}return F},offsetParent:function(){var E=this[0].offsetParent||document.body;while(E&&(!/^body|html$/i.test(E.tagName)&&o.css(E,"position")=="static")){E=E.offsetParent}return o(E)}});o.each(["Left","Top"],function(F,E){var G="scroll"+E;o.fn[G]=function(H){if(!this[0]){return null}return H!==g?this.each(function(){this==l||this==document?l.scrollTo(!F?H:o(l).scrollLeft(),F?H:o(l).scrollTop()):this[G]=H}):this[0]==l||this[0]==document?self[F?"pageYOffset":"pageXOffset"]||o.boxModel&&document.documentElement[G]||document.body[G]:this[0][G]}});o.each(["Height","Width"],function(I,G){var E=I?"Left":"Top",H=I?"Right":"Bottom",F=G.toLowerCase();o.fn["inner"+G]=function(){return this[0]?o.css(this[0],F,false,"padding"):null};o.fn["outer"+G]=function(K){return this[0]?o.css(this[0],F,false,K?"margin":"border"):null};var J=G.toLowerCase();o.fn[J]=function(K){return this[0]==l?document.compatMode=="CSS1Compat"&&document.documentElement["client"+G]||document.body["client"+G]:this[0]==document?Math.max(document.documentElement["client"+G],document.body["scroll"+G],document.documentElement["scroll"+G],document.body["offset"+G],document.documentElement["offset"+G]):K===g?(this.length?o.css(this[0],J):null):this.css(J,typeof K==="string"?K:K+"px")}})})(); \ No newline at end of file
diff --git a/site/app/webroot/js/amo2009/slimbox2.js b/site/app/webroot/js/amo2009/slimbox2.js
new file mode 100755
index 0000000..ccb07c4
--- /dev/null
+++ b/site/app/webroot/js/amo2009/slimbox2.js
@@ -0,0 +1,13 @@
+/*
+ Slimbox v2.02 - The ultimate lightweight Lightbox clone for jQuery
+ (c) 2007-2009 Christophe Beyls <http://www.digitalia.be>
+ MIT-style license.
+*/
+(function(w){var E=w(window),u,g,F=-1,o,x,D,v,y,L,s,n=!window.XMLHttpRequest,e=window.opera&&(document.compatMode=="CSS1Compat")&&(w.browser.version>=9.3),m=document.documentElement,l={},t=new Image(),J=new Image(),H,a,h,q,I,d,G,c,A,K;w(function(){w("body").append(w([H=w('<div id="lbOverlay" />')[0],a=w('<div id="lbCenter" />')[0],G=w('<div id="lbBottomContainer" />')[0]]).css("display","none"));h=w('<div id="lbImage" />').appendTo(a).append(q=w('<div style="position: relative;" />').append([I=w('<a id="lbPrevLink" href="#" />').click(B)[0],d=w('<a id="lbNextLink" href="#" />').click(f)[0]])[0])[0];c=w('<div id="lbBottom" />').appendTo(G).append([w('<a id="lbCloseLink" href="#" />').add(H).click(C)[0],A=w('<div id="lbCaption" />')[0],K=w('<div id="lbNumber" />')[0],w('<div style="clear: both;" />')[0]])[0]});w.slimbox=function(O,N,M){u=w.extend({loop:false,overlayOpacity:0.8,overlayFadeDuration:400,resizeDuration:400,resizeEasing:"swing",initialWidth:250,initialHeight:250,imageFadeDuration:400,captionAnimationDuration:400,counterText:"Image {x} of {y}",closeKeys:[27,88,67],previousKeys:[37,80],nextKeys:[39,78]},M);if(typeof O=="string"){O=[[O,N]];N=0}y=E.scrollTop()+((e?m.clientHeight:E.height())/2);L=u.initialWidth;s=u.initialHeight;w(a).css({top:Math.max(0,y-(s/2)),width:L,height:s,marginLeft:-L/2}).show();v=n||(H.currentStyle&&(H.currentStyle.position!="fixed"));if(v){H.style.position="absolute"}w(H).css("opacity",u.overlayOpacity).fadeIn(u.overlayFadeDuration);z();k(1);g=O;u.loop=u.loop&&(g.length>1);return b(N)};w.fn.slimbox=function(M,P,O){P=P||function(Q){return[Q.href,Q.title]};O=O||function(){return true};var N=this;return N.unbind("click").click(function(){var S=this,U=0,T,Q=0,R;T=w.grep(N,function(W,V){return O.call(S,W,V)});for(R=T.length;Q<R;++Q){if(T[Q]==S){U=Q}T[Q]=P(T[Q],Q)}return w.slimbox(T,U,M)})};function z(){var N=E.scrollLeft(),M=e?m.clientWidth:E.width();w([a,G]).css("left",N+(M/2));if(v){w(H).css({left:N,top:E.scrollTop(),width:M,height:E.height()})}}function k(M){w("object").add(n?"select":"embed").each(function(O,P){if(M){w.data(P,"slimbox",P.style.visibility)}P.style.visibility=M?"hidden":w.data(P,"slimbox")});var N=M?"bind":"unbind";E[N]("scroll resize",z);w(document)[N]("keydown",p)}function p(O){var N=O.keyCode,M=w.inArray;return(M(N,u.closeKeys)>=0)?C():(M(N,u.nextKeys)>=0)?f():(M(N,u.previousKeys)>=0)?B():false}function B(){return b(x)}function f(){return b(D)}function b(M){if(M>=0){F=M;o=g[F][0];x=(F||(u.loop?g.length:0))-1;D=((F+1)%g.length)||(u.loop?0:-1);r();a.className="lbLoading";l=new Image();l.onload=j;l.src=o}return false}function j(){a.className="";w(h).css({backgroundImage:"url("+o+")",visibility:"hidden",display:""});w(q).width(l.width);w([q,I,d]).height(l.height);w(A).html(g[F][1]||"");w(K).html((((g.length>1)&&u.counterText)||"").replace(/{x}/,F+1).replace(/{y}/,g.length));if(x>=0){t.src=g[x][0]}if(D>=0){J.src=g[D][0]}L=h.offsetWidth;s=h.offsetHeight;var M=Math.max(0,y-(s/2));if(a.offsetHeight!=s){w(a).animate({height:s,top:M},u.resizeDuration,u.resizeEasing)}if(a.offsetWidth!=L){w(a).animate({width:L,marginLeft:-L/2},u.resizeDuration,u.resizeEasing)}w(a).queue(function(){w(G).css({width:L,top:M+s,marginLeft:-L/2,visibility:"hidden",display:""});w(h).css({display:"none",visibility:"",opacity:""}).fadeIn(u.imageFadeDuration,i)})}function i(){if(x>=0){w(I).show()}if(D>=0){w(d).show()}w(c).css("marginTop",-c.offsetHeight).animate({marginTop:0},u.captionAnimationDuration);G.style.visibility=""}function r(){l.onload=null;l.src=t.src=J.src=o;w([a,h,c]).stop(true);w([I,d,h,G]).hide()}function C(){if(F>=0){r();F=x=D=-1;w(a).hide();w(H).stop().fadeOut(u.overlayFadeDuration,k)}return false}})(jQuery);
+
+// AUTOLOAD CODE BLOCK (MAY BE CHANGED OR REMOVED)
+jQuery(function($) {
+ $("a[rel^='lightbox']").slimbox({/* Put custom options here */}, null, function(el) {
+ return (this == el) || ((this.rel.length > 8) && (this.rel == el.rel));
+ });
+}); \ No newline at end of file
diff --git a/site/app/webroot/js/compatibility.js b/site/app/webroot/js/compatibility.js
new file mode 100644
index 0000000..d338dd5
--- /dev/null
+++ b/site/app/webroot/js/compatibility.js
@@ -0,0 +1,55 @@
+var compatibility = {
+ viewReport: function() {
+ $('#compat-intro').fadeOut('medium', function() {
+ $('#compat-home-nav').fadeIn();
+ $('#report-intro').fadeIn('medium');
+ });
+ },
+
+ viewReportDetails: function() {
+ $('#report-intro').fadeOut('medium', function() {
+ $('.compat-box').animate({ width: '950px'}, 'medium', null, function() {
+ $('#report-details').fadeIn('medium', function() {
+ $('#report-details .loading').show();
+ $('#report-details-data').load(detailsURL, null, function() {
+ $('#report-details .loading').hide();
+ $('#report-details-data').show();
+ });
+ });
+ });
+ });
+
+ },
+
+ viewHome: function() {
+ $('#report-intro,#report-details,#report-details-data,.loading,#compat-home-nav,#developers-intro,#developers-details,#users-intro').hide();
+ $('.compat-box').animate({ width: '650px'}, 'fast');
+ $('#compat-intro').fadeIn('medium');
+ },
+
+ viewDeveloperInfo: function() {
+ $('#compat-intro').fadeOut('medium', function() {
+ $('#compat-home-nav').fadeIn();
+ $('#developers-intro').fadeIn('medium');
+ });
+ },
+
+ viewDeveloperDetails: function() {
+ $('#developers-intro').fadeOut('medium', function() {
+ $('#developers-details').fadeIn('medium', function() {
+ $('#developers-details .loading').show();
+ $('#developers-details-data').load(developerStatusURL, null, function() {
+ $('#developers-details .loading').hide();
+ $('#developers-details-data').show();
+ });
+ });
+ });
+ },
+
+ viewEndUserInfo: function() {
+ $('#compat-intro').fadeOut('medium', function() {
+ $('#compat-home-nav').fadeIn();
+ $('#users-intro').fadeIn('medium');
+ });
+ }
+}; \ No newline at end of file
diff --git a/site/app/webroot/js/developers.js b/site/app/webroot/js/developers.js
new file mode 100644
index 0000000..4bde261
--- /dev/null
+++ b/site/app/webroot/js/developers.js
@@ -0,0 +1,761 @@
+var author_roles = {
+ NONE: 0,
+ VIEWER: 1,
+ DEV: 4,
+ OWNER: 5,
+ ADMIN: 6,
+ ADMINOWNER: 7
+};
+
+var addon_statuses = {
+ NULL: 0,
+ SANDBOX: 1,
+ PENDING: 2,
+ NOMINATED: 3,
+ PUBLIC: 4,
+ DISABLED: 5
+};
+
+var upload = {
+ 'type': null,
+ 'response': null,
+ 'pastFirstLoad': false,
+
+ showAgreement: function() {
+ $('#step-intro').slideUp();
+ $('#step-agreement').slideDown();
+ },
+
+ hideAgreement: function() {
+ $('#step-agreement').slideUp();
+ $('#step-intro').slideDown();
+ },
+
+ acceptAgreement: function() {
+ if (license_picker.acceptable()) {
+ $('#step-agreement').slideUp();
+ $('#file-upload').slideDown();
+ } else {
+ license_picker.complain();
+ }
+ },
+
+ platformAll: function() {
+ $('#file-upload input[type=checkbox]').attr('disabled', 'disabled');
+ $('#file-upload .specific-platforms').addClass('disabled');
+ },
+
+ platformSpecific: function() {
+ $('#file-upload input[type=checkbox]').attr('disabled', '');
+ $('#file-upload .specific-platforms').removeClass('disabled');
+ },
+
+ uploadFile: function() {
+ if (!license_picker.acceptable()) {
+ $('#file-upload').slideUp();
+ upload.showAgreement();
+ upload.acceptAgreement();
+ return false;
+ }
+ else if ($('#upload-field').val() != '') {
+ $('#file-upload input[type=submit]').attr('disabled', 'disabled');
+ $('#upload-loading').show();
+ $('#upload-error').slideUp('slow');
+ $.each(['#license-name', '#license-translationbox'], function(i, s){
+ $(s).hide().appendTo('#upload-form');
+ });
+ upload.pastFirstLoad = true;
+ return true;
+ }
+ else {
+ alert(devcp_js_upload_alert);
+ return false;
+ }
+ }
+};
+
+function iframeLoaded() {
+ if (!upload.pastFirstLoad)
+ return;
+
+ $('#upload-loading').hide();
+
+ upload.response = JSON.parse(document.getElementById('upload-frame').contentWindow.document.getElementById('json').innerHTML);
+
+ if (upload.response.error == '1') {
+ $('#upload-error-text').html(urldecode(upload.response.error_message));
+ $('#upload-error').slideDown('slow');
+ $('#file-upload input[type=submit]').attr('disabled', '');
+ }
+ else {
+ $('#submission-area').slideUp('slow');
+ $('#upload-success').slideDown('slow');
+
+ if (upload.response.uploadtype == 'new') {
+ $('#status-link').attr('href', $('#status-link').attr('href') + upload.response.addon_id);
+ $('#complete-link').attr('href', $('#complete-link').attr('href') + upload.response.addon_id);
+ }
+ else if (upload.response.uploadtype == 'update') {
+ if (upload.response.status == addon_statuses.PUBLIC) {
+ $('#pending-message').hide();
+ $('#new-file-status').text(addons_status_public);
+ }
+ else if (upload.response.status == addon_statuses.SANDBOX) {
+ $('#new-file-status').text(addons_status_sandbox);
+ }
+ else if (upload.response.status == addon_statuses.PENDING) {
+ $('#new-file-status').text(addons_status_pending);
+ }
+ $('#new-file-status').addClass('status-' + upload.response.status);
+ $('#new-version-number').text(upload.response.version);
+ $('#queue-count').text(upload.response.queuecount);
+ $('#version-link').attr('href', $('#version-link').attr('href') + upload.response.version_id);
+ $('#complete-link').attr('href', $('#complete-link').attr('href') + upload.response.version_id);
+ }
+ else if (upload.response.uploadtype == 'file') {
+ if (upload.response.status == addon_statuses.PUBLIC) {
+ $('#pending-message').hide();
+ $('#new-file-status').text(addons_status_public);
+ }
+ else if (upload.response.status == addon_statuses.PENDING) {
+ $('#new-file-status').text(addons_status_pending);
+ }
+ $('#new-file-status').addClass('status-' + upload.response.status);
+ $('#queue-count').text(upload.response.queuecount);
+ }
+ }
+}
+
+function urldecode(str) {
+ str = str.replace(/\+/g, ' ');
+ str = unescape(str);
+ return str;
+}
+
+var addon_edit_authors = {
+ showAddForm: function() {
+ $('#add-author').show();
+ },
+
+ deleteAuthor: function(a) {
+ var container = $(a).parent();
+ container.addClass('open');
+ container.find('.inline-delete-box').slideDown();
+ $(a).blur();
+ },
+
+ confirmDelete: function(a) {
+ this.cancelDelete(a);
+
+ var container = $(a).parent().parent().parent();
+ var tr = container.parent().parent();
+ tr.fadeOut('slow', function() {
+ tr.remove();
+ addon_edit_authors.checkRowColors();
+ addon_edit_authors.checkArrows();
+ addon_edit_authors.checkAuthors();
+ });
+ tr.parent().parent().parent().find('.save-changes').slideDown();
+ },
+
+ cancelDelete: function(a) {
+ var container = $(a).parent().parent().parent();
+ container.find('.inline-delete-box').slideUp('normal', function() {
+ container.removeClass('open');
+ });
+ },
+
+ addAuthor: function(user_id, author, role, visible, markChanges) {
+ var row = '<tr><td>';
+ row += '<a class="down-arrow" href="#" onclick="addon_edit_authors.moveDownRow(this); return false;"><img src="' + imageURL + '/developers/arrow_down.png" alt="' + devcp_js_img_move_down + '" title="' + devcp_js_img_move_down + '" /></a>';
+ row += '<a class="up-arrow" href="#" onclick="addon_edit_authors.moveUpRow(this); return false;"><img src="' + imageURL + '/developers/arrow_up.png" alt="' + devcp_js_img_move_up + '" title="' + devcp_js_img_move_up + '" /></a>';
+ row += '</td><td><a href="' + profileURL + '/' + user_id + '">' + author + '</a></td><td>';
+ row += '<select name="data[addons_users][' + user_id + '][role]">';
+ row += '<option value="' + author_roles.OWNER + '" ' + (role == author_roles.OWNER ? ' selected="selected"' : '') + '>' + devcp_js_option_owner + '</option>';
+ row += '<option value="' + author_roles.DEV + '" ' + (role == author_roles.DEV ? ' selected="selected"' : '') + '>' + devcp_js_option_developer + '</option>';
+ row += '<option value="' + author_roles.VIEWER + '" ' + (role == author_roles.VIEWER ? ' selected="selected"' : '') + '>' + devcp_js_option_viewer + '</option>';
+ row += '</td><td>';
+ row += '<input type="checkbox" name="data[addons_users][' + user_id + '][listed]" value="1" ' + (visible == true ? ' checked="checked"' : '') + ' title="' + devcp_js_input_list_author + '"/>';
+ row += '</td><td style="width: 25px;">';
+ row += '<div class="inline-delete-button uses-image">';
+ row += '<a href="#" onclick="addon_edit_authors.deleteAuthor(this); return false;"><img src="' + imageURL + '/developers/delete.png" alt="' + devcp_js_remove_author + '" title="' + devcp_js_remove_author + '" /></a>';
+ row += '<div class="inline-delete-box">';
+ row += '<p>' + devcp_js_sure_remove + '</p><br/>';
+ row += '<p><a href="#" onclick="addon_edit_authors.confirmDelete(this); return false;" class="remove-button rounded">' + devcp_js_remove_author + '</a>&nbsp;&nbsp;';
+ row += '<a href="#" onclick="addon_edit_authors.cancelDelete(this); return false;" class="button rounded">' + devcp_js_a_cancel + '</a></p>';
+ row += '</div></div>';
+ row += '</td></tr>';
+
+ var newrow = $('#author-table tbody').append(row);
+ this.checkRowColors();
+ this.checkArrows();
+ // check author roles
+ this.checkAuthors();
+ newrow.find('select[name*=role]').change(addon_edit_authors.checkAuthors);
+
+ if (markChanges) $('.save-changes').slideDown();
+ },
+
+ moveUpRow: function(a) {
+ var row = $(a).parent().parent();
+ var prev = row.prev();
+ if (prev.html() != null) {
+ var selectedIndex = a.parentNode.parentNode.getElementsByTagName('select')[0].selectedIndex;
+ prev.before(row.clone(true));
+ prev.prev().find('select').attr('selectedIndex', selectedIndex);
+ row.remove();
+
+ this.checkArrows();
+ this.checkRowColors();
+ }
+ },
+
+ moveDownRow: function(a) {
+ var row = $(a).parent().parent();
+ var next = row.next();
+ if (next.html() != null) {
+ var selectedIndex = a.parentNode.parentNode.getElementsByTagName('select')[0].selectedIndex;
+ next.after(row.clone(true));
+ next.next().find('select').attr('selectedIndex', selectedIndex);
+ row.remove();
+
+ this.checkArrows();
+ this.checkRowColors();
+ }
+ },
+
+ checkRowColors: function() {
+ $('#author-table tbody tr:visible:even').addClass('alt');
+ $('#author-table tbody tr:visible:odd').removeClass('alt');
+ },
+
+ checkArrows: function() {
+ $('#author-table tbody .down-arrow').css('visibility', 'visible');
+ $('#author-table tbody .up-arrow').show();
+ $('#author-table tbody tr:first .up-arrow').hide();
+ $('#author-table tbody tr:last .down-arrow').css('visibility', 'hidden');
+ },
+
+ checkAddForm: function() {
+ var email = $('#add-email').val();
+
+ if (email != '') {
+ $('#add-error').slideUp();
+ $('#add-loading').show();
+ $.getJSON(jsonURL + '/verifyauthor/?email=' + email, null, function(data) {
+ $('#add-loading').hide();
+ if (data.error == '0') {
+ var listed = $('#add-listed').attr('checked');
+ var role = $('#add-role-developer').attr('checked') ? author_roles.DEV : ($('#add-role-viewer').attr('checked') ? author_roles.VIEWER : author_roles.OWNER);
+ addon_edit_authors.addAuthor(data.id, data.displayname, role, listed, true);
+ addon_edit_authors.resetAddForm();
+ }
+ else {
+ $('#add-error').text(data.error_message);
+ $('#add-error').slideDown();
+ }
+ });
+
+ return true;
+ }
+ else {
+ $('#add-error').html(devcp_js_add_email);
+ $('#add-error').slideDown();
+ return false;
+ }
+ },
+
+ resetAddForm: function() {
+ $('#add-author').hide();
+ $('#add-email').val('');
+ $('#add-role-owner').attr('checked', 'checked');
+ $('#add-listed').attr('checked', 'checked');
+ $('#add-error').slideUp();
+ $('#add-loading').hide();
+ },
+
+ checkAuthors: function() {
+ var empty_authors = (!$('#author-table select[name*=role]>option:selected[value='+author_roles['OWNER']+']').size());
+ // TODO: with jQuery 1.3+, just use toggle(empty_authors)
+ if (empty_authors) {
+ $('#submit').hide();
+ $('#empty-authors').fadeIn();
+ } else {
+ $('#empty-authors').fadeOut('normal', function(){$('#submit').show();});
+ }
+ },
+
+ save: function() {
+ $('#addon-edit-authors-form').submit();
+ }
+};
+
+var addon_edit_descriptions = {
+ save: function() {
+ if ($('.translation-error').size() > 1 || $('.translation-maxlength.over').size() > 0) {
+ $('#edit-error').show();
+ }
+ else {
+ $('#addon-edit-descriptions-form').submit();
+ }
+ }
+};
+
+var addon_edit_properties = {
+ deleteIcon: function() {
+ $('#delete-icon').val('1');
+ $('#addon-icon').addClass('deleted');
+ $('#delete-icon-area').hide();
+ $('#undelete-icon-area').show();
+ },
+
+ undeleteIcon: function() {
+ $('#delete-icon').val('0');
+ $('#addon-icon').removeClass('deleted');
+ $('#undelete-icon-area').hide();
+ $('#delete-icon-area').show();
+ },
+
+ save: function() {
+ $('#addon-edit-properties-form').submit();
+ }
+};
+
+var addon_edit_categories = {
+ updateDescription: function(app_id, description) {
+ $('#edit-categories-descriptions' + app_id).html(description);
+ },
+
+ toggleDropdowns: function(checkbox, app_id) {
+ if (checkbox.checked) {
+ $('.app-' + app_id + ' select').attr('disabled', 'disabled');
+ }
+ else {
+ $('.app-' + app_id + ' select').attr('disabled', '');
+ }
+ },
+
+ save: function() {
+ $('#addon-edit-categories-form').submit();
+ }
+};
+
+var versions = {
+ deleteVersion: function(a) {
+ var container = $(a).parent();
+ container.addClass('open');
+ container.find('.inline-delete-box').slideDown();
+ $(a).blur();
+ },
+
+ cancelDelete: function(a) {
+ var container = $(a).parent().parent().parent();
+ container.find('.inline-delete-box').slideUp('normal', function() {
+ container.removeClass('open');
+ });
+ }
+};
+
+var versions_delete = {
+ confirm: function() {
+ $('#versions-delete-form').submit();
+ }
+};
+
+var versions_edit = {
+ deleteVersion: function(a) {
+ var container = $(a).parent();
+ container.addClass('open');
+ container.find('.inline-delete-box').slideDown();
+ $(a).blur();
+ },
+
+ confirmDelete: function(a) {
+ this.cancelDelete(a);
+
+ var container = $(a).parent().parent().parent();
+ var tr = container.parent().parent();
+ tr.fadeOut('slow', function() {
+ tr.parent().find('tr:visible:even').addClass('alt');
+ tr.parent().find('tr:visible:odd').removeClass('alt');
+ });
+ tr.find('input.delete').val('1');
+ tr.parent().parent().parent().find('.save-changes').slideDown();
+ },
+
+ cancelDelete: function(a) {
+ var container = $(a).parent().parent().parent();
+ container.find('.inline-delete-box').slideUp('normal', function() {
+ container.removeClass('open');
+ });
+ },
+
+ showAppPicker: function() {
+ $.each(application_names, function(app_id, app_name) {
+ var disabled = ($('#edit-versions-targetapps-table tr.' + app_id + ':visible').size() > 0) ? 'disabled' : '';
+ $('#new-app-picker select option[value="' + app_id + '"]').attr('disabled', disabled);
+ });
+
+ $('#new-app-picker').show();
+ $('#new-app-picker select').focus();
+ },
+
+ addApplication: function(select) {
+ var application_id = $(select).val();
+ if (application_id == '')
+ return;
+
+ var newRow = '<tr class="' + application_id + '">';
+ newRow += '<td><img src="' + imageBase + '/' + application_names[application_id].toLowerCase() + '.png" alt="' + application_names[application_id] + '"/></td>';
+ newRow += '<td class="appname">' + application_names[application_id];
+ newRow += '<input type="hidden" name="data[Application][' + application_id + '][new]" value="1"/></td>';
+ newRow += '<td>' + $('#app' + application_id + '-dropdowns').html() + '</td>';
+ newRow += '<td style="width: 25px;"><div class="inline-delete-button">';
+ newRow += '<a href="#" onclick="versions_edit.confirmDelete(this); return false;"><img src="' + imageBase + '/delete.png" alt="' + devcp_js_img_remove_compat + '" title="' + devcp_js_img_remove_compat + '" /></a>';
+ newRow += '</div></td>';
+ newRow += '</tr>';
+
+ $('#edit-versions-targetapps-table').append(newRow);
+ $('#new-app-picker').hide();
+ $('#new-app-picker select option:first').attr('selected', 'selected');
+
+ $('#edit-versions-targetapps-table tr:visible:even').addClass('alt');
+ $('#edit-versions-targetapps-table tr:visible:odd').removeClass('alt');
+ },
+
+ save: function() {
+ if (!license_picker.acceptable(true)) {
+ license_picker.complain();
+ } else {
+ $('#versions-edit-form').submit();
+ }
+ }
+
+};
+
+var license_picker = {
+ // Called from document.ready.
+ // license_trans is a dict {"license picker vals": "transbox HTML"}
+ init: function(license_trans) {
+ // Turn the strings into DOM elements.
+ for (var k in license_trans) {
+ license_trans[k] = $(license_trans[k]);
+ }
+ $("#license-name").change(function() {
+ var val = $(this).val();
+ $("#license-translationbox").contents().remove();
+ if(val in license_trans) {
+ license_trans[val].appendTo($('#license-translationbox'));
+ }
+ });
+ $('#license-name').change();
+ },
+
+ acceptable: function(accept_null) {
+ var val = $("#license-name").val();
+ var trans = $.grep($("#license-translationbox textarea"),
+ function(e) {
+ return $(e).val() != "";
+ });
+ var is_null = val == 'null';
+ var empty_custom = val == 'other' && trans.length < 1;
+ return !(!accept_null && is_null || empty_custom);
+ },
+
+ complain: function(accept_null) {
+ if (!license_picker.acceptable(accept_null)) {
+ if ($('#license-name').val() == 'other') {
+ // The text box must be empty.
+ alert(devcp_js_license_text);
+ } else {
+ alert(devcp_js_license_select);
+ }
+ }
+ }
+};
+
+var previews = {
+ showReplaceBox: function(a) {
+ var box = $(a).parent().parent().parent().parent().parent();
+ box.find('.replace-preview').slideDown().focus();
+ },
+
+ showAddBox: function(button) {
+ $('#add-preview-box').show();
+ $(button).parent().hide();
+ },
+
+ cancelReplace: function(a) {
+ var replaceBox = $(a).parent().parent();
+ replaceBox.slideUp();
+ replaceBox.find('input').val('');
+ },
+
+ addUploadBox: function() {
+ $('#new-preview-container').append('<label class="new-preview">' + $('.new-preview:first').html() + '</label>');
+ },
+
+ deletePreview: function(a) {
+ var box = $(a).parent().parent().parent().parent().parent().parent().parent().parent().parent();
+ box.addClass('errors');
+ box.find('input.delete').val('true');
+ },
+
+ cancelDelete: function(a) {
+ var box = $(a).parent().parent();
+ box.removeClass('errors');
+ box.find('input.delete').val('false');
+ },
+
+ save: function() {
+ $('#previews-form').submit();
+ }
+};
+
+var addon_status = {
+ confirm: function() {
+ $('#status-form').submit();
+ }
+}
+
+/************************************************
+* addontype constants *
+************************************************/
+var ADDON_EXTENSION = '1';
+var ADDON_THEME = '2';
+var ADDON_DICT = '3';
+var ADDON_SEARCH = '4';
+var ADDON_LPAPP = '5';
+var ADDON_LPADDON = '6';
+
+/************************************************
+* developers/add_step1.thtml *
+************************************************/
+//Show appropriate form items based on addontype
+function selectType(select) {
+ var addonType = select.options[select.selectedIndex].value;
+
+ if (addonType == ADDON_SEARCH) {
+ document.getElementById('file2').style.display = 'none';
+ document.getElementById('file3').style.display = 'none';
+ document.getElementById('addrow').style.display = 'none';
+ document.getElementById('platform1').style.display = 'none';
+ document.getElementById('platform2').style.display = 'none';
+ }
+ else {
+ document.getElementById('platform1').style.display = '';
+ document.getElementById('platform2').style.display = '';
+ }
+}
+
+//Show the next available file upload box
+function addFile() {
+ if(document.getElementById('file2').style.display == 'none') {
+ //show file 2
+ document.getElementById('file2').style.display = '';
+ }
+ else {
+ //show file 3
+ document.getElementById('file3').style.display = '';
+ document.getElementById('addrow').style.display = 'none';
+ }
+}
+
+//Show or hide additional version boxes
+function selectPlatform(select) {
+ //If the first file is version ALL, hide other boxes
+ if (select.selectedIndex == 0) {
+ document.getElementById('file2').style.display = 'none';
+ document.getElementById('file3').style.display = 'none';
+ document.getElementById('addrow').style.display = 'none';
+ }
+ //If the first file is not ALL, allow other boxes
+ else {
+ if (document.getElementById('file3').style.display == 'none') {
+ document.getElementById('addrow').style.display = '';
+ }
+ }
+}
+
+/************************************************
+* developers/add_step2.thtml *
+* developers/edit *
+************************************************/
+//Show addontype change form
+function showAddontypes() {
+ document.getElementById('changeAddontype').style.display = '';
+}
+
+//Change addontype
+function changeAddontype(select, current) {
+ var addontype_id = select.options[select.selectedIndex].value;
+
+ var tags = document.getElementById('TagTag');
+ var msg = document.getElementById('tagNext');
+ var desc = document.getElementById('tagDescription');
+
+ if (addontype_id != current) {
+ tags.style.display = 'none';
+ desc.style.display = 'none';
+ msg.style.display = '';
+ }
+ else {
+ tags.style.display = '';
+ desc.style.display = '';
+ msg.style.display = 'none';
+ }
+}
+
+//Make sure summary is the correct length
+function checkSummary(summary, message) {
+ if (summary.value.length > 250) {
+ alert(message.replace('%s', summary.value.length));
+ }
+}
+
+//Shows the add author textbox/button
+function showAuthorForm() {
+ document.getElementById('addAuthorRow').style.display = 'none';
+ document.getElementById('newAuthorRow').style.display = '';
+ document.getElementById('newAuthor').focus();
+}
+
+//Retrieves a user's name by email and creates a hidden input with id
+function addAuthor(url) {
+ var newAuthorElt = document.getElementById('newAuthor');
+ var addButtonElt = document.getElementById('addButton');
+ var authorsElt = document.getElementById('authors');
+
+ //Remove any "not found" errors
+ var divs = authorsElt.getElementsByTagName('div');
+ for(var i = 0; i < divs.length; i++) {
+ if(divs[i].className.indexOf('notfound') != -1) {
+ $(divs[i]).fadeOut();
+ }
+ }
+
+ //Only proceed if the text field is not empty, else highlight the field
+ if (newAuthorElt.value != '') {
+ newAuthorElt.disabled = true;
+ addButtonElt.disabled = true;
+
+ //Callback function for success
+ var updateAuthors = function(t, status) {
+ var div = document.createElement('div');
+ //If not found, mark for later removal
+ if (t.indexOf('<strong>') != -1) {
+ div.className += ' notfound';
+ }
+ div.innerHTML = t;
+ authorsElt.appendChild(div);
+
+ newAuthorElt.disabled = false;
+ newAuthorElt.value = '';
+ addButtonElt.disabled = false;
+ newAuthorElt.focus();
+ }
+
+ //Callback function for failure
+ var showError = function(req, status, errorThrown) {
+ //Error messages won't be localized, but... what can we do?
+ alert('Error: ' + status + ' - ' + errorThrown);
+ newAuthorElt.disabled = false;
+ addButtonElt.disabled = false;
+ newAuthorElt.focus();
+ }
+ $.ajax({
+ type : 'GET',
+ url : url,
+ data : {q : newAuthorElt.value},
+ success : updateAuthors,
+ error : showError
+ });
+ }
+}
+
+//Removes an author by clearing the hidden input value and hiding the div
+function removeAuthor(author) {
+ var div = author.parentNode;
+ var hidden = div.getElementsByTagName('input')[0];
+ hidden.value = '';
+ $(div).fadeOut();
+}
+
+//Update tag description div
+function updateTagDescription(select) {
+ var option = select.options[select.selectedIndex];
+ document.getElementById('tagDescription').innerHTML = tagDescriptions[option.value];
+}
+
+/************************************************
+* developers/add_step4.thtml *
+************************************************/
+//currently shown locale
+var previousLocale = '';
+var previousSpan = '';
+
+//show a locale
+function showLocale(locale, span) {
+ if (previousLocale != '') {
+ document.getElementById('locale_' + previousLocale).style.display = 'none';
+ previousSpan.className = '';
+ }
+ document.getElementById('locale_' + locale).style.display = '';
+ span.className = 'selected';
+
+ previousLocale = locale;
+ previousSpan = span;
+}
+
+/************************************************
+* developers/edit.thtml *
+************************************************/
+//Shows icon upload boxes
+function addIcon(type) {
+ document.getElementById('newIcon').style.display = '';
+
+ //Only unhide delete div if updating
+ if (type == 'edit') {
+ document.getElementById('deleteIcon').style.display = '';
+ document.getElementById('iconLink').style.display = 'none';
+ }
+ else if (type =='new') {
+ document.getElementById('iconDiv').style.display = 'none';
+ }
+}
+
+/************************************************
+* developers/editversion.thtml *
+************************************************/
+//Only confirm delete if checking the box
+function confirmDelete(checkbox) {
+ if (checkbox.checked == false) {
+ return true;
+ }
+ else {
+ return confirm(localized['deleteMessage']);
+ }
+}
+
+/************************************************
+* previews/edit.thtml *
+************************************************/
+//Confirm making default if not already default
+function confirmMakeDefault(checkbox) {
+ if (checkbox.checked == false) {
+ return true;
+ }
+ else {
+ return confirm(localized['makeDefaultNotice']);
+ }
+}
+
+//Confirm clearing default
+function confirmClearDefault(checkbox) {
+ if (checkbox.checked == true) {
+ return true;
+ }
+ else {
+ return confirm(localized['clearDefaultNotice']);
+ }
+}
diff --git a/site/app/webroot/js/editors.js b/site/app/webroot/js/editors.js
new file mode 100644
index 0000000..e79a91a
--- /dev/null
+++ b/site/app/webroot/js/editors.js
@@ -0,0 +1,435 @@
+function showMenu() {
+ document.getElementById('showMenuItem').style.display = 'none';
+ document.getElementById('hideMenuItem').style.display = '';
+ $("#editorMenu").slideDown('medium');
+}
+function hideMenu() {
+ $("#editorMenu").slideUp('medium');
+ document.getElementById('showMenuItem').style.display = '';
+ document.getElementById('hideMenuItem').style.display = 'none';
+}
+/*************************************************
+* editors/queue *
+*************************************************/
+var editors_queue = {
+ init: function() {
+ $('#filterHeader').click(this.toggleFilters);
+
+ $('input#FilterAddonOrAuthor').autocomplete(addonAutocompleteUrl, {
+ minChars: 4,
+ max: 40,
+ formatItem: function(row) {
+ // encode results using a temporary jquery element
+ return '<b>' + $('<div/>').text(row[0]).html() + '</b>';
+ },
+ formatResult: function(row) { return row[0]; },
+ });
+
+ $('select#FilterApplication').change(this.populateAppVersions);
+
+ if (! $('select#FilterApplication').val()) {
+ $('select#FilterMaxVersion').attr('disabled', 'disabled');
+ }
+ },
+
+ /**
+ * Expand/collapse the filter box
+ */
+ toggleFilters: function() {
+ var div = document.getElementById('filterTable');
+ if (div.style.display == 'none') {
+ div.style.display = '';
+ }
+ else {
+ div.style.display = 'none';
+ }
+ },
+
+ /**
+ * Fill the maxVersion select dropdown based on selected application
+ */
+ populateAppVersions: function() {
+ var appId = $('select#FilterApplication').val();
+ var selectNode = $('select#FilterMaxVersion');
+ if (appId) {
+ selectNode.attr('disabled', '');
+ selectNode.load(appversionLookupUrl+appId);
+ } else {
+ selectNode.html('');
+ selectNode.attr('disabled', 'disabled');
+ }
+ },
+}
+
+/*************************************************
+* editors/review *
+*************************************************/
+//Array of possible actions
+var actions = ['public', 'sandbox', 'info', 'superreview'];
+
+//Simulate radio button group for action icons
+function selectAction(action) {
+ var actionField = document.getElementById('actionField');
+ actionField.value = action;
+
+ //Select action and deselect other actions
+ for (var i = 0; i < actions.length; i++) {
+ if (actions[i] == action) {
+ changeIcon(actions[i], 'color');
+ document.getElementById('details-' + actions[i]).style.display = '';
+ }
+ else {
+ changeIcon(actions[i], 'bw');
+ document.getElementById('details-' + actions[i]).style.display = 'none';
+ }
+ }
+
+ // when rejecting, pre-select notification box
+ $('#subscribe input').attr('checked', (action=='sandbox'));
+ // no canned responses/app/os for info request
+ if (action=='info')
+ $('#canned,#testing').hide();
+ else
+ $('#canned,#testing').show();
+
+ $('#subform').show('medium');
+}
+
+//Turn an icon colored/bw
+function changeIcon(action, colorbw) {
+ var icon = document.getElementById(action + 'Icon');
+ var span = document.getElementById(action);
+
+ icon.src = icon.src.substring(0, icon.src.lastIndexOf('/')+1) + action + '-' + colorbw + '.png';
+ span.className = 'action_'+colorbw;
+}
+
+//Get number of selected files
+function selectedFileCount() {
+ var filesSelected = 0;
+ var elements = document.getElementsByTagName('input');
+ for (var i = 0; i < elements.length; i++) {
+ if (elements[i].className == 'fileCheckbox' && elements[i].disabled == false) {
+ if (elements[i].checked == true) {
+ filesSelected++;
+ }
+ }
+ }
+
+ return filesSelected;
+}
+
+//Show notice if more than one file selected
+function selectedFile() {
+ var filesSelected = selectedFileCount();
+
+ if (filesSelected > 1) {
+ document.getElementById('multipleNotice').style.display = '';
+ }
+ else {
+ document.getElementById('multipleNotice').style.display = 'none';
+ }
+}
+
+//Validate review form
+function validateReview(type) {
+ //Make sure an action was selected
+ var action = document.getElementById('actionField').value;
+ if (action == '') {
+ errors += '- ' + localized['action'] + '\n';
+ }
+
+ if (type == 'pending' && action!='info') {
+ //Make sure at least one file is selected
+ var filesSelected = selectedFileCount();
+
+ if (filesSelected == 0) {
+ alert(localized['files']);
+ return false;
+ }
+ }
+
+ var errors = '';
+
+ //Make sure comments were entered
+ if (document.getElementById('comments').value == '') {
+ errors += '- ' + localized['comments'] + '\n';
+ }
+ if (type == 'pending' && action!='info') {
+ //Make sure tested operating system was entered
+ if (document.getElementById('ApprovalOs').value == '') {
+ errors += '- ' + localized['os'] + '\n';
+ }
+ //Make sure tested application was entered
+ if (document.getElementById('ApprovalApplications').value == '') {
+ errors += '- ' + localized['applications'] + '\n';
+ }
+ }
+
+ if (errors != '') {
+ alert(localized['errors'] + '\n' + errors);
+ return false;
+ }
+ else {
+ return true;
+ }
+}
+
+/*************************************************
+* editors/reviewlog *
+*************************************************/
+//Show a review entry's comments
+function showComments(id) {
+ document.getElementById('reviewComment_' + id).style.display = '';
+ document.getElementById('reviewShow_' + id).style.display = 'none';
+ document.getElementById('reviewHide_' + id).style.display = '';
+ document.getElementById('reviewEntry_' + id).className = 'reviewEntryActive';
+}
+
+//Hide a review entry's comments
+function hideComments(id) {
+ document.getElementById('reviewComment_' + id).style.display = 'none';
+ document.getElementById('reviewShow_' + id).style.display = '';
+ document.getElementById('reviewHide_' + id).style.display = 'none';
+ document.getElementById('reviewEntry_' + id).className = '';
+}
+
+function clearInput(input) {
+ if (input.value == 'YYYY-MM-DD') {
+ input.value = '';
+ }
+}
+
+/*************************************************
+* editors/featured *
+*************************************************/
+
+
+/*
+ Creates new autocomplete object for whichever input that just recieved focus.
+ Most likely done on focus to reduce # of objects instantiated on page load
+*/
+function prepAutocomplete(tagid) {
+ $('#new-addon-id-' + tagid).autocomplete(autocompleteurl,
+ {
+ minChars:4,
+ formatItem: function(row) { return '<b>' + row[0] + '</b><br><i>' + row[1] + '</i>'; },
+ formatResult: function(row) { return row[2]; }
+ });
+ $('#new-addon-id-' + tagid).focus();
+}
+
+/*
+ Parses input for addon id and name, then sends to server
+*/
+function addFeatureSubmit(tagid) {
+
+ var addonid = document.getElementById('new-addon-id-' + tagid).value;
+
+ addonname = addonid.substring(0, addonid.lastIndexOf('['));
+ addonid = addonid.substring(addonid.lastIndexOf('[')+1, addonid.lastIndexOf(']'));
+
+ if (addonid.length == 0) {
+ editFeatureMessage(tagid, featureaddfailure, false);
+ return false;
+ }
+
+ $.ajax({
+ type: 'POST',
+ url: featuredurl + '/add/ajax',
+ data: $('#feature-add-form-'+tagid).serialize(),
+ success : function() {
+ $('#new-addon-id-' + tagid).attr('value', '');
+ addNewFeatureRowBeforeElement($('#feature-add-tr-form-' + tagid), tagid, addonid, addonname);
+ },
+ error : function() {
+ editFeatureMessage(tagid, featureaddfailure, false);
+ }
+ });
+
+ return false;
+}
+
+/*
+ After an addon is added to a featured list, it is added above the search box
+*/
+function addNewFeatureRowBeforeElement(sibling, tagid, addonid, addonname) {
+ // Sure would be nice if we had a newer Prototype library :(
+
+ var addonrow = document.createElement('tr');
+ addonrow.setAttribute('id', 'feature-' + tagid + '-' + addonid);
+
+ // First <td>
+ var deletelink = document.createElement('a');
+ deletelink.setAttribute('href', featuredurl + '/remove/' + tagid + '/' + addonid);
+ deletelink.setAttribute('id', 'delete-' + tagid + '-' + addonid);
+ deletelink.setAttribute('onclick', 'removeFeature(' + tagid + ',' + addonid + '); return false;');
+
+ var deleteimage = document.createElement('img');
+ deleteimage.setAttribute('src', imageurl + '/developers/delete.png');
+ deleteimage.setAttribute('class', 'featureremove');
+ deletelink.appendChild(deleteimage);
+
+ var addonlink = document.createElement('a');
+ addonlink.setAttribute('href', addonurl + '/' + addonid);
+ addonlink.appendChild(document.createTextNode(addonname));
+
+ var addontd1 = document.createElement('td');
+ addontd1.appendChild(deletelink);
+ addontd1.appendChild(addonlink);
+
+ // Second <td>
+ var addonform = document.createElement('form');
+ addonform.setAttribute('id', 'feature-edit-form-' + tagid + '-' + addonid);
+ addonform.setAttribute('onsubmit', 'editFeatureSubmit(' + tagid + ',' + addonid + '); return false;');
+ addonform.setAttribute('action', featuredurl + '/edit');
+ addonform.setAttribute('method', 'post');
+
+ var addonforminputlocale = document.createElement('input');
+ addonforminputlocale.setAttribute('name', 'data[AddonTag][feature_locales]');
+ addonforminputlocale.setAttribute('id', 'edit-addon-locales-' + tagid + '-' + addonid);
+ addonforminputlocale.setAttribute('size', '40');
+ addonforminputlocale.setAttribute('type', 'text');
+ addonform.appendChild(addonforminputlocale);
+
+ var addonforminputsubmit = document.createElement('input');
+ addonforminputsubmit.setAttribute('id', 'edit-feature-submit-' + tagid + '-' + addonid);
+ addonforminputsubmit.setAttribute('value', featureeditsubmit);
+ addonforminputsubmit.setAttribute('type', 'submit');
+ addonforminputsubmit.setAttribute('value', featureeditsubmit);
+ addonform.appendChild(addonforminputsubmit);
+
+ var addonformfeaturemessage = document.createElement('span');
+ addonformfeaturemessage.setAttribute('id', 'edit-feature-message-' + tagid + '-' + addonid);
+ addonform.appendChild(addonformfeaturemessage);
+
+
+ var addontd2 = document.createElement('td');
+ addontd2.appendChild(addonform);
+
+ addonrow.appendChild(addontd1);
+ addonrow.appendChild(addontd2);
+
+ sibling.before(addonrow);
+ return true;
+}
+
+
+function editFeatureSubmit(tagid, addonid) {
+ var locales = document.getElementById('edit-addon-locales-' + tagid + '-' + addonid).value;
+
+ if (locales.match(/[^A-Za-z,-]/)) {
+ editFeatureMessage(tagid, addedinvalidlocale, false);
+ return false;
+ }
+
+ $.ajax({
+ type: 'POST',
+ url: featuredurl + '/edit/ajax',
+ data: $('#feature-edit-form-'+tagid+'-'+addonid).serialize(),
+ success : function(){
+ editFeatureMessage(tagid, featureeditsuccess, true);
+ },
+ error : function(){
+ editFeatureMessage(tagid, featureeditfailure, false);
+ }
+ });
+
+ return false;
+}
+
+/*
+ Shows a message when editing a featured addon, then hides after 5 seconds
+*/
+function editFeatureMessage(tagid, message, success) {
+ var target = $('#edit-feature-message-' + tagid);
+ if (success) {
+ target.attr('class', 'success');
+ } else {
+ target.attr('class', 'failure');
+ }
+ target.html(message);
+
+ var toclear = $('#edit-feature-message-' + tagid);
+
+ setTimeout( function() {toclear.html('');} , 5000);
+}
+
+
+function removeFeature(tagid, addonid) {
+ $.ajax({
+ url: featuredurl + '/remove/ajax',
+ type: 'POST',
+ data: $('#feature-remove-form-'+tagid+'-'+addonid).serialize(),
+ success: function(){
+ $('#feature-' + tagid + '-' + addonid).fadeOut();
+ },
+ error : function(){
+ editFeatureMessage(tagid, featureremovefailure, false);
+ }
+ });
+ return false;
+}
+
+/*************************************************
+* editors/performance *
+*************************************************/
+var editors_performance = {
+ init: function() {
+ $('.performanceHeader.collapsible').click(function() {
+ var el = $(this).next();
+ if(! $(':animated', el).length) {
+ if ($(':visible', el).length) {
+ el.slideUp('200', function(){});
+ $(this).removeClass('expanded');
+ } else {
+ el.slideDown('200', function(){});
+ $(this).addClass('expanded');
+ }
+ }
+ });
+
+ $('select#performanceUser').change(this.switchUser);
+
+ $('#historyTable').tablesorter({cssHeader:'headerSort'});
+ },
+
+ switchUser: function() {
+ var qs = '?user='+encodeURIComponent($('select#performanceUser').val());
+ if (document.location.search.length > 0) {
+ var params = document.location.search.substr(1).split("&");
+ for (var i = 0; i < params.length; i++) {
+ if (params[i].substr(0, 5) != 'user=') {
+ qs = qs + '&' + params[i];
+ }
+ }
+ }
+ window.location.search = qs;
+ },
+
+ showChartTooltip: function(x, y, contents) {
+ $('<div id="chartTip">' + contents + '</div>').css( {
+ position: 'absolute',
+ display: 'none',
+ top: y - 25,
+ left: x + 5,
+ border: '1px solid #fdd',
+ padding: '2px',
+ 'background-color': '#fee',
+ opacity: 0.80
+ }).appendTo('body').fadeIn(100);
+ },
+
+ pieLegendEntry: function(color, text, value, total, id) {
+ var percent = 0;
+ if (total > 0) {
+ percent = 100 * value / total;
+ }
+ var precision = 0;
+ if (percent < 1 && percent > 0) {
+ precision = 2;
+ }
+ var label = text + ' ' + percent.toFixed(precision) + '%';
+ return $('<div id="' + id + '">' + label + '</div>').css('border-left','1.5em solid '+color);
+ }
+}
diff --git a/site/app/webroot/js/f8.js b/site/app/webroot/js/f8.js
new file mode 100644
index 0000000..882dcec
--- /dev/null
+++ b/site/app/webroot/js/f8.js
@@ -0,0 +1,152 @@
+var addons;
+var currentSort;
+var currentAddon;
+
+$(document).ready(function(){
+ $("#TagId1").change(function(){ loadAddons(null, null); });
+ $("#TagId2").change(function(){ loadAddons(null, null); });
+ $("#AddontypeId").change(function(){ changeTags(); loadAddons(null, null); });
+});
+
+function loadAddons(caption, sort, url_tail){
+ $("#loading").show();
+ $("#pagenavigation").hide();
+ $(".browselist > li").removeClass('selected');
+ $("#" + sort).addClass('selected');
+
+ if (sort == null)
+ sort = currentSort;
+ else
+ currentSort = sort;
+
+ if (url_tail == null)
+ url_tail = '';
+
+ var url = base_url + 'sort:' + sort + '/type:' + $("#AddontypeId").val() + '/cat:' + $("#TagId" + $("#AddontypeId").val()).val() + url_tail;
+ //alert(url);
+ $("#addonbox_title").html(caption);
+
+ var req = $.getJSON(url, null, function(json){ populateAddons(json); });
+
+ //setTimeout(function(){alert(req.responseText);}, 5000);
+}
+
+function search() {
+ alert('Search doesn\'t work yet, k!');
+}
+
+function populateAddons(json) {
+ $("#loading").hide();
+ $("#addonlist").empty();
+
+ if (json.noresults != 'true') {
+ $.each(json.addons, function(i, n){
+ var item = '<div class="addon"><div class="name">';
+ item += '<a href="#" onClick="addonDetails(' + n.id + ');">' + n.name + '</a>';
+ if (n.favorite == 'true') {
+ item += '&nbsp;<img src="../../../img/smallMedal.png" title="Favorite Add-on">';
+ }
+ if (n.friend != null) {
+ item += ' (' + n.friend + ')';
+ }
+ item += '</div>';
+ item += '<div class="summary">' + n.summary + '</div></div>';
+
+ $(item).appendTo("#addonlist");
+
+ $("#pagenavigation").show();
+ });
+
+ addons = json.addons;
+ if (json.query_url != null) {
+ $("#moreresults").show();
+ $("#moreresults").attr('href', json.query_url);
+ }
+ else {
+ $("#moreresults").hide();
+ }
+ }
+ else {
+ $("#addonlist").html('No add-ons found. Please try different criteria.');
+ }
+}
+
+function changeTags() {
+ $("#TagId" + $("#AddontypeId").val()).css('display', '');
+ $("#TagId" + (3 - $("#AddontypeId").val())).css('display', 'none');
+}
+
+function addonDetails(id) {
+ $("#fav_loading").hide();
+ if ($("#addonwindow").css('display') == 'none') {
+ $("#addonwindow").slideDown();
+ }
+ currentAddon = id;
+
+ $("#addonwindow > .name > .name").html(addons[id].name);
+ $("#addonwindow > .summary").html(addons[id].summary);
+ $("#addonwindow > .details > .version").html(addons[id].version);
+ $("#addonwindow > .details > .released").html(addons[id].released_pretty);
+ $("#addonpreview").attr('src', addons[id].preview_url);
+ $("#addoninstall_link").attr('href', addons[id].display_url);
+ $("#addonwindow > .details > .compat_versions").html(addons[id].apps[1].min + ' - ' + addons[id].apps[1].max);
+
+ var authors = '';
+ var count = 0;
+ $.each(addons[id].authors, function (i, n){
+ if (count != 0)
+ authors += ', ';
+ authors += n.firstname + ' ' + n.lastname;
+ count++;
+ });
+ $("#addonwindow > .authors > .authors").html(authors);
+
+ if (addons[id].favorite == 'true') {
+ $("#add_fav").hide();
+ $("#remove_fav").show();
+ $("#fav_medal").show();
+ }
+ else {
+ $("#add_fav").show();
+ $("#remove_fav").hide();
+ $("#fav_medal").hide();
+ }
+}
+
+function hideAddonDetails() {
+ $("#addonwindow").slideUp();
+}
+
+function addFavorite(url) {
+ $("#fav_loading").show();
+ url = url + currentAddon;
+
+ $.getJSON(url, null, function(json) {
+ $("#fav_loading").hide();
+ if (json.result == 'success') {
+ $("#add_fav").hide();
+ $("#remove_fav").show();
+ $("#fav_medal").show();
+ }
+ else {
+ alert(json.error);
+ }
+ });
+}
+
+function removeFavorite(url) {
+ $("#fav_loading").show();
+ url = url + currentAddon;
+
+ $.getJSON(url, null, function(json) {
+ $("#fav_loading").hide();
+ if (json.result == 'success') {
+ $("#remove_fav").hide();
+ $("#add_fav").show();
+ $("#fav_medal").hide();
+ }
+ else {
+ alert(json.error);
+ }
+ });
+} \ No newline at end of file
diff --git a/site/app/webroot/js/filebrowser.js b/site/app/webroot/js/filebrowser.js
new file mode 100644
index 0000000..bf5fe57
--- /dev/null
+++ b/site/app/webroot/js/filebrowser.js
@@ -0,0 +1,18 @@
+/************************************************
+* files/browse *
+************************************************/
+//Expand/collapse the file listing
+function toggleFileListing() {
+ var div = document.getElementById('fileListing');
+ if (div.style.display == 'none') {
+ Effect.SlideDown(div);
+ }
+ else {
+ Effect.SlideUp(div);
+ }
+}
+
+//Change iframe location to selected location
+function viewFile(file) {
+ document.getElementById('fileBrowser').src = file;
+}
diff --git a/site/app/webroot/js/jquery-compressed.js b/site/app/webroot/js/jquery-compressed.js
new file mode 100644
index 0000000..b1ae21d
--- /dev/null
+++ b/site/app/webroot/js/jquery-compressed.js
@@ -0,0 +1,19 @@
+/*
+ * jQuery JavaScript Library v1.3.2
+ * http://jquery.com/
+ *
+ * Copyright (c) 2009 John Resig
+ * Dual licensed under the MIT and GPL licenses.
+ * http://docs.jquery.com/License
+ *
+ * Date: 2009-02-19 17:34:21 -0500 (Thu, 19 Feb 2009)
+ * Revision: 6246
+ */
+(function(){var l=this,g,y=l.jQuery,p=l.$,o=l.jQuery=l.$=function(E,F){return new o.fn.init(E,F)},D=/^[^<]*(<(.|\s)+>)[^>]*$|^#([\w-]+)$/,f=/^.[^:#\[\.,]*$/;o.fn=o.prototype={init:function(E,H){E=E||document;if(E.nodeType){this[0]=E;this.length=1;this.context=E;return this}if(typeof E==="string"){var G=D.exec(E);if(G&&(G[1]||!H)){if(G[1]){E=o.clean([G[1]],H)}else{var I=document.getElementById(G[3]);if(I&&I.id!=G[3]){return o().find(E)}var F=o(I||[]);F.context=document;F.selector=E;return F}}else{return o(H).find(E)}}else{if(o.isFunction(E)){return o(document).ready(E)}}if(E.selector&&E.context){this.selector=E.selector;this.context=E.context}return this.setArray(o.isArray(E)?E:o.makeArray(E))},selector:"",jquery:"1.3.2",size:function(){return this.length},get:function(E){return E===g?Array.prototype.slice.call(this):this[E]},pushStack:function(F,H,E){var G=o(F);G.prevObject=this;G.context=this.context;if(H==="find"){G.selector=this.selector+(this.selector?" ":"")+E}else{if(H){G.selector=this.selector+"."+H+"("+E+")"}}return G},setArray:function(E){this.length=0;Array.prototype.push.apply(this,E);return this},each:function(F,E){return o.each(this,F,E)},index:function(E){return o.inArray(E&&E.jquery?E[0]:E,this)},attr:function(F,H,G){var E=F;if(typeof F==="string"){if(H===g){return this[0]&&o[G||"attr"](this[0],F)}else{E={};E[F]=H}}return this.each(function(I){for(F in E){o.attr(G?this.style:this,F,o.prop(this,E[F],G,I,F))}})},css:function(E,F){if((E=="width"||E=="height")&&parseFloat(F)<0){F=g}return this.attr(E,F,"curCSS")},text:function(F){if(typeof F!=="object"&&F!=null){return this.empty().append((this[0]&&this[0].ownerDocument||document).createTextNode(F))}var E="";o.each(F||this,function(){o.each(this.childNodes,function(){if(this.nodeType!=8){E+=this.nodeType!=1?this.nodeValue:o.fn.text([this])}})});return E},wrapAll:function(E){if(this[0]){var F=o(E,this[0].ownerDocument).clone();if(this[0].parentNode){F.insertBefore(this[0])}F.map(function(){var G=this;while(G.firstChild){G=G.firstChild}return G}).append(this)}return this},wrapInner:function(E){return this.each(function(){o(this).contents().wrapAll(E)})},wrap:function(E){return this.each(function(){o(this).wrapAll(E)})},append:function(){return this.domManip(arguments,true,function(E){if(this.nodeType==1){this.appendChild(E)}})},prepend:function(){return this.domManip(arguments,true,function(E){if(this.nodeType==1){this.insertBefore(E,this.firstChild)}})},before:function(){return this.domManip(arguments,false,function(E){this.parentNode.insertBefore(E,this)})},after:function(){return this.domManip(arguments,false,function(E){this.parentNode.insertBefore(E,this.nextSibling)})},end:function(){return this.prevObject||o([])},push:[].push,sort:[].sort,splice:[].splice,find:function(E){if(this.length===1){var F=this.pushStack([],"find",E);F.length=0;o.find(E,this[0],F);return F}else{return this.pushStack(o.unique(o.map(this,function(G){return o.find(E,G)})),"find",E)}},clone:function(G){var E=this.map(function(){if(!o.support.noCloneEvent&&!o.isXMLDoc(this)){var I=this.outerHTML;if(!I){var J=this.ownerDocument.createElement("div");J.appendChild(this.cloneNode(true));I=J.innerHTML}return o.clean([I.replace(/ jQuery\d+="(?:\d+|null)"/g,"").replace(/^\s*/,"")])[0]}else{return this.cloneNode(true)}});if(G===true){var H=this.find("*").andSelf(),F=0;E.find("*").andSelf().each(function(){if(this.nodeName!==H[F].nodeName){return}var I=o.data(H[F],"events");for(var K in I){for(var J in I[K]){o.event.add(this,K,I[K][J],I[K][J].data)}}F++})}return E},filter:function(E){return this.pushStack(o.isFunction(E)&&o.grep(this,function(G,F){return E.call(G,F)})||o.multiFilter(E,o.grep(this,function(F){return F.nodeType===1})),"filter",E)},closest:function(E){var G=o.expr.match.POS.test(E)?o(E):null,F=0;return this.map(function(){var H=this;while(H&&H.ownerDocument){if(G?G.index(H)>-1:o(H).is(E)){o.data(H,"closest",F);return H}H=H.parentNode;F++}})},not:function(E){if(typeof E==="string"){if(f.test(E)){return this.pushStack(o.multiFilter(E,this,true),"not",E)}else{E=o.multiFilter(E,this)}}var F=E.length&&E[E.length-1]!==g&&!E.nodeType;return this.filter(function(){return F?o.inArray(this,E)<0:this!=E})},add:function(E){return this.pushStack(o.unique(o.merge(this.get(),typeof E==="string"?o(E):o.makeArray(E))))},is:function(E){return !!E&&o.multiFilter(E,this).length>0},hasClass:function(E){return !!E&&this.is("."+E)},val:function(K){if(K===g){var E=this[0];if(E){if(o.nodeName(E,"option")){return(E.attributes.value||{}).specified?E.value:E.text}if(o.nodeName(E,"select")){var I=E.selectedIndex,L=[],M=E.options,H=E.type=="select-one";if(I<0){return null}for(var F=H?I:0,J=H?I+1:M.length;F<J;F++){var G=M[F];if(G.selected){K=o(G).val();if(H){return K}L.push(K)}}return L}return(E.value||"").replace(/\r/g,"")}return g}if(typeof K==="number"){K+=""}return this.each(function(){if(this.nodeType!=1){return}if(o.isArray(K)&&/radio|checkbox/.test(this.type)){this.checked=(o.inArray(this.value,K)>=0||o.inArray(this.name,K)>=0)}else{if(o.nodeName(this,"select")){var N=o.makeArray(K);o("option",this).each(function(){this.selected=(o.inArray(this.value,N)>=0||o.inArray(this.text,N)>=0)});if(!N.length){this.selectedIndex=-1}}else{this.value=K}}})},html:function(E){return E===g?(this[0]?this[0].innerHTML.replace(/ jQuery\d+="(?:\d+|null)"/g,""):null):this.empty().append(E)},replaceWith:function(E){return this.after(E).remove()},eq:function(E){return this.slice(E,+E+1)},slice:function(){return this.pushStack(Array.prototype.slice.apply(this,arguments),"slice",Array.prototype.slice.call(arguments).join(","))},map:function(E){return this.pushStack(o.map(this,function(G,F){return E.call(G,F,G)}))},andSelf:function(){return this.add(this.prevObject)},domManip:function(J,M,L){if(this[0]){var I=(this[0].ownerDocument||this[0]).createDocumentFragment(),F=o.clean(J,(this[0].ownerDocument||this[0]),I),H=I.firstChild;if(H){for(var G=0,E=this.length;G<E;G++){L.call(K(this[G],H),this.length>1||G>0?I.cloneNode(true):I)}}if(F){o.each(F,z)}}return this;function K(N,O){return M&&o.nodeName(N,"table")&&o.nodeName(O,"tr")?(N.getElementsByTagName("tbody")[0]||N.appendChild(N.ownerDocument.createElement("tbody"))):N}}};o.fn.init.prototype=o.fn;function z(E,F){if(F.src){o.ajax({url:F.src,async:false,dataType:"script"})}else{o.globalEval(F.text||F.textContent||F.innerHTML||"")}if(F.parentNode){F.parentNode.removeChild(F)}}function e(){return +new Date}o.extend=o.fn.extend=function(){var J=arguments[0]||{},H=1,I=arguments.length,E=false,G;if(typeof J==="boolean"){E=J;J=arguments[1]||{};H=2}if(typeof J!=="object"&&!o.isFunction(J)){J={}}if(I==H){J=this;--H}for(;H<I;H++){if((G=arguments[H])!=null){for(var F in G){var K=J[F],L=G[F];if(J===L){continue}if(E&&L&&typeof L==="object"&&!L.nodeType){J[F]=o.extend(E,K||(L.length!=null?[]:{}),L)}else{if(L!==g){J[F]=L}}}}}return J};var b=/z-?index|font-?weight|opacity|zoom|line-?height/i,q=document.defaultView||{},s=Object.prototype.toString;o.extend({noConflict:function(E){l.$=p;if(E){l.jQuery=y}return o},isFunction:function(E){return s.call(E)==="[object Function]"},isArray:function(E){return s.call(E)==="[object Array]"},isXMLDoc:function(E){return E.nodeType===9&&E.documentElement.nodeName!=="HTML"||!!E.ownerDocument&&o.isXMLDoc(E.ownerDocument)},globalEval:function(G){if(G&&/\S/.test(G)){var F=document.getElementsByTagName("head")[0]||document.documentElement,E=document.createElement("script");E.type="text/javascript";if(o.support.scriptEval){E.appendChild(document.createTextNode(G))}else{E.text=G}F.insertBefore(E,F.firstChild);F.removeChild(E)}},nodeName:function(F,E){return F.nodeName&&F.nodeName.toUpperCase()==E.toUpperCase()},each:function(G,K,F){var E,H=0,I=G.length;if(F){if(I===g){for(E in G){if(K.apply(G[E],F)===false){break}}}else{for(;H<I;){if(K.apply(G[H++],F)===false){break}}}}else{if(I===g){for(E in G){if(K.call(G[E],E,G[E])===false){break}}}else{for(var J=G[0];H<I&&K.call(J,H,J)!==false;J=G[++H]){}}}return G},prop:function(H,I,G,F,E){if(o.isFunction(I)){I=I.call(H,F)}return typeof I==="number"&&G=="curCSS"&&!b.test(E)?I+"px":I},className:{add:function(E,F){o.each((F||"").split(/\s+/),function(G,H){if(E.nodeType==1&&!o.className.has(E.className,H)){E.className+=(E.className?" ":"")+H}})},remove:function(E,F){if(E.nodeType==1){E.className=F!==g?o.grep(E.className.split(/\s+/),function(G){return !o.className.has(F,G)}).join(" "):""}},has:function(F,E){return F&&o.inArray(E,(F.className||F).toString().split(/\s+/))>-1}},swap:function(H,G,I){var E={};for(var F in G){E[F]=H.style[F];H.style[F]=G[F]}I.call(H);for(var F in G){H.style[F]=E[F]}},css:function(H,F,J,E){if(F=="width"||F=="height"){var L,G={position:"absolute",visibility:"hidden",display:"block"},K=F=="width"?["Left","Right"]:["Top","Bottom"];function I(){L=F=="width"?H.offsetWidth:H.offsetHeight;if(E==="border"){return}o.each(K,function(){if(!E){L-=parseFloat(o.curCSS(H,"padding"+this,true))||0}if(E==="margin"){L+=parseFloat(o.curCSS(H,"margin"+this,true))||0}else{L-=parseFloat(o.curCSS(H,"border"+this+"Width",true))||0}})}if(H.offsetWidth!==0){I()}else{o.swap(H,G,I)}return Math.max(0,Math.round(L))}return o.curCSS(H,F,J)},curCSS:function(I,F,G){var L,E=I.style;if(F=="opacity"&&!o.support.opacity){L=o.attr(E,"opacity");return L==""?"1":L}if(F.match(/float/i)){F=w}if(!G&&E&&E[F]){L=E[F]}else{if(q.getComputedStyle){if(F.match(/float/i)){F="float"}F=F.replace(/([A-Z])/g,"-$1").toLowerCase();var M=q.getComputedStyle(I,null);if(M){L=M.getPropertyValue(F)}if(F=="opacity"&&L==""){L="1"}}else{if(I.currentStyle){var J=F.replace(/\-(\w)/g,function(N,O){return O.toUpperCase()});L=I.currentStyle[F]||I.currentStyle[J];if(!/^\d+(px)?$/i.test(L)&&/^\d/.test(L)){var H=E.left,K=I.runtimeStyle.left;I.runtimeStyle.left=I.currentStyle.left;E.left=L||0;L=E.pixelLeft+"px";E.left=H;I.runtimeStyle.left=K}}}}return L},clean:function(F,K,I){K=K||document;if(typeof K.createElement==="undefined"){K=K.ownerDocument||K[0]&&K[0].ownerDocument||document}if(!I&&F.length===1&&typeof F[0]==="string"){var H=/^<(\w+)\s*\/?>$/.exec(F[0]);if(H){return[K.createElement(H[1])]}}var G=[],E=[],L=K.createElement("div");o.each(F,function(P,S){if(typeof S==="number"){S+=""}if(!S){return}if(typeof S==="string"){S=S.replace(/(<(\w+)[^>]*?)\/>/g,function(U,V,T){return T.match(/^(abbr|br|col|img|input|link|meta|param|hr|area|embed)$/i)?U:V+"></"+T+">"});var O=S.replace(/^\s+/,"").substring(0,10).toLowerCase();var Q=!O.indexOf("<opt")&&[1,"<select multiple='multiple'>","</select>"]||!O.indexOf("<leg")&&[1,"<fieldset>","</fieldset>"]||O.match(/^<(thead|tbody|tfoot|colg|cap)/)&&[1,"<table>","</table>"]||!O.indexOf("<tr")&&[2,"<table><tbody>","</tbody></table>"]||(!O.indexOf("<td")||!O.indexOf("<th"))&&[3,"<table><tbody><tr>","</tr></tbody></table>"]||!O.indexOf("<col")&&[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"]||!o.support.htmlSerialize&&[1,"div<div>","</div>"]||[0,"",""];L.innerHTML=Q[1]+S+Q[2];while(Q[0]--){L=L.lastChild}if(!o.support.tbody){var R=/<tbody/i.test(S),N=!O.indexOf("<table")&&!R?L.firstChild&&L.firstChild.childNodes:Q[1]=="<table>"&&!R?L.childNodes:[];for(var M=N.length-1;M>=0;--M){if(o.nodeName(N[M],"tbody")&&!N[M].childNodes.length){N[M].parentNode.removeChild(N[M])}}}if(!o.support.leadingWhitespace&&/^\s/.test(S)){L.insertBefore(K.createTextNode(S.match(/^\s*/)[0]),L.firstChild)}S=o.makeArray(L.childNodes)}if(S.nodeType){G.push(S)}else{G=o.merge(G,S)}});if(I){for(var J=0;G[J];J++){if(o.nodeName(G[J],"script")&&(!G[J].type||G[J].type.toLowerCase()==="text/javascript")){E.push(G[J].parentNode?G[J].parentNode.removeChild(G[J]):G[J])}else{if(G[J].nodeType===1){G.splice.apply(G,[J+1,0].concat(o.makeArray(G[J].getElementsByTagName("script"))))}I.appendChild(G[J])}}return E}return G},attr:function(J,G,K){if(!J||J.nodeType==3||J.nodeType==8){return g}var H=!o.isXMLDoc(J),L=K!==g;G=H&&o.props[G]||G;if(J.tagName){var F=/href|src|style/.test(G);if(G=="selected"&&J.parentNode){J.parentNode.selectedIndex}if(G in J&&H&&!F){if(L){if(G=="type"&&o.nodeName(J,"input")&&J.parentNode){throw"type property can't be changed"}J[G]=K}if(o.nodeName(J,"form")&&J.getAttributeNode(G)){return J.getAttributeNode(G).nodeValue}if(G=="tabIndex"){var I=J.getAttributeNode("tabIndex");return I&&I.specified?I.value:J.nodeName.match(/(button|input|object|select|textarea)/i)?0:J.nodeName.match(/^(a|area)$/i)&&J.href?0:g}return J[G]}if(!o.support.style&&H&&G=="style"){return o.attr(J.style,"cssText",K)}if(L){J.setAttribute(G,""+K)}var E=!o.support.hrefNormalized&&H&&F?J.getAttribute(G,2):J.getAttribute(G);return E===null?g:E}if(!o.support.opacity&&G=="opacity"){if(L){J.zoom=1;J.filter=(J.filter||"").replace(/alpha\([^)]*\)/,"")+(parseInt(K)+""=="NaN"?"":"alpha(opacity="+K*100+")")}return J.filter&&J.filter.indexOf("opacity=")>=0?(parseFloat(J.filter.match(/opacity=([^)]*)/)[1])/100)+"":""}G=G.replace(/-([a-z])/ig,function(M,N){return N.toUpperCase()});if(L){J[G]=K}return J[G]},trim:function(E){return(E||"").replace(/^\s+|\s+$/g,"")},makeArray:function(G){var E=[];if(G!=null){var F=G.length;if(F==null||typeof G==="string"||o.isFunction(G)||G.setInterval){E[0]=G}else{while(F){E[--F]=G[F]}}}return E},inArray:function(G,H){for(var E=0,F=H.length;E<F;E++){if(H[E]===G){return E}}return -1},merge:function(H,E){var F=0,G,I=H.length;if(!o.support.getAll){while((G=E[F++])!=null){if(G.nodeType!=8){H[I++]=G}}}else{while((G=E[F++])!=null){H[I++]=G}}return H},unique:function(K){var F=[],E={};try{for(var G=0,H=K.length;G<H;G++){var J=o.data(K[G]);if(!E[J]){E[J]=true;F.push(K[G])}}}catch(I){F=K}return F},grep:function(F,J,E){var G=[];for(var H=0,I=F.length;H<I;H++){if(!E!=!J(F[H],H)){G.push(F[H])}}return G},map:function(E,J){var F=[];for(var G=0,H=E.length;G<H;G++){var I=J(E[G],G);if(I!=null){F[F.length]=I}}return F.concat.apply([],F)}});var C=navigator.userAgent.toLowerCase();o.browser={version:(C.match(/.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/)||[0,"0"])[1],safari:/webkit/.test(C),opera:/opera/.test(C),msie:/msie/.test(C)&&!/opera/.test(C),mozilla:/mozilla/.test(C)&&!/(compatible|webkit)/.test(C)};o.each({parent:function(E){return E.parentNode},parents:function(E){return o.dir(E,"parentNode")},next:function(E){return o.nth(E,2,"nextSibling")},prev:function(E){return o.nth(E,2,"previousSibling")},nextAll:function(E){return o.dir(E,"nextSibling")},prevAll:function(E){return o.dir(E,"previousSibling")},siblings:function(E){return o.sibling(E.parentNode.firstChild,E)},children:function(E){return o.sibling(E.firstChild)},contents:function(E){return o.nodeName(E,"iframe")?E.contentDocument||E.contentWindow.document:o.makeArray(E.childNodes)}},function(E,F){o.fn[E]=function(G){var H=o.map(this,F);if(G&&typeof G=="string"){H=o.multiFilter(G,H)}return this.pushStack(o.unique(H),E,G)}});o.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(E,F){o.fn[E]=function(G){var J=[],L=o(G);for(var K=0,H=L.length;K<H;K++){var I=(K>0?this.clone(true):this).get();o.fn[F].apply(o(L[K]),I);J=J.concat(I)}return this.pushStack(J,E,G)}});o.each({removeAttr:function(E){o.attr(this,E,"");if(this.nodeType==1){this.removeAttribute(E)}},addClass:function(E){o.className.add(this,E)},removeClass:function(E){o.className.remove(this,E)},toggleClass:function(F,E){if(typeof E!=="boolean"){E=!o.className.has(this,F)}o.className[E?"add":"remove"](this,F)},remove:function(E){if(!E||o.filter(E,[this]).length){o("*",this).add([this]).each(function(){o.event.remove(this);o.removeData(this)});if(this.parentNode){this.parentNode.removeChild(this)}}},empty:function(){o(this).children().remove();while(this.firstChild){this.removeChild(this.firstChild)}}},function(E,F){o.fn[E]=function(){return this.each(F,arguments)}});function j(E,F){return E[0]&&parseInt(o.curCSS(E[0],F,true),10)||0}var h="jQuery"+e(),v=0,A={};o.extend({cache:{},data:function(F,E,G){F=F==l?A:F;var H=F[h];if(!H){H=F[h]=++v}if(E&&!o.cache[H]){o.cache[H]={}}if(G!==g){o.cache[H][E]=G}return E?o.cache[H][E]:H},removeData:function(F,E){F=F==l?A:F;var H=F[h];if(E){if(o.cache[H]){delete o.cache[H][E];E="";for(E in o.cache[H]){break}if(!E){o.removeData(F)}}}else{try{delete F[h]}catch(G){if(F.removeAttribute){F.removeAttribute(h)}}delete o.cache[H]}},queue:function(F,E,H){if(F){E=(E||"fx")+"queue";var G=o.data(F,E);if(!G||o.isArray(H)){G=o.data(F,E,o.makeArray(H))}else{if(H){G.push(H)}}}return G},dequeue:function(H,G){var E=o.queue(H,G),F=E.shift();if(!G||G==="fx"){F=E[0]}if(F!==g){F.call(H)}}});o.fn.extend({data:function(E,G){var H=E.split(".");H[1]=H[1]?"."+H[1]:"";if(G===g){var F=this.triggerHandler("getData"+H[1]+"!",[H[0]]);if(F===g&&this.length){F=o.data(this[0],E)}return F===g&&H[1]?this.data(H[0]):F}else{return this.trigger("setData"+H[1]+"!",[H[0],G]).each(function(){o.data(this,E,G)})}},removeData:function(E){return this.each(function(){o.removeData(this,E)})},queue:function(E,F){if(typeof E!=="string"){F=E;E="fx"}if(F===g){return o.queue(this[0],E)}return this.each(function(){var G=o.queue(this,E,F);if(E=="fx"&&G.length==1){G[0].call(this)}})},dequeue:function(E){return this.each(function(){o.dequeue(this,E)})}});
+/*
+ * Sizzle CSS Selector Engine - v0.9.3
+ * Copyright 2009, The Dojo Foundation
+ * Released under the MIT, BSD, and GPL Licenses.
+ * More information: http://sizzlejs.com/
+ */
+(function(){var R=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?/g,L=0,H=Object.prototype.toString;var F=function(Y,U,ab,ac){ab=ab||[];U=U||document;if(U.nodeType!==1&&U.nodeType!==9){return[]}if(!Y||typeof Y!=="string"){return ab}var Z=[],W,af,ai,T,ad,V,X=true;R.lastIndex=0;while((W=R.exec(Y))!==null){Z.push(W[1]);if(W[2]){V=RegExp.rightContext;break}}if(Z.length>1&&M.exec(Y)){if(Z.length===2&&I.relative[Z[0]]){af=J(Z[0]+Z[1],U)}else{af=I.relative[Z[0]]?[U]:F(Z.shift(),U);while(Z.length){Y=Z.shift();if(I.relative[Y]){Y+=Z.shift()}af=J(Y,af)}}}else{var ae=ac?{expr:Z.pop(),set:E(ac)}:F.find(Z.pop(),Z.length===1&&U.parentNode?U.parentNode:U,Q(U));af=F.filter(ae.expr,ae.set);if(Z.length>0){ai=E(af)}else{X=false}while(Z.length){var ah=Z.pop(),ag=ah;if(!I.relative[ah]){ah=""}else{ag=Z.pop()}if(ag==null){ag=U}I.relative[ah](ai,ag,Q(U))}}if(!ai){ai=af}if(!ai){throw"Syntax error, unrecognized expression: "+(ah||Y)}if(H.call(ai)==="[object Array]"){if(!X){ab.push.apply(ab,ai)}else{if(U.nodeType===1){for(var aa=0;ai[aa]!=null;aa++){if(ai[aa]&&(ai[aa]===true||ai[aa].nodeType===1&&K(U,ai[aa]))){ab.push(af[aa])}}}else{for(var aa=0;ai[aa]!=null;aa++){if(ai[aa]&&ai[aa].nodeType===1){ab.push(af[aa])}}}}}else{E(ai,ab)}if(V){F(V,U,ab,ac);if(G){hasDuplicate=false;ab.sort(G);if(hasDuplicate){for(var aa=1;aa<ab.length;aa++){if(ab[aa]===ab[aa-1]){ab.splice(aa--,1)}}}}}return ab};F.matches=function(T,U){return F(T,null,null,U)};F.find=function(aa,T,ab){var Z,X;if(!aa){return[]}for(var W=0,V=I.order.length;W<V;W++){var Y=I.order[W],X;if((X=I.match[Y].exec(aa))){var U=RegExp.leftContext;if(U.substr(U.length-1)!=="\\"){X[1]=(X[1]||"").replace(/\\/g,"");Z=I.find[Y](X,T,ab);if(Z!=null){aa=aa.replace(I.match[Y],"");break}}}}if(!Z){Z=T.getElementsByTagName("*")}return{set:Z,expr:aa}};F.filter=function(ad,ac,ag,W){var V=ad,ai=[],aa=ac,Y,T,Z=ac&&ac[0]&&Q(ac[0]);while(ad&&ac.length){for(var ab in I.filter){if((Y=I.match[ab].exec(ad))!=null){var U=I.filter[ab],ah,af;T=false;if(aa==ai){ai=[]}if(I.preFilter[ab]){Y=I.preFilter[ab](Y,aa,ag,ai,W,Z);if(!Y){T=ah=true}else{if(Y===true){continue}}}if(Y){for(var X=0;(af=aa[X])!=null;X++){if(af){ah=U(af,Y,X,aa);var ae=W^!!ah;if(ag&&ah!=null){if(ae){T=true}else{aa[X]=false}}else{if(ae){ai.push(af);T=true}}}}}if(ah!==g){if(!ag){aa=ai}ad=ad.replace(I.match[ab],"");if(!T){return[]}break}}}if(ad==V){if(T==null){throw"Syntax error, unrecognized expression: "+ad}else{break}}V=ad}return aa};var I=F.selectors={order:["ID","NAME","TAG"],match:{ID:/#((?:[\w\u00c0-\uFFFF_-]|\\.)+)/,CLASS:/\.((?:[\w\u00c0-\uFFFF_-]|\\.)+)/,NAME:/\[name=['"]*((?:[\w\u00c0-\uFFFF_-]|\\.)+)['"]*\]/,ATTR:/\[\s*((?:[\w\u00c0-\uFFFF_-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,TAG:/^((?:[\w\u00c0-\uFFFF\*_-]|\\.)+)/,CHILD:/:(only|nth|last|first)-child(?:\((even|odd|[\dn+-]*)\))?/,POS:/:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^-]|$)/,PSEUDO:/:((?:[\w\u00c0-\uFFFF_-]|\\.)+)(?:\((['"]*)((?:\([^\)]+\)|[^\2\(\)]*)+)\2\))?/},attrMap:{"class":"className","for":"htmlFor"},attrHandle:{href:function(T){return T.getAttribute("href")}},relative:{"+":function(aa,T,Z){var X=typeof T==="string",ab=X&&!/\W/.test(T),Y=X&&!ab;if(ab&&!Z){T=T.toUpperCase()}for(var W=0,V=aa.length,U;W<V;W++){if((U=aa[W])){while((U=U.previousSibling)&&U.nodeType!==1){}aa[W]=Y||U&&U.nodeName===T?U||false:U===T}}if(Y){F.filter(T,aa,true)}},">":function(Z,U,aa){var X=typeof U==="string";if(X&&!/\W/.test(U)){U=aa?U:U.toUpperCase();for(var V=0,T=Z.length;V<T;V++){var Y=Z[V];if(Y){var W=Y.parentNode;Z[V]=W.nodeName===U?W:false}}}else{for(var V=0,T=Z.length;V<T;V++){var Y=Z[V];if(Y){Z[V]=X?Y.parentNode:Y.parentNode===U}}if(X){F.filter(U,Z,true)}}},"":function(W,U,Y){var V=L++,T=S;if(!U.match(/\W/)){var X=U=Y?U:U.toUpperCase();T=P}T("parentNode",U,V,W,X,Y)},"~":function(W,U,Y){var V=L++,T=S;if(typeof U==="string"&&!U.match(/\W/)){var X=U=Y?U:U.toUpperCase();T=P}T("previousSibling",U,V,W,X,Y)}},find:{ID:function(U,V,W){if(typeof V.getElementById!=="undefined"&&!W){var T=V.getElementById(U[1]);return T?[T]:[]}},NAME:function(V,Y,Z){if(typeof Y.getElementsByName!=="undefined"){var U=[],X=Y.getElementsByName(V[1]);for(var W=0,T=X.length;W<T;W++){if(X[W].getAttribute("name")===V[1]){U.push(X[W])}}return U.length===0?null:U}},TAG:function(T,U){return U.getElementsByTagName(T[1])}},preFilter:{CLASS:function(W,U,V,T,Z,aa){W=" "+W[1].replace(/\\/g,"")+" ";if(aa){return W}for(var X=0,Y;(Y=U[X])!=null;X++){if(Y){if(Z^(Y.className&&(" "+Y.className+" ").indexOf(W)>=0)){if(!V){T.push(Y)}}else{if(V){U[X]=false}}}}return false},ID:function(T){return T[1].replace(/\\/g,"")},TAG:function(U,T){for(var V=0;T[V]===false;V++){}return T[V]&&Q(T[V])?U[1]:U[1].toUpperCase()},CHILD:function(T){if(T[1]=="nth"){var U=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(T[2]=="even"&&"2n"||T[2]=="odd"&&"2n+1"||!/\D/.test(T[2])&&"0n+"+T[2]||T[2]);T[2]=(U[1]+(U[2]||1))-0;T[3]=U[3]-0}T[0]=L++;return T},ATTR:function(X,U,V,T,Y,Z){var W=X[1].replace(/\\/g,"");if(!Z&&I.attrMap[W]){X[1]=I.attrMap[W]}if(X[2]==="~="){X[4]=" "+X[4]+" "}return X},PSEUDO:function(X,U,V,T,Y){if(X[1]==="not"){if(X[3].match(R).length>1||/^\w/.test(X[3])){X[3]=F(X[3],null,null,U)}else{var W=F.filter(X[3],U,V,true^Y);if(!V){T.push.apply(T,W)}return false}}else{if(I.match.POS.test(X[0])||I.match.CHILD.test(X[0])){return true}}return X},POS:function(T){T.unshift(true);return T}},filters:{enabled:function(T){return T.disabled===false&&T.type!=="hidden"},disabled:function(T){return T.disabled===true},checked:function(T){return T.checked===true},selected:function(T){T.parentNode.selectedIndex;return T.selected===true},parent:function(T){return !!T.firstChild},empty:function(T){return !T.firstChild},has:function(V,U,T){return !!F(T[3],V).length},header:function(T){return/h\d/i.test(T.nodeName)},text:function(T){return"text"===T.type},radio:function(T){return"radio"===T.type},checkbox:function(T){return"checkbox"===T.type},file:function(T){return"file"===T.type},password:function(T){return"password"===T.type},submit:function(T){return"submit"===T.type},image:function(T){return"image"===T.type},reset:function(T){return"reset"===T.type},button:function(T){return"button"===T.type||T.nodeName.toUpperCase()==="BUTTON"},input:function(T){return/input|select|textarea|button/i.test(T.nodeName)}},setFilters:{first:function(U,T){return T===0},last:function(V,U,T,W){return U===W.length-1},even:function(U,T){return T%2===0},odd:function(U,T){return T%2===1},lt:function(V,U,T){return U<T[3]-0},gt:function(V,U,T){return U>T[3]-0},nth:function(V,U,T){return T[3]-0==U},eq:function(V,U,T){return T[3]-0==U}},filter:{PSEUDO:function(Z,V,W,aa){var U=V[1],X=I.filters[U];if(X){return X(Z,W,V,aa)}else{if(U==="contains"){return(Z.textContent||Z.innerText||"").indexOf(V[3])>=0}else{if(U==="not"){var Y=V[3];for(var W=0,T=Y.length;W<T;W++){if(Y[W]===Z){return false}}return true}}}},CHILD:function(T,W){var Z=W[1],U=T;switch(Z){case"only":case"first":while(U=U.previousSibling){if(U.nodeType===1){return false}}if(Z=="first"){return true}U=T;case"last":while(U=U.nextSibling){if(U.nodeType===1){return false}}return true;case"nth":var V=W[2],ac=W[3];if(V==1&&ac==0){return true}var Y=W[0],ab=T.parentNode;if(ab&&(ab.sizcache!==Y||!T.nodeIndex)){var X=0;for(U=ab.firstChild;U;U=U.nextSibling){if(U.nodeType===1){U.nodeIndex=++X}}ab.sizcache=Y}var aa=T.nodeIndex-ac;if(V==0){return aa==0}else{return(aa%V==0&&aa/V>=0)}}},ID:function(U,T){return U.nodeType===1&&U.getAttribute("id")===T},TAG:function(U,T){return(T==="*"&&U.nodeType===1)||U.nodeName===T},CLASS:function(U,T){return(" "+(U.className||U.getAttribute("class"))+" ").indexOf(T)>-1},ATTR:function(Y,W){var V=W[1],T=I.attrHandle[V]?I.attrHandle[V](Y):Y[V]!=null?Y[V]:Y.getAttribute(V),Z=T+"",X=W[2],U=W[4];return T==null?X==="!=":X==="="?Z===U:X==="*="?Z.indexOf(U)>=0:X==="~="?(" "+Z+" ").indexOf(U)>=0:!U?Z&&T!==false:X==="!="?Z!=U:X==="^="?Z.indexOf(U)===0:X==="$="?Z.substr(Z.length-U.length)===U:X==="|="?Z===U||Z.substr(0,U.length+1)===U+"-":false},POS:function(X,U,V,Y){var T=U[2],W=I.setFilters[T];if(W){return W(X,V,U,Y)}}}};var M=I.match.POS;for(var O in I.match){I.match[O]=RegExp(I.match[O].source+/(?![^\[]*\])(?![^\(]*\))/.source)}var E=function(U,T){U=Array.prototype.slice.call(U);if(T){T.push.apply(T,U);return T}return U};try{Array.prototype.slice.call(document.documentElement.childNodes)}catch(N){E=function(X,W){var U=W||[];if(H.call(X)==="[object Array]"){Array.prototype.push.apply(U,X)}else{if(typeof X.length==="number"){for(var V=0,T=X.length;V<T;V++){U.push(X[V])}}else{for(var V=0;X[V];V++){U.push(X[V])}}}return U}}var G;if(document.documentElement.compareDocumentPosition){G=function(U,T){var V=U.compareDocumentPosition(T)&4?-1:U===T?0:1;if(V===0){hasDuplicate=true}return V}}else{if("sourceIndex" in document.documentElement){G=function(U,T){var V=U.sourceIndex-T.sourceIndex;if(V===0){hasDuplicate=true}return V}}else{if(document.createRange){G=function(W,U){var V=W.ownerDocument.createRange(),T=U.ownerDocument.createRange();V.selectNode(W);V.collapse(true);T.selectNode(U);T.collapse(true);var X=V.compareBoundaryPoints(Range.START_TO_END,T);if(X===0){hasDuplicate=true}return X}}}}(function(){var U=document.createElement("form"),V="script"+(new Date).getTime();U.innerHTML="<input name='"+V+"'/>";var T=document.documentElement;T.insertBefore(U,T.firstChild);if(!!document.getElementById(V)){I.find.ID=function(X,Y,Z){if(typeof Y.getElementById!=="undefined"&&!Z){var W=Y.getElementById(X[1]);return W?W.id===X[1]||typeof W.getAttributeNode!=="undefined"&&W.getAttributeNode("id").nodeValue===X[1]?[W]:g:[]}};I.filter.ID=function(Y,W){var X=typeof Y.getAttributeNode!=="undefined"&&Y.getAttributeNode("id");return Y.nodeType===1&&X&&X.nodeValue===W}}T.removeChild(U)})();(function(){var T=document.createElement("div");T.appendChild(document.createComment(""));if(T.getElementsByTagName("*").length>0){I.find.TAG=function(U,Y){var X=Y.getElementsByTagName(U[1]);if(U[1]==="*"){var W=[];for(var V=0;X[V];V++){if(X[V].nodeType===1){W.push(X[V])}}X=W}return X}}T.innerHTML="<a href='#'></a>";if(T.firstChild&&typeof T.firstChild.getAttribute!=="undefined"&&T.firstChild.getAttribute("href")!=="#"){I.attrHandle.href=function(U){return U.getAttribute("href",2)}}})();if(document.querySelectorAll){(function(){var T=F,U=document.createElement("div");U.innerHTML="<p class='TEST'></p>";if(U.querySelectorAll&&U.querySelectorAll(".TEST").length===0){return}F=function(Y,X,V,W){X=X||document;if(!W&&X.nodeType===9&&!Q(X)){try{return E(X.querySelectorAll(Y),V)}catch(Z){}}return T(Y,X,V,W)};F.find=T.find;F.filter=T.filter;F.selectors=T.selectors;F.matches=T.matches})()}if(document.getElementsByClassName&&document.documentElement.getElementsByClassName){(function(){var T=document.createElement("div");T.innerHTML="<div class='test e'></div><div class='test'></div>";if(T.getElementsByClassName("e").length===0){return}T.lastChild.className="e";if(T.getElementsByClassName("e").length===1){return}I.order.splice(1,0,"CLASS");I.find.CLASS=function(U,V,W){if(typeof V.getElementsByClassName!=="undefined"&&!W){return V.getElementsByClassName(U[1])}}})()}function P(U,Z,Y,ad,aa,ac){var ab=U=="previousSibling"&&!ac;for(var W=0,V=ad.length;W<V;W++){var T=ad[W];if(T){if(ab&&T.nodeType===1){T.sizcache=Y;T.sizset=W}T=T[U];var X=false;while(T){if(T.sizcache===Y){X=ad[T.sizset];break}if(T.nodeType===1&&!ac){T.sizcache=Y;T.sizset=W}if(T.nodeName===Z){X=T;break}T=T[U]}ad[W]=X}}}function S(U,Z,Y,ad,aa,ac){var ab=U=="previousSibling"&&!ac;for(var W=0,V=ad.length;W<V;W++){var T=ad[W];if(T){if(ab&&T.nodeType===1){T.sizcache=Y;T.sizset=W}T=T[U];var X=false;while(T){if(T.sizcache===Y){X=ad[T.sizset];break}if(T.nodeType===1){if(!ac){T.sizcache=Y;T.sizset=W}if(typeof Z!=="string"){if(T===Z){X=true;break}}else{if(F.filter(Z,[T]).length>0){X=T;break}}}T=T[U]}ad[W]=X}}}var K=document.compareDocumentPosition?function(U,T){return U.compareDocumentPosition(T)&16}:function(U,T){return U!==T&&(U.contains?U.contains(T):true)};var Q=function(T){return T.nodeType===9&&T.documentElement.nodeName!=="HTML"||!!T.ownerDocument&&Q(T.ownerDocument)};var J=function(T,aa){var W=[],X="",Y,V=aa.nodeType?[aa]:aa;while((Y=I.match.PSEUDO.exec(T))){X+=Y[0];T=T.replace(I.match.PSEUDO,"")}T=I.relative[T]?T+"*":T;for(var Z=0,U=V.length;Z<U;Z++){F(T,V[Z],W)}return F.filter(X,W)};o.find=F;o.filter=F.filter;o.expr=F.selectors;o.expr[":"]=o.expr.filters;F.selectors.filters.hidden=function(T){return T.offsetWidth===0||T.offsetHeight===0};F.selectors.filters.visible=function(T){return T.offsetWidth>0||T.offsetHeight>0};F.selectors.filters.animated=function(T){return o.grep(o.timers,function(U){return T===U.elem}).length};o.multiFilter=function(V,T,U){if(U){V=":not("+V+")"}return F.matches(V,T)};o.dir=function(V,U){var T=[],W=V[U];while(W&&W!=document){if(W.nodeType==1){T.push(W)}W=W[U]}return T};o.nth=function(X,T,V,W){T=T||1;var U=0;for(;X;X=X[V]){if(X.nodeType==1&&++U==T){break}}return X};o.sibling=function(V,U){var T=[];for(;V;V=V.nextSibling){if(V.nodeType==1&&V!=U){T.push(V)}}return T};return;l.Sizzle=F})();o.event={add:function(I,F,H,K){if(I.nodeType==3||I.nodeType==8){return}if(I.setInterval&&I!=l){I=l}if(!H.guid){H.guid=this.guid++}if(K!==g){var G=H;H=this.proxy(G);H.data=K}var E=o.data(I,"events")||o.data(I,"events",{}),J=o.data(I,"handle")||o.data(I,"handle",function(){return typeof o!=="undefined"&&!o.event.triggered?o.event.handle.apply(arguments.callee.elem,arguments):g});J.elem=I;o.each(F.split(/\s+/),function(M,N){var O=N.split(".");N=O.shift();H.type=O.slice().sort().join(".");var L=E[N];if(o.event.specialAll[N]){o.event.specialAll[N].setup.call(I,K,O)}if(!L){L=E[N]={};if(!o.event.special[N]||o.event.special[N].setup.call(I,K,O)===false){if(I.addEventListener){I.addEventListener(N,J,false)}else{if(I.attachEvent){I.attachEvent("on"+N,J)}}}}L[H.guid]=H;o.event.global[N]=true});I=null},guid:1,global:{},remove:function(K,H,J){if(K.nodeType==3||K.nodeType==8){return}var G=o.data(K,"events"),F,E;if(G){if(H===g||(typeof H==="string"&&H.charAt(0)==".")){for(var I in G){this.remove(K,I+(H||""))}}else{if(H.type){J=H.handler;H=H.type}o.each(H.split(/\s+/),function(M,O){var Q=O.split(".");O=Q.shift();var N=RegExp("(^|\\.)"+Q.slice().sort().join(".*\\.")+"(\\.|$)");if(G[O]){if(J){delete G[O][J.guid]}else{for(var P in G[O]){if(N.test(G[O][P].type)){delete G[O][P]}}}if(o.event.specialAll[O]){o.event.specialAll[O].teardown.call(K,Q)}for(F in G[O]){break}if(!F){if(!o.event.special[O]||o.event.special[O].teardown.call(K,Q)===false){if(K.removeEventListener){K.removeEventListener(O,o.data(K,"handle"),false)}else{if(K.detachEvent){K.detachEvent("on"+O,o.data(K,"handle"))}}}F=null;delete G[O]}}})}for(F in G){break}if(!F){var L=o.data(K,"handle");if(L){L.elem=null}o.removeData(K,"events");o.removeData(K,"handle")}}},trigger:function(I,K,H,E){var G=I.type||I;if(!E){I=typeof I==="object"?I[h]?I:o.extend(o.Event(G),I):o.Event(G);if(G.indexOf("!")>=0){I.type=G=G.slice(0,-1);I.exclusive=true}if(!H){I.stopPropagation();if(this.global[G]){o.each(o.cache,function(){if(this.events&&this.events[G]){o.event.trigger(I,K,this.handle.elem)}})}}if(!H||H.nodeType==3||H.nodeType==8){return g}I.result=g;I.target=H;K=o.makeArray(K);K.unshift(I)}I.currentTarget=H;var J=o.data(H,"handle");if(J){J.apply(H,K)}if((!H[G]||(o.nodeName(H,"a")&&G=="click"))&&H["on"+G]&&H["on"+G].apply(H,K)===false){I.result=false}if(!E&&H[G]&&!I.isDefaultPrevented()&&!(o.nodeName(H,"a")&&G=="click")){this.triggered=true;try{H[G]()}catch(L){}}this.triggered=false;if(!I.isPropagationStopped()){var F=H.parentNode||H.ownerDocument;if(F){o.event.trigger(I,K,F,true)}}},handle:function(K){var J,E;K=arguments[0]=o.event.fix(K||l.event);K.currentTarget=this;var L=K.type.split(".");K.type=L.shift();J=!L.length&&!K.exclusive;var I=RegExp("(^|\\.)"+L.slice().sort().join(".*\\.")+"(\\.|$)");E=(o.data(this,"events")||{})[K.type];for(var G in E){var H=E[G];if(J||I.test(H.type)){K.handler=H;K.data=H.data;var F=H.apply(this,arguments);if(F!==g){K.result=F;if(F===false){K.preventDefault();K.stopPropagation()}}if(K.isImmediatePropagationStopped()){break}}}},props:"altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode metaKey newValue originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),fix:function(H){if(H[h]){return H}var F=H;H=o.Event(F);for(var G=this.props.length,J;G;){J=this.props[--G];H[J]=F[J]}if(!H.target){H.target=H.srcElement||document}if(H.target.nodeType==3){H.target=H.target.parentNode}if(!H.relatedTarget&&H.fromElement){H.relatedTarget=H.fromElement==H.target?H.toElement:H.fromElement}if(H.pageX==null&&H.clientX!=null){var I=document.documentElement,E=document.body;H.pageX=H.clientX+(I&&I.scrollLeft||E&&E.scrollLeft||0)-(I.clientLeft||0);H.pageY=H.clientY+(I&&I.scrollTop||E&&E.scrollTop||0)-(I.clientTop||0)}if(!H.which&&((H.charCode||H.charCode===0)?H.charCode:H.keyCode)){H.which=H.charCode||H.keyCode}if(!H.metaKey&&H.ctrlKey){H.metaKey=H.ctrlKey}if(!H.which&&H.button){H.which=(H.button&1?1:(H.button&2?3:(H.button&4?2:0)))}return H},proxy:function(F,E){E=E||function(){return F.apply(this,arguments)};E.guid=F.guid=F.guid||E.guid||this.guid++;return E},special:{ready:{setup:B,teardown:function(){}}},specialAll:{live:{setup:function(E,F){o.event.add(this,F[0],c)},teardown:function(G){if(G.length){var E=0,F=RegExp("(^|\\.)"+G[0]+"(\\.|$)");o.each((o.data(this,"events").live||{}),function(){if(F.test(this.type)){E++}});if(E<1){o.event.remove(this,G[0],c)}}}}}};o.Event=function(E){if(!this.preventDefault){return new o.Event(E)}if(E&&E.type){this.originalEvent=E;this.type=E.type}else{this.type=E}this.timeStamp=e();this[h]=true};function k(){return false}function u(){return true}o.Event.prototype={preventDefault:function(){this.isDefaultPrevented=u;var E=this.originalEvent;if(!E){return}if(E.preventDefault){E.preventDefault()}E.returnValue=false},stopPropagation:function(){this.isPropagationStopped=u;var E=this.originalEvent;if(!E){return}if(E.stopPropagation){E.stopPropagation()}E.cancelBubble=true},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=u;this.stopPropagation()},isDefaultPrevented:k,isPropagationStopped:k,isImmediatePropagationStopped:k};var a=function(F){var E=F.relatedTarget;while(E&&E!=this){try{E=E.parentNode}catch(G){E=this}}if(E!=this){F.type=F.data;o.event.handle.apply(this,arguments)}};o.each({mouseover:"mouseenter",mouseout:"mouseleave"},function(F,E){o.event.special[E]={setup:function(){o.event.add(this,F,a,E)},teardown:function(){o.event.remove(this,F,a)}}});o.fn.extend({bind:function(F,G,E){return F=="unload"?this.one(F,G,E):this.each(function(){o.event.add(this,F,E||G,E&&G)})},one:function(G,H,F){var E=o.event.proxy(F||H,function(I){o(this).unbind(I,E);return(F||H).apply(this,arguments)});return this.each(function(){o.event.add(this,G,E,F&&H)})},unbind:function(F,E){return this.each(function(){o.event.remove(this,F,E)})},trigger:function(E,F){return this.each(function(){o.event.trigger(E,F,this)})},triggerHandler:function(E,G){if(this[0]){var F=o.Event(E);F.preventDefault();F.stopPropagation();o.event.trigger(F,G,this[0]);return F.result}},toggle:function(G){var E=arguments,F=1;while(F<E.length){o.event.proxy(G,E[F++])}return this.click(o.event.proxy(G,function(H){this.lastToggle=(this.lastToggle||0)%F;H.preventDefault();return E[this.lastToggle++].apply(this,arguments)||false}))},hover:function(E,F){return this.mouseenter(E).mouseleave(F)},ready:function(E){B();if(o.isReady){E.call(document,o)}else{o.readyList.push(E)}return this},live:function(G,F){var E=o.event.proxy(F);E.guid+=this.selector+G;o(document).bind(i(G,this.selector),this.selector,E);return this},die:function(F,E){o(document).unbind(i(F,this.selector),E?{guid:E.guid+this.selector+F}:null);return this}});function c(H){var E=RegExp("(^|\\.)"+H.type+"(\\.|$)"),G=true,F=[];o.each(o.data(this,"events").live||[],function(I,J){if(E.test(J.type)){var K=o(H.target).closest(J.data)[0];if(K){F.push({elem:K,fn:J})}}});F.sort(function(J,I){return o.data(J.elem,"closest")-o.data(I.elem,"closest")});o.each(F,function(){if(this.fn.call(this.elem,H,this.fn.data)===false){return(G=false)}});return G}function i(F,E){return["live",F,E.replace(/\./g,"`").replace(/ /g,"|")].join(".")}o.extend({isReady:false,readyList:[],ready:function(){if(!o.isReady){o.isReady=true;if(o.readyList){o.each(o.readyList,function(){this.call(document,o)});o.readyList=null}o(document).triggerHandler("ready")}}});var x=false;function B(){if(x){return}x=true;if(document.addEventListener){document.addEventListener("DOMContentLoaded",function(){document.removeEventListener("DOMContentLoaded",arguments.callee,false);o.ready()},false)}else{if(document.attachEvent){document.attachEvent("onreadystatechange",function(){if(document.readyState==="complete"){document.detachEvent("onreadystatechange",arguments.callee);o.ready()}});if(document.documentElement.doScroll&&l==l.top){(function(){if(o.isReady){return}try{document.documentElement.doScroll("left")}catch(E){setTimeout(arguments.callee,0);return}o.ready()})()}}}o.event.add(l,"load",o.ready)}o.each(("blur,focus,load,resize,scroll,unload,click,dblclick,mousedown,mouseup,mousemove,mouseover,mouseout,mouseenter,mouseleave,change,select,submit,keydown,keypress,keyup,error").split(","),function(F,E){o.fn[E]=function(G){return G?this.bind(E,G):this.trigger(E)}});o(l).bind("unload",function(){for(var E in o.cache){if(E!=1&&o.cache[E].handle){o.event.remove(o.cache[E].handle.elem)}}});(function(){o.support={};var F=document.documentElement,G=document.createElement("script"),K=document.createElement("div"),J="script"+(new Date).getTime();K.style.display="none";K.innerHTML=' <link/><table></table><a href="/a" style="color:red;float:left;opacity:.5;">a</a><select><option>text</option></select><object><param/></object>';var H=K.getElementsByTagName("*"),E=K.getElementsByTagName("a")[0];if(!H||!H.length||!E){return}o.support={leadingWhitespace:K.firstChild.nodeType==3,tbody:!K.getElementsByTagName("tbody").length,objectAll:!!K.getElementsByTagName("object")[0].getElementsByTagName("*").length,htmlSerialize:!!K.getElementsByTagName("link").length,style:/red/.test(E.getAttribute("style")),hrefNormalized:E.getAttribute("href")==="/a",opacity:E.style.opacity==="0.5",cssFloat:!!E.style.cssFloat,scriptEval:false,noCloneEvent:true,boxModel:null};G.type="text/javascript";try{G.appendChild(document.createTextNode("window."+J+"=1;"))}catch(I){}F.insertBefore(G,F.firstChild);if(l[J]){o.support.scriptEval=true;delete l[J]}F.removeChild(G);if(K.attachEvent&&K.fireEvent){K.attachEvent("onclick",function(){o.support.noCloneEvent=false;K.detachEvent("onclick",arguments.callee)});K.cloneNode(true).fireEvent("onclick")}o(function(){var L=document.createElement("div");L.style.width=L.style.paddingLeft="1px";document.body.appendChild(L);o.boxModel=o.support.boxModel=L.offsetWidth===2;document.body.removeChild(L).style.display="none"})})();var w=o.support.cssFloat?"cssFloat":"styleFloat";o.props={"for":"htmlFor","class":"className","float":w,cssFloat:w,styleFloat:w,readonly:"readOnly",maxlength:"maxLength",cellspacing:"cellSpacing",rowspan:"rowSpan",tabindex:"tabIndex"};o.fn.extend({_load:o.fn.load,load:function(G,J,K){if(typeof G!=="string"){return this._load(G)}var I=G.indexOf(" ");if(I>=0){var E=G.slice(I,G.length);G=G.slice(0,I)}var H="GET";if(J){if(o.isFunction(J)){K=J;J=null}else{if(typeof J==="object"){J=o.param(J);H="POST"}}}var F=this;o.ajax({url:G,type:H,dataType:"html",data:J,complete:function(M,L){if(L=="success"||L=="notmodified"){F.html(E?o("<div/>").append(M.responseText.replace(/<script(.|\s)*?\/script>/g,"")).find(E):M.responseText)}if(K){F.each(K,[M.responseText,L,M])}}});return this},serialize:function(){return o.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?o.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||/select|textarea/i.test(this.nodeName)||/text|hidden|password|search/i.test(this.type))}).map(function(E,F){var G=o(this).val();return G==null?null:o.isArray(G)?o.map(G,function(I,H){return{name:F.name,value:I}}):{name:F.name,value:G}}).get()}});o.each("ajaxStart,ajaxStop,ajaxComplete,ajaxError,ajaxSuccess,ajaxSend".split(","),function(E,F){o.fn[F]=function(G){return this.bind(F,G)}});var r=e();o.extend({get:function(E,G,H,F){if(o.isFunction(G)){H=G;G=null}return o.ajax({type:"GET",url:E,data:G,success:H,dataType:F})},getScript:function(E,F){return o.get(E,null,F,"script")},getJSON:function(E,F,G){return o.get(E,F,G,"json")},post:function(E,G,H,F){if(o.isFunction(G)){H=G;G={}}return o.ajax({type:"POST",url:E,data:G,success:H,dataType:F})},ajaxSetup:function(E){o.extend(o.ajaxSettings,E)},ajaxSettings:{url:location.href,global:true,type:"GET",contentType:"application/x-www-form-urlencoded",processData:true,async:true,xhr:function(){return l.ActiveXObject?new ActiveXObject("Microsoft.XMLHTTP"):new XMLHttpRequest()},accepts:{xml:"application/xml, text/xml",html:"text/html",script:"text/javascript, application/javascript",json:"application/json, text/javascript",text:"text/plain",_default:"*/*"}},lastModified:{},ajax:function(M){M=o.extend(true,M,o.extend(true,{},o.ajaxSettings,M));var W,F=/=\?(&|$)/g,R,V,G=M.type.toUpperCase();if(M.data&&M.processData&&typeof M.data!=="string"){M.data=o.param(M.data)}if(M.dataType=="jsonp"){if(G=="GET"){if(!M.url.match(F)){M.url+=(M.url.match(/\?/)?"&":"?")+(M.jsonp||"callback")+"=?"}}else{if(!M.data||!M.data.match(F)){M.data=(M.data?M.data+"&":"")+(M.jsonp||"callback")+"=?"}}M.dataType="json"}if(M.dataType=="json"&&(M.data&&M.data.match(F)||M.url.match(F))){W="jsonp"+r++;if(M.data){M.data=(M.data+"").replace(F,"="+W+"$1")}M.url=M.url.replace(F,"="+W+"$1");M.dataType="script";l[W]=function(X){V=X;I();L();l[W]=g;try{delete l[W]}catch(Y){}if(H){H.removeChild(T)}}}if(M.dataType=="script"&&M.cache==null){M.cache=false}if(M.cache===false&&G=="GET"){var E=e();var U=M.url.replace(/(\?|&)_=.*?(&|$)/,"$1_="+E+"$2");M.url=U+((U==M.url)?(M.url.match(/\?/)?"&":"?")+"_="+E:"")}if(M.data&&G=="GET"){M.url+=(M.url.match(/\?/)?"&":"?")+M.data;M.data=null}if(M.global&&!o.active++){o.event.trigger("ajaxStart")}var Q=/^(\w+:)?\/\/([^\/?#]+)/.exec(M.url);if(M.dataType=="script"&&G=="GET"&&Q&&(Q[1]&&Q[1]!=location.protocol||Q[2]!=location.host)){var H=document.getElementsByTagName("head")[0];var T=document.createElement("script");T.src=M.url;if(M.scriptCharset){T.charset=M.scriptCharset}if(!W){var O=false;T.onload=T.onreadystatechange=function(){if(!O&&(!this.readyState||this.readyState=="loaded"||this.readyState=="complete")){O=true;I();L();T.onload=T.onreadystatechange=null;H.removeChild(T)}}}H.appendChild(T);return g}var K=false;var J=M.xhr();if(M.username){J.open(G,M.url,M.async,M.username,M.password)}else{J.open(G,M.url,M.async)}try{if(M.data){J.setRequestHeader("Content-Type",M.contentType)}if(M.ifModified){J.setRequestHeader("If-Modified-Since",o.lastModified[M.url]||"Thu, 01 Jan 1970 00:00:00 GMT")}J.setRequestHeader("X-Requested-With","XMLHttpRequest");J.setRequestHeader("Accept",M.dataType&&M.accepts[M.dataType]?M.accepts[M.dataType]+", */*":M.accepts._default)}catch(S){}if(M.beforeSend&&M.beforeSend(J,M)===false){if(M.global&&!--o.active){o.event.trigger("ajaxStop")}J.abort();return false}if(M.global){o.event.trigger("ajaxSend",[J,M])}var N=function(X){if(J.readyState==0){if(P){clearInterval(P);P=null;if(M.global&&!--o.active){o.event.trigger("ajaxStop")}}}else{if(!K&&J&&(J.readyState==4||X=="timeout")){K=true;if(P){clearInterval(P);P=null}R=X=="timeout"?"timeout":!o.httpSuccess(J)?"error":M.ifModified&&o.httpNotModified(J,M.url)?"notmodified":"success";if(R=="success"){try{V=o.httpData(J,M.dataType,M)}catch(Z){R="parsererror"}}if(R=="success"){var Y;try{Y=J.getResponseHeader("Last-Modified")}catch(Z){}if(M.ifModified&&Y){o.lastModified[M.url]=Y}if(!W){I()}}else{o.handleError(M,J,R)}L();if(X){J.abort()}if(M.async){J=null}}}};if(M.async){var P=setInterval(N,13);if(M.timeout>0){setTimeout(function(){if(J&&!K){N("timeout")}},M.timeout)}}try{J.send(M.data)}catch(S){o.handleError(M,J,null,S)}if(!M.async){N()}function I(){if(M.success){M.success(V,R)}if(M.global){o.event.trigger("ajaxSuccess",[J,M])}}function L(){if(M.complete){M.complete(J,R)}if(M.global){o.event.trigger("ajaxComplete",[J,M])}if(M.global&&!--o.active){o.event.trigger("ajaxStop")}}return J},handleError:function(F,H,E,G){if(F.error){F.error(H,E,G)}if(F.global){o.event.trigger("ajaxError",[H,F,G])}},active:0,httpSuccess:function(F){try{return !F.status&&location.protocol=="file:"||(F.status>=200&&F.status<300)||F.status==304||F.status==1223}catch(E){}return false},httpNotModified:function(G,E){try{var H=G.getResponseHeader("Last-Modified");return G.status==304||H==o.lastModified[E]}catch(F){}return false},httpData:function(J,H,G){var F=J.getResponseHeader("content-type"),E=H=="xml"||!H&&F&&F.indexOf("xml")>=0,I=E?J.responseXML:J.responseText;if(E&&I.documentElement.tagName=="parsererror"){throw"parsererror"}if(G&&G.dataFilter){I=G.dataFilter(I,H)}if(typeof I==="string"){if(H=="script"){o.globalEval(I)}if(H=="json"){I=l["eval"]("("+I+")")}}return I},param:function(E){var G=[];function H(I,J){G[G.length]=encodeURIComponent(I)+"="+encodeURIComponent(J)}if(o.isArray(E)||E.jquery){o.each(E,function(){H(this.name,this.value)})}else{for(var F in E){if(o.isArray(E[F])){o.each(E[F],function(){H(F,this)})}else{H(F,o.isFunction(E[F])?E[F]():E[F])}}}return G.join("&").replace(/%20/g,"+")}});var m={},n,d=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]];function t(F,E){var G={};o.each(d.concat.apply([],d.slice(0,E)),function(){G[this]=F});return G}o.fn.extend({show:function(J,L){if(J){return this.animate(t("show",3),J,L)}else{for(var H=0,F=this.length;H<F;H++){var E=o.data(this[H],"olddisplay");this[H].style.display=E||"";if(o.css(this[H],"display")==="none"){var G=this[H].tagName,K;if(m[G]){K=m[G]}else{var I=o("<"+G+" />").appendTo("body");K=I.css("display");if(K==="none"){K="block"}I.remove();m[G]=K}o.data(this[H],"olddisplay",K)}}for(var H=0,F=this.length;H<F;H++){this[H].style.display=o.data(this[H],"olddisplay")||""}return this}},hide:function(H,I){if(H){return this.animate(t("hide",3),H,I)}else{for(var G=0,F=this.length;G<F;G++){var E=o.data(this[G],"olddisplay");if(!E&&E!=="none"){o.data(this[G],"olddisplay",o.css(this[G],"display"))}}for(var G=0,F=this.length;G<F;G++){this[G].style.display="none"}return this}},_toggle:o.fn.toggle,toggle:function(G,F){var E=typeof G==="boolean";return o.isFunction(G)&&o.isFunction(F)?this._toggle.apply(this,arguments):G==null||E?this.each(function(){var H=E?G:o(this).is(":hidden");o(this)[H?"show":"hide"]()}):this.animate(t("toggle",3),G,F)},fadeTo:function(E,G,F){return this.animate({opacity:G},E,F)},animate:function(I,F,H,G){var E=o.speed(F,H,G);return this[E.queue===false?"each":"queue"](function(){var K=o.extend({},E),M,L=this.nodeType==1&&o(this).is(":hidden"),J=this;for(M in I){if(I[M]=="hide"&&L||I[M]=="show"&&!L){return K.complete.call(this)}if((M=="height"||M=="width")&&this.style){K.display=o.css(this,"display");K.overflow=this.style.overflow}}if(K.overflow!=null){this.style.overflow="hidden"}K.curAnim=o.extend({},I);o.each(I,function(O,S){var R=new o.fx(J,K,O);if(/toggle|show|hide/.test(S)){R[S=="toggle"?L?"show":"hide":S](I)}else{var Q=S.toString().match(/^([+-]=)?([\d+-.]+)(.*)$/),T=R.cur(true)||0;if(Q){var N=parseFloat(Q[2]),P=Q[3]||"px";if(P!="px"){J.style[O]=(N||1)+P;T=((N||1)/R.cur(true))*T;J.style[O]=T+P}if(Q[1]){N=((Q[1]=="-="?-1:1)*N)+T}R.custom(T,N,P)}else{R.custom(T,S,"")}}});return true})},stop:function(F,E){var G=o.timers;if(F){this.queue([])}this.each(function(){for(var H=G.length-1;H>=0;H--){if(G[H].elem==this){if(E){G[H](true)}G.splice(H,1)}}});if(!E){this.dequeue()}return this}});o.each({slideDown:t("show",1),slideUp:t("hide",1),slideToggle:t("toggle",1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"}},function(E,F){o.fn[E]=function(G,H){return this.animate(F,G,H)}});o.extend({speed:function(G,H,F){var E=typeof G==="object"?G:{complete:F||!F&&H||o.isFunction(G)&&G,duration:G,easing:F&&H||H&&!o.isFunction(H)&&H};E.duration=o.fx.off?0:typeof E.duration==="number"?E.duration:o.fx.speeds[E.duration]||o.fx.speeds._default;E.old=E.complete;E.complete=function(){if(E.queue!==false){o(this).dequeue()}if(o.isFunction(E.old)){E.old.call(this)}};return E},easing:{linear:function(G,H,E,F){return E+F*G},swing:function(G,H,E,F){return((-Math.cos(G*Math.PI)/2)+0.5)*F+E}},timers:[],fx:function(F,E,G){this.options=E;this.elem=F;this.prop=G;if(!E.orig){E.orig={}}}});o.fx.prototype={update:function(){if(this.options.step){this.options.step.call(this.elem,this.now,this)}(o.fx.step[this.prop]||o.fx.step._default)(this);if((this.prop=="height"||this.prop=="width")&&this.elem.style){this.elem.style.display="block"}},cur:function(F){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==null)){return this.elem[this.prop]}var E=parseFloat(o.css(this.elem,this.prop,F));return E&&E>-10000?E:parseFloat(o.curCSS(this.elem,this.prop))||0},custom:function(I,H,G){this.startTime=e();this.start=I;this.end=H;this.unit=G||this.unit||"px";this.now=this.start;this.pos=this.state=0;var E=this;function F(J){return E.step(J)}F.elem=this.elem;if(F()&&o.timers.push(F)&&!n){n=setInterval(function(){var K=o.timers;for(var J=0;J<K.length;J++){if(!K[J]()){K.splice(J--,1)}}if(!K.length){clearInterval(n);n=g}},13)}},show:function(){this.options.orig[this.prop]=o.attr(this.elem.style,this.prop);this.options.show=true;this.custom(this.prop=="width"||this.prop=="height"?1:0,this.cur());o(this.elem).show()},hide:function(){this.options.orig[this.prop]=o.attr(this.elem.style,this.prop);this.options.hide=true;this.custom(this.cur(),0)},step:function(H){var G=e();if(H||G>=this.options.duration+this.startTime){this.now=this.end;this.pos=this.state=1;this.update();this.options.curAnim[this.prop]=true;var E=true;for(var F in this.options.curAnim){if(this.options.curAnim[F]!==true){E=false}}if(E){if(this.options.display!=null){this.elem.style.overflow=this.options.overflow;this.elem.style.display=this.options.display;if(o.css(this.elem,"display")=="none"){this.elem.style.display="block"}}if(this.options.hide){o(this.elem).hide()}if(this.options.hide||this.options.show){for(var I in this.options.curAnim){o.attr(this.elem.style,I,this.options.orig[I])}}this.options.complete.call(this.elem)}return false}else{var J=G-this.startTime;this.state=J/this.options.duration;this.pos=o.easing[this.options.easing||(o.easing.swing?"swing":"linear")](this.state,J,0,1,this.options.duration);this.now=this.start+((this.end-this.start)*this.pos);this.update()}return true}};o.extend(o.fx,{speeds:{slow:600,fast:200,_default:400},step:{opacity:function(E){o.attr(E.elem.style,"opacity",E.now)},_default:function(E){if(E.elem.style&&E.elem.style[E.prop]!=null){E.elem.style[E.prop]=E.now+E.unit}else{E.elem[E.prop]=E.now}}}});if(document.documentElement.getBoundingClientRect){o.fn.offset=function(){if(!this[0]){return{top:0,left:0}}if(this[0]===this[0].ownerDocument.body){return o.offset.bodyOffset(this[0])}var G=this[0].getBoundingClientRect(),J=this[0].ownerDocument,F=J.body,E=J.documentElement,L=E.clientTop||F.clientTop||0,K=E.clientLeft||F.clientLeft||0,I=G.top+(self.pageYOffset||o.boxModel&&E.scrollTop||F.scrollTop)-L,H=G.left+(self.pageXOffset||o.boxModel&&E.scrollLeft||F.scrollLeft)-K;return{top:I,left:H}}}else{o.fn.offset=function(){if(!this[0]){return{top:0,left:0}}if(this[0]===this[0].ownerDocument.body){return o.offset.bodyOffset(this[0])}o.offset.initialized||o.offset.initialize();var J=this[0],G=J.offsetParent,F=J,O=J.ownerDocument,M,H=O.documentElement,K=O.body,L=O.defaultView,E=L.getComputedStyle(J,null),N=J.offsetTop,I=J.offsetLeft;while((J=J.parentNode)&&J!==K&&J!==H){M=L.getComputedStyle(J,null);N-=J.scrollTop,I-=J.scrollLeft;if(J===G){N+=J.offsetTop,I+=J.offsetLeft;if(o.offset.doesNotAddBorder&&!(o.offset.doesAddBorderForTableAndCells&&/^t(able|d|h)$/i.test(J.tagName))){N+=parseInt(M.borderTopWidth,10)||0,I+=parseInt(M.borderLeftWidth,10)||0}F=G,G=J.offsetParent}if(o.offset.subtractsBorderForOverflowNotVisible&&M.overflow!=="visible"){N+=parseInt(M.borderTopWidth,10)||0,I+=parseInt(M.borderLeftWidth,10)||0}E=M}if(E.position==="relative"||E.position==="static"){N+=K.offsetTop,I+=K.offsetLeft}if(E.position==="fixed"){N+=Math.max(H.scrollTop,K.scrollTop),I+=Math.max(H.scrollLeft,K.scrollLeft)}return{top:N,left:I}}}o.offset={initialize:function(){if(this.initialized){return}var L=document.body,F=document.createElement("div"),H,G,N,I,M,E,J=L.style.marginTop,K='<div style="position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;"><div></div></div><table style="position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;" cellpadding="0" cellspacing="0"><tr><td></td></tr></table>';M={position:"absolute",top:0,left:0,margin:0,border:0,width:"1px",height:"1px",visibility:"hidden"};for(E in M){F.style[E]=M[E]}F.innerHTML=K;L.insertBefore(F,L.firstChild);H=F.firstChild,G=H.firstChild,I=H.nextSibling.firstChild.firstChild;this.doesNotAddBorder=(G.offsetTop!==5);this.doesAddBorderForTableAndCells=(I.offsetTop===5);H.style.overflow="hidden",H.style.position="relative";this.subtractsBorderForOverflowNotVisible=(G.offsetTop===-5);L.style.marginTop="1px";this.doesNotIncludeMarginInBodyOffset=(L.offsetTop===0);L.style.marginTop=J;L.removeChild(F);this.initialized=true},bodyOffset:function(E){o.offset.initialized||o.offset.initialize();var G=E.offsetTop,F=E.offsetLeft;if(o.offset.doesNotIncludeMarginInBodyOffset){G+=parseInt(o.curCSS(E,"marginTop",true),10)||0,F+=parseInt(o.curCSS(E,"marginLeft",true),10)||0}return{top:G,left:F}}};o.fn.extend({position:function(){var I=0,H=0,F;if(this[0]){var G=this.offsetParent(),J=this.offset(),E=/^body|html$/i.test(G[0].tagName)?{top:0,left:0}:G.offset();J.top-=j(this,"marginTop");J.left-=j(this,"marginLeft");E.top+=j(G,"borderTopWidth");E.left+=j(G,"borderLeftWidth");F={top:J.top-E.top,left:J.left-E.left}}return F},offsetParent:function(){var E=this[0].offsetParent||document.body;while(E&&(!/^body|html$/i.test(E.tagName)&&o.css(E,"position")=="static")){E=E.offsetParent}return o(E)}});o.each(["Left","Top"],function(F,E){var G="scroll"+E;o.fn[G]=function(H){if(!this[0]){return null}return H!==g?this.each(function(){this==l||this==document?l.scrollTo(!F?H:o(l).scrollLeft(),F?H:o(l).scrollTop()):this[G]=H}):this[0]==l||this[0]==document?self[F?"pageYOffset":"pageXOffset"]||o.boxModel&&document.documentElement[G]||document.body[G]:this[0][G]}});o.each(["Height","Width"],function(I,G){var E=I?"Left":"Top",H=I?"Right":"Bottom",F=G.toLowerCase();o.fn["inner"+G]=function(){return this[0]?o.css(this[0],F,false,"padding"):null};o.fn["outer"+G]=function(K){return this[0]?o.css(this[0],F,false,K?"margin":"border"):null};var J=G.toLowerCase();o.fn[J]=function(K){return this[0]==l?document.compatMode=="CSS1Compat"&&document.documentElement["client"+G]||document.body["client"+G]:this[0]==document?Math.max(document.documentElement["client"+G],document.body["scroll"+G],document.documentElement["scroll"+G],document.body["offset"+G],document.documentElement["offset"+G]):K===g?(this.length?o.css(this[0],J):null):this.css(J,typeof K==="string"?K:K+"px")}})})(); \ No newline at end of file
diff --git a/site/app/webroot/js/jquery-ui/GPL-LICENSE.txt b/site/app/webroot/js/jquery-ui/GPL-LICENSE.txt
new file mode 100644
index 0000000..11dddd0
--- /dev/null
+++ b/site/app/webroot/js/jquery-ui/GPL-LICENSE.txt
@@ -0,0 +1,278 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Lesser General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
diff --git a/site/app/webroot/js/jquery-ui/MIT-LICENSE.txt b/site/app/webroot/js/jquery-ui/MIT-LICENSE.txt
new file mode 100644
index 0000000..965a831
--- /dev/null
+++ b/site/app/webroot/js/jquery-ui/MIT-LICENSE.txt
@@ -0,0 +1,20 @@
+Copyright (c) 2007 John Resig, http://jquery.com/
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/site/app/webroot/js/jquery-ui/effects.blind.min.js b/site/app/webroot/js/jquery-ui/effects.blind.min.js
new file mode 100755
index 0000000..4a1a7d3
--- /dev/null
+++ b/site/app/webroot/js/jquery-ui/effects.blind.min.js
@@ -0,0 +1 @@
+(function(A){A.effects.blind=function(B){return this.queue(function(){var D=A(this),C=["position","top","left"];var H=A.effects.setMode(D,B.options.mode||"hide");var G=B.options.direction||"vertical";A.effects.save(D,C);D.show();var J=A.effects.createWrapper(D).css({overflow:"hidden"});var E=(G=="vertical")?"height":"width";var I=(G=="vertical")?J.height():J.width();if(H=="show"){J.css(E,0)}var F={};F[E]=H=="show"?I:0;J.animate(F,B.duration,B.options.easing,function(){if(H=="hide"){D.hide()}A.effects.restore(D,C);A.effects.removeWrapper(D);if(B.callback){B.callback.apply(D[0],arguments)}D.dequeue()})})}})(jQuery) \ No newline at end of file
diff --git a/site/app/webroot/js/jquery-ui/effects.bounce.min.js b/site/app/webroot/js/jquery-ui/effects.bounce.min.js
new file mode 100755
index 0000000..e6e8ac5
--- /dev/null
+++ b/site/app/webroot/js/jquery-ui/effects.bounce.min.js
@@ -0,0 +1 @@
+(function(A){A.effects.bounce=function(B){return this.queue(function(){var E=A(this),K=["position","top","left"];var J=A.effects.setMode(E,B.options.mode||"effect");var M=B.options.direction||"up";var C=B.options.distance||20;var D=B.options.times||5;var G=B.duration||250;if(/show|hide/.test(J)){K.push("opacity")}A.effects.save(E,K);E.show();A.effects.createWrapper(E);var F=(M=="up"||M=="down")?"top":"left";var O=(M=="up"||M=="left")?"pos":"neg";var C=B.options.distance||(F=="top"?E.outerHeight({margin:true})/3:E.outerWidth({margin:true})/3);if(J=="show"){E.css("opacity",0).css(F,O=="pos"?-C:C)}if(J=="hide"){C=C/(D*2)}if(J!="hide"){D--}if(J=="show"){var H={opacity:1};H[F]=(O=="pos"?"+=":"-=")+C;E.animate(H,G/2,B.options.easing);C=C/2;D--}for(var I=0;I<D;I++){var N={},L={};N[F]=(O=="pos"?"-=":"+=")+C;L[F]=(O=="pos"?"+=":"-=")+C;E.animate(N,G/2,B.options.easing).animate(L,G/2,B.options.easing);C=(J=="hide")?C*2:C/2}if(J=="hide"){var H={opacity:0};H[F]=(O=="pos"?"-=":"+=")+C;E.animate(H,G/2,B.options.easing,function(){E.hide();A.effects.restore(E,K);A.effects.removeWrapper(E);if(B.callback){B.callback.apply(this,arguments)}})}else{var N={},L={};N[F]=(O=="pos"?"-=":"+=")+C;L[F]=(O=="pos"?"+=":"-=")+C;E.animate(N,G/2,B.options.easing).animate(L,G/2,B.options.easing,function(){A.effects.restore(E,K);A.effects.removeWrapper(E);if(B.callback){B.callback.apply(this,arguments)}})}E.queue("fx",function(){E.dequeue()});E.dequeue()})}})(jQuery) \ No newline at end of file
diff --git a/site/app/webroot/js/jquery-ui/effects.clip.min.js b/site/app/webroot/js/jquery-ui/effects.clip.min.js
new file mode 100755
index 0000000..e5aced3
--- /dev/null
+++ b/site/app/webroot/js/jquery-ui/effects.clip.min.js
@@ -0,0 +1 @@
+(function(A){A.effects.clip=function(B){return this.queue(function(){var F=A(this),J=["position","top","left","height","width"];var I=A.effects.setMode(F,B.options.mode||"hide");var K=B.options.direction||"vertical";A.effects.save(F,J);F.show();var C=A.effects.createWrapper(F).css({overflow:"hidden"});var E=F[0].tagName=="IMG"?C:F;var G={size:(K=="vertical")?"height":"width",position:(K=="vertical")?"top":"left"};var D=(K=="vertical")?E.height():E.width();if(I=="show"){E.css(G.size,0);E.css(G.position,D/2)}var H={};H[G.size]=I=="show"?D:0;H[G.position]=I=="show"?0:D/2;E.animate(H,{queue:false,duration:B.duration,easing:B.options.easing,complete:function(){if(I=="hide"){F.hide()}A.effects.restore(F,J);A.effects.removeWrapper(F);if(B.callback){B.callback.apply(F[0],arguments)}F.dequeue()}})})}})(jQuery) \ No newline at end of file
diff --git a/site/app/webroot/js/jquery-ui/effects.core.min.js b/site/app/webroot/js/jquery-ui/effects.core.min.js
new file mode 100755
index 0000000..f244590
--- /dev/null
+++ b/site/app/webroot/js/jquery-ui/effects.core.min.js
@@ -0,0 +1 @@
+(function(C){C.effects=C.effects||{};C.extend(C.effects,{save:function(F,G){for(var E=0;E<G.length;E++){if(G[E]!==null){C.data(F[0],"ec.storage."+G[E],F[0].style[G[E]])}}},restore:function(F,G){for(var E=0;E<G.length;E++){if(G[E]!==null){F.css(G[E],C.data(F[0],"ec.storage."+G[E]))}}},setMode:function(E,F){if(F=="toggle"){F=E.is(":hidden")?"show":"hide"}return F},getBaseline:function(F,G){var H,E;switch(F[0]){case"top":H=0;break;case"middle":H=0.5;break;case"bottom":H=1;break;default:H=F[0]/G.height}switch(F[1]){case"left":E=0;break;case"center":E=0.5;break;case"right":E=1;break;default:E=F[1]/G.width}return{x:E,y:H}},createWrapper:function(F){if(F.parent().attr("id")=="fxWrapper"){return F}var E={width:F.outerWidth({margin:true}),height:F.outerHeight({margin:true}),"float":F.css("float")};F.wrap('<div id="fxWrapper" style="font-size:100%;background:transparent;border:none;margin:0;padding:0"></div>');var I=F.parent();if(F.css("position")=="static"){I.css({position:"relative"});F.css({position:"relative"})}else{var H=F.css("top");if(isNaN(parseInt(H))){H="auto"}var G=F.css("left");if(isNaN(parseInt(G))){G="auto"}I.css({position:F.css("position"),top:H,left:G,zIndex:F.css("z-index")}).show();F.css({position:"relative",top:0,left:0})}I.css(E);return I},removeWrapper:function(E){if(E.parent().attr("id")=="fxWrapper"){return E.parent().replaceWith(E)}return E},setTransition:function(F,G,E,H){H=H||{};C.each(G,function(J,I){unit=F.cssUnit(I);if(unit[0]>0){H[I]=unit[0]*E+unit[1]}});return H},animateClass:function(G,H,J,I){var E=(typeof J=="function"?J:(I?I:null));var F=(typeof J=="object"?J:null);return this.each(function(){var O={};var M=C(this);var N=M.attr("style")||"";if(typeof N=="object"){N=N["cssText"]}if(G.toggle){M.hasClass(G.toggle)?G.remove=G.toggle:G.add=G.toggle}var K=C.extend({},(document.defaultView?document.defaultView.getComputedStyle(this,null):this.currentStyle));if(G.add){M.addClass(G.add)}if(G.remove){M.removeClass(G.remove)}var L=C.extend({},(document.defaultView?document.defaultView.getComputedStyle(this,null):this.currentStyle));if(G.add){M.removeClass(G.add)}if(G.remove){M.addClass(G.remove)}for(var P in L){if(typeof L[P]!="function"&&L[P]&&P.indexOf("Moz")==-1&&P.indexOf("length")==-1&&L[P]!=K[P]&&(P.match(/color/i)||(!P.match(/color/i)&&!isNaN(parseInt(L[P],10))))&&(K.position!="static"||(K.position=="static"&&!P.match(/left|top|bottom|right/)))){O[P]=L[P]}}M.animate(O,H,F,function(){if(typeof C(this).attr("style")=="object"){C(this).attr("style")["cssText"]="";C(this).attr("style")["cssText"]=N}else{C(this).attr("style",N)}if(G.add){C(this).addClass(G.add)}if(G.remove){C(this).removeClass(G.remove)}if(E){E.apply(this,arguments)}})})}});C.fn.extend({_show:C.fn.show,_hide:C.fn.hide,__toggle:C.fn.toggle,_addClass:C.fn.addClass,_removeClass:C.fn.removeClass,_toggleClass:C.fn.toggleClass,effect:function(E,G,F,H){return C.effects[E]?C.effects[E].call(this,{method:E,options:G||{},duration:F,callback:H}):null},show:function(){if(!arguments[0]||(arguments[0].constructor==Number||/(slow|normal|fast)/.test(arguments[0]))){return this._show.apply(this,arguments)}else{var E=arguments[1]||{};E["mode"]="show";return this.effect.apply(this,[arguments[0],E,arguments[2]||E.duration,arguments[3]||E.callback])}},hide:function(){if(!arguments[0]||(arguments[0].constructor==Number||/(slow|normal|fast)/.test(arguments[0]))){return this._hide.apply(this,arguments)}else{var E=arguments[1]||{};E["mode"]="hide";return this.effect.apply(this,[arguments[0],E,arguments[2]||E.duration,arguments[3]||E.callback])}},toggle:function(){if(!arguments[0]||(arguments[0].constructor==Number||/(slow|normal|fast)/.test(arguments[0]))||(arguments[0].constructor==Function)){return this.__toggle.apply(this,arguments)}else{var E=arguments[1]||{};E["mode"]="toggle";return this.effect.apply(this,[arguments[0],E,arguments[2]||E.duration,arguments[3]||E.callback])}},addClass:function(F,E,H,G){return E?C.effects.animateClass.apply(this,[{add:F},E,H,G]):this._addClass(F)},removeClass:function(F,E,H,G){return E?C.effects.animateClass.apply(this,[{remove:F},E,H,G]):this._removeClass(F)},toggleClass:function(F,E,H,G){return E?C.effects.animateClass.apply(this,[{toggle:F},E,H,G]):this._toggleClass(F)},morph:function(E,G,F,I,H){return C.effects.animateClass.apply(this,[{add:G,remove:E},F,I,H])},switchClass:function(){return this.morph.apply(this,arguments)},cssUnit:function(E){var F=this.css(E),G=[];C.each(["em","px","%","pt"],function(H,I){if(F.indexOf(I)>0){G=[parseFloat(F),I]}});return G}});jQuery.each(["backgroundColor","borderBottomColor","borderLeftColor","borderRightColor","borderTopColor","color","outlineColor"],function(F,E){jQuery.fx.step[E]=function(G){if(G.state==0){G.start=D(G.elem,E);G.end=B(G.end)}G.elem.style[E]="rgb("+[Math.max(Math.min(parseInt((G.pos*(G.end[0]-G.start[0]))+G.start[0]),255),0),Math.max(Math.min(parseInt((G.pos*(G.end[1]-G.start[1]))+G.start[1]),255),0),Math.max(Math.min(parseInt((G.pos*(G.end[2]-G.start[2]))+G.start[2]),255),0)].join(",")+")"}});function B(F){var E;if(F&&F.constructor==Array&&F.length==3){return F}if(E=/rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(F)){return[parseInt(E[1]),parseInt(E[2]),parseInt(E[3])]}if(E=/rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(F)){return[parseFloat(E[1])*2.55,parseFloat(E[2])*2.55,parseFloat(E[3])*2.55]}if(E=/#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(F)){return[parseInt(E[1],16),parseInt(E[2],16),parseInt(E[3],16)]}if(E=/#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(F)){return[parseInt(E[1]+E[1],16),parseInt(E[2]+E[2],16),parseInt(E[3]+E[3],16)]}if(E=/rgba\(0, 0, 0, 0\)/.exec(F)){return A["transparent"]}return A[jQuery.trim(F).toLowerCase()]}function D(G,E){var F;do{F=jQuery.curCSS(G,E);if(F!=""&&F!="transparent"||jQuery.nodeName(G,"body")){break}E="backgroundColor"}while(G=G.parentNode);return B(F)}var A={aqua:[0,255,255],azure:[240,255,255],beige:[245,245,220],black:[0,0,0],blue:[0,0,255],brown:[165,42,42],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgrey:[169,169,169],darkgreen:[0,100,0],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkviolet:[148,0,211],fuchsia:[255,0,255],gold:[255,215,0],green:[0,128,0],indigo:[75,0,130],khaki:[240,230,140],lightblue:[173,216,230],lightcyan:[224,255,255],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightyellow:[255,255,224],lime:[0,255,0],magenta:[255,0,255],maroon:[128,0,0],navy:[0,0,128],olive:[128,128,0],orange:[255,165,0],pink:[255,192,203],purple:[128,0,128],violet:[128,0,128],red:[255,0,0],silver:[192,192,192],white:[255,255,255],yellow:[255,255,0],transparent:[255,255,255]};jQuery.easing["jswing"]=jQuery.easing["swing"];jQuery.extend(jQuery.easing,{def:"easeOutQuad",swing:function(F,G,E,I,H){return jQuery.easing[jQuery.easing.def](F,G,E,I,H)},easeInQuad:function(F,G,E,I,H){return I*(G/=H)*G+E},easeOutQuad:function(F,G,E,I,H){return -I*(G/=H)*(G-2)+E},easeInOutQuad:function(F,G,E,I,H){if((G/=H/2)<1){return I/2*G*G+E}return -I/2*((--G)*(G-2)-1)+E},easeInCubic:function(F,G,E,I,H){return I*(G/=H)*G*G+E},easeOutCubic:function(F,G,E,I,H){return I*((G=G/H-1)*G*G+1)+E},easeInOutCubic:function(F,G,E,I,H){if((G/=H/2)<1){return I/2*G*G*G+E}return I/2*((G-=2)*G*G+2)+E},easeInQuart:function(F,G,E,I,H){return I*(G/=H)*G*G*G+E},easeOutQuart:function(F,G,E,I,H){return -I*((G=G/H-1)*G*G*G-1)+E},easeInOutQuart:function(F,G,E,I,H){if((G/=H/2)<1){return I/2*G*G*G*G+E}return -I/2*((G-=2)*G*G*G-2)+E},easeInQuint:function(F,G,E,I,H){return I*(G/=H)*G*G*G*G+E},easeOutQuint:function(F,G,E,I,H){return I*((G=G/H-1)*G*G*G*G+1)+E},easeInOutQuint:function(F,G,E,I,H){if((G/=H/2)<1){return I/2*G*G*G*G*G+E}return I/2*((G-=2)*G*G*G*G+2)+E},easeInSine:function(F,G,E,I,H){return -I*Math.cos(G/H*(Math.PI/2))+I+E},easeOutSine:function(F,G,E,I,H){return I*Math.sin(G/H*(Math.PI/2))+E},easeInOutSine:function(F,G,E,I,H){return -I/2*(Math.cos(Math.PI*G/H)-1)+E},easeInExpo:function(F,G,E,I,H){return(G==0)?E:I*Math.pow(2,10*(G/H-1))+E},easeOutExpo:function(F,G,E,I,H){return(G==H)?E+I:I*(-Math.pow(2,-10*G/H)+1)+E},easeInOutExpo:function(F,G,E,I,H){if(G==0){return E}if(G==H){return E+I}if((G/=H/2)<1){return I/2*Math.pow(2,10*(G-1))+E}return I/2*(-Math.pow(2,-10*--G)+2)+E},easeInCirc:function(F,G,E,I,H){return -I*(Math.sqrt(1-(G/=H)*G)-1)+E},easeOutCirc:function(F,G,E,I,H){return I*Math.sqrt(1-(G=G/H-1)*G)+E},easeInOutCirc:function(F,G,E,I,H){if((G/=H/2)<1){return -I/2*(Math.sqrt(1-G*G)-1)+E}return I/2*(Math.sqrt(1-(G-=2)*G)+1)+E},easeInElastic:function(F,H,E,L,K){var I=1.70158;var J=0;var G=L;if(H==0){return E}if((H/=K)==1){return E+L}if(!J){J=K*0.3}if(G<Math.abs(L)){G=L;var I=J/4}else{var I=J/(2*Math.PI)*Math.asin(L/G)}return -(G*Math.pow(2,10*(H-=1))*Math.sin((H*K-I)*(2*Math.PI)/J))+E},easeOutElastic:function(F,H,E,L,K){var I=1.70158;var J=0;var G=L;if(H==0){return E}if((H/=K)==1){return E+L}if(!J){J=K*0.3}if(G<Math.abs(L)){G=L;var I=J/4}else{var I=J/(2*Math.PI)*Math.asin(L/G)}return G*Math.pow(2,-10*H)*Math.sin((H*K-I)*(2*Math.PI)/J)+L+E},easeInOutElastic:function(F,H,E,L,K){var I=1.70158;var J=0;var G=L;if(H==0){return E}if((H/=K/2)==2){return E+L}if(!J){J=K*(0.3*1.5)}if(G<Math.abs(L)){G=L;var I=J/4}else{var I=J/(2*Math.PI)*Math.asin(L/G)}if(H<1){return -0.5*(G*Math.pow(2,10*(H-=1))*Math.sin((H*K-I)*(2*Math.PI)/J))+E}return G*Math.pow(2,-10*(H-=1))*Math.sin((H*K-I)*(2*Math.PI)/J)*0.5+L+E},easeInBack:function(F,G,E,J,I,H){if(H==undefined){H=1.70158}return J*(G/=I)*G*((H+1)*G-H)+E},easeOutBack:function(F,G,E,J,I,H){if(H==undefined){H=1.70158}return J*((G=G/I-1)*G*((H+1)*G+H)+1)+E},easeInOutBack:function(F,G,E,J,I,H){if(H==undefined){H=1.70158}if((G/=I/2)<1){return J/2*(G*G*(((H*=(1.525))+1)*G-H))+E}return J/2*((G-=2)*G*(((H*=(1.525))+1)*G+H)+2)+E},easeInBounce:function(F,G,E,I,H){return I-jQuery.easing.easeOutBounce(F,H-G,0,I,H)+E},easeOutBounce:function(F,G,E,I,H){if((G/=H)<(1/2.75)){return I*(7.5625*G*G)+E}else{if(G<(2/2.75)){return I*(7.5625*(G-=(1.5/2.75))*G+0.75)+E}else{if(G<(2.5/2.75)){return I*(7.5625*(G-=(2.25/2.75))*G+0.9375)+E}else{return I*(7.5625*(G-=(2.625/2.75))*G+0.984375)+E}}}},easeInOutBounce:function(F,G,E,I,H){if(G<H/2){return jQuery.easing.easeInBounce(F,G*2,0,I,H)*0.5+E}return jQuery.easing.easeOutBounce(F,G*2-H,0,I,H)*0.5+I*0.5+E}})})(jQuery) \ No newline at end of file
diff --git a/site/app/webroot/js/jquery-ui/effects.drop.min.js b/site/app/webroot/js/jquery-ui/effects.drop.min.js
new file mode 100755
index 0000000..a00c79c
--- /dev/null
+++ b/site/app/webroot/js/jquery-ui/effects.drop.min.js
@@ -0,0 +1 @@
+(function(A){A.effects.drop=function(B){return this.queue(function(){var E=A(this),D=["position","top","left","opacity"];var I=A.effects.setMode(E,B.options.mode||"hide");var H=B.options.direction||"left";A.effects.save(E,D);E.show();A.effects.createWrapper(E);var F=(H=="up"||H=="down")?"top":"left";var C=(H=="up"||H=="left")?"pos":"neg";var J=B.options.distance||(F=="top"?E.outerHeight({margin:true})/2:E.outerWidth({margin:true})/2);if(I=="show"){E.css("opacity",0).css(F,C=="pos"?-J:J)}var G={opacity:I=="show"?1:0};G[F]=(I=="show"?(C=="pos"?"+=":"-="):(C=="pos"?"-=":"+="))+J;E.animate(G,{queue:false,duration:B.duration,easing:B.options.easing,complete:function(){if(I=="hide"){E.hide()}A.effects.restore(E,D);A.effects.removeWrapper(E);if(B.callback){B.callback.apply(this,arguments)}E.dequeue()}})})}})(jQuery) \ No newline at end of file
diff --git a/site/app/webroot/js/jquery-ui/effects.explode.min.js b/site/app/webroot/js/jquery-ui/effects.explode.min.js
new file mode 100755
index 0000000..3cbf3be
--- /dev/null
+++ b/site/app/webroot/js/jquery-ui/effects.explode.min.js
@@ -0,0 +1 @@
+(function(A){A.effects.explode=function(B){return this.queue(function(){var I=B.options.pieces?Math.round(Math.sqrt(B.options.pieces)):3;var E=B.options.pieces?Math.round(Math.sqrt(B.options.pieces)):3;B.options.mode=B.options.mode=="toggle"?(A(this).is(":visible")?"hide":"show"):B.options.mode;var H=A(this).show().css("visibility","hidden");var J=H.offset();J.top-=parseInt(H.css("marginTop"))||0;J.left-=parseInt(H.css("marginLeft"))||0;var G=H.outerWidth(true);var C=H.outerHeight(true);for(var F=0;F<I;F++){for(var D=0;D<E;D++){H.clone().appendTo("body").wrap("<div></div>").css({position:"absolute",visibility:"visible",left:-D*(G/E),top:-F*(C/I)}).parent().addClass("effects-explode").css({position:"absolute",overflow:"hidden",width:G/E,height:C/I,left:J.left+D*(G/E)+(B.options.mode=="show"?(D-Math.floor(E/2))*(G/E):0),top:J.top+F*(C/I)+(B.options.mode=="show"?(F-Math.floor(I/2))*(C/I):0),opacity:B.options.mode=="show"?0:1}).animate({left:J.left+D*(G/E)+(B.options.mode=="show"?0:(D-Math.floor(E/2))*(G/E)),top:J.top+F*(C/I)+(B.options.mode=="show"?0:(F-Math.floor(I/2))*(C/I)),opacity:B.options.mode=="show"?1:0},B.duration||500)}}setTimeout(function(){B.options.mode=="show"?H.css({visibility:"visible"}):H.css({visibility:"visible"}).hide();if(B.callback){B.callback.apply(H[0])}H.dequeue();A(".effects-explode").remove()},B.duration||500)})}})(jQuery) \ No newline at end of file
diff --git a/site/app/webroot/js/jquery-ui/effects.fold.min.js b/site/app/webroot/js/jquery-ui/effects.fold.min.js
new file mode 100755
index 0000000..17c678d
--- /dev/null
+++ b/site/app/webroot/js/jquery-ui/effects.fold.min.js
@@ -0,0 +1 @@
+(function(A){A.effects.fold=function(B){return this.queue(function(){var E=A(this),J=["position","top","left"];var G=A.effects.setMode(E,B.options.mode||"hide");var N=B.options.size||15;var M=!(!B.options.horizFirst);A.effects.save(E,J);E.show();var D=A.effects.createWrapper(E).css({overflow:"hidden"});var H=((G=="show")!=M);var F=H?["width","height"]:["height","width"];var C=H?[D.width(),D.height()]:[D.height(),D.width()];var I=/([0-9]+)%/.exec(N);if(I){N=parseInt(I[1])/100*C[G=="hide"?0:1]}if(G=="show"){D.css(M?{height:0,width:N}:{height:N,width:0})}var L={},K={};L[F[0]]=G=="show"?C[0]:N;K[F[1]]=G=="show"?C[1]:0;D.animate(L,B.duration/2,B.options.easing).animate(K,B.duration/2,B.options.easing,function(){if(G=="hide"){E.hide()}A.effects.restore(E,J);A.effects.removeWrapper(E);if(B.callback){B.callback.apply(E[0],arguments)}E.dequeue()})})}})(jQuery) \ No newline at end of file
diff --git a/site/app/webroot/js/jquery-ui/effects.highlight.min.js b/site/app/webroot/js/jquery-ui/effects.highlight.min.js
new file mode 100755
index 0000000..d330418
--- /dev/null
+++ b/site/app/webroot/js/jquery-ui/effects.highlight.min.js
@@ -0,0 +1 @@
+(function(A){A.effects.highlight=function(B){return this.queue(function(){var E=A(this),D=["backgroundImage","backgroundColor","opacity"];var H=A.effects.setMode(E,B.options.mode||"show");var C=B.options.color||"#ffff99";var G=E.css("backgroundColor");A.effects.save(E,D);E.show();E.css({backgroundImage:"none",backgroundColor:C});var F={backgroundColor:G};if(H=="hide"){F["opacity"]=0}E.animate(F,{queue:false,duration:B.duration,easing:B.options.easing,complete:function(){if(H=="hide"){E.hide()}A.effects.restore(E,D);if(H=="show"&&jQuery.browser.msie){this.style.removeAttribute("filter")}if(B.callback){B.callback.apply(this,arguments)}E.dequeue()}})})}})(jQuery) \ No newline at end of file
diff --git a/site/app/webroot/js/jquery-ui/effects.pulsate.min.js b/site/app/webroot/js/jquery-ui/effects.pulsate.min.js
new file mode 100755
index 0000000..8e29ced
--- /dev/null
+++ b/site/app/webroot/js/jquery-ui/effects.pulsate.min.js
@@ -0,0 +1 @@
+(function(A){A.effects.pulsate=function(B){return this.queue(function(){var D=A(this);var F=A.effects.setMode(D,B.options.mode||"show");var E=B.options.times||5;if(F=="hide"){E--}if(D.is(":hidden")){D.css("opacity",0);D.show();D.animate({opacity:1},B.duration/2,B.options.easing);E=E-2}for(var C=0;C<E;C++){D.animate({opacity:0},B.duration/2,B.options.easing).animate({opacity:1},B.duration/2,B.options.easing)}if(F=="hide"){D.animate({opacity:0},B.duration/2,B.options.easing,function(){D.hide();if(B.callback){B.callback.apply(this,arguments)}})}else{D.animate({opacity:0},B.duration/2,B.options.easing).animate({opacity:1},B.duration/2,B.options.easing,function(){if(B.callback){B.callback.apply(this,arguments)}})}D.queue("fx",function(){D.dequeue()});D.dequeue()})}})(jQuery) \ No newline at end of file
diff --git a/site/app/webroot/js/jquery-ui/effects.scale.min.js b/site/app/webroot/js/jquery-ui/effects.scale.min.js
new file mode 100755
index 0000000..e7e5014
--- /dev/null
+++ b/site/app/webroot/js/jquery-ui/effects.scale.min.js
@@ -0,0 +1 @@
+(function(A){A.effects.puff=function(B){return this.queue(function(){var F=A(this);var C=A.extend(true,{},B.options);var H=A.effects.setMode(F,B.options.mode||"hide");var G=parseInt(B.options.percent)||150;C.fade=true;var E={height:F.height(),width:F.width()};var D=G/100;F.from=(H=="hide")?E:{height:E.height*D,width:E.width*D};C.from=F.from;C.percent=(H=="hide")?G:100;C.mode=H;F.effect("scale",C,B.duration,B.callback);F.dequeue()})};A.effects.scale=function(B){return this.queue(function(){var G=A(this);var D=A.extend(true,{},B.options);var J=A.effects.setMode(G,B.options.mode||"effect");var H=parseInt(B.options.percent)||(parseInt(B.options.percent)==0?0:(J=="hide"?0:100));var I=B.options.direction||"both";var C=B.options.origin;if(J!="effect"){D.origin=C||["middle","center"];D.restore=true}var F={height:G.height(),width:G.width()};G.from=B.options.from||(J=="show"?{height:0,width:0}:F);var E={y:I!="horizontal"?(H/100):1,x:I!="vertical"?(H/100):1};G.to={height:F.height*E.y,width:F.width*E.x};if(B.options.fade){if(J=="show"){G.from.opacity=0;G.to.opacity=1}if(J=="hide"){G.from.opacity=1;G.to.opacity=0}}D.from=G.from;D.to=G.to;D.mode=J;G.effect("size",D,B.duration,B.callback);G.dequeue()})};A.effects.size=function(B){return this.queue(function(){var C=A(this),N=["position","top","left","width","height","overflow","opacity"];var M=["position","top","left","overflow","opacity"];var J=["width","height","overflow"];var P=["fontSize"];var K=["borderTopWidth","borderBottomWidth","paddingTop","paddingBottom"];var F=["borderLeftWidth","borderRightWidth","paddingLeft","paddingRight"];var G=A.effects.setMode(C,B.options.mode||"effect");var I=B.options.restore||false;var E=B.options.scale||"both";var O=B.options.origin;var D={height:C.height(),width:C.width()};C.from=B.options.from||D;C.to=B.options.to||D;if(O){var H=A.effects.getBaseline(O,D);C.from.top=(D.height-C.from.height)*H.y;C.from.left=(D.width-C.from.width)*H.x;C.to.top=(D.height-C.to.height)*H.y;C.to.left=(D.width-C.to.width)*H.x}var L={from:{y:C.from.height/D.height,x:C.from.width/D.width},to:{y:C.to.height/D.height,x:C.to.width/D.width}};if(E=="box"||E=="both"){if(L.from.y!=L.to.y){N=N.concat(K);C.from=A.effects.setTransition(C,K,L.from.y,C.from);C.to=A.effects.setTransition(C,K,L.to.y,C.to)}if(L.from.x!=L.to.x){N=N.concat(F);C.from=A.effects.setTransition(C,F,L.from.x,C.from);C.to=A.effects.setTransition(C,F,L.to.x,C.to)}}if(E=="content"||E=="both"){if(L.from.y!=L.to.y){N=N.concat(P);C.from=A.effects.setTransition(C,P,L.from.y,C.from);C.to=A.effects.setTransition(C,P,L.to.y,C.to)}}A.effects.save(C,I?N:M);C.show();A.effects.createWrapper(C);C.css("overflow","hidden").css(C.from);if(E=="content"||E=="both"){K=K.concat(["marginTop","marginBottom"]).concat(P);F=F.concat(["marginLeft","marginRight"]);J=N.concat(K).concat(F);C.find("*[width]").each(function(){child=A(this);if(I){A.effects.save(child,J)}var Q={height:child.height(),width:child.width()};child.from={height:Q.height*L.from.y,width:Q.width*L.from.x};child.to={height:Q.height*L.to.y,width:Q.width*L.to.x};if(L.from.y!=L.to.y){child.from=A.effects.setTransition(child,K,L.from.y,child.from);child.to=A.effects.setTransition(child,K,L.to.y,child.to)}if(L.from.x!=L.to.x){child.from=A.effects.setTransition(child,F,L.from.x,child.from);child.to=A.effects.setTransition(child,F,L.to.x,child.to)}child.css(child.from);child.animate(child.to,B.duration,B.options.easing,function(){if(I){A.effects.restore(child,J)}})})}C.animate(C.to,{queue:false,duration:B.duration,easing:B.options.easing,complete:function(){if(G=="hide"){C.hide()}A.effects.restore(C,I?N:M);A.effects.removeWrapper(C);if(B.callback){B.callback.apply(this,arguments)}C.dequeue()}})})}})(jQuery) \ No newline at end of file
diff --git a/site/app/webroot/js/jquery-ui/effects.shake.min.js b/site/app/webroot/js/jquery-ui/effects.shake.min.js
new file mode 100755
index 0000000..48d320c
--- /dev/null
+++ b/site/app/webroot/js/jquery-ui/effects.shake.min.js
@@ -0,0 +1 @@
+(function(A){A.effects.shake=function(B){return this.queue(function(){var E=A(this),K=["position","top","left"];var J=A.effects.setMode(E,B.options.mode||"effect");var M=B.options.direction||"left";var C=B.options.distance||20;var D=B.options.times||3;var G=B.duration||B.options.duration||140;A.effects.save(E,K);E.show();A.effects.createWrapper(E);var F=(M=="up"||M=="down")?"top":"left";var O=(M=="up"||M=="left")?"pos":"neg";var H={},N={},L={};H[F]=(O=="pos"?"-=":"+=")+C;N[F]=(O=="pos"?"+=":"-=")+C*2;L[F]=(O=="pos"?"-=":"+=")+C*2;E.animate(H,G,B.options.easing);for(var I=1;I<D;I++){E.animate(N,G,B.options.easing).animate(L,G,B.options.easing)}E.animate(N,G,B.options.easing).animate(H,G/2,B.options.easing,function(){A.effects.restore(E,K);A.effects.removeWrapper(E);if(B.callback){B.callback.apply(this,arguments)}});E.queue("fx",function(){E.dequeue()});E.dequeue()})}})(jQuery) \ No newline at end of file
diff --git a/site/app/webroot/js/jquery-ui/effects.slide.min.js b/site/app/webroot/js/jquery-ui/effects.slide.min.js
new file mode 100755
index 0000000..5cd6d99
--- /dev/null
+++ b/site/app/webroot/js/jquery-ui/effects.slide.min.js
@@ -0,0 +1 @@
+(function(A){A.effects.slide=function(B){return this.queue(function(){var E=A(this),D=["position","top","left"];var I=A.effects.setMode(E,B.options.mode||"show");var H=B.options.direction||"left";A.effects.save(E,D);E.show();A.effects.createWrapper(E).css({overflow:"hidden"});var F=(H=="up"||H=="down")?"top":"left";var C=(H=="up"||H=="left")?"pos":"neg";var J=B.options.distance||(F=="top"?E.outerHeight({margin:true}):E.outerWidth({margin:true}));if(I=="show"){E.css(F,C=="pos"?-J:J)}var G={};G[F]=(I=="show"?(C=="pos"?"+=":"-="):(C=="pos"?"-=":"+="))+J;E.animate(G,{queue:false,duration:B.duration,easing:B.options.easing,complete:function(){if(I=="hide"){E.hide()}A.effects.restore(E,D);A.effects.removeWrapper(E);if(B.callback){B.callback.apply(this,arguments)}E.dequeue()}})})}})(jQuery) \ No newline at end of file
diff --git a/site/app/webroot/js/jquery-ui/effects.transfer.min.js b/site/app/webroot/js/jquery-ui/effects.transfer.min.js
new file mode 100755
index 0000000..a735abb
--- /dev/null
+++ b/site/app/webroot/js/jquery-ui/effects.transfer.min.js
@@ -0,0 +1 @@
+(function(A){A.effects.transfer=function(B){return this.queue(function(){var E=A(this);var G=A.effects.setMode(E,B.options.mode||"effect");var F=A(B.options.to);var C=E.offset();var D=A('<div class="ui-effects-transfer"></div>').appendTo(document.body);if(B.options.className){D.addClass(B.options.className)}D.addClass(B.options.className);D.css({top:C.top,left:C.left,height:E.outerHeight()-parseInt(D.css("borderTopWidth"))-parseInt(D.css("borderBottomWidth")),width:E.outerWidth()-parseInt(D.css("borderLeftWidth"))-parseInt(D.css("borderRightWidth")),position:"absolute"});C=F.offset();animation={top:C.top,left:C.left,height:F.outerHeight()-parseInt(D.css("borderTopWidth"))-parseInt(D.css("borderBottomWidth")),width:F.outerWidth()-parseInt(D.css("borderLeftWidth"))-parseInt(D.css("borderRightWidth"))};D.animate(animation,B.duration,B.options.easing,function(){D.remove();if(B.callback){B.callback.apply(E[0],arguments)}E.dequeue()})})}})(jQuery) \ No newline at end of file
diff --git a/site/app/webroot/js/jquery-ui/jq-ui-162rc2-accordion-bundle-a11y.min.js b/site/app/webroot/js/jquery-ui/jq-ui-162rc2-accordion-bundle-a11y.min.js
new file mode 100644
index 0000000..fed7a60
--- /dev/null
+++ b/site/app/webroot/js/jquery-ui/jq-ui-162rc2-accordion-bundle-a11y.min.js
@@ -0,0 +1 @@
+(function(D){var C=D.fn.remove;D.fn.remove=function(){D("*",this).add(this).triggerHandler("remove");return C.apply(this,arguments)};function B(E){function G(H){var I=H.style;return(I.display!="none"&&I.visibility!="hidden")}var F=G(E);(F&&D.each(D.dir(E,"parentNode"),function(){return(F=G(this))}));return F}D.extend(D.expr[":"],{data:function(F,G,E){return D.data(F,E[3])},tabbable:function(F,G,E){var H=F.nodeName.toLowerCase();return(F.tabIndex>=0&&(("a"==H&&F.href)||(/input|select|textarea|button/.test(H)&&"hidden"!=F.type&&!F.disabled))&&B(F))}});D.keyCode={BACKSPACE:8,CAPS_LOCK:20,COMMA:188,CONTROL:17,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,INSERT:45,LEFT:37,NUMPAD_ADD:107,NUMPAD_DECIMAL:110,NUMPAD_DIVIDE:111,NUMPAD_ENTER:108,NUMPAD_MULTIPLY:106,NUMPAD_SUBTRACT:109,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SHIFT:16,SPACE:32,TAB:9,UP:38};function A(H,I,J,G){function F(L){var K=D[H][I][L]||[];return(typeof K=="string"?K.split(/,?\s+/):K)}var E=F("getter");if(G.length==1&&typeof G[0]=="string"){E=E.concat(F("getterSetter"))}return(D.inArray(J,E)!=-1)}D.widget=function(F,E){var G=F.split(".")[0];F=F.split(".")[1];D.fn[F]=function(K){var I=(typeof K=="string"),J=Array.prototype.slice.call(arguments,1);if(I&&K.substring(0,1)=="_"){return this}if(I&&A(G,F,K,J)){var H=D.data(this[0],F);return(H?H[K].apply(H,J):undefined)}return this.each(function(){var L=D.data(this,F);(!L&&!I&&D.data(this,F,new D[G][F](this,K)));(L&&I&&D.isFunction(L[K])&&L[K].apply(L,J))})};D[G][F]=function(J,I){var H=this;this.widgetName=F;this.widgetEventPrefix=D[G][F].eventPrefix||F;this.widgetBaseClass=G+"-"+F;this.options=D.extend({},D.widget.defaults,D[G][F].defaults,D.metadata&&D.metadata.get(J)[F],I);this.element=D(J).bind("setData."+F,function(M,K,L){return H._setData(K,L)}).bind("getData."+F,function(L,K){return H._getData(K)}).bind("remove",function(){return H.destroy()});this._init()};D[G][F].prototype=D.extend({},D.widget.prototype,E);D[G][F].getterSetter="option"};D.widget.prototype={_init:function(){},destroy:function(){this.element.removeData(this.widgetName)},option:function(G,H){var F=G,E=this;if(typeof G=="string"){if(H===undefined){return this._getData(G)}F={};F[G]=H}D.each(F,function(I,J){E._setData(I,J)})},_getData:function(E){return this.options[E]},_setData:function(E,F){this.options[E]=F;if(E=="disabled"){this.element[F?"addClass":"removeClass"](this.widgetBaseClass+"-disabled")}},enable:function(){this._setData("disabled",false)},disable:function(){this._setData("disabled",true)},_trigger:function(F,H,G){var E=(F==this.widgetEventPrefix?F:this.widgetEventPrefix+F);H=H||D.event.fix({type:E,target:this.element[0]});return this.element.triggerHandler(E,[H,G],this.options[F])}};D.widget.defaults={disabled:false};D.ui={plugin:{add:function(F,G,I){var H=D.ui[F].prototype;for(var E in I){H.plugins[E]=H.plugins[E]||[];H.plugins[E].push([G,I[E]])}},call:function(E,G,F){var I=E.plugins[G];if(!I){return }for(var H=0;H<I.length;H++){if(E.options[I[H][0]]){I[H][1].apply(E.element,F)}}}},cssCache:{},css:function(E){if(D.ui.cssCache[E]){return D.ui.cssCache[E]}var F=D('<div class="ui-gen">').addClass(E).css({position:"absolute",top:"-5000px",left:"-5000px",display:"block"}).appendTo("body");D.ui.cssCache[E]=!!((!(/auto|default/).test(F.css("cursor"))||(/^[1-9]/).test(F.css("height"))||(/^[1-9]/).test(F.css("width"))||!(/none/).test(F.css("backgroundImage"))||!(/transparent|rgba\(0, 0, 0, 0\)/).test(F.css("backgroundColor"))));try{D("body").get(0).removeChild(F.get(0))}catch(G){}return D.ui.cssCache[E]},disableSelection:function(E){return D(E).attr("unselectable","on").css("MozUserSelect","none").bind("selectstart.ui",function(){return false})},enableSelection:function(E){return D(E).attr("unselectable","off").css("MozUserSelect","").unbind("selectstart.ui")},hasScroll:function(H,F){if(D(H).css("overflow")=="hidden"){return false}var E=(F&&F=="left")?"scrollLeft":"scrollTop",G=false;if(H[E]>0){return true}H[E]=1;G=(H[E]>0);H[E]=0;return G}};D.ui.mouse={_mouseInit:function(){var E=this;this.element.bind("mousedown."+this.widgetName,function(F){return E._mouseDown(F)});if(D.browser.msie){this._mouseUnselectable=this.element.attr("unselectable");this.element.attr("unselectable","on")}this.started=false},_mouseDestroy:function(){this.element.unbind("."+this.widgetName);(D.browser.msie&&this.element.attr("unselectable",this._mouseUnselectable))},_mouseDown:function(G){(this._mouseStarted&&this._mouseUp(G));this._mouseDownEvent=G;var F=this,H=(G.which==1),E=(typeof this.options.cancel=="string"?D(G.target).parents().add(G.target).filter(this.options.cancel).length:false);if(!H||E||!this._mouseCapture(G)){return true}this.mouseDelayMet=!this.options.delay;if(!this.mouseDelayMet){this._mouseDelayTimer=setTimeout(function(){F.mouseDelayMet=true},this.options.delay)}if(this._mouseDistanceMet(G)&&this._mouseDelayMet(G)){this._mouseStarted=(this._mouseStart(G)!==false);if(!this._mouseStarted){G.preventDefault();return true}}this._mouseMoveDelegate=function(I){return F._mouseMove(I)};this._mouseUpDelegate=function(I){return F._mouseUp(I)};D(document).bind("mousemove."+this.widgetName,this._mouseMoveDelegate).bind("mouseup."+this.widgetName,this._mouseUpDelegate);return false},_mouseMove:function(E){if(D.browser.msie&&!E.button){return this._mouseUp(E)}if(this._mouseStarted){this._mouseDrag(E);return false}if(this._mouseDistanceMet(E)&&this._mouseDelayMet(E)){this._mouseStarted=(this._mouseStart(this._mouseDownEvent,E)!==false);(this._mouseStarted?this._mouseDrag(E):this._mouseUp(E))}return !this._mouseStarted},_mouseUp:function(E){D(document).unbind("mousemove."+this.widgetName,this._mouseMoveDelegate).unbind("mouseup."+this.widgetName,this._mouseUpDelegate);if(this._mouseStarted){this._mouseStarted=false;this._mouseStop(E)}return false},_mouseDistanceMet:function(E){return(Math.max(Math.abs(this._mouseDownEvent.pageX-E.pageX),Math.abs(this._mouseDownEvent.pageY-E.pageY))>=this.options.distance)},_mouseDelayMet:function(E){return this.mouseDelayMet},_mouseStart:function(E){},_mouseDrag:function(E){},_mouseStop:function(E){},_mouseCapture:function(E){return true}};D.ui.mouse.defaults={cancel:null,distance:1,delay:0}})(jQuery);(function(E){E.widget("ui.accordion",{_init:function(){var H=this.options;if(H.navigation){var K=this.element.find("a").filter(H.navigationFilter);if(K.length){if(K.filter(H.header).length){H.active=K}else{H.active=K.parent().parent().prev();K.addClass("current")}}}H.headers=this.element.find(H.header);H.active=C(H.headers,H.active);if(E.browser.msie){this.element.find("a").css("zoom","1")}if(!this.element.hasClass("ui-accordion")){this.element.addClass("ui-accordion");E('<span class="ui-accordion-left"/>').insertBefore(H.headers);E('<span class="ui-accordion-right"/>').appendTo(H.headers);H.headers.addClass("ui-accordion-header")}var J;if(H.fillSpace){J=this.element.parent().height();H.headers.each(function(){J-=E(this).outerHeight()});var I=0;H.headers.next().each(function(){I=Math.max(I,E(this).innerHeight()-E(this).height())}).height(J-I)}else{if(H.autoHeight){J=0;H.headers.next().each(function(){J=Math.max(J,E(this).outerHeight())}).height(J)}}this.element.attr("role","tablist");var G=this;H.headers.attr("role","tab").bind("keydown",function(L){return G._keydown(L)}).next().attr("role","tabpanel");H.headers.not(H.active||"").attr("aria-expanded","false").attr("tabIndex","-1").next().hide();if(!H.active.length){H.headers.eq(0).attr("tabIndex","0")}else{H.active.attr("aria-expanded","true").attr("tabIndex","0").parent().andSelf().addClass(H.selectedClass)}if(!E.browser.safari){H.headers.find("a").attr("tabIndex","-1")}if(H.event){this.element.bind((H.event)+".accordion",F)}},_keydown:function(K){if(this.options.disabled||K.altKey||K.ctrlKey){return }var J=E.keyCode;var I=this.options.headers.length;var G=this.options.headers.index(K.target);var H=false;if(K.keyCode==J.RIGHT||K.keyCode==J.DOWN){H=this.options.headers[(G+1)%I]}else{if(K.keyCode==J.LEFT||K.keyCode==J.UP){H=this.options.headers[(G-1+I)%I]}else{if(K.keyCode==J.SPACE||K.keyCode==J.ENTER){return F.call(this.element[0],{target:K.target})}}}if(H){E(K.target).attr("tabIndex","-1");E(H).attr("tabIndex","0");H.focus();return false}return true},activate:function(G){F.call(this.element[0],{target:C(this.options.headers,G)[0]})},destroy:function(){this.options.headers.next().css("display","");if(this.options.fillSpace||this.options.autoHeight){this.options.headers.next().css("height","")}E.removeData(this.element[0],"accordion");this.element.removeClass("ui-accordion").unbind(".accordion")}});function B(H,G){return function(){return H.apply(G,arguments)}}function D(I){if(!E.data(this,"accordion")){return }var G=E.data(this,"accordion");var H=G.options;H.running=I?0:--H.running;if(H.running){return }if(H.clearStyle){H.toShow.add(H.toHide).css({height:"",overflow:""})}G._trigger("change",null,H.data)}function A(G,K,L,J,M){var I=E.data(this,"accordion").options;I.toShow=G;I.toHide=K;I.data=L;var H=B(D,this);E.data(this,"accordion")._trigger("changestart",null,I.data);I.running=K.size()===0?G.size():K.size();if(I.animated){if(!I.alwaysOpen&&J){E.ui.accordion.animations[I.animated]({toShow:jQuery([]),toHide:K,complete:H,down:M,autoHeight:I.autoHeight})}else{E.ui.accordion.animations[I.animated]({toShow:G,toHide:K,complete:H,down:M,autoHeight:I.autoHeight})}}else{if(!I.alwaysOpen&&J){G.toggle()}else{K.hide();G.show()}H(true)}K.prev().attr("aria-expanded","false").attr("tabIndex","-1");G.prev().attr("aria-expanded","true").attr("tabIndex","0").focus()}function F(L){var J=E.data(this,"accordion").options;if(J.disabled){return false}if(!L.target&&!J.alwaysOpen){J.active.parent().andSelf().toggleClass(J.selectedClass);var I=J.active.next(),M={options:J,newHeader:jQuery([]),oldHeader:J.active,newContent:jQuery([]),oldContent:I},G=(J.active=E([]));A.call(this,G,I,M);return false}var K=E(L.target);K=E(K.parents(J.header)[0]||K);var H=K[0]==J.active[0];if(J.running||(J.alwaysOpen&&H)){return false}if(!K.is(J.header)){return }J.active.parent().andSelf().toggleClass(J.selectedClass);if(!H){K.parent().andSelf().addClass(J.selectedClass)}var G=K.next(),I=J.active.next(),M={options:J,newHeader:H&&!J.alwaysOpen?E([]):K,oldHeader:J.active,newContent:H&&!J.alwaysOpen?E([]):G,oldContent:I},N=J.headers.index(J.active[0])>J.headers.index(K[0]);J.active=H?E([]):K;A.call(this,G,I,M,H,N);return false}function C(H,G){return G?typeof G=="number"?H.filter(":eq("+G+")"):H.not(H.not(G)):G===false?E([]):H.filter(":eq(0)")}E.extend(E.ui.accordion,{defaults:{selectedClass:"selected",alwaysOpen:true,animated:"slide",event:"click",header:"a",autoHeight:true,running:0,navigationFilter:function(){return this.href.toLowerCase()==location.href.toLowerCase()}},animations:{slide:function(G,I){G=E.extend({easing:"swing",duration:300},G,I);if(!G.toHide.size()){G.toShow.animate({height:"show"},G);return }var H=G.toHide.height(),J=G.toShow.height(),K=J/H;G.toShow.css({height:0,overflow:"hidden"}).show();G.toHide.filter(":hidden").each(G.complete).end().filter(":visible").animate({height:"hide"},{step:function(L){var M=(H-L)*K;if(E.browser.msie||E.browser.opera){M=Math.ceil(M)}G.toShow.height(M)},duration:G.duration,easing:G.easing,complete:function(){if(!G.autoHeight){G.toShow.css("height","auto")}G.complete()}})},bounceslide:function(G){this.slide(G,{easing:G.down?"bounceout":"swing",duration:G.down?1000:200})},easeslide:function(G){this.slide(G,{easing:"easeinout",duration:700})}}})})(jQuery); \ No newline at end of file
diff --git a/site/app/webroot/js/jquery-ui/jqModal.js b/site/app/webroot/js/jquery-ui/jqModal.js
new file mode 100644
index 0000000..f3665cc
--- /dev/null
+++ b/site/app/webroot/js/jquery-ui/jqModal.js
@@ -0,0 +1,69 @@
+/*
+ * jqModal - Minimalist Modaling with jQuery
+ * (http://dev.iceburg.net/jquery/jqmodal/)
+ *
+ * Copyright (c) 2007,2008 Brice Burgess <bhb@iceburg.net>
+ * Dual licensed under the MIT and GPL licenses:
+ * http://www.opensource.org/licenses/mit-license.php
+ * http://www.gnu.org/licenses/gpl.html
+ *
+ * $Version: 07/06/2008 +r13
+ */
+(function($) {
+$.fn.jqm=function(o){
+var p={
+overlay: 50,
+overlayClass: 'jqmOverlay',
+closeClass: 'jqmClose',
+trigger: '.jqModal',
+ajax: F,
+ajaxText: '',
+target: F,
+modal: F,
+toTop: F,
+onShow: F,
+onHide: F,
+onLoad: F
+};
+return this.each(function(){if(this._jqm)return H[this._jqm].c=$.extend({},H[this._jqm].c,o);s++;this._jqm=s;
+H[s]={c:$.extend(p,$.jqm.params,o),a:F,w:$(this).addClass('jqmID'+s),s:s};
+if(p.trigger)$(this).jqmAddTrigger(p.trigger);
+});};
+
+$.fn.jqmAddClose=function(e){return hs(this,e,'jqmHide');};
+$.fn.jqmAddTrigger=function(e){return hs(this,e,'jqmShow');};
+$.fn.jqmShow=function(t){return this.each(function(){$.jqm.open(this._jqm,t);});};
+$.fn.jqmHide=function(t){return this.each(function(){$.jqm.close(this._jqm,t)});};
+
+$.jqm = {
+hash:{},
+open:function(s,t){var h=H[s],c=h.c,cc='.'+c.closeClass,z=(parseInt(h.w.css('z-index'))),z=(z>0)?z:3000,o=$('<div></div>').css({height:'100%',width:'100%',position:'fixed',left:0,top:0,'z-index':z-1,opacity:c.overlay/100});if(h.a)return F;h.t=t;h.a=true;h.w.css('z-index',z);
+ if(c.modal) {if(!A[0])L('bind');A.push(s);}
+ else if(c.overlay > 0)h.w.jqmAddClose(o);
+ else o=F;
+
+ h.o=(o)?o.addClass(c.overlayClass).prependTo('body'):F;
+ if(ie6){$('html,body').css({height:'100%',width:'100%'});if(o){o=o.css({position:'absolute'})[0];for(var y in {Top:1,Left:1})o.style.setExpression(y.toLowerCase(),"(_=(document.documentElement.scroll"+y+" || document.body.scroll"+y+"))+'px'");}}
+
+ if(c.ajax) {var r=c.target||h.w,u=c.ajax,r=(typeof r == 'string')?$(r,h.w):$(r),u=(u.substr(0,1) == '@')?$(t).attr(u.substring(1)):u;
+ r.html(c.ajaxText).load(u,function(){if(c.onLoad)c.onLoad.call(this,h);if(cc)h.w.jqmAddClose($(cc,h.w));e(h);});}
+ else if(cc)h.w.jqmAddClose($(cc,h.w));
+
+ if(c.toTop&&h.o)h.w.before('<span id="jqmP'+h.w[0]._jqm+'"></span>').insertAfter(h.o);
+ (c.onShow)?c.onShow(h):h.w.show();e(h);return F;
+},
+close:function(s){var h=H[s];if(!h.a)return F;h.a=F;
+ if(A[0]){A.pop();if(!A[0])L('unbind');}
+ if(h.c.toTop&&h.o)$('#jqmP'+h.w[0]._jqm).after(h.w).remove();
+ if(h.c.onHide)h.c.onHide(h);else{h.w.hide();if(h.o)h.o.remove();} return F;
+},
+params:{}};
+var s=0,H=$.jqm.hash,A=[],ie6=$.browser.msie&&($.browser.version == "6.0"),F=false,
+i=$('<iframe src="javascript:false;document.write(\'\');" class="jqm"></iframe>').css({opacity:0}),
+e=function(h){if(ie6)if(h.o)h.o.html('<p style="width:100%;height:100%"/>').prepend(i);else if(!$('iframe.jqm',h.w)[0])h.w.prepend(i); f(h);},
+f=function(h){try{$(':input:visible',h.w)[0].focus();}catch(_){}},
+L=function(t){$()[t]("keypress",m)[t]("keydown",m)[t]("mousedown",m);},
+m=function(e){var h=H[A[A.length-1]],r=(!$(e.target).parents('.jqmID'+h.s)[0]);if(r)f(h);return !r;},
+hs=function(w,t,c){return w.each(function(){var s=this._jqm;$(t).each(function() {
+ if(!this[c]){this[c]=[];$(this).click(function(){for(var i in {jqmShow:1,jqmHide:1})for(var s in this[i])if(H[this[i][s]])H[this[i][s]].w[i](this);return F;});}this[c].push(s);});});};
+})(jQuery); \ No newline at end of file
diff --git a/site/app/webroot/js/jquery-ui/jquery.dimensions.js b/site/app/webroot/js/jquery-ui/jquery.dimensions.js
new file mode 100644
index 0000000..b7e6f7e
--- /dev/null
+++ b/site/app/webroot/js/jquery-ui/jquery.dimensions.js
@@ -0,0 +1,116 @@
+/* Copyright (c) 2007 Paul Bakaus (paul.bakaus@googlemail.com) and Brandon Aaron (brandon.aaron@gmail.com || http://brandonaaron.net)
+ * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php)
+ * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.
+ *
+ * $LastChangedDate: 2007-09-11 02:38:31 +0000 (Tue, 11 Sep 2007) $
+ * $Rev: 3238 $
+ *
+ * Version: @VERSION
+ *
+ * Requires: jQuery 1.2+
+ */
+
+(function($){
+
+$.dimensions = {
+ version: '@VERSION'
+};
+
+// Create innerHeight, innerWidth, outerHeight and outerWidth methods
+$.each( [ 'Height', 'Width' ], function(i, name){
+
+ // innerHeight and innerWidth
+ $.fn[ 'inner' + name ] = function() {
+ if (!this[0]) return;
+
+ var torl = name == 'Height' ? 'Top' : 'Left', // top or left
+ borr = name == 'Height' ? 'Bottom' : 'Right'; // bottom or right
+
+ return this[ name.toLowerCase() ]() + num(this, 'padding' + torl) + num(this, 'padding' + borr);
+ };
+
+ // outerHeight and outerWidth
+ $.fn[ 'outer' + name ] = function(options) {
+ if (!this[0]) return;
+
+ var torl = name == 'Height' ? 'Top' : 'Left', // top or left
+ borr = name == 'Height' ? 'Bottom' : 'Right'; // bottom or right
+
+ options = $.extend({ margin: false }, options || {});
+
+ return this[ name.toLowerCase() ]()
+ + num(this, 'border' + torl + 'Width') + num(this, 'border' + borr + 'Width')
+ + num(this, 'padding' + torl) + num(this, 'padding' + borr)
+ + (options.margin ? (num(this, 'margin' + torl) + num(this, 'margin' + borr)) : 0);
+ };
+});
+
+// Create scrollLeft and scrollTop methods
+$.each( ['Left', 'Top'], function(i, name) {
+ $.fn[ 'scroll' + name ] = function(val) {
+ if (!this[0]) return;
+
+ return val != undefined ?
+
+ // Set the scroll offset
+ this.each(function() {
+ this == window || this == document ?
+ window.scrollTo(
+ name == 'Left' ? val : $(window)[ 'scrollLeft' ](),
+ name == 'Top' ? val : $(window)[ 'scrollTop' ]()
+ ) :
+ this[ 'scroll' + name ] = val;
+ }) :
+
+ // Return the scroll offset
+ this[0] == window || this[0] == document ?
+ self[ (name == 'Left' ? 'pageXOffset' : 'pageYOffset') ] ||
+ $.boxModel && document.documentElement[ 'scroll' + name ] ||
+ document.body[ 'scroll' + name ] :
+ this[0][ 'scroll' + name ];
+ };
+});
+
+$.fn.extend({
+ position: function() {
+ var left = 0, top = 0, elem = this[0], offset, parentOffset, offsetParent, results;
+
+ if (elem) {
+ // Get *real* offsetParent
+ offsetParent = this.offsetParent();
+
+ // Get correct offsets
+ offset = this.offset();
+ parentOffset = offsetParent.offset();
+
+ // Subtract element margins
+ offset.top -= num(elem, 'marginTop');
+ offset.left -= num(elem, 'marginLeft');
+
+ // Add offsetParent borders
+ parentOffset.top += num(offsetParent, 'borderTopWidth');
+ parentOffset.left += num(offsetParent, 'borderLeftWidth');
+
+ // Subtract the two offsets
+ results = {
+ top: offset.top - parentOffset.top,
+ left: offset.left - parentOffset.left
+ };
+ }
+
+ return results;
+ },
+
+ offsetParent: function() {
+ var offsetParent = this[0].offsetParent;
+ while ( offsetParent && (!/^body|html$/i.test(offsetParent.tagName) && $.css(offsetParent, 'position') == 'static') )
+ offsetParent = offsetParent.offsetParent;
+ return $(offsetParent);
+ }
+});
+
+var num = function(el, prop) {
+ return parseInt($.css(el.jquery?el[0]:el,prop))||0;
+};
+
+})(jQuery); \ No newline at end of file
diff --git a/site/app/webroot/js/jquery-ui/jquery.dimensions.min.js b/site/app/webroot/js/jquery-ui/jquery.dimensions.min.js
new file mode 100644
index 0000000..b841169
--- /dev/null
+++ b/site/app/webroot/js/jquery-ui/jquery.dimensions.min.js
@@ -0,0 +1,20 @@
+/* Copyright (c) 2007 Paul Bakaus (paul.bakaus@googlemail.com) and Brandon Aaron (brandon.aaron@gmail.com || http://brandonaaron.net)
+ * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php)
+ * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.
+ *
+ * $LastChangedDate: 2007-08-17 13:14:11 -0500 (Fri, 17 Aug 2007) $
+ * $Rev: 2759 $
+ *
+ * Version: 1.1.2
+ *
+ * Requires: jQuery 1.1.3+
+ */
+(function($){var height=$.fn.height,width=$.fn.width;$.fn.extend({height:function(){if(!this[0])error();if(this[0]==window)if($.browser.opera||($.browser.safari&&parseInt($.browser.version)>520))return self.innerHeight-(($(document).height()>self.innerHeight)?getScrollbarWidth():0);else if($.browser.safari)return self.innerHeight;else
+return $.boxModel&&document.documentElement.clientHeight||document.body.clientHeight;if(this[0]==document)return Math.max(($.boxModel&&document.documentElement.scrollHeight||document.body.scrollHeight),document.body.offsetHeight);return height.apply(this,arguments);},width:function(){if(!this[0])error();if(this[0]==window)if($.browser.opera||($.browser.safari&&parseInt($.browser.version)>520))return self.innerWidth-(($(document).width()>self.innerWidth)?getScrollbarWidth():0);else if($.browser.safari)return self.innerWidth;else
+return $.boxModel&&document.documentElement.clientWidth||document.body.clientWidth;if(this[0]==document)if($.browser.mozilla){var scrollLeft=self.pageXOffset;self.scrollTo(99999999,self.pageYOffset);var scrollWidth=self.pageXOffset;self.scrollTo(scrollLeft,self.pageYOffset);return document.body.offsetWidth+scrollWidth;}else
+return Math.max((($.boxModel&&!$.browser.safari)&&document.documentElement.scrollWidth||document.body.scrollWidth),document.body.offsetWidth);return width.apply(this,arguments);},innerHeight:function(){if(!this[0])error();return this[0]==window||this[0]==document?this.height():this.is(':visible')?this[0].offsetHeight-num(this,'borderTopWidth')-num(this,'borderBottomWidth'):this.height()+num(this,'paddingTop')+num(this,'paddingBottom');},innerWidth:function(){if(!this[0])error();return this[0]==window||this[0]==document?this.width():this.is(':visible')?this[0].offsetWidth-num(this,'borderLeftWidth')-num(this,'borderRightWidth'):this.width()+num(this,'paddingLeft')+num(this,'paddingRight');},outerHeight:function(options){if(!this[0])error();options=$.extend({margin:false},options||{});return this[0]==window||this[0]==document?this.height():this.is(':visible')?this[0].offsetHeight+(options.margin?(num(this,'marginTop')+num(this,'marginBottom')):0):this.height()+num(this,'borderTopWidth')+num(this,'borderBottomWidth')+num(this,'paddingTop')+num(this,'paddingBottom')+(options.margin?(num(this,'marginTop')+num(this,'marginBottom')):0);},outerWidth:function(options){if(!this[0])error();options=$.extend({margin:false},options||{});return this[0]==window||this[0]==document?this.width():this.is(':visible')?this[0].offsetWidth+(options.margin?(num(this,'marginLeft')+num(this,'marginRight')):0):this.width()+num(this,'borderLeftWidth')+num(this,'borderRightWidth')+num(this,'paddingLeft')+num(this,'paddingRight')+(options.margin?(num(this,'marginLeft')+num(this,'marginRight')):0);},scrollLeft:function(val){if(!this[0])error();if(val!=undefined)return this.each(function(){if(this==window||this==document)window.scrollTo(val,$(window).scrollTop());else
+this.scrollLeft=val;});if(this[0]==window||this[0]==document)return self.pageXOffset||$.boxModel&&document.documentElement.scrollLeft||document.body.scrollLeft;return this[0].scrollLeft;},scrollTop:function(val){if(!this[0])error();if(val!=undefined)return this.each(function(){if(this==window||this==document)window.scrollTo($(window).scrollLeft(),val);else
+this.scrollTop=val;});if(this[0]==window||this[0]==document)return self.pageYOffset||$.boxModel&&document.documentElement.scrollTop||document.body.scrollTop;return this[0].scrollTop;},position:function(returnObject){return this.offset({margin:false,scroll:false,relativeTo:this.offsetParent()},returnObject);},offset:function(options,returnObject){if(!this[0])error();var x=0,y=0,sl=0,st=0,elem=this[0],parent=this[0],op,parPos,elemPos=$.css(elem,'position'),mo=$.browser.mozilla,ie=$.browser.msie,oa=$.browser.opera,sf=$.browser.safari,sf3=$.browser.safari&&parseInt($.browser.version)>520,absparent=false,relparent=false,options=$.extend({margin:true,border:false,padding:false,scroll:true,lite:false,relativeTo:document.body},options||{});if(options.lite)return this.offsetLite(options,returnObject);if(options.relativeTo.jquery)options.relativeTo=options.relativeTo[0];if(elem.tagName=='BODY'){x=elem.offsetLeft;y=elem.offsetTop;if(mo){x+=num(elem,'marginLeft')+(num(elem,'borderLeftWidth')*2);y+=num(elem,'marginTop')+(num(elem,'borderTopWidth')*2);}else
+if(oa){x+=num(elem,'marginLeft');y+=num(elem,'marginTop');}else
+if((ie&&jQuery.boxModel)){x+=num(elem,'borderLeftWidth');y+=num(elem,'borderTopWidth');}else
+if(sf3){x+=num(elem,'marginLeft')+num(elem,'borderLeftWidth');y+=num(elem,'marginTop')+num(elem,'borderTopWidth');}}else{do{parPos=$.css(parent,'position');x+=parent.offsetLeft;y+=parent.offsetTop;if((mo&&!parent.tagName.match(/^t[d|h]$/i))||ie||sf3){x+=num(parent,'borderLeftWidth');y+=num(parent,'borderTopWidth');if(mo&&parPos=='absolute')absparent=true;if(ie&&parPos=='relative')relparent=true;}op=parent.offsetParent||document.body;if(options.scroll||mo){do{if(options.scroll){sl+=parent.scrollLeft;st+=parent.scrollTop;}if(oa&&($.css(parent,'display')||'').match(/table-row|inline/)){sl=sl-((parent.scrollLeft==parent.offsetLeft)?parent.scrollLeft:0);st=st-((parent.scrollTop==parent.offsetTop)?parent.scrollTop:0);}if(mo&&parent!=elem&&$.css(parent,'overflow')!='visible'){x+=num(parent,'borderLeftWidth');y+=num(parent,'borderTopWidth');}parent=parent.parentNode;}while(parent!=op);}parent=op;if(parent==options.relativeTo&&!(parent.tagName=='BODY'||parent.tagName=='HTML')){if(mo&&parent!=elem&&$.css(parent,'overflow')!='visible'){x+=num(parent,'borderLeftWidth');y+=num(parent,'borderTopWidth');}if(((sf&&!sf3)||oa)&&parPos!='static'){x-=num(op,'borderLeftWidth');y-=num(op,'borderTopWidth');}break;}if(parent.tagName=='BODY'||parent.tagName=='HTML'){if(((sf&&!sf3)||(ie&&$.boxModel))&&elemPos!='absolute'&&elemPos!='fixed'){x+=num(parent,'marginLeft');y+=num(parent,'marginTop');}if(sf3||(mo&&!absparent&&elemPos!='fixed')||(ie&&elemPos=='static'&&!relparent)){x+=num(parent,'borderLeftWidth');y+=num(parent,'borderTopWidth');}break;}}while(parent);}var returnValue=handleOffsetReturn(elem,options,x,y,sl,st);if(returnObject){$.extend(returnObject,returnValue);return this;}else{return returnValue;}},offsetLite:function(options,returnObject){if(!this[0])error();var x=0,y=0,sl=0,st=0,parent=this[0],offsetParent,options=$.extend({margin:true,border:false,padding:false,scroll:true,relativeTo:document.body},options||{});if(options.relativeTo.jquery)options.relativeTo=options.relativeTo[0];do{x+=parent.offsetLeft;y+=parent.offsetTop;offsetParent=parent.offsetParent||document.body;if(options.scroll){do{sl+=parent.scrollLeft;st+=parent.scrollTop;parent=parent.parentNode;}while(parent!=offsetParent);}parent=offsetParent;}while(parent&&parent.tagName!='BODY'&&parent.tagName!='HTML'&&parent!=options.relativeTo);var returnValue=handleOffsetReturn(this[0],options,x,y,sl,st);if(returnObject){$.extend(returnObject,returnValue);return this;}else{return returnValue;}},offsetParent:function(){if(!this[0])error();var offsetParent=this[0].offsetParent;while(offsetParent&&(offsetParent.tagName!='BODY'&&$.css(offsetParent,'position')=='static'))offsetParent=offsetParent.offsetParent;return $(offsetParent);}});var error=function(){throw"Dimensions: jQuery collection is empty";};var num=function(el,prop){return parseInt($.css(el.jquery?el[0]:el,prop))||0;};var handleOffsetReturn=function(elem,options,x,y,sl,st){if(!options.margin){x-=num(elem,'marginLeft');y-=num(elem,'marginTop');}if(options.border&&(($.browser.safari&&parseInt($.browser.version)<520)||$.browser.opera)){x+=num(elem,'borderLeftWidth');y+=num(elem,'borderTopWidth');}else if(!options.border&&!(($.browser.safari&&parseInt($.browser.version)<520)||$.browser.opera)){x-=num(elem,'borderLeftWidth');y-=num(elem,'borderTopWidth');}if(options.padding){x+=num(elem,'paddingLeft');y+=num(elem,'paddingTop');}if(options.scroll&&(!$.browser.opera||elem.offsetLeft!=elem.scrollLeft&&elem.offsetTop!=elem.scrollLeft)){sl-=elem.scrollLeft;st-=elem.scrollTop;}return options.scroll?{top:y-st,left:x-sl,scrollTop:st,scrollLeft:sl}:{top:y,left:x};};var scrollbarWidth=0;var getScrollbarWidth=function(){if(!scrollbarWidth){var testEl=$('<div>').css({width:100,height:100,overflow:'auto',position:'absolute',top:-1000,left:-1000}).appendTo('body');scrollbarWidth=100-testEl.append('<div>').find('div').css({width:'100%',height:200}).width();testEl.remove();}return scrollbarWidth;};})(jQuery); \ No newline at end of file
diff --git a/site/app/webroot/js/jquery-ui/jquery.ui.all.min.js b/site/app/webroot/js/jquery-ui/jquery.ui.all.min.js
new file mode 100755
index 0000000..c0795b4
--- /dev/null
+++ b/site/app/webroot/js/jquery-ui/jquery.ui.all.min.js
@@ -0,0 +1 @@
+(function(D){var C=D.fn.remove;D.fn.remove=function(){D("*",this).add(this).triggerHandler("remove");return C.apply(this,arguments)};function B(E){function G(H){var I=H.style;return(I.display!="none"&&I.visibility!="hidden")}var F=G(E);(F&&D.each(D.dir(E,"parentNode"),function(){return(F=G(this))}));return F}D.extend(D.expr[":"],{data:function(F,G,E){return D.data(F,E[3])},tabbable:function(F,G,E){var H=F.nodeName.toLowerCase();return(F.tabIndex>=0&&(("a"==H&&F.href)||(/input|select|textarea|button/.test(H)&&"hidden"!=F.type&&!F.disabled))&&B(F))}});D.keyCode={BACKSPACE:8,CAPS_LOCK:20,COMMA:188,CONTROL:17,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,INSERT:45,LEFT:37,NUMPAD_ADD:107,NUMPAD_DECIMAL:110,NUMPAD_DIVIDE:111,NUMPAD_ENTER:108,NUMPAD_MULTIPLY:106,NUMPAD_SUBTRACT:109,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SHIFT:16,SPACE:32,TAB:9,UP:38};function A(H,I,J,G){function F(L){var K=D[H][I][L]||[];return(typeof K=="string"?K.split(/,?\s+/):K)}var E=F("getter");if(G.length==1&&typeof G[0]=="string"){E=E.concat(F("getterSetter"))}return(D.inArray(J,E)!=-1)}D.widget=function(F,E){var G=F.split(".")[0];F=F.split(".")[1];D.fn[F]=function(K){var I=(typeof K=="string"),J=Array.prototype.slice.call(arguments,1);if(I&&K.substring(0,1)=="_"){return this}if(I&&A(G,F,K,J)){var H=D.data(this[0],F);return(H?H[K].apply(H,J):undefined)}return this.each(function(){var L=D.data(this,F);(!L&&!I&&D.data(this,F,new D[G][F](this,K)));(L&&I&&D.isFunction(L[K])&&L[K].apply(L,J))})};D[G][F]=function(J,I){var H=this;this.widgetName=F;this.widgetEventPrefix=D[G][F].eventPrefix||F;this.widgetBaseClass=G+"-"+F;this.options=D.extend({},D.widget.defaults,D[G][F].defaults,D.metadata&&D.metadata.get(J)[F],I);this.element=D(J).bind("setData."+F,function(M,K,L){return H._setData(K,L)}).bind("getData."+F,function(L,K){return H._getData(K)}).bind("remove",function(){return H.destroy()});this._init()};D[G][F].prototype=D.extend({},D.widget.prototype,E);D[G][F].getterSetter="option"};D.widget.prototype={_init:function(){},destroy:function(){this.element.removeData(this.widgetName)},option:function(G,H){var F=G,E=this;if(typeof G=="string"){if(H===undefined){return this._getData(G)}F={};F[G]=H}D.each(F,function(I,J){E._setData(I,J)})},_getData:function(E){return this.options[E]},_setData:function(E,F){this.options[E]=F;if(E=="disabled"){this.element[F?"addClass":"removeClass"](this.widgetBaseClass+"-disabled")}},enable:function(){this._setData("disabled",false)},disable:function(){this._setData("disabled",true)},_trigger:function(F,H,G){var E=(F==this.widgetEventPrefix?F:this.widgetEventPrefix+F);H=H||D.event.fix({type:E,target:this.element[0]});return this.element.triggerHandler(E,[H,G],this.options[F])}};D.widget.defaults={disabled:false};D.ui={plugin:{add:function(F,G,I){var H=D.ui[F].prototype;for(var E in I){H.plugins[E]=H.plugins[E]||[];H.plugins[E].push([G,I[E]])}},call:function(E,G,F){var I=E.plugins[G];if(!I){return }for(var H=0;H<I.length;H++){if(E.options[I[H][0]]){I[H][1].apply(E.element,F)}}}},cssCache:{},css:function(E){if(D.ui.cssCache[E]){return D.ui.cssCache[E]}var F=D('<div class="ui-gen">').addClass(E).css({position:"absolute",top:"-5000px",left:"-5000px",display:"block"}).appendTo("body");D.ui.cssCache[E]=!!((!(/auto|default/).test(F.css("cursor"))||(/^[1-9]/).test(F.css("height"))||(/^[1-9]/).test(F.css("width"))||!(/none/).test(F.css("backgroundImage"))||!(/transparent|rgba\(0, 0, 0, 0\)/).test(F.css("backgroundColor"))));try{D("body").get(0).removeChild(F.get(0))}catch(G){}return D.ui.cssCache[E]},disableSelection:function(E){return D(E).attr("unselectable","on").css("MozUserSelect","none").bind("selectstart.ui",function(){return false})},enableSelection:function(E){return D(E).attr("unselectable","off").css("MozUserSelect","").unbind("selectstart.ui")},hasScroll:function(H,F){if(D(H).css("overflow")=="hidden"){return false}var E=(F&&F=="left")?"scrollLeft":"scrollTop",G=false;if(H[E]>0){return true}H[E]=1;G=(H[E]>0);H[E]=0;return G}};D.ui.mouse={_mouseInit:function(){var E=this;this.element.bind("mousedown."+this.widgetName,function(F){return E._mouseDown(F)});if(D.browser.msie){this._mouseUnselectable=this.element.attr("unselectable");this.element.attr("unselectable","on")}this.started=false},_mouseDestroy:function(){this.element.unbind("."+this.widgetName);(D.browser.msie&&this.element.attr("unselectable",this._mouseUnselectable))},_mouseDown:function(G){(this._mouseStarted&&this._mouseUp(G));this._mouseDownEvent=G;var F=this,H=(G.which==1),E=(typeof this.options.cancel=="string"?D(G.target).parents().add(G.target).filter(this.options.cancel).length:false);if(!H||E||!this._mouseCapture(G)){return true}this.mouseDelayMet=!this.options.delay;if(!this.mouseDelayMet){this._mouseDelayTimer=setTimeout(function(){F.mouseDelayMet=true},this.options.delay)}if(this._mouseDistanceMet(G)&&this._mouseDelayMet(G)){this._mouseStarted=(this._mouseStart(G)!==false);if(!this._mouseStarted){G.preventDefault();return true}}this._mouseMoveDelegate=function(I){return F._mouseMove(I)};this._mouseUpDelegate=function(I){return F._mouseUp(I)};D(document).bind("mousemove."+this.widgetName,this._mouseMoveDelegate).bind("mouseup."+this.widgetName,this._mouseUpDelegate);return false},_mouseMove:function(E){if(D.browser.msie&&!E.button){return this._mouseUp(E)}if(this._mouseStarted){this._mouseDrag(E);return false}if(this._mouseDistanceMet(E)&&this._mouseDelayMet(E)){this._mouseStarted=(this._mouseStart(this._mouseDownEvent,E)!==false);(this._mouseStarted?this._mouseDrag(E):this._mouseUp(E))}return !this._mouseStarted},_mouseUp:function(E){D(document).unbind("mousemove."+this.widgetName,this._mouseMoveDelegate).unbind("mouseup."+this.widgetName,this._mouseUpDelegate);if(this._mouseStarted){this._mouseStarted=false;this._mouseStop(E)}return false},_mouseDistanceMet:function(E){return(Math.max(Math.abs(this._mouseDownEvent.pageX-E.pageX),Math.abs(this._mouseDownEvent.pageY-E.pageY))>=this.options.distance)},_mouseDelayMet:function(E){return this.mouseDelayMet},_mouseStart:function(E){},_mouseDrag:function(E){},_mouseStop:function(E){},_mouseCapture:function(E){return true}};D.ui.mouse.defaults={cancel:null,distance:1,delay:0}})(jQuery);(function(A){A.widget("ui.draggable",A.extend({},A.ui.mouse,{getHandle:function(C){var B=!this.options.handle||!A(this.options.handle,this.element).length?true:false;A(this.options.handle,this.element).find("*").andSelf().each(function(){if(this==C.target){B=true}});return B},createHelper:function(){var C=this.options;var B=A.isFunction(C.helper)?A(C.helper.apply(this.element[0],[e])):(C.helper=="clone"?this.element.clone():this.element);if(!B.parents("body").length){B.appendTo((C.appendTo=="parent"?this.element[0].parentNode:C.appendTo))}if(B[0]!=this.element[0]&&!(/(fixed|absolute)/).test(B.css("position"))){B.css("position","absolute")}return B},_init:function(){if(this.options.helper=="original"&&!(/^(?:r|a|f)/).test(this.element.css("position"))){this.element[0].style.position="relative"}(this.options.cssNamespace&&this.element.addClass(this.options.cssNamespace+"-draggable"));(this.options.disabled&&this.element.addClass("ui-draggable-disabled"));this._mouseInit()},_mouseCapture:function(B){var C=this.options;if(this.helper||C.disabled||A(B.target).is(".ui-resizable-handle")){return false}this.handle=this.getHandle(B);if(!this.handle){return false}return true},_mouseStart:function(D){var E=this.options;this.helper=this.createHelper();if(A.ui.ddmanager){A.ui.ddmanager.current=this}this.margins={left:(parseInt(this.element.css("marginLeft"),10)||0),top:(parseInt(this.element.css("marginTop"),10)||0)};this.cssPosition=this.helper.css("position");this.offset=this.element.offset();this.offset={top:this.offset.top-this.margins.top,left:this.offset.left-this.margins.left};this.offset.click={left:D.pageX-this.offset.left,top:D.pageY-this.offset.top};this.cacheScrollParents();this.offsetParent=this.helper.offsetParent();var B=this.offsetParent.offset();if(this.offsetParent[0]==document.body&&A.browser.mozilla){B={top:0,left:0}}this.offset.parent={top:B.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:B.left+(parseInt(this.offsetParent.css("borderLeftWidth"),10)||0)};if(this.cssPosition=="relative"){var C=this.element.position();this.offset.relative={top:C.top-(parseInt(this.helper.css("top"),10)||0)+this.scrollTopParent.scrollTop(),left:C.left-(parseInt(this.helper.css("left"),10)||0)+this.scrollLeftParent.scrollLeft()}}else{this.offset.relative={top:0,left:0}}this.originalPosition=this._generatePosition(D);this.cacheHelperProportions();if(E.cursorAt){this.adjustOffsetFromHelper(E.cursorAt)}A.extend(this,{PAGEY_INCLUDES_SCROLL:(this.cssPosition=="absolute"&&(!this.scrollTopParent[0].tagName||(/(html|body)/i).test(this.scrollTopParent[0].tagName))),PAGEX_INCLUDES_SCROLL:(this.cssPosition=="absolute"&&(!this.scrollLeftParent[0].tagName||(/(html|body)/i).test(this.scrollLeftParent[0].tagName))),OFFSET_PARENT_NOT_SCROLL_PARENT_Y:this.scrollTopParent[0]!=this.offsetParent[0]&&!(this.scrollTopParent[0]==document&&(/(body|html)/i).test(this.offsetParent[0].tagName)),OFFSET_PARENT_NOT_SCROLL_PARENT_X:this.scrollLeftParent[0]!=this.offsetParent[0]&&!(this.scrollLeftParent[0]==document&&(/(body|html)/i).test(this.offsetParent[0].tagName))});if(E.containment){this.setContainment()}this._propagate("start",D);this.cacheHelperProportions();if(A.ui.ddmanager&&!E.dropBehaviour){A.ui.ddmanager.prepareOffsets(this,D)}this.helper.addClass("ui-draggable-dragging");this._mouseDrag(D);return true},cacheScrollParents:function(){this.scrollTopParent=function(B){do{if(/auto|scroll/.test(B.css("overflow"))||(/auto|scroll/).test(B.css("overflow-y"))){return B}B=B.parent()}while(B[0].parentNode);return A(document)}(this.helper);this.scrollLeftParent=function(B){do{if(/auto|scroll/.test(B.css("overflow"))||(/auto|scroll/).test(B.css("overflow-x"))){return B}B=B.parent()}while(B[0].parentNode);return A(document)}(this.helper)},adjustOffsetFromHelper:function(B){if(B.left!=undefined){this.offset.click.left=B.left+this.margins.left}if(B.right!=undefined){this.offset.click.left=this.helperProportions.width-B.right+this.margins.left}if(B.top!=undefined){this.offset.click.top=B.top+this.margins.top}if(B.bottom!=undefined){this.offset.click.top=this.helperProportions.height-B.bottom+this.margins.top}},cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(),height:this.helper.outerHeight()}},setContainment:function(){var E=this.options;if(E.containment=="parent"){E.containment=this.helper[0].parentNode}if(E.containment=="document"||E.containment=="window"){this.containment=[0-this.offset.relative.left-this.offset.parent.left,0-this.offset.relative.top-this.offset.parent.top,A(E.containment=="document"?document:window).width()-this.offset.relative.left-this.offset.parent.left-this.helperProportions.width-this.margins.left-(parseInt(this.element.css("marginRight"),10)||0),(A(E.containment=="document"?document:window).height()||document.body.parentNode.scrollHeight)-this.offset.relative.top-this.offset.parent.top-this.helperProportions.height-this.margins.top-(parseInt(this.element.css("marginBottom"),10)||0)]}if(!(/^(document|window|parent)$/).test(E.containment)){var C=A(E.containment)[0];var D=A(E.containment).offset();var B=(A(C).css("overflow")!="hidden");this.containment=[D.left+(parseInt(A(C).css("borderLeftWidth"),10)||0)-this.offset.relative.left-this.offset.parent.left,D.top+(parseInt(A(C).css("borderTopWidth"),10)||0)-this.offset.relative.top-this.offset.parent.top,D.left+(B?Math.max(C.scrollWidth,C.offsetWidth):C.offsetWidth)-(parseInt(A(C).css("borderLeftWidth"),10)||0)-this.offset.relative.left-this.offset.parent.left-this.helperProportions.width-this.margins.left-(parseInt(this.element.css("marginRight"),10)||0),D.top+(B?Math.max(C.scrollHeight,C.offsetHeight):C.offsetHeight)-(parseInt(A(C).css("borderTopWidth"),10)||0)-this.offset.relative.top-this.offset.parent.top-this.helperProportions.height-this.margins.top-(parseInt(this.element.css("marginBottom"),10)||0)]}},_convertPositionTo:function(C,D){if(!D){D=this.position}var B=C=="absolute"?1:-1;return{top:(D.top+this.offset.relative.top*B+this.offset.parent.top*B-(this.cssPosition=="fixed"||this.PAGEY_INCLUDES_SCROLL||this.OFFSET_PARENT_NOT_SCROLL_PARENT_Y?0:this.scrollTopParent.scrollTop())*B+(this.cssPosition=="fixed"?A(document).scrollTop():0)*B+this.margins.top*B),left:(D.left+this.offset.relative.left*B+this.offset.parent.left*B-(this.cssPosition=="fixed"||this.PAGEX_INCLUDES_SCROLL||this.OFFSET_PARENT_NOT_SCROLL_PARENT_X?0:this.scrollLeftParent.scrollLeft())*B+(this.cssPosition=="fixed"?A(document).scrollLeft():0)*B+this.margins.left*B)}},_generatePosition:function(E){var F=this.options;var B={top:(E.pageY-this.offset.click.top-this.offset.relative.top-this.offset.parent.top+(this.cssPosition=="fixed"||this.PAGEY_INCLUDES_SCROLL||this.OFFSET_PARENT_NOT_SCROLL_PARENT_Y?0:this.scrollTopParent.scrollTop())-(this.cssPosition=="fixed"?A(document).scrollTop():0)),left:(E.pageX-this.offset.click.left-this.offset.relative.left-this.offset.parent.left+(this.cssPosition=="fixed"||this.PAGEX_INCLUDES_SCROLL||this.OFFSET_PARENT_NOT_SCROLL_PARENT_X?0:this.scrollLeftParent.scrollLeft())-(this.cssPosition=="fixed"?A(document).scrollLeft():0))};if(!this.originalPosition){return B}if(this.containment){if(B.left<this.containment[0]){B.left=this.containment[0]}if(B.top<this.containment[1]){B.top=this.containment[1]}if(B.left>this.containment[2]){B.left=this.containment[2]}if(B.top>this.containment[3]){B.top=this.containment[3]}}if(F.grid){var D=this.originalPosition.top+Math.round((B.top-this.originalPosition.top)/F.grid[1])*F.grid[1];B.top=this.containment?(!(D<this.containment[1]||D>this.containment[3])?D:(!(D<this.containment[1])?D-F.grid[1]:D+F.grid[1])):D;var C=this.originalPosition.left+Math.round((B.left-this.originalPosition.left)/F.grid[0])*F.grid[0];B.left=this.containment?(!(C<this.containment[0]||C>this.containment[2])?C:(!(C<this.containment[0])?C-F.grid[0]:C+F.grid[0])):C}return B},_mouseDrag:function(B){this.position=this._generatePosition(B);this.positionAbs=this._convertPositionTo("absolute");this.position=this._propagate("drag",B)||this.position;if(!this.options.axis||this.options.axis!="y"){this.helper[0].style.left=this.position.left+"px"}if(!this.options.axis||this.options.axis!="x"){this.helper[0].style.top=this.position.top+"px"}if(A.ui.ddmanager){A.ui.ddmanager.drag(this,B)}return false},_mouseStop:function(C){var D=false;if(A.ui.ddmanager&&!this.options.dropBehaviour){var D=A.ui.ddmanager.drop(this,C)}if((this.options.revert=="invalid"&&!D)||(this.options.revert=="valid"&&D)||this.options.revert===true||(A.isFunction(this.options.revert)&&this.options.revert.call(this.element,D))){var B=this;A(this.helper).animate(this.originalPosition,parseInt(this.options.revertDuration,10)||500,function(){B._propagate("stop",C);B._clear()})}else{this._propagate("stop",C);this._clear()}return false},_clear:function(){this.helper.removeClass("ui-draggable-dragging");if(this.options.helper!="original"&&!this.cancelHelperRemoval){this.helper.remove()}this.helper=null;this.cancelHelperRemoval=false},plugins:{},uiHash:function(B){return{helper:this.helper,position:this.position,absolutePosition:this.positionAbs,options:this.options}},_propagate:function(C,B){A.ui.plugin.call(this,C,[B,this.uiHash()]);if(C=="drag"){this.positionAbs=this._convertPositionTo("absolute")}return this.element.triggerHandler(C=="drag"?C:"drag"+C,[B,this.uiHash()],this.options[C])},destroy:function(){if(!this.element.data("draggable")){return }this.element.removeData("draggable").unbind(".draggable").removeClass("ui-draggable ui-draggable-dragging ui-draggable-disabled");this._mouseDestroy()}}));A.extend(A.ui.draggable,{defaults:{appendTo:"parent",axis:false,cancel:":input",delay:0,distance:1,helper:"original",scope:"default",cssNamespace:"ui"}});A.ui.plugin.add("draggable","cursor",{start:function(D,C){var B=A("body");if(B.css("cursor")){C.options._cursor=B.css("cursor")}B.css("cursor",C.options.cursor)},stop:function(C,B){if(B.options._cursor){A("body").css("cursor",B.options._cursor)}}});A.ui.plugin.add("draggable","zIndex",{start:function(D,C){var B=A(C.helper);if(B.css("zIndex")){C.options._zIndex=B.css("zIndex")}B.css("zIndex",C.options.zIndex)},stop:function(C,B){if(B.options._zIndex){A(B.helper).css("zIndex",B.options._zIndex)}}});A.ui.plugin.add("draggable","opacity",{start:function(D,C){var B=A(C.helper);if(B.css("opacity")){C.options._opacity=B.css("opacity")}B.css("opacity",C.options.opacity)},stop:function(C,B){if(B.options._opacity){A(B.helper).css("opacity",B.options._opacity)}}});A.ui.plugin.add("draggable","iframeFix",{start:function(C,B){A(B.options.iframeFix===true?"iframe":B.options.iframeFix).each(function(){A('<div class="ui-draggable-iframeFix" style="background: #fff;"></div>').css({width:this.offsetWidth+"px",height:this.offsetHeight+"px",position:"absolute",opacity:"0.001",zIndex:1000}).css(A(this).offset()).appendTo("body")})},stop:function(C,B){A("div.ui-draggable-iframeFix").each(function(){this.parentNode.removeChild(this)})}});A.ui.plugin.add("draggable","scroll",{start:function(D,C){var E=C.options;var B=A(this).data("draggable");E.scrollSensitivity=E.scrollSensitivity||20;E.scrollSpeed=E.scrollSpeed||20;B.overflowY=function(F){do{if(/auto|scroll/.test(F.css("overflow"))||(/auto|scroll/).test(F.css("overflow-y"))){return F}F=F.parent()}while(F[0].parentNode);return A(document)}(this);B.overflowX=function(F){do{if(/auto|scroll/.test(F.css("overflow"))||(/auto|scroll/).test(F.css("overflow-x"))){return F}F=F.parent()}while(F[0].parentNode);return A(document)}(this);if(B.overflowY[0]!=document&&B.overflowY[0].tagName!="HTML"){B.overflowYOffset=B.overflowY.offset()}if(B.overflowX[0]!=document&&B.overflowX[0].tagName!="HTML"){B.overflowXOffset=B.overflowX.offset()}},drag:function(E,D){var F=D.options,B=false;var C=A(this).data("draggable");if(C.overflowY[0]!=document&&C.overflowY[0].tagName!="HTML"){if((C.overflowYOffset.top+C.overflowY[0].offsetHeight)-E.pageY<F.scrollSensitivity){C.overflowY[0].scrollTop=B=C.overflowY[0].scrollTop+F.scrollSpeed}if(E.pageY-C.overflowYOffset.top<F.scrollSensitivity){C.overflowY[0].scrollTop=B=C.overflowY[0].scrollTop-F.scrollSpeed}}else{if(E.pageY-A(document).scrollTop()<F.scrollSensitivity){B=A(document).scrollTop(A(document).scrollTop()-F.scrollSpeed)}if(A(window).height()-(E.pageY-A(document).scrollTop())<F.scrollSensitivity){B=A(document).scrollTop(A(document).scrollTop()+F.scrollSpeed)}}if(C.overflowX[0]!=document&&C.overflowX[0].tagName!="HTML"){if((C.overflowXOffset.left+C.overflowX[0].offsetWidth)-E.pageX<F.scrollSensitivity){C.overflowX[0].scrollLeft=B=C.overflowX[0].scrollLeft+F.scrollSpeed}if(E.pageX-C.overflowXOffset.left<F.scrollSensitivity){C.overflowX[0].scrollLeft=B=C.overflowX[0].scrollLeft-F.scrollSpeed}}else{if(E.pageX-A(document).scrollLeft()<F.scrollSensitivity){B=A(document).scrollLeft(A(document).scrollLeft()-F.scrollSpeed)}if(A(window).width()-(E.pageX-A(document).scrollLeft())<F.scrollSensitivity){B=A(document).scrollLeft(A(document).scrollLeft()+F.scrollSpeed)}}if(B!==false){A.ui.ddmanager.prepareOffsets(C,E)}}});A.ui.plugin.add("draggable","snap",{start:function(D,C){var B=A(this).data("draggable");B.snapElements=[];A(C.options.snap.constructor!=String?(C.options.snap.items||":data(draggable)"):C.options.snap).each(function(){var F=A(this);var E=F.offset();if(this!=B.element[0]){B.snapElements.push({item:this,width:F.outerWidth(),height:F.outerHeight(),top:E.top,left:E.left})}})},drag:function(P,K){var E=A(this).data("draggable");var Q=K.options.snapTolerance||20;var O=K.absolutePosition.left,N=O+E.helperProportions.width,D=K.absolutePosition.top,C=D+E.helperProportions.height;for(var M=E.snapElements.length-1;M>=0;M--){var L=E.snapElements[M].left,J=L+E.snapElements[M].width,I=E.snapElements[M].top,S=I+E.snapElements[M].height;if(!((L-Q<O&&O<J+Q&&I-Q<D&&D<S+Q)||(L-Q<O&&O<J+Q&&I-Q<C&&C<S+Q)||(L-Q<N&&N<J+Q&&I-Q<D&&D<S+Q)||(L-Q<N&&N<J+Q&&I-Q<C&&C<S+Q))){if(E.snapElements[M].snapping){(E.options.snap.release&&E.options.snap.release.call(E.element,null,A.extend(E.uiHash(),{snapItem:E.snapElements[M].item})))}E.snapElements[M].snapping=false;continue}if(K.options.snapMode!="inner"){var B=Math.abs(I-C)<=Q;var R=Math.abs(S-D)<=Q;var G=Math.abs(L-N)<=Q;var H=Math.abs(J-O)<=Q;if(B){K.position.top=E._convertPositionTo("relative",{top:I-E.helperProportions.height,left:0}).top}if(R){K.position.top=E._convertPositionTo("relative",{top:S,left:0}).top}if(G){K.position.left=E._convertPositionTo("relative",{top:0,left:L-E.helperProportions.width}).left}if(H){K.position.left=E._convertPositionTo("relative",{top:0,left:J}).left}}var F=(B||R||G||H);if(K.options.snapMode!="outer"){var B=Math.abs(I-D)<=Q;var R=Math.abs(S-C)<=Q;var G=Math.abs(L-O)<=Q;var H=Math.abs(J-N)<=Q;if(B){K.position.top=E._convertPositionTo("relative",{top:I,left:0}).top}if(R){K.position.top=E._convertPositionTo("relative",{top:S-E.helperProportions.height,left:0}).top}if(G){K.position.left=E._convertPositionTo("relative",{top:0,left:L}).left}if(H){K.position.left=E._convertPositionTo("relative",{top:0,left:J-E.helperProportions.width}).left}}if(!E.snapElements[M].snapping&&(B||R||G||H||F)){(E.options.snap.snap&&E.options.snap.snap.call(E.element,null,A.extend(E.uiHash(),{snapItem:E.snapElements[M].item})))}E.snapElements[M].snapping=(B||R||G||H||F)}}});A.ui.plugin.add("draggable","connectToSortable",{start:function(D,C){var B=A(this).data("draggable");B.sortables=[];A(C.options.connectToSortable).each(function(){if(A.data(this,"sortable")){var E=A.data(this,"sortable");B.sortables.push({instance:E,shouldRevert:E.options.revert});E._refreshItems();E._propagate("activate",D,B)}})},stop:function(D,C){var B=A(this).data("draggable");A.each(B.sortables,function(){if(this.instance.isOver){this.instance.isOver=0;B.cancelHelperRemoval=true;this.instance.cancelHelperRemoval=false;if(this.shouldRevert){this.instance.options.revert=true}this.instance._mouseStop(D);this.instance.element.triggerHandler("sortreceive",[D,A.extend(this.instance.ui(),{sender:B.element})],this.instance.options["receive"]);this.instance.options.helper=this.instance.options._helper}else{this.instance._propagate("deactivate",D,B)}})},drag:function(F,E){var D=A(this).data("draggable"),B=this;var C=function(K){var H=K.left,J=H+K.width,I=K.top,G=I+K.height;return(H<(this.positionAbs.left+this.offset.click.left)&&(this.positionAbs.left+this.offset.click.left)<J&&I<(this.positionAbs.top+this.offset.click.top)&&(this.positionAbs.top+this.offset.click.top)<G)};A.each(D.sortables,function(G){if(C.call(D,this.instance.containerCache)){if(!this.instance.isOver){this.instance.isOver=1;this.instance.currentItem=A(B).clone().appendTo(this.instance.element).data("sortable-item",true);this.instance.options._helper=this.instance.options.helper;this.instance.options.helper=function(){return E.helper[0]};F.target=this.instance.currentItem[0];this.instance._mouseCapture(F,true);this.instance._mouseStart(F,true,true);this.instance.offset.click.top=D.offset.click.top;this.instance.offset.click.left=D.offset.click.left;this.instance.offset.parent.left-=D.offset.parent.left-this.instance.offset.parent.left;this.instance.offset.parent.top-=D.offset.parent.top-this.instance.offset.parent.top;D._propagate("toSortable",F)}if(this.instance.currentItem){this.instance._mouseDrag(F)}}else{if(this.instance.isOver){this.instance.isOver=0;this.instance.cancelHelperRemoval=true;this.instance.options.revert=false;this.instance._mouseStop(F,true);this.instance.options.helper=this.instance.options._helper;this.instance.currentItem.remove();if(this.instance.placeholder){this.instance.placeholder.remove()}D._propagate("fromSortable",F)}}})}});A.ui.plugin.add("draggable","stack",{start:function(D,B){var C=A.makeArray(A(B.options.stack.group)).sort(function(F,E){return(parseInt(A(F).css("zIndex"),10)||B.options.stack.min)-(parseInt(A(E).css("zIndex"),10)||B.options.stack.min)});A(C).each(function(E){this.style.zIndex=B.options.stack.min+E});this[0].style.zIndex=B.options.stack.min+C.length}})})(jQuery);(function(A){A.widget("ui.droppable",{_setData:function(B,C){if(B=="accept"){this.options.accept=C&&A.isFunction(C)?C:function(D){return D.is(accept)}}else{A.widget.prototype._setData.apply(this,arguments)}},_init:function(){var C=this.options,B=C.accept;this.isover=0;this.isout=1;this.options.accept=this.options.accept&&A.isFunction(this.options.accept)?this.options.accept:function(D){return D.is(B)};this.proportions={width:this.element[0].offsetWidth,height:this.element[0].offsetHeight};A.ui.ddmanager.droppables[this.options.scope]=A.ui.ddmanager.droppables[this.options.scope]||[];A.ui.ddmanager.droppables[this.options.scope].push(this);(this.options.cssNamespace&&this.element.addClass(this.options.cssNamespace+"-droppable"))},plugins:{},ui:function(B){return{draggable:(B.currentItem||B.element),helper:B.helper,position:B.position,absolutePosition:B.positionAbs,options:this.options,element:this.element}},destroy:function(){var B=A.ui.ddmanager.droppables[this.options.scope];for(var C=0;C<B.length;C++){if(B[C]==this){B.splice(C,1)}}this.element.removeClass("ui-droppable-disabled").removeData("droppable").unbind(".droppable")},_over:function(C){var B=A.ui.ddmanager.current;if(!B||(B.currentItem||B.element)[0]==this.element[0]){return }if(this.options.accept.call(this.element,(B.currentItem||B.element))){A.ui.plugin.call(this,"over",[C,this.ui(B)]);this.element.triggerHandler("dropover",[C,this.ui(B)],this.options.over)}},_out:function(C){var B=A.ui.ddmanager.current;if(!B||(B.currentItem||B.element)[0]==this.element[0]){return }if(this.options.accept.call(this.element,(B.currentItem||B.element))){A.ui.plugin.call(this,"out",[C,this.ui(B)]);this.element.triggerHandler("dropout",[C,this.ui(B)],this.options.out)}},_drop:function(D,C){var B=C||A.ui.ddmanager.current;if(!B||(B.currentItem||B.element)[0]==this.element[0]){return false}var E=false;this.element.find(":data(droppable)").not(".ui-draggable-dragging").each(function(){var F=A.data(this,"droppable");if(F.options.greedy&&A.ui.intersect(B,A.extend(F,{offset:F.element.offset()}),F.options.tolerance)){E=true;return false}});if(E){return false}if(this.options.accept.call(this.element,(B.currentItem||B.element))){A.ui.plugin.call(this,"drop",[D,this.ui(B)]);this.element.triggerHandler("drop",[D,this.ui(B)],this.options.drop);return this.element}return false},_activate:function(C){var B=A.ui.ddmanager.current;A.ui.plugin.call(this,"activate",[C,this.ui(B)]);if(B){this.element.triggerHandler("dropactivate",[C,this.ui(B)],this.options.activate)}},_deactivate:function(C){var B=A.ui.ddmanager.current;A.ui.plugin.call(this,"deactivate",[C,this.ui(B)]);if(B){this.element.triggerHandler("dropdeactivate",[C,this.ui(B)],this.options.deactivate)}}});A.extend(A.ui.droppable,{defaults:{disabled:false,tolerance:"intersect",scope:"default",cssNamespace:"ui"}});A.ui.intersect=function(L,F,J){if(!F.offset){return false}var D=(L.positionAbs||L.position.absolute).left,C=D+L.helperProportions.width,I=(L.positionAbs||L.position.absolute).top,H=I+L.helperProportions.height;var E=F.offset.left,B=E+F.proportions.width,K=F.offset.top,G=K+F.proportions.height;switch(J){case"fit":return(E<D&&C<B&&K<I&&H<G);break;case"intersect":return(E<D+(L.helperProportions.width/2)&&C-(L.helperProportions.width/2)<B&&K<I+(L.helperProportions.height/2)&&H-(L.helperProportions.height/2)<G);break;case"pointer":return(E<((L.positionAbs||L.position.absolute).left+(L.clickOffset||L.offset.click).left)&&((L.positionAbs||L.position.absolute).left+(L.clickOffset||L.offset.click).left)<B&&K<((L.positionAbs||L.position.absolute).top+(L.clickOffset||L.offset.click).top)&&((L.positionAbs||L.position.absolute).top+(L.clickOffset||L.offset.click).top)<G);break;case"touch":return((I>=K&&I<=G)||(H>=K&&H<=G)||(I<K&&H>G))&&((D>=E&&D<=B)||(C>=E&&C<=B)||(D<E&&C>B));break;default:return false;break}};A.ui.ddmanager={current:null,droppables:{"default":[]},prepareOffsets:function(E,H){var B=A.ui.ddmanager.droppables[E.options.scope];var F=H?H.type:null;var G=(E.currentItem||E.element).find(":data(droppable)").andSelf();droppablesLoop:for(var D=0;D<B.length;D++){if(B[D].options.disabled||(E&&!B[D].options.accept.call(B[D].element,(E.currentItem||E.element)))){continue}for(var C=0;C<G.length;C++){if(G[C]==B[D].element[0]){B[D].proportions.height=0;continue droppablesLoop}}B[D].visible=B[D].element.css("display")!="none";if(!B[D].visible){continue}B[D].offset=B[D].element.offset();B[D].proportions={width:B[D].element[0].offsetWidth,height:B[D].element[0].offsetHeight};if(F=="dragstart"||F=="sortactivate"){B[D]._activate.call(B[D],H)}}},drop:function(B,C){var D=false;A.each(A.ui.ddmanager.droppables[B.options.scope],function(){if(!this.options){return }if(!this.options.disabled&&this.visible&&A.ui.intersect(B,this,this.options.tolerance)){D=this._drop.call(this,C)}if(!this.options.disabled&&this.visible&&this.options.accept.call(this.element,(B.currentItem||B.element))){this.isout=1;this.isover=0;this._deactivate.call(this,C)}});return D},drag:function(B,C){if(B.options.refreshPositions){A.ui.ddmanager.prepareOffsets(B,C)}A.each(A.ui.ddmanager.droppables[B.options.scope],function(){if(this.options.disabled||this.greedyChild||!this.visible){return }var E=A.ui.intersect(B,this,this.options.tolerance);var G=!E&&this.isover==1?"isout":(E&&this.isover==0?"isover":null);if(!G){return }var F;if(this.options.greedy){var D=this.element.parents(":data(droppable):eq(0)");if(D.length){F=A.data(D[0],"droppable");F.greedyChild=(G=="isover"?1:0)}}if(F&&G=="isover"){F["isover"]=0;F["isout"]=1;F._out.call(F,C)}this[G]=1;this[G=="isout"?"isover":"isout"]=0;this[G=="isover"?"_over":"_out"].call(this,C);if(F&&G=="isout"){F["isout"]=0;F["isover"]=1;F._over.call(F,C)}})}};A.ui.plugin.add("droppable","activeClass",{activate:function(C,B){A(this).addClass(B.options.activeClass)},deactivate:function(C,B){A(this).removeClass(B.options.activeClass)},drop:function(C,B){A(this).removeClass(B.options.activeClass)}});A.ui.plugin.add("droppable","hoverClass",{over:function(C,B){A(this).addClass(B.options.hoverClass)},out:function(C,B){A(this).removeClass(B.options.hoverClass)},drop:function(C,B){A(this).removeClass(B.options.hoverClass)}})})(jQuery);(function(A){A.widget("ui.resizable",A.extend({},A.ui.mouse,{_init:function(){var M=this,N=this.options;var Q=this.element.css("position");this.originalElement=this.element;this.element.addClass("ui-resizable").css({position:/static/.test(Q)?"relative":Q});A.extend(N,{_aspectRatio:!!(N.aspectRatio),helper:N.helper||N.ghost||N.animate?N.helper||"proxy":null,knobHandles:N.knobHandles===true?"ui-resizable-knob-handle":N.knobHandles});var H="1px solid #DEDEDE";N.defaultTheme={"ui-resizable":{display:"block"},"ui-resizable-handle":{position:"absolute",background:"#F2F2F2",fontSize:"0.1px"},"ui-resizable-n":{cursor:"n-resize",height:"4px",left:"0px",right:"0px",borderTop:H},"ui-resizable-s":{cursor:"s-resize",height:"4px",left:"0px",right:"0px",borderBottom:H},"ui-resizable-e":{cursor:"e-resize",width:"4px",top:"0px",bottom:"0px",borderRight:H},"ui-resizable-w":{cursor:"w-resize",width:"4px",top:"0px",bottom:"0px",borderLeft:H},"ui-resizable-se":{cursor:"se-resize",width:"4px",height:"4px",borderRight:H,borderBottom:H},"ui-resizable-sw":{cursor:"sw-resize",width:"4px",height:"4px",borderBottom:H,borderLeft:H},"ui-resizable-ne":{cursor:"ne-resize",width:"4px",height:"4px",borderRight:H,borderTop:H},"ui-resizable-nw":{cursor:"nw-resize",width:"4px",height:"4px",borderLeft:H,borderTop:H}};N.knobTheme={"ui-resizable-handle":{background:"#F2F2F2",border:"1px solid #808080",height:"8px",width:"8px"},"ui-resizable-n":{cursor:"n-resize",top:"0px",left:"45%"},"ui-resizable-s":{cursor:"s-resize",bottom:"0px",left:"45%"},"ui-resizable-e":{cursor:"e-resize",right:"0px",top:"45%"},"ui-resizable-w":{cursor:"w-resize",left:"0px",top:"45%"},"ui-resizable-se":{cursor:"se-resize",right:"0px",bottom:"0px"},"ui-resizable-sw":{cursor:"sw-resize",left:"0px",bottom:"0px"},"ui-resizable-nw":{cursor:"nw-resize",left:"0px",top:"0px"},"ui-resizable-ne":{cursor:"ne-resize",right:"0px",top:"0px"}};N._nodeName=this.element[0].nodeName;if(N._nodeName.match(/canvas|textarea|input|select|button|img/i)){var B=this.element;if(/relative/.test(B.css("position"))&&A.browser.opera){B.css({position:"relative",top:"auto",left:"auto"})}B.wrap(A('<div class="ui-wrapper" style="overflow: hidden;"></div>').css({position:B.css("position"),width:B.outerWidth(),height:B.outerHeight(),top:B.css("top"),left:B.css("left")}));var J=this.element;this.element=this.element.parent();this.element.data("resizable",this);this.element.css({marginLeft:J.css("marginLeft"),marginTop:J.css("marginTop"),marginRight:J.css("marginRight"),marginBottom:J.css("marginBottom")});J.css({marginLeft:0,marginTop:0,marginRight:0,marginBottom:0});if(A.browser.safari&&N.preventDefault){J.css("resize","none")}N.proportionallyResize=J.css({position:"static",zoom:1,display:"block"});this.element.css({margin:J.css("margin")});this._proportionallyResize()}if(!N.handles){N.handles=!A(".ui-resizable-handle",this.element).length?"e,s,se":{n:".ui-resizable-n",e:".ui-resizable-e",s:".ui-resizable-s",w:".ui-resizable-w",se:".ui-resizable-se",sw:".ui-resizable-sw",ne:".ui-resizable-ne",nw:".ui-resizable-nw"}}if(N.handles.constructor==String){N.zIndex=N.zIndex||1000;if(N.handles=="all"){N.handles="n,e,s,w,se,sw,ne,nw"}var O=N.handles.split(",");N.handles={};var G={handle:"position: absolute; display: none; overflow:hidden;",n:"top: 0pt; width:100%;",e:"right: 0pt; height:100%;",s:"bottom: 0pt; width:100%;",w:"left: 0pt; height:100%;",se:"bottom: 0pt; right: 0px;",sw:"bottom: 0pt; left: 0px;",ne:"top: 0pt; right: 0px;",nw:"top: 0pt; left: 0px;"};for(var R=0;R<O.length;R++){var S=A.trim(O[R]),L=N.defaultTheme,F="ui-resizable-"+S,C=!A.ui.css(F)&&!N.knobHandles,P=A.ui.css("ui-resizable-knob-handle"),T=A.extend(L[F],L["ui-resizable-handle"]),D=A.extend(N.knobTheme[F],!P?N.knobTheme["ui-resizable-handle"]:{});var K=/sw|se|ne|nw/.test(S)?{zIndex:++N.zIndex}:{};var I=(C?G[S]:""),E=A(['<div class="ui-resizable-handle ',F,'" style="',I,G.handle,'"></div>'].join("")).css(K);N.handles[S]=".ui-resizable-"+S;this.element.append(E.css(C?T:{}).css(N.knobHandles?D:{}).addClass(N.knobHandles?"ui-resizable-knob-handle":"").addClass(N.knobHandles))}if(N.knobHandles){this.element.addClass("ui-resizable-knob").css(!A.ui.css("ui-resizable-knob")?{}:{})}}this._renderAxis=function(Y){Y=Y||this.element;for(var V in N.handles){if(N.handles[V].constructor==String){N.handles[V]=A(N.handles[V],this.element).show()}if(N.transparent){N.handles[V].css({opacity:0})}if(this.element.is(".ui-wrapper")&&N._nodeName.match(/textarea|input|select|button/i)){var W=A(N.handles[V],this.element),X=0;X=/sw|ne|nw|se|n|s/.test(V)?W.outerHeight():W.outerWidth();var U=["padding",/ne|nw|n/.test(V)?"Top":/se|sw|s/.test(V)?"Bottom":/^e$/.test(V)?"Right":"Left"].join("");if(!N.transparent){Y.css(U,X)}this._proportionallyResize()}if(!A(N.handles[V]).length){continue}}};this._renderAxis(this.element);N._handles=A(".ui-resizable-handle",M.element);if(N.disableSelection){N._handles.each(function(U,V){A.ui.disableSelection(V)})}N._handles.mouseover(function(){if(!N.resizing){if(this.className){var U=this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i)}M.axis=N.axis=U&&U[1]?U[1]:"se"}});if(N.autoHide){N._handles.hide();A(M.element).addClass("ui-resizable-autohide").hover(function(){A(this).removeClass("ui-resizable-autohide");N._handles.show()},function(){if(!N.resizing){A(this).addClass("ui-resizable-autohide");N._handles.hide()}})}this._mouseInit()},plugins:{},ui:function(){return{originalElement:this.originalElement,element:this.element,helper:this.helper,position:this.position,size:this.size,options:this.options,originalSize:this.originalSize,originalPosition:this.originalPosition}},_propagate:function(C,B){A.ui.plugin.call(this,C,[B,this.ui()]);if(C!="resize"){this.element.triggerHandler(["resize",C].join(""),[B,this.ui()],this.options[C])}},destroy:function(){var D=this.element,C=D.children(".ui-resizable").get(0);this._mouseDestroy();var B=function(E){A(E).removeClass("ui-resizable ui-resizable-disabled").removeData("resizable").unbind(".resizable").find(".ui-resizable-handle").remove()};B(D);if(D.is(".ui-wrapper")&&C){D.parent().append(A(C).css({position:D.css("position"),width:D.outerWidth(),height:D.outerHeight(),top:D.css("top"),left:D.css("left")})).end().remove();B(C)}},_mouseCapture:function(D){if(this.options.disabled){return false}var C=false;for(var B in this.options.handles){if(A(this.options.handles[B])[0]==D.target){C=true}}if(!C){return false}return true},_mouseStart:function(I){var C=this.options,B=this.element.position(),D=this.element,H=function(M){return parseInt(M,10)||0},G=A.browser.msie&&A.browser.version<7;C.resizing=true;C.documentScroll={top:A(document).scrollTop(),left:A(document).scrollLeft()};if(D.is(".ui-draggable")||(/absolute/).test(D.css("position"))){var J=A.browser.msie&&!C.containment&&(/absolute/).test(D.css("position"))&&!(/relative/).test(D.parent().css("position"));var K=J?C.documentScroll.top:0,F=J?C.documentScroll.left:0;D.css({position:"absolute",top:(B.top+K),left:(B.left+F)})}if(A.browser.opera&&/relative/.test(D.css("position"))){D.css({position:"relative",top:"auto",left:"auto"})}this._renderProxy();var L=H(this.helper.css("left")),E=H(this.helper.css("top"));if(C.containment){L+=A(C.containment).scrollLeft()||0;E+=A(C.containment).scrollTop()||0}this.offset=this.helper.offset();this.position={left:L,top:E};this.size=C.helper||G?{width:D.outerWidth(),height:D.outerHeight()}:{width:D.width(),height:D.height()};this.originalSize=C.helper||G?{width:D.outerWidth(),height:D.outerHeight()}:{width:D.width(),height:D.height()};this.originalPosition={left:L,top:E};this.sizeDiff={width:D.outerWidth()-D.width(),height:D.outerHeight()-D.height()};this.originalMousePosition={left:I.pageX,top:I.pageY};C.aspectRatio=(typeof C.aspectRatio=="number")?C.aspectRatio:((this.originalSize.width/this.originalSize.height)||1);if(C.preserveCursor){A("body").css("cursor",this.axis+"-resize")}this._propagate("start",I);return true},_mouseDrag:function(I){var D=this.helper,C=this.options,J={},M=this,F=this.originalMousePosition,K=this.axis;var N=(I.pageX-F.left)||0,L=(I.pageY-F.top)||0;var E=this._change[K];if(!E){return false}var H=E.apply(this,[I,N,L]),G=A.browser.msie&&A.browser.version<7,B=this.sizeDiff;if(C._aspectRatio||I.shiftKey){H=this._updateRatio(H,I)}H=this._respectSize(H,I);this._propagate("resize",I);D.css({top:this.position.top+"px",left:this.position.left+"px",width:this.size.width+"px",height:this.size.height+"px"});if(!C.helper&&C.proportionallyResize){this._proportionallyResize()}this._updateCache(H);this.element.triggerHandler("resize",[I,this.ui()],this.options["resize"]);return false},_mouseStop:function(I){this.options.resizing=false;var E=this.options,H=function(M){return parseInt(M,10)||0},K=this;if(E.helper){var D=E.proportionallyResize,B=D&&(/textarea/i).test(D.get(0).nodeName),C=B&&A.ui.hasScroll(D.get(0),"left")?0:K.sizeDiff.height,G=B?0:K.sizeDiff.width;var L={width:(K.size.width-G),height:(K.size.height-C)},F=(parseInt(K.element.css("left"),10)+(K.position.left-K.originalPosition.left))||null,J=(parseInt(K.element.css("top"),10)+(K.position.top-K.originalPosition.top))||null;if(!E.animate){this.element.css(A.extend(L,{top:J,left:F}))}if(E.helper&&!E.animate){this._proportionallyResize()}}if(E.preserveCursor){A("body").css("cursor","auto")}this._propagate("stop",I);if(E.helper){this.helper.remove()}return false},_updateCache:function(B){var C=this.options;this.offset=this.helper.offset();if(B.left){this.position.left=B.left}if(B.top){this.position.top=B.top}if(B.height){this.size.height=B.height}if(B.width){this.size.width=B.width}},_updateRatio:function(D,E){var F=this.options,G=this.position,C=this.size,B=this.axis;if(D.height){D.width=(C.height*F.aspectRatio)}else{if(D.width){D.height=(C.width/F.aspectRatio)}}if(B=="sw"){D.left=G.left+(C.width-D.width);D.top=null}if(B=="nw"){D.top=G.top+(C.height-D.height);D.left=G.left+(C.width-D.width)}return D},_respectSize:function(H,I){var F=this.helper,E=this.options,N=E._aspectRatio||I.shiftKey,M=this.axis,P=H.width&&E.maxWidth&&E.maxWidth<H.width,J=H.height&&E.maxHeight&&E.maxHeight<H.height,D=H.width&&E.minWidth&&E.minWidth>H.width,O=H.height&&E.minHeight&&E.minHeight>H.height;if(D){H.width=E.minWidth}if(O){H.height=E.minHeight}if(P){H.width=E.maxWidth}if(J){H.height=E.maxHeight}var C=this.originalPosition.left+this.originalSize.width,L=this.position.top+this.size.height;var G=/sw|nw|w/.test(M),B=/nw|ne|n/.test(M);if(D&&G){H.left=C-E.minWidth}if(P&&G){H.left=C-E.maxWidth}if(O&&B){H.top=L-E.minHeight}if(J&&B){H.top=L-E.maxHeight}var K=!H.width&&!H.height;if(K&&!H.left&&H.top){H.top=null}else{if(K&&!H.top&&H.left){H.left=null}}return H},_proportionallyResize:function(){var F=this.options;if(!F.proportionallyResize){return }var D=F.proportionallyResize,C=this.helper||this.element;if(!F.borderDif){var B=[D.css("borderTopWidth"),D.css("borderRightWidth"),D.css("borderBottomWidth"),D.css("borderLeftWidth")],E=[D.css("paddingTop"),D.css("paddingRight"),D.css("paddingBottom"),D.css("paddingLeft")];F.borderDif=A.map(B,function(G,I){var H=parseInt(G,10)||0,J=parseInt(E[I],10)||0;return H+J})}D.css({height:(C.height()-F.borderDif[0]-F.borderDif[2])+"px",width:(C.width()-F.borderDif[1]-F.borderDif[3])+"px"})},_renderProxy:function(){var C=this.element,F=this.options;this.elementOffset=C.offset();if(F.helper){this.helper=this.helper||A('<div style="overflow:hidden;"></div>');var B=A.browser.msie&&A.browser.version<7,D=(B?1:0),E=(B?2:-1);this.helper.addClass(F.helper).css({width:C.outerWidth()+E,height:C.outerHeight()+E,position:"absolute",left:this.elementOffset.left-D+"px",top:this.elementOffset.top-D+"px",zIndex:++F.zIndex});this.helper.appendTo("body");if(F.disableSelection){A.ui.disableSelection(this.helper.get(0))}}else{this.helper=C}},_change:{e:function(D,C,B){return{width:this.originalSize.width+C}},w:function(F,C,B){var G=this.options,D=this.originalSize,E=this.originalPosition;return{left:E.left+C,width:D.width-C}},n:function(F,C,B){var G=this.options,D=this.originalSize,E=this.originalPosition;return{top:E.top+B,height:D.height-B}},s:function(D,C,B){return{height:this.originalSize.height+B}},se:function(D,C,B){return A.extend(this._change.s.apply(this,arguments),this._change.e.apply(this,[D,C,B]))},sw:function(D,C,B){return A.extend(this._change.s.apply(this,arguments),this._change.w.apply(this,[D,C,B]))},ne:function(D,C,B){return A.extend(this._change.n.apply(this,arguments),this._change.e.apply(this,[D,C,B]))},nw:function(D,C,B){return A.extend(this._change.n.apply(this,arguments),this._change.w.apply(this,[D,C,B]))}}}));A.extend(A.ui.resizable,{defaults:{cancel:":input",distance:1,delay:0,preventDefault:true,transparent:false,minWidth:10,minHeight:10,aspectRatio:false,disableSelection:true,preserveCursor:true,autoHide:false,knobHandles:false}});A.ui.plugin.add("resizable","containment",{start:function(I,K){var E=K.options,M=A(this).data("resizable"),G=M.element;var C=E.containment,F=(C instanceof A)?C.get(0):(/parent/.test(C))?G.parent().get(0):C;if(!F){return }M.containerElement=A(F);if(/document/.test(C)||C==document){M.containerOffset={left:0,top:0};M.containerPosition={left:0,top:0};M.parentData={element:A(document),left:0,top:0,width:A(document).width(),height:A(document).height()||document.body.parentNode.scrollHeight}}else{M.containerOffset=A(F).offset();M.containerPosition=A(F).position();M.containerSize={height:A(F).innerHeight(),width:A(F).innerWidth()};var J=M.containerOffset,B=M.containerSize.height,H=M.containerSize.width,D=(A.ui.hasScroll(F,"left")?F.scrollWidth:H),L=(A.ui.hasScroll(F)?F.scrollHeight:B);M.parentData={element:F,left:J.left,top:J.top,width:D,height:L}}},resize:function(H,K){var E=K.options,N=A(this).data("resizable"),C=N.containerSize,J=N.containerOffset,G=N.size,I=N.position,L=E._aspectRatio||H.shiftKey,B={top:0,left:0},D=N.containerElement;if(D[0]!=document&&/static/.test(D.css("position"))){B=N.containerPosition}if(I.left<(E.helper?J.left:B.left)){N.size.width=N.size.width+(E.helper?(N.position.left-J.left):(N.position.left-B.left));if(L){N.size.height=N.size.width/E.aspectRatio}N.position.left=E.helper?J.left:B.left}if(I.top<(E.helper?J.top:0)){N.size.height=N.size.height+(E.helper?(N.position.top-J.top):N.position.top);if(L){N.size.width=N.size.height*E.aspectRatio}N.position.top=E.helper?J.top:0}var F=(E.helper?N.offset.left-J.left:(N.position.left-B.left))+N.sizeDiff.width,M=(E.helper?N.offset.top-J.top:N.position.top)+N.sizeDiff.height;if(F+N.size.width>=N.parentData.width){N.size.width=N.parentData.width-F;if(L){N.size.height=N.size.width/E.aspectRatio}}if(M+N.size.height>=N.parentData.height){N.size.height=N.parentData.height-M;if(L){N.size.width=N.size.height*E.aspectRatio}}},stop:function(G,J){var C=J.options,L=A(this).data("resizable"),H=L.position,I=L.containerOffset,B=L.containerPosition,D=L.containerElement;var E=A(L.helper),M=E.offset(),K=E.innerWidth(),F=E.innerHeight();if(C.helper&&!C.animate&&/relative/.test(D.css("position"))){A(this).css({left:(M.left-I.left),top:(M.top-I.top),width:K,height:F})}if(C.helper&&!C.animate&&/static/.test(D.css("position"))){A(this).css({left:B.left+(M.left-I.left),top:B.top+(M.top-I.top),width:K,height:F})}}});A.ui.plugin.add("resizable","grid",{resize:function(H,J){var D=J.options,L=A(this).data("resizable"),G=L.size,E=L.originalSize,F=L.originalPosition,K=L.axis,I=D._aspectRatio||H.shiftKey;D.grid=typeof D.grid=="number"?[D.grid,D.grid]:D.grid;var C=Math.round((G.width-E.width)/(D.grid[0]||1))*(D.grid[0]||1),B=Math.round((G.height-E.height)/(D.grid[1]||1))*(D.grid[1]||1);if(/^(se|s|e)$/.test(K)){L.size.width=E.width+C;L.size.height=E.height+B}else{if(/^(ne)$/.test(K)){L.size.width=E.width+C;L.size.height=E.height+B;L.position.top=F.top-B}else{if(/^(sw)$/.test(K)){L.size.width=E.width+C;L.size.height=E.height+B;L.position.left=F.left-C}else{L.size.width=E.width+C;L.size.height=E.height+B;L.position.top=F.top-B;L.position.left=F.left-C}}}}});A.ui.plugin.add("resizable","animate",{stop:function(I,K){var F=K.options,L=A(this).data("resizable");var E=F.proportionallyResize,B=E&&(/textarea/i).test(E.get(0).nodeName),C=B&&A.ui.hasScroll(E.get(0),"left")?0:L.sizeDiff.height,H=B?0:L.sizeDiff.width;var D={width:(L.size.width-H),height:(L.size.height-C)},G=(parseInt(L.element.css("left"),10)+(L.position.left-L.originalPosition.left))||null,J=(parseInt(L.element.css("top"),10)+(L.position.top-L.originalPosition.top))||null;L.element.animate(A.extend(D,J&&G?{top:J,left:G}:{}),{duration:F.animateDuration||"slow",easing:F.animateEasing||"swing",step:function(){var M={width:parseInt(L.element.css("width"),10),height:parseInt(L.element.css("height"),10),top:parseInt(L.element.css("top"),10),left:parseInt(L.element.css("left"),10)};if(E){E.css({width:M.width,height:M.height})}L._updateCache(M);L._propagate("animate",I)}})}});A.ui.plugin.add("resizable","ghost",{start:function(E,D){var F=D.options,B=A(this).data("resizable"),G=F.proportionallyResize,C=B.size;if(!G){B.ghost=B.element.clone()}else{B.ghost=G.clone()}B.ghost.css({opacity:0.25,display:"block",position:"relative",height:C.height,width:C.width,margin:0,left:0,top:0}).addClass("ui-resizable-ghost").addClass(typeof F.ghost=="string"?F.ghost:"");B.ghost.appendTo(B.helper)},resize:function(D,C){var E=C.options,B=A(this).data("resizable"),F=E.proportionallyResize;if(B.ghost){B.ghost.css({position:"relative",height:B.size.height,width:B.size.width})}},stop:function(D,C){var E=C.options,B=A(this).data("resizable"),F=E.proportionallyResize;if(B.ghost&&B.helper){B.helper.get(0).removeChild(B.ghost.get(0))}}});A.ui.plugin.add("resizable","alsoResize",{start:function(E,C){var F=C.options,B=A(this).data("resizable"),D=function(G){A(G).each(function(){A(this).data("resizable-alsoresize",{width:parseInt(A(this).width(),10),height:parseInt(A(this).height(),10),left:parseInt(A(this).css("left"),10),top:parseInt(A(this).css("top"),10)})})};if(typeof (F.alsoResize)=="object"){if(F.alsoResize.length){F.alsoResize=F.alsoResize[0];D(F.alsoResize)}else{A.each(F.alsoResize,function(G,H){D(G)})}}else{D(F.alsoResize)}},resize:function(F,E){var G=E.options,C=A(this).data("resizable"),D=C.originalSize,I=C.originalPosition;var H={height:(C.size.height-D.height)||0,width:(C.size.width-D.width)||0,top:(C.position.top-I.top)||0,left:(C.position.left-I.left)||0},B=function(J,K){A(J).each(function(){var N=A(this).data("resizable-alsoresize"),M={},L=K&&K.length?K:["width","height","top","left"];A.each(L||["width","height","top","left"],function(O,Q){var P=(N[Q]||0)+(H[Q]||0);if(P&&P>=0){M[Q]=P||null}});A(this).css(M)})};if(typeof (G.alsoResize)=="object"){A.each(G.alsoResize,function(J,K){B(J,K)})}else{B(G.alsoResize)}},stop:function(C,B){A(this).removeData("resizable-alsoresize-start")}})})(jQuery);(function(A){A.widget("ui.selectable",A.extend({},A.ui.mouse,{_init:function(){var B=this;this.element.addClass("ui-selectable");this.dragged=false;var C;this.refresh=function(){C=A(B.options.filter,B.element[0]);C.each(function(){var D=A(this);var E=D.offset();A.data(this,"selectable-item",{element:this,$element:D,left:E.left,top:E.top,right:E.left+D.width(),bottom:E.top+D.height(),startselected:false,selected:D.hasClass("ui-selected"),selecting:D.hasClass("ui-selecting"),unselecting:D.hasClass("ui-unselecting")})})};this.refresh();this.selectees=C.addClass("ui-selectee");this._mouseInit();this.helper=A(document.createElement("div")).css({border:"1px dotted black"}).addClass("ui-selectable-helper")},toggle:function(){if(this.options.disabled){this.enable()}else{this.disable()}},destroy:function(){this.element.removeClass("ui-selectable ui-selectable-disabled").removeData("selectable").unbind(".selectable");this._mouseDestroy()},_mouseStart:function(E){var C=this;this.opos=[E.pageX,E.pageY];if(this.options.disabled){return }var D=this.options;this.selectees=A(D.filter,this.element[0]);this.element.triggerHandler("selectablestart",[E,{"selectable":this.element[0],"options":D}],D.start);A("body").append(this.helper);this.helper.css({"z-index":100,"position":"absolute","left":E.clientX,"top":E.clientY,"width":0,"height":0});if(D.autoRefresh){this.refresh()}this.selectees.filter(".ui-selected").each(function(){var F=A.data(this,"selectable-item");F.startselected=true;if(!E.metaKey){F.$element.removeClass("ui-selected");F.selected=false;F.$element.addClass("ui-unselecting");F.unselecting=true;C.element.triggerHandler("selectableunselecting",[E,{selectable:C.element[0],unselecting:F.element,options:D}],D.unselecting)}});var B=false;A(E.target).parents().andSelf().each(function(){if(A.data(this,"selectable-item")){B=true}});return this.options.keyboard?!B:true},_mouseDrag:function(I){var C=this;this.dragged=true;if(this.options.disabled){return }var E=this.options;var D=this.opos[0],H=this.opos[1],B=I.pageX,G=I.pageY;if(D>B){var F=B;B=D;D=F}if(H>G){var F=G;G=H;H=F}this.helper.css({left:D,top:H,width:B-D,height:G-H});this.selectees.each(function(){var J=A.data(this,"selectable-item");if(!J||J.element==C.element[0]){return }var K=false;if(E.tolerance=="touch"){K=(!(J.left>B||J.right<D||J.top>G||J.bottom<H))}else{if(E.tolerance=="fit"){K=(J.left>D&&J.right<B&&J.top>H&&J.bottom<G)}}if(K){if(J.selected){J.$element.removeClass("ui-selected");J.selected=false}if(J.unselecting){J.$element.removeClass("ui-unselecting");J.unselecting=false}if(!J.selecting){J.$element.addClass("ui-selecting");J.selecting=true;C.element.triggerHandler("selectableselecting",[I,{selectable:C.element[0],selecting:J.element,options:E}],E.selecting)}}else{if(J.selecting){if(I.metaKey&&J.startselected){J.$element.removeClass("ui-selecting");J.selecting=false;J.$element.addClass("ui-selected");J.selected=true}else{J.$element.removeClass("ui-selecting");J.selecting=false;if(J.startselected){J.$element.addClass("ui-unselecting");J.unselecting=true}C.element.triggerHandler("selectableunselecting",[I,{selectable:C.element[0],unselecting:J.element,options:E}],E.unselecting)}}if(J.selected){if(!I.metaKey&&!J.startselected){J.$element.removeClass("ui-selected");J.selected=false;J.$element.addClass("ui-unselecting");J.unselecting=true;C.element.triggerHandler("selectableunselecting",[I,{selectable:C.element[0],unselecting:J.element,options:E}],E.unselecting)}}}});return false},_mouseStop:function(D){var B=this;this.dragged=false;var C=this.options;A(".ui-unselecting",this.element[0]).each(function(){var E=A.data(this,"selectable-item");E.$element.removeClass("ui-unselecting");E.unselecting=false;E.startselected=false;B.element.triggerHandler("selectableunselected",[D,{selectable:B.element[0],unselected:E.element,options:C}],C.unselected)});A(".ui-selecting",this.element[0]).each(function(){var E=A.data(this,"selectable-item");E.$element.removeClass("ui-selecting").addClass("ui-selected");E.selecting=false;E.selected=true;E.startselected=true;B.element.triggerHandler("selectableselected",[D,{selectable:B.element[0],selected:E.element,options:C}],C.selected)});this.element.triggerHandler("selectablestop",[D,{selectable:B.element[0],options:this.options}],this.options.stop);this.helper.remove();return false}}));A.extend(A.ui.selectable,{defaults:{distance:1,delay:0,cancel:":input",appendTo:"body",autoRefresh:true,filter:"*",tolerance:"touch"}})})(jQuery);(function(B){function A(E,D){var C=B.browser.safari&&B.browser.version<522;if(E.contains&&!C){return E.contains(D)}if(E.compareDocumentPosition){return !!(E.compareDocumentPosition(D)&16)}while(D=D.parentNode){if(D==E){return true}}return false}B.widget("ui.sortable",B.extend({},B.ui.mouse,{_init:function(){var C=this.options;this.containerCache={};this.element.addClass("ui-sortable");this.refresh();this.floating=this.items.length?(/left|right/).test(this.items[0].item.css("float")):false;this.offset=this.element.offset();this._mouseInit()},plugins:{},ui:function(C){return{helper:(C||this)["helper"],placeholder:(C||this)["placeholder"]||B([]),position:(C||this)["position"],absolutePosition:(C||this)["positionAbs"],options:this.options,element:this.element,item:(C||this)["currentItem"],sender:C?C.element:null}},_propagate:function(F,E,C,D){B.ui.plugin.call(this,F,[E,this.ui(C)]);if(!D){this.element.triggerHandler(F=="sort"?F:"sort"+F,[E,this.ui(C)],this.options[F])}},serialize:function(E){var C=this._getItemsAsjQuery(E&&E.connected);var D=[];E=E||{};B(C).each(function(){var F=(B(this.item||this).attr(E.attribute||"id")||"").match(E.expression||(/(.+)[-=_](.+)/));if(F){D.push((E.key||F[1]+"[]")+"="+(E.key&&E.expression?F[1]:F[2]))}});return D.join("&")},toArray:function(E){var C=this._getItemsAsjQuery(E&&E.connected);var D=[];C.each(function(){D.push(B(this).attr(E.attr||"id"))});return D},_intersectsWith:function(L){var E=this.positionAbs.left,D=E+this.helperProportions.width,K=this.positionAbs.top,J=K+this.helperProportions.height;var F=L.left,C=F+L.width,M=L.top,I=M+L.height;var N=this.offset.click.top,H=this.offset.click.left;var G=(K+N)>M&&(K+N)<I&&(E+H)>F&&(E+H)<C;if(this.options.tolerance=="pointer"||this.options.forcePointerForContainers||(this.options.tolerance=="guess"&&this.helperProportions[this.floating?"width":"height"]>L[this.floating?"width":"height"])){return G}else{return(F<E+(this.helperProportions.width/2)&&D-(this.helperProportions.width/2)<C&&M<K+(this.helperProportions.height/2)&&J-(this.helperProportions.height/2)<I)}},_intersectsWithEdge:function(N){var E=this.positionAbs.left,D=E+this.helperProportions.width,L=this.positionAbs.top,J=L+this.helperProportions.height;var F=N.left,C=F+N.width,O=N.top,I=O+N.height;var P=this.offset.click.top,H=this.offset.click.left;var G=(L+P)>O&&(L+P)<I&&(E+H)>F&&(E+H)<C;if(this.options.tolerance=="pointer"||(this.options.tolerance=="guess"&&this.helperProportions[this.floating?"width":"height"]>N[this.floating?"width":"height"])){if(!G){return false}if(this.floating){if((E+H)>F&&(E+H)<F+N.width/2){return 2}if((E+H)>F+N.width/2&&(E+H)<C){return 1}}else{var M=N.height;var K=L-this.updateOriginalPosition.top<0?2:1;if(K==1&&(L+P)<O+M/2){return 2}else{if(K==2&&(L+P)>O+M/2){return 1}}}}else{if(!(F<E+(this.helperProportions.width/2)&&D-(this.helperProportions.width/2)<C&&O<L+(this.helperProportions.height/2)&&J-(this.helperProportions.height/2)<I)){return false}if(this.floating){if(D>F&&E<F){return 2}if(E<C&&D>C){return 1}}else{if(J>O&&L<O){return 1}if(L<I&&J>I){return 2}}}return false},refresh:function(){this._refreshItems();this.refreshPositions()},_getItemsAsjQuery:function(H){var D=this;var C=[];var F=[];if(this.options.connectWith&&H){for(var G=this.options.connectWith.length-1;G>=0;G--){var J=B(this.options.connectWith[G]);for(var E=J.length-1;E>=0;E--){var I=B.data(J[E],"sortable");if(I&&I!=this&&!I.options.disabled){F.push([B.isFunction(I.options.items)?I.options.items.call(I.element):B(I.options.items,I.element).not(".ui-sortable-helper"),I])}}}}F.push([B.isFunction(this.options.items)?this.options.items.call(this.element,null,{options:this.options,item:this.currentItem}):B(this.options.items,this.element).not(".ui-sortable-helper"),this]);for(var G=F.length-1;G>=0;G--){F[G][0].each(function(){C.push(this)})}return B(C)},_removeCurrentsFromItems:function(){var E=this.currentItem.find(":data(sortable-item)");for(var D=0;D<this.items.length;D++){for(var C=0;C<E.length;C++){if(E[C]==this.items[D].item[0]){this.items.splice(D,1)}}}},_refreshItems:function(){this.items=[];this.containers=[this];var D=this.items;var C=this;var F=[[B.isFunction(this.options.items)?this.options.items.call(this.element,null,{options:this.options,item:this.currentItem}):B(this.options.items,this.element),this]];if(this.options.connectWith){for(var G=this.options.connectWith.length-1;G>=0;G--){var I=B(this.options.connectWith[G]);for(var E=I.length-1;E>=0;E--){var H=B.data(I[E],"sortable");if(H&&H!=this&&!H.options.disabled){F.push([B.isFunction(H.options.items)?H.options.items.call(H.element):B(H.options.items,H.element),H]);this.containers.push(H)}}}}for(var G=F.length-1;G>=0;G--){F[G][0].each(function(){B.data(this,"sortable-item",F[G][1]);D.push({item:B(this),instance:F[G][1],width:0,height:0,left:0,top:0})})}},refreshPositions:function(D){if(this.offsetParent){var C=this.offsetParent.offset();this.offset.parent={top:C.top+this.offsetParentBorders.top,left:C.left+this.offsetParentBorders.left}}for(var F=this.items.length-1;F>=0;F--){if(this.items[F].instance!=this.currentContainer&&this.currentContainer&&this.items[F].item[0]!=this.currentItem[0]){continue}var E=this.options.toleranceElement?B(this.options.toleranceElement,this.items[F].item):this.items[F].item;if(!D){this.items[F].width=E[0].offsetWidth;this.items[F].height=E[0].offsetHeight}var G=E.offset();this.items[F].left=G.left;this.items[F].top=G.top}if(this.options.custom&&this.options.custom.refreshContainers){this.options.custom.refreshContainers.call(this)}else{for(var F=this.containers.length-1;F>=0;F--){var G=this.containers[F].element.offset();this.containers[F].containerCache.left=G.left;this.containers[F].containerCache.top=G.top;this.containers[F].containerCache.width=this.containers[F].element.outerWidth();this.containers[F].containerCache.height=this.containers[F].element.outerHeight()}}},destroy:function(){this.element.removeClass("ui-sortable ui-sortable-disabled").removeData("sortable").unbind(".sortable");this._mouseDestroy();for(var C=this.items.length-1;C>=0;C--){this.items[C].item.removeData("sortable-item")}},_createPlaceholder:function(E){var C=E||this,F=C.options;if(!F.placeholder||F.placeholder.constructor==String){var D=F.placeholder;F.placeholder={element:function(){var G=B(document.createElement(C.currentItem[0].nodeName)).addClass(D||"ui-sortable-placeholder")[0];if(!D){G.style.visibility="hidden";document.body.appendChild(G);G.innerHTML=C.currentItem[0].innerHTML;document.body.removeChild(G)}return G},update:function(G,H){if(D&&!F.forcePlaceholderSize){return }if(!H.height()){H.height(C.currentItem.innerHeight()-parseInt(C.currentItem.css("paddingTop")||0,10)-parseInt(C.currentItem.css("paddingBottom")||0,10))}if(!H.width()){H.width(C.currentItem.innerWidth()-parseInt(C.currentItem.css("paddingLeft")||0,10)-parseInt(C.currentItem.css("paddingRight")||0,10))}}}}C.placeholder=B(F.placeholder.element.call(C.element,C.currentItem));C.currentItem.parent()[0].appendChild(C.placeholder[0]);C.placeholder[0].parentNode.insertBefore(C.placeholder[0],C.currentItem[0]);F.placeholder.update(C,C.placeholder)},_contactContainers:function(F){for(var D=this.containers.length-1;D>=0;D--){if(this._intersectsWith(this.containers[D].containerCache)){if(!this.containers[D].containerCache.over){if(this.currentContainer!=this.containers[D]){var I=10000;var H=null;var E=this.positionAbs[this.containers[D].floating?"left":"top"];for(var C=this.items.length-1;C>=0;C--){if(!A(this.containers[D].element[0],this.items[C].item[0])){continue}var G=this.items[C][this.containers[D].floating?"left":"top"];if(Math.abs(G-E)<I){I=Math.abs(G-E);H=this.items[C]}}if(!H&&!this.options.dropOnEmpty){continue}this.currentContainer=this.containers[D];H?this.options.sortIndicator.call(this,F,H,null,true):this.options.sortIndicator.call(this,F,null,this.containers[D].element,true);this._propagate("change",F);this.containers[D]._propagate("change",F,this);this.options.placeholder.update(this.currentContainer,this.placeholder)}this.containers[D]._propagate("over",F,this);this.containers[D].containerCache.over=1}}else{if(this.containers[D].containerCache.over){this.containers[D]._propagate("out",F,this);this.containers[D].containerCache.over=0}}}},_mouseCapture:function(G,F){if(this.options.disabled||this.options.type=="static"){return false}this._refreshItems();var E=null,D=this,C=B(G.target).parents().each(function(){if(B.data(this,"sortable-item")==D){E=B(this);return false}});if(B.data(G.target,"sortable-item")==D){E=B(G.target)}if(!E){return false}if(this.options.handle&&!F){var H=false;B(this.options.handle,E).find("*").andSelf().each(function(){if(this==G.target){H=true}});if(!H){return false}}this.currentItem=E;this._removeCurrentsFromItems();return true},createHelper:function(D){var E=this.options;var C=typeof E.helper=="function"?B(E.helper.apply(this.element[0],[D,this.currentItem])):(E.helper=="original"?this.currentItem:this.currentItem.clone());if(!C.parents("body").length){B(E.appendTo!="parent"?E.appendTo:this.currentItem[0].parentNode)[0].appendChild(C[0])}return C},_mouseStart:function(G,I,K){var C=this.options;this.currentContainer=this;this.refreshPositions();this.helper=this.createHelper(G);this.margins={left:(parseInt(this.currentItem.css("marginLeft"),10)||0),top:(parseInt(this.currentItem.css("marginTop"),10)||0)};this.offset=this.currentItem.offset();this.offset={top:this.offset.top-this.margins.top,left:this.offset.left-this.margins.left};this.offset.click={left:G.pageX-this.offset.left,top:G.pageY-this.offset.top};this.offsetParent=this.helper.offsetParent();var E=this.offsetParent.offset();this.offsetParentBorders={top:(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:(parseInt(this.offsetParent.css("borderLeftWidth"),10)||0)};this.offset.parent={top:E.top+this.offsetParentBorders.top,left:E.left+this.offsetParentBorders.left};this.updateOriginalPosition=this.originalPosition=this._generatePosition(G);this.domPosition={prev:this.currentItem.prev()[0],parent:this.currentItem.parent()[0]};this.helperProportions={width:this.helper.outerWidth(),height:this.helper.outerHeight()};if(C.helper=="original"){this._storedCSS={position:this.currentItem.css("position"),top:this.currentItem.css("top"),left:this.currentItem.css("left"),clear:this.currentItem.css("clear")}}else{this.currentItem.hide()}this.helper.css({position:"absolute",clear:"both"}).addClass("ui-sortable-helper");this._createPlaceholder();this._propagate("start",G);if(!this._preserveHelperProportions){this.helperProportions={width:this.helper.outerWidth(),height:this.helper.outerHeight()}}if(C.cursorAt){if(C.cursorAt.left!=undefined){this.offset.click.left=C.cursorAt.left}if(C.cursorAt.right!=undefined){this.offset.click.left=this.helperProportions.width-C.cursorAt.right}if(C.cursorAt.top!=undefined){this.offset.click.top=C.cursorAt.top}if(C.cursorAt.bottom!=undefined){this.offset.click.top=this.helperProportions.height-C.cursorAt.bottom}}if(C.containment){if(C.containment=="parent"){C.containment=this.helper[0].parentNode}if(C.containment=="document"||C.containment=="window"){this.containment=[0-this.offset.parent.left,0-this.offset.parent.top,B(C.containment=="document"?document:window).width()-this.offset.parent.left-this.helperProportions.width-this.margins.left-(parseInt(this.element.css("marginRight"),10)||0),(B(C.containment=="document"?document:window).height()||document.body.parentNode.scrollHeight)-this.offset.parent.top-this.helperProportions.height-this.margins.top-(parseInt(this.element.css("marginBottom"),10)||0)]}if(!(/^(document|window|parent)$/).test(C.containment)){var D=B(C.containment)[0];var J=B(C.containment).offset();var H=(B(D).css("overflow")!="hidden");this.containment=[J.left+(parseInt(B(D).css("borderLeftWidth"),10)||0)-this.offset.parent.left,J.top+(parseInt(B(D).css("borderTopWidth"),10)||0)-this.offset.parent.top,J.left+(H?Math.max(D.scrollWidth,D.offsetWidth):D.offsetWidth)-(parseInt(B(D).css("borderLeftWidth"),10)||0)-this.offset.parent.left-this.helperProportions.width-this.margins.left-(parseInt(this.currentItem.css("marginRight"),10)||0),J.top+(H?Math.max(D.scrollHeight,D.offsetHeight):D.offsetHeight)-(parseInt(B(D).css("borderTopWidth"),10)||0)-this.offset.parent.top-this.helperProportions.height-this.margins.top-(parseInt(this.currentItem.css("marginBottom"),10)||0)]}}if(!K){for(var F=this.containers.length-1;F>=0;F--){this.containers[F]._propagate("activate",G,this)}}if(B.ui.ddmanager){B.ui.ddmanager.current=this}if(B.ui.ddmanager&&!C.dropBehaviour){B.ui.ddmanager.prepareOffsets(this,G)}this.dragging=true;this._mouseDrag(G);return true},_convertPositionTo:function(D,E){if(!E){E=this.position}var C=D=="absolute"?1:-1;return{top:(E.top+this.offset.parent.top*C-(this.offsetParent[0]==document.body?0:this.offsetParent[0].scrollTop)*C+this.margins.top*C),left:(E.left+this.offset.parent.left*C-(this.offsetParent[0]==document.body?0:this.offsetParent[0].scrollLeft)*C+this.margins.left*C)}},_generatePosition:function(F){var G=this.options;var C={top:(F.pageY-this.offset.click.top-this.offset.parent.top+(this.offsetParent[0]==document.body?0:this.offsetParent[0].scrollTop)),left:(F.pageX-this.offset.click.left-this.offset.parent.left+(this.offsetParent[0]==document.body?0:this.offsetParent[0].scrollLeft))};if(!this.originalPosition){return C}if(this.containment){if(C.left<this.containment[0]){C.left=this.containment[0]}if(C.top<this.containment[1]){C.top=this.containment[1]}if(C.left>this.containment[2]){C.left=this.containment[2]}if(C.top>this.containment[3]){C.top=this.containment[3]}}if(G.grid){var E=this.originalPosition.top+Math.round((C.top-this.originalPosition.top)/G.grid[1])*G.grid[1];C.top=this.containment?(!(E<this.containment[1]||E>this.containment[3])?E:(!(E<this.containment[1])?E-G.grid[1]:E+G.grid[1])):E;var D=this.originalPosition.left+Math.round((C.left-this.originalPosition.left)/G.grid[0])*G.grid[0];C.left=this.containment?(!(D<this.containment[0]||D>this.containment[2])?D:(!(D<this.containment[0])?D-G.grid[0]:D+G.grid[0])):D}return C},_mouseDrag:function(D){this.position=this._generatePosition(D);this.positionAbs=this._convertPositionTo("absolute");B.ui.plugin.call(this,"sort",[D,this.ui()]);this.positionAbs=this._convertPositionTo("absolute");this.helper[0].style.left=this.position.left+"px";this.helper[0].style.top=this.position.top+"px";for(var C=this.items.length-1;C>=0;C--){var E=this._intersectsWithEdge(this.items[C]);if(!E){continue}if(this.items[C].item[0]!=this.currentItem[0]&&this.placeholder[E==1?"next":"prev"]()[0]!=this.items[C].item[0]&&!A(this.placeholder[0],this.items[C].item[0])&&(this.options.type=="semi-dynamic"?!A(this.element[0],this.items[C].item[0]):true)){this.updateOriginalPosition=this._generatePosition(D);this.direction=E==1?"down":"up";this.options.sortIndicator.call(this,D,this.items[C]);this._propagate("change",D);break}}this._contactContainers(D);if(B.ui.ddmanager){B.ui.ddmanager.drag(this,D)}this.element.triggerHandler("sort",[D,this.ui()],this.options["sort"]);return false},_rearrange:function(H,G,D,F){D?D[0].appendChild(this.placeholder[0]):G.item[0].parentNode.insertBefore(this.placeholder[0],(this.direction=="down"?G.item[0]:G.item[0].nextSibling));this.counter=this.counter?++this.counter:1;var E=this,C=this.counter;window.setTimeout(function(){if(C==E.counter){E.refreshPositions(!F)}},0)},_mouseStop:function(E,D){if(B.ui.ddmanager&&!this.options.dropBehaviour){B.ui.ddmanager.drop(this,E)}if(this.options.revert){var C=this;var F=C.placeholder.offset();B(this.helper).animate({left:F.left-this.offset.parent.left-C.margins.left+(this.offsetParent[0]==document.body?0:this.offsetParent[0].scrollLeft),top:F.top-this.offset.parent.top-C.margins.top+(this.offsetParent[0]==document.body?0:this.offsetParent[0].scrollTop)},parseInt(this.options.revert,10)||500,function(){C._clear(E)})}else{this._clear(E,D)}return false},_clear:function(E,D){if(!this._noFinalSort){this.placeholder.before(this.currentItem)}this._noFinalSort=null;if(this.options.helper=="original"){this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper")}else{this.currentItem.show()}if(this.domPosition.prev!=this.currentItem.prev().not(".ui-sortable-helper")[0]||this.domPosition.parent!=this.currentItem.parent()[0]){this._propagate("update",E,null,D)}if(!A(this.element[0],this.currentItem[0])){this._propagate("remove",E,null,D);for(var C=this.containers.length-1;C>=0;C--){if(A(this.containers[C].element[0],this.currentItem[0])){this.containers[C]._propagate("update",E,this,D);this.containers[C]._propagate("receive",E,this,D)}}}for(var C=this.containers.length-1;C>=0;C--){this.containers[C]._propagate("deactivate",E,this,D);if(this.containers[C].containerCache.over){this.containers[C]._propagate("out",E,this);this.containers[C].containerCache.over=0}}this.dragging=false;if(this.cancelHelperRemoval){this._propagate("beforeStop",E,null,D);this._propagate("stop",E,null,D);return false}this._propagate("beforeStop",E,null,D);this.placeholder.remove();if(this.options.helper!="original"){this.helper.remove()}this.helper=null;this._propagate("stop",E,null,D);return true}}));B.extend(B.ui.sortable,{getter:"serialize toArray",defaults:{helper:"original",tolerance:"guess",distance:1,delay:0,scroll:true,scrollSensitivity:20,scrollSpeed:20,cancel:":input",items:"> *",zIndex:1000,dropOnEmpty:true,appendTo:"parent",sortIndicator:B.ui.sortable.prototype._rearrange,scope:"default",forcePlaceholderSize:false}});B.ui.plugin.add("sortable","cursor",{start:function(E,D){var C=B("body");if(C.css("cursor")){D.options._cursor=C.css("cursor")}C.css("cursor",D.options.cursor)},beforeStop:function(D,C){if(C.options._cursor){B("body").css("cursor",C.options._cursor)}}});B.ui.plugin.add("sortable","zIndex",{start:function(E,D){var C=D.helper;if(C.css("zIndex")){D.options._zIndex=C.css("zIndex")}C.css("zIndex",D.options.zIndex)},beforeStop:function(D,C){if(C.options._zIndex){B(C.helper).css("zIndex",C.options._zIndex)}}});B.ui.plugin.add("sortable","opacity",{start:function(E,D){var C=D.helper;if(C.css("opacity")){D.options._opacity=C.css("opacity")}C.css("opacity",D.options.opacity)},beforeStop:function(D,C){if(C.options._opacity){B(C.helper).css("opacity",C.options._opacity)}}});B.ui.plugin.add("sortable","scroll",{start:function(E,D){var F=D.options;var C=B(this).data("sortable");C.overflowY=function(G){do{if(/auto|scroll/.test(G.css("overflow"))||(/auto|scroll/).test(G.css("overflow-y"))){return G}G=G.parent()}while(G[0].parentNode);return B(document)}(C.currentItem);C.overflowX=function(G){do{if(/auto|scroll/.test(G.css("overflow"))||(/auto|scroll/).test(G.css("overflow-x"))){return G}G=G.parent()}while(G[0].parentNode);return B(document)}(C.currentItem);if(C.overflowY[0]!=document&&C.overflowY[0].tagName!="HTML"){C.overflowYOffset=C.overflowY.offset()}if(C.overflowX[0]!=document&&C.overflowX[0].tagName!="HTML"){C.overflowXOffset=C.overflowX.offset()}},sort:function(E,D){var F=D.options;var C=B(this).data("sortable");if(C.overflowY[0]!=document&&C.overflowY[0].tagName!="HTML"){if((C.overflowYOffset.top+C.overflowY[0].offsetHeight)-E.pageY<F.scrollSensitivity){C.overflowY[0].scrollTop=C.overflowY[0].scrollTop+F.scrollSpeed}if(E.pageY-C.overflowYOffset.top<F.scrollSensitivity){C.overflowY[0].scrollTop=C.overflowY[0].scrollTop-F.scrollSpeed}}else{if(E.pageY-B(document).scrollTop()<F.scrollSensitivity){B(document).scrollTop(B(document).scrollTop()-F.scrollSpeed)}if(B(window).height()-(E.pageY-B(document).scrollTop())<F.scrollSensitivity){B(document).scrollTop(B(document).scrollTop()+F.scrollSpeed)}}if(C.overflowX[0]!=document&&C.overflowX[0].tagName!="HTML"){if((C.overflowXOffset.left+C.overflowX[0].offsetWidth)-E.pageX<F.scrollSensitivity){C.overflowX[0].scrollLeft=C.overflowX[0].scrollLeft+F.scrollSpeed}if(E.pageX-C.overflowXOffset.left<F.scrollSensitivity){C.overflowX[0].scrollLeft=C.overflowX[0].scrollLeft-F.scrollSpeed}}else{if(E.pageX-B(document).scrollLeft()<F.scrollSensitivity){B(document).scrollLeft(B(document).scrollLeft()-F.scrollSpeed)}if(B(window).width()-(E.pageX-B(document).scrollLeft())<F.scrollSensitivity){B(document).scrollLeft(B(document).scrollLeft()+F.scrollSpeed)}}}});B.ui.plugin.add("sortable","axis",{sort:function(E,D){var C=B(this).data("sortable");if(D.options.axis=="y"){C.position.left=C.originalPosition.left}if(D.options.axis=="x"){C.position.top=C.originalPosition.top}}})})(jQuery);(function(C){C.effects=C.effects||{};C.extend(C.effects,{save:function(F,G){for(var E=0;E<G.length;E++){if(G[E]!==null){C.data(F[0],"ec.storage."+G[E],F[0].style[G[E]])}}},restore:function(F,G){for(var E=0;E<G.length;E++){if(G[E]!==null){F.css(G[E],C.data(F[0],"ec.storage."+G[E]))}}},setMode:function(E,F){if(F=="toggle"){F=E.is(":hidden")?"show":"hide"}return F},getBaseline:function(F,G){var H,E;switch(F[0]){case"top":H=0;break;case"middle":H=0.5;break;case"bottom":H=1;break;default:H=F[0]/G.height}switch(F[1]){case"left":E=0;break;case"center":E=0.5;break;case"right":E=1;break;default:E=F[1]/G.width}return{x:E,y:H}},createWrapper:function(F){if(F.parent().attr("id")=="fxWrapper"){return F}var E={width:F.outerWidth({margin:true}),height:F.outerHeight({margin:true}),"float":F.css("float")};F.wrap('<div id="fxWrapper" style="font-size:100%;background:transparent;border:none;margin:0;padding:0"></div>');var I=F.parent();if(F.css("position")=="static"){I.css({position:"relative"});F.css({position:"relative"})}else{var H=F.css("top");if(isNaN(parseInt(H))){H="auto"}var G=F.css("left");if(isNaN(parseInt(G))){G="auto"}I.css({position:F.css("position"),top:H,left:G,zIndex:F.css("z-index")}).show();F.css({position:"relative",top:0,left:0})}I.css(E);return I},removeWrapper:function(E){if(E.parent().attr("id")=="fxWrapper"){return E.parent().replaceWith(E)}return E},setTransition:function(F,G,E,H){H=H||{};C.each(G,function(J,I){unit=F.cssUnit(I);if(unit[0]>0){H[I]=unit[0]*E+unit[1]}});return H},animateClass:function(G,H,J,I){var E=(typeof J=="function"?J:(I?I:null));var F=(typeof J=="object"?J:null);return this.each(function(){var O={};var M=C(this);var N=M.attr("style")||"";if(typeof N=="object"){N=N["cssText"]}if(G.toggle){M.hasClass(G.toggle)?G.remove=G.toggle:G.add=G.toggle}var K=C.extend({},(document.defaultView?document.defaultView.getComputedStyle(this,null):this.currentStyle));if(G.add){M.addClass(G.add)}if(G.remove){M.removeClass(G.remove)}var L=C.extend({},(document.defaultView?document.defaultView.getComputedStyle(this,null):this.currentStyle));if(G.add){M.removeClass(G.add)}if(G.remove){M.addClass(G.remove)}for(var P in L){if(typeof L[P]!="function"&&L[P]&&P.indexOf("Moz")==-1&&P.indexOf("length")==-1&&L[P]!=K[P]&&(P.match(/color/i)||(!P.match(/color/i)&&!isNaN(parseInt(L[P],10))))&&(K.position!="static"||(K.position=="static"&&!P.match(/left|top|bottom|right/)))){O[P]=L[P]}}M.animate(O,H,F,function(){if(typeof C(this).attr("style")=="object"){C(this).attr("style")["cssText"]="";C(this).attr("style")["cssText"]=N}else{C(this).attr("style",N)}if(G.add){C(this).addClass(G.add)}if(G.remove){C(this).removeClass(G.remove)}if(E){E.apply(this,arguments)}})})}});C.fn.extend({_show:C.fn.show,_hide:C.fn.hide,__toggle:C.fn.toggle,_addClass:C.fn.addClass,_removeClass:C.fn.removeClass,_toggleClass:C.fn.toggleClass,effect:function(E,G,F,H){return C.effects[E]?C.effects[E].call(this,{method:E,options:G||{},duration:F,callback:H}):null},show:function(){if(!arguments[0]||(arguments[0].constructor==Number||/(slow|normal|fast)/.test(arguments[0]))){return this._show.apply(this,arguments)}else{var E=arguments[1]||{};E["mode"]="show";return this.effect.apply(this,[arguments[0],E,arguments[2]||E.duration,arguments[3]||E.callback])}},hide:function(){if(!arguments[0]||(arguments[0].constructor==Number||/(slow|normal|fast)/.test(arguments[0]))){return this._hide.apply(this,arguments)}else{var E=arguments[1]||{};E["mode"]="hide";return this.effect.apply(this,[arguments[0],E,arguments[2]||E.duration,arguments[3]||E.callback])}},toggle:function(){if(!arguments[0]||(arguments[0].constructor==Number||/(slow|normal|fast)/.test(arguments[0]))||(arguments[0].constructor==Function)){return this.__toggle.apply(this,arguments)}else{var E=arguments[1]||{};E["mode"]="toggle";return this.effect.apply(this,[arguments[0],E,arguments[2]||E.duration,arguments[3]||E.callback])}},addClass:function(F,E,H,G){return E?C.effects.animateClass.apply(this,[{add:F},E,H,G]):this._addClass(F)},removeClass:function(F,E,H,G){return E?C.effects.animateClass.apply(this,[{remove:F},E,H,G]):this._removeClass(F)},toggleClass:function(F,E,H,G){return E?C.effects.animateClass.apply(this,[{toggle:F},E,H,G]):this._toggleClass(F)},morph:function(E,G,F,I,H){return C.effects.animateClass.apply(this,[{add:G,remove:E},F,I,H])},switchClass:function(){return this.morph.apply(this,arguments)},cssUnit:function(E){var F=this.css(E),G=[];C.each(["em","px","%","pt"],function(H,I){if(F.indexOf(I)>0){G=[parseFloat(F),I]}});return G}});jQuery.each(["backgroundColor","borderBottomColor","borderLeftColor","borderRightColor","borderTopColor","color","outlineColor"],function(F,E){jQuery.fx.step[E]=function(G){if(G.state==0){G.start=D(G.elem,E);G.end=B(G.end)}G.elem.style[E]="rgb("+[Math.max(Math.min(parseInt((G.pos*(G.end[0]-G.start[0]))+G.start[0]),255),0),Math.max(Math.min(parseInt((G.pos*(G.end[1]-G.start[1]))+G.start[1]),255),0),Math.max(Math.min(parseInt((G.pos*(G.end[2]-G.start[2]))+G.start[2]),255),0)].join(",")+")"}});function B(F){var E;if(F&&F.constructor==Array&&F.length==3){return F}if(E=/rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(F)){return[parseInt(E[1]),parseInt(E[2]),parseInt(E[3])]}if(E=/rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(F)){return[parseFloat(E[1])*2.55,parseFloat(E[2])*2.55,parseFloat(E[3])*2.55]}if(E=/#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(F)){return[parseInt(E[1],16),parseInt(E[2],16),parseInt(E[3],16)]}if(E=/#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(F)){return[parseInt(E[1]+E[1],16),parseInt(E[2]+E[2],16),parseInt(E[3]+E[3],16)]}if(E=/rgba\(0, 0, 0, 0\)/.exec(F)){return A["transparent"]}return A[jQuery.trim(F).toLowerCase()]}function D(G,E){var F;do{F=jQuery.curCSS(G,E);if(F!=""&&F!="transparent"||jQuery.nodeName(G,"body")){break}E="backgroundColor"}while(G=G.parentNode);return B(F)}var A={aqua:[0,255,255],azure:[240,255,255],beige:[245,245,220],black:[0,0,0],blue:[0,0,255],brown:[165,42,42],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgrey:[169,169,169],darkgreen:[0,100,0],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkviolet:[148,0,211],fuchsia:[255,0,255],gold:[255,215,0],green:[0,128,0],indigo:[75,0,130],khaki:[240,230,140],lightblue:[173,216,230],lightcyan:[224,255,255],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightyellow:[255,255,224],lime:[0,255,0],magenta:[255,0,255],maroon:[128,0,0],navy:[0,0,128],olive:[128,128,0],orange:[255,165,0],pink:[255,192,203],purple:[128,0,128],violet:[128,0,128],red:[255,0,0],silver:[192,192,192],white:[255,255,255],yellow:[255,255,0],transparent:[255,255,255]};jQuery.easing["jswing"]=jQuery.easing["swing"];jQuery.extend(jQuery.easing,{def:"easeOutQuad",swing:function(F,G,E,I,H){return jQuery.easing[jQuery.easing.def](F,G,E,I,H)},easeInQuad:function(F,G,E,I,H){return I*(G/=H)*G+E},easeOutQuad:function(F,G,E,I,H){return -I*(G/=H)*(G-2)+E},easeInOutQuad:function(F,G,E,I,H){if((G/=H/2)<1){return I/2*G*G+E}return -I/2*((--G)*(G-2)-1)+E},easeInCubic:function(F,G,E,I,H){return I*(G/=H)*G*G+E},easeOutCubic:function(F,G,E,I,H){return I*((G=G/H-1)*G*G+1)+E},easeInOutCubic:function(F,G,E,I,H){if((G/=H/2)<1){return I/2*G*G*G+E}return I/2*((G-=2)*G*G+2)+E},easeInQuart:function(F,G,E,I,H){return I*(G/=H)*G*G*G+E},easeOutQuart:function(F,G,E,I,H){return -I*((G=G/H-1)*G*G*G-1)+E},easeInOutQuart:function(F,G,E,I,H){if((G/=H/2)<1){return I/2*G*G*G*G+E}return -I/2*((G-=2)*G*G*G-2)+E},easeInQuint:function(F,G,E,I,H){return I*(G/=H)*G*G*G*G+E},easeOutQuint:function(F,G,E,I,H){return I*((G=G/H-1)*G*G*G*G+1)+E},easeInOutQuint:function(F,G,E,I,H){if((G/=H/2)<1){return I/2*G*G*G*G*G+E}return I/2*((G-=2)*G*G*G*G+2)+E},easeInSine:function(F,G,E,I,H){return -I*Math.cos(G/H*(Math.PI/2))+I+E},easeOutSine:function(F,G,E,I,H){return I*Math.sin(G/H*(Math.PI/2))+E},easeInOutSine:function(F,G,E,I,H){return -I/2*(Math.cos(Math.PI*G/H)-1)+E},easeInExpo:function(F,G,E,I,H){return(G==0)?E:I*Math.pow(2,10*(G/H-1))+E},easeOutExpo:function(F,G,E,I,H){return(G==H)?E+I:I*(-Math.pow(2,-10*G/H)+1)+E},easeInOutExpo:function(F,G,E,I,H){if(G==0){return E}if(G==H){return E+I}if((G/=H/2)<1){return I/2*Math.pow(2,10*(G-1))+E}return I/2*(-Math.pow(2,-10*--G)+2)+E},easeInCirc:function(F,G,E,I,H){return -I*(Math.sqrt(1-(G/=H)*G)-1)+E},easeOutCirc:function(F,G,E,I,H){return I*Math.sqrt(1-(G=G/H-1)*G)+E},easeInOutCirc:function(F,G,E,I,H){if((G/=H/2)<1){return -I/2*(Math.sqrt(1-G*G)-1)+E}return I/2*(Math.sqrt(1-(G-=2)*G)+1)+E},easeInElastic:function(F,H,E,L,K){var I=1.70158;var J=0;var G=L;if(H==0){return E}if((H/=K)==1){return E+L}if(!J){J=K*0.3}if(G<Math.abs(L)){G=L;var I=J/4}else{var I=J/(2*Math.PI)*Math.asin(L/G)}return -(G*Math.pow(2,10*(H-=1))*Math.sin((H*K-I)*(2*Math.PI)/J))+E},easeOutElastic:function(F,H,E,L,K){var I=1.70158;var J=0;var G=L;if(H==0){return E}if((H/=K)==1){return E+L}if(!J){J=K*0.3}if(G<Math.abs(L)){G=L;var I=J/4}else{var I=J/(2*Math.PI)*Math.asin(L/G)}return G*Math.pow(2,-10*H)*Math.sin((H*K-I)*(2*Math.PI)/J)+L+E},easeInOutElastic:function(F,H,E,L,K){var I=1.70158;var J=0;var G=L;if(H==0){return E}if((H/=K/2)==2){return E+L}if(!J){J=K*(0.3*1.5)}if(G<Math.abs(L)){G=L;var I=J/4}else{var I=J/(2*Math.PI)*Math.asin(L/G)}if(H<1){return -0.5*(G*Math.pow(2,10*(H-=1))*Math.sin((H*K-I)*(2*Math.PI)/J))+E}return G*Math.pow(2,-10*(H-=1))*Math.sin((H*K-I)*(2*Math.PI)/J)*0.5+L+E},easeInBack:function(F,G,E,J,I,H){if(H==undefined){H=1.70158}return J*(G/=I)*G*((H+1)*G-H)+E},easeOutBack:function(F,G,E,J,I,H){if(H==undefined){H=1.70158}return J*((G=G/I-1)*G*((H+1)*G+H)+1)+E},easeInOutBack:function(F,G,E,J,I,H){if(H==undefined){H=1.70158}if((G/=I/2)<1){return J/2*(G*G*(((H*=(1.525))+1)*G-H))+E}return J/2*((G-=2)*G*(((H*=(1.525))+1)*G+H)+2)+E},easeInBounce:function(F,G,E,I,H){return I-jQuery.easing.easeOutBounce(F,H-G,0,I,H)+E},easeOutBounce:function(F,G,E,I,H){if((G/=H)<(1/2.75)){return I*(7.5625*G*G)+E}else{if(G<(2/2.75)){return I*(7.5625*(G-=(1.5/2.75))*G+0.75)+E}else{if(G<(2.5/2.75)){return I*(7.5625*(G-=(2.25/2.75))*G+0.9375)+E}else{return I*(7.5625*(G-=(2.625/2.75))*G+0.984375)+E}}}},easeInOutBounce:function(F,G,E,I,H){if(G<H/2){return jQuery.easing.easeInBounce(F,G*2,0,I,H)*0.5+E}return jQuery.easing.easeOutBounce(F,G*2-H,0,I,H)*0.5+I*0.5+E}})})(jQuery);(function(A){A.effects.blind=function(B){return this.queue(function(){var D=A(this),C=["position","top","left"];var H=A.effects.setMode(D,B.options.mode||"hide");var G=B.options.direction||"vertical";A.effects.save(D,C);D.show();var J=A.effects.createWrapper(D).css({overflow:"hidden"});var E=(G=="vertical")?"height":"width";var I=(G=="vertical")?J.height():J.width();if(H=="show"){J.css(E,0)}var F={};F[E]=H=="show"?I:0;J.animate(F,B.duration,B.options.easing,function(){if(H=="hide"){D.hide()}A.effects.restore(D,C);A.effects.removeWrapper(D);if(B.callback){B.callback.apply(D[0],arguments)}D.dequeue()})})}})(jQuery);(function(A){A.effects.bounce=function(B){return this.queue(function(){var E=A(this),K=["position","top","left"];var J=A.effects.setMode(E,B.options.mode||"effect");var M=B.options.direction||"up";var C=B.options.distance||20;var D=B.options.times||5;var G=B.duration||250;if(/show|hide/.test(J)){K.push("opacity")}A.effects.save(E,K);E.show();A.effects.createWrapper(E);var F=(M=="up"||M=="down")?"top":"left";var O=(M=="up"||M=="left")?"pos":"neg";var C=B.options.distance||(F=="top"?E.outerHeight({margin:true})/3:E.outerWidth({margin:true})/3);if(J=="show"){E.css("opacity",0).css(F,O=="pos"?-C:C)}if(J=="hide"){C=C/(D*2)}if(J!="hide"){D--}if(J=="show"){var H={opacity:1};H[F]=(O=="pos"?"+=":"-=")+C;E.animate(H,G/2,B.options.easing);C=C/2;D--}for(var I=0;I<D;I++){var N={},L={};N[F]=(O=="pos"?"-=":"+=")+C;L[F]=(O=="pos"?"+=":"-=")+C;E.animate(N,G/2,B.options.easing).animate(L,G/2,B.options.easing);C=(J=="hide")?C*2:C/2}if(J=="hide"){var H={opacity:0};H[F]=(O=="pos"?"-=":"+=")+C;E.animate(H,G/2,B.options.easing,function(){E.hide();A.effects.restore(E,K);A.effects.removeWrapper(E);if(B.callback){B.callback.apply(this,arguments)}})}else{var N={},L={};N[F]=(O=="pos"?"-=":"+=")+C;L[F]=(O=="pos"?"+=":"-=")+C;E.animate(N,G/2,B.options.easing).animate(L,G/2,B.options.easing,function(){A.effects.restore(E,K);A.effects.removeWrapper(E);if(B.callback){B.callback.apply(this,arguments)}})}E.queue("fx",function(){E.dequeue()});E.dequeue()})}})(jQuery);(function(A){A.effects.clip=function(B){return this.queue(function(){var F=A(this),J=["position","top","left","height","width"];var I=A.effects.setMode(F,B.options.mode||"hide");var K=B.options.direction||"vertical";A.effects.save(F,J);F.show();var C=A.effects.createWrapper(F).css({overflow:"hidden"});var E=F[0].tagName=="IMG"?C:F;var G={size:(K=="vertical")?"height":"width",position:(K=="vertical")?"top":"left"};var D=(K=="vertical")?E.height():E.width();if(I=="show"){E.css(G.size,0);E.css(G.position,D/2)}var H={};H[G.size]=I=="show"?D:0;H[G.position]=I=="show"?0:D/2;E.animate(H,{queue:false,duration:B.duration,easing:B.options.easing,complete:function(){if(I=="hide"){F.hide()}A.effects.restore(F,J);A.effects.removeWrapper(F);if(B.callback){B.callback.apply(F[0],arguments)}F.dequeue()}})})}})(jQuery);(function(A){A.effects.drop=function(B){return this.queue(function(){var E=A(this),D=["position","top","left","opacity"];var I=A.effects.setMode(E,B.options.mode||"hide");var H=B.options.direction||"left";A.effects.save(E,D);E.show();A.effects.createWrapper(E);var F=(H=="up"||H=="down")?"top":"left";var C=(H=="up"||H=="left")?"pos":"neg";var J=B.options.distance||(F=="top"?E.outerHeight({margin:true})/2:E.outerWidth({margin:true})/2);if(I=="show"){E.css("opacity",0).css(F,C=="pos"?-J:J)}var G={opacity:I=="show"?1:0};G[F]=(I=="show"?(C=="pos"?"+=":"-="):(C=="pos"?"-=":"+="))+J;E.animate(G,{queue:false,duration:B.duration,easing:B.options.easing,complete:function(){if(I=="hide"){E.hide()}A.effects.restore(E,D);A.effects.removeWrapper(E);if(B.callback){B.callback.apply(this,arguments)}E.dequeue()}})})}})(jQuery);(function(A){A.effects.explode=function(B){return this.queue(function(){var I=B.options.pieces?Math.round(Math.sqrt(B.options.pieces)):3;var E=B.options.pieces?Math.round(Math.sqrt(B.options.pieces)):3;B.options.mode=B.options.mode=="toggle"?(A(this).is(":visible")?"hide":"show"):B.options.mode;var H=A(this).show().css("visibility","hidden");var J=H.offset();J.top-=parseInt(H.css("marginTop"))||0;J.left-=parseInt(H.css("marginLeft"))||0;var G=H.outerWidth(true);var C=H.outerHeight(true);for(var F=0;F<I;F++){for(var D=0;D<E;D++){H.clone().appendTo("body").wrap("<div></div>").css({position:"absolute",visibility:"visible",left:-D*(G/E),top:-F*(C/I)}).parent().addClass("effects-explode").css({position:"absolute",overflow:"hidden",width:G/E,height:C/I,left:J.left+D*(G/E)+(B.options.mode=="show"?(D-Math.floor(E/2))*(G/E):0),top:J.top+F*(C/I)+(B.options.mode=="show"?(F-Math.floor(I/2))*(C/I):0),opacity:B.options.mode=="show"?0:1}).animate({left:J.left+D*(G/E)+(B.options.mode=="show"?0:(D-Math.floor(E/2))*(G/E)),top:J.top+F*(C/I)+(B.options.mode=="show"?0:(F-Math.floor(I/2))*(C/I)),opacity:B.options.mode=="show"?1:0},B.duration||500)}}setTimeout(function(){B.options.mode=="show"?H.css({visibility:"visible"}):H.css({visibility:"visible"}).hide();if(B.callback){B.callback.apply(H[0])}H.dequeue();A(".effects-explode").remove()},B.duration||500)})}})(jQuery);(function(A){A.effects.fold=function(B){return this.queue(function(){var E=A(this),J=["position","top","left"];var G=A.effects.setMode(E,B.options.mode||"hide");var N=B.options.size||15;var M=!(!B.options.horizFirst);A.effects.save(E,J);E.show();var D=A.effects.createWrapper(E).css({overflow:"hidden"});var H=((G=="show")!=M);var F=H?["width","height"]:["height","width"];var C=H?[D.width(),D.height()]:[D.height(),D.width()];var I=/([0-9]+)%/.exec(N);if(I){N=parseInt(I[1])/100*C[G=="hide"?0:1]}if(G=="show"){D.css(M?{height:0,width:N}:{height:N,width:0})}var L={},K={};L[F[0]]=G=="show"?C[0]:N;K[F[1]]=G=="show"?C[1]:0;D.animate(L,B.duration/2,B.options.easing).animate(K,B.duration/2,B.options.easing,function(){if(G=="hide"){E.hide()}A.effects.restore(E,J);A.effects.removeWrapper(E);if(B.callback){B.callback.apply(E[0],arguments)}E.dequeue()})})}})(jQuery);(function(A){A.effects.highlight=function(B){return this.queue(function(){var E=A(this),D=["backgroundImage","backgroundColor","opacity"];var H=A.effects.setMode(E,B.options.mode||"show");var C=B.options.color||"#ffff99";var G=E.css("backgroundColor");A.effects.save(E,D);E.show();E.css({backgroundImage:"none",backgroundColor:C});var F={backgroundColor:G};if(H=="hide"){F["opacity"]=0}E.animate(F,{queue:false,duration:B.duration,easing:B.options.easing,complete:function(){if(H=="hide"){E.hide()}A.effects.restore(E,D);if(H=="show"&&jQuery.browser.msie){this.style.removeAttribute("filter")}if(B.callback){B.callback.apply(this,arguments)}E.dequeue()}})})}})(jQuery);(function(A){A.effects.pulsate=function(B){return this.queue(function(){var D=A(this);var F=A.effects.setMode(D,B.options.mode||"show");var E=B.options.times||5;if(F=="hide"){E--}if(D.is(":hidden")){D.css("opacity",0);D.show();D.animate({opacity:1},B.duration/2,B.options.easing);E=E-2}for(var C=0;C<E;C++){D.animate({opacity:0},B.duration/2,B.options.easing).animate({opacity:1},B.duration/2,B.options.easing)}if(F=="hide"){D.animate({opacity:0},B.duration/2,B.options.easing,function(){D.hide();if(B.callback){B.callback.apply(this,arguments)}})}else{D.animate({opacity:0},B.duration/2,B.options.easing).animate({opacity:1},B.duration/2,B.options.easing,function(){if(B.callback){B.callback.apply(this,arguments)}})}D.queue("fx",function(){D.dequeue()});D.dequeue()})}})(jQuery);(function(A){A.effects.puff=function(B){return this.queue(function(){var F=A(this);var C=A.extend(true,{},B.options);var H=A.effects.setMode(F,B.options.mode||"hide");var G=parseInt(B.options.percent)||150;C.fade=true;var E={height:F.height(),width:F.width()};var D=G/100;F.from=(H=="hide")?E:{height:E.height*D,width:E.width*D};C.from=F.from;C.percent=(H=="hide")?G:100;C.mode=H;F.effect("scale",C,B.duration,B.callback);F.dequeue()})};A.effects.scale=function(B){return this.queue(function(){var G=A(this);var D=A.extend(true,{},B.options);var J=A.effects.setMode(G,B.options.mode||"effect");var H=parseInt(B.options.percent)||(parseInt(B.options.percent)==0?0:(J=="hide"?0:100));var I=B.options.direction||"both";var C=B.options.origin;if(J!="effect"){D.origin=C||["middle","center"];D.restore=true}var F={height:G.height(),width:G.width()};G.from=B.options.from||(J=="show"?{height:0,width:0}:F);var E={y:I!="horizontal"?(H/100):1,x:I!="vertical"?(H/100):1};G.to={height:F.height*E.y,width:F.width*E.x};if(B.options.fade){if(J=="show"){G.from.opacity=0;G.to.opacity=1}if(J=="hide"){G.from.opacity=1;G.to.opacity=0}}D.from=G.from;D.to=G.to;D.mode=J;G.effect("size",D,B.duration,B.callback);G.dequeue()})};A.effects.size=function(B){return this.queue(function(){var C=A(this),N=["position","top","left","width","height","overflow","opacity"];var M=["position","top","left","overflow","opacity"];var J=["width","height","overflow"];var P=["fontSize"];var K=["borderTopWidth","borderBottomWidth","paddingTop","paddingBottom"];var F=["borderLeftWidth","borderRightWidth","paddingLeft","paddingRight"];var G=A.effects.setMode(C,B.options.mode||"effect");var I=B.options.restore||false;var E=B.options.scale||"both";var O=B.options.origin;var D={height:C.height(),width:C.width()};C.from=B.options.from||D;C.to=B.options.to||D;if(O){var H=A.effects.getBaseline(O,D);C.from.top=(D.height-C.from.height)*H.y;C.from.left=(D.width-C.from.width)*H.x;C.to.top=(D.height-C.to.height)*H.y;C.to.left=(D.width-C.to.width)*H.x}var L={from:{y:C.from.height/D.height,x:C.from.width/D.width},to:{y:C.to.height/D.height,x:C.to.width/D.width}};if(E=="box"||E=="both"){if(L.from.y!=L.to.y){N=N.concat(K);C.from=A.effects.setTransition(C,K,L.from.y,C.from);C.to=A.effects.setTransition(C,K,L.to.y,C.to)}if(L.from.x!=L.to.x){N=N.concat(F);C.from=A.effects.setTransition(C,F,L.from.x,C.from);C.to=A.effects.setTransition(C,F,L.to.x,C.to)}}if(E=="content"||E=="both"){if(L.from.y!=L.to.y){N=N.concat(P);C.from=A.effects.setTransition(C,P,L.from.y,C.from);C.to=A.effects.setTransition(C,P,L.to.y,C.to)}}A.effects.save(C,I?N:M);C.show();A.effects.createWrapper(C);C.css("overflow","hidden").css(C.from);if(E=="content"||E=="both"){K=K.concat(["marginTop","marginBottom"]).concat(P);F=F.concat(["marginLeft","marginRight"]);J=N.concat(K).concat(F);C.find("*[width]").each(function(){child=A(this);if(I){A.effects.save(child,J)}var Q={height:child.height(),width:child.width()};child.from={height:Q.height*L.from.y,width:Q.width*L.from.x};child.to={height:Q.height*L.to.y,width:Q.width*L.to.x};if(L.from.y!=L.to.y){child.from=A.effects.setTransition(child,K,L.from.y,child.from);child.to=A.effects.setTransition(child,K,L.to.y,child.to)}if(L.from.x!=L.to.x){child.from=A.effects.setTransition(child,F,L.from.x,child.from);child.to=A.effects.setTransition(child,F,L.to.x,child.to)}child.css(child.from);child.animate(child.to,B.duration,B.options.easing,function(){if(I){A.effects.restore(child,J)}})})}C.animate(C.to,{queue:false,duration:B.duration,easing:B.options.easing,complete:function(){if(G=="hide"){C.hide()}A.effects.restore(C,I?N:M);A.effects.removeWrapper(C);if(B.callback){B.callback.apply(this,arguments)}C.dequeue()}})})}})(jQuery);(function(A){A.effects.shake=function(B){return this.queue(function(){var E=A(this),K=["position","top","left"];var J=A.effects.setMode(E,B.options.mode||"effect");var M=B.options.direction||"left";var C=B.options.distance||20;var D=B.options.times||3;var G=B.duration||B.options.duration||140;A.effects.save(E,K);E.show();A.effects.createWrapper(E);var F=(M=="up"||M=="down")?"top":"left";var O=(M=="up"||M=="left")?"pos":"neg";var H={},N={},L={};H[F]=(O=="pos"?"-=":"+=")+C;N[F]=(O=="pos"?"+=":"-=")+C*2;L[F]=(O=="pos"?"-=":"+=")+C*2;E.animate(H,G,B.options.easing);for(var I=1;I<D;I++){E.animate(N,G,B.options.easing).animate(L,G,B.options.easing)}E.animate(N,G,B.options.easing).animate(H,G/2,B.options.easing,function(){A.effects.restore(E,K);A.effects.removeWrapper(E);if(B.callback){B.callback.apply(this,arguments)}});E.queue("fx",function(){E.dequeue()});E.dequeue()})}})(jQuery);(function(A){A.effects.slide=function(B){return this.queue(function(){var E=A(this),D=["position","top","left"];var I=A.effects.setMode(E,B.options.mode||"show");var H=B.options.direction||"left";A.effects.save(E,D);E.show();A.effects.createWrapper(E).css({overflow:"hidden"});var F=(H=="up"||H=="down")?"top":"left";var C=(H=="up"||H=="left")?"pos":"neg";var J=B.options.distance||(F=="top"?E.outerHeight({margin:true}):E.outerWidth({margin:true}));if(I=="show"){E.css(F,C=="pos"?-J:J)}var G={};G[F]=(I=="show"?(C=="pos"?"+=":"-="):(C=="pos"?"-=":"+="))+J;E.animate(G,{queue:false,duration:B.duration,easing:B.options.easing,complete:function(){if(I=="hide"){E.hide()}A.effects.restore(E,D);A.effects.removeWrapper(E);if(B.callback){B.callback.apply(this,arguments)}E.dequeue()}})})}})(jQuery);(function(A){A.effects.transfer=function(B){return this.queue(function(){var E=A(this);var G=A.effects.setMode(E,B.options.mode||"effect");var F=A(B.options.to);var C=E.offset();var D=A('<div class="ui-effects-transfer"></div>').appendTo(document.body);if(B.options.className){D.addClass(B.options.className)}D.addClass(B.options.className);D.css({top:C.top,left:C.left,height:E.outerHeight()-parseInt(D.css("borderTopWidth"))-parseInt(D.css("borderBottomWidth")),width:E.outerWidth()-parseInt(D.css("borderLeftWidth"))-parseInt(D.css("borderRightWidth")),position:"absolute"});C=F.offset();animation={top:C.top,left:C.left,height:F.outerHeight()-parseInt(D.css("borderTopWidth"))-parseInt(D.css("borderBottomWidth")),width:F.outerWidth()-parseInt(D.css("borderLeftWidth"))-parseInt(D.css("borderRightWidth"))};D.animate(animation,B.duration,B.options.easing,function(){D.remove();if(B.callback){B.callback.apply(E[0],arguments)}E.dequeue()})})}})(jQuery);(function(E){E.widget("ui.accordion",{_init:function(){var G=this.options;if(G.navigation){var J=this.element.find("a").filter(G.navigationFilter);if(J.length){if(J.filter(G.header).length){G.active=J}else{G.active=J.parent().parent().prev();J.addClass("current")}}}G.headers=this.element.find(G.header);G.active=C(G.headers,G.active);if(E.browser.msie){this.element.find("a").css("zoom","1")}if(!this.element.hasClass("ui-accordion")){this.element.addClass("ui-accordion");E('<span class="ui-accordion-left"/>').insertBefore(G.headers);E('<span class="ui-accordion-right"/>').appendTo(G.headers);G.headers.addClass("ui-accordion-header").attr("tabindex","0")}var I;if(G.fillSpace){I=this.element.parent().height();G.headers.each(function(){I-=E(this).outerHeight()});var H=0;G.headers.next().each(function(){H=Math.max(H,E(this).innerHeight()-E(this).height())}).height(I-H)}else{if(G.autoHeight){I=0;G.headers.next().each(function(){I=Math.max(I,E(this).outerHeight())}).height(I)}}G.headers.not(G.active||"").next().hide();G.active.parent().andSelf().addClass(G.selectedClass);if(G.event){this.element.bind((G.event)+".accordion",F)}},activate:function(G){F.call(this.element[0],{target:C(this.options.headers,G)[0]})},destroy:function(){this.options.headers.next().css("display","");if(this.options.fillSpace||this.options.autoHeight){this.options.headers.next().css("height","")}E.removeData(this.element[0],"accordion");this.element.removeClass("ui-accordion").unbind(".accordion")}});function B(H,G){return function(){return H.apply(G,arguments)}}function D(I){if(!E.data(this,"accordion")){return }var G=E.data(this,"accordion");var H=G.options;H.running=I?0:--H.running;if(H.running){return }if(H.clearStyle){H.toShow.add(H.toHide).css({height:"",overflow:""})}G._trigger("change",null,H.data)}function A(G,K,L,J,M){var I=E.data(this,"accordion").options;I.toShow=G;I.toHide=K;I.data=L;var H=B(D,this);E.data(this,"accordion")._trigger("changestart",null,I.data);I.running=K.size()===0?G.size():K.size();if(I.animated){if(!I.alwaysOpen&&J){E.ui.accordion.animations[I.animated]({toShow:jQuery([]),toHide:K,complete:H,down:M,autoHeight:I.autoHeight})}else{E.ui.accordion.animations[I.animated]({toShow:G,toHide:K,complete:H,down:M,autoHeight:I.autoHeight})}}else{if(!I.alwaysOpen&&J){G.toggle()}else{K.hide();G.show()}H(true)}}function F(L){var J=E.data(this,"accordion").options;if(J.disabled){return false}if(!L.target&&!J.alwaysOpen){J.active.parent().andSelf().toggleClass(J.selectedClass);var I=J.active.next(),M={options:J,newHeader:jQuery([]),oldHeader:J.active,newContent:jQuery([]),oldContent:I},G=(J.active=E([]));A.call(this,G,I,M);return false}var K=E(L.target);K=E(K.parents(J.header)[0]||K);var H=K[0]==J.active[0];if(J.running||(J.alwaysOpen&&H)){return false}if(!K.is(J.header)){return }J.active.parent().andSelf().toggleClass(J.selectedClass);if(!H){K.parent().andSelf().addClass(J.selectedClass)}var G=K.next(),I=J.active.next(),M={options:J,newHeader:H&&!J.alwaysOpen?E([]):K,oldHeader:J.active,newContent:H&&!J.alwaysOpen?E([]):G,oldContent:I},N=J.headers.index(J.active[0])>J.headers.index(K[0]);J.active=H?E([]):K;A.call(this,G,I,M,H,N);return false}function C(H,G){return G?typeof G=="number"?H.filter(":eq("+G+")"):H.not(H.not(G)):G===false?E([]):H.filter(":eq(0)")}E.extend(E.ui.accordion,{defaults:{selectedClass:"selected",alwaysOpen:true,animated:"slide",event:"click",header:"a",autoHeight:true,running:0,navigationFilter:function(){return this.href.toLowerCase()==location.href.toLowerCase()}},animations:{slide:function(G,I){G=E.extend({easing:"swing",duration:300},G,I);if(!G.toHide.size()){G.toShow.animate({height:"show"},G);return }var H=G.toHide.height(),J=G.toShow.height(),K=J/H;G.toShow.css({height:0,overflow:"hidden"}).show();G.toHide.filter(":hidden").each(G.complete).end().filter(":visible").animate({height:"hide"},{step:function(L){var M=(H-L)*K;if(E.browser.msie||E.browser.opera){M=Math.ceil(M)}G.toShow.height(M)},duration:G.duration,easing:G.easing,complete:function(){if(!G.autoHeight){G.toShow.css("height","auto")}G.complete()}})},bounceslide:function(G){this.slide(G,{easing:G.down?"bounceout":"swing",duration:G.down?1000:200})},easeslide:function(G){this.slide(G,{easing:"easeinout",duration:700})}}})})(jQuery);(function(A){A.widget("ui.autocomplete",{_init:function(){A.extend(this.options,{delay:this.options.url?A.Autocompleter.defaults.delay:10,max:!this.options.scroll?10:150,highlight:this.options.highlight||function(B){return B},formatMatch:this.options.formatMatch||this.options.formatItem});new A.Autocompleter(this.element[0],this.options)},result:function(B){return this.element.bind("result",B)},search:function(B){return this.element.trigger("search",[B])},flushCache:function(){return this.element.trigger("flushCache")},setData:function(B,C){return this.element.trigger("setOptions",[{key:C}])},destroy:function(){return this.element.trigger("unautocomplete")}});A.Autocompleter=function(L,G){var C={UP:38,DOWN:40,DEL:46,TAB:9,RETURN:13,ESC:27,COMMA:188,PAGEUP:33,PAGEDOWN:34,BACKSPACE:8};var B=A(L).attr("autocomplete","off").addClass(G.inputClass);if(G.result){B.bind("result.autocomplete",G.result)}var J;var P="";var M=A.Autocompleter.Cache(G);var E=0;var U;var X={mouseDownOnSelect:false};var R=A.Autocompleter.Select(G,L,D,X);var W;A.browser.opera&&A(L.form).bind("submit.autocomplete",function(){if(W){W=false;return false}});B.bind((A.browser.opera?"keypress":"keydown")+".autocomplete",function(Y){U=Y.keyCode;switch(Y.keyCode){case C.UP:Y.preventDefault();if(R.visible()){R.prev()}else{T(0,true)}break;case C.DOWN:Y.preventDefault();if(R.visible()){R.next()}else{T(0,true)}break;case C.PAGEUP:Y.preventDefault();if(R.visible()){R.pageUp()}else{T(0,true)}break;case C.PAGEDOWN:Y.preventDefault();if(R.visible()){R.pageDown()}else{T(0,true)}break;case G.multiple&&A.trim(G.multipleSeparator)==","&&C.COMMA:case C.TAB:case C.RETURN:if(D()){Y.preventDefault();W=true;return false}break;case C.ESC:R.hide();break;default:clearTimeout(J);J=setTimeout(T,G.delay);break}}).focus(function(){E++}).blur(function(){E=0;if(!X.mouseDownOnSelect){S()}}).click(function(){if(E++>1&&!R.visible()){T(0,true)}}).bind("search",function(){var Y=(arguments.length>1)?arguments[1]:null;function Z(d,c){var a;if(c&&c.length){for(var b=0;b<c.length;b++){if(c[b].result.toLowerCase()==d.toLowerCase()){a=c[b];break}}}if(typeof Y=="function"){Y(a)}else{B.trigger("result",a&&[a.data,a.value])}}A.each(H(B.val()),function(a,b){F(b,Z,Z)})}).bind("flushCache",function(){M.flush()}).bind("setOptions",function(){A.extend(G,arguments[1]);if("data" in arguments[1]){M.populate()}}).bind("unautocomplete",function(){R.unbind();B.unbind();A(L.form).unbind(".autocomplete")});function D(){var Z=R.selected();if(!Z){return false}var Y=Z.result;P=Y;if(G.multiple){var a=H(B.val());if(a.length>1){Y=a.slice(0,a.length-1).join(G.multipleSeparator)+G.multipleSeparator+Y}Y+=G.multipleSeparator}B.val(Y);V();B.trigger("result",[Z.data,Z.value]);return true}function T(a,Z){if(U==C.DEL){R.hide();return }var Y=B.val();if(!Z&&Y==P){return }P=Y;Y=I(Y);if(Y.length>=G.minChars){B.addClass(G.loadingClass);if(!G.matchCase){Y=Y.toLowerCase()}F(Y,K,V)}else{N();R.hide()}}function H(Z){if(!Z){return[""]}var a=Z.split(G.multipleSeparator);var Y=[];A.each(a,function(b,c){if(A.trim(c)){Y[b]=A.trim(c)}});return Y}function I(Y){if(!G.multiple){return Y}var Z=H(Y);return Z[Z.length-1]}function Q(Y,Z){if(G.autoFill&&(I(B.val()).toLowerCase()==Y.toLowerCase())&&U!=C.BACKSPACE){B.val(B.val()+Z.substring(I(P).length));A.Autocompleter.Selection(L,P.length,P.length+Z.length)}}function S(){clearTimeout(J);J=setTimeout(V,200)}function V(){var Y=R.visible();R.hide();clearTimeout(J);N();if(G.mustMatch){B.autocomplete("search",function(Z){if(!Z){if(G.multiple){var a=H(B.val()).slice(0,-1);B.val(a.join(G.multipleSeparator)+(a.length?G.multipleSeparator:""))}else{B.val("")}}})}if(Y){A.Autocompleter.Selection(L,L.value.length,L.value.length)}}function K(Z,Y){if(Y&&Y.length&&E){N();R.display(Y,Z);Q(Z,Y[0].value);R.show()}else{V()}}function F(b,d,a){if(!G.matchCase){b=b.toLowerCase()}var c=M.load(b);if(c&&c.length){d(b,c)}else{if((typeof G.url=="string")&&(G.url.length>0)){var f={timestamp:+new Date()};A.each(G.extraParams,function(g,h){f[g]=typeof h=="function"?h():h});A.ajax({mode:"abort",port:"autocomplete"+L.name,dataType:G.dataType,url:G.url,data:A.extend({q:I(b),limit:G.max},f),success:function(h){var g=G.parse&&G.parse(h)||O(h);M.add(b,g);d(b,g)}})}else{if(G.source&&typeof G.source=="function"){var Z=G.source(b);var Y=(G.parse)?G.parse(Z):Z;M.add(b,Y);d(b,Y)}else{R.emptyList();a(b)}}}}function O(b){var Y=[];var a=b.split("\n");for(var Z=0;Z<a.length;Z++){var c=A.trim(a[Z]);if(c){c=c.split("|");Y[Y.length]={data:c,value:c[0],result:G.formatResult&&G.formatResult(c,c[0])||c[0]}}}return Y}function N(){B.removeClass(G.loadingClass)}};A.Autocompleter.defaults={inputClass:"ui-autocomplete-input",resultsClass:"ui-autocomplete-results",loadingClass:"ui-autocomplete-loading",minChars:1,delay:400,matchCase:false,matchSubset:true,matchContains:false,cacheLength:10,max:100,mustMatch:false,extraParams:{},selectFirst:true,formatItem:function(B){return B[0]},formatMatch:null,autoFill:false,width:0,multiple:false,multipleSeparator:", ",highlight:function(C,B){return C.replace(new RegExp("(?![^&;]+;)(?!<[^<>]*)("+B.replace(/([\^\$\(\)\[\]\{\}\*\.\+\?\|\\])/gi,"\\$1")+")(?![^<>]*>)(?![^&;]+;)","gi"),"<strong>$1</strong>")},scroll:true,scrollHeight:180};A.extend(A.ui.autocomplete,{defaults:A.Autocompleter.defaults});A.Autocompleter.Cache=function(C){var F={};var D=0;function H(K,J){if(!C.matchCase){K=K.toLowerCase()}var I=K.indexOf(J);if(I==-1){return false}return I==0||C.matchContains}function G(J,I){if(D>C.cacheLength){B()}if(!F[J]){D++}F[J]=I}function E(){if(!C.data){return false}var J={},I=0;if(!C.url){C.cacheLength=1}J[""]=[];for(var L=0,K=C.data.length;L<K;L++){var O=C.data[L];O=(typeof O=="string")?[O]:O;var N=C.formatMatch(O,L+1,C.data.length);if(N===false){continue}var M=N.charAt(0).toLowerCase();if(!J[M]){J[M]=[]}var P={value:N,data:O,result:C.formatResult&&C.formatResult(O)||N};J[M].push(P);if(I++<C.max){J[""].push(P)}}A.each(J,function(Q,R){C.cacheLength++;G(Q,R)})}setTimeout(E,25);function B(){F={};D=0}return{flush:B,add:G,populate:E,load:function(L){if(!C.cacheLength||!D){return null}if(!C.url&&C.matchContains){var K=[];for(var I in F){if(I.length>0){var M=F[I];A.each(M,function(O,N){if(H(N.value,L)){K.push(N)}})}}return K}else{if(F[L]){return F[L]}else{if(C.matchSubset){for(var J=L.length-1;J>=C.minChars;J--){var M=F[L.substr(0,J)];if(M){var K=[];A.each(M,function(O,N){if(H(N.value,L)){K[K.length]=N}});return K}}}}}return null}}};A.Autocompleter.Select=function(E,J,L,P){var I={ACTIVE:"ui-autocomplete-over"};var K,F=-1,R,M="",S=true,C,O;function N(){if(!S){return }C=A("<div/>").hide().addClass(E.resultsClass).css("position","absolute").appendTo(document.body);O=A("<ul/>").appendTo(C).mouseover(function(T){if(Q(T).nodeName&&Q(T).nodeName.toUpperCase()=="LI"){F=A("li",O).removeClass(I.ACTIVE).index(Q(T));A(Q(T)).addClass(I.ACTIVE)}}).click(function(T){A(Q(T)).addClass(I.ACTIVE);L();J.focus();return false}).mousedown(function(){P.mouseDownOnSelect=true}).mouseup(function(){P.mouseDownOnSelect=false});if(E.width>0){C.css("width",E.width)}S=false}function Q(U){var T=U.target;while(T&&T.tagName!="LI"){T=T.parentNode}if(!T){return[]}return T}function H(T){K.slice(F,F+1).removeClass(I.ACTIVE);G(T);var V=K.slice(F,F+1).addClass(I.ACTIVE);if(E.scroll){var U=0;K.slice(0,F).each(function(){U+=this.offsetHeight});if((U+V[0].offsetHeight-O.scrollTop())>O[0].clientHeight){O.scrollTop(U+V[0].offsetHeight-O.innerHeight())}else{if(U<O.scrollTop()){O.scrollTop(U)}}}}function G(T){F+=T;if(F<0){F=K.size()-1}else{if(F>=K.size()){F=0}}}function B(T){return E.max&&E.max<T?E.max:T}function D(){O.empty();var U=B(R.length);for(var V=0;V<U;V++){if(!R[V]){continue}var W=E.formatItem(R[V].data,V+1,U,R[V].value,M);if(W===false){continue}var T=A("<li/>").html(E.highlight(W,M)).addClass(V%2==0?"ui-autocomplete-even":"ui-autocomplete-odd").appendTo(O)[0];A.data(T,"ui-autocomplete-data",R[V])}K=O.find("li");if(E.selectFirst){K.slice(0,1).addClass(I.ACTIVE);F=0}if(A.fn.bgiframe){O.bgiframe()}}return{display:function(U,T){N();R=U;M=T;D()},next:function(){H(1)},prev:function(){H(-1)},pageUp:function(){if(F!=0&&F-8<0){H(-F)}else{H(-8)}},pageDown:function(){if(F!=K.size()-1&&F+8>K.size()){H(K.size()-1-F)}else{H(8)}},hide:function(){C&&C.hide();K&&K.removeClass(I.ACTIVE);F=-1;A(J).triggerHandler("autocompletehide",[{},{options:E}],E["hide"])},visible:function(){return C&&C.is(":visible")},current:function(){return this.visible()&&(K.filter("."+I.ACTIVE)[0]||E.selectFirst&&K[0])},show:function(){var V=A(J).offset();C.css({width:typeof E.width=="string"||E.width>0?E.width:A(J).width(),top:V.top+J.offsetHeight,left:V.left}).show();if(E.scroll){O.scrollTop(0);O.css({maxHeight:E.scrollHeight,overflow:"auto"});if(A.browser.msie&&typeof document.body.style.maxHeight==="undefined"){var T=0;K.each(function(){T+=this.offsetHeight});var U=T>E.scrollHeight;O.css("height",U?E.scrollHeight:T);if(!U){K.width(O.width()-parseInt(K.css("padding-left"))-parseInt(K.css("padding-right")))}}}A(J).triggerHandler("autocompleteshow",[{},{options:E}],E["show"])},selected:function(){var T=K&&K.filter("."+I.ACTIVE).removeClass(I.ACTIVE);return T&&T.length&&A.data(T[0],"ui-autocomplete-data")},emptyList:function(){O&&O.empty()},unbind:function(){C&&C.remove()}}};A.Autocompleter.Selection=function(D,E,C){if(D.createTextRange){var B=D.createTextRange();B.collapse(true);B.moveStart("character",E);B.moveEnd("character",C);B.select()}else{if(D.setSelectionRange){D.setSelectionRange(E,C)}else{if(D.selectionStart){D.selectionStart=E;D.selectionEnd=C}}}D.focus()}})(jQuery);(function(A){A.widget("ui.colorpicker",{_init:function(){this.charMin=65;var D=this.options,B=this,C='<div class="ui-colorpicker clearfix"><div class="ui-colorpicker-color"><div><div></div></div></div><div class="ui-colorpicker-hue"><div></div></div><div class="ui-colorpicker-new-color"></div><div class="ui-colorpicker-current-color"></div><div class="ui-colorpicker-hex"><label for="ui-colorpicker-hex" title="hex"></label><input type="text" maxlength="6" size="6" /></div><div class="ui-colorpicker-rgb-r ui-colorpicker-field"><label for="ui-colorpicker-rgb-r"></label><input type="text" maxlength="3" size="2" /><span></span></div><div class="ui-colorpicker-rgb-g ui-colorpicker-field"><label for="ui-colorpicker-rgb-g"></label><input type="text" maxlength="3" size="2" /><span></span></div><div class="ui-colorpicker-rgb-b ui-colorpicker-field"><label for="ui-colorpicker-rgb-b"</label><input type="text" maxlength="3" size="2" /><span></span></div><div class="ui-colorpicker-hsb-h ui-colorpicker-field"><label for="ui-colorpicker-hsb-h"></label><input type="text" maxlength="3" size="2" /><span></span></div><div class="ui-colorpicker-hsb-s ui-colorpicker-field"><label for="ui-colorpicker-hsb-s"></label><input type="text" maxlength="3" size="2" /><span></span></div><div class="ui-colorpicker-hsb-b ui-colorpicker-field"><label for="ui-colorpicker-hsb-b"></label><input type="text" maxlength="3" size="2" /><span></span></div><button class="ui-colorpicker-submit ui-default-state" name="submit" type="button">Done</button></div>';if(typeof D.color=="string"){this.color=this._HexToHSB(D.color)}else{if(D.color.r!=undefined&&D.color.g!=undefined&&D.color.b!=undefined){this.color=this._RGBToHSB(D.color)}else{if(D.color.h!=undefined&&D.color.s!=undefined&&D.color.b!=undefined){this.color=this._fixHSB(D.color)}else{return this}}}this.origColor=this.color;this.picker=A(C);if(D.flat){this.picker.appendTo(this.element).show()}else{this.picker.appendTo(document.body)}this.fields=this.picker.find("input").bind("keydown",function(E){return B._keyDown.call(B,E)}).bind("change",function(E){return B._change.call(B,E)}).bind("blur",function(E){return B._blur.call(B,E)}).bind("focus",function(E){return B._focus.call(B,E)});this.picker.find("span").bind("mousedown",function(E){return B._downIncrement.call(B,E)});this.selector=this.picker.find("div.ui-colorpicker-color").bind("mousedown",function(E){return B._downSelector.call(B,E)});this.selectorIndic=this.selector.find("div div");this.hue=this.picker.find("div.ui-colorpicker-hue div");this.picker.find("div.ui-colorpicker-hue").bind("mousedown",function(E){return B._downHue.call(B,E)});this.newColor=this.picker.find("div.ui-colorpicker-new-color");this.currentColor=this.picker.find("div.ui-colorpicker-current-color");this.picker.find(".ui-colorpicker-submit").bind("mouseenter",function(E){return B._enterSubmit.call(B,E)}).bind("mouseleave",function(E){return B._leaveSubmit.call(B,E)}).bind("click",function(E){return B._clickSubmit.call(B,E)});this._fillRGBFields(this.color);this._fillHSBFields(this.color);this._fillHexFields(this.color);this._setHue(this.color);this._setSelector(this.color);this._setCurrentColor(this.color);this._setNewColor(this.color);if(D.flat){this.picker.css({position:"relative",display:"block"})}else{A(this.element).bind(D.eventName+".colorpicker",function(E){return B._show.call(B,E)})}},destroy:function(){this.picker.remove();this.element.removeData("colorpicker").unbind(".colorpicker")},_fillRGBFields:function(B){var C=this._HSBToRGB(B);this.fields.eq(1).val(C.r).end().eq(2).val(C.g).end().eq(3).val(C.b).end()},_fillHSBFields:function(B){this.fields.eq(4).val(B.h).end().eq(5).val(B.s).end().eq(6).val(B.b).end()},_fillHexFields:function(B){this.fields.eq(0).val(this._HSBToHex(B)).end()},_setSelector:function(B){this.selector.css("backgroundColor","#"+this._HSBToHex({h:B.h,s:100,b:100}));this.selectorIndic.css({left:parseInt(150*B.s/100,10),top:parseInt(150*(100-B.b)/100,10)})},_setHue:function(B){this.hue.css("top",parseInt(150-150*B.h/360,10))},_setCurrentColor:function(B){this.currentColor.css("backgroundColor","#"+this._HSBToHex(B))},_setNewColor:function(B){this.newColor.css("backgroundColor","#"+this._HSBToHex(B))},_keyDown:function(B){var C=B.charCode||B.keyCode||-1;if((C>=this.charMin&&C<=90)||C==32){return false}},_change:function(D,C){var B;C=C||D.target;if(C.parentNode.className.indexOf("-hex")>0){this.color=B=this._HexToHSB(this.value);this._fillRGBFields(B.color);this._fillHSBFields(B)}else{if(C.parentNode.className.indexOf("-hsb")>0){this.color=B=this._fixHSB({h:parseInt(this.fields.eq(4).val(),10),s:parseInt(this.fields.eq(5).val(),10),b:parseInt(this.fields.eq(6).val(),10)});this._fillRGBFields(B);this._fillHexFields(B)}else{this.color=B=this._RGBToHSB(this._fixRGB({r:parseInt(this.fields.eq(1).val(),10),g:parseInt(this.fields.eq(2).val(),10),b:parseInt(this.fields.eq(3).val(),10)}));this._fillHexFields(B);this._fillHSBFields(B)}}this._setSelector(B);this._setHue(B);this._setNewColor(B);this._trigger("change",D,{options:this.options,hsb:B,hex:this._HSBToHex(B),rgb:this._HSBToRGB(B)})},_blur:function(C){var B=this.color;this._fillRGBFields(B);this._fillHSBFields(B);this._fillHexFields(B);this._setHue(B);this._setSelector(B);this._setNewColor(B);this.fields.parent().removeClass("ui-colorpicker-focus")},_focus:function(B){this.charMin=B.target.parentNode.className.indexOf("-hex")>0?70:65;this.fields.parent().removeClass("ui-colorpicker-focus");A(B.target.parentNode).addClass("ui-colorpicker-focus")},_downIncrement:function(D){var C=A(D.target).parent().find("input").focus(),B=this;this.currentIncrement={el:A(D.target).parent().addClass("ui-colorpicker-slider"),max:D.target.parentNode.className.indexOf("-hsb-h")>0?360:(D.target.parentNode.className.indexOf("-hsb")>0?100:255),y:D.pageY,field:C,val:parseInt(C.val(),10)};A(document).bind("mouseup.cpSlider",function(E){return B._upIncrement.call(B,E)});A(document).bind("mousemove.cpSlider",function(E){return B._moveIncrement.call(B,E)});return false},_moveIncrement:function(B){this.currentIncrement.field.val(Math.max(0,Math.min(this.currentIncrement.max,parseInt(this.currentIncrement.val+B.pageY-this.currentIncrement.y,10))));this._change.apply(this,[B,this.currentIncrement.field.get(0)]);return false},_upIncrement:function(B){this.currentIncrement.el.removeClass("ui-colorpicker-slider").find("input").focus();this._change.apply(this,[B,this.currentIncrement.field.get(0)]);A(document).unbind("mouseup.cpSlider");A(document).unbind("mousemove.cpSlider");return false},_downHue:function(C){this.currentHue={y:this.picker.find("div.ui-colorpicker-hue").offset().top};this._change.apply(this,[C,this.fields.eq(4).val(parseInt(360*(150-Math.max(0,Math.min(150,(C.pageY-this.currentHue.y))))/150,10)).get(0)]);var B=this;A(document).bind("mouseup.cpSlider",function(D){return B._upHue.call(B,D)});A(document).bind("mousemove.cpSlider",function(D){return B._moveHue.call(B,D)});return false},_moveHue:function(B){this._change.apply(this,[B,this.fields.eq(4).val(parseInt(360*(150-Math.max(0,Math.min(150,(B.pageY-this.currentHue.y))))/150,10)).get(0)]);return false},_upHue:function(B){A(document).unbind("mouseup.cpSlider");A(document).unbind("mousemove.cpSlider");return false},_downSelector:function(C){var B=this;this.currentSelector={pos:this.picker.find("div.ui-colorpicker-color").offset()};this._change.apply(this,[C,this.fields.eq(6).val(parseInt(100*(150-Math.max(0,Math.min(150,(C.pageY-this.currentSelector.pos.top))))/150,10)).end().eq(5).val(parseInt(100*(Math.max(0,Math.min(150,(C.pageX-this.currentSelector.pos.left))))/150,10)).get(0)]);A(document).bind("mouseup.cpSlider",function(D){return B._upSelector.call(B,D)});A(document).bind("mousemove.cpSlider",function(D){return B._moveSelector.call(B,D)});return false},_moveSelector:function(B){this._change.apply(this,[B,this.fields.eq(6).val(parseInt(100*(150-Math.max(0,Math.min(150,(B.pageY-this.currentSelector.pos.top))))/150,10)).end().eq(5).val(parseInt(100*(Math.max(0,Math.min(150,(B.pageX-this.currentSelector.pos.left))))/150,10)).get(0)]);return false},_upSelector:function(B){A(document).unbind("mouseup.cpSlider");A(document).unbind("mousemove.cpSlider");return false},_enterSubmit:function(B){this.picker.find(".ui-colorpicker-submit").addClass("ui-colorpicker-focus")},_leaveSubmit:function(B){this.picker.find(".ui-colorpicker-submit").removeClass("ui-colorpicker-focus")},_clickSubmit:function(C){var B=this.color;this.origColor=B;this._setCurrentColor(B);this._trigger("submit",C,{options:this.options,hsb:B,hex:this._HSBToHex(B),rgb:this._HSBToRGB(B)});return false},_show:function(F){this._trigger("beforeShow",F,{options:this.options,hsb:this.color,hex:this._HSBToHex(this.color),rgb:this._HSBToRGB(this.color)});var G=this.element.offset();var E=this._getScroll();var D=G.top+this.element[0].offsetHeight;var C=G.left;if(D+176>E.t+Math.min(E.h,E.ih)){D-=this.element[0].offsetHeight+176}if(C+356>E.l+Math.min(E.w,E.iw)){C-=356}this.picker.css({left:C+"px",top:D+"px"});if(this._trigger("show",F,{options:this.options,hsb:this.color,hex:this._HSBToHex(this.color),rgb:this._HSBToRGB(this.color)})!=false){this.picker.show()}var B=this;A(document).bind("mousedown.colorpicker",function(H){return B._hide.call(B,H)});return false},_hide:function(B){if(!this._isChildOf(this.picker[0],B.target,this.picker[0])){if(this._trigger("hide",B,{options:this.options,hsb:this.color,hex:this._HSBToHex(this.color),rgb:this._HSBToRGB(this.color)})!=false){this.picker.hide()}A(document).unbind("mousedown.colorpicker")}},_isChildOf:function(D,C,B){if(D==C){return true}if(D.contains&&!A.browser.safari){return D.contains(C)}if(D.compareDocumentPosition){return !!(D.compareDocumentPosition(C)&16)}var E=C.parentNode;while(E&&E!=B){if(E==D){return true}E=E.parentNode}return false},_getScroll:function(){var E,C,B,F,D,G;if(document.documentElement){E=document.documentElement.scrollTop;C=document.documentElement.scrollLeft;B=document.documentElement.scrollWidth;F=document.documentElement.scrollHeight}else{E=document.body.scrollTop;C=document.body.scrollLeft;B=document.body.scrollWidth;F=document.body.scrollHeight}D=self.innerWidth||document.documentElement.clientWidth||document.body.clientWidth||0;G=self.innerHeight||document.documentElement.clientHeight||document.body.clientHeight||0;return{t:E,l:C,w:B,h:F,iw:D,ih:G}},_fixHSB:function(B){return{h:Math.min(360,Math.max(0,B.h)),s:Math.min(100,Math.max(0,B.s)),b:Math.min(100,Math.max(0,B.b))}},_fixRGB:function(B){return{r:Math.min(255,Math.max(0,B.r)),g:Math.min(255,Math.max(0,B.g)),b:Math.min(255,Math.max(0,B.b))}},_HexToRGB:function(B){var B=parseInt(((B.indexOf("#")>-1)?B.substring(1):B),16);return{r:B>>16,g:(B&65280)>>8,b:(B&255)}},_HexToHSB:function(B){return this._RGBToHSB(this._HexToRGB(B))},_RGBToHSB:function(C){var B={};B.b=Math.max(Math.max(C.r,C.g),C.b);B.s=(B.b<=0)?0:Math.round(100*(B.b-Math.min(Math.min(C.r,C.g),C.b))/B.b);B.b=Math.round((B.b/255)*100);if((C.r==C.g)&&(C.g==C.b)){B.h=0}else{if(C.r>=C.g&&C.g>=C.b){B.h=60*(C.g-C.b)/(C.r-C.b)}else{if(C.g>=C.r&&C.r>=C.b){B.h=60+60*(C.g-C.r)/(C.g-C.b)}else{if(C.g>=C.b&&C.b>=C.r){B.h=120+60*(C.b-C.r)/(C.g-C.r)}else{if(C.b>=C.g&&C.g>=C.r){B.h=180+60*(C.b-C.g)/(C.b-C.r)}else{if(C.b>=C.r&&C.r>=C.g){B.h=240+60*(C.r-C.g)/(C.b-C.g)}else{if(C.r>=C.b&&C.b>=C.g){B.h=300+60*(C.r-C.b)/(C.r-C.g)}else{B.h=0}}}}}}}B.h=Math.round(B.h);return B},_HSBToRGB:function(B){var D={};var H=Math.round(B.h);var G=Math.round(B.s*255/100);var C=Math.round(B.b*255/100);if(G==0){D.r=D.g=D.b=C}else{var I=C;var F=(255-G)*C/255;var E=(I-F)*(H%60)/60;if(H==360){H=0}if(H<60){D.r=I;D.b=F;D.g=F+E}else{if(H<120){D.g=I;D.b=F;D.r=I-E}else{if(H<180){D.g=I;D.r=F;D.b=F+E}else{if(H<240){D.b=I;D.r=F;D.g=I-E}else{if(H<300){D.b=I;D.g=F;D.r=F+E}else{if(H<360){D.r=I;D.g=F;D.b=I-E}else{D.r=0;D.g=0;D.b=0}}}}}}}return{r:Math.round(D.r),g:Math.round(D.g),b:Math.round(D.b)}},_RGBToHex:function(B){var C=[B.r.toString(16),B.g.toString(16),B.b.toString(16)];A.each(C,function(D,E){if(E.length==1){C[D]="0"+E}});return C.join("")},_HSBToHex:function(B){return this._RGBToHex(this._HSBToRGB(B))},setColor:function(B){if(typeof B=="string"){B=this._HexToHSB(B)}else{if(B.r!=undefined&&B.g!=undefined&&B.b!=undefined){B=this._RGBToHSB(B)}else{if(B.h!=undefined&&B.s!=undefined&&B.b!=undefined){B=this._fixHSB(B)}else{return this}}}this.color=B;this.origColor=B;this._fillRGBFields(B);this._fillHSBFields(B);this._fillHexFields(B);this._setHue(B);this._setSelector(B);this._setCurrentColor(B);this._setNewColor(B)}});A.extend(A.ui.colorpicker,{defaults:{eventName:"click",color:"ff0000",flat:false}})})(jQuery);(function($){var PROP_NAME="datepicker";function Datepicker(){this.debug=false;this._curInst=null;this._disabledInputs=[];this._datepickerShowing=false;this._inDialog=false;this._mainDivId="ui-datepicker-div";this._inlineClass="ui-datepicker-inline";this._appendClass="ui-datepicker-append";this._triggerClass="ui-datepicker-trigger";this._dialogClass="ui-datepicker-dialog";this._promptClass="ui-datepicker-prompt";this._disableClass="ui-datepicker-disabled";this._unselectableClass="ui-datepicker-unselectable";this._currentClass="ui-datepicker-current-day";this.regional=[];this.regional[""]={clearText:"Clear",clearStatus:"Erase the current date",closeText:"Close",closeStatus:"Close without change",prevText:"&#x3c;Prev",prevStatus:"Show the previous month",prevBigText:"&#x3c;&#x3c;",prevBigStatus:"Show the previous year",nextText:"Next&#x3e;",nextStatus:"Show the next month",nextBigText:"&#x3e;&#x3e;",nextBigStatus:"Show the next year",currentText:"Today",currentStatus:"Show the current month",monthNames:["January","February","March","April","May","June","July","August","September","October","November","December"],monthNamesShort:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],monthStatus:"Show a different month",yearStatus:"Show a different year",weekHeader:"Wk",weekStatus:"Week of the year",dayNames:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],dayNamesShort:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],dayNamesMin:["Su","Mo","Tu","We","Th","Fr","Sa"],dayStatus:"Set DD as first week day",dateStatus:"Select DD, M d",dateFormat:"mm/dd/yy",firstDay:0,initStatus:"Select a date",isRTL:false};this._defaults={showOn:"focus",showAnim:"show",showOptions:{},defaultDate:null,appendText:"",buttonText:"...",buttonImage:"",buttonImageOnly:false,closeAtTop:true,mandatory:false,hideIfNoPrevNext:false,navigationAsDateFormat:false,showBigPrevNext:false,gotoCurrent:false,changeMonth:true,changeYear:true,showMonthAfterYear:false,yearRange:"-10:+10",changeFirstDay:true,highlightWeek:false,showOtherMonths:false,showWeeks:false,calculateWeek:this.iso8601Week,shortYearCutoff:"+10",showStatus:false,statusForDate:this.dateStatus,minDate:null,maxDate:null,duration:"normal",beforeShowDay:null,beforeShow:null,onSelect:null,onChangeMonthYear:null,onClose:null,numberOfMonths:1,showCurrentAtPos:0,stepMonths:1,stepBigMonths:12,rangeSelect:false,rangeSeparator:" - ",altField:"",altFormat:""};$.extend(this._defaults,this.regional[""]);this.dpDiv=$('<div id="'+this._mainDivId+'" style="display: none;"></div>')}$.extend(Datepicker.prototype,{markerClassName:"hasDatepicker",log:function(){if(this.debug){console.log.apply("",arguments)}},setDefaults:function(settings){extendRemove(this._defaults,settings||{});return this},_attachDatepicker:function(target,settings){var inlineSettings=null;for(attrName in this._defaults){var attrValue=target.getAttribute("date:"+attrName);if(attrValue){inlineSettings=inlineSettings||{};try{inlineSettings[attrName]=eval(attrValue)}catch(err){inlineSettings[attrName]=attrValue}}}var nodeName=target.nodeName.toLowerCase();var inline=(nodeName=="div"||nodeName=="span");if(!target.id){target.id="dp"+(++this.uuid)}var inst=this._newInst($(target),inline);inst.settings=$.extend({},settings||{},inlineSettings||{});if(nodeName=="input"){this._connectDatepicker(target,inst)}else{if(inline){this._inlineDatepicker(target,inst)}}},_newInst:function(target,inline){var id=target[0].id.replace(/([:\[\]\.])/g,"\\\\$1");return{id:id,input:target,selectedDay:0,selectedMonth:0,selectedYear:0,drawMonth:0,drawYear:0,inline:inline,dpDiv:(!inline?this.dpDiv:$('<div class="'+this._inlineClass+'"></div>'))}},_connectDatepicker:function(target,inst){var input=$(target);if(input.hasClass(this.markerClassName)){return }var appendText=this._get(inst,"appendText");var isRTL=this._get(inst,"isRTL");if(appendText){input[isRTL?"before":"after"]('<span class="'+this._appendClass+'">'+appendText+"</span>")}var showOn=this._get(inst,"showOn");if(showOn=="focus"||showOn=="both"){input.focus(this._showDatepicker)}if(showOn=="button"||showOn=="both"){var buttonText=this._get(inst,"buttonText");var buttonImage=this._get(inst,"buttonImage");var trigger=$(this._get(inst,"buttonImageOnly")?$("<img/>").addClass(this._triggerClass).attr({src:buttonImage,alt:buttonText,title:buttonText}):$('<button type="button"></button>').addClass(this._triggerClass).html(buttonImage==""?buttonText:$("<img/>").attr({src:buttonImage,alt:buttonText,title:buttonText})));input[isRTL?"before":"after"](trigger);trigger.click(function(){if($.datepicker._datepickerShowing&&$.datepicker._lastInput==target){$.datepicker._hideDatepicker()}else{$.datepicker._showDatepicker(target)}return false})}input.addClass(this.markerClassName).keydown(this._doKeyDown).keypress(this._doKeyPress).bind("setData.datepicker",function(event,key,value){inst.settings[key]=value}).bind("getData.datepicker",function(event,key){return this._get(inst,key)});$.data(target,PROP_NAME,inst)},_inlineDatepicker:function(target,inst){var divSpan=$(target);if(divSpan.hasClass(this.markerClassName)){return }divSpan.addClass(this.markerClassName).append(inst.dpDiv).bind("setData.datepicker",function(event,key,value){inst.settings[key]=value}).bind("getData.datepicker",function(event,key){return this._get(inst,key)});$.data(target,PROP_NAME,inst);this._setDate(inst,this._getDefaultDate(inst));this._updateDatepicker(inst)},_inlineShow:function(inst){var numMonths=this._getNumberOfMonths(inst);inst.dpDiv.width(numMonths[1]*$(".ui-datepicker",inst.dpDiv[0]).width())},_dialogDatepicker:function(input,dateText,onSelect,settings,pos){var inst=this._dialogInst;if(!inst){var id="dp"+(++this.uuid);this._dialogInput=$('<input type="text" id="'+id+'" size="1" style="position: absolute; top: -100px;"/>');this._dialogInput.keydown(this._doKeyDown);$("body").append(this._dialogInput);inst=this._dialogInst=this._newInst(this._dialogInput,false);inst.settings={};$.data(this._dialogInput[0],PROP_NAME,inst)}extendRemove(inst.settings,settings||{});this._dialogInput.val(dateText);this._pos=(pos?(pos.length?pos:[pos.pageX,pos.pageY]):null);if(!this._pos){var browserWidth=window.innerWidth||document.documentElement.clientWidth||document.body.clientWidth;var browserHeight=window.innerHeight||document.documentElement.clientHeight||document.body.clientHeight;var scrollX=document.documentElement.scrollLeft||document.body.scrollLeft;var scrollY=document.documentElement.scrollTop||document.body.scrollTop;this._pos=[(browserWidth/2)-100+scrollX,(browserHeight/2)-150+scrollY]}this._dialogInput.css("left",this._pos[0]+"px").css("top",this._pos[1]+"px");inst.settings.onSelect=onSelect;this._inDialog=true;this.dpDiv.addClass(this._dialogClass);this._showDatepicker(this._dialogInput[0]);if($.blockUI){$.blockUI(this.dpDiv)}$.data(this._dialogInput[0],PROP_NAME,inst);return this},_destroyDatepicker:function(target){var $target=$(target);if(!$target.hasClass(this.markerClassName)){return }var nodeName=target.nodeName.toLowerCase();$.removeData(target,PROP_NAME);if(nodeName=="input"){$target.siblings("."+this._appendClass).remove().end().siblings("."+this._triggerClass).remove().end().removeClass(this.markerClassName).unbind("focus",this._showDatepicker).unbind("keydown",this._doKeyDown).unbind("keypress",this._doKeyPress)}else{if(nodeName=="div"||nodeName=="span"){$target.removeClass(this.markerClassName).empty()}}},_enableDatepicker:function(target){var $target=$(target);if(!$target.hasClass(this.markerClassName)){return }var nodeName=target.nodeName.toLowerCase();if(nodeName=="input"){target.disabled=false;$target.siblings("button."+this._triggerClass).each(function(){this.disabled=false}).end().siblings("img."+this._triggerClass).css({opacity:"1.0",cursor:""})}else{if(nodeName=="div"||nodeName=="span"){$target.children("."+this._disableClass).remove()}}this._disabledInputs=$.map(this._disabledInputs,function(value){return(value==target?null:value)})},_disableDatepicker:function(target){var $target=$(target);if(!$target.hasClass(this.markerClassName)){return }var nodeName=target.nodeName.toLowerCase();if(nodeName=="input"){target.disabled=true;$target.siblings("button."+this._triggerClass).each(function(){this.disabled=true}).end().siblings("img."+this._triggerClass).css({opacity:"0.5",cursor:"default"})}else{if(nodeName=="div"||nodeName=="span"){var inline=$target.children("."+this._inlineClass);var offset=inline.offset();var relOffset={left:0,top:0};inline.parents().each(function(){if($(this).css("position")=="relative"){relOffset=$(this).offset();return false}});$target.prepend('<div class="'+this._disableClass+'" style="'+($.browser.msie?"background-color: transparent; ":"")+"width: "+inline.width()+"px; height: "+inline.height()+"px; left: "+(offset.left-relOffset.left)+"px; top: "+(offset.top-relOffset.top)+'px;"></div>')}}this._disabledInputs=$.map(this._disabledInputs,function(value){return(value==target?null:value)});this._disabledInputs[this._disabledInputs.length]=target},_isDisabledDatepicker:function(target){if(!target){return false}for(var i=0;i<this._disabledInputs.length;i++){if(this._disabledInputs[i]==target){return true}}return false},_getInst:function(target){try{return $.data(target,PROP_NAME)}catch(err){throw"Missing instance data for this datepicker"}},_changeDatepicker:function(target,name,value){var settings=name||{};if(typeof name=="string"){settings={};settings[name]=value}var inst=this._getInst(target);if(inst){if(this._curInst==inst){this._hideDatepicker(null)}extendRemove(inst.settings,settings);var date=new Date();extendRemove(inst,{rangeStart:null,endDay:null,endMonth:null,endYear:null,selectedDay:date.getDate(),selectedMonth:date.getMonth(),selectedYear:date.getFullYear(),currentDay:date.getDate(),currentMonth:date.getMonth(),currentYear:date.getFullYear(),drawMonth:date.getMonth(),drawYear:date.getFullYear()});this._updateDatepicker(inst)}},_refreshDatepicker:function(target){var inst=this._getInst(target);if(inst){this._updateDatepicker(inst)}},_setDateDatepicker:function(target,date,endDate){var inst=this._getInst(target);if(inst){this._setDate(inst,date,endDate);this._updateDatepicker(inst);this._updateAlternate(inst)}},_getDateDatepicker:function(target){var inst=this._getInst(target);if(inst&&!inst.inline){this._setDateFromField(inst)}return(inst?this._getDate(inst):null)},_doKeyDown:function(e){var inst=$.datepicker._getInst(e.target);var handled=true;if($.datepicker._datepickerShowing){switch(e.keyCode){case 9:$.datepicker._hideDatepicker(null,"");break;case 13:$.datepicker._selectDay(e.target,inst.selectedMonth,inst.selectedYear,$("td.ui-datepicker-days-cell-over",inst.dpDiv)[0]);return false;break;case 27:$.datepicker._hideDatepicker(null,$.datepicker._get(inst,"duration"));break;case 33:$.datepicker._adjustDate(e.target,(e.ctrlKey?-$.datepicker._get(inst,"stepBigMonths"):-$.datepicker._get(inst,"stepMonths")),"M");break;case 34:$.datepicker._adjustDate(e.target,(e.ctrlKey?+$.datepicker._get(inst,"stepBigMonths"):+$.datepicker._get(inst,"stepMonths")),"M");break;case 35:if(e.ctrlKey){$.datepicker._clearDate(e.target)}handled=e.ctrlKey;break;case 36:if(e.ctrlKey){$.datepicker._gotoToday(e.target)}handled=e.ctrlKey;break;case 37:if(e.ctrlKey){$.datepicker._adjustDate(e.target,-1,"D")}handled=e.ctrlKey;break;case 38:if(e.ctrlKey){$.datepicker._adjustDate(e.target,-7,"D")}handled=e.ctrlKey;break;case 39:if(e.ctrlKey){$.datepicker._adjustDate(e.target,+1,"D")}handled=e.ctrlKey;break;case 40:if(e.ctrlKey){$.datepicker._adjustDate(e.target,+7,"D")}handled=e.ctrlKey;break;default:handled=false}}else{if(e.keyCode==36&&e.ctrlKey){$.datepicker._showDatepicker(this)}else{handled=false}}if(handled){e.preventDefault();e.stopPropagation()}},_doKeyPress:function(e){var inst=$.datepicker._getInst(e.target);var chars=$.datepicker._possibleChars($.datepicker._get(inst,"dateFormat"));var chr=String.fromCharCode(e.charCode==undefined?e.keyCode:e.charCode);return e.ctrlKey||(chr<" "||!chars||chars.indexOf(chr)>-1)},_showDatepicker:function(input){input=input.target||input;if(input.nodeName.toLowerCase()!="input"){input=$("input",input.parentNode)[0]}if($.datepicker._isDisabledDatepicker(input)||$.datepicker._lastInput==input){return }var inst=$.datepicker._getInst(input);var beforeShow=$.datepicker._get(inst,"beforeShow");extendRemove(inst.settings,(beforeShow?beforeShow.apply(input,[input,inst]):{}));$.datepicker._hideDatepicker(null,"");$.datepicker._lastInput=input;$.datepicker._setDateFromField(inst);if($.datepicker._inDialog){input.value=""}if(!$.datepicker._pos){$.datepicker._pos=$.datepicker._findPos(input);$.datepicker._pos[1]+=input.offsetHeight}var isFixed=false;$(input).parents().each(function(){isFixed|=$(this).css("position")=="fixed";return !isFixed});if(isFixed&&$.browser.opera){$.datepicker._pos[0]-=document.documentElement.scrollLeft;$.datepicker._pos[1]-=document.documentElement.scrollTop}var offset={left:$.datepicker._pos[0],top:$.datepicker._pos[1]};$.datepicker._pos=null;inst.rangeStart=null;inst.dpDiv.css({position:"absolute",display:"block",top:"-1000px"});$.datepicker._updateDatepicker(inst);inst.dpDiv.width($.datepicker._getNumberOfMonths(inst)[1]*$(".ui-datepicker",inst.dpDiv[0])[0].offsetWidth);offset=$.datepicker._checkOffset(inst,offset,isFixed);inst.dpDiv.css({position:($.datepicker._inDialog&&$.blockUI?"static":(isFixed?"fixed":"absolute")),display:"none",left:offset.left+"px",top:offset.top+"px"});if(!inst.inline){var showAnim=$.datepicker._get(inst,"showAnim")||"show";var duration=$.datepicker._get(inst,"duration");var postProcess=function(){$.datepicker._datepickerShowing=true;if($.browser.msie&&parseInt($.browser.version,10)<7){$("iframe.ui-datepicker-cover").css({width:inst.dpDiv.width()+4,height:inst.dpDiv.height()+4})}};if($.effects&&$.effects[showAnim]){inst.dpDiv.show(showAnim,$.datepicker._get(inst,"showOptions"),duration,postProcess)}else{inst.dpDiv[showAnim](duration,postProcess)}if(duration==""){postProcess()}if(inst.input[0].type!="hidden"){inst.input[0].focus()}$.datepicker._curInst=inst}},_updateDatepicker:function(inst){var dims={width:inst.dpDiv.width()+4,height:inst.dpDiv.height()+4};inst.dpDiv.empty().append(this._generateHTML(inst)).find("iframe.ui-datepicker-cover").css({width:dims.width,height:dims.height});var numMonths=this._getNumberOfMonths(inst);inst.dpDiv[(numMonths[0]!=1||numMonths[1]!=1?"add":"remove")+"Class"]("ui-datepicker-multi");inst.dpDiv[(this._get(inst,"isRTL")?"add":"remove")+"Class"]("ui-datepicker-rtl");if(inst.input&&inst.input[0].type!="hidden"){$(inst.input[0]).focus()}},_checkOffset:function(inst,offset,isFixed){var pos=inst.input?this._findPos(inst.input[0]):null;var browserWidth=window.innerWidth||document.documentElement.clientWidth;var browserHeight=window.innerHeight||document.documentElement.clientHeight;var scrollX=document.documentElement.scrollLeft||document.body.scrollLeft;var scrollY=document.documentElement.scrollTop||document.body.scrollTop;if(this._get(inst,"isRTL")||(offset.left+inst.dpDiv.width()-scrollX)>browserWidth){offset.left=Math.max((isFixed?0:scrollX),pos[0]+(inst.input?inst.input.width():0)-(isFixed?scrollX:0)-inst.dpDiv.width()-(isFixed&&$.browser.opera?document.documentElement.scrollLeft:0))}else{offset.left-=(isFixed?scrollX:0)}if((offset.top+inst.dpDiv.height()-scrollY)>browserHeight){offset.top=Math.max((isFixed?0:scrollY),pos[1]-(isFixed?scrollY:0)-(this._inDialog?0:inst.dpDiv.height())-(isFixed&&$.browser.opera?document.documentElement.scrollTop:0))}else{offset.top-=(isFixed?scrollY:0)}return offset},_findPos:function(obj){while(obj&&(obj.type=="hidden"||obj.nodeType!=1)){obj=obj.nextSibling}var position=$(obj).offset();return[position.left,position.top]},_hideDatepicker:function(input,duration){var inst=this._curInst;if(!inst||(input&&inst!=$.data(input,PROP_NAME))){return }var rangeSelect=this._get(inst,"rangeSelect");if(rangeSelect&&inst.stayOpen){this._selectDate("#"+inst.id,this._formatDate(inst,inst.currentDay,inst.currentMonth,inst.currentYear))}inst.stayOpen=false;if(this._datepickerShowing){duration=(duration!=null?duration:this._get(inst,"duration"));var showAnim=this._get(inst,"showAnim");var postProcess=function(){$.datepicker._tidyDialog(inst)};if(duration!=""&&$.effects&&$.effects[showAnim]){inst.dpDiv.hide(showAnim,$.datepicker._get(inst,"showOptions"),duration,postProcess)}else{inst.dpDiv[(duration==""?"hide":(showAnim=="slideDown"?"slideUp":(showAnim=="fadeIn"?"fadeOut":"hide")))](duration,postProcess)}if(duration==""){this._tidyDialog(inst)}var onClose=this._get(inst,"onClose");if(onClose){onClose.apply((inst.input?inst.input[0]:null),[(inst.input?inst.input.val():""),inst])}this._datepickerShowing=false;this._lastInput=null;inst.settings.prompt=null;if(this._inDialog){this._dialogInput.css({position:"absolute",left:"0",top:"-100px"});if($.blockUI){$.unblockUI();$("body").append(this.dpDiv)}}this._inDialog=false}this._curInst=null},_tidyDialog:function(inst){inst.dpDiv.removeClass(this._dialogClass).unbind(".ui-datepicker");$("."+this._promptClass,inst.dpDiv).remove()},_checkExternalClick:function(event){if(!$.datepicker._curInst){return }var $target=$(event.target);if(($target.parents("#"+$.datepicker._mainDivId).length==0)&&!$target.hasClass($.datepicker.markerClassName)&&!$target.hasClass($.datepicker._triggerClass)&&$.datepicker._datepickerShowing&&!($.datepicker._inDialog&&$.blockUI)){$.datepicker._hideDatepicker(null,"")}},_adjustDate:function(id,offset,period){var target=$(id);var inst=this._getInst(target[0]);this._adjustInstDate(inst,offset,period);this._updateDatepicker(inst)},_gotoToday:function(id){var target=$(id);var inst=this._getInst(target[0]);if(this._get(inst,"gotoCurrent")&&inst.currentDay){inst.selectedDay=inst.currentDay;inst.drawMonth=inst.selectedMonth=inst.currentMonth;inst.drawYear=inst.selectedYear=inst.currentYear}else{var date=new Date();inst.selectedDay=date.getDate();inst.drawMonth=inst.selectedMonth=date.getMonth();inst.drawYear=inst.selectedYear=date.getFullYear()}this._notifyChange(inst);this._adjustDate(target)},_selectMonthYear:function(id,select,period){var target=$(id);var inst=this._getInst(target[0]);inst._selectingMonthYear=false;inst["selected"+(period=="M"?"Month":"Year")]=inst["draw"+(period=="M"?"Month":"Year")]=parseInt(select.options[select.selectedIndex].value,10);this._notifyChange(inst);this._adjustDate(target)},_clickMonthYear:function(id){var target=$(id);var inst=this._getInst(target[0]);if(inst.input&&inst._selectingMonthYear&&!$.browser.msie){inst.input[0].focus()}inst._selectingMonthYear=!inst._selectingMonthYear},_changeFirstDay:function(id,day){var target=$(id);var inst=this._getInst(target[0]);inst.settings.firstDay=day;this._updateDatepicker(inst)},_selectDay:function(id,month,year,td){if($(td).hasClass(this._unselectableClass)){return }var target=$(id);var inst=this._getInst(target[0]);var rangeSelect=this._get(inst,"rangeSelect");if(rangeSelect){inst.stayOpen=!inst.stayOpen;if(inst.stayOpen){$(".ui-datepicker td",inst.dpDiv).removeClass(this._currentClass);$(td).addClass(this._currentClass)}}inst.selectedDay=inst.currentDay=$("a",td).html();inst.selectedMonth=inst.currentMonth=month;inst.selectedYear=inst.currentYear=year;if(inst.stayOpen){inst.endDay=inst.endMonth=inst.endYear=null}else{if(rangeSelect){inst.endDay=inst.currentDay;inst.endMonth=inst.currentMonth;inst.endYear=inst.currentYear}}this._selectDate(id,this._formatDate(inst,inst.currentDay,inst.currentMonth,inst.currentYear));if(inst.stayOpen){inst.rangeStart=new Date(inst.currentYear,inst.currentMonth,inst.currentDay);this._updateDatepicker(inst)}else{if(rangeSelect){inst.selectedDay=inst.currentDay=inst.rangeStart.getDate();inst.selectedMonth=inst.currentMonth=inst.rangeStart.getMonth();inst.selectedYear=inst.currentYear=inst.rangeStart.getFullYear();inst.rangeStart=null;if(inst.inline){this._updateDatepicker(inst)}}}},_clearDate:function(id){var target=$(id);var inst=this._getInst(target[0]);if(this._get(inst,"mandatory")){return }inst.stayOpen=false;inst.endDay=inst.endMonth=inst.endYear=inst.rangeStart=null;this._selectDate(target,"")},_selectDate:function(id,dateStr){var target=$(id);var inst=this._getInst(target[0]);dateStr=(dateStr!=null?dateStr:this._formatDate(inst));if(this._get(inst,"rangeSelect")&&dateStr){dateStr=(inst.rangeStart?this._formatDate(inst,inst.rangeStart):dateStr)+this._get(inst,"rangeSeparator")+dateStr}if(inst.input){inst.input.val(dateStr)}this._updateAlternate(inst);var onSelect=this._get(inst,"onSelect");if(onSelect){onSelect.apply((inst.input?inst.input[0]:null),[dateStr,inst])}else{if(inst.input){inst.input.trigger("change")}}if(inst.inline){this._updateDatepicker(inst)}else{if(!inst.stayOpen){this._hideDatepicker(null,this._get(inst,"duration"));this._lastInput=inst.input[0];if(typeof (inst.input[0])!="object"){inst.input[0].focus()}this._lastInput=null}}},_updateAlternate:function(inst){var altField=this._get(inst,"altField");if(altField){var altFormat=this._get(inst,"altFormat");var date=this._getDate(inst);dateStr=(isArray(date)?(!date[0]&&!date[1]?"":this.formatDate(altFormat,date[0],this._getFormatConfig(inst))+this._get(inst,"rangeSeparator")+this.formatDate(altFormat,date[1]||date[0],this._getFormatConfig(inst))):this.formatDate(altFormat,date,this._getFormatConfig(inst)));$(altField).each(function(){$(this).val(dateStr)})}},noWeekends:function(date){var day=date.getDay();return[(day>0&&day<6),""]},iso8601Week:function(date){var checkDate=new Date(date.getFullYear(),date.getMonth(),date.getDate(),(date.getTimezoneOffset()/-60));var firstMon=new Date(checkDate.getFullYear(),1-1,4);var firstDay=firstMon.getDay()||7;firstMon.setDate(firstMon.getDate()+1-firstDay);if(firstDay<4&&checkDate<firstMon){checkDate.setDate(checkDate.getDate()-3);return $.datepicker.iso8601Week(checkDate)}else{if(checkDate>new Date(checkDate.getFullYear(),12-1,28)){firstDay=new Date(checkDate.getFullYear()+1,1-1,4).getDay()||7;if(firstDay>4&&(checkDate.getDay()||7)<firstDay-3){return 1}}}return Math.floor(((checkDate-firstMon)/86400000)/7)+1},dateStatus:function(date,inst){return $.datepicker.formatDate($.datepicker._get(inst,"dateStatus"),date,$.datepicker._getFormatConfig(inst))},parseDate:function(format,value,settings){if(format==null||value==null){throw"Invalid arguments"}value=(typeof value=="object"?value.toString():value+"");if(value==""){return null}var shortYearCutoff=(settings?settings.shortYearCutoff:null)||this._defaults.shortYearCutoff;var dayNamesShort=(settings?settings.dayNamesShort:null)||this._defaults.dayNamesShort;var dayNames=(settings?settings.dayNames:null)||this._defaults.dayNames;var monthNamesShort=(settings?settings.monthNamesShort:null)||this._defaults.monthNamesShort;var monthNames=(settings?settings.monthNames:null)||this._defaults.monthNames;var year=-1;var month=-1;var day=-1;var doy=-1;var literal=false;var lookAhead=function(match){var matches=(iFormat+1<format.length&&format.charAt(iFormat+1)==match);if(matches){iFormat++}return matches};var getNumber=function(match){lookAhead(match);var origSize=(match=="@"?14:(match=="y"?4:(match=="o"?3:2)));var size=origSize;var num=0;while(size>0&&iValue<value.length&&value.charAt(iValue)>="0"&&value.charAt(iValue)<="9"){num=num*10+parseInt(value.charAt(iValue++),10);size--}if(size==origSize){throw"Missing number at position "+iValue}return num};var getName=function(match,shortNames,longNames){var names=(lookAhead(match)?longNames:shortNames);var size=0;for(var j=0;j<names.length;j++){size=Math.max(size,names[j].length)}var name="";var iInit=iValue;while(size>0&&iValue<value.length){name+=value.charAt(iValue++);for(var i=0;i<names.length;i++){if(name==names[i]){return i+1}}size--}throw"Unknown name at position "+iInit};var checkLiteral=function(){if(value.charAt(iValue)!=format.charAt(iFormat)){throw"Unexpected literal at position "+iValue}iValue++};var iValue=0;for(var iFormat=0;iFormat<format.length;iFormat++){if(literal){if(format.charAt(iFormat)=="'"&&!lookAhead("'")){literal=false}else{checkLiteral()}}else{switch(format.charAt(iFormat)){case"d":day=getNumber("d");break;case"D":getName("D",dayNamesShort,dayNames);break;case"o":doy=getNumber("o");break;case"m":month=getNumber("m");break;case"M":month=getName("M",monthNamesShort,monthNames);break;case"y":year=getNumber("y");break;case"@":var date=new Date(getNumber("@"));year=date.getFullYear();month=date.getMonth()+1;day=date.getDate();break;case"'":if(lookAhead("'")){checkLiteral()}else{literal=true}break;default:checkLiteral()}}}if(year<100){year+=new Date().getFullYear()-new Date().getFullYear()%100+(year<=shortYearCutoff?0:-100)}if(doy>-1){month=1;day=doy;do{var dim=this._getDaysInMonth(year,month-1);if(day<=dim){break}month++;day-=dim}while(true)}var date=new Date(year,month-1,day);if(date.getFullYear()!=year||date.getMonth()+1!=month||date.getDate()!=day){throw"Invalid date"}return date},ATOM:"yy-mm-dd",COOKIE:"D, dd M yy",ISO_8601:"yy-mm-dd",RFC_822:"D, d M y",RFC_850:"DD, dd-M-y",RFC_1036:"D, d M y",RFC_1123:"D, d M yy",RFC_2822:"D, d M yy",RSS:"D, d M y",TIMESTAMP:"@",W3C:"yy-mm-dd",formatDate:function(format,date,settings){if(!date){return""}var dayNamesShort=(settings?settings.dayNamesShort:null)||this._defaults.dayNamesShort;var dayNames=(settings?settings.dayNames:null)||this._defaults.dayNames;var monthNamesShort=(settings?settings.monthNamesShort:null)||this._defaults.monthNamesShort;var monthNames=(settings?settings.monthNames:null)||this._defaults.monthNames;var lookAhead=function(match){var matches=(iFormat+1<format.length&&format.charAt(iFormat+1)==match);if(matches){iFormat++}return matches};var formatNumber=function(match,value,len){var num=""+value;if(lookAhead(match)){while(num.length<len){num="0"+num}}return num};var formatName=function(match,value,shortNames,longNames){return(lookAhead(match)?longNames[value]:shortNames[value])};var output="";var literal=false;if(date){for(var iFormat=0;iFormat<format.length;iFormat++){if(literal){if(format.charAt(iFormat)=="'"&&!lookAhead("'")){literal=false}else{output+=format.charAt(iFormat)}}else{switch(format.charAt(iFormat)){case"d":output+=formatNumber("d",date.getDate(),2);break;case"D":output+=formatName("D",date.getDay(),dayNamesShort,dayNames);break;case"o":var doy=date.getDate();for(var m=date.getMonth()-1;m>=0;m--){doy+=this._getDaysInMonth(date.getFullYear(),m)}output+=formatNumber("o",doy,3);break;case"m":output+=formatNumber("m",date.getMonth()+1,2);break;case"M":output+=formatName("M",date.getMonth(),monthNamesShort,monthNames);break;case"y":output+=(lookAhead("y")?date.getFullYear():(date.getYear()%100<10?"0":"")+date.getYear()%100);break;case"@":output+=date.getTime();break;case"'":if(lookAhead("'")){output+="'"}else{literal=true}break;default:output+=format.charAt(iFormat)}}}}return output},_possibleChars:function(format){var chars="";var literal=false;for(var iFormat=0;iFormat<format.length;iFormat++){if(literal){if(format.charAt(iFormat)=="'"&&!lookAhead("'")){literal=false}else{chars+=format.charAt(iFormat)}}else{switch(format.charAt(iFormat)){case"d":case"m":case"y":case"@":chars+="0123456789";break;case"D":case"M":return null;case"'":if(lookAhead("'")){chars+="'"}else{literal=true}break;default:chars+=format.charAt(iFormat)}}}return chars},_get:function(inst,name){return inst.settings[name]!==undefined?inst.settings[name]:this._defaults[name]},_setDateFromField:function(inst){var dateFormat=this._get(inst,"dateFormat");var dates=inst.input?inst.input.val().split(this._get(inst,"rangeSeparator")):null;inst.endDay=inst.endMonth=inst.endYear=null;var date=defaultDate=this._getDefaultDate(inst);if(dates.length>0){var settings=this._getFormatConfig(inst);if(dates.length>1){date=this.parseDate(dateFormat,dates[1],settings)||defaultDate;inst.endDay=date.getDate();inst.endMonth=date.getMonth();inst.endYear=date.getFullYear()}try{date=this.parseDate(dateFormat,dates[0],settings)||defaultDate}catch(e){this.log(e);date=defaultDate}}inst.selectedDay=date.getDate();inst.drawMonth=inst.selectedMonth=date.getMonth();inst.drawYear=inst.selectedYear=date.getFullYear();inst.currentDay=(dates[0]?date.getDate():0);inst.currentMonth=(dates[0]?date.getMonth():0);inst.currentYear=(dates[0]?date.getFullYear():0);this._adjustInstDate(inst)},_getDefaultDate:function(inst){var date=this._determineDate(this._get(inst,"defaultDate"),new Date());var minDate=this._getMinMaxDate(inst,"min",true);var maxDate=this._getMinMaxDate(inst,"max");date=(minDate&&date<minDate?minDate:date);date=(maxDate&&date>maxDate?maxDate:date);return date},_determineDate:function(date,defaultDate){var offsetNumeric=function(offset){var date=new Date();date.setUTCDate(date.getUTCDate()+offset);return date};var offsetString=function(offset,getDaysInMonth){var date=new Date();var year=date.getFullYear();var month=date.getMonth();var day=date.getDate();var pattern=/([+-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g;var matches=pattern.exec(offset);while(matches){switch(matches[2]||"d"){case"d":case"D":day+=parseInt(matches[1],10);break;case"w":case"W":day+=parseInt(matches[1],10)*7;break;case"m":case"M":month+=parseInt(matches[1],10);day=Math.min(day,getDaysInMonth(year,month));break;case"y":case"Y":year+=parseInt(matches[1],10);day=Math.min(day,getDaysInMonth(year,month));break}matches=pattern.exec(offset)}return new Date(year,month,day)};date=(date==null?defaultDate:(typeof date=="string"?offsetString(date,this._getDaysInMonth):(typeof date=="number"?(isNaN(date)?defaultDate:offsetNumeric(date)):date)));return(date&&date.toString()=="Invalid Date"?defaultDate:date)},_setDate:function(inst,date,endDate){var clear=!(date);var origMonth=inst.selectedMonth;var origYear=inst.selectedYear;date=this._determineDate(date,new Date());inst.selectedDay=inst.currentDay=date.getDate();inst.drawMonth=inst.selectedMonth=inst.currentMonth=date.getMonth();inst.drawYear=inst.selectedYear=inst.currentYear=date.getFullYear();if(this._get(inst,"rangeSelect")){if(endDate){endDate=this._determineDate(endDate,null);inst.endDay=endDate.getDate();inst.endMonth=endDate.getMonth();inst.endYear=endDate.getFullYear()}else{inst.endDay=inst.currentDay;inst.endMonth=inst.currentMonth;inst.endYear=inst.currentYear}}if(origMonth!=inst.selectedMonth||origYear!=inst.selectedYear){this._notifyChange(inst)}this._adjustInstDate(inst);if(inst.input){inst.input.val(clear?"":this._formatDate(inst)+(!this._get(inst,"rangeSelect")?"":this._get(inst,"rangeSeparator")+this._formatDate(inst,inst.endDay,inst.endMonth,inst.endYear)))}},_getDate:function(inst){var startDate=(!inst.currentYear||(inst.input&&inst.input.val()=="")?null:new Date(inst.currentYear,inst.currentMonth,inst.currentDay));if(this._get(inst,"rangeSelect")){return[inst.rangeStart||startDate,(!inst.endYear?inst.rangeStart||startDate:new Date(inst.endYear,inst.endMonth,inst.endDay))]}else{return startDate}},_generateHTML:function(inst){var today=new Date();today=new Date(today.getFullYear(),today.getMonth(),today.getDate());var showStatus=this._get(inst,"showStatus");var initStatus=this._get(inst,"initStatus")||"&#xa0;";var isRTL=this._get(inst,"isRTL");var clear=(this._get(inst,"mandatory")?"":'<div class="ui-datepicker-clear"><a onclick="jQuery.datepicker._clearDate(\'#'+inst.id+"');\""+this._addStatus(showStatus,inst.id,this._get(inst,"clearStatus"),initStatus)+">"+this._get(inst,"clearText")+"</a></div>");var controls='<div class="ui-datepicker-control">'+(isRTL?"":clear)+'<div class="ui-datepicker-close"><a onclick="jQuery.datepicker._hideDatepicker();"'+this._addStatus(showStatus,inst.id,this._get(inst,"closeStatus"),initStatus)+">"+this._get(inst,"closeText")+"</a></div>"+(isRTL?clear:"")+"</div>";var prompt=this._get(inst,"prompt");var closeAtTop=this._get(inst,"closeAtTop");var hideIfNoPrevNext=this._get(inst,"hideIfNoPrevNext");var navigationAsDateFormat=this._get(inst,"navigationAsDateFormat");var showBigPrevNext=this._get(inst,"showBigPrevNext");var numMonths=this._getNumberOfMonths(inst);var showCurrentAtPos=this._get(inst,"showCurrentAtPos");var stepMonths=this._get(inst,"stepMonths");var stepBigMonths=this._get(inst,"stepBigMonths");var isMultiMonth=(numMonths[0]!=1||numMonths[1]!=1);var currentDate=(!inst.currentDay?new Date(9999,9,9):new Date(inst.currentYear,inst.currentMonth,inst.currentDay));var minDate=this._getMinMaxDate(inst,"min",true);var maxDate=this._getMinMaxDate(inst,"max");var drawMonth=inst.drawMonth-showCurrentAtPos;var drawYear=inst.drawYear;if(drawMonth<0){drawMonth+=12;drawYear--}if(maxDate){var maxDraw=new Date(maxDate.getFullYear(),maxDate.getMonth()-numMonths[1]+1,maxDate.getDate());maxDraw=(minDate&&maxDraw<minDate?minDate:maxDraw);while(new Date(drawYear,drawMonth,1)>maxDraw){drawMonth--;if(drawMonth<0){drawMonth=11;drawYear--}}}var prevText=this._get(inst,"prevText");prevText=(!navigationAsDateFormat?prevText:this.formatDate(prevText,new Date(drawYear,drawMonth-stepMonths,1),this._getFormatConfig(inst)));var prevBigText=(showBigPrevNext?this._get(inst,"prevBigText"):"");prevBigText=(!navigationAsDateFormat?prevBigText:this.formatDate(prevBigText,new Date(drawYear,drawMonth-stepBigMonths,1),this._getFormatConfig(inst)));var prev='<div class="ui-datepicker-prev">'+(this._canAdjustMonth(inst,-1,drawYear,drawMonth)?(showBigPrevNext?"<a onclick=\"jQuery.datepicker._adjustDate('#"+inst.id+"', -"+stepBigMonths+", 'M');\""+this._addStatus(showStatus,inst.id,this._get(inst,"prevBigStatus"),initStatus)+">"+prevBigText+"</a>":"")+"<a onclick=\"jQuery.datepicker._adjustDate('#"+inst.id+"', -"+stepMonths+", 'M');\""+this._addStatus(showStatus,inst.id,this._get(inst,"prevStatus"),initStatus)+">"+prevText+"</a>":(hideIfNoPrevNext?"":"<label>"+prevBigText+"</label><label>"+prevText+"</label>"))+"</div>";var nextText=this._get(inst,"nextText");nextText=(!navigationAsDateFormat?nextText:this.formatDate(nextText,new Date(drawYear,drawMonth+stepMonths,1),this._getFormatConfig(inst)));var nextBigText=(showBigPrevNext?this._get(inst,"nextBigText"):"");nextBigText=(!navigationAsDateFormat?nextBigText:this.formatDate(nextBigText,new Date(drawYear,drawMonth+stepBigMonths,1),this._getFormatConfig(inst)));var next='<div class="ui-datepicker-next">'+(this._canAdjustMonth(inst,+1,drawYear,drawMonth)?"<a onclick=\"jQuery.datepicker._adjustDate('#"+inst.id+"', +"+stepMonths+", 'M');\""+this._addStatus(showStatus,inst.id,this._get(inst,"nextStatus"),initStatus)+">"+nextText+"</a>"+(showBigPrevNext?"<a onclick=\"jQuery.datepicker._adjustDate('#"+inst.id+"', +"+stepBigMonths+", 'M');\""+this._addStatus(showStatus,inst.id,this._get(inst,"nextBigStatus"),initStatus)+">"+nextBigText+"</a>":""):(hideIfNoPrevNext?"":"<label>"+nextText+"</label><label>"+nextBigText+"</label>"))+"</div>";var currentText=this._get(inst,"currentText");var gotoDate=(this._get(inst,"gotoCurrent")&&inst.currentDay?currentDate:today);currentText=(!navigationAsDateFormat?currentText:this.formatDate(currentText,gotoDate,this._getFormatConfig(inst)));var html=(prompt?'<div class="'+this._promptClass+'">'+prompt+"</div>":"")+(closeAtTop&&!inst.inline?controls:"")+'<div class="ui-datepicker-links">'+(isRTL?next:prev)+(this._isInRange(inst,gotoDate)?'<div class="ui-datepicker-current"><a onclick="jQuery.datepicker._gotoToday(\'#'+inst.id+"');\""+this._addStatus(showStatus,inst.id,this._get(inst,"currentStatus"),initStatus)+">"+currentText+"</a></div>":"")+(isRTL?prev:next)+"</div>";var firstDay=this._get(inst,"firstDay");var changeFirstDay=this._get(inst,"changeFirstDay");var dayNames=this._get(inst,"dayNames");var dayNamesShort=this._get(inst,"dayNamesShort");var dayNamesMin=this._get(inst,"dayNamesMin");var monthNames=this._get(inst,"monthNames");var beforeShowDay=this._get(inst,"beforeShowDay");var highlightWeek=this._get(inst,"highlightWeek");var showOtherMonths=this._get(inst,"showOtherMonths");var showWeeks=this._get(inst,"showWeeks");var calculateWeek=this._get(inst,"calculateWeek")||this.iso8601Week;var weekStatus=this._get(inst,"weekStatus");var status=(showStatus?this._get(inst,"dayStatus")||initStatus:"");var dateStatus=this._get(inst,"statusForDate")||this.dateStatus;var endDate=inst.endDay?new Date(inst.endYear,inst.endMonth,inst.endDay):currentDate;for(var row=0;row<numMonths[0];row++){for(var col=0;col<numMonths[1];col++){var selectedDate=new Date(drawYear,drawMonth,inst.selectedDay);html+='<div class="ui-datepicker-one-month'+(col==0?" ui-datepicker-new-row":"")+'">'+this._generateMonthYearHeader(inst,drawMonth,drawYear,minDate,maxDate,selectedDate,row>0||col>0,showStatus,initStatus,monthNames)+'<table class="ui-datepicker" cellpadding="0" cellspacing="0"><thead><tr class="ui-datepicker-title-row">'+(showWeeks?"<td"+this._addStatus(showStatus,inst.id,weekStatus,initStatus)+">"+this._get(inst,"weekHeader")+"</td>":"");for(var dow=0;dow<7;dow++){var day=(dow+firstDay)%7;var dayStatus=(status.indexOf("DD")>-1?status.replace(/DD/,dayNames[day]):status.replace(/D/,dayNamesShort[day]));html+="<td"+((dow+firstDay+6)%7>=5?' class="ui-datepicker-week-end-cell"':"")+">"+(!changeFirstDay?"<span":"<a onclick=\"jQuery.datepicker._changeFirstDay('#"+inst.id+"', "+day+');"')+this._addStatus(showStatus,inst.id,dayStatus,initStatus)+' title="'+dayNames[day]+'">'+dayNamesMin[day]+(changeFirstDay?"</a>":"</span>")+"</td>"}html+="</tr></thead><tbody>";var daysInMonth=this._getDaysInMonth(drawYear,drawMonth);if(drawYear==inst.selectedYear&&drawMonth==inst.selectedMonth){inst.selectedDay=Math.min(inst.selectedDay,daysInMonth)}var leadDays=(this._getFirstDayOfMonth(drawYear,drawMonth)-firstDay+7)%7;var tzDate=new Date(drawYear,drawMonth,1-leadDays);var utcDate=new Date(drawYear,drawMonth,1-leadDays);var printDate=utcDate;var numRows=(isMultiMonth?6:Math.ceil((leadDays+daysInMonth)/7));for(var dRow=0;dRow<numRows;dRow++){html+='<tr class="ui-datepicker-days-row">'+(showWeeks?'<td class="ui-datepicker-week-col"'+this._addStatus(showStatus,inst.id,weekStatus,initStatus)+">"+calculateWeek(printDate)+"</td>":"");for(var dow=0;dow<7;dow++){var daySettings=(beforeShowDay?beforeShowDay.apply((inst.input?inst.input[0]:null),[printDate]):[true,""]);var otherMonth=(printDate.getMonth()!=drawMonth);var unselectable=otherMonth||!daySettings[0]||(minDate&&printDate<minDate)||(maxDate&&printDate>maxDate);html+='<td class="ui-datepicker-days-cell'+((dow+firstDay+6)%7>=5?" ui-datepicker-week-end-cell":"")+(otherMonth?" ui-datepicker-other-month":"")+(printDate.getTime()==selectedDate.getTime()&&drawMonth==inst.selectedMonth?" ui-datepicker-days-cell-over":"")+(unselectable?" "+this._unselectableClass:"")+(otherMonth&&!showOtherMonths?"":" "+daySettings[1]+(printDate.getTime()>=currentDate.getTime()&&printDate.getTime()<=endDate.getTime()?" "+this._currentClass:"")+(printDate.getTime()==today.getTime()?" ui-datepicker-today":""))+'"'+((!otherMonth||showOtherMonths)&&daySettings[2]?' title="'+daySettings[2]+'"':"")+(unselectable?(highlightWeek?" onmouseover=\"jQuery(this).parent().addClass('ui-datepicker-week-over');\" onmouseout=\"jQuery(this).parent().removeClass('ui-datepicker-week-over');\"":""):" onmouseover=\"jQuery(this).addClass('ui-datepicker-days-cell-over')"+(highlightWeek?".parent().addClass('ui-datepicker-week-over')":"")+";"+(!showStatus||(otherMonth&&!showOtherMonths)?"":"jQuery('#ui-datepicker-status-"+inst.id+"').html('"+(dateStatus.apply((inst.input?inst.input[0]:null),[printDate,inst])||initStatus)+"');")+"\" onmouseout=\"jQuery(this).removeClass('ui-datepicker-days-cell-over')"+(highlightWeek?".parent().removeClass('ui-datepicker-week-over')":"")+";"+(!showStatus||(otherMonth&&!showOtherMonths)?"":"jQuery('#ui-datepicker-status-"+inst.id+"').html('"+initStatus+"');")+'" onclick="jQuery.datepicker._selectDay(\'#'+inst.id+"',"+drawMonth+","+drawYear+', this);"')+">"+(otherMonth?(showOtherMonths?printDate.getDate():"&#xa0;"):(unselectable?printDate.getDate():"<a>"+printDate.getDate()+"</a>"))+"</td>";tzDate.setDate(tzDate.getDate()+1);utcDate.setUTCDate(utcDate.getUTCDate()+1);printDate=(tzDate>utcDate?tzDate:utcDate)}html+="</tr>"}drawMonth++;if(drawMonth>11){drawMonth=0;drawYear++}html+="</tbody></table></div>"}}html+=(showStatus?'<div style="clear: both;"></div><div id="ui-datepicker-status-'+inst.id+'" class="ui-datepicker-status">'+initStatus+"</div>":"")+(!closeAtTop&&!inst.inline?controls:"")+'<div style="clear: both;"></div>'+($.browser.msie&&parseInt($.browser.version,10)<7&&!inst.inline?'<iframe src="javascript:false;" class="ui-datepicker-cover"></iframe>':"");return html},_generateMonthYearHeader:function(inst,drawMonth,drawYear,minDate,maxDate,selectedDate,secondary,showStatus,initStatus,monthNames){minDate=(inst.rangeStart&&minDate&&selectedDate<minDate?selectedDate:minDate);var showMonthAfterYear=this._get(inst,"showMonthAfterYear");var html='<div class="ui-datepicker-header">';var monthHtml="";if(secondary||!this._get(inst,"changeMonth")){monthHtml+=monthNames[drawMonth]+"&#xa0;"}else{var inMinYear=(minDate&&minDate.getFullYear()==drawYear);var inMaxYear=(maxDate&&maxDate.getFullYear()==drawYear);monthHtml+='<select class="ui-datepicker-new-month" onchange="jQuery.datepicker._selectMonthYear(\'#'+inst.id+"', this, 'M');\" onclick=\"jQuery.datepicker._clickMonthYear('#"+inst.id+"');\""+this._addStatus(showStatus,inst.id,this._get(inst,"monthStatus"),initStatus)+">";for(var month=0;month<12;month++){if((!inMinYear||month>=minDate.getMonth())&&(!inMaxYear||month<=maxDate.getMonth())){monthHtml+='<option value="'+month+'"'+(month==drawMonth?' selected="selected"':"")+">"+monthNames[month]+"</option>"}}monthHtml+="</select>"}if(!showMonthAfterYear){html+=monthHtml}if(secondary||!this._get(inst,"changeYear")){html+=drawYear}else{var years=this._get(inst,"yearRange").split(":");var year=0;var endYear=0;if(years.length!=2){year=drawYear-10;endYear=drawYear+10}else{if(years[0].charAt(0)=="+"||years[0].charAt(0)=="-"){year=endYear=new Date().getFullYear();year+=parseInt(years[0],10);endYear+=parseInt(years[1],10)}else{year=parseInt(years[0],10);endYear=parseInt(years[1],10)}}year=(minDate?Math.max(year,minDate.getFullYear()):year);endYear=(maxDate?Math.min(endYear,maxDate.getFullYear()):endYear);html+='<select class="ui-datepicker-new-year" onchange="jQuery.datepicker._selectMonthYear(\'#'+inst.id+"', this, 'Y');\" onclick=\"jQuery.datepicker._clickMonthYear('#"+inst.id+"');\""+this._addStatus(showStatus,inst.id,this._get(inst,"yearStatus"),initStatus)+">";for(;year<=endYear;year++){html+='<option value="'+year+'"'+(year==drawYear?' selected="selected"':"")+">"+year+"</option>"}html+="</select>"}if(showMonthAfterYear){html+=monthHtml}html+="</div>";return html},_addStatus:function(showStatus,id,text,initStatus){return(showStatus?" onmouseover=\"jQuery('#ui-datepicker-status-"+id+"').html('"+(text||initStatus)+"');\" onmouseout=\"jQuery('#ui-datepicker-status-"+id+"').html('"+initStatus+"');\"":"")},_adjustInstDate:function(inst,offset,period){var year=inst.drawYear+(period=="Y"?offset:0);var month=inst.drawMonth+(period=="M"?offset:0);var day=Math.min(inst.selectedDay,this._getDaysInMonth(year,month))+(period=="D"?offset:0);var date=new Date(year,month,day);var minDate=this._getMinMaxDate(inst,"min",true);var maxDate=this._getMinMaxDate(inst,"max");date=(minDate&&date<minDate?minDate:date);date=(maxDate&&date>maxDate?maxDate:date);inst.selectedDay=date.getDate();inst.drawMonth=inst.selectedMonth=date.getMonth();inst.drawYear=inst.selectedYear=date.getFullYear();if(period=="M"||period=="Y"){this._notifyChange(inst)}},_notifyChange:function(inst){var onChange=this._get(inst,"onChangeMonthYear");if(onChange){onChange.apply((inst.input?inst.input[0]:null),[inst.selectedYear,inst.selectedMonth+1,inst])}},_getNumberOfMonths:function(inst){var numMonths=this._get(inst,"numberOfMonths");return(numMonths==null?[1,1]:(typeof numMonths=="number"?[1,numMonths]:numMonths))},_getMinMaxDate:function(inst,minMax,checkRange){var date=this._determineDate(this._get(inst,minMax+"Date"),null);if(date){date.setHours(0);date.setMinutes(0);date.setSeconds(0);date.setMilliseconds(0)}return(!checkRange||!inst.rangeStart?date:(!date||inst.rangeStart>date?inst.rangeStart:date))},_getDaysInMonth:function(year,month){return 32-new Date(year,month,32).getDate()},_getFirstDayOfMonth:function(year,month){return new Date(year,month,1).getDay()},_canAdjustMonth:function(inst,offset,curYear,curMonth){var numMonths=this._getNumberOfMonths(inst);var date=new Date(curYear,curMonth+(offset<0?offset:numMonths[1]),1);if(offset<0){date.setDate(this._getDaysInMonth(date.getFullYear(),date.getMonth()))}return this._isInRange(inst,date)},_isInRange:function(inst,date){var newMinDate=(!inst.rangeStart?null:new Date(inst.selectedYear,inst.selectedMonth,inst.selectedDay));newMinDate=(newMinDate&&inst.rangeStart<newMinDate?inst.rangeStart:newMinDate);var minDate=newMinDate||this._getMinMaxDate(inst,"min");var maxDate=this._getMinMaxDate(inst,"max");return((!minDate||date>=minDate)&&(!maxDate||date<=maxDate))},_getFormatConfig:function(inst){var shortYearCutoff=this._get(inst,"shortYearCutoff");shortYearCutoff=(typeof shortYearCutoff!="string"?shortYearCutoff:new Date().getFullYear()%100+parseInt(shortYearCutoff,10));return{shortYearCutoff:shortYearCutoff,dayNamesShort:this._get(inst,"dayNamesShort"),dayNames:this._get(inst,"dayNames"),monthNamesShort:this._get(inst,"monthNamesShort"),monthNames:this._get(inst,"monthNames")}},_formatDate:function(inst,day,month,year){if(!day){inst.currentDay=inst.selectedDay;inst.currentMonth=inst.selectedMonth;inst.currentYear=inst.selectedYear}var date=(day?(typeof day=="object"?day:new Date(year,month,day)):new Date(inst.currentYear,inst.currentMonth,inst.currentDay));return this.formatDate(this._get(inst,"dateFormat"),date,this._getFormatConfig(inst))}});function extendRemove(target,props){$.extend(target,props);for(var name in props){if(props[name]==null||props[name]==undefined){target[name]=props[name]}}return target}function isArray(a){return(a&&(($.browser.safari&&typeof a=="object"&&a.length)||(a.constructor&&a.constructor.toString().match(/\Array\(\)/))))}$.fn.datepicker=function(options){if(!$.datepicker.initialized){$(document.body).append($.datepicker.dpDiv).mousedown($.datepicker._checkExternalClick);$.datepicker.initialized=true}var otherArgs=Array.prototype.slice.call(arguments,1);if(typeof options=="string"&&(options=="isDisabled"||options=="getDate")){return $.datepicker["_"+options+"Datepicker"].apply($.datepicker,[this[0]].concat(otherArgs))}return this.each(function(){typeof options=="string"?$.datepicker["_"+options+"Datepicker"].apply($.datepicker,[this].concat(otherArgs)):$.datepicker._attachDatepicker(this,options)})};$.datepicker=new Datepicker();$.datepicker.initialized=false;$.datepicker.uuid=new Date().getTime()})(jQuery);(function(B){var A={dragStart:"start.draggable",drag:"drag.draggable",dragStop:"stop.draggable",maxHeight:"maxHeight.resizable",minHeight:"minHeight.resizable",maxWidth:"maxWidth.resizable",minWidth:"minWidth.resizable",resizeStart:"start.resizable",resize:"drag.resizable",resizeStop:"stop.resizable"};B.widget("ui.dialog",{_init:function(){this.originalTitle=this.element.attr("title");this.options.title=this.options.title||this.originalTitle;var K=this,L=this.options,F=this.element.removeAttr("title").addClass("ui-dialog-content").wrap("<div/>").wrap("<div/>"),H=(this.uiDialogContainer=F.parent()).addClass("ui-dialog-container").css({position:"relative",width:"100%",height:"100%"}),E=(this.uiDialogTitlebar=B("<div/>")).addClass("ui-dialog-titlebar").append('<a href="#" class="ui-dialog-titlebar-close"><span>X</span></a>').prependTo(H),J=L.title||"&nbsp;",C=B.ui.dialog.getTitleId(this.element),D=B("<span/>").addClass("ui-dialog-title").attr("id",C).html(J).prependTo(E),I=(this.uiDialog=H.parent()).appendTo(document.body).hide().addClass("ui-dialog").addClass(L.dialogClass).addClass(F.attr("className")).removeClass("ui-dialog-content").css({position:"absolute",width:L.width,height:L.height,overflow:"hidden",zIndex:L.zIndex}).attr("tabIndex",-1).css("outline",0).keydown(function(M){(L.closeOnEscape&&M.keyCode&&M.keyCode==B.keyCode.ESCAPE&&K.close())}).mousedown(function(){K._moveToTop()}),G=(this.uiDialogButtonPane=B("<div/>")).addClass("ui-dialog-buttonpane").css({position:"absolute",bottom:0}).appendTo(I);this.uiDialogTitlebarClose=B(".ui-dialog-titlebar-close",E).hover(function(){B(this).addClass("ui-dialog-titlebar-close-hover")},function(){B(this).removeClass("ui-dialog-titlebar-close-hover")}).mousedown(function(M){M.stopPropagation()}).click(function(){K.close();return false});E.find("*").add(E).each(function(){B.ui.disableSelection(this)});(L.draggable&&B.fn.draggable&&this._makeDraggable());(L.resizable&&B.fn.resizable&&this._makeResizable());this._createButtons(L.buttons);this._isOpen=false;(L.bgiframe&&B.fn.bgiframe&&I.bgiframe());(L.autoOpen&&this.open())},destroy:function(){(this.overlay&&this.overlay.destroy());this.uiDialog.hide();this.element.unbind(".dialog").removeData("dialog").removeClass("ui-dialog-content").hide().appendTo("body");this.uiDialog.remove();(this.originalTitle&&this.element.attr("title",this.originalTitle))},close:function(){if(false===this._trigger("beforeclose",null,{options:this.options})){return }(this.overlay&&this.overlay.destroy());this.uiDialog.hide(this.options.hide).unbind("keypress.ui-dialog");this._trigger("close",null,{options:this.options});B.ui.dialog.overlay.resize();this._isOpen=false},isOpen:function(){return this._isOpen},open:function(){if(this._isOpen){return }this.overlay=this.options.modal?new B.ui.dialog.overlay(this):null;(this.uiDialog.next().length&&this.uiDialog.appendTo("body"));this._position(this.options.position);this.uiDialog.show(this.options.show);(this.options.autoResize&&this._size());this._moveToTop(true);(this.options.modal&&this.uiDialog.bind("keypress.ui-dialog",function(E){if(E.keyCode!=B.keyCode.TAB){return }var D=B(":tabbable",this),F=D.filter(":first")[0],C=D.filter(":last")[0];if(E.target==C&&!E.shiftKey){setTimeout(function(){F.focus()},1)}else{if(E.target==F&&E.shiftKey){setTimeout(function(){C.focus()},1)}}}));this.uiDialog.find(":tabbable:first").focus();this._trigger("open",null,{options:this.options});this._isOpen=true},_createButtons:function(F){var E=this,C=false,D=this.uiDialogButtonPane;D.empty().hide();B.each(F,function(){return !(C=true)});if(C){D.show();B.each(F,function(G,H){B('<button type="button"></button>').text(G).click(function(){H.apply(E.element[0],arguments)}).appendTo(D)})}},_makeDraggable:function(){var C=this,D=this.options;this.uiDialog.draggable({cancel:".ui-dialog-content",helper:D.dragHelper,handle:".ui-dialog-titlebar",start:function(){C._moveToTop();(D.dragStart&&D.dragStart.apply(C.element[0],arguments))},drag:function(){(D.drag&&D.drag.apply(C.element[0],arguments))},stop:function(){(D.dragStop&&D.dragStop.apply(C.element[0],arguments));B.ui.dialog.overlay.resize()}})},_makeResizable:function(F){F=(F===undefined?this.options.resizable:F);var C=this,E=this.options,D=typeof F=="string"?F:"n,e,s,w,se,sw,ne,nw";this.uiDialog.resizable({cancel:".ui-dialog-content",helper:E.resizeHelper,maxWidth:E.maxWidth,maxHeight:E.maxHeight,minWidth:E.minWidth,minHeight:E.minHeight,start:function(){(E.resizeStart&&E.resizeStart.apply(C.element[0],arguments))},resize:function(){(E.autoResize&&C._size.apply(C));(E.resize&&E.resize.apply(C.element[0],arguments))},handles:D,stop:function(){(E.autoResize&&C._size.apply(C));(E.resizeStop&&E.resizeStop.apply(C.element[0],arguments));B.ui.dialog.overlay.resize()}})},_moveToTop:function(E){if((this.options.modal&&!E)||(!this.options.stack&&!this.options.modal)){return this._trigger("focus",null,{options:this.options})}var D=this.options.zIndex,C=this.options;B(".ui-dialog:visible").each(function(){D=Math.max(D,parseInt(B(this).css("z-index"),10)||C.zIndex)});(this.overlay&&this.overlay.$el.css("z-index",++D));this.uiDialog.css("z-index",++D);this._trigger("focus",null,{options:this.options})},_position:function(H){var D=B(window),E=B(document),F=E.scrollTop(),C=E.scrollLeft(),G=F;if(B.inArray(H,["center","top","right","bottom","left"])>=0){H=[H=="right"||H=="left"?H:"center",H=="top"||H=="bottom"?H:"middle"]}if(H.constructor!=Array){H=["center","middle"]}if(H[0].constructor==Number){C+=H[0]}else{switch(H[0]){case"left":C+=0;break;case"right":C+=D.width()-this.uiDialog.width();break;default:case"center":C+=(D.width()-this.uiDialog.width())/2}}if(H[1].constructor==Number){F+=H[1]}else{switch(H[1]){case"top":F+=0;break;case"bottom":F+=D.height()-this.uiDialog.height();break;default:case"middle":F+=(D.height()-this.uiDialog.height())/2}}F=Math.max(F,G);this.uiDialog.css({top:F,left:C})},_setData:function(D,E){(A[D]&&this.uiDialog.data(A[D],E));switch(D){case"buttons":this._createButtons(E);break;case"draggable":(E?this._makeDraggable():this.uiDialog.draggable("destroy"));break;case"height":this.uiDialog.height(E);break;case"position":this._position(E);break;case"resizable":var C=this.uiDialog,F=this.uiDialog.is(":data(resizable)");(F&&!E&&C.resizable("destroy"));(F&&typeof E=="string"&&C.resizable("option","handles",E));(F||this._makeResizable(E));break;case"title":B(".ui-dialog-title",this.uiDialogTitlebar).html(E||"&nbsp;");break;case"width":this.uiDialog.width(E);break}B.widget.prototype._setData.apply(this,arguments)},_size:function(){var D=this.uiDialogContainer,G=this.uiDialogTitlebar,E=this.element,F=(parseInt(E.css("margin-top"),10)||0)+(parseInt(E.css("margin-bottom"),10)||0),C=(parseInt(E.css("margin-left"),10)||0)+(parseInt(E.css("margin-right"),10)||0);E.height(D.height()-G.outerHeight()-F);E.width(D.width()-C)}});B.extend(B.ui.dialog,{defaults:{autoOpen:true,autoResize:true,bgiframe:false,buttons:{},closeOnEscape:true,draggable:true,height:200,minHeight:100,minWidth:150,modal:false,overlay:{},position:"center",resizable:true,stack:true,width:300,zIndex:1000},getter:"isOpen",uuid:0,getTitleId:function(C){return"ui-dialog-title-"+(C.attr("id")||++this.uuid)},overlay:function(C){this.$el=B.ui.dialog.overlay.create(C)}});B.extend(B.ui.dialog.overlay,{instances:[],events:B.map("focus,mousedown,mouseup,keydown,keypress,click".split(","),function(C){return C+".dialog-overlay"}).join(" "),create:function(D){if(this.instances.length===0){setTimeout(function(){B("a, :input").bind(B.ui.dialog.overlay.events,function(){var F=false;var H=B(this).parents(".ui-dialog");if(H.length){var E=B(".ui-dialog-overlay");if(E.length){var G=parseInt(E.css("z-index"),10);E.each(function(){G=Math.max(G,parseInt(B(this).css("z-index"),10))});F=parseInt(H.css("z-index"),10)>G}else{F=true}}return F})},1);B(document).bind("keydown.dialog-overlay",function(E){(D.options.closeOnEscape&&E.keyCode&&E.keyCode==B.keyCode.ESCAPE&&D.close())});B(window).bind("resize.dialog-overlay",B.ui.dialog.overlay.resize)}var C=B("<div/>").appendTo(document.body).addClass("ui-dialog-overlay").css(B.extend({borderWidth:0,margin:0,padding:0,position:"absolute",top:0,left:0,width:this.width(),height:this.height()},D.options.overlay));(D.options.bgiframe&&B.fn.bgiframe&&C.bgiframe());this.instances.push(C);return C},destroy:function(C){this.instances.splice(B.inArray(this.instances,C),1);if(this.instances.length===0){B("a, :input").add([document,window]).unbind(".dialog-overlay")}C.remove()},height:function(){if(B.browser.msie&&B.browser.version<7){var D=Math.max(document.documentElement.scrollHeight,document.body.scrollHeight);var C=Math.max(document.documentElement.offsetHeight,document.body.offsetHeight);if(D<C){return B(window).height()+"px"}else{return D+"px"}}else{if(B.browser.opera){return Math.max(window.innerHeight,B(document).height())+"px"}else{return B(document).height()+"px"}}},width:function(){if(B.browser.msie&&B.browser.version<7){var C=Math.max(document.documentElement.scrollWidth,document.body.scrollWidth);var D=Math.max(document.documentElement.offsetWidth,document.body.offsetWidth);if(C<D){return B(window).width()+"px"}else{return C+"px"}}else{if(B.browser.opera){return Math.max(window.innerWidth,B(document).width())+"px"}else{return B(document).width()+"px"}}},resize:function(){var C=B([]);B.each(B.ui.dialog.overlay.instances,function(){C=C.add(this)});C.css({width:0,height:0}).css({width:B.ui.dialog.overlay.width(),height:B.ui.dialog.overlay.height()})}});B.extend(B.ui.dialog.overlay.prototype,{destroy:function(){B.ui.dialog.overlay.destroy(this.$el)}})})(jQuery);(function(B){var A=0;B.widget("ui.magnifier",{_init:function(){var C=this,D=this.options;this.element.addClass("ui-magnifier").bind("click.magnifier",function(E){(!C.disabled&&D.click&&D.click.apply(this,[E,{options:C.options,current:C.current[0],currentOffset:C.current[1]}]))});if(!(/^(r|a)/).test(this.element.css("position"))){this.element.css("position","relative")}this.items=[];this.element.find(D.items).each(function(){var E=B(this);C.items.push([this,E.offset(),[E.width(),E.height()],(D.overlap?E.position():null)]);(D.opacity&&E.css("opacity",D.opacity.min))});(D.overlap&&B.each(this.items,function(){B(this[0]).css({position:"absolute",top:this[3].top,left:this[3].left})}));this.identifier=++A;B(document).bind("mousemove.magnifier"+this.identifier,function(E){(C.disabled||C._magnify.apply(C,[E]))});this.pp=this.element.offset()},destroy:function(){this.reset();this.element.removeClass("ui-magnifier ui-magnifier-disabled").unbind(".magnifier");B(document).unbind("mousemove.magnifier"+this.identifier)},disable:function(){this.reset();B.widget.prototype.disable.apply(this,arguments)},reset:function(C){var D=this.options;B.each(this.items,function(){var E=this;B(E[0]).css({width:E[2][0],height:E[2][1],top:(E[3]?E[3].top:0),left:(E[3]?E[3].left:0)});(D.opacity&&B(E[0]).css("opacity",D.opacity.min));(D.zIndex&&B(E[0]).css("z-index",""))})},_magnify:function(G){var F=[G.pageX,G.pageY],H=this.options,J,I=1;this.current=this.items[0];var C=((F[0]>this.pp.left-H.distance)&&(F[0]<this.pp.left+this.element[0].offsetWidth+H.distance)&&(F[1]>this.pp.top-H.distance)&&(F[1]<this.pp.top+this.element[0].offsetHeight+H.distance));if(!C){return false}for(var E=0;E<this.items.length;E++){J=this.items[E];var D=I;if(!H.axis){I=Math.sqrt(Math.pow(F[0]-((J[3]?this.pp.left:J[1].left)+parseInt(J[0].style.left,10))-(J[0].offsetWidth/2),2)+Math.pow(F[1]-((J[3]?this.pp.top:J[1].top)+parseInt(J[0].style.top,10))-(J[0].offsetHeight/2),2))}else{if(H.axis=="y"){I=Math.abs(F[1]-((J[3]?this.pp.top:J[1].top)+parseInt(J[0].style.top,10))-(J[0].offsetHeight/2))}else{I=Math.abs(F[0]-((J[3]?this.pp.left:J[1].left)+parseInt(J[0].style.left,10))-(J[0].offsetWidth/2))}}if(I<H.distance){this.current=I<D?J:this.current;if(!H.axis||H.axis!="y"){B(J[0]).css({width:J[2][0]+(J[2][0]*(H.magnification-1))-(((I/H.distance)*J[2][0])*(H.magnification-1)),left:(J[3]?(J[3].left+H.verticalLine*((J[2][1]*(H.magnification-1))-(((I/H.distance)*J[2][1])*(H.magnification-1)))):0)})}if(!H.axis||H.axis!="x"){B(J[0]).css({height:J[2][1]+(J[2][1]*(H.magnification-1))-(((I/H.distance)*J[2][1])*(H.magnification-1)),top:(J[3]?J[3].top:0)+(H.baseline-0.5)*((J[2][0]*(H.magnification-1))-(((I/H.distance)*J[2][0])*(H.magnification-1)))})}if(H.opacity){B(J[0]).css("opacity",H.opacity.max-(I/H.distance)<H.opacity.min?H.opacity.min:H.opacity.max-(I/H.distance))}}else{B(J[0]).css({width:J[2][0],height:J[2][1],top:(J[3]?J[3].top:0),left:(J[3]?J[3].left:0)});(H.opacity&&B(J[0]).css("opacity",H.opacity.min))}(H.zIndex&&B(J[0]).css("z-index",""))}(H.zIndex&&B(this.current[0]).css("z-index",H.zIndex))}});B.extend(B.ui.magnifier,{defaults:{distance:150,magnification:2,baseline:0,verticalLine:-0.5,items:"> *"}})})(jQuery);(function(A){A.widget("ui.progressbar",{_init:function(){this._interval=this.options.interval;var B=this,C=this.options,E=(new Date()).getTime()+Math.random(),D=C.text||"0%";this.element.addClass("ui-progressbar").width(C.width);A.extend(this,{active:false,pixelState:0,percentState:0,identifier:E,bar:A('<div class="ui-progressbar-bar ui-hidden"></div>').css({width:"0px",overflow:"hidden",zIndex:100}),textElement:A('<div class="ui-progressbar-text"></div>').html(D).css({width:"0px",overflow:"hidden"}),textBg:A('<div class="ui-progressbar-text ui-progressbar-text-back"></div>').html(D).css({width:this.element.width()}),wrapper:A('<div class="ui-progressbar-wrap"></div>')});this.wrapper.append(this.bar.append(this.textElement.addClass(C.textClass)),this.textBg).appendTo(this.element)},plugins:{},ui:function(B){return{instance:this,identifier:this.identifier,options:this.options,element:this.bar,textElement:this.textElement,pixelState:this.pixelState,percentState:this.percentState}},_propagate:function(C,B){A.ui.plugin.call(this,C,[B,this.ui()]);this.element.triggerHandler(C=="progressbar"?C:["progressbar",C].join(""),[B,this.ui()],this.options[C])},destroy:function(){this.stop();this.element.removeClass("ui-progressbar ui-progressbar-disabled").removeData("progressbar").unbind(".progressbar").find(".ui-progressbar-wrap").remove();delete jQuery.easing[this.identifier]},enable:function(){this.element.removeClass("ui-progressbar-disabled");this.disabled=false},disable:function(){this.element.addClass("ui-progressbar-disabled");this.disabled=true},start:function(){var B=this,C=this.options;if(this.disabled){return }jQuery.easing[this.identifier]=function(K,L,J,I,H){var G=C.increment,E=C.width,F=((G>E?E:G)/E),D=Math.round(K/F)*F;return D>1?1:D};B.active=true;setTimeout(function(){B.active=false},C.duration);this._animate();this._propagate("start",this.ui());return false},_animate:function(){var C=this,D=this.options,B=D.interval;this.bar.animate({width:D.width},{duration:B,easing:this.identifier,step:function(G,E){C.progress((G/D.width)*100);var H=new Date().getTime(),F=(H-E.startTime);D.interval=B-F},complete:function(){delete jQuery.easing[C.identifier];C.pause();if(C.active){}}})},pause:function(){if(this.disabled){return }this.bar.stop();this._propagate("pause",this.ui())},stop:function(){this.bar.stop();this.bar.width(0);this.textElement.width(0);this.bar.addClass("ui-hidden");this.options.interval=this._interval;this._propagate("stop",this.ui())},text:function(B){this.textElement.html(B);this.textBg.html(B)},progress:function(B){if(this.bar.is(".ui-hidden")){this.bar.removeClass("ui-hidden")}this.percentState=B>100?100:B;this.pixelState=(this.percentState/100)*this.options.width;this.bar.width(this.pixelState);this.textElement.width(this.pixelState);if(this.options.range&&!this.options.text){this.textElement.html(Math.round(this.percentState)+"%")}this._propagate("progress",this.ui())}});A.ui.progressbar.defaults={width:300,duration:3000,interval:200,increment:1,range:true,text:"",addClass:"",textClass:""}})(jQuery);(function(A){A.fn.unwrap=A.fn.unwrap||function(B){return this.each(function(){A(this).parents(B).eq(0).after(this).remove()})};A.widget("ui.slider",{plugins:{},ui:function(B){return{options:this.options,handle:this.currentHandle,value:this.options.axis!="both"||!this.options.axis?Math.round(this.value(null,this.options.axis=="vertical"?"y":"x")):{x:Math.round(this.value(null,"x")),y:Math.round(this.value(null,"y"))},range:this._getRange()}},_propagate:function(C,B){A.ui.plugin.call(this,C,[B,this.ui()]);this.element.triggerHandler(C=="slide"?C:"slide"+C,[B,this.ui()],this.options[C])},destroy:function(){this.element.removeClass("ui-slider ui-slider-disabled").removeData("slider").unbind(".slider");if(this.handle&&this.handle.length){this.handle.unwrap("a");this.handle.each(function(){A(this).data("mouse")._mouseDestroy()})}this.generated&&this.generated.remove()},_setData:function(B,C){A.widget.prototype._setData.apply(this,arguments);if(/min|max|steps/.test(B)){this._initBoundaries()}if(B=="range"){C?this.handle.length==2&&this._createRange():this._removeRange()}},_init:function(){var B=this;this.element.addClass("ui-slider");this._initBoundaries();this.handle=A(this.options.handle,this.element);if(!this.handle.length){B.handle=B.generated=A(B.options.handles||[0]).map(function(){var D=A("<div/>").addClass("ui-slider-handle").appendTo(B.element);if(this.id){D.attr("id",this.id)}return D[0]})}var C=function(D){this.element=A(D);this.element.data("mouse",this);this.options=B.options;this.element.bind("mousedown",function(){if(B.currentHandle){this.blur(B.currentHandle)}B._focus(this,true)});this._mouseInit()};A.extend(C.prototype,A.ui.mouse,{_mouseStart:function(D){return B._start.call(B,D,this.element[0])},_mouseStop:function(D){return B._stop.call(B,D,this.element[0])},_mouseDrag:function(D){return B._drag.call(B,D,this.element[0])},_mouseCapture:function(){return true},trigger:function(D){this._mouseDown(D)}});A(this.handle).each(function(){new C(this)}).wrap('<a href="#" style="outline:none;border:none;"></a>').parent().bind("click",function(){return false}).bind("focus",function(D){B._focus(this.firstChild)}).bind("blur",function(D){B._blur(this.firstChild)}).bind("keydown",function(D){if(!B.options.noKeyboard){return B._keydown(D.keyCode,this.firstChild)}});this.element.bind("mousedown.slider",function(D){B._click.apply(B,[D]);B.currentHandle.data("mouse").trigger(D);B.firstValue=B.firstValue+1});A.each(this.options.handles||[],function(D,E){B.moveTo(E.start,D,true)});if(!isNaN(this.options.startValue)){this.moveTo(this.options.startValue,0,true)}this.previousHandle=A(this.handle[0]);if(this.handle.length==2&&this.options.range){this._createRange()}},_initBoundaries:function(){var B=this.element[0],C=this.options;this.actualSize={width:this.element.outerWidth(),height:this.element.outerHeight()};A.extend(C,{axis:C.axis||(B.offsetWidth<B.offsetHeight?"vertical":"horizontal"),max:!isNaN(parseInt(C.max,10))?{x:parseInt(C.max,10),y:parseInt(C.max,10)}:({x:C.max&&C.max.x||100,y:C.max&&C.max.y||100}),min:!isNaN(parseInt(C.min,10))?{x:parseInt(C.min,10),y:parseInt(C.min,10)}:({x:C.min&&C.min.x||0,y:C.min&&C.min.y||0})});C.realMax={x:C.max.x-C.min.x,y:C.max.y-C.min.y};C.stepping={x:C.stepping&&C.stepping.x||parseInt(C.stepping,10)||(C.steps?C.realMax.x/(C.steps.x||parseInt(C.steps,10)||C.realMax.x):0),y:C.stepping&&C.stepping.y||parseInt(C.stepping,10)||(C.steps?C.realMax.y/(C.steps.y||parseInt(C.steps,10)||C.realMax.y):0)}},_keydown:function(F,E){var C=F;if(/(33|34|35|36|37|38|39|40)/.test(C)){var G=this.options,B,I;if(/(35|36)/.test(C)){B=(C==35)?G.max.x:G.min.x;I=(C==35)?G.max.y:G.min.y}else{var H=/(34|37|40)/.test(C)?"-=":"+=";var D=/(37|38|39|40)/.test(C)?"_oneStep":"_pageStep";B=H+this[D]("x");I=H+this[D]("y")}this.moveTo({x:B,y:I},E);return false}return true},_focus:function(B,C){this.currentHandle=A(B).addClass("ui-slider-handle-active");if(C){this.currentHandle.parent()[0].focus()}},_blur:function(B){A(B).removeClass("ui-slider-handle-active");if(this.currentHandle&&this.currentHandle[0]==B){this.previousHandle=this.currentHandle;this.currentHandle=null}},_click:function(C){var D=[C.pageX,C.pageY];var B=false;this.handle.each(function(){if(this==C.target){B=true}});if(B||this.options.disabled||!(this.currentHandle||this.previousHandle)){return }if(!this.currentHandle&&this.previousHandle){this._focus(this.previousHandle,true)}this.offset=this.element.offset();this.moveTo({y:this._convertValue(C.pageY-this.offset.top-this.currentHandle[0].offsetHeight/2,"y"),x:this._convertValue(C.pageX-this.offset.left-this.currentHandle[0].offsetWidth/2,"x")},null,!this.options.distance)},_createRange:function(){if(this.rangeElement){return }this.rangeElement=A("<div></div>").addClass("ui-slider-range").css({position:"absolute"}).appendTo(this.element);this._updateRange()},_removeRange:function(){this.rangeElement.remove();this.rangeElement=null},_updateRange:function(){var C=this.options.axis=="vertical"?"top":"left";var B=this.options.axis=="vertical"?"height":"width";this.rangeElement.css(C,(parseInt(A(this.handle[0]).css(C),10)||0)+this._handleSize(0,this.options.axis=="vertical"?"y":"x")/2);this.rangeElement.css(B,(parseInt(A(this.handle[1]).css(C),10)||0)-(parseInt(A(this.handle[0]).css(C),10)||0))},_getRange:function(){return this.rangeElement?this._convertValue(parseInt(this.rangeElement.css(this.options.axis=="vertical"?"height":"width"),10),this.options.axis=="vertical"?"y":"x"):null},_handleIndex:function(){return this.handle.index(this.currentHandle[0])},value:function(D,B){if(this.handle.length==1){this.currentHandle=this.handle}if(!B){B=this.options.axis=="vertical"?"y":"x"}var C=A(D!=undefined&&D!==null?this.handle[D]||D:this.currentHandle);if(C.data("mouse").sliderValue){return parseInt(C.data("mouse").sliderValue[B],10)}else{return parseInt(((parseInt(C.css(B=="x"?"left":"top"),10)/(this.actualSize[B=="x"?"width":"height"]-this._handleSize(D,B)))*this.options.realMax[B])+this.options.min[B],10)}},_convertValue:function(C,B){return this.options.min[B]+(C/(this.actualSize[B=="x"?"width":"height"]-this._handleSize(null,B)))*this.options.realMax[B]},_translateValue:function(C,B){return((C-this.options.min[B])/this.options.realMax[B])*(this.actualSize[B=="x"?"width":"height"]-this._handleSize(null,B))},_translateRange:function(D,B){if(this.rangeElement){if(this.currentHandle[0]==this.handle[0]&&D>=this._translateValue(this.value(1),B)){D=this._translateValue(this.value(1,B)-this._oneStep(B),B)}if(this.currentHandle[0]==this.handle[1]&&D<=this._translateValue(this.value(0),B)){D=this._translateValue(this.value(0,B)+this._oneStep(B),B)}}if(this.options.handles){var C=this.options.handles[this._handleIndex()];if(D<this._translateValue(C.min,B)){D=this._translateValue(C.min,B)}else{if(D>this._translateValue(C.max,B)){D=this._translateValue(C.max,B)}}}return D},_translateLimits:function(C,B){if(C>=this.actualSize[B=="x"?"width":"height"]-this._handleSize(null,B)){C=this.actualSize[B=="x"?"width":"height"]-this._handleSize(null,B)}if(C<=0){C=0}return C},_handleSize:function(C,B){return A(C!=undefined&&C!==null?this.handle[C]:this.currentHandle)[0]["offset"+(B=="x"?"Width":"Height")]},_oneStep:function(B){return this.options.stepping[B]||1},_pageStep:function(B){return 10},_start:function(C,B){var D=this.options;if(D.disabled){return false}this.actualSize={width:this.element.outerWidth(),height:this.element.outerHeight()};if(!this.currentHandle){this._focus(this.previousHandle,true)}this.offset=this.element.offset();this.handleOffset=this.currentHandle.offset();this.clickOffset={top:C.pageY-this.handleOffset.top,left:C.pageX-this.handleOffset.left};this.firstValue=this.value();this._propagate("start",C);this._drag(C,B);return true},_stop:function(B){this._propagate("stop",B);if(this.firstValue!=this.value()){this._propagate("change",B)}this._focus(this.currentHandle,true);return false},_drag:function(E,D){var F=this.options;var B={top:E.pageY-this.offset.top-this.clickOffset.top,left:E.pageX-this.offset.left-this.clickOffset.left};if(!this.currentHandle){this._focus(this.previousHandle,true)}B.left=this._translateLimits(B.left,"x");B.top=this._translateLimits(B.top,"y");if(F.stepping.x){var C=this._convertValue(B.left,"x");C=Math.round(C/F.stepping.x)*F.stepping.x;B.left=this._translateValue(C,"x")}if(F.stepping.y){var C=this._convertValue(B.top,"y");C=Math.round(C/F.stepping.y)*F.stepping.y;B.top=this._translateValue(C,"y")}B.left=this._translateRange(B.left,"x");B.top=this._translateRange(B.top,"y");if(F.axis!="vertical"){this.currentHandle.css({left:B.left})}if(F.axis!="horizontal"){this.currentHandle.css({top:B.top})}this.currentHandle.data("mouse").sliderValue={x:Math.round(this._convertValue(B.left,"x"))||0,y:Math.round(this._convertValue(B.top,"y"))||0};if(this.rangeElement){this._updateRange()}this._propagate("slide",E);return false},moveTo:function(F,E,G){var H=this.options;this.actualSize={width:this.element.outerWidth(),height:this.element.outerHeight()};if(E==undefined&&!this.currentHandle&&this.handle.length!=1){return false}if(E==undefined&&!this.currentHandle){E=0}if(E!=undefined){this.currentHandle=this.previousHandle=A(this.handle[E]||E)}if(F.x!==undefined&&F.y!==undefined){var B=F.x,I=F.y}else{var B=F,I=F}if(B!==undefined&&B.constructor!=Number){var D=/^\-\=/.test(B),C=/^\+\=/.test(B);if(D||C){B=this.value(null,"x")+parseInt(B.replace(D?"=":"+=",""),10)}else{B=isNaN(parseInt(B,10))?undefined:parseInt(B,10)}}if(I!==undefined&&I.constructor!=Number){var D=/^\-\=/.test(I),C=/^\+\=/.test(I);if(D||C){I=this.value(null,"y")+parseInt(I.replace(D?"=":"+=",""),10)}else{I=isNaN(parseInt(I,10))?undefined:parseInt(I,10)}}if(H.axis!="vertical"&&B!==undefined){if(H.stepping.x){B=Math.round(B/H.stepping.x)*H.stepping.x}B=this._translateValue(B,"x");B=this._translateLimits(B,"x");B=this._translateRange(B,"x");H.animate?this.currentHandle.stop().animate({left:B},(Math.abs(parseInt(this.currentHandle.css("left"))-B))*(!isNaN(parseInt(H.animate))?H.animate:5)):this.currentHandle.css({left:B})}if(H.axis!="horizontal"&&I!==undefined){if(H.stepping.y){I=Math.round(I/H.stepping.y)*H.stepping.y}I=this._translateValue(I,"y");I=this._translateLimits(I,"y");I=this._translateRange(I,"y");H.animate?this.currentHandle.stop().animate({top:I},(Math.abs(parseInt(this.currentHandle.css("top"))-I))*(!isNaN(parseInt(H.animate))?H.animate:5)):this.currentHandle.css({top:I})}if(this.rangeElement){this._updateRange()}this.currentHandle.data("mouse").sliderValue={x:Math.round(this._convertValue(B,"x"))||0,y:Math.round(this._convertValue(I,"y"))||0};if(!G){this._propagate("start",null);this._propagate("stop",null);this._propagate("change",null);this._propagate("slide",null)}}});A.ui.slider.getter="value";A.ui.slider.defaults={handle:".ui-slider-handle",distance:1,animate:false}})(jQuery);(function(A){A.widget("ui.spinner",{_init:function(){if(A.data(this.element[0],"spinner")){return }if(this.options.init){this.options.init(this.ui(null))}this._decimals=0;if(this.options.stepping.toString().indexOf(".")!=-1){var C=this.options.stepping.toString();this._decimals=C.slice(C.indexOf(".")+1,C.length).length}var B=this;this.element.addClass("ui-spinner-box").attr("autocomplete","off");this._setValue(isNaN(this._getValue())?this.options.start:this._getValue());this.element.wrap("<div>").parent().addClass("ui-spinner").append('<button class="ui-spinner-up" type="button">&#9650;</button>').find(".ui-spinner-up").bind("mousedown",function(D){A(this).addClass("ui-spinner-pressed");if(!B.counter){B.counter=1}B._mousedown(100,"_up",D)}).bind("mouseup",function(D){A(this).removeClass("ui-spinner-pressed");if(B.counter==1){B._up(D)}B._mouseup(D)}).bind("mouseout",function(D){A(this).removeClass("ui-spinner-pressed");B._mouseup(D)}).bind("dblclick",function(D){A(this).removeClass("ui-spinner-pressed");B._up(D)}).bind("keydown.spinner",function(E){var D=A.keyCode;if(E.keyCode==D.SPACE||E.keyCode==D.ENTER){A(this).addClass("ui-spinner-pressed");if(!B.counter){B.counter=1}B._up.call(B,E)}else{if(E.keyCode==D.DOWN||E.keyCode==D.RIGHT){B.element.siblings(".ui-spinner-down").focus()}else{if(E.keyCode==D.LEFT){B.element.focus()}}}}).bind("keyup.spinner",function(D){A(this).removeClass("ui-spinner-pressed");B.counter=0;B._propagate("change",D)}).end().append('<button class="ui-spinner-down" type="button">&#9660;</button>').find(".ui-spinner-down").bind("mousedown",function(D){A(this).addClass("ui-spinner-pressed");if(!B.counter){B.counter=1}B._mousedown(100,"_down",D)}).bind("mouseup",function(D){A(this).removeClass("ui-spinner-pressed");if(B.counter==1){B._down()}B._mouseup(D)}).bind("mouseout",function(D){A(this).removeClass("ui-spinner-pressed");B._mouseup(D)}).bind("dblclick",function(D){A(this).removeClass("ui-spinner-pressed");B._down(D)}).bind("keydown.spinner",function(E){var D=A.keyCode;if(E.keyCode==D.SPACE||E.keyCode==D.ENTER){A(this).addClass("ui-spinner-pressed");if(!B.counter){B.counter=1}B._down.call(B,E)}else{if(E.keyCode==D.UP||E.keyCode==D.LEFT){B.element.siblings(".ui-spinner-up").focus()}}}).bind("keyup.spinner",function(D){A(this).removeClass("ui-spinner-pressed");B.counter=0;B._propagate("change",D)}).end();this._items=this.element.children().length;if(this._items>1){this.element.addClass("ui-spinner-list").css("height",this.element.outerHeight()/this._items).children().addClass("ui-spinner-listitem").end().parent().css("height",this.element.outerHeight()).end();this.options.stepping=1;this.options.min=0;this.options.max=this._items-1}this.element.bind("keydown.spinner",function(D){if(!B.counter){B.counter=1}return B._keydown.call(B,D)}).bind("keyup.spinner",function(D){B.counter=0;B._propagate("change",D)}).bind("blur.spinner",function(D){B._cleanUp()});if(A.fn.mousewheel){this.element.mousewheel(function(D,E){B._mousewheel(D,E)})}},_constrain:function(){if(this.options.min!=undefined&&this._getValue()<this.options.min){this._setValue(this.options.min)}if(this.options.max!=undefined&&this._getValue()>this.options.max){this._setValue(this.options.max)}},_cleanUp:function(){this._setValue(this._getValue());this._constrain()},_spin:function(C,B){if(this.disabled){return }if(isNaN(this._getValue())){this._setValue(this.options.start)}this._setValue(this._getValue()+(C=="up"?1:-1)*(this.options.incremental&&this.counter>100?(this.counter>200?100:10):1)*this.options.stepping);this._animate(C);this._constrain();if(this.counter){this.counter++}this._propagate("spin",B)},_down:function(B){this._spin("down",B);this._propagate("down",B)},_up:function(B){this._spin("up",B);this._propagate("up",B)},_mousedown:function(C,E,D){var B=this;C=C||100;if(this.timer){window.clearInterval(this.timer)}this.timer=window.setInterval(function(){B[E](D);if(B.counter>20){B._mousedown(20,E,D)}},C)},_mouseup:function(B){this.counter=0;if(this.timer){window.clearInterval(this.timer)}this.element[0].focus();this._propagate("change",B)},_keydown:function(C){var B=A.keyCode;if(C.keyCode==B.UP){this._up(C)}if(C.keyCode==B.DOWN){this._down(C)}if(C.keyCode==B.HOME){this._setValue(this.options.min||this.options.start)}if(C.keyCode==B.END&&this.options.max!=undefined){this._setValue(this.options.max)}return(C.keyCode==B.TAB||C.keyCode==B.BACKSPACE||C.keyCode==B.LEFT||C.keyCode==B.RIGHT||C.keyCode==B.PERIOD||C.keyCode==B.NUMPAD_DECIMAL||C.keyCode==B.NUMPAD_SUBTRACT||(C.keyCode>=96&&C.keyCode<=105)||(/[0-9\-\.]/).test(String.fromCharCode(C.keyCode)))?true:false},_mousewheel:function(B,C){C=(A.browser.opera?-C/Math.abs(C):C);C>0?this._up(B):this._down(B);B.preventDefault()},_getValue:function(){return parseFloat(this.element.val().replace(/[^0-9\-\.]/g,""))},_setValue:function(B){if(isNaN(B)){B=this.options.start}this.element.val(this.options.currency?A.ui.spinner.format.currency(B,this.options.currency):A.ui.spinner.format.number(B,this._decimals))},_animate:function(B){if(this.element.hasClass("ui-spinner-list")&&((B=="up"&&this._getValue()<=this.options.max)||(B=="down"&&this._getValue()>=this.options.min))){this.element.animate({marginTop:"-"+this._getValue()*this.element.outerHeight()},{duration:"fast",queue:false})}},_addItem:function(B){if(!this.element.is("input")){var C="div";if(this.element.is("ol")||this.element.is("ul")){C="li"}this.element.append("<"+C+' class="ui-spinner-dyn">'+B+"</"+C+">")}},plugins:{},ui:function(B){return{options:this.options,element:this.element,value:this._getValue(),add:this._addItem}},_propagate:function(C,B){A.ui.plugin.call(this,C,[B,this.ui()]);return this.element.triggerHandler(C=="spin"?C:"spin"+C,[B,this.ui()],this.options[C])},destroy:function(){if(!A.data(this.element[0],"spinner")){return }if(A.fn.mousewheel){this.element.unmousewheel()}this.element.removeClass("ui-spinner-box ui-spinner-list").removeAttr("disabled").removeAttr("autocomplete").removeData("spinner").unbind(".spinner").siblings().remove().end().children().removeClass("ui-spinner-listitem").remove(".ui-spinner-dyn").end().parent().removeClass("ui-spinner ui-spinner-disabled").before(this.element.clone()).remove().end()},enable:function(){this.element.removeAttr("disabled").siblings().removeAttr("disabled").parent().removeClass("ui-spinner-disabled");this.disabled=false},disable:function(){this.element.attr("disabled",true).siblings().attr("disabled",true).parent().addClass("ui-spinner-disabled");this.disabled=true}});A.extend(A.ui.spinner,{defaults:{stepping:1,start:0,incremental:true,currency:false},format:{number:function(B,C){return this.round(B,C)},currency:function(C,B){return(C!==Math.abs(C)?"-":"")+B+this.round(Math.abs(C),2)},round:function(B,D){var C=Math.round(parseFloat(B)*Math.pow(10,D))/Math.pow(10,D);if(D>0){C=C+((C.toString().indexOf(".")==-1)?".":"")+"0000000001";C=C.substr(0,C.indexOf(".")+1+D)}else{C=Math.round(C)}return C}}})})(jQuery);(function(A){A.widget("ui.tabs",{_init:function(){this.options.event+=".tabs";this._tabify(true)},_setData:function(B,C){if((/^selected/).test(B)){this.select(C)}else{this.options[B]=C;this._tabify()}},length:function(){return this.$tabs.length},_tabId:function(B){return B.title&&B.title.replace(/\s/g,"_").replace(/[^A-Za-z0-9\-_:\.]/g,"")||this.options.idPrefix+A.data(B)},ui:function(C,B){return{options:this.options,tab:C,panel:B,index:this.$tabs.index(C)}},_tabify:function(O){this.$lis=A("li:has(a[href])",this.element);this.$tabs=this.$lis.map(function(){return A("a",this)[0]});this.$panels=A([]);var P=this,D=this.options;this.$tabs.each(function(R,Q){if(Q.hash&&Q.hash.replace("#","")){P.$panels=P.$panels.add(Q.hash)}else{if(A(Q).attr("href")!="#"){A.data(Q,"href.tabs",Q.href);A.data(Q,"load.tabs",Q.href);var T=P._tabId(Q);Q.href="#"+T;var S=A("#"+T);if(!S.length){S=A(D.panelTemplate).attr("id",T).addClass(D.panelClass).insertAfter(P.$panels[R-1]||P.element);S.data("destroy.tabs",true)}P.$panels=P.$panels.add(S)}else{D.disabled.push(R+1)}}});if(O){this.element.addClass(D.navClass);this.$panels.each(function(){var Q=A(this);Q.addClass(D.panelClass)});if(D.selected===undefined){if(location.hash){this.$tabs.each(function(S,Q){if(Q.hash==location.hash){D.selected=S;if(A.browser.msie||A.browser.opera){var R=A(location.hash),T=R.attr("id");R.attr("id","");setTimeout(function(){R.attr("id",T)},500)}scrollTo(0,0);return false}})}else{if(D.cookie){var J=parseInt(A.cookie("ui-tabs-"+A.data(P.element[0])),10);if(J&&P.$tabs[J]){D.selected=J}}else{if(P.$lis.filter("."+D.selectedClass).length){D.selected=P.$lis.index(P.$lis.filter("."+D.selectedClass)[0])}}}}D.selected=D.selected===null||D.selected!==undefined?D.selected:0;D.disabled=A.unique(D.disabled.concat(A.map(this.$lis.filter("."+D.disabledClass),function(R,Q){return P.$lis.index(R)}))).sort();if(A.inArray(D.selected,D.disabled)!=-1){D.disabled.splice(A.inArray(D.selected,D.disabled),1)}this.$panels.addClass(D.hideClass);this.$lis.removeClass(D.selectedClass);if(D.selected!==null){this.$panels.eq(D.selected).show().removeClass(D.hideClass);this.$lis.eq(D.selected).addClass(D.selectedClass);var K=function(){P._trigger("show",null,P.ui(P.$tabs[D.selected],P.$panels[D.selected]))};if(A.data(this.$tabs[D.selected],"load.tabs")){this.load(D.selected,K)}else{K()}}A(window).bind("unload",function(){P.$tabs.unbind(".tabs");P.$lis=P.$tabs=P.$panels=null})}else{D.selected=this.$lis.index(this.$lis.filter("."+D.selectedClass)[0])}if(D.cookie){A.cookie("ui-tabs-"+A.data(P.element[0]),D.selected,D.cookie)}for(var G=0,N;N=this.$lis[G];G++){A(N)[A.inArray(G,D.disabled)!=-1&&!A(N).hasClass(D.selectedClass)?"addClass":"removeClass"](D.disabledClass)}if(D.cache===false){this.$tabs.removeData("cache.tabs")}var C,I,B={"min-width":0,duration:1},E="normal";if(D.fx&&D.fx.constructor==Array){C=D.fx[0]||B,I=D.fx[1]||B}else{C=I=D.fx||B}var H={display:"",overflow:"",height:""};if(!A.browser.msie){H.opacity=""}function M(R,Q,S){Q.animate(C,C.duration||E,function(){Q.addClass(D.hideClass).css(H);if(A.browser.msie&&C.opacity){Q[0].style.filter=""}if(S){L(R,S,Q)}})}function L(R,S,Q){if(I===B){S.css("display","block")}S.animate(I,I.duration||E,function(){S.removeClass(D.hideClass).css(H);if(A.browser.msie&&I.opacity){S[0].style.filter=""}P._trigger("show",null,P.ui(R,S[0]))})}function F(R,T,Q,S){T.addClass(D.selectedClass).siblings().removeClass(D.selectedClass);M(R,Q,S)}this.$tabs.unbind(".tabs").bind(D.event,function(){var T=A(this).parents("li:eq(0)"),Q=P.$panels.filter(":visible"),S=A(this.hash);if((T.hasClass(D.selectedClass)&&!D.unselect)||T.hasClass(D.disabledClass)||A(this).hasClass(D.loadingClass)||P._trigger("select",null,P.ui(this,S[0]))===false){this.blur();return false}P.options.selected=P.$tabs.index(this);if(D.unselect){if(T.hasClass(D.selectedClass)){P.options.selected=null;T.removeClass(D.selectedClass);P.$panels.stop();M(this,Q);this.blur();return false}else{if(!Q.length){P.$panels.stop();var R=this;P.load(P.$tabs.index(this),function(){T.addClass(D.selectedClass).addClass(D.unselectClass);L(R,S)});this.blur();return false}}}if(D.cookie){A.cookie("ui-tabs-"+A.data(P.element[0]),P.options.selected,D.cookie)}P.$panels.stop();if(S.length){var R=this;P.load(P.$tabs.index(this),Q.length?function(){F(R,T,Q,S)}:function(){T.addClass(D.selectedClass);L(R,S)})}else{throw"jQuery UI Tabs: Mismatching fragment identifier."}if(A.browser.msie){this.blur()}return false});if(!(/^click/).test(D.event)){this.$tabs.bind("click.tabs",function(){return false})}},add:function(E,D,C){if(C==undefined){C=this.$tabs.length}var G=this.options;var I=A(G.tabTemplate.replace(/#\{href\}/g,E).replace(/#\{label\}/g,D));I.data("destroy.tabs",true);var H=E.indexOf("#")==0?E.replace("#",""):this._tabId(A("a:first-child",I)[0]);var F=A("#"+H);if(!F.length){F=A(G.panelTemplate).attr("id",H).addClass(G.hideClass).data("destroy.tabs",true)}F.addClass(G.panelClass);if(C>=this.$lis.length){I.appendTo(this.element);F.appendTo(this.element[0].parentNode)}else{I.insertBefore(this.$lis[C]);F.insertBefore(this.$panels[C])}G.disabled=A.map(G.disabled,function(K,J){return K>=C?++K:K});this._tabify();if(this.$tabs.length==1){I.addClass(G.selectedClass);F.removeClass(G.hideClass);var B=A.data(this.$tabs[0],"load.tabs");if(B){this.load(C,B)}}this._trigger("add",null,this.ui(this.$tabs[C],this.$panels[C]))},remove:function(B){var D=this.options,E=this.$lis.eq(B).remove(),C=this.$panels.eq(B).remove();if(E.hasClass(D.selectedClass)&&this.$tabs.length>1){this.select(B+(B+1<this.$tabs.length?1:-1))}D.disabled=A.map(A.grep(D.disabled,function(G,F){return G!=B}),function(G,F){return G>=B?--G:G});this._tabify();this._trigger("remove",null,this.ui(E.find("a")[0],C[0]))},enable:function(B){var C=this.options;if(A.inArray(B,C.disabled)==-1){return }var D=this.$lis.eq(B).removeClass(C.disabledClass);if(A.browser.safari){D.css("display","inline-block");setTimeout(function(){D.css("display","block")},0)}C.disabled=A.grep(C.disabled,function(F,E){return F!=B});this._trigger("enable",null,this.ui(this.$tabs[B],this.$panels[B]))},disable:function(C){var B=this,D=this.options;if(C!=D.selected){this.$lis.eq(C).addClass(D.disabledClass);D.disabled.push(C);D.disabled.sort();this._trigger("disable",null,this.ui(this.$tabs[C],this.$panels[C]))}},select:function(B){if(typeof B=="string"){B=this.$tabs.index(this.$tabs.filter("[href$="+B+"]")[0])}this.$tabs.eq(B).trigger(this.options.event)},load:function(G,K){var L=this,D=this.options,E=this.$tabs.eq(G),J=E[0],H=K==undefined||K===false,B=E.data("load.tabs");K=K||function(){};if(!B||!H&&A.data(J,"cache.tabs")){K();return }var M=function(N){var O=A(N),P=O.find("*:last");return P.length&&P.is(":not(img)")&&P||O};var C=function(){L.$tabs.filter("."+D.loadingClass).removeClass(D.loadingClass).each(function(){if(D.spinner){M(this).parent().html(M(this).data("label.tabs"))}});L.xhr=null};if(D.spinner){var I=M(J).html();M(J).wrapInner("<em></em>").find("em").data("label.tabs",I).html(D.spinner)}var F=A.extend({},D.ajaxOptions,{url:B,success:function(O,N){A(J.hash).html(O);C();if(D.cache){A.data(J,"cache.tabs",true)}L._trigger("load",null,L.ui(L.$tabs[G],L.$panels[G]));D.ajaxOptions.success&&D.ajaxOptions.success(O,N);K()}});if(this.xhr){this.xhr.abort();C()}E.addClass(D.loadingClass);setTimeout(function(){L.xhr=A.ajax(F)},0)},url:function(C,B){this.$tabs.eq(C).removeData("cache.tabs").data("load.tabs",B)},destroy:function(){var B=this.options;this.element.unbind(".tabs").removeClass(B.navClass).removeData("tabs");this.$tabs.each(function(){var C=A.data(this,"href.tabs");if(C){this.href=C}var D=A(this).unbind(".tabs");A.each(["href","load","cache"],function(E,F){D.removeData(F+".tabs")})});this.$lis.add(this.$panels).each(function(){if(A.data(this,"destroy.tabs")){A(this).remove()}else{A(this).removeClass([B.selectedClass,B.unselectClass,B.disabledClass,B.panelClass,B.hideClass].join(" "))}})}});A.ui.tabs.defaults={unselect:false,event:"click",disabled:[],cookie:null,spinner:"Loading&#8230;",cache:false,idPrefix:"ui-tabs-",ajaxOptions:{},fx:null,tabTemplate:'<li><a href="#{href}"><span>#{label}</span></a></li>',panelTemplate:"<div></div>",navClass:"ui-tabs-nav",selectedClass:"ui-tabs-selected",unselectClass:"ui-tabs-unselect",disabledClass:"ui-tabs-disabled",panelClass:"ui-tabs-panel",hideClass:"ui-tabs-hide",loadingClass:"ui-tabs-loading"};A.ui.tabs.getter="length";A.extend(A.ui.tabs.prototype,{rotation:null,rotate:function(C,F){F=F||false;var B=this,E=this.options.selected;function G(){B.rotation=setInterval(function(){E=++E<B.$tabs.length?E:0;B.select(E)},C)}function D(H){if(!H||H.clientX){clearInterval(B.rotation)}}if(C){G();if(!F){this.$tabs.bind(this.options.event,D)}else{this.$tabs.bind(this.options.event,function(){D();E=B.options.selected;G()})}}else{D();this.$tabs.unbind(this.options.event,D)}}})})(jQuery) \ No newline at end of file
diff --git a/site/app/webroot/js/jquery-ui/ui.accordion.min.js b/site/app/webroot/js/jquery-ui/ui.accordion.min.js
new file mode 100755
index 0000000..483ae10
--- /dev/null
+++ b/site/app/webroot/js/jquery-ui/ui.accordion.min.js
@@ -0,0 +1 @@
+(function(E){E.widget("ui.accordion",{_init:function(){var G=this.options;if(G.navigation){var J=this.element.find("a").filter(G.navigationFilter);if(J.length){if(J.filter(G.header).length){G.active=J}else{G.active=J.parent().parent().prev();J.addClass("current")}}}G.headers=this.element.find(G.header);G.active=C(G.headers,G.active);if(E.browser.msie){this.element.find("a").css("zoom","1")}if(!this.element.hasClass("ui-accordion")){this.element.addClass("ui-accordion");E('<span class="ui-accordion-left"/>').insertBefore(G.headers);E('<span class="ui-accordion-right"/>').appendTo(G.headers);G.headers.addClass("ui-accordion-header").attr("tabindex","0")}var I;if(G.fillSpace){I=this.element.parent().height();G.headers.each(function(){I-=E(this).outerHeight()});var H=0;G.headers.next().each(function(){H=Math.max(H,E(this).innerHeight()-E(this).height())}).height(I-H)}else{if(G.autoHeight){I=0;G.headers.next().each(function(){I=Math.max(I,E(this).outerHeight())}).height(I)}}G.headers.not(G.active||"").next().hide();G.active.parent().andSelf().addClass(G.selectedClass);if(G.event){this.element.bind((G.event)+".accordion",F)}},activate:function(G){F.call(this.element[0],{target:C(this.options.headers,G)[0]})},destroy:function(){this.options.headers.next().css("display","");if(this.options.fillSpace||this.options.autoHeight){this.options.headers.next().css("height","")}E.removeData(this.element[0],"accordion");this.element.removeClass("ui-accordion").unbind(".accordion")}});function B(H,G){return function(){return H.apply(G,arguments)}}function D(I){if(!E.data(this,"accordion")){return }var G=E.data(this,"accordion");var H=G.options;H.running=I?0:--H.running;if(H.running){return }if(H.clearStyle){H.toShow.add(H.toHide).css({height:"",overflow:""})}G._trigger("change",null,H.data)}function A(G,K,L,J,M){var I=E.data(this,"accordion").options;I.toShow=G;I.toHide=K;I.data=L;var H=B(D,this);E.data(this,"accordion")._trigger("changestart",null,I.data);I.running=K.size()===0?G.size():K.size();if(I.animated){if(!I.alwaysOpen&&J){E.ui.accordion.animations[I.animated]({toShow:jQuery([]),toHide:K,complete:H,down:M,autoHeight:I.autoHeight})}else{E.ui.accordion.animations[I.animated]({toShow:G,toHide:K,complete:H,down:M,autoHeight:I.autoHeight})}}else{if(!I.alwaysOpen&&J){G.toggle()}else{K.hide();G.show()}H(true)}}function F(L){var J=E.data(this,"accordion").options;if(J.disabled){return false}if(!L.target&&!J.alwaysOpen){J.active.parent().andSelf().toggleClass(J.selectedClass);var I=J.active.next(),M={options:J,newHeader:jQuery([]),oldHeader:J.active,newContent:jQuery([]),oldContent:I},G=(J.active=E([]));A.call(this,G,I,M);return false}var K=E(L.target);K=E(K.parents(J.header)[0]||K);var H=K[0]==J.active[0];if(J.running||(J.alwaysOpen&&H)){return false}if(!K.is(J.header)){return }J.active.parent().andSelf().toggleClass(J.selectedClass);if(!H){K.parent().andSelf().addClass(J.selectedClass)}var G=K.next(),I=J.active.next(),M={options:J,newHeader:H&&!J.alwaysOpen?E([]):K,oldHeader:J.active,newContent:H&&!J.alwaysOpen?E([]):G,oldContent:I},N=J.headers.index(J.active[0])>J.headers.index(K[0]);J.active=H?E([]):K;A.call(this,G,I,M,H,N);return false}function C(H,G){return G?typeof G=="number"?H.filter(":eq("+G+")"):H.not(H.not(G)):G===false?E([]):H.filter(":eq(0)")}E.extend(E.ui.accordion,{defaults:{selectedClass:"selected",alwaysOpen:true,animated:"slide",event:"click",header:"a",autoHeight:true,running:0,navigationFilter:function(){return this.href.toLowerCase()==location.href.toLowerCase()}},animations:{slide:function(G,I){G=E.extend({easing:"swing",duration:300},G,I);if(!G.toHide.size()){G.toShow.animate({height:"show"},G);return }var H=G.toHide.height(),J=G.toShow.height(),K=J/H;G.toShow.css({height:0,overflow:"hidden"}).show();G.toHide.filter(":hidden").each(G.complete).end().filter(":visible").animate({height:"hide"},{step:function(L){var M=(H-L)*K;if(E.browser.msie||E.browser.opera){M=Math.ceil(M)}G.toShow.height(M)},duration:G.duration,easing:G.easing,complete:function(){if(!G.autoHeight){G.toShow.css("height","auto")}G.complete()}})},bounceslide:function(G){this.slide(G,{easing:G.down?"bounceout":"swing",duration:G.down?1000:200})},easeslide:function(G){this.slide(G,{easing:"easeinout",duration:700})}}})})(jQuery) \ No newline at end of file
diff --git a/site/app/webroot/js/jquery-ui/ui.autocomplete.min.js b/site/app/webroot/js/jquery-ui/ui.autocomplete.min.js
new file mode 100755
index 0000000..6c44d36
--- /dev/null
+++ b/site/app/webroot/js/jquery-ui/ui.autocomplete.min.js
@@ -0,0 +1 @@
+(function(A){A.widget("ui.autocomplete",{_init:function(){A.extend(this.options,{delay:this.options.url?A.Autocompleter.defaults.delay:10,max:!this.options.scroll?10:150,highlight:this.options.highlight||function(B){return B},formatMatch:this.options.formatMatch||this.options.formatItem});new A.Autocompleter(this.element[0],this.options)},result:function(B){return this.element.bind("result",B)},search:function(B){return this.element.trigger("search",[B])},flushCache:function(){return this.element.trigger("flushCache")},setData:function(B,C){return this.element.trigger("setOptions",[{key:C}])},destroy:function(){return this.element.trigger("unautocomplete")}});A.Autocompleter=function(L,G){var C={UP:38,DOWN:40,DEL:46,TAB:9,RETURN:13,ESC:27,COMMA:188,PAGEUP:33,PAGEDOWN:34,BACKSPACE:8};var B=A(L).attr("autocomplete","off").addClass(G.inputClass);if(G.result){B.bind("result.autocomplete",G.result)}var J;var P="";var M=A.Autocompleter.Cache(G);var E=0;var U;var X={mouseDownOnSelect:false};var R=A.Autocompleter.Select(G,L,D,X);var W;A.browser.opera&&A(L.form).bind("submit.autocomplete",function(){if(W){W=false;return false}});B.bind((A.browser.opera?"keypress":"keydown")+".autocomplete",function(Y){U=Y.keyCode;switch(Y.keyCode){case C.UP:Y.preventDefault();if(R.visible()){R.prev()}else{T(0,true)}break;case C.DOWN:Y.preventDefault();if(R.visible()){R.next()}else{T(0,true)}break;case C.PAGEUP:Y.preventDefault();if(R.visible()){R.pageUp()}else{T(0,true)}break;case C.PAGEDOWN:Y.preventDefault();if(R.visible()){R.pageDown()}else{T(0,true)}break;case G.multiple&&A.trim(G.multipleSeparator)==","&&C.COMMA:case C.TAB:case C.RETURN:if(D()){Y.preventDefault();W=true;return false}break;case C.ESC:R.hide();break;default:clearTimeout(J);J=setTimeout(T,G.delay);break}}).focus(function(){E++}).blur(function(){E=0;if(!X.mouseDownOnSelect){S()}}).click(function(){if(E++>1&&!R.visible()){T(0,true)}}).bind("search",function(){var Y=(arguments.length>1)?arguments[1]:null;function Z(d,c){var a;if(c&&c.length){for(var b=0;b<c.length;b++){if(c[b].result.toLowerCase()==d.toLowerCase()){a=c[b];break}}}if(typeof Y=="function"){Y(a)}else{B.trigger("result",a&&[a.data,a.value])}}A.each(H(B.val()),function(a,b){F(b,Z,Z)})}).bind("flushCache",function(){M.flush()}).bind("setOptions",function(){A.extend(G,arguments[1]);if("data" in arguments[1]){M.populate()}}).bind("unautocomplete",function(){R.unbind();B.unbind();A(L.form).unbind(".autocomplete")});function D(){var Z=R.selected();if(!Z){return false}var Y=Z.result;P=Y;if(G.multiple){var a=H(B.val());if(a.length>1){Y=a.slice(0,a.length-1).join(G.multipleSeparator)+G.multipleSeparator+Y}Y+=G.multipleSeparator}B.val(Y);V();B.trigger("result",[Z.data,Z.value]);return true}function T(a,Z){if(U==C.DEL){R.hide();return }var Y=B.val();if(!Z&&Y==P){return }P=Y;Y=I(Y);if(Y.length>=G.minChars){B.addClass(G.loadingClass);if(!G.matchCase){Y=Y.toLowerCase()}F(Y,K,V)}else{N();R.hide()}}function H(Z){if(!Z){return[""]}var a=Z.split(G.multipleSeparator);var Y=[];A.each(a,function(b,c){if(A.trim(c)){Y[b]=A.trim(c)}});return Y}function I(Y){if(!G.multiple){return Y}var Z=H(Y);return Z[Z.length-1]}function Q(Y,Z){if(G.autoFill&&(I(B.val()).toLowerCase()==Y.toLowerCase())&&U!=C.BACKSPACE){B.val(B.val()+Z.substring(I(P).length));A.Autocompleter.Selection(L,P.length,P.length+Z.length)}}function S(){clearTimeout(J);J=setTimeout(V,200)}function V(){var Y=R.visible();R.hide();clearTimeout(J);N();if(G.mustMatch){B.autocomplete("search",function(Z){if(!Z){if(G.multiple){var a=H(B.val()).slice(0,-1);B.val(a.join(G.multipleSeparator)+(a.length?G.multipleSeparator:""))}else{B.val("")}}})}if(Y){A.Autocompleter.Selection(L,L.value.length,L.value.length)}}function K(Z,Y){if(Y&&Y.length&&E){N();R.display(Y,Z);Q(Z,Y[0].value);R.show()}else{V()}}function F(b,d,a){if(!G.matchCase){b=b.toLowerCase()}var c=M.load(b);if(c&&c.length){d(b,c)}else{if((typeof G.url=="string")&&(G.url.length>0)){var e={timestamp:+new Date()};A.each(G.extraParams,function(f,g){e[f]=typeof g=="function"?g():g});A.ajax({mode:"abort",port:"autocomplete"+L.name,dataType:G.dataType,url:G.url,data:A.extend({q:I(b),limit:G.max},e),success:function(g){var f=G.parse&&G.parse(g)||O(g);M.add(b,f);d(b,f)}})}else{if(G.source&&typeof G.source=="function"){var Z=G.source(b);var Y=(G.parse)?G.parse(Z):Z;M.add(b,Y);d(b,Y)}else{R.emptyList();a(b)}}}}function O(b){var Y=[];var a=b.split("\n");for(var Z=0;Z<a.length;Z++){var c=A.trim(a[Z]);if(c){c=c.split("|");Y[Y.length]={data:c,value:c[0],result:G.formatResult&&G.formatResult(c,c[0])||c[0]}}}return Y}function N(){B.removeClass(G.loadingClass)}};A.Autocompleter.defaults={inputClass:"ui-autocomplete-input",resultsClass:"ui-autocomplete-results",loadingClass:"ui-autocomplete-loading",minChars:1,delay:400,matchCase:false,matchSubset:true,matchContains:false,cacheLength:10,max:100,mustMatch:false,extraParams:{},selectFirst:true,formatItem:function(B){return B[0]},formatMatch:null,autoFill:false,width:0,multiple:false,multipleSeparator:", ",highlight:function(C,B){return C.replace(new RegExp("(?![^&;]+;)(?!<[^<>]*)("+B.replace(/([\^\$\(\)\[\]\{\}\*\.\+\?\|\\])/gi,"\\$1")+")(?![^<>]*>)(?![^&;]+;)","gi"),"<strong>$1</strong>")},scroll:true,scrollHeight:180};A.extend(A.ui.autocomplete,{defaults:A.Autocompleter.defaults});A.Autocompleter.Cache=function(C){var F={};var D=0;function H(K,J){if(!C.matchCase){K=K.toLowerCase()}var I=K.indexOf(J);if(I==-1){return false}return I==0||C.matchContains}function G(J,I){if(D>C.cacheLength){B()}if(!F[J]){D++}F[J]=I}function E(){if(!C.data){return false}var J={},I=0;if(!C.url){C.cacheLength=1}J[""]=[];for(var L=0,K=C.data.length;L<K;L++){var O=C.data[L];O=(typeof O=="string")?[O]:O;var N=C.formatMatch(O,L+1,C.data.length);if(N===false){continue}var M=N.charAt(0).toLowerCase();if(!J[M]){J[M]=[]}var P={value:N,data:O,result:C.formatResult&&C.formatResult(O)||N};J[M].push(P);if(I++<C.max){J[""].push(P)}}A.each(J,function(Q,R){C.cacheLength++;G(Q,R)})}setTimeout(E,25);function B(){F={};D=0}return{flush:B,add:G,populate:E,load:function(L){if(!C.cacheLength||!D){return null}if(!C.url&&C.matchContains){var K=[];for(var I in F){if(I.length>0){var M=F[I];A.each(M,function(O,N){if(H(N.value,L)){K.push(N)}})}}return K}else{if(F[L]){return F[L]}else{if(C.matchSubset){for(var J=L.length-1;J>=C.minChars;J--){var M=F[L.substr(0,J)];if(M){var K=[];A.each(M,function(O,N){if(H(N.value,L)){K[K.length]=N}});return K}}}}}return null}}};A.Autocompleter.Select=function(E,J,L,P){var I={ACTIVE:"ui-autocomplete-over"};var K,F=-1,R,M="",S=true,C,O;function N(){if(!S){return }C=A("<div/>").hide().addClass(E.resultsClass).css("position","absolute").appendTo(document.body);O=A("<ul/>").appendTo(C).mouseover(function(T){if(Q(T).nodeName&&Q(T).nodeName.toUpperCase()=="LI"){F=A("li",O).removeClass(I.ACTIVE).index(Q(T));A(Q(T)).addClass(I.ACTIVE)}}).click(function(T){A(Q(T)).addClass(I.ACTIVE);L();J.focus();return false}).mousedown(function(){P.mouseDownOnSelect=true}).mouseup(function(){P.mouseDownOnSelect=false});if(E.width>0){C.css("width",E.width)}S=false}function Q(U){var T=U.target;while(T&&T.tagName!="LI"){T=T.parentNode}if(!T){return[]}return T}function H(T){K.slice(F,F+1).removeClass(I.ACTIVE);G(T);var V=K.slice(F,F+1).addClass(I.ACTIVE);if(E.scroll){var U=0;K.slice(0,F).each(function(){U+=this.offsetHeight});if((U+V[0].offsetHeight-O.scrollTop())>O[0].clientHeight){O.scrollTop(U+V[0].offsetHeight-O.innerHeight())}else{if(U<O.scrollTop()){O.scrollTop(U)}}}}function G(T){F+=T;if(F<0){F=K.size()-1}else{if(F>=K.size()){F=0}}}function B(T){return E.max&&E.max<T?E.max:T}function D(){O.empty();var U=B(R.length);for(var V=0;V<U;V++){if(!R[V]){continue}var W=E.formatItem(R[V].data,V+1,U,R[V].value,M);if(W===false){continue}var T=A("<li/>").html(E.highlight(W,M)).addClass(V%2==0?"ui-autocomplete-even":"ui-autocomplete-odd").appendTo(O)[0];A.data(T,"ui-autocomplete-data",R[V])}K=O.find("li");if(E.selectFirst){K.slice(0,1).addClass(I.ACTIVE);F=0}if(A.fn.bgiframe){O.bgiframe()}}return{display:function(U,T){N();R=U;M=T;D()},next:function(){H(1)},prev:function(){H(-1)},pageUp:function(){if(F!=0&&F-8<0){H(-F)}else{H(-8)}},pageDown:function(){if(F!=K.size()-1&&F+8>K.size()){H(K.size()-1-F)}else{H(8)}},hide:function(){C&&C.hide();K&&K.removeClass(I.ACTIVE);F=-1;A(J).triggerHandler("autocompletehide",[{},{options:E}],E["hide"])},visible:function(){return C&&C.is(":visible")},current:function(){return this.visible()&&(K.filter("."+I.ACTIVE)[0]||E.selectFirst&&K[0])},show:function(){var V=A(J).offset();C.css({width:typeof E.width=="string"||E.width>0?E.width:A(J).width(),top:V.top+J.offsetHeight,left:V.left}).show();if(E.scroll){O.scrollTop(0);O.css({maxHeight:E.scrollHeight,overflow:"auto"});if(A.browser.msie&&typeof document.body.style.maxHeight==="undefined"){var T=0;K.each(function(){T+=this.offsetHeight});var U=T>E.scrollHeight;O.css("height",U?E.scrollHeight:T);if(!U){K.width(O.width()-parseInt(K.css("padding-left"))-parseInt(K.css("padding-right")))}}}A(J).triggerHandler("autocompleteshow",[{},{options:E}],E["show"])},selected:function(){var T=K&&K.filter("."+I.ACTIVE).removeClass(I.ACTIVE);return T&&T.length&&A.data(T[0],"ui-autocomplete-data")},emptyList:function(){O&&O.empty()},unbind:function(){C&&C.remove()}}};A.Autocompleter.Selection=function(D,E,C){if(D.createTextRange){var B=D.createTextRange();B.collapse(true);B.moveStart("character",E);B.moveEnd("character",C);B.select()}else{if(D.setSelectionRange){D.setSelectionRange(E,C)}else{if(D.selectionStart){D.selectionStart=E;D.selectionEnd=C}}}D.focus()}})(jQuery) \ No newline at end of file
diff --git a/site/app/webroot/js/jquery-ui/ui.colorpicker.min.js b/site/app/webroot/js/jquery-ui/ui.colorpicker.min.js
new file mode 100755
index 0000000..5edd61b
--- /dev/null
+++ b/site/app/webroot/js/jquery-ui/ui.colorpicker.min.js
@@ -0,0 +1 @@
+(function(A){A.widget("ui.colorpicker",{_init:function(){this.charMin=65;var D=this.options,B=this,C='<div class="ui-colorpicker clearfix"><div class="ui-colorpicker-color"><div><div></div></div></div><div class="ui-colorpicker-hue"><div></div></div><div class="ui-colorpicker-new-color"></div><div class="ui-colorpicker-current-color"></div><div class="ui-colorpicker-hex"><label for="ui-colorpicker-hex" title="hex"></label><input type="text" maxlength="6" size="6" /></div><div class="ui-colorpicker-rgb-r ui-colorpicker-field"><label for="ui-colorpicker-rgb-r"></label><input type="text" maxlength="3" size="2" /><span></span></div><div class="ui-colorpicker-rgb-g ui-colorpicker-field"><label for="ui-colorpicker-rgb-g"></label><input type="text" maxlength="3" size="2" /><span></span></div><div class="ui-colorpicker-rgb-b ui-colorpicker-field"><label for="ui-colorpicker-rgb-b"</label><input type="text" maxlength="3" size="2" /><span></span></div><div class="ui-colorpicker-hsb-h ui-colorpicker-field"><label for="ui-colorpicker-hsb-h"></label><input type="text" maxlength="3" size="2" /><span></span></div><div class="ui-colorpicker-hsb-s ui-colorpicker-field"><label for="ui-colorpicker-hsb-s"></label><input type="text" maxlength="3" size="2" /><span></span></div><div class="ui-colorpicker-hsb-b ui-colorpicker-field"><label for="ui-colorpicker-hsb-b"></label><input type="text" maxlength="3" size="2" /><span></span></div><button class="ui-colorpicker-submit ui-default-state" name="submit" type="button">Done</button></div>';if(typeof D.color=="string"){this.color=this._HexToHSB(D.color)}else{if(D.color.r!=undefined&&D.color.g!=undefined&&D.color.b!=undefined){this.color=this._RGBToHSB(D.color)}else{if(D.color.h!=undefined&&D.color.s!=undefined&&D.color.b!=undefined){this.color=this._fixHSB(D.color)}else{return this}}}this.origColor=this.color;this.picker=A(C);if(D.flat){this.picker.appendTo(this.element).show()}else{this.picker.appendTo(document.body)}this.fields=this.picker.find("input").bind("keydown",function(E){return B._keyDown.call(B,E)}).bind("change",function(E){return B._change.call(B,E)}).bind("blur",function(E){return B._blur.call(B,E)}).bind("focus",function(E){return B._focus.call(B,E)});this.picker.find("span").bind("mousedown",function(E){return B._downIncrement.call(B,E)});this.selector=this.picker.find("div.ui-colorpicker-color").bind("mousedown",function(E){return B._downSelector.call(B,E)});this.selectorIndic=this.selector.find("div div");this.hue=this.picker.find("div.ui-colorpicker-hue div");this.picker.find("div.ui-colorpicker-hue").bind("mousedown",function(E){return B._downHue.call(B,E)});this.newColor=this.picker.find("div.ui-colorpicker-new-color");this.currentColor=this.picker.find("div.ui-colorpicker-current-color");this.picker.find(".ui-colorpicker-submit").bind("mouseenter",function(E){return B._enterSubmit.call(B,E)}).bind("mouseleave",function(E){return B._leaveSubmit.call(B,E)}).bind("click",function(E){return B._clickSubmit.call(B,E)});this._fillRGBFields(this.color);this._fillHSBFields(this.color);this._fillHexFields(this.color);this._setHue(this.color);this._setSelector(this.color);this._setCurrentColor(this.color);this._setNewColor(this.color);if(D.flat){this.picker.css({position:"relative",display:"block"})}else{A(this.element).bind(D.eventName+".colorpicker",function(E){return B._show.call(B,E)})}},destroy:function(){this.picker.remove();this.element.removeData("colorpicker").unbind(".colorpicker")},_fillRGBFields:function(B){var C=this._HSBToRGB(B);this.fields.eq(1).val(C.r).end().eq(2).val(C.g).end().eq(3).val(C.b).end()},_fillHSBFields:function(B){this.fields.eq(4).val(B.h).end().eq(5).val(B.s).end().eq(6).val(B.b).end()},_fillHexFields:function(B){this.fields.eq(0).val(this._HSBToHex(B)).end()},_setSelector:function(B){this.selector.css("backgroundColor","#"+this._HSBToHex({h:B.h,s:100,b:100}));this.selectorIndic.css({left:parseInt(150*B.s/100,10),top:parseInt(150*(100-B.b)/100,10)})},_setHue:function(B){this.hue.css("top",parseInt(150-150*B.h/360,10))},_setCurrentColor:function(B){this.currentColor.css("backgroundColor","#"+this._HSBToHex(B))},_setNewColor:function(B){this.newColor.css("backgroundColor","#"+this._HSBToHex(B))},_keyDown:function(B){var C=B.charCode||B.keyCode||-1;if((C>=this.charMin&&C<=90)||C==32){return false}},_change:function(D,C){var B;C=C||D.target;if(C.parentNode.className.indexOf("-hex")>0){this.color=B=this._HexToHSB(this.value);this._fillRGBFields(B.color);this._fillHSBFields(B)}else{if(C.parentNode.className.indexOf("-hsb")>0){this.color=B=this._fixHSB({h:parseInt(this.fields.eq(4).val(),10),s:parseInt(this.fields.eq(5).val(),10),b:parseInt(this.fields.eq(6).val(),10)});this._fillRGBFields(B);this._fillHexFields(B)}else{this.color=B=this._RGBToHSB(this._fixRGB({r:parseInt(this.fields.eq(1).val(),10),g:parseInt(this.fields.eq(2).val(),10),b:parseInt(this.fields.eq(3).val(),10)}));this._fillHexFields(B);this._fillHSBFields(B)}}this._setSelector(B);this._setHue(B);this._setNewColor(B);this._trigger("change",D,{options:this.options,hsb:B,hex:this._HSBToHex(B),rgb:this._HSBToRGB(B)})},_blur:function(C){var B=this.color;this._fillRGBFields(B);this._fillHSBFields(B);this._fillHexFields(B);this._setHue(B);this._setSelector(B);this._setNewColor(B);this.fields.parent().removeClass("ui-colorpicker-focus")},_focus:function(B){this.charMin=B.target.parentNode.className.indexOf("-hex")>0?70:65;this.fields.parent().removeClass("ui-colorpicker-focus");A(B.target.parentNode).addClass("ui-colorpicker-focus")},_downIncrement:function(D){var C=A(D.target).parent().find("input").focus(),B=this;this.currentIncrement={el:A(D.target).parent().addClass("ui-colorpicker-slider"),max:D.target.parentNode.className.indexOf("-hsb-h")>0?360:(D.target.parentNode.className.indexOf("-hsb")>0?100:255),y:D.pageY,field:C,val:parseInt(C.val(),10)};A(document).bind("mouseup.cpSlider",function(E){return B._upIncrement.call(B,E)});A(document).bind("mousemove.cpSlider",function(E){return B._moveIncrement.call(B,E)});return false},_moveIncrement:function(B){this.currentIncrement.field.val(Math.max(0,Math.min(this.currentIncrement.max,parseInt(this.currentIncrement.val+B.pageY-this.currentIncrement.y,10))));this._change.apply(this,[B,this.currentIncrement.field.get(0)]);return false},_upIncrement:function(B){this.currentIncrement.el.removeClass("ui-colorpicker-slider").find("input").focus();this._change.apply(this,[B,this.currentIncrement.field.get(0)]);A(document).unbind("mouseup.cpSlider");A(document).unbind("mousemove.cpSlider");return false},_downHue:function(C){this.currentHue={y:this.picker.find("div.ui-colorpicker-hue").offset().top};this._change.apply(this,[C,this.fields.eq(4).val(parseInt(360*(150-Math.max(0,Math.min(150,(C.pageY-this.currentHue.y))))/150,10)).get(0)]);var B=this;A(document).bind("mouseup.cpSlider",function(D){return B._upHue.call(B,D)});A(document).bind("mousemove.cpSlider",function(D){return B._moveHue.call(B,D)});return false},_moveHue:function(B){this._change.apply(this,[B,this.fields.eq(4).val(parseInt(360*(150-Math.max(0,Math.min(150,(B.pageY-this.currentHue.y))))/150,10)).get(0)]);return false},_upHue:function(B){A(document).unbind("mouseup.cpSlider");A(document).unbind("mousemove.cpSlider");return false},_downSelector:function(C){var B=this;this.currentSelector={pos:this.picker.find("div.ui-colorpicker-color").offset()};this._change.apply(this,[C,this.fields.eq(6).val(parseInt(100*(150-Math.max(0,Math.min(150,(C.pageY-this.currentSelector.pos.top))))/150,10)).end().eq(5).val(parseInt(100*(Math.max(0,Math.min(150,(C.pageX-this.currentSelector.pos.left))))/150,10)).get(0)]);A(document).bind("mouseup.cpSlider",function(D){return B._upSelector.call(B,D)});A(document).bind("mousemove.cpSlider",function(D){return B._moveSelector.call(B,D)});return false},_moveSelector:function(B){this._change.apply(this,[B,this.fields.eq(6).val(parseInt(100*(150-Math.max(0,Math.min(150,(B.pageY-this.currentSelector.pos.top))))/150,10)).end().eq(5).val(parseInt(100*(Math.max(0,Math.min(150,(B.pageX-this.currentSelector.pos.left))))/150,10)).get(0)]);return false},_upSelector:function(B){A(document).unbind("mouseup.cpSlider");A(document).unbind("mousemove.cpSlider");return false},_enterSubmit:function(B){this.picker.find(".ui-colorpicker-submit").addClass("ui-colorpicker-focus")},_leaveSubmit:function(B){this.picker.find(".ui-colorpicker-submit").removeClass("ui-colorpicker-focus")},_clickSubmit:function(C){var B=this.color;this.origColor=B;this._setCurrentColor(B);this._trigger("submit",C,{options:this.options,hsb:B,hex:this._HSBToHex(B),rgb:this._HSBToRGB(B)});return false},_show:function(F){this._trigger("beforeShow",F,{options:this.options,hsb:this.color,hex:this._HSBToHex(this.color),rgb:this._HSBToRGB(this.color)});var G=this.element.offset();var E=this._getScroll();var D=G.top+this.element[0].offsetHeight;var C=G.left;if(D+176>E.t+Math.min(E.h,E.ih)){D-=this.element[0].offsetHeight+176}if(C+356>E.l+Math.min(E.w,E.iw)){C-=356}this.picker.css({left:C+"px",top:D+"px"});if(this._trigger("show",F,{options:this.options,hsb:this.color,hex:this._HSBToHex(this.color),rgb:this._HSBToRGB(this.color)})!=false){this.picker.show()}var B=this;A(document).bind("mousedown.colorpicker",function(H){return B._hide.call(B,H)});return false},_hide:function(B){if(!this._isChildOf(this.picker[0],B.target,this.picker[0])){if(this._trigger("hide",B,{options:this.options,hsb:this.color,hex:this._HSBToHex(this.color),rgb:this._HSBToRGB(this.color)})!=false){this.picker.hide()}A(document).unbind("mousedown.colorpicker")}},_isChildOf:function(D,C,B){if(D==C){return true}if(D.contains&&!A.browser.safari){return D.contains(C)}if(D.compareDocumentPosition){return !!(D.compareDocumentPosition(C)&16)}var E=C.parentNode;while(E&&E!=B){if(E==D){return true}E=E.parentNode}return false},_getScroll:function(){var E,C,B,F,D,G;if(document.documentElement){E=document.documentElement.scrollTop;C=document.documentElement.scrollLeft;B=document.documentElement.scrollWidth;F=document.documentElement.scrollHeight}else{E=document.body.scrollTop;C=document.body.scrollLeft;B=document.body.scrollWidth;F=document.body.scrollHeight}D=self.innerWidth||document.documentElement.clientWidth||document.body.clientWidth||0;G=self.innerHeight||document.documentElement.clientHeight||document.body.clientHeight||0;return{t:E,l:C,w:B,h:F,iw:D,ih:G}},_fixHSB:function(B){return{h:Math.min(360,Math.max(0,B.h)),s:Math.min(100,Math.max(0,B.s)),b:Math.min(100,Math.max(0,B.b))}},_fixRGB:function(B){return{r:Math.min(255,Math.max(0,B.r)),g:Math.min(255,Math.max(0,B.g)),b:Math.min(255,Math.max(0,B.b))}},_HexToRGB:function(B){var B=parseInt(((B.indexOf("#")>-1)?B.substring(1):B),16);return{r:B>>16,g:(B&65280)>>8,b:(B&255)}},_HexToHSB:function(B){return this._RGBToHSB(this._HexToRGB(B))},_RGBToHSB:function(C){var B={};B.b=Math.max(Math.max(C.r,C.g),C.b);B.s=(B.b<=0)?0:Math.round(100*(B.b-Math.min(Math.min(C.r,C.g),C.b))/B.b);B.b=Math.round((B.b/255)*100);if((C.r==C.g)&&(C.g==C.b)){B.h=0}else{if(C.r>=C.g&&C.g>=C.b){B.h=60*(C.g-C.b)/(C.r-C.b)}else{if(C.g>=C.r&&C.r>=C.b){B.h=60+60*(C.g-C.r)/(C.g-C.b)}else{if(C.g>=C.b&&C.b>=C.r){B.h=120+60*(C.b-C.r)/(C.g-C.r)}else{if(C.b>=C.g&&C.g>=C.r){B.h=180+60*(C.b-C.g)/(C.b-C.r)}else{if(C.b>=C.r&&C.r>=C.g){B.h=240+60*(C.r-C.g)/(C.b-C.g)}else{if(C.r>=C.b&&C.b>=C.g){B.h=300+60*(C.r-C.b)/(C.r-C.g)}else{B.h=0}}}}}}}B.h=Math.round(B.h);return B},_HSBToRGB:function(B){var D={};var H=Math.round(B.h);var G=Math.round(B.s*255/100);var C=Math.round(B.b*255/100);if(G==0){D.r=D.g=D.b=C}else{var I=C;var F=(255-G)*C/255;var E=(I-F)*(H%60)/60;if(H==360){H=0}if(H<60){D.r=I;D.b=F;D.g=F+E}else{if(H<120){D.g=I;D.b=F;D.r=I-E}else{if(H<180){D.g=I;D.r=F;D.b=F+E}else{if(H<240){D.b=I;D.r=F;D.g=I-E}else{if(H<300){D.b=I;D.g=F;D.r=F+E}else{if(H<360){D.r=I;D.g=F;D.b=I-E}else{D.r=0;D.g=0;D.b=0}}}}}}}return{r:Math.round(D.r),g:Math.round(D.g),b:Math.round(D.b)}},_RGBToHex:function(B){var C=[B.r.toString(16),B.g.toString(16),B.b.toString(16)];A.each(C,function(D,E){if(E.length==1){C[D]="0"+E}});return C.join("")},_HSBToHex:function(B){return this._RGBToHex(this._HSBToRGB(B))},setColor:function(B){if(typeof B=="string"){B=this._HexToHSB(B)}else{if(B.r!=undefined&&B.g!=undefined&&B.b!=undefined){B=this._RGBToHSB(B)}else{if(B.h!=undefined&&B.s!=undefined&&B.b!=undefined){B=this._fixHSB(B)}else{return this}}}this.color=B;this.origColor=B;this._fillRGBFields(B);this._fillHSBFields(B);this._fillHexFields(B);this._setHue(B);this._setSelector(B);this._setCurrentColor(B);this._setNewColor(B)}});A.extend(A.ui.colorpicker,{defaults:{eventName:"click",color:"ff0000",flat:false}})})(jQuery) \ No newline at end of file
diff --git a/site/app/webroot/js/jquery-ui/ui.core.min.js b/site/app/webroot/js/jquery-ui/ui.core.min.js
new file mode 100755
index 0000000..7cd3681
--- /dev/null
+++ b/site/app/webroot/js/jquery-ui/ui.core.min.js
@@ -0,0 +1 @@
+(function(D){var C=D.fn.remove;D.fn.remove=function(){D("*",this).add(this).triggerHandler("remove");return C.apply(this,arguments)};function B(E){function G(H){var I=H.style;return(I.display!="none"&&I.visibility!="hidden")}var F=G(E);(F&&D.each(D.dir(E,"parentNode"),function(){return(F=G(this))}));return F}D.extend(D.expr[":"],{data:function(F,G,E){return D.data(F,E[3])},tabbable:function(F,G,E){var H=F.nodeName.toLowerCase();return(F.tabIndex>=0&&(("a"==H&&F.href)||(/input|select|textarea|button/.test(H)&&"hidden"!=F.type&&!F.disabled))&&B(F))}});D.keyCode={BACKSPACE:8,CAPS_LOCK:20,COMMA:188,CONTROL:17,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,INSERT:45,LEFT:37,NUMPAD_ADD:107,NUMPAD_DECIMAL:110,NUMPAD_DIVIDE:111,NUMPAD_ENTER:108,NUMPAD_MULTIPLY:106,NUMPAD_SUBTRACT:109,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SHIFT:16,SPACE:32,TAB:9,UP:38};function A(H,I,J,G){function F(L){var K=D[H][I][L]||[];return(typeof K=="string"?K.split(/,?\s+/):K)}var E=F("getter");if(G.length==1&&typeof G[0]=="string"){E=E.concat(F("getterSetter"))}return(D.inArray(J,E)!=-1)}D.widget=function(F,E){var G=F.split(".")[0];F=F.split(".")[1];D.fn[F]=function(K){var I=(typeof K=="string"),J=Array.prototype.slice.call(arguments,1);if(I&&K.substring(0,1)=="_"){return this}if(I&&A(G,F,K,J)){var H=D.data(this[0],F);return(H?H[K].apply(H,J):undefined)}return this.each(function(){var L=D.data(this,F);(!L&&!I&&D.data(this,F,new D[G][F](this,K)));(L&&I&&D.isFunction(L[K])&&L[K].apply(L,J))})};D[G][F]=function(J,I){var H=this;this.widgetName=F;this.widgetEventPrefix=D[G][F].eventPrefix||F;this.widgetBaseClass=G+"-"+F;this.options=D.extend({},D.widget.defaults,D[G][F].defaults,D.metadata&&D.metadata.get(J)[F],I);this.element=D(J).bind("setData."+F,function(M,K,L){return H._setData(K,L)}).bind("getData."+F,function(L,K){return H._getData(K)}).bind("remove",function(){return H.destroy()});this._init()};D[G][F].prototype=D.extend({},D.widget.prototype,E);D[G][F].getterSetter="option"};D.widget.prototype={_init:function(){},destroy:function(){this.element.removeData(this.widgetName)},option:function(G,H){var F=G,E=this;if(typeof G=="string"){if(H===undefined){return this._getData(G)}F={};F[G]=H}D.each(F,function(I,J){E._setData(I,J)})},_getData:function(E){return this.options[E]},_setData:function(E,F){this.options[E]=F;if(E=="disabled"){this.element[F?"addClass":"removeClass"](this.widgetBaseClass+"-disabled")}},enable:function(){this._setData("disabled",false)},disable:function(){this._setData("disabled",true)},_trigger:function(F,H,G){var E=(F==this.widgetEventPrefix?F:this.widgetEventPrefix+F);H=H||D.event.fix({type:E,target:this.element[0]});return this.element.triggerHandler(E,[H,G],this.options[F])}};D.widget.defaults={disabled:false};D.ui={plugin:{add:function(F,G,I){var H=D.ui[F].prototype;for(var E in I){H.plugins[E]=H.plugins[E]||[];H.plugins[E].push([G,I[E]])}},call:function(E,G,F){var I=E.plugins[G];if(!I){return }for(var H=0;H<I.length;H++){if(E.options[I[H][0]]){I[H][1].apply(E.element,F)}}}},cssCache:{},css:function(E){if(D.ui.cssCache[E]){return D.ui.cssCache[E]}var F=D('<div class="ui-gen">').addClass(E).css({position:"absolute",top:"-5000px",left:"-5000px",display:"block"}).appendTo("body");D.ui.cssCache[E]=!!((!(/auto|default/).test(F.css("cursor"))||(/^[1-9]/).test(F.css("height"))||(/^[1-9]/).test(F.css("width"))||!(/none/).test(F.css("backgroundImage"))||!(/transparent|rgba\(0, 0, 0, 0\)/).test(F.css("backgroundColor"))));try{D("body").get(0).removeChild(F.get(0))}catch(G){}return D.ui.cssCache[E]},disableSelection:function(E){return D(E).attr("unselectable","on").css("MozUserSelect","none").bind("selectstart.ui",function(){return false})},enableSelection:function(E){return D(E).attr("unselectable","off").css("MozUserSelect","").unbind("selectstart.ui")},hasScroll:function(H,F){if(D(H).css("overflow")=="hidden"){return false}var E=(F&&F=="left")?"scrollLeft":"scrollTop",G=false;if(H[E]>0){return true}H[E]=1;G=(H[E]>0);H[E]=0;return G}};D.ui.mouse={_mouseInit:function(){var E=this;this.element.bind("mousedown."+this.widgetName,function(F){return E._mouseDown(F)});if(D.browser.msie){this._mouseUnselectable=this.element.attr("unselectable");this.element.attr("unselectable","on")}this.started=false},_mouseDestroy:function(){this.element.unbind("."+this.widgetName);(D.browser.msie&&this.element.attr("unselectable",this._mouseUnselectable))},_mouseDown:function(G){(this._mouseStarted&&this._mouseUp(G));this._mouseDownEvent=G;var F=this,H=(G.which==1),E=(typeof this.options.cancel=="string"?D(G.target).parents().add(G.target).filter(this.options.cancel).length:false);if(!H||E||!this._mouseCapture(G)){return true}this.mouseDelayMet=!this.options.delay;if(!this.mouseDelayMet){this._mouseDelayTimer=setTimeout(function(){F.mouseDelayMet=true},this.options.delay)}if(this._mouseDistanceMet(G)&&this._mouseDelayMet(G)){this._mouseStarted=(this._mouseStart(G)!==false);if(!this._mouseStarted){G.preventDefault();return true}}this._mouseMoveDelegate=function(I){return F._mouseMove(I)};this._mouseUpDelegate=function(I){return F._mouseUp(I)};D(document).bind("mousemove."+this.widgetName,this._mouseMoveDelegate).bind("mouseup."+this.widgetName,this._mouseUpDelegate);return false},_mouseMove:function(E){if(D.browser.msie&&!E.button){return this._mouseUp(E)}if(this._mouseStarted){this._mouseDrag(E);return false}if(this._mouseDistanceMet(E)&&this._mouseDelayMet(E)){this._mouseStarted=(this._mouseStart(this._mouseDownEvent,E)!==false);(this._mouseStarted?this._mouseDrag(E):this._mouseUp(E))}return !this._mouseStarted},_mouseUp:function(E){D(document).unbind("mousemove."+this.widgetName,this._mouseMoveDelegate).unbind("mouseup."+this.widgetName,this._mouseUpDelegate);if(this._mouseStarted){this._mouseStarted=false;this._mouseStop(E)}return false},_mouseDistanceMet:function(E){return(Math.max(Math.abs(this._mouseDownEvent.pageX-E.pageX),Math.abs(this._mouseDownEvent.pageY-E.pageY))>=this.options.distance)},_mouseDelayMet:function(E){return this.mouseDelayMet},_mouseStart:function(E){},_mouseDrag:function(E){},_mouseStop:function(E){},_mouseCapture:function(E){return true}};D.ui.mouse.defaults={cancel:null,distance:1,delay:0}})(jQuery) \ No newline at end of file
diff --git a/site/app/webroot/js/jquery-ui/ui.datepicker.min.js b/site/app/webroot/js/jquery-ui/ui.datepicker.min.js
new file mode 100755
index 0000000..d048138
--- /dev/null
+++ b/site/app/webroot/js/jquery-ui/ui.datepicker.min.js
@@ -0,0 +1 @@
+(function($){var PROP_NAME="datepicker";function Datepicker(){this.debug=false;this._curInst=null;this._disabledInputs=[];this._datepickerShowing=false;this._inDialog=false;this._mainDivId="ui-datepicker-div";this._inlineClass="ui-datepicker-inline";this._appendClass="ui-datepicker-append";this._triggerClass="ui-datepicker-trigger";this._dialogClass="ui-datepicker-dialog";this._promptClass="ui-datepicker-prompt";this._disableClass="ui-datepicker-disabled";this._unselectableClass="ui-datepicker-unselectable";this._currentClass="ui-datepicker-current-day";this.regional=[];this.regional[""]={clearText:"Clear",clearStatus:"Erase the current date",closeText:"Close",closeStatus:"Close without change",prevText:"&#x3c;Prev",prevStatus:"Show the previous month",prevBigText:"&#x3c;&#x3c;",prevBigStatus:"Show the previous year",nextText:"Next&#x3e;",nextStatus:"Show the next month",nextBigText:"&#x3e;&#x3e;",nextBigStatus:"Show the next year",currentText:"Today",currentStatus:"Show the current month",monthNames:["January","February","March","April","May","June","July","August","September","October","November","December"],monthNamesShort:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],monthStatus:"Show a different month",yearStatus:"Show a different year",weekHeader:"Wk",weekStatus:"Week of the year",dayNames:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],dayNamesShort:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],dayNamesMin:["Su","Mo","Tu","We","Th","Fr","Sa"],dayStatus:"Set DD as first week day",dateStatus:"Select DD, M d",dateFormat:"mm/dd/yy",firstDay:0,initStatus:"Select a date",isRTL:false};this._defaults={showOn:"focus",showAnim:"show",showOptions:{},defaultDate:null,appendText:"",buttonText:"...",buttonImage:"",buttonImageOnly:false,closeAtTop:true,mandatory:false,hideIfNoPrevNext:false,navigationAsDateFormat:false,showBigPrevNext:false,gotoCurrent:false,changeMonth:true,changeYear:true,showMonthAfterYear:false,yearRange:"-10:+10",changeFirstDay:true,highlightWeek:false,showOtherMonths:false,showWeeks:false,calculateWeek:this.iso8601Week,shortYearCutoff:"+10",showStatus:false,statusForDate:this.dateStatus,minDate:null,maxDate:null,duration:"normal",beforeShowDay:null,beforeShow:null,onSelect:null,onChangeMonthYear:null,onClose:null,numberOfMonths:1,showCurrentAtPos:0,stepMonths:1,stepBigMonths:12,rangeSelect:false,rangeSeparator:" - ",altField:"",altFormat:""};$.extend(this._defaults,this.regional[""]);this.dpDiv=$('<div id="'+this._mainDivId+'" style="display: none;"></div>')}$.extend(Datepicker.prototype,{markerClassName:"hasDatepicker",log:function(){if(this.debug){console.log.apply("",arguments)}},setDefaults:function(settings){extendRemove(this._defaults,settings||{});return this},_attachDatepicker:function(target,settings){var inlineSettings=null;for(attrName in this._defaults){var attrValue=target.getAttribute("date:"+attrName);if(attrValue){inlineSettings=inlineSettings||{};try{inlineSettings[attrName]=eval(attrValue)}catch(err){inlineSettings[attrName]=attrValue}}}var nodeName=target.nodeName.toLowerCase();var inline=(nodeName=="div"||nodeName=="span");if(!target.id){target.id="dp"+(++this.uuid)}var inst=this._newInst($(target),inline);inst.settings=$.extend({},settings||{},inlineSettings||{});if(nodeName=="input"){this._connectDatepicker(target,inst)}else{if(inline){this._inlineDatepicker(target,inst)}}},_newInst:function(target,inline){var id=target[0].id.replace(/([:\[\]\.])/g,"\\\\$1");return{id:id,input:target,selectedDay:0,selectedMonth:0,selectedYear:0,drawMonth:0,drawYear:0,inline:inline,dpDiv:(!inline?this.dpDiv:$('<div class="'+this._inlineClass+'"></div>'))}},_connectDatepicker:function(target,inst){var input=$(target);if(input.hasClass(this.markerClassName)){return }var appendText=this._get(inst,"appendText");var isRTL=this._get(inst,"isRTL");if(appendText){input[isRTL?"before":"after"]('<span class="'+this._appendClass+'">'+appendText+"</span>")}var showOn=this._get(inst,"showOn");if(showOn=="focus"||showOn=="both"){input.focus(this._showDatepicker)}if(showOn=="button"||showOn=="both"){var buttonText=this._get(inst,"buttonText");var buttonImage=this._get(inst,"buttonImage");var trigger=$(this._get(inst,"buttonImageOnly")?$("<img/>").addClass(this._triggerClass).attr({src:buttonImage,alt:buttonText,title:buttonText}):$('<button type="button"></button>').addClass(this._triggerClass).html(buttonImage==""?buttonText:$("<img/>").attr({src:buttonImage,alt:buttonText,title:buttonText})));input[isRTL?"before":"after"](trigger);trigger.click(function(){if($.datepicker._datepickerShowing&&$.datepicker._lastInput==target){$.datepicker._hideDatepicker()}else{$.datepicker._showDatepicker(target)}return false})}input.addClass(this.markerClassName).keydown(this._doKeyDown).keypress(this._doKeyPress).bind("setData.datepicker",function(event,key,value){inst.settings[key]=value}).bind("getData.datepicker",function(event,key){return this._get(inst,key)});$.data(target,PROP_NAME,inst)},_inlineDatepicker:function(target,inst){var divSpan=$(target);if(divSpan.hasClass(this.markerClassName)){return }divSpan.addClass(this.markerClassName).append(inst.dpDiv).bind("setData.datepicker",function(event,key,value){inst.settings[key]=value}).bind("getData.datepicker",function(event,key){return this._get(inst,key)});$.data(target,PROP_NAME,inst);this._setDate(inst,this._getDefaultDate(inst));this._updateDatepicker(inst)},_inlineShow:function(inst){var numMonths=this._getNumberOfMonths(inst);inst.dpDiv.width(numMonths[1]*$(".ui-datepicker",inst.dpDiv[0]).width())},_dialogDatepicker:function(input,dateText,onSelect,settings,pos){var inst=this._dialogInst;if(!inst){var id="dp"+(++this.uuid);this._dialogInput=$('<input type="text" id="'+id+'" size="1" style="position: absolute; top: -100px;"/>');this._dialogInput.keydown(this._doKeyDown);$("body").append(this._dialogInput);inst=this._dialogInst=this._newInst(this._dialogInput,false);inst.settings={};$.data(this._dialogInput[0],PROP_NAME,inst)}extendRemove(inst.settings,settings||{});this._dialogInput.val(dateText);this._pos=(pos?(pos.length?pos:[pos.pageX,pos.pageY]):null);if(!this._pos){var browserWidth=window.innerWidth||document.documentElement.clientWidth||document.body.clientWidth;var browserHeight=window.innerHeight||document.documentElement.clientHeight||document.body.clientHeight;var scrollX=document.documentElement.scrollLeft||document.body.scrollLeft;var scrollY=document.documentElement.scrollTop||document.body.scrollTop;this._pos=[(browserWidth/2)-100+scrollX,(browserHeight/2)-150+scrollY]}this._dialogInput.css("left",this._pos[0]+"px").css("top",this._pos[1]+"px");inst.settings.onSelect=onSelect;this._inDialog=true;this.dpDiv.addClass(this._dialogClass);this._showDatepicker(this._dialogInput[0]);if($.blockUI){$.blockUI(this.dpDiv)}$.data(this._dialogInput[0],PROP_NAME,inst);return this},_destroyDatepicker:function(target){var $target=$(target);if(!$target.hasClass(this.markerClassName)){return }var nodeName=target.nodeName.toLowerCase();$.removeData(target,PROP_NAME);if(nodeName=="input"){$target.siblings("."+this._appendClass).remove().end().siblings("."+this._triggerClass).remove().end().removeClass(this.markerClassName).unbind("focus",this._showDatepicker).unbind("keydown",this._doKeyDown).unbind("keypress",this._doKeyPress)}else{if(nodeName=="div"||nodeName=="span"){$target.removeClass(this.markerClassName).empty()}}},_enableDatepicker:function(target){var $target=$(target);if(!$target.hasClass(this.markerClassName)){return }var nodeName=target.nodeName.toLowerCase();if(nodeName=="input"){target.disabled=false;$target.siblings("button."+this._triggerClass).each(function(){this.disabled=false}).end().siblings("img."+this._triggerClass).css({opacity:"1.0",cursor:""})}else{if(nodeName=="div"||nodeName=="span"){$target.children("."+this._disableClass).remove()}}this._disabledInputs=$.map(this._disabledInputs,function(value){return(value==target?null:value)})},_disableDatepicker:function(target){var $target=$(target);if(!$target.hasClass(this.markerClassName)){return }var nodeName=target.nodeName.toLowerCase();if(nodeName=="input"){target.disabled=true;$target.siblings("button."+this._triggerClass).each(function(){this.disabled=true}).end().siblings("img."+this._triggerClass).css({opacity:"0.5",cursor:"default"})}else{if(nodeName=="div"||nodeName=="span"){var inline=$target.children("."+this._inlineClass);var offset=inline.offset();var relOffset={left:0,top:0};inline.parents().each(function(){if($(this).css("position")=="relative"){relOffset=$(this).offset();return false}});$target.prepend('<div class="'+this._disableClass+'" style="'+($.browser.msie?"background-color: transparent; ":"")+"width: "+inline.width()+"px; height: "+inline.height()+"px; left: "+(offset.left-relOffset.left)+"px; top: "+(offset.top-relOffset.top)+'px;"></div>')}}this._disabledInputs=$.map(this._disabledInputs,function(value){return(value==target?null:value)});this._disabledInputs[this._disabledInputs.length]=target},_isDisabledDatepicker:function(target){if(!target){return false}for(var i=0;i<this._disabledInputs.length;i++){if(this._disabledInputs[i]==target){return true}}return false},_getInst:function(target){try{return $.data(target,PROP_NAME)}catch(err){throw"Missing instance data for this datepicker"}},_changeDatepicker:function(target,name,value){var settings=name||{};if(typeof name=="string"){settings={};settings[name]=value}var inst=this._getInst(target);if(inst){if(this._curInst==inst){this._hideDatepicker(null)}extendRemove(inst.settings,settings);var date=new Date();extendRemove(inst,{rangeStart:null,endDay:null,endMonth:null,endYear:null,selectedDay:date.getDate(),selectedMonth:date.getMonth(),selectedYear:date.getFullYear(),currentDay:date.getDate(),currentMonth:date.getMonth(),currentYear:date.getFullYear(),drawMonth:date.getMonth(),drawYear:date.getFullYear()});this._updateDatepicker(inst)}},_refreshDatepicker:function(target){var inst=this._getInst(target);if(inst){this._updateDatepicker(inst)}},_setDateDatepicker:function(target,date,endDate){var inst=this._getInst(target);if(inst){this._setDate(inst,date,endDate);this._updateDatepicker(inst);this._updateAlternate(inst)}},_getDateDatepicker:function(target){var inst=this._getInst(target);if(inst&&!inst.inline){this._setDateFromField(inst)}return(inst?this._getDate(inst):null)},_doKeyDown:function(e){var inst=$.datepicker._getInst(e.target);var handled=true;if($.datepicker._datepickerShowing){switch(e.keyCode){case 9:$.datepicker._hideDatepicker(null,"");break;case 13:$.datepicker._selectDay(e.target,inst.selectedMonth,inst.selectedYear,$("td.ui-datepicker-days-cell-over",inst.dpDiv)[0]);return false;break;case 27:$.datepicker._hideDatepicker(null,$.datepicker._get(inst,"duration"));break;case 33:$.datepicker._adjustDate(e.target,(e.ctrlKey?-$.datepicker._get(inst,"stepBigMonths"):-$.datepicker._get(inst,"stepMonths")),"M");break;case 34:$.datepicker._adjustDate(e.target,(e.ctrlKey?+$.datepicker._get(inst,"stepBigMonths"):+$.datepicker._get(inst,"stepMonths")),"M");break;case 35:if(e.ctrlKey){$.datepicker._clearDate(e.target)}handled=e.ctrlKey;break;case 36:if(e.ctrlKey){$.datepicker._gotoToday(e.target)}handled=e.ctrlKey;break;case 37:if(e.ctrlKey){$.datepicker._adjustDate(e.target,-1,"D")}handled=e.ctrlKey;break;case 38:if(e.ctrlKey){$.datepicker._adjustDate(e.target,-7,"D")}handled=e.ctrlKey;break;case 39:if(e.ctrlKey){$.datepicker._adjustDate(e.target,+1,"D")}handled=e.ctrlKey;break;case 40:if(e.ctrlKey){$.datepicker._adjustDate(e.target,+7,"D")}handled=e.ctrlKey;break;default:handled=false}}else{if(e.keyCode==36&&e.ctrlKey){$.datepicker._showDatepicker(this)}else{handled=false}}if(handled){e.preventDefault();e.stopPropagation()}},_doKeyPress:function(e){var inst=$.datepicker._getInst(e.target);var chars=$.datepicker._possibleChars($.datepicker._get(inst,"dateFormat"));var chr=String.fromCharCode(e.charCode==undefined?e.keyCode:e.charCode);return e.ctrlKey||(chr<" "||!chars||chars.indexOf(chr)>-1)},_showDatepicker:function(input){input=input.target||input;if(input.nodeName.toLowerCase()!="input"){input=$("input",input.parentNode)[0]}if($.datepicker._isDisabledDatepicker(input)||$.datepicker._lastInput==input){return }var inst=$.datepicker._getInst(input);var beforeShow=$.datepicker._get(inst,"beforeShow");extendRemove(inst.settings,(beforeShow?beforeShow.apply(input,[input,inst]):{}));$.datepicker._hideDatepicker(null,"");$.datepicker._lastInput=input;$.datepicker._setDateFromField(inst);if($.datepicker._inDialog){input.value=""}if(!$.datepicker._pos){$.datepicker._pos=$.datepicker._findPos(input);$.datepicker._pos[1]+=input.offsetHeight}var isFixed=false;$(input).parents().each(function(){isFixed|=$(this).css("position")=="fixed";return !isFixed});if(isFixed&&$.browser.opera){$.datepicker._pos[0]-=document.documentElement.scrollLeft;$.datepicker._pos[1]-=document.documentElement.scrollTop}var offset={left:$.datepicker._pos[0],top:$.datepicker._pos[1]};$.datepicker._pos=null;inst.rangeStart=null;inst.dpDiv.css({position:"absolute",display:"block",top:"-1000px"});$.datepicker._updateDatepicker(inst);inst.dpDiv.width($.datepicker._getNumberOfMonths(inst)[1]*$(".ui-datepicker",inst.dpDiv[0])[0].offsetWidth);offset=$.datepicker._checkOffset(inst,offset,isFixed);inst.dpDiv.css({position:($.datepicker._inDialog&&$.blockUI?"static":(isFixed?"fixed":"absolute")),display:"none",left:offset.left+"px",top:offset.top+"px"});if(!inst.inline){var showAnim=$.datepicker._get(inst,"showAnim")||"show";var duration=$.datepicker._get(inst,"duration");var postProcess=function(){$.datepicker._datepickerShowing=true;if($.browser.msie&&parseInt($.browser.version,10)<7){$("iframe.ui-datepicker-cover").css({width:inst.dpDiv.width()+4,height:inst.dpDiv.height()+4})}};if($.effects&&$.effects[showAnim]){inst.dpDiv.show(showAnim,$.datepicker._get(inst,"showOptions"),duration,postProcess)}else{inst.dpDiv[showAnim](duration,postProcess)}if(duration==""){postProcess()}if(inst.input[0].type!="hidden"){inst.input[0].focus()}$.datepicker._curInst=inst}},_updateDatepicker:function(inst){var dims={width:inst.dpDiv.width()+4,height:inst.dpDiv.height()+4};inst.dpDiv.empty().append(this._generateHTML(inst)).find("iframe.ui-datepicker-cover").css({width:dims.width,height:dims.height});var numMonths=this._getNumberOfMonths(inst);inst.dpDiv[(numMonths[0]!=1||numMonths[1]!=1?"add":"remove")+"Class"]("ui-datepicker-multi");inst.dpDiv[(this._get(inst,"isRTL")?"add":"remove")+"Class"]("ui-datepicker-rtl");if(inst.input&&inst.input[0].type!="hidden"){$(inst.input[0]).focus()}},_checkOffset:function(inst,offset,isFixed){var pos=inst.input?this._findPos(inst.input[0]):null;var browserWidth=window.innerWidth||document.documentElement.clientWidth;var browserHeight=window.innerHeight||document.documentElement.clientHeight;var scrollX=document.documentElement.scrollLeft||document.body.scrollLeft;var scrollY=document.documentElement.scrollTop||document.body.scrollTop;if(this._get(inst,"isRTL")||(offset.left+inst.dpDiv.width()-scrollX)>browserWidth){offset.left=Math.max((isFixed?0:scrollX),pos[0]+(inst.input?inst.input.width():0)-(isFixed?scrollX:0)-inst.dpDiv.width()-(isFixed&&$.browser.opera?document.documentElement.scrollLeft:0))}else{offset.left-=(isFixed?scrollX:0)}if((offset.top+inst.dpDiv.height()-scrollY)>browserHeight){offset.top=Math.max((isFixed?0:scrollY),pos[1]-(isFixed?scrollY:0)-(this._inDialog?0:inst.dpDiv.height())-(isFixed&&$.browser.opera?document.documentElement.scrollTop:0))}else{offset.top-=(isFixed?scrollY:0)}return offset},_findPos:function(obj){while(obj&&(obj.type=="hidden"||obj.nodeType!=1)){obj=obj.nextSibling}var position=$(obj).offset();return[position.left,position.top]},_hideDatepicker:function(input,duration){var inst=this._curInst;if(!inst||(input&&inst!=$.data(input,PROP_NAME))){return }var rangeSelect=this._get(inst,"rangeSelect");if(rangeSelect&&inst.stayOpen){this._selectDate("#"+inst.id,this._formatDate(inst,inst.currentDay,inst.currentMonth,inst.currentYear))}inst.stayOpen=false;if(this._datepickerShowing){duration=(duration!=null?duration:this._get(inst,"duration"));var showAnim=this._get(inst,"showAnim");var postProcess=function(){$.datepicker._tidyDialog(inst)};if(duration!=""&&$.effects&&$.effects[showAnim]){inst.dpDiv.hide(showAnim,$.datepicker._get(inst,"showOptions"),duration,postProcess)}else{inst.dpDiv[(duration==""?"hide":(showAnim=="slideDown"?"slideUp":(showAnim=="fadeIn"?"fadeOut":"hide")))](duration,postProcess)}if(duration==""){this._tidyDialog(inst)}var onClose=this._get(inst,"onClose");if(onClose){onClose.apply((inst.input?inst.input[0]:null),[(inst.input?inst.input.val():""),inst])}this._datepickerShowing=false;this._lastInput=null;inst.settings.prompt=null;if(this._inDialog){this._dialogInput.css({position:"absolute",left:"0",top:"-100px"});if($.blockUI){$.unblockUI();$("body").append(this.dpDiv)}}this._inDialog=false}this._curInst=null},_tidyDialog:function(inst){inst.dpDiv.removeClass(this._dialogClass).unbind(".ui-datepicker");$("."+this._promptClass,inst.dpDiv).remove()},_checkExternalClick:function(event){if(!$.datepicker._curInst){return }var $target=$(event.target);if(($target.parents("#"+$.datepicker._mainDivId).length==0)&&!$target.hasClass($.datepicker.markerClassName)&&!$target.hasClass($.datepicker._triggerClass)&&$.datepicker._datepickerShowing&&!($.datepicker._inDialog&&$.blockUI)){$.datepicker._hideDatepicker(null,"")}},_adjustDate:function(id,offset,period){var target=$(id);var inst=this._getInst(target[0]);this._adjustInstDate(inst,offset,period);this._updateDatepicker(inst)},_gotoToday:function(id){var target=$(id);var inst=this._getInst(target[0]);if(this._get(inst,"gotoCurrent")&&inst.currentDay){inst.selectedDay=inst.currentDay;inst.drawMonth=inst.selectedMonth=inst.currentMonth;inst.drawYear=inst.selectedYear=inst.currentYear}else{var date=new Date();inst.selectedDay=date.getDate();inst.drawMonth=inst.selectedMonth=date.getMonth();inst.drawYear=inst.selectedYear=date.getFullYear()}this._notifyChange(inst);this._adjustDate(target)},_selectMonthYear:function(id,select,period){var target=$(id);var inst=this._getInst(target[0]);inst._selectingMonthYear=false;inst["selected"+(period=="M"?"Month":"Year")]=inst["draw"+(period=="M"?"Month":"Year")]=parseInt(select.options[select.selectedIndex].value,10);this._notifyChange(inst);this._adjustDate(target)},_clickMonthYear:function(id){var target=$(id);var inst=this._getInst(target[0]);if(inst.input&&inst._selectingMonthYear&&!$.browser.msie){inst.input[0].focus()}inst._selectingMonthYear=!inst._selectingMonthYear},_changeFirstDay:function(id,day){var target=$(id);var inst=this._getInst(target[0]);inst.settings.firstDay=day;this._updateDatepicker(inst)},_selectDay:function(id,month,year,td){if($(td).hasClass(this._unselectableClass)){return }var target=$(id);var inst=this._getInst(target[0]);var rangeSelect=this._get(inst,"rangeSelect");if(rangeSelect){inst.stayOpen=!inst.stayOpen;if(inst.stayOpen){$(".ui-datepicker td",inst.dpDiv).removeClass(this._currentClass);$(td).addClass(this._currentClass)}}inst.selectedDay=inst.currentDay=$("a",td).html();inst.selectedMonth=inst.currentMonth=month;inst.selectedYear=inst.currentYear=year;if(inst.stayOpen){inst.endDay=inst.endMonth=inst.endYear=null}else{if(rangeSelect){inst.endDay=inst.currentDay;inst.endMonth=inst.currentMonth;inst.endYear=inst.currentYear}}this._selectDate(id,this._formatDate(inst,inst.currentDay,inst.currentMonth,inst.currentYear));if(inst.stayOpen){inst.rangeStart=new Date(inst.currentYear,inst.currentMonth,inst.currentDay);this._updateDatepicker(inst)}else{if(rangeSelect){inst.selectedDay=inst.currentDay=inst.rangeStart.getDate();inst.selectedMonth=inst.currentMonth=inst.rangeStart.getMonth();inst.selectedYear=inst.currentYear=inst.rangeStart.getFullYear();inst.rangeStart=null;if(inst.inline){this._updateDatepicker(inst)}}}},_clearDate:function(id){var target=$(id);var inst=this._getInst(target[0]);if(this._get(inst,"mandatory")){return }inst.stayOpen=false;inst.endDay=inst.endMonth=inst.endYear=inst.rangeStart=null;this._selectDate(target,"")},_selectDate:function(id,dateStr){var target=$(id);var inst=this._getInst(target[0]);dateStr=(dateStr!=null?dateStr:this._formatDate(inst));if(this._get(inst,"rangeSelect")&&dateStr){dateStr=(inst.rangeStart?this._formatDate(inst,inst.rangeStart):dateStr)+this._get(inst,"rangeSeparator")+dateStr}if(inst.input){inst.input.val(dateStr)}this._updateAlternate(inst);var onSelect=this._get(inst,"onSelect");if(onSelect){onSelect.apply((inst.input?inst.input[0]:null),[dateStr,inst])}else{if(inst.input){inst.input.trigger("change")}}if(inst.inline){this._updateDatepicker(inst)}else{if(!inst.stayOpen){this._hideDatepicker(null,this._get(inst,"duration"));this._lastInput=inst.input[0];if(typeof (inst.input[0])!="object"){inst.input[0].focus()}this._lastInput=null}}},_updateAlternate:function(inst){var altField=this._get(inst,"altField");if(altField){var altFormat=this._get(inst,"altFormat");var date=this._getDate(inst);dateStr=(isArray(date)?(!date[0]&&!date[1]?"":this.formatDate(altFormat,date[0],this._getFormatConfig(inst))+this._get(inst,"rangeSeparator")+this.formatDate(altFormat,date[1]||date[0],this._getFormatConfig(inst))):this.formatDate(altFormat,date,this._getFormatConfig(inst)));$(altField).each(function(){$(this).val(dateStr)})}},noWeekends:function(date){var day=date.getDay();return[(day>0&&day<6),""]},iso8601Week:function(date){var checkDate=new Date(date.getFullYear(),date.getMonth(),date.getDate(),(date.getTimezoneOffset()/-60));var firstMon=new Date(checkDate.getFullYear(),1-1,4);var firstDay=firstMon.getDay()||7;firstMon.setDate(firstMon.getDate()+1-firstDay);if(firstDay<4&&checkDate<firstMon){checkDate.setDate(checkDate.getDate()-3);return $.datepicker.iso8601Week(checkDate)}else{if(checkDate>new Date(checkDate.getFullYear(),12-1,28)){firstDay=new Date(checkDate.getFullYear()+1,1-1,4).getDay()||7;if(firstDay>4&&(checkDate.getDay()||7)<firstDay-3){return 1}}}return Math.floor(((checkDate-firstMon)/86400000)/7)+1},dateStatus:function(date,inst){return $.datepicker.formatDate($.datepicker._get(inst,"dateStatus"),date,$.datepicker._getFormatConfig(inst))},parseDate:function(format,value,settings){if(format==null||value==null){throw"Invalid arguments"}value=(typeof value=="object"?value.toString():value+"");if(value==""){return null}var shortYearCutoff=(settings?settings.shortYearCutoff:null)||this._defaults.shortYearCutoff;var dayNamesShort=(settings?settings.dayNamesShort:null)||this._defaults.dayNamesShort;var dayNames=(settings?settings.dayNames:null)||this._defaults.dayNames;var monthNamesShort=(settings?settings.monthNamesShort:null)||this._defaults.monthNamesShort;var monthNames=(settings?settings.monthNames:null)||this._defaults.monthNames;var year=-1;var month=-1;var day=-1;var doy=-1;var literal=false;var lookAhead=function(match){var matches=(iFormat+1<format.length&&format.charAt(iFormat+1)==match);if(matches){iFormat++}return matches};var getNumber=function(match){lookAhead(match);var origSize=(match=="@"?14:(match=="y"?4:(match=="o"?3:2)));var size=origSize;var num=0;while(size>0&&iValue<value.length&&value.charAt(iValue)>="0"&&value.charAt(iValue)<="9"){num=num*10+parseInt(value.charAt(iValue++),10);size--}if(size==origSize){throw"Missing number at position "+iValue}return num};var getName=function(match,shortNames,longNames){var names=(lookAhead(match)?longNames:shortNames);var size=0;for(var j=0;j<names.length;j++){size=Math.max(size,names[j].length)}var name="";var iInit=iValue;while(size>0&&iValue<value.length){name+=value.charAt(iValue++);for(var i=0;i<names.length;i++){if(name==names[i]){return i+1}}size--}throw"Unknown name at position "+iInit};var checkLiteral=function(){if(value.charAt(iValue)!=format.charAt(iFormat)){throw"Unexpected literal at position "+iValue}iValue++};var iValue=0;for(var iFormat=0;iFormat<format.length;iFormat++){if(literal){if(format.charAt(iFormat)=="'"&&!lookAhead("'")){literal=false}else{checkLiteral()}}else{switch(format.charAt(iFormat)){case"d":day=getNumber("d");break;case"D":getName("D",dayNamesShort,dayNames);break;case"o":doy=getNumber("o");break;case"m":month=getNumber("m");break;case"M":month=getName("M",monthNamesShort,monthNames);break;case"y":year=getNumber("y");break;case"@":var date=new Date(getNumber("@"));year=date.getFullYear();month=date.getMonth()+1;day=date.getDate();break;case"'":if(lookAhead("'")){checkLiteral()}else{literal=true}break;default:checkLiteral()}}}if(year<100){year+=new Date().getFullYear()-new Date().getFullYear()%100+(year<=shortYearCutoff?0:-100)}if(doy>-1){month=1;day=doy;do{var dim=this._getDaysInMonth(year,month-1);if(day<=dim){break}month++;day-=dim}while(true)}var date=new Date(year,month-1,day);if(date.getFullYear()!=year||date.getMonth()+1!=month||date.getDate()!=day){throw"Invalid date"}return date},ATOM:"yy-mm-dd",COOKIE:"D, dd M yy",ISO_8601:"yy-mm-dd",RFC_822:"D, d M y",RFC_850:"DD, dd-M-y",RFC_1036:"D, d M y",RFC_1123:"D, d M yy",RFC_2822:"D, d M yy",RSS:"D, d M y",TIMESTAMP:"@",W3C:"yy-mm-dd",formatDate:function(format,date,settings){if(!date){return""}var dayNamesShort=(settings?settings.dayNamesShort:null)||this._defaults.dayNamesShort;var dayNames=(settings?settings.dayNames:null)||this._defaults.dayNames;var monthNamesShort=(settings?settings.monthNamesShort:null)||this._defaults.monthNamesShort;var monthNames=(settings?settings.monthNames:null)||this._defaults.monthNames;var lookAhead=function(match){var matches=(iFormat+1<format.length&&format.charAt(iFormat+1)==match);if(matches){iFormat++}return matches};var formatNumber=function(match,value,len){var num=""+value;if(lookAhead(match)){while(num.length<len){num="0"+num}}return num};var formatName=function(match,value,shortNames,longNames){return(lookAhead(match)?longNames[value]:shortNames[value])};var output="";var literal=false;if(date){for(var iFormat=0;iFormat<format.length;iFormat++){if(literal){if(format.charAt(iFormat)=="'"&&!lookAhead("'")){literal=false}else{output+=format.charAt(iFormat)}}else{switch(format.charAt(iFormat)){case"d":output+=formatNumber("d",date.getDate(),2);break;case"D":output+=formatName("D",date.getDay(),dayNamesShort,dayNames);break;case"o":var doy=date.getDate();for(var m=date.getMonth()-1;m>=0;m--){doy+=this._getDaysInMonth(date.getFullYear(),m)}output+=formatNumber("o",doy,3);break;case"m":output+=formatNumber("m",date.getMonth()+1,2);break;case"M":output+=formatName("M",date.getMonth(),monthNamesShort,monthNames);break;case"y":output+=(lookAhead("y")?date.getFullYear():(date.getYear()%100<10?"0":"")+date.getYear()%100);break;case"@":output+=date.getTime();break;case"'":if(lookAhead("'")){output+="'"}else{literal=true}break;default:output+=format.charAt(iFormat)}}}}return output},_possibleChars:function(format){var chars="";var literal=false;for(var iFormat=0;iFormat<format.length;iFormat++){if(literal){if(format.charAt(iFormat)=="'"&&!lookAhead("'")){literal=false}else{chars+=format.charAt(iFormat)}}else{switch(format.charAt(iFormat)){case"d":case"m":case"y":case"@":chars+="0123456789";break;case"D":case"M":return null;case"'":if(lookAhead("'")){chars+="'"}else{literal=true}break;default:chars+=format.charAt(iFormat)}}}return chars},_get:function(inst,name){return inst.settings[name]!==undefined?inst.settings[name]:this._defaults[name]},_setDateFromField:function(inst){var dateFormat=this._get(inst,"dateFormat");var dates=inst.input?inst.input.val().split(this._get(inst,"rangeSeparator")):null;inst.endDay=inst.endMonth=inst.endYear=null;var date=defaultDate=this._getDefaultDate(inst);if(dates.length>0){var settings=this._getFormatConfig(inst);if(dates.length>1){date=this.parseDate(dateFormat,dates[1],settings)||defaultDate;inst.endDay=date.getDate();inst.endMonth=date.getMonth();inst.endYear=date.getFullYear()}try{date=this.parseDate(dateFormat,dates[0],settings)||defaultDate}catch(e){this.log(e);date=defaultDate}}inst.selectedDay=date.getDate();inst.drawMonth=inst.selectedMonth=date.getMonth();inst.drawYear=inst.selectedYear=date.getFullYear();inst.currentDay=(dates[0]?date.getDate():0);inst.currentMonth=(dates[0]?date.getMonth():0);inst.currentYear=(dates[0]?date.getFullYear():0);this._adjustInstDate(inst)},_getDefaultDate:function(inst){var date=this._determineDate(this._get(inst,"defaultDate"),new Date());var minDate=this._getMinMaxDate(inst,"min",true);var maxDate=this._getMinMaxDate(inst,"max");date=(minDate&&date<minDate?minDate:date);date=(maxDate&&date>maxDate?maxDate:date);return date},_determineDate:function(date,defaultDate){var offsetNumeric=function(offset){var date=new Date();date.setUTCDate(date.getUTCDate()+offset);return date};var offsetString=function(offset,getDaysInMonth){var date=new Date();var year=date.getFullYear();var month=date.getMonth();var day=date.getDate();var pattern=/([+-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g;var matches=pattern.exec(offset);while(matches){switch(matches[2]||"d"){case"d":case"D":day+=parseInt(matches[1],10);break;case"w":case"W":day+=parseInt(matches[1],10)*7;break;case"m":case"M":month+=parseInt(matches[1],10);day=Math.min(day,getDaysInMonth(year,month));break;case"y":case"Y":year+=parseInt(matches[1],10);day=Math.min(day,getDaysInMonth(year,month));break}matches=pattern.exec(offset)}return new Date(year,month,day)};date=(date==null?defaultDate:(typeof date=="string"?offsetString(date,this._getDaysInMonth):(typeof date=="number"?(isNaN(date)?defaultDate:offsetNumeric(date)):date)));return(date&&date.toString()=="Invalid Date"?defaultDate:date)},_setDate:function(inst,date,endDate){var clear=!(date);var origMonth=inst.selectedMonth;var origYear=inst.selectedYear;date=this._determineDate(date,new Date());inst.selectedDay=inst.currentDay=date.getDate();inst.drawMonth=inst.selectedMonth=inst.currentMonth=date.getMonth();inst.drawYear=inst.selectedYear=inst.currentYear=date.getFullYear();if(this._get(inst,"rangeSelect")){if(endDate){endDate=this._determineDate(endDate,null);inst.endDay=endDate.getDate();inst.endMonth=endDate.getMonth();inst.endYear=endDate.getFullYear()}else{inst.endDay=inst.currentDay;inst.endMonth=inst.currentMonth;inst.endYear=inst.currentYear}}if(origMonth!=inst.selectedMonth||origYear!=inst.selectedYear){this._notifyChange(inst)}this._adjustInstDate(inst);if(inst.input){inst.input.val(clear?"":this._formatDate(inst)+(!this._get(inst,"rangeSelect")?"":this._get(inst,"rangeSeparator")+this._formatDate(inst,inst.endDay,inst.endMonth,inst.endYear)))}},_getDate:function(inst){var startDate=(!inst.currentYear||(inst.input&&inst.input.val()=="")?null:new Date(inst.currentYear,inst.currentMonth,inst.currentDay));if(this._get(inst,"rangeSelect")){return[inst.rangeStart||startDate,(!inst.endYear?inst.rangeStart||startDate:new Date(inst.endYear,inst.endMonth,inst.endDay))]}else{return startDate}},_generateHTML:function(inst){var today=new Date();today=new Date(today.getFullYear(),today.getMonth(),today.getDate());var showStatus=this._get(inst,"showStatus");var initStatus=this._get(inst,"initStatus")||"&#xa0;";var isRTL=this._get(inst,"isRTL");var clear=(this._get(inst,"mandatory")?"":'<div class="ui-datepicker-clear"><a onclick="jQuery.datepicker._clearDate(\'#'+inst.id+"');\""+this._addStatus(showStatus,inst.id,this._get(inst,"clearStatus"),initStatus)+">"+this._get(inst,"clearText")+"</a></div>");var controls='<div class="ui-datepicker-control">'+(isRTL?"":clear)+'<div class="ui-datepicker-close"><a onclick="jQuery.datepicker._hideDatepicker();"'+this._addStatus(showStatus,inst.id,this._get(inst,"closeStatus"),initStatus)+">"+this._get(inst,"closeText")+"</a></div>"+(isRTL?clear:"")+"</div>";var prompt=this._get(inst,"prompt");var closeAtTop=this._get(inst,"closeAtTop");var hideIfNoPrevNext=this._get(inst,"hideIfNoPrevNext");var navigationAsDateFormat=this._get(inst,"navigationAsDateFormat");var showBigPrevNext=this._get(inst,"showBigPrevNext");var numMonths=this._getNumberOfMonths(inst);var showCurrentAtPos=this._get(inst,"showCurrentAtPos");var stepMonths=this._get(inst,"stepMonths");var stepBigMonths=this._get(inst,"stepBigMonths");var isMultiMonth=(numMonths[0]!=1||numMonths[1]!=1);var currentDate=(!inst.currentDay?new Date(9999,9,9):new Date(inst.currentYear,inst.currentMonth,inst.currentDay));var minDate=this._getMinMaxDate(inst,"min",true);var maxDate=this._getMinMaxDate(inst,"max");var drawMonth=inst.drawMonth-showCurrentAtPos;var drawYear=inst.drawYear;if(drawMonth<0){drawMonth+=12;drawYear--}if(maxDate){var maxDraw=new Date(maxDate.getFullYear(),maxDate.getMonth()-numMonths[1]+1,maxDate.getDate());maxDraw=(minDate&&maxDraw<minDate?minDate:maxDraw);while(new Date(drawYear,drawMonth,1)>maxDraw){drawMonth--;if(drawMonth<0){drawMonth=11;drawYear--}}}var prevText=this._get(inst,"prevText");prevText=(!navigationAsDateFormat?prevText:this.formatDate(prevText,new Date(drawYear,drawMonth-stepMonths,1),this._getFormatConfig(inst)));var prevBigText=(showBigPrevNext?this._get(inst,"prevBigText"):"");prevBigText=(!navigationAsDateFormat?prevBigText:this.formatDate(prevBigText,new Date(drawYear,drawMonth-stepBigMonths,1),this._getFormatConfig(inst)));var prev='<div class="ui-datepicker-prev">'+(this._canAdjustMonth(inst,-1,drawYear,drawMonth)?(showBigPrevNext?"<a onclick=\"jQuery.datepicker._adjustDate('#"+inst.id+"', -"+stepBigMonths+", 'M');\""+this._addStatus(showStatus,inst.id,this._get(inst,"prevBigStatus"),initStatus)+">"+prevBigText+"</a>":"")+"<a onclick=\"jQuery.datepicker._adjustDate('#"+inst.id+"', -"+stepMonths+", 'M');\""+this._addStatus(showStatus,inst.id,this._get(inst,"prevStatus"),initStatus)+">"+prevText+"</a>":(hideIfNoPrevNext?"":"<label>"+prevBigText+"</label><label>"+prevText+"</label>"))+"</div>";var nextText=this._get(inst,"nextText");nextText=(!navigationAsDateFormat?nextText:this.formatDate(nextText,new Date(drawYear,drawMonth+stepMonths,1),this._getFormatConfig(inst)));var nextBigText=(showBigPrevNext?this._get(inst,"nextBigText"):"");nextBigText=(!navigationAsDateFormat?nextBigText:this.formatDate(nextBigText,new Date(drawYear,drawMonth+stepBigMonths,1),this._getFormatConfig(inst)));var next='<div class="ui-datepicker-next">'+(this._canAdjustMonth(inst,+1,drawYear,drawMonth)?"<a onclick=\"jQuery.datepicker._adjustDate('#"+inst.id+"', +"+stepMonths+", 'M');\""+this._addStatus(showStatus,inst.id,this._get(inst,"nextStatus"),initStatus)+">"+nextText+"</a>"+(showBigPrevNext?"<a onclick=\"jQuery.datepicker._adjustDate('#"+inst.id+"', +"+stepBigMonths+", 'M');\""+this._addStatus(showStatus,inst.id,this._get(inst,"nextBigStatus"),initStatus)+">"+nextBigText+"</a>":""):(hideIfNoPrevNext?"":"<label>"+nextText+"</label><label>"+nextBigText+"</label>"))+"</div>";var currentText=this._get(inst,"currentText");var gotoDate=(this._get(inst,"gotoCurrent")&&inst.currentDay?currentDate:today);currentText=(!navigationAsDateFormat?currentText:this.formatDate(currentText,gotoDate,this._getFormatConfig(inst)));var html=(prompt?'<div class="'+this._promptClass+'">'+prompt+"</div>":"")+(closeAtTop&&!inst.inline?controls:"")+'<div class="ui-datepicker-links">'+(isRTL?next:prev)+(this._isInRange(inst,gotoDate)?'<div class="ui-datepicker-current"><a onclick="jQuery.datepicker._gotoToday(\'#'+inst.id+"');\""+this._addStatus(showStatus,inst.id,this._get(inst,"currentStatus"),initStatus)+">"+currentText+"</a></div>":"")+(isRTL?prev:next)+"</div>";var firstDay=this._get(inst,"firstDay");var changeFirstDay=this._get(inst,"changeFirstDay");var dayNames=this._get(inst,"dayNames");var dayNamesShort=this._get(inst,"dayNamesShort");var dayNamesMin=this._get(inst,"dayNamesMin");var monthNames=this._get(inst,"monthNames");var beforeShowDay=this._get(inst,"beforeShowDay");var highlightWeek=this._get(inst,"highlightWeek");var showOtherMonths=this._get(inst,"showOtherMonths");var showWeeks=this._get(inst,"showWeeks");var calculateWeek=this._get(inst,"calculateWeek")||this.iso8601Week;var weekStatus=this._get(inst,"weekStatus");var status=(showStatus?this._get(inst,"dayStatus")||initStatus:"");var dateStatus=this._get(inst,"statusForDate")||this.dateStatus;var endDate=inst.endDay?new Date(inst.endYear,inst.endMonth,inst.endDay):currentDate;for(var row=0;row<numMonths[0];row++){for(var col=0;col<numMonths[1];col++){var selectedDate=new Date(drawYear,drawMonth,inst.selectedDay);html+='<div class="ui-datepicker-one-month'+(col==0?" ui-datepicker-new-row":"")+'">'+this._generateMonthYearHeader(inst,drawMonth,drawYear,minDate,maxDate,selectedDate,row>0||col>0,showStatus,initStatus,monthNames)+'<table class="ui-datepicker" cellpadding="0" cellspacing="0"><thead><tr class="ui-datepicker-title-row">'+(showWeeks?"<td"+this._addStatus(showStatus,inst.id,weekStatus,initStatus)+">"+this._get(inst,"weekHeader")+"</td>":"");for(var dow=0;dow<7;dow++){var day=(dow+firstDay)%7;var dayStatus=(status.indexOf("DD")>-1?status.replace(/DD/,dayNames[day]):status.replace(/D/,dayNamesShort[day]));html+="<td"+((dow+firstDay+6)%7>=5?' class="ui-datepicker-week-end-cell"':"")+">"+(!changeFirstDay?"<span":"<a onclick=\"jQuery.datepicker._changeFirstDay('#"+inst.id+"', "+day+');"')+this._addStatus(showStatus,inst.id,dayStatus,initStatus)+' title="'+dayNames[day]+'">'+dayNamesMin[day]+(changeFirstDay?"</a>":"</span>")+"</td>"}html+="</tr></thead><tbody>";var daysInMonth=this._getDaysInMonth(drawYear,drawMonth);if(drawYear==inst.selectedYear&&drawMonth==inst.selectedMonth){inst.selectedDay=Math.min(inst.selectedDay,daysInMonth)}var leadDays=(this._getFirstDayOfMonth(drawYear,drawMonth)-firstDay+7)%7;var tzDate=new Date(drawYear,drawMonth,1-leadDays);var utcDate=new Date(drawYear,drawMonth,1-leadDays);var printDate=utcDate;var numRows=(isMultiMonth?6:Math.ceil((leadDays+daysInMonth)/7));for(var dRow=0;dRow<numRows;dRow++){html+='<tr class="ui-datepicker-days-row">'+(showWeeks?'<td class="ui-datepicker-week-col"'+this._addStatus(showStatus,inst.id,weekStatus,initStatus)+">"+calculateWeek(printDate)+"</td>":"");for(var dow=0;dow<7;dow++){var daySettings=(beforeShowDay?beforeShowDay.apply((inst.input?inst.input[0]:null),[printDate]):[true,""]);var otherMonth=(printDate.getMonth()!=drawMonth);var unselectable=otherMonth||!daySettings[0]||(minDate&&printDate<minDate)||(maxDate&&printDate>maxDate);html+='<td class="ui-datepicker-days-cell'+((dow+firstDay+6)%7>=5?" ui-datepicker-week-end-cell":"")+(otherMonth?" ui-datepicker-other-month":"")+(printDate.getTime()==selectedDate.getTime()&&drawMonth==inst.selectedMonth?" ui-datepicker-days-cell-over":"")+(unselectable?" "+this._unselectableClass:"")+(otherMonth&&!showOtherMonths?"":" "+daySettings[1]+(printDate.getTime()>=currentDate.getTime()&&printDate.getTime()<=endDate.getTime()?" "+this._currentClass:"")+(printDate.getTime()==today.getTime()?" ui-datepicker-today":""))+'"'+((!otherMonth||showOtherMonths)&&daySettings[2]?' title="'+daySettings[2]+'"':"")+(unselectable?(highlightWeek?" onmouseover=\"jQuery(this).parent().addClass('ui-datepicker-week-over');\" onmouseout=\"jQuery(this).parent().removeClass('ui-datepicker-week-over');\"":""):" onmouseover=\"jQuery(this).addClass('ui-datepicker-days-cell-over')"+(highlightWeek?".parent().addClass('ui-datepicker-week-over')":"")+";"+(!showStatus||(otherMonth&&!showOtherMonths)?"":"jQuery('#ui-datepicker-status-"+inst.id+"').html('"+(dateStatus.apply((inst.input?inst.input[0]:null),[printDate,inst])||initStatus)+"');")+"\" onmouseout=\"jQuery(this).removeClass('ui-datepicker-days-cell-over')"+(highlightWeek?".parent().removeClass('ui-datepicker-week-over')":"")+";"+(!showStatus||(otherMonth&&!showOtherMonths)?"":"jQuery('#ui-datepicker-status-"+inst.id+"').html('"+initStatus+"');")+'" onclick="jQuery.datepicker._selectDay(\'#'+inst.id+"',"+drawMonth+","+drawYear+', this);"')+">"+(otherMonth?(showOtherMonths?printDate.getDate():"&#xa0;"):(unselectable?printDate.getDate():"<a>"+printDate.getDate()+"</a>"))+"</td>";tzDate.setDate(tzDate.getDate()+1);utcDate.setUTCDate(utcDate.getUTCDate()+1);printDate=(tzDate>utcDate?tzDate:utcDate)}html+="</tr>"}drawMonth++;if(drawMonth>11){drawMonth=0;drawYear++}html+="</tbody></table></div>"}}html+=(showStatus?'<div style="clear: both;"></div><div id="ui-datepicker-status-'+inst.id+'" class="ui-datepicker-status">'+initStatus+"</div>":"")+(!closeAtTop&&!inst.inline?controls:"")+'<div style="clear: both;"></div>'+($.browser.msie&&parseInt($.browser.version,10)<7&&!inst.inline?'<iframe src="javascript:false;" class="ui-datepicker-cover"></iframe>':"");return html},_generateMonthYearHeader:function(inst,drawMonth,drawYear,minDate,maxDate,selectedDate,secondary,showStatus,initStatus,monthNames){minDate=(inst.rangeStart&&minDate&&selectedDate<minDate?selectedDate:minDate);var showMonthAfterYear=this._get(inst,"showMonthAfterYear");var html='<div class="ui-datepicker-header">';var monthHtml="";if(secondary||!this._get(inst,"changeMonth")){monthHtml+=monthNames[drawMonth]+"&#xa0;"}else{var inMinYear=(minDate&&minDate.getFullYear()==drawYear);var inMaxYear=(maxDate&&maxDate.getFullYear()==drawYear);monthHtml+='<select class="ui-datepicker-new-month" onchange="jQuery.datepicker._selectMonthYear(\'#'+inst.id+"', this, 'M');\" onclick=\"jQuery.datepicker._clickMonthYear('#"+inst.id+"');\""+this._addStatus(showStatus,inst.id,this._get(inst,"monthStatus"),initStatus)+">";for(var month=0;month<12;month++){if((!inMinYear||month>=minDate.getMonth())&&(!inMaxYear||month<=maxDate.getMonth())){monthHtml+='<option value="'+month+'"'+(month==drawMonth?' selected="selected"':"")+">"+monthNames[month]+"</option>"}}monthHtml+="</select>"}if(!showMonthAfterYear){html+=monthHtml}if(secondary||!this._get(inst,"changeYear")){html+=drawYear}else{var years=this._get(inst,"yearRange").split(":");var year=0;var endYear=0;if(years.length!=2){year=drawYear-10;endYear=drawYear+10}else{if(years[0].charAt(0)=="+"||years[0].charAt(0)=="-"){year=endYear=new Date().getFullYear();year+=parseInt(years[0],10);endYear+=parseInt(years[1],10)}else{year=parseInt(years[0],10);endYear=parseInt(years[1],10)}}year=(minDate?Math.max(year,minDate.getFullYear()):year);endYear=(maxDate?Math.min(endYear,maxDate.getFullYear()):endYear);html+='<select class="ui-datepicker-new-year" onchange="jQuery.datepicker._selectMonthYear(\'#'+inst.id+"', this, 'Y');\" onclick=\"jQuery.datepicker._clickMonthYear('#"+inst.id+"');\""+this._addStatus(showStatus,inst.id,this._get(inst,"yearStatus"),initStatus)+">";for(;year<=endYear;year++){html+='<option value="'+year+'"'+(year==drawYear?' selected="selected"':"")+">"+year+"</option>"}html+="</select>"}if(showMonthAfterYear){html+=monthHtml}html+="</div>";return html},_addStatus:function(showStatus,id,text,initStatus){return(showStatus?" onmouseover=\"jQuery('#ui-datepicker-status-"+id+"').html('"+(text||initStatus)+"');\" onmouseout=\"jQuery('#ui-datepicker-status-"+id+"').html('"+initStatus+"');\"":"")},_adjustInstDate:function(inst,offset,period){var year=inst.drawYear+(period=="Y"?offset:0);var month=inst.drawMonth+(period=="M"?offset:0);var day=Math.min(inst.selectedDay,this._getDaysInMonth(year,month))+(period=="D"?offset:0);var date=new Date(year,month,day);var minDate=this._getMinMaxDate(inst,"min",true);var maxDate=this._getMinMaxDate(inst,"max");date=(minDate&&date<minDate?minDate:date);date=(maxDate&&date>maxDate?maxDate:date);inst.selectedDay=date.getDate();inst.drawMonth=inst.selectedMonth=date.getMonth();inst.drawYear=inst.selectedYear=date.getFullYear();if(period=="M"||period=="Y"){this._notifyChange(inst)}},_notifyChange:function(inst){var onChange=this._get(inst,"onChangeMonthYear");if(onChange){onChange.apply((inst.input?inst.input[0]:null),[inst.selectedYear,inst.selectedMonth+1,inst])}},_getNumberOfMonths:function(inst){var numMonths=this._get(inst,"numberOfMonths");return(numMonths==null?[1,1]:(typeof numMonths=="number"?[1,numMonths]:numMonths))},_getMinMaxDate:function(inst,minMax,checkRange){var date=this._determineDate(this._get(inst,minMax+"Date"),null);if(date){date.setHours(0);date.setMinutes(0);date.setSeconds(0);date.setMilliseconds(0)}return(!checkRange||!inst.rangeStart?date:(!date||inst.rangeStart>date?inst.rangeStart:date))},_getDaysInMonth:function(year,month){return 32-new Date(year,month,32).getDate()},_getFirstDayOfMonth:function(year,month){return new Date(year,month,1).getDay()},_canAdjustMonth:function(inst,offset,curYear,curMonth){var numMonths=this._getNumberOfMonths(inst);var date=new Date(curYear,curMonth+(offset<0?offset:numMonths[1]),1);if(offset<0){date.setDate(this._getDaysInMonth(date.getFullYear(),date.getMonth()))}return this._isInRange(inst,date)},_isInRange:function(inst,date){var newMinDate=(!inst.rangeStart?null:new Date(inst.selectedYear,inst.selectedMonth,inst.selectedDay));newMinDate=(newMinDate&&inst.rangeStart<newMinDate?inst.rangeStart:newMinDate);var minDate=newMinDate||this._getMinMaxDate(inst,"min");var maxDate=this._getMinMaxDate(inst,"max");return((!minDate||date>=minDate)&&(!maxDate||date<=maxDate))},_getFormatConfig:function(inst){var shortYearCutoff=this._get(inst,"shortYearCutoff");shortYearCutoff=(typeof shortYearCutoff!="string"?shortYearCutoff:new Date().getFullYear()%100+parseInt(shortYearCutoff,10));return{shortYearCutoff:shortYearCutoff,dayNamesShort:this._get(inst,"dayNamesShort"),dayNames:this._get(inst,"dayNames"),monthNamesShort:this._get(inst,"monthNamesShort"),monthNames:this._get(inst,"monthNames")}},_formatDate:function(inst,day,month,year){if(!day){inst.currentDay=inst.selectedDay;inst.currentMonth=inst.selectedMonth;inst.currentYear=inst.selectedYear}var date=(day?(typeof day=="object"?day:new Date(year,month,day)):new Date(inst.currentYear,inst.currentMonth,inst.currentDay));return this.formatDate(this._get(inst,"dateFormat"),date,this._getFormatConfig(inst))}});function extendRemove(target,props){$.extend(target,props);for(var name in props){if(props[name]==null||props[name]==undefined){target[name]=props[name]}}return target}function isArray(a){return(a&&(($.browser.safari&&typeof a=="object"&&a.length)||(a.constructor&&a.constructor.toString().match(/\Array\(\)/))))}$.fn.datepicker=function(options){if(!$.datepicker.initialized){$(document.body).append($.datepicker.dpDiv).mousedown($.datepicker._checkExternalClick);$.datepicker.initialized=true}var otherArgs=Array.prototype.slice.call(arguments,1);if(typeof options=="string"&&(options=="isDisabled"||options=="getDate")){return $.datepicker["_"+options+"Datepicker"].apply($.datepicker,[this[0]].concat(otherArgs))}return this.each(function(){typeof options=="string"?$.datepicker["_"+options+"Datepicker"].apply($.datepicker,[this].concat(otherArgs)):$.datepicker._attachDatepicker(this,options)})};$.datepicker=new Datepicker();$.datepicker.initialized=false;$.datepicker.uuid=new Date().getTime()})(jQuery) \ No newline at end of file
diff --git a/site/app/webroot/js/jquery-ui/ui.dialog.min.js b/site/app/webroot/js/jquery-ui/ui.dialog.min.js
new file mode 100755
index 0000000..b671e05
--- /dev/null
+++ b/site/app/webroot/js/jquery-ui/ui.dialog.min.js
@@ -0,0 +1 @@
+(function(B){var A={dragStart:"start.draggable",drag:"drag.draggable",dragStop:"stop.draggable",maxHeight:"maxHeight.resizable",minHeight:"minHeight.resizable",maxWidth:"maxWidth.resizable",minWidth:"minWidth.resizable",resizeStart:"start.resizable",resize:"drag.resizable",resizeStop:"stop.resizable"};B.widget("ui.dialog",{_init:function(){this.originalTitle=this.element.attr("title");this.options.title=this.options.title||this.originalTitle;var K=this,L=this.options,F=this.element.removeAttr("title").addClass("ui-dialog-content").wrap("<div/>").wrap("<div/>"),H=(this.uiDialogContainer=F.parent()).addClass("ui-dialog-container").css({position:"relative",width:"100%",height:"100%"}),E=(this.uiDialogTitlebar=B("<div/>")).addClass("ui-dialog-titlebar").append('<a href="#" class="ui-dialog-titlebar-close"><span>X</span></a>').prependTo(H),J=L.title||"&nbsp;",C=B.ui.dialog.getTitleId(this.element),D=B("<span/>").addClass("ui-dialog-title").attr("id",C).html(J).prependTo(E),I=(this.uiDialog=H.parent()).appendTo(document.body).hide().addClass("ui-dialog").addClass(L.dialogClass).addClass(F.attr("className")).removeClass("ui-dialog-content").css({position:"absolute",width:L.width,height:L.height,overflow:"hidden",zIndex:L.zIndex}).attr("tabIndex",-1).css("outline",0).keydown(function(M){(L.closeOnEscape&&M.keyCode&&M.keyCode==B.keyCode.ESCAPE&&K.close())}).mousedown(function(){K._moveToTop()}),G=(this.uiDialogButtonPane=B("<div/>")).addClass("ui-dialog-buttonpane").css({position:"absolute",bottom:0}).appendTo(I);this.uiDialogTitlebarClose=B(".ui-dialog-titlebar-close",E).hover(function(){B(this).addClass("ui-dialog-titlebar-close-hover")},function(){B(this).removeClass("ui-dialog-titlebar-close-hover")}).mousedown(function(M){M.stopPropagation()}).click(function(){K.close();return false});E.find("*").add(E).each(function(){B.ui.disableSelection(this)});(L.draggable&&B.fn.draggable&&this._makeDraggable());(L.resizable&&B.fn.resizable&&this._makeResizable());this._createButtons(L.buttons);this._isOpen=false;(L.bgiframe&&B.fn.bgiframe&&I.bgiframe());(L.autoOpen&&this.open())},destroy:function(){(this.overlay&&this.overlay.destroy());this.uiDialog.hide();this.element.unbind(".dialog").removeData("dialog").removeClass("ui-dialog-content").hide().appendTo("body");this.uiDialog.remove();(this.originalTitle&&this.element.attr("title",this.originalTitle))},close:function(){if(false===this._trigger("beforeclose",null,{options:this.options})){return }(this.overlay&&this.overlay.destroy());this.uiDialog.hide(this.options.hide).unbind("keypress.ui-dialog");this._trigger("close",null,{options:this.options});B.ui.dialog.overlay.resize();this._isOpen=false},isOpen:function(){return this._isOpen},open:function(){if(this._isOpen){return }this.overlay=this.options.modal?new B.ui.dialog.overlay(this):null;(this.uiDialog.next().length&&this.uiDialog.appendTo("body"));this._position(this.options.position);this.uiDialog.show(this.options.show);(this.options.autoResize&&this._size());this._moveToTop(true);(this.options.modal&&this.uiDialog.bind("keypress.ui-dialog",function(E){if(E.keyCode!=B.keyCode.TAB){return }var D=B(":tabbable",this),F=D.filter(":first")[0],C=D.filter(":last")[0];if(E.target==C&&!E.shiftKey){setTimeout(function(){F.focus()},1)}else{if(E.target==F&&E.shiftKey){setTimeout(function(){C.focus()},1)}}}));this.uiDialog.find(":tabbable:first").focus();this._trigger("open",null,{options:this.options});this._isOpen=true},_createButtons:function(F){var E=this,C=false,D=this.uiDialogButtonPane;D.empty().hide();B.each(F,function(){return !(C=true)});if(C){D.show();B.each(F,function(G,H){B('<button type="button"></button>').text(G).click(function(){H.apply(E.element[0],arguments)}).appendTo(D)})}},_makeDraggable:function(){var C=this,D=this.options;this.uiDialog.draggable({cancel:".ui-dialog-content",helper:D.dragHelper,handle:".ui-dialog-titlebar",start:function(){C._moveToTop();(D.dragStart&&D.dragStart.apply(C.element[0],arguments))},drag:function(){(D.drag&&D.drag.apply(C.element[0],arguments))},stop:function(){(D.dragStop&&D.dragStop.apply(C.element[0],arguments));B.ui.dialog.overlay.resize()}})},_makeResizable:function(F){F=(F===undefined?this.options.resizable:F);var C=this,E=this.options,D=typeof F=="string"?F:"n,e,s,w,se,sw,ne,nw";this.uiDialog.resizable({cancel:".ui-dialog-content",helper:E.resizeHelper,maxWidth:E.maxWidth,maxHeight:E.maxHeight,minWidth:E.minWidth,minHeight:E.minHeight,start:function(){(E.resizeStart&&E.resizeStart.apply(C.element[0],arguments))},resize:function(){(E.autoResize&&C._size.apply(C));(E.resize&&E.resize.apply(C.element[0],arguments))},handles:D,stop:function(){(E.autoResize&&C._size.apply(C));(E.resizeStop&&E.resizeStop.apply(C.element[0],arguments));B.ui.dialog.overlay.resize()}})},_moveToTop:function(E){if((this.options.modal&&!E)||(!this.options.stack&&!this.options.modal)){return this._trigger("focus",null,{options:this.options})}var D=this.options.zIndex,C=this.options;B(".ui-dialog:visible").each(function(){D=Math.max(D,parseInt(B(this).css("z-index"),10)||C.zIndex)});(this.overlay&&this.overlay.$el.css("z-index",++D));this.uiDialog.css("z-index",++D);this._trigger("focus",null,{options:this.options})},_position:function(H){var D=B(window),E=B(document),F=E.scrollTop(),C=E.scrollLeft(),G=F;if(B.inArray(H,["center","top","right","bottom","left"])>=0){H=[H=="right"||H=="left"?H:"center",H=="top"||H=="bottom"?H:"middle"]}if(H.constructor!=Array){H=["center","middle"]}if(H[0].constructor==Number){C+=H[0]}else{switch(H[0]){case"left":C+=0;break;case"right":C+=D.width()-this.uiDialog.width();break;default:case"center":C+=(D.width()-this.uiDialog.width())/2}}if(H[1].constructor==Number){F+=H[1]}else{switch(H[1]){case"top":F+=0;break;case"bottom":F+=D.height()-this.uiDialog.height();break;default:case"middle":F+=(D.height()-this.uiDialog.height())/2}}F=Math.max(F,G);this.uiDialog.css({top:F,left:C})},_setData:function(D,E){(A[D]&&this.uiDialog.data(A[D],E));switch(D){case"buttons":this._createButtons(E);break;case"draggable":(E?this._makeDraggable():this.uiDialog.draggable("destroy"));break;case"height":this.uiDialog.height(E);break;case"position":this._position(E);break;case"resizable":var C=this.uiDialog,F=this.uiDialog.is(":data(resizable)");(F&&!E&&C.resizable("destroy"));(F&&typeof E=="string"&&C.resizable("option","handles",E));(F||this._makeResizable(E));break;case"title":B(".ui-dialog-title",this.uiDialogTitlebar).html(E||"&nbsp;");break;case"width":this.uiDialog.width(E);break}B.widget.prototype._setData.apply(this,arguments)},_size:function(){var D=this.uiDialogContainer,G=this.uiDialogTitlebar,E=this.element,F=(parseInt(E.css("margin-top"),10)||0)+(parseInt(E.css("margin-bottom"),10)||0),C=(parseInt(E.css("margin-left"),10)||0)+(parseInt(E.css("margin-right"),10)||0);E.height(D.height()-G.outerHeight()-F);E.width(D.width()-C)}});B.extend(B.ui.dialog,{defaults:{autoOpen:true,autoResize:true,bgiframe:false,buttons:{},closeOnEscape:true,draggable:true,height:200,minHeight:100,minWidth:150,modal:false,overlay:{},position:"center",resizable:true,stack:true,width:300,zIndex:1000},getter:"isOpen",uuid:0,getTitleId:function(C){return"ui-dialog-title-"+(C.attr("id")||++this.uuid)},overlay:function(C){this.$el=B.ui.dialog.overlay.create(C)}});B.extend(B.ui.dialog.overlay,{instances:[],events:B.map("focus,mousedown,mouseup,keydown,keypress,click".split(","),function(C){return C+".dialog-overlay"}).join(" "),create:function(D){if(this.instances.length===0){setTimeout(function(){B("a, :input").bind(B.ui.dialog.overlay.events,function(){var F=false;var H=B(this).parents(".ui-dialog");if(H.length){var E=B(".ui-dialog-overlay");if(E.length){var G=parseInt(E.css("z-index"),10);E.each(function(){G=Math.max(G,parseInt(B(this).css("z-index"),10))});F=parseInt(H.css("z-index"),10)>G}else{F=true}}return F})},1);B(document).bind("keydown.dialog-overlay",function(E){(D.options.closeOnEscape&&E.keyCode&&E.keyCode==B.keyCode.ESCAPE&&D.close())});B(window).bind("resize.dialog-overlay",B.ui.dialog.overlay.resize)}var C=B("<div/>").appendTo(document.body).addClass("ui-dialog-overlay").css(B.extend({borderWidth:0,margin:0,padding:0,position:"absolute",top:0,left:0,width:this.width(),height:this.height()},D.options.overlay));(D.options.bgiframe&&B.fn.bgiframe&&C.bgiframe());this.instances.push(C);return C},destroy:function(C){this.instances.splice(B.inArray(this.instances,C),1);if(this.instances.length===0){B("a, :input").add([document,window]).unbind(".dialog-overlay")}C.remove()},height:function(){if(B.browser.msie&&B.browser.version<7){var D=Math.max(document.documentElement.scrollHeight,document.body.scrollHeight);var C=Math.max(document.documentElement.offsetHeight,document.body.offsetHeight);if(D<C){return B(window).height()+"px"}else{return D+"px"}}else{if(B.browser.opera){return Math.max(window.innerHeight,B(document).height())+"px"}else{return B(document).height()+"px"}}},width:function(){if(B.browser.msie&&B.browser.version<7){var C=Math.max(document.documentElement.scrollWidth,document.body.scrollWidth);var D=Math.max(document.documentElement.offsetWidth,document.body.offsetWidth);if(C<D){return B(window).width()+"px"}else{return C+"px"}}else{if(B.browser.opera){return Math.max(window.innerWidth,B(document).width())+"px"}else{return B(document).width()+"px"}}},resize:function(){var C=B([]);B.each(B.ui.dialog.overlay.instances,function(){C=C.add(this)});C.css({width:0,height:0}).css({width:B.ui.dialog.overlay.width(),height:B.ui.dialog.overlay.height()})}});B.extend(B.ui.dialog.overlay.prototype,{destroy:function(){B.ui.dialog.overlay.destroy(this.$el)}})})(jQuery) \ No newline at end of file
diff --git a/site/app/webroot/js/jquery-ui/ui.draggable.min.js b/site/app/webroot/js/jquery-ui/ui.draggable.min.js
new file mode 100755
index 0000000..b9497d1
--- /dev/null
+++ b/site/app/webroot/js/jquery-ui/ui.draggable.min.js
@@ -0,0 +1 @@
+(function(A){A.widget("ui.draggable",A.extend({},A.ui.mouse,{getHandle:function(C){var B=!this.options.handle||!A(this.options.handle,this.element).length?true:false;A(this.options.handle,this.element).find("*").andSelf().each(function(){if(this==C.target){B=true}});return B},createHelper:function(){var C=this.options;var B=A.isFunction(C.helper)?A(C.helper.apply(this.element[0],[e])):(C.helper=="clone"?this.element.clone():this.element);if(!B.parents("body").length){B.appendTo((C.appendTo=="parent"?this.element[0].parentNode:C.appendTo))}if(B[0]!=this.element[0]&&!(/(fixed|absolute)/).test(B.css("position"))){B.css("position","absolute")}return B},_init:function(){if(this.options.helper=="original"&&!(/^(?:r|a|f)/).test(this.element.css("position"))){this.element[0].style.position="relative"}(this.options.cssNamespace&&this.element.addClass(this.options.cssNamespace+"-draggable"));(this.options.disabled&&this.element.addClass("ui-draggable-disabled"));this._mouseInit()},_mouseCapture:function(B){var C=this.options;if(this.helper||C.disabled||A(B.target).is(".ui-resizable-handle")){return false}this.handle=this.getHandle(B);if(!this.handle){return false}return true},_mouseStart:function(D){var E=this.options;this.helper=this.createHelper();if(A.ui.ddmanager){A.ui.ddmanager.current=this}this.margins={left:(parseInt(this.element.css("marginLeft"),10)||0),top:(parseInt(this.element.css("marginTop"),10)||0)};this.cssPosition=this.helper.css("position");this.offset=this.element.offset();this.offset={top:this.offset.top-this.margins.top,left:this.offset.left-this.margins.left};this.offset.click={left:D.pageX-this.offset.left,top:D.pageY-this.offset.top};this.cacheScrollParents();this.offsetParent=this.helper.offsetParent();var B=this.offsetParent.offset();if(this.offsetParent[0]==document.body&&A.browser.mozilla){B={top:0,left:0}}this.offset.parent={top:B.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:B.left+(parseInt(this.offsetParent.css("borderLeftWidth"),10)||0)};if(this.cssPosition=="relative"){var C=this.element.position();this.offset.relative={top:C.top-(parseInt(this.helper.css("top"),10)||0)+this.scrollTopParent.scrollTop(),left:C.left-(parseInt(this.helper.css("left"),10)||0)+this.scrollLeftParent.scrollLeft()}}else{this.offset.relative={top:0,left:0}}this.originalPosition=this._generatePosition(D);this.cacheHelperProportions();if(E.cursorAt){this.adjustOffsetFromHelper(E.cursorAt)}A.extend(this,{PAGEY_INCLUDES_SCROLL:(this.cssPosition=="absolute"&&(!this.scrollTopParent[0].tagName||(/(html|body)/i).test(this.scrollTopParent[0].tagName))),PAGEX_INCLUDES_SCROLL:(this.cssPosition=="absolute"&&(!this.scrollLeftParent[0].tagName||(/(html|body)/i).test(this.scrollLeftParent[0].tagName))),OFFSET_PARENT_NOT_SCROLL_PARENT_Y:this.scrollTopParent[0]!=this.offsetParent[0]&&!(this.scrollTopParent[0]==document&&(/(body|html)/i).test(this.offsetParent[0].tagName)),OFFSET_PARENT_NOT_SCROLL_PARENT_X:this.scrollLeftParent[0]!=this.offsetParent[0]&&!(this.scrollLeftParent[0]==document&&(/(body|html)/i).test(this.offsetParent[0].tagName))});if(E.containment){this.setContainment()}this._propagate("start",D);this.cacheHelperProportions();if(A.ui.ddmanager&&!E.dropBehaviour){A.ui.ddmanager.prepareOffsets(this,D)}this.helper.addClass("ui-draggable-dragging");this._mouseDrag(D);return true},cacheScrollParents:function(){this.scrollTopParent=function(B){do{if(/auto|scroll/.test(B.css("overflow"))||(/auto|scroll/).test(B.css("overflow-y"))){return B}B=B.parent()}while(B[0].parentNode);return A(document)}(this.helper);this.scrollLeftParent=function(B){do{if(/auto|scroll/.test(B.css("overflow"))||(/auto|scroll/).test(B.css("overflow-x"))){return B}B=B.parent()}while(B[0].parentNode);return A(document)}(this.helper)},adjustOffsetFromHelper:function(B){if(B.left!=undefined){this.offset.click.left=B.left+this.margins.left}if(B.right!=undefined){this.offset.click.left=this.helperProportions.width-B.right+this.margins.left}if(B.top!=undefined){this.offset.click.top=B.top+this.margins.top}if(B.bottom!=undefined){this.offset.click.top=this.helperProportions.height-B.bottom+this.margins.top}},cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(),height:this.helper.outerHeight()}},setContainment:function(){var E=this.options;if(E.containment=="parent"){E.containment=this.helper[0].parentNode}if(E.containment=="document"||E.containment=="window"){this.containment=[0-this.offset.relative.left-this.offset.parent.left,0-this.offset.relative.top-this.offset.parent.top,A(E.containment=="document"?document:window).width()-this.offset.relative.left-this.offset.parent.left-this.helperProportions.width-this.margins.left-(parseInt(this.element.css("marginRight"),10)||0),(A(E.containment=="document"?document:window).height()||document.body.parentNode.scrollHeight)-this.offset.relative.top-this.offset.parent.top-this.helperProportions.height-this.margins.top-(parseInt(this.element.css("marginBottom"),10)||0)]}if(!(/^(document|window|parent)$/).test(E.containment)){var C=A(E.containment)[0];var D=A(E.containment).offset();var B=(A(C).css("overflow")!="hidden");this.containment=[D.left+(parseInt(A(C).css("borderLeftWidth"),10)||0)-this.offset.relative.left-this.offset.parent.left,D.top+(parseInt(A(C).css("borderTopWidth"),10)||0)-this.offset.relative.top-this.offset.parent.top,D.left+(B?Math.max(C.scrollWidth,C.offsetWidth):C.offsetWidth)-(parseInt(A(C).css("borderLeftWidth"),10)||0)-this.offset.relative.left-this.offset.parent.left-this.helperProportions.width-this.margins.left-(parseInt(this.element.css("marginRight"),10)||0),D.top+(B?Math.max(C.scrollHeight,C.offsetHeight):C.offsetHeight)-(parseInt(A(C).css("borderTopWidth"),10)||0)-this.offset.relative.top-this.offset.parent.top-this.helperProportions.height-this.margins.top-(parseInt(this.element.css("marginBottom"),10)||0)]}},_convertPositionTo:function(C,D){if(!D){D=this.position}var B=C=="absolute"?1:-1;return{top:(D.top+this.offset.relative.top*B+this.offset.parent.top*B-(this.cssPosition=="fixed"||this.PAGEY_INCLUDES_SCROLL||this.OFFSET_PARENT_NOT_SCROLL_PARENT_Y?0:this.scrollTopParent.scrollTop())*B+(this.cssPosition=="fixed"?A(document).scrollTop():0)*B+this.margins.top*B),left:(D.left+this.offset.relative.left*B+this.offset.parent.left*B-(this.cssPosition=="fixed"||this.PAGEX_INCLUDES_SCROLL||this.OFFSET_PARENT_NOT_SCROLL_PARENT_X?0:this.scrollLeftParent.scrollLeft())*B+(this.cssPosition=="fixed"?A(document).scrollLeft():0)*B+this.margins.left*B)}},_generatePosition:function(E){var F=this.options;var B={top:(E.pageY-this.offset.click.top-this.offset.relative.top-this.offset.parent.top+(this.cssPosition=="fixed"||this.PAGEY_INCLUDES_SCROLL||this.OFFSET_PARENT_NOT_SCROLL_PARENT_Y?0:this.scrollTopParent.scrollTop())-(this.cssPosition=="fixed"?A(document).scrollTop():0)),left:(E.pageX-this.offset.click.left-this.offset.relative.left-this.offset.parent.left+(this.cssPosition=="fixed"||this.PAGEX_INCLUDES_SCROLL||this.OFFSET_PARENT_NOT_SCROLL_PARENT_X?0:this.scrollLeftParent.scrollLeft())-(this.cssPosition=="fixed"?A(document).scrollLeft():0))};if(!this.originalPosition){return B}if(this.containment){if(B.left<this.containment[0]){B.left=this.containment[0]}if(B.top<this.containment[1]){B.top=this.containment[1]}if(B.left>this.containment[2]){B.left=this.containment[2]}if(B.top>this.containment[3]){B.top=this.containment[3]}}if(F.grid){var D=this.originalPosition.top+Math.round((B.top-this.originalPosition.top)/F.grid[1])*F.grid[1];B.top=this.containment?(!(D<this.containment[1]||D>this.containment[3])?D:(!(D<this.containment[1])?D-F.grid[1]:D+F.grid[1])):D;var C=this.originalPosition.left+Math.round((B.left-this.originalPosition.left)/F.grid[0])*F.grid[0];B.left=this.containment?(!(C<this.containment[0]||C>this.containment[2])?C:(!(C<this.containment[0])?C-F.grid[0]:C+F.grid[0])):C}return B},_mouseDrag:function(B){this.position=this._generatePosition(B);this.positionAbs=this._convertPositionTo("absolute");this.position=this._propagate("drag",B)||this.position;if(!this.options.axis||this.options.axis!="y"){this.helper[0].style.left=this.position.left+"px"}if(!this.options.axis||this.options.axis!="x"){this.helper[0].style.top=this.position.top+"px"}if(A.ui.ddmanager){A.ui.ddmanager.drag(this,B)}return false},_mouseStop:function(C){var D=false;if(A.ui.ddmanager&&!this.options.dropBehaviour){var D=A.ui.ddmanager.drop(this,C)}if((this.options.revert=="invalid"&&!D)||(this.options.revert=="valid"&&D)||this.options.revert===true||(A.isFunction(this.options.revert)&&this.options.revert.call(this.element,D))){var B=this;A(this.helper).animate(this.originalPosition,parseInt(this.options.revertDuration,10)||500,function(){B._propagate("stop",C);B._clear()})}else{this._propagate("stop",C);this._clear()}return false},_clear:function(){this.helper.removeClass("ui-draggable-dragging");if(this.options.helper!="original"&&!this.cancelHelperRemoval){this.helper.remove()}this.helper=null;this.cancelHelperRemoval=false},plugins:{},uiHash:function(B){return{helper:this.helper,position:this.position,absolutePosition:this.positionAbs,options:this.options}},_propagate:function(C,B){A.ui.plugin.call(this,C,[B,this.uiHash()]);if(C=="drag"){this.positionAbs=this._convertPositionTo("absolute")}return this.element.triggerHandler(C=="drag"?C:"drag"+C,[B,this.uiHash()],this.options[C])},destroy:function(){if(!this.element.data("draggable")){return }this.element.removeData("draggable").unbind(".draggable").removeClass("ui-draggable ui-draggable-dragging ui-draggable-disabled");this._mouseDestroy()}}));A.extend(A.ui.draggable,{defaults:{appendTo:"parent",axis:false,cancel:":input",delay:0,distance:1,helper:"original",scope:"default",cssNamespace:"ui"}});A.ui.plugin.add("draggable","cursor",{start:function(D,C){var B=A("body");if(B.css("cursor")){C.options._cursor=B.css("cursor")}B.css("cursor",C.options.cursor)},stop:function(C,B){if(B.options._cursor){A("body").css("cursor",B.options._cursor)}}});A.ui.plugin.add("draggable","zIndex",{start:function(D,C){var B=A(C.helper);if(B.css("zIndex")){C.options._zIndex=B.css("zIndex")}B.css("zIndex",C.options.zIndex)},stop:function(C,B){if(B.options._zIndex){A(B.helper).css("zIndex",B.options._zIndex)}}});A.ui.plugin.add("draggable","opacity",{start:function(D,C){var B=A(C.helper);if(B.css("opacity")){C.options._opacity=B.css("opacity")}B.css("opacity",C.options.opacity)},stop:function(C,B){if(B.options._opacity){A(B.helper).css("opacity",B.options._opacity)}}});A.ui.plugin.add("draggable","iframeFix",{start:function(C,B){A(B.options.iframeFix===true?"iframe":B.options.iframeFix).each(function(){A('<div class="ui-draggable-iframeFix" style="background: #fff;"></div>').css({width:this.offsetWidth+"px",height:this.offsetHeight+"px",position:"absolute",opacity:"0.001",zIndex:1000}).css(A(this).offset()).appendTo("body")})},stop:function(C,B){A("div.ui-draggable-iframeFix").each(function(){this.parentNode.removeChild(this)})}});A.ui.plugin.add("draggable","scroll",{start:function(D,C){var E=C.options;var B=A(this).data("draggable");E.scrollSensitivity=E.scrollSensitivity||20;E.scrollSpeed=E.scrollSpeed||20;B.overflowY=function(F){do{if(/auto|scroll/.test(F.css("overflow"))||(/auto|scroll/).test(F.css("overflow-y"))){return F}F=F.parent()}while(F[0].parentNode);return A(document)}(this);B.overflowX=function(F){do{if(/auto|scroll/.test(F.css("overflow"))||(/auto|scroll/).test(F.css("overflow-x"))){return F}F=F.parent()}while(F[0].parentNode);return A(document)}(this);if(B.overflowY[0]!=document&&B.overflowY[0].tagName!="HTML"){B.overflowYOffset=B.overflowY.offset()}if(B.overflowX[0]!=document&&B.overflowX[0].tagName!="HTML"){B.overflowXOffset=B.overflowX.offset()}},drag:function(E,D){var F=D.options,B=false;var C=A(this).data("draggable");if(C.overflowY[0]!=document&&C.overflowY[0].tagName!="HTML"){if((C.overflowYOffset.top+C.overflowY[0].offsetHeight)-E.pageY<F.scrollSensitivity){C.overflowY[0].scrollTop=B=C.overflowY[0].scrollTop+F.scrollSpeed}if(E.pageY-C.overflowYOffset.top<F.scrollSensitivity){C.overflowY[0].scrollTop=B=C.overflowY[0].scrollTop-F.scrollSpeed}}else{if(E.pageY-A(document).scrollTop()<F.scrollSensitivity){B=A(document).scrollTop(A(document).scrollTop()-F.scrollSpeed)}if(A(window).height()-(E.pageY-A(document).scrollTop())<F.scrollSensitivity){B=A(document).scrollTop(A(document).scrollTop()+F.scrollSpeed)}}if(C.overflowX[0]!=document&&C.overflowX[0].tagName!="HTML"){if((C.overflowXOffset.left+C.overflowX[0].offsetWidth)-E.pageX<F.scrollSensitivity){C.overflowX[0].scrollLeft=B=C.overflowX[0].scrollLeft+F.scrollSpeed}if(E.pageX-C.overflowXOffset.left<F.scrollSensitivity){C.overflowX[0].scrollLeft=B=C.overflowX[0].scrollLeft-F.scrollSpeed}}else{if(E.pageX-A(document).scrollLeft()<F.scrollSensitivity){B=A(document).scrollLeft(A(document).scrollLeft()-F.scrollSpeed)}if(A(window).width()-(E.pageX-A(document).scrollLeft())<F.scrollSensitivity){B=A(document).scrollLeft(A(document).scrollLeft()+F.scrollSpeed)}}if(B!==false){A.ui.ddmanager.prepareOffsets(C,E)}}});A.ui.plugin.add("draggable","snap",{start:function(D,C){var B=A(this).data("draggable");B.snapElements=[];A(C.options.snap.constructor!=String?(C.options.snap.items||":data(draggable)"):C.options.snap).each(function(){var F=A(this);var E=F.offset();if(this!=B.element[0]){B.snapElements.push({item:this,width:F.outerWidth(),height:F.outerHeight(),top:E.top,left:E.left})}})},drag:function(P,K){var E=A(this).data("draggable");var Q=K.options.snapTolerance||20;var O=K.absolutePosition.left,N=O+E.helperProportions.width,D=K.absolutePosition.top,C=D+E.helperProportions.height;for(var M=E.snapElements.length-1;M>=0;M--){var L=E.snapElements[M].left,J=L+E.snapElements[M].width,I=E.snapElements[M].top,S=I+E.snapElements[M].height;if(!((L-Q<O&&O<J+Q&&I-Q<D&&D<S+Q)||(L-Q<O&&O<J+Q&&I-Q<C&&C<S+Q)||(L-Q<N&&N<J+Q&&I-Q<D&&D<S+Q)||(L-Q<N&&N<J+Q&&I-Q<C&&C<S+Q))){if(E.snapElements[M].snapping){(E.options.snap.release&&E.options.snap.release.call(E.element,null,A.extend(E.uiHash(),{snapItem:E.snapElements[M].item})))}E.snapElements[M].snapping=false;continue}if(K.options.snapMode!="inner"){var B=Math.abs(I-C)<=Q;var R=Math.abs(S-D)<=Q;var G=Math.abs(L-N)<=Q;var H=Math.abs(J-O)<=Q;if(B){K.position.top=E._convertPositionTo("relative",{top:I-E.helperProportions.height,left:0}).top}if(R){K.position.top=E._convertPositionTo("relative",{top:S,left:0}).top}if(G){K.position.left=E._convertPositionTo("relative",{top:0,left:L-E.helperProportions.width}).left}if(H){K.position.left=E._convertPositionTo("relative",{top:0,left:J}).left}}var F=(B||R||G||H);if(K.options.snapMode!="outer"){var B=Math.abs(I-D)<=Q;var R=Math.abs(S-C)<=Q;var G=Math.abs(L-O)<=Q;var H=Math.abs(J-N)<=Q;if(B){K.position.top=E._convertPositionTo("relative",{top:I,left:0}).top}if(R){K.position.top=E._convertPositionTo("relative",{top:S-E.helperProportions.height,left:0}).top}if(G){K.position.left=E._convertPositionTo("relative",{top:0,left:L}).left}if(H){K.position.left=E._convertPositionTo("relative",{top:0,left:J-E.helperProportions.width}).left}}if(!E.snapElements[M].snapping&&(B||R||G||H||F)){(E.options.snap.snap&&E.options.snap.snap.call(E.element,null,A.extend(E.uiHash(),{snapItem:E.snapElements[M].item})))}E.snapElements[M].snapping=(B||R||G||H||F)}}});A.ui.plugin.add("draggable","connectToSortable",{start:function(D,C){var B=A(this).data("draggable");B.sortables=[];A(C.options.connectToSortable).each(function(){if(A.data(this,"sortable")){var E=A.data(this,"sortable");B.sortables.push({instance:E,shouldRevert:E.options.revert});E._refreshItems();E._propagate("activate",D,B)}})},stop:function(D,C){var B=A(this).data("draggable");A.each(B.sortables,function(){if(this.instance.isOver){this.instance.isOver=0;B.cancelHelperRemoval=true;this.instance.cancelHelperRemoval=false;if(this.shouldRevert){this.instance.options.revert=true}this.instance._mouseStop(D);this.instance.element.triggerHandler("sortreceive",[D,A.extend(this.instance.ui(),{sender:B.element})],this.instance.options["receive"]);this.instance.options.helper=this.instance.options._helper}else{this.instance._propagate("deactivate",D,B)}})},drag:function(F,E){var D=A(this).data("draggable"),B=this;var C=function(K){var H=K.left,J=H+K.width,I=K.top,G=I+K.height;return(H<(this.positionAbs.left+this.offset.click.left)&&(this.positionAbs.left+this.offset.click.left)<J&&I<(this.positionAbs.top+this.offset.click.top)&&(this.positionAbs.top+this.offset.click.top)<G)};A.each(D.sortables,function(G){if(C.call(D,this.instance.containerCache)){if(!this.instance.isOver){this.instance.isOver=1;this.instance.currentItem=A(B).clone().appendTo(this.instance.element).data("sortable-item",true);this.instance.options._helper=this.instance.options.helper;this.instance.options.helper=function(){return E.helper[0]};F.target=this.instance.currentItem[0];this.instance._mouseCapture(F,true);this.instance._mouseStart(F,true,true);this.instance.offset.click.top=D.offset.click.top;this.instance.offset.click.left=D.offset.click.left;this.instance.offset.parent.left-=D.offset.parent.left-this.instance.offset.parent.left;this.instance.offset.parent.top-=D.offset.parent.top-this.instance.offset.parent.top;D._propagate("toSortable",F)}if(this.instance.currentItem){this.instance._mouseDrag(F)}}else{if(this.instance.isOver){this.instance.isOver=0;this.instance.cancelHelperRemoval=true;this.instance.options.revert=false;this.instance._mouseStop(F,true);this.instance.options.helper=this.instance.options._helper;this.instance.currentItem.remove();if(this.instance.placeholder){this.instance.placeholder.remove()}D._propagate("fromSortable",F)}}})}});A.ui.plugin.add("draggable","stack",{start:function(D,B){var C=A.makeArray(A(B.options.stack.group)).sort(function(F,E){return(parseInt(A(F).css("zIndex"),10)||B.options.stack.min)-(parseInt(A(E).css("zIndex"),10)||B.options.stack.min)});A(C).each(function(E){this.style.zIndex=B.options.stack.min+E});this[0].style.zIndex=B.options.stack.min+C.length}})})(jQuery) \ No newline at end of file
diff --git a/site/app/webroot/js/jquery-ui/ui.droppable.min.js b/site/app/webroot/js/jquery-ui/ui.droppable.min.js
new file mode 100755
index 0000000..632ebdb
--- /dev/null
+++ b/site/app/webroot/js/jquery-ui/ui.droppable.min.js
@@ -0,0 +1 @@
+(function(A){A.widget("ui.droppable",{_setData:function(B,C){if(B=="accept"){this.options.accept=C&&A.isFunction(C)?C:function(D){return D.is(accept)}}else{A.widget.prototype._setData.apply(this,arguments)}},_init:function(){var C=this.options,B=C.accept;this.isover=0;this.isout=1;this.options.accept=this.options.accept&&A.isFunction(this.options.accept)?this.options.accept:function(D){return D.is(B)};this.proportions={width:this.element[0].offsetWidth,height:this.element[0].offsetHeight};A.ui.ddmanager.droppables[this.options.scope]=A.ui.ddmanager.droppables[this.options.scope]||[];A.ui.ddmanager.droppables[this.options.scope].push(this);(this.options.cssNamespace&&this.element.addClass(this.options.cssNamespace+"-droppable"))},plugins:{},ui:function(B){return{draggable:(B.currentItem||B.element),helper:B.helper,position:B.position,absolutePosition:B.positionAbs,options:this.options,element:this.element}},destroy:function(){var B=A.ui.ddmanager.droppables[this.options.scope];for(var C=0;C<B.length;C++){if(B[C]==this){B.splice(C,1)}}this.element.removeClass("ui-droppable-disabled").removeData("droppable").unbind(".droppable")},_over:function(C){var B=A.ui.ddmanager.current;if(!B||(B.currentItem||B.element)[0]==this.element[0]){return }if(this.options.accept.call(this.element,(B.currentItem||B.element))){A.ui.plugin.call(this,"over",[C,this.ui(B)]);this.element.triggerHandler("dropover",[C,this.ui(B)],this.options.over)}},_out:function(C){var B=A.ui.ddmanager.current;if(!B||(B.currentItem||B.element)[0]==this.element[0]){return }if(this.options.accept.call(this.element,(B.currentItem||B.element))){A.ui.plugin.call(this,"out",[C,this.ui(B)]);this.element.triggerHandler("dropout",[C,this.ui(B)],this.options.out)}},_drop:function(D,C){var B=C||A.ui.ddmanager.current;if(!B||(B.currentItem||B.element)[0]==this.element[0]){return false}var E=false;this.element.find(":data(droppable)").not(".ui-draggable-dragging").each(function(){var F=A.data(this,"droppable");if(F.options.greedy&&A.ui.intersect(B,A.extend(F,{offset:F.element.offset()}),F.options.tolerance)){E=true;return false}});if(E){return false}if(this.options.accept.call(this.element,(B.currentItem||B.element))){A.ui.plugin.call(this,"drop",[D,this.ui(B)]);this.element.triggerHandler("drop",[D,this.ui(B)],this.options.drop);return this.element}return false},_activate:function(C){var B=A.ui.ddmanager.current;A.ui.plugin.call(this,"activate",[C,this.ui(B)]);if(B){this.element.triggerHandler("dropactivate",[C,this.ui(B)],this.options.activate)}},_deactivate:function(C){var B=A.ui.ddmanager.current;A.ui.plugin.call(this,"deactivate",[C,this.ui(B)]);if(B){this.element.triggerHandler("dropdeactivate",[C,this.ui(B)],this.options.deactivate)}}});A.extend(A.ui.droppable,{defaults:{disabled:false,tolerance:"intersect",scope:"default",cssNamespace:"ui"}});A.ui.intersect=function(L,F,J){if(!F.offset){return false}var D=(L.positionAbs||L.position.absolute).left,C=D+L.helperProportions.width,I=(L.positionAbs||L.position.absolute).top,H=I+L.helperProportions.height;var E=F.offset.left,B=E+F.proportions.width,K=F.offset.top,G=K+F.proportions.height;switch(J){case"fit":return(E<D&&C<B&&K<I&&H<G);break;case"intersect":return(E<D+(L.helperProportions.width/2)&&C-(L.helperProportions.width/2)<B&&K<I+(L.helperProportions.height/2)&&H-(L.helperProportions.height/2)<G);break;case"pointer":return(E<((L.positionAbs||L.position.absolute).left+(L.clickOffset||L.offset.click).left)&&((L.positionAbs||L.position.absolute).left+(L.clickOffset||L.offset.click).left)<B&&K<((L.positionAbs||L.position.absolute).top+(L.clickOffset||L.offset.click).top)&&((L.positionAbs||L.position.absolute).top+(L.clickOffset||L.offset.click).top)<G);break;case"touch":return((I>=K&&I<=G)||(H>=K&&H<=G)||(I<K&&H>G))&&((D>=E&&D<=B)||(C>=E&&C<=B)||(D<E&&C>B));break;default:return false;break}};A.ui.ddmanager={current:null,droppables:{"default":[]},prepareOffsets:function(E,H){var B=A.ui.ddmanager.droppables[E.options.scope];var F=H?H.type:null;var G=(E.currentItem||E.element).find(":data(droppable)").andSelf();droppablesLoop:for(var D=0;D<B.length;D++){if(B[D].options.disabled||(E&&!B[D].options.accept.call(B[D].element,(E.currentItem||E.element)))){continue}for(var C=0;C<G.length;C++){if(G[C]==B[D].element[0]){B[D].proportions.height=0;continue droppablesLoop}}B[D].visible=B[D].element.css("display")!="none";if(!B[D].visible){continue}B[D].offset=B[D].element.offset();B[D].proportions={width:B[D].element[0].offsetWidth,height:B[D].element[0].offsetHeight};if(F=="dragstart"||F=="sortactivate"){B[D]._activate.call(B[D],H)}}},drop:function(B,C){var D=false;A.each(A.ui.ddmanager.droppables[B.options.scope],function(){if(!this.options){return }if(!this.options.disabled&&this.visible&&A.ui.intersect(B,this,this.options.tolerance)){D=this._drop.call(this,C)}if(!this.options.disabled&&this.visible&&this.options.accept.call(this.element,(B.currentItem||B.element))){this.isout=1;this.isover=0;this._deactivate.call(this,C)}});return D},drag:function(B,C){if(B.options.refreshPositions){A.ui.ddmanager.prepareOffsets(B,C)}A.each(A.ui.ddmanager.droppables[B.options.scope],function(){if(this.options.disabled||this.greedyChild||!this.visible){return }var E=A.ui.intersect(B,this,this.options.tolerance);var G=!E&&this.isover==1?"isout":(E&&this.isover==0?"isover":null);if(!G){return }var F;if(this.options.greedy){var D=this.element.parents(":data(droppable):eq(0)");if(D.length){F=A.data(D[0],"droppable");F.greedyChild=(G=="isover"?1:0)}}if(F&&G=="isover"){F["isover"]=0;F["isout"]=1;F._out.call(F,C)}this[G]=1;this[G=="isout"?"isover":"isout"]=0;this[G=="isover"?"_over":"_out"].call(this,C);if(F&&G=="isout"){F["isout"]=0;F["isover"]=1;F._over.call(F,C)}})}};A.ui.plugin.add("droppable","activeClass",{activate:function(C,B){A(this).addClass(B.options.activeClass)},deactivate:function(C,B){A(this).removeClass(B.options.activeClass)},drop:function(C,B){A(this).removeClass(B.options.activeClass)}});A.ui.plugin.add("droppable","hoverClass",{over:function(C,B){A(this).addClass(B.options.hoverClass)},out:function(C,B){A(this).removeClass(B.options.hoverClass)},drop:function(C,B){A(this).removeClass(B.options.hoverClass)}})})(jQuery) \ No newline at end of file
diff --git a/site/app/webroot/js/jquery-ui/ui.lightbox.js b/site/app/webroot/js/jquery-ui/ui.lightbox.js
new file mode 100644
index 0000000..9bb0713
--- /dev/null
+++ b/site/app/webroot/js/jquery-ui/ui.lightbox.js
@@ -0,0 +1,446 @@
+/**
+ * jQuery lightBox plugin
+ * This jQuery plugin was inspired and based on Lightbox 2 by Lokesh Dhakar (http://www.huddletogether.com/projects/lightbox2/)
+ * and adapted to me for use like a plugin from jQuery.
+ * @name jquery-lightbox-0.4.js
+ * @author Leandro Vieira Pinho - http://leandrovieira.com
+ * @version 0.4
+ * @date November 17, 2007
+ * @category jQuery plugin
+ * @copyright (c) 2007 Leandro Vieira Pinho (leandrovieira.com)
+ * @license CC Attribution-No Derivative Works 2.5 Brazil - http://creativecommons.org/licenses/by-nd/2.5/br/deed.en_US
+ * @example Visit http://leandrovieira.com/projects/jquery/lightbox/ for more informations about this jQuery plugin
+ */
+
+// Offering a Custom Alias suport - More info: http://docs.jquery.com/Plugins/Authoring#Custom_Alias
+(function($) {
+ /**
+ * $ is an alias to jQuery object
+ *
+ */
+ $.fn.lightBox = function(settings) {
+ // Settings to configure the jQuery lightBox plugin how you like
+ settings = jQuery.extend({
+ // Configuration related to overlay
+ overlayBgColor: '#000', // (string) Background color to overlay; inform a hexadecimal value like: #RRGGBB. Where RR, GG, and BB are the hexadecimal values for the red, green, and blue values of the color.
+ overlayOpacity: 0.8, // (integer) Opacity value to overlay; inform: 0.X. Where X are number from 0 to 9
+ // Configuration related to images
+ imageLoading: 'images/lightbox-ico-loading.gif', // (string) Path and the name of the loading icon
+ imageBtnPrev: 'images/lightbox-btn-prev.gif', // (string) Path and the name of the prev button image
+ imageBtnNext: 'images/lightbox-btn-next.gif', // (string) Path and the name of the next button image
+ imageBtnClose: 'images/lightbox-btn-close.gif', // (string) Path and the name of the close btn
+ imageBlank: 'images/lightbox-blank.gif', // (string) Path and the name of a blank image (one pixel)
+ // Configuration related to container image box
+ containerBorderSize: 10, // (integer) If you adjust the padding in the CSS for the container, #lightbox-container-image-box, you will need to update this value
+ containerResizeSpeed: 400, // (integer) Specify the resize duration of container image. These number are miliseconds. 400 is default.
+ // Configuration related to texts in caption. For example: Image 2 of 8. You can alter either "Image" and "of" texts.
+ txtImage: 'Image', // (string) Specify text "Image"
+ txtOf: 'of', // (string) Specify text "of"
+ // Configuration related to keyboard navigation
+ keyToClose: 'c', // (string) (c = close) Letter to close the jQuery lightBox interface. Beyond this letter, the letter X and the SCAPE key is used to.
+ keyToPrev: 'p', // (string) (p = previous) Letter to show the previous image
+ keyToNext: 'n', // (string) (n = next) Letter to show the next image.
+ // Don´t alter these variables in any way
+ imageArray: [],
+ activeImage: 0
+ },settings);
+ // Caching the jQuery object with all elements matched
+ var jQueryMatchedObj = this; // This, in this context, refer to jQuery object
+ /**
+ * Initializing the plugin calling the start function
+ *
+ * @return boolean false
+ */
+ function _initialize() {
+ _start(this,jQueryMatchedObj); // This, in this context, refer to object (link) which the user have clicked
+ return false; // Avoid the browser following the link
+ }
+ /**
+ * Start the jQuery lightBox plugin
+ *
+ * @param object objClicked The object (link) whick the user have clicked
+ * @param object jQueryMatchedObj The jQuery object with all elements matched
+ */
+ function _start(objClicked,jQueryMatchedObj) {
+ // Hime some elements to avoid conflict with overlay in IE. These elements appear above the overlay.
+ $('embed, object, select').css({ 'visibility' : 'hidden' });
+ // Call the function to create the markup structure; style some elements; assign events in some elements.
+ _set_interface();
+ // Unset total images in imageArray
+ settings.imageArray.length = 0;
+ // Unset image active information
+ settings.activeImage = 0;
+ // We have an image set? Or just an image? Let´s see it.
+ if ( jQueryMatchedObj.length == 1 ) {
+ settings.imageArray.push(new Array(objClicked.getAttribute('href'),objClicked.getAttribute('title')));
+ } else {
+ // Add an Array (as many as we have), with href and title atributes, inside the Array that storage the images references
+ for ( var i = 0; i < jQueryMatchedObj.length; i++ ) {
+ settings.imageArray.push(new Array(jQueryMatchedObj[i].getAttribute('href'),jQueryMatchedObj[i].getAttribute('title')));
+ }
+ }
+ while ( settings.imageArray[settings.activeImage][0] != objClicked.getAttribute('href') ) {
+ settings.activeImage++;
+ }
+ // Call the function that prepares image exibition
+ _set_image_to_view();
+ }
+ /**
+ * Create the jQuery lightBox plugin interface
+ *
+ * The HTML markup will be like that:
+ <div id="jquery-overlay"></div>
+ <div id="jquery-lightbox">
+ <div id="lightbox-container-image-box">
+ <div id="lightbox-container-image">
+ <img src="../fotos/XX.jpg" id="lightbox-image">
+ <div id="lightbox-nav">
+ <a href="#" id="lightbox-nav-btnPrev"></a>
+ <a href="#" id="lightbox-nav-btnNext"></a>
+ </div>
+ <div id="lightbox-loading">
+ <a href="#" id="lightbox-loading-link">
+ <img src="../images/lightbox-ico-loading.gif">
+ </a>
+ </div>
+ </div>
+ </div>
+ <div id="lightbox-container-image-data-box">
+ <div id="lightbox-container-image-data">
+ <div id="lightbox-image-details">
+ <span id="lightbox-image-details-caption"></span>
+ <span id="lightbox-image-details-currentNumber"></span>
+ </div>
+ <div id="lightbox-secNav">
+ <a href="#" id="lightbox-secNav-btnClose">
+ <img src="../images/lightbox-btn-close.gif">
+ </a>
+ </div>
+ </div>
+ </div>
+ </div>
+ *
+ */
+ function _set_interface() {
+ // Apply the HTML markup into body tag
+ $('body').append('<div id="jquery-overlay"></div><div id="jquery-lightbox"><div id="lightbox-container-image-box"><div id="lightbox-container-image"><img id="lightbox-image"><div style="" id="lightbox-nav"><a href="#" id="lightbox-nav-btnPrev"></a><a href="#" id="lightbox-nav-btnNext"></a></div><div id="lightbox-loading"><a href="#" id="lightbox-loading-link"><img src="' + settings.imageLoading + '"></a></div></div></div><div id="lightbox-container-image-data-box"><div id="lightbox-container-image-data"><div id="lightbox-image-details"><span id="lightbox-image-details-caption"></span><span id="lightbox-image-details-currentNumber"></span></div><div id="lightbox-secNav"><a href="#" id="lightbox-secNav-btnClose"><img src="' + settings.imageBtnClose + '"></a></div></div></div></div>');
+ // Get page sizes
+ var arrPageSizes = ___getPageSize();
+ // Style overlay and show it
+ $('#jquery-overlay').css({
+ backgroundColor: settings.overlayBgColor,
+ opacity: settings.overlayOpacity,
+ width: arrPageSizes[0],
+ height: arrPageSizes[1]
+ }).fadeIn();
+ // Get page scroll
+ var arrPageScroll = ___getPageScroll();
+ // Calculate top and left offset for the jquery-lightbox div object and show it
+ $('#jquery-lightbox').css({
+ top: arrPageScroll[1] + (arrPageSizes[3] / 10),
+ left: arrPageScroll[0]
+ }).show();
+ // Assigning click events in elements to close overlay
+ $('#jquery-overlay,#jquery-lightbox').click(function() {
+ _finish();
+ });
+ // Assign the _finish function to lightbox-loading-link and lightbox-secNav-btnClose objects
+ $('#lightbox-loading-link,#lightbox-secNav-btnClose').click(function() {
+ _finish();
+ return false;
+ });
+ // If window was resized, calculate the new overlay dimensions
+ $(window).resize(function() {
+ // Get page sizes
+ var arrPageSizes = ___getPageSize();
+ // Style overlay and show it
+ $('#jquery-overlay').css({
+ width: arrPageSizes[0],
+ height: arrPageSizes[1]
+ });
+ // Get page scroll
+ var arrPageScroll = ___getPageScroll();
+ // Calculate top and left offset for the jquery-lightbox div object and show it
+ $('#jquery-lightbox').css({
+ top: arrPageScroll[1] + (arrPageSizes[3] / 10),
+ left: arrPageScroll[0]
+ });
+ });
+ }
+ /**
+ * Prepares image exibition; doing a image´s preloader to calculate it´s size
+ *
+ */
+ function _set_image_to_view() { // show the loading
+ // Show the loading
+ $('#lightbox-loading').show();
+ // Hide some elements
+ $('#lightbox-image,#lightbox-nav,#lightbox-nav-btnPrev,#lightbox-nav-btnNext,#lightbox-container-image-data-box,#lightbox-image-details-currentNumber').hide();
+ // Image preload process
+ var objImagePreloader = new Image();
+ objImagePreloader.onload = function() {
+ $('#lightbox-image').attr('src',settings.imageArray[settings.activeImage][0]);
+ // Perfomance an effect in the image container resizing it
+ _resize_container_image_box(objImagePreloader.width,objImagePreloader.height);
+ // clear onLoad, IE behaves irratically with animated gifs otherwise
+ objImagePreloader.onload=function(){};
+ }
+ objImagePreloader.src = settings.imageArray[settings.activeImage][0];
+ };
+ /**
+ * Perfomance an effect in the image container resizing it
+ *
+ * @param integer intImageWidth The image´s width that will be showed
+ * @param integer intImageHeight The image´s height that will be showed
+ */
+ function _resize_container_image_box(intImageWidth,intImageHeight) {
+ // Get current width and height
+ var intCurrentWidth = $('#lightbox-container-image-box').width();
+ var intCurrentHeight = $('#lightbox-container-image-box').height();
+ // Get the width and height of the selected image plus the padding
+ var intWidth = (intImageWidth + (settings.containerBorderSize * 2)); // Plus the image´s width and the left and right padding value
+ var intHeight = (intImageHeight + (settings.containerBorderSize * 2)); // Plus the image´s height and the left and right padding value
+ // Diferences
+ var intDiffW = intCurrentWidth - intWidth;
+ var intDiffH = intCurrentHeight - intHeight;
+ // Perfomance the effect
+ $('#lightbox-container-image-box').animate({ width: intWidth, height: intHeight },settings.containerResizeSpeed,function() { _show_image(); });
+ if ( ( intDiffW == 0 ) && ( intDiffH == 0 ) ) {
+ if ( $.browser.msie ) {
+ ___pause(250);
+ } else {
+ ___pause(100);
+ }
+ }
+ $('#lightbox-nav-btnPrev,#lightbox-nav-btnNext').css({ height: intImageHeight + (settings.containerBorderSize * 2) });
+ $('#lightbox-container-image-data-box').css({ width: intImageWidth });
+ };
+ /**
+ * Show the prepared image
+ *
+ */
+ function _show_image() {
+ $('#lightbox-loading').hide();
+ $('#lightbox-image').fadeIn(function() {
+ _show_image_data();
+ _set_navigation();
+ });
+ _preload_neighbor_images();
+ };
+ /**
+ * Show the image information
+ *
+ */
+ function _show_image_data() {
+ $('#lightbox-container-image-data-box').slideDown('fast');
+ $('#lightbox-image-details-caption').hide();
+ if ( settings.imageArray[settings.activeImage][1] ) {
+ $('#lightbox-image-details-caption').html(settings.imageArray[settings.activeImage][1]).show();
+ }
+ // If we have a image set, display 'Image X of X'
+ if ( settings.imageArray.length > 1 ) {
+ $('#lightbox-image-details-currentNumber').html(settings.txtImage + ' ' + ( settings.activeImage + 1 ) + ' ' + settings.txtOf + ' ' + settings.imageArray.length).show();
+ }
+ }
+ /**
+ * Display the button navigations
+ *
+ */
+ function _set_navigation() {
+ $('#lightbox-nav').show();
+
+ // Instead to define this configuration in CSS file, we define here. And it´s need to IE. Just.
+ $('#lightbox-nav-btnPrev,#lightbox-nav-btnNext').css({ 'background' : 'transparent url(' + settings.imageBlank + ') no-repeat' });
+
+ // Show the prev button, if not the first image in set
+ if ( settings.activeImage != 0 ) {
+ // Show the images button for Next buttons
+ $('#lightbox-nav-btnPrev').unbind().hover(function() {
+ $(this).css({ 'background' : 'url(' + settings.imageBtnPrev + ') left 45% no-repeat' });
+ },function() {
+ $(this).css({ 'background' : 'transparent url(' + settings.imageBlank + ') no-repeat' });
+ }).show().bind('click',function() {
+ settings.activeImage = settings.activeImage - 1;
+ _set_image_to_view();
+ return false;
+ });
+ }
+
+ // Show the next button, if not the last image in set
+ if ( settings.activeImage != ( settings.imageArray.length -1 ) ) {
+ // Show the images button for Next buttons
+ $('#lightbox-nav-btnNext').unbind().hover(function() {
+ $(this).css({ 'background' : 'url(' + settings.imageBtnNext + ') right 45% no-repeat' });
+ },function() {
+ $(this).css({ 'background' : 'transparent url(' + settings.imageBlank + ') no-repeat' });
+ }).show().bind('click',function() {
+ settings.activeImage = settings.activeImage + 1;
+ _set_image_to_view();
+ return false;
+ });
+ }
+ // Enable keyboard navigation
+ _enable_keyboard_navigation();
+ }
+ /**
+ * Enable a support to keyboard navigation
+ *
+ */
+ function _enable_keyboard_navigation() {
+ $(document).keydown(function(objEvent) {
+ _keyboard_action(objEvent);
+ });
+ }
+ /**
+ * Disable the support to keyboard navigation
+ *
+ */
+ function _disable_keyboard_navigation() {
+ $(document).unbind();
+ }
+ /**
+ * Perform the keyboard actions
+ *
+ */
+ function _keyboard_action(objEvent) {
+ // To ie
+ if ( objEvent == null ) {
+ keycode = event.keyCode;
+ escapeKey = 27;
+ // To Mozilla
+ } else {
+ keycode = objEvent.keyCode;
+ escapeKey = objEvent.DOM_VK_ESCAPE;
+ }
+ // Get the key in lower case form
+ key = String.fromCharCode(keycode).toLowerCase();
+ // Verify the keys to close the ligthBox
+ if ( ( key == settings.keyToClose ) || ( key == 'x' ) || ( keycode == escapeKey ) ) {
+ _finish();
+ }
+ // Verify the key to show the previous image
+ if ( ( key == settings.keyToPrev ) || ( keycode == 37 ) ) {
+ // If we´re not showing the first image, call the previous
+ if ( settings.activeImage != 0 ) {
+ settings.activeImage = settings.activeImage - 1;
+ _set_image_to_view();
+ _disable_keyboard_navigation();
+ }
+ }
+ // Verify the key to show the next image
+ if ( ( key == settings.keyToNext ) || ( keycode == 39 ) ) {
+ // If we´re not showing the last image, call the next
+ if ( settings.activeImage != ( settings.imageArray.length - 1 ) ) {
+ settings.activeImage = settings.activeImage + 1;
+ _set_image_to_view();
+ _disable_keyboard_navigation();
+ }
+ }
+ }
+ /**
+ * Preload prev and next images being showed
+ *
+ */
+ function _preload_neighbor_images() {
+ if ( (settings.imageArray.length -1) > settings.activeImage ) {
+ objNext = new Image();
+ objNext.src = settings.imageArray[settings.activeImage + 1][0];
+ }
+ if ( settings.activeImage > 0 ) {
+ objPrev = new Image();
+ objPrev.src = settings.imageArray[settings.activeImage -1][0];
+ }
+ }
+ /**
+ * Remove jQuery lightBox plugin HTML markup
+ *
+ */
+ function _finish() {
+ $('#jquery-lightbox').remove();
+ $('#jquery-overlay').fadeOut(function() { $('#jquery-overlay').remove(); });
+ // Show some elements to avoid conflict with overlay in IE. These elements appear above the overlay.
+ $('embed, object, select').css({ 'visibility' : 'visible' });
+ }
+ /**
+ / THIRD FUNCTION
+ * getPageSize() by quirksmode.com
+ *
+ * @return Array Return an array with page width, height and window width, height
+ */
+ function ___getPageSize() {
+ var xScroll, yScroll;
+ if (window.innerHeight && window.scrollMaxY) {
+ xScroll = window.innerWidth + window.scrollMaxX;
+ yScroll = window.innerHeight + window.scrollMaxY;
+ } else if (document.body.scrollHeight > document.body.offsetHeight){ // all but Explorer Mac
+ xScroll = document.body.scrollWidth;
+ yScroll = document.body.scrollHeight;
+ } else { // Explorer Mac...would also work in Explorer 6 Strict, Mozilla and Safari
+ xScroll = document.body.offsetWidth;
+ yScroll = document.body.offsetHeight;
+ }
+ var windowWidth, windowHeight;
+ if (self.innerHeight) { // all except Explorer
+ if(document.documentElement.clientWidth){
+ windowWidth = document.documentElement.clientWidth;
+ } else {
+ windowWidth = self.innerWidth;
+ }
+ windowHeight = self.innerHeight;
+ } else if (document.documentElement && document.documentElement.clientHeight) { // Explorer 6 Strict Mode
+ windowWidth = document.documentElement.clientWidth;
+ windowHeight = document.documentElement.clientHeight;
+ } else if (document.body) { // other Explorers
+ windowWidth = document.body.clientWidth;
+ windowHeight = document.body.clientHeight;
+ }
+ // for small pages with total height less then height of the viewport
+ if(yScroll < windowHeight){
+ pageHeight = windowHeight;
+ } else {
+ pageHeight = yScroll;
+ }
+ // for small pages with total width less then width of the viewport
+ if(xScroll < windowWidth){
+ pageWidth = xScroll;
+ } else {
+ pageWidth = windowWidth;
+ }
+ arrayPageSize = new Array(pageWidth,pageHeight,windowWidth,windowHeight)
+ return arrayPageSize;
+ };
+ /**
+ / THIRD FUNCTION
+ * getPageScroll() by quirksmode.com
+ *
+ * @return Array Return an array with x,y page scroll values.
+ */
+ function ___getPageScroll() {
+ var xScroll, yScroll;
+ if (self.pageYOffset) {
+ yScroll = self.pageYOffset;
+ xScroll = self.pageXOffset;
+ } else if (document.documentElement && document.documentElement.scrollTop) { // Explorer 6 Strict
+ yScroll = document.documentElement.scrollTop;
+ xScroll = document.documentElement.scrollLeft;
+ } else if (document.body) {// all other Explorers
+ yScroll = document.body.scrollTop;
+ xScroll = document.body.scrollLeft;
+ }
+ arrayPageScroll = new Array(xScroll,yScroll)
+ return arrayPageScroll;
+ };
+ /**
+ * Stop the code execution from a escified time in milisecond
+ *
+ */
+ function ___pause(ms) {
+ var date = new Date();
+ curDate = null;
+ do { var curDate = new Date(); }
+ while ( curDate - date < ms);
+ };
+ // Return the jQuery object for chaining. The unbind method is used to avoid click conflict when the plugin is called more than once
+ return this.unbind('click').click(_initialize);
+ };
+})(jQuery); // Call and execute the function immediately passing the jQuery object
diff --git a/site/app/webroot/js/jquery-ui/ui.magnifier.min.js b/site/app/webroot/js/jquery-ui/ui.magnifier.min.js
new file mode 100755
index 0000000..7d2f8f7
--- /dev/null
+++ b/site/app/webroot/js/jquery-ui/ui.magnifier.min.js
@@ -0,0 +1 @@
+(function(B){var A=0;B.widget("ui.magnifier",{_init:function(){var C=this,D=this.options;this.element.addClass("ui-magnifier").bind("click.magnifier",function(E){(!C.disabled&&D.click&&D.click.apply(this,[E,{options:C.options,current:C.current[0],currentOffset:C.current[1]}]))});if(!(/^(r|a)/).test(this.element.css("position"))){this.element.css("position","relative")}this.items=[];this.element.find(D.items).each(function(){var E=B(this);C.items.push([this,E.offset(),[E.width(),E.height()],(D.overlap?E.position():null)]);(D.opacity&&E.css("opacity",D.opacity.min))});(D.overlap&&B.each(this.items,function(){B(this[0]).css({position:"absolute",top:this[3].top,left:this[3].left})}));this.identifier=++A;B(document).bind("mousemove.magnifier"+this.identifier,function(E){(C.disabled||C._magnify.apply(C,[E]))});this.pp=this.element.offset()},destroy:function(){this.reset();this.element.removeClass("ui-magnifier ui-magnifier-disabled").unbind(".magnifier");B(document).unbind("mousemove.magnifier"+this.identifier)},disable:function(){this.reset();B.widget.prototype.disable.apply(this,arguments)},reset:function(C){var D=this.options;B.each(this.items,function(){var E=this;B(E[0]).css({width:E[2][0],height:E[2][1],top:(E[3]?E[3].top:0),left:(E[3]?E[3].left:0)});(D.opacity&&B(E[0]).css("opacity",D.opacity.min));(D.zIndex&&B(E[0]).css("z-index",""))})},_magnify:function(G){var F=[G.pageX,G.pageY],H=this.options,J,I=1;this.current=this.items[0];var C=((F[0]>this.pp.left-H.distance)&&(F[0]<this.pp.left+this.element[0].offsetWidth+H.distance)&&(F[1]>this.pp.top-H.distance)&&(F[1]<this.pp.top+this.element[0].offsetHeight+H.distance));if(!C){return false}for(var E=0;E<this.items.length;E++){J=this.items[E];var D=I;if(!H.axis){I=Math.sqrt(Math.pow(F[0]-((J[3]?this.pp.left:J[1].left)+parseInt(J[0].style.left,10))-(J[0].offsetWidth/2),2)+Math.pow(F[1]-((J[3]?this.pp.top:J[1].top)+parseInt(J[0].style.top,10))-(J[0].offsetHeight/2),2))}else{if(H.axis=="y"){I=Math.abs(F[1]-((J[3]?this.pp.top:J[1].top)+parseInt(J[0].style.top,10))-(J[0].offsetHeight/2))}else{I=Math.abs(F[0]-((J[3]?this.pp.left:J[1].left)+parseInt(J[0].style.left,10))-(J[0].offsetWidth/2))}}if(I<H.distance){this.current=I<D?J:this.current;if(!H.axis||H.axis!="y"){B(J[0]).css({width:J[2][0]+(J[2][0]*(H.magnification-1))-(((I/H.distance)*J[2][0])*(H.magnification-1)),left:(J[3]?(J[3].left+H.verticalLine*((J[2][1]*(H.magnification-1))-(((I/H.distance)*J[2][1])*(H.magnification-1)))):0)})}if(!H.axis||H.axis!="x"){B(J[0]).css({height:J[2][1]+(J[2][1]*(H.magnification-1))-(((I/H.distance)*J[2][1])*(H.magnification-1)),top:(J[3]?J[3].top:0)+(H.baseline-0.5)*((J[2][0]*(H.magnification-1))-(((I/H.distance)*J[2][0])*(H.magnification-1)))})}if(H.opacity){B(J[0]).css("opacity",H.opacity.max-(I/H.distance)<H.opacity.min?H.opacity.min:H.opacity.max-(I/H.distance))}}else{B(J[0]).css({width:J[2][0],height:J[2][1],top:(J[3]?J[3].top:0),left:(J[3]?J[3].left:0)});(H.opacity&&B(J[0]).css("opacity",H.opacity.min))}(H.zIndex&&B(J[0]).css("z-index",""))}(H.zIndex&&B(this.current[0]).css("z-index",H.zIndex))}});B.extend(B.ui.magnifier,{defaults:{distance:150,magnification:2,baseline:0,verticalLine:-0.5,items:"> *"}})})(jQuery) \ No newline at end of file
diff --git a/site/app/webroot/js/jquery-ui/ui.progressbar.min.js b/site/app/webroot/js/jquery-ui/ui.progressbar.min.js
new file mode 100755
index 0000000..588fd7f
--- /dev/null
+++ b/site/app/webroot/js/jquery-ui/ui.progressbar.min.js
@@ -0,0 +1 @@
+(function(A){A.widget("ui.progressbar",{_init:function(){this._interval=this.options.interval;var B=this,C=this.options,E=(new Date()).getTime()+Math.random(),D=C.text||"0%";this.element.addClass("ui-progressbar").width(C.width);A.extend(this,{active:false,pixelState:0,percentState:0,identifier:E,bar:A('<div class="ui-progressbar-bar ui-hidden"></div>').css({width:"0px",overflow:"hidden",zIndex:100}),textElement:A('<div class="ui-progressbar-text"></div>').html(D).css({width:"0px",overflow:"hidden"}),textBg:A('<div class="ui-progressbar-text ui-progressbar-text-back"></div>').html(D).css({width:this.element.width()}),wrapper:A('<div class="ui-progressbar-wrap"></div>')});this.wrapper.append(this.bar.append(this.textElement.addClass(C.textClass)),this.textBg).appendTo(this.element)},plugins:{},ui:function(B){return{instance:this,identifier:this.identifier,options:this.options,element:this.bar,textElement:this.textElement,pixelState:this.pixelState,percentState:this.percentState}},_propagate:function(C,B){A.ui.plugin.call(this,C,[B,this.ui()]);this.element.triggerHandler(C=="progressbar"?C:["progressbar",C].join(""),[B,this.ui()],this.options[C])},destroy:function(){this.stop();this.element.removeClass("ui-progressbar ui-progressbar-disabled").removeData("progressbar").unbind(".progressbar").find(".ui-progressbar-wrap").remove();delete jQuery.easing[this.identifier]},enable:function(){this.element.removeClass("ui-progressbar-disabled");this.disabled=false},disable:function(){this.element.addClass("ui-progressbar-disabled");this.disabled=true},start:function(){var B=this,C=this.options;if(this.disabled){return }jQuery.easing[this.identifier]=function(K,L,J,I,H){var G=C.increment,E=C.width,F=((G>E?E:G)/E),D=Math.round(K/F)*F;return D>1?1:D};B.active=true;setTimeout(function(){B.active=false},C.duration);this._animate();this._propagate("start",this.ui());return false},_animate:function(){var C=this,D=this.options,B=D.interval;this.bar.animate({width:D.width},{duration:B,easing:this.identifier,step:function(G,E){C.progress((G/D.width)*100);var H=new Date().getTime(),F=(H-E.startTime);D.interval=B-F},complete:function(){delete jQuery.easing[C.identifier];C.pause();if(C.active){}}})},pause:function(){if(this.disabled){return }this.bar.stop();this._propagate("pause",this.ui())},stop:function(){this.bar.stop();this.bar.width(0);this.textElement.width(0);this.bar.addClass("ui-hidden");this.options.interval=this._interval;this._propagate("stop",this.ui())},text:function(B){this.textElement.html(B);this.textBg.html(B)},progress:function(B){if(this.bar.is(".ui-hidden")){this.bar.removeClass("ui-hidden")}this.percentState=B>100?100:B;this.pixelState=(this.percentState/100)*this.options.width;this.bar.width(this.pixelState);this.textElement.width(this.pixelState);if(this.options.range&&!this.options.text){this.textElement.html(Math.round(this.percentState)+"%")}this._propagate("progress",this.ui())}});A.ui.progressbar.defaults={width:300,duration:3000,interval:200,increment:1,range:true,text:"",addClass:"",textClass:""}})(jQuery) \ No newline at end of file
diff --git a/site/app/webroot/js/jquery-ui/ui.resizable.min.js b/site/app/webroot/js/jquery-ui/ui.resizable.min.js
new file mode 100755
index 0000000..26f1c7a
--- /dev/null
+++ b/site/app/webroot/js/jquery-ui/ui.resizable.min.js
@@ -0,0 +1 @@
+(function(A){A.widget("ui.resizable",A.extend({},A.ui.mouse,{_init:function(){var M=this,N=this.options;var Q=this.element.css("position");this.originalElement=this.element;this.element.addClass("ui-resizable").css({position:/static/.test(Q)?"relative":Q});A.extend(N,{_aspectRatio:!!(N.aspectRatio),helper:N.helper||N.ghost||N.animate?N.helper||"proxy":null,knobHandles:N.knobHandles===true?"ui-resizable-knob-handle":N.knobHandles});var H="1px solid #DEDEDE";N.defaultTheme={"ui-resizable":{display:"block"},"ui-resizable-handle":{position:"absolute",background:"#F2F2F2",fontSize:"0.1px"},"ui-resizable-n":{cursor:"n-resize",height:"4px",left:"0px",right:"0px",borderTop:H},"ui-resizable-s":{cursor:"s-resize",height:"4px",left:"0px",right:"0px",borderBottom:H},"ui-resizable-e":{cursor:"e-resize",width:"4px",top:"0px",bottom:"0px",borderRight:H},"ui-resizable-w":{cursor:"w-resize",width:"4px",top:"0px",bottom:"0px",borderLeft:H},"ui-resizable-se":{cursor:"se-resize",width:"4px",height:"4px",borderRight:H,borderBottom:H},"ui-resizable-sw":{cursor:"sw-resize",width:"4px",height:"4px",borderBottom:H,borderLeft:H},"ui-resizable-ne":{cursor:"ne-resize",width:"4px",height:"4px",borderRight:H,borderTop:H},"ui-resizable-nw":{cursor:"nw-resize",width:"4px",height:"4px",borderLeft:H,borderTop:H}};N.knobTheme={"ui-resizable-handle":{background:"#F2F2F2",border:"1px solid #808080",height:"8px",width:"8px"},"ui-resizable-n":{cursor:"n-resize",top:"0px",left:"45%"},"ui-resizable-s":{cursor:"s-resize",bottom:"0px",left:"45%"},"ui-resizable-e":{cursor:"e-resize",right:"0px",top:"45%"},"ui-resizable-w":{cursor:"w-resize",left:"0px",top:"45%"},"ui-resizable-se":{cursor:"se-resize",right:"0px",bottom:"0px"},"ui-resizable-sw":{cursor:"sw-resize",left:"0px",bottom:"0px"},"ui-resizable-nw":{cursor:"nw-resize",left:"0px",top:"0px"},"ui-resizable-ne":{cursor:"ne-resize",right:"0px",top:"0px"}};N._nodeName=this.element[0].nodeName;if(N._nodeName.match(/canvas|textarea|input|select|button|img/i)){var B=this.element;if(/relative/.test(B.css("position"))&&A.browser.opera){B.css({position:"relative",top:"auto",left:"auto"})}B.wrap(A('<div class="ui-wrapper" style="overflow: hidden;"></div>').css({position:B.css("position"),width:B.outerWidth(),height:B.outerHeight(),top:B.css("top"),left:B.css("left")}));var J=this.element;this.element=this.element.parent();this.element.data("resizable",this);this.element.css({marginLeft:J.css("marginLeft"),marginTop:J.css("marginTop"),marginRight:J.css("marginRight"),marginBottom:J.css("marginBottom")});J.css({marginLeft:0,marginTop:0,marginRight:0,marginBottom:0});if(A.browser.safari&&N.preventDefault){J.css("resize","none")}N.proportionallyResize=J.css({position:"static",zoom:1,display:"block"});this.element.css({margin:J.css("margin")});this._proportionallyResize()}if(!N.handles){N.handles=!A(".ui-resizable-handle",this.element).length?"e,s,se":{n:".ui-resizable-n",e:".ui-resizable-e",s:".ui-resizable-s",w:".ui-resizable-w",se:".ui-resizable-se",sw:".ui-resizable-sw",ne:".ui-resizable-ne",nw:".ui-resizable-nw"}}if(N.handles.constructor==String){N.zIndex=N.zIndex||1000;if(N.handles=="all"){N.handles="n,e,s,w,se,sw,ne,nw"}var O=N.handles.split(",");N.handles={};var G={handle:"position: absolute; display: none; overflow:hidden;",n:"top: 0pt; width:100%;",e:"right: 0pt; height:100%;",s:"bottom: 0pt; width:100%;",w:"left: 0pt; height:100%;",se:"bottom: 0pt; right: 0px;",sw:"bottom: 0pt; left: 0px;",ne:"top: 0pt; right: 0px;",nw:"top: 0pt; left: 0px;"};for(var R=0;R<O.length;R++){var S=A.trim(O[R]),L=N.defaultTheme,F="ui-resizable-"+S,C=!A.ui.css(F)&&!N.knobHandles,P=A.ui.css("ui-resizable-knob-handle"),T=A.extend(L[F],L["ui-resizable-handle"]),D=A.extend(N.knobTheme[F],!P?N.knobTheme["ui-resizable-handle"]:{});var K=/sw|se|ne|nw/.test(S)?{zIndex:++N.zIndex}:{};var I=(C?G[S]:""),E=A(['<div class="ui-resizable-handle ',F,'" style="',I,G.handle,'"></div>'].join("")).css(K);N.handles[S]=".ui-resizable-"+S;this.element.append(E.css(C?T:{}).css(N.knobHandles?D:{}).addClass(N.knobHandles?"ui-resizable-knob-handle":"").addClass(N.knobHandles))}if(N.knobHandles){this.element.addClass("ui-resizable-knob").css(!A.ui.css("ui-resizable-knob")?{}:{})}}this._renderAxis=function(Y){Y=Y||this.element;for(var V in N.handles){if(N.handles[V].constructor==String){N.handles[V]=A(N.handles[V],this.element).show()}if(N.transparent){N.handles[V].css({opacity:0})}if(this.element.is(".ui-wrapper")&&N._nodeName.match(/textarea|input|select|button/i)){var W=A(N.handles[V],this.element),X=0;X=/sw|ne|nw|se|n|s/.test(V)?W.outerHeight():W.outerWidth();var U=["padding",/ne|nw|n/.test(V)?"Top":/se|sw|s/.test(V)?"Bottom":/^e$/.test(V)?"Right":"Left"].join("");if(!N.transparent){Y.css(U,X)}this._proportionallyResize()}if(!A(N.handles[V]).length){continue}}};this._renderAxis(this.element);N._handles=A(".ui-resizable-handle",M.element);if(N.disableSelection){N._handles.each(function(U,V){A.ui.disableSelection(V)})}N._handles.mouseover(function(){if(!N.resizing){if(this.className){var U=this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i)}M.axis=N.axis=U&&U[1]?U[1]:"se"}});if(N.autoHide){N._handles.hide();A(M.element).addClass("ui-resizable-autohide").hover(function(){A(this).removeClass("ui-resizable-autohide");N._handles.show()},function(){if(!N.resizing){A(this).addClass("ui-resizable-autohide");N._handles.hide()}})}this._mouseInit()},plugins:{},ui:function(){return{originalElement:this.originalElement,element:this.element,helper:this.helper,position:this.position,size:this.size,options:this.options,originalSize:this.originalSize,originalPosition:this.originalPosition}},_propagate:function(C,B){A.ui.plugin.call(this,C,[B,this.ui()]);if(C!="resize"){this.element.triggerHandler(["resize",C].join(""),[B,this.ui()],this.options[C])}},destroy:function(){var D=this.element,C=D.children(".ui-resizable").get(0);this._mouseDestroy();var B=function(E){A(E).removeClass("ui-resizable ui-resizable-disabled").removeData("resizable").unbind(".resizable").find(".ui-resizable-handle").remove()};B(D);if(D.is(".ui-wrapper")&&C){D.parent().append(A(C).css({position:D.css("position"),width:D.outerWidth(),height:D.outerHeight(),top:D.css("top"),left:D.css("left")})).end().remove();B(C)}},_mouseCapture:function(D){if(this.options.disabled){return false}var C=false;for(var B in this.options.handles){if(A(this.options.handles[B])[0]==D.target){C=true}}if(!C){return false}return true},_mouseStart:function(I){var C=this.options,B=this.element.position(),D=this.element,H=function(M){return parseInt(M,10)||0},G=A.browser.msie&&A.browser.version<7;C.resizing=true;C.documentScroll={top:A(document).scrollTop(),left:A(document).scrollLeft()};if(D.is(".ui-draggable")||(/absolute/).test(D.css("position"))){var J=A.browser.msie&&!C.containment&&(/absolute/).test(D.css("position"))&&!(/relative/).test(D.parent().css("position"));var K=J?C.documentScroll.top:0,F=J?C.documentScroll.left:0;D.css({position:"absolute",top:(B.top+K),left:(B.left+F)})}if(A.browser.opera&&/relative/.test(D.css("position"))){D.css({position:"relative",top:"auto",left:"auto"})}this._renderProxy();var L=H(this.helper.css("left")),E=H(this.helper.css("top"));if(C.containment){L+=A(C.containment).scrollLeft()||0;E+=A(C.containment).scrollTop()||0}this.offset=this.helper.offset();this.position={left:L,top:E};this.size=C.helper||G?{width:D.outerWidth(),height:D.outerHeight()}:{width:D.width(),height:D.height()};this.originalSize=C.helper||G?{width:D.outerWidth(),height:D.outerHeight()}:{width:D.width(),height:D.height()};this.originalPosition={left:L,top:E};this.sizeDiff={width:D.outerWidth()-D.width(),height:D.outerHeight()-D.height()};this.originalMousePosition={left:I.pageX,top:I.pageY};C.aspectRatio=(typeof C.aspectRatio=="number")?C.aspectRatio:((this.originalSize.width/this.originalSize.height)||1);if(C.preserveCursor){A("body").css("cursor",this.axis+"-resize")}this._propagate("start",I);return true},_mouseDrag:function(I){var D=this.helper,C=this.options,J={},M=this,F=this.originalMousePosition,K=this.axis;var N=(I.pageX-F.left)||0,L=(I.pageY-F.top)||0;var E=this._change[K];if(!E){return false}var H=E.apply(this,[I,N,L]),G=A.browser.msie&&A.browser.version<7,B=this.sizeDiff;if(C._aspectRatio||I.shiftKey){H=this._updateRatio(H,I)}H=this._respectSize(H,I);this._propagate("resize",I);D.css({top:this.position.top+"px",left:this.position.left+"px",width:this.size.width+"px",height:this.size.height+"px"});if(!C.helper&&C.proportionallyResize){this._proportionallyResize()}this._updateCache(H);this.element.triggerHandler("resize",[I,this.ui()],this.options["resize"]);return false},_mouseStop:function(I){this.options.resizing=false;var E=this.options,H=function(M){return parseInt(M,10)||0},K=this;if(E.helper){var D=E.proportionallyResize,B=D&&(/textarea/i).test(D.get(0).nodeName),C=B&&A.ui.hasScroll(D.get(0),"left")?0:K.sizeDiff.height,G=B?0:K.sizeDiff.width;var L={width:(K.size.width-G),height:(K.size.height-C)},F=(parseInt(K.element.css("left"),10)+(K.position.left-K.originalPosition.left))||null,J=(parseInt(K.element.css("top"),10)+(K.position.top-K.originalPosition.top))||null;if(!E.animate){this.element.css(A.extend(L,{top:J,left:F}))}if(E.helper&&!E.animate){this._proportionallyResize()}}if(E.preserveCursor){A("body").css("cursor","auto")}this._propagate("stop",I);if(E.helper){this.helper.remove()}return false},_updateCache:function(B){var C=this.options;this.offset=this.helper.offset();if(B.left){this.position.left=B.left}if(B.top){this.position.top=B.top}if(B.height){this.size.height=B.height}if(B.width){this.size.width=B.width}},_updateRatio:function(D,E){var F=this.options,G=this.position,C=this.size,B=this.axis;if(D.height){D.width=(C.height*F.aspectRatio)}else{if(D.width){D.height=(C.width/F.aspectRatio)}}if(B=="sw"){D.left=G.left+(C.width-D.width);D.top=null}if(B=="nw"){D.top=G.top+(C.height-D.height);D.left=G.left+(C.width-D.width)}return D},_respectSize:function(H,I){var F=this.helper,E=this.options,N=E._aspectRatio||I.shiftKey,M=this.axis,P=H.width&&E.maxWidth&&E.maxWidth<H.width,J=H.height&&E.maxHeight&&E.maxHeight<H.height,D=H.width&&E.minWidth&&E.minWidth>H.width,O=H.height&&E.minHeight&&E.minHeight>H.height;if(D){H.width=E.minWidth}if(O){H.height=E.minHeight}if(P){H.width=E.maxWidth}if(J){H.height=E.maxHeight}var C=this.originalPosition.left+this.originalSize.width,L=this.position.top+this.size.height;var G=/sw|nw|w/.test(M),B=/nw|ne|n/.test(M);if(D&&G){H.left=C-E.minWidth}if(P&&G){H.left=C-E.maxWidth}if(O&&B){H.top=L-E.minHeight}if(J&&B){H.top=L-E.maxHeight}var K=!H.width&&!H.height;if(K&&!H.left&&H.top){H.top=null}else{if(K&&!H.top&&H.left){H.left=null}}return H},_proportionallyResize:function(){var F=this.options;if(!F.proportionallyResize){return }var D=F.proportionallyResize,C=this.helper||this.element;if(!F.borderDif){var B=[D.css("borderTopWidth"),D.css("borderRightWidth"),D.css("borderBottomWidth"),D.css("borderLeftWidth")],E=[D.css("paddingTop"),D.css("paddingRight"),D.css("paddingBottom"),D.css("paddingLeft")];F.borderDif=A.map(B,function(G,I){var H=parseInt(G,10)||0,J=parseInt(E[I],10)||0;return H+J})}D.css({height:(C.height()-F.borderDif[0]-F.borderDif[2])+"px",width:(C.width()-F.borderDif[1]-F.borderDif[3])+"px"})},_renderProxy:function(){var C=this.element,F=this.options;this.elementOffset=C.offset();if(F.helper){this.helper=this.helper||A('<div style="overflow:hidden;"></div>');var B=A.browser.msie&&A.browser.version<7,D=(B?1:0),E=(B?2:-1);this.helper.addClass(F.helper).css({width:C.outerWidth()+E,height:C.outerHeight()+E,position:"absolute",left:this.elementOffset.left-D+"px",top:this.elementOffset.top-D+"px",zIndex:++F.zIndex});this.helper.appendTo("body");if(F.disableSelection){A.ui.disableSelection(this.helper.get(0))}}else{this.helper=C}},_change:{e:function(D,C,B){return{width:this.originalSize.width+C}},w:function(F,C,B){var G=this.options,D=this.originalSize,E=this.originalPosition;return{left:E.left+C,width:D.width-C}},n:function(F,C,B){var G=this.options,D=this.originalSize,E=this.originalPosition;return{top:E.top+B,height:D.height-B}},s:function(D,C,B){return{height:this.originalSize.height+B}},se:function(D,C,B){return A.extend(this._change.s.apply(this,arguments),this._change.e.apply(this,[D,C,B]))},sw:function(D,C,B){return A.extend(this._change.s.apply(this,arguments),this._change.w.apply(this,[D,C,B]))},ne:function(D,C,B){return A.extend(this._change.n.apply(this,arguments),this._change.e.apply(this,[D,C,B]))},nw:function(D,C,B){return A.extend(this._change.n.apply(this,arguments),this._change.w.apply(this,[D,C,B]))}}}));A.extend(A.ui.resizable,{defaults:{cancel:":input",distance:1,delay:0,preventDefault:true,transparent:false,minWidth:10,minHeight:10,aspectRatio:false,disableSelection:true,preserveCursor:true,autoHide:false,knobHandles:false}});A.ui.plugin.add("resizable","containment",{start:function(I,K){var E=K.options,M=A(this).data("resizable"),G=M.element;var C=E.containment,F=(C instanceof A)?C.get(0):(/parent/.test(C))?G.parent().get(0):C;if(!F){return }M.containerElement=A(F);if(/document/.test(C)||C==document){M.containerOffset={left:0,top:0};M.containerPosition={left:0,top:0};M.parentData={element:A(document),left:0,top:0,width:A(document).width(),height:A(document).height()||document.body.parentNode.scrollHeight}}else{M.containerOffset=A(F).offset();M.containerPosition=A(F).position();M.containerSize={height:A(F).innerHeight(),width:A(F).innerWidth()};var J=M.containerOffset,B=M.containerSize.height,H=M.containerSize.width,D=(A.ui.hasScroll(F,"left")?F.scrollWidth:H),L=(A.ui.hasScroll(F)?F.scrollHeight:B);M.parentData={element:F,left:J.left,top:J.top,width:D,height:L}}},resize:function(H,K){var E=K.options,N=A(this).data("resizable"),C=N.containerSize,J=N.containerOffset,G=N.size,I=N.position,L=E._aspectRatio||H.shiftKey,B={top:0,left:0},D=N.containerElement;if(D[0]!=document&&/static/.test(D.css("position"))){B=N.containerPosition}if(I.left<(E.helper?J.left:B.left)){N.size.width=N.size.width+(E.helper?(N.position.left-J.left):(N.position.left-B.left));if(L){N.size.height=N.size.width/E.aspectRatio}N.position.left=E.helper?J.left:B.left}if(I.top<(E.helper?J.top:0)){N.size.height=N.size.height+(E.helper?(N.position.top-J.top):N.position.top);if(L){N.size.width=N.size.height*E.aspectRatio}N.position.top=E.helper?J.top:0}var F=(E.helper?N.offset.left-J.left:(N.position.left-B.left))+N.sizeDiff.width,M=(E.helper?N.offset.top-J.top:N.position.top)+N.sizeDiff.height;if(F+N.size.width>=N.parentData.width){N.size.width=N.parentData.width-F;if(L){N.size.height=N.size.width/E.aspectRatio}}if(M+N.size.height>=N.parentData.height){N.size.height=N.parentData.height-M;if(L){N.size.width=N.size.height*E.aspectRatio}}},stop:function(G,J){var C=J.options,L=A(this).data("resizable"),H=L.position,I=L.containerOffset,B=L.containerPosition,D=L.containerElement;var E=A(L.helper),M=E.offset(),K=E.innerWidth(),F=E.innerHeight();if(C.helper&&!C.animate&&/relative/.test(D.css("position"))){A(this).css({left:(M.left-I.left),top:(M.top-I.top),width:K,height:F})}if(C.helper&&!C.animate&&/static/.test(D.css("position"))){A(this).css({left:B.left+(M.left-I.left),top:B.top+(M.top-I.top),width:K,height:F})}}});A.ui.plugin.add("resizable","grid",{resize:function(H,J){var D=J.options,L=A(this).data("resizable"),G=L.size,E=L.originalSize,F=L.originalPosition,K=L.axis,I=D._aspectRatio||H.shiftKey;D.grid=typeof D.grid=="number"?[D.grid,D.grid]:D.grid;var C=Math.round((G.width-E.width)/(D.grid[0]||1))*(D.grid[0]||1),B=Math.round((G.height-E.height)/(D.grid[1]||1))*(D.grid[1]||1);if(/^(se|s|e)$/.test(K)){L.size.width=E.width+C;L.size.height=E.height+B}else{if(/^(ne)$/.test(K)){L.size.width=E.width+C;L.size.height=E.height+B;L.position.top=F.top-B}else{if(/^(sw)$/.test(K)){L.size.width=E.width+C;L.size.height=E.height+B;L.position.left=F.left-C}else{L.size.width=E.width+C;L.size.height=E.height+B;L.position.top=F.top-B;L.position.left=F.left-C}}}}});A.ui.plugin.add("resizable","animate",{stop:function(I,K){var F=K.options,L=A(this).data("resizable");var E=F.proportionallyResize,B=E&&(/textarea/i).test(E.get(0).nodeName),C=B&&A.ui.hasScroll(E.get(0),"left")?0:L.sizeDiff.height,H=B?0:L.sizeDiff.width;var D={width:(L.size.width-H),height:(L.size.height-C)},G=(parseInt(L.element.css("left"),10)+(L.position.left-L.originalPosition.left))||null,J=(parseInt(L.element.css("top"),10)+(L.position.top-L.originalPosition.top))||null;L.element.animate(A.extend(D,J&&G?{top:J,left:G}:{}),{duration:F.animateDuration||"slow",easing:F.animateEasing||"swing",step:function(){var M={width:parseInt(L.element.css("width"),10),height:parseInt(L.element.css("height"),10),top:parseInt(L.element.css("top"),10),left:parseInt(L.element.css("left"),10)};if(E){E.css({width:M.width,height:M.height})}L._updateCache(M);L._propagate("animate",I)}})}});A.ui.plugin.add("resizable","ghost",{start:function(E,D){var F=D.options,B=A(this).data("resizable"),G=F.proportionallyResize,C=B.size;if(!G){B.ghost=B.element.clone()}else{B.ghost=G.clone()}B.ghost.css({opacity:0.25,display:"block",position:"relative",height:C.height,width:C.width,margin:0,left:0,top:0}).addClass("ui-resizable-ghost").addClass(typeof F.ghost=="string"?F.ghost:"");B.ghost.appendTo(B.helper)},resize:function(D,C){var E=C.options,B=A(this).data("resizable"),F=E.proportionallyResize;if(B.ghost){B.ghost.css({position:"relative",height:B.size.height,width:B.size.width})}},stop:function(D,C){var E=C.options,B=A(this).data("resizable"),F=E.proportionallyResize;if(B.ghost&&B.helper){B.helper.get(0).removeChild(B.ghost.get(0))}}});A.ui.plugin.add("resizable","alsoResize",{start:function(E,C){var F=C.options,B=A(this).data("resizable"),D=function(G){A(G).each(function(){A(this).data("resizable-alsoresize",{width:parseInt(A(this).width(),10),height:parseInt(A(this).height(),10),left:parseInt(A(this).css("left"),10),top:parseInt(A(this).css("top"),10)})})};if(typeof (F.alsoResize)=="object"){if(F.alsoResize.length){F.alsoResize=F.alsoResize[0];D(F.alsoResize)}else{A.each(F.alsoResize,function(G,H){D(G)})}}else{D(F.alsoResize)}},resize:function(F,E){var G=E.options,C=A(this).data("resizable"),D=C.originalSize,I=C.originalPosition;var H={height:(C.size.height-D.height)||0,width:(C.size.width-D.width)||0,top:(C.position.top-I.top)||0,left:(C.position.left-I.left)||0},B=function(J,K){A(J).each(function(){var N=A(this).data("resizable-alsoresize"),M={},L=K&&K.length?K:["width","height","top","left"];A.each(L||["width","height","top","left"],function(O,Q){var P=(N[Q]||0)+(H[Q]||0);if(P&&P>=0){M[Q]=P||null}});A(this).css(M)})};if(typeof (G.alsoResize)=="object"){A.each(G.alsoResize,function(J,K){B(J,K)})}else{B(G.alsoResize)}},stop:function(C,B){A(this).removeData("resizable-alsoresize-start")}})})(jQuery) \ No newline at end of file
diff --git a/site/app/webroot/js/jquery-ui/ui.selectable.min.js b/site/app/webroot/js/jquery-ui/ui.selectable.min.js
new file mode 100755
index 0000000..b88cacf
--- /dev/null
+++ b/site/app/webroot/js/jquery-ui/ui.selectable.min.js
@@ -0,0 +1 @@
+(function(A){A.widget("ui.selectable",A.extend({},A.ui.mouse,{_init:function(){var B=this;this.element.addClass("ui-selectable");this.dragged=false;var C;this.refresh=function(){C=A(B.options.filter,B.element[0]);C.each(function(){var D=A(this);var E=D.offset();A.data(this,"selectable-item",{element:this,$element:D,left:E.left,top:E.top,right:E.left+D.width(),bottom:E.top+D.height(),startselected:false,selected:D.hasClass("ui-selected"),selecting:D.hasClass("ui-selecting"),unselecting:D.hasClass("ui-unselecting")})})};this.refresh();this.selectees=C.addClass("ui-selectee");this._mouseInit();this.helper=A(document.createElement("div")).css({border:"1px dotted black"}).addClass("ui-selectable-helper")},toggle:function(){if(this.options.disabled){this.enable()}else{this.disable()}},destroy:function(){this.element.removeClass("ui-selectable ui-selectable-disabled").removeData("selectable").unbind(".selectable");this._mouseDestroy()},_mouseStart:function(E){var C=this;this.opos=[E.pageX,E.pageY];if(this.options.disabled){return }var D=this.options;this.selectees=A(D.filter,this.element[0]);this.element.triggerHandler("selectablestart",[E,{"selectable":this.element[0],"options":D}],D.start);A("body").append(this.helper);this.helper.css({"z-index":100,"position":"absolute","left":E.clientX,"top":E.clientY,"width":0,"height":0});if(D.autoRefresh){this.refresh()}this.selectees.filter(".ui-selected").each(function(){var F=A.data(this,"selectable-item");F.startselected=true;if(!E.metaKey){F.$element.removeClass("ui-selected");F.selected=false;F.$element.addClass("ui-unselecting");F.unselecting=true;C.element.triggerHandler("selectableunselecting",[E,{selectable:C.element[0],unselecting:F.element,options:D}],D.unselecting)}});var B=false;A(E.target).parents().andSelf().each(function(){if(A.data(this,"selectable-item")){B=true}});return this.options.keyboard?!B:true},_mouseDrag:function(I){var C=this;this.dragged=true;if(this.options.disabled){return }var E=this.options;var D=this.opos[0],H=this.opos[1],B=I.pageX,G=I.pageY;if(D>B){var F=B;B=D;D=F}if(H>G){var F=G;G=H;H=F}this.helper.css({left:D,top:H,width:B-D,height:G-H});this.selectees.each(function(){var J=A.data(this,"selectable-item");if(!J||J.element==C.element[0]){return }var K=false;if(E.tolerance=="touch"){K=(!(J.left>B||J.right<D||J.top>G||J.bottom<H))}else{if(E.tolerance=="fit"){K=(J.left>D&&J.right<B&&J.top>H&&J.bottom<G)}}if(K){if(J.selected){J.$element.removeClass("ui-selected");J.selected=false}if(J.unselecting){J.$element.removeClass("ui-unselecting");J.unselecting=false}if(!J.selecting){J.$element.addClass("ui-selecting");J.selecting=true;C.element.triggerHandler("selectableselecting",[I,{selectable:C.element[0],selecting:J.element,options:E}],E.selecting)}}else{if(J.selecting){if(I.metaKey&&J.startselected){J.$element.removeClass("ui-selecting");J.selecting=false;J.$element.addClass("ui-selected");J.selected=true}else{J.$element.removeClass("ui-selecting");J.selecting=false;if(J.startselected){J.$element.addClass("ui-unselecting");J.unselecting=true}C.element.triggerHandler("selectableunselecting",[I,{selectable:C.element[0],unselecting:J.element,options:E}],E.unselecting)}}if(J.selected){if(!I.metaKey&&!J.startselected){J.$element.removeClass("ui-selected");J.selected=false;J.$element.addClass("ui-unselecting");J.unselecting=true;C.element.triggerHandler("selectableunselecting",[I,{selectable:C.element[0],unselecting:J.element,options:E}],E.unselecting)}}}});return false},_mouseStop:function(D){var B=this;this.dragged=false;var C=this.options;A(".ui-unselecting",this.element[0]).each(function(){var E=A.data(this,"selectable-item");E.$element.removeClass("ui-unselecting");E.unselecting=false;E.startselected=false;B.element.triggerHandler("selectableunselected",[D,{selectable:B.element[0],unselected:E.element,options:C}],C.unselected)});A(".ui-selecting",this.element[0]).each(function(){var E=A.data(this,"selectable-item");E.$element.removeClass("ui-selecting").addClass("ui-selected");E.selecting=false;E.selected=true;E.startselected=true;B.element.triggerHandler("selectableselected",[D,{selectable:B.element[0],selected:E.element,options:C}],C.selected)});this.element.triggerHandler("selectablestop",[D,{selectable:B.element[0],options:this.options}],this.options.stop);this.helper.remove();return false}}));A.extend(A.ui.selectable,{defaults:{distance:1,delay:0,cancel:":input",appendTo:"body",autoRefresh:true,filter:"*",tolerance:"touch"}})})(jQuery) \ No newline at end of file
diff --git a/site/app/webroot/js/jquery-ui/ui.slider.min.js b/site/app/webroot/js/jquery-ui/ui.slider.min.js
new file mode 100755
index 0000000..0bb40ed
--- /dev/null
+++ b/site/app/webroot/js/jquery-ui/ui.slider.min.js
@@ -0,0 +1 @@
+(function(A){A.fn.unwrap=A.fn.unwrap||function(B){return this.each(function(){A(this).parents(B).eq(0).after(this).remove()})};A.widget("ui.slider",{plugins:{},ui:function(B){return{options:this.options,handle:this.currentHandle,value:this.options.axis!="both"||!this.options.axis?Math.round(this.value(null,this.options.axis=="vertical"?"y":"x")):{x:Math.round(this.value(null,"x")),y:Math.round(this.value(null,"y"))},range:this._getRange()}},_propagate:function(C,B){A.ui.plugin.call(this,C,[B,this.ui()]);this.element.triggerHandler(C=="slide"?C:"slide"+C,[B,this.ui()],this.options[C])},destroy:function(){this.element.removeClass("ui-slider ui-slider-disabled").removeData("slider").unbind(".slider");if(this.handle&&this.handle.length){this.handle.unwrap("a");this.handle.each(function(){A(this).data("mouse")._mouseDestroy()})}this.generated&&this.generated.remove()},_setData:function(B,C){A.widget.prototype._setData.apply(this,arguments);if(/min|max|steps/.test(B)){this._initBoundaries()}if(B=="range"){C?this.handle.length==2&&this._createRange():this._removeRange()}},_init:function(){var B=this;this.element.addClass("ui-slider");this._initBoundaries();this.handle=A(this.options.handle,this.element);if(!this.handle.length){B.handle=B.generated=A(B.options.handles||[0]).map(function(){var D=A("<div/>").addClass("ui-slider-handle").appendTo(B.element);if(this.id){D.attr("id",this.id)}return D[0]})}var C=function(D){this.element=A(D);this.element.data("mouse",this);this.options=B.options;this.element.bind("mousedown",function(){if(B.currentHandle){this.blur(B.currentHandle)}B._focus(this,true)});this._mouseInit()};A.extend(C.prototype,A.ui.mouse,{_mouseStart:function(D){return B._start.call(B,D,this.element[0])},_mouseStop:function(D){return B._stop.call(B,D,this.element[0])},_mouseDrag:function(D){return B._drag.call(B,D,this.element[0])},_mouseCapture:function(){return true},trigger:function(D){this._mouseDown(D)}});A(this.handle).each(function(){new C(this)}).wrap('<a href="#" style="outline:none;border:none;"></a>').parent().bind("click",function(){return false}).bind("focus",function(D){B._focus(this.firstChild)}).bind("blur",function(D){B._blur(this.firstChild)}).bind("keydown",function(D){if(!B.options.noKeyboard){return B._keydown(D.keyCode,this.firstChild)}});this.element.bind("mousedown.slider",function(D){B._click.apply(B,[D]);B.currentHandle.data("mouse").trigger(D);B.firstValue=B.firstValue+1});A.each(this.options.handles||[],function(D,E){B.moveTo(E.start,D,true)});if(!isNaN(this.options.startValue)){this.moveTo(this.options.startValue,0,true)}this.previousHandle=A(this.handle[0]);if(this.handle.length==2&&this.options.range){this._createRange()}},_initBoundaries:function(){var B=this.element[0],C=this.options;this.actualSize={width:this.element.outerWidth(),height:this.element.outerHeight()};A.extend(C,{axis:C.axis||(B.offsetWidth<B.offsetHeight?"vertical":"horizontal"),max:!isNaN(parseInt(C.max,10))?{x:parseInt(C.max,10),y:parseInt(C.max,10)}:({x:C.max&&C.max.x||100,y:C.max&&C.max.y||100}),min:!isNaN(parseInt(C.min,10))?{x:parseInt(C.min,10),y:parseInt(C.min,10)}:({x:C.min&&C.min.x||0,y:C.min&&C.min.y||0})});C.realMax={x:C.max.x-C.min.x,y:C.max.y-C.min.y};C.stepping={x:C.stepping&&C.stepping.x||parseInt(C.stepping,10)||(C.steps?C.realMax.x/(C.steps.x||parseInt(C.steps,10)||C.realMax.x):0),y:C.stepping&&C.stepping.y||parseInt(C.stepping,10)||(C.steps?C.realMax.y/(C.steps.y||parseInt(C.steps,10)||C.realMax.y):0)}},_keydown:function(F,E){var C=F;if(/(33|34|35|36|37|38|39|40)/.test(C)){var G=this.options,B,I;if(/(35|36)/.test(C)){B=(C==35)?G.max.x:G.min.x;I=(C==35)?G.max.y:G.min.y}else{var H=/(34|37|40)/.test(C)?"-=":"+=";var D=/(37|38|39|40)/.test(C)?"_oneStep":"_pageStep";B=H+this[D]("x");I=H+this[D]("y")}this.moveTo({x:B,y:I},E);return false}return true},_focus:function(B,C){this.currentHandle=A(B).addClass("ui-slider-handle-active");if(C){this.currentHandle.parent()[0].focus()}},_blur:function(B){A(B).removeClass("ui-slider-handle-active");if(this.currentHandle&&this.currentHandle[0]==B){this.previousHandle=this.currentHandle;this.currentHandle=null}},_click:function(C){var D=[C.pageX,C.pageY];var B=false;this.handle.each(function(){if(this==C.target){B=true}});if(B||this.options.disabled||!(this.currentHandle||this.previousHandle)){return }if(!this.currentHandle&&this.previousHandle){this._focus(this.previousHandle,true)}this.offset=this.element.offset();this.moveTo({y:this._convertValue(C.pageY-this.offset.top-this.currentHandle[0].offsetHeight/2,"y"),x:this._convertValue(C.pageX-this.offset.left-this.currentHandle[0].offsetWidth/2,"x")},null,!this.options.distance)},_createRange:function(){if(this.rangeElement){return }this.rangeElement=A("<div></div>").addClass("ui-slider-range").css({position:"absolute"}).appendTo(this.element);this._updateRange()},_removeRange:function(){this.rangeElement.remove();this.rangeElement=null},_updateRange:function(){var C=this.options.axis=="vertical"?"top":"left";var B=this.options.axis=="vertical"?"height":"width";this.rangeElement.css(C,(parseInt(A(this.handle[0]).css(C),10)||0)+this._handleSize(0,this.options.axis=="vertical"?"y":"x")/2);this.rangeElement.css(B,(parseInt(A(this.handle[1]).css(C),10)||0)-(parseInt(A(this.handle[0]).css(C),10)||0))},_getRange:function(){return this.rangeElement?this._convertValue(parseInt(this.rangeElement.css(this.options.axis=="vertical"?"height":"width"),10),this.options.axis=="vertical"?"y":"x"):null},_handleIndex:function(){return this.handle.index(this.currentHandle[0])},value:function(D,B){if(this.handle.length==1){this.currentHandle=this.handle}if(!B){B=this.options.axis=="vertical"?"y":"x"}var C=A(D!=undefined&&D!==null?this.handle[D]||D:this.currentHandle);if(C.data("mouse").sliderValue){return parseInt(C.data("mouse").sliderValue[B],10)}else{return parseInt(((parseInt(C.css(B=="x"?"left":"top"),10)/(this.actualSize[B=="x"?"width":"height"]-this._handleSize(D,B)))*this.options.realMax[B])+this.options.min[B],10)}},_convertValue:function(C,B){return this.options.min[B]+(C/(this.actualSize[B=="x"?"width":"height"]-this._handleSize(null,B)))*this.options.realMax[B]},_translateValue:function(C,B){return((C-this.options.min[B])/this.options.realMax[B])*(this.actualSize[B=="x"?"width":"height"]-this._handleSize(null,B))},_translateRange:function(D,B){if(this.rangeElement){if(this.currentHandle[0]==this.handle[0]&&D>=this._translateValue(this.value(1),B)){D=this._translateValue(this.value(1,B)-this._oneStep(B),B)}if(this.currentHandle[0]==this.handle[1]&&D<=this._translateValue(this.value(0),B)){D=this._translateValue(this.value(0,B)+this._oneStep(B),B)}}if(this.options.handles){var C=this.options.handles[this._handleIndex()];if(D<this._translateValue(C.min,B)){D=this._translateValue(C.min,B)}else{if(D>this._translateValue(C.max,B)){D=this._translateValue(C.max,B)}}}return D},_translateLimits:function(C,B){if(C>=this.actualSize[B=="x"?"width":"height"]-this._handleSize(null,B)){C=this.actualSize[B=="x"?"width":"height"]-this._handleSize(null,B)}if(C<=0){C=0}return C},_handleSize:function(C,B){return A(C!=undefined&&C!==null?this.handle[C]:this.currentHandle)[0]["offset"+(B=="x"?"Width":"Height")]},_oneStep:function(B){return this.options.stepping[B]||1},_pageStep:function(B){return 10},_start:function(C,B){var D=this.options;if(D.disabled){return false}this.actualSize={width:this.element.outerWidth(),height:this.element.outerHeight()};if(!this.currentHandle){this._focus(this.previousHandle,true)}this.offset=this.element.offset();this.handleOffset=this.currentHandle.offset();this.clickOffset={top:C.pageY-this.handleOffset.top,left:C.pageX-this.handleOffset.left};this.firstValue=this.value();this._propagate("start",C);this._drag(C,B);return true},_stop:function(B){this._propagate("stop",B);if(this.firstValue!=this.value()){this._propagate("change",B)}this._focus(this.currentHandle,true);return false},_drag:function(E,D){var F=this.options;var B={top:E.pageY-this.offset.top-this.clickOffset.top,left:E.pageX-this.offset.left-this.clickOffset.left};if(!this.currentHandle){this._focus(this.previousHandle,true)}B.left=this._translateLimits(B.left,"x");B.top=this._translateLimits(B.top,"y");if(F.stepping.x){var C=this._convertValue(B.left,"x");C=Math.round(C/F.stepping.x)*F.stepping.x;B.left=this._translateValue(C,"x")}if(F.stepping.y){var C=this._convertValue(B.top,"y");C=Math.round(C/F.stepping.y)*F.stepping.y;B.top=this._translateValue(C,"y")}B.left=this._translateRange(B.left,"x");B.top=this._translateRange(B.top,"y");if(F.axis!="vertical"){this.currentHandle.css({left:B.left})}if(F.axis!="horizontal"){this.currentHandle.css({top:B.top})}this.currentHandle.data("mouse").sliderValue={x:Math.round(this._convertValue(B.left,"x"))||0,y:Math.round(this._convertValue(B.top,"y"))||0};if(this.rangeElement){this._updateRange()}this._propagate("slide",E);return false},moveTo:function(F,E,G){var H=this.options;this.actualSize={width:this.element.outerWidth(),height:this.element.outerHeight()};if(E==undefined&&!this.currentHandle&&this.handle.length!=1){return false}if(E==undefined&&!this.currentHandle){E=0}if(E!=undefined){this.currentHandle=this.previousHandle=A(this.handle[E]||E)}if(F.x!==undefined&&F.y!==undefined){var B=F.x,I=F.y}else{var B=F,I=F}if(B!==undefined&&B.constructor!=Number){var D=/^\-\=/.test(B),C=/^\+\=/.test(B);if(D||C){B=this.value(null,"x")+parseInt(B.replace(D?"=":"+=",""),10)}else{B=isNaN(parseInt(B,10))?undefined:parseInt(B,10)}}if(I!==undefined&&I.constructor!=Number){var D=/^\-\=/.test(I),C=/^\+\=/.test(I);if(D||C){I=this.value(null,"y")+parseInt(I.replace(D?"=":"+=",""),10)}else{I=isNaN(parseInt(I,10))?undefined:parseInt(I,10)}}if(H.axis!="vertical"&&B!==undefined){if(H.stepping.x){B=Math.round(B/H.stepping.x)*H.stepping.x}B=this._translateValue(B,"x");B=this._translateLimits(B,"x");B=this._translateRange(B,"x");H.animate?this.currentHandle.stop().animate({left:B},(Math.abs(parseInt(this.currentHandle.css("left"))-B))*(!isNaN(parseInt(H.animate))?H.animate:5)):this.currentHandle.css({left:B})}if(H.axis!="horizontal"&&I!==undefined){if(H.stepping.y){I=Math.round(I/H.stepping.y)*H.stepping.y}I=this._translateValue(I,"y");I=this._translateLimits(I,"y");I=this._translateRange(I,"y");H.animate?this.currentHandle.stop().animate({top:I},(Math.abs(parseInt(this.currentHandle.css("top"))-I))*(!isNaN(parseInt(H.animate))?H.animate:5)):this.currentHandle.css({top:I})}if(this.rangeElement){this._updateRange()}this.currentHandle.data("mouse").sliderValue={x:Math.round(this._convertValue(B,"x"))||0,y:Math.round(this._convertValue(I,"y"))||0};if(!G){this._propagate("start",null);this._propagate("stop",null);this._propagate("change",null);this._propagate("slide",null)}}});A.ui.slider.getter="value";A.ui.slider.defaults={handle:".ui-slider-handle",distance:1,animate:false}})(jQuery) \ No newline at end of file
diff --git a/site/app/webroot/js/jquery-ui/ui.sortable.min.js b/site/app/webroot/js/jquery-ui/ui.sortable.min.js
new file mode 100755
index 0000000..8203da2
--- /dev/null
+++ b/site/app/webroot/js/jquery-ui/ui.sortable.min.js
@@ -0,0 +1 @@
+(function(B){function A(E,D){var C=B.browser.safari&&B.browser.version<522;if(E.contains&&!C){return E.contains(D)}if(E.compareDocumentPosition){return !!(E.compareDocumentPosition(D)&16)}while(D=D.parentNode){if(D==E){return true}}return false}B.widget("ui.sortable",B.extend({},B.ui.mouse,{_init:function(){var C=this.options;this.containerCache={};this.element.addClass("ui-sortable");this.refresh();this.floating=this.items.length?(/left|right/).test(this.items[0].item.css("float")):false;this.offset=this.element.offset();this._mouseInit()},plugins:{},ui:function(C){return{helper:(C||this)["helper"],placeholder:(C||this)["placeholder"]||B([]),position:(C||this)["position"],absolutePosition:(C||this)["positionAbs"],options:this.options,element:this.element,item:(C||this)["currentItem"],sender:C?C.element:null}},_propagate:function(F,E,C,D){B.ui.plugin.call(this,F,[E,this.ui(C)]);if(!D){this.element.triggerHandler(F=="sort"?F:"sort"+F,[E,this.ui(C)],this.options[F])}},serialize:function(E){var C=this._getItemsAsjQuery(E&&E.connected);var D=[];E=E||{};B(C).each(function(){var F=(B(this.item||this).attr(E.attribute||"id")||"").match(E.expression||(/(.+)[-=_](.+)/));if(F){D.push((E.key||F[1]+"[]")+"="+(E.key&&E.expression?F[1]:F[2]))}});return D.join("&")},toArray:function(E){var C=this._getItemsAsjQuery(E&&E.connected);var D=[];C.each(function(){D.push(B(this).attr(E.attr||"id"))});return D},_intersectsWith:function(L){var E=this.positionAbs.left,D=E+this.helperProportions.width,K=this.positionAbs.top,J=K+this.helperProportions.height;var F=L.left,C=F+L.width,M=L.top,I=M+L.height;var N=this.offset.click.top,H=this.offset.click.left;var G=(K+N)>M&&(K+N)<I&&(E+H)>F&&(E+H)<C;if(this.options.tolerance=="pointer"||this.options.forcePointerForContainers||(this.options.tolerance=="guess"&&this.helperProportions[this.floating?"width":"height"]>L[this.floating?"width":"height"])){return G}else{return(F<E+(this.helperProportions.width/2)&&D-(this.helperProportions.width/2)<C&&M<K+(this.helperProportions.height/2)&&J-(this.helperProportions.height/2)<I)}},_intersectsWithEdge:function(N){var E=this.positionAbs.left,D=E+this.helperProportions.width,L=this.positionAbs.top,J=L+this.helperProportions.height;var F=N.left,C=F+N.width,O=N.top,I=O+N.height;var P=this.offset.click.top,H=this.offset.click.left;var G=(L+P)>O&&(L+P)<I&&(E+H)>F&&(E+H)<C;if(this.options.tolerance=="pointer"||(this.options.tolerance=="guess"&&this.helperProportions[this.floating?"width":"height"]>N[this.floating?"width":"height"])){if(!G){return false}if(this.floating){if((E+H)>F&&(E+H)<F+N.width/2){return 2}if((E+H)>F+N.width/2&&(E+H)<C){return 1}}else{var M=N.height;var K=L-this.updateOriginalPosition.top<0?2:1;if(K==1&&(L+P)<O+M/2){return 2}else{if(K==2&&(L+P)>O+M/2){return 1}}}}else{if(!(F<E+(this.helperProportions.width/2)&&D-(this.helperProportions.width/2)<C&&O<L+(this.helperProportions.height/2)&&J-(this.helperProportions.height/2)<I)){return false}if(this.floating){if(D>F&&E<F){return 2}if(E<C&&D>C){return 1}}else{if(J>O&&L<O){return 1}if(L<I&&J>I){return 2}}}return false},refresh:function(){this._refreshItems();this.refreshPositions()},_getItemsAsjQuery:function(H){var D=this;var C=[];var F=[];if(this.options.connectWith&&H){for(var G=this.options.connectWith.length-1;G>=0;G--){var J=B(this.options.connectWith[G]);for(var E=J.length-1;E>=0;E--){var I=B.data(J[E],"sortable");if(I&&I!=this&&!I.options.disabled){F.push([B.isFunction(I.options.items)?I.options.items.call(I.element):B(I.options.items,I.element).not(".ui-sortable-helper"),I])}}}}F.push([B.isFunction(this.options.items)?this.options.items.call(this.element,null,{options:this.options,item:this.currentItem}):B(this.options.items,this.element).not(".ui-sortable-helper"),this]);for(var G=F.length-1;G>=0;G--){F[G][0].each(function(){C.push(this)})}return B(C)},_removeCurrentsFromItems:function(){var E=this.currentItem.find(":data(sortable-item)");for(var D=0;D<this.items.length;D++){for(var C=0;C<E.length;C++){if(E[C]==this.items[D].item[0]){this.items.splice(D,1)}}}},_refreshItems:function(){this.items=[];this.containers=[this];var D=this.items;var C=this;var F=[[B.isFunction(this.options.items)?this.options.items.call(this.element,null,{options:this.options,item:this.currentItem}):B(this.options.items,this.element),this]];if(this.options.connectWith){for(var G=this.options.connectWith.length-1;G>=0;G--){var I=B(this.options.connectWith[G]);for(var E=I.length-1;E>=0;E--){var H=B.data(I[E],"sortable");if(H&&H!=this&&!H.options.disabled){F.push([B.isFunction(H.options.items)?H.options.items.call(H.element):B(H.options.items,H.element),H]);this.containers.push(H)}}}}for(var G=F.length-1;G>=0;G--){F[G][0].each(function(){B.data(this,"sortable-item",F[G][1]);D.push({item:B(this),instance:F[G][1],width:0,height:0,left:0,top:0})})}},refreshPositions:function(D){if(this.offsetParent){var C=this.offsetParent.offset();this.offset.parent={top:C.top+this.offsetParentBorders.top,left:C.left+this.offsetParentBorders.left}}for(var F=this.items.length-1;F>=0;F--){if(this.items[F].instance!=this.currentContainer&&this.currentContainer&&this.items[F].item[0]!=this.currentItem[0]){continue}var E=this.options.toleranceElement?B(this.options.toleranceElement,this.items[F].item):this.items[F].item;if(!D){this.items[F].width=E[0].offsetWidth;this.items[F].height=E[0].offsetHeight}var G=E.offset();this.items[F].left=G.left;this.items[F].top=G.top}if(this.options.custom&&this.options.custom.refreshContainers){this.options.custom.refreshContainers.call(this)}else{for(var F=this.containers.length-1;F>=0;F--){var G=this.containers[F].element.offset();this.containers[F].containerCache.left=G.left;this.containers[F].containerCache.top=G.top;this.containers[F].containerCache.width=this.containers[F].element.outerWidth();this.containers[F].containerCache.height=this.containers[F].element.outerHeight()}}},destroy:function(){this.element.removeClass("ui-sortable ui-sortable-disabled").removeData("sortable").unbind(".sortable");this._mouseDestroy();for(var C=this.items.length-1;C>=0;C--){this.items[C].item.removeData("sortable-item")}},_createPlaceholder:function(E){var C=E||this,F=C.options;if(!F.placeholder||F.placeholder.constructor==String){var D=F.placeholder;F.placeholder={element:function(){var G=B(document.createElement(C.currentItem[0].nodeName)).addClass(D||"ui-sortable-placeholder")[0];if(!D){G.style.visibility="hidden";document.body.appendChild(G);G.innerHTML=C.currentItem[0].innerHTML;document.body.removeChild(G)}return G},update:function(G,H){if(D&&!F.forcePlaceholderSize){return }if(!H.height()){H.height(C.currentItem.innerHeight()-parseInt(C.currentItem.css("paddingTop")||0,10)-parseInt(C.currentItem.css("paddingBottom")||0,10))}if(!H.width()){H.width(C.currentItem.innerWidth()-parseInt(C.currentItem.css("paddingLeft")||0,10)-parseInt(C.currentItem.css("paddingRight")||0,10))}}}}C.placeholder=B(F.placeholder.element.call(C.element,C.currentItem));C.currentItem.parent()[0].appendChild(C.placeholder[0]);C.placeholder[0].parentNode.insertBefore(C.placeholder[0],C.currentItem[0]);F.placeholder.update(C,C.placeholder)},_contactContainers:function(F){for(var D=this.containers.length-1;D>=0;D--){if(this._intersectsWith(this.containers[D].containerCache)){if(!this.containers[D].containerCache.over){if(this.currentContainer!=this.containers[D]){var I=10000;var H=null;var E=this.positionAbs[this.containers[D].floating?"left":"top"];for(var C=this.items.length-1;C>=0;C--){if(!A(this.containers[D].element[0],this.items[C].item[0])){continue}var G=this.items[C][this.containers[D].floating?"left":"top"];if(Math.abs(G-E)<I){I=Math.abs(G-E);H=this.items[C]}}if(!H&&!this.options.dropOnEmpty){continue}this.currentContainer=this.containers[D];H?this.options.sortIndicator.call(this,F,H,null,true):this.options.sortIndicator.call(this,F,null,this.containers[D].element,true);this._propagate("change",F);this.containers[D]._propagate("change",F,this);this.options.placeholder.update(this.currentContainer,this.placeholder)}this.containers[D]._propagate("over",F,this);this.containers[D].containerCache.over=1}}else{if(this.containers[D].containerCache.over){this.containers[D]._propagate("out",F,this);this.containers[D].containerCache.over=0}}}},_mouseCapture:function(G,F){if(this.options.disabled||this.options.type=="static"){return false}this._refreshItems();var E=null,D=this,C=B(G.target).parents().each(function(){if(B.data(this,"sortable-item")==D){E=B(this);return false}});if(B.data(G.target,"sortable-item")==D){E=B(G.target)}if(!E){return false}if(this.options.handle&&!F){var H=false;B(this.options.handle,E).find("*").andSelf().each(function(){if(this==G.target){H=true}});if(!H){return false}}this.currentItem=E;this._removeCurrentsFromItems();return true},createHelper:function(D){var E=this.options;var C=typeof E.helper=="function"?B(E.helper.apply(this.element[0],[D,this.currentItem])):(E.helper=="original"?this.currentItem:this.currentItem.clone());if(!C.parents("body").length){B(E.appendTo!="parent"?E.appendTo:this.currentItem[0].parentNode)[0].appendChild(C[0])}return C},_mouseStart:function(G,I,K){var C=this.options;this.currentContainer=this;this.refreshPositions();this.helper=this.createHelper(G);this.margins={left:(parseInt(this.currentItem.css("marginLeft"),10)||0),top:(parseInt(this.currentItem.css("marginTop"),10)||0)};this.offset=this.currentItem.offset();this.offset={top:this.offset.top-this.margins.top,left:this.offset.left-this.margins.left};this.offset.click={left:G.pageX-this.offset.left,top:G.pageY-this.offset.top};this.offsetParent=this.helper.offsetParent();var E=this.offsetParent.offset();this.offsetParentBorders={top:(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:(parseInt(this.offsetParent.css("borderLeftWidth"),10)||0)};this.offset.parent={top:E.top+this.offsetParentBorders.top,left:E.left+this.offsetParentBorders.left};this.updateOriginalPosition=this.originalPosition=this._generatePosition(G);this.domPosition={prev:this.currentItem.prev()[0],parent:this.currentItem.parent()[0]};this.helperProportions={width:this.helper.outerWidth(),height:this.helper.outerHeight()};if(C.helper=="original"){this._storedCSS={position:this.currentItem.css("position"),top:this.currentItem.css("top"),left:this.currentItem.css("left"),clear:this.currentItem.css("clear")}}else{this.currentItem.hide()}this.helper.css({position:"absolute",clear:"both"}).addClass("ui-sortable-helper");this._createPlaceholder();this._propagate("start",G);if(!this._preserveHelperProportions){this.helperProportions={width:this.helper.outerWidth(),height:this.helper.outerHeight()}}if(C.cursorAt){if(C.cursorAt.left!=undefined){this.offset.click.left=C.cursorAt.left}if(C.cursorAt.right!=undefined){this.offset.click.left=this.helperProportions.width-C.cursorAt.right}if(C.cursorAt.top!=undefined){this.offset.click.top=C.cursorAt.top}if(C.cursorAt.bottom!=undefined){this.offset.click.top=this.helperProportions.height-C.cursorAt.bottom}}if(C.containment){if(C.containment=="parent"){C.containment=this.helper[0].parentNode}if(C.containment=="document"||C.containment=="window"){this.containment=[0-this.offset.parent.left,0-this.offset.parent.top,B(C.containment=="document"?document:window).width()-this.offset.parent.left-this.helperProportions.width-this.margins.left-(parseInt(this.element.css("marginRight"),10)||0),(B(C.containment=="document"?document:window).height()||document.body.parentNode.scrollHeight)-this.offset.parent.top-this.helperProportions.height-this.margins.top-(parseInt(this.element.css("marginBottom"),10)||0)]}if(!(/^(document|window|parent)$/).test(C.containment)){var D=B(C.containment)[0];var J=B(C.containment).offset();var H=(B(D).css("overflow")!="hidden");this.containment=[J.left+(parseInt(B(D).css("borderLeftWidth"),10)||0)-this.offset.parent.left,J.top+(parseInt(B(D).css("borderTopWidth"),10)||0)-this.offset.parent.top,J.left+(H?Math.max(D.scrollWidth,D.offsetWidth):D.offsetWidth)-(parseInt(B(D).css("borderLeftWidth"),10)||0)-this.offset.parent.left-this.helperProportions.width-this.margins.left-(parseInt(this.currentItem.css("marginRight"),10)||0),J.top+(H?Math.max(D.scrollHeight,D.offsetHeight):D.offsetHeight)-(parseInt(B(D).css("borderTopWidth"),10)||0)-this.offset.parent.top-this.helperProportions.height-this.margins.top-(parseInt(this.currentItem.css("marginBottom"),10)||0)]}}if(!K){for(var F=this.containers.length-1;F>=0;F--){this.containers[F]._propagate("activate",G,this)}}if(B.ui.ddmanager){B.ui.ddmanager.current=this}if(B.ui.ddmanager&&!C.dropBehaviour){B.ui.ddmanager.prepareOffsets(this,G)}this.dragging=true;this._mouseDrag(G);return true},_convertPositionTo:function(D,E){if(!E){E=this.position}var C=D=="absolute"?1:-1;return{top:(E.top+this.offset.parent.top*C-(this.offsetParent[0]==document.body?0:this.offsetParent[0].scrollTop)*C+this.margins.top*C),left:(E.left+this.offset.parent.left*C-(this.offsetParent[0]==document.body?0:this.offsetParent[0].scrollLeft)*C+this.margins.left*C)}},_generatePosition:function(F){var G=this.options;var C={top:(F.pageY-this.offset.click.top-this.offset.parent.top+(this.offsetParent[0]==document.body?0:this.offsetParent[0].scrollTop)),left:(F.pageX-this.offset.click.left-this.offset.parent.left+(this.offsetParent[0]==document.body?0:this.offsetParent[0].scrollLeft))};if(!this.originalPosition){return C}if(this.containment){if(C.left<this.containment[0]){C.left=this.containment[0]}if(C.top<this.containment[1]){C.top=this.containment[1]}if(C.left>this.containment[2]){C.left=this.containment[2]}if(C.top>this.containment[3]){C.top=this.containment[3]}}if(G.grid){var E=this.originalPosition.top+Math.round((C.top-this.originalPosition.top)/G.grid[1])*G.grid[1];C.top=this.containment?(!(E<this.containment[1]||E>this.containment[3])?E:(!(E<this.containment[1])?E-G.grid[1]:E+G.grid[1])):E;var D=this.originalPosition.left+Math.round((C.left-this.originalPosition.left)/G.grid[0])*G.grid[0];C.left=this.containment?(!(D<this.containment[0]||D>this.containment[2])?D:(!(D<this.containment[0])?D-G.grid[0]:D+G.grid[0])):D}return C},_mouseDrag:function(D){this.position=this._generatePosition(D);this.positionAbs=this._convertPositionTo("absolute");B.ui.plugin.call(this,"sort",[D,this.ui()]);this.positionAbs=this._convertPositionTo("absolute");this.helper[0].style.left=this.position.left+"px";this.helper[0].style.top=this.position.top+"px";for(var C=this.items.length-1;C>=0;C--){var E=this._intersectsWithEdge(this.items[C]);if(!E){continue}if(this.items[C].item[0]!=this.currentItem[0]&&this.placeholder[E==1?"next":"prev"]()[0]!=this.items[C].item[0]&&!A(this.placeholder[0],this.items[C].item[0])&&(this.options.type=="semi-dynamic"?!A(this.element[0],this.items[C].item[0]):true)){this.updateOriginalPosition=this._generatePosition(D);this.direction=E==1?"down":"up";this.options.sortIndicator.call(this,D,this.items[C]);this._propagate("change",D);break}}this._contactContainers(D);if(B.ui.ddmanager){B.ui.ddmanager.drag(this,D)}this.element.triggerHandler("sort",[D,this.ui()],this.options["sort"]);return false},_rearrange:function(H,G,D,F){D?D[0].appendChild(this.placeholder[0]):G.item[0].parentNode.insertBefore(this.placeholder[0],(this.direction=="down"?G.item[0]:G.item[0].nextSibling));this.counter=this.counter?++this.counter:1;var E=this,C=this.counter;window.setTimeout(function(){if(C==E.counter){E.refreshPositions(!F)}},0)},_mouseStop:function(E,D){if(B.ui.ddmanager&&!this.options.dropBehaviour){B.ui.ddmanager.drop(this,E)}if(this.options.revert){var C=this;var F=C.placeholder.offset();B(this.helper).animate({left:F.left-this.offset.parent.left-C.margins.left+(this.offsetParent[0]==document.body?0:this.offsetParent[0].scrollLeft),top:F.top-this.offset.parent.top-C.margins.top+(this.offsetParent[0]==document.body?0:this.offsetParent[0].scrollTop)},parseInt(this.options.revert,10)||500,function(){C._clear(E)})}else{this._clear(E,D)}return false},_clear:function(E,D){if(!this._noFinalSort){this.placeholder.before(this.currentItem)}this._noFinalSort=null;if(this.options.helper=="original"){this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper")}else{this.currentItem.show()}if(this.domPosition.prev!=this.currentItem.prev().not(".ui-sortable-helper")[0]||this.domPosition.parent!=this.currentItem.parent()[0]){this._propagate("update",E,null,D)}if(!A(this.element[0],this.currentItem[0])){this._propagate("remove",E,null,D);for(var C=this.containers.length-1;C>=0;C--){if(A(this.containers[C].element[0],this.currentItem[0])){this.containers[C]._propagate("update",E,this,D);this.containers[C]._propagate("receive",E,this,D)}}}for(var C=this.containers.length-1;C>=0;C--){this.containers[C]._propagate("deactivate",E,this,D);if(this.containers[C].containerCache.over){this.containers[C]._propagate("out",E,this);this.containers[C].containerCache.over=0}}this.dragging=false;if(this.cancelHelperRemoval){this._propagate("beforeStop",E,null,D);this._propagate("stop",E,null,D);return false}this._propagate("beforeStop",E,null,D);this.placeholder.remove();if(this.options.helper!="original"){this.helper.remove()}this.helper=null;this._propagate("stop",E,null,D);return true}}));B.extend(B.ui.sortable,{getter:"serialize toArray",defaults:{helper:"original",tolerance:"guess",distance:1,delay:0,scroll:true,scrollSensitivity:20,scrollSpeed:20,cancel:":input",items:"> *",zIndex:1000,dropOnEmpty:true,appendTo:"parent",sortIndicator:B.ui.sortable.prototype._rearrange,scope:"default",forcePlaceholderSize:false}});B.ui.plugin.add("sortable","cursor",{start:function(E,D){var C=B("body");if(C.css("cursor")){D.options._cursor=C.css("cursor")}C.css("cursor",D.options.cursor)},beforeStop:function(D,C){if(C.options._cursor){B("body").css("cursor",C.options._cursor)}}});B.ui.plugin.add("sortable","zIndex",{start:function(E,D){var C=D.helper;if(C.css("zIndex")){D.options._zIndex=C.css("zIndex")}C.css("zIndex",D.options.zIndex)},beforeStop:function(D,C){if(C.options._zIndex){B(C.helper).css("zIndex",C.options._zIndex)}}});B.ui.plugin.add("sortable","opacity",{start:function(E,D){var C=D.helper;if(C.css("opacity")){D.options._opacity=C.css("opacity")}C.css("opacity",D.options.opacity)},beforeStop:function(D,C){if(C.options._opacity){B(C.helper).css("opacity",C.options._opacity)}}});B.ui.plugin.add("sortable","scroll",{start:function(E,D){var F=D.options;var C=B(this).data("sortable");C.overflowY=function(G){do{if(/auto|scroll/.test(G.css("overflow"))||(/auto|scroll/).test(G.css("overflow-y"))){return G}G=G.parent()}while(G[0].parentNode);return B(document)}(C.currentItem);C.overflowX=function(G){do{if(/auto|scroll/.test(G.css("overflow"))||(/auto|scroll/).test(G.css("overflow-x"))){return G}G=G.parent()}while(G[0].parentNode);return B(document)}(C.currentItem);if(C.overflowY[0]!=document&&C.overflowY[0].tagName!="HTML"){C.overflowYOffset=C.overflowY.offset()}if(C.overflowX[0]!=document&&C.overflowX[0].tagName!="HTML"){C.overflowXOffset=C.overflowX.offset()}},sort:function(E,D){var F=D.options;var C=B(this).data("sortable");if(C.overflowY[0]!=document&&C.overflowY[0].tagName!="HTML"){if((C.overflowYOffset.top+C.overflowY[0].offsetHeight)-E.pageY<F.scrollSensitivity){C.overflowY[0].scrollTop=C.overflowY[0].scrollTop+F.scrollSpeed}if(E.pageY-C.overflowYOffset.top<F.scrollSensitivity){C.overflowY[0].scrollTop=C.overflowY[0].scrollTop-F.scrollSpeed}}else{if(E.pageY-B(document).scrollTop()<F.scrollSensitivity){B(document).scrollTop(B(document).scrollTop()-F.scrollSpeed)}if(B(window).height()-(E.pageY-B(document).scrollTop())<F.scrollSensitivity){B(document).scrollTop(B(document).scrollTop()+F.scrollSpeed)}}if(C.overflowX[0]!=document&&C.overflowX[0].tagName!="HTML"){if((C.overflowXOffset.left+C.overflowX[0].offsetWidth)-E.pageX<F.scrollSensitivity){C.overflowX[0].scrollLeft=C.overflowX[0].scrollLeft+F.scrollSpeed}if(E.pageX-C.overflowXOffset.left<F.scrollSensitivity){C.overflowX[0].scrollLeft=C.overflowX[0].scrollLeft-F.scrollSpeed}}else{if(E.pageX-B(document).scrollLeft()<F.scrollSensitivity){B(document).scrollLeft(B(document).scrollLeft()-F.scrollSpeed)}if(B(window).width()-(E.pageX-B(document).scrollLeft())<F.scrollSensitivity){B(document).scrollLeft(B(document).scrollLeft()+F.scrollSpeed)}}}});B.ui.plugin.add("sortable","axis",{sort:function(E,D){var C=B(this).data("sortable");if(D.options.axis=="y"){C.position.left=C.originalPosition.left}if(D.options.axis=="x"){C.position.top=C.originalPosition.top}}})})(jQuery) \ No newline at end of file
diff --git a/site/app/webroot/js/jquery-ui/ui.spinner.min.js b/site/app/webroot/js/jquery-ui/ui.spinner.min.js
new file mode 100755
index 0000000..bfe2fbf
--- /dev/null
+++ b/site/app/webroot/js/jquery-ui/ui.spinner.min.js
@@ -0,0 +1 @@
+(function(A){A.widget("ui.spinner",{_init:function(){if(A.data(this.element[0],"spinner")){return }if(this.options.init){this.options.init(this.ui(null))}this._decimals=0;if(this.options.stepping.toString().indexOf(".")!=-1){var C=this.options.stepping.toString();this._decimals=C.slice(C.indexOf(".")+1,C.length).length}var B=this;this.element.addClass("ui-spinner-box").attr("autocomplete","off");this._setValue(isNaN(this._getValue())?this.options.start:this._getValue());this.element.wrap("<div>").parent().addClass("ui-spinner").append('<button class="ui-spinner-up" type="button">&#9650;</button>').find(".ui-spinner-up").bind("mousedown",function(D){A(this).addClass("ui-spinner-pressed");if(!B.counter){B.counter=1}B._mousedown(100,"_up",D)}).bind("mouseup",function(D){A(this).removeClass("ui-spinner-pressed");if(B.counter==1){B._up(D)}B._mouseup(D)}).bind("mouseout",function(D){A(this).removeClass("ui-spinner-pressed");B._mouseup(D)}).bind("dblclick",function(D){A(this).removeClass("ui-spinner-pressed");B._up(D)}).bind("keydown.spinner",function(E){var D=A.keyCode;if(E.keyCode==D.SPACE||E.keyCode==D.ENTER){A(this).addClass("ui-spinner-pressed");if(!B.counter){B.counter=1}B._up.call(B,E)}else{if(E.keyCode==D.DOWN||E.keyCode==D.RIGHT){B.element.siblings(".ui-spinner-down").focus()}else{if(E.keyCode==D.LEFT){B.element.focus()}}}}).bind("keyup.spinner",function(D){A(this).removeClass("ui-spinner-pressed");B.counter=0;B._propagate("change",D)}).end().append('<button class="ui-spinner-down" type="button">&#9660;</button>').find(".ui-spinner-down").bind("mousedown",function(D){A(this).addClass("ui-spinner-pressed");if(!B.counter){B.counter=1}B._mousedown(100,"_down",D)}).bind("mouseup",function(D){A(this).removeClass("ui-spinner-pressed");if(B.counter==1){B._down()}B._mouseup(D)}).bind("mouseout",function(D){A(this).removeClass("ui-spinner-pressed");B._mouseup(D)}).bind("dblclick",function(D){A(this).removeClass("ui-spinner-pressed");B._down(D)}).bind("keydown.spinner",function(E){var D=A.keyCode;if(E.keyCode==D.SPACE||E.keyCode==D.ENTER){A(this).addClass("ui-spinner-pressed");if(!B.counter){B.counter=1}B._down.call(B,E)}else{if(E.keyCode==D.UP||E.keyCode==D.LEFT){B.element.siblings(".ui-spinner-up").focus()}}}).bind("keyup.spinner",function(D){A(this).removeClass("ui-spinner-pressed");B.counter=0;B._propagate("change",D)}).end();this._items=this.element.children().length;if(this._items>1){this.element.addClass("ui-spinner-list").css("height",this.element.outerHeight()/this._items).children().addClass("ui-spinner-listitem").end().parent().css("height",this.element.outerHeight()).end();this.options.stepping=1;this.options.min=0;this.options.max=this._items-1}this.element.bind("keydown.spinner",function(D){if(!B.counter){B.counter=1}return B._keydown.call(B,D)}).bind("keyup.spinner",function(D){B.counter=0;B._propagate("change",D)}).bind("blur.spinner",function(D){B._cleanUp()});if(A.fn.mousewheel){this.element.mousewheel(function(D,E){B._mousewheel(D,E)})}},_constrain:function(){if(this.options.min!=undefined&&this._getValue()<this.options.min){this._setValue(this.options.min)}if(this.options.max!=undefined&&this._getValue()>this.options.max){this._setValue(this.options.max)}},_cleanUp:function(){this._setValue(this._getValue());this._constrain()},_spin:function(C,B){if(this.disabled){return }if(isNaN(this._getValue())){this._setValue(this.options.start)}this._setValue(this._getValue()+(C=="up"?1:-1)*(this.options.incremental&&this.counter>100?(this.counter>200?100:10):1)*this.options.stepping);this._animate(C);this._constrain();if(this.counter){this.counter++}this._propagate("spin",B)},_down:function(B){this._spin("down",B);this._propagate("down",B)},_up:function(B){this._spin("up",B);this._propagate("up",B)},_mousedown:function(C,E,D){var B=this;C=C||100;if(this.timer){window.clearInterval(this.timer)}this.timer=window.setInterval(function(){B[E](D);if(B.counter>20){B._mousedown(20,E,D)}},C)},_mouseup:function(B){this.counter=0;if(this.timer){window.clearInterval(this.timer)}this.element[0].focus();this._propagate("change",B)},_keydown:function(C){var B=A.keyCode;if(C.keyCode==B.UP){this._up(C)}if(C.keyCode==B.DOWN){this._down(C)}if(C.keyCode==B.HOME){this._setValue(this.options.min||this.options.start)}if(C.keyCode==B.END&&this.options.max!=undefined){this._setValue(this.options.max)}return(C.keyCode==B.TAB||C.keyCode==B.BACKSPACE||C.keyCode==B.LEFT||C.keyCode==B.RIGHT||C.keyCode==B.PERIOD||C.keyCode==B.NUMPAD_DECIMAL||C.keyCode==B.NUMPAD_SUBTRACT||(C.keyCode>=96&&C.keyCode<=105)||(/[0-9\-\.]/).test(String.fromCharCode(C.keyCode)))?true:false},_mousewheel:function(B,C){C=(A.browser.opera?-C/Math.abs(C):C);C>0?this._up(B):this._down(B);B.preventDefault()},_getValue:function(){return parseFloat(this.element.val().replace(/[^0-9\-\.]/g,""))},_setValue:function(B){if(isNaN(B)){B=this.options.start}this.element.val(this.options.currency?A.ui.spinner.format.currency(B,this.options.currency):A.ui.spinner.format.number(B,this._decimals))},_animate:function(B){if(this.element.hasClass("ui-spinner-list")&&((B=="up"&&this._getValue()<=this.options.max)||(B=="down"&&this._getValue()>=this.options.min))){this.element.animate({marginTop:"-"+this._getValue()*this.element.outerHeight()},{duration:"fast",queue:false})}},_addItem:function(B){if(!this.element.is("input")){var C="div";if(this.element.is("ol")||this.element.is("ul")){C="li"}this.element.append("<"+C+' class="ui-spinner-dyn">'+B+"</"+C+">")}},plugins:{},ui:function(B){return{options:this.options,element:this.element,value:this._getValue(),add:this._addItem}},_propagate:function(C,B){A.ui.plugin.call(this,C,[B,this.ui()]);return this.element.triggerHandler(C=="spin"?C:"spin"+C,[B,this.ui()],this.options[C])},destroy:function(){if(!A.data(this.element[0],"spinner")){return }if(A.fn.mousewheel){this.element.unmousewheel()}this.element.removeClass("ui-spinner-box ui-spinner-list").removeAttr("disabled").removeAttr("autocomplete").removeData("spinner").unbind(".spinner").siblings().remove().end().children().removeClass("ui-spinner-listitem").remove(".ui-spinner-dyn").end().parent().removeClass("ui-spinner ui-spinner-disabled").before(this.element.clone()).remove().end()},enable:function(){this.element.removeAttr("disabled").siblings().removeAttr("disabled").parent().removeClass("ui-spinner-disabled");this.disabled=false},disable:function(){this.element.attr("disabled",true).siblings().attr("disabled",true).parent().addClass("ui-spinner-disabled");this.disabled=true}});A.extend(A.ui.spinner,{defaults:{stepping:1,start:0,incremental:true,currency:false},format:{number:function(B,C){return this.round(B,C)},currency:function(C,B){return(C!==Math.abs(C)?"-":"")+B+this.round(Math.abs(C),2)},round:function(B,D){var C=Math.round(parseFloat(B)*Math.pow(10,D))/Math.pow(10,D);if(D>0){C=C+((C.toString().indexOf(".")==-1)?".":"")+"0000000001";C=C.substr(0,C.indexOf(".")+1+D)}else{C=Math.round(C)}return C}}})})(jQuery) \ No newline at end of file
diff --git a/site/app/webroot/js/jquery-ui/ui.tabs.min.js b/site/app/webroot/js/jquery-ui/ui.tabs.min.js
new file mode 100755
index 0000000..5a9da53
--- /dev/null
+++ b/site/app/webroot/js/jquery-ui/ui.tabs.min.js
@@ -0,0 +1 @@
+(function(A){A.widget("ui.tabs",{_init:function(){this.options.event+=".tabs";this._tabify(true)},_setData:function(B,C){if((/^selected/).test(B)){this.select(C)}else{this.options[B]=C;this._tabify()}},length:function(){return this.$tabs.length},_tabId:function(B){return B.title&&B.title.replace(/\s/g,"_").replace(/[^A-Za-z0-9\-_:\.]/g,"")||this.options.idPrefix+A.data(B)},ui:function(C,B){return{options:this.options,tab:C,panel:B,index:this.$tabs.index(C)}},_tabify:function(O){this.$lis=A("li:has(a[href])",this.element);this.$tabs=this.$lis.map(function(){return A("a",this)[0]});this.$panels=A([]);var P=this,D=this.options;this.$tabs.each(function(R,Q){if(Q.hash&&Q.hash.replace("#","")){P.$panels=P.$panels.add(Q.hash)}else{if(A(Q).attr("href")!="#"){A.data(Q,"href.tabs",Q.href);A.data(Q,"load.tabs",Q.href);var T=P._tabId(Q);Q.href="#"+T;var S=A("#"+T);if(!S.length){S=A(D.panelTemplate).attr("id",T).addClass(D.panelClass).insertAfter(P.$panels[R-1]||P.element);S.data("destroy.tabs",true)}P.$panels=P.$panels.add(S)}else{D.disabled.push(R+1)}}});if(O){this.element.addClass(D.navClass);this.$panels.each(function(){var Q=A(this);Q.addClass(D.panelClass)});if(D.selected===undefined){if(location.hash){this.$tabs.each(function(S,Q){if(Q.hash==location.hash){D.selected=S;if(A.browser.msie||A.browser.opera){var R=A(location.hash),T=R.attr("id");R.attr("id","");setTimeout(function(){R.attr("id",T)},500)}scrollTo(0,0);return false}})}else{if(D.cookie){var J=parseInt(A.cookie("ui-tabs-"+A.data(P.element[0])),10);if(J&&P.$tabs[J]){D.selected=J}}else{if(P.$lis.filter("."+D.selectedClass).length){D.selected=P.$lis.index(P.$lis.filter("."+D.selectedClass)[0])}}}}D.selected=D.selected===null||D.selected!==undefined?D.selected:0;D.disabled=A.unique(D.disabled.concat(A.map(this.$lis.filter("."+D.disabledClass),function(R,Q){return P.$lis.index(R)}))).sort();if(A.inArray(D.selected,D.disabled)!=-1){D.disabled.splice(A.inArray(D.selected,D.disabled),1)}this.$panels.addClass(D.hideClass);this.$lis.removeClass(D.selectedClass);if(D.selected!==null){this.$panels.eq(D.selected).show().removeClass(D.hideClass);this.$lis.eq(D.selected).addClass(D.selectedClass);var K=function(){P._trigger("show",null,P.ui(P.$tabs[D.selected],P.$panels[D.selected]))};if(A.data(this.$tabs[D.selected],"load.tabs")){this.load(D.selected,K)}else{K()}}A(window).bind("unload",function(){P.$tabs.unbind(".tabs");P.$lis=P.$tabs=P.$panels=null})}else{D.selected=this.$lis.index(this.$lis.filter("."+D.selectedClass)[0])}if(D.cookie){A.cookie("ui-tabs-"+A.data(P.element[0]),D.selected,D.cookie)}for(var G=0,N;N=this.$lis[G];G++){A(N)[A.inArray(G,D.disabled)!=-1&&!A(N).hasClass(D.selectedClass)?"addClass":"removeClass"](D.disabledClass)}if(D.cache===false){this.$tabs.removeData("cache.tabs")}var C,I,B={"min-width":0,duration:1},E="normal";if(D.fx&&D.fx.constructor==Array){C=D.fx[0]||B,I=D.fx[1]||B}else{C=I=D.fx||B}var H={display:"",overflow:"",height:""};if(!A.browser.msie){H.opacity=""}function M(R,Q,S){Q.animate(C,C.duration||E,function(){Q.addClass(D.hideClass).css(H);if(A.browser.msie&&C.opacity){Q[0].style.filter=""}if(S){L(R,S,Q)}})}function L(R,S,Q){if(I===B){S.css("display","block")}S.animate(I,I.duration||E,function(){S.removeClass(D.hideClass).css(H);if(A.browser.msie&&I.opacity){S[0].style.filter=""}P._trigger("show",null,P.ui(R,S[0]))})}function F(R,T,Q,S){T.addClass(D.selectedClass).siblings().removeClass(D.selectedClass);M(R,Q,S)}this.$tabs.unbind(".tabs").bind(D.event,function(){var T=A(this).parents("li:eq(0)"),Q=P.$panels.filter(":visible"),S=A(this.hash);if((T.hasClass(D.selectedClass)&&!D.unselect)||T.hasClass(D.disabledClass)||A(this).hasClass(D.loadingClass)||P._trigger("select",null,P.ui(this,S[0]))===false){this.blur();return false}P.options.selected=P.$tabs.index(this);if(D.unselect){if(T.hasClass(D.selectedClass)){P.options.selected=null;T.removeClass(D.selectedClass);P.$panels.stop();M(this,Q);this.blur();return false}else{if(!Q.length){P.$panels.stop();var R=this;P.load(P.$tabs.index(this),function(){T.addClass(D.selectedClass).addClass(D.unselectClass);L(R,S)});this.blur();return false}}}if(D.cookie){A.cookie("ui-tabs-"+A.data(P.element[0]),P.options.selected,D.cookie)}P.$panels.stop();if(S.length){var R=this;P.load(P.$tabs.index(this),Q.length?function(){F(R,T,Q,S)}:function(){T.addClass(D.selectedClass);L(R,S)})}else{throw"jQuery UI Tabs: Mismatching fragment identifier."}if(A.browser.msie){this.blur()}return false});if(!(/^click/).test(D.event)){this.$tabs.bind("click.tabs",function(){return false})}},add:function(E,D,C){if(C==undefined){C=this.$tabs.length}var G=this.options;var I=A(G.tabTemplate.replace(/#\{href\}/g,E).replace(/#\{label\}/g,D));I.data("destroy.tabs",true);var H=E.indexOf("#")==0?E.replace("#",""):this._tabId(A("a:first-child",I)[0]);var F=A("#"+H);if(!F.length){F=A(G.panelTemplate).attr("id",H).addClass(G.hideClass).data("destroy.tabs",true)}F.addClass(G.panelClass);if(C>=this.$lis.length){I.appendTo(this.element);F.appendTo(this.element[0].parentNode)}else{I.insertBefore(this.$lis[C]);F.insertBefore(this.$panels[C])}G.disabled=A.map(G.disabled,function(K,J){return K>=C?++K:K});this._tabify();if(this.$tabs.length==1){I.addClass(G.selectedClass);F.removeClass(G.hideClass);var B=A.data(this.$tabs[0],"load.tabs");if(B){this.load(C,B)}}this._trigger("add",null,this.ui(this.$tabs[C],this.$panels[C]))},remove:function(B){var D=this.options,E=this.$lis.eq(B).remove(),C=this.$panels.eq(B).remove();if(E.hasClass(D.selectedClass)&&this.$tabs.length>1){this.select(B+(B+1<this.$tabs.length?1:-1))}D.disabled=A.map(A.grep(D.disabled,function(G,F){return G!=B}),function(G,F){return G>=B?--G:G});this._tabify();this._trigger("remove",null,this.ui(E.find("a")[0],C[0]))},enable:function(B){var C=this.options;if(A.inArray(B,C.disabled)==-1){return }var D=this.$lis.eq(B).removeClass(C.disabledClass);if(A.browser.safari){D.css("display","inline-block");setTimeout(function(){D.css("display","block")},0)}C.disabled=A.grep(C.disabled,function(F,E){return F!=B});this._trigger("enable",null,this.ui(this.$tabs[B],this.$panels[B]))},disable:function(C){var B=this,D=this.options;if(C!=D.selected){this.$lis.eq(C).addClass(D.disabledClass);D.disabled.push(C);D.disabled.sort();this._trigger("disable",null,this.ui(this.$tabs[C],this.$panels[C]))}},select:function(B){if(typeof B=="string"){B=this.$tabs.index(this.$tabs.filter("[href$="+B+"]")[0])}this.$tabs.eq(B).trigger(this.options.event)},load:function(G,K){var L=this,D=this.options,E=this.$tabs.eq(G),J=E[0],H=K==undefined||K===false,B=E.data("load.tabs");K=K||function(){};if(!B||!H&&A.data(J,"cache.tabs")){K();return }var M=function(N){var O=A(N),P=O.find("*:last");return P.length&&P.is(":not(img)")&&P||O};var C=function(){L.$tabs.filter("."+D.loadingClass).removeClass(D.loadingClass).each(function(){if(D.spinner){M(this).parent().html(M(this).data("label.tabs"))}});L.xhr=null};if(D.spinner){var I=M(J).html();M(J).wrapInner("<em></em>").find("em").data("label.tabs",I).html(D.spinner)}var F=A.extend({},D.ajaxOptions,{url:B,success:function(O,N){A(J.hash).html(O);C();if(D.cache){A.data(J,"cache.tabs",true)}L._trigger("load",null,L.ui(L.$tabs[G],L.$panels[G]));D.ajaxOptions.success&&D.ajaxOptions.success(O,N);K()}});if(this.xhr){this.xhr.abort();C()}E.addClass(D.loadingClass);setTimeout(function(){L.xhr=A.ajax(F)},0)},url:function(C,B){this.$tabs.eq(C).removeData("cache.tabs").data("load.tabs",B)},destroy:function(){var B=this.options;this.element.unbind(".tabs").removeClass(B.navClass).removeData("tabs");this.$tabs.each(function(){var C=A.data(this,"href.tabs");if(C){this.href=C}var D=A(this).unbind(".tabs");A.each(["href","load","cache"],function(E,F){D.removeData(F+".tabs")})});this.$lis.add(this.$panels).each(function(){if(A.data(this,"destroy.tabs")){A(this).remove()}else{A(this).removeClass([B.selectedClass,B.unselectClass,B.disabledClass,B.panelClass,B.hideClass].join(" "))}})}});A.ui.tabs.defaults={unselect:false,event:"click",disabled:[],cookie:null,spinner:"Loading&#8230;",cache:false,idPrefix:"ui-tabs-",ajaxOptions:{},fx:null,tabTemplate:'<li><a href="#{href}"><span>#{label}</span></a></li>',panelTemplate:"<div></div>",navClass:"ui-tabs-nav",selectedClass:"ui-tabs-selected",unselectClass:"ui-tabs-unselect",disabledClass:"ui-tabs-disabled",panelClass:"ui-tabs-panel",hideClass:"ui-tabs-hide",loadingClass:"ui-tabs-loading"};A.ui.tabs.getter="length";A.extend(A.ui.tabs.prototype,{rotation:null,rotate:function(C,F){F=F||false;var B=this,E=this.options.selected;function G(){B.rotation=setInterval(function(){E=++E<B.$tabs.length?E:0;B.select(E)},C)}function D(H){if(!H||H.clientX){clearInterval(B.rotation)}}if(C){G();if(!F){this.$tabs.bind(this.options.event,D)}else{this.$tabs.bind(this.options.event,function(){D();E=B.options.selected;G()})}}else{D();this.$tabs.unbind(this.options.event,D)}}})})(jQuery) \ No newline at end of file
diff --git a/site/app/webroot/js/jquery.addons.min.js b/site/app/webroot/js/jquery.addons.min.js
new file mode 100644
index 0000000..008964f
--- /dev/null
+++ b/site/app/webroot/js/jquery.addons.min.js
@@ -0,0 +1 @@
+(function(){var W=this,AB,F=W.jQuery,R=W.$,T=W.jQuery=W.$=function(B,A){return new T.fn.init(B,A)},L=/^[^<]*(<(.|\s)+>)[^>]*$|^#([\w-]+)$/,AC=/^.[^:#\[\.,]*$/;T.fn=T.prototype={init:function(a,B){a=a||document;if(a.nodeType){this[0]=a;this.length=1;this.context=a;return this}if(typeof a==="string"){var C=L.exec(a);if(C&&(C[1]||!B)){if(C[1]){a=T.clean([C[1]],B)}else{var A=document.getElementById(C[3]);if(A&&A.id!=C[3]){return T().find(a)}var D=T(A||[]);D.context=document;D.selector=a;return D}}else{return T(B).find(a)}}else{if(T.isFunction(a)){return T(document).ready(a)}}if(a.selector&&a.context){this.selector=a.selector;this.context=a.context}return this.setArray(T.isArray(a)?a:T.makeArray(a))},selector:"",jquery:"1.3.2",size:function(){return this.length},get:function(A){return A===AB?Array.prototype.slice.call(this):this[A]},pushStack:function(C,A,D){var B=T(C);B.prevObject=this;B.context=this.context;if(A==="find"){B.selector=this.selector+(this.selector?" ":"")+D}else{if(A){B.selector=this.selector+"."+A+"("+D+")"}}return B},setArray:function(A){this.length=0;Array.prototype.push.apply(this,A);return this},each:function(A,B){return T.each(this,A,B)},index:function(A){return T.inArray(A&&A.jquery?A[0]:A,this)},attr:function(C,A,B){var D=C;if(typeof C==="string"){if(A===AB){return this[0]&&T[B||"attr"](this[0],C)}else{D={};D[C]=A}}return this.each(function(a){for(C in D){T.attr(B?this.style:this,C,T.prop(this,D[C],B,a,C))}})},css:function(B,A){if((B=="width"||B=="height")&&parseFloat(A)<0){A=AB}return this.attr(B,A,"curCSS")},text:function(A){if(typeof A!=="object"&&A!=null){return this.empty().append((this[0]&&this[0].ownerDocument||document).createTextNode(A))}var B="";T.each(A||this,function(){T.each(this.childNodes,function(){if(this.nodeType!=8){B+=this.nodeType!=1?this.nodeValue:T.fn.text([this])}})});return B},wrapAll:function(B){if(this[0]){var A=T(B,this[0].ownerDocument).clone();if(this[0].parentNode){A.insertBefore(this[0])}A.map(function(){var C=this;while(C.firstChild){C=C.firstChild}return C}).append(this)}return this},wrapInner:function(A){return this.each(function(){T(this).contents().wrapAll(A)})},wrap:function(A){return this.each(function(){T(this).wrapAll(A)})},append:function(){return this.domManip(arguments,true,function(A){if(this.nodeType==1){this.appendChild(A)}})},prepend:function(){return this.domManip(arguments,true,function(A){if(this.nodeType==1){this.insertBefore(A,this.firstChild)}})},before:function(){return this.domManip(arguments,false,function(A){this.parentNode.insertBefore(A,this)})},after:function(){return this.domManip(arguments,false,function(A){this.parentNode.insertBefore(A,this.nextSibling)})},end:function(){return this.prevObject||T([])},push:[].push,sort:[].sort,splice:[].splice,find:function(B){if(this.length===1){var A=this.pushStack([],"find",B);A.length=0;T.find(B,this[0],A);return A}else{return this.pushStack(T.unique(T.map(this,function(C){return T.find(B,C)})),"find",B)}},clone:function(B){var D=this.map(function(){if(!T.support.noCloneEvent&&!T.isXMLDoc(this)){var c=this.outerHTML;if(!c){var a=this.ownerDocument.createElement("div");a.appendChild(this.cloneNode(true));c=a.innerHTML}return T.clean([c.replace(/ jQuery\d+="(?:\d+|null)"/g,"").replace(/^\s*/,"")])[0]}else{return this.cloneNode(true)}});if(B===true){var A=this.find("*").andSelf(),C=0;D.find("*").andSelf().each(function(){if(this.nodeName!==A[C].nodeName){return }var d=T.data(A[C],"events");for(var a in d){for(var c in d[a]){T.event.add(this,a,d[a][c],d[a][c].data)}}C++})}return D},filter:function(A){return this.pushStack(T.isFunction(A)&&T.grep(this,function(B,C){return A.call(B,C)})||T.multiFilter(A,T.grep(this,function(B){return B.nodeType===1})),"filter",A)},closest:function(C){var A=T.expr.match.POS.test(C)?T(C):null,B=0;return this.map(function(){var D=this;while(D&&D.ownerDocument){if(A?A.index(D)>-1:T(D).is(C)){T.data(D,"closest",B);return D}D=D.parentNode;B++}})},not:function(B){if(typeof B==="string"){if(AC.test(B)){return this.pushStack(T.multiFilter(B,this,true),"not",B)}else{B=T.multiFilter(B,this)}}var A=B.length&&B[B.length-1]!==AB&&!B.nodeType;return this.filter(function(){return A?T.inArray(this,B)<0:this!=B})},add:function(A){return this.pushStack(T.unique(T.merge(this.get(),typeof A==="string"?T(A):T.makeArray(A))))},is:function(A){return !!A&&T.multiFilter(A,this).length>0},hasClass:function(A){return !!A&&this.is("."+A)},val:function(C){if(C===AB){var f=this[0];if(f){if(T.nodeName(f,"option")){return(f.attributes.value||{}).specified?f.value:f.text}if(T.nodeName(f,"select")){var a=f.selectedIndex,B=[],A=f.options,c=f.type=="select-one";if(a<0){return null}for(var e=c?a:0,D=c?a+1:A.length;e<D;e++){var d=A[e];if(d.selected){C=T(d).val();if(c){return C}B.push(C)}}return B}return(f.value||"").replace(/\r/g,"")}return AB}if(typeof C==="number"){C+=""}return this.each(function(){if(this.nodeType!=1){return }if(T.isArray(C)&&/radio|checkbox/.test(this.type)){this.checked=(T.inArray(this.value,C)>=0||T.inArray(this.name,C)>=0)}else{if(T.nodeName(this,"select")){var g=T.makeArray(C);T("option",this).each(function(){this.selected=(T.inArray(this.value,g)>=0||T.inArray(this.text,g)>=0)});if(!g.length){this.selectedIndex=-1}}else{this.value=C}}})},html:function(A){return A===AB?(this[0]?this[0].innerHTML.replace(/ jQuery\d+="(?:\d+|null)"/g,""):null):this.empty().append(A)},replaceWith:function(A){return this.after(A).remove()},eq:function(A){return this.slice(A,+A+1)},slice:function(){return this.pushStack(Array.prototype.slice.apply(this,arguments),"slice",Array.prototype.slice.call(arguments).join(","))},map:function(A){return this.pushStack(T.map(this,function(B,C){return A.call(B,C,B)}))},andSelf:function(){return this.add(this.prevObject)},domManip:function(D,A,B){if(this[0]){var a=(this[0].ownerDocument||this[0]).createDocumentFragment(),e=T.clean(D,(this[0].ownerDocument||this[0]),a),c=a.firstChild;if(c){for(var d=0,f=this.length;d<f;d++){B.call(C(this[d],c),this.length>1||d>0?a.cloneNode(true):a)}}if(e){T.each(e,E)}}return this;function C(h,g){return A&&T.nodeName(h,"table")&&T.nodeName(g,"tr")?(h.getElementsByTagName("tbody")[0]||h.appendChild(h.ownerDocument.createElement("tbody"))):h}}};T.fn.init.prototype=T.fn;function E(B,A){if(A.src){T.ajax({url:A.src,async:false,dataType:"script"})}else{T.globalEval(A.text||A.textContent||A.innerHTML||"")}if(A.parentNode){A.parentNode.removeChild(A)}}function AD(){return +new Date}T.extend=T.fn.extend=function(){var C=arguments[0]||{},a=1,D=arguments.length,e=false,c;if(typeof C==="boolean"){e=C;C=arguments[1]||{};a=2}if(typeof C!=="object"&&!T.isFunction(C)){C={}}if(D==a){C=this;--a}for(;a<D;a++){if((c=arguments[a])!=null){for(var d in c){var B=C[d],A=c[d];if(C===A){continue}if(e&&A&&typeof A==="object"&&!A.nodeType){C[d]=T.extend(e,B||(A.length!=null?[]:{}),A)}else{if(A!==AB){C[d]=A}}}}}return C};var AG=/z-?index|font-?weight|opacity|zoom|line-?height/i,Q=document.defaultView||{},M=Object.prototype.toString;T.extend({noConflict:function(A){W.$=R;if(A){W.jQuery=F}return T},isFunction:function(A){return M.call(A)==="[object Function]"},isArray:function(A){return M.call(A)==="[object Array]"},isXMLDoc:function(A){return A.nodeType===9&&A.documentElement.nodeName!=="HTML"||!!A.ownerDocument&&T.isXMLDoc(A.ownerDocument)},globalEval:function(A){if(A&&/\S/.test(A)){var B=document.getElementsByTagName("head")[0]||document.documentElement,C=document.createElement("script");C.type="text/javascript";if(T.support.scriptEval){C.appendChild(document.createTextNode(A))}else{C.text=A}B.insertBefore(C,B.firstChild);B.removeChild(C)}},nodeName:function(A,B){return A.nodeName&&A.nodeName.toUpperCase()==B.toUpperCase()},each:function(a,A,c){var d,D=0,C=a.length;if(c){if(C===AB){for(d in a){if(A.apply(a[d],c)===false){break}}}else{for(;D<C;){if(A.apply(a[D++],c)===false){break}}}}else{if(C===AB){for(d in a){if(A.call(a[d],d,a[d])===false){break}}}else{for(var B=a[0];D<C&&A.call(B,D,B)!==false;B=a[++D]){}}}return a},prop:function(B,A,C,D,a){if(T.isFunction(A)){A=A.call(B,D)}return typeof A==="number"&&C=="curCSS"&&!AG.test(a)?A+"px":A},className:{add:function(B,A){T.each((A||"").split(/\s+/),function(D,C){if(B.nodeType==1&&!T.className.has(B.className,C)){B.className+=(B.className?" ":"")+C}})},remove:function(B,A){if(B.nodeType==1){B.className=A!==AB?T.grep(B.className.split(/\s+/),function(C){return !T.className.has(A,C)}).join(" "):""}},has:function(A,B){return A&&T.inArray(B,(A.className||A).toString().split(/\s+/))>-1}},swap:function(B,C,A){var a={};for(var D in C){a[D]=B.style[D];B.style[D]=C[D]}A.call(B);for(var D in C){B.style[D]=a[D]}},css:function(a,d,C,e){if(d=="width"||d=="height"){var A,c={position:"absolute",visibility:"hidden",display:"block"},B=d=="width"?["Left","Right"]:["Top","Bottom"];function D(){A=d=="width"?a.offsetWidth:a.offsetHeight;if(e==="border"){return }T.each(B,function(){if(!e){A-=parseFloat(T.curCSS(a,"padding"+this,true))||0}if(e==="margin"){A+=parseFloat(T.curCSS(a,"margin"+this,true))||0}else{A-=parseFloat(T.curCSS(a,"border"+this+"Width",true))||0}})}if(a.offsetWidth!==0){D()}else{T.swap(a,c,D)}return Math.max(0,Math.round(A))}return T.curCSS(a,d,C)},curCSS:function(a,e,d){var B,f=a.style;if(e=="opacity"&&!T.support.opacity){B=T.attr(f,"opacity");return B==""?"1":B}if(e.match(/float/i)){e=H}if(!d&&f&&f[e]){B=f[e]}else{if(Q.getComputedStyle){if(e.match(/float/i)){e="float"}e=e.replace(/([A-Z])/g,"-$1").toLowerCase();var A=Q.getComputedStyle(a,null);if(A){B=A.getPropertyValue(e)}if(e=="opacity"&&B==""){B="1"}}else{if(a.currentStyle){var D=e.replace(/\-(\w)/g,function(h,g){return g.toUpperCase()});B=a.currentStyle[e]||a.currentStyle[D];if(!/^\d+(px)?$/i.test(B)&&/^\d/.test(B)){var c=f.left,C=a.runtimeStyle.left;a.runtimeStyle.left=a.currentStyle.left;f.left=B||0;B=f.pixelLeft+"px";f.left=c;a.runtimeStyle.left=C}}}}return B},clean:function(d,B,D){B=B||document;if(typeof B.createElement==="undefined"){B=B.ownerDocument||B[0]&&B[0].ownerDocument||document}if(!D&&d.length===1&&typeof d[0]==="string"){var a=/^<(\w+)\s*\/?>$/.exec(d[0]);if(a){return[B.createElement(a[1])]}}var c=[],e=[],A=B.createElement("div");T.each(d,function(i,f){if(typeof f==="number"){f+=""}if(!f){return }if(typeof f==="string"){f=f.replace(/(<(\w+)[^>]*?)\/>/g,function(o,m,p){return p.match(/^(abbr|br|col|img|input|link|meta|param|hr|area|embed)$/i)?o:m+"></"+p+">"});var j=f.replace(/^\s+/,"").substring(0,10).toLowerCase();var h=!j.indexOf("<opt")&&[1,"<select multiple='multiple'>","</select>"]||!j.indexOf("<leg")&&[1,"<fieldset>","</fieldset>"]||j.match(/^<(thead|tbody|tfoot|colg|cap)/)&&[1,"<table>","</table>"]||!j.indexOf("<tr")&&[2,"<table><tbody>","</tbody></table>"]||(!j.indexOf("<td")||!j.indexOf("<th"))&&[3,"<table><tbody><tr>","</tr></tbody></table>"]||!j.indexOf("<col")&&[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"]||!T.support.htmlSerialize&&[1,"div<div>","</div>"]||[0,"",""];A.innerHTML=h[1]+f+h[2];while(h[0]--){A=A.lastChild}if(!T.support.tbody){var g=/<tbody/i.test(f),k=!j.indexOf("<table")&&!g?A.firstChild&&A.firstChild.childNodes:h[1]=="<table>"&&!g?A.childNodes:[];for(var l=k.length-1;l>=0;--l){if(T.nodeName(k[l],"tbody")&&!k[l].childNodes.length){k[l].parentNode.removeChild(k[l])}}}if(!T.support.leadingWhitespace&&/^\s/.test(f)){A.insertBefore(B.createTextNode(f.match(/^\s*/)[0]),A.firstChild)}f=T.makeArray(A.childNodes)}if(f.nodeType){c.push(f)}else{c=T.merge(c,f)}});if(D){for(var C=0;c[C];C++){if(T.nodeName(c[C],"script")&&(!c[C].type||c[C].type.toLowerCase()==="text/javascript")){e.push(c[C].parentNode?c[C].parentNode.removeChild(c[C]):c[C])}else{if(c[C].nodeType===1){c.splice.apply(c,[C+1,0].concat(T.makeArray(c[C].getElementsByTagName("script"))))}D.appendChild(c[C])}}return e}return c},attr:function(C,c,B){if(!C||C.nodeType==3||C.nodeType==8){return AB}var a=!T.isXMLDoc(C),A=B!==AB;c=a&&T.props[c]||c;if(C.tagName){var d=/href|src|style/.test(c);if(c=="selected"&&C.parentNode){C.parentNode.selectedIndex}if(c in C&&a&&!d){if(A){if(c=="type"&&T.nodeName(C,"input")&&C.parentNode){throw"type property can't be changed"}C[c]=B}if(T.nodeName(C,"form")&&C.getAttributeNode(c)){return C.getAttributeNode(c).nodeValue}if(c=="tabIndex"){var D=C.getAttributeNode("tabIndex");return D&&D.specified?D.value:C.nodeName.match(/(button|input|object|select|textarea)/i)?0:C.nodeName.match(/^(a|area)$/i)&&C.href?0:AB}return C[c]}if(!T.support.style&&a&&c=="style"){return T.attr(C.style,"cssText",B)}if(A){C.setAttribute(c,""+B)}var e=!T.support.hrefNormalized&&a&&d?C.getAttribute(c,2):C.getAttribute(c);return e===null?AB:e}if(!T.support.opacity&&c=="opacity"){if(A){C.zoom=1;C.filter=(C.filter||"").replace(/alpha\([^)]*\)/,"")+(parseInt(B)+""=="NaN"?"":"alpha(opacity="+B*100+")")}return C.filter&&C.filter.indexOf("opacity=")>=0?(parseFloat(C.filter.match(/opacity=([^)]*)/)[1])/100)+"":""}c=c.replace(/-([a-z])/ig,function(g,f){return f.toUpperCase()});if(A){C[c]=B}return C[c]},trim:function(A){return(A||"").replace(/^\s+|\s+$/g,"")},makeArray:function(A){var C=[];if(A!=null){var B=A.length;if(B==null||typeof A==="string"||T.isFunction(A)||A.setInterval){C[0]=A}else{while(B){C[--B]=A[B]}}}return C},inArray:function(B,A){for(var D=0,C=A.length;D<C;D++){if(A[D]===B){return D}}return -1},merge:function(B,a){var D=0,C,A=B.length;if(!T.support.getAll){while((C=a[D++])!=null){if(C.nodeType!=8){B[A++]=C}}}else{while((C=a[D++])!=null){B[A++]=C}}return B},unique:function(A){var c=[],d={};try{for(var a=0,D=A.length;a<D;a++){var B=T.data(A[a]);if(!d[B]){d[B]=true;c.push(A[a])}}}catch(C){c=A}return c},grep:function(a,A,c){var D=[];for(var C=0,B=a.length;C<B;C++){if(!c!=!A(a[C],C)){D.push(a[C])}}return D},map:function(c,A){var a=[];for(var D=0,C=c.length;D<C;D++){var B=A(c[D],D);if(B!=null){a[a.length]=B}}return a.concat.apply([],a)}});var O=navigator.userAgent.toLowerCase();T.browser={version:(O.match(/.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/)||[0,"0"])[1],safari:/webkit/.test(O),opera:/opera/.test(O),msie:/msie/.test(O)&&!/opera/.test(O),mozilla:/mozilla/.test(O)&&!/(compatible|webkit)/.test(O)};T.each({parent:function(A){return A.parentNode},parents:function(A){return T.dir(A,"parentNode")},next:function(A){return T.nth(A,2,"nextSibling")},prev:function(A){return T.nth(A,2,"previousSibling")},nextAll:function(A){return T.dir(A,"nextSibling")},prevAll:function(A){return T.dir(A,"previousSibling")},siblings:function(A){return T.sibling(A.parentNode.firstChild,A)},children:function(A){return T.sibling(A.firstChild)},contents:function(A){return T.nodeName(A,"iframe")?A.contentDocument||A.contentWindow.document:T.makeArray(A.childNodes)}},function(B,A){T.fn[B]=function(D){var C=T.map(this,A);if(D&&typeof D=="string"){C=T.multiFilter(D,C)}return this.pushStack(T.unique(C),B,D)}});T.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(B,A){T.fn[B]=function(e){var a=[],C=T(e);for(var D=0,d=C.length;D<d;D++){var c=(D>0?this.clone(true):this).get();T.fn[A].apply(T(C[D]),c);a=a.concat(c)}return this.pushStack(a,B,e)}});T.each({removeAttr:function(A){T.attr(this,A,"");if(this.nodeType==1){this.removeAttribute(A)}},addClass:function(A){T.className.add(this,A)},removeClass:function(A){T.className.remove(this,A)},toggleClass:function(A,B){if(typeof B!=="boolean"){B=!T.className.has(this,A)}T.className[B?"add":"remove"](this,A)},remove:function(A){if(!A||T.filter(A,[this]).length){T("*",this).add([this]).each(function(){T.event.remove(this);T.removeData(this)});if(this.parentNode){this.parentNode.removeChild(this)}}},empty:function(){T(this).children().remove();while(this.firstChild){this.removeChild(this.firstChild)}}},function(B,A){T.fn[B]=function(){return this.each(A,arguments)}});function Y(B,A){return B[0]&&parseInt(T.curCSS(B[0],A,true),10)||0}var AA="jQuery"+AD(),I=0,S={};T.extend({cache:{},data:function(C,D,B){C=C==W?S:C;var A=C[AA];if(!A){A=C[AA]=++I}if(D&&!T.cache[A]){T.cache[A]={}}if(B!==AB){T.cache[A][D]=B}return D?T.cache[A][D]:A},removeData:function(C,D){C=C==W?S:C;var A=C[AA];if(D){if(T.cache[A]){delete T.cache[A][D];D="";for(D in T.cache[A]){break}if(!D){T.removeData(C)}}}else{try{delete C[AA]}catch(B){if(C.removeAttribute){C.removeAttribute(AA)}}delete T.cache[A]}},queue:function(C,D,A){if(C){D=(D||"fx")+"queue";var B=T.data(C,D);if(!B||T.isArray(A)){B=T.data(C,D,T.makeArray(A))}else{if(A){B.push(A)}}}return B},dequeue:function(A,B){var D=T.queue(A,B),C=D.shift();if(!B||B==="fx"){C=D[0]}if(C!==AB){C.call(A)}}});T.fn.extend({data:function(D,B){var A=D.split(".");A[1]=A[1]?"."+A[1]:"";if(B===AB){var C=this.triggerHandler("getData"+A[1]+"!",[A[0]]);if(C===AB&&this.length){C=T.data(this[0],D)}return C===AB&&A[1]?this.data(A[0]):C}else{return this.trigger("setData"+A[1]+"!",[A[0],B]).each(function(){T.data(this,D,B)})}},removeData:function(A){return this.each(function(){T.removeData(this,A)})},queue:function(B,A){if(typeof B!=="string"){A=B;B="fx"}if(A===AB){return T.queue(this[0],B)}return this.each(function(){var C=T.queue(this,B,A);if(B=="fx"&&C.length==1){C[0].call(this)}})},dequeue:function(A){return this.each(function(){T.dequeue(this,A)})}});(function(){var B=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?/g,e=0,i=Object.prototype.toString;var k=function(p,t,AK,AJ){AK=AK||[];t=t||document;if(t.nodeType!==1&&t.nodeType!==9){return[]}if(!p||typeof p!=="string"){return AK}var o=[],r,y,v,u,AI,s,q=true;B.lastIndex=0;while((r=B.exec(p))!==null){o.push(r[1]);if(r[2]){s=RegExp.rightContext;break}}if(o.length>1&&d.exec(p)){if(o.length===2&&h.relative[o[0]]){y=g(o[0]+o[1],t)}else{y=h.relative[o[0]]?[t]:k(o.shift(),t);while(o.length){p=o.shift();if(h.relative[p]){p+=o.shift()}y=g(p,y)}}}else{var z=AJ?{expr:o.pop(),set:l(AJ)}:k.find(o.pop(),o.length===1&&t.parentNode?t.parentNode:t,C(t));y=k.filter(z.expr,z.set);if(o.length>0){v=l(y)}else{q=false}while(o.length){var w=o.pop(),x=w;if(!h.relative[w]){w=""}else{x=o.pop()}if(x==null){x=t}h.relative[w](v,x,C(t))}}if(!v){v=y}if(!v){throw"Syntax error, unrecognized expression: "+(w||p)}if(i.call(v)==="[object Array]"){if(!q){AK.push.apply(AK,v)}else{if(t.nodeType===1){for(var m=0;v[m]!=null;m++){if(v[m]&&(v[m]===true||v[m].nodeType===1&&f(t,v[m]))){AK.push(y[m])}}}else{for(var m=0;v[m]!=null;m++){if(v[m]&&v[m].nodeType===1){AK.push(y[m])}}}}}else{l(v,AK)}if(s){k(s,t,AK,AJ);if(j){hasDuplicate=false;AK.sort(j);if(hasDuplicate){for(var m=1;m<AK.length;m++){if(AK[m]===AK[m-1]){AK.splice(m--,1)}}}}}return AK};k.matches=function(o,m){return k(o,null,null,m)};k.find=function(m,u,v){var o,q;if(!m){return[]}for(var r=0,s=h.order.length;r<s;r++){var p=h.order[r],q;if((q=h.match[p].exec(m))){var t=RegExp.leftContext;if(t.substr(t.length-1)!=="\\"){q[1]=(q[1]||"").replace(/\\/g,"");o=h.find[p](q,u,v);if(o!=null){m=m.replace(h.match[p],"");break}}}}if(!o){o=u.getElementsByTagName("*")}return{set:o,expr:m}};k.filter=function(AI,AJ,x,r){var s=AI,v=[],m=AJ,p,u,o=AJ&&AJ[0]&&C(AJ[0]);while(AI&&AJ.length){for(var AK in h.filter){if((p=h.match[AK].exec(AI))!=null){var t=h.filter[AK],w,y;u=false;if(m==v){v=[]}if(h.preFilter[AK]){p=h.preFilter[AK](p,m,x,v,r,o);if(!p){u=w=true}else{if(p===true){continue}}}if(p){for(var q=0;(y=m[q])!=null;q++){if(y){w=t(y,p,q,m);var z=r^!!w;if(x&&w!=null){if(z){u=true}else{m[q]=false}}else{if(z){v.push(y);u=true}}}}}if(w!==AB){if(!x){m=v}AI=AI.replace(h.match[AK],"");if(!u){return[]}break}}}if(AI==s){if(u==null){throw"Syntax error, unrecognized expression: "+AI}else{break}}s=AI}return m};var h=k.selectors={order:["ID","NAME","TAG"],match:{ID:/#((?:[\w\u00c0-\uFFFF_-]|\\.)+)/,CLASS:/\.((?:[\w\u00c0-\uFFFF_-]|\\.)+)/,NAME:/\[name=['"]*((?:[\w\u00c0-\uFFFF_-]|\\.)+)['"]*\]/,ATTR:/\[\s*((?:[\w\u00c0-\uFFFF_-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,TAG:/^((?:[\w\u00c0-\uFFFF\*_-]|\\.)+)/,CHILD:/:(only|nth|last|first)-child(?:\((even|odd|[\dn+-]*)\))?/,POS:/:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^-]|$)/,PSEUDO:/:((?:[\w\u00c0-\uFFFF_-]|\\.)+)(?:\((['"]*)((?:\([^\)]+\)|[^\2\(\)]*)+)\2\))?/},attrMap:{"class":"className","for":"htmlFor"},attrHandle:{href:function(m){return m.getAttribute("href")}},relative:{"+":function(m,u,o){var q=typeof u==="string",v=q&&!/\W/.test(u),p=q&&!v;if(v&&!o){u=u.toUpperCase()}for(var r=0,s=m.length,t;r<s;r++){if((t=m[r])){while((t=t.previousSibling)&&t.nodeType!==1){}m[r]=p||t&&t.nodeName===u?t||false:t===u}}if(p){k.filter(u,m,true)}},">":function(s,p,r){var u=typeof p==="string";if(u&&!/\W/.test(p)){p=r?p:p.toUpperCase();for(var o=0,q=s.length;o<q;o++){var t=s[o];if(t){var m=t.parentNode;s[o]=m.nodeName===p?m:false}}}else{for(var o=0,q=s.length;o<q;o++){var t=s[o];if(t){s[o]=u?t.parentNode:t.parentNode===p}}if(u){k.filter(p,s,true)}}},"":function(m,p,r){var o=e++,q=A;if(!p.match(/\W/)){var s=p=r?p:p.toUpperCase();q=D}q("parentNode",p,o,m,s,r)},"~":function(m,p,r){var o=e++,q=A;if(typeof p==="string"&&!p.match(/\W/)){var s=p=r?p:p.toUpperCase();q=D}q("previousSibling",p,o,m,s,r)}},find:{ID:function(p,o,m){if(typeof o.getElementById!=="undefined"&&!m){var q=o.getElementById(p[1]);return q?[q]:[]}},NAME:function(o,s,r){if(typeof s.getElementsByName!=="undefined"){var p=[],t=s.getElementsByName(o[1]);for(var m=0,q=t.length;m<q;m++){if(t[m].getAttribute("name")===o[1]){p.push(t[m])}}return p.length===0?null:p}},TAG:function(o,m){return m.getElementsByTagName(o[1])}},preFilter:{CLASS:function(m,p,o,q,s,r){m=" "+m[1].replace(/\\/g,"")+" ";if(r){return m}for(var u=0,t;(t=p[u])!=null;u++){if(t){if(s^(t.className&&(" "+t.className+" ").indexOf(m)>=0)){if(!o){q.push(t)}}else{if(o){p[u]=false}}}}return false},ID:function(m){return m[1].replace(/\\/g,"")},TAG:function(o,p){for(var m=0;p[m]===false;m++){}return p[m]&&C(p[m])?o[1]:o[1].toUpperCase()},CHILD:function(o){if(o[1]=="nth"){var m=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(o[2]=="even"&&"2n"||o[2]=="odd"&&"2n+1"||!/\D/.test(o[2])&&"0n+"+o[2]||o[2]);o[2]=(m[1]+(m[2]||1))-0;o[3]=m[3]-0}o[0]=e++;return o},ATTR:function(t,p,o,q,s,r){var m=t[1].replace(/\\/g,"");if(!r&&h.attrMap[m]){t[1]=h.attrMap[m]}if(t[2]==="~="){t[4]=" "+t[4]+" "}return t},PSEUDO:function(s,p,o,q,r){if(s[1]==="not"){if(s[3].match(B).length>1||/^\w/.test(s[3])){s[3]=k(s[3],null,null,p)}else{var m=k.filter(s[3],p,o,true^r);if(!o){q.push.apply(q,m)}return false}}else{if(h.match.POS.test(s[0])||h.match.CHILD.test(s[0])){return true}}return s},POS:function(m){m.unshift(true);return m}},filters:{enabled:function(m){return m.disabled===false&&m.type!=="hidden"},disabled:function(m){return m.disabled===true},checked:function(m){return m.checked===true},selected:function(m){m.parentNode.selectedIndex;return m.selected===true},parent:function(m){return !!m.firstChild},empty:function(m){return !m.firstChild},has:function(m,o,p){return !!k(p[3],m).length},header:function(m){return/h\d/i.test(m.nodeName)},text:function(m){return"text"===m.type},radio:function(m){return"radio"===m.type},checkbox:function(m){return"checkbox"===m.type},file:function(m){return"file"===m.type},password:function(m){return"password"===m.type},submit:function(m){return"submit"===m.type},image:function(m){return"image"===m.type},reset:function(m){return"reset"===m.type},button:function(m){return"button"===m.type||m.nodeName.toUpperCase()==="BUTTON"},input:function(m){return/input|select|textarea|button/i.test(m.nodeName)}},setFilters:{first:function(m,o){return o===0},last:function(o,p,q,m){return p===m.length-1},even:function(m,o){return o%2===0},odd:function(m,o){return o%2===1},lt:function(m,o,p){return o<p[3]-0},gt:function(m,o,p){return o>p[3]-0},nth:function(m,o,p){return p[3]-0==o},eq:function(m,o,p){return p[3]-0==o}},filter:{PSEUDO:function(s,o,m,r){var p=o[1],u=h.filters[p];if(u){return u(s,m,o,r)}else{if(p==="contains"){return(s.textContent||s.innerText||"").indexOf(o[3])>=0}else{if(p==="not"){var t=o[3];for(var m=0,q=t.length;m<q;m++){if(t[m]===s){return false}}return true}}}},CHILD:function(u,r){var o=r[1],t=u;switch(o){case"only":case"first":while(t=t.previousSibling){if(t.nodeType===1){return false}}if(o=="first"){return true}t=u;case"last":while(t=t.nextSibling){if(t.nodeType===1){return false}}return true;case"nth":var s=r[2],v=r[3];if(s==1&&v==0){return true}var p=r[0],w=u.parentNode;if(w&&(w.sizcache!==p||!u.nodeIndex)){var q=0;for(t=w.firstChild;t;t=t.nextSibling){if(t.nodeType===1){t.nodeIndex=++q}}w.sizcache=p}var m=u.nodeIndex-v;if(s==0){return m==0}else{return(m%s==0&&m/s>=0)}}},ID:function(m,o){return m.nodeType===1&&m.getAttribute("id")===o},TAG:function(m,o){return(o==="*"&&m.nodeType===1)||m.nodeName===o},CLASS:function(m,o){return(" "+(m.className||m.getAttribute("class"))+" ").indexOf(o)>-1},ATTR:function(s,m){var o=m[1],q=h.attrHandle[o]?h.attrHandle[o](s):s[o]!=null?s[o]:s.getAttribute(o),r=q+"",t=m[2],p=m[4];return q==null?t==="!=":t==="="?r===p:t==="*="?r.indexOf(p)>=0:t==="~="?(" "+r+" ").indexOf(p)>=0:!p?r&&q!==false:t==="!="?r!=p:t==="^="?r.indexOf(p)===0:t==="$="?r.substr(r.length-p.length)===p:t==="|="?r===p||r.substr(0,p.length+1)===p+"-":false},POS:function(s,p,o,r){var q=p[2],m=h.setFilters[q];if(m){return m(s,o,p,r)}}}};var d=h.match.POS;for(var a in h.match){h.match[a]=RegExp(h.match[a].source+/(?![^\[]*\])(?![^\(]*\))/.source)}var l=function(m,o){m=Array.prototype.slice.call(m);if(o){o.push.apply(o,m);return o}return m};try{Array.prototype.slice.call(document.documentElement.childNodes)}catch(c){l=function(r,m){var p=m||[];if(i.call(r)==="[object Array]"){Array.prototype.push.apply(p,r)}else{if(typeof r.length==="number"){for(var o=0,q=r.length;o<q;o++){p.push(r[o])}}else{for(var o=0;r[o];o++){p.push(r[o])}}}return p}}var j;if(document.documentElement.compareDocumentPosition){j=function(o,p){var m=o.compareDocumentPosition(p)&4?-1:o===p?0:1;if(m===0){hasDuplicate=true}return m}}else{if("sourceIndex" in document.documentElement){j=function(o,p){var m=o.sourceIndex-p.sourceIndex;if(m===0){hasDuplicate=true}return m}}else{if(document.createRange){j=function(m,p){var o=m.ownerDocument.createRange(),q=p.ownerDocument.createRange();o.selectNode(m);o.collapse(true);q.selectNode(p);q.collapse(true);var r=o.compareBoundaryPoints(Range.START_TO_END,q);if(r===0){hasDuplicate=true}return r}}}}(function(){var o=document.createElement("form"),m="script"+(new Date).getTime();o.innerHTML="<input name='"+m+"'/>";var p=document.documentElement;p.insertBefore(o,p.firstChild);if(!!document.getElementById(m)){h.find.ID=function(t,s,r){if(typeof s.getElementById!=="undefined"&&!r){var q=s.getElementById(t[1]);return q?q.id===t[1]||typeof q.getAttributeNode!=="undefined"&&q.getAttributeNode("id").nodeValue===t[1]?[q]:AB:[]}};h.filter.ID=function(r,q){var s=typeof r.getAttributeNode!=="undefined"&&r.getAttributeNode("id");return r.nodeType===1&&s&&s.nodeValue===q}}p.removeChild(o)})();(function(){var m=document.createElement("div");m.appendChild(document.createComment(""));if(m.getElementsByTagName("*").length>0){h.find.TAG=function(q,r){var s=r.getElementsByTagName(q[1]);if(q[1]==="*"){var o=[];for(var p=0;s[p];p++){if(s[p].nodeType===1){o.push(s[p])}}s=o}return s}}m.innerHTML="<a href='#'></a>";if(m.firstChild&&typeof m.firstChild.getAttribute!=="undefined"&&m.firstChild.getAttribute("href")!=="#"){h.attrHandle.href=function(o){return o.getAttribute("href",2)}}})();if(document.querySelectorAll){(function(){var o=k,m=document.createElement("div");m.innerHTML="<p class='TEST'></p>";if(m.querySelectorAll&&m.querySelectorAll(".TEST").length===0){return }k=function(s,t,q,p){t=t||document;if(!p&&t.nodeType===9&&!C(t)){try{return l(t.querySelectorAll(s),q)}catch(r){}}return o(s,t,q,p)};k.find=o.find;k.filter=o.filter;k.selectors=o.selectors;k.matches=o.matches})()}if(document.getElementsByClassName&&document.documentElement.getElementsByClassName){(function(){var m=document.createElement("div");m.innerHTML="<div class='test e'></div><div class='test'></div>";if(m.getElementsByClassName("e").length===0){return }m.lastChild.className="e";if(m.getElementsByClassName("e").length===1){return }h.order.splice(1,0,"CLASS");h.find.CLASS=function(q,p,o){if(typeof p.getElementsByClassName!=="undefined"&&!o){return p.getElementsByClassName(q[1])}}})()}function D(t,o,p,v,m,w){var x=t=="previousSibling"&&!w;for(var r=0,s=v.length;r<s;r++){var u=v[r];if(u){if(x&&u.nodeType===1){u.sizcache=p;u.sizset=r}u=u[t];var q=false;while(u){if(u.sizcache===p){q=v[u.sizset];break}if(u.nodeType===1&&!w){u.sizcache=p;u.sizset=r}if(u.nodeName===o){q=u;break}u=u[t]}v[r]=q}}}function A(t,o,p,v,m,w){var x=t=="previousSibling"&&!w;for(var r=0,s=v.length;r<s;r++){var u=v[r];if(u){if(x&&u.nodeType===1){u.sizcache=p;u.sizset=r}u=u[t];var q=false;while(u){if(u.sizcache===p){q=v[u.sizset];break}if(u.nodeType===1){if(!w){u.sizcache=p;u.sizset=r}if(typeof o!=="string"){if(u===o){q=true;break}}else{if(k.filter(o,[u]).length>0){q=u;break}}}u=u[t]}v[r]=q}}}var f=document.compareDocumentPosition?function(m,o){return m.compareDocumentPosition(o)&16}:function(m,o){return m!==o&&(m.contains?m.contains(o):true)};var C=function(m){return m.nodeType===9&&m.documentElement.nodeName!=="HTML"||!!m.ownerDocument&&C(m.ownerDocument)};var g=function(q,s){var m=[],u="",t,o=s.nodeType?[s]:s;while((t=h.match.PSEUDO.exec(q))){u+=t[0];q=q.replace(h.match.PSEUDO,"")}q=h.relative[q]?q+"*":q;for(var r=0,p=o.length;r<p;r++){k(q,o[r],m)}return k.filter(u,m)};T.find=k;T.filter=k.filter;T.expr=k.selectors;T.expr[":"]=T.expr.filters;k.selectors.filters.hidden=function(m){return m.offsetWidth===0||m.offsetHeight===0};k.selectors.filters.visible=function(m){return m.offsetWidth>0||m.offsetHeight>0};k.selectors.filters.animated=function(m){return T.grep(T.timers,function(o){return m===o.elem}).length};T.multiFilter=function(m,p,o){if(o){m=":not("+m+")"}return k.matches(m,p)};T.dir=function(o,p){var q=[],m=o[p];while(m&&m!=document){if(m.nodeType==1){q.push(m)}m=m[p]}return q};T.nth=function(r,q,o,m){q=q||1;var p=0;for(;r;r=r[o]){if(r.nodeType==1&&++p==q){break}}return r};T.sibling=function(m,o){var p=[];for(;m;m=m.nextSibling){if(m.nodeType==1&&m!=o){p.push(m)}}return p};return ;W.Sizzle=k})();T.event={add:function(C,c,D,A){if(C.nodeType==3||C.nodeType==8){return }if(C.setInterval&&C!=W){C=W}if(!D.guid){D.guid=this.guid++}if(A!==AB){var a=D;D=this.proxy(a);D.data=A}var d=T.data(C,"events")||T.data(C,"events",{}),B=T.data(C,"handle")||T.data(C,"handle",function(){return typeof T!=="undefined"&&!T.event.triggered?T.event.handle.apply(arguments.callee.elem,arguments):AB});B.elem=C;T.each(c.split(/\s+/),function(h,g){var f=g.split(".");g=f.shift();D.type=f.slice().sort().join(".");var e=d[g];if(T.event.specialAll[g]){T.event.specialAll[g].setup.call(C,A,f)}if(!e){e=d[g]={};if(!T.event.special[g]||T.event.special[g].setup.call(C,A,f)===false){if(C.addEventListener){C.addEventListener(g,B,false)}else{if(C.attachEvent){C.attachEvent("on"+g,B)}}}}e[D.guid]=D;T.event.global[g]=true});C=null},guid:1,global:{},remove:function(B,a,C){if(B.nodeType==3||B.nodeType==8){return }var c=T.data(B,"events"),d,e;if(c){if(a===AB||(typeof a==="string"&&a.charAt(0)==".")){for(var D in c){this.remove(B,D+(a||""))}}else{if(a.type){C=a.handler;a=a.type}T.each(a.split(/\s+/),function(j,h){var f=h.split(".");h=f.shift();var i=RegExp("(^|\\.)"+f.slice().sort().join(".*\\.")+"(\\.|$)");if(c[h]){if(C){delete c[h][C.guid]}else{for(var g in c[h]){if(i.test(c[h][g].type)){delete c[h][g]}}}if(T.event.specialAll[h]){T.event.specialAll[h].teardown.call(B,f)}for(d in c[h]){break}if(!d){if(!T.event.special[h]||T.event.special[h].teardown.call(B,f)===false){if(B.removeEventListener){B.removeEventListener(h,T.data(B,"handle"),false)}else{if(B.detachEvent){B.detachEvent("on"+h,T.data(B,"handle"))}}}d=null;delete c[h]}}})}for(d in c){break}if(!d){var A=T.data(B,"handle");if(A){A.elem=null}T.removeData(B,"events");T.removeData(B,"handle")}}},trigger:function(D,B,a,e){var c=D.type||D;if(!e){D=typeof D==="object"?D[AA]?D:T.extend(T.Event(c),D):T.Event(c);if(c.indexOf("!")>=0){D.type=c=c.slice(0,-1);D.exclusive=true}if(!a){D.stopPropagation();if(this.global[c]){T.each(T.cache,function(){if(this.events&&this.events[c]){T.event.trigger(D,B,this.handle.elem)}})}}if(!a||a.nodeType==3||a.nodeType==8){return AB}D.result=AB;D.target=a;B=T.makeArray(B);B.unshift(D)}D.currentTarget=a;var C=T.data(a,"handle");if(C){C.apply(a,B)}if((!a[c]||(T.nodeName(a,"a")&&c=="click"))&&a["on"+c]&&a["on"+c].apply(a,B)===false){D.result=false}if(!e&&a[c]&&!D.isDefaultPrevented()&&!(T.nodeName(a,"a")&&c=="click")){this.triggered=true;try{a[c]()}catch(A){}}this.triggered=false;if(!D.isPropagationStopped()){var d=a.parentNode||a.ownerDocument;if(d){T.event.trigger(D,B,d,true)}}},handle:function(B){var C,e;B=arguments[0]=T.event.fix(B||W.event);B.currentTarget=this;var A=B.type.split(".");B.type=A.shift();C=!A.length&&!B.exclusive;var D=RegExp("(^|\\.)"+A.slice().sort().join(".*\\.")+"(\\.|$)");e=(T.data(this,"events")||{})[B.type];for(var c in e){var a=e[c];if(C||D.test(a.type)){B.handler=a;B.data=a.data;var d=a.apply(this,arguments);if(d!==AB){B.result=d;if(d===false){B.preventDefault();B.stopPropagation()}}if(B.isImmediatePropagationStopped()){break}}}},props:"altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode metaKey newValue originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),fix:function(C){if(C[AA]){return C}var a=C;C=T.Event(a);for(var D=this.props.length,A;D;){A=this.props[--D];C[A]=a[A]}if(!C.target){C.target=C.srcElement||document}if(C.target.nodeType==3){C.target=C.target.parentNode}if(!C.relatedTarget&&C.fromElement){C.relatedTarget=C.fromElement==C.target?C.toElement:C.fromElement}if(C.pageX==null&&C.clientX!=null){var B=document.documentElement,c=document.body;C.pageX=C.clientX+(B&&B.scrollLeft||c&&c.scrollLeft||0)-(B.clientLeft||0);C.pageY=C.clientY+(B&&B.scrollTop||c&&c.scrollTop||0)-(B.clientTop||0)}if(!C.which&&((C.charCode||C.charCode===0)?C.charCode:C.keyCode)){C.which=C.charCode||C.keyCode}if(!C.metaKey&&C.ctrlKey){C.metaKey=C.ctrlKey}if(!C.which&&C.button){C.which=(C.button&1?1:(C.button&2?3:(C.button&4?2:0)))}return C},proxy:function(A,B){B=B||function(){return A.apply(this,arguments)};B.guid=A.guid=A.guid||B.guid||this.guid++;return B},special:{ready:{setup:P,teardown:function(){}}},specialAll:{live:{setup:function(B,A){T.event.add(this,A[0],AF)},teardown:function(A){if(A.length){var C=0,B=RegExp("(^|\\.)"+A[0]+"(\\.|$)");T.each((T.data(this,"events").live||{}),function(){if(B.test(this.type)){C++}});if(C<1){T.event.remove(this,A[0],AF)}}}}}};T.Event=function(A){if(!this.preventDefault){return new T.Event(A)}if(A&&A.type){this.originalEvent=A;this.type=A.type}else{this.type=A}this.timeStamp=AD();this[AA]=true};function X(){return false}function J(){return true}T.Event.prototype={preventDefault:function(){this.isDefaultPrevented=J;var A=this.originalEvent;if(!A){return }if(A.preventDefault){A.preventDefault()}A.returnValue=false},stopPropagation:function(){this.isPropagationStopped=J;var A=this.originalEvent;if(!A){return }if(A.stopPropagation){A.stopPropagation()}A.cancelBubble=true},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=J;this.stopPropagation()},isDefaultPrevented:X,isPropagationStopped:X,isImmediatePropagationStopped:X};var AH=function(B){var C=B.relatedTarget;while(C&&C!=this){try{C=C.parentNode}catch(A){C=this}}if(C!=this){B.type=B.data;T.event.handle.apply(this,arguments)}};T.each({mouseover:"mouseenter",mouseout:"mouseleave"},function(A,B){T.event.special[B]={setup:function(){T.event.add(this,A,AH,B)},teardown:function(){T.event.remove(this,A,AH)}}});T.fn.extend({bind:function(B,A,C){return B=="unload"?this.one(B,A,C):this.each(function(){T.event.add(this,B,C||A,C&&A)})},one:function(B,A,C){var D=T.event.proxy(C||A,function(a){T(this).unbind(a,D);return(C||A).apply(this,arguments)});return this.each(function(){T.event.add(this,B,D,C&&A)})},unbind:function(A,B){return this.each(function(){T.event.remove(this,A,B)})},trigger:function(B,A){return this.each(function(){T.event.trigger(B,A,this)})},triggerHandler:function(C,A){if(this[0]){var B=T.Event(C);B.preventDefault();B.stopPropagation();T.event.trigger(B,A,this[0]);return B.result}},toggle:function(A){var C=arguments,B=1;while(B<C.length){T.event.proxy(A,C[B++])}return this.click(T.event.proxy(A,function(D){this.lastToggle=(this.lastToggle||0)%B;D.preventDefault();return C[this.lastToggle++].apply(this,arguments)||false}))},hover:function(B,A){return this.mouseenter(B).mouseleave(A)},ready:function(A){P();if(T.isReady){A.call(document,T)}else{T.readyList.push(A)}return this},live:function(A,B){var C=T.event.proxy(B);C.guid+=this.selector+A;T(document).bind(Z(A,this.selector),this.selector,C);return this},die:function(A,B){T(document).unbind(Z(A,this.selector),B?{guid:B.guid+this.selector+A}:null);return this}});function AF(A){var D=RegExp("(^|\\.)"+A.type+"(\\.|$)"),B=true,C=[];T.each(T.data(this,"events").live||[],function(d,c){if(D.test(c.type)){var a=T(A.target).closest(c.data)[0];if(a){C.push({elem:a,fn:c})}}});C.sort(function(a,c){return T.data(a.elem,"closest")-T.data(c.elem,"closest")});T.each(C,function(){if(this.fn.call(this.elem,A,this.fn.data)===false){return(B=false)}});return B}function Z(A,B){return["live",A,B.replace(/\./g,"`").replace(/ /g,"|")].join(".")}T.extend({isReady:false,readyList:[],ready:function(){if(!T.isReady){T.isReady=true;if(T.readyList){T.each(T.readyList,function(){this.call(document,T)});T.readyList=null}T(document).triggerHandler("ready")}}});var G=false;function P(){if(G){return }G=true;if(document.addEventListener){document.addEventListener("DOMContentLoaded",function(){document.removeEventListener("DOMContentLoaded",arguments.callee,false);T.ready()},false)}else{if(document.attachEvent){document.attachEvent("onreadystatechange",function(){if(document.readyState==="complete"){document.detachEvent("onreadystatechange",arguments.callee);T.ready()}});if(document.documentElement.doScroll&&W==W.top){(function(){if(T.isReady){return }try{document.documentElement.doScroll("left")}catch(A){setTimeout(arguments.callee,0);return }T.ready()})()}}}T.event.add(W,"load",T.ready)}T.each(("blur,focus,load,resize,scroll,unload,click,dblclick,mousedown,mouseup,mousemove,mouseover,mouseout,mouseenter,mouseleave,change,select,submit,keydown,keypress,keyup,error").split(","),function(A,B){T.fn[B]=function(C){return C?this.bind(B,C):this.trigger(B)}});T(W).bind("unload",function(){for(var A in T.cache){if(A!=1&&T.cache[A].handle){T.event.remove(T.cache[A].handle.elem)}}});(function(){T.support={};var c=document.documentElement,a=document.createElement("script"),A=document.createElement("div"),B="script"+(new Date).getTime();A.style.display="none";A.innerHTML=' <link/><table></table><a href="/a" style="color:red;float:left;opacity:.5;">a</a><select><option>text</option></select><object><param/></object>';var D=A.getElementsByTagName("*"),d=A.getElementsByTagName("a")[0];if(!D||!D.length||!d){return }T.support={leadingWhitespace:A.firstChild.nodeType==3,tbody:!A.getElementsByTagName("tbody").length,objectAll:!!A.getElementsByTagName("object")[0].getElementsByTagName("*").length,htmlSerialize:!!A.getElementsByTagName("link").length,style:/red/.test(d.getAttribute("style")),hrefNormalized:d.getAttribute("href")==="/a",opacity:d.style.opacity==="0.5",cssFloat:!!d.style.cssFloat,scriptEval:false,noCloneEvent:true,boxModel:null};a.type="text/javascript";try{a.appendChild(document.createTextNode("window."+B+"=1;"))}catch(C){}c.insertBefore(a,c.firstChild);if(W[B]){T.support.scriptEval=true;delete W[B]}c.removeChild(a);if(A.attachEvent&&A.fireEvent){A.attachEvent("onclick",function(){T.support.noCloneEvent=false;A.detachEvent("onclick",arguments.callee)});A.cloneNode(true).fireEvent("onclick")}T(function(){var e=document.createElement("div");e.style.width=e.style.paddingLeft="1px";document.body.appendChild(e);T.boxModel=T.support.boxModel=e.offsetWidth===2;document.body.removeChild(e).style.display="none"})})();var H=T.support.cssFloat?"cssFloat":"styleFloat";T.props={"for":"htmlFor","class":"className","float":H,cssFloat:H,styleFloat:H,readonly:"readOnly",maxlength:"maxLength",cellspacing:"cellSpacing",rowspan:"rowSpan",tabindex:"tabIndex"};T.fn.extend({_load:T.fn.load,load:function(a,B,A){if(typeof a!=="string"){return this._load(a)}var C=a.indexOf(" ");if(C>=0){var d=a.slice(C,a.length);a=a.slice(0,C)}var D="GET";if(B){if(T.isFunction(B)){A=B;B=null}else{if(typeof B==="object"){B=T.param(B);D="POST"}}}var c=this;T.ajax({url:a,type:D,dataType:"html",data:B,complete:function(f,e){if(e=="success"||e=="notmodified"){c.html(d?T("<div/>").append(f.responseText.replace(/<script(.|\s)*?\/script>/g,"")).find(d):f.responseText)}if(A){c.each(A,[f.responseText,e,f])}}});return this},serialize:function(){return T.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?T.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||/select|textarea/i.test(this.nodeName)||/text|hidden|password|search/i.test(this.type))}).map(function(C,B){var A=T(this).val();return A==null?null:T.isArray(A)?T.map(A,function(D,a){return{name:B.name,value:D}}):{name:B.name,value:A}}).get()}});T.each("ajaxStart,ajaxStop,ajaxComplete,ajaxError,ajaxSuccess,ajaxSend".split(","),function(B,A){T.fn[A]=function(C){return this.bind(A,C)}});var N=AD();T.extend({get:function(D,B,A,C){if(T.isFunction(B)){A=B;B=null}return T.ajax({type:"GET",url:D,data:B,success:A,dataType:C})},getScript:function(B,A){return T.get(B,null,A,"script")},getJSON:function(C,B,A){return T.get(C,B,A,"json")},post:function(D,B,A,C){if(T.isFunction(B)){A=B;B={}}return T.ajax({type:"POST",url:D,data:B,success:A,dataType:C})},ajaxSetup:function(A){T.extend(T.ajaxSettings,A)},ajaxSettings:{url:location.href,global:true,type:"GET",contentType:"application/x-www-form-urlencoded",processData:true,async:true,xhr:function(){return W.ActiveXObject?new ActiveXObject("Microsoft.XMLHTTP"):new XMLHttpRequest()},accepts:{xml:"application/xml, text/xml",html:"text/html",script:"text/javascript, application/javascript",json:"application/json, text/javascript",text:"text/plain",_default:"*/*"}},lastModified:{},ajax:function(h){h=T.extend(true,h,T.extend(true,{},T.ajaxSettings,h));var A,p=/=\?(&|$)/g,c,B,o=h.type.toUpperCase();if(h.data&&h.processData&&typeof h.data!=="string"){h.data=T.param(h.data)}if(h.dataType=="jsonp"){if(o=="GET"){if(!h.url.match(p)){h.url+=(h.url.match(/\?/)?"&":"?")+(h.jsonp||"callback")+"=?"}}else{if(!h.data||!h.data.match(p)){h.data=(h.data?h.data+"&":"")+(h.jsonp||"callback")+"=?"}}h.dataType="json"}if(h.dataType=="json"&&(h.data&&h.data.match(p)||h.url.match(p))){A="jsonp"+N++;if(h.data){h.data=(h.data+"").replace(p,"="+A+"$1")}h.url=h.url.replace(p,"="+A+"$1");h.dataType="script";W[A]=function(s){B=s;l();i();W[A]=AB;try{delete W[A]}catch(r){}if(m){m.removeChild(D)}}}if(h.dataType=="script"&&h.cache==null){h.cache=false}if(h.cache===false&&o=="GET"){var q=AD();var C=h.url.replace(/(\?|&)_=.*?(&|$)/,"$1_="+q+"$2");h.url=C+((C==h.url)?(h.url.match(/\?/)?"&":"?")+"_="+q:"")}if(h.data&&o=="GET"){h.url+=(h.url.match(/\?/)?"&":"?")+h.data;h.data=null}if(h.global&&!T.active++){T.event.trigger("ajaxStart")}var d=/^(\w+:)?\/\/([^\/?#]+)/.exec(h.url);if(h.dataType=="script"&&o=="GET"&&d&&(d[1]&&d[1]!=location.protocol||d[2]!=location.host)){var m=document.getElementsByTagName("head")[0];var D=document.createElement("script");D.src=h.url;if(h.scriptCharset){D.charset=h.scriptCharset}if(!A){var f=false;D.onload=D.onreadystatechange=function(){if(!f&&(!this.readyState||this.readyState=="loaded"||this.readyState=="complete")){f=true;l();i();D.onload=D.onreadystatechange=null;m.removeChild(D)}}}m.appendChild(D);return AB}var j=false;var k=h.xhr();if(h.username){k.open(o,h.url,h.async,h.username,h.password)}else{k.open(o,h.url,h.async)}try{if(h.data){k.setRequestHeader("Content-Type",h.contentType)}if(h.ifModified){k.setRequestHeader("If-Modified-Since",T.lastModified[h.url]||"Thu, 01 Jan 1970 00:00:00 GMT")}k.setRequestHeader("X-Requested-With","XMLHttpRequest");k.setRequestHeader("Accept",h.dataType&&h.accepts[h.dataType]?h.accepts[h.dataType]+", */*":h.accepts._default)}catch(a){}if(h.beforeSend&&h.beforeSend(k,h)===false){if(h.global&&!--T.active){T.event.trigger("ajaxStop")}k.abort();return false}if(h.global){T.event.trigger("ajaxSend",[k,h])}var g=function(t){if(k.readyState==0){if(e){clearInterval(e);e=null;if(h.global&&!--T.active){T.event.trigger("ajaxStop")}}}else{if(!j&&k&&(k.readyState==4||t=="timeout")){j=true;if(e){clearInterval(e);e=null}c=t=="timeout"?"timeout":!T.httpSuccess(k)?"error":h.ifModified&&T.httpNotModified(k,h.url)?"notmodified":"success";if(c=="success"){try{B=T.httpData(k,h.dataType,h)}catch(r){c="parsererror"}}if(c=="success"){var s;try{s=k.getResponseHeader("Last-Modified")}catch(r){}if(h.ifModified&&s){T.lastModified[h.url]=s}if(!A){l()}}else{T.handleError(h,k,c)}i();if(t){k.abort()}if(h.async){k=null}}}};if(h.async){var e=setInterval(g,13);if(h.timeout>0){setTimeout(function(){if(k&&!j){g("timeout")}},h.timeout)}}try{k.send(h.data)}catch(a){T.handleError(h,k,null,a)}if(!h.async){g()}function l(){if(h.success){h.success(B,c)}if(h.global){T.event.trigger("ajaxSuccess",[k,h])}}function i(){if(h.complete){h.complete(k,c)}if(h.global){T.event.trigger("ajaxComplete",[k,h])}if(h.global&&!--T.active){T.event.trigger("ajaxStop")}}return k},handleError:function(C,A,D,B){if(C.error){C.error(A,D,B)}if(C.global){T.event.trigger("ajaxError",[A,C,B])}},active:0,httpSuccess:function(A){try{return !A.status&&location.protocol=="file:"||(A.status>=200&&A.status<300)||A.status==304||A.status==1223}catch(B){}return false},httpNotModified:function(B,D){try{var A=B.getResponseHeader("Last-Modified");return B.status==304||A==T.lastModified[D]}catch(C){}return false},httpData:function(A,C,D){var a=A.getResponseHeader("content-type"),c=C=="xml"||!C&&a&&a.indexOf("xml")>=0,B=c?A.responseXML:A.responseText;if(c&&B.documentElement.tagName=="parsererror"){throw"parsererror"}if(D&&D.dataFilter){B=D.dataFilter(B,C)}if(typeof B==="string"){if(C=="script"){T.globalEval(B)}if(C=="json"){B=W["eval"]("("+B+")")}}return B},param:function(D){var B=[];function A(c,a){B[B.length]=encodeURIComponent(c)+"="+encodeURIComponent(a)}if(T.isArray(D)||D.jquery){T.each(D,function(){A(this.name,this.value)})}else{for(var C in D){if(T.isArray(D[C])){T.each(D[C],function(){A(C,this)})}else{A(C,T.isFunction(D[C])?D[C]():D[C])}}}return B.join("&").replace(/%20/g,"+")}});var V={},U,AE=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]];function K(B,C){var A={};T.each(AE.concat.apply([],AE.slice(0,C)),function(){A[this]=B});return A}T.fn.extend({show:function(C,A){if(C){return this.animate(K("show",3),C,A)}else{for(var a=0,d=this.length;a<d;a++){var e=T.data(this[a],"olddisplay");this[a].style.display=e||"";if(T.css(this[a],"display")==="none"){var c=this[a].tagName,B;if(V[c]){B=V[c]}else{var D=T("<"+c+" />").appendTo("body");B=D.css("display");if(B==="none"){B="block"}D.remove();V[c]=B}T.data(this[a],"olddisplay",B)}}for(var a=0,d=this.length;a<d;a++){this[a].style.display=T.data(this[a],"olddisplay")||""}return this}},hide:function(B,A){if(B){return this.animate(K("hide",3),B,A)}else{for(var C=0,D=this.length;C<D;C++){var a=T.data(this[C],"olddisplay");if(!a&&a!=="none"){T.data(this[C],"olddisplay",T.css(this[C],"display"))}}for(var C=0,D=this.length;C<D;C++){this[C].style.display="none"}return this}},_toggle:T.fn.toggle,toggle:function(A,B){var C=typeof A==="boolean";return T.isFunction(A)&&T.isFunction(B)?this._toggle.apply(this,arguments):A==null||C?this.each(function(){var D=C?A:T(this).is(":hidden");T(this)[D?"show":"hide"]()}):this.animate(K("toggle",3),A,B)},fadeTo:function(C,A,B){return this.animate({opacity:A},C,B)},animate:function(A,D,B,C){var a=T.speed(D,B,C);return this[a.queue===false?"each":"queue"](function(){var d=T.extend({},a),f,c=this.nodeType==1&&T(this).is(":hidden"),e=this;for(f in A){if(A[f]=="hide"&&c||A[f]=="show"&&!c){return d.complete.call(this)}if((f=="height"||f=="width")&&this.style){d.display=T.css(this,"display");d.overflow=this.style.overflow}}if(d.overflow!=null){this.style.overflow="hidden"}d.curAnim=T.extend({},A);T.each(A,function(l,h){var i=new T.fx(e,d,l);if(/toggle|show|hide/.test(h)){i[h=="toggle"?c?"show":"hide":h](A)}else{var j=h.toString().match(/^([+-]=)?([\d+-.]+)(.*)$/),g=i.cur(true)||0;if(j){var m=parseFloat(j[2]),k=j[3]||"px";if(k!="px"){e.style[l]=(m||1)+k;g=((m||1)/i.cur(true))*g;e.style[l]=g+k}if(j[1]){m=((j[1]=="-="?-1:1)*m)+g}i.custom(g,m,k)}else{i.custom(g,h,"")}}});return true})},stop:function(B,C){var A=T.timers;if(B){this.queue([])}this.each(function(){for(var D=A.length-1;D>=0;D--){if(A[D].elem==this){if(C){A[D](true)}A.splice(D,1)}}});if(!C){this.dequeue()}return this}});T.each({slideDown:K("show",1),slideUp:K("hide",1),slideToggle:K("toggle",1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"}},function(B,A){T.fn[B]=function(D,C){return this.animate(A,D,C)}});T.extend({speed:function(B,A,C){var D=typeof B==="object"?B:{complete:C||!C&&A||T.isFunction(B)&&B,duration:B,easing:C&&A||A&&!T.isFunction(A)&&A};D.duration=T.fx.off?0:typeof D.duration==="number"?D.duration:T.fx.speeds[D.duration]||T.fx.speeds._default;D.old=D.complete;D.complete=function(){if(D.queue!==false){T(this).dequeue()}if(T.isFunction(D.old)){D.old.call(this)}};return D},easing:{linear:function(B,A,D,C){return D+C*B},swing:function(B,A,D,C){return((-Math.cos(B*Math.PI)/2)+0.5)*C+D}},timers:[],fx:function(B,C,A){this.options=C;this.elem=B;this.prop=A;if(!C.orig){C.orig={}}}});T.fx.prototype={update:function(){if(this.options.step){this.options.step.call(this.elem,this.now,this)}(T.fx.step[this.prop]||T.fx.step._default)(this);if((this.prop=="height"||this.prop=="width")&&this.elem.style){this.elem.style.display="block"}},cur:function(A){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==null)){return this.elem[this.prop]}var B=parseFloat(T.css(this.elem,this.prop,A));return B&&B>-10000?B:parseFloat(T.curCSS(this.elem,this.prop))||0},custom:function(A,B,C){this.startTime=AD();this.start=A;this.end=B;this.unit=C||this.unit||"px";this.now=this.start;this.pos=this.state=0;var a=this;function D(c){return a.step(c)}D.elem=this.elem;if(D()&&T.timers.push(D)&&!U){U=setInterval(function(){var c=T.timers;for(var d=0;d<c.length;d++){if(!c[d]()){c.splice(d--,1)}}if(!c.length){clearInterval(U);U=AB}},13)}},show:function(){this.options.orig[this.prop]=T.attr(this.elem.style,this.prop);this.options.show=true;this.custom(this.prop=="width"||this.prop=="height"?1:0,this.cur());T(this.elem).show()},hide:function(){this.options.orig[this.prop]=T.attr(this.elem.style,this.prop);this.options.hide=true;this.custom(this.cur(),0)},step:function(C){var D=AD();if(C||D>=this.options.duration+this.startTime){this.now=this.end;this.pos=this.state=1;this.update();this.options.curAnim[this.prop]=true;var c=true;for(var a in this.options.curAnim){if(this.options.curAnim[a]!==true){c=false}}if(c){if(this.options.display!=null){this.elem.style.overflow=this.options.overflow;this.elem.style.display=this.options.display;if(T.css(this.elem,"display")=="none"){this.elem.style.display="block"}}if(this.options.hide){T(this.elem).hide()}if(this.options.hide||this.options.show){for(var B in this.options.curAnim){T.attr(this.elem.style,B,this.options.orig[B])}}this.options.complete.call(this.elem)}return false}else{var A=D-this.startTime;this.state=A/this.options.duration;this.pos=T.easing[this.options.easing||(T.easing.swing?"swing":"linear")](this.state,A,0,1,this.options.duration);this.now=this.start+((this.end-this.start)*this.pos);this.update()}return true}};T.extend(T.fx,{speeds:{slow:600,fast:200,_default:400},step:{opacity:function(A){T.attr(A.elem.style,"opacity",A.now)},_default:function(A){if(A.elem.style&&A.elem.style[A.prop]!=null){A.elem.style[A.prop]=A.now+A.unit}else{A.elem[A.prop]=A.now}}}});if(document.documentElement.getBoundingClientRect){T.fn.offset=function(){if(!this[0]){return{top:0,left:0}}if(this[0]===this[0].ownerDocument.body){return T.offset.bodyOffset(this[0])}var c=this[0].getBoundingClientRect(),C=this[0].ownerDocument,d=C.body,e=C.documentElement,A=e.clientTop||d.clientTop||0,B=e.clientLeft||d.clientLeft||0,D=c.top+(self.pageYOffset||T.boxModel&&e.scrollTop||d.scrollTop)-A,a=c.left+(self.pageXOffset||T.boxModel&&e.scrollLeft||d.scrollLeft)-B;return{top:D,left:a}}}else{T.fn.offset=function(){if(!this[0]){return{top:0,left:0}}if(this[0]===this[0].ownerDocument.body){return T.offset.bodyOffset(this[0])}T.offset.initialized||T.offset.initialize();var c=this[0],f=c.offsetParent,g=c,A=c.ownerDocument,C,e=A.documentElement,a=A.body,D=A.defaultView,h=D.getComputedStyle(c,null),B=c.offsetTop,d=c.offsetLeft;while((c=c.parentNode)&&c!==a&&c!==e){C=D.getComputedStyle(c,null);B-=c.scrollTop,d-=c.scrollLeft;if(c===f){B+=c.offsetTop,d+=c.offsetLeft;if(T.offset.doesNotAddBorder&&!(T.offset.doesAddBorderForTableAndCells&&/^t(able|d|h)$/i.test(c.tagName))){B+=parseInt(C.borderTopWidth,10)||0,d+=parseInt(C.borderLeftWidth,10)||0}g=f,f=c.offsetParent}if(T.offset.subtractsBorderForOverflowNotVisible&&C.overflow!=="visible"){B+=parseInt(C.borderTopWidth,10)||0,d+=parseInt(C.borderLeftWidth,10)||0}h=C}if(h.position==="relative"||h.position==="static"){B+=a.offsetTop,d+=a.offsetLeft}if(h.position==="fixed"){B+=Math.max(e.scrollTop,a.scrollTop),d+=Math.max(e.scrollLeft,a.scrollLeft)}return{top:B,left:d}}}T.offset={initialize:function(){if(this.initialized){return }var C=document.body,f=document.createElement("div"),d,e,A,c,B,g,a=C.style.marginTop,D='<div style="position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;"><div></div></div><table style="position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;" cellpadding="0" cellspacing="0"><tr><td></td></tr></table>';B={position:"absolute",top:0,left:0,margin:0,border:0,width:"1px",height:"1px",visibility:"hidden"};for(g in B){f.style[g]=B[g]}f.innerHTML=D;C.insertBefore(f,C.firstChild);d=f.firstChild,e=d.firstChild,c=d.nextSibling.firstChild.firstChild;this.doesNotAddBorder=(e.offsetTop!==5);this.doesAddBorderForTableAndCells=(c.offsetTop===5);d.style.overflow="hidden",d.style.position="relative";this.subtractsBorderForOverflowNotVisible=(e.offsetTop===-5);C.style.marginTop="1px";this.doesNotIncludeMarginInBodyOffset=(C.offsetTop===0);C.style.marginTop=a;C.removeChild(f);this.initialized=true},bodyOffset:function(C){T.offset.initialized||T.offset.initialize();var A=C.offsetTop,B=C.offsetLeft;if(T.offset.doesNotIncludeMarginInBodyOffset){A+=parseInt(T.curCSS(C,"marginTop",true),10)||0,B+=parseInt(T.curCSS(C,"marginLeft",true),10)||0}return{top:A,left:B}}};T.fn.extend({position:function(){var B=0,C=0,a;if(this[0]){var D=this.offsetParent(),A=this.offset(),c=/^body|html$/i.test(D[0].tagName)?{top:0,left:0}:D.offset();A.top-=Y(this,"marginTop");A.left-=Y(this,"marginLeft");c.top+=Y(D,"borderTopWidth");c.left+=Y(D,"borderLeftWidth");a={top:A.top-c.top,left:A.left-c.left}}return a},offsetParent:function(){var A=this[0].offsetParent||document.body;while(A&&(!/^body|html$/i.test(A.tagName)&&T.css(A,"position")=="static")){A=A.offsetParent}return T(A)}});T.each(["Left","Top"],function(B,C){var A="scroll"+C;T.fn[A]=function(D){if(!this[0]){return null}return D!==AB?this.each(function(){this==W||this==document?W.scrollTo(!B?D:T(W).scrollLeft(),B?D:T(W).scrollTop()):this[A]=D}):this[0]==W||this[0]==document?self[B?"pageYOffset":"pageXOffset"]||T.boxModel&&document.documentElement[A]||document.body[A]:this[0][A]}});T.each(["Height","Width"],function(B,D){var c=B?"Left":"Top",C=B?"Right":"Bottom",a=D.toLowerCase();T.fn["inner"+D]=function(){return this[0]?T.css(this[0],a,false,"padding"):null};T.fn["outer"+D]=function(d){return this[0]?T.css(this[0],a,false,d?"margin":"border"):null};var A=D.toLowerCase();T.fn[A]=function(d){return this[0]==W?document.compatMode=="CSS1Compat"&&document.documentElement["client"+D]||document.body["client"+D]:this[0]==document?Math.max(document.documentElement["client"+D],document.body["scroll"+D],document.documentElement["scroll"+D],document.body["offset"+D],document.documentElement["offset"+D]):d===AB?(this.length?T.css(this[0],A):null):this.css(A,typeof d==="string"?d:d+"px")}})})();var gPlatform=PLATFORM_WINDOWS;var gLatestVersionID=null;var gLatestAddonVersion=null;var gLatestAppVersion=null;var PLATFORM_OTHER=0;var PLATFORM_WINDOWS=1;var PLATFORM_LINUX=2;var PLATFORM_MACOSX=3;var PLATFORM_MAC=4;if(navigator.platform.indexOf("Win32")!=-1){gPlatform=PLATFORM_WINDOWS}else{if(navigator.platform.indexOf("Linux")!=-1){gPlatform=PLATFORM_LINUX}else{if(navigator.userAgent.indexOf("Mac OS X")!=-1){gPlatform=PLATFORM_MACOSX}else{if(navigator.userAgent.indexOf("MSIE 5.2")!=-1){gPlatform=PLATFORM_MACOSX}else{if(navigator.platform.indexOf("Mac")!=-1){gPlatform=PLATFORM_MAC}else{gPlatform=PLATFORM_OTHER}}}}}function getPlatformName(){if(gPlatform==PLATFORM_WINDOWS){return"Windows"}if(gPlatform==PLATFORM_LINUX){return"Linux"}if(gPlatform==PLATFORM_MACOSX){return"MacOSX"}return"Unknown"}function getInstallURL(A){var B=A.target;while(B&&!B.href){B=B.parentNode}return B&&B.href}function checkMatchUserAgentAppId(){var C=/(?:Firefox|Minefield|Shiretoko|GranParadiso|BonEcho|Iceweasel)/;var B=navigator.userAgent;var A=C.exec(B);if(A!=null&&APP_ID==1){return true}C=/(SeaMonkey|Iceape)/;B=navigator.userAgent;A=C.exec(B);if(A!=null&&APP_ID==59){return true}return false}function install(B,A,E,D){if(B.altKey||!window.InstallTrigger||!checkMatchUserAgentAppId()){return true}var C=getInstallURL(B);if(C){var F=new Array();F[A]={URL:C,IconURL:E,toString:function(){return this.URL}};if(D){F[A].Hash=D}InstallTrigger.install(F);return false}return true}function addEngine(A){if(window.external&&("AddSearchProvider" in window.external)){window.external.AddSearchProvider(A);return false}else{alert(error_opensearch_unsupported);return true}}function fixPlatformLinks(F,D){if(gPlatform==PLATFORM_OTHER){return true}var A=getPlatformName();var E=$("#install-"+F);var B=E.find("p.install-button");var C=B.not(".platform-ALL,.platform-"+A);C.hide();C.each(function(){var G=$(this).parents(".exp-loggedout, .exp-confirmed");if($(G).length){$(G).hide()}else{$(this).hide()}});if(B.length==C.length){E.find(".exp-loggedout").hide();E.append($('<p class="not-avail"></p>').append(sprintf(addOnNotAvailableForPlatform,D,A)))}return true}function installVersusDownloadCheck(G,F,B){var D=F;var E=/Mozilla.*(Firefox|Minefield|Shiretoko|GranParadiso|BonEcho|SeaMonkey|Iceweasel|Iceape)\/.*$/;var C=navigator.userAgent;var A=E.exec(C);if(!A||A.length<2||!checkMatchUserAgentAppId()){D=B}$("#"+G+" strong").text(D)}function addCompatibilityHints(D,K,Q,M,I,N){var A=/Mozilla.*(?:Firefox|Minefield|Shiretoko|GranParadiso|BonEcho|Iceweasel)\/([^\s]*).*$/;var O=navigator.userAgent;var R=A.exec(O);if(!R||R.length<2){return true}var B=$("#install-"+K);var G=R[1];var C=new VersionCompare();if(C.compareVersions(G,Q)<0){var P=true}else{if(C.compareVersions(G,M)>0){var P=false}else{if(gLatestVersionID==null){var L=B.find("p.install-button");if(L.find(".platform-ALL")||L.find(".platform-"+gPlatform)){gLatestVersionID=K;var J=B.prev().prev().prev();gLatestAddonVersion=J.clone();gLatestApplicationVersion=G}}return true}}if(N){return true}var E=B.find("p:visible a");if(E.length==0){return true}var F=B.clone();F.attr("id","orig-"+K);F.hide();B.after(F);$(E).each(function(){var S=$(this).parents(".exp-loggedout");if(S.length){$(S).find(".exp-confirm-install").hide();return }var T=document.createElement("div");T.setAttribute("class","exp-loggedout");B.wrapInner(T)});var H=E.attr("href");E.removeAttr("href");E.removeAttr("onClick");E.removeAttr("title");E.css("cursor","default");E.parent().css("float","none");E.attr("frozen","true");if(H.indexOf("downloads")>0){H=H.substring(0,H.indexOf("downloads"))}else{if(H.indexOf("addons")>0){H=H.substring(0,H.indexOf("addons"))}}H=H+"addons/versions/"+D;if(P&&I){E.parent().after(sprintf(app_compat_older_version_or_ignore_check,H,"removeCompatibilityHint("+K+");return false;"))}else{if(!P&&I){E.parent().after('<br /><a href="#" onclick="removeCompatibilityHint(\''+K+"');return false;\">"+app_compat_ignore_check+"</a>");E.parent().after(app_compat_older_firefox_only)}else{if(!P){E.parent().after(app_compat_older_firefox_only)}else{E.parent().after(sprintf(app_compat_try_old_version,H))}}}if(P){if(C.compareVersions(Q,LATEST_FIREFOX_DEVEL_VERSION)>=0){E.parent().after(sprintf("<strong>"+app_compat_unreleased_version+"</strong><br />","http://www.mozilla.com/"+LANG+"/firefox/all-beta.html#"+LANG,LATEST_FIREFOX_DEVEL_VERSION))}else{if(C.compareVersions(Q,LATEST_FIREFOX_VERSION)<0){E.parent().after(sprintf("<strong>"+app_compat_update_firefox+"</strong><br />","http://www.mozilla.com/"+LANG+"/firefox/all.html#"+LANG,LATEST_FIREFOX_VERSION))}}}return true}function removeCompatibilityHint(A){var B=$("#orig-"+A);B.prev().remove();B.attr("id","install-"+A);B.show();return true}function createLatestVersionElement(C,D){var A=$("#latest-version-container");A.wrapInner("<p>"+sprintf(C,D,gLatestApplicationVersion)+"</p>");A.append(gLatestAddonVersion);var E=$("#install-"+gLatestVersionID);var B=E.clone();B.attr("id","install-0"+gLatestVersionID);A.append(B);A.attr("id","latest-version");fixPlatformLinks("0"+gLatestVersionID,"")}function replaceOptions(C,B,A){$(C+" > *").remove();for(opt in B){sel_text="";val=B[opt];opt_obj=document.createElement("option");if(val==A){opt_obj.selected="selected"}opt_obj.value=val;opt_obj.appendChild(document.createTextNode(opt));$(C).append(opt_obj)}}function emailLink(F,D,E){var A=document.getElementById(F);var C=D+"@"+E;var B=document.createElement("a");B.setAttribute("href","mailto:"+C);B.appendChild(document.createTextNode(C));A.replaceChild(B,A.lastChild)}var translation_box={switchLocale:function(A,C){var B=$(A).parent().parent().parent();if(B.find(".translation-deletelocale").size()>0){return }B.find(".selected").removeClass("selected");$(A).addClass("selected");B.find("."+C).addClass("selected");this.checkDeleteButton(B);B.find(".translation-area .input.selected").trigger("onchange");B.find("."+C).focus()},checkDeleteButton:function(B){var C=B.find(".translation-area").attr("defaultLocale");var A=B.find(".translation-tab.selected").text();if(A==C||A==""){B.find(".translation-button.remove").hide()}else{B.find(".translation-button.remove").show()}},checkLength:function(C,A){var B=$(C).parent().parent();B.find(".translation-maxlength.selected span").text(C.value.length);if(C.value.length>A){B.find(".translation-maxlength.selected").addClass("over");B.addClass("errors")}else{B.find(".translation-maxlength.selected").removeClass("over");if(B.find(".translation-area .over").size()==0){B.removeClass("errors")}}},addTab:function(A){var C=$(A).parent().parent().parent();if(C.find(".translation-deletelocale").size()>0){return }if(C.find(".translation-tab").hasClass("new")){C.find(".selected").removeClass("selected");C.find(".new").addClass("selected");return }var B='<div class="translation-tab selected new" onclick="translation_box.switchLocale(this, \'new\');"></div>';C.find(".selected").removeClass("selected");C.find(".translation-tabs").append(B);C.find(".translation-area").append($(".translation-newlocale-container").html());C.find(".translation-tab:not(.new)").each(function(D,E){C.find('.translation-newlocale select option[value="'+$(E).text()+'"]').remove()});this.checkDeleteButton(C)},addLocale:function(C,E){var G=$(C).parent().parent().parent().parent().parent();var A=G;if(E==true){G=G.parent()}var F=A.find("select").val();var B=A.find("select option:selected").text();var D='<div class="translation-tab selected" title="'+B+'" onclick="translation_box.switchLocale(this, \''+F+"');\">"+F+"</div>";G.find(".input."+F+".deleted").remove();G.find(".translation-area:not(:has(."+F+"))").each(function(K,P){var M=$(P).attr("itemID");var N="data["+$(P).attr("table")+"]"+(M!=null?"["+M+"]":"")+"["+$(P).attr("field")+"]["+F+"]";$(P).parent().find(".selected").removeClass("selected");var J=$(P).find(".input")[0].tagName.toLowerCase();var I=$(P).find(".input").attr("style");if(J=="textarea"){var O='<textarea class="input '+F+' selected" name="'+N+'" style="'+I+'"';var L=$(P).find(".input").attr("maxLength");if(L){O+=' maxLength="'+L+'" onkeyup="translation_box.checkLength(this, '+L+');" onchange="translation_box.checkLength(this, '+L+');"';var H='<div class="translation-maxlength '+F+' selected">'+$(P).find(".translation-maxlength").html()+"</div>"}O+="></textarea>"}else{if(J=="input"){var O='<input type="text" class="input '+F+' selected" value="" name="'+N+'" style="'+I+'" />';var H=""}}$(P).append(O).append(H);G.find(".translation-area .input.selected").trigger("onchange");$(P).parent().find(".translation-tabs").append(D)});A.find(".new").remove();this.checkDeleteButton(G);A.find(".translation-area .selected").focus()},confirmRemove:function(A){var B=$(A).parent().parent().parent();if(B.find(".translation-deletelocale").size()>0){return }B.find(".translation-area .input.selected").hide();B.find(".translation-area .input:first").before($(".translation-deletelocale-container").html());B.find(".translation-deletelocale").css("width",B.css("width"))},removeLocale:function(A){var C=$(A).parent().parent().parent().parent().parent();var B=C.find(".translation-row .selected").text();C.find(".translation-tab:contains("+B+")").remove();C.find(".translation-area .input."+B).val("");C.find(".translation-area .input."+B).addClass("deleted");C.find(".translation-area .input."+B).removeClass("selected");C.find(".translation-maxlength."+B).remove();C.find(".translation-deletelocale").remove();C.find(".translation-area .input").removeClass("confirm-delete");var D=C.find(".translation-area").attr("defaultLocale");C.find(".translation-tab:contains("+D+")").addClass("selected");C.find(".translation-area ."+D).addClass("selected");this.checkDeleteButton(C)},cancelRemove:function(A){var B=$(A).parent().parent().parent().parent().parent();B.find(".translation-deletelocale").remove();B.find(".translation-area .input").removeClass("confirm-delete");B.find(".translation-area .input.selected").show();B.find(".translation-area .input.selected").focus()},cancelAdd:function(A){var B=$(A).parent().parent().parent().parent().parent();B.find(".translation-tabs .new").remove();B.find(".translation-newlocale").remove();var C=B.find(".translation-area").attr("defaultLocale");B.find(".translation-tab:contains("+C+")").addClass("selected");B.find(".translation-area ."+C).addClass("selected");this.checkDeleteButton(B)},showHelp:function(A){var B=$(A).parent().parent();if(B.prev(".translation-help").size()>0){return }B.before($(".translation-help-container").html());B.prev(".translation-help").slideDown("slow")},hideHelp:function(B){var A=$(B).parent().parent().parent().parent();A.slideUp("normal",function(){A.remove()})}};function sprintf(){if(!arguments||arguments.length<1||!RegExp){return null}var M=arguments[0];var L=/([^%]*)%((\d+)\$)?('.|0|\x20)?(-)?(\d+)?(\.\d+)?(%|b|c|d|u|f|o|s|x|X)(.*)/;var U=b=[],A=0,C=0;while((U=L.exec(M))){var K=U[1],F=U[3],R=U[4],I=U[5];var S=U[6],N=U[7],H=U[8];var D=U[9];C++;if(H=="%"){E="%"}else{if(F==""){A++;F=A}if(parseInt(F)>=arguments.length){alert("Error! Not enough function arguments ("+(arguments.length-1)+", excluding the string)\nfor the number of substitution parameters in string ("+A+" so far).")}var G=arguments[parseInt(F)];var T="";if(R&&R.substr(0,1)=="'"){T=K.substr(1,1)}else{if(R){T=R}}var P=true;if(I&&I==="-"){P=false}var J=-1;if(S){J=parseInt(S)}var O=-1;if(N&&H=="f"){O=parseInt(N.substring(1))}var E=G;switch(H){case"b":E=parseInt(G).toString(2);break;case"c":E=String.fromCharCode(parseInt(G));break;case"d":E=parseInt(G)?parseInt(G):0;break;case"u":E=Math.abs(G);break;case"f":E=(O>-1)?Math.round(parseFloat(G)*Math.pow(10,O))/Math.pow(10,O):parseFloat(G);break;case"o":E=parseInt(G).toString(8);break;case"s":E=G;break;case"x":E=(""+parseInt(G).toString(16)).toLowerCase();break;case"X":E=(""+parseInt(G).toString(16)).toUpperCase();break}var Q=J-E.toString().length;if(Q>0){var B=new Array(Q+1);var V=B.join(T?T:" ")}else{var V=""}}M=K+V+E+D}return M}if(jQuery){(function(A){A.fn.rating=function(C){C=A.extend({cancel:"",cancelValue:0,required:false,readOnly:false},C||{});var E=this;var F={};var D={fill:function(I,H,G){this.drain(I);A(H).prevAll(".star").andSelf().addClass(G||"star_hover")},drain:function(G){A(F[G].valueElem).siblings(".star").removeClass("star_on").removeClass("star_hover")},reset:function(G){if(!A(F[G].currentElem).is(".cancel")){A(F[G].currentElem).prevAll(".star").andSelf().addClass("star_on")}},click:function(I,G){F[I].currentElem=G;var H=A(G).children("a").text();A(F[I].valueElem).val(H);D.drain(I);D.reset(I);if(C.callback){C.callback.apply(F[I].valueElem,[H,G])}}};var B=A(this).find("input[type=radio]");A(this).empty();A(this).removeClass("degrade");B.each(function(G){var H=this.name;if(!F[H]){F[H]={count:0}}G=F[H].count;F[H].count++;if(G==0){C.readOnly=A(this).attr("disabled")||C.readOnly;F[H].valueElem=A('<input type="hidden" name="'+H+'" value=""'+(C.readOnly?' disabled="disabled"':"")+">");A(E).append(F[H].valueElem);if(C.readOnly||C.required){}else{}}eStar=A('<div class="star"><a title="'+(this.title||this.value)+'">'+this.value+"</a></div>");A(E).append(eStar);if(C.readOnly){A(eStar).addClass("star_readonly")}else{A(eStar).mouseover(function(){D.drain(H);D.fill(H,this)}).mouseout(function(){D.drain(H);D.reset(H)}).click(function(){D.click(H,this)})}if(this.checked){F[H].currentElem=eStar}if(G+1==this.length){D.reset(H)}});for(n in F){if(F[n].currentElem){D.fill(n,F[n].currentElem,"star_on");A(F[n].valueElem).val(A(F[n].currentElem).children("a").text())}}return this}})(jQuery)}function VersionCompare(){this.compareVersions=function(B,A){var G=B.split(".");var H=A.split(".");for(var D=0;D<G.length||D<H.length;D++){var C=(D<G.length?G[D]:null);var F=(D<H.length?H[D]:null);var E=this.compareVersionParts(C,F);if(E!=0){return E}}return 0};this.compareVersionParts=function(A,D){var E=this.parseVersionPart(A);var C=this.parseVersionPart(D);var B=this.cmp(E.numA,C.numA);if(B){return B}B=this.strcmp(E.strB,C.strB);if(B){return B}B=this.cmp(E.numC,C.numC);if(B){return B}return this.strcmp(E.extraD,C.extraD)};this.parseVersionPart=function(D){if(D=="*"){return{numA:Number.MAX_VALUE,strB:"",numC:0,extraD:""}}var B=/^([-\d]*)([^-\d]*)([-\d]*)(.*)$/;var A=B.exec(D);var C={numA:parseInt(A[1]),strB:A[2],numC:parseInt(A[3]),extraD:A[4]};if(C.strB=="+"){C.numA++;C.strB="pre"}return C};this.cmp=function(A,B){if(isNaN(A)){A=0}if(isNaN(B)){B=0}if(A<B){return -1}if(A>B){return 1}return 0};this.strcmp=function(A,B){if(A==B){return 0}if(A==""){return 1}if(B==""){return -1}if(A<B){return -1}else{if(A>B){return 1}else{return 0}}}}if(jQuery){(function(A){A.fn.slider=function(B){var C=arguments.callee.support;new C(this[0].id,B);return this};A.fn.slider.support=function(B,C){this.init(B,C)};A.fn.slider.support.prototype=function(){return{init:function(B,C){this.options=A.extend({duration:250,prev_img_src:"/img/slider-prev.gif",prev_disabled_img_src:"/img/slider-prev-disabled.gif",next_img_src:"/img/slider-next.gif",next_disabled_img_src:"/img/slider-next-disabled.gif"},C||{});this.slider_id=B;this.slider_sel="#"+B;this._resize_timer=null;var D=this;A(window).unload(function(){return D.onUnload()});A(window).resize(function(){return D.onResize()});A(document).ready(function(){return D.onReady()})},onReady:function(){this.items=A(this.slider_sel+" .item");this.item_idx=0;var B=this;A(this.slider_sel+" .controls .prev").click(function(C){return B.onClickPrev(C)});A(this.slider_sel+" .controls .next").click(function(C){return B.onClickNext(C)});this.onResize()},onUnload:function(){delete this.items},onResize:function(){var B=this;if(this._resize_timer){clearTimeout(this._resize_timer)}this._resize_timer=window.setTimeout(function(){B._doResize()},50)},_doResize:function(){var C=A(this.slider_sel);var B=C.select(".viewport")[0];A(this.slider_sel+" .addon").width(B.offsetWidth-260);this.revealSelectedItem(15)},onClickPrev:function(B){if((this.item_idx-1)<0){return false}this.item_idx--;return this.changeSelectedItem()},onClickNext:function(B){if((this.item_idx+1)>=this.items.length){return false}this.item_idx++;return this.changeSelectedItem()},changeSelectedItem:function(){this.updateItemNumber();this.updateButtonStates();this.revealSelectedItem();return false},updateItemNumber:function(){A(this.slider_sel+" .controls .index").text(this.item_idx+1)},updateButtonStates:function(){var B=A(this.slider_sel+" .controls .prev img")[0];if(this.item_idx==0){B.src=this.options.prev_disabled_img_src}else{B.src=this.options.prev_img_src}var C=A(this.slider_sel+" .controls .next img")[0];if(this.item_idx==this.items.length-1){C.src=this.options.next_disabled_img_src}else{C.src=this.options.next_img_src}},revealSelectedItem:function(B){if(!B){B=this.options.slide_duration}A(this.slider_sel+" .viewport").animate({scrollLeft:this.items[this.item_idx].offsetLeft},B)},EOF:null}}()})(jQuery)}if(jQuery){(function(A){A.fn.collection=function(B){B=A.extend({shoppingCart:false},B||{});var D=B.installUrl;A("input.want").change(function(){A("#done-"+A(this).attr("value")).slideToggle("fast");A(".installsubmit input").attr("disabled",(A("input.want:checked").length==0))});A("input.want:checked").each(function(){A("#done-"+A(this).attr("value")).show()});A(".installsubmit input").attr("disabled",(A("input.want:checked").length==0));var C=function(){A.post(D,A("input.want:checked").serialize(),function(F,E){A("#installdialog").html(F).jqmAddClose("#installdialog .installsubmit input.cancel").show()})};A("#installdialog").jqm({onShow:C,trigger:"#collectionform .installsubmit input,a.installlink",overlay:80});A(document).keypress(function(E){if(E.keyCode==27){A("#installdialog").jqmHide()}})}})(jQuery)}function confirmExpInstall(D){$(D).removeClass("exp-loggedout");$(D).addClass("exp-confirmed");var B=$(D).find(".install-button a");var A=$(B).attr("href");if(A&&A.match(/(policy|\.xml|\.xpi|\.jar)/)){if(A.match(/collection_id/)){A+="&confirmed"}else{A+="?confirmed"}$(B).attr("href",A)}var C=$(B).attr("engineURL");if(C&&C.match(/\.xml/)){if(C.match(/collection_id/)){C+="&confirmed"}else{C+="?confirmed"}$(B).attr("engineURL",C)}$(B).removeAttr("frozen")}function unconfirmExpInstall(D){$(D).removeClass("exp-confirmed");$(D).addClass("exp-loggedout");var B=$(D).find(".install-button a");var A=$(B).attr("href");if(A){A=A.replace(/\?confirmed/,"").replace(/&confirmed/,"");$(B).attr("href",A)}var C=$(B).attr("engineURL");if(C){C=C.replace(/\?confirmed/,"").replace(/&confirmed/,"");$(B).attr("engineURL",C)}$(B).attr("frozen","true")}$(document).ready(function(){$(".exp-confirm-install input").each(function(){var A=$(this).parents(".exp-loggedout, .exp-confirmed");if(this.checked){confirmExpInstall(A)}else{unconfirmExpInstall(A)}});$(".exp-confirm-install input").change(function(A){var B=$(this).parents(".exp-loggedout, .exp-confirmed");if(this.checked){confirmExpInstall(B)}else{unconfirmExpInstall(B)}})});function initExpConfirm(A){var B=$("#install-"+A);$(B).find(".exp-confirm-install").show();$(B).find(".exp-loggedout .install-button").show()}if(jQuery){(function(A){A.fn.rolloverReveal=function(C){var B=arguments.callee.support;A.each(this,function(){new B(this,C)});return this};A.fn.rolloverReveal.support=function(C,B){this.init(C,B)};A.fn.rolloverReveal.support.prototype=function(){var B={reveal_delay:250,dismiss_delay:1000,enable_rollover:true};return{timers:{},init:function(D,C){var E=this;this.options=A.extend({},B,C);this.root=A(D);this.to_reveal=this.root.find(".to-reveal");this.root.find(".activator").click(function(){E.toggle();return false}).mouseover(function(){if(!E.options.enable_rollover){return }E.schedule("reveal");E.cancel("dismiss")}).mouseout(function(){if(!E.options.enable_rollover){return }E.cancel("reveal");E.schedule("dismiss")}).end().find(".to-reveal").mouseover(function(){E.cancel("dismiss")}).mouseout(function(){E.schedule("dismiss")}).end().find(".to-reveal a").click(function(){E.dismiss();return true}).mouseover(function(){E.cancel("dismiss")}).mouseout(function(){E.schedule("dismiss")}).end()},reveal:function(){this.to_reveal.show().addClass("revealed")},revealStatus:function(){return this.to_reveal.hasClass("revealed")},dismiss:function(){this.to_reveal.hide().removeClass("revealed")},dismissStatus:function(){return !this.to_reveal.hasClass("revealed")},toggle:function(){return(this.revealStatus())?this.dismiss():this.reveal()},schedule:function(C){var D=this;if(this[C+"Status"]()){return }this.cancel(C);this.timers[C]=setTimeout(function(){D[C]()},this.options[C+"_delay"])},cancel:function(C){if(this.timers[C]){clearTimeout(this.timers[C])}},EOF:null}}()})(jQuery)}if(jQuery){(function(A){A.nl2br=function(B){return B.replace(/\n/g,"<br/>")};A.br2nl=function(B){return B.replace(RegExp("<brs*/?>","g"),"\n")}})(jQuery)}if(jQuery){(function(A){A.fn.delay=function(C,B){return this.each(function(){A(this).animate({opacity:1},C,B)})}})(jQuery)}if(jQuery){(function(A){A.fn.fadeRemove=function(){return this.each(function(){A(this).fadeOut("normal",function(){A(this).remove()})})}})(jQuery)}function urchinDownloadTrackingEvent(A){urchinTracker(A)}function installButtonAttachUrchin(A){if($(A).attr("isEULAPageLink")){return false}$(A).mousedown(function(B){if($(this).attr("frozen")=="true"){return false}urchinDownloadTrackingEvent($(this).attr("href"))})}function installButtonAttachInstallMethod(A){var B=$(A).attr("jsInstallMethod");$(A).click(function(C){if($(this).attr("frozen")=="true"){return false}if(B=="browser_app_addon_install"){return install(C,$(this).attr("addonName"),$(this).attr("addonIcon"),$(this).attr("addonHash"))}else{if(B=="search_engine_install"){return addEngine($(this).attr("engineURL"))}}})}$(document).ready(function(){$("p.install-button a").each(function(){installButtonAttachUrchin(this);installButtonAttachInstallMethod(this)})});function bandwagonRefreshEvent(){var A=document.createEvent("Events");A.initEvent("bandwagonRefresh",true,false);document.dispatchEvent(A)}var collections_edit={init:function(){$("#coll-edit .jsonly").show();this.tabs_init();this.nickname_init();this.icon_init();this.user_init();this.addon_init();this.addon_comment_init();$("#delete-coll").click(function(){$(this).hide();$("#delete-confirm").show()});$("#delete-coll-noscript").change(function(){if($(this).is(":checked")){$("#delete-warning").fadeIn();$("#submitbutton").val(collections_edit_submit_deletecollection)}else{$("#delete-warning").fadeOut();$("#submitbutton").val(collections_edit_submit)}});$("#saved_success").delay(10000,function(){$(this).fadeRemove()})},tabs_init:function(){$("#coll-edit > ul").tabs().bind("tabsselect",function(C,B,A){window.location.hash="#"+$(A.panel).attr("id")})},nickname_init:function(){this.nickname_old=$("#CollectionNickname").val();$("#nick-avail").click(this.nickname_check);$("#CollectionNickname").blur(this.nickname_check).keypress(function(A){if(A.which==KEYCODE_ENTER){collections_edit.nickname_check();A.preventDefault()}}).keyup(function(A){if(A.which!=KEYCODE_ENTER){collections_edit.nickname_checked=false;collections_edit.nickname_showButton()}})},nickname_check:function(){if(collections_edit.nickname_checked){return true}else{collections_edit.nickname_checked=true}var A=$.trim($("#CollectionNickname").val());$("#CollectionNickname").val(A);if(A==collections_edit.nickname_old){collections_edit.nickname_showLabel("available");return true}if(A.length>0){$("#CollectionNickname").siblings("img").show();$.getJSON(jsonURL+"/nickname",{nickname:A},function(B){$("#CollectionNickname").siblings("img").hide();$("#nick-avail").hide();if(B.nickname){$("#CollectionNickname").val(B.nickname)}if(B.error){var C=$('<span class="error">'+B.error_message+"</span>");C.insertAfter($("#CollectionNickname"));C.delay(3000,function(){$(this).fadeRemove();collections_edit.nickname_checked=false;collections_edit.nickname_showButton()});$("#CollectionNickname").select()}else{collections_edit.nickname_showLabel(B.taken?"taken":"available")}})}else{$("#nick-avail").hide().siblings("span").hide()}return true},nickname_showLabel:function(A){$("#nick-avail").hide().siblings("span").hide().filter("."+A).show()},nickname_showButton:function(){$("#nick-avail").siblings("span").hide();if($("#CollectionNickname").val().length>0){$("#nick-avail").show()}else{$("#nick-avail").hide()}},icon_init:function(){$("#icon_replace").click(this.icon_replace);$("#icon_remove").click(this.icon_delete);$("#icon>a.cancel").click(this.icon_reset);this.icon_reset()},icon_reset:function(){var A=$("#icon");if(A.children("img").length==0){return false}A.children("input:file,.toberemoved,.cancel").hide();A.children(".replaceremove").show();$("#IconDelete").remove();return false},icon_delete:function(){var A=$("#icon");if(A.children("img").length==0){return false}A.children("input:file,.replaceremove").hide();A.children(".cancel,.toberemoved").show();if($("#IconDelete").length==0){A.append('<input type="hidden" id="IconDelete" name="data[Icon][delete]" value="1"/>')}return false},icon_replace:function(){var A=$("#icon");if(A.children("img").length==0){return false}A.children("input:file,.cancel").show();A.children(".replaceremove,.toberemoved").hide();return false},addon_init:function(){$("#addonname").autocomplete(collURL+"/addonLookup",{minChars:2,max:0,formatItem:function(A){return'<img src="'+A[2]+'"/>&nbsp;'+A[0]},formatResult:function(A){return A[0]+" ["+A[1]+"]"},extraParams:{timestamp:null}});$("#addonname").keypress(function(A){if(A.which==KEYCODE_ENTER){$("#addon-add").click();return false}return true});$("#addon-add").click(function(){var A=/\[(\d+)\]/.exec($("#addonname").val());if(undefined==A||A.length!=2){return false}collections_edit.addon_add(A[1]);return true})},addon_show:function(E,B,L,G,C,J,F,I){var A=$('<div class="coll-addon" id="addon-'+E+'"/>');var K=$("#addon-new");var H=K.children("input:hidden").clone();H.val(E);A.append(H);var D=K.children("p").clone();D.find("img").attr("src",L);D.find(".name").text(B);D.find(".added").html(sprintf(D.find(".added").text(),G,C));A.append(D);if(F){A.append(K.children(".removeaddon").clone(true))}if(!I){$("#currentaddons").append(A)}else{$("#currentaddons #addon-new").after(A)}collections_edit.addon_comment_show(E,J,F);$("#currentaddons").show()},addon_add:function(A){$.post(jsonURL+"/addon/add",{sessionCheck:$("#collections>div.hsession>input[name=sessionCheck]").val(),collection_id:collection_id,addon_id:A},function(B){if(B.error){var C=$('<span class="error">'+B.error_message+"</span>");$("#addon-add").after(C);C.delay(2000,function(){$(this).fadeRemove()});$("#addonname").select()}else{collections_edit.addon_show(B.id,B.name,B.iconURL,B.date,B.publisher,"",1,1);$("#addonname").val("")}return true},"json")},addon_delete:function(){var A=$(this).parent().attr("id");var B=A.substr(A.lastIndexOf("-")+1);$.post(jsonURL+"/addon/del",{sessionCheck:$("#collections>div.hsession>input[name=sessionCheck]").val(),collection_id:collection_id,addon_id:B},function(C){if(C.error){alert(C.error_message)}else{$("#addon-"+C.id).fadeRemove();if($("#currentaddons").children("div:visible").length==0){$("#currentaddons").hide()}}return true},"json");return false},addon_comment_init:function(){var A=$("#addon-new");A.children("a.removeaddon").click(this.addon_delete);A.children("a.addlink").click(this.addon_comment_add);A.find("a.editlink").click(this.addon_comment_edit);A.find("a.deletelink").click(function(){var D=$(this).parent().parent();var C=D.attr("id");var B=C.substr(C.lastIndexOf("-")+1);collections_edit.addon_comment_save(B,"");return false});A.find(".editbox>input:button").click(function(){var E=$(this).siblings("textarea").val();var D=$(this).parent().parent();var C=D.attr("id");var B=C.substr(C.lastIndexOf("-")+1);collections_edit.addon_comment_save(B,E);return false})},addon_comment_show:function(C,E,B){var D=$("#addon-"+C);var A=$("#addon-new");if(E.length>0){D.append(A.children("blockquote").clone().html($.nl2br(E)));if(B){D.append(A.children(".editdelete").clone(true))}}else{if(B){D.append(A.children(".addlink").clone(true))}}},addon_comment_add:function(){var A=$("#addon-new>.editbox").clone(true);$(this).parent().append(A);$(this).remove();A.children("textarea").focus();return false},addon_comment_edit:function(){var B=$(this).parent().siblings("blockquote");var A=$("#addon-new>.editbox").clone(true);A.children("textarea").html($.br2nl(B.html()));$(this).parent().parent().append(A);$(this).parent().remove();B.remove();A.children("textarea").select();return false},addon_comment_save:function(A,B){$.post(jsonURL+"/addon/savecomment",{sessionCheck:$("#collections>div.hsession>input[name=sessionCheck]").val(),collection_id:collection_id,addon_id:A,comment:B},function(E){var C=/addon_id=(\d+)/.exec(this.data)[1];var D=$("#addon-"+C);if(E.error){var F=$('<div class="error">'+E.error_message+"</div>");D.append(F);F.delay(2000,function(){$(this).fadeRemove()})}else{D.children("blockquote,.addlink,.editdelete,.editbox").remove();collections_edit.addon_comment_show(C,E.comment,true)}return true},"json")},user_init:function(){$("#publishers>input:text,#managers>input:text").keypress(function(A){if(A.which==KEYCODE_ENTER){$(this).siblings("input:button").click();return false}return true});$("#publishers>input:button,#managers>input:button").click(collections_edit.user_check)},user_check:function(){var B=$(this).parent().attr("id");var A=$("#"+B+">:text").val();if(A.length==0){return }$(this).siblings("img").show();$.post(jsonURL+"/user/add",{sessionCheck:$("#collections>div.hsession>input[name=sessionCheck]").val(),collection_id:collection_id,role:B,email:A},function(C){var E=/role=(\w+)/.exec(this.data)[1];$("#"+E+">img").hide();if(C.error){var D=$('<li class="error">'+C.error_message+"</li>");$("#"+E+">ul").append(D);D.delay(2000,function(){$(this).fadeRemove()});$("#"+E+">input:text").select()}else{collections_edit.user_add(E,C.id,C.email);$("#"+E+">input:text").val("").focus()}return true},"json")},user_add:function(C,B,A){$("#"+C).siblings("input:radio[value=0]").attr("checked","checked");$("#"+C+">ul").append('<li><input type="hidden" name="'+C+'[]" value="'+B+'"/>'+A+' <a href="#" onclick="collections_edit.user_remove(this);return false;">Remove</a></li>')},user_remove:function(A){var B=$(A).siblings("input:hidden").val();$.post(jsonURL+"/user/del",{sessionCheck:$("#collections>div.hsession>input[name=sessionCheck]").val(),role:$(A).parent().parent().parent().attr("id"),collection_id:collection_id,user_id:B},function(C){var E=/role=(\w+)/.exec(this.data)[1];if(C.error){var D=$('<li class="error">'+C.error_message+"</li>");$("#"+E+">ul").append(D);D.delay(2000,function(){$(this).fadeRemove()});$("#"+E+">input:text").select()}else{$("#"+E+" input:hidden[value="+C.id+"]").parent().fadeRemove()}return true},"json")}};var addons_display={init:function(A){this.options=A;$(".stars").rating({readOnly:(!A.loggedIn)});$(".rollover-reveal").rolloverReveal({enable_rollover:false});$("#coll_publish input:submit").click(this.coll_publish)},coll_publish:function(){var B=$("#coll_publish option:selected").val();if(!B){return false}else{if(B=="new"){return true}}var A=$("#coll_publish input[name='data[addon_id]']").val();$.post(addons_display.options.jsonURL+"/addon/add",{sessionCheck:$("#coll_publish div.hsession>input[name=sessionCheck]").val(),collection_uuid:B,addon_id:A},function(D){if(D.error){var E=$('<div class="error">'+D.error_message+"</div>");$("#coll_publish>input:submit").after(E);E.delay(3000,function(){$(this).fadeRemove()})}else{var C=$("#coll_publish option:selected");var E=$("<div>"+sprintf(addons_display_collection_publish_success,D.name,'<a href="'+addons_display.options.collViewURL+C.val()+'">'+C.text()+"</a>")+"</div>");$("#coll_publish input:submit").after(E);E.delay(10000,function(){$(this).fadeRemove()});C.remove()}},"json");return false}}; \ No newline at end of file
diff --git a/site/app/webroot/js/jquery.autocomplete.pack.js b/site/app/webroot/js/jquery.autocomplete.pack.js
new file mode 100644
index 0000000..8fdd592
--- /dev/null
+++ b/site/app/webroot/js/jquery.autocomplete.pack.js
@@ -0,0 +1,13 @@
+/*
+ * Autocomplete - jQuery plugin 1.0.2
+ *
+ * Copyright (c) 2007 Dylan Verheul, Dan G. Switzer, Anjesh Tuladhar, Jörn Zaefferer
+ *
+ * Dual licensed under the MIT and GPL licenses:
+ * http://www.opensource.org/licenses/mit-license.php
+ * http://www.gnu.org/licenses/gpl.html
+ *
+ * Revision: $Id: jquery.autocomplete.js 5747 2008-06-25 18:30:55Z joern.zaefferer $
+ *
+ */
+eval(function(p,a,c,k,e,r){e=function(c){return(c<a?'':e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)r[e(c)]=k[c]||e(c);k=[function(e){return r[e]}];e=function(){return'\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}(';(3($){$.24.1m({12:3(b,c){5 d=S b=="1n";c=$.1m({},$.D.1E,{T:d?b:14,w:d?14:b,1o:d?$.D.1E.1o:10,U:c&&!c.1p?10:35},c);c.1q=c.1q||3(a){6 a};c.1r=c.1r||c.1F;6 H.K(3(){1G $.D(H,c)})},M:3(a){6 H.V("M",a)},1s:3(a){6 H.15("1s",[a])},1H:3(){6 H.15("1H")},1I:3(a){6 H.15("1I",[a])},1J:3(){6 H.15("1J")}});$.D=3(h,j){5 k={26:38,28:40,29:46,2a:9,2b:13,2c:27,2d:36,2e:33,2f:34,2g:8};5 l=$(h).37("12","39").N(j.2h);5 m;5 n="";5 o=$.D.2i(j);5 p=0;5 r;5 s={1t:B};5 t=$.D.2j(j,h,1K,s);5 u;$.1L.2k&&$(h.2l).V("3a.12",3(){4(u){u=B;6 B}});l.V(($.1L.2k?"3b":"3c")+".12",3(a){r=a.2m;3d(a.2m){O k.26:a.18();4(t.L()){t.2n()}A{W(0,C)}P;O k.28:a.18();4(t.L()){t.2o()}A{W(0,C)}P;O k.2e:a.18();4(t.L()){t.2p()}A{W(0,C)}P;O k.2f:a.18();4(t.L()){t.2q()}A{W(0,C)}P;O j.19&&$.1u(j.Q)==","&&k.2d:O k.2a:O k.2b:4(1K()){a.18();u=C;6 B}P;O k.2c:t.X();P;3e:1M(m);m=1N(W,j.1o);P}}).1O(3(){p++}).3f(3(){p=0;4(!s.1t){2r()}}).2s(3(){4(p++>1&&!t.L()){W(0,C)}}).V("1s",3(){5 c=(1v.7>1)?1v[1]:14;3 1P(q,a){5 b;4(a&&a.7){16(5 i=0;i<a.7;i++){4(a[i].M.R()==q.R()){b=a[i];P}}}4(S c=="3")c(b);A l.15("M",b&&[b.w,b.I])}$.K(1a(l.J()),3(i,a){1Q(a,1P,1P)})}).V("1H",3(){o.1b()}).V("1I",3(){$.1m(j,1v[1]);4("w"2t 1v[1])o.1c()}).V("1J",3(){t.1w();l.1w();$(h.2l).1w(".12")});3 1K(){5 a=t.2u();4(!a)6 B;5 v=a.M;n=v;4(j.19){5 b=1a(l.J());4(b.7>1){v=b.17(0,b.7-1).2v(j.Q)+j.Q+v}v+=j.Q}l.J(v);1d();l.15("M",[a.w,a.I]);6 C}3 W(a,b){4(r==k.29){t.X();6}5 c=l.J();4(!b&&c==n)6;n=c;c=1e(c);4(c.7>=j.1R){l.N(j.1S);4(!j.1x)c=c.R();1Q(c,2w,1d)}A{1y();t.X()}};3 1a(b){4(!b){6[""]}5 c=b.1T(j.Q);5 d=[];$.K(c,3(i,a){4($.1u(a))d[i]=$.1u(a)});6 d}3 1e(a){4(!j.19)6 a;5 b=1a(a);6 b[b.7-1]}3 1z(q,a){4(j.1z&&(1e(l.J()).R()==q.R())&&r!=k.2g){l.J(l.J()+a.3g(1e(n).7));$.D.1U(h,n.7,n.7+a.7)}};3 2r(){1M(m);m=1N(1d,3h)};3 1d(){5 c=t.L();t.X();1M(m);1y();4(j.2x){l.1s(3(a){4(!a){4(j.19){5 b=1a(l.J()).17(0,-1);l.J(b.2v(j.Q)+(b.7?j.Q:""))}A l.J("")}})}4(c)$.D.1U(h,h.I.7,h.I.7)};3 2w(q,a){4(a&&a.7&&p){1y();t.2y(a,q);1z(q,a[0].I);t.1V()}A{1d()}};3 1Q(c,d,e){4(!j.1x)c=c.R();5 f=o.2z(c);4(f&&f.7){d(c,f)}A 4((S j.T=="1n")&&(j.T.7>0)){5 g={3i:+1G 3j()};$.K(j.2A,3(a,b){g[a]=S b=="3"?b():b});$.3k({3l:"3m",3n:"12"+h.3o,2B:j.2B,T:j.T,w:$.1m({q:1e(c),3p:j.U},g),3q:3(a){5 b=j.1A&&j.1A(a)||1A(a);o.1f(c,b);d(c,b)}})}A{t.2C();e(c)}};3 1A(a){5 b=[];5 c=a.1T("\\n");16(5 i=0;i<c.7;i++){5 d=$.1u(c[i]);4(d){d=d.1T("|");b[b.7]={w:d,I:d[0],M:j.1B&&j.1B(d,d[0])||d[0]}}}6 b};3 1y(){l.1g(j.1S)}};$.D.1E={2h:"3r",2D:"3s",1S:"3t",1R:1,1o:3u,1x:B,1h:C,1W:B,1i:10,U:3v,2x:B,2A:{},1X:C,1F:3(a){6 a[0]},1r:14,1z:B,E:0,19:B,Q:", ",1q:3(a,b){6 a.2E(1G 3w("(?![^&;]+;)(?!<[^<>]*)("+b.2E(/([\\^\\$\\(\\)\\[\\]\\{\\}\\*\\.\\+\\?\\|\\\\])/2F,"\\\\$1")+")(?![^<>]*>)(?![^&;]+;)","2F"),"<2G>$1</2G>")},1p:C,1C:3x};$.D.2i=3(g){5 h={};5 j=0;3 1h(s,a){4(!g.1x)s=s.R();5 i=s.3y(a);4(i==-1)6 B;6 i==0||g.1W};3 1f(q,a){4(j>g.1i){1b()}4(!h[q]){j++}h[q]=a}3 1c(){4(!g.w)6 B;5 b={},2H=0;4(!g.T)g.1i=1;b[""]=[];16(5 i=0,2I=g.w.7;i<2I;i++){5 c=g.w[i];c=(S c=="1n")?[c]:c;5 d=g.1r(c,i+1,g.w.7);4(d===B)1Y;5 e=d.3z(0).R();4(!b[e])b[e]=[];5 f={I:d,w:c,M:g.1B&&g.1B(c)||d};b[e].1Z(f);4(2H++<g.U){b[""].1Z(f)}};$.K(b,3(i,a){g.1i++;1f(i,a)})}1N(1c,25);3 1b(){h={};j=0}6{1b:1b,1f:1f,1c:1c,2z:3(q){4(!g.1i||!j)6 14;4(!g.T&&g.1W){5 a=[];16(5 k 2t h){4(k.7>0){5 c=h[k];$.K(c,3(i,x){4(1h(x.I,q)){a.1Z(x)}})}}6 a}A 4(h[q]){6 h[q]}A 4(g.1h){16(5 i=q.7-1;i>=g.1R;i--){5 c=h[q.3A(0,i)];4(c){5 a=[];$.K(c,3(i,x){4(1h(x.I,q)){a[a.7]=x}});6 a}}}6 14}}};$.D.2j=3(e,f,g,h){5 j={F:"3B"};5 k,y=-1,w,1D="",20=C,G,z;3 2J(){4(!20)6;G=$("<3C/>").X().N(e.2D).Y("3D","3E").21(2K.2L);z=$("<3F/>").21(G).3G(3(a){4(Z(a).2M&&Z(a).2M.3H()==\'2N\'){y=$("22",z).1g(j.F).3I(Z(a));$(Z(a)).N(j.F)}}).2s(3(a){$(Z(a)).N(j.F);g();f.1O();6 B}).3J(3(){h.1t=C}).3K(3(){h.1t=B});4(e.E>0)G.Y("E",e.E);20=B}3 Z(a){5 b=a.Z;3L(b&&b.3M!="2N")b=b.3N;4(!b)6[];6 b}3 11(a){k.17(y,y+1).1g(j.F);2O(a);5 b=k.17(y,y+1).N(j.F);4(e.1p){5 c=0;k.17(0,y).K(3(){c+=H.1j});4((c+b[0].1j-z.1k())>z[0].3O){z.1k(c+b[0].1j-z.3P())}A 4(c<z.1k()){z.1k(c)}}};3 2O(a){y+=a;4(y<0){y=k.1l()-1}A 4(y>=k.1l()){y=0}}3 2P(a){6 e.U&&e.U<a?e.U:a}3 2Q(){z.2R();5 a=2P(w.7);16(5 i=0;i<a;i++){4(!w[i])1Y;5 b=e.1F(w[i].w,i+1,a,w[i].I,1D);4(b===B)1Y;5 c=$("<22/>").3Q(e.1q(b,1D)).N(i%2==0?"3R":"3S").21(z)[0];$.w(c,"2S",w[i])}k=z.3T("22");4(e.1X){k.17(0,1).N(j.F);y=0}4($.24.2T)z.2T()}6{2y:3(d,q){2J();w=d;1D=q;2Q()},2o:3(){11(1)},2n:3(){11(-1)},2p:3(){4(y!=0&&y-8<0){11(-y)}A{11(-8)}},2q:3(){4(y!=k.1l()-1&&y+8>k.1l()){11(k.1l()-1-y)}A{11(8)}},X:3(){G&&G.X();k&&k.1g(j.F);y=-1},L:3(){6 G&&G.3U(":L")},3V:3(){6 H.L()&&(k.2U("."+j.F)[0]||e.1X&&k[0])},1V:3(){5 a=$(f).3W();G.Y({E:S e.E=="1n"||e.E>0?e.E:$(f).E(),2V:a.2V+f.1j,23:a.23}).1V();4(e.1p){z.1k(0);z.Y({2W:e.1C});4($.1L.3X&&S 2K.2L.3Y.2W==="3Z"){5 b=0;k.K(3(){b+=H.1j});5 c=b>e.1C;z.Y(\'41\',c?e.1C:b);4(!c){k.E(z.E()-2X(k.Y("2Y-23"))-2X(k.Y("2Y-42")))}}}},2u:3(){5 a=k&&k.2U("."+j.F).1g(j.F);6 a&&a.7&&$.w(a[0],"2S")},2C:3(){z&&z.2R()},1w:3(){G&&G.43()}}};$.D.1U=3(a,b,c){4(a.2Z){5 d=a.2Z();d.44(C);d.45("30",b);d.47("30",c);d.48()}A 4(a.31){a.31(b,c)}A{4(a.32){a.32=b;a.49=c}}a.1O()}})(4a);',62,259,'|||function|if|var|return|length|||||||||||||||||||||||||data||active|list|else|false|true|Autocompleter|width|ACTIVE|element|this|value|val|each|visible|result|addClass|case|break|multipleSeparator|toLowerCase|typeof|url|max|bind|onChange|hide|css|target||moveSelect|autocomplete||null|trigger|for|slice|preventDefault|multiple|trimWords|flush|populate|hideResultsNow|lastWord|add|removeClass|matchSubset|cacheLength|offsetHeight|scrollTop|size|extend|string|delay|scroll|highlight|formatMatch|search|mouseDownOnSelect|trim|arguments|unbind|matchCase|stopLoading|autoFill|parse|formatResult|scrollHeight|term|defaults|formatItem|new|flushCache|setOptions|unautocomplete|selectCurrent|browser|clearTimeout|setTimeout|focus|findValueCallback|request|minChars|loadingClass|split|Selection|show|matchContains|selectFirst|continue|push|needsInit|appendTo|li|left|fn||UP||DOWN|DEL|TAB|RETURN|ESC|COMMA|PAGEUP|PAGEDOWN|BACKSPACE|inputClass|Cache|Select|opera|form|keyCode|prev|next|pageUp|pageDown|hideResults|click|in|selected|join|receiveData|mustMatch|display|load|extraParams|dataType|emptyList|resultsClass|replace|gi|strong|nullData|ol|init|document|body|nodeName|LI|movePosition|limitNumberOfItems|fillList|empty|ac_data|bgiframe|filter|top|maxHeight|parseInt|padding|createTextRange|character|setSelectionRange|selectionStart|||150|188|attr||off|submit|keypress|keydown|switch|default|blur|substring|200|timestamp|Date|ajax|mode|abort|port|name|limit|success|ac_input|ac_results|ac_loading|400|100|RegExp|180|indexOf|charAt|substr|ac_over|div|position|absolute|ul|mouseover|toUpperCase|index|mousedown|mouseup|while|tagName|parentNode|clientHeight|innerHeight|html|ac_even|ac_odd|find|is|current|offset|msie|style|undefined||height|right|remove|collapse|moveStart||moveEnd|select|selectionEnd|jQuery'.split('|'),0,{}))
diff --git a/site/app/webroot/js/jquery.cookie.js b/site/app/webroot/js/jquery.cookie.js
new file mode 100644
index 0000000..6df1fac
--- /dev/null
+++ b/site/app/webroot/js/jquery.cookie.js
@@ -0,0 +1,96 @@
+/**
+ * Cookie plugin
+ *
+ * Copyright (c) 2006 Klaus Hartl (stilbuero.de)
+ * Dual licensed under the MIT and GPL licenses:
+ * http://www.opensource.org/licenses/mit-license.php
+ * http://www.gnu.org/licenses/gpl.html
+ *
+ */
+
+/**
+ * Create a cookie with the given name and value and other optional parameters.
+ *
+ * @example $.cookie('the_cookie', 'the_value');
+ * @desc Set the value of a cookie.
+ * @example $.cookie('the_cookie', 'the_value', { expires: 7, path: '/', domain: 'jquery.com', secure: true });
+ * @desc Create a cookie with all available options.
+ * @example $.cookie('the_cookie', 'the_value');
+ * @desc Create a session cookie.
+ * @example $.cookie('the_cookie', null);
+ * @desc Delete a cookie by passing null as value. Keep in mind that you have to use the same path and domain
+ * used when the cookie was set.
+ *
+ * @param String name The name of the cookie.
+ * @param String value The value of the cookie.
+ * @param Object options An object literal containing key/value pairs to provide optional cookie attributes.
+ * @option Number|Date expires Either an integer specifying the expiration date from now on in days or a Date object.
+ * If a negative value is specified (e.g. a date in the past), the cookie will be deleted.
+ * If set to null or omitted, the cookie will be a session cookie and will not be retained
+ * when the the browser exits.
+ * @option String path The value of the path atribute of the cookie (default: path of page that created the cookie).
+ * @option String domain The value of the domain attribute of the cookie (default: domain of page that created the cookie).
+ * @option Boolean secure If true, the secure attribute of the cookie will be set and the cookie transmission will
+ * require a secure protocol (like HTTPS).
+ * @type undefined
+ *
+ * @name $.cookie
+ * @cat Plugins/Cookie
+ * @author Klaus Hartl/klaus.hartl@stilbuero.de
+ */
+
+/**
+ * Get the value of a cookie with the given name.
+ *
+ * @example $.cookie('the_cookie');
+ * @desc Get the value of a cookie.
+ *
+ * @param String name The name of the cookie.
+ * @return The value of the cookie.
+ * @type String
+ *
+ * @name $.cookie
+ * @cat Plugins/Cookie
+ * @author Klaus Hartl/klaus.hartl@stilbuero.de
+ */
+jQuery.cookie = function(name, value, options) {
+ if (typeof value != 'undefined') { // name and value given, set cookie
+ options = options || {};
+ if (value === null) {
+ value = '';
+ options.expires = -1;
+ }
+ var expires = '';
+ if (options.expires && (typeof options.expires == 'number' || options.expires.toUTCString)) {
+ var date;
+ if (typeof options.expires == 'number') {
+ date = new Date();
+ date.setTime(date.getTime() + (options.expires * 24 * 60 * 60 * 1000));
+ } else {
+ date = options.expires;
+ }
+ expires = '; expires=' + date.toUTCString(); // use expires attribute, max-age is not supported by IE
+ }
+ // CAUTION: Needed to parenthesize options.path and options.domain
+ // in the following expressions, otherwise they evaluate to undefined
+ // in the packed version for some reason...
+ var path = options.path ? '; path=' + (options.path) : '';
+ var domain = options.domain ? '; domain=' + (options.domain) : '';
+ var secure = options.secure ? '; secure' : '';
+ document.cookie = [name, '=', encodeURIComponent(value), expires, path, domain, secure].join('');
+ } else { // only name given, get cookie
+ var cookieValue = null;
+ if (document.cookie && document.cookie != '') {
+ var cookies = document.cookie.split(';');
+ for (var i = 0; i < cookies.length; i++) {
+ var cookie = jQuery.trim(cookies[i]);
+ // Does this cookie string begin with the name we want?
+ if (cookie.substring(0, name.length + 1) == (name + '=')) {
+ cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
+ break;
+ }
+ }
+ }
+ return cookieValue;
+ }
+}; \ No newline at end of file
diff --git a/site/app/webroot/js/jquery.flot.js b/site/app/webroot/js/jquery.flot.js
new file mode 100644
index 0000000..9a6a4c2
--- /dev/null
+++ b/site/app/webroot/js/jquery.flot.js
@@ -0,0 +1,2380 @@
+/* Javascript plotting library for jQuery, v. 0.5.
+ * r159 of http://flot.googlecode.com/svn/trunk/
+ *
+ * Released under the MIT license by IOLA, December 2007.
+ *
+ */
+
+(function($) {
+ function Plot(target, data_, options_, plugins) {
+ // data is on the form:
+ // [ series1, series2 ... ]
+ // where series is either just the data as [ [x1, y1], [x2, y2], ... ]
+ // or { data: [ [x1, y1], [x2, y2], ... ], label: "some label", ... }
+
+ var series = [],
+ options = {
+ // the color theme used for graphs
+ colors: ["#edc240", "#afd8f8", "#cb4b4b", "#4da74d", "#9440ed"],
+ legend: {
+ show: true,
+ noColumns: 1, // number of colums in legend table
+ labelFormatter: null, // fn: string -> string
+ labelBoxBorderColor: "#ccc", // border color for the little label boxes
+ container: null, // container (as jQuery object) to put legend in, null means default on top of graph
+ position: "ne", // position of default legend container within plot
+ margin: 5, // distance from grid edge to default legend container within plot
+ backgroundColor: null, // null means auto-detect
+ backgroundOpacity: 0.85 // set to 0 to avoid background
+ },
+ xaxis: {
+ mode: null, // null or "time"
+ min: null, // min. value to show, null means set automatically
+ max: null, // max. value to show, null means set automatically
+ autoscaleMargin: null, // margin in % to add if auto-setting min/max
+ ticks: null, // either [1, 3] or [[1, "a"], 3] or (fn: axis info -> ticks) or app. number of ticks for auto-ticks
+ tickFormatter: null, // fn: number -> string
+ labelWidth: null, // size of tick labels in pixels
+ labelHeight: null,
+
+ // mode specific options
+ tickDecimals: null, // no. of decimals, null means auto
+ tickSize: null, // number or [number, "unit"]
+ minTickSize: null, // number or [number, "unit"]
+ monthNames: null, // list of names of months
+ timeformat: null // format string to use
+ },
+ yaxis: {
+ autoscaleMargin: 0.02
+ },
+ x2axis: {
+ autoscaleMargin: null
+ },
+ y2axis: {
+ autoscaleMargin: 0.02
+ },
+ series: {
+ points: {
+ show: false,
+ radius: 3,
+ lineWidth: 2, // in pixels
+ fill: true,
+ fillColor: "#ffffff"
+ },
+ lines: {
+ // we don't put in show: false so we can see
+ // whether lines were actively disabled
+ lineWidth: 2, // in pixels
+ fill: false,
+ fillColor: null,
+ steps: false
+ },
+ bars: {
+ show: false,
+ lineWidth: 2, // in pixels
+ barWidth: 1, // in units of the x axis
+ fill: true,
+ fillColor: null,
+ align: "left", // or "center"
+ horizontal: false // when horizontal, left is now top
+ },
+ shadowSize: 3
+ },
+ grid: {
+ color: "#545454", // primary color used for outline and labels
+ backgroundColor: null, // null for transparent, else color
+ tickColor: "#dddddd", // color used for the ticks
+ labelMargin: 5, // in pixels
+ borderWidth: 2, // in pixels
+ borderColor: null, // set if different from the grid color
+ markings: null, // array of ranges or fn: axes -> array of ranges
+ markingsColor: "#f4f4f4",
+ markingsLineWidth: 2,
+ // interactive stuff
+ clickable: false,
+ hoverable: false,
+ autoHighlight: true, // highlight in case mouse is near
+ mouseActiveRadius: 10 // how far the mouse can be away to activate an item
+ },
+ selection: {
+ mode: null, // one of null, "x", "y" or "xy"
+ color: "#e8cfac"
+ }
+ },
+ canvas = null, // the canvas for the plot itself
+ overlay = null, // canvas for interactive stuff on top of plot
+ eventHolder = null, // jQuery object that events should be bound to
+ ctx = null, octx = null,
+ axes = { xaxis: {}, yaxis: {}, x2axis: {}, y2axis: {} },
+ plotOffset = { left: 0, right: 0, top: 0, bottom: 0},
+ canvasWidth = 0, canvasHeight = 0,
+ plotWidth = 0, plotHeight = 0,
+ hooks = {
+ processOptions: [],
+ processRawData: [],
+ processDatapoints: [],
+ bindEvents: [],
+ drawOverlay: []
+ },
+ plot = this,
+ // dedicated to storing data for buggy standard compliance cases
+ workarounds = {};
+
+ // public functions
+ plot.setData = setData;
+ plot.setupGrid = setupGrid;
+ plot.draw = draw;
+ plot.clearSelection = clearSelection;
+ plot.setSelection = setSelection;
+ plot.getSelection = getSelection;
+ plot.getCanvas = function() { return canvas; };
+ plot.getPlotOffset = function() { return plotOffset; };
+ plot.width = function () { return plotWidth; }
+ plot.height = function () { return plotHeight; }
+ plot.offset = function () {
+ var o = eventHolder.offset();
+ o.left += plotOffset.left;
+ o.top += plotOffset.top;
+ return o;
+ };
+ plot.getData = function() { return series; };
+ plot.getAxes = function() { return axes; };
+ plot.getOptions = function() { return options; };
+ plot.highlight = highlight;
+ plot.unhighlight = unhighlight;
+ plot.triggerRedrawOverlay = triggerRedrawOverlay;
+
+ // public attributes
+ plot.hooks = hooks;
+
+ // initialize
+ initPlugins(plot);
+ parseOptions(options_);
+ constructCanvas();
+ setData(data_);
+ setupGrid();
+ draw();
+ bindEvents();
+
+
+ function executeHooks(hook, args) {
+ args = [plot].concat(args);
+ for (var i = 0; i < hook.length; ++i)
+ hook[i].apply(this, args);
+ }
+
+ function initPlugins() {
+ for (var i = 0; i < plugins.length; ++i) {
+ var p = plugins[i];
+ p.init(plot);
+ if (p.options)
+ $.extend(true, options, p.options);
+ }
+ }
+
+ function parseOptions(opts) {
+ $.extend(true, options, opts);
+ if (options.grid.borderColor == null)
+ options.grid.borderColor = options.grid.color
+ // backwards compatibility, to be removed in future
+ if (options.xaxis.noTicks && options.xaxis.ticks == null)
+ options.xaxis.ticks = options.xaxis.noTicks;
+ if (options.yaxis.noTicks && options.yaxis.ticks == null)
+ options.yaxis.ticks = options.yaxis.noTicks;
+ if (options.grid.coloredAreas)
+ options.grid.markings = options.grid.coloredAreas;
+ if (options.grid.coloredAreasColor)
+ options.grid.markingsColor = options.grid.coloredAreasColor;
+ if (options.lines)
+ $.extend(true, options.series.lines, options.lines);
+ if (options.points)
+ $.extend(true, options.series.points, options.points);
+ if (options.bars)
+ $.extend(true, options.series.bars, options.bars);
+ if (options.shadowSize)
+ options.series.shadowSize = options.shadowSize;
+
+ executeHooks(hooks.processOptions, [options]);
+ }
+
+ function setData(d) {
+ series = parseData(d);
+ fillInSeriesOptions();
+ processData();
+ }
+
+ function parseData(d) {
+ var res = [];
+ for (var i = 0; i < d.length; ++i) {
+ var s = $.extend(true, {}, options.series);
+
+ if (d[i].data) {
+ s.data = d[i].data; // move the data instead of deep-copy
+ delete d[i].data;
+
+ $.extend(true, s, d[i]);
+
+ d[i].data = s.data;
+ }
+ else
+ s.data = d[i];
+ res.push(s);
+ }
+
+ return res;
+ }
+
+ function fillInSeriesOptions() {
+ var i;
+
+ // collect what we already got of colors
+ var neededColors = series.length,
+ usedColors = [],
+ assignedColors = [];
+ for (i = 0; i < series.length; ++i) {
+ var sc = series[i].color;
+ if (sc != null) {
+ --neededColors;
+ if (typeof sc == "number")
+ assignedColors.push(sc);
+ else
+ usedColors.push(parseColor(series[i].color));
+ }
+ }
+
+ // we might need to generate more colors if higher indices
+ // are assigned
+ for (i = 0; i < assignedColors.length; ++i) {
+ neededColors = Math.max(neededColors, assignedColors[i] + 1);
+ }
+
+ // produce colors as needed
+ var colors = [], variation = 0;
+ i = 0;
+ while (colors.length < neededColors) {
+ var c;
+ if (options.colors.length == i) // check degenerate case
+ c = new Color(100, 100, 100);
+ else
+ c = parseColor(options.colors[i]);
+
+ // vary color if needed
+ var sign = variation % 2 == 1 ? -1 : 1;
+ var factor = 1 + sign * Math.ceil(variation / 2) * 0.2;
+ c.scale(factor, factor, factor);
+
+ // FIXME: if we're getting to close to something else,
+ // we should probably skip this one
+ colors.push(c);
+
+ ++i;
+ if (i >= options.colors.length) {
+ i = 0;
+ ++variation;
+ }
+ }
+
+ // fill in the options
+ var colori = 0, s;
+ for (i = 0; i < series.length; ++i) {
+ s = series[i];
+
+ // assign colors
+ if (s.color == null) {
+ s.color = colors[colori].toString();
+ ++colori;
+ }
+ else if (typeof s.color == "number")
+ s.color = colors[s.color].toString();
+
+ // turn on lines automatically in case nothing is set
+ if (s.lines.show == null && !s.bars.show && !s.points.show)
+ s.lines.show = true;
+
+ // setup axes
+ if (!s.xaxis)
+ s.xaxis = axes.xaxis;
+
+ if (s.xaxis == 1)
+ s.xaxis = axes.xaxis;
+ else if (s.xaxis == 2)
+ s.xaxis = axes.x2axis;
+
+ if (!s.yaxis)
+ s.yaxis = axes.yaxis;
+
+ if (s.yaxis == 1)
+ s.yaxis = axes.yaxis;
+ else if (s.yaxis == 2)
+ s.yaxis = axes.y2axis;
+ }
+ }
+
+ function processData() {
+ var topSentry = Number.POSITIVE_INFINITY,
+ bottomSentry = Number.NEGATIVE_INFINITY,
+ i, j, k, m, length,
+ s, points, ps, x, y;
+
+ for (axis in axes) {
+ axes[axis].datamin = topSentry;
+ axes[axis].datamax = bottomSentry;
+ axes[axis].min = options[axis].min;
+ axes[axis].max = options[axis].max;
+ axes[axis].used = false;
+ }
+
+ function updateAxis(axis, min, max) {
+ if (min < axis.datamin)
+ axis.datamin = min;
+ if (max > axis.datamax)
+ axis.datamax = max;
+ }
+
+ for (i = 0; i < series.length; ++i) {
+ s = series[i];
+ s.datapoints = { points: [] };
+
+ executeHooks(hooks.processRawData, [ s, s.data, s.datapoints ]);
+ }
+
+ // first pass: clean and copy data
+ for (i = 0; i < series.length; ++i) {
+ s = series[i];
+
+ if (s.datapoints.pointsize != null)
+ continue; // already filled in
+
+ var data = s.data, format = [], p;
+
+ // determine the point size
+ if (s.bars.show) {
+ s.datapoints.pointsize = 3;
+ format.push({ d: 0 });
+ }
+ else
+ s.datapoints.pointsize = 2;
+
+ /*
+ // examine data to find out how to copy
+ for (j = 0; j < data.length; ++j) {
+ }*/
+
+ ps = s.datapoints.pointsize;
+ points = s.datapoints.points;
+
+ insertSteps = s.lines.show && s.lines.steps;
+ s.xaxis.used = s.yaxis.used = true;
+
+ for (j = k = 0; j < data.length; ++j, k += ps) {
+ p = data[j];
+
+ if (p != null) {
+ x = p[0];
+ y = p[1];
+ }
+ else
+ y = x = null;
+
+ if (x != null) {
+ x = +x; // convert to number
+ if (isNaN(x))
+ x = null;
+ }
+
+ if (y != null) {
+ y = +y; // convert to number
+ if (isNaN(y))
+ y = null;
+ }
+
+ // check validity of point, making sure both are cleared
+ if (x == null && y != null) {
+ // extract min/max info before we whack
+ updateAxis(s.yaxis, y, y);
+ y = null;
+ }
+
+ if (y == null && x != null) {
+ updateAxis(s.xaxis, x, x);
+ x = null;
+ }
+
+ if (insertSteps && x != null && k > 0
+ && points[k - ps] != null
+ && points[k - ps] != x && points[k - ps + 1] != y) {
+ points[k + 1] = points[k - ps + 1];
+ points[k] = x;
+
+ // copy the remainding from real point
+ for (m = 2; m < ps; ++m)
+ points[k + m] = p[m] == null ? format[m-2].d : p[m];
+ k += ps;
+ }
+
+ for (m = 2; m < ps; ++m)
+ points[k + m] = p[m] == null ? format[m-2].d : p[m];
+
+ points[k] = x;
+ points[k + 1] = y;
+ }
+ }
+
+ for (i = 0; i < series.length; ++i) {
+ s = series[i];
+
+ executeHooks(hooks.processDatapoints, [ s, s.datapoints]);
+ }
+
+ // second pass: find datamax/datamin for auto-scaling
+ for (i = 0; i < series.length; ++i) {
+ s = series[i];
+ points = s.datapoints.points,
+ ps = s.datapoints.pointsize;
+
+ var xmin = topSentry, ymin = topSentry,
+ xmax = bottomSentry, ymax = bottomSentry;
+
+ for (j = 0; j < points.length; j += ps) {
+ x = points[j];
+
+ if (x == null)
+ continue;
+
+ if (x < xmin)
+ xmin = x;
+ if (x > xmax)
+ xmax = x;
+
+ y = points[j + 1];
+
+ if (y < ymin)
+ ymin = y;
+ if (y > ymax)
+ ymax = y;
+ }
+
+ if (s.bars.show) {
+ // make sure we got room for the bar on the dancing floor
+ var delta = s.bars.align == "left" ? 0 : -s.bars.barWidth/2;
+ if (s.bars.horizontal) {
+ ymin += delta;
+ ymax += delta + s.bars.barWidth;
+ }
+ else {
+ xmin += delta;
+ xmax += delta + s.bars.barWidth;
+ }
+ }
+
+ updateAxis(s.xaxis, xmin, xmax);
+ updateAxis(s.yaxis, ymin, ymax);
+ }
+ }
+
+ function constructCanvas() {
+ function makeCanvas(width, height) {
+ var c = document.createElement('canvas');
+ c.width = width;
+ c.height = height;
+ if ($.browser.msie) // excanvas hack
+ c = window.G_vmlCanvasManager.initElement(c);
+ return c;
+ }
+
+ canvasWidth = target.width();
+ canvasHeight = target.height();
+ target.html(""); // clear target
+ if (target.css("position") == 'static')
+ target.css("position", "relative"); // for positioning labels and overlay
+
+ if (canvasWidth <= 0 || canvasHeight <= 0)
+ throw "Invalid dimensions for plot, width = " + canvasWidth + ", height = " + canvasHeight;
+
+ if ($.browser.msie) // excanvas hack
+ window.G_vmlCanvasManager.init_(document); // make sure everything is setup
+
+ // the canvas
+ canvas = $(makeCanvas(canvasWidth, canvasHeight)).appendTo(target).get(0);
+ ctx = canvas.getContext("2d");
+
+ // overlay canvas for interactive features
+ overlay = $(makeCanvas(canvasWidth, canvasHeight)).css({ position: 'absolute', left: 0, top: 0 }).appendTo(target).get(0);
+ octx = overlay.getContext("2d");
+ octx.stroke();
+ }
+
+ function bindEvents() {
+ // we include the canvas in the event holder too, because IE 7
+ // sometimes has trouble with the stacking order
+ eventHolder = $([overlay, canvas]);
+
+ // bind events
+ if (options.selection.mode != null
+ || options.grid.hoverable)
+ eventHolder.mousemove(onMouseMove);
+
+ if (options.selection.mode != null)
+ eventHolder.mousedown(onMouseDown);
+
+ if (options.grid.clickable)
+ eventHolder.click(onClick);
+
+ executeHooks(hooks.bindEvents, [eventHolder]);
+ }
+
+ function setupGrid() {
+ function setupAxis(axis, options) {
+ setRange(axis, options);
+ prepareTickGeneration(axis, options);
+ setTicks(axis, options);
+ // add transformation helpers
+ if (axis == axes.xaxis || axis == axes.x2axis) {
+ // data point to canvas coordinate
+ axis.p2c = function (p) { return (p - axis.min) * axis.scale; };
+ // canvas coordinate to data point
+ axis.c2p = function (c) { return axis.min + c / axis.scale; };
+ }
+ else {
+ axis.p2c = function (p) { return (axis.max - p) * axis.scale; };
+ axis.c2p = function (p) { return axis.max - p / axis.scale; };
+ }
+ }
+
+ for (var axis in axes)
+ setupAxis(axes[axis], options[axis]);
+
+ setSpacing();
+ insertLabels();
+ insertLegend();
+ }
+
+ function setRange(axis, axisOptions) {
+ var min = axisOptions.min != null ? +axisOptions.min : axis.datamin,
+ max = axisOptions.max != null ? +axisOptions.max : axis.datamax;
+
+ // degenerate case
+ if (min == Number.POSITIVE_INFINITY)
+ min = 0;
+ if (max == Number.NEGATIVE_INFINITY)
+ max = 1;
+
+ if (max - min == 0.0) {
+ // degenerate case
+ var widen = max == 0 ? 1 : 0.01;
+
+ if (axisOptions.min == null)
+ min -= widen;
+ // alway widen max if we couldn't widen min to ensure we
+ // don't fall into min == max which doesn't work
+ if (axisOptions.max == null || axisOptions.min != null)
+ max += widen;
+ }
+ else {
+ // consider autoscaling
+ var margin = axisOptions.autoscaleMargin;
+ if (margin != null) {
+ if (axisOptions.min == null) {
+ min -= (max - min) * margin;
+ // make sure we don't go below zero if all values
+ // are positive
+ if (min < 0 && axis.datamin >= 0)
+ min = 0;
+ }
+ if (axisOptions.max == null) {
+ max += (max - min) * margin;
+ if (max > 0 && axis.datamax <= 0)
+ max = 0;
+ }
+ }
+ }
+ axis.min = min;
+ axis.max = max;
+ }
+
+ function prepareTickGeneration(axis, axisOptions) {
+ // estimate number of ticks
+ var noTicks;
+ if (typeof axisOptions.ticks == "number" && axisOptions.ticks > 0)
+ noTicks = axisOptions.ticks;
+ else if (axis == axes.xaxis || axis == axes.x2axis)
+ noTicks = canvasWidth / 100;
+ else
+ noTicks = canvasHeight / 60;
+
+ var delta = (axis.max - axis.min) / noTicks;
+ var size, generator, unit, formatter, i, magn, norm;
+
+ if (axisOptions.mode == "time") {
+ // pretty handling of time
+
+ // map of app. size of time units in milliseconds
+ var timeUnitSize = {
+ "second": 1000,
+ "minute": 60 * 1000,
+ "hour": 60 * 60 * 1000,
+ "day": 24 * 60 * 60 * 1000,
+ "month": 30 * 24 * 60 * 60 * 1000,
+ "year": 365.2425 * 24 * 60 * 60 * 1000
+ };
+
+
+ // the allowed tick sizes, after 1 year we use
+ // an integer algorithm
+ var spec = [
+ [1, "second"], [2, "second"], [5, "second"], [10, "second"],
+ [30, "second"],
+ [1, "minute"], [2, "minute"], [5, "minute"], [10, "minute"],
+ [30, "minute"],
+ [1, "hour"], [2, "hour"], [4, "hour"],
+ [8, "hour"], [12, "hour"],
+ [1, "day"], [2, "day"], [3, "day"],
+ [0.25, "month"], [0.5, "month"], [1, "month"],
+ [2, "month"], [3, "month"], [6, "month"],
+ [1, "year"]
+ ];
+
+ var minSize = 0;
+ if (axisOptions.minTickSize != null) {
+ if (typeof axisOptions.tickSize == "number")
+ minSize = axisOptions.tickSize;
+ else
+ minSize = axisOptions.minTickSize[0] * timeUnitSize[axisOptions.minTickSize[1]];
+ }
+
+ for (i = 0; i < spec.length - 1; ++i)
+ if (delta < (spec[i][0] * timeUnitSize[spec[i][1]]
+ + spec[i + 1][0] * timeUnitSize[spec[i + 1][1]]) / 2
+ && spec[i][0] * timeUnitSize[spec[i][1]] >= minSize)
+ break;
+ size = spec[i][0];
+ unit = spec[i][1];
+
+ // special-case the possibility of several years
+ if (unit == "year") {
+ magn = Math.pow(10, Math.floor(Math.log(delta / timeUnitSize.year) / Math.LN10));
+ norm = (delta / timeUnitSize.year) / magn;
+ if (norm < 1.5)
+ size = 1;
+ else if (norm < 3)
+ size = 2;
+ else if (norm < 7.5)
+ size = 5;
+ else
+ size = 10;
+
+ size *= magn;
+ }
+
+ if (axisOptions.tickSize) {
+ size = axisOptions.tickSize[0];
+ unit = axisOptions.tickSize[1];
+ }
+
+ generator = function(axis) {
+ var ticks = [],
+ tickSize = axis.tickSize[0], unit = axis.tickSize[1],
+ d = new Date(axis.min);
+
+ var step = tickSize * timeUnitSize[unit];
+
+ if (unit == "second")
+ d.setUTCSeconds(floorInBase(d.getUTCSeconds(), tickSize));
+ if (unit == "minute")
+ d.setUTCMinutes(floorInBase(d.getUTCMinutes(), tickSize));
+ if (unit == "hour")
+ d.setUTCHours(floorInBase(d.getUTCHours(), tickSize));
+ if (unit == "month")
+ d.setUTCMonth(floorInBase(d.getUTCMonth(), tickSize));
+ if (unit == "year")
+ d.setUTCFullYear(floorInBase(d.getUTCFullYear(), tickSize));
+
+ // reset smaller components
+ d.setUTCMilliseconds(0);
+ if (step >= timeUnitSize.minute)
+ d.setUTCSeconds(0);
+ if (step >= timeUnitSize.hour)
+ d.setUTCMinutes(0);
+ if (step >= timeUnitSize.day)
+ d.setUTCHours(0);
+ if (step >= timeUnitSize.day * 4)
+ d.setUTCDate(1);
+ if (step >= timeUnitSize.year)
+ d.setUTCMonth(0);
+
+
+ var carry = 0, v = Number.NaN, prev;
+ do {
+ prev = v;
+ v = d.getTime();
+ ticks.push({ v: v, label: axis.tickFormatter(v, axis) });
+ if (unit == "month") {
+ if (tickSize < 1) {
+ // a bit complicated - we'll divide the month
+ // up but we need to take care of fractions
+ // so we don't end up in the middle of a day
+ d.setUTCDate(1);
+ var start = d.getTime();
+ d.setUTCMonth(d.getUTCMonth() + 1);
+ var end = d.getTime();
+ d.setTime(v + carry * timeUnitSize.hour + (end - start) * tickSize);
+ carry = d.getUTCHours();
+ d.setUTCHours(0);
+ }
+ else
+ d.setUTCMonth(d.getUTCMonth() + tickSize);
+ }
+ else if (unit == "year") {
+ d.setUTCFullYear(d.getUTCFullYear() + tickSize);
+ }
+ else
+ d.setTime(v + step);
+ } while (v < axis.max && v != prev);
+
+ return ticks;
+ };
+
+ formatter = function (v, axis) {
+ var d = new Date(v);
+
+ // first check global format
+ if (axisOptions.timeformat != null)
+ return $.plot.formatDate(d, axisOptions.timeformat, axisOptions.monthNames);
+
+ var t = axis.tickSize[0] * timeUnitSize[axis.tickSize[1]];
+ var span = axis.max - axis.min;
+
+ if (t < timeUnitSize.minute)
+ fmt = "%h:%M:%S";
+ else if (t < timeUnitSize.day) {
+ if (span < 2 * timeUnitSize.day)
+ fmt = "%h:%M";
+ else
+ fmt = "%b %d %h:%M";
+ }
+ else if (t < timeUnitSize.month)
+ fmt = "%b %d";
+ else if (t < timeUnitSize.year) {
+ if (span < timeUnitSize.year)
+ fmt = "%b";
+ else
+ fmt = "%b %y";
+ }
+ else
+ fmt = "%y";
+
+ return $.plot.formatDate(d, fmt, axisOptions.monthNames);
+ };
+ }
+ else {
+ // pretty rounding of base-10 numbers
+ var maxDec = axisOptions.tickDecimals;
+ var dec = -Math.floor(Math.log(delta) / Math.LN10);
+ if (maxDec != null && dec > maxDec)
+ dec = maxDec;
+
+ magn = Math.pow(10, -dec);
+ norm = delta / magn; // norm is between 1.0 and 10.0
+
+ if (norm < 1.5)
+ size = 1;
+ else if (norm < 3) {
+ size = 2;
+ // special case for 2.5, requires an extra decimal
+ if (norm > 2.25 && (maxDec == null || dec + 1 <= maxDec)) {
+ size = 2.5;
+ ++dec;
+ }
+ }
+ else if (norm < 7.5)
+ size = 5;
+ else
+ size = 10;
+
+ size *= magn;
+
+ if (axisOptions.minTickSize != null && size < axisOptions.minTickSize)
+ size = axisOptions.minTickSize;
+
+ if (axisOptions.tickSize != null)
+ size = axisOptions.tickSize;
+
+ axis.tickDecimals = Math.max(0, (maxDec != null) ? maxDec : dec);
+
+ generator = function (axis) {
+ var ticks = [];
+
+ // spew out all possible ticks
+ var start = floorInBase(axis.min, axis.tickSize),
+ i = 0, v = Number.NaN, prev;
+ do {
+ prev = v;
+ v = start + i * axis.tickSize;
+ ticks.push({ v: v, label: axis.tickFormatter(v, axis) });
+ ++i;
+ } while (v < axis.max && v != prev);
+ return ticks;
+ };
+
+ formatter = function (v, axis) {
+ return v.toFixed(axis.tickDecimals);
+ };
+ }
+
+ axis.tickSize = unit ? [size, unit] : size;
+ axis.tickGenerator = generator;
+ if ($.isFunction(axisOptions.tickFormatter))
+ axis.tickFormatter = function (v, axis) { return "" + axisOptions.tickFormatter(v, axis); };
+ else
+ axis.tickFormatter = formatter;
+ if (axisOptions.labelWidth != null)
+ axis.labelWidth = axisOptions.labelWidth;
+ if (axisOptions.labelHeight != null)
+ axis.labelHeight = axisOptions.labelHeight;
+ }
+
+ function setTicks(axis, axisOptions) {
+ axis.ticks = [];
+
+ if (!axis.used)
+ return;
+
+ if (axisOptions.ticks == null)
+ axis.ticks = axis.tickGenerator(axis);
+ else if (typeof axisOptions.ticks == "number") {
+ if (axisOptions.ticks > 0)
+ axis.ticks = axis.tickGenerator(axis);
+ }
+ else if (axisOptions.ticks) {
+ var ticks = axisOptions.ticks;
+
+ if ($.isFunction(ticks))
+ // generate the ticks
+ ticks = ticks({ min: axis.min, max: axis.max });
+
+ // clean up the user-supplied ticks, copy them over
+ var i, v;
+ for (i = 0; i < ticks.length; ++i) {
+ var label = null;
+ var t = ticks[i];
+ if (typeof t == "object") {
+ v = t[0];
+ if (t.length > 1)
+ label = t[1];
+ }
+ else
+ v = t;
+ if (label == null)
+ label = axis.tickFormatter(v, axis);
+ axis.ticks[i] = { v: v, label: label };
+ }
+ }
+
+ if (axisOptions.autoscaleMargin != null && axis.ticks.length > 0) {
+ // snap to ticks
+ if (axisOptions.min == null)
+ axis.min = Math.min(axis.min, axis.ticks[0].v);
+ if (axisOptions.max == null && axis.ticks.length > 1)
+ axis.max = Math.min(axis.max, axis.ticks[axis.ticks.length - 1].v);
+ }
+ }
+
+ function setSpacing() {
+ function measureXLabels(axis) {
+ // to avoid measuring the widths of the labels, we
+ // construct fixed-size boxes and put the labels inside
+ // them, we don't need the exact figures and the
+ // fixed-size box content is easy to center
+ if (axis.labelWidth == null)
+ axis.labelWidth = canvasWidth / 6;
+
+ // measure x label heights
+ if (axis.labelHeight == null) {
+ labels = [];
+ for (i = 0; i < axis.ticks.length; ++i) {
+ l = axis.ticks[i].label;
+ if (l)
+ labels.push('<div class="tickLabel" style="float:left;width:' + axis.labelWidth + 'px">' + l + '</div>');
+ }
+
+ axis.labelHeight = 0;
+ if (labels.length > 0) {
+ var dummyDiv = $('<div style="position:absolute;top:-10000px;width:10000px;font-size:smaller">'
+ + labels.join("") + '<div style="clear:left"></div></div>').appendTo(target);
+ axis.labelHeight = dummyDiv.height();
+ dummyDiv.remove();
+ }
+ }
+ }
+
+ function measureYLabels(axis) {
+ if (axis.labelWidth == null || axis.labelHeight == null) {
+ var i, labels = [], l;
+ // calculate y label dimensions
+ for (i = 0; i < axis.ticks.length; ++i) {
+ l = axis.ticks[i].label;
+ if (l)
+ labels.push('<div class="tickLabel">' + l + '</div>');
+ }
+
+ if (labels.length > 0) {
+ var dummyDiv = $('<div style="position:absolute;top:-10000px;font-size:smaller">'
+ + labels.join("") + '</div>').appendTo(target);
+ if (axis.labelWidth == null)
+ axis.labelWidth = dummyDiv.width();
+ if (axis.labelHeight == null)
+ axis.labelHeight = dummyDiv.find("div").height();
+ dummyDiv.remove();
+ }
+
+ if (axis.labelWidth == null)
+ axis.labelWidth = 0;
+ if (axis.labelHeight == null)
+ axis.labelHeight = 0;
+ }
+ }
+
+ measureXLabels(axes.xaxis);
+ measureYLabels(axes.yaxis);
+ measureXLabels(axes.x2axis);
+ measureYLabels(axes.y2axis);
+
+ // get the most space needed around the grid for things
+ // that may stick out
+ var maxOutset = options.grid.borderWidth;
+ for (i = 0; i < series.length; ++i)
+ maxOutset = Math.max(maxOutset, 2 * (series[i].points.radius + series[i].points.lineWidth/2));
+
+ plotOffset.left = plotOffset.right = plotOffset.top = plotOffset.bottom = maxOutset;
+
+ var margin = options.grid.labelMargin + options.grid.borderWidth;
+
+ if (axes.xaxis.labelHeight > 0)
+ plotOffset.bottom = Math.max(maxOutset, axes.xaxis.labelHeight + margin);
+ if (axes.yaxis.labelWidth > 0)
+ plotOffset.left = Math.max(maxOutset, axes.yaxis.labelWidth + margin);
+
+ if (axes.x2axis.labelHeight > 0)
+ plotOffset.top = Math.max(maxOutset, axes.x2axis.labelHeight + margin);
+
+ if (axes.y2axis.labelWidth > 0)
+ plotOffset.right = Math.max(maxOutset, axes.y2axis.labelWidth + margin);
+
+ plotWidth = canvasWidth - plotOffset.left - plotOffset.right;
+ plotHeight = canvasHeight - plotOffset.bottom - plotOffset.top;
+
+ // precompute how much the axis is scaling a point in canvas space
+ axes.xaxis.scale = plotWidth / (axes.xaxis.max - axes.xaxis.min);
+ axes.yaxis.scale = plotHeight / (axes.yaxis.max - axes.yaxis.min);
+ axes.x2axis.scale = plotWidth / (axes.x2axis.max - axes.x2axis.min);
+ axes.y2axis.scale = plotHeight / (axes.y2axis.max - axes.y2axis.min);
+ }
+
+ function draw() {
+ drawGrid();
+ for (var i = 0; i < series.length; ++i)
+ drawSeries(series[i]);
+ }
+
+ function extractRange(ranges, coord) {
+ var firstAxis = coord + "axis",
+ secondaryAxis = coord + "2axis",
+ axis, from, to, reverse;
+
+ if (ranges[firstAxis]) {
+ axis = axes[firstAxis];
+ from = ranges[firstAxis].from;
+ to = ranges[firstAxis].to;
+ }
+ else if (ranges[secondaryAxis]) {
+ axis = axes[secondaryAxis];
+ from = ranges[secondaryAxis].from;
+ to = ranges[secondaryAxis].to;
+ }
+ else {
+ // backwards-compat stuff - to be removed in future
+ axis = axes[firstAxis];
+ from = ranges[coord + "1"];
+ to = ranges[coord + "2"];
+ }
+
+ // auto-reverse as an added bonus
+ if (from != null && to != null && from > to)
+ return { from: to, to: from, axis: axis };
+
+ return { from: from, to: to, axis: axis };
+ }
+
+ function drawGrid() {
+ var i;
+
+ ctx.save();
+ ctx.clearRect(0, 0, canvasWidth, canvasHeight);
+ ctx.translate(plotOffset.left, plotOffset.top);
+
+ // draw background, if any
+ if (options.grid.backgroundColor) {
+ ctx.fillStyle = getColorOrGradient(options.grid.backgroundColor, plotHeight, 0, "rgba(255, 255, 255, 0)");
+ ctx.fillRect(0, 0, plotWidth, plotHeight);
+ }
+
+ // draw markings
+ var markings = options.grid.markings;
+ if (markings) {
+ if ($.isFunction(markings))
+ // xmin etc. are backwards-compatible, to be removed in future
+ markings = markings({ xmin: axes.xaxis.min, xmax: axes.xaxis.max, ymin: axes.yaxis.min, ymax: axes.yaxis.max, xaxis: axes.xaxis, yaxis: axes.yaxis, x2axis: axes.x2axis, y2axis: axes.y2axis });
+
+ for (i = 0; i < markings.length; ++i) {
+ var m = markings[i],
+ xrange = extractRange(m, "x"),
+ yrange = extractRange(m, "y");
+
+ // fill in missing
+ if (xrange.from == null)
+ xrange.from = xrange.axis.min;
+ if (xrange.to == null)
+ xrange.to = xrange.axis.max;
+ if (yrange.from == null)
+ yrange.from = yrange.axis.min;
+ if (yrange.to == null)
+ yrange.to = yrange.axis.max;
+
+ // clip
+ if (xrange.to < xrange.axis.min || xrange.from > xrange.axis.max ||
+ yrange.to < yrange.axis.min || yrange.from > yrange.axis.max)
+ continue;
+
+ xrange.from = Math.max(xrange.from, xrange.axis.min);
+ xrange.to = Math.min(xrange.to, xrange.axis.max);
+ yrange.from = Math.max(yrange.from, yrange.axis.min);
+ yrange.to = Math.min(yrange.to, yrange.axis.max);
+
+ if (xrange.from == xrange.to && yrange.from == yrange.to)
+ continue;
+
+ // then draw
+ xrange.from = xrange.axis.p2c(xrange.from);
+ xrange.to = xrange.axis.p2c(xrange.to);
+ yrange.from = yrange.axis.p2c(yrange.from);
+ yrange.to = yrange.axis.p2c(yrange.to);
+
+ if (xrange.from == xrange.to || yrange.from == yrange.to) {
+ // draw line
+ ctx.strokeStyle = m.color || options.grid.markingsColor;
+ ctx.beginPath();
+ ctx.lineWidth = m.lineWidth || options.grid.markingsLineWidth;
+ //ctx.moveTo(Math.floor(xrange.from), yrange.from);
+ //ctx.lineTo(Math.floor(xrange.to), yrange.to);
+ ctx.moveTo(xrange.from, yrange.from);
+ ctx.lineTo(xrange.to, yrange.to);
+ ctx.stroke();
+ }
+ else {
+ // fill area
+ ctx.fillStyle = m.color || options.grid.markingsColor;
+ ctx.fillRect(xrange.from, yrange.to,
+ xrange.to - xrange.from,
+ yrange.from - yrange.to);
+ }
+ }
+ }
+
+ // draw the inner grid
+ ctx.lineWidth = 1;
+ ctx.strokeStyle = options.grid.tickColor;
+ ctx.beginPath();
+ var v, axis = axes.xaxis;
+ for (i = 0; i < axis.ticks.length; ++i) {
+ v = axis.ticks[i].v;
+ if (v <= axis.min || v >= axes.xaxis.max)
+ continue; // skip those lying on the axes
+
+ ctx.moveTo(Math.floor(axis.p2c(v)) + ctx.lineWidth/2, 0);
+ ctx.lineTo(Math.floor(axis.p2c(v)) + ctx.lineWidth/2, plotHeight);
+ }
+
+ axis = axes.yaxis;
+ for (i = 0; i < axis.ticks.length; ++i) {
+ v = axis.ticks[i].v;
+ if (v <= axis.min || v >= axis.max)
+ continue;
+
+ ctx.moveTo(0, Math.floor(axis.p2c(v)) + ctx.lineWidth/2);
+ ctx.lineTo(plotWidth, Math.floor(axis.p2c(v)) + ctx.lineWidth/2);
+ }
+
+ axis = axes.x2axis;
+ for (i = 0; i < axis.ticks.length; ++i) {
+ v = axis.ticks[i].v;
+ if (v <= axis.min || v >= axis.max)
+ continue;
+
+ ctx.moveTo(Math.floor(axis.p2c(v)) + ctx.lineWidth/2, -5);
+ ctx.lineTo(Math.floor(axis.p2c(v)) + ctx.lineWidth/2, 5);
+ }
+
+ axis = axes.y2axis;
+ for (i = 0; i < axis.ticks.length; ++i) {
+ v = axis.ticks[i].v;
+ if (v <= axis.min || v >= axis.max)
+ continue;
+
+ ctx.moveTo(plotWidth-5, Math.floor(axis.p2c(v)) + ctx.lineWidth/2);
+ ctx.lineTo(plotWidth+5, Math.floor(axis.p2c(v)) + ctx.lineWidth/2);
+ }
+
+ ctx.stroke();
+
+ if (options.grid.borderWidth) {
+ // draw border
+ var bw = options.grid.borderWidth;
+ ctx.lineWidth = bw;
+ ctx.strokeStyle = options.grid.borderColor;
+ ctx.strokeRect(-bw/2, -bw/2, plotWidth + bw, plotHeight + bw);
+ }
+
+ ctx.restore();
+ }
+
+ function insertLabels() {
+ target.find(".tickLabels").remove();
+
+ var html = ['<div class="tickLabels" style="font-size:smaller;color:' + options.grid.color + '">'];
+
+ function addLabels(axis, labelGenerator) {
+ for (var i = 0; i < axis.ticks.length; ++i) {
+ var tick = axis.ticks[i];
+ if (!tick.label || tick.v < axis.min || tick.v > axis.max)
+ continue;
+ html.push(labelGenerator(tick, axis));
+ }
+ }
+
+ var margin = options.grid.labelMargin + options.grid.borderWidth;
+
+ addLabels(axes.xaxis, function (tick, axis) {
+ return '<div style="position:absolute;top:' + (plotOffset.top + plotHeight + margin) + 'px;left:' + Math.round(plotOffset.left + axis.p2c(tick.v) - axis.labelWidth/2) + 'px;width:' + axis.labelWidth + 'px;text-align:center" class="tickLabel">' + tick.label + "</div>";
+ });
+
+
+ addLabels(axes.yaxis, function (tick, axis) {
+ return '<div style="position:absolute;top:' + Math.round(plotOffset.top + axis.p2c(tick.v) - axis.labelHeight/2) + 'px;right:' + (plotOffset.right + plotWidth + margin) + 'px;width:' + axis.labelWidth + 'px;text-align:right" class="tickLabel">' + tick.label + "</div>";
+ });
+
+ addLabels(axes.x2axis, function (tick, axis) {
+ return '<div style="position:absolute;bottom:' + (plotOffset.bottom + plotHeight + margin) + 'px;left:' + Math.round(plotOffset.left + axis.p2c(tick.v) - axis.labelWidth/2) + 'px;width:' + axis.labelWidth + 'px;text-align:center" class="tickLabel">' + tick.label + "</div>";
+ });
+
+ addLabels(axes.y2axis, function (tick, axis) {
+ return '<div style="position:absolute;top:' + Math.round(plotOffset.top + axis.p2c(tick.v) - axis.labelHeight/2) + 'px;left:' + (plotOffset.left + plotWidth + margin) +'px;width:' + axis.labelWidth + 'px;text-align:left" class="tickLabel">' + tick.label + "</div>";
+ });
+
+ html.push('</div>');
+
+ target.append(html.join(""));
+ }
+
+ function drawSeries(series) {
+ if (series.lines.show)
+ drawSeriesLines(series);
+ if (series.bars.show)
+ drawSeriesBars(series);
+ if (series.points.show)
+ drawSeriesPoints(series);
+ }
+
+ function drawSeriesLines(series) {
+ function plotLine(datapoints, xoffset, yoffset, axisx, axisy) {
+ var points = datapoints.points,
+ ps = datapoints.pointsize,
+ prevx = null, prevy = null;
+
+ ctx.beginPath();
+ for (var i = ps; i < points.length; i += ps) {
+ var x1 = points[i - ps], y1 = points[i - ps + 1],
+ x2 = points[i], y2 = points[i + 1];
+
+ if (x1 == null || x2 == null)
+ continue;
+
+ // clip with ymin
+ if (y1 <= y2 && y1 < axisy.min) {
+ if (y2 < axisy.min)
+ continue; // line segment is outside
+ // compute new intersection point
+ x1 = (axisy.min - y1) / (y2 - y1) * (x2 - x1) + x1;
+ y1 = axisy.min;
+ }
+ else if (y2 <= y1 && y2 < axisy.min) {
+ if (y1 < axisy.min)
+ continue;
+ x2 = (axisy.min - y1) / (y2 - y1) * (x2 - x1) + x1;
+ y2 = axisy.min;
+ }
+
+ // clip with ymax
+ if (y1 >= y2 && y1 > axisy.max) {
+ if (y2 > axisy.max)
+ continue;
+ x1 = (axisy.max - y1) / (y2 - y1) * (x2 - x1) + x1;
+ y1 = axisy.max;
+ }
+ else if (y2 >= y1 && y2 > axisy.max) {
+ if (y1 > axisy.max)
+ continue;
+ x2 = (axisy.max - y1) / (y2 - y1) * (x2 - x1) + x1;
+ y2 = axisy.max;
+ }
+
+ // clip with xmin
+ if (x1 <= x2 && x1 < axisx.min) {
+ if (x2 < axisx.min)
+ continue;
+ y1 = (axisx.min - x1) / (x2 - x1) * (y2 - y1) + y1;
+ x1 = axisx.min;
+ }
+ else if (x2 <= x1 && x2 < axisx.min) {
+ if (x1 < axisx.min)
+ continue;
+ y2 = (axisx.min - x1) / (x2 - x1) * (y2 - y1) + y1;
+ x2 = axisx.min;
+ }
+
+ // clip with xmax
+ if (x1 >= x2 && x1 > axisx.max) {
+ if (x2 > axisx.max)
+ continue;
+ y1 = (axisx.max - x1) / (x2 - x1) * (y2 - y1) + y1;
+ x1 = axisx.max;
+ }
+ else if (x2 >= x1 && x2 > axisx.max) {
+ if (x1 > axisx.max)
+ continue;
+ y2 = (axisx.max - x1) / (x2 - x1) * (y2 - y1) + y1;
+ x2 = axisx.max;
+ }
+
+ if (x1 != prevx || y1 != prevy)
+ ctx.moveTo(axisx.p2c(x1) + xoffset, axisy.p2c(y1) + yoffset);
+
+ prevx = x2;
+ prevy = y2;
+ ctx.lineTo(axisx.p2c(x2) + xoffset, axisy.p2c(y2) + yoffset);
+ }
+ ctx.stroke();
+ }
+
+ function plotLineArea(datapoints, axisx, axisy) {
+ var points = datapoints.points,
+ ps = datapoints.pointsize,
+ bottom = Math.min(Math.max(0, axisy.min), axisy.max),
+ top, lastX = 0, areaOpen = false;
+
+ for (var i = ps; i < points.length; i += ps) {
+ var x1 = points[i - ps], y1 = points[i - ps + 1],
+ x2 = points[i], y2 = points[i + 1];
+
+ if (areaOpen && x1 != null && x2 == null) {
+ // close area
+ ctx.lineTo(axisx.p2c(lastX), axisy.p2c(bottom));
+ ctx.fill();
+ areaOpen = false;
+ continue;
+ }
+
+ if (x1 == null || x2 == null)
+ continue;
+
+ // clip x values
+
+ // clip with xmin
+ if (x1 <= x2 && x1 < axisx.min) {
+ if (x2 < axisx.min)
+ continue;
+ y1 = (axisx.min - x1) / (x2 - x1) * (y2 - y1) + y1;
+ x1 = axisx.min;
+ }
+ else if (x2 <= x1 && x2 < axisx.min) {
+ if (x1 < axisx.min)
+ continue;
+ y2 = (axisx.min - x1) / (x2 - x1) * (y2 - y1) + y1;
+ x2 = axisx.min;
+ }
+
+ // clip with xmax
+ if (x1 >= x2 && x1 > axisx.max) {
+ if (x2 > axisx.max)
+ continue;
+ y1 = (axisx.max - x1) / (x2 - x1) * (y2 - y1) + y1;
+ x1 = axisx.max;
+ }
+ else if (x2 >= x1 && x2 > axisx.max) {
+ if (x1 > axisx.max)
+ continue;
+ y2 = (axisx.max - x1) / (x2 - x1) * (y2 - y1) + y1;
+ x2 = axisx.max;
+ }
+
+ if (!areaOpen) {
+ // open area
+ ctx.beginPath();
+ ctx.moveTo(axisx.p2c(x1), axisy.p2c(bottom));
+ areaOpen = true;
+ }
+
+ // now first check the case where both is outside
+ if (y1 >= axisy.max && y2 >= axisy.max) {
+ ctx.lineTo(axisx.p2c(x1), axisy.p2c(axisy.max));
+ ctx.lineTo(axisx.p2c(x2), axisy.p2c(axisy.max));
+ lastX = x2;
+ continue;
+ }
+ else if (y1 <= axisy.min && y2 <= axisy.min) {
+ ctx.lineTo(axisx.p2c(x1), axisy.p2c(axisy.min));
+ ctx.lineTo(axisx.p2c(x2), axisy.p2c(axisy.min));
+ lastX = x2;
+ continue;
+ }
+
+ // else it's a bit more complicated, there might
+ // be two rectangles and two triangles we need to fill
+ // in; to find these keep track of the current x values
+ var x1old = x1, x2old = x2;
+
+ // and clip the y values, without shortcutting
+
+ // clip with ymin
+ if (y1 <= y2 && y1 < axisy.min && y2 >= axisy.min) {
+ x1 = (axisy.min - y1) / (y2 - y1) * (x2 - x1) + x1;
+ y1 = axisy.min;
+ }
+ else if (y2 <= y1 && y2 < axisy.min && y1 >= axisy.min) {
+ x2 = (axisy.min - y1) / (y2 - y1) * (x2 - x1) + x1;
+ y2 = axisy.min;
+ }
+
+ // clip with ymax
+ if (y1 >= y2 && y1 > axisy.max && y2 <= axisy.max) {
+ x1 = (axisy.max - y1) / (y2 - y1) * (x2 - x1) + x1;
+ y1 = axisy.max;
+ }
+ else if (y2 >= y1 && y2 > axisy.max && y1 <= axisy.max) {
+ x2 = (axisy.max - y1) / (y2 - y1) * (x2 - x1) + x1;
+ y2 = axisy.max;
+ }
+
+
+ // if the x value was changed we got a rectangle
+ // to fill
+ if (x1 != x1old) {
+ if (y1 <= axisy.min)
+ top = axisy.min;
+ else
+ top = axisy.max;
+
+ ctx.lineTo(axisx.p2c(x1old), axisy.p2c(top));
+ ctx.lineTo(axisx.p2c(x1), axisy.p2c(top));
+ }
+
+ // fill the triangles
+ ctx.lineTo(axisx.p2c(x1), axisy.p2c(y1));
+ ctx.lineTo(axisx.p2c(x2), axisy.p2c(y2));
+
+ // fill the other rectangle if it's there
+ if (x2 != x2old) {
+ if (y2 <= axisy.min)
+ top = axisy.min;
+ else
+ top = axisy.max;
+
+ ctx.lineTo(axisx.p2c(x2), axisy.p2c(top));
+ ctx.lineTo(axisx.p2c(x2old), axisy.p2c(top));
+ }
+
+ lastX = Math.max(x2, x2old);
+ }
+
+ if (areaOpen) {
+ ctx.lineTo(axisx.p2c(lastX), axisy.p2c(bottom));
+ ctx.fill();
+ }
+ }
+
+ ctx.save();
+ ctx.translate(plotOffset.left, plotOffset.top);
+ ctx.lineJoin = "round";
+
+ var lw = series.lines.lineWidth,
+ sw = series.shadowSize;
+ // FIXME: consider another form of shadow when filling is turned on
+ if (lw > 0 && sw > 0) {
+ // draw shadow as a thick and thin line with transparency
+ ctx.lineWidth = sw;
+ ctx.strokeStyle = "rgba(0,0,0,0.1)";
+ var xoffset = 1;
+ plotLine(series.datapoints, xoffset, Math.sqrt((lw/2 + sw/2)*(lw/2 + sw/2) - xoffset*xoffset), series.xaxis, series.yaxis);
+ ctx.lineWidth = sw/2;
+ plotLine(series.datapoints, xoffset, Math.sqrt((lw/2 + sw/4)*(lw/2 + sw/4) - xoffset*xoffset), series.xaxis, series.yaxis);
+ }
+
+ ctx.lineWidth = lw;
+ ctx.strokeStyle = series.color;
+ var fillStyle = getFillStyle(series.lines, series.color, 0, plotHeight);
+ if (fillStyle) {
+ ctx.fillStyle = fillStyle;
+ plotLineArea(series.datapoints, series.xaxis, series.yaxis);
+ }
+
+ if (lw > 0)
+ plotLine(series.datapoints, 0, 0, series.xaxis, series.yaxis);
+ ctx.restore();
+ }
+
+ function drawSeriesPoints(series) {
+ function plotPoints(datapoints, radius, fillStyle, offset, circumference, axisx, axisy) {
+ var points = datapoints.points, ps = datapoints.pointsize;
+
+ for (var i = 0; i < points.length; i += ps) {
+ var x = points[i], y = points[i + 1];
+ if (x == null || x < axisx.min || x > axisx.max || y < axisy.min || y > axisy.max)
+ continue;
+
+ ctx.beginPath();
+ ctx.arc(axisx.p2c(x), axisy.p2c(y) + offset, radius, 0, circumference, true);
+ if (fillStyle) {
+ ctx.fillStyle = fillStyle;
+ ctx.fill();
+ }
+ ctx.stroke();
+ }
+ }
+
+ ctx.save();
+ ctx.translate(plotOffset.left, plotOffset.top);
+
+ var lw = series.lines.lineWidth,
+ sw = series.shadowSize,
+ radius = series.points.radius;
+ if (lw > 0 && sw > 0) {
+ // draw shadow in two steps
+ var w = sw / 2;
+ ctx.lineWidth = w;
+ ctx.strokeStyle = "rgba(0,0,0,0.1)";
+ plotPoints(series.datapoints, radius, null, w + w/2, 2 * Math.PI,
+ series.xaxis, series.yaxis);
+
+ ctx.strokeStyle = "rgba(0,0,0,0.2)";
+ plotPoints(series.datapoints, radius, null, w/2, 2 * Math.PI,
+ series.xaxis, series.yaxis);
+ }
+
+ ctx.lineWidth = lw;
+ ctx.strokeStyle = series.color;
+ plotPoints(series.datapoints, radius,
+ getFillStyle(series.points, series.color), 0, 2 * Math.PI,
+ series.xaxis, series.yaxis);
+ ctx.restore();
+ }
+
+ function drawBar(x, y, b, barLeft, barRight, offset, fillStyleCallback, axisx, axisy, c, horizontal) {
+ var left, right, bottom, top,
+ drawLeft, drawRight, drawTop, drawBottom,
+ tmp;
+
+ if (horizontal) {
+ drawBottom = drawRight = drawTop = true;
+ drawLeft = false;
+ left = b;
+ right = x;
+ top = y + barLeft;
+ bottom = y + barRight;
+
+ // account for negative bars
+ if (right < left) {
+ tmp = right;
+ right = left;
+ left = tmp;
+ drawLeft = true;
+ drawRight = false;
+ }
+ }
+ else {
+ drawLeft = drawRight = drawTop = true;
+ drawBottom = false;
+ left = x + barLeft;
+ right = x + barRight;
+ bottom = b;
+ top = y;
+
+ // account for negative bars
+ if (top < bottom) {
+ tmp = top;
+ top = bottom;
+ bottom = tmp;
+ drawBottom = true;
+ drawTop = false;
+ }
+ }
+
+ // clip
+ if (right < axisx.min || left > axisx.max ||
+ top < axisy.min || bottom > axisy.max)
+ return;
+
+ if (left < axisx.min) {
+ left = axisx.min;
+ drawLeft = false;
+ }
+
+ if (right > axisx.max) {
+ right = axisx.max;
+ drawRight = false;
+ }
+
+ if (bottom < axisy.min) {
+ bottom = axisy.min;
+ drawBottom = false;
+ }
+
+ if (top > axisy.max) {
+ top = axisy.max;
+ drawTop = false;
+ }
+
+ left = axisx.p2c(left);
+ bottom = axisy.p2c(bottom);
+ right = axisx.p2c(right);
+ top = axisy.p2c(top);
+
+ // fill the bar
+ if (fillStyleCallback) {
+ c.beginPath();
+ c.moveTo(left, bottom);
+ c.lineTo(left, top);
+ c.lineTo(right, top);
+ c.lineTo(right, bottom);
+ c.fillStyle = fillStyleCallback(bottom, top);
+ c.fill();
+ }
+
+ // draw outline
+ if (drawLeft || drawRight || drawTop || drawBottom) {
+ c.beginPath();
+
+ // FIXME: inline moveTo is buggy with excanvas
+ c.moveTo(left, bottom + offset);
+ if (drawLeft)
+ c.lineTo(left, top + offset);
+ else
+ c.moveTo(left, top + offset);
+ if (drawTop)
+ c.lineTo(right, top + offset);
+ else
+ c.moveTo(right, top + offset);
+ if (drawRight)
+ c.lineTo(right, bottom + offset);
+ else
+ c.moveTo(right, bottom + offset);
+ if (drawBottom)
+ c.lineTo(left, bottom + offset);
+ else
+ c.moveTo(left, bottom + offset);
+ c.stroke();
+ }
+ }
+
+ function drawSeriesBars(series) {
+ function plotBars(datapoints, barLeft, barRight, offset, fillStyleCallback, axisx, axisy) {
+ var points = datapoints.points, ps = datapoints.pointsize;
+
+ for (var i = 0; i < points.length; i += ps) {
+ if (points[i] == null)
+ continue;
+ drawBar(points[i], points[i + 1], points[i + 2], barLeft, barRight, offset, fillStyleCallback, axisx, axisy, ctx, series.bars.horizontal);
+ }
+ }
+
+ ctx.save();
+ ctx.translate(plotOffset.left, plotOffset.top);
+
+ // FIXME: figure out a way to add shadows (for instance along the right edge)
+ ctx.lineWidth = series.bars.lineWidth;
+ ctx.strokeStyle = series.color;
+ var barLeft = series.bars.align == "left" ? 0 : -series.bars.barWidth/2;
+ var fillStyleCallback = series.bars.fill ? function (bottom, top) { return getFillStyle(series.bars, series.color, bottom, top); } : null;
+ plotBars(series.datapoints, barLeft, barLeft + series.bars.barWidth, 0, fillStyleCallback, series.xaxis, series.yaxis);
+ ctx.restore();
+ }
+
+ function getFillStyle(filloptions, seriesColor, bottom, top) {
+ var fill = filloptions.fill;
+ if (!fill)
+ return null;
+
+ if (filloptions.fillColor)
+ return getColorOrGradient(filloptions.fillColor, bottom, top, seriesColor);
+
+ var c = parseColor(seriesColor);
+ c.a = typeof fill == "number" ? fill : 0.4;
+ c.normalize();
+ return c.toString();
+ }
+
+ function insertLegend() {
+ target.find(".legend").remove();
+
+ if (!options.legend.show)
+ return;
+
+ var fragments = [], rowStarted = false,
+ lf = options.legend.labelFormatter, s, label;
+ for (i = 0; i < series.length; ++i) {
+ s = series[i];
+ label = s.label;
+ if (!label)
+ continue;
+
+ if (i % options.legend.noColumns == 0) {
+ if (rowStarted)
+ fragments.push('</tr>');
+ fragments.push('<tr>');
+ rowStarted = true;
+ }
+
+ if (lf)
+ label = lf(label, s);
+
+ fragments.push(
+ '<td class="legendColorBox"><div style="border:1px solid ' + options.legend.labelBoxBorderColor + ';padding:1px"><div style="width:4px;height:0;border:5px solid ' + s.color + ';overflow:hidden"></div></div></td>' +
+ '<td class="legendLabel">' + label + '</td>');
+ }
+ if (rowStarted)
+ fragments.push('</tr>');
+
+ if (fragments.length == 0)
+ return;
+
+ var table = '<table style="font-size:smaller;color:' + options.grid.color + '">' + fragments.join("") + '</table>';
+ if (options.legend.container != null)
+ $(options.legend.container).html(table);
+ else {
+ var pos = "",
+ p = options.legend.position,
+ m = options.legend.margin;
+ if (m[0] == null)
+ m = [m, m];
+ if (p.charAt(0) == "n")
+ pos += 'top:' + (m[1] + plotOffset.top) + 'px;';
+ else if (p.charAt(0) == "s")
+ pos += 'bottom:' + (m[1] + plotOffset.bottom) + 'px;';
+ if (p.charAt(1) == "e")
+ pos += 'right:' + (m[0] + plotOffset.right) + 'px;';
+ else if (p.charAt(1) == "w")
+ pos += 'left:' + (m[0] + plotOffset.left) + 'px;';
+ var legend = $('<div class="legend">' + table.replace('style="', 'style="position:absolute;' + pos +';') + '</div>').appendTo(target);
+ if (options.legend.backgroundOpacity != 0.0) {
+ // put in the transparent background
+ // separately to avoid blended labels and
+ // label boxes
+ var c = options.legend.backgroundColor;
+ if (c == null) {
+ var tmp;
+ if (options.grid.backgroundColor && typeof options.grid.backgroundColor == "string")
+ tmp = options.grid.backgroundColor;
+ else
+ tmp = extractColor(legend);
+ c = parseColor(tmp).adjust(null, null, null, 1).toString();
+ }
+ var div = legend.children();
+ $('<div style="position:absolute;width:' + div.width() + 'px;height:' + div.height() + 'px;' + pos +'background-color:' + c + ';"> </div>').prependTo(legend).css('opacity', options.legend.backgroundOpacity);
+ }
+ }
+ }
+
+
+ // interactive features
+
+ var lastMousePos = { pageX: null, pageY: null },
+ selection = {
+ first: { x: -1, y: -1}, second: { x: -1, y: -1},
+ show: false,
+ active: false
+ },
+ highlights = [],
+ clickIsMouseUp = false,
+ redrawTimeout = null,
+ hoverTimeout = null;
+
+ // returns the data item the mouse is over, or null if none is found
+ function findNearbyItem(mouseX, mouseY, seriesFilter) {
+ var maxDistance = options.grid.mouseActiveRadius,
+ lowestDistance = maxDistance * maxDistance + 1,
+ item = null, foundPoint = false, i, j;
+
+ for (var i = 0; i < series.length; ++i) {
+ if (!seriesFilter(series[i]))
+ continue;
+
+ var s = series[i],
+ axisx = s.xaxis,
+ axisy = s.yaxis,
+ points = s.datapoints.points,
+ ps = s.datapoints.pointsize,
+ mx = axisx.c2p(mouseX), // precompute some stuff to make the loop faster
+ my = axisy.c2p(mouseY),
+ maxx = maxDistance / axisx.scale,
+ maxy = maxDistance / axisy.scale;
+
+ if (s.lines.show || s.points.show) {
+ for (j = 0; j < points.length; j += ps) {
+ var x = points[j], y = points[j + 1];
+ if (x == null)
+ continue;
+
+ // For points and lines, the cursor must be within a
+ // certain distance to the data point
+ if (x - mx > maxx || x - mx < -maxx ||
+ y - my > maxy || y - my < -maxy)
+ continue;
+
+ // We have to calculate distances in pixels, not in
+ // data units, because the scales of the axes may be different
+ var dx = Math.abs(axisx.p2c(x) - mouseX),
+ dy = Math.abs(axisy.p2c(y) - mouseY),
+ dist = dx * dx + dy * dy; // no idea in taking sqrt
+ if (dist < lowestDistance) {
+ lowestDistance = dist;
+ item = [i, j / ps];
+ }
+ }
+ }
+
+ if (s.bars.show && !item) { // no other point can be nearby
+ var barLeft = s.bars.align == "left" ? 0 : -s.bars.barWidth/2,
+ barRight = barLeft + s.bars.barWidth;
+
+ for (j = 0; j < points.length; j += ps) {
+ var x = points[j], y = points[j + 1], b = points[j + 2];
+ if (x == null)
+ continue;
+
+ // for a bar graph, the cursor must be inside the bar
+ if (series[i].bars.horizontal ?
+ (mx <= Math.max(b, x) && mx >= Math.min(b, x) &&
+ my >= y + barLeft && my <= y + barRight) :
+ (mx >= x + barLeft && mx <= x + barRight &&
+ my >= Math.min(b, y) && my <= Math.max(b, y)))
+ item = [i, j / ps];
+ }
+ }
+ }
+
+ if (item) {
+ i = item[0];
+ j = item[1];
+
+ return { datapoint: series[i].datapoints.points.slice(j * ps, (j + 1) * ps),
+ dataIndex: j,
+ series: series[i],
+ seriesIndex: i };
+ }
+
+ return null;
+ }
+
+ function onMouseMove(e) {
+ lastMousePos.pageX = e.pageX;
+ lastMousePos.pageY = e.pageY;
+
+ if (options.grid.hoverable)
+ triggerClickHoverEvent("plothover", lastMousePos,
+ function (s) { return s["hoverable"] != false; });
+
+ if (selection.active) {
+ target.trigger("plotselecting", [ getSelection() ]);
+
+ updateSelection(lastMousePos);
+ }
+ }
+
+ function onMouseDown(e) {
+ if (e.which != 1) // only accept left-click
+ return;
+
+ // cancel out any text selections
+ document.body.focus();
+
+ // prevent text selection and drag in old-school browsers
+ if (document.onselectstart !== undefined && workarounds.onselectstart == null) {
+ workarounds.onselectstart = document.onselectstart;
+ document.onselectstart = function () { return false; };
+ }
+ if (document.ondrag !== undefined && workarounds.ondrag == null) {
+ workarounds.ondrag = document.ondrag;
+ document.ondrag = function () { return false; };
+ }
+
+ setSelectionPos(selection.first, e);
+
+ lastMousePos.pageX = null;
+ selection.active = true;
+ $(document).one("mouseup", onSelectionMouseUp);
+ }
+
+ function onClick(e) {
+ if (clickIsMouseUp) {
+ clickIsMouseUp = false;
+ return;
+ }
+
+ triggerClickHoverEvent("plotclick", e,
+ function (s) { return s["clickable"] != false; });
+ }
+
+ /*
+ function userPositionInCanvasSpace(pos) {
+ return { x: parseInt(pos.x != null ? axes.xaxis.p2c(pos.x) : axes.x2axis.p2c(pos.x2)),
+ y: parseInt(pos.y != null ? axes.yaxis.p2c(pos.y) : axes.y2axis.p2c(pos.y2)) };
+ }
+
+ function positionInDivSpace(pos) {
+ var cpos = userPositionInCanvasSpace(pos);
+ return { x: cpos.x + plotOffset.left,
+ y: cpos.y + plotOffset.top };
+ }*/
+
+ // trigger click or hover event (they send the same parameters
+ // so we share their code)
+ function triggerClickHoverEvent(eventname, event, seriesFilter) {
+ var offset = eventHolder.offset(),
+ pos = { pageX: event.pageX, pageY: event.pageY },
+ canvasX = event.pageX - offset.left - plotOffset.left,
+ canvasY = event.pageY - offset.top - plotOffset.top;
+
+ if (axes.xaxis.used)
+ pos.x = axes.xaxis.c2p(canvasX);
+ if (axes.yaxis.used)
+ pos.y = axes.yaxis.c2p(canvasY);
+ if (axes.x2axis.used)
+ pos.x2 = axes.x2axis.c2p(canvasX);
+ if (axes.y2axis.used)
+ pos.y2 = axes.y2axis.c2p(canvasY);
+
+ var item = findNearbyItem(canvasX, canvasY, seriesFilter);
+
+ if (item) {
+ // fill in mouse pos for any listeners out there
+ item.pageX = parseInt(item.series.xaxis.p2c(item.datapoint[0]) + offset.left + plotOffset.left);
+ item.pageY = parseInt(item.series.yaxis.p2c(item.datapoint[1]) + offset.top + plotOffset.top);
+ }
+
+ if (options.grid.autoHighlight) {
+ // clear auto-highlights
+ for (var i = 0; i < highlights.length; ++i) {
+ var h = highlights[i];
+ if (h.auto == eventname &&
+ !(item && h.series == item.series && h.point == item.datapoint))
+ unhighlight(h.series, h.point);
+ }
+
+ if (item)
+ highlight(item.series, item.datapoint, eventname);
+ }
+
+ target.trigger(eventname, [ pos, item ]);
+ }
+
+ function triggerRedrawOverlay() {
+ if (!redrawTimeout)
+ redrawTimeout = setTimeout(drawOverlay, 30);
+ }
+
+ function drawOverlay() {
+ redrawTimeout = null;
+
+ // draw highlights
+ octx.save();
+ octx.clearRect(0, 0, canvasWidth, canvasHeight);
+ octx.translate(plotOffset.left, plotOffset.top);
+
+ var i, hi;
+ for (i = 0; i < highlights.length; ++i) {
+ hi = highlights[i];
+
+ if (hi.series.bars.show)
+ drawBarHighlight(hi.series, hi.point);
+ else
+ drawPointHighlight(hi.series, hi.point);
+ }
+
+ // draw selection
+ if (selection.show && selectionIsSane()) {
+ octx.strokeStyle = parseColor(options.selection.color).scale(null, null, null, 0.8).toString();
+ octx.lineWidth = 1;
+ ctx.lineJoin = "round";
+ octx.fillStyle = parseColor(options.selection.color).scale(null, null, null, 0.4).toString();
+
+ var x = Math.min(selection.first.x, selection.second.x),
+ y = Math.min(selection.first.y, selection.second.y),
+ w = Math.abs(selection.second.x - selection.first.x),
+ h = Math.abs(selection.second.y - selection.first.y);
+
+ octx.fillRect(x, y, w, h);
+ octx.strokeRect(x, y, w, h);
+ }
+ octx.restore();
+
+ executeHooks(hooks.drawOverlay, [octx]);
+ }
+
+ function highlight(s, point, auto) {
+ if (typeof s == "number")
+ s = series[s];
+
+ if (typeof point == "number")
+ point = s.data[point];
+
+ var i = indexOfHighlight(s, point);
+ if (i == -1) {
+ highlights.push({ series: s, point: point, auto: auto });
+
+ triggerRedrawOverlay();
+ }
+ else if (!auto)
+ highlights[i].auto = false;
+ }
+
+ function unhighlight(s, point) {
+ if (s == null && point == null) {
+ highlights = [];
+ triggerRedrawOverlay();
+ }
+
+ if (typeof s == "number")
+ s = series[s];
+
+ if (typeof point == "number")
+ point = s.data[point];
+
+ var i = indexOfHighlight(s, point);
+ if (i != -1) {
+ highlights.splice(i, 1);
+
+ triggerRedrawOverlay();
+ }
+ }
+
+ function indexOfHighlight(s, p) {
+ for (var i = 0; i < highlights.length; ++i) {
+ var h = highlights[i];
+ if (h.series == s && h.point[0] == p[0]
+ && h.point[1] == p[1])
+ return i;
+ }
+ return -1;
+ }
+
+ function drawPointHighlight(series, point) {
+ var x = point[0], y = point[1],
+ axisx = series.xaxis, axisy = series.yaxis;
+
+ if (x < axisx.min || x > axisx.max || y < axisy.min || y > axisy.max)
+ return;
+
+ var pointRadius = series.points.radius + series.points.lineWidth / 2;
+ octx.lineWidth = pointRadius;
+ octx.strokeStyle = parseColor(series.color).scale(1, 1, 1, 0.5).toString();
+ var radius = 1.5 * pointRadius;
+ octx.beginPath();
+ octx.arc(axisx.p2c(x), axisy.p2c(y), radius, 0, 2 * Math.PI, true);
+ octx.stroke();
+ }
+
+ function drawBarHighlight(series, point) {
+ octx.lineWidth = series.bars.lineWidth;
+ octx.strokeStyle = parseColor(series.color).scale(1, 1, 1, 0.5).toString();
+ var fillStyle = parseColor(series.color).scale(1, 1, 1, 0.5).toString();
+ var barLeft = series.bars.align == "left" ? 0 : -series.bars.barWidth/2;
+ drawBar(point[0], point[1], point[2] || 0, barLeft, barLeft + series.bars.barWidth,
+ 0, function () { return fillStyle; }, series.xaxis, series.yaxis, octx, series.bars.horizontal);
+ }
+
+ function getSelection() {
+ if (!selectionIsSane())
+ return null;
+
+ var x1 = Math.min(selection.first.x, selection.second.x),
+ x2 = Math.max(selection.first.x, selection.second.x),
+ y1 = Math.max(selection.first.y, selection.second.y),
+ y2 = Math.min(selection.first.y, selection.second.y);
+
+ var r = {};
+ if (axes.xaxis.used)
+ r.xaxis = { from: axes.xaxis.c2p(x1), to: axes.xaxis.c2p(x2) };
+ if (axes.x2axis.used)
+ r.x2axis = { from: axes.x2axis.c2p(x1), to: axes.x2axis.c2p(x2) };
+ if (axes.yaxis.used)
+ r.yaxis = { from: axes.yaxis.c2p(y1), to: axes.yaxis.c2p(y2) };
+ if (axes.y2axis.used)
+ r.y2axis = { from: axes.y2axis.c2p(y1), to: axes.y2axis.c2p(y2) };
+ return r;
+ }
+
+ function triggerSelectedEvent() {
+ var r = getSelection();
+
+ target.trigger("plotselected", [ r ]);
+
+ // backwards-compat stuff, to be removed in future
+ if (axes.xaxis.used && axes.yaxis.used)
+ target.trigger("selected", [ { x1: r.xaxis.from, y1: r.yaxis.from, x2: r.xaxis.to, y2: r.yaxis.to } ]);
+ }
+
+ function onSelectionMouseUp(e) {
+ // revert drag stuff for old-school browsers
+ if (document.onselectstart !== undefined)
+ document.onselectstart = workarounds.onselectstart;
+ if (document.ondrag !== undefined)
+ document.ondrag = workarounds.ondrag;
+
+ // no more draggy-dee-drag
+ selection.active = false;
+ updateSelection(e);
+
+ if (selectionIsSane()) {
+ triggerSelectedEvent();
+ clickIsMouseUp = true;
+ }
+ else {
+ // this counts as a clear
+ target.trigger("plotunselected", [ ]);
+ target.trigger("plotselecting", [ null ]);
+ }
+
+ return false;
+ }
+
+ function setSelectionPos(pos, e) {
+ var offset = eventHolder.offset();
+ pos.x = clamp(0, e.pageX - offset.left - plotOffset.left, plotWidth);
+ pos.y = clamp(0, e.pageY - offset.top - plotOffset.top, plotHeight);
+
+ if (options.selection.mode == "y") {
+ if (pos == selection.first)
+ pos.x = 0;
+ else
+ pos.x = plotWidth;
+ }
+
+ if (options.selection.mode == "x") {
+ if (pos == selection.first)
+ pos.y = 0;
+ else
+ pos.y = plotHeight;
+ }
+ }
+
+ function updateSelection(pos) {
+ if (pos.pageX == null)
+ return;
+
+ setSelectionPos(selection.second, pos);
+ if (selectionIsSane()) {
+ selection.show = true;
+ triggerRedrawOverlay();
+ }
+ else
+ clearSelection(true);
+ }
+
+ function clearSelection(preventEvent) {
+ if (selection.show) {
+ selection.show = false;
+ triggerRedrawOverlay();
+ if (!preventEvent)
+ target.trigger("plotunselected", [ ]);
+ }
+ }
+
+ function setSelection(ranges, preventEvent) {
+ var range;
+
+ if (options.selection.mode == "y") {
+ selection.first.x = 0;
+ selection.second.x = plotWidth;
+ }
+ else {
+ range = extractRange(ranges, "x");
+
+ selection.first.x = range.axis.p2c(range.from);
+ selection.second.x = range.axis.p2c(range.to);
+ }
+
+ if (options.selection.mode == "x") {
+ selection.first.y = 0;
+ selection.second.y = plotHeight;
+ }
+ else {
+ range = extractRange(ranges, "y");
+
+ selection.first.y = range.axis.p2c(range.from);
+ selection.second.y = range.axis.p2c(range.to);
+ }
+
+ selection.show = true;
+ triggerRedrawOverlay();
+ if (!preventEvent)
+ triggerSelectedEvent();
+ }
+
+ function selectionIsSane() {
+ var minSize = 5;
+ return Math.abs(selection.second.x - selection.first.x) >= minSize &&
+ Math.abs(selection.second.y - selection.first.y) >= minSize;
+ }
+
+ function getColorOrGradient(spec, bottom, top, defaultColor) {
+ if (typeof spec == "string")
+ return spec;
+ else {
+ // assume this is a gradient spec; IE currently only
+ // supports a simple vertical gradient properly, so that's
+ // what we support too
+ var gradient = ctx.createLinearGradient(0, top, 0, bottom);
+
+ for (var i = 0, l = spec.colors.length; i < l; ++i) {
+ var c = spec.colors[i];
+ gradient.addColorStop(i / (l - 1), typeof c == "string" ? c : parseColor(defaultColor).scale(c.brightness, c.brightness, c.brightness, c.opacity));
+ }
+
+ return gradient;
+ }
+ }
+ }
+
+ $.plot = function(target, data, options) {
+ var plot = new Plot($(target), data, options, $.plot.plugins);
+ /*var t0 = new Date();
+ var t1 = new Date();
+ var tstr = "time used (msecs): " + (t1.getTime() - t0.getTime())
+ if (window.console)
+ console.log(tstr);
+ else
+ alert(tstr);*/
+ return plot;
+ };
+
+ $.plot.plugins = [];
+
+ // returns a string with the date d formatted according to fmt
+ $.plot.formatDate = function(d, fmt, monthNames) {
+ var leftPad = function(n) {
+ n = "" + n;
+ return n.length == 1 ? "0" + n : n;
+ };
+
+ var r = [];
+ var escape = false;
+ if (monthNames == null)
+ monthNames = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
+ for (var i = 0; i < fmt.length; ++i) {
+ var c = fmt.charAt(i);
+
+ if (escape) {
+ switch (c) {
+ case 'h': c = "" + d.getUTCHours(); break;
+ case 'H': c = leftPad(d.getUTCHours()); break;
+ case 'M': c = leftPad(d.getUTCMinutes()); break;
+ case 'S': c = leftPad(d.getUTCSeconds()); break;
+ case 'd': c = "" + d.getUTCDate(); break;
+ case 'm': c = "" + (d.getUTCMonth() + 1); break;
+ case 'y': c = "" + d.getUTCFullYear(); break;
+ case 'b': c = "" + monthNames[d.getUTCMonth()]; break;
+ }
+ r.push(c);
+ escape = false;
+ }
+ else {
+ if (c == "%")
+ escape = true;
+ else
+ r.push(c);
+ }
+ }
+ return r.join("");
+ };
+
+ // round to nearby lower multiple of base
+ function floorInBase(n, base) {
+ return base * Math.floor(n / base);
+ }
+
+ function clamp(min, value, max) {
+ if (value < min)
+ return min;
+ else if (value > max)
+ return max;
+ else
+ return value;
+ }
+
+ // color helpers, inspiration from the jquery color animation
+ // plugin by John Resig
+ function Color (r, g, b, a) {
+
+ var rgba = ['r','g','b','a'];
+ var x = 4; //rgba.length
+
+ while (-1<--x) {
+ this[rgba[x]] = arguments[x] || ((x==3) ? 1.0 : 0);
+ }
+
+ this.toString = function() {
+ if (this.a >= 1.0) {
+ return "rgb("+[this.r,this.g,this.b].join(",")+")";
+ } else {
+ return "rgba("+[this.r,this.g,this.b,this.a].join(",")+")";
+ }
+ };
+
+ this.scale = function(rf, gf, bf, af) {
+ x = 4; //rgba.length
+ while (-1<--x) {
+ if (arguments[x] != null)
+ this[rgba[x]] *= arguments[x];
+ }
+ return this.normalize();
+ };
+
+ this.adjust = function(rd, gd, bd, ad) {
+ x = 4; //rgba.length
+ while (-1<--x) {
+ if (arguments[x] != null)
+ this[rgba[x]] += arguments[x];
+ }
+ return this.normalize();
+ };
+
+ this.clone = function() {
+ return new Color(this.r, this.b, this.g, this.a);
+ };
+
+ var limit = function(val,minVal,maxVal) {
+ return Math.max(Math.min(val, maxVal), minVal);
+ };
+
+ this.normalize = function() {
+ this.r = clamp(0, parseInt(this.r), 255);
+ this.g = clamp(0, parseInt(this.g), 255);
+ this.b = clamp(0, parseInt(this.b), 255);
+ this.a = clamp(0, this.a, 1);
+ return this;
+ };
+
+ this.normalize();
+ }
+
+ var lookupColors = {
+ aqua:[0,255,255],
+ azure:[240,255,255],
+ beige:[245,245,220],
+ black:[0,0,0],
+ blue:[0,0,255],
+ brown:[165,42,42],
+ cyan:[0,255,255],
+ darkblue:[0,0,139],
+ darkcyan:[0,139,139],
+ darkgrey:[169,169,169],
+ darkgreen:[0,100,0],
+ darkkhaki:[189,183,107],
+ darkmagenta:[139,0,139],
+ darkolivegreen:[85,107,47],
+ darkorange:[255,140,0],
+ darkorchid:[153,50,204],
+ darkred:[139,0,0],
+ darksalmon:[233,150,122],
+ darkviolet:[148,0,211],
+ fuchsia:[255,0,255],
+ gold:[255,215,0],
+ green:[0,128,0],
+ indigo:[75,0,130],
+ khaki:[240,230,140],
+ lightblue:[173,216,230],
+ lightcyan:[224,255,255],
+ lightgreen:[144,238,144],
+ lightgrey:[211,211,211],
+ lightpink:[255,182,193],
+ lightyellow:[255,255,224],
+ lime:[0,255,0],
+ magenta:[255,0,255],
+ maroon:[128,0,0],
+ navy:[0,0,128],
+ olive:[128,128,0],
+ orange:[255,165,0],
+ pink:[255,192,203],
+ purple:[128,0,128],
+ violet:[128,0,128],
+ red:[255,0,0],
+ silver:[192,192,192],
+ white:[255,255,255],
+ yellow:[255,255,0]
+ };
+
+ function extractColor(element) {
+ var color, elem = element;
+ do {
+ color = elem.css("background-color").toLowerCase();
+ // keep going until we find an element that has color, or
+ // we hit the body
+ if (color != '' && color != 'transparent')
+ break;
+ elem = elem.parent();
+ } while (!$.nodeName(elem.get(0), "body"));
+
+ // catch Safari's way of signalling transparent
+ if (color == "rgba(0, 0, 0, 0)")
+ return "transparent";
+
+ return color;
+ }
+
+ // parse string, returns Color
+ function parseColor(str) {
+ var result;
+
+ // Look for rgb(num,num,num)
+ if (result = /rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(str))
+ return new Color(parseInt(result[1], 10), parseInt(result[2], 10), parseInt(result[3], 10));
+
+ // Look for rgba(num,num,num,num)
+ if (result = /rgba\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]+(?:\.[0-9]+)?)\s*\)/.exec(str))
+ return new Color(parseInt(result[1], 10), parseInt(result[2], 10), parseInt(result[3], 10), parseFloat(result[4]));
+
+ // Look for rgb(num%,num%,num%)
+ if (result = /rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(str))
+ return new Color(parseFloat(result[1])*2.55, parseFloat(result[2])*2.55, parseFloat(result[3])*2.55);
+
+ // Look for rgba(num%,num%,num%,num)
+ if (result = /rgba\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\s*\)/.exec(str))
+ return new Color(parseFloat(result[1])*2.55, parseFloat(result[2])*2.55, parseFloat(result[3])*2.55, parseFloat(result[4]));
+
+ // Look for #a0b1c2
+ if (result = /#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(str))
+ return new Color(parseInt(result[1], 16), parseInt(result[2], 16), parseInt(result[3], 16));
+
+ // Look for #fff
+ if (result = /#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(str))
+ return new Color(parseInt(result[1]+result[1], 16), parseInt(result[2]+result[2], 16), parseInt(result[3]+result[3], 16));
+
+ // Otherwise, we're most likely dealing with a named color
+ var name = $.trim(str).toLowerCase();
+ if (name == "transparent")
+ return new Color(255, 255, 255, 0);
+ else {
+ result = lookupColors[name];
+ return new Color(result[0], result[1], result[2]);
+ }
+ }
+
+})(jQuery);
diff --git a/site/app/webroot/js/jquery.sparkline.min.js b/site/app/webroot/js/jquery.sparkline.min.js
new file mode 100644
index 0000000..8b50d71
--- /dev/null
+++ b/site/app/webroot/js/jquery.sparkline.min.js
@@ -0,0 +1,72 @@
+/* jquery.sparkline 1.4.2 - http://omnipotent.net/jquery.sparkline/ */
+
+(function($){$.fn.simpledraw=function(width,height,use_existing){if(use_existing&&this[0].vcanvas)return this[0].vcanvas;if(width==undefined)width=$(this).innerWidth();if(height==undefined)height=$(this).innerHeight();if($.browser.hasCanvas){return new vcanvas_canvas(width,height,this);}else if($.browser.msie){return new vcanvas_vml(width,height,this);}else{return false;}};var pending=[];$.fn.sparkline=function(uservalues,options){var options=$.extend({type:'line',lineColor:'#00f',fillColor:'#cdf',defaultPixelsPerValue:3,width:'auto',height:'auto',composite:false},options?options:{});return this.each(function(){var render=function(){var values=(uservalues=='html'||uservalues==undefined)?$(this).text().split(','):uservalues;var width=options.width=='auto'?values.length*options.defaultPixelsPerValue:options.width;if(options.height=='auto'){if(!options.composite||!this.vcanvas){var tmp=document.createElement('span');tmp.innerHTML='a';$(this).html(tmp);height=$(tmp).innerHeight();$(tmp).remove();}}else{height=options.height;}
+$.fn.sparkline[options.type].call(this,values,options,width,height);}
+if(($(this).html()&&$(this).is(':hidden'))||($.fn.jquery<"1.3.0"&&$(this).parents().is(':hidden'))){pending.push([this,render]);}else{render.call(this);}});};$.sparkline_display_visible=function(){for(var i=pending.length-1;i>=0;i--){var el=pending[i][0];if($(el).is(':visible')&&!$(el).parents().is(':hidden')){pending[i][1].call(el);pending.splice(i,1);}}};$.fn.sparkline.line=function(values,options,width,height){var options=$.extend({spotColor:'#f80',spotRadius:1.5,minSpotColor:'#f80',maxSpotColor:'#f80',normalRangeMin:undefined,normalRangeMax:undefined,normalRangeColor:'#ccc',chartRangeMin:undefined,chartRangeMax:undefined},options?options:{});var xvalues=[],yvalues=[];for(i=0;i<values.length;i++){var isstr=typeof(values[i])=='string';var isarray=typeof(values[i])=='object'&&values[i]instanceof Array;var sp=isstr&&values[i].split(':');if(isstr&&sp.length==2){xvalues.push(Number(sp[0]));yvalues.push(Number(sp[1]));}else if(isarray){xvalues.push(values[i][0]);yvalues.push(values[i][1]);}else{xvalues.push(i);yvalues.push(Number(values[i]));}}
+if(options.xvalues){xvalues=options.xvalues;}
+var maxy=Math.max.apply(Math,yvalues);var maxyval=maxy;var miny=Math.min.apply(Math,yvalues);var minyval=miny;var maxx=Math.max.apply(Math,xvalues);var maxxval=maxx;var minx=Math.min.apply(Math,xvalues);var minxval=minx;if(options.normalRangeMin!=undefined){if(options.normalRangeMin<miny)
+miny=options.normalRangeMin;if(options.normalRangeMax>maxy)
+maxy=options.normalRangeMax;}
+if(options.chartRangeMin!=undefined&&options.chartRangeMin<miny){miny=options.chartRangeMin;}
+if(options.chartRangeMax!=undefined&&options.chartRangeMax>maxy){maxy=options.chartRangeMax;}
+var rangex=maxx-minx==0?1:maxx-minx;var rangey=maxy-miny==0?1:maxy-miny;var vl=yvalues.length-1;if(vl<1){this.innerHTML='';return;}
+var target=$(this).simpledraw(width,height,options.composite);if(target){var canvas_width=target.pixel_width;var canvas_height=target.pixel_height;var canvas_top=0;var canvas_left=0;if(options.spotRadius&&(canvas_width<(options.spotRadius*4)||canvas_height<(options.spotRadius*4))){options.spotRadius=0;}
+if(options.spotRadius){if(options.minSpotColor||(options.spotColor&&yvalues[vl]==miny))
+canvas_height-=Math.ceil(options.spotRadius);if(options.maxSpotColor||(options.spotColor&&yvalues[vl]==maxy)){canvas_height-=Math.ceil(options.spotRadius);canvas_top+=Math.ceil(options.spotRadius);}
+if(options.minSpotColor||options.maxSpotColor&&(yvalues[0]==miny||yvalues[0]==maxy)){canvas_left+=Math.ceil(options.spotRadius);canvas_width-=Math.ceil(options.spotRadius);}
+if(options.spotColor||(options.minSpotColor||options.maxSpotColor&&(yvalues[vl]==miny||yvalues[vl]==maxy)))
+canvas_width-=Math.ceil(options.spotRadius);}
+canvas_height--;if(options.normalRangeMin!=undefined){var ytop=canvas_top+Math.round(canvas_height-(canvas_height*((options.normalRangeMax-miny)/rangey)));var height=Math.round((canvas_height*(options.normalRangeMax-options.normalRangeMin))/rangey);target.drawRect(canvas_left,ytop,canvas_width,height,undefined,options.normalRangeColor);}
+var path=[[canvas_left,canvas_top+canvas_height]];for(var i=0;i<yvalues.length;i++){var x=xvalues[i],y=yvalues[i];path.push([canvas_left+Math.round((x-minx)*(canvas_width/rangex)),canvas_top+Math.round(canvas_height-(canvas_height*((y-miny)/rangey)))]);}
+if(options.fillColor){path.push([canvas_left+canvas_width,canvas_top+canvas_height-1]);target.drawShape(path,undefined,options.fillColor);path.pop();}
+path[0]=[canvas_left,canvas_top+Math.round(canvas_height-(canvas_height*((yvalues[0]-miny)/rangey)))];target.drawShape(path,options.lineColor);if(options.spotRadius&&options.spotColor){target.drawCircle(canvas_left+canvas_width,canvas_top+Math.round(canvas_height-(canvas_height*((yvalues[vl]-miny)/rangey))),options.spotRadius,undefined,options.spotColor);}
+if(maxy!=minyval){if(options.spotRadius&&options.minSpotColor){var x=xvalues[yvalues.indexOf(minyval)];target.drawCircle(canvas_left+Math.round((x-minx)*(canvas_width/rangex)),canvas_top+Math.round(canvas_height-(canvas_height*((minyval-miny)/rangey))),options.spotRadius,undefined,options.minSpotColor);}
+if(options.spotRadius&&options.maxSpotColor){var x=xvalues[yvalues.indexOf(maxyval)];target.drawCircle(canvas_left+Math.round((x-minx)*(canvas_width/rangex)),canvas_top+Math.round(canvas_height-(canvas_height*((maxyval-miny)/rangey))),options.spotRadius,undefined,options.maxSpotColor);}}}else{this.innerHTML='';}};$.fn.sparkline.bar=function(values,options,width,height){values=$.map(values,Number);var options=$.extend({type:'bar',barColor:'#00f',negBarColor:'#f44',zeroColor:undefined,zeroAxis:undefined,barWidth:4,barSpacing:1,chartRangeMax:undefined,chartRangeMin:undefined},options?options:{});var width=(values.length*options.barWidth)+((values.length-1)*options.barSpacing);var max=Math.max.apply(Math,values);var min=Math.min.apply(Math,values);if(options.chartRangeMin!=undefined&&options.chartRangeMin<min){min=options.chartRangeMin;}
+if(options.chartRangeMax!=undefined&&options.chartRangeMax>max){max=options.chartRangeMax;}
+if(options.zeroAxis==undefined)options.zeroAxis=min<0;var range=max-min==0?1:max-min;var target=$(this).simpledraw(width,height);if(target){var canvas_width=target.pixel_width;var canvas_height=target.pixel_height;var yzero=min<0&&options.zeroAxis?canvas_height-Math.round(canvas_height*(Math.abs(min)/range))-1:canvas_height-1;for(var i=0;i<values.length;i++){var x=i*(options.barWidth+options.barSpacing);var val=values[i];var color=(val<0)?options.negBarColor:options.barColor;if(options.zeroAxis&&min<0){var height=Math.round(canvas_height*((Math.abs(val)/range)))+1;var y=(val<0)?yzero:yzero-height;}else{var height=Math.round(canvas_height*((val-min)/range))+1;var y=canvas_height-height;}
+if(val==0&&options.zeroColor!=undefined){color=options.zeroColor;}
+target.drawRect(x,y,options.barWidth-1,height-1,color,color);}}else{this.innerHTML='';}};$.fn.sparkline.tristate=function(values,options,width,height){values=$.map(values,Number);var options=$.extend({barWidth:4,barSpacing:1,posBarColor:'#6f6',negBarColor:'#f44',zeroBarColor:'#999',colorMap:{}},options);var width=(values.length*options.barWidth)+((values.length-1)*options.barSpacing);var target=$(this).simpledraw(width,height);if(target){var canvas_width=target.pixel_width;var canvas_height=target.pixel_height;var half_height=Math.round(canvas_height/2);for(var i=0;i<values.length;i++){var x=i*(options.barWidth+options.barSpacing);if(values[i]<0){var y=half_height;var height=half_height-1;var color=options.negBarColor;}else if(values[i]>0){var y=0;var height=half_height-1;var color=options.posBarColor;}else{var y=half_height-1;var height=2;var color=options.zeroBarColor;}
+if(options.colorMap[values[i]]){color=options.colorMap[values[i]];}
+target.drawRect(x,y,options.barWidth-1,height-1,color,color);}}else{this.innerHTML='';}};$.fn.sparkline.discrete=function(values,options,width,height){values=$.map(values,Number);var options=$.extend({lineHeight:'auto',thresholdColor:undefined,thresholdValue:0,chartRangeMax:undefined,chartRangeMin:undefined},options);width=options.width=='auto'?values.length*2:width;var interval=Math.floor(width/values.length);var target=$(this).simpledraw(width,height);if(target){var canvas_width=target.pixel_width;var canvas_height=target.pixel_height;var line_height=options.lineHeight=='auto'?Math.round(canvas_height*0.3):options.lineHeight;var pheight=canvas_height-line_height;var min=Math.min.apply(Math,values);var max=Math.max.apply(Math,values);if(options.chartRangeMin!=undefined&&options.chartRangeMin<min){min=options.chartRangeMin;}
+if(options.chartRangeMax!=undefined&&options.chartRangeMax>max){max=options.chartRangeMax;}
+var range=max-min;for(var i=0;i<values.length;i++){var val=values[i];var x=(i*interval);var ytop=Math.round(pheight-pheight*((val-min)/range));target.drawLine(x,ytop,x,ytop+line_height,(options.thresholdColor&&val<options.thresholdValue)?options.thresholdColor:options.lineColor);}}else{this.innerHTML='';}};$.fn.sparkline.bullet=function(values,options,width,height){values=$.map(values,Number);var options=$.extend({targetColor:'red',targetWidth:3,performanceColor:'blue',rangeColors:['#D3DAFE','#A8B6FF','#7F94FF'],base:undefined},options);width=options.width=='auto'?'4.0em':width;var target=$(this).simpledraw(width,height);if(target&&values.length>1){var canvas_width=target.pixel_width-Math.ceil(options.targetWidth/2);var canvas_height=target.pixel_height;var min=Math.min.apply(Math,values);var max=Math.max.apply(Math,values);if(options.base==undefined){var min=min<0?min:0;}else{min=options.base;}
+var range=max-min;for(i=2;i<values.length;i++){var rangeval=parseInt(values[i]);var rangewidth=Math.round(canvas_width*((rangeval-min)/range));target.drawRect(0,0,rangewidth-1,canvas_height-1,options.rangeColors[i-2],options.rangeColors[i-2]);}
+var perfval=parseInt(values[1]);var perfwidth=Math.round(canvas_width*((perfval-min)/range));target.drawRect(0,Math.round(canvas_height*0.3),perfwidth-1,Math.round(canvas_height*0.4)-1,options.performanceColor,options.performanceColor);var targetval=parseInt(values[0]);var x=Math.round(canvas_width*((targetval-min)/range)-(options.targetWidth/2));var targettop=Math.round(canvas_height*0.10);var targetheight=canvas_height-(targettop*2);target.drawRect(x,targettop,options.targetWidth-1,targetheight-1,options.targetColor,options.targetColor);}else{this.innerHTML='';}};$.fn.sparkline.pie=function(values,options,width,height){values=$.map(values,Number);var options=$.extend({sliceColors:['#f00','#0f0','#00f']},options);width=options.width=='auto'?height:width;var target=$(this).simpledraw(width,height);if(target&&values.length>1){var canvas_width=target.pixel_width;var canvas_height=target.pixel_height;var radius=Math.floor(Math.min(canvas_width,canvas_height)/2);var total=0;for(var i=0;i<values.length;i++)
+total+=values[i];var next=0;if(options.offset){next+=(2*Math.PI)*(options.offset/360);}
+var circle=2*Math.PI;for(var i=0;i<values.length;i++){var start=next;var end=next;if(total>0){end=next+(circle*(values[i]/total));}
+target.drawPieSlice(radius,radius,radius,start,end,undefined,options.sliceColors[i%options.sliceColors.length]);next=end;}}};function quartile(values,q){if(q==2){var vl2=Math.floor(values.length/2);return values.length%2?values[vl2]:(values[vl2]+values[vl2+1])/2;}else{var vl4=Math.floor(values.length/4);return values.length%2?(values[vl4*q]+values[vl4*q+1])/2:values[vl4*q];}};$.fn.sparkline.box=function(values,options,width,height){values=$.map(values,Number);var options=$.extend({raw:false,boxLineColor:'black',boxFillColor:'#cdf',whiskerColor:'black',outlierLineColor:'#333',outlierFillColor:'white',medianColor:'red',showOutliers:true,outlierIQR:1.5,spotRadius:1.5,target:undefined,targetColor:'#4a2',chartRangeMax:undefined,chartRangeMin:undefined},options);width=options.width=='auto'?'4.0em':width;minvalue=options.chartRangeMin==undefined?Math.min.apply(Math,values):options.chartRangeMin;maxvalue=options.chartRangeMax==undefined?Math.max.apply(Math,values):options.chartRangeMax;var target=$(this).simpledraw(width,height);if(target&&values.length>1){var canvas_width=target.pixel_width;var canvas_height=target.pixel_height;if(options.raw){if(options.showOutliers&&values.length>5){var loutlier=values[0],lwhisker=values[1],q1=values[2],q2=values[3],q3=values[4],rwhisker=values[5],routlier=values[6];}else{var lwhisker=values[0],q1=values[1],q2=values[2],q3=values[3],rwhisker=values[4];}}else{values.sort(function(a,b){return a-b;});var q1=quartile(values,1);var q2=quartile(values,2);var q3=quartile(values,3);var iqr=q3-q1;if(options.showOutliers){var lwhisker=undefined,rwhisker=undefined;for(var i=0;i<values.length;i++){if(lwhisker==undefined&&values[i]>q1-(iqr*options.outlierIQR))
+lwhisker=values[i];if(values[i]<q3+(iqr*options.outlierIQR))
+rwhisker=values[i];}
+var loutlier=values[0];var routlier=values[values.length-1];}else{var lwhisker=values[0];var rwhisker=values[values.length-1];}}
+var unitsize=canvas_width/(maxvalue-minvalue+1);var canvas_left=0;if(options.showOutliers){canvas_left=Math.ceil(options.spotRadius);canvas_width-=2*Math.ceil(options.spotRadius);var unitsize=canvas_width/(maxvalue-minvalue+1);if(loutlier<lwhisker)
+target.drawCircle((loutlier-minvalue)*unitsize+canvas_left,canvas_height/2,options.spotRadius,options.outlierLineColor,options.outlierFillColor);if(routlier>rwhisker)
+target.drawCircle((routlier-minvalue)*unitsize+canvas_left,canvas_height/2,options.spotRadius,options.outlierLineColor,options.outlierFillColor);}
+target.drawRect(Math.round((q1-minvalue)*unitsize+canvas_left),Math.round(canvas_height*0.1),Math.round((q3-q1)*unitsize),Math.round(canvas_height*0.8),options.boxLineColor,options.boxFillColor);target.drawLine(Math.round((lwhisker-minvalue)*unitsize+canvas_left),Math.round(canvas_height/2),Math.round((q1-minvalue)*unitsize+canvas_left),Math.round(canvas_height/2),options.lineColor);target.drawLine(Math.round((lwhisker-minvalue)*unitsize+canvas_left),Math.round(canvas_height/4),Math.round((lwhisker-minvalue)*unitsize+canvas_left),Math.round(canvas_height-canvas_height/4),options.whiskerColor);target.drawLine(Math.round((rwhisker-minvalue)*unitsize+canvas_left),Math.round(canvas_height/2),Math.round((q3-minvalue)*unitsize+canvas_left),Math.round(canvas_height/2),options.lineColor);target.drawLine(Math.round((rwhisker-minvalue)*unitsize+canvas_left),Math.round(canvas_height/4),Math.round((rwhisker-minvalue)*unitsize+canvas_left),Math.round(canvas_height-canvas_height/4),options.whiskerColor);target.drawLine(Math.round((q2-minvalue)*unitsize+canvas_left),Math.round(canvas_height*0.1),Math.round((q2-minvalue)*unitsize+canvas_left),Math.round(canvas_height*0.9),options.medianColor);if(options.target){var size=Math.ceil(options.spotRadius);target.drawLine(Math.round((options.target-minvalue)*unitsize+canvas_left),Math.round((canvas_height/2)-size),Math.round((options.target-minvalue)*unitsize+canvas_left),Math.round((canvas_height/2)+size),options.targetColor);target.drawLine(Math.round((options.target-minvalue)*unitsize+canvas_left-size),Math.round(canvas_height/2),Math.round((options.target-minvalue)*unitsize+canvas_left+size),Math.round(canvas_height/2),options.targetColor);}}else{this.innerHTML='';}};if(!Array.prototype.indexOf){Array.prototype.indexOf=function(entry){for(var i=0;i<this.length;i++){if(this[i]==entry)
+return i;}
+return-1;}}
+if($.browser.msie&&!document.namespaces['v']){document.namespaces.add('v','urn:schemas-microsoft-com:vml','#default#VML');}
+if($.browser.hasCanvas==undefined){var t=document.createElement('canvas');$.browser.hasCanvas=t.getContext!=undefined;}
+var vcanvas_base=function(width,height,target){};vcanvas_base.prototype={init:function(width,height,target){this.width=width;this.height=height;this.target=target;if(target[0])target=target[0];target.vcanvas=this;},drawShape:function(path,lineColor,fillColor){alert('drawShape not implemented');},drawLine:function(x1,y1,x2,y2,lineColor){return this.drawShape([[x1,y1],[x2,y2]],lineColor);},drawCircle:function(x,y,radius,lineColor,fillColor){alert('drawCircle not implemented');},drawPieSlice:function(x,y,radius,startAngle,endAngle,lineColor,fillColor){alert('drawPieSlice not implemented');},drawRect:function(x,y,width,height,lineColor,fillColor){alert('drawRect not implemented');},getElement:function(){return this.canvas;},_insert:function(el,target){$(target).html(el);}};var vcanvas_canvas=function(width,height,target){return this.init(width,height,target);};vcanvas_canvas.prototype=$.extend(new vcanvas_base,{_super:vcanvas_base.prototype,init:function(width,height,target){this._super.init(width,height,target);this.canvas=document.createElement('canvas');if(target[0])target=target[0];target.vcanvas=this;$(this.canvas).css({display:'inline-block',width:width,height:height,verticalAlign:'top'});this._insert(this.canvas,target);this.pixel_height=$(this.canvas).height();this.pixel_width=$(this.canvas).width();this.canvas.width=this.pixel_width;this.canvas.height=this.pixel_height;$(this.canvas).css({width:this.pixel_width,height:this.pixel_height});},_getContext:function(lineColor,fillColor){var context=this.canvas.getContext('2d');if(lineColor!=undefined)
+context.strokeStyle=lineColor;context.lineWidth=1;if(fillColor!=undefined)
+context.fillStyle=fillColor;return context;},drawShape:function(path,lineColor,fillColor){var context=this._getContext(lineColor,fillColor);context.beginPath();context.moveTo(path[0][0]+0.5,path[0][1]+0.5);for(var i=1;i<path.length;i++){context.lineTo(path[i][0]+0.5,path[i][1]+0.5);}
+if(lineColor!=undefined){context.stroke();}
+if(fillColor!=undefined){context.fill();}},drawCircle:function(x,y,radius,lineColor,fillColor){var context=this._getContext(lineColor,fillColor);context.beginPath();context.arc(x,y,radius,0,2*Math.PI,false);if(lineColor!=undefined){context.stroke();}
+if(fillColor!=undefined){context.fill();}},drawPieSlice:function(x,y,radius,startAngle,endAngle,lineColor,fillColor){var context=this._getContext(lineColor,fillColor);context.beginPath();context.moveTo(x,y);context.arc(x,y,radius,startAngle,endAngle,false);context.lineTo(x,y);context.closePath();if(lineColor!=undefined){context.stroke();}
+if(fillColor){context.fill();}},drawRect:function(x,y,width,height,lineColor,fillColor){return this.drawShape([[x,y],[x+width,y],[x+width,y+height],[x,y+height],[x,y]],lineColor,fillColor);}});var vcanvas_vml=function(width,height,target){return this.init(width,height,target);};vcanvas_vml.prototype=$.extend(new vcanvas_base,{_super:vcanvas_base.prototype,init:function(width,height,target){this._super.init(width,height,target);if(target[0])target=target[0];target.vcanvas=this;this.canvas=document.createElement('span');$(this.canvas).css({display:'inline-block',position:'relative',overflow:'hidden',width:width,height:height,margin:'0px',padding:'0px',verticalAlign:'top'});this._insert(this.canvas,target);this.pixel_height=$(this.canvas).height();this.pixel_width=$(this.canvas).width();this.canvas.width=this.pixel_width;this.canvas.height=this.pixel_height;;var groupel='<v:group coordorigin="0 0" coordsize="'+this.pixel_width+' '+this.pixel_height+'"'
++' style="position:absolute;top:0;left:0;width:'+this.pixel_width+'px;height='+this.pixel_height+'px;"></v:group>';this.canvas.insertAdjacentHTML('beforeEnd',groupel);this.group=$(this.canvas).children()[0];},drawShape:function(path,lineColor,fillColor){var vpath=[];for(var i=0;i<path.length;i++){vpath[i]=''+(path[i][0])+','+(path[i][1]);}
+var initial=vpath.splice(0,1);var stroke=lineColor==undefined?' stroked="false" ':' strokeWeight="1" strokeColor="'+lineColor+'" ';var fill=fillColor==undefined?' filled="false"':' fillColor="'+fillColor+'" filled="true" ';var closed=vpath[0]==vpath[vpath.length-1]?'x ':'';var vel='<v:shape coordorigin="0 0" coordsize="'+this.pixel_width+' '+this.pixel_height+'" '
++stroke
++fill
++' style="position:absolute;left:0px;top:0px;height:'+this.pixel_height+'px;width:'+this.pixel_width+'px;padding:0px;margin:0px;" '
++' path="m '+initial+' l '+vpath.join(', ')+' '+closed+'e">'
++' </v:shape>';this.group.insertAdjacentHTML('beforeEnd',vel);},drawCircle:function(x,y,radius,lineColor,fillColor){x-=radius+1;y-=radius+1;var stroke=lineColor==undefined?' stroked="false" ':' strokeWeight="1" strokeColor="'+lineColor+'" ';var fill=fillColor==undefined?' filled="false"':' fillColor="'+fillColor+'" filled="true" ';var vel='<v:oval '
++stroke
++fill
++' style="position:absolute;top:'+y+'px; left:'+x+'px; width:'+(radius*2)+'px; height:'+(radius*2)+'px"></v:oval>';this.group.insertAdjacentHTML('beforeEnd',vel);},drawPieSlice:function(x,y,radius,startAngle,endAngle,lineColor,fillColor){if(startAngle==endAngle){return;}
+if((endAngle-startAngle)==(2*Math.PI)){startAngle=0.0;endAngle=(2*Math.PI);}
+var startx=x+Math.round(Math.cos(startAngle)*radius);var starty=y+Math.round(Math.sin(startAngle)*radius);var endx=x+Math.round(Math.cos(endAngle)*radius);var endy=y+Math.round(Math.sin(endAngle)*radius);var vpath=[x-radius,y-radius,x+radius,y+radius,startx,starty,endx,endy];var stroke=lineColor==undefined?' stroked="false" ':' strokeWeight="1" strokeColor="'+lineColor+'" ';var fill=fillColor==undefined?' filled="false"':' fillColor="'+fillColor+'" filled="true" ';var vel='<v:shape coordorigin="0 0" coordsize="'+this.pixel_width+' '+this.pixel_height+'" '
++stroke
++fill
++' style="position:absolute;left:0px;top:0px;height:'+this.pixel_height+'px;width:'+this.pixel_width+'px;padding:0px;margin:0px;" '
++' path="m '+x+','+y+' wa '+vpath.join(', ')+' x e">'
++' </v:shape>';this.group.insertAdjacentHTML('beforeEnd',vel);},drawRect:function(x,y,width,height,lineColor,fillColor){return this.drawShape([[x,y],[x,y+height],[x+width,y+height],[x+width,y],[x,y]],lineColor,fillColor);}});})(jQuery); \ No newline at end of file
diff --git a/site/app/webroot/js/jquery.tablesorter.min.js b/site/app/webroot/js/jquery.tablesorter.min.js
new file mode 100644
index 0000000..fe7abfb
--- /dev/null
+++ b/site/app/webroot/js/jquery.tablesorter.min.js
@@ -0,0 +1,2 @@
+/* jquery.tablesorter 2.0 - http://tablesorter.com/ */
+(function($){$.extend({tablesorter:new function(){var parsers=[],widgets=[];this.defaults={cssHeader:"header",cssAsc:"headerSortUp",cssDesc:"headerSortDown",sortInitialOrder:"asc",sortMultiSortKey:"shiftKey",sortForce:null,sortAppend:null,textExtraction:"simple",parsers:{},widgets:[],widgetZebra:{css:["even","odd"]},headers:{},widthFixed:false,cancelSelection:true,sortList:[],headerList:[],dateFormat:"us",decimal:'.',debug:false};function benchmark(s,d){log(s+","+(new Date().getTime()-d.getTime())+"ms");}this.benchmark=benchmark;function log(s){if(typeof console!="undefined"&&typeof console.debug!="undefined"){console.log(s);}else{alert(s);}}function buildParserCache(table,$headers){if(table.config.debug){var parsersDebug="";}var rows=table.tBodies[0].rows;if(table.tBodies[0].rows[0]){var list=[],cells=rows[0].cells,l=cells.length;for(var i=0;i<l;i++){var p=false;if($.metadata&&($($headers[i]).metadata()&&$($headers[i]).metadata().sorter)){p=getParserById($($headers[i]).metadata().sorter);}else if((table.config.headers[i]&&table.config.headers[i].sorter)){p=getParserById(table.config.headers[i].sorter);}if(!p){p=detectParserForColumn(table,cells[i]);}if(table.config.debug){parsersDebug+="column:"+i+" parser:"+p.id+"\n";}list.push(p);}}if(table.config.debug){log(parsersDebug);}return list;};function detectParserForColumn(table,node){var l=parsers.length;for(var i=1;i<l;i++){if(parsers[i].is($.trim(getElementText(table.config,node)),table,node)){return parsers[i];}}return parsers[0];}function getParserById(name){var l=parsers.length;for(var i=0;i<l;i++){if(parsers[i].id.toLowerCase()==name.toLowerCase()){return parsers[i];}}return false;}function buildCache(table){if(table.config.debug){var cacheTime=new Date();}var totalRows=(table.tBodies[0]&&table.tBodies[0].rows.length)||0,totalCells=(table.tBodies[0].rows[0]&&table.tBodies[0].rows[0].cells.length)||0,parsers=table.config.parsers,cache={row:[],normalized:[]};for(var i=0;i<totalRows;++i){var c=table.tBodies[0].rows[i],cols=[];cache.row.push($(c));for(var j=0;j<totalCells;++j){cols.push(parsers[j].format(getElementText(table.config,c.cells[j]),table,c.cells[j]));}cols.push(i);cache.normalized.push(cols);cols=null;};if(table.config.debug){benchmark("Building cache for "+totalRows+" rows:",cacheTime);}return cache;};function getElementText(config,node){if(!node)return"";var t="";if(config.textExtraction=="simple"){if(node.childNodes[0]&&node.childNodes[0].hasChildNodes()){t=node.childNodes[0].innerHTML;}else{t=node.innerHTML;}}else{if(typeof(config.textExtraction)=="function"){t=config.textExtraction(node);}else{t=$(node).text();}}return t;}function appendToTable(table,cache){if(table.config.debug){var appendTime=new Date()}var c=cache,r=c.row,n=c.normalized,totalRows=n.length,checkCell=(n[0].length-1),tableBody=$(table.tBodies[0]),rows=[];for(var i=0;i<totalRows;i++){rows.push(r[n[i][checkCell]]);if(!table.config.appender){var o=r[n[i][checkCell]];var l=o.length;for(var j=0;j<l;j++){tableBody[0].appendChild(o[j]);}}}if(table.config.appender){table.config.appender(table,rows);}rows=null;if(table.config.debug){benchmark("Rebuilt table:",appendTime);}applyWidget(table);setTimeout(function(){$(table).trigger("sortEnd");},0);};function buildHeaders(table){if(table.config.debug){var time=new Date();}var meta=($.metadata)?true:false,tableHeadersRows=[];for(var i=0;i<table.tHead.rows.length;i++){tableHeadersRows[i]=0;};$tableHeaders=$("thead th",table);$tableHeaders.each(function(index){this.count=0;this.column=index;this.order=formatSortingOrder(table.config.sortInitialOrder);if(checkHeaderMetadata(this)||checkHeaderOptions(table,index))this.sortDisabled=true;if(!this.sortDisabled){$(this).addClass(table.config.cssHeader);}table.config.headerList[index]=this;});if(table.config.debug){benchmark("Built headers:",time);log($tableHeaders);}return $tableHeaders;};function checkCellColSpan(table,rows,row){var arr=[],r=table.tHead.rows,c=r[row].cells;for(var i=0;i<c.length;i++){var cell=c[i];if(cell.colSpan>1){arr=arr.concat(checkCellColSpan(table,headerArr,row++));}else{if(table.tHead.length==1||(cell.rowSpan>1||!r[row+1])){arr.push(cell);}}}return arr;};function checkHeaderMetadata(cell){if(($.metadata)&&($(cell).metadata().sorter===false)){return true;};return false;}function checkHeaderOptions(table,i){if((table.config.headers[i])&&(table.config.headers[i].sorter===false)){return true;};return false;}function applyWidget(table){var c=table.config.widgets;var l=c.length;for(var i=0;i<l;i++){getWidgetById(c[i]).format(table);}}function getWidgetById(name){var l=widgets.length;for(var i=0;i<l;i++){if(widgets[i].id.toLowerCase()==name.toLowerCase()){return widgets[i];}}};function formatSortingOrder(v){if(typeof(v)!="Number"){i=(v.toLowerCase()=="desc")?1:0;}else{i=(v==(0||1))?v:0;}return i;}function isValueInArray(v,a){var l=a.length;for(var i=0;i<l;i++){if(a[i][0]==v){return true;}}return false;}function setHeadersCss(table,$headers,list,css){$headers.removeClass(css[0]).removeClass(css[1]);var h=[];$headers.each(function(offset){if(!this.sortDisabled){h[this.column]=$(this);}});var l=list.length;for(var i=0;i<l;i++){h[list[i][0]].addClass(css[list[i][1]]);}}function fixColumnWidth(table,$headers){var c=table.config;if(c.widthFixed){var colgroup=$('<colgroup>');$("tr:first td",table.tBodies[0]).each(function(){colgroup.append($('<col>').css('width',$(this).width()));});$(table).prepend(colgroup);};}function updateHeaderSortCount(table,sortList){var c=table.config,l=sortList.length;for(var i=0;i<l;i++){var s=sortList[i],o=c.headerList[s[0]];o.count=s[1];o.count++;}}function multisort(table,sortList,cache){if(table.config.debug){var sortTime=new Date();}var dynamicExp="var sortWrapper = function(a,b) {",l=sortList.length;for(var i=0;i<l;i++){var c=sortList[i][0];var order=sortList[i][1];var s=(getCachedSortType(table.config.parsers,c)=="text")?((order==0)?"sortText":"sortTextDesc"):((order==0)?"sortNumeric":"sortNumericDesc");var e="e"+i;dynamicExp+="var "+e+" = "+s+"(a["+c+"],b["+c+"]); ";dynamicExp+="if("+e+") { return "+e+"; } ";dynamicExp+="else { ";}var orgOrderCol=cache.normalized[0].length-1;dynamicExp+="return a["+orgOrderCol+"]-b["+orgOrderCol+"];";for(var i=0;i<l;i++){dynamicExp+="}; ";}dynamicExp+="return 0; ";dynamicExp+="}; ";eval(dynamicExp);cache.normalized.sort(sortWrapper);if(table.config.debug){benchmark("Sorting on "+sortList.toString()+" and dir "+order+" time:",sortTime);}return cache;};function sortText(a,b){return((a<b)?-1:((a>b)?1:0));};function sortTextDesc(a,b){return((b<a)?-1:((b>a)?1:0));};function sortNumeric(a,b){return a-b;};function sortNumericDesc(a,b){return b-a;};function getCachedSortType(parsers,i){return parsers[i].type;};this.construct=function(settings){return this.each(function(){if(!this.tHead||!this.tBodies)return;var $this,$document,$headers,cache,config,shiftDown=0,sortOrder;this.config={};config=$.extend(this.config,$.tablesorter.defaults,settings);$this=$(this);$headers=buildHeaders(this);this.config.parsers=buildParserCache(this,$headers);cache=buildCache(this);var sortCSS=[config.cssDesc,config.cssAsc];fixColumnWidth(this);$headers.click(function(e){$this.trigger("sortStart");var totalRows=($this[0].tBodies[0]&&$this[0].tBodies[0].rows.length)||0;if(!this.sortDisabled&&totalRows>0){var $cell=$(this);var i=this.column;this.order=this.count++%2;if(!e[config.sortMultiSortKey]){config.sortList=[];if(config.sortForce!=null){var a=config.sortForce;for(var j=0;j<a.length;j++){if(a[j][0]!=i){config.sortList.push(a[j]);}}}config.sortList.push([i,this.order]);}else{if(isValueInArray(i,config.sortList)){for(var j=0;j<config.sortList.length;j++){var s=config.sortList[j],o=config.headerList[s[0]];if(s[0]==i){o.count=s[1];o.count++;s[1]=o.count%2;}}}else{config.sortList.push([i,this.order]);}};setTimeout(function(){setHeadersCss($this[0],$headers,config.sortList,sortCSS);appendToTable($this[0],multisort($this[0],config.sortList,cache));},1);return false;}}).mousedown(function(){if(config.cancelSelection){this.onselectstart=function(){return false};return false;}});$this.bind("update",function(){this.config.parsers=buildParserCache(this,$headers);cache=buildCache(this);}).bind("sorton",function(e,list){$(this).trigger("sortStart");config.sortList=list;var sortList=config.sortList;updateHeaderSortCount(this,sortList);setHeadersCss(this,$headers,sortList,sortCSS);appendToTable(this,multisort(this,sortList,cache));}).bind("appendCache",function(){appendToTable(this,cache);}).bind("applyWidgetId",function(e,id){getWidgetById(id).format(this);}).bind("applyWidgets",function(){applyWidget(this);});if($.metadata&&($(this).metadata()&&$(this).metadata().sortlist)){config.sortList=$(this).metadata().sortlist;}if(config.sortList.length>0){$this.trigger("sorton",[config.sortList]);}applyWidget(this);});};this.addParser=function(parser){var l=parsers.length,a=true;for(var i=0;i<l;i++){if(parsers[i].id.toLowerCase()==parser.id.toLowerCase()){a=false;}}if(a){parsers.push(parser);};};this.addWidget=function(widget){widgets.push(widget);};this.formatFloat=function(s){var i=parseFloat(s);return(isNaN(i))?0:i;};this.formatInt=function(s){var i=parseInt(s);return(isNaN(i))?0:i;};this.isDigit=function(s,config){var DECIMAL='\\'+config.decimal;var exp='/(^[+]?0('+DECIMAL+'0+)?$)|(^([-+]?[1-9][0-9]*)$)|(^([-+]?((0?|[1-9][0-9]*)'+DECIMAL+'(0*[1-9][0-9]*)))$)|(^[-+]?[1-9]+[0-9]*'+DECIMAL+'0+$)/';return RegExp(exp).test($.trim(s));};this.clearTableBody=function(table){if($.browser.msie){function empty(){while(this.firstChild)this.removeChild(this.firstChild);}empty.apply(table.tBodies[0]);}else{table.tBodies[0].innerHTML="";}};}});$.fn.extend({tablesorter:$.tablesorter.construct});var ts=$.tablesorter;ts.addParser({id:"text",is:function(s){return true;},format:function(s){return $.trim(s.toLowerCase());},type:"text"});ts.addParser({id:"digit",is:function(s,table){var c=table.config;return $.tablesorter.isDigit(s,c);},format:function(s){return $.tablesorter.formatFloat(s);},type:"numeric"});ts.addParser({id:"currency",is:function(s){return/^[£$€?.]/.test(s);},format:function(s){return $.tablesorter.formatFloat(s.replace(new RegExp(/[^0-9.]/g),""));},type:"numeric"});ts.addParser({id:"ipAddress",is:function(s){return/^\d{2,3}[\.]\d{2,3}[\.]\d{2,3}[\.]\d{2,3}$/.test(s);},format:function(s){var a=s.split("."),r="",l=a.length;for(var i=0;i<l;i++){var item=a[i];if(item.length==2){r+="0"+item;}else{r+=item;}}return $.tablesorter.formatFloat(r);},type:"numeric"});ts.addParser({id:"url",is:function(s){return/^(https?|ftp|file):\/\/$/.test(s);},format:function(s){return jQuery.trim(s.replace(new RegExp(/(https?|ftp|file):\/\//),''));},type:"text"});ts.addParser({id:"isoDate",is:function(s){return/^\d{4}[\/-]\d{1,2}[\/-]\d{1,2}$/.test(s);},format:function(s){return $.tablesorter.formatFloat((s!="")?new Date(s.replace(new RegExp(/-/g),"/")).getTime():"0");},type:"numeric"});ts.addParser({id:"percent",is:function(s){return/\%$/.test($.trim(s));},format:function(s){return $.tablesorter.formatFloat(s.replace(new RegExp(/%/g),""));},type:"numeric"});ts.addParser({id:"usLongDate",is:function(s){return s.match(new RegExp(/^[A-Za-z]{3,10}\.? [0-9]{1,2}, ([0-9]{4}|'?[0-9]{2}) (([0-2]?[0-9]:[0-5][0-9])|([0-1]?[0-9]:[0-5][0-9]\s(AM|PM)))$/));},format:function(s){return $.tablesorter.formatFloat(new Date(s).getTime());},type:"numeric"});ts.addParser({id:"shortDate",is:function(s){return/\d{1,2}[\/\-]\d{1,2}[\/\-]\d{2,4}/.test(s);},format:function(s,table){var c=table.config;s=s.replace(/\-/g,"/");if(c.dateFormat=="us"){s=s.replace(/(\d{1,2})[\/\-](\d{1,2})[\/\-](\d{4})/,"$3/$1/$2");}else if(c.dateFormat=="uk"){s=s.replace(/(\d{1,2})[\/\-](\d{1,2})[\/\-](\d{4})/,"$3/$2/$1");}else if(c.dateFormat=="dd/mm/yy"||c.dateFormat=="dd-mm-yy"){s=s.replace(/(\d{1,2})[\/\-](\d{1,2})[\/\-](\d{2})/,"$1/$2/$3");}return $.tablesorter.formatFloat(new Date(s).getTime());},type:"numeric"});ts.addParser({id:"time",is:function(s){return/^(([0-2]?[0-9]:[0-5][0-9])|([0-1]?[0-9]:[0-5][0-9]\s(am|pm)))$/.test(s);},format:function(s){return $.tablesorter.formatFloat(new Date("2000/01/01 "+s).getTime());},type:"numeric"});ts.addParser({id:"metadata",is:function(s){return false;},format:function(s,table,cell){var c=table.config,p=(!c.parserMetadataName)?'sortValue':c.parserMetadataName;return $(cell).metadata()[p];},type:"numeric"});ts.addWidget({id:"zebra",format:function(table){if(table.config.debug){var time=new Date();}$("tr:visible",table.tBodies[0]).filter(':even').removeClass(table.config.widgetZebra.css[1]).addClass(table.config.widgetZebra.css[0]).end().filter(':odd').removeClass(table.config.widgetZebra.css[0]).addClass(table.config.widgetZebra.css[1]);if(table.config.debug){$.tablesorter.benchmark("Applying Zebra widget",time);}}});})(jQuery);
diff --git a/site/app/webroot/js/json.js b/site/app/webroot/js/json.js
new file mode 100644
index 0000000..cc07400
--- /dev/null
+++ b/site/app/webroot/js/json.js
@@ -0,0 +1,2 @@
+// from http://www.json.org/json2.js
+eval(function(p,a,c,k,e,r){e=function(c){return(c<a?'':e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)r[e(c)]=k[c]||e(c);k=[function(e){return r[e]}];e=function(){return'\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}('3(!l.B){B=6(){6 f(n){4 n<10?\'0\'+n:n}X.Y.H=6(){4 l.11()+\'-\'+f(l.12()+1)+\'-\'+f(l.13())+\'T\'+f(l.14())+\':\'+f(l.15())+\':\'+f(l.17())+\'Z\'};m g=/["\\\\\\18-\\19\\1a-\\1b]/g,7,p,J={\'\\b\':\'\\\\b\',\'\\t\':\'\\\\t\',\'\\n\':\'\\\\n\',\'\\f\':\'\\\\f\',\'\\r\':\'\\\\r\',\'"\':\'\\\\"\',\'\\\\\':\'\\\\\\\\\'},h;6 o(b){4 g.K(b)?\'"\'+b.C(g,6(a){m c=J[a];3(5 c===\'D\'){4 c}c=a.1c();4\'\\\\1d\'+1e.1f(c/16).L(16)+(c%16).L(16)})+\'"\':\'"\'+b+\'"\'}6 q(a,b){m i,k,v,8,u=7,9,2=b[a];3(2&&5 2===\'w\'&&5 2.H===\'6\'){2=2.H(a)}3(5 h===\'6\'){2=h.E(b,a,2)}1g(5 2){x\'D\':4 o(2);x\'F\':4 1h(2)?M(2):\'y\';x\'1i\':x\'y\':4 M(2);x\'w\':3(!2){4\'y\'}7+=p;9=[];3(5 2.8===\'F\'&&!(2.1j(\'8\'))){8=2.8;z(i=0;i<8;i+=1){9[i]=q(i,2)||\'y\'}v=9.8===0?\'[]\':7?\'[\\n\'+7+9.G(\',\\n\'+7)+\'\\n\'+u+\']\':\'[\'+9.G(\',\')+\']\';7=u;4 v}3(5 h===\'w\'){8=h.8;z(i=0;i<8;i+=1){k=h[i];3(5 k===\'D\'){v=q(k,2,h);3(v){9.N(o(k)+(7?\': \':\':\')+v)}}}}A{z(k O 2){v=q(k,2,h);3(v){9.N(o(k)+(7?\': \':\':\')+v)}}}v=9.8===0?\'{}\':7?\'{\\n\'+7+9.G(\',\\n\'+7)+\'\\n\'+u+\'}\':\'{\'+9.G(\',\')+\'}\';7=u;4 v}}4{P:6(c,d,e){m i;7=\'\';p=\'\';3(e){3(5 e===\'F\'){z(i=0;i<e;i+=1){p+=\' \'}}A 3(5 e===\'D\'){p=e}}3(!d){h=6(a,b){3(!Q.R.E(l,a)){4 S}4 b}}A 3(5 d===\'6\'||(5 d===\'w\'&&5 d.8===\'F\')){h=d}A{U V 1k(\'B.P\');}4 q(\'\',{\'\':c})},W:6(c,d){m j;6 I(a,b){m k,v,2=a[b];3(2&&5 2===\'w\'){z(k O 2){3(Q.R.E(2,k)){v=I(2,k);3(v!==S){2[k]=v}A{1l 2[k]}}}}4 d.E(a,b,2)}3(/^[\\],:{}\\s]*$/.K(c.C(/\\\\["\\\\\\/1m]/g,\'@\').C(/"[^"\\\\\\n\\r]*"|1n|1o|y|-?\\d+(?:\\.\\d*)?(?:[1p][+\\-]?\\d+)?/g,\']\').C(/(?:^|:|,)(?:\\s*\\[)+/g,\'\'))){j=1q(\'(\'+c+\')\');4 5 d===\'6\'?I({\'\':j},\'\'):j}U V 1r(\'B.W\');},o:o}}()}',62,90,'||value|if|return|typeof|function|gap|length|partial||||||||rep||||this|var||quote|indent|str||||mind||object|case|null|for|else|JSON|replace|string|call|number|join|toJSON|walk|meta|test|toString|String|push|in|stringify|Object|hasOwnProperty|undefined||throw|new|parse|Date|prototype|||getUTCFullYear|getUTCMonth|getUTCDate|getUTCHours|getUTCMinutes||getUTCSeconds|x00|x1f|x7f|x9f|charCodeAt|u00|Math|floor|switch|isFinite|boolean|propertyIsEnumerable|Error|delete|bfnrtu|true|false|eE|eval|SyntaxError'.split('|'),0,{})) \ No newline at end of file
diff --git a/site/app/webroot/js/listing.js b/site/app/webroot/js/listing.js
new file mode 100644
index 0000000..8970a35
--- /dev/null
+++ b/site/app/webroot/js/listing.js
@@ -0,0 +1,28 @@
+//toggle visibility
+function toggleNode(node) {
+ var nodes = document.getElementsByTagName('ul');
+ for (var i = 0; i < nodes.length; i++) {
+ if (nodes[i].className == node) {
+ if (nodes[i].style.display == 'none') {
+ nodes[i].style.display = '';
+ }
+ else {
+ nodes[i].style.display = 'none';
+ }
+ }
+ }
+}
+
+function expandNodes() {
+ var nodes = document.getElementsByTagName('ul');
+ for (var i = 0; i < nodes.length; i++) {
+ nodes[i].style.display = '';
+ }
+}
+
+function collapseNodes() {
+ var nodes = document.getElementsByTagName('ul');
+ for (var i = 0; i < nodes.length; i++) {
+ nodes[i].style.display = 'none';
+ }
+}
diff --git a/site/app/webroot/js/mochikit/MochiKit.js b/site/app/webroot/js/mochikit/MochiKit.js
new file mode 100644
index 0000000..37c0d72
--- /dev/null
+++ b/site/app/webroot/js/mochikit/MochiKit.js
@@ -0,0 +1,4802 @@
+/***
+
+ MochiKit.MochiKit 1.3.1 : PACKED VERSION
+
+ THIS FILE IS AUTOMATICALLY GENERATED. If creating patches, please
+ diff against the source tree, not this file.
+
+ See <http://mochikit.com/> for documentation, downloads, license, etc.
+
+ (c) 2005 Bob Ippolito. All rights Reserved.
+
+***/
+
+if(typeof (dojo)!="undefined"){
+dojo.provide("MochiKit.Base");
+}
+if(typeof (MochiKit)=="undefined"){
+MochiKit={};
+}
+if(typeof (MochiKit.Base)=="undefined"){
+MochiKit.Base={};
+}
+MochiKit.Base.VERSION="1.3.1";
+MochiKit.Base.NAME="MochiKit.Base";
+MochiKit.Base.update=function(_1,_2){
+if(_1===null){
+_1={};
+}
+for(var i=1;i<arguments.length;i++){
+var o=arguments[i];
+if(typeof (o)!="undefined"&&o!==null){
+for(var k in o){
+_1[k]=o[k];
+}
+}
+}
+return _1;
+};
+MochiKit.Base.update(MochiKit.Base,{__repr__:function(){
+return "["+this.NAME+" "+this.VERSION+"]";
+},toString:function(){
+return this.__repr__();
+},counter:function(n){
+if(arguments.length===0){
+n=1;
+}
+return function(){
+return n++;
+};
+},clone:function(_7){
+var me=arguments.callee;
+if(arguments.length==1){
+me.prototype=_7;
+return new me();
+}
+},flattenArguments:function(_9){
+var res=[];
+var m=MochiKit.Base;
+var _12=m.extend(null,arguments);
+while(_12.length){
+var o=_12.shift();
+if(o&&typeof (o)=="object"&&typeof (o.length)=="number"){
+for(var i=o.length-1;i>=0;i--){
+_12.unshift(o[i]);
+}
+}else{
+res.push(o);
+}
+}
+return res;
+},extend:function(_13,obj,_15){
+if(!_15){
+_15=0;
+}
+if(obj){
+var l=obj.length;
+if(typeof (l)!="number"){
+if(typeof (MochiKit.Iter)!="undefined"){
+obj=MochiKit.Iter.list(obj);
+l=obj.length;
+}else{
+throw new TypeError("Argument not an array-like and MochiKit.Iter not present");
+}
+}
+if(!_13){
+_13=[];
+}
+for(var i=_15;i<l;i++){
+_13.push(obj[i]);
+}
+}
+return _13;
+},updatetree:function(_17,obj){
+if(_17===null){
+_17={};
+}
+for(var i=1;i<arguments.length;i++){
+var o=arguments[i];
+if(typeof (o)!="undefined"&&o!==null){
+for(var k in o){
+var v=o[k];
+if(typeof (_17[k])=="object"&&typeof (v)=="object"){
+arguments.callee(_17[k],v);
+}else{
+_17[k]=v;
+}
+}
+}
+}
+return _17;
+},setdefault:function(_19,obj){
+if(_19===null){
+_19={};
+}
+for(var i=1;i<arguments.length;i++){
+var o=arguments[i];
+for(var k in o){
+if(!(k in _19)){
+_19[k]=o[k];
+}
+}
+}
+return _19;
+},keys:function(obj){
+var _20=[];
+for(var _21 in obj){
+_20.push(_21);
+}
+return _20;
+},items:function(obj){
+var _22=[];
+var e;
+for(var _24 in obj){
+var v;
+try{
+v=obj[_24];
+}
+catch(e){
+continue;
+}
+_22.push([_24,v]);
+}
+return _22;
+},_newNamedError:function(_25,_26,_27){
+_27.prototype=new MochiKit.Base.NamedError(_25.NAME+"."+_26);
+_25[_26]=_27;
+},operator:{truth:function(a){
+return !!a;
+},lognot:function(a){
+return !a;
+},identity:function(a){
+return a;
+},not:function(a){
+return ~a;
+},neg:function(a){
+return -a;
+},add:function(a,b){
+return a+b;
+},sub:function(a,b){
+return a-b;
+},div:function(a,b){
+return a/b;
+},mod:function(a,b){
+return a%b;
+},mul:function(a,b){
+return a*b;
+},and:function(a,b){
+return a&b;
+},or:function(a,b){
+return a|b;
+},xor:function(a,b){
+return a^b;
+},lshift:function(a,b){
+return a<<b;
+},rshift:function(a,b){
+return a>>b;
+},zrshift:function(a,b){
+return a>>>b;
+},eq:function(a,b){
+return a==b;
+},ne:function(a,b){
+return a!=b;
+},gt:function(a,b){
+return a>b;
+},ge:function(a,b){
+return a>=b;
+},lt:function(a,b){
+return a<b;
+},le:function(a,b){
+return a<=b;
+},ceq:function(a,b){
+return MochiKit.Base.compare(a,b)===0;
+},cne:function(a,b){
+return MochiKit.Base.compare(a,b)!==0;
+},cgt:function(a,b){
+return MochiKit.Base.compare(a,b)==1;
+},cge:function(a,b){
+return MochiKit.Base.compare(a,b)!=-1;
+},clt:function(a,b){
+return MochiKit.Base.compare(a,b)==-1;
+},cle:function(a,b){
+return MochiKit.Base.compare(a,b)!=1;
+},logand:function(a,b){
+return a&&b;
+},logor:function(a,b){
+return a||b;
+},contains:function(a,b){
+return b in a;
+}},forwardCall:function(_30){
+return function(){
+return this[_30].apply(this,arguments);
+};
+},itemgetter:function(_31){
+return function(arg){
+return arg[_31];
+};
+},typeMatcher:function(){
+var _33={};
+for(var i=0;i<arguments.length;i++){
+var typ=arguments[i];
+_33[typ]=typ;
+}
+return function(){
+for(var i=0;i<arguments.length;i++){
+if(!(typeof (arguments[i]) in _33)){
+return false;
+}
+}
+return true;
+};
+},isNull:function(){
+for(var i=0;i<arguments.length;i++){
+if(arguments[i]!==null){
+return false;
+}
+}
+return true;
+},isUndefinedOrNull:function(){
+for(var i=0;i<arguments.length;i++){
+var o=arguments[i];
+if(!(typeof (o)=="undefined"||o===null)){
+return false;
+}
+}
+return true;
+},isEmpty:function(obj){
+return !MochiKit.Base.isNotEmpty.apply(this,arguments);
+},isNotEmpty:function(obj){
+for(var i=0;i<arguments.length;i++){
+var o=arguments[i];
+if(!(o&&o.length)){
+return false;
+}
+}
+return true;
+},isArrayLike:function(){
+for(var i=0;i<arguments.length;i++){
+var o=arguments[i];
+var typ=typeof (o);
+if((typ!="object"&&!(typ=="function"&&typeof (o.item)=="function"))||o===null||typeof (o.length)!="number"){
+return false;
+}
+}
+return true;
+},isDateLike:function(){
+for(var i=0;i<arguments.length;i++){
+var o=arguments[i];
+if(typeof (o)!="object"||o===null||typeof (o.getTime)!="function"){
+return false;
+}
+}
+return true;
+},xmap:function(fn){
+if(fn===null){
+return MochiKit.Base.extend(null,arguments,1);
+}
+var _36=[];
+for(var i=1;i<arguments.length;i++){
+_36.push(fn(arguments[i]));
+}
+return _36;
+},map:function(fn,lst){
+var m=MochiKit.Base;
+var itr=MochiKit.Iter;
+var _39=m.isArrayLike;
+if(arguments.length<=2){
+if(!_39(lst)){
+if(itr){
+lst=itr.list(lst);
+if(fn===null){
+return lst;
+}
+}else{
+throw new TypeError("Argument not an array-like and MochiKit.Iter not present");
+}
+}
+if(fn===null){
+return m.extend(null,lst);
+}
+var _40=[];
+for(var i=0;i<lst.length;i++){
+_40.push(fn(lst[i]));
+}
+return _40;
+}else{
+if(fn===null){
+fn=Array;
+}
+var _41=null;
+for(i=1;i<arguments.length;i++){
+if(!_39(arguments[i])){
+if(itr){
+return itr.list(itr.imap.apply(null,arguments));
+}else{
+throw new TypeError("Argument not an array-like and MochiKit.Iter not present");
+}
+}
+var l=arguments[i].length;
+if(_41===null||_41>l){
+_41=l;
+}
+}
+_40=[];
+for(i=0;i<_41;i++){
+var _42=[];
+for(var j=1;j<arguments.length;j++){
+_42.push(arguments[j][i]);
+}
+_40.push(fn.apply(this,_42));
+}
+return _40;
+}
+},xfilter:function(fn){
+var _44=[];
+if(fn===null){
+fn=MochiKit.Base.operator.truth;
+}
+for(var i=1;i<arguments.length;i++){
+var o=arguments[i];
+if(fn(o)){
+_44.push(o);
+}
+}
+return _44;
+},filter:function(fn,lst,_45){
+var _46=[];
+var m=MochiKit.Base;
+if(!m.isArrayLike(lst)){
+if(MochiKit.Iter){
+lst=MochiKit.Iter.list(lst);
+}else{
+throw new TypeError("Argument not an array-like and MochiKit.Iter not present");
+}
+}
+if(fn===null){
+fn=m.operator.truth;
+}
+if(typeof (Array.prototype.filter)=="function"){
+return Array.prototype.filter.call(lst,fn,_45);
+}else{
+if(typeof (_45)=="undefined"||_45===null){
+for(var i=0;i<lst.length;i++){
+var o=lst[i];
+if(fn(o)){
+_46.push(o);
+}
+}
+}else{
+for(i=0;i<lst.length;i++){
+o=lst[i];
+if(fn.call(_45,o)){
+_46.push(o);
+}
+}
+}
+}
+return _46;
+},_wrapDumbFunction:function(_47){
+return function(){
+switch(arguments.length){
+case 0:
+return _47();
+case 1:
+return _47(arguments[0]);
+case 2:
+return _47(arguments[0],arguments[1]);
+case 3:
+return _47(arguments[0],arguments[1],arguments[2]);
+}
+var _48=[];
+for(var i=0;i<arguments.length;i++){
+_48.push("arguments["+i+"]");
+}
+return eval("(func("+_48.join(",")+"))");
+};
+},method:function(_49,_50){
+var m=MochiKit.Base;
+return m.bind.apply(this,m.extend([_50,_49],arguments,2));
+},bind:function(_51,_52){
+if(typeof (_51)=="string"){
+_51=_52[_51];
+}
+var _53=_51.im_func;
+var _54=_51.im_preargs;
+var _55=_51.im_self;
+var m=MochiKit.Base;
+if(typeof (_51)=="function"&&typeof (_51.apply)=="undefined"){
+_51=m._wrapDumbFunction(_51);
+}
+if(typeof (_53)!="function"){
+_53=_51;
+}
+if(typeof (_52)!="undefined"){
+_55=_52;
+}
+if(typeof (_54)=="undefined"){
+_54=[];
+}else{
+_54=_54.slice();
+}
+m.extend(_54,arguments,2);
+var _56=function(){
+var _57=arguments;
+var me=arguments.callee;
+if(me.im_preargs.length>0){
+_57=m.concat(me.im_preargs,_57);
+}
+var _52=me.im_self;
+if(!_52){
+_52=this;
+}
+return me.im_func.apply(_52,_57);
+};
+_56.im_self=_55;
+_56.im_func=_53;
+_56.im_preargs=_54;
+return _56;
+},bindMethods:function(_58){
+var _59=MochiKit.Base.bind;
+for(var k in _58){
+var _60=_58[k];
+if(typeof (_60)=="function"){
+_58[k]=_59(_60,_58);
+}
+}
+},registerComparator:function(_61,_62,_63,_64){
+MochiKit.Base.comparatorRegistry.register(_61,_62,_63,_64);
+},_primitives:{"boolean":true,"string":true,"number":true},compare:function(a,b){
+if(a==b){
+return 0;
+}
+var _65=(typeof (a)=="undefined"||a===null);
+var _66=(typeof (b)=="undefined"||b===null);
+if(_65&&_66){
+return 0;
+}else{
+if(_65){
+return -1;
+}else{
+if(_66){
+return 1;
+}
+}
+}
+var m=MochiKit.Base;
+var _67=m._primitives;
+if(!(typeof (a) in _67&&typeof (b) in _67)){
+try{
+return m.comparatorRegistry.match(a,b);
+}
+catch(e){
+if(e!=m.NotFound){
+throw e;
+}
+}
+}
+if(a<b){
+return -1;
+}else{
+if(a>b){
+return 1;
+}
+}
+var _68=m.repr;
+throw new TypeError(_68(a)+" and "+_68(b)+" can not be compared");
+},compareDateLike:function(a,b){
+return MochiKit.Base.compare(a.getTime(),b.getTime());
+},compareArrayLike:function(a,b){
+var _69=MochiKit.Base.compare;
+var _70=a.length;
+var _71=0;
+if(_70>b.length){
+_71=1;
+_70=b.length;
+}else{
+if(_70<b.length){
+_71=-1;
+}
+}
+for(var i=0;i<_70;i++){
+var cmp=_69(a[i],b[i]);
+if(cmp){
+return cmp;
+}
+}
+return _71;
+},registerRepr:function(_73,_74,_75,_76){
+MochiKit.Base.reprRegistry.register(_73,_74,_75,_76);
+},repr:function(o){
+if(typeof (o)=="undefined"){
+return "undefined";
+}else{
+if(o===null){
+return "null";
+}
+}
+try{
+if(typeof (o.__repr__)=="function"){
+return o.__repr__();
+}else{
+if(typeof (o.repr)=="function"&&o.repr!=arguments.callee){
+return o.repr();
+}
+}
+return MochiKit.Base.reprRegistry.match(o);
+}
+catch(e){
+if(typeof (o.NAME)=="string"&&(o.toString==Function.prototype.toString||o.toString==Object.prototype.toString)){
+return o.NAME;
+}
+}
+try{
+var _77=(o+"");
+}
+catch(e){
+return "["+typeof (o)+"]";
+}
+if(typeof (o)=="function"){
+o=_77.replace(/^\s+/,"");
+var idx=o.indexOf("{");
+if(idx!=-1){
+o=o.substr(0,idx)+"{...}";
+}
+}
+return _77;
+},reprArrayLike:function(o){
+var m=MochiKit.Base;
+return "["+m.map(m.repr,o).join(", ")+"]";
+},reprString:function(o){
+return ("\""+o.replace(/(["\\])/g,"\\$1")+"\"").replace(/[\f]/g,"\\f").replace(/[\b]/g,"\\b").replace(/[\n]/g,"\\n").replace(/[\t]/g,"\\t").replace(/[\r]/g,"\\r");
+},reprNumber:function(o){
+return o+"";
+},registerJSON:function(_79,_80,_81,_82){
+MochiKit.Base.jsonRegistry.register(_79,_80,_81,_82);
+},evalJSON:function(){
+return eval("("+arguments[0]+")");
+},serializeJSON:function(o){
+var _83=typeof (o);
+if(_83=="undefined"){
+return "undefined";
+}else{
+if(_83=="number"||_83=="boolean"){
+return o+"";
+}else{
+if(o===null){
+return "null";
+}
+}
+}
+var m=MochiKit.Base;
+var _84=m.reprString;
+if(_83=="string"){
+return _84(o);
+}
+var me=arguments.callee;
+var _85;
+if(typeof (o.__json__)=="function"){
+_85=o.__json__();
+if(o!==_85){
+return me(_85);
+}
+}
+if(typeof (o.json)=="function"){
+_85=o.json();
+if(o!==_85){
+return me(_85);
+}
+}
+if(_83!="function"&&typeof (o.length)=="number"){
+var res=[];
+for(var i=0;i<o.length;i++){
+var val=me(o[i]);
+if(typeof (val)!="string"){
+val="undefined";
+}
+res.push(val);
+}
+return "["+res.join(", ")+"]";
+}
+try{
+_85=m.jsonRegistry.match(o);
+return me(_85);
+}
+catch(e){
+if(e!=m.NotFound){
+throw e;
+}
+}
+if(_83=="function"){
+return null;
+}
+res=[];
+for(var k in o){
+var _87;
+if(typeof (k)=="number"){
+_87="\""+k+"\"";
+}else{
+if(typeof (k)=="string"){
+_87=_84(k);
+}else{
+continue;
+}
+}
+val=me(o[k]);
+if(typeof (val)!="string"){
+continue;
+}
+res.push(_87+":"+val);
+}
+return "{"+res.join(", ")+"}";
+},objEqual:function(a,b){
+return (MochiKit.Base.compare(a,b)===0);
+},arrayEqual:function(_88,arr){
+if(_88.length!=arr.length){
+return false;
+}
+return (MochiKit.Base.compare(_88,arr)===0);
+},concat:function(){
+var _90=[];
+var _91=MochiKit.Base.extend;
+for(var i=0;i<arguments.length;i++){
+_91(_90,arguments[i]);
+}
+return _90;
+},keyComparator:function(key){
+var m=MochiKit.Base;
+var _93=m.compare;
+if(arguments.length==1){
+return function(a,b){
+return _93(a[key],b[key]);
+};
+}
+var _94=m.extend(null,arguments);
+return function(a,b){
+var _95=0;
+for(var i=0;(_95===0)&&(i<_94.length);i++){
+var key=_94[i];
+_95=_93(a[key],b[key]);
+}
+return _95;
+};
+},reverseKeyComparator:function(key){
+var _96=MochiKit.Base.keyComparator.apply(this,arguments);
+return function(a,b){
+return _96(b,a);
+};
+},partial:function(_97){
+var m=MochiKit.Base;
+return m.bind.apply(this,m.extend([_97,undefined],arguments,1));
+},listMinMax:function(_98,lst){
+if(lst.length===0){
+return null;
+}
+var cur=lst[0];
+var _100=MochiKit.Base.compare;
+for(var i=1;i<lst.length;i++){
+var o=lst[i];
+if(_100(o,cur)==_98){
+cur=o;
+}
+}
+return cur;
+},objMax:function(){
+return MochiKit.Base.listMinMax(1,arguments);
+},objMin:function(){
+return MochiKit.Base.listMinMax(-1,arguments);
+},findIdentical:function(lst,_101,_102,end){
+if(typeof (end)=="undefined"||end===null){
+end=lst.length;
+}
+for(var i=(_102||0);i<end;i++){
+if(lst[i]===_101){
+return i;
+}
+}
+return -1;
+},findValue:function(lst,_104,_105,end){
+if(typeof (end)=="undefined"||end===null){
+end=lst.length;
+}
+var cmp=MochiKit.Base.compare;
+for(var i=(_105||0);i<end;i++){
+if(cmp(lst[i],_104)===0){
+return i;
+}
+}
+return -1;
+},nodeWalk:function(node,_107){
+var _108=[node];
+var _109=MochiKit.Base.extend;
+while(_108.length){
+var res=_107(_108.shift());
+if(res){
+_109(_108,res);
+}
+}
+},nameFunctions:function(_110){
+var base=_110.NAME;
+if(typeof (base)=="undefined"){
+base="";
+}else{
+base=base+".";
+}
+for(var name in _110){
+var o=_110[name];
+if(typeof (o)=="function"&&typeof (o.NAME)=="undefined"){
+try{
+o.NAME=base+name;
+}
+catch(e){
+}
+}
+}
+},queryString:function(_113,_114){
+if(typeof (MochiKit.DOM)!="undefined"&&arguments.length==1&&(typeof (_113)=="string"||(typeof (_113.nodeType)!="undefined"&&_113.nodeType>0))){
+var kv=MochiKit.DOM.formContents(_113);
+_113=kv[0];
+_114=kv[1];
+}else{
+if(arguments.length==1){
+var o=_113;
+_113=[];
+_114=[];
+for(var k in o){
+var v=o[k];
+if(typeof (v)!="function"){
+_113.push(k);
+_114.push(v);
+}
+}
+}
+}
+var rval=[];
+var len=Math.min(_113.length,_114.length);
+var _118=MochiKit.Base.urlEncode;
+for(var i=0;i<len;i++){
+v=_114[i];
+if(typeof (v)!="undefined"&&v!==null){
+rval.push(_118(_113[i])+"="+_118(v));
+}
+}
+return rval.join("&");
+},parseQueryString:function(_119,_120){
+var _121=_119.replace(/\+/g,"%20").split("&");
+var o={};
+var _122;
+if(typeof (decodeURIComponent)!="undefined"){
+_122=decodeURIComponent;
+}else{
+_122=unescape;
+}
+if(_120){
+for(var i=0;i<_121.length;i++){
+var pair=_121[i].split("=");
+var name=_122(pair[0]);
+var arr=o[name];
+if(!(arr instanceof Array)){
+arr=[];
+o[name]=arr;
+}
+arr.push(_122(pair[1]));
+}
+}else{
+for(i=0;i<_121.length;i++){
+pair=_121[i].split("=");
+o[_122(pair[0])]=_122(pair[1]);
+}
+}
+return o;
+}});
+MochiKit.Base.AdapterRegistry=function(){
+this.pairs=[];
+};
+MochiKit.Base.AdapterRegistry.prototype={register:function(name,_124,wrap,_126){
+if(_126){
+this.pairs.unshift([name,_124,wrap]);
+}else{
+this.pairs.push([name,_124,wrap]);
+}
+},match:function(){
+for(var i=0;i<this.pairs.length;i++){
+var pair=this.pairs[i];
+if(pair[1].apply(this,arguments)){
+return pair[2].apply(this,arguments);
+}
+}
+throw MochiKit.Base.NotFound;
+},unregister:function(name){
+for(var i=0;i<this.pairs.length;i++){
+var pair=this.pairs[i];
+if(pair[0]==name){
+this.pairs.splice(i,1);
+return true;
+}
+}
+return false;
+}};
+MochiKit.Base.EXPORT=["counter","clone","extend","update","updatetree","setdefault","keys","items","NamedError","operator","forwardCall","itemgetter","typeMatcher","isCallable","isUndefined","isUndefinedOrNull","isNull","isEmpty","isNotEmpty","isArrayLike","isDateLike","xmap","map","xfilter","filter","bind","bindMethods","NotFound","AdapterRegistry","registerComparator","compare","registerRepr","repr","objEqual","arrayEqual","concat","keyComparator","reverseKeyComparator","partial","merge","listMinMax","listMax","listMin","objMax","objMin","nodeWalk","zip","urlEncode","queryString","serializeJSON","registerJSON","evalJSON","parseQueryString","findValue","findIdentical","flattenArguments","method"];
+MochiKit.Base.EXPORT_OK=["nameFunctions","comparatorRegistry","reprRegistry","jsonRegistry","compareDateLike","compareArrayLike","reprArrayLike","reprString","reprNumber"];
+MochiKit.Base._exportSymbols=function(_127,_128){
+if(typeof (MochiKit.__export__)=="undefined"){
+MochiKit.__export__=(MochiKit.__compat__||(typeof (JSAN)=="undefined"&&typeof (dojo)=="undefined"));
+}
+if(!MochiKit.__export__){
+return;
+}
+var all=_128.EXPORT_TAGS[":all"];
+for(var i=0;i<all.length;i++){
+_127[all[i]]=_128[all[i]];
+}
+};
+MochiKit.Base.__new__=function(){
+var m=this;
+m.forward=m.forwardCall;
+m.find=m.findValue;
+if(typeof (encodeURIComponent)!="undefined"){
+m.urlEncode=function(_130){
+return encodeURIComponent(_130).replace(/\'/g,"%27");
+};
+}else{
+m.urlEncode=function(_131){
+return escape(_131).replace(/\+/g,"%2B").replace(/\"/g,"%22").rval.replace(/\'/g,"%27");
+};
+}
+m.NamedError=function(name){
+this.message=name;
+this.name=name;
+};
+m.NamedError.prototype=new Error();
+m.update(m.NamedError.prototype,{repr:function(){
+if(this.message&&this.message!=this.name){
+return this.name+"("+m.repr(this.message)+")";
+}else{
+return this.name+"()";
+}
+},toString:m.forwardCall("repr")});
+m.NotFound=new m.NamedError("MochiKit.Base.NotFound");
+m.listMax=m.partial(m.listMinMax,1);
+m.listMin=m.partial(m.listMinMax,-1);
+m.isCallable=m.typeMatcher("function");
+m.isUndefined=m.typeMatcher("undefined");
+m.merge=m.partial(m.update,null);
+m.zip=m.partial(m.map,null);
+m.comparatorRegistry=new m.AdapterRegistry();
+m.registerComparator("dateLike",m.isDateLike,m.compareDateLike);
+m.registerComparator("arrayLike",m.isArrayLike,m.compareArrayLike);
+m.reprRegistry=new m.AdapterRegistry();
+m.registerRepr("arrayLike",m.isArrayLike,m.reprArrayLike);
+m.registerRepr("string",m.typeMatcher("string"),m.reprString);
+m.registerRepr("numbers",m.typeMatcher("number","boolean"),m.reprNumber);
+m.jsonRegistry=new m.AdapterRegistry();
+var all=m.concat(m.EXPORT,m.EXPORT_OK);
+m.EXPORT_TAGS={":common":m.concat(m.EXPORT_OK),":all":all};
+m.nameFunctions(this);
+};
+MochiKit.Base.__new__();
+if(!MochiKit.__compat__){
+compare=MochiKit.Base.compare;
+}
+MochiKit.Base._exportSymbols(this,MochiKit.Base);
+if(typeof (dojo)!="undefined"){
+dojo.provide("MochiKit.Iter");
+dojo.require("MochiKit.Base");
+}
+if(typeof (JSAN)!="undefined"){
+JSAN.use("MochiKit.Base",[]);
+}
+try{
+if(typeof (MochiKit.Base)=="undefined"){
+throw "";
+}
+}
+catch(e){
+throw "MochiKit.Iter depends on MochiKit.Base!";
+}
+if(typeof (MochiKit.Iter)=="undefined"){
+MochiKit.Iter={};
+}
+MochiKit.Iter.NAME="MochiKit.Iter";
+MochiKit.Iter.VERSION="1.3.1";
+MochiKit.Base.update(MochiKit.Iter,{__repr__:function(){
+return "["+this.NAME+" "+this.VERSION+"]";
+},toString:function(){
+return this.__repr__();
+},registerIteratorFactory:function(name,_132,_133,_134){
+MochiKit.Iter.iteratorRegistry.register(name,_132,_133,_134);
+},iter:function(_135,_136){
+var self=MochiKit.Iter;
+if(arguments.length==2){
+return self.takewhile(function(a){
+return a!=_136;
+},_135);
+}
+if(typeof (_135.next)=="function"){
+return _135;
+}else{
+if(typeof (_135.iter)=="function"){
+return _135.iter();
+}
+}
+try{
+return self.iteratorRegistry.match(_135);
+}
+catch(e){
+var m=MochiKit.Base;
+if(e==m.NotFound){
+e=new TypeError(typeof (_135)+": "+m.repr(_135)+" is not iterable");
+}
+throw e;
+}
+},count:function(n){
+if(!n){
+n=0;
+}
+var m=MochiKit.Base;
+return {repr:function(){
+return "count("+n+")";
+},toString:m.forwardCall("repr"),next:m.counter(n)};
+},cycle:function(p){
+var self=MochiKit.Iter;
+var m=MochiKit.Base;
+var lst=[];
+var _139=self.iter(p);
+return {repr:function(){
+return "cycle(...)";
+},toString:m.forwardCall("repr"),next:function(){
+try{
+var rval=_139.next();
+lst.push(rval);
+return rval;
+}
+catch(e){
+if(e!=self.StopIteration){
+throw e;
+}
+if(lst.length===0){
+this.next=function(){
+throw self.StopIteration;
+};
+}else{
+var i=-1;
+this.next=function(){
+i=(i+1)%lst.length;
+return lst[i];
+};
+}
+return this.next();
+}
+}};
+},repeat:function(elem,n){
+var m=MochiKit.Base;
+if(typeof (n)=="undefined"){
+return {repr:function(){
+return "repeat("+m.repr(elem)+")";
+},toString:m.forwardCall("repr"),next:function(){
+return elem;
+}};
+}
+return {repr:function(){
+return "repeat("+m.repr(elem)+", "+n+")";
+},toString:m.forwardCall("repr"),next:function(){
+if(n<=0){
+throw MochiKit.Iter.StopIteration;
+}
+n-=1;
+return elem;
+}};
+},next:function(_141){
+return _141.next();
+},izip:function(p,q){
+var m=MochiKit.Base;
+var next=MochiKit.Iter.next;
+var _144=m.map(iter,arguments);
+return {repr:function(){
+return "izip(...)";
+},toString:m.forwardCall("repr"),next:function(){
+return m.map(next,_144);
+}};
+},ifilter:function(pred,seq){
+var m=MochiKit.Base;
+seq=MochiKit.Iter.iter(seq);
+if(pred===null){
+pred=m.operator.truth;
+}
+return {repr:function(){
+return "ifilter(...)";
+},toString:m.forwardCall("repr"),next:function(){
+while(true){
+var rval=seq.next();
+if(pred(rval)){
+return rval;
+}
+}
+return undefined;
+}};
+},ifilterfalse:function(pred,seq){
+var m=MochiKit.Base;
+seq=MochiKit.Iter.iter(seq);
+if(pred===null){
+pred=m.operator.truth;
+}
+return {repr:function(){
+return "ifilterfalse(...)";
+},toString:m.forwardCall("repr"),next:function(){
+while(true){
+var rval=seq.next();
+if(!pred(rval)){
+return rval;
+}
+}
+return undefined;
+}};
+},islice:function(seq){
+var self=MochiKit.Iter;
+var m=MochiKit.Base;
+seq=self.iter(seq);
+var _147=0;
+var stop=0;
+var step=1;
+var i=-1;
+if(arguments.length==2){
+stop=arguments[1];
+}else{
+if(arguments.length==3){
+_147=arguments[1];
+stop=arguments[2];
+}else{
+_147=arguments[1];
+stop=arguments[2];
+step=arguments[3];
+}
+}
+return {repr:function(){
+return "islice("+["...",_147,stop,step].join(", ")+")";
+},toString:m.forwardCall("repr"),next:function(){
+var rval;
+while(i<_147){
+rval=seq.next();
+i++;
+}
+if(_147>=stop){
+throw self.StopIteration;
+}
+_147+=step;
+return rval;
+}};
+},imap:function(fun,p,q){
+var m=MochiKit.Base;
+var self=MochiKit.Iter;
+var _151=m.map(self.iter,m.extend(null,arguments,1));
+var map=m.map;
+var next=self.next;
+return {repr:function(){
+return "imap(...)";
+},toString:m.forwardCall("repr"),next:function(){
+return fun.apply(this,map(next,_151));
+}};
+},applymap:function(fun,seq,self){
+seq=MochiKit.Iter.iter(seq);
+var m=MochiKit.Base;
+return {repr:function(){
+return "applymap(...)";
+},toString:m.forwardCall("repr"),next:function(){
+return fun.apply(self,seq.next());
+}};
+},chain:function(p,q){
+var self=MochiKit.Iter;
+var m=MochiKit.Base;
+if(arguments.length==1){
+return self.iter(arguments[0]);
+}
+var _153=m.map(self.iter,arguments);
+return {repr:function(){
+return "chain(...)";
+},toString:m.forwardCall("repr"),next:function(){
+while(_153.length>1){
+try{
+return _153[0].next();
+}
+catch(e){
+if(e!=self.StopIteration){
+throw e;
+}
+_153.shift();
+}
+}
+if(_153.length==1){
+var arg=_153.shift();
+this.next=m.bind("next",arg);
+return this.next();
+}
+throw self.StopIteration;
+}};
+},takewhile:function(pred,seq){
+var self=MochiKit.Iter;
+seq=self.iter(seq);
+return {repr:function(){
+return "takewhile(...)";
+},toString:MochiKit.Base.forwardCall("repr"),next:function(){
+var rval=seq.next();
+if(!pred(rval)){
+this.next=function(){
+throw self.StopIteration;
+};
+this.next();
+}
+return rval;
+}};
+},dropwhile:function(pred,seq){
+seq=MochiKit.Iter.iter(seq);
+var m=MochiKit.Base;
+var bind=m.bind;
+return {"repr":function(){
+return "dropwhile(...)";
+},"toString":m.forwardCall("repr"),"next":function(){
+while(true){
+var rval=seq.next();
+if(!pred(rval)){
+break;
+}
+}
+this.next=bind("next",seq);
+return rval;
+}};
+},_tee:function(_155,sync,_157){
+sync.pos[_155]=-1;
+var m=MochiKit.Base;
+var _158=m.listMin;
+return {repr:function(){
+return "tee("+_155+", ...)";
+},toString:m.forwardCall("repr"),next:function(){
+var rval;
+var i=sync.pos[_155];
+if(i==sync.max){
+rval=_157.next();
+sync.deque.push(rval);
+sync.max+=1;
+sync.pos[_155]+=1;
+}else{
+rval=sync.deque[i-sync.min];
+sync.pos[_155]+=1;
+if(i==sync.min&&_158(sync.pos)!=sync.min){
+sync.min+=1;
+sync.deque.shift();
+}
+}
+return rval;
+}};
+},tee:function(_159,n){
+var rval=[];
+var sync={"pos":[],"deque":[],"max":-1,"min":-1};
+if(arguments.length==1){
+n=2;
+}
+var self=MochiKit.Iter;
+_159=self.iter(_159);
+var _tee=self._tee;
+for(var i=0;i<n;i++){
+rval.push(_tee(i,sync,_159));
+}
+return rval;
+},list:function(_161){
+var m=MochiKit.Base;
+if(typeof (_161.slice)=="function"){
+return _161.slice();
+}else{
+if(m.isArrayLike(_161)){
+return m.concat(_161);
+}
+}
+var self=MochiKit.Iter;
+_161=self.iter(_161);
+var rval=[];
+try{
+while(true){
+rval.push(_161.next());
+}
+}
+catch(e){
+if(e!=self.StopIteration){
+throw e;
+}
+return rval;
+}
+return undefined;
+},reduce:function(fn,_162,_163){
+var i=0;
+var x=_163;
+var self=MochiKit.Iter;
+_162=self.iter(_162);
+if(arguments.length<3){
+try{
+x=_162.next();
+}
+catch(e){
+if(e==self.StopIteration){
+e=new TypeError("reduce() of empty sequence with no initial value");
+}
+throw e;
+}
+i++;
+}
+try{
+while(true){
+x=fn(x,_162.next());
+}
+}
+catch(e){
+if(e!=self.StopIteration){
+throw e;
+}
+}
+return x;
+},range:function(){
+var _165=0;
+var stop=0;
+var step=1;
+if(arguments.length==1){
+stop=arguments[0];
+}else{
+if(arguments.length==2){
+_165=arguments[0];
+stop=arguments[1];
+}else{
+if(arguments.length==3){
+_165=arguments[0];
+stop=arguments[1];
+step=arguments[2];
+}else{
+throw new TypeError("range() takes 1, 2, or 3 arguments!");
+}
+}
+}
+if(step===0){
+throw new TypeError("range() step must not be 0");
+}
+return {next:function(){
+if((step>0&&_165>=stop)||(step<0&&_165<=stop)){
+throw MochiKit.Iter.StopIteration;
+}
+var rval=_165;
+_165+=step;
+return rval;
+},repr:function(){
+return "range("+[_165,stop,step].join(", ")+")";
+},toString:MochiKit.Base.forwardCall("repr")};
+},sum:function(_166,_167){
+var x=_167||0;
+var self=MochiKit.Iter;
+_166=self.iter(_166);
+try{
+while(true){
+x+=_166.next();
+}
+}
+catch(e){
+if(e!=self.StopIteration){
+throw e;
+}
+}
+return x;
+},exhaust:function(_168){
+var self=MochiKit.Iter;
+_168=self.iter(_168);
+try{
+while(true){
+_168.next();
+}
+}
+catch(e){
+if(e!=self.StopIteration){
+throw e;
+}
+}
+},forEach:function(_169,func,self){
+var m=MochiKit.Base;
+if(arguments.length>2){
+func=m.bind(func,self);
+}
+if(m.isArrayLike(_169)){
+try{
+for(var i=0;i<_169.length;i++){
+func(_169[i]);
+}
+}
+catch(e){
+if(e!=MochiKit.Iter.StopIteration){
+throw e;
+}
+}
+}else{
+self=MochiKit.Iter;
+self.exhaust(self.imap(func,_169));
+}
+},every:function(_171,func){
+var self=MochiKit.Iter;
+try{
+self.ifilterfalse(func,_171).next();
+return false;
+}
+catch(e){
+if(e!=self.StopIteration){
+throw e;
+}
+return true;
+}
+},sorted:function(_172,cmp){
+var rval=MochiKit.Iter.list(_172);
+if(arguments.length==1){
+cmp=MochiKit.Base.compare;
+}
+rval.sort(cmp);
+return rval;
+},reversed:function(_173){
+var rval=MochiKit.Iter.list(_173);
+rval.reverse();
+return rval;
+},some:function(_174,func){
+var self=MochiKit.Iter;
+try{
+self.ifilter(func,_174).next();
+return true;
+}
+catch(e){
+if(e!=self.StopIteration){
+throw e;
+}
+return false;
+}
+},iextend:function(lst,_175){
+if(MochiKit.Base.isArrayLike(_175)){
+for(var i=0;i<_175.length;i++){
+lst.push(_175[i]);
+}
+}else{
+var self=MochiKit.Iter;
+_175=self.iter(_175);
+try{
+while(true){
+lst.push(_175.next());
+}
+}
+catch(e){
+if(e!=self.StopIteration){
+throw e;
+}
+}
+}
+return lst;
+},groupby:function(_176,_177){
+var m=MochiKit.Base;
+var self=MochiKit.Iter;
+if(arguments.length<2){
+_177=m.operator.identity;
+}
+_176=self.iter(_176);
+var pk=undefined;
+var k=undefined;
+var v;
+function fetch(){
+v=_176.next();
+k=_177(v);
+}
+function eat(){
+var ret=v;
+v=undefined;
+return ret;
+}
+var _180=true;
+return {repr:function(){
+return "groupby(...)";
+},next:function(){
+while(k==pk){
+fetch();
+if(_180){
+_180=false;
+break;
+}
+}
+pk=k;
+return [k,{next:function(){
+if(v==undefined){
+fetch();
+}
+if(k!=pk){
+throw self.StopIteration;
+}
+return eat();
+}}];
+}};
+},groupby_as_array:function(_181,_182){
+var m=MochiKit.Base;
+var self=MochiKit.Iter;
+if(arguments.length<2){
+_182=m.operator.identity;
+}
+_181=self.iter(_181);
+var _183=[];
+var _184=true;
+var _185;
+while(true){
+try{
+var _186=_181.next();
+var key=_182(_186);
+}
+catch(e){
+if(e==self.StopIteration){
+break;
+}
+throw e;
+}
+if(_184||key!=_185){
+var _187=[];
+_183.push([key,_187]);
+}
+_187.push(_186);
+_184=false;
+_185=key;
+}
+return _183;
+},arrayLikeIter:function(_188){
+var i=0;
+return {repr:function(){
+return "arrayLikeIter(...)";
+},toString:MochiKit.Base.forwardCall("repr"),next:function(){
+if(i>=_188.length){
+throw MochiKit.Iter.StopIteration;
+}
+return _188[i++];
+}};
+},hasIterateNext:function(_189){
+return (_189&&typeof (_189.iterateNext)=="function");
+},iterateNextIter:function(_190){
+return {repr:function(){
+return "iterateNextIter(...)";
+},toString:MochiKit.Base.forwardCall("repr"),next:function(){
+var rval=_190.iterateNext();
+if(rval===null||rval===undefined){
+throw MochiKit.Iter.StopIteration;
+}
+return rval;
+}};
+}});
+MochiKit.Iter.EXPORT_OK=["iteratorRegistry","arrayLikeIter","hasIterateNext","iterateNextIter",];
+MochiKit.Iter.EXPORT=["StopIteration","registerIteratorFactory","iter","count","cycle","repeat","next","izip","ifilter","ifilterfalse","islice","imap","applymap","chain","takewhile","dropwhile","tee","list","reduce","range","sum","exhaust","forEach","every","sorted","reversed","some","iextend","groupby","groupby_as_array"];
+MochiKit.Iter.__new__=function(){
+var m=MochiKit.Base;
+this.StopIteration=new m.NamedError("StopIteration");
+this.iteratorRegistry=new m.AdapterRegistry();
+this.registerIteratorFactory("arrayLike",m.isArrayLike,this.arrayLikeIter);
+this.registerIteratorFactory("iterateNext",this.hasIterateNext,this.iterateNextIter);
+this.EXPORT_TAGS={":common":this.EXPORT,":all":m.concat(this.EXPORT,this.EXPORT_OK)};
+m.nameFunctions(this);
+};
+MochiKit.Iter.__new__();
+if(!MochiKit.__compat__){
+reduce=MochiKit.Iter.reduce;
+}
+MochiKit.Base._exportSymbols(this,MochiKit.Iter);
+if(typeof (dojo)!="undefined"){
+dojo.provide("MochiKit.Logging");
+dojo.require("MochiKit.Base");
+}
+if(typeof (JSAN)!="undefined"){
+JSAN.use("MochiKit.Base",[]);
+}
+try{
+if(typeof (MochiKit.Base)=="undefined"){
+throw "";
+}
+}
+catch(e){
+throw "MochiKit.Logging depends on MochiKit.Base!";
+}
+if(typeof (MochiKit.Logging)=="undefined"){
+MochiKit.Logging={};
+}
+MochiKit.Logging.NAME="MochiKit.Logging";
+MochiKit.Logging.VERSION="1.3.1";
+MochiKit.Logging.__repr__=function(){
+return "["+this.NAME+" "+this.VERSION+"]";
+};
+MochiKit.Logging.toString=function(){
+return this.__repr__();
+};
+MochiKit.Logging.EXPORT=["LogLevel","LogMessage","Logger","alertListener","logger","log","logError","logDebug","logFatal","logWarning"];
+MochiKit.Logging.EXPORT_OK=["logLevelAtLeast","isLogMessage","compareLogMessage"];
+MochiKit.Logging.LogMessage=function(num,_192,info){
+this.num=num;
+this.level=_192;
+this.info=info;
+this.timestamp=new Date();
+};
+MochiKit.Logging.LogMessage.prototype={repr:function(){
+var m=MochiKit.Base;
+return "LogMessage("+m.map(m.repr,[this.num,this.level,this.info]).join(", ")+")";
+},toString:MochiKit.Base.forwardCall("repr")};
+MochiKit.Base.update(MochiKit.Logging,{logLevelAtLeast:function(_194){
+var self=MochiKit.Logging;
+if(typeof (_194)=="string"){
+_194=self.LogLevel[_194];
+}
+return function(msg){
+var _196=msg.level;
+if(typeof (_196)=="string"){
+_196=self.LogLevel[_196];
+}
+return _196>=_194;
+};
+},isLogMessage:function(){
+var _197=MochiKit.Logging.LogMessage;
+for(var i=0;i<arguments.length;i++){
+if(!(arguments[i] instanceof _197)){
+return false;
+}
+}
+return true;
+},compareLogMessage:function(a,b){
+return MochiKit.Base.compare([a.level,a.info],[b.level,b.info]);
+},alertListener:function(msg){
+alert("num: "+msg.num+"\nlevel: "+msg.level+"\ninfo: "+msg.info.join(" "));
+}});
+MochiKit.Logging.Logger=function(_198){
+this.counter=0;
+if(typeof (_198)=="undefined"||_198===null){
+_198=-1;
+}
+this.maxSize=_198;
+this._messages=[];
+this.listeners={};
+this.useNativeConsole=false;
+};
+MochiKit.Logging.Logger.prototype={clear:function(){
+this._messages.splice(0,this._messages.length);
+},logToConsole:function(msg){
+if(typeof (window)!="undefined"&&window.console&&window.console.log){
+window.console.log(msg);
+}else{
+if(typeof (opera)!="undefined"&&opera.postError){
+opera.postError(msg);
+}else{
+if(typeof (printfire)=="function"){
+printfire(msg);
+}
+}
+}
+},dispatchListeners:function(msg){
+for(var k in this.listeners){
+var pair=this.listeners[k];
+if(pair.ident!=k||(pair[0]&&!pair[0](msg))){
+continue;
+}
+pair[1](msg);
+}
+},addListener:function(_199,_200,_201){
+if(typeof (_200)=="string"){
+_200=MochiKit.Logging.logLevelAtLeast(_200);
+}
+var _202=[_200,_201];
+_202.ident=_199;
+this.listeners[_199]=_202;
+},removeListener:function(_203){
+delete this.listeners[_203];
+},baseLog:function(_204,_205){
+var msg=new MochiKit.Logging.LogMessage(this.counter,_204,MochiKit.Base.extend(null,arguments,1));
+this._messages.push(msg);
+this.dispatchListeners(msg);
+if(this.useNativeConsole){
+this.logToConsole(msg.level+": "+msg.info.join(" "));
+}
+this.counter+=1;
+while(this.maxSize>=0&&this._messages.length>this.maxSize){
+this._messages.shift();
+}
+},getMessages:function(_206){
+var _207=0;
+if(!(typeof (_206)=="undefined"||_206===null)){
+_207=Math.max(0,this._messages.length-_206);
+}
+return this._messages.slice(_207);
+},getMessageText:function(_208){
+if(typeof (_208)=="undefined"||_208===null){
+_208=30;
+}
+var _209=this.getMessages(_208);
+if(_209.length){
+var lst=map(function(m){
+return "\n ["+m.num+"] "+m.level+": "+m.info.join(" ");
+},_209);
+lst.unshift("LAST "+_209.length+" MESSAGES:");
+return lst.join("");
+}
+return "";
+},debuggingBookmarklet:function(_210){
+if(typeof (MochiKit.LoggingPane)=="undefined"){
+alert(this.getMessageText());
+}else{
+MochiKit.LoggingPane.createLoggingPane(_210||false);
+}
+}};
+MochiKit.Logging.__new__=function(){
+this.LogLevel={ERROR:40,FATAL:50,WARNING:30,INFO:20,DEBUG:10};
+var m=MochiKit.Base;
+m.registerComparator("LogMessage",this.isLogMessage,this.compareLogMessage);
+var _211=m.partial;
+var _212=this.Logger;
+var _213=_212.prototype.baseLog;
+m.update(this.Logger.prototype,{debug:_211(_213,"DEBUG"),log:_211(_213,"INFO"),error:_211(_213,"ERROR"),fatal:_211(_213,"FATAL"),warning:_211(_213,"WARNING")});
+var self=this;
+var _214=function(name){
+return function(){
+self.logger[name].apply(self.logger,arguments);
+};
+};
+this.log=_214("log");
+this.logError=_214("error");
+this.logDebug=_214("debug");
+this.logFatal=_214("fatal");
+this.logWarning=_214("warning");
+this.logger=new _212();
+this.logger.useNativeConsole=true;
+this.EXPORT_TAGS={":common":this.EXPORT,":all":m.concat(this.EXPORT,this.EXPORT_OK)};
+m.nameFunctions(this);
+};
+if(typeof (printfire)=="undefined"&&typeof (document)!="undefined"&&document.createEvent&&typeof (dispatchEvent)!="undefined"){
+printfire=function(){
+printfire.args=arguments;
+var ev=document.createEvent("Events");
+ev.initEvent("printfire",false,true);
+dispatchEvent(ev);
+};
+}
+MochiKit.Logging.__new__();
+MochiKit.Base._exportSymbols(this,MochiKit.Logging);
+if(typeof (dojo)!="undefined"){
+dojo.provide("MochiKit.DateTime");
+}
+if(typeof (MochiKit)=="undefined"){
+MochiKit={};
+}
+if(typeof (MochiKit.DateTime)=="undefined"){
+MochiKit.DateTime={};
+}
+MochiKit.DateTime.NAME="MochiKit.DateTime";
+MochiKit.DateTime.VERSION="1.3.1";
+MochiKit.DateTime.__repr__=function(){
+return "["+this.NAME+" "+this.VERSION+"]";
+};
+MochiKit.DateTime.toString=function(){
+return this.__repr__();
+};
+MochiKit.DateTime.isoDate=function(str){
+str=str+"";
+if(typeof (str)!="string"||str.length===0){
+return null;
+}
+var iso=str.split("-");
+if(iso.length===0){
+return null;
+}
+return new Date(iso[0],iso[1]-1,iso[2]);
+};
+MochiKit.DateTime._isoRegexp=/(\d{4,})(?:-(\d{1,2})(?:-(\d{1,2})(?:[T ](\d{1,2}):(\d{1,2})(?::(\d{1,2})(?:\.(\d+))?)?(?:(Z)|([+-])(\d{1,2})(?::(\d{1,2}))?)?)?)?)?/;
+MochiKit.DateTime.isoTimestamp=function(str){
+str=str+"";
+if(typeof (str)!="string"||str.length===0){
+return null;
+}
+var res=str.match(MochiKit.DateTime._isoRegexp);
+if(typeof (res)=="undefined"||res===null){
+return null;
+}
+var year,month,day,hour,min,sec,msec;
+year=parseInt(res[1],10);
+if(typeof (res[2])=="undefined"||res[2]===""){
+return new Date(year);
+}
+month=parseInt(res[2],10)-1;
+day=parseInt(res[3],10);
+if(typeof (res[4])=="undefined"||res[4]===""){
+return new Date(year,month,day);
+}
+hour=parseInt(res[4],10);
+min=parseInt(res[5],10);
+sec=(typeof (res[6])!="undefined"&&res[6]!=="")?parseInt(res[6],10):0;
+if(typeof (res[7])!="undefined"&&res[7]!==""){
+msec=Math.round(1000*parseFloat("0."+res[7]));
+}else{
+msec=0;
+}
+if((typeof (res[8])=="undefined"||res[8]==="")&&(typeof (res[9])=="undefined"||res[9]==="")){
+return new Date(year,month,day,hour,min,sec,msec);
+}
+var ofs;
+if(typeof (res[9])!="undefined"&&res[9]!==""){
+ofs=parseInt(res[10],10)*3600000;
+if(typeof (res[11])!="undefined"&&res[11]!==""){
+ofs+=parseInt(res[11],10)*60000;
+}
+if(res[9]=="-"){
+ofs=-ofs;
+}
+}else{
+ofs=0;
+}
+return new Date(Date.UTC(year,month,day,hour,min,sec,msec)-ofs);
+};
+MochiKit.DateTime.toISOTime=function(date,_221){
+if(typeof (date)=="undefined"||date===null){
+return null;
+}
+var hh=date.getHours();
+var mm=date.getMinutes();
+var ss=date.getSeconds();
+var lst=[((_221&&(hh<10))?"0"+hh:hh),((mm<10)?"0"+mm:mm),((ss<10)?"0"+ss:ss)];
+return lst.join(":");
+};
+MochiKit.DateTime.toISOTimestamp=function(date,_225){
+if(typeof (date)=="undefined"||date===null){
+return null;
+}
+var sep=_225?"T":" ";
+var foot=_225?"Z":"";
+if(_225){
+date=new Date(date.getTime()+(date.getTimezoneOffset()*60000));
+}
+return MochiKit.DateTime.toISODate(date)+sep+MochiKit.DateTime.toISOTime(date,_225)+foot;
+};
+MochiKit.DateTime.toISODate=function(date){
+if(typeof (date)=="undefined"||date===null){
+return null;
+}
+var _228=MochiKit.DateTime._padTwo;
+return [date.getFullYear(),_228(date.getMonth()+1),_228(date.getDate())].join("-");
+};
+MochiKit.DateTime.americanDate=function(d){
+d=d+"";
+if(typeof (d)!="string"||d.length===0){
+return null;
+}
+var a=d.split("/");
+return new Date(a[2],a[0]-1,a[1]);
+};
+MochiKit.DateTime._padTwo=function(n){
+return (n>9)?n:"0"+n;
+};
+MochiKit.DateTime.toPaddedAmericanDate=function(d){
+if(typeof (d)=="undefined"||d===null){
+return null;
+}
+var _230=MochiKit.DateTime._padTwo;
+return [_230(d.getMonth()+1),_230(d.getDate()),d.getFullYear()].join("/");
+};
+MochiKit.DateTime.toAmericanDate=function(d){
+if(typeof (d)=="undefined"||d===null){
+return null;
+}
+return [d.getMonth()+1,d.getDate(),d.getFullYear()].join("/");
+};
+MochiKit.DateTime.EXPORT=["isoDate","isoTimestamp","toISOTime","toISOTimestamp","toISODate","americanDate","toPaddedAmericanDate","toAmericanDate"];
+MochiKit.DateTime.EXPORT_OK=[];
+MochiKit.DateTime.EXPORT_TAGS={":common":MochiKit.DateTime.EXPORT,":all":MochiKit.DateTime.EXPORT};
+MochiKit.DateTime.__new__=function(){
+var base=this.NAME+".";
+for(var k in this){
+var o=this[k];
+if(typeof (o)=="function"&&typeof (o.NAME)=="undefined"){
+try{
+o.NAME=base+k;
+}
+catch(e){
+}
+}
+}
+};
+MochiKit.DateTime.__new__();
+if(typeof (MochiKit.Base)!="undefined"){
+MochiKit.Base._exportSymbols(this,MochiKit.DateTime);
+}else{
+(function(_231,_232){
+if((typeof (JSAN)=="undefined"&&typeof (dojo)=="undefined")||(typeof (MochiKit.__compat__)=="boolean"&&MochiKit.__compat__)){
+var all=_232.EXPORT_TAGS[":all"];
+for(var i=0;i<all.length;i++){
+_231[all[i]]=_232[all[i]];
+}
+}
+})(this,MochiKit.DateTime);
+}
+if(typeof (dojo)!="undefined"){
+dojo.provide("MochiKit.Format");
+}
+if(typeof (MochiKit)=="undefined"){
+MochiKit={};
+}
+if(typeof (MochiKit.Format)=="undefined"){
+MochiKit.Format={};
+}
+MochiKit.Format.NAME="MochiKit.Format";
+MochiKit.Format.VERSION="1.3.1";
+MochiKit.Format.__repr__=function(){
+return "["+this.NAME+" "+this.VERSION+"]";
+};
+MochiKit.Format.toString=function(){
+return this.__repr__();
+};
+MochiKit.Format._numberFormatter=function(_233,_234,_235,_236,_237,_238,_239,_240,_241){
+return function(num){
+num=parseFloat(num);
+if(typeof (num)=="undefined"||num===null||isNaN(num)){
+return _233;
+}
+var _242=_234;
+var _243=_235;
+if(num<0){
+num=-num;
+}else{
+_242=_242.replace(/-/,"");
+}
+var me=arguments.callee;
+var fmt=MochiKit.Format.formatLocale(_236);
+if(_237){
+num=num*100;
+_243=fmt.percent+_243;
+}
+num=MochiKit.Format.roundToFixed(num,_238);
+var _245=num.split(/\./);
+var _246=_245[0];
+var frac=(_245.length==1)?"":_245[1];
+var res="";
+while(_246.length<_239){
+_246="0"+_246;
+}
+if(_240){
+while(_246.length>_240){
+var i=_246.length-_240;
+res=fmt.separator+_246.substring(i,_246.length)+res;
+_246=_246.substring(0,i);
+}
+}
+res=_246+res;
+if(_238>0){
+while(frac.length<_241){
+frac=frac+"0";
+}
+res=res+fmt.decimal+frac;
+}
+return _242+res+_243;
+};
+};
+MochiKit.Format.numberFormatter=function(_248,_249,_250){
+if(typeof (_249)=="undefined"){
+_249="";
+}
+var _251=_248.match(/((?:[0#]+,)?[0#]+)(?:\.([0#]+))?(%)?/);
+if(!_251){
+throw TypeError("Invalid pattern");
+}
+var _252=_248.substr(0,_251.index);
+var _253=_248.substr(_251.index+_251[0].length);
+if(_252.search(/-/)==-1){
+_252=_252+"-";
+}
+var _254=_251[1];
+var frac=(typeof (_251[2])=="string"&&_251[2]!="")?_251[2]:"";
+var _255=(typeof (_251[3])=="string"&&_251[3]!="");
+var tmp=_254.split(/,/);
+var _257;
+if(typeof (_250)=="undefined"){
+_250="default";
+}
+if(tmp.length==1){
+_257=null;
+}else{
+_257=tmp[1].length;
+}
+var _258=_254.length-_254.replace(/0/g,"").length;
+var _259=frac.length-frac.replace(/0/g,"").length;
+var _260=frac.length;
+var rval=MochiKit.Format._numberFormatter(_249,_252,_253,_250,_255,_260,_258,_257,_259);
+var m=MochiKit.Base;
+if(m){
+var fn=arguments.callee;
+var args=m.concat(arguments);
+rval.repr=function(){
+return [self.NAME,"(",map(m.repr,args).join(", "),")"].join("");
+};
+}
+return rval;
+};
+MochiKit.Format.formatLocale=function(_262){
+if(typeof (_262)=="undefined"||_262===null){
+_262="default";
+}
+if(typeof (_262)=="string"){
+var rval=MochiKit.Format.LOCALE[_262];
+if(typeof (rval)=="string"){
+rval=arguments.callee(rval);
+MochiKit.Format.LOCALE[_262]=rval;
+}
+return rval;
+}else{
+return _262;
+}
+};
+MochiKit.Format.twoDigitAverage=function(_263,_264){
+if(_264){
+var res=_263/_264;
+if(!isNaN(res)){
+return MochiKit.Format.twoDigitFloat(_263/_264);
+}
+}
+return "0";
+};
+MochiKit.Format.twoDigitFloat=function(_265){
+var sign=(_265<0?"-":"");
+var s=Math.floor(Math.abs(_265)*100).toString();
+if(s=="0"){
+return s;
+}
+if(s.length<3){
+while(s.charAt(s.length-1)=="0"){
+s=s.substring(0,s.length-1);
+}
+return sign+"0."+s;
+}
+var head=sign+s.substring(0,s.length-2);
+var tail=s.substring(s.length-2,s.length);
+if(tail=="00"){
+return head;
+}else{
+if(tail.charAt(1)=="0"){
+return head+"."+tail.charAt(0);
+}else{
+return head+"."+tail;
+}
+}
+};
+MochiKit.Format.lstrip=function(str,_270){
+str=str+"";
+if(typeof (str)!="string"){
+return null;
+}
+if(!_270){
+return str.replace(/^\s+/,"");
+}else{
+return str.replace(new RegExp("^["+_270+"]+"),"");
+}
+};
+MochiKit.Format.rstrip=function(str,_271){
+str=str+"";
+if(typeof (str)!="string"){
+return null;
+}
+if(!_271){
+return str.replace(/\s+$/,"");
+}else{
+return str.replace(new RegExp("["+_271+"]+$"),"");
+}
+};
+MochiKit.Format.strip=function(str,_272){
+var self=MochiKit.Format;
+return self.rstrip(self.lstrip(str,_272),_272);
+};
+MochiKit.Format.truncToFixed=function(_273,_274){
+_273=Math.floor(_273*Math.pow(10,_274));
+var res=(_273*Math.pow(10,-_274)).toFixed(_274);
+if(res.charAt(0)=="."){
+res="0"+res;
+}
+return res;
+};
+MochiKit.Format.roundToFixed=function(_275,_276){
+return MochiKit.Format.truncToFixed(_275+0.5*Math.pow(10,-_276),_276);
+};
+MochiKit.Format.percentFormat=function(_277){
+return MochiKit.Format.twoDigitFloat(100*_277)+"%";
+};
+MochiKit.Format.EXPORT=["truncToFixed","roundToFixed","numberFormatter","formatLocale","twoDigitAverage","twoDigitFloat","percentFormat","lstrip","rstrip","strip"];
+MochiKit.Format.LOCALE={en_US:{separator:",",decimal:".",percent:"%"},de_DE:{separator:".",decimal:",",percent:"%"},fr_FR:{separator:" ",decimal:",",percent:"%"},"default":"en_US"};
+MochiKit.Format.EXPORT_OK=[];
+MochiKit.Format.EXPORT_TAGS={":all":MochiKit.Format.EXPORT,":common":MochiKit.Format.EXPORT};
+MochiKit.Format.__new__=function(){
+var base=this.NAME+".";
+var k,v,o;
+for(k in this.LOCALE){
+o=this.LOCALE[k];
+if(typeof (o)=="object"){
+o.repr=function(){
+return this.NAME;
+};
+o.NAME=base+"LOCALE."+k;
+}
+}
+for(k in this){
+o=this[k];
+if(typeof (o)=="function"&&typeof (o.NAME)=="undefined"){
+try{
+o.NAME=base+k;
+}
+catch(e){
+}
+}
+}
+};
+MochiKit.Format.__new__();
+if(typeof (MochiKit.Base)!="undefined"){
+MochiKit.Base._exportSymbols(this,MochiKit.Format);
+}else{
+(function(_278,_279){
+if((typeof (JSAN)=="undefined"&&typeof (dojo)=="undefined")||(typeof (MochiKit.__compat__)=="boolean"&&MochiKit.__compat__)){
+var all=_279.EXPORT_TAGS[":all"];
+for(var i=0;i<all.length;i++){
+_278[all[i]]=_279[all[i]];
+}
+}
+})(this,MochiKit.Format);
+}
+if(typeof (dojo)!="undefined"){
+dojo.provide("MochiKit.Async");
+dojo.require("MochiKit.Base");
+}
+if(typeof (JSAN)!="undefined"){
+JSAN.use("MochiKit.Base",[]);
+}
+try{
+if(typeof (MochiKit.Base)=="undefined"){
+throw "";
+}
+}
+catch(e){
+throw "MochiKit.Async depends on MochiKit.Base!";
+}
+if(typeof (MochiKit.Async)=="undefined"){
+MochiKit.Async={};
+}
+MochiKit.Async.NAME="MochiKit.Async";
+MochiKit.Async.VERSION="1.3.1";
+MochiKit.Async.__repr__=function(){
+return "["+this.NAME+" "+this.VERSION+"]";
+};
+MochiKit.Async.toString=function(){
+return this.__repr__();
+};
+MochiKit.Async.Deferred=function(_280){
+this.chain=[];
+this.id=this._nextId();
+this.fired=-1;
+this.paused=0;
+this.results=[null,null];
+this.canceller=_280;
+this.silentlyCancelled=false;
+this.chained=false;
+};
+MochiKit.Async.Deferred.prototype={repr:function(){
+var _281;
+if(this.fired==-1){
+_281="unfired";
+}else{
+if(this.fired===0){
+_281="success";
+}else{
+_281="error";
+}
+}
+return "Deferred("+this.id+", "+_281+")";
+},toString:MochiKit.Base.forwardCall("repr"),_nextId:MochiKit.Base.counter(),cancel:function(){
+var self=MochiKit.Async;
+if(this.fired==-1){
+if(this.canceller){
+this.canceller(this);
+}else{
+this.silentlyCancelled=true;
+}
+if(this.fired==-1){
+this.errback(new self.CancelledError(this));
+}
+}else{
+if((this.fired===0)&&(this.results[0] instanceof self.Deferred)){
+this.results[0].cancel();
+}
+}
+},_pause:function(){
+this.paused++;
+},_unpause:function(){
+this.paused--;
+if((this.paused===0)&&(this.fired>=0)){
+this._fire();
+}
+},_continue:function(res){
+this._resback(res);
+this._unpause();
+},_resback:function(res){
+this.fired=((res instanceof Error)?1:0);
+this.results[this.fired]=res;
+this._fire();
+},_check:function(){
+if(this.fired!=-1){
+if(!this.silentlyCancelled){
+throw new MochiKit.Async.AlreadyCalledError(this);
+}
+this.silentlyCancelled=false;
+return;
+}
+},callback:function(res){
+this._check();
+if(res instanceof MochiKit.Async.Deferred){
+throw new Error("Deferred instances can only be chained if they are the result of a callback");
+}
+this._resback(res);
+},errback:function(res){
+this._check();
+var self=MochiKit.Async;
+if(res instanceof self.Deferred){
+throw new Error("Deferred instances can only be chained if they are the result of a callback");
+}
+if(!(res instanceof Error)){
+res=new self.GenericError(res);
+}
+this._resback(res);
+},addBoth:function(fn){
+if(arguments.length>1){
+fn=MochiKit.Base.partial.apply(null,arguments);
+}
+return this.addCallbacks(fn,fn);
+},addCallback:function(fn){
+if(arguments.length>1){
+fn=MochiKit.Base.partial.apply(null,arguments);
+}
+return this.addCallbacks(fn,null);
+},addErrback:function(fn){
+if(arguments.length>1){
+fn=MochiKit.Base.partial.apply(null,arguments);
+}
+return this.addCallbacks(null,fn);
+},addCallbacks:function(cb,eb){
+if(this.chained){
+throw new Error("Chained Deferreds can not be re-used");
+}
+this.chain.push([cb,eb]);
+if(this.fired>=0){
+this._fire();
+}
+return this;
+},_fire:function(){
+var _284=this.chain;
+var _285=this.fired;
+var res=this.results[_285];
+var self=this;
+var cb=null;
+while(_284.length>0&&this.paused===0){
+var pair=_284.shift();
+var f=pair[_285];
+if(f===null){
+continue;
+}
+try{
+res=f(res);
+_285=((res instanceof Error)?1:0);
+if(res instanceof MochiKit.Async.Deferred){
+cb=function(res){
+self._continue(res);
+};
+this._pause();
+}
+}
+catch(err){
+_285=1;
+if(!(err instanceof Error)){
+err=new MochiKit.Async.GenericError(err);
+}
+res=err;
+}
+}
+this.fired=_285;
+this.results[_285]=res;
+if(cb&&this.paused){
+res.addBoth(cb);
+res.chained=true;
+}
+}};
+MochiKit.Base.update(MochiKit.Async,{evalJSONRequest:function(){
+return eval("("+arguments[0].responseText+")");
+},succeed:function(_287){
+var d=new MochiKit.Async.Deferred();
+d.callback.apply(d,arguments);
+return d;
+},fail:function(_288){
+var d=new MochiKit.Async.Deferred();
+d.errback.apply(d,arguments);
+return d;
+},getXMLHttpRequest:function(){
+var self=arguments.callee;
+if(!self.XMLHttpRequest){
+var _289=[function(){
+return new XMLHttpRequest();
+},function(){
+return new ActiveXObject("Msxml2.XMLHTTP");
+},function(){
+return new ActiveXObject("Microsoft.XMLHTTP");
+},function(){
+return new ActiveXObject("Msxml2.XMLHTTP.4.0");
+},function(){
+throw new MochiKit.Async.BrowserComplianceError("Browser does not support XMLHttpRequest");
+}];
+for(var i=0;i<_289.length;i++){
+var func=_289[i];
+try{
+self.XMLHttpRequest=func;
+return func();
+}
+catch(e){
+}
+}
+}
+return self.XMLHttpRequest();
+},_nothing:function(){
+},_xhr_onreadystatechange:function(d){
+if(this.readyState==4){
+try{
+this.onreadystatechange=null;
+}
+catch(e){
+try{
+this.onreadystatechange=MochiKit.Async._nothing;
+}
+catch(e){
+}
+}
+var _290=null;
+try{
+_290=this.status;
+if(!_290&&MochiKit.Base.isNotEmpty(this.responseText)){
+_290=304;
+}
+}
+catch(e){
+}
+if(_290==200||_290==304){
+d.callback(this);
+}else{
+var err=new MochiKit.Async.XMLHttpRequestError(this,"Request failed");
+if(err.number){
+d.errback(err);
+}else{
+d.errback(err);
+}
+}
+}
+},_xhr_canceller:function(req){
+try{
+req.onreadystatechange=null;
+}
+catch(e){
+try{
+req.onreadystatechange=MochiKit.Async._nothing;
+}
+catch(e){
+}
+}
+req.abort();
+},sendXMLHttpRequest:function(req,_293){
+if(typeof (_293)=="undefined"||_293===null){
+_293="";
+}
+var m=MochiKit.Base;
+var self=MochiKit.Async;
+var d=new self.Deferred(m.partial(self._xhr_canceller,req));
+try{
+req.onreadystatechange=m.bind(self._xhr_onreadystatechange,req,d);
+req.send(_293);
+}
+catch(e){
+try{
+req.onreadystatechange=null;
+}
+catch(ignore){
+}
+d.errback(e);
+}
+return d;
+},doSimpleXMLHttpRequest:function(url){
+var self=MochiKit.Async;
+var req=self.getXMLHttpRequest();
+if(arguments.length>1){
+var m=MochiKit.Base;
+var qs=m.queryString.apply(null,m.extend(null,arguments,1));
+if(qs){
+url+="?"+qs;
+}
+}
+req.open("GET",url,true);
+return self.sendXMLHttpRequest(req);
+},loadJSONDoc:function(url){
+var self=MochiKit.Async;
+var d=self.doSimpleXMLHttpRequest.apply(self,arguments);
+d=d.addCallback(self.evalJSONRequest);
+return d;
+},wait:function(_296,_297){
+var d=new MochiKit.Async.Deferred();
+var m=MochiKit.Base;
+if(typeof (_297)!="undefined"){
+d.addCallback(function(){
+return _297;
+});
+}
+var _298=setTimeout(m.bind("callback",d),Math.floor(_296*1000));
+d.canceller=function(){
+try{
+clearTimeout(_298);
+}
+catch(e){
+}
+};
+return d;
+},callLater:function(_299,func){
+var m=MochiKit.Base;
+var _300=m.partial.apply(m,m.extend(null,arguments,1));
+return MochiKit.Async.wait(_299).addCallback(function(res){
+return _300();
+});
+}});
+MochiKit.Async.DeferredLock=function(){
+this.waiting=[];
+this.locked=false;
+this.id=this._nextId();
+};
+MochiKit.Async.DeferredLock.prototype={__class__:MochiKit.Async.DeferredLock,acquire:function(){
+d=new MochiKit.Async.Deferred();
+if(this.locked){
+this.waiting.push(d);
+}else{
+this.locked=true;
+d.callback(this);
+}
+return d;
+},release:function(){
+if(!this.locked){
+throw TypeError("Tried to release an unlocked DeferredLock");
+}
+this.locked=false;
+if(this.waiting.length>0){
+this.locked=true;
+this.waiting.shift().callback(this);
+}
+},_nextId:MochiKit.Base.counter(),repr:function(){
+var _301;
+if(this.locked){
+_301="locked, "+this.waiting.length+" waiting";
+}else{
+_301="unlocked";
+}
+return "DeferredLock("+this.id+", "+_301+")";
+},toString:MochiKit.Base.forwardCall("repr")};
+MochiKit.Async.DeferredList=function(list,_303,_304,_305,_306){
+this.list=list;
+this.resultList=new Array(this.list.length);
+this.chain=[];
+this.id=this._nextId();
+this.fired=-1;
+this.paused=0;
+this.results=[null,null];
+this.canceller=_306;
+this.silentlyCancelled=false;
+if(this.list.length===0&&!_303){
+this.callback(this.resultList);
+}
+this.finishedCount=0;
+this.fireOnOneCallback=_303;
+this.fireOnOneErrback=_304;
+this.consumeErrors=_305;
+var _307=0;
+MochiKit.Base.map(MochiKit.Base.bind(function(d){
+d.addCallback(MochiKit.Base.bind(this._cbDeferred,this),_307,true);
+d.addErrback(MochiKit.Base.bind(this._cbDeferred,this),_307,false);
+_307+=1;
+},this),this.list);
+};
+MochiKit.Base.update(MochiKit.Async.DeferredList.prototype,MochiKit.Async.Deferred.prototype);
+MochiKit.Base.update(MochiKit.Async.DeferredList.prototype,{_cbDeferred:function(_308,_309,_310){
+this.resultList[_308]=[_309,_310];
+this.finishedCount+=1;
+if(this.fired!==0){
+if(_309&&this.fireOnOneCallback){
+this.callback([_308,_310]);
+}else{
+if(!_309&&this.fireOnOneErrback){
+this.errback(_310);
+}else{
+if(this.finishedCount==this.list.length){
+this.callback(this.resultList);
+}
+}
+}
+}
+if(!_309&&this.consumeErrors){
+_310=null;
+}
+return _310;
+}});
+MochiKit.Async.gatherResults=function(_311){
+var d=new MochiKit.Async.DeferredList(_311,false,true,false);
+d.addCallback(function(_312){
+var ret=[];
+for(var i=0;i<_312.length;i++){
+ret.push(_312[i][1]);
+}
+return ret;
+});
+return d;
+};
+MochiKit.Async.maybeDeferred=function(func){
+var self=MochiKit.Async;
+var _313;
+try{
+var r=func.apply(null,MochiKit.Base.extend([],arguments,1));
+if(r instanceof self.Deferred){
+_313=r;
+}else{
+if(r instanceof Error){
+_313=self.fail(r);
+}else{
+_313=self.succeed(r);
+}
+}
+}
+catch(e){
+_313=self.fail(e);
+}
+return _313;
+};
+MochiKit.Async.EXPORT=["AlreadyCalledError","CancelledError","BrowserComplianceError","GenericError","XMLHttpRequestError","Deferred","succeed","fail","getXMLHttpRequest","doSimpleXMLHttpRequest","loadJSONDoc","wait","callLater","sendXMLHttpRequest","DeferredLock","DeferredList","gatherResults","maybeDeferred"];
+MochiKit.Async.EXPORT_OK=["evalJSONRequest"];
+MochiKit.Async.__new__=function(){
+var m=MochiKit.Base;
+var ne=m.partial(m._newNamedError,this);
+ne("AlreadyCalledError",function(_316){
+this.deferred=_316;
+});
+ne("CancelledError",function(_317){
+this.deferred=_317;
+});
+ne("BrowserComplianceError",function(msg){
+this.message=msg;
+});
+ne("GenericError",function(msg){
+this.message=msg;
+});
+ne("XMLHttpRequestError",function(req,msg){
+this.req=req;
+this.message=msg;
+try{
+this.number=req.status;
+}
+catch(e){
+}
+});
+this.EXPORT_TAGS={":common":this.EXPORT,":all":m.concat(this.EXPORT,this.EXPORT_OK)};
+m.nameFunctions(this);
+};
+MochiKit.Async.__new__();
+MochiKit.Base._exportSymbols(this,MochiKit.Async);
+if(typeof (dojo)!="undefined"){
+dojo.provide("MochiKit.DOM");
+dojo.require("MochiKit.Iter");
+}
+if(typeof (JSAN)!="undefined"){
+JSAN.use("MochiKit.Iter",[]);
+}
+try{
+if(typeof (MochiKit.Iter)=="undefined"){
+throw "";
+}
+}
+catch(e){
+throw "MochiKit.DOM depends on MochiKit.Iter!";
+}
+if(typeof (MochiKit.DOM)=="undefined"){
+MochiKit.DOM={};
+}
+MochiKit.DOM.NAME="MochiKit.DOM";
+MochiKit.DOM.VERSION="1.3.1";
+MochiKit.DOM.__repr__=function(){
+return "["+this.NAME+" "+this.VERSION+"]";
+};
+MochiKit.DOM.toString=function(){
+return this.__repr__();
+};
+MochiKit.DOM.EXPORT=["formContents","currentWindow","currentDocument","withWindow","withDocument","registerDOMConverter","coerceToDOM","createDOM","createDOMFunc","getNodeAttribute","setNodeAttribute","updateNodeAttributes","appendChildNodes","replaceChildNodes","removeElement","swapDOM","BUTTON","TT","PRE","H1","H2","H3","BR","CANVAS","HR","LABEL","TEXTAREA","FORM","STRONG","SELECT","OPTION","OPTGROUP","LEGEND","FIELDSET","P","UL","OL","LI","TD","TR","THEAD","TBODY","TFOOT","TABLE","TH","INPUT","SPAN","A","DIV","IMG","getElement","$","computedStyle","getElementsByTagAndClassName","addToCallStack","addLoadEvent","focusOnLoad","setElementClass","toggleElementClass","addElementClass","removeElementClass","swapElementClass","hasElementClass","escapeHTML","toHTML","emitHTML","setDisplayForElement","hideElement","showElement","scrapeText","elementDimensions","elementPosition","setElementDimensions","setElementPosition","getViewportDimensions","setOpacity"];
+MochiKit.DOM.EXPORT_OK=["domConverters"];
+MochiKit.DOM.Dimensions=function(w,h){
+this.w=w;
+this.h=h;
+};
+MochiKit.DOM.Dimensions.prototype.repr=function(){
+var repr=MochiKit.Base.repr;
+return "{w: "+repr(this.w)+", h: "+repr(this.h)+"}";
+};
+MochiKit.DOM.Coordinates=function(x,y){
+this.x=x;
+this.y=y;
+};
+MochiKit.DOM.Coordinates.prototype.repr=function(){
+var repr=MochiKit.Base.repr;
+return "{x: "+repr(this.x)+", y: "+repr(this.y)+"}";
+};
+MochiKit.DOM.Coordinates.prototype.toString=function(){
+return this.repr();
+};
+MochiKit.Base.update(MochiKit.DOM,{setOpacity:function(elem,o){
+elem=MochiKit.DOM.getElement(elem);
+MochiKit.DOM.updateNodeAttributes(elem,{"style":{"opacity":o,"-moz-opacity":o,"-khtml-opacity":o,"filter":" alpha(opacity="+(o*100)+")"}});
+},getViewportDimensions:function(){
+var d=new MochiKit.DOM.Dimensions();
+var w=MochiKit.DOM._window;
+var b=MochiKit.DOM._document.body;
+if(w.innerWidth){
+d.w=w.innerWidth;
+d.h=w.innerHeight;
+}else{
+if(b.parentElement.clientWidth){
+d.w=b.parentElement.clientWidth;
+d.h=b.parentElement.clientHeight;
+}else{
+if(b&&b.clientWidth){
+d.w=b.clientWidth;
+d.h=b.clientHeight;
+}
+}
+}
+return d;
+},elementDimensions:function(elem){
+var self=MochiKit.DOM;
+if(typeof (elem.w)=="number"||typeof (elem.h)=="number"){
+return new self.Dimensions(elem.w||0,elem.h||0);
+}
+elem=self.getElement(elem);
+if(!elem){
+return undefined;
+}
+if(self.computedStyle(elem,"display")!="none"){
+return new self.Dimensions(elem.offsetWidth||0,elem.offsetHeight||0);
+}
+var s=elem.style;
+var _322=s.visibility;
+var _323=s.position;
+s.visibility="hidden";
+s.position="absolute";
+s.display="";
+var _324=elem.offsetWidth;
+var _325=elem.offsetHeight;
+s.display="none";
+s.position=_323;
+s.visibility=_322;
+return new self.Dimensions(_324,_325);
+},elementPosition:function(elem,_326){
+var self=MochiKit.DOM;
+elem=self.getElement(elem);
+if(!elem){
+return undefined;
+}
+var c=new self.Coordinates(0,0);
+if(elem.x&&elem.y){
+c.x+=elem.x||0;
+c.y+=elem.y||0;
+return c;
+}else{
+if(elem.parentNode===null||self.computedStyle(elem,"display")=="none"){
+return undefined;
+}
+}
+var box=null;
+var _329=null;
+var d=MochiKit.DOM._document;
+var de=d.documentElement;
+var b=d.body;
+if(elem.getBoundingClientRect){
+box=elem.getBoundingClientRect();
+c.x+=box.left+(de.scrollLeft||b.scrollLeft)-(de.clientLeft||b.clientLeft);
+c.y+=box.top+(de.scrollTop||b.scrollTop)-(de.clientTop||b.clientTop);
+}else{
+if(d.getBoxObjectFor){
+box=d.getBoxObjectFor(elem);
+c.x+=box.x;
+c.y+=box.y;
+}else{
+if(elem.offsetParent){
+c.x+=elem.offsetLeft;
+c.y+=elem.offsetTop;
+_329=elem.offsetParent;
+if(_329!=elem){
+while(_329){
+c.x+=_329.offsetLeft;
+c.y+=_329.offsetTop;
+_329=_329.offsetParent;
+}
+}
+var ua=navigator.userAgent.toLowerCase();
+if((typeof (opera)!="undefined"&&parseFloat(opera.version())<9)||(ua.indexOf("safari")!=-1&&self.computedStyle(elem,"position")=="absolute")){
+c.x-=b.offsetLeft;
+c.y-=b.offsetTop;
+}
+}
+}
+}
+if(typeof (_326)!="undefined"){
+_326=arguments.callee(_326);
+if(_326){
+c.x-=(_326.x||0);
+c.y-=(_326.y||0);
+}
+}
+if(elem.parentNode){
+_329=elem.parentNode;
+}else{
+_329=null;
+}
+while(_329&&_329.tagName!="BODY"&&_329.tagName!="HTML"){
+c.x-=_329.scrollLeft;
+c.y-=_329.scrollTop;
+if(_329.parentNode){
+_329=_329.parentNode;
+}else{
+_329=null;
+}
+}
+return c;
+},setElementDimensions:function(elem,_332,_333){
+elem=MochiKit.DOM.getElement(elem);
+if(typeof (_333)=="undefined"){
+_333="px";
+}
+MochiKit.DOM.updateNodeAttributes(elem,{"style":{"width":_332.w+_333,"height":_332.h+_333}});
+},setElementPosition:function(elem,_334,_335){
+elem=MochiKit.DOM.getElement(elem);
+if(typeof (_335)=="undefined"){
+_335="px";
+}
+MochiKit.DOM.updateNodeAttributes(elem,{"style":{"left":_334.x+_335,"top":_334.y+_335}});
+},currentWindow:function(){
+return MochiKit.DOM._window;
+},currentDocument:function(){
+return MochiKit.DOM._document;
+},withWindow:function(win,func){
+var self=MochiKit.DOM;
+var _337=self._document;
+var _338=self._win;
+var rval;
+try{
+self._window=win;
+self._document=win.document;
+rval=func();
+}
+catch(e){
+self._window=_338;
+self._document=_337;
+throw e;
+}
+self._window=_338;
+self._document=_337;
+return rval;
+},formContents:function(elem){
+var _339=[];
+var _340=[];
+var m=MochiKit.Base;
+var self=MochiKit.DOM;
+if(typeof (elem)=="undefined"||elem===null){
+elem=self._document;
+}else{
+elem=self.getElement(elem);
+}
+m.nodeWalk(elem,function(elem){
+var name=elem.name;
+if(m.isNotEmpty(name)){
+var _341=elem.nodeName;
+if(_341=="INPUT"&&(elem.type=="radio"||elem.type=="checkbox")&&!elem.checked){
+return null;
+}
+if(_341=="SELECT"){
+if(elem.selectedIndex>=0){
+var opt=elem.options[elem.selectedIndex];
+_339.push(name);
+_340.push((opt.value)?opt.value:opt.text);
+return null;
+}
+_339.push(name);
+_340.push("");
+return null;
+}
+if(_341=="FORM"||_341=="P"||_341=="SPAN"||_341=="DIV"){
+return elem.childNodes;
+}
+_339.push(name);
+_340.push(elem.value||"");
+return null;
+}
+return elem.childNodes;
+});
+return [_339,_340];
+},withDocument:function(doc,func){
+var self=MochiKit.DOM;
+var _344=self._document;
+var rval;
+try{
+self._document=doc;
+rval=func();
+}
+catch(e){
+self._document=_344;
+throw e;
+}
+self._document=_344;
+return rval;
+},registerDOMConverter:function(name,_345,wrap,_346){
+MochiKit.DOM.domConverters.register(name,_345,wrap,_346);
+},coerceToDOM:function(node,ctx){
+var im=MochiKit.Iter;
+var self=MochiKit.DOM;
+var iter=im.iter;
+var _350=im.repeat;
+var imap=im.imap;
+var _352=self.domConverters;
+var _353=self.coerceToDOM;
+var _354=MochiKit.Base.NotFound;
+while(true){
+if(typeof (node)=="undefined"||node===null){
+return null;
+}
+if(typeof (node.nodeType)!="undefined"&&node.nodeType>0){
+return node;
+}
+if(typeof (node)=="number"||typeof (node)=="boolean"){
+node=node.toString();
+}
+if(typeof (node)=="string"){
+return self._document.createTextNode(node);
+}
+if(typeof (node.toDOM)=="function"){
+node=node.toDOM(ctx);
+continue;
+}
+if(typeof (node)=="function"){
+node=node(ctx);
+continue;
+}
+var _355=null;
+try{
+_355=iter(node);
+}
+catch(e){
+}
+if(_355){
+return imap(_353,_355,_350(ctx));
+}
+try{
+node=_352.match(node,ctx);
+continue;
+}
+catch(e){
+if(e!=_354){
+throw e;
+}
+}
+return self._document.createTextNode(node.toString());
+}
+return undefined;
+},setNodeAttribute:function(node,attr,_357){
+var o={};
+o[attr]=_357;
+try{
+return MochiKit.DOM.updateNodeAttributes(node,o);
+}
+catch(e){
+}
+return null;
+},getNodeAttribute:function(node,attr){
+var self=MochiKit.DOM;
+var _358=self.attributeArray.renames[attr];
+node=self.getElement(node);
+try{
+if(_358){
+return node[_358];
+}
+return node.getAttribute(attr);
+}
+catch(e){
+}
+return null;
+},updateNodeAttributes:function(node,_359){
+var elem=node;
+var self=MochiKit.DOM;
+if(typeof (node)=="string"){
+elem=self.getElement(node);
+}
+if(_359){
+var _360=MochiKit.Base.updatetree;
+if(self.attributeArray.compliant){
+for(var k in _359){
+var v=_359[k];
+if(typeof (v)=="object"&&typeof (elem[k])=="object"){
+_360(elem[k],v);
+}else{
+if(k.substring(0,2)=="on"){
+if(typeof (v)=="string"){
+v=new Function(v);
+}
+elem[k]=v;
+}else{
+elem.setAttribute(k,v);
+}
+}
+}
+}else{
+var _361=self.attributeArray.renames;
+for(k in _359){
+v=_359[k];
+var _362=_361[k];
+if(k=="style"&&typeof (v)=="string"){
+elem.style.cssText=v;
+}else{
+if(typeof (_362)=="string"){
+elem[_362]=v;
+}else{
+if(typeof (elem[k])=="object"&&typeof (v)=="object"){
+_360(elem[k],v);
+}else{
+if(k.substring(0,2)=="on"){
+if(typeof (v)=="string"){
+v=new Function(v);
+}
+elem[k]=v;
+}else{
+elem.setAttribute(k,v);
+}
+}
+}
+}
+}
+}
+}
+return elem;
+},appendChildNodes:function(node){
+var elem=node;
+var self=MochiKit.DOM;
+if(typeof (node)=="string"){
+elem=self.getElement(node);
+}
+var _363=[self.coerceToDOM(MochiKit.Base.extend(null,arguments,1),elem)];
+var _364=MochiKit.Base.concat;
+while(_363.length){
+var n=_363.shift();
+if(typeof (n)=="undefined"||n===null){
+}else{
+if(typeof (n.nodeType)=="number"){
+elem.appendChild(n);
+}else{
+_363=_364(n,_363);
+}
+}
+}
+return elem;
+},replaceChildNodes:function(node){
+var elem=node;
+var self=MochiKit.DOM;
+if(typeof (node)=="string"){
+elem=self.getElement(node);
+arguments[0]=elem;
+}
+var _365;
+while((_365=elem.firstChild)){
+elem.removeChild(_365);
+}
+if(arguments.length<2){
+return elem;
+}else{
+return self.appendChildNodes.apply(this,arguments);
+}
+},createDOM:function(name,_366){
+var elem;
+var self=MochiKit.DOM;
+var m=MochiKit.Base;
+if(typeof (_366)=="string"||typeof (_366)=="number"){
+var args=m.extend([name,null],arguments,1);
+return arguments.callee.apply(this,args);
+}
+if(typeof (name)=="string"){
+if(_366&&"name" in _366&&!self.attributeArray.compliant){
+name=("<"+name+" name=\""+self.escapeHTML(_366.name)+"\">");
+}
+elem=self._document.createElement(name);
+}else{
+elem=name;
+}
+if(_366){
+self.updateNodeAttributes(elem,_366);
+}
+if(arguments.length<=2){
+return elem;
+}else{
+var args=m.extend([elem],arguments,2);
+return self.appendChildNodes.apply(this,args);
+}
+},createDOMFunc:function(){
+var m=MochiKit.Base;
+return m.partial.apply(this,m.extend([MochiKit.DOM.createDOM],arguments));
+},swapDOM:function(dest,src){
+var self=MochiKit.DOM;
+dest=self.getElement(dest);
+var _369=dest.parentNode;
+if(src){
+src=self.getElement(src);
+_369.replaceChild(src,dest);
+}else{
+_369.removeChild(dest);
+}
+return src;
+},getElement:function(id){
+var self=MochiKit.DOM;
+if(arguments.length==1){
+return ((typeof (id)=="string")?self._document.getElementById(id):id);
+}else{
+return MochiKit.Base.map(self.getElement,arguments);
+}
+},computedStyle:function(_371,_372,_373){
+if(arguments.length==2){
+_373=_372;
+}
+var self=MochiKit.DOM;
+var el=self.getElement(_371);
+var _375=self._document;
+if(!el||el==_375){
+return undefined;
+}
+if(el.currentStyle){
+return el.currentStyle[_372];
+}
+if(typeof (_375.defaultView)=="undefined"){
+return undefined;
+}
+if(_375.defaultView===null){
+return undefined;
+}
+var _376=_375.defaultView.getComputedStyle(el,null);
+if(typeof (_376)=="undefined"||_376===null){
+return undefined;
+}
+return _376.getPropertyValue(_373);
+},getElementsByTagAndClassName:function(_377,_378,_379){
+var self=MochiKit.DOM;
+if(typeof (_377)=="undefined"||_377===null){
+_377="*";
+}
+if(typeof (_379)=="undefined"||_379===null){
+_379=self._document;
+}
+_379=self.getElement(_379);
+var _380=(_379.getElementsByTagName(_377)||self._document.all);
+if(typeof (_378)=="undefined"||_378===null){
+return MochiKit.Base.extend(null,_380);
+}
+var _381=[];
+for(var i=0;i<_380.length;i++){
+var _382=_380[i];
+var _383=_382.className.split(" ");
+for(var j=0;j<_383.length;j++){
+if(_383[j]==_378){
+_381.push(_382);
+break;
+}
+}
+}
+return _381;
+},_newCallStack:function(path,once){
+var rval=function(){
+var _386=arguments.callee.callStack;
+for(var i=0;i<_386.length;i++){
+if(_386[i].apply(this,arguments)===false){
+break;
+}
+}
+if(once){
+try{
+this[path]=null;
+}
+catch(e){
+}
+}
+};
+rval.callStack=[];
+return rval;
+},addToCallStack:function(_387,path,func,once){
+var self=MochiKit.DOM;
+var _388=_387[path];
+var _389=_388;
+if(!(typeof (_388)=="function"&&typeof (_388.callStack)=="object"&&_388.callStack!==null)){
+_389=self._newCallStack(path,once);
+if(typeof (_388)=="function"){
+_389.callStack.push(_388);
+}
+_387[path]=_389;
+}
+_389.callStack.push(func);
+},addLoadEvent:function(func){
+var self=MochiKit.DOM;
+self.addToCallStack(self._window,"onload",func,true);
+},focusOnLoad:function(_390){
+var self=MochiKit.DOM;
+self.addLoadEvent(function(){
+_390=self.getElement(_390);
+if(_390){
+_390.focus();
+}
+});
+},setElementClass:function(_391,_392){
+var self=MochiKit.DOM;
+var obj=self.getElement(_391);
+if(self.attributeArray.compliant){
+obj.setAttribute("class",_392);
+}else{
+obj.setAttribute("className",_392);
+}
+},toggleElementClass:function(_393){
+var self=MochiKit.DOM;
+for(var i=1;i<arguments.length;i++){
+var obj=self.getElement(arguments[i]);
+if(!self.addElementClass(obj,_393)){
+self.removeElementClass(obj,_393);
+}
+}
+},addElementClass:function(_394,_395){
+var self=MochiKit.DOM;
+var obj=self.getElement(_394);
+var cls=obj.className;
+if(cls.length===0){
+self.setElementClass(obj,_395);
+return true;
+}
+if(cls==_395){
+return false;
+}
+var _397=obj.className.split(" ");
+for(var i=0;i<_397.length;i++){
+if(_397[i]==_395){
+return false;
+}
+}
+self.setElementClass(obj,cls+" "+_395);
+return true;
+},removeElementClass:function(_398,_399){
+var self=MochiKit.DOM;
+var obj=self.getElement(_398);
+var cls=obj.className;
+if(cls.length===0){
+return false;
+}
+if(cls==_399){
+self.setElementClass(obj,"");
+return true;
+}
+var _400=obj.className.split(" ");
+for(var i=0;i<_400.length;i++){
+if(_400[i]==_399){
+_400.splice(i,1);
+self.setElementClass(obj,_400.join(" "));
+return true;
+}
+}
+return false;
+},swapElementClass:function(_401,_402,_403){
+var obj=MochiKit.DOM.getElement(_401);
+var res=MochiKit.DOM.removeElementClass(obj,_402);
+if(res){
+MochiKit.DOM.addElementClass(obj,_403);
+}
+return res;
+},hasElementClass:function(_404,_405){
+var obj=MochiKit.DOM.getElement(_404);
+var _406=obj.className.split(" ");
+for(var i=1;i<arguments.length;i++){
+var good=false;
+for(var j=0;j<_406.length;j++){
+if(_406[j]==arguments[i]){
+good=true;
+break;
+}
+}
+if(!good){
+return false;
+}
+}
+return true;
+},escapeHTML:function(s){
+return s.replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/</g,"&lt;").replace(/>/g,"&gt;");
+},toHTML:function(dom){
+return MochiKit.DOM.emitHTML(dom).join("");
+},emitHTML:function(dom,lst){
+if(typeof (lst)=="undefined"||lst===null){
+lst=[];
+}
+var _409=[dom];
+var self=MochiKit.DOM;
+var _410=self.escapeHTML;
+var _411=self.attributeArray;
+while(_409.length){
+dom=_409.pop();
+if(typeof (dom)=="string"){
+lst.push(dom);
+}else{
+if(dom.nodeType==1){
+lst.push("<"+dom.nodeName.toLowerCase());
+var _412=[];
+var _413=_411(dom);
+for(var i=0;i<_413.length;i++){
+var a=_413[i];
+_412.push([" ",a.name,"=\"",_410(a.value),"\""]);
+}
+_412.sort();
+for(i=0;i<_412.length;i++){
+var _414=_412[i];
+for(var j=0;j<_414.length;j++){
+lst.push(_414[j]);
+}
+}
+if(dom.hasChildNodes()){
+lst.push(">");
+_409.push("</"+dom.nodeName.toLowerCase()+">");
+var _415=dom.childNodes;
+for(i=_415.length-1;i>=0;i--){
+_409.push(_415[i]);
+}
+}else{
+lst.push("/>");
+}
+}else{
+if(dom.nodeType==3){
+lst.push(_410(dom.nodeValue));
+}
+}
+}
+}
+return lst;
+},setDisplayForElement:function(_416,_417){
+var m=MochiKit.Base;
+var _418=m.extend(null,arguments,1);
+MochiKit.Iter.forEach(m.filter(null,m.map(MochiKit.DOM.getElement,_418)),function(_417){
+_417.style.display=_416;
+});
+},scrapeText:function(node,_419){
+var rval=[];
+(function(node){
+var cn=node.childNodes;
+if(cn){
+for(var i=0;i<cn.length;i++){
+arguments.callee.call(this,cn[i]);
+}
+}
+var _421=node.nodeValue;
+if(typeof (_421)=="string"){
+rval.push(_421);
+}
+})(MochiKit.DOM.getElement(node));
+if(_419){
+return rval;
+}else{
+return rval.join("");
+}
+},__new__:function(win){
+var m=MochiKit.Base;
+this._document=document;
+this._window=win;
+this.domConverters=new m.AdapterRegistry();
+var _422=this._document.createElement("span");
+var _423;
+if(_422&&_422.attributes&&_422.attributes.length>0){
+var _424=m.filter;
+_423=function(node){
+return _424(_423.ignoreAttrFilter,node.attributes);
+};
+_423.ignoreAttr={};
+MochiKit.Iter.forEach(_422.attributes,function(a){
+_423.ignoreAttr[a.name]=a.value;
+});
+_423.ignoreAttrFilter=function(a){
+return (_423.ignoreAttr[a.name]!=a.value);
+};
+_423.compliant=false;
+_423.renames={"class":"className","checked":"defaultChecked","usemap":"useMap","for":"htmlFor"};
+}else{
+_423=function(node){
+return node.attributes;
+};
+_423.compliant=true;
+_423.renames={};
+}
+this.attributeArray=_423;
+var _425=this.createDOMFunc;
+this.UL=_425("ul");
+this.OL=_425("ol");
+this.LI=_425("li");
+this.TD=_425("td");
+this.TR=_425("tr");
+this.TBODY=_425("tbody");
+this.THEAD=_425("thead");
+this.TFOOT=_425("tfoot");
+this.TABLE=_425("table");
+this.TH=_425("th");
+this.INPUT=_425("input");
+this.SPAN=_425("span");
+this.A=_425("a");
+this.DIV=_425("div");
+this.IMG=_425("img");
+this.BUTTON=_425("button");
+this.TT=_425("tt");
+this.PRE=_425("pre");
+this.H1=_425("h1");
+this.H2=_425("h2");
+this.H3=_425("h3");
+this.BR=_425("br");
+this.HR=_425("hr");
+this.LABEL=_425("label");
+this.TEXTAREA=_425("textarea");
+this.FORM=_425("form");
+this.P=_425("p");
+this.SELECT=_425("select");
+this.OPTION=_425("option");
+this.OPTGROUP=_425("optgroup");
+this.LEGEND=_425("legend");
+this.FIELDSET=_425("fieldset");
+this.STRONG=_425("strong");
+this.CANVAS=_425("canvas");
+this.hideElement=m.partial(this.setDisplayForElement,"none");
+this.showElement=m.partial(this.setDisplayForElement,"block");
+this.removeElement=this.swapDOM;
+this.$=this.getElement;
+this.EXPORT_TAGS={":common":this.EXPORT,":all":m.concat(this.EXPORT,this.EXPORT_OK)};
+m.nameFunctions(this);
+}});
+MochiKit.DOM.__new__(((typeof (window)=="undefined")?this:window));
+if(!MochiKit.__compat__){
+withWindow=MochiKit.DOM.withWindow;
+withDocument=MochiKit.DOM.withDocument;
+}
+MochiKit.Base._exportSymbols(this,MochiKit.DOM);
+if(typeof (dojo)!="undefined"){
+dojo.provide("MochiKit.LoggingPane");
+dojo.require("MochiKit.Logging");
+dojo.require("MochiKit.Base");
+}
+if(typeof (JSAN)!="undefined"){
+JSAN.use("MochiKit.Logging",[]);
+JSAN.use("MochiKit.Base",[]);
+}
+try{
+if(typeof (MochiKit.Base)=="undefined"||typeof (MochiKit.Logging)=="undefined"){
+throw "";
+}
+}
+catch(e){
+throw "MochiKit.LoggingPane depends on MochiKit.Base and MochiKit.Logging!";
+}
+if(typeof (MochiKit.LoggingPane)=="undefined"){
+MochiKit.LoggingPane={};
+}
+MochiKit.LoggingPane.NAME="MochiKit.LoggingPane";
+MochiKit.LoggingPane.VERSION="1.3.1";
+MochiKit.LoggingPane.__repr__=function(){
+return "["+this.NAME+" "+this.VERSION+"]";
+};
+MochiKit.LoggingPane.toString=function(){
+return this.__repr__();
+};
+MochiKit.LoggingPane.createLoggingPane=function(_426){
+var m=MochiKit.LoggingPane;
+_426=!(!_426);
+if(m._loggingPane&&m._loggingPane.inline!=_426){
+m._loggingPane.closePane();
+m._loggingPane=null;
+}
+if(!m._loggingPane||m._loggingPane.closed){
+m._loggingPane=new m.LoggingPane(_426,MochiKit.Logging.logger);
+}
+return m._loggingPane;
+};
+MochiKit.LoggingPane.LoggingPane=function(_427,_428){
+if(typeof (_428)=="undefined"||_428===null){
+_428=MochiKit.Logging.logger;
+}
+this.logger=_428;
+var _429=MochiKit.Base.update;
+var _430=MochiKit.Base.updatetree;
+var bind=MochiKit.Base.bind;
+var _431=MochiKit.Base.clone;
+var win=window;
+var uid="_MochiKit_LoggingPane";
+if(typeof (MochiKit.DOM)!="undefined"){
+win=MochiKit.DOM.currentWindow();
+}
+if(!_427){
+var url=win.location.href.split("?")[0].replace(/[:\/.><&]/g,"_");
+var name=uid+"_"+url;
+var nwin=win.open("",name,"dependent,resizable,height=200");
+if(!nwin){
+alert("Not able to open debugging window due to pop-up blocking.");
+return undefined;
+}
+nwin.document.write("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\" "+"\"http://www.w3.org/TR/html4/loose.dtd\">"+"<html><head><title>[MochiKit.LoggingPane]</title></head>"+"<body></body></html>");
+nwin.document.close();
+nwin.document.title+=" "+win.document.title;
+win=nwin;
+}
+var doc=win.document;
+this.doc=doc;
+var _434=doc.getElementById(uid);
+var _435=!!_434;
+if(_434&&typeof (_434.loggingPane)!="undefined"){
+_434.loggingPane.logger=this.logger;
+_434.loggingPane.buildAndApplyFilter();
+return _434.loggingPane;
+}
+if(_435){
+var _436;
+while((_436=_434.firstChild)){
+_434.removeChild(_436);
+}
+}else{
+_434=doc.createElement("div");
+_434.id=uid;
+}
+_434.loggingPane=this;
+var _437=doc.createElement("input");
+var _438=doc.createElement("input");
+var _439=doc.createElement("button");
+var _440=doc.createElement("button");
+var _441=doc.createElement("button");
+var _442=doc.createElement("button");
+var _443=doc.createElement("div");
+var _444=doc.createElement("div");
+var _445=uid+"_Listener";
+this.colorTable=_431(this.colorTable);
+var _446=[];
+var _447=null;
+var _448=function(msg){
+var _449=msg.level;
+if(typeof (_449)=="number"){
+_449=MochiKit.Logging.LogLevel[_449];
+}
+return _449;
+};
+var _450=function(msg){
+return msg.info.join(" ");
+};
+var _451=bind(function(msg){
+var _452=_448(msg);
+var text=_450(msg);
+var c=this.colorTable[_452];
+var p=doc.createElement("span");
+p.className="MochiKit-LogMessage MochiKit-LogLevel-"+_452;
+p.style.cssText="margin: 0px; white-space: -moz-pre-wrap; white-space: -o-pre-wrap; white-space: pre-wrap; white-space: pre-line; word-wrap: break-word; wrap-option: emergency; color: "+c;
+p.appendChild(doc.createTextNode(_452+": "+text));
+_444.appendChild(p);
+_444.appendChild(doc.createElement("br"));
+if(_443.offsetHeight>_443.scrollHeight){
+_443.scrollTop=0;
+}else{
+_443.scrollTop=_443.scrollHeight;
+}
+},this);
+var _454=function(msg){
+_446[_446.length]=msg;
+_451(msg);
+};
+var _455=function(){
+var _456,infore;
+try{
+_456=new RegExp(_437.value);
+infore=new RegExp(_438.value);
+}
+catch(e){
+logDebug("Error in filter regex: "+e.message);
+return null;
+}
+return function(msg){
+return (_456.test(_448(msg))&&infore.test(_450(msg)));
+};
+};
+var _457=function(){
+while(_444.firstChild){
+_444.removeChild(_444.firstChild);
+}
+};
+var _458=function(){
+_446=[];
+_457();
+};
+var _459=bind(function(){
+if(this.closed){
+return;
+}
+this.closed=true;
+if(MochiKit.LoggingPane._loggingPane==this){
+MochiKit.LoggingPane._loggingPane=null;
+}
+this.logger.removeListener(_445);
+_434.loggingPane=null;
+if(_427){
+_434.parentNode.removeChild(_434);
+}else{
+this.win.close();
+}
+},this);
+var _460=function(){
+_457();
+for(var i=0;i<_446.length;i++){
+var msg=_446[i];
+if(_447===null||_447(msg)){
+_451(msg);
+}
+}
+};
+this.buildAndApplyFilter=function(){
+_447=_455();
+_460();
+this.logger.removeListener(_445);
+this.logger.addListener(_445,_447,_454);
+};
+var _461=bind(function(){
+_446=this.logger.getMessages();
+_460();
+},this);
+var _462=bind(function(_463){
+_463=_463||window.event;
+key=_463.which||_463.keyCode;
+if(key==13){
+this.buildAndApplyFilter();
+}
+},this);
+var _464="display: block; z-index: 1000; left: 0px; bottom: 0px; position: fixed; width: 100%; background-color: white; font: "+this.logFont;
+if(_427){
+_464+="; height: 10em; border-top: 2px solid black";
+}else{
+_464+="; height: 100%;";
+}
+_434.style.cssText=_464;
+if(!_435){
+doc.body.appendChild(_434);
+}
+_464={"cssText":"width: 33%; display: inline; font: "+this.logFont};
+_430(_437,{"value":"FATAL|ERROR|WARNING|INFO|DEBUG","onkeypress":_462,"style":_464});
+_434.appendChild(_437);
+_430(_438,{"value":".*","onkeypress":_462,"style":_464});
+_434.appendChild(_438);
+_464="width: 8%; display:inline; font: "+this.logFont;
+_439.appendChild(doc.createTextNode("Filter"));
+_439.onclick=bind("buildAndApplyFilter",this);
+_439.style.cssText=_464;
+_434.appendChild(_439);
+_440.appendChild(doc.createTextNode("Load"));
+_440.onclick=_461;
+_440.style.cssText=_464;
+_434.appendChild(_440);
+_441.appendChild(doc.createTextNode("Clear"));
+_441.onclick=_458;
+_441.style.cssText=_464;
+_434.appendChild(_441);
+_442.appendChild(doc.createTextNode("Close"));
+_442.onclick=_459;
+_442.style.cssText=_464;
+_434.appendChild(_442);
+_443.style.cssText="overflow: auto; width: 100%";
+_444.style.cssText="width: 100%; height: "+(_427?"8em":"100%");
+_443.appendChild(_444);
+_434.appendChild(_443);
+this.buildAndApplyFilter();
+_461();
+if(_427){
+this.win=undefined;
+}else{
+this.win=win;
+}
+this.inline=_427;
+this.closePane=_459;
+this.closed=false;
+return this;
+};
+MochiKit.LoggingPane.LoggingPane.prototype={"logFont":"8pt Verdana,sans-serif","colorTable":{"ERROR":"red","FATAL":"darkred","WARNING":"blue","INFO":"black","DEBUG":"green"}};
+MochiKit.LoggingPane.EXPORT_OK=["LoggingPane"];
+MochiKit.LoggingPane.EXPORT=["createLoggingPane"];
+MochiKit.LoggingPane.__new__=function(){
+this.EXPORT_TAGS={":common":this.EXPORT,":all":MochiKit.Base.concat(this.EXPORT,this.EXPORT_OK)};
+MochiKit.Base.nameFunctions(this);
+MochiKit.LoggingPane._loggingPane=null;
+};
+MochiKit.LoggingPane.__new__();
+MochiKit.Base._exportSymbols(this,MochiKit.LoggingPane);
+if(typeof (dojo)!="undefined"){
+dojo.provide("MochiKit.Color");
+dojo.require("MochiKit.Base");
+}
+if(typeof (JSAN)!="undefined"){
+JSAN.use("MochiKit.Base",[]);
+}
+try{
+if(typeof (MochiKit.Base)=="undefined"){
+throw "";
+}
+}
+catch(e){
+throw "MochiKit.Color depends on MochiKit.Base";
+}
+if(typeof (MochiKit.Color)=="undefined"){
+MochiKit.Color={};
+}
+MochiKit.Color.NAME="MochiKit.Color";
+MochiKit.Color.VERSION="1.3.1";
+MochiKit.Color.__repr__=function(){
+return "["+this.NAME+" "+this.VERSION+"]";
+};
+MochiKit.Color.toString=function(){
+return this.__repr__();
+};
+MochiKit.Color.Color=function(red,_466,blue,_468){
+if(typeof (_468)=="undefined"||_468===null){
+_468=1;
+}
+this.rgb={r:red,g:_466,b:blue,a:_468};
+};
+MochiKit.Color.Color.prototype={__class__:MochiKit.Color.Color,colorWithAlpha:function(_469){
+var rgb=this.rgb;
+var m=MochiKit.Color;
+return m.Color.fromRGB(rgb.r,rgb.g,rgb.b,_469);
+},colorWithHue:function(hue){
+var hsl=this.asHSL();
+hsl.h=hue;
+var m=MochiKit.Color;
+return m.Color.fromHSL(hsl);
+},colorWithSaturation:function(_473){
+var hsl=this.asHSL();
+hsl.s=_473;
+var m=MochiKit.Color;
+return m.Color.fromHSL(hsl);
+},colorWithLightness:function(_474){
+var hsl=this.asHSL();
+hsl.l=_474;
+var m=MochiKit.Color;
+return m.Color.fromHSL(hsl);
+},darkerColorWithLevel:function(_475){
+var hsl=this.asHSL();
+hsl.l=Math.max(hsl.l-_475,0);
+var m=MochiKit.Color;
+return m.Color.fromHSL(hsl);
+},lighterColorWithLevel:function(_476){
+var hsl=this.asHSL();
+hsl.l=Math.min(hsl.l+_476,1);
+var m=MochiKit.Color;
+return m.Color.fromHSL(hsl);
+},blendedColor:function(_477,_478){
+if(typeof (_478)=="undefined"||_478===null){
+_478=0.5;
+}
+var sf=1-_478;
+var s=this.rgb;
+var d=_477.rgb;
+var df=_478;
+return MochiKit.Color.Color.fromRGB((s.r*sf)+(d.r*df),(s.g*sf)+(d.g*df),(s.b*sf)+(d.b*df),(s.a*sf)+(d.a*df));
+},compareRGB:function(_481){
+var a=this.asRGB();
+var b=_481.asRGB();
+return MochiKit.Base.compare([a.r,a.g,a.b,a.a],[b.r,b.g,b.b,b.a]);
+},isLight:function(){
+return this.asHSL().b>0.5;
+},isDark:function(){
+return (!this.isLight());
+},toHSLString:function(){
+var c=this.asHSL();
+var ccc=MochiKit.Color.clampColorComponent;
+var rval=this._hslString;
+if(!rval){
+var mid=(ccc(c.h,360).toFixed(0)+","+ccc(c.s,100).toPrecision(4)+"%"+","+ccc(c.l,100).toPrecision(4)+"%");
+var a=c.a;
+if(a>=1){
+a=1;
+rval="hsl("+mid+")";
+}else{
+if(a<=0){
+a=0;
+}
+rval="hsla("+mid+","+a+")";
+}
+this._hslString=rval;
+}
+return rval;
+},toRGBString:function(){
+var c=this.rgb;
+var ccc=MochiKit.Color.clampColorComponent;
+var rval=this._rgbString;
+if(!rval){
+var mid=(ccc(c.r,255).toFixed(0)+","+ccc(c.g,255).toFixed(0)+","+ccc(c.b,255).toFixed(0));
+if(c.a!=1){
+rval="rgba("+mid+","+c.a+")";
+}else{
+rval="rgb("+mid+")";
+}
+this._rgbString=rval;
+}
+return rval;
+},asRGB:function(){
+return MochiKit.Base.clone(this.rgb);
+},toHexString:function(){
+var m=MochiKit.Color;
+var c=this.rgb;
+var ccc=MochiKit.Color.clampColorComponent;
+var rval=this._hexString;
+if(!rval){
+rval=("#"+m.toColorPart(ccc(c.r,255))+m.toColorPart(ccc(c.g,255))+m.toColorPart(ccc(c.b,255)));
+this._hexString=rval;
+}
+return rval;
+},asHSV:function(){
+var hsv=this.hsv;
+var c=this.rgb;
+if(typeof (hsv)=="undefined"||hsv===null){
+hsv=MochiKit.Color.rgbToHSV(this.rgb);
+this.hsv=hsv;
+}
+return MochiKit.Base.clone(hsv);
+},asHSL:function(){
+var hsl=this.hsl;
+var c=this.rgb;
+if(typeof (hsl)=="undefined"||hsl===null){
+hsl=MochiKit.Color.rgbToHSL(this.rgb);
+this.hsl=hsl;
+}
+return MochiKit.Base.clone(hsl);
+},toString:function(){
+return this.toRGBString();
+},repr:function(){
+var c=this.rgb;
+var col=[c.r,c.g,c.b,c.a];
+return this.__class__.NAME+"("+col.join(", ")+")";
+}};
+MochiKit.Base.update(MochiKit.Color.Color,{fromRGB:function(red,_486,blue,_487){
+var _488=MochiKit.Color.Color;
+if(arguments.length==1){
+var rgb=red;
+red=rgb.r;
+_486=rgb.g;
+blue=rgb.b;
+if(typeof (rgb.a)=="undefined"){
+_487=undefined;
+}else{
+_487=rgb.a;
+}
+}
+return new _488(red,_486,blue,_487);
+},fromHSL:function(hue,_489,_490,_491){
+var m=MochiKit.Color;
+return m.Color.fromRGB(m.hslToRGB.apply(m,arguments));
+},fromHSV:function(hue,_492,_493,_494){
+var m=MochiKit.Color;
+return m.Color.fromRGB(m.hsvToRGB.apply(m,arguments));
+},fromName:function(name){
+var _495=MochiKit.Color.Color;
+if(name.charAt(0)=="\""){
+name=name.substr(1,name.length-2);
+}
+var _496=_495._namedColors[name.toLowerCase()];
+if(typeof (_496)=="string"){
+return _495.fromHexString(_496);
+}else{
+if(name=="transparent"){
+return _495.transparentColor();
+}
+}
+return null;
+},fromString:function(_497){
+var self=MochiKit.Color.Color;
+var _498=_497.substr(0,3);
+if(_498=="rgb"){
+return self.fromRGBString(_497);
+}else{
+if(_498=="hsl"){
+return self.fromHSLString(_497);
+}else{
+if(_497.charAt(0)=="#"){
+return self.fromHexString(_497);
+}
+}
+}
+return self.fromName(_497);
+},fromHexString:function(_499){
+if(_499.charAt(0)=="#"){
+_499=_499.substring(1);
+}
+var _500=[];
+var i,hex;
+if(_499.length==3){
+for(i=0;i<3;i++){
+hex=_499.substr(i,1);
+_500.push(parseInt(hex+hex,16)/255);
+}
+}else{
+for(i=0;i<6;i+=2){
+hex=_499.substr(i,2);
+_500.push(parseInt(hex,16)/255);
+}
+}
+var _501=MochiKit.Color.Color;
+return _501.fromRGB.apply(_501,_500);
+},_fromColorString:function(pre,_503,_504,_505){
+if(_505.indexOf(pre)===0){
+_505=_505.substring(_505.indexOf("(",3)+1,_505.length-1);
+}
+var _506=_505.split(/\s*,\s*/);
+var _507=[];
+for(var i=0;i<_506.length;i++){
+var c=_506[i];
+var val;
+var _508=c.substring(c.length-3);
+if(c.charAt(c.length-1)=="%"){
+val=0.01*parseFloat(c.substring(0,c.length-1));
+}else{
+if(_508=="deg"){
+val=parseFloat(c)/360;
+}else{
+if(_508=="rad"){
+val=parseFloat(c)/(Math.PI*2);
+}else{
+val=_504[i]*parseFloat(c);
+}
+}
+}
+_507.push(val);
+}
+return this[_503].apply(this,_507);
+},fromComputedStyle:function(elem,_509,_510){
+var d=MochiKit.DOM;
+var cls=MochiKit.Color.Color;
+for(elem=d.getElement(elem);elem;elem=elem.parentNode){
+var _511=d.computedStyle.apply(d,arguments);
+if(!_511){
+continue;
+}
+var _512=cls.fromString(_511);
+if(!_512){
+break;
+}
+if(_512.asRGB().a>0){
+return _512;
+}
+}
+return null;
+},fromBackground:function(elem){
+var cls=MochiKit.Color.Color;
+return cls.fromComputedStyle(elem,"backgroundColor","background-color")||cls.whiteColor();
+},fromText:function(elem){
+var cls=MochiKit.Color.Color;
+return cls.fromComputedStyle(elem,"color","color")||cls.blackColor();
+},namedColors:function(){
+return MochiKit.Base.clone(MochiKit.Color.Color._namedColors);
+}});
+MochiKit.Base.update(MochiKit.Color,{clampColorComponent:function(v,_513){
+v*=_513;
+if(v<0){
+return 0;
+}else{
+if(v>_513){
+return _513;
+}else{
+return v;
+}
+}
+},_hslValue:function(n1,n2,hue){
+if(hue>6){
+hue-=6;
+}else{
+if(hue<0){
+hue+=6;
+}
+}
+var val;
+if(hue<1){
+val=n1+(n2-n1)*hue;
+}else{
+if(hue<3){
+val=n2;
+}else{
+if(hue<4){
+val=n1+(n2-n1)*(4-hue);
+}else{
+val=n1;
+}
+}
+}
+return val;
+},hsvToRGB:function(hue,_516,_517,_518){
+if(arguments.length==1){
+var hsv=hue;
+hue=hsv.h;
+_516=hsv.s;
+_517=hsv.v;
+_518=hsv.a;
+}
+var red;
+var _519;
+var blue;
+if(_516===0){
+red=0;
+_519=0;
+blue=0;
+}else{
+var i=Math.floor(hue*6);
+var f=(hue*6)-i;
+var p=_517*(1-_516);
+var q=_517*(1-(_516*f));
+var t=_517*(1-(_516*(1-f)));
+switch(i){
+case 1:
+red=q;
+_519=_517;
+blue=p;
+break;
+case 2:
+red=p;
+_519=_517;
+blue=t;
+break;
+case 3:
+red=p;
+_519=q;
+blue=_517;
+break;
+case 4:
+red=t;
+_519=p;
+blue=_517;
+break;
+case 5:
+red=_517;
+_519=p;
+blue=q;
+break;
+case 6:
+case 0:
+red=_517;
+_519=t;
+blue=p;
+break;
+}
+}
+return {r:red,g:_519,b:blue,a:_518};
+},hslToRGB:function(hue,_521,_522,_523){
+if(arguments.length==1){
+var hsl=hue;
+hue=hsl.h;
+_521=hsl.s;
+_522=hsl.l;
+_523=hsl.a;
+}
+var red;
+var _524;
+var blue;
+if(_521===0){
+red=_522;
+_524=_522;
+blue=_522;
+}else{
+var m2;
+if(_522<=0.5){
+m2=_522*(1+_521);
+}else{
+m2=_522+_521-(_522*_521);
+}
+var m1=(2*_522)-m2;
+var f=MochiKit.Color._hslValue;
+var h6=hue*6;
+red=f(m1,m2,h6+2);
+_524=f(m1,m2,h6);
+blue=f(m1,m2,h6-2);
+}
+return {r:red,g:_524,b:blue,a:_523};
+},rgbToHSV:function(red,_528,blue,_529){
+if(arguments.length==1){
+var rgb=red;
+red=rgb.r;
+_528=rgb.g;
+blue=rgb.b;
+_529=rgb.a;
+}
+var max=Math.max(Math.max(red,_528),blue);
+var min=Math.min(Math.min(red,_528),blue);
+var hue;
+var _532;
+var _533=max;
+if(min==max){
+hue=0;
+_532=0;
+}else{
+var _534=(max-min);
+_532=_534/max;
+if(red==max){
+hue=(_528-blue)/_534;
+}else{
+if(_528==max){
+hue=2+((blue-red)/_534);
+}else{
+hue=4+((red-_528)/_534);
+}
+}
+hue/=6;
+if(hue<0){
+hue+=1;
+}
+if(hue>1){
+hue-=1;
+}
+}
+return {h:hue,s:_532,v:_533,a:_529};
+},rgbToHSL:function(red,_535,blue,_536){
+if(arguments.length==1){
+var rgb=red;
+red=rgb.r;
+_535=rgb.g;
+blue=rgb.b;
+_536=rgb.a;
+}
+var max=Math.max(red,Math.max(_535,blue));
+var min=Math.min(red,Math.min(_535,blue));
+var hue;
+var _537;
+var _538=(max+min)/2;
+var _539=max-min;
+if(_539===0){
+hue=0;
+_537=0;
+}else{
+if(_538<=0.5){
+_537=_539/(max+min);
+}else{
+_537=_539/(2-max-min);
+}
+if(red==max){
+hue=(_535-blue)/_539;
+}else{
+if(_535==max){
+hue=2+((blue-red)/_539);
+}else{
+hue=4+((red-_535)/_539);
+}
+}
+hue/=6;
+if(hue<0){
+hue+=1;
+}
+if(hue>1){
+hue-=1;
+}
+}
+return {h:hue,s:_537,l:_538,a:_536};
+},toColorPart:function(num){
+num=Math.round(num);
+var _540=num.toString(16);
+if(num<16){
+return "0"+_540;
+}
+return _540;
+},__new__:function(){
+var m=MochiKit.Base;
+this.Color.fromRGBString=m.bind(this.Color._fromColorString,this.Color,"rgb","fromRGB",[1/255,1/255,1/255,1]);
+this.Color.fromHSLString=m.bind(this.Color._fromColorString,this.Color,"hsl","fromHSL",[1/360,0.01,0.01,1]);
+var _541=1/3;
+var _542={black:[0,0,0],blue:[0,0,1],brown:[0.6,0.4,0.2],cyan:[0,1,1],darkGray:[_541,_541,_541],gray:[0.5,0.5,0.5],green:[0,1,0],lightGray:[2*_541,2*_541,2*_541],magenta:[1,0,1],orange:[1,0.5,0],purple:[0.5,0,0.5],red:[1,0,0],transparent:[0,0,0,0],white:[1,1,1],yellow:[1,1,0]};
+var _543=function(name,r,g,b,a){
+var rval=this.fromRGB(r,g,b,a);
+this[name]=function(){
+return rval;
+};
+return rval;
+};
+for(var k in _542){
+var name=k+"Color";
+var _545=m.concat([_543,this.Color,name],_542[k]);
+this.Color[name]=m.bind.apply(null,_545);
+}
+var _546=function(){
+for(var i=0;i<arguments.length;i++){
+if(!(arguments[i] instanceof Color)){
+return false;
+}
+}
+return true;
+};
+var _547=function(a,b){
+return a.compareRGB(b);
+};
+m.nameFunctions(this);
+m.registerComparator(this.Color.NAME,_546,_547);
+this.EXPORT_TAGS={":common":this.EXPORT,":all":m.concat(this.EXPORT,this.EXPORT_OK)};
+}});
+MochiKit.Color.EXPORT=["Color"];
+MochiKit.Color.EXPORT_OK=["clampColorComponent","rgbToHSL","hslToRGB","rgbToHSV","hsvToRGB","toColorPart"];
+MochiKit.Color.__new__();
+MochiKit.Base._exportSymbols(this,MochiKit.Color);
+MochiKit.Color.Color._namedColors={aliceblue:"#f0f8ff",antiquewhite:"#faebd7",aqua:"#00ffff",aquamarine:"#7fffd4",azure:"#f0ffff",beige:"#f5f5dc",bisque:"#ffe4c4",black:"#000000",blanchedalmond:"#ffebcd",blue:"#0000ff",blueviolet:"#8a2be2",brown:"#a52a2a",burlywood:"#deb887",cadetblue:"#5f9ea0",chartreuse:"#7fff00",chocolate:"#d2691e",coral:"#ff7f50",cornflowerblue:"#6495ed",cornsilk:"#fff8dc",crimson:"#dc143c",cyan:"#00ffff",darkblue:"#00008b",darkcyan:"#008b8b",darkgoldenrod:"#b8860b",darkgray:"#a9a9a9",darkgreen:"#006400",darkgrey:"#a9a9a9",darkkhaki:"#bdb76b",darkmagenta:"#8b008b",darkolivegreen:"#556b2f",darkorange:"#ff8c00",darkorchid:"#9932cc",darkred:"#8b0000",darksalmon:"#e9967a",darkseagreen:"#8fbc8f",darkslateblue:"#483d8b",darkslategray:"#2f4f4f",darkslategrey:"#2f4f4f",darkturquoise:"#00ced1",darkviolet:"#9400d3",deeppink:"#ff1493",deepskyblue:"#00bfff",dimgray:"#696969",dimgrey:"#696969",dodgerblue:"#1e90ff",firebrick:"#b22222",floralwhite:"#fffaf0",forestgreen:"#228b22",fuchsia:"#ff00ff",gainsboro:"#dcdcdc",ghostwhite:"#f8f8ff",gold:"#ffd700",goldenrod:"#daa520",gray:"#808080",green:"#008000",greenyellow:"#adff2f",grey:"#808080",honeydew:"#f0fff0",hotpink:"#ff69b4",indianred:"#cd5c5c",indigo:"#4b0082",ivory:"#fffff0",khaki:"#f0e68c",lavender:"#e6e6fa",lavenderblush:"#fff0f5",lawngreen:"#7cfc00",lemonchiffon:"#fffacd",lightblue:"#add8e6",lightcoral:"#f08080",lightcyan:"#e0ffff",lightgoldenrodyellow:"#fafad2",lightgray:"#d3d3d3",lightgreen:"#90ee90",lightgrey:"#d3d3d3",lightpink:"#ffb6c1",lightsalmon:"#ffa07a",lightseagreen:"#20b2aa",lightskyblue:"#87cefa",lightslategray:"#778899",lightslategrey:"#778899",lightsteelblue:"#b0c4de",lightyellow:"#ffffe0",lime:"#00ff00",limegreen:"#32cd32",linen:"#faf0e6",magenta:"#ff00ff",maroon:"#800000",mediumaquamarine:"#66cdaa",mediumblue:"#0000cd",mediumorchid:"#ba55d3",mediumpurple:"#9370db",mediumseagreen:"#3cb371",mediumslateblue:"#7b68ee",mediumspringgreen:"#00fa9a",mediumturquoise:"#48d1cc",mediumvioletred:"#c71585",midnightblue:"#191970",mintcream:"#f5fffa",mistyrose:"#ffe4e1",moccasin:"#ffe4b5",navajowhite:"#ffdead",navy:"#000080",oldlace:"#fdf5e6",olive:"#808000",olivedrab:"#6b8e23",orange:"#ffa500",orangered:"#ff4500",orchid:"#da70d6",palegoldenrod:"#eee8aa",palegreen:"#98fb98",paleturquoise:"#afeeee",palevioletred:"#db7093",papayawhip:"#ffefd5",peachpuff:"#ffdab9",peru:"#cd853f",pink:"#ffc0cb",plum:"#dda0dd",powderblue:"#b0e0e6",purple:"#800080",red:"#ff0000",rosybrown:"#bc8f8f",royalblue:"#4169e1",saddlebrown:"#8b4513",salmon:"#fa8072",sandybrown:"#f4a460",seagreen:"#2e8b57",seashell:"#fff5ee",sienna:"#a0522d",silver:"#c0c0c0",skyblue:"#87ceeb",slateblue:"#6a5acd",slategray:"#708090",slategrey:"#708090",snow:"#fffafa",springgreen:"#00ff7f",steelblue:"#4682b4",tan:"#d2b48c",teal:"#008080",thistle:"#d8bfd8",tomato:"#ff6347",turquoise:"#40e0d0",violet:"#ee82ee",wheat:"#f5deb3",white:"#ffffff",whitesmoke:"#f5f5f5",yellow:"#ffff00",yellowgreen:"#9acd32"};
+if(typeof (dojo)!="undefined"){
+dojo.provide("MochiKit.Signal");
+dojo.require("MochiKit.Base");
+dojo.require("MochiKit.DOM");
+}
+if(typeof (JSAN)!="undefined"){
+JSAN.use("MochiKit.Base",[]);
+JSAN.use("MochiKit.DOM",[]);
+}
+try{
+if(typeof (MochiKit.Base)=="undefined"){
+throw "";
+}
+}
+catch(e){
+throw "MochiKit.Signal depends on MochiKit.Base!";
+}
+try{
+if(typeof (MochiKit.DOM)=="undefined"){
+throw "";
+}
+}
+catch(e){
+throw "MochiKit.Signal depends on MochiKit.DOM!";
+}
+if(typeof (MochiKit.Signal)=="undefined"){
+MochiKit.Signal={};
+}
+MochiKit.Signal.NAME="MochiKit.Signal";
+MochiKit.Signal.VERSION="1.3.1";
+MochiKit.Signal._observers=[];
+MochiKit.Signal.Event=function(src,e){
+this._event=e||window.event;
+this._src=src;
+};
+MochiKit.Base.update(MochiKit.Signal.Event.prototype,{__repr__:function(){
+var repr=MochiKit.Base.repr;
+var str="{event(): "+repr(this.event())+", src(): "+repr(this.src())+", type(): "+repr(this.type())+", target(): "+repr(this.target())+", modifier(): "+"{alt: "+repr(this.modifier().alt)+", ctrl: "+repr(this.modifier().ctrl)+", meta: "+repr(this.modifier().meta)+", shift: "+repr(this.modifier().shift)+", any: "+repr(this.modifier().any)+"}";
+if(this.type()&&this.type().indexOf("key")===0){
+str+=", key(): {code: "+repr(this.key().code)+", string: "+repr(this.key().string)+"}";
+}
+if(this.type()&&(this.type().indexOf("mouse")===0||this.type().indexOf("click")!=-1||this.type()=="contextmenu")){
+str+=", mouse(): {page: "+repr(this.mouse().page)+", client: "+repr(this.mouse().client);
+if(this.type()!="mousemove"){
+str+=", button: {left: "+repr(this.mouse().button.left)+", middle: "+repr(this.mouse().button.middle)+", right: "+repr(this.mouse().button.right)+"}}";
+}else{
+str+="}";
+}
+}
+if(this.type()=="mouseover"||this.type()=="mouseout"){
+str+=", relatedTarget(): "+repr(this.relatedTarget());
+}
+str+="}";
+return str;
+},toString:function(){
+return this.__repr__();
+},src:function(){
+return this._src;
+},event:function(){
+return this._event;
+},type:function(){
+return this._event.type||undefined;
+},target:function(){
+return this._event.target||this._event.srcElement;
+},relatedTarget:function(){
+if(this.type()=="mouseover"){
+return (this._event.relatedTarget||this._event.fromElement);
+}else{
+if(this.type()=="mouseout"){
+return (this._event.relatedTarget||this._event.toElement);
+}
+}
+return undefined;
+},modifier:function(){
+var m={};
+m.alt=this._event.altKey;
+m.ctrl=this._event.ctrlKey;
+m.meta=this._event.metaKey||false;
+m.shift=this._event.shiftKey;
+m.any=m.alt||m.ctrl||m.shift||m.meta;
+return m;
+},key:function(){
+var k={};
+if(this.type()&&this.type().indexOf("key")===0){
+if(this.type()=="keydown"||this.type()=="keyup"){
+k.code=this._event.keyCode;
+k.string=(MochiKit.Signal._specialKeys[k.code]||"KEY_UNKNOWN");
+return k;
+}else{
+if(this.type()=="keypress"){
+k.code=0;
+k.string="";
+if(typeof (this._event.charCode)!="undefined"&&this._event.charCode!==0&&!MochiKit.Signal._specialMacKeys[this._event.charCode]){
+k.code=this._event.charCode;
+k.string=String.fromCharCode(k.code);
+}else{
+if(this._event.keyCode&&typeof (this._event.charCode)=="undefined"){
+k.code=this._event.keyCode;
+k.string=String.fromCharCode(k.code);
+}
+}
+return k;
+}
+}
+}
+return undefined;
+},mouse:function(){
+var m={};
+var e=this._event;
+if(this.type()&&(this.type().indexOf("mouse")===0||this.type().indexOf("click")!=-1||this.type()=="contextmenu")){
+m.client=new MochiKit.DOM.Coordinates(0,0);
+if(e.clientX||e.clientY){
+m.client.x=(!e.clientX||e.clientX<0)?0:e.clientX;
+m.client.y=(!e.clientY||e.clientY<0)?0:e.clientY;
+}
+m.page=new MochiKit.DOM.Coordinates(0,0);
+if(e.pageX||e.pageY){
+m.page.x=(!e.pageX||e.pageX<0)?0:e.pageX;
+m.page.y=(!e.pageY||e.pageY<0)?0:e.pageY;
+}else{
+var de=MochiKit.DOM._document.documentElement;
+var b=MochiKit.DOM._document.body;
+m.page.x=e.clientX+(de.scrollLeft||b.scrollLeft)-(de.clientLeft||b.clientLeft);
+m.page.y=e.clientY+(de.scrollTop||b.scrollTop)-(de.clientTop||b.clientTop);
+}
+if(this.type()!="mousemove"){
+m.button={};
+m.button.left=false;
+m.button.right=false;
+m.button.middle=false;
+if(e.which){
+m.button.left=(e.which==1);
+m.button.middle=(e.which==2);
+m.button.right=(e.which==3);
+}else{
+m.button.left=!!(e.button&1);
+m.button.right=!!(e.button&2);
+m.button.middle=!!(e.button&4);
+}
+}
+return m;
+}
+return undefined;
+},stop:function(){
+this.stopPropagation();
+this.preventDefault();
+},stopPropagation:function(){
+if(this._event.stopPropagation){
+this._event.stopPropagation();
+}else{
+this._event.cancelBubble=true;
+}
+},preventDefault:function(){
+if(this._event.preventDefault){
+this._event.preventDefault();
+}else{
+this._event.returnValue=false;
+}
+}});
+MochiKit.Signal._specialMacKeys={3:"KEY_ENTER",63289:"KEY_NUM_PAD_CLEAR",63276:"KEY_PAGE_UP",63277:"KEY_PAGE_DOWN",63275:"KEY_END",63273:"KEY_HOME",63234:"KEY_ARROW_LEFT",63232:"KEY_ARROW_UP",63235:"KEY_ARROW_RIGHT",63233:"KEY_ARROW_DOWN",63302:"KEY_INSERT",63272:"KEY_DELETE"};
+for(i=63236;i<=63242;i++){
+MochiKit.Signal._specialMacKeys[i]="KEY_F"+(i-63236+1);
+}
+MochiKit.Signal._specialKeys={8:"KEY_BACKSPACE",9:"KEY_TAB",12:"KEY_NUM_PAD_CLEAR",13:"KEY_ENTER",16:"KEY_SHIFT",17:"KEY_CTRL",18:"KEY_ALT",19:"KEY_PAUSE",20:"KEY_CAPS_LOCK",27:"KEY_ESCAPE",32:"KEY_SPACEBAR",33:"KEY_PAGE_UP",34:"KEY_PAGE_DOWN",35:"KEY_END",36:"KEY_HOME",37:"KEY_ARROW_LEFT",38:"KEY_ARROW_UP",39:"KEY_ARROW_RIGHT",40:"KEY_ARROW_DOWN",44:"KEY_PRINT_SCREEN",45:"KEY_INSERT",46:"KEY_DELETE",59:"KEY_SEMICOLON",91:"KEY_WINDOWS_LEFT",92:"KEY_WINDOWS_RIGHT",93:"KEY_SELECT",106:"KEY_NUM_PAD_ASTERISK",107:"KEY_NUM_PAD_PLUS_SIGN",109:"KEY_NUM_PAD_HYPHEN-MINUS",110:"KEY_NUM_PAD_FULL_STOP",111:"KEY_NUM_PAD_SOLIDUS",144:"KEY_NUM_LOCK",145:"KEY_SCROLL_LOCK",186:"KEY_SEMICOLON",187:"KEY_EQUALS_SIGN",188:"KEY_COMMA",189:"KEY_HYPHEN-MINUS",190:"KEY_FULL_STOP",191:"KEY_SOLIDUS",192:"KEY_GRAVE_ACCENT",219:"KEY_LEFT_SQUARE_BRACKET",220:"KEY_REVERSE_SOLIDUS",221:"KEY_RIGHT_SQUARE_BRACKET",222:"KEY_APOSTROPHE"};
+for(var i=48;i<=57;i++){
+MochiKit.Signal._specialKeys[i]="KEY_"+(i-48);
+}
+for(i=65;i<=90;i++){
+MochiKit.Signal._specialKeys[i]="KEY_"+String.fromCharCode(i);
+}
+for(i=96;i<=105;i++){
+MochiKit.Signal._specialKeys[i]="KEY_NUM_PAD_"+(i-96);
+}
+for(i=112;i<=123;i++){
+MochiKit.Signal._specialKeys[i]="KEY_F"+(i-112+1);
+}
+MochiKit.Base.update(MochiKit.Signal,{__repr__:function(){
+return "["+this.NAME+" "+this.VERSION+"]";
+},toString:function(){
+return this.__repr__();
+},_unloadCache:function(){
+var self=MochiKit.Signal;
+var _548=self._observers;
+for(var i=0;i<_548.length;i++){
+self._disconnect(_548[i]);
+}
+delete self._observers;
+try{
+window.onload=undefined;
+}
+catch(e){
+}
+try{
+window.onunload=undefined;
+}
+catch(e){
+}
+},_listener:function(src,func,obj,_549){
+var E=MochiKit.Signal.Event;
+if(!_549){
+return MochiKit.Base.bind(func,obj);
+}
+obj=obj||src;
+if(typeof (func)=="string"){
+return function(_551){
+obj[func].apply(obj,[new E(src,_551)]);
+};
+}else{
+return function(_552){
+func.apply(obj,[new E(src,_552)]);
+};
+}
+},connect:function(src,sig,_554,_555){
+src=MochiKit.DOM.getElement(src);
+var self=MochiKit.Signal;
+if(typeof (sig)!="string"){
+throw new Error("'sig' must be a string");
+}
+var obj=null;
+var func=null;
+if(typeof (_555)!="undefined"){
+obj=_554;
+func=_555;
+if(typeof (_555)=="string"){
+if(typeof (_554[_555])!="function"){
+throw new Error("'funcOrStr' must be a function on 'objOrFunc'");
+}
+}else{
+if(typeof (_555)!="function"){
+throw new Error("'funcOrStr' must be a function or string");
+}
+}
+}else{
+if(typeof (_554)!="function"){
+throw new Error("'objOrFunc' must be a function if 'funcOrStr' is not given");
+}else{
+func=_554;
+}
+}
+if(typeof (obj)=="undefined"||obj===null){
+obj=src;
+}
+var _556=!!(src.addEventListener||src.attachEvent);
+var _557=self._listener(src,func,obj,_556);
+if(src.addEventListener){
+src.addEventListener(sig.substr(2),_557,false);
+}else{
+if(src.attachEvent){
+src.attachEvent(sig,_557);
+}
+}
+var _558=[src,sig,_557,_556,_554,_555];
+self._observers.push(_558);
+return _558;
+},_disconnect:function(_559){
+if(!_559[3]){
+return;
+}
+var src=_559[0];
+var sig=_559[1];
+var _560=_559[2];
+if(src.removeEventListener){
+src.removeEventListener(sig.substr(2),_560,false);
+}else{
+if(src.detachEvent){
+src.detachEvent(sig,_560);
+}else{
+throw new Error("'src' must be a DOM element");
+}
+}
+},disconnect:function(_561){
+var self=MochiKit.Signal;
+var _562=self._observers;
+var m=MochiKit.Base;
+if(arguments.length>1){
+var src=MochiKit.DOM.getElement(arguments[0]);
+var sig=arguments[1];
+var obj=arguments[2];
+var func=arguments[3];
+for(var i=_562.length-1;i>=0;i--){
+var o=_562[i];
+if(o[0]===src&&o[1]===sig&&o[4]===obj&&o[5]===func){
+self._disconnect(o);
+_562.splice(i,1);
+return true;
+}
+}
+}else{
+var idx=m.findIdentical(_562,_561);
+if(idx>=0){
+self._disconnect(_561);
+_562.splice(idx,1);
+return true;
+}
+}
+return false;
+},disconnectAll:function(src,sig){
+src=MochiKit.DOM.getElement(src);
+var m=MochiKit.Base;
+var _563=m.flattenArguments(m.extend(null,arguments,1));
+var self=MochiKit.Signal;
+var _564=self._disconnect;
+var _565=self._observers;
+if(_563.length===0){
+for(var i=_565.length-1;i>=0;i--){
+var _566=_565[i];
+if(_566[0]===src){
+_564(_566);
+_565.splice(i,1);
+}
+}
+}else{
+var sigs={};
+for(var i=0;i<_563.length;i++){
+sigs[_563[i]]=true;
+}
+for(var i=_565.length-1;i>=0;i--){
+var _566=_565[i];
+if(_566[0]===src&&_566[1] in sigs){
+_564(_566);
+_565.splice(i,1);
+}
+}
+}
+},signal:function(src,sig){
+var _568=MochiKit.Signal._observers;
+src=MochiKit.DOM.getElement(src);
+var args=MochiKit.Base.extend(null,arguments,2);
+var _569=[];
+for(var i=0;i<_568.length;i++){
+var _570=_568[i];
+if(_570[0]===src&&_570[1]===sig){
+try{
+_570[2].apply(src,args);
+}
+catch(e){
+_569.push(e);
+}
+}
+}
+if(_569.length==1){
+throw _569[0];
+}else{
+if(_569.length>1){
+var e=new Error("Multiple errors thrown in handling 'sig', see errors property");
+e.errors=_569;
+throw e;
+}
+}
+}});
+MochiKit.Signal.EXPORT_OK=[];
+MochiKit.Signal.EXPORT=["connect","disconnect","signal","disconnectAll"];
+MochiKit.Signal.__new__=function(win){
+var m=MochiKit.Base;
+this._document=document;
+this._window=win;
+try{
+this.connect(window,"onunload",this._unloadCache);
+}
+catch(e){
+}
+this.EXPORT_TAGS={":common":this.EXPORT,":all":m.concat(this.EXPORT,this.EXPORT_OK)};
+m.nameFunctions(this);
+};
+MochiKit.Signal.__new__(this);
+if(!MochiKit.__compat__){
+connect=MochiKit.Signal.connect;
+disconnect=MochiKit.Signal.disconnect;
+disconnectAll=MochiKit.Signal.disconnectAll;
+signal=MochiKit.Signal.signal;
+}
+MochiKit.Base._exportSymbols(this,MochiKit.Signal);
+if(typeof (dojo)!="undefined"){
+dojo.provide("MochiKit.Visual");
+dojo.require("MochiKit.Base");
+dojo.require("MochiKit.DOM");
+dojo.require("MochiKit.Color");
+}
+if(typeof (JSAN)!="undefined"){
+JSAN.use("MochiKit.Base",[]);
+JSAN.use("MochiKit.DOM",[]);
+JSAN.use("MochiKit.Color",[]);
+}
+try{
+if(typeof (MochiKit.Base)=="undefined"||typeof (MochiKit.DOM)=="undefined"||typeof (MochiKit.Color)=="undefined"){
+throw "";
+}
+}
+catch(e){
+throw "MochiKit.Visual depends on MochiKit.Base, MochiKit.DOM and MochiKit.Color!";
+}
+if(typeof (MochiKit.Visual)=="undefined"){
+MochiKit.Visual={};
+}
+MochiKit.Visual.NAME="MochiKit.Visual";
+MochiKit.Visual.VERSION="1.3.1";
+MochiKit.Visual.__repr__=function(){
+return "["+this.NAME+" "+this.VERSION+"]";
+};
+MochiKit.Visual.toString=function(){
+return this.__repr__();
+};
+MochiKit.Visual._RoundCorners=function(e,_571){
+e=MochiKit.DOM.getElement(e);
+this._setOptions(_571);
+if(this.options.__unstable__wrapElement){
+e=this._doWrap(e);
+}
+var _572=this.options.color;
+var C=MochiKit.Color.Color;
+if(this.options.color=="fromElement"){
+_572=C.fromBackground(e);
+}else{
+if(!(_572 instanceof C)){
+_572=C.fromString(_572);
+}
+}
+this.isTransparent=(_572.asRGB().a<=0);
+var _574=this.options.bgColor;
+if(this.options.bgColor=="fromParent"){
+_574=C.fromBackground(e.offsetParent);
+}else{
+if(!(_574 instanceof C)){
+_574=C.fromString(_574);
+}
+}
+this._roundCornersImpl(e,_572,_574);
+};
+MochiKit.Visual._RoundCorners.prototype={_doWrap:function(e){
+var _575=e.parentNode;
+var doc=MochiKit.DOM.currentDocument();
+if(typeof (doc.defaultView)=="undefined"||doc.defaultView===null){
+return e;
+}
+var _576=doc.defaultView.getComputedStyle(e,null);
+if(typeof (_576)=="undefined"||_576===null){
+return e;
+}
+var _577=MochiKit.DOM.DIV({"style":{display:"block",marginTop:_576.getPropertyValue("padding-top"),marginRight:_576.getPropertyValue("padding-right"),marginBottom:_576.getPropertyValue("padding-bottom"),marginLeft:_576.getPropertyValue("padding-left"),padding:"0px"}});
+_577.innerHTML=e.innerHTML;
+e.innerHTML="";
+e.appendChild(_577);
+return e;
+},_roundCornersImpl:function(e,_578,_579){
+if(this.options.border){
+this._renderBorder(e,_579);
+}
+if(this._isTopRounded()){
+this._roundTopCorners(e,_578,_579);
+}
+if(this._isBottomRounded()){
+this._roundBottomCorners(e,_578,_579);
+}
+},_renderBorder:function(el,_580){
+var _581="1px solid "+this._borderColor(_580);
+var _582="border-left: "+_581;
+var _583="border-right: "+_581;
+var _584="style='"+_582+";"+_583+"'";
+el.innerHTML="<div "+_584+">"+el.innerHTML+"</div>";
+},_roundTopCorners:function(el,_585,_586){
+var _587=this._createCorner(_586);
+for(var i=0;i<this.options.numSlices;i++){
+_587.appendChild(this._createCornerSlice(_585,_586,i,"top"));
+}
+el.style.paddingTop=0;
+el.insertBefore(_587,el.firstChild);
+},_roundBottomCorners:function(el,_588,_589){
+var _590=this._createCorner(_589);
+for(var i=(this.options.numSlices-1);i>=0;i--){
+_590.appendChild(this._createCornerSlice(_588,_589,i,"bottom"));
+}
+el.style.paddingBottom=0;
+el.appendChild(_590);
+},_createCorner:function(_591){
+var dom=MochiKit.DOM;
+return dom.DIV({style:{backgroundColor:_591.toString()}});
+},_createCornerSlice:function(_592,_593,n,_594){
+var _595=MochiKit.DOM.SPAN();
+var _596=_595.style;
+_596.backgroundColor=_592.toString();
+_596.display="block";
+_596.height="1px";
+_596.overflow="hidden";
+_596.fontSize="1px";
+var _597=this._borderColor(_592,_593);
+if(this.options.border&&n===0){
+_596.borderTopStyle="solid";
+_596.borderTopWidth="1px";
+_596.borderLeftWidth="0px";
+_596.borderRightWidth="0px";
+_596.borderBottomWidth="0px";
+_596.height="0px";
+_596.borderColor=_597.toString();
+}else{
+if(_597){
+_596.borderColor=_597.toString();
+_596.borderStyle="solid";
+_596.borderWidth="0px 1px";
+}
+}
+if(!this.options.compact&&(n==(this.options.numSlices-1))){
+_596.height="2px";
+}
+this._setMargin(_595,n,_594);
+this._setBorder(_595,n,_594);
+return _595;
+},_setOptions:function(_598){
+this.options={corners:"all",color:"fromElement",bgColor:"fromParent",blend:true,border:false,compact:false,__unstable__wrapElement:false};
+MochiKit.Base.update(this.options,_598);
+this.options.numSlices=(this.options.compact?2:4);
+},_whichSideTop:function(){
+var _599=this.options.corners;
+if(this._hasString(_599,"all","top")){
+return "";
+}
+var _600=(_599.indexOf("tl")!=-1);
+var _601=(_599.indexOf("tr")!=-1);
+if(_600&&_601){
+return "";
+}
+if(_600){
+return "left";
+}
+if(_601){
+return "right";
+}
+return "";
+},_whichSideBottom:function(){
+var _602=this.options.corners;
+if(this._hasString(_602,"all","bottom")){
+return "";
+}
+var _603=(_602.indexOf("bl")!=-1);
+var _604=(_602.indexOf("br")!=-1);
+if(_603&&_604){
+return "";
+}
+if(_603){
+return "left";
+}
+if(_604){
+return "right";
+}
+return "";
+},_borderColor:function(_605,_606){
+if(_605=="transparent"){
+return _606;
+}else{
+if(this.options.border){
+return this.options.border;
+}else{
+if(this.options.blend){
+return _606.blendedColor(_605);
+}
+}
+}
+return "";
+},_setMargin:function(el,n,_607){
+var _608=this._marginSize(n)+"px";
+var _609=(_607=="top"?this._whichSideTop():this._whichSideBottom());
+var _610=el.style;
+if(_609=="left"){
+_610.marginLeft=_608;
+_610.marginRight="0px";
+}else{
+if(_609=="right"){
+_610.marginRight=_608;
+_610.marginLeft="0px";
+}else{
+_610.marginLeft=_608;
+_610.marginRight=_608;
+}
+}
+},_setBorder:function(el,n,_611){
+var _612=this._borderSize(n)+"px";
+var _613=(_611=="top"?this._whichSideTop():this._whichSideBottom());
+var _614=el.style;
+if(_613=="left"){
+_614.borderLeftWidth=_612;
+_614.borderRightWidth="0px";
+}else{
+if(_613=="right"){
+_614.borderRightWidth=_612;
+_614.borderLeftWidth="0px";
+}else{
+_614.borderLeftWidth=_612;
+_614.borderRightWidth=_612;
+}
+}
+},_marginSize:function(n){
+if(this.isTransparent){
+return 0;
+}
+var o=this.options;
+if(o.compact&&o.blend){
+var _615=[1,0];
+return _615[n];
+}else{
+if(o.compact){
+var _616=[2,1];
+return _616[n];
+}else{
+if(o.blend){
+var _617=[3,2,1,0];
+return _617[n];
+}else{
+var _618=[5,3,2,1];
+return _618[n];
+}
+}
+}
+},_borderSize:function(n){
+var o=this.options;
+var _619;
+if(o.compact&&(o.blend||this.isTransparent)){
+return 1;
+}else{
+if(o.compact){
+_619=[1,0];
+}else{
+if(o.blend){
+_619=[2,1,1,1];
+}else{
+if(o.border){
+_619=[0,2,0,0];
+}else{
+if(this.isTransparent){
+_619=[5,3,2,1];
+}else{
+return 0;
+}
+}
+}
+}
+}
+return _619[n];
+},_hasString:function(str){
+for(var i=1;i<arguments.length;i++){
+if(str.indexOf(arguments[i])!=-1){
+return true;
+}
+}
+return false;
+},_isTopRounded:function(){
+return this._hasString(this.options.corners,"all","top","tl","tr");
+},_isBottomRounded:function(){
+return this._hasString(this.options.corners,"all","bottom","bl","br");
+},_hasSingleTextChild:function(el){
+return (el.childNodes.length==1&&el.childNodes[0].nodeType==3);
+}};
+MochiKit.Visual.roundElement=function(e,_620){
+new MochiKit.Visual._RoundCorners(e,_620);
+};
+MochiKit.Visual.roundClass=function(_621,_622,_623){
+var _624=MochiKit.DOM.getElementsByTagAndClassName(_621,_622);
+for(var i=0;i<_624.length;i++){
+MochiKit.Visual.roundElement(_624[i],_623);
+}
+};
+MochiKit.Visual.Color=MochiKit.Color.Color;
+MochiKit.Visual.getElementsComputedStyle=MochiKit.DOM.computedStyle;
+MochiKit.Visual.__new__=function(){
+var m=MochiKit.Base;
+m.nameFunctions(this);
+this.EXPORT_TAGS={":common":this.EXPORT,":all":m.concat(this.EXPORT,this.EXPORT_OK)};
+};
+MochiKit.Visual.EXPORT=["roundElement","roundClass"];
+MochiKit.Visual.EXPORT_OK=[];
+MochiKit.Visual.__new__();
+MochiKit.Base._exportSymbols(this,MochiKit.Visual);
+if(typeof (MochiKit)=="undefined"){
+MochiKit={};
+}
+if(typeof (MochiKit.MochiKit)=="undefined"){
+MochiKit.MochiKit={};
+}
+MochiKit.MochiKit.NAME="MochiKit.MochiKit";
+MochiKit.MochiKit.VERSION="1.3.1";
+MochiKit.MochiKit.__repr__=function(){
+return "["+this.NAME+" "+this.VERSION+"]";
+};
+MochiKit.MochiKit.toString=function(){
+return this.__repr__();
+};
+MochiKit.MochiKit.SUBMODULES=["Base","Iter","Logging","DateTime","Format","Async","DOM","LoggingPane","Color","Signal","Visual"];
+if(typeof (JSAN)!="undefined"||typeof (dojo)!="undefined"){
+if(typeof (dojo)!="undefined"){
+dojo.provide("MochiKit.MochiKit");
+dojo.require("MochiKit.*");
+}
+if(typeof (JSAN)!="undefined"){
+JSAN.use("MochiKit.Base",[]);
+JSAN.use("MochiKit.Iter",[]);
+JSAN.use("MochiKit.Logging",[]);
+JSAN.use("MochiKit.DateTime",[]);
+JSAN.use("MochiKit.Format",[]);
+JSAN.use("MochiKit.Async",[]);
+JSAN.use("MochiKit.DOM",[]);
+JSAN.use("MochiKit.LoggingPane",[]);
+JSAN.use("MochiKit.Color",[]);
+JSAN.use("MochiKit.Signal",[]);
+JSAN.use("MochiKit.Visual",[]);
+}
+(function(){
+var _625=MochiKit.Base.extend;
+var self=MochiKit.MochiKit;
+var _626=self.SUBMODULES;
+var _627=[];
+var _628=[];
+var _629={};
+var i,k,m,all;
+for(i=0;i<_626.length;i++){
+m=MochiKit[_626[i]];
+_625(_627,m.EXPORT);
+_625(_628,m.EXPORT_OK);
+for(k in m.EXPORT_TAGS){
+_629[k]=_625(_629[k],m.EXPORT_TAGS[k]);
+}
+all=m.EXPORT_TAGS[":all"];
+if(!all){
+all=_625(null,m.EXPORT,m.EXPORT_OK);
+}
+var j;
+for(j=0;j<all.length;j++){
+k=all[j];
+self[k]=m[k];
+}
+}
+self.EXPORT=_627;
+self.EXPORT_OK=_628;
+self.EXPORT_TAGS=_629;
+}());
+}else{
+if(typeof (MochiKit.__compat__)=="undefined"){
+MochiKit.__compat__=true;
+}
+(function(){
+var _630=document.getElementsByTagName("script");
+var _631="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
+var base=null;
+var _632=null;
+var _633={};
+var i;
+for(i=0;i<_630.length;i++){
+var src=_630[i].getAttribute("src");
+if(!src){
+continue;
+}
+_633[src]=true;
+if(src.match(/MochiKit.js$/)){
+base=src.substring(0,src.lastIndexOf("MochiKit.js"));
+_632=_630[i];
+}
+}
+if(base===null){
+return;
+}
+var _634=MochiKit.MochiKit.SUBMODULES;
+for(var i=0;i<_634.length;i++){
+if(MochiKit[_634[i]]){
+continue;
+}
+var uri=base+_634[i]+".js";
+if(uri in _633){
+continue;
+}
+if(document.documentElement&&document.documentElement.namespaceURI==_631){
+var s=document.createElementNS(_631,"script");
+s.setAttribute("id","MochiKit_"+base+_634[i]);
+s.setAttribute("src",uri);
+s.setAttribute("type","application/x-javascript");
+_632.parentNode.appendChild(s);
+}else{
+document.write("<script src=\""+uri+"\" type=\"text/javascript\"></script>");
+}
+}
+})();
+}
+
+
diff --git a/site/app/webroot/js/mochikit/__package__.js b/site/app/webroot/js/mochikit/__package__.js
new file mode 100644
index 0000000..2f5be0d
--- /dev/null
+++ b/site/app/webroot/js/mochikit/__package__.js
@@ -0,0 +1,2 @@
+dojo.hostenv.conditionalLoadModule({"common": ["MochiKit.MochiKit"]});
+dojo.hostenv.moduleLoaded("MochiKit.*");
diff --git a/site/app/webroot/js/mootools/mootools-release-1.11.js b/site/app/webroot/js/mootools/mootools-release-1.11.js
new file mode 100644
index 0000000..bf6e4a8
--- /dev/null
+++ b/site/app/webroot/js/mootools/mootools-release-1.11.js
@@ -0,0 +1,184 @@
+//MooTools, My Object Oriented Javascript Tools. Copyright (c) 2006-2007 Valerio Proietti, <http://mad4milk.net>, MIT Style License.
+
+var MooTools={version:"1.11"};function $defined(A){return(A!=undefined);}function $type(B){if(!$defined(B)){return false;}if(B.htmlElement){return"element";
+}var A=typeof B;if(A=="object"&&B.nodeName){switch(B.nodeType){case 1:return"element";case 3:return(/\S/).test(B.nodeValue)?"textnode":"whitespace";}}if(A=="object"||A=="function"){switch(B.constructor){case Array:return"array";
+case RegExp:return"regexp";case Class:return"class";}if(typeof B.length=="number"){if(B.item){return"collection";}if(B.callee){return"arguments";}}}return A;
+}function $merge(){var C={};for(var B=0;B<arguments.length;B++){for(var E in arguments[B]){var A=arguments[B][E];var D=C[E];if(D&&$type(A)=="object"&&$type(D)=="object"){C[E]=$merge(D,A);
+}else{C[E]=A;}}}return C;}var $extend=function(){var A=arguments;if(!A[1]){A=[this,A[0]];}for(var B in A[1]){A[0][B]=A[1][B];}return A[0];};var $native=function(){for(var B=0,A=arguments.length;
+B<A;B++){arguments[B].extend=function(C){for(var D in C){if(!this.prototype[D]){this.prototype[D]=C[D];}if(!this[D]){this[D]=$native.generic(D);}}};}};
+$native.generic=function(A){return function(B){return this.prototype[A].apply(B,Array.prototype.slice.call(arguments,1));};};$native(Function,Array,String,Number);
+function $chk(A){return !!(A||A===0);}function $pick(B,A){return $defined(B)?B:A;}function $random(B,A){return Math.floor(Math.random()*(A-B+1)+B);}function $time(){return new Date().getTime();
+}function $clear(A){clearTimeout(A);clearInterval(A);return null;}var Abstract=function(A){A=A||{};A.extend=$extend;return A;};var Window=new Abstract(window);
+var Document=new Abstract(document);document.head=document.getElementsByTagName("head")[0];window.xpath=!!(document.evaluate);if(window.ActiveXObject){window.ie=window[window.XMLHttpRequest?"ie7":"ie6"]=true;
+}else{if(document.childNodes&&!document.all&&!navigator.taintEnabled){window.webkit=window[window.xpath?"webkit420":"webkit419"]=true;}else{if(document.getBoxObjectFor!=null){window.gecko=true;
+}}}window.khtml=window.webkit;Object.extend=$extend;if(typeof HTMLElement=="undefined"){var HTMLElement=function(){};if(window.webkit){document.createElement("iframe");
+}HTMLElement.prototype=(window.webkit)?window["[[DOMElement.prototype]]"]:{};}HTMLElement.prototype.htmlElement=function(){};if(window.ie6){try{document.execCommand("BackgroundImageCache",false,true);
+}catch(e){}}var Class=function(B){var A=function(){return(arguments[0]!==null&&this.initialize&&$type(this.initialize)=="function")?this.initialize.apply(this,arguments):this;
+};$extend(A,this);A.prototype=B;A.constructor=Class;return A;};Class.empty=function(){};Class.prototype={extend:function(B){var C=new this(null);for(var D in B){var A=C[D];
+C[D]=Class.Merge(A,B[D]);}return new Class(C);},implement:function(){for(var B=0,A=arguments.length;B<A;B++){$extend(this.prototype,arguments[B]);}}};Class.Merge=function(C,D){if(C&&C!=D){var B=$type(D);
+if(B!=$type(C)){return D;}switch(B){case"function":var A=function(){this.parent=arguments.callee.parent;return D.apply(this,arguments);};A.parent=C;return A;
+case"object":return $merge(C,D);}}return D;};var Chain=new Class({chain:function(A){this.chains=this.chains||[];this.chains.push(A);return this;},callChain:function(){if(this.chains&&this.chains.length){this.chains.shift().delay(10,this);
+}},clearChain:function(){this.chains=[];}});var Events=new Class({addEvent:function(B,A){if(A!=Class.empty){this.$events=this.$events||{};this.$events[B]=this.$events[B]||[];
+this.$events[B].include(A);}return this;},fireEvent:function(C,B,A){if(this.$events&&this.$events[C]){this.$events[C].each(function(D){D.create({"bind":this,"delay":A,"arguments":B})();
+},this);}return this;},removeEvent:function(B,A){if(this.$events&&this.$events[B]){this.$events[B].remove(A);}return this;}});var Options=new Class({setOptions:function(){this.options=$merge.apply(null,[this.options].extend(arguments));
+if(this.addEvent){for(var A in this.options){if($type(this.options[A]=="function")&&(/^on[A-Z]/).test(A)){this.addEvent(A,this.options[A]);}}}return this;
+}});Array.extend({forEach:function(C,D){for(var B=0,A=this.length;B<A;B++){C.call(D,this[B],B,this);}},filter:function(D,E){var C=[];for(var B=0,A=this.length;
+B<A;B++){if(D.call(E,this[B],B,this)){C.push(this[B]);}}return C;},map:function(D,E){var C=[];for(var B=0,A=this.length;B<A;B++){C[B]=D.call(E,this[B],B,this);
+}return C;},every:function(C,D){for(var B=0,A=this.length;B<A;B++){if(!C.call(D,this[B],B,this)){return false;}}return true;},some:function(C,D){for(var B=0,A=this.length;
+B<A;B++){if(C.call(D,this[B],B,this)){return true;}}return false;},indexOf:function(C,D){var A=this.length;for(var B=(D<0)?Math.max(0,A+D):D||0;B<A;B++){if(this[B]===C){return B;
+}}return -1;},copy:function(D,C){D=D||0;if(D<0){D=this.length+D;}C=C||(this.length-D);var A=[];for(var B=0;B<C;B++){A[B]=this[D++];}return A;},remove:function(C){var B=0;
+var A=this.length;while(B<A){if(this[B]===C){this.splice(B,1);A--;}else{B++;}}return this;},contains:function(A,B){return this.indexOf(A,B)!=-1;},associate:function(C){var D={},B=Math.min(this.length,C.length);
+for(var A=0;A<B;A++){D[C[A]]=this[A];}return D;},extend:function(C){for(var B=0,A=C.length;B<A;B++){this.push(C[B]);}return this;},merge:function(C){for(var B=0,A=C.length;
+B<A;B++){this.include(C[B]);}return this;},include:function(A){if(!this.contains(A)){this.push(A);}return this;},getRandom:function(){return this[$random(0,this.length-1)]||null;
+},getLast:function(){return this[this.length-1]||null;}});Array.prototype.each=Array.prototype.forEach;Array.each=Array.forEach;function $A(A){return Array.copy(A);
+}function $each(C,B,D){if(C&&typeof C.length=="number"&&$type(C)!="object"){Array.forEach(C,B,D);}else{for(var A in C){B.call(D||C,C[A],A);}}}Array.prototype.test=Array.prototype.contains;
+String.extend({test:function(A,B){return(($type(A)=="string")?new RegExp(A,B):A).test(this);},toInt:function(){return parseInt(this,10);},toFloat:function(){return parseFloat(this);
+},camelCase:function(){return this.replace(/-\D/g,function(A){return A.charAt(1).toUpperCase();});},hyphenate:function(){return this.replace(/\w[A-Z]/g,function(A){return(A.charAt(0)+"-"+A.charAt(1).toLowerCase());
+});},capitalize:function(){return this.replace(/\b[a-z]/g,function(A){return A.toUpperCase();});},trim:function(){return this.replace(/^\s+|\s+$/g,"");
+},clean:function(){return this.replace(/\s{2,}/g," ").trim();},rgbToHex:function(B){var A=this.match(/\d{1,3}/g);return(A)?A.rgbToHex(B):false;},hexToRgb:function(B){var A=this.match(/^#?(\w{1,2})(\w{1,2})(\w{1,2})$/);
+return(A)?A.slice(1).hexToRgb(B):false;},contains:function(A,B){return(B)?(B+this+B).indexOf(B+A+B)>-1:this.indexOf(A)>-1;},escapeRegExp:function(){return this.replace(/([.*+?^${}()|[\]\/\\])/g,"\\$1");
+}});Array.extend({rgbToHex:function(D){if(this.length<3){return false;}if(this.length==4&&this[3]==0&&!D){return"transparent";}var B=[];for(var A=0;A<3;
+A++){var C=(this[A]-0).toString(16);B.push((C.length==1)?"0"+C:C);}return D?B:"#"+B.join("");},hexToRgb:function(C){if(this.length!=3){return false;}var A=[];
+for(var B=0;B<3;B++){A.push(parseInt((this[B].length==1)?this[B]+this[B]:this[B],16));}return C?A:"rgb("+A.join(",")+")";}});Function.extend({create:function(A){var B=this;
+A=$merge({"bind":B,"event":false,"arguments":null,"delay":false,"periodical":false,"attempt":false},A);if($chk(A.arguments)&&$type(A.arguments)!="array"){A.arguments=[A.arguments];
+}return function(E){var C;if(A.event){E=E||window.event;C=[(A.event===true)?E:new A.event(E)];if(A.arguments){C.extend(A.arguments);}}else{C=A.arguments||arguments;
+}var F=function(){return B.apply($pick(A.bind,B),C);};if(A.delay){return setTimeout(F,A.delay);}if(A.periodical){return setInterval(F,A.periodical);}if(A.attempt){try{return F();
+}catch(D){return false;}}return F();};},pass:function(A,B){return this.create({"arguments":A,"bind":B});},attempt:function(A,B){return this.create({"arguments":A,"bind":B,"attempt":true})();
+},bind:function(B,A){return this.create({"bind":B,"arguments":A});},bindAsEventListener:function(B,A){return this.create({"bind":B,"event":true,"arguments":A});
+},delay:function(B,C,A){return this.create({"delay":B,"bind":C,"arguments":A})();},periodical:function(A,C,B){return this.create({"periodical":A,"bind":C,"arguments":B})();
+}});Number.extend({toInt:function(){return parseInt(this);},toFloat:function(){return parseFloat(this);},limit:function(B,A){return Math.min(A,Math.max(B,this));
+},round:function(A){A=Math.pow(10,A||0);return Math.round(this*A)/A;},times:function(B){for(var A=0;A<this;A++){B(A);}}});var Element=new Class({initialize:function(D,C){if($type(D)=="string"){if(window.ie&&C&&(C.name||C.type)){var A=(C.name)?' name="'+C.name+'"':"";
+var B=(C.type)?' type="'+C.type+'"':"";delete C.name;delete C.type;D="<"+D+A+B+">";}D=document.createElement(D);}D=$(D);return(!C||!D)?D:D.set(C);}});var Elements=new Class({initialize:function(A){return(A)?$extend(A,this):this;
+}});Elements.extend=function(A){for(var B in A){this.prototype[B]=A[B];this[B]=$native.generic(B);}};function $(B){if(!B){return null;}if(B.htmlElement){return Garbage.collect(B);
+}if([window,document].contains(B)){return B;}var A=$type(B);if(A=="string"){B=document.getElementById(B);A=(B)?"element":false;}if(A!="element"){return null;
+}if(B.htmlElement){return Garbage.collect(B);}if(["object","embed"].contains(B.tagName.toLowerCase())){return B;}$extend(B,Element.prototype);B.htmlElement=function(){};
+return Garbage.collect(B);}document.getElementsBySelector=document.getElementsByTagName;function $$(){var D=[];for(var C=0,B=arguments.length;C<B;C++){var A=arguments[C];
+switch($type(A)){case"element":D.push(A);case"boolean":break;case false:break;case"string":A=document.getElementsBySelector(A,true);default:D.extend(A);
+}}return $$.unique(D);}$$.unique=function(G){var D=[];for(var C=0,A=G.length;C<A;C++){if(G[C].$included){continue;}var B=$(G[C]);if(B&&!B.$included){B.$included=true;
+D.push(B);}}for(var F=0,E=D.length;F<E;F++){D[F].$included=null;}return new Elements(D);};Elements.Multi=function(A){return function(){var D=arguments;
+var B=[];var G=true;for(var E=0,C=this.length,F;E<C;E++){F=this[E][A].apply(this[E],D);if($type(F)!="element"){G=false;}B.push(F);}return(G)?$$.unique(B):B;
+};};Element.extend=function(A){for(var B in A){HTMLElement.prototype[B]=A[B];Element.prototype[B]=A[B];Element[B]=$native.generic(B);var C=(Array.prototype[B])?B+"Elements":B;
+Elements.prototype[C]=Elements.Multi(B);}};Element.extend({set:function(A){for(var C in A){var B=A[C];switch(C){case"styles":this.setStyles(B);break;case"events":if(this.addEvents){this.addEvents(B);
+}break;case"properties":this.setProperties(B);break;default:this.setProperty(C,B);}}return this;},inject:function(C,A){C=$(C);switch(A){case"before":C.parentNode.insertBefore(this,C);
+break;case"after":var B=C.getNext();if(!B){C.parentNode.appendChild(this);}else{C.parentNode.insertBefore(this,B);}break;case"top":var D=C.firstChild;if(D){C.insertBefore(this,D);
+break;}default:C.appendChild(this);}return this;},injectBefore:function(A){return this.inject(A,"before");},injectAfter:function(A){return this.inject(A,"after");
+},injectInside:function(A){return this.inject(A,"bottom");},injectTop:function(A){return this.inject(A,"top");},adopt:function(){var A=[];$each(arguments,function(B){A=A.concat(B);
+});$$(A).inject(this);return this;},remove:function(){return this.parentNode.removeChild(this);},clone:function(C){var B=$(this.cloneNode(C!==false));if(!B.$events){return B;
+}B.$events={};for(var A in this.$events){B.$events[A]={"keys":$A(this.$events[A].keys),"values":$A(this.$events[A].values)};}return B.removeEvents();},replaceWith:function(A){A=$(A);
+this.parentNode.replaceChild(A,this);return A;},appendText:function(A){this.appendChild(document.createTextNode(A));return this;},hasClass:function(A){return this.className.contains(A," ");
+},addClass:function(A){if(!this.hasClass(A)){this.className=(this.className+" "+A).clean();}return this;},removeClass:function(A){this.className=this.className.replace(new RegExp("(^|\\s)"+A+"(?:\\s|$)"),"$1").clean();
+return this;},toggleClass:function(A){return this.hasClass(A)?this.removeClass(A):this.addClass(A);},setStyle:function(B,A){switch(B){case"opacity":return this.setOpacity(parseFloat(A));
+case"float":B=(window.ie)?"styleFloat":"cssFloat";}B=B.camelCase();switch($type(A)){case"number":if(!["zIndex","zoom"].contains(B)){A+="px";}break;case"array":A="rgb("+A.join(",")+")";
+}this.style[B]=A;return this;},setStyles:function(A){switch($type(A)){case"object":Element.setMany(this,"setStyle",A);break;case"string":this.style.cssText=A;
+}return this;},setOpacity:function(A){if(A==0){if(this.style.visibility!="hidden"){this.style.visibility="hidden";}}else{if(this.style.visibility!="visible"){this.style.visibility="visible";
+}}if(!this.currentStyle||!this.currentStyle.hasLayout){this.style.zoom=1;}if(window.ie){this.style.filter=(A==1)?"":"alpha(opacity="+A*100+")";}this.style.opacity=this.$tmp.opacity=A;
+return this;},getStyle:function(C){C=C.camelCase();var A=this.style[C];if(!$chk(A)){if(C=="opacity"){return this.$tmp.opacity;}A=[];for(var B in Element.Styles){if(C==B){Element.Styles[B].each(function(F){var E=this.getStyle(F);
+A.push(parseInt(E)?E:"0px");},this);if(C=="border"){var D=A.every(function(E){return(E==A[0]);});return(D)?A[0]:false;}return A.join(" ");}}if(C.contains("border")){if(Element.Styles.border.contains(C)){return["Width","Style","Color"].map(function(E){return this.getStyle(C+E);
+},this).join(" ");}else{if(Element.borderShort.contains(C)){return["Top","Right","Bottom","Left"].map(function(E){return this.getStyle("border"+E+C.replace("border",""));
+},this).join(" ");}}}if(document.defaultView){A=document.defaultView.getComputedStyle(this,null).getPropertyValue(C.hyphenate());}else{if(this.currentStyle){A=this.currentStyle[C];
+}}}if(window.ie){A=Element.fixStyle(C,A,this);}if(A&&C.test(/color/i)&&A.contains("rgb")){return A.split("rgb").splice(1,4).map(function(E){return E.rgbToHex();
+}).join(" ");}return A;},getStyles:function(){return Element.getMany(this,"getStyle",arguments);},walk:function(A,C){A+="Sibling";var B=(C)?this[C]:this[A];
+while(B&&$type(B)!="element"){B=B[A];}return $(B);},getPrevious:function(){return this.walk("previous");},getNext:function(){return this.walk("next");},getFirst:function(){return this.walk("next","firstChild");
+},getLast:function(){return this.walk("previous","lastChild");},getParent:function(){return $(this.parentNode);},getChildren:function(){return $$(this.childNodes);
+},hasChild:function(A){return !!$A(this.getElementsByTagName("*")).contains(A);},getProperty:function(D){var B=Element.Properties[D];if(B){return this[B];
+}var A=Element.PropertiesIFlag[D]||0;if(!window.ie||A){return this.getAttribute(D,A);}var C=this.attributes[D];return(C)?C.nodeValue:null;},removeProperty:function(B){var A=Element.Properties[B];
+if(A){this[A]="";}else{this.removeAttribute(B);}return this;},getProperties:function(){return Element.getMany(this,"getProperty",arguments);},setProperty:function(C,B){var A=Element.Properties[C];
+if(A){this[A]=B;}else{this.setAttribute(C,B);}return this;},setProperties:function(A){return Element.setMany(this,"setProperty",A);},setHTML:function(){this.innerHTML=$A(arguments).join("");
+return this;},setText:function(B){var A=this.getTag();if(["style","script"].contains(A)){if(window.ie){if(A=="style"){this.styleSheet.cssText=B;}else{if(A=="script"){this.setProperty("text",B);
+}}return this;}else{this.removeChild(this.firstChild);return this.appendText(B);}}this[$defined(this.innerText)?"innerText":"textContent"]=B;return this;
+},getText:function(){var A=this.getTag();if(["style","script"].contains(A)){if(window.ie){if(A=="style"){return this.styleSheet.cssText;}else{if(A=="script"){return this.getProperty("text");
+}}}else{return this.innerHTML;}}return($pick(this.innerText,this.textContent));},getTag:function(){return this.tagName.toLowerCase();},empty:function(){Garbage.trash(this.getElementsByTagName("*"));
+return this.setHTML("");}});Element.fixStyle=function(E,A,D){if($chk(parseInt(A))){return A;}if(["height","width"].contains(E)){var B=(E=="width")?["left","right"]:["top","bottom"];
+var C=0;B.each(function(F){C+=D.getStyle("border-"+F+"-width").toInt()+D.getStyle("padding-"+F).toInt();});return D["offset"+E.capitalize()]-C+"px";}else{if(E.test(/border(.+)Width|margin|padding/)){return"0px";
+}}return A;};Element.Styles={"border":[],"padding":[],"margin":[]};["Top","Right","Bottom","Left"].each(function(B){for(var A in Element.Styles){Element.Styles[A].push(A+B);
+}});Element.borderShort=["borderWidth","borderStyle","borderColor"];Element.getMany=function(B,D,C){var A={};$each(C,function(E){A[E]=B[D](E);});return A;
+};Element.setMany=function(B,D,C){for(var A in C){B[D](A,C[A]);}return B;};Element.Properties=new Abstract({"class":"className","for":"htmlFor","colspan":"colSpan","rowspan":"rowSpan","accesskey":"accessKey","tabindex":"tabIndex","maxlength":"maxLength","readonly":"readOnly","frameborder":"frameBorder","value":"value","disabled":"disabled","checked":"checked","multiple":"multiple","selected":"selected"});
+Element.PropertiesIFlag={"href":2,"src":2};Element.Methods={Listeners:{addListener:function(B,A){if(this.addEventListener){this.addEventListener(B,A,false);
+}else{this.attachEvent("on"+B,A);}return this;},removeListener:function(B,A){if(this.removeEventListener){this.removeEventListener(B,A,false);}else{this.detachEvent("on"+B,A);
+}return this;}}};window.extend(Element.Methods.Listeners);document.extend(Element.Methods.Listeners);Element.extend(Element.Methods.Listeners);var Garbage={elements:[],collect:function(A){if(!A.$tmp){Garbage.elements.push(A);
+A.$tmp={"opacity":1};}return A;},trash:function(D){for(var B=0,A=D.length,C;B<A;B++){if(!(C=D[B])||!C.$tmp){continue;}if(C.$events){C.fireEvent("trash").removeEvents();
+}for(var E in C.$tmp){C.$tmp[E]=null;}for(var F in Element.prototype){C[F]=null;}Garbage.elements[Garbage.elements.indexOf(C)]=null;C.htmlElement=C.$tmp=C=null;
+}Garbage.elements.remove(null);},empty:function(){Garbage.collect(window);Garbage.collect(document);Garbage.trash(Garbage.elements);}};window.addListener("beforeunload",function(){window.addListener("unload",Garbage.empty);
+if(window.ie){window.addListener("unload",CollectGarbage);}});var Event=new Class({initialize:function(C){if(C&&C.$extended){return C;}this.$extended=true;
+C=C||window.event;this.event=C;this.type=C.type;this.target=C.target||C.srcElement;if(this.target.nodeType==3){this.target=this.target.parentNode;}this.shift=C.shiftKey;
+this.control=C.ctrlKey;this.alt=C.altKey;this.meta=C.metaKey;if(["DOMMouseScroll","mousewheel"].contains(this.type)){this.wheel=(C.wheelDelta)?C.wheelDelta/120:-(C.detail||0)/3;
+}else{if(this.type.contains("key")){this.code=C.which||C.keyCode;for(var B in Event.keys){if(Event.keys[B]==this.code){this.key=B;break;}}if(this.type=="keydown"){var A=this.code-111;
+if(A>0&&A<13){this.key="f"+A;}}this.key=this.key||String.fromCharCode(this.code).toLowerCase();}else{if(this.type.test(/(click|mouse|menu)/)){this.page={"x":C.pageX||C.clientX+document.documentElement.scrollLeft,"y":C.pageY||C.clientY+document.documentElement.scrollTop};
+this.client={"x":C.pageX?C.pageX-window.pageXOffset:C.clientX,"y":C.pageY?C.pageY-window.pageYOffset:C.clientY};this.rightClick=(C.which==3)||(C.button==2);
+switch(this.type){case"mouseover":this.relatedTarget=C.relatedTarget||C.fromElement;break;case"mouseout":this.relatedTarget=C.relatedTarget||C.toElement;
+}this.fixRelatedTarget();}}}return this;},stop:function(){return this.stopPropagation().preventDefault();},stopPropagation:function(){if(this.event.stopPropagation){this.event.stopPropagation();
+}else{this.event.cancelBubble=true;}return this;},preventDefault:function(){if(this.event.preventDefault){this.event.preventDefault();}else{this.event.returnValue=false;
+}return this;}});Event.fix={relatedTarget:function(){if(this.relatedTarget&&this.relatedTarget.nodeType==3){this.relatedTarget=this.relatedTarget.parentNode;
+}},relatedTargetGecko:function(){try{Event.fix.relatedTarget.call(this);}catch(A){this.relatedTarget=this.target;}}};Event.prototype.fixRelatedTarget=(window.gecko)?Event.fix.relatedTargetGecko:Event.fix.relatedTarget;
+Event.keys=new Abstract({"enter":13,"up":38,"down":40,"left":37,"right":39,"esc":27,"space":32,"backspace":8,"tab":9,"delete":46});Element.Methods.Events={addEvent:function(C,B){this.$events=this.$events||{};
+this.$events[C]=this.$events[C]||{"keys":[],"values":[]};if(this.$events[C].keys.contains(B)){return this;}this.$events[C].keys.push(B);var A=C;var D=Element.Events[C];
+if(D){if(D.add){D.add.call(this,B);}if(D.map){B=D.map;}if(D.type){A=D.type;}}if(!this.addEventListener){B=B.create({"bind":this,"event":true});}this.$events[C].values.push(B);
+return(Element.NativeEvents.contains(A))?this.addListener(A,B):this;},removeEvent:function(C,B){if(!this.$events||!this.$events[C]){return this;}var F=this.$events[C].keys.indexOf(B);
+if(F==-1){return this;}var A=this.$events[C].keys.splice(F,1)[0];var E=this.$events[C].values.splice(F,1)[0];var D=Element.Events[C];if(D){if(D.remove){D.remove.call(this,B);
+}if(D.type){C=D.type;}}return(Element.NativeEvents.contains(C))?this.removeListener(C,E):this;},addEvents:function(A){return Element.setMany(this,"addEvent",A);
+},removeEvents:function(A){if(!this.$events){return this;}if(!A){for(var B in this.$events){this.removeEvents(B);}this.$events=null;}else{if(this.$events[A]){this.$events[A].keys.each(function(C){this.removeEvent(A,C);
+},this);this.$events[A]=null;}}return this;},fireEvent:function(C,B,A){if(this.$events&&this.$events[C]){this.$events[C].keys.each(function(D){D.create({"bind":this,"delay":A,"arguments":B})();
+},this);}return this;},cloneEvents:function(C,A){if(!C.$events){return this;}if(!A){for(var B in C.$events){this.cloneEvents(C,B);}}else{if(C.$events[A]){C.$events[A].keys.each(function(D){this.addEvent(A,D);
+},this);}}return this;}};window.extend(Element.Methods.Events);document.extend(Element.Methods.Events);Element.extend(Element.Methods.Events);Element.Events=new Abstract({"mouseenter":{type:"mouseover",map:function(A){A=new Event(A);
+if(A.relatedTarget!=this&&!this.hasChild(A.relatedTarget)){this.fireEvent("mouseenter",A);}}},"mouseleave":{type:"mouseout",map:function(A){A=new Event(A);
+if(A.relatedTarget!=this&&!this.hasChild(A.relatedTarget)){this.fireEvent("mouseleave",A);}}},"mousewheel":{type:(window.gecko)?"DOMMouseScroll":"mousewheel"}});
+Element.NativeEvents=["click","dblclick","mouseup","mousedown","mousewheel","DOMMouseScroll","mouseover","mouseout","mousemove","keydown","keypress","keyup","load","unload","beforeunload","resize","move","focus","blur","change","submit","reset","select","error","abort","contextmenu","scroll"];
+Function.extend({bindWithEvent:function(B,A){return this.create({"bind":B,"arguments":A,"event":Event});}});Elements.extend({filterByTag:function(A){return new Elements(this.filter(function(B){return(Element.getTag(B)==A);
+}));},filterByClass:function(A,C){var B=this.filter(function(D){return(D.className&&D.className.contains(A," "));});return(C)?B:new Elements(B);},filterById:function(C,B){var A=this.filter(function(D){return(D.id==C);
+});return(B)?A:new Elements(A);},filterByAttribute:function(B,A,D,E){var C=this.filter(function(F){var G=Element.getProperty(F,B);if(!G){return false;}if(!A){return true;
+}switch(A){case"=":return(G==D);case"*=":return(G.contains(D));case"^=":return(G.substr(0,D.length)==D);case"$=":return(G.substr(G.length-D.length)==D);
+case"!=":return(G!=D);case"~=":return G.contains(D," ");}return false;});return(E)?C:new Elements(C);}});function $E(A,B){return($(B)||document).getElement(A);
+}function $ES(A,B){return($(B)||document).getElementsBySelector(A);}$$.shared={"regexp":/^(\w*|\*)(?:#([\w-]+)|\.([\w-]+))?(?:\[(\w+)(?:([!*^$]?=)["']?([^"'\]]*)["']?)?])?$/,"xpath":{getParam:function(B,D,E,C){var A=[D.namespaceURI?"xhtml:":"",E[1]];
+if(E[2]){A.push('[@id="',E[2],'"]');}if(E[3]){A.push('[contains(concat(" ", @class, " "), " ',E[3],' ")]');}if(E[4]){if(E[5]&&E[6]){switch(E[5]){case"*=":A.push("[contains(@",E[4],', "',E[6],'")]');
+break;case"^=":A.push("[starts-with(@",E[4],', "',E[6],'")]');break;case"$=":A.push("[substring(@",E[4],", string-length(@",E[4],") - ",E[6].length,' + 1) = "',E[6],'"]');
+break;case"=":A.push("[@",E[4],'="',E[6],'"]');break;case"!=":A.push("[@",E[4],'!="',E[6],'"]');}}else{A.push("[@",E[4],"]");}}B.push(A.join(""));return B;
+},getItems:function(B,E,G){var F=[];var A=document.evaluate(".//"+B.join("//"),E,$$.shared.resolver,XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE,null);for(var D=0,C=A.snapshotLength;
+D<C;D++){F.push(A.snapshotItem(D));}return(G)?F:new Elements(F.map($));}},"normal":{getParam:function(A,C,E,B){if(B==0){if(E[2]){var D=C.getElementById(E[2]);
+if(!D||((E[1]!="*")&&(Element.getTag(D)!=E[1]))){return false;}A=[D];}else{A=$A(C.getElementsByTagName(E[1]));}}else{A=$$.shared.getElementsByTagName(A,E[1]);
+if(E[2]){A=Elements.filterById(A,E[2],true);}}if(E[3]){A=Elements.filterByClass(A,E[3],true);}if(E[4]){A=Elements.filterByAttribute(A,E[4],E[5],E[6],true);
+}return A;},getItems:function(A,B,C){return(C)?A:$$.unique(A);}},resolver:function(A){return(A=="xhtml")?"http://www.w3.org/1999/xhtml":false;},getElementsByTagName:function(D,C){var E=[];
+for(var B=0,A=D.length;B<A;B++){E.extend(D[B].getElementsByTagName(C));}return E;}};$$.shared.method=(window.xpath)?"xpath":"normal";Element.Methods.Dom={getElements:function(A,H){var C=[];
+A=A.trim().split(" ");for(var E=0,D=A.length;E<D;E++){var F=A[E];var G=F.match($$.shared.regexp);if(!G){break;}G[1]=G[1]||"*";var B=$$.shared[$$.shared.method].getParam(C,this,G,E);
+if(!B){break;}C=B;}return $$.shared[$$.shared.method].getItems(C,this,H);},getElement:function(A){return $(this.getElements(A,true)[0]||false);},getElementsBySelector:function(A,E){var D=[];
+A=A.split(",");for(var C=0,B=A.length;C<B;C++){D=D.concat(this.getElements(A[C],true));}return(E)?D:$$.unique(D);}};Element.extend({getElementById:function(C){var B=document.getElementById(C);
+if(!B){return false;}for(var A=B.parentNode;A!=this;A=A.parentNode){if(!A){return false;}}return B;},getElementsByClassName:function(A){return this.getElements("."+A);
+}});document.extend(Element.Methods.Dom);Element.extend(Element.Methods.Dom);Element.Events.domready={add:function(B){if(window.loaded){B.call(this);return ;
+}var A=function(){if(window.loaded){return ;}window.loaded=true;window.timer=$clear(window.timer);this.fireEvent("domready");}.bind(this);if(document.readyState&&window.webkit){window.timer=function(){if(["loaded","complete"].contains(document.readyState)){A();
+}}.periodical(50);}else{if(document.readyState&&window.ie){if(!$("ie_ready")){var C=(window.location.protocol=="https:")?"://0":"javascript:void(0)";document.write('<script id="ie_ready" defer src="'+C+'"><\/script>');
+$("ie_ready").onreadystatechange=function(){if(this.readyState=="complete"){A();}};}}else{window.addListener("load",A);document.addListener("DOMContentLoaded",A);
+}}}};window.onDomReady=function(A){return this.addEvent("domready",A);};window.extend({getWidth:function(){if(this.webkit419){return this.innerWidth;}if(this.opera){return document.body.clientWidth;
+}return document.documentElement.clientWidth;},getHeight:function(){if(this.webkit419){return this.innerHeight;}if(this.opera){return document.body.clientHeight;
+}return document.documentElement.clientHeight;},getScrollWidth:function(){if(this.ie){return Math.max(document.documentElement.offsetWidth,document.documentElement.scrollWidth);
+}if(this.webkit){return document.body.scrollWidth;}return document.documentElement.scrollWidth;},getScrollHeight:function(){if(this.ie){return Math.max(document.documentElement.offsetHeight,document.documentElement.scrollHeight);
+}if(this.webkit){return document.body.scrollHeight;}return document.documentElement.scrollHeight;},getScrollLeft:function(){return this.pageXOffset||document.documentElement.scrollLeft;
+},getScrollTop:function(){return this.pageYOffset||document.documentElement.scrollTop;},getSize:function(){return{"size":{"x":this.getWidth(),"y":this.getHeight()},"scrollSize":{"x":this.getScrollWidth(),"y":this.getScrollHeight()},"scroll":{"x":this.getScrollLeft(),"y":this.getScrollTop()}};
+},getPosition:function(){return{"x":0,"y":0};}});var Fx={};Fx.Base=new Class({options:{onStart:Class.empty,onComplete:Class.empty,onCancel:Class.empty,transition:function(A){return -(Math.cos(Math.PI*A)-1)/2;
+},duration:500,unit:"px",wait:true,fps:50},initialize:function(A){this.element=this.element||null;this.setOptions(A);if(this.options.initialize){this.options.initialize.call(this);
+}},step:function(){var A=$time();if(A<this.time+this.options.duration){this.delta=this.options.transition((A-this.time)/this.options.duration);this.setNow();
+this.increase();}else{this.stop(true);this.set(this.to);this.fireEvent("onComplete",this.element,10);this.callChain();}},set:function(A){this.now=A;this.increase();
+return this;},setNow:function(){this.now=this.compute(this.from,this.to);},compute:function(B,A){return(A-B)*this.delta+B;},start:function(B,A){if(!this.options.wait){this.stop();
+}else{if(this.timer){return this;}}this.from=B;this.to=A;this.change=this.to-this.from;this.time=$time();this.timer=this.step.periodical(Math.round(1000/this.options.fps),this);
+this.fireEvent("onStart",this.element);return this;},stop:function(A){if(!this.timer){return this;}this.timer=$clear(this.timer);if(!A){this.fireEvent("onCancel",this.element);
+}return this;},custom:function(B,A){return this.start(B,A);},clearTimer:function(A){return this.stop(A);}});Fx.Base.implement(new Chain,new Events,new Options);
+Fx.CSS={select:function(B,C){if(B.test(/color/i)){return this.Color;}var A=$type(C);if((A=="array")||(A=="string"&&C.contains(" "))){return this.Multi;
+}return this.Single;},parse:function(C,D,A){if(!A.push){A=[A];}var F=A[0],E=A[1];if(!$chk(E)){E=F;F=C.getStyle(D);}var B=this.select(D,E);return{"from":B.parse(F),"to":B.parse(E),"css":B};
+}};Fx.CSS.Single={parse:function(A){return parseFloat(A);},getNow:function(C,B,A){return A.compute(C,B);},getValue:function(C,A,B){if(A=="px"&&B!="opacity"){C=Math.round(C);
+}return C+A;}};Fx.CSS.Multi={parse:function(A){return A.push?A:A.split(" ").map(function(B){return parseFloat(B);});},getNow:function(E,D,C){var A=[];for(var B=0;
+B<E.length;B++){A[B]=C.compute(E[B],D[B]);}return A;},getValue:function(C,A,B){if(A=="px"&&B!="opacity"){C=C.map(Math.round);}return C.join(A+" ")+A;}};
+Fx.CSS.Color={parse:function(A){return A.push?A:A.hexToRgb(true);},getNow:function(E,D,C){var A=[];for(var B=0;B<E.length;B++){A[B]=Math.round(C.compute(E[B],D[B]));
+}return A;},getValue:function(A){return"rgb("+A.join(",")+")";}};Fx.Style=Fx.Base.extend({initialize:function(B,C,A){this.element=$(B);this.property=C;
+this.parent(A);},hide:function(){return this.set(0);},setNow:function(){this.now=this.css.getNow(this.from,this.to,this);},set:function(A){this.css=Fx.CSS.select(this.property,A);
+return this.parent(this.css.parse(A));},start:function(C,B){if(this.timer&&this.options.wait){return this;}var A=Fx.CSS.parse(this.element,this.property,[C,B]);
+this.css=A.css;return this.parent(A.from,A.to);},increase:function(){this.element.setStyle(this.property,this.css.getValue(this.now,this.options.unit,this.property));
+}});Element.extend({effect:function(B,A){return new Fx.Style(this,B,A);}});Fx.Styles=Fx.Base.extend({initialize:function(B,A){this.element=$(B);this.parent(A);
+},setNow:function(){for(var A in this.from){this.now[A]=this.css[A].getNow(this.from[A],this.to[A],this);}},set:function(C){var A={};this.css={};for(var B in C){this.css[B]=Fx.CSS.select(B,C[B]);
+A[B]=this.css[B].parse(C[B]);}return this.parent(A);},start:function(C){if(this.timer&&this.options.wait){return this;}this.now={};this.css={};var E={},D={};
+for(var B in C){var A=Fx.CSS.parse(this.element,B,C[B]);E[B]=A.from;D[B]=A.to;this.css[B]=A.css;}return this.parent(E,D);},increase:function(){for(var A in this.now){this.element.setStyle(A,this.css[A].getValue(this.now[A],this.options.unit,A));
+}}});Element.extend({effects:function(A){return new Fx.Styles(this,A);}});Fx.Transition=function(B,A){A=A||[];if($type(A)!="array"){A=[A];}return $extend(B,{easeIn:function(C){return B(C,A);
+},easeOut:function(C){return 1-B(1-C,A);},easeInOut:function(C){return(C<=0.5)?B(2*C,A)/2:(2-B(2*(1-C),A))/2;}});};Fx.Transitions=new Abstract({linear:function(A){return A;
+}});Fx.Transitions.extend=function(A){for(var B in A){Fx.Transitions[B]=new Fx.Transition(A[B]);Fx.Transitions.compat(B);}};Fx.Transitions.compat=function(A){["In","Out","InOut"].each(function(B){Fx.Transitions[A.toLowerCase()+B]=Fx.Transitions[A]["ease"+B];
+});};Fx.Transitions.extend({Pow:function(B,A){return Math.pow(B,A[0]||6);},Expo:function(A){return Math.pow(2,8*(A-1));},Circ:function(A){return 1-Math.sin(Math.acos(A));
+},Sine:function(A){return 1-Math.sin((1-A)*Math.PI/2);},Back:function(B,A){A=A[0]||1.618;return Math.pow(B,2)*((A+1)*B-A);},Bounce:function(D){var C;for(var B=0,A=1;
+1;B+=A,A/=2){if(D>=(7-4*B)/11){C=-Math.pow((11-6*B-11*D)/4,2)+A*A;break;}}return C;},Elastic:function(B,A){return Math.pow(2,10*--B)*Math.cos(20*B*Math.PI*(A[0]||1)/3);
+}});["Quad","Cubic","Quart","Quint"].each(function(B,A){Fx.Transitions[B]=new Fx.Transition(function(C){return Math.pow(C,[A+2]);});Fx.Transitions.compat(B);
+}); \ No newline at end of file
diff --git a/site/app/webroot/js/plotkit/Base.js b/site/app/webroot/js/plotkit/Base.js
new file mode 100644
index 0000000..49988c9
--- /dev/null
+++ b/site/app/webroot/js/plotkit/Base.js
@@ -0,0 +1,406 @@
+/*
+ PlotKit
+ =======
+ PlotKit is a collection of Javascript classes that allows
+ you to quickly visualise data using different types of charts.
+
+ For license/info/documentation: http://www.liquidx.net/plotkit/
+
+ Copyright
+ ---------
+ Copyright 2005,2006 (c) Alastair Tse <alastair^liquidx.net>
+ For use under the BSD license. <http://www.liquidx.net/plotkit>
+*/
+
+// --------------------------------------------------------------------
+// Check required components
+// --------------------------------------------------------------------
+
+try {
+ if (typeof(MochiKit.Base) == 'undefined' ||
+ typeof(MochiKit.DOM) == 'undefined' ||
+ typeof(MochiKit.Color) == 'undefined' ||
+ typeof(MochiKit.Format) == 'undefined')
+ {
+ throw "";
+ }
+}
+catch (e) {
+ throw "PlotKit depends on MochiKit.{Base,Color,DOM,Format}"
+}
+
+// -------------------------------------------------------------------
+// Inject Common Shortcuts we use into MochiKit.Color.Color
+// -------------------------------------------------------------------
+
+MochiKit.Base.update(MochiKit.Color.Color.prototype, {
+ asFillColor: function() {
+ return this.lighterColorWithLevel(0.3);
+ },
+
+ asStrokeColor: function() {
+ return this.darkerColorWithLevel(0.1);
+ },
+
+ asPointColor: function() {
+ return this.lighterColorWithLevel(0.1);
+ }
+});
+
+
+// -------------------------------------------------------------------
+// Define our own PlotKit namespace
+// -------------------------------------------------------------------
+
+if (typeof(PlotKit) == 'undefined') {
+ PlotKit = {};
+}
+
+PlotKit.NAME = "PlotKit";
+PlotKit.VERSION = "0.8";
+PlotKit.__repr__ = function() {
+ return "[" + this.NAME + " " + this.VERSION + "]";
+};
+
+PlotKit.toString = function() {
+ return this.__repr__();
+}
+
+// -------------------------------------------------------------------
+// Encapsulate all our utility function into it's own namespace.
+// -------------------------------------------------------------------
+
+if (typeof(PlotKit.Base) == 'undefined') {
+ PlotKit.Base = {};
+}
+
+PlotKit.Base.NAME = 'PlotKit.Base';
+PlotKit.Base.VERSION = PlotKit.VERSION;
+
+PlotKit.Base.__repr__ = function() {
+ return "[" + this.NAME + " " + this.VERSION + "]";
+};
+
+PlotKit.Base.toString = function() {
+ return this.__repr__();
+}
+
+
+// Detect whether we are using prototype.js
+PlotKit.Base.usingPrototype = function() {
+ try {
+ return (typeof(Object.extend) == 'function');
+ }
+ catch (e) {
+ return false;
+ }
+}
+
+
+MochiKit.Base.update(PlotKit.Base, {
+ roundInterval: function(range, intervals, precision) {
+ // We want to make the interval look regular,
+ var trunc = MochiKit.Format.roundToFixed;
+ var sep = range/intervals;
+ return parseFloat(trunc(sep, precision));
+ },
+
+ collapse: function(lst) {
+ var m = MochiKit.Base;
+ var biggerList = new Array();
+ for (var i = 0; i < lst.length; i++) {
+ biggerList = m.concat(biggerList, lst[i]);
+ }
+ if (PlotKit.Base.usingPrototype()) {
+ delete biggerList.extend;
+ delete biggerList.from;
+ delete biggerList.inspect;
+ }
+
+ return biggerList;
+ },
+
+ uniq: function(sortedList) {
+ // get unique elements in list, exactly the same as unix shell's uniq.
+ var m = MochiKit.Base;
+
+ if (!m.isArrayLike(sortedList) || (sortedList.length < 1))
+ return new Array();
+
+ var uniq = new Array();
+ var lastElem = sortedList[0];
+ uniq.push(sortedList[0]);
+ for (var i = 1; i < sortedList.length; i++) {
+ if (m.compare(sortedList[i], lastElem) != 0) {
+ lastElem = sortedList[i];
+ uniq.push(sortedList[i]);
+ }
+ }
+ return uniq;
+ },
+
+ colorScheme: function() {
+ var mb = MochiKit.Base;
+ var mc = MochiKit.Color
+ var scheme = ["red", "orange", "yellow", "green", "cyan", "blue", "purple", "magenta"];
+
+ var makeColor = function(name) {
+ return mc.Color[name + "Color"]()
+ };
+
+ return mb.map(makeColor, scheme);
+ },
+
+ baseDarkPrimaryColors: function () {
+ var hexColor = MochiKit.Color.Color.fromHexString;
+ return [hexColor("#ad3f40"),
+ hexColor("#ddac2c"),
+ hexColor("#dfdd0c"),
+ hexColor("#5276c4"),
+ hexColor("#739c5a")];
+ },
+
+ basePrimaryColors: function () {
+ var hexColor = MochiKit.Color.Color.fromHexString;
+ return [hexColor("#d24c4d"),
+ hexColor("#f2b32f"),
+ hexColor("#ece90e"),
+ hexColor("#5d83da"),
+ hexColor("#78a15d")];
+ },
+
+ baseBlueColors: function () {
+ var hexColor = MochiKit.Color.Color.fromHexString;
+ return [hexColor("#4b6b94"), hexColor("#5d81b4"), hexColor("#acbad2")];
+ },
+
+ palette: function(baseColor, fromLevel, toLevel, increment) {
+ var isNil = MochiKit.Base.isUndefinedOrNull;
+ var fractions = new Array();
+ if (isNil(increment))
+ increment = 0.1;
+ if (isNil(toLevel))
+ toLevel = 0.4;
+ if (isNil(fromLevel))
+ fromLevel = -0.2;
+
+ var level = fromLevel;
+ while (level <= toLevel) {
+ fractions.push(level);
+ level += increment;
+ }
+
+ var makeColor = function(color, fraction) {
+ return color.lighterColorWithLevel(fraction);
+ };
+ return MochiKit.Base.map(partial(makeColor, baseColor), fractions);
+ },
+
+ excanvasSupported: function() {
+ if (/MSIE/.test(navigator.userAgent) && !window.opera) {
+ return true;
+ }
+ return false;
+ },
+
+ // The following functions are from quirksmode.org
+ // http://www.quirksmode.org/js/findpos.html
+
+ findPosX: function(obj) {
+ var curleft = 0;
+ if (obj.offsetParent) {
+ while (obj.offsetParent) {
+ curleft += obj.offsetLeft
+ obj = obj.offsetParent;
+ }
+ }
+ else if (obj.x)
+ curleft += obj.x;
+ return curleft;
+ },
+
+ findPosY: function(obj) {
+ var curtop = 0;
+ if (obj.offsetParent) {
+ while (obj.offsetParent) {
+ curtop += obj.offsetTop
+ obj = obj.offsetParent;
+ }
+ }
+ else if (obj.y)
+ curtop += obj.y;
+ return curtop;
+ },
+
+ isFuncLike: function(obj) {
+ return (typeof(obj) == 'function');
+ }
+});
+
+//
+// Prototype.js aware (crippled) versions of map and items.
+//
+
+PlotKit.Base.map = function(fn, lst) {
+ if (PlotKit.Base.usingPrototype()) {
+ var rval = [];
+ for (var x in lst) {
+ if (typeof(lst[x]) == 'function') continue;
+ rval.push(fn(lst[x]));
+ }
+ return rval;
+ }
+ else {
+ return MochiKit.Base.map(fn, lst);
+ }
+};
+
+PlotKit.Base.items = function(lst) {
+ if (PlotKit.Base.usingPrototype()) {
+ var rval = [];
+ for (var x in lst) {
+ if (typeof(lst[x]) == 'function') continue;
+ rval.push([x, lst[x]]);
+ }
+ return rval;
+ }
+ else {
+ return MochiKit.Base.items(lst);
+ }
+};
+
+PlotKit.Base.keys = function(lst) {
+ if (PlotKit.Base.usingPrototype()) {
+ var rval = [];
+ for (var x in lst) {
+ if (typeof(lst[x]) == 'function') continue;
+ rval.push(x);
+ }
+ return rval;
+ }
+ else {
+ return MochiKit.Base.keys(lst);
+ }
+};
+
+//
+// colour schemes
+//
+
+PlotKit.Base.baseColors = function () {
+ var hexColor = MochiKit.Color.Color.fromHexString;
+ return [hexColor("#476fb2"),
+ hexColor("#be2c2b"),
+ hexColor("#85b730"),
+ hexColor("#734a99"),
+ hexColor("#26a1c5"),
+ hexColor("#fb8707"),
+ hexColor("#000000")];
+};
+
+PlotKit.Base.officeBaseStyle = {
+ "axisLineWidth": 2.0,
+ "axisLabelColor": Color.grayColor(),
+ "axisLineColor": Color.whiteColor(),
+ "padding": {top: 5, bottom: 10, left: 30, right: 30}
+};
+
+MochiKit.Base.update(PlotKit.Base,{
+ officeBlue: function() {
+ var r = {
+ "colorScheme": PlotKit.Base.palette(PlotKit.Base.baseColors()[0]),
+ "backgroundColor": PlotKit.Base.baseColors()[0].lighterColorWithLevel(0.45)
+ };
+ MochiKit.Base.update(r, PlotKit.Base.officeBaseStyle);
+ return r;
+ },
+ officeRed: function() {
+ var r = {
+ "colorScheme": PlotKit.Base.palette(PlotKit.Base.baseColors()[1]),
+ "backgroundColor": PlotKit.Base.baseColors()[1].lighterColorWithLevel(0.5)
+ };
+ MochiKit.Base.update(r, PlotKit.Base.officeBaseStyle);
+ return r;
+ },
+ officeGreen: function() {
+ var r = {
+ "colorScheme": PlotKit.Base.palette(PlotKit.Base.baseColors()[2]),
+ "backgroundColor": PlotKit.Base.baseColors()[2].lighterColorWithLevel(0.5)
+ };
+ MochiKit.Base.update(r, PlotKit.Base.officeBaseStyle);
+ return r;
+ },
+ officePurple: function() {
+ var r = {
+ "colorScheme": PlotKit.Base.palette(PlotKit.Base.baseColors()[3]),
+ "backgroundColor": PlotKit.Base.baseColors()[3].lighterColorWithLevel(0.5)
+ };
+ MochiKit.Base.update(r, PlotKit.Base.officeBaseStyle);
+ return r;
+ },
+
+ officeCyan: function() {
+ var r = {
+ "colorScheme": PlotKit.Base.palette(PlotKit.Base.baseColors()[4]),
+ "backgroundColor": PlotKit.Base.baseColors()[4].lighterColorWithLevel(0.5)
+ };
+ MochiKit.Base.update(r, PlotKit.Base.officeBaseStyle);
+ return r;
+ },
+
+ officeOrange: function() {
+ var r = {
+ "colorScheme": PlotKit.Base.palette(PlotKit.Base.baseColors()[5]),
+ "backgroundColor": PlotKit.Base.baseColors()[5].lighterColorWithLevel(0.4)
+ };
+ MochiKit.Base.update(r, PlotKit.Base.officeBaseStyle);
+ return r;
+ },
+
+ officeBlack: function() {
+ var r = {
+ "colorScheme": PlotKit.Base.palette(PlotKit.Base.baseColors()[6], 0.0, 0.6),
+ "backgroundColor": PlotKit.Base.baseColors()[6].lighterColorWithLevel(0.9)
+ };
+ MochiKit.Base.update(r, PlotKit.Base.officeBaseStyle);
+ return r;
+ }
+});
+
+
+PlotKit.Base.EXPORT = [
+ "baseColors",
+ "collapse",
+ "colorScheme",
+ "findPosX",
+ "findPosY",
+ "officeBaseStyle",
+ "officeBlue",
+ "officeRed",
+ "officeGreen",
+ "officePurple",
+ "officeCyan",
+ "officeOrange",
+ "officeBlack",
+ "roundInterval",
+ "uniq",
+ "isFuncLike",
+ "excanvasSupported"
+];
+
+PlotKit.Base.EXPORT_OK = [];
+
+PlotKit.Base.__new__ = function() {
+ var m = MochiKit.Base;
+
+ m.nameFunctions(this);
+
+ this.EXPORT_TAGS = {
+ ":common": this.EXPORT,
+ ":all": m.concat(this.EXPORT, this.EXPORT_OK)
+ };
+};
+
+PlotKit.Base.__new__();
+MochiKit.Base._exportSymbols(this, PlotKit.Base);
+
diff --git a/site/app/webroot/js/plotkit/Canvas.js b/site/app/webroot/js/plotkit/Canvas.js
new file mode 100644
index 0000000..1e88e3c
--- /dev/null
+++ b/site/app/webroot/js/plotkit/Canvas.js
@@ -0,0 +1,683 @@
+/*
+ PlotKit Canvas
+ ==============
+
+ Provides HTML Canvas Renderer. This is supported under:
+
+ - Safari 2.0
+ - Mozilla Firefox 1.5
+ - Opera 9.0 preview 2
+ - IE 6 (via VML Emulation)
+
+ It uses DIVs for labels.
+
+ Copyright
+ ---------
+ Copyright 2005,2006 (c) Alastair Tse <alastair^liquidx.net>
+ For use under the BSD license. <http://www.liquidx.net/plotkit>
+
+*/
+// --------------------------------------------------------------------
+// Check required components
+// --------------------------------------------------------------------
+
+try {
+ if ((typeof(PlotKit.Base) == 'undefined') ||
+ (typeof(PlotKit.Layout) == 'undefined'))
+ {
+ throw "";
+ }
+}
+catch (e) {
+ throw "PlotKit.Layout depends on MochiKit.{Base,Color,DOM,Format} and PlotKit.{Base,Layout}"
+}
+
+
+// ------------------------------------------------------------------------
+// Defines the renderer class
+// ------------------------------------------------------------------------
+
+if (typeof(PlotKit.CanvasRenderer) == 'undefined') {
+ PlotKit.CanvasRenderer = {};
+}
+
+PlotKit.CanvasRenderer.NAME = "PlotKit.CanvasRenderer";
+PlotKit.CanvasRenderer.VERSION = PlotKit.VERSION;
+
+PlotKit.CanvasRenderer.__repr__ = function() {
+ return "[" + this.NAME + " " + this.VERSION + "]";
+};
+
+PlotKit.CanvasRenderer.toString = function() {
+ return this.__repr__();
+}
+
+PlotKit.CanvasRenderer = function(element, layout, options) {
+ if (arguments.length > 0)
+ this.__init__(element, layout, options);
+};
+
+PlotKit.CanvasRenderer.prototype.__init__ = function(element, layout, options) {
+ var isNil = MochiKit.Base.isUndefinedOrNull;
+ var Color = MochiKit.Color.Color;
+
+ // default options
+ this.options = {
+ "drawBackground": true,
+ "backgroundColor": Color.whiteColor(),
+ "padding": {left: 30, right: 30, top: 5, bottom: 10},
+ "colorScheme": PlotKit.Base.palette(PlotKit.Base.baseColors()[0]),
+ "strokeColor": Color.whiteColor(),
+ "strokeColorTransform": "asStrokeColor",
+ "strokeWidth": 0.5,
+ "shouldFill": true,
+ "shouldStroke": true,
+ "drawXAxis": true,
+ "drawYAxis": true,
+ "axisLineColor": Color.blackColor(),
+ "axisLineWidth": 0.5,
+ "axisTickSize": 3,
+ "axisLabelColor": Color.blackColor(),
+ "axisLabelFont": "Arial",
+ "axisLabelFontSize": 9,
+ "axisLabelWidth": 50,
+ "pieRadius": 0.4,
+ "enableEvents": true
+ };
+ MochiKit.Base.update(this.options, options ? options : {});
+
+ this.layout = layout;
+ this.element = MochiKit.DOM.getElement(element);
+ this.container = this.element.parentNode;
+
+ // Stuff relating to Canvas on IE support
+ this.isIE = PlotKit.Base.excanvasSupported();
+
+ if (this.isIE && !isNil(G_vmlCanvasManager)) {
+ this.IEDelay = 0.5;
+ this.maxTries = 5;
+ this.renderDelay = null;
+ this.clearDelay = null;
+ this.element = G_vmlCanvasManager.initElement(this.element);
+ }
+
+ this.height = this.element.height;
+ this.width = this.element.width;
+
+ // --- check whether everything is ok before we return
+
+ if (isNil(this.element))
+ throw "CanvasRenderer() - passed canvas is not found";
+
+ if (!this.isIE && !(PlotKit.CanvasRenderer.isSupported(this.element)))
+ throw "CanvasRenderer() - Canvas is not supported.";
+
+ if (isNil(this.container) || (this.container.nodeName.toLowerCase() != "div"))
+ throw "CanvasRenderer() - <canvas> needs to be enclosed in <div>";
+
+ // internal state
+ this.xlabels = new Array();
+ this.ylabels = new Array();
+ this.isFirstRender = true;
+
+ this.area = {
+ x: this.options.padding.left,
+ y: this.options.padding.top,
+ w: this.width - this.options.padding.left - this.options.padding.right,
+ h: this.height - this.options.padding.top - this.options.padding.bottom
+ };
+
+ MochiKit.DOM.updateNodeAttributes(this.container,
+ {"style":{ "position": "relative", "width": this.width + "px"}});
+
+ // load event system if we have Signals
+ /* Disabled until we have a proper implementation
+ try {
+ this.event_isinside = null;
+ if (MochiKit.Signal && this.options.enableEvents) {
+ this._initialiseEvents();
+ }
+ }
+ catch (e) {
+ // still experimental
+ }
+ */
+};
+
+PlotKit.CanvasRenderer.prototype.render = function() {
+ if (this.isIE) {
+ // VML takes a while to start up, so we just poll every this.IEDelay
+ try {
+ if (this.renderDelay) {
+ this.renderDelay.cancel();
+ this.renderDelay = null;
+ }
+ var context = this.element.getContext("2d");
+ }
+ catch (e) {
+ this.isFirstRender = false;
+ if (this.maxTries-- > 0) {
+ this.renderDelay = MochiKit.Async.wait(this.IEDelay);
+ this.renderDelay.addCallback(bind(this.render, this));
+ }
+ return;
+ }
+ }
+
+ if (this.options.drawBackground)
+ this._renderBackground();
+
+ if (this.layout.style == "bar") {
+ this._renderBarChart();
+ this._renderBarAxis();
+ }
+ else if (this.layout.style == "pie") {
+ this._renderPieChart();
+ this._renderPieAxis();
+ }
+ else if (this.layout.style == "line") {
+ this._renderLineChart();
+ this._renderLineAxis();
+ }
+};
+
+PlotKit.CanvasRenderer.prototype._renderBarChartWrap = function(data, plotFunc) {
+ var context = this.element.getContext("2d");
+ var colorCount = this.options.colorScheme.length;
+ var colorScheme = this.options.colorScheme;
+ var setNames = MochiKit.Base.keys(this.layout.datasets);
+ var setCount = setNames.length;
+
+ for (var i = 0; i < setCount; i++) {
+ var setName = setNames[i];
+ var color = colorScheme[i%colorCount];
+ context.save();
+ context.fillStyle = color.toRGBString();
+ if (this.options.strokeColor)
+ context.strokeStyle = this.options.strokeColor.toRGBString();
+ else if (this.options.strokeColorTransform)
+ context.strokeStyle = color[this.options.strokeColorTransform]().toRGBString();
+
+ context.lineWidth = this.options.strokeWidth;
+ var forEachFunc = function(obj) {
+ if (obj.name == setName)
+ plotFunc(context, obj);
+ };
+
+ MochiKit.Iter.forEach(data, bind(forEachFunc, this));
+ context.restore();
+ }
+};
+
+PlotKit.CanvasRenderer.prototype._renderBarChart = function() {
+ var bind = MochiKit.Base.bind;
+
+ var drawRect = function(context, bar) {
+ var x = this.area.w * bar.x + this.area.x;
+ var y = this.area.h * bar.y + this.area.y;
+ var w = this.area.w * bar.w;
+ var h = this.area.h * bar.h;
+ if ((w < 1) || (h < 1))
+ return;
+ if (this.options.shouldFill)
+ context.fillRect(x, y, w, h);
+ if (this.options.shouldStroke)
+ context.strokeRect(x, y, w, h);
+ };
+ this._renderBarChartWrap(this.layout.bars, bind(drawRect, this));
+};
+
+PlotKit.CanvasRenderer.prototype._renderLineChart = function() {
+ var context = this.element.getContext("2d");
+ var colorCount = this.options.colorScheme.length;
+ var colorScheme = this.options.colorScheme;
+ var setNames = MochiKit.Base.keys(this.layout.datasets);
+ var setCount = setNames.length;
+ var bind = MochiKit.Base.bind;
+ var partial = MochiKit.Base.partial;
+
+ for (var i = 0; i < setCount; i++) {
+ var setName = setNames[i];
+ var color = colorScheme[i%colorCount];
+ var strokeX = this.options.strokeColorTransform;
+
+ // setup graphics context
+ context.save();
+ context.fillStyle = color.toRGBString();
+ if (this.options.strokeColor)
+ context.strokeStyle = this.options.strokeColor.toRGBString();
+ else if (this.options.strokeColorTransform)
+ context.strokeStyle = color[strokeX]().toRGBString();
+
+ context.lineWidth = this.options.strokeWidth;
+
+ // create paths
+ var makePath = function(ctx) {
+ ctx.beginPath();
+ ctx.moveTo(this.area.x, this.area.y + this.area.h);
+ var addPoint = function(ctx_, point) {
+ if (point.name == setName)
+ ctx_.lineTo(this.area.w * point.x + this.area.x,
+ this.area.h * point.y + this.area.y);
+ };
+ MochiKit.Iter.forEach(this.layout.points, partial(addPoint, ctx), this);
+ ctx.lineTo(this.area.w + this.area.x,
+ this.area.h + this.area.y);
+ ctx.lineTo(this.area.x, this.area.y + this.area.h);
+ ctx.closePath();
+ };
+
+ if (this.options.shouldFill) {
+ bind(makePath, this)(context);
+ context.fill();
+ }
+ if (this.options.shouldStroke) {
+ bind(makePath, this)(context);
+ context.stroke();
+ }
+
+ context.restore();
+ }
+};
+
+PlotKit.CanvasRenderer.prototype._renderPieChart = function() {
+ var context = this.element.getContext("2d");
+ var colorCount = this.options.colorScheme.length;
+ var slices = this.layout.slices;
+
+ var centerx = this.area.x + this.area.w * 0.5;
+ var centery = this.area.y + this.area.h * 0.5;
+ var radius = Math.min(this.area.w * this.options.pieRadius,
+ this.area.h * this.options.pieRadius);
+
+ if (this.isIE) {
+ centerx = parseInt(centerx);
+ centery = parseInt(centery);
+ radius = parseInt(radius);
+ }
+
+
+ // NOTE NOTE!! Canvas Tag draws the circle clockwise from the y = 0, x = 1
+ // so we have to subtract 90 degrees to make it start at y = 1, x = 0
+
+ for (var i = 0; i < slices.length; i++) {
+ var color = this.options.colorScheme[i%colorCount];
+ context.save();
+ context.fillStyle = color.toRGBString();
+
+ var makePath = function() {
+ context.beginPath();
+ context.moveTo(centerx, centery);
+ context.arc(centerx, centery, radius,
+ slices[i].startAngle - Math.PI/2,
+ slices[i].endAngle - Math.PI/2,
+ false);
+ context.lineTo(centerx, centery);
+ context.closePath();
+ };
+
+ if (Math.abs(slices[i].startAngle - slices[i].endAngle) > 0.001) {
+ if (this.options.shouldFill) {
+ makePath();
+ context.fill();
+ }
+
+ if (this.options.shouldStroke) {
+ makePath();
+ context.lineWidth = this.options.strokeWidth;
+ if (this.options.strokeColor)
+ context.strokeStyle = this.options.strokeColor.toRGBString();
+ else if (this.options.strokeColorTransform)
+ context.strokeStyle = color[this.options.strokeColorTransform]().toRGBString();
+ context.stroke();
+ }
+ }
+ context.restore();
+ }
+};
+
+PlotKit.CanvasRenderer.prototype._renderBarAxis = function() {
+ this._renderAxis();
+}
+
+PlotKit.CanvasRenderer.prototype._renderLineAxis = function() {
+ this._renderAxis();
+};
+
+
+PlotKit.CanvasRenderer.prototype._renderAxis = function() {
+ if (!this.options.drawXAxis && !this.options.drawYAxis)
+ return;
+
+ var context = this.element.getContext("2d");
+
+ var labelStyle = {"style":
+ {"position": "absolute",
+ "fontSize": this.options.axisLabelFontSize + "px",
+ "zIndex": 10,
+ "color": this.options.axisLabelColor.toRGBString(),
+ "width": this.options.axisLabelWidth + "px",
+ "overflow": "hidden"
+ }
+ };
+
+ // axis lines
+ context.save();
+ context.strokeStyle = this.options.axisLineColor.toRGBString();
+ context.lineWidth = this.options.axisLineWidth;
+
+
+ if (this.options.drawYAxis) {
+ if (this.layout.yticks) {
+ var drawTick = function(tick) {
+ if (typeof(tick) == "function") return;
+ var x = this.area.x;
+ var y = this.area.y + tick[0] * this.area.h;
+ context.beginPath();
+ context.moveTo(x, y);
+ context.lineTo(x - this.options.axisTickSize, y);
+ context.closePath();
+ context.stroke();
+
+ var label = DIV(labelStyle, tick[1]);
+ label.style.top = (y - this.options.axisLabelFontSize) + "px";
+ label.style.left = (x - this.options.padding.left - this.options.axisTickSize) + "px";
+ label.style.textAlign = "right";
+ label.style.width = (this.options.padding.left - this.options.axisTickSize * 2) + "px";
+ MochiKit.DOM.appendChildNodes(this.container, label);
+ this.ylabels.push(label);
+ };
+
+ MochiKit.Iter.forEach(this.layout.yticks, bind(drawTick, this));
+ }
+
+ context.beginPath();
+ context.moveTo(this.area.x, this.area.y);
+ context.lineTo(this.area.x, this.area.y + this.area.h);
+ context.closePath();
+ context.stroke();
+ }
+
+ if (this.options.drawXAxis) {
+ if (this.layout.xticks) {
+ var drawTick = function(tick) {
+ if (typeof(dataset) == "function") return;
+
+ var x = this.area.x + tick[0] * this.area.w;
+ var y = this.area.y + this.area.h;
+ context.beginPath();
+ context.moveTo(x, y);
+ context.lineTo(x, y + this.options.axisTickSize);
+ context.closePath();
+ context.stroke();
+
+ var label = DIV(labelStyle, tick[1]);
+ label.style.top = (y + this.options.axisTickSize) + "px";
+ label.style.left = (x - this.options.axisLabelWidth/2) + "px";
+ label.style.textAlign = "center";
+ label.style.width = this.options.axisLabelWidth + "px";
+ MochiKit.DOM.appendChildNodes(this.container, label);
+ this.xlabels.push(label);
+ };
+
+ MochiKit.Iter.forEach(this.layout.xticks, bind(drawTick, this));
+ }
+
+ context.beginPath();
+ context.moveTo(this.area.x, this.area.y + this.area.h);
+ context.lineTo(this.area.x + this.area.w, this.area.y + this.area.h);
+ context.closePath();
+ context.stroke();
+ }
+
+ context.restore();
+
+};
+
+PlotKit.CanvasRenderer.prototype._renderPieAxis = function() {
+ if (!this.options.drawXAxis)
+ return;
+
+ if (this.layout.xticks) {
+ // make a lookup dict for x->slice values
+ var lookup = new Array();
+ for (var i = 0; i < this.layout.slices.length; i++) {
+ lookup[this.layout.slices[i].xval] = this.layout.slices[i];
+ }
+
+ var centerx = this.area.x + this.area.w * 0.5;
+ var centery = this.area.y + this.area.h * 0.5;
+ var radius = Math.min(this.area.w * this.options.pieRadius,
+ this.area.h * this.options.pieRadius);
+ var labelWidth = this.options.axisLabelWidth;
+
+ for (var i = 0; i < this.layout.xticks.length; i++) {
+ var slice = lookup[this.layout.xticks[i][0]];
+ if (MochiKit.Base.isUndefinedOrNull(slice))
+ continue;
+
+
+ var angle = (slice.startAngle + slice.endAngle)/2;
+ // normalize the angle
+ var normalisedAngle = angle;
+ if (normalisedAngle > Math.PI * 2)
+ normalisedAngle = normalisedAngle - Math.PI * 2;
+ else if (normalisedAngle < 0)
+ normalisedAngle = normalisedAngle + Math.PI * 2;
+
+ var labelx = centerx + Math.sin(normalisedAngle) * (radius + 10);
+ var labely = centery - Math.cos(normalisedAngle) * (radius + 10);
+
+ var attrib = {"position": "absolute",
+ "zIndex": 11,
+ "width": labelWidth + "px",
+ "fontSize": this.options.axisLabelFontSize + "px",
+ "overflow": "hidden",
+ "color": this.options.axisLabelColor.toHexString()
+ };
+
+ if (normalisedAngle <= Math.PI * 0.5) {
+ // text on top and align left
+ attrib["textAlign"] = "left";
+ attrib["verticalAlign"] = "top";
+ attrib["left"] = labelx + "px";
+ attrib["top"] = (labely - this.options.axisLabelFontSize) + "px";
+ }
+ else if ((normalisedAngle > Math.PI * 0.5) && (normalisedAngle <= Math.PI)) {
+ // text on bottom and align left
+ attrib["textAlign"] = "left";
+ attrib["verticalAlign"] = "bottom";
+ attrib["left"] = labelx + "px";
+ attrib["top"] = labely + "px";
+
+ }
+ else if ((normalisedAngle > Math.PI) && (normalisedAngle <= Math.PI*1.5)) {
+ // text on bottom and align right
+ attrib["textAlign"] = "right";
+ attrib["verticalAlign"] = "bottom";
+ attrib["left"] = (labelx - labelWidth) + "px";
+ attrib["top"] = labely + "px";
+ }
+ else {
+ // text on top and align right
+ attrib["textAlign"] = "right";
+ attrib["verticalAlign"] = "bottom";
+ attrib["left"] = (labelx - labelWidth) + "px";
+ attrib["top"] = (labely - this.options.axisLabelFontSize) + "px";
+ }
+
+ var label = DIV({'style': attrib}, this.layout.xticks[i][1]);
+ this.xlabels.push(label);
+ MochiKit.DOM.appendChildNodes(this.container, label);
+ }
+
+ }
+};
+
+PlotKit.CanvasRenderer.prototype._renderBackground = function() {
+ var context = this.element.getContext("2d");
+ context.save();
+ context.fillStyle = this.options.backgroundColor.toRGBString();
+ context.fillRect(0, 0, this.width, this.height);
+ context.restore();
+};
+
+PlotKit.CanvasRenderer.prototype.clear = function() {
+ if (this.isIE) {
+ // VML takes a while to start up, so we just poll every this.IEDelay
+ try {
+ if (this.clearDelay) {
+ this.clearDelay.cancel();
+ this.clearDelay = null;
+ }
+ var context = this.element.getContext("2d");
+ }
+ catch (e) {
+ this.isFirstRender = false;
+ this.clearDelay = MochiKit.Async.wait(this.IEDelay);
+ this.clearDelay.addCallback(bind(this.clear, this));
+ return;
+ }
+ }
+
+ var context = this.element.getContext("2d");
+ context.clearRect(0, 0, this.width, this.height);
+
+ MochiKit.Iter.forEach(this.xlabels, MochiKit.DOM.removeElement);
+ MochiKit.Iter.forEach(this.ylabels, MochiKit.DOM.removeElement);
+ this.xlabels = new Array();
+ this.ylabels = new Array();
+};
+
+// ----------------------------------------------------------------
+// Everything below here is experimental and undocumented.
+// ----------------------------------------------------------------
+
+PlotKit.CanvasRenderer.prototype._initialiseEvents = function() {
+ var connect = MochiKit.Signal.connect;
+ var bind = MochiKit.Base.bind;
+ //MochiKit.Signal.registerSignals(this, ['onmouseover', 'onclick', 'onmouseout', 'onmousemove']);
+ //connect(this.element, 'onmouseover', bind(this.onmouseover, this));
+ //connect(this.element, 'onmouseout', bind(this.onmouseout, this));
+ //connect(this.element, 'onmousemove', bind(this.onmousemove, this));
+ connect(this.element, 'onclick', bind(this.onclick, this));
+};
+
+PlotKit.CanvasRenderer.prototype._resolveObject = function(e) {
+ // does not work in firefox
+ //var x = (e.event().offsetX - this.area.x) / this.area.w;
+ //var y = (e.event().offsetY - this.area.y) / this.area.h;
+
+ var x = (e.mouse().page.x - PlotKit.Base.findPosX(this.element) - this.area.x) / this.area.w;
+ var y = (e.mouse().page.y - PlotKit.Base.findPosY(this.element) - this.area.y) / this.area.h;
+
+ //log(x, y);
+
+ var isHit = this.layout.hitTest(x, y);
+ if (isHit)
+ return isHit;
+ return null;
+};
+
+PlotKit.CanvasRenderer.prototype._createEventObject = function(layoutObj, e) {
+ if (layoutObj == null) {
+ return null;
+ }
+
+ e.chart = layoutObj
+ return e;
+};
+
+
+PlotKit.CanvasRenderer.prototype.onclick = function(e) {
+ var layoutObject = this._resolveObject(e);
+ var eventObject = this._createEventObject(layoutObject, e);
+ if (eventObject != null)
+ MochiKit.Signal.signal(this, "onclick", eventObject);
+};
+
+PlotKit.CanvasRenderer.prototype.onmouseover = function(e) {
+ var layoutObject = this._resolveObject(e);
+ var eventObject = this._createEventObject(layoutObject, e);
+ if (eventObject != null)
+ signal(this, "onmouseover", eventObject);
+};
+
+PlotKit.CanvasRenderer.prototype.onmouseout = function(e) {
+ var layoutObject = this._resolveObject(e);
+ var eventObject = this._createEventObject(layoutObject, e);
+ if (eventObject == null)
+ signal(this, "onmouseout", e);
+ else
+ signal(this, "onmouseout", eventObject);
+
+};
+
+PlotKit.CanvasRenderer.prototype.onmousemove = function(e) {
+ var layoutObject = this._resolveObject(e);
+ var eventObject = this._createEventObject(layoutObject, e);
+
+ if ((layoutObject == null) && (this.event_isinside == null)) {
+ // TODO: should we emit an event anyway?
+ return;
+ }
+
+ if ((layoutObject != null) && (this.event_isinside == null))
+ signal(this, "onmouseover", eventObject);
+
+ if ((layoutObject == null) && (this.event_isinside != null))
+ signal(this, "onmouseout", eventObject);
+
+ if ((layoutObject != null) && (this.event_isinside != null))
+ signal(this, "onmousemove", eventObject);
+
+ this.event_isinside = layoutObject;
+ //log("move", x, y);
+};
+
+PlotKit.CanvasRenderer.isSupported = function(canvasName) {
+ var canvas = null;
+ try {
+ if (MochiKit.Base.isUndefinedOrNull(canvasName))
+ canvas = MochiKit.DOM.CANVAS({});
+ else
+ canvas = MochiKit.DOM.getElement(canvasName);
+ var context = canvas.getContext("2d");
+ }
+ catch (e) {
+ var ie = navigator.appVersion.match(/MSIE (\d\.\d)/);
+ var opera = (navigator.userAgent.toLowerCase().indexOf("opera") != -1);
+ if ((!ie) || (ie[1] < 6) || (opera))
+ return false;
+ return true;
+ }
+ return true;
+};
+
+// Namespace Iniitialisation
+
+PlotKit.Canvas = {}
+PlotKit.Canvas.CanvasRenderer = PlotKit.CanvasRenderer;
+
+PlotKit.Canvas.EXPORT = [
+ "CanvasRenderer"
+];
+
+PlotKit.Canvas.EXPORT_OK = [
+ "CanvasRenderer"
+];
+
+PlotKit.Canvas.__new__ = function() {
+ var m = MochiKit.Base;
+
+ m.nameFunctions(this);
+
+ this.EXPORT_TAGS = {
+ ":common": this.EXPORT,
+ ":all": m.concat(this.EXPORT, this.EXPORT_OK)
+ };
+};
+
+PlotKit.Canvas.__new__();
+MochiKit.Base._exportSymbols(this, PlotKit.Canvas);
+
diff --git a/site/app/webroot/js/plotkit/EasyPlot.js b/site/app/webroot/js/plotkit/EasyPlot.js
new file mode 100644
index 0000000..7607731
--- /dev/null
+++ b/site/app/webroot/js/plotkit/EasyPlot.js
@@ -0,0 +1,161 @@
+/*
+ PlotKit EasyPlot
+ ================
+
+ User friendly wrapper around the common plotting functions.
+
+ Copyright
+ ---------
+ Copyright 2005,2006 (c) Alastair Tse <alastair^liquidx.net>
+ For use under the BSD license. <http://www.liquidx.net/plotkit>
+
+*/
+
+try {
+ if (typeof(PlotKit.CanvasRenderer) == 'undefined')
+ {
+ throw ""
+ }
+}
+catch (e) {
+ throw "PlotKit.EasyPlot depends on all of PlotKit's components";
+}
+
+// --------------------------------------------------------------------
+// Start of EasyPlot definition
+// --------------------------------------------------------------------
+
+if (typeof(PlotKit.EasyPlot) == 'undefined') {
+ PlotKit.EasyPlot = {};
+}
+
+PlotKit.EasyPlot.NAME = "PlotKit.EasyPlot";
+PlotKit.EasyPlot.VERSION = PlotKit.VERSION;
+
+PlotKit.EasyPlot.__repr__ = function() {
+ return "[" + this.NAME + " " + this.VERSION + "]";
+};
+
+PlotKit.EasyPlot.toString = function() {
+ return this.__repr__();
+}
+
+// --------------------------------------------------------------------
+// Start of EasyPlot definition
+// --------------------------------------------------------------------
+
+PlotKit.EasyPlot = function(style, options, divElem, datasources) {
+ this.layout = new Layout(style, options);
+ this.divElem = divElem;
+ this.width = parseInt(divElem.getAttribute('width'));
+ this.height = parseInt(divElem.getAttribute('height'));
+ this.deferredCount = 0;
+
+ // make sure we have non-zero width
+ if (this.width < 1) {
+ this.width = this.divElem.width ? this.divElem.width : 300;
+ }
+
+ if (this.height < 1) {
+ this.height = this.divElem.height ? this.divElem.height : 300;
+ }
+
+ // load data sources
+ if (isArrayLike(datasources)) {
+ for (var i = 0; i < datasources.length; i++) {
+ if (typeof(datasources[i]) == "string") {
+ this.deferredCount++;
+ // load CSV via ajax
+ var d = MochiKit.Async.doSimpleXMLHttpRequest(datasources[i]);
+ d.addCallback(MochiKit.Base.bind(PlotKit.EasyPlot.onDataLoaded, this));
+ }
+ else if (isArrayLike(datasources[i])) {
+ this.layout.addDataset("data-" + i, datasources[i]);
+ }
+ }
+ }
+ else if (!isUndefinedOrNull(datasources)) {
+ throw "Passed datasources are not Array like";
+ }
+
+ // setup canvas to render
+
+ if (CanvasRenderer.isSupported()) {
+ this.element = CANVAS({"id": this.divElem.getAttribute("id") + "-canvas",
+ "width": this.width,
+ "height": this.height}, "");
+ this.divElem.appendChild(this.element);
+ this.renderer = new SweetCanvasRenderer(this.element, this.layout, options);
+ }
+ else if (SVGRenderer.isSupported()) {
+ this.element = SVGRenderer.SVG({"id": this.divElem.getAttribute("id") + "-svg",
+ "width": this.width,
+ "height": this.height,
+ "version": "1.1",
+ "baseProfile": "full"}, "");
+ this.divElem.appendChild(this.element);
+ this.renderer = new SweetSVGRenderer(this.element, this.layout, options);
+ }
+
+ if ((this.deferredCount == 0) && (PlotKit.Base.keys(this.layout.datasets).length > 0)) {
+ this.layout.evaluate();
+ this.renderer.clear();
+ this.renderer.render();
+ }
+
+};
+
+PlotKit.EasyPlot.onDataLoaded = function(request) {
+
+ // very primitive CSV parser, should fix to make it more compliant.
+ var table = new Array();
+ var lines = request.responseText.split('\n');
+ for (var i = 0; i < lines.length; i++) {
+ var stripped = MochiKit.Format.strip(lines[i]);
+ if ((stripped.length > 1) && (stripped.charAt(0) != '#')) {
+ table.push(stripped.split(','));
+ }
+ }
+
+ this.layout.addDataset("data-ajax-" + this.deferredCount, table);
+ this.deferredCount--;
+
+ if ((this.deferredCount == 0) && (PlotKit.Base.keys(this.layout.datasets).length > 0)) {
+ this.layout.evaluate();
+ this.renderer.clear();
+ this.renderer.render();
+ }
+};
+
+PlotKit.EasyPlot.prototype.reload = function() {
+ this.layout.evaluate();
+ this.renderer.clear();
+ this.renderer.render();
+};
+
+// Namespace Iniitialisation
+
+PlotKit.EasyPlotModule = {};
+PlotKit.EasyPlotModule.EasyPlot = PlotKit.EasyPlot;
+
+PlotKit.EasyPlotModule.EXPORT = [
+ "EasyPlot"
+];
+
+PlotKit.EasyPlotModule.EXPORT_OK = [];
+
+PlotKit.EasyPlotModule.__new__ = function() {
+ var m = MochiKit.Base;
+
+ m.nameFunctions(this);
+
+ this.EXPORT_TAGS = {
+ ":common": this.EXPORT,
+ ":all": m.concat(this.EXPORT, this.EXPORT_OK)
+ };
+};
+
+PlotKit.EasyPlotModule.__new__();
+MochiKit.Base._exportSymbols(this, PlotKit.EasyPlotModule);
+
+
diff --git a/site/app/webroot/js/plotkit/Layout.js b/site/app/webroot/js/plotkit/Layout.js
new file mode 100644
index 0000000..ff1c9db
--- /dev/null
+++ b/site/app/webroot/js/plotkit/Layout.js
@@ -0,0 +1,756 @@
+/*
+ PlotKit Layout
+ ==============
+
+ Handles laying out data on to a virtual canvas square canvas between 0.0
+ and 1.0. If you want to add new chart/plot types such as point plots,
+ you need to add them here.
+
+ Copyright
+ ---------
+ Copyright 2005,2006 (c) Alastair Tse <alastair^liquidx.net>
+ For use under the BSD license. <http://www.liquidx.net/plotkit>
+
+*/
+
+try {
+ if (typeof(PlotKit.Base) == 'undefined')
+ {
+ throw ""
+ }
+}
+catch (e) {
+ throw "PlotKit.Layout depends on MochiKit.{Base,Color,DOM,Format} and PlotKit.Base"
+}
+
+// --------------------------------------------------------------------
+// Start of Layout definition
+// --------------------------------------------------------------------
+
+if (typeof(PlotKit.Layout) == 'undefined') {
+ PlotKit.Layout = {};
+}
+
+PlotKit.Layout.NAME = "PlotKit.Layout";
+PlotKit.Layout.VERSION = PlotKit.VERSION;
+
+PlotKit.Layout.__repr__ = function() {
+ return "[" + this.NAME + " " + this.VERSION + "]";
+};
+
+PlotKit.Layout.toString = function() {
+ return this.__repr__();
+}
+
+PlotKit.Layout.valid_styles = ["bar", "line", "pie", "point"];
+
+// --------------------------------------------------------------------
+// Start of Layout definition
+// --------------------------------------------------------------------
+
+PlotKit.Layout = function(style, options) {
+
+ this.options = {
+ "barWidthFillFraction": 0.75,
+ "barOrientation": "vertical",
+ "xOriginIsZero": true,
+ "yOriginIsZero": true,
+ "xAxis": null, // [xmin, xmax]
+ "yAxis": null, // [ymin, ymax]
+ "xTicks": null, // [{label: "somelabel", v: value}, ..] (label opt.)
+ "yTicks": null, // [{label: "somelabel", v: value}, ..] (label opt.)
+ "xNumberOfTicks": 10,
+ "yNumberOfTicks": 5,
+ "xTickPrecision": 1,
+ "yTickPrecision": 1,
+ "pieRadius": 0.4
+ };
+
+ // valid external options : TODO: input verification
+ this.style = style;
+ MochiKit.Base.update(this.options, options ? options : {});
+
+ // externally visible states
+ // overriden if xAxis and yAxis are set in options
+ if (!MochiKit.Base.isUndefinedOrNull(this.options.xAxis)) {
+ this.minxval = this.options.xAxis[0];
+ this.maxxval = this.options.xAxis[1];
+ this.xscale = this.maxxval - this.minxval;
+ }
+ else {
+ this.minxval = 0;
+ this.maxxval = null;
+ this.xscale = null; // val -> pos factor (eg, xval * xscale = xpos)
+ }
+
+ if (!MochiKit.Base.isUndefinedOrNull(this.options.yAxis)) {
+ this.minyval = this.options.yAxis[0];
+ this.maxyval = this.options.yAxis[1];
+ this.yscale = this.maxyval - this.minyval;
+ }
+ else {
+ this.minyval = 0;
+ this.maxyval = null;
+ this.yscale = null;
+ }
+
+ this.bars = new Array(); // array of bars to plot for bar charts
+ this.points = new Array(); // array of points to plot for line plots
+ this.slices = new Array(); // array of slices to draw for pie charts
+
+ this.xticks = new Array();
+ this.yticks = new Array();
+
+ // internal states
+ this.datasets = new Array();
+ this.minxdelta = 0;
+ this.xrange = 1;
+ this.yrange = 1;
+
+ this.hitTestCache = {x2maxy: null};
+
+};
+
+// --------------------------------------------------------------------
+// Dataset Manipulation
+// --------------------------------------------------------------------
+
+
+PlotKit.Layout.prototype.addDataset = function(setname, set_xy) {
+ this.datasets[setname] = set_xy;
+};
+
+PlotKit.Layout.prototype.removeDataset = function(setname, set_xy) {
+ delete this.datasets[setname];
+};
+
+PlotKit.Layout.prototype.addDatasetFromTable = function(name, tableElement, xcol, ycol, lcol) {
+ var isNil = MochiKit.Base.isUndefinedOrNull;
+ var scrapeText = MochiKit.DOM.scrapeText;
+ var strip = MochiKit.Format.strip;
+
+ if (isNil(xcol))
+ xcol = 0;
+ if (isNil(ycol))
+ ycol = 1;
+ if (isNil(lcol))
+ lcol = -1;
+
+ var rows = tableElement.tBodies[0].rows;
+ var data = new Array();
+ var labels = new Array();
+
+ if (!isNil(rows)) {
+ for (var i = 0; i < rows.length; i++) {
+ data.push([parseFloat(strip(scrapeText(rows[i].cells[xcol]))),
+ parseFloat(strip(scrapeText(rows[i].cells[ycol])))]);
+ if (lcol >= 0){
+ labels.push({v: parseFloat(strip(scrapeText(rows[i].cells[xcol]))),
+ label: strip(scrapeText(rows[i].cells[lcol]))});
+ }
+ }
+ this.addDataset(name, data);
+ if (lcol >= 0) {
+ this.options.xTicks = labels;
+ }
+ return true;
+ }
+ return false;
+};
+
+// --------------------------------------------------------------------
+// Evaluates the layout for the current data and style.
+// --------------------------------------------------------------------
+
+PlotKit.Layout.prototype.evaluate = function() {
+ this._evaluateLimits();
+ this._evaluateScales();
+ if (this.style == "bar") {
+ if (this.options.barOrientation == "horizontal") {
+ this._evaluateHorizBarCharts();
+ }
+ else {
+ this._evaluateBarCharts();
+ }
+ this._evaluateBarTicks();
+ }
+ else if (this.style == "line") {
+ this._evaluateLineCharts();
+ this._evaluateLineTicks();
+ }
+ else if (this.style == "pie") {
+ this._evaluatePieCharts();
+ this._evaluatePieTicks();
+ }
+};
+
+
+
+// Given the fractional x, y positions, report the corresponding
+// x, y values.
+PlotKit.Layout.prototype.hitTest = function(x, y) {
+ // TODO: make this more efficient with better datastructures
+ // for this.bars, this.points and this.slices
+
+ var f = MochiKit.Format.twoDigitFloat;
+
+ if ((this.style == "bar") && this.bars && (this.bars.length > 0)) {
+ for (var i = 0; i < this.bars.length; i++) {
+ var bar = this.bars[i];
+ if ((x >= bar.x) && (x <= bar.x + bar.w)
+ && (y >= bar.y) && (y - bar.y <= bar.h))
+ return bar;
+ }
+ }
+
+ else if (this.style == "line") {
+ if (this.hitTestCache.x2maxy == null) {
+ this._regenerateHitTestCache();
+ }
+
+ // 1. find the xvalues that equal or closest to the give x
+ var xval = x / this.xscale;
+ var xvalues = this.hitTestCache.xvalues;
+ var xbefore = null;
+ var xafter = null;
+
+ for (var i = 1; i < xvalues.length; i++) {
+ if (xvalues[i] > xval) {
+ xbefore = xvalues[i-1];
+ xafter = xvalues[i];
+ break;
+ }
+ }
+
+ if ((xbefore != null)) {
+ var ybefore = this.hitTestCache.x2maxy[xbefore];
+ var yafter = this.hitTestCache.x2maxy[xafter];
+ var yval = (1.0 - y)/this.yscale;
+
+ // interpolate whether we will fall inside or outside
+ var gradient = (yafter - ybefore) / (xafter - xbefore);
+ var projmaxy = ybefore + gradient * (xval - xbefore);
+ if (projmaxy >= yval) {
+ // inside the highest curve (roughly)
+ var obj = {xval: xval, yval: yval,
+ xafter: xafter, yafter: yafter,
+ xbefore: xbefore, ybefore: ybefore,
+ yprojected: projmaxy
+ };
+ return obj;
+ }
+ }
+ }
+
+ else if (this.style == "pie") {
+ var dist = Math.sqrt((y-0.5)*(y-0.5) + (x-0.5)*(x-0.5));
+ if (dist > this.options.pieRadius)
+ return null;
+
+ // TODO: actually doesn't work if we don't know how the Canvas
+ // lays it out, need to fix!
+ var angle = Math.atan2(y - 0.5, x - 0.5) - Math.PI/2;
+ for (var i = 0; i < this.slices.length; i++) {
+ var slice = this.slices[i];
+ if (slice.startAngle < angle && slice.endAngle >= angle)
+ return slice;
+ }
+ }
+
+ return null;
+};
+
+// Reports valid position rectangle for X value (only valid for bar charts)
+PlotKit.Layout.prototype.rectForX = function(x) {
+ return null;
+};
+
+// Reports valid angles through which X value encloses (only valid for pie charts)
+PlotKit.Layout.prototype.angleRangeForX = function(x) {
+ return null;
+};
+
+// --------------------------------------------------------------------
+// START Internal Functions
+// --------------------------------------------------------------------
+
+PlotKit.Layout.prototype._evaluateLimits = function() {
+ // take all values from all datasets and find max and min
+ var map = PlotKit.Base.map;
+ var items = PlotKit.Base.items;
+ var itemgetter = MochiKit.Base.itemgetter;
+ var collapse = PlotKit.Base.collapse;
+ var listMin = MochiKit.Base.listMin;
+ var listMax = MochiKit.Base.listMax;
+ var isNil = MochiKit.Base.isUndefinedOrNull;
+
+
+ var all = collapse(map(itemgetter(1), items(this.datasets)));
+ if (isNil(this.options.xAxis)) {
+ if (this.options.xOriginIsZero)
+ this.minxval = 0;
+ else
+ this.minxval = listMin(map(parseFloat, map(itemgetter(0), all)));
+
+ this.maxxval = listMax(map(parseFloat, map(itemgetter(0), all)));
+ }
+ else {
+ this.minxval = this.options.xAxis[0];
+ this.maxxval = this.options.xAxis[1];
+ this.xscale = this.maxval - this.minxval;
+ }
+
+ if (isNil(this.options.yAxis)) {
+ if (this.options.yOriginIsZero)
+ this.minyval = 0;
+ else
+ this.minyval = listMin(map(parseFloat, map(itemgetter(1), all)));
+
+ this.maxyval = listMax(map(parseFloat, map(itemgetter(1), all)));
+ }
+ else {
+ this.minyval = this.options.yAxis[0];
+ this.maxyval = this.options.yAxis[1];
+ this.yscale = this.maxyval - this.minyval;
+ }
+
+};
+
+PlotKit.Layout.prototype._evaluateScales = function() {
+ var isNil = MochiKit.Base.isUndefinedOrNull;
+
+ this.xrange = this.maxxval - this.minxval;
+ if (this.xrange == 0)
+ this.xscale = 1.0;
+ else
+ this.xscale = 1/this.xrange;
+
+ this.yrange = this.maxyval - this.minyval;
+ if (this.yrange == 0)
+ this.yscale = 1.0;
+ else
+ this.yscale = 1/this.yrange;
+};
+
+PlotKit.Layout.prototype._uniqueXValues = function() {
+ var collapse = PlotKit.Base.collapse;
+ var map = PlotKit.Base.map;
+ var uniq = PlotKit.Base.uniq;
+ var getter = MochiKit.Base.itemgetter;
+ var items = PlotKit.Base.items;
+
+ var xvalues = map(parseFloat, map(getter(0), collapse(map(getter(1), items(this.datasets)))));
+ xvalues.sort(MochiKit.Base.compare);
+ return uniq(xvalues);
+};
+
+// Create the bars
+PlotKit.Layout.prototype._evaluateBarCharts = function() {
+ var items = PlotKit.Base.items;
+
+ var setCount = items(this.datasets).length;
+
+ // work out how far separated values are
+ var xdelta = 10000000;
+ var xvalues = this._uniqueXValues();
+ for (var i = 1; i < xvalues.length; i++) {
+ xdelta = Math.min(Math.abs(xvalues[i] - xvalues[i-1]), xdelta);
+ }
+
+ var barWidth = 0;
+ var barWidthForSet = 0;
+ var barMargin = 0;
+ if (xvalues.length == 1) {
+ // note we have to do something smarter if we only plot one value
+ xdelta = 1.0;
+ this.xscale = 1.0;
+ this.minxval = xvalues[0];
+ barWidth = 1.0 * this.options.barWidthFillFraction;
+ barWidthForSet = barWidth/setCount;
+ barMargin = (1.0 - this.options.barWidthFillFraction)/2;
+ }
+ else {
+ // readjust xscale to fix with bar charts
+ if (this.xrange == 1) {
+ this.xscale = 0.5;
+ }
+ else if (this.xrange == 2) {
+ this.xscale = 1/3.0;
+ }
+ else {
+ this.xscale = (1.0 - xdelta/this.xrange)/this.xrange;
+ }
+ barWidth = xdelta * this.xscale * this.options.barWidthFillFraction;
+ barWidthForSet = barWidth / setCount;
+ barMargin = xdelta * this.xscale * (1.0 - this.options.barWidthFillFraction)/2;
+ }
+
+ this.minxdelta = xdelta; // need this for tick positions
+
+ // add all the rects
+ this.bars = new Array();
+ var i = 0;
+ for (var setName in this.datasets) {
+ var dataset = this.datasets[setName];
+ if (PlotKit.Base.isFuncLike(dataset)) continue;
+ for (var j = 0; j < dataset.length; j++) {
+ var item = dataset[j];
+ var rect = {
+ x: ((parseFloat(item[0]) - this.minxval) * this.xscale) + (i * barWidthForSet) + barMargin,
+ y: 1.0 - ((parseFloat(item[1]) - this.minyval) * this.yscale),
+ w: barWidthForSet,
+ h: ((parseFloat(item[1]) - this.minyval) * this.yscale),
+ xval: parseFloat(item[0]),
+ yval: parseFloat(item[1]),
+ name: setName
+ };
+ if ((rect.x >= 0.0) && (rect.x <= 1.0) &&
+ (rect.y >= 0.0) && (rect.y <= 1.0)) {
+ this.bars.push(rect);
+ }
+ }
+ i++;
+ }
+};
+
+// Create the horizontal bars
+PlotKit.Layout.prototype._evaluateHorizBarCharts = function() {
+ var items = PlotKit.Base.items;
+
+ var setCount = items(this.datasets).length;
+
+ // work out how far separated values are
+ var xdelta = 10000000;
+ var xvalues = this._uniqueXValues();
+ for (var i = 1; i < xvalues.length; i++) {
+ xdelta = Math.min(Math.abs(xvalues[i] - xvalues[i-1]), xdelta);
+ }
+
+ var barWidth = 0;
+ var barWidthForSet = 0;
+ var barMargin = 0;
+
+ // work out how far each far each bar is separated
+ if (xvalues.length == 1) {
+ // do something smarter if we only plot one value
+ xdelta = 1.0;
+ this.xscale = 1.0;
+ this.minxval = xvalues[0];
+ barWidth = 1.0 * this.options.barWidthFillFraction;
+ barWidthForSet = barWidth/setCount;
+ barMargin = (1.0 - this.options.barWidthFillFraction)/2;
+ }
+ else {
+ // readjust yscale to fix with bar charts
+ this.xscale = (1.0 - xdelta/this.xrange)/this.xrange;
+ barWidth = xdelta * this.xscale * this.options.barWidthFillFraction;
+ barWidthForSet = barWidth / setCount;
+ barMargin = xdelta * this.xscale * (1.0 - this.options.barWidthFillFraction)/2;
+ }
+
+ this.minxdelta = xdelta; // need this for tick positions
+
+ // add all the rects
+ this.bars = new Array();
+ var i = 0;
+ for (var setName in this.datasets) {
+ var dataset = this.datasets[setName];
+ if (PlotKit.Base.isFuncLike(dataset)) continue;
+ for (var j = 0; j < dataset.length; j++) {
+ var item = dataset[j];
+ var rect = {
+ y: ((parseFloat(item[0]) - this.minxval) * this.xscale) + (i * barWidthForSet) + barMargin,
+ x: 0.0,
+ h: barWidthForSet,
+ w: ((parseFloat(item[1]) - this.minyval) * this.yscale),
+ xval: parseFloat(item[0]),
+ yval: parseFloat(item[1]),
+ name: setName
+ };
+
+ // limit the x, y values so they do not overdraw
+ if (rect.y <= 0.0) {
+ rect.y = 0.0;
+ }
+ if (rect.y >= 1.0) {
+ rect.y = 1.0;
+ }
+ if ((rect.x >= 0.0) && (rect.x <= 1.0)) {
+ this.bars.push(rect);
+ }
+ }
+ i++;
+ }
+};
+
+
+// Create the line charts
+PlotKit.Layout.prototype._evaluateLineCharts = function() {
+ var items = PlotKit.Base.items;
+
+ var setCount = items(this.datasets).length;
+
+ // add all the rects
+ this.points = new Array();
+ var i = 0;
+ for (var setName in this.datasets) {
+ var dataset = this.datasets[setName];
+ if (PlotKit.Base.isFuncLike(dataset)) continue;
+ dataset.sort(function(a, b) { return compare(parseFloat(a[0]), parseFloat(b[0])); });
+ for (var j = 0; j < dataset.length; j++) {
+ var item = dataset[j];
+ var point = {
+ x: ((parseFloat(item[0]) - this.minxval) * this.xscale),
+ y: 1.0 - ((parseFloat(item[1]) - this.minyval) * this.yscale),
+ xval: parseFloat(item[0]),
+ yval: parseFloat(item[1]),
+ name: setName
+ };
+
+ // limit the x, y values so they do not overdraw
+ if (point.y <= 0.0) {
+ point.y = 0.0;
+ }
+ if (point.y >= 1.0) {
+ point.y = 1.0;
+ }
+ if ((point.x >= 0.0) && (point.x <= 1.0)) {
+ this.points.push(point);
+ }
+ }
+ i++;
+ }
+};
+
+// Create the pie charts
+PlotKit.Layout.prototype._evaluatePieCharts = function() {
+ var items = PlotKit.Base.items;
+ var sum = MochiKit.Iter.sum;
+ var getter = MochiKit.Base.itemgetter;
+
+ var setCount = items(this.datasets).length;
+
+ // we plot the y values of the first dataset
+ var dataset = items(this.datasets)[0][1];
+ var total = sum(map(getter(1), dataset));
+
+ this.slices = new Array();
+ var currentAngle = 0.0;
+ for (var i = 0; i < dataset.length; i++) {
+ var fraction = dataset[i][1] / total;
+ var startAngle = currentAngle * Math.PI * 2;
+ var endAngle = (currentAngle + fraction) * Math.PI * 2;
+
+ var slice = {fraction: fraction,
+ xval: dataset[i][0],
+ yval: dataset[i][1],
+ startAngle: startAngle,
+ endAngle: endAngle
+ };
+ if (dataset[i][1] != 0) {
+ this.slices.push(slice);
+ }
+ currentAngle += fraction;
+ }
+};
+
+PlotKit.Layout.prototype._evaluateLineTicksForXAxis = function() {
+ var isNil = MochiKit.Base.isUndefinedOrNull;
+
+ if (this.options.xTicks) {
+ // we use use specified ticks with optional labels
+
+ this.xticks = new Array();
+ var makeTicks = function(tick) {
+ var label = tick.label;
+ if (isNil(label))
+ label = tick.v.toString();
+ var pos = this.xscale * (tick.v - this.minxval);
+ if ((pos >= 0.0) && (pos <= 1.0)) {
+ this.xticks.push([pos, label]);
+ }
+ };
+ MochiKit.Iter.forEach(this.options.xTicks, bind(makeTicks, this));
+ }
+ else if (this.options.xNumberOfTicks) {
+ // we use defined number of ticks as hint to auto generate
+ var xvalues = this._uniqueXValues();
+ var roughSeparation = this.xrange / this.options.xNumberOfTicks;
+ var tickCount = 0;
+
+ this.xticks = new Array();
+ for (var i = 0; i <= xvalues.length; i++) {
+ if ((xvalues[i] - this.minxval) >= (tickCount * roughSeparation)) {
+ var pos = this.xscale * (xvalues[i] - this.minxval);
+ if ((pos > 1.0) || (pos < 0.0))
+ continue;
+ this.xticks.push([pos, xvalues[i]]);
+ tickCount++;
+ }
+ if (tickCount > this.options.xNumberOfTicks)
+ break;
+ }
+ }
+};
+
+PlotKit.Layout.prototype._evaluateLineTicksForYAxis = function() {
+ var isNil = MochiKit.Base.isUndefinedOrNull;
+
+
+ if (this.options.yTicks) {
+ this.yticks = new Array();
+ var makeTicks = function(tick) {
+ var label = tick.label;
+ if (isNil(label))
+ label = tick.v.toString();
+ var pos = 1.0 - (this.yscale * (tick.v - this.minyval));
+ if ((pos >= 0.0) && (pos <= 1.0)) {
+ this.yticks.push([pos, label]);
+ }
+ };
+ MochiKit.Iter.forEach(this.options.yTicks, bind(makeTicks, this));
+ }
+ else if (this.options.yNumberOfTicks) {
+ // We use the optionally defined number of ticks as a guide
+ this.yticks = new Array();
+
+ // if we get this separation right, we'll have good looking graphs
+ var roundInt = PlotKit.Base.roundInterval;
+ var prec = this.options.yTickPrecision;
+ var roughSeparation = roundInt(this.yrange,
+ this.options.yNumberOfTicks, prec);
+
+ // round off each value of the y-axis to the precision
+ // eg. 1.3333 at precision 1 -> 1.3
+ for (var i = 0; i <= this.options.yNumberOfTicks; i++) {
+ var yval = this.minyval + (i * roughSeparation);
+ var pos = 1.0 - ((yval - this.minyval) * this.yscale);
+ if ((pos > 1.0) || (pos < 0.0))
+ continue;
+ this.yticks.push([pos, MochiKit.Format.roundToFixed(yval, prec)]);
+ }
+ }
+};
+
+PlotKit.Layout.prototype._evaluateLineTicks = function() {
+ this._evaluateLineTicksForXAxis();
+ this._evaluateLineTicksForYAxis();
+};
+
+PlotKit.Layout.prototype._evaluateBarTicks = function() {
+ this._evaluateLineTicks();
+ var centerInBar = function(tick) {
+ return [tick[0] + (this.minxdelta * this.xscale)/2, tick[1]];
+ };
+ this.xticks = MochiKit.Base.map(bind(centerInBar, this), this.xticks);
+
+ if (this.options.barOrientation == "horizontal") {
+ // swap scales
+ var tempticks = this.xticks;
+ this.xticks = this.yticks;
+ this.yticks = tempticks;
+
+ // we need to invert the "yaxis" (which is now the xaxis when drawn)
+ var invert = function(tick) {
+ return [1.0 - tick[0], tick[1]];
+ }
+ this.xticks = MochiKit.Base.map(invert, this.xticks);
+ }
+};
+
+PlotKit.Layout.prototype._evaluatePieTicks = function() {
+ var isNil = MochiKit.Base.isUndefinedOrNull;
+ var formatter = MochiKit.Format.numberFormatter("#%");
+
+ this.xticks = new Array();
+ if (this.options.xTicks) {
+ // make a lookup dict for x->slice values
+ var lookup = new Array();
+ for (var i = 0; i < this.slices.length; i++) {
+ lookup[this.slices[i].xval] = this.slices[i];
+ }
+
+ for (var i =0; i < this.options.xTicks.length; i++) {
+ var tick = this.options.xTicks[i];
+ var slice = lookup[tick.v];
+ var label = tick.label;
+ if (slice) {
+ if (isNil(label))
+ label = tick.v.toString();
+ label += " (" + formatter(slice.fraction) + ")";
+ this.xticks.push([tick.v, label]);
+ }
+ }
+ }
+ else {
+ // we make our own labels from all the slices
+ for (var i =0; i < this.slices.length; i++) {
+ var slice = this.slices[i];
+ var label = slice.xval + " (" + formatter(slice.fraction) + ")";
+ this.xticks.push([slice.xval, label]);
+ }
+ }
+};
+
+PlotKit.Layout.prototype._regenerateHitTestCache = function() {
+ this.hitTestCache.xvalues = this._uniqueXValues();
+ this.hitTestCache.xlookup = new Array();
+ this.hitTestCache.x2maxy = new Array();
+
+ var listMax = MochiKit.Base.listMax;
+ var itemgetter = MochiKit.Base.itemgetter;
+ var map = MochiKit.Base.map;
+
+ // generate a lookup table for x values to y values
+ var setNames = keys(this.datasets);
+ for (var i = 0; i < setNames.length; i++) {
+ var dataset = this.datasets[setNames[i]];
+ for (var j = 0; j < dataset.length; j++) {
+ var xval = dataset[j][0];
+ var yval = dataset[j][1];
+ if (this.hitTestCache.xlookup[xval])
+ this.hitTestCache.xlookup[xval].push([yval, setNames[i]]);
+ else
+ this.hitTestCache.xlookup[xval] = [[yval, setNames[i]]];
+ }
+ }
+
+ for (var x in this.hitTestCache.xlookup) {
+ var yvals = this.hitTestCache.xlookup[x];
+ this.hitTestCache.x2maxy[x] = listMax(map(itemgetter(0), yvals));
+ }
+
+
+};
+
+// --------------------------------------------------------------------
+// END Internal Functions
+// --------------------------------------------------------------------
+
+
+// Namespace Iniitialisation
+
+PlotKit.LayoutModule = {};
+PlotKit.LayoutModule.Layout = PlotKit.Layout;
+
+PlotKit.LayoutModule.EXPORT = [
+ "Layout"
+];
+
+PlotKit.LayoutModule.EXPORT_OK = [];
+
+PlotKit.LayoutModule.__new__ = function() {
+ var m = MochiKit.Base;
+
+ m.nameFunctions(this);
+
+ this.EXPORT_TAGS = {
+ ":common": this.EXPORT,
+ ":all": m.concat(this.EXPORT, this.EXPORT_OK)
+ };
+};
+
+PlotKit.LayoutModule.__new__();
+MochiKit.Base._exportSymbols(this, PlotKit.LayoutModule);
+
+
diff --git a/site/app/webroot/js/plotkit/PlotKit.js b/site/app/webroot/js/plotkit/PlotKit.js
new file mode 100644
index 0000000..e79abf7
--- /dev/null
+++ b/site/app/webroot/js/plotkit/PlotKit.js
@@ -0,0 +1,151 @@
+/***
+
+PlotKit Autoload Javascript Module.
+
+This file was adapted from MochiKit.
+See <http://mochikit.com/> for documentation, downloads, license, etc.
+(c) 2005 Bob Ippolito. All rights Reserved.
+
+Modified by Alastair Tse, 2006, for PlotKit.
+
+***/
+
+if (typeof(PlotKit) == 'undefined') {
+ PlotKit = {};
+}
+
+if (typeof(PlotKit.PlotKit) == 'undefined') {
+ PlotKit.PlotKit = {};
+}
+
+PlotKit.PlotKit.NAME = "PlotKit.PlotKit";
+PlotKit.PlotKit.VERSION = "0.9.1";
+PlotKit.PlotKit.__repr__ = function () {
+ return "[" + this.NAME + " " + this.VERSION + "]";
+};
+
+PlotKit.PlotKit.toString = function () {
+ return this.__repr__();
+};
+
+PlotKit.PlotKit.SUBMODULES = [
+ "Base",
+ "Layout",
+ "Canvas",
+ "SVG",
+ "SweetCanvas",
+ "SweetSVG",
+ "EasyPlot"
+];
+
+if (typeof(JSAN) != 'undefined' || typeof(dojo) != 'undefined') {
+ if (typeof(dojo) != 'undefined') {
+ dojo.provide('PlotKit.PlotKit');
+ dojo.require("PlotKit.*");
+ }
+ if (typeof(JSAN) != 'undefined') {
+ // hopefully this makes it easier for static analysis?
+ JSAN.use("PlotKit.Base", []);
+ JSAN.use("PlotKit.Layout", []);
+ JSAN.use("PlotKit.Canvas", []);
+ JSAN.use("PlotKit.SweetCanvas", []);
+ JSAN.use("PlotKit.SVG", []);
+ JSAN.use("PlotKit.SweetSVG", []);
+ }
+ (function () {
+ var extend = MochiKit.Base.extend;
+ var self = PlotKit.PlotKit;
+ var modules = self.SUBMODULES;
+ var EXPORT = [];
+ var EXPORT_OK = [];
+ var EXPORT_TAGS = {};
+ var i, k, m, all;
+ for (i = 0; i < modules.length; i++) {
+ m = PlotKit[modules[i]];
+ extend(EXPORT, m.EXPORT);
+ extend(EXPORT_OK, m.EXPORT_OK);
+ for (k in m.EXPORT_TAGS) {
+ EXPORT_TAGS[k] = extend(EXPORT_TAGS[k], m.EXPORT_TAGS[k]);
+ }
+ all = m.EXPORT_TAGS[":all"];
+ if (!all) {
+ all = extend(null, m.EXPORT, m.EXPORT_OK);
+ }
+ var j;
+ for (j = 0; j < all.length; j++) {
+ k = all[j];
+ self[k] = m[k];
+ }
+ }
+ self.EXPORT = EXPORT;
+ self.EXPORT_OK = EXPORT_OK;
+ self.EXPORT_TAGS = EXPORT_TAGS;
+ }());
+
+} else {
+ if (typeof(PlotKit.__compat__) == 'undefined') {
+ PlotKit.__compat__ = true;
+ }
+ (function () {
+ if (typeof(document) == "undefined") {
+ return;
+ }
+
+ var scripts = document.getElementsByTagName("script");
+ var kXULNSURI = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
+ var base = null;
+ var baseElem = null;
+ var allScripts = {};
+ var i;
+ for (i = 0; i < scripts.length; i++) {
+ var src = scripts[i].getAttribute("src");
+ if (!src) {
+ continue;
+ }
+ allScripts[src] = true;
+ if (src.match(/PlotKit.js$/)) {
+ base = src.substring(0, src.lastIndexOf('PlotKit.js'));
+ baseElem = scripts[i];
+ }
+
+ }
+
+ if (base === null) {
+ return;
+ }
+ var modules = PlotKit.PlotKit.SUBMODULES;
+ for (var i = 0; i < modules.length; i++) {
+ if (PlotKit[modules[i]]) {
+ continue;
+ }
+ var uri = base + modules[i] + '.js';
+ if (uri in allScripts) {
+ continue;
+ }
+ if (document.documentElement &&
+ document.documentElement.namespaceURI == kXULNSURI) {
+ // XUL
+ var s = document.createElementNS(kXULNSURI, 'script');
+ s.setAttribute("id", "PlotKit_" + base + modules[i]);
+ s.setAttribute("src", uri);
+ s.setAttribute("type", "application/x-javascript");
+ baseElem.parentNode.appendChild(s);
+ } else {
+ // HTML
+ /*
+ DOM can not be used here because Safari does
+ deferred loading of scripts unless they are
+ in the document or inserted with document.write
+
+ This is not XHTML compliant. If you want XHTML
+ compliance then you must use the packed version of MochiKit
+ or include each script individually (basically unroll
+ these document.write calls into your XHTML source)
+
+ */
+ document.write('<script src="' + uri +
+ '" type="text/javascript"></script>');
+ }
+ };
+ })();
+}
diff --git a/site/app/webroot/js/plotkit/PlotKit_Packed.js b/site/app/webroot/js/plotkit/PlotKit_Packed.js
new file mode 100644
index 0000000..363042a
--- /dev/null
+++ b/site/app/webroot/js/plotkit/PlotKit_Packed.js
@@ -0,0 +1,2177 @@
+/***
+
+ PlotKit.PlotKit 0.9.1 : PACKED VERSION
+
+ THIS FILE IS AUTOMATICALLY GENERATED. If creating patches, please
+ diff against the source tree, not this file.
+
+ For more information, <http://www.liquidx.net/plotkit/>.
+
+ Copyright (c) 2006. Alastair Tse.
+
+***/
+
+try{
+if(typeof (MochiKit.Base)=="undefined"||typeof (MochiKit.DOM)=="undefined"||typeof (MochiKit.Color)=="undefined"||typeof (MochiKit.Format)=="undefined"){
+throw "";
+}
+}
+catch(e){
+throw "PlotKit depends on MochiKit.{Base,Color,DOM,Format}";
+}
+MochiKit.Base.update(MochiKit.Color.Color.prototype,{asFillColor:function(){
+return this.lighterColorWithLevel(0.3);
+},asStrokeColor:function(){
+return this.darkerColorWithLevel(0.1);
+},asPointColor:function(){
+return this.lighterColorWithLevel(0.1);
+}});
+if(typeof (PlotKit)=="undefined"){
+PlotKit={};
+}
+PlotKit.NAME="PlotKit";
+PlotKit.VERSION="0.8";
+PlotKit.__repr__=function(){
+return "["+this.NAME+" "+this.VERSION+"]";
+};
+PlotKit.toString=function(){
+return this.__repr__();
+};
+if(typeof (PlotKit.Base)=="undefined"){
+PlotKit.Base={};
+}
+PlotKit.Base.NAME="PlotKit.Base";
+PlotKit.Base.VERSION=PlotKit.VERSION;
+PlotKit.Base.__repr__=function(){
+return "["+this.NAME+" "+this.VERSION+"]";
+};
+PlotKit.Base.toString=function(){
+return this.__repr__();
+};
+PlotKit.Base.usingPrototype=function(){
+try{
+return (typeof (Object.extend)=="function");
+}
+catch(e){
+return false;
+}
+};
+MochiKit.Base.update(PlotKit.Base,{roundInterval:function(_1,_2,_3){
+var _4=MochiKit.Format.roundToFixed;
+var _5=_1/_2;
+return parseFloat(_4(_5,_3));
+},collapse:function(_6){
+var m=MochiKit.Base;
+var _8=new Array();
+for(var i=0;i<_6.length;i++){
+_8=m.concat(_8,_6[i]);
+}
+if(PlotKit.Base.usingPrototype()){
+delete _8.extend;
+delete _8.from;
+delete _8.inspect;
+}
+return _8;
+},uniq:function(_10){
+var m=MochiKit.Base;
+if(!m.isArrayLike(_10)||(_10.length<1)){
+return new Array();
+}
+var _11=new Array();
+var _12=_10[0];
+_11.push(_10[0]);
+for(var i=1;i<_10.length;i++){
+if(m.compare(_10[i],_12)!=0){
+_12=_10[i];
+_11.push(_10[i]);
+}
+}
+return _11;
+},colorScheme:function(){
+var mb=MochiKit.Base;
+var mc=MochiKit.Color;
+var _15=["red","orange","yellow","green","cyan","blue","purple","magenta"];
+var _16=function(_17){
+return mc.Color[_17+"Color"]();
+};
+return mb.map(_16,_15);
+},baseDarkPrimaryColors:function(){
+var _18=MochiKit.Color.Color.fromHexString;
+return [_18("#ad3f40"),_18("#ddac2c"),_18("#dfdd0c"),_18("#5276c4"),_18("#739c5a")];
+},basePrimaryColors:function(){
+var _19=MochiKit.Color.Color.fromHexString;
+return [_19("#d24c4d"),_19("#f2b32f"),_19("#ece90e"),_19("#5d83da"),_19("#78a15d")];
+},baseBlueColors:function(){
+var _20=MochiKit.Color.Color.fromHexString;
+return [_20("#4b6b94"),_20("#5d81b4"),_20("#acbad2")];
+},palette:function(_21,_22,_23,_24){
+var _25=MochiKit.Base.isUndefinedOrNull;
+var _26=new Array();
+if(_25(_24)){
+_24=0.1;
+}
+if(_25(_23)){
+_23=0.4;
+}
+if(_25(_22)){
+_22=-0.2;
+}
+var _27=_22;
+while(_27<=_23){
+_26.push(_27);
+_27+=_24;
+}
+var _28=function(_29,_30){
+return _29.lighterColorWithLevel(_30);
+};
+return MochiKit.Base.map(partial(_28,_21),_26);
+},excanvasSupported:function(){
+if(/MSIE/.test(navigator.userAgent)&&!window.opera){
+return true;
+}
+return false;
+},findPosX:function(obj){
+var _32=0;
+if(obj.offsetParent){
+while(obj.offsetParent){
+_32+=obj.offsetLeft;
+obj=obj.offsetParent;
+}
+}else{
+if(obj.x){
+_32+=obj.x;
+}
+}
+return _32;
+},findPosY:function(obj){
+var _33=0;
+if(obj.offsetParent){
+while(obj.offsetParent){
+_33+=obj.offsetTop;
+obj=obj.offsetParent;
+}
+}else{
+if(obj.y){
+_33+=obj.y;
+}
+}
+return _33;
+},isFuncLike:function(obj){
+return (typeof (obj)=="function");
+}});
+PlotKit.Base.map=function(fn,lst){
+if(PlotKit.Base.usingPrototype()){
+var _36=[];
+for(var x in lst){
+if(typeof (lst[x])=="function"){
+continue;
+}
+_36.push(fn(lst[x]));
+}
+return _36;
+}else{
+return MochiKit.Base.map(fn,lst);
+}
+};
+PlotKit.Base.items=function(lst){
+if(PlotKit.Base.usingPrototype()){
+var _38=[];
+for(var x in lst){
+if(typeof (lst[x])=="function"){
+continue;
+}
+_38.push([x,lst[x]]);
+}
+return _38;
+}else{
+return MochiKit.Base.items(lst);
+}
+};
+PlotKit.Base.keys=function(lst){
+if(PlotKit.Base.usingPrototype()){
+var _39=[];
+for(var x in lst){
+if(typeof (lst[x])=="function"){
+continue;
+}
+_39.push(x);
+}
+return _39;
+}else{
+return MochiKit.Base.keys(lst);
+}
+};
+PlotKit.Base.baseColors=function(){
+var _40=MochiKit.Color.Color.fromHexString;
+return [_40("#476fb2"),_40("#be2c2b"),_40("#85b730"),_40("#734a99"),_40("#26a1c5"),_40("#fb8707"),_40("#000000")];
+};
+PlotKit.Base.officeBaseStyle={"axisLineWidth":2,"axisLabelColor":Color.grayColor(),"axisLineColor":Color.whiteColor(),"padding":{top:5,bottom:10,left:30,right:30}};
+MochiKit.Base.update(PlotKit.Base,{officeBlue:function(){
+var r={"colorScheme":PlotKit.Base.palette(PlotKit.Base.baseColors()[0]),"backgroundColor":PlotKit.Base.baseColors()[0].lighterColorWithLevel(0.45)};
+MochiKit.Base.update(r,PlotKit.Base.officeBaseStyle);
+return r;
+},officeRed:function(){
+var r={"colorScheme":PlotKit.Base.palette(PlotKit.Base.baseColors()[1]),"backgroundColor":PlotKit.Base.baseColors()[1].lighterColorWithLevel(0.5)};
+MochiKit.Base.update(r,PlotKit.Base.officeBaseStyle);
+return r;
+},officeGreen:function(){
+var r={"colorScheme":PlotKit.Base.palette(PlotKit.Base.baseColors()[2]),"backgroundColor":PlotKit.Base.baseColors()[2].lighterColorWithLevel(0.5)};
+MochiKit.Base.update(r,PlotKit.Base.officeBaseStyle);
+return r;
+},officePurple:function(){
+var r={"colorScheme":PlotKit.Base.palette(PlotKit.Base.baseColors()[3]),"backgroundColor":PlotKit.Base.baseColors()[3].lighterColorWithLevel(0.5)};
+MochiKit.Base.update(r,PlotKit.Base.officeBaseStyle);
+return r;
+},officeCyan:function(){
+var r={"colorScheme":PlotKit.Base.palette(PlotKit.Base.baseColors()[4]),"backgroundColor":PlotKit.Base.baseColors()[4].lighterColorWithLevel(0.5)};
+MochiKit.Base.update(r,PlotKit.Base.officeBaseStyle);
+return r;
+},officeOrange:function(){
+var r={"colorScheme":PlotKit.Base.palette(PlotKit.Base.baseColors()[5]),"backgroundColor":PlotKit.Base.baseColors()[5].lighterColorWithLevel(0.4)};
+MochiKit.Base.update(r,PlotKit.Base.officeBaseStyle);
+return r;
+},officeBlack:function(){
+var r={"colorScheme":PlotKit.Base.palette(PlotKit.Base.baseColors()[6],0,0.6),"backgroundColor":PlotKit.Base.baseColors()[6].lighterColorWithLevel(0.9)};
+MochiKit.Base.update(r,PlotKit.Base.officeBaseStyle);
+return r;
+}});
+PlotKit.Base.EXPORT=["baseColors","collapse","colorScheme","findPosX","findPosY","officeBaseStyle","officeBlue","officeRed","officeGreen","officePurple","officeCyan","officeOrange","officeBlack","roundInterval","uniq","isFuncLike","excanvasSupported"];
+PlotKit.Base.EXPORT_OK=[];
+PlotKit.Base.__new__=function(){
+var m=MochiKit.Base;
+m.nameFunctions(this);
+this.EXPORT_TAGS={":common":this.EXPORT,":all":m.concat(this.EXPORT,this.EXPORT_OK)};
+};
+PlotKit.Base.__new__();
+MochiKit.Base._exportSymbols(this,PlotKit.Base);
+try{
+if(typeof (PlotKit.Base)=="undefined"){
+throw "";
+}
+}
+catch(e){
+throw "PlotKit.Layout depends on MochiKit.{Base,Color,DOM,Format} and PlotKit.Base";
+}
+if(typeof (PlotKit.Layout)=="undefined"){
+PlotKit.Layout={};
+}
+PlotKit.Layout.NAME="PlotKit.Layout";
+PlotKit.Layout.VERSION=PlotKit.VERSION;
+PlotKit.Layout.__repr__=function(){
+return "["+this.NAME+" "+this.VERSION+"]";
+};
+PlotKit.Layout.toString=function(){
+return this.__repr__();
+};
+PlotKit.Layout.valid_styles=["bar","line","pie","point"];
+PlotKit.Layout=function(_42,_43){
+this.options={"barWidthFillFraction":0.75,"barOrientation":"vertical","xOriginIsZero":true,"yOriginIsZero":true,"xAxis":null,"yAxis":null,"xTicks":null,"yTicks":null,"xNumberOfTicks":10,"yNumberOfTicks":5,"xTickPrecision":1,"yTickPrecision":1,"pieRadius":0.4};
+this.style=_42;
+MochiKit.Base.update(this.options,_43?_43:{});
+if(!MochiKit.Base.isUndefinedOrNull(this.options.xAxis)){
+this.minxval=this.options.xAxis[0];
+this.maxxval=this.options.xAxis[1];
+this.xscale=this.maxxval-this.minxval;
+}else{
+this.minxval=0;
+this.maxxval=null;
+this.xscale=null;
+}
+if(!MochiKit.Base.isUndefinedOrNull(this.options.yAxis)){
+this.minyval=this.options.yAxis[0];
+this.maxyval=this.options.yAxis[1];
+this.yscale=this.maxyval-this.minyval;
+}else{
+this.minyval=0;
+this.maxyval=null;
+this.yscale=null;
+}
+this.bars=new Array();
+this.points=new Array();
+this.slices=new Array();
+this.xticks=new Array();
+this.yticks=new Array();
+this.datasets=new Array();
+this.minxdelta=0;
+this.xrange=1;
+this.yrange=1;
+this.hitTestCache={x2maxy:null};
+};
+PlotKit.Layout.prototype.addDataset=function(_44,_45){
+this.datasets[_44]=_45;
+};
+PlotKit.Layout.prototype.removeDataset=function(_46,_47){
+delete this.datasets[_46];
+};
+PlotKit.Layout.prototype.addDatasetFromTable=function(_48,_49,_50,_51,_52){
+var _53=MochiKit.Base.isUndefinedOrNull;
+var _54=MochiKit.DOM.scrapeText;
+var _55=MochiKit.Format.strip;
+if(_53(_50)){
+_50=0;
+}
+if(_53(_51)){
+_51=1;
+}
+if(_53(_52)){
+_52=-1;
+}
+var _56=_49.tBodies[0].rows;
+var _57=new Array();
+var _58=new Array();
+if(!_53(_56)){
+for(var i=0;i<_56.length;i++){
+_57.push([parseFloat(_55(_54(_56[i].cells[_50]))),parseFloat(_55(_54(_56[i].cells[_51])))]);
+if(_52>=0){
+_58.push({v:parseFloat(_55(_54(_56[i].cells[_50]))),label:_55(_54(_56[i].cells[_52]))});
+}
+}
+this.addDataset(_48,_57);
+if(_52>=0){
+this.options.xTicks=_58;
+}
+return true;
+}
+return false;
+};
+PlotKit.Layout.prototype.evaluate=function(){
+this._evaluateLimits();
+this._evaluateScales();
+if(this.style=="bar"){
+if(this.options.barOrientation=="horizontal"){
+this._evaluateHorizBarCharts();
+}else{
+this._evaluateBarCharts();
+}
+this._evaluateBarTicks();
+}else{
+if(this.style=="line"){
+this._evaluateLineCharts();
+this._evaluateLineTicks();
+}else{
+if(this.style=="pie"){
+this._evaluatePieCharts();
+this._evaluatePieTicks();
+}
+}
+}
+};
+PlotKit.Layout.prototype.hitTest=function(x,y){
+var f=MochiKit.Format.twoDigitFloat;
+if((this.style=="bar")&&this.bars&&(this.bars.length>0)){
+for(var i=0;i<this.bars.length;i++){
+var bar=this.bars[i];
+if((x>=bar.x)&&(x<=bar.x+bar.w)&&(y>=bar.y)&&(y-bar.y<=bar.h)){
+return bar;
+}
+}
+}else{
+if(this.style=="line"){
+if(this.hitTestCache.x2maxy==null){
+this._regenerateHitTestCache();
+}
+var _62=x/this.xscale;
+var _63=this.hitTestCache.xvalues;
+var _64=null;
+var _65=null;
+for(var i=1;i<_63.length;i++){
+if(_63[i]>_62){
+_64=_63[i-1];
+_65=_63[i];
+break;
+}
+}
+if((_64!=null)){
+var _66=this.hitTestCache.x2maxy[_64];
+var _67=this.hitTestCache.x2maxy[_65];
+var _68=(1-y)/this.yscale;
+var _69=(_67-_66)/(_65-_64);
+var _70=_66+_69*(_62-_64);
+if(_70>=_68){
+var obj={xval:_62,yval:_68,xafter:_65,yafter:_67,xbefore:_64,ybefore:_66,yprojected:_70};
+return obj;
+}
+}
+}else{
+if(this.style=="pie"){
+var _71=Math.sqrt((y-0.5)*(y-0.5)+(x-0.5)*(x-0.5));
+if(_71>this.options.pieRadius){
+return null;
+}
+var _72=Math.atan2(y-0.5,x-0.5)-Math.PI/2;
+for(var i=0;i<this.slices.length;i++){
+var _73=this.slices[i];
+if(_73.startAngle<_72&&_73.endAngle>=_72){
+return _73;
+}
+}
+}
+}
+}
+return null;
+};
+PlotKit.Layout.prototype.rectForX=function(x){
+return null;
+};
+PlotKit.Layout.prototype.angleRangeForX=function(x){
+return null;
+};
+PlotKit.Layout.prototype._evaluateLimits=function(){
+var map=PlotKit.Base.map;
+var _75=PlotKit.Base.items;
+var _76=MochiKit.Base.itemgetter;
+var _77=PlotKit.Base.collapse;
+var _78=MochiKit.Base.listMin;
+var _79=MochiKit.Base.listMax;
+var _80=MochiKit.Base.isUndefinedOrNull;
+var all=_77(map(_76(1),_75(this.datasets)));
+if(_80(this.options.xAxis)){
+if(this.options.xOriginIsZero){
+this.minxval=0;
+}else{
+this.minxval=_78(map(parseFloat,map(_76(0),all)));
+}
+this.maxxval=_79(map(parseFloat,map(_76(0),all)));
+}else{
+this.minxval=this.options.xAxis[0];
+this.maxxval=this.options.xAxis[1];
+this.xscale=this.maxval-this.minxval;
+}
+if(_80(this.options.yAxis)){
+if(this.options.yOriginIsZero){
+this.minyval=0;
+}else{
+this.minyval=_78(map(parseFloat,map(_76(1),all)));
+}
+this.maxyval=_79(map(parseFloat,map(_76(1),all)));
+}else{
+this.minyval=this.options.yAxis[0];
+this.maxyval=this.options.yAxis[1];
+this.yscale=this.maxyval-this.minyval;
+}
+};
+PlotKit.Layout.prototype._evaluateScales=function(){
+var _82=MochiKit.Base.isUndefinedOrNull;
+this.xrange=this.maxxval-this.minxval;
+if(this.xrange==0){
+this.xscale=1;
+}else{
+this.xscale=1/this.xrange;
+}
+this.yrange=this.maxyval-this.minyval;
+if(this.yrange==0){
+this.yscale=1;
+}else{
+this.yscale=1/this.yrange;
+}
+};
+PlotKit.Layout.prototype._uniqueXValues=function(){
+var _83=PlotKit.Base.collapse;
+var map=PlotKit.Base.map;
+var _84=PlotKit.Base.uniq;
+var _85=MochiKit.Base.itemgetter;
+var _86=PlotKit.Base.items;
+var _87=map(parseFloat,map(_85(0),_83(map(_85(1),_86(this.datasets)))));
+_87.sort(MochiKit.Base.compare);
+return _84(_87);
+};
+PlotKit.Layout.prototype._evaluateBarCharts=function(){
+var _88=PlotKit.Base.items;
+var _89=_88(this.datasets).length;
+var _90=10000000;
+var _91=this._uniqueXValues();
+for(var i=1;i<_91.length;i++){
+_90=Math.min(Math.abs(_91[i]-_91[i-1]),_90);
+}
+var _92=0;
+var _93=0;
+var _94=0;
+if(_91.length==1){
+_90=1;
+this.xscale=1;
+this.minxval=_91[0];
+_92=1*this.options.barWidthFillFraction;
+_93=_92/_89;
+_94=(1-this.options.barWidthFillFraction)/2;
+}else{
+if(this.xrange==1){
+this.xscale=0.5;
+}else{
+if(this.xrange==2){
+this.xscale=1/3;
+}else{
+this.xscale=(1-_90/this.xrange)/this.xrange;
+}
+}
+_92=_90*this.xscale*this.options.barWidthFillFraction;
+_93=_92/_89;
+_94=_90*this.xscale*(1-this.options.barWidthFillFraction)/2;
+}
+this.minxdelta=_90;
+this.bars=new Array();
+var i=0;
+for(var _95 in this.datasets){
+var _96=this.datasets[_95];
+if(PlotKit.Base.isFuncLike(_96)){
+continue;
+}
+for(var j=0;j<_96.length;j++){
+var _98=_96[j];
+var _99={x:((parseFloat(_98[0])-this.minxval)*this.xscale)+(i*_93)+_94,y:1-((parseFloat(_98[1])-this.minyval)*this.yscale),w:_93,h:((parseFloat(_98[1])-this.minyval)*this.yscale),xval:parseFloat(_98[0]),yval:parseFloat(_98[1]),name:_95};
+if((_99.x>=0)&&(_99.x<=1)&&(_99.y>=0)&&(_99.y<=1)){
+this.bars.push(_99);
+}
+}
+i++;
+}
+};
+PlotKit.Layout.prototype._evaluateHorizBarCharts=function(){
+var _100=PlotKit.Base.items;
+var _101=_100(this.datasets).length;
+var _102=10000000;
+var _103=this._uniqueXValues();
+for(var i=1;i<_103.length;i++){
+_102=Math.min(Math.abs(_103[i]-_103[i-1]),_102);
+}
+var _104=0;
+var _105=0;
+var _106=0;
+if(_103.length==1){
+_102=1;
+this.xscale=1;
+this.minxval=_103[0];
+_104=1*this.options.barWidthFillFraction;
+_105=_104/_101;
+_106=(1-this.options.barWidthFillFraction)/2;
+}else{
+this.xscale=(1-_102/this.xrange)/this.xrange;
+_104=_102*this.xscale*this.options.barWidthFillFraction;
+_105=_104/_101;
+_106=_102*this.xscale*(1-this.options.barWidthFillFraction)/2;
+}
+this.minxdelta=_102;
+this.bars=new Array();
+var i=0;
+for(var _107 in this.datasets){
+var _108=this.datasets[_107];
+if(PlotKit.Base.isFuncLike(_108)){
+continue;
+}
+for(var j=0;j<_108.length;j++){
+var item=_108[j];
+var rect={y:((parseFloat(item[0])-this.minxval)*this.xscale)+(i*_105)+_106,x:0,h:_105,w:((parseFloat(item[1])-this.minyval)*this.yscale),xval:parseFloat(item[0]),yval:parseFloat(item[1]),name:_107};
+if(rect.y<=0){
+rect.y=0;
+}
+if(rect.y>=1){
+rect.y=1;
+}
+if((rect.x>=0)&&(rect.x<=1)){
+this.bars.push(rect);
+}
+}
+i++;
+}
+};
+PlotKit.Layout.prototype._evaluateLineCharts=function(){
+var _111=PlotKit.Base.items;
+var _112=_111(this.datasets).length;
+this.points=new Array();
+var i=0;
+for(var _113 in this.datasets){
+var _114=this.datasets[_113];
+if(PlotKit.Base.isFuncLike(_114)){
+continue;
+}
+_114.sort(function(a,b){
+return compare(parseFloat(a[0]),parseFloat(b[0]));
+});
+for(var j=0;j<_114.length;j++){
+var item=_114[j];
+var _117={x:((parseFloat(item[0])-this.minxval)*this.xscale),y:1-((parseFloat(item[1])-this.minyval)*this.yscale),xval:parseFloat(item[0]),yval:parseFloat(item[1]),name:_113};
+if(_117.y<=0){
+_117.y=0;
+}
+if(_117.y>=1){
+_117.y=1;
+}
+if((_117.x>=0)&&(_117.x<=1)){
+this.points.push(_117);
+}
+}
+i++;
+}
+};
+PlotKit.Layout.prototype._evaluatePieCharts=function(){
+var _118=PlotKit.Base.items;
+var sum=MochiKit.Iter.sum;
+var _120=MochiKit.Base.itemgetter;
+var _121=_118(this.datasets).length;
+var _122=_118(this.datasets)[0][1];
+var _123=sum(map(_120(1),_122));
+this.slices=new Array();
+var _124=0;
+for(var i=0;i<_122.length;i++){
+var _125=_122[i][1]/_123;
+var _126=_124*Math.PI*2;
+var _127=(_124+_125)*Math.PI*2;
+var _128={fraction:_125,xval:_122[i][0],yval:_122[i][1],startAngle:_126,endAngle:_127};
+if(_122[i][1]!=0){
+this.slices.push(_128);
+}
+_124+=_125;
+}
+};
+PlotKit.Layout.prototype._evaluateLineTicksForXAxis=function(){
+var _129=MochiKit.Base.isUndefinedOrNull;
+if(this.options.xTicks){
+this.xticks=new Array();
+var _130=function(tick){
+var _132=tick.label;
+if(_129(_132)){
+_132=tick.v.toString();
+}
+var pos=this.xscale*(tick.v-this.minxval);
+if((pos>=0)&&(pos<=1)){
+this.xticks.push([pos,_132]);
+}
+};
+MochiKit.Iter.forEach(this.options.xTicks,bind(_130,this));
+}else{
+if(this.options.xNumberOfTicks){
+var _134=this._uniqueXValues();
+var _135=this.xrange/this.options.xNumberOfTicks;
+var _136=0;
+this.xticks=new Array();
+for(var i=0;i<=_134.length;i++){
+if((_134[i]-this.minxval)>=(_136*_135)){
+var pos=this.xscale*(_134[i]-this.minxval);
+if((pos>1)||(pos<0)){
+continue;
+}
+this.xticks.push([pos,_134[i]]);
+_136++;
+}
+if(_136>this.options.xNumberOfTicks){
+break;
+}
+}
+}
+}
+};
+PlotKit.Layout.prototype._evaluateLineTicksForYAxis=function(){
+var _137=MochiKit.Base.isUndefinedOrNull;
+if(this.options.yTicks){
+this.yticks=new Array();
+var _138=function(tick){
+var _139=tick.label;
+if(_137(_139)){
+_139=tick.v.toString();
+}
+var pos=1-(this.yscale*(tick.v-this.minyval));
+if((pos>=0)&&(pos<=1)){
+this.yticks.push([pos,_139]);
+}
+};
+MochiKit.Iter.forEach(this.options.yTicks,bind(_138,this));
+}else{
+if(this.options.yNumberOfTicks){
+this.yticks=new Array();
+var _140=PlotKit.Base.roundInterval;
+var prec=this.options.yTickPrecision;
+var _142=_140(this.yrange,this.options.yNumberOfTicks,prec);
+for(var i=0;i<=this.options.yNumberOfTicks;i++){
+var yval=this.minyval+(i*_142);
+var pos=1-((yval-this.minyval)*this.yscale);
+if((pos>1)||(pos<0)){
+continue;
+}
+this.yticks.push([pos,MochiKit.Format.roundToFixed(yval,prec)]);
+}
+}
+}
+};
+PlotKit.Layout.prototype._evaluateLineTicks=function(){
+this._evaluateLineTicksForXAxis();
+this._evaluateLineTicksForYAxis();
+};
+PlotKit.Layout.prototype._evaluateBarTicks=function(){
+this._evaluateLineTicks();
+var _144=function(tick){
+return [tick[0]+(this.minxdelta*this.xscale)/2,tick[1]];
+};
+this.xticks=MochiKit.Base.map(bind(_144,this),this.xticks);
+if(this.options.barOrientation=="horizontal"){
+var _145=this.xticks;
+this.xticks=this.yticks;
+this.yticks=_145;
+var _146=function(tick){
+return [1-tick[0],tick[1]];
+};
+this.xticks=MochiKit.Base.map(_146,this.xticks);
+}
+};
+PlotKit.Layout.prototype._evaluatePieTicks=function(){
+var _147=MochiKit.Base.isUndefinedOrNull;
+var _148=MochiKit.Format.numberFormatter("#%");
+this.xticks=new Array();
+if(this.options.xTicks){
+var _149=new Array();
+for(var i=0;i<this.slices.length;i++){
+_149[this.slices[i].xval]=this.slices[i];
+}
+for(var i=0;i<this.options.xTicks.length;i++){
+var tick=this.options.xTicks[i];
+var _150=_149[tick.v];
+var _151=tick.label;
+if(_150){
+if(_147(_151)){
+_151=tick.v.toString();
+}
+_151+=" ("+_148(_150.fraction)+")";
+this.xticks.push([tick.v,_151]);
+}
+}
+}else{
+for(var i=0;i<this.slices.length;i++){
+var _150=this.slices[i];
+var _151=_150.xval+" ("+_148(_150.fraction)+")";
+this.xticks.push([_150.xval,_151]);
+}
+}
+};
+PlotKit.Layout.prototype._regenerateHitTestCache=function(){
+this.hitTestCache.xvalues=this._uniqueXValues();
+this.hitTestCache.xlookup=new Array();
+this.hitTestCache.x2maxy=new Array();
+var _152=MochiKit.Base.listMax;
+var _153=MochiKit.Base.itemgetter;
+var map=MochiKit.Base.map;
+var _154=keys(this.datasets);
+for(var i=0;i<_154.length;i++){
+var _155=this.datasets[_154[i]];
+for(var j=0;j<_155.length;j++){
+var xval=_155[j][0];
+var yval=_155[j][1];
+if(this.hitTestCache.xlookup[xval]){
+this.hitTestCache.xlookup[xval].push([yval,_154[i]]);
+}else{
+this.hitTestCache.xlookup[xval]=[[yval,_154[i]]];
+}
+}
+}
+for(var x in this.hitTestCache.xlookup){
+var _157=this.hitTestCache.xlookup[x];
+this.hitTestCache.x2maxy[x]=_152(map(_153(0),_157));
+}
+};
+PlotKit.LayoutModule={};
+PlotKit.LayoutModule.Layout=PlotKit.Layout;
+PlotKit.LayoutModule.EXPORT=["Layout"];
+PlotKit.LayoutModule.EXPORT_OK=[];
+PlotKit.LayoutModule.__new__=function(){
+var m=MochiKit.Base;
+m.nameFunctions(this);
+this.EXPORT_TAGS={":common":this.EXPORT,":all":m.concat(this.EXPORT,this.EXPORT_OK)};
+};
+PlotKit.LayoutModule.__new__();
+MochiKit.Base._exportSymbols(this,PlotKit.LayoutModule);
+try{
+if((typeof (PlotKit.Base)=="undefined")||(typeof (PlotKit.Layout)=="undefined")){
+throw "";
+}
+}
+catch(e){
+throw "PlotKit.Layout depends on MochiKit.{Base,Color,DOM,Format} and PlotKit.{Base,Layout}";
+}
+if(typeof (PlotKit.CanvasRenderer)=="undefined"){
+PlotKit.CanvasRenderer={};
+}
+PlotKit.CanvasRenderer.NAME="PlotKit.CanvasRenderer";
+PlotKit.CanvasRenderer.VERSION=PlotKit.VERSION;
+PlotKit.CanvasRenderer.__repr__=function(){
+return "["+this.NAME+" "+this.VERSION+"]";
+};
+PlotKit.CanvasRenderer.toString=function(){
+return this.__repr__();
+};
+PlotKit.CanvasRenderer=function(_158,_159,_160){
+if(arguments.length>0){
+this.__init__(_158,_159,_160);
+}
+};
+PlotKit.CanvasRenderer.prototype.__init__=function(_161,_162,_163){
+var _164=MochiKit.Base.isUndefinedOrNull;
+var _165=MochiKit.Color.Color;
+this.options={"drawBackground":true,"backgroundColor":_165.whiteColor(),"padding":{left:30,right:30,top:5,bottom:10},"colorScheme":PlotKit.Base.palette(PlotKit.Base.baseColors()[0]),"strokeColor":_165.whiteColor(),"strokeColorTransform":"asStrokeColor","strokeWidth":0.5,"shouldFill":true,"shouldStroke":true,"drawXAxis":true,"drawYAxis":true,"axisLineColor":_165.blackColor(),"axisLineWidth":0.5,"axisTickSize":3,"axisLabelColor":_165.blackColor(),"axisLabelFont":"Arial","axisLabelFontSize":9,"axisLabelWidth":50,"pieRadius":0.4,"enableEvents":true};
+MochiKit.Base.update(this.options,_163?_163:{});
+this.layout=_162;
+this.element=MochiKit.DOM.getElement(_161);
+this.container=this.element.parentNode;
+this.isIE=PlotKit.Base.excanvasSupported();
+if(this.isIE&&!_164(G_vmlCanvasManager)){
+this.IEDelay=0.5;
+this.maxTries=5;
+this.renderDelay=null;
+this.clearDelay=null;
+this.element=G_vmlCanvasManager.initElement(this.element);
+}
+this.height=this.element.height;
+this.width=this.element.width;
+if(_164(this.element)){
+throw "CanvasRenderer() - passed canvas is not found";
+}
+if(!this.isIE&&!(PlotKit.CanvasRenderer.isSupported(this.element))){
+throw "CanvasRenderer() - Canvas is not supported.";
+}
+if(_164(this.container)||(this.container.nodeName.toLowerCase()!="div")){
+throw "CanvasRenderer() - <canvas> needs to be enclosed in <div>";
+}
+this.xlabels=new Array();
+this.ylabels=new Array();
+this.isFirstRender=true;
+this.area={x:this.options.padding.left,y:this.options.padding.top,w:this.width-this.options.padding.left-this.options.padding.right,h:this.height-this.options.padding.top-this.options.padding.bottom};
+MochiKit.DOM.updateNodeAttributes(this.container,{"style":{"position":"relative","width":this.width+"px"}});
+};
+PlotKit.CanvasRenderer.prototype.render=function(){
+if(this.isIE){
+try{
+if(this.renderDelay){
+this.renderDelay.cancel();
+this.renderDelay=null;
+}
+var _166=this.element.getContext("2d");
+}
+catch(e){
+this.isFirstRender=false;
+if(this.maxTries-->0){
+this.renderDelay=MochiKit.Async.wait(this.IEDelay);
+this.renderDelay.addCallback(bind(this.render,this));
+}
+return;
+}
+}
+if(this.options.drawBackground){
+this._renderBackground();
+}
+if(this.layout.style=="bar"){
+this._renderBarChart();
+this._renderBarAxis();
+}else{
+if(this.layout.style=="pie"){
+this._renderPieChart();
+this._renderPieAxis();
+}else{
+if(this.layout.style=="line"){
+this._renderLineChart();
+this._renderLineAxis();
+}
+}
+}
+};
+PlotKit.CanvasRenderer.prototype._renderBarChartWrap=function(data,_168){
+var _169=this.element.getContext("2d");
+var _170=this.options.colorScheme.length;
+var _171=this.options.colorScheme;
+var _172=MochiKit.Base.keys(this.layout.datasets);
+var _173=_172.length;
+for(var i=0;i<_173;i++){
+var _174=_172[i];
+var _175=_171[i%_170];
+_169.save();
+_169.fillStyle=_175.toRGBString();
+if(this.options.strokeColor){
+_169.strokeStyle=this.options.strokeColor.toRGBString();
+}else{
+if(this.options.strokeColorTransform){
+_169.strokeStyle=_175[this.options.strokeColorTransform]().toRGBString();
+}
+}
+_169.lineWidth=this.options.strokeWidth;
+var _176=function(obj){
+if(obj.name==_174){
+_168(_169,obj);
+}
+};
+MochiKit.Iter.forEach(data,bind(_176,this));
+_169.restore();
+}
+};
+PlotKit.CanvasRenderer.prototype._renderBarChart=function(){
+var bind=MochiKit.Base.bind;
+var _178=function(_179,bar){
+var x=this.area.w*bar.x+this.area.x;
+var y=this.area.h*bar.y+this.area.y;
+var w=this.area.w*bar.w;
+var h=this.area.h*bar.h;
+if((w<1)||(h<1)){
+return;
+}
+if(this.options.shouldFill){
+_179.fillRect(x,y,w,h);
+}
+if(this.options.shouldStroke){
+_179.strokeRect(x,y,w,h);
+}
+};
+this._renderBarChartWrap(this.layout.bars,bind(_178,this));
+};
+PlotKit.CanvasRenderer.prototype._renderLineChart=function(){
+var _182=this.element.getContext("2d");
+var _183=this.options.colorScheme.length;
+var _184=this.options.colorScheme;
+var _185=MochiKit.Base.keys(this.layout.datasets);
+var _186=_185.length;
+var bind=MochiKit.Base.bind;
+var _187=MochiKit.Base.partial;
+for(var i=0;i<_186;i++){
+var _188=_185[i];
+var _189=_184[i%_183];
+var _190=this.options.strokeColorTransform;
+_182.save();
+_182.fillStyle=_189.toRGBString();
+if(this.options.strokeColor){
+_182.strokeStyle=this.options.strokeColor.toRGBString();
+}else{
+if(this.options.strokeColorTransform){
+_182.strokeStyle=_189[_190]().toRGBString();
+}
+}
+_182.lineWidth=this.options.strokeWidth;
+var _191=function(ctx){
+ctx.beginPath();
+ctx.moveTo(this.area.x,this.area.y+this.area.h);
+var _193=function(ctx_,_195){
+if(_195.name==_188){
+ctx_.lineTo(this.area.w*_195.x+this.area.x,this.area.h*_195.y+this.area.y);
+}
+};
+MochiKit.Iter.forEach(this.layout.points,_187(_193,ctx),this);
+ctx.lineTo(this.area.w+this.area.x,this.area.h+this.area.y);
+ctx.lineTo(this.area.x,this.area.y+this.area.h);
+ctx.closePath();
+};
+if(this.options.shouldFill){
+bind(_191,this)(_182);
+_182.fill();
+}
+if(this.options.shouldStroke){
+bind(_191,this)(_182);
+_182.stroke();
+}
+_182.restore();
+}
+};
+PlotKit.CanvasRenderer.prototype._renderPieChart=function(){
+var _196=this.element.getContext("2d");
+var _197=this.options.colorScheme.length;
+var _198=this.layout.slices;
+var _199=this.area.x+this.area.w*0.5;
+var _200=this.area.y+this.area.h*0.5;
+var _201=Math.min(this.area.w*this.options.pieRadius,this.area.h*this.options.pieRadius);
+if(this.isIE){
+_199=parseInt(_199);
+_200=parseInt(_200);
+_201=parseInt(_201);
+}
+for(var i=0;i<_198.length;i++){
+var _202=this.options.colorScheme[i%_197];
+_196.save();
+_196.fillStyle=_202.toRGBString();
+var _203=function(){
+_196.beginPath();
+_196.moveTo(_199,_200);
+_196.arc(_199,_200,_201,_198[i].startAngle-Math.PI/2,_198[i].endAngle-Math.PI/2,false);
+_196.lineTo(_199,_200);
+_196.closePath();
+};
+if(Math.abs(_198[i].startAngle-_198[i].endAngle)>0.001){
+if(this.options.shouldFill){
+_203();
+_196.fill();
+}
+if(this.options.shouldStroke){
+_203();
+_196.lineWidth=this.options.strokeWidth;
+if(this.options.strokeColor){
+_196.strokeStyle=this.options.strokeColor.toRGBString();
+}else{
+if(this.options.strokeColorTransform){
+_196.strokeStyle=_202[this.options.strokeColorTransform]().toRGBString();
+}
+}
+_196.stroke();
+}
+}
+_196.restore();
+}
+};
+PlotKit.CanvasRenderer.prototype._renderBarAxis=function(){
+this._renderAxis();
+};
+PlotKit.CanvasRenderer.prototype._renderLineAxis=function(){
+this._renderAxis();
+};
+PlotKit.CanvasRenderer.prototype._renderAxis=function(){
+if(!this.options.drawXAxis&&!this.options.drawYAxis){
+return;
+}
+var _204=this.element.getContext("2d");
+var _205={"style":{"position":"absolute","fontSize":this.options.axisLabelFontSize+"px","zIndex":10,"color":this.options.axisLabelColor.toRGBString(),"width":this.options.axisLabelWidth+"px","overflow":"hidden"}};
+_204.save();
+_204.strokeStyle=this.options.axisLineColor.toRGBString();
+_204.lineWidth=this.options.axisLineWidth;
+if(this.options.drawYAxis){
+if(this.layout.yticks){
+var _206=function(tick){
+if(typeof (tick)=="function"){
+return;
+}
+var x=this.area.x;
+var y=this.area.y+tick[0]*this.area.h;
+_204.beginPath();
+_204.moveTo(x,y);
+_204.lineTo(x-this.options.axisTickSize,y);
+_204.closePath();
+_204.stroke();
+var _207=DIV(_205,tick[1]);
+_207.style.top=(y-this.options.axisLabelFontSize)+"px";
+_207.style.left=(x-this.options.padding.left-this.options.axisTickSize)+"px";
+_207.style.textAlign="right";
+_207.style.width=(this.options.padding.left-this.options.axisTickSize*2)+"px";
+MochiKit.DOM.appendChildNodes(this.container,_207);
+this.ylabels.push(_207);
+};
+MochiKit.Iter.forEach(this.layout.yticks,bind(_206,this));
+}
+_204.beginPath();
+_204.moveTo(this.area.x,this.area.y);
+_204.lineTo(this.area.x,this.area.y+this.area.h);
+_204.closePath();
+_204.stroke();
+}
+if(this.options.drawXAxis){
+if(this.layout.xticks){
+var _206=function(tick){
+if(typeof (dataset)=="function"){
+return;
+}
+var x=this.area.x+tick[0]*this.area.w;
+var y=this.area.y+this.area.h;
+_204.beginPath();
+_204.moveTo(x,y);
+_204.lineTo(x,y+this.options.axisTickSize);
+_204.closePath();
+_204.stroke();
+var _208=DIV(_205,tick[1]);
+_208.style.top=(y+this.options.axisTickSize)+"px";
+_208.style.left=(x-this.options.axisLabelWidth/2)+"px";
+_208.style.textAlign="center";
+_208.style.width=this.options.axisLabelWidth+"px";
+MochiKit.DOM.appendChildNodes(this.container,_208);
+this.xlabels.push(_208);
+};
+MochiKit.Iter.forEach(this.layout.xticks,bind(_206,this));
+}
+_204.beginPath();
+_204.moveTo(this.area.x,this.area.y+this.area.h);
+_204.lineTo(this.area.x+this.area.w,this.area.y+this.area.h);
+_204.closePath();
+_204.stroke();
+}
+_204.restore();
+};
+PlotKit.CanvasRenderer.prototype._renderPieAxis=function(){
+if(!this.options.drawXAxis){
+return;
+}
+if(this.layout.xticks){
+var _209=new Array();
+for(var i=0;i<this.layout.slices.length;i++){
+_209[this.layout.slices[i].xval]=this.layout.slices[i];
+}
+var _210=this.area.x+this.area.w*0.5;
+var _211=this.area.y+this.area.h*0.5;
+var _212=Math.min(this.area.w*this.options.pieRadius,this.area.h*this.options.pieRadius);
+var _213=this.options.axisLabelWidth;
+for(var i=0;i<this.layout.xticks.length;i++){
+var _214=_209[this.layout.xticks[i][0]];
+if(MochiKit.Base.isUndefinedOrNull(_214)){
+continue;
+}
+var _215=(_214.startAngle+_214.endAngle)/2;
+var _216=_215;
+if(_216>Math.PI*2){
+_216=_216-Math.PI*2;
+}else{
+if(_216<0){
+_216=_216+Math.PI*2;
+}
+}
+var _217=_210+Math.sin(_216)*(_212+10);
+var _218=_211-Math.cos(_216)*(_212+10);
+var _219={"position":"absolute","zIndex":11,"width":_213+"px","fontSize":this.options.axisLabelFontSize+"px","overflow":"hidden","color":this.options.axisLabelColor.toHexString()};
+if(_216<=Math.PI*0.5){
+_219["textAlign"]="left";
+_219["verticalAlign"]="top";
+_219["left"]=_217+"px";
+_219["top"]=(_218-this.options.axisLabelFontSize)+"px";
+}else{
+if((_216>Math.PI*0.5)&&(_216<=Math.PI)){
+_219["textAlign"]="left";
+_219["verticalAlign"]="bottom";
+_219["left"]=_217+"px";
+_219["top"]=_218+"px";
+}else{
+if((_216>Math.PI)&&(_216<=Math.PI*1.5)){
+_219["textAlign"]="right";
+_219["verticalAlign"]="bottom";
+_219["left"]=(_217-_213)+"px";
+_219["top"]=_218+"px";
+}else{
+_219["textAlign"]="right";
+_219["verticalAlign"]="bottom";
+_219["left"]=(_217-_213)+"px";
+_219["top"]=(_218-this.options.axisLabelFontSize)+"px";
+}
+}
+}
+var _220=DIV({"style":_219},this.layout.xticks[i][1]);
+this.xlabels.push(_220);
+MochiKit.DOM.appendChildNodes(this.container,_220);
+}
+}
+};
+PlotKit.CanvasRenderer.prototype._renderBackground=function(){
+var _221=this.element.getContext("2d");
+_221.save();
+_221.fillStyle=this.options.backgroundColor.toRGBString();
+_221.fillRect(0,0,this.width,this.height);
+_221.restore();
+};
+PlotKit.CanvasRenderer.prototype.clear=function(){
+if(this.isIE){
+try{
+if(this.clearDelay){
+this.clearDelay.cancel();
+this.clearDelay=null;
+}
+var _222=this.element.getContext("2d");
+}
+catch(e){
+this.isFirstRender=false;
+this.clearDelay=MochiKit.Async.wait(this.IEDelay);
+this.clearDelay.addCallback(bind(this.clear,this));
+return;
+}
+}
+var _222=this.element.getContext("2d");
+_222.clearRect(0,0,this.width,this.height);
+MochiKit.Iter.forEach(this.xlabels,MochiKit.DOM.removeElement);
+MochiKit.Iter.forEach(this.ylabels,MochiKit.DOM.removeElement);
+this.xlabels=new Array();
+this.ylabels=new Array();
+};
+PlotKit.CanvasRenderer.prototype._initialiseEvents=function(){
+var _223=MochiKit.Signal.connect;
+var bind=MochiKit.Base.bind;
+_223(this.element,"onclick",bind(this.onclick,this));
+};
+PlotKit.CanvasRenderer.prototype._resolveObject=function(e){
+var x=(e.mouse().page.x-PlotKit.Base.findPosX(this.element)-this.area.x)/this.area.w;
+var y=(e.mouse().page.y-PlotKit.Base.findPosY(this.element)-this.area.y)/this.area.h;
+var _225=this.layout.hitTest(x,y);
+if(_225){
+return _225;
+}
+return null;
+};
+PlotKit.CanvasRenderer.prototype._createEventObject=function(_226,e){
+if(_226==null){
+return null;
+}
+e.chart=_226;
+return e;
+};
+PlotKit.CanvasRenderer.prototype.onclick=function(e){
+var _227=this._resolveObject(e);
+var _228=this._createEventObject(_227,e);
+if(_228!=null){
+MochiKit.Signal.signal(this,"onclick",_228);
+}
+};
+PlotKit.CanvasRenderer.prototype.onmouseover=function(e){
+var _229=this._resolveObject(e);
+var _230=this._createEventObject(_229,e);
+if(_230!=null){
+signal(this,"onmouseover",_230);
+}
+};
+PlotKit.CanvasRenderer.prototype.onmouseout=function(e){
+var _231=this._resolveObject(e);
+var _232=this._createEventObject(_231,e);
+if(_232==null){
+signal(this,"onmouseout",e);
+}else{
+signal(this,"onmouseout",_232);
+}
+};
+PlotKit.CanvasRenderer.prototype.onmousemove=function(e){
+var _233=this._resolveObject(e);
+var _234=this._createEventObject(_233,e);
+if((_233==null)&&(this.event_isinside==null)){
+return;
+}
+if((_233!=null)&&(this.event_isinside==null)){
+signal(this,"onmouseover",_234);
+}
+if((_233==null)&&(this.event_isinside!=null)){
+signal(this,"onmouseout",_234);
+}
+if((_233!=null)&&(this.event_isinside!=null)){
+signal(this,"onmousemove",_234);
+}
+this.event_isinside=_233;
+};
+PlotKit.CanvasRenderer.isSupported=function(_235){
+var _236=null;
+try{
+if(MochiKit.Base.isUndefinedOrNull(_235)){
+_236=MochiKit.DOM.CANVAS({});
+}else{
+_236=MochiKit.DOM.getElement(_235);
+}
+var _237=_236.getContext("2d");
+}
+catch(e){
+var ie=navigator.appVersion.match(/MSIE (\d\.\d)/);
+var _239=(navigator.userAgent.toLowerCase().indexOf("opera")!=-1);
+if((!ie)||(ie[1]<6)||(_239)){
+return false;
+}
+return true;
+}
+return true;
+};
+PlotKit.Canvas={};
+PlotKit.Canvas.CanvasRenderer=PlotKit.CanvasRenderer;
+PlotKit.Canvas.EXPORT=["CanvasRenderer"];
+PlotKit.Canvas.EXPORT_OK=["CanvasRenderer"];
+PlotKit.Canvas.__new__=function(){
+var m=MochiKit.Base;
+m.nameFunctions(this);
+this.EXPORT_TAGS={":common":this.EXPORT,":all":m.concat(this.EXPORT,this.EXPORT_OK)};
+};
+PlotKit.Canvas.__new__();
+MochiKit.Base._exportSymbols(this,PlotKit.Canvas);
+try{
+if(typeof (PlotKit.Layout)=="undefined"){
+throw "";
+}
+}
+catch(e){
+throw "PlotKit depends on MochiKit.{Base,Color,DOM,Format} and PlotKit.Layout";
+}
+PlotKit.SVGRenderer=function(_240,_241,_242){
+if(arguments.length>0){
+this.__init__(_240,_241,_242);
+}
+};
+PlotKit.SVGRenderer.NAME="PlotKit.SVGRenderer";
+PlotKit.SVGRenderer.VERSION=PlotKit.VERSION;
+PlotKit.SVGRenderer.__repr__=function(){
+return "["+this.NAME+" "+this.VERSION+"]";
+};
+PlotKit.SVGRenderer.toString=function(){
+return this.__repr__();
+};
+PlotKit.SVGRenderer.SVGNS="http://www.w3.org/2000/svg";
+PlotKit.SVGRenderer.prototype.__init__=function(_243,_244,_245){
+var _246=MochiKit.Base.isUndefinedOrNull;
+this.options={"drawBackground":true,"backgroundColor":Color.whiteColor(),"padding":{left:30,right:30,top:5,bottom:10},"colorScheme":PlotKit.Base.palette(PlotKit.Base.baseColors()[1]),"strokeColor":Color.whiteColor(),"strokeColorTransform":"asStrokeColor","strokeWidth":0.5,"shouldFill":true,"shouldStroke":true,"drawXAxis":true,"drawYAxis":true,"axisLineColor":Color.blackColor(),"axisLineWidth":0.5,"axisTickSize":3,"axisLabelColor":Color.blackColor(),"axisLabelFont":"Arial","axisLabelFontSize":9,"axisLabelWidth":50,"axisLabelUseDiv":true,"pieRadius":0.4,"enableEvents":true};
+MochiKit.Base.update(this.options,_245?_245:{});
+this.layout=_244;
+this.element=MochiKit.DOM.getElement(_243);
+this.container=this.element.parentNode;
+this.height=parseInt(this.element.getAttribute("height"));
+this.width=parseInt(this.element.getAttribute("width"));
+this.document=document;
+this.root=this.element;
+try{
+this.document=this.element.getSVGDocument();
+this.root=_246(this.document.documentElement)?this.element:this.document.documentElement;
+}
+catch(e){
+}
+this.element.style.zIndex=1;
+if(_246(this.element)){
+throw "SVGRenderer() - passed SVG object is not found";
+}
+if(_246(this.container)||this.container.nodeName.toLowerCase()!="div"){
+throw "SVGRenderer() - No DIV's around the SVG.";
+}
+this.xlabels=new Array();
+this.ylabels=new Array();
+this.defs=this.createSVGElement("defs");
+this.area={x:this.options.padding.left,y:this.options.padding.top,w:this.width-this.options.padding.left-this.options.padding.right,h:this.height-this.options.padding.top-this.options.padding.bottom};
+MochiKit.DOM.updateNodeAttributes(this.container,{"style":{"position":"relative","width":this.width+"px"}});
+};
+PlotKit.SVGRenderer.prototype.render=function(){
+if(this.options.drawBackground){
+this._renderBackground();
+}
+if(this.layout.style=="bar"){
+this._renderBarChart();
+this._renderBarAxis();
+}else{
+if(this.layout.style=="pie"){
+this._renderPieChart();
+this._renderPieAxis();
+}else{
+if(this.layout.style=="line"){
+this._renderLineChart();
+this._renderLineAxis();
+}
+}
+}
+};
+PlotKit.SVGRenderer.prototype._renderBarOrLine=function(data,_247,_248,_249){
+var _250=this.options.colorScheme.length;
+var _251=this.options.colorScheme;
+var _252=MochiKit.Base.keys(this.layout.datasets);
+var _253=_252.length;
+for(var i=0;i<_253;i++){
+var _254=_252[i];
+var _255=new Array();
+var _256=_251[i%_250];
+if(this.options.shouldFill){
+_255["fill"]=_256.toRGBString();
+}else{
+_255["fill"]="none";
+}
+if(this.options.shouldStroke&&(this.options.strokeColor||this.options.strokeColorTransform)){
+if(this.options.strokeColor){
+_255["stroke"]=this.options.strokeColor.toRGBString();
+}else{
+if(this.options.strokeColorTransform){
+_255["stroke"]=_256[this.options.strokeColorTransform]().toRGBString();
+}
+}
+_255["strokeWidth"]=this.options.strokeWidth;
+}
+if(_248){
+_248(_255);
+}
+var _257=function(obj){
+if(obj.name==_254){
+_247(_255,obj);
+}
+};
+MochiKit.Iter.forEach(data,bind(_257,this));
+if(_249){
+_249(_255);
+}
+}
+};
+PlotKit.SVGRenderer.prototype._renderBarChart=function(){
+var bind=MochiKit.Base.bind;
+var _258=function(_259,bar){
+var x=this.area.w*bar.x+this.area.x;
+var y=this.area.h*bar.y+this.area.y;
+var w=this.area.w*bar.w;
+var h=this.area.h*bar.h;
+this._drawRect(x,y,w,h,_259);
+};
+this._renderBarOrLine(this.layout.bars,bind(_258,this));
+};
+PlotKit.SVGRenderer.prototype._renderLineChart=function(){
+var bind=MochiKit.Base.bind;
+var _260=function(_261,_262){
+this._tempPointsBuffer+=(this.area.w*_262.x+this.area.x)+","+(this.area.h*_262.y+this.area.y)+" ";
+};
+var _263=function(_264){
+this._tempPointsBuffer="";
+this._tempPointsBuffer+=(this.area.x)+","+(this.area.y+this.area.h)+" ";
+};
+var _265=function(_266){
+this._tempPointsBuffer+=(this.area.w+this.area.x)+","+(this.area.h+this.area.y);
+_266["points"]=this._tempPointsBuffer;
+var elem=this.createSVGElement("polygon",_266);
+this.root.appendChild(elem);
+};
+this._renderBarOrLine(this.layout.points,bind(_260,this),bind(_263,this),bind(_265,this));
+};
+PlotKit.SVGRenderer.prototype._renderPieChart=function(){
+var _268=this.options.colorScheme.length;
+var _269=this.layout.slices;
+var _270=this.area.x+this.area.w*0.5;
+var _271=this.area.y+this.area.h*0.5;
+var _272=Math.min(this.area.w*this.options.pieRadius,this.area.h*this.options.pieRadius);
+if(_269.length==1&&(Math.abs(_269[0].startAngle)-Math.abs(_269[0].endAngle)<0.1)){
+var _273={"cx":_270,"cy":_271,"r":_272};
+var _274=this.options.colorScheme[0];
+if(this.options.shouldFill){
+_273["fill"]=_274.toRGBString();
+}else{
+_273["fill"]="none";
+}
+if(this.options.shouldStroke&&(this.options.strokeColor||this.options.strokeColorTransform)){
+if(this.options.strokeColor){
+_273["stroke"]=this.options.strokeColor.toRGBString();
+}else{
+if(this.options.strokeColorTransform){
+_273["stroke"]=_274[this.options.strokeColorTransform]().toRGBString();
+}
+}
+_273["style"]="stroke-width: "+this.options.strokeWidth;
+}
+this.root.appendChild(this.createSVGElement("circle",_273));
+return;
+}
+for(var i=0;i<_269.length;i++){
+var _273=new Array();
+var _274=this.options.colorScheme[i%_268];
+if(this.options.shouldFill){
+_273["fill"]=_274.toRGBString();
+}else{
+_273["fill"]="none";
+}
+if(this.options.shouldStroke&&(this.options.strokeColor||this.options.strokeColorTransform)){
+if(this.options.strokeColor){
+_273["stroke"]=this.options.strokeColor.toRGBString();
+}else{
+if(this.options.strokeColorTransform){
+_273["stroke"]=_274[this.options.strokeColorTransform]().toRGBString();
+}
+}
+_273["style"]="stroke-width:"+this.options.strokeWidth;
+}
+var _275=0;
+if(Math.abs(_269[i].endAngle-_269[i].startAngle)>Math.PI){
+_275=1;
+}
+var x1=Math.cos(_269[i].startAngle-Math.PI/2)*_272;
+var y1=Math.sin(_269[i].startAngle-Math.PI/2)*_272;
+var x2=Math.cos(_269[i].endAngle-Math.PI/2)*_272;
+var y2=Math.sin(_269[i].endAngle-Math.PI/2)*_272;
+var rx=x2-x1;
+var ry=y2-y1;
+var _282="M"+_270+","+_271+" ";
+_282+="l"+x1+","+y1+" ";
+_282+="a"+_272+","+_272+" 0 "+_275+",1 "+rx+","+ry+" z";
+_273["d"]=_282;
+var elem=this.createSVGElement("path",_273);
+this.root.appendChild(elem);
+}
+};
+PlotKit.SVGRenderer.prototype._renderBarAxis=function(){
+this._renderAxis();
+};
+PlotKit.SVGRenderer.prototype._renderLineAxis=function(){
+this._renderAxis();
+};
+PlotKit.SVGRenderer.prototype._renderAxis=function(){
+if(!this.options.drawXAxis&&!this.options.drawYAxis){
+return;
+}
+var _283={"style":{"position":"absolute","textAlign":"center","fontSize":this.options.axisLabelFontSize+"px","zIndex":10,"color":this.options.axisLabelColor.toRGBString(),"width":this.options.axisLabelWidth+"px","overflow":"hidden"}};
+var _284={"stroke":this.options.axisLineColor.toRGBString(),"strokeWidth":this.options.axisLineWidth};
+if(this.options.drawYAxis){
+if(this.layout.yticks){
+var _285=function(tick){
+var x=this.area.x;
+var y=this.area.y+tick[0]*this.area.h;
+this._drawLine(x,y,x-3,y,_284);
+if(this.options.axisLabelUseDiv){
+var _286=DIV(_283,tick[1]);
+_286.style.top=(y-this.options.axisLabelFontSize)+"px";
+_286.style.left=(x-this.options.padding.left+this.options.axisTickSize)+"px";
+_286.style.textAlign="left";
+_286.style.width=(this.options.padding.left-3)+"px";
+MochiKit.DOM.appendChildNodes(this.container,_286);
+this.ylabels.push(_286);
+}else{
+var _287={y:y+3,x:(x-this.options.padding.left+3),width:(this.options.padding.left-this.options.axisTickSize)+"px",height:(this.options.axisLabelFontSize+3)+"px",fontFamily:"Arial",fontSize:this.options.axisLabelFontSize+"px",fill:this.options.axisLabelColor.toRGBString()};
+var _286=this.createSVGElement("text",_287);
+_286.appendChild(this.document.createTextNode(tick[1]));
+this.root.appendChild(_286);
+}
+};
+MochiKit.Iter.forEach(this.layout.yticks,bind(_285,this));
+}
+this._drawLine(this.area.x,this.area.y,this.area.x,this.area.y+this.area.h,_284);
+}
+if(this.options.drawXAxis){
+if(this.layout.xticks){
+var _285=function(tick){
+var x=this.area.x+tick[0]*this.area.w;
+var y=this.area.y+this.area.h;
+this._drawLine(x,y,x,y+this.options.axisTickSize,_284);
+if(this.options.axisLabelUseDiv){
+var _288=DIV(_283,tick[1]);
+_288.style.top=(y+this.options.axisTickSize)+"px";
+_288.style.left=(x-this.options.axisLabelWidth/2)+"px";
+_288.style.textAlign="center";
+_288.style.width=this.options.axisLabelWidth+"px";
+MochiKit.DOM.appendChildNodes(this.container,_288);
+this.xlabels.push(_288);
+}else{
+var _289={y:(y+this.options.axisTickSize+this.options.axisLabelFontSize),x:x-3,width:this.options.axisLabelWidth+"px",height:(this.options.axisLabelFontSize+3)+"px",fontFamily:"Arial",fontSize:this.options.axisLabelFontSize+"px",fill:this.options.axisLabelColor.toRGBString(),textAnchor:"middle"};
+var _288=this.createSVGElement("text",_289);
+_288.appendChild(this.document.createTextNode(tick[1]));
+this.root.appendChild(_288);
+}
+};
+MochiKit.Iter.forEach(this.layout.xticks,bind(_285,this));
+}
+this._drawLine(this.area.x,this.area.y+this.area.h,this.area.x+this.area.w,this.area.y+this.area.h,_284);
+}
+};
+PlotKit.SVGRenderer.prototype._renderPieAxis=function(){
+if(this.layout.xticks){
+var _290=new Array();
+for(var i=0;i<this.layout.slices.length;i++){
+_290[this.layout.slices[i].xval]=this.layout.slices[i];
+}
+var _291=this.area.x+this.area.w*0.5;
+var _292=this.area.y+this.area.h*0.5;
+var _293=Math.min(this.area.w*this.options.pieRadius+10,this.area.h*this.options.pieRadius+10);
+var _294=this.options.axisLabelWidth;
+for(var i=0;i<this.layout.xticks.length;i++){
+var _295=_290[this.layout.xticks[i][0]];
+if(MochiKit.Base.isUndefinedOrNull(_295)){
+continue;
+}
+var _296=(_295.startAngle+_295.endAngle)/2;
+var _297=_296;
+if(_297>Math.PI*2){
+_297=_297-Math.PI*2;
+}else{
+if(_297<0){
+_297=_297+Math.PI*2;
+}
+}
+var _298=_291+Math.sin(_297)*(_293+10);
+var _299=_292-Math.cos(_297)*(_293+10);
+var _300={"position":"absolute","zIndex":11,"width":_294+"px","fontSize":this.options.axisLabelFontSize+"px","overflow":"hidden","color":this.options.axisLabelColor.toHexString()};
+var _301={"width":_294+"px","fontSize":this.options.axisLabelFontSize+"px","height":(this.options.axisLabelFontSize+3)+"px","fill":this.options.axisLabelColor.toRGBString()};
+if(_297<=Math.PI*0.5){
+MochiKit.Base.update(_300,{"textAlign":"left","verticalAlign":"top","left":_298+"px","top":(_299-this.options.axisLabelFontSize)+"px"});
+MochiKit.Base.update(_301,{"x":_298,"y":(_299-this.options.axisLabelFontSize),"textAnchor":"left"});
+}else{
+if((_297>Math.PI*0.5)&&(_297<=Math.PI)){
+MochiKit.Base.update(_300,{"textAlign":"left","verticalAlign":"bottom","left":_298+"px","top":_299+"px"});
+MochiKit.Base.update(_301,{"textAnchor":"left","x":_298,"y":_299});
+}else{
+if((_297>Math.PI)&&(_297<=Math.PI*1.5)){
+MochiKit.Base.update(_300,{"textAlign":"right","verticalAlign":"bottom","left":_298+"px","top":_299+"px"});
+MochiKit.Base.update(_301,{"textAnchor":"right","x":_298-_294,"y":_299});
+}else{
+MochiKit.Base.update(_300,{"textAlign":"left","verticalAlign":"bottom","left":_298+"px","top":_299+"px"});
+MochiKit.Base.update(_301,{"textAnchor":"left","x":_298-_294,"y":_299-this.options.axisLabelFontSize});
+}
+}
+}
+if(this.options.axisLabelUseDiv){
+var _302=DIV({"style":_300},this.layout.xticks[i][1]);
+this.xlabels.push(_302);
+MochiKit.DOM.appendChildNodes(this.container,_302);
+}else{
+var _302=this.createSVGElement("text",_301);
+_302.appendChild(this.document.createTextNode(this.layout.xticks[i][1]));
+this.root.appendChild(_302);
+}
+}
+}
+};
+PlotKit.SVGRenderer.prototype._renderBackground=function(){
+var opts={"stroke":"none","fill":this.options.backgroundColor.toRGBString()};
+this._drawRect(0,0,this.width,this.height,opts);
+};
+PlotKit.SVGRenderer.prototype._drawRect=function(x,y,w,h,_304){
+var _305={x:x+"px",y:y+"px",width:w+"px",height:h+"px"};
+if(_304){
+MochiKit.Base.update(_305,_304);
+}
+var elem=this.createSVGElement("rect",_305);
+this.root.appendChild(elem);
+};
+PlotKit.SVGRenderer.prototype._drawLine=function(x1,y1,x2,y2,_306){
+var _307={x1:x1+"px",y1:y1+"px",x2:x2+"px",y2:y2+"px"};
+if(_306){
+MochiKit.Base.update(_307,_306);
+}
+var elem=this.createSVGElement("line",_307);
+this.root.appendChild(elem);
+};
+PlotKit.SVGRenderer.prototype.clear=function(){
+while(this.element.firstChild){
+this.element.removeChild(this.element.firstChild);
+}
+if(this.options.axisLabelUseDiv){
+for(var i=0;i<this.xlabels.length;i++){
+MochiKit.DOM.removeElement(this.xlabels[i]);
+}
+for(var i=0;i<this.ylabels.length;i++){
+MochiKit.DOM.removeElement(this.ylabels[i]);
+}
+}
+this.xlabels=new Array();
+this.ylabels=new Array();
+};
+PlotKit.SVGRenderer.prototype.createSVGElement=function(name,_309){
+var _310=MochiKit.Base.isUndefinedOrNull;
+var elem;
+var doc=_310(this.document)?document:this.document;
+try{
+elem=doc.createElementNS(PlotKit.SVGRenderer.SVGNS,name);
+}
+catch(e){
+elem=doc.createElement(name);
+elem.setAttribute("xmlns",PlotKit.SVGRenderer.SVGNS);
+}
+if(_309){
+MochiKit.DOM.updateNodeAttributes(elem,_309);
+}
+return elem;
+};
+PlotKit.SVGRenderer.SVG=function(_312){
+var ie=navigator.appVersion.match(/MSIE (\d\.\d)/);
+var _313=(navigator.userAgent.toLowerCase().indexOf("opera")!=-1);
+if(ie&&(ie[1]>=6)&&(!_313)){
+var _314=_312["width"]?_312["width"]:"100";
+var _315=_312["height"]?_312["height"]:"100";
+var eid=_312["id"]?_312["id"]:"notunique";
+var html="<svg:svg width=\""+_314+"\" height=\""+_315+"\" ";
+html+="id=\""+eid+"\" version=\"1.1\" baseProfile=\"full\" />";
+var _318=document.createElement(html);
+var _319=_318.getSVGDocument().createElementNS(PlotKit.SVGRenderer.SVGNS,"svg");
+_319.setAttribute("width",_314);
+_319.setAttribute("height",_315);
+_318.getSVGDocument().appendChild(_319);
+return _318;
+}else{
+return PlotKit.SVGRenderer.prototype.createSVGElement("svg",_312);
+}
+};
+PlotKit.SVGRenderer.isSupported=function(){
+var _320=(navigator.userAgent.toLowerCase().indexOf("opera")!=-1);
+var _321=navigator.appVersion.match(/MSIE (\d\.\d)/);
+var _322=navigator.userAgent.match(/AppleWebKit\/(\d+)/);
+var _323=navigator.userAgent.match(/Opera\/(\d*\.\d*)/);
+var _324=navigator.userAgent.match(/rv:(\d*\.\d*).*Gecko/);
+var _325="http://www.w3.org/TR/SVG11/feature#SVG";
+if(_321&&(_321[1]>=6)&&!_320){
+return document.implementation.hasFeature(_325,"1.1");
+}
+if(_323&&(_323[1]>8.9)){
+return true;
+}
+if(_324&&(_324>1.7)){
+return true;
+}
+return false;
+};
+PlotKit.SVG={};
+PlotKit.SVG.SVGRenderer=PlotKit.SVGRenderer;
+PlotKit.SVG.EXPORT=["SVGRenderer"];
+PlotKit.SVG.EXPORT_OK=["SVGRenderer"];
+PlotKit.SVG.__new__=function(){
+var m=MochiKit.Base;
+m.nameFunctions(this);
+this.EXPORT_TAGS={":common":this.EXPORT,":all":m.concat(this.EXPORT,this.EXPORT_OK)};
+};
+PlotKit.SVG.__new__();
+MochiKit.Base._exportSymbols(this,PlotKit.SVG);
+try{
+if(typeof (PlotKit.CanvasRenderer)=="undefined"){
+throw "";
+}
+}
+catch(e){
+throw "SweetCanvas depends on MochiKit.{Base,Color,DOM,Format} and PlotKit.{Layout, Canvas}";
+}
+if(typeof (PlotKit.SweetCanvasRenderer)=="undefined"){
+PlotKit.SweetCanvasRenderer={};
+}
+PlotKit.SweetCanvasRenderer=function(_326,_327,_328){
+if(arguments.length>0){
+this.__init__(_326,_327,_328);
+}
+};
+PlotKit.SweetCanvasRenderer.NAME="PlotKit.SweetCanvasRenderer";
+PlotKit.SweetCanvasRenderer.VERSION=PlotKit.VERSION;
+PlotKit.SweetCanvasRenderer.__repr__=function(){
+return "["+this.NAME+" "+this.VERSION+"]";
+};
+PlotKit.SweetCanvasRenderer.toString=function(){
+return this.__repr__();
+};
+PlotKit.SweetCanvasRenderer.prototype=new PlotKit.CanvasRenderer();
+PlotKit.SweetCanvasRenderer.prototype.constructor=PlotKit.SweetCanvasRenderer;
+PlotKit.SweetCanvasRenderer.__super__=PlotKit.CanvasRenderer.prototype;
+PlotKit.SweetCanvasRenderer.prototype.__init__=function(el,_330,opts){
+var _331=PlotKit.Base.officeBlue();
+MochiKit.Base.update(_331,opts);
+PlotKit.SweetCanvasRenderer.__super__.__init__.call(this,el,_330,_331);
+};
+PlotKit.SweetCanvasRenderer.prototype._renderBarChart=function(){
+var bind=MochiKit.Base.bind;
+var _332=Color.blackColor().colorWithAlpha(0.1).toRGBString();
+var _333=function(_334,x,y,w,h){
+_334.fillStyle=_332;
+_334.fillRect(x-2,y-2,w+4,h+2);
+_334.fillStyle=_332;
+_334.fillRect(x-1,y-1,w+2,h+1);
+};
+var _335=this.options.colorScheme.length;
+var _336=this.options.colorScheme;
+var _337=PlotKit.Base.keys(this.layout.datasets);
+var _338=_337.length;
+var _339=function(name){
+for(var i=0;i<_338;i++){
+if(name==_337[i]){
+return _336[i%_335];
+}
+}
+return _336[0];
+};
+var _340=function(_341,bar){
+var x=this.area.w*bar.x+this.area.x;
+var y=this.area.h*bar.y+this.area.y;
+var w=this.area.w*bar.w;
+var h=this.area.h*bar.h;
+if((w<1)||(h<1)){
+return;
+}
+_341.save();
+_341.shadowBlur=5;
+_341.shadowColor=Color.fromHexString("#888888").toRGBString();
+if(this.isIE){
+_341.save();
+_341.fillStyle="#cccccc";
+_341.fillRect(x-2,y-2,w+4,h+2);
+_341.restore();
+}else{
+_333(_341,x,y,w,h);
+}
+if(this.options.shouldFill){
+_341.fillStyle=_339(bar.name).toRGBString();
+_341.fillRect(x,y,w,h);
+}
+_341.shadowBlur=0;
+_341.strokeStyle=Color.whiteColor().toRGBString();
+_341.lineWidth=2;
+if(this.options.shouldStroke){
+_341.strokeRect(x,y,w,h);
+}
+_341.restore();
+};
+this._renderBarChartWrap(this.layout.bars,bind(_340,this));
+};
+PlotKit.SweetCanvasRenderer.prototype._renderLineChart=function(){
+var _342=this.element.getContext("2d");
+var _343=this.options.colorScheme.length;
+var _344=this.options.colorScheme;
+var _345=PlotKit.Base.keys(this.layout.datasets);
+var _346=_345.length;
+var bind=MochiKit.Base.bind;
+for(var i=0;i<_346;i++){
+var _347=_345[i];
+var _348=_344[i%_343];
+var _349=this.options.strokeColorTransform;
+_342.save();
+var _350=function(ctx){
+ctx.beginPath();
+ctx.moveTo(this.area.x,this.area.y+this.area.h);
+var _351=function(ctx_,_352){
+if(_352.name==_347){
+ctx_.lineTo(this.area.w*_352.x+this.area.x,this.area.h*_352.y+this.area.y);
+}
+};
+MochiKit.Iter.forEach(this.layout.points,partial(_351,ctx),this);
+ctx.lineTo(this.area.w+this.area.x,this.area.h+this.area.y);
+ctx.lineTo(this.area.x,this.area.y+this.area.h);
+ctx.closePath();
+};
+if(this.options.shouldFill){
+_342.save();
+if(this.isIE){
+_342.fillStyle="#cccccc";
+}else{
+_342.fillStyle=Color.blackColor().colorWithAlpha(0.2).toRGBString();
+}
+_342.translate(-1,-2);
+bind(_350,this)(_342);
+if(this.options.shouldFill){
+_342.fill();
+}
+_342.restore();
+}
+_342.shadowBlur=5;
+_342.shadowColor=Color.fromHexString("#888888").toRGBString();
+_342.fillStyle=_348.toRGBString();
+_342.lineWidth=2;
+_342.strokeStyle=Color.whiteColor().toRGBString();
+if(this.options.shouldFill){
+bind(_350,this)(_342);
+_342.fill();
+}
+if(this.options.shouldStroke){
+bind(_350,this)(_342);
+_342.stroke();
+}
+_342.restore();
+}
+};
+PlotKit.SweetCanvasRenderer.prototype._renderPieChart=function(){
+var _353=this.element.getContext("2d");
+var _354=this.options.colorScheme.length;
+var _355=this.layout.slices;
+var _356=this.area.x+this.area.w*0.5;
+var _357=this.area.y+this.area.h*0.5;
+var _358=Math.min(this.area.w*this.options.pieRadius,this.area.h*this.options.pieRadius);
+if(this.isIE){
+_356=parseInt(_356);
+_357=parseInt(_357);
+_358=parseInt(_358);
+}
+if(!this.isIE){
+_353.save();
+var _359=Color.blackColor().colorWithAlpha(0.2);
+_353.fillStyle=_359.toRGBString();
+_353.shadowBlur=5;
+_353.shadowColor=Color.fromHexString("#888888").toRGBString();
+_353.translate(1,1);
+_353.beginPath();
+_353.moveTo(_356,_357);
+_353.arc(_356,_357,_358+2,0,Math.PI*2,false);
+_353.closePath();
+_353.fill();
+_353.restore();
+}
+_353.save();
+_353.strokeStyle=Color.whiteColor().toRGBString();
+_353.lineWidth=2;
+for(var i=0;i<_355.length;i++){
+var _360=this.options.colorScheme[i%_354];
+_353.fillStyle=_360.toRGBString();
+var _361=function(){
+_353.beginPath();
+_353.moveTo(_356,_357);
+_353.arc(_356,_357,_358,_355[i].startAngle-Math.PI/2,_355[i].endAngle-Math.PI/2,false);
+_353.lineTo(_356,_357);
+_353.closePath();
+};
+if(Math.abs(_355[i].startAngle-_355[i].endAngle)>0.0001){
+if(this.options.shouldFill){
+_361();
+_353.fill();
+}
+if(this.options.shouldStroke){
+_361();
+_353.stroke();
+}
+}
+}
+_353.restore();
+};
+PlotKit.SweetCanvasRenderer.prototype._renderBackground=function(){
+var _362=this.element.getContext("2d");
+if(this.layout.style=="bar"||this.layout.style=="line"){
+_362.save();
+_362.fillStyle=this.options.backgroundColor.toRGBString();
+_362.fillRect(this.area.x,this.area.y,this.area.w,this.area.h);
+_362.strokeStyle=this.options.axisLineColor.toRGBString();
+_362.lineWidth=1;
+var _363=this.layout.yticks;
+var _364=false;
+if(this.layout.style=="bar"&&this.layout.options.barOrientation=="horizontal"){
+_363=this.layout.xticks;
+_364=true;
+}
+for(var i=0;i<_363.length;i++){
+var x1=0;
+var y1=0;
+var x2=0;
+var y2=0;
+if(_364){
+x1=_363[i][0]*this.area.w+this.area.x;
+y1=this.area.y;
+x2=x1;
+y2=y1+this.area.h;
+}else{
+x1=this.area.x;
+y1=_363[i][0]*this.area.h+this.area.y;
+x2=x1+this.area.w;
+y2=y1;
+}
+_362.beginPath();
+_362.moveTo(x1,y1);
+_362.lineTo(x2,y2);
+_362.closePath();
+_362.stroke();
+}
+_362.restore();
+}else{
+PlotKit.SweetCanvasRenderer.__super__._renderBackground.call(this);
+}
+};
+PlotKit.SweetCanvas={};
+PlotKit.SweetCanvas.SweetCanvasRenderer=PlotKit.SweetCanvasRenderer;
+PlotKit.SweetCanvas.EXPORT=["SweetCanvasRenderer"];
+PlotKit.SweetCanvas.EXPORT_OK=["SweetCanvasRenderer"];
+PlotKit.SweetCanvas.__new__=function(){
+var m=MochiKit.Base;
+m.nameFunctions(this);
+this.EXPORT_TAGS={":common":this.EXPORT,":all":m.concat(this.EXPORT,this.EXPORT_OK)};
+};
+PlotKit.SweetCanvas.__new__();
+MochiKit.Base._exportSymbols(this,PlotKit.SweetCanvas);
+try{
+if(typeof (PlotKit.SVGRenderer)=="undefined"){
+throw "";
+}
+}
+catch(e){
+throw "SweetSVG depends on MochiKit.{Base,Color,DOM,Format} and PlotKit.{Layout, SVG}";
+}
+if(typeof (PlotKit.SweetSVGRenderer)=="undefined"){
+PlotKit.SweetSVGRenderer={};
+}
+PlotKit.SweetSVGRenderer=function(_365,_366,_367){
+if(arguments.length>0){
+this.__init__(_365,_366,_367);
+}
+};
+PlotKit.SweetSVGRenderer.NAME="PlotKit.SweetSVGRenderer";
+PlotKit.SweetSVGRenderer.VERSION=PlotKit.VERSION;
+PlotKit.SweetSVGRenderer.__repr__=function(){
+return "["+this.NAME+" "+this.VERSION+"]";
+};
+PlotKit.SweetSVGRenderer.toString=function(){
+return this.__repr__();
+};
+PlotKit.SweetSVGRenderer.prototype=new PlotKit.SVGRenderer();
+PlotKit.SweetSVGRenderer.prototype.constructor=PlotKit.SweetSVGRenderer;
+PlotKit.SweetSVGRenderer.__super__=PlotKit.SVGRenderer.prototype;
+PlotKit.SweetSVGRenderer.prototype.__init__=function(_368,_369,_370){
+var _371=PlotKit.Base.officeBlue();
+MochiKit.Base.update(_371,_370);
+PlotKit.SweetSVGRenderer.__super__.__init__.call(this,_368,_369,_371);
+};
+PlotKit.SweetSVGRenderer.prototype._addDropShadowFilter=function(){
+var _372=this.createSVGElement("filter",{x:0,y:0,"id":"dropShadow"});
+var _373=this.createSVGElement("feOffset",{"in":"SourceGraphic","dx":0,"dy":0,"result":"topCopy"});
+var blur=this.createSVGElement("feGaussianBlur",{"in":"SourceAlpha","StdDeviation":2,"result":"shadow"});
+var _375=this.createSVGElement("feOffset",{"in":"shadow","dx":-1,"dy":-2,"result":"movedShadow"});
+var _376=this.createSVGElement("feMerge");
+var _377=this.createSVGElement("feMergeNode",{"in":"topCopy"});
+var _378=this.createSVGElement("feMergeNode",{"in":"movedShadow"});
+_376.appendChild(_377);
+_376.appendChild(_378);
+_372.appendChild(_373);
+_372.appendChild(blur);
+_372.appendChild(_375);
+_372.appendChild(_376);
+this.defs.appendChild(_372);
+};
+PlotKit.SweetSVGRenderer.prototype._renderBarChart=function(){
+var bind=MochiKit.Base.bind;
+var _379=Color.blackColor().toRGBString();
+var _380="fill:"+_379+";fill-opacity:0.15";
+var _381="stroke-width: 2.0; stroke:"+Color.whiteColor().toRGBString();
+var _382=function(_383,bar){
+var x=this.area.w*bar.x+this.area.x;
+var y=this.area.h*bar.y+this.area.y;
+var w=this.area.w*bar.w;
+var h=this.area.h*bar.h;
+if((w<1)||(h<1)){
+return;
+}
+_383["style"]=_381;
+this._drawRect(x-2,y-1,w+4,h+2,{"style":_380});
+this._drawRect(x,y,w,h,_383);
+};
+this._renderBarOrLine(this.layout.bars,bind(_382,this));
+};
+PlotKit.SweetSVGRenderer.prototype._renderLineChart=function(){
+var bind=MochiKit.Base.bind;
+var _384=Color.blackColor().toRGBString();
+var _385="fill:"+_384+";fill-opacity:0.15";
+var _386="stroke-width: 2.0; stroke:"+Color.whiteColor().toRGBString();
+var _387=function(_388,_389){
+this._tempPointsBuffer+=(this.area.w*_389.x+this.area.x)+","+(this.area.h*_389.y+this.area.y)+" ";
+};
+var _390=function(_391){
+this._tempPointsBuffer="";
+this._tempPointsBuffer+=(this.area.x)+","+(this.area.y+this.area.h)+" ";
+};
+var _392=function(_393){
+this._tempPointsBuffer+=(this.area.w+this.area.x)+","+(this.area.h+this.area.y);
+_393["points"]=this._tempPointsBuffer;
+_393["stroke"]="none";
+_393["transform"]="translate(-2, -1)";
+_393["style"]=_385;
+var _394=this.createSVGElement("polygon",_393);
+this.root.appendChild(_394);
+_393["transform"]="";
+_393["style"]=_386;
+var elem=this.createSVGElement("polygon",_393);
+this.root.appendChild(elem);
+};
+this._renderBarOrLine(this.layout.points,bind(_387,this),bind(_390,this),bind(_392,this));
+};
+PlotKit.SweetSVGRenderer.prototype._renderPieChart=function(){
+var _395=this.area.x+this.area.w*0.5;
+var _396=this.area.y+this.area.h*0.5;
+var _397=Color.blackColor().toRGBString();
+var _398=Math.min(this.area.w*this.options.pieRadius,this.area.h*this.options.pieRadius);
+var _399="fill:"+_397+";fill-opacity:0.15";
+var _400=this.createSVGElement("circle",{"style":_399,"cx":_395+1,"cy":_396+1,"r":_398+1});
+this.root.appendChild(_400);
+PlotKit.SweetSVGRenderer.__super__._renderPieChart.call(this);
+};
+PlotKit.SweetSVGRenderer.prototype._renderBackground=function(){
+var _401={"fill":this.options.backgroundColor.toRGBString(),"stroke":"none"};
+if(this.layout.style=="bar"||this.layout.style=="line"){
+this._drawRect(this.area.x,this.area.y,this.area.w,this.area.h,_401);
+var _402=this.layout.yticks;
+var _403=false;
+if(this.layout.style=="bar"&&this.layout.options.barOrientation=="horizontal"){
+_402=this.layout.xticks;
+_403=true;
+}
+for(var i=0;i<_402.length;i++){
+var x=0;
+var y=0;
+var w=0;
+var h=0;
+if(_403){
+x=_402[i][0]*this.area.w+this.area.x;
+y=this.area.y;
+w=1;
+h=this.area.w;
+}else{
+x=this.area.x;
+y=_402[i][0]*this.area.h+this.area.y;
+w=this.area.w;
+h=1;
+}
+this._drawRect(x,y,w,h,{"fill":this.options.axisLineColor.toRGBString()});
+}
+}else{
+PlotKit.SweetSVGRenderer.__super__._renderBackground.call(this);
+}
+};
+PlotKit.SweetSVG={};
+PlotKit.SweetSVG.SweetSVGRenderer=PlotKit.SweetSVGRenderer;
+PlotKit.SweetSVG.EXPORT=["SweetSVGRenderer"];
+PlotKit.SweetSVG.EXPORT_OK=["SweetSVGRenderer"];
+PlotKit.SweetSVG.__new__=function(){
+var m=MochiKit.Base;
+m.nameFunctions(this);
+this.EXPORT_TAGS={":common":this.EXPORT,":all":m.concat(this.EXPORT,this.EXPORT_OK)};
+};
+PlotKit.SweetSVG.__new__();
+MochiKit.Base._exportSymbols(this,PlotKit.SweetSVG);
+try{
+if(typeof (PlotKit.CanvasRenderer)=="undefined"){
+throw "";
+}
+}
+catch(e){
+throw "PlotKit.EasyPlot depends on all of PlotKit's components";
+}
+if(typeof (PlotKit.EasyPlot)=="undefined"){
+PlotKit.EasyPlot={};
+}
+PlotKit.EasyPlot.NAME="PlotKit.EasyPlot";
+PlotKit.EasyPlot.VERSION=PlotKit.VERSION;
+PlotKit.EasyPlot.__repr__=function(){
+return "["+this.NAME+" "+this.VERSION+"]";
+};
+PlotKit.EasyPlot.toString=function(){
+return this.__repr__();
+};
+PlotKit.EasyPlot=function(_404,_405,_406,_407){
+this.layout=new Layout(_404,_405);
+this.divElem=_406;
+this.width=parseInt(_406.getAttribute("width"));
+this.height=parseInt(_406.getAttribute("height"));
+this.deferredCount=0;
+if(this.width<1){
+this.width=this.divElem.width?this.divElem.width:300;
+}
+if(this.height<1){
+this.height=this.divElem.height?this.divElem.height:300;
+}
+if(isArrayLike(_407)){
+for(var i=0;i<_407.length;i++){
+if(typeof (_407[i])=="string"){
+this.deferredCount++;
+var d=MochiKit.Async.doSimpleXMLHttpRequest(_407[i]);
+d.addCallback(MochiKit.Base.bind(PlotKit.EasyPlot.onDataLoaded,this));
+}else{
+if(isArrayLike(_407[i])){
+this.layout.addDataset("data-"+i,_407[i]);
+}
+}
+}
+}else{
+if(!isUndefinedOrNull(_407)){
+throw "Passed datasources are not Array like";
+}
+}
+if(CanvasRenderer.isSupported()){
+this.element=CANVAS({"id":this.divElem.getAttribute("id")+"-canvas","width":this.width,"height":this.height},"");
+this.divElem.appendChild(this.element);
+this.renderer=new SweetCanvasRenderer(this.element,this.layout,_405);
+}else{
+if(SVGRenderer.isSupported()){
+this.element=SVGRenderer.SVG({"id":this.divElem.getAttribute("id")+"-svg","width":this.width,"height":this.height,"version":"1.1","baseProfile":"full"},"");
+this.divElem.appendChild(this.element);
+this.renderer=new SweetSVGRenderer(this.element,this.layout,_405);
+}
+}
+if((this.deferredCount==0)&&(PlotKit.Base.keys(this.layout.datasets).length>0)){
+this.layout.evaluate();
+this.renderer.clear();
+this.renderer.render();
+}
+};
+PlotKit.EasyPlot.onDataLoaded=function(_409){
+var _410=new Array();
+var _411=_409.responseText.split("\n");
+for(var i=0;i<_411.length;i++){
+var _412=MochiKit.Format.strip(_411[i]);
+if((_412.length>1)&&(_412.charAt(0)!="#")){
+_410.push(_412.split(","));
+}
+}
+this.layout.addDataset("data-ajax-"+this.deferredCount,_410);
+this.deferredCount--;
+if((this.deferredCount==0)&&(PlotKit.Base.keys(this.layout.datasets).length>0)){
+this.layout.evaluate();
+this.renderer.clear();
+this.renderer.render();
+}
+};
+PlotKit.EasyPlot.prototype.reload=function(){
+this.layout.evaluate();
+this.renderer.clear();
+this.renderer.render();
+};
+PlotKit.EasyPlotModule={};
+PlotKit.EasyPlotModule.EasyPlot=PlotKit.EasyPlot;
+PlotKit.EasyPlotModule.EXPORT=["EasyPlot"];
+PlotKit.EasyPlotModule.EXPORT_OK=[];
+PlotKit.EasyPlotModule.__new__=function(){
+var m=MochiKit.Base;
+m.nameFunctions(this);
+this.EXPORT_TAGS={":common":this.EXPORT,":all":m.concat(this.EXPORT,this.EXPORT_OK)};
+};
+PlotKit.EasyPlotModule.__new__();
+MochiKit.Base._exportSymbols(this,PlotKit.EasyPlotModule);
+
+
diff --git a/site/app/webroot/js/plotkit/SVG.js b/site/app/webroot/js/plotkit/SVG.js
new file mode 100644
index 0000000..3687bc0
--- /dev/null
+++ b/site/app/webroot/js/plotkit/SVG.js
@@ -0,0 +1,705 @@
+/*
+ PlotKit SVG
+ ===========
+ SVG Renderer for PlotKit
+
+ Copyright
+ ---------
+ Copyright 2005,2006 (c) Alastair Tse <alastair^liquidx.net>
+ For use under the BSD license. <http://www.liquidx.net/plotkit>
+*/
+
+// -------------------------------------------------------------------------
+// NOTES: - If you use XHTML1.1 strict, then you must include each MochiKit
+// file individuall.
+// - For IE support, you must include the AdobeSVG object hack.
+// See tests/svg.html for details.
+// -------------------------------------------------------------------------
+// -------------------------------------------------------------------------
+// Check required components
+// -------------------------------------------------------------------------
+
+try {
+ if (typeof(PlotKit.Layout) == 'undefined')
+ {
+ throw "";
+ }
+}
+catch (e) {
+ throw "PlotKit depends on MochiKit.{Base,Color,DOM,Format} and PlotKit.Layout"
+}
+
+
+// ---------------------------------------------------------------------------
+// SVG Renderer
+// ---------------------------------------------------------------------------
+
+PlotKit.SVGRenderer = function(element, layout, options) {
+ if (arguments.length > 0)
+ this.__init__(element, layout, options);
+};
+
+PlotKit.SVGRenderer.NAME = "PlotKit.SVGRenderer";
+PlotKit.SVGRenderer.VERSION = PlotKit.VERSION;
+
+PlotKit.SVGRenderer.__repr__ = function() {
+ return "[" + this.NAME + " " + this.VERSION + "]";
+};
+
+PlotKit.SVGRenderer.toString = function() {
+ return this.__repr__();
+}
+
+PlotKit.SVGRenderer.SVGNS = 'http://www.w3.org/2000/svg';
+
+PlotKit.SVGRenderer.prototype.__init__ = function(element, layout, options) {
+ var isNil = MochiKit.Base.isUndefinedOrNull;
+
+ // default options
+ this.options = {
+ "drawBackground": true,
+ "backgroundColor": Color.whiteColor(),
+ "padding": {left: 30, right: 30, top: 5, bottom: 10},
+ "colorScheme": PlotKit.Base.palette(PlotKit.Base.baseColors()[1]),
+ "strokeColor": Color.whiteColor(),
+ "strokeColorTransform": "asStrokeColor",
+ "strokeWidth": 0.5,
+ "shouldFill": true,
+ "shouldStroke": true,
+ "drawXAxis": true,
+ "drawYAxis": true,
+ "axisLineColor": Color.blackColor(),
+ "axisLineWidth": 0.5,
+ "axisTickSize": 3,
+ "axisLabelColor": Color.blackColor(),
+ "axisLabelFont": "Arial",
+ "axisLabelFontSize": 9,
+ "axisLabelWidth": 50,
+ "axisLabelUseDiv": true,
+ "pieRadius": 0.4,
+ "enableEvents": true
+ };
+
+ MochiKit.Base.update(this.options, options ? options : {});
+ this.layout = layout;
+ this.element = MochiKit.DOM.getElement(element);
+ this.container = this.element.parentNode;
+ this.height = parseInt(this.element.getAttribute("height"));
+ this.width = parseInt(this.element.getAttribute("width"));
+ this.document = document;
+ this.root = this.element;
+
+ // Adobe SVG Support:
+ // - if an exception is thrown, then no Adobe SVG Plugin support.
+ try {
+ this.document = this.element.getSVGDocument();
+ this.root = isNil(this.document.documentElement) ? this.element : this.document.documentElement;
+ }
+ catch (e) {
+ }
+
+ this.element.style.zIndex = 1;
+
+ if (isNil(this.element))
+ throw "SVGRenderer() - passed SVG object is not found";
+
+ if (isNil(this.container) || this.container.nodeName.toLowerCase() != "div")
+ throw "SVGRenderer() - No DIV's around the SVG.";
+
+ // internal state
+ this.xlabels = new Array();
+ this.ylabels = new Array();
+
+ // initialise some meta structures in SVG
+ this.defs = this.createSVGElement("defs");
+
+ this.area = {
+ x: this.options.padding.left,
+ y: this.options.padding.top,
+ w: this.width - this.options.padding.left - this.options.padding.right,
+ h: this.height - this.options.padding.top - this.options.padding.bottom
+ };
+
+ MochiKit.DOM.updateNodeAttributes(this.container,
+ {"style":{ "position": "relative", "width": this.width + "px"}});
+
+
+};
+
+
+PlotKit.SVGRenderer.prototype.render = function() {
+ if (this.options.drawBackground)
+ this._renderBackground();
+
+ if (this.layout.style == "bar") {
+ this._renderBarChart();
+ this._renderBarAxis();
+ }
+ else if (this.layout.style == "pie") {
+ this._renderPieChart();
+ this._renderPieAxis();
+ }
+ else if (this.layout.style == "line") {
+ this._renderLineChart();
+ this._renderLineAxis();
+ }
+};
+
+PlotKit.SVGRenderer.prototype._renderBarOrLine = function(data, plotFunc, startFunc, endFunc) {
+
+ var colorCount = this.options.colorScheme.length;
+ var colorScheme = this.options.colorScheme;
+ var setNames = MochiKit.Base.keys(this.layout.datasets);
+ var setCount = setNames.length;
+
+ for (var i = 0; i < setCount; i++) {
+ var setName = setNames[i];
+ var attrs = new Array();
+ var color = colorScheme[i%colorCount];
+
+ if (this.options.shouldFill)
+ attrs["fill"] = color.toRGBString();
+ else
+ attrs["fill"] = "none";
+
+ if (this.options.shouldStroke &&
+ (this.options.strokeColor || this.options.strokeColorTransform)) {
+ if (this.options.strokeColor)
+ attrs["stroke"] = this.options.strokeColor.toRGBString();
+ else if (this.options.strokeColorTransform)
+ attrs["stroke"] = color[this.options.strokeColorTransform]().toRGBString();
+ attrs["strokeWidth"] = this.options.strokeWidth;
+ }
+
+ if (startFunc)
+ startFunc(attrs);
+
+ var forEachFunc = function(obj) {
+ if (obj.name == setName)
+ plotFunc(attrs, obj);
+ };
+
+ MochiKit.Iter.forEach(data, bind(forEachFunc, this));
+ if (endFunc)
+ endFunc(attrs);
+ }
+};
+
+PlotKit.SVGRenderer.prototype._renderBarChart = function() {
+ var bind = MochiKit.Base.bind;
+
+ var drawRect = function(attrs, bar) {
+ var x = this.area.w * bar.x + this.area.x;
+ var y = this.area.h * bar.y + this.area.y;
+ var w = this.area.w * bar.w;
+ var h = this.area.h * bar.h;
+ this._drawRect(x, y, w, h, attrs);
+ };
+ this._renderBarOrLine(this.layout.bars, bind(drawRect, this));
+};
+
+PlotKit.SVGRenderer.prototype._renderLineChart = function() {
+ var bind = MochiKit.Base.bind;
+
+ var addPoint = function(attrs, point) {
+ this._tempPointsBuffer += (this.area.w * point.x + this.area.x) + "," +
+ (this.area.h * point.y + this.area.y) + " ";
+ };
+
+ var startLine = function(attrs) {
+ this._tempPointsBuffer = "";
+ this._tempPointsBuffer += (this.area.x) + "," + (this.area.y+this.area.h) + " ";
+ };
+
+ var endLine = function(attrs) {
+ this._tempPointsBuffer += (this.area.w + this.area.x) + "," +(this.area.h + this.area.y);
+ attrs["points"] = this._tempPointsBuffer;
+ var elem = this.createSVGElement("polygon", attrs);
+ this.root.appendChild(elem);
+ };
+
+ this._renderBarOrLine(this.layout.points,
+ bind(addPoint, this),
+ bind(startLine, this),
+ bind(endLine, this));
+};
+
+
+PlotKit.SVGRenderer.prototype._renderPieChart = function() {
+ var colorCount = this.options.colorScheme.length;
+ var slices = this.layout.slices;
+
+ var centerx = this.area.x + this.area.w * 0.5;
+ var centery = this.area.y + this.area.h * 0.5;
+ var radius = Math.min(this.area.w * this.options.pieRadius,
+ this.area.h * this.options.pieRadius);
+
+ // NOTE NOTE!! Canvas Tag draws the circle clockwise from the y = 0, x = 1
+ // so we have to subtract 90 degrees to make it start at y = 1, x = 0
+
+ // workaround if we only have 1 slice of 100%
+ if (slices.length == 1 && (Math.abs(slices[0].startAngle) - Math.abs(slices[0].endAngle) < 0.1)) {
+ var attrs = {"cx": centerx , "cy": centery , "r": radius };
+ var color = this.options.colorScheme[0];
+ if (this.options.shouldFill)
+ attrs["fill"] = color.toRGBString();
+ else
+ attrs["fill"] = "none";
+
+ if (this.options.shouldStroke &&
+ (this.options.strokeColor || this.options.strokeColorTransform)) {
+ if (this.options.strokeColor)
+ attrs["stroke"] = this.options.strokeColor.toRGBString();
+ else if (this.options.strokeColorTransform)
+ attrs["stroke"] = color[this.options.strokeColorTransform]().toRGBString();
+ attrs["style"] = "stroke-width: " + this.options.strokeWidth;
+ }
+
+ this.root.appendChild(this.createSVGElement("circle", attrs));
+ return;
+ }
+
+ for (var i = 0; i < slices.length; i++) {
+ var attrs = new Array();
+ var color = this.options.colorScheme[i%colorCount];
+ if (this.options.shouldFill)
+ attrs["fill"] = color.toRGBString();
+ else
+ attrs["fill"] = "none";
+
+ if (this.options.shouldStroke &&
+ (this.options.strokeColor || this.options.strokeColorTransform)) {
+ if (this.options.strokeColor)
+ attrs["stroke"] = this.options.strokeColor.toRGBString();
+ else if (this.options.strokeColorTransform)
+ attrs["stroke"] = color[this.options.strokeColorTransform]().toRGBString();
+ attrs["style"] = "stroke-width:" + this.options.strokeWidth;
+ }
+
+ var largearc = 0;
+ if (Math.abs(slices[i].endAngle - slices[i].startAngle) > Math.PI)
+ largearc = 1;
+ var x1 = Math.cos(slices[i].startAngle - Math.PI/2) * radius;
+ var y1 = Math.sin(slices[i].startAngle - Math.PI/2) * radius;
+ var x2 = Math.cos(slices[i].endAngle - Math.PI/2) * radius;
+ var y2 = Math.sin(slices[i].endAngle - Math.PI/2) * radius;
+ var rx = x2 - x1;
+ var ry = y2 - y1;
+
+ var pathString = "M" + centerx + "," + centery + " ";
+ pathString += "l" + x1 + "," + y1 + " ";
+ pathString += "a" + radius + "," + radius + " 0 " + largearc + ",1 " + rx + "," + ry + " z";
+
+ attrs["d"] = pathString;
+
+ var elem = this.createSVGElement("path", attrs);
+ this.root.appendChild(elem);
+ }
+};
+
+PlotKit.SVGRenderer.prototype._renderBarAxis = function() {
+ this._renderAxis();
+}
+
+PlotKit.SVGRenderer.prototype._renderLineAxis = function() {
+ this._renderAxis();
+};
+
+
+PlotKit.SVGRenderer.prototype._renderAxis = function() {
+
+ if (!this.options.drawXAxis && !this.options.drawYAxis)
+ return;
+
+ var labelStyle = {"style":
+ {"position": "absolute",
+ "textAlign": "center",
+ "fontSize": this.options.axisLabelFontSize + "px",
+ "zIndex": 10,
+ "color": this.options.axisLabelColor.toRGBString(),
+ "width": this.options.axisLabelWidth + "px",
+ "overflow": "hidden"
+ }
+ };
+
+ // axis lines
+ var lineAttrs = {
+ "stroke": this.options.axisLineColor.toRGBString(),
+ "strokeWidth": this.options.axisLineWidth
+ };
+
+
+ if (this.options.drawYAxis) {
+ if (this.layout.yticks) {
+ var drawTick = function(tick) {
+ var x = this.area.x;
+ var y = this.area.y + tick[0] * this.area.h;
+ this._drawLine(x, y, x - 3, y, lineAttrs);
+
+ if (this.options.axisLabelUseDiv) {
+ var label = DIV(labelStyle, tick[1]);
+ label.style.top = (y - this.options.axisLabelFontSize) + "px";
+ label.style.left = (x - this.options.padding.left + this.options.axisTickSize) + "px";
+ label.style.textAlign = "left";
+ label.style.width = (this.options.padding.left - 3) + "px";
+ MochiKit.DOM.appendChildNodes(this.container, label);
+ this.ylabels.push(label);
+ }
+ else {
+ var attrs = {
+ y: y + 3,
+ x: (x - this.options.padding.left + 3),
+ width: (this.options.padding.left - this.options.axisTickSize) + "px",
+ height: (this.options.axisLabelFontSize + 3) + "px",
+ fontFamily: "Arial",
+ fontSize: this.options.axisLabelFontSize + "px",
+ fill: this.options.axisLabelColor.toRGBString()
+ };
+
+ /* we can do clipping just like DIVs
+ http://www.xml.com/pub/a/2004/06/02/svgtype.html */
+ /*
+ var mask = this.createSVGElement("mask", {id: "mask" + tick[0]});
+ var maskShape = this.createSVGElement("rect",
+ {y: y + 3,
+ x: (x - this.options.padding.left + 3),
+ width: (this.options.padding.left - this.options.axisTickSize) + "px",
+ height: (this.options.axisLabelFontSize + 3) + "px",
+ style: {"fill": "#ffffff", "stroke": "#000000"}});
+ mask.appendChild(maskShape);
+ this.defs.appendChild(mask);
+
+ attrs["filter"] = "url(#mask" + tick[0] + ")";
+ */
+
+ var label = this.createSVGElement("text", attrs);
+ label.appendChild(this.document.createTextNode(tick[1]));
+ this.root.appendChild(label);
+ }
+ };
+
+ MochiKit.Iter.forEach(this.layout.yticks, bind(drawTick, this));
+ }
+
+ this._drawLine(this.area.x, this.area.y, this.area.x, this.area.y + this.area.h, lineAttrs);
+ }
+
+ if (this.options.drawXAxis) {
+ if (this.layout.xticks) {
+ var drawTick = function(tick) {
+ var x = this.area.x + tick[0] * this.area.w;
+ var y = this.area.y + this.area.h;
+ this._drawLine(x, y, x, y + this.options.axisTickSize, lineAttrs);
+
+ if (this.options.axisLabelUseDiv) {
+ var label = DIV(labelStyle, tick[1]);
+ label.style.top = (y + this.options.axisTickSize) + "px";
+ label.style.left = (x - this.options.axisLabelWidth/2) + "px";
+ label.style.textAlign = "center";
+ label.style.width = this.options.axisLabelWidth + "px";
+ MochiKit.DOM.appendChildNodes(this.container, label);
+ this.xlabels.push(label);
+ }
+ else {
+ var attrs = {
+ y: (y + this.options.axisTickSize + this.options.axisLabelFontSize),
+ x: x - 3,
+ width: this.options.axisLabelWidth + "px",
+ height: (this.options.axisLabelFontSize + 3) + "px",
+ fontFamily: "Arial",
+ fontSize: this.options.axisLabelFontSize + "px",
+ fill: this.options.axisLabelColor.toRGBString(),
+ textAnchor: "middle"
+ };
+ var label = this.createSVGElement("text", attrs);
+ label.appendChild(this.document.createTextNode(tick[1]));
+ this.root.appendChild(label);
+ }
+ };
+
+ MochiKit.Iter.forEach(this.layout.xticks, bind(drawTick, this));
+ }
+
+ this._drawLine(this.area.x, this.area.y + this.area.h, this.area.x + this.area.w, this.area.y + this.area.h, lineAttrs)
+ }
+};
+
+PlotKit.SVGRenderer.prototype._renderPieAxis = function() {
+
+ if (this.layout.xticks) {
+ // make a lookup dict for x->slice values
+ var lookup = new Array();
+ for (var i = 0; i < this.layout.slices.length; i++) {
+ lookup[this.layout.slices[i].xval] = this.layout.slices[i];
+ }
+
+ var centerx = this.area.x + this.area.w * 0.5;
+ var centery = this.area.y + this.area.h * 0.5;
+ var radius = Math.min(this.area.w * this.options.pieRadius + 10,
+ this.area.h * this.options.pieRadius + 10);
+ var labelWidth = this.options.axisLabelWidth;
+
+ for (var i = 0; i < this.layout.xticks.length; i++) {
+ var slice = lookup[this.layout.xticks[i][0]];
+ if (MochiKit.Base.isUndefinedOrNull(slice))
+ continue;
+
+
+ var angle = (slice.startAngle + slice.endAngle)/2;
+ // normalize the angle
+ var normalisedAngle = angle;
+ if (normalisedAngle > Math.PI * 2)
+ normalisedAngle = normalisedAngle - Math.PI * 2;
+ else if (normalisedAngle < 0)
+ normalisedAngle = normalisedAngle + Math.PI * 2;
+
+ var labelx = centerx + Math.sin(normalisedAngle) * (radius + 10);
+ var labely = centery - Math.cos(normalisedAngle) * (radius + 10);
+
+ var attrib = {
+ "position": "absolute",
+ "zIndex": 11,
+ "width": labelWidth + "px",
+ "fontSize": this.options.axisLabelFontSize + "px",
+ "overflow": "hidden",
+ "color": this.options.axisLabelColor.toHexString()
+ };
+
+ var svgattrib = {
+ "width": labelWidth + "px",
+ "fontSize": this.options.axisLabelFontSize + "px",
+ "height": (this.options.axisLabelFontSize + 3) + "px",
+ "fill": this.options.axisLabelColor.toRGBString()
+ };
+
+ if (normalisedAngle <= Math.PI * 0.5) {
+ // text on top and align left
+ MochiKit.Base.update(attrib, {
+ 'textAlign': 'left', 'verticalAlign': 'top',
+ 'left': labelx + 'px',
+ 'top': (labely - this.options.axisLabelFontSize) + "px"
+ });
+ MochiKit.Base.update(svgattrib, {
+ "x": labelx,
+ "y" :(labely - this.options.axisLabelFontSize),
+ "textAnchor": "left"
+ });
+ }
+ else if ((normalisedAngle > Math.PI * 0.5) && (normalisedAngle <= Math.PI)) {
+ // text on bottom and align left
+ MochiKit.Base.update(attrib, {
+ 'textAlign': 'left', 'verticalAlign': 'bottom',
+ 'left': labelx + 'px',
+ 'top': labely + "px"
+ });
+ MochiKit.Base.update(svgattrib, {
+ 'textAnchor': 'left',
+ 'x': labelx,
+ 'y': labely
+ });
+ }
+ else if ((normalisedAngle > Math.PI) && (normalisedAngle <= Math.PI*1.5)) {
+ // text on bottom and align right
+ MochiKit.Base.update(attrib, {
+ 'textAlign': 'right', 'verticalAlign': 'bottom',
+ 'left': labelx + 'px',
+ 'top': labely + "px"
+ });
+ MochiKit.Base.update(svgattrib, {
+ 'textAnchor': 'right',
+ 'x': labelx - labelWidth,
+ 'y': labely
+ });
+ }
+ else {
+ // text on top and align right
+ MochiKit.Base.update(attrib, {
+ 'textAlign': 'left', 'verticalAlign': 'bottom',
+ 'left': labelx + 'px',
+ 'top': labely + "px"
+ });
+ MochiKit.Base.update(svgattrib, {
+ 'textAnchor': 'left',
+ 'x': labelx - labelWidth,
+ 'y': labely - this.options.axisLabelFontSize
+ });
+ }
+
+ if (this.options.axisLabelUseDiv) {
+ var label = DIV({'style': attrib}, this.layout.xticks[i][1]);
+ this.xlabels.push(label);
+ MochiKit.DOM.appendChildNodes(this.container, label);
+ }
+ else {
+ var label = this.createSVGElement("text", svgattrib);
+ label.appendChild(this.document.createTextNode(this.layout.xticks[i][1]))
+ this.root.appendChild(label);
+ }
+ }
+
+ }
+};
+
+PlotKit.SVGRenderer.prototype._renderBackground = function() {
+ var opts = {"stroke": "none",
+ "fill": this.options.backgroundColor.toRGBString()
+ };
+ this._drawRect(0, 0, this.width, this.height, opts);
+};
+
+PlotKit.SVGRenderer.prototype._drawRect = function(x, y, w, h, moreattrs) {
+ var attrs = {x: x + "px", y: y + "px", width: w + "px", height: h + "px"};
+ if (moreattrs)
+ MochiKit.Base.update(attrs, moreattrs);
+
+ var elem = this.createSVGElement("rect", attrs);
+ this.root.appendChild(elem);
+};
+
+PlotKit.SVGRenderer.prototype._drawLine = function(x1, y1, x2, y2, moreattrs) {
+ var attrs = {x1: x1 + "px", y1: y1 + "px", x2: x2 + "px", y2: y2 + "px"};
+ if (moreattrs)
+ MochiKit.Base.update(attrs, moreattrs);
+
+ var elem = this.createSVGElement("line", attrs);
+ this.root.appendChild(elem);
+}
+
+PlotKit.SVGRenderer.prototype.clear = function() {
+ while(this.element.firstChild) {
+ this.element.removeChild(this.element.firstChild);
+ }
+
+ if (this.options.axisLabelUseDiv) {
+ for (var i = 0; i < this.xlabels.length; i++) {
+ MochiKit.DOM.removeElement(this.xlabels[i]);
+ }
+ for (var i = 0; i < this.ylabels.length; i++) {
+ MochiKit.DOM.removeElement(this.ylabels[i]);
+ }
+ }
+ this.xlabels = new Array();
+ this.ylabels = new Array();
+};
+
+
+PlotKit.SVGRenderer.prototype.createSVGElement = function(name, attrs) {
+ var isNil = MochiKit.Base.isUndefinedOrNull;
+ var elem;
+ var doc = isNil(this.document) ? document : this.document;
+
+ try {
+ elem = doc.createElementNS(PlotKit.SVGRenderer.SVGNS, name);
+ }
+ catch (e) {
+ elem = doc.createElement(name);
+ elem.setAttribute("xmlns", PlotKit.SVGRenderer.SVGNS);
+ }
+
+ if (attrs)
+ MochiKit.DOM.updateNodeAttributes(elem, attrs);
+
+ // TODO: we don't completely emulate the MochiKit.DOM.createElement
+ // as we don't care about nodes contained. We really should though.
+
+ return elem;
+
+};
+
+
+PlotKit.SVGRenderer.SVG = function(attrs) {
+ // we have to do things differently for IE+AdobeSVG.
+ // My guess this works (via trial and error) is that we need to
+ // have an SVG object in order to use SVGDocument.createElementNS
+ // but IE doesn't allow us to that.
+
+ var ie = navigator.appVersion.match(/MSIE (\d\.\d)/);
+ var opera = (navigator.userAgent.toLowerCase().indexOf("opera") != -1);
+ if (ie && (ie[1] >= 6) && (!opera)) {
+ var width = attrs["width"] ? attrs["width"] : "100";
+ var height = attrs["height"] ? attrs["height"] : "100";
+ var eid = attrs["id"] ? attrs["id"] : "notunique";
+
+ var html = '<svg:svg width="' + width + '" height="' + height + '" ';
+ html += 'id="' + eid + '" version="1.1" baseProfile="full" />';
+
+ var canvas = document.createElement(html);
+
+ // create embedded SVG inside SVG.
+ var group = canvas.getSVGDocument().createElementNS(PlotKit.SVGRenderer.SVGNS, "svg");
+ group.setAttribute("width", width);
+ group.setAttribute("height", height);
+ canvas.getSVGDocument().appendChild(group);
+
+ return canvas;
+ }
+ else {
+ return PlotKit.SVGRenderer.prototype.createSVGElement("svg", attrs);
+ }
+};
+
+PlotKit.SVGRenderer.isSupported = function() {
+ var isOpera = (navigator.userAgent.toLowerCase().indexOf("opera") != -1);
+ var ieVersion = navigator.appVersion.match(/MSIE (\d\.\d)/);
+ var safariVersion = navigator.userAgent.match(/AppleWebKit\/(\d+)/);
+ var operaVersion = navigator.userAgent.match(/Opera\/(\d*\.\d*)/);
+ var mozillaVersion = navigator.userAgent.match(/rv:(\d*\.\d*).*Gecko/);
+ var svgFeature = "http://www.w3.org/TR/SVG11/feature#SVG";
+
+ if (ieVersion && (ieVersion[1] >= 6) && !isOpera) {
+ return document.implementation.hasFeature(svgFeature,"1.1");
+ /*
+ var dummysvg = document.createElement('<svg:svg width="1" height="1" baseProfile="full" version="1.1" id="dummy">');
+ try {
+ dummysvg.getSVGDocument();
+ dummysvg = null;
+ return true;
+ }
+ catch (e) {
+ return false;
+ }
+ */
+
+ }
+
+ /* support not really there yet. no text and paths are buggy
+ if (safariVersion && (safariVersion[1] > 419))
+ return true;
+ */
+
+ if (operaVersion && (operaVersion[1] > 8.9))
+ return true
+
+ if (mozillaVersion && (mozillaVersion > 1.7))
+ return true;
+
+ return false;
+};
+
+// Namespace Iniitialisation
+
+PlotKit.SVG = {}
+PlotKit.SVG.SVGRenderer = PlotKit.SVGRenderer;
+
+PlotKit.SVG.EXPORT = [
+ "SVGRenderer"
+];
+
+PlotKit.SVG.EXPORT_OK = [
+ "SVGRenderer"
+];
+
+PlotKit.SVG.__new__ = function() {
+ var m = MochiKit.Base;
+
+ m.nameFunctions(this);
+
+ this.EXPORT_TAGS = {
+ ":common": this.EXPORT,
+ ":all": m.concat(this.EXPORT, this.EXPORT_OK)
+ };
+};
+
+PlotKit.SVG.__new__();
+MochiKit.Base._exportSymbols(this, PlotKit.SVG);
+
diff --git a/site/app/webroot/js/plotkit/SweetCanvas.js b/site/app/webroot/js/plotkit/SweetCanvas.js
new file mode 100644
index 0000000..bb6fe5c
--- /dev/null
+++ b/site/app/webroot/js/plotkit/SweetCanvas.js
@@ -0,0 +1,348 @@
+/*
+ PlotKit Sweet Canvas Renderer
+ =============================
+ Canvas Renderer for PlotKit which looks pretty!
+
+ Copyright
+ ---------
+ Copyright 2005,2006 (c) Alastair Tse <alastair^liquidx.net>
+ For use under the BSD license. <http://www.liquidx.net/plotkit>
+*/
+
+// -------------------------------------------------------------------------
+// Check required components
+// -------------------------------------------------------------------------
+
+try {
+ if (typeof(PlotKit.CanvasRenderer) == 'undefined')
+ {
+ throw "";
+ }
+}
+catch (e) {
+ throw "SweetCanvas depends on MochiKit.{Base,Color,DOM,Format} and PlotKit.{Layout, Canvas}"
+}
+
+
+if (typeof(PlotKit.SweetCanvasRenderer) == 'undefined') {
+ PlotKit.SweetCanvasRenderer = {};
+}
+
+PlotKit.SweetCanvasRenderer = function(element, layout, options) {
+ if (arguments.length > 0) {
+ this.__init__(element, layout, options);
+ }
+};
+
+PlotKit.SweetCanvasRenderer.NAME = "PlotKit.SweetCanvasRenderer";
+PlotKit.SweetCanvasRenderer.VERSION = PlotKit.VERSION;
+
+PlotKit.SweetCanvasRenderer.__repr__ = function() {
+ return "[" + this.NAME + " " + this.VERSION + "]";
+};
+
+PlotKit.SweetCanvasRenderer.toString = function() {
+ return this.__repr__();
+};
+
+// ---------------------------------------------------------------------
+// Subclassing Magic
+// ---------------------------------------------------------------------
+
+PlotKit.SweetCanvasRenderer.prototype = new PlotKit.CanvasRenderer();
+PlotKit.SweetCanvasRenderer.prototype.constructor = PlotKit.SweetCanvasRenderer;
+PlotKit.SweetCanvasRenderer.__super__ = PlotKit.CanvasRenderer.prototype;
+
+// ---------------------------------------------------------------------
+// Constructor
+// ---------------------------------------------------------------------
+
+PlotKit.SweetCanvasRenderer.prototype.__init__ = function(el, layout, opts) {
+ var moreOpts = PlotKit.Base.officeBlue();
+ MochiKit.Base.update(moreOpts, opts);
+ PlotKit.SweetCanvasRenderer.__super__.__init__.call(this, el, layout, moreOpts);
+};
+
+// ---------------------------------------------------------------------
+// Extended Plotting Functions
+// ---------------------------------------------------------------------
+
+PlotKit.SweetCanvasRenderer.prototype._renderBarChart = function() {
+ var bind = MochiKit.Base.bind;
+ var shadowColor = Color.blackColor().colorWithAlpha(0.1).toRGBString();
+
+ var prepareFakeShadow = function(context, x, y, w, h) {
+ context.fillStyle = shadowColor;
+ context.fillRect(x-2, y-2, w+4, h+2);
+ context.fillStyle = shadowColor;
+ context.fillRect(x-1, y-1, w+2, h+1);
+ };
+
+ var colorCount = this.options.colorScheme.length;
+ var colorScheme = this.options.colorScheme;
+ var setNames = PlotKit.Base.keys(this.layout.datasets);
+ var setCount = setNames.length;
+
+ var chooseColor = function(name) {
+ for (var i = 0; i < setCount; i++) {
+ if (name == setNames[i])
+ return colorScheme[i%colorCount];
+ }
+ return colorScheme[0];
+ };
+
+ var drawRect = function(context, bar) {
+ var x = this.area.w * bar.x + this.area.x;
+ var y = this.area.h * bar.y + this.area.y;
+ var w = this.area.w * bar.w;
+ var h = this.area.h * bar.h;
+
+ if ((w < 1) || (h < 1))
+ return;
+
+ context.save();
+
+ context.shadowBlur = 5.0;
+ context.shadowColor = Color.fromHexString("#888888").toRGBString();
+
+ if (this.isIE) {
+ context.save();
+ context.fillStyle = "#cccccc";
+ context.fillRect(x-2, y-2, w+4, h+2);
+ context.restore();
+ }
+ else {
+ prepareFakeShadow(context, x, y, w, h);
+ }
+
+ if (this.options.shouldFill) {
+ context.fillStyle = chooseColor(bar.name).toRGBString();
+ context.fillRect(x, y, w, h);
+ }
+
+ context.shadowBlur = 0;
+ context.strokeStyle = Color.whiteColor().toRGBString();
+ context.lineWidth = 2.0;
+
+ if (this.options.shouldStroke) {
+ context.strokeRect(x, y, w, h);
+ }
+
+ context.restore();
+
+ };
+ this._renderBarChartWrap(this.layout.bars, bind(drawRect, this));
+};
+
+PlotKit.SweetCanvasRenderer.prototype._renderLineChart = function() {
+ var context = this.element.getContext("2d");
+ var colorCount = this.options.colorScheme.length;
+ var colorScheme = this.options.colorScheme;
+ var setNames = PlotKit.Base.keys(this.layout.datasets);
+ var setCount = setNames.length;
+ var bind = MochiKit.Base.bind;
+
+
+ for (var i = 0; i < setCount; i++) {
+ var setName = setNames[i];
+ var color = colorScheme[i%colorCount];
+ var strokeX = this.options.strokeColorTransform;
+
+ // setup graphics context
+ context.save();
+
+ // create paths
+ var makePath = function(ctx) {
+ ctx.beginPath();
+ ctx.moveTo(this.area.x, this.area.y + this.area.h);
+ var addPoint = function(ctx_, point) {
+ if (point.name == setName)
+ ctx_.lineTo(this.area.w * point.x + this.area.x,
+ this.area.h * point.y + this.area.y);
+ };
+ MochiKit.Iter.forEach(this.layout.points, partial(addPoint, ctx), this);
+ ctx.lineTo(this.area.w + this.area.x,
+ this.area.h + this.area.y);
+ ctx.lineTo(this.area.x, this.area.y + this.area.h);
+ ctx.closePath();
+ };
+
+ // faux shadow for firefox
+ if (this.options.shouldFill) {
+ context.save();
+ if (this.isIE) {
+ context.fillStyle = "#cccccc";
+ }
+ else {
+ context.fillStyle = Color.blackColor().colorWithAlpha(0.2).toRGBString();
+ }
+ context.translate(-1, -2);
+ bind(makePath, this)(context);
+ if (this.options.shouldFill) {
+ context.fill();
+ }
+ context.restore();
+ }
+
+ context.shadowBlur = 5.0;
+ context.shadowColor = Color.fromHexString("#888888").toRGBString();
+ context.fillStyle = color.toRGBString();
+ context.lineWidth = 2.0;
+ context.strokeStyle = Color.whiteColor().toRGBString();
+
+ if (this.options.shouldFill) {
+ bind(makePath, this)(context);
+ context.fill();
+ }
+ if (this.options.shouldStroke) {
+ bind(makePath, this)(context);
+ context.stroke();
+ }
+ context.restore();
+ }
+};
+
+PlotKit.SweetCanvasRenderer.prototype._renderPieChart = function() {
+ var context = this.element.getContext("2d");
+
+ var colorCount = this.options.colorScheme.length;
+ var slices = this.layout.slices;
+
+ var centerx = this.area.x + this.area.w * 0.5;
+ var centery = this.area.y + this.area.h * 0.5;
+ var radius = Math.min(this.area.w * this.options.pieRadius,
+ this.area.h * this.options.pieRadius);
+
+ if (this.isIE) {
+ centerx = parseInt(centerx);
+ centery = parseInt(centery);
+ radius = parseInt(radius);
+ }
+
+ // NOTE NOTE!! Canvas Tag draws the circle clockwise from the y = 0, x = 1
+ // so we have to subtract 90 degrees to make it start at y = 1, x = 0
+
+ if (!this.isIE) {
+ context.save();
+ var shadowColor = Color.blackColor().colorWithAlpha(0.2);
+ context.fillStyle = shadowColor.toRGBString();
+ context.shadowBlur = 5.0;
+ context.shadowColor = Color.fromHexString("#888888").toRGBString();
+ context.translate(1, 1);
+ context.beginPath();
+ context.moveTo(centerx, centery);
+ context.arc(centerx, centery, radius + 2, 0, Math.PI*2, false);
+ context.closePath();
+ context.fill();
+ context.restore();
+ }
+
+ context.save();
+ context.strokeStyle = Color.whiteColor().toRGBString();
+ context.lineWidth = 2.0;
+ for (var i = 0; i < slices.length; i++) {
+ var color = this.options.colorScheme[i%colorCount];
+ context.fillStyle = color.toRGBString();
+
+ var makePath = function() {
+ context.beginPath();
+ context.moveTo(centerx, centery);
+ context.arc(centerx, centery, radius,
+ slices[i].startAngle - Math.PI/2,
+ slices[i].endAngle - Math.PI/2,
+ false);
+ context.lineTo(centerx, centery);
+ context.closePath();
+ };
+
+ if (Math.abs(slices[i].startAngle - slices[i].endAngle) > 0.0001) {
+ if (this.options.shouldFill) {
+ makePath();
+ context.fill();
+ }
+ if (this.options.shouldStroke) {
+ makePath();
+ context.stroke();
+ }
+ }
+ }
+ context.restore();
+};
+
+PlotKit.SweetCanvasRenderer.prototype._renderBackground = function() {
+ var context = this.element.getContext("2d");
+
+ if (this.layout.style == "bar" || this.layout.style == "line") {
+ context.save();
+ context.fillStyle = this.options.backgroundColor.toRGBString();
+ context.fillRect(this.area.x, this.area.y, this.area.w, this.area.h);
+ context.strokeStyle = this.options.axisLineColor.toRGBString();
+ context.lineWidth = 1.0;
+
+ var ticks = this.layout.yticks;
+ var horiz = false;
+ if (this.layout.style == "bar" &&
+ this.layout.options.barOrientation == "horizontal") {
+ ticks = this.layout.xticks;
+ horiz = true;
+ }
+
+ for (var i = 0; i < ticks.length; i++) {
+ var x1 = 0;
+ var y1 = 0;
+ var x2 = 0;
+ var y2 = 0;
+
+ if (horiz) {
+ x1 = ticks[i][0] * this.area.w + this.area.x;
+ y1 = this.area.y;
+ x2 = x1;
+ y2 = y1 + this.area.h;
+ }
+ else {
+ x1 = this.area.x;
+ y1 = ticks[i][0] * this.area.h + this.area.y;
+ x2 = x1 + this.area.w;
+ y2 = y1;
+ }
+
+ context.beginPath();
+ context.moveTo(x1, y1);
+ context.lineTo(x2, y2);
+ context.closePath();
+ context.stroke();
+ }
+ context.restore();
+ }
+ else {
+ PlotKit.SweetCanvasRenderer.__super__._renderBackground.call(this);
+ }
+};
+
+// Namespace Iniitialisation
+
+PlotKit.SweetCanvas = {}
+PlotKit.SweetCanvas.SweetCanvasRenderer = PlotKit.SweetCanvasRenderer;
+
+PlotKit.SweetCanvas.EXPORT = [
+ "SweetCanvasRenderer"
+];
+
+PlotKit.SweetCanvas.EXPORT_OK = [
+ "SweetCanvasRenderer"
+];
+
+PlotKit.SweetCanvas.__new__ = function() {
+ var m = MochiKit.Base;
+
+ m.nameFunctions(this);
+
+ this.EXPORT_TAGS = {
+ ":common": this.EXPORT,
+ ":all": m.concat(this.EXPORT, this.EXPORT_OK)
+ };
+};
+
+PlotKit.SweetCanvas.__new__();
+MochiKit.Base._exportSymbols(this, PlotKit.SweetCanvas);
+
diff --git a/site/app/webroot/js/plotkit/SweetSVG.js b/site/app/webroot/js/plotkit/SweetSVG.js
new file mode 100644
index 0000000..4183058
--- /dev/null
+++ b/site/app/webroot/js/plotkit/SweetSVG.js
@@ -0,0 +1,247 @@
+/*
+ PlotKit Sweet SVG Renderer
+ ==========================
+ SVG Renderer for PlotKit which looks pretty!
+
+ Copyright
+ ---------
+ Copyright 2005,2006 (c) Alastair Tse <alastair^liquidx.net>
+ For use under the BSD license. <http://www.liquidx.net/plotkit>
+*/
+
+
+// -------------------------------------------------------------------------
+// Check required components
+// -------------------------------------------------------------------------
+
+try {
+ if (typeof(PlotKit.SVGRenderer) == 'undefined')
+ {
+ throw "";
+ }
+}
+catch (e) {
+ throw "SweetSVG depends on MochiKit.{Base,Color,DOM,Format} and PlotKit.{Layout, SVG}"
+}
+
+
+if (typeof(PlotKit.SweetSVGRenderer) == 'undefined') {
+ PlotKit.SweetSVGRenderer = {};
+}
+
+PlotKit.SweetSVGRenderer = function(element, layout, options) {
+ if (arguments.length > 0) {
+ this.__init__(element, layout, options);
+ }
+};
+
+PlotKit.SweetSVGRenderer.NAME = "PlotKit.SweetSVGRenderer";
+PlotKit.SweetSVGRenderer.VERSION = PlotKit.VERSION;
+
+PlotKit.SweetSVGRenderer.__repr__ = function() {
+ return "[" + this.NAME + " " + this.VERSION + "]";
+};
+
+PlotKit.SweetSVGRenderer.toString = function() {
+ return this.__repr__();
+};
+
+// ---------------------------------------------------------------------
+// Subclassing Magic
+// ---------------------------------------------------------------------
+
+PlotKit.SweetSVGRenderer.prototype = new PlotKit.SVGRenderer();
+PlotKit.SweetSVGRenderer.prototype.constructor = PlotKit.SweetSVGRenderer;
+PlotKit.SweetSVGRenderer.__super__ = PlotKit.SVGRenderer.prototype;
+
+// ---------------------------------------------------------------------
+// Constructor
+// ---------------------------------------------------------------------
+
+PlotKit.SweetSVGRenderer.prototype.__init__ = function(element, layout, options) {
+ var moreOpts = PlotKit.Base.officeBlue();
+ MochiKit.Base.update(moreOpts, options);
+ PlotKit.SweetSVGRenderer.__super__.__init__.call(this, element, layout, moreOpts);
+ //this._addDropShadowFilter();
+};
+
+PlotKit.SweetSVGRenderer.prototype._addDropShadowFilter = function() {
+ var filter = this.createSVGElement("filter", {x: 0, y: 0, "id":"dropShadow"});
+ var goffset = this.createSVGElement("feOffset",
+ {"in": "SourceGraphic", "dx": 0, "dy": 0, "result": "topCopy"});
+ var blur = this.createSVGElement("feGaussianBlur",
+ {"in": "SourceAlpha", "StdDeviation": 2, "result": "shadow"});
+ var soffset = this.createSVGElement("feOffset",
+ {"in": "shadow", "dx": -1, "dy": -2, "result":"movedShadow"});
+ var merge = this.createSVGElement("feMerge");
+ var gmerge = this.createSVGElement("feMergeNode", {"in":"topCopy"});
+ var smerge = this.createSVGElement("feMergeNode", {"in":"movedShadow"});
+
+ merge.appendChild(gmerge);
+ merge.appendChild(smerge);
+ filter.appendChild(goffset);
+ filter.appendChild(blur);
+ filter.appendChild(soffset);
+ filter.appendChild(merge);
+ this.defs.appendChild(filter);
+};
+
+// ---------------------------------------------------------------------
+// Extended Plotting Functions
+// ---------------------------------------------------------------------
+
+PlotKit.SweetSVGRenderer.prototype._renderBarChart = function() {
+ var bind = MochiKit.Base.bind;
+ var shadowColor = Color.blackColor().toRGBString();
+ var shadowStyle = "fill:" + shadowColor + ";fill-opacity:0.15";
+ var strokeStyle = "stroke-width: 2.0; stroke:" + Color.whiteColor().toRGBString();
+
+ var drawRect = function(attrs, bar) {
+ var x = this.area.w * bar.x + this.area.x;
+ var y = this.area.h * bar.y + this.area.y;
+ var w = this.area.w * bar.w;
+ var h = this.area.h * bar.h;
+
+ if ((w < 1) || (h < 1))
+ return;
+
+ //attrs["filter"] = "url(#dropShadow)";
+ attrs["style"] = strokeStyle;
+ this._drawRect(x - 2, y - 1, w+4, h+2, {"style":shadowStyle});
+ this._drawRect(x, y, w, h, attrs);
+ };
+ this._renderBarOrLine(this.layout.bars, bind(drawRect, this));
+
+};
+
+PlotKit.SweetSVGRenderer.prototype._renderLineChart = function() {
+ var bind = MochiKit.Base.bind;
+ var shadowColor = Color.blackColor().toRGBString();
+ var shadowStyle = "fill:" + shadowColor + ";fill-opacity:0.15";
+ var strokeStyle = "stroke-width: 2.0; stroke:" + Color.whiteColor().toRGBString();
+
+ var addPoint = function(attrs, point) {
+ this._tempPointsBuffer += (this.area.w * point.x + this.area.x) + "," +
+ (this.area.h * point.y + this.area.y) + " ";
+ };
+
+ var startLine = function(attrs) {
+ this._tempPointsBuffer = "";
+ this._tempPointsBuffer += (this.area.x) + "," + (this.area.y+this.area.h) + " ";
+ };
+
+ var endLine = function(attrs) {
+ this._tempPointsBuffer += (this.area.w + this.area.x) + "," +(this.area.h + this.area.y);
+ attrs["points"] = this._tempPointsBuffer;
+
+ attrs["stroke"] = "none";
+ attrs["transform"] = "translate(-2, -1)";
+ attrs["style"] = shadowStyle;
+ var shadow = this.createSVGElement("polygon", attrs);
+ this.root.appendChild(shadow);
+
+ attrs["transform"] = "";
+ attrs["style"] = strokeStyle;
+ var elem = this.createSVGElement("polygon", attrs);
+ this.root.appendChild(elem);
+
+
+ };
+
+ this._renderBarOrLine(this.layout.points,
+ bind(addPoint, this),
+ bind(startLine, this),
+ bind(endLine, this));
+};
+
+PlotKit.SweetSVGRenderer.prototype._renderPieChart = function() {
+ var centerx = this.area.x + this.area.w * 0.5;
+ var centery = this.area.y + this.area.h * 0.5;
+ var shadowColor = Color.blackColor().toRGBString();
+ var radius = Math.min(this.area.w * this.options.pieRadius,
+ this.area.h * this.options.pieRadius);
+ var shadowStyle = "fill:" + shadowColor + ";fill-opacity:0.15";
+
+ var shadow = this.createSVGElement("circle",
+ {"style": shadowStyle, "cx": centerx + 1, "cy": centery + 1, "r": radius + 1});
+ this.root.appendChild(shadow);
+
+ PlotKit.SweetSVGRenderer.__super__._renderPieChart.call(this);
+};
+
+
+PlotKit.SweetSVGRenderer.prototype._renderBackground = function() {
+ var attrs = {
+ "fill": this.options.backgroundColor.toRGBString(),
+ "stroke": "none"
+ };
+
+
+ if (this.layout.style == "bar" || this.layout.style == "line") {
+ this._drawRect(this.area.x, this.area.y,
+ this.area.w, this.area.h, attrs);
+
+ var ticks = this.layout.yticks;
+ var horiz = false;
+ if (this.layout.style == "bar" &&
+ this.layout.options.barOrientation == "horizontal") {
+ ticks = this.layout.xticks;
+ horiz = true;
+ }
+
+ for (var i = 0; i < ticks.length; i++) {
+ var x = 0;
+ var y = 0;
+ var w = 0;
+ var h = 0;
+
+ if (horiz) {
+ x = ticks[i][0] * this.area.w + this.area.x;
+ y = this.area.y;
+ w = 1;
+ h = this.area.w;
+ }
+ else {
+ x = this.area.x;
+ y = ticks[i][0] * this.area.h + this.area.y;
+ w = this.area.w;
+ h = 1;
+ }
+
+ this._drawRect(x, y, w, h,
+ {"fill": this.options.axisLineColor.toRGBString()});
+ }
+ }
+ else {
+ PlotKit.SweetSVGRenderer.__super__._renderBackground.call(this);
+
+ }
+
+};
+
+// Namespace Iniitialisation
+
+PlotKit.SweetSVG = {}
+PlotKit.SweetSVG.SweetSVGRenderer = PlotKit.SweetSVGRenderer;
+
+PlotKit.SweetSVG.EXPORT = [
+ "SweetSVGRenderer"
+];
+
+PlotKit.SweetSVG.EXPORT_OK = [
+ "SweetSVGRenderer"
+];
+
+PlotKit.SweetSVG.__new__ = function() {
+ var m = MochiKit.Base;
+
+ m.nameFunctions(this);
+
+ this.EXPORT_TAGS = {
+ ":common": this.EXPORT,
+ ":all": m.concat(this.EXPORT, this.EXPORT_OK)
+ };
+};
+
+PlotKit.SweetSVG.__new__();
+MochiKit.Base._exportSymbols(this, PlotKit.SweetSVG);
diff --git a/site/app/webroot/js/plotkit/dummy.svg b/site/app/webroot/js/plotkit/dummy.svg
new file mode 100644
index 0000000..6a82bd4
--- /dev/null
+++ b/site/app/webroot/js/plotkit/dummy.svg
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://web.resource.org/cc/"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink">
+</svg>
diff --git a/site/app/webroot/js/plotkit/excanvas.js b/site/app/webroot/js/plotkit/excanvas.js
new file mode 100755
index 0000000..ca77da2
--- /dev/null
+++ b/site/app/webroot/js/plotkit/excanvas.js
@@ -0,0 +1,723 @@
+// Copyright 2006 Google Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// TODO: Patterns
+// TODO: Radial gradient
+// TODO: Clipping paths
+// TODO: Coordsize (still need to support stretching)
+// TODO: Painting mode
+// TODO: Optimize
+// TODO: canvas width/height sets content size in moz, border size in ie
+
+// only add this code if we do not already have a canvas implementation
+if (!window.CanvasRenderingContext2D) {
+
+(function () {
+
+ // alias some functions to make (compiled) code shorter
+ var m = Math;
+ var mr = m.round;
+ var ms = m.sin;
+ var mc = m.cos;
+
+ var G_vmlCanvasManager_ = {
+ init: function (opt_doc) {
+ var doc = opt_doc || document;
+ if (/MSIE/.test(navigator.userAgent) && !window.opera) {
+ var self = this;
+ doc.attachEvent("onreadystatechange", function () {
+ self.init_(doc);
+ });
+ }
+ },
+
+ init_: function (doc, e) {
+ if (doc.readyState == "complete") {
+ // create xmlns
+ if (!doc.namespaces["g_vml_"]) {
+ doc.namespaces.add("g_vml_", "urn:schemas-microsoft-com:vml");
+ }
+
+ // setup default css
+ var ss = doc.createStyleSheet();
+ ss.cssText = "canvas{display:inline-block;overflow:hidden;" +
+ "text-align:left;}" +
+ "g_vml_\\:*{behavior:url(#default#VML)}";
+
+ // find all canvas elements
+ var els = doc.getElementsByTagName("canvas");
+ for (var i = 0; i < els.length; i++) {
+ if (!els[i].getContext) {
+ this.initElement(els[i]);
+ }
+ }
+ }
+ },
+
+ fixElement_: function (el) {
+ // in IE before version 5.5 we would need to add HTML: to the tag name
+ // but we do not care about IE before version 6
+ var outerHTML = el.outerHTML;
+ var newEl = document.createElement(outerHTML);
+ // if the tag is still open IE has created the children as siblings and
+ // it has also created a tag with the name "/FOO"
+ if (outerHTML.slice(-2) != "/>") {
+ var tagName = "/" + el.tagName;
+ var ns;
+ // remove content
+ while ((ns = el.nextSibling) && ns.tagName != tagName) {
+ ns.removeNode();
+ }
+ // remove the incorrect closing tag
+ if (ns) {
+ ns.removeNode();
+ }
+ }
+ el.parentNode.replaceChild(newEl, el);
+ return newEl;
+ },
+
+ /**
+ * Public initializes a canvas element so that it can be used as canvas
+ * element from now on. This is called automatically before the page is
+ * loaded but if you are creating elements using createElement you need to
+ * make sure this is called on the element.
+ * @param {HTMLElement} el The canvas element to initialize.
+ * @return {HTMLElement} the element that was created.
+ */
+ initElement: function (el) {
+ el = this.fixElement_(el);
+ el.getContext = function () {
+ if (this.context_) {
+ return this.context_;
+ }
+ return this.context_ = new CanvasRenderingContext2D_(this);
+ };
+
+ // do not use inline function because that will leak memory
+ // el.attachEvent('onpropertychange', onPropertyChange)
+ el.attachEvent('onresize', onResize);
+
+ var attrs = el.attributes;
+ if (attrs.width && attrs.width.specified) {
+ // TODO: use runtimeStyle and coordsize
+ // el.getContext().setWidth_(attrs.width.nodeValue);
+ el.style.width = attrs.width.nodeValue + "px";
+ }
+ if (attrs.height && attrs.height.specified) {
+ // TODO: use runtimeStyle and coordsize
+ // el.getContext().setHeight_(attrs.height.nodeValue);
+ el.style.height = attrs.height.nodeValue + "px";
+ }
+ //el.getContext().setCoordsize_()
+ return el;
+ }
+ };
+
+ function onPropertyChange(e) {
+ // we need to watch changes to width and height
+ switch (e.propertyName) {
+ case 'width':
+ case 'height':
+ // TODO: coordsize and size
+ break;
+ }
+ }
+
+ function onResize(e) {
+ var el = e.srcElement;
+ if (el.firstChild) {
+ el.firstChild.style.width = el.clientWidth + 'px';
+ el.firstChild.style.height = el.clientHeight + 'px';
+ }
+ }
+
+ G_vmlCanvasManager_.init();
+
+ // precompute "00" to "FF"
+ var dec2hex = [];
+ for (var i = 0; i < 16; i++) {
+ for (var j = 0; j < 16; j++) {
+ dec2hex[i * 16 + j] = i.toString(16) + j.toString(16);
+ }
+ }
+
+ function createMatrixIdentity() {
+ return [
+ [1, 0, 0],
+ [0, 1, 0],
+ [0, 0, 1]
+ ];
+ }
+
+ function matrixMultiply(m1, m2) {
+ var result = createMatrixIdentity();
+
+ for (var x = 0; x < 3; x++) {
+ for (var y = 0; y < 3; y++) {
+ var sum = 0;
+
+ for (var z = 0; z < 3; z++) {
+ sum += m1[x][z] * m2[z][y];
+ }
+
+ result[x][y] = sum;
+ }
+ }
+ return result;
+ }
+
+ function copyState(o1, o2) {
+ o2.fillStyle = o1.fillStyle;
+ o2.lineCap = o1.lineCap;
+ o2.lineJoin = o1.lineJoin;
+ o2.lineWidth = o1.lineWidth;
+ o2.miterLimit = o1.miterLimit;
+ o2.shadowBlur = o1.shadowBlur;
+ o2.shadowColor = o1.shadowColor;
+ o2.shadowOffsetX = o1.shadowOffsetX;
+ o2.shadowOffsetY = o1.shadowOffsetY;
+ o2.strokeStyle = o1.strokeStyle;
+ }
+
+ function processStyle(styleString) {
+ var str, alpha = 1;
+
+ styleString = String(styleString);
+ if (styleString.substring(0, 3) == "rgb") {
+ var start = styleString.indexOf("(", 3);
+ var end = styleString.indexOf(")", start + 1);
+ var guts = styleString.substring(start + 1, end).split(",");
+
+ str = "#";
+ for (var i = 0; i < 3; i++) {
+ str += dec2hex[parseInt(guts[i])];
+ }
+
+ if ((guts.length == 4) && (styleString.substr(3, 1) == "a")) {
+ alpha = guts[3];
+ }
+ } else {
+ str = styleString;
+ }
+
+ return [str, alpha];
+ }
+
+ function processLineCap(lineCap) {
+ switch (lineCap) {
+ case "butt":
+ return "flat";
+ case "round":
+ return "round";
+ case "square":
+ default:
+ return "square";
+ }
+ }
+
+ /**
+ * This class implements CanvasRenderingContext2D interface as described by
+ * the WHATWG.
+ * @param {HTMLElement} surfaceElement The element that the 2D context should
+ * be associated with
+ */
+ function CanvasRenderingContext2D_(surfaceElement) {
+ this.m_ = createMatrixIdentity();
+
+ this.mStack_ = [];
+ this.aStack_ = [];
+ this.currentPath_ = [];
+
+ // Canvas context properties
+ this.strokeStyle = "#000";
+ this.fillStyle = "#ccc";
+
+ this.lineWidth = 1;
+ this.lineJoin = "miter";
+ this.lineCap = "butt";
+ this.miterLimit = 10;
+ this.globalAlpha = 1;
+
+ var el = document.createElement('div');
+ el.style.width = surfaceElement.clientWidth + 'px';
+ el.style.height = surfaceElement.clientHeight + 'px';
+ el.style.overflow = 'hidden';
+ el.style.position = 'absolute';
+ surfaceElement.appendChild(el);
+
+ this.element_ = el;
+ this.arcScaleX_ = 1;
+ this.arcScaleY_ = 1;
+ };
+
+ var contextPrototype = CanvasRenderingContext2D_.prototype;
+ contextPrototype.clearRect = function() {
+ this.element_.innerHTML = "";
+ this.currentPath_ = [];
+ };
+
+ contextPrototype.beginPath = function() {
+ // TODO: Branch current matrix so that save/restore has no effect
+ // as per safari docs.
+
+ this.currentPath_ = [];
+ };
+
+ contextPrototype.moveTo = function(aX, aY) {
+ this.currentPath_.push({type: "moveTo", x: aX, y: aY});
+ };
+
+ contextPrototype.lineTo = function(aX, aY) {
+ this.currentPath_.push({type: "lineTo", x: aX, y: aY});
+ };
+
+ contextPrototype.bezierCurveTo = function(aCP1x, aCP1y,
+ aCP2x, aCP2y,
+ aX, aY) {
+ this.currentPath_.push({type: "bezierCurveTo",
+ cp1x: aCP1x,
+ cp1y: aCP1y,
+ cp2x: aCP2x,
+ cp2y: aCP2y,
+ x: aX,
+ y: aY});
+ };
+
+ contextPrototype.quadraticCurveTo = function(aCPx, aCPy, aX, aY) {
+ // VML's qb produces different output to Firefox's
+ // FF's behaviour seems to have changed in 1.5.0.1, check this
+ this.bezierCurveTo(aCPx, aCPy, aCPx, aCPy, aX, aY);
+ };
+
+ contextPrototype.arc = function(aX, aY, aRadius,
+ aStartAngle, aEndAngle, aClockwise) {
+ aRadius *= 10;
+ var arcType = aClockwise ? "at" : "wa";
+
+ var xStart = aX + (mc(aStartAngle) * aRadius) - 5;
+ var yStart = aY + (ms(aStartAngle) * aRadius) - 5;
+
+ var xEnd = aX + (mc(aEndAngle) * aRadius) - 5;
+ var yEnd = aY + (ms(aEndAngle) * aRadius) - 5;
+
+ this.currentPath_.push({type: arcType,
+ x: aX,
+ y: aY,
+ radius: aRadius,
+ xStart: xStart,
+ yStart: yStart,
+ xEnd: xEnd,
+ yEnd: yEnd});
+
+ };
+
+ contextPrototype.rect = function(aX, aY, aWidth, aHeight) {
+ this.moveTo(aX, aY);
+ this.lineTo(aX + aWidth, aY);
+ this.lineTo(aX + aWidth, aY + aHeight);
+ this.lineTo(aX, aY + aHeight);
+ this.closePath();
+ };
+
+ contextPrototype.strokeRect = function(aX, aY, aWidth, aHeight) {
+ // Will destroy any existing path (same as FF behaviour)
+ this.beginPath();
+ this.moveTo(aX, aY);
+ this.lineTo(aX + aWidth, aY);
+ this.lineTo(aX + aWidth, aY + aHeight);
+ this.lineTo(aX, aY + aHeight);
+ this.closePath();
+ this.stroke();
+ };
+
+ contextPrototype.fillRect = function(aX, aY, aWidth, aHeight) {
+ // Will destroy any existing path (same as FF behaviour)
+ this.beginPath();
+ this.moveTo(aX, aY);
+ this.lineTo(aX + aWidth, aY);
+ this.lineTo(aX + aWidth, aY + aHeight);
+ this.lineTo(aX, aY + aHeight);
+ this.closePath();
+ this.fill();
+ };
+
+ contextPrototype.createLinearGradient = function(aX0, aY0, aX1, aY1) {
+ var gradient = new CanvasGradient_("gradient");
+ return gradient;
+ };
+
+ contextPrototype.createRadialGradient = function(aX0, aY0,
+ aR0, aX1,
+ aY1, aR1) {
+ var gradient = new CanvasGradient_("gradientradial");
+ gradient.radius1_ = aR0;
+ gradient.radius2_ = aR1;
+ gradient.focus_.x = aX0;
+ gradient.focus_.y = aY0;
+ return gradient;
+ };
+
+ contextPrototype.drawImage = function (image, var_args) {
+ var dx, dy, dw, dh, sx, sy, sw, sh;
+ var w = image.width;
+ var h = image.height;
+
+ if (arguments.length == 3) {
+ dx = arguments[1];
+ dy = arguments[2];
+ sx = sy = 0;
+ sw = dw = w;
+ sh = dh = h;
+ } else if (arguments.length == 5) {
+ dx = arguments[1];
+ dy = arguments[2];
+ dw = arguments[3];
+ dh = arguments[4];
+ sx = sy = 0;
+ sw = w;
+ sh = h;
+ } else if (arguments.length == 9) {
+ sx = arguments[1];
+ sy = arguments[2];
+ sw = arguments[3];
+ sh = arguments[4];
+ dx = arguments[5];
+ dy = arguments[6];
+ dw = arguments[7];
+ dh = arguments[8];
+ } else {
+ throw "Invalid number of arguments";
+ }
+
+ var d = this.getCoords_(dx, dy);
+
+ var w2 = (sw / 2);
+ var h2 = (sh / 2);
+
+ var vmlStr = [];
+
+ // For some reason that I've now forgotten, using divs didn't work
+ vmlStr.push(' <g_vml_:group',
+ ' coordsize="1000,1000"',
+ ' coordorigin="0, 0"' ,
+ ' style="width:100px;height:100px;position:absolute;');
+
+ // If filters are necessary (rotation exists), create them
+ // filters are bog-slow, so only create them if abbsolutely necessary
+ // The following check doesn't account for skews (which don't exist
+ // in the canvas spec (yet) anyway.
+
+ if (this.m_[0][0] != 1 || this.m_[0][1]) {
+ var filter = [];
+
+ // Note the 12/21 reversal
+ filter.push("M11='", this.m_[0][0], "',",
+ "M12='", this.m_[1][0], "',",
+ "M21='", this.m_[0][1], "',",
+ "M22='", this.m_[1][1], "',",
+ "Dx='", d.x, "',",
+ "Dy='", d.y, "'");
+
+ // Bounding box calculation (need to minimize displayed area so that
+ // filters don't waste time on unused pixels.
+ var max = d;
+ var c2 = this.getCoords_(dx+dw, dy);
+ var c3 = this.getCoords_(dx, dy+dh);
+ var c4 = this.getCoords_(dx+dw, dy+dh);
+
+ max.x = Math.max(max.x, c2.x, c3.x, c4.x);
+ max.y = Math.max(max.y, c2.y, c3.y, c4.y);
+
+ vmlStr.push(" padding:0 ", mr(max.x), "px ", mr(max.y),
+ "px 0;filter:progid:DXImageTransform.Microsoft.Matrix(",
+ filter.join(""), ", sizingmethod='clip');")
+ } else {
+ vmlStr.push(" top:", d.y, "px;left:", d.x, "px;")
+ }
+
+ vmlStr.push(' ">' ,
+ '<g_vml_:image src="', image.src, '"',
+ ' style="width:', dw, ';',
+ ' height:', dh, ';"',
+ ' cropleft="', sx / w, '"',
+ ' croptop="', sy / h, '"',
+ ' cropright="', (w - sx - sw) / w, '"',
+ ' cropbottom="', (h - sy - sh) / h, '"',
+ ' />',
+ '</g_vml_:group>');
+
+ this.element_.insertAdjacentHTML("BeforeEnd",
+ vmlStr.join(""));
+ };
+
+ contextPrototype.stroke = function(aFill) {
+ var lineStr = [];
+ var lineOpen = false;
+ var a = processStyle(aFill ? this.fillStyle : this.strokeStyle);
+ var color = a[0];
+ var opacity = a[1] * this.globalAlpha;
+
+ lineStr.push('<g_vml_:shape',
+ ' fillcolor="', color, '"',
+ ' filled="', Boolean(aFill), '"',
+ ' style="position:absolute;width:10;height:10;"',
+ ' coordorigin="0 0" coordsize="100 100"',
+ ' stroked="', !aFill, '"',
+ ' strokeweight="', this.lineWidth, '"',
+ ' strokecolor="', color, '"',
+ ' path="');
+
+ var newSeq = false;
+ var min = {x: null, y: null};
+ var max = {x: null, y: null};
+
+ for (var i = 0; i < this.currentPath_.length; i++) {
+ var p = this.currentPath_[i];
+
+ if (p.type == "moveTo") {
+ lineStr.push(" m ");
+ var c = this.getCoords_(p.x, p.y);
+ lineStr.push(mr(c.x), ",", mr(c.y));
+ } else if (p.type == "lineTo") {
+ lineStr.push(" l ");
+ var c = this.getCoords_(p.x, p.y);
+ lineStr.push(mr(c.x), ",", mr(c.y));
+ } else if (p.type == "close") {
+ lineStr.push(" x ");
+ } else if (p.type == "bezierCurveTo") {
+ lineStr.push(" c ");
+ var c = this.getCoords_(p.x, p.y);
+ var c1 = this.getCoords_(p.cp1x, p.cp1y);
+ var c2 = this.getCoords_(p.cp2x, p.cp2y);
+ lineStr.push(mr(c1.x), ",", mr(c1.y), ",",
+ mr(c2.x), ",", mr(c2.y), ",",
+ mr(c.x), ",", mr(c.y));
+ } else if (p.type == "at" || p.type == "wa") {
+ lineStr.push(" ", p.type, " ");
+ var c = this.getCoords_(p.x, p.y);
+ var cStart = this.getCoords_(p.xStart, p.yStart);
+ var cEnd = this.getCoords_(p.xEnd, p.yEnd);
+
+ lineStr.push(mr(c.x - this.arcScaleX_ * p.radius), ",",
+ mr(c.y - this.arcScaleY_ * p.radius), " ",
+ mr(c.x + this.arcScaleX_ * p.radius), ",",
+ mr(c.y + this.arcScaleY_ * p.radius), " ",
+ mr(cStart.x), ",", mr(cStart.y), " ",
+ mr(cEnd.x), ",", mr(cEnd.y));
+ }
+
+
+ // TODO: Following is broken for curves due to
+ // move to proper paths.
+
+ // Figure out dimensions so we can do gradient fills
+ // properly
+ if(c) {
+ if (min.x == null || c.x < min.x) {
+ min.x = c.x;
+ }
+ if (max.x == null || c.x > max.x) {
+ max.x = c.x;
+ }
+ if (min.y == null || c.y < min.y) {
+ min.y = c.y;
+ }
+ if (max.y == null || c.y > max.y) {
+ max.y = c.y;
+ }
+ }
+ }
+ lineStr.push(' ">');
+
+ if (typeof this.fillStyle == "object") {
+ var focus = {x: "50%", y: "50%"};
+ var width = (max.x - min.x);
+ var height = (max.y - min.y);
+ var dimension = (width > height) ? width : height;
+
+ focus.x = mr((this.fillStyle.focus_.x / width) * 100 + 50) + "%";
+ focus.y = mr((this.fillStyle.focus_.y / height) * 100 + 50) + "%";
+
+ var colors = [];
+
+ // inside radius (%)
+ if (this.fillStyle.type_ == "gradientradial") {
+ var inside = (this.fillStyle.radius1_ / dimension * 100);
+
+ // percentage that outside radius exceeds inside radius
+ var expansion = (this.fillStyle.radius2_ / dimension * 100) - inside;
+ } else {
+ var inside = 0;
+ var expansion = 100;
+ }
+
+ var insidecolor = {offset: null, color: null};
+ var outsidecolor = {offset: null, color: null};
+
+ // We need to sort 'colors' by percentage, from 0 > 100 otherwise ie
+ // won't interpret it correctly
+ this.fillStyle.colors_.sort(function (cs1, cs2) {
+ return cs1.offset - cs2.offset;
+ });
+
+ for (var i = 0; i < this.fillStyle.colors_.length; i++) {
+ var fs = this.fillStyle.colors_[i];
+
+ colors.push( (fs.offset * expansion) + inside, "% ", fs.color, ",");
+
+ if (fs.offset > insidecolor.offset || insidecolor.offset == null) {
+ insidecolor.offset = fs.offset;
+ insidecolor.color = fs.color;
+ }
+
+ if (fs.offset < outsidecolor.offset || outsidecolor.offset == null) {
+ outsidecolor.offset = fs.offset;
+ outsidecolor.color = fs.color;
+ }
+ }
+ colors.pop();
+
+ lineStr.push('<g_vml_:fill',
+ ' color="', outsidecolor.color, '"',
+ ' color2="', insidecolor.color, '"',
+ ' type="', this.fillStyle.type_, '"',
+ ' focusposition="', focus.x, ', ', focus.y, '"',
+ ' colors="', colors.join(""), '"',
+ ' opacity="', opacity, '" />');
+ } else if (aFill) {
+ lineStr.push('<g_vml_:fill color="', color, '" opacity="', opacity, '" />');
+ } else {
+ lineStr.push(
+ '<g_vml_:stroke',
+ ' opacity="', opacity,'"',
+ ' joinstyle="', this.lineJoin, '"',
+ ' miterlimit="', this.miterLimit, '"',
+ ' endcap="', processLineCap(this.lineCap) ,'"',
+ ' weight="', this.lineWidth, 'px"',
+ ' color="', color,'" />'
+ );
+ }
+
+ lineStr.push("</g_vml_:shape>");
+
+ this.element_.insertAdjacentHTML("beforeEnd", lineStr.join(""));
+
+ this.currentPath_ = [];
+ };
+
+ contextPrototype.fill = function() {
+ this.stroke(true);
+ }
+
+ contextPrototype.closePath = function() {
+ this.currentPath_.push({type: "close"});
+ };
+
+ /**
+ * @private
+ */
+ contextPrototype.getCoords_ = function(aX, aY) {
+ return {
+ x: 10 * (aX * this.m_[0][0] + aY * this.m_[1][0] + this.m_[2][0]) - 5,
+ y: 10 * (aX * this.m_[0][1] + aY * this.m_[1][1] + this.m_[2][1]) - 5
+ }
+ };
+
+ contextPrototype.save = function() {
+ var o = {};
+ copyState(this, o);
+ this.aStack_.push(o);
+ this.mStack_.push(this.m_);
+ this.m_ = matrixMultiply(createMatrixIdentity(), this.m_);
+ };
+
+ contextPrototype.restore = function() {
+ copyState(this.aStack_.pop(), this);
+ this.m_ = this.mStack_.pop();
+ };
+
+ contextPrototype.translate = function(aX, aY) {
+ var m1 = [
+ [1, 0, 0],
+ [0, 1, 0],
+ [aX, aY, 1]
+ ];
+
+ this.m_ = matrixMultiply(m1, this.m_);
+ };
+
+ contextPrototype.rotate = function(aRot) {
+ var c = mc(aRot);
+ var s = ms(aRot);
+
+ var m1 = [
+ [c, s, 0],
+ [-s, c, 0],
+ [0, 0, 1]
+ ];
+
+ this.m_ = matrixMultiply(m1, this.m_);
+ };
+
+ contextPrototype.scale = function(aX, aY) {
+ this.arcScaleX_ *= aX;
+ this.arcScaleY_ *= aY;
+ var m1 = [
+ [aX, 0, 0],
+ [0, aY, 0],
+ [0, 0, 1]
+ ];
+
+ this.m_ = matrixMultiply(m1, this.m_);
+ };
+
+ /******** STUBS ********/
+ contextPrototype.clip = function() {
+ // TODO: Implement
+ };
+
+ contextPrototype.arcTo = function() {
+ // TODO: Implement
+ };
+
+ contextPrototype.createPattern = function() {
+ return new CanvasPattern_;
+ };
+
+ // Gradient / Pattern Stubs
+ function CanvasGradient_(aType) {
+ this.type_ = aType;
+ this.radius1_ = 0;
+ this.radius2_ = 0;
+ this.colors_ = [];
+ this.focus_ = {x: 0, y: 0};
+ }
+
+ CanvasGradient_.prototype.addColorStop = function(aOffset, aColor) {
+ aColor = processStyle(aColor);
+ this.colors_.push({offset: 1-aOffset, color: aColor});
+ };
+
+ function CanvasPattern_() {}
+
+ // set up externs
+ G_vmlCanvasManager = G_vmlCanvasManager_;
+ CanvasRenderingContext2D = CanvasRenderingContext2D_;
+ CanvasGradient = CanvasGradient_;
+ CanvasPattern = CanvasPattern_;
+
+})();
+
+} // if
diff --git a/site/app/webroot/js/reviews.js b/site/app/webroot/js/reviews.js
new file mode 100644
index 0000000..d341b27
--- /dev/null
+++ b/site/app/webroot/js/reviews.js
@@ -0,0 +1,105 @@
+// Cheap JS detect for CSS - if it executes, add a class to the body
+// indicating JS works.
+$('body').addClass('with-js');
+
+$(document).ready(function() {
+
+ // Wire up a top-level event delegation handler for all drop-down
+ // selectors in the main content area. This prevents the need to wire
+ // every single selector on page, including those loaded by AJAX.
+ $('#content-main').change(function(e) {
+
+ // Only handle as a review flag selector if parent has 'reason' class.
+ if ( $(e.target.parentNode).hasClass('reason') ) {
+
+ // Grab the selection field, blur because it looks better.
+ var reason_sel = e.target;
+ reason_sel.blur();
+
+ // Flag the review if there's a non-blank reason selected.
+ var reason_opt = reason_sel.options[reason_sel.selectedIndex];
+ var reason = reason_opt.value;
+ if (reason) {
+ var the_form = $(reason_sel).parents('form');
+
+ // If the reason is 'other', prompt for the reason notes.
+ if (reason == 'review_flag_reason_other') {
+
+ // HACK: To cop out on translation worries, just scoop up
+ // elements from the hidden form.
+ var select_title = reason_opt.innerHTML;
+ var notes_label = the_form
+ .children('label.FlagNotesLabel').text();
+
+ // TODO: Maybe make this fancy and DHTML-y someday.
+ var reason_notes = '';
+ reason_notes = window.prompt(select_title, reason_notes);
+
+ // Ask for notes to go along with the choice of "other"
+ if (reason_notes === null) {
+ // Bail out! Looks like the cancel button was hit!
+ reason_sel.selectedIndex = 0; return;
+ }
+
+ // Populate the hidden form field with the notes.
+ the_form.children('input.FlagNotes')
+ .attr('value', reason_notes);
+ }
+
+ // Start the spinner and launch the AJAX request.
+ the_form.children('.reason').addClass('loading');
+ var review_id = the_form
+ .children('input.ReviewId').attr('value');
+ $.ajax({
+ type : 'POST',
+ url : flagurl + '/' + review_id + '/ajax',
+ data : the_form.serialize(),
+ success : function(t) {
+ $('#flag-' + review_id).hide()
+ .html(t)
+ .fadeIn('slow');
+ },
+ error : function(req) {
+ the_form.children('.reason').removeClass('loading');
+ the_form.children('.reason').children('.error').hide()
+ .html(req.responseText).fadeIn('slow');
+ reason_sel.selectedIndex = 0;
+ }
+ });
+ }
+
+ }
+
+ });
+
+ // Wire up all the links to reveal older reviews with Ajax in-place loaders.
+ $('.review .others-by-user a').click(function(e) {
+
+ // Convert from the reveal link parent ID to the content load div ID.
+ var t_pos = 0, t_id = '#' + this.parentNode.id;
+ if (t_pos = t_id.lastIndexOf('-')) {
+ var load_id = '#others-by-user-load-' + t_id.substring(t_pos+1);
+
+ // Hide the reveal link and content div in preparation for reveal.
+ $(this).blur();
+ $(this).addClass('loading');
+ $(load_id).slideUp('fast');
+
+ // Load up the HTML for the user's other hidden reviews.
+ $(load_id).load(
+ this.href + '&bare=1&skip_first=1',
+ null,
+ function(data, status, req) {
+ // Hide the link and reveal the just-loaded content.
+ $(t_id).fadeOut('fast');
+ $(load_id).slideDown('slow');
+ return true;
+ }
+ )
+
+ return false;
+ }
+
+ });
+
+});
diff --git a/site/app/webroot/js/scriptaculous/builder.js b/site/app/webroot/js/scriptaculous/builder.js
new file mode 100644
index 0000000..5b15ba9
--- /dev/null
+++ b/site/app/webroot/js/scriptaculous/builder.js
@@ -0,0 +1,101 @@
+// Copyright (c) 2005 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
+//
+// See scriptaculous.js for full license.
+
+var Builder = {
+ NODEMAP: {
+ AREA: 'map',
+ CAPTION: 'table',
+ COL: 'table',
+ COLGROUP: 'table',
+ LEGEND: 'fieldset',
+ OPTGROUP: 'select',
+ OPTION: 'select',
+ PARAM: 'object',
+ TBODY: 'table',
+ TD: 'table',
+ TFOOT: 'table',
+ TH: 'table',
+ THEAD: 'table',
+ TR: 'table'
+ },
+ // note: For Firefox < 1.5, OPTION and OPTGROUP tags are currently broken,
+ // due to a Firefox bug
+ node: function(elementName) {
+ elementName = elementName.toUpperCase();
+
+ // try innerHTML approach
+ var parentTag = this.NODEMAP[elementName] || 'div';
+ var parentElement = document.createElement(parentTag);
+ try { // prevent IE "feature": http://dev.rubyonrails.org/ticket/2707
+ parentElement.innerHTML = "<" + elementName + "></" + elementName + ">";
+ } catch(e) {}
+ var element = parentElement.firstChild || null;
+
+ // see if browser added wrapping tags
+ if(element && (element.tagName != elementName))
+ element = element.getElementsByTagName(elementName)[0];
+
+ // fallback to createElement approach
+ if(!element) element = document.createElement(elementName);
+
+ // abort if nothing could be created
+ if(!element) return;
+
+ // attributes (or text)
+ if(arguments[1])
+ if(this._isStringOrNumber(arguments[1]) ||
+ (arguments[1] instanceof Array)) {
+ this._children(element, arguments[1]);
+ } else {
+ var attrs = this._attributes(arguments[1]);
+ if(attrs.length) {
+ try { // prevent IE "feature": http://dev.rubyonrails.org/ticket/2707
+ parentElement.innerHTML = "<" +elementName + " " +
+ attrs + "></" + elementName + ">";
+ } catch(e) {}
+ element = parentElement.firstChild || null;
+ // workaround firefox 1.0.X bug
+ if(!element) {
+ element = document.createElement(elementName);
+ for(attr in arguments[1])
+ element[attr == 'class' ? 'className' : attr] = arguments[1][attr];
+ }
+ if(element.tagName != elementName)
+ element = parentElement.getElementsByTagName(elementName)[0];
+ }
+ }
+
+ // text, or array of children
+ if(arguments[2])
+ this._children(element, arguments[2]);
+
+ return element;
+ },
+ _text: function(text) {
+ return document.createTextNode(text);
+ },
+ _attributes: function(attributes) {
+ var attrs = [];
+ for(attribute in attributes)
+ attrs.push((attribute=='className' ? 'class' : attribute) +
+ '="' + attributes[attribute].toString().escapeHTML() + '"');
+ return attrs.join(" ");
+ },
+ _children: function(element, children) {
+ if(typeof children=='object') { // array can hold nodes and text
+ children.flatten().each( function(e) {
+ if(typeof e=='object')
+ element.appendChild(e)
+ else
+ if(Builder._isStringOrNumber(e))
+ element.appendChild(Builder._text(e));
+ });
+ } else
+ if(Builder._isStringOrNumber(children))
+ element.appendChild(Builder._text(children));
+ },
+ _isStringOrNumber: function(param) {
+ return(typeof param=='string' || typeof param=='number');
+ }
+} \ No newline at end of file
diff --git a/site/app/webroot/js/scriptaculous/controls.js b/site/app/webroot/js/scriptaculous/controls.js
new file mode 100644
index 0000000..315aad7
--- /dev/null
+++ b/site/app/webroot/js/scriptaculous/controls.js
@@ -0,0 +1,821 @@
+// Copyright (c) 2005 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
+// (c) 2005 Ivan Krstic (http://blogs.law.harvard.edu/ivan)
+// (c) 2005 Jon Tirsen (http://www.tirsen.com)
+// Contributors:
+// Richard Livsey
+// Rahul Bhargava
+// Rob Wills
+//
+// See scriptaculous.js for full license.
+
+// Autocompleter.Base handles all the autocompletion functionality
+// that's independent of the data source for autocompletion. This
+// includes drawing the autocompletion menu, observing keyboard
+// and mouse events, and similar.
+//
+// Specific autocompleters need to provide, at the very least,
+// a getUpdatedChoices function that will be invoked every time
+// the text inside the monitored textbox changes. This method
+// should get the text for which to provide autocompletion by
+// invoking this.getToken(), NOT by directly accessing
+// this.element.value. This is to allow incremental tokenized
+// autocompletion. Specific auto-completion logic (AJAX, etc)
+// belongs in getUpdatedChoices.
+//
+// Tokenized incremental autocompletion is enabled automatically
+// when an autocompleter is instantiated with the 'tokens' option
+// in the options parameter, e.g.:
+// new Ajax.Autocompleter('id','upd', '/url/', { tokens: ',' });
+// will incrementally autocomplete with a comma as the token.
+// Additionally, ',' in the above example can be replaced with
+// a token array, e.g. { tokens: [',', '\n'] } which
+// enables autocompletion on multiple tokens. This is most
+// useful when one of the tokens is \n (a newline), as it
+// allows smart autocompletion after linebreaks.
+
+if(typeof Effect == 'undefined')
+ throw("controls.js requires including script.aculo.us' effects.js library");
+
+var Autocompleter = {}
+Autocompleter.Base = function() {};
+Autocompleter.Base.prototype = {
+ baseInitialize: function(element, update, options) {
+ this.element = $(element);
+ this.update = $(update);
+ this.hasFocus = false;
+ this.changed = false;
+ this.active = false;
+ this.index = 0;
+ this.entryCount = 0;
+
+ if (this.setOptions)
+ this.setOptions(options);
+ else
+ this.options = options || {};
+
+ this.options.paramName = this.options.paramName || this.element.name;
+ this.options.tokens = this.options.tokens || [];
+ this.options.frequency = this.options.frequency || 0.4;
+ this.options.minChars = this.options.minChars || 1;
+ this.options.onShow = this.options.onShow ||
+ function(element, update){
+ if(!update.style.position || update.style.position=='absolute') {
+ update.style.position = 'absolute';
+ Position.clone(element, update, {setHeight: false, offsetTop: element.offsetHeight});
+ }
+ Effect.Appear(update,{duration:0.15});
+ };
+ this.options.onHide = this.options.onHide ||
+ function(element, update){ new Effect.Fade(update,{duration:0.15}) };
+
+ if (typeof(this.options.tokens) == 'string')
+ this.options.tokens = new Array(this.options.tokens);
+
+ this.observer = null;
+
+ this.element.setAttribute('autocomplete','off');
+
+ Element.hide(this.update);
+
+ Event.observe(this.element, "blur", this.onBlur.bindAsEventListener(this));
+ Event.observe(this.element, "keypress", this.onKeyPress.bindAsEventListener(this));
+ },
+
+ show: function() {
+ if(Element.getStyle(this.update, 'display')=='none') this.options.onShow(this.element, this.update);
+ if(!this.iefix &&
+ (navigator.appVersion.indexOf('MSIE')>0) &&
+ (navigator.userAgent.indexOf('Opera')<0) &&
+ (Element.getStyle(this.update, 'position')=='absolute')) {
+ new Insertion.After(this.update,
+ '<iframe id="' + this.update.id + '_iefix" '+
+ 'style="display:none;position:absolute;filter:progid:DXImageTransform.Microsoft.Alpha(opacity=0);" ' +
+ 'src="javascript:false;" frameborder="0" scrolling="no"></iframe>');
+ this.iefix = $(this.update.id+'_iefix');
+ }
+ if(this.iefix) setTimeout(this.fixIEOverlapping.bind(this), 50);
+ },
+
+ fixIEOverlapping: function() {
+ Position.clone(this.update, this.iefix, {setTop:(!this.update.style.height)});
+ this.iefix.style.zIndex = 1;
+ this.update.style.zIndex = 2;
+ Element.show(this.iefix);
+ },
+
+ hide: function() {
+ this.stopIndicator();
+ if(Element.getStyle(this.update, 'display')!='none') this.options.onHide(this.element, this.update);
+ if(this.iefix) Element.hide(this.iefix);
+ },
+
+ startIndicator: function() {
+ if(this.options.indicator) Element.show(this.options.indicator);
+ },
+
+ stopIndicator: function() {
+ if(this.options.indicator) Element.hide(this.options.indicator);
+ },
+
+ onKeyPress: function(event) {
+ if(this.active)
+ switch(event.keyCode) {
+ case Event.KEY_TAB:
+ case Event.KEY_RETURN:
+ this.selectEntry();
+ Event.stop(event);
+ case Event.KEY_ESC:
+ this.hide();
+ this.active = false;
+ Event.stop(event);
+ return;
+ case Event.KEY_LEFT:
+ case Event.KEY_RIGHT:
+ return;
+ case Event.KEY_UP:
+ this.markPrevious();
+ this.render();
+ if(navigator.appVersion.indexOf('AppleWebKit')>0) Event.stop(event);
+ return;
+ case Event.KEY_DOWN:
+ this.markNext();
+ this.render();
+ if(navigator.appVersion.indexOf('AppleWebKit')>0) Event.stop(event);
+ return;
+ }
+ else
+ if(event.keyCode==Event.KEY_TAB || event.keyCode==Event.KEY_RETURN ||
+ (navigator.appVersion.indexOf('AppleWebKit') > 0 && event.keyCode == 0)) return;
+
+ this.changed = true;
+ this.hasFocus = true;
+
+ if(this.observer) clearTimeout(this.observer);
+ this.observer =
+ setTimeout(this.onObserverEvent.bind(this), this.options.frequency*1000);
+ },
+
+ activate: function() {
+ this.changed = false;
+ this.hasFocus = true;
+ this.getUpdatedChoices();
+ },
+
+ onHover: function(event) {
+ var element = Event.findElement(event, 'LI');
+ if(this.index != element.autocompleteIndex)
+ {
+ this.index = element.autocompleteIndex;
+ this.render();
+ }
+ Event.stop(event);
+ },
+
+ onClick: function(event) {
+ var element = Event.findElement(event, 'LI');
+ this.index = element.autocompleteIndex;
+ this.selectEntry();
+ this.hide();
+ },
+
+ onBlur: function(event) {
+ // needed to make click events working
+ setTimeout(this.hide.bind(this), 250);
+ this.hasFocus = false;
+ this.active = false;
+ },
+
+ render: function() {
+ if(this.entryCount > 0) {
+ for (var i = 0; i < this.entryCount; i++)
+ this.index==i ?
+ Element.addClassName(this.getEntry(i),"selected") :
+ Element.removeClassName(this.getEntry(i),"selected");
+
+ if(this.hasFocus) {
+ this.show();
+ this.active = true;
+ }
+ } else {
+ this.active = false;
+ this.hide();
+ }
+ },
+
+ markPrevious: function() {
+ if(this.index > 0) this.index--
+ else this.index = this.entryCount-1;
+ this.getEntry(this.index).scrollIntoView(true);
+ },
+
+ markNext: function() {
+ if(this.index < this.entryCount-1) this.index++
+ else this.index = 0;
+ this.getEntry(this.index).scrollIntoView(false);
+ },
+
+ getEntry: function(index) {
+ return this.update.firstChild.childNodes[index];
+ },
+
+ getCurrentEntry: function() {
+ return this.getEntry(this.index);
+ },
+
+ selectEntry: function() {
+ this.active = false;
+ this.updateElement(this.getCurrentEntry());
+ },
+
+ updateElement: function(selectedElement) {
+ if (this.options.updateElement) {
+ this.options.updateElement(selectedElement);
+ return;
+ }
+ var value = '';
+ if (this.options.select) {
+ var nodes = document.getElementsByClassName(this.options.select, selectedElement) || [];
+ if(nodes.length>0) value = Element.collectTextNodes(nodes[0], this.options.select);
+ } else
+ value = Element.collectTextNodesIgnoreClass(selectedElement, 'informal');
+
+ var lastTokenPos = this.findLastToken();
+ if (lastTokenPos != -1) {
+ var newValue = this.element.value.substr(0, lastTokenPos + 1);
+ var whitespace = this.element.value.substr(lastTokenPos + 1).match(/^\s+/);
+ if (whitespace)
+ newValue += whitespace[0];
+ this.element.value = newValue + value;
+ } else {
+ this.element.value = value;
+ }
+ this.element.focus();
+
+ if (this.options.afterUpdateElement)
+ this.options.afterUpdateElement(this.element, selectedElement);
+ },
+
+ updateChoices: function(choices) {
+ if(!this.changed && this.hasFocus) {
+ this.update.innerHTML = choices;
+ Element.cleanWhitespace(this.update);
+ Element.cleanWhitespace(this.update.firstChild);
+
+ if(this.update.firstChild && this.update.firstChild.childNodes) {
+ this.entryCount =
+ this.update.firstChild.childNodes.length;
+ for (var i = 0; i < this.entryCount; i++) {
+ var entry = this.getEntry(i);
+ entry.autocompleteIndex = i;
+ this.addObservers(entry);
+ }
+ } else {
+ this.entryCount = 0;
+ }
+
+ this.stopIndicator();
+
+ this.index = 0;
+ this.render();
+ }
+ },
+
+ addObservers: function(element) {
+ Event.observe(element, "mouseover", this.onHover.bindAsEventListener(this));
+ Event.observe(element, "click", this.onClick.bindAsEventListener(this));
+ },
+
+ onObserverEvent: function() {
+ this.changed = false;
+ if(this.getToken().length>=this.options.minChars) {
+ this.startIndicator();
+ this.getUpdatedChoices();
+ } else {
+ this.active = false;
+ this.hide();
+ }
+ },
+
+ getToken: function() {
+ var tokenPos = this.findLastToken();
+ if (tokenPos != -1)
+ var ret = this.element.value.substr(tokenPos + 1).replace(/^\s+/,'').replace(/\s+$/,'');
+ else
+ var ret = this.element.value;
+
+ return /\n/.test(ret) ? '' : ret;
+ },
+
+ findLastToken: function() {
+ var lastTokenPos = -1;
+
+ for (var i=0; i<this.options.tokens.length; i++) {
+ var thisTokenPos = this.element.value.lastIndexOf(this.options.tokens[i]);
+ if (thisTokenPos > lastTokenPos)
+ lastTokenPos = thisTokenPos;
+ }
+ return lastTokenPos;
+ }
+}
+
+Ajax.Autocompleter = Class.create();
+Object.extend(Object.extend(Ajax.Autocompleter.prototype, Autocompleter.Base.prototype), {
+ initialize: function(element, update, url, options) {
+ this.baseInitialize(element, update, options);
+ this.options.asynchronous = true;
+ this.options.onComplete = this.onComplete.bind(this);
+ this.options.defaultParams = this.options.parameters || null;
+ this.url = url;
+ },
+
+ getUpdatedChoices: function() {
+ entry = encodeURIComponent(this.options.paramName) + '=' +
+ encodeURIComponent(this.getToken());
+
+ this.options.parameters = this.options.callback ?
+ this.options.callback(this.element, entry) : entry;
+
+ if(this.options.defaultParams)
+ this.options.parameters += '&' + this.options.defaultParams;
+
+ new Ajax.Request(this.url, this.options);
+ },
+
+ onComplete: function(request) {
+ this.updateChoices(request.responseText);
+ }
+
+});
+
+// The local array autocompleter. Used when you'd prefer to
+// inject an array of autocompletion options into the page, rather
+// than sending out Ajax queries, which can be quite slow sometimes.
+//
+// The constructor takes four parameters. The first two are, as usual,
+// the id of the monitored textbox, and id of the autocompletion menu.
+// The third is the array you want to autocomplete from, and the fourth
+// is the options block.
+//
+// Extra local autocompletion options:
+// - choices - How many autocompletion choices to offer
+//
+// - partialSearch - If false, the autocompleter will match entered
+// text only at the beginning of strings in the
+// autocomplete array. Defaults to true, which will
+// match text at the beginning of any *word* in the
+// strings in the autocomplete array. If you want to
+// search anywhere in the string, additionally set
+// the option fullSearch to true (default: off).
+//
+// - fullSsearch - Search anywhere in autocomplete array strings.
+//
+// - partialChars - How many characters to enter before triggering
+// a partial match (unlike minChars, which defines
+// how many characters are required to do any match
+// at all). Defaults to 2.
+//
+// - ignoreCase - Whether to ignore case when autocompleting.
+// Defaults to true.
+//
+// It's possible to pass in a custom function as the 'selector'
+// option, if you prefer to write your own autocompletion logic.
+// In that case, the other options above will not apply unless
+// you support them.
+
+Autocompleter.Local = Class.create();
+Autocompleter.Local.prototype = Object.extend(new Autocompleter.Base(), {
+ initialize: function(element, update, array, options) {
+ this.baseInitialize(element, update, options);
+ this.options.array = array;
+ },
+
+ getUpdatedChoices: function() {
+ this.updateChoices(this.options.selector(this));
+ },
+
+ setOptions: function(options) {
+ this.options = Object.extend({
+ choices: 10,
+ partialSearch: true,
+ partialChars: 2,
+ ignoreCase: true,
+ fullSearch: false,
+ selector: function(instance) {
+ var ret = []; // Beginning matches
+ var partial = []; // Inside matches
+ var entry = instance.getToken();
+ var count = 0;
+
+ for (var i = 0; i < instance.options.array.length &&
+ ret.length < instance.options.choices ; i++) {
+
+ var elem = instance.options.array[i];
+ var foundPos = instance.options.ignoreCase ?
+ elem.toLowerCase().indexOf(entry.toLowerCase()) :
+ elem.indexOf(entry);
+
+ while (foundPos != -1) {
+ if (foundPos == 0 && elem.length != entry.length) {
+ ret.push("<li><strong>" + elem.substr(0, entry.length) + "</strong>" +
+ elem.substr(entry.length) + "</li>");
+ break;
+ } else if (entry.length >= instance.options.partialChars &&
+ instance.options.partialSearch && foundPos != -1) {
+ if (instance.options.fullSearch || /\s/.test(elem.substr(foundPos-1,1))) {
+ partial.push("<li>" + elem.substr(0, foundPos) + "<strong>" +
+ elem.substr(foundPos, entry.length) + "</strong>" + elem.substr(
+ foundPos + entry.length) + "</li>");
+ break;
+ }
+ }
+
+ foundPos = instance.options.ignoreCase ?
+ elem.toLowerCase().indexOf(entry.toLowerCase(), foundPos + 1) :
+ elem.indexOf(entry, foundPos + 1);
+
+ }
+ }
+ if (partial.length)
+ ret = ret.concat(partial.slice(0, instance.options.choices - ret.length))
+ return "<ul>" + ret.join('') + "</ul>";
+ }
+ }, options || {});
+ }
+});
+
+// AJAX in-place editor
+//
+// see documentation on http://wiki.script.aculo.us/scriptaculous/show/Ajax.InPlaceEditor
+
+// Use this if you notice weird scrolling problems on some browsers,
+// the DOM might be a bit confused when this gets called so do this
+// waits 1 ms (with setTimeout) until it does the activation
+Field.scrollFreeActivate = function(field) {
+ setTimeout(function() {
+ Field.activate(field);
+ }, 1);
+}
+
+Ajax.InPlaceEditor = Class.create();
+Ajax.InPlaceEditor.defaultHighlightColor = "#FFFF99";
+Ajax.InPlaceEditor.prototype = {
+ initialize: function(element, url, options) {
+ this.url = url;
+ this.element = $(element);
+
+ this.options = Object.extend({
+ okButton: true,
+ okText: "ok",
+ cancelLink: true,
+ cancelText: "cancel",
+ savingText: "Saving...",
+ clickToEditText: "Click to edit",
+ okText: "ok",
+ rows: 1,
+ onComplete: function(transport, element) {
+ new Effect.Highlight(element, {startcolor: this.options.highlightcolor});
+ },
+ onFailure: function(transport) {
+ alert("Error communicating with the server: " + transport.responseText.stripTags());
+ },
+ callback: function(form) {
+ return Form.serialize(form);
+ },
+ handleLineBreaks: true,
+ loadingText: 'Loading...',
+ savingClassName: 'inplaceeditor-saving',
+ loadingClassName: 'inplaceeditor-loading',
+ formClassName: 'inplaceeditor-form',
+ highlightcolor: Ajax.InPlaceEditor.defaultHighlightColor,
+ highlightendcolor: "#FFFFFF",
+ externalControl: null,
+ submitOnBlur: false,
+ ajaxOptions: {},
+ evalScripts: false
+ }, options || {});
+
+ if(!this.options.formId && this.element.id) {
+ this.options.formId = this.element.id + "-inplaceeditor";
+ if ($(this.options.formId)) {
+ // there's already a form with that name, don't specify an id
+ this.options.formId = null;
+ }
+ }
+
+ if (this.options.externalControl) {
+ this.options.externalControl = $(this.options.externalControl);
+ }
+
+ this.originalBackground = Element.getStyle(this.element, 'background-color');
+ if (!this.originalBackground) {
+ this.originalBackground = "transparent";
+ }
+
+ this.element.title = this.options.clickToEditText;
+
+ this.onclickListener = this.enterEditMode.bindAsEventListener(this);
+ this.mouseoverListener = this.enterHover.bindAsEventListener(this);
+ this.mouseoutListener = this.leaveHover.bindAsEventListener(this);
+ Event.observe(this.element, 'click', this.onclickListener);
+ Event.observe(this.element, 'mouseover', this.mouseoverListener);
+ Event.observe(this.element, 'mouseout', this.mouseoutListener);
+ if (this.options.externalControl) {
+ Event.observe(this.options.externalControl, 'click', this.onclickListener);
+ Event.observe(this.options.externalControl, 'mouseover', this.mouseoverListener);
+ Event.observe(this.options.externalControl, 'mouseout', this.mouseoutListener);
+ }
+ },
+ enterEditMode: function(evt) {
+ if (this.saving) return;
+ if (this.editing) return;
+ this.editing = true;
+ this.onEnterEditMode();
+ if (this.options.externalControl) {
+ Element.hide(this.options.externalControl);
+ }
+ Element.hide(this.element);
+ this.createForm();
+ this.element.parentNode.insertBefore(this.form, this.element);
+ if (!this.options.loadTextURL) Field.scrollFreeActivate(this.editField);
+ // stop the event to avoid a page refresh in Safari
+ if (evt) {
+ Event.stop(evt);
+ }
+ return false;
+ },
+ createForm: function() {
+ this.form = document.createElement("form");
+ this.form.id = this.options.formId;
+ Element.addClassName(this.form, this.options.formClassName)
+ this.form.onsubmit = this.onSubmit.bind(this);
+
+ this.createEditField();
+
+ if (this.options.textarea) {
+ var br = document.createElement("br");
+ this.form.appendChild(br);
+ }
+
+ if (this.options.okButton) {
+ okButton = document.createElement("input");
+ okButton.type = "submit";
+ okButton.value = this.options.okText;
+ okButton.className = 'editor_ok_button';
+ this.form.appendChild(okButton);
+ }
+
+ if (this.options.cancelLink) {
+ cancelLink = document.createElement("a");
+ cancelLink.href = "#";
+ cancelLink.appendChild(document.createTextNode(this.options.cancelText));
+ cancelLink.onclick = this.onclickCancel.bind(this);
+ cancelLink.className = 'editor_cancel';
+ this.form.appendChild(cancelLink);
+ }
+ },
+ hasHTMLLineBreaks: function(string) {
+ if (!this.options.handleLineBreaks) return false;
+ return string.match(/<br/i) || string.match(/<p>/i);
+ },
+ convertHTMLLineBreaks: function(string) {
+ return string.replace(/<br>/gi, "\n").replace(/<br\/>/gi, "\n").replace(/<\/p>/gi, "\n").replace(/<p>/gi, "");
+ },
+ createEditField: function() {
+ var text;
+ if(this.options.loadTextURL) {
+ text = this.options.loadingText;
+ } else {
+ text = this.getText();
+ }
+
+ var obj = this;
+
+ if (this.options.rows == 1 && !this.hasHTMLLineBreaks(text)) {
+ this.options.textarea = false;
+ var textField = document.createElement("input");
+ textField.obj = this;
+ textField.type = "text";
+ textField.name = "value";
+ textField.value = text;
+ textField.style.backgroundColor = this.options.highlightcolor;
+ textField.className = 'editor_field';
+ var size = this.options.size || this.options.cols || 0;
+ if (size != 0) textField.size = size;
+ if (this.options.submitOnBlur)
+ textField.onblur = this.onSubmit.bind(this);
+ this.editField = textField;
+ } else {
+ this.options.textarea = true;
+ var textArea = document.createElement("textarea");
+ textArea.obj = this;
+ textArea.name = "value";
+ textArea.value = this.convertHTMLLineBreaks(text);
+ textArea.rows = this.options.rows;
+ textArea.cols = this.options.cols || 40;
+ textArea.className = 'editor_field';
+ if (this.options.submitOnBlur)
+ textArea.onblur = this.onSubmit.bind(this);
+ this.editField = textArea;
+ }
+
+ if(this.options.loadTextURL) {
+ this.loadExternalText();
+ }
+ this.form.appendChild(this.editField);
+ },
+ getText: function() {
+ return this.element.innerHTML;
+ },
+ loadExternalText: function() {
+ Element.addClassName(this.form, this.options.loadingClassName);
+ this.editField.disabled = true;
+ new Ajax.Request(
+ this.options.loadTextURL,
+ Object.extend({
+ asynchronous: true,
+ onComplete: this.onLoadedExternalText.bind(this)
+ }, this.options.ajaxOptions)
+ );
+ },
+ onLoadedExternalText: function(transport) {
+ Element.removeClassName(this.form, this.options.loadingClassName);
+ this.editField.disabled = false;
+ this.editField.value = transport.responseText.stripTags();
+ Field.scrollFreeActivate(this.editField);
+ },
+ onclickCancel: function() {
+ this.onComplete();
+ this.leaveEditMode();
+ return false;
+ },
+ onFailure: function(transport) {
+ this.options.onFailure(transport);
+ if (this.oldInnerHTML) {
+ this.element.innerHTML = this.oldInnerHTML;
+ this.oldInnerHTML = null;
+ }
+ return false;
+ },
+ onSubmit: function() {
+ // onLoading resets these so we need to save them away for the Ajax call
+ var form = this.form;
+ var value = this.editField.value;
+
+ // do this first, sometimes the ajax call returns before we get a chance to switch on Saving...
+ // which means this will actually switch on Saving... *after* we've left edit mode causing Saving...
+ // to be displayed indefinitely
+ this.onLoading();
+
+ if (this.options.evalScripts) {
+ new Ajax.Request(
+ this.url, Object.extend({
+ parameters: this.options.callback(form, value),
+ onComplete: this.onComplete.bind(this),
+ onFailure: this.onFailure.bind(this),
+ asynchronous:true,
+ evalScripts:true
+ }, this.options.ajaxOptions));
+ } else {
+ new Ajax.Updater(
+ { success: this.element,
+ // don't update on failure (this could be an option)
+ failure: null },
+ this.url, Object.extend({
+ parameters: this.options.callback(form, value),
+ onComplete: this.onComplete.bind(this),
+ onFailure: this.onFailure.bind(this)
+ }, this.options.ajaxOptions));
+ }
+ // stop the event to avoid a page refresh in Safari
+ if (arguments.length > 1) {
+ Event.stop(arguments[0]);
+ }
+ return false;
+ },
+ onLoading: function() {
+ this.saving = true;
+ this.removeForm();
+ this.leaveHover();
+ this.showSaving();
+ },
+ showSaving: function() {
+ this.oldInnerHTML = this.element.innerHTML;
+ this.element.innerHTML = this.options.savingText;
+ Element.addClassName(this.element, this.options.savingClassName);
+ this.element.style.backgroundColor = this.originalBackground;
+ Element.show(this.element);
+ },
+ removeForm: function() {
+ if(this.form) {
+ if (this.form.parentNode) Element.remove(this.form);
+ this.form = null;
+ }
+ },
+ enterHover: function() {
+ if (this.saving) return;
+ this.element.style.backgroundColor = this.options.highlightcolor;
+ if (this.effect) {
+ this.effect.cancel();
+ }
+ Element.addClassName(this.element, this.options.hoverClassName)
+ },
+ leaveHover: function() {
+ if (this.options.backgroundColor) {
+ this.element.style.backgroundColor = this.oldBackground;
+ }
+ Element.removeClassName(this.element, this.options.hoverClassName)
+ if (this.saving) return;
+ this.effect = new Effect.Highlight(this.element, {
+ startcolor: this.options.highlightcolor,
+ endcolor: this.options.highlightendcolor,
+ restorecolor: this.originalBackground
+ });
+ },
+ leaveEditMode: function() {
+ Element.removeClassName(this.element, this.options.savingClassName);
+ this.removeForm();
+ this.leaveHover();
+ this.element.style.backgroundColor = this.originalBackground;
+ Element.show(this.element);
+ if (this.options.externalControl) {
+ Element.show(this.options.externalControl);
+ }
+ this.editing = false;
+ this.saving = false;
+ this.oldInnerHTML = null;
+ this.onLeaveEditMode();
+ },
+ onComplete: function(transport) {
+ this.leaveEditMode();
+ this.options.onComplete.bind(this)(transport, this.element);
+ },
+ onEnterEditMode: function() {},
+ onLeaveEditMode: function() {},
+ dispose: function() {
+ if (this.oldInnerHTML) {
+ this.element.innerHTML = this.oldInnerHTML;
+ }
+ this.leaveEditMode();
+ Event.stopObserving(this.element, 'click', this.onclickListener);
+ Event.stopObserving(this.element, 'mouseover', this.mouseoverListener);
+ Event.stopObserving(this.element, 'mouseout', this.mouseoutListener);
+ if (this.options.externalControl) {
+ Event.stopObserving(this.options.externalControl, 'click', this.onclickListener);
+ Event.stopObserving(this.options.externalControl, 'mouseover', this.mouseoverListener);
+ Event.stopObserving(this.options.externalControl, 'mouseout', this.mouseoutListener);
+ }
+ }
+};
+
+Ajax.InPlaceCollectionEditor = Class.create();
+Object.extend(Ajax.InPlaceCollectionEditor.prototype, Ajax.InPlaceEditor.prototype);
+Object.extend(Ajax.InPlaceCollectionEditor.prototype, {
+ createEditField: function() {
+ if (!this.cached_selectTag) {
+ var selectTag = document.createElement("select");
+ var collection = this.options.collection || [];
+ var optionTag;
+ collection.each(function(e,i) {
+ optionTag = document.createElement("option");
+ optionTag.value = (e instanceof Array) ? e[0] : e;
+ if(this.options.value==optionTag.value) optionTag.selected = true;
+ optionTag.appendChild(document.createTextNode((e instanceof Array) ? e[1] : e));
+ selectTag.appendChild(optionTag);
+ }.bind(this));
+ this.cached_selectTag = selectTag;
+ }
+
+ this.editField = this.cached_selectTag;
+ if(this.options.loadTextURL) this.loadExternalText();
+ this.form.appendChild(this.editField);
+ this.options.callback = function(form, value) {
+ return "value=" + encodeURIComponent(value);
+ }
+ }
+});
+
+// Delayed observer, like Form.Element.Observer,
+// but waits for delay after last key input
+// Ideal for live-search fields
+
+Form.Element.DelayedObserver = Class.create();
+Form.Element.DelayedObserver.prototype = {
+ initialize: function(element, delay, callback) {
+ this.delay = delay || 0.5;
+ this.element = $(element);
+ this.callback = callback;
+ this.timer = null;
+ this.lastValue = $F(this.element);
+ Event.observe(this.element,'keyup',this.delayedListener.bindAsEventListener(this));
+ },
+ delayedListener: function(event) {
+ if(this.lastValue == $F(this.element)) return;
+ if(this.timer) clearTimeout(this.timer);
+ this.timer = setTimeout(this.onTimerEvent.bind(this), this.delay * 1000);
+ this.lastValue = $F(this.element);
+ },
+ onTimerEvent: function() {
+ this.timer = null;
+ this.callback(this.element, $F(this.element));
+ }
+};
diff --git a/site/app/webroot/js/scriptaculous/dragdrop.js b/site/app/webroot/js/scriptaculous/dragdrop.js
new file mode 100644
index 0000000..1528ece
--- /dev/null
+++ b/site/app/webroot/js/scriptaculous/dragdrop.js
@@ -0,0 +1,931 @@
+// Copyright (c) 2005 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
+// (c) 2005 Sammi Williams (http://www.oriontransfer.co.nz, sammi@oriontransfer.co.nz)
+//
+// See scriptaculous.js for full license.
+
+/*--------------------------------------------------------------------------*/
+
+if(typeof Effect == 'undefined')
+ throw("dragdrop.js requires including script.aculo.us' effects.js library");
+
+var Droppables = {
+ drops: [],
+
+ remove: function(element) {
+ this.drops = this.drops.reject(function(d) { return d.element==$(element) });
+ },
+
+ add: function(element) {
+ element = $(element);
+ var options = Object.extend({
+ greedy: true,
+ hoverclass: null,
+ tree: false
+ }, arguments[1] || {});
+
+ // cache containers
+ if(options.containment) {
+ options._containers = [];
+ var containment = options.containment;
+ if((typeof containment == 'object') &&
+ (containment.constructor == Array)) {
+ containment.each( function(c) { options._containers.push($(c)) });
+ } else {
+ options._containers.push($(containment));
+ }
+ }
+
+ if(options.accept) options.accept = [options.accept].flatten();
+
+ Element.makePositioned(element); // fix IE
+ options.element = element;
+
+ this.drops.push(options);
+ },
+
+ findDeepestChild: function(drops) {
+ deepest = drops[0];
+
+ for (i = 1; i < drops.length; ++i)
+ if (Element.isParent(drops[i].element, deepest.element))
+ deepest = drops[i];
+
+ return deepest;
+ },
+
+ isContained: function(element, drop) {
+ var containmentNode;
+ if(drop.tree) {
+ containmentNode = element.treeNode;
+ } else {
+ containmentNode = element.parentNode;
+ }
+ return drop._containers.detect(function(c) { return containmentNode == c });
+ },
+
+ isAffected: function(point, element, drop) {
+ return (
+ (drop.element!=element) &&
+ ((!drop._containers) ||
+ this.isContained(element, drop)) &&
+ ((!drop.accept) ||
+ (Element.classNames(element).detect(
+ function(v) { return drop.accept.include(v) } ) )) &&
+ Position.within(drop.element, point[0], point[1]) );
+ },
+
+ deactivate: function(drop) {
+ if(drop.hoverclass)
+ Element.removeClassName(drop.element, drop.hoverclass);
+ this.last_active = null;
+ },
+
+ activate: function(drop) {
+ if(drop.hoverclass)
+ Element.addClassName(drop.element, drop.hoverclass);
+ this.last_active = drop;
+ },
+
+ show: function(point, element) {
+ if(!this.drops.length) return;
+ var affected = [];
+
+ if(this.last_active) this.deactivate(this.last_active);
+ this.drops.each( function(drop) {
+ if(Droppables.isAffected(point, element, drop))
+ affected.push(drop);
+ });
+
+ if(affected.length>0) {
+ drop = Droppables.findDeepestChild(affected);
+ Position.within(drop.element, point[0], point[1]);
+ if(drop.onHover)
+ drop.onHover(element, drop.element, Position.overlap(drop.overlap, drop.element));
+
+ Droppables.activate(drop);
+ }
+ },
+
+ fire: function(event, element) {
+ if(!this.last_active) return;
+ Position.prepare();
+
+ if (this.isAffected([Event.pointerX(event), Event.pointerY(event)], element, this.last_active))
+ if (this.last_active.onDrop)
+ this.last_active.onDrop(element, this.last_active.element, event);
+ },
+
+ reset: function() {
+ if(this.last_active)
+ this.deactivate(this.last_active);
+ }
+}
+
+var Draggables = {
+ drags: [],
+ observers: [],
+
+ register: function(draggable) {
+ if(this.drags.length == 0) {
+ this.eventMouseUp = this.endDrag.bindAsEventListener(this);
+ this.eventMouseMove = this.updateDrag.bindAsEventListener(this);
+ this.eventKeypress = this.keyPress.bindAsEventListener(this);
+
+ Event.observe(document, "mouseup", this.eventMouseUp);
+ Event.observe(document, "mousemove", this.eventMouseMove);
+ Event.observe(document, "keypress", this.eventKeypress);
+ }
+ this.drags.push(draggable);
+ },
+
+ unregister: function(draggable) {
+ this.drags = this.drags.reject(function(d) { return d==draggable });
+ if(this.drags.length == 0) {
+ Event.stopObserving(document, "mouseup", this.eventMouseUp);
+ Event.stopObserving(document, "mousemove", this.eventMouseMove);
+ Event.stopObserving(document, "keypress", this.eventKeypress);
+ }
+ },
+
+ activate: function(draggable) {
+ window.focus(); // allows keypress events if window isn't currently focused, fails for Safari
+ this.activeDraggable = draggable;
+ },
+
+ deactivate: function() {
+ this.activeDraggable = null;
+ },
+
+ updateDrag: function(event) {
+ if(!this.activeDraggable) return;
+ var pointer = [Event.pointerX(event), Event.pointerY(event)];
+ // Mozilla-based browsers fire successive mousemove events with
+ // the same coordinates, prevent needless redrawing (moz bug?)
+ if(this._lastPointer && (this._lastPointer.inspect() == pointer.inspect())) return;
+ this._lastPointer = pointer;
+ this.activeDraggable.updateDrag(event, pointer);
+ },
+
+ endDrag: function(event) {
+ if(!this.activeDraggable) return;
+ this._lastPointer = null;
+ this.activeDraggable.endDrag(event);
+ this.activeDraggable = null;
+ },
+
+ keyPress: function(event) {
+ if(this.activeDraggable)
+ this.activeDraggable.keyPress(event);
+ },
+
+ addObserver: function(observer) {
+ this.observers.push(observer);
+ this._cacheObserverCallbacks();
+ },
+
+ removeObserver: function(element) { // element instead of observer fixes mem leaks
+ this.observers = this.observers.reject( function(o) { return o.element==element });
+ this._cacheObserverCallbacks();
+ },
+
+ notify: function(eventName, draggable, event) { // 'onStart', 'onEnd', 'onDrag'
+ if(this[eventName+'Count'] > 0)
+ this.observers.each( function(o) {
+ if(o[eventName]) o[eventName](eventName, draggable, event);
+ });
+ },
+
+ _cacheObserverCallbacks: function() {
+ ['onStart','onEnd','onDrag'].each( function(eventName) {
+ Draggables[eventName+'Count'] = Draggables.observers.select(
+ function(o) { return o[eventName]; }
+ ).length;
+ });
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+var Draggable = Class.create();
+Draggable._revertCache = {};
+Draggable._dragging = {};
+
+Draggable.prototype = {
+ initialize: function(element) {
+ var options = Object.extend({
+ handle: false,
+ starteffect: function(element) {
+ element._opacity = Element.getOpacity(element);
+ Draggable._dragging[element] = true;
+ new Effect.Opacity(element, {duration:0.2, from:element._opacity, to:0.7});
+ },
+ reverteffect: function(element, top_offset, left_offset) {
+ var dur = Math.sqrt(Math.abs(top_offset^2)+Math.abs(left_offset^2))*0.02;
+ Draggable._revertCache[element] =
+ new Effect.Move(element, { x: -left_offset, y: -top_offset, duration: dur,
+ queue: {scope:'_draggable', position:'end'}
+ });
+ },
+ endeffect: function(element) {
+ var toOpacity = typeof element._opacity == 'number' ? element._opacity : 1.0;
+ new Effect.Opacity(element, {duration:0.2, from:0.7, to:toOpacity,
+ queue: {scope:'_draggable', position:'end'},
+ afterFinish: function(){ Draggable._dragging[element] = false }
+ });
+ },
+ zindex: 1000,
+ revert: false,
+ scroll: false,
+ scrollSensitivity: 20,
+ scrollSpeed: 15,
+ snap: false // false, or xy or [x,y] or function(x,y){ return [x,y] }
+ }, arguments[1] || {});
+
+ this.element = $(element);
+
+ if(options.handle && (typeof options.handle == 'string')) {
+ var h = Element.childrenWithClassName(this.element, options.handle, true);
+ if(h.length>0) this.handle = h[0];
+ }
+ if(!this.handle) this.handle = $(options.handle);
+ if(!this.handle) this.handle = this.element;
+
+ if(options.scroll && !options.scroll.scrollTo && !options.scroll.outerHTML)
+ options.scroll = $(options.scroll);
+
+ Element.makePositioned(this.element); // fix IE
+
+ this.delta = this.currentDelta();
+ this.options = options;
+ this.dragging = false;
+
+ this.eventMouseDown = this.initDrag.bindAsEventListener(this);
+ Event.observe(this.handle, "mousedown", this.eventMouseDown);
+
+ Draggables.register(this);
+ },
+
+ destroy: function() {
+ Event.stopObserving(this.handle, "mousedown", this.eventMouseDown);
+ Draggables.unregister(this);
+ },
+
+ currentDelta: function() {
+ return([
+ parseInt(Element.getStyle(this.element,'left') || '0'),
+ parseInt(Element.getStyle(this.element,'top') || '0')]);
+ },
+
+ initDrag: function(event) {
+ if(typeof Draggable._dragging[this.element] != undefined &&
+ Draggable._dragging[this.element]) return;
+ if(Event.isLeftClick(event)) {
+ // abort on form elements, fixes a Firefox issue
+ var src = Event.element(event);
+ if(src.tagName && (
+ src.tagName=='INPUT' ||
+ src.tagName=='SELECT' ||
+ src.tagName=='OPTION' ||
+ src.tagName=='BUTTON' ||
+ src.tagName=='TEXTAREA')) return;
+
+ if(Draggable._revertCache[this.element]) {
+ Draggable._revertCache[this.element].cancel();
+ Draggable._revertCache[this.element] = null;
+ }
+
+ var pointer = [Event.pointerX(event), Event.pointerY(event)];
+ var pos = Position.cumulativeOffset(this.element);
+ this.offset = [0,1].map( function(i) { return (pointer[i] - pos[i]) });
+
+ Draggables.activate(this);
+ Event.stop(event);
+ }
+ },
+
+ startDrag: function(event) {
+ this.dragging = true;
+
+ if(this.options.zindex) {
+ this.originalZ = parseInt(Element.getStyle(this.element,'z-index') || 0);
+ this.element.style.zIndex = this.options.zindex;
+ }
+
+ if(this.options.ghosting) {
+ this._clone = this.element.cloneNode(true);
+ Position.absolutize(this.element);
+ this.element.parentNode.insertBefore(this._clone, this.element);
+ }
+
+ if(this.options.scroll) {
+ if (this.options.scroll == window) {
+ var where = this._getWindowScroll(this.options.scroll);
+ this.originalScrollLeft = where.left;
+ this.originalScrollTop = where.top;
+ } else {
+ this.originalScrollLeft = this.options.scroll.scrollLeft;
+ this.originalScrollTop = this.options.scroll.scrollTop;
+ }
+ }
+
+ Draggables.notify('onStart', this, event);
+ if(this.options.starteffect) this.options.starteffect(this.element);
+ },
+
+ updateDrag: function(event, pointer) {
+ if(!this.dragging) this.startDrag(event);
+ Position.prepare();
+ Droppables.show(pointer, this.element);
+ Draggables.notify('onDrag', this, event);
+ this.draw(pointer);
+ if(this.options.change) this.options.change(this);
+
+ if(this.options.scroll) {
+ this.stopScrolling();
+
+ var p;
+ if (this.options.scroll == window) {
+ with(this._getWindowScroll(this.options.scroll)) { p = [ left, top, left+width, top+height ]; }
+ } else {
+ p = Position.page(this.options.scroll);
+ p[0] += this.options.scroll.scrollLeft;
+ p[1] += this.options.scroll.scrollTop;
+ p.push(p[0]+this.options.scroll.offsetWidth);
+ p.push(p[1]+this.options.scroll.offsetHeight);
+ }
+ var speed = [0,0];
+ if(pointer[0] < (p[0]+this.options.scrollSensitivity)) speed[0] = pointer[0]-(p[0]+this.options.scrollSensitivity);
+ if(pointer[1] < (p[1]+this.options.scrollSensitivity)) speed[1] = pointer[1]-(p[1]+this.options.scrollSensitivity);
+ if(pointer[0] > (p[2]-this.options.scrollSensitivity)) speed[0] = pointer[0]-(p[2]-this.options.scrollSensitivity);
+ if(pointer[1] > (p[3]-this.options.scrollSensitivity)) speed[1] = pointer[1]-(p[3]-this.options.scrollSensitivity);
+ this.startScrolling(speed);
+ }
+
+ // fix AppleWebKit rendering
+ if(navigator.appVersion.indexOf('AppleWebKit')>0) window.scrollBy(0,0);
+
+ Event.stop(event);
+ },
+
+ finishDrag: function(event, success) {
+ this.dragging = false;
+
+ if(this.options.ghosting) {
+ Position.relativize(this.element);
+ Element.remove(this._clone);
+ this._clone = null;
+ }
+
+ if(success) Droppables.fire(event, this.element);
+ Draggables.notify('onEnd', this, event);
+
+ var revert = this.options.revert;
+ if(revert && typeof revert == 'function') revert = revert(this.element);
+
+ var d = this.currentDelta();
+ if(revert && this.options.reverteffect) {
+ this.options.reverteffect(this.element,
+ d[1]-this.delta[1], d[0]-this.delta[0]);
+ } else {
+ this.delta = d;
+ }
+
+ if(this.options.zindex)
+ this.element.style.zIndex = this.originalZ;
+
+ if(this.options.endeffect)
+ this.options.endeffect(this.element);
+
+ Draggables.deactivate(this);
+ Droppables.reset();
+ },
+
+ keyPress: function(event) {
+ if(event.keyCode!=Event.KEY_ESC) return;
+ this.finishDrag(event, false);
+ Event.stop(event);
+ },
+
+ endDrag: function(event) {
+ if(!this.dragging) return;
+ this.stopScrolling();
+ this.finishDrag(event, true);
+ Event.stop(event);
+ },
+
+ draw: function(point) {
+ var pos = Position.cumulativeOffset(this.element);
+ var d = this.currentDelta();
+ pos[0] -= d[0]; pos[1] -= d[1];
+
+ if(this.options.scroll && (this.options.scroll != window)) {
+ pos[0] -= this.options.scroll.scrollLeft-this.originalScrollLeft;
+ pos[1] -= this.options.scroll.scrollTop-this.originalScrollTop;
+ }
+
+ var p = [0,1].map(function(i){
+ return (point[i]-pos[i]-this.offset[i])
+ }.bind(this));
+
+ if(this.options.snap) {
+ if(typeof this.options.snap == 'function') {
+ p = this.options.snap(p[0],p[1],this);
+ } else {
+ if(this.options.snap instanceof Array) {
+ p = p.map( function(v, i) {
+ return Math.round(v/this.options.snap[i])*this.options.snap[i] }.bind(this))
+ } else {
+ p = p.map( function(v) {
+ return Math.round(v/this.options.snap)*this.options.snap }.bind(this))
+ }
+ }}
+
+ var style = this.element.style;
+ if((!this.options.constraint) || (this.options.constraint=='horizontal'))
+ style.left = p[0] + "px";
+ if((!this.options.constraint) || (this.options.constraint=='vertical'))
+ style.top = p[1] + "px";
+ if(style.visibility=="hidden") style.visibility = ""; // fix gecko rendering
+ },
+
+ stopScrolling: function() {
+ if(this.scrollInterval) {
+ clearInterval(this.scrollInterval);
+ this.scrollInterval = null;
+ Draggables._lastScrollPointer = null;
+ }
+ },
+
+ startScrolling: function(speed) {
+ if(!(speed[0] || speed[1])) return;
+ this.scrollSpeed = [speed[0]*this.options.scrollSpeed,speed[1]*this.options.scrollSpeed];
+ this.lastScrolled = new Date();
+ this.scrollInterval = setInterval(this.scroll.bind(this), 10);
+ },
+
+ scroll: function() {
+ var current = new Date();
+ var delta = current - this.lastScrolled;
+ this.lastScrolled = current;
+ if(this.options.scroll == window) {
+ with (this._getWindowScroll(this.options.scroll)) {
+ if (this.scrollSpeed[0] || this.scrollSpeed[1]) {
+ var d = delta / 1000;
+ this.options.scroll.scrollTo( left + d*this.scrollSpeed[0], top + d*this.scrollSpeed[1] );
+ }
+ }
+ } else {
+ this.options.scroll.scrollLeft += this.scrollSpeed[0] * delta / 1000;
+ this.options.scroll.scrollTop += this.scrollSpeed[1] * delta / 1000;
+ }
+
+ Position.prepare();
+ Droppables.show(Draggables._lastPointer, this.element);
+ Draggables.notify('onDrag', this);
+ Draggables._lastScrollPointer = Draggables._lastScrollPointer || $A(Draggables._lastPointer);
+ Draggables._lastScrollPointer[0] += this.scrollSpeed[0] * delta / 1000;
+ Draggables._lastScrollPointer[1] += this.scrollSpeed[1] * delta / 1000;
+ if (Draggables._lastScrollPointer[0] < 0)
+ Draggables._lastScrollPointer[0] = 0;
+ if (Draggables._lastScrollPointer[1] < 0)
+ Draggables._lastScrollPointer[1] = 0;
+ this.draw(Draggables._lastScrollPointer);
+
+ if(this.options.change) this.options.change(this);
+ },
+
+ _getWindowScroll: function(w) {
+ var T, L, W, H;
+ with (w.document) {
+ if (w.document.documentElement && documentElement.scrollTop) {
+ T = documentElement.scrollTop;
+ L = documentElement.scrollLeft;
+ } else if (w.document.body) {
+ T = body.scrollTop;
+ L = body.scrollLeft;
+ }
+ if (w.innerWidth) {
+ W = w.innerWidth;
+ H = w.innerHeight;
+ } else if (w.document.documentElement && documentElement.clientWidth) {
+ W = documentElement.clientWidth;
+ H = documentElement.clientHeight;
+ } else {
+ W = body.offsetWidth;
+ H = body.offsetHeight
+ }
+ }
+ return { top: T, left: L, width: W, height: H };
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+var SortableObserver = Class.create();
+SortableObserver.prototype = {
+ initialize: function(element, observer) {
+ this.element = $(element);
+ this.observer = observer;
+ this.lastValue = Sortable.serialize(this.element);
+ },
+
+ onStart: function() {
+ this.lastValue = Sortable.serialize(this.element);
+ },
+
+ onEnd: function() {
+ Sortable.unmark();
+ if(this.lastValue != Sortable.serialize(this.element))
+ this.observer(this.element)
+ }
+}
+
+var Sortable = {
+ sortables: {},
+
+ _findRootElement: function(element) {
+ while (element.tagName != "BODY") {
+ if(element.id && Sortable.sortables[element.id]) return element;
+ element = element.parentNode;
+ }
+ },
+
+ options: function(element) {
+ element = Sortable._findRootElement($(element));
+ if(!element) return;
+ return Sortable.sortables[element.id];
+ },
+
+ destroy: function(element){
+ var s = Sortable.options(element);
+
+ if(s) {
+ Draggables.removeObserver(s.element);
+ s.droppables.each(function(d){ Droppables.remove(d) });
+ s.draggables.invoke('destroy');
+
+ delete Sortable.sortables[s.element.id];
+ }
+ },
+
+ create: function(element) {
+ element = $(element);
+ var options = Object.extend({
+ element: element,
+ tag: 'li', // assumes li children, override with tag: 'tagname'
+ dropOnEmpty: false,
+ tree: false,
+ treeTag: 'ul',
+ overlap: 'vertical', // one of 'vertical', 'horizontal'
+ constraint: 'vertical', // one of 'vertical', 'horizontal', false
+ containment: element, // also takes array of elements (or id's); or false
+ handle: false, // or a CSS class
+ only: false,
+ hoverclass: null,
+ ghosting: false,
+ scroll: false,
+ scrollSensitivity: 20,
+ scrollSpeed: 15,
+ format: /^[^_]*_(.*)$/,
+ onChange: Prototype.emptyFunction,
+ onUpdate: Prototype.emptyFunction
+ }, arguments[1] || {});
+
+ // clear any old sortable with same element
+ this.destroy(element);
+
+ // build options for the draggables
+ var options_for_draggable = {
+ revert: true,
+ scroll: options.scroll,
+ scrollSpeed: options.scrollSpeed,
+ scrollSensitivity: options.scrollSensitivity,
+ ghosting: options.ghosting,
+ constraint: options.constraint,
+ handle: options.handle };
+
+ if(options.starteffect)
+ options_for_draggable.starteffect = options.starteffect;
+
+ if(options.reverteffect)
+ options_for_draggable.reverteffect = options.reverteffect;
+ else
+ if(options.ghosting) options_for_draggable.reverteffect = function(element) {
+ element.style.top = 0;
+ element.style.left = 0;
+ };
+
+ if(options.endeffect)
+ options_for_draggable.endeffect = options.endeffect;
+
+ if(options.zindex)
+ options_for_draggable.zindex = options.zindex;
+
+ // build options for the droppables
+ var options_for_droppable = {
+ overlap: options.overlap,
+ containment: options.containment,
+ tree: options.tree,
+ hoverclass: options.hoverclass,
+ onHover: Sortable.onHover
+ //greedy: !options.dropOnEmpty
+ }
+
+ var options_for_tree = {
+ onHover: Sortable.onEmptyHover,
+ overlap: options.overlap,
+ containment: options.containment,
+ hoverclass: options.hoverclass
+ }
+
+ // fix for gecko engine
+ Element.cleanWhitespace(element);
+
+ options.draggables = [];
+ options.droppables = [];
+
+ // drop on empty handling
+ if(options.dropOnEmpty || options.tree) {
+ Droppables.add(element, options_for_tree);
+ options.droppables.push(element);
+ }
+
+ (this.findElements(element, options) || []).each( function(e) {
+ // handles are per-draggable
+ var handle = options.handle ?
+ Element.childrenWithClassName(e, options.handle)[0] : e;
+ options.draggables.push(
+ new Draggable(e, Object.extend(options_for_draggable, { handle: handle })));
+ Droppables.add(e, options_for_droppable);
+ if(options.tree) e.treeNode = element;
+ options.droppables.push(e);
+ });
+
+ if(options.tree) {
+ (Sortable.findTreeElements(element, options) || []).each( function(e) {
+ Droppables.add(e, options_for_tree);
+ e.treeNode = element;
+ options.droppables.push(e);
+ });
+ }
+
+ // keep reference
+ this.sortables[element.id] = options;
+
+ // for onupdate
+ Draggables.addObserver(new SortableObserver(element, options.onUpdate));
+
+ },
+
+ // return all suitable-for-sortable elements in a guaranteed order
+ findElements: function(element, options) {
+ return Element.findChildren(
+ element, options.only, options.tree ? true : false, options.tag);
+ },
+
+ findTreeElements: function(element, options) {
+ return Element.findChildren(
+ element, options.only, options.tree ? true : false, options.treeTag);
+ },
+
+ onHover: function(element, dropon, overlap) {
+ if(Element.isParent(dropon, element)) return;
+
+ if(overlap > .33 && overlap < .66 && Sortable.options(dropon).tree) {
+ return;
+ } else if(overlap>0.5) {
+ Sortable.mark(dropon, 'before');
+ if(dropon.previousSibling != element) {
+ var oldParentNode = element.parentNode;
+ element.style.visibility = "hidden"; // fix gecko rendering
+ dropon.parentNode.insertBefore(element, dropon);
+ if(dropon.parentNode!=oldParentNode)
+ Sortable.options(oldParentNode).onChange(element);
+ Sortable.options(dropon.parentNode).onChange(element);
+ }
+ } else {
+ Sortable.mark(dropon, 'after');
+ var nextElement = dropon.nextSibling || null;
+ if(nextElement != element) {
+ var oldParentNode = element.parentNode;
+ element.style.visibility = "hidden"; // fix gecko rendering
+ dropon.parentNode.insertBefore(element, nextElement);
+ if(dropon.parentNode!=oldParentNode)
+ Sortable.options(oldParentNode).onChange(element);
+ Sortable.options(dropon.parentNode).onChange(element);
+ }
+ }
+ },
+
+ onEmptyHover: function(element, dropon, overlap) {
+ var oldParentNode = element.parentNode;
+ var droponOptions = Sortable.options(dropon);
+
+ if(!Element.isParent(dropon, element)) {
+ var index;
+
+ var children = Sortable.findElements(dropon, {tag: droponOptions.tag, only: droponOptions.only});
+ var child = null;
+
+ if(children) {
+ var offset = Element.offsetSize(dropon, droponOptions.overlap) * (1.0 - overlap);
+
+ for (index = 0; index < children.length; index += 1) {
+ if (offset - Element.offsetSize (children[index], droponOptions.overlap) >= 0) {
+ offset -= Element.offsetSize (children[index], droponOptions.overlap);
+ } else if (offset - (Element.offsetSize (children[index], droponOptions.overlap) / 2) >= 0) {
+ child = index + 1 < children.length ? children[index + 1] : null;
+ break;
+ } else {
+ child = children[index];
+ break;
+ }
+ }
+ }
+
+ dropon.insertBefore(element, child);
+
+ Sortable.options(oldParentNode).onChange(element);
+ droponOptions.onChange(element);
+ }
+ },
+
+ unmark: function() {
+ if(Sortable._marker) Element.hide(Sortable._marker);
+ },
+
+ mark: function(dropon, position) {
+ // mark on ghosting only
+ var sortable = Sortable.options(dropon.parentNode);
+ if(sortable && !sortable.ghosting) return;
+
+ if(!Sortable._marker) {
+ Sortable._marker = $('dropmarker') || document.createElement('DIV');
+ Element.hide(Sortable._marker);
+ Element.addClassName(Sortable._marker, 'dropmarker');
+ Sortable._marker.style.position = 'absolute';
+ document.getElementsByTagName("body").item(0).appendChild(Sortable._marker);
+ }
+ var offsets = Position.cumulativeOffset(dropon);
+ Sortable._marker.style.left = offsets[0] + 'px';
+ Sortable._marker.style.top = offsets[1] + 'px';
+
+ if(position=='after')
+ if(sortable.overlap == 'horizontal')
+ Sortable._marker.style.left = (offsets[0]+dropon.clientWidth) + 'px';
+ else
+ Sortable._marker.style.top = (offsets[1]+dropon.clientHeight) + 'px';
+
+ Element.show(Sortable._marker);
+ },
+
+ _tree: function(element, options, parent) {
+ var children = Sortable.findElements(element, options) || [];
+
+ for (var i = 0; i < children.length; ++i) {
+ var match = children[i].id.match(options.format);
+
+ if (!match) continue;
+
+ var child = {
+ id: encodeURIComponent(match ? match[1] : null),
+ element: element,
+ parent: parent,
+ children: new Array,
+ position: parent.children.length,
+ container: Sortable._findChildrenElement(children[i], options.treeTag.toUpperCase())
+ }
+
+ /* Get the element containing the children and recurse over it */
+ if (child.container)
+ this._tree(child.container, options, child)
+
+ parent.children.push (child);
+ }
+
+ return parent;
+ },
+
+ /* Finds the first element of the given tag type within a parent element.
+ Used for finding the first LI[ST] within a L[IST]I[TEM].*/
+ _findChildrenElement: function (element, containerTag) {
+ if (element && element.hasChildNodes)
+ for (var i = 0; i < element.childNodes.length; ++i)
+ if (element.childNodes[i].tagName == containerTag)
+ return element.childNodes[i];
+
+ return null;
+ },
+
+ tree: function(element) {
+ element = $(element);
+ var sortableOptions = this.options(element);
+ var options = Object.extend({
+ tag: sortableOptions.tag,
+ treeTag: sortableOptions.treeTag,
+ only: sortableOptions.only,
+ name: element.id,
+ format: sortableOptions.format
+ }, arguments[1] || {});
+
+ var root = {
+ id: null,
+ parent: null,
+ children: new Array,
+ container: element,
+ position: 0
+ }
+
+ return Sortable._tree (element, options, root);
+ },
+
+ /* Construct a [i] index for a particular node */
+ _constructIndex: function(node) {
+ var index = '';
+ do {
+ if (node.id) index = '[' + node.position + ']' + index;
+ } while ((node = node.parent) != null);
+ return index;
+ },
+
+ sequence: function(element) {
+ element = $(element);
+ var options = Object.extend(this.options(element), arguments[1] || {});
+
+ return $(this.findElements(element, options) || []).map( function(item) {
+ return item.id.match(options.format) ? item.id.match(options.format)[1] : '';
+ });
+ },
+
+ setSequence: function(element, new_sequence) {
+ element = $(element);
+ var options = Object.extend(this.options(element), arguments[2] || {});
+
+ var nodeMap = {};
+ this.findElements(element, options).each( function(n) {
+ if (n.id.match(options.format))
+ nodeMap[n.id.match(options.format)[1]] = [n, n.parentNode];
+ n.parentNode.removeChild(n);
+ });
+
+ new_sequence.each(function(ident) {
+ var n = nodeMap[ident];
+ if (n) {
+ n[1].appendChild(n[0]);
+ delete nodeMap[ident];
+ }
+ });
+ },
+
+ serialize: function(element) {
+ element = $(element);
+ var options = Object.extend(Sortable.options(element), arguments[1] || {});
+ var name = encodeURIComponent(
+ (arguments[1] && arguments[1].name) ? arguments[1].name : element.id);
+
+ if (options.tree) {
+ return Sortable.tree(element, arguments[1]).children.map( function (item) {
+ return [name + Sortable._constructIndex(item) + "[id]=" +
+ encodeURIComponent(item.id)].concat(item.children.map(arguments.callee));
+ }).flatten().join('&');
+ } else {
+ return Sortable.sequence(element, arguments[1]).map( function(item) {
+ return name + "[]=" + encodeURIComponent(item);
+ }).join('&');
+ }
+ }
+}
+
+/* Returns true if child is contained within element */
+Element.isParent = function(child, element) {
+ if (!child.parentNode || child == element) return false;
+
+ if (child.parentNode == element) return true;
+
+ return Element.isParent(child.parentNode, element);
+}
+
+Element.findChildren = function(element, only, recursive, tagName) {
+ if(!element.hasChildNodes()) return null;
+ tagName = tagName.toUpperCase();
+ if(only) only = [only].flatten();
+ var elements = [];
+ $A(element.childNodes).each( function(e) {
+ if(e.tagName && e.tagName.toUpperCase()==tagName &&
+ (!only || (Element.classNames(e).detect(function(v) { return only.include(v) }))))
+ elements.push(e);
+ if(recursive) {
+ var grandchildren = Element.findChildren(e, only, recursive, tagName);
+ if(grandchildren) elements.push(grandchildren);
+ }
+ });
+
+ return (elements.length>0 ? elements.flatten() : []);
+}
+
+Element.offsetSize = function (element, type) {
+ if (type == 'vertical' || type == 'height')
+ return element.offsetHeight;
+ else
+ return element.offsetWidth;
+} \ No newline at end of file
diff --git a/site/app/webroot/js/scriptaculous/effects.js b/site/app/webroot/js/scriptaculous/effects.js
new file mode 100644
index 0000000..1f3d50b
--- /dev/null
+++ b/site/app/webroot/js/scriptaculous/effects.js
@@ -0,0 +1,959 @@
+// Copyright (c) 2005 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
+// Contributors:
+// Justin Palmer (http://encytemedia.com/)
+// Mark Pilgrim (http://diveintomark.org/)
+// Martin Bialasinki
+//
+// See scriptaculous.js for full license.
+
+// converts rgb() and #xxx to #xxxxxx format,
+// returns self (or first argument) if not convertable
+String.prototype.parseColor = function() {
+ var color = '#';
+ if(this.slice(0,4) == 'rgb(') {
+ var cols = this.slice(4,this.length-1).split(',');
+ var i=0; do { color += parseInt(cols[i]).toColorPart() } while (++i<3);
+ } else {
+ if(this.slice(0,1) == '#') {
+ if(this.length==4) for(var i=1;i<4;i++) color += (this.charAt(i) + this.charAt(i)).toLowerCase();
+ if(this.length==7) color = this.toLowerCase();
+ }
+ }
+ return(color.length==7 ? color : (arguments[0] || this));
+}
+
+/*--------------------------------------------------------------------------*/
+
+Element.collectTextNodes = function(element) {
+ return $A($(element).childNodes).collect( function(node) {
+ return (node.nodeType==3 ? node.nodeValue :
+ (node.hasChildNodes() ? Element.collectTextNodes(node) : ''));
+ }).flatten().join('');
+}
+
+Element.collectTextNodesIgnoreClass = function(element, className) {
+ return $A($(element).childNodes).collect( function(node) {
+ return (node.nodeType==3 ? node.nodeValue :
+ ((node.hasChildNodes() && !Element.hasClassName(node,className)) ?
+ Element.collectTextNodesIgnoreClass(node, className) : ''));
+ }).flatten().join('');
+}
+
+Element.setContentZoom = function(element, percent) {
+ element = $(element);
+ Element.setStyle(element, {fontSize: (percent/100) + 'em'});
+ if(navigator.appVersion.indexOf('AppleWebKit')>0) window.scrollBy(0,0);
+}
+
+Element.getOpacity = function(element){
+ var opacity;
+ if (opacity = Element.getStyle(element, 'opacity'))
+ return parseFloat(opacity);
+ if (opacity = (Element.getStyle(element, 'filter') || '').match(/alpha\(opacity=(.*)\)/))
+ if(opacity[1]) return parseFloat(opacity[1]) / 100;
+ return 1.0;
+}
+
+Element.setOpacity = function(element, value){
+ element= $(element);
+ if (value == 1){
+ Element.setStyle(element, { opacity:
+ (/Gecko/.test(navigator.userAgent) && !/Konqueror|Safari|KHTML/.test(navigator.userAgent)) ?
+ 0.999999 : null });
+ if(/MSIE/.test(navigator.userAgent))
+ Element.setStyle(element, {filter: Element.getStyle(element,'filter').replace(/alpha\([^\)]*\)/gi,'')});
+ } else {
+ if(value < 0.00001) value = 0;
+ Element.setStyle(element, {opacity: value});
+ if(/MSIE/.test(navigator.userAgent))
+ Element.setStyle(element,
+ { filter: Element.getStyle(element,'filter').replace(/alpha\([^\)]*\)/gi,'') +
+ 'alpha(opacity='+value*100+')' });
+ }
+}
+
+Element.getInlineOpacity = function(element){
+ return $(element).style.opacity || '';
+}
+
+Element.childrenWithClassName = function(element, className, findFirst) {
+ var classNameRegExp = new RegExp("(^|\\s)" + className + "(\\s|$)");
+ var results = $A($(element).getElementsByTagName('*'))[findFirst ? 'detect' : 'select']( function(c) {
+ return (c.className && c.className.match(classNameRegExp));
+ });
+ if(!results) results = [];
+ return results;
+}
+
+Element.forceRerendering = function(element) {
+ try {
+ element = $(element);
+ var n = document.createTextNode(' ');
+ element.appendChild(n);
+ element.removeChild(n);
+ } catch(e) { }
+};
+
+/*--------------------------------------------------------------------------*/
+
+Array.prototype.call = function() {
+ var args = arguments;
+ this.each(function(f){ f.apply(this, args) });
+}
+
+/*--------------------------------------------------------------------------*/
+
+var Effect = {
+ tagifyText: function(element) {
+ if(typeof Builder == 'undefined')
+ throw("Effect.tagifyText requires including script.aculo.us' builder.js library");
+
+ var tagifyStyle = 'position:relative';
+ if(/MSIE/.test(navigator.userAgent)) tagifyStyle += ';zoom:1';
+ element = $(element);
+ $A(element.childNodes).each( function(child) {
+ if(child.nodeType==3) {
+ child.nodeValue.toArray().each( function(character) {
+ element.insertBefore(
+ Builder.node('span',{style: tagifyStyle},
+ character == ' ' ? String.fromCharCode(160) : character),
+ child);
+ });
+ Element.remove(child);
+ }
+ });
+ },
+ multiple: function(element, effect) {
+ var elements;
+ if(((typeof element == 'object') ||
+ (typeof element == 'function')) &&
+ (element.length))
+ elements = element;
+ else
+ elements = $(element).childNodes;
+
+ var options = Object.extend({
+ speed: 0.1,
+ delay: 0.0
+ }, arguments[2] || {});
+ var masterDelay = options.delay;
+
+ $A(elements).each( function(element, index) {
+ new effect(element, Object.extend(options, { delay: index * options.speed + masterDelay }));
+ });
+ },
+ PAIRS: {
+ 'slide': ['SlideDown','SlideUp'],
+ 'blind': ['BlindDown','BlindUp'],
+ 'appear': ['Appear','Fade']
+ },
+ toggle: function(element, effect) {
+ element = $(element);
+ effect = (effect || 'appear').toLowerCase();
+ var options = Object.extend({
+ queue: { position:'end', scope:(element.id || 'global'), limit: 1 }
+ }, arguments[2] || {});
+ Effect[element.visible() ?
+ Effect.PAIRS[effect][1] : Effect.PAIRS[effect][0]](element, options);
+ }
+};
+
+var Effect2 = Effect; // deprecated
+
+/* ------------- transitions ------------- */
+
+Effect.Transitions = {}
+
+Effect.Transitions.linear = Prototype.K;
+
+Effect.Transitions.sinoidal = function(pos) {
+ return (-Math.cos(pos*Math.PI)/2) + 0.5;
+}
+Effect.Transitions.reverse = function(pos) {
+ return 1-pos;
+}
+Effect.Transitions.flicker = function(pos) {
+ return ((-Math.cos(pos*Math.PI)/4) + 0.75) + Math.random()/4;
+}
+Effect.Transitions.wobble = function(pos) {
+ return (-Math.cos(pos*Math.PI*(9*pos))/2) + 0.5;
+}
+Effect.Transitions.pulse = function(pos) {
+ return (Math.floor(pos*10) % 2 == 0 ?
+ (pos*10-Math.floor(pos*10)) : 1-(pos*10-Math.floor(pos*10)));
+}
+Effect.Transitions.none = function(pos) {
+ return 0;
+}
+Effect.Transitions.full = function(pos) {
+ return 1;
+}
+
+/* ------------- core effects ------------- */
+
+Effect.ScopedQueue = Class.create();
+Object.extend(Object.extend(Effect.ScopedQueue.prototype, Enumerable), {
+ initialize: function() {
+ this.effects = [];
+ this.interval = null;
+ },
+ _each: function(iterator) {
+ this.effects._each(iterator);
+ },
+ add: function(effect) {
+ var timestamp = new Date().getTime();
+
+ var position = (typeof effect.options.queue == 'string') ?
+ effect.options.queue : effect.options.queue.position;
+
+ switch(position) {
+ case 'front':
+ // move unstarted effects after this effect
+ this.effects.findAll(function(e){ return e.state=='idle' }).each( function(e) {
+ e.startOn += effect.finishOn;
+ e.finishOn += effect.finishOn;
+ });
+ break;
+ case 'end':
+ // start effect after last queued effect has finished
+ timestamp = this.effects.pluck('finishOn').max() || timestamp;
+ break;
+ }
+
+ effect.startOn += timestamp;
+ effect.finishOn += timestamp;
+
+ if(!effect.options.queue.limit || (this.effects.length < effect.options.queue.limit))
+ this.effects.push(effect);
+
+ if(!this.interval)
+ this.interval = setInterval(this.loop.bind(this), 40);
+ },
+ remove: function(effect) {
+ this.effects = this.effects.reject(function(e) { return e==effect });
+ if(this.effects.length == 0) {
+ clearInterval(this.interval);
+ this.interval = null;
+ }
+ },
+ loop: function() {
+ var timePos = new Date().getTime();
+ this.effects.invoke('loop', timePos);
+ }
+});
+
+Effect.Queues = {
+ instances: $H(),
+ get: function(queueName) {
+ if(typeof queueName != 'string') return queueName;
+
+ if(!this.instances[queueName])
+ this.instances[queueName] = new Effect.ScopedQueue();
+
+ return this.instances[queueName];
+ }
+}
+Effect.Queue = Effect.Queues.get('global');
+
+Effect.DefaultOptions = {
+ transition: Effect.Transitions.sinoidal,
+ duration: 1.0, // seconds
+ fps: 25.0, // max. 25fps due to Effect.Queue implementation
+ sync: false, // true for combining
+ from: 0.0,
+ to: 1.0,
+ delay: 0.0,
+ queue: 'parallel'
+}
+
+Effect.Base = function() {};
+Effect.Base.prototype = {
+ position: null,
+ start: function(options) {
+ this.options = Object.extend(Object.extend({},Effect.DefaultOptions), options || {});
+ this.currentFrame = 0;
+ this.state = 'idle';
+ this.startOn = this.options.delay*1000;
+ this.finishOn = this.startOn + (this.options.duration*1000);
+ this.event('beforeStart');
+ if(!this.options.sync)
+ Effect.Queues.get(typeof this.options.queue == 'string' ?
+ 'global' : this.options.queue.scope).add(this);
+ },
+ loop: function(timePos) {
+ if(timePos >= this.startOn) {
+ if(timePos >= this.finishOn) {
+ this.render(1.0);
+ this.cancel();
+ this.event('beforeFinish');
+ if(this.finish) this.finish();
+ this.event('afterFinish');
+ return;
+ }
+ var pos = (timePos - this.startOn) / (this.finishOn - this.startOn);
+ var frame = Math.round(pos * this.options.fps * this.options.duration);
+ if(frame > this.currentFrame) {
+ this.render(pos);
+ this.currentFrame = frame;
+ }
+ }
+ },
+ render: function(pos) {
+ if(this.state == 'idle') {
+ this.state = 'running';
+ this.event('beforeSetup');
+ if(this.setup) this.setup();
+ this.event('afterSetup');
+ }
+ if(this.state == 'running') {
+ if(this.options.transition) pos = this.options.transition(pos);
+ pos *= (this.options.to-this.options.from);
+ pos += this.options.from;
+ this.position = pos;
+ this.event('beforeUpdate');
+ if(this.update) this.update(pos);
+ this.event('afterUpdate');
+ }
+ },
+ cancel: function() {
+ if(!this.options.sync)
+ Effect.Queues.get(typeof this.options.queue == 'string' ?
+ 'global' : this.options.queue.scope).remove(this);
+ this.state = 'finished';
+ },
+ event: function(eventName) {
+ if(this.options[eventName + 'Internal']) this.options[eventName + 'Internal'](this);
+ if(this.options[eventName]) this.options[eventName](this);
+ },
+ inspect: function() {
+ return '#<Effect:' + $H(this).inspect() + ',options:' + $H(this.options).inspect() + '>';
+ }
+}
+
+Effect.Parallel = Class.create();
+Object.extend(Object.extend(Effect.Parallel.prototype, Effect.Base.prototype), {
+ initialize: function(effects) {
+ this.effects = effects || [];
+ this.start(arguments[1]);
+ },
+ update: function(position) {
+ this.effects.invoke('render', position);
+ },
+ finish: function(position) {
+ this.effects.each( function(effect) {
+ effect.render(1.0);
+ effect.cancel();
+ effect.event('beforeFinish');
+ if(effect.finish) effect.finish(position);
+ effect.event('afterFinish');
+ });
+ }
+});
+
+Effect.Opacity = Class.create();
+Object.extend(Object.extend(Effect.Opacity.prototype, Effect.Base.prototype), {
+ initialize: function(element) {
+ this.element = $(element);
+ // make this work on IE on elements without 'layout'
+ if(/MSIE/.test(navigator.userAgent) && (!this.element.currentStyle.hasLayout))
+ this.element.setStyle({zoom: 1});
+ var options = Object.extend({
+ from: this.element.getOpacity() || 0.0,
+ to: 1.0
+ }, arguments[1] || {});
+ this.start(options);
+ },
+ update: function(position) {
+ this.element.setOpacity(position);
+ }
+});
+
+Effect.Move = Class.create();
+Object.extend(Object.extend(Effect.Move.prototype, Effect.Base.prototype), {
+ initialize: function(element) {
+ this.element = $(element);
+ var options = Object.extend({
+ x: 0,
+ y: 0,
+ mode: 'relative'
+ }, arguments[1] || {});
+ this.start(options);
+ },
+ setup: function() {
+ // Bug in Opera: Opera returns the "real" position of a static element or
+ // relative element that does not have top/left explicitly set.
+ // ==> Always set top and left for position relative elements in your stylesheets
+ // (to 0 if you do not need them)
+ this.element.makePositioned();
+ this.originalLeft = parseFloat(this.element.getStyle('left') || '0');
+ this.originalTop = parseFloat(this.element.getStyle('top') || '0');
+ if(this.options.mode == 'absolute') {
+ // absolute movement, so we need to calc deltaX and deltaY
+ this.options.x = this.options.x - this.originalLeft;
+ this.options.y = this.options.y - this.originalTop;
+ }
+ },
+ update: function(position) {
+ this.element.setStyle({
+ left: Math.round(this.options.x * position + this.originalLeft) + 'px',
+ top: Math.round(this.options.y * position + this.originalTop) + 'px'
+ });
+ }
+});
+
+// for backwards compatibility
+Effect.MoveBy = function(element, toTop, toLeft) {
+ return new Effect.Move(element,
+ Object.extend({ x: toLeft, y: toTop }, arguments[3] || {}));
+};
+
+Effect.Scale = Class.create();
+Object.extend(Object.extend(Effect.Scale.prototype, Effect.Base.prototype), {
+ initialize: function(element, percent) {
+ this.element = $(element)
+ var options = Object.extend({
+ scaleX: true,
+ scaleY: true,
+ scaleContent: true,
+ scaleFromCenter: false,
+ scaleMode: 'box', // 'box' or 'contents' or {} with provided values
+ scaleFrom: 100.0,
+ scaleTo: percent
+ }, arguments[2] || {});
+ this.start(options);
+ },
+ setup: function() {
+ this.restoreAfterFinish = this.options.restoreAfterFinish || false;
+ this.elementPositioning = this.element.getStyle('position');
+
+ this.originalStyle = {};
+ ['top','left','width','height','fontSize'].each( function(k) {
+ this.originalStyle[k] = this.element.style[k];
+ }.bind(this));
+
+ this.originalTop = this.element.offsetTop;
+ this.originalLeft = this.element.offsetLeft;
+
+ var fontSize = this.element.getStyle('font-size') || '100%';
+ ['em','px','%','pt'].each( function(fontSizeType) {
+ if(fontSize.indexOf(fontSizeType)>0) {
+ this.fontSize = parseFloat(fontSize);
+ this.fontSizeType = fontSizeType;
+ }
+ }.bind(this));
+
+ this.factor = (this.options.scaleTo - this.options.scaleFrom)/100;
+
+ this.dims = null;
+ if(this.options.scaleMode=='box')
+ this.dims = [this.element.offsetHeight, this.element.offsetWidth];
+ if(/^content/.test(this.options.scaleMode))
+ this.dims = [this.element.scrollHeight, this.element.scrollWidth];
+ if(!this.dims)
+ this.dims = [this.options.scaleMode.originalHeight,
+ this.options.scaleMode.originalWidth];
+ },
+ update: function(position) {
+ var currentScale = (this.options.scaleFrom/100.0) + (this.factor * position);
+ if(this.options.scaleContent && this.fontSize)
+ this.element.setStyle({fontSize: this.fontSize * currentScale + this.fontSizeType });
+ this.setDimensions(this.dims[0] * currentScale, this.dims[1] * currentScale);
+ },
+ finish: function(position) {
+ if (this.restoreAfterFinish) this.element.setStyle(this.originalStyle);
+ },
+ setDimensions: function(height, width) {
+ var d = {};
+ if(this.options.scaleX) d.width = Math.round(width) + 'px';
+ if(this.options.scaleY) d.height = Math.round(height) + 'px';
+ if(this.options.scaleFromCenter) {
+ var topd = (height - this.dims[0])/2;
+ var leftd = (width - this.dims[1])/2;
+ if(this.elementPositioning == 'absolute') {
+ if(this.options.scaleY) d.top = this.originalTop-topd + 'px';
+ if(this.options.scaleX) d.left = this.originalLeft-leftd + 'px';
+ } else {
+ if(this.options.scaleY) d.top = -topd + 'px';
+ if(this.options.scaleX) d.left = -leftd + 'px';
+ }
+ }
+ this.element.setStyle(d);
+ }
+});
+
+Effect.Highlight = Class.create();
+Object.extend(Object.extend(Effect.Highlight.prototype, Effect.Base.prototype), {
+ initialize: function(element) {
+ this.element = $(element);
+ var options = Object.extend({ startcolor: '#ffff99' }, arguments[1] || {});
+ this.start(options);
+ },
+ setup: function() {
+ // Prevent executing on elements not in the layout flow
+ if(this.element.getStyle('display')=='none') { this.cancel(); return; }
+ // Disable background image during the effect
+ this.oldStyle = {
+ backgroundImage: this.element.getStyle('background-image') };
+ this.element.setStyle({backgroundImage: 'none'});
+ if(!this.options.endcolor)
+ this.options.endcolor = this.element.getStyle('background-color').parseColor('#ffffff');
+ if(!this.options.restorecolor)
+ this.options.restorecolor = this.element.getStyle('background-color');
+ // init color calculations
+ this._base = $R(0,2).map(function(i){ return parseInt(this.options.startcolor.slice(i*2+1,i*2+3),16) }.bind(this));
+ this._delta = $R(0,2).map(function(i){ return parseInt(this.options.endcolor.slice(i*2+1,i*2+3),16)-this._base[i] }.bind(this));
+ },
+ update: function(position) {
+ this.element.setStyle({backgroundColor: $R(0,2).inject('#',function(m,v,i){
+ return m+(Math.round(this._base[i]+(this._delta[i]*position)).toColorPart()); }.bind(this)) });
+ },
+ finish: function() {
+ this.element.setStyle(Object.extend(this.oldStyle, {
+ backgroundColor: this.options.restorecolor
+ }));
+ }
+});
+
+Effect.ScrollTo = Class.create();
+Object.extend(Object.extend(Effect.ScrollTo.prototype, Effect.Base.prototype), {
+ initialize: function(element) {
+ this.element = $(element);
+ this.start(arguments[1] || {});
+ },
+ setup: function() {
+ Position.prepare();
+ var offsets = Position.cumulativeOffset(this.element);
+ if(this.options.offset) offsets[1] += this.options.offset;
+ var max = window.innerHeight ?
+ window.height - window.innerHeight :
+ document.body.scrollHeight -
+ (document.documentElement.clientHeight ?
+ document.documentElement.clientHeight : document.body.clientHeight);
+ this.scrollStart = Position.deltaY;
+ this.delta = (offsets[1] > max ? max : offsets[1]) - this.scrollStart;
+ },
+ update: function(position) {
+ Position.prepare();
+ window.scrollTo(Position.deltaX,
+ this.scrollStart + (position*this.delta));
+ }
+});
+
+/* ------------- combination effects ------------- */
+
+Effect.Fade = function(element) {
+ element = $(element);
+ var oldOpacity = element.getInlineOpacity();
+ var options = Object.extend({
+ from: element.getOpacity() || 1.0,
+ to: 0.0,
+ afterFinishInternal: function(effect) {
+ if(effect.options.to!=0) return;
+ effect.element.hide();
+ effect.element.setStyle({opacity: oldOpacity});
+ }}, arguments[1] || {});
+ return new Effect.Opacity(element,options);
+}
+
+Effect.Appear = function(element) {
+ element = $(element);
+ var options = Object.extend({
+ from: (element.getStyle('display') == 'none' ? 0.0 : element.getOpacity() || 0.0),
+ to: 1.0,
+ // force Safari to render floated elements properly
+ afterFinishInternal: function(effect) {
+ effect.element.forceRerendering();
+ },
+ beforeSetup: function(effect) {
+ effect.element.setOpacity(effect.options.from);
+ effect.element.show();
+ }}, arguments[1] || {});
+ return new Effect.Opacity(element,options);
+}
+
+Effect.Puff = function(element) {
+ element = $(element);
+ var oldStyle = { opacity: element.getInlineOpacity(), position: element.getStyle('position') };
+ return new Effect.Parallel(
+ [ new Effect.Scale(element, 200,
+ { sync: true, scaleFromCenter: true, scaleContent: true, restoreAfterFinish: true }),
+ new Effect.Opacity(element, { sync: true, to: 0.0 } ) ],
+ Object.extend({ duration: 1.0,
+ beforeSetupInternal: function(effect) {
+ effect.effects[0].element.setStyle({position: 'absolute'}); },
+ afterFinishInternal: function(effect) {
+ effect.effects[0].element.hide();
+ effect.effects[0].element.setStyle(oldStyle); }
+ }, arguments[1] || {})
+ );
+}
+
+Effect.BlindUp = function(element) {
+ element = $(element);
+ element.makeClipping();
+ return new Effect.Scale(element, 0,
+ Object.extend({ scaleContent: false,
+ scaleX: false,
+ restoreAfterFinish: true,
+ afterFinishInternal: function(effect) {
+ effect.element.hide();
+ effect.element.undoClipping();
+ }
+ }, arguments[1] || {})
+ );
+}
+
+Effect.BlindDown = function(element) {
+ element = $(element);
+ var elementDimensions = element.getDimensions();
+ return new Effect.Scale(element, 100, Object.extend({
+ scaleContent: false,
+ scaleX: false,
+ scaleFrom: 0,
+ scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width},
+ restoreAfterFinish: true,
+ afterSetup: function(effect) {
+ effect.element.makeClipping();
+ effect.element.setStyle({height: '0px'});
+ effect.element.show();
+ },
+ afterFinishInternal: function(effect) {
+ effect.element.undoClipping();
+ }
+ }, arguments[1] || {}));
+}
+
+Effect.SwitchOff = function(element) {
+ element = $(element);
+ var oldOpacity = element.getInlineOpacity();
+ return new Effect.Appear(element, Object.extend({
+ duration: 0.4,
+ from: 0,
+ transition: Effect.Transitions.flicker,
+ afterFinishInternal: function(effect) {
+ new Effect.Scale(effect.element, 1, {
+ duration: 0.3, scaleFromCenter: true,
+ scaleX: false, scaleContent: false, restoreAfterFinish: true,
+ beforeSetup: function(effect) {
+ effect.element.makePositioned();
+ effect.element.makeClipping();
+ },
+ afterFinishInternal: function(effect) {
+ effect.element.hide();
+ effect.element.undoClipping();
+ effect.element.undoPositioned();
+ effect.element.setStyle({opacity: oldOpacity});
+ }
+ })
+ }
+ }, arguments[1] || {}));
+}
+
+Effect.DropOut = function(element) {
+ element = $(element);
+ var oldStyle = {
+ top: element.getStyle('top'),
+ left: element.getStyle('left'),
+ opacity: element.getInlineOpacity() };
+ return new Effect.Parallel(
+ [ new Effect.Move(element, {x: 0, y: 100, sync: true }),
+ new Effect.Opacity(element, { sync: true, to: 0.0 }) ],
+ Object.extend(
+ { duration: 0.5,
+ beforeSetup: function(effect) {
+ effect.effects[0].element.makePositioned();
+ },
+ afterFinishInternal: function(effect) {
+ effect.effects[0].element.hide();
+ effect.effects[0].element.undoPositioned();
+ effect.effects[0].element.setStyle(oldStyle);
+ }
+ }, arguments[1] || {}));
+}
+
+Effect.Shake = function(element) {
+ element = $(element);
+ var oldStyle = {
+ top: element.getStyle('top'),
+ left: element.getStyle('left') };
+ return new Effect.Move(element,
+ { x: 20, y: 0, duration: 0.05, afterFinishInternal: function(effect) {
+ new Effect.Move(effect.element,
+ { x: -40, y: 0, duration: 0.1, afterFinishInternal: function(effect) {
+ new Effect.Move(effect.element,
+ { x: 40, y: 0, duration: 0.1, afterFinishInternal: function(effect) {
+ new Effect.Move(effect.element,
+ { x: -40, y: 0, duration: 0.1, afterFinishInternal: function(effect) {
+ new Effect.Move(effect.element,
+ { x: 40, y: 0, duration: 0.1, afterFinishInternal: function(effect) {
+ new Effect.Move(effect.element,
+ { x: -20, y: 0, duration: 0.05, afterFinishInternal: function(effect) {
+ effect.element.undoPositioned();
+ effect.element.setStyle(oldStyle);
+ }}) }}) }}) }}) }}) }});
+}
+
+Effect.SlideDown = function(element) {
+ element = $(element);
+ element.cleanWhitespace();
+ // SlideDown need to have the content of the element wrapped in a container element with fixed height!
+ var oldInnerBottom = $(element.firstChild).getStyle('bottom');
+ var elementDimensions = element.getDimensions();
+ return new Effect.Scale(element, 100, Object.extend({
+ scaleContent: false,
+ scaleX: false,
+ scaleFrom: window.opera ? 0 : 1,
+ scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width},
+ restoreAfterFinish: true,
+ afterSetup: function(effect) {
+ effect.element.makePositioned();
+ effect.element.firstChild.makePositioned();
+ if(window.opera) effect.element.setStyle({top: ''});
+ effect.element.makeClipping();
+ effect.element.setStyle({height: '0px'});
+ effect.element.show(); },
+ afterUpdateInternal: function(effect) {
+ effect.element.firstChild.setStyle({bottom:
+ (effect.dims[0] - effect.element.clientHeight) + 'px' });
+ },
+ afterFinishInternal: function(effect) {
+ effect.element.undoClipping();
+ // IE will crash if child is undoPositioned first
+ if(/MSIE/.test(navigator.userAgent)){
+ effect.element.undoPositioned();
+ effect.element.firstChild.undoPositioned();
+ }else{
+ effect.element.firstChild.undoPositioned();
+ effect.element.undoPositioned();
+ }
+ effect.element.firstChild.setStyle({bottom: oldInnerBottom}); }
+ }, arguments[1] || {})
+ );
+}
+
+Effect.SlideUp = function(element) {
+ element = $(element);
+ element.cleanWhitespace();
+ var oldInnerBottom = $(element.firstChild).getStyle('bottom');
+ return new Effect.Scale(element, window.opera ? 0 : 1,
+ Object.extend({ scaleContent: false,
+ scaleX: false,
+ scaleMode: 'box',
+ scaleFrom: 100,
+ restoreAfterFinish: true,
+ beforeStartInternal: function(effect) {
+ effect.element.makePositioned();
+ effect.element.firstChild.makePositioned();
+ if(window.opera) effect.element.setStyle({top: ''});
+ effect.element.makeClipping();
+ effect.element.show(); },
+ afterUpdateInternal: function(effect) {
+ effect.element.firstChild.setStyle({bottom:
+ (effect.dims[0] - effect.element.clientHeight) + 'px' }); },
+ afterFinishInternal: function(effect) {
+ effect.element.hide();
+ effect.element.undoClipping();
+ effect.element.firstChild.undoPositioned();
+ effect.element.undoPositioned();
+ effect.element.setStyle({bottom: oldInnerBottom}); }
+ }, arguments[1] || {})
+ );
+}
+
+// Bug in opera makes the TD containing this element expand for a instance after finish
+Effect.Squish = function(element) {
+ return new Effect.Scale(element, window.opera ? 1 : 0,
+ { restoreAfterFinish: true,
+ beforeSetup: function(effect) {
+ effect.element.makeClipping(effect.element); },
+ afterFinishInternal: function(effect) {
+ effect.element.hide(effect.element);
+ effect.element.undoClipping(effect.element); }
+ });
+}
+
+Effect.Grow = function(element) {
+ element = $(element);
+ var options = Object.extend({
+ direction: 'center',
+ moveTransition: Effect.Transitions.sinoidal,
+ scaleTransition: Effect.Transitions.sinoidal,
+ opacityTransition: Effect.Transitions.full
+ }, arguments[1] || {});
+ var oldStyle = {
+ top: element.style.top,
+ left: element.style.left,
+ height: element.style.height,
+ width: element.style.width,
+ opacity: element.getInlineOpacity() };
+
+ var dims = element.getDimensions();
+ var initialMoveX, initialMoveY;
+ var moveX, moveY;
+
+ switch (options.direction) {
+ case 'top-left':
+ initialMoveX = initialMoveY = moveX = moveY = 0;
+ break;
+ case 'top-right':
+ initialMoveX = dims.width;
+ initialMoveY = moveY = 0;
+ moveX = -dims.width;
+ break;
+ case 'bottom-left':
+ initialMoveX = moveX = 0;
+ initialMoveY = dims.height;
+ moveY = -dims.height;
+ break;
+ case 'bottom-right':
+ initialMoveX = dims.width;
+ initialMoveY = dims.height;
+ moveX = -dims.width;
+ moveY = -dims.height;
+ break;
+ case 'center':
+ initialMoveX = dims.width / 2;
+ initialMoveY = dims.height / 2;
+ moveX = -dims.width / 2;
+ moveY = -dims.height / 2;
+ break;
+ }
+
+ return new Effect.Move(element, {
+ x: initialMoveX,
+ y: initialMoveY,
+ duration: 0.01,
+ beforeSetup: function(effect) {
+ effect.element.hide();
+ effect.element.makeClipping();
+ effect.element.makePositioned();
+ },
+ afterFinishInternal: function(effect) {
+ new Effect.Parallel(
+ [ new Effect.Opacity(effect.element, { sync: true, to: 1.0, from: 0.0, transition: options.opacityTransition }),
+ new Effect.Move(effect.element, { x: moveX, y: moveY, sync: true, transition: options.moveTransition }),
+ new Effect.Scale(effect.element, 100, {
+ scaleMode: { originalHeight: dims.height, originalWidth: dims.width },
+ sync: true, scaleFrom: window.opera ? 1 : 0, transition: options.scaleTransition, restoreAfterFinish: true})
+ ], Object.extend({
+ beforeSetup: function(effect) {
+ effect.effects[0].element.setStyle({height: '0px'});
+ effect.effects[0].element.show();
+ },
+ afterFinishInternal: function(effect) {
+ effect.effects[0].element.undoClipping();
+ effect.effects[0].element.undoPositioned();
+ effect.effects[0].element.setStyle(oldStyle);
+ }
+ }, options)
+ )
+ }
+ });
+}
+
+Effect.Shrink = function(element) {
+ element = $(element);
+ var options = Object.extend({
+ direction: 'center',
+ moveTransition: Effect.Transitions.sinoidal,
+ scaleTransition: Effect.Transitions.sinoidal,
+ opacityTransition: Effect.Transitions.none
+ }, arguments[1] || {});
+ var oldStyle = {
+ top: element.style.top,
+ left: element.style.left,
+ height: element.style.height,
+ width: element.style.width,
+ opacity: element.getInlineOpacity() };
+
+ var dims = element.getDimensions();
+ var moveX, moveY;
+
+ switch (options.direction) {
+ case 'top-left':
+ moveX = moveY = 0;
+ break;
+ case 'top-right':
+ moveX = dims.width;
+ moveY = 0;
+ break;
+ case 'bottom-left':
+ moveX = 0;
+ moveY = dims.height;
+ break;
+ case 'bottom-right':
+ moveX = dims.width;
+ moveY = dims.height;
+ break;
+ case 'center':
+ moveX = dims.width / 2;
+ moveY = dims.height / 2;
+ break;
+ }
+
+ return new Effect.Parallel(
+ [ new Effect.Opacity(element, { sync: true, to: 0.0, from: 1.0, transition: options.opacityTransition }),
+ new Effect.Scale(element, window.opera ? 1 : 0, { sync: true, transition: options.scaleTransition, restoreAfterFinish: true}),
+ new Effect.Move(element, { x: moveX, y: moveY, sync: true, transition: options.moveTransition })
+ ], Object.extend({
+ beforeStartInternal: function(effect) {
+ effect.effects[0].element.makePositioned();
+ effect.effects[0].element.makeClipping(); },
+ afterFinishInternal: function(effect) {
+ effect.effects[0].element.hide();
+ effect.effects[0].element.undoClipping();
+ effect.effects[0].element.undoPositioned();
+ effect.effects[0].element.setStyle(oldStyle); }
+ }, options)
+ );
+}
+
+Effect.Pulsate = function(element) {
+ element = $(element);
+ var options = arguments[1] || {};
+ var oldOpacity = element.getInlineOpacity();
+ var transition = options.transition || Effect.Transitions.sinoidal;
+ var reverser = function(pos){ return transition(1-Effect.Transitions.pulse(pos)) };
+ reverser.bind(transition);
+ return new Effect.Opacity(element,
+ Object.extend(Object.extend({ duration: 3.0, from: 0,
+ afterFinishInternal: function(effect) { effect.element.setStyle({opacity: oldOpacity}); }
+ }, options), {transition: reverser}));
+}
+
+Effect.Fold = function(element) {
+ element = $(element);
+ var oldStyle = {
+ top: element.style.top,
+ left: element.style.left,
+ width: element.style.width,
+ height: element.style.height };
+ Element.makeClipping(element);
+ return new Effect.Scale(element, 5, Object.extend({
+ scaleContent: false,
+ scaleX: false,
+ afterFinishInternal: function(effect) {
+ new Effect.Scale(element, 1, {
+ scaleContent: false,
+ scaleY: false,
+ afterFinishInternal: function(effect) {
+ effect.element.hide();
+ effect.element.undoClipping();
+ effect.element.setStyle(oldStyle);
+ } });
+ }}, arguments[1] || {}));
+};
+
+['setOpacity','getOpacity','getInlineOpacity','forceRerendering','setContentZoom',
+ 'collectTextNodes','collectTextNodesIgnoreClass','childrenWithClassName'].each(
+ function(f) { Element.Methods[f] = Element[f]; }
+);
+
+Element.Methods.visualEffect = function(element, effect, options) {
+ s = effect.gsub(/_/, '-').camelize();
+ effect_class = s.charAt(0).toUpperCase() + s.substring(1);
+ new Effect[effect_class](element, options);
+ return $(element);
+};
+
+Element.addMethods(); \ No newline at end of file
diff --git a/site/app/webroot/js/scriptaculous/prototype.js b/site/app/webroot/js/scriptaculous/prototype.js
new file mode 100644
index 0000000..0caf9cd
--- /dev/null
+++ b/site/app/webroot/js/scriptaculous/prototype.js
@@ -0,0 +1,2006 @@
+/* Prototype JavaScript framework, version 1.5.0_rc0
+ * (c) 2005 Sam Stephenson <sam@conio.net>
+ *
+ * Prototype is freely distributable under the terms of an MIT-style license.
+ * For details, see the Prototype web site: http://prototype.conio.net/
+ *
+/*--------------------------------------------------------------------------*/
+
+var Prototype = {
+ Version: '1.5.0_rc0',
+ ScriptFragment: '(?:<script.*?>)((\n|\r|.)*?)(?:<\/script>)',
+
+ emptyFunction: function() {},
+ K: function(x) {return x}
+}
+
+var Class = {
+ create: function() {
+ return function() {
+ this.initialize.apply(this, arguments);
+ }
+ }
+}
+
+var Abstract = new Object();
+
+Object.extend = function(destination, source) {
+ for (var property in source) {
+ destination[property] = source[property];
+ }
+ return destination;
+}
+
+Object.inspect = function(object) {
+ try {
+ if (object == undefined) return 'undefined';
+ if (object == null) return 'null';
+ return object.inspect ? object.inspect() : object.toString();
+ } catch (e) {
+ if (e instanceof RangeError) return '...';
+ throw e;
+ }
+}
+
+Function.prototype.bind = function() {
+ var __method = this, args = $A(arguments), object = args.shift();
+ return function() {
+ return __method.apply(object, args.concat($A(arguments)));
+ }
+}
+
+Function.prototype.bindAsEventListener = function(object) {
+ var __method = this;
+ return function(event) {
+ return __method.call(object, event || window.event);
+ }
+}
+
+Object.extend(Number.prototype, {
+ toColorPart: function() {
+ var digits = this.toString(16);
+ if (this < 16) return '0' + digits;
+ return digits;
+ },
+
+ succ: function() {
+ return this + 1;
+ },
+
+ times: function(iterator) {
+ $R(0, this, true).each(iterator);
+ return this;
+ }
+});
+
+var Try = {
+ these: function() {
+ var returnValue;
+
+ for (var i = 0; i < arguments.length; i++) {
+ var lambda = arguments[i];
+ try {
+ returnValue = lambda();
+ break;
+ } catch (e) {}
+ }
+
+ return returnValue;
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+var PeriodicalExecuter = Class.create();
+PeriodicalExecuter.prototype = {
+ initialize: function(callback, frequency) {
+ this.callback = callback;
+ this.frequency = frequency;
+ this.currentlyExecuting = false;
+
+ this.registerCallback();
+ },
+
+ registerCallback: function() {
+ setInterval(this.onTimerEvent.bind(this), this.frequency * 1000);
+ },
+
+ onTimerEvent: function() {
+ if (!this.currentlyExecuting) {
+ try {
+ this.currentlyExecuting = true;
+ this.callback();
+ } finally {
+ this.currentlyExecuting = false;
+ }
+ }
+ }
+}
+Object.extend(String.prototype, {
+ gsub: function(pattern, replacement) {
+ var result = '', source = this, match;
+ replacement = arguments.callee.prepareReplacement(replacement);
+
+ while (source.length > 0) {
+ if (match = source.match(pattern)) {
+ result += source.slice(0, match.index);
+ result += (replacement(match) || '').toString();
+ source = source.slice(match.index + match[0].length);
+ } else {
+ result += source, source = '';
+ }
+ }
+ return result;
+ },
+
+ sub: function(pattern, replacement, count) {
+ replacement = this.gsub.prepareReplacement(replacement);
+ count = count === undefined ? 1 : count;
+
+ return this.gsub(pattern, function(match) {
+ if (--count < 0) return match[0];
+ return replacement(match);
+ });
+ },
+
+ scan: function(pattern, iterator) {
+ this.gsub(pattern, iterator);
+ return this;
+ },
+
+ truncate: function(length, truncation) {
+ length = length || 30;
+ truncation = truncation === undefined ? '...' : truncation;
+ return this.length > length ?
+ this.slice(0, length - truncation.length) + truncation : this;
+ },
+
+ strip: function() {
+ return this.replace(/^\s+/, '').replace(/\s+$/, '');
+ },
+
+ stripTags: function() {
+ return this.replace(/<\/?[^>]+>/gi, '');
+ },
+
+ stripScripts: function() {
+ return this.replace(new RegExp(Prototype.ScriptFragment, 'img'), '');
+ },
+
+ extractScripts: function() {
+ var matchAll = new RegExp(Prototype.ScriptFragment, 'img');
+ var matchOne = new RegExp(Prototype.ScriptFragment, 'im');
+ return (this.match(matchAll) || []).map(function(scriptTag) {
+ return (scriptTag.match(matchOne) || ['', ''])[1];
+ });
+ },
+
+ evalScripts: function() {
+ return this.extractScripts().map(function(script) { return eval(script) });
+ },
+
+ escapeHTML: function() {
+ var div = document.createElement('div');
+ var text = document.createTextNode(this);
+ div.appendChild(text);
+ return div.innerHTML;
+ },
+
+ unescapeHTML: function() {
+ var div = document.createElement('div');
+ div.innerHTML = this.stripTags();
+ return div.childNodes[0] ? div.childNodes[0].nodeValue : '';
+ },
+
+ toQueryParams: function() {
+ var pairs = this.match(/^\??(.*)$/)[1].split('&');
+ return pairs.inject({}, function(params, pairString) {
+ var pair = pairString.split('=');
+ params[pair[0]] = pair[1];
+ return params;
+ });
+ },
+
+ toArray: function() {
+ return this.split('');
+ },
+
+ camelize: function() {
+ var oStringList = this.split('-');
+ if (oStringList.length == 1) return oStringList[0];
+
+ var camelizedString = this.indexOf('-') == 0
+ ? oStringList[0].charAt(0).toUpperCase() + oStringList[0].substring(1)
+ : oStringList[0];
+
+ for (var i = 1, len = oStringList.length; i < len; i++) {
+ var s = oStringList[i];
+ camelizedString += s.charAt(0).toUpperCase() + s.substring(1);
+ }
+
+ return camelizedString;
+ },
+
+ inspect: function() {
+ return "'" + this.replace(/\\/g, '\\\\').replace(/'/g, '\\\'') + "'";
+ }
+});
+
+String.prototype.gsub.prepareReplacement = function(replacement) {
+ if (typeof replacement == 'function') return replacement;
+ var template = new Template(replacement);
+ return function(match) { return template.evaluate(match) };
+}
+
+String.prototype.parseQuery = String.prototype.toQueryParams;
+
+var Template = Class.create();
+Template.Pattern = /(^|.|\r|\n)(#\{(.*?)\})/;
+Template.prototype = {
+ initialize: function(template, pattern) {
+ this.template = template.toString();
+ this.pattern = pattern || Template.Pattern;
+ },
+
+ evaluate: function(object) {
+ return this.template.gsub(this.pattern, function(match) {
+ var before = match[1];
+ if (before == '\\') return match[2];
+ return before + (object[match[3]] || '').toString();
+ });
+ }
+}
+
+var $break = new Object();
+var $continue = new Object();
+
+var Enumerable = {
+ each: function(iterator) {
+ var index = 0;
+ try {
+ this._each(function(value) {
+ try {
+ iterator(value, index++);
+ } catch (e) {
+ if (e != $continue) throw e;
+ }
+ });
+ } catch (e) {
+ if (e != $break) throw e;
+ }
+ },
+
+ all: function(iterator) {
+ var result = true;
+ this.each(function(value, index) {
+ result = result && !!(iterator || Prototype.K)(value, index);
+ if (!result) throw $break;
+ });
+ return result;
+ },
+
+ any: function(iterator) {
+ var result = true;
+ this.each(function(value, index) {
+ if (result = !!(iterator || Prototype.K)(value, index))
+ throw $break;
+ });
+ return result;
+ },
+
+ collect: function(iterator) {
+ var results = [];
+ this.each(function(value, index) {
+ results.push(iterator(value, index));
+ });
+ return results;
+ },
+
+ detect: function (iterator) {
+ var result;
+ this.each(function(value, index) {
+ if (iterator(value, index)) {
+ result = value;
+ throw $break;
+ }
+ });
+ return result;
+ },
+
+ findAll: function(iterator) {
+ var results = [];
+ this.each(function(value, index) {
+ if (iterator(value, index))
+ results.push(value);
+ });
+ return results;
+ },
+
+ grep: function(pattern, iterator) {
+ var results = [];
+ this.each(function(value, index) {
+ var stringValue = value.toString();
+ if (stringValue.match(pattern))
+ results.push((iterator || Prototype.K)(value, index));
+ })
+ return results;
+ },
+
+ include: function(object) {
+ var found = false;
+ this.each(function(value) {
+ if (value == object) {
+ found = true;
+ throw $break;
+ }
+ });
+ return found;
+ },
+
+ inject: function(memo, iterator) {
+ this.each(function(value, index) {
+ memo = iterator(memo, value, index);
+ });
+ return memo;
+ },
+
+ invoke: function(method) {
+ var args = $A(arguments).slice(1);
+ return this.collect(function(value) {
+ return value[method].apply(value, args);
+ });
+ },
+
+ max: function(iterator) {
+ var result;
+ this.each(function(value, index) {
+ value = (iterator || Prototype.K)(value, index);
+ if (result == undefined || value >= result)
+ result = value;
+ });
+ return result;
+ },
+
+ min: function(iterator) {
+ var result;
+ this.each(function(value, index) {
+ value = (iterator || Prototype.K)(value, index);
+ if (result == undefined || value < result)
+ result = value;
+ });
+ return result;
+ },
+
+ partition: function(iterator) {
+ var trues = [], falses = [];
+ this.each(function(value, index) {
+ ((iterator || Prototype.K)(value, index) ?
+ trues : falses).push(value);
+ });
+ return [trues, falses];
+ },
+
+ pluck: function(property) {
+ var results = [];
+ this.each(function(value, index) {
+ results.push(value[property]);
+ });
+ return results;
+ },
+
+ reject: function(iterator) {
+ var results = [];
+ this.each(function(value, index) {
+ if (!iterator(value, index))
+ results.push(value);
+ });
+ return results;
+ },
+
+ sortBy: function(iterator) {
+ return this.collect(function(value, index) {
+ return {value: value, criteria: iterator(value, index)};
+ }).sort(function(left, right) {
+ var a = left.criteria, b = right.criteria;
+ return a < b ? -1 : a > b ? 1 : 0;
+ }).pluck('value');
+ },
+
+ toArray: function() {
+ return this.collect(Prototype.K);
+ },
+
+ zip: function() {
+ var iterator = Prototype.K, args = $A(arguments);
+ if (typeof args.last() == 'function')
+ iterator = args.pop();
+
+ var collections = [this].concat(args).map($A);
+ return this.map(function(value, index) {
+ return iterator(collections.pluck(index));
+ });
+ },
+
+ inspect: function() {
+ return '#<Enumerable:' + this.toArray().inspect() + '>';
+ }
+}
+
+Object.extend(Enumerable, {
+ map: Enumerable.collect,
+ find: Enumerable.detect,
+ select: Enumerable.findAll,
+ member: Enumerable.include,
+ entries: Enumerable.toArray
+});
+var $A = Array.from = function(iterable) {
+ if (!iterable) return [];
+ if (iterable.toArray) {
+ return iterable.toArray();
+ } else {
+ var results = [];
+ for (var i = 0; i < iterable.length; i++)
+ results.push(iterable[i]);
+ return results;
+ }
+}
+
+Object.extend(Array.prototype, Enumerable);
+
+if (!Array.prototype._reverse)
+ Array.prototype._reverse = Array.prototype.reverse;
+
+Object.extend(Array.prototype, {
+ _each: function(iterator) {
+ for (var i = 0; i < this.length; i++)
+ iterator(this[i]);
+ },
+
+ clear: function() {
+ this.length = 0;
+ return this;
+ },
+
+ first: function() {
+ return this[0];
+ },
+
+ last: function() {
+ return this[this.length - 1];
+ },
+
+ compact: function() {
+ return this.select(function(value) {
+ return value != undefined || value != null;
+ });
+ },
+
+ flatten: function() {
+ return this.inject([], function(array, value) {
+ return array.concat(value && value.constructor == Array ?
+ value.flatten() : [value]);
+ });
+ },
+
+ without: function() {
+ var values = $A(arguments);
+ return this.select(function(value) {
+ return !values.include(value);
+ });
+ },
+
+ indexOf: function(object) {
+ for (var i = 0; i < this.length; i++)
+ if (this[i] == object) return i;
+ return -1;
+ },
+
+ reverse: function(inline) {
+ return (inline !== false ? this : this.toArray())._reverse();
+ },
+
+ inspect: function() {
+ return '[' + this.map(Object.inspect).join(', ') + ']';
+ }
+});
+var Hash = {
+ _each: function(iterator) {
+ for (var key in this) {
+ var value = this[key];
+ if (typeof value == 'function') continue;
+
+ var pair = [key, value];
+ pair.key = key;
+ pair.value = value;
+ iterator(pair);
+ }
+ },
+
+ keys: function() {
+ return this.pluck('key');
+ },
+
+ values: function() {
+ return this.pluck('value');
+ },
+
+ merge: function(hash) {
+ return $H(hash).inject($H(this), function(mergedHash, pair) {
+ mergedHash[pair.key] = pair.value;
+ return mergedHash;
+ });
+ },
+
+ toQueryString: function() {
+ return this.map(function(pair) {
+ return pair.map(encodeURIComponent).join('=');
+ }).join('&');
+ },
+
+ inspect: function() {
+ return '#<Hash:{' + this.map(function(pair) {
+ return pair.map(Object.inspect).join(': ');
+ }).join(', ') + '}>';
+ }
+}
+
+function $H(object) {
+ var hash = Object.extend({}, object || {});
+ Object.extend(hash, Enumerable);
+ Object.extend(hash, Hash);
+ return hash;
+}
+ObjectRange = Class.create();
+Object.extend(ObjectRange.prototype, Enumerable);
+Object.extend(ObjectRange.prototype, {
+ initialize: function(start, end, exclusive) {
+ this.start = start;
+ this.end = end;
+ this.exclusive = exclusive;
+ },
+
+ _each: function(iterator) {
+ var value = this.start;
+ do {
+ iterator(value);
+ value = value.succ();
+ } while (this.include(value));
+ },
+
+ include: function(value) {
+ if (value < this.start)
+ return false;
+ if (this.exclusive)
+ return value < this.end;
+ return value <= this.end;
+ }
+});
+
+var $R = function(start, end, exclusive) {
+ return new ObjectRange(start, end, exclusive);
+}
+
+var Ajax = {
+ getTransport: function() {
+ return Try.these(
+ function() {return new XMLHttpRequest()},
+ function() {return new ActiveXObject('Msxml2.XMLHTTP')},
+ function() {return new ActiveXObject('Microsoft.XMLHTTP')}
+ ) || false;
+ },
+
+ activeRequestCount: 0
+}
+
+Ajax.Responders = {
+ responders: [],
+
+ _each: function(iterator) {
+ this.responders._each(iterator);
+ },
+
+ register: function(responderToAdd) {
+ if (!this.include(responderToAdd))
+ this.responders.push(responderToAdd);
+ },
+
+ unregister: function(responderToRemove) {
+ this.responders = this.responders.without(responderToRemove);
+ },
+
+ dispatch: function(callback, request, transport, json) {
+ this.each(function(responder) {
+ if (responder[callback] && typeof responder[callback] == 'function') {
+ try {
+ responder[callback].apply(responder, [request, transport, json]);
+ } catch (e) {}
+ }
+ });
+ }
+};
+
+Object.extend(Ajax.Responders, Enumerable);
+
+Ajax.Responders.register({
+ onCreate: function() {
+ Ajax.activeRequestCount++;
+ },
+
+ onComplete: function() {
+ Ajax.activeRequestCount--;
+ }
+});
+
+Ajax.Base = function() {};
+Ajax.Base.prototype = {
+ setOptions: function(options) {
+ this.options = {
+ method: 'post',
+ asynchronous: true,
+ contentType: 'application/x-www-form-urlencoded',
+ parameters: ''
+ }
+ Object.extend(this.options, options || {});
+ },
+
+ responseIsSuccess: function() {
+ return this.transport.status == undefined
+ || this.transport.status == 0
+ || (this.transport.status >= 200 && this.transport.status < 300);
+ },
+
+ responseIsFailure: function() {
+ return !this.responseIsSuccess();
+ }
+}
+
+Ajax.Request = Class.create();
+Ajax.Request.Events =
+ ['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete'];
+
+Ajax.Request.prototype = Object.extend(new Ajax.Base(), {
+ initialize: function(url, options) {
+ this.transport = Ajax.getTransport();
+ this.setOptions(options);
+ this.request(url);
+ },
+
+ request: function(url) {
+ var parameters = this.options.parameters || '';
+ if (parameters.length > 0) parameters += '&_=';
+
+ try {
+ this.url = url;
+ if (this.options.method == 'get' && parameters.length > 0)
+ this.url += (this.url.match(/\?/) ? '&' : '?') + parameters;
+
+ Ajax.Responders.dispatch('onCreate', this, this.transport);
+
+ this.transport.open(this.options.method, this.url,
+ this.options.asynchronous);
+
+ if (this.options.asynchronous) {
+ this.transport.onreadystatechange = this.onStateChange.bind(this);
+ setTimeout((function() {this.respondToReadyState(1)}).bind(this), 10);
+ }
+
+ this.setRequestHeaders();
+
+ var body = this.options.postBody ? this.options.postBody : parameters;
+ this.transport.send(this.options.method == 'post' ? body : null);
+
+ } catch (e) {
+ this.dispatchException(e);
+ }
+ },
+
+ setRequestHeaders: function() {
+ var requestHeaders =
+ ['X-Requested-With', 'XMLHttpRequest',
+ 'X-Prototype-Version', Prototype.Version,
+ 'Accept', 'text/javascript, text/html, application/xml, text/xml, */*'];
+
+ if (this.options.method == 'post') {
+ requestHeaders.push('Content-type', this.options.contentType);
+
+ /* Force "Connection: close" for Mozilla browsers to work around
+ * a bug where XMLHttpReqeuest sends an incorrect Content-length
+ * header. See Mozilla Bugzilla #246651.
+ */
+ if (this.transport.overrideMimeType)
+ requestHeaders.push('Connection', 'close');
+ }
+
+ if (this.options.requestHeaders)
+ requestHeaders.push.apply(requestHeaders, this.options.requestHeaders);
+
+ for (var i = 0; i < requestHeaders.length; i += 2)
+ this.transport.setRequestHeader(requestHeaders[i], requestHeaders[i+1]);
+ },
+
+ onStateChange: function() {
+ var readyState = this.transport.readyState;
+ if (readyState != 1)
+ this.respondToReadyState(this.transport.readyState);
+ },
+
+ header: function(name) {
+ try {
+ return this.transport.getResponseHeader(name);
+ } catch (e) {}
+ },
+
+ evalJSON: function() {
+ try {
+ return eval('(' + this.header('X-JSON') + ')');
+ } catch (e) {}
+ },
+
+ evalResponse: function() {
+ try {
+ return eval(this.transport.responseText);
+ } catch (e) {
+ this.dispatchException(e);
+ }
+ },
+
+ respondToReadyState: function(readyState) {
+ var event = Ajax.Request.Events[readyState];
+ var transport = this.transport, json = this.evalJSON();
+
+ if (event == 'Complete') {
+ try {
+ (this.options['on' + this.transport.status]
+ || this.options['on' + (this.responseIsSuccess() ? 'Success' : 'Failure')]
+ || Prototype.emptyFunction)(transport, json);
+ } catch (e) {
+ this.dispatchException(e);
+ }
+
+ if ((this.header('Content-type') || '').match(/^text\/javascript/i))
+ this.evalResponse();
+ }
+
+ try {
+ (this.options['on' + event] || Prototype.emptyFunction)(transport, json);
+ Ajax.Responders.dispatch('on' + event, this, transport, json);
+ } catch (e) {
+ this.dispatchException(e);
+ }
+
+ /* Avoid memory leak in MSIE: clean up the oncomplete event handler */
+ if (event == 'Complete')
+ this.transport.onreadystatechange = Prototype.emptyFunction;
+ },
+
+ dispatchException: function(exception) {
+ (this.options.onException || Prototype.emptyFunction)(this, exception);
+ Ajax.Responders.dispatch('onException', this, exception);
+ }
+});
+
+Ajax.Updater = Class.create();
+
+Object.extend(Object.extend(Ajax.Updater.prototype, Ajax.Request.prototype), {
+ initialize: function(container, url, options) {
+ this.containers = {
+ success: container.success ? $(container.success) : $(container),
+ failure: container.failure ? $(container.failure) :
+ (container.success ? null : $(container))
+ }
+
+ this.transport = Ajax.getTransport();
+ this.setOptions(options);
+
+ var onComplete = this.options.onComplete || Prototype.emptyFunction;
+ this.options.onComplete = (function(transport, object) {
+ this.updateContent();
+ onComplete(transport, object);
+ }).bind(this);
+
+ this.request(url);
+ },
+
+ updateContent: function() {
+ var receiver = this.responseIsSuccess() ?
+ this.containers.success : this.containers.failure;
+ var response = this.transport.responseText;
+
+ if (!this.options.evalScripts)
+ response = response.stripScripts();
+
+ if (receiver) {
+ if (this.options.insertion) {
+ new this.options.insertion(receiver, response);
+ } else {
+ Element.update(receiver, response);
+ }
+ }
+
+ if (this.responseIsSuccess()) {
+ if (this.onComplete)
+ setTimeout(this.onComplete.bind(this), 10);
+ }
+ }
+});
+
+Ajax.PeriodicalUpdater = Class.create();
+Ajax.PeriodicalUpdater.prototype = Object.extend(new Ajax.Base(), {
+ initialize: function(container, url, options) {
+ this.setOptions(options);
+ this.onComplete = this.options.onComplete;
+
+ this.frequency = (this.options.frequency || 2);
+ this.decay = (this.options.decay || 1);
+
+ this.updater = {};
+ this.container = container;
+ this.url = url;
+
+ this.start();
+ },
+
+ start: function() {
+ this.options.onComplete = this.updateComplete.bind(this);
+ this.onTimerEvent();
+ },
+
+ stop: function() {
+ this.updater.onComplete = undefined;
+ clearTimeout(this.timer);
+ (this.onComplete || Prototype.emptyFunction).apply(this, arguments);
+ },
+
+ updateComplete: function(request) {
+ if (this.options.decay) {
+ this.decay = (request.responseText == this.lastText ?
+ this.decay * this.options.decay : 1);
+
+ this.lastText = request.responseText;
+ }
+ this.timer = setTimeout(this.onTimerEvent.bind(this),
+ this.decay * this.frequency * 1000);
+ },
+
+ onTimerEvent: function() {
+ this.updater = new Ajax.Updater(this.container, this.url, this.options);
+ }
+});
+function $() {
+ var results = [], element;
+ for (var i = 0; i < arguments.length; i++) {
+ element = arguments[i];
+ if (typeof element == 'string')
+ element = document.getElementById(element);
+ results.push(Element.extend(element));
+ }
+ return results.length < 2 ? results[0] : results;
+}
+
+document.getElementsByClassName = function(className, parentElement) {
+ var children = ($(parentElement) || document.body).getElementsByTagName('*');
+ return $A(children).inject([], function(elements, child) {
+ if (child.className.match(new RegExp("(^|\\s)" + className + "(\\s|$)")))
+ elements.push(Element.extend(child));
+ return elements;
+ });
+}
+
+/*--------------------------------------------------------------------------*/
+
+if (!window.Element)
+ var Element = new Object();
+
+Element.extend = function(element) {
+ if (!element) return;
+ if (_nativeExtensions) return element;
+
+ if (!element._extended && element.tagName && element != window) {
+ var methods = Element.Methods, cache = Element.extend.cache;
+ for (property in methods) {
+ var value = methods[property];
+ if (typeof value == 'function')
+ element[property] = cache.findOrStore(value);
+ }
+ }
+
+ element._extended = true;
+ return element;
+}
+
+Element.extend.cache = {
+ findOrStore: function(value) {
+ return this[value] = this[value] || function() {
+ return value.apply(null, [this].concat($A(arguments)));
+ }
+ }
+}
+
+Element.Methods = {
+ visible: function(element) {
+ return $(element).style.display != 'none';
+ },
+
+ toggle: function() {
+ for (var i = 0; i < arguments.length; i++) {
+ var element = $(arguments[i]);
+ Element[Element.visible(element) ? 'hide' : 'show'](element);
+ }
+ },
+
+ hide: function() {
+ for (var i = 0; i < arguments.length; i++) {
+ var element = $(arguments[i]);
+ element.style.display = 'none';
+ }
+ },
+
+ show: function() {
+ for (var i = 0; i < arguments.length; i++) {
+ var element = $(arguments[i]);
+ element.style.display = '';
+ }
+ },
+
+ remove: function(element) {
+ element = $(element);
+ element.parentNode.removeChild(element);
+ },
+
+ update: function(element, html) {
+ $(element).innerHTML = html.stripScripts();
+ setTimeout(function() {html.evalScripts()}, 10);
+ },
+
+ replace: function(element, html) {
+ element = $(element);
+ if (element.outerHTML) {
+ element.outerHTML = html.stripScripts();
+ } else {
+ var range = element.ownerDocument.createRange();
+ range.selectNodeContents(element);
+ element.parentNode.replaceChild(
+ range.createContextualFragment(html.stripScripts()), element);
+ }
+ setTimeout(function() {html.evalScripts()}, 10);
+ },
+
+ getHeight: function(element) {
+ element = $(element);
+ return element.offsetHeight;
+ },
+
+ classNames: function(element) {
+ return new Element.ClassNames(element);
+ },
+
+ hasClassName: function(element, className) {
+ if (!(element = $(element))) return;
+ return Element.classNames(element).include(className);
+ },
+
+ addClassName: function(element, className) {
+ if (!(element = $(element))) return;
+ return Element.classNames(element).add(className);
+ },
+
+ removeClassName: function(element, className) {
+ if (!(element = $(element))) return;
+ return Element.classNames(element).remove(className);
+ },
+
+ // removes whitespace-only text node children
+ cleanWhitespace: function(element) {
+ element = $(element);
+ for (var i = 0; i < element.childNodes.length; i++) {
+ var node = element.childNodes[i];
+ if (node.nodeType == 3 && !/\S/.test(node.nodeValue))
+ Element.remove(node);
+ }
+ },
+
+ empty: function(element) {
+ return $(element).innerHTML.match(/^\s*$/);
+ },
+
+ childOf: function(element, ancestor) {
+ element = $(element), ancestor = $(ancestor);
+ while (element = element.parentNode)
+ if (element == ancestor) return true;
+ return false;
+ },
+
+ scrollTo: function(element) {
+ element = $(element);
+ var x = element.x ? element.x : element.offsetLeft,
+ y = element.y ? element.y : element.offsetTop;
+ window.scrollTo(x, y);
+ },
+
+ getStyle: function(element, style) {
+ element = $(element);
+ var value = element.style[style.camelize()];
+ if (!value) {
+ if (document.defaultView && document.defaultView.getComputedStyle) {
+ var css = document.defaultView.getComputedStyle(element, null);
+ value = css ? css.getPropertyValue(style) : null;
+ } else if (element.currentStyle) {
+ value = element.currentStyle[style.camelize()];
+ }
+ }
+
+ if (window.opera && ['left', 'top', 'right', 'bottom'].include(style))
+ if (Element.getStyle(element, 'position') == 'static') value = 'auto';
+
+ return value == 'auto' ? null : value;
+ },
+
+ setStyle: function(element, style) {
+ element = $(element);
+ for (var name in style)
+ element.style[name.camelize()] = style[name];
+ },
+
+ getDimensions: function(element) {
+ element = $(element);
+ if (Element.getStyle(element, 'display') != 'none')
+ return {width: element.offsetWidth, height: element.offsetHeight};
+
+ // All *Width and *Height properties give 0 on elements with display none,
+ // so enable the element temporarily
+ var els = element.style;
+ var originalVisibility = els.visibility;
+ var originalPosition = els.position;
+ els.visibility = 'hidden';
+ els.position = 'absolute';
+ els.display = '';
+ var originalWidth = element.clientWidth;
+ var originalHeight = element.clientHeight;
+ els.display = 'none';
+ els.position = originalPosition;
+ els.visibility = originalVisibility;
+ return {width: originalWidth, height: originalHeight};
+ },
+
+ makePositioned: function(element) {
+ element = $(element);
+ var pos = Element.getStyle(element, 'position');
+ if (pos == 'static' || !pos) {
+ element._madePositioned = true;
+ element.style.position = 'relative';
+ // Opera returns the offset relative to the positioning context, when an
+ // element is position relative but top and left have not been defined
+ if (window.opera) {
+ element.style.top = 0;
+ element.style.left = 0;
+ }
+ }
+ },
+
+ undoPositioned: function(element) {
+ element = $(element);
+ if (element._madePositioned) {
+ element._madePositioned = undefined;
+ element.style.position =
+ element.style.top =
+ element.style.left =
+ element.style.bottom =
+ element.style.right = '';
+ }
+ },
+
+ makeClipping: function(element) {
+ element = $(element);
+ if (element._overflow) return;
+ element._overflow = element.style.overflow;
+ if ((Element.getStyle(element, 'overflow') || 'visible') != 'hidden')
+ element.style.overflow = 'hidden';
+ },
+
+ undoClipping: function(element) {
+ element = $(element);
+ if (element._overflow) return;
+ element.style.overflow = element._overflow;
+ element._overflow = undefined;
+ }
+}
+
+Object.extend(Element, Element.Methods);
+
+var _nativeExtensions = false;
+
+if(!HTMLElement && /Konqueror|Safari|KHTML/.test(navigator.userAgent)) {
+ var HTMLElement = {}
+ HTMLElement.prototype = document.createElement('div').__proto__;
+}
+
+Element.addMethods = function(methods) {
+ Object.extend(Element.Methods, methods || {});
+
+ if(typeof HTMLElement != 'undefined') {
+ var methods = Element.Methods, cache = Element.extend.cache;
+ for (property in methods) {
+ var value = methods[property];
+ if (typeof value == 'function')
+ HTMLElement.prototype[property] = cache.findOrStore(value);
+ }
+ _nativeExtensions = true;
+ }
+}
+
+Element.addMethods();
+
+var Toggle = new Object();
+Toggle.display = Element.toggle;
+
+/*--------------------------------------------------------------------------*/
+
+Abstract.Insertion = function(adjacency) {
+ this.adjacency = adjacency;
+}
+
+Abstract.Insertion.prototype = {
+ initialize: function(element, content) {
+ this.element = $(element);
+ this.content = content.stripScripts();
+
+ if (this.adjacency && this.element.insertAdjacentHTML) {
+ try {
+ this.element.insertAdjacentHTML(this.adjacency, this.content);
+ } catch (e) {
+ var tagName = this.element.tagName.toLowerCase();
+ if (tagName == 'tbody' || tagName == 'tr') {
+ this.insertContent(this.contentFromAnonymousTable());
+ } else {
+ throw e;
+ }
+ }
+ } else {
+ this.range = this.element.ownerDocument.createRange();
+ if (this.initializeRange) this.initializeRange();
+ this.insertContent([this.range.createContextualFragment(this.content)]);
+ }
+
+ setTimeout(function() {content.evalScripts()}, 10);
+ },
+
+ contentFromAnonymousTable: function() {
+ var div = document.createElement('div');
+ div.innerHTML = '<table><tbody>' + this.content + '</tbody></table>';
+ return $A(div.childNodes[0].childNodes[0].childNodes);
+ }
+}
+
+var Insertion = new Object();
+
+Insertion.Before = Class.create();
+Insertion.Before.prototype = Object.extend(new Abstract.Insertion('beforeBegin'), {
+ initializeRange: function() {
+ this.range.setStartBefore(this.element);
+ },
+
+ insertContent: function(fragments) {
+ fragments.each((function(fragment) {
+ this.element.parentNode.insertBefore(fragment, this.element);
+ }).bind(this));
+ }
+});
+
+Insertion.Top = Class.create();
+Insertion.Top.prototype = Object.extend(new Abstract.Insertion('afterBegin'), {
+ initializeRange: function() {
+ this.range.selectNodeContents(this.element);
+ this.range.collapse(true);
+ },
+
+ insertContent: function(fragments) {
+ fragments.reverse(false).each((function(fragment) {
+ this.element.insertBefore(fragment, this.element.firstChild);
+ }).bind(this));
+ }
+});
+
+Insertion.Bottom = Class.create();
+Insertion.Bottom.prototype = Object.extend(new Abstract.Insertion('beforeEnd'), {
+ initializeRange: function() {
+ this.range.selectNodeContents(this.element);
+ this.range.collapse(this.element);
+ },
+
+ insertContent: function(fragments) {
+ fragments.each((function(fragment) {
+ this.element.appendChild(fragment);
+ }).bind(this));
+ }
+});
+
+Insertion.After = Class.create();
+Insertion.After.prototype = Object.extend(new Abstract.Insertion('afterEnd'), {
+ initializeRange: function() {
+ this.range.setStartAfter(this.element);
+ },
+
+ insertContent: function(fragments) {
+ fragments.each((function(fragment) {
+ this.element.parentNode.insertBefore(fragment,
+ this.element.nextSibling);
+ }).bind(this));
+ }
+});
+
+/*--------------------------------------------------------------------------*/
+
+Element.ClassNames = Class.create();
+Element.ClassNames.prototype = {
+ initialize: function(element) {
+ this.element = $(element);
+ },
+
+ _each: function(iterator) {
+ this.element.className.split(/\s+/).select(function(name) {
+ return name.length > 0;
+ })._each(iterator);
+ },
+
+ set: function(className) {
+ this.element.className = className;
+ },
+
+ add: function(classNameToAdd) {
+ if (this.include(classNameToAdd)) return;
+ this.set(this.toArray().concat(classNameToAdd).join(' '));
+ },
+
+ remove: function(classNameToRemove) {
+ if (!this.include(classNameToRemove)) return;
+ this.set(this.select(function(className) {
+ return className != classNameToRemove;
+ }).join(' '));
+ },
+
+ toString: function() {
+ return this.toArray().join(' ');
+ }
+}
+
+Object.extend(Element.ClassNames.prototype, Enumerable);
+var Selector = Class.create();
+Selector.prototype = {
+ initialize: function(expression) {
+ this.params = {classNames: []};
+ this.expression = expression.toString().strip();
+ this.parseExpression();
+ this.compileMatcher();
+ },
+
+ parseExpression: function() {
+ function abort(message) { throw 'Parse error in selector: ' + message; }
+
+ if (this.expression == '') abort('empty expression');
+
+ var params = this.params, expr = this.expression, match, modifier, clause, rest;
+ while (match = expr.match(/^(.*)\[([a-z0-9_:-]+?)(?:([~\|!]?=)(?:"([^"]*)"|([^\]\s]*)))?\]$/i)) {
+ params.attributes = params.attributes || [];
+ params.attributes.push({name: match[2], operator: match[3], value: match[4] || match[5] || ''});
+ expr = match[1];
+ }
+
+ if (expr == '*') return this.params.wildcard = true;
+
+ while (match = expr.match(/^([^a-z0-9_-])?([a-z0-9_-]+)(.*)/i)) {
+ modifier = match[1], clause = match[2], rest = match[3];
+ switch (modifier) {
+ case '#': params.id = clause; break;
+ case '.': params.classNames.push(clause); break;
+ case '':
+ case undefined: params.tagName = clause.toUpperCase(); break;
+ default: abort(expr.inspect());
+ }
+ expr = rest;
+ }
+
+ if (expr.length > 0) abort(expr.inspect());
+ },
+
+ buildMatchExpression: function() {
+ var params = this.params, conditions = [], clause;
+
+ if (params.wildcard)
+ conditions.push('true');
+ if (clause = params.id)
+ conditions.push('element.id == ' + clause.inspect());
+ if (clause = params.tagName)
+ conditions.push('element.tagName.toUpperCase() == ' + clause.inspect());
+ if ((clause = params.classNames).length > 0)
+ for (var i = 0; i < clause.length; i++)
+ conditions.push('Element.hasClassName(element, ' + clause[i].inspect() + ')');
+ if (clause = params.attributes) {
+ clause.each(function(attribute) {
+ var value = 'element.getAttribute(' + attribute.name.inspect() + ')';
+ var splitValueBy = function(delimiter) {
+ return value + ' && ' + value + '.split(' + delimiter.inspect() + ')';
+ }
+
+ switch (attribute.operator) {
+ case '=': conditions.push(value + ' == ' + attribute.value.inspect()); break;
+ case '~=': conditions.push(splitValueBy(' ') + '.include(' + attribute.value.inspect() + ')'); break;
+ case '|=': conditions.push(
+ splitValueBy('-') + '.first().toUpperCase() == ' + attribute.value.toUpperCase().inspect()
+ ); break;
+ case '!=': conditions.push(value + ' != ' + attribute.value.inspect()); break;
+ case '':
+ case undefined: conditions.push(value + ' != null'); break;
+ default: throw 'Unknown operator ' + attribute.operator + ' in selector';
+ }
+ });
+ }
+
+ return conditions.join(' && ');
+ },
+
+ compileMatcher: function() {
+ this.match = new Function('element', 'if (!element.tagName) return false; \
+ return ' + this.buildMatchExpression());
+ },
+
+ findElements: function(scope) {
+ var element;
+
+ if (element = $(this.params.id))
+ if (this.match(element))
+ if (!scope || Element.childOf(element, scope))
+ return [element];
+
+ scope = (scope || document).getElementsByTagName(this.params.tagName || '*');
+
+ var results = [];
+ for (var i = 0; i < scope.length; i++)
+ if (this.match(element = scope[i]))
+ results.push(Element.extend(element));
+
+ return results;
+ },
+
+ toString: function() {
+ return this.expression;
+ }
+}
+
+function $$() {
+ return $A(arguments).map(function(expression) {
+ return expression.strip().split(/\s+/).inject([null], function(results, expr) {
+ var selector = new Selector(expr);
+ return results.map(selector.findElements.bind(selector)).flatten();
+ });
+ }).flatten();
+}
+var Field = {
+ clear: function() {
+ for (var i = 0; i < arguments.length; i++)
+ $(arguments[i]).value = '';
+ },
+
+ focus: function(element) {
+ $(element).focus();
+ },
+
+ present: function() {
+ for (var i = 0; i < arguments.length; i++)
+ if ($(arguments[i]).value == '') return false;
+ return true;
+ },
+
+ select: function(element) {
+ $(element).select();
+ },
+
+ activate: function(element) {
+ element = $(element);
+ element.focus();
+ if (element.select)
+ element.select();
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+var Form = {
+ serialize: function(form) {
+ var elements = Form.getElements($(form));
+ var queryComponents = new Array();
+
+ for (var i = 0; i < elements.length; i++) {
+ var queryComponent = Form.Element.serialize(elements[i]);
+ if (queryComponent)
+ queryComponents.push(queryComponent);
+ }
+
+ return queryComponents.join('&');
+ },
+
+ getElements: function(form) {
+ form = $(form);
+ var elements = new Array();
+
+ for (var tagName in Form.Element.Serializers) {
+ var tagElements = form.getElementsByTagName(tagName);
+ for (var j = 0; j < tagElements.length; j++)
+ elements.push(tagElements[j]);
+ }
+ return elements;
+ },
+
+ getInputs: function(form, typeName, name) {
+ form = $(form);
+ var inputs = form.getElementsByTagName('input');
+
+ if (!typeName && !name)
+ return inputs;
+
+ var matchingInputs = new Array();
+ for (var i = 0; i < inputs.length; i++) {
+ var input = inputs[i];
+ if ((typeName && input.type != typeName) ||
+ (name && input.name != name))
+ continue;
+ matchingInputs.push(input);
+ }
+
+ return matchingInputs;
+ },
+
+ disable: function(form) {
+ var elements = Form.getElements(form);
+ for (var i = 0; i < elements.length; i++) {
+ var element = elements[i];
+ element.blur();
+ element.disabled = 'true';
+ }
+ },
+
+ enable: function(form) {
+ var elements = Form.getElements(form);
+ for (var i = 0; i < elements.length; i++) {
+ var element = elements[i];
+ element.disabled = '';
+ }
+ },
+
+ findFirstElement: function(form) {
+ return Form.getElements(form).find(function(element) {
+ return element.type != 'hidden' && !element.disabled &&
+ ['input', 'select', 'textarea'].include(element.tagName.toLowerCase());
+ });
+ },
+
+ focusFirstElement: function(form) {
+ Field.activate(Form.findFirstElement(form));
+ },
+
+ reset: function(form) {
+ $(form).reset();
+ }
+}
+
+Form.Element = {
+ serialize: function(element) {
+ element = $(element);
+ var method = element.tagName.toLowerCase();
+ var parameter = Form.Element.Serializers[method](element);
+
+ if (parameter) {
+ var key = encodeURIComponent(parameter[0]);
+ if (key.length == 0) return;
+
+ if (parameter[1].constructor != Array)
+ parameter[1] = [parameter[1]];
+
+ return parameter[1].map(function(value) {
+ return key + '=' + encodeURIComponent(value);
+ }).join('&');
+ }
+ },
+
+ getValue: function(element) {
+ element = $(element);
+ var method = element.tagName.toLowerCase();
+ var parameter = Form.Element.Serializers[method](element);
+
+ if (parameter)
+ return parameter[1];
+ }
+}
+
+Form.Element.Serializers = {
+ input: function(element) {
+ switch (element.type.toLowerCase()) {
+ case 'submit':
+ case 'hidden':
+ case 'password':
+ case 'text':
+ return Form.Element.Serializers.textarea(element);
+ case 'checkbox':
+ case 'radio':
+ return Form.Element.Serializers.inputSelector(element);
+ }
+ return false;
+ },
+
+ inputSelector: function(element) {
+ if (element.checked)
+ return [element.name, element.value];
+ },
+
+ textarea: function(element) {
+ return [element.name, element.value];
+ },
+
+ select: function(element) {
+ return Form.Element.Serializers[element.type == 'select-one' ?
+ 'selectOne' : 'selectMany'](element);
+ },
+
+ selectOne: function(element) {
+ var value = '', opt, index = element.selectedIndex;
+ if (index >= 0) {
+ opt = element.options[index];
+ value = opt.value || opt.text;
+ }
+ return [element.name, value];
+ },
+
+ selectMany: function(element) {
+ var value = [];
+ for (var i = 0; i < element.length; i++) {
+ var opt = element.options[i];
+ if (opt.selected)
+ value.push(opt.value || opt.text);
+ }
+ return [element.name, value];
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+var $F = Form.Element.getValue;
+
+/*--------------------------------------------------------------------------*/
+
+Abstract.TimedObserver = function() {}
+Abstract.TimedObserver.prototype = {
+ initialize: function(element, frequency, callback) {
+ this.frequency = frequency;
+ this.element = $(element);
+ this.callback = callback;
+
+ this.lastValue = this.getValue();
+ this.registerCallback();
+ },
+
+ registerCallback: function() {
+ setInterval(this.onTimerEvent.bind(this), this.frequency * 1000);
+ },
+
+ onTimerEvent: function() {
+ var value = this.getValue();
+ if (this.lastValue != value) {
+ this.callback(this.element, value);
+ this.lastValue = value;
+ }
+ }
+}
+
+Form.Element.Observer = Class.create();
+Form.Element.Observer.prototype = Object.extend(new Abstract.TimedObserver(), {
+ getValue: function() {
+ return Form.Element.getValue(this.element);
+ }
+});
+
+Form.Observer = Class.create();
+Form.Observer.prototype = Object.extend(new Abstract.TimedObserver(), {
+ getValue: function() {
+ return Form.serialize(this.element);
+ }
+});
+
+/*--------------------------------------------------------------------------*/
+
+Abstract.EventObserver = function() {}
+Abstract.EventObserver.prototype = {
+ initialize: function(element, callback) {
+ this.element = $(element);
+ this.callback = callback;
+
+ this.lastValue = this.getValue();
+ if (this.element.tagName.toLowerCase() == 'form')
+ this.registerFormCallbacks();
+ else
+ this.registerCallback(this.element);
+ },
+
+ onElementEvent: function() {
+ var value = this.getValue();
+ if (this.lastValue != value) {
+ this.callback(this.element, value);
+ this.lastValue = value;
+ }
+ },
+
+ registerFormCallbacks: function() {
+ var elements = Form.getElements(this.element);
+ for (var i = 0; i < elements.length; i++)
+ this.registerCallback(elements[i]);
+ },
+
+ registerCallback: function(element) {
+ if (element.type) {
+ switch (element.type.toLowerCase()) {
+ case 'checkbox':
+ case 'radio':
+ Event.observe(element, 'click', this.onElementEvent.bind(this));
+ break;
+ case 'password':
+ case 'text':
+ case 'textarea':
+ case 'select-one':
+ case 'select-multiple':
+ Event.observe(element, 'change', this.onElementEvent.bind(this));
+ break;
+ }
+ }
+ }
+}
+
+Form.Element.EventObserver = Class.create();
+Form.Element.EventObserver.prototype = Object.extend(new Abstract.EventObserver(), {
+ getValue: function() {
+ return Form.Element.getValue(this.element);
+ }
+});
+
+Form.EventObserver = Class.create();
+Form.EventObserver.prototype = Object.extend(new Abstract.EventObserver(), {
+ getValue: function() {
+ return Form.serialize(this.element);
+ }
+});
+if (!window.Event) {
+ var Event = new Object();
+}
+
+Object.extend(Event, {
+ KEY_BACKSPACE: 8,
+ KEY_TAB: 9,
+ KEY_RETURN: 13,
+ KEY_ESC: 27,
+ KEY_LEFT: 37,
+ KEY_UP: 38,
+ KEY_RIGHT: 39,
+ KEY_DOWN: 40,
+ KEY_DELETE: 46,
+
+ element: function(event) {
+ return event.target || event.srcElement;
+ },
+
+ isLeftClick: function(event) {
+ return (((event.which) && (event.which == 1)) ||
+ ((event.button) && (event.button == 1)));
+ },
+
+ pointerX: function(event) {
+ return event.pageX || (event.clientX +
+ (document.documentElement.scrollLeft || document.body.scrollLeft));
+ },
+
+ pointerY: function(event) {
+ return event.pageY || (event.clientY +
+ (document.documentElement.scrollTop || document.body.scrollTop));
+ },
+
+ stop: function(event) {
+ if (event.preventDefault) {
+ event.preventDefault();
+ event.stopPropagation();
+ } else {
+ event.returnValue = false;
+ event.cancelBubble = true;
+ }
+ },
+
+ // find the first node with the given tagName, starting from the
+ // node the event was triggered on; traverses the DOM upwards
+ findElement: function(event, tagName) {
+ var element = Event.element(event);
+ while (element.parentNode && (!element.tagName ||
+ (element.tagName.toUpperCase() != tagName.toUpperCase())))
+ element = element.parentNode;
+ return element;
+ },
+
+ observers: false,
+
+ _observeAndCache: function(element, name, observer, useCapture) {
+ if (!this.observers) this.observers = [];
+ if (element.addEventListener) {
+ this.observers.push([element, name, observer, useCapture]);
+ element.addEventListener(name, observer, useCapture);
+ } else if (element.attachEvent) {
+ this.observers.push([element, name, observer, useCapture]);
+ element.attachEvent('on' + name, observer);
+ }
+ },
+
+ unloadCache: function() {
+ if (!Event.observers) return;
+ for (var i = 0; i < Event.observers.length; i++) {
+ Event.stopObserving.apply(this, Event.observers[i]);
+ Event.observers[i][0] = null;
+ }
+ Event.observers = false;
+ },
+
+ observe: function(element, name, observer, useCapture) {
+ var element = $(element);
+ useCapture = useCapture || false;
+
+ if (name == 'keypress' &&
+ (navigator.appVersion.match(/Konqueror|Safari|KHTML/)
+ || element.attachEvent))
+ name = 'keydown';
+
+ this._observeAndCache(element, name, observer, useCapture);
+ },
+
+ stopObserving: function(element, name, observer, useCapture) {
+ var element = $(element);
+ useCapture = useCapture || false;
+
+ if (name == 'keypress' &&
+ (navigator.appVersion.match(/Konqueror|Safari|KHTML/)
+ || element.detachEvent))
+ name = 'keydown';
+
+ if (element.removeEventListener) {
+ element.removeEventListener(name, observer, useCapture);
+ } else if (element.detachEvent) {
+ element.detachEvent('on' + name, observer);
+ }
+ }
+});
+
+/* prevent memory leaks in IE */
+if (navigator.appVersion.match(/\bMSIE\b/))
+ Event.observe(window, 'unload', Event.unloadCache, false);
+var Position = {
+ // set to true if needed, warning: firefox performance problems
+ // NOT neeeded for page scrolling, only if draggable contained in
+ // scrollable elements
+ includeScrollOffsets: false,
+
+ // must be called before calling withinIncludingScrolloffset, every time the
+ // page is scrolled
+ prepare: function() {
+ this.deltaX = window.pageXOffset
+ || document.documentElement.scrollLeft
+ || document.body.scrollLeft
+ || 0;
+ this.deltaY = window.pageYOffset
+ || document.documentElement.scrollTop
+ || document.body.scrollTop
+ || 0;
+ },
+
+ realOffset: function(element) {
+ var valueT = 0, valueL = 0;
+ do {
+ valueT += element.scrollTop || 0;
+ valueL += element.scrollLeft || 0;
+ element = element.parentNode;
+ } while (element);
+ return [valueL, valueT];
+ },
+
+ cumulativeOffset: function(element) {
+ var valueT = 0, valueL = 0;
+ do {
+ valueT += element.offsetTop || 0;
+ valueL += element.offsetLeft || 0;
+ element = element.offsetParent;
+ } while (element);
+ return [valueL, valueT];
+ },
+
+ positionedOffset: function(element) {
+ var valueT = 0, valueL = 0;
+ do {
+ valueT += element.offsetTop || 0;
+ valueL += element.offsetLeft || 0;
+ element = element.offsetParent;
+ if (element) {
+ p = Element.getStyle(element, 'position');
+ if (p == 'relative' || p == 'absolute') break;
+ }
+ } while (element);
+ return [valueL, valueT];
+ },
+
+ offsetParent: function(element) {
+ if (element.offsetParent) return element.offsetParent;
+ if (element == document.body) return element;
+
+ while ((element = element.parentNode) && element != document.body)
+ if (Element.getStyle(element, 'position') != 'static')
+ return element;
+
+ return document.body;
+ },
+
+ // caches x/y coordinate pair to use with overlap
+ within: function(element, x, y) {
+ if (this.includeScrollOffsets)
+ return this.withinIncludingScrolloffsets(element, x, y);
+ this.xcomp = x;
+ this.ycomp = y;
+ this.offset = this.cumulativeOffset(element);
+
+ return (y >= this.offset[1] &&
+ y < this.offset[1] + element.offsetHeight &&
+ x >= this.offset[0] &&
+ x < this.offset[0] + element.offsetWidth);
+ },
+
+ withinIncludingScrolloffsets: function(element, x, y) {
+ var offsetcache = this.realOffset(element);
+
+ this.xcomp = x + offsetcache[0] - this.deltaX;
+ this.ycomp = y + offsetcache[1] - this.deltaY;
+ this.offset = this.cumulativeOffset(element);
+
+ return (this.ycomp >= this.offset[1] &&
+ this.ycomp < this.offset[1] + element.offsetHeight &&
+ this.xcomp >= this.offset[0] &&
+ this.xcomp < this.offset[0] + element.offsetWidth);
+ },
+
+ // within must be called directly before
+ overlap: function(mode, element) {
+ if (!mode) return 0;
+ if (mode == 'vertical')
+ return ((this.offset[1] + element.offsetHeight) - this.ycomp) /
+ element.offsetHeight;
+ if (mode == 'horizontal')
+ return ((this.offset[0] + element.offsetWidth) - this.xcomp) /
+ element.offsetWidth;
+ },
+
+ clone: function(source, target) {
+ source = $(source);
+ target = $(target);
+ target.style.position = 'absolute';
+ var offsets = this.cumulativeOffset(source);
+ target.style.top = offsets[1] + 'px';
+ target.style.left = offsets[0] + 'px';
+ target.style.width = source.offsetWidth + 'px';
+ target.style.height = source.offsetHeight + 'px';
+ },
+
+ page: function(forElement) {
+ var valueT = 0, valueL = 0;
+
+ var element = forElement;
+ do {
+ valueT += element.offsetTop || 0;
+ valueL += element.offsetLeft || 0;
+
+ // Safari fix
+ if (element.offsetParent==document.body)
+ if (Element.getStyle(element,'position')=='absolute') break;
+
+ } while (element = element.offsetParent);
+
+ element = forElement;
+ do {
+ valueT -= element.scrollTop || 0;
+ valueL -= element.scrollLeft || 0;
+ } while (element = element.parentNode);
+
+ return [valueL, valueT];
+ },
+
+ clone: function(source, target) {
+ var options = Object.extend({
+ setLeft: true,
+ setTop: true,
+ setWidth: true,
+ setHeight: true,
+ offsetTop: 0,
+ offsetLeft: 0
+ }, arguments[2] || {})
+
+ // find page position of source
+ source = $(source);
+ var p = Position.page(source);
+
+ // find coordinate system to use
+ target = $(target);
+ var delta = [0, 0];
+ var parent = null;
+ // delta [0,0] will do fine with position: fixed elements,
+ // position:absolute needs offsetParent deltas
+ if (Element.getStyle(target,'position') == 'absolute') {
+ parent = Position.offsetParent(target);
+ delta = Position.page(parent);
+ }
+
+ // correct by body offsets (fixes Safari)
+ if (parent == document.body) {
+ delta[0] -= document.body.offsetLeft;
+ delta[1] -= document.body.offsetTop;
+ }
+
+ // set position
+ if(options.setLeft) target.style.left = (p[0] - delta[0] + options.offsetLeft) + 'px';
+ if(options.setTop) target.style.top = (p[1] - delta[1] + options.offsetTop) + 'px';
+ if(options.setWidth) target.style.width = source.offsetWidth + 'px';
+ if(options.setHeight) target.style.height = source.offsetHeight + 'px';
+ },
+
+ absolutize: function(element) {
+ element = $(element);
+ if (element.style.position == 'absolute') return;
+ Position.prepare();
+
+ var offsets = Position.positionedOffset(element);
+ var top = offsets[1];
+ var left = offsets[0];
+ var width = element.clientWidth;
+ var height = element.clientHeight;
+
+ element._originalLeft = left - parseFloat(element.style.left || 0);
+ element._originalTop = top - parseFloat(element.style.top || 0);
+ element._originalWidth = element.style.width;
+ element._originalHeight = element.style.height;
+
+ element.style.position = 'absolute';
+ element.style.top = top + 'px';;
+ element.style.left = left + 'px';;
+ element.style.width = width + 'px';;
+ element.style.height = height + 'px';;
+ },
+
+ relativize: function(element) {
+ element = $(element);
+ if (element.style.position == 'relative') return;
+ Position.prepare();
+
+ element.style.position = 'relative';
+ var top = parseFloat(element.style.top || 0) - (element._originalTop || 0);
+ var left = parseFloat(element.style.left || 0) - (element._originalLeft || 0);
+
+ element.style.top = top + 'px';
+ element.style.left = left + 'px';
+ element.style.height = element._originalHeight;
+ element.style.width = element._originalWidth;
+ }
+}
+
+// Safari returns margins on body which is incorrect if the child is absolutely
+// positioned. For performance reasons, redefine Position.cumulativeOffset for
+// KHTML/WebKit only.
+if (/Konqueror|Safari|KHTML/.test(navigator.userAgent)) {
+ Position.cumulativeOffset = function(element) {
+ var valueT = 0, valueL = 0;
+ do {
+ valueT += element.offsetTop || 0;
+ valueL += element.offsetLeft || 0;
+ if (element.offsetParent == document.body)
+ if (Element.getStyle(element, 'position') == 'absolute') break;
+
+ element = element.offsetParent;
+ } while (element);
+
+ return [valueL, valueT];
+ }
+} \ No newline at end of file
diff --git a/site/app/webroot/js/scriptaculous/scriptaculous.js b/site/app/webroot/js/scriptaculous/scriptaculous.js
new file mode 100644
index 0000000..e9abf14
--- /dev/null
+++ b/site/app/webroot/js/scriptaculous/scriptaculous.js
@@ -0,0 +1,47 @@
+// Copyright (c) 2005 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+var Scriptaculous = {
+ Version: '1.6.2',
+ require: function(libraryName) {
+ // inserting via DOM fails in Safari 2.0, so brute force approach
+ document.write('<script type="text/javascript" src="'+libraryName+'"></script>');
+ },
+ load: function() {
+ if((typeof Prototype=='undefined') ||
+ (typeof Element == 'undefined') ||
+ (typeof Element.Methods=='undefined') ||
+ parseFloat(Prototype.Version.split(".")[0] + "." +
+ Prototype.Version.split(".")[1]) < 1.5)
+ throw("script.aculo.us requires the Prototype JavaScript framework >= 1.5.0");
+
+ $A(document.getElementsByTagName("script")).findAll( function(s) {
+ return (s.src && s.src.match(/scriptaculous\.js(\?.*)?$/))
+ }).each( function(s) {
+ var path = s.src.replace(/scriptaculous\.js(\?.*)?$/,'');
+ var includes = s.src.match(/\?.*load=([a-z,]*)/);
+ (includes ? includes[1] : 'builder,effects,dragdrop,controls,slider').split(',').each(
+ function(include) { Scriptaculous.require(path+include+'.js') });
+ });
+ }
+}
+
+Scriptaculous.load(); \ No newline at end of file
diff --git a/site/app/webroot/js/scriptaculous/slider.js b/site/app/webroot/js/scriptaculous/slider.js
new file mode 100644
index 0000000..696992c
--- /dev/null
+++ b/site/app/webroot/js/scriptaculous/slider.js
@@ -0,0 +1,292 @@
+// Copyright (c) 2005 Marty Haught, Thomas Fuchs
+//
+// See http://script.aculo.us for more info
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+if(!Control) var Control = {};
+Control.Slider = Class.create();
+
+// options:
+// axis: 'vertical', or 'horizontal' (default)
+//
+// callbacks:
+// onChange(value)
+// onSlide(value)
+Control.Slider.prototype = {
+ initialize: function(handle, track, options) {
+ var slider = this;
+
+ if(handle instanceof Array) {
+ this.handles = handle.collect( function(e) { return $(e) });
+ } else {
+ this.handles = [$(handle)];
+ }
+
+ this.track = $(track);
+ this.options = options || {};
+
+ this.axis = this.options.axis || 'horizontal';
+ this.increment = this.options.increment || 1;
+ this.step = parseInt(this.options.step || '1');
+ this.range = this.options.range || $R(0,1);
+
+ this.value = 0; // assure backwards compat
+ this.values = this.handles.map( function() { return 0 });
+ this.spans = this.options.spans ? this.options.spans.map(function(s){ return $(s) }) : false;
+ this.options.startSpan = $(this.options.startSpan || null);
+ this.options.endSpan = $(this.options.endSpan || null);
+
+ this.restricted = this.options.restricted || false;
+
+ this.maximum = this.options.maximum || this.range.end;
+ this.minimum = this.options.minimum || this.range.start;
+
+ // Will be used to align the handle onto the track, if necessary
+ this.alignX = parseInt(this.options.alignX || '0');
+ this.alignY = parseInt(this.options.alignY || '0');
+
+ this.trackLength = this.maximumOffset() - this.minimumOffset();
+
+ this.handleLength = this.isVertical() ?
+ (this.handles[0].offsetHeight != 0 ?
+ this.handles[0].offsetHeight : this.handles[0].style.height.replace(/px$/,"")) :
+ (this.handles[0].offsetWidth != 0 ? this.handles[0].offsetWidth :
+ this.handles[0].style.width.replace(/px$/,""));
+
+ this.active = false;
+ this.dragging = false;
+ this.disabled = false;
+
+ if(this.options.disabled) this.setDisabled();
+
+ // Allowed values array
+ this.allowedValues = this.options.values ? this.options.values.sortBy(Prototype.K) : false;
+ if(this.allowedValues) {
+ this.minimum = this.allowedValues.min();
+ this.maximum = this.allowedValues.max();
+ }
+
+ this.eventMouseDown = this.startDrag.bindAsEventListener(this);
+ this.eventMouseUp = this.endDrag.bindAsEventListener(this);
+ this.eventMouseMove = this.update.bindAsEventListener(this);
+
+ // Initialize handles in reverse (make sure first handle is active)
+ this.handles.each( function(h,i) {
+ i = slider.handles.length-1-i;
+ slider.setValue(parseFloat(
+ (slider.options.sliderValue instanceof Array ?
+ slider.options.sliderValue[i] : slider.options.sliderValue) ||
+ slider.range.start), i);
+ Element.makePositioned(h); // fix IE
+ Event.observe(h, "mousedown", slider.eventMouseDown);
+ });
+
+ Event.observe(this.track, "mousedown", this.eventMouseDown);
+ Event.observe(document, "mouseup", this.eventMouseUp);
+ Event.observe(document, "mousemove", this.eventMouseMove);
+
+ this.initialized = true;
+ },
+ dispose: function() {
+ var slider = this;
+ Event.stopObserving(this.track, "mousedown", this.eventMouseDown);
+ Event.stopObserving(document, "mouseup", this.eventMouseUp);
+ Event.stopObserving(document, "mousemove", this.eventMouseMove);
+ this.handles.each( function(h) {
+ Event.stopObserving(h, "mousedown", slider.eventMouseDown);
+ });
+ },
+ setDisabled: function(){
+ this.disabled = true;
+ },
+ setEnabled: function(){
+ this.disabled = false;
+ },
+ getNearestValue: function(value){
+ if(this.allowedValues){
+ if(value >= this.allowedValues.max()) return(this.allowedValues.max());
+ if(value <= this.allowedValues.min()) return(this.allowedValues.min());
+
+ var offset = Math.abs(this.allowedValues[0] - value);
+ var newValue = this.allowedValues[0];
+ this.allowedValues.each( function(v) {
+ var currentOffset = Math.abs(v - value);
+ if(currentOffset <= offset){
+ newValue = v;
+ offset = currentOffset;
+ }
+ });
+ return newValue;
+ }
+ if(value > this.range.end) return this.range.end;
+ if(value < this.range.start) return this.range.start;
+ return value;
+ },
+ setValue: function(sliderValue, handleIdx){
+ if(!this.active) {
+ this.activeHandleIdx = handleIdx || 0;
+ this.activeHandle = this.handles[this.activeHandleIdx];
+ this.updateStyles();
+ }
+ handleIdx = handleIdx || this.activeHandleIdx || 0;
+ if(this.initialized && this.restricted) {
+ if((handleIdx>0) && (sliderValue<this.values[handleIdx-1]))
+ sliderValue = this.values[handleIdx-1];
+ if((handleIdx < (this.handles.length-1)) && (sliderValue>this.values[handleIdx+1]))
+ sliderValue = this.values[handleIdx+1];
+ }
+ sliderValue = this.getNearestValue(sliderValue);
+ this.values[handleIdx] = sliderValue;
+ this.value = this.values[0]; // assure backwards compat
+
+ this.handles[handleIdx].style[this.isVertical() ? 'top' : 'left'] =
+ this.translateToPx(sliderValue);
+
+ this.drawSpans();
+ if(!this.dragging || !this.event) this.updateFinished();
+ },
+ setValueBy: function(delta, handleIdx) {
+ this.setValue(this.values[handleIdx || this.activeHandleIdx || 0] + delta,
+ handleIdx || this.activeHandleIdx || 0);
+ },
+ translateToPx: function(value) {
+ return Math.round(
+ ((this.trackLength-this.handleLength)/(this.range.end-this.range.start)) *
+ (value - this.range.start)) + "px";
+ },
+ translateToValue: function(offset) {
+ return ((offset/(this.trackLength-this.handleLength) *
+ (this.range.end-this.range.start)) + this.range.start);
+ },
+ getRange: function(range) {
+ var v = this.values.sortBy(Prototype.K);
+ range = range || 0;
+ return $R(v[range],v[range+1]);
+ },
+ minimumOffset: function(){
+ return(this.isVertical() ? this.alignY : this.alignX);
+ },
+ maximumOffset: function(){
+ return(this.isVertical() ?
+ (this.track.offsetHeight != 0 ? this.track.offsetHeight :
+ this.track.style.height.replace(/px$/,"")) - this.alignY :
+ (this.track.offsetWidth != 0 ? this.track.offsetWidth :
+ this.track.style.width.replace(/px$/,"")) - this.alignY);
+ },
+ isVertical: function(){
+ return (this.axis == 'vertical');
+ },
+ drawSpans: function() {
+ var slider = this;
+ if(this.spans)
+ $R(0, this.spans.length-1).each(function(r) { slider.setSpan(slider.spans[r], slider.getRange(r)) });
+ if(this.options.startSpan)
+ this.setSpan(this.options.startSpan,
+ $R(0, this.values.length>1 ? this.getRange(0).min() : this.value ));
+ if(this.options.endSpan)
+ this.setSpan(this.options.endSpan,
+ $R(this.values.length>1 ? this.getRange(this.spans.length-1).max() : this.value, this.maximum));
+ },
+ setSpan: function(span, range) {
+ if(this.isVertical()) {
+ span.style.top = this.translateToPx(range.start);
+ span.style.height = this.translateToPx(range.end - range.start + this.range.start);
+ } else {
+ span.style.left = this.translateToPx(range.start);
+ span.style.width = this.translateToPx(range.end - range.start + this.range.start);
+ }
+ },
+ updateStyles: function() {
+ this.handles.each( function(h){ Element.removeClassName(h, 'selected') });
+ Element.addClassName(this.activeHandle, 'selected');
+ },
+ startDrag: function(event) {
+ if(Event.isLeftClick(event)) {
+ if(!this.disabled){
+ this.active = true;
+
+ var handle = Event.element(event);
+ var pointer = [Event.pointerX(event), Event.pointerY(event)];
+ var track = handle;
+ if(track==this.track) {
+ var offsets = Position.cumulativeOffset(this.track);
+ this.event = event;
+ this.setValue(this.translateToValue(
+ (this.isVertical() ? pointer[1]-offsets[1] : pointer[0]-offsets[0])-(this.handleLength/2)
+ ));
+ var offsets = Position.cumulativeOffset(this.activeHandle);
+ this.offsetX = (pointer[0] - offsets[0]);
+ this.offsetY = (pointer[1] - offsets[1]);
+ } else {
+ // find the handle (prevents issues with Safari)
+ while((this.handles.indexOf(handle) == -1) && handle.parentNode)
+ handle = handle.parentNode;
+
+ this.activeHandle = handle;
+ this.activeHandleIdx = this.handles.indexOf(this.activeHandle);
+ this.updateStyles();
+
+ var offsets = Position.cumulativeOffset(this.activeHandle);
+ this.offsetX = (pointer[0] - offsets[0]);
+ this.offsetY = (pointer[1] - offsets[1]);
+ }
+ }
+ Event.stop(event);
+ }
+ },
+ update: function(event) {
+ if(this.active) {
+ if(!this.dragging) this.dragging = true;
+ this.draw(event);
+ // fix AppleWebKit rendering
+ if(navigator.appVersion.indexOf('AppleWebKit')>0) window.scrollBy(0,0);
+ Event.stop(event);
+ }
+ },
+ draw: function(event) {
+ var pointer = [Event.pointerX(event), Event.pointerY(event)];
+ var offsets = Position.cumulativeOffset(this.track);
+ pointer[0] -= this.offsetX + offsets[0];
+ pointer[1] -= this.offsetY + offsets[1];
+ this.event = event;
+ this.setValue(this.translateToValue( this.isVertical() ? pointer[1] : pointer[0] ));
+ if(this.initialized && this.options.onSlide)
+ this.options.onSlide(this.values.length>1 ? this.values : this.value, this);
+ },
+ endDrag: function(event) {
+ if(this.active && this.dragging) {
+ this.finishDrag(event, true);
+ Event.stop(event);
+ }
+ this.active = false;
+ this.dragging = false;
+ },
+ finishDrag: function(event, success) {
+ this.active = false;
+ this.dragging = false;
+ this.updateFinished();
+ },
+ updateFinished: function() {
+ if(this.initialized && this.options.onChange)
+ this.options.onChange(this.values.length>1 ? this.values : this.value, this);
+ this.event = null;
+ }
+} \ No newline at end of file
diff --git a/site/app/webroot/js/scriptaculous/unittest.js b/site/app/webroot/js/scriptaculous/unittest.js
new file mode 100644
index 0000000..d5b77c1
--- /dev/null
+++ b/site/app/webroot/js/scriptaculous/unittest.js
@@ -0,0 +1,390 @@
+// Copyright (c) 2005 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
+// (c) 2005 Jon Tirsen (http://www.tirsen.com)
+// (c) 2005 Michael Schuerig (http://www.schuerig.de/michael/)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+
+// experimental, Firefox-only
+Event.simulateMouse = function(element, eventName) {
+ var options = Object.extend({
+ pointerX: 0,
+ pointerY: 0,
+ buttons: 0
+ }, arguments[2] || {});
+ var oEvent = document.createEvent("MouseEvents");
+ oEvent.initMouseEvent(eventName, true, true, document.defaultView,
+ options.buttons, options.pointerX, options.pointerY, options.pointerX, options.pointerY,
+ false, false, false, false, 0, $(element));
+
+ if(this.mark) Element.remove(this.mark);
+ this.mark = document.createElement('div');
+ this.mark.appendChild(document.createTextNode(" "));
+ document.body.appendChild(this.mark);
+ this.mark.style.position = 'absolute';
+ this.mark.style.top = options.pointerY + "px";
+ this.mark.style.left = options.pointerX + "px";
+ this.mark.style.width = "5px";
+ this.mark.style.height = "5px;";
+ this.mark.style.borderTop = "1px solid red;"
+ this.mark.style.borderLeft = "1px solid red;"
+
+ if(this.step)
+ alert('['+new Date().getTime().toString()+'] '+eventName+'/'+Test.Unit.inspect(options));
+
+ $(element).dispatchEvent(oEvent);
+};
+
+// Note: Due to a fix in Firefox 1.0.5/6 that probably fixed "too much", this doesn't work in 1.0.6 or DP2.
+// You need to downgrade to 1.0.4 for now to get this working
+// See https://bugzilla.mozilla.org/show_bug.cgi?id=289940 for the fix that fixed too much
+Event.simulateKey = function(element, eventName) {
+ var options = Object.extend({
+ ctrlKey: false,
+ altKey: false,
+ shiftKey: false,
+ metaKey: false,
+ keyCode: 0,
+ charCode: 0
+ }, arguments[2] || {});
+
+ var oEvent = document.createEvent("KeyEvents");
+ oEvent.initKeyEvent(eventName, true, true, window,
+ options.ctrlKey, options.altKey, options.shiftKey, options.metaKey,
+ options.keyCode, options.charCode );
+ $(element).dispatchEvent(oEvent);
+};
+
+Event.simulateKeys = function(element, command) {
+ for(var i=0; i<command.length; i++) {
+ Event.simulateKey(element,'keypress',{charCode:command.charCodeAt(i)});
+ }
+};
+
+var Test = {}
+Test.Unit = {};
+
+// security exception workaround
+Test.Unit.inspect = Object.inspect;
+
+Test.Unit.Logger = Class.create();
+Test.Unit.Logger.prototype = {
+ initialize: function(log) {
+ this.log = $(log);
+ if (this.log) {
+ this._createLogTable();
+ }
+ },
+ start: function(testName) {
+ if (!this.log) return;
+ this.testName = testName;
+ this.lastLogLine = document.createElement('tr');
+ this.statusCell = document.createElement('td');
+ this.nameCell = document.createElement('td');
+ this.nameCell.appendChild(document.createTextNode(testName));
+ this.messageCell = document.createElement('td');
+ this.lastLogLine.appendChild(this.statusCell);
+ this.lastLogLine.appendChild(this.nameCell);
+ this.lastLogLine.appendChild(this.messageCell);
+ this.loglines.appendChild(this.lastLogLine);
+ },
+ finish: function(status, summary) {
+ if (!this.log) return;
+ this.lastLogLine.className = status;
+ this.statusCell.innerHTML = status;
+ this.messageCell.innerHTML = this._toHTML(summary);
+ },
+ message: function(message) {
+ if (!this.log) return;
+ this.messageCell.innerHTML = this._toHTML(message);
+ },
+ summary: function(summary) {
+ if (!this.log) return;
+ this.logsummary.innerHTML = this._toHTML(summary);
+ },
+ _createLogTable: function() {
+ this.log.innerHTML =
+ '<div id="logsummary"></div>' +
+ '<table id="logtable">' +
+ '<thead><tr><th>Status</th><th>Test</th><th>Message</th></tr></thead>' +
+ '<tbody id="loglines"></tbody>' +
+ '</table>';
+ this.logsummary = $('logsummary')
+ this.loglines = $('loglines');
+ },
+ _toHTML: function(txt) {
+ return txt.escapeHTML().replace(/\n/g,"<br/>");
+ }
+}
+
+Test.Unit.Runner = Class.create();
+Test.Unit.Runner.prototype = {
+ initialize: function(testcases) {
+ this.options = Object.extend({
+ testLog: 'testlog'
+ }, arguments[1] || {});
+ this.options.resultsURL = this.parseResultsURLQueryParameter();
+ if (this.options.testLog) {
+ this.options.testLog = $(this.options.testLog) || null;
+ }
+ if(this.options.tests) {
+ this.tests = [];
+ for(var i = 0; i < this.options.tests.length; i++) {
+ if(/^test/.test(this.options.tests[i])) {
+ this.tests.push(new Test.Unit.Testcase(this.options.tests[i], testcases[this.options.tests[i]], testcases["setup"], testcases["teardown"]));
+ }
+ }
+ } else {
+ if (this.options.test) {
+ this.tests = [new Test.Unit.Testcase(this.options.test, testcases[this.options.test], testcases["setup"], testcases["teardown"])];
+ } else {
+ this.tests = [];
+ for(var testcase in testcases) {
+ if(/^test/.test(testcase)) {
+ this.tests.push(new Test.Unit.Testcase(testcase, testcases[testcase], testcases["setup"], testcases["teardown"]));
+ }
+ }
+ }
+ }
+ this.currentTest = 0;
+ this.logger = new Test.Unit.Logger(this.options.testLog);
+ setTimeout(this.runTests.bind(this), 1000);
+ },
+ parseResultsURLQueryParameter: function() {
+ return window.location.search.parseQuery()["resultsURL"];
+ },
+ // Returns:
+ // "ERROR" if there was an error,
+ // "FAILURE" if there was a failure, or
+ // "SUCCESS" if there was neither
+ getResult: function() {
+ var hasFailure = false;
+ for(var i=0;i<this.tests.length;i++) {
+ if (this.tests[i].errors > 0) {
+ return "ERROR";
+ }
+ if (this.tests[i].failures > 0) {
+ hasFailure = true;
+ }
+ }
+ if (hasFailure) {
+ return "FAILURE";
+ } else {
+ return "SUCCESS";
+ }
+ },
+ postResults: function() {
+ if (this.options.resultsURL) {
+ new Ajax.Request(this.options.resultsURL,
+ { method: 'get', parameters: 'result=' + this.getResult(), asynchronous: false });
+ }
+ },
+ runTests: function() {
+ var test = this.tests[this.currentTest];
+ if (!test) {
+ // finished!
+ this.postResults();
+ this.logger.summary(this.summary());
+ return;
+ }
+ if(!test.isWaiting) {
+ this.logger.start(test.name);
+ }
+ test.run();
+ if(test.isWaiting) {
+ this.logger.message("Waiting for " + test.timeToWait + "ms");
+ setTimeout(this.runTests.bind(this), test.timeToWait || 1000);
+ } else {
+ this.logger.finish(test.status(), test.summary());
+ this.currentTest++;
+ // tail recursive, hopefully the browser will skip the stackframe
+ this.runTests();
+ }
+ },
+ summary: function() {
+ var assertions = 0;
+ var failures = 0;
+ var errors = 0;
+ var messages = [];
+ for(var i=0;i<this.tests.length;i++) {
+ assertions += this.tests[i].assertions;
+ failures += this.tests[i].failures;
+ errors += this.tests[i].errors;
+ }
+ return (
+ this.tests.length + " tests, " +
+ assertions + " assertions, " +
+ failures + " failures, " +
+ errors + " errors");
+ }
+}
+
+Test.Unit.Assertions = Class.create();
+Test.Unit.Assertions.prototype = {
+ initialize: function() {
+ this.assertions = 0;
+ this.failures = 0;
+ this.errors = 0;
+ this.messages = [];
+ },
+ summary: function() {
+ return (
+ this.assertions + " assertions, " +
+ this.failures + " failures, " +
+ this.errors + " errors" + "\n" +
+ this.messages.join("\n"));
+ },
+ pass: function() {
+ this.assertions++;
+ },
+ fail: function(message) {
+ this.failures++;
+ this.messages.push("Failure: " + message);
+ },
+ info: function(message) {
+ this.messages.push("Info: " + message);
+ },
+ error: function(error) {
+ this.errors++;
+ this.messages.push(error.name + ": "+ error.message + "(" + Test.Unit.inspect(error) +")");
+ },
+ status: function() {
+ if (this.failures > 0) return 'failed';
+ if (this.errors > 0) return 'error';
+ return 'passed';
+ },
+ assert: function(expression) {
+ var message = arguments[1] || 'assert: got "' + Test.Unit.inspect(expression) + '"';
+ try { expression ? this.pass() :
+ this.fail(message); }
+ catch(e) { this.error(e); }
+ },
+ assertEqual: function(expected, actual) {
+ var message = arguments[2] || "assertEqual";
+ try { (expected == actual) ? this.pass() :
+ this.fail(message + ': expected "' + Test.Unit.inspect(expected) +
+ '", actual "' + Test.Unit.inspect(actual) + '"'); }
+ catch(e) { this.error(e); }
+ },
+ assertEnumEqual: function(expected, actual) {
+ var message = arguments[2] || "assertEnumEqual";
+ try { $A(expected).length == $A(actual).length &&
+ expected.zip(actual).all(function(pair) { return pair[0] == pair[1] }) ?
+ this.pass() : this.fail(message + ': expected ' + Test.Unit.inspect(expected) +
+ ', actual ' + Test.Unit.inspect(actual)); }
+ catch(e) { this.error(e); }
+ },
+ assertNotEqual: function(expected, actual) {
+ var message = arguments[2] || "assertNotEqual";
+ try { (expected != actual) ? this.pass() :
+ this.fail(message + ': got "' + Test.Unit.inspect(actual) + '"'); }
+ catch(e) { this.error(e); }
+ },
+ assertNull: function(obj) {
+ var message = arguments[1] || 'assertNull'
+ try { (obj==null) ? this.pass() :
+ this.fail(message + ': got "' + Test.Unit.inspect(obj) + '"'); }
+ catch(e) { this.error(e); }
+ },
+ assertMatch: function(expected, actual) {
+ var message = arguments[2] || 'assertMatch';
+ var regex = new RegExp(expected);
+ try { (regex.exec(actual)) ? this.pass() :
+ this.fail(message + ' : regex: "' + Test.Unit.inspect(expected) + ' did not match: ' + Test.Unit.inspect(actual) + '"'); }
+ catch(e) { this.error(e); }
+ },
+ assertHidden: function(element) {
+ var message = arguments[1] || 'assertHidden';
+ this.assertEqual("none", element.style.display, message);
+ },
+ assertNotNull: function(object) {
+ var message = arguments[1] || 'assertNotNull';
+ this.assert(object != null, message);
+ },
+ assertInstanceOf: function(expected, actual) {
+ var message = arguments[2] || 'assertInstanceOf';
+ try {
+ (actual instanceof expected) ? this.pass() :
+ this.fail(message + ": object was not an instance of the expected type"); }
+ catch(e) { this.error(e); }
+ },
+ assertNotInstanceOf: function(expected, actual) {
+ var message = arguments[2] || 'assertNotInstanceOf';
+ try {
+ !(actual instanceof expected) ? this.pass() :
+ this.fail(message + ": object was an instance of the not expected type"); }
+ catch(e) { this.error(e); }
+ },
+ _isVisible: function(element) {
+ element = $(element);
+ if(!element.parentNode) return true;
+ this.assertNotNull(element);
+ if(element.style && Element.getStyle(element, 'display') == 'none')
+ return false;
+
+ return this._isVisible(element.parentNode);
+ },
+ assertNotVisible: function(element) {
+ this.assert(!this._isVisible(element), Test.Unit.inspect(element) + " was not hidden and didn't have a hidden parent either. " + ("" || arguments[1]));
+ },
+ assertVisible: function(element) {
+ this.assert(this._isVisible(element), Test.Unit.inspect(element) + " was not visible. " + ("" || arguments[1]));
+ },
+ benchmark: function(operation, iterations) {
+ var startAt = new Date();
+ (iterations || 1).times(operation);
+ var timeTaken = ((new Date())-startAt);
+ this.info((arguments[2] || 'Operation') + ' finished ' +
+ iterations + ' iterations in ' + (timeTaken/1000)+'s' );
+ return timeTaken;
+ }
+}
+
+Test.Unit.Testcase = Class.create();
+Object.extend(Object.extend(Test.Unit.Testcase.prototype, Test.Unit.Assertions.prototype), {
+ initialize: function(name, test, setup, teardown) {
+ Test.Unit.Assertions.prototype.initialize.bind(this)();
+ this.name = name;
+ this.test = test || function() {};
+ this.setup = setup || function() {};
+ this.teardown = teardown || function() {};
+ this.isWaiting = false;
+ this.timeToWait = 1000;
+ },
+ wait: function(time, nextPart) {
+ this.isWaiting = true;
+ this.test = nextPart;
+ this.timeToWait = time;
+ },
+ run: function() {
+ try {
+ try {
+ if (!this.isWaiting) this.setup.bind(this)();
+ this.isWaiting = false;
+ this.test.bind(this)();
+ } finally {
+ if(!this.isWaiting) {
+ this.teardown.bind(this)();
+ }
+ }
+ }
+ catch(e) { this.error(e); }
+ }
+});
diff --git a/site/app/webroot/js/simile/ajax/ajax-api-amo-bundle.js b/site/app/webroot/js/simile/ajax/ajax-api-amo-bundle.js
new file mode 100644
index 0000000..d8fbd8f
--- /dev/null
+++ b/site/app/webroot/js/simile/ajax/ajax-api-amo-bundle.js
@@ -0,0 +1,161 @@
+
+//////////////////////////// AJAX LOADER /////////////////////////////
+
+if (typeof SimileAjax == "undefined") {
+ var SimileAjax = {
+ loaded: false,
+ loadingScriptsCount: 0,
+ error: null,
+ params: { bundle:"true" }
+ };
+
+ SimileAjax.Platform = new Object();
+ /*
+ HACK: We need these 2 things here because we cannot simply append
+ a <script> element containing code that accesses SimileAjax.Platform
+ to initialize it because IE executes that <script> code first
+ before it loads ajax.js and platform.js.
+ */
+
+ var getHead = function(doc) {
+ return doc.getElementsByTagName("head")[0];
+ };
+
+ SimileAjax.findScript = function(doc, substring) {
+ var heads = doc.documentElement.getElementsByTagName("head");
+ for (var h = 0; h < heads.length; h++) {
+ var node = heads[h].firstChild;
+ while (node != null) {
+ if (node.nodeType == 1 && node.tagName.toLowerCase() == "script") {
+ var url = node.src;
+ var i = url.indexOf(substring);
+ if (i >= 0) {
+ return url;
+ }
+ }
+ node = node.nextSibling;
+ }
+ }
+ return null;
+ };
+ SimileAjax.includeJavascriptFile = function(doc, url, onerror, charset) {
+ onerror = onerror || "";
+ if (doc.body == null) {
+ try {
+ var q = "'" + onerror.replace( /'/g, '&apos' ) + "'"; // "
+ doc.write("<script src='" + url + "' onerror="+ q +
+ (charset ? " charset='"+ charset +"'" : "") +
+ " type='text/javascript'>"+ onerror + "</script>");
+ return false;
+ } catch (e) {
+ // fall through
+ }
+ }
+
+ var script = doc.createElement("script");
+ if (onerror) {
+ try { script.innerHTML = onerror; } catch(e) {}
+ script.setAttribute("onerror", onerror);
+ }
+ if (charset) {
+ script.setAttribute("charset", charset);
+ }
+ script.type = "text/javascript";
+ script.language = "JavaScript";
+ script.src = url;
+ return getHead(doc).appendChild(script);
+ };
+ SimileAjax.includeJavascriptFiles = function(doc, urlPrefix, filenames) {
+ for (var i = 0; i < filenames.length; i++) {
+ SimileAjax.includeJavascriptFile(doc, urlPrefix + filenames[i]);
+ }
+ SimileAjax.loadingScriptsCount += filenames.length;
+ SimileAjax.includeJavascriptFile(doc, SimileAjax.urlPrefix + "scripts/signal.js?" + filenames.length);
+ };
+ SimileAjax.includeCssFile = function(doc, url) {
+ if (doc.body == null) {
+ try {
+ doc.write("<link rel='stylesheet' href='" + url + "' type='text/css'/>");
+ return;
+ } catch (e) {
+ // fall through
+ }
+ }
+
+ var link = doc.createElement("link");
+ link.setAttribute("rel", "stylesheet");
+ link.setAttribute("type", "text/css");
+ link.setAttribute("href", url);
+ getHead(doc).appendChild(link);
+ };
+ SimileAjax.includeCssFiles = function(doc, urlPrefix, filenames) {
+ for (var i = 0; i < filenames.length; i++) {
+ SimileAjax.includeCssFile(doc, urlPrefix + filenames[i]);
+ }
+ };
+
+ /**
+ * Append into urls each string in suffixes after prefixing it with urlPrefix.
+ * @param {Array} urls
+ * @param {String} urlPrefix
+ * @param {Array} suffixes
+ */
+ SimileAjax.prefixURLs = function(urls, urlPrefix, suffixes) {
+ for (var i = 0; i < suffixes.length; i++) {
+ urls.push(urlPrefix + suffixes[i]);
+ }
+ };
+
+ /**
+ * Parse out the query parameters from a URL
+ * @param {String} url the url to parse, or location.href if undefined
+ * @param {Object} to optional object to extend with the parameters
+ * @param {Object} types optional object mapping keys to value types
+ * (String, Number, Boolean or Array, String by default)
+ * @return a key/value Object whose keys are the query parameter names
+ * @type Object
+ */
+ SimileAjax.parseURLParameters = function(url, to, types) {
+ to = to || {};
+ types = types || {};
+
+ if (typeof url == "undefined") {
+ url = location.href;
+ }
+ var q = url.indexOf("?");
+ if (q < 0) {
+ return to;
+ }
+ url = (url+"#").slice(q+1, url.indexOf("#")); // toss the URL fragment
+
+ var params = url.split("&"), param, parsed = {};
+ var decode = window.decodeURIComponent || unescape;
+ for (var i = 0; param = params[i]; i++) {
+ var eq = param.indexOf("=");
+ var name = decode(param.slice(0,eq));
+ var old = parsed[name];
+ if (typeof old == "undefined") {
+ old = [];
+ } else if (!(old instanceof Array)) {
+ old = [old];
+ }
+ parsed[name] = old.concat(decode(param.slice(eq+1)));
+ }
+ for (var i in parsed) {
+ if (!parsed.hasOwnProperty(i)) continue;
+ var type = types[i] || String;
+ var data = parsed[i];
+ if (!(data instanceof Array)) {
+ data = [data];
+ }
+ if (type === Boolean && data[0] == "false") {
+ to[i] = false; // because Boolean("false") === true
+ } else {
+ to[i] = type.apply(this, data);
+ }
+ }
+ return to;
+ };
+
+ SimileAjax.loaded = true;
+} \ No newline at end of file
diff --git a/site/app/webroot/js/simile/ajax/content/history.html b/site/app/webroot/js/simile/ajax/content/history.html
new file mode 100755
index 0000000..a30fbd8
--- /dev/null
+++ b/site/app/webroot/js/simile/ajax/content/history.html
@@ -0,0 +1,7 @@
+<html>
+<head>
+ <title>Dummy Page for Keeping Track of History</title>
+</head>
+<body>
+</body>
+</html> \ No newline at end of file
diff --git a/site/app/webroot/js/simile/ajax/images/bubble-bottom-arrow.png b/site/app/webroot/js/simile/ajax/images/bubble-bottom-arrow.png
new file mode 100755
index 0000000..38c3917
--- /dev/null
+++ b/site/app/webroot/js/simile/ajax/images/bubble-bottom-arrow.png
Binary files differ
diff --git a/site/app/webroot/js/simile/ajax/images/bubble-bottom-left.png b/site/app/webroot/js/simile/ajax/images/bubble-bottom-left.png
new file mode 100755
index 0000000..6d32026
--- /dev/null
+++ b/site/app/webroot/js/simile/ajax/images/bubble-bottom-left.png
Binary files differ
diff --git a/site/app/webroot/js/simile/ajax/images/bubble-bottom-right.png b/site/app/webroot/js/simile/ajax/images/bubble-bottom-right.png
new file mode 100755
index 0000000..e5dc136
--- /dev/null
+++ b/site/app/webroot/js/simile/ajax/images/bubble-bottom-right.png
Binary files differ
diff --git a/site/app/webroot/js/simile/ajax/images/bubble-bottom.png b/site/app/webroot/js/simile/ajax/images/bubble-bottom.png
new file mode 100755
index 0000000..166b057
--- /dev/null
+++ b/site/app/webroot/js/simile/ajax/images/bubble-bottom.png
Binary files differ
diff --git a/site/app/webroot/js/simile/ajax/images/bubble-left-arrow.png b/site/app/webroot/js/simile/ajax/images/bubble-left-arrow.png
new file mode 100755
index 0000000..5b173cd
--- /dev/null
+++ b/site/app/webroot/js/simile/ajax/images/bubble-left-arrow.png
Binary files differ
diff --git a/site/app/webroot/js/simile/ajax/images/bubble-left.png b/site/app/webroot/js/simile/ajax/images/bubble-left.png
new file mode 100755
index 0000000..3826722
--- /dev/null
+++ b/site/app/webroot/js/simile/ajax/images/bubble-left.png
Binary files differ
diff --git a/site/app/webroot/js/simile/ajax/images/bubble-right-arrow.png b/site/app/webroot/js/simile/ajax/images/bubble-right-arrow.png
new file mode 100755
index 0000000..11e2873
--- /dev/null
+++ b/site/app/webroot/js/simile/ajax/images/bubble-right-arrow.png
Binary files differ
diff --git a/site/app/webroot/js/simile/ajax/images/bubble-right.png b/site/app/webroot/js/simile/ajax/images/bubble-right.png
new file mode 100755
index 0000000..f66f879
--- /dev/null
+++ b/site/app/webroot/js/simile/ajax/images/bubble-right.png
Binary files differ
diff --git a/site/app/webroot/js/simile/ajax/images/bubble-top-arrow.png b/site/app/webroot/js/simile/ajax/images/bubble-top-arrow.png
new file mode 100755
index 0000000..524c46e
--- /dev/null
+++ b/site/app/webroot/js/simile/ajax/images/bubble-top-arrow.png
Binary files differ
diff --git a/site/app/webroot/js/simile/ajax/images/bubble-top-left.png b/site/app/webroot/js/simile/ajax/images/bubble-top-left.png
new file mode 100755
index 0000000..d69841f
--- /dev/null
+++ b/site/app/webroot/js/simile/ajax/images/bubble-top-left.png
Binary files differ
diff --git a/site/app/webroot/js/simile/ajax/images/bubble-top-right.png b/site/app/webroot/js/simile/ajax/images/bubble-top-right.png
new file mode 100755
index 0000000..9ab219a
--- /dev/null
+++ b/site/app/webroot/js/simile/ajax/images/bubble-top-right.png
Binary files differ
diff --git a/site/app/webroot/js/simile/ajax/images/bubble-top.png b/site/app/webroot/js/simile/ajax/images/bubble-top.png
new file mode 100755
index 0000000..917defa
--- /dev/null
+++ b/site/app/webroot/js/simile/ajax/images/bubble-top.png
Binary files differ
diff --git a/site/app/webroot/js/simile/ajax/images/close-button.png b/site/app/webroot/js/simile/ajax/images/close-button.png
new file mode 100755
index 0000000..15f31b3
--- /dev/null
+++ b/site/app/webroot/js/simile/ajax/images/close-button.png
Binary files differ
diff --git a/site/app/webroot/js/simile/ajax/images/copy.png b/site/app/webroot/js/simile/ajax/images/copy.png
new file mode 100755
index 0000000..cf7cee4
--- /dev/null
+++ b/site/app/webroot/js/simile/ajax/images/copy.png
Binary files differ
diff --git a/site/app/webroot/js/simile/ajax/images/message-bottom-left.png b/site/app/webroot/js/simile/ajax/images/message-bottom-left.png
new file mode 100755
index 0000000..43a9d61
--- /dev/null
+++ b/site/app/webroot/js/simile/ajax/images/message-bottom-left.png
Binary files differ
diff --git a/site/app/webroot/js/simile/ajax/images/message-bottom-right.png b/site/app/webroot/js/simile/ajax/images/message-bottom-right.png
new file mode 100755
index 0000000..bfa4954
--- /dev/null
+++ b/site/app/webroot/js/simile/ajax/images/message-bottom-right.png
Binary files differ
diff --git a/site/app/webroot/js/simile/ajax/images/message-left.png b/site/app/webroot/js/simile/ajax/images/message-left.png
new file mode 100755
index 0000000..f354376
--- /dev/null
+++ b/site/app/webroot/js/simile/ajax/images/message-left.png
Binary files differ
diff --git a/site/app/webroot/js/simile/ajax/images/message-right.png b/site/app/webroot/js/simile/ajax/images/message-right.png
new file mode 100755
index 0000000..4702c28
--- /dev/null
+++ b/site/app/webroot/js/simile/ajax/images/message-right.png
Binary files differ
diff --git a/site/app/webroot/js/simile/ajax/images/message-top-left.png b/site/app/webroot/js/simile/ajax/images/message-top-left.png
new file mode 100755
index 0000000..b19b0ea
--- /dev/null
+++ b/site/app/webroot/js/simile/ajax/images/message-top-left.png
Binary files differ
diff --git a/site/app/webroot/js/simile/ajax/images/message-top-right.png b/site/app/webroot/js/simile/ajax/images/message-top-right.png
new file mode 100755
index 0000000..c092555
--- /dev/null
+++ b/site/app/webroot/js/simile/ajax/images/message-top-right.png
Binary files differ
diff --git a/site/app/webroot/js/simile/ajax/scripts/ajax.js b/site/app/webroot/js/simile/ajax/scripts/ajax.js
new file mode 100755
index 0000000..7172609
--- /dev/null
+++ b/site/app/webroot/js/simile/ajax/scripts/ajax.js
@@ -0,0 +1,45 @@
+/*==================================================
+ * General, miscellaneous SimileAjax stuff
+ *==================================================
+ */
+
+SimileAjax.ListenerQueue = function(wildcardHandlerName) {
+ this._listeners = [];
+ this._wildcardHandlerName = wildcardHandlerName;
+};
+
+SimileAjax.ListenerQueue.prototype.add = function(listener) {
+ this._listeners.push(listener);
+};
+
+SimileAjax.ListenerQueue.prototype.remove = function(listener) {
+ var listeners = this._listeners;
+ for (var i = 0; i < listeners.length; i++) {
+ if (listeners[i] == listener) {
+ listeners.splice(i, 1);
+ break;
+ }
+ }
+};
+
+SimileAjax.ListenerQueue.prototype.fire = function(handlerName, args) {
+ var listeners = [].concat(this._listeners);
+ for (var i = 0; i < listeners.length; i++) {
+ var listener = listeners[i];
+ if (handlerName in listener) {
+ try {
+ listener[handlerName].apply(listener, args);
+ } catch (e) {
+ SimileAjax.Debug.exception("Error firing event of name " + handlerName, e);
+ }
+ } else if (this._wildcardHandlerName != null &&
+ this._wildcardHandlerName in listener) {
+ try {
+ listener[this._wildcardHandlerName].apply(listener, [ handlerName ]);
+ } catch (e) {
+ SimileAjax.Debug.exception("Error firing event of name " + handlerName + " to wildcard handler", e);
+ }
+ }
+ }
+};
+
diff --git a/site/app/webroot/js/simile/ajax/scripts/data-structure.js b/site/app/webroot/js/simile/ajax/scripts/data-structure.js
new file mode 100755
index 0000000..e789cb4
--- /dev/null
+++ b/site/app/webroot/js/simile/ajax/scripts/data-structure.js
@@ -0,0 +1,447 @@
+/**
+ * A basic set (in the mathematical sense) data structure
+ *
+ * @constructor
+ * @param {Array or SimileAjax.Set} [a] an initial collection
+ */
+SimileAjax.Set = function(a) {
+ this._hash = {};
+ this._count = 0;
+
+ if (a instanceof Array) {
+ for (var i = 0; i < a.length; i++) {
+ this.add(a[i]);
+ }
+ } else if (a instanceof SimileAjax.Set) {
+ this.addSet(a);
+ }
+}
+
+/**
+ * Adds the given object to this set, assuming there it does not already exist
+ *
+ * @param {Object} o the object to add
+ * @return {Boolean} true if the object was added, false if not
+ */
+SimileAjax.Set.prototype.add = function(o) {
+ if (!(o in this._hash)) {
+ this._hash[o] = true;
+ this._count++;
+ return true;
+ }
+ return false;
+}
+
+/**
+ * Adds each element in the given set to this set
+ *
+ * @param {SimileAjax.Set} set the set of elements to add
+ */
+SimileAjax.Set.prototype.addSet = function(set) {
+ for (var o in set._hash) {
+ this.add(o);
+ }
+}
+
+/**
+ * Removes the given element from this set
+ *
+ * @param {Object} o the object to remove
+ * @return {Boolean} true if the object was successfully removed,
+ * false otherwise
+ */
+SimileAjax.Set.prototype.remove = function(o) {
+ if (o in this._hash) {
+ delete this._hash[o];
+ this._count--;
+ return true;
+ }
+ return false;
+}
+
+/**
+ * Removes the elements in this set that correspond to the elements in the
+ * given set
+ *
+ * @param {SimileAjax.Set} set the set of elements to remove
+ */
+SimileAjax.Set.prototype.removeSet = function(set) {
+ for (var o in set._hash) {
+ this.remove(o);
+ }
+}
+
+/**
+ * Removes all elements in this set that are not present in the given set, i.e.
+ * modifies this set to the intersection of the two sets
+ *
+ * @param {SimileAjax.Set} set the set to intersect
+ */
+SimileAjax.Set.prototype.retainSet = function(set) {
+ for (var o in this._hash) {
+ if (!set.contains(o)) {
+ delete this._hash[o];
+ this._count--;
+ }
+ }
+}
+
+/**
+ * Returns whether or not the given element exists in this set
+ *
+ * @param {SimileAjax.Set} o the object to test for
+ * @return {Boolean} true if the object is present, false otherwise
+ */
+SimileAjax.Set.prototype.contains = function(o) {
+ return (o in this._hash);
+}
+
+/**
+ * Returns the number of elements in this set
+ *
+ * @return {Number} the number of elements in this set
+ */
+SimileAjax.Set.prototype.size = function() {
+ return this._count;
+}
+
+/**
+ * Returns the elements of this set as an array
+ *
+ * @return {Array} a new array containing the elements of this set
+ */
+SimileAjax.Set.prototype.toArray = function() {
+ var a = [];
+ for (var o in this._hash) {
+ a.push(o);
+ }
+ return a;
+}
+
+/**
+ * Iterates through the elements of this set, order unspecified, executing the
+ * given function on each element until the function returns true
+ *
+ * @param {Function} f a function of form f(element)
+ */
+SimileAjax.Set.prototype.visit = function(f) {
+ for (var o in this._hash) {
+ if (f(o) == true) {
+ break;
+ }
+ }
+}
+
+/**
+ * A sorted array data structure
+ *
+ * @constructor
+ */
+SimileAjax.SortedArray = function(compare, initialArray) {
+ this._a = (initialArray instanceof Array) ? initialArray : [];
+ this._compare = compare;
+};
+
+SimileAjax.SortedArray.prototype.add = function(elmt) {
+ var sa = this;
+ var index = this.find(function(elmt2) {
+ return sa._compare(elmt2, elmt);
+ });
+
+ if (index < this._a.length) {
+ this._a.splice(index, 0, elmt);
+ } else {
+ this._a.push(elmt);
+ }
+};
+
+SimileAjax.SortedArray.prototype.remove = function(elmt) {
+ var sa = this;
+ var index = this.find(function(elmt2) {
+ return sa._compare(elmt2, elmt);
+ });
+
+ while (index < this._a.length && this._compare(this._a[index], elmt) == 0) {
+ if (this._a[index] == elmt) {
+ this._a.splice(index, 1);
+ return true;
+ } else {
+ index++;
+ }
+ }
+ return false;
+};
+
+SimileAjax.SortedArray.prototype.removeAll = function() {
+ this._a = [];
+};
+
+SimileAjax.SortedArray.prototype.elementAt = function(index) {
+ return this._a[index];
+};
+
+SimileAjax.SortedArray.prototype.length = function() {
+ return this._a.length;
+};
+
+SimileAjax.SortedArray.prototype.find = function(compare) {
+ var a = 0;
+ var b = this._a.length;
+
+ while (a < b) {
+ var mid = Math.floor((a + b) / 2);
+ var c = compare(this._a[mid]);
+ if (mid == a) {
+ return c < 0 ? a+1 : a;
+ } else if (c < 0) {
+ a = mid;
+ } else {
+ b = mid;
+ }
+ }
+ return a;
+};
+
+SimileAjax.SortedArray.prototype.getFirst = function() {
+ return (this._a.length > 0) ? this._a[0] : null;
+};
+
+SimileAjax.SortedArray.prototype.getLast = function() {
+ return (this._a.length > 0) ? this._a[this._a.length - 1] : null;
+};
+
+/*==================================================
+ * Event Index
+ *==================================================
+ */
+
+SimileAjax.EventIndex = function(unit) {
+ var eventIndex = this;
+
+ this._unit = (unit != null) ? unit : SimileAjax.NativeDateUnit;
+ this._events = new SimileAjax.SortedArray(
+ function(event1, event2) {
+ return eventIndex._unit.compare(event1.getStart(), event2.getStart());
+ }
+ );
+ this._idToEvent = {};
+ this._indexed = true;
+};
+
+SimileAjax.EventIndex.prototype.getUnit = function() {
+ return this._unit;
+};
+
+SimileAjax.EventIndex.prototype.getEvent = function(id) {
+ return this._idToEvent[id];
+};
+
+SimileAjax.EventIndex.prototype.add = function(evt) {
+ this._events.add(evt);
+ this._idToEvent[evt.getID()] = evt;
+ this._indexed = false;
+};
+
+SimileAjax.EventIndex.prototype.removeAll = function() {
+ this._events.removeAll();
+ this._idToEvent = {};
+ this._indexed = false;
+};
+
+SimileAjax.EventIndex.prototype.getCount = function() {
+ return this._events.length();
+};
+
+SimileAjax.EventIndex.prototype.getIterator = function(startDate, endDate) {
+ if (!this._indexed) {
+ this._index();
+ }
+ return new SimileAjax.EventIndex._Iterator(this._events, startDate, endDate, this._unit);
+};
+
+SimileAjax.EventIndex.prototype.getReverseIterator = function(startDate, endDate) {
+ if (!this._indexed) {
+ this._index();
+ }
+ return new SimileAjax.EventIndex._ReverseIterator(this._events, startDate, endDate, this._unit);
+};
+
+SimileAjax.EventIndex.prototype.getAllIterator = function() {
+ return new SimileAjax.EventIndex._AllIterator(this._events);
+};
+
+SimileAjax.EventIndex.prototype.getEarliestDate = function() {
+ var evt = this._events.getFirst();
+ return (evt == null) ? null : evt.getStart();
+};
+
+SimileAjax.EventIndex.prototype.getLatestDate = function() {
+ var evt = this._events.getLast();
+ if (evt == null) {
+ return null;
+ }
+
+ if (!this._indexed) {
+ this._index();
+ }
+
+ var index = evt._earliestOverlapIndex;
+ var date = this._events.elementAt(index).getEnd();
+ for (var i = index + 1; i < this._events.length(); i++) {
+ date = this._unit.later(date, this._events.elementAt(i).getEnd());
+ }
+
+ return date;
+};
+
+SimileAjax.EventIndex.prototype._index = function() {
+ /*
+ * For each event, we want to find the earliest preceding
+ * event that overlaps with it, if any.
+ */
+
+ var l = this._events.length();
+ for (var i = 0; i < l; i++) {
+ var evt = this._events.elementAt(i);
+ evt._earliestOverlapIndex = i;
+ }
+
+ var toIndex = 1;
+ for (var i = 0; i < l; i++) {
+ var evt = this._events.elementAt(i);
+ var end = evt.getEnd();
+
+ toIndex = Math.max(toIndex, i + 1);
+ while (toIndex < l) {
+ var evt2 = this._events.elementAt(toIndex);
+ var start2 = evt2.getStart();
+
+ if (this._unit.compare(start2, end) < 0) {
+ evt2._earliestOverlapIndex = i;
+ toIndex++;
+ } else {
+ break;
+ }
+ }
+ }
+ this._indexed = true;
+};
+
+SimileAjax.EventIndex._Iterator = function(events, startDate, endDate, unit) {
+ this._events = events;
+ this._startDate = startDate;
+ this._endDate = endDate;
+ this._unit = unit;
+
+ this._currentIndex = events.find(function(evt) {
+ return unit.compare(evt.getStart(), startDate);
+ });
+ if (this._currentIndex - 1 >= 0) {
+ this._currentIndex = this._events.elementAt(this._currentIndex - 1)._earliestOverlapIndex;
+ }
+ this._currentIndex--;
+
+ this._maxIndex = events.find(function(evt) {
+ return unit.compare(evt.getStart(), endDate);
+ });
+
+ this._hasNext = false;
+ this._next = null;
+ this._findNext();
+};
+
+SimileAjax.EventIndex._Iterator.prototype = {
+ hasNext: function() { return this._hasNext; },
+ next: function() {
+ if (this._hasNext) {
+ var next = this._next;
+ this._findNext();
+
+ return next;
+ } else {
+ return null;
+ }
+ },
+ _findNext: function() {
+ var unit = this._unit;
+ while ((++this._currentIndex) < this._maxIndex) {
+ var evt = this._events.elementAt(this._currentIndex);
+ if (unit.compare(evt.getStart(), this._endDate) < 0 &&
+ unit.compare(evt.getEnd(), this._startDate) > 0) {
+
+ this._next = evt;
+ this._hasNext = true;
+ return;
+ }
+ }
+ this._next = null;
+ this._hasNext = false;
+ }
+};
+
+SimileAjax.EventIndex._ReverseIterator = function(events, startDate, endDate, unit) {
+ this._events = events;
+ this._startDate = startDate;
+ this._endDate = endDate;
+ this._unit = unit;
+
+ this._minIndex = events.find(function(evt) {
+ return unit.compare(evt.getStart(), startDate);
+ });
+ if (this._minIndex - 1 >= 0) {
+ this._minIndex = this._events.elementAt(this._minIndex - 1)._earliestOverlapIndex;
+ }
+
+ this._maxIndex = events.find(function(evt) {
+ return unit.compare(evt.getStart(), endDate);
+ });
+
+ this._currentIndex = this._maxIndex;
+ this._hasNext = false;
+ this._next = null;
+ this._findNext();
+};
+
+SimileAjax.EventIndex._ReverseIterator.prototype = {
+ hasNext: function() { return this._hasNext; },
+ next: function() {
+ if (this._hasNext) {
+ var next = this._next;
+ this._findNext();
+
+ return next;
+ } else {
+ return null;
+ }
+ },
+ _findNext: function() {
+ var unit = this._unit;
+ while ((--this._currentIndex) >= this._minIndex) {
+ var evt = this._events.elementAt(this._currentIndex);
+ if (unit.compare(evt.getStart(), this._endDate) < 0 &&
+ unit.compare(evt.getEnd(), this._startDate) > 0) {
+
+ this._next = evt;
+ this._hasNext = true;
+ return;
+ }
+ }
+ this._next = null;
+ this._hasNext = false;
+ }
+};
+
+SimileAjax.EventIndex._AllIterator = function(events) {
+ this._events = events;
+ this._index = 0;
+};
+
+SimileAjax.EventIndex._AllIterator.prototype = {
+ hasNext: function() {
+ return this._index < this._events.length();
+ },
+ next: function() {
+ return this._index < this._events.length() ?
+ this._events.elementAt(this._index++) : null;
+ }
+}; \ No newline at end of file
diff --git a/site/app/webroot/js/simile/ajax/scripts/date-time.js b/site/app/webroot/js/simile/ajax/scripts/date-time.js
new file mode 100755
index 0000000..d0498bf
--- /dev/null
+++ b/site/app/webroot/js/simile/ajax/scripts/date-time.js
@@ -0,0 +1,452 @@
+/**
+ * @fileOverview A collection of date/time utility functions
+ * @name SimileAjax.DateTime
+ */
+
+SimileAjax.DateTime = new Object();
+
+SimileAjax.DateTime.MILLISECOND = 0;
+SimileAjax.DateTime.SECOND = 1;
+SimileAjax.DateTime.MINUTE = 2;
+SimileAjax.DateTime.HOUR = 3;
+SimileAjax.DateTime.DAY = 4;
+SimileAjax.DateTime.WEEK = 5;
+SimileAjax.DateTime.MONTH = 6;
+SimileAjax.DateTime.YEAR = 7;
+SimileAjax.DateTime.DECADE = 8;
+SimileAjax.DateTime.CENTURY = 9;
+SimileAjax.DateTime.MILLENNIUM = 10;
+
+SimileAjax.DateTime.EPOCH = -1;
+SimileAjax.DateTime.ERA = -2;
+
+/**
+ * An array of unit lengths, expressed in milliseconds, of various lengths of
+ * time. The array indices are predefined and stored as properties of the
+ * SimileAjax.DateTime object, e.g. SimileAjax.DateTime.YEAR.
+ * @type Array
+ */
+SimileAjax.DateTime.gregorianUnitLengths = [];
+ (function() {
+ var d = SimileAjax.DateTime;
+ var a = d.gregorianUnitLengths;
+
+ a[d.MILLISECOND] = 1;
+ a[d.SECOND] = 1000;
+ a[d.MINUTE] = a[d.SECOND] * 60;
+ a[d.HOUR] = a[d.MINUTE] * 60;
+ a[d.DAY] = a[d.HOUR] * 24;
+ a[d.WEEK] = a[d.DAY] * 7;
+ a[d.MONTH] = a[d.DAY] * 31;
+ a[d.YEAR] = a[d.DAY] * 365;
+ a[d.DECADE] = a[d.YEAR] * 10;
+ a[d.CENTURY] = a[d.YEAR] * 100;
+ a[d.MILLENNIUM] = a[d.YEAR] * 1000;
+ })();
+
+SimileAjax.DateTime._dateRegexp = new RegExp(
+ "^(-?)([0-9]{4})(" + [
+ "(-?([0-9]{2})(-?([0-9]{2}))?)", // -month-dayOfMonth
+ "(-?([0-9]{3}))", // -dayOfYear
+ "(-?W([0-9]{2})(-?([1-7]))?)" // -Wweek-dayOfWeek
+ ].join("|") + ")?$"
+);
+SimileAjax.DateTime._timezoneRegexp = new RegExp(
+ "Z|(([-+])([0-9]{2})(:?([0-9]{2}))?)$"
+);
+SimileAjax.DateTime._timeRegexp = new RegExp(
+ "^([0-9]{2})(:?([0-9]{2})(:?([0-9]{2})(\.([0-9]+))?)?)?$"
+);
+
+/**
+ * Takes a date object and a string containing an ISO 8601 date and sets the
+ * the date using information parsed from the string. Note that this method
+ * does not parse any time information.
+ *
+ * @param {Date} dateObject the date object to modify
+ * @param {String} string an ISO 8601 string to parse
+ * @return {Date} the modified date object
+ */
+SimileAjax.DateTime.setIso8601Date = function(dateObject, string) {
+ /*
+ * This function has been adapted from dojo.date, v.0.3.0
+ * http://dojotoolkit.org/.
+ */
+
+ var d = string.match(SimileAjax.DateTime._dateRegexp);
+ if(!d) {
+ throw new Error("Invalid date string: " + string);
+ }
+
+ var sign = (d[1] == "-") ? -1 : 1; // BC or AD
+ var year = sign * d[2];
+ var month = d[5];
+ var date = d[7];
+ var dayofyear = d[9];
+ var week = d[11];
+ var dayofweek = (d[13]) ? d[13] : 1;
+
+ dateObject.setUTCFullYear(year);
+ if (dayofyear) {
+ dateObject.setUTCMonth(0);
+ dateObject.setUTCDate(Number(dayofyear));
+ } else if (week) {
+ dateObject.setUTCMonth(0);
+ dateObject.setUTCDate(1);
+ var gd = dateObject.getUTCDay();
+ var day = (gd) ? gd : 7;
+ var offset = Number(dayofweek) + (7 * Number(week));
+
+ if (day <= 4) {
+ dateObject.setUTCDate(offset + 1 - day);
+ } else {
+ dateObject.setUTCDate(offset + 8 - day);
+ }
+ } else {
+ if (month) {
+ dateObject.setUTCDate(1);
+ dateObject.setUTCMonth(month - 1);
+ }
+ if (date) {
+ dateObject.setUTCDate(date);
+ }
+ }
+
+ return dateObject;
+};
+
+/**
+ * Takes a date object and a string containing an ISO 8601 time and sets the
+ * the time using information parsed from the string. Note that this method
+ * does not parse any date information.
+ *
+ * @param {Date} dateObject the date object to modify
+ * @param {String} string an ISO 8601 string to parse
+ * @return {Date} the modified date object
+ */
+SimileAjax.DateTime.setIso8601Time = function (dateObject, string) {
+ /*
+ * This function has been adapted from dojo.date, v.0.3.0
+ * http://dojotoolkit.org/.
+ */
+
+ var d = string.match(SimileAjax.DateTime._timeRegexp);
+ if(!d) {
+ SimileAjax.Debug.warn("Invalid time string: " + string);
+ return false;
+ }
+ var hours = d[1];
+ var mins = Number((d[3]) ? d[3] : 0);
+ var secs = (d[5]) ? d[5] : 0;
+ var ms = d[7] ? (Number("0." + d[7]) * 1000) : 0;
+
+ dateObject.setUTCHours(hours);
+ dateObject.setUTCMinutes(mins);
+ dateObject.setUTCSeconds(secs);
+ dateObject.setUTCMilliseconds(ms);
+
+ return dateObject;
+};
+
+/**
+ * The timezone offset in minutes in the user's browser.
+ * @type Number
+ */
+SimileAjax.DateTime.timezoneOffset = new Date().getTimezoneOffset();
+
+/**
+ * Takes a date object and a string containing an ISO 8601 date and time and
+ * sets the date object using information parsed from the string.
+ *
+ * @param {Date} dateObject the date object to modify
+ * @param {String} string an ISO 8601 string to parse
+ * @return {Date} the modified date object
+ */
+SimileAjax.DateTime.setIso8601 = function (dateObject, string){
+ /*
+ * This function has been adapted from dojo.date, v.0.3.0
+ * http://dojotoolkit.org/.
+ */
+
+ var offset = null;
+ var comps = (string.indexOf("T") == -1) ? string.split(" ") : string.split("T");
+
+ SimileAjax.DateTime.setIso8601Date(dateObject, comps[0]);
+ if (comps.length == 2) {
+ // first strip timezone info from the end
+ var d = comps[1].match(SimileAjax.DateTime._timezoneRegexp);
+ if (d) {
+ if (d[0] == 'Z') {
+ offset = 0;
+ } else {
+ offset = (Number(d[3]) * 60) + Number(d[5]);
+ offset *= ((d[2] == '-') ? 1 : -1);
+ }
+ comps[1] = comps[1].substr(0, comps[1].length - d[0].length);
+ }
+
+ SimileAjax.DateTime.setIso8601Time(dateObject, comps[1]);
+ }
+ if (offset == null) {
+ offset = dateObject.getTimezoneOffset(); // local time zone if no tz info
+ }
+ dateObject.setTime(dateObject.getTime() + offset * 60000);
+
+ return dateObject;
+};
+
+/**
+ * Takes a string containing an ISO 8601 date and returns a newly instantiated
+ * date object with the parsed date and time information from the string.
+ *
+ * @param {String} string an ISO 8601 string to parse
+ * @return {Date} a new date object created from the string
+ */
+SimileAjax.DateTime.parseIso8601DateTime = function (string) {
+ try {
+ return SimileAjax.DateTime.setIso8601(new Date(0), string);
+ } catch (e) {
+ return null;
+ }
+};
+
+/**
+ * Takes a string containing a Gregorian date and time and returns a newly
+ * instantiated date object with the parsed date and time information from the
+ * string. If the param is actually an instance of Date instead of a string,
+ * simply returns the given date instead.
+ *
+ * @param {Object} o an object, to either return or parse as a string
+ * @return {Date} the date object
+ */
+SimileAjax.DateTime.parseGregorianDateTime = function(o) {
+ if (o == null) {
+ return null;
+ } else if (o instanceof Date) {
+ return o;
+ }
+
+ var s = o.toString();
+ if (s.length > 0 && s.length < 8) {
+ var space = s.indexOf(" ");
+ if (space > 0) {
+ var year = parseInt(s.substr(0, space));
+ var suffix = s.substr(space + 1);
+ if (suffix.toLowerCase() == "bc") {
+ year = 1 - year;
+ }
+ } else {
+ var year = parseInt(s);
+ }
+
+ var d = new Date(0);
+ d.setUTCFullYear(year);
+
+ return d;
+ }
+
+ try {
+ return new Date(Date.parse(s));
+ } catch (e) {
+ return null;
+ }
+};
+
+/**
+ * Rounds date objects down to the nearest interval or multiple of an interval.
+ * This method modifies the given date object, converting it to the given
+ * timezone if specified.
+ *
+ * @param {Date} date the date object to round
+ * @param {Number} intervalUnit a constant, integer index specifying an
+ * interval, e.g. SimileAjax.DateTime.HOUR
+ * @param {Number} timeZone a timezone shift, given in hours
+ * @param {Number} multiple a multiple of the interval to round by
+ * @param {Number} firstDayOfWeek an integer specifying the first day of the
+ * week, 0 corresponds to Sunday, 1 to Monday, etc.
+ */
+SimileAjax.DateTime.roundDownToInterval = function(date, intervalUnit, timeZone, multiple, firstDayOfWeek) {
+ var timeShift = timeZone *
+ SimileAjax.DateTime.gregorianUnitLengths[SimileAjax.DateTime.HOUR];
+
+ var date2 = new Date(date.getTime() + timeShift);
+ var clearInDay = function(d) {
+ d.setUTCMilliseconds(0);
+ d.setUTCSeconds(0);
+ d.setUTCMinutes(0);
+ d.setUTCHours(0);
+ };
+ var clearInYear = function(d) {
+ clearInDay(d);
+ d.setUTCDate(1);
+ d.setUTCMonth(0);
+ };
+
+ switch(intervalUnit) {
+ case SimileAjax.DateTime.MILLISECOND:
+ var x = date2.getUTCMilliseconds();
+ date2.setUTCMilliseconds(x - (x % multiple));
+ break;
+ case SimileAjax.DateTime.SECOND:
+ date2.setUTCMilliseconds(0);
+
+ var x = date2.getUTCSeconds();
+ date2.setUTCSeconds(x - (x % multiple));
+ break;
+ case SimileAjax.DateTime.MINUTE:
+ date2.setUTCMilliseconds(0);
+ date2.setUTCSeconds(0);
+
+ var x = date2.getUTCMinutes();
+ date2.setTime(date2.getTime() -
+ (x % multiple) * SimileAjax.DateTime.gregorianUnitLengths[SimileAjax.DateTime.MINUTE]);
+ break;
+ case SimileAjax.DateTime.HOUR:
+ date2.setUTCMilliseconds(0);
+ date2.setUTCSeconds(0);
+ date2.setUTCMinutes(0);
+
+ var x = date2.getUTCHours();
+ date2.setUTCHours(x - (x % multiple));
+ break;
+ case SimileAjax.DateTime.DAY:
+ clearInDay(date2);
+ break;
+ case SimileAjax.DateTime.WEEK:
+ clearInDay(date2);
+ var d = (date2.getUTCDay() + 7 - firstDayOfWeek) % 7;
+ date2.setTime(date2.getTime() -
+ d * SimileAjax.DateTime.gregorianUnitLengths[SimileAjax.DateTime.DAY]);
+ break;
+ case SimileAjax.DateTime.MONTH:
+ clearInDay(date2);
+ date2.setUTCDate(1);
+
+ var x = date2.getUTCMonth();
+ date2.setUTCMonth(x - (x % multiple));
+ break;
+ case SimileAjax.DateTime.YEAR:
+ clearInYear(date2);
+
+ var x = date2.getUTCFullYear();
+ date2.setUTCFullYear(x - (x % multiple));
+ break;
+ case SimileAjax.DateTime.DECADE:
+ clearInYear(date2);
+ date2.setUTCFullYear(Math.floor(date2.getUTCFullYear() / 10) * 10);
+ break;
+ case SimileAjax.DateTime.CENTURY:
+ clearInYear(date2);
+ date2.setUTCFullYear(Math.floor(date2.getUTCFullYear() / 100) * 100);
+ break;
+ case SimileAjax.DateTime.MILLENNIUM:
+ clearInYear(date2);
+ date2.setUTCFullYear(Math.floor(date2.getUTCFullYear() / 1000) * 1000);
+ break;
+ }
+
+ date.setTime(date2.getTime() - timeShift);
+};
+
+/**
+ * Rounds date objects up to the nearest interval or multiple of an interval.
+ * This method modifies the given date object, converting it to the given
+ * timezone if specified.
+ *
+ * @param {Date} date the date object to round
+ * @param {Number} intervalUnit a constant, integer index specifying an
+ * interval, e.g. SimileAjax.DateTime.HOUR
+ * @param {Number} timeZone a timezone shift, given in hours
+ * @param {Number} multiple a multiple of the interval to round by
+ * @param {Number} firstDayOfWeek an integer specifying the first day of the
+ * week, 0 corresponds to Sunday, 1 to Monday, etc.
+ * @see SimileAjax.DateTime.roundDownToInterval
+ */
+SimileAjax.DateTime.roundUpToInterval = function(date, intervalUnit, timeZone, multiple, firstDayOfWeek) {
+ var originalTime = date.getTime();
+ SimileAjax.DateTime.roundDownToInterval(date, intervalUnit, timeZone, multiple, firstDayOfWeek);
+ if (date.getTime() < originalTime) {
+ date.setTime(date.getTime() +
+ SimileAjax.DateTime.gregorianUnitLengths[intervalUnit] * multiple);
+ }
+};
+
+/**
+ * Increments a date object by a specified interval, taking into
+ * consideration the timezone.
+ *
+ * @param {Date} date the date object to increment
+ * @param {Number} intervalUnit a constant, integer index specifying an
+ * interval, e.g. SimileAjax.DateTime.HOUR
+ * @param {Number} timeZone the timezone offset in hours
+ */
+SimileAjax.DateTime.incrementByInterval = function(date, intervalUnit, timeZone) {
+ timeZone = (typeof timeZone == 'undefined') ? 0 : timeZone;
+
+ var timeShift = timeZone *
+ SimileAjax.DateTime.gregorianUnitLengths[SimileAjax.DateTime.HOUR];
+
+ var date2 = new Date(date.getTime() + timeShift);
+
+ switch(intervalUnit) {
+ case SimileAjax.DateTime.MILLISECOND:
+ date2.setTime(date2.getTime() + 1)
+ break;
+ case SimileAjax.DateTime.SECOND:
+ date2.setTime(date2.getTime() + 1000);
+ break;
+ case SimileAjax.DateTime.MINUTE:
+ date2.setTime(date2.getTime() +
+ SimileAjax.DateTime.gregorianUnitLengths[SimileAjax.DateTime.MINUTE]);
+ break;
+ case SimileAjax.DateTime.HOUR:
+ date2.setTime(date2.getTime() +
+ SimileAjax.DateTime.gregorianUnitLengths[SimileAjax.DateTime.HOUR]);
+ break;
+ case SimileAjax.DateTime.DAY:
+ date2.setUTCDate(date2.getUTCDate() + 1);
+ break;
+ case SimileAjax.DateTime.WEEK:
+ date2.setUTCDate(date2.getUTCDate() + 7);
+ break;
+ case SimileAjax.DateTime.MONTH:
+ date2.setUTCMonth(date2.getUTCMonth() + 1);
+ break;
+ case SimileAjax.DateTime.YEAR:
+ date2.setUTCFullYear(date2.getUTCFullYear() + 1);
+ break;
+ case SimileAjax.DateTime.DECADE:
+ date2.setUTCFullYear(date2.getUTCFullYear() + 10);
+ break;
+ case SimileAjax.DateTime.CENTURY:
+ date2.setUTCFullYear(date2.getUTCFullYear() + 100);
+ break;
+ case SimileAjax.DateTime.MILLENNIUM:
+ date2.setUTCFullYear(date2.getUTCFullYear() + 1000);
+ break;
+ }
+
+ date.setTime(date2.getTime() - timeShift);
+};
+
+/**
+ * Returns a new date object with the given time offset removed.
+ *
+ * @param {Date} date the starting date
+ * @param {Number} timeZone a timezone specified in an hour offset to remove
+ * @return {Date} a new date object with the offset removed
+ */
+SimileAjax.DateTime.removeTimeZoneOffset = function(date, timeZone) {
+ return new Date(date.getTime() +
+ timeZone * SimileAjax.DateTime.gregorianUnitLengths[SimileAjax.DateTime.HOUR]);
+};
+
+/**
+ * Returns the timezone of the user's browser.
+ *
+ * @return {Number} the timezone in the user's locale in hours
+ */
+SimileAjax.DateTime.getTimezone = function() {
+ var d = new Date().getTimezoneOffset();
+ return d / -60;
+};
diff --git a/site/app/webroot/js/simile/ajax/scripts/debug.js b/site/app/webroot/js/simile/ajax/scripts/debug.js
new file mode 100755
index 0000000..3fca6a5
--- /dev/null
+++ b/site/app/webroot/js/simile/ajax/scripts/debug.js
@@ -0,0 +1,94 @@
+/*==================================================
+ * Debug Utility Functions
+ *==================================================
+ */
+
+SimileAjax.Debug = {
+ silent: false
+};
+
+SimileAjax.Debug.log = function(msg) {
+ var f;
+ if ("console" in window && "log" in window.console) { // FireBug installed
+ f = function(msg2) {
+ console.log(msg2);
+ }
+ } else {
+ f = function(msg2) {
+ if (!SimileAjax.Debug.silent) {
+ alert(msg2);
+ }
+ }
+ }
+ SimileAjax.Debug.log = f;
+ f(msg);
+};
+
+SimileAjax.Debug.warn = function(msg) {
+ var f;
+ if ("console" in window && "warn" in window.console) { // FireBug installed
+ f = function(msg2) {
+ console.warn(msg2);
+ }
+ } else {
+ f = function(msg2) {
+ if (!SimileAjax.Debug.silent) {
+ alert(msg2);
+ }
+ }
+ }
+ SimileAjax.Debug.warn = f;
+ f(msg);
+};
+
+SimileAjax.Debug.exception = function(e, msg) {
+ var f, params = SimileAjax.parseURLParameters();
+ if (params.errors == "throw" || SimileAjax.params.errors == "throw") {
+ f = function(e2, msg2) {
+ throw(e2); // do not hide from browser's native debugging features
+ };
+ } else if ("console" in window && "error" in window.console) { // FireBug installed
+ f = function(e2, msg2) {
+ if (msg2 != null) {
+ console.error(msg2 + " %o", e2);
+ } else {
+ console.error(e2);
+ }
+ throw(e2); // do not hide from browser's native debugging features
+ };
+ } else {
+ f = function(e2, msg2) {
+ if (!SimileAjax.Debug.silent) {
+ alert("Caught exception: " + msg2 + "\n\nDetails: " + ("description" in e2 ? e2.description : e2));
+ }
+ throw(e2); // do not hide from browser's native debugging features
+ };
+ }
+ SimileAjax.Debug.exception = f;
+ f(e, msg);
+};
+
+SimileAjax.Debug.objectToString = function(o) {
+ return SimileAjax.Debug._objectToString(o, "");
+};
+
+SimileAjax.Debug._objectToString = function(o, indent) {
+ var indent2 = indent + " ";
+ if (typeof o == "object") {
+ var s = "{";
+ for (n in o) {
+ s += indent2 + n + ": " + SimileAjax.Debug._objectToString(o[n], indent2) + "\n";
+ }
+ s += indent + "}";
+ return s;
+ } else if (typeof o == "array") {
+ var s = "[";
+ for (var n = 0; n < o.length; n++) {
+ s += SimileAjax.Debug._objectToString(o[n], indent2) + "\n";
+ }
+ s += indent + "]";
+ return s;
+ } else {
+ return o;
+ }
+};
diff --git a/site/app/webroot/js/simile/ajax/scripts/dom.js b/site/app/webroot/js/simile/ajax/scripts/dom.js
new file mode 100755
index 0000000..9c6f5dd
--- /dev/null
+++ b/site/app/webroot/js/simile/ajax/scripts/dom.js
@@ -0,0 +1,324 @@
+/*==================================================
+ * DOM Utility Functions
+ *==================================================
+ */
+
+SimileAjax.DOM = new Object();
+
+SimileAjax.DOM.registerEventWithObject = function(elmt, eventName, obj, handlerName) {
+ SimileAjax.DOM.registerEvent(elmt, eventName, function(elmt2, evt, target) {
+ return obj[handlerName].call(obj, elmt2, evt, target);
+ });
+};
+
+SimileAjax.DOM.registerEvent = function(elmt, eventName, handler) {
+ var handler2 = function(evt) {
+ evt = (evt) ? evt : ((event) ? event : null);
+ if (evt) {
+ var target = (evt.target) ?
+ evt.target : ((evt.srcElement) ? evt.srcElement : null);
+ if (target) {
+ target = (target.nodeType == 1 || target.nodeType == 9) ?
+ target : target.parentNode;
+ }
+
+ return handler(elmt, evt, target);
+ }
+ return true;
+ }
+
+ if (SimileAjax.Platform.browser.isIE) {
+ elmt.attachEvent("on" + eventName, handler2);
+ } else {
+ elmt.addEventListener(eventName, handler2, false);
+ }
+};
+
+SimileAjax.DOM.getPageCoordinates = function(elmt) {
+ var left = 0;
+ var top = 0;
+
+ if (elmt.nodeType != 1) {
+ elmt = elmt.parentNode;
+ }
+
+ var elmt2 = elmt;
+ while (elmt2 != null) {
+ left += elmt2.offsetLeft;
+ top += elmt2.offsetTop;
+ elmt2 = elmt2.offsetParent;
+ }
+
+ var body = document.body;
+ while (elmt != null && elmt != body) {
+ if ("scrollLeft" in elmt) {
+ left -= elmt.scrollLeft;
+ top -= elmt.scrollTop;
+ }
+ elmt = elmt.parentNode;
+ }
+
+ return { left: left, top: top };
+};
+
+SimileAjax.DOM.getSize = function(elmt) {
+ var w = this.getStyle(elmt,"width");
+ var h = this.getStyle(elmt,"height");
+ if (w.indexOf("px") > -1) w = w.replace("px","");
+ if (h.indexOf("px") > -1) h = h.replace("px","");
+ return {
+ w: w,
+ h: h
+ }
+}
+
+SimileAjax.DOM.getStyle = function(elmt, styleProp) {
+ if (elmt.currentStyle) { // IE
+ var style = elmt.currentStyle[styleProp];
+ } else if (window.getComputedStyle) { // standard DOM
+ var style = document.defaultView.getComputedStyle(elmt, null).getPropertyValue(styleProp);
+ } else {
+ var style = "";
+ }
+ return style;
+}
+
+SimileAjax.DOM.getEventRelativeCoordinates = function(evt, elmt) {
+ if (SimileAjax.Platform.browser.isIE) {
+ return {
+ x: evt.offsetX,
+ y: evt.offsetY
+ };
+ } else {
+ var coords = SimileAjax.DOM.getPageCoordinates(elmt);
+ return {
+ x: evt.pageX - coords.left,
+ y: evt.pageY - coords.top
+ };
+ }
+};
+
+SimileAjax.DOM.getEventPageCoordinates = function(evt) {
+ if (SimileAjax.Platform.browser.isIE) {
+ return {
+ x: evt.clientX + document.body.scrollLeft,
+ y: evt.clientY + document.body.scrollTop
+ };
+ } else {
+ return {
+ x: evt.pageX,
+ y: evt.pageY
+ };
+ }
+};
+
+SimileAjax.DOM.hittest = function(x, y, except) {
+ return SimileAjax.DOM._hittest(document.body, x, y, except);
+};
+
+SimileAjax.DOM._hittest = function(elmt, x, y, except) {
+ var childNodes = elmt.childNodes;
+ outer: for (var i = 0; i < childNodes.length; i++) {
+ var childNode = childNodes[i];
+ for (var j = 0; j < except.length; j++) {
+ if (childNode == except[j]) {
+ continue outer;
+ }
+ }
+
+ if (childNode.offsetWidth == 0 && childNode.offsetHeight == 0) {
+ /*
+ * Sometimes SPAN elements have zero width and height but
+ * they have children like DIVs that cover non-zero areas.
+ */
+ var hitNode = SimileAjax.DOM._hittest(childNode, x, y, except);
+ if (hitNode != childNode) {
+ return hitNode;
+ }
+ } else {
+ var top = 0;
+ var left = 0;
+
+ var node = childNode;
+ while (node) {
+ top += node.offsetTop;
+ left += node.offsetLeft;
+ node = node.offsetParent;
+ }
+
+ if (left <= x && top <= y && (x - left) < childNode.offsetWidth && (y - top) < childNode.offsetHeight) {
+ return SimileAjax.DOM._hittest(childNode, x, y, except);
+ } else if (childNode.nodeType == 1 && childNode.tagName == "TR") {
+ /*
+ * Table row might have cells that span several rows.
+ */
+ var childNode2 = SimileAjax.DOM._hittest(childNode, x, y, except);
+ if (childNode2 != childNode) {
+ return childNode2;
+ }
+ }
+ }
+ }
+ return elmt;
+};
+
+SimileAjax.DOM.cancelEvent = function(evt) {
+ evt.returnValue = false;
+ evt.cancelBubble = true;
+ if ("preventDefault" in evt) {
+ evt.preventDefault();
+ }
+};
+
+SimileAjax.DOM.appendClassName = function(elmt, className) {
+ var classes = elmt.className.split(" ");
+ for (var i = 0; i < classes.length; i++) {
+ if (classes[i] == className) {
+ return;
+ }
+ }
+ classes.push(className);
+ elmt.className = classes.join(" ");
+};
+
+SimileAjax.DOM.createInputElement = function(type) {
+ var div = document.createElement("div");
+ div.innerHTML = "<input type='" + type + "' />";
+
+ return div.firstChild;
+};
+
+SimileAjax.DOM.createDOMFromTemplate = function(template) {
+ var result = {};
+ result.elmt = SimileAjax.DOM._createDOMFromTemplate(template, result, null);
+
+ return result;
+};
+
+SimileAjax.DOM._createDOMFromTemplate = function(templateNode, result, parentElmt) {
+ if (templateNode == null) {
+ /*
+ var node = doc.createTextNode("--null--");
+ if (parentElmt != null) {
+ parentElmt.appendChild(node);
+ }
+ return node;
+ */
+ return null;
+ } else if (typeof templateNode != "object") {
+ var node = document.createTextNode(templateNode);
+ if (parentElmt != null) {
+ parentElmt.appendChild(node);
+ }
+ return node;
+ } else {
+ var elmt = null;
+ if ("tag" in templateNode) {
+ var tag = templateNode.tag;
+ if (parentElmt != null) {
+ if (tag == "tr") {
+ elmt = parentElmt.insertRow(parentElmt.rows.length);
+ } else if (tag == "td") {
+ elmt = parentElmt.insertCell(parentElmt.cells.length);
+ }
+ }
+ if (elmt == null) {
+ elmt = tag == "input" ?
+ SimileAjax.DOM.createInputElement(templateNode.type) :
+ document.createElement(tag);
+
+ if (parentElmt != null) {
+ parentElmt.appendChild(elmt);
+ }
+ }
+ } else {
+ elmt = templateNode.elmt;
+ if (parentElmt != null) {
+ parentElmt.appendChild(elmt);
+ }
+ }
+
+ for (var attribute in templateNode) {
+ var value = templateNode[attribute];
+
+ if (attribute == "field") {
+ result[value] = elmt;
+
+ } else if (attribute == "className") {
+ elmt.className = value;
+ } else if (attribute == "id") {
+ elmt.id = value;
+ } else if (attribute == "title") {
+ elmt.title = value;
+ } else if (attribute == "type" && elmt.tagName == "input") {
+ // do nothing
+ } else if (attribute == "style") {
+ for (n in value) {
+ var v = value[n];
+ if (n == "float") {
+ n = SimileAjax.Platform.browser.isIE ? "styleFloat" : "cssFloat";
+ }
+ elmt.style[n] = v;
+ }
+ } else if (attribute == "children") {
+ for (var i = 0; i < value.length; i++) {
+ SimileAjax.DOM._createDOMFromTemplate(value[i], result, elmt);
+ }
+ } else if (attribute != "tag" && attribute != "elmt") {
+ elmt.setAttribute(attribute, value);
+ }
+ }
+ return elmt;
+ }
+}
+
+SimileAjax.DOM._cachedParent = null;
+SimileAjax.DOM.createElementFromString = function(s) {
+ if (SimileAjax.DOM._cachedParent == null) {
+ SimileAjax.DOM._cachedParent = document.createElement("div");
+ }
+ SimileAjax.DOM._cachedParent.innerHTML = s;
+ return SimileAjax.DOM._cachedParent.firstChild;
+};
+
+SimileAjax.DOM.createDOMFromString = function(root, s, fieldElmts) {
+ var elmt = typeof root == "string" ? document.createElement(root) : root;
+ elmt.innerHTML = s;
+
+ var dom = { elmt: elmt };
+ SimileAjax.DOM._processDOMChildrenConstructedFromString(dom, elmt, fieldElmts != null ? fieldElmts : {} );
+
+ return dom;
+};
+
+SimileAjax.DOM._processDOMConstructedFromString = function(dom, elmt, fieldElmts) {
+ var id = elmt.id;
+ if (id != null && id.length > 0) {
+ elmt.removeAttribute("id");
+ if (id in fieldElmts) {
+ var parentElmt = elmt.parentNode;
+ parentElmt.insertBefore(fieldElmts[id], elmt);
+ parentElmt.removeChild(elmt);
+
+ dom[id] = fieldElmts[id];
+ return;
+ } else {
+ dom[id] = elmt;
+ }
+ }
+
+ if (elmt.hasChildNodes()) {
+ SimileAjax.DOM._processDOMChildrenConstructedFromString(dom, elmt, fieldElmts);
+ }
+};
+
+SimileAjax.DOM._processDOMChildrenConstructedFromString = function(dom, elmt, fieldElmts) {
+ var node = elmt.firstChild;
+ while (node != null) {
+ var node2 = node.nextSibling;
+ if (node.nodeType == 1) {
+ SimileAjax.DOM._processDOMConstructedFromString(dom, node, fieldElmts);
+ }
+ node = node2;
+ }
+};
diff --git a/site/app/webroot/js/simile/ajax/scripts/graphics.js b/site/app/webroot/js/simile/ajax/scripts/graphics.js
new file mode 100755
index 0000000..0177c22
--- /dev/null
+++ b/site/app/webroot/js/simile/ajax/scripts/graphics.js
@@ -0,0 +1,572 @@
+/**
+ * @fileOverview Graphics utility functions and constants
+ * @name SimileAjax.Graphics
+ */
+
+SimileAjax.Graphics = new Object();
+
+/**
+ * A boolean value indicating whether PNG translucency is supported on the
+ * user's browser or not.
+ *
+ * @type Boolean
+ */
+SimileAjax.Graphics.pngIsTranslucent = (!SimileAjax.Platform.browser.isIE) || (SimileAjax.Platform.browser.majorVersion > 6);
+
+/*==================================================
+ * Opacity, translucency
+ *==================================================
+ */
+SimileAjax.Graphics._createTranslucentImage1 = function(url, verticalAlign) {
+ var elmt = document.createElement("img");
+ elmt.setAttribute("src", url);
+ if (verticalAlign != null) {
+ elmt.style.verticalAlign = verticalAlign;
+ }
+ return elmt;
+};
+SimileAjax.Graphics._createTranslucentImage2 = function(url, verticalAlign) {
+ var elmt = document.createElement("img");
+ elmt.style.width = "1px"; // just so that IE will calculate the size property
+ elmt.style.height = "1px";
+ elmt.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + url +"', sizingMethod='image')";
+ elmt.style.verticalAlign = (verticalAlign != null) ? verticalAlign : "middle";
+ return elmt;
+};
+
+/**
+ * Creates a DOM element for an <code>img</code> tag using the URL given. This
+ * is a convenience method that automatically includes the necessary CSS to
+ * allow for translucency, even on IE.
+ *
+ * @function
+ * @param {String} url the URL to the image
+ * @param {String} verticalAlign the CSS value for the image's vertical-align
+ * @return {Element} a DOM element containing the <code>img</code> tag
+ */
+SimileAjax.Graphics.createTranslucentImage = SimileAjax.Graphics.pngIsTranslucent ?
+ SimileAjax.Graphics._createTranslucentImage1 :
+ SimileAjax.Graphics._createTranslucentImage2;
+
+SimileAjax.Graphics._createTranslucentImageHTML1 = function(url, verticalAlign) {
+ return "<img src=\"" + url + "\"" +
+ (verticalAlign != null ? " style=\"vertical-align: " + verticalAlign + ";\"" : "") +
+ " />";
+};
+SimileAjax.Graphics._createTranslucentImageHTML2 = function(url, verticalAlign) {
+ var style =
+ "width: 1px; height: 1px; " +
+ "filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + url +"', sizingMethod='image');" +
+ (verticalAlign != null ? " vertical-align: " + verticalAlign + ";" : "");
+
+ return "<img src='" + url + "' style=\"" + style + "\" />";
+};
+
+/**
+ * Creates an HTML string for an <code>img</code> tag using the URL given.
+ * This is a convenience method that automatically includes the necessary CSS
+ * to allow for translucency, even on IE.
+ *
+ * @function
+ * @param {String} url the URL to the image
+ * @param {String} verticalAlign the CSS value for the image's vertical-align
+ * @return {String} a string containing the <code>img</code> tag
+ */
+SimileAjax.Graphics.createTranslucentImageHTML = SimileAjax.Graphics.pngIsTranslucent ?
+ SimileAjax.Graphics._createTranslucentImageHTML1 :
+ SimileAjax.Graphics._createTranslucentImageHTML2;
+
+/**
+ * Sets the opacity on the given DOM element.
+ *
+ * @param {Element} elmt the DOM element to set the opacity on
+ * @param {Number} opacity an integer from 0 to 100 specifying the opacity
+ */
+SimileAjax.Graphics.setOpacity = function(elmt, opacity) {
+ if (SimileAjax.Platform.browser.isIE) {
+ elmt.style.filter = "progid:DXImageTransform.Microsoft.Alpha(Style=0,Opacity=" + opacity + ")";
+ } else {
+ var o = (opacity / 100).toString();
+ elmt.style.opacity = o;
+ elmt.style.MozOpacity = o;
+ }
+};
+
+/*==================================================
+ * Bubble
+ *==================================================
+ */
+SimileAjax.Graphics._bubbleMargins = {
+ top: 33,
+ bottom: 42,
+ left: 33,
+ right: 40
+}
+
+// pixels from boundary of the whole bubble div to the tip of the arrow
+SimileAjax.Graphics._arrowOffsets = {
+ top: 0,
+ bottom: 9,
+ left: 1,
+ right: 8
+}
+
+SimileAjax.Graphics._bubblePadding = 15;
+SimileAjax.Graphics._bubblePointOffset = 6;
+SimileAjax.Graphics._halfArrowWidth = 18;
+
+/**
+ * Creates a nice, rounded bubble popup with the given content in a div,
+ * page coordinates and a suggested width. The bubble will point to the
+ * location on the page as described by pageX and pageY. All measurements
+ * should be given in pixels.
+ *
+ * @param {Element} the content div
+ * @param {Number} pageX the x coordinate of the point to point to
+ * @param {Number} pageY the y coordinate of the point to point to
+ * @param {Number} contentWidth a suggested width of the content
+ * @param {String} orientation a string ("top", "bottom", "left", or "right")
+ * that describes the orientation of the arrow on the bubble
+ */
+SimileAjax.Graphics.createBubbleForContentAndPoint = function(div, pageX, pageY, contentWidth, orientation) {
+ if (typeof contentWidth != "number") {
+ contentWidth = 300;
+ }
+
+ div.style.position = "absolute";
+ div.style.left = "-5000px";
+ div.style.top = "0px";
+ div.style.width = contentWidth + "px";
+ document.body.appendChild(div);
+
+ window.setTimeout(function() {
+ var width = div.scrollWidth + 10;
+ var height = div.scrollHeight + 10;
+
+ var bubble = SimileAjax.Graphics.createBubbleForPoint(pageX, pageY, width, height, orientation);
+
+ document.body.removeChild(div);
+ div.style.position = "static";
+ div.style.left = "";
+ div.style.top = "";
+ div.style.width = width + "px";
+ bubble.content.appendChild(div);
+ }, 200);
+};
+
+/**
+ * Creates a nice, rounded bubble popup with the given page coordinates and
+ * content dimensions. The bubble will point to the location on the page
+ * as described by pageX and pageY. All measurements should be given in
+ * pixels.
+ *
+ * @param {Number} pageX the x coordinate of the point to point to
+ * @param {Number} pageY the y coordinate of the point to point to
+ * @param {Number} contentWidth the width of the content box in the bubble
+ * @param {Number} contentHeight the height of the content box in the bubble
+ * @param {String} orientation a string ("top", "bottom", "left", or "right")
+ * that describes the orientation of the arrow on the bubble
+ * @return {Element} a DOM element for the newly created bubble
+ */
+SimileAjax.Graphics.createBubbleForPoint = function(pageX, pageY, contentWidth, contentHeight, orientation) {
+ function getWindowDims() {
+ if (typeof window.innerHeight == 'number') {
+ return { w:window.innerWidth, h:window.innerHeight }; // Non-IE
+ } else if (document.documentElement && document.documentElement.clientHeight) {
+ return { // IE6+, in "standards compliant mode"
+ w:document.documentElement.clientWidth,
+ h:document.documentElement.clientHeight
+ };
+ } else if (document.body && document.body.clientHeight) {
+ return { // IE 4 compatible
+ w:document.body.clientWidth,
+ h:document.body.clientHeight
+ };
+ }
+ }
+
+ var close = function() {
+ if (!bubble._closed) {
+ document.body.removeChild(bubble._div);
+ bubble._doc = null;
+ bubble._div = null;
+ bubble._content = null;
+ bubble._closed = true;
+ }
+ }
+ var bubble = {
+ _closed: false
+ };
+
+ var dims = getWindowDims();
+ var docWidth = dims.w;
+ var docHeight = dims.h;
+
+ var margins = SimileAjax.Graphics._bubbleMargins;
+ contentWidth = parseInt(contentWidth, 10); // harden against bad input bugs
+ contentHeight = parseInt(contentHeight, 10); // getting numbers-as-strings
+ var bubbleWidth = margins.left + contentWidth + margins.right;
+ var bubbleHeight = margins.top + contentHeight + margins.bottom;
+
+ var pngIsTranslucent = SimileAjax.Graphics.pngIsTranslucent;
+ var urlPrefix = SimileAjax.urlPrefix;
+
+ var setImg = function(elmt, url, width, height) {
+ elmt.style.position = "absolute";
+ elmt.style.width = width + "px";
+ elmt.style.height = height + "px";
+ if (pngIsTranslucent) {
+ elmt.style.background = "url(" + url + ")";
+ } else {
+ elmt.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + url +"', sizingMethod='crop')";
+ }
+ }
+ var div = document.createElement("div");
+ div.style.width = bubbleWidth + "px";
+ div.style.height = bubbleHeight + "px";
+ div.style.position = "absolute";
+ div.style.zIndex = 1000;
+
+ var layer = SimileAjax.WindowManager.pushLayer(close, true, div);
+ bubble._div = div;
+ bubble.close = function() { SimileAjax.WindowManager.popLayer(layer); }
+
+ var divInner = document.createElement("div");
+ divInner.style.width = "100%";
+ divInner.style.height = "100%";
+ divInner.style.position = "relative";
+ div.appendChild(divInner);
+
+ var createImg = function(url, left, top, width, height) {
+ var divImg = document.createElement("div");
+ divImg.style.left = left + "px";
+ divImg.style.top = top + "px";
+ setImg(divImg, url, width, height);
+ divInner.appendChild(divImg);
+ }
+
+ createImg(urlPrefix + "images/bubble-top-left.png", 0, 0, margins.left, margins.top);
+ createImg(urlPrefix + "images/bubble-top.png", margins.left, 0, contentWidth, margins.top);
+ createImg(urlPrefix + "images/bubble-top-right.png", margins.left + contentWidth, 0, margins.right, margins.top);
+
+ createImg(urlPrefix + "images/bubble-left.png", 0, margins.top, margins.left, contentHeight);
+ createImg(urlPrefix + "images/bubble-right.png", margins.left + contentWidth, margins.top, margins.right, contentHeight);
+
+ createImg(urlPrefix + "images/bubble-bottom-left.png", 0, margins.top + contentHeight, margins.left, margins.bottom);
+ createImg(urlPrefix + "images/bubble-bottom.png", margins.left, margins.top + contentHeight, contentWidth, margins.bottom);
+ createImg(urlPrefix + "images/bubble-bottom-right.png", margins.left + contentWidth, margins.top + contentHeight, margins.right, margins.bottom);
+
+ var divClose = document.createElement("div");
+ divClose.style.left = (bubbleWidth - margins.right + SimileAjax.Graphics._bubblePadding - 16 - 2) + "px";
+ divClose.style.top = (margins.top - SimileAjax.Graphics._bubblePadding + 1) + "px";
+ divClose.style.cursor = "pointer";
+ setImg(divClose, urlPrefix + "images/close-button.png", 16, 16);
+ SimileAjax.WindowManager.registerEventWithObject(divClose, "click", bubble, "close");
+ divInner.appendChild(divClose);
+
+ var divContent = document.createElement("div");
+ divContent.style.position = "absolute";
+ divContent.style.left = margins.left + "px";
+ divContent.style.top = margins.top + "px";
+ divContent.style.width = contentWidth + "px";
+ divContent.style.height = contentHeight + "px";
+ divContent.style.overflow = "auto";
+ divContent.style.background = "white";
+ divInner.appendChild(divContent);
+ bubble.content = divContent;
+
+ (function() {
+ if (pageX - SimileAjax.Graphics._halfArrowWidth - SimileAjax.Graphics._bubblePadding > 0 &&
+ pageX + SimileAjax.Graphics._halfArrowWidth + SimileAjax.Graphics._bubblePadding < docWidth) {
+
+ var left = pageX - Math.round(contentWidth / 2) - margins.left;
+ left = pageX < (docWidth / 2) ?
+ Math.max(left, -(margins.left - SimileAjax.Graphics._bubblePadding)) :
+ Math.min(left, docWidth + (margins.right - SimileAjax.Graphics._bubblePadding) - bubbleWidth);
+
+ if ((orientation && orientation == "top") || (!orientation && (pageY - SimileAjax.Graphics._bubblePointOffset - bubbleHeight > 0))) { // top
+ var divImg = document.createElement("div");
+
+ divImg.style.left = (pageX - SimileAjax.Graphics._halfArrowWidth - left) + "px";
+ divImg.style.top = (margins.top + contentHeight) + "px";
+ setImg(divImg, urlPrefix + "images/bubble-bottom-arrow.png", 37, margins.bottom);
+ divInner.appendChild(divImg);
+
+ div.style.left = left + "px";
+ div.style.top = (pageY - SimileAjax.Graphics._bubblePointOffset - bubbleHeight +
+ SimileAjax.Graphics._arrowOffsets.bottom) + "px";
+
+ return;
+ } else if ((orientation && orientation == "bottom") || (!orientation && (pageY + SimileAjax.Graphics._bubblePointOffset + bubbleHeight < docHeight))) { // bottom
+ var divImg = document.createElement("div");
+
+ divImg.style.left = (pageX - SimileAjax.Graphics._halfArrowWidth - left) + "px";
+ divImg.style.top = "0px";
+ setImg(divImg, urlPrefix + "images/bubble-top-arrow.png", 37, margins.top);
+ divInner.appendChild(divImg);
+
+ div.style.left = left + "px";
+ div.style.top = (pageY + SimileAjax.Graphics._bubblePointOffset -
+ SimileAjax.Graphics._arrowOffsets.top) + "px";
+
+ return;
+ }
+ }
+
+ var top = pageY - Math.round(contentHeight / 2) - margins.top;
+ top = pageY < (docHeight / 2) ?
+ Math.max(top, -(margins.top - SimileAjax.Graphics._bubblePadding)) :
+ Math.min(top, docHeight + (margins.bottom - SimileAjax.Graphics._bubblePadding) - bubbleHeight);
+
+ if ((orientation && orientation == "left") || (!orientation && (pageX - SimileAjax.Graphics._bubblePointOffset - bubbleWidth > 0))) { // left
+ var divImg = document.createElement("div");
+
+ divImg.style.left = (margins.left + contentWidth) + "px";
+ divImg.style.top = (pageY - SimileAjax.Graphics._halfArrowWidth - top) + "px";
+ setImg(divImg, urlPrefix + "images/bubble-right-arrow.png", margins.right, 37);
+ divInner.appendChild(divImg);
+
+ div.style.left = (pageX - SimileAjax.Graphics._bubblePointOffset - bubbleWidth +
+ SimileAjax.Graphics._arrowOffsets.right) + "px";
+ div.style.top = top + "px";
+ } else if ((orientation && orientation == "right") || (!orientation && (pageX - SimileAjax.Graphics._bubblePointOffset - bubbleWidth < docWidth))) { // right
+ var divImg = document.createElement("div");
+
+ divImg.style.left = "0px";
+ divImg.style.top = (pageY - SimileAjax.Graphics._halfArrowWidth - top) + "px";
+ setImg(divImg, urlPrefix + "images/bubble-left-arrow.png", margins.left, 37);
+ divInner.appendChild(divImg);
+
+ div.style.left = (pageX + SimileAjax.Graphics._bubblePointOffset -
+ SimileAjax.Graphics._arrowOffsets.left) + "px";
+ div.style.top = top + "px";
+ }
+ })();
+
+ document.body.appendChild(div);
+
+ return bubble;
+};
+
+/**
+ * Creates a floating, rounded message bubble in the center of the window for
+ * displaying modal information, e.g. "Loading..."
+ *
+ * @param {Document} doc the root document for the page to render on
+ * @param {Object} an object with two properties, contentDiv and containerDiv,
+ * consisting of the newly created DOM elements
+ */
+SimileAjax.Graphics.createMessageBubble = function(doc) {
+ var containerDiv = doc.createElement("div");
+ if (SimileAjax.Graphics.pngIsTranslucent) {
+ var topDiv = doc.createElement("div");
+ topDiv.style.height = "33px";
+ topDiv.style.background = "url(" + SimileAjax.urlPrefix + "images/message-top-left.png) top left no-repeat";
+ topDiv.style.paddingLeft = "44px";
+ containerDiv.appendChild(topDiv);
+
+ var topRightDiv = doc.createElement("div");
+ topRightDiv.style.height = "33px";
+ topRightDiv.style.background = "url(" + SimileAjax.urlPrefix + "images/message-top-right.png) top right no-repeat";
+ topDiv.appendChild(topRightDiv);
+
+ var middleDiv = doc.createElement("div");
+ middleDiv.style.background = "url(" + SimileAjax.urlPrefix + "images/message-left.png) top left repeat-y";
+ middleDiv.style.paddingLeft = "44px";
+ containerDiv.appendChild(middleDiv);
+
+ var middleRightDiv = doc.createElement("div");
+ middleRightDiv.style.background = "url(" + SimileAjax.urlPrefix + "images/message-right.png) top right repeat-y";
+ middleRightDiv.style.paddingRight = "44px";
+ middleDiv.appendChild(middleRightDiv);
+
+ var contentDiv = doc.createElement("div");
+ middleRightDiv.appendChild(contentDiv);
+
+ var bottomDiv = doc.createElement("div");
+ bottomDiv.style.height = "55px";
+ bottomDiv.style.background = "url(" + SimileAjax.urlPrefix + "images/message-bottom-left.png) bottom left no-repeat";
+ bottomDiv.style.paddingLeft = "44px";
+ containerDiv.appendChild(bottomDiv);
+
+ var bottomRightDiv = doc.createElement("div");
+ bottomRightDiv.style.height = "55px";
+ bottomRightDiv.style.background = "url(" + SimileAjax.urlPrefix + "images/message-bottom-right.png) bottom right no-repeat";
+ bottomDiv.appendChild(bottomRightDiv);
+ } else {
+ containerDiv.style.border = "2px solid #7777AA";
+ containerDiv.style.padding = "20px";
+ containerDiv.style.background = "white";
+ SimileAjax.Graphics.setOpacity(containerDiv, 90);
+
+ var contentDiv = doc.createElement("div");
+ containerDiv.appendChild(contentDiv);
+ }
+
+ return {
+ containerDiv: containerDiv,
+ contentDiv: contentDiv
+ };
+};
+
+/*==================================================
+ * Animation
+ *==================================================
+ */
+
+/**
+ * Creates an animation for a function, and an interval of values. The word
+ * "animation" here is used in the sense of repeatedly calling a function with
+ * a current value from within an interval, and a delta value.
+ *
+ * @param {Function} f a function to be called every 50 milliseconds throughout
+ * the animation duration, of the form f(current, delta), where current is
+ * the current value within the range and delta is the current change.
+ * @param {Number} from a starting value
+ * @param {Number} to an ending value
+ * @param {Number} duration the duration of the animation in milliseconds
+ * @param {Function} [cont] an optional function that is called at the end of
+ * the animation, i.e. a continuation.
+ * @return {SimileAjax.Graphics._Animation} a new animation object
+ */
+SimileAjax.Graphics.createAnimation = function(f, from, to, duration, cont) {
+ return new SimileAjax.Graphics._Animation(f, from, to, duration, cont);
+};
+
+SimileAjax.Graphics._Animation = function(f, from, to, duration, cont) {
+ this.f = f;
+ this.cont = (typeof cont == "function") ? cont : function() {};
+
+ this.from = from;
+ this.to = to;
+ this.current = from;
+
+ this.duration = duration;
+ this.start = new Date().getTime();
+ this.timePassed = 0;
+};
+
+/**
+ * Runs this animation.
+ */
+SimileAjax.Graphics._Animation.prototype.run = function() {
+ var a = this;
+ window.setTimeout(function() { a.step(); }, 50);
+};
+
+/**
+ * Increments this animation by one step, and then continues the animation with
+ * <code>run()</code>.
+ */
+SimileAjax.Graphics._Animation.prototype.step = function() {
+ this.timePassed += 50;
+
+ var timePassedFraction = this.timePassed / this.duration;
+ var parameterFraction = -Math.cos(timePassedFraction * Math.PI) / 2 + 0.5;
+ var current = parameterFraction * (this.to - this.from) + this.from;
+
+ try {
+ this.f(current, current - this.current);
+ } catch (e) {
+ }
+ this.current = current;
+
+ if (this.timePassed < this.duration) {
+ this.run();
+ } else {
+ this.f(this.to, 0);
+ this["cont"]();
+ }
+};
+
+/*==================================================
+ * CopyPasteButton
+ *
+ * Adapted from http://spaces.live.com/editorial/rayozzie/demo/liveclip/liveclipsample/techPreview.html.
+ *==================================================
+ */
+
+/**
+ * Creates a button and textarea for displaying structured data and copying it
+ * to the clipboard. The data is dynamically generated by the given
+ * createDataFunction parameter.
+ *
+ * @param {String} image an image URL to use as the background for the
+ * generated box
+ * @param {Number} width the width in pixels of the generated box
+ * @param {Number} height the height in pixels of the generated box
+ * @param {Function} createDataFunction a function that is called with no
+ * arguments to generate the structured data
+ * @return a new DOM element
+ */
+SimileAjax.Graphics.createStructuredDataCopyButton = function(image, width, height, createDataFunction) {
+ var div = document.createElement("div");
+ div.style.position = "relative";
+ div.style.display = "inline";
+ div.style.width = width + "px";
+ div.style.height = height + "px";
+ div.style.overflow = "hidden";
+ div.style.margin = "2px";
+
+ if (SimileAjax.Graphics.pngIsTranslucent) {
+ div.style.background = "url(" + image + ") no-repeat";
+ } else {
+ div.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + image +"', sizingMethod='image')";
+ }
+
+ var style;
+ if (SimileAjax.Platform.browser.isIE) {
+ style = "filter:alpha(opacity=0)";
+ } else {
+ style = "opacity: 0";
+ }
+ div.innerHTML = "<textarea rows='1' autocomplete='off' value='none' style='" + style + "' />";
+
+ var textarea = div.firstChild;
+ textarea.style.width = width + "px";
+ textarea.style.height = height + "px";
+ textarea.onmousedown = function(evt) {
+ evt = (evt) ? evt : ((event) ? event : null);
+ if (evt.button == 2) {
+ textarea.value = createDataFunction();
+ textarea.select();
+ }
+ };
+
+ return div;
+};
+
+SimileAjax.Graphics.getFontRenderingContext = function(elmt, width) {
+ return new SimileAjax.Graphics._FontRenderingContext(elmt, width);
+};
+
+SimileAjax.Graphics._FontRenderingContext = function(elmt, width) {
+ this._elmt = elmt;
+ this._elmt.style.visibility = "hidden";
+ if (typeof width == "string") {
+ this._elmt.style.width = width;
+ } else if (typeof width == "number") {
+ this._elmt.style.width = width + "px";
+ }
+};
+
+SimileAjax.Graphics._FontRenderingContext.prototype.dispose = function() {
+ this._elmt = null;
+};
+
+SimileAjax.Graphics._FontRenderingContext.prototype.update = function() {
+ this._elmt.innerHTML = "A";
+ this._lineHeight = this._elmt.offsetHeight;
+};
+
+SimileAjax.Graphics._FontRenderingContext.prototype.computeSize = function(text) {
+ this._elmt.innerHTML = text;
+ return {
+ width: this._elmt.offsetWidth,
+ height: this._elmt.offsetHeight
+ };
+};
+
+SimileAjax.Graphics._FontRenderingContext.prototype.getLineHeight = function() {
+ return this._lineHeight;
+};
diff --git a/site/app/webroot/js/simile/ajax/scripts/history.js b/site/app/webroot/js/simile/ajax/scripts/history.js
new file mode 100755
index 0000000..678b1ec
--- /dev/null
+++ b/site/app/webroot/js/simile/ajax/scripts/history.js
@@ -0,0 +1,220 @@
+/*======================================================================
+ * History
+ *
+ * This is a singleton that keeps track of undoable user actions and
+ * performs undos and redos in response to the browser's Back and
+ * Forward buttons.
+ *
+ * Call addAction(action) to register an undoable user action. action
+ * must have 4 fields:
+ *
+ * perform: an argument-less function that carries out the action
+ * undo: an argument-less function that undos the action
+ * label: a short, user-friendly string describing the action
+ * uiLayer: the UI layer on which the action takes place
+ *
+ * By default, the history keeps track of upto 10 actions. You can
+ * configure this behavior by setting
+ * SimileAjax.History.maxHistoryLength
+ * to a different number.
+ *
+ * An iframe is inserted into the document's body element to track
+ * onload events.
+ *======================================================================
+ */
+
+SimileAjax.History = {
+ maxHistoryLength: 10,
+ historyFile: "__history__.html",
+ enabled: true,
+
+ _initialized: false,
+ _listeners: new SimileAjax.ListenerQueue(),
+
+ _actions: [],
+ _baseIndex: 0,
+ _currentIndex: 0,
+
+ _plainDocumentTitle: document.title
+};
+
+SimileAjax.History.formatHistoryEntryTitle = function(actionLabel) {
+ return SimileAjax.History._plainDocumentTitle + " {" + actionLabel + "}";
+};
+
+SimileAjax.History.initialize = function() {
+ if (SimileAjax.History._initialized) {
+ return;
+ }
+
+ if (SimileAjax.History.enabled) {
+ var iframe = document.createElement("iframe");
+ iframe.id = "simile-ajax-history";
+ iframe.style.position = "absolute";
+ iframe.style.width = "10px";
+ iframe.style.height = "10px";
+ iframe.style.top = "0px";
+ iframe.style.left = "0px";
+ iframe.style.visibility = "hidden";
+ iframe.src = SimileAjax.History.historyFile + "?0";
+
+ document.body.appendChild(iframe);
+ SimileAjax.DOM.registerEvent(iframe, "load", SimileAjax.History._handleIFrameOnLoad);
+
+ SimileAjax.History._iframe = iframe;
+ }
+ SimileAjax.History._initialized = true;
+};
+
+SimileAjax.History.addListener = function(listener) {
+ SimileAjax.History.initialize();
+
+ SimileAjax.History._listeners.add(listener);
+};
+
+SimileAjax.History.removeListener = function(listener) {
+ SimileAjax.History.initialize();
+
+ SimileAjax.History._listeners.remove(listener);
+};
+
+SimileAjax.History.addAction = function(action) {
+ SimileAjax.History.initialize();
+
+ SimileAjax.History._listeners.fire("onBeforePerform", [ action ]);
+ window.setTimeout(function() {
+ try {
+ action.perform();
+ SimileAjax.History._listeners.fire("onAfterPerform", [ action ]);
+
+ if (SimileAjax.History.enabled) {
+ SimileAjax.History._actions = SimileAjax.History._actions.slice(
+ 0, SimileAjax.History._currentIndex - SimileAjax.History._baseIndex);
+
+ SimileAjax.History._actions.push(action);
+ SimileAjax.History._currentIndex++;
+
+ var diff = SimileAjax.History._actions.length - SimileAjax.History.maxHistoryLength;
+ if (diff > 0) {
+ SimileAjax.History._actions = SimileAjax.History._actions.slice(diff);
+ SimileAjax.History._baseIndex += diff;
+ }
+
+ try {
+ SimileAjax.History._iframe.contentWindow.location.search =
+ "?" + SimileAjax.History._currentIndex;
+ } catch (e) {
+ /*
+ * We can't modify location.search most probably because it's a file:// url.
+ * We'll just going to modify the document's title.
+ */
+ var title = SimileAjax.History.formatHistoryEntryTitle(action.label);
+ document.title = title;
+ }
+ }
+ } catch (e) {
+ SimileAjax.Debug.exception(e, "Error adding action {" + action.label + "} to history");
+ }
+ }, 0);
+};
+
+SimileAjax.History.addLengthyAction = function(perform, undo, label) {
+ SimileAjax.History.addAction({
+ perform: perform,
+ undo: undo,
+ label: label,
+ uiLayer: SimileAjax.WindowManager.getBaseLayer(),
+ lengthy: true
+ });
+};
+
+SimileAjax.History._handleIFrameOnLoad = function() {
+ /*
+ * This function is invoked when the user herself
+ * navigates backward or forward. We need to adjust
+ * the application's state accordingly.
+ */
+
+ try {
+ var q = SimileAjax.History._iframe.contentWindow.location.search;
+ var c = (q.length == 0) ? 0 : Math.max(0, parseInt(q.substr(1)));
+
+ var finishUp = function() {
+ var diff = c - SimileAjax.History._currentIndex;
+ SimileAjax.History._currentIndex += diff;
+ SimileAjax.History._baseIndex += diff;
+
+ SimileAjax.History._iframe.contentWindow.location.search = "?" + c;
+ };
+
+ if (c < SimileAjax.History._currentIndex) { // need to undo
+ SimileAjax.History._listeners.fire("onBeforeUndoSeveral", []);
+ window.setTimeout(function() {
+ while (SimileAjax.History._currentIndex > c &&
+ SimileAjax.History._currentIndex > SimileAjax.History._baseIndex) {
+
+ SimileAjax.History._currentIndex--;
+
+ var action = SimileAjax.History._actions[SimileAjax.History._currentIndex - SimileAjax.History._baseIndex];
+
+ try {
+ action.undo();
+ } catch (e) {
+ SimileAjax.Debug.exception(e, "History: Failed to undo action {" + action.label + "}");
+ }
+ }
+
+ SimileAjax.History._listeners.fire("onAfterUndoSeveral", []);
+ finishUp();
+ }, 0);
+ } else if (c > SimileAjax.History._currentIndex) { // need to redo
+ SimileAjax.History._listeners.fire("onBeforeRedoSeveral", []);
+ window.setTimeout(function() {
+ while (SimileAjax.History._currentIndex < c &&
+ SimileAjax.History._currentIndex - SimileAjax.History._baseIndex < SimileAjax.History._actions.length) {
+
+ var action = SimileAjax.History._actions[SimileAjax.History._currentIndex - SimileAjax.History._baseIndex];
+
+ try {
+ action.perform();
+ } catch (e) {
+ SimileAjax.Debug.exception(e, "History: Failed to redo action {" + action.label + "}");
+ }
+
+ SimileAjax.History._currentIndex++;
+ }
+
+ SimileAjax.History._listeners.fire("onAfterRedoSeveral", []);
+ finishUp();
+ }, 0);
+ } else {
+ var index = SimileAjax.History._currentIndex - SimileAjax.History._baseIndex - 1;
+ var title = (index >= 0 && index < SimileAjax.History._actions.length) ?
+ SimileAjax.History.formatHistoryEntryTitle(SimileAjax.History._actions[index].label) :
+ SimileAjax.History._plainDocumentTitle;
+
+ SimileAjax.History._iframe.contentWindow.document.title = title;
+ document.title = title;
+ }
+ } catch (e) {
+ // silent
+ }
+};
+
+SimileAjax.History.getNextUndoAction = function() {
+ try {
+ var index = SimileAjax.History._currentIndex - SimileAjax.History._baseIndex - 1;
+ return SimileAjax.History._actions[index];
+ } catch (e) {
+ return null;
+ }
+};
+
+SimileAjax.History.getNextRedoAction = function() {
+ try {
+ var index = SimileAjax.History._currentIndex - SimileAjax.History._baseIndex;
+ return SimileAjax.History._actions[index];
+ } catch (e) {
+ return null;
+ }
+};
diff --git a/site/app/webroot/js/simile/ajax/scripts/html.js b/site/app/webroot/js/simile/ajax/scripts/html.js
new file mode 100755
index 0000000..cedeb4a
--- /dev/null
+++ b/site/app/webroot/js/simile/ajax/scripts/html.js
@@ -0,0 +1,274 @@
+/*==================================================
+ * HTML Utility Functions
+ *==================================================
+ */
+
+SimileAjax.HTML = new Object();
+
+SimileAjax.HTML._e2uHash = {};
+(function() {
+ var e2uHash = SimileAjax.HTML._e2uHash;
+ e2uHash['nbsp']= '\u00A0[space]';
+ e2uHash['iexcl']= '\u00A1';
+ e2uHash['cent']= '\u00A2';
+ e2uHash['pound']= '\u00A3';
+ e2uHash['curren']= '\u00A4';
+ e2uHash['yen']= '\u00A5';
+ e2uHash['brvbar']= '\u00A6';
+ e2uHash['sect']= '\u00A7';
+ e2uHash['uml']= '\u00A8';
+ e2uHash['copy']= '\u00A9';
+ e2uHash['ordf']= '\u00AA';
+ e2uHash['laquo']= '\u00AB';
+ e2uHash['not']= '\u00AC';
+ e2uHash['shy']= '\u00AD';
+ e2uHash['reg']= '\u00AE';
+ e2uHash['macr']= '\u00AF';
+ e2uHash['deg']= '\u00B0';
+ e2uHash['plusmn']= '\u00B1';
+ e2uHash['sup2']= '\u00B2';
+ e2uHash['sup3']= '\u00B3';
+ e2uHash['acute']= '\u00B4';
+ e2uHash['micro']= '\u00B5';
+ e2uHash['para']= '\u00B6';
+ e2uHash['middot']= '\u00B7';
+ e2uHash['cedil']= '\u00B8';
+ e2uHash['sup1']= '\u00B9';
+ e2uHash['ordm']= '\u00BA';
+ e2uHash['raquo']= '\u00BB';
+ e2uHash['frac14']= '\u00BC';
+ e2uHash['frac12']= '\u00BD';
+ e2uHash['frac34']= '\u00BE';
+ e2uHash['iquest']= '\u00BF';
+ e2uHash['Agrave']= '\u00C0';
+ e2uHash['Aacute']= '\u00C1';
+ e2uHash['Acirc']= '\u00C2';
+ e2uHash['Atilde']= '\u00C3';
+ e2uHash['Auml']= '\u00C4';
+ e2uHash['Aring']= '\u00C5';
+ e2uHash['AElig']= '\u00C6';
+ e2uHash['Ccedil']= '\u00C7';
+ e2uHash['Egrave']= '\u00C8';
+ e2uHash['Eacute']= '\u00C9';
+ e2uHash['Ecirc']= '\u00CA';
+ e2uHash['Euml']= '\u00CB';
+ e2uHash['Igrave']= '\u00CC';
+ e2uHash['Iacute']= '\u00CD';
+ e2uHash['Icirc']= '\u00CE';
+ e2uHash['Iuml']= '\u00CF';
+ e2uHash['ETH']= '\u00D0';
+ e2uHash['Ntilde']= '\u00D1';
+ e2uHash['Ograve']= '\u00D2';
+ e2uHash['Oacute']= '\u00D3';
+ e2uHash['Ocirc']= '\u00D4';
+ e2uHash['Otilde']= '\u00D5';
+ e2uHash['Ouml']= '\u00D6';
+ e2uHash['times']= '\u00D7';
+ e2uHash['Oslash']= '\u00D8';
+ e2uHash['Ugrave']= '\u00D9';
+ e2uHash['Uacute']= '\u00DA';
+ e2uHash['Ucirc']= '\u00DB';
+ e2uHash['Uuml']= '\u00DC';
+ e2uHash['Yacute']= '\u00DD';
+ e2uHash['THORN']= '\u00DE';
+ e2uHash['szlig']= '\u00DF';
+ e2uHash['agrave']= '\u00E0';
+ e2uHash['aacute']= '\u00E1';
+ e2uHash['acirc']= '\u00E2';
+ e2uHash['atilde']= '\u00E3';
+ e2uHash['auml']= '\u00E4';
+ e2uHash['aring']= '\u00E5';
+ e2uHash['aelig']= '\u00E6';
+ e2uHash['ccedil']= '\u00E7';
+ e2uHash['egrave']= '\u00E8';
+ e2uHash['eacute']= '\u00E9';
+ e2uHash['ecirc']= '\u00EA';
+ e2uHash['euml']= '\u00EB';
+ e2uHash['igrave']= '\u00EC';
+ e2uHash['iacute']= '\u00ED';
+ e2uHash['icirc']= '\u00EE';
+ e2uHash['iuml']= '\u00EF';
+ e2uHash['eth']= '\u00F0';
+ e2uHash['ntilde']= '\u00F1';
+ e2uHash['ograve']= '\u00F2';
+ e2uHash['oacute']= '\u00F3';
+ e2uHash['ocirc']= '\u00F4';
+ e2uHash['otilde']= '\u00F5';
+ e2uHash['ouml']= '\u00F6';
+ e2uHash['divide']= '\u00F7';
+ e2uHash['oslash']= '\u00F8';
+ e2uHash['ugrave']= '\u00F9';
+ e2uHash['uacute']= '\u00FA';
+ e2uHash['ucirc']= '\u00FB';
+ e2uHash['uuml']= '\u00FC';
+ e2uHash['yacute']= '\u00FD';
+ e2uHash['thorn']= '\u00FE';
+ e2uHash['yuml']= '\u00FF';
+ e2uHash['quot']= '\u0022';
+ e2uHash['amp']= '\u0026';
+ e2uHash['lt']= '\u003C';
+ e2uHash['gt']= '\u003E';
+ e2uHash['OElig']= '';
+ e2uHash['oelig']= '\u0153';
+ e2uHash['Scaron']= '\u0160';
+ e2uHash['scaron']= '\u0161';
+ e2uHash['Yuml']= '\u0178';
+ e2uHash['circ']= '\u02C6';
+ e2uHash['tilde']= '\u02DC';
+ e2uHash['ensp']= '\u2002';
+ e2uHash['emsp']= '\u2003';
+ e2uHash['thinsp']= '\u2009';
+ e2uHash['zwnj']= '\u200C';
+ e2uHash['zwj']= '\u200D';
+ e2uHash['lrm']= '\u200E';
+ e2uHash['rlm']= '\u200F';
+ e2uHash['ndash']= '\u2013';
+ e2uHash['mdash']= '\u2014';
+ e2uHash['lsquo']= '\u2018';
+ e2uHash['rsquo']= '\u2019';
+ e2uHash['sbquo']= '\u201A';
+ e2uHash['ldquo']= '\u201C';
+ e2uHash['rdquo']= '\u201D';
+ e2uHash['bdquo']= '\u201E';
+ e2uHash['dagger']= '\u2020';
+ e2uHash['Dagger']= '\u2021';
+ e2uHash['permil']= '\u2030';
+ e2uHash['lsaquo']= '\u2039';
+ e2uHash['rsaquo']= '\u203A';
+ e2uHash['euro']= '\u20AC';
+ e2uHash['fnof']= '\u0192';
+ e2uHash['Alpha']= '\u0391';
+ e2uHash['Beta']= '\u0392';
+ e2uHash['Gamma']= '\u0393';
+ e2uHash['Delta']= '\u0394';
+ e2uHash['Epsilon']= '\u0395';
+ e2uHash['Zeta']= '\u0396';
+ e2uHash['Eta']= '\u0397';
+ e2uHash['Theta']= '\u0398';
+ e2uHash['Iota']= '\u0399';
+ e2uHash['Kappa']= '\u039A';
+ e2uHash['Lambda']= '\u039B';
+ e2uHash['Mu']= '\u039C';
+ e2uHash['Nu']= '\u039D';
+ e2uHash['Xi']= '\u039E';
+ e2uHash['Omicron']= '\u039F';
+ e2uHash['Pi']= '\u03A0';
+ e2uHash['Rho']= '\u03A1';
+ e2uHash['Sigma']= '\u03A3';
+ e2uHash['Tau']= '\u03A4';
+ e2uHash['Upsilon']= '\u03A5';
+ e2uHash['Phi']= '\u03A6';
+ e2uHash['Chi']= '\u03A7';
+ e2uHash['Psi']= '\u03A8';
+ e2uHash['Omega']= '\u03A9';
+ e2uHash['alpha']= '\u03B1';
+ e2uHash['beta']= '\u03B2';
+ e2uHash['gamma']= '\u03B3';
+ e2uHash['delta']= '\u03B4';
+ e2uHash['epsilon']= '\u03B5';
+ e2uHash['zeta']= '\u03B6';
+ e2uHash['eta']= '\u03B7';
+ e2uHash['theta']= '\u03B8';
+ e2uHash['iota']= '\u03B9';
+ e2uHash['kappa']= '\u03BA';
+ e2uHash['lambda']= '\u03BB';
+ e2uHash['mu']= '\u03BC';
+ e2uHash['nu']= '\u03BD';
+ e2uHash['xi']= '\u03BE';
+ e2uHash['omicron']= '\u03BF';
+ e2uHash['pi']= '\u03C0';
+ e2uHash['rho']= '\u03C1';
+ e2uHash['sigmaf']= '\u03C2';
+ e2uHash['sigma']= '\u03C3';
+ e2uHash['tau']= '\u03C4';
+ e2uHash['upsilon']= '\u03C5';
+ e2uHash['phi']= '\u03C6';
+ e2uHash['chi']= '\u03C7';
+ e2uHash['psi']= '\u03C8';
+ e2uHash['omega']= '\u03C9';
+ e2uHash['thetasym']= '\u03D1';
+ e2uHash['upsih']= '\u03D2';
+ e2uHash['piv']= '\u03D6';
+ e2uHash['bull']= '\u2022';
+ e2uHash['hellip']= '\u2026';
+ e2uHash['prime']= '\u2032';
+ e2uHash['Prime']= '\u2033';
+ e2uHash['oline']= '\u203E';
+ e2uHash['frasl']= '\u2044';
+ e2uHash['weierp']= '\u2118';
+ e2uHash['image']= '\u2111';
+ e2uHash['real']= '\u211C';
+ e2uHash['trade']= '\u2122';
+ e2uHash['alefsym']= '\u2135';
+ e2uHash['larr']= '\u2190';
+ e2uHash['uarr']= '\u2191';
+ e2uHash['rarr']= '\u2192';
+ e2uHash['darr']= '\u2193';
+ e2uHash['harr']= '\u2194';
+ e2uHash['crarr']= '\u21B5';
+ e2uHash['lArr']= '\u21D0';
+ e2uHash['uArr']= '\u21D1';
+ e2uHash['rArr']= '\u21D2';
+ e2uHash['dArr']= '\u21D3';
+ e2uHash['hArr']= '\u21D4';
+ e2uHash['forall']= '\u2200';
+ e2uHash['part']= '\u2202';
+ e2uHash['exist']= '\u2203';
+ e2uHash['empty']= '\u2205';
+ e2uHash['nabla']= '\u2207';
+ e2uHash['isin']= '\u2208';
+ e2uHash['notin']= '\u2209';
+ e2uHash['ni']= '\u220B';
+ e2uHash['prod']= '\u220F';
+ e2uHash['sum']= '\u2211';
+ e2uHash['minus']= '\u2212';
+ e2uHash['lowast']= '\u2217';
+ e2uHash['radic']= '\u221A';
+ e2uHash['prop']= '\u221D';
+ e2uHash['infin']= '\u221E';
+ e2uHash['ang']= '\u2220';
+ e2uHash['and']= '\u2227';
+ e2uHash['or']= '\u2228';
+ e2uHash['cap']= '\u2229';
+ e2uHash['cup']= '\u222A';
+ e2uHash['int']= '\u222B';
+ e2uHash['there4']= '\u2234';
+ e2uHash['sim']= '\u223C';
+ e2uHash['cong']= '\u2245';
+ e2uHash['asymp']= '\u2248';
+ e2uHash['ne']= '\u2260';
+ e2uHash['equiv']= '\u2261';
+ e2uHash['le']= '\u2264';
+ e2uHash['ge']= '\u2265';
+ e2uHash['sub']= '\u2282';
+ e2uHash['sup']= '\u2283';
+ e2uHash['nsub']= '\u2284';
+ e2uHash['sube']= '\u2286';
+ e2uHash['supe']= '\u2287';
+ e2uHash['oplus']= '\u2295';
+ e2uHash['otimes']= '\u2297';
+ e2uHash['perp']= '\u22A5';
+ e2uHash['sdot']= '\u22C5';
+ e2uHash['lceil']= '\u2308';
+ e2uHash['rceil']= '\u2309';
+ e2uHash['lfloor']= '\u230A';
+ e2uHash['rfloor']= '\u230B';
+ e2uHash['lang']= '\u2329';
+ e2uHash['rang']= '\u232A';
+ e2uHash['loz']= '\u25CA';
+ e2uHash['spades']= '\u2660';
+ e2uHash['clubs']= '\u2663';
+ e2uHash['hearts']= '\u2665';
+ e2uHash['diams']= '\u2666';
+})();
+
+SimileAjax.HTML.deEntify = function(s) {
+ var e2uHash = SimileAjax.HTML._e2uHash;
+
+ var re = /&(\w+?);/;
+ while (re.test(s)) {
+ var m = s.match(re);
+ s = s.replace(re, e2uHash[m[1]]);
+ }
+ return s;
+}; \ No newline at end of file
diff --git a/site/app/webroot/js/simile/ajax/scripts/jquery-1.2.1.js b/site/app/webroot/js/simile/ajax/scripts/jquery-1.2.1.js
new file mode 100755
index 0000000..9fb3a8e
--- /dev/null
+++ b/site/app/webroot/js/simile/ajax/scripts/jquery-1.2.1.js
@@ -0,0 +1,2992 @@
+(function(){
+/*
+ * jQuery 1.2.1 - New Wave Javascript
+ *
+ * Copyright (c) 2007 John Resig (jquery.com)
+ * Dual licensed under the MIT (MIT-LICENSE.txt)
+ * and GPL (GPL-LICENSE.txt) licenses.
+ *
+ * $Date: 2007-09-16 23:42:06 -0400 (Sun, 16 Sep 2007) $
+ * $Rev: 3353 $
+ */
+
+// Map over jQuery in case of overwrite
+if ( typeof jQuery != "undefined" )
+ var _jQuery = jQuery;
+
+var jQuery = window.jQuery = function(selector, context) {
+ // If the context is a namespace object, return a new object
+ return this instanceof jQuery ?
+ this.init(selector, context) :
+ new jQuery(selector, context);
+};
+
+// Map over the $ in case of overwrite
+if ( typeof $ != "undefined" )
+ var _$ = $;
+
+// Map the jQuery namespace to the '$' one
+window.$ = jQuery;
+
+var quickExpr = /^[^<]*(<(.|\s)+>)[^>]*$|^#(\w+)$/;
+
+jQuery.fn = jQuery.prototype = {
+ init: function(selector, context) {
+ // Make sure that a selection was provided
+ selector = selector || document;
+
+ // Handle HTML strings
+ if ( typeof selector == "string" ) {
+ var m = quickExpr.exec(selector);
+ if ( m && (m[1] || !context) ) {
+ // HANDLE: $(html) -> $(array)
+ if ( m[1] )
+ selector = jQuery.clean( [ m[1] ], context );
+
+ // HANDLE: $("#id")
+ else {
+ var tmp = document.getElementById( m[3] );
+ if ( tmp )
+ // Handle the case where IE and Opera return items
+ // by name instead of ID
+ if ( tmp.id != m[3] )
+ return jQuery().find( selector );
+ else {
+ this[0] = tmp;
+ this.length = 1;
+ return this;
+ }
+ else
+ selector = [];
+ }
+
+ // HANDLE: $(expr)
+ } else
+ return new jQuery( context ).find( selector );
+
+ // HANDLE: $(function)
+ // Shortcut for document ready
+ } else if ( jQuery.isFunction(selector) )
+ return new jQuery(document)[ jQuery.fn.ready ? "ready" : "load" ]( selector );
+
+ return this.setArray(
+ // HANDLE: $(array)
+ selector.constructor == Array && selector ||
+
+ // HANDLE: $(arraylike)
+ // Watch for when an array-like object is passed as the selector
+ (selector.jquery || selector.length && selector != window && !selector.nodeType && selector[0] != undefined && selector[0].nodeType) && jQuery.makeArray( selector ) ||
+
+ // HANDLE: $(*)
+ [ selector ] );
+ },
+
+ jquery: "1.2.1",
+
+ size: function() {
+ return this.length;
+ },
+
+ length: 0,
+
+ get: function( num ) {
+ return num == undefined ?
+
+ // Return a 'clean' array
+ jQuery.makeArray( this ) :
+
+ // Return just the object
+ this[num];
+ },
+
+ pushStack: function( a ) {
+ var ret = jQuery(a);
+ ret.prevObject = this;
+ return ret;
+ },
+
+ setArray: function( a ) {
+ this.length = 0;
+ Array.prototype.push.apply( this, a );
+ return this;
+ },
+
+ each: function( fn, args ) {
+ return jQuery.each( this, fn, args );
+ },
+
+ index: function( obj ) {
+ var pos = -1;
+ this.each(function(i){
+ if ( this == obj ) pos = i;
+ });
+ return pos;
+ },
+
+ attr: function( key, value, type ) {
+ var obj = key;
+
+ // Look for the case where we're accessing a style value
+ if ( key.constructor == String )
+ if ( value == undefined )
+ return this.length && jQuery[ type || "attr" ]( this[0], key ) || undefined;
+ else {
+ obj = {};
+ obj[ key ] = value;
+ }
+
+ // Check to see if we're setting style values
+ return this.each(function(index){
+ // Set all the styles
+ for ( var prop in obj )
+ jQuery.attr(
+ type ? this.style : this,
+ prop, jQuery.prop(this, obj[prop], type, index, prop)
+ );
+ });
+ },
+
+ css: function( key, value ) {
+ return this.attr( key, value, "curCSS" );
+ },
+
+ text: function(e) {
+ if ( typeof e != "object" && e != null )
+ return this.empty().append( document.createTextNode( e ) );
+
+ var t = "";
+ jQuery.each( e || this, function(){
+ jQuery.each( this.childNodes, function(){
+ if ( this.nodeType != 8 )
+ t += this.nodeType != 1 ?
+ this.nodeValue : jQuery.fn.text([ this ]);
+ });
+ });
+ return t;
+ },
+
+ wrapAll: function(html) {
+ if ( this[0] )
+ // The elements to wrap the target around
+ jQuery(html, this[0].ownerDocument)
+ .clone()
+ .insertBefore(this[0])
+ .map(function(){
+ var elem = this;
+ while ( elem.firstChild )
+ elem = elem.firstChild;
+ return elem;
+ })
+ .append(this);
+
+ return this;
+ },
+
+ wrapInner: function(html) {
+ return this.each(function(){
+ jQuery(this).contents().wrapAll(html);
+ });
+ },
+
+ wrap: function(html) {
+ return this.each(function(){
+ jQuery(this).wrapAll(html);
+ });
+ },
+
+ append: function() {
+ return this.domManip(arguments, true, 1, function(a){
+ this.appendChild( a );
+ });
+ },
+
+ prepend: function() {
+ return this.domManip(arguments, true, -1, function(a){
+ this.insertBefore( a, this.firstChild );
+ });
+ },
+
+ before: function() {
+ return this.domManip(arguments, false, 1, function(a){
+ this.parentNode.insertBefore( a, this );
+ });
+ },
+
+ after: function() {
+ return this.domManip(arguments, false, -1, function(a){
+ this.parentNode.insertBefore( a, this.nextSibling );
+ });
+ },
+
+ end: function() {
+ return this.prevObject || jQuery([]);
+ },
+
+ find: function(t) {
+ var data = jQuery.map(this, function(a){ return jQuery.find(t,a); });
+ return this.pushStack( /[^+>] [^+>]/.test( t ) || t.indexOf("..") > -1 ?
+ jQuery.unique( data ) : data );
+ },
+
+ clone: function(events) {
+ // Do the clone
+ var ret = this.map(function(){
+ return this.outerHTML ? jQuery(this.outerHTML)[0] : this.cloneNode(true);
+ });
+
+ // Need to set the expando to null on the cloned set if it exists
+ // removeData doesn't work here, IE removes it from the original as well
+ // this is primarily for IE but the data expando shouldn't be copied over in any browser
+ var clone = ret.find("*").andSelf().each(function(){
+ if ( this[ expando ] != undefined )
+ this[ expando ] = null;
+ });
+
+ // Copy the events from the original to the clone
+ if (events === true)
+ this.find("*").andSelf().each(function(i) {
+ var events = jQuery.data(this, "events");
+ for ( var type in events )
+ for ( var handler in events[type] )
+ jQuery.event.add(clone[i], type, events[type][handler], events[type][handler].data);
+ });
+
+ // Return the cloned set
+ return ret;
+ },
+
+ filter: function(t) {
+ return this.pushStack(
+ jQuery.isFunction( t ) &&
+ jQuery.grep(this, function(el, index){
+ return t.apply(el, [index]);
+ }) ||
+
+ jQuery.multiFilter(t,this) );
+ },
+
+ not: function(t) {
+ return this.pushStack(
+ t.constructor == String &&
+ jQuery.multiFilter(t, this, true) ||
+
+ jQuery.grep(this, function(a) {
+ return ( t.constructor == Array || t.jquery )
+ ? jQuery.inArray( a, t ) < 0
+ : a != t;
+ })
+ );
+ },
+
+ add: function(t) {
+ return this.pushStack( jQuery.merge(
+ this.get(),
+ t.constructor == String ?
+ jQuery(t).get() :
+ t.length != undefined && (!t.nodeName || jQuery.nodeName(t, "form")) ?
+ t : [t] )
+ );
+ },
+
+ is: function(expr) {
+ return expr ? jQuery.multiFilter(expr,this).length > 0 : false;
+ },
+
+ hasClass: function(expr) {
+ return this.is("." + expr);
+ },
+
+ val: function( val ) {
+ if ( val == undefined ) {
+ if ( this.length ) {
+ var elem = this[0];
+
+ // We need to handle select boxes special
+ if ( jQuery.nodeName(elem, "select") ) {
+ var index = elem.selectedIndex,
+ a = [],
+ options = elem.options,
+ one = elem.type == "select-one";
+
+ // Nothing was selected
+ if ( index < 0 )
+ return null;
+
+ // Loop through all the selected options
+ for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) {
+ var option = options[i];
+ if ( option.selected ) {
+ // Get the specifc value for the option
+ var val = jQuery.browser.msie && !option.attributes["value"].specified ? option.text : option.value;
+
+ // We don't need an array for one selects
+ if ( one )
+ return val;
+
+ // Multi-Selects return an array
+ a.push(val);
+ }
+ }
+
+ return a;
+
+ // Everything else, we just grab the value
+ } else
+ return this[0].value.replace(/\r/g, "");
+ }
+ } else
+ return this.each(function(){
+ if ( val.constructor == Array && /radio|checkbox/.test(this.type) )
+ this.checked = (jQuery.inArray(this.value, val) >= 0 ||
+ jQuery.inArray(this.name, val) >= 0);
+ else if ( jQuery.nodeName(this, "select") ) {
+ var tmp = val.constructor == Array ? val : [val];
+
+ jQuery("option", this).each(function(){
+ this.selected = (jQuery.inArray(this.value, tmp) >= 0 ||
+ jQuery.inArray(this.text, tmp) >= 0);
+ });
+
+ if ( !tmp.length )
+ this.selectedIndex = -1;
+ } else
+ this.value = val;
+ });
+ },
+
+ html: function( val ) {
+ return val == undefined ?
+ ( this.length ? this[0].innerHTML : null ) :
+ this.empty().append( val );
+ },
+
+ replaceWith: function( val ) {
+ return this.after( val ).remove();
+ },
+
+ eq: function(i){
+ return this.slice(i, i+1);
+ },
+
+ slice: function() {
+ return this.pushStack( Array.prototype.slice.apply( this, arguments ) );
+ },
+
+ map: function(fn) {
+ return this.pushStack(jQuery.map( this, function(elem,i){
+ return fn.call( elem, i, elem );
+ }));
+ },
+
+ andSelf: function() {
+ return this.add( this.prevObject );
+ },
+
+ domManip: function(args, table, dir, fn) {
+ var clone = this.length > 1, a;
+
+ return this.each(function(){
+ if ( !a ) {
+ a = jQuery.clean(args, this.ownerDocument);
+ if ( dir < 0 )
+ a.reverse();
+ }
+
+ var obj = this;
+
+ if ( table && jQuery.nodeName(this, "table") && jQuery.nodeName(a[0], "tr") )
+ obj = this.getElementsByTagName("tbody")[0] || this.appendChild(document.createElement("tbody"));
+
+ jQuery.each( a, function(){
+ var elem = clone ? this.cloneNode(true) : this;
+ if ( !evalScript(0, elem) )
+ fn.call( obj, elem );
+ });
+ });
+ }
+};
+
+function evalScript(i, elem){
+ var script = jQuery.nodeName(elem, "script");
+
+ if ( script ) {
+ if ( elem.src )
+ jQuery.ajax({ url: elem.src, async: false, dataType: "script" });
+ else
+ jQuery.globalEval( elem.text || elem.textContent || elem.innerHTML || "" );
+
+ if ( elem.parentNode )
+ elem.parentNode.removeChild(elem);
+
+ } else if ( elem.nodeType == 1 )
+ jQuery("script", elem).each(evalScript);
+
+ return script;
+}
+
+jQuery.extend = jQuery.fn.extend = function() {
+ // copy reference to target object
+ var target = arguments[0] || {}, a = 1, al = arguments.length, deep = false;
+
+ // Handle a deep copy situation
+ if ( target.constructor == Boolean ) {
+ deep = target;
+ target = arguments[1] || {};
+ }
+
+ // extend jQuery itself if only one argument is passed
+ if ( al == 1 ) {
+ target = this;
+ a = 0;
+ }
+
+ var prop;
+
+ for ( ; a < al; a++ )
+ // Only deal with non-null/undefined values
+ if ( (prop = arguments[a]) != null )
+ // Extend the base object
+ for ( var i in prop ) {
+ // Prevent never-ending loop
+ if ( target == prop[i] )
+ continue;
+
+ // Recurse if we're merging object values
+ if ( deep && typeof prop[i] == 'object' && target[i] )
+ jQuery.extend( target[i], prop[i] );
+
+ // Don't bring in undefined values
+ else if ( prop[i] != undefined )
+ target[i] = prop[i];
+ }
+
+ // Return the modified object
+ return target;
+};
+
+var expando = "jQuery" + (new Date()).getTime(), uuid = 0, win = {};
+
+jQuery.extend({
+ noConflict: function(deep) {
+ window.$ = _$;
+ if ( deep )
+ window.jQuery = _jQuery;
+ return jQuery;
+ },
+
+ // This may seem like some crazy code, but trust me when I say that this
+ // is the only cross-browser way to do this. --John
+ isFunction: function( fn ) {
+ return !!fn && typeof fn != "string" && !fn.nodeName &&
+ fn.constructor != Array && /function/i.test( fn + "" );
+ },
+
+ // check if an element is in a XML document
+ isXMLDoc: function(elem) {
+ return elem.documentElement && !elem.body ||
+ elem.tagName && elem.ownerDocument && !elem.ownerDocument.body;
+ },
+
+ // Evalulates a script in a global context
+ // Evaluates Async. in Safari 2 :-(
+ globalEval: function( data ) {
+ data = jQuery.trim( data );
+ if ( data ) {
+ if ( window.execScript )
+ window.execScript( data );
+ else if ( jQuery.browser.safari )
+ // safari doesn't provide a synchronous global eval
+ window.setTimeout( data, 0 );
+ else
+ eval.call( window, data );
+ }
+ },
+
+ nodeName: function( elem, name ) {
+ return elem.nodeName && elem.nodeName.toUpperCase() == name.toUpperCase();
+ },
+
+ cache: {},
+
+ data: function( elem, name, data ) {
+ elem = elem == window ? win : elem;
+
+ var id = elem[ expando ];
+
+ // Compute a unique ID for the element
+ if ( !id )
+ id = elem[ expando ] = ++uuid;
+
+ // Only generate the data cache if we're
+ // trying to access or manipulate it
+ if ( name && !jQuery.cache[ id ] )
+ jQuery.cache[ id ] = {};
+
+ // Prevent overriding the named cache with undefined values
+ if ( data != undefined )
+ jQuery.cache[ id ][ name ] = data;
+
+ // Return the named cache data, or the ID for the element
+ return name ? jQuery.cache[ id ][ name ] : id;
+ },
+
+ removeData: function( elem, name ) {
+ elem = elem == window ? win : elem;
+
+ var id = elem[ expando ];
+
+ // If we want to remove a specific section of the element's data
+ if ( name ) {
+ if ( jQuery.cache[ id ] ) {
+ // Remove the section of cache data
+ delete jQuery.cache[ id ][ name ];
+
+ // If we've removed all the data, remove the element's cache
+ name = "";
+ for ( name in jQuery.cache[ id ] ) break;
+ if ( !name )
+ jQuery.removeData( elem );
+ }
+
+ // Otherwise, we want to remove all of the element's data
+ } else {
+ // Clean up the element expando
+ try {
+ delete elem[ expando ];
+ } catch(e){
+ // IE has trouble directly removing the expando
+ // but it's ok with using removeAttribute
+ if ( elem.removeAttribute )
+ elem.removeAttribute( expando );
+ }
+
+ // Completely remove the data cache
+ delete jQuery.cache[ id ];
+ }
+ },
+
+ // args is for internal usage only
+ each: function( obj, fn, args ) {
+ if ( args ) {
+ if ( obj.length == undefined )
+ for ( var i in obj )
+ fn.apply( obj[i], args );
+ else
+ for ( var i = 0, ol = obj.length; i < ol; i++ )
+ if ( fn.apply( obj[i], args ) === false ) break;
+
+ // A special, fast, case for the most common use of each
+ } else {
+ if ( obj.length == undefined )
+ for ( var i in obj )
+ fn.call( obj[i], i, obj[i] );
+ else
+ for ( var i = 0, ol = obj.length, val = obj[0];
+ i < ol && fn.call(val,i,val) !== false; val = obj[++i] ){}
+ }
+
+ return obj;
+ },
+
+ prop: function(elem, value, type, index, prop){
+ // Handle executable functions
+ if ( jQuery.isFunction( value ) )
+ value = value.call( elem, [index] );
+
+ // exclude the following css properties to add px
+ var exclude = /z-?index|font-?weight|opacity|zoom|line-?height/i;
+
+ // Handle passing in a number to a CSS property
+ return value && value.constructor == Number && type == "curCSS" && !exclude.test(prop) ?
+ value + "px" :
+ value;
+ },
+
+ className: {
+ // internal only, use addClass("class")
+ add: function( elem, c ){
+ jQuery.each( (c || "").split(/\s+/), function(i, cur){
+ if ( !jQuery.className.has( elem.className, cur ) )
+ elem.className += ( elem.className ? " " : "" ) + cur;
+ });
+ },
+
+ // internal only, use removeClass("class")
+ remove: function( elem, c ){
+ elem.className = c != undefined ?
+ jQuery.grep( elem.className.split(/\s+/), function(cur){
+ return !jQuery.className.has( c, cur );
+ }).join(" ") : "";
+ },
+
+ // internal only, use is(".class")
+ has: function( t, c ) {
+ return jQuery.inArray( c, (t.className || t).toString().split(/\s+/) ) > -1;
+ }
+ },
+
+ swap: function(e,o,f) {
+ for ( var i in o ) {
+ e.style["old"+i] = e.style[i];
+ e.style[i] = o[i];
+ }
+ f.apply( e, [] );
+ for ( var i in o )
+ e.style[i] = e.style["old"+i];
+ },
+
+ css: function(e,p) {
+ if ( p == "height" || p == "width" ) {
+ var old = {}, oHeight, oWidth, d = ["Top","Bottom","Right","Left"];
+
+ jQuery.each( d, function(){
+ old["padding" + this] = 0;
+ old["border" + this + "Width"] = 0;
+ });
+
+ jQuery.swap( e, old, function() {
+ if ( jQuery(e).is(':visible') ) {
+ oHeight = e.offsetHeight;
+ oWidth = e.offsetWidth;
+ } else {
+ e = jQuery(e.cloneNode(true))
+ .find(":radio").removeAttr("checked").end()
+ .css({
+ visibility: "hidden", position: "absolute", display: "block", right: "0", left: "0"
+ }).appendTo(e.parentNode)[0];
+
+ var parPos = jQuery.css(e.parentNode,"position") || "static";
+ if ( parPos == "static" )
+ e.parentNode.style.position = "relative";
+
+ oHeight = e.clientHeight;
+ oWidth = e.clientWidth;
+
+ if ( parPos == "static" )
+ e.parentNode.style.position = "static";
+
+ e.parentNode.removeChild(e);
+ }
+ });
+
+ return p == "height" ? oHeight : oWidth;
+ }
+
+ return jQuery.curCSS( e, p );
+ },
+
+ curCSS: function(elem, prop, force) {
+ var ret, stack = [], swap = [];
+
+ // A helper method for determining if an element's values are broken
+ function color(a){
+ if ( !jQuery.browser.safari )
+ return false;
+
+ var ret = document.defaultView.getComputedStyle(a,null);
+ return !ret || ret.getPropertyValue("color") == "";
+ }
+
+ if (prop == "opacity" && jQuery.browser.msie) {
+ ret = jQuery.attr(elem.style, "opacity");
+ return ret == "" ? "1" : ret;
+ }
+
+ if (prop.match(/float/i))
+ prop = styleFloat;
+
+ if (!force && elem.style[prop])
+ ret = elem.style[prop];
+
+ else if (document.defaultView && document.defaultView.getComputedStyle) {
+
+ if (prop.match(/float/i))
+ prop = "float";
+
+ prop = prop.replace(/([A-Z])/g,"-$1").toLowerCase();
+ var cur = document.defaultView.getComputedStyle(elem, null);
+
+ if ( cur && !color(elem) )
+ ret = cur.getPropertyValue(prop);
+
+ // If the element isn't reporting its values properly in Safari
+ // then some display: none elements are involved
+ else {
+ // Locate all of the parent display: none elements
+ for ( var a = elem; a && color(a); a = a.parentNode )
+ stack.unshift(a);
+
+ // Go through and make them visible, but in reverse
+ // (It would be better if we knew the exact display type that they had)
+ for ( a = 0; a < stack.length; a++ )
+ if ( color(stack[a]) ) {
+ swap[a] = stack[a].style.display;
+ stack[a].style.display = "block";
+ }
+
+ // Since we flip the display style, we have to handle that
+ // one special, otherwise get the value
+ ret = prop == "display" && swap[stack.length-1] != null ?
+ "none" :
+ document.defaultView.getComputedStyle(elem,null).getPropertyValue(prop) || "";
+
+ // Finally, revert the display styles back
+ for ( a = 0; a < swap.length; a++ )
+ if ( swap[a] != null )
+ stack[a].style.display = swap[a];
+ }
+
+ if ( prop == "opacity" && ret == "" )
+ ret = "1";
+
+ } else if (elem.currentStyle) {
+ var newProp = prop.replace(/\-(\w)/g,function(m,c){return c.toUpperCase();});
+ ret = elem.currentStyle[prop] || elem.currentStyle[newProp];
+
+ // From the awesome hack by Dean Edwards
+ // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
+
+ // If we're not dealing with a regular pixel number
+ // but a number that has a weird ending, we need to convert it to pixels
+ if ( !/^\d+(px)?$/i.test(ret) && /^\d/.test(ret) ) {
+ var style = elem.style.left;
+ var runtimeStyle = elem.runtimeStyle.left;
+ elem.runtimeStyle.left = elem.currentStyle.left;
+ elem.style.left = ret || 0;
+ ret = elem.style.pixelLeft + "px";
+ elem.style.left = style;
+ elem.runtimeStyle.left = runtimeStyle;
+ }
+ }
+
+ return ret;
+ },
+
+ clean: function(a, doc) {
+ var r = [];
+ doc = doc || document;
+
+ jQuery.each( a, function(i,arg){
+ if ( !arg ) return;
+
+ if ( arg.constructor == Number )
+ arg = arg.toString();
+
+ // Convert html string into DOM nodes
+ if ( typeof arg == "string" ) {
+ // Fix "XHTML"-style tags in all browsers
+ arg = arg.replace(/(<(\w+)[^>]*?)\/>/g, function(m, all, tag){
+ return tag.match(/^(abbr|br|col|img|input|link|meta|param|hr|area)$/i)? m : all+"></"+tag+">";
+ });
+
+ // Trim whitespace, otherwise indexOf won't work as expected
+ var s = jQuery.trim(arg).toLowerCase(), div = doc.createElement("div"), tb = [];
+
+ var wrap =
+ // option or optgroup
+ !s.indexOf("<opt") &&
+ [1, "<select>", "</select>"] ||
+
+ !s.indexOf("<leg") &&
+ [1, "<fieldset>", "</fieldset>"] ||
+
+ s.match(/^<(thead|tbody|tfoot|colg|cap)/) &&
+ [1, "<table>", "</table>"] ||
+
+ !s.indexOf("<tr") &&
+ [2, "<table><tbody>", "</tbody></table>"] ||
+
+ // <thead> matched above
+ (!s.indexOf("<td") || !s.indexOf("<th")) &&
+ [3, "<table><tbody><tr>", "</tr></tbody></table>"] ||
+
+ !s.indexOf("<col") &&
+ [2, "<table><tbody></tbody><colgroup>", "</colgroup></table>"] ||
+
+ // IE can't serialize <link> and <script> tags normally
+ jQuery.browser.msie &&
+ [1, "div<div>", "</div>"] ||
+
+ [0,"",""];
+
+ // Go to html and back, then peel off extra wrappers
+ div.innerHTML = wrap[1] + arg + wrap[2];
+
+ // Move to the right depth
+ while ( wrap[0]-- )
+ div = div.lastChild;
+
+ // Remove IE's autoinserted <tbody> from table fragments
+ if ( jQuery.browser.msie ) {
+
+ // String was a <table>, *may* have spurious <tbody>
+ if ( !s.indexOf("<table") && s.indexOf("<tbody") < 0 )
+ tb = div.firstChild && div.firstChild.childNodes;
+
+ // String was a bare <thead> or <tfoot>
+ else if ( wrap[1] == "<table>" && s.indexOf("<tbody") < 0 )
+ tb = div.childNodes;
+
+ for ( var n = tb.length-1; n >= 0 ; --n )
+ if ( jQuery.nodeName(tb[n], "tbody") && !tb[n].childNodes.length )
+ tb[n].parentNode.removeChild(tb[n]);
+
+ // IE completely kills leading whitespace when innerHTML is used
+ if ( /^\s/.test(arg) )
+ div.insertBefore( doc.createTextNode( arg.match(/^\s*/)[0] ), div.firstChild );
+
+ }
+
+ arg = jQuery.makeArray( div.childNodes );
+ }
+
+ if ( 0 === arg.length && (!jQuery.nodeName(arg, "form") && !jQuery.nodeName(arg, "select")) )
+ return;
+
+ if ( arg[0] == undefined || jQuery.nodeName(arg, "form") || arg.options )
+ r.push( arg );
+ else
+ r = jQuery.merge( r, arg );
+
+ });
+
+ return r;
+ },
+
+ attr: function(elem, name, value){
+ var fix = jQuery.isXMLDoc(elem) ? {} : jQuery.props;
+
+ // Safari mis-reports the default selected property of a hidden option
+ // Accessing the parent's selectedIndex property fixes it
+ if ( name == "selected" && jQuery.browser.safari )
+ elem.parentNode.selectedIndex;
+
+ // Certain attributes only work when accessed via the old DOM 0 way
+ if ( fix[name] ) {
+ if ( value != undefined ) elem[fix[name]] = value;
+ return elem[fix[name]];
+ } else if ( jQuery.browser.msie && name == "style" )
+ return jQuery.attr( elem.style, "cssText", value );
+
+ else if ( value == undefined && jQuery.browser.msie && jQuery.nodeName(elem, "form") && (name == "action" || name == "method") )
+ return elem.getAttributeNode(name).nodeValue;
+
+ // IE elem.getAttribute passes even for style
+ else if ( elem.tagName ) {
+
+ if ( value != undefined ) {
+ if ( name == "type" && jQuery.nodeName(elem,"input") && elem.parentNode )
+ throw "type property can't be changed";
+ elem.setAttribute( name, value );
+ }
+
+ if ( jQuery.browser.msie && /href|src/.test(name) && !jQuery.isXMLDoc(elem) )
+ return elem.getAttribute( name, 2 );
+
+ return elem.getAttribute( name );
+
+ // elem is actually elem.style ... set the style
+ } else {
+ // IE actually uses filters for opacity
+ if ( name == "opacity" && jQuery.browser.msie ) {
+ if ( value != undefined ) {
+ // IE has trouble with opacity if it does not have layout
+ // Force it by setting the zoom level
+ elem.zoom = 1;
+
+ // Set the alpha filter to set the opacity
+ elem.filter = (elem.filter || "").replace(/alpha\([^)]*\)/,"") +
+ (parseFloat(value).toString() == "NaN" ? "" : "alpha(opacity=" + value * 100 + ")");
+ }
+
+ return elem.filter ?
+ (parseFloat( elem.filter.match(/opacity=([^)]*)/)[1] ) / 100).toString() : "";
+ }
+ name = name.replace(/-([a-z])/ig,function(z,b){return b.toUpperCase();});
+ if ( value != undefined ) elem[name] = value;
+ return elem[name];
+ }
+ },
+
+ trim: function(t){
+ return (t||"").replace(/^\s+|\s+$/g, "");
+ },
+
+ makeArray: function( a ) {
+ var r = [];
+
+ // Need to use typeof to fight Safari childNodes crashes
+ if ( typeof a != "array" )
+ for ( var i = 0, al = a.length; i < al; i++ )
+ r.push( a[i] );
+ else
+ r = a.slice( 0 );
+
+ return r;
+ },
+
+ inArray: function( b, a ) {
+ for ( var i = 0, al = a.length; i < al; i++ )
+ if ( a[i] == b )
+ return i;
+ return -1;
+ },
+
+ merge: function(first, second) {
+ // We have to loop this way because IE & Opera overwrite the length
+ // expando of getElementsByTagName
+
+ // Also, we need to make sure that the correct elements are being returned
+ // (IE returns comment nodes in a '*' query)
+ if ( jQuery.browser.msie ) {
+ for ( var i = 0; second[i]; i++ )
+ if ( second[i].nodeType != 8 )
+ first.push(second[i]);
+ } else
+ for ( var i = 0; second[i]; i++ )
+ first.push(second[i]);
+
+ return first;
+ },
+
+ unique: function(first) {
+ var r = [], done = {};
+
+ try {
+ for ( var i = 0, fl = first.length; i < fl; i++ ) {
+ var id = jQuery.data(first[i]);
+ if ( !done[id] ) {
+ done[id] = true;
+ r.push(first[i]);
+ }
+ }
+ } catch(e) {
+ r = first;
+ }
+
+ return r;
+ },
+
+ grep: function(elems, fn, inv) {
+ // If a string is passed in for the function, make a function
+ // for it (a handy shortcut)
+ if ( typeof fn == "string" )
+ fn = eval("false||function(a,i){return " + fn + "}");
+
+ var result = [];
+
+ // Go through the array, only saving the items
+ // that pass the validator function
+ for ( var i = 0, el = elems.length; i < el; i++ )
+ if ( !inv && fn(elems[i],i) || inv && !fn(elems[i],i) )
+ result.push( elems[i] );
+
+ return result;
+ },
+
+ map: function(elems, fn) {
+ // If a string is passed in for the function, make a function
+ // for it (a handy shortcut)
+ if ( typeof fn == "string" )
+ fn = eval("false||function(a){return " + fn + "}");
+
+ var result = [];
+
+ // Go through the array, translating each of the items to their
+ // new value (or values).
+ for ( var i = 0, el = elems.length; i < el; i++ ) {
+ var val = fn(elems[i],i);
+
+ if ( val !== null && val != undefined ) {
+ if ( val.constructor != Array ) val = [val];
+ result = result.concat( val );
+ }
+ }
+
+ return result;
+ }
+});
+
+var userAgent = navigator.userAgent.toLowerCase();
+
+// Figure out what browser is being used
+jQuery.browser = {
+ version: (userAgent.match(/.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/) || [])[1],
+ safari: /webkit/.test(userAgent),
+ opera: /opera/.test(userAgent),
+ msie: /msie/.test(userAgent) && !/opera/.test(userAgent),
+ mozilla: /mozilla/.test(userAgent) && !/(compatible|webkit)/.test(userAgent)
+};
+
+var styleFloat = jQuery.browser.msie ? "styleFloat" : "cssFloat";
+
+jQuery.extend({
+ // Check to see if the W3C box model is being used
+ boxModel: !jQuery.browser.msie || document.compatMode == "CSS1Compat",
+
+ styleFloat: jQuery.browser.msie ? "styleFloat" : "cssFloat",
+
+ props: {
+ "for": "htmlFor",
+ "class": "className",
+ "float": styleFloat,
+ cssFloat: styleFloat,
+ styleFloat: styleFloat,
+ innerHTML: "innerHTML",
+ className: "className",
+ value: "value",
+ disabled: "disabled",
+ checked: "checked",
+ readonly: "readOnly",
+ selected: "selected",
+ maxlength: "maxLength"
+ }
+});
+
+jQuery.each({
+ parent: "a.parentNode",
+ parents: "jQuery.dir(a,'parentNode')",
+ next: "jQuery.nth(a,2,'nextSibling')",
+ prev: "jQuery.nth(a,2,'previousSibling')",
+ nextAll: "jQuery.dir(a,'nextSibling')",
+ prevAll: "jQuery.dir(a,'previousSibling')",
+ siblings: "jQuery.sibling(a.parentNode.firstChild,a)",
+ children: "jQuery.sibling(a.firstChild)",
+ contents: "jQuery.nodeName(a,'iframe')?a.contentDocument||a.contentWindow.document:jQuery.makeArray(a.childNodes)"
+}, function(i,n){
+ jQuery.fn[ i ] = function(a) {
+ var ret = jQuery.map(this,n);
+ if ( a && typeof a == "string" )
+ ret = jQuery.multiFilter(a,ret);
+ return this.pushStack( jQuery.unique(ret) );
+ };
+});
+
+jQuery.each({
+ appendTo: "append",
+ prependTo: "prepend",
+ insertBefore: "before",
+ insertAfter: "after",
+ replaceAll: "replaceWith"
+}, function(i,n){
+ jQuery.fn[ i ] = function(){
+ var a = arguments;
+ return this.each(function(){
+ for ( var j = 0, al = a.length; j < al; j++ )
+ jQuery(a[j])[n]( this );
+ });
+ };
+});
+
+jQuery.each( {
+ removeAttr: function( key ) {
+ jQuery.attr( this, key, "" );
+ this.removeAttribute( key );
+ },
+ addClass: function(c){
+ jQuery.className.add(this,c);
+ },
+ removeClass: function(c){
+ jQuery.className.remove(this,c);
+ },
+ toggleClass: function( c ){
+ jQuery.className[ jQuery.className.has(this,c) ? "remove" : "add" ](this, c);
+ },
+ remove: function(a){
+ if ( !a || jQuery.filter( a, [this] ).r.length ) {
+ jQuery.removeData( this );
+ this.parentNode.removeChild( this );
+ }
+ },
+ empty: function() {
+ // Clean up the cache
+ jQuery("*", this).each(function(){ jQuery.removeData(this); });
+
+ while ( this.firstChild )
+ this.removeChild( this.firstChild );
+ }
+}, function(i,n){
+ jQuery.fn[ i ] = function() {
+ return this.each( n, arguments );
+ };
+});
+
+jQuery.each( [ "Height", "Width" ], function(i,name){
+ var n = name.toLowerCase();
+
+ jQuery.fn[ n ] = function(h) {
+ return this[0] == window ?
+ jQuery.browser.safari && self["inner" + name] ||
+ jQuery.boxModel && Math.max(document.documentElement["client" + name], document.body["client" + name]) ||
+ document.body["client" + name] :
+
+ this[0] == document ?
+ Math.max( document.body["scroll" + name], document.body["offset" + name] ) :
+
+ h == undefined ?
+ ( this.length ? jQuery.css( this[0], n ) : null ) :
+ this.css( n, h.constructor == String ? h : h + "px" );
+ };
+});
+
+var chars = jQuery.browser.safari && parseInt(jQuery.browser.version) < 417 ?
+ "(?:[\\w*_-]|\\\\.)" :
+ "(?:[\\w\u0128-\uFFFF*_-]|\\\\.)",
+ quickChild = new RegExp("^>\\s*(" + chars + "+)"),
+ quickID = new RegExp("^(" + chars + "+)(#)(" + chars + "+)"),
+ quickClass = new RegExp("^([#.]?)(" + chars + "*)");
+
+jQuery.extend({
+ expr: {
+ "": "m[2]=='*'||jQuery.nodeName(a,m[2])",
+ "#": "a.getAttribute('id')==m[2]",
+ ":": {
+ // Position Checks
+ lt: "i<m[3]-0",
+ gt: "i>m[3]-0",
+ nth: "m[3]-0==i",
+ eq: "m[3]-0==i",
+ first: "i==0",
+ last: "i==r.length-1",
+ even: "i%2==0",
+ odd: "i%2",
+
+ // Child Checks
+ "first-child": "a.parentNode.getElementsByTagName('*')[0]==a",
+ "last-child": "jQuery.nth(a.parentNode.lastChild,1,'previousSibling')==a",
+ "only-child": "!jQuery.nth(a.parentNode.lastChild,2,'previousSibling')",
+
+ // Parent Checks
+ parent: "a.firstChild",
+ empty: "!a.firstChild",
+
+ // Text Check
+ contains: "(a.textContent||a.innerText||jQuery(a).text()||'').indexOf(m[3])>=0",
+
+ // Visibility
+ visible: '"hidden"!=a.type&&jQuery.css(a,"display")!="none"&&jQuery.css(a,"visibility")!="hidden"',
+ hidden: '"hidden"==a.type||jQuery.css(a,"display")=="none"||jQuery.css(a,"visibility")=="hidden"',
+
+ // Form attributes
+ enabled: "!a.disabled",
+ disabled: "a.disabled",
+ checked: "a.checked",
+ selected: "a.selected||jQuery.attr(a,'selected')",
+
+ // Form elements
+ text: "'text'==a.type",
+ radio: "'radio'==a.type",
+ checkbox: "'checkbox'==a.type",
+ file: "'file'==a.type",
+ password: "'password'==a.type",
+ submit: "'submit'==a.type",
+ image: "'image'==a.type",
+ reset: "'reset'==a.type",
+ button: '"button"==a.type||jQuery.nodeName(a,"button")',
+ input: "/input|select|textarea|button/i.test(a.nodeName)",
+
+ // :has()
+ has: "jQuery.find(m[3],a).length",
+
+ // :header
+ header: "/h\\d/i.test(a.nodeName)",
+
+ // :animated
+ animated: "jQuery.grep(jQuery.timers,function(fn){return a==fn.elem;}).length"
+ }
+ },
+
+ // The regular expressions that power the parsing engine
+ parse: [
+ // Match: [@value='test'], [@foo]
+ /^(\[) *@?([\w-]+) *([!*$^~=]*) *('?"?)(.*?)\4 *\]/,
+
+ // Match: :contains('foo')
+ /^(:)([\w-]+)\("?'?(.*?(\(.*?\))?[^(]*?)"?'?\)/,
+
+ // Match: :even, :last-chlid, #id, .class
+ new RegExp("^([:.#]*)(" + chars + "+)")
+ ],
+
+ multiFilter: function( expr, elems, not ) {
+ var old, cur = [];
+
+ while ( expr && expr != old ) {
+ old = expr;
+ var f = jQuery.filter( expr, elems, not );
+ expr = f.t.replace(/^\s*,\s*/, "" );
+ cur = not ? elems = f.r : jQuery.merge( cur, f.r );
+ }
+
+ return cur;
+ },
+
+ find: function( t, context ) {
+ // Quickly handle non-string expressions
+ if ( typeof t != "string" )
+ return [ t ];
+
+ // Make sure that the context is a DOM Element
+ if ( context && !context.nodeType )
+ context = null;
+
+ // Set the correct context (if none is provided)
+ context = context || document;
+
+ // Initialize the search
+ var ret = [context], done = [], last;
+
+ // Continue while a selector expression exists, and while
+ // we're no longer looping upon ourselves
+ while ( t && last != t ) {
+ var r = [];
+ last = t;
+
+ t = jQuery.trim(t);
+
+ var foundToken = false;
+
+ // An attempt at speeding up child selectors that
+ // point to a specific element tag
+ var re = quickChild;
+ var m = re.exec(t);
+
+ if ( m ) {
+ var nodeName = m[1].toUpperCase();
+
+ // Perform our own iteration and filter
+ for ( var i = 0; ret[i]; i++ )
+ for ( var c = ret[i].firstChild; c; c = c.nextSibling )
+ if ( c.nodeType == 1 && (nodeName == "*" || c.nodeName.toUpperCase() == nodeName.toUpperCase()) )
+ r.push( c );
+
+ ret = r;
+ t = t.replace( re, "" );
+ if ( t.indexOf(" ") == 0 ) continue;
+ foundToken = true;
+ } else {
+ re = /^([>+~])\s*(\w*)/i;
+
+ if ( (m = re.exec(t)) != null ) {
+ r = [];
+
+ var nodeName = m[2], merge = {};
+ m = m[1];
+
+ for ( var j = 0, rl = ret.length; j < rl; j++ ) {
+ var n = m == "~" || m == "+" ? ret[j].nextSibling : ret[j].firstChild;
+ for ( ; n; n = n.nextSibling )
+ if ( n.nodeType == 1 ) {
+ var id = jQuery.data(n);
+
+ if ( m == "~" && merge[id] ) break;
+
+ if (!nodeName || n.nodeName.toUpperCase() == nodeName.toUpperCase() ) {
+ if ( m == "~" ) merge[id] = true;
+ r.push( n );
+ }
+
+ if ( m == "+" ) break;
+ }
+ }
+
+ ret = r;
+
+ // And remove the token
+ t = jQuery.trim( t.replace( re, "" ) );
+ foundToken = true;
+ }
+ }
+
+ // See if there's still an expression, and that we haven't already
+ // matched a token
+ if ( t && !foundToken ) {
+ // Handle multiple expressions
+ if ( !t.indexOf(",") ) {
+ // Clean the result set
+ if ( context == ret[0] ) ret.shift();
+
+ // Merge the result sets
+ done = jQuery.merge( done, ret );
+
+ // Reset the context
+ r = ret = [context];
+
+ // Touch up the selector string
+ t = " " + t.substr(1,t.length);
+
+ } else {
+ // Optimize for the case nodeName#idName
+ var re2 = quickID;
+ var m = re2.exec(t);
+
+ // Re-organize the results, so that they're consistent
+ if ( m ) {
+ m = [ 0, m[2], m[3], m[1] ];
+
+ } else {
+ // Otherwise, do a traditional filter check for
+ // ID, class, and element selectors
+ re2 = quickClass;
+ m = re2.exec(t);
+ }
+
+ m[2] = m[2].replace(/\\/g, "");
+
+ var elem = ret[ret.length-1];
+
+ // Try to do a global search by ID, where we can
+ if ( m[1] == "#" && elem && elem.getElementById && !jQuery.isXMLDoc(elem) ) {
+ // Optimization for HTML document case
+ var oid = elem.getElementById(m[2]);
+
+ // Do a quick check for the existence of the actual ID attribute
+ // to avoid selecting by the name attribute in IE
+ // also check to insure id is a string to avoid selecting an element with the name of 'id' inside a form
+ if ( (jQuery.browser.msie||jQuery.browser.opera) && oid && typeof oid.id == "string" && oid.id != m[2] )
+ oid = jQuery('[@id="'+m[2]+'"]', elem)[0];
+
+ // Do a quick check for node name (where applicable) so
+ // that div#foo searches will be really fast
+ ret = r = oid && (!m[3] || jQuery.nodeName(oid, m[3])) ? [oid] : [];
+ } else {
+ // We need to find all descendant elements
+ for ( var i = 0; ret[i]; i++ ) {
+ // Grab the tag name being searched for
+ var tag = m[1] == "#" && m[3] ? m[3] : m[1] != "" || m[0] == "" ? "*" : m[2];
+
+ // Handle IE7 being really dumb about <object>s
+ if ( tag == "*" && ret[i].nodeName.toLowerCase() == "object" )
+ tag = "param";
+
+ r = jQuery.merge( r, ret[i].getElementsByTagName( tag ));
+ }
+
+ // It's faster to filter by class and be done with it
+ if ( m[1] == "." )
+ r = jQuery.classFilter( r, m[2] );
+
+ // Same with ID filtering
+ if ( m[1] == "#" ) {
+ var tmp = [];
+
+ // Try to find the element with the ID
+ for ( var i = 0; r[i]; i++ )
+ if ( r[i].getAttribute("id") == m[2] ) {
+ tmp = [ r[i] ];
+ break;
+ }
+
+ r = tmp;
+ }
+
+ ret = r;
+ }
+
+ t = t.replace( re2, "" );
+ }
+
+ }
+
+ // If a selector string still exists
+ if ( t ) {
+ // Attempt to filter it
+ var val = jQuery.filter(t,r);
+ ret = r = val.r;
+ t = jQuery.trim(val.t);
+ }
+ }
+
+ // An error occurred with the selector;
+ // just return an empty set instead
+ if ( t )
+ ret = [];
+
+ // Remove the root context
+ if ( ret && context == ret[0] )
+ ret.shift();
+
+ // And combine the results
+ done = jQuery.merge( done, ret );
+
+ return done;
+ },
+
+ classFilter: function(r,m,not){
+ m = " " + m + " ";
+ var tmp = [];
+ for ( var i = 0; r[i]; i++ ) {
+ var pass = (" " + r[i].className + " ").indexOf( m ) >= 0;
+ if ( !not && pass || not && !pass )
+ tmp.push( r[i] );
+ }
+ return tmp;
+ },
+
+ filter: function(t,r,not) {
+ var last;
+
+ // Look for common filter expressions
+ while ( t && t != last ) {
+ last = t;
+
+ var p = jQuery.parse, m;
+
+ for ( var i = 0; p[i]; i++ ) {
+ m = p[i].exec( t );
+
+ if ( m ) {
+ // Remove what we just matched
+ t = t.substring( m[0].length );
+
+ m[2] = m[2].replace(/\\/g, "");
+ break;
+ }
+ }
+
+ if ( !m )
+ break;
+
+ // :not() is a special case that can be optimized by
+ // keeping it out of the expression list
+ if ( m[1] == ":" && m[2] == "not" )
+ r = jQuery.filter(m[3], r, true).r;
+
+ // We can get a big speed boost by filtering by class here
+ else if ( m[1] == "." )
+ r = jQuery.classFilter(r, m[2], not);
+
+ else if ( m[1] == "[" ) {
+ var tmp = [], type = m[3];
+
+ for ( var i = 0, rl = r.length; i < rl; i++ ) {
+ var a = r[i], z = a[ jQuery.props[m[2]] || m[2] ];
+
+ if ( z == null || /href|src|selected/.test(m[2]) )
+ z = jQuery.attr(a,m[2]) || '';
+
+ if ( (type == "" && !!z ||
+ type == "=" && z == m[5] ||
+ type == "!=" && z != m[5] ||
+ type == "^=" && z && !z.indexOf(m[5]) ||
+ type == "$=" && z.substr(z.length - m[5].length) == m[5] ||
+ (type == "*=" || type == "~=") && z.indexOf(m[5]) >= 0) ^ not )
+ tmp.push( a );
+ }
+
+ r = tmp;
+
+ // We can get a speed boost by handling nth-child here
+ } else if ( m[1] == ":" && m[2] == "nth-child" ) {
+ var merge = {}, tmp = [],
+ test = /(\d*)n\+?(\d*)/.exec(
+ m[3] == "even" && "2n" || m[3] == "odd" && "2n+1" ||
+ !/\D/.test(m[3]) && "n+" + m[3] || m[3]),
+ first = (test[1] || 1) - 0, last = test[2] - 0;
+
+ for ( var i = 0, rl = r.length; i < rl; i++ ) {
+ var node = r[i], parentNode = node.parentNode, id = jQuery.data(parentNode);
+
+ if ( !merge[id] ) {
+ var c = 1;
+
+ for ( var n = parentNode.firstChild; n; n = n.nextSibling )
+ if ( n.nodeType == 1 )
+ n.nodeIndex = c++;
+
+ merge[id] = true;
+ }
+
+ var add = false;
+
+ if ( first == 1 ) {
+ if ( last == 0 || node.nodeIndex == last )
+ add = true;
+ } else if ( (node.nodeIndex + last) % first == 0 )
+ add = true;
+
+ if ( add ^ not )
+ tmp.push( node );
+ }
+
+ r = tmp;
+
+ // Otherwise, find the expression to execute
+ } else {
+ var f = jQuery.expr[m[1]];
+ if ( typeof f != "string" )
+ f = jQuery.expr[m[1]][m[2]];
+
+ // Build a custom macro to enclose it
+ f = eval("false||function(a,i){return " + f + "}");
+
+ // Execute it against the current filter
+ r = jQuery.grep( r, f, not );
+ }
+ }
+
+ // Return an array of filtered elements (r)
+ // and the modified expression string (t)
+ return { r: r, t: t };
+ },
+
+ dir: function( elem, dir ){
+ var matched = [];
+ var cur = elem[dir];
+ while ( cur && cur != document ) {
+ if ( cur.nodeType == 1 )
+ matched.push( cur );
+ cur = cur[dir];
+ }
+ return matched;
+ },
+
+ nth: function(cur,result,dir,elem){
+ result = result || 1;
+ var num = 0;
+
+ for ( ; cur; cur = cur[dir] )
+ if ( cur.nodeType == 1 && ++num == result )
+ break;
+
+ return cur;
+ },
+
+ sibling: function( n, elem ) {
+ var r = [];
+
+ for ( ; n; n = n.nextSibling ) {
+ if ( n.nodeType == 1 && (!elem || n != elem) )
+ r.push( n );
+ }
+
+ return r;
+ }
+});
+/*
+ * A number of helper functions used for managing events.
+ * Many of the ideas behind this code orignated from
+ * Dean Edwards' addEvent library.
+ */
+jQuery.event = {
+
+ // Bind an event to an element
+ // Original by Dean Edwards
+ add: function(element, type, handler, data) {
+ // For whatever reason, IE has trouble passing the window object
+ // around, causing it to be cloned in the process
+ if ( jQuery.browser.msie && element.setInterval != undefined )
+ element = window;
+
+ // Make sure that the function being executed has a unique ID
+ if ( !handler.guid )
+ handler.guid = this.guid++;
+
+ // if data is passed, bind to handler
+ if( data != undefined ) {
+ // Create temporary function pointer to original handler
+ var fn = handler;
+
+ // Create unique handler function, wrapped around original handler
+ handler = function() {
+ // Pass arguments and context to original handler
+ return fn.apply(this, arguments);
+ };
+
+ // Store data in unique handler
+ handler.data = data;
+
+ // Set the guid of unique handler to the same of original handler, so it can be removed
+ handler.guid = fn.guid;
+ }
+
+ // Namespaced event handlers
+ var parts = type.split(".");
+ type = parts[0];
+ handler.type = parts[1];
+
+ // Init the element's event structure
+ var events = jQuery.data(element, "events") || jQuery.data(element, "events", {});
+
+ var handle = jQuery.data(element, "handle", function(){
+ // returned undefined or false
+ var val;
+
+ // Handle the second event of a trigger and when
+ // an event is called after a page has unloaded
+ if ( typeof jQuery == "undefined" || jQuery.event.triggered )
+ return val;
+
+ val = jQuery.event.handle.apply(element, arguments);
+
+ return val;
+ });
+
+ // Get the current list of functions bound to this event
+ var handlers = events[type];
+
+ // Init the event handler queue
+ if (!handlers) {
+ handlers = events[type] = {};
+
+ // And bind the global event handler to the element
+ if (element.addEventListener)
+ element.addEventListener(type, handle, false);
+ else
+ element.attachEvent("on" + type, handle);
+ }
+
+ // Add the function to the element's handler list
+ handlers[handler.guid] = handler;
+
+ // Keep track of which events have been used, for global triggering
+ this.global[type] = true;
+ },
+
+ guid: 1,
+ global: {},
+
+ // Detach an event or set of events from an element
+ remove: function(element, type, handler) {
+ var events = jQuery.data(element, "events"), ret, index;
+
+ // Namespaced event handlers
+ if ( typeof type == "string" ) {
+ var parts = type.split(".");
+ type = parts[0];
+ }
+
+ if ( events ) {
+ // type is actually an event object here
+ if ( type && type.type ) {
+ handler = type.handler;
+ type = type.type;
+ }
+
+ if ( !type ) {
+ for ( type in events )
+ this.remove( element, type );
+
+ } else if ( events[type] ) {
+ // remove the given handler for the given type
+ if ( handler )
+ delete events[type][handler.guid];
+
+ // remove all handlers for the given type
+ else
+ for ( handler in events[type] )
+ // Handle the removal of namespaced events
+ if ( !parts[1] || events[type][handler].type == parts[1] )
+ delete events[type][handler];
+
+ // remove generic event handler if no more handlers exist
+ for ( ret in events[type] ) break;
+ if ( !ret ) {
+ if (element.removeEventListener)
+ element.removeEventListener(type, jQuery.data(element, "handle"), false);
+ else
+ element.detachEvent("on" + type, jQuery.data(element, "handle"));
+ ret = null;
+ delete events[type];
+ }
+ }
+
+ // Remove the expando if it's no longer used
+ for ( ret in events ) break;
+ if ( !ret ) {
+ jQuery.removeData( element, "events" );
+ jQuery.removeData( element, "handle" );
+ }
+ }
+ },
+
+ trigger: function(type, data, element, donative, extra) {
+ // Clone the incoming data, if any
+ data = jQuery.makeArray(data || []);
+
+ // Handle a global trigger
+ if ( !element ) {
+ // Only trigger if we've ever bound an event for it
+ if ( this.global[type] )
+ jQuery("*").add([window, document]).trigger(type, data);
+
+ // Handle triggering a single element
+ } else {
+ var val, ret, fn = jQuery.isFunction( element[ type ] || null ),
+ // Check to see if we need to provide a fake event, or not
+ evt = !data[0] || !data[0].preventDefault;
+
+ // Pass along a fake event
+ if ( evt )
+ data.unshift( this.fix({ type: type, target: element }) );
+
+ // Enforce the right trigger type
+ data[0].type = type;
+
+ // Trigger the event
+ if ( jQuery.isFunction( jQuery.data(element, "handle") ) )
+ val = jQuery.data(element, "handle").apply( element, data );
+
+ // Handle triggering native .onfoo handlers
+ if ( !fn && element["on"+type] && element["on"+type].apply( element, data ) === false )
+ val = false;
+
+ // Extra functions don't get the custom event object
+ if ( evt )
+ data.shift();
+
+ // Handle triggering of extra function
+ if ( extra && extra.apply( element, data ) === false )
+ val = false;
+
+ // Trigger the native events (except for clicks on links)
+ if ( fn && donative !== false && val !== false && !(jQuery.nodeName(element, 'a') && type == "click") ) {
+ this.triggered = true;
+ element[ type ]();
+ }
+
+ this.triggered = false;
+ }
+
+ return val;
+ },
+
+ handle: function(event) {
+ // returned undefined or false
+ var val;
+
+ // Empty object is for triggered events with no data
+ event = jQuery.event.fix( event || window.event || {} );
+
+ // Namespaced event handlers
+ var parts = event.type.split(".");
+ event.type = parts[0];
+
+ var c = jQuery.data(this, "events") && jQuery.data(this, "events")[event.type], args = Array.prototype.slice.call( arguments, 1 );
+ args.unshift( event );
+
+ for ( var j in c ) {
+ // Pass in a reference to the handler function itself
+ // So that we can later remove it
+ args[0].handler = c[j];
+ args[0].data = c[j].data;
+
+ // Filter the functions by class
+ if ( !parts[1] || c[j].type == parts[1] ) {
+ var tmp = c[j].apply( this, args );
+
+ if ( val !== false )
+ val = tmp;
+
+ if ( tmp === false ) {
+ event.preventDefault();
+ event.stopPropagation();
+ }
+ }
+ }
+
+ // Clean up added properties in IE to prevent memory leak
+ if (jQuery.browser.msie)
+ event.target = event.preventDefault = event.stopPropagation =
+ event.handler = event.data = null;
+
+ return val;
+ },
+
+ fix: function(event) {
+ // store a copy of the original event object
+ // and clone to set read-only properties
+ var originalEvent = event;
+ event = jQuery.extend({}, originalEvent);
+
+ // add preventDefault and stopPropagation since
+ // they will not work on the clone
+ event.preventDefault = function() {
+ // if preventDefault exists run it on the original event
+ if (originalEvent.preventDefault)
+ originalEvent.preventDefault();
+ // otherwise set the returnValue property of the original event to false (IE)
+ originalEvent.returnValue = false;
+ };
+ event.stopPropagation = function() {
+ // if stopPropagation exists run it on the original event
+ if (originalEvent.stopPropagation)
+ originalEvent.stopPropagation();
+ // otherwise set the cancelBubble property of the original event to true (IE)
+ originalEvent.cancelBubble = true;
+ };
+
+ // Fix target property, if necessary
+ if ( !event.target && event.srcElement )
+ event.target = event.srcElement;
+
+ // check if target is a textnode (safari)
+ if (jQuery.browser.safari && event.target.nodeType == 3)
+ event.target = originalEvent.target.parentNode;
+
+ // Add relatedTarget, if necessary
+ if ( !event.relatedTarget && event.fromElement )
+ event.relatedTarget = event.fromElement == event.target ? event.toElement : event.fromElement;
+
+ // Calculate pageX/Y if missing and clientX/Y available
+ if ( event.pageX == null && event.clientX != null ) {
+ var e = document.documentElement, b = document.body;
+ event.pageX = event.clientX + (e && e.scrollLeft || b.scrollLeft || 0);
+ event.pageY = event.clientY + (e && e.scrollTop || b.scrollTop || 0);
+ }
+
+ // Add which for key events
+ if ( !event.which && (event.charCode || event.keyCode) )
+ event.which = event.charCode || event.keyCode;
+
+ // Add metaKey to non-Mac browsers (use ctrl for PC's and Meta for Macs)
+ if ( !event.metaKey && event.ctrlKey )
+ event.metaKey = event.ctrlKey;
+
+ // Add which for click: 1 == left; 2 == middle; 3 == right
+ // Note: button is not normalized, so don't use it
+ if ( !event.which && event.button )
+ event.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) ));
+
+ return event;
+ }
+};
+
+jQuery.fn.extend({
+ bind: function( type, data, fn ) {
+ return type == "unload" ? this.one(type, data, fn) : this.each(function(){
+ jQuery.event.add( this, type, fn || data, fn && data );
+ });
+ },
+
+ one: function( type, data, fn ) {
+ return this.each(function(){
+ jQuery.event.add( this, type, function(event) {
+ jQuery(this).unbind(event);
+ return (fn || data).apply( this, arguments);
+ }, fn && data);
+ });
+ },
+
+ unbind: function( type, fn ) {
+ return this.each(function(){
+ jQuery.event.remove( this, type, fn );
+ });
+ },
+
+ trigger: function( type, data, fn ) {
+ return this.each(function(){
+ jQuery.event.trigger( type, data, this, true, fn );
+ });
+ },
+
+ triggerHandler: function( type, data, fn ) {
+ if ( this[0] )
+ return jQuery.event.trigger( type, data, this[0], false, fn );
+ },
+
+ toggle: function() {
+ // Save reference to arguments for access in closure
+ var a = arguments;
+
+ return this.click(function(e) {
+ // Figure out which function to execute
+ this.lastToggle = 0 == this.lastToggle ? 1 : 0;
+
+ // Make sure that clicks stop
+ e.preventDefault();
+
+ // and execute the function
+ return a[this.lastToggle].apply( this, [e] ) || false;
+ });
+ },
+
+ hover: function(f,g) {
+
+ // A private function for handling mouse 'hovering'
+ function handleHover(e) {
+ // Check if mouse(over|out) are still within the same parent element
+ var p = e.relatedTarget;
+
+ // Traverse up the tree
+ while ( p && p != this ) try { p = p.parentNode; } catch(e) { p = this; };
+
+ // If we actually just moused on to a sub-element, ignore it
+ if ( p == this ) return false;
+
+ // Execute the right function
+ return (e.type == "mouseover" ? f : g).apply(this, [e]);
+ }
+
+ // Bind the function to the two event listeners
+ return this.mouseover(handleHover).mouseout(handleHover);
+ },
+
+ ready: function(f) {
+ // Attach the listeners
+ bindReady();
+
+ // If the DOM is already ready
+ if ( jQuery.isReady )
+ // Execute the function immediately
+ f.apply( document, [jQuery] );
+
+ // Otherwise, remember the function for later
+ else
+ // Add the function to the wait list
+ jQuery.readyList.push( function() { return f.apply(this, [jQuery]); } );
+
+ return this;
+ }
+});
+
+jQuery.extend({
+ /*
+ * All the code that makes DOM Ready work nicely.
+ */
+ isReady: false,
+ readyList: [],
+
+ // Handle when the DOM is ready
+ ready: function() {
+ // Make sure that the DOM is not already loaded
+ if ( !jQuery.isReady ) {
+ // Remember that the DOM is ready
+ jQuery.isReady = true;
+
+ // If there are functions bound, to execute
+ if ( jQuery.readyList ) {
+ // Execute all of them
+ jQuery.each( jQuery.readyList, function(){
+ this.apply( document );
+ });
+
+ // Reset the list of functions
+ jQuery.readyList = null;
+ }
+ // Remove event listener to avoid memory leak
+ if ( jQuery.browser.mozilla || jQuery.browser.opera )
+ document.removeEventListener( "DOMContentLoaded", jQuery.ready, false );
+
+ // Remove script element used by IE hack
+ if( !window.frames.length ) // don't remove if frames are present (#1187)
+ jQuery(window).load(function(){ jQuery("#__ie_init").remove(); });
+ }
+ }
+});
+
+jQuery.each( ("blur,focus,load,resize,scroll,unload,click,dblclick," +
+ "mousedown,mouseup,mousemove,mouseover,mouseout,change,select," +
+ "submit,keydown,keypress,keyup,error").split(","), function(i,o){
+
+ // Handle event binding
+ jQuery.fn[o] = function(f){
+ return f ? this.bind(o, f) : this.trigger(o);
+ };
+});
+
+var readyBound = false;
+
+function bindReady(){
+ if ( readyBound ) return;
+ readyBound = true;
+
+ // If Mozilla is used
+ if ( jQuery.browser.mozilla || jQuery.browser.opera )
+ // Use the handy event callback
+ document.addEventListener( "DOMContentLoaded", jQuery.ready, false );
+
+ // If IE is used, use the excellent hack by Matthias Miller
+ // http://www.outofhanwell.com/blog/index.php?title=the_window_onload_problem_revisited
+ else if ( jQuery.browser.msie ) {
+
+ // Only works if you document.write() it
+ document.write("<scr" + "ipt id=__ie_init defer=true " +
+ "src=//:><\/script>");
+
+ // Use the defer script hack
+ var script = document.getElementById("__ie_init");
+
+ // script does not exist if jQuery is loaded dynamically
+ if ( script )
+ script.onreadystatechange = function() {
+ if ( this.readyState != "complete" ) return;
+ jQuery.ready();
+ };
+
+ // Clear from memory
+ script = null;
+
+ // If Safari is used
+ } else if ( jQuery.browser.safari )
+ // Continually check to see if the document.readyState is valid
+ jQuery.safariTimer = setInterval(function(){
+ // loaded and complete are both valid states
+ if ( document.readyState == "loaded" ||
+ document.readyState == "complete" ) {
+
+ // If either one are found, remove the timer
+ clearInterval( jQuery.safariTimer );
+ jQuery.safariTimer = null;
+
+ // and execute any waiting functions
+ jQuery.ready();
+ }
+ }, 10);
+
+ // A fallback to window.onload, that will always work
+ jQuery.event.add( window, "load", jQuery.ready );
+}
+jQuery.fn.extend({
+ load: function( url, params, callback ) {
+ if ( jQuery.isFunction( url ) )
+ return this.bind("load", url);
+
+ var off = url.indexOf(" ");
+ if ( off >= 0 ) {
+ var selector = url.slice(off, url.length);
+ url = url.slice(0, off);
+ }
+
+ callback = callback || function(){};
+
+ // Default to a GET request
+ var type = "GET";
+
+ // If the second parameter was provided
+ if ( params )
+ // If it's a function
+ if ( jQuery.isFunction( params ) ) {
+ // We assume that it's the callback
+ callback = params;
+ params = null;
+
+ // Otherwise, build a param string
+ } else {
+ params = jQuery.param( params );
+ type = "POST";
+ }
+
+ var self = this;
+
+ // Request the remote document
+ jQuery.ajax({
+ url: url,
+ type: type,
+ data: params,
+ complete: function(res, status){
+ // If successful, inject the HTML into all the matched elements
+ if ( status == "success" || status == "notmodified" )
+ // See if a selector was specified
+ self.html( selector ?
+ // Create a dummy div to hold the results
+ jQuery("<div/>")
+ // inject the contents of the document in, removing the scripts
+ // to avoid any 'Permission Denied' errors in IE
+ .append(res.responseText.replace(/<script(.|\s)*?\/script>/g, ""))
+
+ // Locate the specified elements
+ .find(selector) :
+
+ // If not, just inject the full result
+ res.responseText );
+
+ // Add delay to account for Safari's delay in globalEval
+ setTimeout(function(){
+ self.each( callback, [res.responseText, status, res] );
+ }, 13);
+ }
+ });
+ return this;
+ },
+
+ serialize: function() {
+ return jQuery.param(this.serializeArray());
+ },
+ serializeArray: function() {
+ return this.map(function(){
+ return jQuery.nodeName(this, "form") ?
+ jQuery.makeArray(this.elements) : this;
+ })
+ .filter(function(){
+ return this.name && !this.disabled &&
+ (this.checked || /select|textarea/i.test(this.nodeName) ||
+ /text|hidden|password/i.test(this.type));
+ })
+ .map(function(i, elem){
+ var val = jQuery(this).val();
+ return val == null ? null :
+ val.constructor == Array ?
+ jQuery.map( val, function(val, i){
+ return {name: elem.name, value: val};
+ }) :
+ {name: elem.name, value: val};
+ }).get();
+ }
+});
+
+// Attach a bunch of functions for handling common AJAX events
+jQuery.each( "ajaxStart,ajaxStop,ajaxComplete,ajaxError,ajaxSuccess,ajaxSend".split(","), function(i,o){
+ jQuery.fn[o] = function(f){
+ return this.bind(o, f);
+ };
+});
+
+var jsc = (new Date).getTime();
+
+jQuery.extend({
+ get: function( url, data, callback, type ) {
+ // shift arguments if data argument was ommited
+ if ( jQuery.isFunction( data ) ) {
+ callback = data;
+ data = null;
+ }
+
+ return jQuery.ajax({
+ type: "GET",
+ url: url,
+ data: data,
+ success: callback,
+ dataType: type
+ });
+ },
+
+ getScript: function( url, callback ) {
+ return jQuery.get(url, null, callback, "script");
+ },
+
+ getJSON: function( url, data, callback ) {
+ return jQuery.get(url, data, callback, "json");
+ },
+
+ post: function( url, data, callback, type ) {
+ if ( jQuery.isFunction( data ) ) {
+ callback = data;
+ data = {};
+ }
+
+ return jQuery.ajax({
+ type: "POST",
+ url: url,
+ data: data,
+ success: callback,
+ dataType: type
+ });
+ },
+
+ ajaxSetup: function( settings ) {
+ jQuery.extend( jQuery.ajaxSettings, settings );
+ },
+
+ ajaxSettings: {
+ global: true,
+ type: "GET",
+ timeout: 0,
+ contentType: "application/x-www-form-urlencoded",
+ processData: true,
+ async: true,
+ data: null
+ },
+
+ // Last-Modified header cache for next request
+ lastModified: {},
+
+ ajax: function( s ) {
+ var jsonp, jsre = /=(\?|%3F)/g, status, data;
+
+ // Extend the settings, but re-extend 's' so that it can be
+ // checked again later (in the test suite, specifically)
+ s = jQuery.extend(true, s, jQuery.extend(true, {}, jQuery.ajaxSettings, s));
+
+ // convert data if not already a string
+ if ( s.data && s.processData && typeof s.data != "string" )
+ s.data = jQuery.param(s.data);
+
+ // Handle JSONP Parameter Callbacks
+ if ( s.dataType == "jsonp" ) {
+ if ( s.type.toLowerCase() == "get" ) {
+ if ( !s.url.match(jsre) )
+ s.url += (s.url.match(/\?/) ? "&" : "?") + (s.jsonp || "callback") + "=?";
+ } else if ( !s.data || !s.data.match(jsre) )
+ s.data = (s.data ? s.data + "&" : "") + (s.jsonp || "callback") + "=?";
+ s.dataType = "json";
+ }
+
+ // Build temporary JSONP function
+ if ( s.dataType == "json" && (s.data && s.data.match(jsre) || s.url.match(jsre)) ) {
+ jsonp = "jsonp" + jsc++;
+
+ // Replace the =? sequence both in the query string and the data
+ if ( s.data )
+ s.data = s.data.replace(jsre, "=" + jsonp);
+ s.url = s.url.replace(jsre, "=" + jsonp);
+
+ // We need to make sure
+ // that a JSONP style response is executed properly
+ s.dataType = "script";
+
+ // Handle JSONP-style loading
+ window[ jsonp ] = function(tmp){
+ data = tmp;
+ success();
+ complete();
+ // Garbage collect
+ window[ jsonp ] = undefined;
+ try{ delete window[ jsonp ]; } catch(e){}
+ };
+ }
+
+ if ( s.dataType == "script" && s.cache == null )
+ s.cache = false;
+
+ if ( s.cache === false && s.type.toLowerCase() == "get" )
+ s.url += (s.url.match(/\?/) ? "&" : "?") + "_=" + (new Date()).getTime();
+
+ // If data is available, append data to url for get requests
+ if ( s.data && s.type.toLowerCase() == "get" ) {
+ s.url += (s.url.match(/\?/) ? "&" : "?") + s.data;
+
+ // IE likes to send both get and post data, prevent this
+ s.data = null;
+ }
+
+ // Watch for a new set of requests
+ if ( s.global && ! jQuery.active++ )
+ jQuery.event.trigger( "ajaxStart" );
+
+ // If we're requesting a remote document
+ // and trying to load JSON or Script
+ if ( !s.url.indexOf("http") && s.dataType == "script" ) {
+ var head = document.getElementsByTagName("head")[0];
+ var script = document.createElement("script");
+ script.src = s.url;
+
+ // Handle Script loading
+ if ( !jsonp && (s.success || s.complete) ) {
+ var done = false;
+
+ // Attach handlers for all browsers
+ script.onload = script.onreadystatechange = function(){
+ if ( !done && (!this.readyState ||
+ this.readyState == "loaded" || this.readyState == "complete") ) {
+ done = true;
+ success();
+ complete();
+ head.removeChild( script );
+ }
+ };
+ }
+
+ head.appendChild(script);
+
+ // We handle everything using the script element injection
+ return;
+ }
+
+ var requestDone = false;
+
+ // Create the request object; Microsoft failed to properly
+ // implement the XMLHttpRequest in IE7, so we use the ActiveXObject when it is available
+ var xml = window.ActiveXObject ? new ActiveXObject("Microsoft.XMLHTTP") : new XMLHttpRequest();
+
+ // Open the socket
+ xml.open(s.type, s.url, s.async);
+
+ // Set the correct header, if data is being sent
+ if ( s.data )
+ xml.setRequestHeader("Content-Type", s.contentType);
+
+ // Set the If-Modified-Since header, if ifModified mode.
+ if ( s.ifModified )
+ xml.setRequestHeader("If-Modified-Since",
+ jQuery.lastModified[s.url] || "Thu, 01 Jan 1970 00:00:00 GMT" );
+
+ // Set header so the called script knows that it's an XMLHttpRequest
+ xml.setRequestHeader("X-Requested-With", "XMLHttpRequest");
+
+ // Allow custom headers/mimetypes
+ if ( s.beforeSend )
+ s.beforeSend(xml);
+
+ if ( s.global )
+ jQuery.event.trigger("ajaxSend", [xml, s]);
+
+ // Wait for a response to come back
+ var onreadystatechange = function(isTimeout){
+ // The transfer is complete and the data is available, or the request timed out
+ if ( !requestDone && xml && (xml.readyState == 4 || isTimeout == "timeout") ) {
+ requestDone = true;
+
+ // clear poll interval
+ if (ival) {
+ clearInterval(ival);
+ ival = null;
+ }
+
+ status = isTimeout == "timeout" && "timeout" ||
+ !jQuery.httpSuccess( xml ) && "error" ||
+ s.ifModified && jQuery.httpNotModified( xml, s.url ) && "notmodified" ||
+ "success";
+
+ if ( status == "success" ) {
+ // Watch for, and catch, XML document parse errors
+ try {
+ // process the data (runs the xml through httpData regardless of callback)
+ data = jQuery.httpData( xml, s.dataType );
+ } catch(e) {
+ status = "parsererror";
+ }
+ }
+
+ // Make sure that the request was successful or notmodified
+ if ( status == "success" ) {
+ // Cache Last-Modified header, if ifModified mode.
+ var modRes;
+ try {
+ modRes = xml.getResponseHeader("Last-Modified");
+ } catch(e) {} // swallow exception thrown by FF if header is not available
+
+ if ( s.ifModified && modRes )
+ jQuery.lastModified[s.url] = modRes;
+
+ // JSONP handles its own success callback
+ if ( !jsonp )
+ success();
+ } else
+ jQuery.handleError(s, xml, status);
+
+ // Fire the complete handlers
+ complete();
+
+ // Stop memory leaks
+ if ( s.async )
+ xml = null;
+ }
+ };
+
+ if ( s.async ) {
+ // don't attach the handler to the request, just poll it instead
+ var ival = setInterval(onreadystatechange, 13);
+
+ // Timeout checker
+ if ( s.timeout > 0 )
+ setTimeout(function(){
+ // Check to see if the request is still happening
+ if ( xml ) {
+ // Cancel the request
+ xml.abort();
+
+ if( !requestDone )
+ onreadystatechange( "timeout" );
+ }
+ }, s.timeout);
+ }
+
+ // Send the data
+ try {
+ xml.send(s.data);
+ } catch(e) {
+ jQuery.handleError(s, xml, null, e);
+ }
+
+ // firefox 1.5 doesn't fire statechange for sync requests
+ if ( !s.async )
+ onreadystatechange();
+
+ // return XMLHttpRequest to allow aborting the request etc.
+ return xml;
+
+ function success(){
+ // If a local callback was specified, fire it and pass it the data
+ if ( s.success )
+ s.success( data, status );
+
+ // Fire the global callback
+ if ( s.global )
+ jQuery.event.trigger( "ajaxSuccess", [xml, s] );
+ }
+
+ function complete(){
+ // Process result
+ if ( s.complete )
+ s.complete(xml, status);
+
+ // The request was completed
+ if ( s.global )
+ jQuery.event.trigger( "ajaxComplete", [xml, s] );
+
+ // Handle the global AJAX counter
+ if ( s.global && ! --jQuery.active )
+ jQuery.event.trigger( "ajaxStop" );
+ }
+ },
+
+ handleError: function( s, xml, status, e ) {
+ // If a local callback was specified, fire it
+ if ( s.error ) s.error( xml, status, e );
+
+ // Fire the global callback
+ if ( s.global )
+ jQuery.event.trigger( "ajaxError", [xml, s, e] );
+ },
+
+ // Counter for holding the number of active queries
+ active: 0,
+
+ // Determines if an XMLHttpRequest was successful or not
+ httpSuccess: function( r ) {
+ try {
+ return !r.status && location.protocol == "file:" ||
+ ( r.status >= 200 && r.status < 300 ) || r.status == 304 ||
+ jQuery.browser.safari && r.status == undefined;
+ } catch(e){}
+ return false;
+ },
+
+ // Determines if an XMLHttpRequest returns NotModified
+ httpNotModified: function( xml, url ) {
+ try {
+ var xmlRes = xml.getResponseHeader("Last-Modified");
+
+ // Firefox always returns 200. check Last-Modified date
+ return xml.status == 304 || xmlRes == jQuery.lastModified[url] ||
+ jQuery.browser.safari && xml.status == undefined;
+ } catch(e){}
+ return false;
+ },
+
+ httpData: function( r, type ) {
+ var ct = r.getResponseHeader("content-type");
+ var xml = type == "xml" || !type && ct && ct.indexOf("xml") >= 0;
+ var data = xml ? r.responseXML : r.responseText;
+
+ if ( xml && data.documentElement.tagName == "parsererror" )
+ throw "parsererror";
+
+ // If the type is "script", eval it in global context
+ if ( type == "script" )
+ jQuery.globalEval( data );
+
+ // Get the JavaScript object, if JSON is used.
+ if ( type == "json" )
+ data = eval("(" + data + ")");
+
+ return data;
+ },
+
+ // Serialize an array of form elements or a set of
+ // key/values into a query string
+ param: function( a ) {
+ var s = [];
+
+ // If an array was passed in, assume that it is an array
+ // of form elements
+ if ( a.constructor == Array || a.jquery )
+ // Serialize the form elements
+ jQuery.each( a, function(){
+ s.push( encodeURIComponent(this.name) + "=" + encodeURIComponent( this.value ) );
+ });
+
+ // Otherwise, assume that it's an object of key/value pairs
+ else
+ // Serialize the key/values
+ for ( var j in a )
+ // If the value is an array then the key names need to be repeated
+ if ( a[j] && a[j].constructor == Array )
+ jQuery.each( a[j], function(){
+ s.push( encodeURIComponent(j) + "=" + encodeURIComponent( this ) );
+ });
+ else
+ s.push( encodeURIComponent(j) + "=" + encodeURIComponent( a[j] ) );
+
+ // Return the resulting serialization
+ return s.join("&").replace(/%20/g, "+");
+ }
+
+});
+jQuery.fn.extend({
+ show: function(speed,callback){
+ return speed ?
+ this.animate({
+ height: "show", width: "show", opacity: "show"
+ }, speed, callback) :
+
+ this.filter(":hidden").each(function(){
+ this.style.display = this.oldblock ? this.oldblock : "";
+ if ( jQuery.css(this,"display") == "none" )
+ this.style.display = "block";
+ }).end();
+ },
+
+ hide: function(speed,callback){
+ return speed ?
+ this.animate({
+ height: "hide", width: "hide", opacity: "hide"
+ }, speed, callback) :
+
+ this.filter(":visible").each(function(){
+ this.oldblock = this.oldblock || jQuery.css(this,"display");
+ if ( this.oldblock == "none" )
+ this.oldblock = "block";
+ this.style.display = "none";
+ }).end();
+ },
+
+ // Save the old toggle function
+ _toggle: jQuery.fn.toggle,
+
+ toggle: function( fn, fn2 ){
+ return jQuery.isFunction(fn) && jQuery.isFunction(fn2) ?
+ this._toggle( fn, fn2 ) :
+ fn ?
+ this.animate({
+ height: "toggle", width: "toggle", opacity: "toggle"
+ }, fn, fn2) :
+ this.each(function(){
+ jQuery(this)[ jQuery(this).is(":hidden") ? "show" : "hide" ]();
+ });
+ },
+
+ slideDown: function(speed,callback){
+ return this.animate({height: "show"}, speed, callback);
+ },
+
+ slideUp: function(speed,callback){
+ return this.animate({height: "hide"}, speed, callback);
+ },
+
+ slideToggle: function(speed, callback){
+ return this.animate({height: "toggle"}, speed, callback);
+ },
+
+ fadeIn: function(speed, callback){
+ return this.animate({opacity: "show"}, speed, callback);
+ },
+
+ fadeOut: function(speed, callback){
+ return this.animate({opacity: "hide"}, speed, callback);
+ },
+
+ fadeTo: function(speed,to,callback){
+ return this.animate({opacity: to}, speed, callback);
+ },
+
+ animate: function( prop, speed, easing, callback ) {
+ var opt = jQuery.speed(speed, easing, callback);
+
+ return this[ opt.queue === false ? "each" : "queue" ](function(){
+ opt = jQuery.extend({}, opt);
+ var hidden = jQuery(this).is(":hidden"), self = this;
+
+ for ( var p in prop ) {
+ if ( prop[p] == "hide" && hidden || prop[p] == "show" && !hidden )
+ return jQuery.isFunction(opt.complete) && opt.complete.apply(this);
+
+ if ( p == "height" || p == "width" ) {
+ // Store display property
+ opt.display = jQuery.css(this, "display");
+
+ // Make sure that nothing sneaks out
+ opt.overflow = this.style.overflow;
+ }
+ }
+
+ if ( opt.overflow != null )
+ this.style.overflow = "hidden";
+
+ opt.curAnim = jQuery.extend({}, prop);
+
+ jQuery.each( prop, function(name, val){
+ var e = new jQuery.fx( self, opt, name );
+
+ if ( /toggle|show|hide/.test(val) )
+ e[ val == "toggle" ? hidden ? "show" : "hide" : val ]( prop );
+ else {
+ var parts = val.toString().match(/^([+-]=)?([\d+-.]+)(.*)$/),
+ start = e.cur(true) || 0;
+
+ if ( parts ) {
+ var end = parseFloat(parts[2]),
+ unit = parts[3] || "px";
+
+ // We need to compute starting value
+ if ( unit != "px" ) {
+ self.style[ name ] = (end || 1) + unit;
+ start = ((end || 1) / e.cur(true)) * start;
+ self.style[ name ] = start + unit;
+ }
+
+ // If a +=/-= token was provided, we're doing a relative animation
+ if ( parts[1] )
+ end = ((parts[1] == "-=" ? -1 : 1) * end) + start;
+
+ e.custom( start, end, unit );
+ } else
+ e.custom( start, val, "" );
+ }
+ });
+
+ // For JS strict compliance
+ return true;
+ });
+ },
+
+ queue: function(type, fn){
+ if ( jQuery.isFunction(type) ) {
+ fn = type;
+ type = "fx";
+ }
+
+ if ( !type || (typeof type == "string" && !fn) )
+ return queue( this[0], type );
+
+ return this.each(function(){
+ if ( fn.constructor == Array )
+ queue(this, type, fn);
+ else {
+ queue(this, type).push( fn );
+
+ if ( queue(this, type).length == 1 )
+ fn.apply(this);
+ }
+ });
+ },
+
+ stop: function(){
+ var timers = jQuery.timers;
+
+ return this.each(function(){
+ for ( var i = 0; i < timers.length; i++ )
+ if ( timers[i].elem == this )
+ timers.splice(i--, 1);
+ }).dequeue();
+ }
+
+});
+
+var queue = function( elem, type, array ) {
+ if ( !elem )
+ return;
+
+ var q = jQuery.data( elem, type + "queue" );
+
+ if ( !q || array )
+ q = jQuery.data( elem, type + "queue",
+ array ? jQuery.makeArray(array) : [] );
+
+ return q;
+};
+
+jQuery.fn.dequeue = function(type){
+ type = type || "fx";
+
+ return this.each(function(){
+ var q = queue(this, type);
+
+ q.shift();
+
+ if ( q.length )
+ q[0].apply( this );
+ });
+};
+
+jQuery.extend({
+
+ speed: function(speed, easing, fn) {
+ var opt = speed && speed.constructor == Object ? speed : {
+ complete: fn || !fn && easing ||
+ jQuery.isFunction( speed ) && speed,
+ duration: speed,
+ easing: fn && easing || easing && easing.constructor != Function && easing
+ };
+
+ opt.duration = (opt.duration && opt.duration.constructor == Number ?
+ opt.duration :
+ { slow: 600, fast: 200 }[opt.duration]) || 400;
+
+ // Queueing
+ opt.old = opt.complete;
+ opt.complete = function(){
+ jQuery(this).dequeue();
+ if ( jQuery.isFunction( opt.old ) )
+ opt.old.apply( this );
+ };
+
+ return opt;
+ },
+
+ easing: {
+ linear: function( p, n, firstNum, diff ) {
+ return firstNum + diff * p;
+ },
+ swing: function( p, n, firstNum, diff ) {
+ return ((-Math.cos(p*Math.PI)/2) + 0.5) * diff + firstNum;
+ }
+ },
+
+ timers: [],
+
+ fx: function( elem, options, prop ){
+ this.options = options;
+ this.elem = elem;
+ this.prop = prop;
+
+ if ( !options.orig )
+ options.orig = {};
+ }
+
+});
+
+jQuery.fx.prototype = {
+
+ // Simple function for setting a style value
+ update: function(){
+ if ( this.options.step )
+ this.options.step.apply( this.elem, [ this.now, this ] );
+
+ (jQuery.fx.step[this.prop] || jQuery.fx.step._default)( this );
+
+ // Set display property to block for height/width animations
+ if ( this.prop == "height" || this.prop == "width" )
+ this.elem.style.display = "block";
+ },
+
+ // Get the current size
+ cur: function(force){
+ if ( this.elem[this.prop] != null && this.elem.style[this.prop] == null )
+ return this.elem[ this.prop ];
+
+ var r = parseFloat(jQuery.curCSS(this.elem, this.prop, force));
+ return r && r > -10000 ? r : parseFloat(jQuery.css(this.elem, this.prop)) || 0;
+ },
+
+ // Start an animation from one number to another
+ custom: function(from, to, unit){
+ this.startTime = (new Date()).getTime();
+ this.start = from;
+ this.end = to;
+ this.unit = unit || this.unit || "px";
+ this.now = this.start;
+ this.pos = this.state = 0;
+ this.update();
+
+ var self = this;
+ function t(){
+ return self.step();
+ }
+
+ t.elem = this.elem;
+
+ jQuery.timers.push(t);
+
+ if ( jQuery.timers.length == 1 ) {
+ var timer = setInterval(function(){
+ var timers = jQuery.timers;
+
+ for ( var i = 0; i < timers.length; i++ )
+ if ( !timers[i]() )
+ timers.splice(i--, 1);
+
+ if ( !timers.length )
+ clearInterval( timer );
+ }, 13);
+ }
+ },
+
+ // Simple 'show' function
+ show: function(){
+ // Remember where we started, so that we can go back to it later
+ this.options.orig[this.prop] = jQuery.attr( this.elem.style, this.prop );
+ this.options.show = true;
+
+ // Begin the animation
+ this.custom(0, this.cur());
+
+ // Make sure that we start at a small width/height to avoid any
+ // flash of content
+ if ( this.prop == "width" || this.prop == "height" )
+ this.elem.style[this.prop] = "1px";
+
+ // Start by showing the element
+ jQuery(this.elem).show();
+ },
+
+ // Simple 'hide' function
+ hide: function(){
+ // Remember where we started, so that we can go back to it later
+ this.options.orig[this.prop] = jQuery.attr( this.elem.style, this.prop );
+ this.options.hide = true;
+
+ // Begin the animation
+ this.custom(this.cur(), 0);
+ },
+
+ // Each step of an animation
+ step: function(){
+ var t = (new Date()).getTime();
+
+ if ( t > this.options.duration + this.startTime ) {
+ this.now = this.end;
+ this.pos = this.state = 1;
+ this.update();
+
+ this.options.curAnim[ this.prop ] = true;
+
+ var done = true;
+ for ( var i in this.options.curAnim )
+ if ( this.options.curAnim[i] !== true )
+ done = false;
+
+ if ( done ) {
+ if ( this.options.display != null ) {
+ // Reset the overflow
+ this.elem.style.overflow = this.options.overflow;
+
+ // Reset the display
+ this.elem.style.display = this.options.display;
+ if ( jQuery.css(this.elem, "display") == "none" )
+ this.elem.style.display = "block";
+ }
+
+ // Hide the element if the "hide" operation was done
+ if ( this.options.hide )
+ this.elem.style.display = "none";
+
+ // Reset the properties, if the item has been hidden or shown
+ if ( this.options.hide || this.options.show )
+ for ( var p in this.options.curAnim )
+ jQuery.attr(this.elem.style, p, this.options.orig[p]);
+ }
+
+ // If a callback was provided, execute it
+ if ( done && jQuery.isFunction( this.options.complete ) )
+ // Execute the complete function
+ this.options.complete.apply( this.elem );
+
+ return false;
+ } else {
+ var n = t - this.startTime;
+ this.state = n / this.options.duration;
+
+ // Perform the easing function, defaults to swing
+ this.pos = jQuery.easing[this.options.easing || (jQuery.easing.swing ? "swing" : "linear")](this.state, n, 0, 1, this.options.duration);
+ this.now = this.start + ((this.end - this.start) * this.pos);
+
+ // Perform the next step of the animation
+ this.update();
+ }
+
+ return true;
+ }
+
+};
+
+jQuery.fx.step = {
+ scrollLeft: function(fx){
+ fx.elem.scrollLeft = fx.now;
+ },
+
+ scrollTop: function(fx){
+ fx.elem.scrollTop = fx.now;
+ },
+
+ opacity: function(fx){
+ jQuery.attr(fx.elem.style, "opacity", fx.now);
+ },
+
+ _default: function(fx){
+ fx.elem.style[ fx.prop ] = fx.now + fx.unit;
+ }
+};
+// The Offset Method
+// Originally By Brandon Aaron, part of the Dimension Plugin
+// http://jquery.com/plugins/project/dimensions
+jQuery.fn.offset = function() {
+ var left = 0, top = 0, elem = this[0], results;
+
+ if ( elem ) with ( jQuery.browser ) {
+ var absolute = jQuery.css(elem, "position") == "absolute",
+ parent = elem.parentNode,
+ offsetParent = elem.offsetParent,
+ doc = elem.ownerDocument,
+ safari2 = safari && parseInt(version) < 522;
+
+ // Use getBoundingClientRect if available
+ if ( elem.getBoundingClientRect ) {
+ box = elem.getBoundingClientRect();
+
+ // Add the document scroll offsets
+ add(
+ box.left + Math.max(doc.documentElement.scrollLeft, doc.body.scrollLeft),
+ box.top + Math.max(doc.documentElement.scrollTop, doc.body.scrollTop)
+ );
+
+ // IE adds the HTML element's border, by default it is medium which is 2px
+ // IE 6 and IE 7 quirks mode the border width is overwritable by the following css html { border: 0; }
+ // IE 7 standards mode, the border is always 2px
+ if ( msie ) {
+ var border = jQuery("html").css("borderWidth");
+ border = (border == "medium" || jQuery.boxModel && parseInt(version) >= 7) && 2 || border;
+ add( -border, -border );
+ }
+
+ // Otherwise loop through the offsetParents and parentNodes
+ } else {
+
+ // Initial element offsets
+ add( elem.offsetLeft, elem.offsetTop );
+
+ // Get parent offsets
+ while ( offsetParent ) {
+ // Add offsetParent offsets
+ add( offsetParent.offsetLeft, offsetParent.offsetTop );
+
+ // Mozilla and Safari > 2 does not include the border on offset parents
+ // However Mozilla adds the border for table cells
+ if ( mozilla && /^t[d|h]$/i.test(parent.tagName) || !safari2 )
+ border( offsetParent );
+
+ // Safari <= 2 doubles body offsets with an absolutely positioned element or parent
+ if ( safari2 && !absolute && jQuery.css(offsetParent, "position") == "absolute" )
+ absolute = true;
+
+ // Get next offsetParent
+ offsetParent = offsetParent.offsetParent;
+ }
+
+ // Get parent scroll offsets
+ while ( parent.tagName && !/^body|html$/i.test(parent.tagName) ) {
+ // Work around opera inline/table scrollLeft/Top bug
+ if ( !/^inline|table-row.*$/i.test(jQuery.css(parent, "display")) )
+ // Subtract parent scroll offsets
+ add( -parent.scrollLeft, -parent.scrollTop );
+
+ // Mozilla does not add the border for a parent that has overflow != visible
+ if ( mozilla && jQuery.css(parent, "overflow") != "visible" )
+ border( parent );
+
+ // Get next parent
+ parent = parent.parentNode;
+ }
+
+ // Safari doubles body offsets with an absolutely positioned element or parent
+ if ( safari2 && absolute )
+ add( -doc.body.offsetLeft, -doc.body.offsetTop );
+ }
+
+ // Return an object with top and left properties
+ results = { top: top, left: left };
+ }
+
+ return results;
+
+ function border(elem) {
+ add( jQuery.css(elem, "borderLeftWidth"), jQuery.css(elem, "borderTopWidth") );
+ }
+
+ function add(l, t) {
+ left += parseInt(l) || 0;
+ top += parseInt(t) || 0;
+ }
+};
+})();
diff --git a/site/app/webroot/js/simile/ajax/scripts/json.js b/site/app/webroot/js/simile/ajax/scripts/json.js
new file mode 100755
index 0000000..ef6dc30
--- /dev/null
+++ b/site/app/webroot/js/simile/ajax/scripts/json.js
@@ -0,0 +1,129 @@
+/*
+ * Copied directly from http://www.json.org/json.js.
+ */
+
+/*
+ json.js
+ 2006-04-28
+
+ This file adds these methods to JavaScript:
+
+ object.toJSONString()
+
+ This method produces a JSON text from an object. The
+ object must not contain any cyclical references.
+
+ array.toJSONString()
+
+ This method produces a JSON text from an array. The
+ array must not contain any cyclical references.
+
+ string.parseJSON()
+
+ This method parses a JSON text to produce an object or
+ array. It will return false if there is an error.
+*/
+
+SimileAjax.JSON = new Object();
+
+(function () {
+ var m = {
+ '\b': '\\b',
+ '\t': '\\t',
+ '\n': '\\n',
+ '\f': '\\f',
+ '\r': '\\r',
+ '"' : '\\"',
+ '\\': '\\\\'
+ };
+ var s = {
+ array: function (x) {
+ var a = ['['], b, f, i, l = x.length, v;
+ for (i = 0; i < l; i += 1) {
+ v = x[i];
+ f = s[typeof v];
+ if (f) {
+ v = f(v);
+ if (typeof v == 'string') {
+ if (b) {
+ a[a.length] = ',';
+ }
+ a[a.length] = v;
+ b = true;
+ }
+ }
+ }
+ a[a.length] = ']';
+ return a.join('');
+ },
+ 'boolean': function (x) {
+ return String(x);
+ },
+ 'null': function (x) {
+ return "null";
+ },
+ number: function (x) {
+ return isFinite(x) ? String(x) : 'null';
+ },
+ object: function (x) {
+ if (x) {
+ if (x instanceof Array) {
+ return s.array(x);
+ }
+ var a = ['{'], b, f, i, v;
+ for (i in x) {
+ v = x[i];
+ f = s[typeof v];
+ if (f) {
+ v = f(v);
+ if (typeof v == 'string') {
+ if (b) {
+ a[a.length] = ',';
+ }
+ a.push(s.string(i), ':', v);
+ b = true;
+ }
+ }
+ }
+ a[a.length] = '}';
+ return a.join('');
+ }
+ return 'null';
+ },
+ string: function (x) {
+ if (/["\\\x00-\x1f]/.test(x)) {
+ x = x.replace(/([\x00-\x1f\\"])/g, function(a, b) {
+ var c = m[b];
+ if (c) {
+ return c;
+ }
+ c = b.charCodeAt();
+ return '\\u00' +
+ Math.floor(c / 16).toString(16) +
+ (c % 16).toString(16);
+ });
+ }
+ return '"' + x + '"';
+ }
+ };
+
+ SimileAjax.JSON.toJSONString = function(o) {
+ if (o instanceof Object) {
+ return s.object(o);
+ } else if (o instanceof Array) {
+ return s.array(o);
+ } else {
+ return o.toString();
+ }
+ };
+
+ SimileAjax.JSON.parseJSON = function () {
+ try {
+ return !(/[^,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]/.test(
+ this.replace(/"(\\.|[^"\\])*"/g, ''))) &&
+ eval('(' + this + ')');
+ } catch (e) {
+ return false;
+ }
+ };
+})();
diff --git a/site/app/webroot/js/simile/ajax/scripts/platform.js b/site/app/webroot/js/simile/ajax/scripts/platform.js
new file mode 100755
index 0000000..7fd342f
--- /dev/null
+++ b/site/app/webroot/js/simile/ajax/scripts/platform.js
@@ -0,0 +1,98 @@
+/*==================================================
+ * Platform Utility Functions and Constants
+ *==================================================
+ */
+
+SimileAjax.Platform.os = {
+ isMac: false,
+ isWin: false,
+ isWin32: false,
+ isUnix: false
+};
+SimileAjax.Platform.browser = {
+ isIE: false,
+ isNetscape: false,
+ isMozilla: false,
+ isFirefox: false,
+ isOpera: false,
+ isSafari: false,
+
+ majorVersion: 0,
+ minorVersion: 0
+};
+
+(function() {
+ var an = navigator.appName.toLowerCase();
+ var ua = navigator.userAgent.toLowerCase();
+
+ /*
+ * Operating system
+ */
+ SimileAjax.Platform.os.isMac = (ua.indexOf('mac') != -1);
+ SimileAjax.Platform.os.isWin = (ua.indexOf('win') != -1);
+ SimileAjax.Platform.os.isWin32 = SimileAjax.Platform.isWin && (
+ ua.indexOf('95') != -1 ||
+ ua.indexOf('98') != -1 ||
+ ua.indexOf('nt') != -1 ||
+ ua.indexOf('win32') != -1 ||
+ ua.indexOf('32bit') != -1
+ );
+ SimileAjax.Platform.os.isUnix = (ua.indexOf('x11') != -1);
+
+ /*
+ * Browser
+ */
+ SimileAjax.Platform.browser.isIE = (an.indexOf("microsoft") != -1);
+ SimileAjax.Platform.browser.isNetscape = (an.indexOf("netscape") != -1);
+ SimileAjax.Platform.browser.isMozilla = (ua.indexOf("mozilla") != -1);
+ SimileAjax.Platform.browser.isFirefox = (ua.indexOf("firefox") != -1);
+ SimileAjax.Platform.browser.isOpera = (an.indexOf("opera") != -1);
+ SimileAjax.Platform.browser.isSafari = (an.indexOf("safari") != -1);
+
+ var parseVersionString = function(s) {
+ var a = s.split(".");
+ SimileAjax.Platform.browser.majorVersion = parseInt(a[0]);
+ SimileAjax.Platform.browser.minorVersion = parseInt(a[1]);
+ };
+ var indexOf = function(s, sub, start) {
+ var i = s.indexOf(sub, start);
+ return i >= 0 ? i : s.length;
+ };
+
+ if (SimileAjax.Platform.browser.isMozilla) {
+ var offset = ua.indexOf("mozilla/");
+ if (offset >= 0) {
+ parseVersionString(ua.substring(offset + 8, indexOf(ua, " ", offset)));
+ }
+ }
+ if (SimileAjax.Platform.browser.isIE) {
+ var offset = ua.indexOf("msie ");
+ if (offset >= 0) {
+ parseVersionString(ua.substring(offset + 5, indexOf(ua, ";", offset)));
+ }
+ }
+ if (SimileAjax.Platform.browser.isNetscape) {
+ var offset = ua.indexOf("rv:");
+ if (offset >= 0) {
+ parseVersionString(ua.substring(offset + 3, indexOf(ua, ")", offset)));
+ }
+ }
+ if (SimileAjax.Platform.browser.isFirefox) {
+ var offset = ua.indexOf("firefox/");
+ if (offset >= 0) {
+ parseVersionString(ua.substring(offset + 8, indexOf(ua, " ", offset)));
+ }
+ }
+
+ if (!("localeCompare" in String.prototype)) {
+ String.prototype.localeCompare = function (s) {
+ if (this < s) return -1;
+ else if (this > s) return 1;
+ else return 0;
+ };
+ }
+})();
+
+SimileAjax.Platform.getDefaultLocale = function() {
+ return SimileAjax.Platform.clientLocale;
+}; \ No newline at end of file
diff --git a/site/app/webroot/js/simile/ajax/scripts/signal.js b/site/app/webroot/js/simile/ajax/scripts/signal.js
new file mode 100755
index 0000000..7bfcf2a
--- /dev/null
+++ b/site/app/webroot/js/simile/ajax/scripts/signal.js
@@ -0,0 +1,44 @@
+/*==================================================
+ * This file is used to detect that all outstanding
+ * javascript files have been loaded. You can put
+ * a function reference into SimileAjax_onLoad
+ * to have it executed once all javascript files
+ * have loaded.
+ *==================================================
+ */
+(function() {
+ var substring = SimileAjax.urlPrefix + "scripts/signal.js";
+ var heads = document.documentElement.getElementsByTagName("head");
+ for (var h = 0; h < heads.length; h++) {
+ var node = heads[h].firstChild;
+ while (node != null) {
+ if (node.nodeType == 1 && node.tagName.toLowerCase() == "script") {
+ var url = node.src;
+ var i = url.indexOf(substring);
+ if (i >= 0) {
+ heads[h].removeChild(node); // remove it so we won't hit it again
+
+ var count = parseInt(url.substr(substring.length + 1));
+ SimileAjax.loadingScriptsCount -= count;
+
+ if (SimileAjax.loadingScriptsCount == 0) {
+ var f = null;
+ if (typeof SimileAjax_onLoad == "string") {
+ f = eval(SimileAjax_onLoad);
+ SimileAjax_onLoad = null;
+ } else if (typeof SimileAjax_onLoad == "function") {
+ f = SimileAjax_onLoad;
+ SimileAjax_onLoad = null;
+ }
+
+ if (f != null) {
+ f();
+ }
+ }
+ return;
+ }
+ }
+ node = node.nextSibling;
+ }
+ }
+})(); \ No newline at end of file
diff --git a/site/app/webroot/js/simile/ajax/scripts/string.js b/site/app/webroot/js/simile/ajax/scripts/string.js
new file mode 100755
index 0000000..01466d8
--- /dev/null
+++ b/site/app/webroot/js/simile/ajax/scripts/string.js
@@ -0,0 +1,43 @@
+/*==================================================
+ * String Utility Functions and Constants
+ *==================================================
+ */
+
+String.prototype.trim = function() {
+ return this.replace(/^\s+|\s+$/g, '');
+};
+
+String.prototype.startsWith = function(prefix) {
+ return this.length >= prefix.length && this.substr(0, prefix.length) == prefix;
+};
+
+String.prototype.endsWith = function(suffix) {
+ return this.length >= suffix.length && this.substr(this.length - suffix.length) == suffix;
+};
+
+String.substitute = function(s, objects) {
+ var result = "";
+ var start = 0;
+ while (start < s.length - 1) {
+ var percent = s.indexOf("%", start);
+ if (percent < 0 || percent == s.length - 1) {
+ break;
+ } else if (percent > start && s.charAt(percent - 1) == "\\") {
+ result += s.substring(start, percent - 1) + "%";
+ start = percent + 1;
+ } else {
+ var n = parseInt(s.charAt(percent + 1));
+ if (isNaN(n) || n >= objects.length) {
+ result += s.substring(start, percent + 2);
+ } else {
+ result += s.substring(start, percent) + objects[n].toString();
+ }
+ start = percent + 2;
+ }
+ }
+
+ if (start < s.length) {
+ result += s.substring(start);
+ }
+ return result;
+};
diff --git a/site/app/webroot/js/simile/ajax/scripts/units.js b/site/app/webroot/js/simile/ajax/scripts/units.js
new file mode 100755
index 0000000..54f2a5b
--- /dev/null
+++ b/site/app/webroot/js/simile/ajax/scripts/units.js
@@ -0,0 +1,64 @@
+/*==================================================
+ * Default Unit
+ *==================================================
+ */
+
+SimileAjax.NativeDateUnit = new Object();
+
+SimileAjax.NativeDateUnit.makeDefaultValue = function() {
+ return new Date();
+};
+
+SimileAjax.NativeDateUnit.cloneValue = function(v) {
+ return new Date(v.getTime());
+};
+
+SimileAjax.NativeDateUnit.getParser = function(format) {
+ if (typeof format == "string") {
+ format = format.toLowerCase();
+ }
+ return (format == "iso8601" || format == "iso 8601") ?
+ SimileAjax.DateTime.parseIso8601DateTime :
+ SimileAjax.DateTime.parseGregorianDateTime;
+};
+
+SimileAjax.NativeDateUnit.parseFromObject = function(o) {
+ return SimileAjax.DateTime.parseGregorianDateTime(o);
+};
+
+SimileAjax.NativeDateUnit.toNumber = function(v) {
+ return v.getTime();
+};
+
+SimileAjax.NativeDateUnit.fromNumber = function(n) {
+ return new Date(n);
+};
+
+SimileAjax.NativeDateUnit.compare = function(v1, v2) {
+ var n1, n2;
+ if (typeof v1 == "object") {
+ n1 = v1.getTime();
+ } else {
+ n1 = Number(v1);
+ }
+ if (typeof v2 == "object") {
+ n2 = v2.getTime();
+ } else {
+ n2 = Number(v2);
+ }
+
+ return n1 - n2;
+};
+
+SimileAjax.NativeDateUnit.earlier = function(v1, v2) {
+ return SimileAjax.NativeDateUnit.compare(v1, v2) < 0 ? v1 : v2;
+};
+
+SimileAjax.NativeDateUnit.later = function(v1, v2) {
+ return SimileAjax.NativeDateUnit.compare(v1, v2) > 0 ? v1 : v2;
+};
+
+SimileAjax.NativeDateUnit.change = function(v, n) {
+ return new Date(v.getTime() + n);
+};
+
diff --git a/site/app/webroot/js/simile/ajax/scripts/window-manager.js b/site/app/webroot/js/simile/ajax/scripts/window-manager.js
new file mode 100755
index 0000000..eb383ee
--- /dev/null
+++ b/site/app/webroot/js/simile/ajax/scripts/window-manager.js
@@ -0,0 +1,414 @@
+/**
+ * @fileOverview UI layers and window-wide dragging
+ * @name SimileAjax.WindowManager
+ */
+
+/**
+ * This is a singleton that keeps track of UI layers (modal and
+ * modeless) and enables/disables UI elements based on which layers
+ * they belong to. It also provides window-wide dragging
+ * implementation.
+ */
+SimileAjax.WindowManager = {
+ _initialized: false,
+ _listeners: [],
+
+ _draggedElement: null,
+ _draggedElementCallback: null,
+ _dropTargetHighlightElement: null,
+ _lastCoords: null,
+ _ghostCoords: null,
+ _draggingMode: "",
+ _dragging: false,
+
+ _layers: []
+};
+
+SimileAjax.WindowManager.initialize = function() {
+ if (SimileAjax.WindowManager._initialized) {
+ return;
+ }
+
+ SimileAjax.DOM.registerEvent(document.body, "mousedown", SimileAjax.WindowManager._onBodyMouseDown);
+ SimileAjax.DOM.registerEvent(document.body, "mousemove", SimileAjax.WindowManager._onBodyMouseMove);
+ SimileAjax.DOM.registerEvent(document.body, "mouseup", SimileAjax.WindowManager._onBodyMouseUp);
+ SimileAjax.DOM.registerEvent(document, "keydown", SimileAjax.WindowManager._onBodyKeyDown);
+ SimileAjax.DOM.registerEvent(document, "keyup", SimileAjax.WindowManager._onBodyKeyUp);
+
+ SimileAjax.WindowManager._layers.push({index: 0});
+
+ SimileAjax.WindowManager._historyListener = {
+ onBeforeUndoSeveral: function() {},
+ onAfterUndoSeveral: function() {},
+ onBeforeUndo: function() {},
+ onAfterUndo: function() {},
+
+ onBeforeRedoSeveral: function() {},
+ onAfterRedoSeveral: function() {},
+ onBeforeRedo: function() {},
+ onAfterRedo: function() {}
+ };
+ //SimileAjax.History.addListener(SimileAjax.WindowManager._historyListener);
+
+ SimileAjax.WindowManager._initialized = true;
+};
+
+SimileAjax.WindowManager.getBaseLayer = function() {
+ SimileAjax.WindowManager.initialize();
+ return SimileAjax.WindowManager._layers[0];
+};
+
+SimileAjax.WindowManager.getHighestLayer = function() {
+ SimileAjax.WindowManager.initialize();
+ return SimileAjax.WindowManager._layers[SimileAjax.WindowManager._layers.length - 1];
+};
+
+SimileAjax.WindowManager.registerEventWithObject = function(elmt, eventName, obj, handlerName, layer) {
+ SimileAjax.WindowManager.registerEvent(
+ elmt,
+ eventName,
+ function(elmt2, evt, target) {
+ return obj[handlerName].call(obj, elmt2, evt, target);
+ },
+ layer
+ );
+};
+
+SimileAjax.WindowManager.registerEvent = function(elmt, eventName, handler, layer) {
+ if (layer == null) {
+ layer = SimileAjax.WindowManager.getHighestLayer();
+ }
+
+ var handler2 = function(elmt, evt, target) {
+ if (SimileAjax.WindowManager._canProcessEventAtLayer(layer)) {
+ SimileAjax.WindowManager._popToLayer(layer.index);
+ try {
+ handler(elmt, evt, target);
+ } catch (e) {
+ SimileAjax.Debug.exception(e);
+ }
+ }
+ SimileAjax.DOM.cancelEvent(evt);
+ return false;
+ }
+
+ SimileAjax.DOM.registerEvent(elmt, eventName, handler2);
+};
+
+SimileAjax.WindowManager.pushLayer = function(f, ephemeral, elmt) {
+ var layer = { onPop: f, index: SimileAjax.WindowManager._layers.length, ephemeral: (ephemeral), elmt: elmt };
+ SimileAjax.WindowManager._layers.push(layer);
+
+ return layer;
+};
+
+SimileAjax.WindowManager.popLayer = function(layer) {
+ for (var i = 1; i < SimileAjax.WindowManager._layers.length; i++) {
+ if (SimileAjax.WindowManager._layers[i] == layer) {
+ SimileAjax.WindowManager._popToLayer(i - 1);
+ break;
+ }
+ }
+};
+
+SimileAjax.WindowManager.popAllLayers = function() {
+ SimileAjax.WindowManager._popToLayer(0);
+};
+
+SimileAjax.WindowManager.registerForDragging = function(elmt, callback, layer) {
+ SimileAjax.WindowManager.registerEvent(
+ elmt,
+ "mousedown",
+ function(elmt, evt, target) {
+ SimileAjax.WindowManager._handleMouseDown(elmt, evt, callback);
+ },
+ layer
+ );
+};
+
+SimileAjax.WindowManager._popToLayer = function(level) {
+ while (level+1 < SimileAjax.WindowManager._layers.length) {
+ try {
+ var layer = SimileAjax.WindowManager._layers.pop();
+ if (layer.onPop != null) {
+ layer.onPop();
+ }
+ } catch (e) {
+ }
+ }
+};
+
+SimileAjax.WindowManager._canProcessEventAtLayer = function(layer) {
+ if (layer.index == (SimileAjax.WindowManager._layers.length - 1)) {
+ return true;
+ }
+ for (var i = layer.index + 1; i < SimileAjax.WindowManager._layers.length; i++) {
+ if (!SimileAjax.WindowManager._layers[i].ephemeral) {
+ return false;
+ }
+ }
+ return true;
+};
+
+SimileAjax.WindowManager.cancelPopups = function(evt) {
+ var evtCoords = (evt) ? SimileAjax.DOM.getEventPageCoordinates(evt) : { x: -1, y: -1 };
+
+ var i = SimileAjax.WindowManager._layers.length - 1;
+ while (i > 0 && SimileAjax.WindowManager._layers[i].ephemeral) {
+ var layer = SimileAjax.WindowManager._layers[i];
+ if (layer.elmt != null) { // if event falls within main element of layer then don't cancel
+ var elmt = layer.elmt;
+ var elmtCoords = SimileAjax.DOM.getPageCoordinates(elmt);
+ if (evtCoords.x >= elmtCoords.left && evtCoords.x < (elmtCoords.left + elmt.offsetWidth) &&
+ evtCoords.y >= elmtCoords.top && evtCoords.y < (elmtCoords.top + elmt.offsetHeight)) {
+ break;
+ }
+ }
+ i--;
+ }
+ SimileAjax.WindowManager._popToLayer(i);
+};
+
+SimileAjax.WindowManager._onBodyMouseDown = function(elmt, evt, target) {
+ if (!("eventPhase" in evt) || evt.eventPhase == evt.BUBBLING_PHASE) {
+ SimileAjax.WindowManager.cancelPopups(evt);
+ }
+};
+
+SimileAjax.WindowManager._handleMouseDown = function(elmt, evt, callback) {
+ SimileAjax.WindowManager._draggedElement = elmt;
+ SimileAjax.WindowManager._draggedElementCallback = callback;
+ SimileAjax.WindowManager._lastCoords = { x: evt.clientX, y: evt.clientY };
+
+ SimileAjax.DOM.cancelEvent(evt);
+ return false;
+};
+
+SimileAjax.WindowManager._onBodyKeyDown = function(elmt, evt, target) {
+ if (SimileAjax.WindowManager._dragging) {
+ if (evt.keyCode == 27) { // esc
+ SimileAjax.WindowManager._cancelDragging();
+ } else if ((evt.keyCode == 17 || evt.keyCode == 16) && SimileAjax.WindowManager._draggingMode != "copy") {
+ SimileAjax.WindowManager._draggingMode = "copy";
+
+ var img = SimileAjax.Graphics.createTranslucentImage(SimileAjax.urlPrefix + "images/copy.png");
+ img.style.position = "absolute";
+ img.style.left = (SimileAjax.WindowManager._ghostCoords.left - 16) + "px";
+ img.style.top = (SimileAjax.WindowManager._ghostCoords.top) + "px";
+ document.body.appendChild(img);
+
+ SimileAjax.WindowManager._draggingModeIndicatorElmt = img;
+ }
+ }
+};
+
+SimileAjax.WindowManager._onBodyKeyUp = function(elmt, evt, target) {
+ if (SimileAjax.WindowManager._dragging) {
+ if (evt.keyCode == 17 || evt.keyCode == 16) {
+ SimileAjax.WindowManager._draggingMode = "";
+ if (SimileAjax.WindowManager._draggingModeIndicatorElmt != null) {
+ document.body.removeChild(SimileAjax.WindowManager._draggingModeIndicatorElmt);
+ SimileAjax.WindowManager._draggingModeIndicatorElmt = null;
+ }
+ }
+ }
+};
+
+SimileAjax.WindowManager._onBodyMouseMove = function(elmt, evt, target) {
+ if (SimileAjax.WindowManager._draggedElement != null) {
+ var callback = SimileAjax.WindowManager._draggedElementCallback;
+
+ var lastCoords = SimileAjax.WindowManager._lastCoords;
+ var diffX = evt.clientX - lastCoords.x;
+ var diffY = evt.clientY - lastCoords.y;
+
+ if (!SimileAjax.WindowManager._dragging) {
+ if (Math.abs(diffX) > 5 || Math.abs(diffY) > 5) {
+ try {
+ if ("onDragStart" in callback) {
+ callback.onDragStart();
+ }
+
+ if ("ghost" in callback && callback.ghost) {
+ var draggedElmt = SimileAjax.WindowManager._draggedElement;
+
+ SimileAjax.WindowManager._ghostCoords = SimileAjax.DOM.getPageCoordinates(draggedElmt);
+ SimileAjax.WindowManager._ghostCoords.left += diffX;
+ SimileAjax.WindowManager._ghostCoords.top += diffY;
+
+ var ghostElmt = draggedElmt.cloneNode(true);
+ ghostElmt.style.position = "absolute";
+ ghostElmt.style.left = SimileAjax.WindowManager._ghostCoords.left + "px";
+ ghostElmt.style.top = SimileAjax.WindowManager._ghostCoords.top + "px";
+ ghostElmt.style.zIndex = 1000;
+ SimileAjax.Graphics.setOpacity(ghostElmt, 50);
+
+ document.body.appendChild(ghostElmt);
+ callback._ghostElmt = ghostElmt;
+ }
+
+ SimileAjax.WindowManager._dragging = true;
+ SimileAjax.WindowManager._lastCoords = { x: evt.clientX, y: evt.clientY };
+
+ document.body.focus();
+ } catch (e) {
+ SimileAjax.Debug.exception("WindowManager: Error handling mouse down", e);
+ SimileAjax.WindowManager._cancelDragging();
+ }
+ }
+ } else {
+ try {
+ SimileAjax.WindowManager._lastCoords = { x: evt.clientX, y: evt.clientY };
+
+ if ("onDragBy" in callback) {
+ callback.onDragBy(diffX, diffY);
+ }
+
+ if ("_ghostElmt" in callback) {
+ var ghostElmt = callback._ghostElmt;
+
+ SimileAjax.WindowManager._ghostCoords.left += diffX;
+ SimileAjax.WindowManager._ghostCoords.top += diffY;
+
+ ghostElmt.style.left = SimileAjax.WindowManager._ghostCoords.left + "px";
+ ghostElmt.style.top = SimileAjax.WindowManager._ghostCoords.top + "px";
+ if (SimileAjax.WindowManager._draggingModeIndicatorElmt != null) {
+ var indicatorElmt = SimileAjax.WindowManager._draggingModeIndicatorElmt;
+
+ indicatorElmt.style.left = (SimileAjax.WindowManager._ghostCoords.left - 16) + "px";
+ indicatorElmt.style.top = SimileAjax.WindowManager._ghostCoords.top + "px";
+ }
+
+ if ("droppable" in callback && callback.droppable) {
+ var coords = SimileAjax.DOM.getEventPageCoordinates(evt);
+ var target = SimileAjax.DOM.hittest(
+ coords.x, coords.y,
+ [ SimileAjax.WindowManager._ghostElmt,
+ SimileAjax.WindowManager._dropTargetHighlightElement
+ ]
+ );
+ target = SimileAjax.WindowManager._findDropTarget(target);
+
+ if (target != SimileAjax.WindowManager._potentialDropTarget) {
+ if (SimileAjax.WindowManager._dropTargetHighlightElement != null) {
+ document.body.removeChild(SimileAjax.WindowManager._dropTargetHighlightElement);
+
+ SimileAjax.WindowManager._dropTargetHighlightElement = null;
+ SimileAjax.WindowManager._potentialDropTarget = null;
+ }
+
+ var droppable = false;
+ if (target != null) {
+ if ((!("canDropOn" in callback) || callback.canDropOn(target)) &&
+ (!("canDrop" in target) || target.canDrop(SimileAjax.WindowManager._draggedElement))) {
+
+ droppable = true;
+ }
+ }
+
+ if (droppable) {
+ var border = 4;
+ var targetCoords = SimileAjax.DOM.getPageCoordinates(target);
+ var highlight = document.createElement("div");
+ highlight.style.border = border + "px solid yellow";
+ highlight.style.backgroundColor = "yellow";
+ highlight.style.position = "absolute";
+ highlight.style.left = targetCoords.left + "px";
+ highlight.style.top = targetCoords.top + "px";
+ highlight.style.width = (target.offsetWidth - border * 2) + "px";
+ highlight.style.height = (target.offsetHeight - border * 2) + "px";
+ SimileAjax.Graphics.setOpacity(highlight, 30);
+ document.body.appendChild(highlight);
+
+ SimileAjax.WindowManager._potentialDropTarget = target;
+ SimileAjax.WindowManager._dropTargetHighlightElement = highlight;
+ }
+ }
+ }
+ }
+ } catch (e) {
+ SimileAjax.Debug.exception("WindowManager: Error handling mouse move", e);
+ SimileAjax.WindowManager._cancelDragging();
+ }
+ }
+
+ SimileAjax.DOM.cancelEvent(evt);
+ return false;
+ }
+};
+
+SimileAjax.WindowManager._onBodyMouseUp = function(elmt, evt, target) {
+ if (SimileAjax.WindowManager._draggedElement != null) {
+ try {
+ if (SimileAjax.WindowManager._dragging) {
+ var callback = SimileAjax.WindowManager._draggedElementCallback;
+ if ("onDragEnd" in callback) {
+ callback.onDragEnd();
+ }
+ if ("droppable" in callback && callback.droppable) {
+ var dropped = false;
+
+ var target = SimileAjax.WindowManager._potentialDropTarget;
+ if (target != null) {
+ if ((!("canDropOn" in callback) || callback.canDropOn(target)) &&
+ (!("canDrop" in target) || target.canDrop(SimileAjax.WindowManager._draggedElement))) {
+
+ if ("onDropOn" in callback) {
+ callback.onDropOn(target);
+ }
+ target.ondrop(SimileAjax.WindowManager._draggedElement, SimileAjax.WindowManager._draggingMode);
+
+ dropped = true;
+ }
+ }
+
+ if (!dropped) {
+ // TODO: do holywood explosion here
+ }
+ }
+ }
+ } finally {
+ SimileAjax.WindowManager._cancelDragging();
+ }
+
+ SimileAjax.DOM.cancelEvent(evt);
+ return false;
+ }
+};
+
+SimileAjax.WindowManager._cancelDragging = function() {
+ var callback = SimileAjax.WindowManager._draggedElementCallback;
+ if ("_ghostElmt" in callback) {
+ var ghostElmt = callback._ghostElmt;
+ document.body.removeChild(ghostElmt);
+
+ delete callback._ghostElmt;
+ }
+ if (SimileAjax.WindowManager._dropTargetHighlightElement != null) {
+ document.body.removeChild(SimileAjax.WindowManager._dropTargetHighlightElement);
+ SimileAjax.WindowManager._dropTargetHighlightElement = null;
+ }
+ if (SimileAjax.WindowManager._draggingModeIndicatorElmt != null) {
+ document.body.removeChild(SimileAjax.WindowManager._draggingModeIndicatorElmt);
+ SimileAjax.WindowManager._draggingModeIndicatorElmt = null;
+ }
+
+ SimileAjax.WindowManager._draggedElement = null;
+ SimileAjax.WindowManager._draggedElementCallback = null;
+ SimileAjax.WindowManager._potentialDropTarget = null;
+ SimileAjax.WindowManager._dropTargetHighlightElement = null;
+ SimileAjax.WindowManager._lastCoords = null;
+ SimileAjax.WindowManager._ghostCoords = null;
+ SimileAjax.WindowManager._draggingMode = "";
+ SimileAjax.WindowManager._dragging = false;
+};
+
+SimileAjax.WindowManager._findDropTarget = function(elmt) {
+ while (elmt != null) {
+ if ("ondrop" in elmt && (typeof elmt.ondrop) == "function") {
+ break;
+ }
+ elmt = elmt.parentNode;
+ }
+ return elmt;
+};
diff --git a/site/app/webroot/js/simile/ajax/scripts/xmlhttp.js b/site/app/webroot/js/simile/ajax/scripts/xmlhttp.js
new file mode 100755
index 0000000..b6d2c0a
--- /dev/null
+++ b/site/app/webroot/js/simile/ajax/scripts/xmlhttp.js
@@ -0,0 +1,137 @@
+/**
+ * @fileOverview XmlHttp utility functions
+ * @name SimileAjax.XmlHttp
+ */
+
+SimileAjax.XmlHttp = new Object();
+
+/**
+ * Callback for XMLHttp onRequestStateChange.
+ */
+SimileAjax.XmlHttp._onReadyStateChange = function(xmlhttp, fError, fDone) {
+ switch (xmlhttp.readyState) {
+ // 1: Request not yet made
+ // 2: Contact established with server but nothing downloaded yet
+ // 3: Called multiple while downloading in progress
+
+ // Download complete
+ case 4:
+ try {
+ if (xmlhttp.status == 0 // file:// urls, works on Firefox
+ || xmlhttp.status == 200 // http:// urls
+ ) {
+ if (fDone) {
+ fDone(xmlhttp);
+ }
+ } else {
+ if (fError) {
+ fError(
+ xmlhttp.statusText,
+ xmlhttp.status,
+ xmlhttp
+ );
+ }
+ }
+ } catch (e) {
+ SimileAjax.Debug.exception("XmlHttp: Error handling onReadyStateChange", e);
+ }
+ break;
+ }
+};
+
+/**
+ * Creates an XMLHttpRequest object. On the first run, this
+ * function creates a platform-specific function for
+ * instantiating an XMLHttpRequest object and then replaces
+ * itself with that function.
+ */
+SimileAjax.XmlHttp._createRequest = function() {
+ if (SimileAjax.Platform.browser.isIE) {
+ var programIDs = [
+ "Msxml2.XMLHTTP",
+ "Microsoft.XMLHTTP",
+ "Msxml2.XMLHTTP.4.0"
+ ];
+ for (var i = 0; i < programIDs.length; i++) {
+ try {
+ var programID = programIDs[i];
+ var f = function() {
+ return new ActiveXObject(programID);
+ };
+ var o = f();
+
+ // We are replacing the SimileAjax._createXmlHttpRequest
+ // function with this inner function as we've
+ // found out that it works. This is so that we
+ // don't have to do all the testing over again
+ // on subsequent calls.
+ SimileAjax.XmlHttp._createRequest = f;
+
+ return o;
+ } catch (e) {
+ // silent
+ }
+ }
+ // fall through to try new XMLHttpRequest();
+ }
+
+ try {
+ var f = function() {
+ return new XMLHttpRequest();
+ };
+ var o = f();
+
+ // We are replacing the SimileAjax._createXmlHttpRequest
+ // function with this inner function as we've
+ // found out that it works. This is so that we
+ // don't have to do all the testing over again
+ // on subsequent calls.
+ SimileAjax.XmlHttp._createRequest = f;
+
+ return o;
+ } catch (e) {
+ throw new Error("Failed to create an XMLHttpRequest object");
+ }
+};
+
+/**
+ * Performs an asynchronous HTTP GET.
+ *
+ * @param {Function} fError a function of the form
+ function(statusText, statusCode, xmlhttp)
+ * @param {Function} fDone a function of the form function(xmlhttp)
+ */
+SimileAjax.XmlHttp.get = function(url, fError, fDone) {
+ var xmlhttp = SimileAjax.XmlHttp._createRequest();
+
+ xmlhttp.open("GET", url, true);
+ xmlhttp.onreadystatechange = function() {
+ SimileAjax.XmlHttp._onReadyStateChange(xmlhttp, fError, fDone);
+ };
+ xmlhttp.send(null);
+};
+
+/**
+ * Performs an asynchronous HTTP POST.
+ *
+ * @param {Function} fError a function of the form
+ function(statusText, statusCode, xmlhttp)
+ * @param {Function} fDone a function of the form function(xmlhttp)
+ */
+SimileAjax.XmlHttp.post = function(url, body, fError, fDone) {
+ var xmlhttp = SimileAjax.XmlHttp._createRequest();
+
+ xmlhttp.open("POST", url, true);
+ xmlhttp.onreadystatechange = function() {
+ SimileAjax.XmlHttp._onReadyStateChange(xmlhttp, fError, fDone);
+ };
+ xmlhttp.send(body);
+};
+
+SimileAjax.XmlHttp._forceXML = function(xmlhttp) {
+ try {
+ xmlhttp.overrideMimeType("text/xml");
+ } catch (e) {
+ xmlhttp.setrequestheader("Content-Type", "text/xml");
+ }
+}; \ No newline at end of file
diff --git a/site/app/webroot/js/simile/ajax/simile-ajax-api.js b/site/app/webroot/js/simile/ajax/simile-ajax-api.js
new file mode 100755
index 0000000..188e17e
--- /dev/null
+++ b/site/app/webroot/js/simile/ajax/simile-ajax-api.js
@@ -0,0 +1,211 @@
+/*==================================================
+ * Simile Ajax API
+ *
+ * Include this file in your HTML file as follows:
+ *
+ * <script src="http://simile.mit.edu/ajax/api/simile-ajax-api.js" type="text/javascript"></script>
+ *
+ *==================================================
+ */
+
+if (typeof SimileAjax == "undefined") {
+ var SimileAjax = {
+ loaded: false,
+ loadingScriptsCount: 0,
+ error: null,
+ params: { bundle:"true" }
+ };
+
+ SimileAjax.Platform = new Object();
+ /*
+ HACK: We need these 2 things here because we cannot simply append
+ a <script> element containing code that accesses SimileAjax.Platform
+ to initialize it because IE executes that <script> code first
+ before it loads ajax.js and platform.js.
+ */
+
+ var getHead = function(doc) {
+ return doc.getElementsByTagName("head")[0];
+ };
+
+ SimileAjax.findScript = function(doc, substring) {
+ var heads = doc.documentElement.getElementsByTagName("head");
+ for (var h = 0; h < heads.length; h++) {
+ var node = heads[h].firstChild;
+ while (node != null) {
+ if (node.nodeType == 1 && node.tagName.toLowerCase() == "script") {
+ var url = node.src;
+ var i = url.indexOf(substring);
+ if (i >= 0) {
+ return url;
+ }
+ }
+ node = node.nextSibling;
+ }
+ }
+ return null;
+ };
+ SimileAjax.includeJavascriptFile = function(doc, url, onerror, charset) {
+ onerror = onerror || "";
+ if (doc.body == null) {
+ try {
+ var q = "'" + onerror.replace( /'/g, '&apos' ) + "'"; // "
+ doc.write("<script src='" + url + "' onerror="+ q +
+ (charset ? " charset='"+ charset +"'" : "") +
+ " type='text/javascript'>"+ onerror + "</script>");
+ return;
+ } catch (e) {
+ // fall through
+ }
+ }
+
+ var script = doc.createElement("script");
+ if (onerror) {
+ try { script.innerHTML = onerror; } catch(e) {}
+ script.setAttribute("onerror", onerror);
+ }
+ if (charset) {
+ script.setAttribute("charset", charset);
+ }
+ script.type = "text/javascript";
+ script.language = "JavaScript";
+ script.src = url;
+ return getHead(doc).appendChild(script);
+ };
+ SimileAjax.includeJavascriptFiles = function(doc, urlPrefix, filenames) {
+ for (var i = 0; i < filenames.length; i++) {
+ SimileAjax.includeJavascriptFile(doc, urlPrefix + filenames[i]);
+ }
+ SimileAjax.loadingScriptsCount += filenames.length;
+ SimileAjax.includeJavascriptFile(doc, SimileAjax.urlPrefix + "scripts/signal.js?" + filenames.length);
+ };
+ SimileAjax.includeCssFile = function(doc, url) {
+ if (doc.body == null) {
+ try {
+ doc.write("<link rel='stylesheet' href='" + url + "' type='text/css'/>");
+ return;
+ } catch (e) {
+ // fall through
+ }
+ }
+
+ var link = doc.createElement("link");
+ link.setAttribute("rel", "stylesheet");
+ link.setAttribute("type", "text/css");
+ link.setAttribute("href", url);
+ getHead(doc).appendChild(link);
+ };
+ SimileAjax.includeCssFiles = function(doc, urlPrefix, filenames) {
+ for (var i = 0; i < filenames.length; i++) {
+ SimileAjax.includeCssFile(doc, urlPrefix + filenames[i]);
+ }
+ };
+
+ /**
+ * Append into urls each string in suffixes after prefixing it with urlPrefix.
+ * @param {Array} urls
+ * @param {String} urlPrefix
+ * @param {Array} suffixes
+ */
+ SimileAjax.prefixURLs = function(urls, urlPrefix, suffixes) {
+ for (var i = 0; i < suffixes.length; i++) {
+ urls.push(urlPrefix + suffixes[i]);
+ }
+ };
+
+ /**
+ * Parse out the query parameters from a URL
+ * @param {String} url the url to parse, or location.href if undefined
+ * @param {Object} to optional object to extend with the parameters
+ * @param {Object} types optional object mapping keys to value types
+ * (String, Number, Boolean or Array, String by default)
+ * @return a key/value Object whose keys are the query parameter names
+ * @type Object
+ */
+ SimileAjax.parseURLParameters = function(url, to, types) {
+ to = to || {};
+ types = types || {};
+
+ if (typeof url == "undefined") {
+ url = location.href;
+ }
+ var q = url.indexOf("?");
+ if (q < 0) {
+ return to;
+ }
+ url = (url+"#").slice(q+1, url.indexOf("#")); // toss the URL fragment
+
+ var params = url.split("&"), param, parsed = {};
+ var decode = window.decodeURIComponent || unescape;
+ for (var i = 0; param = params[i]; i++) {
+ var eq = param.indexOf("=");
+ var name = decode(param.slice(0,eq));
+ var old = parsed[name];
+ if (typeof old == "undefined") {
+ old = [];
+ } else if (!(old instanceof Array)) {
+ old = [old];
+ }
+ parsed[name] = old.concat(decode(param.slice(eq+1)));
+ }
+ for (var i in parsed) {
+ if (!parsed.hasOwnProperty(i)) continue;
+ var type = types[i] || String;
+ var data = parsed[i];
+ if (!(data instanceof Array)) {
+ data = [data];
+ }
+ if (type === Boolean && data[0] == "false") {
+ to[i] = false; // because Boolean("false") === true
+ } else {
+ to[i] = type.apply(this, data);
+ }
+ }
+ return to;
+ };
+
+ (function() {
+ var javascriptFiles = [
+ "jquery-1.2.1.js",
+ "platform.js",
+ "debug.js",
+ "xmlhttp.js",
+ "json.js",
+ "dom.js",
+ "graphics.js",
+ "date-time.js",
+ "string.js",
+ "html.js",
+ "data-structure.js",
+ "units.js",
+
+ "ajax.js",
+ "history.js",
+ "window-manager.js"
+ ];
+ var cssFiles = [
+ ];
+
+ if (typeof SimileAjax_urlPrefix == "string") {
+ SimileAjax.urlPrefix = SimileAjax_urlPrefix;
+ } else {
+ var url = SimileAjax.findScript(document, "simile-ajax-api.js");
+ if (url == null) {
+ SimileAjax.error = new Error("Failed to derive URL prefix for Simile Ajax API code files");
+ return;
+ }
+
+ SimileAjax.urlPrefix = url.substr(0, url.indexOf("simile-ajax-api.js"));
+ }
+
+ SimileAjax.parseURLParameters(url, SimileAjax.params, {bundle:Boolean});
+ if (SimileAjax.params.bundle) {
+ SimileAjax.includeJavascriptFiles(document, SimileAjax.urlPrefix, [ "simile-ajax-bundle.js" ]);
+ } else {
+ SimileAjax.includeJavascriptFiles(document, SimileAjax.urlPrefix + "scripts/", javascriptFiles);
+ }
+ SimileAjax.includeCssFiles(document, SimileAjax.urlPrefix + "styles/", cssFiles);
+
+ SimileAjax.loaded = true;
+ })();
+}
diff --git a/site/app/webroot/js/simile/ajax/simile-ajax-bundle.js b/site/app/webroot/js/simile/ajax/simile-ajax-bundle.js
new file mode 100755
index 0000000..3374e4e
--- /dev/null
+++ b/site/app/webroot/js/simile/ajax/simile-ajax-bundle.js
@@ -0,0 +1,2464 @@
+
+
+/* platform.js */
+SimileAjax.Platform.os={isMac:false,isWin:false,isWin32:false,isUnix:false};
+SimileAjax.Platform.browser={isIE:false,isNetscape:false,isMozilla:false,isFirefox:false,isOpera:false,isSafari:false,majorVersion:0,minorVersion:0};
+(function(){var C=navigator.appName.toLowerCase();
+var A=navigator.userAgent.toLowerCase();
+SimileAjax.Platform.os.isMac=(A.indexOf("mac")!=-1);
+SimileAjax.Platform.os.isWin=(A.indexOf("win")!=-1);
+SimileAjax.Platform.os.isWin32=SimileAjax.Platform.isWin&&(A.indexOf("95")!=-1||A.indexOf("98")!=-1||A.indexOf("nt")!=-1||A.indexOf("win32")!=-1||A.indexOf("32bit")!=-1);
+SimileAjax.Platform.os.isUnix=(A.indexOf("x11")!=-1);
+SimileAjax.Platform.browser.isIE=(C.indexOf("microsoft")!=-1);
+SimileAjax.Platform.browser.isNetscape=(C.indexOf("netscape")!=-1);
+SimileAjax.Platform.browser.isMozilla=(A.indexOf("mozilla")!=-1);
+SimileAjax.Platform.browser.isFirefox=(A.indexOf("firefox")!=-1);
+SimileAjax.Platform.browser.isOpera=(C.indexOf("opera")!=-1);
+SimileAjax.Platform.browser.isSafari=(C.indexOf("safari")!=-1);
+var E=function(G){var F=G.split(".");
+SimileAjax.Platform.browser.majorVersion=parseInt(F[0]);
+SimileAjax.Platform.browser.minorVersion=parseInt(F[1]);
+};
+var B=function(H,G,I){var F=H.indexOf(G,I);
+return F>=0?F:H.length;
+};
+if(SimileAjax.Platform.browser.isMozilla){var D=A.indexOf("mozilla/");
+if(D>=0){E(A.substring(D+8,B(A," ",D)));
+}}if(SimileAjax.Platform.browser.isIE){var D=A.indexOf("msie ");
+if(D>=0){E(A.substring(D+5,B(A,";",D)));
+}}if(SimileAjax.Platform.browser.isNetscape){var D=A.indexOf("rv:");
+if(D>=0){E(A.substring(D+3,B(A,")",D)));
+}}if(SimileAjax.Platform.browser.isFirefox){var D=A.indexOf("firefox/");
+if(D>=0){E(A.substring(D+8,B(A," ",D)));
+}}if(!("localeCompare" in String.prototype)){String.prototype.localeCompare=function(F){if(this<F){return -1;
+}else{if(this>F){return 1;
+}else{return 0;
+}}};
+}})();
+SimileAjax.Platform.getDefaultLocale=function(){return SimileAjax.Platform.clientLocale;
+};
+
+
+/* ajax.js */
+SimileAjax.ListenerQueue=function(A){this._listeners=[];
+this._wildcardHandlerName=A;
+};
+SimileAjax.ListenerQueue.prototype.add=function(A){this._listeners.push(A);
+};
+SimileAjax.ListenerQueue.prototype.remove=function(C){var B=this._listeners;
+for(var A=0;
+A<B.length;
+A++){if(B[A]==C){B.splice(A,1);
+break;
+}}};
+SimileAjax.ListenerQueue.prototype.fire=function(B,A){var D=[].concat(this._listeners);
+for(var C=0;
+C<D.length;
+C++){var E=D[C];
+if(B in E){try{E[B].apply(E,A);
+}catch(F){SimileAjax.Debug.exception("Error firing event of name "+B,F);
+}}else{if(this._wildcardHandlerName!=null&&this._wildcardHandlerName in E){try{E[this._wildcardHandlerName].apply(E,[B]);
+}catch(F){SimileAjax.Debug.exception("Error firing event of name "+B+" to wildcard handler",F);
+}}}}};
+
+
+/* data-structure.js */
+SimileAjax.Set=function(A){this._hash={};
+this._count=0;
+if(A instanceof Array){for(var B=0;
+B<A.length;
+B++){this.add(A[B]);
+}}else{if(A instanceof SimileAjax.Set){this.addSet(A);
+}}};
+SimileAjax.Set.prototype.add=function(A){if(!(A in this._hash)){this._hash[A]=true;
+this._count++;
+return true;
+}return false;
+};
+SimileAjax.Set.prototype.addSet=function(B){for(var A in B._hash){this.add(A);
+}};
+SimileAjax.Set.prototype.remove=function(A){if(A in this._hash){delete this._hash[A];
+this._count--;
+return true;
+}return false;
+};
+SimileAjax.Set.prototype.removeSet=function(B){for(var A in B._hash){this.remove(A);
+}};
+SimileAjax.Set.prototype.retainSet=function(B){for(var A in this._hash){if(!B.contains(A)){delete this._hash[A];
+this._count--;
+}}};
+SimileAjax.Set.prototype.contains=function(A){return(A in this._hash);
+};
+SimileAjax.Set.prototype.size=function(){return this._count;
+};
+SimileAjax.Set.prototype.toArray=function(){var A=[];
+for(var B in this._hash){A.push(B);
+}return A;
+};
+SimileAjax.Set.prototype.visit=function(A){for(var B in this._hash){if(A(B)==true){break;
+}}};
+SimileAjax.SortedArray=function(B,A){this._a=(A instanceof Array)?A:[];
+this._compare=B;
+};
+SimileAjax.SortedArray.prototype.add=function(C){var A=this;
+var B=this.find(function(D){return A._compare(D,C);
+});
+if(B<this._a.length){this._a.splice(B,0,C);
+}else{this._a.push(C);
+}};
+SimileAjax.SortedArray.prototype.remove=function(C){var A=this;
+var B=this.find(function(D){return A._compare(D,C);
+});
+while(B<this._a.length&&this._compare(this._a[B],C)==0){if(this._a[B]==C){this._a.splice(B,1);
+return true;
+}else{B++;
+}}return false;
+};
+SimileAjax.SortedArray.prototype.removeAll=function(){this._a=[];
+};
+SimileAjax.SortedArray.prototype.elementAt=function(A){return this._a[A];
+};
+SimileAjax.SortedArray.prototype.length=function(){return this._a.length;
+};
+SimileAjax.SortedArray.prototype.find=function(D){var B=0;
+var A=this._a.length;
+while(B<A){var C=Math.floor((B+A)/2);
+var E=D(this._a[C]);
+if(C==B){return E<0?B+1:B;
+}else{if(E<0){B=C;
+}else{A=C;
+}}}return B;
+};
+SimileAjax.SortedArray.prototype.getFirst=function(){return(this._a.length>0)?this._a[0]:null;
+};
+SimileAjax.SortedArray.prototype.getLast=function(){return(this._a.length>0)?this._a[this._a.length-1]:null;
+};
+SimileAjax.EventIndex=function(B){var A=this;
+this._unit=(B!=null)?B:SimileAjax.NativeDateUnit;
+this._events=new SimileAjax.SortedArray(function(D,C){return A._unit.compare(D.getStart(),C.getStart());
+});
+this._idToEvent={};
+this._indexed=true;
+};
+SimileAjax.EventIndex.prototype.getUnit=function(){return this._unit;
+};
+SimileAjax.EventIndex.prototype.getEvent=function(A){return this._idToEvent[A];
+};
+SimileAjax.EventIndex.prototype.add=function(A){this._events.add(A);
+this._idToEvent[A.getID()]=A;
+this._indexed=false;
+};
+SimileAjax.EventIndex.prototype.removeAll=function(){this._events.removeAll();
+this._idToEvent={};
+this._indexed=false;
+};
+SimileAjax.EventIndex.prototype.getCount=function(){return this._events.length();
+};
+SimileAjax.EventIndex.prototype.getIterator=function(A,B){if(!this._indexed){this._index();
+}return new SimileAjax.EventIndex._Iterator(this._events,A,B,this._unit);
+};
+SimileAjax.EventIndex.prototype.getReverseIterator=function(A,B){if(!this._indexed){this._index();
+}return new SimileAjax.EventIndex._ReverseIterator(this._events,A,B,this._unit);
+};
+SimileAjax.EventIndex.prototype.getAllIterator=function(){return new SimileAjax.EventIndex._AllIterator(this._events);
+};
+SimileAjax.EventIndex.prototype.getEarliestDate=function(){var A=this._events.getFirst();
+return(A==null)?null:A.getStart();
+};
+SimileAjax.EventIndex.prototype.getLatestDate=function(){var A=this._events.getLast();
+if(A==null){return null;
+}if(!this._indexed){this._index();
+}var C=A._earliestOverlapIndex;
+var B=this._events.elementAt(C).getEnd();
+for(var D=C+1;
+D<this._events.length();
+D++){B=this._unit.later(B,this._events.elementAt(D).getEnd());
+}return B;
+};
+SimileAjax.EventIndex.prototype._index=function(){var D=this._events.length();
+for(var E=0;
+E<D;
+E++){var C=this._events.elementAt(E);
+C._earliestOverlapIndex=E;
+}var G=1;
+for(var E=0;
+E<D;
+E++){var C=this._events.elementAt(E);
+var B=C.getEnd();
+G=Math.max(G,E+1);
+while(G<D){var A=this._events.elementAt(G);
+var F=A.getStart();
+if(this._unit.compare(F,B)<0){A._earliestOverlapIndex=E;
+G++;
+}else{break;
+}}}this._indexed=true;
+};
+SimileAjax.EventIndex._Iterator=function(B,A,D,C){this._events=B;
+this._startDate=A;
+this._endDate=D;
+this._unit=C;
+this._currentIndex=B.find(function(E){return C.compare(E.getStart(),A);
+});
+if(this._currentIndex-1>=0){this._currentIndex=this._events.elementAt(this._currentIndex-1)._earliestOverlapIndex;
+}this._currentIndex--;
+this._maxIndex=B.find(function(E){return C.compare(E.getStart(),D);
+});
+this._hasNext=false;
+this._next=null;
+this._findNext();
+};
+SimileAjax.EventIndex._Iterator.prototype={hasNext:function(){return this._hasNext;
+},next:function(){if(this._hasNext){var A=this._next;
+this._findNext();
+return A;
+}else{return null;
+}},_findNext:function(){var B=this._unit;
+while((++this._currentIndex)<this._maxIndex){var A=this._events.elementAt(this._currentIndex);
+if(B.compare(A.getStart(),this._endDate)<0&&B.compare(A.getEnd(),this._startDate)>0){this._next=A;
+this._hasNext=true;
+return ;
+}}this._next=null;
+this._hasNext=false;
+}};
+SimileAjax.EventIndex._ReverseIterator=function(B,A,D,C){this._events=B;
+this._startDate=A;
+this._endDate=D;
+this._unit=C;
+this._minIndex=B.find(function(E){return C.compare(E.getStart(),A);
+});
+if(this._minIndex-1>=0){this._minIndex=this._events.elementAt(this._minIndex-1)._earliestOverlapIndex;
+}this._maxIndex=B.find(function(E){return C.compare(E.getStart(),D);
+});
+this._currentIndex=this._maxIndex;
+this._hasNext=false;
+this._next=null;
+this._findNext();
+};
+SimileAjax.EventIndex._ReverseIterator.prototype={hasNext:function(){return this._hasNext;
+},next:function(){if(this._hasNext){var A=this._next;
+this._findNext();
+return A;
+}else{return null;
+}},_findNext:function(){var B=this._unit;
+while((--this._currentIndex)>=this._minIndex){var A=this._events.elementAt(this._currentIndex);
+if(B.compare(A.getStart(),this._endDate)<0&&B.compare(A.getEnd(),this._startDate)>0){this._next=A;
+this._hasNext=true;
+return ;
+}}this._next=null;
+this._hasNext=false;
+}};
+SimileAjax.EventIndex._AllIterator=function(A){this._events=A;
+this._index=0;
+};
+SimileAjax.EventIndex._AllIterator.prototype={hasNext:function(){return this._index<this._events.length();
+},next:function(){return this._index<this._events.length()?this._events.elementAt(this._index++):null;
+}};
+
+
+/* date-time.js */
+SimileAjax.DateTime=new Object();
+SimileAjax.DateTime.MILLISECOND=0;
+SimileAjax.DateTime.SECOND=1;
+SimileAjax.DateTime.MINUTE=2;
+SimileAjax.DateTime.HOUR=3;
+SimileAjax.DateTime.DAY=4;
+SimileAjax.DateTime.WEEK=5;
+SimileAjax.DateTime.MONTH=6;
+SimileAjax.DateTime.YEAR=7;
+SimileAjax.DateTime.DECADE=8;
+SimileAjax.DateTime.CENTURY=9;
+SimileAjax.DateTime.MILLENNIUM=10;
+SimileAjax.DateTime.EPOCH=-1;
+SimileAjax.DateTime.ERA=-2;
+SimileAjax.DateTime.gregorianUnitLengths=[];
+(function(){var B=SimileAjax.DateTime;
+var A=B.gregorianUnitLengths;
+A[B.MILLISECOND]=1;
+A[B.SECOND]=1000;
+A[B.MINUTE]=A[B.SECOND]*60;
+A[B.HOUR]=A[B.MINUTE]*60;
+A[B.DAY]=A[B.HOUR]*24;
+A[B.WEEK]=A[B.DAY]*7;
+A[B.MONTH]=A[B.DAY]*31;
+A[B.YEAR]=A[B.DAY]*365;
+A[B.DECADE]=A[B.YEAR]*10;
+A[B.CENTURY]=A[B.YEAR]*100;
+A[B.MILLENNIUM]=A[B.YEAR]*1000;
+})();
+SimileAjax.DateTime._dateRegexp=new RegExp("^(-?)([0-9]{4})("+["(-?([0-9]{2})(-?([0-9]{2}))?)","(-?([0-9]{3}))","(-?W([0-9]{2})(-?([1-7]))?)"].join("|")+")?$");
+SimileAjax.DateTime._timezoneRegexp=new RegExp("Z|(([-+])([0-9]{2})(:?([0-9]{2}))?)$");
+SimileAjax.DateTime._timeRegexp=new RegExp("^([0-9]{2})(:?([0-9]{2})(:?([0-9]{2})(.([0-9]+))?)?)?$");
+SimileAjax.DateTime.setIso8601Date=function(H,F){var I=F.match(SimileAjax.DateTime._dateRegexp);
+if(!I){throw new Error("Invalid date string: "+F);
+}var B=(I[1]=="-")?-1:1;
+var J=B*I[2];
+var G=I[5];
+var C=I[7];
+var E=I[9];
+var A=I[11];
+var M=(I[13])?I[13]:1;
+H.setUTCFullYear(J);
+if(E){H.setUTCMonth(0);
+H.setUTCDate(Number(E));
+}else{if(A){H.setUTCMonth(0);
+H.setUTCDate(1);
+var L=H.getUTCDay();
+var K=(L)?L:7;
+var D=Number(M)+(7*Number(A));
+if(K<=4){H.setUTCDate(D+1-K);
+}else{H.setUTCDate(D+8-K);
+}}else{if(G){H.setUTCDate(1);
+H.setUTCMonth(G-1);
+}if(C){H.setUTCDate(C);
+}}}return H;
+};
+SimileAjax.DateTime.setIso8601Time=function(F,C){var G=C.match(SimileAjax.DateTime._timeRegexp);
+if(!G){SimileAjax.Debug.warn("Invalid time string: "+C);
+return false;
+}var A=G[1];
+var E=Number((G[3])?G[3]:0);
+var D=(G[5])?G[5]:0;
+var B=G[7]?(Number("0."+G[7])*1000):0;
+F.setUTCHours(A);
+F.setUTCMinutes(E);
+F.setUTCSeconds(D);
+F.setUTCMilliseconds(B);
+return F;
+};
+SimileAjax.DateTime.timezoneOffset=new Date().getTimezoneOffset();
+SimileAjax.DateTime.setIso8601=function(B,A){var D=null;
+var E=(A.indexOf("T")==-1)?A.split(" "):A.split("T");
+SimileAjax.DateTime.setIso8601Date(B,E[0]);
+if(E.length==2){var C=E[1].match(SimileAjax.DateTime._timezoneRegexp);
+if(C){if(C[0]=="Z"){D=0;
+}else{D=(Number(C[3])*60)+Number(C[5]);
+D*=((C[2]=="-")?1:-1);
+}E[1]=E[1].substr(0,E[1].length-C[0].length);
+}SimileAjax.DateTime.setIso8601Time(B,E[1]);
+}if(D==null){D=B.getTimezoneOffset();
+}B.setTime(B.getTime()+D*60000);
+return B;
+};
+SimileAjax.DateTime.parseIso8601DateTime=function(A){try{return SimileAjax.DateTime.setIso8601(new Date(0),A);
+}catch(B){return null;
+}};
+SimileAjax.DateTime.parseGregorianDateTime=function(G){if(G==null){return null;
+}else{if(G instanceof Date){return G;
+}}var B=G.toString();
+if(B.length>0&&B.length<8){var C=B.indexOf(" ");
+if(C>0){var A=parseInt(B.substr(0,C));
+var E=B.substr(C+1);
+if(E.toLowerCase()=="bc"){A=1-A;
+}}else{var A=parseInt(B);
+}var F=new Date(0);
+F.setUTCFullYear(A);
+return F;
+}try{return new Date(Date.parse(B));
+}catch(D){return null;
+}};
+SimileAjax.DateTime.roundDownToInterval=function(B,G,J,K,A){var D=J*SimileAjax.DateTime.gregorianUnitLengths[SimileAjax.DateTime.HOUR];
+var I=new Date(B.getTime()+D);
+var E=function(L){L.setUTCMilliseconds(0);
+L.setUTCSeconds(0);
+L.setUTCMinutes(0);
+L.setUTCHours(0);
+};
+var C=function(L){E(L);
+L.setUTCDate(1);
+L.setUTCMonth(0);
+};
+switch(G){case SimileAjax.DateTime.MILLISECOND:var H=I.getUTCMilliseconds();
+I.setUTCMilliseconds(H-(H%K));
+break;
+case SimileAjax.DateTime.SECOND:I.setUTCMilliseconds(0);
+var H=I.getUTCSeconds();
+I.setUTCSeconds(H-(H%K));
+break;
+case SimileAjax.DateTime.MINUTE:I.setUTCMilliseconds(0);
+I.setUTCSeconds(0);
+var H=I.getUTCMinutes();
+I.setTime(I.getTime()-(H%K)*SimileAjax.DateTime.gregorianUnitLengths[SimileAjax.DateTime.MINUTE]);
+break;
+case SimileAjax.DateTime.HOUR:I.setUTCMilliseconds(0);
+I.setUTCSeconds(0);
+I.setUTCMinutes(0);
+var H=I.getUTCHours();
+I.setUTCHours(H-(H%K));
+break;
+case SimileAjax.DateTime.DAY:E(I);
+break;
+case SimileAjax.DateTime.WEEK:E(I);
+var F=(I.getUTCDay()+7-A)%7;
+I.setTime(I.getTime()-F*SimileAjax.DateTime.gregorianUnitLengths[SimileAjax.DateTime.DAY]);
+break;
+case SimileAjax.DateTime.MONTH:E(I);
+I.setUTCDate(1);
+var H=I.getUTCMonth();
+I.setUTCMonth(H-(H%K));
+break;
+case SimileAjax.DateTime.YEAR:C(I);
+var H=I.getUTCFullYear();
+I.setUTCFullYear(H-(H%K));
+break;
+case SimileAjax.DateTime.DECADE:C(I);
+I.setUTCFullYear(Math.floor(I.getUTCFullYear()/10)*10);
+break;
+case SimileAjax.DateTime.CENTURY:C(I);
+I.setUTCFullYear(Math.floor(I.getUTCFullYear()/100)*100);
+break;
+case SimileAjax.DateTime.MILLENNIUM:C(I);
+I.setUTCFullYear(Math.floor(I.getUTCFullYear()/1000)*1000);
+break;
+}B.setTime(I.getTime()-D);
+};
+SimileAjax.DateTime.roundUpToInterval=function(D,F,C,A,B){var E=D.getTime();
+SimileAjax.DateTime.roundDownToInterval(D,F,C,A,B);
+if(D.getTime()<E){D.setTime(D.getTime()+SimileAjax.DateTime.gregorianUnitLengths[F]*A);
+}};
+SimileAjax.DateTime.incrementByInterval=function(B,E,A){A=(typeof A=="undefined")?0:A;
+var D=A*SimileAjax.DateTime.gregorianUnitLengths[SimileAjax.DateTime.HOUR];
+var C=new Date(B.getTime()+D);
+switch(E){case SimileAjax.DateTime.MILLISECOND:C.setTime(C.getTime()+1);
+break;
+case SimileAjax.DateTime.SECOND:C.setTime(C.getTime()+1000);
+break;
+case SimileAjax.DateTime.MINUTE:C.setTime(C.getTime()+SimileAjax.DateTime.gregorianUnitLengths[SimileAjax.DateTime.MINUTE]);
+break;
+case SimileAjax.DateTime.HOUR:C.setTime(C.getTime()+SimileAjax.DateTime.gregorianUnitLengths[SimileAjax.DateTime.HOUR]);
+break;
+case SimileAjax.DateTime.DAY:C.setUTCDate(C.getUTCDate()+1);
+break;
+case SimileAjax.DateTime.WEEK:C.setUTCDate(C.getUTCDate()+7);
+break;
+case SimileAjax.DateTime.MONTH:C.setUTCMonth(C.getUTCMonth()+1);
+break;
+case SimileAjax.DateTime.YEAR:C.setUTCFullYear(C.getUTCFullYear()+1);
+break;
+case SimileAjax.DateTime.DECADE:C.setUTCFullYear(C.getUTCFullYear()+10);
+break;
+case SimileAjax.DateTime.CENTURY:C.setUTCFullYear(C.getUTCFullYear()+100);
+break;
+case SimileAjax.DateTime.MILLENNIUM:C.setUTCFullYear(C.getUTCFullYear()+1000);
+break;
+}B.setTime(C.getTime()-D);
+};
+SimileAjax.DateTime.removeTimeZoneOffset=function(B,A){return new Date(B.getTime()+A*SimileAjax.DateTime.gregorianUnitLengths[SimileAjax.DateTime.HOUR]);
+};
+SimileAjax.DateTime.getTimezone=function(){var A=new Date().getTimezoneOffset();
+return A/-60;
+};
+
+
+/* debug.js */
+SimileAjax.Debug={silent:false};
+SimileAjax.Debug.log=function(B){var A;
+if("console" in window&&"log" in window.console){A=function(C){console.log(C);
+};
+}else{A=function(C){if(!SimileAjax.Debug.silent){alert(C);
+}};
+}SimileAjax.Debug.log=A;
+A(B);
+};
+SimileAjax.Debug.warn=function(B){var A;
+if("console" in window&&"warn" in window.console){A=function(C){console.warn(C);
+};
+}else{A=function(C){if(!SimileAjax.Debug.silent){alert(C);
+}};
+}SimileAjax.Debug.warn=A;
+A(B);
+};
+SimileAjax.Debug.exception=function(B,D){var A,C=SimileAjax.parseURLParameters();
+if(C.errors=="throw"||SimileAjax.params.errors=="throw"){A=function(F,E){throw (F);
+};
+}else{if("console" in window&&"error" in window.console){A=function(F,E){if(E!=null){console.error(E+" %o",F);
+}else{console.error(F);
+}throw (F);
+};
+}else{A=function(F,E){if(!SimileAjax.Debug.silent){alert("Caught exception: "+E+"\n\nDetails: "+("description" in F?F.description:F));
+}throw (F);
+};
+}}SimileAjax.Debug.exception=A;
+A(B,D);
+};
+SimileAjax.Debug.objectToString=function(A){return SimileAjax.Debug._objectToString(A,"");
+};
+SimileAjax.Debug._objectToString=function(D,A){var C=A+" ";
+if(typeof D=="object"){var B="{";
+for(E in D){B+=C+E+": "+SimileAjax.Debug._objectToString(D[E],C)+"\n";
+}B+=A+"}";
+return B;
+}else{if(typeof D=="array"){var B="[";
+for(var E=0;
+E<D.length;
+E++){B+=SimileAjax.Debug._objectToString(D[E],C)+"\n";
+}B+=A+"]";
+return B;
+}else{return D;
+}}};
+
+
+/* dom.js */
+SimileAjax.DOM=new Object();
+SimileAjax.DOM.registerEventWithObject=function(C,A,D,B){SimileAjax.DOM.registerEvent(C,A,function(F,E,G){return D[B].call(D,F,E,G);
+});
+};
+SimileAjax.DOM.registerEvent=function(C,B,D){var A=function(E){E=(E)?E:((event)?event:null);
+if(E){var F=(E.target)?E.target:((E.srcElement)?E.srcElement:null);
+if(F){F=(F.nodeType==1||F.nodeType==9)?F:F.parentNode;
+}return D(C,E,F);
+}return true;
+};
+if(SimileAjax.Platform.browser.isIE){C.attachEvent("on"+B,A);
+}else{C.addEventListener(B,A,false);
+}};
+SimileAjax.DOM.getPageCoordinates=function(B){var E=0;
+var D=0;
+if(B.nodeType!=1){B=B.parentNode;
+}var C=B;
+while(C!=null){E+=C.offsetLeft;
+D+=C.offsetTop;
+C=C.offsetParent;
+}var A=document.body;
+while(B!=null&&B!=A){if("scrollLeft" in B){E-=B.scrollLeft;
+D-=B.scrollTop;
+}B=B.parentNode;
+}return{left:E,top:D};
+};
+SimileAjax.DOM.getSize=function(B){var A=this.getStyle(B,"width");
+var C=this.getStyle(B,"height");
+if(A.indexOf("px")>-1){A=A.replace("px","");
+}if(C.indexOf("px")>-1){C=C.replace("px","");
+}return{w:A,h:C};
+};
+SimileAjax.DOM.getStyle=function(B,A){if(B.currentStyle){var C=B.currentStyle[A];
+}else{if(window.getComputedStyle){var C=document.defaultView.getComputedStyle(B,null).getPropertyValue(A);
+}else{var C="";
+}}return C;
+};
+SimileAjax.DOM.getEventRelativeCoordinates=function(A,B){if(SimileAjax.Platform.browser.isIE){return{x:A.offsetX,y:A.offsetY};
+}else{var C=SimileAjax.DOM.getPageCoordinates(B);
+return{x:A.pageX-C.left,y:A.pageY-C.top};
+}};
+SimileAjax.DOM.getEventPageCoordinates=function(A){if(SimileAjax.Platform.browser.isIE){return{x:A.clientX+document.body.scrollLeft,y:A.clientY+document.body.scrollTop};
+}else{return{x:A.pageX,y:A.pageY};
+}};
+SimileAjax.DOM.hittest=function(A,C,B){return SimileAjax.DOM._hittest(document.body,A,C,B);
+};
+SimileAjax.DOM._hittest=function(C,L,K,H){var M=C.childNodes;
+outer:for(var G=0;
+G<M.length;
+G++){var A=M[G];
+for(var F=0;
+F<H.length;
+F++){if(A==H[F]){continue outer;
+}}if(A.offsetWidth==0&&A.offsetHeight==0){var B=SimileAjax.DOM._hittest(A,L,K,H);
+if(B!=A){return B;
+}}else{var J=0;
+var E=0;
+var D=A;
+while(D){J+=D.offsetTop;
+E+=D.offsetLeft;
+D=D.offsetParent;
+}if(E<=L&&J<=K&&(L-E)<A.offsetWidth&&(K-J)<A.offsetHeight){return SimileAjax.DOM._hittest(A,L,K,H);
+}else{if(A.nodeType==1&&A.tagName=="TR"){var I=SimileAjax.DOM._hittest(A,L,K,H);
+if(I!=A){return I;
+}}}}}return C;
+};
+SimileAjax.DOM.cancelEvent=function(A){A.returnValue=false;
+A.cancelBubble=true;
+if("preventDefault" in A){A.preventDefault();
+}};
+SimileAjax.DOM.appendClassName=function(C,D){var B=C.className.split(" ");
+for(var A=0;
+A<B.length;
+A++){if(B[A]==D){return ;
+}}B.push(D);
+C.className=B.join(" ");
+};
+SimileAjax.DOM.createInputElement=function(A){var B=document.createElement("div");
+B.innerHTML="<input type='"+A+"' />";
+return B.firstChild;
+};
+SimileAjax.DOM.createDOMFromTemplate=function(B){var A={};
+A.elmt=SimileAjax.DOM._createDOMFromTemplate(B,A,null);
+return A;
+};
+SimileAjax.DOM._createDOMFromTemplate=function(A,I,E){if(A==null){return null;
+}else{if(typeof A!="object"){var D=document.createTextNode(A);
+if(E!=null){E.appendChild(D);
+}return D;
+}else{var C=null;
+if("tag" in A){var J=A.tag;
+if(E!=null){if(J=="tr"){C=E.insertRow(E.rows.length);
+}else{if(J=="td"){C=E.insertCell(E.cells.length);
+}}}if(C==null){C=J=="input"?SimileAjax.DOM.createInputElement(A.type):document.createElement(J);
+if(E!=null){E.appendChild(C);
+}}}else{C=A.elmt;
+if(E!=null){E.appendChild(C);
+}}for(var B in A){var G=A[B];
+if(B=="field"){I[G]=C;
+}else{if(B=="className"){C.className=G;
+}else{if(B=="id"){C.id=G;
+}else{if(B=="title"){C.title=G;
+}else{if(B=="type"&&C.tagName=="input"){}else{if(B=="style"){for(n in G){var H=G[n];
+if(n=="float"){n=SimileAjax.Platform.browser.isIE?"styleFloat":"cssFloat";
+}C.style[n]=H;
+}}else{if(B=="children"){for(var F=0;
+F<G.length;
+F++){SimileAjax.DOM._createDOMFromTemplate(G[F],I,C);
+}}else{if(B!="tag"&&B!="elmt"){C.setAttribute(B,G);
+}}}}}}}}}return C;
+}}};
+SimileAjax.DOM._cachedParent=null;
+SimileAjax.DOM.createElementFromString=function(A){if(SimileAjax.DOM._cachedParent==null){SimileAjax.DOM._cachedParent=document.createElement("div");
+}SimileAjax.DOM._cachedParent.innerHTML=A;
+return SimileAjax.DOM._cachedParent.firstChild;
+};
+SimileAjax.DOM.createDOMFromString=function(A,C,D){var B=typeof A=="string"?document.createElement(A):A;
+B.innerHTML=C;
+var E={elmt:B};
+SimileAjax.DOM._processDOMChildrenConstructedFromString(E,B,D!=null?D:{});
+return E;
+};
+SimileAjax.DOM._processDOMConstructedFromString=function(D,A,B){var E=A.id;
+if(E!=null&&E.length>0){A.removeAttribute("id");
+if(E in B){var C=A.parentNode;
+C.insertBefore(B[E],A);
+C.removeChild(A);
+D[E]=B[E];
+return ;
+}else{D[E]=A;
+}}if(A.hasChildNodes()){SimileAjax.DOM._processDOMChildrenConstructedFromString(D,A,B);
+}};
+SimileAjax.DOM._processDOMChildrenConstructedFromString=function(E,B,D){var C=B.firstChild;
+while(C!=null){var A=C.nextSibling;
+if(C.nodeType==1){SimileAjax.DOM._processDOMConstructedFromString(E,C,D);
+}C=A;
+}};
+
+
+/* graphics.js */
+SimileAjax.Graphics=new Object();
+SimileAjax.Graphics.pngIsTranslucent=(!SimileAjax.Platform.browser.isIE)||(SimileAjax.Platform.browser.majorVersion>6);
+SimileAjax.Graphics._createTranslucentImage1=function(A,C){var B=document.createElement("img");
+B.setAttribute("src",A);
+if(C!=null){B.style.verticalAlign=C;
+}return B;
+};
+SimileAjax.Graphics._createTranslucentImage2=function(A,C){var B=document.createElement("img");
+B.style.width="1px";
+B.style.height="1px";
+B.style.filter="progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+A+"', sizingMethod='image')";
+B.style.verticalAlign=(C!=null)?C:"middle";
+return B;
+};
+SimileAjax.Graphics.createTranslucentImage=SimileAjax.Graphics.pngIsTranslucent?SimileAjax.Graphics._createTranslucentImage1:SimileAjax.Graphics._createTranslucentImage2;
+SimileAjax.Graphics._createTranslucentImageHTML1=function(A,B){return'<img src="'+A+'"'+(B!=null?' style="vertical-align: '+B+';"':"")+" />";
+};
+SimileAjax.Graphics._createTranslucentImageHTML2=function(A,C){var B="width: 1px; height: 1px; filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+A+"', sizingMethod='image');"+(C!=null?" vertical-align: "+C+";":"");
+return"<img src='"+A+"' style=\""+B+'" />';
+};
+SimileAjax.Graphics.createTranslucentImageHTML=SimileAjax.Graphics.pngIsTranslucent?SimileAjax.Graphics._createTranslucentImageHTML1:SimileAjax.Graphics._createTranslucentImageHTML2;
+SimileAjax.Graphics.setOpacity=function(B,A){if(SimileAjax.Platform.browser.isIE){B.style.filter="progid:DXImageTransform.Microsoft.Alpha(Style=0,Opacity="+A+")";
+}else{var C=(A/100).toString();
+B.style.opacity=C;
+B.style.MozOpacity=C;
+}};
+SimileAjax.Graphics._bubbleMargins={top:33,bottom:42,left:33,right:40};
+SimileAjax.Graphics._arrowOffsets={top:0,bottom:9,left:1,right:8};
+SimileAjax.Graphics._bubblePadding=15;
+SimileAjax.Graphics._bubblePointOffset=6;
+SimileAjax.Graphics._halfArrowWidth=18;
+SimileAjax.Graphics.createBubbleForContentAndPoint=function(E,D,C,A,B){if(typeof A!="number"){A=300;
+}E.style.position="absolute";
+E.style.left="-5000px";
+E.style.top="0px";
+E.style.width=A+"px";
+document.body.appendChild(E);
+window.setTimeout(function(){var H=E.scrollWidth+10;
+var F=E.scrollHeight+10;
+var G=SimileAjax.Graphics.createBubbleForPoint(D,C,H,F,B);
+document.body.removeChild(E);
+E.style.position="static";
+E.style.left="";
+E.style.top="";
+E.style.width=H+"px";
+G.content.appendChild(E);
+},200);
+};
+SimileAjax.Graphics.createBubbleForPoint=function(C,B,N,R,F){function T(){if(typeof window.innerHeight=="number"){return{w:window.innerWidth,h:window.innerHeight};
+}else{if(document.documentElement&&document.documentElement.clientHeight){return{w:document.documentElement.clientWidth,h:document.documentElement.clientHeight};
+}else{if(document.body&&document.body.clientHeight){return{w:document.body.clientWidth,h:document.body.clientHeight};
+}}}}var L=function(){if(!M._closed){document.body.removeChild(M._div);
+M._doc=null;
+M._div=null;
+M._content=null;
+M._closed=true;
+}};
+var M={_closed:false};
+var O=T();
+var H=O.w;
+var G=O.h;
+var D=SimileAjax.Graphics._bubbleMargins;
+N=parseInt(N,10);
+R=parseInt(R,10);
+var P=D.left+N+D.right;
+var U=D.top+R+D.bottom;
+var Q=SimileAjax.Graphics.pngIsTranslucent;
+var J=SimileAjax.urlPrefix;
+var A=function(Z,Y,a,X){Z.style.position="absolute";
+Z.style.width=a+"px";
+Z.style.height=X+"px";
+if(Q){Z.style.background="url("+Y+")";
+}else{Z.style.filter="progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+Y+"', sizingMethod='crop')";
+}};
+var K=document.createElement("div");
+K.style.width=P+"px";
+K.style.height=U+"px";
+K.style.position="absolute";
+K.style.zIndex=1000;
+var W=SimileAjax.WindowManager.pushLayer(L,true,K);
+M._div=K;
+M.close=function(){SimileAjax.WindowManager.popLayer(W);
+};
+var I=document.createElement("div");
+I.style.width="100%";
+I.style.height="100%";
+I.style.position="relative";
+K.appendChild(I);
+var S=function(Z,c,b,a,Y){var X=document.createElement("div");
+X.style.left=c+"px";
+X.style.top=b+"px";
+A(X,Z,a,Y);
+I.appendChild(X);
+};
+S(J+"images/bubble-top-left.png",0,0,D.left,D.top);
+S(J+"images/bubble-top.png",D.left,0,N,D.top);
+S(J+"images/bubble-top-right.png",D.left+N,0,D.right,D.top);
+S(J+"images/bubble-left.png",0,D.top,D.left,R);
+S(J+"images/bubble-right.png",D.left+N,D.top,D.right,R);
+S(J+"images/bubble-bottom-left.png",0,D.top+R,D.left,D.bottom);
+S(J+"images/bubble-bottom.png",D.left,D.top+R,N,D.bottom);
+S(J+"images/bubble-bottom-right.png",D.left+N,D.top+R,D.right,D.bottom);
+var V=document.createElement("div");
+V.style.left=(P-D.right+SimileAjax.Graphics._bubblePadding-16-2)+"px";
+V.style.top=(D.top-SimileAjax.Graphics._bubblePadding+1)+"px";
+V.style.cursor="pointer";
+A(V,J+"images/close-button.png",16,16);
+SimileAjax.WindowManager.registerEventWithObject(V,"click",M,"close");
+I.appendChild(V);
+var E=document.createElement("div");
+E.style.position="absolute";
+E.style.left=D.left+"px";
+E.style.top=D.top+"px";
+E.style.width=N+"px";
+E.style.height=R+"px";
+E.style.overflow="auto";
+E.style.background="white";
+I.appendChild(E);
+M.content=E;
+(function(){if(C-SimileAjax.Graphics._halfArrowWidth-SimileAjax.Graphics._bubblePadding>0&&C+SimileAjax.Graphics._halfArrowWidth+SimileAjax.Graphics._bubblePadding<H){var Z=C-Math.round(N/2)-D.left;
+Z=C<(H/2)?Math.max(Z,-(D.left-SimileAjax.Graphics._bubblePadding)):Math.min(Z,H+(D.right-SimileAjax.Graphics._bubblePadding)-P);
+if((F&&F=="top")||(!F&&(B-SimileAjax.Graphics._bubblePointOffset-U>0))){var X=document.createElement("div");
+X.style.left=(C-SimileAjax.Graphics._halfArrowWidth-Z)+"px";
+X.style.top=(D.top+R)+"px";
+A(X,J+"images/bubble-bottom-arrow.png",37,D.bottom);
+I.appendChild(X);
+K.style.left=Z+"px";
+K.style.top=(B-SimileAjax.Graphics._bubblePointOffset-U+SimileAjax.Graphics._arrowOffsets.bottom)+"px";
+return ;
+}else{if((F&&F=="bottom")||(!F&&(B+SimileAjax.Graphics._bubblePointOffset+U<G))){var X=document.createElement("div");
+X.style.left=(C-SimileAjax.Graphics._halfArrowWidth-Z)+"px";
+X.style.top="0px";
+A(X,J+"images/bubble-top-arrow.png",37,D.top);
+I.appendChild(X);
+K.style.left=Z+"px";
+K.style.top=(B+SimileAjax.Graphics._bubblePointOffset-SimileAjax.Graphics._arrowOffsets.top)+"px";
+return ;
+}}}var Y=B-Math.round(R/2)-D.top;
+Y=B<(G/2)?Math.max(Y,-(D.top-SimileAjax.Graphics._bubblePadding)):Math.min(Y,G+(D.bottom-SimileAjax.Graphics._bubblePadding)-U);
+if((F&&F=="left")||(!F&&(C-SimileAjax.Graphics._bubblePointOffset-P>0))){var X=document.createElement("div");
+X.style.left=(D.left+N)+"px";
+X.style.top=(B-SimileAjax.Graphics._halfArrowWidth-Y)+"px";
+A(X,J+"images/bubble-right-arrow.png",D.right,37);
+I.appendChild(X);
+K.style.left=(C-SimileAjax.Graphics._bubblePointOffset-P+SimileAjax.Graphics._arrowOffsets.right)+"px";
+K.style.top=Y+"px";
+}else{if((F&&F=="right")||(!F&&(C-SimileAjax.Graphics._bubblePointOffset-P<H))){var X=document.createElement("div");
+X.style.left="0px";
+X.style.top=(B-SimileAjax.Graphics._halfArrowWidth-Y)+"px";
+A(X,J+"images/bubble-left-arrow.png",D.left,37);
+I.appendChild(X);
+K.style.left=(C+SimileAjax.Graphics._bubblePointOffset-SimileAjax.Graphics._arrowOffsets.left)+"px";
+K.style.top=Y+"px";
+}}})();
+document.body.appendChild(K);
+return M;
+};
+SimileAjax.Graphics.createMessageBubble=function(H){var G=H.createElement("div");
+if(SimileAjax.Graphics.pngIsTranslucent){var I=H.createElement("div");
+I.style.height="33px";
+I.style.background="url("+SimileAjax.urlPrefix+"images/message-top-left.png) top left no-repeat";
+I.style.paddingLeft="44px";
+G.appendChild(I);
+var C=H.createElement("div");
+C.style.height="33px";
+C.style.background="url("+SimileAjax.urlPrefix+"images/message-top-right.png) top right no-repeat";
+I.appendChild(C);
+var F=H.createElement("div");
+F.style.background="url("+SimileAjax.urlPrefix+"images/message-left.png) top left repeat-y";
+F.style.paddingLeft="44px";
+G.appendChild(F);
+var A=H.createElement("div");
+A.style.background="url("+SimileAjax.urlPrefix+"images/message-right.png) top right repeat-y";
+A.style.paddingRight="44px";
+F.appendChild(A);
+var D=H.createElement("div");
+A.appendChild(D);
+var B=H.createElement("div");
+B.style.height="55px";
+B.style.background="url("+SimileAjax.urlPrefix+"images/message-bottom-left.png) bottom left no-repeat";
+B.style.paddingLeft="44px";
+G.appendChild(B);
+var E=H.createElement("div");
+E.style.height="55px";
+E.style.background="url("+SimileAjax.urlPrefix+"images/message-bottom-right.png) bottom right no-repeat";
+B.appendChild(E);
+}else{G.style.border="2px solid #7777AA";
+G.style.padding="20px";
+G.style.background="white";
+SimileAjax.Graphics.setOpacity(G,90);
+var D=H.createElement("div");
+G.appendChild(D);
+}return{containerDiv:G,contentDiv:D};
+};
+SimileAjax.Graphics.createAnimation=function(B,E,D,C,A){return new SimileAjax.Graphics._Animation(B,E,D,C,A);
+};
+SimileAjax.Graphics._Animation=function(B,E,D,C,A){this.f=B;
+this.cont=(typeof A=="function")?A:function(){};
+this.from=E;
+this.to=D;
+this.current=E;
+this.duration=C;
+this.start=new Date().getTime();
+this.timePassed=0;
+};
+SimileAjax.Graphics._Animation.prototype.run=function(){var A=this;
+window.setTimeout(function(){A.step();
+},50);
+};
+SimileAjax.Graphics._Animation.prototype.step=function(){this.timePassed+=50;
+var B=this.timePassed/this.duration;
+var A=-Math.cos(B*Math.PI)/2+0.5;
+var D=A*(this.to-this.from)+this.from;
+try{this.f(D,D-this.current);
+}catch(C){}this.current=D;
+if(this.timePassed<this.duration){this.run();
+}else{this.f(this.to,0);
+this["cont"]();
+}};
+SimileAjax.Graphics.createStructuredDataCopyButton=function(F,D,A,E){var G=document.createElement("div");
+G.style.position="relative";
+G.style.display="inline";
+G.style.width=D+"px";
+G.style.height=A+"px";
+G.style.overflow="hidden";
+G.style.margin="2px";
+if(SimileAjax.Graphics.pngIsTranslucent){G.style.background="url("+F+") no-repeat";
+}else{G.style.filter="progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+F+"', sizingMethod='image')";
+}var C;
+if(SimileAjax.Platform.browser.isIE){C="filter:alpha(opacity=0)";
+}else{C="opacity: 0";
+}G.innerHTML="<textarea rows='1' autocomplete='off' value='none' style='"+C+"' />";
+var B=G.firstChild;
+B.style.width=D+"px";
+B.style.height=A+"px";
+B.onmousedown=function(H){H=(H)?H:((event)?event:null);
+if(H.button==2){B.value=E();
+B.select();
+}};
+return G;
+};
+SimileAjax.Graphics.getFontRenderingContext=function(A,B){return new SimileAjax.Graphics._FontRenderingContext(A,B);
+};
+SimileAjax.Graphics._FontRenderingContext=function(A,B){this._elmt=A;
+this._elmt.style.visibility="hidden";
+if(typeof B=="string"){this._elmt.style.width=B;
+}else{if(typeof B=="number"){this._elmt.style.width=B+"px";
+}}};
+SimileAjax.Graphics._FontRenderingContext.prototype.dispose=function(){this._elmt=null;
+};
+SimileAjax.Graphics._FontRenderingContext.prototype.update=function(){this._elmt.innerHTML="A";
+this._lineHeight=this._elmt.offsetHeight;
+};
+SimileAjax.Graphics._FontRenderingContext.prototype.computeSize=function(A){this._elmt.innerHTML=A;
+return{width:this._elmt.offsetWidth,height:this._elmt.offsetHeight};
+};
+SimileAjax.Graphics._FontRenderingContext.prototype.getLineHeight=function(){return this._lineHeight;
+};
+
+
+/* history.js */
+SimileAjax.History={maxHistoryLength:10,historyFile:"__history__.html",enabled:true,_initialized:false,_listeners:new SimileAjax.ListenerQueue(),_actions:[],_baseIndex:0,_currentIndex:0,_plainDocumentTitle:document.title};
+SimileAjax.History.formatHistoryEntryTitle=function(A){return SimileAjax.History._plainDocumentTitle+" {"+A+"}";
+};
+SimileAjax.History.initialize=function(){if(SimileAjax.History._initialized){return ;
+}if(SimileAjax.History.enabled){var A=document.createElement("iframe");
+A.id="simile-ajax-history";
+A.style.position="absolute";
+A.style.width="10px";
+A.style.height="10px";
+A.style.top="0px";
+A.style.left="0px";
+A.style.visibility="hidden";
+A.src=SimileAjax.History.historyFile+"?0";
+document.body.appendChild(A);
+SimileAjax.DOM.registerEvent(A,"load",SimileAjax.History._handleIFrameOnLoad);
+SimileAjax.History._iframe=A;
+}SimileAjax.History._initialized=true;
+};
+SimileAjax.History.addListener=function(A){SimileAjax.History.initialize();
+SimileAjax.History._listeners.add(A);
+};
+SimileAjax.History.removeListener=function(A){SimileAjax.History.initialize();
+SimileAjax.History._listeners.remove(A);
+};
+SimileAjax.History.addAction=function(A){SimileAjax.History.initialize();
+SimileAjax.History._listeners.fire("onBeforePerform",[A]);
+window.setTimeout(function(){try{A.perform();
+SimileAjax.History._listeners.fire("onAfterPerform",[A]);
+if(SimileAjax.History.enabled){SimileAjax.History._actions=SimileAjax.History._actions.slice(0,SimileAjax.History._currentIndex-SimileAjax.History._baseIndex);
+SimileAjax.History._actions.push(A);
+SimileAjax.History._currentIndex++;
+var C=SimileAjax.History._actions.length-SimileAjax.History.maxHistoryLength;
+if(C>0){SimileAjax.History._actions=SimileAjax.History._actions.slice(C);
+SimileAjax.History._baseIndex+=C;
+}try{SimileAjax.History._iframe.contentWindow.location.search="?"+SimileAjax.History._currentIndex;
+}catch(B){var D=SimileAjax.History.formatHistoryEntryTitle(A.label);
+document.title=D;
+}}}catch(B){SimileAjax.Debug.exception(B,"Error adding action {"+A.label+"} to history");
+}},0);
+};
+SimileAjax.History.addLengthyAction=function(C,A,B){SimileAjax.History.addAction({perform:C,undo:A,label:B,uiLayer:SimileAjax.WindowManager.getBaseLayer(),lengthy:true});
+};
+SimileAjax.History._handleIFrameOnLoad=function(){try{var B=SimileAjax.History._iframe.contentWindow.location.search;
+var F=(B.length==0)?0:Math.max(0,parseInt(B.substr(1)));
+var E=function(){var G=F-SimileAjax.History._currentIndex;
+SimileAjax.History._currentIndex+=G;
+SimileAjax.History._baseIndex+=G;
+SimileAjax.History._iframe.contentWindow.location.search="?"+F;
+};
+if(F<SimileAjax.History._currentIndex){SimileAjax.History._listeners.fire("onBeforeUndoSeveral",[]);
+window.setTimeout(function(){while(SimileAjax.History._currentIndex>F&&SimileAjax.History._currentIndex>SimileAjax.History._baseIndex){SimileAjax.History._currentIndex--;
+var G=SimileAjax.History._actions[SimileAjax.History._currentIndex-SimileAjax.History._baseIndex];
+try{G.undo();
+}catch(H){SimileAjax.Debug.exception(H,"History: Failed to undo action {"+G.label+"}");
+}}SimileAjax.History._listeners.fire("onAfterUndoSeveral",[]);
+E();
+},0);
+}else{if(F>SimileAjax.History._currentIndex){SimileAjax.History._listeners.fire("onBeforeRedoSeveral",[]);
+window.setTimeout(function(){while(SimileAjax.History._currentIndex<F&&SimileAjax.History._currentIndex-SimileAjax.History._baseIndex<SimileAjax.History._actions.length){var G=SimileAjax.History._actions[SimileAjax.History._currentIndex-SimileAjax.History._baseIndex];
+try{G.perform();
+}catch(H){SimileAjax.Debug.exception(H,"History: Failed to redo action {"+G.label+"}");
+}SimileAjax.History._currentIndex++;
+}SimileAjax.History._listeners.fire("onAfterRedoSeveral",[]);
+E();
+},0);
+}else{var A=SimileAjax.History._currentIndex-SimileAjax.History._baseIndex-1;
+var D=(A>=0&&A<SimileAjax.History._actions.length)?SimileAjax.History.formatHistoryEntryTitle(SimileAjax.History._actions[A].label):SimileAjax.History._plainDocumentTitle;
+SimileAjax.History._iframe.contentWindow.document.title=D;
+document.title=D;
+}}}catch(C){}};
+SimileAjax.History.getNextUndoAction=function(){try{var A=SimileAjax.History._currentIndex-SimileAjax.History._baseIndex-1;
+return SimileAjax.History._actions[A];
+}catch(B){return null;
+}};
+SimileAjax.History.getNextRedoAction=function(){try{var A=SimileAjax.History._currentIndex-SimileAjax.History._baseIndex;
+return SimileAjax.History._actions[A];
+}catch(B){return null;
+}};
+
+
+/* html.js */
+SimileAjax.HTML=new Object();
+SimileAjax.HTML._e2uHash={};
+(function(){var A=SimileAjax.HTML._e2uHash;
+A["nbsp"]="\u00A0[space]";
+A["iexcl"]="\u00A1";
+A["cent"]="\u00A2";
+A["pound"]="\u00A3";
+A["curren"]="\u00A4";
+A["yen"]="\u00A5";
+A["brvbar"]="\u00A6";
+A["sect"]="\u00A7";
+A["uml"]="\u00A8";
+A["copy"]="\u00A9";
+A["ordf"]="\u00AA";
+A["laquo"]="\u00AB";
+A["not"]="\u00AC";
+A["shy"]="\u00AD";
+A["reg"]="\u00AE";
+A["macr"]="\u00AF";
+A["deg"]="\u00B0";
+A["plusmn"]="\u00B1";
+A["sup2"]="\u00B2";
+A["sup3"]="\u00B3";
+A["acute"]="\u00B4";
+A["micro"]="\u00B5";
+A["para"]="\u00B6";
+A["middot"]="\u00B7";
+A["cedil"]="\u00B8";
+A["sup1"]="\u00B9";
+A["ordm"]="\u00BA";
+A["raquo"]="\u00BB";
+A["frac14"]="\u00BC";
+A["frac12"]="\u00BD";
+A["frac34"]="\u00BE";
+A["iquest"]="\u00BF";
+A["Agrave"]="\u00C0";
+A["Aacute"]="\u00C1";
+A["Acirc"]="\u00C2";
+A["Atilde"]="\u00C3";
+A["Auml"]="\u00C4";
+A["Aring"]="\u00C5";
+A["AElig"]="\u00C6";
+A["Ccedil"]="\u00C7";
+A["Egrave"]="\u00C8";
+A["Eacute"]="\u00C9";
+A["Ecirc"]="\u00CA";
+A["Euml"]="\u00CB";
+A["Igrave"]="\u00CC";
+A["Iacute"]="\u00CD";
+A["Icirc"]="\u00CE";
+A["Iuml"]="\u00CF";
+A["ETH"]="\u00D0";
+A["Ntilde"]="\u00D1";
+A["Ograve"]="\u00D2";
+A["Oacute"]="\u00D3";
+A["Ocirc"]="\u00D4";
+A["Otilde"]="\u00D5";
+A["Ouml"]="\u00D6";
+A["times"]="\u00D7";
+A["Oslash"]="\u00D8";
+A["Ugrave"]="\u00D9";
+A["Uacute"]="\u00DA";
+A["Ucirc"]="\u00DB";
+A["Uuml"]="\u00DC";
+A["Yacute"]="\u00DD";
+A["THORN"]="\u00DE";
+A["szlig"]="\u00DF";
+A["agrave"]="\u00E0";
+A["aacute"]="\u00E1";
+A["acirc"]="\u00E2";
+A["atilde"]="\u00E3";
+A["auml"]="\u00E4";
+A["aring"]="\u00E5";
+A["aelig"]="\u00E6";
+A["ccedil"]="\u00E7";
+A["egrave"]="\u00E8";
+A["eacute"]="\u00E9";
+A["ecirc"]="\u00EA";
+A["euml"]="\u00EB";
+A["igrave"]="\u00EC";
+A["iacute"]="\u00ED";
+A["icirc"]="\u00EE";
+A["iuml"]="\u00EF";
+A["eth"]="\u00F0";
+A["ntilde"]="\u00F1";
+A["ograve"]="\u00F2";
+A["oacute"]="\u00F3";
+A["ocirc"]="\u00F4";
+A["otilde"]="\u00F5";
+A["ouml"]="\u00F6";
+A["divide"]="\u00F7";
+A["oslash"]="\u00F8";
+A["ugrave"]="\u00F9";
+A["uacute"]="\u00FA";
+A["ucirc"]="\u00FB";
+A["uuml"]="\u00FC";
+A["yacute"]="\u00FD";
+A["thorn"]="\u00FE";
+A["yuml"]="\u00FF";
+A["quot"]="\u0022";
+A["amp"]="\u0026";
+A["lt"]="\u003C";
+A["gt"]="\u003E";
+A["OElig"]="";
+A["oelig"]="\u0153";
+A["Scaron"]="\u0160";
+A["scaron"]="\u0161";
+A["Yuml"]="\u0178";
+A["circ"]="\u02C6";
+A["tilde"]="\u02DC";
+A["ensp"]="\u2002";
+A["emsp"]="\u2003";
+A["thinsp"]="\u2009";
+A["zwnj"]="\u200C";
+A["zwj"]="\u200D";
+A["lrm"]="\u200E";
+A["rlm"]="\u200F";
+A["ndash"]="\u2013";
+A["mdash"]="\u2014";
+A["lsquo"]="\u2018";
+A["rsquo"]="\u2019";
+A["sbquo"]="\u201A";
+A["ldquo"]="\u201C";
+A["rdquo"]="\u201D";
+A["bdquo"]="\u201E";
+A["dagger"]="\u2020";
+A["Dagger"]="\u2021";
+A["permil"]="\u2030";
+A["lsaquo"]="\u2039";
+A["rsaquo"]="\u203A";
+A["euro"]="\u20AC";
+A["fnof"]="\u0192";
+A["Alpha"]="\u0391";
+A["Beta"]="\u0392";
+A["Gamma"]="\u0393";
+A["Delta"]="\u0394";
+A["Epsilon"]="\u0395";
+A["Zeta"]="\u0396";
+A["Eta"]="\u0397";
+A["Theta"]="\u0398";
+A["Iota"]="\u0399";
+A["Kappa"]="\u039A";
+A["Lambda"]="\u039B";
+A["Mu"]="\u039C";
+A["Nu"]="\u039D";
+A["Xi"]="\u039E";
+A["Omicron"]="\u039F";
+A["Pi"]="\u03A0";
+A["Rho"]="\u03A1";
+A["Sigma"]="\u03A3";
+A["Tau"]="\u03A4";
+A["Upsilon"]="\u03A5";
+A["Phi"]="\u03A6";
+A["Chi"]="\u03A7";
+A["Psi"]="\u03A8";
+A["Omega"]="\u03A9";
+A["alpha"]="\u03B1";
+A["beta"]="\u03B2";
+A["gamma"]="\u03B3";
+A["delta"]="\u03B4";
+A["epsilon"]="\u03B5";
+A["zeta"]="\u03B6";
+A["eta"]="\u03B7";
+A["theta"]="\u03B8";
+A["iota"]="\u03B9";
+A["kappa"]="\u03BA";
+A["lambda"]="\u03BB";
+A["mu"]="\u03BC";
+A["nu"]="\u03BD";
+A["xi"]="\u03BE";
+A["omicron"]="\u03BF";
+A["pi"]="\u03C0";
+A["rho"]="\u03C1";
+A["sigmaf"]="\u03C2";
+A["sigma"]="\u03C3";
+A["tau"]="\u03C4";
+A["upsilon"]="\u03C5";
+A["phi"]="\u03C6";
+A["chi"]="\u03C7";
+A["psi"]="\u03C8";
+A["omega"]="\u03C9";
+A["thetasym"]="\u03D1";
+A["upsih"]="\u03D2";
+A["piv"]="\u03D6";
+A["bull"]="\u2022";
+A["hellip"]="\u2026";
+A["prime"]="\u2032";
+A["Prime"]="\u2033";
+A["oline"]="\u203E";
+A["frasl"]="\u2044";
+A["weierp"]="\u2118";
+A["image"]="\u2111";
+A["real"]="\u211C";
+A["trade"]="\u2122";
+A["alefsym"]="\u2135";
+A["larr"]="\u2190";
+A["uarr"]="\u2191";
+A["rarr"]="\u2192";
+A["darr"]="\u2193";
+A["harr"]="\u2194";
+A["crarr"]="\u21B5";
+A["lArr"]="\u21D0";
+A["uArr"]="\u21D1";
+A["rArr"]="\u21D2";
+A["dArr"]="\u21D3";
+A["hArr"]="\u21D4";
+A["forall"]="\u2200";
+A["part"]="\u2202";
+A["exist"]="\u2203";
+A["empty"]="\u2205";
+A["nabla"]="\u2207";
+A["isin"]="\u2208";
+A["notin"]="\u2209";
+A["ni"]="\u220B";
+A["prod"]="\u220F";
+A["sum"]="\u2211";
+A["minus"]="\u2212";
+A["lowast"]="\u2217";
+A["radic"]="\u221A";
+A["prop"]="\u221D";
+A["infin"]="\u221E";
+A["ang"]="\u2220";
+A["and"]="\u2227";
+A["or"]="\u2228";
+A["cap"]="\u2229";
+A["cup"]="\u222A";
+A["int"]="\u222B";
+A["there4"]="\u2234";
+A["sim"]="\u223C";
+A["cong"]="\u2245";
+A["asymp"]="\u2248";
+A["ne"]="\u2260";
+A["equiv"]="\u2261";
+A["le"]="\u2264";
+A["ge"]="\u2265";
+A["sub"]="\u2282";
+A["sup"]="\u2283";
+A["nsub"]="\u2284";
+A["sube"]="\u2286";
+A["supe"]="\u2287";
+A["oplus"]="\u2295";
+A["otimes"]="\u2297";
+A["perp"]="\u22A5";
+A["sdot"]="\u22C5";
+A["lceil"]="\u2308";
+A["rceil"]="\u2309";
+A["lfloor"]="\u230A";
+A["rfloor"]="\u230B";
+A["lang"]="\u2329";
+A["rang"]="\u232A";
+A["loz"]="\u25CA";
+A["spades"]="\u2660";
+A["clubs"]="\u2663";
+A["hearts"]="\u2665";
+A["diams"]="\u2666";
+})();
+SimileAjax.HTML.deEntify=function(C){var D=SimileAjax.HTML._e2uHash;
+var B=/&(\w+?);/;
+while(B.test(C)){var A=C.match(B);
+C=C.replace(B,D[A[1]]);
+}return C;
+};
+
+
+/* jquery-1.2.1.js */
+(function(){if(typeof jQuery!="undefined"){var _jQuery=jQuery;
+}var jQuery=window.jQuery=function(selector,context){return this instanceof jQuery?this.init(selector,context):new jQuery(selector,context);
+};
+if(typeof $!="undefined"){var _$=$;
+}window.$=jQuery;
+var quickExpr=/^[^<]*(<(.|\s)+>)[^>]*$|^#(\w+)$/;
+jQuery.fn=jQuery.prototype={init:function(selector,context){selector=selector||document;
+if(typeof selector=="string"){var m=quickExpr.exec(selector);
+if(m&&(m[1]||!context)){if(m[1]){selector=jQuery.clean([m[1]],context);
+}else{var tmp=document.getElementById(m[3]);
+if(tmp){if(tmp.id!=m[3]){return jQuery().find(selector);
+}else{this[0]=tmp;
+this.length=1;
+return this;
+}}else{selector=[];
+}}}else{return new jQuery(context).find(selector);
+}}else{if(jQuery.isFunction(selector)){return new jQuery(document)[jQuery.fn.ready?"ready":"load"](selector);
+}}return this.setArray(selector.constructor==Array&&selector||(selector.jquery||selector.length&&selector!=window&&!selector.nodeType&&selector[0]!=undefined&&selector[0].nodeType)&&jQuery.makeArray(selector)||[selector]);
+},jquery:"1.2.1",size:function(){return this.length;
+},length:0,get:function(num){return num==undefined?jQuery.makeArray(this):this[num];
+},pushStack:function(a){var ret=jQuery(a);
+ret.prevObject=this;
+return ret;
+},setArray:function(a){this.length=0;
+Array.prototype.push.apply(this,a);
+return this;
+},each:function(fn,args){return jQuery.each(this,fn,args);
+},index:function(obj){var pos=-1;
+this.each(function(i){if(this==obj){pos=i;
+}});
+return pos;
+},attr:function(key,value,type){var obj=key;
+if(key.constructor==String){if(value==undefined){return this.length&&jQuery[type||"attr"](this[0],key)||undefined;
+}else{obj={};
+obj[key]=value;
+}}return this.each(function(index){for(var prop in obj){jQuery.attr(type?this.style:this,prop,jQuery.prop(this,obj[prop],type,index,prop));
+}});
+},css:function(key,value){return this.attr(key,value,"curCSS");
+},text:function(e){if(typeof e!="object"&&e!=null){return this.empty().append(document.createTextNode(e));
+}var t="";
+jQuery.each(e||this,function(){jQuery.each(this.childNodes,function(){if(this.nodeType!=8){t+=this.nodeType!=1?this.nodeValue:jQuery.fn.text([this]);
+}});
+});
+return t;
+},wrapAll:function(html){if(this[0]){jQuery(html,this[0].ownerDocument).clone().insertBefore(this[0]).map(function(){var elem=this;
+while(elem.firstChild){elem=elem.firstChild;
+}return elem;
+}).append(this);
+}return this;
+},wrapInner:function(html){return this.each(function(){jQuery(this).contents().wrapAll(html);
+});
+},wrap:function(html){return this.each(function(){jQuery(this).wrapAll(html);
+});
+},append:function(){return this.domManip(arguments,true,1,function(a){this.appendChild(a);
+});
+},prepend:function(){return this.domManip(arguments,true,-1,function(a){this.insertBefore(a,this.firstChild);
+});
+},before:function(){return this.domManip(arguments,false,1,function(a){this.parentNode.insertBefore(a,this);
+});
+},after:function(){return this.domManip(arguments,false,-1,function(a){this.parentNode.insertBefore(a,this.nextSibling);
+});
+},end:function(){return this.prevObject||jQuery([]);
+},find:function(t){var data=jQuery.map(this,function(a){return jQuery.find(t,a);
+});
+return this.pushStack(/[^+>] [^+>]/.test(t)||t.indexOf("..")>-1?jQuery.unique(data):data);
+},clone:function(events){var ret=this.map(function(){return this.outerHTML?jQuery(this.outerHTML)[0]:this.cloneNode(true);
+});
+var clone=ret.find("*").andSelf().each(function(){if(this[expando]!=undefined){this[expando]=null;
+}});
+if(events===true){this.find("*").andSelf().each(function(i){var events=jQuery.data(this,"events");
+for(var type in events){for(var handler in events[type]){jQuery.event.add(clone[i],type,events[type][handler],events[type][handler].data);
+}}});
+}return ret;
+},filter:function(t){return this.pushStack(jQuery.isFunction(t)&&jQuery.grep(this,function(el,index){return t.apply(el,[index]);
+})||jQuery.multiFilter(t,this));
+},not:function(t){return this.pushStack(t.constructor==String&&jQuery.multiFilter(t,this,true)||jQuery.grep(this,function(a){return(t.constructor==Array||t.jquery)?jQuery.inArray(a,t)<0:a!=t;
+}));
+},add:function(t){return this.pushStack(jQuery.merge(this.get(),t.constructor==String?jQuery(t).get():t.length!=undefined&&(!t.nodeName||jQuery.nodeName(t,"form"))?t:[t]));
+},is:function(expr){return expr?jQuery.multiFilter(expr,this).length>0:false;
+},hasClass:function(expr){return this.is("."+expr);
+},val:function(val){if(val==undefined){if(this.length){var elem=this[0];
+if(jQuery.nodeName(elem,"select")){var index=elem.selectedIndex,a=[],options=elem.options,one=elem.type=="select-one";
+if(index<0){return null;
+}for(var i=one?index:0,max=one?index+1:options.length;
+i<max;
+i++){var option=options[i];
+if(option.selected){var val=jQuery.browser.msie&&!option.attributes["value"].specified?option.text:option.value;
+if(one){return val;
+}a.push(val);
+}}return a;
+}else{return this[0].value.replace(/\r/g,"");
+}}}else{return this.each(function(){if(val.constructor==Array&&/radio|checkbox/.test(this.type)){this.checked=(jQuery.inArray(this.value,val)>=0||jQuery.inArray(this.name,val)>=0);
+}else{if(jQuery.nodeName(this,"select")){var tmp=val.constructor==Array?val:[val];
+jQuery("option",this).each(function(){this.selected=(jQuery.inArray(this.value,tmp)>=0||jQuery.inArray(this.text,tmp)>=0);
+});
+if(!tmp.length){this.selectedIndex=-1;
+}}else{this.value=val;
+}}});
+}},html:function(val){return val==undefined?(this.length?this[0].innerHTML:null):this.empty().append(val);
+},replaceWith:function(val){return this.after(val).remove();
+},eq:function(i){return this.slice(i,i+1);
+},slice:function(){return this.pushStack(Array.prototype.slice.apply(this,arguments));
+},map:function(fn){return this.pushStack(jQuery.map(this,function(elem,i){return fn.call(elem,i,elem);
+}));
+},andSelf:function(){return this.add(this.prevObject);
+},domManip:function(args,table,dir,fn){var clone=this.length>1,a;
+return this.each(function(){if(!a){a=jQuery.clean(args,this.ownerDocument);
+if(dir<0){a.reverse();
+}}var obj=this;
+if(table&&jQuery.nodeName(this,"table")&&jQuery.nodeName(a[0],"tr")){obj=this.getElementsByTagName("tbody")[0]||this.appendChild(document.createElement("tbody"));
+}jQuery.each(a,function(){var elem=clone?this.cloneNode(true):this;
+if(!evalScript(0,elem)){fn.call(obj,elem);
+}});
+});
+}};
+function evalScript(i,elem){var script=jQuery.nodeName(elem,"script");
+if(script){if(elem.src){jQuery.ajax({url:elem.src,async:false,dataType:"script"});
+}else{jQuery.globalEval(elem.text||elem.textContent||elem.innerHTML||"");
+}if(elem.parentNode){elem.parentNode.removeChild(elem);
+}}else{if(elem.nodeType==1){jQuery("script",elem).each(evalScript);
+}}return script;
+}jQuery.extend=jQuery.fn.extend=function(){var target=arguments[0]||{},a=1,al=arguments.length,deep=false;
+if(target.constructor==Boolean){deep=target;
+target=arguments[1]||{};
+}if(al==1){target=this;
+a=0;
+}var prop;
+for(;
+a<al;
+a++){if((prop=arguments[a])!=null){for(var i in prop){if(target==prop[i]){continue;
+}if(deep&&typeof prop[i]=="object"&&target[i]){jQuery.extend(target[i],prop[i]);
+}else{if(prop[i]!=undefined){target[i]=prop[i];
+}}}}}return target;
+};
+var expando="jQuery"+(new Date()).getTime(),uuid=0,win={};
+jQuery.extend({noConflict:function(deep){window.$=_$;
+if(deep){window.jQuery=_jQuery;
+}return jQuery;
+},isFunction:function(fn){return !!fn&&typeof fn!="string"&&!fn.nodeName&&fn.constructor!=Array&&/function/i.test(fn+"");
+},isXMLDoc:function(elem){return elem.documentElement&&!elem.body||elem.tagName&&elem.ownerDocument&&!elem.ownerDocument.body;
+},globalEval:function(data){data=jQuery.trim(data);
+if(data){if(window.execScript){window.execScript(data);
+}else{if(jQuery.browser.safari){window.setTimeout(data,0);
+}else{eval.call(window,data);
+}}}},nodeName:function(elem,name){return elem.nodeName&&elem.nodeName.toUpperCase()==name.toUpperCase();
+},cache:{},data:function(elem,name,data){elem=elem==window?win:elem;
+var id=elem[expando];
+if(!id){id=elem[expando]=++uuid;
+}if(name&&!jQuery.cache[id]){jQuery.cache[id]={};
+}if(data!=undefined){jQuery.cache[id][name]=data;
+}return name?jQuery.cache[id][name]:id;
+},removeData:function(elem,name){elem=elem==window?win:elem;
+var id=elem[expando];
+if(name){if(jQuery.cache[id]){delete jQuery.cache[id][name];
+name="";
+for(name in jQuery.cache[id]){break;
+}if(!name){jQuery.removeData(elem);
+}}}else{try{delete elem[expando];
+}catch(e){if(elem.removeAttribute){elem.removeAttribute(expando);
+}}delete jQuery.cache[id];
+}},each:function(obj,fn,args){if(args){if(obj.length==undefined){for(var i in obj){fn.apply(obj[i],args);
+}}else{for(var i=0,ol=obj.length;
+i<ol;
+i++){if(fn.apply(obj[i],args)===false){break;
+}}}}else{if(obj.length==undefined){for(var i in obj){fn.call(obj[i],i,obj[i]);
+}}else{for(var i=0,ol=obj.length,val=obj[0];
+i<ol&&fn.call(val,i,val)!==false;
+val=obj[++i]){}}}return obj;
+},prop:function(elem,value,type,index,prop){if(jQuery.isFunction(value)){value=value.call(elem,[index]);
+}var exclude=/z-?index|font-?weight|opacity|zoom|line-?height/i;
+return value&&value.constructor==Number&&type=="curCSS"&&!exclude.test(prop)?value+"px":value;
+},className:{add:function(elem,c){jQuery.each((c||"").split(/\s+/),function(i,cur){if(!jQuery.className.has(elem.className,cur)){elem.className+=(elem.className?" ":"")+cur;
+}});
+},remove:function(elem,c){elem.className=c!=undefined?jQuery.grep(elem.className.split(/\s+/),function(cur){return !jQuery.className.has(c,cur);
+}).join(" "):"";
+},has:function(t,c){return jQuery.inArray(c,(t.className||t).toString().split(/\s+/))>-1;
+}},swap:function(e,o,f){for(var i in o){e.style["old"+i]=e.style[i];
+e.style[i]=o[i];
+}f.apply(e,[]);
+for(var i in o){e.style[i]=e.style["old"+i];
+}},css:function(e,p){if(p=="height"||p=="width"){var old={},oHeight,oWidth,d=["Top","Bottom","Right","Left"];
+jQuery.each(d,function(){old["padding"+this]=0;
+old["border"+this+"Width"]=0;
+});
+jQuery.swap(e,old,function(){if(jQuery(e).is(":visible")){oHeight=e.offsetHeight;
+oWidth=e.offsetWidth;
+}else{e=jQuery(e.cloneNode(true)).find(":radio").removeAttr("checked").end().css({visibility:"hidden",position:"absolute",display:"block",right:"0",left:"0"}).appendTo(e.parentNode)[0];
+var parPos=jQuery.css(e.parentNode,"position")||"static";
+if(parPos=="static"){e.parentNode.style.position="relative";
+}oHeight=e.clientHeight;
+oWidth=e.clientWidth;
+if(parPos=="static"){e.parentNode.style.position="static";
+}e.parentNode.removeChild(e);
+}});
+return p=="height"?oHeight:oWidth;
+}return jQuery.curCSS(e,p);
+},curCSS:function(elem,prop,force){var ret,stack=[],swap=[];
+function color(a){if(!jQuery.browser.safari){return false;
+}var ret=document.defaultView.getComputedStyle(a,null);
+return !ret||ret.getPropertyValue("color")=="";
+}if(prop=="opacity"&&jQuery.browser.msie){ret=jQuery.attr(elem.style,"opacity");
+return ret==""?"1":ret;
+}if(prop.match(/float/i)){prop=styleFloat;
+}if(!force&&elem.style[prop]){ret=elem.style[prop];
+}else{if(document.defaultView&&document.defaultView.getComputedStyle){if(prop.match(/float/i)){prop="float";
+}prop=prop.replace(/([A-Z])/g,"-$1").toLowerCase();
+var cur=document.defaultView.getComputedStyle(elem,null);
+if(cur&&!color(elem)){ret=cur.getPropertyValue(prop);
+}else{for(var a=elem;
+a&&color(a);
+a=a.parentNode){stack.unshift(a);
+}for(a=0;
+a<stack.length;
+a++){if(color(stack[a])){swap[a]=stack[a].style.display;
+stack[a].style.display="block";
+}}ret=prop=="display"&&swap[stack.length-1]!=null?"none":document.defaultView.getComputedStyle(elem,null).getPropertyValue(prop)||"";
+for(a=0;
+a<swap.length;
+a++){if(swap[a]!=null){stack[a].style.display=swap[a];
+}}}if(prop=="opacity"&&ret==""){ret="1";
+}}else{if(elem.currentStyle){var newProp=prop.replace(/\-(\w)/g,function(m,c){return c.toUpperCase();
+});
+ret=elem.currentStyle[prop]||elem.currentStyle[newProp];
+if(!/^\d+(px)?$/i.test(ret)&&/^\d/.test(ret)){var style=elem.style.left;
+var runtimeStyle=elem.runtimeStyle.left;
+elem.runtimeStyle.left=elem.currentStyle.left;
+elem.style.left=ret||0;
+ret=elem.style.pixelLeft+"px";
+elem.style.left=style;
+elem.runtimeStyle.left=runtimeStyle;
+}}}}return ret;
+},clean:function(a,doc){var r=[];
+doc=doc||document;
+jQuery.each(a,function(i,arg){if(!arg){return ;
+}if(arg.constructor==Number){arg=arg.toString();
+}if(typeof arg=="string"){arg=arg.replace(/(<(\w+)[^>]*?)\/>/g,function(m,all,tag){return tag.match(/^(abbr|br|col|img|input|link|meta|param|hr|area)$/i)?m:all+"></"+tag+">";
+});
+var s=jQuery.trim(arg).toLowerCase(),div=doc.createElement("div"),tb=[];
+var wrap=!s.indexOf("<opt")&&[1,"<select>","</select>"]||!s.indexOf("<leg")&&[1,"<fieldset>","</fieldset>"]||s.match(/^<(thead|tbody|tfoot|colg|cap)/)&&[1,"<table>","</table>"]||!s.indexOf("<tr")&&[2,"<table><tbody>","</tbody></table>"]||(!s.indexOf("<td")||!s.indexOf("<th"))&&[3,"<table><tbody><tr>","</tr></tbody></table>"]||!s.indexOf("<col")&&[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"]||jQuery.browser.msie&&[1,"div<div>","</div>"]||[0,"",""];
+div.innerHTML=wrap[1]+arg+wrap[2];
+while(wrap[0]--){div=div.lastChild;
+}if(jQuery.browser.msie){if(!s.indexOf("<table")&&s.indexOf("<tbody")<0){tb=div.firstChild&&div.firstChild.childNodes;
+}else{if(wrap[1]=="<table>"&&s.indexOf("<tbody")<0){tb=div.childNodes;
+}}for(var n=tb.length-1;
+n>=0;
+--n){if(jQuery.nodeName(tb[n],"tbody")&&!tb[n].childNodes.length){tb[n].parentNode.removeChild(tb[n]);
+}}if(/^\s/.test(arg)){div.insertBefore(doc.createTextNode(arg.match(/^\s*/)[0]),div.firstChild);
+}}arg=jQuery.makeArray(div.childNodes);
+}if(0===arg.length&&(!jQuery.nodeName(arg,"form")&&!jQuery.nodeName(arg,"select"))){return ;
+}if(arg[0]==undefined||jQuery.nodeName(arg,"form")||arg.options){r.push(arg);
+}else{r=jQuery.merge(r,arg);
+}});
+return r;
+},attr:function(elem,name,value){var fix=jQuery.isXMLDoc(elem)?{}:jQuery.props;
+if(name=="selected"&&jQuery.browser.safari){elem.parentNode.selectedIndex;
+}if(fix[name]){if(value!=undefined){elem[fix[name]]=value;
+}return elem[fix[name]];
+}else{if(jQuery.browser.msie&&name=="style"){return jQuery.attr(elem.style,"cssText",value);
+}else{if(value==undefined&&jQuery.browser.msie&&jQuery.nodeName(elem,"form")&&(name=="action"||name=="method")){return elem.getAttributeNode(name).nodeValue;
+}else{if(elem.tagName){if(value!=undefined){if(name=="type"&&jQuery.nodeName(elem,"input")&&elem.parentNode){throw"type property can't be changed";
+}elem.setAttribute(name,value);
+}if(jQuery.browser.msie&&/href|src/.test(name)&&!jQuery.isXMLDoc(elem)){return elem.getAttribute(name,2);
+}return elem.getAttribute(name);
+}else{if(name=="opacity"&&jQuery.browser.msie){if(value!=undefined){elem.zoom=1;
+elem.filter=(elem.filter||"").replace(/alpha\([^)]*\)/,"")+(parseFloat(value).toString()=="NaN"?"":"alpha(opacity="+value*100+")");
+}return elem.filter?(parseFloat(elem.filter.match(/opacity=([^)]*)/)[1])/100).toString():"";
+}name=name.replace(/-([a-z])/ig,function(z,b){return b.toUpperCase();
+});
+if(value!=undefined){elem[name]=value;
+}return elem[name];
+}}}}},trim:function(t){return(t||"").replace(/^\s+|\s+$/g,"");
+},makeArray:function(a){var r=[];
+if(typeof a!="array"){for(var i=0,al=a.length;
+i<al;
+i++){r.push(a[i]);
+}}else{r=a.slice(0);
+}return r;
+},inArray:function(b,a){for(var i=0,al=a.length;
+i<al;
+i++){if(a[i]==b){return i;
+}}return -1;
+},merge:function(first,second){if(jQuery.browser.msie){for(var i=0;
+second[i];
+i++){if(second[i].nodeType!=8){first.push(second[i]);
+}}}else{for(var i=0;
+second[i];
+i++){first.push(second[i]);
+}}return first;
+},unique:function(first){var r=[],done={};
+try{for(var i=0,fl=first.length;
+i<fl;
+i++){var id=jQuery.data(first[i]);
+if(!done[id]){done[id]=true;
+r.push(first[i]);
+}}}catch(e){r=first;
+}return r;
+},grep:function(elems,fn,inv){if(typeof fn=="string"){fn=eval("false||function(a,i){return "+fn+"}");
+}var result=[];
+for(var i=0,el=elems.length;
+i<el;
+i++){if(!inv&&fn(elems[i],i)||inv&&!fn(elems[i],i)){result.push(elems[i]);
+}}return result;
+},map:function(elems,fn){if(typeof fn=="string"){fn=eval("false||function(a){return "+fn+"}");
+}var result=[];
+for(var i=0,el=elems.length;
+i<el;
+i++){var val=fn(elems[i],i);
+if(val!==null&&val!=undefined){if(val.constructor!=Array){val=[val];
+}result=result.concat(val);
+}}return result;
+}});
+var userAgent=navigator.userAgent.toLowerCase();
+jQuery.browser={version:(userAgent.match(/.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/)||[])[1],safari:/webkit/.test(userAgent),opera:/opera/.test(userAgent),msie:/msie/.test(userAgent)&&!/opera/.test(userAgent),mozilla:/mozilla/.test(userAgent)&&!/(compatible|webkit)/.test(userAgent)};
+var styleFloat=jQuery.browser.msie?"styleFloat":"cssFloat";
+jQuery.extend({boxModel:!jQuery.browser.msie||document.compatMode=="CSS1Compat",styleFloat:jQuery.browser.msie?"styleFloat":"cssFloat",props:{"for":"htmlFor","class":"className","float":styleFloat,cssFloat:styleFloat,styleFloat:styleFloat,innerHTML:"innerHTML",className:"className",value:"value",disabled:"disabled",checked:"checked",readonly:"readOnly",selected:"selected",maxlength:"maxLength"}});
+jQuery.each({parent:"a.parentNode",parents:"jQuery.dir(a,'parentNode')",next:"jQuery.nth(a,2,'nextSibling')",prev:"jQuery.nth(a,2,'previousSibling')",nextAll:"jQuery.dir(a,'nextSibling')",prevAll:"jQuery.dir(a,'previousSibling')",siblings:"jQuery.sibling(a.parentNode.firstChild,a)",children:"jQuery.sibling(a.firstChild)",contents:"jQuery.nodeName(a,'iframe')?a.contentDocument||a.contentWindow.document:jQuery.makeArray(a.childNodes)"},function(i,n){jQuery.fn[i]=function(a){var ret=jQuery.map(this,n);
+if(a&&typeof a=="string"){ret=jQuery.multiFilter(a,ret);
+}return this.pushStack(jQuery.unique(ret));
+};
+});
+jQuery.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(i,n){jQuery.fn[i]=function(){var a=arguments;
+return this.each(function(){for(var j=0,al=a.length;
+j<al;
+j++){jQuery(a[j])[n](this);
+}});
+};
+});
+jQuery.each({removeAttr:function(key){jQuery.attr(this,key,"");
+this.removeAttribute(key);
+},addClass:function(c){jQuery.className.add(this,c);
+},removeClass:function(c){jQuery.className.remove(this,c);
+},toggleClass:function(c){jQuery.className[jQuery.className.has(this,c)?"remove":"add"](this,c);
+},remove:function(a){if(!a||jQuery.filter(a,[this]).r.length){jQuery.removeData(this);
+this.parentNode.removeChild(this);
+}},empty:function(){jQuery("*",this).each(function(){jQuery.removeData(this);
+});
+while(this.firstChild){this.removeChild(this.firstChild);
+}}},function(i,n){jQuery.fn[i]=function(){return this.each(n,arguments);
+};
+});
+jQuery.each(["Height","Width"],function(i,name){var n=name.toLowerCase();
+jQuery.fn[n]=function(h){return this[0]==window?jQuery.browser.safari&&self["inner"+name]||jQuery.boxModel&&Math.max(document.documentElement["client"+name],document.body["client"+name])||document.body["client"+name]:this[0]==document?Math.max(document.body["scroll"+name],document.body["offset"+name]):h==undefined?(this.length?jQuery.css(this[0],n):null):this.css(n,h.constructor==String?h:h+"px");
+};
+});
+var chars=jQuery.browser.safari&&parseInt(jQuery.browser.version)<417?"(?:[\\w*_-]|\\\\.)":"(?:[\\w\u0128-\uFFFF*_-]|\\\\.)",quickChild=new RegExp("^>\\s*("+chars+"+)"),quickID=new RegExp("^("+chars+"+)(#)("+chars+"+)"),quickClass=new RegExp("^([#.]?)("+chars+"*)");
+jQuery.extend({expr:{"":"m[2]=='*'||jQuery.nodeName(a,m[2])","#":"a.getAttribute('id')==m[2]",":":{lt:"i<m[3]-0",gt:"i>m[3]-0",nth:"m[3]-0==i",eq:"m[3]-0==i",first:"i==0",last:"i==r.length-1",even:"i%2==0",odd:"i%2","first-child":"a.parentNode.getElementsByTagName('*')[0]==a","last-child":"jQuery.nth(a.parentNode.lastChild,1,'previousSibling')==a","only-child":"!jQuery.nth(a.parentNode.lastChild,2,'previousSibling')",parent:"a.firstChild",empty:"!a.firstChild",contains:"(a.textContent||a.innerText||jQuery(a).text()||'').indexOf(m[3])>=0",visible:'"hidden"!=a.type&&jQuery.css(a,"display")!="none"&&jQuery.css(a,"visibility")!="hidden"',hidden:'"hidden"==a.type||jQuery.css(a,"display")=="none"||jQuery.css(a,"visibility")=="hidden"',enabled:"!a.disabled",disabled:"a.disabled",checked:"a.checked",selected:"a.selected||jQuery.attr(a,'selected')",text:"'text'==a.type",radio:"'radio'==a.type",checkbox:"'checkbox'==a.type",file:"'file'==a.type",password:"'password'==a.type",submit:"'submit'==a.type",image:"'image'==a.type",reset:"'reset'==a.type",button:'"button"==a.type||jQuery.nodeName(a,"button")',input:"/input|select|textarea|button/i.test(a.nodeName)",has:"jQuery.find(m[3],a).length",header:"/h\\d/i.test(a.nodeName)",animated:"jQuery.grep(jQuery.timers,function(fn){return a==fn.elem;}).length"}},parse:[/^(\[) *@?([\w-]+) *([!*$^~=]*) *('?"?)(.*?)\4 *\]/,/^(:)([\w-]+)\("?'?(.*?(\(.*?\))?[^(]*?)"?'?\)/,new RegExp("^([:.#]*)("+chars+"+)")],multiFilter:function(expr,elems,not){var old,cur=[];
+while(expr&&expr!=old){old=expr;
+var f=jQuery.filter(expr,elems,not);
+expr=f.t.replace(/^\s*,\s*/,"");
+cur=not?elems=f.r:jQuery.merge(cur,f.r);
+}return cur;
+},find:function(t,context){if(typeof t!="string"){return[t];
+}if(context&&!context.nodeType){context=null;
+}context=context||document;
+var ret=[context],done=[],last;
+while(t&&last!=t){var r=[];
+last=t;
+t=jQuery.trim(t);
+var foundToken=false;
+var re=quickChild;
+var m=re.exec(t);
+if(m){var nodeName=m[1].toUpperCase();
+for(var i=0;
+ret[i];
+i++){for(var c=ret[i].firstChild;
+c;
+c=c.nextSibling){if(c.nodeType==1&&(nodeName=="*"||c.nodeName.toUpperCase()==nodeName.toUpperCase())){r.push(c);
+}}}ret=r;
+t=t.replace(re,"");
+if(t.indexOf(" ")==0){continue;
+}foundToken=true;
+}else{re=/^([>+~])\s*(\w*)/i;
+if((m=re.exec(t))!=null){r=[];
+var nodeName=m[2],merge={};
+m=m[1];
+for(var j=0,rl=ret.length;
+j<rl;
+j++){var n=m=="~"||m=="+"?ret[j].nextSibling:ret[j].firstChild;
+for(;
+n;
+n=n.nextSibling){if(n.nodeType==1){var id=jQuery.data(n);
+if(m=="~"&&merge[id]){break;
+}if(!nodeName||n.nodeName.toUpperCase()==nodeName.toUpperCase()){if(m=="~"){merge[id]=true;
+}r.push(n);
+}if(m=="+"){break;
+}}}}ret=r;
+t=jQuery.trim(t.replace(re,""));
+foundToken=true;
+}}if(t&&!foundToken){if(!t.indexOf(",")){if(context==ret[0]){ret.shift();
+}done=jQuery.merge(done,ret);
+r=ret=[context];
+t=" "+t.substr(1,t.length);
+}else{var re2=quickID;
+var m=re2.exec(t);
+if(m){m=[0,m[2],m[3],m[1]];
+}else{re2=quickClass;
+m=re2.exec(t);
+}m[2]=m[2].replace(/\\/g,"");
+var elem=ret[ret.length-1];
+if(m[1]=="#"&&elem&&elem.getElementById&&!jQuery.isXMLDoc(elem)){var oid=elem.getElementById(m[2]);
+if((jQuery.browser.msie||jQuery.browser.opera)&&oid&&typeof oid.id=="string"&&oid.id!=m[2]){oid=jQuery('[@id="'+m[2]+'"]',elem)[0];
+}ret=r=oid&&(!m[3]||jQuery.nodeName(oid,m[3]))?[oid]:[];
+}else{for(var i=0;
+ret[i];
+i++){var tag=m[1]=="#"&&m[3]?m[3]:m[1]!=""||m[0]==""?"*":m[2];
+if(tag=="*"&&ret[i].nodeName.toLowerCase()=="object"){tag="param";
+}r=jQuery.merge(r,ret[i].getElementsByTagName(tag));
+}if(m[1]=="."){r=jQuery.classFilter(r,m[2]);
+}if(m[1]=="#"){var tmp=[];
+for(var i=0;
+r[i];
+i++){if(r[i].getAttribute("id")==m[2]){tmp=[r[i]];
+break;
+}}r=tmp;
+}ret=r;
+}t=t.replace(re2,"");
+}}if(t){var val=jQuery.filter(t,r);
+ret=r=val.r;
+t=jQuery.trim(val.t);
+}}if(t){ret=[];
+}if(ret&&context==ret[0]){ret.shift();
+}done=jQuery.merge(done,ret);
+return done;
+},classFilter:function(r,m,not){m=" "+m+" ";
+var tmp=[];
+for(var i=0;
+r[i];
+i++){var pass=(" "+r[i].className+" ").indexOf(m)>=0;
+if(!not&&pass||not&&!pass){tmp.push(r[i]);
+}}return tmp;
+},filter:function(t,r,not){var last;
+while(t&&t!=last){last=t;
+var p=jQuery.parse,m;
+for(var i=0;
+p[i];
+i++){m=p[i].exec(t);
+if(m){t=t.substring(m[0].length);
+m[2]=m[2].replace(/\\/g,"");
+break;
+}}if(!m){break;
+}if(m[1]==":"&&m[2]=="not"){r=jQuery.filter(m[3],r,true).r;
+}else{if(m[1]=="."){r=jQuery.classFilter(r,m[2],not);
+}else{if(m[1]=="["){var tmp=[],type=m[3];
+for(var i=0,rl=r.length;
+i<rl;
+i++){var a=r[i],z=a[jQuery.props[m[2]]||m[2]];
+if(z==null||/href|src|selected/.test(m[2])){z=jQuery.attr(a,m[2])||"";
+}if((type==""&&!!z||type=="="&&z==m[5]||type=="!="&&z!=m[5]||type=="^="&&z&&!z.indexOf(m[5])||type=="$="&&z.substr(z.length-m[5].length)==m[5]||(type=="*="||type=="~=")&&z.indexOf(m[5])>=0)^not){tmp.push(a);
+}}r=tmp;
+}else{if(m[1]==":"&&m[2]=="nth-child"){var merge={},tmp=[],test=/(\d*)n\+?(\d*)/.exec(m[3]=="even"&&"2n"||m[3]=="odd"&&"2n+1"||!/\D/.test(m[3])&&"n+"+m[3]||m[3]),first=(test[1]||1)-0,last=test[2]-0;
+for(var i=0,rl=r.length;
+i<rl;
+i++){var node=r[i],parentNode=node.parentNode,id=jQuery.data(parentNode);
+if(!merge[id]){var c=1;
+for(var n=parentNode.firstChild;
+n;
+n=n.nextSibling){if(n.nodeType==1){n.nodeIndex=c++;
+}}merge[id]=true;
+}var add=false;
+if(first==1){if(last==0||node.nodeIndex==last){add=true;
+}}else{if((node.nodeIndex+last)%first==0){add=true;
+}}if(add^not){tmp.push(node);
+}}r=tmp;
+}else{var f=jQuery.expr[m[1]];
+if(typeof f!="string"){f=jQuery.expr[m[1]][m[2]];
+}f=eval("false||function(a,i){return "+f+"}");
+r=jQuery.grep(r,f,not);
+}}}}}return{r:r,t:t};
+},dir:function(elem,dir){var matched=[];
+var cur=elem[dir];
+while(cur&&cur!=document){if(cur.nodeType==1){matched.push(cur);
+}cur=cur[dir];
+}return matched;
+},nth:function(cur,result,dir,elem){result=result||1;
+var num=0;
+for(;
+cur;
+cur=cur[dir]){if(cur.nodeType==1&&++num==result){break;
+}}return cur;
+},sibling:function(n,elem){var r=[];
+for(;
+n;
+n=n.nextSibling){if(n.nodeType==1&&(!elem||n!=elem)){r.push(n);
+}}return r;
+}});
+jQuery.event={add:function(element,type,handler,data){if(jQuery.browser.msie&&element.setInterval!=undefined){element=window;
+}if(!handler.guid){handler.guid=this.guid++;
+}if(data!=undefined){var fn=handler;
+handler=function(){return fn.apply(this,arguments);
+};
+handler.data=data;
+handler.guid=fn.guid;
+}var parts=type.split(".");
+type=parts[0];
+handler.type=parts[1];
+var events=jQuery.data(element,"events")||jQuery.data(element,"events",{});
+var handle=jQuery.data(element,"handle",function(){var val;
+if(typeof jQuery=="undefined"||jQuery.event.triggered){return val;
+}val=jQuery.event.handle.apply(element,arguments);
+return val;
+});
+var handlers=events[type];
+if(!handlers){handlers=events[type]={};
+if(element.addEventListener){element.addEventListener(type,handle,false);
+}else{element.attachEvent("on"+type,handle);
+}}handlers[handler.guid]=handler;
+this.global[type]=true;
+},guid:1,global:{},remove:function(element,type,handler){var events=jQuery.data(element,"events"),ret,index;
+if(typeof type=="string"){var parts=type.split(".");
+type=parts[0];
+}if(events){if(type&&type.type){handler=type.handler;
+type=type.type;
+}if(!type){for(type in events){this.remove(element,type);
+}}else{if(events[type]){if(handler){delete events[type][handler.guid];
+}else{for(handler in events[type]){if(!parts[1]||events[type][handler].type==parts[1]){delete events[type][handler];
+}}}for(ret in events[type]){break;
+}if(!ret){if(element.removeEventListener){element.removeEventListener(type,jQuery.data(element,"handle"),false);
+}else{element.detachEvent("on"+type,jQuery.data(element,"handle"));
+}ret=null;
+delete events[type];
+}}}for(ret in events){break;
+}if(!ret){jQuery.removeData(element,"events");
+jQuery.removeData(element,"handle");
+}}},trigger:function(type,data,element,donative,extra){data=jQuery.makeArray(data||[]);
+if(!element){if(this.global[type]){jQuery("*").add([window,document]).trigger(type,data);
+}}else{var val,ret,fn=jQuery.isFunction(element[type]||null),evt=!data[0]||!data[0].preventDefault;
+if(evt){data.unshift(this.fix({type:type,target:element}));
+}data[0].type=type;
+if(jQuery.isFunction(jQuery.data(element,"handle"))){val=jQuery.data(element,"handle").apply(element,data);
+}if(!fn&&element["on"+type]&&element["on"+type].apply(element,data)===false){val=false;
+}if(evt){data.shift();
+}if(extra&&extra.apply(element,data)===false){val=false;
+}if(fn&&donative!==false&&val!==false&&!(jQuery.nodeName(element,"a")&&type=="click")){this.triggered=true;
+element[type]();
+}this.triggered=false;
+}return val;
+},handle:function(event){var val;
+event=jQuery.event.fix(event||window.event||{});
+var parts=event.type.split(".");
+event.type=parts[0];
+var c=jQuery.data(this,"events")&&jQuery.data(this,"events")[event.type],args=Array.prototype.slice.call(arguments,1);
+args.unshift(event);
+for(var j in c){args[0].handler=c[j];
+args[0].data=c[j].data;
+if(!parts[1]||c[j].type==parts[1]){var tmp=c[j].apply(this,args);
+if(val!==false){val=tmp;
+}if(tmp===false){event.preventDefault();
+event.stopPropagation();
+}}}if(jQuery.browser.msie){event.target=event.preventDefault=event.stopPropagation=event.handler=event.data=null;
+}return val;
+},fix:function(event){var originalEvent=event;
+event=jQuery.extend({},originalEvent);
+event.preventDefault=function(){if(originalEvent.preventDefault){originalEvent.preventDefault();
+}originalEvent.returnValue=false;
+};
+event.stopPropagation=function(){if(originalEvent.stopPropagation){originalEvent.stopPropagation();
+}originalEvent.cancelBubble=true;
+};
+if(!event.target&&event.srcElement){event.target=event.srcElement;
+}if(jQuery.browser.safari&&event.target.nodeType==3){event.target=originalEvent.target.parentNode;
+}if(!event.relatedTarget&&event.fromElement){event.relatedTarget=event.fromElement==event.target?event.toElement:event.fromElement;
+}if(event.pageX==null&&event.clientX!=null){var e=document.documentElement,b=document.body;
+event.pageX=event.clientX+(e&&e.scrollLeft||b.scrollLeft||0);
+event.pageY=event.clientY+(e&&e.scrollTop||b.scrollTop||0);
+}if(!event.which&&(event.charCode||event.keyCode)){event.which=event.charCode||event.keyCode;
+}if(!event.metaKey&&event.ctrlKey){event.metaKey=event.ctrlKey;
+}if(!event.which&&event.button){event.which=(event.button&1?1:(event.button&2?3:(event.button&4?2:0)));
+}return event;
+}};
+jQuery.fn.extend({bind:function(type,data,fn){return type=="unload"?this.one(type,data,fn):this.each(function(){jQuery.event.add(this,type,fn||data,fn&&data);
+});
+},one:function(type,data,fn){return this.each(function(){jQuery.event.add(this,type,function(event){jQuery(this).unbind(event);
+return(fn||data).apply(this,arguments);
+},fn&&data);
+});
+},unbind:function(type,fn){return this.each(function(){jQuery.event.remove(this,type,fn);
+});
+},trigger:function(type,data,fn){return this.each(function(){jQuery.event.trigger(type,data,this,true,fn);
+});
+},triggerHandler:function(type,data,fn){if(this[0]){return jQuery.event.trigger(type,data,this[0],false,fn);
+}},toggle:function(){var a=arguments;
+return this.click(function(e){this.lastToggle=0==this.lastToggle?1:0;
+e.preventDefault();
+return a[this.lastToggle].apply(this,[e])||false;
+});
+},hover:function(f,g){function handleHover(e){var p=e.relatedTarget;
+while(p&&p!=this){try{p=p.parentNode;
+}catch(e){p=this;
+}}if(p==this){return false;
+}return(e.type=="mouseover"?f:g).apply(this,[e]);
+}return this.mouseover(handleHover).mouseout(handleHover);
+},ready:function(f){bindReady();
+if(jQuery.isReady){f.apply(document,[jQuery]);
+}else{jQuery.readyList.push(function(){return f.apply(this,[jQuery]);
+});
+}return this;
+}});
+jQuery.extend({isReady:false,readyList:[],ready:function(){if(!jQuery.isReady){jQuery.isReady=true;
+if(jQuery.readyList){jQuery.each(jQuery.readyList,function(){this.apply(document);
+});
+jQuery.readyList=null;
+}if(jQuery.browser.mozilla||jQuery.browser.opera){document.removeEventListener("DOMContentLoaded",jQuery.ready,false);
+}if(!window.frames.length){jQuery(window).load(function(){jQuery("#__ie_init").remove();
+});
+}}}});
+jQuery.each(("blur,focus,load,resize,scroll,unload,click,dblclick,mousedown,mouseup,mousemove,mouseover,mouseout,change,select,submit,keydown,keypress,keyup,error").split(","),function(i,o){jQuery.fn[o]=function(f){return f?this.bind(o,f):this.trigger(o);
+};
+});
+var readyBound=false;
+function bindReady(){if(readyBound){return ;
+}readyBound=true;
+if(jQuery.browser.mozilla||jQuery.browser.opera){document.addEventListener("DOMContentLoaded",jQuery.ready,false);
+}else{if(jQuery.browser.msie){document.write("<script id=__ie_init defer=true src=//:><\/script>");
+var script=document.getElementById("__ie_init");
+if(script){script.onreadystatechange=function(){if(this.readyState!="complete"){return ;
+}jQuery.ready();
+};
+}script=null;
+}else{if(jQuery.browser.safari){jQuery.safariTimer=setInterval(function(){if(document.readyState=="loaded"||document.readyState=="complete"){clearInterval(jQuery.safariTimer);
+jQuery.safariTimer=null;
+jQuery.ready();
+}},10);
+}}}jQuery.event.add(window,"load",jQuery.ready);
+}jQuery.fn.extend({load:function(url,params,callback){if(jQuery.isFunction(url)){return this.bind("load",url);
+}var off=url.indexOf(" ");
+if(off>=0){var selector=url.slice(off,url.length);
+url=url.slice(0,off);
+}callback=callback||function(){};
+var type="GET";
+if(params){if(jQuery.isFunction(params)){callback=params;
+params=null;
+}else{params=jQuery.param(params);
+type="POST";
+}}var self=this;
+jQuery.ajax({url:url,type:type,data:params,complete:function(res,status){if(status=="success"||status=="notmodified"){self.html(selector?jQuery("<div/>").append(res.responseText.replace(/<script(.|\s)*?\/script>/g,"")).find(selector):res.responseText);
+}setTimeout(function(){self.each(callback,[res.responseText,status,res]);
+},13);
+}});
+return this;
+},serialize:function(){return jQuery.param(this.serializeArray());
+},serializeArray:function(){return this.map(function(){return jQuery.nodeName(this,"form")?jQuery.makeArray(this.elements):this;
+}).filter(function(){return this.name&&!this.disabled&&(this.checked||/select|textarea/i.test(this.nodeName)||/text|hidden|password/i.test(this.type));
+}).map(function(i,elem){var val=jQuery(this).val();
+return val==null?null:val.constructor==Array?jQuery.map(val,function(val,i){return{name:elem.name,value:val};
+}):{name:elem.name,value:val};
+}).get();
+}});
+jQuery.each("ajaxStart,ajaxStop,ajaxComplete,ajaxError,ajaxSuccess,ajaxSend".split(","),function(i,o){jQuery.fn[o]=function(f){return this.bind(o,f);
+};
+});
+var jsc=(new Date).getTime();
+jQuery.extend({get:function(url,data,callback,type){if(jQuery.isFunction(data)){callback=data;
+data=null;
+}return jQuery.ajax({type:"GET",url:url,data:data,success:callback,dataType:type});
+},getScript:function(url,callback){return jQuery.get(url,null,callback,"script");
+},getJSON:function(url,data,callback){return jQuery.get(url,data,callback,"json");
+},post:function(url,data,callback,type){if(jQuery.isFunction(data)){callback=data;
+data={};
+}return jQuery.ajax({type:"POST",url:url,data:data,success:callback,dataType:type});
+},ajaxSetup:function(settings){jQuery.extend(jQuery.ajaxSettings,settings);
+},ajaxSettings:{global:true,type:"GET",timeout:0,contentType:"application/x-www-form-urlencoded",processData:true,async:true,data:null},lastModified:{},ajax:function(s){var jsonp,jsre=/=(\?|%3F)/g,status,data;
+s=jQuery.extend(true,s,jQuery.extend(true,{},jQuery.ajaxSettings,s));
+if(s.data&&s.processData&&typeof s.data!="string"){s.data=jQuery.param(s.data);
+}if(s.dataType=="jsonp"){if(s.type.toLowerCase()=="get"){if(!s.url.match(jsre)){s.url+=(s.url.match(/\?/)?"&":"?")+(s.jsonp||"callback")+"=?";
+}}else{if(!s.data||!s.data.match(jsre)){s.data=(s.data?s.data+"&":"")+(s.jsonp||"callback")+"=?";
+}}s.dataType="json";
+}if(s.dataType=="json"&&(s.data&&s.data.match(jsre)||s.url.match(jsre))){jsonp="jsonp"+jsc++;
+if(s.data){s.data=s.data.replace(jsre,"="+jsonp);
+}s.url=s.url.replace(jsre,"="+jsonp);
+s.dataType="script";
+window[jsonp]=function(tmp){data=tmp;
+success();
+complete();
+window[jsonp]=undefined;
+try{delete window[jsonp];
+}catch(e){}};
+}if(s.dataType=="script"&&s.cache==null){s.cache=false;
+}if(s.cache===false&&s.type.toLowerCase()=="get"){s.url+=(s.url.match(/\?/)?"&":"?")+"_="+(new Date()).getTime();
+}if(s.data&&s.type.toLowerCase()=="get"){s.url+=(s.url.match(/\?/)?"&":"?")+s.data;
+s.data=null;
+}if(s.global&&!jQuery.active++){jQuery.event.trigger("ajaxStart");
+}if(!s.url.indexOf("http")&&s.dataType=="script"){var head=document.getElementsByTagName("head")[0];
+var script=document.createElement("script");
+script.src=s.url;
+if(!jsonp&&(s.success||s.complete)){var done=false;
+script.onload=script.onreadystatechange=function(){if(!done&&(!this.readyState||this.readyState=="loaded"||this.readyState=="complete")){done=true;
+success();
+complete();
+head.removeChild(script);
+}};
+}head.appendChild(script);
+return ;
+}var requestDone=false;
+var xml=window.ActiveXObject?new ActiveXObject("Microsoft.XMLHTTP"):new XMLHttpRequest();
+xml.open(s.type,s.url,s.async);
+if(s.data){xml.setRequestHeader("Content-Type",s.contentType);
+}if(s.ifModified){xml.setRequestHeader("If-Modified-Since",jQuery.lastModified[s.url]||"Thu, 01 Jan 1970 00:00:00 GMT");
+}xml.setRequestHeader("X-Requested-With","XMLHttpRequest");
+if(s.beforeSend){s.beforeSend(xml);
+}if(s.global){jQuery.event.trigger("ajaxSend",[xml,s]);
+}var onreadystatechange=function(isTimeout){if(!requestDone&&xml&&(xml.readyState==4||isTimeout=="timeout")){requestDone=true;
+if(ival){clearInterval(ival);
+ival=null;
+}status=isTimeout=="timeout"&&"timeout"||!jQuery.httpSuccess(xml)&&"error"||s.ifModified&&jQuery.httpNotModified(xml,s.url)&&"notmodified"||"success";
+if(status=="success"){try{data=jQuery.httpData(xml,s.dataType);
+}catch(e){status="parsererror";
+}}if(status=="success"){var modRes;
+try{modRes=xml.getResponseHeader("Last-Modified");
+}catch(e){}if(s.ifModified&&modRes){jQuery.lastModified[s.url]=modRes;
+}if(!jsonp){success();
+}}else{jQuery.handleError(s,xml,status);
+}complete();
+if(s.async){xml=null;
+}}};
+if(s.async){var ival=setInterval(onreadystatechange,13);
+if(s.timeout>0){setTimeout(function(){if(xml){xml.abort();
+if(!requestDone){onreadystatechange("timeout");
+}}},s.timeout);
+}}try{xml.send(s.data);
+}catch(e){jQuery.handleError(s,xml,null,e);
+}if(!s.async){onreadystatechange();
+}return xml;
+function success(){if(s.success){s.success(data,status);
+}if(s.global){jQuery.event.trigger("ajaxSuccess",[xml,s]);
+}}function complete(){if(s.complete){s.complete(xml,status);
+}if(s.global){jQuery.event.trigger("ajaxComplete",[xml,s]);
+}if(s.global&&!--jQuery.active){jQuery.event.trigger("ajaxStop");
+}}},handleError:function(s,xml,status,e){if(s.error){s.error(xml,status,e);
+}if(s.global){jQuery.event.trigger("ajaxError",[xml,s,e]);
+}},active:0,httpSuccess:function(r){try{return !r.status&&location.protocol=="file:"||(r.status>=200&&r.status<300)||r.status==304||jQuery.browser.safari&&r.status==undefined;
+}catch(e){}return false;
+},httpNotModified:function(xml,url){try{var xmlRes=xml.getResponseHeader("Last-Modified");
+return xml.status==304||xmlRes==jQuery.lastModified[url]||jQuery.browser.safari&&xml.status==undefined;
+}catch(e){}return false;
+},httpData:function(r,type){var ct=r.getResponseHeader("content-type");
+var xml=type=="xml"||!type&&ct&&ct.indexOf("xml")>=0;
+var data=xml?r.responseXML:r.responseText;
+if(xml&&data.documentElement.tagName=="parsererror"){throw"parsererror";
+}if(type=="script"){jQuery.globalEval(data);
+}if(type=="json"){data=eval("("+data+")");
+}return data;
+},param:function(a){var s=[];
+if(a.constructor==Array||a.jquery){jQuery.each(a,function(){s.push(encodeURIComponent(this.name)+"="+encodeURIComponent(this.value));
+});
+}else{for(var j in a){if(a[j]&&a[j].constructor==Array){jQuery.each(a[j],function(){s.push(encodeURIComponent(j)+"="+encodeURIComponent(this));
+});
+}else{s.push(encodeURIComponent(j)+"="+encodeURIComponent(a[j]));
+}}}return s.join("&").replace(/%20/g,"+");
+}});
+jQuery.fn.extend({show:function(speed,callback){return speed?this.animate({height:"show",width:"show",opacity:"show"},speed,callback):this.filter(":hidden").each(function(){this.style.display=this.oldblock?this.oldblock:"";
+if(jQuery.css(this,"display")=="none"){this.style.display="block";
+}}).end();
+},hide:function(speed,callback){return speed?this.animate({height:"hide",width:"hide",opacity:"hide"},speed,callback):this.filter(":visible").each(function(){this.oldblock=this.oldblock||jQuery.css(this,"display");
+if(this.oldblock=="none"){this.oldblock="block";
+}this.style.display="none";
+}).end();
+},_toggle:jQuery.fn.toggle,toggle:function(fn,fn2){return jQuery.isFunction(fn)&&jQuery.isFunction(fn2)?this._toggle(fn,fn2):fn?this.animate({height:"toggle",width:"toggle",opacity:"toggle"},fn,fn2):this.each(function(){jQuery(this)[jQuery(this).is(":hidden")?"show":"hide"]();
+});
+},slideDown:function(speed,callback){return this.animate({height:"show"},speed,callback);
+},slideUp:function(speed,callback){return this.animate({height:"hide"},speed,callback);
+},slideToggle:function(speed,callback){return this.animate({height:"toggle"},speed,callback);
+},fadeIn:function(speed,callback){return this.animate({opacity:"show"},speed,callback);
+},fadeOut:function(speed,callback){return this.animate({opacity:"hide"},speed,callback);
+},fadeTo:function(speed,to,callback){return this.animate({opacity:to},speed,callback);
+},animate:function(prop,speed,easing,callback){var opt=jQuery.speed(speed,easing,callback);
+return this[opt.queue===false?"each":"queue"](function(){opt=jQuery.extend({},opt);
+var hidden=jQuery(this).is(":hidden"),self=this;
+for(var p in prop){if(prop[p]=="hide"&&hidden||prop[p]=="show"&&!hidden){return jQuery.isFunction(opt.complete)&&opt.complete.apply(this);
+}if(p=="height"||p=="width"){opt.display=jQuery.css(this,"display");
+opt.overflow=this.style.overflow;
+}}if(opt.overflow!=null){this.style.overflow="hidden";
+}opt.curAnim=jQuery.extend({},prop);
+jQuery.each(prop,function(name,val){var e=new jQuery.fx(self,opt,name);
+if(/toggle|show|hide/.test(val)){e[val=="toggle"?hidden?"show":"hide":val](prop);
+}else{var parts=val.toString().match(/^([+-]=)?([\d+-.]+)(.*)$/),start=e.cur(true)||0;
+if(parts){var end=parseFloat(parts[2]),unit=parts[3]||"px";
+if(unit!="px"){self.style[name]=(end||1)+unit;
+start=((end||1)/e.cur(true))*start;
+self.style[name]=start+unit;
+}if(parts[1]){end=((parts[1]=="-="?-1:1)*end)+start;
+}e.custom(start,end,unit);
+}else{e.custom(start,val,"");
+}}});
+return true;
+});
+},queue:function(type,fn){if(jQuery.isFunction(type)){fn=type;
+type="fx";
+}if(!type||(typeof type=="string"&&!fn)){return queue(this[0],type);
+}return this.each(function(){if(fn.constructor==Array){queue(this,type,fn);
+}else{queue(this,type).push(fn);
+if(queue(this,type).length==1){fn.apply(this);
+}}});
+},stop:function(){var timers=jQuery.timers;
+return this.each(function(){for(var i=0;
+i<timers.length;
+i++){if(timers[i].elem==this){timers.splice(i--,1);
+}}}).dequeue();
+}});
+var queue=function(elem,type,array){if(!elem){return ;
+}var q=jQuery.data(elem,type+"queue");
+if(!q||array){q=jQuery.data(elem,type+"queue",array?jQuery.makeArray(array):[]);
+}return q;
+};
+jQuery.fn.dequeue=function(type){type=type||"fx";
+return this.each(function(){var q=queue(this,type);
+q.shift();
+if(q.length){q[0].apply(this);
+}});
+};
+jQuery.extend({speed:function(speed,easing,fn){var opt=speed&&speed.constructor==Object?speed:{complete:fn||!fn&&easing||jQuery.isFunction(speed)&&speed,duration:speed,easing:fn&&easing||easing&&easing.constructor!=Function&&easing};
+opt.duration=(opt.duration&&opt.duration.constructor==Number?opt.duration:{slow:600,fast:200}[opt.duration])||400;
+opt.old=opt.complete;
+opt.complete=function(){jQuery(this).dequeue();
+if(jQuery.isFunction(opt.old)){opt.old.apply(this);
+}};
+return opt;
+},easing:{linear:function(p,n,firstNum,diff){return firstNum+diff*p;
+},swing:function(p,n,firstNum,diff){return((-Math.cos(p*Math.PI)/2)+0.5)*diff+firstNum;
+}},timers:[],fx:function(elem,options,prop){this.options=options;
+this.elem=elem;
+this.prop=prop;
+if(!options.orig){options.orig={};
+}}});
+jQuery.fx.prototype={update:function(){if(this.options.step){this.options.step.apply(this.elem,[this.now,this]);
+}(jQuery.fx.step[this.prop]||jQuery.fx.step._default)(this);
+if(this.prop=="height"||this.prop=="width"){this.elem.style.display="block";
+}},cur:function(force){if(this.elem[this.prop]!=null&&this.elem.style[this.prop]==null){return this.elem[this.prop];
+}var r=parseFloat(jQuery.curCSS(this.elem,this.prop,force));
+return r&&r>-10000?r:parseFloat(jQuery.css(this.elem,this.prop))||0;
+},custom:function(from,to,unit){this.startTime=(new Date()).getTime();
+this.start=from;
+this.end=to;
+this.unit=unit||this.unit||"px";
+this.now=this.start;
+this.pos=this.state=0;
+this.update();
+var self=this;
+function t(){return self.step();
+}t.elem=this.elem;
+jQuery.timers.push(t);
+if(jQuery.timers.length==1){var timer=setInterval(function(){var timers=jQuery.timers;
+for(var i=0;
+i<timers.length;
+i++){if(!timers[i]()){timers.splice(i--,1);
+}}if(!timers.length){clearInterval(timer);
+}},13);
+}},show:function(){this.options.orig[this.prop]=jQuery.attr(this.elem.style,this.prop);
+this.options.show=true;
+this.custom(0,this.cur());
+if(this.prop=="width"||this.prop=="height"){this.elem.style[this.prop]="1px";
+}jQuery(this.elem).show();
+},hide:function(){this.options.orig[this.prop]=jQuery.attr(this.elem.style,this.prop);
+this.options.hide=true;
+this.custom(this.cur(),0);
+},step:function(){var t=(new Date()).getTime();
+if(t>this.options.duration+this.startTime){this.now=this.end;
+this.pos=this.state=1;
+this.update();
+this.options.curAnim[this.prop]=true;
+var done=true;
+for(var i in this.options.curAnim){if(this.options.curAnim[i]!==true){done=false;
+}}if(done){if(this.options.display!=null){this.elem.style.overflow=this.options.overflow;
+this.elem.style.display=this.options.display;
+if(jQuery.css(this.elem,"display")=="none"){this.elem.style.display="block";
+}}if(this.options.hide){this.elem.style.display="none";
+}if(this.options.hide||this.options.show){for(var p in this.options.curAnim){jQuery.attr(this.elem.style,p,this.options.orig[p]);
+}}}if(done&&jQuery.isFunction(this.options.complete)){this.options.complete.apply(this.elem);
+}return false;
+}else{var n=t-this.startTime;
+this.state=n/this.options.duration;
+this.pos=jQuery.easing[this.options.easing||(jQuery.easing.swing?"swing":"linear")](this.state,n,0,1,this.options.duration);
+this.now=this.start+((this.end-this.start)*this.pos);
+this.update();
+}return true;
+}};
+jQuery.fx.step={scrollLeft:function(fx){fx.elem.scrollLeft=fx.now;
+},scrollTop:function(fx){fx.elem.scrollTop=fx.now;
+},opacity:function(fx){jQuery.attr(fx.elem.style,"opacity",fx.now);
+},_default:function(fx){fx.elem.style[fx.prop]=fx.now+fx.unit;
+}};
+jQuery.fn.offset=function(){var left=0,top=0,elem=this[0],results;
+if(elem){with(jQuery.browser){var absolute=jQuery.css(elem,"position")=="absolute",parent=elem.parentNode,offsetParent=elem.offsetParent,doc=elem.ownerDocument,safari2=safari&&parseInt(version)<522;
+if(elem.getBoundingClientRect){box=elem.getBoundingClientRect();
+add(box.left+Math.max(doc.documentElement.scrollLeft,doc.body.scrollLeft),box.top+Math.max(doc.documentElement.scrollTop,doc.body.scrollTop));
+if(msie){var border=jQuery("html").css("borderWidth");
+border=(border=="medium"||jQuery.boxModel&&parseInt(version)>=7)&&2||border;
+add(-border,-border);
+}}else{add(elem.offsetLeft,elem.offsetTop);
+while(offsetParent){add(offsetParent.offsetLeft,offsetParent.offsetTop);
+if(mozilla&&/^t[d|h]$/i.test(parent.tagName)||!safari2){border(offsetParent);
+}if(safari2&&!absolute&&jQuery.css(offsetParent,"position")=="absolute"){absolute=true;
+}offsetParent=offsetParent.offsetParent;
+}while(parent.tagName&&!/^body|html$/i.test(parent.tagName)){if(!/^inline|table-row.*$/i.test(jQuery.css(parent,"display"))){add(-parent.scrollLeft,-parent.scrollTop);
+}if(mozilla&&jQuery.css(parent,"overflow")!="visible"){border(parent);
+}parent=parent.parentNode;
+}if(safari2&&absolute){add(-doc.body.offsetLeft,-doc.body.offsetTop);
+}}results={top:top,left:left};
+}}return results;
+function border(elem){add(jQuery.css(elem,"borderLeftWidth"),jQuery.css(elem,"borderTopWidth"));
+}function add(l,t){left+=parseInt(l)||0;
+top+=parseInt(t)||0;
+}};
+})();
+
+
+/* json.js */
+SimileAjax.JSON=new Object();
+(function(){var m={"\b":"\\b","\t":"\\t","\n":"\\n","\f":"\\f","\r":"\\r",'"':'\\"',"\\":"\\\\"};
+var s={array:function(x){var a=["["],b,f,i,l=x.length,v;
+for(i=0;
+i<l;
+i+=1){v=x[i];
+f=s[typeof v];
+if(f){v=f(v);
+if(typeof v=="string"){if(b){a[a.length]=",";
+}a[a.length]=v;
+b=true;
+}}}a[a.length]="]";
+return a.join("");
+},"boolean":function(x){return String(x);
+},"null":function(x){return"null";
+},number:function(x){return isFinite(x)?String(x):"null";
+},object:function(x){if(x){if(x instanceof Array){return s.array(x);
+}var a=["{"],b,f,i,v;
+for(i in x){v=x[i];
+f=s[typeof v];
+if(f){v=f(v);
+if(typeof v=="string"){if(b){a[a.length]=",";
+}a.push(s.string(i),":",v);
+b=true;
+}}}a[a.length]="}";
+return a.join("");
+}return"null";
+},string:function(x){if(/["\\\x00-\x1f]/.test(x)){x=x.replace(/([\x00-\x1f\\"])/g,function(a,b){var c=m[b];
+if(c){return c;
+}c=b.charCodeAt();
+return"\\u00"+Math.floor(c/16).toString(16)+(c%16).toString(16);
+});
+}return'"'+x+'"';
+}};
+SimileAjax.JSON.toJSONString=function(o){if(o instanceof Object){return s.object(o);
+}else{if(o instanceof Array){return s.array(o);
+}else{return o.toString();
+}}};
+SimileAjax.JSON.parseJSON=function(){try{return !(/[^,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]/.test(this.replace(/"(\\.|[^"\\])*"/g,"")))&&eval("("+this+")");
+}catch(e){return false;
+}};
+})();
+
+
+/* string.js */
+String.prototype.trim=function(){return this.replace(/^\s+|\s+$/g,"");
+};
+String.prototype.startsWith=function(A){return this.length>=A.length&&this.substr(0,A.length)==A;
+};
+String.prototype.endsWith=function(A){return this.length>=A.length&&this.substr(this.length-A.length)==A;
+};
+String.substitute=function(B,D){var A="";
+var F=0;
+while(F<B.length-1){var C=B.indexOf("%",F);
+if(C<0||C==B.length-1){break;
+}else{if(C>F&&B.charAt(C-1)=="\\"){A+=B.substring(F,C-1)+"%";
+F=C+1;
+}else{var E=parseInt(B.charAt(C+1));
+if(isNaN(E)||E>=D.length){A+=B.substring(F,C+2);
+}else{A+=B.substring(F,C)+D[E].toString();
+}F=C+2;
+}}}if(F<B.length){A+=B.substring(F);
+}return A;
+};
+
+
+/* units.js */
+SimileAjax.NativeDateUnit=new Object();
+SimileAjax.NativeDateUnit.makeDefaultValue=function(){return new Date();
+};
+SimileAjax.NativeDateUnit.cloneValue=function(A){return new Date(A.getTime());
+};
+SimileAjax.NativeDateUnit.getParser=function(A){if(typeof A=="string"){A=A.toLowerCase();
+}return(A=="iso8601"||A=="iso 8601")?SimileAjax.DateTime.parseIso8601DateTime:SimileAjax.DateTime.parseGregorianDateTime;
+};
+SimileAjax.NativeDateUnit.parseFromObject=function(A){return SimileAjax.DateTime.parseGregorianDateTime(A);
+};
+SimileAjax.NativeDateUnit.toNumber=function(A){return A.getTime();
+};
+SimileAjax.NativeDateUnit.fromNumber=function(A){return new Date(A);
+};
+SimileAjax.NativeDateUnit.compare=function(D,C){var B,A;
+if(typeof D=="object"){B=D.getTime();
+}else{B=Number(D);
+}if(typeof C=="object"){A=C.getTime();
+}else{A=Number(C);
+}return B-A;
+};
+SimileAjax.NativeDateUnit.earlier=function(B,A){return SimileAjax.NativeDateUnit.compare(B,A)<0?B:A;
+};
+SimileAjax.NativeDateUnit.later=function(B,A){return SimileAjax.NativeDateUnit.compare(B,A)>0?B:A;
+};
+SimileAjax.NativeDateUnit.change=function(A,B){return new Date(A.getTime()+B);
+};
+
+
+/* window-manager.js */
+SimileAjax.WindowManager={_initialized:false,_listeners:[],_draggedElement:null,_draggedElementCallback:null,_dropTargetHighlightElement:null,_lastCoords:null,_ghostCoords:null,_draggingMode:"",_dragging:false,_layers:[]};
+SimileAjax.WindowManager.initialize=function(){if(SimileAjax.WindowManager._initialized){return ;
+}SimileAjax.DOM.registerEvent(document.body,"mousedown",SimileAjax.WindowManager._onBodyMouseDown);
+SimileAjax.DOM.registerEvent(document.body,"mousemove",SimileAjax.WindowManager._onBodyMouseMove);
+SimileAjax.DOM.registerEvent(document.body,"mouseup",SimileAjax.WindowManager._onBodyMouseUp);
+SimileAjax.DOM.registerEvent(document,"keydown",SimileAjax.WindowManager._onBodyKeyDown);
+SimileAjax.DOM.registerEvent(document,"keyup",SimileAjax.WindowManager._onBodyKeyUp);
+SimileAjax.WindowManager._layers.push({index:0});
+SimileAjax.WindowManager._historyListener={onBeforeUndoSeveral:function(){},onAfterUndoSeveral:function(){},onBeforeUndo:function(){},onAfterUndo:function(){},onBeforeRedoSeveral:function(){},onAfterRedoSeveral:function(){},onBeforeRedo:function(){},onAfterRedo:function(){}};
+SimileAjax.History.addListener(SimileAjax.WindowManager._historyListener);
+SimileAjax.WindowManager._initialized=true;
+};
+SimileAjax.WindowManager.getBaseLayer=function(){SimileAjax.WindowManager.initialize();
+return SimileAjax.WindowManager._layers[0];
+};
+SimileAjax.WindowManager.getHighestLayer=function(){SimileAjax.WindowManager.initialize();
+return SimileAjax.WindowManager._layers[SimileAjax.WindowManager._layers.length-1];
+};
+SimileAjax.WindowManager.registerEventWithObject=function(D,A,E,B,C){SimileAjax.WindowManager.registerEvent(D,A,function(G,F,H){return E[B].call(E,G,F,H);
+},C);
+};
+SimileAjax.WindowManager.registerEvent=function(D,B,E,C){if(C==null){C=SimileAjax.WindowManager.getHighestLayer();
+}var A=function(G,F,I){if(SimileAjax.WindowManager._canProcessEventAtLayer(C)){SimileAjax.WindowManager._popToLayer(C.index);
+try{E(G,F,I);
+}catch(H){SimileAjax.Debug.exception(H);
+}}SimileAjax.DOM.cancelEvent(F);
+return false;
+};
+SimileAjax.DOM.registerEvent(D,B,A);
+};
+SimileAjax.WindowManager.pushLayer=function(C,D,B){var A={onPop:C,index:SimileAjax.WindowManager._layers.length,ephemeral:(D),elmt:B};
+SimileAjax.WindowManager._layers.push(A);
+return A;
+};
+SimileAjax.WindowManager.popLayer=function(B){for(var A=1;
+A<SimileAjax.WindowManager._layers.length;
+A++){if(SimileAjax.WindowManager._layers[A]==B){SimileAjax.WindowManager._popToLayer(A-1);
+break;
+}}};
+SimileAjax.WindowManager.popAllLayers=function(){SimileAjax.WindowManager._popToLayer(0);
+};
+SimileAjax.WindowManager.registerForDragging=function(B,C,A){SimileAjax.WindowManager.registerEvent(B,"mousedown",function(E,D,F){SimileAjax.WindowManager._handleMouseDown(E,D,C);
+},A);
+};
+SimileAjax.WindowManager._popToLayer=function(C){while(C+1<SimileAjax.WindowManager._layers.length){try{var A=SimileAjax.WindowManager._layers.pop();
+if(A.onPop!=null){A.onPop();
+}}catch(B){}}};
+SimileAjax.WindowManager._canProcessEventAtLayer=function(B){if(B.index==(SimileAjax.WindowManager._layers.length-1)){return true;
+}for(var A=B.index+1;
+A<SimileAjax.WindowManager._layers.length;
+A++){if(!SimileAjax.WindowManager._layers[A].ephemeral){return false;
+}}return true;
+};
+SimileAjax.WindowManager.cancelPopups=function(A){var F=(A)?SimileAjax.DOM.getEventPageCoordinates(A):{x:-1,y:-1};
+var E=SimileAjax.WindowManager._layers.length-1;
+while(E>0&&SimileAjax.WindowManager._layers[E].ephemeral){var D=SimileAjax.WindowManager._layers[E];
+if(D.elmt!=null){var C=D.elmt;
+var B=SimileAjax.DOM.getPageCoordinates(C);
+if(F.x>=B.left&&F.x<(B.left+C.offsetWidth)&&F.y>=B.top&&F.y<(B.top+C.offsetHeight)){break;
+}}E--;
+}SimileAjax.WindowManager._popToLayer(E);
+};
+SimileAjax.WindowManager._onBodyMouseDown=function(B,A,C){if(!("eventPhase" in A)||A.eventPhase==A.BUBBLING_PHASE){SimileAjax.WindowManager.cancelPopups(A);
+}};
+SimileAjax.WindowManager._handleMouseDown=function(B,A,C){SimileAjax.WindowManager._draggedElement=B;
+SimileAjax.WindowManager._draggedElementCallback=C;
+SimileAjax.WindowManager._lastCoords={x:A.clientX,y:A.clientY};
+SimileAjax.DOM.cancelEvent(A);
+return false;
+};
+SimileAjax.WindowManager._onBodyKeyDown=function(C,A,D){if(SimileAjax.WindowManager._dragging){if(A.keyCode==27){SimileAjax.WindowManager._cancelDragging();
+}else{if((A.keyCode==17||A.keyCode==16)&&SimileAjax.WindowManager._draggingMode!="copy"){SimileAjax.WindowManager._draggingMode="copy";
+var B=SimileAjax.Graphics.createTranslucentImage(SimileAjax.urlPrefix+"images/copy.png");
+B.style.position="absolute";
+B.style.left=(SimileAjax.WindowManager._ghostCoords.left-16)+"px";
+B.style.top=(SimileAjax.WindowManager._ghostCoords.top)+"px";
+document.body.appendChild(B);
+SimileAjax.WindowManager._draggingModeIndicatorElmt=B;
+}}}};
+SimileAjax.WindowManager._onBodyKeyUp=function(B,A,C){if(SimileAjax.WindowManager._dragging){if(A.keyCode==17||A.keyCode==16){SimileAjax.WindowManager._draggingMode="";
+if(SimileAjax.WindowManager._draggingModeIndicatorElmt!=null){document.body.removeChild(SimileAjax.WindowManager._draggingModeIndicatorElmt);
+SimileAjax.WindowManager._draggingModeIndicatorElmt=null;
+}}}};
+SimileAjax.WindowManager._onBodyMouseMove=function(A,N,H){if(SimileAjax.WindowManager._draggedElement!=null){var P=SimileAjax.WindowManager._draggedElementCallback;
+var E=SimileAjax.WindowManager._lastCoords;
+var M=N.clientX-E.x;
+var J=N.clientY-E.y;
+if(!SimileAjax.WindowManager._dragging){if(Math.abs(M)>5||Math.abs(J)>5){try{if("onDragStart" in P){P.onDragStart();
+}if("ghost" in P&&P.ghost){var K=SimileAjax.WindowManager._draggedElement;
+SimileAjax.WindowManager._ghostCoords=SimileAjax.DOM.getPageCoordinates(K);
+SimileAjax.WindowManager._ghostCoords.left+=M;
+SimileAjax.WindowManager._ghostCoords.top+=J;
+var O=K.cloneNode(true);
+O.style.position="absolute";
+O.style.left=SimileAjax.WindowManager._ghostCoords.left+"px";
+O.style.top=SimileAjax.WindowManager._ghostCoords.top+"px";
+O.style.zIndex=1000;
+SimileAjax.Graphics.setOpacity(O,50);
+document.body.appendChild(O);
+P._ghostElmt=O;
+}SimileAjax.WindowManager._dragging=true;
+SimileAjax.WindowManager._lastCoords={x:N.clientX,y:N.clientY};
+document.body.focus();
+}catch(G){SimileAjax.Debug.exception("WindowManager: Error handling mouse down",G);
+SimileAjax.WindowManager._cancelDragging();
+}}}else{try{SimileAjax.WindowManager._lastCoords={x:N.clientX,y:N.clientY};
+if("onDragBy" in P){P.onDragBy(M,J);
+}if("_ghostElmt" in P){var O=P._ghostElmt;
+SimileAjax.WindowManager._ghostCoords.left+=M;
+SimileAjax.WindowManager._ghostCoords.top+=J;
+O.style.left=SimileAjax.WindowManager._ghostCoords.left+"px";
+O.style.top=SimileAjax.WindowManager._ghostCoords.top+"px";
+if(SimileAjax.WindowManager._draggingModeIndicatorElmt!=null){var I=SimileAjax.WindowManager._draggingModeIndicatorElmt;
+I.style.left=(SimileAjax.WindowManager._ghostCoords.left-16)+"px";
+I.style.top=SimileAjax.WindowManager._ghostCoords.top+"px";
+}if("droppable" in P&&P.droppable){var L=SimileAjax.DOM.getEventPageCoordinates(N);
+var H=SimileAjax.DOM.hittest(L.x,L.y,[SimileAjax.WindowManager._ghostElmt,SimileAjax.WindowManager._dropTargetHighlightElement]);
+H=SimileAjax.WindowManager._findDropTarget(H);
+if(H!=SimileAjax.WindowManager._potentialDropTarget){if(SimileAjax.WindowManager._dropTargetHighlightElement!=null){document.body.removeChild(SimileAjax.WindowManager._dropTargetHighlightElement);
+SimileAjax.WindowManager._dropTargetHighlightElement=null;
+SimileAjax.WindowManager._potentialDropTarget=null;
+}var F=false;
+if(H!=null){if((!("canDropOn" in P)||P.canDropOn(H))&&(!("canDrop" in H)||H.canDrop(SimileAjax.WindowManager._draggedElement))){F=true;
+}}if(F){var C=4;
+var D=SimileAjax.DOM.getPageCoordinates(H);
+var B=document.createElement("div");
+B.style.border=C+"px solid yellow";
+B.style.backgroundColor="yellow";
+B.style.position="absolute";
+B.style.left=D.left+"px";
+B.style.top=D.top+"px";
+B.style.width=(H.offsetWidth-C*2)+"px";
+B.style.height=(H.offsetHeight-C*2)+"px";
+SimileAjax.Graphics.setOpacity(B,30);
+document.body.appendChild(B);
+SimileAjax.WindowManager._potentialDropTarget=H;
+SimileAjax.WindowManager._dropTargetHighlightElement=B;
+}}}}}catch(G){SimileAjax.Debug.exception("WindowManager: Error handling mouse move",G);
+SimileAjax.WindowManager._cancelDragging();
+}}SimileAjax.DOM.cancelEvent(N);
+return false;
+}};
+SimileAjax.WindowManager._onBodyMouseUp=function(B,A,C){if(SimileAjax.WindowManager._draggedElement!=null){try{if(SimileAjax.WindowManager._dragging){var E=SimileAjax.WindowManager._draggedElementCallback;
+if("onDragEnd" in E){E.onDragEnd();
+}if("droppable" in E&&E.droppable){var D=false;
+var C=SimileAjax.WindowManager._potentialDropTarget;
+if(C!=null){if((!("canDropOn" in E)||E.canDropOn(C))&&(!("canDrop" in C)||C.canDrop(SimileAjax.WindowManager._draggedElement))){if("onDropOn" in E){E.onDropOn(C);
+}C.ondrop(SimileAjax.WindowManager._draggedElement,SimileAjax.WindowManager._draggingMode);
+D=true;
+}}if(!D){}}}}finally{SimileAjax.WindowManager._cancelDragging();
+}SimileAjax.DOM.cancelEvent(A);
+return false;
+}};
+SimileAjax.WindowManager._cancelDragging=function(){var B=SimileAjax.WindowManager._draggedElementCallback;
+if("_ghostElmt" in B){var A=B._ghostElmt;
+document.body.removeChild(A);
+delete B._ghostElmt;
+}if(SimileAjax.WindowManager._dropTargetHighlightElement!=null){document.body.removeChild(SimileAjax.WindowManager._dropTargetHighlightElement);
+SimileAjax.WindowManager._dropTargetHighlightElement=null;
+}if(SimileAjax.WindowManager._draggingModeIndicatorElmt!=null){document.body.removeChild(SimileAjax.WindowManager._draggingModeIndicatorElmt);
+SimileAjax.WindowManager._draggingModeIndicatorElmt=null;
+}SimileAjax.WindowManager._draggedElement=null;
+SimileAjax.WindowManager._draggedElementCallback=null;
+SimileAjax.WindowManager._potentialDropTarget=null;
+SimileAjax.WindowManager._dropTargetHighlightElement=null;
+SimileAjax.WindowManager._lastCoords=null;
+SimileAjax.WindowManager._ghostCoords=null;
+SimileAjax.WindowManager._draggingMode="";
+SimileAjax.WindowManager._dragging=false;
+};
+SimileAjax.WindowManager._findDropTarget=function(A){while(A!=null){if("ondrop" in A&&(typeof A.ondrop)=="function"){break;
+}A=A.parentNode;
+}return A;
+};
+
+
+/* xmlhttp.js */
+SimileAjax.XmlHttp=new Object();
+SimileAjax.XmlHttp._onReadyStateChange=function(A,D,B){switch(A.readyState){case 4:try{if(A.status==0||A.status==200){if(B){B(A);
+}}else{if(D){D(A.statusText,A.status,A);
+}}}catch(C){SimileAjax.Debug.exception("XmlHttp: Error handling onReadyStateChange",C);
+}break;
+}};
+SimileAjax.XmlHttp._createRequest=function(){if(SimileAjax.Platform.browser.isIE){var A=["Msxml2.XMLHTTP","Microsoft.XMLHTTP","Msxml2.XMLHTTP.4.0"];
+for(var B=0;
+B<A.length;
+B++){try{var C=A[B];
+var D=function(){return new ActiveXObject(C);
+};
+var F=D();
+SimileAjax.XmlHttp._createRequest=D;
+return F;
+}catch(E){}}}try{var D=function(){return new XMLHttpRequest();
+};
+var F=D();
+SimileAjax.XmlHttp._createRequest=D;
+return F;
+}catch(E){throw new Error("Failed to create an XMLHttpRequest object");
+}};
+SimileAjax.XmlHttp.get=function(A,D,C){var B=SimileAjax.XmlHttp._createRequest();
+B.open("GET",A,true);
+B.onreadystatechange=function(){SimileAjax.XmlHttp._onReadyStateChange(B,D,C);
+};
+B.send(null);
+};
+SimileAjax.XmlHttp.post=function(B,A,E,D){var C=SimileAjax.XmlHttp._createRequest();
+C.open("POST",B,true);
+C.onreadystatechange=function(){SimileAjax.XmlHttp._onReadyStateChange(C,E,D);
+};
+C.send(A);
+};
+SimileAjax.XmlHttp._forceXML=function(A){try{A.overrideMimeType("text/xml");
+}catch(B){A.setrequestheader("Content-Type","text/xml");
+}};
diff --git a/site/app/webroot/js/simile/amo-bundle.compressed.js b/site/app/webroot/js/simile/amo-bundle.compressed.js
new file mode 100644
index 0000000..a042e44
--- /dev/null
+++ b/site/app/webroot/js/simile/amo-bundle.compressed.js
@@ -0,0 +1 @@
+eval(function(p,a,c,k,e,d){e=function(c){return(c<a?'':e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--){d[e(c)]=k[c]||e(c)}k=[function(e){return d[e]}];e=function(){return'\\w+'};c=1};while(c--){if(k[c]){p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c])}}return p}('if(2u D=="5S"){B D={f3:1B,kW:0,fO:N,P:{jH:"1x"}};D.2C=1h 4C();B k8=C(1u){I 1u.iX("kX")[0]};D.vm=C(1u,6B){B kF=1u.68.iX("kX");1i(B h=0;h<kF.12;h++){B 1N=kF[h].32;1P(1N!=N){if(1N.6b==1&&1N.aK.bb()=="6q"){B 1k=1N.5B;B i=1k.1X(6B);if(i>=0){I 1k}}1N=1N.au}}I N};D.k1=C(1u,1k,7N,a8){7N=7N||"";if(1u.2S==N){3N{B q="\'"+7N.5F(/\'/g,\'&vj\')+"\'";1u.ln("<6q 5B=\'"+1k+"\' 7N="+q+(a8?" a8=\'"+a8+"\'":"")+" 3v=\'1m/kO\'>"+7N+"</6q>");I 1B}4c(e){}}B 6q=1u.1y("6q");if(7N){3N{6q.3I=7N}4c(e){}6q.3B("7N",7N)}if(a8){6q.3B("a8",a8)}6q.3v="1m/kO";6q.jR="vn";6q.5B=1k;I k8(1u).1p(6q)};D.vo=C(1u,2t,9w){1i(B i=0;i<9w.12;i++){D.k1(1u,2t+9w[i])}D.kW+=9w.12;D.k1(1u,D.2t+"vs/vr.js?"+9w.12)};D.lr=C(1u,1k){if(1u.2S==N){3N{1u.ln("<51 lk=\'lq\' 9M=\'"+1k+"\' 3v=\'1m/bH\'/>");I}4c(e){}}B 51=1u.1y("51");51.3B("lk","lq");51.3B("3v","1m/bH");51.3B("9M",1k);k8(1u).1p(51)};D.vi=C(1u,2t,9w){1i(B i=0;i<9w.12;i++){D.lr(1u,2t+9w[i])}};D.vg=C(lx,2t,jK){1i(B i=0;i<jK.12;i++){lx.1L(2t+jK[i])}};D.l9=C(1k,to,fn){to=to||{};fn=fn||{};if(2u 1k=="5S"){1k=bi.9M}B q=1k.1X("?");if(q<0){I to}1k=(1k+"#").d3(q+1,1k.1X("#"));B P=1k.77("&"),eJ,bJ={};B jF=2Q.v9||v8;1i(B i=0;eJ=P[i];i++){B eq=eJ.1X("=");B 3j=jF(eJ.d3(0,eq));B b2=bJ[3j];if(2u b2=="5S"){b2=[]}S if(!(b2 7w 4P)){b2=[b2]}bJ[3j]=b2.ki(jF(eJ.d3(eq+1)))}1i(B i in bJ){if(!bJ.v7(i))kl;B 3v=fn[i]||7c;B 2f=bJ[i];if(!(2f 7w 4P)){2f=[2f]}if(3v===f6&&2f[0]=="1B"){to[i]=1B}S{to[i]=3v.71(k,2f)}}I to};D.f3=1x}D.2C.os={lv:1B,jN:1B,ls:1B,li:1B};D.2C.2X={5I:1B,kI:1B,kd:1B,kG:1B,l5:1B,l6:1B,gl:0,l4:0};(C(){B an=cu.v6.bb();B ua=cu.nY.bb();D.2C.os.lv=(ua.1X(\'vb\')!=-1);D.2C.os.jN=(ua.1X(\'vf\')!=-1);D.2C.os.ls=D.2C.jN&&(ua.1X(\'95\')!=-1||ua.1X(\'98\')!=-1||ua.1X(\'nt\')!=-1||ua.1X(\'vd\')!=-1||ua.1X(\'vc\')!=-1);D.2C.os.li=(ua.1X(\'vt\')!=-1);D.2C.2X.5I=(an.1X("nq")!=-1);D.2C.2X.kI=(an.1X("vu")!=-1);D.2C.2X.kd=(ua.1X("l1")!=-1);D.2C.2X.kG=(ua.1X("l8")!=-1);D.2C.2X.l5=(an.1X("nW")!=-1);D.2C.2X.l6=(an.1X("vK")!=-1);B dP=C(s){B a=s.77(".");D.2C.2X.gl=3F(a[0]);D.2C.2X.l4=3F(a[1])};B 1X=C(s,jv,2i){B i=s.1X(jv,2i);I i>=0?i:s.12};if(D.2C.2X.kd){B 1O=ua.1X("l1/");if(1O>=0){dP(ua.6B(1O+8,1X(ua," ",1O)))}}if(D.2C.2X.5I){B 1O=ua.1X("vJ ");if(1O>=0){dP(ua.6B(1O+5,1X(ua,";",1O)))}}if(D.2C.2X.kI){B 1O=ua.1X("rv:");if(1O>=0){dP(ua.6B(1O+3,1X(ua,")",1O)))}}if(D.2C.2X.kG){B 1O=ua.1X("l8/");if(1O>=0){dP(ua.6B(1O+8,1X(ua," ",1O)))}}if(!("lc"in 7c.L)){7c.L.lc=C(s){if(k<s)I-1;S if(k>s)I 1;S I 0}}})();D.2C.e9=C(){I D.2C.hG};D.3h={fP:1B};D.3h.53=C(cP){B f;if("82"in 2Q&&"53"in 2Q.82){f=C(5U){82.53(5U)}}S{f=C(5U){if(!D.3h.fP){8z(5U)}}}D.3h.53=f;f(cP)};D.3h.cZ=C(cP){B f;if("82"in 2Q&&"cZ"in 2Q.82){f=C(5U){82.cZ(5U)}}S{f=C(5U){if(!D.3h.fP){8z(5U)}}}D.3h.cZ=f;f(cP)};D.3h.6E=C(e,cP){B f,P=D.l9();if(P.la=="9n"||D.P.la=="9n"){f=C(e2,5U){9n(e2)}}S if("82"in 2Q&&"fO"in 2Q.82){f=C(e2,5U){if(5U!=N){82.fO(5U+" %o",e2)}S{82.fO(e2)}9n(e2)}}S{f=C(e2,5U){if(!D.3h.fP){8z("vO 6E: "+5U+"\\n\\vH: "+("8O"in e2?e2.8O:e2))}9n(e2)}}D.3h.6E=f;f(e,cP)};D.3h.vG=C(o){I D.3h.fR(o,"")};D.3h.fR=C(o,fF){B fL=fF+" ";if(2u o=="7J"){B s="{";1i(n in o){s+=fL+n+": "+D.3h.fR(o[n],fL)+"\\n"}s+=fF+"}";I s}S if(2u o=="fY"){B s="[";1i(B n=0;n<o.12;n++){s+=D.3h.fR(o[n],fL)+"\\n"}s+=fF+"]";I s}S{I o}};D.4s=1h 4C();D.4s.ie=C(26,4t,4r){79(26.o8){1K 4:3N{if(26.8F==0||26.8F==dI){if(4r){4r(26)}}S{if(4t){4t(26.64,26.8F,26)}}}4c(e){D.3h.6E("4s: aj ib vy",e)}1v}};D.4s.cX=C(){if(D.2C.2X.5I){B iL=["lb.iC","ai.iC","lb.iC.4.0"];1i(B i=0;i<iL.12;i++){3N{B ld=iL[i];B f=C(){I 1h vx(ld)};B o=f();D.4s.cX=f;I o}4c(e){}}}3N{B f=C(){I 1h lg()};B o=f();D.4s.cX=f;I o}4c(e){9n 1h aj("ad to dJ an lg 7J")}};D.4s.9U=C(1k,4t,4r){B 26=D.4s.cX();26.lf("vv",1k,1x);26.je=C(){D.4s.ie(26,4t,4r)};26.l7(N)};D.4s.vA=C(1k,2S,4t,4r){B 26=D.4s.cX();26.lf("vB",1k,1x);26.je=C(){D.4s.ie(26,4t,4r)};26.l7(2S)};D.4s.vE=C(26){3N{26.vD("1m/3w")}4c(e){26.vC("v4-v3","1m/3w")}};D.i6=1h 4C();(C(){B m={\'\\b\':\'\\\\b\',\'\\t\':\'\\\\t\',\'\\n\':\'\\\\n\',\'\\f\':\'\\\\f\',\'\\r\':\'\\\\r\',\'"\':\'\\\\"\',\'\\\\\':\'\\\\\\\\\'};B s={fY:C(x){B a=[\'[\'],b,f,i,l=x.12,v;1i(i=0;i<l;i+=1){v=x[i];f=s[2u v];if(f){v=f(v);if(2u v==\'2H\'){if(b){a[a.12]=\',\'}a[a.12]=v;b=1x}}}a[a.12]=\']\';I a.8D(\'\')},\'uv\':C(x){I 7c(x)},\'N\':C(x){I"N"},dM:C(x){I uu(x)?7c(x):\'N\'},7J:C(x){if(x){if(x 7w 4P){I s.fY(x)}B a=[\'{\'],b,f,i,v;1i(i in x){v=x[i];f=s[2u v];if(f){v=f(v);if(2u v==\'2H\'){if(b){a[a.12]=\',\'}a.1L(s.2H(i),\':\',v);b=1x}}}a[a.12]=\'}\';I a.8D(\'\')}I\'N\'},2H:C(x){if(/["\\\\\\l0-\\l3]/.cd(x)){x=x.5F(/([\\l0-\\l3\\\\"])/g,C(a,b){B c=m[b];if(c){I c}c=b.uw();I\'\\\\ux\'+1b.5P(c/16).47(16)+(c%16).47(16)})}I\'"\'+x+\'"\'}};D.i6.uB=C(o){if(o 7w 4C){I s.7J(o)}S if(o 7w 4P){I s.fY(o)}S{I o.47()}};D.i6.uy=C(){3N{I!(/[^,:{}\\[\\]0-9.\\-+ur-u \\n\\r\\t]/.cd(k.5F(/"(\\\\.|[^"\\\\])*"/g,\'\')))&&eW(\'(\'+k+\')\')}4c(e){I 1B}}})();D.1g=1h 4C();D.1g.7t=C(M,8g,cb,6f){D.1g.2a(M,8g,C(5X,K,1C){I cb[6f].hJ(cb,5X,K,1C)})};D.1g.2a=C(M,8g,eP){B er=C(K){K=(K)?K:((1o)?1o:N);if(K){B 1C=(K.1C)?K.1C:((K.gv)?K.gv:N);if(1C){1C=(1C.6b==1||1C.6b==9)?1C:1C.7L}I eP(M,K,1C)}I 1x}if(D.2C.2X.5I){M.gq("on"+8g,er)}S{M.uq(8g,er,1B)}};D.1g.6z=C(M){B U=0;B V=0;if(M.6b!=1){M=M.7L}B 5X=M;1P(5X!=N){U+=5X.fm;V+=5X.kc;5X=5X.ly}B 2S=1G.2S;1P(M!=N&&M!=2S){if("ir"in M){U-=M.ir;V-=M.lu}M=M.7L}I{U:U,V:V}};D.1g.uj=C(M){B w=k.i7(M,"X");B h=k.i7(M,"19");if(w.1X("px")>-1)w=w.5F("px","");if(h.1X("px")>-1)h=h.5F("px","");I{w:w,h:h}}D.1g.i7=C(M,iq){if(M.lh){B E=M.lh[iq]}S if(2Q.jV){B E=1G.ui.jV(M,N).uh(iq)}S{B E=""}I E}D.1g.8f=C(K,M){if(D.2C.2X.5I){I{x:K.hX,y:K.hN}}S{B 3x=D.1g.6z(M);I{x:K.4z-3x.U,y:K.5y-3x.V}}};D.1g.gA=C(K){if(D.2C.2X.5I){I{x:K.91+1G.2S.ir,y:K.96+1G.2S.lu}}S{I{x:K.4z,y:K.5y}}};D.1g.mY=C(x,y,9K){I D.1g.e5(1G.2S,x,y,9K)};D.1g.e5=C(M,x,y,9K){B f5=M.f5;lw:1i(B i=0;i<f5.12;i++){B 5L=f5[i];1i(B j=0;j<9K.12;j++){if(5L==9K[j]){kl lw}}if(5L.63==0&&5L.5M==0){B iS=D.1g.e5(5L,x,y,9K);if(iS!=5L){I iS}}S{B V=0;B U=0;B 1N=5L;1P(1N){V+=1N.kc;U+=1N.fm;1N=1N.ly}if(U<=x&&V<=y&&(x-U)<5L.63&&(y-V)<5L.5M){I D.1g.e5(5L,x,y,9K)}S if(5L.6b==1&&5L.aK=="uk"){B jl=D.1g.e5(5L,x,y,9K);if(jl!=5L){I jl}}}}I M};D.1g.70=C(K){K.uo=1B;K.eN=1x;if("ll"in K){K.ll()}};D.1g.un=C(M,1W){B dA=M.1W.77(" ");1i(B i=0;i<dA.12;i++){if(dA[i]==1W){I}}dA.1L(1W);M.1W=dA.8D(" ")};D.1g.lm=C(3v){B R=1G.1y("R");R.3I="<d5 3v=\'"+3v+"\' />";I R.32};D.1g.um=C(lj){B 3L={};3L.M=D.1g.jy(lj,3L,N);I 3L};D.1g.jy=C(7s,3L,5z){if(7s==N){I N}S if(2u 7s!="7J"){B 1N=1G.7m(7s);if(5z!=N){5z.1p(1N)}I 1N}S{B M=N;if("9I"in 7s){B 9I=7s.9I;if(5z!=N){if(9I=="tr"){M=5z.qy(5z.bh.12)}S if(9I=="td"){M=5z.qv(5z.hH.12)}}if(M==N){M=9I=="d5"?D.1g.lm(7s.3v):1G.1y(9I);if(5z!=N){5z.1p(M)}}}S{M=7s.M;if(5z!=N){5z.1p(M)}}1i(B 6t in 7s){B 2B=7s[6t];if(6t=="uD"){3L[2B]=M}S if(6t=="1W"){M.1W=2B}S if(6t=="id"){M.id=2B}S if(6t=="7R"){M.7R=2B}S if(6t=="3v"&&M.aK=="d5"){}S if(6t=="E"){1i(n in 2B){B v=2B[n];if(n=="uU"){n=D.2C.2X.5I?"uT":"uS"}M.E[n]=v}}S if(6t=="uR"){1i(B i=0;i<2B.12;i++){D.1g.jy(2B[i],3L,M)}}S if(6t!="9I"&&6t!="M"){M.3B(6t,2B)}}I M}}D.1g.dt=N;D.1g.v0=C(s){if(D.1g.dt==N){D.1g.dt=1G.1y("R")}D.1g.dt.3I=s;I D.1g.dt.32};D.1g.uY=C(eX,s,80){B M=2u eX=="2H"?1G.1y(eX):eX;M.3I=s;B 8P={M:M};D.1g.jz(8P,M,80!=N?80:{});I 8P};D.1g.lp=C(8P,M,80){B id=M.id;if(id!=N&&id.12>0){M.uX("id");if(id in 80){B 5z=M.7L;5z.uQ(80[id],M);5z.5r(M);8P[id]=80[id];I}S{8P[id]=M}}if(M.uP()){D.1g.jz(8P,M,80)}};D.1g.jz=C(8P,M,80){B 1N=M.32;1P(1N!=N){B lo=1N.au;if(1N.6b==1){D.1g.lp(8P,1N,80)}1N=lo}};D.1j=1h 4C();D.1j.9p=(!D.2C.2X.5I)||(D.2C.2X.gl>6);D.1j.lz=C(1k,58){B M=1G.1y("48");M.3B("5B",1k);if(58!=N){M.E.58=58}I M};D.1j.kQ=C(1k,58){B M=1G.1y("48");M.E.X="8i";M.E.19="8i";M.E.5C="cN:cO.ai.hc(5B=\'"+1k+"\', hf=\'2Y\')";M.E.58=(58!=N)?58:"7y";I M};D.1j.9q=D.1j.9p?D.1j.lz:D.1j.kQ;D.1j.kM=C(1k,58){I"<48 5B=\\""+1k+"\\""+(58!=N?" E=\\"kk-2T: "+58+";\\"":"")+" />"};D.1j.kY=C(1k,58){B E="X: 8i; 19: 8i; "+"5C:cN:cO.ai.hc(5B=\'"+1k+"\', hf=\'2Y\');"+(58!=N?" kk-2T: "+58+";":"");I"<48 5B=\'"+1k+"\' E=\\""+E+"\\" />"};D.1j.uG=D.1j.9p?D.1j.kM:D.1j.kY;D.1j.4p=C(M,2m){if(D.2C.2X.5I){M.E.5C="cN:cO.ai.mA(uE=0,uF="+2m+")"}S{B o=(2m/28).47();M.E.2m=o;M.E.uJ=o}};D.1j.kS={V:33,2j:42,U:33,2E:40}D.1j.du={V:0,2j:9,U:1,2E:8}D.1j.8X=15;D.1j.8Q=6;D.1j.9V=18;D.1j.i1=C(R,4z,5y,57,4j){if(2u 57!="dM"){57=ps}R.E.2p="2U";R.E.U="-uK";R.E.V="4w";R.E.X=57+"px";1G.2S.1p(R);2Q.aS(C(){B X=R.uO+10;B 19=R.uN+10;B 2o=D.1j.ku(4z,5y,X,19,4j);1G.2S.5r(R);R.E.2p="uM";R.E.U="";R.E.V="";R.E.X=X+"px";2o.kp.1p(R)},dI)};D.1j.ku=C(4z,5y,57,6m,4j){C kV(){if(2u 2Q.kU==\'dM\'){I{w:2Q.uL,h:2Q.kU}}S if(1G.68&&1G.68.6W){I{w:1G.68.6k,h:1G.68.6W}}S if(1G.2S&&1G.2S.6W){I{w:1G.2S.6k,h:1G.2S.6W}}}B 9H=C(){if(!2o.j0){1G.2S.5r(2o.3H);2o.vS=N;2o.3H=N;2o.vT=N;2o.j0=1x}}B 2o={j0:1B};B iY=kV();B dF=iY.w;B fo=iY.h;B 2c=D.1j.kS;57=3F(57,10);6m=3F(6m,10);B 6U=2c.U+57+2c.2E;B 83=2c.V+6m+2c.2j;B 9p=D.1j.9p;B 2t=D.2t;B 9Q=C(M,1k,X,19){M.E.2p="2U";M.E.X=X+"px";M.E.19=19+"px";if(9p){M.E.2G="1k("+1k+")"}S{M.E.5C="cN:cO.ai.hc(5B=\'"+1k+"\', hf=\'x1\')"}}B R=1G.1y("R");R.E.X=6U+"px";R.E.19=83+"px";R.E.2p="2U";R.E.d8=61;B 2s=D.1c.nc(9H,1x,R);2o.3H=R;2o.9H=C(){D.1c.nb(2s)}B 6p=1G.1y("R");6p.E.X="28%";6p.E.19="28%";6p.E.2p="kK";R.1p(6p);B 8B=C(1k,U,V,X,19){B 3E=1G.1y("R");3E.E.U=U+"px";3E.E.V=V+"px";9Q(3E,1k,X,19);6p.1p(3E)}8B(2t+"3d/2o-V-U.3A",0,0,2c.U,2c.V);8B(2t+"3d/2o-V.3A",2c.U,0,57,2c.V);8B(2t+"3d/2o-V-2E.3A",2c.U+57,0,2c.2E,2c.V);8B(2t+"3d/2o-U.3A",0,2c.V,2c.U,6m);8B(2t+"3d/2o-2E.3A",2c.U+57,2c.V,2c.2E,6m);8B(2t+"3d/2o-2j-U.3A",0,2c.V+6m,2c.U,2c.2j);8B(2t+"3d/2o-2j.3A",2c.U,2c.V+6m,57,2c.2j);8B(2t+"3d/2o-2j-2E.3A",2c.U+57,2c.V+6m,2c.2E,2c.2j);B ae=1G.1y("R");ae.E.U=(6U-2c.2E+D.1j.8X-16-2)+"px";ae.E.V=(2c.V-D.1j.8X+1)+"px";ae.E.7G="a9";9Q(ae,2t+"3d/9H-nd.3A",16,16);D.1c.7t(ae,"h9",2o,"9H");6p.1p(ae);B 7Y=1G.1y("R");7Y.E.2p="2U";7Y.E.U=2c.U+"px";7Y.E.V=2c.V+"px";7Y.E.X=57+"px";7Y.E.19=6m+"px";7Y.E.5t="iW";7Y.E.2G="fl";6p.1p(7Y);2o.kp=7Y;(C(){if(4z-D.1j.9V-D.1j.8X>0&&4z+D.1j.9V+D.1j.8X<dF){B U=4z-1b.1A(57/2)-2c.U;U=4z<(dF/2)?1b.1R(U,-(2c.U-D.1j.8X)):1b.2b(U,dF+(2c.2E-D.1j.8X)-6U);if((4j&&4j=="V")||(!4j&&(5y-D.1j.8Q-83>0))){B 3E=1G.1y("R");3E.E.U=(4z-D.1j.9V-U)+"px";3E.E.V=(2c.V+6m)+"px";9Q(3E,2t+"3d/2o-2j-fi.3A",37,2c.2j);6p.1p(3E);R.E.U=U+"px";R.E.V=(5y-D.1j.8Q-83+D.1j.du.2j)+"px";I}S if((4j&&4j=="2j")||(!4j&&(5y+D.1j.8Q+83<fo))){B 3E=1G.1y("R");3E.E.U=(4z-D.1j.9V-U)+"px";3E.E.V="4w";9Q(3E,2t+"3d/2o-V-fi.3A",37,2c.V);6p.1p(3E);R.E.U=U+"px";R.E.V=(5y+D.1j.8Q-D.1j.du.V)+"px";I}}B V=5y-1b.1A(6m/2)-2c.V;V=5y<(fo/2)?1b.1R(V,-(2c.V-D.1j.8X)):1b.2b(V,fo+(2c.2j-D.1j.8X)-83);if((4j&&4j=="U")||(!4j&&(4z-D.1j.8Q-6U>0))){B 3E=1G.1y("R");3E.E.U=(2c.U+57)+"px";3E.E.V=(5y-D.1j.9V-V)+"px";9Q(3E,2t+"3d/2o-2E-fi.3A",2c.2E,37);6p.1p(3E);R.E.U=(4z-D.1j.8Q-6U+D.1j.du.2E)+"px";R.E.V=V+"px"}S if((4j&&4j=="2E")||(!4j&&(4z-D.1j.8Q-6U<dF))){B 3E=1G.1y("R");3E.E.U="4w";3E.E.V=(5y-D.1j.9V-V)+"px";9Q(3E,2t+"3d/2o-U-fi.3A",2c.U,37);6p.1p(3E);R.E.U=(4z+D.1j.8Q-D.1j.du.U)+"px";R.E.V=V+"px"}})();1G.2S.1p(R);I 2o};D.1j.gO=C(1u){B 1Z=1u.1y("R");if(D.1j.9p){B c8=1u.1y("R");c8.E.19="kR";c8.E.2G="1k("+D.2t+"3d/3s-V-U.3A) V U no-aR";c8.E.gw="hi";1Z.1p(c8);B fj=1u.1y("R");fj.E.19="kR";fj.E.2G="1k("+D.2t+"3d/3s-V-2E.3A) V 2E no-aR";c8.1p(fj);B dD=1u.1y("R");dD.E.2G="1k("+D.2t+"3d/3s-U.3A) V U aR-y";dD.E.gw="hi";1Z.1p(dD);B dB=1u.1y("R");dB.E.2G="1k("+D.2t+"3d/3s-2E.3A) V 2E aR-y";dB.E.o6="hi";dD.1p(dB);B 6o=1u.1y("R");dB.1p(6o);B bU=1u.1y("R");bU.E.19="kP";bU.E.2G="1k("+D.2t+"3d/3s-2j-U.3A) 2j U no-aR";bU.E.gw="hi";1Z.1p(bU);B hb=1u.1y("R");hb.E.19="kP";hb.E.2G="1k("+D.2t+"3d/3s-2j-2E.3A) 2j 2E no-aR";bU.1p(hb)}S{1Z.E.cE="gL 4v #wW";1Z.E.nx="wV";1Z.E.2G="fl";D.1j.4p(1Z,90);B 6o=1u.1y("R");1Z.1p(6o)}I{1Z:1Z,6o:6o}};D.1j.md=C(f,5R,to,4J,aZ){I 1h D.1j.hg(f,5R,to,4J,aZ)};D.1j.hg=C(f,5R,to,4J,aZ){k.f=f;k.aZ=(2u aZ=="C")?aZ:C(){};k.5R=5R;k.to=to;k.aV=5R;k.4J=4J;k.2i=1h 3f().1M();k.h7=0};D.1j.hg.L.bA=C(){B a=k;2Q.aS(C(){a.kT()},50)};D.1j.hg.L.kT=C(){k.h7+=50;B kN=k.h7/k.4J;B kL=-1b.qG(kN*1b.op)/2+0.5;B aV=kL*(k.to-k.5R)+k.5R;3N{k.f(aV,aV-k.aV)}4c(e){}k.aV=aV;if(k.h7<k.4J){k.bA()}S{k.f(k.to,0);k["aZ"]()}};D.1j.wN=C(2Y,X,19,mH){B R=1G.1y("R");R.E.2p="kK";R.E.1H="nv";R.E.X=X+"px";R.E.19=19+"px";R.E.5t="4b";R.E.wM="gL";if(D.1j.9p){R.E.2G="1k("+2Y+") no-aR"}S{R.E.5C="cN:cO.ai.hc(5B=\'"+2Y+"\', hf=\'2Y\')"}B E;if(D.2C.2X.5I){E="5C:9F(2m=0)"}S{E="2m: 0"}R.3I="<b4 bh=\'1\' wL=\'wP\' 2B=\'3b\' E=\'"+E+"\' />";B b4=R.32;b4.E.X=X+"px";b4.E.19=19+"px";b4.wQ=C(K){K=(K)?K:((1o)?1o:N);if(K.nd==2){b4.2B=mH();b4.wU()}};I R};D.1j.hB=C(M,X){I 1h D.1j.ca(M,X)};D.1j.ca=C(M,X){k.7M=M;k.7M.E.8b="4b";if(2u X=="2H"){k.7M.E.X=X}S if(2u X=="dM"){k.7M.E.X=X+"px"}};D.1j.ca.L.8v=C(){k.7M=N};D.1j.ca.L.6H=C(){k.7M.3I="A";k.mG=k.7M.5M};D.1j.ca.L.8V=C(1m){k.7M.3I=1m;I{X:k.7M.63,19:k.7M.5M}};D.1j.ca.L.hF=C(){I k.mG};D.1f=1h 4C();D.1f.e6=0;D.1f.aW=1;D.1f.8c=2;D.1f.7a=3;D.1f.6P=4;D.1f.9N=5;D.1f.aM=6;D.1f.6u=7;D.1f.ak=8;D.1f.b1=9;D.1f.8h=10;D.1f.wT=-1;D.1f.wS=-2;D.1f.5b=[];(C(){B d=D.1f;B a=d.5b;a[d.e6]=1;a[d.aW]=61;a[d.8c]=a[d.aW]*60;a[d.7a]=a[d.8c]*60;a[d.6P]=a[d.7a]*24;a[d.9N]=a[d.6P]*7;a[d.aM]=a[d.6P]*31;a[d.6u]=a[d.6P]*ue;a[d.ak]=a[d.6u]*10;a[d.b1]=a[d.6u]*28;a[d.8h]=a[d.6u]*61})();D.1f.mF=1h j7("^(-?)([0-9]{4})("+["(-?([0-9]{2})(-?([0-9]{2}))?)","(-?([0-9]{3}))","(-?W([0-9]{2})(-?([1-7]))?)"].8D("|")+")?$");D.1f.mD=1h j7("Z|(([-+])([0-9]{2})(:?([0-9]{2}))?)$");D.1f.mJ=1h j7("^([0-9]{2})(:?([0-9]{2})(:?([0-9]{2})(\\.([0-9]+))?)?)?$");D.1f.mK=C(3t,2H){B d=2H.eT(D.1f.mF);if(!d){9n 1h aj("iU 1q 2H: "+2H)}B mE=(d[1]=="-")?-1:1;B av=mE*d[2];B aF=d[5];B 1q=d[7];B j5=d[9];B ja=d[11];B mI=(d[13])?d[13]:1;3t.6r(av);if(j5){3t.99(0);3t.86(2r(j5))}S if(ja){3t.99(0);3t.86(1);B gd=3t.mq();B 7n=(gd)?gd:7;B 1O=2r(mI)+(7*2r(ja));if(7n<=4){3t.86(1O+1-7n)}S{3t.86(1O+8-7n)}}S{if(aF){3t.86(1);3t.99(aF-1)}if(1q){3t.86(1q)}}I 3t};D.1f.mv=C(3t,2H){B d=2H.eT(D.1f.mJ);if(!d){D.3h.cZ("iU 29 2H: "+2H);I 1B}B mN=d[1];B mM=2r((d[3])?d[3]:0);B mL=(d[5])?d[5]:0;B ms=d[7]?(2r("0."+d[7])*61):0;3t.j1(mN);3t.j2(mM);3t.cR(mL);3t.cn(ms);I 3t};D.1f.xp=1h 3f().iZ();D.1f.mt=C(3t,2H){B 1O=N;B 9k=(2H.1X("T")==-1)?2H.77(" "):2H.77("T");D.1f.mK(3t,9k[0]);if(9k.12==2){B d=9k[1].eT(D.1f.mD);if(d){if(d[0]==\'Z\'){1O=0}S{1O=(2r(d[3])*60)+2r(d[5]);1O*=((d[2]==\'-\')?1:-1)}9k[1]=9k[1].4d(0,9k[1].12-d[0].12)}D.1f.mv(3t,9k[1])}if(1O==N){1O=3t.iZ()}3t.88(3t.1M()+1O*xm);I 3t};D.1f.kH=C(2H){3N{I D.1f.mt(1h 3f(0),2H)}4c(e){I N}};D.1f.8U=C(o){if(o==N){I N}S if(o 7w 3f){I o}B s=o.47();if(s.12>0&&s.12<8){B dk=s.1X(" ");if(dk>0){B av=3F(s.4d(0,dk));B cw=s.4d(dk+1);if(cw.bb()=="bc"){av=1-av}}S{B av=3F(s)}B d=1h 3f(0);d.6r(av);I d}3N{I 1h 3f(3f.xv(s))}4c(e){I N}};D.1f.eH=C(1q,4f,2I,3c,7l){B cs=2I*D.1f.5b[D.1f.7a];B 1J=1h 3f(1q.1M()+cs);B cT=C(d){d.cn(0);d.cR(0);d.j2(0);d.j1(0)};B cU=C(d){cT(d);d.86(1);d.99(0)};79(4f){1K D.1f.e6:B x=1J.qk();1J.cn(x-(x%3c));1v;1K D.1f.aW:1J.cn(0);B x=1J.qj();1J.cR(x-(x%3c));1v;1K D.1f.8c:1J.cn(0);1J.cR(0);B x=1J.ql();1J.88(1J.1M()-(x%3c)*D.1f.5b[D.1f.8c]);1v;1K D.1f.7a:1J.cn(0);1J.cR(0);1J.j2(0);B x=1J.hA();1J.j1(x-(x%3c));1v;1K D.1f.6P:cT(1J);1v;1K D.1f.9N:cT(1J);B d=(1J.mq()+7-7l)%7;1J.88(1J.1M()-d*D.1f.5b[D.1f.6P]);1v;1K D.1f.aM:cT(1J);1J.86(1);B x=1J.8R();1J.99(x-(x%3c));1v;1K D.1f.6u:cU(1J);B x=1J.4h();1J.6r(x-(x%3c));1v;1K D.1f.ak:cU(1J);1J.6r(1b.5P(1J.4h()/10)*10);1v;1K D.1f.b1:cU(1J);1J.6r(1b.5P(1J.4h()/28)*28);1v;1K D.1f.8h:cU(1J);1J.6r(1b.5P(1J.4h()/61)*61);1v}1q.88(1J.1M()-cs)};D.1f.kZ=C(1q,4f,2I,3c,7l){B mw=1q.1M();D.1f.eH(1q,4f,2I,3c,7l);if(1q.1M()<mw){1q.88(1q.1M()+D.1f.5b[4f]*3c)}};D.1f.eL=C(1q,4f,2I){2I=(2u 2I==\'5S\')?0:2I;B cs=2I*D.1f.5b[D.1f.7a];B 1J=1h 3f(1q.1M()+cs);79(4f){1K D.1f.e6:1J.88(1J.1M()+1)1v;1K D.1f.aW:1J.88(1J.1M()+61);1v;1K D.1f.8c:1J.88(1J.1M()+D.1f.5b[D.1f.8c]);1v;1K D.1f.7a:1J.88(1J.1M()+D.1f.5b[D.1f.7a]);1v;1K D.1f.6P:1J.86(1J.fH()+1);1v;1K D.1f.9N:1J.86(1J.fH()+7);1v;1K D.1f.aM:1J.99(1J.8R()+1);1v;1K D.1f.6u:1J.6r(1J.4h()+1);1v;1K D.1f.ak:1J.6r(1J.4h()+10);1v;1K D.1f.b1:1J.6r(1J.4h()+28);1v;1K D.1f.8h:1J.6r(1J.4h()+61);1v}1q.88(1J.1M()-cs)};D.1f.hQ=C(1q,2I){I 1h 3f(1q.1M()+2I*D.1f.5b[D.1f.7a])};D.1f.oC=C(){B d=1h 3f().iZ();I d/-60};7c.L.pW=C(){I k.5F(/^\\s+|\\s+$/g,\'\')};7c.L.xd=C(gH){I k.12>=gH.12&&k.4d(0,gH.12)==gH};7c.L.xe=C(cw){I k.12>=cw.12&&k.4d(k.12-cw.12)==cw};7c.xj=C(s,jf){B 3L="";B 2i=0;1P(2i<s.12-1){B 69=s.1X("%",2i);if(69<0||69==s.12-1){1v}S if(69>2i&&s.8M(69-1)=="\\\\"){3L+=s.6B(2i,69-1)+"%";2i=69+1}S{B n=3F(s.8M(69+1));if(fT(n)||n>=jf.12){3L+=s.6B(2i,69+2)}S{3L+=s.6B(2i,69)+jf[n].47()}2i=69+2}}if(2i<s.12){3L+=s.6B(2i)}I 3L};D.9W=1h 4C();D.9W.ju={};(C(){B O=D.9W.ju;O[\'xh\']=\'\\xg[dk]\';O[\'xf\']=\'\\wJ\';O[\'wI\']=\'\\wc\';O[\'wb\']=\'\\w9\';O[\'w8\']=\'\\wd\';O[\'we\']=\'\\wi\';O[\'wh\']=\'\\wg\';O[\'wf\']=\'\\w7\';O[\'w6\']=\'\\vY\';O[\'fh\']=\'\\vX\';O[\'vW\']=\'\\vU\';O[\'vV\']=\'\\vZ\';O[\'nr\']=\'\\w0\';O[\'w5\']=\'\\w4\';O[\'w3\']=\'\\w1\';O[\'wj\']=\'\\wk\';O[\'wB\']=\'\\wA\';O[\'wz\']=\'\\wy\';O[\'wC\']=\'\\wD\';O[\'wH\']=\'\\wG\';O[\'wF\']=\'\\wE\';O[\'wx\']=\'\\ww\';O[\'wp\']=\'\\wo\';O[\'wn\']=\'\\wl\';O[\'wm\']=\'\\wq\';O[\'wr\']=\'\\wv\';O[\'wu\']=\'\\wt\';O[\'ws\']=\'\\xw\';O[\'tb\']=\'\\rb\';O[\'rc\']=\'\\rd\';O[\'ra\']=\'\\qS\';O[\'qT\']=\'\\qN\';O[\'qU\']=\'\\r2\';O[\'r0\']=\'\\qZ\';O[\'rp\']=\'\\rS\';O[\'rM\']=\'\\rN\';O[\'rw\']=\'\\rt\';O[\'rI\']=\'\\rJ\';O[\'rG\']=\'\\rC\';O[\'rD\']=\'\\rz\';O[\'rL\']=\'\\rZ\';O[\'s2\']=\'\\rP\';O[\'rR\']=\'\\r1\';O[\'qR\']=\'\\r9\';O[\'rU\']=\'\\rV\';O[\'rr\']=\'\\rx\';O[\'rK\']=\'\\rX\';O[\'rQ\']=\'\\rT\';O[\'qO\']=\'\\qM\';O[\'qP\']=\'\\qQ\';O[\'ri\']=\'\\rk\';O[\'rl\']=\'\\rE\';O[\'r7\']=\'\\r8\';O[\'rf\']=\'\\rm\';O[\'ro\']=\'\\rj\';O[\'5k\']=\'\\r4\';O[\'qV\']=\'\\qW\';O[\'s0\']=\'\\rW\';O[\'ry\']=\'\\ru\';O[\'rs\']=\'\\rA\';O[\'rB\']=\'\\rH\';O[\'qY\']=\'\\rh\';O[\'s1\']=\'\\r6\';O[\'rg\']=\'\\rn\';O[\'r5\']=\'\\r3\';O[\'qX\']=\'\\rq\';O[\'s3\']=\'\\rF\';O[\'rY\']=\'\\rO\';O[\'ud\']=\'\\tA\';O[\'tB\']=\'\\tz\';O[\'ty\']=\'\\tu\';O[\'tv\']=\'\\tC\';O[\'tD\']=\'\\tI\';O[\'tH\']=\'\\tG\';O[\'tE\']=\'\\tF\';O[\'tt\']=\'\\ts\';O[\'te\']=\'\\tf\';O[\'tc\']=\'\\s4\';O[\'t9\']=\'\\ta\';O[\'tg\']=\'\\ti\';O[\'tq\']=\'\\tn\';O[\'tm\']=\'\\tj\';O[\'tk\']=\'\\tJ\';O[\'tK\']=\'\\u4\';O[\'u3\']=\'\\u2\';O[\'u0\']=\'\\u1\';O[\'u5\']=\'\\u6\';O[\'uc\']=\'\\ub\';O[\'u9\']=\'\\u7\';O[\'u8\']=\'\\tZ\';O[\'tY\']=\'\\tP\';O[\'tQ\']=\'\\tO\';O[\'tN\']=\'\\tL\';O[\'tM\']=\'\\tR\';O[\'tS\']=\'\\tX\';O[\'tW\']=\'\\tV\';O[\'tT\']=\'\\tU\';O[\'t8\']=\'\\t7\';O[\'lt\']=\'\\sq\';O[\'gt\']=\'\\sr\';O[\'sp\']=\'\';O[\'so\']=\'\\sm\';O[\'sn\']=\'\\st\';O[\'su\']=\'\\sC\';O[\'sB\']=\'\\sA\';O[\'sv\']=\'\\sz\';O[\'sl\']=\'\\sk\';O[\'s9\']=\'\\sb\';O[\'s8\']=\'\\s7\';O[\'s5\']=\'\\s6\';O[\'sc\']=\'\\sd\';O[\'sj\']=\'\\si\';O[\'sg\']=\'\\se\';O[\'sf\']=\'\\sD\';O[\'sE\']=\'\\sY\';O[\'sZ\']=\'\\sX\';O[\'sW\']=\'\\sU\';O[\'sV\']=\'\\t0\';O[\'t1\']=\'\\t6\';O[\'t5\']=\'\\t4\';O[\'t2\']=\'\\t3\';O[\'sT\']=\'\\sS\';O[\'sJ\']=\'\\sK\';O[\'sI\']=\'\\sH\';O[\'sF\']=\'\\sG\';O[\'sL\']=\'\\sM\';O[\'sR\']=\'\\sQ\';O[\'sP\']=\'\\sN\';O[\'sO\']=\'\\wR\';O[\'mA\']=\'\\CF\';O[\'CC\']=\'\\Do\';O[\'Dp\']=\'\\DE\';O[\'CZ\']=\'\\CY\';O[\'Dj\']=\'\\Dk\';O[\'B5\']=\'\\B1\';O[\'B2\']=\'\\B3\';O[\'Bf\']=\'\\AL\';O[\'AD\']=\'\\AW\';O[\'BZ\']=\'\\C6\';O[\'C3\']=\'\\BI\';O[\'BG\']=\'\\Ba\';O[\'BF\']=\'\\BE\';O[\'BD\']=\'\\BB\';O[\'BH\']=\'\\BL\';O[\'BK\']=\'\\BJ\';O[\'xx\']=\'\\BA\';O[\'Bz\']=\'\\Bs\';O[\'Br\']=\'\\Bq\';O[\'Bp\']=\'\\Bt\';O[\'Bu\']=\'\\By\';O[\'Bx\']=\'\\Bw\';O[\'Bv\']=\'\\BM\';O[\'BN\']=\'\\C2\';O[\'9F\']=\'\\C1\';O[\'C0\']=\'\\C4\';O[\'C5\']=\'\\C8\';O[\'C7\']=\'\\BY\';O[\'BR\']=\'\\BQ\';O[\'BP\']=\'\\BO\';O[\'BT\']=\'\\BW\';O[\'BV\']=\'\\BU\';O[\'Bo\']=\'\\Bn\';O[\'AS\']=\'\\AR\';O[\'AQ\']=\'\\AP\';O[\'mu\']=\'\\AU\';O[\'nu\']=\'\\AX\';O[\'xi\']=\'\\AV\';O[\'AO\']=\'\\AN\';O[\'pi\']=\'\\AG\';O[\'AF\']=\'\\AE\';O[\'AH\']=\'\\AI\';O[\'AM\']=\'\\AK\';O[\'AJ\']=\'\\AZ\';O[\'Bg\']=\'\\Be\';O[\'Bd\']=\'\\Bh\';O[\'Bi\']=\'\\Bm\';O[\'Bl\']=\'\\Bk\';O[\'Bj\']=\'\\Bc\';O[\'Bb\']=\'\\B4\';O[\'B6\']=\'\\Ca\';O[\'B9\']=\'\\B8\';O[\'B7\']=\'\\C9\';O[\'Co\']=\'\\Df\';O[\'De\']=\'\\Dd\';O[\'Db\']=\'\\Dc\';O[\'Dg\']=\'\\Dh\';O[\'Dl\']=\'\\Di\';O[\'Da\']=\'\\D9\';O[\'2Y\']=\'\\D2\';O[\'D1\']=\'\\D0\';O[\'D3\']=\'\\D4\';O[\'D8\']=\'\\D7\';O[\'D6\']=\'\\Dn\';O[\'Dm\']=\'\\DD\';O[\'DC\']=\'\\DB\';O[\'DA\']=\'\\DF\';O[\'Dw\']=\'\\Dz\';O[\'Dq\']=\'\\Dr\';O[\'Ds\']=\'\\Dv\';O[\'Du\']=\'\\Dt\';O[\'D5\']=\'\\CW\';O[\'Cr\']=\'\\Cq\';O[\'Cp\']=\'\\CX\';O[\'Cs\']=\'\\Ct\';O[\'Cx\']=\'\\Cw\';O[\'Cv\']=\'\\Cu\';O[\'Cn\']=\'\\Cm\';O[\'Cf\']=\'\\Ce\';O[\'Cd\']=\'\\Cb\';O[\'Cc\']=\'\\Cg\';O[\'ni\']=\'\\Ch\';O[\'Cl\']=\'\\Ck\';O[\'6X\']=\'\\Cj\';O[\'Ci\']=\'\\Cy\';O[\'Cz\']=\'\\CP\';O[\'CO\']=\'\\CN\';O[\'CM\']=\'\\CQ\';O[\'CR\']=\'\\CV\';O[\'CU\']=\'\\CT\';O[\'CS\']=\'\\CL\';O[\'or\']=\'\\CD\';O[\'CB\']=\'\\CA\';O[\'CE\']=\'\\CJ\';O[\'CI\']=\'\\CH\';O[\'CG\']=\'\\B0\';O[\'AB\']=\'\\yz\';O[\'yy\']=\'\\yx\';O[\'yw\']=\'\\yA\';O[\'ne\']=\'\\yB\';O[\'yF\']=\'\\yE\';O[\'le\']=\'\\yD\';O[\'ge\']=\'\\yC\';O[\'jv\']=\'\\yv\';O[\'yu\']=\'\\yn\';O[\'ym\']=\'\\yl\';O[\'yk\']=\'\\yo\';O[\'yp\']=\'\\yt\';O[\'AC\']=\'\\yr\';O[\'yq\']=\'\\yG\';O[\'yH\']=\'\\yX\';O[\'yW\']=\'\\yV\';O[\'yU\']=\'\\yY\';O[\'yZ\']=\'\\z3\';O[\'z2\']=\'\\z1\';O[\'z0\']=\'\\yT\';O[\'yS\']=\'\\yL\';O[\'yK\']=\'\\yJ\';O[\'yI\']=\'\\yM\';O[\'yN\']=\'\\yR\';O[\'yQ\']=\'\\yP\';O[\'yO\']=\'\\yj\';O[\'yi\']=\'\\xN\'})();D.9W.hE=C(s){B O=D.9W.ju;B re=/&(\\w+?);/;1P(re.cd(s)){B m=s.eT(re);s=s.5F(re,O[m[1]])}I s};D.6Q=C(a){k.6j={};k.dg=0;if(a 7w 4P){1i(B i=0;i<a.12;i++){k.5c(a[i])}}S if(a 7w D.6Q){k.mz(a)}}D.6Q.L.5c=C(o){if(!(o in k.6j)){k.6j[o]=1x;k.dg++;I 1x}I 1B}D.6Q.L.mz=C(8Y){1i(B o in 8Y.6j){k.5c(o)}}D.6Q.L.dG=C(o){if(o in k.6j){iI k.6j[o];k.dg--;I 1x}I 1B}D.6Q.L.xL=C(8Y){1i(B o in 8Y.6j){k.dG(o)}}D.6Q.L.xK=C(8Y){1i(B o in k.6j){if(!8Y.my(o)){iI k.6j[o];k.dg--}}}D.6Q.L.my=C(o){I(o in k.6j)}D.6Q.L.4V=C(){I k.dg}D.6Q.L.xO=C(){B a=[];1i(B o in k.6j){a.1L(o)}I a}D.6Q.L.xP=C(f){1i(B o in k.6j){if(f(o)==1x){1v}}}D.7A=C(2k,jx){k.4H=(jx 7w 4P)?jx:[];k.h1=2k};D.7A.L.5c=C(M){B sa=k;B 1T=k.aH(C(5X){I sa.h1(5X,M)});if(1T<k.4H.12){k.4H.5s(1T,0,M)}S{k.4H.1L(M)}};D.7A.L.dG=C(M){B sa=k;B 1T=k.aH(C(5X){I sa.h1(5X,M)});1P(1T<k.4H.12&&k.h1(k.4H[1T],M)==0){if(k.4H[1T]==M){k.4H.5s(1T,1);I 1x}S{1T++}}I 1B};D.7A.L.f2=C(){k.4H=[]};D.7A.L.7k=C(1T){I k.4H[1T]};D.7A.L.12=C(){I k.4H.12};D.7A.L.aH=C(2k){B a=0;B b=k.4H.12;1P(a<b){B dl=1b.5P((a+b)/2);B c=2k(k.4H[dl]);if(dl==a){I c<0?a+1:a}S if(c<0){a=dl}S{b=dl}}I a};D.7A.L.n7=C(){I(k.4H.12>0)?k.4H[0]:N};D.7A.L.n6=C(){I(k.4H.12>0)?k.4H[k.4H.12-1]:N};D.3W=C(1I){B bD=k;k.1D=(1I!=N)?1I:D.2N;k.21=1h D.7A(C(mO,mP){I bD.1D.2k(mO.3P(),mP.3P())});k.gk={};k.aG=1x};D.3W.L.6N=C(){I k.1D};D.3W.L.eV=C(id){I k.gk[id]};D.3W.L.5c=C(K){k.21.5c(K);k.gk[K.4K()]=K;k.aG=1B};D.3W.L.f2=C(){k.21.f2();k.gk={};k.aG=1B};D.3W.L.g6=C(){I k.21.12()};D.3W.L.qf=C(1V,2h){if(!k.aG){k.7X()}I 1h D.3W.jp(k.21,1V,2h,k.1D)};D.3W.L.qg=C(1V,2h){if(!k.aG){k.7X()}I 1h D.3W.jj(k.21,1V,2h,k.1D)};D.3W.L.pX=C(){I 1h D.3W.ji(k.21)};D.3W.L.ba=C(){B K=k.21.n7();I(K==N)?N:K.3P()};D.3W.L.bC=C(){B K=k.21.n6();if(K==N){I N}if(!k.aG){k.7X()}B 1T=K.cV;B 1q=k.21.7k(1T).5K();1i(B i=1T+1;i<k.21.12();i++){1q=k.1D.e7(1q,k.21.7k(i).5K())}I 1q};D.3W.L.7X=C(){B l=k.21.12();1i(B i=0;i<l;i++){B K=k.21.7k(i);K.cV=i}B ci=1;1i(B i=0;i<l;i++){B K=k.21.7k(i);B 45=K.5K();ci=1b.1R(ci,i+1);1P(ci<l){B jq=k.21.7k(ci);B n5=jq.3P();if(k.1D.2k(n5,45)<0){jq.cV=i;ci++}S{1v}}}k.aG=1x};D.3W.jp=C(46,1V,2h,1I){k.21=46;k.5a=1V;k.a0=2h;k.1D=1I;k.7u=46.aH(C(K){I 1I.2k(K.3P(),1V)});if(k.7u-1>=0){k.7u=k.21.7k(k.7u-1).cV}k.7u--;k.fC=46.aH(C(K){I 1I.2k(K.3P(),2h)});k.7v=1B;k.9v=N;k.ch()};D.3W.jp.L={9i:C(){I k.7v},6I:C(){if(k.7v){B 6I=k.9v;k.ch();I 6I}S{I N}},ch:C(){B 1I=k.1D;1P((++k.7u)<k.fC){B K=k.21.7k(k.7u);if(1I.2k(K.3P(),k.a0)<0&&1I.2k(K.5K(),k.5a)>0){k.9v=K;k.7v=1x;I}}k.9v=N;k.7v=1B}};D.3W.jj=C(46,1V,2h,1I){k.21=46;k.5a=1V;k.a0=2h;k.1D=1I;k.dC=46.aH(C(K){I 1I.2k(K.3P(),1V)});if(k.dC-1>=0){k.dC=k.21.7k(k.dC-1).cV}k.fC=46.aH(C(K){I 1I.2k(K.3P(),2h)});k.7u=k.fC;k.7v=1B;k.9v=N;k.ch()};D.3W.jj.L={9i:C(){I k.7v},6I:C(){if(k.7v){B 6I=k.9v;k.ch();I 6I}S{I N}},ch:C(){B 1I=k.1D;1P((--k.7u)>=k.dC){B K=k.21.7k(k.7u);if(1I.2k(K.3P(),k.a0)<0&&1I.2k(K.5K(),k.5a)>0){k.9v=K;k.7v=1x;I}}k.9v=N;k.7v=1B}};D.3W.ji=C(46){k.21=46;k.7X=0};D.3W.ji.L={9i:C(){I k.7X<k.21.12()},6I:C(){I k.7X<k.21.12()?k.21.7k(k.7X++):N}};D.2N=1h 4C();D.2N.g7=C(){I 1h 3f()};D.2N.eG=C(v){I 1h 3f(v.1M())};D.2N.aa=C(6i){if(2u 6i=="2H"){6i=6i.bb()}I(6i=="eA"||6i=="qA qH")?D.1f.kH:D.1f.8U};D.2N.6h=C(o){I D.1f.8U(o)};D.2N.ig=C(v){I v.1M()};D.2N.qI=C(n){I 1h 3f(n)};D.2N.2k=C(v1,v2){B n1,n2;if(2u v1=="7J"){n1=v1.1M()}S{n1=2r(v1)}if(2u v2=="7J"){n2=v2.1M()}S{n2=2r(v2)}I n1-n2};D.2N.g5=C(v1,v2){I D.2N.2k(v1,v2)<0?v1:v2};D.2N.e7=C(v1,v2){I D.2N.2k(v1,v2)>0?v1:v2};D.2N.9u=C(v,n){I 1h 3f(v.1M()+n)};D.gZ=C(n4){k.67=[];k.fk=n4};D.gZ.L.5c=C(2e){k.67.1L(2e)};D.gZ.L.dG=C(2e){B aJ=k.67;1i(B i=0;i<aJ.12;i++){if(aJ[i]==2e){aJ.5s(i,1);1v}}};D.gZ.L.yb=C(6f,fv){B aJ=[].ki(k.67);1i(B i=0;i<aJ.12;i++){B 2e=aJ[i];if(6f in 2e){3N{2e[6f].71(2e,fv)}4c(e){D.3h.6E("aj lA 1o of 3j "+6f,e)}}S if(k.fk!=N&&k.fk in 2e){3N{2e[k.fk].71(2e,[6f])}4c(e){D.3h.6E("aj lA 1o of 3j "+6f+" to y8 eP",e)}}}};D.1c={jo:1B,67:[],8T:N,be:N,7x:N,b9:N,5x:N,bt:"",5O:1B,4Y:[]};D.1c.3M=C(){if(D.1c.jo){I}D.1g.2a(1G.2S,"3R",D.1c.n3);D.1g.2a(1G.2S,"ey",D.1c.mQ);D.1g.2a(1G.2S,"bS",D.1c.mo);D.1g.2a(1G,"lE",D.1c.mS);D.1g.2a(1G,"lD",D.1c.mR);D.1c.4Y.1L({1T:0});D.1c.yd={yh:C(){},yg:C(){},yf:C(){},ye:C(){},y7:C(){},y6:C(){},xZ:C(){},xY:C(){}};D.1c.jo=1x};D.1c.xX=C(){D.1c.3M();I D.1c.4Y[0]};D.1c.n9=C(){D.1c.3M();I D.1c.4Y[D.1c.4Y.12-1]};D.1c.7t=C(M,8g,cb,6f,2s){D.1c.2a(M,8g,C(5X,K,1C){I cb[6f].hJ(cb,5X,K,1C)},2s)};D.1c.2a=C(M,8g,eP,2s){if(2s==N){2s=D.1c.n9()}B er=C(M,K,1C){if(D.1c.na(2s)){D.1c.ej(2s.1T);3N{eP(M,K,1C)}4c(e){D.3h.6E(e)}}D.1g.70(K);I 1B}D.1g.2a(M,8g,er)};D.1c.nc=C(f,eo,M){B 2s={iR:f,1T:D.1c.4Y.12,eo:(eo),M:M};D.1c.4Y.1L(2s);I 2s};D.1c.nb=C(2s){1i(B i=1;i<D.1c.4Y.12;i++){if(D.1c.4Y[i]==2s){D.1c.ej(i-1);1v}}};D.1c.z5=C(){D.1c.ej(0)};D.1c.A7=C(M,2J,2s){D.1c.2a(M,"3R",C(M,K,1C){D.1c.mT(M,K,2J)},2s)};D.1c.ej=C(7z){1P(7z+1<D.1c.4Y.12){3N{B 2s=D.1c.4Y.h8();if(2s.iR!=N){2s.iR()}}4c(e){}}};D.1c.na=C(2s){if(2s.1T==(D.1c.4Y.12-1)){I 1x}1i(B i=2s.1T+1;i<D.1c.4Y.12;i++){if(!D.1c.4Y[i].eo){I 1B}}I 1x};D.1c.ef=C(K){B ec=(K)?D.1g.gA(K):{x:-1,y:-1};B i=D.1c.4Y.12-1;1P(i>0&&D.1c.4Y[i].eo){B 2s=D.1c.4Y[i];if(2s.M!=N){B M=2s.M;B ay=D.1g.6z(M);if(ec.x>=ay.U&&ec.x<(ay.U+M.63)&&ec.y>=ay.V&&ec.y<(ay.V+M.5M)){1v}}i--}D.1c.ej(i)};D.1c.n3=C(M,K,1C){if(!("n0"in K)||K.n0==K.A6){D.1c.ef(K)}};D.1c.mT=C(M,K,2J){D.1c.8T=M;D.1c.be=2J;D.1c.b9={x:K.91,y:K.96};D.1g.70(K);I 1B};D.1c.mS=C(M,K,1C){if(D.1c.5O){if(K.aQ==27){D.1c.eC()}S if((K.aQ==17||K.aQ==16)&&D.1c.bt!="fh"){D.1c.bt="fh";B 48=D.1j.9q(D.2t+"3d/fh.3A");48.E.2p="2U";48.E.U=(D.1c.5x.U-16)+"px";48.E.V=(D.1c.5x.V)+"px";1G.2S.1p(48);D.1c.8m=48}}};D.1c.mR=C(M,K,1C){if(D.1c.5O){if(K.aQ==17||K.aQ==16){D.1c.bt="";if(D.1c.8m!=N){1G.2S.5r(D.1c.8m);D.1c.8m=N}}}};D.1c.mQ=C(M,K,1C){if(D.1c.8T!=N){B 2J=D.1c.be;B i5=D.1c.b9;B ax=K.91-i5.x;B aw=K.96-i5.y;if(!D.1c.5O){if(1b.6S(ax)>5||1b.6S(aw)>5){3N{if("mU"in 2J){2J.mU()}if("mV"in 2J&&2J.mV){B i9=D.1c.8T;D.1c.5x=D.1g.6z(i9);D.1c.5x.U+=ax;D.1c.5x.V+=aw;B 62=i9.Ad(1x);62.E.2p="2U";62.E.U=D.1c.5x.U+"px";62.E.V=D.1c.5x.V+"px";62.E.d8=61;D.1j.4p(62,50);1G.2S.1p(62);2J.a2=62}D.1c.5O=1x;D.1c.b9={x:K.91,y:K.96};1G.2S.a4()}4c(e){D.3h.6E("1c: aj ib mW Ac",e);D.1c.eC()}}}S{3N{D.1c.b9={x:K.91,y:K.96};if("mZ"in 2J){2J.mZ(ax,aw)}if("a2"in 2J){B 62=2J.a2;D.1c.5x.U+=ax;D.1c.5x.V+=aw;62.E.U=D.1c.5x.U+"px";62.E.V=D.1c.5x.V+"px";if(D.1c.8m!=N){B ia=D.1c.8m;ia.E.U=(D.1c.5x.U-16)+"px";ia.E.V=D.1c.5x.V+"px"}if("af"in 2J&&2J.af){B 3x=D.1g.gA(K);B 1C=D.1g.mY(3x.x,3x.y,[D.1c.a2,D.1c.7x]);1C=D.1c.lP(1C);if(1C!=D.1c.eD){if(D.1c.7x!=N){1G.2S.5r(D.1c.7x);D.1c.7x=N;D.1c.eD=N}B af=1B;if(1C!=N){if((!("g9"in 2J)||2J.g9(1C))&&(!("ga"in 1C)||1C.ga(D.1c.8T))){af=1x}}if(af){B cE=4;B ic=D.1g.6z(1C);B 4q=1G.1y("R");4q.E.cE=cE+"px 4v mX";4q.E.94="mX";4q.E.2p="2U";4q.E.U=ic.U+"px";4q.E.V=ic.V+"px";4q.E.X=(1C.63-cE*2)+"px";4q.E.19=(1C.5M-cE*2)+"px";D.1j.4p(4q,30);1G.2S.1p(4q);D.1c.eD=1C;D.1c.7x=4q}}}}}4c(e){D.3h.6E("1c: aj ib mW ih",e);D.1c.eC()}}D.1g.70(K);I 1B}};D.1c.mo=C(M,K,1C){if(D.1c.8T!=N){3N{if(D.1c.5O){B 2J=D.1c.be;if("mn"in 2J){2J.mn()}if("af"in 2J&&2J.af){B iJ=1B;B 1C=D.1c.eD;if(1C!=N){if((!("g9"in 2J)||2J.g9(1C))&&(!("ga"in 1C)||1C.ga(D.1c.8T))){if("lQ"in 2J){2J.lQ(1C)}1C.iD(D.1c.8T,D.1c.bt);iJ=1x}}if(!iJ){}}}}dz{D.1c.eC()}D.1g.70(K);I 1B}};D.1c.eC=C(){B 2J=D.1c.be;if("a2"in 2J){B 62=2J.a2;1G.2S.5r(62);iI 2J.a2}if(D.1c.7x!=N){1G.2S.5r(D.1c.7x);D.1c.7x=N}if(D.1c.8m!=N){1G.2S.5r(D.1c.8m);D.1c.8m=N}D.1c.8T=N;D.1c.be=N;D.1c.eD=N;D.1c.7x=N;D.1c.b9=N;D.1c.5x=N;D.1c.bt="";D.1c.5O=1B};D.1c.lP=C(M){1P(M!=N){if("iD"in M&&(2u M.iD)=="C"){1v}M=M.7L}I M};(C(){B lN=1B;if(1G.bi.lO.12>0){B P=1G.bi.lO.4d(1).77("&");1i(B i=0;i<P.12;i++){if(P[i]=="1r-A1-qJ-A0"){lN=1x}}};B lR=C(){if("J"in 2Q){I}2Q.J=1h 4C();2Q.J.1f=2Q.D.1f};lR()})();J.pC={};J.e9=C(){I J.hG};J.dJ=C(M,bf,4j,1I){I 1h J.3K(M,bf,4j,1I)};J.h5=0;J.km=1;J.eK=N;J.zY=C(P){B 1a=("1a"in P)?P.1a:J.f0();B 2L=("2L"in P)?P.2L:N;B 1Y=1h J.a7({ck:("1q"in P)?P.1q:1h 3f(),5h:D.1f.5b[P.4f],fu:P.lS});B 9D=1h J.bT({1I:P.4f,3c:("3c"in P)?P.3c:1,1a:1a,2T:("2T"in P)?P.2T:5S});B 6w={lW:("fy"in P)?P.fy:1x,1a:1a};if("3m"in P){6w.3m=P.3m}if("8L"in P){6w.8L=P.8L}B 7e=("92"in P&&P.92)?"92":("7e"in P?P.7e:"lV");B 5Q;79(7e){1K"92":5Q=1h J.4l(6w);1v;1K"lU":5Q=1h J.2y(6w);1v;aN:5Q=1h J.2V(6w)}I{X:P.X,2L:2L,2I:("2I"in P)?P.2I:0,1Y:1Y,9D:9D,5Q:5Q}};J.Ae=C(P){B 1a=("1a"in P)?P.1a:J.f0();B 2L=("2L"in P)?P.2L:N;B 1Y=1h J.7Q({ck:("1q"in P)?P.1q:1h 3f(),5h:D.1f.5b[P.4f],fu:P.lS,97:P.97});B 9D=1h J.cG({1I:P.4f,97:P.97,1a:1a,2T:("2T"in P)?P.2T:5S});B 6w={lW:("fy"in P)?P.fy:1x,1a:1a};if("3m"in P){6w.3m=P.3m}if("8L"in P){6w.8L=P.8L}B 7e=("92"in P&&P.92)?"92":("7e"in P?P.7e:"lV");B 5Q;79(7e){1K"92":5Q=1h J.4l(6w);1v;1K"lU":5Q=1h J.2y(6w);1v;aN:5Q=1h J.2V(6w)}I{X:P.X,2L:2L,2I:("2I"in P)?P.2I:0,1Y:1Y,9D:9D,5Q:5Q}};J.f0=C(){if(J.eK==N){J.eK=J.a1.dJ(J.e9())}I J.eK};J.At=C(1a){J.eK=1a};J.ds=C(1k,f){B 4t=C(64,8F,26){8z("ad to 8H 2f 3w 5R "+1k+"\\n"+64)};B 4r=C(26){B 3w=26.k0;if(!3w.68&&26.bm){3w.8H(26.bm)}f(3w,1k)};D.4s.9U(1k,4t,4r)};J.hS=C(1k,f){B 4t=C(64,8F,26){8z("ad to 8H lT 2f 5R "+1k+"\\n"+64)};B 4r=C(26){f(eW(\'(\'+26.k3+\')\'),1k)};D.4s.9U(1k,4t,4r)};J.3K=C(M,bf,4j,1I){D.1c.3M();k.49=M;k.aP=bf;k.ee=4j==N?J.h5:4j;k.1D=(1I!=N)?1I:D.2N;k.go()};J.3K.L.8v=C(){1i(B i=0;i<k.6d.12;i++){k.6d[i].8v()}k.6d=N;k.aP=N;k.49.3I=""};J.3K.L.As=C(){I k.6d.12};J.3K.L.Aw=C(1T){I k.6d[1T]};J.3K.L.7e=C(){k.kE()};J.3K.L.3l=C(){1i(B i=0;i<k.6d.12;i++){k.6d[i].3l()}};J.3K.L.2D=C(){I k.49.4U};J.3K.L.kB=C(R){k.49.1p(R)};J.3K.L.bk=C(R){k.49.5r(R)};J.3K.L.5D=C(){I k.ee==J.h5};J.3K.L.Ax=C(){I k.ee==J.km};J.3K.L.7B=C(){I k.ee==J.h5?k.49.63:k.49.5M};J.3K.L.lL=C(){I k.ee==J.km?k.49.63:k.49.5M};J.3K.L.6N=C(){I k.1D};J.3K.L.ds=C(1k,f){B tl=k;B 4t=C(64,8F,26){8z("ad to 8H 2f 3w 5R "+1k+"\\n"+64);tl.87()};B 4r=C(26){3N{B 3w=26.k0;if(!3w.68&&26.bm){3w.8H(26.bm)}f(3w,1k)}dz{tl.87()}};k.bB();2Q.aS(C(){D.4s.9U(1k,4t,4r)},0)};J.3K.L.hS=C(1k,f){B tl=k;B 4t=C(64,8F,26){8z("ad to 8H lT 2f 5R "+1k+"\\n"+64);tl.87()};B 4r=C(26){3N{f(eW(\'(\'+26.k3+\')\'),1k)}dz{tl.87()}};k.bB();2Q.aS(C(){D.4s.9U(1k,4t,4r)},0)};J.3K.L.go=C(){B 1Z=k.49;B 1u=1Z.4U;1Z.1W=1Z.1W.77(" ").ki("1r-as").8D(" ");1P(1Z.32){1Z.5r(1Z.32)}B 7D=D.1j.9q(J.2t+(k.5D()?"3d/d1-kk.3A":"3d/d1.3A"));7D.1W="1r-d1";7D.7R="J (c) ol - al://ao.ap.aq/1r/";D.1g.2a(7D,"h9",C(){2Q.bi="al://ao.ap.aq/1r/"});1Z.1p(7D);k.6d=[];1i(B i=0;i<k.aP.12;i++){B 1t=1h J.1E(k,k.aP[i],i);k.6d.1L(1t)}k.kE();1i(B i=0;i<k.aP.12;i++){B 3Z=k.aP[i];if("lM"in 3Z){k.6d[i].lG(k.6d[3Z.lM],("4q"in 3Z)?3Z.4q:1B)}}B 3s=D.1j.gO(1u);3s.1Z.1W="1r-3s-as";1Z.1p(3s.1Z);3s.6o.1W="1r-3s";3s.6o.3I="<48 5B=\'"+J.2t+"3d/oh-og.oa\' /> o9...";k.bB=C(){3s.1Z.E.1H="2x"};k.87=C(){3s.1Z.E.1H="3b"}};J.3K.L.kE=C(){B 12=k.7B();B X=k.lL();B kJ=0;1i(B i=0;i<k.6d.12;i++){B 1t=k.6d[i];B bf=k.aP[i];B g8=bf.X;B x=g8.1X("%");if(x>0){B 69=3F(g8.4d(0,x));B fN=69*X/28}S{B fN=3F(g8)}1t.lI(kJ,fN);1t.lX(12);kJ+=fN}};J.1E=C(1r,3Z,1T){k.1F=1r;k.lB=3Z;k.7X=1T;k.6T=("3T"in 3Z)?3Z.3T:J.e9();k.7d=("2I"in 3Z)?3Z.2I:0;k.fG=("3r"in 3Z)?3Z.3r:(("g1"in 1r.6N())?1r.6N().g1(k.6T,k.7d):1h J.55(k.6T,k.7d));k.5O=1B;k.bp=1B;k.k9=5;k.9f=k.k9;k.8Z=[];B b=k;k.5Y=N;k.gW=C(1t){b.jZ()};k.lF=C(1t){b.jZ()};B 8w=k.1F.2D().1y("R");8w.1W="1r-1t-d5";k.1F.kB(8w);k.9j=1G.1y("d5");k.9j.3v="1m";8w.1p(k.9j);D.1g.7t(k.9j,"lE",k,"mm");D.1g.7t(k.9j,"lD",k,"ml");k.3H=k.1F.2D().1y("R");k.3H.1W="1r-1t 1r-1t-"+1T;k.1F.kB(k.3H);D.1g.7t(k.3H,"3R",k,"mg");D.1g.7t(k.3H,"ey",k,"mf");D.1g.7t(k.3H,"bS",k,"me");D.1g.7t(k.3H,"pa",k,"mi");D.1g.7t(k.3H,"zQ",k,"mj");k.bv=k.1F.2D().1y("R");k.bv.1W="1r-1t-lY";k.3H.1p(k.bv);k.4I=3Z.1Y;3Z.1Y.3M(1r);k.9Y=3Z.9D;3Z.9D.3M(k,1r);k.4o=3Z.2L;if(k.4o){k.gn={8I:C(){b.m6()},db:C(){b.ma()}}k.4o.84(k.gn)}k.bg=3Z.5Q;3Z.5Q.3M(k,1r);k.9x=("lC"in 3Z)?3Z.lC:[];1i(B i=0;i<k.9x.12;i++){k.9x[i].3M(k,1r)}};J.1E.a6=5;J.1E.L.8v=C(){k.b7();if(k.4o){k.4o.85(k.gn);k.gn=N;k.4o=N}k.1F=N;k.lB=N;k.fG=N;k.4I=N;k.9Y=N;k.bg=N;k.9x=N;k.8Z=N;k.gW=N;k.lF=N;k.3H=N;k.bv=N;k.9j=N};J.1E.L.lJ=C(2e){k.8Z.1L(2e)};J.1E.L.lK=C(2e){1i(B i=0;i<k.8Z.12;i++){if(k.8Z[i]==2e){k.8Z.5s(i,1);1v}}};J.1E.L.lG=C(1t,4q){if(k.5Y){k.5Y.lK(k.gW)}k.5Y=1t;k.5Y.lJ(k.gW);k.6O=4q;k.jP()};J.1E.L.zp=C(){I k.6T};J.1E.L.hK=C(){I k.7d};J.1E.L.eg=C(){I k.fG};J.1E.L.di=C(){I k.7X};J.1E.L.z9=C(){I k.4I};J.1E.L.z6=C(){I k.9Y};J.1E.L.es=C(){I k.4o};J.1E.L.za=C(){I k.bg};J.1E.L.7e=C(){k.3l()};J.1E.L.3l=C(){k.9Y.3l();k.n8();k.fV()};J.1E.L.mb=C(){k.5N()};J.1E.L.5N=C(){k.9Y.5N();k.m7();k.m8()};J.1E.L.lI=C(aT,X){B 8w=k.9j.7L;B 7y=aT+1b.5P(X/2);if(k.1F.5D()){k.3H.E.V=aT+"px";k.3H.E.19=X+"px";8w.E.V=7y+"px";8w.E.U="-lH"}S{k.3H.E.U=aT+"px";k.3H.E.X=X+"px";8w.E.U=7y+"px";8w.E.V="-lH"}};J.1E.L.gC=C(){if(k.1F.5D()){I k.3H.5M}S{I k.3H.63}};J.1E.L.lX=C(12){k.4e=12;k.kD();k.k4()};J.1E.L.m0=C(){I k.4e};J.1E.L.qr=C(){I J.1E.a6*k.4e};J.1E.L.zd=C(){I k.5w};J.1E.L.7i=C(){I k.4I.66(k.5w)};J.1E.L.7F=C(){I k.4I.66(k.5w+J.1E.a6*k.4e)};J.1E.L.kx=C(){I k.4I.66(0)};J.1E.L.kC=C(){I k.4I.66(k.4e)};J.1E.L.lZ=C(){I k.4I.66(k.4e/2)};J.1E.L.zc=C(1q){if(!k.bp){k.8G(1b.1A(-k.4I.2n(1q)))}};J.1E.L.zs=C(1q){if(!k.bp){k.8G(1b.1A(k.4e-k.4I.2n(1q)))}};J.1E.L.bE=C(1q){if(!k.bp){k.8G(1b.1A(k.4e/2-k.4I.2n(1q)))}};J.1E.L.2n=C(1q){I k.4I.2n(1q)-k.5w};J.1E.L.66=C(2M){I k.4I.66(2M+k.5w)};J.1E.L.3G=C(d8,1W){B R=k.1F.2D().1y("R");R.1W="1r-1t-2s"+(2u 1W=="2H"?(" "+1W):"");R.E.d8=d8;k.bv.1p(R);B bs=k.1F.2D().1y("R");bs.1W="1r-1t-2s-lY";if(D.2C.2X.5I){bs.E.7G="ih"}S{bs.E.7G="-zJ-zI"}R.1p(bs);I bs};J.1E.L.4A=C(R){k.bv.5r(R.7L)};J.1E.L.mh=C(1q,f){B dn=k.4I.2n(1q);if(dn<-k.4e/2){k.bE(k.66(dn+k.4e))}S if(dn>3*k.4e/2){k.bE(k.66(dn-k.4e))}k.dU(1b.1A(k.4e/2-k.4I.2n(1q)),f)};J.1E.L.zG=C(b6){B K=k.es().eV(b6);if(K){B 4g=k;k.mh(K.3P(),C(){4g.bg.f4(K)})}};J.1E.L.mg=C(8W,K,1C){k.b7();k.5O=1x;k.jD=K.91;k.jG=K.96};J.1E.L.mf=C(8W,K,1C){if(k.5O){B ax=K.91-k.jD;B aw=K.96-k.jG;k.jD=K.91;k.jG=K.96;k.8G(k.1F.5D()?ax:aw);k.jP()}};J.1E.L.me=C(8W,K,1C){k.5O=1B;k.9j.a4()};J.1E.L.mi=C(8W,K,1C){B 3x=D.1g.8f(K,8W);3x.x+=k.5w;if(3x.x<0||3x.x>8W.63||3x.y<0||3x.y>8W.5M){k.5O=1B}};J.1E.L.mj=C(8W,K,1C){B 3x=D.1g.8f(K,8W);B h0=3x.x-(k.4e/2-k.5w);k.dU(-h0)};J.1E.L.mm=C(mk,K,1C){if(!k.5O){79(K.aQ){1K 27:1v;1K 37:1K 38:k.9f=1b.2b(50,1b.6S(k.9f*1.fS));k.8G(k.9f);1v;1K 39:1K 40:k.9f=-1b.2b(50,1b.6S(k.9f*1.fS));k.8G(k.9f);1v;aN:I 1x}k.b7();D.1g.70(K);I 1B}I 1x};J.1E.L.ml=C(mk,K,1C){if(!k.5O){k.9f=k.k9;79(K.aQ){1K 35:k.bE(k.4o.bC());1v;1K 36:k.bE(k.4o.ba());1v;1K 33:k.dU(k.1F.7B());1v;1K 34:k.dU(-k.1F.7B());1v;aN:I 1x}k.b7();D.1g.70(K);I 1B}I 1x};J.1E.L.dU=C(h0,f){B b=k;B a=D.1j.md(C(6S,cW){b.8G(cW)},0,h0,61,f);a.bA()};J.1E.L.8G=C(aT){k.b7();k.5w+=aT;k.4I.8x(-aT);if(k.1F.5D()){k.3H.E.U=k.5w+"px"}S{k.3H.E.V=k.5w+"px"}if(k.5w>-k.4e*0.5||k.5w<-k.4e*(J.1E.a6-1.5)){k.kD()}S{k.mb()}k.k4()}J.1E.L.k4=C(){k.bp=1x;k.m4();k.m3();k.bp=1B};J.1E.L.m4=C(){1i(B i=0;i<k.8Z.12;i++){k.8Z[i](k)}};J.1E.L.m3=C(){if(k.5Y){B fd=k.4I.66(k.m0()/2);k.5Y.bE(fd)}};J.1E.L.jZ=C(){if(k.5Y){B fd=k.5Y.lZ();B m5=k.4I.2n(fd);k.8G(1b.1A(k.4e/2-m5));if(k.6O){k.9Y.c9(k.5Y.kx(),k.5Y.kC())}}};J.1E.L.m6=C(){k.fV()};J.1E.L.ma=C(){k.fV()};J.1E.L.jP=C(){if(k.5Y){B 1V=k.5Y.kx();B 2h=k.5Y.kC();if(k.6O){k.9Y.c9(1V,2h)}}};J.1E.L.kD=C(){k.5w=-k.4e*(J.1E.a6-1)/2;if(k.1F.5D()){k.3H.E.U=k.5w+"px";k.3H.E.X=(J.1E.a6*k.4e)+"px"}S{k.3H.E.V=k.5w+"px";k.3H.E.19=(J.1E.a6*k.4e)+"px"}k.7e()};J.1E.L.fV=C(){k.bg.3l()};J.1E.L.m8=C(){k.bg.5N()};J.1E.L.n8=C(){1i(B i=0;i<k.9x.12;i++){k.9x[i].3l()}};J.1E.L.m7=C(){1i(B i=0;i<k.9x.12;i++){k.9x[i].5N()}};J.1E.L.b7=C(){D.1c.ef()};J.a1=1h 4C();J.a1.m9=[];J.a1.dJ=C(3T){if(3T==N){3T=J.e9()}B f=J.a1.m9[3T];if(f==N){f=J.a1.3K}I 1h f()};J.a1.3K=C(){k.7l=0;k.1Y={d4:["#z8","#zg","#zh","#zq"],pZ:"fl",pY:50,5h:{3a:{dZ:1x,1d:"#zr",2m:25},qo:{1d:"#Al",2m:30},5G:{dY:"Ak",Ag:C(M){M.1W="1r-1Y-5G-2j"},Ah:C(M){M.1W="1r-1Y-5G-2j-6c"},Ai:C(M){M.1W="1r-1Y-5G-V"},Aj:C(M){M.1W="1r-1Y-5G-V-6c"},dH:"Aq",Ar:C(M){M.1W="1r-1Y-5G-2E"},Ay:C(M){M.1W="1r-1Y-5G-2E-6c"},Az:C(M){M.1W="1r-1Y-5G-U"},AA:C(M){M.1W="1r-1Y-5G-U-6c"}}}};k.1o={3i:{19:10,8A:2},9P:{1O:20,qp:6,19:2,8A:1},ce:{19:4},5l:{2O:J.2t+"3d/Au-zT-zU.3A",5A:10,8n:10,1d:"#e1",cl:"#e1",cv:20},4J:{1d:"#e1",cl:"#e1",cv:20},2w:{94:"fl",pP:50,7q:"#e1",7T:3},ag:["#A3","#Aa","#A9","#A8"],2o:{X:A4,19:p1,py:C(M){M.1W="1r-1o-2o-7R"},pz:C(M){M.1W="1r-1o-2o-2S"},pw:C(M){M.1W="1r-1o-2o-2Y"},pR:C(M){M.1W="1r-1o-2o-bz"},pJ:C(M){M.1W="1r-1o-2o-29"}}}};J.a7=C(P){k.1S=P;k.bN=P.5h;k.bM=P.fu};J.a7.L.3M=C(1r){k.1F=1r;k.1D=1r.6N();if("f8"in k.1S){k.3y=k.1D.6h(k.1S.f8)}S if("gp"in k.1S){k.3y=k.1D.6h(k.1S.gp);k.8x(-k.1F.7B())}S if("ck"in k.1S){k.3y=k.1D.6h(k.1S.ck);k.8x(-k.1F.7B()/2)}S{k.3y=k.1D.g7();k.8x(-k.1F.7B()/2)}};J.a7.L.mB=C(1q){k.3y=k.1D.eG(1q)};J.a7.L.8x=C(2M){B cH=k.bN*2M/k.bM;k.3y=k.1D.9u(k.3y,cH)};J.a7.L.2n=C(1q){B cH=k.1D.2k(1q,k.3y);I k.bM*cH/k.bN};J.a7.L.66=C(2M){B cH=2M*k.bN/k.bM;I k.1D.9u(k.3y,cH)};J.7Q=C(P){k.1S=P;k.bN=P.5h;k.bM=P.fu};J.7Q.L.3M=C(1r){k.1F=1r;k.1D=1r.6N();k.3o=[{3S:2r.ev,4k:2r.54,6y:1}];B P=k.1S;1i(B i=0;i<P.97.12;i++){B 2g=P.97[i];B 4L=k.1D.6h(2g.2i);B 6s=k.1D.6h(2g.45);1i(B j=0;j<k.3o.12&&k.1D.2k(6s,4L)>0;j++){B 3Q=k.3o[j];if(k.1D.2k(4L,3Q.4k)<0){if(k.1D.2k(4L,3Q.3S)>0){k.3o.5s(j,0,{3S:3Q.3S,4k:4L,6y:3Q.6y});j++;3Q.3S=4L}if(k.1D.2k(6s,3Q.4k)<0){k.3o.5s(j,0,{3S:4L,4k:6s,6y:2g.6y*3Q.6y});j++;3Q.3S=6s;4L=6s}S{3Q.6y*=2g.6y;4L=3Q.4k}}}}if("f8"in k.1S){k.3y=k.1D.6h(k.1S.f8)}S if("gp"in k.1S){k.3y=k.1D.6h(k.1S.gp);k.8x(-k.1F.7B())}S if("ck"in k.1S){k.3y=k.1D.6h(k.1S.ck);k.8x(-k.1F.7B()/2)}S{k.3y=k.1D.g7();k.8x(-k.1F.7B()/2)}};J.7Q.L.mB=C(1q){k.3y=k.1D.eG(1q)};J.7Q.L.8x=C(2M){k.3y=k.66(2M)};J.7Q.L.2n=C(1q){I k.mx(k.3y,1q)};J.7Q.L.66=C(2M){I k.mC(2M,k.3y)};J.7Q.L.mx=C(gE,mp){B 9l=k.hY();B 7U=gE;B cr=mp;B 2M=0;if(k.1D.2k(7U,cr)<0){B z=0;1P(z<k.3o.12){if(k.1D.2k(7U,k.3o[z].4k)<0){1v}z++}1P(k.1D.2k(7U,cr)<0){B 2g=k.3o[z];B cp=k.1D.g5(cr,2g.4k);2M+=(k.1D.2k(cp,7U)/(9l/2g.6y));7U=cp;z++}}S{B z=k.3o.12-1;1P(z>=0){if(k.1D.2k(7U,k.3o[z].3S)>0){1v}z--}1P(k.1D.2k(7U,cr)>0){B 2g=k.3o[z];B cp=k.1D.e7(cr,2g.3S);2M+=(k.1D.2k(cp,7U)/(9l/2g.6y));7U=cp;z--}}I 2M};J.7Q.L.mC=C(2M,gE){B 9l=k.hY();B 29=gE;if(2M>0){B z=0;1P(z<k.3o.12){if(k.1D.2k(29,k.3o[z].4k)<0){1v}z++}1P(2M>0){B 2g=k.3o[z];B 9g=9l/2g.6y;if(2g.4k==2r.54){29=k.1D.9u(29,2M*9g);2M=0}S{B bP=k.1D.2k(2g.4k,29)/9g;if(bP>2M){29=k.1D.9u(29,2M*9g);2M=0}S{29=2g.4k;2M-=bP}}z++}}S{B z=k.3o.12-1;1P(z>=0){if(k.1D.2k(29,k.3o[z].3S)>0){1v}z--}2M=-2M;1P(2M>0){B 2g=k.3o[z];B 9g=9l/2g.6y;if(2g.3S==2r.ev){29=k.1D.9u(29,-2M*9g);2M=0}S{B bP=k.1D.2k(29,2g.3S)/9g;if(bP>2M){29=k.1D.9u(29,-2M*9g);2M=0}S{29=2g.3S;2M-=bP}}z--}}I 29};J.7Q.L.hY=C(){I k.bN/k.bM};J.bT=C(P){k.1S=P;k.2W=P.1a;k.1D=P.1I;k.cJ=("3c"in P)?P.3c:1};J.bT.L.3M=C(1t,1r){k.1l=1t;k.1F=1r;k.5j=1t.3G(0);k.5j.3B("3j","1Y-2G");k.5j.E.2G=k.2W.1Y.d4[1t.di()];k.2R=N;k.23=N;B 2T=("2T"in k.1S&&k.1S.2T!=5S)?k.1S.2T:k.2W.1Y.5h.5G[1r.5D()?"dY":"dH"];B 4S=("4S"in k.1S)?k.1S.4S:k.2W.1Y.5h.3a.dZ;k.9B=1h J.dq(k.1F,k.1l,k.2W,2T,4S);k.6O=1h J.eh(k.1F,k.1l,k.2W,k.5j)}J.bT.L.c9=C(1V,2h){k.6O.2p(1V,2h)}J.bT.L.3l=C(){if(k.2R){k.1l.4A(k.2R)}k.2R=k.1l.3G(28);k.2R.3B("3j","1Y-gz");k.2R.E.1H="3b";if(k.23){k.1l.4A(k.23)}k.23=k.1l.3G(1);k.23.3B("3j","1Y-cj");k.23.E.1H="3b";B 2P=k.1l.7i();B 3V=k.1l.7F();B 2I=k.1l.hK();B 3r=k.1l.eg();D.1f.eH(2P,k.1D,2I,k.cJ,k.2W.7l);B p=k;B 9O=C(1q){1i(B i=0;i<p.cJ;i++){D.1f.eL(1q,p.1D)}};1P(2P.1M()<3V.1M()){k.9B.dN(2P,3r,k.1D,k.2R,k.23);9O(2P)}k.2R.E.1H="2x";k.23.E.1H="2x"};J.bT.L.5N=C(){};J.cG=C(P){k.1S=P;k.2W=P.1a;k.3o=[{3S:2r.ev,4k:2r.54,1I:P.1I,3c:1}];1i(B i=0;i<P.97.12;i++){B 2g=P.97[i];B 4L=D.1f.8U(2g.2i).1M();B 6s=D.1f.8U(2g.45).1M();1i(B j=0;j<k.3o.12&&6s>4L;j++){B 3Q=k.3o[j];if(4L<3Q.4k){if(4L>3Q.3S){k.3o.5s(j,0,{3S:3Q.3S,4k:4L,1I:3Q.1I,3c:3Q.3c});j++;3Q.3S=4L}if(6s<3Q.4k){k.3o.5s(j,0,{3S:4L,4k:6s,1I:2g.1I,3c:(2g.3c)?2g.3c:1});j++;3Q.3S=6s;4L=6s}S{3Q.3c=2g.3c;3Q.1I=2g.1I;4L=3Q.4k}}}}};J.cG.L.3M=C(1t,1r){k.1l=1t;k.1F=1r;k.5j=1t.3G(0);k.5j.3B("3j","1Y-2G");k.5j.E.2G=k.2W.1Y.d4[1t.di()];k.2R=N;k.23=N;B 2T=("2T"in k.1S&&k.1S.2T!=5S)?k.1S.2T:k.2W.1Y.5h.5G[1r.5D()?"dY":"dH"];B 4S=("4S"in k.1S)?k.1S.4S:k.2W.1Y.5h.3a.dZ;k.9B=1h J.dq(k.1F,k.1l,k.2W,2T,4S);k.6O=1h J.eh(k.1F,k.1l,k.2W,k.5j)}J.cG.L.c9=C(1V,2h){k.6O.2p(1V,2h)}J.cG.L.3l=C(){if(k.2R){k.1l.4A(k.2R)}k.2R=k.1l.3G(28);k.2R.3B("3j","1Y-gz");k.2R.E.1H="3b";if(k.23){k.1l.4A(k.23)}k.23=k.1l.3G(1);k.23.3B("3j","1Y-cj");k.23.E.1H="3b";B 2P=k.1l.7i();B 3V=k.1l.7F();B 2I=k.1l.hK();B 3r=k.1l.eg();B p=k;B 9O=C(1q,2g){1i(B i=0;i<2g.3c;i++){D.1f.eL(1q,2g.1I)}};B dV=0;1P(dV<k.3o.12){if(2P.1M()<k.3o[dV].4k){1v}dV++}B dE=k.3o.12-1;1P(dE>=0){if(3V.1M()>k.3o[dE].3S){1v}dE--}1i(B z=dV;z<=dE;z++){B 2g=k.3o[z];B e0=1h 3f(1b.1R(2P.1M(),2g.3S));B hI=1h 3f(1b.2b(3V.1M(),2g.4k));D.1f.eH(e0,2g.1I,2I,2g.3c,k.2W.7l);D.1f.kZ(hI,2g.1I,2I,2g.3c,k.2W.7l);1P(e0.1M()<hI.1M()){k.9B.dN(e0,3r,2g.1I,k.2R,k.23);9O(e0,2g)}}k.2R.E.1H="2x";k.23.E.1H="2x"};J.cG.L.5N=C(){};J.dm=C(P){k.1S=P;k.2W=P.1a;k.5a=D.1f.8U(P.1V);k.cJ=("3c"in P)?P.3c:1};J.dm.L.3M=C(1t,1r){k.1l=1t;k.1F=1r;k.5j=1t.3G(0);k.5j.3B("3j","1Y-2G");k.5j.E.2G=k.2W.1Y.d4[1t.di()];k.2R=N;k.23=N;B 2T=("2T"in k.1S)?k.1S.2T:k.2W.1Y.5h.5G[1r.5D()?"dY":"dH"];B 4S=("4S"in k.1S)?k.1S.4S:k.2W.1Y.5h.3a.dZ;k.9B=1h J.dq(k.1F,k.1l,k.2W,2T,4S);k.6O=1h J.eh(k.1F,k.1l,k.2W,k.5j)};J.dm.L.c9=C(1V,2h){k.6O.2p(1V,2h)};J.dm.L.3l=C(){if(k.2R){k.1l.4A(k.2R)}k.2R=k.1l.3G(28);k.2R.3B("3j","1Y-gz");k.2R.E.1H="3b";if(k.23){k.1l.4A(k.23)}k.23=k.1l.3G(1);k.23.3B("3j","1Y-cj");k.23.E.1H="3b";B 2P=1h 3f(k.5a.1M());B 3V=k.1l.7F();B l2=k.1l.7i().4h()-k.5a.4h();2P.6r(k.1l.7i().4h()-l2%k.cJ);B p=k;B 9O=C(1q){1i(B i=0;i<p.cJ;i++){D.1f.eL(1q,D.1f.6u)}};B 3r={hm:C(1q,4f){B cW=1q.4h()-p.5a.4h();I{1m:cW,6c:cW==0}}};1P(2P.1M()<3V.1M()){k.9B.dN(2P,3r,D.1f.6u,k.2R,k.23);9O(2P)}k.2R.E.1H="2x";k.23.E.1H="2x"};J.dm.L.5N=C(){};J.e4=C(P){k.1S=P;k.2W=P.1a;k.5a=D.1f.8U(P.1V)};J.e4.L.3M=C(1t,1r){k.1l=1t;k.1F=1r;k.5j=1t.3G(0);k.5j.3B("3j","1Y-2G");k.5j.E.2G=k.2W.1Y.d4[1t.di()];k.2R=N;k.23=N;B 2T=("2T"in k.1S)?k.1S.2T:k.2W.1Y.5h.5G[1r.5D()?"dY":"dH"];B 4S=("4S"in k.1S)?k.1S.4S:k.2W.1Y.5h.3a.dZ;k.9B=1h J.dq(k.1F,k.1l,k.2W,2T,4S);k.6O=1h J.eh(k.1F,k.1l,k.2W,k.5j)};J.e4.L.c9=C(1V,2h){k.6O.2p(1V,2h)};J.e4.L.3l=C(){if(k.2R){k.1l.4A(k.2R)}k.2R=k.1l.3G(28);k.2R.3B("3j","1Y-gz");k.2R.E.1H="3b";if(k.23){k.1l.4A(k.23)}k.23=k.1l.3G(1);k.23.3B("3j","1Y-cj");k.23.E.1H="3b";B 2P=1h 3f(0);B 3V=k.1l.7F();2P.6r(1b.1R(k.5a.4h(),k.1l.7i().4h()));2P.99(k.5a.8R());B p=k;B 9O=C(1q){1q.99(1q.8R()+3)};B 3r={hm:C(1q,4f){B i0=(4+(1q.8R()-p.5a.8R())/3)%4;if(i0!=0){I{1m:"Q"+(i0+1),6c:1B}}S{I{1m:"Y"+(1q.4h()-p.5a.4h()+1),6c:1x}}}};1P(2P.1M()<3V.1M()){k.9B.dN(2P,3r,D.1f.6u,k.2R,k.23);9O(2P)}k.2R.E.1H="2x";k.23.E.1H="2x"};J.e4.L.5N=C(){};J.dq=C(1r,1t,1a,2T,4S){B am=1r.5D();if(am){if(2T=="BX"){k.eI=C(R,1O){R.E.U=1O+"px";R.E.V="4w"}}S{k.eI=C(R,1O){R.E.U=1O+"px";R.E.2j="4w"}}}S{if(2T=="BS"){k.eI=C(R,1O){R.E.V=1O+"px";R.E.U="4w"}}S{k.eI=C(R,1O){R.E.V=1O+"px";R.E.2E="4w"}}}B hp=1a.1Y.5h.5G;B cY=1a.1Y.5h.3a;B ff=1a.1Y.5h.qo;B hV=(am?"h":"v")+2T;B q9=hp[hV+"AT"];B q7=hp[hV+"AY"];B 7n=D.1f.5b[D.1f.6P];k.dN=C(1q,3r,1I,q3,5V){B 1O=1b.1A(1t.2n(1q));if(4S&&1I!=D.1f.9N){B 5T=1r.2D().1y("R");5T.E.2p="2U";if(cY.2m<28){D.1j.4p(5T,cY.2m)}if(am){5T.E.pQ="8i 4v "+cY.1d;5T.E.U=1O+"px";5T.E.X="8i";5T.E.V="4w";5T.E.19="28%"}S{5T.E.pV="8i 4v "+cY.1d;5T.E.V=1O+"px";5T.E.19="8i";5T.E.U="4w";5T.E.X="28%"}5V.1p(5T)}if(1I==D.1f.9N){B 7l=1a.7l;B ht=1h 3f(1q.1M()+(6-7l-7)*7n);B q6=1h 3f(ht.1M()+2*7n);B fx=1b.1A(1t.2n(ht));B q5=1b.1A(1t.2n(q6));B 12=1b.1R(1,q5-fx);B 6e=1r.2D().1y("R");6e.E.2p="2U";6e.E.2G=ff.1d;if(ff.2m<28){D.1j.4p(6e,ff.2m)}if(am){6e.E.U=fx+"px";6e.E.X=12+"px";6e.E.V="4w";6e.E.19="28%"}S{6e.E.V=fx+"px";6e.E.19=12+"px";6e.E.U="4w";6e.E.X="28%"}5V.1p(6e)}B 2w=3r.hm(1q,1I);B R=1r.2D().1y("R");R.3I=2w.1m;R.E.2p="2U";(2w.6c?q7:q9)(R);k.eI(R,1O);q3.1p(R);I R}};J.eh=C(1r,1t,1a,q0){B am=1r.5D();k.5e=N;k.5v=C(){if(k.5e==N){k.5e=1r.2D().1y("R");k.5e.3B("3j","1Y-4q");k.5e.E.2p="2U";k.5e.E.2G=1a.1Y.pZ;B 2m=1a.1Y.pY;if(2m<28){D.1j.4p(k.5e,2m)}q0.1p(k.5e)}}k.2p=C(1V,2h){k.5v();B 1Q=1b.1A(1t.2n(1V));B 3C=1b.1A(1t.2n(2h));B 12=1b.1R(3C-1Q,3);if(am){k.5e.E.U=1Q+"px";k.5e.E.X=12+"px";k.5e.E.V="gL";k.5e.E.19=(1t.gC()-4)+"px"}S{k.5e.E.V=1Q+"px";k.5e.E.19=12+"px";k.5e.E.U="gL";k.5e.E.X=(1t.gC()-4)+"px"}}};J.55=C(3T,2I){k.6T=3T;k.7d=2I};J.55.q2=[];J.55.CK=[];J.55.qa=[];J.55.fK=C(aF,3T){I J.55.q2[3T][aF]};J.55.L.hm=C(1q,4f){B f=J.55.qa[k.6T];if(f==N){f=J.55.L.qb}I f.hJ(k,1q,4f)};J.55.L.7S=C(1q){I D.1f.hQ(1q,k.7d).qm()};J.55.L.qb=C(1q,4f){B 1m;B 6c=1B;1q=D.1f.hQ(1q,k.7d);79(4f){1K D.1f.e6:1m=1q.qk();1v;1K D.1f.aW:1m=1q.qj();1v;1K D.1f.8c:B m=1q.ql();if(m==0){1m=1q.hA()+":jk";6c=1x}S{1m=m}1v;1K D.1f.7a:1m=1q.hA()+"hr";1v;1K D.1f.6P:1m=J.55.fK(1q.8R(),k.6T)+" "+1q.fH();1v;1K D.1f.9N:1m=J.55.fK(1q.8R(),k.6T)+" "+1q.fH();1v;1K D.1f.aM:B m=1q.8R();if(m!=0){1m=J.55.fK(m,k.6T);1v}1K D.1f.6u:1K D.1f.ak:1K D.1f.b1:1K D.1f.8h:B y=1q.4h();if(y>0){1m=1q.4h()}S{1m=(1-y)+"BC"}6c=(4f==D.1f.aM)||(4f==D.1f.ak&&y%28==0)||(4f==D.1f.b1&&y%61==0);1v;aN:1m=1q.qm()}I{1m:1m,6c:6c}}J.2A=C(bD){k.21=(bD 7w 4C)?bD:1h D.3W();k.67=[]};J.2A.L.84=C(2e){k.67.1L(2e)};J.2A.L.85=C(2e){1i(B i=0;i<k.67.12;i++){if(k.67[i]==2e){k.67.5s(i,1);1v}}};J.2A.L.ds=C(3w,1k){B 4M=k.bd(1k);B 76=3w.68.4B("bz-1k");B 74=3w.68.4B("bz-qd");B 7V=3w.68.4B("1q-29-6i");B 52=k.21.6N().aa(7V);B 1N=3w.68.32;B 6G=1B;1P(1N!=N){if(1N.6b==1){B 8O="";if(1N.32!=N&&1N.32.6b==3){8O=1N.32.cq}B K=1h J.2A.dO(1N.4B("id"),52(1N.4B("2i")),52(1N.4B("45")),52(1N.4B("bW")),52(1N.4B("bV")),1N.4B("hM")!="1x",1N.4B("7R"),8O,k.7Z(1N.4B("2Y"),4M),k.7Z(1N.4B("51"),4M),k.7Z(1N.4B("2O"),4M),1N.4B("1d"),1N.4B("9T"));K.qn=1N;K.dX=C(3j){I k.qn.4B(3j)};K.gD(76,74);k.21.5c(K);6G=1x}1N=1N.au}if(6G){k.9h("8I",[])}};J.2A.L.hS=C(2f,1k){B 4M=k.bd(1k);B 6G=1B;if(2f&&2f.46){B 76=("76"in 2f)?2f.76:N;B 74=("74"in 2f)?2f.74:N;B 7V=("7V"in 2f)?2f.7V:N;B 52=k.21.6N().aa(7V);1i(B i=0;i<2f.46.12;i++){B 1o=2f.46[i];B K=1h J.2A.dO(("id"in 1o)?1o.id:5S,52(1o.2i),52(1o.45),52(1o.bW),52(1o.bV),1o.hM||1B,1o.7R,1o.8O,k.7Z(1o.2Y,4M),k.7Z(1o.51,4M),k.7Z(1o.2O,4M),1o.1d,1o.9T);K.qi=1o;K.dX=C(3j){I k.qi[3j]};K.gD(76,74);k.21.5c(K);6G=1x}}if(6G){k.9h("8I",[])}};J.2A.L.xT=C(3w,1k){B 4M=k.bd(1k);B 7V=\'eA\';B 52=k.21.6N().aa(7V);if(3w==N){I}B 1N=3w.68.32;1P(1N!=N&&(1N.6b!=1||1N.xI!=\'xy\')){1N=1N.au}B 76=N;B 74=N;if(1N!=N){76=1N.4B("bz-1k");74=1N.4B("bz-qd");1N=1N.32}B 6G=1B;1P(1N!=N){if(1N.6b==1){B 4n={};B 6V=1N.32;1P(6V!=N){if(6V.6b==1&&6V.32!=N&&6V.32.6b==1&&6V.32.32!=N&&6V.32.32.6b==3){4n[6V.4B(\'3j\')]=6V.32.32.cq}6V=6V.au}if(4n["2i"]==N&&4n["1q"]!=N){4n["2i"]=4n["1q"]}B K=1h J.2A.dO(4n["id"],52(4n["2i"]),52(4n["45"]),52(4n["bW"]),52(4n["bV"]),4n["hM"]!="1x",4n["7R"],4n["8O"],k.7Z(4n["2Y"],4M),k.7Z(4n["51"],4M),k.7Z(4n["2O"],4M),4n["1d"],4n["9T"]);K.qc=4n;K.dX=C(3j){I k.qc[3j]};K.gD(76,74);k.21.5c(K);6G=1x}1N=1N.au}if(6G){k.9h("8I",[])}};J.2A.L.5c=C(K){k.21.5c(K);k.9h("xC",[K])};J.2A.L.xD=C(46){1i(B i=0;i<46.12;i++){k.21.5c(46[i])}k.9h("8I",[])};J.2A.L.xG=C(){k.21.f2();k.9h("db",[])};J.2A.L.eV=C(id){I k.21.eV(id)};J.2A.L.xU=C(1V,2h){I k.21.qf(1V,2h)};J.2A.L.fc=C(1V,2h){I k.21.qg(1V,2h)};J.2A.L.iF=C(){I k.21.pX()};J.2A.L.g6=C(){I k.21.g6()};J.2A.L.ba=C(){I k.21.ba()};J.2A.L.bC=C(){I k.21.bC()};J.2A.L.9h=C(6f,fv){1i(B i=0;i<k.67.12;i++){B 2e=k.67[i];if(6f in 2e){3N{2e[6f].71(2e,fv)}4c(e){D.3h.6E(e)}}}};J.2A.L.bd=C(1k){if(1k.1X("://")<0){B dK=k.bd(1G.bi.9M);if(1k.4d(0,1)=="/"){1k=dK.4d(0,dK.1X("/",dK.1X("://")+3))+1k}S{1k=dK+1k}}B i=1k.yc("/");if(i<0){I""}S{I 1k.4d(0,i+1)}};J.2A.L.7Z=C(1k,4M){if(1k==N||1k==""){I 1k}S if(1k.1X("://")>0){I 1k}S if(1k.4d(0,1)=="/"){I 4M.4d(0,4M.1X("/",4M.1X("://")+3))+1k}S{I 4M+1k}};J.2A.dO=C(id,2i,45,bW,bV,5l,1m,8O,2Y,51,2O,1d,9T){id=(id)?id.pW():"";k.3k=id.12>0?id:("e"+1b.5P(1b.cC()*cM));k.hZ=5l||(45==N);k.3y=2i;k.9m=(45!=N)?45:2i;k.gs=(bW!=N)?bW:(5l?k.9m:k.3y);k.gr=(bV!=N)?bV:(5l?k.3y:k.9m);k.pE=D.9W.hE(1m);k.hL=D.9W.hE(8O);k.pD=(2Y!=N&&2Y!="")?2Y:N;k.pF=(51!=N&&51!="")?51:N;k.pG=(2O!=N&&2O!="")?2O:N;k.9z=(1d!=N&&1d!="")?1d:N;k.nf=(9T!=N&&9T!="")?9T:N;k.ea=N;k.dp=N};J.2A.dO.L={4K:C(){I k.3k},fg:C(){I k.hZ},az:C(){I k.3y!=k.gs||k.9m!=k.gr},3P:C(){I k.3y},5K:C(){I k.9m},gG:C(){I k.gs},gI:C(){I k.gr},73:C(){I k.pE},y0:C(){I k.hL},pu:C(){I k.pD},pv:C(){I k.pF},hq:C(){I k.pG},7p:C(){I k.9z},hx:C(){I k.nf},dX:C(3j){I N},y5:C(){I k.ea},y4:C(){I k.dp},gD:C(76,74){k.ea=76;k.dp=74},pA:C(M){M.3I=k.hL},pS:C(M){if(k.ea!=N&&k.dp!=N){B 9c=k.dX("9c");if(9c==N||9c.12==0){9c=k.73()}9c=9c.5F(/\\s/g,"pH");B 1k=k.ea+k.dp.5F(/\\s/g,"pH")+"/"+9c;B a=1G.1y("a");a.9M=1k;a.1C="1h";a.3I=J.pC[J.hG].y2;M.1p(1G.7m("["));M.1p(a);M.1p(1G.7m("]"))}S{M.E.1H="3b"}},pI:C(M,3r){if(k.hZ){if(k.az()){M.1p(M.4U.7m(3r.7S(k.3y)));M.1p(M.4U.1y("br"));M.1p(M.4U.7m(3r.7S(k.9m)))}S{M.1p(M.4U.7m(3r.7S(k.3y)))}}S{if(k.az()){M.1p(M.4U.7m(3r.7S(k.3y)+" ~ "+3r.7S(k.gs)));M.1p(M.4U.1y("br"));M.1p(M.4U.7m(3r.7S(k.gr)+" ~ "+3r.7S(k.9m)))}S{M.1p(M.4U.7m(3r.7S(k.3y)));M.1p(M.4U.1y("br"));M.1p(M.4U.7m(3r.7S(k.9m)))}}},h4:C(M,1a,3r){B 1u=M.4U;B 7R=k.73();B 51=k.pv();B 2Y=k.pu();if(2Y!=N){B 48=1u.1y("48");48.5B=2Y;1a.1o.2o.pw(48);M.1p(48)}B cS=1u.1y("R");B hW=1u.7m(7R);if(51!=N){B a=1u.1y("a");a.9M=51;a.1p(hW);cS.1p(a)}S{cS.1p(hW)}1a.1o.2o.py(cS);M.1p(cS);B gP=1u.1y("R");k.pA(gP);1a.1o.2o.pz(gP);M.1p(gP);B gJ=1u.1y("R");k.pI(gJ,3r);1a.1o.2o.pJ(gJ);M.1p(gJ);B gN=1u.1y("R");k.pS(gN);1a.1o.2o.pR(gN);M.1p(gN)}};J.2V=C(P){k.1S=P;k.4u=[];k.5o=N;k.5n=N;k.5g=N;k.5f={}};J.2V.L.3M=C(1t,1r){k.1l=1t;k.1F=1r;k.7C=N;k.3q=N;k.23=N;k.43=N;k.5f=N};J.2V.L.hs=C(2e){k.4u.1L(2e)};J.2V.L.hC=C(2e){1i(B i=0;i<k.4u.12;i++){if(k.4u[i]==2e){k.4u.5s(i,1);1v}}};J.2V.L.hu=C(){I k.5o};J.2V.L.hz=C(6K){k.5o=6K};J.2V.L.hv=C(){I k.5n};J.2V.L.hw=C(6l){k.5n=6l};J.2V.L.3l=C(){B 2L=k.1l.es();if(2L==N){I}k.5f={};k.bx();B 2F=k.1S.1a.1o;B 3m=1b.1R(2F.3i.19,2F.ce.19+k.5g.hF());B 1e={4N:2F.3i.8A,3m:3m,8L:2F.3i.8A,4E:3m+2F.3i.8A,2O:2F.5l.2O,5A:2F.5l.5A,8n:2F.5l.8n,pT:2F.2w.X}B 2P=k.1l.7i();B 3V=k.1l.7F();B 6K=(k.5o!=N)?k.5o:C(K){I 1x};B 6l=(k.5n!=N)?k.5n:C(K){I-1};B 6J=2L.fc(2P,3V);1P(6J.9i()){B K=6J.6I();if(6K(K)){k.bo(K,1e,k.1S.1a,6l(K))}}k.43.E.1H="2x";k.23.E.1H="2x";k.3q.E.1H="2x"};J.2V.L.5N=C(){};J.2V.L.bx=C(){B 1t=k.1l;if(k.7C==N){k.7C=k.1l.3G(0,"1r-1t-46");k.7C.E.8b="4b";B 9C=1G.1y("fD");9C.1W="1r-1o-2w";k.7C.1p(9C);k.5g=D.1j.hB(9C)}k.5g.6H();k.7f=[];if(k.43!=N){1t.4A(k.43)}k.43=1t.3G(hU,"1r-1t-i3");k.43.E.1H="3b";if(k.23!=N){1t.4A(k.23)}k.23=1t.3G(gU,"1r-1t-cj");k.23.E.1H="3b";if(k.3q!=N){1t.4A(k.3q)}k.3q=1t.3G(z4,"1r-1t-46");k.3q.E.1H="3b"};J.2V.L.bo=C(K,1e,1a,1U){if(K.fg()){k.bq(K,1e,1a,1U)}S{k.bu(K,1e,1a,1U)}};J.2V.L.bq=C(K,1e,1a,1U){if(K.az()){k.eZ(K,1e,1a,1U)}S{k.fr(K,1e,1a,1U)}}J.2V.L.bu=C(K,1e,1a,1U){if(K.az()){k.fZ(K,1e,1a,1U)}S{k.fQ(K,1e,1a,1U)}}J.2V.L.fr=C(K,1e,1a,1U){B 1u=k.1F.2D();B 1m=K.73();B 1V=K.3P();B 1Q=1b.1A(k.1l.2n(1V));B 8C=1b.1A(1Q+1e.5A/2);B 5q=1b.1A(1Q-1e.5A/2);B 2l=k.5g.8V(1m);B 2Z=8C+1a.1o.2w.7T;B 6F=2Z+2l.X;B 7W=6F;B 3i=k.df(7W);B 5i=1b.1A(1e.4N+3i*1e.4E+1e.3m/2-2l.19/2);B 4m=k.cK(K,3i,5q,1e,1a);B 5d=k.7r(K,1m,2Z,5i,2l.X,2l.19,1a);B 4g=k;B 3g=C(M,2q,1C){I 4g.9a(4m.M,2q,K)};D.1g.2a(4m.M,"3R",3g);D.1g.2a(5d.M,"3R",3g);k.5v(1U,4m,1a);k.5f[K.4K()]=4m.M;k.7f[3i]=5q};J.2V.L.eZ=C(K,1e,1a,1U){B 1u=k.1F.2D();B 1m=K.73();B 1V=K.3P();B 2h=K.5K();B 1Q=1b.1A(k.1l.2n(1V));B 3C=1b.1A(k.1l.2n(2h));B 8C=1b.1A(1Q+1e.5A/2);B 5q=1b.1A(1Q-1e.5A/2);B 2l=k.5g.8V(1m);B 2Z=8C+1a.1o.2w.7T;B 6F=2Z+2l.X;B 7W=1b.1R(6F,3C);B 3i=k.df(7W);B 5i=1b.1A(1e.4N+3i*1e.4E+1e.3m/2-2l.19/2);B 4m=k.cK(K,3i,5q,1e,1a);B 5d=k.7r(K,1m,2Z,5i,2l.X,2l.19,1a);B 3z=k.6v(K,3i,1Q,3C,1a.1o.5l.cl,1a.1o.5l.cv,1e,1a);B 4g=k;B 3g=C(M,2q,1C){I 4g.9a(4m.M,2q,K)};D.1g.2a(4m.M,"3R",3g);D.1g.2a(3z.M,"3R",3g);D.1g.2a(5d.M,"3R",3g);k.5v(1U,4m,1a);k.5f[K.4K()]=4m.M;k.7f[3i]=5q};J.2V.L.fQ=C(K,1e,1a,1U){B 1u=k.1F.2D();B 1m=K.73();B 1V=K.3P();B 2h=K.5K();B 1Q=1b.1A(k.1l.2n(1V));B 3C=1b.1A(k.1l.2n(2h));B 2l=k.5g.8V(1m);B 2Z=1Q;B 6F=2Z+2l.X;B 7W=1b.1R(6F,3C);B 3i=k.df(7W);B 5i=1b.1A(1e.4N+3i*1e.4E+1a.1o.ce.19);B 1d=K.7p();1d=1d!=N?1d:1a.1o.4J.1d;B 3z=k.6v(K,3i,1Q,3C,1d,28,1e,1a);B 5d=k.7r(K,1m,2Z,5i,2l.X,2l.19,1a);B 4g=k;B 3g=C(M,2q,1C){I 4g.9a(3z.M,2q,K)};D.1g.2a(3z.M,"3R",3g);D.1g.2a(5d.M,"3R",3g);k.5v(1U,3z,1a);k.5f[K.4K()]=3z.M;k.7f[3i]=1Q};J.2V.L.fZ=C(K,1e,1a,1U){B 1u=k.1F.2D();B 1m=K.73();B 1V=K.3P();B bj=K.gG();B 2h=K.5K();B bF=K.gI();B 1Q=1b.1A(k.1l.2n(1V));B 6Z=1b.1A(k.1l.2n(bj));B 3C=1b.1A(k.1l.2n(2h));B 9e=1b.1A(k.1l.2n(bF));B 2l=k.5g.8V(1m);B 2Z=6Z;B 6F=2Z+2l.X;B 7W=1b.1R(6F,3C);B 3i=k.df(7W);B 5i=1b.1A(1e.4N+3i*1e.4E+1a.1o.ce.19);B 1d=K.7p();1d=1d!=N?1d:1a.1o.4J.1d;B pU=k.6v(K,3i,1Q,3C,1a.1o.4J.cl,1a.1o.4J.cv,1e,1a);B 3z=k.6v(K,3i,6Z,9e,1d,28,1e,1a);B 5d=k.7r(K,1m,2Z,5i,2l.X,2l.19,1a);B 4g=k;B 3g=C(M,2q,1C){I 4g.9a(3z.M,2q,K)};D.1g.2a(3z.M,"3R",3g);D.1g.2a(5d.M,"3R",3g);k.5v(1U,3z,1a);k.5f[K.4K()]=3z.M;k.7f[3i]=1Q};J.2V.L.df=C(7W){1i(B i=0;i<k.7f.12;i++){B t=k.7f[i];if(t>7W){1v}}I i};J.2V.L.cK=C(K,4a,U,1e,1a){B 2O=K.hq();2O=2O!=N?2O:1e.2O;B 7y=1e.4N+4a*1e.4E+1e.3m/2;B V=1b.1A(7y-1e.8n/2);B 48=D.1j.9q(2O);B 59=k.1F.2D().1y("R");59.E.2p="2U";59.E.U=U+"px";59.E.V=V+"px";59.1p(48);59.E.7G="a9";k.3q.1p(59);I{U:U,V:V,X:1e.5A,19:1e.8n,M:59}};J.2V.L.7r=C(K,1m,U,V,X,19,1a){B 1u=k.1F.2D();B 4i=1u.1y("R");4i.E.2p="2U";4i.E.U=U+"px";4i.E.X=X+"px";4i.E.V=V+"px";4i.3I=1m;4i.E.7G="a9";B 1d=K.hx();if(1d==N){1d=K.7p()}if(1d!=N){4i.E.1d=1d}k.3q.1p(4i);I{U:U,V:V,X:X,19:19,M:4i}};J.2V.L.6v=C(K,4a,1Q,3C,1d,2m,1e,1a){B bn=3C-1Q;B 9X=1a.1o.ce.19;B V=1e.4N+4a*1e.4E;B 2z=k.1F.2D().1y("R");2z.E.2p="2U";2z.E.U=1Q+"px";2z.E.X=bn+"px";2z.E.V=V+"px";2z.E.19=9X+"px";2z.E.94=1d;2z.E.5t="4b";2z.E.7G="a9";D.1j.4p(2z,2m);k.3q.1p(2z);I{U:1Q,V:V,X:bn,19:9X,M:2z}}J.2V.L.5v=C(1U,5E,1a){if(1U>=0){B 1u=k.1F.2D();B 2F=1a.1o;B 1d=2F.ag[1b.2b(1U,2F.ag.12-1)];B R=1u.1y("R");R.E.2p="2U";R.E.5t="4b";R.E.U=(5E.U-2)+"px";R.E.X=(5E.X+4)+"px";R.E.V=(5E.V-2)+"px";R.E.19=(5E.19+4)+"px";R.E.2G=1d;k.43.1p(R)}};J.2V.L.9a=C(2O,2q,K){B c=D.1g.6z(2O);k.9L(c.U+1b.g3(2O.63/2),c.V+1b.g3(2O.5M/2),K);k.b8(K.4K());2q.eN=1x;D.1g.70(2q);I 1B};J.2V.L.f7=C(1C,2q,K){if("4z"in 2q){B x=2q.4z;B y=2q.5y}S{B c=D.1g.6z(1C);B x=2q.hX+c.U;B y=2q.hN+c.V}k.9L(x,y,K);k.b8(K.4K());2q.eN=1x;D.1g.70(2q);I 1B};J.2V.L.f4=C(K){B M=k.5f[K.4K()];if(M){B c=D.1g.6z(M);k.9L(c.U+M.63/2,c.V+M.5M/2,K)}};J.2V.L.9L=C(x,y,K){B R=1G.1y("R");K.h4(R,k.1S.1a,k.1l.eg());D.1c.ef();D.1j.i1(R,x,y,k.1S.1a.1o.2o.X)};J.2V.L.b8=C(b6){1i(B i=0;i<k.4u.12;i++){k.4u[i](b6)}};J.2y=C(P){k.1S=P;k.4u=[];k.5o=N;k.5n=N;k.5g=N;k.5f={}};J.2y.L.3M=C(1t,1r){k.1l=1t;k.1F=1r;k.7C=N;k.3q=N;k.23=N;k.43=N;k.5f=N};J.2y.L.hs=C(2e){k.4u.1L(2e)};J.2y.L.hC=C(2e){1i(B i=0;i<k.4u.12;i++){if(k.4u[i]==2e){k.4u.5s(i,1);1v}}};J.2y.L.hu=C(){I k.5o};J.2y.L.hz=C(6K){k.5o=6K};J.2y.L.hv=C(){I k.5n};J.2y.L.hw=C(6l){k.5n=6l};J.2y.L.3l=C(){B 2L=k.1l.es();if(2L==N){I}k.5f={};k.bx();B 2F=k.1S.1a.1o;B 3m=1b.1R(2F.3i.19,k.5g.hF());B 1e={4N:1b.1A(k.1l.gC()/2-3m/2),3m:3m,8L:2F.3i.8A,4E:3m+2F.3i.8A,2O:2F.5l.2O,5A:2F.5l.5A,8n:2F.5l.8n,pT:2F.2w.X}B 2P=k.1l.7i();B 3V=k.1l.7F();B 6K=(k.5o!=N)?k.5o:C(K){I 1x};B 6l=(k.5n!=N)?k.5n:C(K){I-1};B 6J=2L.fc(2P,3V);1P(6J.9i()){B K=6J.6I();if(6K(K)){k.bo(K,1e,k.1S.1a,6l(K))}}k.43.E.1H="2x";k.23.E.1H="2x";k.3q.E.1H="2x"};J.2y.L.5N=C(){};J.2y.L.bx=C(){B 1t=k.1l;if(k.7C==N){k.7C=k.1l.3G(0,"1r-1t-46");k.7C.E.8b="4b";B 9C=1G.1y("fD");9C.1W="1r-1o-2w";k.7C.1p(9C);k.5g=D.1j.hB(9C)}k.5g.6H();k.7O=[];k.7K=[];if(k.43!=N){1t.4A(k.43)}k.43=1t.3G(hU,"1r-1t-i3");k.43.E.1H="3b";if(k.23!=N){1t.4A(k.23)}k.23=1t.3G(gU,"1r-1t-cj");k.23.E.1H="3b";if(k.3q!=N){1t.4A(k.3q)}k.3q=1t.3G(gU,"1r-1t-46");k.3q.E.1H="3b"};J.2y.L.bo=C(K,1e,1a,1U){if(K.fg()){k.bq(K,1e,1a,1U)}S{k.bu(K,1e,1a,1U)}};J.2y.L.bq=C(K,1e,1a,1U){if(K.az()){k.eZ(K,1e,1a,1U)}S{k.fr(K,1e,1a,1U)}}J.2y.L.bu=C(K,1e,1a,1U){if(K.az()){k.fZ(K,1e,1a,1U)}S{k.fQ(K,1e,1a,1U)}}J.2y.L.fr=C(K,1e,1a,1U){B 1u=k.1F.2D();B 1m=K.73();B 1V=K.3P();B 1Q=1b.1A(k.1l.2n(1V));B 8C=1b.1A(1Q+1e.5A/2);B 5q=1b.1A(1Q-1e.5A/2);B 2l=k.5g.8V(1m);B 4a=k.ed(8C,1Q);B 4m=k.cK(K,4a,5q,1e,1a);B 2Z=8C+1a.1o.2w.7T;B 4x=4a;B 9s=k.8l(4a);if(1b.2b(9s.4v,9s.1m)>=2Z+2l.X){9s.4v=5q;9s.1m=2Z}S{9s.4v=5q;2Z=1Q+1a.1o.2w.7T;4x=k.eQ(4a,2Z+2l.X,C(t){t.3a=1Q-2});k.8l(4x).1m=5q;k.eO(K,1Q,4a,4x,1e,1a)}B 5i=1b.1A(1e.4N+4x*1e.4E+1e.3m/2-2l.19/2);B 5d=k.7r(K,1m,2Z,5i,2l.X,2l.19,1a);B 4g=k;B 3g=C(M,2q,1C){I 4g.9a(4m.M,2q,K)};D.1g.2a(4m.M,"3R",3g);D.1g.2a(5d.M,"3R",3g);k.5v(1U,4m,1a);k.5f[K.4K()]=4m.M};J.2y.L.eZ=C(K,1e,1a,1U){B 1u=k.1F.2D();B 1m=K.73();B 1V=K.3P();B 2h=K.5K();B 1Q=1b.1A(k.1l.2n(1V));B 3C=1b.1A(k.1l.2n(2h));B 8C=1b.1A(1Q+1e.5A/2);B 5q=1b.1A(1Q-1e.5A/2);B 2l=k.5g.8V(1m);B 4a=k.ed(3C,1Q);B 3z=k.6v(K,4a,1Q,3C,1a.1o.5l.cl,1a.1o.5l.cv,1e,1a);B 4m=k.cK(K,4a,5q,1e,1a);B 9s=k.8l(4a);9s.4v=5q;B 2Z=8C+1a.1o.2w.7T;B 6F=2Z+2l.X;B 4x;if(6F<3C){4x=4a}S{2Z=1Q+1a.1o.2w.7T;6F=2Z+2l.X;4x=k.eQ(4a,6F,C(t){t.3a=1Q-2});k.8l(4x).1m=5q;k.eO(K,1Q,4a,4x,1e,1a)}B 5i=1b.1A(1e.4N+4x*1e.4E+1e.3m/2-2l.19/2);B 5d=k.7r(K,1m,2Z,5i,2l.X,2l.19,1a);B 4g=k;B 3g=C(M,2q,1C){I 4g.9a(4m.M,2q,K)};D.1g.2a(4m.M,"3R",3g);D.1g.2a(3z.M,"3R",3g);D.1g.2a(5d.M,"3R",3g);k.5v(1U,4m,1a);k.5f[K.4K()]=4m.M};J.2y.L.fQ=C(K,1e,1a,1U){B 1u=k.1F.2D();B 1m=K.73();B 1V=K.3P();B 2h=K.5K();B 1Q=1b.1A(k.1l.2n(1V));B 3C=1b.1A(k.1l.2n(2h));B 2l=k.5g.8V(1m);B 4W=k.ed(3C);B 1d=K.7p();1d=1d!=N?1d:1a.1o.4J.1d;B 3z=k.6v(K,4W,1Q,3C,1d,28,1e,1a);B gV=k.8l(4W);gV.4v=1Q;B 2Z=1Q+1a.1o.2w.7T;B 4x=k.eQ(4W,2Z+2l.X,C(t){t.3a=1Q-2});k.8l(4x).1m=1Q-2;k.eO(K,1Q,4W,4x,1e,1a);B 5i=1b.1A(1e.4N+4x*1e.4E+1e.3m/2-2l.19/2);B 5d=k.7r(K,1m,2Z,5i,2l.X,2l.19,1a);B 4g=k;B 3g=C(M,2q,1C){I 4g.f7(3z.M,2q,K)};D.1g.2a(3z.M,"3R",3g);D.1g.2a(5d.M,"3R",3g);k.5v(1U,3z,1a);k.5f[K.4K()]=3z.M};J.2y.L.fZ=C(K,1e,1a,1U){B 1u=k.1F.2D();B 1m=K.73();B 1V=K.3P();B bj=K.gG();B 2h=K.5K();B bF=K.gI();B 1Q=1b.1A(k.1l.2n(1V));B 6Z=1b.1A(k.1l.2n(bj));B 3C=1b.1A(k.1l.2n(2h));B 9e=1b.1A(k.1l.2n(bF));B 2l=k.5g.8V(1m);B 4W=k.ed(3C);B 1d=K.7p();1d=1d!=N?1d:1a.1o.4J.1d;B pU=k.6v(K,4W,1Q,3C,1a.1o.4J.cl,1a.1o.4J.cv,1e,1a);B 3z=k.6v(K,4W,6Z,9e,1d,28,1e,1a);B gV=k.8l(4W);gV.4v=1Q;B 2Z=6Z+1a.1o.2w.7T;B 4x=k.eQ(4W,2Z+2l.X,C(t){t.3a=6Z-2});k.8l(4x).1m=6Z-2;k.eO(K,6Z,4W,4x,1e,1a);B 5i=1b.1A(1e.4N+4x*1e.4E+1e.3m/2-2l.19/2);B 5d=k.7r(K,1m,2Z,5i,2l.X,2l.19,1a);B 4g=k;B 3g=C(M,2q,1C){I 4g.f7(3z.M,2q,K)};D.1g.2a(3z.M,"3R",3g);D.1g.2a(5d.M,"3R",3g);k.5v(1U,3z,1a);k.5f[K.4K()]=3z.M};J.2y.L.ed=C(hP,ei){1i(B i=0;1x;i++){if(i<k.7O.12){B t=k.7O[i];if(1b.2b(t.4v,t.1m)>hP&&(!(ei)||t.3a>ei)){I i}}S{k.7O.1L({4v:2r.54,1m:2r.54,3a:2r.54});I i}if(i<k.7K.12){B t=k.7K[i];if(1b.2b(t.4v,t.1m)>hP&&(!(ei)||t.3a>ei)){I-1-i}}S{k.7K.1L({4v:2r.54,1m:2r.54,3a:2r.54});I-1-i}}};J.2y.L.eQ=C(ex,8o,hn){B cy;B 1T;B 8u;B 3L;if(ex<0){cy=1x;8u=-ex;1T=k.hT(8u,8o);3L=-1-1T}S if(ex>0){cy=1B;8u=ex+1;1T=k.ho(8u,8o);3L=1T}S{B hy=k.hT(0,8o);B hD=k.ho(1,8o);if(hD-1<=hy){cy=1B;8u=1;1T=hD;3L=1T}S{cy=1x;8u=0;1T=hy;3L=-1-1T}}if(cy){if(1T==k.7K.12){k.7K.1L({4v:2r.54,1m:2r.54,3a:2r.54})}1i(B i=8u;i<1T;i++){hn(k.7K[i])}}S{if(1T==k.7O.12){k.7O.1L({4v:2r.54,1m:2r.54,3a:2r.54})}1i(B i=8u;i<1T;i++){hn(k.7O[i])}}I 3L};J.2y.L.ho=C(1T,8o){1i(;1T<k.7O.12;1T++){B t=k.7O[1T];if(1b.2b(t.4v,t.1m)>=8o){1v}}I 1T};J.2y.L.hT=C(1T,8o){1i(;1T<k.7K.12;1T++){B t=k.7K[1T];if(1b.2b(t.4v,t.1m)>=8o){1v}}I 1T};J.2y.L.8l=C(1T){I(1T<0)?k.7K[-1T-1]:k.7O[1T]};J.2y.L.eO=C(K,U,f1,hO,1e,1a){B V=1b.1A(1e.4N+f1*1e.4E+1e.3m/2);B 19=1b.1A(1b.6S(hO-f1)*1e.4E);B gf="8i 4v "+1a.1o.2w.7q;B 5V=k.1F.2D().1y("R");5V.E.2p="2U";5V.E.U=U+"px";5V.E.X=1a.1o.2w.7T+"px";5V.E.19=19+"px";if(f1>hO){5V.E.V=(V-19)+"px";5V.E.pV=gf}S{5V.E.V=V+"px";5V.E.A5=gf}5V.E.pQ=gf;k.23.1p(5V)};J.2y.L.cK=C(K,4a,U,1e,1a){B 2O=K.hq();2O=2O!=N?2O:1e.2O;B 7y=1e.4N+4a*1e.4E+1e.3m/2;B V=1b.1A(7y-1e.8n/2);B 48=D.1j.9q(2O);B 59=k.1F.2D().1y("R");59.E.2p="2U";59.E.U=U+"px";59.E.V=V+"px";59.1p(48);59.E.7G="a9";k.3q.1p(59);I{U:U,V:V,X:1e.5A,19:1e.8n,M:59}};J.2y.L.7r=C(K,1m,U,V,X,19,1a){B 1u=k.1F.2D();B 89=1u.1y("R");89.E.2p="2U";89.E.U=U+"px";89.E.X=X+"px";89.E.V=V+"px";89.E.19=19+"px";89.E.94=1a.1o.2w.94;D.1j.4p(89,1a.1o.2w.pP);k.3q.1p(89);B 4i=1u.1y("R");4i.E.2p="2U";4i.E.U=U+"px";4i.E.X=X+"px";4i.E.V=V+"px";4i.3I=1m;4i.E.7G="a9";B 1d=K.hx();if(1d==N){1d=K.7p()}if(1d!=N){4i.E.1d=1d}k.3q.1p(4i);I{U:U,V:V,X:X,19:19,M:4i}};J.2y.L.6v=C(K,4a,1Q,3C,1d,2m,1e,1a){B bn=3C-1Q;B 9X=1a.1o.ce.19;B 7y=1e.4N+4a*1e.4E+1e.3m/2;B V=1b.1A(7y-9X/2);B 2z=k.1F.2D().1y("R");2z.E.2p="2U";2z.E.U=1Q+"px";2z.E.X=bn+"px";2z.E.V=V+"px";2z.E.19=9X+"px";2z.E.94=1d;2z.E.5t="4b";2z.E.7G="a9";D.1j.4p(2z,2m);k.3q.1p(2z);I{U:1Q,V:V,X:bn,19:9X,M:2z}}J.2y.L.5v=C(1U,5E,1a){if(1U>=0){B 1u=k.1F.2D();B 2F=1a.1o;B 1d=2F.ag[1b.2b(1U,2F.ag.12-1)];B R=1u.1y("R");R.E.2p="2U";R.E.5t="4b";R.E.U=(5E.U-2)+"px";R.E.X=(5E.X+4)+"px";R.E.V=(5E.V-2)+"px";R.E.19=(5E.19+4)+"px";R.E.2G=1d;k.43.1p(R)}};J.2y.L.9a=C(2O,2q,K){B c=D.1g.6z(2O);k.9L(c.U+1b.g3(2O.63/2),c.V+1b.g3(2O.5M/2),K);k.b8(K.4K());2q.eN=1x;D.1g.70(2q);I 1B};J.2y.L.f7=C(1C,2q,K){if("4z"in 2q){B x=2q.4z;B y=2q.5y}S{B c=D.1g.6z(1C);B x=2q.hX+c.U;B y=2q.hN+c.V}k.9L(x,y,K);k.b8(K.4K());2q.eN=1x;D.1g.70(2q);I 1B};J.2y.L.f4=C(K){B M=k.5f[K.4K()];if(M){B c=D.1g.6z(M);k.9L(c.U+M.63/2,c.V+M.5M/2,K)}};J.2y.L.9L=C(x,y,K){B R=1G.1y("R");K.h4(R,k.1S.1a,k.1l.eg());D.1c.ef();D.1j.i1(R,x,y,k.1S.1a.1o.2o.X)};J.2y.L.b8=C(b6){1i(B i=0;i<k.4u.12;i++){k.4u[i](b6)}};J.4l=C(P){k.1S=P;k.4u=[];k.5o=N;k.5n=N};J.4l.L.3M=C(1t,1r){k.1l=1t;k.1F=1r;k.3q=N;k.43=N};J.4l.L.hs=C(2e){k.4u.1L(2e)};J.4l.L.hC=C(2e){1i(B i=0;i<k.4u.12;i++){if(k.4u[i]==2e){k.4u.5s(i,1);1v}}};J.4l.L.hu=C(){I k.5o};J.4l.L.hz=C(6K){k.5o=6K};J.4l.L.hv=C(){I k.5n};J.4l.L.hw=C(6l){k.5n=6l};J.4l.L.3l=C(){B 2L=k.1l.es();if(2L==N){I}k.bx();B 2F=k.1S.1a.1o;B 1e={4N:2F.9P.1O,3m:2F.9P.19,8L:2F.9P.8A,4E:2F.9P.19+2F.9P.8A}B 2P=k.1l.7i();B 3V=k.1l.7F();B 6K=(k.5o!=N)?k.5o:C(K){I 1x};B 6l=(k.5n!=N)?k.5n:C(K){I-1};B 6J=2L.fc(2P,3V);1P(6J.9i()){B K=6J.6I();if(6K(K)){k.bo(K,1e,k.1S.1a,6l(K))}}k.43.E.1H="2x";k.3q.E.1H="2x"};J.4l.L.5N=C(){};J.4l.L.bx=C(){B 1t=k.1l;k.7f=[];if(k.43!=N){1t.4A(k.43)}k.43=1t.3G(hU,"1r-1t-i3");k.43.E.1H="3b";if(k.3q!=N){1t.4A(k.3q)}k.3q=1t.3G(gU,"1r-1t-46");k.3q.E.1H="3b"};J.4l.L.bo=C(K,1e,1a,1U){if(K.fg()){k.bq(K,1e,1a,1U)}S{k.bu(K,1e,1a,1U)}};J.4l.L.bq=C(K,1e,1a,1U){B 1V=K.3P();B 1Q=1b.1A(k.1l.2n(1V));B 1d=K.7p();1d=1d!=N?1d:1a.1o.4J.1d;B pL=k.pK(K,1Q,1d,28,1e,1a);k.5v(1U,pL,1a)};J.4l.L.bu=C(K,1e,1a,1U){B bj=K.gG();B bF=K.gI();B 6Z=1b.1A(k.1l.2n(bj));B 9e=1b.1A(k.1l.2n(bF));B 4W=0;1i(;4W<k.7f.12;4W++){if(9e<k.7f[4W]){1v}}k.7f[4W]=9e;B 1d=K.7p();1d=1d!=N?1d:1a.1o.4J.1d;B 3z=k.6v(K,4W,6Z,9e,1d,28,1e,1a);k.5v(1U,3z,1a)};J.4l.L.6v=C(K,3i,U,2E,1d,2m,1e,1a){B V=1e.4N+3i*1e.4E;B X=2E-U;B 19=1e.3m;B 2z=k.1F.2D().1y("R");2z.E.2p="2U";2z.E.U=U+"px";2z.E.X=X+"px";2z.E.V=V+"px";2z.E.19=19+"px";2z.E.94=1d;2z.E.5t="4b";D.1j.4p(2z,2m);k.3q.1p(2z);I{U:U,V:V,X:X,19:19,M:2z}}J.4l.L.pK=C(K,U,1d,2m,1e,1a){B 19=1a.1o.9P.qp;B V=1e.4N-19;B X=1;B 6R=k.1F.2D().1y("R");6R.E.2p="2U";6R.E.U=U+"px";6R.E.X=X+"px";6R.E.V=V+"px";6R.E.19=19+"px";6R.E.94=1d;6R.E.5t="4b";D.1j.4p(6R,2m);k.3q.1p(6R);I{U:U,V:V,X:X,19:19,M:6R}}J.4l.L.5v=C(1U,5E,1a){if(1U>=0){B 1u=k.1F.2D();B 2F=1a.1o;B 1d=2F.ag[1b.2b(1U,2F.ag.12-1)];B R=1u.1y("R");R.E.2p="2U";R.E.5t="4b";R.E.U=(5E.U-1)+"px";R.E.X=(5E.X+2)+"px";R.E.V=(5E.V-1)+"px";R.E.19=(5E.19+2)+"px";R.E.2G=1d;k.43.1p(R)}};J.4l.L.f4=C(K){};J.fU=C(P){k.1D=("1I"in P)?P.1I:D.2N;k.5a=(2u P.1V=="2H")?k.1D.6h(P.1V):P.1V;k.a0=(2u P.2h=="2H")?k.1D.6h(P.2h):P.2h;k.kA=P.z7;k.kv=P.zb;k.9z=P.1d;k.bl=("2m"in P)?P.2m:28};J.fU.L.3M=C(1t,1r){k.1l=1t;k.1F=1r;k.4G=N};J.fU.L.3l=C(){if(k.4G!=N){k.1l.4A(k.4G)}k.4G=k.1l.3G(10);k.4G.3B("3j","fD-4q-qt");k.4G.E.1H="3b";B 2P=k.1l.7i();B 3V=k.1l.7F();if(k.1D.2k(k.5a,3V)<0&&k.1D.2k(k.a0,2P)>0){2P=k.1D.e7(2P,k.5a);3V=k.1D.g5(3V,k.a0);B 7E=k.1l.2n(2P);B de=k.1l.2n(3V);B 1u=k.1F.2D();B hR=C(){B 8p=1u.1y("8p");8p.qy(0).qv(0);I 8p};B R=1u.1y("R");R.E.2p="2U";R.E.5t="4b";R.E.2G=k.9z;if(k.bl<28){D.1j.4p(R,k.bl)}k.4G.1p(R);B 4F=hR();4F.E.2p="2U";4F.E.5t="4b";4F.E.qL="dI%";4F.E.qu="qq";4F.E.1d=k.9z;4F.bh[0].hH[0].3I=k.kA;k.4G.1p(4F);B 4T=hR();4T.E.2p="2U";4T.E.5t="4b";4T.E.qL="dI%";4T.E.qu="qq";4T.E.1d=k.9z;4T.bh[0].hH[0].3I=k.kv;k.4G.1p(4T);if(k.1F.5D()){R.E.U=7E+"px";R.E.X=(de-7E)+"px";R.E.V="4w";R.E.19="28%";4F.E.2E=(k.1l.qr()-7E)+"px";4F.E.X=(k.kA.12)+"em";4F.E.V="4w";4F.E.19="28%";4F.E.zt="2E";4F.bh[0].E.58="V";4T.E.U=de+"px";4T.E.X=(k.kv.12)+"em";4T.E.V="4w";4T.E.19="28%";4T.bh[0].E.58="V"}S{R.E.V=7E+"px";R.E.19=(de-7E)+"px";R.E.U="4w";R.E.X="28%";4F.E.2j=7E+"px";4F.E.19="1.qs";4F.E.U="4w";4F.E.X="28%";4T.E.V=de+"px";4T.E.19="1.qs";4T.E.U="4w";4T.E.X="28%"}}k.4G.E.1H="2x"};J.fU.L.5N=C(){};J.gh=C(P){k.1D=("1I"in P)?P.1I:D.2N;k.fI=(2u P.1q=="2H")?k.1D.6h(P.1q):P.1q;k.gc=("X"in P)?P.X:10;k.9z=P.1d;k.bl=("2m"in P)?P.2m:28};J.gh.L.3M=C(1t,1r){k.1l=1t;k.1F=1r;k.4G=N};J.gh.L.3l=C(){if(k.4G!=N){k.1l.4A(k.4G)}k.4G=k.1l.3G(10);k.4G.3B("3j","fD-4q-qt");k.4G.E.1H="3b";B 2P=k.1l.7i();B 3V=k.1l.7F();if(k.1D.2k(k.fI,3V)<0&&k.1D.2k(k.fI,2P)>0){B qz=k.1l.2n(k.fI);B 7E=qz-1b.1A(k.gc/2);B 1u=k.1F.2D();B R=1u.1y("R");R.E.2p="2U";R.E.5t="4b";R.E.2G=k.9z;if(k.bl<28){D.1j.4p(R,k.bl)}k.4G.1p(R);if(k.1F.5D()){R.E.U=7E+"px";R.E.X=k.gc+"px";R.E.V="4w";R.E.19="28%"}S{R.E.V=7E+"px";R.E.19=k.gc+"px";R.E.U="4w";R.E.X="28%"}}k.4G.E.1H="2x"};J.gh.L.5N=C(){};J.2N=1h 4C();J.2N.g1=C(3T,2I){I 1h J.55(3T,2I)};J.2N.g7=C(){I 1h 3f()};J.2N.eG=C(v){I 1h 3f(v.1M())};J.2N.aa=C(6i){if(2u 6i=="2H"){6i=6i.bb()}I(6i=="eA"||6i=="qA qH")?J.1f.kH:J.1f.8U};J.2N.6h=C(o){I J.1f.8U(o)};J.2N.ig=C(v){I v.1M()};J.2N.qI=C(n){I 1h 3f(n)};J.2N.2k=C(v1,v2){B n1,n2;if(2u v1=="7J"){n1=v1.1M()}S{n1=2r(v1)}if(2u v2=="7J"){n2=v2.1M()}S{n2=2r(v2)}I n1-n2};J.2N.g5=C(v1,v2){I J.2N.2k(v1,v2)<0?v1:v2};J.2N.e7=C(v1,v2){I J.2N.2k(v1,v2)>0?v1:v2};J.2N.9u=C(v,n){I 1h 3f(v.1M()+n)};(C(){B qJ=1x;B jU=C(){if(2u 2Q.1n!="5S"){I}2Q.1n={f3:1B,P:{jH:1x,qC:1x},zN:"al://ao.ap.aq/zM/zF/22#",zE:{}};B dv=["en"];B jT=("jR"in cu?cu.jR:cu.zx).77(";");1i(B l=0;l<jT.12;l++){B 3T=jT[l];if(3T!="en"){B 9J=3T.77("-");if(9J.12>1&&9J[0]!="en"){dv.1L(9J[0])}dv.1L(3T)}}B zw={jH:f6,qC:f6};if(1n.P.3T){if(1n.P.3T!="en"){B 9J=1n.P.3T.77("-");if(9J.12>1&&9J[0]!="en"){dv.1L(9J[0])}dv.1L(1n.P.3T)}}B 3e=1G.1y("3e");2Q.k7=C(){if(1n.P.2J){eW(1n.P.2J+"()")}}if(2u qD=="2H"){1n.2t=qD+\'/22/\'}1n.f3=1x};B k6=C(){if(2u J!="5S"){jU()}S{2Q.k7=jU}};if(2u D=="5S"){2Q.k7=k6}S{k6()}})();J.3h=D.3h;B 53=D.3h.53;4C.bY=C(jY,9S){1i(B k5 in 9S){jY[k5]=9S[k5]}I jY}1n.dJ=C(M,fq){I 1h 1n.3K(M,fq)};1n.zv=C(P){I{id:("id"in P)?P.id:"p"+1b.1A(1b.cC()*cM),6g:("6g"in P)?P.6g:N,2L:("2L"in P)?P.2L:N,ft:("ft"in P)?P.ft:1h 1n.bX(),fA:("fA"in P)?P.fA:1h 1n.cL(),2I:("2I"in P)?P.2I:0,8k:("8k"in P)?((P.8k=="2H")?1h 1n.5J(P.8k):P.8k):N,gQ:("gQ"in P)?P.gQ:1x,aI:("aI"in P)?P.aI:2r.ev,7q:("7q"in P)?((P.7q=="2H")?1h 1n.5J(P.7q):P.7q):1h 1n.5J("#iK"),5u:("5u"in P)?P.5u:1.0,gm:("gm"in P)?P.gm:2.0,ek:("ek"in P)?P.ek:N,gB:("gB"in P)?P.gB:1.0,fb:("fb"in P)?P.fb:1B,hj:("hj"in P)?P.hj:1x,h6:("h6"in P)?P.h6:75,6U:("6U"in P)?P.6U:ps,83:("83"in P)?P.83:dI}};1n.3K=C(M,fq){k.3k="t"+1b.1A(1b.cC()*cM);k.49=M;k.8J=fq;k.dR={2G:[],93:[]};k.gy=N;k.aL=1B;k.gu=1B;k.go()};1n.3K.L={8v:C(){1i(B i=0;i<k.4D.12;i++){k.4D[i].8v()}k.4D=N;k.zC=N;k.49.3I=""},nF:C(){I k.49},2D:C(){I k.49.4U},5c:C(R){k.49.1p(R)},dG:C(R){k.49.5r(R)},hl:C(fz,aU){B 2s=k.dR[fz];if(2s){1i(B i=0;i<2s.12;i++){if(2s[i].5W.3k==aU.5W.3k){I}}2s.1L(aU)}},o3:C(fz,aU){B 2s=k.dR[fz];if(2s){1i(B i=0;i<2s.12;i++){if(2s[i].5W.3k==aU.5W.3k){2s.5s(i,1);1v}}}},nR:C(){I k.49.6k},nT:C(){I k.49.6W},cI:C(){I k.1z},kj:C(1k,b0,2L,5C){if(k.aL){B tp=k;B 4t=C(64,8F,26){8z("ad to 8H 2f 3w 5R "+1k+"\\n"+64);tp.87()};B 4r=C(26){3N{2L.kj(26.k3,b0,1k,5C)}4c(e){D.3h.6E(e)}dz{tp.87()}};k.bB();2Q.aS(C(){D.4s.9U(1k,4t,4r)},0)}},ds:C(1k,2L){if(k.aL){B tl=k;B 4t=C(64,8F,26){8z("ad to 8H 2f 3w 5R "+1k+"\\n"+64);tl.87()};B 4r=C(26){3N{B 3w=26.k0;if(!3w.68&&26.bm){3w.8H(26.bm)}2L.ds(3w,1k)}dz{tl.87()}};k.bB();2Q.aS(C(){D.4s.9U(1k,4t,4r)},0)}},eB:C(id,1m,e3,3Y){B R=k.8s(id,"22-R "+e3,3Y);R.3I=1m;I R},8s:C(id,e3,3Y){B jX=k.3k+"-"+id;B R=1G.nZ(jX);if(!R){B as=k.49.32;R=1G.1y("R");R.3B("id",jX);as.1p(R)}R.3B("zB","22-R "+e3);R.3B("1W","22-R "+e3);k.5m(R,3Y);I R},bk:C(id){B R=1G.nZ(k.3k+"-"+id);if(R)R.7L.5r(R)},5m:C(R,3Y){if(3Y){1i(E in 3Y){if(E=="U"){3Y[E]+=k.8r;3Y[E]+="px"}S if(E=="2E"){3Y[E]+=k.8r;3Y[E]+="px"}S if(E=="V"){3Y[E]+=k.dW;3Y[E]+="px"}S if(E=="2j"){3Y[E]+=k.dW;3Y[E]+="px"}S if(E=="X"){if(3Y[E]<0)3Y[E]=0;3Y[E]+="px"}S if(E=="19"){if(3Y[E]<0)3Y[E]=0;3Y[E]+="px"}R.E[E]=3Y[E]}}},om:C(7j,6H){if(6H)k.8J.1L(7j);B 22=k;B aU={8I:C(){22.6H()},db:C(){22.6H()}}B 1w=1h 1n.kf(k,7j);B 6g=1w.kn();if(6g){if(6H)6g.cc();6g.84(aU)}k.hl("2G",{5W:1w.ks(),aO:1w.ks().3l});k.hl("2G",{5W:1w.kt(),aO:1w.kt().3l});k.hl("93",{5W:1w,aO:1w.3l});1w.3M();k.4D.1L(1w);if(6H)k.6H();I 1x},zA:C(kb){B e8=1B;if(k.4D){1i(B i=0;i<k.4D.12;i++){if(k.4D[i].3k==kb){k.o3("93",{5W:k.4D[i]});k.bk(k.4D[i].3k+\'b5\');k.bk(k.4D[i].3k+\'nJ\');k.bk(k.4D[i].3k+\'nL\');k.bk(k.4D[i].3k+\'nO\');k.4D.5s(i,1);e8=1x}}}if(k.8J){1i(i=0;i<k.8J.12;i++){if(k.8J[i].id==kb){k.8J.5s(i,1);e8=1x}}}if(e8)k.6H();I e8},oJ:C(R){I{x:R.fm-k.8r,y:R.kc-k.dW}},6H:C(){if(k.aL){1i(B i=0;i<k.4D.12;i++){B 1w=k.4D[i];B 6g=1w.kn();if(6g){B 44=6g.dc();if(44){1w.8j.fB(44);1w.65.fB(44)}}}k.3l()}},ys:C(){if(k.aL){k.jI();1i(B i=0;i<k.4D.12;i++){B 1w=k.4D[i];if(1w.65)1w.65.7b();if(1w.8j)1w.8j.7b()}k.3l()}},3l:C(){if(k.aL&&k.gy==N){B 22=k;k.gy=2Q.aS(C(){22.o4();B bA=C(aO,5W){3N{if(5W.g2)5W.g2(22);aO.71(5W,[])}4c(e){D.3h.6E(e)}}B 2G=22.dR.2G;1i(B i=0;i<2G.12;i++){bA(2G[i].aO,2G[i].5W)}B 93=22.dR.93;1i(B i=0;i<93.12;i++){bA(93[i].aO,93[i].5W)}22.gy=N},20)}},o4:C(){B 3e=k.cI();B 1s=3e.72(\'2d\');1s.ha(0,0,3e.X,3e.19)},jI:C(){B 3e=k.cI();B dr=$(\'#\'+k.49.id);k.8r=(3F(dr.bH(\'gw\'))+3F(dr.bH(\'o6\')))/2;k.dW=(3F(dr.bH(\'zD\'))+3F(dr.bH(\'zz\')))/2;3e.X=k.nR()-(k.8r*2);3e.19=k.nT()-(k.dW*2);B 1s=3e.72(\'2d\');k.oj(1s,3e);1s.zy=\'9S-zu\'},oj:C(1s,3e){if(!D.2C.2X.5I)k.gu=1B;if(!k.gu){k.gu=1x;1s.pB(0,3e.19);1s.9l(1,-1)}},oi:C(3e){B 2X=D.2C.2X;if((3e.72&&2Q.jV)||(2X.5I&&2X.gl>=6)){I 1x}S{I 1B}},go:C(){D.1c.3M();B 1Z=k.49;B 1u=1Z.4U;1Z.1W="22-as "+1Z.1W;1P(1Z.32){1Z.5r(1Z.32)}B 3e=1u.1y("3e");if(k.oi(3e)){B ok=1u.1y("R");1Z.1p(ok);k.1z=3e;3e.1W="22-3e";1Z.1p(3e);if(!3e.72&&jO){3e=jO.iV(k.1z);k.1z=3e}k.jI();B 7D=D.1j.9q(1n.2t+"3d/d1.3A");7D.1W="22-d1";7D.7R="1n (c) ol - al://ao.ap.aq/22/";D.1g.2a(7D,"h9",C(){2Q.bi="al://ao.ap.aq/22/"});1Z.1p(7D);k.4D=[];if(k.8J){1i(B i=0;i<k.8J.12;i++){k.om(k.8J[i])}}B 3s=D.1j.gO(1u);3s.1Z.1W="22-3s-as";1Z.1p(3s.1Z);3s.6o.1W="22-3s";3s.6o.3I="<48 5B=\'"+1n.2t+"3d/oh-og.oa\' /> o9...";k.bB=C(){3s.1Z.E.1H="2x"};k.87=C(){3s.1Z.E.1H="3b"};k.aL=1x}S{k.7o=D.1j.gO(1u);k.7o.1Z.1W="22-3s-as";k.7o.1Z.E.V="15%";k.7o.1Z.E.U="20%";k.7o.1Z.E.2E="20%";k.7o.1Z.E.zO="zP";k.7o.6o.1W="22-3s";k.7o.6o.3I="nw\'re zL zK, nh zH 2X is nr nk nm by <a 9M=\'al://ao.ap.aq/22/\'>1n</a>.<br><br> nw ze zf on zo it in ng zn zm nh, 1i zi, zj ng <a 9M=\'al://ao.ap.aq/bz/zk\'>zl of nk nm zR</a>.";k.7o.1Z.E.1H="2x";1Z.1p(k.7o.1Z)}}};1n.kf=C(22,7j){k.2v=22;k.1z=22.cI();k.3X=7j;k.3k=7j.id;k.65=7j.ft;k.8j=7j.fA;k.nA=7j.fb;k.2W=1h J.f0();k.4O=7j.6g;k.4o=7j.2L;k.bG=N};1n.kf.L={3M:C(){if(k.nA&&k.4O&&k.4O.d9){k.8e=k.2v.8s("nK","22-nK");k.6Y=k.2v.8s(k.3k+"b5","22-b5");k.9A=k.2v.8s(k.3k+"nJ","22-b5-3a");k.aE=k.2v.8s(k.3k+"nL","22-b5-3a");if(!k.9A.32){k.9A.1p(D.1j.9q(1n.2t+"3d/Am.3A"));k.aE.1p(D.1j.9q(1n.2t+"3d/An.3A"))}k.gK=k.2v.8s(k.3k+"nO","22-b5-Ao");B 2m=k.3X.h6;D.1j.4p(k.8e,2m);D.1j.4p(k.6Y,2m);D.1j.4p(k.9A,2m);D.1j.4p(k.aE,2m);D.1j.4p(k.gK,2m);B 1w=k;B h3=C(M,K,1C){1w.6Y.E.1H="2x";kh(M,K,1C)}B 7n=24*60*60*61;B aF=30*7n;B kh=C(M,K,1C){if(2u D!="5S"){B c=1w.1z;B x=1b.1A(D.1g.8f(K,1w.1z).x);if(x>c.X)x=c.X;if(fT(x)||x<0)x=0;B t=1w.65.gx(x);if(t==0){1w.6Y.E.1H="3b";I}B v=1w.4O.d9(t);if(1w.3X.hj)v=1b.1A(v);1w.6Y.3I=1h 7c(v);B d=1h 3f(t);B p=1w.65.oq();if(p<7n){1w.8e.3I=d.oR()}S if(p>aF){1w.8e.3I=d.oU()}S{1w.8e.3I=d.Ap()}B tw=1w.8e.6k;B th=1w.8e.6W;B aC=1b.1A(tw/2);B vw=1w.6Y.6k;B vh=1w.6Y.6W;B y=1w.8j.41(v);if(x+aC>c.X){B tx=c.X-aC}S if(x-aC<0){B tx=aC}S{B tx=x}if(1w.65.oy=="V"){1w.2v.5m(1w.gK,{U:x,V:th-5,19:c.19-y-th+6,1H:"2x"});1w.2v.5m(1w.8e,{U:tx-aC,V:-6,1H:"2x"})}S{1w.2v.5m(1w.gK,{U:x,2j:th-5,19:y-th+6,1H:"2x"});1w.2v.5m(1w.8e,{U:tx-aC,2j:-6,1H:"2x"})}if(x+vw+14>c.X&&y+vh+4>c.19){1w.9A.E.1H="3b";1w.2v.5m(1w.aE,{U:x-14,2j:y-14,1H:"2x"});1w.2v.5m(1w.6Y,{U:x-vw-13,2j:y-vh-13,1H:"2x"})}S if(x+vw+14>c.X&&y+vh+4<c.19){1w.aE.E.1H="3b";1w.2v.5m(1w.9A,{U:x-14,2j:y,1H:"2x"});1w.2v.5m(1w.6Y,{U:x-vw-13,2j:y+13,1H:"2x"})}S if(x+vw+14<c.X&&y+vh+4>c.19){1w.aE.E.1H="3b";1w.2v.5m(1w.9A,{U:x,2j:y-13,1H:"2x"});1w.2v.5m(1w.6Y,{U:x+13,2j:y-13,1H:"2x"})}S{1w.9A.E.1H="3b";1w.2v.5m(1w.aE,{U:x,2j:y,1H:"2x"});1w.2v.5m(1w.6Y,{U:x+13,2j:y+13,1H:"2x"})}}}B kg=k.2v.nF();D.1g.2a(kg,"pb",h3);D.1g.2a(kg,"ey",kh)}},8v:C(){if(k.4O){k.4O.85(k.oo);k.oo=N;k.4O.8v();k.4O=N}},kn:C(){I(k.4O)?k.4O:k.4o},ks:C(){I k.65},kt:C(){I k.8j},3l:C(){B 1s=k.1z.72(\'2d\');1s.5u=k.3X.5u;1s.9r=\'dT\';if(k.4O){if(k.3X.8k){if(k.3X.gQ){B 3p=1s.c6(0,k.1z.19,0,0);3p.4R(0,k.3X.8k.47());3p.4R(0.5,k.3X.8k.47());3p.4R(1,\'aB(3D,3D,3D,0)\');1s.4Q=3p}S{1s.4Q=k.3X.8k.47()}1s.6M();1s.56(0,0);k.g4(C(x,y){1s.3n(x,y)});if(k.3X.aI==2r.ev){1s.3n(k.1z.X,0)}S if(k.3X.aI==2r.54){1s.3n(k.1z.X,k.1z.19);1s.3n(0,k.1z.19)}S{1s.3n(k.1z.X,k.8j.41(k.3X.aI));1s.3n(0,k.8j.41(k.3X.aI))}1s.co()}if(k.3X.7q){1s.8K=k.3X.7q.47();1s.6M();B kr=1x;k.g4(C(x,y){if(kr){kr=1B;1s.56(x,y)}1s.3n(x,y)});1s.7g()}if(k.3X.ek){1s.4Q=k.3X.ek.47();B r=k.3X.gm;k.g4(C(x,y){1s.6M();1s.p2(x,y,r,0,2*1b.op,1x);1s.co()})}}if(k.4o){B 3p=1s.c6(0,0,0,k.1z.19);3p.4R(1,\'aB(3D,3D,3D,0)\');1s.8K=3p;1s.4Q=3p;1s.5u=k.3X.gB;1s.9r=\'dT\';B i=k.4o.iF();1P(i.9i()){B 1o=i.6I();B 1d=1o.7p();1d=(1d)?1h 1n.5J(1d):k.3X.7q;B gY=1o.3P().1M();B kq=1o.5K().1M();if(gY==kq){B c=1d.47();3p.4R(0,c);B 2i=k.65.41(gY);2i=1b.5P(2i)+0.5;B 45=2i;1s.6M();1s.56(2i,0);1s.3n(2i,k.1z.19);1s.7g();B x=2i-4;B w=7}S{B c=1d.47(0.5);3p.4R(0,c);B 2i=k.65.41(gY);2i=1b.5P(2i)+0.5;B 45=k.65.41(kq);45=1b.5P(45)+0.5;1s.p9(2i,0,45-2i,k.1z.19);B x=2i;B w=45-2i-1}B R=k.2v.8s(1o.4K(),"22-1o-p7",{U:1b.1A(x),X:1b.1A(w),V:0,19:k.1z.19-1});B 1w=k;B 3g=C(1o){I C(M,K,1C){B 1u=1w.2v.2D();1w.oZ();B 3x=D.1g.gA(K);B ay=D.1g.6z(M);1w.bG=D.1j.ku(3x.x,ay.V+1w.1z.19,1w.3X.6U,1w.3X.83,"2j");1o.h4(1w.bG.kp,1w.2W,1w.65.ou())}};B h3=C(M,K,1C){M.ko=M.1W;M.1W=M.1W+" 22-1o-p7-4q"};B p5=C(M,K,1C){M.1W=M.ko;M.ko=N}if(!R.bR){D.1g.2a(R,"h9",3g(1o));D.1g.2a(R,"pb",h3);D.1g.2a(R,"pa",p5);R.bR=1x}}}},g4:C(f){B 2f=k.4O.gM();if(2f){B 5k=2f.5k;B 5p=2f.5p;B T=5k.12;1i(B t=0;t<T;t++){B x=k.65.41(5k[t]);B y=k.8j.41(5p[t]);f(x,y)}}},oZ:C(){if(k.bG!=N){k.bG.9H();k.bG=N}}}1n.2A=C(bD){J.2A.71(k,3J)};4C.bY(1n.2A.L,J.2A.L);1n.2A.L.kj=C(1m,b0,1k,5C){if(1m==N){I}k.21.Av=1h 4P();B 4M=k.bd(1k);B 7V=\'eA\';B 52=k.21.6N().aa(7V);B 2f=1m;B 6G=1B;if(5C){2f=5C(2f)}2f=k.p0(2f,b0);if(2f){1i(B i=0;i<2f.12;i++){B fp=2f[i];if(fp.12>1){B K=1h 1n.2A.ky(52(fp[0]),fp.d3(1));k.21.5c(K);6G=1x}}}if(6G){k.9h("8I",[])}}1n.2A.L.p0=C(1m,b0){1m=1m.5F(/\\r\\n?/g,"\\n");B 3U=0;B bw=1m.12;B 8p=[];1P(3U<bw){B 3a=[];if(1m.8M(3U)!=\'#\'){1P(3U<bw){if(1m.8M(3U)==\'"\'){B 5H=1m.1X(\'"\',3U+1);1P(5H<bw&&5H>-1){if(1m.8M(5H+1)!=\'"\'){1v}5H=1m.1X(\'"\',5H+2)}if(5H<0){}S if(1m.8M(5H+1)==b0){B 9b=1m.4d(3U+1,5H-3U-1);9b=9b.5F(/""/g,\'"\');3a[3a.12]=9b;3U=5H+2;kl}S if(1m.8M(5H+1)=="\\n"||bw==5H+1){B 9b=1m.4d(3U+1,5H-3U-1);9b=9b.5F(/""/g,\'"\');3a[3a.12]=9b;3U=5H+2;1v}S{}}B eM=1m.1X(b0,3U);B 8d=1m.1X("\\n",3U);if(8d<0)8d=bw;if(eM>-1&&eM<8d){3a[3a.12]=1m.4d(3U,eM-3U);3U=eM+1}S{3a[3a.12]=1m.4d(3U,8d-3U);3U=8d+1;1v}}}S{B 8d=1m.1X("\\n",3U);3U=(8d>-1)?8d+1:Af}if(3a.12>0){8p[8p.12]=3a}}if(8p.12<0)I;I 8p}1n.2A.L.dc=C(){B 6D=k.ba();B 6C=k.bC();I{6D:(6D)?6D:N,6C:(6C)?6C:N,2b:0,1R:0}}1n.2A.ky=C(29,5p){k.3k="e"+1b.1A(1b.cC()*cM);k.fa=29;k.p3=5p};1n.2A.ky.L={4K:C(){I k.3k},1M:C(){I k.fa},fE:C(){I k.p3},3P:C(){I k.fa},5K:C(){I k.fa}};1n.d7=C(2L){k.4o=2L;B 9S=k;k.cg={8I:C(){9S.cc()},db:C(){9S.cf()}}k.84(k.cg);k.67=[];k.6L=N;k.9o=N};1n.d7.L={cf:C(){k.6L=N;k.9o=N},cc:C(){k.6L={5k:1h 4P(),5p:1h 4P()};k.9o={6D:N,6C:N,2b:0,1R:0}},dc:C(){I k.9o},gM:C(){I k.6L},d9:C(t){if(k.6L){1i(B i=0;i<k.6L.5k.12;i++){B l=k.6L.5k[i];if(l>=t){I k.6L.5p[i]}}}I 0},84:C(2e){k.4o.84(2e)},85:C(2e){k.4o.85(2e)},zZ:C(pd,pp){k.85(pd);k.84(pp)}}1n.ah=C(2L,pq){1n.d7.71(k,3J);k.ix=pq-1};4C.bY(1n.ah.L,1n.d7.L);1n.ah.L.8v=C(){k.85(k.cg);k.cf()}1n.ah.L.cc=C(){B iE=k.4o.g6();B 5k=1h 4P(iE);B 5p=1h 4P(iE);B 2b=2r.ny;B 1R=2r.jh;B i=0;B 6J=k.4o.iF();1P(6J.9i()){B 1o=6J.6I();B 29=1o.1M();5k[i]=29;B 2B=k.iB(1o);if(!fT(2B)){if(2B<2b){2b=2B}if(2B>1R){1R=2B}5p[i]=2B}i++}k.6L={5k:5k,5p:5p};if(1R==2r.jh)1R=1;k.9o={6D:k.4o.ba(),6C:k.4o.bC(),2b:2b,1R:1R}}1n.ah.L.iB=C(1o){I iy(1o.fE()[k.ix])}1n.i4=C(2L,zX,pm){1n.ah.71(k,3J);k.pl=pm-1};4C.bY(1n.i4.L,1n.ah.L);1n.i4.L.iB=C(1o){B a=iy(1o.fE()[k.ix]);B b=iy(1o.fE()[k.pl]);I a-b}1n.cL=C(P){if(!P)P={};k.3k=("id"in P)?P.id:"g"+1b.1A(1b.cC()*cM);k.cB=("9E"in P)?((2u P.9E=="2H")?1h 1n.5J(P.9E):P.9E):1h 1n.5J("#iK"),k.8q=("9G"in P)?((2u P.9G=="2H")?1h 1n.5J(P.9G):P.9G):N,k.f9=("fW"in P)?P.fW:0.5;k.9t=("gb"in P)?P.gb:"2E";k.iP=("zW"in P)?P.iw:50;k.iz=("pe"in P)?P.pe:"pk";k.iA=("pg"in P)?P.pg:10;k.6x=("2b"in P)?P.2b:N;k.8a=("1R"in P)?P.1R:N;k.aA={9d:C(v){I v},cx:C(y){I y}}k.5Z=k.aA;k.iG=[];k.7H=[]}1n.cL.L={g2:C(22){k.2v=22;k.1z=22.cI();k.7b()},fB:C(44){if((k.6x==N)||((k.6x!=N)&&(44.2b<k.6x))){k.6x=44.2b}if((k.8a==N)||((k.8a!=N)&&(44.1R*1.fS>k.8a))){k.8a=44.1R*1.fS}k.cm();if(!(k.6x==0&&k.8a==0)){k.7H=k.8t()}},7b:C(){k.pj();k.cm();k.7H=k.8t()},41:C(2B){if(k.1z&&k.8a){B v=2B-k.6x;I k.1z.19*(k.5Z.9d(v))/k.jC}S{I-50}},gx:C(y){if(k.1z){I k.5Z.cx(k.jC*y/k.1z.19)+k.6x}S{I 0}},3l:C(){if(k.2v){B 1s=k.1z.72(\'2d\');1s.9r=\'dT\';if(k.8q){B eF=1s.c6(0,0,0,k.1z.19);eF.4R(0,k.8q.eS());eF.4R(0.3,k.8q.eS());eF.4R(1,"aB(3D,3D,3D,0.5)");1s.5u=k.f9;1s.8K=eF;1i(B i=0;i<k.7H.12;i++){B 7I=k.7H[i];B y=1b.5P(7I.y)+0.5;if(2u 7I.2w!="5S"){if(k.9t=="U"){B R=k.2v.eB(k.3k+"-"+i,7I.2w,"22-4y-2w",{U:4,2j:y+2,1d:k.8q.eS(),8b:"4b"})}S if(k.9t=="2E"){B R=k.2v.eB(k.3k+"-"+i,7I.2w,"22-4y-2w",{2E:4,2j:y+2,1d:k.8q.eS(),8b:"4b"})}if(y+R.6W<k.1z.19+10){R.E.8b="ow"}}1s.6M();if(k.iz=="zS"||7I.2w==0){1s.56(0,y);1s.3n(k.1z.X,y)}S if(k.iz=="pk"){if(k.9t=="U"){1s.56(0,y);1s.3n(k.iA,y)}S if(k.9t=="2E"){1s.56(k.1z.X,y);1s.3n(k.1z.X-k.iA,y)}}1s.7g()}}B eE=1s.c6(0,0,0,k.1z.19);eE.4R(0,k.cB.47());eE.4R(0.5,k.cB.47());eE.4R(1,"aB(3D,3D,3D,0.5)");1s.5u=1;1s.8K=eE;1s.6M();1s.56(0,k.1z.19);1s.3n(0,0);1s.7g();1s.6M();1s.56(k.1z.X,0);1s.3n(k.1z.X,k.1z.19);1s.7g()}},pj:C(){1i(B i=0;i<k.iG.12;i++){B l=k.iG[i];B iH=l.7L;if(iH)iH.5r(l)}},8t:C(){B 4y=[];if(!k.1z||k.a3==0)I 4y;B a5=0;if(k.a3>1){1P(1b.iO(10,a5)<k.a3){a5++}a5--}S{1P(1b.iO(10,a5)>k.a3){a5--}}B 1I=1b.iO(10,a5);B 81=1I;1P(1x){B dy=k.41(k.6x+81);1P(dy<k.iP){81+=1I;dy=k.41(k.6x+81)}if(dy>2*k.iP){1I/=10;81=1I}S{1v}}B v=0;B y=k.41(v);if(k.6x>=0){1P(y<k.1z.19){if(y>0){4y.1L({y:y,2w:v})}v+=81;y=k.41(v)}}S if(k.8a<=0){1P(y>0){if(y<k.1z.19){4y.1L({y:y,2w:v})}v-=81;y=k.41(v)}}S{1P(y<k.1z.19){if(y>0){4y.1L({y:y,2w:v})}v+=81;y=k.41(v)}v=-81;y=k.41(v);1P(y>0){if(y<k.1z.19){4y.1L({y:y,2w:v})}v-=81;y=k.41(v)}}I 4y},cm:C(){k.a3=1b.6S(k.8a-k.6x);k.jC=k.5Z.9d(k.a3)}}1n.9Z=C(P){1n.cL.71(k,3J);k.iN={9d:C(v){I 1b.53(v+1)/1b.53(10)},cx:C(y){I 1b.hk(1b.53(10)*y)-1}}k.9y="53";k.5Z=k.iN;k.8t=k.iM};1n.9Z.L.oX=1n.cL.L.8t;4C.bY(1n.9Z.L,1n.cL.L);1n.9Z.L.iM=C(){B 4y=[];if(!k.1z||k.a3==0)I 4y;B v=1;B y=k.41(v);1P(y<k.1z.19||fT(y)){if(y>0){4y.1L({y:y,2w:v})}v*=10;y=k.41(v)}I 4y};1n.9Z.L.eU=C(){k.9y="jm";k.5Z=k.aA;k.8t=k.oX;k.7b()}1n.9Z.L.oW=C(){k.9y="53";k.5Z=k.iN;k.8t=k.iM;k.7b()}1n.9Z.L.nB=C(){if(k.9y=="53"){k.eU()}S{k.oW()}}1n.bX=C(P){if(!P)P={};k.3k=("id"in P)?P.id:"g"+1b.1A(1b.cC()*cM);k.6T=("3T"in P)?P.3T:"en";k.7d=("2I"in P)?P.2I:D.1f.oC();k.fG=("3r"in P)?P.3r:N;k.cB=("9E"in P)?((P.9E=="2H")?1h 1n.5J(P.9E):P.9E):1h 1n.5J("#iK"),k.8q=("9G"in P)?((P.9G=="2H")?1h 1n.5J(P.9G):P.9G):N,k.f9=("fW"in P)?P.fW:0.5;k.9t=("gb"in P)?P.gb:"2j";k.zV=("iw"in P)?P.iw:28;k.A2=("oE"in P)?P.oE:20;k.ab=("2b"in P)?P.2b:N;k.ac=("1R"in P)?P.1R:N;k.oy=("ot"in P)?P.ot:"2j";k.1D=("1I"in P)?P.1I:J.2N;k.aA={9d:C(t){I t},cx:C(x){I x}}k.5Z=k.aA;k.ov=k.1D.g1(k.6T,k.7d);B iv=k.1D.aa("eA");if(k.ab&&!k.ab.1M){k.ab=iv(k.ab)}if(k.ac&&!k.ac.1M){k.ac=iv(k.ac)}k.7H=[]}1n.bX.L={g2:C(22){k.2v=22;k.1z=22.cI();k.7b()},fB:C(44){if(k.ab){k.6A=k.ab}S if(44.6D&&((k.6A==N)||((k.6A!=N)&&(44.6D.1M()<k.6A.1M())))){k.6A=44.6D}if(k.ac){k.7P=k.ac}S if(44.6C&&((k.7P==N)||((k.7P!=N)&&(44.6C.1M()>k.7P.1M())))){k.7P=44.6C}if(!k.6A&&!k.7P){k.7H=[]}S{k.7b()}},7b:C(){k.cm();if(k.1z)k.7H=k.8t()},41:C(29){if(k.1z&&k.7P){B t=29-k.6A.1M();I k.1z.X*k.5Z.9d(t)/k.fw}S{I-50}},gx:C(x){if(k.1z){I k.5Z.cx(k.fw*x/k.1z.X)+k.6A.1M()}S{I 0}},oq:C(){I k.bQ},ou:C(){I k.ov},6N:C(){I k.1D},3l:C(){if(k.1z){B 1I=k.1D;B 1s=k.1z.72(\'2d\');B 3p=1s.c6(0,0,0,k.1z.19);1s.8K=3p;1s.5u=k.f9;1s.9r=\'dT\';if(k.8q){3p.4R(0,k.8q.47());3p.4R(1,"aB(3D,3D,3D,0.9)");1i(B i=0;i<k.7H.12;i++){B 7I=k.7H[i];B x=1b.5P(7I.x)+0.5;if(k.9t=="V"){B R=k.2v.eB(k.3k+"-"+i,7I.2w,"22-4y-2w",{U:x+4,V:2,8b:"4b"})}S if(k.9t=="2j"){B R=k.2v.eB(k.3k+"-"+i,7I.2w,"22-4y-2w",{U:x+4,2j:2,8b:"4b"})}if(x+R.6k<k.1z.X+10){R.E.8b="ow"}1s.6M();1s.56(x,0);1s.3n(x,k.1z.19);1s.7g()}}3p.4R(0,k.cB.47());3p.4R(1,"aB(3D,3D,3D,0.5)");1s.5u=1;3p.4R(0,k.cB.47());1s.6M();1s.56(0,0);1s.3n(k.1z.X,0);1s.7g()}},8t:C(){B 4y=[];B 29=D.1f;B u=k.1D;B p=k.bQ;if(p==0)I 4y;if(p>29.5b[29.8h]){1I=29.8h}S{1i(B 1I=29.8h;1I>0;1I--){if(29.5b[1I-1]<=p&&p<29.5b[1I]){1I--;1v}}}B t=u.eG(k.6A);do{29.eH(t,1I,k.7d,1,0);B x=k.41(u.ig(t));79(1I){1K 29.aW:B l=t.oR();1v;1K 29.8c:B m=t.Ab();B l=t.oV()+":"+((m<10)?"0":"")+m;1v;1K 29.7a:B l=t.oV()+":jk";1v;1K 29.6P:1K 29.9N:1K 29.aM:B l=t.oU();1v;1K 29.6u:1K 29.ak:1K 29.b1:1K 29.8h:B l=t.4h();1v}if(x>0){4y.1L({x:x,2w:l})}29.eL(t,1I,k.7d)}1P(t.1M()<k.7P.1M());I 4y},cm:C(){if(k.7P&&k.6A){k.bQ=k.7P.1M()-k.6A.1M();k.fw=k.5Z.9d(k.bQ)}S{k.bQ=0;k.fw=0}}}1n.aD=C(P){1n.bX.71(k,3J);B g=k;k.p8={9d:C(t){if(t<g.ik){B x=t*g.im}S if(g.ik<t&&t<g.oH){B x=t*g.et+g.oF}S{B x=t*g.ep+g.pr}I x},cx:C(x){if(x<g.io){B t=x/g.im}S if(g.io<x&&x<g.oQ){B t=x/g.et+g.oD}S{B t=x/g.ep+g.p4}I t}}k.9y="jm";k.5Z=k.aA};4C.bY(1n.aD.L,1n.bX.L);1n.aD.L.3M=C(22){1n.bX.L.3M.71(k,3J);if(!k.4Z){k.4Z=k.2v.8s("6n","22-6n")}B oL=61*60*60*24*30;B 2K=k;B ii=C(6n){B i8=6n.6k;B oK=2K.2v.oJ(6n);2K.oS(oK.x+i8/2,i8,oL);2K.jn();2K.2v.3l()}B oN=C(M,K,1C){2K.1z.c5=D.1g.8f(K,M);2K.1z.c7=1x}B ip=C(M,K,1C){2K.1z.c7=1B;B 3x=D.1g.8f(K,M);if(1n.1b.pt(3x,2K.1z.c5,5)){2K.4Z.E.1H="3b";2K.eU();2K.2v.3l()}S{2K.4Z.E.7G="ih";ii(2K.4Z)}}B oM=C(M,K,1C){if(2K.1z.c7){B 3x=D.1g.8f(K,M);if(3x.x<0)3x.x=0;if(3x.x>2K.1z.X)3x.x=2K.1z.X;2K.2v.5m(2K.4Z,{U:2K.1z.c5.x,X:3x.x-2K.1z.c5.x,2j:0,19:2K.1z.19,1H:"2x"})}}B oO=C(M,K,1C){2K.4Z.c5=D.1g.8f(K,M);2K.4Z.c7=1x}B iu=C(M,K,1C){2K.4Z.c7=1B}B oT=C(M,K,1C){if(2K.4Z.c7){B 3x=D.1g.8f(K,M);B 6n=2K.4Z;B U=6n.fm+3x.x-6n.c5.x;if(U<2K.2v.8r)U=2K.2v.8r;if(U+6n.6k>2K.1z.X-2K.2v.8r)U=2K.1z.X-6n.6k+2K.2v.8r;6n.E.U=U;ii(6n)}}if(!k.1z.bR){D.1g.2a(k.1z,"3R",oN);D.1g.2a(k.1z,"ey",oM);D.1g.2a(k.1z,"bS",ip);D.1g.2a(k.1z,"bS",iu);k.1z.bR=1x}if(!k.4Z.bR){D.1g.2a(k.4Z,"3R",oO);D.1g.2a(k.4Z,"ey",oT);D.1g.2a(k.4Z,"bS",iu);D.1g.2a(k.4Z,"bS",ip);k.4Z.bR=1x}}1n.aD.L.oS=C(c,a,b){a=a/2;b=b/2;B w=k.1z.X;B d=k.bQ;if(c<0)c=0;if(c>w)c=w;if(c-a<0)a=c;if(c+a>w)a=w-c;B ct=k.gx(c)-k.6A.1M();if(ct-b<0)b=ct;if(ct+b>d)b=d-ct;k.eu=c;k.ew=ct;k.ij=a;k.il=b;k.io=k.eu-k.ij;k.oQ=k.eu+k.ij;k.ik=k.ew-k.il;k.oH=k.ew+k.il;k.im=(c-a)/(ct-b);k.et=a/b;k.ep=(w-c-a)/(d-ct-b);k.oF=k.eu-k.ew*k.et;k.oD=k.ew-k.eu/k.et;k.pr=(c+a)-(ct+b)*k.ep;k.p4=(ct+b)-(c+a)/k.ep;k.cm()}1n.aD.L.eU=C(){k.9y="jm";k.5Z=k.aA;k.7b()}1n.aD.L.jn=C(){k.9y="nC";k.5Z=k.p8;k.7b()}1n.aD.L.nB=C(){if(k.9y=="nC"){k.eU()}S{k.jn()}}1n.5J=C(1d){k.nz(1d)};1n.5J.L={8Y:C(r,g,b,a){k.r=r;k.g=g;k.b=b;k.a=(a)?a:1.0;I k.he()},y3:C(a){k.a=a;I k.he()},y1:C(7z){B 1d=1h 1n.5J();I 1d.8Y(k.r+=3F(7z,10),k.g+=3F(7z,10),k.b+=3F(7z,10))},xW:C(7z){B 1d=1h 1n.5J();I 1d.8Y(k.r-=3F(7z,10),k.g-=3F(7z,10),k.b-=3F(7z,10))},he:C(){if(k.r>3D){k.r=3D}S if(k.r<0){k.r=0}if(k.g>3D){k.g=3D}S if(k.g<0){k.g=0}if(k.b>3D){k.b=3D}S if(k.b<0){k.b=0}if(k.a>1.0){k.a=1.0}S if(k.a<0.0){k.a=0.0}I k},47:C(9F){B a=(9F)?9F:((k.a)?k.a:1.0);I\'aB(\'+k.r+\',\'+k.g+\',\'+k.b+\',\'+a+\')\'},eS:C(){I"#"+k.hd(k.r)+k.hd(k.g)+k.hd(k.b)},nz:C(1d){if(/^#?([\\da-f]{3}|[\\da-f]{6})$/i.cd(1d)){1d=1d.5F(/^#/,\'\').5F(/^([\\da-f])([\\da-f])([\\da-f])$/i,"$1$1$2$2$3$3");k.r=3F(1d.4d(0,2),16);k.g=3F(1d.4d(2,2),16);k.b=3F(1d.4d(4,2),16)}S if(/^j8 *\\( *\\d{0,3} *, *\\d{0,3} *, *\\d{0,3} *\\)$/i.cd(1d)){1d=1d.eT(/^j8 *\\( *(\\d{0,3}) *, *(\\d{0,3}) *, *(\\d{0,3}) *\\)$/i);k.r=3F(1d[1],10);k.g=3F(1d[2],10);k.b=3F(1d[3],10)}k.a=1.0;I k.he()},hd:C(eR){B jg="y9"if(eR<0)I"jk";if(eR>3D)I"ya";B i=1b.5P(eR/16);B j=eR%16;I jg.8M(i)+jg.8M(j)}};1n.1b={44:C(f){B F=f.12;B 2b=2r.ny;B 1R=2r.jh;1i(B t=0;t<F;t++){B 2B=f[t];if(2B<2b){2b=2B}if(2B>1R){1R=2B}}I{2b:2b,1R:1R}},o0:C(f,4V){B F=f.12;B g=1h 4P(F);1i(B n=0;n<F;n++){B 2B=0;1i(B m=n-4V;m<n+4V;m++){if(m<0){B v=f[0]}S if(m>=F){B v=g[n-1]}S{B v=f[m]}2B+=v}g[n]=2B/(2*4V)}I g},o5:C(f){B F=f.12;B g=1h 4P(F);B 6X=0;1i(B t=0;t<F;t++){6X+=f[t];g[t]=6X}I g},oe:C(f){B F=f.12;B 6X=0.0;1i(B t=0;t<F;t++){6X+=f[t]}1i(B t=0;t<F;t++){f[t]/=6X}I f},xV:C(f,g){B F=f.12;B G=g.12;B c=1h 4P(F);1i(B m=0;m<F;m++){B r=0;B 45=(m+G<F)?m+G:F;1i(B n=m;n<45;n++){B a=f[n-G];B b=g[n-m];r+=a*b}c[m]=r}I c},xF:C(4V){B f=1h 4P(4V);B 2B=1/4V;1i(B t=0;t<4V;t++){f[t]=2B}I f},xH:C(4V,nP){oc(1b){B 8S=4V/2;B od=8S*8S/53(nP);B g=1h 4P(4V);1i(B t=0;t<4V;t++){B l=t-8S;g[t]=hk(-od*l*l)}}I k.oe(g)},1A:C(x,n){oc(1b){if(6S(x)>1){B l=5P(53(x)/53(10));B d=1A(hk((l-n+1)*53(10)));B y=1A(1A(x/d)*d);I y}S{53("xz(xA): xB to xJ 1i 0 < 6S(x) < 1");I x}}},xQ:C(x){if(x>5){I 1}S if(x<5){I-1}S{B jA=1b.hk(2*x);I(jA-1)/(jA+1)}},pt:C(a,b,2B){I(a&&b&&1b.6S(a.x-b.x)<2B&&1b.6S(a.y-b.y)<2B)}}1n.xR={6X:C(2f,P){I 1n.1b.o5(2f.5p)},xS:C(2f,P){B 4V=("4V"in P)?P.4V:30;B 3L=1n.1b.o0(2f.5p,4V);I 3L}}1n.qB=C(6g,qE,P){k.4O=6g;k.qF=qE;k.1S=P;k.6L={5k:1h 4P(),5p:1h 4P()};k.9o={6D:N,6C:N,2b:0,1R:0};B jw=k;k.cg={8I:C(){jw.cc()},db:C(){jw.cf()}}k.84(k.cg)};1n.qB.L={cf:C(){k.85(k.cg);k.4O.cf()},cc:C(){B 2f=k.4O.gM();B 44=k.4O.dc();B jr=k.qF(2f,k.1S);B jt=1n.1b.44(jr);k.6L={5k:2f.5k,5p:jr};k.9o={6D:44.6D,6C:44.6C,2b:jt.2b,1R:jt.1R}},dc:C(){I k.9o},gM:C(){I k.6L},d9:1n.d7.L.d9,84:C(2e){k.4O.84(2e)},85:C(2e){k.4O.85(2e)}}if(!2Q.q8){(C(){B m=1b;B mr=m.1A;B ms=m.xM;B mc=m.qG;B Z=10;B ar=Z/2;B ke={nN:C(q1){B 1u=q1||1G;if(/xE/.cd(cu.nY)&&!2Q.nW){B 4g=k;1u.gq("je",C(){4g.o7(1u)})}},o7:C(1u){if(1u.o8=="x9"){if(!1u.nQ["78"]){1u.nQ.5c("78","xa:xb-nq-xc:xk")}B ss=1u.xl();ss.xs="3e{1H:nv-2x;5t:4b;"+"1m-2T:U;X:xt;19:xu}"+"78\\\\:*{xr:1k(#aN#xq)}";B gR=1u.iX("3e");1i(B i=0;i<gR.12;i++){if(!gR[i].72){k.iV(gR[i])}}}},nn:C(el){B gS=el.gS;B iT=el.4U.1y(gS);if(gS.d3(-2)!="/>"){B aK="/"+el.aK;B ns;1P((ns=el.au)&&ns.aK!=aK){ns.np()}if(ns){ns.np()}}el.7L.xn(iT,el);I iT},iV:C(el){el=k.nn(el);el.72=C(){if(k.j3){I k.j3}I k.j3=1h fM(k)};el.gq(\'xo\',nl);el.gq(\'x8\',nM);B b3=el.jc;if(b3.X&&b3.X.nj){el.E.X=b3.X.cq+"px"}S{el.X=el.6k}if(b3.19&&b3.19.nj){el.E.19=b3.19.cq+"px"}S{el.19=el.6W}I el}};C nl(e){B el=e.gv;79(e.x7){1K\'X\':el.E.X=el.jc.X.cq+"px";el.72().ha();1v;1K\'19\':el.E.19=el.jc.19.cq+"px";el.72().ha();1v}}C nM(e){B el=e.gv;if(el.32){el.32.E.X=el.6k+\'px\';el.32.E.19=el.6W+\'px\'}}ke.nN();B iQ=[];1i(B i=0;i<16;i++){1i(B j=0;j<16;j++){iQ[i*16+j]=i.47(16)+j.47(16)}}C gF(){I[[1,0,0],[0,1,0],[0,0,1]]}C ez(m1,m2){B 3L=gF();1i(B x=0;x<3;x++){1i(B y=0;y<3;y++){B 6X=0;1i(B z=0;z<3;z++){6X+=m1[x][z]*m2[z][y]}3L[x][y]=6X}}I 3L}C jS(o1,o2){o2.4Q=o1.4Q;o2.c0=o1.c0;o2.9r=o1.9r;o2.5u=o1.5u;o2.eY=o1.eY;o2.pc=o1.pc;o2.nX=o1.nX;o2.oI=o1.oI;o2.oP=o1.oP;o2.8K=o1.8K;o2.bI=o1.bI;o2.cD=o1.cD}C jQ(8E){B dQ,9F=1;8E=7c(8E);if(8E.6B(0,3)=="j8"){B 2i=8E.1X("(",3);B 45=8E.1X(")",2i+1);B hh=8E.6B(2i+1,45).77(",");dQ="#";1i(B i=0;i<3;i++){dQ+=iQ[2r(hh[i])]}if((hh.12==4)&&(8E.4d(3,1)=="a")){9F=hh[3]}}S{dQ=8E}I[dQ,9F]}C pO(c0){79(c0){1K"oz":I"wK";1K"1A":I"1A";1K"oG":aN:I"oG"}}C fM(bO){k.3O=gF();k.jL=[];k.jM=[];k.7h=[];k.8K="#ox";k.4Q="#ox";k.5u=1;k.9r="dT";k.c0="oz";k.eY=Z*1;k.nV=1;k.3e=bO;B el=bO.4U.1y(\'R\');el.E.X=bO.6k+\'px\';el.E.19=bO.6W+\'px\';el.E.5t=\'4b\';el.E.2p=\'2U\';bO.1p(el);k.gX=el;k.bI=1;k.cD=1};B 3u=fM.L;3u.ha=C(){k.gX.3I="";k.7h=[]};3u.6M=C(){k.7h=[]};3u.56=C(aX,aY){k.7h.1L({3v:"56",x:aX,y:aY});k.bK=aX;k.bL=aY};3u.3n=C(aX,aY){k.7h.1L({3v:"3n",x:aX,y:aY});k.bK=aX;k.bL=aY};3u.g0=C(oA,oB,ph,pf,aX,aY){k.7h.1L({3v:"g0",d0:oA,d2:oB,gg:ph,gi:pf,x:aX,y:aY});k.bK=aX;k.bL=aY};3u.wO=C(pn,po,aX,aY){B d0=k.bK+2.0/3.0*(pn-k.bK);B d2=k.bL+2.0/3.0*(po-k.bL);B gg=d0+(aX-k.bK)/3.0;B gi=d2+(aY-k.bL)/3.0;k.g0(d0,d2,gg,gi,aX,aY)};3u.p2=C(aX,aY,9R,j6,j9,jd){9R*=Z;B oY=jd?"at":"wa";B cF=aX+(mc(j6)*9R)-ar;B fX=aY+(ms(j6)*9R)-ar;B d6=aX+(mc(j9)*9R)-ar;B fJ=aY+(ms(j9)*9R)-ar;if(cF==d6&&!jd){cF+=0.p1}k.7h.1L({3v:oY,x:aX,y:aY,8S:9R,cF:cF,fX:fX,d6:d6,fJ:fJ})};3u.x3=C(aX,aY,8N,8y){k.56(aX,aY);k.3n(aX+8N,aY);k.3n(aX+8N,aY+8y);k.3n(aX,aY+8y);k.gT()};3u.x4=C(aX,aY,8N,8y){k.6M();k.56(aX,aY);k.3n(aX+8N,aY);k.3n(aX+8N,aY+8y);k.3n(aX,aY+8y);k.gT();k.7g()};3u.p9=C(aX,aY,8N,8y){k.6M();k.56(aX,aY);k.3n(aX+8N,aY);k.3n(aX+8N,aY+8y);k.3n(aX,aY+8y);k.gT();k.co()};3u.c6=C(jb,j4,p6,nG){B 3p=1h dd("3p");I 3p};3u.x5=C(jb,j4,nE,p6,nG,nD){B 3p=1h dd("qx");3p.jW=nE;3p.k2=nD;3p.eb.x=jb;3p.eb.y=j4;I 3p};3u.x6=C(2Y,x2){B dx,dy,dw,dh,sx,sy,sw,sh;B nH=2Y.bZ.X;B nI=2Y.bZ.19;2Y.bZ.X=\'iW\';2Y.bZ.19=\'iW\';B w=2Y.X;B h=2Y.19;2Y.bZ.X=nH;2Y.bZ.19=nI;if(3J.12==3){dx=3J[1];dy=3J[2];sx=sy=0;sw=dw=w;sh=dh=h}S if(3J.12==5){dx=3J[1];dy=3J[2];dw=3J[3];dh=3J[4];sx=sy=0;sw=w;sh=h}S if(3J.12==9){sx=3J[1];sy=3J[2];sw=3J[3];sh=3J[4];dx=3J[5];dy=3J[6];dw=3J[7];dh=3J[8]}S{9n"iU dM of 3J"}B d=k.6a(dx,dy);B w2=sw/2;B h2=sh/2;B cA=[];B W=10;B H=10;cA.1L(\' <78:ob\',\' nS="\',Z*W,\',\',Z*H,\'"\',\' nU="0,0"\',\' E="X:\',W,\';19:\',H,\';2p:2U;\');if(k.3O[0][0]!=1||k.3O[0][1]){B 5C=[];5C.1L("wX=\'",k.3O[0][0],"\',","wY=\'",k.3O[1][0],"\',","wZ=\'",k.3O[0][1],"\',","x0=\'",k.3O[1][1],"\',","Dx=\'",mr(d.x/Z),"\',","Dy=\'",mr(d.y/Z),"\'");B 1R=d;B c2=k.6a(dx+dw,dy);B c3=k.6a(dx,dy+dh);B c4=k.6a(dx+dw,dy+dh);1R.x=1b.1R(1R.x,c2.x,c3.x,c4.x);1R.y=1b.1R(1R.y,c2.y,c3.y,c4.y);cA.1L("nx:0 ",mr(1R.x/Z),"px ",mr(1R.y/Z),"px 0;5C:cN:cO.ai.uH(",5C.8D(""),", uI=\'qe\');")}S{cA.1L("V:",mr(d.y/Z),"px;U:",mr(d.x/Z),"px;")}cA.1L(\' ">\',\'<78:2Y 5B="\',2Y.5B,\'"\',\' E="X:\',Z*dw,\';\',\' 19:\',Z*dh,\';"\',\' uZ="\',sx/w,\'"\',\' uW="\',sy/h,\'"\',\' uV="\',(w-sx-sw)/w,\'"\',\' uC="\',(h-sy-sh)/h,\'"\',\' />\',\'</78:ob>\');k.gX.pM("up",cA.8D(""))};3u.7g=C(dS){B 4X=[];B ul=1B;B a=jQ(dS?k.4Q:k.8K);B 1d=a[0];B 2m=a[1]*k.nV;B W=10;B H=10;4X.1L(\'<78:pN\',\' ug="\',1d,\'"\',\' uf="\',f6(dS),\'"\',\' E="2p:2U;X:\',W,\';19:\',H,\';"\',\' nU="0 0" nS="\',Z*W,\' \',Z*H,\'"\',\' uz="\',!dS,\'"\',\' uA="\',k.5u,\'"\',\' us="\',1d,\'"\',\' ut="\');B vF=1B;B 2b={x:N,y:N};B 1R={x:N,y:N};1i(B i=0;i<k.7h.12;i++){B p=k.7h[i];if(p.3v=="56"){4X.1L(" m ");B c=k.6a(p.x,p.y);4X.1L(mr(c.x),",",mr(c.y))}S if(p.3v=="3n"){4X.1L(" l ");B c=k.6a(p.x,p.y);4X.1L(mr(c.x),",",mr(c.y))}S if(p.3v=="9H"){4X.1L(" x ")}S if(p.3v=="g0"){4X.1L(" c ");B c=k.6a(p.x,p.y);B c1=k.6a(p.d0,p.d2);B c2=k.6a(p.gg,p.gi);4X.1L(mr(c1.x),",",mr(c1.y),",",mr(c2.x),",",mr(c2.y),",",mr(c.x),",",mr(c.y))}S if(p.3v=="at"||p.3v=="wa"){4X.1L(" ",p.3v," ");B c=k.6a(p.x,p.y);B jB=k.6a(p.cF,p.fX);B jJ=k.6a(p.d6,p.fJ);4X.1L(mr(c.x-k.bI*p.8S),",",mr(c.y-k.cD*p.8S)," ",mr(c.x+k.bI*p.8S),",",mr(c.y+k.cD*p.8S)," ",mr(jB.x),",",mr(jB.y)," ",mr(jJ.x),",",mr(jJ.y))}if(c){if(2b.x==N||c.x<2b.x){2b.x=c.x}if(1R.x==N||c.x>1R.x){1R.x=c.x}if(2b.y==N||c.y<2b.y){2b.y=c.y}if(1R.y==N||c.y>1R.y){1R.y=c.y}}}4X.1L(\' ">\');if(2u k.4Q=="7J"){B a4={x:"50%",y:"50%"};B X=(1R.x-2b.x);B 19=(1R.y-2b.y);B kz=(X>19)?X:19;a4.x=mr((k.4Q.eb.x/X)*28+50)+"%";a4.y=mr((k.4Q.eb.y/19)*28+50)+"%";B dj=[];if(k.4Q.ka=="qx"){B fe=(k.4Q.jW/kz*28);B kw=(k.4Q.k2/kz*28)-fe}S{B fe=0;B kw=28}B cz={1O:N,1d:N};B cQ={1O:N,1d:N};k.4Q.dL.vz(C(qw,qK){I qw.1O-qK.1O});1i(B i=0;i<k.4Q.dL.12;i++){B fs=k.4Q.dL[i];dj.1L((fs.1O*kw)+fe,"% ",fs.1d,",");if(fs.1O>cz.1O||cz.1O==N){cz.1O=fs.1O;cz.1d=fs.1d}if(fs.1O<cQ.1O||cQ.1O==N){cQ.1O=fs.1O;cQ.1d=fs.1d}}dj.h8();4X.1L(\'<78:co\',\' 1d="\',cQ.1d,\'"\',\' vP="\',cz.1d,\'"\',\' 3v="\',k.4Q.ka,\'"\',\' vQ="\',a4.x,\', \',a4.y,\'"\',\' dj="\',dj.8D(""),\'"\',\' 2m="\',2m,\'" />\')}S if(dS){4X.1L(\'<78:co 1d="\',1d,\'" 2m="\',2m,\'" />\')}S{4X.1L(\'<78:7g\',\' 2m="\',2m,\'"\',\' vR="\',k.9r,\'"\',\' vN="\',k.eY,\'"\',\' vM="\',pO(k.c0),\'"\',\' vI="\',k.5u,\'px"\',\' 1d="\',1d,\'" />\')}4X.1L("</78:pN>");k.gX.pM("vL",4X.8D(""));k.7h=[]};3u.co=C(){k.7g(1x)}3u.gT=C(){k.7h.1L({3v:"9H"})};3u.6a=C(aX,aY){I{x:Z*(aX*k.3O[0][0]+aY*k.3O[1][0]+k.3O[2][0])-ar,y:Z*(aX*k.3O[0][1]+aY*k.3O[1][1]+k.3O[2][1])-ar}};3u.ve=C(){B o={};jS(k,o);k.jM.1L(o);k.jL.1L(k.3O);k.3O=ez(gF(),k.3O)};3u.va=C(){jS(k.jM.h8(),k);k.3O=k.jL.h8()};3u.pB=C(aX,aY){B m1=[[1,0,0],[0,1,0],[aX,aY,1]];k.3O=ez(m1,k.3O)};3u.v5=C(jE){B c=mc(jE);B s=ms(jE);B m1=[[c,s,0],[-s,c,0],[0,0,1]];k.3O=ez(m1,k.3O)};3u.9l=C(aX,aY){k.bI*=aX;k.cD*=aY;B m1=[[aX,0,0],[0,aY,0],[0,0,1]];k.3O=ez(m1,k.3O)};3u.qe=C(){};3u.vp=C(){};3u.vq=C(){I 1h i2};C dd(qh){k.ka=qh;k.jW=0;k.k2=0;k.dL=[];k.eb={x:0,y:0}}dd.L.4R=C(q4,gj){gj=jQ(gj);k.dL.1L({1O:1-q4,1d:gj})};C i2(){}jO=ke;q8=fM;vk=dd;vl=i2})()}',62,2460,'||||||||||||||||||||this|||||||||||||||||var|function|SimileAjax|style||||return|Timeline|evt|prototype|elmt|null|e2uHash|params||div|else||left|top||width|||||length|||||||height|theme|Math|WindowManager|color|metrics|DateTime|DOM|new|for|Graphics|url|_band|text|Timeplot|event|appendChild|date|timeline|ctx|band|doc|break|plot|true|createElement|_canvas|round|false|target|_unit|_Band|_timeline|document|display|unit|date2|case|push|getTime|node|offset|while|startPixel|max|_params|index|highlightIndex|startDate|className|indexOf|ether|containerDiv||_events|timeplot|_lineLayer|||xmlhttp||100|time|registerEvent|min|margins||listener|data|zone|endDate|start|bottom|compare|labelSize|opacity|dateToPixelOffset|bubble|position|domEvt|Number|layer|urlPrefix|typeof|_timeplot|label|block|DetailedEventPainter|tapeDiv|DefaultEventSource|value|Platform|getDocument|right|eventTheme|background|string|timeZone|callback|geometry|eventSource|pixels|NativeDateUnit|icon|minDate|window|_markerLayer|body|align|absolute|OriginalEventPainter|_theme|browser|image|labelLeft|||firstChild||||||||line|none|multiple|images|canvas|Date|clickHandler|Debug|track|name|_id|paint|trackHeight|lineTo|_zones|gradient|_eventLayer|labeller|message|dateObject|contextPrototype|type|xml|coords|_start|tapeElmtData|png|setAttribute|endPixel|255|divImg|parseInt|createLayerDiv|_div|innerHTML|arguments|_Impl|result|initialize|try|m_|getStart|zone2|mousedown|startTime|locale|pos|maxDate|EventIndex|_plotInfo|styles|bandInfo||toScreen||_highlightLayer|range|end|events|toString|img|_containerDiv|iconTrack|hidden|catch|substr|_viewLength|intervalUnit|self|getUTCFullYear|labelDiv|orientation|endTime|OverviewEventPainter|iconElmtData|bindings|_eventSource|setOpacity|highlight|fDone|XmlHttp|fError|_onSelectListeners|solid|0px|labelTrack|grid|pageX|removeLayerDiv|getAttribute|Object|_plots|trackIncrement|tableStartLabel|_layerDiv|_a|_ether|duration|getID|zoneStart|base|trackOffset|_dataSource|Array|fillStyle|addColorStop|showLine|tableEndLabel|ownerDocument|size|tapeTrack|lineStr|_layers|_lens||link|parseDateTimeFunction|log|POSITIVE_INFINITY|GregorianDateLabeller|moveTo|contentWidth|verticalAlign|iconDiv|_startDate|gregorianUnitLengths|add|labelElmtData|_highlightDiv|_eventIdToElmt|_frc|interval|labelTop|_backgroundLayer|times|instant|placeDiv|_highlightMatcher|_filterMatcher|values|iconLeftEdge|removeChild|splice|overflow|lineWidth|_createHighlightDiv|_viewOffset|_ghostCoords|pageY|parentElmt|iconWidth|src|filter|isHorizontal|dimensions|replace|marker|nextquote|isIE|Color|getEnd|childNode|offsetHeight|softPaint|_dragging|floor|eventPainter|from|undefined|divLine|msg2|lineDiv|context|elmt2|_syncWithBand|_map||1000|ghostElmt|offsetWidth|statusText|_timeGeometry|pixelOffsetToDate|_listeners|documentElement|percent|getCoords_|nodeType|emphasized|_bands|divWeekend|handlerName|dataSource|parseFromObject|format|_hash|clientWidth|highlightMatcher|contentHeight|lens|contentDiv|divInner|script|setUTCFullYear|zoneEnd|attribute|YEAR|_paintEventTape|eventPainterParams|_minValue|magnify|getPageCoordinates|_earliestDate|substring|latestDate|earliestDate|exception|labelRight|added|update|next|iterator|filterMatcher|_data|beginPath|getUnit|_highlight|DAY|Set|tickDiv|abs|_locale|bubbleWidth|binding|clientHeight|sum|_valueFlag|latestStartPixel|cancelEvent|apply|getContext|getText|wikiSection||wikiURL|split|g_vml_|switch|HOUR|reset|String|_timeZone|layout|_tracks|stroke|currentPath_|getMinDate|plotInfo|elementAt|firstDayOfWeek|createTextNode|day|_message|getColor|lineColor|_paintEventLabel|templateNode|registerEventWithObject|_currentIndex|_hasNext|instanceof|_dropTargetHighlightElement|middle|level|SortedArray|getPixelLength|_backLayer|elmtCopyright|minPixel|getMaxDate|cursor|_grid|tick|object|_upperTracks|parentNode|_elmt|onerror|_lowerTracks|_latestDate|HotZoneEther|title|labelPrecise|offsetFromLine|fromTime|dateTimeFormat|rightEdge|_index|divContent|_resolveRelativeURL|fieldElmts|inc|console|bubbleHeight|addListener|removeListener|setUTCDate|hideLoadingMessage|setTime|labelBackgroundDiv|_maxValue|visibility|MINUTE|nextnline|_timeFlag|getEventRelativeCoordinates|eventName|MILLENNIUM|1px|_valueGeometry|fillColor|_getTrackData|_draggingModeIndicatorElmt|iconHeight|edge|table|_gridColor|_paddingX|putDiv|_calculateGrid|firstIndex|dispose|inputDiv|shiftPixels|aHeight|alert|gap|createImg|iconRightEdge|join|styleString|status|_moveEther|load|onAddMany|_plotInfos|strokeStyle|trackGap|charAt|aWidth|description|dom|_bubblePointOffset|getUTCMonth|radius|_draggedElement|parseGregorianDateTime|computeSize|innerFrame|_bubblePadding|set|_onScrollListeners||clientX|overview|foreground|backgroundColor||clientY|zones||setUTCMonth|_onClickInstantEvent|quoted|wikiID|direct|earliestEndPixel|_scrollSpeed|scale2|_fire|hasNext|_keyboardInput|comps|scale|_end|throw|_range|pngIsTranslucent|createTranslucentImage|lineJoin|iconTrackData|_axisLabelsPlacement|change|_next|filenames|_decorators|_mode|_color|_valueFlagLineLeft|_intervalMarkerLayout|eventLabelPrototype|etherPainter|axisColor|alpha|gridColor|close|tag|segments|except|_showBubble|href|WEEK|incrementDate|overviewTrack|setImg|aRadius|source|textColor|get|_halfArrowWidth|HTML|tapeHeight|_etherPainter|LogarithmicValueGeometry|_endDate|ClassicTheme|_ghostElmt|_valueRange|focus|power|SCROLL_MULTIPLES|LinearEther|charset|pointer|getParser|_min|_max|Failed|divClose|droppable|highlightColors|ColumnSource|Microsoft|Error|DECADE|http|horizontal||simile|mit|edu|Z2|container||nextSibling|year|diffY|diffX|elmtCoords|isImprecise|_linMap|rgba|tdw|MagnifyingTimeGeometry|_valueFlagLineRight|month|_indexed|find|fillFrom|listeners|tagName|_active|MONTH|default|action|_bandInfos|keyCode|repeat|setTimeout|shift|painter|current|SECOND|||cont|separator|CENTURY|old|attrs|textarea|valueflag|eventID|closeBubble|_fireOnSelect|_lastCoords|getEarliestDate|toLowerCase||_getBaseURL|_draggedElementCallback|bandInfos|_eventPainter|rows|location|latestStartDate|removeDiv|_opacity|responseStream|tapeWidth|paintEvent|_changing|paintInstantEvent||innerDiv|_draggingMode|paintDurationEvent|_innerDiv|len|_prepareForPainting||wiki|run|showLoadingMessage|getLatestDate|eventIndex|setCenterVisibleDate|earliestEndDate|_bubble|css|arcScaleX_|parsed|currentX_|currentY_|_pixelsPerInterval|_interval|surfaceElement|pixels2|_period|instrumented|mouseup|GregorianEtherPainter|bottomDiv|earliestEnd|latestStart|DefaultTimeGeometry|extend|runtimeStyle|lineCap|||||startCoords|createLinearGradient|pressed|topDiv|setHighlight|_FontRenderingContext|obj|_process|test|tape|_clear|_processingListener|_findNext|toIndex|lines|centersOn|impreciseColor|_updateMappedValues|setUTCMilliseconds|fill|toTime2|nodeValue|toTime|timeShift||navigator|impreciseOpacity|suffix|inverse|extendUp|insidecolor|vmlStr|_axisColor|random|arcScaleY_|border|xStart|HotZoneGregorianEtherPainter|numeric|getCanvas|_multiple|_paintEventIcon|DefaultValueGeometry|1000000|progid|DXImageTransform|msg|outsidecolor|setUTCSeconds|divTitle|clearInDay|clearInYear|_earliestOverlapIndex|diff|_createRequest|lineTheme|warn|cp1x|copyright|cp1y|slice|backgroundColors|input|xEnd|DataSource|zIndex|getValue||onClear|getRange|CanvasGradient_|maxPixel|_findFreeTrack|_count||getIndex|colors|space|mid|YearCountEtherPainter|pixelOffset||_wikiSection|EtherIntervalMarkerLayout|con|loadXML|_cachedParent|_arrowOffsets|locales||||finally|classes|middleRightDiv|_minIndex|middleDiv|zEnd|docWidth|remove|vAlign|200|create|url2|colors_|number|createIntervalMarker|Event|parseVersionString|str|_painters|aFill|miter|_autoScroll|zStart|_paddingY|getProperty|hAlign|show|minDate2|58A0DC||clazz|QuarterlyEtherPainter|_hittest|MILLISECOND|later|removed|getDefaultLocale|_wikiURL|focus_|evtCoords|_findFreeTrackForSolid|_orientation|cancelPopups|getLabeller|EtherHighlight|softEdge|_popToLayer|dotColor||||ephemeral|_rightRate||handler2|getEventSource|_expandedRate|_centerX|NEGATIVE_INFINITY|_centerTime|fromTrack|mousemove|matrixMultiply|iso8601|putText|_cancelDragging|_potentialDropTarget|axisGradient|gridGradient|cloneValue|roundDownToInterval|positionDiv|param|_defaultTheme|incrementByInterval|nextseparator|cancelBubble|_paintEventLine|handler|_findFreeTrackForText|dec|toHexString|match|actLinear|getEvent|eval|root|miterLimit|paintImpreciseInstantEvent|getDefaultTheme|startTrack|removeAll|loaded|showBubble|childNodes|Boolean|_onClickDurationEvent|startsOn|_gridLineWidth|_time|showValues|getEventReverseIterator|centerDate|inside|weekendTheme|isInstant|copy|arrow|topRightDiv|_wildcardHandlerName|white|offsetLeft|types|docHeight|row|plotInfos|paintPreciseInstantEvent||timeGeometry|pixelsPerInterval|args|_mappedPeriod|saturdayPixel|showEventText|layerName|valueGeometry|setRange|_maxIndex|span|getValues|indent|_labeller|getUTCDate|_date|yEnd|getMonthName|indent2|CanvasRenderingContext2D_|bandWidth|error|silent|paintPreciseDurationEvent|_objectToString|05|isNaN|SpanHighlightDecorator|_paintEvents|gridLineWidth|yStart|array|paintImpreciseDurationEvent|bezierCurveTo|createLabeller|setTimeplot|ceil|_plot|earlier|getCount|makeDefaultValue|widthString|canDropOn|canDrop|axisLabelsPlacement|_width|||lineStyle|cp2x|PointHighlightDecorator|cp2y|aColor|_idToEvent|majorVersion|dotRadius|_eventListener|_initialize|endsOn|attachEvent|_earliestEnd|_latestStart||_upright|srcElement|paddingLeft|fromScreen|_painter|markers|getEventPageCoordinates|eventLineWidth|getViewWidth|setWikiInfo|fromDate|createMatrixIdentity|getLatestStart|prefix|getEarliestEnd|divTime|_valueFlagPole|2px|getData|divWiki|createMessageBubble|divBody|fillGradient|els|outerHTML|closePath|110|tapeTrackData|_syncWithBandHandler|element_|eventStart|ListenerQueue|distance|_compare||mouseOverHandler|fillInfoBubble|HORIZONTAL|valuesOpacity|timePassed|pop|click|clearRect|bottomRightDiv|AlphaImageLoader|_toHex|check|sizingMethod|_Animation|guts|44px|roundValues|exp|addPainter|labelInterval|occupiedTrackVisitor|_findFreeLowerTrackForText|markerTheme|getIcon||addOnSelectListener|saturday|getFilterMatcher|getHighlightMatcher|setHighlightMatcher|getTextColor|upIndex|setFilterMatcher|getUTCHours|getFontRenderingContext|removeOnSelectListener|downIndex|deEntify|getLineHeight|clientLocale|cells|maxDate2|call|getTimeZone|_description|isDuration|offsetY|endTrack|solidEdge|removeTimeZoneOffset|createTable|loadJSON|_findFreeUpperTrackForText|105|stylePrefix|textTitle|offsetX|_getScale|_instant|quarters|createBubbleForContentAndPoint|CanvasPattern_|highlights|ColumnDiffSource|lastCoords|JSON|getStyle|aperture|draggedElmt|indicatorElmt|handling|targetCoords||_onReadyStateChange||toNumber|move|magnifyWith|_aperture|_leftTimeMargin|_aperturePeriod|_leftRate||_leftScreenMargin|canvasMouseUp|styleProp|scrollLeft|||lensMouseUp|dateParser|gridStep|_column|parseFloat|_gridType|_gridShortSize|_getValue|XMLHTTP|ondrop|count|getAllEventIterator|_labels|parent|delete|dropped|606060|programIDs|_logarithmicCalculateGrid|_logMap|pow|_gridSpacing|dec2hex|onPop|hitNode|newEl|Invalid|initElement|auto|getElementsByTagName|dims|getTimezoneOffset|_closed|setUTCHours|setUTCMinutes|context_|aY0|dayofyear|aStartAngle|RegExp|rgb|aEndAngle|week|aX0|attributes|aClockwise|onreadystatechange|objects|hex|MIN_VALUE|_AllIterator|_ReverseIterator|00|childNode2|lin|actMagnifying|_initialized|_Iterator|evt2|newValues||newValueRange|_e2uHash|sub|processor|initialArray|_createDOMFromTemplate|_processDOMChildrenConstructedFromString|expx2|cStart|_mappedRange|_dragX|aRot|decode|_dragY|bundle|_prepareCanvas|cEnd|suffixes|mStack_|aStack_|isWin|G_vmlCanvasManager|_positionHighlight|processStyle|language|copyState|defaultClientLocales|loadTimeplot|getComputedStyle|radius1_|tid|destination|_onHighlightBandScroll|responseXML|includeJavascriptFile|radius2_|responseText|_onChanging|property|loadTimeline|SimileAjax_onLoad|getHead|_originalScrollSpeed|type_|plotID|offsetTop|isMozilla|G_vmlCanvasManager_|Plot|timeplotElement|mouseMoveHandler|concat|loadText|vertical|continue|VERTICAL|getDataSource|oldClass|content|eventEnd|first|getTimeGeometry|getValueGeometry|createBubbleForPoint|_endLabel|expansion|getMinVisibleDate|NumericEvent|dimension|_startLabel|addDiv|getMaxVisibleDate|_recenterDiv|_distributeWidths|heads|isFirefox|parseIso8601DateTime|isNetscape|cumulativeWidth|relative|parameterFraction|_createTranslucentImageHTML1|timePassedFraction|javascript|55px|_createTranslucentImage2|33px|_bubbleMargins|step|innerHeight|getWindowDims|loadingScriptsCount|head|_createTranslucentImageHTML2|roundUpToInterval|x00|mozilla|yearDiff|x1f|minorVersion|isOpera|isSafari|send|firefox|parseURLParameters|errors|Msxml2|localeCompare|programID||open|XMLHttpRequest|currentStyle|isUnix|template|rel|preventDefault|createInputElement|write|node2|_processDOMConstructedFromString|stylesheet|includeCssFile|isWin32||scrollTop|isMac|outer|urls|offsetParent|_createTranslucentImage1|firing|_bandInfo|decorators|keyup|keydown|_selectorListener|setSyncWithBand|1em|setBandShiftAndWidth|addOnScrollListener|removeOnScrollListener|getPixelWidth|syncWith|useLocalResources|search|_findDropTarget|onDropOn|loadMe|intervalPixels|json|detailed|original|showText|setViewLength|inner|getCenterVisibleDate|getViewLength|||_setSyncWithBandDate|_fireOnScroll|centerPixelOffset|_onAddMany|_softPaintDecorators|_softPaintEvents|implementations|_onClear|softLayout||createAnimation|_onMouseUp|_onMouseMove|_onMouseDown|scrollToCenter|_onMouseOut|_onDblClick|keyboardInput|_onKeyUp|_onKeyDown|onDragEnd|_onBodyMouseUp|toDate|getUTCDay|||setIso8601||setIso8601Time|originalTime|_dateDiffToPixelOffset|contains|addSet|Alpha|setDate|_pixelOffsetToDate|_timezoneRegexp|sign|_dateRegexp|_lineHeight|createDataFunction|dayofweek|_timeRegexp|setIso8601Date|secs|mins|hours|event1|event2|_onBodyMouseMove|_onBodyKeyUp|_onBodyKeyDown|_handleMouseDown|onDragStart|ghost|mouse|yellow|hittest|onDragBy|eventPhase|||_onBodyMouseDown|wildcardHandlerName|start2|getLast|getFirst|_paintDecorators|getHighestLayer|_canProcessEventAtLayer|popLayer|pushLayer|button||_textColor|the|but||specified|currently|onPropertyChange|supported|fixElement_||removeNode|microsoft|not||||inline|We|padding|MAX_VALUE|_fromHex|_showValues|toggle|Magnifying|aR1|aR0|getElement|aY1|oldRuntimeWidth|oldRuntimeHeight|valueflagLineLeft|timeflag|valueflagLineRight|onResize|init|valuepole|threshold|namespaces|getWidth|coordsize|getHeight|coordorigin|globalAlpha|opera|shadowColor|userAgent|getElementById|movingAverage|||removePainter|_clearCanvas|integral|paddingRight|init_|readyState|Loading|gif|group|with|variance|normalize||running|progress|_isBrowserSupported|_setUpright|labels|SIMILE|addPlot||_paintingListener|PI|getPeriod|||timeValuePosition|getLabeler|_labeler|visible|000|_timeValuePosition|butt|aCP1x|aCP1y|getTimezone|_expandedScreenTranslation|gridStepRange|_expandedTimeTranslation|square|_rightTimeMargin|shadowOffsetX|locate|loc|period|canvasMouseMove|canvasMouseDown|lensMouseDown|shadowOffsetY|_rightScreenMargin|toLocaleTimeString|setMagnifyingParams|lensMouseMove|toLocaleDateString|getHours|actLogarithmic|_linearCalculateGrid|arcType|_closeBubble|_parseText|125|arc|_values|_rightScreenTranslation|mouseOutHandler|aX1|box|_MagnifyingMap|fillRect|mouseout|mouseover|shadowBlur|oldListener|gridType|aCP2y|gridShortSize|aCP2x||_clearLabels|short|_column2|column2|aCPx|aCPy|newListener|column|_rightTimeTranslation|300|isClose|getImage|getLink|imageStyler||titleStyler|bodyStyler|fillDescription|translate|strings|_image|_text|_link|_icon|_|fillTime|timeStyler|_paintEventTick|tickElmtData|insertAdjacentHTML|shape|processLineCap|backgroundOpacity|borderLeft|wikiStyler|fillWikiInfo|labelWidth|impreciseTapeElmtData|borderTop|trim|getAllIterator|highlightOpacity|highlightColor|backgroundLayer|opt_doc|monthNames|markerDiv|aOffset|mondayPixel|monday|emphasizedLabelStyler|CanvasRenderingContext2D|labelStyler|labelIntervalFunctions|defaultLabelInterval|_bindings|section|clip|getIterator|getReverseIterator|aType|_obj|getUTCSeconds|getUTCMilliseconds|getUTCMinutes|toUTCString|_node|weekend|tickHeight|bold|getTotalViewLength|5px|decorator|fontWeight|insertCell|cs1|gradientradial|insertRow|pixel|iso|Processor|autoCreate|Simile_urlPrefix|operator|_operator|cos|8601|fromNumber|local|cs2|fontSize|u00D0|u00BF|ETH|Ntilde|u00D1|Euml|u00BE|iquest|Agrave|Oslash|u00D8|aacute|Yacute|u00C1|Aacute|u00CA|u00C0|u00E0|u00D7|agrave|u00DE|Ocirc|u00D4|u00CB|frac34|u00BC|frac12|u00BD||Otilde|szlig|u00DD|Ograve|u00D6|u00D2|Oacute|u00D5|u00DF|Ouml|Acirc|u00E1|Iacute|Ucirc|u00C4|u00DA||Auml|u00CD|Uacute|u00C7|u00DB|Uuml|u00C6|Ccedil|u00D3|u00E2|AElig|u00DC|Aring|u00C5|Icirc|Egrave|Atilde|u00C3|u00E3|u00C9|Iuml|Ecirc|u00C2|u00CF|Igrave|u00CC|u00D9|u00CE|atilde|u00C8|Ugrave|THORN|Eacute|acirc|u00ED|thinsp|u2009|u2003|emsp|ensp||u2002|zwnj|u200C|u200E|rlm|lrm||u200D|zwj|u02DC|tilde|u0153|Scaron|oelig|OElig|u003C|u003E||u0160|scaron|circ||||u02C6|u0178|Yuml|u0161|u200F|ndash|permil|u2030|u2021|Dagger|dagger|u2020|lsaquo|u2039|u20AC|fnof|euro|u203A|rsaquo|u201E|bdquo|u2018|rsquo|lsquo|u2014|u2013|mdash|u2019|sbquo|rdquo|u201D|u201C|ldquo|u201A|u0026|amp|icirc|u00EE|frac14|iacute||igrave|u00EC|iuml||u00EF|u00F1|ograve||ntilde|u00F0|||eth||u00EB|euml|u00E6|ccedil|||aelig|u00E5|u00E4|aring|u00E7|egrave|ecirc|u00EA|u00E9|eacute|u00E8|u00F2|oacute|u00FC|yacute|uuml|u00FB|u00FA|ucirc|u00FD|thorn|quot|u0022|u00FF|yuml|u00FE|uacute|u00F9|otilde|u00F5|u00F4|ocirc|u00F3|ouml|u00F6|u00F8|ugrave|oslash||u00F7|divide|auml|365|filled|fillcolor|getPropertyValue|defaultView|getSize|TR|lineOpen|createDOMFromTemplate|appendClassName|returnValue|BeforeEnd|addEventListener|Eaeflnr|strokecolor|path|isFinite|boolean|charCodeAt|u00|parseJSON|stroked|strokeweight|toJSONString|cropbottom|field|Style|Opacity|createTranslucentImageHTML|Matrix|sizingmethod|MozOpacity|5000px|innerWidth|static|scrollHeight|scrollWidth|hasChildNodes|insertBefore|children|cssFloat|styleFloat|float|cropright|croptop|removeAttribute|createDOMFromString|cropleft|createElementFromString|||Type|Content|rotate|appName|hasOwnProperty|unescape|decodeURIComponent|restore|mac|32bit|win32|save|win|prefixURLs||includeCssFiles|apos|CanvasGradient|CanvasPattern|findScript|JavaScript|includeJavascriptFiles|arcTo|createPattern|signal|scripts|x11|netscape|GET||ActiveXObject|onReadyStateChange|sort|post|POST|setrequestheader|overrideMimeType|_forceXML|newSeq|objectToString|nDetails|weight|msie|safari|beforeEnd|endcap|miterlimit|Caught|color2|focusposition|joinstyle|_doc|_content|u00AA|laquo|ordf|u00A9|u00A8|u00AB|u00AC|u00AE||reg|u00AD|shy|uml|u00A7|curren|u00A3||pound|u00A2|u00A4|yen|sect|u00A6|brvbar|u00A5|macr|u00AF|u00B7|cedil|middot|u00B6|para|u00B8|sup1|raquo|u00BA|ordm|u00B9|u00B5|micro|u00B1|plusmn|u00B0|deg|sup2|u00B2|u00B4|acute|u00B3|sup3|cent|u00A1|flat|autocomplete|margin|createStructuredDataCopyButton|quadraticCurveTo|off|onmousedown|u0192|ERA|EPOCH|select|20px|7777AA|M11|M12|M21|M22|crop|var_args|rect|strokeRect|createRadialGradient|drawImage|propertyName|onresize|complete|urn|schemas|com|startsWith|endsWith|iexcl|u00A0|nbsp||substitute|vml|createStyleSheet|60000|replaceChild|onpropertychange|timezoneOffset|VML|behavior|cssText|300px|150px|parse|u00BB|Rho|results|FIXME|SM|still|onAddOne|addMany|MSIE|heavyside|clear|gaussian|nodeName|implement|retainSet|removeSet|sin|u2666|toArray|visit|tanh|Operator|average|loadSPARQL|getEventIterator|convolution|darken|getBaseLayer|onAfterRedo|onBeforeRedo|getDescription|lighten|wikiLinkLabel|transparency|getWikiSection|getWikiURL|onAfterRedoSeveral|onBeforeRedoSeveral|wildcard|0123456789ABCDEF|FF|fire|lastIndexOf|_historyListener|onAfterUndo|onBeforeUndo|onAfterUndoSeveral|onBeforeUndoSeveral|diams|u2665|sube|u2284|nsub|u2283|u2286|supe|otimes|u2295|repaint|u2287|sup|u2282|asymp|u2245|cong|u223C|u2248|u2260|u2265|u2264|u2261|equiv|u2297|perp|loz|u232A|rang|u2329|u25CA|spades|hearts|u2663|clubs|u2660|lang|u230B|lceil|u22C5|sdot|u22A5|u2308|rceil|rfloor|u230A|lfloor|u2309|115|popAllLayers|getEtherPainter|startLabel|EEE|getEther|getEventPainter|endLabel|setMinVisibleDate|getViewOffset|are|working|DDD|CCC|now|see|Timeplot_Limitations|list|future|near|supporting|getLocale|AAA|aaa|setMaxVisibleDate|textAlign|over|createPlotInfo|paramTypes|browserLanguage|globalCompositeOperation|paddingBottom|removePlot|class|_plotsInfos|paddingTop|importers|06|showBubbleForEvent|your|grab|moz|sorry|terribly|2007|namespace|minWidth|20em|dblclick|browsers|long|blue|circle|_gridStep|gridSpacing|column1|createBandInfo|replaceListener|resources|use|_gridStepRange|FFFF00|250|borderBottom|BUBBLING_PHASE|registerForDragging|0000FF|FF0000|FFC000|getMinutes|down|cloneNode|createHotZoneBandInfo|cur|hBottomStyler|hBottomEmphasizedStyler|hTopStyler|hTopEmphasizedStyler|Bottom|FFFFE0|line_left|line_right|pole|toLocaleString|Right|vRightStyler|getBandCount|setDefaultTheme|dull|maxValues|getBand|isVertical|vRightEmphasizedStyler|vLeftStyler|vLeftEmphasizedStyler|sim|oplus|Iota|u03C1|rho|u03C0|sigmaf|u03C2|tau|u03C3|u0398|sigma|u03BF|omicron|u03BB|lambda|u03BA|kappa|Styler|u03BC|u03BE|u0399|u03BD|EmphasizedStyler|u03C4|u2234|u0396|Eta|u0397|u03D1|Zeta|upsih|bull|u03D6|piv|u039C|thetasym|u03C9|phi|u03C5|Theta|upsilon|u03C6|chi|omega|u03C8|psi|u03C7|u03B9|iota|Upsilon|u03A4|Tau|u03A3|u03A5|Phi|Psi|u03A7|Chi|u03A6|Sigma|u03A1|u039E||Xi|u039D|Nu|Mu|Omicron|u039B|u03A0|Pi|u039F|u03A8|Omega|u03B6|zeta|u03B5|epsilon|Left|eta|u03B8|theta|u03B7|Top|u03B4|Kappa|beta|u03B1|u03A9|Lambda|u03B2|gamma|u039A|delta|u03B3|u2022|u03D2|u2208|notin|isin|u2207|nabla|u2209|u220B|minus|u2211|u220F|prod|u2205|empty|hellip|hArr|u21D3|dArr|forall|u2200|u2203|exist|u2202|part|u2212|lowast|u2229|cap|Beta|u2228|cup|u0391|there4|u222B|int|u222A|dayNames|u2227|prop|u221A|radic|u2217|u221D|infin|and|u2220|ang|u221E|u21D2|u21D4|u0394|Delta|u211C|real|u2111|trade|u2122|rArr|larr|u2135|alefsym|u2118|weierp|Prime|u2033|u2032|prime|u2026|oline|u203E|u2044|Epsilon|u0395|frasl|uarr|u2190|u0392|Gamma|crarr|u21B5|lArr|u21D1|uArr|u21D0|harr|||u2194|darr|u2192|rarr|u2191|u0393|u2193'.split('|'),0,{}))
diff --git a/site/app/webroot/js/simile/amo-bundle.js b/site/app/webroot/js/simile/amo-bundle.js
new file mode 100644
index 0000000..ff78cd4
--- /dev/null
+++ b/site/app/webroot/js/simile/amo-bundle.js
@@ -0,0 +1,10830 @@
+
+
+//////////////////////////// AJAX LOADER /////////////////////////////
+
+if (typeof SimileAjax == "undefined") {
+ var SimileAjax = {
+ loaded: false,
+ loadingScriptsCount: 0,
+ error: null,
+ params: { bundle:"true" }
+ };
+
+ SimileAjax.Platform = new Object();
+ /*
+ HACK: We need these 2 things here because we cannot simply append
+ a <script> element containing code that accesses SimileAjax.Platform
+ to initialize it because IE executes that <script> code first
+ before it loads ajax.js and platform.js.
+ */
+
+ var getHead = function(doc) {
+ return doc.getElementsByTagName("head")[0];
+ };
+
+ SimileAjax.findScript = function(doc, substring) {
+ var heads = doc.documentElement.getElementsByTagName("head");
+ for (var h = 0; h < heads.length; h++) {
+ var node = heads[h].firstChild;
+ while (node != null) {
+ if (node.nodeType == 1 && node.tagName.toLowerCase() == "script") {
+ var url = node.src;
+ var i = url.indexOf(substring);
+ if (i >= 0) {
+ return url;
+ }
+ }
+ node = node.nextSibling;
+ }
+ }
+ return null;
+ };
+ SimileAjax.includeJavascriptFile = function(doc, url, onerror, charset) {
+ onerror = onerror || "";
+ if (doc.body == null) {
+ try {
+ var q = "'" + onerror.replace( /'/g, '&apos' ) + "'"; // "
+ doc.write("<script src='" + url + "' onerror="+ q +
+ (charset ? " charset='"+ charset +"'" : "") +
+ " type='text/javascript'>"+ onerror + "</script>");
+ return false;
+ } catch (e) {
+ // fall through
+ }
+ }
+
+ var script = doc.createElement("script");
+ if (onerror) {
+ try { script.innerHTML = onerror; } catch(e) {}
+ script.setAttribute("onerror", onerror);
+ }
+ if (charset) {
+ script.setAttribute("charset", charset);
+ }
+ script.type = "text/javascript";
+ script.language = "JavaScript";
+ script.src = url;
+ return getHead(doc).appendChild(script);
+ };
+ SimileAjax.includeJavascriptFiles = function(doc, urlPrefix, filenames) {
+ for (var i = 0; i < filenames.length; i++) {
+ SimileAjax.includeJavascriptFile(doc, urlPrefix + filenames[i]);
+ }
+ SimileAjax.loadingScriptsCount += filenames.length;
+ SimileAjax.includeJavascriptFile(doc, SimileAjax.urlPrefix + "scripts/signal.js?" + filenames.length);
+ };
+ SimileAjax.includeCssFile = function(doc, url) {
+ if (doc.body == null) {
+ try {
+ doc.write("<link rel='stylesheet' href='" + url + "' type='text/css'/>");
+ return;
+ } catch (e) {
+ // fall through
+ }
+ }
+
+ var link = doc.createElement("link");
+ link.setAttribute("rel", "stylesheet");
+ link.setAttribute("type", "text/css");
+ link.setAttribute("href", url);
+ getHead(doc).appendChild(link);
+ };
+ SimileAjax.includeCssFiles = function(doc, urlPrefix, filenames) {
+ for (var i = 0; i < filenames.length; i++) {
+ SimileAjax.includeCssFile(doc, urlPrefix + filenames[i]);
+ }
+ };
+
+ /**
+ * Append into urls each string in suffixes after prefixing it with urlPrefix.
+ * @param {Array} urls
+ * @param {String} urlPrefix
+ * @param {Array} suffixes
+ */
+ SimileAjax.prefixURLs = function(urls, urlPrefix, suffixes) {
+ for (var i = 0; i < suffixes.length; i++) {
+ urls.push(urlPrefix + suffixes[i]);
+ }
+ };
+
+ /**
+ * Parse out the query parameters from a URL
+ * @param {String} url the url to parse, or location.href if undefined
+ * @param {Object} to optional object to extend with the parameters
+ * @param {Object} types optional object mapping keys to value types
+ * (String, Number, Boolean or Array, String by default)
+ * @return a key/value Object whose keys are the query parameter names
+ * @type Object
+ */
+ SimileAjax.parseURLParameters = function(url, to, types) {
+ to = to || {};
+ types = types || {};
+
+ if (typeof url == "undefined") {
+ url = location.href;
+ }
+ var q = url.indexOf("?");
+ if (q < 0) {
+ return to;
+ }
+ url = (url+"#").slice(q+1, url.indexOf("#")); // toss the URL fragment
+
+ var params = url.split("&"), param, parsed = {};
+ var decode = window.decodeURIComponent || unescape;
+ for (var i = 0; param = params[i]; i++) {
+ var eq = param.indexOf("=");
+ var name = decode(param.slice(0,eq));
+ var old = parsed[name];
+ if (typeof old == "undefined") {
+ old = [];
+ } else if (!(old instanceof Array)) {
+ old = [old];
+ }
+ parsed[name] = old.concat(decode(param.slice(eq+1)));
+ }
+ for (var i in parsed) {
+ if (!parsed.hasOwnProperty(i)) continue;
+ var type = types[i] || String;
+ var data = parsed[i];
+ if (!(data instanceof Array)) {
+ data = [data];
+ }
+ if (type === Boolean && data[0] == "false") {
+ to[i] = false; // because Boolean("false") === true
+ } else {
+ to[i] = type.apply(this, data);
+ }
+ }
+ return to;
+ };
+
+ SimileAjax.loaded = true;
+}/*==================================================
+ * Platform Utility Functions and Constants
+ *==================================================
+ */
+
+SimileAjax.Platform.os = {
+ isMac: false,
+ isWin: false,
+ isWin32: false,
+ isUnix: false
+};
+SimileAjax.Platform.browser = {
+ isIE: false,
+ isNetscape: false,
+ isMozilla: false,
+ isFirefox: false,
+ isOpera: false,
+ isSafari: false,
+
+ majorVersion: 0,
+ minorVersion: 0
+};
+
+(function() {
+ var an = navigator.appName.toLowerCase();
+ var ua = navigator.userAgent.toLowerCase();
+
+ /*
+ * Operating system
+ */
+ SimileAjax.Platform.os.isMac = (ua.indexOf('mac') != -1);
+ SimileAjax.Platform.os.isWin = (ua.indexOf('win') != -1);
+ SimileAjax.Platform.os.isWin32 = SimileAjax.Platform.isWin && (
+ ua.indexOf('95') != -1 ||
+ ua.indexOf('98') != -1 ||
+ ua.indexOf('nt') != -1 ||
+ ua.indexOf('win32') != -1 ||
+ ua.indexOf('32bit') != -1
+ );
+ SimileAjax.Platform.os.isUnix = (ua.indexOf('x11') != -1);
+
+ /*
+ * Browser
+ */
+ SimileAjax.Platform.browser.isIE = (an.indexOf("microsoft") != -1);
+ SimileAjax.Platform.browser.isNetscape = (an.indexOf("netscape") != -1);
+ SimileAjax.Platform.browser.isMozilla = (ua.indexOf("mozilla") != -1);
+ SimileAjax.Platform.browser.isFirefox = (ua.indexOf("firefox") != -1);
+ SimileAjax.Platform.browser.isOpera = (an.indexOf("opera") != -1);
+ SimileAjax.Platform.browser.isSafari = (an.indexOf("safari") != -1);
+
+ var parseVersionString = function(s) {
+ var a = s.split(".");
+ SimileAjax.Platform.browser.majorVersion = parseInt(a[0]);
+ SimileAjax.Platform.browser.minorVersion = parseInt(a[1]);
+ };
+ var indexOf = function(s, sub, start) {
+ var i = s.indexOf(sub, start);
+ return i >= 0 ? i : s.length;
+ };
+
+ if (SimileAjax.Platform.browser.isMozilla) {
+ var offset = ua.indexOf("mozilla/");
+ if (offset >= 0) {
+ parseVersionString(ua.substring(offset + 8, indexOf(ua, " ", offset)));
+ }
+ }
+ if (SimileAjax.Platform.browser.isIE) {
+ var offset = ua.indexOf("msie ");
+ if (offset >= 0) {
+ parseVersionString(ua.substring(offset + 5, indexOf(ua, ";", offset)));
+ }
+ }
+ if (SimileAjax.Platform.browser.isNetscape) {
+ var offset = ua.indexOf("rv:");
+ if (offset >= 0) {
+ parseVersionString(ua.substring(offset + 3, indexOf(ua, ")", offset)));
+ }
+ }
+ if (SimileAjax.Platform.browser.isFirefox) {
+ var offset = ua.indexOf("firefox/");
+ if (offset >= 0) {
+ parseVersionString(ua.substring(offset + 8, indexOf(ua, " ", offset)));
+ }
+ }
+
+ if (!("localeCompare" in String.prototype)) {
+ String.prototype.localeCompare = function (s) {
+ if (this < s) return -1;
+ else if (this > s) return 1;
+ else return 0;
+ };
+ }
+})();
+
+SimileAjax.Platform.getDefaultLocale = function() {
+ return SimileAjax.Platform.clientLocale;
+};/*==================================================
+ * Debug Utility Functions
+ *==================================================
+ */
+
+SimileAjax.Debug = {
+ silent: false
+};
+
+SimileAjax.Debug.log = function(msg) {
+ var f;
+ if ("console" in window && "log" in window.console) { // FireBug installed
+ f = function(msg2) {
+ console.log(msg2);
+ }
+ } else {
+ f = function(msg2) {
+ if (!SimileAjax.Debug.silent) {
+ alert(msg2);
+ }
+ }
+ }
+ SimileAjax.Debug.log = f;
+ f(msg);
+};
+
+SimileAjax.Debug.warn = function(msg) {
+ var f;
+ if ("console" in window && "warn" in window.console) { // FireBug installed
+ f = function(msg2) {
+ console.warn(msg2);
+ }
+ } else {
+ f = function(msg2) {
+ if (!SimileAjax.Debug.silent) {
+ alert(msg2);
+ }
+ }
+ }
+ SimileAjax.Debug.warn = f;
+ f(msg);
+};
+
+SimileAjax.Debug.exception = function(e, msg) {
+ var f, params = SimileAjax.parseURLParameters();
+ if (params.errors == "throw" || SimileAjax.params.errors == "throw") {
+ f = function(e2, msg2) {
+ throw(e2); // do not hide from browser's native debugging features
+ };
+ } else if ("console" in window && "error" in window.console) { // FireBug installed
+ f = function(e2, msg2) {
+ if (msg2 != null) {
+ console.error(msg2 + " %o", e2);
+ } else {
+ console.error(e2);
+ }
+ throw(e2); // do not hide from browser's native debugging features
+ };
+ } else {
+ f = function(e2, msg2) {
+ if (!SimileAjax.Debug.silent) {
+ alert("Caught exception: " + msg2 + "\n\nDetails: " + ("description" in e2 ? e2.description : e2));
+ }
+ throw(e2); // do not hide from browser's native debugging features
+ };
+ }
+ SimileAjax.Debug.exception = f;
+ f(e, msg);
+};
+
+SimileAjax.Debug.objectToString = function(o) {
+ return SimileAjax.Debug._objectToString(o, "");
+};
+
+SimileAjax.Debug._objectToString = function(o, indent) {
+ var indent2 = indent + " ";
+ if (typeof o == "object") {
+ var s = "{";
+ for (n in o) {
+ s += indent2 + n + ": " + SimileAjax.Debug._objectToString(o[n], indent2) + "\n";
+ }
+ s += indent + "}";
+ return s;
+ } else if (typeof o == "array") {
+ var s = "[";
+ for (var n = 0; n < o.length; n++) {
+ s += SimileAjax.Debug._objectToString(o[n], indent2) + "\n";
+ }
+ s += indent + "]";
+ return s;
+ } else {
+ return o;
+ }
+};
+/**
+ * @fileOverview XmlHttp utility functions
+ * @name SimileAjax.XmlHttp
+ */
+
+SimileAjax.XmlHttp = new Object();
+
+/**
+ * Callback for XMLHttp onRequestStateChange.
+ */
+SimileAjax.XmlHttp._onReadyStateChange = function(xmlhttp, fError, fDone) {
+ switch (xmlhttp.readyState) {
+ // 1: Request not yet made
+ // 2: Contact established with server but nothing downloaded yet
+ // 3: Called multiple while downloading in progress
+
+ // Download complete
+ case 4:
+ try {
+ if (xmlhttp.status == 0 // file:// urls, works on Firefox
+ || xmlhttp.status == 200 // http:// urls
+ ) {
+ if (fDone) {
+ fDone(xmlhttp);
+ }
+ } else {
+ if (fError) {
+ fError(
+ xmlhttp.statusText,
+ xmlhttp.status,
+ xmlhttp
+ );
+ }
+ }
+ } catch (e) {
+ SimileAjax.Debug.exception("XmlHttp: Error handling onReadyStateChange", e);
+ }
+ break;
+ }
+};
+
+/**
+ * Creates an XMLHttpRequest object. On the first run, this
+ * function creates a platform-specific function for
+ * instantiating an XMLHttpRequest object and then replaces
+ * itself with that function.
+ */
+SimileAjax.XmlHttp._createRequest = function() {
+ if (SimileAjax.Platform.browser.isIE) {
+ var programIDs = [
+ "Msxml2.XMLHTTP",
+ "Microsoft.XMLHTTP",
+ "Msxml2.XMLHTTP.4.0"
+ ];
+ for (var i = 0; i < programIDs.length; i++) {
+ try {
+ var programID = programIDs[i];
+ var f = function() {
+ return new ActiveXObject(programID);
+ };
+ var o = f();
+
+ // We are replacing the SimileAjax._createXmlHttpRequest
+ // function with this inner function as we've
+ // found out that it works. This is so that we
+ // don't have to do all the testing over again
+ // on subsequent calls.
+ SimileAjax.XmlHttp._createRequest = f;
+
+ return o;
+ } catch (e) {
+ // silent
+ }
+ }
+ // fall through to try new XMLHttpRequest();
+ }
+
+ try {
+ var f = function() {
+ return new XMLHttpRequest();
+ };
+ var o = f();
+
+ // We are replacing the SimileAjax._createXmlHttpRequest
+ // function with this inner function as we've
+ // found out that it works. This is so that we
+ // don't have to do all the testing over again
+ // on subsequent calls.
+ SimileAjax.XmlHttp._createRequest = f;
+
+ return o;
+ } catch (e) {
+ throw new Error("Failed to create an XMLHttpRequest object");
+ }
+};
+
+/**
+ * Performs an asynchronous HTTP GET.
+ *
+ * @param {Function} fError a function of the form
+ function(statusText, statusCode, xmlhttp)
+ * @param {Function} fDone a function of the form function(xmlhttp)
+ */
+SimileAjax.XmlHttp.get = function(url, fError, fDone) {
+ var xmlhttp = SimileAjax.XmlHttp._createRequest();
+
+ xmlhttp.open("GET", url, true);
+ xmlhttp.onreadystatechange = function() {
+ SimileAjax.XmlHttp._onReadyStateChange(xmlhttp, fError, fDone);
+ };
+ xmlhttp.send(null);
+};
+
+/**
+ * Performs an asynchronous HTTP POST.
+ *
+ * @param {Function} fError a function of the form
+ function(statusText, statusCode, xmlhttp)
+ * @param {Function} fDone a function of the form function(xmlhttp)
+ */
+SimileAjax.XmlHttp.post = function(url, body, fError, fDone) {
+ var xmlhttp = SimileAjax.XmlHttp._createRequest();
+
+ xmlhttp.open("POST", url, true);
+ xmlhttp.onreadystatechange = function() {
+ SimileAjax.XmlHttp._onReadyStateChange(xmlhttp, fError, fDone);
+ };
+ xmlhttp.send(body);
+};
+
+SimileAjax.XmlHttp._forceXML = function(xmlhttp) {
+ try {
+ xmlhttp.overrideMimeType("text/xml");
+ } catch (e) {
+ xmlhttp.setrequestheader("Content-Type", "text/xml");
+ }
+};/*
+ * Copied directly from http://www.json.org/json.js.
+ */
+
+/*
+ json.js
+ 2006-04-28
+
+ This file adds these methods to JavaScript:
+
+ object.toJSONString()
+
+ This method produces a JSON text from an object. The
+ object must not contain any cyclical references.
+
+ array.toJSONString()
+
+ This method produces a JSON text from an array. The
+ array must not contain any cyclical references.
+
+ string.parseJSON()
+
+ This method parses a JSON text to produce an object or
+ array. It will return false if there is an error.
+*/
+
+SimileAjax.JSON = new Object();
+
+(function () {
+ var m = {
+ '\b': '\\b',
+ '\t': '\\t',
+ '\n': '\\n',
+ '\f': '\\f',
+ '\r': '\\r',
+ '"' : '\\"',
+ '\\': '\\\\'
+ };
+ var s = {
+ array: function (x) {
+ var a = ['['], b, f, i, l = x.length, v;
+ for (i = 0; i < l; i += 1) {
+ v = x[i];
+ f = s[typeof v];
+ if (f) {
+ v = f(v);
+ if (typeof v == 'string') {
+ if (b) {
+ a[a.length] = ',';
+ }
+ a[a.length] = v;
+ b = true;
+ }
+ }
+ }
+ a[a.length] = ']';
+ return a.join('');
+ },
+ 'boolean': function (x) {
+ return String(x);
+ },
+ 'null': function (x) {
+ return "null";
+ },
+ number: function (x) {
+ return isFinite(x) ? String(x) : 'null';
+ },
+ object: function (x) {
+ if (x) {
+ if (x instanceof Array) {
+ return s.array(x);
+ }
+ var a = ['{'], b, f, i, v;
+ for (i in x) {
+ v = x[i];
+ f = s[typeof v];
+ if (f) {
+ v = f(v);
+ if (typeof v == 'string') {
+ if (b) {
+ a[a.length] = ',';
+ }
+ a.push(s.string(i), ':', v);
+ b = true;
+ }
+ }
+ }
+ a[a.length] = '}';
+ return a.join('');
+ }
+ return 'null';
+ },
+ string: function (x) {
+ if (/["\\\x00-\x1f]/.test(x)) {
+ x = x.replace(/([\x00-\x1f\\"])/g, function(a, b) {
+ var c = m[b];
+ if (c) {
+ return c;
+ }
+ c = b.charCodeAt();
+ return '\\u00' +
+ Math.floor(c / 16).toString(16) +
+ (c % 16).toString(16);
+ });
+ }
+ return '"' + x + '"';
+ }
+ };
+
+ SimileAjax.JSON.toJSONString = function(o) {
+ if (o instanceof Object) {
+ return s.object(o);
+ } else if (o instanceof Array) {
+ return s.array(o);
+ } else {
+ return o.toString();
+ }
+ };
+
+ SimileAjax.JSON.parseJSON = function () {
+ try {
+ return !(/[^,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]/.test(
+ this.replace(/"(\\.|[^"\\])*"/g, ''))) &&
+ eval('(' + this + ')');
+ } catch (e) {
+ return false;
+ }
+ };
+})();
+/*==================================================
+ * DOM Utility Functions
+ *==================================================
+ */
+
+SimileAjax.DOM = new Object();
+
+SimileAjax.DOM.registerEventWithObject = function(elmt, eventName, obj, handlerName) {
+ SimileAjax.DOM.registerEvent(elmt, eventName, function(elmt2, evt, target) {
+ return obj[handlerName].call(obj, elmt2, evt, target);
+ });
+};
+
+SimileAjax.DOM.registerEvent = function(elmt, eventName, handler) {
+ var handler2 = function(evt) {
+ evt = (evt) ? evt : ((event) ? event : null);
+ if (evt) {
+ var target = (evt.target) ?
+ evt.target : ((evt.srcElement) ? evt.srcElement : null);
+ if (target) {
+ target = (target.nodeType == 1 || target.nodeType == 9) ?
+ target : target.parentNode;
+ }
+
+ return handler(elmt, evt, target);
+ }
+ return true;
+ }
+
+ if (SimileAjax.Platform.browser.isIE) {
+ elmt.attachEvent("on" + eventName, handler2);
+ } else {
+ elmt.addEventListener(eventName, handler2, false);
+ }
+};
+
+SimileAjax.DOM.getPageCoordinates = function(elmt) {
+ var left = 0;
+ var top = 0;
+
+ if (elmt.nodeType != 1) {
+ elmt = elmt.parentNode;
+ }
+
+ var elmt2 = elmt;
+ while (elmt2 != null) {
+ left += elmt2.offsetLeft;
+ top += elmt2.offsetTop;
+ elmt2 = elmt2.offsetParent;
+ }
+
+ var body = document.body;
+ while (elmt != null && elmt != body) {
+ if ("scrollLeft" in elmt) {
+ left -= elmt.scrollLeft;
+ top -= elmt.scrollTop;
+ }
+ elmt = elmt.parentNode;
+ }
+
+ return { left: left, top: top };
+};
+
+SimileAjax.DOM.getSize = function(elmt) {
+ var w = this.getStyle(elmt,"width");
+ var h = this.getStyle(elmt,"height");
+ if (w.indexOf("px") > -1) w = w.replace("px","");
+ if (h.indexOf("px") > -1) h = h.replace("px","");
+ return {
+ w: w,
+ h: h
+ }
+}
+
+SimileAjax.DOM.getStyle = function(elmt, styleProp) {
+ if (elmt.currentStyle) { // IE
+ var style = elmt.currentStyle[styleProp];
+ } else if (window.getComputedStyle) { // standard DOM
+ var style = document.defaultView.getComputedStyle(elmt, null).getPropertyValue(styleProp);
+ } else {
+ var style = "";
+ }
+ return style;
+}
+
+SimileAjax.DOM.getEventRelativeCoordinates = function(evt, elmt) {
+ if (SimileAjax.Platform.browser.isIE) {
+ return {
+ x: evt.offsetX,
+ y: evt.offsetY
+ };
+ } else {
+ var coords = SimileAjax.DOM.getPageCoordinates(elmt);
+ return {
+ x: evt.pageX - coords.left,
+ y: evt.pageY - coords.top
+ };
+ }
+};
+
+SimileAjax.DOM.getEventPageCoordinates = function(evt) {
+ if (SimileAjax.Platform.browser.isIE) {
+ return {
+ x: evt.clientX + document.body.scrollLeft,
+ y: evt.clientY + document.body.scrollTop
+ };
+ } else {
+ return {
+ x: evt.pageX,
+ y: evt.pageY
+ };
+ }
+};
+
+SimileAjax.DOM.hittest = function(x, y, except) {
+ return SimileAjax.DOM._hittest(document.body, x, y, except);
+};
+
+SimileAjax.DOM._hittest = function(elmt, x, y, except) {
+ var childNodes = elmt.childNodes;
+ outer: for (var i = 0; i < childNodes.length; i++) {
+ var childNode = childNodes[i];
+ for (var j = 0; j < except.length; j++) {
+ if (childNode == except[j]) {
+ continue outer;
+ }
+ }
+
+ if (childNode.offsetWidth == 0 && childNode.offsetHeight == 0) {
+ /*
+ * Sometimes SPAN elements have zero width and height but
+ * they have children like DIVs that cover non-zero areas.
+ */
+ var hitNode = SimileAjax.DOM._hittest(childNode, x, y, except);
+ if (hitNode != childNode) {
+ return hitNode;
+ }
+ } else {
+ var top = 0;
+ var left = 0;
+
+ var node = childNode;
+ while (node) {
+ top += node.offsetTop;
+ left += node.offsetLeft;
+ node = node.offsetParent;
+ }
+
+ if (left <= x && top <= y && (x - left) < childNode.offsetWidth && (y - top) < childNode.offsetHeight) {
+ return SimileAjax.DOM._hittest(childNode, x, y, except);
+ } else if (childNode.nodeType == 1 && childNode.tagName == "TR") {
+ /*
+ * Table row might have cells that span several rows.
+ */
+ var childNode2 = SimileAjax.DOM._hittest(childNode, x, y, except);
+ if (childNode2 != childNode) {
+ return childNode2;
+ }
+ }
+ }
+ }
+ return elmt;
+};
+
+SimileAjax.DOM.cancelEvent = function(evt) {
+ evt.returnValue = false;
+ evt.cancelBubble = true;
+ if ("preventDefault" in evt) {
+ evt.preventDefault();
+ }
+};
+
+SimileAjax.DOM.appendClassName = function(elmt, className) {
+ var classes = elmt.className.split(" ");
+ for (var i = 0; i < classes.length; i++) {
+ if (classes[i] == className) {
+ return;
+ }
+ }
+ classes.push(className);
+ elmt.className = classes.join(" ");
+};
+
+SimileAjax.DOM.createInputElement = function(type) {
+ var div = document.createElement("div");
+ div.innerHTML = "<input type='" + type + "' />";
+
+ return div.firstChild;
+};
+
+SimileAjax.DOM.createDOMFromTemplate = function(template) {
+ var result = {};
+ result.elmt = SimileAjax.DOM._createDOMFromTemplate(template, result, null);
+
+ return result;
+};
+
+SimileAjax.DOM._createDOMFromTemplate = function(templateNode, result, parentElmt) {
+ if (templateNode == null) {
+ /*
+ var node = doc.createTextNode("--null--");
+ if (parentElmt != null) {
+ parentElmt.appendChild(node);
+ }
+ return node;
+ */
+ return null;
+ } else if (typeof templateNode != "object") {
+ var node = document.createTextNode(templateNode);
+ if (parentElmt != null) {
+ parentElmt.appendChild(node);
+ }
+ return node;
+ } else {
+ var elmt = null;
+ if ("tag" in templateNode) {
+ var tag = templateNode.tag;
+ if (parentElmt != null) {
+ if (tag == "tr") {
+ elmt = parentElmt.insertRow(parentElmt.rows.length);
+ } else if (tag == "td") {
+ elmt = parentElmt.insertCell(parentElmt.cells.length);
+ }
+ }
+ if (elmt == null) {
+ elmt = tag == "input" ?
+ SimileAjax.DOM.createInputElement(templateNode.type) :
+ document.createElement(tag);
+
+ if (parentElmt != null) {
+ parentElmt.appendChild(elmt);
+ }
+ }
+ } else {
+ elmt = templateNode.elmt;
+ if (parentElmt != null) {
+ parentElmt.appendChild(elmt);
+ }
+ }
+
+ for (var attribute in templateNode) {
+ var value = templateNode[attribute];
+
+ if (attribute == "field") {
+ result[value] = elmt;
+
+ } else if (attribute == "className") {
+ elmt.className = value;
+ } else if (attribute == "id") {
+ elmt.id = value;
+ } else if (attribute == "title") {
+ elmt.title = value;
+ } else if (attribute == "type" && elmt.tagName == "input") {
+ // do nothing
+ } else if (attribute == "style") {
+ for (n in value) {
+ var v = value[n];
+ if (n == "float") {
+ n = SimileAjax.Platform.browser.isIE ? "styleFloat" : "cssFloat";
+ }
+ elmt.style[n] = v;
+ }
+ } else if (attribute == "children") {
+ for (var i = 0; i < value.length; i++) {
+ SimileAjax.DOM._createDOMFromTemplate(value[i], result, elmt);
+ }
+ } else if (attribute != "tag" && attribute != "elmt") {
+ elmt.setAttribute(attribute, value);
+ }
+ }
+ return elmt;
+ }
+}
+
+SimileAjax.DOM._cachedParent = null;
+SimileAjax.DOM.createElementFromString = function(s) {
+ if (SimileAjax.DOM._cachedParent == null) {
+ SimileAjax.DOM._cachedParent = document.createElement("div");
+ }
+ SimileAjax.DOM._cachedParent.innerHTML = s;
+ return SimileAjax.DOM._cachedParent.firstChild;
+};
+
+SimileAjax.DOM.createDOMFromString = function(root, s, fieldElmts) {
+ var elmt = typeof root == "string" ? document.createElement(root) : root;
+ elmt.innerHTML = s;
+
+ var dom = { elmt: elmt };
+ SimileAjax.DOM._processDOMChildrenConstructedFromString(dom, elmt, fieldElmts != null ? fieldElmts : {} );
+
+ return dom;
+};
+
+SimileAjax.DOM._processDOMConstructedFromString = function(dom, elmt, fieldElmts) {
+ var id = elmt.id;
+ if (id != null && id.length > 0) {
+ elmt.removeAttribute("id");
+ if (id in fieldElmts) {
+ var parentElmt = elmt.parentNode;
+ parentElmt.insertBefore(fieldElmts[id], elmt);
+ parentElmt.removeChild(elmt);
+
+ dom[id] = fieldElmts[id];
+ return;
+ } else {
+ dom[id] = elmt;
+ }
+ }
+
+ if (elmt.hasChildNodes()) {
+ SimileAjax.DOM._processDOMChildrenConstructedFromString(dom, elmt, fieldElmts);
+ }
+};
+
+SimileAjax.DOM._processDOMChildrenConstructedFromString = function(dom, elmt, fieldElmts) {
+ var node = elmt.firstChild;
+ while (node != null) {
+ var node2 = node.nextSibling;
+ if (node.nodeType == 1) {
+ SimileAjax.DOM._processDOMConstructedFromString(dom, node, fieldElmts);
+ }
+ node = node2;
+ }
+};
+/**
+ * @fileOverview Graphics utility functions and constants
+ * @name SimileAjax.Graphics
+ */
+
+SimileAjax.Graphics = new Object();
+
+/**
+ * A boolean value indicating whether PNG translucency is supported on the
+ * user's browser or not.
+ *
+ * @type Boolean
+ */
+SimileAjax.Graphics.pngIsTranslucent = (!SimileAjax.Platform.browser.isIE) || (SimileAjax.Platform.browser.majorVersion > 6);
+
+/*==================================================
+ * Opacity, translucency
+ *==================================================
+ */
+SimileAjax.Graphics._createTranslucentImage1 = function(url, verticalAlign) {
+ var elmt = document.createElement("img");
+ elmt.setAttribute("src", url);
+ if (verticalAlign != null) {
+ elmt.style.verticalAlign = verticalAlign;
+ }
+ return elmt;
+};
+SimileAjax.Graphics._createTranslucentImage2 = function(url, verticalAlign) {
+ var elmt = document.createElement("img");
+ elmt.style.width = "1px"; // just so that IE will calculate the size property
+ elmt.style.height = "1px";
+ elmt.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + url +"', sizingMethod='image')";
+ elmt.style.verticalAlign = (verticalAlign != null) ? verticalAlign : "middle";
+ return elmt;
+};
+
+/**
+ * Creates a DOM element for an <code>img</code> tag using the URL given. This
+ * is a convenience method that automatically includes the necessary CSS to
+ * allow for translucency, even on IE.
+ *
+ * @function
+ * @param {String} url the URL to the image
+ * @param {String} verticalAlign the CSS value for the image's vertical-align
+ * @return {Element} a DOM element containing the <code>img</code> tag
+ */
+SimileAjax.Graphics.createTranslucentImage = SimileAjax.Graphics.pngIsTranslucent ?
+ SimileAjax.Graphics._createTranslucentImage1 :
+ SimileAjax.Graphics._createTranslucentImage2;
+
+SimileAjax.Graphics._createTranslucentImageHTML1 = function(url, verticalAlign) {
+ return "<img src=\"" + url + "\"" +
+ (verticalAlign != null ? " style=\"vertical-align: " + verticalAlign + ";\"" : "") +
+ " />";
+};
+SimileAjax.Graphics._createTranslucentImageHTML2 = function(url, verticalAlign) {
+ var style =
+ "width: 1px; height: 1px; " +
+ "filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + url +"', sizingMethod='image');" +
+ (verticalAlign != null ? " vertical-align: " + verticalAlign + ";" : "");
+
+ return "<img src='" + url + "' style=\"" + style + "\" />";
+};
+
+/**
+ * Creates an HTML string for an <code>img</code> tag using the URL given.
+ * This is a convenience method that automatically includes the necessary CSS
+ * to allow for translucency, even on IE.
+ *
+ * @function
+ * @param {String} url the URL to the image
+ * @param {String} verticalAlign the CSS value for the image's vertical-align
+ * @return {String} a string containing the <code>img</code> tag
+ */
+SimileAjax.Graphics.createTranslucentImageHTML = SimileAjax.Graphics.pngIsTranslucent ?
+ SimileAjax.Graphics._createTranslucentImageHTML1 :
+ SimileAjax.Graphics._createTranslucentImageHTML2;
+
+/**
+ * Sets the opacity on the given DOM element.
+ *
+ * @param {Element} elmt the DOM element to set the opacity on
+ * @param {Number} opacity an integer from 0 to 100 specifying the opacity
+ */
+SimileAjax.Graphics.setOpacity = function(elmt, opacity) {
+ if (SimileAjax.Platform.browser.isIE) {
+ elmt.style.filter = "progid:DXImageTransform.Microsoft.Alpha(Style=0,Opacity=" + opacity + ")";
+ } else {
+ var o = (opacity / 100).toString();
+ elmt.style.opacity = o;
+ elmt.style.MozOpacity = o;
+ }
+};
+
+/*==================================================
+ * Bubble
+ *==================================================
+ */
+SimileAjax.Graphics._bubbleMargins = {
+ top: 33,
+ bottom: 42,
+ left: 33,
+ right: 40
+}
+
+// pixels from boundary of the whole bubble div to the tip of the arrow
+SimileAjax.Graphics._arrowOffsets = {
+ top: 0,
+ bottom: 9,
+ left: 1,
+ right: 8
+}
+
+SimileAjax.Graphics._bubblePadding = 15;
+SimileAjax.Graphics._bubblePointOffset = 6;
+SimileAjax.Graphics._halfArrowWidth = 18;
+
+/**
+ * Creates a nice, rounded bubble popup with the given content in a div,
+ * page coordinates and a suggested width. The bubble will point to the
+ * location on the page as described by pageX and pageY. All measurements
+ * should be given in pixels.
+ *
+ * @param {Element} the content div
+ * @param {Number} pageX the x coordinate of the point to point to
+ * @param {Number} pageY the y coordinate of the point to point to
+ * @param {Number} contentWidth a suggested width of the content
+ * @param {String} orientation a string ("top", "bottom", "left", or "right")
+ * that describes the orientation of the arrow on the bubble
+ */
+SimileAjax.Graphics.createBubbleForContentAndPoint = function(div, pageX, pageY, contentWidth, orientation) {
+ if (typeof contentWidth != "number") {
+ contentWidth = 300;
+ }
+
+ div.style.position = "absolute";
+ div.style.left = "-5000px";
+ div.style.top = "0px";
+ div.style.width = contentWidth + "px";
+ document.body.appendChild(div);
+
+ window.setTimeout(function() {
+ var width = div.scrollWidth + 10;
+ var height = div.scrollHeight + 10;
+
+ var bubble = SimileAjax.Graphics.createBubbleForPoint(pageX, pageY, width, height, orientation);
+
+ document.body.removeChild(div);
+ div.style.position = "static";
+ div.style.left = "";
+ div.style.top = "";
+ div.style.width = width + "px";
+ bubble.content.appendChild(div);
+ }, 200);
+};
+
+/**
+ * Creates a nice, rounded bubble popup with the given page coordinates and
+ * content dimensions. The bubble will point to the location on the page
+ * as described by pageX and pageY. All measurements should be given in
+ * pixels.
+ *
+ * @param {Number} pageX the x coordinate of the point to point to
+ * @param {Number} pageY the y coordinate of the point to point to
+ * @param {Number} contentWidth the width of the content box in the bubble
+ * @param {Number} contentHeight the height of the content box in the bubble
+ * @param {String} orientation a string ("top", "bottom", "left", or "right")
+ * that describes the orientation of the arrow on the bubble
+ * @return {Element} a DOM element for the newly created bubble
+ */
+SimileAjax.Graphics.createBubbleForPoint = function(pageX, pageY, contentWidth, contentHeight, orientation) {
+ function getWindowDims() {
+ if (typeof window.innerHeight == 'number') {
+ return { w:window.innerWidth, h:window.innerHeight }; // Non-IE
+ } else if (document.documentElement && document.documentElement.clientHeight) {
+ return { // IE6+, in "standards compliant mode"
+ w:document.documentElement.clientWidth,
+ h:document.documentElement.clientHeight
+ };
+ } else if (document.body && document.body.clientHeight) {
+ return { // IE 4 compatible
+ w:document.body.clientWidth,
+ h:document.body.clientHeight
+ };
+ }
+ }
+
+ var close = function() {
+ if (!bubble._closed) {
+ document.body.removeChild(bubble._div);
+ bubble._doc = null;
+ bubble._div = null;
+ bubble._content = null;
+ bubble._closed = true;
+ }
+ }
+ var bubble = {
+ _closed: false
+ };
+
+ var dims = getWindowDims();
+ var docWidth = dims.w;
+ var docHeight = dims.h;
+
+ var margins = SimileAjax.Graphics._bubbleMargins;
+ contentWidth = parseInt(contentWidth, 10); // harden against bad input bugs
+ contentHeight = parseInt(contentHeight, 10); // getting numbers-as-strings
+ var bubbleWidth = margins.left + contentWidth + margins.right;
+ var bubbleHeight = margins.top + contentHeight + margins.bottom;
+
+ var pngIsTranslucent = SimileAjax.Graphics.pngIsTranslucent;
+ var urlPrefix = SimileAjax.urlPrefix;
+
+ var setImg = function(elmt, url, width, height) {
+ elmt.style.position = "absolute";
+ elmt.style.width = width + "px";
+ elmt.style.height = height + "px";
+ if (pngIsTranslucent) {
+ elmt.style.background = "url(" + url + ")";
+ } else {
+ elmt.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + url +"', sizingMethod='crop')";
+ }
+ }
+ var div = document.createElement("div");
+ div.style.width = bubbleWidth + "px";
+ div.style.height = bubbleHeight + "px";
+ div.style.position = "absolute";
+ div.style.zIndex = 1000;
+
+ var layer = SimileAjax.WindowManager.pushLayer(close, true, div);
+ bubble._div = div;
+ bubble.close = function() { SimileAjax.WindowManager.popLayer(layer); }
+
+ var divInner = document.createElement("div");
+ divInner.style.width = "100%";
+ divInner.style.height = "100%";
+ divInner.style.position = "relative";
+ div.appendChild(divInner);
+
+ var createImg = function(url, left, top, width, height) {
+ var divImg = document.createElement("div");
+ divImg.style.left = left + "px";
+ divImg.style.top = top + "px";
+ setImg(divImg, url, width, height);
+ divInner.appendChild(divImg);
+ }
+
+ createImg(urlPrefix + "images/bubble-top-left.png", 0, 0, margins.left, margins.top);
+ createImg(urlPrefix + "images/bubble-top.png", margins.left, 0, contentWidth, margins.top);
+ createImg(urlPrefix + "images/bubble-top-right.png", margins.left + contentWidth, 0, margins.right, margins.top);
+
+ createImg(urlPrefix + "images/bubble-left.png", 0, margins.top, margins.left, contentHeight);
+ createImg(urlPrefix + "images/bubble-right.png", margins.left + contentWidth, margins.top, margins.right, contentHeight);
+
+ createImg(urlPrefix + "images/bubble-bottom-left.png", 0, margins.top + contentHeight, margins.left, margins.bottom);
+ createImg(urlPrefix + "images/bubble-bottom.png", margins.left, margins.top + contentHeight, contentWidth, margins.bottom);
+ createImg(urlPrefix + "images/bubble-bottom-right.png", margins.left + contentWidth, margins.top + contentHeight, margins.right, margins.bottom);
+
+ var divClose = document.createElement("div");
+ divClose.style.left = (bubbleWidth - margins.right + SimileAjax.Graphics._bubblePadding - 16 - 2) + "px";
+ divClose.style.top = (margins.top - SimileAjax.Graphics._bubblePadding + 1) + "px";
+ divClose.style.cursor = "pointer";
+ setImg(divClose, urlPrefix + "images/close-button.png", 16, 16);
+ SimileAjax.WindowManager.registerEventWithObject(divClose, "click", bubble, "close");
+ divInner.appendChild(divClose);
+
+ var divContent = document.createElement("div");
+ divContent.style.position = "absolute";
+ divContent.style.left = margins.left + "px";
+ divContent.style.top = margins.top + "px";
+ divContent.style.width = contentWidth + "px";
+ divContent.style.height = contentHeight + "px";
+ divContent.style.overflow = "auto";
+ divContent.style.background = "white";
+ divInner.appendChild(divContent);
+ bubble.content = divContent;
+
+ (function() {
+ if (pageX - SimileAjax.Graphics._halfArrowWidth - SimileAjax.Graphics._bubblePadding > 0 &&
+ pageX + SimileAjax.Graphics._halfArrowWidth + SimileAjax.Graphics._bubblePadding < docWidth) {
+
+ var left = pageX - Math.round(contentWidth / 2) - margins.left;
+ left = pageX < (docWidth / 2) ?
+ Math.max(left, -(margins.left - SimileAjax.Graphics._bubblePadding)) :
+ Math.min(left, docWidth + (margins.right - SimileAjax.Graphics._bubblePadding) - bubbleWidth);
+
+ if ((orientation && orientation == "top") || (!orientation && (pageY - SimileAjax.Graphics._bubblePointOffset - bubbleHeight > 0))) { // top
+ var divImg = document.createElement("div");
+
+ divImg.style.left = (pageX - SimileAjax.Graphics._halfArrowWidth - left) + "px";
+ divImg.style.top = (margins.top + contentHeight) + "px";
+ setImg(divImg, urlPrefix + "images/bubble-bottom-arrow.png", 37, margins.bottom);
+ divInner.appendChild(divImg);
+
+ div.style.left = left + "px";
+ div.style.top = (pageY - SimileAjax.Graphics._bubblePointOffset - bubbleHeight +
+ SimileAjax.Graphics._arrowOffsets.bottom) + "px";
+
+ return;
+ } else if ((orientation && orientation == "bottom") || (!orientation && (pageY + SimileAjax.Graphics._bubblePointOffset + bubbleHeight < docHeight))) { // bottom
+ var divImg = document.createElement("div");
+
+ divImg.style.left = (pageX - SimileAjax.Graphics._halfArrowWidth - left) + "px";
+ divImg.style.top = "0px";
+ setImg(divImg, urlPrefix + "images/bubble-top-arrow.png", 37, margins.top);
+ divInner.appendChild(divImg);
+
+ div.style.left = left + "px";
+ div.style.top = (pageY + SimileAjax.Graphics._bubblePointOffset -
+ SimileAjax.Graphics._arrowOffsets.top) + "px";
+
+ return;
+ }
+ }
+
+ var top = pageY - Math.round(contentHeight / 2) - margins.top;
+ top = pageY < (docHeight / 2) ?
+ Math.max(top, -(margins.top - SimileAjax.Graphics._bubblePadding)) :
+ Math.min(top, docHeight + (margins.bottom - SimileAjax.Graphics._bubblePadding) - bubbleHeight);
+
+ if ((orientation && orientation == "left") || (!orientation && (pageX - SimileAjax.Graphics._bubblePointOffset - bubbleWidth > 0))) { // left
+ var divImg = document.createElement("div");
+
+ divImg.style.left = (margins.left + contentWidth) + "px";
+ divImg.style.top = (pageY - SimileAjax.Graphics._halfArrowWidth - top) + "px";
+ setImg(divImg, urlPrefix + "images/bubble-right-arrow.png", margins.right, 37);
+ divInner.appendChild(divImg);
+
+ div.style.left = (pageX - SimileAjax.Graphics._bubblePointOffset - bubbleWidth +
+ SimileAjax.Graphics._arrowOffsets.right) + "px";
+ div.style.top = top + "px";
+ } else if ((orientation && orientation == "right") || (!orientation && (pageX - SimileAjax.Graphics._bubblePointOffset - bubbleWidth < docWidth))) { // right
+ var divImg = document.createElement("div");
+
+ divImg.style.left = "0px";
+ divImg.style.top = (pageY - SimileAjax.Graphics._halfArrowWidth - top) + "px";
+ setImg(divImg, urlPrefix + "images/bubble-left-arrow.png", margins.left, 37);
+ divInner.appendChild(divImg);
+
+ div.style.left = (pageX + SimileAjax.Graphics._bubblePointOffset -
+ SimileAjax.Graphics._arrowOffsets.left) + "px";
+ div.style.top = top + "px";
+ }
+ })();
+
+ document.body.appendChild(div);
+
+ return bubble;
+};
+
+/**
+ * Creates a floating, rounded message bubble in the center of the window for
+ * displaying modal information, e.g. "Loading..."
+ *
+ * @param {Document} doc the root document for the page to render on
+ * @param {Object} an object with two properties, contentDiv and containerDiv,
+ * consisting of the newly created DOM elements
+ */
+SimileAjax.Graphics.createMessageBubble = function(doc) {
+ var containerDiv = doc.createElement("div");
+ if (SimileAjax.Graphics.pngIsTranslucent) {
+ var topDiv = doc.createElement("div");
+ topDiv.style.height = "33px";
+ topDiv.style.background = "url(" + SimileAjax.urlPrefix + "images/message-top-left.png) top left no-repeat";
+ topDiv.style.paddingLeft = "44px";
+ containerDiv.appendChild(topDiv);
+
+ var topRightDiv = doc.createElement("div");
+ topRightDiv.style.height = "33px";
+ topRightDiv.style.background = "url(" + SimileAjax.urlPrefix + "images/message-top-right.png) top right no-repeat";
+ topDiv.appendChild(topRightDiv);
+
+ var middleDiv = doc.createElement("div");
+ middleDiv.style.background = "url(" + SimileAjax.urlPrefix + "images/message-left.png) top left repeat-y";
+ middleDiv.style.paddingLeft = "44px";
+ containerDiv.appendChild(middleDiv);
+
+ var middleRightDiv = doc.createElement("div");
+ middleRightDiv.style.background = "url(" + SimileAjax.urlPrefix + "images/message-right.png) top right repeat-y";
+ middleRightDiv.style.paddingRight = "44px";
+ middleDiv.appendChild(middleRightDiv);
+
+ var contentDiv = doc.createElement("div");
+ middleRightDiv.appendChild(contentDiv);
+
+ var bottomDiv = doc.createElement("div");
+ bottomDiv.style.height = "55px";
+ bottomDiv.style.background = "url(" + SimileAjax.urlPrefix + "images/message-bottom-left.png) bottom left no-repeat";
+ bottomDiv.style.paddingLeft = "44px";
+ containerDiv.appendChild(bottomDiv);
+
+ var bottomRightDiv = doc.createElement("div");
+ bottomRightDiv.style.height = "55px";
+ bottomRightDiv.style.background = "url(" + SimileAjax.urlPrefix + "images/message-bottom-right.png) bottom right no-repeat";
+ bottomDiv.appendChild(bottomRightDiv);
+ } else {
+ containerDiv.style.border = "2px solid #7777AA";
+ containerDiv.style.padding = "20px";
+ containerDiv.style.background = "white";
+ SimileAjax.Graphics.setOpacity(containerDiv, 90);
+
+ var contentDiv = doc.createElement("div");
+ containerDiv.appendChild(contentDiv);
+ }
+
+ return {
+ containerDiv: containerDiv,
+ contentDiv: contentDiv
+ };
+};
+
+/*==================================================
+ * Animation
+ *==================================================
+ */
+
+/**
+ * Creates an animation for a function, and an interval of values. The word
+ * "animation" here is used in the sense of repeatedly calling a function with
+ * a current value from within an interval, and a delta value.
+ *
+ * @param {Function} f a function to be called every 50 milliseconds throughout
+ * the animation duration, of the form f(current, delta), where current is
+ * the current value within the range and delta is the current change.
+ * @param {Number} from a starting value
+ * @param {Number} to an ending value
+ * @param {Number} duration the duration of the animation in milliseconds
+ * @param {Function} [cont] an optional function that is called at the end of
+ * the animation, i.e. a continuation.
+ * @return {SimileAjax.Graphics._Animation} a new animation object
+ */
+SimileAjax.Graphics.createAnimation = function(f, from, to, duration, cont) {
+ return new SimileAjax.Graphics._Animation(f, from, to, duration, cont);
+};
+
+SimileAjax.Graphics._Animation = function(f, from, to, duration, cont) {
+ this.f = f;
+ this.cont = (typeof cont == "function") ? cont : function() {};
+
+ this.from = from;
+ this.to = to;
+ this.current = from;
+
+ this.duration = duration;
+ this.start = new Date().getTime();
+ this.timePassed = 0;
+};
+
+/**
+ * Runs this animation.
+ */
+SimileAjax.Graphics._Animation.prototype.run = function() {
+ var a = this;
+ window.setTimeout(function() { a.step(); }, 50);
+};
+
+/**
+ * Increments this animation by one step, and then continues the animation with
+ * <code>run()</code>.
+ */
+SimileAjax.Graphics._Animation.prototype.step = function() {
+ this.timePassed += 50;
+
+ var timePassedFraction = this.timePassed / this.duration;
+ var parameterFraction = -Math.cos(timePassedFraction * Math.PI) / 2 + 0.5;
+ var current = parameterFraction * (this.to - this.from) + this.from;
+
+ try {
+ this.f(current, current - this.current);
+ } catch (e) {
+ }
+ this.current = current;
+
+ if (this.timePassed < this.duration) {
+ this.run();
+ } else {
+ this.f(this.to, 0);
+ this["cont"]();
+ }
+};
+
+/*==================================================
+ * CopyPasteButton
+ *
+ * Adapted from http://spaces.live.com/editorial/rayozzie/demo/liveclip/liveclipsample/techPreview.html.
+ *==================================================
+ */
+
+/**
+ * Creates a button and textarea for displaying structured data and copying it
+ * to the clipboard. The data is dynamically generated by the given
+ * createDataFunction parameter.
+ *
+ * @param {String} image an image URL to use as the background for the
+ * generated box
+ * @param {Number} width the width in pixels of the generated box
+ * @param {Number} height the height in pixels of the generated box
+ * @param {Function} createDataFunction a function that is called with no
+ * arguments to generate the structured data
+ * @return a new DOM element
+ */
+SimileAjax.Graphics.createStructuredDataCopyButton = function(image, width, height, createDataFunction) {
+ var div = document.createElement("div");
+ div.style.position = "relative";
+ div.style.display = "inline";
+ div.style.width = width + "px";
+ div.style.height = height + "px";
+ div.style.overflow = "hidden";
+ div.style.margin = "2px";
+
+ if (SimileAjax.Graphics.pngIsTranslucent) {
+ div.style.background = "url(" + image + ") no-repeat";
+ } else {
+ div.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + image +"', sizingMethod='image')";
+ }
+
+ var style;
+ if (SimileAjax.Platform.browser.isIE) {
+ style = "filter:alpha(opacity=0)";
+ } else {
+ style = "opacity: 0";
+ }
+ div.innerHTML = "<textarea rows='1' autocomplete='off' value='none' style='" + style + "' />";
+
+ var textarea = div.firstChild;
+ textarea.style.width = width + "px";
+ textarea.style.height = height + "px";
+ textarea.onmousedown = function(evt) {
+ evt = (evt) ? evt : ((event) ? event : null);
+ if (evt.button == 2) {
+ textarea.value = createDataFunction();
+ textarea.select();
+ }
+ };
+
+ return div;
+};
+
+SimileAjax.Graphics.getFontRenderingContext = function(elmt, width) {
+ return new SimileAjax.Graphics._FontRenderingContext(elmt, width);
+};
+
+SimileAjax.Graphics._FontRenderingContext = function(elmt, width) {
+ this._elmt = elmt;
+ this._elmt.style.visibility = "hidden";
+ if (typeof width == "string") {
+ this._elmt.style.width = width;
+ } else if (typeof width == "number") {
+ this._elmt.style.width = width + "px";
+ }
+};
+
+SimileAjax.Graphics._FontRenderingContext.prototype.dispose = function() {
+ this._elmt = null;
+};
+
+SimileAjax.Graphics._FontRenderingContext.prototype.update = function() {
+ this._elmt.innerHTML = "A";
+ this._lineHeight = this._elmt.offsetHeight;
+};
+
+SimileAjax.Graphics._FontRenderingContext.prototype.computeSize = function(text) {
+ this._elmt.innerHTML = text;
+ return {
+ width: this._elmt.offsetWidth,
+ height: this._elmt.offsetHeight
+ };
+};
+
+SimileAjax.Graphics._FontRenderingContext.prototype.getLineHeight = function() {
+ return this._lineHeight;
+};
+/**
+ * @fileOverview A collection of date/time utility functions
+ * @name SimileAjax.DateTime
+ */
+
+SimileAjax.DateTime = new Object();
+
+SimileAjax.DateTime.MILLISECOND = 0;
+SimileAjax.DateTime.SECOND = 1;
+SimileAjax.DateTime.MINUTE = 2;
+SimileAjax.DateTime.HOUR = 3;
+SimileAjax.DateTime.DAY = 4;
+SimileAjax.DateTime.WEEK = 5;
+SimileAjax.DateTime.MONTH = 6;
+SimileAjax.DateTime.YEAR = 7;
+SimileAjax.DateTime.DECADE = 8;
+SimileAjax.DateTime.CENTURY = 9;
+SimileAjax.DateTime.MILLENNIUM = 10;
+
+SimileAjax.DateTime.EPOCH = -1;
+SimileAjax.DateTime.ERA = -2;
+
+/**
+ * An array of unit lengths, expressed in milliseconds, of various lengths of
+ * time. The array indices are predefined and stored as properties of the
+ * SimileAjax.DateTime object, e.g. SimileAjax.DateTime.YEAR.
+ * @type Array
+ */
+SimileAjax.DateTime.gregorianUnitLengths = [];
+ (function() {
+ var d = SimileAjax.DateTime;
+ var a = d.gregorianUnitLengths;
+
+ a[d.MILLISECOND] = 1;
+ a[d.SECOND] = 1000;
+ a[d.MINUTE] = a[d.SECOND] * 60;
+ a[d.HOUR] = a[d.MINUTE] * 60;
+ a[d.DAY] = a[d.HOUR] * 24;
+ a[d.WEEK] = a[d.DAY] * 7;
+ a[d.MONTH] = a[d.DAY] * 31;
+ a[d.YEAR] = a[d.DAY] * 365;
+ a[d.DECADE] = a[d.YEAR] * 10;
+ a[d.CENTURY] = a[d.YEAR] * 100;
+ a[d.MILLENNIUM] = a[d.YEAR] * 1000;
+ })();
+
+SimileAjax.DateTime._dateRegexp = new RegExp(
+ "^(-?)([0-9]{4})(" + [
+ "(-?([0-9]{2})(-?([0-9]{2}))?)", // -month-dayOfMonth
+ "(-?([0-9]{3}))", // -dayOfYear
+ "(-?W([0-9]{2})(-?([1-7]))?)" // -Wweek-dayOfWeek
+ ].join("|") + ")?$"
+);
+SimileAjax.DateTime._timezoneRegexp = new RegExp(
+ "Z|(([-+])([0-9]{2})(:?([0-9]{2}))?)$"
+);
+SimileAjax.DateTime._timeRegexp = new RegExp(
+ "^([0-9]{2})(:?([0-9]{2})(:?([0-9]{2})(\.([0-9]+))?)?)?$"
+);
+
+/**
+ * Takes a date object and a string containing an ISO 8601 date and sets the
+ * the date using information parsed from the string. Note that this method
+ * does not parse any time information.
+ *
+ * @param {Date} dateObject the date object to modify
+ * @param {String} string an ISO 8601 string to parse
+ * @return {Date} the modified date object
+ */
+SimileAjax.DateTime.setIso8601Date = function(dateObject, string) {
+ /*
+ * This function has been adapted from dojo.date, v.0.3.0
+ * http://dojotoolkit.org/.
+ */
+
+ var d = string.match(SimileAjax.DateTime._dateRegexp);
+ if(!d) {
+ throw new Error("Invalid date string: " + string);
+ }
+
+ var sign = (d[1] == "-") ? -1 : 1; // BC or AD
+ var year = sign * d[2];
+ var month = d[5];
+ var date = d[7];
+ var dayofyear = d[9];
+ var week = d[11];
+ var dayofweek = (d[13]) ? d[13] : 1;
+
+ dateObject.setUTCFullYear(year);
+ if (dayofyear) {
+ dateObject.setUTCMonth(0);
+ dateObject.setUTCDate(Number(dayofyear));
+ } else if (week) {
+ dateObject.setUTCMonth(0);
+ dateObject.setUTCDate(1);
+ var gd = dateObject.getUTCDay();
+ var day = (gd) ? gd : 7;
+ var offset = Number(dayofweek) + (7 * Number(week));
+
+ if (day <= 4) {
+ dateObject.setUTCDate(offset + 1 - day);
+ } else {
+ dateObject.setUTCDate(offset + 8 - day);
+ }
+ } else {
+ if (month) {
+ dateObject.setUTCDate(1);
+ dateObject.setUTCMonth(month - 1);
+ }
+ if (date) {
+ dateObject.setUTCDate(date);
+ }
+ }
+
+ return dateObject;
+};
+
+/**
+ * Takes a date object and a string containing an ISO 8601 time and sets the
+ * the time using information parsed from the string. Note that this method
+ * does not parse any date information.
+ *
+ * @param {Date} dateObject the date object to modify
+ * @param {String} string an ISO 8601 string to parse
+ * @return {Date} the modified date object
+ */
+SimileAjax.DateTime.setIso8601Time = function (dateObject, string) {
+ /*
+ * This function has been adapted from dojo.date, v.0.3.0
+ * http://dojotoolkit.org/.
+ */
+
+ var d = string.match(SimileAjax.DateTime._timeRegexp);
+ if(!d) {
+ SimileAjax.Debug.warn("Invalid time string: " + string);
+ return false;
+ }
+ var hours = d[1];
+ var mins = Number((d[3]) ? d[3] : 0);
+ var secs = (d[5]) ? d[5] : 0;
+ var ms = d[7] ? (Number("0." + d[7]) * 1000) : 0;
+
+ dateObject.setUTCHours(hours);
+ dateObject.setUTCMinutes(mins);
+ dateObject.setUTCSeconds(secs);
+ dateObject.setUTCMilliseconds(ms);
+
+ return dateObject;
+};
+
+/**
+ * The timezone offset in minutes in the user's browser.
+ * @type Number
+ */
+SimileAjax.DateTime.timezoneOffset = new Date().getTimezoneOffset();
+
+/**
+ * Takes a date object and a string containing an ISO 8601 date and time and
+ * sets the date object using information parsed from the string.
+ *
+ * @param {Date} dateObject the date object to modify
+ * @param {String} string an ISO 8601 string to parse
+ * @return {Date} the modified date object
+ */
+SimileAjax.DateTime.setIso8601 = function (dateObject, string){
+ /*
+ * This function has been adapted from dojo.date, v.0.3.0
+ * http://dojotoolkit.org/.
+ */
+
+ var offset = null;
+ var comps = (string.indexOf("T") == -1) ? string.split(" ") : string.split("T");
+
+ SimileAjax.DateTime.setIso8601Date(dateObject, comps[0]);
+ if (comps.length == 2) {
+ // first strip timezone info from the end
+ var d = comps[1].match(SimileAjax.DateTime._timezoneRegexp);
+ if (d) {
+ if (d[0] == 'Z') {
+ offset = 0;
+ } else {
+ offset = (Number(d[3]) * 60) + Number(d[5]);
+ offset *= ((d[2] == '-') ? 1 : -1);
+ }
+ comps[1] = comps[1].substr(0, comps[1].length - d[0].length);
+ }
+
+ SimileAjax.DateTime.setIso8601Time(dateObject, comps[1]);
+ }
+ if (offset == null) {
+ offset = dateObject.getTimezoneOffset(); // local time zone if no tz info
+ }
+ dateObject.setTime(dateObject.getTime() + offset * 60000);
+
+ return dateObject;
+};
+
+/**
+ * Takes a string containing an ISO 8601 date and returns a newly instantiated
+ * date object with the parsed date and time information from the string.
+ *
+ * @param {String} string an ISO 8601 string to parse
+ * @return {Date} a new date object created from the string
+ */
+SimileAjax.DateTime.parseIso8601DateTime = function (string) {
+ try {
+ return SimileAjax.DateTime.setIso8601(new Date(0), string);
+ } catch (e) {
+ return null;
+ }
+};
+
+/**
+ * Takes a string containing a Gregorian date and time and returns a newly
+ * instantiated date object with the parsed date and time information from the
+ * string. If the param is actually an instance of Date instead of a string,
+ * simply returns the given date instead.
+ *
+ * @param {Object} o an object, to either return or parse as a string
+ * @return {Date} the date object
+ */
+SimileAjax.DateTime.parseGregorianDateTime = function(o) {
+ if (o == null) {
+ return null;
+ } else if (o instanceof Date) {
+ return o;
+ }
+
+ var s = o.toString();
+ if (s.length > 0 && s.length < 8) {
+ var space = s.indexOf(" ");
+ if (space > 0) {
+ var year = parseInt(s.substr(0, space));
+ var suffix = s.substr(space + 1);
+ if (suffix.toLowerCase() == "bc") {
+ year = 1 - year;
+ }
+ } else {
+ var year = parseInt(s);
+ }
+
+ var d = new Date(0);
+ d.setUTCFullYear(year);
+
+ return d;
+ }
+
+ try {
+ return new Date(Date.parse(s));
+ } catch (e) {
+ return null;
+ }
+};
+
+/**
+ * Rounds date objects down to the nearest interval or multiple of an interval.
+ * This method modifies the given date object, converting it to the given
+ * timezone if specified.
+ *
+ * @param {Date} date the date object to round
+ * @param {Number} intervalUnit a constant, integer index specifying an
+ * interval, e.g. SimileAjax.DateTime.HOUR
+ * @param {Number} timeZone a timezone shift, given in hours
+ * @param {Number} multiple a multiple of the interval to round by
+ * @param {Number} firstDayOfWeek an integer specifying the first day of the
+ * week, 0 corresponds to Sunday, 1 to Monday, etc.
+ */
+SimileAjax.DateTime.roundDownToInterval = function(date, intervalUnit, timeZone, multiple, firstDayOfWeek) {
+ var timeShift = timeZone *
+ SimileAjax.DateTime.gregorianUnitLengths[SimileAjax.DateTime.HOUR];
+
+ var date2 = new Date(date.getTime() + timeShift);
+ var clearInDay = function(d) {
+ d.setUTCMilliseconds(0);
+ d.setUTCSeconds(0);
+ d.setUTCMinutes(0);
+ d.setUTCHours(0);
+ };
+ var clearInYear = function(d) {
+ clearInDay(d);
+ d.setUTCDate(1);
+ d.setUTCMonth(0);
+ };
+
+ switch(intervalUnit) {
+ case SimileAjax.DateTime.MILLISECOND:
+ var x = date2.getUTCMilliseconds();
+ date2.setUTCMilliseconds(x - (x % multiple));
+ break;
+ case SimileAjax.DateTime.SECOND:
+ date2.setUTCMilliseconds(0);
+
+ var x = date2.getUTCSeconds();
+ date2.setUTCSeconds(x - (x % multiple));
+ break;
+ case SimileAjax.DateTime.MINUTE:
+ date2.setUTCMilliseconds(0);
+ date2.setUTCSeconds(0);
+
+ var x = date2.getUTCMinutes();
+ date2.setTime(date2.getTime() -
+ (x % multiple) * SimileAjax.DateTime.gregorianUnitLengths[SimileAjax.DateTime.MINUTE]);
+ break;
+ case SimileAjax.DateTime.HOUR:
+ date2.setUTCMilliseconds(0);
+ date2.setUTCSeconds(0);
+ date2.setUTCMinutes(0);
+
+ var x = date2.getUTCHours();
+ date2.setUTCHours(x - (x % multiple));
+ break;
+ case SimileAjax.DateTime.DAY:
+ clearInDay(date2);
+ break;
+ case SimileAjax.DateTime.WEEK:
+ clearInDay(date2);
+ var d = (date2.getUTCDay() + 7 - firstDayOfWeek) % 7;
+ date2.setTime(date2.getTime() -
+ d * SimileAjax.DateTime.gregorianUnitLengths[SimileAjax.DateTime.DAY]);
+ break;
+ case SimileAjax.DateTime.MONTH:
+ clearInDay(date2);
+ date2.setUTCDate(1);
+
+ var x = date2.getUTCMonth();
+ date2.setUTCMonth(x - (x % multiple));
+ break;
+ case SimileAjax.DateTime.YEAR:
+ clearInYear(date2);
+
+ var x = date2.getUTCFullYear();
+ date2.setUTCFullYear(x - (x % multiple));
+ break;
+ case SimileAjax.DateTime.DECADE:
+ clearInYear(date2);
+ date2.setUTCFullYear(Math.floor(date2.getUTCFullYear() / 10) * 10);
+ break;
+ case SimileAjax.DateTime.CENTURY:
+ clearInYear(date2);
+ date2.setUTCFullYear(Math.floor(date2.getUTCFullYear() / 100) * 100);
+ break;
+ case SimileAjax.DateTime.MILLENNIUM:
+ clearInYear(date2);
+ date2.setUTCFullYear(Math.floor(date2.getUTCFullYear() / 1000) * 1000);
+ break;
+ }
+
+ date.setTime(date2.getTime() - timeShift);
+};
+
+/**
+ * Rounds date objects up to the nearest interval or multiple of an interval.
+ * This method modifies the given date object, converting it to the given
+ * timezone if specified.
+ *
+ * @param {Date} date the date object to round
+ * @param {Number} intervalUnit a constant, integer index specifying an
+ * interval, e.g. SimileAjax.DateTime.HOUR
+ * @param {Number} timeZone a timezone shift, given in hours
+ * @param {Number} multiple a multiple of the interval to round by
+ * @param {Number} firstDayOfWeek an integer specifying the first day of the
+ * week, 0 corresponds to Sunday, 1 to Monday, etc.
+ * @see SimileAjax.DateTime.roundDownToInterval
+ */
+SimileAjax.DateTime.roundUpToInterval = function(date, intervalUnit, timeZone, multiple, firstDayOfWeek) {
+ var originalTime = date.getTime();
+ SimileAjax.DateTime.roundDownToInterval(date, intervalUnit, timeZone, multiple, firstDayOfWeek);
+ if (date.getTime() < originalTime) {
+ date.setTime(date.getTime() +
+ SimileAjax.DateTime.gregorianUnitLengths[intervalUnit] * multiple);
+ }
+};
+
+/**
+ * Increments a date object by a specified interval, taking into
+ * consideration the timezone.
+ *
+ * @param {Date} date the date object to increment
+ * @param {Number} intervalUnit a constant, integer index specifying an
+ * interval, e.g. SimileAjax.DateTime.HOUR
+ * @param {Number} timeZone the timezone offset in hours
+ */
+SimileAjax.DateTime.incrementByInterval = function(date, intervalUnit, timeZone) {
+ timeZone = (typeof timeZone == 'undefined') ? 0 : timeZone;
+
+ var timeShift = timeZone *
+ SimileAjax.DateTime.gregorianUnitLengths[SimileAjax.DateTime.HOUR];
+
+ var date2 = new Date(date.getTime() + timeShift);
+
+ switch(intervalUnit) {
+ case SimileAjax.DateTime.MILLISECOND:
+ date2.setTime(date2.getTime() + 1)
+ break;
+ case SimileAjax.DateTime.SECOND:
+ date2.setTime(date2.getTime() + 1000);
+ break;
+ case SimileAjax.DateTime.MINUTE:
+ date2.setTime(date2.getTime() +
+ SimileAjax.DateTime.gregorianUnitLengths[SimileAjax.DateTime.MINUTE]);
+ break;
+ case SimileAjax.DateTime.HOUR:
+ date2.setTime(date2.getTime() +
+ SimileAjax.DateTime.gregorianUnitLengths[SimileAjax.DateTime.HOUR]);
+ break;
+ case SimileAjax.DateTime.DAY:
+ date2.setUTCDate(date2.getUTCDate() + 1);
+ break;
+ case SimileAjax.DateTime.WEEK:
+ date2.setUTCDate(date2.getUTCDate() + 7);
+ break;
+ case SimileAjax.DateTime.MONTH:
+ date2.setUTCMonth(date2.getUTCMonth() + 1);
+ break;
+ case SimileAjax.DateTime.YEAR:
+ date2.setUTCFullYear(date2.getUTCFullYear() + 1);
+ break;
+ case SimileAjax.DateTime.DECADE:
+ date2.setUTCFullYear(date2.getUTCFullYear() + 10);
+ break;
+ case SimileAjax.DateTime.CENTURY:
+ date2.setUTCFullYear(date2.getUTCFullYear() + 100);
+ break;
+ case SimileAjax.DateTime.MILLENNIUM:
+ date2.setUTCFullYear(date2.getUTCFullYear() + 1000);
+ break;
+ }
+
+ date.setTime(date2.getTime() - timeShift);
+};
+
+/**
+ * Returns a new date object with the given time offset removed.
+ *
+ * @param {Date} date the starting date
+ * @param {Number} timeZone a timezone specified in an hour offset to remove
+ * @return {Date} a new date object with the offset removed
+ */
+SimileAjax.DateTime.removeTimeZoneOffset = function(date, timeZone) {
+ return new Date(date.getTime() +
+ timeZone * SimileAjax.DateTime.gregorianUnitLengths[SimileAjax.DateTime.HOUR]);
+};
+
+/**
+ * Returns the timezone of the user's browser.
+ *
+ * @return {Number} the timezone in the user's locale in hours
+ */
+SimileAjax.DateTime.getTimezone = function() {
+ var d = new Date().getTimezoneOffset();
+ return d / -60;
+};
+/*==================================================
+ * String Utility Functions and Constants
+ *==================================================
+ */
+
+String.prototype.trim = function() {
+ return this.replace(/^\s+|\s+$/g, '');
+};
+
+String.prototype.startsWith = function(prefix) {
+ return this.length >= prefix.length && this.substr(0, prefix.length) == prefix;
+};
+
+String.prototype.endsWith = function(suffix) {
+ return this.length >= suffix.length && this.substr(this.length - suffix.length) == suffix;
+};
+
+String.substitute = function(s, objects) {
+ var result = "";
+ var start = 0;
+ while (start < s.length - 1) {
+ var percent = s.indexOf("%", start);
+ if (percent < 0 || percent == s.length - 1) {
+ break;
+ } else if (percent > start && s.charAt(percent - 1) == "\\") {
+ result += s.substring(start, percent - 1) + "%";
+ start = percent + 1;
+ } else {
+ var n = parseInt(s.charAt(percent + 1));
+ if (isNaN(n) || n >= objects.length) {
+ result += s.substring(start, percent + 2);
+ } else {
+ result += s.substring(start, percent) + objects[n].toString();
+ }
+ start = percent + 2;
+ }
+ }
+
+ if (start < s.length) {
+ result += s.substring(start);
+ }
+ return result;
+};
+/*==================================================
+ * HTML Utility Functions
+ *==================================================
+ */
+
+SimileAjax.HTML = new Object();
+
+SimileAjax.HTML._e2uHash = {};
+(function() {
+ var e2uHash = SimileAjax.HTML._e2uHash;
+ e2uHash['nbsp']= '\u00A0[space]';
+ e2uHash['iexcl']= '\u00A1';
+ e2uHash['cent']= '\u00A2';
+ e2uHash['pound']= '\u00A3';
+ e2uHash['curren']= '\u00A4';
+ e2uHash['yen']= '\u00A5';
+ e2uHash['brvbar']= '\u00A6';
+ e2uHash['sect']= '\u00A7';
+ e2uHash['uml']= '\u00A8';
+ e2uHash['copy']= '\u00A9';
+ e2uHash['ordf']= '\u00AA';
+ e2uHash['laquo']= '\u00AB';
+ e2uHash['not']= '\u00AC';
+ e2uHash['shy']= '\u00AD';
+ e2uHash['reg']= '\u00AE';
+ e2uHash['macr']= '\u00AF';
+ e2uHash['deg']= '\u00B0';
+ e2uHash['plusmn']= '\u00B1';
+ e2uHash['sup2']= '\u00B2';
+ e2uHash['sup3']= '\u00B3';
+ e2uHash['acute']= '\u00B4';
+ e2uHash['micro']= '\u00B5';
+ e2uHash['para']= '\u00B6';
+ e2uHash['middot']= '\u00B7';
+ e2uHash['cedil']= '\u00B8';
+ e2uHash['sup1']= '\u00B9';
+ e2uHash['ordm']= '\u00BA';
+ e2uHash['raquo']= '\u00BB';
+ e2uHash['frac14']= '\u00BC';
+ e2uHash['frac12']= '\u00BD';
+ e2uHash['frac34']= '\u00BE';
+ e2uHash['iquest']= '\u00BF';
+ e2uHash['Agrave']= '\u00C0';
+ e2uHash['Aacute']= '\u00C1';
+ e2uHash['Acirc']= '\u00C2';
+ e2uHash['Atilde']= '\u00C3';
+ e2uHash['Auml']= '\u00C4';
+ e2uHash['Aring']= '\u00C5';
+ e2uHash['AElig']= '\u00C6';
+ e2uHash['Ccedil']= '\u00C7';
+ e2uHash['Egrave']= '\u00C8';
+ e2uHash['Eacute']= '\u00C9';
+ e2uHash['Ecirc']= '\u00CA';
+ e2uHash['Euml']= '\u00CB';
+ e2uHash['Igrave']= '\u00CC';
+ e2uHash['Iacute']= '\u00CD';
+ e2uHash['Icirc']= '\u00CE';
+ e2uHash['Iuml']= '\u00CF';
+ e2uHash['ETH']= '\u00D0';
+ e2uHash['Ntilde']= '\u00D1';
+ e2uHash['Ograve']= '\u00D2';
+ e2uHash['Oacute']= '\u00D3';
+ e2uHash['Ocirc']= '\u00D4';
+ e2uHash['Otilde']= '\u00D5';
+ e2uHash['Ouml']= '\u00D6';
+ e2uHash['times']= '\u00D7';
+ e2uHash['Oslash']= '\u00D8';
+ e2uHash['Ugrave']= '\u00D9';
+ e2uHash['Uacute']= '\u00DA';
+ e2uHash['Ucirc']= '\u00DB';
+ e2uHash['Uuml']= '\u00DC';
+ e2uHash['Yacute']= '\u00DD';
+ e2uHash['THORN']= '\u00DE';
+ e2uHash['szlig']= '\u00DF';
+ e2uHash['agrave']= '\u00E0';
+ e2uHash['aacute']= '\u00E1';
+ e2uHash['acirc']= '\u00E2';
+ e2uHash['atilde']= '\u00E3';
+ e2uHash['auml']= '\u00E4';
+ e2uHash['aring']= '\u00E5';
+ e2uHash['aelig']= '\u00E6';
+ e2uHash['ccedil']= '\u00E7';
+ e2uHash['egrave']= '\u00E8';
+ e2uHash['eacute']= '\u00E9';
+ e2uHash['ecirc']= '\u00EA';
+ e2uHash['euml']= '\u00EB';
+ e2uHash['igrave']= '\u00EC';
+ e2uHash['iacute']= '\u00ED';
+ e2uHash['icirc']= '\u00EE';
+ e2uHash['iuml']= '\u00EF';
+ e2uHash['eth']= '\u00F0';
+ e2uHash['ntilde']= '\u00F1';
+ e2uHash['ograve']= '\u00F2';
+ e2uHash['oacute']= '\u00F3';
+ e2uHash['ocirc']= '\u00F4';
+ e2uHash['otilde']= '\u00F5';
+ e2uHash['ouml']= '\u00F6';
+ e2uHash['divide']= '\u00F7';
+ e2uHash['oslash']= '\u00F8';
+ e2uHash['ugrave']= '\u00F9';
+ e2uHash['uacute']= '\u00FA';
+ e2uHash['ucirc']= '\u00FB';
+ e2uHash['uuml']= '\u00FC';
+ e2uHash['yacute']= '\u00FD';
+ e2uHash['thorn']= '\u00FE';
+ e2uHash['yuml']= '\u00FF';
+ e2uHash['quot']= '\u0022';
+ e2uHash['amp']= '\u0026';
+ e2uHash['lt']= '\u003C';
+ e2uHash['gt']= '\u003E';
+ e2uHash['OElig']= '';
+ e2uHash['oelig']= '\u0153';
+ e2uHash['Scaron']= '\u0160';
+ e2uHash['scaron']= '\u0161';
+ e2uHash['Yuml']= '\u0178';
+ e2uHash['circ']= '\u02C6';
+ e2uHash['tilde']= '\u02DC';
+ e2uHash['ensp']= '\u2002';
+ e2uHash['emsp']= '\u2003';
+ e2uHash['thinsp']= '\u2009';
+ e2uHash['zwnj']= '\u200C';
+ e2uHash['zwj']= '\u200D';
+ e2uHash['lrm']= '\u200E';
+ e2uHash['rlm']= '\u200F';
+ e2uHash['ndash']= '\u2013';
+ e2uHash['mdash']= '\u2014';
+ e2uHash['lsquo']= '\u2018';
+ e2uHash['rsquo']= '\u2019';
+ e2uHash['sbquo']= '\u201A';
+ e2uHash['ldquo']= '\u201C';
+ e2uHash['rdquo']= '\u201D';
+ e2uHash['bdquo']= '\u201E';
+ e2uHash['dagger']= '\u2020';
+ e2uHash['Dagger']= '\u2021';
+ e2uHash['permil']= '\u2030';
+ e2uHash['lsaquo']= '\u2039';
+ e2uHash['rsaquo']= '\u203A';
+ e2uHash['euro']= '\u20AC';
+ e2uHash['fnof']= '\u0192';
+ e2uHash['Alpha']= '\u0391';
+ e2uHash['Beta']= '\u0392';
+ e2uHash['Gamma']= '\u0393';
+ e2uHash['Delta']= '\u0394';
+ e2uHash['Epsilon']= '\u0395';
+ e2uHash['Zeta']= '\u0396';
+ e2uHash['Eta']= '\u0397';
+ e2uHash['Theta']= '\u0398';
+ e2uHash['Iota']= '\u0399';
+ e2uHash['Kappa']= '\u039A';
+ e2uHash['Lambda']= '\u039B';
+ e2uHash['Mu']= '\u039C';
+ e2uHash['Nu']= '\u039D';
+ e2uHash['Xi']= '\u039E';
+ e2uHash['Omicron']= '\u039F';
+ e2uHash['Pi']= '\u03A0';
+ e2uHash['Rho']= '\u03A1';
+ e2uHash['Sigma']= '\u03A3';
+ e2uHash['Tau']= '\u03A4';
+ e2uHash['Upsilon']= '\u03A5';
+ e2uHash['Phi']= '\u03A6';
+ e2uHash['Chi']= '\u03A7';
+ e2uHash['Psi']= '\u03A8';
+ e2uHash['Omega']= '\u03A9';
+ e2uHash['alpha']= '\u03B1';
+ e2uHash['beta']= '\u03B2';
+ e2uHash['gamma']= '\u03B3';
+ e2uHash['delta']= '\u03B4';
+ e2uHash['epsilon']= '\u03B5';
+ e2uHash['zeta']= '\u03B6';
+ e2uHash['eta']= '\u03B7';
+ e2uHash['theta']= '\u03B8';
+ e2uHash['iota']= '\u03B9';
+ e2uHash['kappa']= '\u03BA';
+ e2uHash['lambda']= '\u03BB';
+ e2uHash['mu']= '\u03BC';
+ e2uHash['nu']= '\u03BD';
+ e2uHash['xi']= '\u03BE';
+ e2uHash['omicron']= '\u03BF';
+ e2uHash['pi']= '\u03C0';
+ e2uHash['rho']= '\u03C1';
+ e2uHash['sigmaf']= '\u03C2';
+ e2uHash['sigma']= '\u03C3';
+ e2uHash['tau']= '\u03C4';
+ e2uHash['upsilon']= '\u03C5';
+ e2uHash['phi']= '\u03C6';
+ e2uHash['chi']= '\u03C7';
+ e2uHash['psi']= '\u03C8';
+ e2uHash['omega']= '\u03C9';
+ e2uHash['thetasym']= '\u03D1';
+ e2uHash['upsih']= '\u03D2';
+ e2uHash['piv']= '\u03D6';
+ e2uHash['bull']= '\u2022';
+ e2uHash['hellip']= '\u2026';
+ e2uHash['prime']= '\u2032';
+ e2uHash['Prime']= '\u2033';
+ e2uHash['oline']= '\u203E';
+ e2uHash['frasl']= '\u2044';
+ e2uHash['weierp']= '\u2118';
+ e2uHash['image']= '\u2111';
+ e2uHash['real']= '\u211C';
+ e2uHash['trade']= '\u2122';
+ e2uHash['alefsym']= '\u2135';
+ e2uHash['larr']= '\u2190';
+ e2uHash['uarr']= '\u2191';
+ e2uHash['rarr']= '\u2192';
+ e2uHash['darr']= '\u2193';
+ e2uHash['harr']= '\u2194';
+ e2uHash['crarr']= '\u21B5';
+ e2uHash['lArr']= '\u21D0';
+ e2uHash['uArr']= '\u21D1';
+ e2uHash['rArr']= '\u21D2';
+ e2uHash['dArr']= '\u21D3';
+ e2uHash['hArr']= '\u21D4';
+ e2uHash['forall']= '\u2200';
+ e2uHash['part']= '\u2202';
+ e2uHash['exist']= '\u2203';
+ e2uHash['empty']= '\u2205';
+ e2uHash['nabla']= '\u2207';
+ e2uHash['isin']= '\u2208';
+ e2uHash['notin']= '\u2209';
+ e2uHash['ni']= '\u220B';
+ e2uHash['prod']= '\u220F';
+ e2uHash['sum']= '\u2211';
+ e2uHash['minus']= '\u2212';
+ e2uHash['lowast']= '\u2217';
+ e2uHash['radic']= '\u221A';
+ e2uHash['prop']= '\u221D';
+ e2uHash['infin']= '\u221E';
+ e2uHash['ang']= '\u2220';
+ e2uHash['and']= '\u2227';
+ e2uHash['or']= '\u2228';
+ e2uHash['cap']= '\u2229';
+ e2uHash['cup']= '\u222A';
+ e2uHash['int']= '\u222B';
+ e2uHash['there4']= '\u2234';
+ e2uHash['sim']= '\u223C';
+ e2uHash['cong']= '\u2245';
+ e2uHash['asymp']= '\u2248';
+ e2uHash['ne']= '\u2260';
+ e2uHash['equiv']= '\u2261';
+ e2uHash['le']= '\u2264';
+ e2uHash['ge']= '\u2265';
+ e2uHash['sub']= '\u2282';
+ e2uHash['sup']= '\u2283';
+ e2uHash['nsub']= '\u2284';
+ e2uHash['sube']= '\u2286';
+ e2uHash['supe']= '\u2287';
+ e2uHash['oplus']= '\u2295';
+ e2uHash['otimes']= '\u2297';
+ e2uHash['perp']= '\u22A5';
+ e2uHash['sdot']= '\u22C5';
+ e2uHash['lceil']= '\u2308';
+ e2uHash['rceil']= '\u2309';
+ e2uHash['lfloor']= '\u230A';
+ e2uHash['rfloor']= '\u230B';
+ e2uHash['lang']= '\u2329';
+ e2uHash['rang']= '\u232A';
+ e2uHash['loz']= '\u25CA';
+ e2uHash['spades']= '\u2660';
+ e2uHash['clubs']= '\u2663';
+ e2uHash['hearts']= '\u2665';
+ e2uHash['diams']= '\u2666';
+})();
+
+SimileAjax.HTML.deEntify = function(s) {
+ var e2uHash = SimileAjax.HTML._e2uHash;
+
+ var re = /&(\w+?);/;
+ while (re.test(s)) {
+ var m = s.match(re);
+ s = s.replace(re, e2uHash[m[1]]);
+ }
+ return s;
+};/**
+ * A basic set (in the mathematical sense) data structure
+ *
+ * @constructor
+ * @param {Array or SimileAjax.Set} [a] an initial collection
+ */
+SimileAjax.Set = function(a) {
+ this._hash = {};
+ this._count = 0;
+
+ if (a instanceof Array) {
+ for (var i = 0; i < a.length; i++) {
+ this.add(a[i]);
+ }
+ } else if (a instanceof SimileAjax.Set) {
+ this.addSet(a);
+ }
+}
+
+/**
+ * Adds the given object to this set, assuming there it does not already exist
+ *
+ * @param {Object} o the object to add
+ * @return {Boolean} true if the object was added, false if not
+ */
+SimileAjax.Set.prototype.add = function(o) {
+ if (!(o in this._hash)) {
+ this._hash[o] = true;
+ this._count++;
+ return true;
+ }
+ return false;
+}
+
+/**
+ * Adds each element in the given set to this set
+ *
+ * @param {SimileAjax.Set} set the set of elements to add
+ */
+SimileAjax.Set.prototype.addSet = function(set) {
+ for (var o in set._hash) {
+ this.add(o);
+ }
+}
+
+/**
+ * Removes the given element from this set
+ *
+ * @param {Object} o the object to remove
+ * @return {Boolean} true if the object was successfully removed,
+ * false otherwise
+ */
+SimileAjax.Set.prototype.remove = function(o) {
+ if (o in this._hash) {
+ delete this._hash[o];
+ this._count--;
+ return true;
+ }
+ return false;
+}
+
+/**
+ * Removes the elements in this set that correspond to the elements in the
+ * given set
+ *
+ * @param {SimileAjax.Set} set the set of elements to remove
+ */
+SimileAjax.Set.prototype.removeSet = function(set) {
+ for (var o in set._hash) {
+ this.remove(o);
+ }
+}
+
+/**
+ * Removes all elements in this set that are not present in the given set, i.e.
+ * modifies this set to the intersection of the two sets
+ *
+ * @param {SimileAjax.Set} set the set to intersect
+ */
+SimileAjax.Set.prototype.retainSet = function(set) {
+ for (var o in this._hash) {
+ if (!set.contains(o)) {
+ delete this._hash[o];
+ this._count--;
+ }
+ }
+}
+
+/**
+ * Returns whether or not the given element exists in this set
+ *
+ * @param {SimileAjax.Set} o the object to test for
+ * @return {Boolean} true if the object is present, false otherwise
+ */
+SimileAjax.Set.prototype.contains = function(o) {
+ return (o in this._hash);
+}
+
+/**
+ * Returns the number of elements in this set
+ *
+ * @return {Number} the number of elements in this set
+ */
+SimileAjax.Set.prototype.size = function() {
+ return this._count;
+}
+
+/**
+ * Returns the elements of this set as an array
+ *
+ * @return {Array} a new array containing the elements of this set
+ */
+SimileAjax.Set.prototype.toArray = function() {
+ var a = [];
+ for (var o in this._hash) {
+ a.push(o);
+ }
+ return a;
+}
+
+/**
+ * Iterates through the elements of this set, order unspecified, executing the
+ * given function on each element until the function returns true
+ *
+ * @param {Function} f a function of form f(element)
+ */
+SimileAjax.Set.prototype.visit = function(f) {
+ for (var o in this._hash) {
+ if (f(o) == true) {
+ break;
+ }
+ }
+}
+
+/**
+ * A sorted array data structure
+ *
+ * @constructor
+ */
+SimileAjax.SortedArray = function(compare, initialArray) {
+ this._a = (initialArray instanceof Array) ? initialArray : [];
+ this._compare = compare;
+};
+
+SimileAjax.SortedArray.prototype.add = function(elmt) {
+ var sa = this;
+ var index = this.find(function(elmt2) {
+ return sa._compare(elmt2, elmt);
+ });
+
+ if (index < this._a.length) {
+ this._a.splice(index, 0, elmt);
+ } else {
+ this._a.push(elmt);
+ }
+};
+
+SimileAjax.SortedArray.prototype.remove = function(elmt) {
+ var sa = this;
+ var index = this.find(function(elmt2) {
+ return sa._compare(elmt2, elmt);
+ });
+
+ while (index < this._a.length && this._compare(this._a[index], elmt) == 0) {
+ if (this._a[index] == elmt) {
+ this._a.splice(index, 1);
+ return true;
+ } else {
+ index++;
+ }
+ }
+ return false;
+};
+
+SimileAjax.SortedArray.prototype.removeAll = function() {
+ this._a = [];
+};
+
+SimileAjax.SortedArray.prototype.elementAt = function(index) {
+ return this._a[index];
+};
+
+SimileAjax.SortedArray.prototype.length = function() {
+ return this._a.length;
+};
+
+SimileAjax.SortedArray.prototype.find = function(compare) {
+ var a = 0;
+ var b = this._a.length;
+
+ while (a < b) {
+ var mid = Math.floor((a + b) / 2);
+ var c = compare(this._a[mid]);
+ if (mid == a) {
+ return c < 0 ? a+1 : a;
+ } else if (c < 0) {
+ a = mid;
+ } else {
+ b = mid;
+ }
+ }
+ return a;
+};
+
+SimileAjax.SortedArray.prototype.getFirst = function() {
+ return (this._a.length > 0) ? this._a[0] : null;
+};
+
+SimileAjax.SortedArray.prototype.getLast = function() {
+ return (this._a.length > 0) ? this._a[this._a.length - 1] : null;
+};
+
+/*==================================================
+ * Event Index
+ *==================================================
+ */
+
+SimileAjax.EventIndex = function(unit) {
+ var eventIndex = this;
+
+ this._unit = (unit != null) ? unit : SimileAjax.NativeDateUnit;
+ this._events = new SimileAjax.SortedArray(
+ function(event1, event2) {
+ return eventIndex._unit.compare(event1.getStart(), event2.getStart());
+ }
+ );
+ this._idToEvent = {};
+ this._indexed = true;
+};
+
+SimileAjax.EventIndex.prototype.getUnit = function() {
+ return this._unit;
+};
+
+SimileAjax.EventIndex.prototype.getEvent = function(id) {
+ return this._idToEvent[id];
+};
+
+SimileAjax.EventIndex.prototype.add = function(evt) {
+ this._events.add(evt);
+ this._idToEvent[evt.getID()] = evt;
+ this._indexed = false;
+};
+
+SimileAjax.EventIndex.prototype.removeAll = function() {
+ this._events.removeAll();
+ this._idToEvent = {};
+ this._indexed = false;
+};
+
+SimileAjax.EventIndex.prototype.getCount = function() {
+ return this._events.length();
+};
+
+SimileAjax.EventIndex.prototype.getIterator = function(startDate, endDate) {
+ if (!this._indexed) {
+ this._index();
+ }
+ return new SimileAjax.EventIndex._Iterator(this._events, startDate, endDate, this._unit);
+};
+
+SimileAjax.EventIndex.prototype.getReverseIterator = function(startDate, endDate) {
+ if (!this._indexed) {
+ this._index();
+ }
+ return new SimileAjax.EventIndex._ReverseIterator(this._events, startDate, endDate, this._unit);
+};
+
+SimileAjax.EventIndex.prototype.getAllIterator = function() {
+ return new SimileAjax.EventIndex._AllIterator(this._events);
+};
+
+SimileAjax.EventIndex.prototype.getEarliestDate = function() {
+ var evt = this._events.getFirst();
+ return (evt == null) ? null : evt.getStart();
+};
+
+SimileAjax.EventIndex.prototype.getLatestDate = function() {
+ var evt = this._events.getLast();
+ if (evt == null) {
+ return null;
+ }
+
+ if (!this._indexed) {
+ this._index();
+ }
+
+ var index = evt._earliestOverlapIndex;
+ var date = this._events.elementAt(index).getEnd();
+ for (var i = index + 1; i < this._events.length(); i++) {
+ date = this._unit.later(date, this._events.elementAt(i).getEnd());
+ }
+
+ return date;
+};
+
+SimileAjax.EventIndex.prototype._index = function() {
+ /*
+ * For each event, we want to find the earliest preceding
+ * event that overlaps with it, if any.
+ */
+
+ var l = this._events.length();
+ for (var i = 0; i < l; i++) {
+ var evt = this._events.elementAt(i);
+ evt._earliestOverlapIndex = i;
+ }
+
+ var toIndex = 1;
+ for (var i = 0; i < l; i++) {
+ var evt = this._events.elementAt(i);
+ var end = evt.getEnd();
+
+ toIndex = Math.max(toIndex, i + 1);
+ while (toIndex < l) {
+ var evt2 = this._events.elementAt(toIndex);
+ var start2 = evt2.getStart();
+
+ if (this._unit.compare(start2, end) < 0) {
+ evt2._earliestOverlapIndex = i;
+ toIndex++;
+ } else {
+ break;
+ }
+ }
+ }
+ this._indexed = true;
+};
+
+SimileAjax.EventIndex._Iterator = function(events, startDate, endDate, unit) {
+ this._events = events;
+ this._startDate = startDate;
+ this._endDate = endDate;
+ this._unit = unit;
+
+ this._currentIndex = events.find(function(evt) {
+ return unit.compare(evt.getStart(), startDate);
+ });
+ if (this._currentIndex - 1 >= 0) {
+ this._currentIndex = this._events.elementAt(this._currentIndex - 1)._earliestOverlapIndex;
+ }
+ this._currentIndex--;
+
+ this._maxIndex = events.find(function(evt) {
+ return unit.compare(evt.getStart(), endDate);
+ });
+
+ this._hasNext = false;
+ this._next = null;
+ this._findNext();
+};
+
+SimileAjax.EventIndex._Iterator.prototype = {
+ hasNext: function() { return this._hasNext; },
+ next: function() {
+ if (this._hasNext) {
+ var next = this._next;
+ this._findNext();
+
+ return next;
+ } else {
+ return null;
+ }
+ },
+ _findNext: function() {
+ var unit = this._unit;
+ while ((++this._currentIndex) < this._maxIndex) {
+ var evt = this._events.elementAt(this._currentIndex);
+ if (unit.compare(evt.getStart(), this._endDate) < 0 &&
+ unit.compare(evt.getEnd(), this._startDate) > 0) {
+
+ this._next = evt;
+ this._hasNext = true;
+ return;
+ }
+ }
+ this._next = null;
+ this._hasNext = false;
+ }
+};
+
+SimileAjax.EventIndex._ReverseIterator = function(events, startDate, endDate, unit) {
+ this._events = events;
+ this._startDate = startDate;
+ this._endDate = endDate;
+ this._unit = unit;
+
+ this._minIndex = events.find(function(evt) {
+ return unit.compare(evt.getStart(), startDate);
+ });
+ if (this._minIndex - 1 >= 0) {
+ this._minIndex = this._events.elementAt(this._minIndex - 1)._earliestOverlapIndex;
+ }
+
+ this._maxIndex = events.find(function(evt) {
+ return unit.compare(evt.getStart(), endDate);
+ });
+
+ this._currentIndex = this._maxIndex;
+ this._hasNext = false;
+ this._next = null;
+ this._findNext();
+};
+
+SimileAjax.EventIndex._ReverseIterator.prototype = {
+ hasNext: function() { return this._hasNext; },
+ next: function() {
+ if (this._hasNext) {
+ var next = this._next;
+ this._findNext();
+
+ return next;
+ } else {
+ return null;
+ }
+ },
+ _findNext: function() {
+ var unit = this._unit;
+ while ((--this._currentIndex) >= this._minIndex) {
+ var evt = this._events.elementAt(this._currentIndex);
+ if (unit.compare(evt.getStart(), this._endDate) < 0 &&
+ unit.compare(evt.getEnd(), this._startDate) > 0) {
+
+ this._next = evt;
+ this._hasNext = true;
+ return;
+ }
+ }
+ this._next = null;
+ this._hasNext = false;
+ }
+};
+
+SimileAjax.EventIndex._AllIterator = function(events) {
+ this._events = events;
+ this._index = 0;
+};
+
+SimileAjax.EventIndex._AllIterator.prototype = {
+ hasNext: function() {
+ return this._index < this._events.length();
+ },
+ next: function() {
+ return this._index < this._events.length() ?
+ this._events.elementAt(this._index++) : null;
+ }
+};/*==================================================
+ * Default Unit
+ *==================================================
+ */
+
+SimileAjax.NativeDateUnit = new Object();
+
+SimileAjax.NativeDateUnit.makeDefaultValue = function() {
+ return new Date();
+};
+
+SimileAjax.NativeDateUnit.cloneValue = function(v) {
+ return new Date(v.getTime());
+};
+
+SimileAjax.NativeDateUnit.getParser = function(format) {
+ if (typeof format == "string") {
+ format = format.toLowerCase();
+ }
+ return (format == "iso8601" || format == "iso 8601") ?
+ SimileAjax.DateTime.parseIso8601DateTime :
+ SimileAjax.DateTime.parseGregorianDateTime;
+};
+
+SimileAjax.NativeDateUnit.parseFromObject = function(o) {
+ return SimileAjax.DateTime.parseGregorianDateTime(o);
+};
+
+SimileAjax.NativeDateUnit.toNumber = function(v) {
+ return v.getTime();
+};
+
+SimileAjax.NativeDateUnit.fromNumber = function(n) {
+ return new Date(n);
+};
+
+SimileAjax.NativeDateUnit.compare = function(v1, v2) {
+ var n1, n2;
+ if (typeof v1 == "object") {
+ n1 = v1.getTime();
+ } else {
+ n1 = Number(v1);
+ }
+ if (typeof v2 == "object") {
+ n2 = v2.getTime();
+ } else {
+ n2 = Number(v2);
+ }
+
+ return n1 - n2;
+};
+
+SimileAjax.NativeDateUnit.earlier = function(v1, v2) {
+ return SimileAjax.NativeDateUnit.compare(v1, v2) < 0 ? v1 : v2;
+};
+
+SimileAjax.NativeDateUnit.later = function(v1, v2) {
+ return SimileAjax.NativeDateUnit.compare(v1, v2) > 0 ? v1 : v2;
+};
+
+SimileAjax.NativeDateUnit.change = function(v, n) {
+ return new Date(v.getTime() + n);
+};
+
+/*==================================================
+ * General, miscellaneous SimileAjax stuff
+ *==================================================
+ */
+
+SimileAjax.ListenerQueue = function(wildcardHandlerName) {
+ this._listeners = [];
+ this._wildcardHandlerName = wildcardHandlerName;
+};
+
+SimileAjax.ListenerQueue.prototype.add = function(listener) {
+ this._listeners.push(listener);
+};
+
+SimileAjax.ListenerQueue.prototype.remove = function(listener) {
+ var listeners = this._listeners;
+ for (var i = 0; i < listeners.length; i++) {
+ if (listeners[i] == listener) {
+ listeners.splice(i, 1);
+ break;
+ }
+ }
+};
+
+SimileAjax.ListenerQueue.prototype.fire = function(handlerName, args) {
+ var listeners = [].concat(this._listeners);
+ for (var i = 0; i < listeners.length; i++) {
+ var listener = listeners[i];
+ if (handlerName in listener) {
+ try {
+ listener[handlerName].apply(listener, args);
+ } catch (e) {
+ SimileAjax.Debug.exception("Error firing event of name " + handlerName, e);
+ }
+ } else if (this._wildcardHandlerName != null &&
+ this._wildcardHandlerName in listener) {
+ try {
+ listener[this._wildcardHandlerName].apply(listener, [ handlerName ]);
+ } catch (e) {
+ SimileAjax.Debug.exception("Error firing event of name " + handlerName + " to wildcard handler", e);
+ }
+ }
+ }
+};
+
+/**
+ * @fileOverview UI layers and window-wide dragging
+ * @name SimileAjax.WindowManager
+ */
+
+/**
+ * This is a singleton that keeps track of UI layers (modal and
+ * modeless) and enables/disables UI elements based on which layers
+ * they belong to. It also provides window-wide dragging
+ * implementation.
+ */
+SimileAjax.WindowManager = {
+ _initialized: false,
+ _listeners: [],
+
+ _draggedElement: null,
+ _draggedElementCallback: null,
+ _dropTargetHighlightElement: null,
+ _lastCoords: null,
+ _ghostCoords: null,
+ _draggingMode: "",
+ _dragging: false,
+
+ _layers: []
+};
+
+SimileAjax.WindowManager.initialize = function() {
+ if (SimileAjax.WindowManager._initialized) {
+ return;
+ }
+
+ SimileAjax.DOM.registerEvent(document.body, "mousedown", SimileAjax.WindowManager._onBodyMouseDown);
+ SimileAjax.DOM.registerEvent(document.body, "mousemove", SimileAjax.WindowManager._onBodyMouseMove);
+ SimileAjax.DOM.registerEvent(document.body, "mouseup", SimileAjax.WindowManager._onBodyMouseUp);
+ SimileAjax.DOM.registerEvent(document, "keydown", SimileAjax.WindowManager._onBodyKeyDown);
+ SimileAjax.DOM.registerEvent(document, "keyup", SimileAjax.WindowManager._onBodyKeyUp);
+
+ SimileAjax.WindowManager._layers.push({index: 0});
+
+ SimileAjax.WindowManager._historyListener = {
+ onBeforeUndoSeveral: function() {},
+ onAfterUndoSeveral: function() {},
+ onBeforeUndo: function() {},
+ onAfterUndo: function() {},
+
+ onBeforeRedoSeveral: function() {},
+ onAfterRedoSeveral: function() {},
+ onBeforeRedo: function() {},
+ onAfterRedo: function() {}
+ };
+ //SimileAjax.History.addListener(SimileAjax.WindowManager._historyListener);
+
+ SimileAjax.WindowManager._initialized = true;
+};
+
+SimileAjax.WindowManager.getBaseLayer = function() {
+ SimileAjax.WindowManager.initialize();
+ return SimileAjax.WindowManager._layers[0];
+};
+
+SimileAjax.WindowManager.getHighestLayer = function() {
+ SimileAjax.WindowManager.initialize();
+ return SimileAjax.WindowManager._layers[SimileAjax.WindowManager._layers.length - 1];
+};
+
+SimileAjax.WindowManager.registerEventWithObject = function(elmt, eventName, obj, handlerName, layer) {
+ SimileAjax.WindowManager.registerEvent(
+ elmt,
+ eventName,
+ function(elmt2, evt, target) {
+ return obj[handlerName].call(obj, elmt2, evt, target);
+ },
+ layer
+ );
+};
+
+SimileAjax.WindowManager.registerEvent = function(elmt, eventName, handler, layer) {
+ if (layer == null) {
+ layer = SimileAjax.WindowManager.getHighestLayer();
+ }
+
+ var handler2 = function(elmt, evt, target) {
+ if (SimileAjax.WindowManager._canProcessEventAtLayer(layer)) {
+ SimileAjax.WindowManager._popToLayer(layer.index);
+ try {
+ handler(elmt, evt, target);
+ } catch (e) {
+ SimileAjax.Debug.exception(e);
+ }
+ }
+ SimileAjax.DOM.cancelEvent(evt);
+ return false;
+ }
+
+ SimileAjax.DOM.registerEvent(elmt, eventName, handler2);
+};
+
+SimileAjax.WindowManager.pushLayer = function(f, ephemeral, elmt) {
+ var layer = { onPop: f, index: SimileAjax.WindowManager._layers.length, ephemeral: (ephemeral), elmt: elmt };
+ SimileAjax.WindowManager._layers.push(layer);
+
+ return layer;
+};
+
+SimileAjax.WindowManager.popLayer = function(layer) {
+ for (var i = 1; i < SimileAjax.WindowManager._layers.length; i++) {
+ if (SimileAjax.WindowManager._layers[i] == layer) {
+ SimileAjax.WindowManager._popToLayer(i - 1);
+ break;
+ }
+ }
+};
+
+SimileAjax.WindowManager.popAllLayers = function() {
+ SimileAjax.WindowManager._popToLayer(0);
+};
+
+SimileAjax.WindowManager.registerForDragging = function(elmt, callback, layer) {
+ SimileAjax.WindowManager.registerEvent(
+ elmt,
+ "mousedown",
+ function(elmt, evt, target) {
+ SimileAjax.WindowManager._handleMouseDown(elmt, evt, callback);
+ },
+ layer
+ );
+};
+
+SimileAjax.WindowManager._popToLayer = function(level) {
+ while (level+1 < SimileAjax.WindowManager._layers.length) {
+ try {
+ var layer = SimileAjax.WindowManager._layers.pop();
+ if (layer.onPop != null) {
+ layer.onPop();
+ }
+ } catch (e) {
+ }
+ }
+};
+
+SimileAjax.WindowManager._canProcessEventAtLayer = function(layer) {
+ if (layer.index == (SimileAjax.WindowManager._layers.length - 1)) {
+ return true;
+ }
+ for (var i = layer.index + 1; i < SimileAjax.WindowManager._layers.length; i++) {
+ if (!SimileAjax.WindowManager._layers[i].ephemeral) {
+ return false;
+ }
+ }
+ return true;
+};
+
+SimileAjax.WindowManager.cancelPopups = function(evt) {
+ var evtCoords = (evt) ? SimileAjax.DOM.getEventPageCoordinates(evt) : { x: -1, y: -1 };
+
+ var i = SimileAjax.WindowManager._layers.length - 1;
+ while (i > 0 && SimileAjax.WindowManager._layers[i].ephemeral) {
+ var layer = SimileAjax.WindowManager._layers[i];
+ if (layer.elmt != null) { // if event falls within main element of layer then don't cancel
+ var elmt = layer.elmt;
+ var elmtCoords = SimileAjax.DOM.getPageCoordinates(elmt);
+ if (evtCoords.x >= elmtCoords.left && evtCoords.x < (elmtCoords.left + elmt.offsetWidth) &&
+ evtCoords.y >= elmtCoords.top && evtCoords.y < (elmtCoords.top + elmt.offsetHeight)) {
+ break;
+ }
+ }
+ i--;
+ }
+ SimileAjax.WindowManager._popToLayer(i);
+};
+
+SimileAjax.WindowManager._onBodyMouseDown = function(elmt, evt, target) {
+ if (!("eventPhase" in evt) || evt.eventPhase == evt.BUBBLING_PHASE) {
+ SimileAjax.WindowManager.cancelPopups(evt);
+ }
+};
+
+SimileAjax.WindowManager._handleMouseDown = function(elmt, evt, callback) {
+ SimileAjax.WindowManager._draggedElement = elmt;
+ SimileAjax.WindowManager._draggedElementCallback = callback;
+ SimileAjax.WindowManager._lastCoords = { x: evt.clientX, y: evt.clientY };
+
+ SimileAjax.DOM.cancelEvent(evt);
+ return false;
+};
+
+SimileAjax.WindowManager._onBodyKeyDown = function(elmt, evt, target) {
+ if (SimileAjax.WindowManager._dragging) {
+ if (evt.keyCode == 27) { // esc
+ SimileAjax.WindowManager._cancelDragging();
+ } else if ((evt.keyCode == 17 || evt.keyCode == 16) && SimileAjax.WindowManager._draggingMode != "copy") {
+ SimileAjax.WindowManager._draggingMode = "copy";
+
+ var img = SimileAjax.Graphics.createTranslucentImage(SimileAjax.urlPrefix + "images/copy.png");
+ img.style.position = "absolute";
+ img.style.left = (SimileAjax.WindowManager._ghostCoords.left - 16) + "px";
+ img.style.top = (SimileAjax.WindowManager._ghostCoords.top) + "px";
+ document.body.appendChild(img);
+
+ SimileAjax.WindowManager._draggingModeIndicatorElmt = img;
+ }
+ }
+};
+
+SimileAjax.WindowManager._onBodyKeyUp = function(elmt, evt, target) {
+ if (SimileAjax.WindowManager._dragging) {
+ if (evt.keyCode == 17 || evt.keyCode == 16) {
+ SimileAjax.WindowManager._draggingMode = "";
+ if (SimileAjax.WindowManager._draggingModeIndicatorElmt != null) {
+ document.body.removeChild(SimileAjax.WindowManager._draggingModeIndicatorElmt);
+ SimileAjax.WindowManager._draggingModeIndicatorElmt = null;
+ }
+ }
+ }
+};
+
+SimileAjax.WindowManager._onBodyMouseMove = function(elmt, evt, target) {
+ if (SimileAjax.WindowManager._draggedElement != null) {
+ var callback = SimileAjax.WindowManager._draggedElementCallback;
+
+ var lastCoords = SimileAjax.WindowManager._lastCoords;
+ var diffX = evt.clientX - lastCoords.x;
+ var diffY = evt.clientY - lastCoords.y;
+
+ if (!SimileAjax.WindowManager._dragging) {
+ if (Math.abs(diffX) > 5 || Math.abs(diffY) > 5) {
+ try {
+ if ("onDragStart" in callback) {
+ callback.onDragStart();
+ }
+
+ if ("ghost" in callback && callback.ghost) {
+ var draggedElmt = SimileAjax.WindowManager._draggedElement;
+
+ SimileAjax.WindowManager._ghostCoords = SimileAjax.DOM.getPageCoordinates(draggedElmt);
+ SimileAjax.WindowManager._ghostCoords.left += diffX;
+ SimileAjax.WindowManager._ghostCoords.top += diffY;
+
+ var ghostElmt = draggedElmt.cloneNode(true);
+ ghostElmt.style.position = "absolute";
+ ghostElmt.style.left = SimileAjax.WindowManager._ghostCoords.left + "px";
+ ghostElmt.style.top = SimileAjax.WindowManager._ghostCoords.top + "px";
+ ghostElmt.style.zIndex = 1000;
+ SimileAjax.Graphics.setOpacity(ghostElmt, 50);
+
+ document.body.appendChild(ghostElmt);
+ callback._ghostElmt = ghostElmt;
+ }
+
+ SimileAjax.WindowManager._dragging = true;
+ SimileAjax.WindowManager._lastCoords = { x: evt.clientX, y: evt.clientY };
+
+ document.body.focus();
+ } catch (e) {
+ SimileAjax.Debug.exception("WindowManager: Error handling mouse down", e);
+ SimileAjax.WindowManager._cancelDragging();
+ }
+ }
+ } else {
+ try {
+ SimileAjax.WindowManager._lastCoords = { x: evt.clientX, y: evt.clientY };
+
+ if ("onDragBy" in callback) {
+ callback.onDragBy(diffX, diffY);
+ }
+
+ if ("_ghostElmt" in callback) {
+ var ghostElmt = callback._ghostElmt;
+
+ SimileAjax.WindowManager._ghostCoords.left += diffX;
+ SimileAjax.WindowManager._ghostCoords.top += diffY;
+
+ ghostElmt.style.left = SimileAjax.WindowManager._ghostCoords.left + "px";
+ ghostElmt.style.top = SimileAjax.WindowManager._ghostCoords.top + "px";
+ if (SimileAjax.WindowManager._draggingModeIndicatorElmt != null) {
+ var indicatorElmt = SimileAjax.WindowManager._draggingModeIndicatorElmt;
+
+ indicatorElmt.style.left = (SimileAjax.WindowManager._ghostCoords.left - 16) + "px";
+ indicatorElmt.style.top = SimileAjax.WindowManager._ghostCoords.top + "px";
+ }
+
+ if ("droppable" in callback && callback.droppable) {
+ var coords = SimileAjax.DOM.getEventPageCoordinates(evt);
+ var target = SimileAjax.DOM.hittest(
+ coords.x, coords.y,
+ [ SimileAjax.WindowManager._ghostElmt,
+ SimileAjax.WindowManager._dropTargetHighlightElement
+ ]
+ );
+ target = SimileAjax.WindowManager._findDropTarget(target);
+
+ if (target != SimileAjax.WindowManager._potentialDropTarget) {
+ if (SimileAjax.WindowManager._dropTargetHighlightElement != null) {
+ document.body.removeChild(SimileAjax.WindowManager._dropTargetHighlightElement);
+
+ SimileAjax.WindowManager._dropTargetHighlightElement = null;
+ SimileAjax.WindowManager._potentialDropTarget = null;
+ }
+
+ var droppable = false;
+ if (target != null) {
+ if ((!("canDropOn" in callback) || callback.canDropOn(target)) &&
+ (!("canDrop" in target) || target.canDrop(SimileAjax.WindowManager._draggedElement))) {
+
+ droppable = true;
+ }
+ }
+
+ if (droppable) {
+ var border = 4;
+ var targetCoords = SimileAjax.DOM.getPageCoordinates(target);
+ var highlight = document.createElement("div");
+ highlight.style.border = border + "px solid yellow";
+ highlight.style.backgroundColor = "yellow";
+ highlight.style.position = "absolute";
+ highlight.style.left = targetCoords.left + "px";
+ highlight.style.top = targetCoords.top + "px";
+ highlight.style.width = (target.offsetWidth - border * 2) + "px";
+ highlight.style.height = (target.offsetHeight - border * 2) + "px";
+ SimileAjax.Graphics.setOpacity(highlight, 30);
+ document.body.appendChild(highlight);
+
+ SimileAjax.WindowManager._potentialDropTarget = target;
+ SimileAjax.WindowManager._dropTargetHighlightElement = highlight;
+ }
+ }
+ }
+ }
+ } catch (e) {
+ SimileAjax.Debug.exception("WindowManager: Error handling mouse move", e);
+ SimileAjax.WindowManager._cancelDragging();
+ }
+ }
+
+ SimileAjax.DOM.cancelEvent(evt);
+ return false;
+ }
+};
+
+SimileAjax.WindowManager._onBodyMouseUp = function(elmt, evt, target) {
+ if (SimileAjax.WindowManager._draggedElement != null) {
+ try {
+ if (SimileAjax.WindowManager._dragging) {
+ var callback = SimileAjax.WindowManager._draggedElementCallback;
+ if ("onDragEnd" in callback) {
+ callback.onDragEnd();
+ }
+ if ("droppable" in callback && callback.droppable) {
+ var dropped = false;
+
+ var target = SimileAjax.WindowManager._potentialDropTarget;
+ if (target != null) {
+ if ((!("canDropOn" in callback) || callback.canDropOn(target)) &&
+ (!("canDrop" in target) || target.canDrop(SimileAjax.WindowManager._draggedElement))) {
+
+ if ("onDropOn" in callback) {
+ callback.onDropOn(target);
+ }
+ target.ondrop(SimileAjax.WindowManager._draggedElement, SimileAjax.WindowManager._draggingMode);
+
+ dropped = true;
+ }
+ }
+
+ if (!dropped) {
+ // TODO: do holywood explosion here
+ }
+ }
+ }
+ } finally {
+ SimileAjax.WindowManager._cancelDragging();
+ }
+
+ SimileAjax.DOM.cancelEvent(evt);
+ return false;
+ }
+};
+
+SimileAjax.WindowManager._cancelDragging = function() {
+ var callback = SimileAjax.WindowManager._draggedElementCallback;
+ if ("_ghostElmt" in callback) {
+ var ghostElmt = callback._ghostElmt;
+ document.body.removeChild(ghostElmt);
+
+ delete callback._ghostElmt;
+ }
+ if (SimileAjax.WindowManager._dropTargetHighlightElement != null) {
+ document.body.removeChild(SimileAjax.WindowManager._dropTargetHighlightElement);
+ SimileAjax.WindowManager._dropTargetHighlightElement = null;
+ }
+ if (SimileAjax.WindowManager._draggingModeIndicatorElmt != null) {
+ document.body.removeChild(SimileAjax.WindowManager._draggingModeIndicatorElmt);
+ SimileAjax.WindowManager._draggingModeIndicatorElmt = null;
+ }
+
+ SimileAjax.WindowManager._draggedElement = null;
+ SimileAjax.WindowManager._draggedElementCallback = null;
+ SimileAjax.WindowManager._potentialDropTarget = null;
+ SimileAjax.WindowManager._dropTargetHighlightElement = null;
+ SimileAjax.WindowManager._lastCoords = null;
+ SimileAjax.WindowManager._ghostCoords = null;
+ SimileAjax.WindowManager._draggingMode = "";
+ SimileAjax.WindowManager._dragging = false;
+};
+
+SimileAjax.WindowManager._findDropTarget = function(elmt) {
+ while (elmt != null) {
+ if ("ondrop" in elmt && (typeof elmt.ondrop) == "function") {
+ break;
+ }
+ elmt = elmt.parentNode;
+ }
+ return elmt;
+};
+////////////////////////////// TIMELINE LOADER /////////////////////////////////
+
+(function() {
+ var useLocalResources = false;
+ if (document.location.search.length > 0) {
+ var params = document.location.search.substr(1).split("&");
+ for (var i = 0; i < params.length; i++) {
+ if (params[i] == "timeline-use-local-resources") {
+ useLocalResources = true;
+ }
+ }
+ };
+
+ var loadMe = function() {
+ if ("Timeline" in window) {
+ return;
+ }
+
+ window.Timeline = new Object();
+ window.Timeline.DateTime = window.SimileAjax.DateTime; // for backward compatibility
+
+ };
+
+ loadMe();
+})();/*==================================================
+ * Timeline
+ *==================================================
+ */
+
+Timeline.strings = {}; // localization string tables
+
+Timeline.getDefaultLocale = function() {
+ return Timeline.clientLocale;
+};
+
+Timeline.create = function(elmt, bandInfos, orientation, unit) {
+ return new Timeline._Impl(elmt, bandInfos, orientation, unit);
+};
+
+Timeline.HORIZONTAL = 0;
+Timeline.VERTICAL = 1;
+
+Timeline._defaultTheme = null;
+
+Timeline.createBandInfo = function(params) {
+ var theme = ("theme" in params) ? params.theme : Timeline.getDefaultTheme();
+
+ var eventSource = ("eventSource" in params) ? params.eventSource : null;
+
+ var ether = new Timeline.LinearEther({
+ centersOn: ("date" in params) ? params.date : new Date(),
+ interval: SimileAjax.DateTime.gregorianUnitLengths[params.intervalUnit],
+ pixelsPerInterval: params.intervalPixels
+ });
+
+ var etherPainter = new Timeline.GregorianEtherPainter({
+ unit: params.intervalUnit,
+ multiple: ("multiple" in params) ? params.multiple : 1,
+ theme: theme,
+ align: ("align" in params) ? params.align : undefined
+ });
+
+ var eventPainterParams = {
+ showText: ("showEventText" in params) ? params.showEventText : true,
+ theme: theme
+ };
+ if ("trackHeight" in params) {
+ eventPainterParams.trackHeight = params.trackHeight;
+ }
+ if ("trackGap" in params) {
+ eventPainterParams.trackGap = params.trackGap;
+ }
+
+ var layout = ("overview" in params && params.overview) ? "overview" : ("layout" in params ? params.layout : "original");
+ var eventPainter;
+ switch (layout) {
+ case "overview" :
+ eventPainter = new Timeline.OverviewEventPainter(eventPainterParams);
+ break;
+ case "detailed" :
+ eventPainter = new Timeline.DetailedEventPainter(eventPainterParams);
+ break;
+ default:
+ eventPainter = new Timeline.OriginalEventPainter(eventPainterParams);
+ }
+
+ return {
+ width: params.width,
+ eventSource: eventSource,
+ timeZone: ("timeZone" in params) ? params.timeZone : 0,
+ ether: ether,
+ etherPainter: etherPainter,
+ eventPainter: eventPainter
+ };
+};
+
+Timeline.createHotZoneBandInfo = function(params) {
+ var theme = ("theme" in params) ? params.theme : Timeline.getDefaultTheme();
+
+ var eventSource = ("eventSource" in params) ? params.eventSource : null;
+
+ var ether = new Timeline.HotZoneEther({
+ centersOn: ("date" in params) ? params.date : new Date(),
+ interval: SimileAjax.DateTime.gregorianUnitLengths[params.intervalUnit],
+ pixelsPerInterval: params.intervalPixels,
+ zones: params.zones
+ });
+
+ var etherPainter = new Timeline.HotZoneGregorianEtherPainter({
+ unit: params.intervalUnit,
+ zones: params.zones,
+ theme: theme,
+ align: ("align" in params) ? params.align : undefined
+ });
+
+ var eventPainterParams = {
+ showText: ("showEventText" in params) ? params.showEventText : true,
+ theme: theme
+ };
+ if ("trackHeight" in params) {
+ eventPainterParams.trackHeight = params.trackHeight;
+ }
+ if ("trackGap" in params) {
+ eventPainterParams.trackGap = params.trackGap;
+ }
+
+ var layout = ("overview" in params && params.overview) ? "overview" : ("layout" in params ? params.layout : "original");
+ var eventPainter;
+ switch (layout) {
+ case "overview" :
+ eventPainter = new Timeline.OverviewEventPainter(eventPainterParams);
+ break;
+ case "detailed" :
+ eventPainter = new Timeline.DetailedEventPainter(eventPainterParams);
+ break;
+ default:
+ eventPainter = new Timeline.OriginalEventPainter(eventPainterParams);
+ }
+
+ return {
+ width: params.width,
+ eventSource: eventSource,
+ timeZone: ("timeZone" in params) ? params.timeZone : 0,
+ ether: ether,
+ etherPainter: etherPainter,
+ eventPainter: eventPainter
+ };
+};
+
+Timeline.getDefaultTheme = function() {
+ if (Timeline._defaultTheme == null) {
+ Timeline._defaultTheme = Timeline.ClassicTheme.create(Timeline.getDefaultLocale());
+ }
+ return Timeline._defaultTheme;
+};
+
+Timeline.setDefaultTheme = function(theme) {
+ Timeline._defaultTheme = theme;
+};
+
+Timeline.loadXML = function(url, f) {
+ var fError = function(statusText, status, xmlhttp) {
+ alert("Failed to load data xml from " + url + "\n" + statusText);
+ };
+ var fDone = function(xmlhttp) {
+ var xml = xmlhttp.responseXML;
+ if (!xml.documentElement && xmlhttp.responseStream) {
+ xml.load(xmlhttp.responseStream);
+ }
+ f(xml, url);
+ };
+ SimileAjax.XmlHttp.get(url, fError, fDone);
+};
+
+
+Timeline.loadJSON = function(url, f) {
+ var fError = function(statusText, status, xmlhttp) {
+ alert("Failed to load json data from " + url + "\n" + statusText);
+ };
+ var fDone = function(xmlhttp) {
+ f(eval('(' + xmlhttp.responseText + ')'), url);
+ };
+ SimileAjax.XmlHttp.get(url, fError, fDone);
+};
+
+
+Timeline._Impl = function(elmt, bandInfos, orientation, unit) {
+ SimileAjax.WindowManager.initialize();
+
+ this._containerDiv = elmt;
+
+ this._bandInfos = bandInfos;
+ this._orientation = orientation == null ? Timeline.HORIZONTAL : orientation;
+ this._unit = (unit != null) ? unit : SimileAjax.NativeDateUnit;
+
+ this._initialize();
+};
+
+Timeline._Impl.prototype.dispose = function() {
+ for (var i = 0; i < this._bands.length; i++) {
+ this._bands[i].dispose();
+ }
+ this._bands = null;
+ this._bandInfos = null;
+ this._containerDiv.innerHTML = "";
+};
+
+Timeline._Impl.prototype.getBandCount = function() {
+ return this._bands.length;
+};
+
+Timeline._Impl.prototype.getBand = function(index) {
+ return this._bands[index];
+};
+
+Timeline._Impl.prototype.layout = function() {
+ this._distributeWidths();
+};
+
+Timeline._Impl.prototype.paint = function() {
+ for (var i = 0; i < this._bands.length; i++) {
+ this._bands[i].paint();
+ }
+};
+
+Timeline._Impl.prototype.getDocument = function() {
+ return this._containerDiv.ownerDocument;
+};
+
+Timeline._Impl.prototype.addDiv = function(div) {
+ this._containerDiv.appendChild(div);
+};
+
+Timeline._Impl.prototype.removeDiv = function(div) {
+ this._containerDiv.removeChild(div);
+};
+
+Timeline._Impl.prototype.isHorizontal = function() {
+ return this._orientation == Timeline.HORIZONTAL;
+};
+
+Timeline._Impl.prototype.isVertical = function() {
+ return this._orientation == Timeline.VERTICAL;
+};
+
+Timeline._Impl.prototype.getPixelLength = function() {
+ return this._orientation == Timeline.HORIZONTAL ?
+ this._containerDiv.offsetWidth : this._containerDiv.offsetHeight;
+};
+
+Timeline._Impl.prototype.getPixelWidth = function() {
+ return this._orientation == Timeline.VERTICAL ?
+ this._containerDiv.offsetWidth : this._containerDiv.offsetHeight;
+};
+
+Timeline._Impl.prototype.getUnit = function() {
+ return this._unit;
+};
+
+Timeline._Impl.prototype.loadXML = function(url, f) {
+ var tl = this;
+
+
+ var fError = function(statusText, status, xmlhttp) {
+ alert("Failed to load data xml from " + url + "\n" + statusText);
+ tl.hideLoadingMessage();
+ };
+ var fDone = function(xmlhttp) {
+ try {
+ var xml = xmlhttp.responseXML;
+ if (!xml.documentElement && xmlhttp.responseStream) {
+ xml.load(xmlhttp.responseStream);
+ }
+ f(xml, url);
+ } finally {
+ tl.hideLoadingMessage();
+ }
+ };
+
+ this.showLoadingMessage();
+ window.setTimeout(function() { SimileAjax.XmlHttp.get(url, fError, fDone); }, 0);
+};
+
+Timeline._Impl.prototype.loadJSON = function(url, f) {
+ var tl = this;
+
+
+ var fError = function(statusText, status, xmlhttp) {
+ alert("Failed to load json data from " + url + "\n" + statusText);
+ tl.hideLoadingMessage();
+ };
+ var fDone = function(xmlhttp) {
+ try {
+ f(eval('(' + xmlhttp.responseText + ')'), url);
+ } finally {
+ tl.hideLoadingMessage();
+ }
+ };
+
+ this.showLoadingMessage();
+ window.setTimeout(function() { SimileAjax.XmlHttp.get(url, fError, fDone); }, 0);
+};
+
+Timeline._Impl.prototype._initialize = function() {
+ var containerDiv = this._containerDiv;
+ var doc = containerDiv.ownerDocument;
+
+ containerDiv.className =
+ containerDiv.className.split(" ").concat("timeline-container").join(" ");
+
+ while (containerDiv.firstChild) {
+ containerDiv.removeChild(containerDiv.firstChild);
+ }
+
+ /*
+ * inserting copyright and link to simile
+ */
+ var elmtCopyright = SimileAjax.Graphics.createTranslucentImage(Timeline.urlPrefix + (this.isHorizontal() ? "images/copyright-vertical.png" : "images/copyright.png"));
+ elmtCopyright.className = "timeline-copyright";
+ elmtCopyright.title = "Timeline (c) SIMILE - http://simile.mit.edu/timeline/";
+ SimileAjax.DOM.registerEvent(elmtCopyright, "click", function() { window.location = "http://simile.mit.edu/timeline/"; });
+ containerDiv.appendChild(elmtCopyright);
+
+ /*
+ * creating bands
+ */
+ this._bands = [];
+ for (var i = 0; i < this._bandInfos.length; i++) {
+ var band = new Timeline._Band(this, this._bandInfos[i], i);
+ this._bands.push(band);
+ }
+ this._distributeWidths();
+
+ /*
+ * sync'ing bands
+ */
+ for (var i = 0; i < this._bandInfos.length; i++) {
+ var bandInfo = this._bandInfos[i];
+ if ("syncWith" in bandInfo) {
+ this._bands[i].setSyncWithBand(
+ this._bands[bandInfo.syncWith],
+ ("highlight" in bandInfo) ? bandInfo.highlight : false
+ );
+ }
+ }
+
+ /*
+ * creating loading UI
+ */
+ var message = SimileAjax.Graphics.createMessageBubble(doc);
+ message.containerDiv.className = "timeline-message-container";
+ containerDiv.appendChild(message.containerDiv);
+
+ message.contentDiv.className = "timeline-message";
+ message.contentDiv.innerHTML = "<img src='" + Timeline.urlPrefix + "images/progress-running.gif' /> Loading...";
+
+ this.showLoadingMessage = function() { message.containerDiv.style.display = "block"; };
+ this.hideLoadingMessage = function() { message.containerDiv.style.display = "none"; };
+};
+
+Timeline._Impl.prototype._distributeWidths = function() {
+ var length = this.getPixelLength();
+ var width = this.getPixelWidth();
+ var cumulativeWidth = 0;
+
+ for (var i = 0; i < this._bands.length; i++) {
+ var band = this._bands[i];
+ var bandInfos = this._bandInfos[i];
+ var widthString = bandInfos.width;
+
+ var x = widthString.indexOf("%");
+ if (x > 0) {
+ var percent = parseInt(widthString.substr(0, x));
+ var bandWidth = percent * width / 100;
+ } else {
+ var bandWidth = parseInt(widthString);
+ }
+
+ band.setBandShiftAndWidth(cumulativeWidth, bandWidth);
+ band.setViewLength(length);
+
+ cumulativeWidth += bandWidth;
+ }
+};
+
+/*==================================================
+ * Band
+ *==================================================
+ */
+Timeline._Band = function(timeline, bandInfo, index) {
+ this._timeline = timeline;
+ this._bandInfo = bandInfo;
+ this._index = index;
+
+ this._locale = ("locale" in bandInfo) ? bandInfo.locale : Timeline.getDefaultLocale();
+ this._timeZone = ("timeZone" in bandInfo) ? bandInfo.timeZone : 0;
+ this._labeller = ("labeller" in bandInfo) ? bandInfo.labeller :
+ (("createLabeller" in timeline.getUnit()) ?
+ timeline.getUnit().createLabeller(this._locale, this._timeZone) :
+ new Timeline.GregorianDateLabeller(this._locale, this._timeZone));
+
+ this._dragging = false;
+ this._changing = false;
+ this._originalScrollSpeed = 5; // pixels
+ this._scrollSpeed = this._originalScrollSpeed;
+ this._onScrollListeners = [];
+
+ var b = this;
+ this._syncWithBand = null;
+ this._syncWithBandHandler = function(band) {
+ b._onHighlightBandScroll();
+ };
+ this._selectorListener = function(band) {
+ b._onHighlightBandScroll();
+ };
+
+ /*
+ * Install a textbox to capture keyboard events
+ */
+ var inputDiv = this._timeline.getDocument().createElement("div");
+ inputDiv.className = "timeline-band-input";
+ this._timeline.addDiv(inputDiv);
+
+ this._keyboardInput = document.createElement("input");
+ this._keyboardInput.type = "text";
+ inputDiv.appendChild(this._keyboardInput);
+ SimileAjax.DOM.registerEventWithObject(this._keyboardInput, "keydown", this, "_onKeyDown");
+ SimileAjax.DOM.registerEventWithObject(this._keyboardInput, "keyup", this, "_onKeyUp");
+
+ /*
+ * The band's outer most div that slides with respect to the timeline's div
+ */
+ this._div = this._timeline.getDocument().createElement("div");
+ this._div.className = "timeline-band timeline-band-" + index;
+ this._timeline.addDiv(this._div);
+
+ SimileAjax.DOM.registerEventWithObject(this._div, "mousedown", this, "_onMouseDown");
+ SimileAjax.DOM.registerEventWithObject(this._div, "mousemove", this, "_onMouseMove");
+ SimileAjax.DOM.registerEventWithObject(this._div, "mouseup", this, "_onMouseUp");
+ SimileAjax.DOM.registerEventWithObject(this._div, "mouseout", this, "_onMouseOut");
+ SimileAjax.DOM.registerEventWithObject(this._div, "dblclick", this, "_onDblClick");
+
+ /*
+ * The inner div that contains layers
+ */
+ this._innerDiv = this._timeline.getDocument().createElement("div");
+ this._innerDiv.className = "timeline-band-inner";
+ this._div.appendChild(this._innerDiv);
+
+ /*
+ * Initialize parts of the band
+ */
+ this._ether = bandInfo.ether;
+ bandInfo.ether.initialize(timeline);
+
+ this._etherPainter = bandInfo.etherPainter;
+ bandInfo.etherPainter.initialize(this, timeline);
+
+ this._eventSource = bandInfo.eventSource;
+ if (this._eventSource) {
+ this._eventListener = {
+ onAddMany: function() { b._onAddMany(); },
+ onClear: function() { b._onClear(); }
+ }
+ this._eventSource.addListener(this._eventListener);
+ }
+
+ this._eventPainter = bandInfo.eventPainter;
+ bandInfo.eventPainter.initialize(this, timeline);
+
+ this._decorators = ("decorators" in bandInfo) ? bandInfo.decorators : [];
+ for (var i = 0; i < this._decorators.length; i++) {
+ this._decorators[i].initialize(this, timeline);
+ }
+};
+
+Timeline._Band.SCROLL_MULTIPLES = 5;
+
+Timeline._Band.prototype.dispose = function() {
+ this.closeBubble();
+
+ if (this._eventSource) {
+ this._eventSource.removeListener(this._eventListener);
+ this._eventListener = null;
+ this._eventSource = null;
+ }
+
+ this._timeline = null;
+ this._bandInfo = null;
+
+ this._labeller = null;
+ this._ether = null;
+ this._etherPainter = null;
+ this._eventPainter = null;
+ this._decorators = null;
+
+ this._onScrollListeners = null;
+ this._syncWithBandHandler = null;
+ this._selectorListener = null;
+
+ this._div = null;
+ this._innerDiv = null;
+ this._keyboardInput = null;
+};
+
+Timeline._Band.prototype.addOnScrollListener = function(listener) {
+ this._onScrollListeners.push(listener);
+};
+
+Timeline._Band.prototype.removeOnScrollListener = function(listener) {
+ for (var i = 0; i < this._onScrollListeners.length; i++) {
+ if (this._onScrollListeners[i] == listener) {
+ this._onScrollListeners.splice(i, 1);
+ break;
+ }
+ }
+};
+
+Timeline._Band.prototype.setSyncWithBand = function(band, highlight) {
+ if (this._syncWithBand) {
+ this._syncWithBand.removeOnScrollListener(this._syncWithBandHandler);
+ }
+
+ this._syncWithBand = band;
+ this._syncWithBand.addOnScrollListener(this._syncWithBandHandler);
+ this._highlight = highlight;
+ this._positionHighlight();
+};
+
+Timeline._Band.prototype.getLocale = function() {
+ return this._locale;
+};
+
+Timeline._Band.prototype.getTimeZone = function() {
+ return this._timeZone;
+};
+
+Timeline._Band.prototype.getLabeller = function() {
+ return this._labeller;
+};
+
+Timeline._Band.prototype.getIndex = function() {
+ return this._index;
+};
+
+Timeline._Band.prototype.getEther = function() {
+ return this._ether;
+};
+
+Timeline._Band.prototype.getEtherPainter = function() {
+ return this._etherPainter;
+};
+
+Timeline._Band.prototype.getEventSource = function() {
+ return this._eventSource;
+};
+
+Timeline._Band.prototype.getEventPainter = function() {
+ return this._eventPainter;
+};
+
+Timeline._Band.prototype.layout = function() {
+ this.paint();
+};
+
+Timeline._Band.prototype.paint = function() {
+ this._etherPainter.paint();
+ this._paintDecorators();
+ this._paintEvents();
+};
+
+Timeline._Band.prototype.softLayout = function() {
+ this.softPaint();
+};
+
+Timeline._Band.prototype.softPaint = function() {
+ this._etherPainter.softPaint();
+ this._softPaintDecorators();
+ this._softPaintEvents();
+};
+
+Timeline._Band.prototype.setBandShiftAndWidth = function(shift, width) {
+ var inputDiv = this._keyboardInput.parentNode;
+ var middle = shift + Math.floor(width / 2);
+ if (this._timeline.isHorizontal()) {
+ this._div.style.top = shift + "px";
+ this._div.style.height = width + "px";
+
+ inputDiv.style.top = middle + "px";
+ inputDiv.style.left = "-1em";
+ } else {
+ this._div.style.left = shift + "px";
+ this._div.style.width = width + "px";
+
+ inputDiv.style.left = middle + "px";
+ inputDiv.style.top = "-1em";
+ }
+};
+
+Timeline._Band.prototype.getViewWidth = function() {
+ if (this._timeline.isHorizontal()) {
+ return this._div.offsetHeight;
+ } else {
+ return this._div.offsetWidth;
+ }
+};
+
+Timeline._Band.prototype.setViewLength = function(length) {
+ this._viewLength = length;
+ this._recenterDiv();
+ this._onChanging();
+};
+
+Timeline._Band.prototype.getViewLength = function() {
+ return this._viewLength;
+};
+
+Timeline._Band.prototype.getTotalViewLength = function() {
+ return Timeline._Band.SCROLL_MULTIPLES * this._viewLength;
+};
+
+Timeline._Band.prototype.getViewOffset = function() {
+ return this._viewOffset;
+};
+
+Timeline._Band.prototype.getMinDate = function() {
+ return this._ether.pixelOffsetToDate(this._viewOffset);
+};
+
+Timeline._Band.prototype.getMaxDate = function() {
+ return this._ether.pixelOffsetToDate(this._viewOffset + Timeline._Band.SCROLL_MULTIPLES * this._viewLength);
+};
+
+Timeline._Band.prototype.getMinVisibleDate = function() {
+ return this._ether.pixelOffsetToDate(0);
+};
+
+Timeline._Band.prototype.getMaxVisibleDate = function() {
+ return this._ether.pixelOffsetToDate(this._viewLength);
+};
+
+Timeline._Band.prototype.getCenterVisibleDate = function() {
+ return this._ether.pixelOffsetToDate(this._viewLength / 2);
+};
+
+Timeline._Band.prototype.setMinVisibleDate = function(date) {
+ if (!this._changing) {
+ this._moveEther(Math.round(-this._ether.dateToPixelOffset(date)));
+ }
+};
+
+Timeline._Band.prototype.setMaxVisibleDate = function(date) {
+ if (!this._changing) {
+ this._moveEther(Math.round(this._viewLength - this._ether.dateToPixelOffset(date)));
+ }
+};
+
+Timeline._Band.prototype.setCenterVisibleDate = function(date) {
+ if (!this._changing) {
+ this._moveEther(Math.round(this._viewLength / 2 - this._ether.dateToPixelOffset(date)));
+ }
+};
+
+Timeline._Band.prototype.dateToPixelOffset = function(date) {
+ return this._ether.dateToPixelOffset(date) - this._viewOffset;
+};
+
+Timeline._Band.prototype.pixelOffsetToDate = function(pixels) {
+ return this._ether.pixelOffsetToDate(pixels + this._viewOffset);
+};
+
+Timeline._Band.prototype.createLayerDiv = function(zIndex, className) {
+ var div = this._timeline.getDocument().createElement("div");
+ div.className = "timeline-band-layer" + (typeof className == "string" ? (" " + className) : "");
+ div.style.zIndex = zIndex;
+ this._innerDiv.appendChild(div);
+
+ var innerDiv = this._timeline.getDocument().createElement("div");
+ innerDiv.className = "timeline-band-layer-inner";
+ if (SimileAjax.Platform.browser.isIE) {
+ innerDiv.style.cursor = "move";
+ } else {
+ innerDiv.style.cursor = "-moz-grab";
+ }
+ div.appendChild(innerDiv);
+
+ return innerDiv;
+};
+
+Timeline._Band.prototype.removeLayerDiv = function(div) {
+ this._innerDiv.removeChild(div.parentNode);
+};
+
+Timeline._Band.prototype.scrollToCenter = function(date, f) {
+ var pixelOffset = this._ether.dateToPixelOffset(date);
+ if (pixelOffset < -this._viewLength / 2) {
+ this.setCenterVisibleDate(this.pixelOffsetToDate(pixelOffset + this._viewLength));
+ } else if (pixelOffset > 3 * this._viewLength / 2) {
+ this.setCenterVisibleDate(this.pixelOffsetToDate(pixelOffset - this._viewLength));
+ }
+ this._autoScroll(Math.round(this._viewLength / 2 - this._ether.dateToPixelOffset(date)), f);
+};
+
+Timeline._Band.prototype.showBubbleForEvent = function(eventID) {
+ var evt = this.getEventSource().getEvent(eventID);
+ if (evt) {
+ var self = this;
+ this.scrollToCenter(evt.getStart(), function() {
+ self._eventPainter.showBubble(evt);
+ });
+ }
+};
+
+Timeline._Band.prototype._onMouseDown = function(innerFrame, evt, target) {
+ this.closeBubble();
+
+ this._dragging = true;
+ this._dragX = evt.clientX;
+ this._dragY = evt.clientY;
+};
+
+Timeline._Band.prototype._onMouseMove = function(innerFrame, evt, target) {
+ if (this._dragging) {
+ var diffX = evt.clientX - this._dragX;
+ var diffY = evt.clientY - this._dragY;
+
+ this._dragX = evt.clientX;
+ this._dragY = evt.clientY;
+
+ this._moveEther(this._timeline.isHorizontal() ? diffX : diffY);
+ this._positionHighlight();
+ }
+};
+
+Timeline._Band.prototype._onMouseUp = function(innerFrame, evt, target) {
+ this._dragging = false;
+ this._keyboardInput.focus();
+};
+
+Timeline._Band.prototype._onMouseOut = function(innerFrame, evt, target) {
+ var coords = SimileAjax.DOM.getEventRelativeCoordinates(evt, innerFrame);
+ coords.x += this._viewOffset;
+ if (coords.x < 0 || coords.x > innerFrame.offsetWidth ||
+ coords.y < 0 || coords.y > innerFrame.offsetHeight) {
+ this._dragging = false;
+ }
+};
+
+Timeline._Band.prototype._onDblClick = function(innerFrame, evt, target) {
+ var coords = SimileAjax.DOM.getEventRelativeCoordinates(evt, innerFrame);
+ var distance = coords.x - (this._viewLength / 2 - this._viewOffset);
+
+ this._autoScroll(-distance);
+};
+
+Timeline._Band.prototype._onKeyDown = function(keyboardInput, evt, target) {
+ if (!this._dragging) {
+ switch (evt.keyCode) {
+ case 27: // ESC
+ break;
+ case 37: // left arrow
+ case 38: // up arrow
+ this._scrollSpeed = Math.min(50, Math.abs(this._scrollSpeed * 1.05));
+ this._moveEther(this._scrollSpeed);
+ break;
+ case 39: // right arrow
+ case 40: // down arrow
+ this._scrollSpeed = -Math.min(50, Math.abs(this._scrollSpeed * 1.05));
+ this._moveEther(this._scrollSpeed);
+ break;
+ default:
+ return true;
+ }
+ this.closeBubble();
+
+ SimileAjax.DOM.cancelEvent(evt);
+ return false;
+ }
+ return true;
+};
+
+Timeline._Band.prototype._onKeyUp = function(keyboardInput, evt, target) {
+ if (!this._dragging) {
+ this._scrollSpeed = this._originalScrollSpeed;
+
+ switch (evt.keyCode) {
+ case 35: // end
+ this.setCenterVisibleDate(this._eventSource.getLatestDate());
+ break;
+ case 36: // home
+ this.setCenterVisibleDate(this._eventSource.getEarliestDate());
+ break;
+ case 33: // page up
+ this._autoScroll(this._timeline.getPixelLength());
+ break;
+ case 34: // page down
+ this._autoScroll(-this._timeline.getPixelLength());
+ break;
+ default:
+ return true;
+ }
+
+ this.closeBubble();
+
+ SimileAjax.DOM.cancelEvent(evt);
+ return false;
+ }
+ return true;
+};
+
+Timeline._Band.prototype._autoScroll = function(distance, f) {
+ var b = this;
+ var a = SimileAjax.Graphics.createAnimation(
+ function(abs, diff) {
+ b._moveEther(diff);
+ },
+ 0,
+ distance,
+ 1000,
+ f
+ );
+ a.run();
+};
+
+Timeline._Band.prototype._moveEther = function(shift) {
+ this.closeBubble();
+
+ this._viewOffset += shift;
+ this._ether.shiftPixels(-shift);
+ if (this._timeline.isHorizontal()) {
+ this._div.style.left = this._viewOffset + "px";
+ } else {
+ this._div.style.top = this._viewOffset + "px";
+ }
+
+ if (this._viewOffset > -this._viewLength * 0.5 ||
+ this._viewOffset < -this._viewLength * (Timeline._Band.SCROLL_MULTIPLES - 1.5)) {
+
+ this._recenterDiv();
+ } else {
+ this.softLayout();
+ }
+
+ this._onChanging();
+}
+
+Timeline._Band.prototype._onChanging = function() {
+ this._changing = true;
+
+ this._fireOnScroll();
+ this._setSyncWithBandDate();
+
+ this._changing = false;
+};
+
+Timeline._Band.prototype._fireOnScroll = function() {
+ for (var i = 0; i < this._onScrollListeners.length; i++) {
+ this._onScrollListeners[i](this);
+ }
+};
+
+Timeline._Band.prototype._setSyncWithBandDate = function() {
+ if (this._syncWithBand) {
+ var centerDate = this._ether.pixelOffsetToDate(this.getViewLength() / 2);
+ this._syncWithBand.setCenterVisibleDate(centerDate);
+ }
+};
+
+Timeline._Band.prototype._onHighlightBandScroll = function() {
+ if (this._syncWithBand) {
+ var centerDate = this._syncWithBand.getCenterVisibleDate();
+ var centerPixelOffset = this._ether.dateToPixelOffset(centerDate);
+
+ this._moveEther(Math.round(this._viewLength / 2 - centerPixelOffset));
+
+ if (this._highlight) {
+ this._etherPainter.setHighlight(
+ this._syncWithBand.getMinVisibleDate(),
+ this._syncWithBand.getMaxVisibleDate());
+ }
+ }
+};
+
+Timeline._Band.prototype._onAddMany = function() {
+ this._paintEvents();
+};
+
+Timeline._Band.prototype._onClear = function() {
+ this._paintEvents();
+};
+
+Timeline._Band.prototype._positionHighlight = function() {
+ if (this._syncWithBand) {
+ var startDate = this._syncWithBand.getMinVisibleDate();
+ var endDate = this._syncWithBand.getMaxVisibleDate();
+
+ if (this._highlight) {
+ this._etherPainter.setHighlight(startDate, endDate);
+ }
+ }
+};
+
+Timeline._Band.prototype._recenterDiv = function() {
+ this._viewOffset = -this._viewLength * (Timeline._Band.SCROLL_MULTIPLES - 1) / 2;
+ if (this._timeline.isHorizontal()) {
+ this._div.style.left = this._viewOffset + "px";
+ this._div.style.width = (Timeline._Band.SCROLL_MULTIPLES * this._viewLength) + "px";
+ } else {
+ this._div.style.top = this._viewOffset + "px";
+ this._div.style.height = (Timeline._Band.SCROLL_MULTIPLES * this._viewLength) + "px";
+ }
+ this.layout();
+};
+
+Timeline._Band.prototype._paintEvents = function() {
+ this._eventPainter.paint();
+};
+
+Timeline._Band.prototype._softPaintEvents = function() {
+ this._eventPainter.softPaint();
+};
+
+Timeline._Band.prototype._paintDecorators = function() {
+ for (var i = 0; i < this._decorators.length; i++) {
+ this._decorators[i].paint();
+ }
+};
+
+Timeline._Band.prototype._softPaintDecorators = function() {
+ for (var i = 0; i < this._decorators.length; i++) {
+ this._decorators[i].softPaint();
+ }
+};
+
+Timeline._Band.prototype.closeBubble = function() {
+ SimileAjax.WindowManager.cancelPopups();
+};
+/*==================================================
+ * Classic Theme
+ *==================================================
+ */
+
+
+Timeline.ClassicTheme = new Object();
+
+Timeline.ClassicTheme.implementations = [];
+
+Timeline.ClassicTheme.create = function(locale) {
+ if (locale == null) {
+ locale = Timeline.getDefaultLocale();
+ }
+
+ var f = Timeline.ClassicTheme.implementations[locale];
+ if (f == null) {
+ f = Timeline.ClassicTheme._Impl;
+ }
+ return new f();
+};
+
+Timeline.ClassicTheme._Impl = function() {
+ this.firstDayOfWeek = 0; // Sunday
+
+ this.ether = {
+ backgroundColors: [
+ "#EEE",
+ "#DDD",
+ "#CCC",
+ "#AAA"
+ ],
+ highlightColor: "white",
+ highlightOpacity: 50,
+ interval: {
+ line: {
+ show: true,
+ color: "#aaa",
+ opacity: 25
+ },
+ weekend: {
+ color: "#FFFFE0",
+ opacity: 30
+ },
+ marker: {
+ hAlign: "Bottom",
+ hBottomStyler: function(elmt) {
+ elmt.className = "timeline-ether-marker-bottom";
+ },
+ hBottomEmphasizedStyler: function(elmt) {
+ elmt.className = "timeline-ether-marker-bottom-emphasized";
+ },
+ hTopStyler: function(elmt) {
+ elmt.className = "timeline-ether-marker-top";
+ },
+ hTopEmphasizedStyler: function(elmt) {
+ elmt.className = "timeline-ether-marker-top-emphasized";
+ },
+
+ vAlign: "Right",
+ vRightStyler: function(elmt) {
+ elmt.className = "timeline-ether-marker-right";
+ },
+ vRightEmphasizedStyler: function(elmt) {
+ elmt.className = "timeline-ether-marker-right-emphasized";
+ },
+ vLeftStyler: function(elmt) {
+ elmt.className = "timeline-ether-marker-left";
+ },
+ vLeftEmphasizedStyler:function(elmt) {
+ elmt.className = "timeline-ether-marker-left-emphasized";
+ }
+ }
+ }
+ };
+
+ this.event = {
+ track: {
+ height: 10, // px
+ gap: 2 // px
+ },
+ overviewTrack: {
+ offset: 20, // px
+ tickHeight: 6, // px
+ height: 2, // px
+ gap: 1 // px
+ },
+ tape: {
+ height: 4 // px
+ },
+ instant: {
+ icon: Timeline.urlPrefix + "images/dull-blue-circle.png",
+ iconWidth: 10,
+ iconHeight: 10,
+ color: "#58A0DC",
+ impreciseColor: "#58A0DC",
+ impreciseOpacity: 20
+ },
+ duration: {
+ color: "#58A0DC",
+ impreciseColor: "#58A0DC",
+ impreciseOpacity: 20
+ },
+ label: {
+ backgroundColor: "white",
+ backgroundOpacity: 50,
+ lineColor: "#58A0DC",
+ offsetFromLine: 3 // px
+ },
+ highlightColors: [
+ "#FFFF00",
+ "#FFC000",
+ "#FF0000",
+ "#0000FF"
+ ],
+ bubble: {
+ width: 250, // px
+ height: 125, // px
+ titleStyler: function(elmt) {
+ elmt.className = "timeline-event-bubble-title";
+ },
+ bodyStyler: function(elmt) {
+ elmt.className = "timeline-event-bubble-body";
+ },
+ imageStyler: function(elmt) {
+ elmt.className = "timeline-event-bubble-image";
+ },
+ wikiStyler: function(elmt) {
+ elmt.className = "timeline-event-bubble-wiki";
+ },
+ timeStyler: function(elmt) {
+ elmt.className = "timeline-event-bubble-time";
+ }
+ }
+ };
+};/*==================================================
+ * Linear Ether
+ *==================================================
+ */
+
+Timeline.LinearEther = function(params) {
+ this._params = params;
+ this._interval = params.interval;
+ this._pixelsPerInterval = params.pixelsPerInterval;
+};
+
+Timeline.LinearEther.prototype.initialize = function(timeline) {
+ this._timeline = timeline;
+ this._unit = timeline.getUnit();
+
+ if ("startsOn" in this._params) {
+ this._start = this._unit.parseFromObject(this._params.startsOn);
+ } else if ("endsOn" in this._params) {
+ this._start = this._unit.parseFromObject(this._params.endsOn);
+ this.shiftPixels(-this._timeline.getPixelLength());
+ } else if ("centersOn" in this._params) {
+ this._start = this._unit.parseFromObject(this._params.centersOn);
+ this.shiftPixels(-this._timeline.getPixelLength() / 2);
+ } else {
+ this._start = this._unit.makeDefaultValue();
+ this.shiftPixels(-this._timeline.getPixelLength() / 2);
+ }
+};
+
+Timeline.LinearEther.prototype.setDate = function(date) {
+ this._start = this._unit.cloneValue(date);
+};
+
+Timeline.LinearEther.prototype.shiftPixels = function(pixels) {
+ var numeric = this._interval * pixels / this._pixelsPerInterval;
+ this._start = this._unit.change(this._start, numeric);
+};
+
+Timeline.LinearEther.prototype.dateToPixelOffset = function(date) {
+ var numeric = this._unit.compare(date, this._start);
+ return this._pixelsPerInterval * numeric / this._interval;
+};
+
+Timeline.LinearEther.prototype.pixelOffsetToDate = function(pixels) {
+ var numeric = pixels * this._interval / this._pixelsPerInterval;
+ return this._unit.change(this._start, numeric);
+};
+
+/*==================================================
+ * Hot Zone Ether
+ *==================================================
+ */
+
+Timeline.HotZoneEther = function(params) {
+ this._params = params;
+ this._interval = params.interval;
+ this._pixelsPerInterval = params.pixelsPerInterval;
+};
+
+Timeline.HotZoneEther.prototype.initialize = function(timeline) {
+ this._timeline = timeline;
+ this._unit = timeline.getUnit();
+
+ this._zones = [{
+ startTime: Number.NEGATIVE_INFINITY,
+ endTime: Number.POSITIVE_INFINITY,
+ magnify: 1
+ }];
+ var params = this._params;
+ for (var i = 0; i < params.zones.length; i++) {
+ var zone = params.zones[i];
+ var zoneStart = this._unit.parseFromObject(zone.start);
+ var zoneEnd = this._unit.parseFromObject(zone.end);
+
+ for (var j = 0; j < this._zones.length && this._unit.compare(zoneEnd, zoneStart) > 0; j++) {
+ var zone2 = this._zones[j];
+
+ if (this._unit.compare(zoneStart, zone2.endTime) < 0) {
+ if (this._unit.compare(zoneStart, zone2.startTime) > 0) {
+ this._zones.splice(j, 0, {
+ startTime: zone2.startTime,
+ endTime: zoneStart,
+ magnify: zone2.magnify
+ });
+ j++;
+
+ zone2.startTime = zoneStart;
+ }
+
+ if (this._unit.compare(zoneEnd, zone2.endTime) < 0) {
+ this._zones.splice(j, 0, {
+ startTime: zoneStart,
+ endTime: zoneEnd,
+ magnify: zone.magnify * zone2.magnify
+ });
+ j++;
+
+ zone2.startTime = zoneEnd;
+ zoneStart = zoneEnd;
+ } else {
+ zone2.magnify *= zone.magnify;
+ zoneStart = zone2.endTime;
+ }
+ } // else, try the next existing zone
+ }
+ }
+
+ if ("startsOn" in this._params) {
+ this._start = this._unit.parseFromObject(this._params.startsOn);
+ } else if ("endsOn" in this._params) {
+ this._start = this._unit.parseFromObject(this._params.endsOn);
+ this.shiftPixels(-this._timeline.getPixelLength());
+ } else if ("centersOn" in this._params) {
+ this._start = this._unit.parseFromObject(this._params.centersOn);
+ this.shiftPixels(-this._timeline.getPixelLength() / 2);
+ } else {
+ this._start = this._unit.makeDefaultValue();
+ this.shiftPixels(-this._timeline.getPixelLength() / 2);
+ }
+};
+
+Timeline.HotZoneEther.prototype.setDate = function(date) {
+ this._start = this._unit.cloneValue(date);
+};
+
+Timeline.HotZoneEther.prototype.shiftPixels = function(pixels) {
+ this._start = this.pixelOffsetToDate(pixels);
+};
+
+Timeline.HotZoneEther.prototype.dateToPixelOffset = function(date) {
+ return this._dateDiffToPixelOffset(this._start, date);
+};
+
+Timeline.HotZoneEther.prototype.pixelOffsetToDate = function(pixels) {
+ return this._pixelOffsetToDate(pixels, this._start);
+};
+
+Timeline.HotZoneEther.prototype._dateDiffToPixelOffset = function(fromDate, toDate) {
+ var scale = this._getScale();
+ var fromTime = fromDate;
+ var toTime = toDate;
+
+ var pixels = 0;
+ if (this._unit.compare(fromTime, toTime) < 0) {
+ var z = 0;
+ while (z < this._zones.length) {
+ if (this._unit.compare(fromTime, this._zones[z].endTime) < 0) {
+ break;
+ }
+ z++;
+ }
+
+ while (this._unit.compare(fromTime, toTime) < 0) {
+ var zone = this._zones[z];
+ var toTime2 = this._unit.earlier(toTime, zone.endTime);
+
+ pixels += (this._unit.compare(toTime2, fromTime) / (scale / zone.magnify));
+
+ fromTime = toTime2;
+ z++;
+ }
+ } else {
+ var z = this._zones.length - 1;
+ while (z >= 0) {
+ if (this._unit.compare(fromTime, this._zones[z].startTime) > 0) {
+ break;
+ }
+ z--;
+ }
+
+ while (this._unit.compare(fromTime, toTime) > 0) {
+ var zone = this._zones[z];
+ var toTime2 = this._unit.later(toTime, zone.startTime);
+
+ pixels += (this._unit.compare(toTime2, fromTime) / (scale / zone.magnify));
+
+ fromTime = toTime2;
+ z--;
+ }
+ }
+ return pixels;
+};
+
+Timeline.HotZoneEther.prototype._pixelOffsetToDate = function(pixels, fromDate) {
+ var scale = this._getScale();
+ var time = fromDate;
+ if (pixels > 0) {
+ var z = 0;
+ while (z < this._zones.length) {
+ if (this._unit.compare(time, this._zones[z].endTime) < 0) {
+ break;
+ }
+ z++;
+ }
+
+ while (pixels > 0) {
+ var zone = this._zones[z];
+ var scale2 = scale / zone.magnify;
+
+ if (zone.endTime == Number.POSITIVE_INFINITY) {
+ time = this._unit.change(time, pixels * scale2);
+ pixels = 0;
+ } else {
+ var pixels2 = this._unit.compare(zone.endTime, time) / scale2;
+ if (pixels2 > pixels) {
+ time = this._unit.change(time, pixels * scale2);
+ pixels = 0;
+ } else {
+ time = zone.endTime;
+ pixels -= pixels2;
+ }
+ }
+ z++;
+ }
+ } else {
+ var z = this._zones.length - 1;
+ while (z >= 0) {
+ if (this._unit.compare(time, this._zones[z].startTime) > 0) {
+ break;
+ }
+ z--;
+ }
+
+ pixels = -pixels;
+ while (pixels > 0) {
+ var zone = this._zones[z];
+ var scale2 = scale / zone.magnify;
+
+ if (zone.startTime == Number.NEGATIVE_INFINITY) {
+ time = this._unit.change(time, -pixels * scale2);
+ pixels = 0;
+ } else {
+ var pixels2 = this._unit.compare(time, zone.startTime) / scale2;
+ if (pixels2 > pixels) {
+ time = this._unit.change(time, -pixels * scale2);
+ pixels = 0;
+ } else {
+ time = zone.startTime;
+ pixels -= pixels2;
+ }
+ }
+ z--;
+ }
+ }
+ return time;
+};
+
+Timeline.HotZoneEther.prototype._getScale = function() {
+ return this._interval / this._pixelsPerInterval;
+};
+/*==================================================
+ * Gregorian Ether Painter
+ *==================================================
+ */
+
+Timeline.GregorianEtherPainter = function(params) {
+ this._params = params;
+ this._theme = params.theme;
+ this._unit = params.unit;
+ this._multiple = ("multiple" in params) ? params.multiple : 1;
+};
+
+Timeline.GregorianEtherPainter.prototype.initialize = function(band, timeline) {
+ this._band = band;
+ this._timeline = timeline;
+
+ this._backgroundLayer = band.createLayerDiv(0);
+ this._backgroundLayer.setAttribute("name", "ether-background"); // for debugging
+ this._backgroundLayer.style.background = this._theme.ether.backgroundColors[band.getIndex()];
+
+ this._markerLayer = null;
+ this._lineLayer = null;
+
+ var align = ("align" in this._params && this._params.align != undefined) ? this._params.align :
+ this._theme.ether.interval.marker[timeline.isHorizontal() ? "hAlign" : "vAlign"];
+ var showLine = ("showLine" in this._params) ? this._params.showLine :
+ this._theme.ether.interval.line.show;
+
+ this._intervalMarkerLayout = new Timeline.EtherIntervalMarkerLayout(
+ this._timeline, this._band, this._theme, align, showLine);
+
+ this._highlight = new Timeline.EtherHighlight(
+ this._timeline, this._band, this._theme, this._backgroundLayer);
+}
+
+Timeline.GregorianEtherPainter.prototype.setHighlight = function(startDate, endDate) {
+ this._highlight.position(startDate, endDate);
+}
+
+Timeline.GregorianEtherPainter.prototype.paint = function() {
+ if (this._markerLayer) {
+ this._band.removeLayerDiv(this._markerLayer);
+ }
+ this._markerLayer = this._band.createLayerDiv(100);
+ this._markerLayer.setAttribute("name", "ether-markers"); // for debugging
+ this._markerLayer.style.display = "none";
+
+ if (this._lineLayer) {
+ this._band.removeLayerDiv(this._lineLayer);
+ }
+ this._lineLayer = this._band.createLayerDiv(1);
+ this._lineLayer.setAttribute("name", "ether-lines"); // for debugging
+ this._lineLayer.style.display = "none";
+
+ var minDate = this._band.getMinDate();
+ var maxDate = this._band.getMaxDate();
+
+ var timeZone = this._band.getTimeZone();
+ var labeller = this._band.getLabeller();
+
+ SimileAjax.DateTime.roundDownToInterval(minDate, this._unit, timeZone, this._multiple, this._theme.firstDayOfWeek);
+
+ var p = this;
+ var incrementDate = function(date) {
+ for (var i = 0; i < p._multiple; i++) {
+ SimileAjax.DateTime.incrementByInterval(date, p._unit);
+ }
+ };
+
+ while (minDate.getTime() < maxDate.getTime()) {
+ this._intervalMarkerLayout.createIntervalMarker(
+ minDate, labeller, this._unit, this._markerLayer, this._lineLayer);
+
+ incrementDate(minDate);
+ }
+ this._markerLayer.style.display = "block";
+ this._lineLayer.style.display = "block";
+};
+
+Timeline.GregorianEtherPainter.prototype.softPaint = function() {
+};
+
+/*==================================================
+ * Hot Zone Gregorian Ether Painter
+ *==================================================
+ */
+
+Timeline.HotZoneGregorianEtherPainter = function(params) {
+ this._params = params;
+ this._theme = params.theme;
+
+ this._zones = [{
+ startTime: Number.NEGATIVE_INFINITY,
+ endTime: Number.POSITIVE_INFINITY,
+ unit: params.unit,
+ multiple: 1
+ }];
+ for (var i = 0; i < params.zones.length; i++) {
+ var zone = params.zones[i];
+ var zoneStart = SimileAjax.DateTime.parseGregorianDateTime(zone.start).getTime();
+ var zoneEnd = SimileAjax.DateTime.parseGregorianDateTime(zone.end).getTime();
+
+ for (var j = 0; j < this._zones.length && zoneEnd > zoneStart; j++) {
+ var zone2 = this._zones[j];
+
+ if (zoneStart < zone2.endTime) {
+ if (zoneStart > zone2.startTime) {
+ this._zones.splice(j, 0, {
+ startTime: zone2.startTime,
+ endTime: zoneStart,
+ unit: zone2.unit,
+ multiple: zone2.multiple
+ });
+ j++;
+
+ zone2.startTime = zoneStart;
+ }
+
+ if (zoneEnd < zone2.endTime) {
+ this._zones.splice(j, 0, {
+ startTime: zoneStart,
+ endTime: zoneEnd,
+ unit: zone.unit,
+ multiple: (zone.multiple) ? zone.multiple : 1
+ });
+ j++;
+
+ zone2.startTime = zoneEnd;
+ zoneStart = zoneEnd;
+ } else {
+ zone2.multiple = zone.multiple;
+ zone2.unit = zone.unit;
+ zoneStart = zone2.endTime;
+ }
+ } // else, try the next existing zone
+ }
+ }
+};
+
+Timeline.HotZoneGregorianEtherPainter.prototype.initialize = function(band, timeline) {
+ this._band = band;
+ this._timeline = timeline;
+
+ this._backgroundLayer = band.createLayerDiv(0);
+ this._backgroundLayer.setAttribute("name", "ether-background"); // for debugging
+ this._backgroundLayer.style.background = this._theme.ether.backgroundColors[band.getIndex()];
+
+ this._markerLayer = null;
+ this._lineLayer = null;
+
+ var align = ("align" in this._params && this._params.align != undefined) ? this._params.align :
+ this._theme.ether.interval.marker[timeline.isHorizontal() ? "hAlign" : "vAlign"];
+ var showLine = ("showLine" in this._params) ? this._params.showLine :
+ this._theme.ether.interval.line.show;
+
+ this._intervalMarkerLayout = new Timeline.EtherIntervalMarkerLayout(
+ this._timeline, this._band, this._theme, align, showLine);
+
+ this._highlight = new Timeline.EtherHighlight(
+ this._timeline, this._band, this._theme, this._backgroundLayer);
+}
+
+Timeline.HotZoneGregorianEtherPainter.prototype.setHighlight = function(startDate, endDate) {
+ this._highlight.position(startDate, endDate);
+}
+
+Timeline.HotZoneGregorianEtherPainter.prototype.paint = function() {
+ if (this._markerLayer) {
+ this._band.removeLayerDiv(this._markerLayer);
+ }
+ this._markerLayer = this._band.createLayerDiv(100);
+ this._markerLayer.setAttribute("name", "ether-markers"); // for debugging
+ this._markerLayer.style.display = "none";
+
+ if (this._lineLayer) {
+ this._band.removeLayerDiv(this._lineLayer);
+ }
+ this._lineLayer = this._band.createLayerDiv(1);
+ this._lineLayer.setAttribute("name", "ether-lines"); // for debugging
+ this._lineLayer.style.display = "none";
+
+ var minDate = this._band.getMinDate();
+ var maxDate = this._band.getMaxDate();
+
+ var timeZone = this._band.getTimeZone();
+ var labeller = this._band.getLabeller();
+
+ var p = this;
+ var incrementDate = function(date, zone) {
+ for (var i = 0; i < zone.multiple; i++) {
+ SimileAjax.DateTime.incrementByInterval(date, zone.unit);
+ }
+ };
+
+ var zStart = 0;
+ while (zStart < this._zones.length) {
+ if (minDate.getTime() < this._zones[zStart].endTime) {
+ break;
+ }
+ zStart++;
+ }
+ var zEnd = this._zones.length - 1;
+ while (zEnd >= 0) {
+ if (maxDate.getTime() > this._zones[zEnd].startTime) {
+ break;
+ }
+ zEnd--;
+ }
+
+ for (var z = zStart; z <= zEnd; z++) {
+ var zone = this._zones[z];
+
+ var minDate2 = new Date(Math.max(minDate.getTime(), zone.startTime));
+ var maxDate2 = new Date(Math.min(maxDate.getTime(), zone.endTime));
+
+ SimileAjax.DateTime.roundDownToInterval(minDate2, zone.unit, timeZone, zone.multiple, this._theme.firstDayOfWeek);
+ SimileAjax.DateTime.roundUpToInterval(maxDate2, zone.unit, timeZone, zone.multiple, this._theme.firstDayOfWeek);
+
+ while (minDate2.getTime() < maxDate2.getTime()) {
+ this._intervalMarkerLayout.createIntervalMarker(
+ minDate2, labeller, zone.unit, this._markerLayer, this._lineLayer);
+
+ incrementDate(minDate2, zone);
+ }
+ }
+ this._markerLayer.style.display = "block";
+ this._lineLayer.style.display = "block";
+};
+
+Timeline.HotZoneGregorianEtherPainter.prototype.softPaint = function() {
+};
+
+/*==================================================
+ * Year Count Ether Painter
+ *==================================================
+ */
+
+Timeline.YearCountEtherPainter = function(params) {
+ this._params = params;
+ this._theme = params.theme;
+ this._startDate = SimileAjax.DateTime.parseGregorianDateTime(params.startDate);
+ this._multiple = ("multiple" in params) ? params.multiple : 1;
+};
+
+Timeline.YearCountEtherPainter.prototype.initialize = function(band, timeline) {
+ this._band = band;
+ this._timeline = timeline;
+
+ this._backgroundLayer = band.createLayerDiv(0);
+ this._backgroundLayer.setAttribute("name", "ether-background"); // for debugging
+ this._backgroundLayer.style.background = this._theme.ether.backgroundColors[band.getIndex()];
+
+ this._markerLayer = null;
+ this._lineLayer = null;
+
+ var align = ("align" in this._params) ? this._params.align :
+ this._theme.ether.interval.marker[timeline.isHorizontal() ? "hAlign" : "vAlign"];
+ var showLine = ("showLine" in this._params) ? this._params.showLine :
+ this._theme.ether.interval.line.show;
+
+ this._intervalMarkerLayout = new Timeline.EtherIntervalMarkerLayout(
+ this._timeline, this._band, this._theme, align, showLine);
+
+ this._highlight = new Timeline.EtherHighlight(
+ this._timeline, this._band, this._theme, this._backgroundLayer);
+};
+
+Timeline.YearCountEtherPainter.prototype.setHighlight = function(startDate, endDate) {
+ this._highlight.position(startDate, endDate);
+};
+
+Timeline.YearCountEtherPainter.prototype.paint = function() {
+ if (this._markerLayer) {
+ this._band.removeLayerDiv(this._markerLayer);
+ }
+ this._markerLayer = this._band.createLayerDiv(100);
+ this._markerLayer.setAttribute("name", "ether-markers"); // for debugging
+ this._markerLayer.style.display = "none";
+
+ if (this._lineLayer) {
+ this._band.removeLayerDiv(this._lineLayer);
+ }
+ this._lineLayer = this._band.createLayerDiv(1);
+ this._lineLayer.setAttribute("name", "ether-lines"); // for debugging
+ this._lineLayer.style.display = "none";
+
+ var minDate = new Date(this._startDate.getTime());
+ var maxDate = this._band.getMaxDate();
+ var yearDiff = this._band.getMinDate().getUTCFullYear() - this._startDate.getUTCFullYear();
+ minDate.setUTCFullYear(this._band.getMinDate().getUTCFullYear() - yearDiff % this._multiple);
+
+ var p = this;
+ var incrementDate = function(date) {
+ for (var i = 0; i < p._multiple; i++) {
+ SimileAjax.DateTime.incrementByInterval(date, SimileAjax.DateTime.YEAR);
+ }
+ };
+ var labeller = {
+ labelInterval: function(date, intervalUnit) {
+ var diff = date.getUTCFullYear() - p._startDate.getUTCFullYear();
+ return {
+ text: diff,
+ emphasized: diff == 0
+ };
+ }
+ };
+
+ while (minDate.getTime() < maxDate.getTime()) {
+ this._intervalMarkerLayout.createIntervalMarker(
+ minDate, labeller, SimileAjax.DateTime.YEAR, this._markerLayer, this._lineLayer);
+
+ incrementDate(minDate);
+ }
+ this._markerLayer.style.display = "block";
+ this._lineLayer.style.display = "block";
+};
+
+Timeline.YearCountEtherPainter.prototype.softPaint = function() {
+};
+
+/*==================================================
+ * Quarterly Ether Painter
+ *==================================================
+ */
+
+Timeline.QuarterlyEtherPainter = function(params) {
+ this._params = params;
+ this._theme = params.theme;
+ this._startDate = SimileAjax.DateTime.parseGregorianDateTime(params.startDate);
+};
+
+Timeline.QuarterlyEtherPainter.prototype.initialize = function(band, timeline) {
+ this._band = band;
+ this._timeline = timeline;
+
+ this._backgroundLayer = band.createLayerDiv(0);
+ this._backgroundLayer.setAttribute("name", "ether-background"); // for debugging
+ this._backgroundLayer.style.background = this._theme.ether.backgroundColors[band.getIndex()];
+
+ this._markerLayer = null;
+ this._lineLayer = null;
+
+ var align = ("align" in this._params) ? this._params.align :
+ this._theme.ether.interval.marker[timeline.isHorizontal() ? "hAlign" : "vAlign"];
+ var showLine = ("showLine" in this._params) ? this._params.showLine :
+ this._theme.ether.interval.line.show;
+
+ this._intervalMarkerLayout = new Timeline.EtherIntervalMarkerLayout(
+ this._timeline, this._band, this._theme, align, showLine);
+
+ this._highlight = new Timeline.EtherHighlight(
+ this._timeline, this._band, this._theme, this._backgroundLayer);
+};
+
+Timeline.QuarterlyEtherPainter.prototype.setHighlight = function(startDate, endDate) {
+ this._highlight.position(startDate, endDate);
+};
+
+Timeline.QuarterlyEtherPainter.prototype.paint = function() {
+ if (this._markerLayer) {
+ this._band.removeLayerDiv(this._markerLayer);
+ }
+ this._markerLayer = this._band.createLayerDiv(100);
+ this._markerLayer.setAttribute("name", "ether-markers"); // for debugging
+ this._markerLayer.style.display = "none";
+
+ if (this._lineLayer) {
+ this._band.removeLayerDiv(this._lineLayer);
+ }
+ this._lineLayer = this._band.createLayerDiv(1);
+ this._lineLayer.setAttribute("name", "ether-lines"); // for debugging
+ this._lineLayer.style.display = "none";
+
+ var minDate = new Date(0);
+ var maxDate = this._band.getMaxDate();
+
+ minDate.setUTCFullYear(Math.max(this._startDate.getUTCFullYear(), this._band.getMinDate().getUTCFullYear()));
+ minDate.setUTCMonth(this._startDate.getUTCMonth());
+
+ var p = this;
+ var incrementDate = function(date) {
+ date.setUTCMonth(date.getUTCMonth() + 3);
+ };
+ var labeller = {
+ labelInterval: function(date, intervalUnit) {
+ var quarters = (4 + (date.getUTCMonth() - p._startDate.getUTCMonth()) / 3) % 4;
+ if (quarters != 0) {
+ return { text: "Q" + (quarters + 1), emphasized: false };
+ } else {
+ return { text: "Y" + (date.getUTCFullYear() - p._startDate.getUTCFullYear() + 1), emphasized: true };
+ }
+ }
+ };
+
+ while (minDate.getTime() < maxDate.getTime()) {
+ this._intervalMarkerLayout.createIntervalMarker(
+ minDate, labeller, SimileAjax.DateTime.YEAR, this._markerLayer, this._lineLayer);
+
+ incrementDate(minDate);
+ }
+ this._markerLayer.style.display = "block";
+ this._lineLayer.style.display = "block";
+};
+
+Timeline.QuarterlyEtherPainter.prototype.softPaint = function() {
+};
+
+/*==================================================
+ * Ether Interval Marker Layout
+ *==================================================
+ */
+
+Timeline.EtherIntervalMarkerLayout = function(timeline, band, theme, align, showLine) {
+ var horizontal = timeline.isHorizontal();
+ if (horizontal) {
+ if (align == "Top") {
+ this.positionDiv = function(div, offset) {
+ div.style.left = offset + "px";
+ div.style.top = "0px";
+ };
+ } else {
+ this.positionDiv = function(div, offset) {
+ div.style.left = offset + "px";
+ div.style.bottom = "0px";
+ };
+ }
+ } else {
+ if (align == "Left") {
+ this.positionDiv = function(div, offset) {
+ div.style.top = offset + "px";
+ div.style.left = "0px";
+ };
+ } else {
+ this.positionDiv = function(div, offset) {
+ div.style.top = offset + "px";
+ div.style.right = "0px";
+ };
+ }
+ }
+
+ var markerTheme = theme.ether.interval.marker;
+ var lineTheme = theme.ether.interval.line;
+ var weekendTheme = theme.ether.interval.weekend;
+
+ var stylePrefix = (horizontal ? "h" : "v") + align;
+ var labelStyler = markerTheme[stylePrefix + "Styler"];
+ var emphasizedLabelStyler = markerTheme[stylePrefix + "EmphasizedStyler"];
+ var day = SimileAjax.DateTime.gregorianUnitLengths[SimileAjax.DateTime.DAY];
+
+ this.createIntervalMarker = function(date, labeller, unit, markerDiv, lineDiv) {
+ var offset = Math.round(band.dateToPixelOffset(date));
+
+ if (showLine && unit != SimileAjax.DateTime.WEEK) {
+ var divLine = timeline.getDocument().createElement("div");
+ divLine.style.position = "absolute";
+
+ if (lineTheme.opacity < 100) {
+ SimileAjax.Graphics.setOpacity(divLine, lineTheme.opacity);
+ }
+
+ if (horizontal) {
+ divLine.style.borderLeft = "1px solid " + lineTheme.color;
+ divLine.style.left = offset + "px";
+ divLine.style.width = "1px";
+ divLine.style.top = "0px";
+ divLine.style.height = "100%";
+ } else {
+ divLine.style.borderTop = "1px solid " + lineTheme.color;
+ divLine.style.top = offset + "px";
+ divLine.style.height = "1px";
+ divLine.style.left = "0px";
+ divLine.style.width = "100%";
+ }
+ lineDiv.appendChild(divLine);
+ }
+ if (unit == SimileAjax.DateTime.WEEK) {
+ var firstDayOfWeek = theme.firstDayOfWeek;
+
+ var saturday = new Date(date.getTime() + (6 - firstDayOfWeek - 7) * day);
+ var monday = new Date(saturday.getTime() + 2 * day);
+
+ var saturdayPixel = Math.round(band.dateToPixelOffset(saturday));
+ var mondayPixel = Math.round(band.dateToPixelOffset(monday));
+ var length = Math.max(1, mondayPixel - saturdayPixel);
+
+ var divWeekend = timeline.getDocument().createElement("div");
+ divWeekend.style.position = "absolute";
+
+ divWeekend.style.background = weekendTheme.color;
+ if (weekendTheme.opacity < 100) {
+ SimileAjax.Graphics.setOpacity(divWeekend, weekendTheme.opacity);
+ }
+
+ if (horizontal) {
+ divWeekend.style.left = saturdayPixel + "px";
+ divWeekend.style.width = length + "px";
+ divWeekend.style.top = "0px";
+ divWeekend.style.height = "100%";
+ } else {
+ divWeekend.style.top = saturdayPixel + "px";
+ divWeekend.style.height = length + "px";
+ divWeekend.style.left = "0px";
+ divWeekend.style.width = "100%";
+ }
+ lineDiv.appendChild(divWeekend);
+ }
+
+ var label = labeller.labelInterval(date, unit);
+
+ var div = timeline.getDocument().createElement("div");
+ div.innerHTML = label.text;
+ div.style.position = "absolute";
+ (label.emphasized ? emphasizedLabelStyler : labelStyler)(div);
+
+ this.positionDiv(div, offset);
+ markerDiv.appendChild(div);
+
+ return div;
+ };
+};
+
+/*==================================================
+ * Ether Highlight Layout
+ *==================================================
+ */
+
+Timeline.EtherHighlight = function(timeline, band, theme, backgroundLayer) {
+ var horizontal = timeline.isHorizontal();
+
+ this._highlightDiv = null;
+ this._createHighlightDiv = function() {
+ if (this._highlightDiv == null) {
+ this._highlightDiv = timeline.getDocument().createElement("div");
+ this._highlightDiv.setAttribute("name", "ether-highlight"); // for debugging
+ this._highlightDiv.style.position = "absolute";
+ this._highlightDiv.style.background = theme.ether.highlightColor;
+
+ var opacity = theme.ether.highlightOpacity;
+ if (opacity < 100) {
+ SimileAjax.Graphics.setOpacity(this._highlightDiv, opacity);
+ }
+
+ backgroundLayer.appendChild(this._highlightDiv);
+ }
+ }
+
+ this.position = function(startDate, endDate) {
+ this._createHighlightDiv();
+
+ var startPixel = Math.round(band.dateToPixelOffset(startDate));
+ var endPixel = Math.round(band.dateToPixelOffset(endDate));
+ var length = Math.max(endPixel - startPixel, 3);
+ if (horizontal) {
+ this._highlightDiv.style.left = startPixel + "px";
+ this._highlightDiv.style.width = length + "px";
+ this._highlightDiv.style.top = "2px";
+ this._highlightDiv.style.height = (band.getViewWidth() - 4) + "px";
+ } else {
+ this._highlightDiv.style.top = startPixel + "px";
+ this._highlightDiv.style.height = length + "px";
+ this._highlightDiv.style.left = "2px";
+ this._highlightDiv.style.width = (band.getViewWidth() - 4) + "px";
+ }
+ }
+};
+
+/*==================================================
+ * Gregorian Date Labeller
+ *==================================================
+ */
+
+Timeline.GregorianDateLabeller = function(locale, timeZone) {
+ this._locale = locale;
+ this._timeZone = timeZone;
+};
+
+Timeline.GregorianDateLabeller.monthNames = [];
+Timeline.GregorianDateLabeller.dayNames = [];
+Timeline.GregorianDateLabeller.labelIntervalFunctions = [];
+
+Timeline.GregorianDateLabeller.getMonthName = function(month, locale) {
+ return Timeline.GregorianDateLabeller.monthNames[locale][month];
+};
+
+Timeline.GregorianDateLabeller.prototype.labelInterval = function(date, intervalUnit) {
+ var f = Timeline.GregorianDateLabeller.labelIntervalFunctions[this._locale];
+ if (f == null) {
+ f = Timeline.GregorianDateLabeller.prototype.defaultLabelInterval;
+ }
+ return f.call(this, date, intervalUnit);
+};
+
+Timeline.GregorianDateLabeller.prototype.labelPrecise = function(date) {
+ return SimileAjax.DateTime.removeTimeZoneOffset(
+ date,
+ this._timeZone //+ (new Date().getTimezoneOffset() / 60)
+ ).toUTCString();
+};
+
+Timeline.GregorianDateLabeller.prototype.defaultLabelInterval = function(date, intervalUnit) {
+ var text;
+ var emphasized = false;
+
+ date = SimileAjax.DateTime.removeTimeZoneOffset(date, this._timeZone);
+
+ switch(intervalUnit) {
+ case SimileAjax.DateTime.MILLISECOND:
+ text = date.getUTCMilliseconds();
+ break;
+ case SimileAjax.DateTime.SECOND:
+ text = date.getUTCSeconds();
+ break;
+ case SimileAjax.DateTime.MINUTE:
+ var m = date.getUTCMinutes();
+ if (m == 0) {
+ text = date.getUTCHours() + ":00";
+ emphasized = true;
+ } else {
+ text = m;
+ }
+ break;
+ case SimileAjax.DateTime.HOUR:
+ text = date.getUTCHours() + "hr";
+ break;
+ case SimileAjax.DateTime.DAY:
+ text = Timeline.GregorianDateLabeller.getMonthName(date.getUTCMonth(), this._locale) + " " + date.getUTCDate();
+ break;
+ case SimileAjax.DateTime.WEEK:
+ text = Timeline.GregorianDateLabeller.getMonthName(date.getUTCMonth(), this._locale) + " " + date.getUTCDate();
+ break;
+ case SimileAjax.DateTime.MONTH:
+ var m = date.getUTCMonth();
+ if (m != 0) {
+ text = Timeline.GregorianDateLabeller.getMonthName(m, this._locale);
+ break;
+ } // else, fall through
+ case SimileAjax.DateTime.YEAR:
+ case SimileAjax.DateTime.DECADE:
+ case SimileAjax.DateTime.CENTURY:
+ case SimileAjax.DateTime.MILLENNIUM:
+ var y = date.getUTCFullYear();
+ if (y > 0) {
+ text = date.getUTCFullYear();
+ } else {
+ text = (1 - y) + "BC";
+ }
+ emphasized =
+ (intervalUnit == SimileAjax.DateTime.MONTH) ||
+ (intervalUnit == SimileAjax.DateTime.DECADE && y % 100 == 0) ||
+ (intervalUnit == SimileAjax.DateTime.CENTURY && y % 1000 == 0);
+ break;
+ default:
+ text = date.toUTCString();
+ }
+ return { text: text, emphasized: emphasized };
+}
+
+/*==================================================
+ * Default Event Source
+ *==================================================
+ */
+
+
+Timeline.DefaultEventSource = function(eventIndex) {
+ this._events = (eventIndex instanceof Object) ? eventIndex : new SimileAjax.EventIndex();
+ this._listeners = [];
+};
+
+Timeline.DefaultEventSource.prototype.addListener = function(listener) {
+ this._listeners.push(listener);
+};
+
+Timeline.DefaultEventSource.prototype.removeListener = function(listener) {
+ for (var i = 0; i < this._listeners.length; i++) {
+ if (this._listeners[i] == listener) {
+ this._listeners.splice(i, 1);
+ break;
+ }
+ }
+};
+
+Timeline.DefaultEventSource.prototype.loadXML = function(xml, url) {
+ var base = this._getBaseURL(url);
+
+ var wikiURL = xml.documentElement.getAttribute("wiki-url");
+ var wikiSection = xml.documentElement.getAttribute("wiki-section");
+
+ var dateTimeFormat = xml.documentElement.getAttribute("date-time-format");
+ var parseDateTimeFunction = this._events.getUnit().getParser(dateTimeFormat);
+
+ var node = xml.documentElement.firstChild;
+ var added = false;
+ while (node != null) {
+ if (node.nodeType == 1) {
+ var description = "";
+ if (node.firstChild != null && node.firstChild.nodeType == 3) {
+ description = node.firstChild.nodeValue;
+ }
+ var evt = new Timeline.DefaultEventSource.Event(
+ node.getAttribute("id"),
+ parseDateTimeFunction(node.getAttribute("start")),
+ parseDateTimeFunction(node.getAttribute("end")),
+ parseDateTimeFunction(node.getAttribute("latestStart")),
+ parseDateTimeFunction(node.getAttribute("earliestEnd")),
+ node.getAttribute("isDuration") != "true",
+ node.getAttribute("title"),
+ description,
+ this._resolveRelativeURL(node.getAttribute("image"), base),
+ this._resolveRelativeURL(node.getAttribute("link"), base),
+ this._resolveRelativeURL(node.getAttribute("icon"), base),
+ node.getAttribute("color"),
+ node.getAttribute("textColor")
+ );
+ evt._node = node;
+ evt.getProperty = function(name) {
+ return this._node.getAttribute(name);
+ };
+ evt.setWikiInfo(wikiURL, wikiSection);
+
+ this._events.add(evt);
+
+ added = true;
+ }
+ node = node.nextSibling;
+ }
+
+ if (added) {
+ this._fire("onAddMany", []);
+ }
+};
+
+
+Timeline.DefaultEventSource.prototype.loadJSON = function(data, url) {
+ var base = this._getBaseURL(url);
+ var added = false;
+ if (data && data.events){
+ var wikiURL = ("wikiURL" in data) ? data.wikiURL : null;
+ var wikiSection = ("wikiSection" in data) ? data.wikiSection : null;
+
+ var dateTimeFormat = ("dateTimeFormat" in data) ? data.dateTimeFormat : null;
+ var parseDateTimeFunction = this._events.getUnit().getParser(dateTimeFormat);
+
+ for (var i=0; i < data.events.length; i++){
+ var event = data.events[i];
+ var evt = new Timeline.DefaultEventSource.Event(
+ ("id" in event) ? event.id : undefined,
+ parseDateTimeFunction(event.start),
+ parseDateTimeFunction(event.end),
+ parseDateTimeFunction(event.latestStart),
+ parseDateTimeFunction(event.earliestEnd),
+ event.isDuration || false,
+ event.title,
+ event.description,
+ this._resolveRelativeURL(event.image, base),
+ this._resolveRelativeURL(event.link, base),
+ this._resolveRelativeURL(event.icon, base),
+ event.color,
+ event.textColor
+ );
+ evt._obj = event;
+ evt.getProperty = function(name) {
+ return this._obj[name];
+ };
+ evt.setWikiInfo(wikiURL, wikiSection);
+
+ this._events.add(evt);
+ added = true;
+ }
+ }
+
+ if (added) {
+ this._fire("onAddMany", []);
+ }
+};
+
+/*
+ * Contributed by Morten Frederiksen, http://www.wasab.dk/morten/
+ */
+Timeline.DefaultEventSource.prototype.loadSPARQL = function(xml, url) {
+ var base = this._getBaseURL(url);
+
+ var dateTimeFormat = 'iso8601';
+ var parseDateTimeFunction = this._events.getUnit().getParser(dateTimeFormat);
+
+ if (xml == null) {
+ return;
+ }
+
+ /*
+ * Find <results> tag
+ */
+ var node = xml.documentElement.firstChild;
+ while (node != null && (node.nodeType != 1 || node.nodeName != 'results')) {
+ node = node.nextSibling;
+ }
+
+ var wikiURL = null;
+ var wikiSection = null;
+ if (node != null) {
+ wikiURL = node.getAttribute("wiki-url");
+ wikiSection = node.getAttribute("wiki-section");
+
+ node = node.firstChild;
+ }
+
+ var added = false;
+ while (node != null) {
+ if (node.nodeType == 1) {
+ var bindings = { };
+ var binding = node.firstChild;
+ while (binding != null) {
+ if (binding.nodeType == 1 &&
+ binding.firstChild != null &&
+ binding.firstChild.nodeType == 1 &&
+ binding.firstChild.firstChild != null &&
+ binding.firstChild.firstChild.nodeType == 3) {
+ bindings[binding.getAttribute('name')] = binding.firstChild.firstChild.nodeValue;
+ }
+ binding = binding.nextSibling;
+ }
+
+ if (bindings["start"] == null && bindings["date"] != null) {
+ bindings["start"] = bindings["date"];
+ }
+
+ var evt = new Timeline.DefaultEventSource.Event(
+ bindings["id"],
+ parseDateTimeFunction(bindings["start"]),
+ parseDateTimeFunction(bindings["end"]),
+ parseDateTimeFunction(bindings["latestStart"]),
+ parseDateTimeFunction(bindings["earliestEnd"]),
+ bindings["isDuration"] != "true",
+ bindings["title"],
+ bindings["description"],
+ this._resolveRelativeURL(bindings["image"], base),
+ this._resolveRelativeURL(bindings["link"], base),
+ this._resolveRelativeURL(bindings["icon"], base),
+ bindings["color"],
+ bindings["textColor"]
+ );
+ evt._bindings = bindings;
+ evt.getProperty = function(name) {
+ return this._bindings[name];
+ };
+ evt.setWikiInfo(wikiURL, wikiSection);
+
+ this._events.add(evt);
+ added = true;
+ }
+ node = node.nextSibling;
+ }
+
+ if (added) {
+ this._fire("onAddMany", []);
+ }
+};
+
+Timeline.DefaultEventSource.prototype.add = function(evt) {
+ this._events.add(evt);
+ this._fire("onAddOne", [evt]);
+};
+
+Timeline.DefaultEventSource.prototype.addMany = function(events) {
+ for (var i = 0; i < events.length; i++) {
+ this._events.add(events[i]);
+ }
+ this._fire("onAddMany", []);
+};
+
+Timeline.DefaultEventSource.prototype.clear = function() {
+ this._events.removeAll();
+ this._fire("onClear", []);
+};
+
+Timeline.DefaultEventSource.prototype.getEvent = function(id) {
+ return this._events.getEvent(id);
+};
+
+Timeline.DefaultEventSource.prototype.getEventIterator = function(startDate, endDate) {
+ return this._events.getIterator(startDate, endDate);
+};
+
+Timeline.DefaultEventSource.prototype.getEventReverseIterator = function(startDate, endDate) {
+ return this._events.getReverseIterator(startDate, endDate);
+};
+
+Timeline.DefaultEventSource.prototype.getAllEventIterator = function() {
+ return this._events.getAllIterator();
+};
+
+Timeline.DefaultEventSource.prototype.getCount = function() {
+ return this._events.getCount();
+};
+
+Timeline.DefaultEventSource.prototype.getEarliestDate = function() {
+ return this._events.getEarliestDate();
+};
+
+Timeline.DefaultEventSource.prototype.getLatestDate = function() {
+ return this._events.getLatestDate();
+};
+
+Timeline.DefaultEventSource.prototype._fire = function(handlerName, args) {
+ for (var i = 0; i < this._listeners.length; i++) {
+ var listener = this._listeners[i];
+ if (handlerName in listener) {
+ try {
+ listener[handlerName].apply(listener, args);
+ } catch (e) {
+ SimileAjax.Debug.exception(e);
+ }
+ }
+ }
+};
+
+Timeline.DefaultEventSource.prototype._getBaseURL = function(url) {
+ if (url.indexOf("://") < 0) {
+ var url2 = this._getBaseURL(document.location.href);
+ if (url.substr(0,1) == "/") {
+ url = url2.substr(0, url2.indexOf("/", url2.indexOf("://") + 3)) + url;
+ } else {
+ url = url2 + url;
+ }
+ }
+
+ var i = url.lastIndexOf("/");
+ if (i < 0) {
+ return "";
+ } else {
+ return url.substr(0, i+1);
+ }
+};
+
+Timeline.DefaultEventSource.prototype._resolveRelativeURL = function(url, base) {
+ if (url == null || url == "") {
+ return url;
+ } else if (url.indexOf("://") > 0) {
+ return url;
+ } else if (url.substr(0,1) == "/") {
+ return base.substr(0, base.indexOf("/", base.indexOf("://") + 3)) + url;
+ } else {
+ return base + url;
+ }
+};
+
+
+Timeline.DefaultEventSource.Event = function(
+ id,
+ start, end, latestStart, earliestEnd, instant,
+ text, description, image, link,
+ icon, color, textColor) {
+
+ id = (id) ? id.trim() : "";
+ this._id = id.length > 0 ? id : ("e" + Math.floor(Math.random() * 1000000));
+
+ this._instant = instant || (end == null);
+
+ this._start = start;
+ this._end = (end != null) ? end : start;
+
+ this._latestStart = (latestStart != null) ? latestStart : (instant ? this._end : this._start);
+ this._earliestEnd = (earliestEnd != null) ? earliestEnd : (instant ? this._start : this._end);
+
+ this._text = SimileAjax.HTML.deEntify(text);
+ this._description = SimileAjax.HTML.deEntify(description);
+ this._image = (image != null && image != "") ? image : null;
+ this._link = (link != null && link != "") ? link : null;
+
+ this._icon = (icon != null && icon != "") ? icon : null;
+ this._color = (color != null && color != "") ? color : null;
+ this._textColor = (textColor != null && textColor != "") ? textColor : null;
+
+ this._wikiURL = null;
+ this._wikiSection = null;
+};
+
+Timeline.DefaultEventSource.Event.prototype = {
+ getID: function() { return this._id; },
+
+ isInstant: function() { return this._instant; },
+ isImprecise: function() { return this._start != this._latestStart || this._end != this._earliestEnd; },
+
+ getStart: function() { return this._start; },
+ getEnd: function() { return this._end; },
+ getLatestStart: function() { return this._latestStart; },
+ getEarliestEnd: function() { return this._earliestEnd; },
+
+ getText: function() { return this._text; },
+ getDescription: function() { return this._description; },
+ getImage: function() { return this._image; },
+ getLink: function() { return this._link; },
+
+ getIcon: function() { return this._icon; },
+ getColor: function() { return this._color; },
+ getTextColor: function() { return this._textColor; },
+
+ getProperty: function(name) { return null; },
+
+ getWikiURL: function() { return this._wikiURL; },
+ getWikiSection: function() { return this._wikiSection; },
+ setWikiInfo: function(wikiURL, wikiSection) {
+ this._wikiURL = wikiURL;
+ this._wikiSection = wikiSection;
+ },
+
+ fillDescription: function(elmt) {
+ elmt.innerHTML = this._description;
+ },
+ fillWikiInfo: function(elmt) {
+ if (this._wikiURL != null && this._wikiSection != null) {
+ var wikiID = this.getProperty("wikiID");
+ if (wikiID == null || wikiID.length == 0) {
+ wikiID = this.getText();
+ }
+ wikiID = wikiID.replace(/\s/g, "_");
+
+ var url = this._wikiURL + this._wikiSection.replace(/\s/g, "_") + "/" + wikiID;
+ var a = document.createElement("a");
+ a.href = url;
+ a.target = "new";
+ a.innerHTML = Timeline.strings[Timeline.clientLocale].wikiLinkLabel;
+
+ elmt.appendChild(document.createTextNode("["));
+ elmt.appendChild(a);
+ elmt.appendChild(document.createTextNode("]"));
+ } else {
+ elmt.style.display = "none";
+ }
+ },
+ fillTime: function(elmt, labeller) {
+ if (this._instant) {
+ if (this.isImprecise()) {
+ elmt.appendChild(elmt.ownerDocument.createTextNode(labeller.labelPrecise(this._start)));
+ elmt.appendChild(elmt.ownerDocument.createElement("br"));
+ elmt.appendChild(elmt.ownerDocument.createTextNode(labeller.labelPrecise(this._end)));
+ } else {
+ elmt.appendChild(elmt.ownerDocument.createTextNode(labeller.labelPrecise(this._start)));
+ }
+ } else {
+ if (this.isImprecise()) {
+ elmt.appendChild(elmt.ownerDocument.createTextNode(
+ labeller.labelPrecise(this._start) + " ~ " + labeller.labelPrecise(this._latestStart)));
+ elmt.appendChild(elmt.ownerDocument.createElement("br"));
+ elmt.appendChild(elmt.ownerDocument.createTextNode(
+ labeller.labelPrecise(this._earliestEnd) + " ~ " + labeller.labelPrecise(this._end)));
+ } else {
+ elmt.appendChild(elmt.ownerDocument.createTextNode(labeller.labelPrecise(this._start)));
+ elmt.appendChild(elmt.ownerDocument.createElement("br"));
+ elmt.appendChild(elmt.ownerDocument.createTextNode(labeller.labelPrecise(this._end)));
+ }
+ }
+ },
+ fillInfoBubble: function(elmt, theme, labeller) {
+ var doc = elmt.ownerDocument;
+
+ var title = this.getText();
+ var link = this.getLink();
+ var image = this.getImage();
+
+ if (image != null) {
+ var img = doc.createElement("img");
+ img.src = image;
+
+ theme.event.bubble.imageStyler(img);
+ elmt.appendChild(img);
+ }
+
+ var divTitle = doc.createElement("div");
+ var textTitle = doc.createTextNode(title);
+ if (link != null) {
+ var a = doc.createElement("a");
+ a.href = link;
+ a.appendChild(textTitle);
+ divTitle.appendChild(a);
+ } else {
+ divTitle.appendChild(textTitle);
+ }
+ theme.event.bubble.titleStyler(divTitle);
+ elmt.appendChild(divTitle);
+
+ var divBody = doc.createElement("div");
+ this.fillDescription(divBody);
+ theme.event.bubble.bodyStyler(divBody);
+ elmt.appendChild(divBody);
+
+ var divTime = doc.createElement("div");
+ this.fillTime(divTime, labeller);
+ theme.event.bubble.timeStyler(divTime);
+ elmt.appendChild(divTime);
+
+ var divWiki = doc.createElement("div");
+ this.fillWikiInfo(divWiki);
+ theme.event.bubble.wikiStyler(divWiki);
+ elmt.appendChild(divWiki);
+ }
+};/*==================================================
+ * Original Event Painter
+ *==================================================
+ */
+
+Timeline.OriginalEventPainter = function(params) {
+ this._params = params;
+ this._onSelectListeners = [];
+
+ this._filterMatcher = null;
+ this._highlightMatcher = null;
+ this._frc = null;
+
+ this._eventIdToElmt = {};
+};
+
+Timeline.OriginalEventPainter.prototype.initialize = function(band, timeline) {
+ this._band = band;
+ this._timeline = timeline;
+
+ this._backLayer = null;
+ this._eventLayer = null;
+ this._lineLayer = null;
+ this._highlightLayer = null;
+
+ this._eventIdToElmt = null;
+};
+
+Timeline.OriginalEventPainter.prototype.addOnSelectListener = function(listener) {
+ this._onSelectListeners.push(listener);
+};
+
+Timeline.OriginalEventPainter.prototype.removeOnSelectListener = function(listener) {
+ for (var i = 0; i < this._onSelectListeners.length; i++) {
+ if (this._onSelectListeners[i] == listener) {
+ this._onSelectListeners.splice(i, 1);
+ break;
+ }
+ }
+};
+
+Timeline.OriginalEventPainter.prototype.getFilterMatcher = function() {
+ return this._filterMatcher;
+};
+
+Timeline.OriginalEventPainter.prototype.setFilterMatcher = function(filterMatcher) {
+ this._filterMatcher = filterMatcher;
+};
+
+Timeline.OriginalEventPainter.prototype.getHighlightMatcher = function() {
+ return this._highlightMatcher;
+};
+
+Timeline.OriginalEventPainter.prototype.setHighlightMatcher = function(highlightMatcher) {
+ this._highlightMatcher = highlightMatcher;
+};
+
+Timeline.OriginalEventPainter.prototype.paint = function() {
+ var eventSource = this._band.getEventSource();
+ if (eventSource == null) {
+ return;
+ }
+
+ this._eventIdToElmt = {};
+ this._prepareForPainting();
+
+ var eventTheme = this._params.theme.event;
+ var trackHeight = Math.max(eventTheme.track.height, eventTheme.tape.height + this._frc.getLineHeight());
+ var metrics = {
+ trackOffset: eventTheme.track.gap,
+ trackHeight: trackHeight,
+ trackGap: eventTheme.track.gap,
+ trackIncrement: trackHeight + eventTheme.track.gap,
+ icon: eventTheme.instant.icon,
+ iconWidth: eventTheme.instant.iconWidth,
+ iconHeight: eventTheme.instant.iconHeight,
+ labelWidth: eventTheme.label.width
+ }
+
+ var minDate = this._band.getMinDate();
+ var maxDate = this._band.getMaxDate();
+
+ var filterMatcher = (this._filterMatcher != null) ?
+ this._filterMatcher :
+ function(evt) { return true; };
+ var highlightMatcher = (this._highlightMatcher != null) ?
+ this._highlightMatcher :
+ function(evt) { return -1; };
+
+ var iterator = eventSource.getEventReverseIterator(minDate, maxDate);
+ while (iterator.hasNext()) {
+ var evt = iterator.next();
+ if (filterMatcher(evt)) {
+ this.paintEvent(evt, metrics, this._params.theme, highlightMatcher(evt));
+ }
+ }
+
+ this._highlightLayer.style.display = "block";
+ this._lineLayer.style.display = "block";
+ this._eventLayer.style.display = "block";
+};
+
+Timeline.OriginalEventPainter.prototype.softPaint = function() {
+};
+
+Timeline.OriginalEventPainter.prototype._prepareForPainting = function() {
+ var band = this._band;
+
+ if (this._backLayer == null) {
+ this._backLayer = this._band.createLayerDiv(0, "timeline-band-events");
+ this._backLayer.style.visibility = "hidden";
+
+ var eventLabelPrototype = document.createElement("span");
+ eventLabelPrototype.className = "timeline-event-label";
+ this._backLayer.appendChild(eventLabelPrototype);
+ this._frc = SimileAjax.Graphics.getFontRenderingContext(eventLabelPrototype);
+ }
+ this._frc.update();
+ this._tracks = [];
+
+ if (this._highlightLayer != null) {
+ band.removeLayerDiv(this._highlightLayer);
+ }
+ this._highlightLayer = band.createLayerDiv(105, "timeline-band-highlights");
+ this._highlightLayer.style.display = "none";
+
+ if (this._lineLayer != null) {
+ band.removeLayerDiv(this._lineLayer);
+ }
+ this._lineLayer = band.createLayerDiv(110, "timeline-band-lines");
+ this._lineLayer.style.display = "none";
+
+ if (this._eventLayer != null) {
+ band.removeLayerDiv(this._eventLayer);
+ }
+ this._eventLayer = band.createLayerDiv(115, "timeline-band-events");
+ this._eventLayer.style.display = "none";
+};
+
+Timeline.OriginalEventPainter.prototype.paintEvent = function(evt, metrics, theme, highlightIndex) {
+ if (evt.isInstant()) {
+ this.paintInstantEvent(evt, metrics, theme, highlightIndex);
+ } else {
+ this.paintDurationEvent(evt, metrics, theme, highlightIndex);
+ }
+};
+
+Timeline.OriginalEventPainter.prototype.paintInstantEvent = function(evt, metrics, theme, highlightIndex) {
+ if (evt.isImprecise()) {
+ this.paintImpreciseInstantEvent(evt, metrics, theme, highlightIndex);
+ } else {
+ this.paintPreciseInstantEvent(evt, metrics, theme, highlightIndex);
+ }
+}
+
+Timeline.OriginalEventPainter.prototype.paintDurationEvent = function(evt, metrics, theme, highlightIndex) {
+ if (evt.isImprecise()) {
+ this.paintImpreciseDurationEvent(evt, metrics, theme, highlightIndex);
+ } else {
+ this.paintPreciseDurationEvent(evt, metrics, theme, highlightIndex);
+ }
+}
+
+Timeline.OriginalEventPainter.prototype.paintPreciseInstantEvent = function(evt, metrics, theme, highlightIndex) {
+ var doc = this._timeline.getDocument();
+ var text = evt.getText();
+
+ var startDate = evt.getStart();
+ var startPixel = Math.round(this._band.dateToPixelOffset(startDate));
+ var iconRightEdge = Math.round(startPixel + metrics.iconWidth / 2);
+ var iconLeftEdge = Math.round(startPixel - metrics.iconWidth / 2);
+
+ var labelSize = this._frc.computeSize(text);
+ var labelLeft = iconRightEdge + theme.event.label.offsetFromLine;
+ var labelRight = labelLeft + labelSize.width;
+
+ var rightEdge = labelRight;
+ var track = this._findFreeTrack(rightEdge);
+
+ var labelTop = Math.round(
+ metrics.trackOffset + track * metrics.trackIncrement +
+ metrics.trackHeight / 2 - labelSize.height / 2);
+
+ var iconElmtData = this._paintEventIcon(evt, track, iconLeftEdge, metrics, theme);
+ var labelElmtData = this._paintEventLabel(evt, text, labelLeft, labelTop, labelSize.width, labelSize.height, theme);
+
+ var self = this;
+ var clickHandler = function(elmt, domEvt, target) {
+ return self._onClickInstantEvent(iconElmtData.elmt, domEvt, evt);
+ };
+ SimileAjax.DOM.registerEvent(iconElmtData.elmt, "mousedown", clickHandler);
+ SimileAjax.DOM.registerEvent(labelElmtData.elmt, "mousedown", clickHandler);
+
+ this._createHighlightDiv(highlightIndex, iconElmtData, theme);
+
+ this._eventIdToElmt[evt.getID()] = iconElmtData.elmt;
+ this._tracks[track] = iconLeftEdge;
+};
+
+Timeline.OriginalEventPainter.prototype.paintImpreciseInstantEvent = function(evt, metrics, theme, highlightIndex) {
+ var doc = this._timeline.getDocument();
+ var text = evt.getText();
+
+ var startDate = evt.getStart();
+ var endDate = evt.getEnd();
+ var startPixel = Math.round(this._band.dateToPixelOffset(startDate));
+ var endPixel = Math.round(this._band.dateToPixelOffset(endDate));
+
+ var iconRightEdge = Math.round(startPixel + metrics.iconWidth / 2);
+ var iconLeftEdge = Math.round(startPixel - metrics.iconWidth / 2);
+
+ var labelSize = this._frc.computeSize(text);
+ var labelLeft = iconRightEdge + theme.event.label.offsetFromLine;
+ var labelRight = labelLeft + labelSize.width;
+
+ var rightEdge = Math.max(labelRight, endPixel);
+ var track = this._findFreeTrack(rightEdge);
+ var labelTop = Math.round(
+ metrics.trackOffset + track * metrics.trackIncrement +
+ metrics.trackHeight / 2 - labelSize.height / 2);
+
+ var iconElmtData = this._paintEventIcon(evt, track, iconLeftEdge, metrics, theme);
+ var labelElmtData = this._paintEventLabel(evt, text, labelLeft, labelTop, labelSize.width, labelSize.height, theme);
+ var tapeElmtData = this._paintEventTape(evt, track, startPixel, endPixel,
+ theme.event.instant.impreciseColor, theme.event.instant.impreciseOpacity, metrics, theme);
+
+ var self = this;
+ var clickHandler = function(elmt, domEvt, target) {
+ return self._onClickInstantEvent(iconElmtData.elmt, domEvt, evt);
+ };
+ SimileAjax.DOM.registerEvent(iconElmtData.elmt, "mousedown", clickHandler);
+ SimileAjax.DOM.registerEvent(tapeElmtData.elmt, "mousedown", clickHandler);
+ SimileAjax.DOM.registerEvent(labelElmtData.elmt, "mousedown", clickHandler);
+
+ this._createHighlightDiv(highlightIndex, iconElmtData, theme);
+
+ this._eventIdToElmt[evt.getID()] = iconElmtData.elmt;
+ this._tracks[track] = iconLeftEdge;
+};
+
+Timeline.OriginalEventPainter.prototype.paintPreciseDurationEvent = function(evt, metrics, theme, highlightIndex) {
+ var doc = this._timeline.getDocument();
+ var text = evt.getText();
+
+ var startDate = evt.getStart();
+ var endDate = evt.getEnd();
+ var startPixel = Math.round(this._band.dateToPixelOffset(startDate));
+ var endPixel = Math.round(this._band.dateToPixelOffset(endDate));
+
+ var labelSize = this._frc.computeSize(text);
+ var labelLeft = startPixel;
+ var labelRight = labelLeft + labelSize.width;
+
+ var rightEdge = Math.max(labelRight, endPixel);
+ var track = this._findFreeTrack(rightEdge);
+ var labelTop = Math.round(
+ metrics.trackOffset + track * metrics.trackIncrement + theme.event.tape.height);
+
+ var color = evt.getColor();
+ color = color != null ? color : theme.event.duration.color;
+
+ var tapeElmtData = this._paintEventTape(evt, track, startPixel, endPixel, color, 100, metrics, theme);
+ var labelElmtData = this._paintEventLabel(evt, text, labelLeft, labelTop, labelSize.width, labelSize.height, theme);
+
+ var self = this;
+ var clickHandler = function(elmt, domEvt, target) {
+ return self._onClickInstantEvent(tapeElmtData.elmt, domEvt, evt);
+ };
+ SimileAjax.DOM.registerEvent(tapeElmtData.elmt, "mousedown", clickHandler);
+ SimileAjax.DOM.registerEvent(labelElmtData.elmt, "mousedown", clickHandler);
+
+ this._createHighlightDiv(highlightIndex, tapeElmtData, theme);
+
+ this._eventIdToElmt[evt.getID()] = tapeElmtData.elmt;
+ this._tracks[track] = startPixel;
+};
+
+Timeline.OriginalEventPainter.prototype.paintImpreciseDurationEvent = function(evt, metrics, theme, highlightIndex) {
+ var doc = this._timeline.getDocument();
+ var text = evt.getText();
+
+ var startDate = evt.getStart();
+ var latestStartDate = evt.getLatestStart();
+ var endDate = evt.getEnd();
+ var earliestEndDate = evt.getEarliestEnd();
+
+ var startPixel = Math.round(this._band.dateToPixelOffset(startDate));
+ var latestStartPixel = Math.round(this._band.dateToPixelOffset(latestStartDate));
+ var endPixel = Math.round(this._band.dateToPixelOffset(endDate));
+ var earliestEndPixel = Math.round(this._band.dateToPixelOffset(earliestEndDate));
+
+ var labelSize = this._frc.computeSize(text);
+ var labelLeft = latestStartPixel;
+ var labelRight = labelLeft + labelSize.width;
+
+ var rightEdge = Math.max(labelRight, endPixel);
+ var track = this._findFreeTrack(rightEdge);
+ var labelTop = Math.round(
+ metrics.trackOffset + track * metrics.trackIncrement + theme.event.tape.height);
+
+ var color = evt.getColor();
+ color = color != null ? color : theme.event.duration.color;
+
+ var impreciseTapeElmtData = this._paintEventTape(evt, track, startPixel, endPixel,
+ theme.event.duration.impreciseColor, theme.event.duration.impreciseOpacity, metrics, theme);
+ var tapeElmtData = this._paintEventTape(evt, track, latestStartPixel, earliestEndPixel, color, 100, metrics, theme);
+
+ var labelElmtData = this._paintEventLabel(evt, text, labelLeft, labelTop, labelSize.width, labelSize.height, theme);
+
+ var self = this;
+ var clickHandler = function(elmt, domEvt, target) {
+ return self._onClickInstantEvent(tapeElmtData.elmt, domEvt, evt);
+ };
+ SimileAjax.DOM.registerEvent(tapeElmtData.elmt, "mousedown", clickHandler);
+ SimileAjax.DOM.registerEvent(labelElmtData.elmt, "mousedown", clickHandler);
+
+ this._createHighlightDiv(highlightIndex, tapeElmtData, theme);
+
+ this._eventIdToElmt[evt.getID()] = tapeElmtData.elmt;
+ this._tracks[track] = startPixel;
+};
+
+Timeline.OriginalEventPainter.prototype._findFreeTrack = function(rightEdge) {
+ for (var i = 0; i < this._tracks.length; i++) {
+ var t = this._tracks[i];
+ if (t > rightEdge) {
+ break;
+ }
+ }
+ return i;
+};
+
+Timeline.OriginalEventPainter.prototype._paintEventIcon = function(evt, iconTrack, left, metrics, theme) {
+ var icon = evt.getIcon();
+ icon = icon != null ? icon : metrics.icon;
+
+ var middle = metrics.trackOffset + iconTrack * metrics.trackIncrement + metrics.trackHeight / 2;
+ var top = Math.round(middle - metrics.iconHeight / 2);
+
+ var img = SimileAjax.Graphics.createTranslucentImage(icon);
+ var iconDiv = this._timeline.getDocument().createElement("div");
+ iconDiv.style.position = "absolute";
+ iconDiv.style.left = left + "px";
+ iconDiv.style.top = top + "px";
+ iconDiv.appendChild(img);
+ iconDiv.style.cursor = "pointer";
+ this._eventLayer.appendChild(iconDiv);
+
+ return {
+ left: left,
+ top: top,
+ width: metrics.iconWidth,
+ height: metrics.iconHeight,
+ elmt: iconDiv
+ };
+};
+
+Timeline.OriginalEventPainter.prototype._paintEventLabel = function(evt, text, left, top, width, height, theme) {
+ var doc = this._timeline.getDocument();
+
+ var labelDiv = doc.createElement("div");
+ labelDiv.style.position = "absolute";
+ labelDiv.style.left = left + "px";
+ labelDiv.style.width = width + "px";
+ labelDiv.style.top = top + "px";
+ labelDiv.innerHTML = text;
+ labelDiv.style.cursor = "pointer";
+
+ var color = evt.getTextColor();
+ if (color == null) {
+ color = evt.getColor();
+ }
+ if (color != null) {
+ labelDiv.style.color = color;
+ }
+
+ this._eventLayer.appendChild(labelDiv);
+
+ return {
+ left: left,
+ top: top,
+ width: width,
+ height: height,
+ elmt: labelDiv
+ };
+};
+
+Timeline.OriginalEventPainter.prototype._paintEventTape = function(
+ evt, iconTrack, startPixel, endPixel, color, opacity, metrics, theme) {
+
+ var tapeWidth = endPixel - startPixel;
+ var tapeHeight = theme.event.tape.height;
+ var top = metrics.trackOffset + iconTrack * metrics.trackIncrement;
+
+ var tapeDiv = this._timeline.getDocument().createElement("div");
+ tapeDiv.style.position = "absolute";
+ tapeDiv.style.left = startPixel + "px";
+ tapeDiv.style.width = tapeWidth + "px";
+ tapeDiv.style.top = top + "px";
+ tapeDiv.style.height = tapeHeight + "px";
+ tapeDiv.style.backgroundColor = color;
+ tapeDiv.style.overflow = "hidden";
+ tapeDiv.style.cursor = "pointer";
+ SimileAjax.Graphics.setOpacity(tapeDiv, opacity);
+
+ this._eventLayer.appendChild(tapeDiv);
+
+ return {
+ left: startPixel,
+ top: top,
+ width: tapeWidth,
+ height: tapeHeight,
+ elmt: tapeDiv
+ };
+}
+
+Timeline.OriginalEventPainter.prototype._createHighlightDiv = function(highlightIndex, dimensions, theme) {
+ if (highlightIndex >= 0) {
+ var doc = this._timeline.getDocument();
+ var eventTheme = theme.event;
+
+ var color = eventTheme.highlightColors[Math.min(highlightIndex, eventTheme.highlightColors.length - 1)];
+
+ var div = doc.createElement("div");
+ div.style.position = "absolute";
+ div.style.overflow = "hidden";
+ div.style.left = (dimensions.left - 2) + "px";
+ div.style.width = (dimensions.width + 4) + "px";
+ div.style.top = (dimensions.top - 2) + "px";
+ div.style.height = (dimensions.height + 4) + "px";
+ div.style.background = color;
+
+ this._highlightLayer.appendChild(div);
+ }
+};
+
+Timeline.OriginalEventPainter.prototype._onClickInstantEvent = function(icon, domEvt, evt) {
+ var c = SimileAjax.DOM.getPageCoordinates(icon);
+ this._showBubble(
+ c.left + Math.ceil(icon.offsetWidth / 2),
+ c.top + Math.ceil(icon.offsetHeight / 2),
+ evt
+ );
+ this._fireOnSelect(evt.getID());
+
+ domEvt.cancelBubble = true;
+ SimileAjax.DOM.cancelEvent(domEvt);
+ return false;
+};
+
+Timeline.OriginalEventPainter.prototype._onClickDurationEvent = function(target, domEvt, evt) {
+ if ("pageX" in domEvt) {
+ var x = domEvt.pageX;
+ var y = domEvt.pageY;
+ } else {
+ var c = SimileAjax.DOM.getPageCoordinates(target);
+ var x = domEvt.offsetX + c.left;
+ var y = domEvt.offsetY + c.top;
+ }
+ this._showBubble(x, y, evt);
+ this._fireOnSelect(evt.getID());
+
+ domEvt.cancelBubble = true;
+ SimileAjax.DOM.cancelEvent(domEvt);
+ return false;
+};
+
+Timeline.OriginalEventPainter.prototype.showBubble = function(evt) {
+ var elmt = this._eventIdToElmt[evt.getID()];
+ if (elmt) {
+ var c = SimileAjax.DOM.getPageCoordinates(elmt);
+ this._showBubble(c.left + elmt.offsetWidth / 2, c.top + elmt.offsetHeight / 2, evt);
+ }
+};
+
+Timeline.OriginalEventPainter.prototype._showBubble = function(x, y, evt) {
+ var div = document.createElement("div");
+ evt.fillInfoBubble(div, this._params.theme, this._band.getLabeller());
+
+ SimileAjax.WindowManager.cancelPopups();
+ SimileAjax.Graphics.createBubbleForContentAndPoint(div, x, y, this._params.theme.event.bubble.width);
+};
+
+Timeline.OriginalEventPainter.prototype._fireOnSelect = function(eventID) {
+ for (var i = 0; i < this._onSelectListeners.length; i++) {
+ this._onSelectListeners[i](eventID);
+ }
+};
+/*==================================================
+ * Detailed Event Painter
+ *==================================================
+ */
+
+Timeline.DetailedEventPainter = function(params) {
+ this._params = params;
+ this._onSelectListeners = [];
+
+ this._filterMatcher = null;
+ this._highlightMatcher = null;
+ this._frc = null;
+
+ this._eventIdToElmt = {};
+};
+
+Timeline.DetailedEventPainter.prototype.initialize = function(band, timeline) {
+ this._band = band;
+ this._timeline = timeline;
+
+ this._backLayer = null;
+ this._eventLayer = null;
+ this._lineLayer = null;
+ this._highlightLayer = null;
+
+ this._eventIdToElmt = null;
+};
+
+Timeline.DetailedEventPainter.prototype.addOnSelectListener = function(listener) {
+ this._onSelectListeners.push(listener);
+};
+
+Timeline.DetailedEventPainter.prototype.removeOnSelectListener = function(listener) {
+ for (var i = 0; i < this._onSelectListeners.length; i++) {
+ if (this._onSelectListeners[i] == listener) {
+ this._onSelectListeners.splice(i, 1);
+ break;
+ }
+ }
+};
+
+Timeline.DetailedEventPainter.prototype.getFilterMatcher = function() {
+ return this._filterMatcher;
+};
+
+Timeline.DetailedEventPainter.prototype.setFilterMatcher = function(filterMatcher) {
+ this._filterMatcher = filterMatcher;
+};
+
+Timeline.DetailedEventPainter.prototype.getHighlightMatcher = function() {
+ return this._highlightMatcher;
+};
+
+Timeline.DetailedEventPainter.prototype.setHighlightMatcher = function(highlightMatcher) {
+ this._highlightMatcher = highlightMatcher;
+};
+
+Timeline.DetailedEventPainter.prototype.paint = function() {
+ var eventSource = this._band.getEventSource();
+ if (eventSource == null) {
+ return;
+ }
+
+ this._eventIdToElmt = {};
+ this._prepareForPainting();
+
+ var eventTheme = this._params.theme.event;
+ var trackHeight = Math.max(eventTheme.track.height, this._frc.getLineHeight());
+ var metrics = {
+ trackOffset: Math.round(this._band.getViewWidth() / 2 - trackHeight / 2),
+ trackHeight: trackHeight,
+ trackGap: eventTheme.track.gap,
+ trackIncrement: trackHeight + eventTheme.track.gap,
+ icon: eventTheme.instant.icon,
+ iconWidth: eventTheme.instant.iconWidth,
+ iconHeight: eventTheme.instant.iconHeight,
+ labelWidth: eventTheme.label.width
+ }
+
+ var minDate = this._band.getMinDate();
+ var maxDate = this._band.getMaxDate();
+
+ var filterMatcher = (this._filterMatcher != null) ?
+ this._filterMatcher :
+ function(evt) { return true; };
+ var highlightMatcher = (this._highlightMatcher != null) ?
+ this._highlightMatcher :
+ function(evt) { return -1; };
+
+ var iterator = eventSource.getEventReverseIterator(minDate, maxDate);
+ while (iterator.hasNext()) {
+ var evt = iterator.next();
+ if (filterMatcher(evt)) {
+ this.paintEvent(evt, metrics, this._params.theme, highlightMatcher(evt));
+ }
+ }
+
+ this._highlightLayer.style.display = "block";
+ this._lineLayer.style.display = "block";
+ this._eventLayer.style.display = "block";
+};
+
+Timeline.DetailedEventPainter.prototype.softPaint = function() {
+};
+
+Timeline.DetailedEventPainter.prototype._prepareForPainting = function() {
+ var band = this._band;
+
+ if (this._backLayer == null) {
+ this._backLayer = this._band.createLayerDiv(0, "timeline-band-events");
+ this._backLayer.style.visibility = "hidden";
+
+ var eventLabelPrototype = document.createElement("span");
+ eventLabelPrototype.className = "timeline-event-label";
+ this._backLayer.appendChild(eventLabelPrototype);
+ this._frc = SimileAjax.Graphics.getFontRenderingContext(eventLabelPrototype);
+ }
+ this._frc.update();
+ this._lowerTracks = [];
+ this._upperTracks = [];
+
+ if (this._highlightLayer != null) {
+ band.removeLayerDiv(this._highlightLayer);
+ }
+ this._highlightLayer = band.createLayerDiv(105, "timeline-band-highlights");
+ this._highlightLayer.style.display = "none";
+
+ if (this._lineLayer != null) {
+ band.removeLayerDiv(this._lineLayer);
+ }
+ this._lineLayer = band.createLayerDiv(110, "timeline-band-lines");
+ this._lineLayer.style.display = "none";
+
+ if (this._eventLayer != null) {
+ band.removeLayerDiv(this._eventLayer);
+ }
+ this._eventLayer = band.createLayerDiv(110, "timeline-band-events");
+ this._eventLayer.style.display = "none";
+};
+
+Timeline.DetailedEventPainter.prototype.paintEvent = function(evt, metrics, theme, highlightIndex) {
+ if (evt.isInstant()) {
+ this.paintInstantEvent(evt, metrics, theme, highlightIndex);
+ } else {
+ this.paintDurationEvent(evt, metrics, theme, highlightIndex);
+ }
+};
+
+Timeline.DetailedEventPainter.prototype.paintInstantEvent = function(evt, metrics, theme, highlightIndex) {
+ if (evt.isImprecise()) {
+ this.paintImpreciseInstantEvent(evt, metrics, theme, highlightIndex);
+ } else {
+ this.paintPreciseInstantEvent(evt, metrics, theme, highlightIndex);
+ }
+}
+
+Timeline.DetailedEventPainter.prototype.paintDurationEvent = function(evt, metrics, theme, highlightIndex) {
+ if (evt.isImprecise()) {
+ this.paintImpreciseDurationEvent(evt, metrics, theme, highlightIndex);
+ } else {
+ this.paintPreciseDurationEvent(evt, metrics, theme, highlightIndex);
+ }
+}
+
+Timeline.DetailedEventPainter.prototype.paintPreciseInstantEvent = function(evt, metrics, theme, highlightIndex) {
+ var doc = this._timeline.getDocument();
+ var text = evt.getText();
+
+ var startDate = evt.getStart();
+ var startPixel = Math.round(this._band.dateToPixelOffset(startDate));
+ var iconRightEdge = Math.round(startPixel + metrics.iconWidth / 2);
+ var iconLeftEdge = Math.round(startPixel - metrics.iconWidth / 2);
+
+ var labelSize = this._frc.computeSize(text);
+ var iconTrack = this._findFreeTrackForSolid(iconRightEdge, startPixel);
+ var iconElmtData = this._paintEventIcon(evt, iconTrack, iconLeftEdge, metrics, theme);
+
+ var labelLeft = iconRightEdge + theme.event.label.offsetFromLine;
+ var labelTrack = iconTrack;
+
+ var iconTrackData = this._getTrackData(iconTrack);
+ if (Math.min(iconTrackData.solid, iconTrackData.text) >= labelLeft + labelSize.width) { // label on the same track, to the right of icon
+ iconTrackData.solid = iconLeftEdge;
+ iconTrackData.text = labelLeft;
+ } else { // label on a different track, below icon
+ iconTrackData.solid = iconLeftEdge;
+
+ labelLeft = startPixel + theme.event.label.offsetFromLine;
+ labelTrack = this._findFreeTrackForText(iconTrack, labelLeft + labelSize.width, function(t) { t.line = startPixel - 2; });
+ this._getTrackData(labelTrack).text = iconLeftEdge;
+
+ this._paintEventLine(evt, startPixel, iconTrack, labelTrack, metrics, theme);
+ }
+
+ var labelTop = Math.round(
+ metrics.trackOffset + labelTrack * metrics.trackIncrement +
+ metrics.trackHeight / 2 - labelSize.height / 2);
+
+ var labelElmtData = this._paintEventLabel(evt, text, labelLeft, labelTop, labelSize.width, labelSize.height, theme);
+
+ var self = this;
+ var clickHandler = function(elmt, domEvt, target) {
+ return self._onClickInstantEvent(iconElmtData.elmt, domEvt, evt);
+ };
+ SimileAjax.DOM.registerEvent(iconElmtData.elmt, "mousedown", clickHandler);
+ SimileAjax.DOM.registerEvent(labelElmtData.elmt, "mousedown", clickHandler);
+
+ this._createHighlightDiv(highlightIndex, iconElmtData, theme);
+
+ this._eventIdToElmt[evt.getID()] = iconElmtData.elmt;
+};
+
+Timeline.DetailedEventPainter.prototype.paintImpreciseInstantEvent = function(evt, metrics, theme, highlightIndex) {
+ var doc = this._timeline.getDocument();
+ var text = evt.getText();
+
+ var startDate = evt.getStart();
+ var endDate = evt.getEnd();
+ var startPixel = Math.round(this._band.dateToPixelOffset(startDate));
+ var endPixel = Math.round(this._band.dateToPixelOffset(endDate));
+
+ var iconRightEdge = Math.round(startPixel + metrics.iconWidth / 2);
+ var iconLeftEdge = Math.round(startPixel - metrics.iconWidth / 2);
+
+ var labelSize = this._frc.computeSize(text);
+ var iconTrack = this._findFreeTrackForSolid(endPixel, startPixel);
+
+ var tapeElmtData = this._paintEventTape(evt, iconTrack, startPixel, endPixel,
+ theme.event.instant.impreciseColor, theme.event.instant.impreciseOpacity, metrics, theme);
+ var iconElmtData = this._paintEventIcon(evt, iconTrack, iconLeftEdge, metrics, theme);
+
+ var iconTrackData = this._getTrackData(iconTrack);
+ iconTrackData.solid = iconLeftEdge;
+
+ var labelLeft = iconRightEdge + theme.event.label.offsetFromLine;
+ var labelRight = labelLeft + labelSize.width;
+ var labelTrack;
+ if (labelRight < endPixel) {
+ labelTrack = iconTrack;
+ } else {
+ labelLeft = startPixel + theme.event.label.offsetFromLine;
+ labelRight = labelLeft + labelSize.width;
+
+ labelTrack = this._findFreeTrackForText(iconTrack, labelRight, function(t) { t.line = startPixel - 2; });
+ this._getTrackData(labelTrack).text = iconLeftEdge;
+
+ this._paintEventLine(evt, startPixel, iconTrack, labelTrack, metrics, theme);
+ }
+ var labelTop = Math.round(
+ metrics.trackOffset + labelTrack * metrics.trackIncrement +
+ metrics.trackHeight / 2 - labelSize.height / 2);
+
+ var labelElmtData = this._paintEventLabel(evt, text, labelLeft, labelTop, labelSize.width, labelSize.height, theme);
+
+ var self = this;
+ var clickHandler = function(elmt, domEvt, target) {
+ return self._onClickInstantEvent(iconElmtData.elmt, domEvt, evt);
+ };
+ SimileAjax.DOM.registerEvent(iconElmtData.elmt, "mousedown", clickHandler);
+ SimileAjax.DOM.registerEvent(tapeElmtData.elmt, "mousedown", clickHandler);
+ SimileAjax.DOM.registerEvent(labelElmtData.elmt, "mousedown", clickHandler);
+
+ this._createHighlightDiv(highlightIndex, iconElmtData, theme);
+
+ this._eventIdToElmt[evt.getID()] = iconElmtData.elmt;
+};
+
+Timeline.DetailedEventPainter.prototype.paintPreciseDurationEvent = function(evt, metrics, theme, highlightIndex) {
+ var doc = this._timeline.getDocument();
+ var text = evt.getText();
+
+ var startDate = evt.getStart();
+ var endDate = evt.getEnd();
+ var startPixel = Math.round(this._band.dateToPixelOffset(startDate));
+ var endPixel = Math.round(this._band.dateToPixelOffset(endDate));
+
+ var labelSize = this._frc.computeSize(text);
+ var tapeTrack = this._findFreeTrackForSolid(endPixel);
+ var color = evt.getColor();
+ color = color != null ? color : theme.event.duration.color;
+
+ var tapeElmtData = this._paintEventTape(evt, tapeTrack, startPixel, endPixel, color, 100, metrics, theme);
+
+ var tapeTrackData = this._getTrackData(tapeTrack);
+ tapeTrackData.solid = startPixel;
+
+ var labelLeft = startPixel + theme.event.label.offsetFromLine;
+ var labelTrack = this._findFreeTrackForText(tapeTrack, labelLeft + labelSize.width, function(t) { t.line = startPixel - 2; });
+ this._getTrackData(labelTrack).text = startPixel - 2;
+
+ this._paintEventLine(evt, startPixel, tapeTrack, labelTrack, metrics, theme);
+
+ var labelTop = Math.round(
+ metrics.trackOffset + labelTrack * metrics.trackIncrement +
+ metrics.trackHeight / 2 - labelSize.height / 2);
+
+ var labelElmtData = this._paintEventLabel(evt, text, labelLeft, labelTop, labelSize.width, labelSize.height, theme);
+
+ var self = this;
+ var clickHandler = function(elmt, domEvt, target) {
+ return self._onClickDurationEvent(tapeElmtData.elmt, domEvt, evt);
+ };
+ SimileAjax.DOM.registerEvent(tapeElmtData.elmt, "mousedown", clickHandler);
+ SimileAjax.DOM.registerEvent(labelElmtData.elmt, "mousedown", clickHandler);
+
+ this._createHighlightDiv(highlightIndex, tapeElmtData, theme);
+
+ this._eventIdToElmt[evt.getID()] = tapeElmtData.elmt;
+};
+
+Timeline.DetailedEventPainter.prototype.paintImpreciseDurationEvent = function(evt, metrics, theme, highlightIndex) {
+ var doc = this._timeline.getDocument();
+ var text = evt.getText();
+
+ var startDate = evt.getStart();
+ var latestStartDate = evt.getLatestStart();
+ var endDate = evt.getEnd();
+ var earliestEndDate = evt.getEarliestEnd();
+
+ var startPixel = Math.round(this._band.dateToPixelOffset(startDate));
+ var latestStartPixel = Math.round(this._band.dateToPixelOffset(latestStartDate));
+ var endPixel = Math.round(this._band.dateToPixelOffset(endDate));
+ var earliestEndPixel = Math.round(this._band.dateToPixelOffset(earliestEndDate));
+
+ var labelSize = this._frc.computeSize(text);
+ var tapeTrack = this._findFreeTrackForSolid(endPixel);
+ var color = evt.getColor();
+ color = color != null ? color : theme.event.duration.color;
+
+ var impreciseTapeElmtData = this._paintEventTape(evt, tapeTrack, startPixel, endPixel,
+ theme.event.duration.impreciseColor, theme.event.duration.impreciseOpacity, metrics, theme);
+ var tapeElmtData = this._paintEventTape(evt, tapeTrack, latestStartPixel, earliestEndPixel, color, 100, metrics, theme);
+
+ var tapeTrackData = this._getTrackData(tapeTrack);
+ tapeTrackData.solid = startPixel;
+
+ var labelLeft = latestStartPixel + theme.event.label.offsetFromLine;
+ var labelTrack = this._findFreeTrackForText(tapeTrack, labelLeft + labelSize.width, function(t) { t.line = latestStartPixel - 2; });
+ this._getTrackData(labelTrack).text = latestStartPixel - 2;
+
+ this._paintEventLine(evt, latestStartPixel, tapeTrack, labelTrack, metrics, theme);
+
+ var labelTop = Math.round(
+ metrics.trackOffset + labelTrack * metrics.trackIncrement +
+ metrics.trackHeight / 2 - labelSize.height / 2);
+
+ var labelElmtData = this._paintEventLabel(evt, text, labelLeft, labelTop, labelSize.width, labelSize.height, theme);
+
+ var self = this;
+ var clickHandler = function(elmt, domEvt, target) {
+ return self._onClickDurationEvent(tapeElmtData.elmt, domEvt, evt);
+ };
+ SimileAjax.DOM.registerEvent(tapeElmtData.elmt, "mousedown", clickHandler);
+ SimileAjax.DOM.registerEvent(labelElmtData.elmt, "mousedown", clickHandler);
+
+ this._createHighlightDiv(highlightIndex, tapeElmtData, theme);
+
+ this._eventIdToElmt[evt.getID()] = tapeElmtData.elmt;
+};
+
+Timeline.DetailedEventPainter.prototype._findFreeTrackForSolid = function(solidEdge, softEdge) {
+ for (var i = 0; true; i++) {
+ if (i < this._lowerTracks.length) {
+ var t = this._lowerTracks[i];
+ if (Math.min(t.solid, t.text) > solidEdge && (!(softEdge) || t.line > softEdge)) {
+ return i;
+ }
+ } else {
+ this._lowerTracks.push({
+ solid: Number.POSITIVE_INFINITY,
+ text: Number.POSITIVE_INFINITY,
+ line: Number.POSITIVE_INFINITY
+ });
+
+ return i;
+ }
+
+ if (i < this._upperTracks.length) {
+ var t = this._upperTracks[i];
+ if (Math.min(t.solid, t.text) > solidEdge && (!(softEdge) || t.line > softEdge)) {
+ return -1 - i;
+ }
+ } else {
+ this._upperTracks.push({
+ solid: Number.POSITIVE_INFINITY,
+ text: Number.POSITIVE_INFINITY,
+ line: Number.POSITIVE_INFINITY
+ });
+
+ return -1 - i;
+ }
+ }
+};
+
+Timeline.DetailedEventPainter.prototype._findFreeTrackForText = function(fromTrack, edge, occupiedTrackVisitor) {
+ var extendUp;
+ var index;
+ var firstIndex;
+ var result;
+
+ if (fromTrack < 0) {
+ extendUp = true;
+ firstIndex = -fromTrack;
+
+ index = this._findFreeUpperTrackForText(firstIndex, edge);
+ result = -1 - index;
+ } else if (fromTrack > 0) {
+ extendUp = false;
+ firstIndex = fromTrack + 1;
+
+ index = this._findFreeLowerTrackForText(firstIndex, edge);
+ result = index;
+ } else {
+ var upIndex = this._findFreeUpperTrackForText(0, edge);
+ var downIndex = this._findFreeLowerTrackForText(1, edge);
+
+ if (downIndex - 1 <= upIndex) {
+ extendUp = false;
+ firstIndex = 1;
+ index = downIndex;
+ result = index;
+ } else {
+ extendUp = true;
+ firstIndex = 0;
+ index = upIndex;
+ result = -1 - index;
+ }
+ }
+
+ if (extendUp) {
+ if (index == this._upperTracks.length) {
+ this._upperTracks.push({
+ solid: Number.POSITIVE_INFINITY,
+ text: Number.POSITIVE_INFINITY,
+ line: Number.POSITIVE_INFINITY
+ });
+ }
+ for (var i = firstIndex; i < index; i++) {
+ occupiedTrackVisitor(this._upperTracks[i]);
+ }
+ } else {
+ if (index == this._lowerTracks.length) {
+ this._lowerTracks.push({
+ solid: Number.POSITIVE_INFINITY,
+ text: Number.POSITIVE_INFINITY,
+ line: Number.POSITIVE_INFINITY
+ });
+ }
+ for (var i = firstIndex; i < index; i++) {
+ occupiedTrackVisitor(this._lowerTracks[i]);
+ }
+ }
+ return result;
+};
+
+Timeline.DetailedEventPainter.prototype._findFreeLowerTrackForText = function(index, edge) {
+ for (; index < this._lowerTracks.length; index++) {
+ var t = this._lowerTracks[index];
+ if (Math.min(t.solid, t.text) >= edge) {
+ break;
+ }
+ }
+ return index;
+};
+
+Timeline.DetailedEventPainter.prototype._findFreeUpperTrackForText = function(index, edge) {
+ for (; index < this._upperTracks.length; index++) {
+ var t = this._upperTracks[index];
+ if (Math.min(t.solid, t.text) >= edge) {
+ break;
+ }
+ }
+ return index;
+};
+
+Timeline.DetailedEventPainter.prototype._getTrackData = function(index) {
+ return (index < 0) ? this._upperTracks[-index - 1] : this._lowerTracks[index];
+};
+
+Timeline.DetailedEventPainter.prototype._paintEventLine = function(evt, left, startTrack, endTrack, metrics, theme) {
+ var top = Math.round(metrics.trackOffset + startTrack * metrics.trackIncrement + metrics.trackHeight / 2);
+ var height = Math.round(Math.abs(endTrack - startTrack) * metrics.trackIncrement);
+
+ var lineStyle = "1px solid " + theme.event.label.lineColor;
+ var lineDiv = this._timeline.getDocument().createElement("div");
+ lineDiv.style.position = "absolute";
+ lineDiv.style.left = left + "px";
+ lineDiv.style.width = theme.event.label.offsetFromLine + "px";
+ lineDiv.style.height = height + "px";
+ if (startTrack > endTrack) {
+ lineDiv.style.top = (top - height) + "px";
+ lineDiv.style.borderTop = lineStyle;
+ } else {
+ lineDiv.style.top = top + "px";
+ lineDiv.style.borderBottom = lineStyle;
+ }
+ lineDiv.style.borderLeft = lineStyle;
+ this._lineLayer.appendChild(lineDiv);
+};
+
+Timeline.DetailedEventPainter.prototype._paintEventIcon = function(evt, iconTrack, left, metrics, theme) {
+ var icon = evt.getIcon();
+ icon = icon != null ? icon : metrics.icon;
+
+ var middle = metrics.trackOffset + iconTrack * metrics.trackIncrement + metrics.trackHeight / 2;
+ var top = Math.round(middle - metrics.iconHeight / 2);
+
+ var img = SimileAjax.Graphics.createTranslucentImage(icon);
+ var iconDiv = this._timeline.getDocument().createElement("div");
+ iconDiv.style.position = "absolute";
+ iconDiv.style.left = left + "px";
+ iconDiv.style.top = top + "px";
+ iconDiv.appendChild(img);
+ iconDiv.style.cursor = "pointer";
+ this._eventLayer.appendChild(iconDiv);
+
+ return {
+ left: left,
+ top: top,
+ width: metrics.iconWidth,
+ height: metrics.iconHeight,
+ elmt: iconDiv
+ };
+};
+
+Timeline.DetailedEventPainter.prototype._paintEventLabel = function(evt, text, left, top, width, height, theme) {
+ var doc = this._timeline.getDocument();
+
+ var labelBackgroundDiv = doc.createElement("div");
+ labelBackgroundDiv.style.position = "absolute";
+ labelBackgroundDiv.style.left = left + "px";
+ labelBackgroundDiv.style.width = width + "px";
+ labelBackgroundDiv.style.top = top + "px";
+ labelBackgroundDiv.style.height = height + "px";
+ labelBackgroundDiv.style.backgroundColor = theme.event.label.backgroundColor;
+ SimileAjax.Graphics.setOpacity(labelBackgroundDiv, theme.event.label.backgroundOpacity);
+ this._eventLayer.appendChild(labelBackgroundDiv);
+
+ var labelDiv = doc.createElement("div");
+ labelDiv.style.position = "absolute";
+ labelDiv.style.left = left + "px";
+ labelDiv.style.width = width + "px";
+ labelDiv.style.top = top + "px";
+ labelDiv.innerHTML = text;
+ labelDiv.style.cursor = "pointer";
+
+ var color = evt.getTextColor();
+ if (color == null) {
+ color = evt.getColor();
+ }
+ if (color != null) {
+ labelDiv.style.color = color;
+ }
+
+ this._eventLayer.appendChild(labelDiv);
+
+ return {
+ left: left,
+ top: top,
+ width: width,
+ height: height,
+ elmt: labelDiv
+ };
+};
+
+Timeline.DetailedEventPainter.prototype._paintEventTape = function(
+ evt, iconTrack, startPixel, endPixel, color, opacity, metrics, theme) {
+
+ var tapeWidth = endPixel - startPixel;
+ var tapeHeight = theme.event.tape.height;
+ var middle = metrics.trackOffset + iconTrack * metrics.trackIncrement + metrics.trackHeight / 2;
+ var top = Math.round(middle - tapeHeight / 2);
+
+ var tapeDiv = this._timeline.getDocument().createElement("div");
+ tapeDiv.style.position = "absolute";
+ tapeDiv.style.left = startPixel + "px";
+ tapeDiv.style.width = tapeWidth + "px";
+ tapeDiv.style.top = top + "px";
+ tapeDiv.style.height = tapeHeight + "px";
+ tapeDiv.style.backgroundColor = color;
+ tapeDiv.style.overflow = "hidden";
+ tapeDiv.style.cursor = "pointer";
+ SimileAjax.Graphics.setOpacity(tapeDiv, opacity);
+
+ this._eventLayer.appendChild(tapeDiv);
+
+ return {
+ left: startPixel,
+ top: top,
+ width: tapeWidth,
+ height: tapeHeight,
+ elmt: tapeDiv
+ };
+}
+
+Timeline.DetailedEventPainter.prototype._createHighlightDiv = function(highlightIndex, dimensions, theme) {
+ if (highlightIndex >= 0) {
+ var doc = this._timeline.getDocument();
+ var eventTheme = theme.event;
+
+ var color = eventTheme.highlightColors[Math.min(highlightIndex, eventTheme.highlightColors.length - 1)];
+
+ var div = doc.createElement("div");
+ div.style.position = "absolute";
+ div.style.overflow = "hidden";
+ div.style.left = (dimensions.left - 2) + "px";
+ div.style.width = (dimensions.width + 4) + "px";
+ div.style.top = (dimensions.top - 2) + "px";
+ div.style.height = (dimensions.height + 4) + "px";
+ div.style.background = color;
+
+ this._highlightLayer.appendChild(div);
+ }
+};
+
+Timeline.DetailedEventPainter.prototype._onClickInstantEvent = function(icon, domEvt, evt) {
+ var c = SimileAjax.DOM.getPageCoordinates(icon);
+ this._showBubble(
+ c.left + Math.ceil(icon.offsetWidth / 2),
+ c.top + Math.ceil(icon.offsetHeight / 2),
+ evt
+ );
+ this._fireOnSelect(evt.getID());
+
+ domEvt.cancelBubble = true;
+ SimileAjax.DOM.cancelEvent(domEvt);
+ return false;
+};
+
+Timeline.DetailedEventPainter.prototype._onClickDurationEvent = function(target, domEvt, evt) {
+ if ("pageX" in domEvt) {
+ var x = domEvt.pageX;
+ var y = domEvt.pageY;
+ } else {
+ var c = SimileAjax.DOM.getPageCoordinates(target);
+ var x = domEvt.offsetX + c.left;
+ var y = domEvt.offsetY + c.top;
+ }
+ this._showBubble(x, y, evt);
+ this._fireOnSelect(evt.getID());
+
+ domEvt.cancelBubble = true;
+ SimileAjax.DOM.cancelEvent(domEvt);
+ return false;
+};
+
+Timeline.DetailedEventPainter.prototype.showBubble = function(evt) {
+ var elmt = this._eventIdToElmt[evt.getID()];
+ if (elmt) {
+ var c = SimileAjax.DOM.getPageCoordinates(elmt);
+ this._showBubble(c.left + elmt.offsetWidth / 2, c.top + elmt.offsetHeight / 2, evt);
+ }
+};
+
+Timeline.DetailedEventPainter.prototype._showBubble = function(x, y, evt) {
+ var div = document.createElement("div");
+ evt.fillInfoBubble(div, this._params.theme, this._band.getLabeller());
+
+ SimileAjax.WindowManager.cancelPopups();
+ SimileAjax.Graphics.createBubbleForContentAndPoint(div, x, y, this._params.theme.event.bubble.width);
+};
+
+Timeline.DetailedEventPainter.prototype._fireOnSelect = function(eventID) {
+ for (var i = 0; i < this._onSelectListeners.length; i++) {
+ this._onSelectListeners[i](eventID);
+ }
+};
+/*==================================================
+ * Overview Event Painter
+ *==================================================
+ */
+
+Timeline.OverviewEventPainter = function(params) {
+ this._params = params;
+ this._onSelectListeners = [];
+
+ this._filterMatcher = null;
+ this._highlightMatcher = null;
+};
+
+Timeline.OverviewEventPainter.prototype.initialize = function(band, timeline) {
+ this._band = band;
+ this._timeline = timeline;
+
+ this._eventLayer = null;
+ this._highlightLayer = null;
+};
+
+Timeline.OverviewEventPainter.prototype.addOnSelectListener = function(listener) {
+ this._onSelectListeners.push(listener);
+};
+
+Timeline.OverviewEventPainter.prototype.removeOnSelectListener = function(listener) {
+ for (var i = 0; i < this._onSelectListeners.length; i++) {
+ if (this._onSelectListeners[i] == listener) {
+ this._onSelectListeners.splice(i, 1);
+ break;
+ }
+ }
+};
+
+Timeline.OverviewEventPainter.prototype.getFilterMatcher = function() {
+ return this._filterMatcher;
+};
+
+Timeline.OverviewEventPainter.prototype.setFilterMatcher = function(filterMatcher) {
+ this._filterMatcher = filterMatcher;
+};
+
+Timeline.OverviewEventPainter.prototype.getHighlightMatcher = function() {
+ return this._highlightMatcher;
+};
+
+Timeline.OverviewEventPainter.prototype.setHighlightMatcher = function(highlightMatcher) {
+ this._highlightMatcher = highlightMatcher;
+};
+
+Timeline.OverviewEventPainter.prototype.paint = function() {
+ var eventSource = this._band.getEventSource();
+ if (eventSource == null) {
+ return;
+ }
+
+ this._prepareForPainting();
+
+ var eventTheme = this._params.theme.event;
+ var metrics = {
+ trackOffset: eventTheme.overviewTrack.offset,
+ trackHeight: eventTheme.overviewTrack.height,
+ trackGap: eventTheme.overviewTrack.gap,
+ trackIncrement: eventTheme.overviewTrack.height + eventTheme.overviewTrack.gap
+ }
+
+ var minDate = this._band.getMinDate();
+ var maxDate = this._band.getMaxDate();
+
+ var filterMatcher = (this._filterMatcher != null) ?
+ this._filterMatcher :
+ function(evt) { return true; };
+ var highlightMatcher = (this._highlightMatcher != null) ?
+ this._highlightMatcher :
+ function(evt) { return -1; };
+
+ var iterator = eventSource.getEventReverseIterator(minDate, maxDate);
+ while (iterator.hasNext()) {
+ var evt = iterator.next();
+ if (filterMatcher(evt)) {
+ this.paintEvent(evt, metrics, this._params.theme, highlightMatcher(evt));
+ }
+ }
+
+ this._highlightLayer.style.display = "block";
+ this._eventLayer.style.display = "block";
+};
+
+Timeline.OverviewEventPainter.prototype.softPaint = function() {
+};
+
+Timeline.OverviewEventPainter.prototype._prepareForPainting = function() {
+ var band = this._band;
+
+ this._tracks = [];
+
+ if (this._highlightLayer != null) {
+ band.removeLayerDiv(this._highlightLayer);
+ }
+ this._highlightLayer = band.createLayerDiv(105, "timeline-band-highlights");
+ this._highlightLayer.style.display = "none";
+
+ if (this._eventLayer != null) {
+ band.removeLayerDiv(this._eventLayer);
+ }
+ this._eventLayer = band.createLayerDiv(110, "timeline-band-events");
+ this._eventLayer.style.display = "none";
+};
+
+Timeline.OverviewEventPainter.prototype.paintEvent = function(evt, metrics, theme, highlightIndex) {
+ if (evt.isInstant()) {
+ this.paintInstantEvent(evt, metrics, theme, highlightIndex);
+ } else {
+ this.paintDurationEvent(evt, metrics, theme, highlightIndex);
+ }
+};
+
+Timeline.OverviewEventPainter.prototype.paintInstantEvent = function(evt, metrics, theme, highlightIndex) {
+ var startDate = evt.getStart();
+ var startPixel = Math.round(this._band.dateToPixelOffset(startDate));
+
+ var color = evt.getColor();
+ color = color != null ? color : theme.event.duration.color;
+
+ var tickElmtData = this._paintEventTick(evt, startPixel, color, 100, metrics, theme);
+
+ this._createHighlightDiv(highlightIndex, tickElmtData, theme);
+};
+
+Timeline.OverviewEventPainter.prototype.paintDurationEvent = function(evt, metrics, theme, highlightIndex) {
+ var latestStartDate = evt.getLatestStart();
+ var earliestEndDate = evt.getEarliestEnd();
+
+ var latestStartPixel = Math.round(this._band.dateToPixelOffset(latestStartDate));
+ var earliestEndPixel = Math.round(this._band.dateToPixelOffset(earliestEndDate));
+
+ var tapeTrack = 0;
+ for (; tapeTrack < this._tracks.length; tapeTrack++) {
+ if (earliestEndPixel < this._tracks[tapeTrack]) {
+ break;
+ }
+ }
+ this._tracks[tapeTrack] = earliestEndPixel;
+
+ var color = evt.getColor();
+ color = color != null ? color : theme.event.duration.color;
+
+ var tapeElmtData = this._paintEventTape(evt, tapeTrack, latestStartPixel, earliestEndPixel, color, 100, metrics, theme);
+
+ this._createHighlightDiv(highlightIndex, tapeElmtData, theme);
+};
+
+Timeline.OverviewEventPainter.prototype._paintEventTape = function(
+ evt, track, left, right, color, opacity, metrics, theme) {
+
+ var top = metrics.trackOffset + track * metrics.trackIncrement;
+ var width = right - left;
+ var height = metrics.trackHeight;
+
+ var tapeDiv = this._timeline.getDocument().createElement("div");
+ tapeDiv.style.position = "absolute";
+ tapeDiv.style.left = left + "px";
+ tapeDiv.style.width = width + "px";
+ tapeDiv.style.top = top + "px";
+ tapeDiv.style.height = height + "px";
+ tapeDiv.style.backgroundColor = color;
+ tapeDiv.style.overflow = "hidden";
+ SimileAjax.Graphics.setOpacity(tapeDiv, opacity);
+
+ this._eventLayer.appendChild(tapeDiv);
+
+ return {
+ left: left,
+ top: top,
+ width: width,
+ height: height,
+ elmt: tapeDiv
+ };
+}
+
+Timeline.OverviewEventPainter.prototype._paintEventTick = function(
+ evt, left, color, opacity, metrics, theme) {
+
+ var height = theme.event.overviewTrack.tickHeight;
+ var top = metrics.trackOffset - height;
+ var width = 1;
+
+ var tickDiv = this._timeline.getDocument().createElement("div");
+ tickDiv.style.position = "absolute";
+ tickDiv.style.left = left + "px";
+ tickDiv.style.width = width + "px";
+ tickDiv.style.top = top + "px";
+ tickDiv.style.height = height + "px";
+ tickDiv.style.backgroundColor = color;
+ tickDiv.style.overflow = "hidden";
+ SimileAjax.Graphics.setOpacity(tickDiv, opacity);
+
+ this._eventLayer.appendChild(tickDiv);
+
+ return {
+ left: left,
+ top: top,
+ width: width,
+ height: height,
+ elmt: tickDiv
+ };
+}
+
+Timeline.OverviewEventPainter.prototype._createHighlightDiv = function(highlightIndex, dimensions, theme) {
+ if (highlightIndex >= 0) {
+ var doc = this._timeline.getDocument();
+ var eventTheme = theme.event;
+
+ var color = eventTheme.highlightColors[Math.min(highlightIndex, eventTheme.highlightColors.length - 1)];
+
+ var div = doc.createElement("div");
+ div.style.position = "absolute";
+ div.style.overflow = "hidden";
+ div.style.left = (dimensions.left - 1) + "px";
+ div.style.width = (dimensions.width + 2) + "px";
+ div.style.top = (dimensions.top - 1) + "px";
+ div.style.height = (dimensions.height + 2) + "px";
+ div.style.background = color;
+
+ this._highlightLayer.appendChild(div);
+ }
+};
+
+Timeline.OverviewEventPainter.prototype.showBubble = function(evt) {
+ // not implemented
+};
+/*==================================================
+ * Span Highlight Decorator
+ *==================================================
+ */
+
+Timeline.SpanHighlightDecorator = function(params) {
+ this._unit = ("unit" in params) ? params.unit : SimileAjax.NativeDateUnit;
+ this._startDate = (typeof params.startDate == "string") ?
+ this._unit.parseFromObject(params.startDate) : params.startDate;
+ this._endDate = (typeof params.endDate == "string") ?
+ this._unit.parseFromObject(params.endDate) : params.endDate;
+ this._startLabel = params.startLabel;
+ this._endLabel = params.endLabel;
+ this._color = params.color;
+ this._opacity = ("opacity" in params) ? params.opacity : 100;
+};
+
+Timeline.SpanHighlightDecorator.prototype.initialize = function(band, timeline) {
+ this._band = band;
+ this._timeline = timeline;
+
+ this._layerDiv = null;
+};
+
+Timeline.SpanHighlightDecorator.prototype.paint = function() {
+ if (this._layerDiv != null) {
+ this._band.removeLayerDiv(this._layerDiv);
+ }
+ this._layerDiv = this._band.createLayerDiv(10);
+ this._layerDiv.setAttribute("name", "span-highlight-decorator"); // for debugging
+ this._layerDiv.style.display = "none";
+
+ var minDate = this._band.getMinDate();
+ var maxDate = this._band.getMaxDate();
+
+ if (this._unit.compare(this._startDate, maxDate) < 0 &&
+ this._unit.compare(this._endDate, minDate) > 0) {
+
+ minDate = this._unit.later(minDate, this._startDate);
+ maxDate = this._unit.earlier(maxDate, this._endDate);
+
+ var minPixel = this._band.dateToPixelOffset(minDate);
+ var maxPixel = this._band.dateToPixelOffset(maxDate);
+
+ var doc = this._timeline.getDocument();
+
+ var createTable = function() {
+ var table = doc.createElement("table");
+ table.insertRow(0).insertCell(0);
+ return table;
+ };
+
+ var div = doc.createElement("div");
+ div.style.position = "absolute";
+ div.style.overflow = "hidden";
+ div.style.background = this._color;
+ if (this._opacity < 100) {
+ SimileAjax.Graphics.setOpacity(div, this._opacity);
+ }
+ this._layerDiv.appendChild(div);
+
+ var tableStartLabel = createTable();
+ tableStartLabel.style.position = "absolute";
+ tableStartLabel.style.overflow = "hidden";
+ tableStartLabel.style.fontSize = "200%";
+ tableStartLabel.style.fontWeight = "bold";
+ tableStartLabel.style.color = this._color;
+ tableStartLabel.rows[0].cells[0].innerHTML = this._startLabel;
+ this._layerDiv.appendChild(tableStartLabel);
+
+ var tableEndLabel = createTable();
+ tableEndLabel.style.position = "absolute";
+ tableEndLabel.style.overflow = "hidden";
+ tableEndLabel.style.fontSize = "200%";
+ tableEndLabel.style.fontWeight = "bold";
+ tableEndLabel.style.color = this._color;
+ tableEndLabel.rows[0].cells[0].innerHTML = this._endLabel;
+ this._layerDiv.appendChild(tableEndLabel);
+
+ if (this._timeline.isHorizontal()) {
+ div.style.left = minPixel + "px";
+ div.style.width = (maxPixel - minPixel) + "px";
+ div.style.top = "0px";
+ div.style.height = "100%";
+
+ tableStartLabel.style.right = (this._band.getTotalViewLength() - minPixel) + "px";
+ tableStartLabel.style.width = (this._startLabel.length) + "em";
+ tableStartLabel.style.top = "0px";
+ tableStartLabel.style.height = "100%";
+ tableStartLabel.style.textAlign = "right";
+ tableStartLabel.rows[0].style.verticalAlign = "top";
+
+ tableEndLabel.style.left = maxPixel + "px";
+ tableEndLabel.style.width = (this._endLabel.length) + "em";
+ tableEndLabel.style.top = "0px";
+ tableEndLabel.style.height = "100%";
+ tableEndLabel.rows[0].style.verticalAlign = "top";
+ } else {
+ div.style.top = minPixel + "px";
+ div.style.height = (maxPixel - minPixel) + "px";
+ div.style.left = "0px";
+ div.style.width = "100%";
+
+ tableStartLabel.style.bottom = minPixel + "px";
+ tableStartLabel.style.height = "1.5px";
+ tableStartLabel.style.left = "0px";
+ tableStartLabel.style.width = "100%";
+
+ tableEndLabel.style.top = maxPixel + "px";
+ tableEndLabel.style.height = "1.5px";
+ tableEndLabel.style.left = "0px";
+ tableEndLabel.style.width = "100%";
+ }
+ }
+ this._layerDiv.style.display = "block";
+};
+
+Timeline.SpanHighlightDecorator.prototype.softPaint = function() {
+};
+
+/*==================================================
+ * Point Highlight Decorator
+ *==================================================
+ */
+
+Timeline.PointHighlightDecorator = function(params) {
+ this._unit = ("unit" in params) ? params.unit : SimileAjax.NativeDateUnit;
+ this._date = (typeof params.date == "string") ?
+ this._unit.parseFromObject(params.date) : params.date;
+ this._width = ("width" in params) ? params.width : 10;
+ this._color = params.color;
+ this._opacity = ("opacity" in params) ? params.opacity : 100;
+};
+
+Timeline.PointHighlightDecorator.prototype.initialize = function(band, timeline) {
+ this._band = band;
+ this._timeline = timeline;
+
+ this._layerDiv = null;
+};
+
+Timeline.PointHighlightDecorator.prototype.paint = function() {
+ if (this._layerDiv != null) {
+ this._band.removeLayerDiv(this._layerDiv);
+ }
+ this._layerDiv = this._band.createLayerDiv(10);
+ this._layerDiv.setAttribute("name", "span-highlight-decorator"); // for debugging
+ this._layerDiv.style.display = "none";
+
+ var minDate = this._band.getMinDate();
+ var maxDate = this._band.getMaxDate();
+
+ if (this._unit.compare(this._date, maxDate) < 0 &&
+ this._unit.compare(this._date, minDate) > 0) {
+
+ var pixel = this._band.dateToPixelOffset(this._date);
+ var minPixel = pixel - Math.round(this._width / 2);
+
+ var doc = this._timeline.getDocument();
+
+ var div = doc.createElement("div");
+ div.style.position = "absolute";
+ div.style.overflow = "hidden";
+ div.style.background = this._color;
+ if (this._opacity < 100) {
+ SimileAjax.Graphics.setOpacity(div, this._opacity);
+ }
+ this._layerDiv.appendChild(div);
+
+ if (this._timeline.isHorizontal()) {
+ div.style.left = minPixel + "px";
+ div.style.width = this._width + "px";
+ div.style.top = "0px";
+ div.style.height = "100%";
+ } else {
+ div.style.top = minPixel + "px";
+ div.style.height = this._width + "px";
+ div.style.left = "0px";
+ div.style.width = "100%";
+ }
+ }
+ this._layerDiv.style.display = "block";
+};
+
+Timeline.PointHighlightDecorator.prototype.softPaint = function() {
+};
+/*==================================================
+ * Default Unit
+ *==================================================
+ */
+
+Timeline.NativeDateUnit = new Object();
+
+Timeline.NativeDateUnit.createLabeller = function(locale, timeZone) {
+ return new Timeline.GregorianDateLabeller(locale, timeZone);
+};
+
+Timeline.NativeDateUnit.makeDefaultValue = function() {
+ return new Date();
+};
+
+Timeline.NativeDateUnit.cloneValue = function(v) {
+ return new Date(v.getTime());
+};
+
+Timeline.NativeDateUnit.getParser = function(format) {
+ if (typeof format == "string") {
+ format = format.toLowerCase();
+ }
+ return (format == "iso8601" || format == "iso 8601") ?
+ Timeline.DateTime.parseIso8601DateTime :
+ Timeline.DateTime.parseGregorianDateTime;
+};
+
+Timeline.NativeDateUnit.parseFromObject = function(o) {
+ return Timeline.DateTime.parseGregorianDateTime(o);
+};
+
+Timeline.NativeDateUnit.toNumber = function(v) {
+ return v.getTime();
+};
+
+Timeline.NativeDateUnit.fromNumber = function(n) {
+ return new Date(n);
+};
+
+Timeline.NativeDateUnit.compare = function(v1, v2) {
+ var n1, n2;
+ if (typeof v1 == "object") {
+ n1 = v1.getTime();
+ } else {
+ n1 = Number(v1);
+ }
+ if (typeof v2 == "object") {
+ n2 = v2.getTime();
+ } else {
+ n2 = Number(v2);
+ }
+
+ return n1 - n2;
+};
+
+Timeline.NativeDateUnit.earlier = function(v1, v2) {
+ return Timeline.NativeDateUnit.compare(v1, v2) < 0 ? v1 : v2;
+};
+
+Timeline.NativeDateUnit.later = function(v1, v2) {
+ return Timeline.NativeDateUnit.compare(v1, v2) > 0 ? v1 : v2;
+};
+
+Timeline.NativeDateUnit.change = function(v, n) {
+ return new Date(v.getTime() + n);
+};
+
+////////////////////////////// TIMEPLOT LOADER ////////////////////////////////
+(function() {
+
+ var local = true;
+
+ // Load Timeplot if it's not already loaded (after SimileAjax and Timeline)
+ var loadTimeplot = function() {
+
+ if (typeof window.Timeplot != "undefined") {
+ return;
+ }
+
+ window.Timeplot = {
+ loaded: false,
+ params: { bundle: true, autoCreate: true },
+ namespace: "http://simile.mit.edu/2007/06/timeplot#",
+ importers: {}
+ };
+
+ var locales = [ "en" ];
+
+ var defaultClientLocales = ("language" in navigator ? navigator.language : navigator.browserLanguage).split(";");
+ for (var l = 0; l < defaultClientLocales.length; l++) {
+ var locale = defaultClientLocales[l];
+ if (locale != "en") {
+ var segments = locale.split("-");
+ if (segments.length > 1 && segments[0] != "en") {
+ locales.push(segments[0]);
+ }
+ locales.push(locale);
+ }
+ }
+
+ var paramTypes = { bundle:Boolean, autoCreate:Boolean };
+
+ if (Timeplot.params.locale) { // ISO-639 language codes,
+ // optional ISO-3166 country codes (2 characters)
+ if (Timeplot.params.locale != "en") {
+ var segments = Timeplot.params.locale.split("-");
+ if (segments.length > 1 && segments[0] != "en") {
+ locales.push(segments[0]);
+ }
+ locales.push(Timeplot.params.locale);
+ }
+ }
+
+ var canvas = document.createElement("canvas");
+
+ window.SimileAjax_onLoad = function() {
+ //if (local && window.console.open) window.console.open();
+ if (Timeplot.params.callback) {
+ eval(Timeplot.params.callback + "()");
+ }
+ }
+
+ if (typeof Simile_urlPrefix == "string") {
+ Timeplot.urlPrefix = Simile_urlPrefix + '/timeplot/';
+ }
+
+ Timeplot.loaded = true;
+ };
+
+ // Load Timeline if it's not already loaded (after SimileAjax and before Timeplot)
+ var loadTimeline = function() {
+ if (typeof Timeline != "undefined") {
+ loadTimeplot();
+ } else {
+ window.SimileAjax_onLoad = loadTimeplot;
+ }
+ };
+
+ // Load SimileAjax if it's not already loaded
+ if (typeof SimileAjax == "undefined") {
+ window.SimileAjax_onLoad = loadTimeline;
+ } else {
+ loadTimeline();
+ }
+})();
+/**
+ * Timeplot
+ *
+ * @fileOverview Timeplot
+ * @name Timeplot
+ */
+
+Timeline.Debug = SimileAjax.Debug; // timeline uses it's own debug system which is not as advanced
+var log = SimileAjax.Debug.log; // shorter name is easier to use
+
+/*
+ * This function is used to implement a raw but effective OOP-like inheritance
+ * in various Timeplot classes.
+ */
+Object.extend = function(destination, source) {
+ for (var property in source) {
+ destination[property] = source[property];
+ }
+ return destination;
+}
+
+// ---------------------------------------------
+
+/**
+ * Create a timeplot attached to the given element and using the configuration from the given array of PlotInfos
+ */
+Timeplot.create = function(elmt, plotInfos) {
+ return new Timeplot._Impl(elmt, plotInfos);
+};
+
+/**
+ * Create a PlotInfo configuration from the given map of params
+ */
+Timeplot.createPlotInfo = function(params) {
+ return {
+ id: ("id" in params) ? params.id : "p" + Math.round(Math.random() * 1000000),
+ dataSource: ("dataSource" in params) ? params.dataSource : null,
+ eventSource: ("eventSource" in params) ? params.eventSource : null,
+ timeGeometry: ("timeGeometry" in params) ? params.timeGeometry : new Timeplot.DefaultTimeGeometry(),
+ valueGeometry: ("valueGeometry" in params) ? params.valueGeometry : new Timeplot.DefaultValueGeometry(),
+ timeZone: ("timeZone" in params) ? params.timeZone : 0,
+ fillColor: ("fillColor" in params) ? ((params.fillColor == "string") ? new Timeplot.Color(params.fillColor) : params.fillColor) : null,
+ fillGradient: ("fillGradient" in params) ? params.fillGradient : true,
+ fillFrom: ("fillFrom" in params) ? params.fillFrom : Number.NEGATIVE_INFINITY,
+ lineColor: ("lineColor" in params) ? ((params.lineColor == "string") ? new Timeplot.Color(params.lineColor) : params.lineColor) : new Timeplot.Color("#606060"),
+ lineWidth: ("lineWidth" in params) ? params.lineWidth : 1.0,
+ dotRadius: ("dotRadius" in params) ? params.dotRadius : 2.0,
+ dotColor: ("dotColor" in params) ? params.dotColor : null,
+ eventLineWidth: ("eventLineWidth" in params) ? params.eventLineWidth : 1.0,
+ showValues: ("showValues" in params) ? params.showValues : false,
+ roundValues: ("roundValues" in params) ? params.roundValues : true,
+ valuesOpacity: ("valuesOpacity" in params) ? params.valuesOpacity : 75,
+ bubbleWidth: ("bubbleWidth" in params) ? params.bubbleWidth : 300,
+ bubbleHeight: ("bubbleHeight" in params) ? params.bubbleHeight : 200
+ };
+};
+
+// -------------------------------------------------------
+
+/**
+ * This is the implementation of the Timeplot object.
+ *
+ * @constructor
+ */
+Timeplot._Impl = function(elmt, plotInfos) {
+ this._id = "t" + Math.round(Math.random() * 1000000);
+ this._containerDiv = elmt;
+ this._plotInfos = plotInfos;
+ this._painters = {
+ background: [],
+ foreground: []
+ };
+ this._painter = null;
+ this._active = false;
+ this._upright = false;
+ this._initialize();
+};
+
+Timeplot._Impl.prototype = {
+
+ dispose: function() {
+ for (var i = 0; i < this._plots.length; i++) {
+ this._plots[i].dispose();
+ }
+ this._plots = null;
+ this._plotsInfos = null;
+ this._containerDiv.innerHTML = "";
+ },
+
+ /**
+ * Returns the main container div this timeplot is operating on.
+ */
+ getElement: function() {
+ return this._containerDiv;
+ },
+
+ /**
+ * Returns document this timeplot belongs to.
+ */
+ getDocument: function() {
+ return this._containerDiv.ownerDocument;
+ },
+
+ /**
+ * Append the given element to the timeplot DOM
+ */
+ add: function(div) {
+ this._containerDiv.appendChild(div);
+ },
+
+ /**
+ * Remove the given element from the timeplot DOM
+ */
+ remove: function(div) {
+ this._containerDiv.removeChild(div);
+ },
+
+ /**
+ * Add a painter to the timeplot
+ */
+ addPainter: function(layerName, painter) {
+ var layer = this._painters[layerName];
+ if (layer) {
+ for (var i = 0; i < layer.length; i++) {
+ if (layer[i].context._id == painter.context._id) {
+ return;
+ }
+ }
+ layer.push(painter);
+ }
+ },
+
+ /**
+ * Remove a painter from the timeplot
+ */
+ removePainter: function(layerName, painter) {
+ var layer = this._painters[layerName];
+ if (layer) {
+ for (var i = 0; i < layer.length; i++) {
+ if (layer[i].context._id == painter.context._id) {
+ layer.splice(i, 1);
+ break;
+ }
+ }
+ }
+ },
+
+ /**
+ * Get the width in pixels of the area occupied by the entire timeplot in the page
+ */
+ getWidth: function() {
+ return this._containerDiv.clientWidth;
+ },
+
+ /**
+ * Get the height in pixels of the area occupied by the entire timeplot in the page
+ */
+ getHeight: function() {
+ return this._containerDiv.clientHeight;
+ },
+
+ /**
+ * Get the drawing canvas associated with this timeplot
+ */
+ getCanvas: function() {
+ return this._canvas;
+ },
+
+ /**
+ * <p>Load the data from the given url into the given eventSource, using
+ * the given separator to parse the columns and preprocess it before parsing
+ * thru the optional filter function. The filter is useful for when
+ * the data is row-oriented but the format is not compatible with the
+ * one that Timeplot expects.</p>
+ *
+ * <p>Here is an example of a filter that changes dates in the form 'yyyy/mm/dd'
+ * in the required 'yyyy-mm-dd' format:
+ * <pre>var dataFilter = function(data) {
+ * for (var i = 0; i < data.length; i++) {
+ * var row = data[i];
+ * row[0] = row[0].replace(/\//g,"-");
+ * }
+ * return data;
+ * };</pre></p>
+ */
+ loadText: function(url, separator, eventSource, filter) {
+ if (this._active) {
+ var tp = this;
+
+ var fError = function(statusText, status, xmlhttp) {
+ alert("Failed to load data xml from " + url + "\n" + statusText);
+ tp.hideLoadingMessage();
+ };
+
+ var fDone = function(xmlhttp) {
+ try {
+ eventSource.loadText(xmlhttp.responseText, separator, url, filter);
+ } catch (e) {
+ SimileAjax.Debug.exception(e);
+ } finally {
+ tp.hideLoadingMessage();
+ }
+ };
+
+ this.showLoadingMessage();
+ window.setTimeout(function() { SimileAjax.XmlHttp.get(url, fError, fDone); }, 0);
+ }
+ },
+
+ /**
+ * Load event data from the given url into the given eventSource, using
+ * the Timeline XML event format.
+ */
+ loadXML: function(url, eventSource) {
+ if (this._active) {
+ var tl = this;
+
+ var fError = function(statusText, status, xmlhttp) {
+ alert("Failed to load data xml from " + url + "\n" + statusText);
+ tl.hideLoadingMessage();
+ };
+
+ var fDone = function(xmlhttp) {
+ try {
+ var xml = xmlhttp.responseXML;
+ if (!xml.documentElement && xmlhttp.responseStream) {
+ xml.load(xmlhttp.responseStream);
+ }
+ eventSource.loadXML(xml, url);
+ } finally {
+ tl.hideLoadingMessage();
+ }
+ };
+
+ this.showLoadingMessage();
+ window.setTimeout(function() { SimileAjax.XmlHttp.get(url, fError, fDone); }, 0);
+ }
+ },
+
+ /**
+ * Overlay a 'div' element filled with the given text and styles to this timeplot
+ * This is used to implement labels since canvas does not support drawing text.
+ */
+ putText: function(id, text, clazz, styles) {
+ var div = this.putDiv(id, "timeplot-div " + clazz, styles);
+ div.innerHTML = text;
+ return div;
+ },
+
+ /**
+ * Overlay a 'div' element, with the given class and the given styles to this timeplot.
+ * This is used for labels and horizontal and vertical grids.
+ */
+ putDiv: function(id, clazz, styles) {
+ var tid = this._id + "-" + id;
+ var div = document.getElementById(tid);
+ if (!div) {
+ var container = this._containerDiv.firstChild; // get the divs container
+ div = document.createElement("div");
+ div.setAttribute("id",tid);
+ container.appendChild(div);
+ }
+ div.setAttribute("class","timeplot-div " + clazz);
+ div.setAttribute("className","timeplot-div " + clazz);
+ this.placeDiv(div,styles);
+ return div;
+ },
+
+ /**
+ * AMO change
+ * Removes an overlayed 'div' element if it exists
+ */
+ removeDiv: function(id) {
+ var div = document.getElementById(this._id + "-" + id);
+
+ if (div) div.parentNode.removeChild(div);
+ },
+
+ /**
+ * Associate the given map of styles to the given element.
+ * In case such styles indicate position (left,right,top,bottom) correct them
+ * with the padding information so that they align to the 'internal' area
+ * of the timeplot.
+ */
+ placeDiv: function(div, styles) {
+ if (styles) {
+ for (style in styles) {
+ if (style == "left") {
+ styles[style] += this._paddingX;
+ styles[style] += "px";
+ } else if (style == "right") {
+ styles[style] += this._paddingX;
+ styles[style] += "px";
+ } else if (style == "top") {
+ styles[style] += this._paddingY;
+ styles[style] += "px";
+ } else if (style == "bottom") {
+ styles[style] += this._paddingY;
+ styles[style] += "px";
+ } else if (style == "width") {
+ if (styles[style] < 0) styles[style] = 0;
+ styles[style] += "px";
+ } else if (style == "height") {
+ if (styles[style] < 0) styles[style] = 0;
+ styles[style] += "px";
+ }
+ div.style[style] = styles[style];
+ }
+ }
+ },
+
+ /**
+ * AMO change
+ * Adds a new plot
+ * If update = true, adds a new plot to an already processed dataset
+ */
+ addPlot: function(plotInfo, update) {
+ if (update) this._plotInfos.push(plotInfo);
+
+ var timeplot = this;
+ var painter = {
+ onAddMany: function() { timeplot.update(); },
+ onClear: function() { timeplot.update(); }
+ }
+
+ var plot = new Timeplot.Plot(this, plotInfo);
+ var dataSource = plot.getDataSource();
+ if (dataSource) {
+ if (update) dataSource._process();
+ dataSource.addListener(painter);
+ }
+ this.addPainter("background", {
+ context: plot.getTimeGeometry(),
+ action: plot.getTimeGeometry().paint
+ });
+ this.addPainter("background", {
+ context: plot.getValueGeometry(),
+ action: plot.getValueGeometry().paint
+ });
+ this.addPainter("foreground", {
+ context: plot,
+ action: plot.paint
+ });
+ plot.initialize();
+ this._plots.push(plot);
+
+ if (update) this.update();
+
+ return true;
+ },
+
+ /**
+ * AMO change
+ * Removes a plot and repaints
+ */
+ removePlot: function(plotID) {
+ var removed = false;
+
+ if (this._plots) {
+ for (var i = 0; i < this._plots.length; i++) {
+ if (this._plots[i]._id == plotID) {
+ /* Removing only this painter preserves the value and time
+ axis. plot.dispose() isn't used to preserve dataSource in
+ case the plot is added back. */
+ this.removePainter("foreground", {context: this._plots[i]});
+
+ this.removeDiv(this._plots[i]._id + 'valueflag');
+ this.removeDiv(this._plots[i]._id + 'valueflagLineLeft');
+ this.removeDiv(this._plots[i]._id + 'valueflagLineRight');
+ this.removeDiv(this._plots[i]._id + 'valuepole');
+
+ this._plots.splice(i, 1);
+ removed = true;
+ }
+ }
+ }
+
+ if (this._plotInfos) {
+ for (i = 0; i < this._plotInfos.length; i++) {
+ if (this._plotInfos[i].id == plotID) {
+ this._plotInfos.splice(i, 1);
+ removed = true;
+ }
+ }
+ }
+
+ if (removed) this.update();
+
+ return removed;
+ },
+
+ /**
+ * return a {x,y} map with the location of the given element relative to the 'internal' area of the timeplot
+ * (that is, without the container padding)
+ */
+ locate: function(div) {
+ return {
+ x: div.offsetLeft - this._paddingX,
+ y: div.offsetTop - this._paddingY
+ }
+ },
+
+ /**
+ * Forces timeplot to re-evaluate the various value and time geometries
+ * associated with its plot layers and repaint accordingly. This should
+ * be invoked after the data in any of the data sources has been
+ * modified.
+ */
+ update: function() {
+ if (this._active) {
+ for (var i = 0; i < this._plots.length; i++) {
+ var plot = this._plots[i];
+ var dataSource = plot.getDataSource();
+ if (dataSource) {
+ var range = dataSource.getRange();
+ if (range) {
+ plot._valueGeometry.setRange(range);
+ plot._timeGeometry.setRange(range);
+ }
+ }
+ }
+ this.paint();
+ }
+ },
+
+ /**
+ * Forces timeplot to re-evaluate its own geometry, clear itself and paint.
+ * This should be used instead of paint() when you're not sure if the
+ * geometry of the page has changed or not.
+ */
+ repaint: function() {
+ if (this._active) {
+ this._prepareCanvas();
+ for (var i = 0; i < this._plots.length; i++) {
+ var plot = this._plots[i];
+ if (plot._timeGeometry) plot._timeGeometry.reset();
+ if (plot._valueGeometry) plot._valueGeometry.reset();
+ }
+ this.paint();
+ }
+ },
+
+ /**
+ * Calls all the painters that were registered to this timeplot and makes them
+ * paint the timeplot. This should be used only when you're sure that the geometry
+ * of the page hasn't changed.
+ * NOTE: painting is performed by a different thread and it's safe to call this
+ * function in bursts (as in mousemove or during window resizing
+ */
+ paint: function() {
+ if (this._active && this._painter == null) {
+ var timeplot = this;
+ this._painter = window.setTimeout(function() {
+ timeplot._clearCanvas();
+
+ var run = function(action,context) {
+ try {
+ if (context.setTimeplot) context.setTimeplot(timeplot);
+ action.apply(context,[]);
+ } catch (e) {
+ SimileAjax.Debug.exception(e);
+ }
+ }
+
+ var background = timeplot._painters.background;
+ for (var i = 0; i < background.length; i++) {
+ run(background[i].action, background[i].context);
+ }
+ var foreground = timeplot._painters.foreground;
+ for (var i = 0; i < foreground.length; i++) {
+ run(foreground[i].action, foreground[i].context);
+ }
+
+ timeplot._painter = null;
+ }, 20);
+ }
+ },
+
+ _clearCanvas: function() {
+ var canvas = this.getCanvas();
+ var ctx = canvas.getContext('2d');
+ ctx.clearRect(0,0,canvas.width,canvas.height);
+ },
+
+ _prepareCanvas: function() {
+ var canvas = this.getCanvas();
+
+ // using jQuery. note we calculate the average padding; if your
+ // padding settings are not symmetrical, the labels will be off
+ // since they expect to be centered on the canvas.
+ var con = $('#' + this._containerDiv.id);
+ this._paddingX = (parseInt(con.css('paddingLeft')) +
+ parseInt(con.css('paddingRight'))) / 2;
+ this._paddingY = (parseInt(con.css('paddingTop')) +
+ parseInt(con.css('paddingBottom'))) / 2;
+
+ canvas.width = this.getWidth() - (this._paddingX * 2);
+ canvas.height = this.getHeight() - (this._paddingY * 2);
+
+ var ctx = canvas.getContext('2d');
+ this._setUpright(ctx, canvas);
+ ctx.globalCompositeOperation = 'source-over';
+ },
+
+ _setUpright: function(ctx, canvas) {
+ // excanvas+IE requires this to be done only once, ever; actual canvas
+ // implementations reset and require this for each call to re-layout
+ if (!SimileAjax.Platform.browser.isIE) this._upright = false;
+ if (!this._upright) {
+ this._upright = true;
+ ctx.translate(0, canvas.height);
+ ctx.scale(1,-1);
+ }
+ },
+
+ _isBrowserSupported: function(canvas) {
+ var browser = SimileAjax.Platform.browser;
+ if ((canvas.getContext && window.getComputedStyle) ||
+ (browser.isIE && browser.majorVersion >= 6)) {
+ return true;
+ } else {
+ return false;
+ }
+ },
+
+ _initialize: function() {
+
+ // initialize the window manager (used to handle the popups)
+ // NOTE: this is a singleton and it's safe to call multiple times
+ SimileAjax.WindowManager.initialize();
+
+ var containerDiv = this._containerDiv;
+ var doc = containerDiv.ownerDocument;
+
+ // make sure the timeplot div has the right class
+ containerDiv.className = "timeplot-container " + containerDiv.className;
+
+ // clean it up if it contains some content
+ while (containerDiv.firstChild) {
+ containerDiv.removeChild(containerDiv.firstChild);
+ }
+
+ var canvas = doc.createElement("canvas");
+
+ if (this._isBrowserSupported(canvas)) {
+ // this is where we'll place the labels
+ var labels = doc.createElement("div");
+ containerDiv.appendChild(labels);
+
+ this._canvas = canvas;
+ canvas.className = "timeplot-canvas";
+ containerDiv.appendChild(canvas);
+ if(!canvas.getContext && G_vmlCanvasManager) {
+ canvas = G_vmlCanvasManager.initElement(this._canvas);
+ this._canvas = canvas;
+ }
+ this._prepareCanvas();
+
+ // inserting copyright and link to simile
+ var elmtCopyright = SimileAjax.Graphics.createTranslucentImage(Timeplot.urlPrefix + "images/copyright.png");
+ elmtCopyright.className = "timeplot-copyright";
+ elmtCopyright.title = "Timeplot (c) SIMILE - http://simile.mit.edu/timeplot/";
+ SimileAjax.DOM.registerEvent(elmtCopyright, "click", function() { window.location = "http://simile.mit.edu/timeplot/"; });
+ containerDiv.appendChild(elmtCopyright);
+
+ // creating painters
+ this._plots = [];
+ if (this._plotInfos) {
+ for (var i = 0; i < this._plotInfos.length; i++) {
+ this.addPlot(this._plotInfos[i]);
+ }
+ }
+
+ // creating loading UI
+ var message = SimileAjax.Graphics.createMessageBubble(doc);
+ message.containerDiv.className = "timeplot-message-container";
+ containerDiv.appendChild(message.containerDiv);
+
+ message.contentDiv.className = "timeplot-message";
+ message.contentDiv.innerHTML = "<img src='" + Timeplot.urlPrefix + "images/progress-running.gif' /> Loading...";
+
+ this.showLoadingMessage = function() { message.containerDiv.style.display = "block"; };
+ this.hideLoadingMessage = function() { message.containerDiv.style.display = "none"; };
+
+ this._active = true;
+
+ } else {
+
+ this._message = SimileAjax.Graphics.createMessageBubble(doc);
+ this._message.containerDiv.className = "timeplot-message-container";
+ this._message.containerDiv.style.top = "15%";
+ this._message.containerDiv.style.left = "20%";
+ this._message.containerDiv.style.right = "20%";
+ this._message.containerDiv.style.minWidth = "20em";
+ this._message.contentDiv.className = "timeplot-message";
+ this._message.contentDiv.innerHTML = "We're terribly sorry, but your browser is not currently supported by <a href='http://simile.mit.edu/timeplot/'>Timeplot</a>.<br><br> We are working on supporting it in the near future but, for now, see the <a href='http://simile.mit.edu/wiki/Timeplot_Limitations'>list of currently supported browsers</a>.";
+ this._message.containerDiv.style.display = "block";
+
+ containerDiv.appendChild(this._message.containerDiv);
+
+ }
+ }
+};
+/**
+ * Plot Layer
+ *
+ * @fileOverview Plot Layer
+ * @name Plot
+ */
+
+/**
+ * A plot layer is the main building block for timeplots and it's the object
+ * that is responsible for painting the plot itself. Each plot needs to have
+ * a time geometry, either a DataSource (for time series
+ * plots) or an EventSource (for event plots) and a value geometry in case
+ * of time series plots. Such parameters are passed along
+ * in the 'plotInfo' map.
+ *
+ * @constructor
+ */
+Timeplot.Plot = function(timeplot, plotInfo) {
+ this._timeplot = timeplot;
+ this._canvas = timeplot.getCanvas();
+ this._plotInfo = plotInfo;
+ this._id = plotInfo.id;
+ this._timeGeometry = plotInfo.timeGeometry;
+ this._valueGeometry = plotInfo.valueGeometry;
+ this._showValues = plotInfo.showValues;
+ this._theme = new Timeline.getDefaultTheme();
+ this._dataSource = plotInfo.dataSource;
+ this._eventSource = plotInfo.eventSource;
+ this._bubble = null;
+};
+
+Timeplot.Plot.prototype = {
+
+ /**
+ * Initialize the plot layer
+ */
+ initialize: function() {
+ if (this._showValues && this._dataSource && this._dataSource.getValue) {
+ this._timeFlag = this._timeplot.putDiv("timeflag","timeplot-timeflag");
+ this._valueFlag = this._timeplot.putDiv(this._id + "valueflag","timeplot-valueflag");
+ this._valueFlagLineLeft = this._timeplot.putDiv(this._id + "valueflagLineLeft","timeplot-valueflag-line");
+ this._valueFlagLineRight = this._timeplot.putDiv(this._id + "valueflagLineRight","timeplot-valueflag-line");
+ if (!this._valueFlagLineLeft.firstChild) {
+ this._valueFlagLineLeft.appendChild(SimileAjax.Graphics.createTranslucentImage(Timeplot.urlPrefix + "images/line_left.png"));
+ this._valueFlagLineRight.appendChild(SimileAjax.Graphics.createTranslucentImage(Timeplot.urlPrefix + "images/line_right.png"));
+ }
+ this._valueFlagPole = this._timeplot.putDiv(this._id + "valuepole","timeplot-valueflag-pole");
+
+ var opacity = this._plotInfo.valuesOpacity;
+
+ SimileAjax.Graphics.setOpacity(this._timeFlag, opacity);
+ SimileAjax.Graphics.setOpacity(this._valueFlag, opacity);
+ SimileAjax.Graphics.setOpacity(this._valueFlagLineLeft, opacity);
+ SimileAjax.Graphics.setOpacity(this._valueFlagLineRight, opacity);
+ SimileAjax.Graphics.setOpacity(this._valueFlagPole, opacity);
+
+ var plot = this;
+
+ var mouseOverHandler = function(elmt, evt, target) {
+ plot._valueFlag.style.display = "block";
+ mouseMoveHandler(elmt, evt, target);
+ }
+
+ var day = 24 * 60 * 60 * 1000;
+ var month = 30 * day;
+
+ var mouseMoveHandler = function(elmt, evt, target) {
+ if (typeof SimileAjax != "undefined") {
+ var c = plot._canvas;
+ var x = Math.round(SimileAjax.DOM.getEventRelativeCoordinates(evt,plot._canvas).x);
+ if (x > c.width) x = c.width;
+ if (isNaN(x) || x < 0) x = 0;
+ var t = plot._timeGeometry.fromScreen(x);
+ if (t == 0) { // something is wrong
+ plot._valueFlag.style.display = "none";
+ return;
+ }
+
+ var v = plot._dataSource.getValue(t);
+ if (plot._plotInfo.roundValues) v = Math.round(v);
+ plot._valueFlag.innerHTML = new String(v);
+ var d = new Date(t);
+ var p = plot._timeGeometry.getPeriod();
+ if (p < day) {
+ plot._timeFlag.innerHTML = d.toLocaleTimeString();
+ } else if (p > month) {
+ plot._timeFlag.innerHTML = d.toLocaleDateString();
+ } else {
+ plot._timeFlag.innerHTML = d.toLocaleString();
+ }
+
+ var tw = plot._timeFlag.clientWidth;
+ var th = plot._timeFlag.clientHeight;
+ var tdw = Math.round(tw / 2);
+ var vw = plot._valueFlag.clientWidth;
+ var vh = plot._valueFlag.clientHeight;
+ var y = plot._valueGeometry.toScreen(v);
+
+ if (x + tdw > c.width) {
+ var tx = c.width - tdw;
+ } else if (x - tdw < 0) {
+ var tx = tdw;
+ } else {
+ var tx = x;
+ }
+
+ if (plot._timeGeometry._timeValuePosition == "top") {
+ plot._timeplot.placeDiv(plot._valueFlagPole, {
+ left: x,
+ top: th - 5,
+ height: c.height - y - th + 6,
+ display: "block"
+ });
+ plot._timeplot.placeDiv(plot._timeFlag,{
+ left: tx - tdw,
+ top: -6,
+ display: "block"
+ });
+ } else {
+ plot._timeplot.placeDiv(plot._valueFlagPole, {
+ left: x,
+ bottom: th - 5,
+ height: y - th + 6,
+ display: "block"
+ });
+ plot._timeplot.placeDiv(plot._timeFlag,{
+ left: tx - tdw,
+ bottom: -6,
+ display: "block"
+ });
+ }
+
+ if (x + vw + 14 > c.width && y + vh + 4 > c.height) {
+ plot._valueFlagLineLeft.style.display = "none";
+ plot._timeplot.placeDiv(plot._valueFlagLineRight,{
+ left: x - 14,
+ bottom: y - 14,
+ display: "block"
+ });
+ plot._timeplot.placeDiv(plot._valueFlag,{
+ left: x - vw - 13,
+ bottom: y - vh - 13,
+ display: "block"
+ });
+ } else if (x + vw + 14 > c.width && y + vh + 4 < c.height) {
+ plot._valueFlagLineRight.style.display = "none";
+ plot._timeplot.placeDiv(plot._valueFlagLineLeft,{
+ left: x - 14,
+ bottom: y,
+ display: "block"
+ });
+ plot._timeplot.placeDiv(plot._valueFlag,{
+ left: x - vw - 13,
+ bottom: y + 13,
+ display: "block"
+ });
+ } else if (x + vw + 14 < c.width && y + vh + 4 > c.height) {
+ plot._valueFlagLineRight.style.display = "none";
+ plot._timeplot.placeDiv(plot._valueFlagLineLeft,{
+ left: x,
+ bottom: y - 13,
+ display: "block"
+ });
+ plot._timeplot.placeDiv(plot._valueFlag,{
+ left: x + 13,
+ bottom: y - 13,
+ display: "block"
+ });
+ } else {
+ plot._valueFlagLineLeft.style.display = "none";
+ plot._timeplot.placeDiv(plot._valueFlagLineRight,{
+ left: x,
+ bottom: y,
+ display: "block"
+ });
+ plot._timeplot.placeDiv(plot._valueFlag,{
+ left: x + 13,
+ bottom: y + 13,
+ display: "block"
+ });
+ }
+ }
+ }
+
+ var timeplotElement = this._timeplot.getElement();
+ SimileAjax.DOM.registerEvent(timeplotElement, "mouseover", mouseOverHandler);
+ SimileAjax.DOM.registerEvent(timeplotElement, "mousemove", mouseMoveHandler);
+ }
+ },
+
+ /**
+ * Dispose the plot layer and all the data sources and listeners associated to it
+ */
+ dispose: function() {
+ if (this._dataSource) {
+ this._dataSource.removeListener(this._paintingListener);
+ this._paintingListener = null;
+ this._dataSource.dispose();
+ this._dataSource = null;
+ }
+ },
+
+ /**
+ * Return the data source of this plot layer (it could be either a DataSource or an EventSource)
+ */
+ getDataSource: function() {
+ return (this._dataSource) ? this._dataSource : this._eventSource;
+ },
+
+ /**
+ * Return the time geometry associated with this plot layer
+ */
+ getTimeGeometry: function() {
+ return this._timeGeometry;
+ },
+
+ /**
+ * Return the value geometry associated with this plot layer
+ */
+ getValueGeometry: function() {
+ return this._valueGeometry;
+ },
+
+ /**
+ * Paint this plot layer
+ */
+ paint: function() {
+ var ctx = this._canvas.getContext('2d');
+
+ ctx.lineWidth = this._plotInfo.lineWidth;
+ ctx.lineJoin = 'miter';
+
+ if (this._dataSource) {
+ if (this._plotInfo.fillColor) {
+ if (this._plotInfo.fillGradient) {
+ var gradient = ctx.createLinearGradient(0,this._canvas.height,0,0);
+ gradient.addColorStop(0,this._plotInfo.fillColor.toString());
+ gradient.addColorStop(0.5,this._plotInfo.fillColor.toString());
+ gradient.addColorStop(1, 'rgba(255,255,255,0)');
+
+ ctx.fillStyle = gradient;
+ } else {
+ ctx.fillStyle = this._plotInfo.fillColor.toString();
+ }
+
+ ctx.beginPath();
+ ctx.moveTo(0,0);
+ this._plot(function(x,y) {
+ ctx.lineTo(x,y);
+ });
+ if (this._plotInfo.fillFrom == Number.NEGATIVE_INFINITY) {
+ ctx.lineTo(this._canvas.width, 0);
+ } else if (this._plotInfo.fillFrom == Number.POSITIVE_INFINITY) {
+ ctx.lineTo(this._canvas.width, this._canvas.height);
+ ctx.lineTo(0, this._canvas.height);
+ } else {
+ ctx.lineTo(this._canvas.width, this._valueGeometry.toScreen(this._plotInfo.fillFrom));
+ ctx.lineTo(0, this._valueGeometry.toScreen(this._plotInfo.fillFrom));
+ }
+ ctx.fill();
+ }
+
+ if (this._plotInfo.lineColor) {
+ ctx.strokeStyle = this._plotInfo.lineColor.toString();
+ ctx.beginPath();
+ var first = true;
+ this._plot(function(x,y) {
+ if (first) {
+ first = false;
+ ctx.moveTo(x,y);
+ }
+ ctx.lineTo(x,y);
+ });
+ ctx.stroke();
+ }
+
+ if (this._plotInfo.dotColor) {
+ ctx.fillStyle = this._plotInfo.dotColor.toString();
+ var r = this._plotInfo.dotRadius;
+ this._plot(function(x,y) {
+ ctx.beginPath();
+ ctx.arc(x,y,r,0,2*Math.PI,true);
+ ctx.fill();
+ });
+ }
+ }
+
+ if (this._eventSource) {
+ var gradient = ctx.createLinearGradient(0,0,0,this._canvas.height);
+ gradient.addColorStop(1, 'rgba(255,255,255,0)');
+
+ ctx.strokeStyle = gradient;
+ ctx.fillStyle = gradient;
+ ctx.lineWidth = this._plotInfo.eventLineWidth;
+ ctx.lineJoin = 'miter';
+
+ var i = this._eventSource.getAllEventIterator();
+ while (i.hasNext()) {
+ var event = i.next();
+ var color = event.getColor();
+ color = (color) ? new Timeplot.Color(color) : this._plotInfo.lineColor;
+ var eventStart = event.getStart().getTime();
+ var eventEnd = event.getEnd().getTime();
+ if (eventStart == eventEnd) {
+ var c = color.toString();
+ gradient.addColorStop(0, c);
+ var start = this._timeGeometry.toScreen(eventStart);
+ start = Math.floor(start) + 0.5; // center it between two pixels (makes the rendering nicer)
+ var end = start;
+ ctx.beginPath();
+ ctx.moveTo(start,0);
+ ctx.lineTo(start,this._canvas.height);
+ ctx.stroke();
+ var x = start - 4;
+ var w = 7;
+ } else {
+ var c = color.toString(0.5);
+ gradient.addColorStop(0, c);
+ var start = this._timeGeometry.toScreen(eventStart);
+ start = Math.floor(start) + 0.5; // center it between two pixels (makes the rendering nicer)
+ var end = this._timeGeometry.toScreen(eventEnd);
+ end = Math.floor(end) + 0.5; // center it between two pixels (makes the rendering nicer)
+ ctx.fillRect(start,0,end - start, this._canvas.height);
+ var x = start;
+ var w = end - start - 1;
+ }
+
+ var div = this._timeplot.putDiv(event.getID(),"timeplot-event-box",{
+ left: Math.round(x),
+ width: Math.round(w),
+ top: 0,
+ height: this._canvas.height - 1
+ });
+
+ var plot = this;
+ var clickHandler = function(event) {
+ return function(elmt, evt, target) {
+ var doc = plot._timeplot.getDocument();
+ plot._closeBubble();
+ var coords = SimileAjax.DOM.getEventPageCoordinates(evt);
+ var elmtCoords = SimileAjax.DOM.getPageCoordinates(elmt);
+ plot._bubble = SimileAjax.Graphics.createBubbleForPoint(coords.x, elmtCoords.top + plot._canvas.height, plot._plotInfo.bubbleWidth, plot._plotInfo.bubbleHeight, "bottom");
+ event.fillInfoBubble(plot._bubble.content, plot._theme, plot._timeGeometry.getLabeler());
+ }
+ };
+ var mouseOverHandler = function(elmt, evt, target) {
+ elmt.oldClass = elmt.className;
+ elmt.className = elmt.className + " timeplot-event-box-highlight";
+ };
+ var mouseOutHandler = function(elmt, evt, target) {
+ elmt.className = elmt.oldClass;
+ elmt.oldClass = null;
+ }
+
+ if (!div.instrumented) {
+ SimileAjax.DOM.registerEvent(div, "click" , clickHandler(event));
+ SimileAjax.DOM.registerEvent(div, "mouseover", mouseOverHandler);
+ SimileAjax.DOM.registerEvent(div, "mouseout" , mouseOutHandler);
+ div.instrumented = true;
+ }
+ }
+ }
+ },
+
+ _plot: function(f) {
+ var data = this._dataSource.getData();
+ if (data) {
+ var times = data.times;
+ var values = data.values;
+ var T = times.length;
+ for (var t = 0; t < T; t++) {
+ var x = this._timeGeometry.toScreen(times[t]);
+ var y = this._valueGeometry.toScreen(values[t]);
+ f(x, y);
+ }
+ }
+ },
+
+ _closeBubble: function() {
+ if (this._bubble != null) {
+ this._bubble.close();
+ this._bubble = null;
+ }
+ }
+
+}/**
+ * Sources
+ *
+ * @fileOverview Sources
+ * @name Sources
+ */
+
+/**
+ * Timeplot.DefaultEventSource is an extension of Timeline.DefaultEventSource
+ * and therefore reuses the exact same event loading subsystem that
+ * Timeline uses.
+ *
+ * @constructor
+ */
+Timeplot.DefaultEventSource = function(eventIndex) {
+ Timeline.DefaultEventSource.apply(this, arguments);
+};
+
+Object.extend(Timeplot.DefaultEventSource.prototype, Timeline.DefaultEventSource.prototype);
+
+/**
+ * Function used by Timeplot to load time series data from a text file.
+ */
+Timeplot.DefaultEventSource.prototype.loadText = function(text, separator, url, filter) {
+
+ if (text == null) {
+ return;
+ }
+
+ this._events.maxValues = new Array();
+ var base = this._getBaseURL(url);
+
+ var dateTimeFormat = 'iso8601';
+ var parseDateTimeFunction = this._events.getUnit().getParser(dateTimeFormat);
+
+// AMO change - moved to after filter so we can parse comments
+ //var data = this._parseText(text, separator);
+var data = text;
+
+ var added = false;
+
+ if (filter) {
+ data = filter(data);
+ }
+
+ data = this._parseText(data, separator);
+
+ if (data) {
+ for (var i = 0; i < data.length; i++){
+ var row = data[i];
+ if (row.length > 1) {
+ var evt = new Timeplot.DefaultEventSource.NumericEvent(
+ parseDateTimeFunction(row[0]),
+ row.slice(1)
+ );
+ this._events.add(evt);
+ added = true;
+ }
+ }
+ }
+
+ if (added) {
+ this._fire("onAddMany", []);
+ }
+}
+
+/*
+ * Parse the data file.
+ *
+ * Adapted from http://www.kawa.net/works/js/jkl/js/jkl-parsexml.js by Yusuke Kawasaki
+ */
+Timeplot.DefaultEventSource.prototype._parseText = function (text, separator) {
+ text = text.replace( /\r\n?/g, "\n" ); // normalize newlines
+ var pos = 0;
+ var len = text.length;
+ var table = [];
+ while (pos < len) {
+ var line = [];
+ if (text.charAt(pos) != '#') { // if it's not a comment, process
+ while (pos < len) {
+ if (text.charAt(pos) == '"') { // "..." quoted column
+ var nextquote = text.indexOf('"', pos+1 );
+ while (nextquote<len && nextquote > -1) {
+ if (text.charAt(nextquote+1) != '"') {
+ break; // end of column
+ }
+ nextquote = text.indexOf('"', nextquote + 2);
+ }
+ if ( nextquote < 0 ) {
+ // unclosed quote
+ } else if (text.charAt(nextquote + 1) == separator) { // end of column
+ var quoted = text.substr(pos + 1, nextquote-pos - 1);
+ quoted = quoted.replace(/""/g,'"');
+ line[line.length] = quoted;
+ pos = nextquote + 2;
+ continue;
+ } else if (text.charAt(nextquote + 1) == "\n" || // end of line
+ len == nextquote + 1 ) { // end of file
+ var quoted = text.substr(pos + 1, nextquote-pos - 1);
+ quoted = quoted.replace(/""/g,'"');
+ line[line.length] = quoted;
+ pos = nextquote + 2;
+ break;
+ } else {
+ // invalid column
+ }
+ }
+ var nextseparator = text.indexOf(separator, pos);
+ var nextnline = text.indexOf("\n", pos);
+ if (nextnline < 0) nextnline = len;
+ if (nextseparator > -1 && nextseparator < nextnline) {
+ line[line.length] = text.substr(pos, nextseparator-pos);
+ pos = nextseparator + 1;
+ } else { // end of line
+ line[line.length] = text.substr(pos, nextnline-pos);
+ pos = nextnline + 1;
+ break;
+ }
+ }
+ } else { // if it's a comment, ignore
+ var nextnline = text.indexOf("\n", pos);
+ pos = (nextnline > -1) ? nextnline + 1 : cur;
+ }
+ if (line.length > 0) {
+ table[table.length] = line; // push line
+ }
+ }
+ if (table.length < 0) return; // null data
+ return table;
+}
+
+/**
+ * Return the range of the loaded data
+ */
+Timeplot.DefaultEventSource.prototype.getRange = function() {
+ var earliestDate = this.getEarliestDate();
+ var latestDate = this.getLatestDate();
+ return {
+ earliestDate: (earliestDate) ? earliestDate : null,
+ latestDate: (latestDate) ? latestDate : null,
+ min: 0,
+ max: 0
+ };
+}
+
+// -----------------------------------------------------------------------
+
+/**
+ * A NumericEvent is an Event that also contains an array of values,
+ * one for each columns in the loaded data file.
+ *
+ * @constructor
+ */
+Timeplot.DefaultEventSource.NumericEvent = function(time, values) {
+ this._id = "e" + Math.round(Math.random() * 1000000);
+ this._time = time;
+ this._values = values;
+};
+
+Timeplot.DefaultEventSource.NumericEvent.prototype = {
+ getID: function() { return this._id; },
+ getTime: function() { return this._time; },
+ getValues: function() { return this._values; },
+
+ // these are required by the EventSource
+ getStart: function() { return this._time; },
+ getEnd: function() { return this._time; }
+};
+
+// -----------------------------------------------------------------------
+
+/**
+ * A DataSource represent an abstract class that represents a monodimensional time series.
+ *
+ * @constructor
+ */
+Timeplot.DataSource = function(eventSource) {
+ this._eventSource = eventSource;
+ var source = this;
+ this._processingListener = {
+ onAddMany: function() { source._process(); },
+ onClear: function() { source._clear(); }
+ }
+ this.addListener(this._processingListener);
+ this._listeners = [];
+ this._data = null;
+ this._range = null;
+};
+
+Timeplot.DataSource.prototype = {
+
+ _clear: function() {
+ this._data = null;
+ this._range = null;
+ },
+
+ _process: function() {
+ this._data = {
+ times: new Array(),
+ values: new Array()
+ };
+ this._range = {
+ earliestDate: null,
+ latestDate: null,
+ min: 0,
+ max: 0
+ };
+ },
+
+ /**
+ * Return the range of this data source
+ */
+ getRange: function() {
+ return this._range;
+ },
+
+ /**
+ * Return the actual data that this data source represents.
+ * NOTE: _data = { times: [], values: [] }
+ */
+ getData: function() {
+ return this._data;
+ },
+
+ /**
+ * Return the value associated with the given time in this time series
+ */
+ getValue: function(t) {
+ if (this._data) {
+ for (var i = 0; i < this._data.times.length; i++) {
+ var l = this._data.times[i];
+ if (l >= t) {
+ return this._data.values[i];
+ }
+ }
+ }
+ return 0;
+ },
+
+ /**
+ * Add a listener to the underlying event source
+ */
+ addListener: function(listener) {
+ this._eventSource.addListener(listener);
+ },
+
+ /**
+ * Remove a listener from the underlying event source
+ */
+ removeListener: function(listener) {
+ this._eventSource.removeListener(listener);
+ },
+
+ /**
+ * Replace a listener from the underlying event source
+ */
+ replaceListener: function(oldListener, newListener) {
+ this.removeListener(oldListener);
+ this.addListener(newListener);
+ }
+
+}
+
+// -----------------------------------------------------------------------
+
+/**
+ * Implementation of a DataSource that extracts the time series out of a
+ * single column from the events
+ *
+ * @constructor
+ */
+Timeplot.ColumnSource = function(eventSource, column) {
+ Timeplot.DataSource.apply(this, arguments);
+ this._column = column - 1;
+};
+
+Object.extend(Timeplot.ColumnSource.prototype,Timeplot.DataSource.prototype);
+
+Timeplot.ColumnSource.prototype.dispose = function() {
+ this.removeListener(this._processingListener);
+ this._clear();
+}
+
+Timeplot.ColumnSource.prototype._process = function() {
+ var count = this._eventSource.getCount();
+ var times = new Array(count);
+ var values = new Array(count);
+ var min = Number.MAX_VALUE;
+ var max = Number.MIN_VALUE;
+ var i = 0;
+
+ var iterator = this._eventSource.getAllEventIterator();
+ while (iterator.hasNext()) {
+ var event = iterator.next();
+ var time = event.getTime();
+ times[i] = time;
+ var value = this._getValue(event);
+ if (!isNaN(value)) {
+ if (value < min) {
+ min = value;
+ }
+ if (value > max) {
+ max = value;
+ }
+ values[i] = value;
+ }
+ i++;
+ }
+
+ this._data = {
+ times: times,
+ values: values
+ };
+
+ if (max == Number.MIN_VALUE) max = 1;
+
+ this._range = {
+ earliestDate: this._eventSource.getEarliestDate(),
+ latestDate: this._eventSource.getLatestDate(),
+ min: min,
+ max: max
+ };
+}
+
+Timeplot.ColumnSource.prototype._getValue = function(event) {
+ return parseFloat(event.getValues()[this._column]);
+}
+
+// ---------------------------------------------------------------
+
+/**
+ * Data Source that generates the time series out of the difference
+ * between the first and the second column
+ *
+ * @constructor
+ */
+Timeplot.ColumnDiffSource = function(eventSource, column1, column2) {
+ Timeplot.ColumnSource.apply(this, arguments);
+ this._column2 = column2 - 1;
+};
+
+Object.extend(Timeplot.ColumnDiffSource.prototype,Timeplot.ColumnSource.prototype);
+
+Timeplot.ColumnDiffSource.prototype._getValue = function(event) {
+ var a = parseFloat(event.getValues()[this._column]);
+ var b = parseFloat(event.getValues()[this._column2]);
+ return a - b;
+}
+/**
+ * Geometries
+ *
+ * @fileOverview Geometries
+ * @name Geometries
+ */
+
+/**
+ * This is the constructor for the default value geometry.
+ * A value geometry is what regulates mapping of the plot values to the screen y coordinate.
+ * If two plots share the same value geometry, they will be drawn using the same scale.
+ * If "min" and "max" parameters are not set, the geometry will stretch itself automatically
+ * so that the entire plot will be drawn without overflowing. The stretching happens also
+ * when a geometry is shared between multiple plots, the one with the biggest range will
+ * win over the others.
+ *
+ * @constructor
+ */
+Timeplot.DefaultValueGeometry = function(params) {
+ if (!params) params = {};
+ this._id = ("id" in params) ? params.id : "g" + Math.round(Math.random() * 1000000);
+ this._axisColor = ("axisColor" in params) ? ((typeof params.axisColor == "string") ? new Timeplot.Color(params.axisColor) : params.axisColor) : new Timeplot.Color("#606060"),
+ this._gridColor = ("gridColor" in params) ? ((typeof params.gridColor == "string") ? new Timeplot.Color(params.gridColor) : params.gridColor) : null,
+ this._gridLineWidth = ("gridLineWidth" in params) ? params.gridLineWidth : 0.5;
+ this._axisLabelsPlacement = ("axisLabelsPlacement" in params) ? params.axisLabelsPlacement : "right";
+ this._gridSpacing = ("gridSpacing" in params) ? params.gridStep : 50;
+ this._gridType = ("gridType" in params) ? params.gridType : "short";
+ this._gridShortSize = ("gridShortSize" in params) ? params.gridShortSize : 10;
+ this._minValue = ("min" in params) ? params.min : null;
+ this._maxValue = ("max" in params) ? params.max : null;
+ this._linMap = {
+ direct: function(v) {
+ return v;
+ },
+ inverse: function(y) {
+ return y;
+ }
+ }
+ this._map = this._linMap;
+ this._labels = [];
+ this._grid = [];
+}
+
+Timeplot.DefaultValueGeometry.prototype = {
+
+ /**
+ * Since geometries can be reused across timeplots, we need to call this function
+ * before we can paint using this geometry.
+ */
+ setTimeplot: function(timeplot) {
+ this._timeplot = timeplot;
+ this._canvas = timeplot.getCanvas();
+ this.reset();
+ },
+
+ /**
+ * Called by all the plot layers this geometry is associated with
+ * to update the value range. Unless min/max values are specified
+ * in the parameters, the biggest value range will be used.
+ */
+ setRange: function(range) {
+ if ((this._minValue == null) || ((this._minValue != null) && (range.min < this._minValue))) {
+ this._minValue = range.min;
+ }
+ if ((this._maxValue == null) || ((this._maxValue != null) && (range.max * 1.05 > this._maxValue))) {
+ this._maxValue = range.max * 1.05; // get a little more head room to avoid hitting the ceiling
+ }
+
+ this._updateMappedValues();
+
+ if (!(this._minValue == 0 && this._maxValue == 0)) {
+ this._grid = this._calculateGrid();
+ }
+ },
+
+ /**
+ * Called after changing ranges or canvas size to reset the grid values
+ */
+ reset: function() {
+ this._clearLabels();
+ this._updateMappedValues();
+ this._grid = this._calculateGrid();
+ },
+
+ /**
+ * Map the given value to a y screen coordinate.
+ */
+ toScreen: function(value) {
+ if (this._canvas && this._maxValue) {
+ var v = value - this._minValue;
+ return this._canvas.height * (this._map.direct(v)) / this._mappedRange;
+ } else {
+ return -50;
+ }
+ },
+
+ /**
+ * Map the given y screen coordinate to a value
+ */
+ fromScreen: function(y) {
+ if (this._canvas) {
+ return this._map.inverse(this._mappedRange * y / this._canvas.height) + this._minValue;
+ } else {
+ return 0;
+ }
+ },
+
+ /**
+ * Each geometry is also a painter and paints the value grid and grid labels.
+ */
+ paint: function() {
+ if (this._timeplot) {
+ var ctx = this._canvas.getContext('2d');
+
+ ctx.lineJoin = 'miter';
+
+ // paint grid
+ if (this._gridColor) {
+ var gridGradient = ctx.createLinearGradient(0,0,0,this._canvas.height);
+ gridGradient.addColorStop(0, this._gridColor.toHexString());
+ gridGradient.addColorStop(0.3, this._gridColor.toHexString());
+ gridGradient.addColorStop(1, "rgba(255,255,255,0.5)");
+
+ ctx.lineWidth = this._gridLineWidth;
+ ctx.strokeStyle = gridGradient;
+
+ for (var i = 0; i < this._grid.length; i++) {
+ var tick = this._grid[i];
+ var y = Math.floor(tick.y) + 0.5;
+ if (typeof tick.label != "undefined") {
+ if (this._axisLabelsPlacement == "left") {
+ var div = this._timeplot.putText(this._id + "-" + i, tick.label,"timeplot-grid-label",{
+ left: 4,
+ bottom: y + 2,
+ color: this._gridColor.toHexString(),
+ visibility: "hidden"
+ });
+ } else if (this._axisLabelsPlacement == "right") {
+ var div = this._timeplot.putText(this._id + "-" + i, tick.label, "timeplot-grid-label",{
+ right: 4,
+ bottom: y + 2,
+ color: this._gridColor.toHexString(),
+ visibility: "hidden"
+ });
+ }
+ if (y + div.clientHeight < this._canvas.height + 10) {
+ div.style.visibility = "visible"; // avoid the labels that would overflow
+ }
+ }
+
+ // draw grid
+ ctx.beginPath();
+ if (this._gridType == "long" || tick.label == 0) {
+ ctx.moveTo(0, y);
+ ctx.lineTo(this._canvas.width, y);
+ } else if (this._gridType == "short") {
+ if (this._axisLabelsPlacement == "left") {
+ ctx.moveTo(0, y);
+ ctx.lineTo(this._gridShortSize, y);
+ } else if (this._axisLabelsPlacement == "right") {
+ ctx.moveTo(this._canvas.width, y);
+ ctx.lineTo(this._canvas.width - this._gridShortSize, y);
+ }
+ }
+ ctx.stroke();
+ }
+ }
+
+ // paint axis
+ var axisGradient = ctx.createLinearGradient(0,0,0,this._canvas.height);
+ axisGradient.addColorStop(0, this._axisColor.toString());
+ axisGradient.addColorStop(0.5, this._axisColor.toString());
+ axisGradient.addColorStop(1, "rgba(255,255,255,0.5)");
+
+ ctx.lineWidth = 1;
+ ctx.strokeStyle = axisGradient;
+
+ // left axis
+ ctx.beginPath();
+ ctx.moveTo(0,this._canvas.height);
+ ctx.lineTo(0,0);
+ ctx.stroke();
+
+ // right axis
+ ctx.beginPath();
+ ctx.moveTo(this._canvas.width,0);
+ ctx.lineTo(this._canvas.width,this._canvas.height);
+ ctx.stroke();
+ }
+ },
+
+ /**
+ * Removes all the labels that were added by this geometry
+ */
+ _clearLabels: function() {
+ for (var i = 0; i < this._labels.length; i++) {
+ var l = this._labels[i];
+ var parent = l.parentNode;
+ if (parent) parent.removeChild(l);
+ }
+ },
+
+ /*
+ * This function calculates the grid spacing that it will be used
+ * by this geometry to draw the grid in order to reduce clutter.
+ */
+ _calculateGrid: function() {
+ var grid = [];
+
+ if (!this._canvas || this._valueRange == 0) return grid;
+
+ var power = 0;
+ if (this._valueRange > 1) {
+ while (Math.pow(10,power) < this._valueRange) {
+ power++;
+ }
+ power--;
+ } else {
+ while (Math.pow(10,power) > this._valueRange) {
+ power--;
+ }
+ }
+
+ var unit = Math.pow(10,power);
+ var inc = unit;
+ while (true) {
+ var dy = this.toScreen(this._minValue + inc);
+
+ while (dy < this._gridSpacing) {
+ inc += unit;
+ dy = this.toScreen(this._minValue + inc);
+ }
+
+ if (dy > 2 * this._gridSpacing) { // grids are too spaced out
+ unit /= 10;
+ inc = unit;
+ } else {
+ break;
+ }
+ }
+
+ var v = 0;
+ var y = this.toScreen(v);
+ if (this._minValue >= 0) {
+ while (y < this._canvas.height) {
+ if (y > 0) {
+ grid.push({ y: y, label: v });
+ }
+ v += inc;
+ y = this.toScreen(v);
+ }
+ } else if (this._maxValue <= 0) {
+ while (y > 0) {
+ if (y < this._canvas.height) {
+ grid.push({ y: y, label: v });
+ }
+ v -= inc;
+ y = this.toScreen(v);
+ }
+ } else {
+ while (y < this._canvas.height) {
+ if (y > 0) {
+ grid.push({ y: y, label: v });
+ }
+ v += inc;
+ y = this.toScreen(v);
+ }
+ v = -inc;
+ y = this.toScreen(v);
+ while (y > 0) {
+ if (y < this._canvas.height) {
+ grid.push({ y: y, label: v });
+ }
+ v -= inc;
+ y = this.toScreen(v);
+ }
+ }
+
+ return grid;
+ },
+
+ /*
+ * Update the values that are used by the paint function so that
+ * we don't have to calculate them at every repaint.
+ */
+ _updateMappedValues: function() {
+ this._valueRange = Math.abs(this._maxValue - this._minValue);
+ this._mappedRange = this._map.direct(this._valueRange);
+ }
+
+}
+
+// --------------------------------------------------
+
+/**
+ * This is the constructor for a Logarithmic value geometry, which
+ * is useful when plots have values in different magnitudes but
+ * exhibit similar trends and such trends want to be shown on the same
+ * plot (here a cartesian geometry would make the small magnitudes
+ * disappear).
+ *
+ * NOTE: this class extends Timeplot.DefaultValueGeometry and inherits
+ * all of the methods of that class. So refer to that class.
+ *
+ * @constructor
+ */
+Timeplot.LogarithmicValueGeometry = function(params) {
+ Timeplot.DefaultValueGeometry.apply(this, arguments);
+ this._logMap = {
+ direct: function(v) {
+ return Math.log(v + 1) / Math.log(10);
+ },
+ inverse: function(y) {
+ return Math.exp(Math.log(10) * y) - 1;
+ }
+ }
+ this._mode = "log";
+ this._map = this._logMap;
+ this._calculateGrid = this._logarithmicCalculateGrid;
+};
+
+Timeplot.LogarithmicValueGeometry.prototype._linearCalculateGrid = Timeplot.DefaultValueGeometry.prototype._calculateGrid;
+
+Object.extend(Timeplot.LogarithmicValueGeometry.prototype,Timeplot.DefaultValueGeometry.prototype);
+
+/*
+ * This function calculates the grid spacing that it will be used
+ * by this geometry to draw the grid in order to reduce clutter.
+ */
+Timeplot.LogarithmicValueGeometry.prototype._logarithmicCalculateGrid = function() {
+ var grid = [];
+
+ if (!this._canvas || this._valueRange == 0) return grid;
+
+ var v = 1;
+ var y = this.toScreen(v);
+ while (y < this._canvas.height || isNaN(y)) {
+ if (y > 0) {
+ grid.push({ y: y, label: v });
+ }
+ v *= 10;
+ y = this.toScreen(v);
+ }
+
+ return grid;
+};
+
+/**
+ * Turn the logarithmic scaling off.
+ */
+Timeplot.LogarithmicValueGeometry.prototype.actLinear = function() {
+ this._mode = "lin";
+ this._map = this._linMap;
+ this._calculateGrid = this._linearCalculateGrid;
+ this.reset();
+}
+
+/**
+ * Turn the logarithmic scaling on.
+ */
+Timeplot.LogarithmicValueGeometry.prototype.actLogarithmic = function() {
+ this._mode = "log";
+ this._map = this._logMap;
+ this._calculateGrid = this._logarithmicCalculateGrid;
+ this.reset();
+}
+
+/**
+ * Toggle logarithmic scaling seeting it to on if off and viceversa.
+ */
+Timeplot.LogarithmicValueGeometry.prototype.toggle = function() {
+ if (this._mode == "log") {
+ this.actLinear();
+ } else {
+ this.actLogarithmic();
+ }
+}
+
+// -----------------------------------------------------
+
+/**
+ * This is the constructor for the default time geometry.
+ *
+ * @constructor
+ */
+Timeplot.DefaultTimeGeometry = function(params) {
+ if (!params) params = {};
+ this._id = ("id" in params) ? params.id : "g" + Math.round(Math.random() * 1000000);
+ this._locale = ("locale" in params) ? params.locale : "en";
+ this._timeZone = ("timeZone" in params) ? params.timeZone : SimileAjax.DateTime.getTimezone();
+ this._labeller = ("labeller" in params) ? params.labeller : null;
+ this._axisColor = ("axisColor" in params) ? ((params.axisColor == "string") ? new Timeplot.Color(params.axisColor) : params.axisColor) : new Timeplot.Color("#606060"),
+ this._gridColor = ("gridColor" in params) ? ((params.gridColor == "string") ? new Timeplot.Color(params.gridColor) : params.gridColor) : null,
+ this._gridLineWidth = ("gridLineWidth" in params) ? params.gridLineWidth : 0.5;
+ this._axisLabelsPlacement = ("axisLabelsPlacement" in params) ? params.axisLabelsPlacement : "bottom";
+ this._gridStep = ("gridStep" in params) ? params.gridStep : 100;
+ this._gridStepRange = ("gridStepRange" in params) ? params.gridStepRange : 20;
+ this._min = ("min" in params) ? params.min : null;
+ this._max = ("max" in params) ? params.max : null;
+ this._timeValuePosition =("timeValuePosition" in params) ? params.timeValuePosition : "bottom";
+ this._unit = ("unit" in params) ? params.unit : Timeline.NativeDateUnit;
+ this._linMap = {
+ direct: function(t) {
+ return t;
+ },
+ inverse: function(x) {
+ return x;
+ }
+ }
+ this._map = this._linMap;
+ this._labeler = this._unit.createLabeller(this._locale, this._timeZone);
+ var dateParser = this._unit.getParser("iso8601");
+ if (this._min && !this._min.getTime) {
+ this._min = dateParser(this._min);
+ }
+ if (this._max && !this._max.getTime) {
+ this._max = dateParser(this._max);
+ }
+ this._grid = [];
+}
+
+Timeplot.DefaultTimeGeometry.prototype = {
+
+ /**
+ * Since geometries can be reused across timeplots, we need to call this function
+ * before we can paint using this geometry.
+ */
+ setTimeplot: function(timeplot) {
+ this._timeplot = timeplot;
+ this._canvas = timeplot.getCanvas();
+ this.reset();
+ },
+
+ /**
+ * Called by all the plot layers this geometry is associated with
+ * to update the time range. Unless min/max values are specified
+ * in the parameters, the biggest range will be used.
+ */
+ setRange: function(range) {
+ if (this._min) {
+ this._earliestDate = this._min;
+ } else if (range.earliestDate && ((this._earliestDate == null) || ((this._earliestDate != null) && (range.earliestDate.getTime() < this._earliestDate.getTime())))) {
+ this._earliestDate = range.earliestDate;
+ }
+
+ if (this._max) {
+ this._latestDate = this._max;
+ } else if (range.latestDate && ((this._latestDate == null) || ((this._latestDate != null) && (range.latestDate.getTime() > this._latestDate.getTime())))) {
+ this._latestDate = range.latestDate;
+ }
+
+ if (!this._earliestDate && !this._latestDate) {
+ this._grid = [];
+ } else {
+ this.reset();
+ }
+ },
+
+ /**
+ * Called after changing ranges or canvas size to reset the grid values
+ */
+ reset: function() {
+ this._updateMappedValues();
+ if (this._canvas) this._grid = this._calculateGrid();
+ },
+
+ /**
+ * Map the given date to a x screen coordinate.
+ */
+ toScreen: function(time) {
+ if (this._canvas && this._latestDate) {
+ var t = time - this._earliestDate.getTime();
+ return this._canvas.width * this._map.direct(t) / this._mappedPeriod;
+ } else {
+ return -50;
+ }
+ },
+
+ /**
+ * Map the given x screen coordinate to a date.
+ */
+ fromScreen: function(x) {
+ if (this._canvas) {
+ return this._map.inverse(this._mappedPeriod * x / this._canvas.width) + this._earliestDate.getTime();
+ } else {
+ return 0;
+ }
+ },
+
+ /**
+ * Get a period (in milliseconds) this time geometry spans.
+ */
+ getPeriod: function() {
+ return this._period;
+ },
+
+ /**
+ * Return the labeler that has been associated with this time geometry
+ */
+ getLabeler: function() {
+ return this._labeler;
+ },
+
+ /**
+ * Return the time unit associated with this time geometry
+ */
+ getUnit: function() {
+ return this._unit;
+ },
+
+ /**
+ * Each geometry is also a painter and paints the value grid and grid labels.
+ */
+ paint: function() {
+ if (this._canvas) {
+ var unit = this._unit;
+ var ctx = this._canvas.getContext('2d');
+
+ var gradient = ctx.createLinearGradient(0,0,0,this._canvas.height);
+
+ ctx.strokeStyle = gradient;
+ ctx.lineWidth = this._gridLineWidth;
+ ctx.lineJoin = 'miter';
+
+ // paint grid
+ if (this._gridColor) {
+ gradient.addColorStop(0, this._gridColor.toString());
+ gradient.addColorStop(1, "rgba(255,255,255,0.9)");
+
+ for (var i = 0; i < this._grid.length; i++) {
+ var tick = this._grid[i];
+ var x = Math.floor(tick.x) + 0.5;
+ if (this._axisLabelsPlacement == "top") {
+ var div = this._timeplot.putText(this._id + "-" + i, tick.label,"timeplot-grid-label",{
+ left: x + 4,
+ top: 2,
+ visibility: "hidden"
+ });
+ } else if (this._axisLabelsPlacement == "bottom") {
+ var div = this._timeplot.putText(this._id + "-" + i, tick.label, "timeplot-grid-label",{
+ left: x + 4,
+ bottom: 2,
+ visibility: "hidden"
+ });
+ }
+ if (x + div.clientWidth < this._canvas.width + 10) {
+ div.style.visibility = "visible"; // avoid the labels that would overflow
+ }
+
+ // draw separator
+ ctx.beginPath();
+ ctx.moveTo(x,0);
+ ctx.lineTo(x,this._canvas.height);
+ ctx.stroke();
+ }
+ }
+
+ // paint axis
+ gradient.addColorStop(0, this._axisColor.toString());
+ gradient.addColorStop(1, "rgba(255,255,255,0.5)");
+
+ ctx.lineWidth = 1;
+ gradient.addColorStop(0, this._axisColor.toString());
+
+ ctx.beginPath();
+ ctx.moveTo(0,0);
+ ctx.lineTo(this._canvas.width,0);
+ ctx.stroke();
+ }
+ },
+
+ /*
+ * This function calculates the grid spacing that it will be used
+ * by this geometry to draw the grid in order to reduce clutter.
+ */
+ _calculateGrid: function() {
+ var grid = [];
+
+ var time = SimileAjax.DateTime;
+ var u = this._unit;
+ var p = this._period;
+
+ if (p == 0) return grid;
+
+ // find the time units nearest to the time period
+ if (p > time.gregorianUnitLengths[time.MILLENNIUM]) {
+ unit = time.MILLENNIUM;
+ } else {
+ for (var unit = time.MILLENNIUM; unit > 0; unit--) {
+ if (time.gregorianUnitLengths[unit-1] <= p && p < time.gregorianUnitLengths[unit]) {
+ unit--;
+ break;
+ }
+ }
+ }
+
+ var t = u.cloneValue(this._earliestDate);
+
+ do {
+ time.roundDownToInterval(t, unit, this._timeZone, 1, 0);
+ var x = this.toScreen(u.toNumber(t));
+ switch (unit) {
+ case time.SECOND:
+ var l = t.toLocaleTimeString();
+ break;
+ case time.MINUTE:
+ var m = t.getMinutes();
+ var l = t.getHours() + ":" + ((m < 10) ? "0" : "") + m;
+ break;
+ case time.HOUR:
+ var l = t.getHours() + ":00";
+ break;
+ case time.DAY:
+ case time.WEEK:
+ case time.MONTH:
+ var l = t.toLocaleDateString();
+ break;
+ case time.YEAR:
+ case time.DECADE:
+ case time.CENTURY:
+ case time.MILLENNIUM:
+ var l = t.getUTCFullYear();
+ break;
+ }
+ if (x > 0) {
+ grid.push({ x: x, label: l });
+ }
+ time.incrementByInterval(t, unit, this._timeZone);
+ } while (t.getTime() < this._latestDate.getTime());
+
+ return grid;
+ },
+
+ /*
+ * Update the values that are used by the paint function so that
+ * we don't have to calculate them at every repaint.
+ */
+ _updateMappedValues: function() {
+ if (this._latestDate && this._earliestDate) {
+ this._period = this._latestDate.getTime() - this._earliestDate.getTime();
+ this._mappedPeriod = this._map.direct(this._period);
+ } else {
+ this._period = 0;
+ this._mappedPeriod = 0;
+ }
+ }
+
+}
+
+// --------------------------------------------------------------
+
+/**
+ * This is the constructor for the magnifying time geometry.
+ * Users can interact with this geometry and 'magnify' certain areas of the
+ * plot to see the plot enlarged and resolve details that would otherwise
+ * get lost or cluttered with a linear time geometry.
+ *
+ * @constructor
+ */
+Timeplot.MagnifyingTimeGeometry = function(params) {
+ Timeplot.DefaultTimeGeometry.apply(this, arguments);
+
+ var g = this;
+ this._MagnifyingMap = {
+ direct: function(t) {
+ if (t < g._leftTimeMargin) {
+ var x = t * g._leftRate;
+ } else if ( g._leftTimeMargin < t && t < g._rightTimeMargin ) {
+ var x = t * g._expandedRate + g._expandedTimeTranslation;
+ } else {
+ var x = t * g._rightRate + g._rightTimeTranslation;
+ }
+ return x;
+ },
+ inverse: function(x) {
+ if (x < g._leftScreenMargin) {
+ var t = x / g._leftRate;
+ } else if ( g._leftScreenMargin < x && x < g._rightScreenMargin ) {
+ var t = x / g._expandedRate + g._expandedScreenTranslation;
+ } else {
+ var t = x / g._rightRate + g._rightScreenTranslation;
+ }
+ return t;
+ }
+ }
+
+ this._mode = "lin";
+ this._map = this._linMap;
+};
+
+Object.extend(Timeplot.MagnifyingTimeGeometry.prototype,Timeplot.DefaultTimeGeometry.prototype);
+
+/**
+ * Initialize this geometry associating it with the given timeplot and
+ * register the geometry event handlers to the timeplot so that it can
+ * interact with the user.
+ */
+Timeplot.MagnifyingTimeGeometry.prototype.initialize = function(timeplot) {
+ Timeplot.DefaultTimeGeometry.prototype.initialize.apply(this, arguments);
+
+ if (!this._lens) {
+ this._lens = this._timeplot.putDiv("lens","timeplot-lens");
+ }
+
+ var period = 1000 * 60 * 60 * 24 * 30; // a month in the magnifying lens
+
+ var geometry = this;
+
+ var magnifyWith = function(lens) {
+ var aperture = lens.clientWidth;
+ var loc = geometry._timeplot.locate(lens);
+ geometry.setMagnifyingParams(loc.x + aperture / 2, aperture, period);
+ geometry.actMagnifying();
+ geometry._timeplot.paint();
+ }
+
+ var canvasMouseDown = function(elmt, evt, target) {
+ geometry._canvas.startCoords = SimileAjax.DOM.getEventRelativeCoordinates(evt,elmt);
+ geometry._canvas.pressed = true;
+ }
+
+ var canvasMouseUp = function(elmt, evt, target) {
+ geometry._canvas.pressed = false;
+ var coords = SimileAjax.DOM.getEventRelativeCoordinates(evt,elmt);
+ if (Timeplot.Math.isClose(coords,geometry._canvas.startCoords,5)) {
+ geometry._lens.style.display = "none";
+ geometry.actLinear();
+ geometry._timeplot.paint();
+ } else {
+ geometry._lens.style.cursor = "move";
+ magnifyWith(geometry._lens);
+ }
+ }
+
+ var canvasMouseMove = function(elmt, evt, target) {
+ if (geometry._canvas.pressed) {
+ var coords = SimileAjax.DOM.getEventRelativeCoordinates(evt,elmt);
+ if (coords.x < 0) coords.x = 0;
+ if (coords.x > geometry._canvas.width) coords.x = geometry._canvas.width;
+ geometry._timeplot.placeDiv(geometry._lens, {
+ left: geometry._canvas.startCoords.x,
+ width: coords.x - geometry._canvas.startCoords.x,
+ bottom: 0,
+ height: geometry._canvas.height,
+ display: "block"
+ });
+ }
+ }
+
+ var lensMouseDown = function(elmt, evt, target) {
+ geometry._lens.startCoords = SimileAjax.DOM.getEventRelativeCoordinates(evt,elmt);;
+ geometry._lens.pressed = true;
+ }
+
+ var lensMouseUp = function(elmt, evt, target) {
+ geometry._lens.pressed = false;
+ }
+
+ var lensMouseMove = function(elmt, evt, target) {
+ if (geometry._lens.pressed) {
+ var coords = SimileAjax.DOM.getEventRelativeCoordinates(evt,elmt);
+ var lens = geometry._lens;
+ var left = lens.offsetLeft + coords.x - lens.startCoords.x;
+ if (left < geometry._timeplot._paddingX) left = geometry._timeplot._paddingX;
+ if (left + lens.clientWidth > geometry._canvas.width - geometry._timeplot._paddingX) left = geometry._canvas.width - lens.clientWidth + geometry._timeplot._paddingX;
+ lens.style.left = left;
+ magnifyWith(lens);
+ }
+ }
+
+ if (!this._canvas.instrumented) {
+ SimileAjax.DOM.registerEvent(this._canvas, "mousedown", canvasMouseDown);
+ SimileAjax.DOM.registerEvent(this._canvas, "mousemove", canvasMouseMove);
+ SimileAjax.DOM.registerEvent(this._canvas, "mouseup" , canvasMouseUp);
+ SimileAjax.DOM.registerEvent(this._canvas, "mouseup" , lensMouseUp);
+ this._canvas.instrumented = true;
+ }
+
+ if (!this._lens.instrumented) {
+ SimileAjax.DOM.registerEvent(this._lens, "mousedown", lensMouseDown);
+ SimileAjax.DOM.registerEvent(this._lens, "mousemove", lensMouseMove);
+ SimileAjax.DOM.registerEvent(this._lens, "mouseup" , lensMouseUp);
+ SimileAjax.DOM.registerEvent(this._lens, "mouseup" , canvasMouseUp);
+ this._lens.instrumented = true;
+ }
+}
+
+/**
+ * Set the Magnifying parameters. c is the location in pixels where the Magnifying
+ * center should be located in the timeplot, a is the aperture in pixel of
+ * the Magnifying and b is the time period in milliseconds that the Magnifying
+ * should span.
+ */
+Timeplot.MagnifyingTimeGeometry.prototype.setMagnifyingParams = function(c,a,b) {
+ a = a / 2;
+ b = b / 2;
+
+ var w = this._canvas.width;
+ var d = this._period;
+
+ if (c < 0) c = 0;
+ if (c > w) c = w;
+
+ if (c - a < 0) a = c;
+ if (c + a > w) a = w - c;
+
+ var ct = this.fromScreen(c) - this._earliestDate.getTime();
+ if (ct - b < 0) b = ct;
+ if (ct + b > d) b = d - ct;
+
+ this._centerX = c;
+ this._centerTime = ct;
+ this._aperture = a;
+ this._aperturePeriod = b;
+
+ this._leftScreenMargin = this._centerX - this._aperture;
+ this._rightScreenMargin = this._centerX + this._aperture;
+ this._leftTimeMargin = this._centerTime - this._aperturePeriod;
+ this._rightTimeMargin = this._centerTime + this._aperturePeriod;
+
+ this._leftRate = (c - a) / (ct - b);
+ this._expandedRate = a / b;
+ this._rightRate = (w - c - a) / (d - ct - b);
+
+ this._expandedTimeTranslation = this._centerX - this._centerTime * this._expandedRate;
+ this._expandedScreenTranslation = this._centerTime - this._centerX / this._expandedRate;
+ this._rightTimeTranslation = (c + a) - (ct + b) * this._rightRate;
+ this._rightScreenTranslation = (ct + b) - (c + a) / this._rightRate;
+
+ this._updateMappedValues();
+}
+
+/*
+ * Turn magnification off.
+ */
+Timeplot.MagnifyingTimeGeometry.prototype.actLinear = function() {
+ this._mode = "lin";
+ this._map = this._linMap;
+ this.reset();
+}
+
+/*
+ * Turn magnification on.
+ */
+Timeplot.MagnifyingTimeGeometry.prototype.actMagnifying = function() {
+ this._mode = "Magnifying";
+ this._map = this._MagnifyingMap;
+ this.reset();
+}
+
+/*
+ * Toggle magnification.
+ */
+Timeplot.MagnifyingTimeGeometry.prototype.toggle = function() {
+ if (this._mode == "Magnifying") {
+ this.actLinear();
+ } else {
+ this.actMagnifying();
+ }
+}
+
+/**
+ * Color
+ *
+ * @fileOverview Color
+ * @name Color
+ */
+
+/*
+ * Inspired by Plotr
+ * Copyright 2007 (c) Bas Wenneker <sabmann[a]gmail[d]com>
+ * For use under the BSD license. <http://www.solutoire.com/plotr>
+ */
+
+/**
+ * Create a Color object that can be used to manipulate colors programmatically.
+ */
+Timeplot.Color = function(color) {
+ this._fromHex(color);
+};
+
+Timeplot.Color.prototype = {
+
+ /**
+ * Sets the RGB values of this coor
+ *
+ * @param {Number} r,g,b Red green and blue values (between 0 and 255)
+ */
+ set: function (r,g,b,a) {
+ this.r = r;
+ this.g = g;
+ this.b = b;
+ this.a = (a) ? a : 1.0;
+ return this.check();
+ },
+
+ /**
+ * Set the color transparency
+ *
+ * @param {float} a Transparency value, between 0.0 (fully transparent) and 1.0 (fully opaque).
+ */
+ transparency: function(a) {
+ this.a = a;
+ return this.check();
+ },
+
+ /**
+ * Lightens the color.
+ *
+ * @param {integer} level Level to lighten the color with.
+ */
+ lighten: function(level) {
+ var color = new Timeplot.Color();
+ return color.set(
+ this.r += parseInt(level, 10),
+ this.g += parseInt(level, 10),
+ this.b += parseInt(level, 10)
+ );
+ },
+
+ /**
+ * Darkens the color.
+ *
+ * @param {integer} level Level to darken the color with.
+ */
+ darken: function(level){
+ var color = new Timeplot.Color();
+ return color.set(
+ this.r -= parseInt(level, 10),
+ this.g -= parseInt(level, 10),
+ this.b -= parseInt(level, 10)
+ );
+ },
+
+ /**
+ * Checks and validates if the hex values r, g and b are
+ * between 0 and 255.
+ */
+ check: function() {
+ if (this.r > 255) {
+ this.r = 255;
+ } else if (this.r < 0){
+ this.r = 0;
+ }
+ if (this.g > 255) {
+ this.g = 255;
+ } else if (this.g < 0) {
+ this.g = 0;
+ }
+ if (this.b > 255){
+ this.b = 255;
+ } else if (this.b < 0){
+ this.b = 0;
+ }
+ if (this.a > 1.0){
+ this.a = 1.0;
+ } else if (this.a < 0.0){
+ this.a = 0.0;
+ }
+ return this;
+ },
+
+ /**
+ * Returns a string representation of this color.
+ *
+ * @param {float} alpha (optional) Transparency value, between 0.0 (fully transparent) and 1.0 (fully opaque).
+ */
+ toString: function(alpha) {
+ var a = (alpha) ? alpha : ((this.a) ? this.a : 1.0);
+ return 'rgba(' + this.r + ',' + this.g + ',' + this.b + ',' + a + ')';
+ },
+
+ /**
+ * Returns the hexadecimal representation of this color (without the alpha channel as hex colors don't support it)
+ */
+ toHexString: function() {
+ return "#" + this._toHex(this.r) + this._toHex(this.g) + this._toHex(this.b);
+ },
+
+ /*
+ * Parses and stores the hex values of the input color string.
+ *
+ * @param {String} color Hex or rgb() css string.
+ */
+ _fromHex: function(color) {
+ if(/^#?([\da-f]{3}|[\da-f]{6})$/i.test(color)){
+ color = color.replace(/^#/, '').replace(/^([\da-f])([\da-f])([\da-f])$/i, "$1$1$2$2$3$3");
+ this.r = parseInt(color.substr(0,2), 16);
+ this.g = parseInt(color.substr(2,2), 16);
+ this.b = parseInt(color.substr(4,2), 16);
+ } else if(/^rgb *\( *\d{0,3} *, *\d{0,3} *, *\d{0,3} *\)$/i.test(color)){
+ color = color.match(/^rgb *\( *(\d{0,3}) *, *(\d{0,3}) *, *(\d{0,3}) *\)$/i);
+ this.r = parseInt(color[1], 10);
+ this.g = parseInt(color[2], 10);
+ this.b = parseInt(color[3], 10);
+ }
+ this.a = 1.0;
+ return this.check();
+ },
+
+ /*
+ * Returns an hexadecimal representation of a 8 bit integer
+ */
+ _toHex: function(dec) {
+ var hex = "0123456789ABCDEF"
+ if (dec < 0) return "00";
+ if (dec > 255) return "FF";
+ var i = Math.floor(dec / 16);
+ var j = dec % 16;
+ return hex.charAt(i) + hex.charAt(j);
+ }
+
+};/**
+ * Math Utility functions
+ *
+ * @fileOverview Math Utility functions
+ * @name Math
+ */
+
+Timeplot.Math = {
+
+ /**
+ * Evaluates the range (min and max values) of the given array
+ */
+ range: function(f) {
+ var F = f.length;
+ var min = Number.MAX_VALUE;
+ var max = Number.MIN_VALUE;
+
+ for (var t = 0; t < F; t++) {
+ var value = f[t];
+ if (value < min) {
+ min = value;
+ }
+ if (value > max) {
+ max = value;
+ }
+ }
+
+ return {
+ min: min,
+ max: max
+ }
+ },
+
+ /**
+ * Evaluates the windows average of a given array based on the
+ * given window size
+ */
+ movingAverage: function(f, size) {
+ var F = f.length;
+ var g = new Array(F);
+ for (var n = 0; n < F; n++) {
+ var value = 0;
+ for (var m = n - size; m < n + size; m++) {
+ if (m < 0) {
+ var v = f[0];
+ } else if (m >= F) {
+ var v = g[n-1];
+ } else {
+ var v = f[m];
+ }
+ value += v;
+ }
+ g[n] = value / (2 * size);
+ }
+ return g;
+ },
+
+ /**
+ * Returns an array with the integral of the given array
+ */
+ integral: function(f) {
+ var F = f.length;
+
+ var g = new Array(F);
+ var sum = 0;
+
+ for (var t = 0; t < F; t++) {
+ sum += f[t];
+ g[t] = sum;
+ }
+
+ return g;
+ },
+
+ /**
+ * Normalizes an array so that its complete integral is 1.
+ * This is useful to obtain arrays that preserve the overall
+ * integral of a convolution.
+ */
+ normalize: function(f) {
+ var F = f.length;
+ var sum = 0.0;
+
+ for (var t = 0; t < F; t++) {
+ sum += f[t];
+ }
+
+ for (var t = 0; t < F; t++) {
+ f[t] /= sum;
+ }
+
+ return f;
+ },
+
+ /**
+ * Calculates the convolution between two arrays
+ */
+ convolution: function(f,g) {
+ var F = f.length;
+ var G = g.length;
+
+ var c = new Array(F);
+
+ for (var m = 0; m < F; m++) {
+ var r = 0;
+ var end = (m + G < F) ? m + G : F;
+ for (var n = m; n < end; n++) {
+ var a = f[n - G];
+ var b = g[n - m];
+ r += a * b;
+ }
+ c[m] = r;
+ }
+
+ return c;
+ },
+
+ // ------ Array generators -------------------------------------------------
+ // Functions that generate arrays based on mathematical functions
+ // Normally these are used to produce operators by convolving them with the input array
+ // The returned arrays have the property of having
+
+ /**
+ * Generate the heavyside step function of given size
+ */
+ heavyside: function(size) {
+ var f = new Array(size);
+ var value = 1 / size;
+ for (var t = 0; t < size; t++) {
+ f[t] = value;
+ }
+ return f;
+ },
+
+ /**
+ * Generate the gaussian function so that at the given 'size' it has value 'threshold'
+ * and make sure its integral is one.
+ */
+ gaussian: function(size, threshold) {
+ with (Math) {
+ var radius = size / 2;
+ var variance = radius * radius / log(threshold);
+ var g = new Array(size);
+ for (var t = 0; t < size; t++) {
+ var l = t - radius;
+ g[t] = exp(-variance * l * l);
+ }
+ }
+
+ return this.normalize(g);
+ },
+
+ // ---- Utility Methods --------------------------------------------------
+
+ /**
+ * Return x with n significant figures
+ */
+ round: function(x,n) {
+ with (Math) {
+ if (abs(x) > 1) {
+ var l = floor(log(x)/log(10));
+ var d = round(exp((l-n+1)*log(10)));
+ var y = round(round(x / d) * d);
+ return y;
+ } else {
+ log("FIXME(SM): still to implement for 0 < abs(x) < 1");
+ return x;
+ }
+ }
+ },
+
+ /**
+ * Return the hyperbolic tangent of x
+ */
+ tanh: function(x) {
+ if (x > 5) {
+ return 1;
+ } else if (x < 5) {
+ return -1;
+ } else {
+ var expx2 = Math.exp(2 * x);
+ return (expx2 - 1) / (expx2 + 1);
+ }
+ },
+
+ /**
+ * Returns true if |a.x - b.x| < value && | a.y - b.y | < value
+ */
+ isClose: function(a,b,value) {
+ return (a && b && Math.abs(a.x - b.x) < value && Math.abs(a.y - b.y) < value);
+ }
+
+}/**
+ * Processing Data Source
+ *
+ * @fileOverview Processing Data Source and Operators
+ * @name Processor
+ */
+
+/* -----------------------------------------------------------------------------
+ * Operators
+ *
+ * These are functions that can be used directly as Timeplot.Processor operators
+ * ----------------------------------------------------------------------------- */
+
+Timeplot.Operator = {
+
+ /**
+ * This is the operator used when you want to draw the cumulative sum
+ * of a time series and not, for example, their daily values.
+ */
+ sum: function(data, params) {
+ return Timeplot.Math.integral(data.values);
+ },
+
+ /**
+ * This is the operator that is used to 'smooth' a given time series
+ * by taking the average value of a moving window centered around
+ * each value. The size of the moving window is influenced by the 'size'
+ * parameters in the params map.
+ */
+ average: function(data, params) {
+ var size = ("size" in params) ? params.size : 30;
+ var result = Timeplot.Math.movingAverage(data.values, size);
+ return result;
+ }
+}
+
+/*==================================================
+ * Processing Data Source
+ *==================================================*/
+
+/**
+ * A Processor is a special DataSource that can apply an Operator
+ * to the DataSource values and thus return a different one.
+ *
+ * @constructor
+ */
+Timeplot.Processor = function(dataSource, operator, params) {
+ this._dataSource = dataSource;
+ this._operator = operator;
+ this._params = params;
+
+ this._data = {
+ times: new Array(),
+ values: new Array()
+ };
+
+ this._range = {
+ earliestDate: null,
+ latestDate: null,
+ min: 0,
+ max: 0
+ };
+
+ var processor = this;
+ this._processingListener = {
+ onAddMany: function() { processor._process(); },
+ onClear: function() { processor._clear(); }
+ }
+ this.addListener(this._processingListener);
+};
+
+Timeplot.Processor.prototype = {
+
+ _clear: function() {
+ this.removeListener(this._processingListener);
+ this._dataSource._clear();
+ },
+
+ _process: function() {
+ // this method requires the dataSource._process() method to be
+ // called first as to setup the data and range used below
+ // this should be guaranteed by the order of the listener registration
+
+ var data = this._dataSource.getData();
+ var range = this._dataSource.getRange();
+
+ var newValues = this._operator(data, this._params);
+ var newValueRange = Timeplot.Math.range(newValues);
+
+ this._data = {
+ times: data.times,
+ values: newValues
+ };
+
+ this._range = {
+ earliestDate: range.earliestDate,
+ latestDate: range.latestDate,
+ min: newValueRange.min,
+ max: newValueRange.max
+ };
+ },
+
+ getRange: function() {
+ return this._range;
+ },
+
+ getData: function() {
+ return this._data;
+ },
+
+ getValue: Timeplot.DataSource.prototype.getValue,
+
+ addListener: function(listener) {
+ this._dataSource.addListener(listener);
+ },
+
+ removeListener: function(listener) {
+ this._dataSource.removeListener(listener);
+ }
+}
+// Copyright 2006 Google Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+
+// Known Issues:
+//
+// * Patterns are not implemented.
+// * Radial gradient are not implemented. The VML version of these look very
+// different from the canvas one.
+// * Clipping paths are not implemented.
+// * Coordsize. The width and height attribute have higher priority than the
+// width and height style values which isn't correct.
+// * Painting mode isn't implemented.
+// * Canvas width/height should is using content-box by default. IE in
+// Quirks mode will draw the canvas using border-box. Either change your
+// doctype to HTML5
+// (http://www.whatwg.org/specs/web-apps/current-work/#the-doctype)
+// or use Box Sizing Behavior from WebFX
+// (http://webfx.eae.net/dhtml/boxsizing/boxsizing.html)
+// * Optimize. There is always room for speed improvements.
+
+// only add this code if we do not already have a canvas implementation
+if (!window.CanvasRenderingContext2D) {
+
+(function () {
+
+ // alias some functions to make (compiled) code shorter
+ var m = Math;
+ var mr = m.round;
+ var ms = m.sin;
+ var mc = m.cos;
+
+ // this is used for sub pixel precision
+ var Z = 10;
+ var Z2 = Z / 2;
+
+ var G_vmlCanvasManager_ = {
+ init: function (opt_doc) {
+ var doc = opt_doc || document;
+ if (/MSIE/.test(navigator.userAgent) && !window.opera) {
+ var self = this;
+ doc.attachEvent("onreadystatechange", function () {
+ self.init_(doc);
+ });
+ }
+ },
+
+ init_: function (doc) {
+ if (doc.readyState == "complete") {
+ // create xmlns
+ if (!doc.namespaces["g_vml_"]) {
+ doc.namespaces.add("g_vml_", "urn:schemas-microsoft-com:vml");
+ }
+
+ // setup default css
+ var ss = doc.createStyleSheet();
+ ss.cssText = "canvas{display:inline-block;overflow:hidden;" +
+ // default size is 300x150 in Gecko and Opera
+ "text-align:left;width:300px;height:150px}" +
+ "g_vml_\\:*{behavior:url(#default#VML)}";
+
+ // find all canvas elements
+ var els = doc.getElementsByTagName("canvas");
+ for (var i = 0; i < els.length; i++) {
+ if (!els[i].getContext) {
+ this.initElement(els[i]);
+ }
+ }
+ }
+ },
+
+ fixElement_: function (el) {
+ // in IE before version 5.5 we would need to add HTML: to the tag name
+ // but we do not care about IE before version 6
+ var outerHTML = el.outerHTML;
+
+ var newEl = el.ownerDocument.createElement(outerHTML);
+ // if the tag is still open IE has created the children as siblings and
+ // it has also created a tag with the name "/FOO"
+ if (outerHTML.slice(-2) != "/>") {
+ var tagName = "/" + el.tagName;
+ var ns;
+ // remove content
+ while ((ns = el.nextSibling) && ns.tagName != tagName) {
+ ns.removeNode();
+ }
+ // remove the incorrect closing tag
+ if (ns) {
+ ns.removeNode();
+ }
+ }
+ el.parentNode.replaceChild(newEl, el);
+ return newEl;
+ },
+
+ /**
+ * Public initializes a canvas element so that it can be used as canvas
+ * element from now on. This is called automatically before the page is
+ * loaded but if you are creating elements using createElement you need to
+ * make sure this is called on the element.
+ * @param {HTMLElement} el The canvas element to initialize.
+ * @return {HTMLElement} the element that was created.
+ */
+ initElement: function (el) {
+ el = this.fixElement_(el);
+ el.getContext = function () {
+ if (this.context_) {
+ return this.context_;
+ }
+ return this.context_ = new CanvasRenderingContext2D_(this);
+ };
+
+ // do not use inline function because that will leak memory
+ el.attachEvent('onpropertychange', onPropertyChange);
+ el.attachEvent('onresize', onResize);
+
+ var attrs = el.attributes;
+ if (attrs.width && attrs.width.specified) {
+ // TODO: use runtimeStyle and coordsize
+ // el.getContext().setWidth_(attrs.width.nodeValue);
+ el.style.width = attrs.width.nodeValue + "px";
+ } else {
+ el.width = el.clientWidth;
+ }
+ if (attrs.height && attrs.height.specified) {
+ // TODO: use runtimeStyle and coordsize
+ // el.getContext().setHeight_(attrs.height.nodeValue);
+ el.style.height = attrs.height.nodeValue + "px";
+ } else {
+ el.height = el.clientHeight;
+ }
+ //el.getContext().setCoordsize_()
+ return el;
+ }
+ };
+
+ function onPropertyChange(e) {
+ var el = e.srcElement;
+
+ switch (e.propertyName) {
+ case 'width':
+ el.style.width = el.attributes.width.nodeValue + "px";
+ el.getContext().clearRect();
+ break;
+ case 'height':
+ el.style.height = el.attributes.height.nodeValue + "px";
+ el.getContext().clearRect();
+ break;
+ }
+ }
+
+ function onResize(e) {
+ var el = e.srcElement;
+ if (el.firstChild) {
+ el.firstChild.style.width = el.clientWidth + 'px';
+ el.firstChild.style.height = el.clientHeight + 'px';
+ }
+ }
+
+ G_vmlCanvasManager_.init();
+
+ // precompute "00" to "FF"
+ var dec2hex = [];
+ for (var i = 0; i < 16; i++) {
+ for (var j = 0; j < 16; j++) {
+ dec2hex[i * 16 + j] = i.toString(16) + j.toString(16);
+ }
+ }
+
+ function createMatrixIdentity() {
+ return [
+ [1, 0, 0],
+ [0, 1, 0],
+ [0, 0, 1]
+ ];
+ }
+
+ function matrixMultiply(m1, m2) {
+ var result = createMatrixIdentity();
+
+ for (var x = 0; x < 3; x++) {
+ for (var y = 0; y < 3; y++) {
+ var sum = 0;
+
+ for (var z = 0; z < 3; z++) {
+ sum += m1[x][z] * m2[z][y];
+ }
+
+ result[x][y] = sum;
+ }
+ }
+ return result;
+ }
+
+ function copyState(o1, o2) {
+ o2.fillStyle = o1.fillStyle;
+ o2.lineCap = o1.lineCap;
+ o2.lineJoin = o1.lineJoin;
+ o2.lineWidth = o1.lineWidth;
+ o2.miterLimit = o1.miterLimit;
+ o2.shadowBlur = o1.shadowBlur;
+ o2.shadowColor = o1.shadowColor;
+ o2.shadowOffsetX = o1.shadowOffsetX;
+ o2.shadowOffsetY = o1.shadowOffsetY;
+ o2.strokeStyle = o1.strokeStyle;
+ o2.arcScaleX_ = o1.arcScaleX_;
+ o2.arcScaleY_ = o1.arcScaleY_;
+ }
+
+ function processStyle(styleString) {
+ var str, alpha = 1;
+
+ styleString = String(styleString);
+ if (styleString.substring(0, 3) == "rgb") {
+ var start = styleString.indexOf("(", 3);
+ var end = styleString.indexOf(")", start + 1);
+ var guts = styleString.substring(start + 1, end).split(",");
+
+ str = "#";
+ for (var i = 0; i < 3; i++) {
+ str += dec2hex[Number(guts[i])];
+ }
+
+ if ((guts.length == 4) && (styleString.substr(3, 1) == "a")) {
+ alpha = guts[3];
+ }
+ } else {
+ str = styleString;
+ }
+
+ return [str, alpha];
+ }
+
+ function processLineCap(lineCap) {
+ switch (lineCap) {
+ case "butt":
+ return "flat";
+ case "round":
+ return "round";
+ case "square":
+ default:
+ return "square";
+ }
+ }
+
+ /**
+ * This class implements CanvasRenderingContext2D interface as described by
+ * the WHATWG.
+ * @param {HTMLElement} surfaceElement The element that the 2D context should
+ * be associated with
+ */
+ function CanvasRenderingContext2D_(surfaceElement) {
+ this.m_ = createMatrixIdentity();
+
+ this.mStack_ = [];
+ this.aStack_ = [];
+ this.currentPath_ = [];
+
+ // Canvas context properties
+ this.strokeStyle = "#000";
+ this.fillStyle = "#000";
+
+ this.lineWidth = 1;
+ this.lineJoin = "miter";
+ this.lineCap = "butt";
+ this.miterLimit = Z * 1;
+ this.globalAlpha = 1;
+ this.canvas = surfaceElement;
+
+ var el = surfaceElement.ownerDocument.createElement('div');
+ el.style.width = surfaceElement.clientWidth + 'px';
+ el.style.height = surfaceElement.clientHeight + 'px';
+ el.style.overflow = 'hidden';
+ el.style.position = 'absolute';
+ surfaceElement.appendChild(el);
+
+ this.element_ = el;
+ this.arcScaleX_ = 1;
+ this.arcScaleY_ = 1;
+ };
+
+ var contextPrototype = CanvasRenderingContext2D_.prototype;
+ contextPrototype.clearRect = function() {
+ this.element_.innerHTML = "";
+ this.currentPath_ = [];
+ };
+
+ contextPrototype.beginPath = function() {
+ // TODO: Branch current matrix so that save/restore has no effect
+ // as per safari docs.
+
+ this.currentPath_ = [];
+ };
+
+ contextPrototype.moveTo = function(aX, aY) {
+ this.currentPath_.push({type: "moveTo", x: aX, y: aY});
+ this.currentX_ = aX;
+ this.currentY_ = aY;
+ };
+
+ contextPrototype.lineTo = function(aX, aY) {
+ this.currentPath_.push({type: "lineTo", x: aX, y: aY});
+ this.currentX_ = aX;
+ this.currentY_ = aY;
+ };
+
+ contextPrototype.bezierCurveTo = function(aCP1x, aCP1y,
+ aCP2x, aCP2y,
+ aX, aY) {
+ this.currentPath_.push({type: "bezierCurveTo",
+ cp1x: aCP1x,
+ cp1y: aCP1y,
+ cp2x: aCP2x,
+ cp2y: aCP2y,
+ x: aX,
+ y: aY});
+ this.currentX_ = aX;
+ this.currentY_ = aY;
+ };
+
+ contextPrototype.quadraticCurveTo = function(aCPx, aCPy, aX, aY) {
+ // the following is lifted almost directly from
+ // http://developer.mozilla.org/en/docs/Canvas_tutorial:Drawing_shapes
+ var cp1x = this.currentX_ + 2.0 / 3.0 * (aCPx - this.currentX_);
+ var cp1y = this.currentY_ + 2.0 / 3.0 * (aCPy - this.currentY_);
+ var cp2x = cp1x + (aX - this.currentX_) / 3.0;
+ var cp2y = cp1y + (aY - this.currentY_) / 3.0;
+ this.bezierCurveTo(cp1x, cp1y, cp2x, cp2y, aX, aY);
+ };
+
+ contextPrototype.arc = function(aX, aY, aRadius,
+ aStartAngle, aEndAngle, aClockwise) {
+ aRadius *= Z;
+ var arcType = aClockwise ? "at" : "wa";
+
+ var xStart = aX + (mc(aStartAngle) * aRadius) - Z2;
+ var yStart = aY + (ms(aStartAngle) * aRadius) - Z2;
+
+ var xEnd = aX + (mc(aEndAngle) * aRadius) - Z2;
+ var yEnd = aY + (ms(aEndAngle) * aRadius) - Z2;
+
+ // IE won't render arches drawn counter clockwise if xStart == xEnd.
+ if (xStart == xEnd && !aClockwise) {
+ xStart += 0.125; // Offset xStart by 1/80 of a pixel. Use something
+ // that can be represented in binary
+ }
+
+ this.currentPath_.push({type: arcType,
+ x: aX,
+ y: aY,
+ radius: aRadius,
+ xStart: xStart,
+ yStart: yStart,
+ xEnd: xEnd,
+ yEnd: yEnd});
+
+ };
+
+ contextPrototype.rect = function(aX, aY, aWidth, aHeight) {
+ this.moveTo(aX, aY);
+ this.lineTo(aX + aWidth, aY);
+ this.lineTo(aX + aWidth, aY + aHeight);
+ this.lineTo(aX, aY + aHeight);
+ this.closePath();
+ };
+
+ contextPrototype.strokeRect = function(aX, aY, aWidth, aHeight) {
+ // Will destroy any existing path (same as FF behaviour)
+ this.beginPath();
+ this.moveTo(aX, aY);
+ this.lineTo(aX + aWidth, aY);
+ this.lineTo(aX + aWidth, aY + aHeight);
+ this.lineTo(aX, aY + aHeight);
+ this.closePath();
+ this.stroke();
+ };
+
+ contextPrototype.fillRect = function(aX, aY, aWidth, aHeight) {
+ // Will destroy any existing path (same as FF behaviour)
+ this.beginPath();
+ this.moveTo(aX, aY);
+ this.lineTo(aX + aWidth, aY);
+ this.lineTo(aX + aWidth, aY + aHeight);
+ this.lineTo(aX, aY + aHeight);
+ this.closePath();
+ this.fill();
+ };
+
+ contextPrototype.createLinearGradient = function(aX0, aY0, aX1, aY1) {
+ var gradient = new CanvasGradient_("gradient");
+ return gradient;
+ };
+
+ contextPrototype.createRadialGradient = function(aX0, aY0,
+ aR0, aX1,
+ aY1, aR1) {
+ var gradient = new CanvasGradient_("gradientradial");
+ gradient.radius1_ = aR0;
+ gradient.radius2_ = aR1;
+ gradient.focus_.x = aX0;
+ gradient.focus_.y = aY0;
+ return gradient;
+ };
+
+ contextPrototype.drawImage = function (image, var_args) {
+ var dx, dy, dw, dh, sx, sy, sw, sh;
+
+ // to find the original width we overide the width and height
+ var oldRuntimeWidth = image.runtimeStyle.width;
+ var oldRuntimeHeight = image.runtimeStyle.height;
+ image.runtimeStyle.width = 'auto';
+ image.runtimeStyle.height = 'auto';
+
+ // get the original size
+ var w = image.width;
+ var h = image.height;
+
+ // and remove overides
+ image.runtimeStyle.width = oldRuntimeWidth;
+ image.runtimeStyle.height = oldRuntimeHeight;
+
+ if (arguments.length == 3) {
+ dx = arguments[1];
+ dy = arguments[2];
+ sx = sy = 0;
+ sw = dw = w;
+ sh = dh = h;
+ } else if (arguments.length == 5) {
+ dx = arguments[1];
+ dy = arguments[2];
+ dw = arguments[3];
+ dh = arguments[4];
+ sx = sy = 0;
+ sw = w;
+ sh = h;
+ } else if (arguments.length == 9) {
+ sx = arguments[1];
+ sy = arguments[2];
+ sw = arguments[3];
+ sh = arguments[4];
+ dx = arguments[5];
+ dy = arguments[6];
+ dw = arguments[7];
+ dh = arguments[8];
+ } else {
+ throw "Invalid number of arguments";
+ }
+
+ var d = this.getCoords_(dx, dy);
+
+ var w2 = sw / 2;
+ var h2 = sh / 2;
+
+ var vmlStr = [];
+
+ var W = 10;
+ var H = 10;
+
+ // For some reason that I've now forgotten, using divs didn't work
+ vmlStr.push(' <g_vml_:group',
+ ' coordsize="', Z * W, ',', Z * H, '"',
+ ' coordorigin="0,0"' ,
+ ' style="width:', W, ';height:', H, ';position:absolute;');
+
+ // If filters are necessary (rotation exists), create them
+ // filters are bog-slow, so only create them if abbsolutely necessary
+ // The following check doesn't account for skews (which don't exist
+ // in the canvas spec (yet) anyway.
+
+ if (this.m_[0][0] != 1 || this.m_[0][1]) {
+ var filter = [];
+
+ // Note the 12/21 reversal
+ filter.push("M11='", this.m_[0][0], "',",
+ "M12='", this.m_[1][0], "',",
+ "M21='", this.m_[0][1], "',",
+ "M22='", this.m_[1][1], "',",
+ "Dx='", mr(d.x / Z), "',",
+ "Dy='", mr(d.y / Z), "'");
+
+ // Bounding box calculation (need to minimize displayed area so that
+ // filters don't waste time on unused pixels.
+ var max = d;
+ var c2 = this.getCoords_(dx + dw, dy);
+ var c3 = this.getCoords_(dx, dy + dh);
+ var c4 = this.getCoords_(dx + dw, dy + dh);
+
+ max.x = Math.max(max.x, c2.x, c3.x, c4.x);
+ max.y = Math.max(max.y, c2.y, c3.y, c4.y);
+
+ vmlStr.push("padding:0 ", mr(max.x / Z), "px ", mr(max.y / Z),
+ "px 0;filter:progid:DXImageTransform.Microsoft.Matrix(",
+ filter.join(""), ", sizingmethod='clip');")
+ } else {
+ vmlStr.push("top:", mr(d.y / Z), "px;left:", mr(d.x / Z), "px;")
+ }
+
+ vmlStr.push(' ">' ,
+ '<g_vml_:image src="', image.src, '"',
+ ' style="width:', Z * dw, ';',
+ ' height:', Z * dh, ';"',
+ ' cropleft="', sx / w, '"',
+ ' croptop="', sy / h, '"',
+ ' cropright="', (w - sx - sw) / w, '"',
+ ' cropbottom="', (h - sy - sh) / h, '"',
+ ' />',
+ '</g_vml_:group>');
+
+ this.element_.insertAdjacentHTML("BeforeEnd",
+ vmlStr.join(""));
+ };
+
+ contextPrototype.stroke = function(aFill) {
+ var lineStr = [];
+ var lineOpen = false;
+ var a = processStyle(aFill ? this.fillStyle : this.strokeStyle);
+ var color = a[0];
+ var opacity = a[1] * this.globalAlpha;
+
+ var W = 10;
+ var H = 10;
+
+ lineStr.push('<g_vml_:shape',
+ ' fillcolor="', color, '"',
+ ' filled="', Boolean(aFill), '"',
+ ' style="position:absolute;width:', W, ';height:', H, ';"',
+ ' coordorigin="0 0" coordsize="', Z * W, ' ', Z * H, '"',
+ ' stroked="', !aFill, '"',
+ ' strokeweight="', this.lineWidth, '"',
+ ' strokecolor="', color, '"',
+ ' path="');
+
+ var newSeq = false;
+ var min = {x: null, y: null};
+ var max = {x: null, y: null};
+
+ for (var i = 0; i < this.currentPath_.length; i++) {
+ var p = this.currentPath_[i];
+
+ if (p.type == "moveTo") {
+ lineStr.push(" m ");
+ var c = this.getCoords_(p.x, p.y);
+ lineStr.push(mr(c.x), ",", mr(c.y));
+ } else if (p.type == "lineTo") {
+ lineStr.push(" l ");
+ var c = this.getCoords_(p.x, p.y);
+ lineStr.push(mr(c.x), ",", mr(c.y));
+ } else if (p.type == "close") {
+ lineStr.push(" x ");
+ } else if (p.type == "bezierCurveTo") {
+ lineStr.push(" c ");
+ var c = this.getCoords_(p.x, p.y);
+ var c1 = this.getCoords_(p.cp1x, p.cp1y);
+ var c2 = this.getCoords_(p.cp2x, p.cp2y);
+ lineStr.push(mr(c1.x), ",", mr(c1.y), ",",
+ mr(c2.x), ",", mr(c2.y), ",",
+ mr(c.x), ",", mr(c.y));
+ } else if (p.type == "at" || p.type == "wa") {
+ lineStr.push(" ", p.type, " ");
+ var c = this.getCoords_(p.x, p.y);
+ var cStart = this.getCoords_(p.xStart, p.yStart);
+ var cEnd = this.getCoords_(p.xEnd, p.yEnd);
+
+ lineStr.push(mr(c.x - this.arcScaleX_ * p.radius), ",",
+ mr(c.y - this.arcScaleY_ * p.radius), " ",
+ mr(c.x + this.arcScaleX_ * p.radius), ",",
+ mr(c.y + this.arcScaleY_ * p.radius), " ",
+ mr(cStart.x), ",", mr(cStart.y), " ",
+ mr(cEnd.x), ",", mr(cEnd.y));
+ }
+
+
+ // TODO: Following is broken for curves due to
+ // move to proper paths.
+
+ // Figure out dimensions so we can do gradient fills
+ // properly
+ if(c) {
+ if (min.x == null || c.x < min.x) {
+ min.x = c.x;
+ }
+ if (max.x == null || c.x > max.x) {
+ max.x = c.x;
+ }
+ if (min.y == null || c.y < min.y) {
+ min.y = c.y;
+ }
+ if (max.y == null || c.y > max.y) {
+ max.y = c.y;
+ }
+ }
+ }
+ lineStr.push(' ">');
+
+ if (typeof this.fillStyle == "object") {
+ var focus = {x: "50%", y: "50%"};
+ var width = (max.x - min.x);
+ var height = (max.y - min.y);
+ var dimension = (width > height) ? width : height;
+
+ focus.x = mr((this.fillStyle.focus_.x / width) * 100 + 50) + "%";
+ focus.y = mr((this.fillStyle.focus_.y / height) * 100 + 50) + "%";
+
+ var colors = [];
+
+ // inside radius (%)
+ if (this.fillStyle.type_ == "gradientradial") {
+ var inside = (this.fillStyle.radius1_ / dimension * 100);
+
+ // percentage that outside radius exceeds inside radius
+ var expansion = (this.fillStyle.radius2_ / dimension * 100) - inside;
+ } else {
+ var inside = 0;
+ var expansion = 100;
+ }
+
+ var insidecolor = {offset: null, color: null};
+ var outsidecolor = {offset: null, color: null};
+
+ // We need to sort 'colors' by percentage, from 0 > 100 otherwise ie
+ // won't interpret it correctly
+ this.fillStyle.colors_.sort(function (cs1, cs2) {
+ return cs1.offset - cs2.offset;
+ });
+
+ for (var i = 0; i < this.fillStyle.colors_.length; i++) {
+ var fs = this.fillStyle.colors_[i];
+
+ colors.push( (fs.offset * expansion) + inside, "% ", fs.color, ",");
+
+ if (fs.offset > insidecolor.offset || insidecolor.offset == null) {
+ insidecolor.offset = fs.offset;
+ insidecolor.color = fs.color;
+ }
+
+ if (fs.offset < outsidecolor.offset || outsidecolor.offset == null) {
+ outsidecolor.offset = fs.offset;
+ outsidecolor.color = fs.color;
+ }
+ }
+ colors.pop();
+
+ lineStr.push('<g_vml_:fill',
+ ' color="', outsidecolor.color, '"',
+ ' color2="', insidecolor.color, '"',
+ ' type="', this.fillStyle.type_, '"',
+ ' focusposition="', focus.x, ', ', focus.y, '"',
+ ' colors="', colors.join(""), '"',
+ ' opacity="', opacity, '" />');
+ } else if (aFill) {
+ lineStr.push('<g_vml_:fill color="', color, '" opacity="', opacity, '" />');
+ } else {
+ lineStr.push(
+ '<g_vml_:stroke',
+ ' opacity="', opacity,'"',
+ ' joinstyle="', this.lineJoin, '"',
+ ' miterlimit="', this.miterLimit, '"',
+ ' endcap="', processLineCap(this.lineCap) ,'"',
+ ' weight="', this.lineWidth, 'px"',
+ ' color="', color,'" />'
+ );
+ }
+
+ lineStr.push("</g_vml_:shape>");
+
+ this.element_.insertAdjacentHTML("beforeEnd", lineStr.join(""));
+
+ this.currentPath_ = [];
+ };
+
+ contextPrototype.fill = function() {
+ this.stroke(true);
+ }
+
+ contextPrototype.closePath = function() {
+ this.currentPath_.push({type: "close"});
+ };
+
+ /**
+ * @private
+ */
+ contextPrototype.getCoords_ = function(aX, aY) {
+ return {
+ x: Z * (aX * this.m_[0][0] + aY * this.m_[1][0] + this.m_[2][0]) - Z2,
+ y: Z * (aX * this.m_[0][1] + aY * this.m_[1][1] + this.m_[2][1]) - Z2
+ }
+ };
+
+ contextPrototype.save = function() {
+ var o = {};
+ copyState(this, o);
+ this.aStack_.push(o);
+ this.mStack_.push(this.m_);
+ this.m_ = matrixMultiply(createMatrixIdentity(), this.m_);
+ };
+
+ contextPrototype.restore = function() {
+ copyState(this.aStack_.pop(), this);
+ this.m_ = this.mStack_.pop();
+ };
+
+ contextPrototype.translate = function(aX, aY) {
+ var m1 = [
+ [1, 0, 0],
+ [0, 1, 0],
+ [aX, aY, 1]
+ ];
+
+ this.m_ = matrixMultiply(m1, this.m_);
+ };
+
+ contextPrototype.rotate = function(aRot) {
+ var c = mc(aRot);
+ var s = ms(aRot);
+
+ var m1 = [
+ [c, s, 0],
+ [-s, c, 0],
+ [0, 0, 1]
+ ];
+
+ this.m_ = matrixMultiply(m1, this.m_);
+ };
+
+ contextPrototype.scale = function(aX, aY) {
+ this.arcScaleX_ *= aX;
+ this.arcScaleY_ *= aY;
+ var m1 = [
+ [aX, 0, 0],
+ [0, aY, 0],
+ [0, 0, 1]
+ ];
+
+ this.m_ = matrixMultiply(m1, this.m_);
+ };
+
+ /******** STUBS ********/
+ contextPrototype.clip = function() {
+ // TODO: Implement
+ };
+
+ contextPrototype.arcTo = function() {
+ // TODO: Implement
+ };
+
+ contextPrototype.createPattern = function() {
+ return new CanvasPattern_;
+ };
+
+ // Gradient / Pattern Stubs
+ function CanvasGradient_(aType) {
+ this.type_ = aType;
+ this.radius1_ = 0;
+ this.radius2_ = 0;
+ this.colors_ = [];
+ this.focus_ = {x: 0, y: 0};
+ }
+
+ CanvasGradient_.prototype.addColorStop = function(aOffset, aColor) {
+ aColor = processStyle(aColor);
+ this.colors_.push({offset: 1-aOffset, color: aColor});
+ };
+
+ function CanvasPattern_() {}
+
+ // set up externs
+ G_vmlCanvasManager = G_vmlCanvasManager_;
+ CanvasRenderingContext2D = CanvasRenderingContext2D_;
+ CanvasGradient = CanvasGradient_;
+ CanvasPattern = CanvasPattern_;
+
+})();
+
+} // if
diff --git a/site/app/webroot/js/simile/bundlemaker/ajax.txt b/site/app/webroot/js/simile/bundlemaker/ajax.txt
new file mode 100644
index 0000000..39447fb
--- /dev/null
+++ b/site/app/webroot/js/simile/bundlemaker/ajax.txt
@@ -0,0 +1,14 @@
+ajax-api-amo-bundle.js
+scripts/platform.js
+scripts/debug.js
+scripts/xmlhttp.js
+scripts/json.js
+scripts/dom.js
+scripts/graphics.js
+scripts/date-time.js
+scripts/string.js
+scripts/html.js
+scripts/data-structure.js
+scripts/units.js
+scripts/ajax.js
+scripts/window-manager.js
diff --git a/site/app/webroot/js/simile/bundlemaker/bundle-template.js b/site/app/webroot/js/simile/bundlemaker/bundle-template.js
new file mode 100644
index 0000000..f9a793f
--- /dev/null
+++ b/site/app/webroot/js/simile/bundlemaker/bundle-template.js
@@ -0,0 +1,263 @@
+
+//////////////////////////// AJAX LOADER /////////////////////////////
+
+if (typeof SimileAjax == "undefined") {
+ var SimileAjax = {
+ loaded: false,
+ loadingScriptsCount: 0,
+ error: null,
+ params: { bundle:"true" }
+ };
+
+ SimileAjax.Platform = new Object();
+ /*
+ HACK: We need these 2 things here because we cannot simply append
+ a <script> element containing code that accesses SimileAjax.Platform
+ to initialize it because IE executes that <script> code first
+ before it loads ajax.js and platform.js.
+ */
+
+ var getHead = function(doc) {
+ return doc.getElementsByTagName("head")[0];
+ };
+
+ SimileAjax.findScript = function(doc, substring) {
+ var heads = doc.documentElement.getElementsByTagName("head");
+ for (var h = 0; h < heads.length; h++) {
+ var node = heads[h].firstChild;
+ while (node != null) {
+ if (node.nodeType == 1 && node.tagName.toLowerCase() == "script") {
+ var url = node.src;
+ var i = url.indexOf(substring);
+ if (i >= 0) {
+ return url;
+ }
+ }
+ node = node.nextSibling;
+ }
+ }
+ return null;
+ };
+ SimileAjax.includeJavascriptFile = function(doc, url, onerror, charset) {
+ onerror = onerror || "";
+ if (doc.body == null) {
+ try {
+ var q = "'" + onerror.replace( /'/g, '&apos' ) + "'"; // "
+ doc.write("<script src='" + url + "' onerror="+ q +
+ (charset ? " charset='"+ charset +"'" : "") +
+ " type='text/javascript'>"+ onerror + "</script>");
+ return false;
+ } catch (e) {
+ // fall through
+ }
+ }
+
+ var script = doc.createElement("script");
+ if (onerror) {
+ try { script.innerHTML = onerror; } catch(e) {}
+ script.setAttribute("onerror", onerror);
+ }
+ if (charset) {
+ script.setAttribute("charset", charset);
+ }
+ script.type = "text/javascript";
+ script.language = "JavaScript";
+ script.src = url;
+ return getHead(doc).appendChild(script);
+ };
+ SimileAjax.includeJavascriptFiles = function(doc, urlPrefix, filenames) {
+ for (var i = 0; i < filenames.length; i++) {
+ SimileAjax.includeJavascriptFile(doc, urlPrefix + filenames[i]);
+ }
+ SimileAjax.loadingScriptsCount += filenames.length;
+ SimileAjax.includeJavascriptFile(doc, SimileAjax.urlPrefix + "scripts/signal.js?" + filenames.length);
+ };
+ SimileAjax.includeCssFile = function(doc, url) {
+ if (doc.body == null) {
+ try {
+ doc.write("<link rel='stylesheet' href='" + url + "' type='text/css'/>");
+ return;
+ } catch (e) {
+ // fall through
+ }
+ }
+
+ var link = doc.createElement("link");
+ link.setAttribute("rel", "stylesheet");
+ link.setAttribute("type", "text/css");
+ link.setAttribute("href", url);
+ getHead(doc).appendChild(link);
+ };
+ SimileAjax.includeCssFiles = function(doc, urlPrefix, filenames) {
+ for (var i = 0; i < filenames.length; i++) {
+ SimileAjax.includeCssFile(doc, urlPrefix + filenames[i]);
+ }
+ };
+
+ /**
+ * Append into urls each string in suffixes after prefixing it with urlPrefix.
+ * @param {Array} urls
+ * @param {String} urlPrefix
+ * @param {Array} suffixes
+ */
+ SimileAjax.prefixURLs = function(urls, urlPrefix, suffixes) {
+ for (var i = 0; i < suffixes.length; i++) {
+ urls.push(urlPrefix + suffixes[i]);
+ }
+ };
+
+ /**
+ * Parse out the query parameters from a URL
+ * @param {String} url the url to parse, or location.href if undefined
+ * @param {Object} to optional object to extend with the parameters
+ * @param {Object} types optional object mapping keys to value types
+ * (String, Number, Boolean or Array, String by default)
+ * @return a key/value Object whose keys are the query parameter names
+ * @type Object
+ */
+ SimileAjax.parseURLParameters = function(url, to, types) {
+ to = to || {};
+ types = types || {};
+
+ if (typeof url == "undefined") {
+ url = location.href;
+ }
+ var q = url.indexOf("?");
+ if (q < 0) {
+ return to;
+ }
+ url = (url+"#").slice(q+1, url.indexOf("#")); // toss the URL fragment
+
+ var params = url.split("&"), param, parsed = {};
+ var decode = window.decodeURIComponent || unescape;
+ for (var i = 0; param = params[i]; i++) {
+ var eq = param.indexOf("=");
+ var name = decode(param.slice(0,eq));
+ var old = parsed[name];
+ if (typeof old == "undefined") {
+ old = [];
+ } else if (!(old instanceof Array)) {
+ old = [old];
+ }
+ parsed[name] = old.concat(decode(param.slice(eq+1)));
+ }
+ for (var i in parsed) {
+ if (!parsed.hasOwnProperty(i)) continue;
+ var type = types[i] || String;
+ var data = parsed[i];
+ if (!(data instanceof Array)) {
+ data = [data];
+ }
+ if (type === Boolean && data[0] == "false") {
+ to[i] = false; // because Boolean("false") === true
+ } else {
+ to[i] = type.apply(this, data);
+ }
+ }
+ return to;
+ };
+
+ SimileAjax.loaded = true;
+}
+
+////////////////////////////// TIMELINE LOADER /////////////////////////////////
+
+(function() {
+ var useLocalResources = false;
+ if (document.location.search.length > 0) {
+ var params = document.location.search.substr(1).split("&");
+ for (var i = 0; i < params.length; i++) {
+ if (params[i] == "timeline-use-local-resources") {
+ useLocalResources = true;
+ }
+ }
+ };
+
+ var loadMe = function() {
+ if ("Timeline" in window) {
+ return;
+ }
+
+ window.Timeline = new Object();
+ window.Timeline.DateTime = window.SimileAjax.DateTime; // for backward compatibility
+
+ };
+
+ loadMe();
+})();
+
+
+////////////////////////////// TIMEPLOT LOADER ////////////////////////////////
+(function() {
+
+ var local = true;
+
+ // Load Timeplot if it's not already loaded (after SimileAjax and Timeline)
+ var loadTimeplot = function() {
+
+ if (typeof window.Timeplot != "undefined") {
+ return;
+ }
+
+ window.Timeplot = {
+ loaded: false,
+ params: { bundle: true, autoCreate: true },
+ namespace: "http://simile.mit.edu/2007/06/timeplot#",
+ importers: {}
+ };
+
+ var locales = [ "en" ];
+
+ var defaultClientLocales = ("language" in navigator ? navigator.language : navigator.browserLanguage).split(";");
+ for (var l = 0; l < defaultClientLocales.length; l++) {
+ var locale = defaultClientLocales[l];
+ if (locale != "en") {
+ var segments = locale.split("-");
+ if (segments.length > 1 && segments[0] != "en") {
+ locales.push(segments[0]);
+ }
+ locales.push(locale);
+ }
+ }
+
+ var paramTypes = { bundle:Boolean, autoCreate:Boolean };
+
+ if (Timeplot.params.locale) { // ISO-639 language codes,
+ // optional ISO-3166 country codes (2 characters)
+ if (Timeplot.params.locale != "en") {
+ var segments = Timeplot.params.locale.split("-");
+ if (segments.length > 1 && segments[0] != "en") {
+ locales.push(segments[0]);
+ }
+ locales.push(Timeplot.params.locale);
+ }
+ }
+
+ var canvas = document.createElement("canvas");
+
+ window.SimileAjax_onLoad = function() {
+ //if (local && window.console.open) window.console.open();
+ if (Timeplot.params.callback) {
+ eval(Timeplot.params.callback + "()");
+ }
+ }
+
+ Timeplot.loaded = true;
+ };
+
+ // Load Timeline if it's not already loaded (after SimileAjax and before Timeplot)
+ var loadTimeline = function() {
+ if (typeof Timeline != "undefined") {
+ loadTimeplot();
+ } else {
+ window.SimileAjax_onLoad = loadTimeplot;
+ }
+ };
+
+ // Load SimileAjax if it's not already loaded
+ if (typeof SimileAjax == "undefined") {
+ window.SimileAjax_onLoad = loadTimeline;
+ } else {
+ loadTimeline();
+ }
+})();
diff --git a/site/app/webroot/js/simile/bundlemaker/class.JavaScriptPacker.php b/site/app/webroot/js/simile/bundlemaker/class.JavaScriptPacker.php
new file mode 100755
index 0000000..fbbd68c
--- /dev/null
+++ b/site/app/webroot/js/simile/bundlemaker/class.JavaScriptPacker.php
@@ -0,0 +1,736 @@
+<?php
+/* 7 December 2006. version 1.0
+ *
+ * This is the php version of the Dean Edwards JavaScript 's Packer,
+ * Based on :
+ *
+ * ParseMaster, version 1.0.2 (2005-08-19) Copyright 2005, Dean Edwards
+ * a multi-pattern parser.
+ * KNOWN BUG: erroneous behavior when using escapeChar with a replacement
+ * value that is a function
+ *
+ * packer, version 2.0.2 (2005-08-19) Copyright 2004-2005, Dean Edwards
+ *
+ * License: http://creativecommons.org/licenses/LGPL/2.1/
+ *
+ * Ported to PHP by Nicolas Martin.
+ *
+ * ----------------------------------------------------------------------
+ *
+ * examples of usage :
+ * $myPacker = new JavaScriptPacker($script, 62, true, false);
+ * $packed = $myPacker->pack();
+ *
+ * or
+ *
+ * $myPacker = new JavaScriptPacker($script, 'Normal', true, false);
+ * $packed = $myPacker->pack();
+ *
+ * or (default values)
+ *
+ * $myPacker = new JavaScriptPacker($script);
+ * $packed = $myPacker->pack();
+ *
+ *
+ * params of the constructor :
+ * $script: the JavaScript to pack, string.
+ * $encoding: level of encoding, int or string :
+ * 0,10,62,95 or 'None', 'Numeric', 'Normal', 'High ASCII'.
+ * default: 62.
+ * $fastDecode: include the fast decoder in the packed result, boolean.
+ * default : true.
+ * $specialChars: if you are flagged your private and local variables
+ * in the script, boolean.
+ * default: false.
+ *
+ * The pack() method return the compressed JavasScript, as a string.
+ *
+ * see http://dean.edwards.name/packer/usage/ for more information.
+ *
+ * Notes :
+ * # need PHP 5 . Tested with PHP 5.1.2
+ *
+ * # The packed result may be different than with the Dean Edwards
+ * version, but with the same length. The reason is that the PHP
+ * function usort to sort array don't necessarily preserve the
+ * original order of two equal member. The Javascript sort function
+ * in fact preserve this order (but that's not require by the
+ * ECMAScript standard). So the encoded keywords order can be
+ * different in the two results.
+ *
+ * # Be careful with the 'High ASCII' Level encoding if you use
+ * UTF-8 in your files...
+ */
+
+
+class JavaScriptPacker {
+ // constants
+ const IGNORE = '$1';
+
+ // validate parameters
+ private $_script = '';
+ private $_encoding = 62;
+ private $_fastDecode = true;
+ private $_specialChars = false;
+
+ private $LITERAL_ENCODING = array(
+ 'None' => 0,
+ 'Numeric' => 10,
+ 'Normal' => 62,
+ 'High ASCII' => 95
+ );
+
+ public function __construct($_script, $_encoding = 62, $_fastDecode = true, $_specialChars = false)
+ {
+ $this->_script = $_script . "\n";
+ if (array_key_exists($_encoding, $this->LITERAL_ENCODING))
+ $_encoding = $this->LITERAL_ENCODING[$_encoding];
+ $this->_encoding = min((int)$_encoding, 95);
+ $this->_fastDecode = $_fastDecode;
+ $this->_specialChars = $_specialChars;
+ }
+
+ public function pack() {
+ $this->_addParser('_basicCompression');
+ if ($this->_specialChars)
+ $this->_addParser('_encodeSpecialChars');
+ if ($this->_encoding)
+ $this->_addParser('_encodeKeywords');
+
+ // go!
+ return $this->_pack($this->_script);
+ }
+
+ // apply all parsing routines
+ private function _pack($script) {
+ for ($i = 0; isset($this->_parsers[$i]); $i++) {
+ $script = call_user_func(array(&$this,$this->_parsers[$i]), $script);
+ }
+ return $script;
+ }
+
+ // keep a list of parsing functions, they'll be executed all at once
+ private $_parsers = array();
+ private function _addParser($parser) {
+ $this->_parsers[] = $parser;
+ }
+
+ // zero encoding - just removal of white space and comments
+ private function _basicCompression($script) {
+ $parser = new ParseMaster();
+ // make safe
+ $parser->escapeChar = '\\';
+ // protect strings
+ $parser->add('/\'[^\'\\n\\r]*\'/', self::IGNORE);
+ $parser->add('/"[^"\\n\\r]*"/', self::IGNORE);
+ // remove comments
+ $parser->add('/\\/\\/[^\\n\\r]*[\\n\\r]/', ' ');
+ $parser->add('/\\/\\*[^*]*\\*+([^\\/][^*]*\\*+)*\\//', ' ');
+ // protect regular expressions
+ $parser->add('/\\s+(\\/[^\\/\\n\\r\\*][^\\/\\n\\r]*\\/g?i?)/', '$2'); // IGNORE
+ $parser->add('/[^\\w\\x24\\/\'"*)\\?:]\\/[^\\/\\n\\r\\*][^\\/\\n\\r]*\\/g?i?/', self::IGNORE);
+ // remove: ;;; doSomething();
+ if ($this->_specialChars) $parser->add('/;;;[^\\n\\r]+[\\n\\r]/');
+ // remove redundant semi-colons
+ $parser->add('/\\(;;\\)/', self::IGNORE); // protect for (;;) loops
+ $parser->add('/;+\\s*([};])/', '$2');
+ // apply the above
+ $script = $parser->exec($script);
+
+ // remove white-space
+ $parser->add('/(\\b|\\x24)\\s+(\\b|\\x24)/', '$2 $3');
+ $parser->add('/([+\\-])\\s+([+\\-])/', '$2 $3');
+ $parser->add('/\\s+/', '');
+ // done
+ return $parser->exec($script);
+ }
+
+ private function _encodeSpecialChars($script) {
+ $parser = new ParseMaster();
+ // replace: $name -> n, $$name -> na
+ $parser->add('/((\\x24+)([a-zA-Z$_]+))(\\d*)/',
+ array('fn' => '_replace_name')
+ );
+ // replace: _name -> _0, double-underscore (__name) is ignored
+ $regexp = '/\\b_[A-Za-z\\d]\\w*/';
+ // build the word list
+ $keywords = $this->_analyze($script, $regexp, '_encodePrivate');
+ // quick ref
+ $encoded = $keywords['encoded'];
+
+ $parser->add($regexp,
+ array(
+ 'fn' => '_replace_encoded',
+ 'data' => $encoded
+ )
+ );
+ return $parser->exec($script);
+ }
+
+ private function _encodeKeywords($script) {
+ // escape high-ascii values already in the script (i.e. in strings)
+ if ($this->_encoding > 62)
+ $script = $this->_escape95($script);
+ // create the parser
+ $parser = new ParseMaster();
+ $encode = $this->_getEncoder($this->_encoding);
+ // for high-ascii, don't encode single character low-ascii
+ $regexp = ($this->_encoding > 62) ? '/\\w\\w+/' : '/\\w+/';
+ // build the word list
+ $keywords = $this->_analyze($script, $regexp, $encode);
+ $encoded = $keywords['encoded'];
+
+ // encode
+ $parser->add($regexp,
+ array(
+ 'fn' => '_replace_encoded',
+ 'data' => $encoded
+ )
+ );
+ if (empty($script)) return $script;
+ else {
+ //$res = $parser->exec($script);
+ //$res = $this->_bootStrap($res, $keywords);
+ //return $res;
+ return $this->_bootStrap($parser->exec($script), $keywords);
+ }
+ }
+
+ private function _analyze($script, $regexp, $encode) {
+ // analyse
+ // retreive all words in the script
+ $all = array();
+ preg_match_all($regexp, $script, $all);
+ $_sorted = array(); // list of words sorted by frequency
+ $_encoded = array(); // dictionary of word->encoding
+ $_protected = array(); // instances of "protected" words
+ $all = $all[0]; // simulate the javascript comportement of global match
+ if (!empty($all)) {
+ $unsorted = array(); // same list, not sorted
+ $protected = array(); // "protected" words (dictionary of word->"word")
+ $value = array(); // dictionary of charCode->encoding (eg. 256->ff)
+ $this->_count = array(); // word->count
+ $i = count($all); $j = 0; //$word = null;
+ // count the occurrences - used for sorting later
+ do {
+ --$i;
+ $word = '$' . $all[$i];
+ if (!isset($this->_count[$word])) {
+ $this->_count[$word] = 0;
+ $unsorted[$j] = $word;
+ // make a dictionary of all of the protected words in this script
+ // these are words that might be mistaken for encoding
+ //if (is_string($encode) && method_exists($this, $encode))
+ $values[$j] = call_user_func(array(&$this, $encode), $j);
+ $protected['$' . $values[$j]] = $j++;
+ }
+ // increment the word counter
+ $this->_count[$word]++;
+ } while ($i > 0);
+ // prepare to sort the word list, first we must protect
+ // words that are also used as codes. we assign them a code
+ // equivalent to the word itself.
+ // e.g. if "do" falls within our encoding range
+ // then we store keywords["do"] = "do";
+ // this avoids problems when decoding
+ $i = count($unsorted);
+ do {
+ $word = $unsorted[--$i];
+ if (isset($protected[$word]) /*!= null*/) {
+ $_sorted[$protected[$word]] = substr($word, 1);
+ $_protected[$protected[$word]] = true;
+ $this->_count[$word] = 0;
+ }
+ } while ($i);
+
+ // sort the words by frequency
+ // Note: the javascript and php version of sort can be different :
+ // in php manual, usort :
+ // " If two members compare as equal,
+ // their order in the sorted array is undefined."
+ // so the final packed script is different of the Dean's javascript version
+ // but equivalent.
+ // the ECMAscript standard does not guarantee this behaviour,
+ // and thus not all browsers (e.g. Mozilla versions dating back to at
+ // least 2003) respect this.
+ usort($unsorted, array(&$this, '_sortWords'));
+ $j = 0;
+ // because there are "protected" words in the list
+ // we must add the sorted words around them
+ do {
+ if (!isset($_sorted[$i]))
+ $_sorted[$i] = substr($unsorted[$j++], 1);
+ $_encoded[$_sorted[$i]] = $values[$i];
+ } while (++$i < count($unsorted));
+ }
+ return array(
+ 'sorted' => $_sorted,
+ 'encoded' => $_encoded,
+ 'protected' => $_protected);
+ }
+
+ private $_count = array();
+ private function _sortWords($match1, $match2) {
+ return $this->_count[$match2] - $this->_count[$match1];
+ }
+
+ // build the boot function used for loading and decoding
+ private function _bootStrap($packed, $keywords) {
+ $ENCODE = $this->_safeRegExp('$encode\\($count\\)');
+
+ // $packed: the packed script
+ $packed = "'" . $this->_escape($packed) . "'";
+
+ // $ascii: base for encoding
+ $ascii = min(count($keywords['sorted']), $this->_encoding);
+ if ($ascii == 0) $ascii = 1;
+
+ // $count: number of words contained in the script
+ $count = count($keywords['sorted']);
+
+ // $keywords: list of words contained in the script
+ foreach ($keywords['protected'] as $i=>$value) {
+ $keywords['sorted'][$i] = '';
+ }
+ // convert from a string to an array
+ ksort($keywords['sorted']);
+ $keywords = "'" . implode('|',$keywords['sorted']) . "'.split('|')";
+
+ $encode = ($this->_encoding > 62) ? '_encode95' : $this->_getEncoder($ascii);
+ $encode = $this->_getJSFunction($encode);
+ $encode = preg_replace('/_encoding/','$ascii', $encode);
+ $encode = preg_replace('/arguments\\.callee/','$encode', $encode);
+ $inline = '\\$count' . ($ascii > 10 ? '.toString(\\$ascii)' : '');
+
+ // $decode: code snippet to speed up decoding
+ if ($this->_fastDecode) {
+ // create the decoder
+ $decode = $this->_getJSFunction('_decodeBody');
+ if ($this->_encoding > 62)
+ $decode = preg_replace('/\\\\w/', '[\\xa1-\\xff]', $decode);
+ // perform the encoding inline for lower ascii values
+ elseif ($ascii < 36)
+ $decode = preg_replace($ENCODE, $inline, $decode);
+ // special case: when $count==0 there are no keywords. I want to keep
+ // the basic shape of the unpacking funcion so i'll frig the code...
+ if ($count == 0)
+ $decode = preg_replace($this->_safeRegExp('($count)\\s*=\\s*1'), '$1=0', $decode, 1);
+ }
+
+ // boot function
+ $unpack = $this->_getJSFunction('_unpack');
+ if ($this->_fastDecode) {
+ // insert the decoder
+ $this->buffer = $decode;
+ $unpack = preg_replace_callback('/\\{/', array(&$this, '_insertFastDecode'), $unpack, 1);
+ }
+ $unpack = preg_replace('/"/', "'", $unpack);
+ if ($this->_encoding > 62) { // high-ascii
+ // get rid of the word-boundaries for regexp matches
+ $unpack = preg_replace('/\'\\\\\\\\b\'\s*\\+|\\+\s*\'\\\\\\\\b\'/', '', $unpack);
+ }
+ if ($ascii > 36 || $this->_encoding > 62 || $this->_fastDecode) {
+ // insert the encode function
+ $this->buffer = $encode;
+ $unpack = preg_replace_callback('/\\{/', array(&$this, '_insertFastEncode'), $unpack, 1);
+ } else {
+ // perform the encoding inline
+ $unpack = preg_replace($ENCODE, $inline, $unpack);
+ }
+ // pack the boot function too
+ $unpackPacker = new JavaScriptPacker($unpack, 0, false, true);
+ $unpack = $unpackPacker->pack();
+
+ // arguments
+ $params = array($packed, $ascii, $count, $keywords);
+ if ($this->_fastDecode) {
+ $params[] = 0;
+ $params[] = '{}';
+ }
+ $params = implode(',', $params);
+
+ // the whole thing
+ return 'eval(' . $unpack . '(' . $params . "))\n";
+ }
+
+ private $buffer;
+ private function _insertFastDecode($match) {
+ return '{' . $this->buffer . ';';
+ }
+ private function _insertFastEncode($match) {
+ return '{$encode=' . $this->buffer . ';';
+ }
+
+ // mmm.. ..which one do i need ??
+ private function _getEncoder($ascii) {
+ return $ascii > 10 ? $ascii > 36 ? $ascii > 62 ?
+ '_encode95' : '_encode62' : '_encode36' : '_encode10';
+ }
+
+ // zero encoding
+ // characters: 0123456789
+ private function _encode10($charCode) {
+ return $charCode;
+ }
+
+ // inherent base36 support
+ // characters: 0123456789abcdefghijklmnopqrstuvwxyz
+ private function _encode36($charCode) {
+ return base_convert($charCode, 10, 36);
+ }
+
+ // hitch a ride on base36 and add the upper case alpha characters
+ // characters: 0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
+ private function _encode62($charCode) {
+ $res = '';
+ if ($charCode >= $this->_encoding) {
+ $res = $this->_encode62((int)($charCode / $this->_encoding));
+ }
+ $charCode = $charCode % $this->_encoding;
+
+ if ($charCode > 35)
+ return $res . chr($charCode + 29);
+ else
+ return $res . base_convert($charCode, 10, 36);
+ }
+
+ // use high-ascii values
+ // characters: ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÃÂÃÄÅÆÇÈÉÊËÌÃÃŽÃÃÑÒÓÔÕÖ×ØÙÚÛÜÃÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþ
+ private function _encode95($charCode) {
+ $res = '';
+ if ($charCode >= $this->_encoding)
+ $res = $this->_encode95($charCode / $this->_encoding);
+
+ return $res . chr(($charCode % $this->_encoding) + 161);
+ }
+
+ private function _safeRegExp($string) {
+ return '/'.preg_replace('/\$/', '\\\$', $string).'/';
+ }
+
+ private function _encodePrivate($charCode) {
+ return "_" . $charCode;
+ }
+
+ // protect characters used by the parser
+ private function _escape($script) {
+ return preg_replace('/([\\\\\'])/', '\\\$1', $script);
+ }
+
+ // protect high-ascii characters already in the script
+ private function _escape95($script) {
+ return preg_replace_callback(
+ '/[\\xa1-\\xff]/',
+ array(&$this, '_escape95Bis'),
+ $script
+ );
+ }
+ private function _escape95Bis($match) {
+ return '\x'.((string)dechex(ord($match)));
+ }
+
+
+ private function _getJSFunction($aName) {
+ if (defined('self::JSFUNCTION'.$aName))
+ return constant('self::JSFUNCTION'.$aName);
+ else
+ return '';
+ }
+
+ // JavaScript Functions used.
+ // Note : In Dean's version, these functions are converted
+ // with 'String(aFunctionName);'.
+ // This internal conversion complete the original code, ex :
+ // 'while (aBool) anAction();' is converted to
+ // 'while (aBool) { anAction(); }'.
+ // The JavaScript functions below are corrected.
+
+ // unpacking function - this is the boot strap function
+ // data extracted from this packing routine is passed to
+ // this function when decoded in the target
+ // NOTE ! : without the ';' final.
+ const JSFUNCTION_unpack =
+
+'function($packed, $ascii, $count, $keywords, $encode, $decode) {
+ while ($count--) {
+ if ($keywords[$count]) {
+ $packed = $packed.replace(new RegExp(\'\\\\b\' + $encode($count) + \'\\\\b\', \'g\'), $keywords[$count]);
+ }
+ }
+ return $packed;
+}';
+/*
+'function($packed, $ascii, $count, $keywords, $encode, $decode) {
+ while ($count--)
+ if ($keywords[$count])
+ $packed = $packed.replace(new RegExp(\'\\\\b\' + $encode($count) + \'\\\\b\', \'g\'), $keywords[$count]);
+ return $packed;
+}';
+*/
+
+ // code-snippet inserted into the unpacker to speed up decoding
+ const JSFUNCTION_decodeBody =
+//_decode = function() {
+// does the browser support String.replace where the
+// replacement value is a function?
+
+' if (!\'\'.replace(/^/, String)) {
+ // decode all the values we need
+ while ($count--) {
+ $decode[$encode($count)] = $keywords[$count] || $encode($count);
+ }
+ // global replacement function
+ $keywords = [function ($encoded) {return $decode[$encoded]}];
+ // generic match
+ $encode = function () {return \'\\\\w+\'};
+ // reset the loop counter - we are now doing a global replace
+ $count = 1;
+ }
+';
+//};
+/*
+' if (!\'\'.replace(/^/, String)) {
+ // decode all the values we need
+ while ($count--) $decode[$encode($count)] = $keywords[$count] || $encode($count);
+ // global replacement function
+ $keywords = [function ($encoded) {return $decode[$encoded]}];
+ // generic match
+ $encode = function () {return\'\\\\w+\'};
+ // reset the loop counter - we are now doing a global replace
+ $count = 1;
+ }';
+*/
+
+ // zero encoding
+ // characters: 0123456789
+ const JSFUNCTION_encode10 =
+'function($charCode) {
+ return $charCode;
+}';//;';
+
+ // inherent base36 support
+ // characters: 0123456789abcdefghijklmnopqrstuvwxyz
+ const JSFUNCTION_encode36 =
+'function($charCode) {
+ return $charCode.toString(36);
+}';//;';
+
+ // hitch a ride on base36 and add the upper case alpha characters
+ // characters: 0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
+ const JSFUNCTION_encode62 =
+'function($charCode) {
+ return ($charCode < _encoding ? \'\' : arguments.callee(parseInt($charCode / _encoding))) +
+ (($charCode = $charCode % _encoding) > 35 ? String.fromCharCode($charCode + 29) : $charCode.toString(36));
+}';
+
+ // use high-ascii values
+ // characters: ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÃÂÃÄÅÆÇÈÉÊËÌÃÃŽÃÃÑÒÓÔÕÖ×ØÙÚÛÜÃÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþ
+ const JSFUNCTION_encode95 =
+'function($charCode) {
+ return ($charCode < _encoding ? \'\' : arguments.callee($charCode / _encoding)) +
+ String.fromCharCode($charCode % _encoding + 161);
+}';
+
+}
+
+
+class ParseMaster {
+ public $ignoreCase = false;
+ public $escapeChar = '';
+
+ // constants
+ const EXPRESSION = 0;
+ const REPLACEMENT = 1;
+ const LENGTH = 2;
+
+ // used to determine nesting levels
+ private $GROUPS = '/\\(/';//g
+ private $SUB_REPLACE = '/\\$\\d/';
+ private $INDEXED = '/^\\$\\d+$/';
+ private $TRIM = '/([\'"])\\1\\.(.*)\\.\\1\\1$/';
+ private $ESCAPE = '/\\\./';//g
+ private $QUOTE = '/\'/';
+ private $DELETED = '/\\x01[^\\x01]*\\x01/';//g
+
+ public function add($expression, $replacement = '') {
+ // count the number of sub-expressions
+ // - add one because each pattern is itself a sub-expression
+ $length = 1 + preg_match_all($this->GROUPS, $this->_internalEscape((string)$expression), $out);
+
+ // treat only strings $replacement
+ if (is_string($replacement)) {
+ // does the pattern deal with sub-expressions?
+ if (preg_match($this->SUB_REPLACE, $replacement)) {
+ // a simple lookup? (e.g. "$2")
+ if (preg_match($this->INDEXED, $replacement)) {
+ // store the index (used for fast retrieval of matched strings)
+ $replacement = (int)(substr($replacement, 1)) - 1;
+ } else { // a complicated lookup (e.g. "Hello $2 $1")
+ // build a function to do the lookup
+ $quote = preg_match($this->QUOTE, $this->_internalEscape($replacement))
+ ? '"' : "'";
+ $replacement = array(
+ 'fn' => '_backReferences',
+ 'data' => array(
+ 'replacement' => $replacement,
+ 'length' => $length,
+ 'quote' => $quote
+ )
+ );
+ }
+ }
+ }
+ // pass the modified arguments
+ if (!empty($expression)) $this->_add($expression, $replacement, $length);
+ else $this->_add('/^$/', $replacement, $length);
+ }
+
+ public function exec($string) {
+ // execute the global replacement
+ $this->_escaped = array();
+
+ // simulate the _patterns.toSTring of Dean
+ $regexp = '/';
+ foreach ($this->_patterns as $reg) {
+ $regexp .= '(' . substr($reg[self::EXPRESSION], 1, -1) . ')|';
+ }
+ $regexp = substr($regexp, 0, -1) . '/';
+ $regexp .= ($this->ignoreCase) ? 'i' : '';
+
+ $string = $this->_escape($string, $this->escapeChar);
+ $string = preg_replace_callback(
+ $regexp,
+ array(
+ &$this,
+ '_replacement'
+ ),
+ $string
+ );
+ $string = $this->_unescape($string, $this->escapeChar);
+
+ return preg_replace($this->DELETED, '', $string);
+ }
+
+ public function reset() {
+ // clear the patterns collection so that this object may be re-used
+ $this->_patterns = array();
+ }
+
+ // private
+ private $_escaped = array(); // escaped characters
+ private $_patterns = array(); // patterns stored by index
+
+ // create and add a new pattern to the patterns collection
+ private function _add() {
+ $arguments = func_get_args();
+ $this->_patterns[] = $arguments;
+ }
+
+ // this is the global replace function (it's quite complicated)
+ private function _replacement($arguments) {
+ if (empty($arguments)) return '';
+
+ $i = 1; $j = 0;
+ // loop through the patterns
+ while (isset($this->_patterns[$j])) {
+ $pattern = $this->_patterns[$j++];
+ // do we have a result?
+ if (isset($arguments[$i]) && ($arguments[$i] != '')) {
+ $replacement = $pattern[self::REPLACEMENT];
+
+ if (is_array($replacement) && isset($replacement['fn'])) {
+
+ if (isset($replacement['data'])) $this->buffer = $replacement['data'];
+ return call_user_func(array(&$this, $replacement['fn']), $arguments, $i);
+
+ } elseif (is_int($replacement)) {
+ return $arguments[$replacement + $i];
+
+ }
+ $delete = ($this->escapeChar == '' ||
+ strpos($arguments[$i], $this->escapeChar) === false)
+ ? '' : "\x01" . $arguments[$i] . "\x01";
+ return $delete . $replacement;
+
+ // skip over references to sub-expressions
+ } else {
+ $i += $pattern[self::LENGTH];
+ }
+ }
+ }
+
+ private function _backReferences($match, $offset) {
+ $replacement = $this->buffer['replacement'];
+ $quote = $this->buffer['quote'];
+ $i = $this->buffer['length'];
+ while ($i) {
+ $replacement = str_replace('$'.$i--, $match[$offset + $i], $replacement);
+ }
+ return $replacement;
+ }
+
+ private function _replace_name($match, $offset){
+ $length = strlen($match[$offset + 2]);
+ $start = $length - max($length - strlen($match[$offset + 3]), 0);
+ return substr($match[$offset + 1], $start, $length) . $match[$offset + 4];
+ }
+
+ private function _replace_encoded($match, $offset) {
+ return $this->buffer[$match[$offset]];
+ }
+
+
+ // php : we cannot pass additional data to preg_replace_callback,
+ // and we cannot use &$this in create_function, so let's go to lower level
+ private $buffer;
+
+ // encode escaped characters
+ private function _escape($string, $escapeChar) {
+ if ($escapeChar) {
+ $this->buffer = $escapeChar;
+ return preg_replace_callback(
+ '/\\' . $escapeChar . '(.)' .'/',
+ array(&$this, '_escapeBis'),
+ $string
+ );
+
+ } else {
+ return $string;
+ }
+ }
+ private function _escapeBis($match) {
+ $this->_escaped[] = $match[1];
+ return $this->buffer;
+ }
+
+ // decode escaped characters
+ private function _unescape($string, $escapeChar) {
+ if ($escapeChar) {
+ $regexp = '/'.'\\'.$escapeChar.'/';
+ $this->buffer = array('escapeChar'=> $escapeChar, 'i' => 0);
+ return preg_replace_callback
+ (
+ $regexp,
+ array(&$this, '_unescapeBis'),
+ $string
+ );
+
+ } else {
+ return $string;
+ }
+ }
+ private function _unescapeBis() {
+ if (!empty($this->_escaped[$this->buffer['i']])) {
+ $temp = $this->_escaped[$this->buffer['i']];
+ } else {
+ $temp = '';
+ }
+ $this->buffer['i']++;
+ return $this->buffer['escapeChar'] . $temp;
+ }
+
+ private function _internalEscape($string) {
+ return preg_replace($this->ESCAPE, '', $string);
+ }
+}
+?>
diff --git a/site/app/webroot/js/simile/bundlemaker/make-bundle.sh b/site/app/webroot/js/simile/bundlemaker/make-bundle.sh
new file mode 100755
index 0000000..ab8dd1a
--- /dev/null
+++ b/site/app/webroot/js/simile/bundlemaker/make-bundle.sh
@@ -0,0 +1,23 @@
+BUNDLE="../amo-bundle.js"
+COMPRESSED="../amo-bundle.compressed.js"
+
+echo "Creating bundle..."
+echo "" > $BUNDLE
+#echo "Copying bundle template..."
+#cat bundle-template.js > $BUNDLE
+
+DIRECTORIES="ajax timeline timeplot"
+for dir in $DIRECTORIES;
+do
+ echo "Reading $dir inclusions file..."
+ for file in `cat $dir.txt`
+ do
+ echo " $dir/$file";
+ cat "../$dir/$file" >> $BUNDLE
+ done
+done
+
+echo "Compressing bundle..."
+/usr/bin/php -f pack-bundle.php $BUNDLE $COMPRESSED
+
+echo "Done"
diff --git a/site/app/webroot/js/simile/bundlemaker/pack-bundle.php b/site/app/webroot/js/simile/bundlemaker/pack-bundle.php
new file mode 100644
index 0000000..a3e1754
--- /dev/null
+++ b/site/app/webroot/js/simile/bundlemaker/pack-bundle.php
@@ -0,0 +1,26 @@
+<?php
+if ($argc >= 3) {
+ $src = $argv[1];
+ $out = $argv[2];
+} else {
+ echo 'you must specify a source file and a result filename',"\n";
+ echo 'example :', "\n", 'php example-file.php myScript-src.js myPackedScript.js',"\n";
+ return;
+}
+
+
+require 'class.JavaScriptPacker.php';
+
+$script = file_get_contents($src);
+
+$t1 = microtime(true);
+
+$packer = new JavaScriptPacker($script, 'Normal', true, false);
+$packed = $packer->pack();
+
+$t2 = microtime(true);
+$time = sprintf('%.4f', ($t2 - $t1) );
+echo 'script ', $src, ' packed in ' , $out, ', in ', $time, ' s.', "\n";
+
+file_put_contents($out, $packed);
+?>
diff --git a/site/app/webroot/js/simile/bundlemaker/timeline.txt b/site/app/webroot/js/simile/bundlemaker/timeline.txt
new file mode 100644
index 0000000..6afd38a
--- /dev/null
+++ b/site/app/webroot/js/simile/bundlemaker/timeline.txt
@@ -0,0 +1,12 @@
+timeline-api-amo-bundle.js
+scripts/timeline.js
+scripts/themes.js
+scripts/ethers.js
+scripts/ether-painters.js
+scripts/labellers.js
+scripts/sources.js
+scripts/original-painter.js
+scripts/detailed-painter.js
+scripts/overview-painter.js
+scripts/decorators.js
+scripts/units.js
diff --git a/site/app/webroot/js/simile/bundlemaker/timeplot.txt b/site/app/webroot/js/simile/bundlemaker/timeplot.txt
new file mode 100644
index 0000000..35f1924
--- /dev/null
+++ b/site/app/webroot/js/simile/bundlemaker/timeplot.txt
@@ -0,0 +1,9 @@
+timeplot-api-amo-bundle.js
+scripts/timeplot.js
+scripts/plot.js
+scripts/sources.js
+scripts/geometry.js
+scripts/color.js
+scripts/math.js
+scripts/processor.js
+lib/excanvas.js
diff --git a/site/app/webroot/js/simile/timeline/ext/geochrono/geochrono-api.js b/site/app/webroot/js/simile/timeline/ext/geochrono/geochrono-api.js
new file mode 100755
index 0000000..b16a2c3
--- /dev/null
+++ b/site/app/webroot/js/simile/timeline/ext/geochrono/geochrono-api.js
@@ -0,0 +1,92 @@
+/*==================================================
+ * Geochrono Extension
+ *
+ * This file will load all the Javascript files
+ * necessary to make the extension work.
+ *
+ *==================================================
+ */
+
+(function() {
+ var javascriptFiles = [
+ "geochrono.js",
+ "units.js",
+ "ether-painters.js",
+ "labellers.js"
+ ];
+ var cssFiles = [
+ ];
+
+ var localizedJavascriptFiles = [
+ "labellers.js"
+ ];
+ var localizedCssFiles = [
+ ];
+
+ // ISO-639 language codes, ISO-3166 country codes (2 characters)
+ var supportedLocales = [
+ "en" // English
+ ];
+
+ try {
+ var includeJavascriptFile = function(filename) {
+ document.write("<script src='" + Timeline.urlPrefix + "ext/geochrono/scripts/" + filename + "' type='text/javascript'></script>");
+ };
+ var includeCssFile = function(filename) {
+ document.write("<link rel='stylesheet' href='" + Timeline.urlPrefix + "ext/geochrono/styles/" + filename + "' type='text/css'/>");
+ }
+
+ /*
+ * Include non-localized files
+ */
+ for (var i = 0; i < javascriptFiles.length; i++) {
+ includeJavascriptFile(javascriptFiles[i]);
+ }
+ for (var i = 0; i < cssFiles.length; i++) {
+ includeCssFile(cssFiles[i]);
+ }
+
+ /*
+ * Include localized files
+ */
+ var loadLocale = [];
+ var tryExactLocale = function(locale) {
+ for (var l = 0; l < supportedLocales.length; l++) {
+ if (locale == supportedLocales[l]) {
+ loadLocale[locale] = true;
+ return true;
+ }
+ }
+ return false;
+ }
+ var tryLocale = function(locale) {
+ if (tryExactLocale(locale)) {
+ return locale;
+ }
+
+ var dash = locale.indexOf("-");
+ if (dash > 0 && tryExactLocale(locale.substr(0, dash))) {
+ return locale.substr(0, dash);
+ }
+
+ return null;
+ }
+
+ tryLocale(Timeline.serverLocale);
+ tryLocale(Timeline.clientLocale);
+
+ for (var l = 0; l < supportedLocales.length; l++) {
+ var locale = supportedLocales[l];
+ if (loadLocale[locale]) {
+ for (var i = 0; i < localizedJavascriptFiles.length; i++) {
+ includeJavascriptFile("l10n/" + locale + "/" + localizedJavascriptFiles[i]);
+ }
+ for (var i = 0; i < localizedCssFiles.length; i++) {
+ includeCssFile("l10n/" + locale + "/" + localizedCssFiles[i]);
+ }
+ }
+ }
+ } catch (e) {
+ alert(e);
+ }
+})(); \ No newline at end of file
diff --git a/site/app/webroot/js/simile/timeline/ext/geochrono/scripts/ether-painters.js b/site/app/webroot/js/simile/timeline/ext/geochrono/scripts/ether-painters.js
new file mode 100755
index 0000000..c9c0453
--- /dev/null
+++ b/site/app/webroot/js/simile/timeline/ext/geochrono/scripts/ether-painters.js
@@ -0,0 +1,204 @@
+/*==================================================
+ * Geochrono Ether Painter
+ *==================================================
+ */
+
+Timeline.GeochronoEtherPainter = function(params, band, timeline) {
+ this._params = params;
+ this._intervalUnit = params.intervalUnit;
+ this._multiple = ("multiple" in params) ? params.multiple : 1;
+ this._theme = params.theme;
+};
+
+Timeline.GeochronoEtherPainter.prototype.initialize = function(band, timeline) {
+ this._band = band;
+ this._timeline = timeline;
+
+ this._backgroundLayer = band.createLayerDiv(0);
+ this._backgroundLayer.setAttribute("name", "ether-background"); // for debugging
+ this._backgroundLayer.style.background = this._theme.ether.backgroundColors[band.getIndex()];
+
+ this._markerLayer = null;
+ this._lineLayer = null;
+
+ var align = ("align" in this._params && typeof this._params.align == "string") ? this._params.align :
+ this._theme.ether.interval.marker[timeline.isHorizontal() ? "hAlign" : "vAlign"];
+ var showLine = ("showLine" in this._params) ? this._params.showLine :
+ this._theme.ether.interval.line.show;
+
+ this._intervalMarkerLayout = new Timeline.GeochronoEtherMarkerLayout(
+ this._timeline, this._band, this._theme, align, showLine);
+
+ this._highlight = new Timeline.EtherHighlight(
+ this._timeline, this._band, this._theme, this._backgroundLayer);
+}
+
+Timeline.GeochronoEtherPainter.prototype.setHighlight = function(startDate, endDate) {
+ this._highlight.position(startDate, endDate);
+}
+
+Timeline.GeochronoEtherPainter.prototype.paint = function() {
+ if (this._markerLayer) {
+ this._band.removeLayerDiv(this._markerLayer);
+ }
+ this._markerLayer = this._band.createLayerDiv(100);
+ this._markerLayer.setAttribute("name", "ether-markers"); // for debugging
+ this._markerLayer.style.display = "none";
+
+ if (this._lineLayer) {
+ this._band.removeLayerDiv(this._lineLayer);
+ }
+ this._lineLayer = this._band.createLayerDiv(1);
+ this._lineLayer.setAttribute("name", "ether-lines"); // for debugging
+ this._lineLayer.style.display = "none";
+
+ var minDate = Math.ceil(Timeline.GeochronoUnit.toNumber(this._band.getMinDate()));
+ var maxDate = Math.floor(Timeline.GeochronoUnit.toNumber(this._band.getMaxDate()));
+
+ var increment;
+ var hasMore;
+ (function(intervalUnit, multiple) {
+ var dates;
+
+ switch (intervalUnit) {
+ case Timeline.GeochronoUnit.AGE:
+ dates = Timeline.Geochrono.ages; break;
+ case Timeline.GeochronoUnit.EPOCH:
+ dates = Timeline.Geochrono.epoches; break;
+ case Timeline.GeochronoUnit.PERIOD:
+ dates = Timeline.Geochrono.periods; break;
+ case Timeline.GeochronoUnit.ERA:
+ dates = Timeline.Geochrono.eras; break;
+ case Timeline.GeochronoUnit.EON:
+ dates = Timeline.Geochrono.eons; break;
+ default:
+ hasMore = function() {
+ return minDate > 0 && minDate > maxDate;
+ }
+ increment = function() {
+ minDate -= multiple;
+ };
+ return;
+ }
+
+ var startIndex = dates.length - 1;
+ while (startIndex > 0) {
+ if (minDate <= dates[startIndex].start) {
+ break;
+ }
+ startIndex--;
+ }
+
+ minDate = dates[startIndex].start;
+ hasMore = function() {
+ return startIndex < (dates.length - 1) && minDate > maxDate;
+ };
+ increment = function() {
+ startIndex++;
+ minDate = dates[startIndex].start;
+ };
+ })(this._intervalUnit, this._multiple);
+
+ var labeller = this._band.getLabeller();
+ while (true) {
+ this._intervalMarkerLayout.createIntervalMarker(
+ Timeline.GeochronoUnit.fromNumber(minDate),
+ labeller,
+ this._intervalUnit,
+ this._markerLayer,
+ this._lineLayer
+ );
+ if (hasMore()) {
+ increment();
+ } else {
+ break;
+ }
+ }
+ this._markerLayer.style.display = "block";
+ this._lineLayer.style.display = "block";
+};
+
+Timeline.GeochronoEtherPainter.prototype.softPaint = function() {
+};
+
+
+/*==================================================
+ * Geochrono Ether Marker Layout
+ *==================================================
+ */
+
+Timeline.GeochronoEtherMarkerLayout = function(timeline, band, theme, align, showLine) {
+ var horizontal = timeline.isHorizontal();
+ if (horizontal) {
+ if (align == "Top") {
+ this.positionDiv = function(div, offset) {
+ div.style.left = offset + "px";
+ div.style.top = "0px";
+ };
+ } else {
+ this.positionDiv = function(div, offset) {
+ div.style.left = offset + "px";
+ div.style.bottom = "0px";
+ };
+ }
+ } else {
+ if (align == "Left") {
+ this.positionDiv = function(div, offset) {
+ div.style.top = offset + "px";
+ div.style.left = "0px";
+ };
+ } else {
+ this.positionDiv = function(div, offset) {
+ div.style.top = offset + "px";
+ div.style.right = "0px";
+ };
+ }
+ }
+
+ var markerTheme = theme.ether.interval.marker;
+ var lineTheme = theme.ether.interval.line;
+
+ var stylePrefix = (horizontal ? "h" : "v") + align;
+ var labelStyler = markerTheme[stylePrefix + "Styler"];
+ var emphasizedLabelStyler = markerTheme[stylePrefix + "EmphasizedStyler"];
+
+ this.createIntervalMarker = function(date, labeller, unit, markerDiv, lineDiv) {
+ var offset = Math.round(band.dateToPixelOffset(date));
+
+ if (showLine) {
+ var divLine = timeline.getDocument().createElement("div");
+ divLine.style.position = "absolute";
+
+ if (lineTheme.opacity < 100) {
+ SimileAjax.Graphics.setOpacity(divLine, lineTheme.opacity);
+ }
+
+ if (horizontal) {
+ divLine.style.borderLeft = "1px solid " + lineTheme.color;
+ divLine.style.left = offset + "px";
+ divLine.style.width = "1px";
+ divLine.style.top = "0px";
+ divLine.style.height = "100%";
+ } else {
+ divLine.style.borderTop = "1px solid " + lineTheme.color;
+ divLine.style.top = offset + "px";
+ divLine.style.height = "1px";
+ divLine.style.left = "0px";
+ divLine.style.width = "100%";
+ }
+ lineDiv.appendChild(divLine);
+ }
+
+ var label = labeller.labelInterval(date, unit);
+
+ var div = timeline.getDocument().createElement("div");
+ div.innerHTML = label.text;
+ div.style.position = "absolute";
+ (label.emphasized ? emphasizedLabelStyler : labelStyler)(div);
+
+ this.positionDiv(div, offset);
+ markerDiv.appendChild(div);
+
+ return div;
+ };
+}; \ No newline at end of file
diff --git a/site/app/webroot/js/simile/timeline/ext/geochrono/scripts/geochrono.js b/site/app/webroot/js/simile/timeline/ext/geochrono/scripts/geochrono.js
new file mode 100755
index 0000000..dc9716a
--- /dev/null
+++ b/site/app/webroot/js/simile/timeline/ext/geochrono/scripts/geochrono.js
@@ -0,0 +1,518 @@
+/*==================================================
+ * Geochrono
+ *==================================================
+ */
+Timeline.Geochrono = new Object();
+Timeline.Geochrono.eons = [
+ { name: "Proterozoic",
+ start: 2500.000
+ },
+ { name: "Phanerozoic",
+ start: 542.000
+ }
+];
+Timeline.Geochrono.eras = [
+ { name: "Paleoarchean",
+ start: 3600.000
+ },
+ { name: "Mesoarchean",
+ start: 3200.000
+ },
+ { name: "Neoarchean",
+ start: 2800.000
+ },
+ { name: "Paleoproterozoic",
+ start: 2500.000
+ },
+ { name: "Mesoproterozoic",
+ start: 1600.000
+ },
+ { name: "Neoproterozoic",
+ start: 1000.000
+ },
+ { name: "Paleozoic",
+ start: 542.000
+ },
+ { name: "Mesozoic",
+ start: 251.000
+ },
+ { name: "Cenozoic",
+ start: 65.500
+ }
+];
+Timeline.Geochrono.periods = [
+ { name: "Siderian",
+ start: 2500.000
+ },
+ { name: "Rhyacian",
+ start: 2300.000
+ },
+ { name: "Orosirian",
+ start: 2050.000
+ },
+ { name: "Statherian",
+ start: 1800.000
+ },
+ { name: "Calymmian",
+ start: 1600.000
+ },
+ { name: "Ectasian",
+ start: 1400.000
+ },
+ { name: "Stenian",
+ start: 1200.000
+ },
+ { name: "Tonian",
+ start: 1000.000
+ },
+ { name: "Cryogenian",
+ start: 850.000
+ },
+ { name: "Ediacaran",
+ start: 600.000
+ },
+ { name: "Cambrian",
+ start: 542.000
+ },
+ { name: "Ordovician",
+ start: 488.300
+ },
+ { name: "Silurian",
+ start: 443.700
+ },
+ { name: "Devonian",
+ start: 416.000
+ },
+ { name: "Carboniferous",
+ start: 359.200
+ },
+ { name: "Permian",
+ start: 299.000
+ },
+ { name: "Triassic",
+ start: 251.000
+ },
+ { name: "Jurassic",
+ start: 199.600
+ },
+ { name: "Cretaceous",
+ start: 145.500
+ },
+ { name: "Paleogene",
+ start: 65.500
+ },
+ { name: "Neogene",
+ start: 23.030
+ }
+];
+Timeline.Geochrono.epoches = [
+ { name: "Lower Cambrian",
+ start: 542.000
+ },
+ { name: "Middle Cambrian",
+ start: 513.000
+ },
+ { name: "Furongian",
+ start: 501.000
+ },
+ { name: "Lower Ordovician",
+ start: 488.300
+ },
+ { name: "Middle Ordovician",
+ start: 471.800
+ },
+ { name: "Upper Ordovician",
+ start: 460.900
+ },
+ { name: "Llandovery",
+ start: 443.700
+ },
+ { name: "Wenlock",
+ start: 428.200
+ },
+ { name: "Ludlow",
+ start: 422.900
+ },
+ { name: "Pridoli",
+ start: 418.700
+ },
+ { name: "Lower Devonian",
+ start: 416.000
+ },
+ { name: "Middle Devonian",
+ start: 397.500
+ },
+ { name: "Upper Devonian",
+ start: 385.300
+ },
+ { name: "Mississippian",
+ start: 359.200
+ },
+ { name: "Pennsylvanian",
+ start: 318.100
+ },
+ { name: "Cisuralian",
+ start: 299.000
+ },
+ { name: "Guadalupian",
+ start: 270.600
+ },
+ { name: "Lopingian",
+ start: 260.400
+ },
+ { name: "Lower Triassic",
+ start: 251.000
+ },
+ { name: "Middle Triassic",
+ start: 245.000
+ },
+ { name: "Upper Triassic",
+ start: 228.000
+ },
+ { name: "Lower Jurassic",
+ start: 199.600
+ },
+ { name: "Middle Jurassic",
+ start: 175.600
+ },
+ { name: "Upper Jurassic",
+ start: 161.200
+ },
+ { name: "Lower Cretaceous",
+ start: 145.500
+ },
+ { name: "Upper Cretaceous",
+ start: 99.600
+ },
+ { name: "Paleocene",
+ start: 65.500
+ },
+ { name: "Eocene",
+ start: 55.800
+ },
+ { name: "Oligocene",
+ start: 33.900
+ },
+ { name: "Miocene",
+ start: 23.030
+ },
+ { name: "Pliocene",
+ start: 5.332
+ },
+ { name: "Pleistocene",
+ start: 1.806
+ },
+ { name: "Holocene",
+ start: 0.012
+ }
+];
+Timeline.Geochrono.ages = [
+ { name: "-",
+ start: 542.000
+ },
+ { name: "-",
+ start: 513.000
+ },
+ { name: "Paibian",
+ start: 501.000
+ },
+ { name: "Tremadocian",
+ start: 488.300
+ },
+ { name: "-",
+ start: 478.600
+ },
+ { name: "-",
+ start: 471.800
+ },
+ { name: "Darriwilian",
+ start: 468.100
+ },
+ { name: "-",
+ start: 460.900
+ },
+ { name: "-",
+ start: 455.800
+ },
+ { name: "Hirnantian",
+ start: 445.600
+ },
+ { name: "Rhuddanian",
+ start: 443.700
+ },
+ { name: "Aeronian",
+ start: 439.000
+ },
+ { name: "Telychian",
+ start: 436.100
+ },
+ { name: "Sheinwoodian",
+ start: 428.200
+ },
+ { name: "Homerian",
+ start: 426.200
+ },
+ { name: "Gorstian",
+ start: 422.900
+ },
+ { name: "Ludfordian",
+ start: 421.300
+ },
+ { name: "-",
+ start: 418.700
+ },
+ { name: "Lochkovian",
+ start: 416.000
+ },
+ { name: "Pragian",
+ start: 411.200
+ },
+ { name: "Emsian",
+ start: 407.000
+ },
+ { name: "Eifelian",
+ start: 397.500
+ },
+ { name: "Givetian",
+ start: 391.800
+ },
+ { name: "Frasnian",
+ start: 385.300
+ },
+ { name: "Famennian",
+ start: 374.500
+ },
+ { name: "Tournaisian",
+ start: 359.200
+ },
+ { name: "Visean",
+ start: 345.300
+ },
+ { name: "Serpukhovian",
+ start: 326.400
+ },
+ { name: "Bashkirian",
+ start: 318.100
+ },
+ { name: "Moscovian",
+ start: 311.700
+ },
+ { name: "Kazimovian",
+ start: 306.500
+ },
+ { name: "Gzhelian",
+ start: 303.900
+ },
+ { name: "Asselian",
+ start: 299.000
+ },
+ { name: "Sakmarian",
+ start: 294.600
+ },
+ { name: "Artinskian",
+ start: 284.400
+ },
+ { name: "Kungurian",
+ start: 275.600
+ },
+ { name: "Roadian",
+ start: 270.600
+ },
+ { name: "Wordian",
+ start: 268.000
+ },
+ { name: "Capitanian",
+ start: 265.800
+ },
+ { name: "Wuchiapingian",
+ start: 260.400
+ },
+ { name: "Changhsingian",
+ start: 253.800
+ },
+ { name: "Induan",
+ start: 251.000
+ },
+ { name: "Olenekian",
+ start: 249.700
+ },
+ { name: "Anisian",
+ start: 245.000
+ },
+ { name: "Ladinian",
+ start: 237.000
+ },
+ { name: "Carnian",
+ start: 228.000
+ },
+ { name: "Norian",
+ start: 216.500
+ },
+ { name: "Rhaetian",
+ start: 203.600
+ },
+ { name: "Hettangian",
+ start: 199.600
+ },
+ { name: "Sinemurian",
+ start: 196.500
+ },
+ { name: "Pliensbachian",
+ start: 189.600
+ },
+ { name: "Toarcian",
+ start: 183.000
+ },
+ { name: "Aalenian",
+ start: 175.600
+ },
+ { name: "Bajocian",
+ start: 171.600
+ },
+ { name: "Bathonian",
+ start: 167.700
+ },
+ { name: "Callovian",
+ start: 164.700
+ },
+ { name: "Oxfordian",
+ start: 161.200
+ },
+ { name: "Kimmeridgian",
+ start: 155.000
+ },
+ { name: "Tithonian",
+ start: 150.800
+ },
+ { name: "Berriasian",
+ start: 145.500
+ },
+ { name: "Valanginian",
+ start: 140.200
+ },
+ { name: "Hauterivian",
+ start: 136.400
+ },
+ { name: "Barremian",
+ start: 130.000
+ },
+ { name: "Aptian",
+ start: 125.000
+ },
+ { name: "Albian",
+ start: 112.000
+ },
+ { name: "Cenomanian",
+ start: 99.600
+ },
+ { name: "Turonian",
+ start: 93.500
+ },
+ { name: "Coniacian",
+ start: 89.300
+ },
+ { name: "Santonian",
+ start: 85.800
+ },
+ { name: "Campanian",
+ start: 83.500
+ },
+ { name: "Maastrichtian",
+ start: 70.600
+ },
+ { name: "Danian",
+ start: 65.500
+ },
+ { name: "Selandian",
+ start: 61.700
+ },
+ { name: "Thanetian",
+ start: 58.700
+ },
+ { name: "Ypresian",
+ start: 55.800
+ },
+ { name: "Lutetian",
+ start: 48.600
+ },
+ { name: "Bartonian",
+ start: 40.400
+ },
+ { name: "Priabonian",
+ start: 37.200
+ },
+ { name: "Rupelian",
+ start: 33.900
+ },
+ { name: "Chattian",
+ start: 28.400
+ },
+ { name: "Aquitanian",
+ start: 23.030
+ },
+ { name: "Burdigalian",
+ start: 20.430
+ },
+ { name: "Langhian",
+ start: 15.970
+ },
+ { name: "Serravallian",
+ start: 13.650
+ },
+ { name: "Tortonian",
+ start: 11.608
+ },
+ { name: "Messinian",
+ start: 7.246
+ },
+ { name: "Zanclean",
+ start: 5.332
+ },
+ { name: "Piacenzian",
+ start: 3.600
+ },
+ { name: "Gelasian",
+ start: 2.588
+ }
+];
+
+Timeline.Geochrono.createBandInfo = function(params) {
+ var theme = ("theme" in params) ? params.theme : Timeline.getDefaultTheme();
+
+ var eventSource = ("eventSource" in params) ? params.eventSource : null;
+
+ var ether = new Timeline.LinearEther({
+ centersOn: ("date" in params) ? params.date : Timeline.GeochronoUnit.makeDefaultValue(),
+ interval: 1,
+ pixelsPerInterval: params.intervalPixels
+ });
+
+ var etherPainter = new Timeline.GeochronoEtherPainter({
+ intervalUnit: params.intervalUnit,
+ multiple: ("multiple" in params) ? params.multiple : 1,
+ align: params.align,
+ theme: theme
+ });
+
+ var eventPainterParams = {
+ theme: theme
+ };
+ if ("trackHeight" in params) {
+ eventPainterParams.trackHeight = params.trackHeight;
+ }
+ if ("trackGap" in params) {
+ eventPainterParams.trackGap = params.trackGap;
+ }
+ var eventPainter = ("overview" in params && params.overview) ?
+ new Timeline.OverviewEventPainter(eventPainterParams) :
+ new Timeline.DetailedEventPainter(eventPainterParams);
+
+ return {
+ width: params.width,
+ eventSource: eventSource,
+ timeZone: ("timeZone" in params) ? params.timeZone : 0,
+ ether: ether,
+ etherPainter: etherPainter,
+ eventPainter: eventPainter
+ };
+}; \ No newline at end of file
diff --git a/site/app/webroot/js/simile/timeline/ext/geochrono/scripts/l10n/en/labellers.js b/site/app/webroot/js/simile/timeline/ext/geochrono/scripts/l10n/en/labellers.js
new file mode 100755
index 0000000..7e66701
--- /dev/null
+++ b/site/app/webroot/js/simile/timeline/ext/geochrono/scripts/l10n/en/labellers.js
@@ -0,0 +1,10 @@
+/*==================================================
+ * Localization of Geochrono Labeller
+ *==================================================
+ */
+
+Timeline.GeochronoLabeller.eonNames["en"] = Timeline.Geochrono.eons;
+Timeline.GeochronoLabeller.eraNames["en"] = Timeline.Geochrono.eras;
+Timeline.GeochronoLabeller.periodNames["en"] = Timeline.Geochrono.periods;
+Timeline.GeochronoLabeller.epochNames["en"] = Timeline.Geochrono.epoches;
+Timeline.GeochronoLabeller.ageNames["en"] = Timeline.Geochrono.ages;
diff --git a/site/app/webroot/js/simile/timeline/ext/geochrono/scripts/labellers.js b/site/app/webroot/js/simile/timeline/ext/geochrono/scripts/labellers.js
new file mode 100755
index 0000000..3aabd15
--- /dev/null
+++ b/site/app/webroot/js/simile/timeline/ext/geochrono/scripts/labellers.js
@@ -0,0 +1,52 @@
+/*==================================================
+ * Geochrono Labeller
+ *==================================================
+ */
+
+Timeline.GeochronoLabeller = function(locale) {
+ this._locale = locale;
+};
+
+Timeline.GeochronoLabeller.eonNames = [];
+Timeline.GeochronoLabeller.eraNames = [];
+Timeline.GeochronoLabeller.periodNames = [];
+Timeline.GeochronoLabeller.epochNames = [];
+Timeline.GeochronoLabeller.ageNames = [];
+
+Timeline.GeochronoLabeller.prototype.labelInterval = function(date, intervalUnit) {
+ var n = Timeline.GeochronoUnit.toNumber(date);
+ var dates, names;
+ switch (intervalUnit) {
+ case Timeline.GeochronoUnit.AGE:
+ dates = Timeline.Geochrono.ages;
+ names = Timeline.GeochronoLabeller.ageNames; break;
+ case Timeline.GeochronoUnit.EPOCH:
+ dates = Timeline.Geochrono.epoches;
+ names = Timeline.GeochronoLabeller.epochNames; break;
+ case Timeline.GeochronoUnit.PERIOD:
+ dates = Timeline.Geochrono.periods;
+ names = Timeline.GeochronoLabeller.periodNames; break;
+ case Timeline.GeochronoUnit.ERA:
+ dates = Timeline.Geochrono.eras;
+ names = Timeline.GeochronoLabeller.eraNames; break;
+ case Timeline.GeochronoUnit.EON:
+ dates = Timeline.Geochrono.eons;
+ names = Timeline.GeochronoLabeller.eonNames; break;
+ default:
+ return { text: n, emphasized: false };
+ }
+
+ for (var i = dates.length - 1; i >= 0; i--) {
+ if (n <= dates[i].start) {
+ return {
+ text: names[this._locale][i].name,
+ emphasized: n == dates[i].start
+ }
+ }
+ }
+ return { text: n, emphasized: false };
+};
+
+Timeline.GeochronoLabeller.prototype.labelPrecise = function(date) {
+ return Timeline.GeochronoUnit.toNumber(date) + "ma";
+};
diff --git a/site/app/webroot/js/simile/timeline/ext/geochrono/scripts/units.js b/site/app/webroot/js/simile/timeline/ext/geochrono/scripts/units.js
new file mode 100755
index 0000000..86182ff
--- /dev/null
+++ b/site/app/webroot/js/simile/timeline/ext/geochrono/scripts/units.js
@@ -0,0 +1,86 @@
+/*==================================================
+ * Geochrono Unit
+ *==================================================
+ */
+
+Timeline.GeochronoUnit = new Object();
+
+Timeline.GeochronoUnit.MA = 0;
+Timeline.GeochronoUnit.AGE = 1;
+Timeline.GeochronoUnit.EPOCH = 2;
+Timeline.GeochronoUnit.PERIOD = 3;
+Timeline.GeochronoUnit.ERA = 4;
+Timeline.GeochronoUnit.EON = 5;
+
+Timeline.GeochronoUnit.getParser = function(format) {
+ return Timeline.GeochronoUnit.parseFromObject;
+};
+
+Timeline.GeochronoUnit.createLabeller = function(locale, timeZone) {
+ return new Timeline.GeochronoLabeller(locale);
+};
+
+Timeline.GeochronoUnit.wrapMA = function (n) {
+ return new Timeline.GeochronoUnit._MA(n);
+};
+
+Timeline.GeochronoUnit.makeDefaultValue = function () {
+ return Timeline.GeochronoUnit.wrapMA(0);
+};
+
+Timeline.GeochronoUnit.cloneValue = function (v) {
+ return new Timeline.GeochronoUnit._MA(v._n);
+};
+
+Timeline.GeochronoUnit.parseFromObject = function(o) {
+ if (o instanceof Timeline.GeochronoUnit._MA) {
+ return o;
+ } else if (typeof o == "number") {
+ return Timeline.GeochronoUnit.wrapMA(o);
+ } else if (typeof o == "string" && o.length > 0) {
+ return Timeline.GeochronoUnit.wrapMA(Number(o));
+ } else {
+ return null;
+ }
+};
+
+Timeline.GeochronoUnit.toNumber = function(v) {
+ return v._n;
+};
+
+Timeline.GeochronoUnit.fromNumber = function(n) {
+ return new Timeline.GeochronoUnit._MA(n);
+};
+
+Timeline.GeochronoUnit.compare = function(v1, v2) {
+ var n1, n2;
+ if (typeof v1 == "object") {
+ n1 = v1._n;
+ } else {
+ n1 = Number(v1);
+ }
+ if (typeof v2 == "object") {
+ n2 = v2._n;
+ } else {
+ n2 = Number(v2);
+ }
+
+ return n2 - n1;
+};
+
+Timeline.GeochronoUnit.earlier = function(v1, v2) {
+ return Timeline.GeochronoUnit.compare(v1, v2) < 0 ? v1 : v2;
+};
+
+Timeline.GeochronoUnit.later = function(v1, v2) {
+ return Timeline.GeochronoUnit.compare(v1, v2) > 0 ? v1 : v2;
+};
+
+Timeline.GeochronoUnit.change = function(v, n) {
+ return new Timeline.GeochronoUnit._MA(v._n - n);
+};
+
+Timeline.GeochronoUnit._MA = function(n) {
+ this._n = n;
+};
+
diff --git a/site/app/webroot/js/simile/timeline/ext/planning/planning-api.js b/site/app/webroot/js/simile/timeline/ext/planning/planning-api.js
new file mode 100755
index 0000000..9d92681
--- /dev/null
+++ b/site/app/webroot/js/simile/timeline/ext/planning/planning-api.js
@@ -0,0 +1,92 @@
+/*==================================================
+ * Planning Extension
+ *
+ * This file will load all the Javascript files
+ * necessary to make the extension work.
+ *
+ *==================================================
+ */
+
+(function() {
+ var javascriptFiles = [
+ "planning.js",
+ "units.js",
+ "ether-painters.js",
+ "labellers.js"
+ ];
+ var cssFiles = [
+ ];
+
+ var localizedJavascriptFiles = [
+ "labellers.js"
+ ];
+ var localizedCssFiles = [
+ ];
+
+ // ISO-639 language codes, ISO-3166 country codes (2 characters)
+ var supportedLocales = [
+ "en" // English
+ ];
+
+ try {
+ var includeJavascriptFile = function(filename) {
+ document.write("<script src='" + Timeline.urlPrefix + "ext/planning/scripts/" + filename + "' type='text/javascript'></script>");
+ };
+ var includeCssFile = function(filename) {
+ document.write("<link rel='stylesheet' href='" + Timeline.urlPrefix + "ext/planning/styles/" + filename + "' type='text/css'/>");
+ }
+
+ /*
+ * Include non-localized files
+ */
+ for (var i = 0; i < javascriptFiles.length; i++) {
+ includeJavascriptFile(javascriptFiles[i]);
+ }
+ for (var i = 0; i < cssFiles.length; i++) {
+ includeCssFile(cssFiles[i]);
+ }
+
+ /*
+ * Include localized files
+ */
+ var loadLocale = [];
+ var tryExactLocale = function(locale) {
+ for (var l = 0; l < supportedLocales.length; l++) {
+ if (locale == supportedLocales[l]) {
+ loadLocale[locale] = true;
+ return true;
+ }
+ }
+ return false;
+ }
+ var tryLocale = function(locale) {
+ if (tryExactLocale(locale)) {
+ return locale;
+ }
+
+ var dash = locale.indexOf("-");
+ if (dash > 0 && tryExactLocale(locale.substr(0, dash))) {
+ return locale.substr(0, dash);
+ }
+
+ return null;
+ }
+
+ tryLocale(Timeline.serverLocale);
+ tryLocale(Timeline.clientLocale);
+
+ for (var l = 0; l < supportedLocales.length; l++) {
+ var locale = supportedLocales[l];
+ if (loadLocale[locale]) {
+ for (var i = 0; i < localizedJavascriptFiles.length; i++) {
+ includeJavascriptFile("l10n/" + locale + "/" + localizedJavascriptFiles[i]);
+ }
+ for (var i = 0; i < localizedCssFiles.length; i++) {
+ includeCssFile("l10n/" + locale + "/" + localizedCssFiles[i]);
+ }
+ }
+ }
+ } catch (e) {
+ alert(e);
+ }
+})(); \ No newline at end of file
diff --git a/site/app/webroot/js/simile/timeline/ext/planning/scripts/ether-painters.js b/site/app/webroot/js/simile/timeline/ext/planning/scripts/ether-painters.js
new file mode 100755
index 0000000..75c2a62
--- /dev/null
+++ b/site/app/webroot/js/simile/timeline/ext/planning/scripts/ether-painters.js
@@ -0,0 +1,176 @@
+/*==================================================
+ * Planning Ether Painter
+ *==================================================
+ */
+
+Timeline.PlanningEtherPainter = function(params, band, timeline) {
+ this._params = params;
+ this._intervalUnit = params.intervalUnit;
+ this._multiple = ("multiple" in params) ? params.multiple : 1;
+ this._theme = params.theme;
+};
+
+Timeline.PlanningEtherPainter.prototype.initialize = function(band, timeline) {
+ this._band = band;
+ this._timeline = timeline;
+
+ this._backgroundLayer = band.createLayerDiv(0);
+ this._backgroundLayer.setAttribute("name", "ether-background"); // for debugging
+ this._backgroundLayer.style.background = this._theme.ether.backgroundColors[band.getIndex()];
+
+ this._markerLayer = null;
+ this._lineLayer = null;
+
+ var align = ("align" in this._params && typeof this._params.align == "string") ? this._params.align :
+ this._theme.ether.interval.marker[timeline.isHorizontal() ? "hAlign" : "vAlign"];
+ var showLine = ("showLine" in this._params) ? this._params.showLine :
+ this._theme.ether.interval.line.show;
+
+ this._intervalMarkerLayout = new Timeline.PlanningEtherMarkerLayout(
+ this._timeline, this._band, this._theme, align, showLine);
+
+ this._highlight = new Timeline.EtherHighlight(
+ this._timeline, this._band, this._theme, this._backgroundLayer);
+}
+
+Timeline.PlanningEtherPainter.prototype.setHighlight = function(startDate, endDate) {
+ this._highlight.position(startDate, endDate);
+}
+
+Timeline.PlanningEtherPainter.prototype.paint = function() {
+ if (this._markerLayer) {
+ this._band.removeLayerDiv(this._markerLayer);
+ }
+ this._markerLayer = this._band.createLayerDiv(100);
+ this._markerLayer.setAttribute("name", "ether-markers"); // for debugging
+ this._markerLayer.style.display = "none";
+
+ if (this._lineLayer) {
+ this._band.removeLayerDiv(this._lineLayer);
+ }
+ this._lineLayer = this._band.createLayerDiv(1);
+ this._lineLayer.setAttribute("name", "ether-lines"); // for debugging
+ this._lineLayer.style.display = "none";
+
+ var minDate = Math.max(0, Math.ceil(Timeline.PlanningUnit.toNumber(this._band.getMinDate())));
+ var maxDate = Math.floor(Timeline.PlanningUnit.toNumber(this._band.getMaxDate()));
+
+ var hasMore = function() {
+ return minDate < maxDate;
+ };
+ var change = 1;
+ var multiple = this._multiple;
+ switch (this._intervalUnit) {
+ case Timeline.PlanningUnit.DAY: change = 1; break;
+ case Timeline.PlanningUnit.WEEK: change = 7; break;
+ case Timeline.PlanningUnit.MONTH: change = 28; break;
+ case Timeline.PlanningUnit.QUARTER: change = 28 * 3; break;
+ case Timeline.PlanningUnit.YEAR: change = 28 * 12; break;
+ }
+ var increment = function() {
+ minDate += change * multiple;
+ };
+
+ var labeller = this._band.getLabeller();
+ while (true) {
+ this._intervalMarkerLayout.createIntervalMarker(
+ Timeline.PlanningUnit.fromNumber(minDate),
+ labeller,
+ this._intervalUnit,
+ this._markerLayer,
+ this._lineLayer
+ );
+ if (hasMore()) {
+ increment();
+ } else {
+ break;
+ }
+ }
+ this._markerLayer.style.display = "block";
+ this._lineLayer.style.display = "block";
+};
+
+Timeline.PlanningEtherPainter.prototype.softPaint = function() {
+};
+
+
+/*==================================================
+ * Planning Ether Marker Layout
+ *==================================================
+ */
+
+Timeline.PlanningEtherMarkerLayout = function(timeline, band, theme, align, showLine) {
+ var horizontal = timeline.isHorizontal();
+ if (horizontal) {
+ if (align == "Top") {
+ this.positionDiv = function(div, offset) {
+ div.style.left = offset + "px";
+ div.style.top = "0px";
+ };
+ } else {
+ this.positionDiv = function(div, offset) {
+ div.style.left = offset + "px";
+ div.style.bottom = "0px";
+ };
+ }
+ } else {
+ if (align == "Left") {
+ this.positionDiv = function(div, offset) {
+ div.style.top = offset + "px";
+ div.style.left = "0px";
+ };
+ } else {
+ this.positionDiv = function(div, offset) {
+ div.style.top = offset + "px";
+ div.style.right = "0px";
+ };
+ }
+ }
+
+ var markerTheme = theme.ether.interval.marker;
+ var lineTheme = theme.ether.interval.line;
+
+ var stylePrefix = (horizontal ? "h" : "v") + align;
+ var labelStyler = markerTheme[stylePrefix + "Styler"];
+ var emphasizedLabelStyler = markerTheme[stylePrefix + "EmphasizedStyler"];
+
+ this.createIntervalMarker = function(date, labeller, unit, markerDiv, lineDiv) {
+ var offset = Math.round(band.dateToPixelOffset(date));
+
+ if (showLine) {
+ var divLine = timeline.getDocument().createElement("div");
+ divLine.style.position = "absolute";
+
+ if (lineTheme.opacity < 100) {
+ Timeline.Graphics.setOpacity(divLine, lineTheme.opacity);
+ }
+
+ if (horizontal) {
+ divLine.style.borderLeft = "1px solid " + lineTheme.color;
+ divLine.style.left = offset + "px";
+ divLine.style.width = "1px";
+ divLine.style.top = "0px";
+ divLine.style.height = "100%";
+ } else {
+ divLine.style.borderTop = "1px solid " + lineTheme.color;
+ divLine.style.top = offset + "px";
+ divLine.style.height = "1px";
+ divLine.style.left = "0px";
+ divLine.style.width = "100%";
+ }
+ lineDiv.appendChild(divLine);
+ }
+
+ var label = labeller.labelInterval(date, unit);
+
+ var div = timeline.getDocument().createElement("div");
+ div.innerHTML = label.text;
+ div.style.position = "absolute";
+ (label.emphasized ? emphasizedLabelStyler : labelStyler)(div);
+
+ this.positionDiv(div, offset);
+ markerDiv.appendChild(div);
+
+ return div;
+ };
+}; \ No newline at end of file
diff --git a/site/app/webroot/js/simile/timeline/ext/planning/scripts/l10n/en/labellers.js b/site/app/webroot/js/simile/timeline/ext/planning/scripts/l10n/en/labellers.js
new file mode 100755
index 0000000..cdbac8c
--- /dev/null
+++ b/site/app/webroot/js/simile/timeline/ext/planning/scripts/l10n/en/labellers.js
@@ -0,0 +1,12 @@
+/*==================================================
+ * Localization of Planning Labeller
+ *==================================================
+ */
+
+Timeline.PlanningLabeller.labels["en"] = {
+ dayPrefix: "d",
+ weekPrefix: "w",
+ monthPrefix: "m",
+ quarterPrefix: "q",
+ yearPrefix: "y"
+}; \ No newline at end of file
diff --git a/site/app/webroot/js/simile/timeline/ext/planning/scripts/labellers.js b/site/app/webroot/js/simile/timeline/ext/planning/scripts/labellers.js
new file mode 100755
index 0000000..46e5a69
--- /dev/null
+++ b/site/app/webroot/js/simile/timeline/ext/planning/scripts/labellers.js
@@ -0,0 +1,33 @@
+/*==================================================
+ * Planning Labeller
+ *==================================================
+ */
+
+Timeline.PlanningLabeller = function(locale) {
+ this._locale = locale;
+};
+
+Timeline.PlanningLabeller.labels = [];
+
+Timeline.PlanningLabeller.prototype.labelInterval = function(date, intervalUnit) {
+ var n = Timeline.PlanningUnit.toNumber(date);
+
+ var prefix = "";
+ var divider = 1;
+ var divider2 = 7;
+ var labels = Timeline.PlanningLabeller.labels[this._locale];
+
+ switch (intervalUnit) {
+ case Timeline.PlanningUnit.DAY: prefix = labels.dayPrefix; break;
+ case Timeline.PlanningUnit.WEEK: prefix = labels.weekPrefix; divider = 7; divider2 = divider * 4; break;
+ case Timeline.PlanningUnit.MONTH: prefix = labels.monthPrefix; divider = 28; divider2 = divider * 3; break;
+ case Timeline.PlanningUnit.QUARTER: prefix = labels.quarterPrefix; divider = 28 * 3; divider2 = divider * 4; break;
+ case Timeline.PlanningUnit.YEAR: prefix = labels.yearPrefix; divider = 28 * 12; divider2 = divider * 5; break;
+ }
+ return { text: prefix + Math.floor(n / divider), emphasized: (n % divider2) == 0 };
+};
+
+Timeline.PlanningLabeller.prototype.labelPrecise = function(date) {
+ return Timeline.PlanningLabeller.labels[this._locale].dayPrefix +
+ Timeline.PlanningUnit.toNumber(date);
+};
diff --git a/site/app/webroot/js/simile/timeline/ext/planning/scripts/planning.js b/site/app/webroot/js/simile/timeline/ext/planning/scripts/planning.js
new file mode 100755
index 0000000..4201f92
--- /dev/null
+++ b/site/app/webroot/js/simile/timeline/ext/planning/scripts/planning.js
@@ -0,0 +1,47 @@
+/*==================================================
+ * Planning
+ *==================================================
+ */
+
+Timeline.Planning = new Object();
+
+Timeline.Planning.createBandInfo = function(params) {
+ var theme = ("theme" in params) ? params.theme : Timeline.getDefaultTheme();
+
+ var eventSource = ("eventSource" in params) ? params.eventSource : null;
+
+ var ether = new Timeline.LinearEther({
+ centersOn: ("date" in params) ? params.date : Timeline.PlanningUnit.makeDefaultValue(),
+ interval: 1,
+ pixelsPerInterval: params.intervalPixels
+ });
+
+ var etherPainter = new Timeline.PlanningEtherPainter({
+ intervalUnit: params.intervalUnit,
+ multiple: ("multiple" in params) ? params.multiple : 1,
+ align: params.align,
+ theme: theme
+ });
+
+ var eventPainterParams = {
+ theme: theme
+ };
+ if ("trackHeight" in params) {
+ eventPainterParams.trackHeight = params.trackHeight;
+ }
+ if ("trackGap" in params) {
+ eventPainterParams.trackGap = params.trackGap;
+ }
+ var eventPainter = ("overview" in params && params.overview) ?
+ new Timeline.OverviewEventPainter(eventPainterParams) :
+ new Timeline.DetailedEventPainter(eventPainterParams);
+
+ return {
+ width: params.width,
+ eventSource: eventSource,
+ timeZone: ("timeZone" in params) ? params.timeZone : 0,
+ ether: ether,
+ etherPainter: etherPainter,
+ eventPainter: eventPainter
+ };
+}; \ No newline at end of file
diff --git a/site/app/webroot/js/simile/timeline/ext/planning/scripts/units.js b/site/app/webroot/js/simile/timeline/ext/planning/scripts/units.js
new file mode 100755
index 0000000..13c31c1
--- /dev/null
+++ b/site/app/webroot/js/simile/timeline/ext/planning/scripts/units.js
@@ -0,0 +1,66 @@
+/*==================================================
+ * Planning Unit
+ *==================================================
+ */
+
+Timeline.PlanningUnit = new Object();
+
+Timeline.PlanningUnit.DAY = 0;
+Timeline.PlanningUnit.WEEK = 1;
+Timeline.PlanningUnit.MONTH = 2;
+Timeline.PlanningUnit.QUARTER = 3;
+Timeline.PlanningUnit.YEAR = 4;
+
+Timeline.PlanningUnit.getParser = function(format) {
+ return Timeline.PlanningUnit.parseFromObject;
+};
+
+Timeline.PlanningUnit.createLabeller = function(locale, timeZone) {
+ return new Timeline.PlanningLabeller(locale);
+};
+
+Timeline.PlanningUnit.makeDefaultValue = function () {
+ return 0;
+};
+
+Timeline.PlanningUnit.cloneValue = function (v) {
+ return v;
+};
+
+Timeline.PlanningUnit.parseFromObject = function(o) {
+ if (o == null) {
+ return null;
+ } else if (typeof o == "number") {
+ return o;
+ } else {
+ try {
+ return parseInt(o);
+ } catch (e) {
+ return null;
+ }
+ }
+};
+
+Timeline.PlanningUnit.toNumber = function(v) {
+ return v
+};
+
+Timeline.PlanningUnit.fromNumber = function(n) {
+ return n;
+};
+
+Timeline.PlanningUnit.compare = function(v1, v2) {
+ return v1 - v2;
+};
+
+Timeline.PlanningUnit.earlier = function(v1, v2) {
+ return Timeline.PlanningUnit.compare(v1, v2) < 0 ? v1 : v2;
+};
+
+Timeline.PlanningUnit.later = function(v1, v2) {
+ return Timeline.PlanningUnit.compare(v1, v2) > 0 ? v1 : v2;
+};
+
+Timeline.PlanningUnit.change = function(v, n) {
+ return v + n;
+};
diff --git a/site/app/webroot/js/simile/timeline/images/blue-circle.png b/site/app/webroot/js/simile/timeline/images/blue-circle.png
new file mode 100755
index 0000000..9ef045c
--- /dev/null
+++ b/site/app/webroot/js/simile/timeline/images/blue-circle.png
Binary files differ
diff --git a/site/app/webroot/js/simile/timeline/images/bubble-bottom-arrow.png b/site/app/webroot/js/simile/timeline/images/bubble-bottom-arrow.png
new file mode 100755
index 0000000..38c3917
--- /dev/null
+++ b/site/app/webroot/js/simile/timeline/images/bubble-bottom-arrow.png
Binary files differ
diff --git a/site/app/webroot/js/simile/timeline/images/bubble-bottom-left.png b/site/app/webroot/js/simile/timeline/images/bubble-bottom-left.png
new file mode 100755
index 0000000..6d32026
--- /dev/null
+++ b/site/app/webroot/js/simile/timeline/images/bubble-bottom-left.png
Binary files differ
diff --git a/site/app/webroot/js/simile/timeline/images/bubble-bottom-right.png b/site/app/webroot/js/simile/timeline/images/bubble-bottom-right.png
new file mode 100755
index 0000000..e5dc136
--- /dev/null
+++ b/site/app/webroot/js/simile/timeline/images/bubble-bottom-right.png
Binary files differ
diff --git a/site/app/webroot/js/simile/timeline/images/bubble-bottom.png b/site/app/webroot/js/simile/timeline/images/bubble-bottom.png
new file mode 100755
index 0000000..166b057
--- /dev/null
+++ b/site/app/webroot/js/simile/timeline/images/bubble-bottom.png
Binary files differ
diff --git a/site/app/webroot/js/simile/timeline/images/bubble-left-arrow.png b/site/app/webroot/js/simile/timeline/images/bubble-left-arrow.png
new file mode 100755
index 0000000..5b173cd
--- /dev/null
+++ b/site/app/webroot/js/simile/timeline/images/bubble-left-arrow.png
Binary files differ
diff --git a/site/app/webroot/js/simile/timeline/images/bubble-left.png b/site/app/webroot/js/simile/timeline/images/bubble-left.png
new file mode 100755
index 0000000..3826722
--- /dev/null
+++ b/site/app/webroot/js/simile/timeline/images/bubble-left.png
Binary files differ
diff --git a/site/app/webroot/js/simile/timeline/images/bubble-right-arrow.png b/site/app/webroot/js/simile/timeline/images/bubble-right-arrow.png
new file mode 100755
index 0000000..11e2873
--- /dev/null
+++ b/site/app/webroot/js/simile/timeline/images/bubble-right-arrow.png
Binary files differ
diff --git a/site/app/webroot/js/simile/timeline/images/bubble-right.png b/site/app/webroot/js/simile/timeline/images/bubble-right.png
new file mode 100755
index 0000000..f66f879
--- /dev/null
+++ b/site/app/webroot/js/simile/timeline/images/bubble-right.png
Binary files differ
diff --git a/site/app/webroot/js/simile/timeline/images/bubble-top-arrow.png b/site/app/webroot/js/simile/timeline/images/bubble-top-arrow.png
new file mode 100755
index 0000000..524c46e
--- /dev/null
+++ b/site/app/webroot/js/simile/timeline/images/bubble-top-arrow.png
Binary files differ
diff --git a/site/app/webroot/js/simile/timeline/images/bubble-top-left.png b/site/app/webroot/js/simile/timeline/images/bubble-top-left.png
new file mode 100755
index 0000000..d69841f
--- /dev/null
+++ b/site/app/webroot/js/simile/timeline/images/bubble-top-left.png
Binary files differ
diff --git a/site/app/webroot/js/simile/timeline/images/bubble-top-right.png b/site/app/webroot/js/simile/timeline/images/bubble-top-right.png
new file mode 100755
index 0000000..9ab219a
--- /dev/null
+++ b/site/app/webroot/js/simile/timeline/images/bubble-top-right.png
Binary files differ
diff --git a/site/app/webroot/js/simile/timeline/images/bubble-top.png b/site/app/webroot/js/simile/timeline/images/bubble-top.png
new file mode 100755
index 0000000..917defa
--- /dev/null
+++ b/site/app/webroot/js/simile/timeline/images/bubble-top.png
Binary files differ
diff --git a/site/app/webroot/js/simile/timeline/images/close-button.png b/site/app/webroot/js/simile/timeline/images/close-button.png
new file mode 100755
index 0000000..15f31b3
--- /dev/null
+++ b/site/app/webroot/js/simile/timeline/images/close-button.png
Binary files differ
diff --git a/site/app/webroot/js/simile/timeline/images/copyright-vertical.png b/site/app/webroot/js/simile/timeline/images/copyright-vertical.png
new file mode 100755
index 0000000..b15197b
--- /dev/null
+++ b/site/app/webroot/js/simile/timeline/images/copyright-vertical.png
Binary files differ
diff --git a/site/app/webroot/js/simile/timeline/images/copyright.png b/site/app/webroot/js/simile/timeline/images/copyright.png
new file mode 100755
index 0000000..bcf69c6
--- /dev/null
+++ b/site/app/webroot/js/simile/timeline/images/copyright.png
Binary files differ
diff --git a/site/app/webroot/js/simile/timeline/images/dark-blue-circle.png b/site/app/webroot/js/simile/timeline/images/dark-blue-circle.png
new file mode 100755
index 0000000..2747397
--- /dev/null
+++ b/site/app/webroot/js/simile/timeline/images/dark-blue-circle.png
Binary files differ
diff --git a/site/app/webroot/js/simile/timeline/images/dark-green-circle.png b/site/app/webroot/js/simile/timeline/images/dark-green-circle.png
new file mode 100755
index 0000000..903f9fd
--- /dev/null
+++ b/site/app/webroot/js/simile/timeline/images/dark-green-circle.png
Binary files differ
diff --git a/site/app/webroot/js/simile/timeline/images/dark-red-circle.png b/site/app/webroot/js/simile/timeline/images/dark-red-circle.png
new file mode 100755
index 0000000..5cbb085
--- /dev/null
+++ b/site/app/webroot/js/simile/timeline/images/dark-red-circle.png
Binary files differ
diff --git a/site/app/webroot/js/simile/timeline/images/dull-blue-circle.png b/site/app/webroot/js/simile/timeline/images/dull-blue-circle.png
new file mode 100755
index 0000000..19dd0da
--- /dev/null
+++ b/site/app/webroot/js/simile/timeline/images/dull-blue-circle.png
Binary files differ
diff --git a/site/app/webroot/js/simile/timeline/images/dull-green-circle.png b/site/app/webroot/js/simile/timeline/images/dull-green-circle.png
new file mode 100755
index 0000000..eecf665
--- /dev/null
+++ b/site/app/webroot/js/simile/timeline/images/dull-green-circle.png
Binary files differ
diff --git a/site/app/webroot/js/simile/timeline/images/dull-red-circle.png b/site/app/webroot/js/simile/timeline/images/dull-red-circle.png
new file mode 100755
index 0000000..2ff0111
--- /dev/null
+++ b/site/app/webroot/js/simile/timeline/images/dull-red-circle.png
Binary files differ
diff --git a/site/app/webroot/js/simile/timeline/images/gray-circle.png b/site/app/webroot/js/simile/timeline/images/gray-circle.png
new file mode 100755
index 0000000..39360d7
--- /dev/null
+++ b/site/app/webroot/js/simile/timeline/images/gray-circle.png
Binary files differ
diff --git a/site/app/webroot/js/simile/timeline/images/green-circle.png b/site/app/webroot/js/simile/timeline/images/green-circle.png
new file mode 100755
index 0000000..a5fc15c
--- /dev/null
+++ b/site/app/webroot/js/simile/timeline/images/green-circle.png
Binary files differ
diff --git a/site/app/webroot/js/simile/timeline/images/message-bottom-left.png b/site/app/webroot/js/simile/timeline/images/message-bottom-left.png
new file mode 100755
index 0000000..43a9d61
--- /dev/null
+++ b/site/app/webroot/js/simile/timeline/images/message-bottom-left.png
Binary files differ
diff --git a/site/app/webroot/js/simile/timeline/images/message-bottom-right.png b/site/app/webroot/js/simile/timeline/images/message-bottom-right.png
new file mode 100755
index 0000000..bfa4954
--- /dev/null
+++ b/site/app/webroot/js/simile/timeline/images/message-bottom-right.png
Binary files differ
diff --git a/site/app/webroot/js/simile/timeline/images/message-left.png b/site/app/webroot/js/simile/timeline/images/message-left.png
new file mode 100755
index 0000000..f354376
--- /dev/null
+++ b/site/app/webroot/js/simile/timeline/images/message-left.png
Binary files differ
diff --git a/site/app/webroot/js/simile/timeline/images/message-right.png b/site/app/webroot/js/simile/timeline/images/message-right.png
new file mode 100755
index 0000000..4702c28
--- /dev/null
+++ b/site/app/webroot/js/simile/timeline/images/message-right.png
Binary files differ
diff --git a/site/app/webroot/js/simile/timeline/images/message-top-left.png b/site/app/webroot/js/simile/timeline/images/message-top-left.png
new file mode 100755
index 0000000..b19b0ea
--- /dev/null
+++ b/site/app/webroot/js/simile/timeline/images/message-top-left.png
Binary files differ
diff --git a/site/app/webroot/js/simile/timeline/images/message-top-right.png b/site/app/webroot/js/simile/timeline/images/message-top-right.png
new file mode 100755
index 0000000..c092555
--- /dev/null
+++ b/site/app/webroot/js/simile/timeline/images/message-top-right.png
Binary files differ
diff --git a/site/app/webroot/js/simile/timeline/images/progress-running.gif b/site/app/webroot/js/simile/timeline/images/progress-running.gif
new file mode 100755
index 0000000..f7429eb
--- /dev/null
+++ b/site/app/webroot/js/simile/timeline/images/progress-running.gif
Binary files differ
diff --git a/site/app/webroot/js/simile/timeline/images/red-circle.png b/site/app/webroot/js/simile/timeline/images/red-circle.png
new file mode 100755
index 0000000..d56e734
--- /dev/null
+++ b/site/app/webroot/js/simile/timeline/images/red-circle.png
Binary files differ
diff --git a/site/app/webroot/js/simile/timeline/images/top-bubble.png b/site/app/webroot/js/simile/timeline/images/top-bubble.png
new file mode 100755
index 0000000..db6c93d
--- /dev/null
+++ b/site/app/webroot/js/simile/timeline/images/top-bubble.png
Binary files differ
diff --git a/site/app/webroot/js/simile/timeline/scripts/decorators.js b/site/app/webroot/js/simile/timeline/scripts/decorators.js
new file mode 100755
index 0000000..0fc038b
--- /dev/null
+++ b/site/app/webroot/js/simile/timeline/scripts/decorators.js
@@ -0,0 +1,186 @@
+/*==================================================
+ * Span Highlight Decorator
+ *==================================================
+ */
+
+Timeline.SpanHighlightDecorator = function(params) {
+ this._unit = ("unit" in params) ? params.unit : SimileAjax.NativeDateUnit;
+ this._startDate = (typeof params.startDate == "string") ?
+ this._unit.parseFromObject(params.startDate) : params.startDate;
+ this._endDate = (typeof params.endDate == "string") ?
+ this._unit.parseFromObject(params.endDate) : params.endDate;
+ this._startLabel = params.startLabel;
+ this._endLabel = params.endLabel;
+ this._color = params.color;
+ this._opacity = ("opacity" in params) ? params.opacity : 100;
+};
+
+Timeline.SpanHighlightDecorator.prototype.initialize = function(band, timeline) {
+ this._band = band;
+ this._timeline = timeline;
+
+ this._layerDiv = null;
+};
+
+Timeline.SpanHighlightDecorator.prototype.paint = function() {
+ if (this._layerDiv != null) {
+ this._band.removeLayerDiv(this._layerDiv);
+ }
+ this._layerDiv = this._band.createLayerDiv(10);
+ this._layerDiv.setAttribute("name", "span-highlight-decorator"); // for debugging
+ this._layerDiv.style.display = "none";
+
+ var minDate = this._band.getMinDate();
+ var maxDate = this._band.getMaxDate();
+
+ if (this._unit.compare(this._startDate, maxDate) < 0 &&
+ this._unit.compare(this._endDate, minDate) > 0) {
+
+ minDate = this._unit.later(minDate, this._startDate);
+ maxDate = this._unit.earlier(maxDate, this._endDate);
+
+ var minPixel = this._band.dateToPixelOffset(minDate);
+ var maxPixel = this._band.dateToPixelOffset(maxDate);
+
+ var doc = this._timeline.getDocument();
+
+ var createTable = function() {
+ var table = doc.createElement("table");
+ table.insertRow(0).insertCell(0);
+ return table;
+ };
+
+ var div = doc.createElement("div");
+ div.style.position = "absolute";
+ div.style.overflow = "hidden";
+ div.style.background = this._color;
+ if (this._opacity < 100) {
+ SimileAjax.Graphics.setOpacity(div, this._opacity);
+ }
+ this._layerDiv.appendChild(div);
+
+ var tableStartLabel = createTable();
+ tableStartLabel.style.position = "absolute";
+ tableStartLabel.style.overflow = "hidden";
+ tableStartLabel.style.fontSize = "200%";
+ tableStartLabel.style.fontWeight = "bold";
+ tableStartLabel.style.color = this._color;
+ tableStartLabel.rows[0].cells[0].innerHTML = this._startLabel;
+ this._layerDiv.appendChild(tableStartLabel);
+
+ var tableEndLabel = createTable();
+ tableEndLabel.style.position = "absolute";
+ tableEndLabel.style.overflow = "hidden";
+ tableEndLabel.style.fontSize = "200%";
+ tableEndLabel.style.fontWeight = "bold";
+ tableEndLabel.style.color = this._color;
+ tableEndLabel.rows[0].cells[0].innerHTML = this._endLabel;
+ this._layerDiv.appendChild(tableEndLabel);
+
+ if (this._timeline.isHorizontal()) {
+ div.style.left = minPixel + "px";
+ div.style.width = (maxPixel - minPixel) + "px";
+ div.style.top = "0px";
+ div.style.height = "100%";
+
+ tableStartLabel.style.right = (this._band.getTotalViewLength() - minPixel) + "px";
+ tableStartLabel.style.width = (this._startLabel.length) + "em";
+ tableStartLabel.style.top = "0px";
+ tableStartLabel.style.height = "100%";
+ tableStartLabel.style.textAlign = "right";
+ tableStartLabel.rows[0].style.verticalAlign = "top";
+
+ tableEndLabel.style.left = maxPixel + "px";
+ tableEndLabel.style.width = (this._endLabel.length) + "em";
+ tableEndLabel.style.top = "0px";
+ tableEndLabel.style.height = "100%";
+ tableEndLabel.rows[0].style.verticalAlign = "top";
+ } else {
+ div.style.top = minPixel + "px";
+ div.style.height = (maxPixel - minPixel) + "px";
+ div.style.left = "0px";
+ div.style.width = "100%";
+
+ tableStartLabel.style.bottom = minPixel + "px";
+ tableStartLabel.style.height = "1.5px";
+ tableStartLabel.style.left = "0px";
+ tableStartLabel.style.width = "100%";
+
+ tableEndLabel.style.top = maxPixel + "px";
+ tableEndLabel.style.height = "1.5px";
+ tableEndLabel.style.left = "0px";
+ tableEndLabel.style.width = "100%";
+ }
+ }
+ this._layerDiv.style.display = "block";
+};
+
+Timeline.SpanHighlightDecorator.prototype.softPaint = function() {
+};
+
+/*==================================================
+ * Point Highlight Decorator
+ *==================================================
+ */
+
+Timeline.PointHighlightDecorator = function(params) {
+ this._unit = ("unit" in params) ? params.unit : SimileAjax.NativeDateUnit;
+ this._date = (typeof params.date == "string") ?
+ this._unit.parseFromObject(params.date) : params.date;
+ this._width = ("width" in params) ? params.width : 10;
+ this._color = params.color;
+ this._opacity = ("opacity" in params) ? params.opacity : 100;
+};
+
+Timeline.PointHighlightDecorator.prototype.initialize = function(band, timeline) {
+ this._band = band;
+ this._timeline = timeline;
+
+ this._layerDiv = null;
+};
+
+Timeline.PointHighlightDecorator.prototype.paint = function() {
+ if (this._layerDiv != null) {
+ this._band.removeLayerDiv(this._layerDiv);
+ }
+ this._layerDiv = this._band.createLayerDiv(10);
+ this._layerDiv.setAttribute("name", "span-highlight-decorator"); // for debugging
+ this._layerDiv.style.display = "none";
+
+ var minDate = this._band.getMinDate();
+ var maxDate = this._band.getMaxDate();
+
+ if (this._unit.compare(this._date, maxDate) < 0 &&
+ this._unit.compare(this._date, minDate) > 0) {
+
+ var pixel = this._band.dateToPixelOffset(this._date);
+ var minPixel = pixel - Math.round(this._width / 2);
+
+ var doc = this._timeline.getDocument();
+
+ var div = doc.createElement("div");
+ div.style.position = "absolute";
+ div.style.overflow = "hidden";
+ div.style.background = this._color;
+ if (this._opacity < 100) {
+ SimileAjax.Graphics.setOpacity(div, this._opacity);
+ }
+ this._layerDiv.appendChild(div);
+
+ if (this._timeline.isHorizontal()) {
+ div.style.left = minPixel + "px";
+ div.style.width = this._width + "px";
+ div.style.top = "0px";
+ div.style.height = "100%";
+ } else {
+ div.style.top = minPixel + "px";
+ div.style.height = this._width + "px";
+ div.style.left = "0px";
+ div.style.width = "100%";
+ }
+ }
+ this._layerDiv.style.display = "block";
+};
+
+Timeline.PointHighlightDecorator.prototype.softPaint = function() {
+};
diff --git a/site/app/webroot/js/simile/timeline/scripts/detailed-painter.js b/site/app/webroot/js/simile/timeline/scripts/detailed-painter.js
new file mode 100755
index 0000000..8ec14a8
--- /dev/null
+++ b/site/app/webroot/js/simile/timeline/scripts/detailed-painter.js
@@ -0,0 +1,667 @@
+/*==================================================
+ * Detailed Event Painter
+ *==================================================
+ */
+
+Timeline.DetailedEventPainter = function(params) {
+ this._params = params;
+ this._onSelectListeners = [];
+
+ this._filterMatcher = null;
+ this._highlightMatcher = null;
+ this._frc = null;
+
+ this._eventIdToElmt = {};
+};
+
+Timeline.DetailedEventPainter.prototype.initialize = function(band, timeline) {
+ this._band = band;
+ this._timeline = timeline;
+
+ this._backLayer = null;
+ this._eventLayer = null;
+ this._lineLayer = null;
+ this._highlightLayer = null;
+
+ this._eventIdToElmt = null;
+};
+
+Timeline.DetailedEventPainter.prototype.addOnSelectListener = function(listener) {
+ this._onSelectListeners.push(listener);
+};
+
+Timeline.DetailedEventPainter.prototype.removeOnSelectListener = function(listener) {
+ for (var i = 0; i < this._onSelectListeners.length; i++) {
+ if (this._onSelectListeners[i] == listener) {
+ this._onSelectListeners.splice(i, 1);
+ break;
+ }
+ }
+};
+
+Timeline.DetailedEventPainter.prototype.getFilterMatcher = function() {
+ return this._filterMatcher;
+};
+
+Timeline.DetailedEventPainter.prototype.setFilterMatcher = function(filterMatcher) {
+ this._filterMatcher = filterMatcher;
+};
+
+Timeline.DetailedEventPainter.prototype.getHighlightMatcher = function() {
+ return this._highlightMatcher;
+};
+
+Timeline.DetailedEventPainter.prototype.setHighlightMatcher = function(highlightMatcher) {
+ this._highlightMatcher = highlightMatcher;
+};
+
+Timeline.DetailedEventPainter.prototype.paint = function() {
+ var eventSource = this._band.getEventSource();
+ if (eventSource == null) {
+ return;
+ }
+
+ this._eventIdToElmt = {};
+ this._prepareForPainting();
+
+ var eventTheme = this._params.theme.event;
+ var trackHeight = Math.max(eventTheme.track.height, this._frc.getLineHeight());
+ var metrics = {
+ trackOffset: Math.round(this._band.getViewWidth() / 2 - trackHeight / 2),
+ trackHeight: trackHeight,
+ trackGap: eventTheme.track.gap,
+ trackIncrement: trackHeight + eventTheme.track.gap,
+ icon: eventTheme.instant.icon,
+ iconWidth: eventTheme.instant.iconWidth,
+ iconHeight: eventTheme.instant.iconHeight,
+ labelWidth: eventTheme.label.width
+ }
+
+ var minDate = this._band.getMinDate();
+ var maxDate = this._band.getMaxDate();
+
+ var filterMatcher = (this._filterMatcher != null) ?
+ this._filterMatcher :
+ function(evt) { return true; };
+ var highlightMatcher = (this._highlightMatcher != null) ?
+ this._highlightMatcher :
+ function(evt) { return -1; };
+
+ var iterator = eventSource.getEventReverseIterator(minDate, maxDate);
+ while (iterator.hasNext()) {
+ var evt = iterator.next();
+ if (filterMatcher(evt)) {
+ this.paintEvent(evt, metrics, this._params.theme, highlightMatcher(evt));
+ }
+ }
+
+ this._highlightLayer.style.display = "block";
+ this._lineLayer.style.display = "block";
+ this._eventLayer.style.display = "block";
+};
+
+Timeline.DetailedEventPainter.prototype.softPaint = function() {
+};
+
+Timeline.DetailedEventPainter.prototype._prepareForPainting = function() {
+ var band = this._band;
+
+ if (this._backLayer == null) {
+ this._backLayer = this._band.createLayerDiv(0, "timeline-band-events");
+ this._backLayer.style.visibility = "hidden";
+
+ var eventLabelPrototype = document.createElement("span");
+ eventLabelPrototype.className = "timeline-event-label";
+ this._backLayer.appendChild(eventLabelPrototype);
+ this._frc = SimileAjax.Graphics.getFontRenderingContext(eventLabelPrototype);
+ }
+ this._frc.update();
+ this._lowerTracks = [];
+ this._upperTracks = [];
+
+ if (this._highlightLayer != null) {
+ band.removeLayerDiv(this._highlightLayer);
+ }
+ this._highlightLayer = band.createLayerDiv(105, "timeline-band-highlights");
+ this._highlightLayer.style.display = "none";
+
+ if (this._lineLayer != null) {
+ band.removeLayerDiv(this._lineLayer);
+ }
+ this._lineLayer = band.createLayerDiv(110, "timeline-band-lines");
+ this._lineLayer.style.display = "none";
+
+ if (this._eventLayer != null) {
+ band.removeLayerDiv(this._eventLayer);
+ }
+ this._eventLayer = band.createLayerDiv(110, "timeline-band-events");
+ this._eventLayer.style.display = "none";
+};
+
+Timeline.DetailedEventPainter.prototype.paintEvent = function(evt, metrics, theme, highlightIndex) {
+ if (evt.isInstant()) {
+ this.paintInstantEvent(evt, metrics, theme, highlightIndex);
+ } else {
+ this.paintDurationEvent(evt, metrics, theme, highlightIndex);
+ }
+};
+
+Timeline.DetailedEventPainter.prototype.paintInstantEvent = function(evt, metrics, theme, highlightIndex) {
+ if (evt.isImprecise()) {
+ this.paintImpreciseInstantEvent(evt, metrics, theme, highlightIndex);
+ } else {
+ this.paintPreciseInstantEvent(evt, metrics, theme, highlightIndex);
+ }
+}
+
+Timeline.DetailedEventPainter.prototype.paintDurationEvent = function(evt, metrics, theme, highlightIndex) {
+ if (evt.isImprecise()) {
+ this.paintImpreciseDurationEvent(evt, metrics, theme, highlightIndex);
+ } else {
+ this.paintPreciseDurationEvent(evt, metrics, theme, highlightIndex);
+ }
+}
+
+Timeline.DetailedEventPainter.prototype.paintPreciseInstantEvent = function(evt, metrics, theme, highlightIndex) {
+ var doc = this._timeline.getDocument();
+ var text = evt.getText();
+
+ var startDate = evt.getStart();
+ var startPixel = Math.round(this._band.dateToPixelOffset(startDate));
+ var iconRightEdge = Math.round(startPixel + metrics.iconWidth / 2);
+ var iconLeftEdge = Math.round(startPixel - metrics.iconWidth / 2);
+
+ var labelSize = this._frc.computeSize(text);
+ var iconTrack = this._findFreeTrackForSolid(iconRightEdge, startPixel);
+ var iconElmtData = this._paintEventIcon(evt, iconTrack, iconLeftEdge, metrics, theme);
+
+ var labelLeft = iconRightEdge + theme.event.label.offsetFromLine;
+ var labelTrack = iconTrack;
+
+ var iconTrackData = this._getTrackData(iconTrack);
+ if (Math.min(iconTrackData.solid, iconTrackData.text) >= labelLeft + labelSize.width) { // label on the same track, to the right of icon
+ iconTrackData.solid = iconLeftEdge;
+ iconTrackData.text = labelLeft;
+ } else { // label on a different track, below icon
+ iconTrackData.solid = iconLeftEdge;
+
+ labelLeft = startPixel + theme.event.label.offsetFromLine;
+ labelTrack = this._findFreeTrackForText(iconTrack, labelLeft + labelSize.width, function(t) { t.line = startPixel - 2; });
+ this._getTrackData(labelTrack).text = iconLeftEdge;
+
+ this._paintEventLine(evt, startPixel, iconTrack, labelTrack, metrics, theme);
+ }
+
+ var labelTop = Math.round(
+ metrics.trackOffset + labelTrack * metrics.trackIncrement +
+ metrics.trackHeight / 2 - labelSize.height / 2);
+
+ var labelElmtData = this._paintEventLabel(evt, text, labelLeft, labelTop, labelSize.width, labelSize.height, theme);
+
+ var self = this;
+ var clickHandler = function(elmt, domEvt, target) {
+ return self._onClickInstantEvent(iconElmtData.elmt, domEvt, evt);
+ };
+ SimileAjax.DOM.registerEvent(iconElmtData.elmt, "mousedown", clickHandler);
+ SimileAjax.DOM.registerEvent(labelElmtData.elmt, "mousedown", clickHandler);
+
+ this._createHighlightDiv(highlightIndex, iconElmtData, theme);
+
+ this._eventIdToElmt[evt.getID()] = iconElmtData.elmt;
+};
+
+Timeline.DetailedEventPainter.prototype.paintImpreciseInstantEvent = function(evt, metrics, theme, highlightIndex) {
+ var doc = this._timeline.getDocument();
+ var text = evt.getText();
+
+ var startDate = evt.getStart();
+ var endDate = evt.getEnd();
+ var startPixel = Math.round(this._band.dateToPixelOffset(startDate));
+ var endPixel = Math.round(this._band.dateToPixelOffset(endDate));
+
+ var iconRightEdge = Math.round(startPixel + metrics.iconWidth / 2);
+ var iconLeftEdge = Math.round(startPixel - metrics.iconWidth / 2);
+
+ var labelSize = this._frc.computeSize(text);
+ var iconTrack = this._findFreeTrackForSolid(endPixel, startPixel);
+
+ var tapeElmtData = this._paintEventTape(evt, iconTrack, startPixel, endPixel,
+ theme.event.instant.impreciseColor, theme.event.instant.impreciseOpacity, metrics, theme);
+ var iconElmtData = this._paintEventIcon(evt, iconTrack, iconLeftEdge, metrics, theme);
+
+ var iconTrackData = this._getTrackData(iconTrack);
+ iconTrackData.solid = iconLeftEdge;
+
+ var labelLeft = iconRightEdge + theme.event.label.offsetFromLine;
+ var labelRight = labelLeft + labelSize.width;
+ var labelTrack;
+ if (labelRight < endPixel) {
+ labelTrack = iconTrack;
+ } else {
+ labelLeft = startPixel + theme.event.label.offsetFromLine;
+ labelRight = labelLeft + labelSize.width;
+
+ labelTrack = this._findFreeTrackForText(iconTrack, labelRight, function(t) { t.line = startPixel - 2; });
+ this._getTrackData(labelTrack).text = iconLeftEdge;
+
+ this._paintEventLine(evt, startPixel, iconTrack, labelTrack, metrics, theme);
+ }
+ var labelTop = Math.round(
+ metrics.trackOffset + labelTrack * metrics.trackIncrement +
+ metrics.trackHeight / 2 - labelSize.height / 2);
+
+ var labelElmtData = this._paintEventLabel(evt, text, labelLeft, labelTop, labelSize.width, labelSize.height, theme);
+
+ var self = this;
+ var clickHandler = function(elmt, domEvt, target) {
+ return self._onClickInstantEvent(iconElmtData.elmt, domEvt, evt);
+ };
+ SimileAjax.DOM.registerEvent(iconElmtData.elmt, "mousedown", clickHandler);
+ SimileAjax.DOM.registerEvent(tapeElmtData.elmt, "mousedown", clickHandler);
+ SimileAjax.DOM.registerEvent(labelElmtData.elmt, "mousedown", clickHandler);
+
+ this._createHighlightDiv(highlightIndex, iconElmtData, theme);
+
+ this._eventIdToElmt[evt.getID()] = iconElmtData.elmt;
+};
+
+Timeline.DetailedEventPainter.prototype.paintPreciseDurationEvent = function(evt, metrics, theme, highlightIndex) {
+ var doc = this._timeline.getDocument();
+ var text = evt.getText();
+
+ var startDate = evt.getStart();
+ var endDate = evt.getEnd();
+ var startPixel = Math.round(this._band.dateToPixelOffset(startDate));
+ var endPixel = Math.round(this._band.dateToPixelOffset(endDate));
+
+ var labelSize = this._frc.computeSize(text);
+ var tapeTrack = this._findFreeTrackForSolid(endPixel);
+ var color = evt.getColor();
+ color = color != null ? color : theme.event.duration.color;
+
+ var tapeElmtData = this._paintEventTape(evt, tapeTrack, startPixel, endPixel, color, 100, metrics, theme);
+
+ var tapeTrackData = this._getTrackData(tapeTrack);
+ tapeTrackData.solid = startPixel;
+
+ var labelLeft = startPixel + theme.event.label.offsetFromLine;
+ var labelTrack = this._findFreeTrackForText(tapeTrack, labelLeft + labelSize.width, function(t) { t.line = startPixel - 2; });
+ this._getTrackData(labelTrack).text = startPixel - 2;
+
+ this._paintEventLine(evt, startPixel, tapeTrack, labelTrack, metrics, theme);
+
+ var labelTop = Math.round(
+ metrics.trackOffset + labelTrack * metrics.trackIncrement +
+ metrics.trackHeight / 2 - labelSize.height / 2);
+
+ var labelElmtData = this._paintEventLabel(evt, text, labelLeft, labelTop, labelSize.width, labelSize.height, theme);
+
+ var self = this;
+ var clickHandler = function(elmt, domEvt, target) {
+ return self._onClickDurationEvent(tapeElmtData.elmt, domEvt, evt);
+ };
+ SimileAjax.DOM.registerEvent(tapeElmtData.elmt, "mousedown", clickHandler);
+ SimileAjax.DOM.registerEvent(labelElmtData.elmt, "mousedown", clickHandler);
+
+ this._createHighlightDiv(highlightIndex, tapeElmtData, theme);
+
+ this._eventIdToElmt[evt.getID()] = tapeElmtData.elmt;
+};
+
+Timeline.DetailedEventPainter.prototype.paintImpreciseDurationEvent = function(evt, metrics, theme, highlightIndex) {
+ var doc = this._timeline.getDocument();
+ var text = evt.getText();
+
+ var startDate = evt.getStart();
+ var latestStartDate = evt.getLatestStart();
+ var endDate = evt.getEnd();
+ var earliestEndDate = evt.getEarliestEnd();
+
+ var startPixel = Math.round(this._band.dateToPixelOffset(startDate));
+ var latestStartPixel = Math.round(this._band.dateToPixelOffset(latestStartDate));
+ var endPixel = Math.round(this._band.dateToPixelOffset(endDate));
+ var earliestEndPixel = Math.round(this._band.dateToPixelOffset(earliestEndDate));
+
+ var labelSize = this._frc.computeSize(text);
+ var tapeTrack = this._findFreeTrackForSolid(endPixel);
+ var color = evt.getColor();
+ color = color != null ? color : theme.event.duration.color;
+
+ var impreciseTapeElmtData = this._paintEventTape(evt, tapeTrack, startPixel, endPixel,
+ theme.event.duration.impreciseColor, theme.event.duration.impreciseOpacity, metrics, theme);
+ var tapeElmtData = this._paintEventTape(evt, tapeTrack, latestStartPixel, earliestEndPixel, color, 100, metrics, theme);
+
+ var tapeTrackData = this._getTrackData(tapeTrack);
+ tapeTrackData.solid = startPixel;
+
+ var labelLeft = latestStartPixel + theme.event.label.offsetFromLine;
+ var labelTrack = this._findFreeTrackForText(tapeTrack, labelLeft + labelSize.width, function(t) { t.line = latestStartPixel - 2; });
+ this._getTrackData(labelTrack).text = latestStartPixel - 2;
+
+ this._paintEventLine(evt, latestStartPixel, tapeTrack, labelTrack, metrics, theme);
+
+ var labelTop = Math.round(
+ metrics.trackOffset + labelTrack * metrics.trackIncrement +
+ metrics.trackHeight / 2 - labelSize.height / 2);
+
+ var labelElmtData = this._paintEventLabel(evt, text, labelLeft, labelTop, labelSize.width, labelSize.height, theme);
+
+ var self = this;
+ var clickHandler = function(elmt, domEvt, target) {
+ return self._onClickDurationEvent(tapeElmtData.elmt, domEvt, evt);
+ };
+ SimileAjax.DOM.registerEvent(tapeElmtData.elmt, "mousedown", clickHandler);
+ SimileAjax.DOM.registerEvent(labelElmtData.elmt, "mousedown", clickHandler);
+
+ this._createHighlightDiv(highlightIndex, tapeElmtData, theme);
+
+ this._eventIdToElmt[evt.getID()] = tapeElmtData.elmt;
+};
+
+Timeline.DetailedEventPainter.prototype._findFreeTrackForSolid = function(solidEdge, softEdge) {
+ for (var i = 0; true; i++) {
+ if (i < this._lowerTracks.length) {
+ var t = this._lowerTracks[i];
+ if (Math.min(t.solid, t.text) > solidEdge && (!(softEdge) || t.line > softEdge)) {
+ return i;
+ }
+ } else {
+ this._lowerTracks.push({
+ solid: Number.POSITIVE_INFINITY,
+ text: Number.POSITIVE_INFINITY,
+ line: Number.POSITIVE_INFINITY
+ });
+
+ return i;
+ }
+
+ if (i < this._upperTracks.length) {
+ var t = this._upperTracks[i];
+ if (Math.min(t.solid, t.text) > solidEdge && (!(softEdge) || t.line > softEdge)) {
+ return -1 - i;
+ }
+ } else {
+ this._upperTracks.push({
+ solid: Number.POSITIVE_INFINITY,
+ text: Number.POSITIVE_INFINITY,
+ line: Number.POSITIVE_INFINITY
+ });
+
+ return -1 - i;
+ }
+ }
+};
+
+Timeline.DetailedEventPainter.prototype._findFreeTrackForText = function(fromTrack, edge, occupiedTrackVisitor) {
+ var extendUp;
+ var index;
+ var firstIndex;
+ var result;
+
+ if (fromTrack < 0) {
+ extendUp = true;
+ firstIndex = -fromTrack;
+
+ index = this._findFreeUpperTrackForText(firstIndex, edge);
+ result = -1 - index;
+ } else if (fromTrack > 0) {
+ extendUp = false;
+ firstIndex = fromTrack + 1;
+
+ index = this._findFreeLowerTrackForText(firstIndex, edge);
+ result = index;
+ } else {
+ var upIndex = this._findFreeUpperTrackForText(0, edge);
+ var downIndex = this._findFreeLowerTrackForText(1, edge);
+
+ if (downIndex - 1 <= upIndex) {
+ extendUp = false;
+ firstIndex = 1;
+ index = downIndex;
+ result = index;
+ } else {
+ extendUp = true;
+ firstIndex = 0;
+ index = upIndex;
+ result = -1 - index;
+ }
+ }
+
+ if (extendUp) {
+ if (index == this._upperTracks.length) {
+ this._upperTracks.push({
+ solid: Number.POSITIVE_INFINITY,
+ text: Number.POSITIVE_INFINITY,
+ line: Number.POSITIVE_INFINITY
+ });
+ }
+ for (var i = firstIndex; i < index; i++) {
+ occupiedTrackVisitor(this._upperTracks[i]);
+ }
+ } else {
+ if (index == this._lowerTracks.length) {
+ this._lowerTracks.push({
+ solid: Number.POSITIVE_INFINITY,
+ text: Number.POSITIVE_INFINITY,
+ line: Number.POSITIVE_INFINITY
+ });
+ }
+ for (var i = firstIndex; i < index; i++) {
+ occupiedTrackVisitor(this._lowerTracks[i]);
+ }
+ }
+ return result;
+};
+
+Timeline.DetailedEventPainter.prototype._findFreeLowerTrackForText = function(index, edge) {
+ for (; index < this._lowerTracks.length; index++) {
+ var t = this._lowerTracks[index];
+ if (Math.min(t.solid, t.text) >= edge) {
+ break;
+ }
+ }
+ return index;
+};
+
+Timeline.DetailedEventPainter.prototype._findFreeUpperTrackForText = function(index, edge) {
+ for (; index < this._upperTracks.length; index++) {
+ var t = this._upperTracks[index];
+ if (Math.min(t.solid, t.text) >= edge) {
+ break;
+ }
+ }
+ return index;
+};
+
+Timeline.DetailedEventPainter.prototype._getTrackData = function(index) {
+ return (index < 0) ? this._upperTracks[-index - 1] : this._lowerTracks[index];
+};
+
+Timeline.DetailedEventPainter.prototype._paintEventLine = function(evt, left, startTrack, endTrack, metrics, theme) {
+ var top = Math.round(metrics.trackOffset + startTrack * metrics.trackIncrement + metrics.trackHeight / 2);
+ var height = Math.round(Math.abs(endTrack - startTrack) * metrics.trackIncrement);
+
+ var lineStyle = "1px solid " + theme.event.label.lineColor;
+ var lineDiv = this._timeline.getDocument().createElement("div");
+ lineDiv.style.position = "absolute";
+ lineDiv.style.left = left + "px";
+ lineDiv.style.width = theme.event.label.offsetFromLine + "px";
+ lineDiv.style.height = height + "px";
+ if (startTrack > endTrack) {
+ lineDiv.style.top = (top - height) + "px";
+ lineDiv.style.borderTop = lineStyle;
+ } else {
+ lineDiv.style.top = top + "px";
+ lineDiv.style.borderBottom = lineStyle;
+ }
+ lineDiv.style.borderLeft = lineStyle;
+ this._lineLayer.appendChild(lineDiv);
+};
+
+Timeline.DetailedEventPainter.prototype._paintEventIcon = function(evt, iconTrack, left, metrics, theme) {
+ var icon = evt.getIcon();
+ icon = icon != null ? icon : metrics.icon;
+
+ var middle = metrics.trackOffset + iconTrack * metrics.trackIncrement + metrics.trackHeight / 2;
+ var top = Math.round(middle - metrics.iconHeight / 2);
+
+ var img = SimileAjax.Graphics.createTranslucentImage(icon);
+ var iconDiv = this._timeline.getDocument().createElement("div");
+ iconDiv.style.position = "absolute";
+ iconDiv.style.left = left + "px";
+ iconDiv.style.top = top + "px";
+ iconDiv.appendChild(img);
+ iconDiv.style.cursor = "pointer";
+ this._eventLayer.appendChild(iconDiv);
+
+ return {
+ left: left,
+ top: top,
+ width: metrics.iconWidth,
+ height: metrics.iconHeight,
+ elmt: iconDiv
+ };
+};
+
+Timeline.DetailedEventPainter.prototype._paintEventLabel = function(evt, text, left, top, width, height, theme) {
+ var doc = this._timeline.getDocument();
+
+ var labelBackgroundDiv = doc.createElement("div");
+ labelBackgroundDiv.style.position = "absolute";
+ labelBackgroundDiv.style.left = left + "px";
+ labelBackgroundDiv.style.width = width + "px";
+ labelBackgroundDiv.style.top = top + "px";
+ labelBackgroundDiv.style.height = height + "px";
+ labelBackgroundDiv.style.backgroundColor = theme.event.label.backgroundColor;
+ SimileAjax.Graphics.setOpacity(labelBackgroundDiv, theme.event.label.backgroundOpacity);
+ this._eventLayer.appendChild(labelBackgroundDiv);
+
+ var labelDiv = doc.createElement("div");
+ labelDiv.style.position = "absolute";
+ labelDiv.style.left = left + "px";
+ labelDiv.style.width = width + "px";
+ labelDiv.style.top = top + "px";
+ labelDiv.innerHTML = text;
+ labelDiv.style.cursor = "pointer";
+
+ var color = evt.getTextColor();
+ if (color == null) {
+ color = evt.getColor();
+ }
+ if (color != null) {
+ labelDiv.style.color = color;
+ }
+
+ this._eventLayer.appendChild(labelDiv);
+
+ return {
+ left: left,
+ top: top,
+ width: width,
+ height: height,
+ elmt: labelDiv
+ };
+};
+
+Timeline.DetailedEventPainter.prototype._paintEventTape = function(
+ evt, iconTrack, startPixel, endPixel, color, opacity, metrics, theme) {
+
+ var tapeWidth = endPixel - startPixel;
+ var tapeHeight = theme.event.tape.height;
+ var middle = metrics.trackOffset + iconTrack * metrics.trackIncrement + metrics.trackHeight / 2;
+ var top = Math.round(middle - tapeHeight / 2);
+
+ var tapeDiv = this._timeline.getDocument().createElement("div");
+ tapeDiv.style.position = "absolute";
+ tapeDiv.style.left = startPixel + "px";
+ tapeDiv.style.width = tapeWidth + "px";
+ tapeDiv.style.top = top + "px";
+ tapeDiv.style.height = tapeHeight + "px";
+ tapeDiv.style.backgroundColor = color;
+ tapeDiv.style.overflow = "hidden";
+ tapeDiv.style.cursor = "pointer";
+ SimileAjax.Graphics.setOpacity(tapeDiv, opacity);
+
+ this._eventLayer.appendChild(tapeDiv);
+
+ return {
+ left: startPixel,
+ top: top,
+ width: tapeWidth,
+ height: tapeHeight,
+ elmt: tapeDiv
+ };
+}
+
+Timeline.DetailedEventPainter.prototype._createHighlightDiv = function(highlightIndex, dimensions, theme) {
+ if (highlightIndex >= 0) {
+ var doc = this._timeline.getDocument();
+ var eventTheme = theme.event;
+
+ var color = eventTheme.highlightColors[Math.min(highlightIndex, eventTheme.highlightColors.length - 1)];
+
+ var div = doc.createElement("div");
+ div.style.position = "absolute";
+ div.style.overflow = "hidden";
+ div.style.left = (dimensions.left - 2) + "px";
+ div.style.width = (dimensions.width + 4) + "px";
+ div.style.top = (dimensions.top - 2) + "px";
+ div.style.height = (dimensions.height + 4) + "px";
+ div.style.background = color;
+
+ this._highlightLayer.appendChild(div);
+ }
+};
+
+Timeline.DetailedEventPainter.prototype._onClickInstantEvent = function(icon, domEvt, evt) {
+ var c = SimileAjax.DOM.getPageCoordinates(icon);
+ this._showBubble(
+ c.left + Math.ceil(icon.offsetWidth / 2),
+ c.top + Math.ceil(icon.offsetHeight / 2),
+ evt
+ );
+ this._fireOnSelect(evt.getID());
+
+ domEvt.cancelBubble = true;
+ SimileAjax.DOM.cancelEvent(domEvt);
+ return false;
+};
+
+Timeline.DetailedEventPainter.prototype._onClickDurationEvent = function(target, domEvt, evt) {
+ if ("pageX" in domEvt) {
+ var x = domEvt.pageX;
+ var y = domEvt.pageY;
+ } else {
+ var c = SimileAjax.DOM.getPageCoordinates(target);
+ var x = domEvt.offsetX + c.left;
+ var y = domEvt.offsetY + c.top;
+ }
+ this._showBubble(x, y, evt);
+ this._fireOnSelect(evt.getID());
+
+ domEvt.cancelBubble = true;
+ SimileAjax.DOM.cancelEvent(domEvt);
+ return false;
+};
+
+Timeline.DetailedEventPainter.prototype.showBubble = function(evt) {
+ var elmt = this._eventIdToElmt[evt.getID()];
+ if (elmt) {
+ var c = SimileAjax.DOM.getPageCoordinates(elmt);
+ this._showBubble(c.left + elmt.offsetWidth / 2, c.top + elmt.offsetHeight / 2, evt);
+ }
+};
+
+Timeline.DetailedEventPainter.prototype._showBubble = function(x, y, evt) {
+ var div = document.createElement("div");
+ evt.fillInfoBubble(div, this._params.theme, this._band.getLabeller());
+
+ SimileAjax.WindowManager.cancelPopups();
+ SimileAjax.Graphics.createBubbleForContentAndPoint(div, x, y, this._params.theme.event.bubble.width);
+};
+
+Timeline.DetailedEventPainter.prototype._fireOnSelect = function(eventID) {
+ for (var i = 0; i < this._onSelectListeners.length; i++) {
+ this._onSelectListeners[i](eventID);
+ }
+};
diff --git a/site/app/webroot/js/simile/timeline/scripts/ether-painters.js b/site/app/webroot/js/simile/timeline/scripts/ether-painters.js
new file mode 100755
index 0000000..7befc38
--- /dev/null
+++ b/site/app/webroot/js/simile/timeline/scripts/ether-painters.js
@@ -0,0 +1,566 @@
+/*==================================================
+ * Gregorian Ether Painter
+ *==================================================
+ */
+
+Timeline.GregorianEtherPainter = function(params) {
+ this._params = params;
+ this._theme = params.theme;
+ this._unit = params.unit;
+ this._multiple = ("multiple" in params) ? params.multiple : 1;
+};
+
+Timeline.GregorianEtherPainter.prototype.initialize = function(band, timeline) {
+ this._band = band;
+ this._timeline = timeline;
+
+ this._backgroundLayer = band.createLayerDiv(0);
+ this._backgroundLayer.setAttribute("name", "ether-background"); // for debugging
+ this._backgroundLayer.style.background = this._theme.ether.backgroundColors[band.getIndex()];
+
+ this._markerLayer = null;
+ this._lineLayer = null;
+
+ var align = ("align" in this._params && this._params.align != undefined) ? this._params.align :
+ this._theme.ether.interval.marker[timeline.isHorizontal() ? "hAlign" : "vAlign"];
+ var showLine = ("showLine" in this._params) ? this._params.showLine :
+ this._theme.ether.interval.line.show;
+
+ this._intervalMarkerLayout = new Timeline.EtherIntervalMarkerLayout(
+ this._timeline, this._band, this._theme, align, showLine);
+
+ this._highlight = new Timeline.EtherHighlight(
+ this._timeline, this._band, this._theme, this._backgroundLayer);
+}
+
+Timeline.GregorianEtherPainter.prototype.setHighlight = function(startDate, endDate) {
+ this._highlight.position(startDate, endDate);
+}
+
+Timeline.GregorianEtherPainter.prototype.paint = function() {
+ if (this._markerLayer) {
+ this._band.removeLayerDiv(this._markerLayer);
+ }
+ this._markerLayer = this._band.createLayerDiv(100);
+ this._markerLayer.setAttribute("name", "ether-markers"); // for debugging
+ this._markerLayer.style.display = "none";
+
+ if (this._lineLayer) {
+ this._band.removeLayerDiv(this._lineLayer);
+ }
+ this._lineLayer = this._band.createLayerDiv(1);
+ this._lineLayer.setAttribute("name", "ether-lines"); // for debugging
+ this._lineLayer.style.display = "none";
+
+ var minDate = this._band.getMinDate();
+ var maxDate = this._band.getMaxDate();
+
+ var timeZone = this._band.getTimeZone();
+ var labeller = this._band.getLabeller();
+
+ SimileAjax.DateTime.roundDownToInterval(minDate, this._unit, timeZone, this._multiple, this._theme.firstDayOfWeek);
+
+ var p = this;
+ var incrementDate = function(date) {
+ for (var i = 0; i < p._multiple; i++) {
+ SimileAjax.DateTime.incrementByInterval(date, p._unit);
+ }
+ };
+
+ while (minDate.getTime() < maxDate.getTime()) {
+ this._intervalMarkerLayout.createIntervalMarker(
+ minDate, labeller, this._unit, this._markerLayer, this._lineLayer);
+
+ incrementDate(minDate);
+ }
+ this._markerLayer.style.display = "block";
+ this._lineLayer.style.display = "block";
+};
+
+Timeline.GregorianEtherPainter.prototype.softPaint = function() {
+};
+
+/*==================================================
+ * Hot Zone Gregorian Ether Painter
+ *==================================================
+ */
+
+Timeline.HotZoneGregorianEtherPainter = function(params) {
+ this._params = params;
+ this._theme = params.theme;
+
+ this._zones = [{
+ startTime: Number.NEGATIVE_INFINITY,
+ endTime: Number.POSITIVE_INFINITY,
+ unit: params.unit,
+ multiple: 1
+ }];
+ for (var i = 0; i < params.zones.length; i++) {
+ var zone = params.zones[i];
+ var zoneStart = SimileAjax.DateTime.parseGregorianDateTime(zone.start).getTime();
+ var zoneEnd = SimileAjax.DateTime.parseGregorianDateTime(zone.end).getTime();
+
+ for (var j = 0; j < this._zones.length && zoneEnd > zoneStart; j++) {
+ var zone2 = this._zones[j];
+
+ if (zoneStart < zone2.endTime) {
+ if (zoneStart > zone2.startTime) {
+ this._zones.splice(j, 0, {
+ startTime: zone2.startTime,
+ endTime: zoneStart,
+ unit: zone2.unit,
+ multiple: zone2.multiple
+ });
+ j++;
+
+ zone2.startTime = zoneStart;
+ }
+
+ if (zoneEnd < zone2.endTime) {
+ this._zones.splice(j, 0, {
+ startTime: zoneStart,
+ endTime: zoneEnd,
+ unit: zone.unit,
+ multiple: (zone.multiple) ? zone.multiple : 1
+ });
+ j++;
+
+ zone2.startTime = zoneEnd;
+ zoneStart = zoneEnd;
+ } else {
+ zone2.multiple = zone.multiple;
+ zone2.unit = zone.unit;
+ zoneStart = zone2.endTime;
+ }
+ } // else, try the next existing zone
+ }
+ }
+};
+
+Timeline.HotZoneGregorianEtherPainter.prototype.initialize = function(band, timeline) {
+ this._band = band;
+ this._timeline = timeline;
+
+ this._backgroundLayer = band.createLayerDiv(0);
+ this._backgroundLayer.setAttribute("name", "ether-background"); // for debugging
+ this._backgroundLayer.style.background = this._theme.ether.backgroundColors[band.getIndex()];
+
+ this._markerLayer = null;
+ this._lineLayer = null;
+
+ var align = ("align" in this._params && this._params.align != undefined) ? this._params.align :
+ this._theme.ether.interval.marker[timeline.isHorizontal() ? "hAlign" : "vAlign"];
+ var showLine = ("showLine" in this._params) ? this._params.showLine :
+ this._theme.ether.interval.line.show;
+
+ this._intervalMarkerLayout = new Timeline.EtherIntervalMarkerLayout(
+ this._timeline, this._band, this._theme, align, showLine);
+
+ this._highlight = new Timeline.EtherHighlight(
+ this._timeline, this._band, this._theme, this._backgroundLayer);
+}
+
+Timeline.HotZoneGregorianEtherPainter.prototype.setHighlight = function(startDate, endDate) {
+ this._highlight.position(startDate, endDate);
+}
+
+Timeline.HotZoneGregorianEtherPainter.prototype.paint = function() {
+ if (this._markerLayer) {
+ this._band.removeLayerDiv(this._markerLayer);
+ }
+ this._markerLayer = this._band.createLayerDiv(100);
+ this._markerLayer.setAttribute("name", "ether-markers"); // for debugging
+ this._markerLayer.style.display = "none";
+
+ if (this._lineLayer) {
+ this._band.removeLayerDiv(this._lineLayer);
+ }
+ this._lineLayer = this._band.createLayerDiv(1);
+ this._lineLayer.setAttribute("name", "ether-lines"); // for debugging
+ this._lineLayer.style.display = "none";
+
+ var minDate = this._band.getMinDate();
+ var maxDate = this._band.getMaxDate();
+
+ var timeZone = this._band.getTimeZone();
+ var labeller = this._band.getLabeller();
+
+ var p = this;
+ var incrementDate = function(date, zone) {
+ for (var i = 0; i < zone.multiple; i++) {
+ SimileAjax.DateTime.incrementByInterval(date, zone.unit);
+ }
+ };
+
+ var zStart = 0;
+ while (zStart < this._zones.length) {
+ if (minDate.getTime() < this._zones[zStart].endTime) {
+ break;
+ }
+ zStart++;
+ }
+ var zEnd = this._zones.length - 1;
+ while (zEnd >= 0) {
+ if (maxDate.getTime() > this._zones[zEnd].startTime) {
+ break;
+ }
+ zEnd--;
+ }
+
+ for (var z = zStart; z <= zEnd; z++) {
+ var zone = this._zones[z];
+
+ var minDate2 = new Date(Math.max(minDate.getTime(), zone.startTime));
+ var maxDate2 = new Date(Math.min(maxDate.getTime(), zone.endTime));
+
+ SimileAjax.DateTime.roundDownToInterval(minDate2, zone.unit, timeZone, zone.multiple, this._theme.firstDayOfWeek);
+ SimileAjax.DateTime.roundUpToInterval(maxDate2, zone.unit, timeZone, zone.multiple, this._theme.firstDayOfWeek);
+
+ while (minDate2.getTime() < maxDate2.getTime()) {
+ this._intervalMarkerLayout.createIntervalMarker(
+ minDate2, labeller, zone.unit, this._markerLayer, this._lineLayer);
+
+ incrementDate(minDate2, zone);
+ }
+ }
+ this._markerLayer.style.display = "block";
+ this._lineLayer.style.display = "block";
+};
+
+Timeline.HotZoneGregorianEtherPainter.prototype.softPaint = function() {
+};
+
+/*==================================================
+ * Year Count Ether Painter
+ *==================================================
+ */
+
+Timeline.YearCountEtherPainter = function(params) {
+ this._params = params;
+ this._theme = params.theme;
+ this._startDate = SimileAjax.DateTime.parseGregorianDateTime(params.startDate);
+ this._multiple = ("multiple" in params) ? params.multiple : 1;
+};
+
+Timeline.YearCountEtherPainter.prototype.initialize = function(band, timeline) {
+ this._band = band;
+ this._timeline = timeline;
+
+ this._backgroundLayer = band.createLayerDiv(0);
+ this._backgroundLayer.setAttribute("name", "ether-background"); // for debugging
+ this._backgroundLayer.style.background = this._theme.ether.backgroundColors[band.getIndex()];
+
+ this._markerLayer = null;
+ this._lineLayer = null;
+
+ var align = ("align" in this._params) ? this._params.align :
+ this._theme.ether.interval.marker[timeline.isHorizontal() ? "hAlign" : "vAlign"];
+ var showLine = ("showLine" in this._params) ? this._params.showLine :
+ this._theme.ether.interval.line.show;
+
+ this._intervalMarkerLayout = new Timeline.EtherIntervalMarkerLayout(
+ this._timeline, this._band, this._theme, align, showLine);
+
+ this._highlight = new Timeline.EtherHighlight(
+ this._timeline, this._band, this._theme, this._backgroundLayer);
+};
+
+Timeline.YearCountEtherPainter.prototype.setHighlight = function(startDate, endDate) {
+ this._highlight.position(startDate, endDate);
+};
+
+Timeline.YearCountEtherPainter.prototype.paint = function() {
+ if (this._markerLayer) {
+ this._band.removeLayerDiv(this._markerLayer);
+ }
+ this._markerLayer = this._band.createLayerDiv(100);
+ this._markerLayer.setAttribute("name", "ether-markers"); // for debugging
+ this._markerLayer.style.display = "none";
+
+ if (this._lineLayer) {
+ this._band.removeLayerDiv(this._lineLayer);
+ }
+ this._lineLayer = this._band.createLayerDiv(1);
+ this._lineLayer.setAttribute("name", "ether-lines"); // for debugging
+ this._lineLayer.style.display = "none";
+
+ var minDate = new Date(this._startDate.getTime());
+ var maxDate = this._band.getMaxDate();
+ var yearDiff = this._band.getMinDate().getUTCFullYear() - this._startDate.getUTCFullYear();
+ minDate.setUTCFullYear(this._band.getMinDate().getUTCFullYear() - yearDiff % this._multiple);
+
+ var p = this;
+ var incrementDate = function(date) {
+ for (var i = 0; i < p._multiple; i++) {
+ SimileAjax.DateTime.incrementByInterval(date, SimileAjax.DateTime.YEAR);
+ }
+ };
+ var labeller = {
+ labelInterval: function(date, intervalUnit) {
+ var diff = date.getUTCFullYear() - p._startDate.getUTCFullYear();
+ return {
+ text: diff,
+ emphasized: diff == 0
+ };
+ }
+ };
+
+ while (minDate.getTime() < maxDate.getTime()) {
+ this._intervalMarkerLayout.createIntervalMarker(
+ minDate, labeller, SimileAjax.DateTime.YEAR, this._markerLayer, this._lineLayer);
+
+ incrementDate(minDate);
+ }
+ this._markerLayer.style.display = "block";
+ this._lineLayer.style.display = "block";
+};
+
+Timeline.YearCountEtherPainter.prototype.softPaint = function() {
+};
+
+/*==================================================
+ * Quarterly Ether Painter
+ *==================================================
+ */
+
+Timeline.QuarterlyEtherPainter = function(params) {
+ this._params = params;
+ this._theme = params.theme;
+ this._startDate = SimileAjax.DateTime.parseGregorianDateTime(params.startDate);
+};
+
+Timeline.QuarterlyEtherPainter.prototype.initialize = function(band, timeline) {
+ this._band = band;
+ this._timeline = timeline;
+
+ this._backgroundLayer = band.createLayerDiv(0);
+ this._backgroundLayer.setAttribute("name", "ether-background"); // for debugging
+ this._backgroundLayer.style.background = this._theme.ether.backgroundColors[band.getIndex()];
+
+ this._markerLayer = null;
+ this._lineLayer = null;
+
+ var align = ("align" in this._params) ? this._params.align :
+ this._theme.ether.interval.marker[timeline.isHorizontal() ? "hAlign" : "vAlign"];
+ var showLine = ("showLine" in this._params) ? this._params.showLine :
+ this._theme.ether.interval.line.show;
+
+ this._intervalMarkerLayout = new Timeline.EtherIntervalMarkerLayout(
+ this._timeline, this._band, this._theme, align, showLine);
+
+ this._highlight = new Timeline.EtherHighlight(
+ this._timeline, this._band, this._theme, this._backgroundLayer);
+};
+
+Timeline.QuarterlyEtherPainter.prototype.setHighlight = function(startDate, endDate) {
+ this._highlight.position(startDate, endDate);
+};
+
+Timeline.QuarterlyEtherPainter.prototype.paint = function() {
+ if (this._markerLayer) {
+ this._band.removeLayerDiv(this._markerLayer);
+ }
+ this._markerLayer = this._band.createLayerDiv(100);
+ this._markerLayer.setAttribute("name", "ether-markers"); // for debugging
+ this._markerLayer.style.display = "none";
+
+ if (this._lineLayer) {
+ this._band.removeLayerDiv(this._lineLayer);
+ }
+ this._lineLayer = this._band.createLayerDiv(1);
+ this._lineLayer.setAttribute("name", "ether-lines"); // for debugging
+ this._lineLayer.style.display = "none";
+
+ var minDate = new Date(0);
+ var maxDate = this._band.getMaxDate();
+
+ minDate.setUTCFullYear(Math.max(this._startDate.getUTCFullYear(), this._band.getMinDate().getUTCFullYear()));
+ minDate.setUTCMonth(this._startDate.getUTCMonth());
+
+ var p = this;
+ var incrementDate = function(date) {
+ date.setUTCMonth(date.getUTCMonth() + 3);
+ };
+ var labeller = {
+ labelInterval: function(date, intervalUnit) {
+ var quarters = (4 + (date.getUTCMonth() - p._startDate.getUTCMonth()) / 3) % 4;
+ if (quarters != 0) {
+ return { text: "Q" + (quarters + 1), emphasized: false };
+ } else {
+ return { text: "Y" + (date.getUTCFullYear() - p._startDate.getUTCFullYear() + 1), emphasized: true };
+ }
+ }
+ };
+
+ while (minDate.getTime() < maxDate.getTime()) {
+ this._intervalMarkerLayout.createIntervalMarker(
+ minDate, labeller, SimileAjax.DateTime.YEAR, this._markerLayer, this._lineLayer);
+
+ incrementDate(minDate);
+ }
+ this._markerLayer.style.display = "block";
+ this._lineLayer.style.display = "block";
+};
+
+Timeline.QuarterlyEtherPainter.prototype.softPaint = function() {
+};
+
+/*==================================================
+ * Ether Interval Marker Layout
+ *==================================================
+ */
+
+Timeline.EtherIntervalMarkerLayout = function(timeline, band, theme, align, showLine) {
+ var horizontal = timeline.isHorizontal();
+ if (horizontal) {
+ if (align == "Top") {
+ this.positionDiv = function(div, offset) {
+ div.style.left = offset + "px";
+ div.style.top = "0px";
+ };
+ } else {
+ this.positionDiv = function(div, offset) {
+ div.style.left = offset + "px";
+ div.style.bottom = "0px";
+ };
+ }
+ } else {
+ if (align == "Left") {
+ this.positionDiv = function(div, offset) {
+ div.style.top = offset + "px";
+ div.style.left = "0px";
+ };
+ } else {
+ this.positionDiv = function(div, offset) {
+ div.style.top = offset + "px";
+ div.style.right = "0px";
+ };
+ }
+ }
+
+ var markerTheme = theme.ether.interval.marker;
+ var lineTheme = theme.ether.interval.line;
+ var weekendTheme = theme.ether.interval.weekend;
+
+ var stylePrefix = (horizontal ? "h" : "v") + align;
+ var labelStyler = markerTheme[stylePrefix + "Styler"];
+ var emphasizedLabelStyler = markerTheme[stylePrefix + "EmphasizedStyler"];
+ var day = SimileAjax.DateTime.gregorianUnitLengths[SimileAjax.DateTime.DAY];
+
+ this.createIntervalMarker = function(date, labeller, unit, markerDiv, lineDiv) {
+ var offset = Math.round(band.dateToPixelOffset(date));
+
+ if (showLine && unit != SimileAjax.DateTime.WEEK) {
+ var divLine = timeline.getDocument().createElement("div");
+ divLine.style.position = "absolute";
+
+ if (lineTheme.opacity < 100) {
+ SimileAjax.Graphics.setOpacity(divLine, lineTheme.opacity);
+ }
+
+ if (horizontal) {
+ divLine.style.borderLeft = "1px solid " + lineTheme.color;
+ divLine.style.left = offset + "px";
+ divLine.style.width = "1px";
+ divLine.style.top = "0px";
+ divLine.style.height = "100%";
+ } else {
+ divLine.style.borderTop = "1px solid " + lineTheme.color;
+ divLine.style.top = offset + "px";
+ divLine.style.height = "1px";
+ divLine.style.left = "0px";
+ divLine.style.width = "100%";
+ }
+ lineDiv.appendChild(divLine);
+ }
+ if (unit == SimileAjax.DateTime.WEEK) {
+ var firstDayOfWeek = theme.firstDayOfWeek;
+
+ var saturday = new Date(date.getTime() + (6 - firstDayOfWeek - 7) * day);
+ var monday = new Date(saturday.getTime() + 2 * day);
+
+ var saturdayPixel = Math.round(band.dateToPixelOffset(saturday));
+ var mondayPixel = Math.round(band.dateToPixelOffset(monday));
+ var length = Math.max(1, mondayPixel - saturdayPixel);
+
+ var divWeekend = timeline.getDocument().createElement("div");
+ divWeekend.style.position = "absolute";
+
+ divWeekend.style.background = weekendTheme.color;
+ if (weekendTheme.opacity < 100) {
+ SimileAjax.Graphics.setOpacity(divWeekend, weekendTheme.opacity);
+ }
+
+ if (horizontal) {
+ divWeekend.style.left = saturdayPixel + "px";
+ divWeekend.style.width = length + "px";
+ divWeekend.style.top = "0px";
+ divWeekend.style.height = "100%";
+ } else {
+ divWeekend.style.top = saturdayPixel + "px";
+ divWeekend.style.height = length + "px";
+ divWeekend.style.left = "0px";
+ divWeekend.style.width = "100%";
+ }
+ lineDiv.appendChild(divWeekend);
+ }
+
+ var label = labeller.labelInterval(date, unit);
+
+ var div = timeline.getDocument().createElement("div");
+ div.innerHTML = label.text;
+ div.style.position = "absolute";
+ (label.emphasized ? emphasizedLabelStyler : labelStyler)(div);
+
+ this.positionDiv(div, offset);
+ markerDiv.appendChild(div);
+
+ return div;
+ };
+};
+
+/*==================================================
+ * Ether Highlight Layout
+ *==================================================
+ */
+
+Timeline.EtherHighlight = function(timeline, band, theme, backgroundLayer) {
+ var horizontal = timeline.isHorizontal();
+
+ this._highlightDiv = null;
+ this._createHighlightDiv = function() {
+ if (this._highlightDiv == null) {
+ this._highlightDiv = timeline.getDocument().createElement("div");
+ this._highlightDiv.setAttribute("name", "ether-highlight"); // for debugging
+ this._highlightDiv.style.position = "absolute";
+ this._highlightDiv.style.background = theme.ether.highlightColor;
+
+ var opacity = theme.ether.highlightOpacity;
+ if (opacity < 100) {
+ SimileAjax.Graphics.setOpacity(this._highlightDiv, opacity);
+ }
+
+ backgroundLayer.appendChild(this._highlightDiv);
+ }
+ }
+
+ this.position = function(startDate, endDate) {
+ this._createHighlightDiv();
+
+ var startPixel = Math.round(band.dateToPixelOffset(startDate));
+ var endPixel = Math.round(band.dateToPixelOffset(endDate));
+ var length = Math.max(endPixel - startPixel, 3);
+ if (horizontal) {
+ this._highlightDiv.style.left = startPixel + "px";
+ this._highlightDiv.style.width = length + "px";
+ this._highlightDiv.style.top = "2px";
+ this._highlightDiv.style.height = (band.getViewWidth() - 4) + "px";
+ } else {
+ this._highlightDiv.style.top = startPixel + "px";
+ this._highlightDiv.style.height = length + "px";
+ this._highlightDiv.style.left = "2px";
+ this._highlightDiv.style.width = (band.getViewWidth() - 4) + "px";
+ }
+ }
+};
+
diff --git a/site/app/webroot/js/simile/timeline/scripts/ethers.js b/site/app/webroot/js/simile/timeline/scripts/ethers.js
new file mode 100755
index 0000000..809ec70
--- /dev/null
+++ b/site/app/webroot/js/simile/timeline/scripts/ethers.js
@@ -0,0 +1,250 @@
+/*==================================================
+ * Linear Ether
+ *==================================================
+ */
+
+Timeline.LinearEther = function(params) {
+ this._params = params;
+ this._interval = params.interval;
+ this._pixelsPerInterval = params.pixelsPerInterval;
+};
+
+Timeline.LinearEther.prototype.initialize = function(timeline) {
+ this._timeline = timeline;
+ this._unit = timeline.getUnit();
+
+ if ("startsOn" in this._params) {
+ this._start = this._unit.parseFromObject(this._params.startsOn);
+ } else if ("endsOn" in this._params) {
+ this._start = this._unit.parseFromObject(this._params.endsOn);
+ this.shiftPixels(-this._timeline.getPixelLength());
+ } else if ("centersOn" in this._params) {
+ this._start = this._unit.parseFromObject(this._params.centersOn);
+ this.shiftPixels(-this._timeline.getPixelLength() / 2);
+ } else {
+ this._start = this._unit.makeDefaultValue();
+ this.shiftPixels(-this._timeline.getPixelLength() / 2);
+ }
+};
+
+Timeline.LinearEther.prototype.setDate = function(date) {
+ this._start = this._unit.cloneValue(date);
+};
+
+Timeline.LinearEther.prototype.shiftPixels = function(pixels) {
+ var numeric = this._interval * pixels / this._pixelsPerInterval;
+ this._start = this._unit.change(this._start, numeric);
+};
+
+Timeline.LinearEther.prototype.dateToPixelOffset = function(date) {
+ var numeric = this._unit.compare(date, this._start);
+ return this._pixelsPerInterval * numeric / this._interval;
+};
+
+Timeline.LinearEther.prototype.pixelOffsetToDate = function(pixels) {
+ var numeric = pixels * this._interval / this._pixelsPerInterval;
+ return this._unit.change(this._start, numeric);
+};
+
+/*==================================================
+ * Hot Zone Ether
+ *==================================================
+ */
+
+Timeline.HotZoneEther = function(params) {
+ this._params = params;
+ this._interval = params.interval;
+ this._pixelsPerInterval = params.pixelsPerInterval;
+};
+
+Timeline.HotZoneEther.prototype.initialize = function(timeline) {
+ this._timeline = timeline;
+ this._unit = timeline.getUnit();
+
+ this._zones = [{
+ startTime: Number.NEGATIVE_INFINITY,
+ endTime: Number.POSITIVE_INFINITY,
+ magnify: 1
+ }];
+ var params = this._params;
+ for (var i = 0; i < params.zones.length; i++) {
+ var zone = params.zones[i];
+ var zoneStart = this._unit.parseFromObject(zone.start);
+ var zoneEnd = this._unit.parseFromObject(zone.end);
+
+ for (var j = 0; j < this._zones.length && this._unit.compare(zoneEnd, zoneStart) > 0; j++) {
+ var zone2 = this._zones[j];
+
+ if (this._unit.compare(zoneStart, zone2.endTime) < 0) {
+ if (this._unit.compare(zoneStart, zone2.startTime) > 0) {
+ this._zones.splice(j, 0, {
+ startTime: zone2.startTime,
+ endTime: zoneStart,
+ magnify: zone2.magnify
+ });
+ j++;
+
+ zone2.startTime = zoneStart;
+ }
+
+ if (this._unit.compare(zoneEnd, zone2.endTime) < 0) {
+ this._zones.splice(j, 0, {
+ startTime: zoneStart,
+ endTime: zoneEnd,
+ magnify: zone.magnify * zone2.magnify
+ });
+ j++;
+
+ zone2.startTime = zoneEnd;
+ zoneStart = zoneEnd;
+ } else {
+ zone2.magnify *= zone.magnify;
+ zoneStart = zone2.endTime;
+ }
+ } // else, try the next existing zone
+ }
+ }
+
+ if ("startsOn" in this._params) {
+ this._start = this._unit.parseFromObject(this._params.startsOn);
+ } else if ("endsOn" in this._params) {
+ this._start = this._unit.parseFromObject(this._params.endsOn);
+ this.shiftPixels(-this._timeline.getPixelLength());
+ } else if ("centersOn" in this._params) {
+ this._start = this._unit.parseFromObject(this._params.centersOn);
+ this.shiftPixels(-this._timeline.getPixelLength() / 2);
+ } else {
+ this._start = this._unit.makeDefaultValue();
+ this.shiftPixels(-this._timeline.getPixelLength() / 2);
+ }
+};
+
+Timeline.HotZoneEther.prototype.setDate = function(date) {
+ this._start = this._unit.cloneValue(date);
+};
+
+Timeline.HotZoneEther.prototype.shiftPixels = function(pixels) {
+ this._start = this.pixelOffsetToDate(pixels);
+};
+
+Timeline.HotZoneEther.prototype.dateToPixelOffset = function(date) {
+ return this._dateDiffToPixelOffset(this._start, date);
+};
+
+Timeline.HotZoneEther.prototype.pixelOffsetToDate = function(pixels) {
+ return this._pixelOffsetToDate(pixels, this._start);
+};
+
+Timeline.HotZoneEther.prototype._dateDiffToPixelOffset = function(fromDate, toDate) {
+ var scale = this._getScale();
+ var fromTime = fromDate;
+ var toTime = toDate;
+
+ var pixels = 0;
+ if (this._unit.compare(fromTime, toTime) < 0) {
+ var z = 0;
+ while (z < this._zones.length) {
+ if (this._unit.compare(fromTime, this._zones[z].endTime) < 0) {
+ break;
+ }
+ z++;
+ }
+
+ while (this._unit.compare(fromTime, toTime) < 0) {
+ var zone = this._zones[z];
+ var toTime2 = this._unit.earlier(toTime, zone.endTime);
+
+ pixels += (this._unit.compare(toTime2, fromTime) / (scale / zone.magnify));
+
+ fromTime = toTime2;
+ z++;
+ }
+ } else {
+ var z = this._zones.length - 1;
+ while (z >= 0) {
+ if (this._unit.compare(fromTime, this._zones[z].startTime) > 0) {
+ break;
+ }
+ z--;
+ }
+
+ while (this._unit.compare(fromTime, toTime) > 0) {
+ var zone = this._zones[z];
+ var toTime2 = this._unit.later(toTime, zone.startTime);
+
+ pixels += (this._unit.compare(toTime2, fromTime) / (scale / zone.magnify));
+
+ fromTime = toTime2;
+ z--;
+ }
+ }
+ return pixels;
+};
+
+Timeline.HotZoneEther.prototype._pixelOffsetToDate = function(pixels, fromDate) {
+ var scale = this._getScale();
+ var time = fromDate;
+ if (pixels > 0) {
+ var z = 0;
+ while (z < this._zones.length) {
+ if (this._unit.compare(time, this._zones[z].endTime) < 0) {
+ break;
+ }
+ z++;
+ }
+
+ while (pixels > 0) {
+ var zone = this._zones[z];
+ var scale2 = scale / zone.magnify;
+
+ if (zone.endTime == Number.POSITIVE_INFINITY) {
+ time = this._unit.change(time, pixels * scale2);
+ pixels = 0;
+ } else {
+ var pixels2 = this._unit.compare(zone.endTime, time) / scale2;
+ if (pixels2 > pixels) {
+ time = this._unit.change(time, pixels * scale2);
+ pixels = 0;
+ } else {
+ time = zone.endTime;
+ pixels -= pixels2;
+ }
+ }
+ z++;
+ }
+ } else {
+ var z = this._zones.length - 1;
+ while (z >= 0) {
+ if (this._unit.compare(time, this._zones[z].startTime) > 0) {
+ break;
+ }
+ z--;
+ }
+
+ pixels = -pixels;
+ while (pixels > 0) {
+ var zone = this._zones[z];
+ var scale2 = scale / zone.magnify;
+
+ if (zone.startTime == Number.NEGATIVE_INFINITY) {
+ time = this._unit.change(time, -pixels * scale2);
+ pixels = 0;
+ } else {
+ var pixels2 = this._unit.compare(time, zone.startTime) / scale2;
+ if (pixels2 > pixels) {
+ time = this._unit.change(time, -pixels * scale2);
+ pixels = 0;
+ } else {
+ time = zone.startTime;
+ pixels -= pixels2;
+ }
+ }
+ z--;
+ }
+ }
+ return time;
+};
+
+Timeline.HotZoneEther.prototype._getScale = function() {
+ return this._interval / this._pixelsPerInterval;
+};
diff --git a/site/app/webroot/js/simile/timeline/scripts/ext/japanese-eras.js b/site/app/webroot/js/simile/timeline/scripts/ext/japanese-eras.js
new file mode 100755
index 0000000..92027ac
--- /dev/null
+++ b/site/app/webroot/js/simile/timeline/scripts/ext/japanese-eras.js
@@ -0,0 +1,395 @@
+/*==================================================
+ * Japanese Era Date Labeller
+ *==================================================
+ */
+
+Timeline.JapaneseEraDateLabeller = function(locale, timeZone, useRomanizedName) {
+ var o = new Timeline.GregorianDateLabeller(locale, timeZone);
+
+ o._useRomanizedName = (useRomanizedName);
+ o._oldLabelInterval = o.labelInterval;
+ o.labelInterval = Timeline.JapaneseEraDateLabeller._labelInterval;
+
+ return o;
+};
+
+Timeline.JapaneseEraDateLabeller._labelInterval = function(date, intervalUnit) {
+ var text;
+ var emphasized = false;
+
+ var date2 = Timeline.DateTime.removeTimeZoneOffset(date, this._timeZone);
+
+ switch(intervalUnit) {
+ case Timeline.DateTime.YEAR:
+ case Timeline.DateTime.DECADE:
+ case Timeline.DateTime.CENTURY:
+ case Timeline.DateTime.MILLENNIUM:
+ var y = date2.getUTCFullYear();
+ if (y >= Timeline.JapaneseEraDateLabeller._eras.elementAt(0).startingYear) {
+ var eraIndex = Timeline.JapaneseEraDateLabeller._eras.find(function(era) {
+ return era.startingYear - y;
+ }
+ );
+ if (eraIndex < Timeline.JapaneseEraDateLabeller._eras.length()) {
+ var era = Timeline.JapaneseEraDateLabeller._eras.elementAt(eraIndex);
+ if (y < era.startingYear) {
+ era = Timeline.JapaneseEraDateLabeller._eras.elementAt(eraIndex - 1);
+ }
+ } else {
+ var era = Timeline.JapaneseEraDateLabeller._eras.elementAt(eraIndex - 1);
+ }
+
+ text = (this._useRomanizedName ? era.romanizedName : era.japaneseName) + " " + (y - era.startingYear + 1);
+ emphasized = intervalUnit == Timeline.DateTime.YEAR && y == era.startingYear;
+ break;
+ } // else, fall through
+ default:
+ return this._oldLabelInterval(date, intervalUnit);
+ }
+
+ return { text: text, emphasized: emphasized };
+};
+
+/*==================================================
+ * Japanese Era Ether Painter
+ *==================================================
+ */
+
+Timeline.JapaneseEraEtherPainter = function(params, band, timeline) {
+ this._params = params;
+ this._theme = params.theme;
+};
+
+Timeline.JapaneseEraEtherPainter.prototype.initialize = function(band, timeline) {
+ this._band = band;
+ this._timeline = timeline;
+
+ this._backgroundLayer = band.createLayerDiv(0);
+ this._backgroundLayer.setAttribute("name", "ether-background"); // for debugging
+ this._backgroundLayer.style.background = this._theme.ether.backgroundColors[band.getIndex()];
+
+ this._markerLayer = null;
+ this._lineLayer = null;
+
+ var align = ("align" in this._params) ? this._params.align :
+ this._theme.ether.interval.marker[timeline.isHorizontal() ? "hAlign" : "vAlign"];
+ var showLine = ("showLine" in this._params) ? this._params.showLine :
+ this._theme.ether.interval.line.show;
+
+ this._intervalMarkerLayout = new Timeline.EtherIntervalMarkerLayout(
+ this._timeline, this._band, this._theme, align, showLine);
+
+ this._highlight = new Timeline.EtherHighlight(
+ this._timeline, this._band, this._theme, this._backgroundLayer);
+}
+
+Timeline.JapaneseEraEtherPainter.prototype.setHighlight = function(startDate, endDate) {
+ this._highlight.position(startDate, endDate);
+}
+
+Timeline.JapaneseEraEtherPainter.prototype.paint = function() {
+ if (this._markerLayer) {
+ this._band.removeLayerDiv(this._markerLayer);
+ }
+ this._markerLayer = this._band.createLayerDiv(100);
+ this._markerLayer.setAttribute("name", "ether-markers"); // for debugging
+ this._markerLayer.style.display = "none";
+
+ if (this._lineLayer) {
+ this._band.removeLayerDiv(this._lineLayer);
+ }
+ this._lineLayer = this._band.createLayerDiv(1);
+ this._lineLayer.setAttribute("name", "ether-lines"); // for debugging
+ this._lineLayer.style.display = "none";
+
+ var minYear = this._band.getMinDate().getUTCFullYear();
+ var maxYear = this._band.getMaxDate().getUTCFullYear();
+ var eraIndex = Timeline.JapaneseEraDateLabeller._eras.find(function(era) {
+ return era.startingYear - minYear;
+ }
+ );
+
+ var l = Timeline.JapaneseEraDateLabeller._eras.length();
+ for (var i = eraIndex; i < l; i++) {
+ var era = Timeline.JapaneseEraDateLabeller._eras.elementAt(i);
+ if (era.startingYear > maxYear) {
+ break;
+ }
+
+ var d = new Date(0);
+ d.setUTCFullYear(era.startingYear);
+
+ var labeller = {
+ labelInterval: function(date, intervalUnit) {
+ return {
+ text: era.japaneseName,
+ emphasized: true
+ };
+ }
+ };
+
+ this._intervalMarkerLayout.createIntervalMarker(
+ d, labeller, Timeline.DateTime.YEAR, this._markerLayer, this._lineLayer);
+ }
+ this._markerLayer.style.display = "block";
+ this._lineLayer.style.display = "block";
+};
+
+Timeline.JapaneseEraEtherPainter.prototype.softPaint = function() {
+};
+
+
+Timeline.JapaneseEraDateLabeller._eras = new Timeline.SortedArray(
+ function(e1, e2) {
+ return e1.startingYear - e2.startingYear;
+ },
+ [
+ { startingYear: 645, japaneseName: '大化', romanizedName: "Taika" },
+ { startingYear: 650, japaneseName: '白雉', romanizedName: "Hakuchi" },
+ { startingYear: 686, japaneseName: '朱鳥', romanizedName: "ShuchÅ" },
+ { startingYear: 701, japaneseName: '大å®', romanizedName: "TaihÅ" },
+ { startingYear: 704, japaneseName: '慶雲', romanizedName: "Keiun" },
+ { startingYear: 708, japaneseName: '和銅', romanizedName: "WadÅ" },
+ { startingYear: 715, japaneseName: '霊亀', romanizedName: "Reiki" },
+ { startingYear: 717, japaneseName: '養è€', romanizedName: "YÅrÅ" },
+ { startingYear: 724, japaneseName: '神亀', romanizedName: "Jinki" },
+ { startingYear: 729, japaneseName: '天平', romanizedName: "TenpyÅ" },
+ { startingYear: 749, japaneseName: '天平感å®', romanizedName: "TenpyÅ-kanpÅ" },
+ { startingYear: 749, japaneseName: '天平å‹å®', romanizedName: "TenpyÅ-shÅhÅ" },
+ { startingYear: 757, japaneseName: '天平å®å­—', romanizedName: "TenpyÅ-hÅji" },
+ { startingYear: 765, japaneseName: '天平神護', romanizedName: "TenpyÅ-jingo" },
+ { startingYear: 767, japaneseName: '神護景雲', romanizedName: "Jingo-keiun" },
+ { startingYear: 770, japaneseName: 'å®äº€', romanizedName: "HÅki" },
+ { startingYear: 781, japaneseName: '天応', romanizedName: "Ten'Å" },
+ { startingYear: 782, japaneseName: '延暦', romanizedName: "Enryaku" },
+ { startingYear: 806, japaneseName: '大åŒ', romanizedName: "DaidÅ" },
+ { startingYear: 810, japaneseName: '弘ä»', romanizedName: "KÅnin" },
+ { startingYear: 824, japaneseName: '天長', romanizedName: "TenchÅ" },
+ { startingYear: 834, japaneseName: '承和', romanizedName: "JÅwa" },
+ { startingYear: 848, japaneseName: '嘉祥', romanizedName: "KajÅ" },
+ { startingYear: 851, japaneseName: 'ä»å¯¿', romanizedName: "Ninju" },
+ { startingYear: 854, japaneseName: '斉衡', romanizedName: "SaikÅ" },
+ { startingYear: 857, japaneseName: '天安', romanizedName: "Tennan" },
+ { startingYear: 859, japaneseName: '貞観', romanizedName: "JÅgan" },
+ { startingYear: 877, japaneseName: '元慶', romanizedName: "GangyÅ" },
+ { startingYear: 885, japaneseName: 'ä»å’Œ', romanizedName: "Ninna" },
+ { startingYear: 889, japaneseName: '寛平', romanizedName: "KanpyÅ" },
+ { startingYear: 898, japaneseName: '昌泰', romanizedName: "ShÅtai" },
+ { startingYear: 901, japaneseName: '延喜', romanizedName: "Engi" },
+ { startingYear: 923, japaneseName: '延長', romanizedName: "EnchÅ" },
+ { startingYear: 931, japaneseName: '承平', romanizedName: "JÅhei" },
+ { startingYear: 938, japaneseName: '天慶', romanizedName: "TengyÅ" },
+ { startingYear: 947, japaneseName: '天暦', romanizedName: "Tenryaku" },
+ { startingYear: 957, japaneseName: '天徳', romanizedName: "Tentoku" },
+ { startingYear: 961, japaneseName: '応和', romanizedName: "Ōwa" },
+ { startingYear: 964, japaneseName: '康ä¿', romanizedName: "KÅhÅ" },
+ { startingYear: 968, japaneseName: '安和', romanizedName: "Anna" },
+ { startingYear: 970, japaneseName: '天禄', romanizedName: "Tenroku" },
+ { startingYear: 973, japaneseName: '天延', romanizedName: "Ten'en" },
+ { startingYear: 976, japaneseName: '貞元', romanizedName: "JÅgen" },
+ { startingYear: 978, japaneseName: '天元', romanizedName: "Tengen" },
+ { startingYear: 983, japaneseName: '永観', romanizedName: "Eikan" },
+ { startingYear: 985, japaneseName: '寛和', romanizedName: "Kanna" },
+ { startingYear: 987, japaneseName: '永延', romanizedName: "Eien" },
+ { startingYear: 988, japaneseName: '永祚', romanizedName: "Eiso" },
+ { startingYear: 990, japaneseName: '正暦', romanizedName: "ShÅryaku" },
+ { startingYear: 995, japaneseName: 'é•·å¾³', romanizedName: "ChÅtoku" },
+ { startingYear: 999, japaneseName: 'é•·ä¿', romanizedName: "ChÅhÅ" },
+ { startingYear: 1004, japaneseName: '寛弘', romanizedName: "KankÅ" },
+ { startingYear: 1012, japaneseName: 'é•·å’Œ', romanizedName: "ChÅwa" },
+ { startingYear: 1017, japaneseName: '寛ä»', romanizedName: "Kannin" },
+ { startingYear: 1021, japaneseName: '治安', romanizedName: "Jian" },
+ { startingYear: 1024, japaneseName: '万寿', romanizedName: "Manju" },
+ { startingYear: 1028, japaneseName: 'é•·å…ƒ', romanizedName: "ChÅgen" },
+ { startingYear: 1037, japaneseName: '長暦', romanizedName: "ChÅryaku" },
+ { startingYear: 1040, japaneseName: 'é•·ä¹…', romanizedName: "ChÅkyÅ«" },
+ { startingYear: 1044, japaneseName: '寛徳', romanizedName: "Kantoku" },
+ { startingYear: 1046, japaneseName: '永承', romanizedName: "EishÅ" },
+ { startingYear: 1053, japaneseName: '天喜', romanizedName: "Tengi" },
+ { startingYear: 1058, japaneseName: '康平', romanizedName: "KÅhei" },
+ { startingYear: 1065, japaneseName: '治暦', romanizedName: "Jiryaku" },
+ { startingYear: 1069, japaneseName: '延久', romanizedName: "Enkyū" },
+ { startingYear: 1074, japaneseName: '承ä¿', romanizedName: "JÅhÅ" },
+ { startingYear: 1077, japaneseName: '承暦', romanizedName: "JÅryaku" },
+ { startingYear: 1081, japaneseName: 'æ°¸ä¿', romanizedName: "EihÅ" },
+ { startingYear: 1084, japaneseName: '応徳', romanizedName: "Ōtoku" },
+ { startingYear: 1087, japaneseName: '寛治', romanizedName: "Kanji" },
+ { startingYear: 1094, japaneseName: '嘉ä¿', romanizedName: "KahÅ" },
+ { startingYear: 1096, japaneseName: '永長', romanizedName: "EichÅ" },
+ { startingYear: 1097, japaneseName: '承徳', romanizedName: "JÅtoku" },
+ { startingYear: 1099, japaneseName: '康和', romanizedName: "KÅwa" },
+ { startingYear: 1104, japaneseName: 'é•·æ²»', romanizedName: "ChÅji" },
+ { startingYear: 1106, japaneseName: '嘉承', romanizedName: "KajÅ" },
+ { startingYear: 1108, japaneseName: '天ä»', romanizedName: "Tennin" },
+ { startingYear: 1110, japaneseName: '天永', romanizedName: "Ten'ei" },
+ { startingYear: 1113, japaneseName: '永久', romanizedName: "Eikyū" },
+ { startingYear: 1118, japaneseName: '元永', romanizedName: "Gen'ei" },
+ { startingYear: 1120, japaneseName: 'ä¿å®‰', romanizedName: "HÅan" },
+ { startingYear: 1124, japaneseName: '天治', romanizedName: "Tenji" },
+ { startingYear: 1126, japaneseName: '大治', romanizedName: "Daiji" },
+ { startingYear: 1131, japaneseName: '天承', romanizedName: "TenshÅ" },
+ { startingYear: 1132, japaneseName: '長承', romanizedName: "ChÅshÅ" },
+ { startingYear: 1135, japaneseName: 'ä¿å»¶', romanizedName: "HÅen" },
+ { startingYear: 1141, japaneseName: '永治', romanizedName: "Eiji" },
+ { startingYear: 1142, japaneseName: '康治', romanizedName: "KÅji" },
+ { startingYear: 1144, japaneseName: '天養', romanizedName: "Ten'yÅ" },
+ { startingYear: 1145, japaneseName: '久安', romanizedName: "Kyūan" },
+ { startingYear: 1151, japaneseName: 'ä»å¹³', romanizedName: "Ninpei" },
+ { startingYear: 1154, japaneseName: '久寿', romanizedName: "Kyūju" },
+ { startingYear: 1156, japaneseName: 'ä¿å…ƒ', romanizedName: "HÅgen" },
+ { startingYear: 1159, japaneseName: '平治', romanizedName: "Heiji" },
+ { startingYear: 1160, japaneseName: '永暦', romanizedName: "Eiryaku" },
+ { startingYear: 1161, japaneseName: 'å¿œä¿', romanizedName: "ÅŒhÅ" },
+ { startingYear: 1163, japaneseName: '長寛', romanizedName: "ChÅkan" },
+ { startingYear: 1165, japaneseName: '永万', romanizedName: "Eiman" },
+ { startingYear: 1166, japaneseName: 'ä»å®‰', romanizedName: "Ninnan" },
+ { startingYear: 1169, japaneseName: '嘉応', romanizedName: "KaÅ" },
+ { startingYear: 1171, japaneseName: '承安', romanizedName: "JÅan" },
+ { startingYear: 1175, japaneseName: '安元', romanizedName: "Angen" },
+ { startingYear: 1177, japaneseName: '治承', romanizedName: "JishÅ" },
+ { startingYear: 1181, japaneseName: '養和', romanizedName: "YÅwa" },
+ { startingYear: 1182, japaneseName: '寿永', romanizedName: "Juei" },
+ { startingYear: 1184, japaneseName: '元暦', romanizedName: "Genryaku" },
+ { startingYear: 1185, japaneseName: '文治', romanizedName: "Bunji" },
+ { startingYear: 1190, japaneseName: '建久', romanizedName: "Kenkyū" },
+ { startingYear: 1199, japaneseName: '正治', romanizedName: "ShÅji" },
+ { startingYear: 1201, japaneseName: '建ä»', romanizedName: "Kennin" },
+ { startingYear: 1204, japaneseName: '元久', romanizedName: "Genkyū" },
+ { startingYear: 1206, japaneseName: '建永', romanizedName: "Ken'ei" },
+ { startingYear: 1207, japaneseName: '承元', romanizedName: "JÅgen" },
+ { startingYear: 1211, japaneseName: '建暦', romanizedName: "Kenryaku" },
+ { startingYear: 1213, japaneseName: '建ä¿', romanizedName: "KenpÅ" },
+ { startingYear: 1219, japaneseName: '承久', romanizedName: "JÅkyÅ«" },
+ { startingYear: 1222, japaneseName: '貞応', romanizedName: "JÅÅ" },
+ { startingYear: 1224, japaneseName: 'å…ƒä»', romanizedName: "Gennin" },
+ { startingYear: 1225, japaneseName: '嘉禄', romanizedName: "Karoku" },
+ { startingYear: 1227, japaneseName: '安貞', romanizedName: "Antei" },
+ { startingYear: 1229, japaneseName: '寛喜', romanizedName: "Kanki" },
+ { startingYear: 1232, japaneseName: '貞永', romanizedName: "JÅei" },
+ { startingYear: 1233, japaneseName: '天ç¦', romanizedName: "Tenpuku" },
+ { startingYear: 1234, japaneseName: '文暦', romanizedName: "Bunryaku" },
+ { startingYear: 1235, japaneseName: '嘉禎', romanizedName: "Katei" },
+ { startingYear: 1238, japaneseName: '暦ä»', romanizedName: "Ryakunin" },
+ { startingYear: 1239, japaneseName: '延応', romanizedName: "En'Å" },
+ { startingYear: 1240, japaneseName: 'ä»æ²»', romanizedName: "Ninji" },
+ { startingYear: 1243, japaneseName: '寛元', romanizedName: "Kangen" },
+ { startingYear: 1247, japaneseName: 'å®æ²»', romanizedName: "HÅji" },
+ { startingYear: 1249, japaneseName: '建長', romanizedName: "KenchÅ" },
+ { startingYear: 1256, japaneseName: '康元', romanizedName: "KÅgen" },
+ { startingYear: 1257, japaneseName: '正嘉', romanizedName: "ShÅka" },
+ { startingYear: 1259, japaneseName: '正元', romanizedName: "ShÅgen" },
+ { startingYear: 1260, japaneseName: '文応', romanizedName: "Bun'Å" },
+ { startingYear: 1261, japaneseName: '弘長', romanizedName: "KÅcho" },
+ { startingYear: 1264, japaneseName: '文永', romanizedName: "Bun'ei" },
+ { startingYear: 1275, japaneseName: '建治', romanizedName: "Kenji" },
+ { startingYear: 1278, japaneseName: '弘安', romanizedName: "KÅan" },
+ { startingYear: 1288, japaneseName: '正応', romanizedName: "ShÅÅ" },
+ { startingYear: 1293, japaneseName: 'æ°¸ä»', romanizedName: "Einin" },
+ { startingYear: 1299, japaneseName: '正安', romanizedName: "ShÅan" },
+ { startingYear: 1302, japaneseName: '乾元', romanizedName: "Kengen" },
+ { startingYear: 1303, japaneseName: '嘉元', romanizedName: "Kagen" },
+ { startingYear: 1306, japaneseName: '徳治', romanizedName: "Tokuji" },
+ { startingYear: 1308, japaneseName: '延慶', romanizedName: "Enkei" },
+ { startingYear: 1311, japaneseName: '応長', romanizedName: "ÅŒchÅ" },
+ { startingYear: 1312, japaneseName: '正和', romanizedName: "ShÅwa" },
+ { startingYear: 1317, japaneseName: 'æ–‡ä¿', romanizedName: "BunpÅ" },
+ { startingYear: 1319, japaneseName: '元応', romanizedName: "Gen'Å" },
+ { startingYear: 1321, japaneseName: '元亨', romanizedName: "GenkyÅ" },
+ { startingYear: 1324, japaneseName: '正中', romanizedName: "ShÅchÅ«" },
+ { startingYear: 1326, japaneseName: '嘉暦', romanizedName: "Karyaku" },
+ { startingYear: 1329, japaneseName: '元徳', romanizedName: "Gentoku" },
+ { startingYear: 1331, japaneseName: '元弘', romanizedName: "GenkÅ" },
+ { startingYear: 1334, japaneseName: '建武', romanizedName: "Kenmu" },
+ { startingYear: 1336, japaneseName: '延元', romanizedName: "Engen" },
+ { startingYear: 1340, japaneseName: '興国', romanizedName: "KÅkoku" },
+ { startingYear: 1346, japaneseName: '正平', romanizedName: "ShÅhei" },
+ { startingYear: 1370, japaneseName: '建徳', romanizedName: "Kentoku" },
+ { startingYear: 1372, japaneseName: '文中', romanizedName: "Bunchū" },
+ { startingYear: 1375, japaneseName: '天授', romanizedName: "Tenju" },
+ { startingYear: 1381, japaneseName: '弘和', romanizedName: "KÅwa" },
+ { startingYear: 1384, japaneseName: '元中', romanizedName: "Genchū" },
+ { startingYear: 1332, japaneseName: '正慶', romanizedName: "ShÅkei" },
+ { startingYear: 1338, japaneseName: '暦応', romanizedName: "RyakuÅ" },
+ { startingYear: 1342, japaneseName: '康永', romanizedName: "KÅei" },
+ { startingYear: 1345, japaneseName: '貞和', romanizedName: "JÅwa" },
+ { startingYear: 1350, japaneseName: '観応', romanizedName: "Kan'Å" },
+ { startingYear: 1352, japaneseName: '文和', romanizedName: "Bunna" },
+ { startingYear: 1356, japaneseName: '延文', romanizedName: "Enbun" },
+ { startingYear: 1361, japaneseName: '康安', romanizedName: "KÅan" },
+ { startingYear: 1362, japaneseName: '貞治', romanizedName: "JÅji" },
+ { startingYear: 1368, japaneseName: '応安', romanizedName: "Ōan" },
+ { startingYear: 1375, japaneseName: '永和', romanizedName: "Eiwa" },
+ { startingYear: 1379, japaneseName: '康暦', romanizedName: "KÅryaku" },
+ { startingYear: 1381, japaneseName: '永徳', romanizedName: "Eitoku" },
+ { startingYear: 1384, japaneseName: '至徳', romanizedName: "Shitoku" },
+ { startingYear: 1387, japaneseName: '嘉慶', romanizedName: "Kakei" },
+ { startingYear: 1389, japaneseName: '康応', romanizedName: "KÅÅ" },
+ { startingYear: 1390, japaneseName: '明徳', romanizedName: "Meitoku" },
+ { startingYear: 1394, japaneseName: '応永', romanizedName: "Ōei" },
+ { startingYear: 1428, japaneseName: '正長', romanizedName: "ShÅchÅ" },
+ { startingYear: 1429, japaneseName: '永享', romanizedName: "EikyÅ" },
+ { startingYear: 1441, japaneseName: '嘉å‰', romanizedName: "Kakitsu" },
+ { startingYear: 1444, japaneseName: '文安', romanizedName: "Bunnan" },
+ { startingYear: 1449, japaneseName: 'å®å¾³', romanizedName: "HÅtoku" },
+ { startingYear: 1452, japaneseName: '享徳', romanizedName: "KyÅtoku" },
+ { startingYear: 1455, japaneseName: '康正', romanizedName: "KÅshÅ" },
+ { startingYear: 1457, japaneseName: '長禄', romanizedName: "ChÅroku" },
+ { startingYear: 1460, japaneseName: '寛正', romanizedName: "KanshÅ" },
+ { startingYear: 1466, japaneseName: '文正', romanizedName: "BunshÅ" },
+ { startingYear: 1467, japaneseName: 'å¿œä»', romanizedName: "ÅŒnin" },
+ { startingYear: 1469, japaneseName: '文明', romanizedName: "Bunmei" },
+ { startingYear: 1487, japaneseName: '長享', romanizedName: "ChÅkyÅ" },
+ { startingYear: 1489, japaneseName: '延徳', romanizedName: "Entoku" },
+ { startingYear: 1492, japaneseName: '明応', romanizedName: "MeiÅ" },
+ { startingYear: 1501, japaneseName: '文亀', romanizedName: "Bunki" },
+ { startingYear: 1504, japaneseName: '永正', romanizedName: "EishÅ" },
+ { startingYear: 1521, japaneseName: '大永', romanizedName: "Daiei" },
+ { startingYear: 1528, japaneseName: '享禄', romanizedName: "KyÅroku" },
+ { startingYear: 1532, japaneseName: '天文', romanizedName: "Tenbun" },
+ { startingYear: 1555, japaneseName: '弘治', romanizedName: "KÅji" },
+ { startingYear: 1558, japaneseName: '永禄', romanizedName: "Eiroku" },
+ { startingYear: 1570, japaneseName: '元亀', romanizedName: "Genki" },
+ { startingYear: 1573, japaneseName: '天正', romanizedName: "TenshÅ" },
+ { startingYear: 1592, japaneseName: '文禄', romanizedName: "Bunroku" },
+ { startingYear: 1596, japaneseName: '慶長', romanizedName: "KeichÅ" },
+ { startingYear: 1615, japaneseName: '元和', romanizedName: "Genna" },
+ { startingYear: 1624, japaneseName: '寛永', romanizedName: "Kan'ei" },
+ { startingYear: 1644, japaneseName: 'æ­£ä¿', romanizedName: "ShÅhÅ" },
+ { startingYear: 1648, japaneseName: '慶安', romanizedName: "Keian" },
+ { startingYear: 1652, japaneseName: '承応', romanizedName: "JÅÅ" },
+ { startingYear: 1655, japaneseName: '明暦', romanizedName: "Meireki" },
+ { startingYear: 1658, japaneseName: '万治', romanizedName: "Manji" },
+ { startingYear: 1661, japaneseName: '寛文', romanizedName: "Kanbun" },
+ { startingYear: 1673, japaneseName: '延å®', romanizedName: "EnpÅ" },
+ { startingYear: 1681, japaneseName: '天和', romanizedName: "Tenna" },
+ { startingYear: 1684, japaneseName: '貞享', romanizedName: "JÅkyÅ" },
+ { startingYear: 1688, japaneseName: '元禄', romanizedName: "Genroku" },
+ { startingYear: 1704, japaneseName: 'å®æ°¸', romanizedName: "HÅei" },
+ { startingYear: 1711, japaneseName: '正徳', romanizedName: "ShÅtoku" },
+ { startingYear: 1716, japaneseName: '享ä¿', romanizedName: "KyÅhÅ" },
+ { startingYear: 1736, japaneseName: '元文', romanizedName: "Genbun" },
+ { startingYear: 1741, japaneseName: '寛ä¿', romanizedName: "KanpÅ" },
+ { startingYear: 1744, japaneseName: '延享', romanizedName: "EnkyÅ" },
+ { startingYear: 1748, japaneseName: '寛延', romanizedName: "Kan'en" },
+ { startingYear: 1751, japaneseName: 'å®æš¦', romanizedName: "HÅreki" },
+ { startingYear: 1764, japaneseName: '明和', romanizedName: "Meiwa" },
+ { startingYear: 1772, japaneseName: '安永', romanizedName: "An'ei" },
+ { startingYear: 1781, japaneseName: '天明', romanizedName: "Tenmei" },
+ { startingYear: 1789, japaneseName: '寛政', romanizedName: "Kansei" },
+ { startingYear: 1801, japaneseName: '享和', romanizedName: "KyÅwa" },
+ { startingYear: 1804, japaneseName: '文化', romanizedName: "Bunka" },
+ { startingYear: 1818, japaneseName: '文政', romanizedName: "Bunsei" },
+ { startingYear: 1830, japaneseName: '天ä¿', romanizedName: "TenpÅ" },
+ { startingYear: 1844, japaneseName: '弘化', romanizedName: "KÅka" },
+ { startingYear: 1848, japaneseName: '嘉永', romanizedName: "Kaei" },
+ { startingYear: 1854, japaneseName: '安政', romanizedName: "Ansei" },
+ { startingYear: 1860, japaneseName: '万延', romanizedName: "Man'en" },
+ { startingYear: 1861, japaneseName: '文久', romanizedName: "Bunkyū" },
+ { startingYear: 1864, japaneseName: '元治', romanizedName: "Genji" },
+ { startingYear: 1865, japaneseName: '慶応', romanizedName: "KeiÅ" },
+ { startingYear: 1868, japaneseName: '明治', romanizedName: "Meiji" },
+ { startingYear: 1912, japaneseName: '大正', romanizedName: "TaishÅ" },
+ { startingYear: 1926, japaneseName: '昭和', romanizedName: "ShÅwa" },
+ { startingYear: 1989, japaneseName: 'å¹³æˆ', romanizedName: "Heisei" }
+ ]
+);
diff --git a/site/app/webroot/js/simile/timeline/scripts/l10n/cs/labellers.js b/site/app/webroot/js/simile/timeline/scripts/l10n/cs/labellers.js
new file mode 100755
index 0000000..954c7a8
--- /dev/null
+++ b/site/app/webroot/js/simile/timeline/scripts/l10n/cs/labellers.js
@@ -0,0 +1,30 @@
+/*==================================================
+ * Localization of labellers.js
+ *==================================================
+ */
+
+Timeline.GregorianDateLabeller.monthNames["cs"] = [
+ "Leden", "Únor", "Bøezen", "Duben", "Kvìten", "Èerven", "Èervenec", "Srpen", "Záøí", "Øíjen", "Listopad", "Prosinec"
+];
+
+Timeline.GregorianDateLabeller.dayNames["cs"] = [
+ "Ne", "Po", "Út", "St", "Èt", "Pá", "So"
+];
+
+Timeline.GregorianDateLabeller.labelIntervalFunctions["cs"] = function(date, intervalUnit) {
+ var text;
+ var emphasized = false;
+
+ var date2 = Timeline.DateTime.removeTimeZoneOffset(date, this._timeZone);
+
+ switch(intervalUnit) {
+ case Timeline.DateTime.DAY:
+ case Timeline.DateTime.WEEK:
+ text = date2.getUTCDate() + ". " + (date2.getUTCMonth() + 1) + ".";
+ break;
+ default:
+ return this.defaultLabelInterval(date, intervalUnit);
+ }
+
+ return { text: text, emphasized: emphasized };
+};
diff --git a/site/app/webroot/js/simile/timeline/scripts/l10n/cs/timeline.js b/site/app/webroot/js/simile/timeline/scripts/l10n/cs/timeline.js
new file mode 100755
index 0000000..d823a51
--- /dev/null
+++ b/site/app/webroot/js/simile/timeline/scripts/l10n/cs/timeline.js
@@ -0,0 +1,9 @@
+/*==================================================
+ * Common localization strings
+ *==================================================
+ */
+
+Timeline.strings["cs"] = {
+ wikiLinkLabel: "Diskuze"
+};
+
diff --git a/site/app/webroot/js/simile/timeline/scripts/l10n/de/labellers.js b/site/app/webroot/js/simile/timeline/scripts/l10n/de/labellers.js
new file mode 100755
index 0000000..f0eb7df
--- /dev/null
+++ b/site/app/webroot/js/simile/timeline/scripts/l10n/de/labellers.js
@@ -0,0 +1,27 @@
+/*==================================================
+ * Localization of labellers.js
+ *==================================================
+ */
+
+Timeline.GregorianDateLabeller.monthNames["de"] = [
+ "Jan", "Feb", "Mrz", "Apr", "Mai", "Jun", "Jul", "Aug", "Sep", "Okt", "Nov", "Dez"
+];
+
+Timeline.GregorianDateLabeller.labelIntervalFunctions["de"] = function(date, intervalUnit) {
+ var text;
+ var emphasized = false;
+
+ var date2 = Timeline.DateTime.removeTimeZoneOffset(date, this._timeZone);
+
+ switch(intervalUnit) {
+ case Timeline.DateTime.DAY:
+ case Timeline.DateTime.WEEK:
+ text = date2.getUTCDate() + ". " +
+ Timeline.GregorianDateLabeller.getMonthName(date2.getUTCMonth(), this._locale);
+ break;
+ default:
+ return this.defaultLabelInterval(date, intervalUnit);
+ }
+
+ return { text: text, emphasized: emphasized };
+}; \ No newline at end of file
diff --git a/site/app/webroot/js/simile/timeline/scripts/l10n/de/timeline.js b/site/app/webroot/js/simile/timeline/scripts/l10n/de/timeline.js
new file mode 100755
index 0000000..7292cef
--- /dev/null
+++ b/site/app/webroot/js/simile/timeline/scripts/l10n/de/timeline.js
@@ -0,0 +1,8 @@
+/*==================================================
+ * Common localization strings
+ *==================================================
+ */
+
+Timeline.strings["de"] = {
+ wikiLinkLabel: "Diskutieren"
+};
diff --git a/site/app/webroot/js/simile/timeline/scripts/l10n/en/labellers.js b/site/app/webroot/js/simile/timeline/scripts/l10n/en/labellers.js
new file mode 100755
index 0000000..3f1beb6
--- /dev/null
+++ b/site/app/webroot/js/simile/timeline/scripts/l10n/en/labellers.js
@@ -0,0 +1,8 @@
+/*==================================================
+ * Localization of labellers.js
+ *==================================================
+ */
+
+Timeline.GregorianDateLabeller.monthNames["en"] = [
+ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
+];
diff --git a/site/app/webroot/js/simile/timeline/scripts/l10n/en/timeline.js b/site/app/webroot/js/simile/timeline/scripts/l10n/en/timeline.js
new file mode 100755
index 0000000..c6b70dd
--- /dev/null
+++ b/site/app/webroot/js/simile/timeline/scripts/l10n/en/timeline.js
@@ -0,0 +1,9 @@
+/*==================================================
+ * Common localization strings
+ *==================================================
+ */
+
+Timeline.strings["en"] = {
+ wikiLinkLabel: "Discuss"
+};
+
diff --git a/site/app/webroot/js/simile/timeline/scripts/l10n/es/labellers.js b/site/app/webroot/js/simile/timeline/scripts/l10n/es/labellers.js
new file mode 100755
index 0000000..963038e
--- /dev/null
+++ b/site/app/webroot/js/simile/timeline/scripts/l10n/es/labellers.js
@@ -0,0 +1,8 @@
+/*==================================================
+ * Localization of labellers.js
+ *==================================================
+ */
+
+Timeline.GregorianDateLabeller.monthNames["es"] = [
+ "Ene", "Feb", "Mar", "Abr", "May", "Jun", "Jul", "Ago", "Sep", "Oct", "Nov", "Dic"
+];
diff --git a/site/app/webroot/js/simile/timeline/scripts/l10n/es/timeline.js b/site/app/webroot/js/simile/timeline/scripts/l10n/es/timeline.js
new file mode 100755
index 0000000..2a5183c
--- /dev/null
+++ b/site/app/webroot/js/simile/timeline/scripts/l10n/es/timeline.js
@@ -0,0 +1,9 @@
+/*==================================================
+ * Common localization strings
+ *==================================================
+ */
+
+Timeline.strings["es"] = {
+ wikiLinkLabel: "Discute"
+};
+
diff --git a/site/app/webroot/js/simile/timeline/scripts/l10n/fr/labellers.js b/site/app/webroot/js/simile/timeline/scripts/l10n/fr/labellers.js
new file mode 100755
index 0000000..5e7392a
--- /dev/null
+++ b/site/app/webroot/js/simile/timeline/scripts/l10n/fr/labellers.js
@@ -0,0 +1,8 @@
+/*==================================================
+ * Localization of labellers.js
+ *==================================================
+ */
+
+Timeline.GregorianDateLabeller.monthNames["fr"] = [
+ "jan", "fev", "mar", "avr", "mai", "jui", "jui", "aou", "sep", "oct", "nov", "dec"
+];
diff --git a/site/app/webroot/js/simile/timeline/scripts/l10n/fr/timeline.js b/site/app/webroot/js/simile/timeline/scripts/l10n/fr/timeline.js
new file mode 100755
index 0000000..459cc38
--- /dev/null
+++ b/site/app/webroot/js/simile/timeline/scripts/l10n/fr/timeline.js
@@ -0,0 +1,9 @@
+/*==================================================
+ * Common localization strings
+ *==================================================
+ */
+
+Timeline.strings["fr"] = {
+ wikiLinkLabel: "Discute"
+};
+
diff --git a/site/app/webroot/js/simile/timeline/scripts/l10n/it/labellers.js b/site/app/webroot/js/simile/timeline/scripts/l10n/it/labellers.js
new file mode 100755
index 0000000..85d50d4
--- /dev/null
+++ b/site/app/webroot/js/simile/timeline/scripts/l10n/it/labellers.js
@@ -0,0 +1,8 @@
+/*==================================================
+ * Localization of labellers.js
+ *==================================================
+ */
+
+Timeline.GregorianDateLabeller.monthNames["it"] = [
+ "Gen", "Feb", "Mar", "Apr", "Mag", "Giu", "Lug", "Ago", "Set", "Ott", "Nov", "Dic"
+];
diff --git a/site/app/webroot/js/simile/timeline/scripts/l10n/it/timeline.js b/site/app/webroot/js/simile/timeline/scripts/l10n/it/timeline.js
new file mode 100755
index 0000000..69582dc
--- /dev/null
+++ b/site/app/webroot/js/simile/timeline/scripts/l10n/it/timeline.js
@@ -0,0 +1,9 @@
+/*==================================================
+ * Common localization strings
+ *==================================================
+ */
+
+Timeline.strings["it"] = {
+ wikiLinkLabel: "Discuti"
+};
+
diff --git a/site/app/webroot/js/simile/timeline/scripts/l10n/ru/labellers.js b/site/app/webroot/js/simile/timeline/scripts/l10n/ru/labellers.js
new file mode 100755
index 0000000..b7545d6
--- /dev/null
+++ b/site/app/webroot/js/simile/timeline/scripts/l10n/ru/labellers.js
@@ -0,0 +1,10 @@
+/*==================================================
+ * Localization of labellers.js
+ *
+ * UTF-8 encoded
+ *==================================================
+ */
+
+Timeline.GregorianDateLabeller.monthNames["ru"] = [
+ "Янв", "Фев", "Мар", "Ðпр", "Май", "Июн", "Июл", "Ðвг", "Сен", "Окт", "ÐоÑ", "Дек"
+];
diff --git a/site/app/webroot/js/simile/timeline/scripts/l10n/ru/timeline.js b/site/app/webroot/js/simile/timeline/scripts/l10n/ru/timeline.js
new file mode 100755
index 0000000..af5fcc7
--- /dev/null
+++ b/site/app/webroot/js/simile/timeline/scripts/l10n/ru/timeline.js
@@ -0,0 +1,9 @@
+/*==================================================
+ * Common localization strings
+ *==================================================
+ */
+
+Timeline.strings["ru"] = {
+ wikiLinkLabel: "обÑудите"
+};
+
diff --git a/site/app/webroot/js/simile/timeline/scripts/l10n/se/labellers.js b/site/app/webroot/js/simile/timeline/scripts/l10n/se/labellers.js
new file mode 100755
index 0000000..378cda1
--- /dev/null
+++ b/site/app/webroot/js/simile/timeline/scripts/l10n/se/labellers.js
@@ -0,0 +1,12 @@
+/*==================================================
+ * Localization of labellers.js
+ *==================================================
+ */
+
+Timeline.GregorianDateLabeller.monthNames["se"] = [
+ "Jan", "Feb", "Mar", "Apr", "Maj", "Jun", "Jul", "Aug", "Sep", "Okt", "Nov", "Dec"
+];
+
+Timeline.GregorianDateLabeller.dayNames["se"] = [
+ "Sön", "Mån", "Tis", "Ons", "Tors", "Fre", "Lör"
+];
diff --git a/site/app/webroot/js/simile/timeline/scripts/l10n/se/timeline.js b/site/app/webroot/js/simile/timeline/scripts/l10n/se/timeline.js
new file mode 100755
index 0000000..31751ac
--- /dev/null
+++ b/site/app/webroot/js/simile/timeline/scripts/l10n/se/timeline.js
@@ -0,0 +1,9 @@
+/*==================================================
+ * Common localization strings
+ *==================================================
+ */
+
+Timeline.strings["se"] = {
+ wikiLinkLabel: "Discuss"
+};
+
diff --git a/site/app/webroot/js/simile/timeline/scripts/l10n/tr/labellers.js b/site/app/webroot/js/simile/timeline/scripts/l10n/tr/labellers.js
new file mode 100755
index 0000000..5d4dd72
--- /dev/null
+++ b/site/app/webroot/js/simile/timeline/scripts/l10n/tr/labellers.js
@@ -0,0 +1,8 @@
+/*==================================================
+ * Localization of labellers.js
+ *==================================================
+ */
+
+Timeline.GregorianDateLabeller.monthNames["tr"] = [
+ "Ock", "Åžbt", "Mrt", "Nsn", "Mys", "Hzr", "Tem", "AÄŸs", "Eyl", "Ekm", "Ksm", "Arl"
+];
diff --git a/site/app/webroot/js/simile/timeline/scripts/l10n/tr/timeline.js b/site/app/webroot/js/simile/timeline/scripts/l10n/tr/timeline.js
new file mode 100755
index 0000000..696dc34
--- /dev/null
+++ b/site/app/webroot/js/simile/timeline/scripts/l10n/tr/timeline.js
@@ -0,0 +1,9 @@
+/*==================================================
+ * Common localization strings
+ *==================================================
+ */
+
+Timeline.strings["tr"] = {
+ wikiLinkLabel: "Tartış"
+};
+
diff --git a/site/app/webroot/js/simile/timeline/scripts/l10n/vi/labellers.js b/site/app/webroot/js/simile/timeline/scripts/l10n/vi/labellers.js
new file mode 100755
index 0000000..85994d0
--- /dev/null
+++ b/site/app/webroot/js/simile/timeline/scripts/l10n/vi/labellers.js
@@ -0,0 +1,26 @@
+/*==================================================
+ * Localization of labellers.js
+ *==================================================
+ */
+
+Timeline.GregorianDateLabeller.monthNames["vi"] = [
+ "Tháng 1", "Tháng 2", "Tháng 3", "Tháng 4", "Tháng 5", "Tháng 6", "Tháng 7", "Tháng 8", "Tháng 9", "Tháng 10", "Tháng 11", "Tháng 12"
+];
+
+Timeline.GregorianDateLabeller.labelIntervalFunctions["vi"] = function(date, intervalUnit) {
+ var text;
+ var emphasized = false;
+
+ var date2 = Timeline.DateTime.removeTimeZoneOffset(date, this._timeZone);
+
+ switch(intervalUnit) {
+ case Timeline.DateTime.DAY:
+ case Timeline.DateTime.WEEK:
+ text = date2.getUTCDate() + "/" + (date2.getUTCMonth() + 1);
+ break;
+ default:
+ return this.defaultLabelInterval(date, intervalUnit);
+ }
+
+ return { text: text, emphasized: emphasized };
+};
diff --git a/site/app/webroot/js/simile/timeline/scripts/l10n/vi/timeline.js b/site/app/webroot/js/simile/timeline/scripts/l10n/vi/timeline.js
new file mode 100755
index 0000000..a67befc
--- /dev/null
+++ b/site/app/webroot/js/simile/timeline/scripts/l10n/vi/timeline.js
@@ -0,0 +1,9 @@
+/*==================================================
+ * Common localization strings
+ *==================================================
+ */
+
+Timeline.strings["vi"] = {
+ wikiLinkLabel: "Bàn luận"
+};
+
diff --git a/site/app/webroot/js/simile/timeline/scripts/l10n/zh/labellers.js b/site/app/webroot/js/simile/timeline/scripts/l10n/zh/labellers.js
new file mode 100755
index 0000000..599f2d1
--- /dev/null
+++ b/site/app/webroot/js/simile/timeline/scripts/l10n/zh/labellers.js
@@ -0,0 +1,27 @@
+/*==================================================
+ * Localization of labellers.js
+ *==================================================
+ */
+
+Timeline.GregorianDateLabeller.monthNames["zh"] = [
+ "1月", "2月", "3月", "4月", "5月", "6月", "7月", "8月", "9月", "10月", "11月", "12月"
+];
+
+Timeline.GregorianDateLabeller.labelIntervalFunctions["zh"] = function(date, intervalUnit) {
+ var text;
+ var emphasized = false;
+
+ var date2 = Timeline.DateTime.removeTimeZoneOffset(date, this._timeZone);
+
+ switch(intervalUnit) {
+ case Timeline.DateTime.DAY:
+ case Timeline.DateTime.WEEK:
+ text = Timeline.GregorianDateLabeller.getMonthName(date2.getUTCMonth(), this._locale) +
+ date2.getUTCDate() + "æ—¥";
+ break;
+ default:
+ return this.defaultLabelInterval(date, intervalUnit);
+ }
+
+ return { text: text, emphasized: emphasized };
+}; \ No newline at end of file
diff --git a/site/app/webroot/js/simile/timeline/scripts/l10n/zh/timeline.js b/site/app/webroot/js/simile/timeline/scripts/l10n/zh/timeline.js
new file mode 100755
index 0000000..9488492
--- /dev/null
+++ b/site/app/webroot/js/simile/timeline/scripts/l10n/zh/timeline.js
@@ -0,0 +1,9 @@
+/*==================================================
+ * Common localization strings
+ *==================================================
+ */
+
+Timeline.strings["zh"] = {
+ wikiLinkLabel: "讨论"
+};
+
diff --git a/site/app/webroot/js/simile/timeline/scripts/labellers.js b/site/app/webroot/js/simile/timeline/scripts/labellers.js
new file mode 100755
index 0000000..4ac874c
--- /dev/null
+++ b/site/app/webroot/js/simile/timeline/scripts/labellers.js
@@ -0,0 +1,91 @@
+/*==================================================
+ * Gregorian Date Labeller
+ *==================================================
+ */
+
+Timeline.GregorianDateLabeller = function(locale, timeZone) {
+ this._locale = locale;
+ this._timeZone = timeZone;
+};
+
+Timeline.GregorianDateLabeller.monthNames = [];
+Timeline.GregorianDateLabeller.dayNames = [];
+Timeline.GregorianDateLabeller.labelIntervalFunctions = [];
+
+Timeline.GregorianDateLabeller.getMonthName = function(month, locale) {
+ return Timeline.GregorianDateLabeller.monthNames[locale][month];
+};
+
+Timeline.GregorianDateLabeller.prototype.labelInterval = function(date, intervalUnit) {
+ var f = Timeline.GregorianDateLabeller.labelIntervalFunctions[this._locale];
+ if (f == null) {
+ f = Timeline.GregorianDateLabeller.prototype.defaultLabelInterval;
+ }
+ return f.call(this, date, intervalUnit);
+};
+
+Timeline.GregorianDateLabeller.prototype.labelPrecise = function(date) {
+ return SimileAjax.DateTime.removeTimeZoneOffset(
+ date,
+ this._timeZone //+ (new Date().getTimezoneOffset() / 60)
+ ).toUTCString();
+};
+
+Timeline.GregorianDateLabeller.prototype.defaultLabelInterval = function(date, intervalUnit) {
+ var text;
+ var emphasized = false;
+
+ date = SimileAjax.DateTime.removeTimeZoneOffset(date, this._timeZone);
+
+ switch(intervalUnit) {
+ case SimileAjax.DateTime.MILLISECOND:
+ text = date.getUTCMilliseconds();
+ break;
+ case SimileAjax.DateTime.SECOND:
+ text = date.getUTCSeconds();
+ break;
+ case SimileAjax.DateTime.MINUTE:
+ var m = date.getUTCMinutes();
+ if (m == 0) {
+ text = date.getUTCHours() + ":00";
+ emphasized = true;
+ } else {
+ text = m;
+ }
+ break;
+ case SimileAjax.DateTime.HOUR:
+ text = date.getUTCHours() + "hr";
+ break;
+ case SimileAjax.DateTime.DAY:
+ text = Timeline.GregorianDateLabeller.getMonthName(date.getUTCMonth(), this._locale) + " " + date.getUTCDate();
+ break;
+ case SimileAjax.DateTime.WEEK:
+ text = Timeline.GregorianDateLabeller.getMonthName(date.getUTCMonth(), this._locale) + " " + date.getUTCDate();
+ break;
+ case SimileAjax.DateTime.MONTH:
+ var m = date.getUTCMonth();
+ if (m != 0) {
+ text = Timeline.GregorianDateLabeller.getMonthName(m, this._locale);
+ break;
+ } // else, fall through
+ case SimileAjax.DateTime.YEAR:
+ case SimileAjax.DateTime.DECADE:
+ case SimileAjax.DateTime.CENTURY:
+ case SimileAjax.DateTime.MILLENNIUM:
+ var y = date.getUTCFullYear();
+ if (y > 0) {
+ text = date.getUTCFullYear();
+ } else {
+ text = (1 - y) + "BC";
+ }
+ emphasized =
+ (intervalUnit == SimileAjax.DateTime.MONTH) ||
+ (intervalUnit == SimileAjax.DateTime.DECADE && y % 100 == 0) ||
+ (intervalUnit == SimileAjax.DateTime.CENTURY && y % 1000 == 0);
+ break;
+ default:
+ text = date.toUTCString();
+ }
+ return { text: text, emphasized: emphasized };
+}
+
diff --git a/site/app/webroot/js/simile/timeline/scripts/original-painter.js b/site/app/webroot/js/simile/timeline/scripts/original-painter.js
new file mode 100755
index 0000000..3410299
--- /dev/null
+++ b/site/app/webroot/js/simile/timeline/scripts/original-painter.js
@@ -0,0 +1,488 @@
+/*==================================================
+ * Original Event Painter
+ *==================================================
+ */
+
+Timeline.OriginalEventPainter = function(params) {
+ this._params = params;
+ this._onSelectListeners = [];
+
+ this._filterMatcher = null;
+ this._highlightMatcher = null;
+ this._frc = null;
+
+ this._eventIdToElmt = {};
+};
+
+Timeline.OriginalEventPainter.prototype.initialize = function(band, timeline) {
+ this._band = band;
+ this._timeline = timeline;
+
+ this._backLayer = null;
+ this._eventLayer = null;
+ this._lineLayer = null;
+ this._highlightLayer = null;
+
+ this._eventIdToElmt = null;
+};
+
+Timeline.OriginalEventPainter.prototype.addOnSelectListener = function(listener) {
+ this._onSelectListeners.push(listener);
+};
+
+Timeline.OriginalEventPainter.prototype.removeOnSelectListener = function(listener) {
+ for (var i = 0; i < this._onSelectListeners.length; i++) {
+ if (this._onSelectListeners[i] == listener) {
+ this._onSelectListeners.splice(i, 1);
+ break;
+ }
+ }
+};
+
+Timeline.OriginalEventPainter.prototype.getFilterMatcher = function() {
+ return this._filterMatcher;
+};
+
+Timeline.OriginalEventPainter.prototype.setFilterMatcher = function(filterMatcher) {
+ this._filterMatcher = filterMatcher;
+};
+
+Timeline.OriginalEventPainter.prototype.getHighlightMatcher = function() {
+ return this._highlightMatcher;
+};
+
+Timeline.OriginalEventPainter.prototype.setHighlightMatcher = function(highlightMatcher) {
+ this._highlightMatcher = highlightMatcher;
+};
+
+Timeline.OriginalEventPainter.prototype.paint = function() {
+ var eventSource = this._band.getEventSource();
+ if (eventSource == null) {
+ return;
+ }
+
+ this._eventIdToElmt = {};
+ this._prepareForPainting();
+
+ var eventTheme = this._params.theme.event;
+ var trackHeight = Math.max(eventTheme.track.height, eventTheme.tape.height + this._frc.getLineHeight());
+ var metrics = {
+ trackOffset: eventTheme.track.gap,
+ trackHeight: trackHeight,
+ trackGap: eventTheme.track.gap,
+ trackIncrement: trackHeight + eventTheme.track.gap,
+ icon: eventTheme.instant.icon,
+ iconWidth: eventTheme.instant.iconWidth,
+ iconHeight: eventTheme.instant.iconHeight,
+ labelWidth: eventTheme.label.width
+ }
+
+ var minDate = this._band.getMinDate();
+ var maxDate = this._band.getMaxDate();
+
+ var filterMatcher = (this._filterMatcher != null) ?
+ this._filterMatcher :
+ function(evt) { return true; };
+ var highlightMatcher = (this._highlightMatcher != null) ?
+ this._highlightMatcher :
+ function(evt) { return -1; };
+
+ var iterator = eventSource.getEventReverseIterator(minDate, maxDate);
+ while (iterator.hasNext()) {
+ var evt = iterator.next();
+ if (filterMatcher(evt)) {
+ this.paintEvent(evt, metrics, this._params.theme, highlightMatcher(evt));
+ }
+ }
+
+ this._highlightLayer.style.display = "block";
+ this._lineLayer.style.display = "block";
+ this._eventLayer.style.display = "block";
+};
+
+Timeline.OriginalEventPainter.prototype.softPaint = function() {
+};
+
+Timeline.OriginalEventPainter.prototype._prepareForPainting = function() {
+ var band = this._band;
+
+ if (this._backLayer == null) {
+ this._backLayer = this._band.createLayerDiv(0, "timeline-band-events");
+ this._backLayer.style.visibility = "hidden";
+
+ var eventLabelPrototype = document.createElement("span");
+ eventLabelPrototype.className = "timeline-event-label";
+ this._backLayer.appendChild(eventLabelPrototype);
+ this._frc = SimileAjax.Graphics.getFontRenderingContext(eventLabelPrototype);
+ }
+ this._frc.update();
+ this._tracks = [];
+
+ if (this._highlightLayer != null) {
+ band.removeLayerDiv(this._highlightLayer);
+ }
+ this._highlightLayer = band.createLayerDiv(105, "timeline-band-highlights");
+ this._highlightLayer.style.display = "none";
+
+ if (this._lineLayer != null) {
+ band.removeLayerDiv(this._lineLayer);
+ }
+ this._lineLayer = band.createLayerDiv(110, "timeline-band-lines");
+ this._lineLayer.style.display = "none";
+
+ if (this._eventLayer != null) {
+ band.removeLayerDiv(this._eventLayer);
+ }
+ this._eventLayer = band.createLayerDiv(115, "timeline-band-events");
+ this._eventLayer.style.display = "none";
+};
+
+Timeline.OriginalEventPainter.prototype.paintEvent = function(evt, metrics, theme, highlightIndex) {
+ if (evt.isInstant()) {
+ this.paintInstantEvent(evt, metrics, theme, highlightIndex);
+ } else {
+ this.paintDurationEvent(evt, metrics, theme, highlightIndex);
+ }
+};
+
+Timeline.OriginalEventPainter.prototype.paintInstantEvent = function(evt, metrics, theme, highlightIndex) {
+ if (evt.isImprecise()) {
+ this.paintImpreciseInstantEvent(evt, metrics, theme, highlightIndex);
+ } else {
+ this.paintPreciseInstantEvent(evt, metrics, theme, highlightIndex);
+ }
+}
+
+Timeline.OriginalEventPainter.prototype.paintDurationEvent = function(evt, metrics, theme, highlightIndex) {
+ if (evt.isImprecise()) {
+ this.paintImpreciseDurationEvent(evt, metrics, theme, highlightIndex);
+ } else {
+ this.paintPreciseDurationEvent(evt, metrics, theme, highlightIndex);
+ }
+}
+
+Timeline.OriginalEventPainter.prototype.paintPreciseInstantEvent = function(evt, metrics, theme, highlightIndex) {
+ var doc = this._timeline.getDocument();
+ var text = evt.getText();
+
+ var startDate = evt.getStart();
+ var startPixel = Math.round(this._band.dateToPixelOffset(startDate));
+ var iconRightEdge = Math.round(startPixel + metrics.iconWidth / 2);
+ var iconLeftEdge = Math.round(startPixel - metrics.iconWidth / 2);
+
+ var labelSize = this._frc.computeSize(text);
+ var labelLeft = iconRightEdge + theme.event.label.offsetFromLine;
+ var labelRight = labelLeft + labelSize.width;
+
+ var rightEdge = labelRight;
+ var track = this._findFreeTrack(rightEdge);
+
+ var labelTop = Math.round(
+ metrics.trackOffset + track * metrics.trackIncrement +
+ metrics.trackHeight / 2 - labelSize.height / 2);
+
+ var iconElmtData = this._paintEventIcon(evt, track, iconLeftEdge, metrics, theme);
+ var labelElmtData = this._paintEventLabel(evt, text, labelLeft, labelTop, labelSize.width, labelSize.height, theme);
+
+ var self = this;
+ var clickHandler = function(elmt, domEvt, target) {
+ return self._onClickInstantEvent(iconElmtData.elmt, domEvt, evt);
+ };
+ SimileAjax.DOM.registerEvent(iconElmtData.elmt, "mousedown", clickHandler);
+ SimileAjax.DOM.registerEvent(labelElmtData.elmt, "mousedown", clickHandler);
+
+ this._createHighlightDiv(highlightIndex, iconElmtData, theme);
+
+ this._eventIdToElmt[evt.getID()] = iconElmtData.elmt;
+ this._tracks[track] = iconLeftEdge;
+};
+
+Timeline.OriginalEventPainter.prototype.paintImpreciseInstantEvent = function(evt, metrics, theme, highlightIndex) {
+ var doc = this._timeline.getDocument();
+ var text = evt.getText();
+
+ var startDate = evt.getStart();
+ var endDate = evt.getEnd();
+ var startPixel = Math.round(this._band.dateToPixelOffset(startDate));
+ var endPixel = Math.round(this._band.dateToPixelOffset(endDate));
+
+ var iconRightEdge = Math.round(startPixel + metrics.iconWidth / 2);
+ var iconLeftEdge = Math.round(startPixel - metrics.iconWidth / 2);
+
+ var labelSize = this._frc.computeSize(text);
+ var labelLeft = iconRightEdge + theme.event.label.offsetFromLine;
+ var labelRight = labelLeft + labelSize.width;
+
+ var rightEdge = Math.max(labelRight, endPixel);
+ var track = this._findFreeTrack(rightEdge);
+ var labelTop = Math.round(
+ metrics.trackOffset + track * metrics.trackIncrement +
+ metrics.trackHeight / 2 - labelSize.height / 2);
+
+ var iconElmtData = this._paintEventIcon(evt, track, iconLeftEdge, metrics, theme);
+ var labelElmtData = this._paintEventLabel(evt, text, labelLeft, labelTop, labelSize.width, labelSize.height, theme);
+ var tapeElmtData = this._paintEventTape(evt, track, startPixel, endPixel,
+ theme.event.instant.impreciseColor, theme.event.instant.impreciseOpacity, metrics, theme);
+
+ var self = this;
+ var clickHandler = function(elmt, domEvt, target) {
+ return self._onClickInstantEvent(iconElmtData.elmt, domEvt, evt);
+ };
+ SimileAjax.DOM.registerEvent(iconElmtData.elmt, "mousedown", clickHandler);
+ SimileAjax.DOM.registerEvent(tapeElmtData.elmt, "mousedown", clickHandler);
+ SimileAjax.DOM.registerEvent(labelElmtData.elmt, "mousedown", clickHandler);
+
+ this._createHighlightDiv(highlightIndex, iconElmtData, theme);
+
+ this._eventIdToElmt[evt.getID()] = iconElmtData.elmt;
+ this._tracks[track] = iconLeftEdge;
+};
+
+Timeline.OriginalEventPainter.prototype.paintPreciseDurationEvent = function(evt, metrics, theme, highlightIndex) {
+ var doc = this._timeline.getDocument();
+ var text = evt.getText();
+
+ var startDate = evt.getStart();
+ var endDate = evt.getEnd();
+ var startPixel = Math.round(this._band.dateToPixelOffset(startDate));
+ var endPixel = Math.round(this._band.dateToPixelOffset(endDate));
+
+ var labelSize = this._frc.computeSize(text);
+ var labelLeft = startPixel;
+ var labelRight = labelLeft + labelSize.width;
+
+ var rightEdge = Math.max(labelRight, endPixel);
+ var track = this._findFreeTrack(rightEdge);
+ var labelTop = Math.round(
+ metrics.trackOffset + track * metrics.trackIncrement + theme.event.tape.height);
+
+ var color = evt.getColor();
+ color = color != null ? color : theme.event.duration.color;
+
+ var tapeElmtData = this._paintEventTape(evt, track, startPixel, endPixel, color, 100, metrics, theme);
+ var labelElmtData = this._paintEventLabel(evt, text, labelLeft, labelTop, labelSize.width, labelSize.height, theme);
+
+ var self = this;
+ var clickHandler = function(elmt, domEvt, target) {
+ return self._onClickInstantEvent(tapeElmtData.elmt, domEvt, evt);
+ };
+ SimileAjax.DOM.registerEvent(tapeElmtData.elmt, "mousedown", clickHandler);
+ SimileAjax.DOM.registerEvent(labelElmtData.elmt, "mousedown", clickHandler);
+
+ this._createHighlightDiv(highlightIndex, tapeElmtData, theme);
+
+ this._eventIdToElmt[evt.getID()] = tapeElmtData.elmt;
+ this._tracks[track] = startPixel;
+};
+
+Timeline.OriginalEventPainter.prototype.paintImpreciseDurationEvent = function(evt, metrics, theme, highlightIndex) {
+ var doc = this._timeline.getDocument();
+ var text = evt.getText();
+
+ var startDate = evt.getStart();
+ var latestStartDate = evt.getLatestStart();
+ var endDate = evt.getEnd();
+ var earliestEndDate = evt.getEarliestEnd();
+
+ var startPixel = Math.round(this._band.dateToPixelOffset(startDate));
+ var latestStartPixel = Math.round(this._band.dateToPixelOffset(latestStartDate));
+ var endPixel = Math.round(this._band.dateToPixelOffset(endDate));
+ var earliestEndPixel = Math.round(this._band.dateToPixelOffset(earliestEndDate));
+
+ var labelSize = this._frc.computeSize(text);
+ var labelLeft = latestStartPixel;
+ var labelRight = labelLeft + labelSize.width;
+
+ var rightEdge = Math.max(labelRight, endPixel);
+ var track = this._findFreeTrack(rightEdge);
+ var labelTop = Math.round(
+ metrics.trackOffset + track * metrics.trackIncrement + theme.event.tape.height);
+
+ var color = evt.getColor();
+ color = color != null ? color : theme.event.duration.color;
+
+ var impreciseTapeElmtData = this._paintEventTape(evt, track, startPixel, endPixel,
+ theme.event.duration.impreciseColor, theme.event.duration.impreciseOpacity, metrics, theme);
+ var tapeElmtData = this._paintEventTape(evt, track, latestStartPixel, earliestEndPixel, color, 100, metrics, theme);
+
+ var labelElmtData = this._paintEventLabel(evt, text, labelLeft, labelTop, labelSize.width, labelSize.height, theme);
+
+ var self = this;
+ var clickHandler = function(elmt, domEvt, target) {
+ return self._onClickInstantEvent(tapeElmtData.elmt, domEvt, evt);
+ };
+ SimileAjax.DOM.registerEvent(tapeElmtData.elmt, "mousedown", clickHandler);
+ SimileAjax.DOM.registerEvent(labelElmtData.elmt, "mousedown", clickHandler);
+
+ this._createHighlightDiv(highlightIndex, tapeElmtData, theme);
+
+ this._eventIdToElmt[evt.getID()] = tapeElmtData.elmt;
+ this._tracks[track] = startPixel;
+};
+
+Timeline.OriginalEventPainter.prototype._findFreeTrack = function(rightEdge) {
+ for (var i = 0; i < this._tracks.length; i++) {
+ var t = this._tracks[i];
+ if (t > rightEdge) {
+ break;
+ }
+ }
+ return i;
+};
+
+Timeline.OriginalEventPainter.prototype._paintEventIcon = function(evt, iconTrack, left, metrics, theme) {
+ var icon = evt.getIcon();
+ icon = icon != null ? icon : metrics.icon;
+
+ var middle = metrics.trackOffset + iconTrack * metrics.trackIncrement + metrics.trackHeight / 2;
+ var top = Math.round(middle - metrics.iconHeight / 2);
+
+ var img = SimileAjax.Graphics.createTranslucentImage(icon);
+ var iconDiv = this._timeline.getDocument().createElement("div");
+ iconDiv.style.position = "absolute";
+ iconDiv.style.left = left + "px";
+ iconDiv.style.top = top + "px";
+ iconDiv.appendChild(img);
+ iconDiv.style.cursor = "pointer";
+ this._eventLayer.appendChild(iconDiv);
+
+ return {
+ left: left,
+ top: top,
+ width: metrics.iconWidth,
+ height: metrics.iconHeight,
+ elmt: iconDiv
+ };
+};
+
+Timeline.OriginalEventPainter.prototype._paintEventLabel = function(evt, text, left, top, width, height, theme) {
+ var doc = this._timeline.getDocument();
+
+ var labelDiv = doc.createElement("div");
+ labelDiv.style.position = "absolute";
+ labelDiv.style.left = left + "px";
+ labelDiv.style.width = width + "px";
+ labelDiv.style.top = top + "px";
+ labelDiv.innerHTML = text;
+ labelDiv.style.cursor = "pointer";
+
+ var color = evt.getTextColor();
+ if (color == null) {
+ color = evt.getColor();
+ }
+ if (color != null) {
+ labelDiv.style.color = color;
+ }
+
+ this._eventLayer.appendChild(labelDiv);
+
+ return {
+ left: left,
+ top: top,
+ width: width,
+ height: height,
+ elmt: labelDiv
+ };
+};
+
+Timeline.OriginalEventPainter.prototype._paintEventTape = function(
+ evt, iconTrack, startPixel, endPixel, color, opacity, metrics, theme) {
+
+ var tapeWidth = endPixel - startPixel;
+ var tapeHeight = theme.event.tape.height;
+ var top = metrics.trackOffset + iconTrack * metrics.trackIncrement;
+
+ var tapeDiv = this._timeline.getDocument().createElement("div");
+ tapeDiv.style.position = "absolute";
+ tapeDiv.style.left = startPixel + "px";
+ tapeDiv.style.width = tapeWidth + "px";
+ tapeDiv.style.top = top + "px";
+ tapeDiv.style.height = tapeHeight + "px";
+ tapeDiv.style.backgroundColor = color;
+ tapeDiv.style.overflow = "hidden";
+ tapeDiv.style.cursor = "pointer";
+ SimileAjax.Graphics.setOpacity(tapeDiv, opacity);
+
+ this._eventLayer.appendChild(tapeDiv);
+
+ return {
+ left: startPixel,
+ top: top,
+ width: tapeWidth,
+ height: tapeHeight,
+ elmt: tapeDiv
+ };
+}
+
+Timeline.OriginalEventPainter.prototype._createHighlightDiv = function(highlightIndex, dimensions, theme) {
+ if (highlightIndex >= 0) {
+ var doc = this._timeline.getDocument();
+ var eventTheme = theme.event;
+
+ var color = eventTheme.highlightColors[Math.min(highlightIndex, eventTheme.highlightColors.length - 1)];
+
+ var div = doc.createElement("div");
+ div.style.position = "absolute";
+ div.style.overflow = "hidden";
+ div.style.left = (dimensions.left - 2) + "px";
+ div.style.width = (dimensions.width + 4) + "px";
+ div.style.top = (dimensions.top - 2) + "px";
+ div.style.height = (dimensions.height + 4) + "px";
+ div.style.background = color;
+
+ this._highlightLayer.appendChild(div);
+ }
+};
+
+Timeline.OriginalEventPainter.prototype._onClickInstantEvent = function(icon, domEvt, evt) {
+ var c = SimileAjax.DOM.getPageCoordinates(icon);
+ this._showBubble(
+ c.left + Math.ceil(icon.offsetWidth / 2),
+ c.top + Math.ceil(icon.offsetHeight / 2),
+ evt
+ );
+ this._fireOnSelect(evt.getID());
+
+ domEvt.cancelBubble = true;
+ SimileAjax.DOM.cancelEvent(domEvt);
+ return false;
+};
+
+Timeline.OriginalEventPainter.prototype._onClickDurationEvent = function(target, domEvt, evt) {
+ if ("pageX" in domEvt) {
+ var x = domEvt.pageX;
+ var y = domEvt.pageY;
+ } else {
+ var c = SimileAjax.DOM.getPageCoordinates(target);
+ var x = domEvt.offsetX + c.left;
+ var y = domEvt.offsetY + c.top;
+ }
+ this._showBubble(x, y, evt);
+ this._fireOnSelect(evt.getID());
+
+ domEvt.cancelBubble = true;
+ SimileAjax.DOM.cancelEvent(domEvt);
+ return false;
+};
+
+Timeline.OriginalEventPainter.prototype.showBubble = function(evt) {
+ var elmt = this._eventIdToElmt[evt.getID()];
+ if (elmt) {
+ var c = SimileAjax.DOM.getPageCoordinates(elmt);
+ this._showBubble(c.left + elmt.offsetWidth / 2, c.top + elmt.offsetHeight / 2, evt);
+ }
+};
+
+Timeline.OriginalEventPainter.prototype._showBubble = function(x, y, evt) {
+ var div = document.createElement("div");
+ evt.fillInfoBubble(div, this._params.theme, this._band.getLabeller());
+
+ SimileAjax.WindowManager.cancelPopups();
+ SimileAjax.Graphics.createBubbleForContentAndPoint(div, x, y, this._params.theme.event.bubble.width);
+};
+
+Timeline.OriginalEventPainter.prototype._fireOnSelect = function(eventID) {
+ for (var i = 0; i < this._onSelectListeners.length; i++) {
+ this._onSelectListeners[i](eventID);
+ }
+};
diff --git a/site/app/webroot/js/simile/timeline/scripts/overview-painter.js b/site/app/webroot/js/simile/timeline/scripts/overview-painter.js
new file mode 100755
index 0000000..2694a37
--- /dev/null
+++ b/site/app/webroot/js/simile/timeline/scripts/overview-painter.js
@@ -0,0 +1,231 @@
+/*==================================================
+ * Overview Event Painter
+ *==================================================
+ */
+
+Timeline.OverviewEventPainter = function(params) {
+ this._params = params;
+ this._onSelectListeners = [];
+
+ this._filterMatcher = null;
+ this._highlightMatcher = null;
+};
+
+Timeline.OverviewEventPainter.prototype.initialize = function(band, timeline) {
+ this._band = band;
+ this._timeline = timeline;
+
+ this._eventLayer = null;
+ this._highlightLayer = null;
+};
+
+Timeline.OverviewEventPainter.prototype.addOnSelectListener = function(listener) {
+ this._onSelectListeners.push(listener);
+};
+
+Timeline.OverviewEventPainter.prototype.removeOnSelectListener = function(listener) {
+ for (var i = 0; i < this._onSelectListeners.length; i++) {
+ if (this._onSelectListeners[i] == listener) {
+ this._onSelectListeners.splice(i, 1);
+ break;
+ }
+ }
+};
+
+Timeline.OverviewEventPainter.prototype.getFilterMatcher = function() {
+ return this._filterMatcher;
+};
+
+Timeline.OverviewEventPainter.prototype.setFilterMatcher = function(filterMatcher) {
+ this._filterMatcher = filterMatcher;
+};
+
+Timeline.OverviewEventPainter.prototype.getHighlightMatcher = function() {
+ return this._highlightMatcher;
+};
+
+Timeline.OverviewEventPainter.prototype.setHighlightMatcher = function(highlightMatcher) {
+ this._highlightMatcher = highlightMatcher;
+};
+
+Timeline.OverviewEventPainter.prototype.paint = function() {
+ var eventSource = this._band.getEventSource();
+ if (eventSource == null) {
+ return;
+ }
+
+ this._prepareForPainting();
+
+ var eventTheme = this._params.theme.event;
+ var metrics = {
+ trackOffset: eventTheme.overviewTrack.offset,
+ trackHeight: eventTheme.overviewTrack.height,
+ trackGap: eventTheme.overviewTrack.gap,
+ trackIncrement: eventTheme.overviewTrack.height + eventTheme.overviewTrack.gap
+ }
+
+ var minDate = this._band.getMinDate();
+ var maxDate = this._band.getMaxDate();
+
+ var filterMatcher = (this._filterMatcher != null) ?
+ this._filterMatcher :
+ function(evt) { return true; };
+ var highlightMatcher = (this._highlightMatcher != null) ?
+ this._highlightMatcher :
+ function(evt) { return -1; };
+
+ var iterator = eventSource.getEventReverseIterator(minDate, maxDate);
+ while (iterator.hasNext()) {
+ var evt = iterator.next();
+ if (filterMatcher(evt)) {
+ this.paintEvent(evt, metrics, this._params.theme, highlightMatcher(evt));
+ }
+ }
+
+ this._highlightLayer.style.display = "block";
+ this._eventLayer.style.display = "block";
+};
+
+Timeline.OverviewEventPainter.prototype.softPaint = function() {
+};
+
+Timeline.OverviewEventPainter.prototype._prepareForPainting = function() {
+ var band = this._band;
+
+ this._tracks = [];
+
+ if (this._highlightLayer != null) {
+ band.removeLayerDiv(this._highlightLayer);
+ }
+ this._highlightLayer = band.createLayerDiv(105, "timeline-band-highlights");
+ this._highlightLayer.style.display = "none";
+
+ if (this._eventLayer != null) {
+ band.removeLayerDiv(this._eventLayer);
+ }
+ this._eventLayer = band.createLayerDiv(110, "timeline-band-events");
+ this._eventLayer.style.display = "none";
+};
+
+Timeline.OverviewEventPainter.prototype.paintEvent = function(evt, metrics, theme, highlightIndex) {
+ if (evt.isInstant()) {
+ this.paintInstantEvent(evt, metrics, theme, highlightIndex);
+ } else {
+ this.paintDurationEvent(evt, metrics, theme, highlightIndex);
+ }
+};
+
+Timeline.OverviewEventPainter.prototype.paintInstantEvent = function(evt, metrics, theme, highlightIndex) {
+ var startDate = evt.getStart();
+ var startPixel = Math.round(this._band.dateToPixelOffset(startDate));
+
+ var color = evt.getColor();
+ color = color != null ? color : theme.event.duration.color;
+
+ var tickElmtData = this._paintEventTick(evt, startPixel, color, 100, metrics, theme);
+
+ this._createHighlightDiv(highlightIndex, tickElmtData, theme);
+};
+
+Timeline.OverviewEventPainter.prototype.paintDurationEvent = function(evt, metrics, theme, highlightIndex) {
+ var latestStartDate = evt.getLatestStart();
+ var earliestEndDate = evt.getEarliestEnd();
+
+ var latestStartPixel = Math.round(this._band.dateToPixelOffset(latestStartDate));
+ var earliestEndPixel = Math.round(this._band.dateToPixelOffset(earliestEndDate));
+
+ var tapeTrack = 0;
+ for (; tapeTrack < this._tracks.length; tapeTrack++) {
+ if (earliestEndPixel < this._tracks[tapeTrack]) {
+ break;
+ }
+ }
+ this._tracks[tapeTrack] = earliestEndPixel;
+
+ var color = evt.getColor();
+ color = color != null ? color : theme.event.duration.color;
+
+ var tapeElmtData = this._paintEventTape(evt, tapeTrack, latestStartPixel, earliestEndPixel, color, 100, metrics, theme);
+
+ this._createHighlightDiv(highlightIndex, tapeElmtData, theme);
+};
+
+Timeline.OverviewEventPainter.prototype._paintEventTape = function(
+ evt, track, left, right, color, opacity, metrics, theme) {
+
+ var top = metrics.trackOffset + track * metrics.trackIncrement;
+ var width = right - left;
+ var height = metrics.trackHeight;
+
+ var tapeDiv = this._timeline.getDocument().createElement("div");
+ tapeDiv.style.position = "absolute";
+ tapeDiv.style.left = left + "px";
+ tapeDiv.style.width = width + "px";
+ tapeDiv.style.top = top + "px";
+ tapeDiv.style.height = height + "px";
+ tapeDiv.style.backgroundColor = color;
+ tapeDiv.style.overflow = "hidden";
+ SimileAjax.Graphics.setOpacity(tapeDiv, opacity);
+
+ this._eventLayer.appendChild(tapeDiv);
+
+ return {
+ left: left,
+ top: top,
+ width: width,
+ height: height,
+ elmt: tapeDiv
+ };
+}
+
+Timeline.OverviewEventPainter.prototype._paintEventTick = function(
+ evt, left, color, opacity, metrics, theme) {
+
+ var height = theme.event.overviewTrack.tickHeight;
+ var top = metrics.trackOffset - height;
+ var width = 1;
+
+ var tickDiv = this._timeline.getDocument().createElement("div");
+ tickDiv.style.position = "absolute";
+ tickDiv.style.left = left + "px";
+ tickDiv.style.width = width + "px";
+ tickDiv.style.top = top + "px";
+ tickDiv.style.height = height + "px";
+ tickDiv.style.backgroundColor = color;
+ tickDiv.style.overflow = "hidden";
+ SimileAjax.Graphics.setOpacity(tickDiv, opacity);
+
+ this._eventLayer.appendChild(tickDiv);
+
+ return {
+ left: left,
+ top: top,
+ width: width,
+ height: height,
+ elmt: tickDiv
+ };
+}
+
+Timeline.OverviewEventPainter.prototype._createHighlightDiv = function(highlightIndex, dimensions, theme) {
+ if (highlightIndex >= 0) {
+ var doc = this._timeline.getDocument();
+ var eventTheme = theme.event;
+
+ var color = eventTheme.highlightColors[Math.min(highlightIndex, eventTheme.highlightColors.length - 1)];
+
+ var div = doc.createElement("div");
+ div.style.position = "absolute";
+ div.style.overflow = "hidden";
+ div.style.left = (dimensions.left - 1) + "px";
+ div.style.width = (dimensions.width + 2) + "px";
+ div.style.top = (dimensions.top - 1) + "px";
+ div.style.height = (dimensions.height + 2) + "px";
+ div.style.background = color;
+
+ this._highlightLayer.appendChild(div);
+ }
+};
+
+Timeline.OverviewEventPainter.prototype.showBubble = function(evt) {
+ // not implemented
+};
diff --git a/site/app/webroot/js/simile/timeline/scripts/sources.js b/site/app/webroot/js/simile/timeline/scripts/sources.js
new file mode 100755
index 0000000..87c2a00
--- /dev/null
+++ b/site/app/webroot/js/simile/timeline/scripts/sources.js
@@ -0,0 +1,439 @@
+/*==================================================
+ * Default Event Source
+ *==================================================
+ */
+
+
+Timeline.DefaultEventSource = function(eventIndex) {
+ this._events = (eventIndex instanceof Object) ? eventIndex : new SimileAjax.EventIndex();
+ this._listeners = [];
+};
+
+Timeline.DefaultEventSource.prototype.addListener = function(listener) {
+ this._listeners.push(listener);
+};
+
+Timeline.DefaultEventSource.prototype.removeListener = function(listener) {
+ for (var i = 0; i < this._listeners.length; i++) {
+ if (this._listeners[i] == listener) {
+ this._listeners.splice(i, 1);
+ break;
+ }
+ }
+};
+
+Timeline.DefaultEventSource.prototype.loadXML = function(xml, url) {
+ var base = this._getBaseURL(url);
+
+ var wikiURL = xml.documentElement.getAttribute("wiki-url");
+ var wikiSection = xml.documentElement.getAttribute("wiki-section");
+
+ var dateTimeFormat = xml.documentElement.getAttribute("date-time-format");
+ var parseDateTimeFunction = this._events.getUnit().getParser(dateTimeFormat);
+
+ var node = xml.documentElement.firstChild;
+ var added = false;
+ while (node != null) {
+ if (node.nodeType == 1) {
+ var description = "";
+ if (node.firstChild != null && node.firstChild.nodeType == 3) {
+ description = node.firstChild.nodeValue;
+ }
+ var evt = new Timeline.DefaultEventSource.Event(
+ node.getAttribute("id"),
+ parseDateTimeFunction(node.getAttribute("start")),
+ parseDateTimeFunction(node.getAttribute("end")),
+ parseDateTimeFunction(node.getAttribute("latestStart")),
+ parseDateTimeFunction(node.getAttribute("earliestEnd")),
+ node.getAttribute("isDuration") != "true",
+ node.getAttribute("title"),
+ description,
+ this._resolveRelativeURL(node.getAttribute("image"), base),
+ this._resolveRelativeURL(node.getAttribute("link"), base),
+ this._resolveRelativeURL(node.getAttribute("icon"), base),
+ node.getAttribute("color"),
+ node.getAttribute("textColor")
+ );
+ evt._node = node;
+ evt.getProperty = function(name) {
+ return this._node.getAttribute(name);
+ };
+ evt.setWikiInfo(wikiURL, wikiSection);
+
+ this._events.add(evt);
+
+ added = true;
+ }
+ node = node.nextSibling;
+ }
+
+ if (added) {
+ this._fire("onAddMany", []);
+ }
+};
+
+
+Timeline.DefaultEventSource.prototype.loadJSON = function(data, url) {
+ var base = this._getBaseURL(url);
+ var added = false;
+ if (data && data.events){
+ var wikiURL = ("wikiURL" in data) ? data.wikiURL : null;
+ var wikiSection = ("wikiSection" in data) ? data.wikiSection : null;
+
+ var dateTimeFormat = ("dateTimeFormat" in data) ? data.dateTimeFormat : null;
+ var parseDateTimeFunction = this._events.getUnit().getParser(dateTimeFormat);
+
+ for (var i=0; i < data.events.length; i++){
+ var event = data.events[i];
+ var evt = new Timeline.DefaultEventSource.Event(
+ ("id" in event) ? event.id : undefined,
+ parseDateTimeFunction(event.start),
+ parseDateTimeFunction(event.end),
+ parseDateTimeFunction(event.latestStart),
+ parseDateTimeFunction(event.earliestEnd),
+ event.isDuration || false,
+ event.title,
+ event.description,
+ this._resolveRelativeURL(event.image, base),
+ this._resolveRelativeURL(event.link, base),
+ this._resolveRelativeURL(event.icon, base),
+ event.color,
+ event.textColor
+ );
+ evt._obj = event;
+ evt.getProperty = function(name) {
+ return this._obj[name];
+ };
+ evt.setWikiInfo(wikiURL, wikiSection);
+
+ this._events.add(evt);
+ added = true;
+ }
+ }
+
+ if (added) {
+ this._fire("onAddMany", []);
+ }
+};
+
+/*
+ * Contributed by Morten Frederiksen, http://www.wasab.dk/morten/
+ */
+Timeline.DefaultEventSource.prototype.loadSPARQL = function(xml, url) {
+ var base = this._getBaseURL(url);
+
+ var dateTimeFormat = 'iso8601';
+ var parseDateTimeFunction = this._events.getUnit().getParser(dateTimeFormat);
+
+ if (xml == null) {
+ return;
+ }
+
+ /*
+ * Find <results> tag
+ */
+ var node = xml.documentElement.firstChild;
+ while (node != null && (node.nodeType != 1 || node.nodeName != 'results')) {
+ node = node.nextSibling;
+ }
+
+ var wikiURL = null;
+ var wikiSection = null;
+ if (node != null) {
+ wikiURL = node.getAttribute("wiki-url");
+ wikiSection = node.getAttribute("wiki-section");
+
+ node = node.firstChild;
+ }
+
+ var added = false;
+ while (node != null) {
+ if (node.nodeType == 1) {
+ var bindings = { };
+ var binding = node.firstChild;
+ while (binding != null) {
+ if (binding.nodeType == 1 &&
+ binding.firstChild != null &&
+ binding.firstChild.nodeType == 1 &&
+ binding.firstChild.firstChild != null &&
+ binding.firstChild.firstChild.nodeType == 3) {
+ bindings[binding.getAttribute('name')] = binding.firstChild.firstChild.nodeValue;
+ }
+ binding = binding.nextSibling;
+ }
+
+ if (bindings["start"] == null && bindings["date"] != null) {
+ bindings["start"] = bindings["date"];
+ }
+
+ var evt = new Timeline.DefaultEventSource.Event(
+ bindings["id"],
+ parseDateTimeFunction(bindings["start"]),
+ parseDateTimeFunction(bindings["end"]),
+ parseDateTimeFunction(bindings["latestStart"]),
+ parseDateTimeFunction(bindings["earliestEnd"]),
+ bindings["isDuration"] != "true",
+ bindings["title"],
+ bindings["description"],
+ this._resolveRelativeURL(bindings["image"], base),
+ this._resolveRelativeURL(bindings["link"], base),
+ this._resolveRelativeURL(bindings["icon"], base),
+ bindings["color"],
+ bindings["textColor"]
+ );
+ evt._bindings = bindings;
+ evt.getProperty = function(name) {
+ return this._bindings[name];
+ };
+ evt.setWikiInfo(wikiURL, wikiSection);
+
+ this._events.add(evt);
+ added = true;
+ }
+ node = node.nextSibling;
+ }
+
+ if (added) {
+ this._fire("onAddMany", []);
+ }
+};
+
+Timeline.DefaultEventSource.prototype.add = function(evt) {
+ this._events.add(evt);
+ this._fire("onAddOne", [evt]);
+};
+
+Timeline.DefaultEventSource.prototype.addMany = function(events) {
+ for (var i = 0; i < events.length; i++) {
+ this._events.add(events[i]);
+ }
+ this._fire("onAddMany", []);
+};
+
+Timeline.DefaultEventSource.prototype.clear = function() {
+ this._events.removeAll();
+ this._fire("onClear", []);
+};
+
+Timeline.DefaultEventSource.prototype.getEvent = function(id) {
+ return this._events.getEvent(id);
+};
+
+Timeline.DefaultEventSource.prototype.getEventIterator = function(startDate, endDate) {
+ return this._events.getIterator(startDate, endDate);
+};
+
+Timeline.DefaultEventSource.prototype.getEventReverseIterator = function(startDate, endDate) {
+ return this._events.getReverseIterator(startDate, endDate);
+};
+
+Timeline.DefaultEventSource.prototype.getAllEventIterator = function() {
+ return this._events.getAllIterator();
+};
+
+Timeline.DefaultEventSource.prototype.getCount = function() {
+ return this._events.getCount();
+};
+
+Timeline.DefaultEventSource.prototype.getEarliestDate = function() {
+ return this._events.getEarliestDate();
+};
+
+Timeline.DefaultEventSource.prototype.getLatestDate = function() {
+ return this._events.getLatestDate();
+};
+
+Timeline.DefaultEventSource.prototype._fire = function(handlerName, args) {
+ for (var i = 0; i < this._listeners.length; i++) {
+ var listener = this._listeners[i];
+ if (handlerName in listener) {
+ try {
+ listener[handlerName].apply(listener, args);
+ } catch (e) {
+ SimileAjax.Debug.exception(e);
+ }
+ }
+ }
+};
+
+Timeline.DefaultEventSource.prototype._getBaseURL = function(url) {
+ if (url.indexOf("://") < 0) {
+ var url2 = this._getBaseURL(document.location.href);
+ if (url.substr(0,1) == "/") {
+ url = url2.substr(0, url2.indexOf("/", url2.indexOf("://") + 3)) + url;
+ } else {
+ url = url2 + url;
+ }
+ }
+
+ var i = url.lastIndexOf("/");
+ if (i < 0) {
+ return "";
+ } else {
+ return url.substr(0, i+1);
+ }
+};
+
+Timeline.DefaultEventSource.prototype._resolveRelativeURL = function(url, base) {
+ if (url == null || url == "") {
+ return url;
+ } else if (url.indexOf("://") > 0) {
+ return url;
+ } else if (url.substr(0,1) == "/") {
+ return base.substr(0, base.indexOf("/", base.indexOf("://") + 3)) + url;
+ } else {
+ return base + url;
+ }
+};
+
+
+Timeline.DefaultEventSource.Event = function(
+ id,
+ start, end, latestStart, earliestEnd, instant,
+ text, description, image, link,
+ icon, color, textColor) {
+
+ id = (id) ? id.trim() : "";
+ this._id = id.length > 0 ? id : ("e" + Math.floor(Math.random() * 1000000));
+
+ this._instant = instant || (end == null);
+
+ this._start = start;
+ this._end = (end != null) ? end : start;
+
+ this._latestStart = (latestStart != null) ? latestStart : (instant ? this._end : this._start);
+ this._earliestEnd = (earliestEnd != null) ? earliestEnd : (instant ? this._start : this._end);
+
+ this._text = SimileAjax.HTML.deEntify(text);
+ this._description = SimileAjax.HTML.deEntify(description);
+ this._image = (image != null && image != "") ? image : null;
+ this._link = (link != null && link != "") ? link : null;
+
+ this._icon = (icon != null && icon != "") ? icon : null;
+ this._color = (color != null && color != "") ? color : null;
+ this._textColor = (textColor != null && textColor != "") ? textColor : null;
+
+ this._wikiURL = null;
+ this._wikiSection = null;
+};
+
+Timeline.DefaultEventSource.Event.prototype = {
+ getID: function() { return this._id; },
+
+ isInstant: function() { return this._instant; },
+ isImprecise: function() { return this._start != this._latestStart || this._end != this._earliestEnd; },
+
+ getStart: function() { return this._start; },
+ getEnd: function() { return this._end; },
+ getLatestStart: function() { return this._latestStart; },
+ getEarliestEnd: function() { return this._earliestEnd; },
+
+ getText: function() { return this._text; },
+ getDescription: function() { return this._description; },
+ getImage: function() { return this._image; },
+ getLink: function() { return this._link; },
+
+ getIcon: function() { return this._icon; },
+ getColor: function() { return this._color; },
+ getTextColor: function() { return this._textColor; },
+
+ getProperty: function(name) { return null; },
+
+ getWikiURL: function() { return this._wikiURL; },
+ getWikiSection: function() { return this._wikiSection; },
+ setWikiInfo: function(wikiURL, wikiSection) {
+ this._wikiURL = wikiURL;
+ this._wikiSection = wikiSection;
+ },
+
+ fillDescription: function(elmt) {
+ elmt.innerHTML = this._description;
+ },
+ fillWikiInfo: function(elmt) {
+ if (this._wikiURL != null && this._wikiSection != null) {
+ var wikiID = this.getProperty("wikiID");
+ if (wikiID == null || wikiID.length == 0) {
+ wikiID = this.getText();
+ }
+ wikiID = wikiID.replace(/\s/g, "_");
+
+ var url = this._wikiURL + this._wikiSection.replace(/\s/g, "_") + "/" + wikiID;
+ var a = document.createElement("a");
+ a.href = url;
+ a.target = "new";
+ a.innerHTML = Timeline.strings[Timeline.clientLocale].wikiLinkLabel;
+
+ elmt.appendChild(document.createTextNode("["));
+ elmt.appendChild(a);
+ elmt.appendChild(document.createTextNode("]"));
+ } else {
+ elmt.style.display = "none";
+ }
+ },
+ fillTime: function(elmt, labeller) {
+ if (this._instant) {
+ if (this.isImprecise()) {
+ elmt.appendChild(elmt.ownerDocument.createTextNode(labeller.labelPrecise(this._start)));
+ elmt.appendChild(elmt.ownerDocument.createElement("br"));
+ elmt.appendChild(elmt.ownerDocument.createTextNode(labeller.labelPrecise(this._end)));
+ } else {
+ elmt.appendChild(elmt.ownerDocument.createTextNode(labeller.labelPrecise(this._start)));
+ }
+ } else {
+ if (this.isImprecise()) {
+ elmt.appendChild(elmt.ownerDocument.createTextNode(
+ labeller.labelPrecise(this._start) + " ~ " + labeller.labelPrecise(this._latestStart)));
+ elmt.appendChild(elmt.ownerDocument.createElement("br"));
+ elmt.appendChild(elmt.ownerDocument.createTextNode(
+ labeller.labelPrecise(this._earliestEnd) + " ~ " + labeller.labelPrecise(this._end)));
+ } else {
+ elmt.appendChild(elmt.ownerDocument.createTextNode(labeller.labelPrecise(this._start)));
+ elmt.appendChild(elmt.ownerDocument.createElement("br"));
+ elmt.appendChild(elmt.ownerDocument.createTextNode(labeller.labelPrecise(this._end)));
+ }
+ }
+ },
+ fillInfoBubble: function(elmt, theme, labeller) {
+ var doc = elmt.ownerDocument;
+
+ var title = this.getText();
+ var link = this.getLink();
+ var image = this.getImage();
+
+ if (image != null) {
+ var img = doc.createElement("img");
+ img.src = image;
+
+ theme.event.bubble.imageStyler(img);
+ elmt.appendChild(img);
+ }
+
+ var divTitle = doc.createElement("div");
+ var textTitle = doc.createTextNode(title);
+ if (link != null) {
+ var a = doc.createElement("a");
+ a.href = link;
+ a.appendChild(textTitle);
+ divTitle.appendChild(a);
+ } else {
+ divTitle.appendChild(textTitle);
+ }
+ theme.event.bubble.titleStyler(divTitle);
+ elmt.appendChild(divTitle);
+
+ var divBody = doc.createElement("div");
+ this.fillDescription(divBody);
+ theme.event.bubble.bodyStyler(divBody);
+ elmt.appendChild(divBody);
+
+ var divTime = doc.createElement("div");
+ this.fillTime(divTime, labeller);
+ theme.event.bubble.timeStyler(divTime);
+ elmt.appendChild(divTime);
+
+ var divWiki = doc.createElement("div");
+ this.fillWikiInfo(divWiki);
+ theme.event.bubble.wikiStyler(divWiki);
+ elmt.appendChild(divWiki);
+ }
+}; \ No newline at end of file
diff --git a/site/app/webroot/js/simile/timeline/scripts/themes.js b/site/app/webroot/js/simile/timeline/scripts/themes.js
new file mode 100755
index 0000000..37b8614
--- /dev/null
+++ b/site/app/webroot/js/simile/timeline/scripts/themes.js
@@ -0,0 +1,136 @@
+/*==================================================
+ * Classic Theme
+ *==================================================
+ */
+
+
+Timeline.ClassicTheme = new Object();
+
+Timeline.ClassicTheme.implementations = [];
+
+Timeline.ClassicTheme.create = function(locale) {
+ if (locale == null) {
+ locale = Timeline.getDefaultLocale();
+ }
+
+ var f = Timeline.ClassicTheme.implementations[locale];
+ if (f == null) {
+ f = Timeline.ClassicTheme._Impl;
+ }
+ return new f();
+};
+
+Timeline.ClassicTheme._Impl = function() {
+ this.firstDayOfWeek = 0; // Sunday
+
+ this.ether = {
+ backgroundColors: [
+ "#EEE",
+ "#DDD",
+ "#CCC",
+ "#AAA"
+ ],
+ highlightColor: "white",
+ highlightOpacity: 50,
+ interval: {
+ line: {
+ show: true,
+ color: "#aaa",
+ opacity: 25
+ },
+ weekend: {
+ color: "#FFFFE0",
+ opacity: 30
+ },
+ marker: {
+ hAlign: "Bottom",
+ hBottomStyler: function(elmt) {
+ elmt.className = "timeline-ether-marker-bottom";
+ },
+ hBottomEmphasizedStyler: function(elmt) {
+ elmt.className = "timeline-ether-marker-bottom-emphasized";
+ },
+ hTopStyler: function(elmt) {
+ elmt.className = "timeline-ether-marker-top";
+ },
+ hTopEmphasizedStyler: function(elmt) {
+ elmt.className = "timeline-ether-marker-top-emphasized";
+ },
+
+ vAlign: "Right",
+ vRightStyler: function(elmt) {
+ elmt.className = "timeline-ether-marker-right";
+ },
+ vRightEmphasizedStyler: function(elmt) {
+ elmt.className = "timeline-ether-marker-right-emphasized";
+ },
+ vLeftStyler: function(elmt) {
+ elmt.className = "timeline-ether-marker-left";
+ },
+ vLeftEmphasizedStyler:function(elmt) {
+ elmt.className = "timeline-ether-marker-left-emphasized";
+ }
+ }
+ }
+ };
+
+ this.event = {
+ track: {
+ height: 10, // px
+ gap: 2 // px
+ },
+ overviewTrack: {
+ offset: 20, // px
+ tickHeight: 6, // px
+ height: 2, // px
+ gap: 1 // px
+ },
+ tape: {
+ height: 4 // px
+ },
+ instant: {
+ icon: Timeline.urlPrefix + "images/dull-blue-circle.png",
+ iconWidth: 10,
+ iconHeight: 10,
+ color: "#58A0DC",
+ impreciseColor: "#58A0DC",
+ impreciseOpacity: 20
+ },
+ duration: {
+ color: "#58A0DC",
+ impreciseColor: "#58A0DC",
+ impreciseOpacity: 20
+ },
+ label: {
+ backgroundColor: "white",
+ backgroundOpacity: 50,
+ lineColor: "#58A0DC",
+ offsetFromLine: 3 // px
+ },
+ highlightColors: [
+ "#FFFF00",
+ "#FFC000",
+ "#FF0000",
+ "#0000FF"
+ ],
+ bubble: {
+ width: 250, // px
+ height: 125, // px
+ titleStyler: function(elmt) {
+ elmt.className = "timeline-event-bubble-title";
+ },
+ bodyStyler: function(elmt) {
+ elmt.className = "timeline-event-bubble-body";
+ },
+ imageStyler: function(elmt) {
+ elmt.className = "timeline-event-bubble-image";
+ },
+ wikiStyler: function(elmt) {
+ elmt.className = "timeline-event-bubble-wiki";
+ },
+ timeStyler: function(elmt) {
+ elmt.className = "timeline-event-bubble-time";
+ }
+ }
+ };
+}; \ No newline at end of file
diff --git a/site/app/webroot/js/simile/timeline/scripts/timeline.js b/site/app/webroot/js/simile/timeline/scripts/timeline.js
new file mode 100755
index 0000000..49b4af1
--- /dev/null
+++ b/site/app/webroot/js/simile/timeline/scripts/timeline.js
@@ -0,0 +1,913 @@
+/*==================================================
+ * Timeline
+ *==================================================
+ */
+
+Timeline.strings = {}; // localization string tables
+
+Timeline.getDefaultLocale = function() {
+ return Timeline.clientLocale;
+};
+
+Timeline.create = function(elmt, bandInfos, orientation, unit) {
+ return new Timeline._Impl(elmt, bandInfos, orientation, unit);
+};
+
+Timeline.HORIZONTAL = 0;
+Timeline.VERTICAL = 1;
+
+Timeline._defaultTheme = null;
+
+Timeline.createBandInfo = function(params) {
+ var theme = ("theme" in params) ? params.theme : Timeline.getDefaultTheme();
+
+ var eventSource = ("eventSource" in params) ? params.eventSource : null;
+
+ var ether = new Timeline.LinearEther({
+ centersOn: ("date" in params) ? params.date : new Date(),
+ interval: SimileAjax.DateTime.gregorianUnitLengths[params.intervalUnit],
+ pixelsPerInterval: params.intervalPixels
+ });
+
+ var etherPainter = new Timeline.GregorianEtherPainter({
+ unit: params.intervalUnit,
+ multiple: ("multiple" in params) ? params.multiple : 1,
+ theme: theme,
+ align: ("align" in params) ? params.align : undefined
+ });
+
+ var eventPainterParams = {
+ showText: ("showEventText" in params) ? params.showEventText : true,
+ theme: theme
+ };
+ if ("trackHeight" in params) {
+ eventPainterParams.trackHeight = params.trackHeight;
+ }
+ if ("trackGap" in params) {
+ eventPainterParams.trackGap = params.trackGap;
+ }
+
+ var layout = ("overview" in params && params.overview) ? "overview" : ("layout" in params ? params.layout : "original");
+ var eventPainter;
+ switch (layout) {
+ case "overview" :
+ eventPainter = new Timeline.OverviewEventPainter(eventPainterParams);
+ break;
+ case "detailed" :
+ eventPainter = new Timeline.DetailedEventPainter(eventPainterParams);
+ break;
+ default:
+ eventPainter = new Timeline.OriginalEventPainter(eventPainterParams);
+ }
+
+ return {
+ width: params.width,
+ eventSource: eventSource,
+ timeZone: ("timeZone" in params) ? params.timeZone : 0,
+ ether: ether,
+ etherPainter: etherPainter,
+ eventPainter: eventPainter
+ };
+};
+
+Timeline.createHotZoneBandInfo = function(params) {
+ var theme = ("theme" in params) ? params.theme : Timeline.getDefaultTheme();
+
+ var eventSource = ("eventSource" in params) ? params.eventSource : null;
+
+ var ether = new Timeline.HotZoneEther({
+ centersOn: ("date" in params) ? params.date : new Date(),
+ interval: SimileAjax.DateTime.gregorianUnitLengths[params.intervalUnit],
+ pixelsPerInterval: params.intervalPixels,
+ zones: params.zones
+ });
+
+ var etherPainter = new Timeline.HotZoneGregorianEtherPainter({
+ unit: params.intervalUnit,
+ zones: params.zones,
+ theme: theme,
+ align: ("align" in params) ? params.align : undefined
+ });
+
+ var eventPainterParams = {
+ showText: ("showEventText" in params) ? params.showEventText : true,
+ theme: theme
+ };
+ if ("trackHeight" in params) {
+ eventPainterParams.trackHeight = params.trackHeight;
+ }
+ if ("trackGap" in params) {
+ eventPainterParams.trackGap = params.trackGap;
+ }
+
+ var layout = ("overview" in params && params.overview) ? "overview" : ("layout" in params ? params.layout : "original");
+ var eventPainter;
+ switch (layout) {
+ case "overview" :
+ eventPainter = new Timeline.OverviewEventPainter(eventPainterParams);
+ break;
+ case "detailed" :
+ eventPainter = new Timeline.DetailedEventPainter(eventPainterParams);
+ break;
+ default:
+ eventPainter = new Timeline.OriginalEventPainter(eventPainterParams);
+ }
+
+ return {
+ width: params.width,
+ eventSource: eventSource,
+ timeZone: ("timeZone" in params) ? params.timeZone : 0,
+ ether: ether,
+ etherPainter: etherPainter,
+ eventPainter: eventPainter
+ };
+};
+
+Timeline.getDefaultTheme = function() {
+ if (Timeline._defaultTheme == null) {
+ Timeline._defaultTheme = Timeline.ClassicTheme.create(Timeline.getDefaultLocale());
+ }
+ return Timeline._defaultTheme;
+};
+
+Timeline.setDefaultTheme = function(theme) {
+ Timeline._defaultTheme = theme;
+};
+
+Timeline.loadXML = function(url, f) {
+ var fError = function(statusText, status, xmlhttp) {
+ alert("Failed to load data xml from " + url + "\n" + statusText);
+ };
+ var fDone = function(xmlhttp) {
+ var xml = xmlhttp.responseXML;
+ if (!xml.documentElement && xmlhttp.responseStream) {
+ xml.load(xmlhttp.responseStream);
+ }
+ f(xml, url);
+ };
+ SimileAjax.XmlHttp.get(url, fError, fDone);
+};
+
+
+Timeline.loadJSON = function(url, f) {
+ var fError = function(statusText, status, xmlhttp) {
+ alert("Failed to load json data from " + url + "\n" + statusText);
+ };
+ var fDone = function(xmlhttp) {
+ f(eval('(' + xmlhttp.responseText + ')'), url);
+ };
+ SimileAjax.XmlHttp.get(url, fError, fDone);
+};
+
+
+Timeline._Impl = function(elmt, bandInfos, orientation, unit) {
+ SimileAjax.WindowManager.initialize();
+
+ this._containerDiv = elmt;
+
+ this._bandInfos = bandInfos;
+ this._orientation = orientation == null ? Timeline.HORIZONTAL : orientation;
+ this._unit = (unit != null) ? unit : SimileAjax.NativeDateUnit;
+
+ this._initialize();
+};
+
+Timeline._Impl.prototype.dispose = function() {
+ for (var i = 0; i < this._bands.length; i++) {
+ this._bands[i].dispose();
+ }
+ this._bands = null;
+ this._bandInfos = null;
+ this._containerDiv.innerHTML = "";
+};
+
+Timeline._Impl.prototype.getBandCount = function() {
+ return this._bands.length;
+};
+
+Timeline._Impl.prototype.getBand = function(index) {
+ return this._bands[index];
+};
+
+Timeline._Impl.prototype.layout = function() {
+ this._distributeWidths();
+};
+
+Timeline._Impl.prototype.paint = function() {
+ for (var i = 0; i < this._bands.length; i++) {
+ this._bands[i].paint();
+ }
+};
+
+Timeline._Impl.prototype.getDocument = function() {
+ return this._containerDiv.ownerDocument;
+};
+
+Timeline._Impl.prototype.addDiv = function(div) {
+ this._containerDiv.appendChild(div);
+};
+
+Timeline._Impl.prototype.removeDiv = function(div) {
+ this._containerDiv.removeChild(div);
+};
+
+Timeline._Impl.prototype.isHorizontal = function() {
+ return this._orientation == Timeline.HORIZONTAL;
+};
+
+Timeline._Impl.prototype.isVertical = function() {
+ return this._orientation == Timeline.VERTICAL;
+};
+
+Timeline._Impl.prototype.getPixelLength = function() {
+ return this._orientation == Timeline.HORIZONTAL ?
+ this._containerDiv.offsetWidth : this._containerDiv.offsetHeight;
+};
+
+Timeline._Impl.prototype.getPixelWidth = function() {
+ return this._orientation == Timeline.VERTICAL ?
+ this._containerDiv.offsetWidth : this._containerDiv.offsetHeight;
+};
+
+Timeline._Impl.prototype.getUnit = function() {
+ return this._unit;
+};
+
+Timeline._Impl.prototype.loadXML = function(url, f) {
+ var tl = this;
+
+
+ var fError = function(statusText, status, xmlhttp) {
+ alert("Failed to load data xml from " + url + "\n" + statusText);
+ tl.hideLoadingMessage();
+ };
+ var fDone = function(xmlhttp) {
+ try {
+ var xml = xmlhttp.responseXML;
+ if (!xml.documentElement && xmlhttp.responseStream) {
+ xml.load(xmlhttp.responseStream);
+ }
+ f(xml, url);
+ } finally {
+ tl.hideLoadingMessage();
+ }
+ };
+
+ this.showLoadingMessage();
+ window.setTimeout(function() { SimileAjax.XmlHttp.get(url, fError, fDone); }, 0);
+};
+
+Timeline._Impl.prototype.loadJSON = function(url, f) {
+ var tl = this;
+
+
+ var fError = function(statusText, status, xmlhttp) {
+ alert("Failed to load json data from " + url + "\n" + statusText);
+ tl.hideLoadingMessage();
+ };
+ var fDone = function(xmlhttp) {
+ try {
+ f(eval('(' + xmlhttp.responseText + ')'), url);
+ } finally {
+ tl.hideLoadingMessage();
+ }
+ };
+
+ this.showLoadingMessage();
+ window.setTimeout(function() { SimileAjax.XmlHttp.get(url, fError, fDone); }, 0);
+};
+
+Timeline._Impl.prototype._initialize = function() {
+ var containerDiv = this._containerDiv;
+ var doc = containerDiv.ownerDocument;
+
+ containerDiv.className =
+ containerDiv.className.split(" ").concat("timeline-container").join(" ");
+
+ while (containerDiv.firstChild) {
+ containerDiv.removeChild(containerDiv.firstChild);
+ }
+
+ /*
+ * inserting copyright and link to simile
+ */
+ var elmtCopyright = SimileAjax.Graphics.createTranslucentImage(Timeline.urlPrefix + (this.isHorizontal() ? "images/copyright-vertical.png" : "images/copyright.png"));
+ elmtCopyright.className = "timeline-copyright";
+ elmtCopyright.title = "Timeline (c) SIMILE - http://simile.mit.edu/timeline/";
+ SimileAjax.DOM.registerEvent(elmtCopyright, "click", function() { window.location = "http://simile.mit.edu/timeline/"; });
+ containerDiv.appendChild(elmtCopyright);
+
+ /*
+ * creating bands
+ */
+ this._bands = [];
+ for (var i = 0; i < this._bandInfos.length; i++) {
+ var band = new Timeline._Band(this, this._bandInfos[i], i);
+ this._bands.push(band);
+ }
+ this._distributeWidths();
+
+ /*
+ * sync'ing bands
+ */
+ for (var i = 0; i < this._bandInfos.length; i++) {
+ var bandInfo = this._bandInfos[i];
+ if ("syncWith" in bandInfo) {
+ this._bands[i].setSyncWithBand(
+ this._bands[bandInfo.syncWith],
+ ("highlight" in bandInfo) ? bandInfo.highlight : false
+ );
+ }
+ }
+
+ /*
+ * creating loading UI
+ */
+ var message = SimileAjax.Graphics.createMessageBubble(doc);
+ message.containerDiv.className = "timeline-message-container";
+ containerDiv.appendChild(message.containerDiv);
+
+ message.contentDiv.className = "timeline-message";
+ message.contentDiv.innerHTML = "<img src='" + Timeline.urlPrefix + "images/progress-running.gif' /> Loading...";
+
+ this.showLoadingMessage = function() { message.containerDiv.style.display = "block"; };
+ this.hideLoadingMessage = function() { message.containerDiv.style.display = "none"; };
+};
+
+Timeline._Impl.prototype._distributeWidths = function() {
+ var length = this.getPixelLength();
+ var width = this.getPixelWidth();
+ var cumulativeWidth = 0;
+
+ for (var i = 0; i < this._bands.length; i++) {
+ var band = this._bands[i];
+ var bandInfos = this._bandInfos[i];
+ var widthString = bandInfos.width;
+
+ var x = widthString.indexOf("%");
+ if (x > 0) {
+ var percent = parseInt(widthString.substr(0, x));
+ var bandWidth = percent * width / 100;
+ } else {
+ var bandWidth = parseInt(widthString);
+ }
+
+ band.setBandShiftAndWidth(cumulativeWidth, bandWidth);
+ band.setViewLength(length);
+
+ cumulativeWidth += bandWidth;
+ }
+};
+
+/*==================================================
+ * Band
+ *==================================================
+ */
+Timeline._Band = function(timeline, bandInfo, index) {
+ this._timeline = timeline;
+ this._bandInfo = bandInfo;
+ this._index = index;
+
+ this._locale = ("locale" in bandInfo) ? bandInfo.locale : Timeline.getDefaultLocale();
+ this._timeZone = ("timeZone" in bandInfo) ? bandInfo.timeZone : 0;
+ this._labeller = ("labeller" in bandInfo) ? bandInfo.labeller :
+ (("createLabeller" in timeline.getUnit()) ?
+ timeline.getUnit().createLabeller(this._locale, this._timeZone) :
+ new Timeline.GregorianDateLabeller(this._locale, this._timeZone));
+
+ this._dragging = false;
+ this._changing = false;
+ this._originalScrollSpeed = 5; // pixels
+ this._scrollSpeed = this._originalScrollSpeed;
+ this._onScrollListeners = [];
+
+ var b = this;
+ this._syncWithBand = null;
+ this._syncWithBandHandler = function(band) {
+ b._onHighlightBandScroll();
+ };
+ this._selectorListener = function(band) {
+ b._onHighlightBandScroll();
+ };
+
+ /*
+ * Install a textbox to capture keyboard events
+ */
+ var inputDiv = this._timeline.getDocument().createElement("div");
+ inputDiv.className = "timeline-band-input";
+ this._timeline.addDiv(inputDiv);
+
+ this._keyboardInput = document.createElement("input");
+ this._keyboardInput.type = "text";
+ inputDiv.appendChild(this._keyboardInput);
+ SimileAjax.DOM.registerEventWithObject(this._keyboardInput, "keydown", this, "_onKeyDown");
+ SimileAjax.DOM.registerEventWithObject(this._keyboardInput, "keyup", this, "_onKeyUp");
+
+ /*
+ * The band's outer most div that slides with respect to the timeline's div
+ */
+ this._div = this._timeline.getDocument().createElement("div");
+ this._div.className = "timeline-band timeline-band-" + index;
+ this._timeline.addDiv(this._div);
+
+ SimileAjax.DOM.registerEventWithObject(this._div, "mousedown", this, "_onMouseDown");
+ SimileAjax.DOM.registerEventWithObject(this._div, "mousemove", this, "_onMouseMove");
+ SimileAjax.DOM.registerEventWithObject(this._div, "mouseup", this, "_onMouseUp");
+ SimileAjax.DOM.registerEventWithObject(this._div, "mouseout", this, "_onMouseOut");
+ SimileAjax.DOM.registerEventWithObject(this._div, "dblclick", this, "_onDblClick");
+
+ /*
+ * The inner div that contains layers
+ */
+ this._innerDiv = this._timeline.getDocument().createElement("div");
+ this._innerDiv.className = "timeline-band-inner";
+ this._div.appendChild(this._innerDiv);
+
+ /*
+ * Initialize parts of the band
+ */
+ this._ether = bandInfo.ether;
+ bandInfo.ether.initialize(timeline);
+
+ this._etherPainter = bandInfo.etherPainter;
+ bandInfo.etherPainter.initialize(this, timeline);
+
+ this._eventSource = bandInfo.eventSource;
+ if (this._eventSource) {
+ this._eventListener = {
+ onAddMany: function() { b._onAddMany(); },
+ onClear: function() { b._onClear(); }
+ }
+ this._eventSource.addListener(this._eventListener);
+ }
+
+ this._eventPainter = bandInfo.eventPainter;
+ bandInfo.eventPainter.initialize(this, timeline);
+
+ this._decorators = ("decorators" in bandInfo) ? bandInfo.decorators : [];
+ for (var i = 0; i < this._decorators.length; i++) {
+ this._decorators[i].initialize(this, timeline);
+ }
+};
+
+Timeline._Band.SCROLL_MULTIPLES = 5;
+
+Timeline._Band.prototype.dispose = function() {
+ this.closeBubble();
+
+ if (this._eventSource) {
+ this._eventSource.removeListener(this._eventListener);
+ this._eventListener = null;
+ this._eventSource = null;
+ }
+
+ this._timeline = null;
+ this._bandInfo = null;
+
+ this._labeller = null;
+ this._ether = null;
+ this._etherPainter = null;
+ this._eventPainter = null;
+ this._decorators = null;
+
+ this._onScrollListeners = null;
+ this._syncWithBandHandler = null;
+ this._selectorListener = null;
+
+ this._div = null;
+ this._innerDiv = null;
+ this._keyboardInput = null;
+};
+
+Timeline._Band.prototype.addOnScrollListener = function(listener) {
+ this._onScrollListeners.push(listener);
+};
+
+Timeline._Band.prototype.removeOnScrollListener = function(listener) {
+ for (var i = 0; i < this._onScrollListeners.length; i++) {
+ if (this._onScrollListeners[i] == listener) {
+ this._onScrollListeners.splice(i, 1);
+ break;
+ }
+ }
+};
+
+Timeline._Band.prototype.setSyncWithBand = function(band, highlight) {
+ if (this._syncWithBand) {
+ this._syncWithBand.removeOnScrollListener(this._syncWithBandHandler);
+ }
+
+ this._syncWithBand = band;
+ this._syncWithBand.addOnScrollListener(this._syncWithBandHandler);
+ this._highlight = highlight;
+ this._positionHighlight();
+};
+
+Timeline._Band.prototype.getLocale = function() {
+ return this._locale;
+};
+
+Timeline._Band.prototype.getTimeZone = function() {
+ return this._timeZone;
+};
+
+Timeline._Band.prototype.getLabeller = function() {
+ return this._labeller;
+};
+
+Timeline._Band.prototype.getIndex = function() {
+ return this._index;
+};
+
+Timeline._Band.prototype.getEther = function() {
+ return this._ether;
+};
+
+Timeline._Band.prototype.getEtherPainter = function() {
+ return this._etherPainter;
+};
+
+Timeline._Band.prototype.getEventSource = function() {
+ return this._eventSource;
+};
+
+Timeline._Band.prototype.getEventPainter = function() {
+ return this._eventPainter;
+};
+
+Timeline._Band.prototype.layout = function() {
+ this.paint();
+};
+
+Timeline._Band.prototype.paint = function() {
+ this._etherPainter.paint();
+ this._paintDecorators();
+ this._paintEvents();
+};
+
+Timeline._Band.prototype.softLayout = function() {
+ this.softPaint();
+};
+
+Timeline._Band.prototype.softPaint = function() {
+ this._etherPainter.softPaint();
+ this._softPaintDecorators();
+ this._softPaintEvents();
+};
+
+Timeline._Band.prototype.setBandShiftAndWidth = function(shift, width) {
+ var inputDiv = this._keyboardInput.parentNode;
+ var middle = shift + Math.floor(width / 2);
+ if (this._timeline.isHorizontal()) {
+ this._div.style.top = shift + "px";
+ this._div.style.height = width + "px";
+
+ inputDiv.style.top = middle + "px";
+ inputDiv.style.left = "-1em";
+ } else {
+ this._div.style.left = shift + "px";
+ this._div.style.width = width + "px";
+
+ inputDiv.style.left = middle + "px";
+ inputDiv.style.top = "-1em";
+ }
+};
+
+Timeline._Band.prototype.getViewWidth = function() {
+ if (this._timeline.isHorizontal()) {
+ return this._div.offsetHeight;
+ } else {
+ return this._div.offsetWidth;
+ }
+};
+
+Timeline._Band.prototype.setViewLength = function(length) {
+ this._viewLength = length;
+ this._recenterDiv();
+ this._onChanging();
+};
+
+Timeline._Band.prototype.getViewLength = function() {
+ return this._viewLength;
+};
+
+Timeline._Band.prototype.getTotalViewLength = function() {
+ return Timeline._Band.SCROLL_MULTIPLES * this._viewLength;
+};
+
+Timeline._Band.prototype.getViewOffset = function() {
+ return this._viewOffset;
+};
+
+Timeline._Band.prototype.getMinDate = function() {
+ return this._ether.pixelOffsetToDate(this._viewOffset);
+};
+
+Timeline._Band.prototype.getMaxDate = function() {
+ return this._ether.pixelOffsetToDate(this._viewOffset + Timeline._Band.SCROLL_MULTIPLES * this._viewLength);
+};
+
+Timeline._Band.prototype.getMinVisibleDate = function() {
+ return this._ether.pixelOffsetToDate(0);
+};
+
+Timeline._Band.prototype.getMaxVisibleDate = function() {
+ return this._ether.pixelOffsetToDate(this._viewLength);
+};
+
+Timeline._Band.prototype.getCenterVisibleDate = function() {
+ return this._ether.pixelOffsetToDate(this._viewLength / 2);
+};
+
+Timeline._Band.prototype.setMinVisibleDate = function(date) {
+ if (!this._changing) {
+ this._moveEther(Math.round(-this._ether.dateToPixelOffset(date)));
+ }
+};
+
+Timeline._Band.prototype.setMaxVisibleDate = function(date) {
+ if (!this._changing) {
+ this._moveEther(Math.round(this._viewLength - this._ether.dateToPixelOffset(date)));
+ }
+};
+
+Timeline._Band.prototype.setCenterVisibleDate = function(date) {
+ if (!this._changing) {
+ this._moveEther(Math.round(this._viewLength / 2 - this._ether.dateToPixelOffset(date)));
+ }
+};
+
+Timeline._Band.prototype.dateToPixelOffset = function(date) {
+ return this._ether.dateToPixelOffset(date) - this._viewOffset;
+};
+
+Timeline._Band.prototype.pixelOffsetToDate = function(pixels) {
+ return this._ether.pixelOffsetToDate(pixels + this._viewOffset);
+};
+
+Timeline._Band.prototype.createLayerDiv = function(zIndex, className) {
+ var div = this._timeline.getDocument().createElement("div");
+ div.className = "timeline-band-layer" + (typeof className == "string" ? (" " + className) : "");
+ div.style.zIndex = zIndex;
+ this._innerDiv.appendChild(div);
+
+ var innerDiv = this._timeline.getDocument().createElement("div");
+ innerDiv.className = "timeline-band-layer-inner";
+ if (SimileAjax.Platform.browser.isIE) {
+ innerDiv.style.cursor = "move";
+ } else {
+ innerDiv.style.cursor = "-moz-grab";
+ }
+ div.appendChild(innerDiv);
+
+ return innerDiv;
+};
+
+Timeline._Band.prototype.removeLayerDiv = function(div) {
+ this._innerDiv.removeChild(div.parentNode);
+};
+
+Timeline._Band.prototype.scrollToCenter = function(date, f) {
+ var pixelOffset = this._ether.dateToPixelOffset(date);
+ if (pixelOffset < -this._viewLength / 2) {
+ this.setCenterVisibleDate(this.pixelOffsetToDate(pixelOffset + this._viewLength));
+ } else if (pixelOffset > 3 * this._viewLength / 2) {
+ this.setCenterVisibleDate(this.pixelOffsetToDate(pixelOffset - this._viewLength));
+ }
+ this._autoScroll(Math.round(this._viewLength / 2 - this._ether.dateToPixelOffset(date)), f);
+};
+
+Timeline._Band.prototype.showBubbleForEvent = function(eventID) {
+ var evt = this.getEventSource().getEvent(eventID);
+ if (evt) {
+ var self = this;
+ this.scrollToCenter(evt.getStart(), function() {
+ self._eventPainter.showBubble(evt);
+ });
+ }
+};
+
+Timeline._Band.prototype._onMouseDown = function(innerFrame, evt, target) {
+ this.closeBubble();
+
+ this._dragging = true;
+ this._dragX = evt.clientX;
+ this._dragY = evt.clientY;
+};
+
+Timeline._Band.prototype._onMouseMove = function(innerFrame, evt, target) {
+ if (this._dragging) {
+ var diffX = evt.clientX - this._dragX;
+ var diffY = evt.clientY - this._dragY;
+
+ this._dragX = evt.clientX;
+ this._dragY = evt.clientY;
+
+ this._moveEther(this._timeline.isHorizontal() ? diffX : diffY);
+ this._positionHighlight();
+ }
+};
+
+Timeline._Band.prototype._onMouseUp = function(innerFrame, evt, target) {
+ this._dragging = false;
+ this._keyboardInput.focus();
+};
+
+Timeline._Band.prototype._onMouseOut = function(innerFrame, evt, target) {
+ var coords = SimileAjax.DOM.getEventRelativeCoordinates(evt, innerFrame);
+ coords.x += this._viewOffset;
+ if (coords.x < 0 || coords.x > innerFrame.offsetWidth ||
+ coords.y < 0 || coords.y > innerFrame.offsetHeight) {
+ this._dragging = false;
+ }
+};
+
+Timeline._Band.prototype._onDblClick = function(innerFrame, evt, target) {
+ var coords = SimileAjax.DOM.getEventRelativeCoordinates(evt, innerFrame);
+ var distance = coords.x - (this._viewLength / 2 - this._viewOffset);
+
+ this._autoScroll(-distance);
+};
+
+Timeline._Band.prototype._onKeyDown = function(keyboardInput, evt, target) {
+ if (!this._dragging) {
+ switch (evt.keyCode) {
+ case 27: // ESC
+ break;
+ case 37: // left arrow
+ case 38: // up arrow
+ this._scrollSpeed = Math.min(50, Math.abs(this._scrollSpeed * 1.05));
+ this._moveEther(this._scrollSpeed);
+ break;
+ case 39: // right arrow
+ case 40: // down arrow
+ this._scrollSpeed = -Math.min(50, Math.abs(this._scrollSpeed * 1.05));
+ this._moveEther(this._scrollSpeed);
+ break;
+ default:
+ return true;
+ }
+ this.closeBubble();
+
+ SimileAjax.DOM.cancelEvent(evt);
+ return false;
+ }
+ return true;
+};
+
+Timeline._Band.prototype._onKeyUp = function(keyboardInput, evt, target) {
+ if (!this._dragging) {
+ this._scrollSpeed = this._originalScrollSpeed;
+
+ switch (evt.keyCode) {
+ case 35: // end
+ this.setCenterVisibleDate(this._eventSource.getLatestDate());
+ break;
+ case 36: // home
+ this.setCenterVisibleDate(this._eventSource.getEarliestDate());
+ break;
+ case 33: // page up
+ this._autoScroll(this._timeline.getPixelLength());
+ break;
+ case 34: // page down
+ this._autoScroll(-this._timeline.getPixelLength());
+ break;
+ default:
+ return true;
+ }
+
+ this.closeBubble();
+
+ SimileAjax.DOM.cancelEvent(evt);
+ return false;
+ }
+ return true;
+};
+
+Timeline._Band.prototype._autoScroll = function(distance, f) {
+ var b = this;
+ var a = SimileAjax.Graphics.createAnimation(
+ function(abs, diff) {
+ b._moveEther(diff);
+ },
+ 0,
+ distance,
+ 1000,
+ f
+ );
+ a.run();
+};
+
+Timeline._Band.prototype._moveEther = function(shift) {
+ this.closeBubble();
+
+ this._viewOffset += shift;
+ this._ether.shiftPixels(-shift);
+ if (this._timeline.isHorizontal()) {
+ this._div.style.left = this._viewOffset + "px";
+ } else {
+ this._div.style.top = this._viewOffset + "px";
+ }
+
+ if (this._viewOffset > -this._viewLength * 0.5 ||
+ this._viewOffset < -this._viewLength * (Timeline._Band.SCROLL_MULTIPLES - 1.5)) {
+
+ this._recenterDiv();
+ } else {
+ this.softLayout();
+ }
+
+ this._onChanging();
+}
+
+Timeline._Band.prototype._onChanging = function() {
+ this._changing = true;
+
+ this._fireOnScroll();
+ this._setSyncWithBandDate();
+
+ this._changing = false;
+};
+
+Timeline._Band.prototype._fireOnScroll = function() {
+ for (var i = 0; i < this._onScrollListeners.length; i++) {
+ this._onScrollListeners[i](this);
+ }
+};
+
+Timeline._Band.prototype._setSyncWithBandDate = function() {
+ if (this._syncWithBand) {
+ var centerDate = this._ether.pixelOffsetToDate(this.getViewLength() / 2);
+ this._syncWithBand.setCenterVisibleDate(centerDate);
+ }
+};
+
+Timeline._Band.prototype._onHighlightBandScroll = function() {
+ if (this._syncWithBand) {
+ var centerDate = this._syncWithBand.getCenterVisibleDate();
+ var centerPixelOffset = this._ether.dateToPixelOffset(centerDate);
+
+ this._moveEther(Math.round(this._viewLength / 2 - centerPixelOffset));
+
+ if (this._highlight) {
+ this._etherPainter.setHighlight(
+ this._syncWithBand.getMinVisibleDate(),
+ this._syncWithBand.getMaxVisibleDate());
+ }
+ }
+};
+
+Timeline._Band.prototype._onAddMany = function() {
+ this._paintEvents();
+};
+
+Timeline._Band.prototype._onClear = function() {
+ this._paintEvents();
+};
+
+Timeline._Band.prototype._positionHighlight = function() {
+ if (this._syncWithBand) {
+ var startDate = this._syncWithBand.getMinVisibleDate();
+ var endDate = this._syncWithBand.getMaxVisibleDate();
+
+ if (this._highlight) {
+ this._etherPainter.setHighlight(startDate, endDate);
+ }
+ }
+};
+
+Timeline._Band.prototype._recenterDiv = function() {
+ this._viewOffset = -this._viewLength * (Timeline._Band.SCROLL_MULTIPLES - 1) / 2;
+ if (this._timeline.isHorizontal()) {
+ this._div.style.left = this._viewOffset + "px";
+ this._div.style.width = (Timeline._Band.SCROLL_MULTIPLES * this._viewLength) + "px";
+ } else {
+ this._div.style.top = this._viewOffset + "px";
+ this._div.style.height = (Timeline._Band.SCROLL_MULTIPLES * this._viewLength) + "px";
+ }
+ this.layout();
+};
+
+Timeline._Band.prototype._paintEvents = function() {
+ this._eventPainter.paint();
+};
+
+Timeline._Band.prototype._softPaintEvents = function() {
+ this._eventPainter.softPaint();
+};
+
+Timeline._Band.prototype._paintDecorators = function() {
+ for (var i = 0; i < this._decorators.length; i++) {
+ this._decorators[i].paint();
+ }
+};
+
+Timeline._Band.prototype._softPaintDecorators = function() {
+ for (var i = 0; i < this._decorators.length; i++) {
+ this._decorators[i].softPaint();
+ }
+};
+
+Timeline._Band.prototype.closeBubble = function() {
+ SimileAjax.WindowManager.cancelPopups();
+};
diff --git a/site/app/webroot/js/simile/timeline/scripts/units.js b/site/app/webroot/js/simile/timeline/scripts/units.js
new file mode 100755
index 0000000..15ea379
--- /dev/null
+++ b/site/app/webroot/js/simile/timeline/scripts/units.js
@@ -0,0 +1,68 @@
+/*==================================================
+ * Default Unit
+ *==================================================
+ */
+
+Timeline.NativeDateUnit = new Object();
+
+Timeline.NativeDateUnit.createLabeller = function(locale, timeZone) {
+ return new Timeline.GregorianDateLabeller(locale, timeZone);
+};
+
+Timeline.NativeDateUnit.makeDefaultValue = function() {
+ return new Date();
+};
+
+Timeline.NativeDateUnit.cloneValue = function(v) {
+ return new Date(v.getTime());
+};
+
+Timeline.NativeDateUnit.getParser = function(format) {
+ if (typeof format == "string") {
+ format = format.toLowerCase();
+ }
+ return (format == "iso8601" || format == "iso 8601") ?
+ Timeline.DateTime.parseIso8601DateTime :
+ Timeline.DateTime.parseGregorianDateTime;
+};
+
+Timeline.NativeDateUnit.parseFromObject = function(o) {
+ return Timeline.DateTime.parseGregorianDateTime(o);
+};
+
+Timeline.NativeDateUnit.toNumber = function(v) {
+ return v.getTime();
+};
+
+Timeline.NativeDateUnit.fromNumber = function(n) {
+ return new Date(n);
+};
+
+Timeline.NativeDateUnit.compare = function(v1, v2) {
+ var n1, n2;
+ if (typeof v1 == "object") {
+ n1 = v1.getTime();
+ } else {
+ n1 = Number(v1);
+ }
+ if (typeof v2 == "object") {
+ n2 = v2.getTime();
+ } else {
+ n2 = Number(v2);
+ }
+
+ return n1 - n2;
+};
+
+Timeline.NativeDateUnit.earlier = function(v1, v2) {
+ return Timeline.NativeDateUnit.compare(v1, v2) < 0 ? v1 : v2;
+};
+
+Timeline.NativeDateUnit.later = function(v1, v2) {
+ return Timeline.NativeDateUnit.compare(v1, v2) > 0 ? v1 : v2;
+};
+
+Timeline.NativeDateUnit.change = function(v, n) {
+ return new Date(v.getTime() + n);
+};
+
diff --git a/site/app/webroot/js/simile/timeline/timeline-api-amo-bundle.js b/site/app/webroot/js/simile/timeline/timeline-api-amo-bundle.js
new file mode 100644
index 0000000..3559f38
--- /dev/null
+++ b/site/app/webroot/js/simile/timeline/timeline-api-amo-bundle.js
@@ -0,0 +1,25 @@
+////////////////////////////// TIMELINE LOADER /////////////////////////////////
+
+(function() {
+ var useLocalResources = false;
+ if (document.location.search.length > 0) {
+ var params = document.location.search.substr(1).split("&");
+ for (var i = 0; i < params.length; i++) {
+ if (params[i] == "timeline-use-local-resources") {
+ useLocalResources = true;
+ }
+ }
+ };
+
+ var loadMe = function() {
+ if ("Timeline" in window) {
+ return;
+ }
+
+ window.Timeline = new Object();
+ window.Timeline.DateTime = window.SimileAjax.DateTime; // for backward compatibility
+
+ };
+
+ loadMe();
+})(); \ No newline at end of file
diff --git a/site/app/webroot/js/simile/timeline/timeline-api.js b/site/app/webroot/js/simile/timeline/timeline-api.js
new file mode 100755
index 0000000..b827c6c
--- /dev/null
+++ b/site/app/webroot/js/simile/timeline/timeline-api.js
@@ -0,0 +1,224 @@
+/*==================================================
+ * Timeline API
+ *
+ * This file will load all the Javascript files
+ * necessary to make the standard timeline work.
+ * It also detects the default locale.
+ *
+ * Include this file in your HTML file as follows:
+ *
+ * <script src="http://simile.mit.edu/timeline/api/scripts/timeline-api.js" type="text/javascript"></script>
+ *
+ *==================================================
+ */
+
+(function() {
+ var useLocalResources = false;
+ if (document.location.search.length > 0) {
+ var params = document.location.search.substr(1).split("&");
+ for (var i = 0; i < params.length; i++) {
+ if (params[i] == "timeline-use-local-resources") {
+ useLocalResources = true;
+ }
+ }
+ };
+
+ var loadMe = function() {
+ if ("Timeline" in window) {
+ return;
+ }
+
+ window.Timeline = new Object();
+ window.Timeline.DateTime = window.SimileAjax.DateTime; // for backward compatibility
+
+ var bundle = true;
+ var javascriptFiles = [
+ "timeline.js",
+ "themes.js",
+ "ethers.js",
+ "ether-painters.js",
+ "labellers.js",
+ "sources.js",
+ "original-painter.js",
+ "detailed-painter.js",
+ "overview-painter.js",
+ "decorators.js",
+ "units.js"
+ ];
+ var cssFiles = [
+ "timeline.css",
+ "ethers.css",
+ "events.css"
+ ];
+
+ var localizedJavascriptFiles = [
+ "timeline.js",
+ "labellers.js"
+ ];
+ var localizedCssFiles = [
+ ];
+
+ // ISO-639 language codes, ISO-3166 country codes (2 characters)
+ var supportedLocales = [
+ "cs", // Czech
+ "de", // German
+ "en", // English
+ "es", // Spanish
+ "fr", // French
+ "it", // Italian
+ "ru", // Russian
+ "se", // Swedish
+ "tr", // Turkish
+ "vi", // Vietnamese
+ "zh" // Chinese
+ ];
+
+ try {
+ var desiredLocales = [ "en" ];
+ var defaultServerLocale = "en";
+
+ var parseURLParameters = function(parameters) {
+ var params = parameters.split("&");
+ for (var p = 0; p < params.length; p++) {
+ var pair = params[p].split("=");
+ if (pair[0] == "locales") {
+ desiredLocales = desiredLocales.concat(pair[1].split(","));
+ } else if (pair[0] == "defaultLocale") {
+ defaultServerLocale = pair[1];
+ } else if (pair[0] == "bundle") {
+ bundle = pair[1] != "false";
+ }
+ }
+ };
+
+ (function() {
+ if (typeof Timeline_urlPrefix == "string") {
+ Timeline.urlPrefix = Timeline_urlPrefix;
+ if (typeof Timeline_parameters == "string") {
+ parseURLParameters(Timeline_parameters);
+ }
+ } else {
+ var heads = document.documentElement.getElementsByTagName("head");
+ for (var h = 0; h < heads.length; h++) {
+ var scripts = heads[h].getElementsByTagName("script");
+ for (var s = 0; s < scripts.length; s++) {
+ var url = scripts[s].src;
+ var i = url.indexOf("timeline-api.js");
+ if (i >= 0) {
+ Timeline.urlPrefix = url.substr(0, i);
+ var q = url.indexOf("?");
+ if (q > 0) {
+ parseURLParameters(url.substr(q + 1));
+ }
+ return;
+ }
+ }
+ }
+ throw new Error("Failed to derive URL prefix for Timeline API code files");
+ }
+ })();
+
+ var includeJavascriptFiles = function(urlPrefix, filenames) {
+ SimileAjax.includeJavascriptFiles(document, urlPrefix, filenames);
+ }
+ var includeCssFiles = function(urlPrefix, filenames) {
+ SimileAjax.includeCssFiles(document, urlPrefix, filenames);
+ }
+
+ /*
+ * Include non-localized files
+ */
+ if (bundle) {
+ includeJavascriptFiles(Timeline.urlPrefix, [ "timeline-bundle.js" ]);
+ includeCssFiles(Timeline.urlPrefix, [ "timeline-bundle.css" ]);
+ } else {
+ includeJavascriptFiles(Timeline.urlPrefix + "scripts/", javascriptFiles);
+ includeCssFiles(Timeline.urlPrefix + "styles/", cssFiles);
+ }
+
+ /*
+ * Include localized files
+ */
+ var loadLocale = [];
+ loadLocale[defaultServerLocale] = true;
+
+ var tryExactLocale = function(locale) {
+ for (var l = 0; l < supportedLocales.length; l++) {
+ if (locale == supportedLocales[l]) {
+ loadLocale[locale] = true;
+ return true;
+ }
+ }
+ return false;
+ }
+ var tryLocale = function(locale) {
+ if (tryExactLocale(locale)) {
+ return locale;
+ }
+
+ var dash = locale.indexOf("-");
+ if (dash > 0 && tryExactLocale(locale.substr(0, dash))) {
+ return locale.substr(0, dash);
+ }
+
+ return null;
+ }
+
+ for (var l = 0; l < desiredLocales.length; l++) {
+ tryLocale(desiredLocales[l]);
+ }
+
+ var defaultClientLocale = defaultServerLocale;
+ var defaultClientLocales = ("language" in navigator ? navigator.language : navigator.browserLanguage).split(";");
+ for (var l = 0; l < defaultClientLocales.length; l++) {
+ var locale = tryLocale(defaultClientLocales[l]);
+ if (locale != null) {
+ defaultClientLocale = locale;
+ break;
+ }
+ }
+
+ for (var l = 0; l < supportedLocales.length; l++) {
+ var locale = supportedLocales[l];
+ if (loadLocale[locale]) {
+ includeJavascriptFiles(Timeline.urlPrefix + "scripts/l10n/" + locale + "/", localizedJavascriptFiles);
+ includeCssFiles(Timeline.urlPrefix + "styles/l10n/" + locale + "/", localizedCssFiles);
+ }
+ }
+
+ Timeline.serverLocale = defaultServerLocale;
+ Timeline.clientLocale = defaultClientLocale;
+ } catch (e) {
+ alert(e);
+ }
+ };
+
+ /*
+ * Load SimileAjax if it's not already loaded
+ */
+ if (typeof SimileAjax == "undefined") {
+ window.SimileAjax_onLoad = loadMe;
+
+ var url = useLocalResources ?
+ "http://127.0.0.1:9999/ajax/api/simile-ajax-api.js?bundle=false" :
+ "http://static.simile.mit.edu/ajax/api-2.0/simile-ajax-api.js";
+ var createScriptElement = function() {
+ var script = document.createElement("script");
+ script.type = "text/javascript";
+ script.language = "JavaScript";
+ script.src = url;
+ document.getElementsByTagName("head")[0].appendChild(script);
+ }
+ if (document.body == null) {
+ try {
+ document.write("<script src='" + url + "' type='text/javascript'></script>");
+ } catch (e) {
+ createScriptElement();
+ }
+ } else {
+ createScriptElement();
+ }
+ } else {
+ loadMe();
+ }
+})();
diff --git a/site/app/webroot/js/simile/timeline/timeline-bundle.css b/site/app/webroot/js/simile/timeline/timeline-bundle.css
new file mode 100755
index 0000000..62051e0
--- /dev/null
+++ b/site/app/webroot/js/simile/timeline/timeline-bundle.css
@@ -0,0 +1,172 @@
+.timeline-ether-marker-bottom {
+ width: 5em;
+ height: 1.5em;
+ border-left: 1px solid #aaa;
+ padding-left: 2px;
+ color: #aaa;
+}
+
+.timeline-ether-marker-bottom-emphasized {
+ width: 5em;
+ height: 2em;
+ border-left: 1px solid #aaa;
+ padding-left: 2px;
+ color: black;
+}
+
+.timeline-ether-marker-top {
+ width: 5em;
+ height: 1.5em;
+ border-left: 1px solid #aaa;
+ padding-left: 2px;
+ color: #aaa;
+}
+
+.timeline-ether-marker-top-emphasized {
+ width: 5em;
+ height: 2em;
+ border-left: 1px solid #aaa;
+ padding-left: 2px;
+ color: black;
+}
+
+
+.timeline-ether-marker-right {
+ width: 5em;
+ height: 1.5em;
+ border-top: 1px solid #aaa;
+ padding-top: 2px;
+ color: #aaa;
+}
+
+.timeline-ether-marker-right-emphasized {
+ width: 7em;
+ height: 1.5em;
+ border-top: 1px solid #aaa;
+ padding-top: 2px;
+ color: black;
+}
+.timeline-ether-marker-left {
+ width: 5em;
+ height: 1.5em;
+ border-top: 1px solid #aaa;
+ padding-top: 2px;
+ color: #aaa;
+}
+
+.timeline-ether-marker-left-emphasized {
+ width: 7em;
+ height: 1.5em;
+ border-top: 1px solid #aaa;
+ padding-top: 2px;
+ color: black;
+}
+.timeline-duration-event {
+ position: absolute;
+ overflow: hidden;
+ border: 1px solid blue;
+}
+
+.timeline-instant-event2 {
+ position: absolute;
+ overflow: hidden;
+ border-left: 1px solid blue;
+ padding-left: 2px;
+}
+
+.timeline-instant-event {
+ position: absolute;
+ overflow: hidden;
+}
+
+.timeline-event-bubble-title {
+ font-weight: bold;
+ border-bottom: 1px solid #888;
+ margin-bottom: 0.5em;
+}
+
+.timeline-event-bubble-body {
+}
+
+.timeline-event-bubble-wiki {
+ margin: 0.5em;
+ text-align: right;
+ color: #A0A040;
+}
+.timeline-event-bubble-wiki a {
+ color: #A0A040;
+}
+
+.timeline-event-bubble-time {
+ color: #aaa;
+}
+
+.timeline-event-bubble-image {
+ float: right;
+ padding-left: 5px;
+ padding-bottom: 5px;
+}.timeline-container {
+ position: relative;
+ overflow: hidden;
+}
+
+.timeline-copyright {
+ position: absolute;
+ bottom: 0px;
+ left: 0px;
+ z-index: 1000;
+ cursor: pointer;
+}
+
+.timeline-message-container {
+ position: absolute;
+ top: 30%;
+ left: 35%;
+ right: 35%;
+ z-index: 1000;
+ display: none;
+}
+.timeline-message {
+ font-size: 120%;
+ font-weight: bold;
+ text-align: center;
+}
+.timeline-message img {
+ vertical-align: middle;
+}
+
+.timeline-band {
+ position: absolute;
+ background: #eee;
+ z-index: 10;
+}
+
+.timeline-band-inner {
+ position: relative;
+ width: 100%;
+ height: 100%;
+}
+
+.timeline-band-input {
+ position: absolute;
+ width: 1em;
+ height: 1em;
+ overflow: hidden;
+ z-index: 0;
+}
+.timeline-band-input input{
+ width: 0;
+}
+
+.timeline-band-layer {
+ position: absolute;
+ width: 100%;
+ height: 100%;
+}
+
+.timeline-band-layer-inner {
+ position: relative;
+ width: 100%;
+ height: 100%;
+}
+
diff --git a/site/app/webroot/js/simile/timeline/timeline-bundle.js b/site/app/webroot/js/simile/timeline/timeline-bundle.js
new file mode 100755
index 0000000..9eec1b6
--- /dev/null
+++ b/site/app/webroot/js/simile/timeline/timeline-bundle.js
@@ -0,0 +1,4007 @@
+
+
+/* decorators.js */
+
+
+
+Timeline.SpanHighlightDecorator=function(params){
+this._unit=("unit"in params)?params.unit:SimileAjax.NativeDateUnit;
+this._startDate=(typeof params.startDate=="string")?
+this._unit.parseFromObject(params.startDate):params.startDate;
+this._endDate=(typeof params.endDate=="string")?
+this._unit.parseFromObject(params.endDate):params.endDate;
+this._startLabel=params.startLabel;
+this._endLabel=params.endLabel;
+this._color=params.color;
+this._opacity=("opacity"in params)?params.opacity:100;
+};
+
+Timeline.SpanHighlightDecorator.prototype.initialize=function(band,timeline){
+this._band=band;
+this._timeline=timeline;
+
+this._layerDiv=null;
+};
+
+Timeline.SpanHighlightDecorator.prototype.paint=function(){
+if(this._layerDiv!=null){
+this._band.removeLayerDiv(this._layerDiv);
+}
+this._layerDiv=this._band.createLayerDiv(10);
+this._layerDiv.setAttribute("name","span-highlight-decorator");
+this._layerDiv.style.display="none";
+
+var minDate=this._band.getMinDate();
+var maxDate=this._band.getMaxDate();
+
+if(this._unit.compare(this._startDate,maxDate)<0&&
+this._unit.compare(this._endDate,minDate)>0){
+
+minDate=this._unit.later(minDate,this._startDate);
+maxDate=this._unit.earlier(maxDate,this._endDate);
+
+var minPixel=this._band.dateToPixelOffset(minDate);
+var maxPixel=this._band.dateToPixelOffset(maxDate);
+
+var doc=this._timeline.getDocument();
+
+var createTable=function(){
+var table=doc.createElement("table");
+table.insertRow(0).insertCell(0);
+return table;
+};
+
+var div=doc.createElement("div");
+div.style.position="absolute";
+div.style.overflow="hidden";
+div.style.background=this._color;
+if(this._opacity<100){
+SimileAjax.Graphics.setOpacity(div,this._opacity);
+}
+this._layerDiv.appendChild(div);
+
+var tableStartLabel=createTable();
+tableStartLabel.style.position="absolute";
+tableStartLabel.style.overflow="hidden";
+tableStartLabel.style.fontSize="200%";
+tableStartLabel.style.fontWeight="bold";
+tableStartLabel.style.color=this._color;
+tableStartLabel.rows[0].cells[0].innerHTML=this._startLabel;
+this._layerDiv.appendChild(tableStartLabel);
+
+var tableEndLabel=createTable();
+tableEndLabel.style.position="absolute";
+tableEndLabel.style.overflow="hidden";
+tableEndLabel.style.fontSize="200%";
+tableEndLabel.style.fontWeight="bold";
+tableEndLabel.style.color=this._color;
+tableEndLabel.rows[0].cells[0].innerHTML=this._endLabel;
+this._layerDiv.appendChild(tableEndLabel);
+
+if(this._timeline.isHorizontal()){
+div.style.left=minPixel+"px";
+div.style.width=(maxPixel-minPixel)+"px";
+div.style.top="0px";
+div.style.height="100%";
+
+tableStartLabel.style.right=(this._band.getTotalViewLength()-minPixel)+"px";
+tableStartLabel.style.width=(this._startLabel.length)+"em";
+tableStartLabel.style.top="0px";
+tableStartLabel.style.height="100%";
+tableStartLabel.style.textAlign="right";
+tableStartLabel.rows[0].style.verticalAlign="top";
+
+tableEndLabel.style.left=maxPixel+"px";
+tableEndLabel.style.width=(this._endLabel.length)+"em";
+tableEndLabel.style.top="0px";
+tableEndLabel.style.height="100%";
+tableEndLabel.rows[0].style.verticalAlign="top";
+}else{
+div.style.top=minPixel+"px";
+div.style.height=(maxPixel-minPixel)+"px";
+div.style.left="0px";
+div.style.width="100%";
+
+tableStartLabel.style.bottom=minPixel+"px";
+tableStartLabel.style.height="1.5px";
+tableStartLabel.style.left="0px";
+tableStartLabel.style.width="100%";
+
+tableEndLabel.style.top=maxPixel+"px";
+tableEndLabel.style.height="1.5px";
+tableEndLabel.style.left="0px";
+tableEndLabel.style.width="100%";
+}
+}
+this._layerDiv.style.display="block";
+};
+
+Timeline.SpanHighlightDecorator.prototype.softPaint=function(){
+};
+
+
+
+Timeline.PointHighlightDecorator=function(params){
+this._unit=("unit"in params)?params.unit:SimileAjax.NativeDateUnit;
+this._date=(typeof params.date=="string")?
+this._unit.parseFromObject(params.date):params.date;
+this._width=("width"in params)?params.width:10;
+this._color=params.color;
+this._opacity=("opacity"in params)?params.opacity:100;
+};
+
+Timeline.PointHighlightDecorator.prototype.initialize=function(band,timeline){
+this._band=band;
+this._timeline=timeline;
+
+this._layerDiv=null;
+};
+
+Timeline.PointHighlightDecorator.prototype.paint=function(){
+if(this._layerDiv!=null){
+this._band.removeLayerDiv(this._layerDiv);
+}
+this._layerDiv=this._band.createLayerDiv(10);
+this._layerDiv.setAttribute("name","span-highlight-decorator");
+this._layerDiv.style.display="none";
+
+var minDate=this._band.getMinDate();
+var maxDate=this._band.getMaxDate();
+
+if(this._unit.compare(this._date,maxDate)<0&&
+this._unit.compare(this._date,minDate)>0){
+
+var pixel=this._band.dateToPixelOffset(this._date);
+var minPixel=pixel-Math.round(this._width/2);
+
+var doc=this._timeline.getDocument();
+
+var div=doc.createElement("div");
+div.style.position="absolute";
+div.style.overflow="hidden";
+div.style.background=this._color;
+if(this._opacity<100){
+SimileAjax.Graphics.setOpacity(div,this._opacity);
+}
+this._layerDiv.appendChild(div);
+
+if(this._timeline.isHorizontal()){
+div.style.left=minPixel+"px";
+div.style.width=this._width+"px";
+div.style.top="0px";
+div.style.height="100%";
+}else{
+div.style.top=minPixel+"px";
+div.style.height=this._width+"px";
+div.style.left="0px";
+div.style.width="100%";
+}
+}
+this._layerDiv.style.display="block";
+};
+
+Timeline.PointHighlightDecorator.prototype.softPaint=function(){
+};
+
+
+/* detailed-painter.js */
+
+
+
+Timeline.DetailedEventPainter=function(params){
+this._params=params;
+this._onSelectListeners=[];
+
+this._filterMatcher=null;
+this._highlightMatcher=null;
+this._frc=null;
+
+this._eventIdToElmt={};
+};
+
+Timeline.DetailedEventPainter.prototype.initialize=function(band,timeline){
+this._band=band;
+this._timeline=timeline;
+
+this._backLayer=null;
+this._eventLayer=null;
+this._lineLayer=null;
+this._highlightLayer=null;
+
+this._eventIdToElmt=null;
+};
+
+Timeline.DetailedEventPainter.prototype.addOnSelectListener=function(listener){
+this._onSelectListeners.push(listener);
+};
+
+Timeline.DetailedEventPainter.prototype.removeOnSelectListener=function(listener){
+for(var i=0;i<this._onSelectListeners.length;i++){
+if(this._onSelectListeners[i]==listener){
+this._onSelectListeners.splice(i,1);
+break;
+}
+}
+};
+
+Timeline.DetailedEventPainter.prototype.getFilterMatcher=function(){
+return this._filterMatcher;
+};
+
+Timeline.DetailedEventPainter.prototype.setFilterMatcher=function(filterMatcher){
+this._filterMatcher=filterMatcher;
+};
+
+Timeline.DetailedEventPainter.prototype.getHighlightMatcher=function(){
+return this._highlightMatcher;
+};
+
+Timeline.DetailedEventPainter.prototype.setHighlightMatcher=function(highlightMatcher){
+this._highlightMatcher=highlightMatcher;
+};
+
+Timeline.DetailedEventPainter.prototype.paint=function(){
+var eventSource=this._band.getEventSource();
+if(eventSource==null){
+return;
+}
+
+this._eventIdToElmt={};
+this._prepareForPainting();
+
+var eventTheme=this._params.theme.event;
+var trackHeight=Math.max(eventTheme.track.height,this._frc.getLineHeight());
+var metrics={
+trackOffset:Math.round(this._band.getViewWidth()/2-trackHeight/2),
+trackHeight:trackHeight,
+trackGap:eventTheme.track.gap,
+trackIncrement:trackHeight+eventTheme.track.gap,
+icon:eventTheme.instant.icon,
+iconWidth:eventTheme.instant.iconWidth,
+iconHeight:eventTheme.instant.iconHeight,
+labelWidth:eventTheme.label.width
+}
+
+var minDate=this._band.getMinDate();
+var maxDate=this._band.getMaxDate();
+
+var filterMatcher=(this._filterMatcher!=null)?
+this._filterMatcher:
+function(evt){return true;};
+var highlightMatcher=(this._highlightMatcher!=null)?
+this._highlightMatcher:
+function(evt){return-1;};
+
+var iterator=eventSource.getEventReverseIterator(minDate,maxDate);
+while(iterator.hasNext()){
+var evt=iterator.next();
+if(filterMatcher(evt)){
+this.paintEvent(evt,metrics,this._params.theme,highlightMatcher(evt));
+}
+}
+
+this._highlightLayer.style.display="block";
+this._lineLayer.style.display="block";
+this._eventLayer.style.display="block";
+};
+
+Timeline.DetailedEventPainter.prototype.softPaint=function(){
+};
+
+Timeline.DetailedEventPainter.prototype._prepareForPainting=function(){
+var band=this._band;
+
+if(this._backLayer==null){
+this._backLayer=this._band.createLayerDiv(0,"timeline-band-events");
+this._backLayer.style.visibility="hidden";
+
+var eventLabelPrototype=document.createElement("span");
+eventLabelPrototype.className="timeline-event-label";
+this._backLayer.appendChild(eventLabelPrototype);
+this._frc=SimileAjax.Graphics.getFontRenderingContext(eventLabelPrototype);
+}
+this._frc.update();
+this._lowerTracks=[];
+this._upperTracks=[];
+
+if(this._highlightLayer!=null){
+band.removeLayerDiv(this._highlightLayer);
+}
+this._highlightLayer=band.createLayerDiv(105,"timeline-band-highlights");
+this._highlightLayer.style.display="none";
+
+if(this._lineLayer!=null){
+band.removeLayerDiv(this._lineLayer);
+}
+this._lineLayer=band.createLayerDiv(110,"timeline-band-lines");
+this._lineLayer.style.display="none";
+
+if(this._eventLayer!=null){
+band.removeLayerDiv(this._eventLayer);
+}
+this._eventLayer=band.createLayerDiv(110,"timeline-band-events");
+this._eventLayer.style.display="none";
+};
+
+Timeline.DetailedEventPainter.prototype.paintEvent=function(evt,metrics,theme,highlightIndex){
+if(evt.isInstant()){
+this.paintInstantEvent(evt,metrics,theme,highlightIndex);
+}else{
+this.paintDurationEvent(evt,metrics,theme,highlightIndex);
+}
+};
+
+Timeline.DetailedEventPainter.prototype.paintInstantEvent=function(evt,metrics,theme,highlightIndex){
+if(evt.isImprecise()){
+this.paintImpreciseInstantEvent(evt,metrics,theme,highlightIndex);
+}else{
+this.paintPreciseInstantEvent(evt,metrics,theme,highlightIndex);
+}
+}
+
+Timeline.DetailedEventPainter.prototype.paintDurationEvent=function(evt,metrics,theme,highlightIndex){
+if(evt.isImprecise()){
+this.paintImpreciseDurationEvent(evt,metrics,theme,highlightIndex);
+}else{
+this.paintPreciseDurationEvent(evt,metrics,theme,highlightIndex);
+}
+}
+
+Timeline.DetailedEventPainter.prototype.paintPreciseInstantEvent=function(evt,metrics,theme,highlightIndex){
+var doc=this._timeline.getDocument();
+var text=evt.getText();
+
+var startDate=evt.getStart();
+var startPixel=Math.round(this._band.dateToPixelOffset(startDate));
+var iconRightEdge=Math.round(startPixel+metrics.iconWidth/2);
+var iconLeftEdge=Math.round(startPixel-metrics.iconWidth/2);
+
+var labelSize=this._frc.computeSize(text);
+var iconTrack=this._findFreeTrackForSolid(iconRightEdge,startPixel);
+var iconElmtData=this._paintEventIcon(evt,iconTrack,iconLeftEdge,metrics,theme);
+
+var labelLeft=iconRightEdge+theme.event.label.offsetFromLine;
+var labelTrack=iconTrack;
+
+var iconTrackData=this._getTrackData(iconTrack);
+if(Math.min(iconTrackData.solid,iconTrackData.text)>=labelLeft+labelSize.width){
+iconTrackData.solid=iconLeftEdge;
+iconTrackData.text=labelLeft;
+}else{
+iconTrackData.solid=iconLeftEdge;
+
+labelLeft=startPixel+theme.event.label.offsetFromLine;
+labelTrack=this._findFreeTrackForText(iconTrack,labelLeft+labelSize.width,function(t){t.line=startPixel-2;});
+this._getTrackData(labelTrack).text=iconLeftEdge;
+
+this._paintEventLine(evt,startPixel,iconTrack,labelTrack,metrics,theme);
+}
+
+var labelTop=Math.round(
+metrics.trackOffset+labelTrack*metrics.trackIncrement+
+metrics.trackHeight/2-labelSize.height/2);
+
+var labelElmtData=this._paintEventLabel(evt,text,labelLeft,labelTop,labelSize.width,labelSize.height,theme);
+
+var self=this;
+var clickHandler=function(elmt,domEvt,target){
+return self._onClickInstantEvent(iconElmtData.elmt,domEvt,evt);
+};
+SimileAjax.DOM.registerEvent(iconElmtData.elmt,"mousedown",clickHandler);
+SimileAjax.DOM.registerEvent(labelElmtData.elmt,"mousedown",clickHandler);
+
+this._createHighlightDiv(highlightIndex,iconElmtData,theme);
+
+this._eventIdToElmt[evt.getID()]=iconElmtData.elmt;
+};
+
+Timeline.DetailedEventPainter.prototype.paintImpreciseInstantEvent=function(evt,metrics,theme,highlightIndex){
+var doc=this._timeline.getDocument();
+var text=evt.getText();
+
+var startDate=evt.getStart();
+var endDate=evt.getEnd();
+var startPixel=Math.round(this._band.dateToPixelOffset(startDate));
+var endPixel=Math.round(this._band.dateToPixelOffset(endDate));
+
+var iconRightEdge=Math.round(startPixel+metrics.iconWidth/2);
+var iconLeftEdge=Math.round(startPixel-metrics.iconWidth/2);
+
+var labelSize=this._frc.computeSize(text);
+var iconTrack=this._findFreeTrackForSolid(endPixel,startPixel);
+
+var tapeElmtData=this._paintEventTape(evt,iconTrack,startPixel,endPixel,
+theme.event.instant.impreciseColor,theme.event.instant.impreciseOpacity,metrics,theme);
+var iconElmtData=this._paintEventIcon(evt,iconTrack,iconLeftEdge,metrics,theme);
+
+var iconTrackData=this._getTrackData(iconTrack);
+iconTrackData.solid=iconLeftEdge;
+
+var labelLeft=iconRightEdge+theme.event.label.offsetFromLine;
+var labelRight=labelLeft+labelSize.width;
+var labelTrack;
+if(labelRight<endPixel){
+labelTrack=iconTrack;
+}else{
+labelLeft=startPixel+theme.event.label.offsetFromLine;
+labelRight=labelLeft+labelSize.width;
+
+labelTrack=this._findFreeTrackForText(iconTrack,labelRight,function(t){t.line=startPixel-2;});
+this._getTrackData(labelTrack).text=iconLeftEdge;
+
+this._paintEventLine(evt,startPixel,iconTrack,labelTrack,metrics,theme);
+}
+var labelTop=Math.round(
+metrics.trackOffset+labelTrack*metrics.trackIncrement+
+metrics.trackHeight/2-labelSize.height/2);
+
+var labelElmtData=this._paintEventLabel(evt,text,labelLeft,labelTop,labelSize.width,labelSize.height,theme);
+
+var self=this;
+var clickHandler=function(elmt,domEvt,target){
+return self._onClickInstantEvent(iconElmtData.elmt,domEvt,evt);
+};
+SimileAjax.DOM.registerEvent(iconElmtData.elmt,"mousedown",clickHandler);
+SimileAjax.DOM.registerEvent(tapeElmtData.elmt,"mousedown",clickHandler);
+SimileAjax.DOM.registerEvent(labelElmtData.elmt,"mousedown",clickHandler);
+
+this._createHighlightDiv(highlightIndex,iconElmtData,theme);
+
+this._eventIdToElmt[evt.getID()]=iconElmtData.elmt;
+};
+
+Timeline.DetailedEventPainter.prototype.paintPreciseDurationEvent=function(evt,metrics,theme,highlightIndex){
+var doc=this._timeline.getDocument();
+var text=evt.getText();
+
+var startDate=evt.getStart();
+var endDate=evt.getEnd();
+var startPixel=Math.round(this._band.dateToPixelOffset(startDate));
+var endPixel=Math.round(this._band.dateToPixelOffset(endDate));
+
+var labelSize=this._frc.computeSize(text);
+var tapeTrack=this._findFreeTrackForSolid(endPixel);
+var color=evt.getColor();
+color=color!=null?color:theme.event.duration.color;
+
+var tapeElmtData=this._paintEventTape(evt,tapeTrack,startPixel,endPixel,color,100,metrics,theme);
+
+var tapeTrackData=this._getTrackData(tapeTrack);
+tapeTrackData.solid=startPixel;
+
+var labelLeft=startPixel+theme.event.label.offsetFromLine;
+var labelTrack=this._findFreeTrackForText(tapeTrack,labelLeft+labelSize.width,function(t){t.line=startPixel-2;});
+this._getTrackData(labelTrack).text=startPixel-2;
+
+this._paintEventLine(evt,startPixel,tapeTrack,labelTrack,metrics,theme);
+
+var labelTop=Math.round(
+metrics.trackOffset+labelTrack*metrics.trackIncrement+
+metrics.trackHeight/2-labelSize.height/2);
+
+var labelElmtData=this._paintEventLabel(evt,text,labelLeft,labelTop,labelSize.width,labelSize.height,theme);
+
+var self=this;
+var clickHandler=function(elmt,domEvt,target){
+return self._onClickDurationEvent(tapeElmtData.elmt,domEvt,evt);
+};
+SimileAjax.DOM.registerEvent(tapeElmtData.elmt,"mousedown",clickHandler);
+SimileAjax.DOM.registerEvent(labelElmtData.elmt,"mousedown",clickHandler);
+
+this._createHighlightDiv(highlightIndex,tapeElmtData,theme);
+
+this._eventIdToElmt[evt.getID()]=tapeElmtData.elmt;
+};
+
+Timeline.DetailedEventPainter.prototype.paintImpreciseDurationEvent=function(evt,metrics,theme,highlightIndex){
+var doc=this._timeline.getDocument();
+var text=evt.getText();
+
+var startDate=evt.getStart();
+var latestStartDate=evt.getLatestStart();
+var endDate=evt.getEnd();
+var earliestEndDate=evt.getEarliestEnd();
+
+var startPixel=Math.round(this._band.dateToPixelOffset(startDate));
+var latestStartPixel=Math.round(this._band.dateToPixelOffset(latestStartDate));
+var endPixel=Math.round(this._band.dateToPixelOffset(endDate));
+var earliestEndPixel=Math.round(this._band.dateToPixelOffset(earliestEndDate));
+
+var labelSize=this._frc.computeSize(text);
+var tapeTrack=this._findFreeTrackForSolid(endPixel);
+var color=evt.getColor();
+color=color!=null?color:theme.event.duration.color;
+
+var impreciseTapeElmtData=this._paintEventTape(evt,tapeTrack,startPixel,endPixel,
+theme.event.duration.impreciseColor,theme.event.duration.impreciseOpacity,metrics,theme);
+var tapeElmtData=this._paintEventTape(evt,tapeTrack,latestStartPixel,earliestEndPixel,color,100,metrics,theme);
+
+var tapeTrackData=this._getTrackData(tapeTrack);
+tapeTrackData.solid=startPixel;
+
+var labelLeft=latestStartPixel+theme.event.label.offsetFromLine;
+var labelTrack=this._findFreeTrackForText(tapeTrack,labelLeft+labelSize.width,function(t){t.line=latestStartPixel-2;});
+this._getTrackData(labelTrack).text=latestStartPixel-2;
+
+this._paintEventLine(evt,latestStartPixel,tapeTrack,labelTrack,metrics,theme);
+
+var labelTop=Math.round(
+metrics.trackOffset+labelTrack*metrics.trackIncrement+
+metrics.trackHeight/2-labelSize.height/2);
+
+var labelElmtData=this._paintEventLabel(evt,text,labelLeft,labelTop,labelSize.width,labelSize.height,theme);
+
+var self=this;
+var clickHandler=function(elmt,domEvt,target){
+return self._onClickDurationEvent(tapeElmtData.elmt,domEvt,evt);
+};
+SimileAjax.DOM.registerEvent(tapeElmtData.elmt,"mousedown",clickHandler);
+SimileAjax.DOM.registerEvent(labelElmtData.elmt,"mousedown",clickHandler);
+
+this._createHighlightDiv(highlightIndex,tapeElmtData,theme);
+
+this._eventIdToElmt[evt.getID()]=tapeElmtData.elmt;
+};
+
+Timeline.DetailedEventPainter.prototype._findFreeTrackForSolid=function(solidEdge,softEdge){
+for(var i=0;true;i++){
+if(i<this._lowerTracks.length){
+var t=this._lowerTracks[i];
+if(Math.min(t.solid,t.text)>solidEdge&&(!(softEdge)||t.line>softEdge)){
+return i;
+}
+}else{
+this._lowerTracks.push({
+solid:Number.POSITIVE_INFINITY,
+text:Number.POSITIVE_INFINITY,
+line:Number.POSITIVE_INFINITY
+});
+
+return i;
+}
+
+if(i<this._upperTracks.length){
+var t=this._upperTracks[i];
+if(Math.min(t.solid,t.text)>solidEdge&&(!(softEdge)||t.line>softEdge)){
+return-1-i;
+}
+}else{
+this._upperTracks.push({
+solid:Number.POSITIVE_INFINITY,
+text:Number.POSITIVE_INFINITY,
+line:Number.POSITIVE_INFINITY
+});
+
+return-1-i;
+}
+}
+};
+
+Timeline.DetailedEventPainter.prototype._findFreeTrackForText=function(fromTrack,edge,occupiedTrackVisitor){
+var extendUp;
+var index;
+var firstIndex;
+var result;
+
+if(fromTrack<0){
+extendUp=true;
+firstIndex=-fromTrack;
+
+index=this._findFreeUpperTrackForText(firstIndex,edge);
+result=-1-index;
+}else if(fromTrack>0){
+extendUp=false;
+firstIndex=fromTrack+1;
+
+index=this._findFreeLowerTrackForText(firstIndex,edge);
+result=index;
+}else{
+var upIndex=this._findFreeUpperTrackForText(0,edge);
+var downIndex=this._findFreeLowerTrackForText(1,edge);
+
+if(downIndex-1<=upIndex){
+extendUp=false;
+firstIndex=1;
+index=downIndex;
+result=index;
+}else{
+extendUp=true;
+firstIndex=0;
+index=upIndex;
+result=-1-index;
+}
+}
+
+if(extendUp){
+if(index==this._upperTracks.length){
+this._upperTracks.push({
+solid:Number.POSITIVE_INFINITY,
+text:Number.POSITIVE_INFINITY,
+line:Number.POSITIVE_INFINITY
+});
+}
+for(var i=firstIndex;i<index;i++){
+occupiedTrackVisitor(this._upperTracks[i]);
+}
+}else{
+if(index==this._lowerTracks.length){
+this._lowerTracks.push({
+solid:Number.POSITIVE_INFINITY,
+text:Number.POSITIVE_INFINITY,
+line:Number.POSITIVE_INFINITY
+});
+}
+for(var i=firstIndex;i<index;i++){
+occupiedTrackVisitor(this._lowerTracks[i]);
+}
+}
+return result;
+};
+
+Timeline.DetailedEventPainter.prototype._findFreeLowerTrackForText=function(index,edge){
+for(;index<this._lowerTracks.length;index++){
+var t=this._lowerTracks[index];
+if(Math.min(t.solid,t.text)>=edge){
+break;
+}
+}
+return index;
+};
+
+Timeline.DetailedEventPainter.prototype._findFreeUpperTrackForText=function(index,edge){
+for(;index<this._upperTracks.length;index++){
+var t=this._upperTracks[index];
+if(Math.min(t.solid,t.text)>=edge){
+break;
+}
+}
+return index;
+};
+
+Timeline.DetailedEventPainter.prototype._getTrackData=function(index){
+return(index<0)?this._upperTracks[-index-1]:this._lowerTracks[index];
+};
+
+Timeline.DetailedEventPainter.prototype._paintEventLine=function(evt,left,startTrack,endTrack,metrics,theme){
+var top=Math.round(metrics.trackOffset+startTrack*metrics.trackIncrement+metrics.trackHeight/2);
+var height=Math.round(Math.abs(endTrack-startTrack)*metrics.trackIncrement);
+
+var lineStyle="1px solid "+theme.event.label.lineColor;
+var lineDiv=this._timeline.getDocument().createElement("div");
+lineDiv.style.position="absolute";
+lineDiv.style.left=left+"px";
+lineDiv.style.width=theme.event.label.offsetFromLine+"px";
+lineDiv.style.height=height+"px";
+if(startTrack>endTrack){
+lineDiv.style.top=(top-height)+"px";
+lineDiv.style.borderTop=lineStyle;
+}else{
+lineDiv.style.top=top+"px";
+lineDiv.style.borderBottom=lineStyle;
+}
+lineDiv.style.borderLeft=lineStyle;
+this._lineLayer.appendChild(lineDiv);
+};
+
+Timeline.DetailedEventPainter.prototype._paintEventIcon=function(evt,iconTrack,left,metrics,theme){
+var icon=evt.getIcon();
+icon=icon!=null?icon:metrics.icon;
+
+var middle=metrics.trackOffset+iconTrack*metrics.trackIncrement+metrics.trackHeight/2;
+var top=Math.round(middle-metrics.iconHeight/2);
+
+var img=SimileAjax.Graphics.createTranslucentImage(icon);
+var iconDiv=this._timeline.getDocument().createElement("div");
+iconDiv.style.position="absolute";
+iconDiv.style.left=left+"px";
+iconDiv.style.top=top+"px";
+iconDiv.appendChild(img);
+iconDiv.style.cursor="pointer";
+this._eventLayer.appendChild(iconDiv);
+
+return{
+left:left,
+top:top,
+width:metrics.iconWidth,
+height:metrics.iconHeight,
+elmt:iconDiv
+};
+};
+
+Timeline.DetailedEventPainter.prototype._paintEventLabel=function(evt,text,left,top,width,height,theme){
+var doc=this._timeline.getDocument();
+
+var labelBackgroundDiv=doc.createElement("div");
+labelBackgroundDiv.style.position="absolute";
+labelBackgroundDiv.style.left=left+"px";
+labelBackgroundDiv.style.width=width+"px";
+labelBackgroundDiv.style.top=top+"px";
+labelBackgroundDiv.style.height=height+"px";
+labelBackgroundDiv.style.backgroundColor=theme.event.label.backgroundColor;
+SimileAjax.Graphics.setOpacity(labelBackgroundDiv,theme.event.label.backgroundOpacity);
+this._eventLayer.appendChild(labelBackgroundDiv);
+
+var labelDiv=doc.createElement("div");
+labelDiv.style.position="absolute";
+labelDiv.style.left=left+"px";
+labelDiv.style.width=width+"px";
+labelDiv.style.top=top+"px";
+labelDiv.innerHTML=text;
+labelDiv.style.cursor="pointer";
+
+var color=evt.getTextColor();
+if(color==null){
+color=evt.getColor();
+}
+if(color!=null){
+labelDiv.style.color=color;
+}
+
+this._eventLayer.appendChild(labelDiv);
+
+return{
+left:left,
+top:top,
+width:width,
+height:height,
+elmt:labelDiv
+};
+};
+
+Timeline.DetailedEventPainter.prototype._paintEventTape=function(
+evt,iconTrack,startPixel,endPixel,color,opacity,metrics,theme){
+
+var tapeWidth=endPixel-startPixel;
+var tapeHeight=theme.event.tape.height;
+var middle=metrics.trackOffset+iconTrack*metrics.trackIncrement+metrics.trackHeight/2;
+var top=Math.round(middle-tapeHeight/2);
+
+var tapeDiv=this._timeline.getDocument().createElement("div");
+tapeDiv.style.position="absolute";
+tapeDiv.style.left=startPixel+"px";
+tapeDiv.style.width=tapeWidth+"px";
+tapeDiv.style.top=top+"px";
+tapeDiv.style.height=tapeHeight+"px";
+tapeDiv.style.backgroundColor=color;
+tapeDiv.style.overflow="hidden";
+tapeDiv.style.cursor="pointer";
+SimileAjax.Graphics.setOpacity(tapeDiv,opacity);
+
+this._eventLayer.appendChild(tapeDiv);
+
+return{
+left:startPixel,
+top:top,
+width:tapeWidth,
+height:tapeHeight,
+elmt:tapeDiv
+};
+}
+
+Timeline.DetailedEventPainter.prototype._createHighlightDiv=function(highlightIndex,dimensions,theme){
+if(highlightIndex>=0){
+var doc=this._timeline.getDocument();
+var eventTheme=theme.event;
+
+var color=eventTheme.highlightColors[Math.min(highlightIndex,eventTheme.highlightColors.length-1)];
+
+var div=doc.createElement("div");
+div.style.position="absolute";
+div.style.overflow="hidden";
+div.style.left=(dimensions.left-2)+"px";
+div.style.width=(dimensions.width+4)+"px";
+div.style.top=(dimensions.top-2)+"px";
+div.style.height=(dimensions.height+4)+"px";
+div.style.background=color;
+
+this._highlightLayer.appendChild(div);
+}
+};
+
+Timeline.DetailedEventPainter.prototype._onClickInstantEvent=function(icon,domEvt,evt){
+var c=SimileAjax.DOM.getPageCoordinates(icon);
+this._showBubble(
+c.left+Math.ceil(icon.offsetWidth/2),
+c.top+Math.ceil(icon.offsetHeight/2),
+evt
+);
+this._fireOnSelect(evt.getID());
+
+domEvt.cancelBubble=true;
+SimileAjax.DOM.cancelEvent(domEvt);
+return false;
+};
+
+Timeline.DetailedEventPainter.prototype._onClickDurationEvent=function(target,domEvt,evt){
+if("pageX"in domEvt){
+var x=domEvt.pageX;
+var y=domEvt.pageY;
+}else{
+var c=SimileAjax.DOM.getPageCoordinates(target);
+var x=domEvt.offsetX+c.left;
+var y=domEvt.offsetY+c.top;
+}
+this._showBubble(x,y,evt);
+this._fireOnSelect(evt.getID());
+
+domEvt.cancelBubble=true;
+SimileAjax.DOM.cancelEvent(domEvt);
+return false;
+};
+
+Timeline.DetailedEventPainter.prototype.showBubble=function(evt){
+var elmt=this._eventIdToElmt[evt.getID()];
+if(elmt){
+var c=SimileAjax.DOM.getPageCoordinates(elmt);
+this._showBubble(c.left+elmt.offsetWidth/2,c.top+elmt.offsetHeight/2,evt);
+}
+};
+
+Timeline.DetailedEventPainter.prototype._showBubble=function(x,y,evt){
+var div=document.createElement("div");
+evt.fillInfoBubble(div,this._params.theme,this._band.getLabeller());
+
+SimileAjax.WindowManager.cancelPopups();
+SimileAjax.Graphics.createBubbleForContentAndPoint(div,x,y,this._params.theme.event.bubble.width);
+};
+
+Timeline.DetailedEventPainter.prototype._fireOnSelect=function(eventID){
+for(var i=0;i<this._onSelectListeners.length;i++){
+this._onSelectListeners[i](eventID);
+}
+};
+
+
+/* ether-painters.js */
+
+
+
+Timeline.GregorianEtherPainter=function(params){
+this._params=params;
+this._theme=params.theme;
+this._unit=params.unit;
+this._multiple=("multiple"in params)?params.multiple:1;
+};
+
+Timeline.GregorianEtherPainter.prototype.initialize=function(band,timeline){
+this._band=band;
+this._timeline=timeline;
+
+this._backgroundLayer=band.createLayerDiv(0);
+this._backgroundLayer.setAttribute("name","ether-background");
+this._backgroundLayer.style.background=this._theme.ether.backgroundColors[band.getIndex()];
+
+this._markerLayer=null;
+this._lineLayer=null;
+
+var align=("align"in this._params&&this._params.align!=undefined)?this._params.align:
+this._theme.ether.interval.marker[timeline.isHorizontal()?"hAlign":"vAlign"];
+var showLine=("showLine"in this._params)?this._params.showLine:
+this._theme.ether.interval.line.show;
+
+this._intervalMarkerLayout=new Timeline.EtherIntervalMarkerLayout(
+this._timeline,this._band,this._theme,align,showLine);
+
+this._highlight=new Timeline.EtherHighlight(
+this._timeline,this._band,this._theme,this._backgroundLayer);
+}
+
+Timeline.GregorianEtherPainter.prototype.setHighlight=function(startDate,endDate){
+this._highlight.position(startDate,endDate);
+}
+
+Timeline.GregorianEtherPainter.prototype.paint=function(){
+if(this._markerLayer){
+this._band.removeLayerDiv(this._markerLayer);
+}
+this._markerLayer=this._band.createLayerDiv(100);
+this._markerLayer.setAttribute("name","ether-markers");
+this._markerLayer.style.display="none";
+
+if(this._lineLayer){
+this._band.removeLayerDiv(this._lineLayer);
+}
+this._lineLayer=this._band.createLayerDiv(1);
+this._lineLayer.setAttribute("name","ether-lines");
+this._lineLayer.style.display="none";
+
+var minDate=this._band.getMinDate();
+var maxDate=this._band.getMaxDate();
+
+var timeZone=this._band.getTimeZone();
+var labeller=this._band.getLabeller();
+
+SimileAjax.DateTime.roundDownToInterval(minDate,this._unit,timeZone,this._multiple,this._theme.firstDayOfWeek);
+
+var p=this;
+var incrementDate=function(date){
+for(var i=0;i<p._multiple;i++){
+SimileAjax.DateTime.incrementByInterval(date,p._unit);
+}
+};
+
+while(minDate.getTime()<maxDate.getTime()){
+this._intervalMarkerLayout.createIntervalMarker(
+minDate,labeller,this._unit,this._markerLayer,this._lineLayer);
+
+incrementDate(minDate);
+}
+this._markerLayer.style.display="block";
+this._lineLayer.style.display="block";
+};
+
+Timeline.GregorianEtherPainter.prototype.softPaint=function(){
+};
+
+
+
+Timeline.HotZoneGregorianEtherPainter=function(params){
+this._params=params;
+this._theme=params.theme;
+
+this._zones=[{
+startTime:Number.NEGATIVE_INFINITY,
+endTime:Number.POSITIVE_INFINITY,
+unit:params.unit,
+multiple:1
+}];
+for(var i=0;i<params.zones.length;i++){
+var zone=params.zones[i];
+var zoneStart=SimileAjax.DateTime.parseGregorianDateTime(zone.start).getTime();
+var zoneEnd=SimileAjax.DateTime.parseGregorianDateTime(zone.end).getTime();
+
+for(var j=0;j<this._zones.length&&zoneEnd>zoneStart;j++){
+var zone2=this._zones[j];
+
+if(zoneStart<zone2.endTime){
+if(zoneStart>zone2.startTime){
+this._zones.splice(j,0,{
+startTime:zone2.startTime,
+endTime:zoneStart,
+unit:zone2.unit,
+multiple:zone2.multiple
+});
+j++;
+
+zone2.startTime=zoneStart;
+}
+
+if(zoneEnd<zone2.endTime){
+this._zones.splice(j,0,{
+startTime:zoneStart,
+endTime:zoneEnd,
+unit:zone.unit,
+multiple:(zone.multiple)?zone.multiple:1
+});
+j++;
+
+zone2.startTime=zoneEnd;
+zoneStart=zoneEnd;
+}else{
+zone2.multiple=zone.multiple;
+zone2.unit=zone.unit;
+zoneStart=zone2.endTime;
+}
+}
+}
+}
+};
+
+Timeline.HotZoneGregorianEtherPainter.prototype.initialize=function(band,timeline){
+this._band=band;
+this._timeline=timeline;
+
+this._backgroundLayer=band.createLayerDiv(0);
+this._backgroundLayer.setAttribute("name","ether-background");
+this._backgroundLayer.style.background=this._theme.ether.backgroundColors[band.getIndex()];
+
+this._markerLayer=null;
+this._lineLayer=null;
+
+var align=("align"in this._params&&this._params.align!=undefined)?this._params.align:
+this._theme.ether.interval.marker[timeline.isHorizontal()?"hAlign":"vAlign"];
+var showLine=("showLine"in this._params)?this._params.showLine:
+this._theme.ether.interval.line.show;
+
+this._intervalMarkerLayout=new Timeline.EtherIntervalMarkerLayout(
+this._timeline,this._band,this._theme,align,showLine);
+
+this._highlight=new Timeline.EtherHighlight(
+this._timeline,this._band,this._theme,this._backgroundLayer);
+}
+
+Timeline.HotZoneGregorianEtherPainter.prototype.setHighlight=function(startDate,endDate){
+this._highlight.position(startDate,endDate);
+}
+
+Timeline.HotZoneGregorianEtherPainter.prototype.paint=function(){
+if(this._markerLayer){
+this._band.removeLayerDiv(this._markerLayer);
+}
+this._markerLayer=this._band.createLayerDiv(100);
+this._markerLayer.setAttribute("name","ether-markers");
+this._markerLayer.style.display="none";
+
+if(this._lineLayer){
+this._band.removeLayerDiv(this._lineLayer);
+}
+this._lineLayer=this._band.createLayerDiv(1);
+this._lineLayer.setAttribute("name","ether-lines");
+this._lineLayer.style.display="none";
+
+var minDate=this._band.getMinDate();
+var maxDate=this._band.getMaxDate();
+
+var timeZone=this._band.getTimeZone();
+var labeller=this._band.getLabeller();
+
+var p=this;
+var incrementDate=function(date,zone){
+for(var i=0;i<zone.multiple;i++){
+SimileAjax.DateTime.incrementByInterval(date,zone.unit);
+}
+};
+
+var zStart=0;
+while(zStart<this._zones.length){
+if(minDate.getTime()<this._zones[zStart].endTime){
+break;
+}
+zStart++;
+}
+var zEnd=this._zones.length-1;
+while(zEnd>=0){
+if(maxDate.getTime()>this._zones[zEnd].startTime){
+break;
+}
+zEnd--;
+}
+
+for(var z=zStart;z<=zEnd;z++){
+var zone=this._zones[z];
+
+var minDate2=new Date(Math.max(minDate.getTime(),zone.startTime));
+var maxDate2=new Date(Math.min(maxDate.getTime(),zone.endTime));
+
+SimileAjax.DateTime.roundDownToInterval(minDate2,zone.unit,timeZone,zone.multiple,this._theme.firstDayOfWeek);
+SimileAjax.DateTime.roundUpToInterval(maxDate2,zone.unit,timeZone,zone.multiple,this._theme.firstDayOfWeek);
+
+while(minDate2.getTime()<maxDate2.getTime()){
+this._intervalMarkerLayout.createIntervalMarker(
+minDate2,labeller,zone.unit,this._markerLayer,this._lineLayer);
+
+incrementDate(minDate2,zone);
+}
+}
+this._markerLayer.style.display="block";
+this._lineLayer.style.display="block";
+};
+
+Timeline.HotZoneGregorianEtherPainter.prototype.softPaint=function(){
+};
+
+
+
+Timeline.YearCountEtherPainter=function(params){
+this._params=params;
+this._theme=params.theme;
+this._startDate=SimileAjax.DateTime.parseGregorianDateTime(params.startDate);
+this._multiple=("multiple"in params)?params.multiple:1;
+};
+
+Timeline.YearCountEtherPainter.prototype.initialize=function(band,timeline){
+this._band=band;
+this._timeline=timeline;
+
+this._backgroundLayer=band.createLayerDiv(0);
+this._backgroundLayer.setAttribute("name","ether-background");
+this._backgroundLayer.style.background=this._theme.ether.backgroundColors[band.getIndex()];
+
+this._markerLayer=null;
+this._lineLayer=null;
+
+var align=("align"in this._params)?this._params.align:
+this._theme.ether.interval.marker[timeline.isHorizontal()?"hAlign":"vAlign"];
+var showLine=("showLine"in this._params)?this._params.showLine:
+this._theme.ether.interval.line.show;
+
+this._intervalMarkerLayout=new Timeline.EtherIntervalMarkerLayout(
+this._timeline,this._band,this._theme,align,showLine);
+
+this._highlight=new Timeline.EtherHighlight(
+this._timeline,this._band,this._theme,this._backgroundLayer);
+};
+
+Timeline.YearCountEtherPainter.prototype.setHighlight=function(startDate,endDate){
+this._highlight.position(startDate,endDate);
+};
+
+Timeline.YearCountEtherPainter.prototype.paint=function(){
+if(this._markerLayer){
+this._band.removeLayerDiv(this._markerLayer);
+}
+this._markerLayer=this._band.createLayerDiv(100);
+this._markerLayer.setAttribute("name","ether-markers");
+this._markerLayer.style.display="none";
+
+if(this._lineLayer){
+this._band.removeLayerDiv(this._lineLayer);
+}
+this._lineLayer=this._band.createLayerDiv(1);
+this._lineLayer.setAttribute("name","ether-lines");
+this._lineLayer.style.display="none";
+
+var minDate=new Date(this._startDate.getTime());
+var maxDate=this._band.getMaxDate();
+var yearDiff=this._band.getMinDate().getUTCFullYear()-this._startDate.getUTCFullYear();
+minDate.setUTCFullYear(this._band.getMinDate().getUTCFullYear()-yearDiff%this._multiple);
+
+var p=this;
+var incrementDate=function(date){
+for(var i=0;i<p._multiple;i++){
+SimileAjax.DateTime.incrementByInterval(date,SimileAjax.DateTime.YEAR);
+}
+};
+var labeller={
+labelInterval:function(date,intervalUnit){
+var diff=date.getUTCFullYear()-p._startDate.getUTCFullYear();
+return{
+text:diff,
+emphasized:diff==0
+};
+}
+};
+
+while(minDate.getTime()<maxDate.getTime()){
+this._intervalMarkerLayout.createIntervalMarker(
+minDate,labeller,SimileAjax.DateTime.YEAR,this._markerLayer,this._lineLayer);
+
+incrementDate(minDate);
+}
+this._markerLayer.style.display="block";
+this._lineLayer.style.display="block";
+};
+
+Timeline.YearCountEtherPainter.prototype.softPaint=function(){
+};
+
+
+
+Timeline.QuarterlyEtherPainter=function(params){
+this._params=params;
+this._theme=params.theme;
+this._startDate=SimileAjax.DateTime.parseGregorianDateTime(params.startDate);
+};
+
+Timeline.QuarterlyEtherPainter.prototype.initialize=function(band,timeline){
+this._band=band;
+this._timeline=timeline;
+
+this._backgroundLayer=band.createLayerDiv(0);
+this._backgroundLayer.setAttribute("name","ether-background");
+this._backgroundLayer.style.background=this._theme.ether.backgroundColors[band.getIndex()];
+
+this._markerLayer=null;
+this._lineLayer=null;
+
+var align=("align"in this._params)?this._params.align:
+this._theme.ether.interval.marker[timeline.isHorizontal()?"hAlign":"vAlign"];
+var showLine=("showLine"in this._params)?this._params.showLine:
+this._theme.ether.interval.line.show;
+
+this._intervalMarkerLayout=new Timeline.EtherIntervalMarkerLayout(
+this._timeline,this._band,this._theme,align,showLine);
+
+this._highlight=new Timeline.EtherHighlight(
+this._timeline,this._band,this._theme,this._backgroundLayer);
+};
+
+Timeline.QuarterlyEtherPainter.prototype.setHighlight=function(startDate,endDate){
+this._highlight.position(startDate,endDate);
+};
+
+Timeline.QuarterlyEtherPainter.prototype.paint=function(){
+if(this._markerLayer){
+this._band.removeLayerDiv(this._markerLayer);
+}
+this._markerLayer=this._band.createLayerDiv(100);
+this._markerLayer.setAttribute("name","ether-markers");
+this._markerLayer.style.display="none";
+
+if(this._lineLayer){
+this._band.removeLayerDiv(this._lineLayer);
+}
+this._lineLayer=this._band.createLayerDiv(1);
+this._lineLayer.setAttribute("name","ether-lines");
+this._lineLayer.style.display="none";
+
+var minDate=new Date(0);
+var maxDate=this._band.getMaxDate();
+
+minDate.setUTCFullYear(Math.max(this._startDate.getUTCFullYear(),this._band.getMinDate().getUTCFullYear()));
+minDate.setUTCMonth(this._startDate.getUTCMonth());
+
+var p=this;
+var incrementDate=function(date){
+date.setUTCMonth(date.getUTCMonth()+3);
+};
+var labeller={
+labelInterval:function(date,intervalUnit){
+var quarters=(4+(date.getUTCMonth()-p._startDate.getUTCMonth())/3)%4;
+if(quarters!=0){
+return{text:"Q"+(quarters+1),emphasized:false};
+}else{
+return{text:"Y"+(date.getUTCFullYear()-p._startDate.getUTCFullYear()+1),emphasized:true};
+}
+}
+};
+
+while(minDate.getTime()<maxDate.getTime()){
+this._intervalMarkerLayout.createIntervalMarker(
+minDate,labeller,SimileAjax.DateTime.YEAR,this._markerLayer,this._lineLayer);
+
+incrementDate(minDate);
+}
+this._markerLayer.style.display="block";
+this._lineLayer.style.display="block";
+};
+
+Timeline.QuarterlyEtherPainter.prototype.softPaint=function(){
+};
+
+
+
+Timeline.EtherIntervalMarkerLayout=function(timeline,band,theme,align,showLine){
+var horizontal=timeline.isHorizontal();
+if(horizontal){
+if(align=="Top"){
+this.positionDiv=function(div,offset){
+div.style.left=offset+"px";
+div.style.top="0px";
+};
+}else{
+this.positionDiv=function(div,offset){
+div.style.left=offset+"px";
+div.style.bottom="0px";
+};
+}
+}else{
+if(align=="Left"){
+this.positionDiv=function(div,offset){
+div.style.top=offset+"px";
+div.style.left="0px";
+};
+}else{
+this.positionDiv=function(div,offset){
+div.style.top=offset+"px";
+div.style.right="0px";
+};
+}
+}
+
+var markerTheme=theme.ether.interval.marker;
+var lineTheme=theme.ether.interval.line;
+var weekendTheme=theme.ether.interval.weekend;
+
+var stylePrefix=(horizontal?"h":"v")+align;
+var labelStyler=markerTheme[stylePrefix+"Styler"];
+var emphasizedLabelStyler=markerTheme[stylePrefix+"EmphasizedStyler"];
+var day=SimileAjax.DateTime.gregorianUnitLengths[SimileAjax.DateTime.DAY];
+
+this.createIntervalMarker=function(date,labeller,unit,markerDiv,lineDiv){
+var offset=Math.round(band.dateToPixelOffset(date));
+
+if(showLine&&unit!=SimileAjax.DateTime.WEEK){
+var divLine=timeline.getDocument().createElement("div");
+divLine.style.position="absolute";
+
+if(lineTheme.opacity<100){
+SimileAjax.Graphics.setOpacity(divLine,lineTheme.opacity);
+}
+
+if(horizontal){
+divLine.style.borderLeft="1px solid "+lineTheme.color;
+divLine.style.left=offset+"px";
+divLine.style.width="1px";
+divLine.style.top="0px";
+divLine.style.height="100%";
+}else{
+divLine.style.borderTop="1px solid "+lineTheme.color;
+divLine.style.top=offset+"px";
+divLine.style.height="1px";
+divLine.style.left="0px";
+divLine.style.width="100%";
+}
+lineDiv.appendChild(divLine);
+}
+if(unit==SimileAjax.DateTime.WEEK){
+var firstDayOfWeek=theme.firstDayOfWeek;
+
+var saturday=new Date(date.getTime()+(6-firstDayOfWeek-7)*day);
+var monday=new Date(saturday.getTime()+2*day);
+
+var saturdayPixel=Math.round(band.dateToPixelOffset(saturday));
+var mondayPixel=Math.round(band.dateToPixelOffset(monday));
+var length=Math.max(1,mondayPixel-saturdayPixel);
+
+var divWeekend=timeline.getDocument().createElement("div");
+divWeekend.style.position="absolute";
+
+divWeekend.style.background=weekendTheme.color;
+if(weekendTheme.opacity<100){
+SimileAjax.Graphics.setOpacity(divWeekend,weekendTheme.opacity);
+}
+
+if(horizontal){
+divWeekend.style.left=saturdayPixel+"px";
+divWeekend.style.width=length+"px";
+divWeekend.style.top="0px";
+divWeekend.style.height="100%";
+}else{
+divWeekend.style.top=saturdayPixel+"px";
+divWeekend.style.height=length+"px";
+divWeekend.style.left="0px";
+divWeekend.style.width="100%";
+}
+lineDiv.appendChild(divWeekend);
+}
+
+var label=labeller.labelInterval(date,unit);
+
+var div=timeline.getDocument().createElement("div");
+div.innerHTML=label.text;
+div.style.position="absolute";
+(label.emphasized?emphasizedLabelStyler:labelStyler)(div);
+
+this.positionDiv(div,offset);
+markerDiv.appendChild(div);
+
+return div;
+};
+};
+
+
+
+Timeline.EtherHighlight=function(timeline,band,theme,backgroundLayer){
+var horizontal=timeline.isHorizontal();
+
+this._highlightDiv=null;
+this._createHighlightDiv=function(){
+if(this._highlightDiv==null){
+this._highlightDiv=timeline.getDocument().createElement("div");
+this._highlightDiv.setAttribute("name","ether-highlight");
+this._highlightDiv.style.position="absolute";
+this._highlightDiv.style.background=theme.ether.highlightColor;
+
+var opacity=theme.ether.highlightOpacity;
+if(opacity<100){
+SimileAjax.Graphics.setOpacity(this._highlightDiv,opacity);
+}
+
+backgroundLayer.appendChild(this._highlightDiv);
+}
+}
+
+this.position=function(startDate,endDate){
+this._createHighlightDiv();
+
+var startPixel=Math.round(band.dateToPixelOffset(startDate));
+var endPixel=Math.round(band.dateToPixelOffset(endDate));
+var length=Math.max(endPixel-startPixel,3);
+if(horizontal){
+this._highlightDiv.style.left=startPixel+"px";
+this._highlightDiv.style.width=length+"px";
+this._highlightDiv.style.top="2px";
+this._highlightDiv.style.height=(band.getViewWidth()-4)+"px";
+}else{
+this._highlightDiv.style.top=startPixel+"px";
+this._highlightDiv.style.height=length+"px";
+this._highlightDiv.style.left="2px";
+this._highlightDiv.style.width=(band.getViewWidth()-4)+"px";
+}
+}
+};
+
+
+
+/* ethers.js */
+
+
+
+Timeline.LinearEther=function(params){
+this._params=params;
+this._interval=params.interval;
+this._pixelsPerInterval=params.pixelsPerInterval;
+};
+
+Timeline.LinearEther.prototype.initialize=function(timeline){
+this._timeline=timeline;
+this._unit=timeline.getUnit();
+
+if("startsOn"in this._params){
+this._start=this._unit.parseFromObject(this._params.startsOn);
+}else if("endsOn"in this._params){
+this._start=this._unit.parseFromObject(this._params.endsOn);
+this.shiftPixels(-this._timeline.getPixelLength());
+}else if("centersOn"in this._params){
+this._start=this._unit.parseFromObject(this._params.centersOn);
+this.shiftPixels(-this._timeline.getPixelLength()/2);
+}else{
+this._start=this._unit.makeDefaultValue();
+this.shiftPixels(-this._timeline.getPixelLength()/2);
+}
+};
+
+Timeline.LinearEther.prototype.setDate=function(date){
+this._start=this._unit.cloneValue(date);
+};
+
+Timeline.LinearEther.prototype.shiftPixels=function(pixels){
+var numeric=this._interval*pixels/this._pixelsPerInterval;
+this._start=this._unit.change(this._start,numeric);
+};
+
+Timeline.LinearEther.prototype.dateToPixelOffset=function(date){
+var numeric=this._unit.compare(date,this._start);
+return this._pixelsPerInterval*numeric/this._interval;
+};
+
+Timeline.LinearEther.prototype.pixelOffsetToDate=function(pixels){
+var numeric=pixels*this._interval/this._pixelsPerInterval;
+return this._unit.change(this._start,numeric);
+};
+
+
+
+Timeline.HotZoneEther=function(params){
+this._params=params;
+this._interval=params.interval;
+this._pixelsPerInterval=params.pixelsPerInterval;
+};
+
+Timeline.HotZoneEther.prototype.initialize=function(timeline){
+this._timeline=timeline;
+this._unit=timeline.getUnit();
+
+this._zones=[{
+startTime:Number.NEGATIVE_INFINITY,
+endTime:Number.POSITIVE_INFINITY,
+magnify:1
+}];
+var params=this._params;
+for(var i=0;i<params.zones.length;i++){
+var zone=params.zones[i];
+var zoneStart=this._unit.parseFromObject(zone.start);
+var zoneEnd=this._unit.parseFromObject(zone.end);
+
+for(var j=0;j<this._zones.length&&this._unit.compare(zoneEnd,zoneStart)>0;j++){
+var zone2=this._zones[j];
+
+if(this._unit.compare(zoneStart,zone2.endTime)<0){
+if(this._unit.compare(zoneStart,zone2.startTime)>0){
+this._zones.splice(j,0,{
+startTime:zone2.startTime,
+endTime:zoneStart,
+magnify:zone2.magnify
+});
+j++;
+
+zone2.startTime=zoneStart;
+}
+
+if(this._unit.compare(zoneEnd,zone2.endTime)<0){
+this._zones.splice(j,0,{
+startTime:zoneStart,
+endTime:zoneEnd,
+magnify:zone.magnify*zone2.magnify
+});
+j++;
+
+zone2.startTime=zoneEnd;
+zoneStart=zoneEnd;
+}else{
+zone2.magnify*=zone.magnify;
+zoneStart=zone2.endTime;
+}
+}
+}
+}
+
+if("startsOn"in this._params){
+this._start=this._unit.parseFromObject(this._params.startsOn);
+}else if("endsOn"in this._params){
+this._start=this._unit.parseFromObject(this._params.endsOn);
+this.shiftPixels(-this._timeline.getPixelLength());
+}else if("centersOn"in this._params){
+this._start=this._unit.parseFromObject(this._params.centersOn);
+this.shiftPixels(-this._timeline.getPixelLength()/2);
+}else{
+this._start=this._unit.makeDefaultValue();
+this.shiftPixels(-this._timeline.getPixelLength()/2);
+}
+};
+
+Timeline.HotZoneEther.prototype.setDate=function(date){
+this._start=this._unit.cloneValue(date);
+};
+
+Timeline.HotZoneEther.prototype.shiftPixels=function(pixels){
+this._start=this.pixelOffsetToDate(pixels);
+};
+
+Timeline.HotZoneEther.prototype.dateToPixelOffset=function(date){
+return this._dateDiffToPixelOffset(this._start,date);
+};
+
+Timeline.HotZoneEther.prototype.pixelOffsetToDate=function(pixels){
+return this._pixelOffsetToDate(pixels,this._start);
+};
+
+Timeline.HotZoneEther.prototype._dateDiffToPixelOffset=function(fromDate,toDate){
+var scale=this._getScale();
+var fromTime=fromDate;
+var toTime=toDate;
+
+var pixels=0;
+if(this._unit.compare(fromTime,toTime)<0){
+var z=0;
+while(z<this._zones.length){
+if(this._unit.compare(fromTime,this._zones[z].endTime)<0){
+break;
+}
+z++;
+}
+
+while(this._unit.compare(fromTime,toTime)<0){
+var zone=this._zones[z];
+var toTime2=this._unit.earlier(toTime,zone.endTime);
+
+pixels+=(this._unit.compare(toTime2,fromTime)/(scale/zone.magnify));
+
+fromTime=toTime2;
+z++;
+}
+}else{
+var z=this._zones.length-1;
+while(z>=0){
+if(this._unit.compare(fromTime,this._zones[z].startTime)>0){
+break;
+}
+z--;
+}
+
+while(this._unit.compare(fromTime,toTime)>0){
+var zone=this._zones[z];
+var toTime2=this._unit.later(toTime,zone.startTime);
+
+pixels+=(this._unit.compare(toTime2,fromTime)/(scale/zone.magnify));
+
+fromTime=toTime2;
+z--;
+}
+}
+return pixels;
+};
+
+Timeline.HotZoneEther.prototype._pixelOffsetToDate=function(pixels,fromDate){
+var scale=this._getScale();
+var time=fromDate;
+if(pixels>0){
+var z=0;
+while(z<this._zones.length){
+if(this._unit.compare(time,this._zones[z].endTime)<0){
+break;
+}
+z++;
+}
+
+while(pixels>0){
+var zone=this._zones[z];
+var scale2=scale/zone.magnify;
+
+if(zone.endTime==Number.POSITIVE_INFINITY){
+time=this._unit.change(time,pixels*scale2);
+pixels=0;
+}else{
+var pixels2=this._unit.compare(zone.endTime,time)/scale2;
+if(pixels2>pixels){
+time=this._unit.change(time,pixels*scale2);
+pixels=0;
+}else{
+time=zone.endTime;
+pixels-=pixels2;
+}
+}
+z++;
+}
+}else{
+var z=this._zones.length-1;
+while(z>=0){
+if(this._unit.compare(time,this._zones[z].startTime)>0){
+break;
+}
+z--;
+}
+
+pixels=-pixels;
+while(pixels>0){
+var zone=this._zones[z];
+var scale2=scale/zone.magnify;
+
+if(zone.startTime==Number.NEGATIVE_INFINITY){
+time=this._unit.change(time,-pixels*scale2);
+pixels=0;
+}else{
+var pixels2=this._unit.compare(time,zone.startTime)/scale2;
+if(pixels2>pixels){
+time=this._unit.change(time,-pixels*scale2);
+pixels=0;
+}else{
+time=zone.startTime;
+pixels-=pixels2;
+}
+}
+z--;
+}
+}
+return time;
+};
+
+Timeline.HotZoneEther.prototype._getScale=function(){
+return this._interval/this._pixelsPerInterval;
+};
+
+
+/* labellers.js */
+
+
+
+Timeline.GregorianDateLabeller=function(locale,timeZone){
+this._locale=locale;
+this._timeZone=timeZone;
+};
+
+Timeline.GregorianDateLabeller.monthNames=[];
+Timeline.GregorianDateLabeller.dayNames=[];
+Timeline.GregorianDateLabeller.labelIntervalFunctions=[];
+
+Timeline.GregorianDateLabeller.getMonthName=function(month,locale){
+return Timeline.GregorianDateLabeller.monthNames[locale][month];
+};
+
+Timeline.GregorianDateLabeller.prototype.labelInterval=function(date,intervalUnit){
+var f=Timeline.GregorianDateLabeller.labelIntervalFunctions[this._locale];
+if(f==null){
+f=Timeline.GregorianDateLabeller.prototype.defaultLabelInterval;
+}
+return f.call(this,date,intervalUnit);
+};
+
+Timeline.GregorianDateLabeller.prototype.labelPrecise=function(date){
+return SimileAjax.DateTime.removeTimeZoneOffset(
+date,
+this._timeZone
+).toUTCString();
+};
+
+Timeline.GregorianDateLabeller.prototype.defaultLabelInterval=function(date,intervalUnit){
+var text;
+var emphasized=false;
+
+date=SimileAjax.DateTime.removeTimeZoneOffset(date,this._timeZone);
+
+switch(intervalUnit){
+case SimileAjax.DateTime.MILLISECOND:
+text=date.getUTCMilliseconds();
+break;
+case SimileAjax.DateTime.SECOND:
+text=date.getUTCSeconds();
+break;
+case SimileAjax.DateTime.MINUTE:
+var m=date.getUTCMinutes();
+if(m==0){
+text=date.getUTCHours()+":00";
+emphasized=true;
+}else{
+text=m;
+}
+break;
+case SimileAjax.DateTime.HOUR:
+text=date.getUTCHours()+"hr";
+break;
+case SimileAjax.DateTime.DAY:
+text=Timeline.GregorianDateLabeller.getMonthName(date.getUTCMonth(),this._locale)+" "+date.getUTCDate();
+break;
+case SimileAjax.DateTime.WEEK:
+text=Timeline.GregorianDateLabeller.getMonthName(date.getUTCMonth(),this._locale)+" "+date.getUTCDate();
+break;
+case SimileAjax.DateTime.MONTH:
+var m=date.getUTCMonth();
+if(m!=0){
+text=Timeline.GregorianDateLabeller.getMonthName(m,this._locale);
+break;
+}
+case SimileAjax.DateTime.YEAR:
+case SimileAjax.DateTime.DECADE:
+case SimileAjax.DateTime.CENTURY:
+case SimileAjax.DateTime.MILLENNIUM:
+var y=date.getUTCFullYear();
+if(y>0){
+text=date.getUTCFullYear();
+}else{
+text=(1-y)+"BC";
+}
+emphasized=
+(intervalUnit==SimileAjax.DateTime.MONTH)||
+(intervalUnit==SimileAjax.DateTime.DECADE&&y%100==0)||
+(intervalUnit==SimileAjax.DateTime.CENTURY&&y%1000==0);
+break;
+default:
+text=date.toUTCString();
+}
+return{text:text,emphasized:emphasized};
+}
+
+
+
+/* original-painter.js */
+
+
+
+Timeline.OriginalEventPainter=function(params){
+this._params=params;
+this._onSelectListeners=[];
+
+this._filterMatcher=null;
+this._highlightMatcher=null;
+this._frc=null;
+
+this._eventIdToElmt={};
+};
+
+Timeline.OriginalEventPainter.prototype.initialize=function(band,timeline){
+this._band=band;
+this._timeline=timeline;
+
+this._backLayer=null;
+this._eventLayer=null;
+this._lineLayer=null;
+this._highlightLayer=null;
+
+this._eventIdToElmt=null;
+};
+
+Timeline.OriginalEventPainter.prototype.addOnSelectListener=function(listener){
+this._onSelectListeners.push(listener);
+};
+
+Timeline.OriginalEventPainter.prototype.removeOnSelectListener=function(listener){
+for(var i=0;i<this._onSelectListeners.length;i++){
+if(this._onSelectListeners[i]==listener){
+this._onSelectListeners.splice(i,1);
+break;
+}
+}
+};
+
+Timeline.OriginalEventPainter.prototype.getFilterMatcher=function(){
+return this._filterMatcher;
+};
+
+Timeline.OriginalEventPainter.prototype.setFilterMatcher=function(filterMatcher){
+this._filterMatcher=filterMatcher;
+};
+
+Timeline.OriginalEventPainter.prototype.getHighlightMatcher=function(){
+return this._highlightMatcher;
+};
+
+Timeline.OriginalEventPainter.prototype.setHighlightMatcher=function(highlightMatcher){
+this._highlightMatcher=highlightMatcher;
+};
+
+Timeline.OriginalEventPainter.prototype.paint=function(){
+var eventSource=this._band.getEventSource();
+if(eventSource==null){
+return;
+}
+
+this._eventIdToElmt={};
+this._prepareForPainting();
+
+var eventTheme=this._params.theme.event;
+var trackHeight=Math.max(eventTheme.track.height,eventTheme.tape.height+this._frc.getLineHeight());
+var metrics={
+trackOffset:eventTheme.track.gap,
+trackHeight:trackHeight,
+trackGap:eventTheme.track.gap,
+trackIncrement:trackHeight+eventTheme.track.gap,
+icon:eventTheme.instant.icon,
+iconWidth:eventTheme.instant.iconWidth,
+iconHeight:eventTheme.instant.iconHeight,
+labelWidth:eventTheme.label.width
+}
+
+var minDate=this._band.getMinDate();
+var maxDate=this._band.getMaxDate();
+
+var filterMatcher=(this._filterMatcher!=null)?
+this._filterMatcher:
+function(evt){return true;};
+var highlightMatcher=(this._highlightMatcher!=null)?
+this._highlightMatcher:
+function(evt){return-1;};
+
+var iterator=eventSource.getEventReverseIterator(minDate,maxDate);
+while(iterator.hasNext()){
+var evt=iterator.next();
+if(filterMatcher(evt)){
+this.paintEvent(evt,metrics,this._params.theme,highlightMatcher(evt));
+}
+}
+
+this._highlightLayer.style.display="block";
+this._lineLayer.style.display="block";
+this._eventLayer.style.display="block";
+};
+
+Timeline.OriginalEventPainter.prototype.softPaint=function(){
+};
+
+Timeline.OriginalEventPainter.prototype._prepareForPainting=function(){
+var band=this._band;
+
+if(this._backLayer==null){
+this._backLayer=this._band.createLayerDiv(0,"timeline-band-events");
+this._backLayer.style.visibility="hidden";
+
+var eventLabelPrototype=document.createElement("span");
+eventLabelPrototype.className="timeline-event-label";
+this._backLayer.appendChild(eventLabelPrototype);
+this._frc=SimileAjax.Graphics.getFontRenderingContext(eventLabelPrototype);
+}
+this._frc.update();
+this._tracks=[];
+
+if(this._highlightLayer!=null){
+band.removeLayerDiv(this._highlightLayer);
+}
+this._highlightLayer=band.createLayerDiv(105,"timeline-band-highlights");
+this._highlightLayer.style.display="none";
+
+if(this._lineLayer!=null){
+band.removeLayerDiv(this._lineLayer);
+}
+this._lineLayer=band.createLayerDiv(110,"timeline-band-lines");
+this._lineLayer.style.display="none";
+
+if(this._eventLayer!=null){
+band.removeLayerDiv(this._eventLayer);
+}
+this._eventLayer=band.createLayerDiv(115,"timeline-band-events");
+this._eventLayer.style.display="none";
+};
+
+Timeline.OriginalEventPainter.prototype.paintEvent=function(evt,metrics,theme,highlightIndex){
+if(evt.isInstant()){
+this.paintInstantEvent(evt,metrics,theme,highlightIndex);
+}else{
+this.paintDurationEvent(evt,metrics,theme,highlightIndex);
+}
+};
+
+Timeline.OriginalEventPainter.prototype.paintInstantEvent=function(evt,metrics,theme,highlightIndex){
+if(evt.isImprecise()){
+this.paintImpreciseInstantEvent(evt,metrics,theme,highlightIndex);
+}else{
+this.paintPreciseInstantEvent(evt,metrics,theme,highlightIndex);
+}
+}
+
+Timeline.OriginalEventPainter.prototype.paintDurationEvent=function(evt,metrics,theme,highlightIndex){
+if(evt.isImprecise()){
+this.paintImpreciseDurationEvent(evt,metrics,theme,highlightIndex);
+}else{
+this.paintPreciseDurationEvent(evt,metrics,theme,highlightIndex);
+}
+}
+
+Timeline.OriginalEventPainter.prototype.paintPreciseInstantEvent=function(evt,metrics,theme,highlightIndex){
+var doc=this._timeline.getDocument();
+var text=evt.getText();
+
+var startDate=evt.getStart();
+var startPixel=Math.round(this._band.dateToPixelOffset(startDate));
+var iconRightEdge=Math.round(startPixel+metrics.iconWidth/2);
+var iconLeftEdge=Math.round(startPixel-metrics.iconWidth/2);
+
+var labelSize=this._frc.computeSize(text);
+var labelLeft=iconRightEdge+theme.event.label.offsetFromLine;
+var labelRight=labelLeft+labelSize.width;
+
+var rightEdge=labelRight;
+var track=this._findFreeTrack(rightEdge);
+
+var labelTop=Math.round(
+metrics.trackOffset+track*metrics.trackIncrement+
+metrics.trackHeight/2-labelSize.height/2);
+
+var iconElmtData=this._paintEventIcon(evt,track,iconLeftEdge,metrics,theme);
+var labelElmtData=this._paintEventLabel(evt,text,labelLeft,labelTop,labelSize.width,labelSize.height,theme);
+
+var self=this;
+var clickHandler=function(elmt,domEvt,target){
+return self._onClickInstantEvent(iconElmtData.elmt,domEvt,evt);
+};
+SimileAjax.DOM.registerEvent(iconElmtData.elmt,"mousedown",clickHandler);
+SimileAjax.DOM.registerEvent(labelElmtData.elmt,"mousedown",clickHandler);
+
+this._createHighlightDiv(highlightIndex,iconElmtData,theme);
+
+this._eventIdToElmt[evt.getID()]=iconElmtData.elmt;
+this._tracks[track]=iconLeftEdge;
+};
+
+Timeline.OriginalEventPainter.prototype.paintImpreciseInstantEvent=function(evt,metrics,theme,highlightIndex){
+var doc=this._timeline.getDocument();
+var text=evt.getText();
+
+var startDate=evt.getStart();
+var endDate=evt.getEnd();
+var startPixel=Math.round(this._band.dateToPixelOffset(startDate));
+var endPixel=Math.round(this._band.dateToPixelOffset(endDate));
+
+var iconRightEdge=Math.round(startPixel+metrics.iconWidth/2);
+var iconLeftEdge=Math.round(startPixel-metrics.iconWidth/2);
+
+var labelSize=this._frc.computeSize(text);
+var labelLeft=iconRightEdge+theme.event.label.offsetFromLine;
+var labelRight=labelLeft+labelSize.width;
+
+var rightEdge=Math.max(labelRight,endPixel);
+var track=this._findFreeTrack(rightEdge);
+var labelTop=Math.round(
+metrics.trackOffset+track*metrics.trackIncrement+
+metrics.trackHeight/2-labelSize.height/2);
+
+var iconElmtData=this._paintEventIcon(evt,track,iconLeftEdge,metrics,theme);
+var labelElmtData=this._paintEventLabel(evt,text,labelLeft,labelTop,labelSize.width,labelSize.height,theme);
+var tapeElmtData=this._paintEventTape(evt,track,startPixel,endPixel,
+theme.event.instant.impreciseColor,theme.event.instant.impreciseOpacity,metrics,theme);
+
+var self=this;
+var clickHandler=function(elmt,domEvt,target){
+return self._onClickInstantEvent(iconElmtData.elmt,domEvt,evt);
+};
+SimileAjax.DOM.registerEvent(iconElmtData.elmt,"mousedown",clickHandler);
+SimileAjax.DOM.registerEvent(tapeElmtData.elmt,"mousedown",clickHandler);
+SimileAjax.DOM.registerEvent(labelElmtData.elmt,"mousedown",clickHandler);
+
+this._createHighlightDiv(highlightIndex,iconElmtData,theme);
+
+this._eventIdToElmt[evt.getID()]=iconElmtData.elmt;
+this._tracks[track]=iconLeftEdge;
+};
+
+Timeline.OriginalEventPainter.prototype.paintPreciseDurationEvent=function(evt,metrics,theme,highlightIndex){
+var doc=this._timeline.getDocument();
+var text=evt.getText();
+
+var startDate=evt.getStart();
+var endDate=evt.getEnd();
+var startPixel=Math.round(this._band.dateToPixelOffset(startDate));
+var endPixel=Math.round(this._band.dateToPixelOffset(endDate));
+
+var labelSize=this._frc.computeSize(text);
+var labelLeft=startPixel;
+var labelRight=labelLeft+labelSize.width;
+
+var rightEdge=Math.max(labelRight,endPixel);
+var track=this._findFreeTrack(rightEdge);
+var labelTop=Math.round(
+metrics.trackOffset+track*metrics.trackIncrement+theme.event.tape.height);
+
+var color=evt.getColor();
+color=color!=null?color:theme.event.duration.color;
+
+var tapeElmtData=this._paintEventTape(evt,track,startPixel,endPixel,color,100,metrics,theme);
+var labelElmtData=this._paintEventLabel(evt,text,labelLeft,labelTop,labelSize.width,labelSize.height,theme);
+
+var self=this;
+var clickHandler=function(elmt,domEvt,target){
+return self._onClickInstantEvent(tapeElmtData.elmt,domEvt,evt);
+};
+SimileAjax.DOM.registerEvent(tapeElmtData.elmt,"mousedown",clickHandler);
+SimileAjax.DOM.registerEvent(labelElmtData.elmt,"mousedown",clickHandler);
+
+this._createHighlightDiv(highlightIndex,tapeElmtData,theme);
+
+this._eventIdToElmt[evt.getID()]=tapeElmtData.elmt;
+this._tracks[track]=startPixel;
+};
+
+Timeline.OriginalEventPainter.prototype.paintImpreciseDurationEvent=function(evt,metrics,theme,highlightIndex){
+var doc=this._timeline.getDocument();
+var text=evt.getText();
+
+var startDate=evt.getStart();
+var latestStartDate=evt.getLatestStart();
+var endDate=evt.getEnd();
+var earliestEndDate=evt.getEarliestEnd();
+
+var startPixel=Math.round(this._band.dateToPixelOffset(startDate));
+var latestStartPixel=Math.round(this._band.dateToPixelOffset(latestStartDate));
+var endPixel=Math.round(this._band.dateToPixelOffset(endDate));
+var earliestEndPixel=Math.round(this._band.dateToPixelOffset(earliestEndDate));
+
+var labelSize=this._frc.computeSize(text);
+var labelLeft=latestStartPixel;
+var labelRight=labelLeft+labelSize.width;
+
+var rightEdge=Math.max(labelRight,endPixel);
+var track=this._findFreeTrack(rightEdge);
+var labelTop=Math.round(
+metrics.trackOffset+track*metrics.trackIncrement+theme.event.tape.height);
+
+var color=evt.getColor();
+color=color!=null?color:theme.event.duration.color;
+
+var impreciseTapeElmtData=this._paintEventTape(evt,track,startPixel,endPixel,
+theme.event.duration.impreciseColor,theme.event.duration.impreciseOpacity,metrics,theme);
+var tapeElmtData=this._paintEventTape(evt,track,latestStartPixel,earliestEndPixel,color,100,metrics,theme);
+
+var labelElmtData=this._paintEventLabel(evt,text,labelLeft,labelTop,labelSize.width,labelSize.height,theme);
+
+var self=this;
+var clickHandler=function(elmt,domEvt,target){
+return self._onClickInstantEvent(tapeElmtData.elmt,domEvt,evt);
+};
+SimileAjax.DOM.registerEvent(tapeElmtData.elmt,"mousedown",clickHandler);
+SimileAjax.DOM.registerEvent(labelElmtData.elmt,"mousedown",clickHandler);
+
+this._createHighlightDiv(highlightIndex,tapeElmtData,theme);
+
+this._eventIdToElmt[evt.getID()]=tapeElmtData.elmt;
+this._tracks[track]=startPixel;
+};
+
+Timeline.OriginalEventPainter.prototype._findFreeTrack=function(rightEdge){
+for(var i=0;i<this._tracks.length;i++){
+var t=this._tracks[i];
+if(t>rightEdge){
+break;
+}
+}
+return i;
+};
+
+Timeline.OriginalEventPainter.prototype._paintEventIcon=function(evt,iconTrack,left,metrics,theme){
+var icon=evt.getIcon();
+icon=icon!=null?icon:metrics.icon;
+
+var middle=metrics.trackOffset+iconTrack*metrics.trackIncrement+metrics.trackHeight/2;
+var top=Math.round(middle-metrics.iconHeight/2);
+
+var img=SimileAjax.Graphics.createTranslucentImage(icon);
+var iconDiv=this._timeline.getDocument().createElement("div");
+iconDiv.style.position="absolute";
+iconDiv.style.left=left+"px";
+iconDiv.style.top=top+"px";
+iconDiv.appendChild(img);
+iconDiv.style.cursor="pointer";
+this._eventLayer.appendChild(iconDiv);
+
+return{
+left:left,
+top:top,
+width:metrics.iconWidth,
+height:metrics.iconHeight,
+elmt:iconDiv
+};
+};
+
+Timeline.OriginalEventPainter.prototype._paintEventLabel=function(evt,text,left,top,width,height,theme){
+var doc=this._timeline.getDocument();
+
+var labelDiv=doc.createElement("div");
+labelDiv.style.position="absolute";
+labelDiv.style.left=left+"px";
+labelDiv.style.width=width+"px";
+labelDiv.style.top=top+"px";
+labelDiv.innerHTML=text;
+labelDiv.style.cursor="pointer";
+
+var color=evt.getTextColor();
+if(color==null){
+color=evt.getColor();
+}
+if(color!=null){
+labelDiv.style.color=color;
+}
+
+this._eventLayer.appendChild(labelDiv);
+
+return{
+left:left,
+top:top,
+width:width,
+height:height,
+elmt:labelDiv
+};
+};
+
+Timeline.OriginalEventPainter.prototype._paintEventTape=function(
+evt,iconTrack,startPixel,endPixel,color,opacity,metrics,theme){
+
+var tapeWidth=endPixel-startPixel;
+var tapeHeight=theme.event.tape.height;
+var top=metrics.trackOffset+iconTrack*metrics.trackIncrement;
+
+var tapeDiv=this._timeline.getDocument().createElement("div");
+tapeDiv.style.position="absolute";
+tapeDiv.style.left=startPixel+"px";
+tapeDiv.style.width=tapeWidth+"px";
+tapeDiv.style.top=top+"px";
+tapeDiv.style.height=tapeHeight+"px";
+tapeDiv.style.backgroundColor=color;
+tapeDiv.style.overflow="hidden";
+tapeDiv.style.cursor="pointer";
+SimileAjax.Graphics.setOpacity(tapeDiv,opacity);
+
+this._eventLayer.appendChild(tapeDiv);
+
+return{
+left:startPixel,
+top:top,
+width:tapeWidth,
+height:tapeHeight,
+elmt:tapeDiv
+};
+}
+
+Timeline.OriginalEventPainter.prototype._createHighlightDiv=function(highlightIndex,dimensions,theme){
+if(highlightIndex>=0){
+var doc=this._timeline.getDocument();
+var eventTheme=theme.event;
+
+var color=eventTheme.highlightColors[Math.min(highlightIndex,eventTheme.highlightColors.length-1)];
+
+var div=doc.createElement("div");
+div.style.position="absolute";
+div.style.overflow="hidden";
+div.style.left=(dimensions.left-2)+"px";
+div.style.width=(dimensions.width+4)+"px";
+div.style.top=(dimensions.top-2)+"px";
+div.style.height=(dimensions.height+4)+"px";
+div.style.background=color;
+
+this._highlightLayer.appendChild(div);
+}
+};
+
+Timeline.OriginalEventPainter.prototype._onClickInstantEvent=function(icon,domEvt,evt){
+var c=SimileAjax.DOM.getPageCoordinates(icon);
+this._showBubble(
+c.left+Math.ceil(icon.offsetWidth/2),
+c.top+Math.ceil(icon.offsetHeight/2),
+evt
+);
+this._fireOnSelect(evt.getID());
+
+domEvt.cancelBubble=true;
+SimileAjax.DOM.cancelEvent(domEvt);
+return false;
+};
+
+Timeline.OriginalEventPainter.prototype._onClickDurationEvent=function(target,domEvt,evt){
+if("pageX"in domEvt){
+var x=domEvt.pageX;
+var y=domEvt.pageY;
+}else{
+var c=SimileAjax.DOM.getPageCoordinates(target);
+var x=domEvt.offsetX+c.left;
+var y=domEvt.offsetY+c.top;
+}
+this._showBubble(x,y,evt);
+this._fireOnSelect(evt.getID());
+
+domEvt.cancelBubble=true;
+SimileAjax.DOM.cancelEvent(domEvt);
+return false;
+};
+
+Timeline.OriginalEventPainter.prototype.showBubble=function(evt){
+var elmt=this._eventIdToElmt[evt.getID()];
+if(elmt){
+var c=SimileAjax.DOM.getPageCoordinates(elmt);
+this._showBubble(c.left+elmt.offsetWidth/2,c.top+elmt.offsetHeight/2,evt);
+}
+};
+
+Timeline.OriginalEventPainter.prototype._showBubble=function(x,y,evt){
+var div=document.createElement("div");
+evt.fillInfoBubble(div,this._params.theme,this._band.getLabeller());
+
+SimileAjax.WindowManager.cancelPopups();
+SimileAjax.Graphics.createBubbleForContentAndPoint(div,x,y,this._params.theme.event.bubble.width);
+};
+
+Timeline.OriginalEventPainter.prototype._fireOnSelect=function(eventID){
+for(var i=0;i<this._onSelectListeners.length;i++){
+this._onSelectListeners[i](eventID);
+}
+};
+
+
+/* overview-painter.js */
+
+
+
+Timeline.OverviewEventPainter=function(params){
+this._params=params;
+this._onSelectListeners=[];
+
+this._filterMatcher=null;
+this._highlightMatcher=null;
+};
+
+Timeline.OverviewEventPainter.prototype.initialize=function(band,timeline){
+this._band=band;
+this._timeline=timeline;
+
+this._eventLayer=null;
+this._highlightLayer=null;
+};
+
+Timeline.OverviewEventPainter.prototype.addOnSelectListener=function(listener){
+this._onSelectListeners.push(listener);
+};
+
+Timeline.OverviewEventPainter.prototype.removeOnSelectListener=function(listener){
+for(var i=0;i<this._onSelectListeners.length;i++){
+if(this._onSelectListeners[i]==listener){
+this._onSelectListeners.splice(i,1);
+break;
+}
+}
+};
+
+Timeline.OverviewEventPainter.prototype.getFilterMatcher=function(){
+return this._filterMatcher;
+};
+
+Timeline.OverviewEventPainter.prototype.setFilterMatcher=function(filterMatcher){
+this._filterMatcher=filterMatcher;
+};
+
+Timeline.OverviewEventPainter.prototype.getHighlightMatcher=function(){
+return this._highlightMatcher;
+};
+
+Timeline.OverviewEventPainter.prototype.setHighlightMatcher=function(highlightMatcher){
+this._highlightMatcher=highlightMatcher;
+};
+
+Timeline.OverviewEventPainter.prototype.paint=function(){
+var eventSource=this._band.getEventSource();
+if(eventSource==null){
+return;
+}
+
+this._prepareForPainting();
+
+var eventTheme=this._params.theme.event;
+var metrics={
+trackOffset:eventTheme.overviewTrack.offset,
+trackHeight:eventTheme.overviewTrack.height,
+trackGap:eventTheme.overviewTrack.gap,
+trackIncrement:eventTheme.overviewTrack.height+eventTheme.overviewTrack.gap
+}
+
+var minDate=this._band.getMinDate();
+var maxDate=this._band.getMaxDate();
+
+var filterMatcher=(this._filterMatcher!=null)?
+this._filterMatcher:
+function(evt){return true;};
+var highlightMatcher=(this._highlightMatcher!=null)?
+this._highlightMatcher:
+function(evt){return-1;};
+
+var iterator=eventSource.getEventReverseIterator(minDate,maxDate);
+while(iterator.hasNext()){
+var evt=iterator.next();
+if(filterMatcher(evt)){
+this.paintEvent(evt,metrics,this._params.theme,highlightMatcher(evt));
+}
+}
+
+this._highlightLayer.style.display="block";
+this._eventLayer.style.display="block";
+};
+
+Timeline.OverviewEventPainter.prototype.softPaint=function(){
+};
+
+Timeline.OverviewEventPainter.prototype._prepareForPainting=function(){
+var band=this._band;
+
+this._tracks=[];
+
+if(this._highlightLayer!=null){
+band.removeLayerDiv(this._highlightLayer);
+}
+this._highlightLayer=band.createLayerDiv(105,"timeline-band-highlights");
+this._highlightLayer.style.display="none";
+
+if(this._eventLayer!=null){
+band.removeLayerDiv(this._eventLayer);
+}
+this._eventLayer=band.createLayerDiv(110,"timeline-band-events");
+this._eventLayer.style.display="none";
+};
+
+Timeline.OverviewEventPainter.prototype.paintEvent=function(evt,metrics,theme,highlightIndex){
+if(evt.isInstant()){
+this.paintInstantEvent(evt,metrics,theme,highlightIndex);
+}else{
+this.paintDurationEvent(evt,metrics,theme,highlightIndex);
+}
+};
+
+Timeline.OverviewEventPainter.prototype.paintInstantEvent=function(evt,metrics,theme,highlightIndex){
+var startDate=evt.getStart();
+var startPixel=Math.round(this._band.dateToPixelOffset(startDate));
+
+var color=evt.getColor();
+color=color!=null?color:theme.event.duration.color;
+
+var tickElmtData=this._paintEventTick(evt,startPixel,color,100,metrics,theme);
+
+this._createHighlightDiv(highlightIndex,tickElmtData,theme);
+};
+
+Timeline.OverviewEventPainter.prototype.paintDurationEvent=function(evt,metrics,theme,highlightIndex){
+var latestStartDate=evt.getLatestStart();
+var earliestEndDate=evt.getEarliestEnd();
+
+var latestStartPixel=Math.round(this._band.dateToPixelOffset(latestStartDate));
+var earliestEndPixel=Math.round(this._band.dateToPixelOffset(earliestEndDate));
+
+var tapeTrack=0;
+for(;tapeTrack<this._tracks.length;tapeTrack++){
+if(earliestEndPixel<this._tracks[tapeTrack]){
+break;
+}
+}
+this._tracks[tapeTrack]=earliestEndPixel;
+
+var color=evt.getColor();
+color=color!=null?color:theme.event.duration.color;
+
+var tapeElmtData=this._paintEventTape(evt,tapeTrack,latestStartPixel,earliestEndPixel,color,100,metrics,theme);
+
+this._createHighlightDiv(highlightIndex,tapeElmtData,theme);
+};
+
+Timeline.OverviewEventPainter.prototype._paintEventTape=function(
+evt,track,left,right,color,opacity,metrics,theme){
+
+var top=metrics.trackOffset+track*metrics.trackIncrement;
+var width=right-left;
+var height=metrics.trackHeight;
+
+var tapeDiv=this._timeline.getDocument().createElement("div");
+tapeDiv.style.position="absolute";
+tapeDiv.style.left=left+"px";
+tapeDiv.style.width=width+"px";
+tapeDiv.style.top=top+"px";
+tapeDiv.style.height=height+"px";
+tapeDiv.style.backgroundColor=color;
+tapeDiv.style.overflow="hidden";
+SimileAjax.Graphics.setOpacity(tapeDiv,opacity);
+
+this._eventLayer.appendChild(tapeDiv);
+
+return{
+left:left,
+top:top,
+width:width,
+height:height,
+elmt:tapeDiv
+};
+}
+
+Timeline.OverviewEventPainter.prototype._paintEventTick=function(
+evt,left,color,opacity,metrics,theme){
+
+var height=theme.event.overviewTrack.tickHeight;
+var top=metrics.trackOffset-height;
+var width=1;
+
+var tickDiv=this._timeline.getDocument().createElement("div");
+tickDiv.style.position="absolute";
+tickDiv.style.left=left+"px";
+tickDiv.style.width=width+"px";
+tickDiv.style.top=top+"px";
+tickDiv.style.height=height+"px";
+tickDiv.style.backgroundColor=color;
+tickDiv.style.overflow="hidden";
+SimileAjax.Graphics.setOpacity(tickDiv,opacity);
+
+this._eventLayer.appendChild(tickDiv);
+
+return{
+left:left,
+top:top,
+width:width,
+height:height,
+elmt:tickDiv
+};
+}
+
+Timeline.OverviewEventPainter.prototype._createHighlightDiv=function(highlightIndex,dimensions,theme){
+if(highlightIndex>=0){
+var doc=this._timeline.getDocument();
+var eventTheme=theme.event;
+
+var color=eventTheme.highlightColors[Math.min(highlightIndex,eventTheme.highlightColors.length-1)];
+
+var div=doc.createElement("div");
+div.style.position="absolute";
+div.style.overflow="hidden";
+div.style.left=(dimensions.left-1)+"px";
+div.style.width=(dimensions.width+2)+"px";
+div.style.top=(dimensions.top-1)+"px";
+div.style.height=(dimensions.height+2)+"px";
+div.style.background=color;
+
+this._highlightLayer.appendChild(div);
+}
+};
+
+Timeline.OverviewEventPainter.prototype.showBubble=function(evt){
+
+};
+
+
+/* sources.js */
+
+
+
+
+Timeline.DefaultEventSource=function(eventIndex){
+this._events=(eventIndex instanceof Object)?eventIndex:new SimileAjax.EventIndex();
+this._listeners=[];
+};
+
+Timeline.DefaultEventSource.prototype.addListener=function(listener){
+this._listeners.push(listener);
+};
+
+Timeline.DefaultEventSource.prototype.removeListener=function(listener){
+for(var i=0;i<this._listeners.length;i++){
+if(this._listeners[i]==listener){
+this._listeners.splice(i,1);
+break;
+}
+}
+};
+
+Timeline.DefaultEventSource.prototype.loadXML=function(xml,url){
+var base=this._getBaseURL(url);
+
+var wikiURL=xml.documentElement.getAttribute("wiki-url");
+var wikiSection=xml.documentElement.getAttribute("wiki-section");
+
+var dateTimeFormat=xml.documentElement.getAttribute("date-time-format");
+var parseDateTimeFunction=this._events.getUnit().getParser(dateTimeFormat);
+
+var node=xml.documentElement.firstChild;
+var added=false;
+while(node!=null){
+if(node.nodeType==1){
+var description="";
+if(node.firstChild!=null&&node.firstChild.nodeType==3){
+description=node.firstChild.nodeValue;
+}
+var evt=new Timeline.DefaultEventSource.Event(
+node.getAttribute("id"),
+parseDateTimeFunction(node.getAttribute("start")),
+parseDateTimeFunction(node.getAttribute("end")),
+parseDateTimeFunction(node.getAttribute("latestStart")),
+parseDateTimeFunction(node.getAttribute("earliestEnd")),
+node.getAttribute("isDuration")!="true",
+node.getAttribute("title"),
+description,
+this._resolveRelativeURL(node.getAttribute("image"),base),
+this._resolveRelativeURL(node.getAttribute("link"),base),
+this._resolveRelativeURL(node.getAttribute("icon"),base),
+node.getAttribute("color"),
+node.getAttribute("textColor")
+);
+evt._node=node;
+evt.getProperty=function(name){
+return this._node.getAttribute(name);
+};
+evt.setWikiInfo(wikiURL,wikiSection);
+
+this._events.add(evt);
+
+added=true;
+}
+node=node.nextSibling;
+}
+
+if(added){
+this._fire("onAddMany",[]);
+}
+};
+
+
+Timeline.DefaultEventSource.prototype.loadJSON=function(data,url){
+var base=this._getBaseURL(url);
+var added=false;
+if(data&&data.events){
+var wikiURL=("wikiURL"in data)?data.wikiURL:null;
+var wikiSection=("wikiSection"in data)?data.wikiSection:null;
+
+var dateTimeFormat=("dateTimeFormat"in data)?data.dateTimeFormat:null;
+var parseDateTimeFunction=this._events.getUnit().getParser(dateTimeFormat);
+
+for(var i=0;i<data.events.length;i++){
+var event=data.events[i];
+var evt=new Timeline.DefaultEventSource.Event(
+("id"in event)?event.id:undefined,
+parseDateTimeFunction(event.start),
+parseDateTimeFunction(event.end),
+parseDateTimeFunction(event.latestStart),
+parseDateTimeFunction(event.earliestEnd),
+event.isDuration||false,
+event.title,
+event.description,
+this._resolveRelativeURL(event.image,base),
+this._resolveRelativeURL(event.link,base),
+this._resolveRelativeURL(event.icon,base),
+event.color,
+event.textColor
+);
+evt._obj=event;
+evt.getProperty=function(name){
+return this._obj[name];
+};
+evt.setWikiInfo(wikiURL,wikiSection);
+
+this._events.add(evt);
+added=true;
+}
+}
+
+if(added){
+this._fire("onAddMany",[]);
+}
+};
+
+
+Timeline.DefaultEventSource.prototype.loadSPARQL=function(xml,url){
+var base=this._getBaseURL(url);
+
+var dateTimeFormat='iso8601';
+var parseDateTimeFunction=this._events.getUnit().getParser(dateTimeFormat);
+
+if(xml==null){
+return;
+}
+
+
+var node=xml.documentElement.firstChild;
+while(node!=null&&(node.nodeType!=1||node.nodeName!='results')){
+node=node.nextSibling;
+}
+
+var wikiURL=null;
+var wikiSection=null;
+if(node!=null){
+wikiURL=node.getAttribute("wiki-url");
+wikiSection=node.getAttribute("wiki-section");
+
+node=node.firstChild;
+}
+
+var added=false;
+while(node!=null){
+if(node.nodeType==1){
+var bindings={};
+var binding=node.firstChild;
+while(binding!=null){
+if(binding.nodeType==1&&
+binding.firstChild!=null&&
+binding.firstChild.nodeType==1&&
+binding.firstChild.firstChild!=null&&
+binding.firstChild.firstChild.nodeType==3){
+bindings[binding.getAttribute('name')]=binding.firstChild.firstChild.nodeValue;
+}
+binding=binding.nextSibling;
+}
+
+if(bindings["start"]==null&&bindings["date"]!=null){
+bindings["start"]=bindings["date"];
+}
+
+var evt=new Timeline.DefaultEventSource.Event(
+bindings["id"],
+parseDateTimeFunction(bindings["start"]),
+parseDateTimeFunction(bindings["end"]),
+parseDateTimeFunction(bindings["latestStart"]),
+parseDateTimeFunction(bindings["earliestEnd"]),
+bindings["isDuration"]!="true",
+bindings["title"],
+bindings["description"],
+this._resolveRelativeURL(bindings["image"],base),
+this._resolveRelativeURL(bindings["link"],base),
+this._resolveRelativeURL(bindings["icon"],base),
+bindings["color"],
+bindings["textColor"]
+);
+evt._bindings=bindings;
+evt.getProperty=function(name){
+return this._bindings[name];
+};
+evt.setWikiInfo(wikiURL,wikiSection);
+
+this._events.add(evt);
+added=true;
+}
+node=node.nextSibling;
+}
+
+if(added){
+this._fire("onAddMany",[]);
+}
+};
+
+Timeline.DefaultEventSource.prototype.add=function(evt){
+this._events.add(evt);
+this._fire("onAddOne",[evt]);
+};
+
+Timeline.DefaultEventSource.prototype.addMany=function(events){
+for(var i=0;i<events.length;i++){
+this._events.add(events[i]);
+}
+this._fire("onAddMany",[]);
+};
+
+Timeline.DefaultEventSource.prototype.clear=function(){
+this._events.removeAll();
+this._fire("onClear",[]);
+};
+
+Timeline.DefaultEventSource.prototype.getEvent=function(id){
+return this._events.getEvent(id);
+};
+
+Timeline.DefaultEventSource.prototype.getEventIterator=function(startDate,endDate){
+return this._events.getIterator(startDate,endDate);
+};
+
+Timeline.DefaultEventSource.prototype.getEventReverseIterator=function(startDate,endDate){
+return this._events.getReverseIterator(startDate,endDate);
+};
+
+Timeline.DefaultEventSource.prototype.getAllEventIterator=function(){
+return this._events.getAllIterator();
+};
+
+Timeline.DefaultEventSource.prototype.getCount=function(){
+return this._events.getCount();
+};
+
+Timeline.DefaultEventSource.prototype.getEarliestDate=function(){
+return this._events.getEarliestDate();
+};
+
+Timeline.DefaultEventSource.prototype.getLatestDate=function(){
+return this._events.getLatestDate();
+};
+
+Timeline.DefaultEventSource.prototype._fire=function(handlerName,args){
+for(var i=0;i<this._listeners.length;i++){
+var listener=this._listeners[i];
+if(handlerName in listener){
+try{
+listener[handlerName].apply(listener,args);
+}catch(e){
+SimileAjax.Debug.exception(e);
+}
+}
+}
+};
+
+Timeline.DefaultEventSource.prototype._getBaseURL=function(url){
+if(url.indexOf("://")<0){
+var url2=this._getBaseURL(document.location.href);
+if(url.substr(0,1)=="/"){
+url=url2.substr(0,url2.indexOf("/",url2.indexOf("://")+3))+url;
+}else{
+url=url2+url;
+}
+}
+
+var i=url.lastIndexOf("/");
+if(i<0){
+return"";
+}else{
+return url.substr(0,i+1);
+}
+};
+
+Timeline.DefaultEventSource.prototype._resolveRelativeURL=function(url,base){
+if(url==null||url==""){
+return url;
+}else if(url.indexOf("://")>0){
+return url;
+}else if(url.substr(0,1)=="/"){
+return base.substr(0,base.indexOf("/",base.indexOf("://")+3))+url;
+}else{
+return base+url;
+}
+};
+
+
+Timeline.DefaultEventSource.Event=function(
+id,
+start,end,latestStart,earliestEnd,instant,
+text,description,image,link,
+icon,color,textColor){
+
+id=(id)?id.trim():"";
+this._id=id.length>0?id:("e"+Math.floor(Math.random()*1000000));
+
+this._instant=instant||(end==null);
+
+this._start=start;
+this._end=(end!=null)?end:start;
+
+this._latestStart=(latestStart!=null)?latestStart:(instant?this._end:this._start);
+this._earliestEnd=(earliestEnd!=null)?earliestEnd:(instant?this._start:this._end);
+
+this._text=SimileAjax.HTML.deEntify(text);
+this._description=SimileAjax.HTML.deEntify(description);
+this._image=(image!=null&&image!="")?image:null;
+this._link=(link!=null&&link!="")?link:null;
+
+this._icon=(icon!=null&&icon!="")?icon:null;
+this._color=(color!=null&&color!="")?color:null;
+this._textColor=(textColor!=null&&textColor!="")?textColor:null;
+
+this._wikiURL=null;
+this._wikiSection=null;
+};
+
+Timeline.DefaultEventSource.Event.prototype={
+getID:function(){return this._id;},
+
+isInstant:function(){return this._instant;},
+isImprecise:function(){return this._start!=this._latestStart||this._end!=this._earliestEnd;},
+
+getStart:function(){return this._start;},
+getEnd:function(){return this._end;},
+getLatestStart:function(){return this._latestStart;},
+getEarliestEnd:function(){return this._earliestEnd;},
+
+getText:function(){return this._text;},
+getDescription:function(){return this._description;},
+getImage:function(){return this._image;},
+getLink:function(){return this._link;},
+
+getIcon:function(){return this._icon;},
+getColor:function(){return this._color;},
+getTextColor:function(){return this._textColor;},
+
+getProperty:function(name){return null;},
+
+getWikiURL:function(){return this._wikiURL;},
+getWikiSection:function(){return this._wikiSection;},
+setWikiInfo:function(wikiURL,wikiSection){
+this._wikiURL=wikiURL;
+this._wikiSection=wikiSection;
+},
+
+fillDescription:function(elmt){
+elmt.innerHTML=this._description;
+},
+fillWikiInfo:function(elmt){
+if(this._wikiURL!=null&&this._wikiSection!=null){
+var wikiID=this.getProperty("wikiID");
+if(wikiID==null||wikiID.length==0){
+wikiID=this.getText();
+}
+wikiID=wikiID.replace(/\s/g,"_");
+
+var url=this._wikiURL+this._wikiSection.replace(/\s/g,"_")+"/"+wikiID;
+var a=document.createElement("a");
+a.href=url;
+a.target="new";
+a.innerHTML=Timeline.strings[Timeline.clientLocale].wikiLinkLabel;
+
+elmt.appendChild(document.createTextNode("["));
+elmt.appendChild(a);
+elmt.appendChild(document.createTextNode("]"));
+}else{
+elmt.style.display="none";
+}
+},
+fillTime:function(elmt,labeller){
+if(this._instant){
+if(this.isImprecise()){
+elmt.appendChild(elmt.ownerDocument.createTextNode(labeller.labelPrecise(this._start)));
+elmt.appendChild(elmt.ownerDocument.createElement("br"));
+elmt.appendChild(elmt.ownerDocument.createTextNode(labeller.labelPrecise(this._end)));
+}else{
+elmt.appendChild(elmt.ownerDocument.createTextNode(labeller.labelPrecise(this._start)));
+}
+}else{
+if(this.isImprecise()){
+elmt.appendChild(elmt.ownerDocument.createTextNode(
+labeller.labelPrecise(this._start)+" ~ "+labeller.labelPrecise(this._latestStart)));
+elmt.appendChild(elmt.ownerDocument.createElement("br"));
+elmt.appendChild(elmt.ownerDocument.createTextNode(
+labeller.labelPrecise(this._earliestEnd)+" ~ "+labeller.labelPrecise(this._end)));
+}else{
+elmt.appendChild(elmt.ownerDocument.createTextNode(labeller.labelPrecise(this._start)));
+elmt.appendChild(elmt.ownerDocument.createElement("br"));
+elmt.appendChild(elmt.ownerDocument.createTextNode(labeller.labelPrecise(this._end)));
+}
+}
+},
+fillInfoBubble:function(elmt,theme,labeller){
+var doc=elmt.ownerDocument;
+
+var title=this.getText();
+var link=this.getLink();
+var image=this.getImage();
+
+if(image!=null){
+var img=doc.createElement("img");
+img.src=image;
+
+theme.event.bubble.imageStyler(img);
+elmt.appendChild(img);
+}
+
+var divTitle=doc.createElement("div");
+var textTitle=doc.createTextNode(title);
+if(link!=null){
+var a=doc.createElement("a");
+a.href=link;
+a.appendChild(textTitle);
+divTitle.appendChild(a);
+}else{
+divTitle.appendChild(textTitle);
+}
+theme.event.bubble.titleStyler(divTitle);
+elmt.appendChild(divTitle);
+
+var divBody=doc.createElement("div");
+this.fillDescription(divBody);
+theme.event.bubble.bodyStyler(divBody);
+elmt.appendChild(divBody);
+
+var divTime=doc.createElement("div");
+this.fillTime(divTime,labeller);
+theme.event.bubble.timeStyler(divTime);
+elmt.appendChild(divTime);
+
+var divWiki=doc.createElement("div");
+this.fillWikiInfo(divWiki);
+theme.event.bubble.wikiStyler(divWiki);
+elmt.appendChild(divWiki);
+}
+};
+
+/* themes.js */
+
+
+
+
+Timeline.ClassicTheme=new Object();
+
+Timeline.ClassicTheme.implementations=[];
+
+Timeline.ClassicTheme.create=function(locale){
+if(locale==null){
+locale=Timeline.getDefaultLocale();
+}
+
+var f=Timeline.ClassicTheme.implementations[locale];
+if(f==null){
+f=Timeline.ClassicTheme._Impl;
+}
+return new f();
+};
+
+Timeline.ClassicTheme._Impl=function(){
+this.firstDayOfWeek=0;
+
+this.ether={
+backgroundColors:[
+"#EEE",
+"#DDD",
+"#CCC",
+"#AAA"
+],
+highlightColor:"white",
+highlightOpacity:50,
+interval:{
+line:{
+show:true,
+color:"#aaa",
+opacity:25
+},
+weekend:{
+color:"#FFFFE0",
+opacity:30
+},
+marker:{
+hAlign:"Bottom",
+hBottomStyler:function(elmt){
+elmt.className="timeline-ether-marker-bottom";
+},
+hBottomEmphasizedStyler:function(elmt){
+elmt.className="timeline-ether-marker-bottom-emphasized";
+},
+hTopStyler:function(elmt){
+elmt.className="timeline-ether-marker-top";
+},
+hTopEmphasizedStyler:function(elmt){
+elmt.className="timeline-ether-marker-top-emphasized";
+},
+
+vAlign:"Right",
+vRightStyler:function(elmt){
+elmt.className="timeline-ether-marker-right";
+},
+vRightEmphasizedStyler:function(elmt){
+elmt.className="timeline-ether-marker-right-emphasized";
+},
+vLeftStyler:function(elmt){
+elmt.className="timeline-ether-marker-left";
+},
+vLeftEmphasizedStyler:function(elmt){
+elmt.className="timeline-ether-marker-left-emphasized";
+}
+}
+}
+};
+
+this.event={
+track:{
+height:10,
+gap:2
+},
+overviewTrack:{
+offset:20,
+tickHeight:6,
+height:2,
+gap:1
+},
+tape:{
+height:4
+},
+instant:{
+icon:Timeline.urlPrefix+"images/dull-blue-circle.png",
+iconWidth:10,
+iconHeight:10,
+color:"#58A0DC",
+impreciseColor:"#58A0DC",
+impreciseOpacity:20
+},
+duration:{
+color:"#58A0DC",
+impreciseColor:"#58A0DC",
+impreciseOpacity:20
+},
+label:{
+backgroundColor:"white",
+backgroundOpacity:50,
+lineColor:"#58A0DC",
+offsetFromLine:3
+},
+highlightColors:[
+"#FFFF00",
+"#FFC000",
+"#FF0000",
+"#0000FF"
+],
+bubble:{
+width:250,
+height:125,
+titleStyler:function(elmt){
+elmt.className="timeline-event-bubble-title";
+},
+bodyStyler:function(elmt){
+elmt.className="timeline-event-bubble-body";
+},
+imageStyler:function(elmt){
+elmt.className="timeline-event-bubble-image";
+},
+wikiStyler:function(elmt){
+elmt.className="timeline-event-bubble-wiki";
+},
+timeStyler:function(elmt){
+elmt.className="timeline-event-bubble-time";
+}
+}
+};
+};
+
+/* timeline.js */
+
+
+
+Timeline.strings={};
+
+Timeline.getDefaultLocale=function(){
+return Timeline.clientLocale;
+};
+
+Timeline.create=function(elmt,bandInfos,orientation,unit){
+return new Timeline._Impl(elmt,bandInfos,orientation,unit);
+};
+
+Timeline.HORIZONTAL=0;
+Timeline.VERTICAL=1;
+
+Timeline._defaultTheme=null;
+
+Timeline.createBandInfo=function(params){
+var theme=("theme"in params)?params.theme:Timeline.getDefaultTheme();
+
+var eventSource=("eventSource"in params)?params.eventSource:null;
+
+var ether=new Timeline.LinearEther({
+centersOn:("date"in params)?params.date:new Date(),
+interval:SimileAjax.DateTime.gregorianUnitLengths[params.intervalUnit],
+pixelsPerInterval:params.intervalPixels
+});
+
+var etherPainter=new Timeline.GregorianEtherPainter({
+unit:params.intervalUnit,
+multiple:("multiple"in params)?params.multiple:1,
+theme:theme,
+align:("align"in params)?params.align:undefined
+});
+
+var eventPainterParams={
+showText:("showEventText"in params)?params.showEventText:true,
+theme:theme
+};
+if("trackHeight"in params){
+eventPainterParams.trackHeight=params.trackHeight;
+}
+if("trackGap"in params){
+eventPainterParams.trackGap=params.trackGap;
+}
+
+var layout=("overview"in params&&params.overview)?"overview":("layout"in params?params.layout:"original");
+var eventPainter;
+switch(layout){
+case"overview":
+eventPainter=new Timeline.OverviewEventPainter(eventPainterParams);
+break;
+case"detailed":
+eventPainter=new Timeline.DetailedEventPainter(eventPainterParams);
+break;
+default:
+eventPainter=new Timeline.OriginalEventPainter(eventPainterParams);
+}
+
+return{
+width:params.width,
+eventSource:eventSource,
+timeZone:("timeZone"in params)?params.timeZone:0,
+ether:ether,
+etherPainter:etherPainter,
+eventPainter:eventPainter
+};
+};
+
+Timeline.createHotZoneBandInfo=function(params){
+var theme=("theme"in params)?params.theme:Timeline.getDefaultTheme();
+
+var eventSource=("eventSource"in params)?params.eventSource:null;
+
+var ether=new Timeline.HotZoneEther({
+centersOn:("date"in params)?params.date:new Date(),
+interval:SimileAjax.DateTime.gregorianUnitLengths[params.intervalUnit],
+pixelsPerInterval:params.intervalPixels,
+zones:params.zones
+});
+
+var etherPainter=new Timeline.HotZoneGregorianEtherPainter({
+unit:params.intervalUnit,
+zones:params.zones,
+theme:theme,
+align:("align"in params)?params.align:undefined
+});
+
+var eventPainterParams={
+showText:("showEventText"in params)?params.showEventText:true,
+theme:theme
+};
+if("trackHeight"in params){
+eventPainterParams.trackHeight=params.trackHeight;
+}
+if("trackGap"in params){
+eventPainterParams.trackGap=params.trackGap;
+}
+
+var layout=("overview"in params&&params.overview)?"overview":("layout"in params?params.layout:"original");
+var eventPainter;
+switch(layout){
+case"overview":
+eventPainter=new Timeline.OverviewEventPainter(eventPainterParams);
+break;
+case"detailed":
+eventPainter=new Timeline.DetailedEventPainter(eventPainterParams);
+break;
+default:
+eventPainter=new Timeline.OriginalEventPainter(eventPainterParams);
+}
+
+return{
+width:params.width,
+eventSource:eventSource,
+timeZone:("timeZone"in params)?params.timeZone:0,
+ether:ether,
+etherPainter:etherPainter,
+eventPainter:eventPainter
+};
+};
+
+Timeline.getDefaultTheme=function(){
+if(Timeline._defaultTheme==null){
+Timeline._defaultTheme=Timeline.ClassicTheme.create(Timeline.getDefaultLocale());
+}
+return Timeline._defaultTheme;
+};
+
+Timeline.setDefaultTheme=function(theme){
+Timeline._defaultTheme=theme;
+};
+
+Timeline.loadXML=function(url,f){
+var fError=function(statusText,status,xmlhttp){
+alert("Failed to load data xml from "+url+"\n"+statusText);
+};
+var fDone=function(xmlhttp){
+var xml=xmlhttp.responseXML;
+if(!xml.documentElement&&xmlhttp.responseStream){
+xml.load(xmlhttp.responseStream);
+}
+f(xml,url);
+};
+SimileAjax.XmlHttp.get(url,fError,fDone);
+};
+
+
+Timeline.loadJSON=function(url,f){
+var fError=function(statusText,status,xmlhttp){
+alert("Failed to load json data from "+url+"\n"+statusText);
+};
+var fDone=function(xmlhttp){
+f(eval('('+xmlhttp.responseText+')'),url);
+};
+SimileAjax.XmlHttp.get(url,fError,fDone);
+};
+
+
+Timeline._Impl=function(elmt,bandInfos,orientation,unit){
+SimileAjax.WindowManager.initialize();
+
+this._containerDiv=elmt;
+
+this._bandInfos=bandInfos;
+this._orientation=orientation==null?Timeline.HORIZONTAL:orientation;
+this._unit=(unit!=null)?unit:SimileAjax.NativeDateUnit;
+
+this._initialize();
+};
+
+Timeline._Impl.prototype.dispose=function(){
+for(var i=0;i<this._bands.length;i++){
+this._bands[i].dispose();
+}
+this._bands=null;
+this._bandInfos=null;
+this._containerDiv.innerHTML="";
+};
+
+Timeline._Impl.prototype.getBandCount=function(){
+return this._bands.length;
+};
+
+Timeline._Impl.prototype.getBand=function(index){
+return this._bands[index];
+};
+
+Timeline._Impl.prototype.layout=function(){
+this._distributeWidths();
+};
+
+Timeline._Impl.prototype.paint=function(){
+for(var i=0;i<this._bands.length;i++){
+this._bands[i].paint();
+}
+};
+
+Timeline._Impl.prototype.getDocument=function(){
+return this._containerDiv.ownerDocument;
+};
+
+Timeline._Impl.prototype.addDiv=function(div){
+this._containerDiv.appendChild(div);
+};
+
+Timeline._Impl.prototype.removeDiv=function(div){
+this._containerDiv.removeChild(div);
+};
+
+Timeline._Impl.prototype.isHorizontal=function(){
+return this._orientation==Timeline.HORIZONTAL;
+};
+
+Timeline._Impl.prototype.isVertical=function(){
+return this._orientation==Timeline.VERTICAL;
+};
+
+Timeline._Impl.prototype.getPixelLength=function(){
+return this._orientation==Timeline.HORIZONTAL?
+this._containerDiv.offsetWidth:this._containerDiv.offsetHeight;
+};
+
+Timeline._Impl.prototype.getPixelWidth=function(){
+return this._orientation==Timeline.VERTICAL?
+this._containerDiv.offsetWidth:this._containerDiv.offsetHeight;
+};
+
+Timeline._Impl.prototype.getUnit=function(){
+return this._unit;
+};
+
+Timeline._Impl.prototype.loadXML=function(url,f){
+var tl=this;
+
+
+var fError=function(statusText,status,xmlhttp){
+alert("Failed to load data xml from "+url+"\n"+statusText);
+tl.hideLoadingMessage();
+};
+var fDone=function(xmlhttp){
+try{
+var xml=xmlhttp.responseXML;
+if(!xml.documentElement&&xmlhttp.responseStream){
+xml.load(xmlhttp.responseStream);
+}
+f(xml,url);
+}finally{
+tl.hideLoadingMessage();
+}
+};
+
+this.showLoadingMessage();
+window.setTimeout(function(){SimileAjax.XmlHttp.get(url,fError,fDone);},0);
+};
+
+Timeline._Impl.prototype.loadJSON=function(url,f){
+var tl=this;
+
+
+var fError=function(statusText,status,xmlhttp){
+alert("Failed to load json data from "+url+"\n"+statusText);
+tl.hideLoadingMessage();
+};
+var fDone=function(xmlhttp){
+try{
+f(eval('('+xmlhttp.responseText+')'),url);
+}finally{
+tl.hideLoadingMessage();
+}
+};
+
+this.showLoadingMessage();
+window.setTimeout(function(){SimileAjax.XmlHttp.get(url,fError,fDone);},0);
+};
+
+Timeline._Impl.prototype._initialize=function(){
+var containerDiv=this._containerDiv;
+var doc=containerDiv.ownerDocument;
+
+containerDiv.className=
+containerDiv.className.split(" ").concat("timeline-container").join(" ");
+
+while(containerDiv.firstChild){
+containerDiv.removeChild(containerDiv.firstChild);
+}
+
+
+var elmtCopyright=SimileAjax.Graphics.createTranslucentImage(Timeline.urlPrefix+(this.isHorizontal()?"images/copyright-vertical.png":"images/copyright.png"));
+elmtCopyright.className="timeline-copyright";
+elmtCopyright.title="Timeline (c) SIMILE - http://simile.mit.edu/timeline/";
+SimileAjax.DOM.registerEvent(elmtCopyright,"click",function(){window.location="http://simile.mit.edu/timeline/";});
+containerDiv.appendChild(elmtCopyright);
+
+
+this._bands=[];
+for(var i=0;i<this._bandInfos.length;i++){
+var band=new Timeline._Band(this,this._bandInfos[i],i);
+this._bands.push(band);
+}
+this._distributeWidths();
+
+
+for(var i=0;i<this._bandInfos.length;i++){
+var bandInfo=this._bandInfos[i];
+if("syncWith"in bandInfo){
+this._bands[i].setSyncWithBand(
+this._bands[bandInfo.syncWith],
+("highlight"in bandInfo)?bandInfo.highlight:false
+);
+}
+}
+
+
+var message=SimileAjax.Graphics.createMessageBubble(doc);
+message.containerDiv.className="timeline-message-container";
+containerDiv.appendChild(message.containerDiv);
+
+message.contentDiv.className="timeline-message";
+message.contentDiv.innerHTML="<img src='"+Timeline.urlPrefix+"images/progress-running.gif' /> Loading...";
+
+this.showLoadingMessage=function(){message.containerDiv.style.display="block";};
+this.hideLoadingMessage=function(){message.containerDiv.style.display="none";};
+};
+
+Timeline._Impl.prototype._distributeWidths=function(){
+var length=this.getPixelLength();
+var width=this.getPixelWidth();
+var cumulativeWidth=0;
+
+for(var i=0;i<this._bands.length;i++){
+var band=this._bands[i];
+var bandInfos=this._bandInfos[i];
+var widthString=bandInfos.width;
+
+var x=widthString.indexOf("%");
+if(x>0){
+var percent=parseInt(widthString.substr(0,x));
+var bandWidth=percent*width/100;
+}else{
+var bandWidth=parseInt(widthString);
+}
+
+band.setBandShiftAndWidth(cumulativeWidth,bandWidth);
+band.setViewLength(length);
+
+cumulativeWidth+=bandWidth;
+}
+};
+
+
+Timeline._Band=function(timeline,bandInfo,index){
+this._timeline=timeline;
+this._bandInfo=bandInfo;
+this._index=index;
+
+this._locale=("locale"in bandInfo)?bandInfo.locale:Timeline.getDefaultLocale();
+this._timeZone=("timeZone"in bandInfo)?bandInfo.timeZone:0;
+this._labeller=("labeller"in bandInfo)?bandInfo.labeller:
+(("createLabeller"in timeline.getUnit())?
+timeline.getUnit().createLabeller(this._locale,this._timeZone):
+new Timeline.GregorianDateLabeller(this._locale,this._timeZone));
+
+this._dragging=false;
+this._changing=false;
+this._originalScrollSpeed=5;
+this._scrollSpeed=this._originalScrollSpeed;
+this._onScrollListeners=[];
+
+var b=this;
+this._syncWithBand=null;
+this._syncWithBandHandler=function(band){
+b._onHighlightBandScroll();
+};
+this._selectorListener=function(band){
+b._onHighlightBandScroll();
+};
+
+
+var inputDiv=this._timeline.getDocument().createElement("div");
+inputDiv.className="timeline-band-input";
+this._timeline.addDiv(inputDiv);
+
+this._keyboardInput=document.createElement("input");
+this._keyboardInput.type="text";
+inputDiv.appendChild(this._keyboardInput);
+SimileAjax.DOM.registerEventWithObject(this._keyboardInput,"keydown",this,"_onKeyDown");
+SimileAjax.DOM.registerEventWithObject(this._keyboardInput,"keyup",this,"_onKeyUp");
+
+
+this._div=this._timeline.getDocument().createElement("div");
+this._div.className="timeline-band timeline-band-"+index;
+this._timeline.addDiv(this._div);
+
+SimileAjax.DOM.registerEventWithObject(this._div,"mousedown",this,"_onMouseDown");
+SimileAjax.DOM.registerEventWithObject(this._div,"mousemove",this,"_onMouseMove");
+SimileAjax.DOM.registerEventWithObject(this._div,"mouseup",this,"_onMouseUp");
+SimileAjax.DOM.registerEventWithObject(this._div,"mouseout",this,"_onMouseOut");
+SimileAjax.DOM.registerEventWithObject(this._div,"dblclick",this,"_onDblClick");
+
+
+this._innerDiv=this._timeline.getDocument().createElement("div");
+this._innerDiv.className="timeline-band-inner";
+this._div.appendChild(this._innerDiv);
+
+
+this._ether=bandInfo.ether;
+bandInfo.ether.initialize(timeline);
+
+this._etherPainter=bandInfo.etherPainter;
+bandInfo.etherPainter.initialize(this,timeline);
+
+this._eventSource=bandInfo.eventSource;
+if(this._eventSource){
+this._eventListener={
+onAddMany:function(){b._onAddMany();},
+onClear:function(){b._onClear();}
+}
+this._eventSource.addListener(this._eventListener);
+}
+
+this._eventPainter=bandInfo.eventPainter;
+bandInfo.eventPainter.initialize(this,timeline);
+
+this._decorators=("decorators"in bandInfo)?bandInfo.decorators:[];
+for(var i=0;i<this._decorators.length;i++){
+this._decorators[i].initialize(this,timeline);
+}
+};
+
+Timeline._Band.SCROLL_MULTIPLES=5;
+
+Timeline._Band.prototype.dispose=function(){
+this.closeBubble();
+
+if(this._eventSource){
+this._eventSource.removeListener(this._eventListener);
+this._eventListener=null;
+this._eventSource=null;
+}
+
+this._timeline=null;
+this._bandInfo=null;
+
+this._labeller=null;
+this._ether=null;
+this._etherPainter=null;
+this._eventPainter=null;
+this._decorators=null;
+
+this._onScrollListeners=null;
+this._syncWithBandHandler=null;
+this._selectorListener=null;
+
+this._div=null;
+this._innerDiv=null;
+this._keyboardInput=null;
+};
+
+Timeline._Band.prototype.addOnScrollListener=function(listener){
+this._onScrollListeners.push(listener);
+};
+
+Timeline._Band.prototype.removeOnScrollListener=function(listener){
+for(var i=0;i<this._onScrollListeners.length;i++){
+if(this._onScrollListeners[i]==listener){
+this._onScrollListeners.splice(i,1);
+break;
+}
+}
+};
+
+Timeline._Band.prototype.setSyncWithBand=function(band,highlight){
+if(this._syncWithBand){
+this._syncWithBand.removeOnScrollListener(this._syncWithBandHandler);
+}
+
+this._syncWithBand=band;
+this._syncWithBand.addOnScrollListener(this._syncWithBandHandler);
+this._highlight=highlight;
+this._positionHighlight();
+};
+
+Timeline._Band.prototype.getLocale=function(){
+return this._locale;
+};
+
+Timeline._Band.prototype.getTimeZone=function(){
+return this._timeZone;
+};
+
+Timeline._Band.prototype.getLabeller=function(){
+return this._labeller;
+};
+
+Timeline._Band.prototype.getIndex=function(){
+return this._index;
+};
+
+Timeline._Band.prototype.getEther=function(){
+return this._ether;
+};
+
+Timeline._Band.prototype.getEtherPainter=function(){
+return this._etherPainter;
+};
+
+Timeline._Band.prototype.getEventSource=function(){
+return this._eventSource;
+};
+
+Timeline._Band.prototype.getEventPainter=function(){
+return this._eventPainter;
+};
+
+Timeline._Band.prototype.layout=function(){
+this.paint();
+};
+
+Timeline._Band.prototype.paint=function(){
+this._etherPainter.paint();
+this._paintDecorators();
+this._paintEvents();
+};
+
+Timeline._Band.prototype.softLayout=function(){
+this.softPaint();
+};
+
+Timeline._Band.prototype.softPaint=function(){
+this._etherPainter.softPaint();
+this._softPaintDecorators();
+this._softPaintEvents();
+};
+
+Timeline._Band.prototype.setBandShiftAndWidth=function(shift,width){
+var inputDiv=this._keyboardInput.parentNode;
+var middle=shift+Math.floor(width/2);
+if(this._timeline.isHorizontal()){
+this._div.style.top=shift+"px";
+this._div.style.height=width+"px";
+
+inputDiv.style.top=middle+"px";
+inputDiv.style.left="-1em";
+}else{
+this._div.style.left=shift+"px";
+this._div.style.width=width+"px";
+
+inputDiv.style.left=middle+"px";
+inputDiv.style.top="-1em";
+}
+};
+
+Timeline._Band.prototype.getViewWidth=function(){
+if(this._timeline.isHorizontal()){
+return this._div.offsetHeight;
+}else{
+return this._div.offsetWidth;
+}
+};
+
+Timeline._Band.prototype.setViewLength=function(length){
+this._viewLength=length;
+this._recenterDiv();
+this._onChanging();
+};
+
+Timeline._Band.prototype.getViewLength=function(){
+return this._viewLength;
+};
+
+Timeline._Band.prototype.getTotalViewLength=function(){
+return Timeline._Band.SCROLL_MULTIPLES*this._viewLength;
+};
+
+Timeline._Band.prototype.getViewOffset=function(){
+return this._viewOffset;
+};
+
+Timeline._Band.prototype.getMinDate=function(){
+return this._ether.pixelOffsetToDate(this._viewOffset);
+};
+
+Timeline._Band.prototype.getMaxDate=function(){
+return this._ether.pixelOffsetToDate(this._viewOffset+Timeline._Band.SCROLL_MULTIPLES*this._viewLength);
+};
+
+Timeline._Band.prototype.getMinVisibleDate=function(){
+return this._ether.pixelOffsetToDate(0);
+};
+
+Timeline._Band.prototype.getMaxVisibleDate=function(){
+return this._ether.pixelOffsetToDate(this._viewLength);
+};
+
+Timeline._Band.prototype.getCenterVisibleDate=function(){
+return this._ether.pixelOffsetToDate(this._viewLength/2);
+};
+
+Timeline._Band.prototype.setMinVisibleDate=function(date){
+if(!this._changing){
+this._moveEther(Math.round(-this._ether.dateToPixelOffset(date)));
+}
+};
+
+Timeline._Band.prototype.setMaxVisibleDate=function(date){
+if(!this._changing){
+this._moveEther(Math.round(this._viewLength-this._ether.dateToPixelOffset(date)));
+}
+};
+
+Timeline._Band.prototype.setCenterVisibleDate=function(date){
+if(!this._changing){
+this._moveEther(Math.round(this._viewLength/2-this._ether.dateToPixelOffset(date)));
+}
+};
+
+Timeline._Band.prototype.dateToPixelOffset=function(date){
+return this._ether.dateToPixelOffset(date)-this._viewOffset;
+};
+
+Timeline._Band.prototype.pixelOffsetToDate=function(pixels){
+return this._ether.pixelOffsetToDate(pixels+this._viewOffset);
+};
+
+Timeline._Band.prototype.createLayerDiv=function(zIndex,className){
+var div=this._timeline.getDocument().createElement("div");
+div.className="timeline-band-layer"+(typeof className=="string"?(" "+className):"");
+div.style.zIndex=zIndex;
+this._innerDiv.appendChild(div);
+
+var innerDiv=this._timeline.getDocument().createElement("div");
+innerDiv.className="timeline-band-layer-inner";
+if(SimileAjax.Platform.browser.isIE){
+innerDiv.style.cursor="move";
+}else{
+innerDiv.style.cursor="-moz-grab";
+}
+div.appendChild(innerDiv);
+
+return innerDiv;
+};
+
+Timeline._Band.prototype.removeLayerDiv=function(div){
+this._innerDiv.removeChild(div.parentNode);
+};
+
+Timeline._Band.prototype.scrollToCenter=function(date,f){
+var pixelOffset=this._ether.dateToPixelOffset(date);
+if(pixelOffset<-this._viewLength/2){
+this.setCenterVisibleDate(this.pixelOffsetToDate(pixelOffset+this._viewLength));
+}else if(pixelOffset>3*this._viewLength/2){
+this.setCenterVisibleDate(this.pixelOffsetToDate(pixelOffset-this._viewLength));
+}
+this._autoScroll(Math.round(this._viewLength/2-this._ether.dateToPixelOffset(date)),f);
+};
+
+Timeline._Band.prototype.showBubbleForEvent=function(eventID){
+var evt=this.getEventSource().getEvent(eventID);
+if(evt){
+var self=this;
+this.scrollToCenter(evt.getStart(),function(){
+self._eventPainter.showBubble(evt);
+});
+}
+};
+
+Timeline._Band.prototype._onMouseDown=function(innerFrame,evt,target){
+this.closeBubble();
+
+this._dragging=true;
+this._dragX=evt.clientX;
+this._dragY=evt.clientY;
+};
+
+Timeline._Band.prototype._onMouseMove=function(innerFrame,evt,target){
+if(this._dragging){
+var diffX=evt.clientX-this._dragX;
+var diffY=evt.clientY-this._dragY;
+
+this._dragX=evt.clientX;
+this._dragY=evt.clientY;
+
+this._moveEther(this._timeline.isHorizontal()?diffX:diffY);
+this._positionHighlight();
+}
+};
+
+Timeline._Band.prototype._onMouseUp=function(innerFrame,evt,target){
+this._dragging=false;
+this._keyboardInput.focus();
+};
+
+Timeline._Band.prototype._onMouseOut=function(innerFrame,evt,target){
+var coords=SimileAjax.DOM.getEventRelativeCoordinates(evt,innerFrame);
+coords.x+=this._viewOffset;
+if(coords.x<0||coords.x>innerFrame.offsetWidth||
+coords.y<0||coords.y>innerFrame.offsetHeight){
+this._dragging=false;
+}
+};
+
+Timeline._Band.prototype._onDblClick=function(innerFrame,evt,target){
+var coords=SimileAjax.DOM.getEventRelativeCoordinates(evt,innerFrame);
+var distance=coords.x-(this._viewLength/2-this._viewOffset);
+
+this._autoScroll(-distance);
+};
+
+Timeline._Band.prototype._onKeyDown=function(keyboardInput,evt,target){
+if(!this._dragging){
+switch(evt.keyCode){
+case 27:
+break;
+case 37:
+case 38:
+this._scrollSpeed=Math.min(50,Math.abs(this._scrollSpeed*1.05));
+this._moveEther(this._scrollSpeed);
+break;
+case 39:
+case 40:
+this._scrollSpeed=-Math.min(50,Math.abs(this._scrollSpeed*1.05));
+this._moveEther(this._scrollSpeed);
+break;
+default:
+return true;
+}
+this.closeBubble();
+
+SimileAjax.DOM.cancelEvent(evt);
+return false;
+}
+return true;
+};
+
+Timeline._Band.prototype._onKeyUp=function(keyboardInput,evt,target){
+if(!this._dragging){
+this._scrollSpeed=this._originalScrollSpeed;
+
+switch(evt.keyCode){
+case 35:
+this.setCenterVisibleDate(this._eventSource.getLatestDate());
+break;
+case 36:
+this.setCenterVisibleDate(this._eventSource.getEarliestDate());
+break;
+case 33:
+this._autoScroll(this._timeline.getPixelLength());
+break;
+case 34:
+this._autoScroll(-this._timeline.getPixelLength());
+break;
+default:
+return true;
+}
+
+this.closeBubble();
+
+SimileAjax.DOM.cancelEvent(evt);
+return false;
+}
+return true;
+};
+
+Timeline._Band.prototype._autoScroll=function(distance,f){
+var b=this;
+var a=SimileAjax.Graphics.createAnimation(
+function(abs,diff){
+b._moveEther(diff);
+},
+0,
+distance,
+1000,
+f
+);
+a.run();
+};
+
+Timeline._Band.prototype._moveEther=function(shift){
+this.closeBubble();
+
+this._viewOffset+=shift;
+this._ether.shiftPixels(-shift);
+if(this._timeline.isHorizontal()){
+this._div.style.left=this._viewOffset+"px";
+}else{
+this._div.style.top=this._viewOffset+"px";
+}
+
+if(this._viewOffset>-this._viewLength*0.5||
+this._viewOffset<-this._viewLength*(Timeline._Band.SCROLL_MULTIPLES-1.5)){
+
+this._recenterDiv();
+}else{
+this.softLayout();
+}
+
+this._onChanging();
+}
+
+Timeline._Band.prototype._onChanging=function(){
+this._changing=true;
+
+this._fireOnScroll();
+this._setSyncWithBandDate();
+
+this._changing=false;
+};
+
+Timeline._Band.prototype._fireOnScroll=function(){
+for(var i=0;i<this._onScrollListeners.length;i++){
+this._onScrollListeners[i](this);
+}
+};
+
+Timeline._Band.prototype._setSyncWithBandDate=function(){
+if(this._syncWithBand){
+var centerDate=this._ether.pixelOffsetToDate(this.getViewLength()/2);
+this._syncWithBand.setCenterVisibleDate(centerDate);
+}
+};
+
+Timeline._Band.prototype._onHighlightBandScroll=function(){
+if(this._syncWithBand){
+var centerDate=this._syncWithBand.getCenterVisibleDate();
+var centerPixelOffset=this._ether.dateToPixelOffset(centerDate);
+
+this._moveEther(Math.round(this._viewLength/2-centerPixelOffset));
+
+if(this._highlight){
+this._etherPainter.setHighlight(
+this._syncWithBand.getMinVisibleDate(),
+this._syncWithBand.getMaxVisibleDate());
+}
+}
+};
+
+Timeline._Band.prototype._onAddMany=function(){
+this._paintEvents();
+};
+
+Timeline._Band.prototype._onClear=function(){
+this._paintEvents();
+};
+
+Timeline._Band.prototype._positionHighlight=function(){
+if(this._syncWithBand){
+var startDate=this._syncWithBand.getMinVisibleDate();
+var endDate=this._syncWithBand.getMaxVisibleDate();
+
+if(this._highlight){
+this._etherPainter.setHighlight(startDate,endDate);
+}
+}
+};
+
+Timeline._Band.prototype._recenterDiv=function(){
+this._viewOffset=-this._viewLength*(Timeline._Band.SCROLL_MULTIPLES-1)/2;
+if(this._timeline.isHorizontal()){
+this._div.style.left=this._viewOffset+"px";
+this._div.style.width=(Timeline._Band.SCROLL_MULTIPLES*this._viewLength)+"px";
+}else{
+this._div.style.top=this._viewOffset+"px";
+this._div.style.height=(Timeline._Band.SCROLL_MULTIPLES*this._viewLength)+"px";
+}
+this.layout();
+};
+
+Timeline._Band.prototype._paintEvents=function(){
+this._eventPainter.paint();
+};
+
+Timeline._Band.prototype._softPaintEvents=function(){
+this._eventPainter.softPaint();
+};
+
+Timeline._Band.prototype._paintDecorators=function(){
+for(var i=0;i<this._decorators.length;i++){
+this._decorators[i].paint();
+}
+};
+
+Timeline._Band.prototype._softPaintDecorators=function(){
+for(var i=0;i<this._decorators.length;i++){
+this._decorators[i].softPaint();
+}
+};
+
+Timeline._Band.prototype.closeBubble=function(){
+SimileAjax.WindowManager.cancelPopups();
+};
+
+
+/* units.js */
+
+
+
+
+
+Timeline.NativeDateUnit=new Object();
+
+Timeline.NativeDateUnit.createLabeller=function(locale,timeZone){
+return new Timeline.GregorianDateLabeller(locale,timeZone);
+};
+
+
+Timeline.NativeDateUnit.makeDefaultValue=function(){
+return new Date();
+};
+
+Timeline.NativeDateUnit.cloneValue=function(v){
+return new Date(v.getTime());
+};
+
+Timeline.NativeDateUnit.getParser=function(format){
+if(typeof format=="string"){
+format=format.toLowerCase();
+}
+return(format=="iso8601"||format=="iso 8601")?
+
+Timeline.DateTime.parseIso8601DateTime:
+
+Timeline.DateTime.parseGregorianDateTime;
+
+};
+
+Timeline.NativeDateUnit.parseFromObject=function(o){
+return Timeline.DateTime.parseGregorianDateTime(o);
+};
+
+
+Timeline.NativeDateUnit.toNumber=function(v){
+return v.getTime();
+};
+
+Timeline.NativeDateUnit.fromNumber=function(n){
+return new Date(n);
+};
+
+Timeline.NativeDateUnit.compare=function(v1,v2){
+var n1,n2;
+if(typeof v1=="object"){
+n1=v1.getTime();
+}else{
+n1=Number(v1);
+}
+if(typeof v2=="object"){
+n2=v2.getTime();
+}else{
+n2=Number(v2);
+}
+
+return n1-n2;
+};
+
+Timeline.NativeDateUnit.earlier=function(v1,v2){
+return Timeline.NativeDateUnit.compare(v1,v2)<0?v1:v2;
+};
+
+Timeline.NativeDateUnit.later=function(v1,v2){
+return Timeline.NativeDateUnit.compare(v1,v2)>0?v1:v2;
+};
+
+Timeline.NativeDateUnit.change=function(v,n){
+return new Date(v.getTime()+n);
+};
+
diff --git a/site/app/webroot/js/simile/timeplot/images/copyright.png b/site/app/webroot/js/simile/timeplot/images/copyright.png
new file mode 100755
index 0000000..4217f4c
--- /dev/null
+++ b/site/app/webroot/js/simile/timeplot/images/copyright.png
Binary files differ
diff --git a/site/app/webroot/js/simile/timeplot/images/line_left.png b/site/app/webroot/js/simile/timeplot/images/line_left.png
new file mode 100755
index 0000000..fb031fc
--- /dev/null
+++ b/site/app/webroot/js/simile/timeplot/images/line_left.png
Binary files differ
diff --git a/site/app/webroot/js/simile/timeplot/images/line_right.png b/site/app/webroot/js/simile/timeplot/images/line_right.png
new file mode 100755
index 0000000..4d37456
--- /dev/null
+++ b/site/app/webroot/js/simile/timeplot/images/line_right.png
Binary files differ
diff --git a/site/app/webroot/js/simile/timeplot/images/progress-running.gif b/site/app/webroot/js/simile/timeplot/images/progress-running.gif
new file mode 100755
index 0000000..f7429eb
--- /dev/null
+++ b/site/app/webroot/js/simile/timeplot/images/progress-running.gif
Binary files differ
diff --git a/site/app/webroot/js/simile/timeplot/lib/excanvas.js b/site/app/webroot/js/simile/timeplot/lib/excanvas.js
new file mode 100755
index 0000000..3e1aedf
--- /dev/null
+++ b/site/app/webroot/js/simile/timeplot/lib/excanvas.js
@@ -0,0 +1,785 @@
+// Copyright 2006 Google Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+
+// Known Issues:
+//
+// * Patterns are not implemented.
+// * Radial gradient are not implemented. The VML version of these look very
+// different from the canvas one.
+// * Clipping paths are not implemented.
+// * Coordsize. The width and height attribute have higher priority than the
+// width and height style values which isn't correct.
+// * Painting mode isn't implemented.
+// * Canvas width/height should is using content-box by default. IE in
+// Quirks mode will draw the canvas using border-box. Either change your
+// doctype to HTML5
+// (http://www.whatwg.org/specs/web-apps/current-work/#the-doctype)
+// or use Box Sizing Behavior from WebFX
+// (http://webfx.eae.net/dhtml/boxsizing/boxsizing.html)
+// * Optimize. There is always room for speed improvements.
+
+// only add this code if we do not already have a canvas implementation
+if (!window.CanvasRenderingContext2D) {
+
+(function () {
+
+ // alias some functions to make (compiled) code shorter
+ var m = Math;
+ var mr = m.round;
+ var ms = m.sin;
+ var mc = m.cos;
+
+ // this is used for sub pixel precision
+ var Z = 10;
+ var Z2 = Z / 2;
+
+ var G_vmlCanvasManager_ = {
+ init: function (opt_doc) {
+ var doc = opt_doc || document;
+ if (/MSIE/.test(navigator.userAgent) && !window.opera) {
+ var self = this;
+ doc.attachEvent("onreadystatechange", function () {
+ self.init_(doc);
+ });
+ }
+ },
+
+ init_: function (doc) {
+ if (doc.readyState == "complete") {
+ // create xmlns
+ if (!doc.namespaces["g_vml_"]) {
+ doc.namespaces.add("g_vml_", "urn:schemas-microsoft-com:vml");
+ }
+
+ // setup default css
+ var ss = doc.createStyleSheet();
+ ss.cssText = "canvas{display:inline-block;overflow:hidden;" +
+ // default size is 300x150 in Gecko and Opera
+ "text-align:left;width:300px;height:150px}" +
+ "g_vml_\\:*{behavior:url(#default#VML)}";
+
+ // find all canvas elements
+ var els = doc.getElementsByTagName("canvas");
+ for (var i = 0; i < els.length; i++) {
+ if (!els[i].getContext) {
+ this.initElement(els[i]);
+ }
+ }
+ }
+ },
+
+ fixElement_: function (el) {
+ // in IE before version 5.5 we would need to add HTML: to the tag name
+ // but we do not care about IE before version 6
+ var outerHTML = el.outerHTML;
+
+ var newEl = el.ownerDocument.createElement(outerHTML);
+ // if the tag is still open IE has created the children as siblings and
+ // it has also created a tag with the name "/FOO"
+ if (outerHTML.slice(-2) != "/>") {
+ var tagName = "/" + el.tagName;
+ var ns;
+ // remove content
+ while ((ns = el.nextSibling) && ns.tagName != tagName) {
+ ns.removeNode();
+ }
+ // remove the incorrect closing tag
+ if (ns) {
+ ns.removeNode();
+ }
+ }
+ el.parentNode.replaceChild(newEl, el);
+ return newEl;
+ },
+
+ /**
+ * Public initializes a canvas element so that it can be used as canvas
+ * element from now on. This is called automatically before the page is
+ * loaded but if you are creating elements using createElement you need to
+ * make sure this is called on the element.
+ * @param {HTMLElement} el The canvas element to initialize.
+ * @return {HTMLElement} the element that was created.
+ */
+ initElement: function (el) {
+ el = this.fixElement_(el);
+ el.getContext = function () {
+ if (this.context_) {
+ return this.context_;
+ }
+ return this.context_ = new CanvasRenderingContext2D_(this);
+ };
+
+ // do not use inline function because that will leak memory
+ el.attachEvent('onpropertychange', onPropertyChange);
+ el.attachEvent('onresize', onResize);
+
+ var attrs = el.attributes;
+ if (attrs.width && attrs.width.specified) {
+ // TODO: use runtimeStyle and coordsize
+ // el.getContext().setWidth_(attrs.width.nodeValue);
+ el.style.width = attrs.width.nodeValue + "px";
+ } else {
+ el.width = el.clientWidth;
+ }
+ if (attrs.height && attrs.height.specified) {
+ // TODO: use runtimeStyle and coordsize
+ // el.getContext().setHeight_(attrs.height.nodeValue);
+ el.style.height = attrs.height.nodeValue + "px";
+ } else {
+ el.height = el.clientHeight;
+ }
+ //el.getContext().setCoordsize_()
+ return el;
+ }
+ };
+
+ function onPropertyChange(e) {
+ var el = e.srcElement;
+
+ switch (e.propertyName) {
+ case 'width':
+ el.style.width = el.attributes.width.nodeValue + "px";
+ el.getContext().clearRect();
+ break;
+ case 'height':
+ el.style.height = el.attributes.height.nodeValue + "px";
+ el.getContext().clearRect();
+ break;
+ }
+ }
+
+ function onResize(e) {
+ var el = e.srcElement;
+ if (el.firstChild) {
+ el.firstChild.style.width = el.clientWidth + 'px';
+ el.firstChild.style.height = el.clientHeight + 'px';
+ }
+ }
+
+ G_vmlCanvasManager_.init();
+
+ // precompute "00" to "FF"
+ var dec2hex = [];
+ for (var i = 0; i < 16; i++) {
+ for (var j = 0; j < 16; j++) {
+ dec2hex[i * 16 + j] = i.toString(16) + j.toString(16);
+ }
+ }
+
+ function createMatrixIdentity() {
+ return [
+ [1, 0, 0],
+ [0, 1, 0],
+ [0, 0, 1]
+ ];
+ }
+
+ function matrixMultiply(m1, m2) {
+ var result = createMatrixIdentity();
+
+ for (var x = 0; x < 3; x++) {
+ for (var y = 0; y < 3; y++) {
+ var sum = 0;
+
+ for (var z = 0; z < 3; z++) {
+ sum += m1[x][z] * m2[z][y];
+ }
+
+ result[x][y] = sum;
+ }
+ }
+ return result;
+ }
+
+ function copyState(o1, o2) {
+ o2.fillStyle = o1.fillStyle;
+ o2.lineCap = o1.lineCap;
+ o2.lineJoin = o1.lineJoin;
+ o2.lineWidth = o1.lineWidth;
+ o2.miterLimit = o1.miterLimit;
+ o2.shadowBlur = o1.shadowBlur;
+ o2.shadowColor = o1.shadowColor;
+ o2.shadowOffsetX = o1.shadowOffsetX;
+ o2.shadowOffsetY = o1.shadowOffsetY;
+ o2.strokeStyle = o1.strokeStyle;
+ o2.arcScaleX_ = o1.arcScaleX_;
+ o2.arcScaleY_ = o1.arcScaleY_;
+ }
+
+ function processStyle(styleString) {
+ var str, alpha = 1;
+
+ styleString = String(styleString);
+ if (styleString.substring(0, 3) == "rgb") {
+ var start = styleString.indexOf("(", 3);
+ var end = styleString.indexOf(")", start + 1);
+ var guts = styleString.substring(start + 1, end).split(",");
+
+ str = "#";
+ for (var i = 0; i < 3; i++) {
+ str += dec2hex[Number(guts[i])];
+ }
+
+ if ((guts.length == 4) && (styleString.substr(3, 1) == "a")) {
+ alpha = guts[3];
+ }
+ } else {
+ str = styleString;
+ }
+
+ return [str, alpha];
+ }
+
+ function processLineCap(lineCap) {
+ switch (lineCap) {
+ case "butt":
+ return "flat";
+ case "round":
+ return "round";
+ case "square":
+ default:
+ return "square";
+ }
+ }
+
+ /**
+ * This class implements CanvasRenderingContext2D interface as described by
+ * the WHATWG.
+ * @param {HTMLElement} surfaceElement The element that the 2D context should
+ * be associated with
+ */
+ function CanvasRenderingContext2D_(surfaceElement) {
+ this.m_ = createMatrixIdentity();
+
+ this.mStack_ = [];
+ this.aStack_ = [];
+ this.currentPath_ = [];
+
+ // Canvas context properties
+ this.strokeStyle = "#000";
+ this.fillStyle = "#000";
+
+ this.lineWidth = 1;
+ this.lineJoin = "miter";
+ this.lineCap = "butt";
+ this.miterLimit = Z * 1;
+ this.globalAlpha = 1;
+ this.canvas = surfaceElement;
+
+ var el = surfaceElement.ownerDocument.createElement('div');
+ el.style.width = surfaceElement.clientWidth + 'px';
+ el.style.height = surfaceElement.clientHeight + 'px';
+ el.style.overflow = 'hidden';
+ el.style.position = 'absolute';
+ surfaceElement.appendChild(el);
+
+ this.element_ = el;
+ this.arcScaleX_ = 1;
+ this.arcScaleY_ = 1;
+ };
+
+ var contextPrototype = CanvasRenderingContext2D_.prototype;
+ contextPrototype.clearRect = function() {
+ this.element_.innerHTML = "";
+ this.currentPath_ = [];
+ };
+
+ contextPrototype.beginPath = function() {
+ // TODO: Branch current matrix so that save/restore has no effect
+ // as per safari docs.
+
+ this.currentPath_ = [];
+ };
+
+ contextPrototype.moveTo = function(aX, aY) {
+ this.currentPath_.push({type: "moveTo", x: aX, y: aY});
+ this.currentX_ = aX;
+ this.currentY_ = aY;
+ };
+
+ contextPrototype.lineTo = function(aX, aY) {
+ this.currentPath_.push({type: "lineTo", x: aX, y: aY});
+ this.currentX_ = aX;
+ this.currentY_ = aY;
+ };
+
+ contextPrototype.bezierCurveTo = function(aCP1x, aCP1y,
+ aCP2x, aCP2y,
+ aX, aY) {
+ this.currentPath_.push({type: "bezierCurveTo",
+ cp1x: aCP1x,
+ cp1y: aCP1y,
+ cp2x: aCP2x,
+ cp2y: aCP2y,
+ x: aX,
+ y: aY});
+ this.currentX_ = aX;
+ this.currentY_ = aY;
+ };
+
+ contextPrototype.quadraticCurveTo = function(aCPx, aCPy, aX, aY) {
+ // the following is lifted almost directly from
+ // http://developer.mozilla.org/en/docs/Canvas_tutorial:Drawing_shapes
+ var cp1x = this.currentX_ + 2.0 / 3.0 * (aCPx - this.currentX_);
+ var cp1y = this.currentY_ + 2.0 / 3.0 * (aCPy - this.currentY_);
+ var cp2x = cp1x + (aX - this.currentX_) / 3.0;
+ var cp2y = cp1y + (aY - this.currentY_) / 3.0;
+ this.bezierCurveTo(cp1x, cp1y, cp2x, cp2y, aX, aY);
+ };
+
+ contextPrototype.arc = function(aX, aY, aRadius,
+ aStartAngle, aEndAngle, aClockwise) {
+ aRadius *= Z;
+ var arcType = aClockwise ? "at" : "wa";
+
+ var xStart = aX + (mc(aStartAngle) * aRadius) - Z2;
+ var yStart = aY + (ms(aStartAngle) * aRadius) - Z2;
+
+ var xEnd = aX + (mc(aEndAngle) * aRadius) - Z2;
+ var yEnd = aY + (ms(aEndAngle) * aRadius) - Z2;
+
+ // IE won't render arches drawn counter clockwise if xStart == xEnd.
+ if (xStart == xEnd && !aClockwise) {
+ xStart += 0.125; // Offset xStart by 1/80 of a pixel. Use something
+ // that can be represented in binary
+ }
+
+ this.currentPath_.push({type: arcType,
+ x: aX,
+ y: aY,
+ radius: aRadius,
+ xStart: xStart,
+ yStart: yStart,
+ xEnd: xEnd,
+ yEnd: yEnd});
+
+ };
+
+ contextPrototype.rect = function(aX, aY, aWidth, aHeight) {
+ this.moveTo(aX, aY);
+ this.lineTo(aX + aWidth, aY);
+ this.lineTo(aX + aWidth, aY + aHeight);
+ this.lineTo(aX, aY + aHeight);
+ this.closePath();
+ };
+
+ contextPrototype.strokeRect = function(aX, aY, aWidth, aHeight) {
+ // Will destroy any existing path (same as FF behaviour)
+ this.beginPath();
+ this.moveTo(aX, aY);
+ this.lineTo(aX + aWidth, aY);
+ this.lineTo(aX + aWidth, aY + aHeight);
+ this.lineTo(aX, aY + aHeight);
+ this.closePath();
+ this.stroke();
+ };
+
+ contextPrototype.fillRect = function(aX, aY, aWidth, aHeight) {
+ // Will destroy any existing path (same as FF behaviour)
+ this.beginPath();
+ this.moveTo(aX, aY);
+ this.lineTo(aX + aWidth, aY);
+ this.lineTo(aX + aWidth, aY + aHeight);
+ this.lineTo(aX, aY + aHeight);
+ this.closePath();
+ this.fill();
+ };
+
+ contextPrototype.createLinearGradient = function(aX0, aY0, aX1, aY1) {
+ var gradient = new CanvasGradient_("gradient");
+ return gradient;
+ };
+
+ contextPrototype.createRadialGradient = function(aX0, aY0,
+ aR0, aX1,
+ aY1, aR1) {
+ var gradient = new CanvasGradient_("gradientradial");
+ gradient.radius1_ = aR0;
+ gradient.radius2_ = aR1;
+ gradient.focus_.x = aX0;
+ gradient.focus_.y = aY0;
+ return gradient;
+ };
+
+ contextPrototype.drawImage = function (image, var_args) {
+ var dx, dy, dw, dh, sx, sy, sw, sh;
+
+ // to find the original width we overide the width and height
+ var oldRuntimeWidth = image.runtimeStyle.width;
+ var oldRuntimeHeight = image.runtimeStyle.height;
+ image.runtimeStyle.width = 'auto';
+ image.runtimeStyle.height = 'auto';
+
+ // get the original size
+ var w = image.width;
+ var h = image.height;
+
+ // and remove overides
+ image.runtimeStyle.width = oldRuntimeWidth;
+ image.runtimeStyle.height = oldRuntimeHeight;
+
+ if (arguments.length == 3) {
+ dx = arguments[1];
+ dy = arguments[2];
+ sx = sy = 0;
+ sw = dw = w;
+ sh = dh = h;
+ } else if (arguments.length == 5) {
+ dx = arguments[1];
+ dy = arguments[2];
+ dw = arguments[3];
+ dh = arguments[4];
+ sx = sy = 0;
+ sw = w;
+ sh = h;
+ } else if (arguments.length == 9) {
+ sx = arguments[1];
+ sy = arguments[2];
+ sw = arguments[3];
+ sh = arguments[4];
+ dx = arguments[5];
+ dy = arguments[6];
+ dw = arguments[7];
+ dh = arguments[8];
+ } else {
+ throw "Invalid number of arguments";
+ }
+
+ var d = this.getCoords_(dx, dy);
+
+ var w2 = sw / 2;
+ var h2 = sh / 2;
+
+ var vmlStr = [];
+
+ var W = 10;
+ var H = 10;
+
+ // For some reason that I've now forgotten, using divs didn't work
+ vmlStr.push(' <g_vml_:group',
+ ' coordsize="', Z * W, ',', Z * H, '"',
+ ' coordorigin="0,0"' ,
+ ' style="width:', W, ';height:', H, ';position:absolute;');
+
+ // If filters are necessary (rotation exists), create them
+ // filters are bog-slow, so only create them if abbsolutely necessary
+ // The following check doesn't account for skews (which don't exist
+ // in the canvas spec (yet) anyway.
+
+ if (this.m_[0][0] != 1 || this.m_[0][1]) {
+ var filter = [];
+
+ // Note the 12/21 reversal
+ filter.push("M11='", this.m_[0][0], "',",
+ "M12='", this.m_[1][0], "',",
+ "M21='", this.m_[0][1], "',",
+ "M22='", this.m_[1][1], "',",
+ "Dx='", mr(d.x / Z), "',",
+ "Dy='", mr(d.y / Z), "'");
+
+ // Bounding box calculation (need to minimize displayed area so that
+ // filters don't waste time on unused pixels.
+ var max = d;
+ var c2 = this.getCoords_(dx + dw, dy);
+ var c3 = this.getCoords_(dx, dy + dh);
+ var c4 = this.getCoords_(dx + dw, dy + dh);
+
+ max.x = Math.max(max.x, c2.x, c3.x, c4.x);
+ max.y = Math.max(max.y, c2.y, c3.y, c4.y);
+
+ vmlStr.push("padding:0 ", mr(max.x / Z), "px ", mr(max.y / Z),
+ "px 0;filter:progid:DXImageTransform.Microsoft.Matrix(",
+ filter.join(""), ", sizingmethod='clip');")
+ } else {
+ vmlStr.push("top:", mr(d.y / Z), "px;left:", mr(d.x / Z), "px;")
+ }
+
+ vmlStr.push(' ">' ,
+ '<g_vml_:image src="', image.src, '"',
+ ' style="width:', Z * dw, ';',
+ ' height:', Z * dh, ';"',
+ ' cropleft="', sx / w, '"',
+ ' croptop="', sy / h, '"',
+ ' cropright="', (w - sx - sw) / w, '"',
+ ' cropbottom="', (h - sy - sh) / h, '"',
+ ' />',
+ '</g_vml_:group>');
+
+ this.element_.insertAdjacentHTML("BeforeEnd",
+ vmlStr.join(""));
+ };
+
+ contextPrototype.stroke = function(aFill) {
+ var lineStr = [];
+ var lineOpen = false;
+ var a = processStyle(aFill ? this.fillStyle : this.strokeStyle);
+ var color = a[0];
+ var opacity = a[1] * this.globalAlpha;
+
+ var W = 10;
+ var H = 10;
+
+ lineStr.push('<g_vml_:shape',
+ ' fillcolor="', color, '"',
+ ' filled="', Boolean(aFill), '"',
+ ' style="position:absolute;width:', W, ';height:', H, ';"',
+ ' coordorigin="0 0" coordsize="', Z * W, ' ', Z * H, '"',
+ ' stroked="', !aFill, '"',
+ ' strokeweight="', this.lineWidth, '"',
+ ' strokecolor="', color, '"',
+ ' path="');
+
+ var newSeq = false;
+ var min = {x: null, y: null};
+ var max = {x: null, y: null};
+
+ for (var i = 0; i < this.currentPath_.length; i++) {
+ var p = this.currentPath_[i];
+
+ if (p.type == "moveTo") {
+ lineStr.push(" m ");
+ var c = this.getCoords_(p.x, p.y);
+ lineStr.push(mr(c.x), ",", mr(c.y));
+ } else if (p.type == "lineTo") {
+ lineStr.push(" l ");
+ var c = this.getCoords_(p.x, p.y);
+ lineStr.push(mr(c.x), ",", mr(c.y));
+ } else if (p.type == "close") {
+ lineStr.push(" x ");
+ } else if (p.type == "bezierCurveTo") {
+ lineStr.push(" c ");
+ var c = this.getCoords_(p.x, p.y);
+ var c1 = this.getCoords_(p.cp1x, p.cp1y);
+ var c2 = this.getCoords_(p.cp2x, p.cp2y);
+ lineStr.push(mr(c1.x), ",", mr(c1.y), ",",
+ mr(c2.x), ",", mr(c2.y), ",",
+ mr(c.x), ",", mr(c.y));
+ } else if (p.type == "at" || p.type == "wa") {
+ lineStr.push(" ", p.type, " ");
+ var c = this.getCoords_(p.x, p.y);
+ var cStart = this.getCoords_(p.xStart, p.yStart);
+ var cEnd = this.getCoords_(p.xEnd, p.yEnd);
+
+ lineStr.push(mr(c.x - this.arcScaleX_ * p.radius), ",",
+ mr(c.y - this.arcScaleY_ * p.radius), " ",
+ mr(c.x + this.arcScaleX_ * p.radius), ",",
+ mr(c.y + this.arcScaleY_ * p.radius), " ",
+ mr(cStart.x), ",", mr(cStart.y), " ",
+ mr(cEnd.x), ",", mr(cEnd.y));
+ }
+
+
+ // TODO: Following is broken for curves due to
+ // move to proper paths.
+
+ // Figure out dimensions so we can do gradient fills
+ // properly
+ if(c) {
+ if (min.x == null || c.x < min.x) {
+ min.x = c.x;
+ }
+ if (max.x == null || c.x > max.x) {
+ max.x = c.x;
+ }
+ if (min.y == null || c.y < min.y) {
+ min.y = c.y;
+ }
+ if (max.y == null || c.y > max.y) {
+ max.y = c.y;
+ }
+ }
+ }
+ lineStr.push(' ">');
+
+ if (typeof this.fillStyle == "object") {
+ var focus = {x: "50%", y: "50%"};
+ var width = (max.x - min.x);
+ var height = (max.y - min.y);
+ var dimension = (width > height) ? width : height;
+
+ focus.x = mr((this.fillStyle.focus_.x / width) * 100 + 50) + "%";
+ focus.y = mr((this.fillStyle.focus_.y / height) * 100 + 50) + "%";
+
+ var colors = [];
+
+ // inside radius (%)
+ if (this.fillStyle.type_ == "gradientradial") {
+ var inside = (this.fillStyle.radius1_ / dimension * 100);
+
+ // percentage that outside radius exceeds inside radius
+ var expansion = (this.fillStyle.radius2_ / dimension * 100) - inside;
+ } else {
+ var inside = 0;
+ var expansion = 100;
+ }
+
+ var insidecolor = {offset: null, color: null};
+ var outsidecolor = {offset: null, color: null};
+
+ // We need to sort 'colors' by percentage, from 0 > 100 otherwise ie
+ // won't interpret it correctly
+ this.fillStyle.colors_.sort(function (cs1, cs2) {
+ return cs1.offset - cs2.offset;
+ });
+
+ for (var i = 0; i < this.fillStyle.colors_.length; i++) {
+ var fs = this.fillStyle.colors_[i];
+
+ colors.push( (fs.offset * expansion) + inside, "% ", fs.color, ",");
+
+ if (fs.offset > insidecolor.offset || insidecolor.offset == null) {
+ insidecolor.offset = fs.offset;
+ insidecolor.color = fs.color;
+ }
+
+ if (fs.offset < outsidecolor.offset || outsidecolor.offset == null) {
+ outsidecolor.offset = fs.offset;
+ outsidecolor.color = fs.color;
+ }
+ }
+ colors.pop();
+
+ lineStr.push('<g_vml_:fill',
+ ' color="', outsidecolor.color, '"',
+ ' color2="', insidecolor.color, '"',
+ ' type="', this.fillStyle.type_, '"',
+ ' focusposition="', focus.x, ', ', focus.y, '"',
+ ' colors="', colors.join(""), '"',
+ ' opacity="', opacity, '" />');
+ } else if (aFill) {
+ lineStr.push('<g_vml_:fill color="', color, '" opacity="', opacity, '" />');
+ } else {
+ lineStr.push(
+ '<g_vml_:stroke',
+ ' opacity="', opacity,'"',
+ ' joinstyle="', this.lineJoin, '"',
+ ' miterlimit="', this.miterLimit, '"',
+ ' endcap="', processLineCap(this.lineCap) ,'"',
+ ' weight="', this.lineWidth, 'px"',
+ ' color="', color,'" />'
+ );
+ }
+
+ lineStr.push("</g_vml_:shape>");
+
+ this.element_.insertAdjacentHTML("beforeEnd", lineStr.join(""));
+
+ this.currentPath_ = [];
+ };
+
+ contextPrototype.fill = function() {
+ this.stroke(true);
+ }
+
+ contextPrototype.closePath = function() {
+ this.currentPath_.push({type: "close"});
+ };
+
+ /**
+ * @private
+ */
+ contextPrototype.getCoords_ = function(aX, aY) {
+ return {
+ x: Z * (aX * this.m_[0][0] + aY * this.m_[1][0] + this.m_[2][0]) - Z2,
+ y: Z * (aX * this.m_[0][1] + aY * this.m_[1][1] + this.m_[2][1]) - Z2
+ }
+ };
+
+ contextPrototype.save = function() {
+ var o = {};
+ copyState(this, o);
+ this.aStack_.push(o);
+ this.mStack_.push(this.m_);
+ this.m_ = matrixMultiply(createMatrixIdentity(), this.m_);
+ };
+
+ contextPrototype.restore = function() {
+ copyState(this.aStack_.pop(), this);
+ this.m_ = this.mStack_.pop();
+ };
+
+ contextPrototype.translate = function(aX, aY) {
+ var m1 = [
+ [1, 0, 0],
+ [0, 1, 0],
+ [aX, aY, 1]
+ ];
+
+ this.m_ = matrixMultiply(m1, this.m_);
+ };
+
+ contextPrototype.rotate = function(aRot) {
+ var c = mc(aRot);
+ var s = ms(aRot);
+
+ var m1 = [
+ [c, s, 0],
+ [-s, c, 0],
+ [0, 0, 1]
+ ];
+
+ this.m_ = matrixMultiply(m1, this.m_);
+ };
+
+ contextPrototype.scale = function(aX, aY) {
+ this.arcScaleX_ *= aX;
+ this.arcScaleY_ *= aY;
+ var m1 = [
+ [aX, 0, 0],
+ [0, aY, 0],
+ [0, 0, 1]
+ ];
+
+ this.m_ = matrixMultiply(m1, this.m_);
+ };
+
+ /******** STUBS ********/
+ contextPrototype.clip = function() {
+ // TODO: Implement
+ };
+
+ contextPrototype.arcTo = function() {
+ // TODO: Implement
+ };
+
+ contextPrototype.createPattern = function() {
+ return new CanvasPattern_;
+ };
+
+ // Gradient / Pattern Stubs
+ function CanvasGradient_(aType) {
+ this.type_ = aType;
+ this.radius1_ = 0;
+ this.radius2_ = 0;
+ this.colors_ = [];
+ this.focus_ = {x: 0, y: 0};
+ }
+
+ CanvasGradient_.prototype.addColorStop = function(aOffset, aColor) {
+ aColor = processStyle(aColor);
+ this.colors_.push({offset: 1-aOffset, color: aColor});
+ };
+
+ function CanvasPattern_() {}
+
+ // set up externs
+ G_vmlCanvasManager = G_vmlCanvasManager_;
+ CanvasRenderingContext2D = CanvasRenderingContext2D_;
+ CanvasGradient = CanvasGradient_;
+ CanvasPattern = CanvasPattern_;
+
+})();
+
+} // if
diff --git a/site/app/webroot/js/simile/timeplot/lib/firebug/errorIcon.png b/site/app/webroot/js/simile/timeplot/lib/firebug/errorIcon.png
new file mode 100755
index 0000000..2d75261
--- /dev/null
+++ b/site/app/webroot/js/simile/timeplot/lib/firebug/errorIcon.png
Binary files differ
diff --git a/site/app/webroot/js/simile/timeplot/lib/firebug/firebug.css b/site/app/webroot/js/simile/timeplot/lib/firebug/firebug.css
new file mode 100755
index 0000000..1f041c4
--- /dev/null
+++ b/site/app/webroot/js/simile/timeplot/lib/firebug/firebug.css
@@ -0,0 +1,209 @@
+
+html, body {
+ margin: 0;
+ background: #FFFFFF;
+ font-family: Lucida Grande, Tahoma, sans-serif;
+ font-size: 11px;
+ overflow: hidden;
+}
+
+a {
+ text-decoration: none;
+}
+
+a:hover {
+ text-decoration: underline;
+}
+
+.toolbar {
+ height: 14px;
+ border-top: 1px solid ThreeDHighlight;
+ border-bottom: 1px solid ThreeDShadow;
+ padding: 2px 6px;
+ background: ThreeDFace;
+}
+
+.toolbarRight {
+ position: absolute;
+ top: 4px;
+ right: 6px;
+}
+
+#log {
+ overflow: auto;
+ position: absolute;
+ left: 0;
+ width: 100%;
+}
+
+#commandLine {
+ position: absolute;
+ bottom: 0;
+ left: 0;
+ width: 100%;
+ height: 18px;
+ border: none;
+ border-top: 1px solid ThreeDShadow;
+}
+
+/************************************************************************************************/
+
+.logRow {
+ position: relative;
+ border-bottom: 1px solid #D7D7D7;
+ padding: 2px 4px 1px 6px;
+ background-color: #FFFFFF;
+}
+
+.logRow-command {
+ font-family: Monaco, monospace;
+ color: blue;
+}
+
+.objectBox-null {
+ padding: 0 2px;
+ border: 1px solid #666666;
+ background-color: #888888;
+ color: #FFFFFF;
+}
+
+.objectBox-string {
+ font-family: Monaco, monospace;
+ color: red;
+ white-space: pre;
+}
+
+.objectBox-number {
+ color: #000088;
+}
+
+.objectBox-function {
+ font-family: Monaco, monospace;
+ color: DarkGreen;
+}
+
+.objectBox-object {
+ color: DarkGreen;
+ font-weight: bold;
+}
+
+/************************************************************************************************/
+
+.logRow-info,
+.logRow-error,
+.logRow-warning {
+ background: #FFFFFF no-repeat 2px 2px;
+ padding-left: 20px;
+ padding-bottom: 3px;
+}
+
+.logRow-info {
+ background-image: url(infoIcon.png);
+}
+
+.logRow-warning {
+ background-color: cyan;
+ background-image: url(warningIcon.png);
+}
+
+.logRow-error {
+ background-color: LightYellow;
+ background-image: url(errorIcon.png);
+}
+
+.errorMessage {
+ vertical-align: top;
+ color: #FF0000;
+}
+
+.objectBox-sourceLink {
+ position: absolute;
+ right: 4px;
+ top: 2px;
+ padding-left: 8px;
+ font-family: Lucida Grande, sans-serif;
+ font-weight: bold;
+ color: #0000FF;
+}
+
+/************************************************************************************************/
+
+.logRow-group {
+ background: #EEEEEE;
+ border-bottom: none;
+}
+
+.logGroup {
+ background: #EEEEEE;
+}
+
+.logGroupBox {
+ margin-left: 24px;
+ border-top: 1px solid #D7D7D7;
+ border-left: 1px solid #D7D7D7;
+}
+
+/************************************************************************************************/
+
+.selectorTag,
+.selectorId,
+.selectorClass {
+ font-family: Monaco, monospace;
+ font-weight: normal;
+}
+
+.selectorTag {
+ color: #0000FF;
+}
+
+.selectorId {
+ color: DarkBlue;
+}
+
+.selectorClass {
+ color: red;
+}
+
+/************************************************************************************************/
+
+.objectBox-element {
+ font-family: Monaco, monospace;
+ color: #000088;
+}
+
+.nodeChildren {
+ margin-left: 16px;
+}
+
+.nodeTag {
+ color: blue;
+}
+
+.nodeValue {
+ color: #FF0000;
+ font-weight: normal;
+}
+
+.nodeText,
+.nodeComment {
+ margin: 0 2px;
+ vertical-align: top;
+}
+
+.nodeText {
+ color: #333333;
+}
+
+.nodeComment {
+ color: DarkGreen;
+}
+
+/************************************************************************************************/
+
+.propertyNameCell {
+ vertical-align: top;
+}
+
+.propertyName {
+ font-weight: bold;
+}
diff --git a/site/app/webroot/js/simile/timeplot/lib/firebug/firebug.html b/site/app/webroot/js/simile/timeplot/lib/firebug/firebug.html
new file mode 100755
index 0000000..861e639
--- /dev/null
+++ b/site/app/webroot/js/simile/timeplot/lib/firebug/firebug.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+
+<head>
+ <title>Firebug</title>
+ <link rel="stylesheet" type="text/css" href="firebug.css">
+</head>
+
+<body>
+ <div id="toolbar" class="toolbar">
+ <a href="#" onclick="parent.console.clear()">Clear</a>
+ <span class="toolbarRight">
+ <a href="#" onclick="parent.console.close()">Close</a>
+ </span>
+ </div>
+ <div id="log"></div>
+ <input type="text" id="commandLine">
+
+ <script>parent.onFirebugReady(document);</script>
+</body>
+</html>
diff --git a/site/app/webroot/js/simile/timeplot/lib/firebug/firebug.js b/site/app/webroot/js/simile/timeplot/lib/firebug/firebug.js
new file mode 100755
index 0000000..eb853b8
--- /dev/null
+++ b/site/app/webroot/js/simile/timeplot/lib/firebug/firebug.js
@@ -0,0 +1,672 @@
+
+if (!("console" in window) || !("firebug" in console)) {
+(function()
+{
+ window.console =
+ {
+ log: function()
+ {
+ logFormatted(arguments, "");
+ },
+
+ debug: function()
+ {
+ logFormatted(arguments, "debug");
+ },
+
+ info: function()
+ {
+ logFormatted(arguments, "info");
+ },
+
+ warn: function()
+ {
+ logFormatted(arguments, "warning");
+ },
+
+ error: function()
+ {
+ logFormatted(arguments, "error");
+ },
+
+ assert: function(truth, message)
+ {
+ if (!truth)
+ {
+ var args = [];
+ for (var i = 1; i < arguments.length; ++i)
+ args.push(arguments[i]);
+
+ logFormatted(args.length ? args : ["Assertion Failure"], "error");
+ throw message ? message : "Assertion Failure";
+ }
+ },
+
+ dir: function(object)
+ {
+ var html = [];
+
+ var pairs = [];
+ for (var name in object)
+ {
+ try
+ {
+ pairs.push([name, object[name]]);
+ }
+ catch (exc)
+ {
+ }
+ }
+
+ pairs.sort(function(a, b) { return a[0] < b[0] ? -1 : 1; });
+
+ html.push('<table>');
+ for (var i = 0; i < pairs.length; ++i)
+ {
+ var name = pairs[i][0], value = pairs[i][1];
+
+ html.push('<tr>',
+ '<td class="propertyNameCell"><span class="propertyName">',
+ escapeHTML(name), '</span></td>', '<td><span class="propertyValue">');
+ appendObject(value, html);
+ html.push('</span></td></tr>');
+ }
+ html.push('</table>');
+
+ logRow(html, "dir");
+ },
+
+ dirxml: function(node)
+ {
+ var html = [];
+
+ appendNode(node, html);
+ logRow(html, "dirxml");
+ },
+
+ group: function()
+ {
+ logRow(arguments, "group", pushGroup);
+ },
+
+ groupEnd: function()
+ {
+ logRow(arguments, "", popGroup);
+ },
+
+ time: function(name)
+ {
+ timeMap[name] = (new Date()).getTime();
+ },
+
+ timeEnd: function(name)
+ {
+ if (name in timeMap)
+ {
+ var delta = (new Date()).getTime() - timeMap[name];
+ logFormatted([name+ ":", delta+"ms"]);
+ delete timeMap[name];
+ }
+ },
+
+ count: function()
+ {
+ this.warn(["count() not supported."]);
+ },
+
+ trace: function()
+ {
+ this.warn(["trace() not supported."]);
+ },
+
+ profile: function()
+ {
+ this.warn(["profile() not supported."]);
+ },
+
+ profileEnd: function()
+ {
+ },
+
+ clear: function()
+ {
+ consoleBody.innerHTML = "";
+ },
+
+ open: function()
+ {
+ toggleConsole(true);
+ },
+
+ close: function()
+ {
+ if (frameVisible)
+ toggleConsole();
+ }
+ };
+
+ // ********************************************************************************************
+
+ var consoleFrame = null;
+ var consoleBody = null;
+ var commandLine = null;
+
+ var frameVisible = false;
+ var messageQueue = [];
+ var groupStack = [];
+ var timeMap = {};
+
+ var clPrefix = ">>> ";
+
+ var isFirefox = navigator.userAgent.indexOf("Firefox") != -1;
+ var isIE = navigator.userAgent.indexOf("MSIE") != -1;
+ var isOpera = navigator.userAgent.indexOf("Opera") != -1;
+ var isSafari = navigator.userAgent.indexOf("AppleWebKit") != -1;
+
+ // ********************************************************************************************
+
+ function toggleConsole(forceOpen)
+ {
+ frameVisible = forceOpen || !frameVisible;
+ if (consoleFrame)
+ consoleFrame.style.visibility = frameVisible ? "visible" : "hidden";
+ else
+ waitForBody();
+ }
+
+ function focusCommandLine()
+ {
+ toggleConsole(true);
+ if (commandLine)
+ commandLine.focus();
+ }
+
+ function waitForBody()
+ {
+ if (document.body)
+ createFrame();
+ else
+ setTimeout(waitForBody, 200);
+ }
+
+ function createFrame()
+ {
+ if (consoleFrame)
+ return;
+
+ window.onFirebugReady = function(doc)
+ {
+ window.onFirebugReady = null;
+
+ var toolbar = doc.getElementById("toolbar");
+ toolbar.onmousedown = onSplitterMouseDown;
+
+ commandLine = doc.getElementById("commandLine");
+ addEvent(commandLine, "keydown", onCommandLineKeyDown);
+
+ addEvent(doc, isIE || isSafari ? "keydown" : "keypress", onKeyDown);
+
+ consoleBody = doc.getElementById("log");
+ layout();
+ flush();
+ }
+
+ var baseURL = getFirebugURL();
+
+ consoleFrame = document.createElement("iframe");
+ consoleFrame.setAttribute("src", baseURL+"/firebug.html");
+ consoleFrame.setAttribute("frameBorder", "0");
+ consoleFrame.style.visibility = (frameVisible ? "visible" : "hidden");
+ consoleFrame.style.zIndex = "2147483647";
+ consoleFrame.style.position = "fixed";
+ consoleFrame.style.width = "100%";
+ consoleFrame.style.left = "0";
+ consoleFrame.style.bottom = "0";
+ consoleFrame.style.height = "200px";
+ document.body.appendChild(consoleFrame);
+ }
+
+ function getFirebugURL()
+ {
+ var scripts = document.getElementsByTagName("script");
+ for (var i = 0; i < scripts.length; ++i)
+ {
+ if (scripts[i].src.indexOf("firebug.js") != -1)
+ {
+ var lastSlash = scripts[i].src.lastIndexOf("/");
+ return scripts[i].src.substr(0, lastSlash);
+ }
+ }
+ }
+
+ function evalCommandLine()
+ {
+ var text = commandLine.value;
+ commandLine.value = "";
+
+ logRow([clPrefix, text], "command");
+
+ var value;
+ try
+ {
+ value = eval(text);
+ }
+ catch (exc)
+ {
+ }
+
+ console.log(value);
+ }
+
+ function layout()
+ {
+ var toolbar = consoleBody.ownerDocument.getElementById("toolbar");
+ var height = consoleFrame.offsetHeight - (toolbar.offsetHeight + commandLine.offsetHeight);
+ consoleBody.style.top = toolbar.offsetHeight + "px";
+ consoleBody.style.height = height + "px";
+
+ commandLine.style.top = (consoleFrame.offsetHeight - commandLine.offsetHeight) + "px";
+ }
+
+ function logRow(message, className, handler)
+ {
+ if (consoleBody)
+ writeMessage(message, className, handler);
+ else
+ {
+ messageQueue.push([message, className, handler]);
+ waitForBody();
+ }
+ }
+
+ function flush()
+ {
+ var queue = messageQueue;
+ messageQueue = [];
+
+ for (var i = 0; i < queue.length; ++i)
+ writeMessage(queue[i][0], queue[i][1], queue[i][2]);
+ }
+
+ function writeMessage(message, className, handler)
+ {
+ var isScrolledToBottom =
+ consoleBody.scrollTop + consoleBody.offsetHeight >= consoleBody.scrollHeight;
+
+ if (!handler)
+ handler = writeRow;
+
+ handler(message, className);
+
+ if (isScrolledToBottom)
+ consoleBody.scrollTop = consoleBody.scrollHeight - consoleBody.offsetHeight;
+ }
+
+ function appendRow(row)
+ {
+ var container = groupStack.length ? groupStack[groupStack.length-1] : consoleBody;
+ container.appendChild(row);
+ }
+
+ function writeRow(message, className)
+ {
+ var row = consoleBody.ownerDocument.createElement("div");
+ row.className = "logRow" + (className ? " logRow-"+className : "");
+ row.innerHTML = message.join("");
+ appendRow(row);
+ }
+
+ function pushGroup(message, className)
+ {
+ logFormatted(message, className);
+
+ var groupRow = consoleBody.ownerDocument.createElement("div");
+ groupRow.className = "logGroup";
+ var groupRowBox = consoleBody.ownerDocument.createElement("div");
+ groupRowBox.className = "logGroupBox";
+ groupRow.appendChild(groupRowBox);
+ appendRow(groupRowBox);
+ groupStack.push(groupRowBox);
+ }
+
+ function popGroup()
+ {
+ groupStack.pop();
+ }
+
+ // ********************************************************************************************
+
+ function logFormatted(objects, className)
+ {
+ var html = [];
+
+ var format = objects[0];
+ var objIndex = 0;
+
+ if (typeof(format) != "string")
+ {
+ format = "";
+ objIndex = -1;
+ }
+
+ var parts = parseFormat(format);
+ for (var i = 0; i < parts.length; ++i)
+ {
+ var part = parts[i];
+ if (part && typeof(part) == "object")
+ {
+ var object = objects[++objIndex];
+ part.appender(object, html);
+ }
+ else
+ appendText(part, html);
+ }
+
+ for (var i = objIndex+1; i < objects.length; ++i)
+ {
+ appendText(" ", html);
+
+ var object = objects[i];
+ if (typeof(object) == "string")
+ appendText(object, html);
+ else
+ appendObject(object, html);
+ }
+
+ logRow(html, className);
+ }
+
+ function parseFormat(format)
+ {
+ var parts = [];
+
+ var reg = /((^%|[^\\]%)(\d+)?(\.)([a-zA-Z]))|((^%|[^\\]%)([a-zA-Z]))/;
+ var appenderMap = {s: appendText, d: appendInteger, i: appendInteger, f: appendFloat};
+
+ for (var m = reg.exec(format); m; m = reg.exec(format))
+ {
+ var type = m[8] ? m[8] : m[5];
+ var appender = type in appenderMap ? appenderMap[type] : appendObject;
+ var precision = m[3] ? parseInt(m[3]) : (m[4] == "." ? -1 : 0);
+
+ parts.push(format.substr(0, m[0][0] == "%" ? m.index : m.index+1));
+ parts.push({appender: appender, precision: precision});
+
+ format = format.substr(m.index+m[0].length);
+ }
+
+ parts.push(format);
+
+ return parts;
+ }
+
+ function escapeHTML(value)
+ {
+ function replaceChars(ch)
+ {
+ switch (ch)
+ {
+ case "<":
+ return "&lt;";
+ case ">":
+ return "&gt;";
+ case "&":
+ return "&amp;";
+ case "'":
+ return "&#39;";
+ case '"':
+ return "&quot;";
+ }
+ return "?";
+ };
+ return String(value).replace(/[<>&"']/g, replaceChars);
+ }
+
+ function objectToString(object)
+ {
+ try
+ {
+ return object+"";
+ }
+ catch (exc)
+ {
+ return null;
+ }
+ }
+
+ // ********************************************************************************************
+
+ function appendText(object, html)
+ {
+ html.push(escapeHTML(objectToString(object)));
+ }
+
+ function appendNull(object, html)
+ {
+ html.push('<span class="objectBox-null">', escapeHTML(objectToString(object)), '</span>');
+ }
+
+ function appendString(object, html)
+ {
+ html.push('<span class="objectBox-string">&quot;', escapeHTML(objectToString(object)),
+ '&quot;</span>');
+ }
+
+ function appendInteger(object, html)
+ {
+ html.push('<span class="objectBox-number">', escapeHTML(objectToString(object)), '</span>');
+ }
+
+ function appendFloat(object, html)
+ {
+ html.push('<span class="objectBox-number">', escapeHTML(objectToString(object)), '</span>');
+ }
+
+ function appendFunction(object, html)
+ {
+ var reName = /function ?(.*?)\(/;
+ var m = reName.exec(objectToString(object));
+ var name = m ? m[1] : "function";
+ html.push('<span class="objectBox-function">', escapeHTML(name), '()</span>');
+ }
+
+ function appendObject(object, html)
+ {
+ try
+ {
+ if (object == undefined)
+ appendNull("undefined", html);
+ else if (object == null)
+ appendNull("null", html);
+ else if (typeof object == "string")
+ appendString(object, html);
+ else if (typeof object == "number")
+ appendInteger(object, html);
+ else if (typeof object == "function")
+ appendFunction(object, html);
+ else if (object.nodeType == 1)
+ appendSelector(object, html);
+ else if (typeof object == "object")
+ appendObjectFormatted(object, html);
+ else
+ appendText(object, html);
+ }
+ catch (exc)
+ {
+ }
+ }
+
+ function appendObjectFormatted(object, html)
+ {
+ var text = objectToString(object);
+ var reObject = /\[object (.*?)\]/;
+
+ var m = reObject.exec(text);
+ html.push('<span class="objectBox-object">', m ? m[1] : text, '</span>')
+ }
+
+ function appendSelector(object, html)
+ {
+ html.push('<span class="objectBox-selector">');
+
+ html.push('<span class="selectorTag">', escapeHTML(object.nodeName.toLowerCase()), '</span>');
+ if (object.id)
+ html.push('<span class="selectorId">#', escapeHTML(object.id), '</span>');
+ if (object.className)
+ html.push('<span class="selectorClass">.', escapeHTML(object.className), '</span>');
+
+ html.push('</span>');
+ }
+
+ function appendNode(node, html)
+ {
+ if (node.nodeType == 1)
+ {
+ html.push(
+ '<div class="objectBox-element">',
+ '&lt;<span class="nodeTag">', node.nodeName.toLowerCase(), '</span>');
+
+ for (var i = 0; i < node.attributes.length; ++i)
+ {
+ var attr = node.attributes[i];
+ if (!attr.specified)
+ continue;
+
+ html.push('&nbsp;<span class="nodeName">', attr.nodeName.toLowerCase(),
+ '</span>=&quot;<span class="nodeValue">', escapeHTML(attr.nodeValue),
+ '</span>&quot;')
+ }
+
+ if (node.firstChild)
+ {
+ html.push('&gt;</div><div class="nodeChildren">');
+
+ for (var child = node.firstChild; child; child = child.nextSibling)
+ appendNode(child, html);
+
+ html.push('</div><div class="objectBox-element">&lt;/<span class="nodeTag">',
+ node.nodeName.toLowerCase(), '&gt;</span></div>');
+ }
+ else
+ html.push('/&gt;</div>');
+ }
+ else if (node.nodeType == 3)
+ {
+ html.push('<div class="nodeText">', escapeHTML(node.nodeValue),
+ '</div>');
+ }
+ }
+
+ // ********************************************************************************************
+
+ function addEvent(object, name, handler)
+ {
+ if (document.all)
+ object.attachEvent("on"+name, handler);
+ else
+ object.addEventListener(name, handler, false);
+ }
+
+ function removeEvent(object, name, handler)
+ {
+ if (document.all)
+ object.detachEvent("on"+name, handler);
+ else
+ object.removeEventListener(name, handler, false);
+ }
+
+ function cancelEvent(event)
+ {
+ if (document.all)
+ event.cancelBubble = true;
+ else
+ event.stopPropagation();
+ }
+
+ function onError(msg, href, lineNo)
+ {
+ var html = [];
+
+ var lastSlash = href.lastIndexOf("/");
+ var fileName = lastSlash == -1 ? href : href.substr(lastSlash+1);
+
+ html.push(
+ '<span class="errorMessage">', msg, '</span>',
+ '<div class="objectBox-sourceLink">', fileName, ' (line ', lineNo, ')</div>'
+ );
+
+ logRow(html, "error");
+ };
+
+ function onKeyDown(event)
+ {
+ if (event.keyCode == 123)
+ toggleConsole();
+ else if ((event.keyCode == 108 || event.keyCode == 76) && event.shiftKey
+ && (event.metaKey || event.ctrlKey))
+ focusCommandLine();
+ else
+ return;
+
+ cancelEvent(event);
+ }
+
+ function onSplitterMouseDown(event)
+ {
+ if (isSafari || isOpera)
+ return;
+
+ addEvent(document, "mousemove", onSplitterMouseMove);
+ addEvent(document, "mouseup", onSplitterMouseUp);
+
+ for (var i = 0; i < frames.length; ++i)
+ {
+ addEvent(frames[i].document, "mousemove", onSplitterMouseMove);
+ addEvent(frames[i].document, "mouseup", onSplitterMouseUp);
+ }
+ }
+
+ function onSplitterMouseMove(event)
+ {
+ var win = document.all
+ ? event.srcElement.ownerDocument.parentWindow
+ : event.target.ownerDocument.defaultView;
+
+ var clientY = event.clientY;
+ if (win != win.parent)
+ clientY += win.frameElement ? win.frameElement.offsetTop : 0;
+
+ var height = consoleFrame.offsetTop + consoleFrame.clientHeight;
+ var y = height - clientY;
+
+ consoleFrame.style.height = y + "px";
+ layout();
+ }
+
+ function onSplitterMouseUp(event)
+ {
+ removeEvent(document, "mousemove", onSplitterMouseMove);
+ removeEvent(document, "mouseup", onSplitterMouseUp);
+
+ for (var i = 0; i < frames.length; ++i)
+ {
+ removeEvent(frames[i].document, "mousemove", onSplitterMouseMove);
+ removeEvent(frames[i].document, "mouseup", onSplitterMouseUp);
+ }
+ }
+
+ function onCommandLineKeyDown(event)
+ {
+ if (event.keyCode == 13)
+ evalCommandLine();
+ else if (event.keyCode == 27)
+ commandLine.value = "";
+ }
+
+ window.onerror = onError;
+ addEvent(document, isIE || isSafari ? "keydown" : "keypress", onKeyDown);
+
+ if (document.documentElement.getAttribute("debug") == "true")
+ toggleConsole(true);
+})();
+}
diff --git a/site/app/webroot/js/simile/timeplot/lib/firebug/firebugx.js b/site/app/webroot/js/simile/timeplot/lib/firebug/firebugx.js
new file mode 100755
index 0000000..5a467fc
--- /dev/null
+++ b/site/app/webroot/js/simile/timeplot/lib/firebug/firebugx.js
@@ -0,0 +1,10 @@
+
+if (!("console" in window) || !("firebug" in console))
+{
+ var names = ["log", "debug", "info", "warn", "error", "assert", "dir", "dirxml",
+ "group", "groupEnd", "time", "timeEnd", "count", "trace", "profile", "profileEnd"];
+
+ window.console = {};
+ for (var i = 0; i < names.length; ++i)
+ window.console[names[i]] = function() {}
+} \ No newline at end of file
diff --git a/site/app/webroot/js/simile/timeplot/lib/firebug/infoIcon.png b/site/app/webroot/js/simile/timeplot/lib/firebug/infoIcon.png
new file mode 100755
index 0000000..da1e533
--- /dev/null
+++ b/site/app/webroot/js/simile/timeplot/lib/firebug/infoIcon.png
Binary files differ
diff --git a/site/app/webroot/js/simile/timeplot/lib/firebug/warningIcon.png b/site/app/webroot/js/simile/timeplot/lib/firebug/warningIcon.png
new file mode 100755
index 0000000..de51084
--- /dev/null
+++ b/site/app/webroot/js/simile/timeplot/lib/firebug/warningIcon.png
Binary files differ
diff --git a/site/app/webroot/js/simile/timeplot/locales/en/locale.js b/site/app/webroot/js/simile/timeplot/locales/en/locale.js
new file mode 100755
index 0000000..e69de29
--- /dev/null
+++ b/site/app/webroot/js/simile/timeplot/locales/en/locale.js
diff --git a/site/app/webroot/js/simile/timeplot/scripts/color.js b/site/app/webroot/js/simile/timeplot/scripts/color.js
new file mode 100755
index 0000000..31015be
--- /dev/null
+++ b/site/app/webroot/js/simile/timeplot/scripts/color.js
@@ -0,0 +1,152 @@
+/**
+ * Color
+ *
+ * @fileOverview Color
+ * @name Color
+ */
+
+/*
+ * Inspired by Plotr
+ * Copyright 2007 (c) Bas Wenneker <sabmann[a]gmail[d]com>
+ * For use under the BSD license. <http://www.solutoire.com/plotr>
+ */
+
+/**
+ * Create a Color object that can be used to manipulate colors programmatically.
+ */
+Timeplot.Color = function(color) {
+ this._fromHex(color);
+};
+
+Timeplot.Color.prototype = {
+
+ /**
+ * Sets the RGB values of this coor
+ *
+ * @param {Number} r,g,b Red green and blue values (between 0 and 255)
+ */
+ set: function (r,g,b,a) {
+ this.r = r;
+ this.g = g;
+ this.b = b;
+ this.a = (a) ? a : 1.0;
+ return this.check();
+ },
+
+ /**
+ * Set the color transparency
+ *
+ * @param {float} a Transparency value, between 0.0 (fully transparent) and 1.0 (fully opaque).
+ */
+ transparency: function(a) {
+ this.a = a;
+ return this.check();
+ },
+
+ /**
+ * Lightens the color.
+ *
+ * @param {integer} level Level to lighten the color with.
+ */
+ lighten: function(level) {
+ var color = new Timeplot.Color();
+ return color.set(
+ this.r += parseInt(level, 10),
+ this.g += parseInt(level, 10),
+ this.b += parseInt(level, 10)
+ );
+ },
+
+ /**
+ * Darkens the color.
+ *
+ * @param {integer} level Level to darken the color with.
+ */
+ darken: function(level){
+ var color = new Timeplot.Color();
+ return color.set(
+ this.r -= parseInt(level, 10),
+ this.g -= parseInt(level, 10),
+ this.b -= parseInt(level, 10)
+ );
+ },
+
+ /**
+ * Checks and validates if the hex values r, g and b are
+ * between 0 and 255.
+ */
+ check: function() {
+ if (this.r > 255) {
+ this.r = 255;
+ } else if (this.r < 0){
+ this.r = 0;
+ }
+ if (this.g > 255) {
+ this.g = 255;
+ } else if (this.g < 0) {
+ this.g = 0;
+ }
+ if (this.b > 255){
+ this.b = 255;
+ } else if (this.b < 0){
+ this.b = 0;
+ }
+ if (this.a > 1.0){
+ this.a = 1.0;
+ } else if (this.a < 0.0){
+ this.a = 0.0;
+ }
+ return this;
+ },
+
+ /**
+ * Returns a string representation of this color.
+ *
+ * @param {float} alpha (optional) Transparency value, between 0.0 (fully transparent) and 1.0 (fully opaque).
+ */
+ toString: function(alpha) {
+ var a = (alpha) ? alpha : ((this.a) ? this.a : 1.0);
+ return 'rgba(' + this.r + ',' + this.g + ',' + this.b + ',' + a + ')';
+ },
+
+ /**
+ * Returns the hexadecimal representation of this color (without the alpha channel as hex colors don't support it)
+ */
+ toHexString: function() {
+ return "#" + this._toHex(this.r) + this._toHex(this.g) + this._toHex(this.b);
+ },
+
+ /*
+ * Parses and stores the hex values of the input color string.
+ *
+ * @param {String} color Hex or rgb() css string.
+ */
+ _fromHex: function(color) {
+ if(/^#?([\da-f]{3}|[\da-f]{6})$/i.test(color)){
+ color = color.replace(/^#/, '').replace(/^([\da-f])([\da-f])([\da-f])$/i, "$1$1$2$2$3$3");
+ this.r = parseInt(color.substr(0,2), 16);
+ this.g = parseInt(color.substr(2,2), 16);
+ this.b = parseInt(color.substr(4,2), 16);
+ } else if(/^rgb *\( *\d{0,3} *, *\d{0,3} *, *\d{0,3} *\)$/i.test(color)){
+ color = color.match(/^rgb *\( *(\d{0,3}) *, *(\d{0,3}) *, *(\d{0,3}) *\)$/i);
+ this.r = parseInt(color[1], 10);
+ this.g = parseInt(color[2], 10);
+ this.b = parseInt(color[3], 10);
+ }
+ this.a = 1.0;
+ return this.check();
+ },
+
+ /*
+ * Returns an hexadecimal representation of a 8 bit integer
+ */
+ _toHex: function(dec) {
+ var hex = "0123456789ABCDEF"
+ if (dec < 0) return "00";
+ if (dec > 255) return "FF";
+ var i = Math.floor(dec / 16);
+ var j = dec % 16;
+ return hex.charAt(i) + hex.charAt(j);
+ }
+
+}; \ No newline at end of file
diff --git a/site/app/webroot/js/simile/timeplot/scripts/geometry.js b/site/app/webroot/js/simile/timeplot/scripts/geometry.js
new file mode 100755
index 0000000..25725bf
--- /dev/null
+++ b/site/app/webroot/js/simile/timeplot/scripts/geometry.js
@@ -0,0 +1,861 @@
+/**
+ * Geometries
+ *
+ * @fileOverview Geometries
+ * @name Geometries
+ */
+
+/**
+ * This is the constructor for the default value geometry.
+ * A value geometry is what regulates mapping of the plot values to the screen y coordinate.
+ * If two plots share the same value geometry, they will be drawn using the same scale.
+ * If "min" and "max" parameters are not set, the geometry will stretch itself automatically
+ * so that the entire plot will be drawn without overflowing. The stretching happens also
+ * when a geometry is shared between multiple plots, the one with the biggest range will
+ * win over the others.
+ *
+ * @constructor
+ */
+Timeplot.DefaultValueGeometry = function(params) {
+ if (!params) params = {};
+ this._id = ("id" in params) ? params.id : "g" + Math.round(Math.random() * 1000000);
+ this._axisColor = ("axisColor" in params) ? ((typeof params.axisColor == "string") ? new Timeplot.Color(params.axisColor) : params.axisColor) : new Timeplot.Color("#606060"),
+ this._gridColor = ("gridColor" in params) ? ((typeof params.gridColor == "string") ? new Timeplot.Color(params.gridColor) : params.gridColor) : null,
+ this._gridLineWidth = ("gridLineWidth" in params) ? params.gridLineWidth : 0.5;
+ this._axisLabelsPlacement = ("axisLabelsPlacement" in params) ? params.axisLabelsPlacement : "right";
+ this._gridSpacing = ("gridSpacing" in params) ? params.gridStep : 50;
+ this._gridType = ("gridType" in params) ? params.gridType : "short";
+ this._gridShortSize = ("gridShortSize" in params) ? params.gridShortSize : 10;
+ this._minValue = ("min" in params) ? params.min : null;
+ this._maxValue = ("max" in params) ? params.max : null;
+ this._linMap = {
+ direct: function(v) {
+ return v;
+ },
+ inverse: function(y) {
+ return y;
+ }
+ }
+ this._map = this._linMap;
+ this._labels = [];
+ this._grid = [];
+}
+
+Timeplot.DefaultValueGeometry.prototype = {
+
+ /**
+ * Since geometries can be reused across timeplots, we need to call this function
+ * before we can paint using this geometry.
+ */
+ setTimeplot: function(timeplot) {
+ this._timeplot = timeplot;
+ this._canvas = timeplot.getCanvas();
+ this.reset();
+ },
+
+ /**
+ * Called by all the plot layers this geometry is associated with
+ * to update the value range. Unless min/max values are specified
+ * in the parameters, the biggest value range will be used.
+ */
+ setRange: function(range) {
+ if ((this._minValue == null) || ((this._minValue != null) && (range.min < this._minValue))) {
+ this._minValue = range.min;
+ }
+ if ((this._maxValue == null) || ((this._maxValue != null) && (range.max * 1.05 > this._maxValue))) {
+ this._maxValue = range.max * 1.05; // get a little more head room to avoid hitting the ceiling
+ }
+
+ this._updateMappedValues();
+
+ if (!(this._minValue == 0 && this._maxValue == 0)) {
+ this._grid = this._calculateGrid();
+ }
+ },
+
+ /**
+ * Called after changing ranges or canvas size to reset the grid values
+ */
+ reset: function() {
+ this._clearLabels();
+ this._updateMappedValues();
+ this._grid = this._calculateGrid();
+ },
+
+ /**
+ * Map the given value to a y screen coordinate.
+ */
+ toScreen: function(value) {
+ if (this._canvas && this._maxValue) {
+ var v = value - this._minValue;
+ return this._canvas.height * (this._map.direct(v)) / this._mappedRange;
+ } else {
+ return -50;
+ }
+ },
+
+ /**
+ * Map the given y screen coordinate to a value
+ */
+ fromScreen: function(y) {
+ if (this._canvas) {
+ return this._map.inverse(this._mappedRange * y / this._canvas.height) + this._minValue;
+ } else {
+ return 0;
+ }
+ },
+
+ /**
+ * Each geometry is also a painter and paints the value grid and grid labels.
+ */
+ paint: function() {
+ if (this._timeplot) {
+ var ctx = this._canvas.getContext('2d');
+
+ ctx.lineJoin = 'miter';
+
+ // paint grid
+ if (this._gridColor) {
+ var gridGradient = ctx.createLinearGradient(0,0,0,this._canvas.height);
+ gridGradient.addColorStop(0, this._gridColor.toHexString());
+ gridGradient.addColorStop(0.3, this._gridColor.toHexString());
+ gridGradient.addColorStop(1, "rgba(255,255,255,0.5)");
+
+ ctx.lineWidth = this._gridLineWidth;
+ ctx.strokeStyle = gridGradient;
+
+ for (var i = 0; i < this._grid.length; i++) {
+ var tick = this._grid[i];
+ var y = Math.floor(tick.y) + 0.5;
+ if (typeof tick.label != "undefined") {
+ if (this._axisLabelsPlacement == "left") {
+ var div = this._timeplot.putText(this._id + "-" + i, tick.label,"timeplot-grid-label",{
+ left: 4,
+ bottom: y + 2,
+ color: this._gridColor.toHexString(),
+ visibility: "hidden"
+ });
+ } else if (this._axisLabelsPlacement == "right") {
+ var div = this._timeplot.putText(this._id + "-" + i, tick.label, "timeplot-grid-label",{
+ right: 4,
+ bottom: y + 2,
+ color: this._gridColor.toHexString(),
+ visibility: "hidden"
+ });
+ }
+ if (y + div.clientHeight < this._canvas.height + 10) {
+ div.style.visibility = "visible"; // avoid the labels that would overflow
+ }
+ }
+
+ // draw grid
+ ctx.beginPath();
+ if (this._gridType == "long" || tick.label == 0) {
+ ctx.moveTo(0, y);
+ ctx.lineTo(this._canvas.width, y);
+ } else if (this._gridType == "short") {
+ if (this._axisLabelsPlacement == "left") {
+ ctx.moveTo(0, y);
+ ctx.lineTo(this._gridShortSize, y);
+ } else if (this._axisLabelsPlacement == "right") {
+ ctx.moveTo(this._canvas.width, y);
+ ctx.lineTo(this._canvas.width - this._gridShortSize, y);
+ }
+ }
+ ctx.stroke();
+ }
+ }
+
+ // paint axis
+ var axisGradient = ctx.createLinearGradient(0,0,0,this._canvas.height);
+ axisGradient.addColorStop(0, this._axisColor.toString());
+ axisGradient.addColorStop(0.5, this._axisColor.toString());
+ axisGradient.addColorStop(1, "rgba(255,255,255,0.5)");
+
+ ctx.lineWidth = 1;
+ ctx.strokeStyle = axisGradient;
+
+ // left axis
+ ctx.beginPath();
+ ctx.moveTo(0,this._canvas.height);
+ ctx.lineTo(0,0);
+ ctx.stroke();
+
+ // right axis
+ ctx.beginPath();
+ ctx.moveTo(this._canvas.width,0);
+ ctx.lineTo(this._canvas.width,this._canvas.height);
+ ctx.stroke();
+ }
+ },
+
+ /**
+ * Removes all the labels that were added by this geometry
+ */
+ _clearLabels: function() {
+ for (var i = 0; i < this._labels.length; i++) {
+ var l = this._labels[i];
+ var parent = l.parentNode;
+ if (parent) parent.removeChild(l);
+ }
+ },
+
+ /*
+ * This function calculates the grid spacing that it will be used
+ * by this geometry to draw the grid in order to reduce clutter.
+ */
+ _calculateGrid: function() {
+ var grid = [];
+
+ if (!this._canvas || this._valueRange == 0) return grid;
+
+ var power = 0;
+ if (this._valueRange > 1) {
+ while (Math.pow(10,power) < this._valueRange) {
+ power++;
+ }
+ power--;
+ } else {
+ while (Math.pow(10,power) > this._valueRange) {
+ power--;
+ }
+ }
+
+ var unit = Math.pow(10,power);
+ var inc = unit;
+ while (true) {
+ var dy = this.toScreen(this._minValue + inc);
+
+ while (dy < this._gridSpacing) {
+ inc += unit;
+ dy = this.toScreen(this._minValue + inc);
+ }
+
+ if (dy > 2 * this._gridSpacing) { // grids are too spaced out
+ unit /= 10;
+ inc = unit;
+ } else {
+ break;
+ }
+ }
+
+ var v = 0;
+ var y = this.toScreen(v);
+ if (this._minValue >= 0) {
+ while (y < this._canvas.height) {
+ if (y > 0) {
+ grid.push({ y: y, label: v });
+ }
+ v += inc;
+ y = this.toScreen(v);
+ }
+ } else if (this._maxValue <= 0) {
+ while (y > 0) {
+ if (y < this._canvas.height) {
+ grid.push({ y: y, label: v });
+ }
+ v -= inc;
+ y = this.toScreen(v);
+ }
+ } else {
+ while (y < this._canvas.height) {
+ if (y > 0) {
+ grid.push({ y: y, label: v });
+ }
+ v += inc;
+ y = this.toScreen(v);
+ }
+ v = -inc;
+ y = this.toScreen(v);
+ while (y > 0) {
+ if (y < this._canvas.height) {
+ grid.push({ y: y, label: v });
+ }
+ v -= inc;
+ y = this.toScreen(v);
+ }
+ }
+
+ return grid;
+ },
+
+ /*
+ * Update the values that are used by the paint function so that
+ * we don't have to calculate them at every repaint.
+ */
+ _updateMappedValues: function() {
+ this._valueRange = Math.abs(this._maxValue - this._minValue);
+ this._mappedRange = this._map.direct(this._valueRange);
+ }
+
+}
+
+// --------------------------------------------------
+
+/**
+ * This is the constructor for a Logarithmic value geometry, which
+ * is useful when plots have values in different magnitudes but
+ * exhibit similar trends and such trends want to be shown on the same
+ * plot (here a cartesian geometry would make the small magnitudes
+ * disappear).
+ *
+ * NOTE: this class extends Timeplot.DefaultValueGeometry and inherits
+ * all of the methods of that class. So refer to that class.
+ *
+ * @constructor
+ */
+Timeplot.LogarithmicValueGeometry = function(params) {
+ Timeplot.DefaultValueGeometry.apply(this, arguments);
+ this._logMap = {
+ direct: function(v) {
+ return Math.log(v + 1) / Math.log(10);
+ },
+ inverse: function(y) {
+ return Math.exp(Math.log(10) * y) - 1;
+ }
+ }
+ this._mode = "log";
+ this._map = this._logMap;
+ this._calculateGrid = this._logarithmicCalculateGrid;
+};
+
+Timeplot.LogarithmicValueGeometry.prototype._linearCalculateGrid = Timeplot.DefaultValueGeometry.prototype._calculateGrid;
+
+Object.extend(Timeplot.LogarithmicValueGeometry.prototype,Timeplot.DefaultValueGeometry.prototype);
+
+/*
+ * This function calculates the grid spacing that it will be used
+ * by this geometry to draw the grid in order to reduce clutter.
+ */
+Timeplot.LogarithmicValueGeometry.prototype._logarithmicCalculateGrid = function() {
+ var grid = [];
+
+ if (!this._canvas || this._valueRange == 0) return grid;
+
+ var v = 1;
+ var y = this.toScreen(v);
+ while (y < this._canvas.height || isNaN(y)) {
+ if (y > 0) {
+ grid.push({ y: y, label: v });
+ }
+ v *= 10;
+ y = this.toScreen(v);
+ }
+
+ return grid;
+};
+
+/**
+ * Turn the logarithmic scaling off.
+ */
+Timeplot.LogarithmicValueGeometry.prototype.actLinear = function() {
+ this._mode = "lin";
+ this._map = this._linMap;
+ this._calculateGrid = this._linearCalculateGrid;
+ this.reset();
+}
+
+/**
+ * Turn the logarithmic scaling on.
+ */
+Timeplot.LogarithmicValueGeometry.prototype.actLogarithmic = function() {
+ this._mode = "log";
+ this._map = this._logMap;
+ this._calculateGrid = this._logarithmicCalculateGrid;
+ this.reset();
+}
+
+/**
+ * Toggle logarithmic scaling seeting it to on if off and viceversa.
+ */
+Timeplot.LogarithmicValueGeometry.prototype.toggle = function() {
+ if (this._mode == "log") {
+ this.actLinear();
+ } else {
+ this.actLogarithmic();
+ }
+}
+
+// -----------------------------------------------------
+
+/**
+ * This is the constructor for the default time geometry.
+ *
+ * @constructor
+ */
+Timeplot.DefaultTimeGeometry = function(params) {
+ if (!params) params = {};
+ this._id = ("id" in params) ? params.id : "g" + Math.round(Math.random() * 1000000);
+ this._locale = ("locale" in params) ? params.locale : "en";
+ this._timeZone = ("timeZone" in params) ? params.timeZone : SimileAjax.DateTime.getTimezone();
+ this._labeller = ("labeller" in params) ? params.labeller : null;
+ this._axisColor = ("axisColor" in params) ? ((params.axisColor == "string") ? new Timeplot.Color(params.axisColor) : params.axisColor) : new Timeplot.Color("#606060"),
+ this._gridColor = ("gridColor" in params) ? ((params.gridColor == "string") ? new Timeplot.Color(params.gridColor) : params.gridColor) : null,
+ this._gridLineWidth = ("gridLineWidth" in params) ? params.gridLineWidth : 0.5;
+ this._axisLabelsPlacement = ("axisLabelsPlacement" in params) ? params.axisLabelsPlacement : "bottom";
+ this._gridStep = ("gridStep" in params) ? params.gridStep : 100;
+ this._gridStepRange = ("gridStepRange" in params) ? params.gridStepRange : 20;
+ this._min = ("min" in params) ? params.min : null;
+ this._max = ("max" in params) ? params.max : null;
+ this._timeValuePosition =("timeValuePosition" in params) ? params.timeValuePosition : "bottom";
+ this._unit = ("unit" in params) ? params.unit : Timeline.NativeDateUnit;
+ this._linMap = {
+ direct: function(t) {
+ return t;
+ },
+ inverse: function(x) {
+ return x;
+ }
+ }
+ this._map = this._linMap;
+ this._labeler = this._unit.createLabeller(this._locale, this._timeZone);
+ var dateParser = this._unit.getParser("iso8601");
+ if (this._min && !this._min.getTime) {
+ this._min = dateParser(this._min);
+ }
+ if (this._max && !this._max.getTime) {
+ this._max = dateParser(this._max);
+ }
+ this._grid = [];
+}
+
+Timeplot.DefaultTimeGeometry.prototype = {
+
+ /**
+ * Since geometries can be reused across timeplots, we need to call this function
+ * before we can paint using this geometry.
+ */
+ setTimeplot: function(timeplot) {
+ this._timeplot = timeplot;
+ this._canvas = timeplot.getCanvas();
+ this.reset();
+ },
+
+ /**
+ * Called by all the plot layers this geometry is associated with
+ * to update the time range. Unless min/max values are specified
+ * in the parameters, the biggest range will be used.
+ */
+ setRange: function(range) {
+ if (this._min) {
+ this._earliestDate = this._min;
+ } else if (range.earliestDate && ((this._earliestDate == null) || ((this._earliestDate != null) && (range.earliestDate.getTime() < this._earliestDate.getTime())))) {
+ this._earliestDate = range.earliestDate;
+ }
+
+ if (this._max) {
+ this._latestDate = this._max;
+ } else if (range.latestDate && ((this._latestDate == null) || ((this._latestDate != null) && (range.latestDate.getTime() > this._latestDate.getTime())))) {
+ this._latestDate = range.latestDate;
+ }
+
+ if (!this._earliestDate && !this._latestDate) {
+ this._grid = [];
+ } else {
+ this.reset();
+ }
+ },
+
+ /**
+ * Called after changing ranges or canvas size to reset the grid values
+ */
+ reset: function() {
+ this._updateMappedValues();
+ if (this._canvas) this._grid = this._calculateGrid();
+ },
+
+ /**
+ * Map the given date to a x screen coordinate.
+ */
+ toScreen: function(time) {
+ if (this._canvas && this._latestDate) {
+ var t = time - this._earliestDate.getTime();
+ return this._canvas.width * this._map.direct(t) / this._mappedPeriod;
+ } else {
+ return -50;
+ }
+ },
+
+ /**
+ * Map the given x screen coordinate to a date.
+ */
+ fromScreen: function(x) {
+ if (this._canvas) {
+ return this._map.inverse(this._mappedPeriod * x / this._canvas.width) + this._earliestDate.getTime();
+ } else {
+ return 0;
+ }
+ },
+
+ /**
+ * Get a period (in milliseconds) this time geometry spans.
+ */
+ getPeriod: function() {
+ return this._period;
+ },
+
+ /**
+ * Return the labeler that has been associated with this time geometry
+ */
+ getLabeler: function() {
+ return this._labeler;
+ },
+
+ /**
+ * Return the time unit associated with this time geometry
+ */
+ getUnit: function() {
+ return this._unit;
+ },
+
+ /**
+ * Each geometry is also a painter and paints the value grid and grid labels.
+ */
+ paint: function() {
+ if (this._canvas) {
+ var unit = this._unit;
+ var ctx = this._canvas.getContext('2d');
+
+ var gradient = ctx.createLinearGradient(0,0,0,this._canvas.height);
+
+ ctx.strokeStyle = gradient;
+ ctx.lineWidth = this._gridLineWidth;
+ ctx.lineJoin = 'miter';
+
+ // paint grid
+ if (this._gridColor) {
+ gradient.addColorStop(0, this._gridColor.toString());
+ gradient.addColorStop(1, "rgba(255,255,255,0.9)");
+
+ for (var i = 0; i < this._grid.length; i++) {
+ var tick = this._grid[i];
+ var x = Math.floor(tick.x) + 0.5;
+ if (this._axisLabelsPlacement == "top") {
+ var div = this._timeplot.putText(this._id + "-" + i, tick.label,"timeplot-grid-label",{
+ left: x + 4,
+ top: 2,
+ visibility: "hidden"
+ });
+ } else if (this._axisLabelsPlacement == "bottom") {
+ var div = this._timeplot.putText(this._id + "-" + i, tick.label, "timeplot-grid-label",{
+ left: x + 4,
+ bottom: 2,
+ visibility: "hidden"
+ });
+ }
+ if (x + div.clientWidth < this._canvas.width + 10) {
+ div.style.visibility = "visible"; // avoid the labels that would overflow
+ }
+
+ // draw separator
+ ctx.beginPath();
+ ctx.moveTo(x,0);
+ ctx.lineTo(x,this._canvas.height);
+ ctx.stroke();
+ }
+ }
+
+ // paint axis
+ gradient.addColorStop(0, this._axisColor.toString());
+ gradient.addColorStop(1, "rgba(255,255,255,0.5)");
+
+ ctx.lineWidth = 1;
+ gradient.addColorStop(0, this._axisColor.toString());
+
+ ctx.beginPath();
+ ctx.moveTo(0,0);
+ ctx.lineTo(this._canvas.width,0);
+ ctx.stroke();
+ }
+ },
+
+ /*
+ * This function calculates the grid spacing that it will be used
+ * by this geometry to draw the grid in order to reduce clutter.
+ */
+ _calculateGrid: function() {
+ var grid = [];
+
+ var time = SimileAjax.DateTime;
+ var u = this._unit;
+ var p = this._period;
+
+ if (p == 0) return grid;
+
+ // find the time units nearest to the time period
+ if (p > time.gregorianUnitLengths[time.MILLENNIUM]) {
+ unit = time.MILLENNIUM;
+ } else {
+ for (var unit = time.MILLENNIUM; unit > 0; unit--) {
+ if (time.gregorianUnitLengths[unit-1] <= p && p < time.gregorianUnitLengths[unit]) {
+ unit--;
+ break;
+ }
+ }
+ }
+
+ var t = u.cloneValue(this._earliestDate);
+
+ do {
+ time.roundDownToInterval(t, unit, this._timeZone, 1, 0);
+ var x = this.toScreen(u.toNumber(t));
+ switch (unit) {
+ case time.SECOND:
+ var l = t.toLocaleTimeString();
+ break;
+ case time.MINUTE:
+ var m = t.getMinutes();
+ var l = t.getHours() + ":" + ((m < 10) ? "0" : "") + m;
+ break;
+ case time.HOUR:
+ var l = t.getHours() + ":00";
+ break;
+ case time.DAY:
+ case time.WEEK:
+ case time.MONTH:
+ var l = t.toLocaleDateString();
+ break;
+ case time.YEAR:
+ case time.DECADE:
+ case time.CENTURY:
+ case time.MILLENNIUM:
+ var l = t.getUTCFullYear();
+ break;
+ }
+ if (x > 0) {
+ grid.push({ x: x, label: l });
+ }
+ time.incrementByInterval(t, unit, this._timeZone);
+ } while (t.getTime() < this._latestDate.getTime());
+
+ return grid;
+ },
+
+ /*
+ * Update the values that are used by the paint function so that
+ * we don't have to calculate them at every repaint.
+ */
+ _updateMappedValues: function() {
+ if (this._latestDate && this._earliestDate) {
+ this._period = this._latestDate.getTime() - this._earliestDate.getTime();
+ this._mappedPeriod = this._map.direct(this._period);
+ } else {
+ this._period = 0;
+ this._mappedPeriod = 0;
+ }
+ }
+
+}
+
+// --------------------------------------------------------------
+
+/**
+ * This is the constructor for the magnifying time geometry.
+ * Users can interact with this geometry and 'magnify' certain areas of the
+ * plot to see the plot enlarged and resolve details that would otherwise
+ * get lost or cluttered with a linear time geometry.
+ *
+ * @constructor
+ */
+Timeplot.MagnifyingTimeGeometry = function(params) {
+ Timeplot.DefaultTimeGeometry.apply(this, arguments);
+
+ var g = this;
+ this._MagnifyingMap = {
+ direct: function(t) {
+ if (t < g._leftTimeMargin) {
+ var x = t * g._leftRate;
+ } else if ( g._leftTimeMargin < t && t < g._rightTimeMargin ) {
+ var x = t * g._expandedRate + g._expandedTimeTranslation;
+ } else {
+ var x = t * g._rightRate + g._rightTimeTranslation;
+ }
+ return x;
+ },
+ inverse: function(x) {
+ if (x < g._leftScreenMargin) {
+ var t = x / g._leftRate;
+ } else if ( g._leftScreenMargin < x && x < g._rightScreenMargin ) {
+ var t = x / g._expandedRate + g._expandedScreenTranslation;
+ } else {
+ var t = x / g._rightRate + g._rightScreenTranslation;
+ }
+ return t;
+ }
+ }
+
+ this._mode = "lin";
+ this._map = this._linMap;
+};
+
+Object.extend(Timeplot.MagnifyingTimeGeometry.prototype,Timeplot.DefaultTimeGeometry.prototype);
+
+/**
+ * Initialize this geometry associating it with the given timeplot and
+ * register the geometry event handlers to the timeplot so that it can
+ * interact with the user.
+ */
+Timeplot.MagnifyingTimeGeometry.prototype.initialize = function(timeplot) {
+ Timeplot.DefaultTimeGeometry.prototype.initialize.apply(this, arguments);
+
+ if (!this._lens) {
+ this._lens = this._timeplot.putDiv("lens","timeplot-lens");
+ }
+
+ var period = 1000 * 60 * 60 * 24 * 30; // a month in the magnifying lens
+
+ var geometry = this;
+
+ var magnifyWith = function(lens) {
+ var aperture = lens.clientWidth;
+ var loc = geometry._timeplot.locate(lens);
+ geometry.setMagnifyingParams(loc.x + aperture / 2, aperture, period);
+ geometry.actMagnifying();
+ geometry._timeplot.paint();
+ }
+
+ var canvasMouseDown = function(elmt, evt, target) {
+ geometry._canvas.startCoords = SimileAjax.DOM.getEventRelativeCoordinates(evt,elmt);
+ geometry._canvas.pressed = true;
+ }
+
+ var canvasMouseUp = function(elmt, evt, target) {
+ geometry._canvas.pressed = false;
+ var coords = SimileAjax.DOM.getEventRelativeCoordinates(evt,elmt);
+ if (Timeplot.Math.isClose(coords,geometry._canvas.startCoords,5)) {
+ geometry._lens.style.display = "none";
+ geometry.actLinear();
+ geometry._timeplot.paint();
+ } else {
+ geometry._lens.style.cursor = "move";
+ magnifyWith(geometry._lens);
+ }
+ }
+
+ var canvasMouseMove = function(elmt, evt, target) {
+ if (geometry._canvas.pressed) {
+ var coords = SimileAjax.DOM.getEventRelativeCoordinates(evt,elmt);
+ if (coords.x < 0) coords.x = 0;
+ if (coords.x > geometry._canvas.width) coords.x = geometry._canvas.width;
+ geometry._timeplot.placeDiv(geometry._lens, {
+ left: geometry._canvas.startCoords.x,
+ width: coords.x - geometry._canvas.startCoords.x,
+ bottom: 0,
+ height: geometry._canvas.height,
+ display: "block"
+ });
+ }
+ }
+
+ var lensMouseDown = function(elmt, evt, target) {
+ geometry._lens.startCoords = SimileAjax.DOM.getEventRelativeCoordinates(evt,elmt);;
+ geometry._lens.pressed = true;
+ }
+
+ var lensMouseUp = function(elmt, evt, target) {
+ geometry._lens.pressed = false;
+ }
+
+ var lensMouseMove = function(elmt, evt, target) {
+ if (geometry._lens.pressed) {
+ var coords = SimileAjax.DOM.getEventRelativeCoordinates(evt,elmt);
+ var lens = geometry._lens;
+ var left = lens.offsetLeft + coords.x - lens.startCoords.x;
+ if (left < geometry._timeplot._paddingX) left = geometry._timeplot._paddingX;
+ if (left + lens.clientWidth > geometry._canvas.width - geometry._timeplot._paddingX) left = geometry._canvas.width - lens.clientWidth + geometry._timeplot._paddingX;
+ lens.style.left = left;
+ magnifyWith(lens);
+ }
+ }
+
+ if (!this._canvas.instrumented) {
+ SimileAjax.DOM.registerEvent(this._canvas, "mousedown", canvasMouseDown);
+ SimileAjax.DOM.registerEvent(this._canvas, "mousemove", canvasMouseMove);
+ SimileAjax.DOM.registerEvent(this._canvas, "mouseup" , canvasMouseUp);
+ SimileAjax.DOM.registerEvent(this._canvas, "mouseup" , lensMouseUp);
+ this._canvas.instrumented = true;
+ }
+
+ if (!this._lens.instrumented) {
+ SimileAjax.DOM.registerEvent(this._lens, "mousedown", lensMouseDown);
+ SimileAjax.DOM.registerEvent(this._lens, "mousemove", lensMouseMove);
+ SimileAjax.DOM.registerEvent(this._lens, "mouseup" , lensMouseUp);
+ SimileAjax.DOM.registerEvent(this._lens, "mouseup" , canvasMouseUp);
+ this._lens.instrumented = true;
+ }
+}
+
+/**
+ * Set the Magnifying parameters. c is the location in pixels where the Magnifying
+ * center should be located in the timeplot, a is the aperture in pixel of
+ * the Magnifying and b is the time period in milliseconds that the Magnifying
+ * should span.
+ */
+Timeplot.MagnifyingTimeGeometry.prototype.setMagnifyingParams = function(c,a,b) {
+ a = a / 2;
+ b = b / 2;
+
+ var w = this._canvas.width;
+ var d = this._period;
+
+ if (c < 0) c = 0;
+ if (c > w) c = w;
+
+ if (c - a < 0) a = c;
+ if (c + a > w) a = w - c;
+
+ var ct = this.fromScreen(c) - this._earliestDate.getTime();
+ if (ct - b < 0) b = ct;
+ if (ct + b > d) b = d - ct;
+
+ this._centerX = c;
+ this._centerTime = ct;
+ this._aperture = a;
+ this._aperturePeriod = b;
+
+ this._leftScreenMargin = this._centerX - this._aperture;
+ this._rightScreenMargin = this._centerX + this._aperture;
+ this._leftTimeMargin = this._centerTime - this._aperturePeriod;
+ this._rightTimeMargin = this._centerTime + this._aperturePeriod;
+
+ this._leftRate = (c - a) / (ct - b);
+ this._expandedRate = a / b;
+ this._rightRate = (w - c - a) / (d - ct - b);
+
+ this._expandedTimeTranslation = this._centerX - this._centerTime * this._expandedRate;
+ this._expandedScreenTranslation = this._centerTime - this._centerX / this._expandedRate;
+ this._rightTimeTranslation = (c + a) - (ct + b) * this._rightRate;
+ this._rightScreenTranslation = (ct + b) - (c + a) / this._rightRate;
+
+ this._updateMappedValues();
+}
+
+/*
+ * Turn magnification off.
+ */
+Timeplot.MagnifyingTimeGeometry.prototype.actLinear = function() {
+ this._mode = "lin";
+ this._map = this._linMap;
+ this.reset();
+}
+
+/*
+ * Turn magnification on.
+ */
+Timeplot.MagnifyingTimeGeometry.prototype.actMagnifying = function() {
+ this._mode = "Magnifying";
+ this._map = this._MagnifyingMap;
+ this.reset();
+}
+
+/*
+ * Toggle magnification.
+ */
+Timeplot.MagnifyingTimeGeometry.prototype.toggle = function() {
+ if (this._mode == "Magnifying") {
+ this.actLinear();
+ } else {
+ this.actMagnifying();
+ }
+}
+
diff --git a/site/app/webroot/js/simile/timeplot/scripts/math.js b/site/app/webroot/js/simile/timeplot/scripts/math.js
new file mode 100755
index 0000000..3b2fd88
--- /dev/null
+++ b/site/app/webroot/js/simile/timeplot/scripts/math.js
@@ -0,0 +1,193 @@
+/**
+ * Math Utility functions
+ *
+ * @fileOverview Math Utility functions
+ * @name Math
+ */
+
+Timeplot.Math = {
+
+ /**
+ * Evaluates the range (min and max values) of the given array
+ */
+ range: function(f) {
+ var F = f.length;
+ var min = Number.MAX_VALUE;
+ var max = Number.MIN_VALUE;
+
+ for (var t = 0; t < F; t++) {
+ var value = f[t];
+ if (value < min) {
+ min = value;
+ }
+ if (value > max) {
+ max = value;
+ }
+ }
+
+ return {
+ min: min,
+ max: max
+ }
+ },
+
+ /**
+ * Evaluates the windows average of a given array based on the
+ * given window size
+ */
+ movingAverage: function(f, size) {
+ var F = f.length;
+ var g = new Array(F);
+ for (var n = 0; n < F; n++) {
+ var value = 0;
+ for (var m = n - size; m < n + size; m++) {
+ if (m < 0) {
+ var v = f[0];
+ } else if (m >= F) {
+ var v = g[n-1];
+ } else {
+ var v = f[m];
+ }
+ value += v;
+ }
+ g[n] = value / (2 * size);
+ }
+ return g;
+ },
+
+ /**
+ * Returns an array with the integral of the given array
+ */
+ integral: function(f) {
+ var F = f.length;
+
+ var g = new Array(F);
+ var sum = 0;
+
+ for (var t = 0; t < F; t++) {
+ sum += f[t];
+ g[t] = sum;
+ }
+
+ return g;
+ },
+
+ /**
+ * Normalizes an array so that its complete integral is 1.
+ * This is useful to obtain arrays that preserve the overall
+ * integral of a convolution.
+ */
+ normalize: function(f) {
+ var F = f.length;
+ var sum = 0.0;
+
+ for (var t = 0; t < F; t++) {
+ sum += f[t];
+ }
+
+ for (var t = 0; t < F; t++) {
+ f[t] /= sum;
+ }
+
+ return f;
+ },
+
+ /**
+ * Calculates the convolution between two arrays
+ */
+ convolution: function(f,g) {
+ var F = f.length;
+ var G = g.length;
+
+ var c = new Array(F);
+
+ for (var m = 0; m < F; m++) {
+ var r = 0;
+ var end = (m + G < F) ? m + G : F;
+ for (var n = m; n < end; n++) {
+ var a = f[n - G];
+ var b = g[n - m];
+ r += a * b;
+ }
+ c[m] = r;
+ }
+
+ return c;
+ },
+
+ // ------ Array generators -------------------------------------------------
+ // Functions that generate arrays based on mathematical functions
+ // Normally these are used to produce operators by convolving them with the input array
+ // The returned arrays have the property of having
+
+ /**
+ * Generate the heavyside step function of given size
+ */
+ heavyside: function(size) {
+ var f = new Array(size);
+ var value = 1 / size;
+ for (var t = 0; t < size; t++) {
+ f[t] = value;
+ }
+ return f;
+ },
+
+ /**
+ * Generate the gaussian function so that at the given 'size' it has value 'threshold'
+ * and make sure its integral is one.
+ */
+ gaussian: function(size, threshold) {
+ with (Math) {
+ var radius = size / 2;
+ var variance = radius * radius / log(threshold);
+ var g = new Array(size);
+ for (var t = 0; t < size; t++) {
+ var l = t - radius;
+ g[t] = exp(-variance * l * l);
+ }
+ }
+
+ return this.normalize(g);
+ },
+
+ // ---- Utility Methods --------------------------------------------------
+
+ /**
+ * Return x with n significant figures
+ */
+ round: function(x,n) {
+ with (Math) {
+ if (abs(x) > 1) {
+ var l = floor(log(x)/log(10));
+ var d = round(exp((l-n+1)*log(10)));
+ var y = round(round(x / d) * d);
+ return y;
+ } else {
+ log("FIXME(SM): still to implement for 0 < abs(x) < 1");
+ return x;
+ }
+ }
+ },
+
+ /**
+ * Return the hyperbolic tangent of x
+ */
+ tanh: function(x) {
+ if (x > 5) {
+ return 1;
+ } else if (x < 5) {
+ return -1;
+ } else {
+ var expx2 = Math.exp(2 * x);
+ return (expx2 - 1) / (expx2 + 1);
+ }
+ },
+
+ /**
+ * Returns true if |a.x - b.x| < value && | a.y - b.y | < value
+ */
+ isClose: function(a,b,value) {
+ return (a && b && Math.abs(a.x - b.x) < value && Math.abs(a.y - b.y) < value);
+ }
+
+} \ No newline at end of file
diff --git a/site/app/webroot/js/simile/timeplot/scripts/plot.js b/site/app/webroot/js/simile/timeplot/scripts/plot.js
new file mode 100755
index 0000000..b9696b4
--- /dev/null
+++ b/site/app/webroot/js/simile/timeplot/scripts/plot.js
@@ -0,0 +1,386 @@
+/**
+ * Plot Layer
+ *
+ * @fileOverview Plot Layer
+ * @name Plot
+ */
+
+/**
+ * A plot layer is the main building block for timeplots and it's the object
+ * that is responsible for painting the plot itself. Each plot needs to have
+ * a time geometry, either a DataSource (for time series
+ * plots) or an EventSource (for event plots) and a value geometry in case
+ * of time series plots. Such parameters are passed along
+ * in the 'plotInfo' map.
+ *
+ * @constructor
+ */
+Timeplot.Plot = function(timeplot, plotInfo) {
+ this._timeplot = timeplot;
+ this._canvas = timeplot.getCanvas();
+ this._plotInfo = plotInfo;
+ this._id = plotInfo.id;
+ this._timeGeometry = plotInfo.timeGeometry;
+ this._valueGeometry = plotInfo.valueGeometry;
+ this._showValues = plotInfo.showValues;
+ this._theme = new Timeline.getDefaultTheme();
+ this._dataSource = plotInfo.dataSource;
+ this._eventSource = plotInfo.eventSource;
+ this._bubble = null;
+};
+
+Timeplot.Plot.prototype = {
+
+ /**
+ * Initialize the plot layer
+ */
+ initialize: function() {
+ if (this._showValues && this._dataSource && this._dataSource.getValue) {
+ this._timeFlag = this._timeplot.putDiv("timeflag","timeplot-timeflag");
+ this._valueFlag = this._timeplot.putDiv(this._id + "valueflag","timeplot-valueflag");
+ this._valueFlagLineLeft = this._timeplot.putDiv(this._id + "valueflagLineLeft","timeplot-valueflag-line");
+ this._valueFlagLineRight = this._timeplot.putDiv(this._id + "valueflagLineRight","timeplot-valueflag-line");
+ if (!this._valueFlagLineLeft.firstChild) {
+ this._valueFlagLineLeft.appendChild(SimileAjax.Graphics.createTranslucentImage(Timeplot.urlPrefix + "images/line_left.png"));
+ this._valueFlagLineRight.appendChild(SimileAjax.Graphics.createTranslucentImage(Timeplot.urlPrefix + "images/line_right.png"));
+ }
+ this._valueFlagPole = this._timeplot.putDiv(this._id + "valuepole","timeplot-valueflag-pole");
+
+ var opacity = this._plotInfo.valuesOpacity;
+
+ SimileAjax.Graphics.setOpacity(this._timeFlag, opacity);
+ SimileAjax.Graphics.setOpacity(this._valueFlag, opacity);
+ SimileAjax.Graphics.setOpacity(this._valueFlagLineLeft, opacity);
+ SimileAjax.Graphics.setOpacity(this._valueFlagLineRight, opacity);
+ SimileAjax.Graphics.setOpacity(this._valueFlagPole, opacity);
+
+ var plot = this;
+
+ var mouseOverHandler = function(elmt, evt, target) {
+ plot._valueFlag.style.display = "block";
+ mouseMoveHandler(elmt, evt, target);
+ }
+
+ var day = 24 * 60 * 60 * 1000;
+ var month = 30 * day;
+
+ var mouseMoveHandler = function(elmt, evt, target) {
+ if (typeof SimileAjax != "undefined") {
+ var c = plot._canvas;
+ var x = Math.round(SimileAjax.DOM.getEventRelativeCoordinates(evt,plot._canvas).x);
+ if (x > c.width) x = c.width;
+ if (isNaN(x) || x < 0) x = 0;
+ var t = plot._timeGeometry.fromScreen(x);
+ if (t == 0) { // something is wrong
+ plot._valueFlag.style.display = "none";
+ return;
+ }
+
+ var v = plot._dataSource.getValue(t);
+ if (plot._plotInfo.roundValues) v = Math.round(v);
+ plot._valueFlag.innerHTML = new String(v);
+ var d = new Date(t);
+ var p = plot._timeGeometry.getPeriod();
+ if (p < day) {
+ plot._timeFlag.innerHTML = d.toLocaleTimeString();
+ } else if (p > month) {
+ plot._timeFlag.innerHTML = d.toLocaleDateString();
+ } else {
+ plot._timeFlag.innerHTML = d.toLocaleString();
+ }
+
+ var tw = plot._timeFlag.clientWidth;
+ var th = plot._timeFlag.clientHeight;
+ var tdw = Math.round(tw / 2);
+ var vw = plot._valueFlag.clientWidth;
+ var vh = plot._valueFlag.clientHeight;
+ var y = plot._valueGeometry.toScreen(v);
+
+ if (x + tdw > c.width) {
+ var tx = c.width - tdw;
+ } else if (x - tdw < 0) {
+ var tx = tdw;
+ } else {
+ var tx = x;
+ }
+
+ if (plot._timeGeometry._timeValuePosition == "top") {
+ plot._timeplot.placeDiv(plot._valueFlagPole, {
+ left: x,
+ top: th - 5,
+ height: c.height - y - th + 6,
+ display: "block"
+ });
+ plot._timeplot.placeDiv(plot._timeFlag,{
+ left: tx - tdw,
+ top: -6,
+ display: "block"
+ });
+ } else {
+ plot._timeplot.placeDiv(plot._valueFlagPole, {
+ left: x,
+ bottom: th - 5,
+ height: y - th + 6,
+ display: "block"
+ });
+ plot._timeplot.placeDiv(plot._timeFlag,{
+ left: tx - tdw,
+ bottom: -6,
+ display: "block"
+ });
+ }
+
+ if (x + vw + 14 > c.width && y + vh + 4 > c.height) {
+ plot._valueFlagLineLeft.style.display = "none";
+ plot._timeplot.placeDiv(plot._valueFlagLineRight,{
+ left: x - 14,
+ bottom: y - 14,
+ display: "block"
+ });
+ plot._timeplot.placeDiv(plot._valueFlag,{
+ left: x - vw - 13,
+ bottom: y - vh - 13,
+ display: "block"
+ });
+ } else if (x + vw + 14 > c.width && y + vh + 4 < c.height) {
+ plot._valueFlagLineRight.style.display = "none";
+ plot._timeplot.placeDiv(plot._valueFlagLineLeft,{
+ left: x - 14,
+ bottom: y,
+ display: "block"
+ });
+ plot._timeplot.placeDiv(plot._valueFlag,{
+ left: x - vw - 13,
+ bottom: y + 13,
+ display: "block"
+ });
+ } else if (x + vw + 14 < c.width && y + vh + 4 > c.height) {
+ plot._valueFlagLineRight.style.display = "none";
+ plot._timeplot.placeDiv(plot._valueFlagLineLeft,{
+ left: x,
+ bottom: y - 13,
+ display: "block"
+ });
+ plot._timeplot.placeDiv(plot._valueFlag,{
+ left: x + 13,
+ bottom: y - 13,
+ display: "block"
+ });
+ } else {
+ plot._valueFlagLineLeft.style.display = "none";
+ plot._timeplot.placeDiv(plot._valueFlagLineRight,{
+ left: x,
+ bottom: y,
+ display: "block"
+ });
+ plot._timeplot.placeDiv(plot._valueFlag,{
+ left: x + 13,
+ bottom: y + 13,
+ display: "block"
+ });
+ }
+ }
+ }
+
+ var timeplotElement = this._timeplot.getElement();
+ SimileAjax.DOM.registerEvent(timeplotElement, "mouseover", mouseOverHandler);
+ SimileAjax.DOM.registerEvent(timeplotElement, "mousemove", mouseMoveHandler);
+ }
+ },
+
+ /**
+ * Dispose the plot layer and all the data sources and listeners associated to it
+ */
+ dispose: function() {
+ if (this._dataSource) {
+ this._dataSource.removeListener(this._paintingListener);
+ this._paintingListener = null;
+ this._dataSource.dispose();
+ this._dataSource = null;
+ }
+ },
+
+ /**
+ * Return the data source of this plot layer (it could be either a DataSource or an EventSource)
+ */
+ getDataSource: function() {
+ return (this._dataSource) ? this._dataSource : this._eventSource;
+ },
+
+ /**
+ * Return the time geometry associated with this plot layer
+ */
+ getTimeGeometry: function() {
+ return this._timeGeometry;
+ },
+
+ /**
+ * Return the value geometry associated with this plot layer
+ */
+ getValueGeometry: function() {
+ return this._valueGeometry;
+ },
+
+ /**
+ * Paint this plot layer
+ */
+ paint: function() {
+ var ctx = this._canvas.getContext('2d');
+
+ ctx.lineWidth = this._plotInfo.lineWidth;
+ ctx.lineJoin = 'miter';
+
+ if (this._dataSource) {
+ if (this._plotInfo.fillColor) {
+ if (this._plotInfo.fillGradient) {
+ var gradient = ctx.createLinearGradient(0,this._canvas.height,0,0);
+ gradient.addColorStop(0,this._plotInfo.fillColor.toString());
+ gradient.addColorStop(0.5,this._plotInfo.fillColor.toString());
+ gradient.addColorStop(1, 'rgba(255,255,255,0)');
+
+ ctx.fillStyle = gradient;
+ } else {
+ ctx.fillStyle = this._plotInfo.fillColor.toString();
+ }
+
+ ctx.beginPath();
+ ctx.moveTo(0,0);
+ this._plot(function(x,y) {
+ ctx.lineTo(x,y);
+ });
+ if (this._plotInfo.fillFrom == Number.NEGATIVE_INFINITY) {
+ ctx.lineTo(this._canvas.width, 0);
+ } else if (this._plotInfo.fillFrom == Number.POSITIVE_INFINITY) {
+ ctx.lineTo(this._canvas.width, this._canvas.height);
+ ctx.lineTo(0, this._canvas.height);
+ } else {
+ ctx.lineTo(this._canvas.width, this._valueGeometry.toScreen(this._plotInfo.fillFrom));
+ ctx.lineTo(0, this._valueGeometry.toScreen(this._plotInfo.fillFrom));
+ }
+ ctx.fill();
+ }
+
+ if (this._plotInfo.lineColor) {
+ ctx.strokeStyle = this._plotInfo.lineColor.toString();
+ ctx.beginPath();
+ var first = true;
+ this._plot(function(x,y) {
+ if (first) {
+ first = false;
+ ctx.moveTo(x,y);
+ }
+ ctx.lineTo(x,y);
+ });
+ ctx.stroke();
+ }
+
+ if (this._plotInfo.dotColor) {
+ ctx.fillStyle = this._plotInfo.dotColor.toString();
+ var r = this._plotInfo.dotRadius;
+ this._plot(function(x,y) {
+ ctx.beginPath();
+ ctx.arc(x,y,r,0,2*Math.PI,true);
+ ctx.fill();
+ });
+ }
+ }
+
+ if (this._eventSource) {
+ var gradient = ctx.createLinearGradient(0,0,0,this._canvas.height);
+ gradient.addColorStop(1, 'rgba(255,255,255,0)');
+
+ ctx.strokeStyle = gradient;
+ ctx.fillStyle = gradient;
+ ctx.lineWidth = this._plotInfo.eventLineWidth;
+ ctx.lineJoin = 'miter';
+
+ var i = this._eventSource.getAllEventIterator();
+ while (i.hasNext()) {
+ var event = i.next();
+ var color = event.getColor();
+ color = (color) ? new Timeplot.Color(color) : this._plotInfo.lineColor;
+ var eventStart = event.getStart().getTime();
+ var eventEnd = event.getEnd().getTime();
+ if (eventStart == eventEnd) {
+ var c = color.toString();
+ gradient.addColorStop(0, c);
+ var start = this._timeGeometry.toScreen(eventStart);
+ start = Math.floor(start) + 0.5; // center it between two pixels (makes the rendering nicer)
+ var end = start;
+ ctx.beginPath();
+ ctx.moveTo(start,0);
+ ctx.lineTo(start,this._canvas.height);
+ ctx.stroke();
+ var x = start - 4;
+ var w = 7;
+ } else {
+ var c = color.toString(0.5);
+ gradient.addColorStop(0, c);
+ var start = this._timeGeometry.toScreen(eventStart);
+ start = Math.floor(start) + 0.5; // center it between two pixels (makes the rendering nicer)
+ var end = this._timeGeometry.toScreen(eventEnd);
+ end = Math.floor(end) + 0.5; // center it between two pixels (makes the rendering nicer)
+ ctx.fillRect(start,0,end - start, this._canvas.height);
+ var x = start;
+ var w = end - start - 1;
+ }
+
+ var div = this._timeplot.putDiv(event.getID(),"timeplot-event-box",{
+ left: Math.round(x),
+ width: Math.round(w),
+ top: 0,
+ height: this._canvas.height - 1
+ });
+
+ var plot = this;
+ var clickHandler = function(event) {
+ return function(elmt, evt, target) {
+ var doc = plot._timeplot.getDocument();
+ plot._closeBubble();
+ var coords = SimileAjax.DOM.getEventPageCoordinates(evt);
+ var elmtCoords = SimileAjax.DOM.getPageCoordinates(elmt);
+ plot._bubble = SimileAjax.Graphics.createBubbleForPoint(coords.x, elmtCoords.top + plot._canvas.height, plot._plotInfo.bubbleWidth, plot._plotInfo.bubbleHeight, "bottom");
+ event.fillInfoBubble(plot._bubble.content, plot._theme, plot._timeGeometry.getLabeler());
+ }
+ };
+ var mouseOverHandler = function(elmt, evt, target) {
+ elmt.oldClass = elmt.className;
+ elmt.className = elmt.className + " timeplot-event-box-highlight";
+ };
+ var mouseOutHandler = function(elmt, evt, target) {
+ elmt.className = elmt.oldClass;
+ elmt.oldClass = null;
+ }
+
+ if (!div.instrumented) {
+ SimileAjax.DOM.registerEvent(div, "click" , clickHandler(event));
+ SimileAjax.DOM.registerEvent(div, "mouseover", mouseOverHandler);
+ SimileAjax.DOM.registerEvent(div, "mouseout" , mouseOutHandler);
+ div.instrumented = true;
+ }
+ }
+ }
+ },
+
+ _plot: function(f) {
+ var data = this._dataSource.getData();
+ if (data) {
+ var times = data.times;
+ var values = data.values;
+ var T = times.length;
+ for (var t = 0; t < T; t++) {
+ var x = this._timeGeometry.toScreen(times[t]);
+ var y = this._valueGeometry.toScreen(values[t]);
+ f(x, y);
+ }
+ }
+ },
+
+ _closeBubble: function() {
+ if (this._bubble != null) {
+ this._bubble.close();
+ this._bubble = null;
+ }
+ }
+
+} \ No newline at end of file
diff --git a/site/app/webroot/js/simile/timeplot/scripts/processor.js b/site/app/webroot/js/simile/timeplot/scripts/processor.js
new file mode 100755
index 0000000..6ec276e
--- /dev/null
+++ b/site/app/webroot/js/simile/timeplot/scripts/processor.js
@@ -0,0 +1,120 @@
+/**
+ * Processing Data Source
+ *
+ * @fileOverview Processing Data Source and Operators
+ * @name Processor
+ */
+
+/* -----------------------------------------------------------------------------
+ * Operators
+ *
+ * These are functions that can be used directly as Timeplot.Processor operators
+ * ----------------------------------------------------------------------------- */
+
+Timeplot.Operator = {
+
+ /**
+ * This is the operator used when you want to draw the cumulative sum
+ * of a time series and not, for example, their daily values.
+ */
+ sum: function(data, params) {
+ return Timeplot.Math.integral(data.values);
+ },
+
+ /**
+ * This is the operator that is used to 'smooth' a given time series
+ * by taking the average value of a moving window centered around
+ * each value. The size of the moving window is influenced by the 'size'
+ * parameters in the params map.
+ */
+ average: function(data, params) {
+ var size = ("size" in params) ? params.size : 30;
+ var result = Timeplot.Math.movingAverage(data.values, size);
+ return result;
+ }
+}
+
+/*==================================================
+ * Processing Data Source
+ *==================================================*/
+
+/**
+ * A Processor is a special DataSource that can apply an Operator
+ * to the DataSource values and thus return a different one.
+ *
+ * @constructor
+ */
+Timeplot.Processor = function(dataSource, operator, params) {
+ this._dataSource = dataSource;
+ this._operator = operator;
+ this._params = params;
+
+ this._data = {
+ times: new Array(),
+ values: new Array()
+ };
+
+ this._range = {
+ earliestDate: null,
+ latestDate: null,
+ min: 0,
+ max: 0
+ };
+
+ var processor = this;
+ this._processingListener = {
+ onAddMany: function() { processor._process(); },
+ onClear: function() { processor._clear(); }
+ }
+ this.addListener(this._processingListener);
+};
+
+Timeplot.Processor.prototype = {
+
+ _clear: function() {
+ this.removeListener(this._processingListener);
+ this._dataSource._clear();
+ },
+
+ _process: function() {
+ // this method requires the dataSource._process() method to be
+ // called first as to setup the data and range used below
+ // this should be guaranteed by the order of the listener registration
+
+ var data = this._dataSource.getData();
+ var range = this._dataSource.getRange();
+
+ var newValues = this._operator(data, this._params);
+ var newValueRange = Timeplot.Math.range(newValues);
+
+ this._data = {
+ times: data.times,
+ values: newValues
+ };
+
+ this._range = {
+ earliestDate: range.earliestDate,
+ latestDate: range.latestDate,
+ min: newValueRange.min,
+ max: newValueRange.max
+ };
+ },
+
+ getRange: function() {
+ return this._range;
+ },
+
+ getData: function() {
+ return this._data;
+ },
+
+ getValue: Timeplot.DataSource.prototype.getValue,
+
+ addListener: function(listener) {
+ this._dataSource.addListener(listener);
+ },
+
+ removeListener: function(listener) {
+ this._dataSource.removeListener(listener);
+ }
+}
diff --git a/site/app/webroot/js/simile/timeplot/scripts/sources.js b/site/app/webroot/js/simile/timeplot/scripts/sources.js
new file mode 100755
index 0000000..22e07eb
--- /dev/null
+++ b/site/app/webroot/js/simile/timeplot/scripts/sources.js
@@ -0,0 +1,348 @@
+/**
+ * Sources
+ *
+ * @fileOverview Sources
+ * @name Sources
+ */
+
+/**
+ * Timeplot.DefaultEventSource is an extension of Timeline.DefaultEventSource
+ * and therefore reuses the exact same event loading subsystem that
+ * Timeline uses.
+ *
+ * @constructor
+ */
+Timeplot.DefaultEventSource = function(eventIndex) {
+ Timeline.DefaultEventSource.apply(this, arguments);
+};
+
+Object.extend(Timeplot.DefaultEventSource.prototype, Timeline.DefaultEventSource.prototype);
+
+/**
+ * Function used by Timeplot to load time series data from a text file.
+ */
+Timeplot.DefaultEventSource.prototype.loadText = function(text, separator, url, filter) {
+
+ if (text == null) {
+ return;
+ }
+
+ this._events.maxValues = new Array();
+ var base = this._getBaseURL(url);
+
+ var dateTimeFormat = 'iso8601';
+ var parseDateTimeFunction = this._events.getUnit().getParser(dateTimeFormat);
+
+// AMO change - moved to after filter so we can parse comments
+ //var data = this._parseText(text, separator);
+var data = text;
+
+ var added = false;
+
+ if (filter) {
+ data = filter(data);
+ }
+
+ data = this._parseText(data, separator);
+
+ if (data) {
+ for (var i = 0; i < data.length; i++){
+ var row = data[i];
+ if (row.length > 1) {
+ var evt = new Timeplot.DefaultEventSource.NumericEvent(
+ parseDateTimeFunction(row[0]),
+ row.slice(1)
+ );
+ this._events.add(evt);
+ added = true;
+ }
+ }
+ }
+
+ if (added) {
+ this._fire("onAddMany", []);
+ }
+}
+
+/*
+ * Parse the data file.
+ *
+ * Adapted from http://www.kawa.net/works/js/jkl/js/jkl-parsexml.js by Yusuke Kawasaki
+ */
+Timeplot.DefaultEventSource.prototype._parseText = function (text, separator) {
+ text = text.replace( /\r\n?/g, "\n" ); // normalize newlines
+ var pos = 0;
+ var len = text.length;
+ var table = [];
+ while (pos < len) {
+ var line = [];
+ if (text.charAt(pos) != '#') { // if it's not a comment, process
+ while (pos < len) {
+ if (text.charAt(pos) == '"') { // "..." quoted column
+ var nextquote = text.indexOf('"', pos+1 );
+ while (nextquote<len && nextquote > -1) {
+ if (text.charAt(nextquote+1) != '"') {
+ break; // end of column
+ }
+ nextquote = text.indexOf('"', nextquote + 2);
+ }
+ if ( nextquote < 0 ) {
+ // unclosed quote
+ } else if (text.charAt(nextquote + 1) == separator) { // end of column
+ var quoted = text.substr(pos + 1, nextquote-pos - 1);
+ quoted = quoted.replace(/""/g,'"');
+ line[line.length] = quoted;
+ pos = nextquote + 2;
+ continue;
+ } else if (text.charAt(nextquote + 1) == "\n" || // end of line
+ len == nextquote + 1 ) { // end of file
+ var quoted = text.substr(pos + 1, nextquote-pos - 1);
+ quoted = quoted.replace(/""/g,'"');
+ line[line.length] = quoted;
+ pos = nextquote + 2;
+ break;
+ } else {
+ // invalid column
+ }
+ }
+ var nextseparator = text.indexOf(separator, pos);
+ var nextnline = text.indexOf("\n", pos);
+ if (nextnline < 0) nextnline = len;
+ if (nextseparator > -1 && nextseparator < nextnline) {
+ line[line.length] = text.substr(pos, nextseparator-pos);
+ pos = nextseparator + 1;
+ } else { // end of line
+ line[line.length] = text.substr(pos, nextnline-pos);
+ pos = nextnline + 1;
+ break;
+ }
+ }
+ } else { // if it's a comment, ignore
+ var nextnline = text.indexOf("\n", pos);
+ pos = (nextnline > -1) ? nextnline + 1 : cur;
+ }
+ if (line.length > 0) {
+ table[table.length] = line; // push line
+ }
+ }
+ if (table.length < 0) return; // null data
+ return table;
+}
+
+/**
+ * Return the range of the loaded data
+ */
+Timeplot.DefaultEventSource.prototype.getRange = function() {
+ var earliestDate = this.getEarliestDate();
+ var latestDate = this.getLatestDate();
+ return {
+ earliestDate: (earliestDate) ? earliestDate : null,
+ latestDate: (latestDate) ? latestDate : null,
+ min: 0,
+ max: 0
+ };
+}
+
+// -----------------------------------------------------------------------
+
+/**
+ * A NumericEvent is an Event that also contains an array of values,
+ * one for each columns in the loaded data file.
+ *
+ * @constructor
+ */
+Timeplot.DefaultEventSource.NumericEvent = function(time, values) {
+ this._id = "e" + Math.round(Math.random() * 1000000);
+ this._time = time;
+ this._values = values;
+};
+
+Timeplot.DefaultEventSource.NumericEvent.prototype = {
+ getID: function() { return this._id; },
+ getTime: function() { return this._time; },
+ getValues: function() { return this._values; },
+
+ // these are required by the EventSource
+ getStart: function() { return this._time; },
+ getEnd: function() { return this._time; }
+};
+
+// -----------------------------------------------------------------------
+
+/**
+ * A DataSource represent an abstract class that represents a monodimensional time series.
+ *
+ * @constructor
+ */
+Timeplot.DataSource = function(eventSource) {
+ this._eventSource = eventSource;
+ var source = this;
+ this._processingListener = {
+ onAddMany: function() { source._process(); },
+ onClear: function() { source._clear(); }
+ }
+ this.addListener(this._processingListener);
+ this._listeners = [];
+ this._data = null;
+ this._range = null;
+};
+
+Timeplot.DataSource.prototype = {
+
+ _clear: function() {
+ this._data = null;
+ this._range = null;
+ },
+
+ _process: function() {
+ this._data = {
+ times: new Array(),
+ values: new Array()
+ };
+ this._range = {
+ earliestDate: null,
+ latestDate: null,
+ min: 0,
+ max: 0
+ };
+ },
+
+ /**
+ * Return the range of this data source
+ */
+ getRange: function() {
+ return this._range;
+ },
+
+ /**
+ * Return the actual data that this data source represents.
+ * NOTE: _data = { times: [], values: [] }
+ */
+ getData: function() {
+ return this._data;
+ },
+
+ /**
+ * Return the value associated with the given time in this time series
+ */
+ getValue: function(t) {
+ if (this._data) {
+ for (var i = 0; i < this._data.times.length; i++) {
+ var l = this._data.times[i];
+ if (l >= t) {
+ return this._data.values[i];
+ }
+ }
+ }
+ return 0;
+ },
+
+ /**
+ * Add a listener to the underlying event source
+ */
+ addListener: function(listener) {
+ this._eventSource.addListener(listener);
+ },
+
+ /**
+ * Remove a listener from the underlying event source
+ */
+ removeListener: function(listener) {
+ this._eventSource.removeListener(listener);
+ },
+
+ /**
+ * Replace a listener from the underlying event source
+ */
+ replaceListener: function(oldListener, newListener) {
+ this.removeListener(oldListener);
+ this.addListener(newListener);
+ }
+
+}
+
+// -----------------------------------------------------------------------
+
+/**
+ * Implementation of a DataSource that extracts the time series out of a
+ * single column from the events
+ *
+ * @constructor
+ */
+Timeplot.ColumnSource = function(eventSource, column) {
+ Timeplot.DataSource.apply(this, arguments);
+ this._column = column - 1;
+};
+
+Object.extend(Timeplot.ColumnSource.prototype,Timeplot.DataSource.prototype);
+
+Timeplot.ColumnSource.prototype.dispose = function() {
+ this.removeListener(this._processingListener);
+ this._clear();
+}
+
+Timeplot.ColumnSource.prototype._process = function() {
+ var count = this._eventSource.getCount();
+ var times = new Array(count);
+ var values = new Array(count);
+ var min = Number.MAX_VALUE;
+ var max = Number.MIN_VALUE;
+ var i = 0;
+
+ var iterator = this._eventSource.getAllEventIterator();
+ while (iterator.hasNext()) {
+ var event = iterator.next();
+ var time = event.getTime();
+ times[i] = time;
+ var value = this._getValue(event);
+ if (!isNaN(value)) {
+ if (value < min) {
+ min = value;
+ }
+ if (value > max) {
+ max = value;
+ }
+ values[i] = value;
+ }
+ i++;
+ }
+
+ this._data = {
+ times: times,
+ values: values
+ };
+
+ if (max == Number.MIN_VALUE) max = 1;
+
+ this._range = {
+ earliestDate: this._eventSource.getEarliestDate(),
+ latestDate: this._eventSource.getLatestDate(),
+ min: min,
+ max: max
+ };
+}
+
+Timeplot.ColumnSource.prototype._getValue = function(event) {
+ return parseFloat(event.getValues()[this._column]);
+}
+
+// ---------------------------------------------------------------
+
+/**
+ * Data Source that generates the time series out of the difference
+ * between the first and the second column
+ *
+ * @constructor
+ */
+Timeplot.ColumnDiffSource = function(eventSource, column1, column2) {
+ Timeplot.ColumnSource.apply(this, arguments);
+ this._column2 = column2 - 1;
+};
+
+Object.extend(Timeplot.ColumnDiffSource.prototype,Timeplot.ColumnSource.prototype);
+
+Timeplot.ColumnDiffSource.prototype._getValue = function(event) {
+ var a = parseFloat(event.getValues()[this._column]);
+ var b = parseFloat(event.getValues()[this._column2]);
+ return a - b;
+}
diff --git a/site/app/webroot/js/simile/timeplot/scripts/timeplot.js b/site/app/webroot/js/simile/timeplot/scripts/timeplot.js
new file mode 100755
index 0000000..01eeaa3
--- /dev/null
+++ b/site/app/webroot/js/simile/timeplot/scripts/timeplot.js
@@ -0,0 +1,603 @@
+/**
+ * Timeplot
+ *
+ * @fileOverview Timeplot
+ * @name Timeplot
+ */
+
+Timeline.Debug = SimileAjax.Debug; // timeline uses it's own debug system which is not as advanced
+var log = SimileAjax.Debug.log; // shorter name is easier to use
+
+/*
+ * This function is used to implement a raw but effective OOP-like inheritance
+ * in various Timeplot classes.
+ */
+Object.extend = function(destination, source) {
+ for (var property in source) {
+ destination[property] = source[property];
+ }
+ return destination;
+}
+
+// ---------------------------------------------
+
+/**
+ * Create a timeplot attached to the given element and using the configuration from the given array of PlotInfos
+ */
+Timeplot.create = function(elmt, plotInfos) {
+ return new Timeplot._Impl(elmt, plotInfos);
+};
+
+/**
+ * Create a PlotInfo configuration from the given map of params
+ */
+Timeplot.createPlotInfo = function(params) {
+ return {
+ id: ("id" in params) ? params.id : "p" + Math.round(Math.random() * 1000000),
+ dataSource: ("dataSource" in params) ? params.dataSource : null,
+ eventSource: ("eventSource" in params) ? params.eventSource : null,
+ timeGeometry: ("timeGeometry" in params) ? params.timeGeometry : new Timeplot.DefaultTimeGeometry(),
+ valueGeometry: ("valueGeometry" in params) ? params.valueGeometry : new Timeplot.DefaultValueGeometry(),
+ timeZone: ("timeZone" in params) ? params.timeZone : 0,
+ fillColor: ("fillColor" in params) ? ((params.fillColor == "string") ? new Timeplot.Color(params.fillColor) : params.fillColor) : null,
+ fillGradient: ("fillGradient" in params) ? params.fillGradient : true,
+ fillFrom: ("fillFrom" in params) ? params.fillFrom : Number.NEGATIVE_INFINITY,
+ lineColor: ("lineColor" in params) ? ((params.lineColor == "string") ? new Timeplot.Color(params.lineColor) : params.lineColor) : new Timeplot.Color("#606060"),
+ lineWidth: ("lineWidth" in params) ? params.lineWidth : 1.0,
+ dotRadius: ("dotRadius" in params) ? params.dotRadius : 2.0,
+ dotColor: ("dotColor" in params) ? params.dotColor : null,
+ eventLineWidth: ("eventLineWidth" in params) ? params.eventLineWidth : 1.0,
+ showValues: ("showValues" in params) ? params.showValues : false,
+ roundValues: ("roundValues" in params) ? params.roundValues : true,
+ valuesOpacity: ("valuesOpacity" in params) ? params.valuesOpacity : 75,
+ bubbleWidth: ("bubbleWidth" in params) ? params.bubbleWidth : 300,
+ bubbleHeight: ("bubbleHeight" in params) ? params.bubbleHeight : 200
+ };
+};
+
+// -------------------------------------------------------
+
+/**
+ * This is the implementation of the Timeplot object.
+ *
+ * @constructor
+ */
+Timeplot._Impl = function(elmt, plotInfos) {
+ this._id = "t" + Math.round(Math.random() * 1000000);
+ this._containerDiv = elmt;
+ this._plotInfos = plotInfos;
+ this._painters = {
+ background: [],
+ foreground: []
+ };
+ this._painter = null;
+ this._active = false;
+ this._upright = false;
+ this._initialize();
+};
+
+Timeplot._Impl.prototype = {
+
+ dispose: function() {
+ for (var i = 0; i < this._plots.length; i++) {
+ this._plots[i].dispose();
+ }
+ this._plots = null;
+ this._plotsInfos = null;
+ this._containerDiv.innerHTML = "";
+ },
+
+ /**
+ * Returns the main container div this timeplot is operating on.
+ */
+ getElement: function() {
+ return this._containerDiv;
+ },
+
+ /**
+ * Returns document this timeplot belongs to.
+ */
+ getDocument: function() {
+ return this._containerDiv.ownerDocument;
+ },
+
+ /**
+ * Append the given element to the timeplot DOM
+ */
+ add: function(div) {
+ this._containerDiv.appendChild(div);
+ },
+
+ /**
+ * Remove the given element from the timeplot DOM
+ */
+ remove: function(div) {
+ this._containerDiv.removeChild(div);
+ },
+
+ /**
+ * Add a painter to the timeplot
+ */
+ addPainter: function(layerName, painter) {
+ var layer = this._painters[layerName];
+ if (layer) {
+ for (var i = 0; i < layer.length; i++) {
+ if (layer[i].context._id == painter.context._id) {
+ return;
+ }
+ }
+ layer.push(painter);
+ }
+ },
+
+ /**
+ * Remove a painter from the timeplot
+ */
+ removePainter: function(layerName, painter) {
+ var layer = this._painters[layerName];
+ if (layer) {
+ for (var i = 0; i < layer.length; i++) {
+ if (layer[i].context._id == painter.context._id) {
+ layer.splice(i, 1);
+ break;
+ }
+ }
+ }
+ },
+
+ /**
+ * Get the width in pixels of the area occupied by the entire timeplot in the page
+ */
+ getWidth: function() {
+ return this._containerDiv.clientWidth;
+ },
+
+ /**
+ * Get the height in pixels of the area occupied by the entire timeplot in the page
+ */
+ getHeight: function() {
+ return this._containerDiv.clientHeight;
+ },
+
+ /**
+ * Get the drawing canvas associated with this timeplot
+ */
+ getCanvas: function() {
+ return this._canvas;
+ },
+
+ /**
+ * <p>Load the data from the given url into the given eventSource, using
+ * the given separator to parse the columns and preprocess it before parsing
+ * thru the optional filter function. The filter is useful for when
+ * the data is row-oriented but the format is not compatible with the
+ * one that Timeplot expects.</p>
+ *
+ * <p>Here is an example of a filter that changes dates in the form 'yyyy/mm/dd'
+ * in the required 'yyyy-mm-dd' format:
+ * <pre>var dataFilter = function(data) {
+ * for (var i = 0; i < data.length; i++) {
+ * var row = data[i];
+ * row[0] = row[0].replace(/\//g,"-");
+ * }
+ * return data;
+ * };</pre></p>
+ */
+ loadText: function(url, separator, eventSource, filter) {
+ if (this._active) {
+ var tp = this;
+
+ var fError = function(statusText, status, xmlhttp) {
+ alert("Failed to load data xml from " + url + "\n" + statusText);
+ tp.hideLoadingMessage();
+ };
+
+ var fDone = function(xmlhttp) {
+ try {
+ eventSource.loadText(xmlhttp.responseText, separator, url, filter);
+ } catch (e) {
+ SimileAjax.Debug.exception(e);
+ } finally {
+ tp.hideLoadingMessage();
+ }
+ };
+
+ this.showLoadingMessage();
+ window.setTimeout(function() { SimileAjax.XmlHttp.get(url, fError, fDone); }, 0);
+ }
+ },
+
+ /**
+ * Load event data from the given url into the given eventSource, using
+ * the Timeline XML event format.
+ */
+ loadXML: function(url, eventSource) {
+ if (this._active) {
+ var tl = this;
+
+ var fError = function(statusText, status, xmlhttp) {
+ alert("Failed to load data xml from " + url + "\n" + statusText);
+ tl.hideLoadingMessage();
+ };
+
+ var fDone = function(xmlhttp) {
+ try {
+ var xml = xmlhttp.responseXML;
+ if (!xml.documentElement && xmlhttp.responseStream) {
+ xml.load(xmlhttp.responseStream);
+ }
+ eventSource.loadXML(xml, url);
+ } finally {
+ tl.hideLoadingMessage();
+ }
+ };
+
+ this.showLoadingMessage();
+ window.setTimeout(function() { SimileAjax.XmlHttp.get(url, fError, fDone); }, 0);
+ }
+ },
+
+ /**
+ * Overlay a 'div' element filled with the given text and styles to this timeplot
+ * This is used to implement labels since canvas does not support drawing text.
+ */
+ putText: function(id, text, clazz, styles) {
+ var div = this.putDiv(id, "timeplot-div " + clazz, styles);
+ div.innerHTML = text;
+ return div;
+ },
+
+ /**
+ * Overlay a 'div' element, with the given class and the given styles to this timeplot.
+ * This is used for labels and horizontal and vertical grids.
+ */
+ putDiv: function(id, clazz, styles) {
+ var tid = this._id + "-" + id;
+ var div = document.getElementById(tid);
+ if (!div) {
+ var container = this._containerDiv.firstChild; // get the divs container
+ div = document.createElement("div");
+ div.setAttribute("id",tid);
+ container.appendChild(div);
+ }
+ div.setAttribute("class","timeplot-div " + clazz);
+ div.setAttribute("className","timeplot-div " + clazz);
+ this.placeDiv(div,styles);
+ return div;
+ },
+
+ /**
+ * AMO change
+ * Removes an overlayed 'div' element if it exists
+ */
+ removeDiv: function(id) {
+ var div = document.getElementById(this._id + "-" + id);
+
+ if (div) div.parentNode.removeChild(div);
+ },
+
+ /**
+ * Associate the given map of styles to the given element.
+ * In case such styles indicate position (left,right,top,bottom) correct them
+ * with the padding information so that they align to the 'internal' area
+ * of the timeplot.
+ */
+ placeDiv: function(div, styles) {
+ if (styles) {
+ for (style in styles) {
+ if (style == "left") {
+ styles[style] += this._paddingX;
+ styles[style] += "px";
+ } else if (style == "right") {
+ styles[style] += this._paddingX;
+ styles[style] += "px";
+ } else if (style == "top") {
+ styles[style] += this._paddingY;
+ styles[style] += "px";
+ } else if (style == "bottom") {
+ styles[style] += this._paddingY;
+ styles[style] += "px";
+ } else if (style == "width") {
+ if (styles[style] < 0) styles[style] = 0;
+ styles[style] += "px";
+ } else if (style == "height") {
+ if (styles[style] < 0) styles[style] = 0;
+ styles[style] += "px";
+ }
+ div.style[style] = styles[style];
+ }
+ }
+ },
+
+ /**
+ * AMO change
+ * Adds a new plot
+ * If update = true, adds a new plot to an already processed dataset
+ */
+ addPlot: function(plotInfo, update) {
+ if (update) this._plotInfos.push(plotInfo);
+
+ var timeplot = this;
+ var painter = {
+ onAddMany: function() { timeplot.update(); },
+ onClear: function() { timeplot.update(); }
+ }
+
+ var plot = new Timeplot.Plot(this, plotInfo);
+ var dataSource = plot.getDataSource();
+ if (dataSource) {
+ if (update) dataSource._process();
+ dataSource.addListener(painter);
+ }
+ this.addPainter("background", {
+ context: plot.getTimeGeometry(),
+ action: plot.getTimeGeometry().paint
+ });
+ this.addPainter("background", {
+ context: plot.getValueGeometry(),
+ action: plot.getValueGeometry().paint
+ });
+ this.addPainter("foreground", {
+ context: plot,
+ action: plot.paint
+ });
+ plot.initialize();
+ this._plots.push(plot);
+
+ if (update) this.update();
+
+ return true;
+ },
+
+ /**
+ * AMO change
+ * Removes a plot and repaints
+ */
+ removePlot: function(plotID) {
+ var removed = false;
+
+ if (this._plots) {
+ for (var i = 0; i < this._plots.length; i++) {
+ if (this._plots[i]._id == plotID) {
+ /* Removing only this painter preserves the value and time
+ axis. plot.dispose() isn't used to preserve dataSource in
+ case the plot is added back. */
+ this.removePainter("foreground", {context: this._plots[i]});
+
+ this.removeDiv(this._plots[i]._id + 'valueflag');
+ this.removeDiv(this._plots[i]._id + 'valueflagLineLeft');
+ this.removeDiv(this._plots[i]._id + 'valueflagLineRight');
+ this.removeDiv(this._plots[i]._id + 'valuepole');
+
+ this._plots.splice(i, 1);
+ removed = true;
+ }
+ }
+ }
+
+ if (this._plotInfos) {
+ for (i = 0; i < this._plotInfos.length; i++) {
+ if (this._plotInfos[i].id == plotID) {
+ this._plotInfos.splice(i, 1);
+ removed = true;
+ }
+ }
+ }
+
+ if (removed) this.update();
+
+ return removed;
+ },
+
+ /**
+ * return a {x,y} map with the location of the given element relative to the 'internal' area of the timeplot
+ * (that is, without the container padding)
+ */
+ locate: function(div) {
+ return {
+ x: div.offsetLeft - this._paddingX,
+ y: div.offsetTop - this._paddingY
+ }
+ },
+
+ /**
+ * Forces timeplot to re-evaluate the various value and time geometries
+ * associated with its plot layers and repaint accordingly. This should
+ * be invoked after the data in any of the data sources has been
+ * modified.
+ */
+ update: function() {
+ if (this._active) {
+ for (var i = 0; i < this._plots.length; i++) {
+ var plot = this._plots[i];
+ var dataSource = plot.getDataSource();
+ if (dataSource) {
+ var range = dataSource.getRange();
+ if (range) {
+ plot._valueGeometry.setRange(range);
+ plot._timeGeometry.setRange(range);
+ }
+ }
+ }
+ this.paint();
+ }
+ },
+
+ /**
+ * Forces timeplot to re-evaluate its own geometry, clear itself and paint.
+ * This should be used instead of paint() when you're not sure if the
+ * geometry of the page has changed or not.
+ */
+ repaint: function() {
+ if (this._active) {
+ this._prepareCanvas();
+ for (var i = 0; i < this._plots.length; i++) {
+ var plot = this._plots[i];
+ if (plot._timeGeometry) plot._timeGeometry.reset();
+ if (plot._valueGeometry) plot._valueGeometry.reset();
+ }
+ this.paint();
+ }
+ },
+
+ /**
+ * Calls all the painters that were registered to this timeplot and makes them
+ * paint the timeplot. This should be used only when you're sure that the geometry
+ * of the page hasn't changed.
+ * NOTE: painting is performed by a different thread and it's safe to call this
+ * function in bursts (as in mousemove or during window resizing
+ */
+ paint: function() {
+ if (this._active && this._painter == null) {
+ var timeplot = this;
+ this._painter = window.setTimeout(function() {
+ timeplot._clearCanvas();
+
+ var run = function(action,context) {
+ try {
+ if (context.setTimeplot) context.setTimeplot(timeplot);
+ action.apply(context,[]);
+ } catch (e) {
+ SimileAjax.Debug.exception(e);
+ }
+ }
+
+ var background = timeplot._painters.background;
+ for (var i = 0; i < background.length; i++) {
+ run(background[i].action, background[i].context);
+ }
+ var foreground = timeplot._painters.foreground;
+ for (var i = 0; i < foreground.length; i++) {
+ run(foreground[i].action, foreground[i].context);
+ }
+
+ timeplot._painter = null;
+ }, 20);
+ }
+ },
+
+ _clearCanvas: function() {
+ var canvas = this.getCanvas();
+ var ctx = canvas.getContext('2d');
+ ctx.clearRect(0,0,canvas.width,canvas.height);
+ },
+
+ _prepareCanvas: function() {
+ var canvas = this.getCanvas();
+
+ // using jQuery. note we calculate the average padding; if your
+ // padding settings are not symmetrical, the labels will be off
+ // since they expect to be centered on the canvas.
+ var con = $('#' + this._containerDiv.id);
+ this._paddingX = (parseInt(con.css('paddingLeft')) +
+ parseInt(con.css('paddingRight'))) / 2;
+ this._paddingY = (parseInt(con.css('paddingTop')) +
+ parseInt(con.css('paddingBottom'))) / 2;
+
+ canvas.width = this.getWidth() - (this._paddingX * 2);
+ canvas.height = this.getHeight() - (this._paddingY * 2);
+
+ var ctx = canvas.getContext('2d');
+ this._setUpright(ctx, canvas);
+ ctx.globalCompositeOperation = 'source-over';
+ },
+
+ _setUpright: function(ctx, canvas) {
+ // excanvas+IE requires this to be done only once, ever; actual canvas
+ // implementations reset and require this for each call to re-layout
+ if (!SimileAjax.Platform.browser.isIE) this._upright = false;
+ if (!this._upright) {
+ this._upright = true;
+ ctx.translate(0, canvas.height);
+ ctx.scale(1,-1);
+ }
+ },
+
+ _isBrowserSupported: function(canvas) {
+ var browser = SimileAjax.Platform.browser;
+ if ((canvas.getContext && window.getComputedStyle) ||
+ (browser.isIE && browser.majorVersion >= 6)) {
+ return true;
+ } else {
+ return false;
+ }
+ },
+
+ _initialize: function() {
+
+ // initialize the window manager (used to handle the popups)
+ // NOTE: this is a singleton and it's safe to call multiple times
+ SimileAjax.WindowManager.initialize();
+
+ var containerDiv = this._containerDiv;
+ var doc = containerDiv.ownerDocument;
+
+ // make sure the timeplot div has the right class
+ containerDiv.className = "timeplot-container " + containerDiv.className;
+
+ // clean it up if it contains some content
+ while (containerDiv.firstChild) {
+ containerDiv.removeChild(containerDiv.firstChild);
+ }
+
+ var canvas = doc.createElement("canvas");
+
+ if (this._isBrowserSupported(canvas)) {
+ // this is where we'll place the labels
+ var labels = doc.createElement("div");
+ containerDiv.appendChild(labels);
+
+ this._canvas = canvas;
+ canvas.className = "timeplot-canvas";
+ containerDiv.appendChild(canvas);
+ if(!canvas.getContext && G_vmlCanvasManager) {
+ canvas = G_vmlCanvasManager.initElement(this._canvas);
+ this._canvas = canvas;
+ }
+ this._prepareCanvas();
+
+ // inserting copyright and link to simile
+ var elmtCopyright = SimileAjax.Graphics.createTranslucentImage(Timeplot.urlPrefix + "images/copyright.png");
+ elmtCopyright.className = "timeplot-copyright";
+ elmtCopyright.title = "Timeplot (c) SIMILE - http://simile.mit.edu/timeplot/";
+ SimileAjax.DOM.registerEvent(elmtCopyright, "click", function() { window.location = "http://simile.mit.edu/timeplot/"; });
+ containerDiv.appendChild(elmtCopyright);
+
+ // creating painters
+ this._plots = [];
+ if (this._plotInfos) {
+ for (var i = 0; i < this._plotInfos.length; i++) {
+ this.addPlot(this._plotInfos[i]);
+ }
+ }
+
+ // creating loading UI
+ var message = SimileAjax.Graphics.createMessageBubble(doc);
+ message.containerDiv.className = "timeplot-message-container";
+ containerDiv.appendChild(message.containerDiv);
+
+ message.contentDiv.className = "timeplot-message";
+ message.contentDiv.innerHTML = "<img src='" + Timeplot.urlPrefix + "images/progress-running.gif' /> Loading...";
+
+ this.showLoadingMessage = function() { message.containerDiv.style.display = "block"; };
+ this.hideLoadingMessage = function() { message.containerDiv.style.display = "none"; };
+
+ this._active = true;
+
+ } else {
+
+ this._message = SimileAjax.Graphics.createMessageBubble(doc);
+ this._message.containerDiv.className = "timeplot-message-container";
+ this._message.containerDiv.style.top = "15%";
+ this._message.containerDiv.style.left = "20%";
+ this._message.containerDiv.style.right = "20%";
+ this._message.containerDiv.style.minWidth = "20em";
+ this._message.contentDiv.className = "timeplot-message";
+ this._message.contentDiv.innerHTML = "We're terribly sorry, but your browser is not currently supported by <a href='http://simile.mit.edu/timeplot/'>Timeplot</a>.<br><br> We are working on supporting it in the near future but, for now, see the <a href='http://simile.mit.edu/wiki/Timeplot_Limitations'>list of currently supported browsers</a>.";
+ this._message.containerDiv.style.display = "block";
+
+ containerDiv.appendChild(this._message.containerDiv);
+
+ }
+ }
+};
diff --git a/site/app/webroot/js/simile/timeplot/timeplot-api-amo-bundle.js b/site/app/webroot/js/simile/timeplot/timeplot-api-amo-bundle.js
new file mode 100644
index 0000000..55d636f
--- /dev/null
+++ b/site/app/webroot/js/simile/timeplot/timeplot-api-amo-bundle.js
@@ -0,0 +1,78 @@
+////////////////////////////// TIMEPLOT LOADER ////////////////////////////////
+(function() {
+
+ var local = true;
+
+ // Load Timeplot if it's not already loaded (after SimileAjax and Timeline)
+ var loadTimeplot = function() {
+
+ if (typeof window.Timeplot != "undefined") {
+ return;
+ }
+
+ window.Timeplot = {
+ loaded: false,
+ params: { bundle: true, autoCreate: true },
+ namespace: "http://simile.mit.edu/2007/06/timeplot#",
+ importers: {}
+ };
+
+ var locales = [ "en" ];
+
+ var defaultClientLocales = ("language" in navigator ? navigator.language : navigator.browserLanguage).split(";");
+ for (var l = 0; l < defaultClientLocales.length; l++) {
+ var locale = defaultClientLocales[l];
+ if (locale != "en") {
+ var segments = locale.split("-");
+ if (segments.length > 1 && segments[0] != "en") {
+ locales.push(segments[0]);
+ }
+ locales.push(locale);
+ }
+ }
+
+ var paramTypes = { bundle:Boolean, autoCreate:Boolean };
+
+ if (Timeplot.params.locale) { // ISO-639 language codes,
+ // optional ISO-3166 country codes (2 characters)
+ if (Timeplot.params.locale != "en") {
+ var segments = Timeplot.params.locale.split("-");
+ if (segments.length > 1 && segments[0] != "en") {
+ locales.push(segments[0]);
+ }
+ locales.push(Timeplot.params.locale);
+ }
+ }
+
+ var canvas = document.createElement("canvas");
+
+ window.SimileAjax_onLoad = function() {
+ //if (local && window.console.open) window.console.open();
+ if (Timeplot.params.callback) {
+ eval(Timeplot.params.callback + "()");
+ }
+ }
+
+ if (typeof Simile_urlPrefix == "string") {
+ Timeplot.urlPrefix = Simile_urlPrefix + '/timeplot/';
+ }
+
+ Timeplot.loaded = true;
+ };
+
+ // Load Timeline if it's not already loaded (after SimileAjax and before Timeplot)
+ var loadTimeline = function() {
+ if (typeof Timeline != "undefined") {
+ loadTimeplot();
+ } else {
+ window.SimileAjax_onLoad = loadTimeplot;
+ }
+ };
+
+ // Load SimileAjax if it's not already loaded
+ if (typeof SimileAjax == "undefined") {
+ window.SimileAjax_onLoad = loadTimeline;
+ } else {
+ loadTimeline();
+ }
+})();
diff --git a/site/app/webroot/js/simile/timeplot/timeplot-api.js b/site/app/webroot/js/simile/timeplot/timeplot-api.js
new file mode 100755
index 0000000..bde8b8a
--- /dev/null
+++ b/site/app/webroot/js/simile/timeplot/timeplot-api.js
@@ -0,0 +1,190 @@
+/*==================================================
+ * Simile Timeplot API
+ *
+ * Include Timeplot in your HTML file as follows:
+ * <script src="http://static.simile.mit.edu/timeplot/api/1.0/timeplot-api.js" type="text/javascript"></script>
+ *
+ *==================================================*/
+
+(function() {
+
+ var local = false;
+
+ // obtain local mode from the document URL
+ if (document.location.search.length > 0) {
+ var params = document.location.search.substr(1).split("&");
+ for (var i = 0; i < params.length; i++) {
+ if (params[i] == "local") {
+ local = true;
+ }
+ }
+ }
+
+ // obtain local mode from the script URL params attribute
+ if (!local) {
+ var heads = document.documentElement.getElementsByTagName("head");
+ for (var h = 0; h < heads.length; h++) {
+ var node = heads[h].firstChild;
+ while (node != null) {
+ if (node.nodeType == 1 && node.tagName.toLowerCase() == "script") {
+ var url = node.src;
+ if (url.indexOf("timeplot-api") >= 0) {
+ local = (url.indexOf("local") >= 0);
+ }
+ }
+ node = node.nextSibling;
+ }
+ }
+ }
+
+ // Load Timeplot if it's not already loaded (after SimileAjax and Timeline)
+ var loadTimeplot = function() {
+
+ if (typeof window.Timeplot != "undefined") {
+ return;
+ }
+
+ window.Timeplot = {
+ loaded: false,
+ params: { bundle: true, autoCreate: true },
+ namespace: "http://simile.mit.edu/2007/06/timeplot#",
+ importers: {}
+ };
+
+ var javascriptFiles = [
+ "timeplot.js",
+ "plot.js",
+ "sources.js",
+ "geometry.js",
+ "color.js",
+ "math.js",
+ "processor.js"
+ ];
+ var cssFiles = [
+ "timeplot.css"
+ ];
+
+ var locales = [ "en" ];
+
+ var defaultClientLocales = ("language" in navigator ? navigator.language : navigator.browserLanguage).split(";");
+ for (var l = 0; l < defaultClientLocales.length; l++) {
+ var locale = defaultClientLocales[l];
+ if (locale != "en") {
+ var segments = locale.split("-");
+ if (segments.length > 1 && segments[0] != "en") {
+ locales.push(segments[0]);
+ }
+ locales.push(locale);
+ }
+ }
+
+ var paramTypes = { bundle:Boolean, js:Array, css:Array, autoCreate:Boolean };
+ if (typeof Simile_urlPrefix == "string") {
+ Timeplot.urlPrefix = Simile_urlPrefix + '/timeplot/';
+ if ("Timeplot_parameters" in window) {
+ SimileAjax.parseURLParameters(Timeplot_parameters, Timeplot.params, paramTypes);
+ }
+ } else {
+ var url = SimileAjax.findScript(document, "/timeplot-api.js");
+ if (url == null) {
+ Timeplot.error = new Error("Failed to derive URL prefix for Simile Timeplot API code files");
+ return;
+ }
+ Timeplot.urlPrefix = url.substr(0, url.indexOf("timeplot-api.js"));
+
+ SimileAjax.parseURLParameters(url, Timeplot.params, paramTypes);
+ }
+
+ if (Timeplot.params.locale) { // ISO-639 language codes,
+ // optional ISO-3166 country codes (2 characters)
+ if (Timeplot.params.locale != "en") {
+ var segments = Timeplot.params.locale.split("-");
+ if (segments.length > 1 && segments[0] != "en") {
+ locales.push(segments[0]);
+ }
+ locales.push(Timeplot.params.locale);
+ }
+ }
+// AMO change
+ var timeplotURLPrefix = (local) ? Simile_urlPrefix + "/timeplot/" : Timeplot.urlPrefix;
+
+ /*if (local && !("console" in window)) {
+ var firebug = [ timeplotURLPrefix + "lib/firebug/firebug.js" ];
+ SimileAjax.includeJavascriptFiles(document, "", firebug);
+ }*/
+
+ var canvas = document.createElement("canvas");
+
+ if (!canvas.getContext) {
+ var excanvas = [ timeplotURLPrefix + "lib/excanvas.js" ];
+ SimileAjax.includeJavascriptFiles(document, "", excanvas);
+ }
+
+ var scriptURLs = Timeplot.params.js || [];
+ var cssURLs = Timeplot.params.css || [];
+
+ // Core scripts and styles
+ if (Timeplot.params.bundle && !local) {
+ scriptURLs.push(timeplotURLPrefix + "timeplot-bundle.js");
+ cssURLs.push(timeplotURLPrefix + "timeplot-bundle.css");
+ } else {
+ SimileAjax.prefixURLs(scriptURLs, timeplotURLPrefix + "scripts/", javascriptFiles);
+ SimileAjax.prefixURLs(cssURLs, timeplotURLPrefix + "styles/", cssFiles);
+ }
+
+ // Localization
+ //for (var i = 0; i < locales.length; i++) {
+ // scriptURLs.push(Timeplot.urlPrefix + "locales/" + locales[i] + "/locale.js");
+ //};
+
+ window.SimileAjax_onLoad = function() {
+ //if (local && window.console.open) window.console.open();
+ if (Timeplot.params.callback) {
+ eval(Timeplot.params.callback + "()");
+ }
+ }
+
+ SimileAjax.includeJavascriptFiles(document, "", scriptURLs);
+ SimileAjax.includeCssFiles(document, "", cssURLs);
+ Timeplot.loaded = true;
+ };
+
+ // Load Timeline if it's not already loaded (after SimileAjax and before Timeplot)
+ var loadTimeline = function() {
+ if (typeof Timeline != "undefined") {
+ loadTimeplot();
+ } else {
+// AMO change
+ var timelineURL = Simile_urlPrefix + "/timeline/timeline-api.js?bundle=false";
+ window.SimileAjax_onLoad = loadTimeplot;
+ SimileAjax.includeJavascriptFile(document, timelineURL);
+ }
+ };
+
+ // Load SimileAjax if it's not already loaded
+ if (typeof SimileAjax == "undefined") {
+ window.SimileAjax_onLoad = loadTimeline;
+ // AMO change
+ var url = Simile_urlPrefix + "/ajax/simile-ajax-api.js?bundle=false";
+
+ var createScriptElement = function() {
+ var script = document.createElement("script");
+ script.type = "text/javascript";
+ script.language = "JavaScript";
+ script.src = url;
+ document.getElementsByTagName("head")[0].appendChild(script);
+ }
+
+ if (document.body == null) {
+ try {
+ document.write("<script src='" + url + "' type='text/javascript'></script>");
+ } catch (e) {
+ createScriptElement();
+ }
+ } else {
+ createScriptElement();
+ }
+ } else {
+ loadTimeline();
+ }
+})();
diff --git a/site/app/webroot/js/simile/timeplot/timeplot-bundle.css b/site/app/webroot/js/simile/timeplot/timeplot-bundle.css
new file mode 100755
index 0000000..133ac2f
--- /dev/null
+++ b/site/app/webroot/js/simile/timeplot/timeplot-bundle.css
@@ -0,0 +1,95 @@
+.timeplot-container {
+ overflow: hidden;
+ position: relative;
+ height: 200px;
+ border: 1px solid #ccc;
+ padding: 12px 14px;
+}
+
+.timeplot-copyright {
+ position: absolute;
+ top: 0px;
+ left: 0px;
+ z-index: 1000;
+ cursor: pointer;
+}
+
+.timeplot-message-container {
+ position: absolute;
+ top: 30%;
+ left: 35%;
+ right: 35%;
+ max-width: 400px;
+ z-index: 1000;
+ display: none;
+}
+.timeplot-message {
+ font-size: 120%;
+ font-weight: bold;
+ text-align: center;
+}
+.timeplot-message img {
+ vertical-align: middle;
+}
+
+.timeplot-div {
+ position: absolute;
+}
+
+.timeplot-grid-label {
+ font-size: 9px;
+}
+
+.timeplot-event-box {
+ cursor: pointer;
+}
+
+.timeplot-event-box-highlight {
+ border: 1px solid #FFB03B;
+}
+
+.timeplot-valueflag {
+ display: none;
+ border: 1px solid #FFB02D;
+ padding: 2px 4px;
+ text-align: center;
+ background-color: #FFE57F;
+ font-weight: bold;
+ z-index: 1000;
+}
+
+.timeplot-valueflag-line {
+ display: none;
+ width: 14px;
+ height: 14px;
+ z-index: 1000;
+}
+
+.timeplot-timeflag {
+ display: none;
+ border: 1px solid #FFB02D;
+ padding: 2px 4px;
+ text-align: center;
+ background-color: #FFE57F;
+ font-weight: bold;
+ z-index: 1000;
+}
+
+.timeplot-timeflag-triangle {
+ display: none;
+ width: 11px;
+ height: 6px;
+ z-index: 1001;
+}
+
+.timeplot-valueflag-pole {
+ display: none;
+ border-left: 1px solid #FFB02D;
+ z-index: 999;
+}
+
+.timeplot-lens {
+ display: none;
+ border: 1px solid #FFB02D;
+ z-index: 998;
+}
diff --git a/site/app/webroot/js/simile/timeplot/timeplot-bundle.js b/site/app/webroot/js/simile/timeplot/timeplot-bundle.js
new file mode 100755
index 0000000..4b2eb71
--- /dev/null
+++ b/site/app/webroot/js/simile/timeplot/timeplot-bundle.js
@@ -0,0 +1,2253 @@
+
+
+/* timeplot.js */
+
+
+
+Timeline.Debug=SimileAjax.Debug;
+var log=SimileAjax.Debug.log;
+
+
+Object.extend=function(destination,source){
+for(var property in source){
+destination[property]=source[property];
+}
+return destination;
+}
+
+
+
+
+Timeplot.create=function(elmt,plotInfos){
+return new Timeplot._Impl(elmt,plotInfos);
+};
+
+
+Timeplot.createPlotInfo=function(params){
+return{
+id:("id"in params)?params.id:"p"+Math.round(Math.random()*1000000),
+dataSource:("dataSource"in params)?params.dataSource:null,
+eventSource:("eventSource"in params)?params.eventSource:null,
+timeGeometry:("timeGeometry"in params)?params.timeGeometry:new Timeplot.DefaultTimeGeometry(),
+valueGeometry:("valueGeometry"in params)?params.valueGeometry:new Timeplot.DefaultValueGeometry(),
+timeZone:("timeZone"in params)?params.timeZone:0,
+fillColor:("fillColor"in params)?((params.fillColor=="string")?new Timeplot.Color(params.fillColor):params.fillColor):null,
+fillGradient:("fillGradient"in params)?params.fillGradient:true,
+fillFrom:("fillFrom"in params)?params.fillFrom:Number.NEGATIVE_INFINITY,
+lineColor:("lineColor"in params)?((params.lineColor=="string")?new Timeplot.Color(params.lineColor):params.lineColor):new Timeplot.Color("#606060"),
+lineWidth:("lineWidth"in params)?params.lineWidth:1.0,
+dotRadius:("dotRadius"in params)?params.dotRadius:2.0,
+dotColor:("dotColor"in params)?params.dotColor:null,
+eventLineWidth:("eventLineWidth"in params)?params.eventLineWidth:1.0,
+showValues:("showValues"in params)?params.showValues:false,
+roundValues:("roundValues"in params)?params.roundValues:true,
+valuesOpacity:("valuesOpacity"in params)?params.valuesOpacity:75,
+bubbleWidth:("bubbleWidth"in params)?params.bubbleWidth:300,
+bubbleHeight:("bubbleHeight"in params)?params.bubbleHeight:200
+};
+};
+
+
+
+
+Timeplot._Impl=function(elmt,plotInfos){
+this._id="t"+Math.round(Math.random()*1000000);
+this._containerDiv=elmt;
+this._plotInfos=plotInfos;
+this._painters={
+background:[],
+foreground:[]
+};
+this._painter=null;
+this._active=false;
+this._upright=false;
+this._initialize();
+};
+
+Timeplot._Impl.prototype={
+
+dispose:function(){
+for(var i=0;i<this._plots.length;i++){
+this._plots[i].dispose();
+}
+this._plots=null;
+this._plotsInfos=null;
+this._containerDiv.innerHTML="";
+},
+
+
+getElement:function(){
+return this._containerDiv;
+},
+
+
+getDocument:function(){
+return this._containerDiv.ownerDocument;
+},
+
+
+add:function(div){
+this._containerDiv.appendChild(div);
+},
+
+
+remove:function(div){
+this._containerDiv.removeChild(div);
+},
+
+
+addPainter:function(layerName,painter){
+var layer=this._painters[layerName];
+if(layer){
+for(var i=0;i<layer.length;i++){
+if(layer[i].context._id==painter.context._id){
+return;
+}
+}
+layer.push(painter);
+}
+},
+
+
+removePainter:function(layerName,painter){
+var layer=this._painters[layerName];
+if(layer){
+for(var i=0;i<layer.length;i++){
+if(layer[i].context._id==painter.context._id){
+layer.splice(i,1);
+break;
+}
+}
+}
+},
+
+
+getWidth:function(){
+return this._containerDiv.clientWidth;
+},
+
+
+getHeight:function(){
+return this._containerDiv.clientHeight;
+},
+
+
+getCanvas:function(){
+return this._canvas;
+},
+
+
+loadText:function(url,separator,eventSource,filter){
+if(this._active){
+var tp=this;
+
+var fError=function(statusText,status,xmlhttp){
+alert("Failed to load data xml from "+url+"\n"+statusText);
+tp.hideLoadingMessage();
+};
+
+var fDone=function(xmlhttp){
+try{
+eventSource.loadText(xmlhttp.responseText,separator,url,filter);
+}catch(e){
+SimileAjax.Debug.exception(e);
+}finally{
+tp.hideLoadingMessage();
+}
+};
+
+this.showLoadingMessage();
+window.setTimeout(function(){SimileAjax.XmlHttp.get(url,fError,fDone);},0);
+}
+},
+
+
+loadXML:function(url,eventSource){
+if(this._active){
+var tl=this;
+
+var fError=function(statusText,status,xmlhttp){
+alert("Failed to load data xml from "+url+"\n"+statusText);
+tl.hideLoadingMessage();
+};
+
+var fDone=function(xmlhttp){
+try{
+var xml=xmlhttp.responseXML;
+if(!xml.documentElement&&xmlhttp.responseStream){
+xml.load(xmlhttp.responseStream);
+}
+eventSource.loadXML(xml,url);
+}finally{
+tl.hideLoadingMessage();
+}
+};
+
+this.showLoadingMessage();
+window.setTimeout(function(){SimileAjax.XmlHttp.get(url,fError,fDone);},0);
+}
+},
+
+
+putText:function(id,text,clazz,styles){
+var div=this.putDiv(id,"timeplot-div "+clazz,styles);
+div.innerHTML=text;
+return div;
+},
+
+
+putDiv:function(id,clazz,styles){
+var tid=this._id+"-"+id;
+var div=document.getElementById(tid);
+if(!div){
+var container=this._containerDiv.firstChild;
+div=document.createElement("div");
+div.setAttribute("id",tid);
+container.appendChild(div);
+}
+div.setAttribute("class","timeplot-div "+clazz);
+div.setAttribute("className","timeplot-div "+clazz);
+this.placeDiv(div,styles);
+return div;
+},
+
+
+placeDiv:function(div,styles){
+if(styles){
+for(style in styles){
+if(style=="left"){
+styles[style]+=this._paddingX;
+styles[style]+="px";
+}else if(style=="right"){
+styles[style]+=this._paddingX;
+styles[style]+="px";
+}else if(style=="top"){
+styles[style]+=this._paddingY;
+styles[style]+="px";
+}else if(style=="bottom"){
+styles[style]+=this._paddingY;
+styles[style]+="px";
+}else if(style=="width"){
+if(styles[style]<0)styles[style]=0;
+styles[style]+="px";
+}else if(style=="height"){
+if(styles[style]<0)styles[style]=0;
+styles[style]+="px";
+}
+div.style[style]=styles[style];
+}
+}
+},
+
+
+locate:function(div){
+return{
+x:div.offsetLeft-this._paddingX,
+y:div.offsetTop-this._paddingY
+}
+},
+
+
+update:function(){
+if(this._active){
+for(var i=0;i<this._plots.length;i++){
+var plot=this._plots[i];
+var dataSource=plot.getDataSource();
+if(dataSource){
+var range=dataSource.getRange();
+if(range){
+plot._valueGeometry.setRange(range);
+plot._timeGeometry.setRange(range);
+}
+}
+}
+this.paint();
+}
+},
+
+
+repaint:function(){
+if(this._active){
+this._prepareCanvas();
+for(var i=0;i<this._plots.length;i++){
+var plot=this._plots[i];
+if(plot._timeGeometry)plot._timeGeometry.reset();
+if(plot._valueGeometry)plot._valueGeometry.reset();
+}
+this.paint();
+}
+},
+
+
+paint:function(){
+if(this._active&&this._painter==null){
+var timeplot=this;
+this._painter=window.setTimeout(function(){
+timeplot._clearCanvas();
+
+var run=function(action,context){
+try{
+if(context.setTimeplot)context.setTimeplot(timeplot);
+action.apply(context,[]);
+}catch(e){
+SimileAjax.Debug.exception(e);
+}
+}
+
+var background=timeplot._painters.background;
+for(var i=0;i<background.length;i++){
+run(background[i].action,background[i].context);
+}
+var foreground=timeplot._painters.foreground;
+for(var i=0;i<foreground.length;i++){
+run(foreground[i].action,foreground[i].context);
+}
+
+timeplot._painter=null;
+},20);
+}
+},
+
+_clearCanvas:function(){
+var canvas=this.getCanvas();
+var ctx=canvas.getContext('2d');
+ctx.clearRect(0,0,canvas.width,canvas.height);
+},
+
+_prepareCanvas:function(){
+var canvas=this.getCanvas();
+
+
+
+
+var con=$('#'+this._containerDiv.id);
+this._paddingX=(parseInt(con.css('paddingLeft'))+
+parseInt(con.css('paddingRight')))/2;
+this._paddingY=(parseInt(con.css('paddingTop'))+
+parseInt(con.css('paddingBottom')))/2;
+
+canvas.width=this.getWidth()-(this._paddingX*2);
+canvas.height=this.getHeight()-(this._paddingY*2);
+
+var ctx=canvas.getContext('2d');
+this._setUpright(ctx,canvas);
+ctx.globalCompositeOperation='source-over';
+},
+
+_setUpright:function(ctx,canvas){
+
+
+if(!SimileAjax.Platform.browser.isIE)this._upright=false;
+if(!this._upright){
+this._upright=true;
+ctx.translate(0,canvas.height);
+ctx.scale(1,-1);
+}
+},
+
+_isBrowserSupported:function(canvas){
+var browser=SimileAjax.Platform.browser;
+if((canvas.getContext&&window.getComputedStyle)||
+(browser.isIE&&browser.majorVersion>=6)){
+return true;
+}else{
+return false;
+}
+},
+
+_initialize:function(){
+
+
+
+SimileAjax.WindowManager.initialize();
+
+var containerDiv=this._containerDiv;
+var doc=containerDiv.ownerDocument;
+
+
+containerDiv.className="timeplot-container "+containerDiv.className;
+
+
+while(containerDiv.firstChild){
+containerDiv.removeChild(containerDiv.firstChild);
+}
+
+var canvas=doc.createElement("canvas");
+
+if(this._isBrowserSupported(canvas)){
+
+var labels=doc.createElement("div");
+containerDiv.appendChild(labels);
+
+this._canvas=canvas;
+canvas.className="timeplot-canvas";
+containerDiv.appendChild(canvas);
+if(!canvas.getContext&&G_vmlCanvasManager){
+canvas=G_vmlCanvasManager.initElement(this._canvas);
+this._canvas=canvas;
+}
+this._prepareCanvas();
+
+
+var elmtCopyright=SimileAjax.Graphics.createTranslucentImage(Timeplot.urlPrefix+"images/copyright.png");
+elmtCopyright.className="timeplot-copyright";
+elmtCopyright.title="Timeplot (c) SIMILE - http://simile.mit.edu/timeplot/";
+SimileAjax.DOM.registerEvent(elmtCopyright,"click",function(){window.location="http://simile.mit.edu/timeplot/";});
+containerDiv.appendChild(elmtCopyright);
+
+var timeplot=this;
+var painter={
+onAddMany:function(){timeplot.update();},
+onClear:function(){timeplot.update();}
+}
+
+
+this._plots=[];
+if(this._plotInfos){
+for(var i=0;i<this._plotInfos.length;i++){
+var plot=new Timeplot.Plot(this,this._plotInfos[i]);
+var dataSource=plot.getDataSource();
+if(dataSource){
+dataSource.addListener(painter);
+}
+this.addPainter("background",{
+context:plot.getTimeGeometry(),
+action:plot.getTimeGeometry().paint
+});
+this.addPainter("background",{
+context:plot.getValueGeometry(),
+action:plot.getValueGeometry().paint
+});
+this.addPainter("foreground",{
+context:plot,
+action:plot.paint
+});
+this._plots.push(plot);
+plot.initialize();
+}
+}
+
+
+var message=SimileAjax.Graphics.createMessageBubble(doc);
+message.containerDiv.className="timeplot-message-container";
+containerDiv.appendChild(message.containerDiv);
+
+message.contentDiv.className="timeplot-message";
+message.contentDiv.innerHTML="<img src='"+Timeplot.urlPrefix+"images/progress-running.gif' /> Loading...";
+
+this.showLoadingMessage=function(){message.containerDiv.style.display="block";};
+this.hideLoadingMessage=function(){message.containerDiv.style.display="none";};
+
+this._active=true;
+
+}else{
+
+this._message=SimileAjax.Graphics.createMessageBubble(doc);
+this._message.containerDiv.className="timeplot-message-container";
+this._message.containerDiv.style.top="15%";
+this._message.containerDiv.style.left="20%";
+this._message.containerDiv.style.right="20%";
+this._message.containerDiv.style.minWidth="20em";
+this._message.contentDiv.className="timeplot-message";
+this._message.contentDiv.innerHTML="We're terribly sorry, but your browser is not currently supported by <a href='http://simile.mit.edu/timeplot/'>Timeplot</a>.<br><br> We are working on supporting it in the near future but, for now, see the <a href='http://simile.mit.edu/wiki/Timeplot_Limitations'>list of currently supported browsers</a>.";
+this._message.containerDiv.style.display="block";
+
+containerDiv.appendChild(this._message.containerDiv);
+
+}
+}
+};
+
+
+/* plot.js */
+
+
+
+
+Timeplot.Plot=function(timeplot,plotInfo){
+this._timeplot=timeplot;
+this._canvas=timeplot.getCanvas();
+this._plotInfo=plotInfo;
+this._id=plotInfo.id;
+this._timeGeometry=plotInfo.timeGeometry;
+this._valueGeometry=plotInfo.valueGeometry;
+this._showValues=plotInfo.showValues;
+this._theme=new Timeline.getDefaultTheme();
+this._dataSource=plotInfo.dataSource;
+this._eventSource=plotInfo.eventSource;
+this._bubble=null;
+};
+
+Timeplot.Plot.prototype={
+
+
+initialize:function(){
+if(this._showValues&&this._dataSource&&this._dataSource.getValue){
+this._timeFlag=this._timeplot.putDiv("timeflag","timeplot-timeflag");
+this._valueFlag=this._timeplot.putDiv(this._id+"valueflag","timeplot-valueflag");
+this._valueFlagLineLeft=this._timeplot.putDiv(this._id+"valueflagLineLeft","timeplot-valueflag-line");
+this._valueFlagLineRight=this._timeplot.putDiv(this._id+"valueflagLineRight","timeplot-valueflag-line");
+if(!this._valueFlagLineLeft.firstChild){
+this._valueFlagLineLeft.appendChild(SimileAjax.Graphics.createTranslucentImage(Timeplot.urlPrefix+"images/line_left.png"));
+this._valueFlagLineRight.appendChild(SimileAjax.Graphics.createTranslucentImage(Timeplot.urlPrefix+"images/line_right.png"));
+}
+this._valueFlagPole=this._timeplot.putDiv(this._id+"valuepole","timeplot-valueflag-pole");
+
+var opacity=this._plotInfo.valuesOpacity;
+
+SimileAjax.Graphics.setOpacity(this._timeFlag,opacity);
+SimileAjax.Graphics.setOpacity(this._valueFlag,opacity);
+SimileAjax.Graphics.setOpacity(this._valueFlagLineLeft,opacity);
+SimileAjax.Graphics.setOpacity(this._valueFlagLineRight,opacity);
+SimileAjax.Graphics.setOpacity(this._valueFlagPole,opacity);
+
+var plot=this;
+
+var mouseOverHandler=function(elmt,evt,target){
+plot._valueFlag.style.display="block";
+mouseMoveHandler(elmt,evt,target);
+}
+
+var day=24*60*60*1000;
+var month=30*day;
+
+var mouseMoveHandler=function(elmt,evt,target){
+if(typeof SimileAjax!="undefined"){
+var c=plot._canvas;
+var x=Math.round(SimileAjax.DOM.getEventRelativeCoordinates(evt,plot._canvas).x);
+if(x>c.width)x=c.width;
+if(isNaN(x)||x<0)x=0;
+var t=plot._timeGeometry.fromScreen(x);
+if(t==0){
+plot._valueFlag.style.display="none";
+return;
+}
+
+var v=plot._dataSource.getValue(t);
+if(plot._plotInfo.roundValues)v=Math.round(v);
+plot._valueFlag.innerHTML=new String(v);
+var d=new Date(t);
+var p=plot._timeGeometry.getPeriod();
+if(p<day){
+plot._timeFlag.innerHTML=d.toLocaleTimeString();
+}else if(p>month){
+plot._timeFlag.innerHTML=d.toLocaleDateString();
+}else{
+plot._timeFlag.innerHTML=d.toLocaleString();
+}
+
+var tw=plot._timeFlag.clientWidth;
+var th=plot._timeFlag.clientHeight;
+var tdw=Math.round(tw/2);
+var vw=plot._valueFlag.clientWidth;
+var vh=plot._valueFlag.clientHeight;
+var y=plot._valueGeometry.toScreen(v);
+
+if(x+tdw>c.width){
+var tx=c.width-tdw;
+}else if(x-tdw<0){
+var tx=tdw;
+}else{
+var tx=x;
+}
+
+if(plot._timeGeometry._timeValuePosition=="top"){
+plot._timeplot.placeDiv(plot._valueFlagPole,{
+left:x,
+top:th-5,
+height:c.height-y-th+6,
+display:"block"
+});
+plot._timeplot.placeDiv(plot._timeFlag,{
+left:tx-tdw,
+top:-6,
+display:"block"
+});
+}else{
+plot._timeplot.placeDiv(plot._valueFlagPole,{
+left:x,
+bottom:th-5,
+height:y-th+6,
+display:"block"
+});
+plot._timeplot.placeDiv(plot._timeFlag,{
+left:tx-tdw,
+bottom:-6,
+display:"block"
+});
+}
+
+if(x+vw+14>c.width&&y+vh+4>c.height){
+plot._valueFlagLineLeft.style.display="none";
+plot._timeplot.placeDiv(plot._valueFlagLineRight,{
+left:x-14,
+bottom:y-14,
+display:"block"
+});
+plot._timeplot.placeDiv(plot._valueFlag,{
+left:x-vw-13,
+bottom:y-vh-13,
+display:"block"
+});
+}else if(x+vw+14>c.width&&y+vh+4<c.height){
+plot._valueFlagLineRight.style.display="none";
+plot._timeplot.placeDiv(plot._valueFlagLineLeft,{
+left:x-14,
+bottom:y,
+display:"block"
+});
+plot._timeplot.placeDiv(plot._valueFlag,{
+left:x-vw-13,
+bottom:y+13,
+display:"block"
+});
+}else if(x+vw+14<c.width&&y+vh+4>c.height){
+plot._valueFlagLineRight.style.display="none";
+plot._timeplot.placeDiv(plot._valueFlagLineLeft,{
+left:x,
+bottom:y-13,
+display:"block"
+});
+plot._timeplot.placeDiv(plot._valueFlag,{
+left:x+13,
+bottom:y-13,
+display:"block"
+});
+}else{
+plot._valueFlagLineLeft.style.display="none";
+plot._timeplot.placeDiv(plot._valueFlagLineRight,{
+left:x,
+bottom:y,
+display:"block"
+});
+plot._timeplot.placeDiv(plot._valueFlag,{
+left:x+13,
+bottom:y+13,
+display:"block"
+});
+}
+}
+}
+
+var timeplotElement=this._timeplot.getElement();
+SimileAjax.DOM.registerEvent(timeplotElement,"mouseover",mouseOverHandler);
+SimileAjax.DOM.registerEvent(timeplotElement,"mousemove",mouseMoveHandler);
+}
+},
+
+
+dispose:function(){
+if(this._dataSource){
+this._dataSource.removeListener(this._paintingListener);
+this._paintingListener=null;
+this._dataSource.dispose();
+this._dataSource=null;
+}
+},
+
+
+getDataSource:function(){
+return(this._dataSource)?this._dataSource:this._eventSource;
+},
+
+
+getTimeGeometry:function(){
+return this._timeGeometry;
+},
+
+
+getValueGeometry:function(){
+return this._valueGeometry;
+},
+
+
+paint:function(){
+var ctx=this._canvas.getContext('2d');
+
+ctx.lineWidth=this._plotInfo.lineWidth;
+ctx.lineJoin='miter';
+
+if(this._dataSource){
+if(this._plotInfo.fillColor){
+if(this._plotInfo.fillGradient){
+var gradient=ctx.createLinearGradient(0,this._canvas.height,0,0);
+gradient.addColorStop(0,this._plotInfo.fillColor.toString());
+gradient.addColorStop(0.5,this._plotInfo.fillColor.toString());
+gradient.addColorStop(1,'rgba(255,255,255,0)');
+
+ctx.fillStyle=gradient;
+}else{
+ctx.fillStyle=this._plotInfo.fillColor.toString();
+}
+
+ctx.beginPath();
+ctx.moveTo(0,0);
+this._plot(function(x,y){
+ctx.lineTo(x,y);
+});
+if(this._plotInfo.fillFrom==Number.NEGATIVE_INFINITY){
+ctx.lineTo(this._canvas.width,0);
+}else if(this._plotInfo.fillFrom==Number.POSITIVE_INFINITY){
+ctx.lineTo(this._canvas.width,this._canvas.height);
+ctx.lineTo(0,this._canvas.height);
+}else{
+ctx.lineTo(this._canvas.width,this._valueGeometry.toScreen(this._plotInfo.fillFrom));
+ctx.lineTo(0,this._valueGeometry.toScreen(this._plotInfo.fillFrom));
+}
+ctx.fill();
+}
+
+if(this._plotInfo.lineColor){
+ctx.strokeStyle=this._plotInfo.lineColor.toString();
+ctx.beginPath();
+var first=true;
+this._plot(function(x,y){
+if(first){
+first=false;
+ctx.moveTo(x,y);
+}
+ctx.lineTo(x,y);
+});
+ctx.stroke();
+}
+
+if(this._plotInfo.dotColor){
+ctx.fillStyle=this._plotInfo.dotColor.toString();
+var r=this._plotInfo.dotRadius;
+this._plot(function(x,y){
+ctx.beginPath();
+ctx.arc(x,y,r,0,2*Math.PI,true);
+ctx.fill();
+});
+}
+}
+
+if(this._eventSource){
+var gradient=ctx.createLinearGradient(0,0,0,this._canvas.height);
+gradient.addColorStop(1,'rgba(255,255,255,0)');
+
+ctx.strokeStyle=gradient;
+ctx.fillStyle=gradient;
+ctx.lineWidth=this._plotInfo.eventLineWidth;
+ctx.lineJoin='miter';
+
+var i=this._eventSource.getAllEventIterator();
+while(i.hasNext()){
+var event=i.next();
+var color=event.getColor();
+color=(color)?new Timeplot.Color(color):this._plotInfo.lineColor;
+var eventStart=event.getStart().getTime();
+var eventEnd=event.getEnd().getTime();
+if(eventStart==eventEnd){
+var c=color.toString();
+gradient.addColorStop(0,c);
+var start=this._timeGeometry.toScreen(eventStart);
+start=Math.floor(start)+0.5;
+var end=start;
+ctx.beginPath();
+ctx.moveTo(start,0);
+ctx.lineTo(start,this._canvas.height);
+ctx.stroke();
+var x=start-4;
+var w=7;
+}else{
+var c=color.toString(0.5);
+gradient.addColorStop(0,c);
+var start=this._timeGeometry.toScreen(eventStart);
+start=Math.floor(start)+0.5;
+var end=this._timeGeometry.toScreen(eventEnd);
+end=Math.floor(end)+0.5;
+ctx.fillRect(start,0,end-start,this._canvas.height);
+var x=start;
+var w=end-start-1;
+}
+
+var div=this._timeplot.putDiv(event.getID(),"timeplot-event-box",{
+left:Math.round(x),
+width:Math.round(w),
+top:0,
+height:this._canvas.height-1
+});
+
+var plot=this;
+var clickHandler=function(event){
+return function(elmt,evt,target){
+var doc=plot._timeplot.getDocument();
+plot._closeBubble();
+var coords=SimileAjax.DOM.getEventPageCoordinates(evt);
+var elmtCoords=SimileAjax.DOM.getPageCoordinates(elmt);
+plot._bubble=SimileAjax.Graphics.createBubbleForPoint(coords.x,elmtCoords.top+plot._canvas.height,plot._plotInfo.bubbleWidth,plot._plotInfo.bubbleHeight,"bottom");
+event.fillInfoBubble(plot._bubble.content,plot._theme,plot._timeGeometry.getLabeler());
+}
+};
+var mouseOverHandler=function(elmt,evt,target){
+elmt.oldClass=elmt.className;
+elmt.className=elmt.className+" timeplot-event-box-highlight";
+};
+var mouseOutHandler=function(elmt,evt,target){
+elmt.className=elmt.oldClass;
+elmt.oldClass=null;
+}
+
+if(!div.instrumented){
+SimileAjax.DOM.registerEvent(div,"click",clickHandler(event));
+SimileAjax.DOM.registerEvent(div,"mouseover",mouseOverHandler);
+SimileAjax.DOM.registerEvent(div,"mouseout",mouseOutHandler);
+div.instrumented=true;
+}
+}
+}
+},
+
+_plot:function(f){
+var data=this._dataSource.getData();
+if(data){
+var times=data.times;
+var values=data.values;
+var T=times.length;
+for(var t=0;t<T;t++){
+var x=this._timeGeometry.toScreen(times[t]);
+var y=this._valueGeometry.toScreen(values[t]);
+f(x,y);
+}
+}
+},
+
+_closeBubble:function(){
+if(this._bubble!=null){
+this._bubble.close();
+this._bubble=null;
+}
+}
+
+}
+
+/* sources.js */
+
+
+
+
+Timeplot.DefaultEventSource=function(eventIndex){
+Timeline.DefaultEventSource.apply(this,arguments);
+};
+
+Object.extend(Timeplot.DefaultEventSource.prototype,Timeline.DefaultEventSource.prototype);
+
+
+Timeplot.DefaultEventSource.prototype.loadText=function(text,separator,url,filter){
+
+if(text==null){
+return;
+}
+
+this._events.maxValues=new Array();
+var base=this._getBaseURL(url);
+
+var dateTimeFormat='iso8601';
+var parseDateTimeFunction=this._events.getUnit().getParser(dateTimeFormat);
+
+var data=this._parseText(text,separator);
+
+var added=false;
+
+if(filter){
+data=filter(data);
+}
+
+if(data){
+for(var i=0;i<data.length;i++){
+var row=data[i];
+if(row.length>1){
+var evt=new Timeplot.DefaultEventSource.NumericEvent(
+parseDateTimeFunction(row[0]),
+row.slice(1)
+);
+this._events.add(evt);
+added=true;
+}
+}
+}
+
+if(added){
+this._fire("onAddMany",[]);
+}
+}
+
+
+Timeplot.DefaultEventSource.prototype._parseText=function(text,separator){
+text=text.replace(/\r\n?/g,"\n");
+var pos=0;
+var len=text.length;
+var table=[];
+while(pos<len){
+var line=[];
+if(text.charAt(pos)!='#'){
+while(pos<len){
+if(text.charAt(pos)=='"'){
+var nextquote=text.indexOf('"',pos+1);
+while(nextquote<len&&nextquote>-1){
+if(text.charAt(nextquote+1)!='"'){
+break;
+}
+nextquote=text.indexOf('"',nextquote+2);
+}
+if(nextquote<0){
+
+}else if(text.charAt(nextquote+1)==separator){
+var quoted=text.substr(pos+1,nextquote-pos-1);
+quoted=quoted.replace(/""/g,'"');
+line[line.length]=quoted;
+pos=nextquote+2;
+continue;
+}else if(text.charAt(nextquote+1)=="\n"||
+len==nextquote+1){
+var quoted=text.substr(pos+1,nextquote-pos-1);
+quoted=quoted.replace(/""/g,'"');
+line[line.length]=quoted;
+pos=nextquote+2;
+break;
+}else{
+
+}
+}
+var nextseparator=text.indexOf(separator,pos);
+var nextnline=text.indexOf("\n",pos);
+if(nextnline<0)nextnline=len;
+if(nextseparator>-1&&nextseparator<nextnline){
+line[line.length]=text.substr(pos,nextseparator-pos);
+pos=nextseparator+1;
+}else{
+line[line.length]=text.substr(pos,nextnline-pos);
+pos=nextnline+1;
+break;
+}
+}
+}else{
+var nextnline=text.indexOf("\n",pos);
+pos=(nextnline>-1)?nextnline+1:cur;
+}
+if(line.length>0){
+table[table.length]=line;
+}
+}
+if(table.length<0)return;
+return table;
+}
+
+
+Timeplot.DefaultEventSource.prototype.getRange=function(){
+var earliestDate=this.getEarliestDate();
+var latestDate=this.getLatestDate();
+return{
+earliestDate:(earliestDate)?earliestDate:null,
+latestDate:(latestDate)?latestDate:null,
+min:0,
+max:0
+};
+}
+
+
+
+
+Timeplot.DefaultEventSource.NumericEvent=function(time,values){
+this._id="e"+Math.round(Math.random()*1000000);
+this._time=time;
+this._values=values;
+};
+
+Timeplot.DefaultEventSource.NumericEvent.prototype={
+getID:function(){return this._id;},
+getTime:function(){return this._time;},
+getValues:function(){return this._values;},
+
+
+getStart:function(){return this._time;},
+getEnd:function(){return this._time;}
+};
+
+
+
+
+Timeplot.DataSource=function(eventSource){
+this._eventSource=eventSource;
+var source=this;
+this._processingListener={
+onAddMany:function(){source._process();},
+onClear:function(){source._clear();}
+}
+this.addListener(this._processingListener);
+this._listeners=[];
+this._data=null;
+this._range=null;
+};
+
+Timeplot.DataSource.prototype={
+
+_clear:function(){
+this._data=null;
+this._range=null;
+},
+
+_process:function(){
+this._data={
+times:new Array(),
+values:new Array()
+};
+this._range={
+earliestDate:null,
+latestDate:null,
+min:0,
+max:0
+};
+},
+
+
+getRange:function(){
+return this._range;
+},
+
+
+getData:function(){
+return this._data;
+},
+
+
+getValue:function(t){
+if(this._data){
+for(var i=0;i<this._data.times.length;i++){
+var l=this._data.times[i];
+if(l>=t){
+return this._data.values[i];
+}
+}
+}
+return 0;
+},
+
+
+addListener:function(listener){
+this._eventSource.addListener(listener);
+},
+
+
+removeListener:function(listener){
+this._eventSource.removeListener(listener);
+},
+
+
+replaceListener:function(oldListener,newListener){
+this.removeListener(oldListener);
+this.addListener(newListener);
+}
+
+}
+
+
+
+
+Timeplot.ColumnSource=function(eventSource,column){
+Timeplot.DataSource.apply(this,arguments);
+this._column=column-1;
+};
+
+Object.extend(Timeplot.ColumnSource.prototype,Timeplot.DataSource.prototype);
+
+Timeplot.ColumnSource.prototype.dispose=function(){
+this.removeListener(this._processingListener);
+this._clear();
+}
+
+Timeplot.ColumnSource.prototype._process=function(){
+var count=this._eventSource.getCount();
+var times=new Array(count);
+var values=new Array(count);
+var min=Number.MAX_VALUE;
+var max=Number.MIN_VALUE;
+var i=0;
+
+var iterator=this._eventSource.getAllEventIterator();
+while(iterator.hasNext()){
+var event=iterator.next();
+var time=event.getTime();
+times[i]=time;
+var value=this._getValue(event);
+if(!isNaN(value)){
+if(value<min){
+min=value;
+}
+if(value>max){
+max=value;
+}
+values[i]=value;
+}
+i++;
+}
+
+this._data={
+times:times,
+values:values
+};
+
+if(max==Number.MIN_VALUE)max=1;
+
+this._range={
+earliestDate:this._eventSource.getEarliestDate(),
+latestDate:this._eventSource.getLatestDate(),
+min:min,
+max:max
+};
+}
+
+Timeplot.ColumnSource.prototype._getValue=function(event){
+return parseFloat(event.getValues()[this._column]);
+}
+
+
+
+
+Timeplot.ColumnDiffSource=function(eventSource,column1,column2){
+Timeplot.ColumnSource.apply(this,arguments);
+this._column2=column2-1;
+};
+
+Object.extend(Timeplot.ColumnDiffSource.prototype,Timeplot.ColumnSource.prototype);
+
+Timeplot.ColumnDiffSource.prototype._getValue=function(event){
+var a=parseFloat(event.getValues()[this._column]);
+var b=parseFloat(event.getValues()[this._column2]);
+return a-b;
+}
+
+
+/* geometry.js */
+
+
+
+
+Timeplot.DefaultValueGeometry=function(params){
+if(!params)params={};
+this._id=("id"in params)?params.id:"g"+Math.round(Math.random()*1000000);
+this._axisColor=("axisColor"in params)?((typeof params.axisColor=="string")?new Timeplot.Color(params.axisColor):params.axisColor):new Timeplot.Color("#606060"),
+this._gridColor=("gridColor"in params)?((typeof params.gridColor=="string")?new Timeplot.Color(params.gridColor):params.gridColor):null,
+this._gridLineWidth=("gridLineWidth"in params)?params.gridLineWidth:0.5;
+this._axisLabelsPlacement=("axisLabelsPlacement"in params)?params.axisLabelsPlacement:"right";
+this._gridSpacing=("gridSpacing"in params)?params.gridStep:50;
+this._gridType=("gridType"in params)?params.gridType:"short";
+this._gridShortSize=("gridShortSize"in params)?params.gridShortSize:10;
+this._minValue=("min"in params)?params.min:null;
+this._maxValue=("max"in params)?params.max:null;
+this._linMap={
+direct:function(v){
+return v;
+},
+inverse:function(y){
+return y;
+}
+}
+this._map=this._linMap;
+this._labels=[];
+this._grid=[];
+}
+
+Timeplot.DefaultValueGeometry.prototype={
+
+
+setTimeplot:function(timeplot){
+this._timeplot=timeplot;
+this._canvas=timeplot.getCanvas();
+this.reset();
+},
+
+
+setRange:function(range){
+if((this._minValue==null)||((this._minValue!=null)&&(range.min<this._minValue))){
+this._minValue=range.min;
+}
+if((this._maxValue==null)||((this._maxValue!=null)&&(range.max*1.05>this._maxValue))){
+this._maxValue=range.max*1.05;
+}
+
+this._updateMappedValues();
+
+if(!(this._minValue==0&&this._maxValue==0)){
+this._grid=this._calculateGrid();
+}
+},
+
+
+reset:function(){
+this._clearLabels();
+this._updateMappedValues();
+this._grid=this._calculateGrid();
+},
+
+
+toScreen:function(value){
+if(this._canvas&&this._maxValue){
+var v=value-this._minValue;
+return this._canvas.height*(this._map.direct(v))/this._mappedRange;
+}else{
+return-50;
+}
+},
+
+
+fromScreen:function(y){
+if(this._canvas){
+return this._map.inverse(this._mappedRange*y/this._canvas.height)+this._minValue;
+}else{
+return 0;
+}
+},
+
+
+paint:function(){
+if(this._timeplot){
+var ctx=this._canvas.getContext('2d');
+
+ctx.lineJoin='miter';
+
+
+if(this._gridColor){
+var gridGradient=ctx.createLinearGradient(0,0,0,this._canvas.height);
+gridGradient.addColorStop(0,this._gridColor.toHexString());
+gridGradient.addColorStop(0.3,this._gridColor.toHexString());
+gridGradient.addColorStop(1,"rgba(255,255,255,0.5)");
+
+ctx.lineWidth=this._gridLineWidth;
+ctx.strokeStyle=gridGradient;
+
+for(var i=0;i<this._grid.length;i++){
+var tick=this._grid[i];
+var y=Math.floor(tick.y)+0.5;
+if(typeof tick.label!="undefined"){
+if(this._axisLabelsPlacement=="left"){
+var div=this._timeplot.putText(this._id+"-"+i,tick.label,"timeplot-grid-label",{
+left:4,
+bottom:y+2,
+color:this._gridColor.toHexString(),
+visibility:"hidden"
+});
+}else if(this._axisLabelsPlacement=="right"){
+var div=this._timeplot.putText(this._id+"-"+i,tick.label,"timeplot-grid-label",{
+right:4,
+bottom:y+2,
+color:this._gridColor.toHexString(),
+visibility:"hidden"
+});
+}
+if(y+div.clientHeight<this._canvas.height+10){
+div.style.visibility="visible";
+}
+}
+
+
+ctx.beginPath();
+if(this._gridType=="long"||tick.label==0){
+ctx.moveTo(0,y);
+ctx.lineTo(this._canvas.width,y);
+}else if(this._gridType=="short"){
+if(this._axisLabelsPlacement=="left"){
+ctx.moveTo(0,y);
+ctx.lineTo(this._gridShortSize,y);
+}else if(this._axisLabelsPlacement=="right"){
+ctx.moveTo(this._canvas.width,y);
+ctx.lineTo(this._canvas.width-this._gridShortSize,y);
+}
+}
+ctx.stroke();
+}
+}
+
+
+var axisGradient=ctx.createLinearGradient(0,0,0,this._canvas.height);
+axisGradient.addColorStop(0,this._axisColor.toString());
+axisGradient.addColorStop(0.5,this._axisColor.toString());
+axisGradient.addColorStop(1,"rgba(255,255,255,0.5)");
+
+ctx.lineWidth=1;
+ctx.strokeStyle=axisGradient;
+
+
+ctx.beginPath();
+ctx.moveTo(0,this._canvas.height);
+ctx.lineTo(0,0);
+ctx.stroke();
+
+
+ctx.beginPath();
+ctx.moveTo(this._canvas.width,0);
+ctx.lineTo(this._canvas.width,this._canvas.height);
+ctx.stroke();
+}
+},
+
+
+_clearLabels:function(){
+for(var i=0;i<this._labels.length;i++){
+var l=this._labels[i];
+var parent=l.parentNode;
+if(parent)parent.removeChild(l);
+}
+},
+
+
+_calculateGrid:function(){
+var grid=[];
+
+if(!this._canvas||this._valueRange==0)return grid;
+
+var power=0;
+if(this._valueRange>1){
+while(Math.pow(10,power)<this._valueRange){
+power++;
+}
+power--;
+}else{
+while(Math.pow(10,power)>this._valueRange){
+power--;
+}
+}
+
+var unit=Math.pow(10,power);
+var inc=unit;
+while(true){
+var dy=this.toScreen(this._minValue+inc);
+
+while(dy<this._gridSpacing){
+inc+=unit;
+dy=this.toScreen(this._minValue+inc);
+}
+
+if(dy>2*this._gridSpacing){
+unit/=10;
+inc=unit;
+}else{
+break;
+}
+}
+
+var v=0;
+var y=this.toScreen(v);
+if(this._minValue>=0){
+while(y<this._canvas.height){
+if(y>0){
+grid.push({y:y,label:v});
+}
+v+=inc;
+y=this.toScreen(v);
+}
+}else if(this._maxValue<=0){
+while(y>0){
+if(y<this._canvas.height){
+grid.push({y:y,label:v});
+}
+v-=inc;
+y=this.toScreen(v);
+}
+}else{
+while(y<this._canvas.height){
+if(y>0){
+grid.push({y:y,label:v});
+}
+v+=inc;
+y=this.toScreen(v);
+}
+v=-inc;
+y=this.toScreen(v);
+while(y>0){
+if(y<this._canvas.height){
+grid.push({y:y,label:v});
+}
+v-=inc;
+y=this.toScreen(v);
+}
+}
+
+return grid;
+},
+
+
+_updateMappedValues:function(){
+this._valueRange=Math.abs(this._maxValue-this._minValue);
+this._mappedRange=this._map.direct(this._valueRange);
+}
+
+}
+
+
+
+
+Timeplot.LogarithmicValueGeometry=function(params){
+Timeplot.DefaultValueGeometry.apply(this,arguments);
+this._logMap={
+direct:function(v){
+return Math.log(v+1)/Math.log(10);
+},
+inverse:function(y){
+return Math.exp(Math.log(10)*y)-1;
+}
+}
+this._mode="log";
+this._map=this._logMap;
+this._calculateGrid=this._logarithmicCalculateGrid;
+};
+
+Timeplot.LogarithmicValueGeometry.prototype._linearCalculateGrid=Timeplot.DefaultValueGeometry.prototype._calculateGrid;
+
+Object.extend(Timeplot.LogarithmicValueGeometry.prototype,Timeplot.DefaultValueGeometry.prototype);
+
+
+Timeplot.LogarithmicValueGeometry.prototype._logarithmicCalculateGrid=function(){
+var grid=[];
+
+if(!this._canvas||this._valueRange==0)return grid;
+
+var v=1;
+var y=this.toScreen(v);
+while(y<this._canvas.height||isNaN(y)){
+if(y>0){
+grid.push({y:y,label:v});
+}
+v*=10;
+y=this.toScreen(v);
+}
+
+return grid;
+};
+
+
+Timeplot.LogarithmicValueGeometry.prototype.actLinear=function(){
+this._mode="lin";
+this._map=this._linMap;
+this._calculateGrid=this._linearCalculateGrid;
+this.reset();
+}
+
+
+Timeplot.LogarithmicValueGeometry.prototype.actLogarithmic=function(){
+this._mode="log";
+this._map=this._logMap;
+this._calculateGrid=this._logarithmicCalculateGrid;
+this.reset();
+}
+
+
+Timeplot.LogarithmicValueGeometry.prototype.toggle=function(){
+if(this._mode=="log"){
+this.actLinear();
+}else{
+this.actLogarithmic();
+}
+}
+
+
+
+
+Timeplot.DefaultTimeGeometry=function(params){
+if(!params)params={};
+this._id=("id"in params)?params.id:"g"+Math.round(Math.random()*1000000);
+this._locale=("locale"in params)?params.locale:"en";
+this._timeZone=("timeZone"in params)?params.timeZone:SimileAjax.DateTime.getTimezone();
+this._labeller=("labeller"in params)?params.labeller:null;
+this._axisColor=("axisColor"in params)?((params.axisColor=="string")?new Timeplot.Color(params.axisColor):params.axisColor):new Timeplot.Color("#606060"),
+this._gridColor=("gridColor"in params)?((params.gridColor=="string")?new Timeplot.Color(params.gridColor):params.gridColor):null,
+this._gridLineWidth=("gridLineWidth"in params)?params.gridLineWidth:0.5;
+this._axisLabelsPlacement=("axisLabelsPlacement"in params)?params.axisLabelsPlacement:"bottom";
+this._gridStep=("gridStep"in params)?params.gridStep:100;
+this._gridStepRange=("gridStepRange"in params)?params.gridStepRange:20;
+this._min=("min"in params)?params.min:null;
+this._max=("max"in params)?params.max:null;
+this._timeValuePosition=("timeValuePosition"in params)?params.timeValuePosition:"bottom";
+this._unit=("unit"in params)?params.unit:Timeline.NativeDateUnit;
+this._linMap={
+direct:function(t){
+return t;
+},
+inverse:function(x){
+return x;
+}
+}
+this._map=this._linMap;
+this._labeler=this._unit.createLabeller(this._locale,this._timeZone);
+var dateParser=this._unit.getParser("iso8601");
+if(this._min&&!this._min.getTime){
+this._min=dateParser(this._min);
+}
+if(this._max&&!this._max.getTime){
+this._max=dateParser(this._max);
+}
+this._grid=[];
+}
+
+Timeplot.DefaultTimeGeometry.prototype={
+
+
+setTimeplot:function(timeplot){
+this._timeplot=timeplot;
+this._canvas=timeplot.getCanvas();
+this.reset();
+},
+
+
+setRange:function(range){
+if(this._min){
+this._earliestDate=this._min;
+}else if(range.earliestDate&&((this._earliestDate==null)||((this._earliestDate!=null)&&(range.earliestDate.getTime()<this._earliestDate.getTime())))){
+this._earliestDate=range.earliestDate;
+}
+
+if(this._max){
+this._latestDate=this._max;
+}else if(range.latestDate&&((this._latestDate==null)||((this._latestDate!=null)&&(range.latestDate.getTime()>this._latestDate.getTime())))){
+this._latestDate=range.latestDate;
+}
+
+if(!this._earliestDate&&!this._latestDate){
+this._grid=[];
+}else{
+this.reset();
+}
+},
+
+
+reset:function(){
+this._updateMappedValues();
+if(this._canvas)this._grid=this._calculateGrid();
+},
+
+
+toScreen:function(time){
+if(this._canvas&&this._latestDate){
+var t=time-this._earliestDate.getTime();
+return this._canvas.width*this._map.direct(t)/this._mappedPeriod;
+}else{
+return-50;
+}
+},
+
+
+fromScreen:function(x){
+if(this._canvas){
+return this._map.inverse(this._mappedPeriod*x/this._canvas.width)+this._earliestDate.getTime();
+}else{
+return 0;
+}
+},
+
+
+getPeriod:function(){
+return this._period;
+},
+
+
+getLabeler:function(){
+return this._labeler;
+},
+
+
+getUnit:function(){
+return this._unit;
+},
+
+
+paint:function(){
+if(this._canvas){
+var unit=this._unit;
+var ctx=this._canvas.getContext('2d');
+
+var gradient=ctx.createLinearGradient(0,0,0,this._canvas.height);
+
+ctx.strokeStyle=gradient;
+ctx.lineWidth=this._gridLineWidth;
+ctx.lineJoin='miter';
+
+
+if(this._gridColor){
+gradient.addColorStop(0,this._gridColor.toString());
+gradient.addColorStop(1,"rgba(255,255,255,0.9)");
+
+for(var i=0;i<this._grid.length;i++){
+var tick=this._grid[i];
+var x=Math.floor(tick.x)+0.5;
+if(this._axisLabelsPlacement=="top"){
+var div=this._timeplot.putText(this._id+"-"+i,tick.label,"timeplot-grid-label",{
+left:x+4,
+top:2,
+visibility:"hidden"
+});
+}else if(this._axisLabelsPlacement=="bottom"){
+var div=this._timeplot.putText(this._id+"-"+i,tick.label,"timeplot-grid-label",{
+left:x+4,
+bottom:2,
+visibility:"hidden"
+});
+}
+if(x+div.clientWidth<this._canvas.width+10){
+div.style.visibility="visible";
+}
+
+
+ctx.beginPath();
+ctx.moveTo(x,0);
+ctx.lineTo(x,this._canvas.height);
+ctx.stroke();
+}
+}
+
+
+gradient.addColorStop(0,this._axisColor.toString());
+gradient.addColorStop(1,"rgba(255,255,255,0.5)");
+
+ctx.lineWidth=1;
+gradient.addColorStop(0,this._axisColor.toString());
+
+ctx.beginPath();
+ctx.moveTo(0,0);
+ctx.lineTo(this._canvas.width,0);
+ctx.stroke();
+}
+},
+
+
+_calculateGrid:function(){
+var grid=[];
+
+var time=SimileAjax.DateTime;
+var u=this._unit;
+var p=this._period;
+
+if(p==0)return grid;
+
+
+if(p>time.gregorianUnitLengths[time.MILLENNIUM]){
+unit=time.MILLENNIUM;
+}else{
+for(var unit=time.MILLENNIUM;unit>0;unit--){
+if(time.gregorianUnitLengths[unit-1]<=p&&p<time.gregorianUnitLengths[unit]){
+unit--;
+break;
+}
+}
+}
+
+var t=u.cloneValue(this._earliestDate);
+
+do{
+time.roundDownToInterval(t,unit,this._timeZone,1,0);
+var x=this.toScreen(u.toNumber(t));
+switch(unit){
+case time.SECOND:
+var l=t.toLocaleTimeString();
+break;
+case time.MINUTE:
+var m=t.getMinutes();
+var l=t.getHours()+":"+((m<10)?"0":"")+m;
+break;
+case time.HOUR:
+var l=t.getHours()+":00";
+break;
+case time.DAY:
+case time.WEEK:
+case time.MONTH:
+var l=t.toLocaleDateString();
+break;
+case time.YEAR:
+case time.DECADE:
+case time.CENTURY:
+case time.MILLENNIUM:
+var l=t.getUTCFullYear();
+break;
+}
+if(x>0){
+grid.push({x:x,label:l});
+}
+time.incrementByInterval(t,unit,this._timeZone);
+}while(t.getTime()<this._latestDate.getTime());
+
+return grid;
+},
+
+
+_updateMappedValues:function(){
+if(this._latestDate&&this._earliestDate){
+this._period=this._latestDate.getTime()-this._earliestDate.getTime();
+this._mappedPeriod=this._map.direct(this._period);
+}else{
+this._period=0;
+this._mappedPeriod=0;
+}
+}
+
+}
+
+
+
+
+Timeplot.MagnifyingTimeGeometry=function(params){
+Timeplot.DefaultTimeGeometry.apply(this,arguments);
+
+var g=this;
+this._MagnifyingMap={
+direct:function(t){
+if(t<g._leftTimeMargin){
+var x=t*g._leftRate;
+}else if(g._leftTimeMargin<t&&t<g._rightTimeMargin){
+var x=t*g._expandedRate+g._expandedTimeTranslation;
+}else{
+var x=t*g._rightRate+g._rightTimeTranslation;
+}
+return x;
+},
+inverse:function(x){
+if(x<g._leftScreenMargin){
+var t=x/g._leftRate;
+}else if(g._leftScreenMargin<x&&x<g._rightScreenMargin){
+var t=x/g._expandedRate+g._expandedScreenTranslation;
+}else{
+var t=x/g._rightRate+g._rightScreenTranslation;
+}
+return t;
+}
+}
+
+this._mode="lin";
+this._map=this._linMap;
+};
+
+Object.extend(Timeplot.MagnifyingTimeGeometry.prototype,Timeplot.DefaultTimeGeometry.prototype);
+
+
+Timeplot.MagnifyingTimeGeometry.prototype.initialize=function(timeplot){
+Timeplot.DefaultTimeGeometry.prototype.initialize.apply(this,arguments);
+
+if(!this._lens){
+this._lens=this._timeplot.putDiv("lens","timeplot-lens");
+}
+
+var period=1000*60*60*24*30;
+
+var geometry=this;
+
+var magnifyWith=function(lens){
+var aperture=lens.clientWidth;
+var loc=geometry._timeplot.locate(lens);
+geometry.setMagnifyingParams(loc.x+aperture/2,aperture,period);
+geometry.actMagnifying();
+geometry._timeplot.paint();
+}
+
+var canvasMouseDown=function(elmt,evt,target){
+geometry._canvas.startCoords=SimileAjax.DOM.getEventRelativeCoordinates(evt,elmt);
+geometry._canvas.pressed=true;
+}
+
+var canvasMouseUp=function(elmt,evt,target){
+geometry._canvas.pressed=false;
+var coords=SimileAjax.DOM.getEventRelativeCoordinates(evt,elmt);
+if(Timeplot.Math.isClose(coords,geometry._canvas.startCoords,5)){
+geometry._lens.style.display="none";
+geometry.actLinear();
+geometry._timeplot.paint();
+}else{
+geometry._lens.style.cursor="move";
+magnifyWith(geometry._lens);
+}
+}
+
+var canvasMouseMove=function(elmt,evt,target){
+if(geometry._canvas.pressed){
+var coords=SimileAjax.DOM.getEventRelativeCoordinates(evt,elmt);
+if(coords.x<0)coords.x=0;
+if(coords.x>geometry._canvas.width)coords.x=geometry._canvas.width;
+geometry._timeplot.placeDiv(geometry._lens,{
+left:geometry._canvas.startCoords.x,
+width:coords.x-geometry._canvas.startCoords.x,
+bottom:0,
+height:geometry._canvas.height,
+display:"block"
+});
+}
+}
+
+var lensMouseDown=function(elmt,evt,target){
+geometry._lens.startCoords=SimileAjax.DOM.getEventRelativeCoordinates(evt,elmt);;
+geometry._lens.pressed=true;
+}
+
+var lensMouseUp=function(elmt,evt,target){
+geometry._lens.pressed=false;
+}
+
+var lensMouseMove=function(elmt,evt,target){
+if(geometry._lens.pressed){
+var coords=SimileAjax.DOM.getEventRelativeCoordinates(evt,elmt);
+var lens=geometry._lens;
+var left=lens.offsetLeft+coords.x-lens.startCoords.x;
+if(left<geometry._timeplot._paddingX)left=geometry._timeplot._paddingX;
+if(left+lens.clientWidth>geometry._canvas.width-geometry._timeplot._paddingX)left=geometry._canvas.width-lens.clientWidth+geometry._timeplot._paddingX;
+lens.style.left=left;
+magnifyWith(lens);
+}
+}
+
+if(!this._canvas.instrumented){
+SimileAjax.DOM.registerEvent(this._canvas,"mousedown",canvasMouseDown);
+SimileAjax.DOM.registerEvent(this._canvas,"mousemove",canvasMouseMove);
+SimileAjax.DOM.registerEvent(this._canvas,"mouseup",canvasMouseUp);
+SimileAjax.DOM.registerEvent(this._canvas,"mouseup",lensMouseUp);
+this._canvas.instrumented=true;
+}
+
+if(!this._lens.instrumented){
+SimileAjax.DOM.registerEvent(this._lens,"mousedown",lensMouseDown);
+SimileAjax.DOM.registerEvent(this._lens,"mousemove",lensMouseMove);
+SimileAjax.DOM.registerEvent(this._lens,"mouseup",lensMouseUp);
+SimileAjax.DOM.registerEvent(this._lens,"mouseup",canvasMouseUp);
+this._lens.instrumented=true;
+}
+}
+
+
+Timeplot.MagnifyingTimeGeometry.prototype.setMagnifyingParams=function(c,a,b){
+a=a/2;
+b=b/2;
+
+var w=this._canvas.width;
+var d=this._period;
+
+if(c<0)c=0;
+if(c>w)c=w;
+
+if(c-a<0)a=c;
+if(c+a>w)a=w-c;
+
+var ct=this.fromScreen(c)-this._earliestDate.getTime();
+if(ct-b<0)b=ct;
+if(ct+b>d)b=d-ct;
+
+this._centerX=c;
+this._centerTime=ct;
+this._aperture=a;
+this._aperturePeriod=b;
+
+this._leftScreenMargin=this._centerX-this._aperture;
+this._rightScreenMargin=this._centerX+this._aperture;
+this._leftTimeMargin=this._centerTime-this._aperturePeriod;
+this._rightTimeMargin=this._centerTime+this._aperturePeriod;
+
+this._leftRate=(c-a)/(ct-b);
+this._expandedRate=a/b;
+this._rightRate=(w-c-a)/(d-ct-b);
+
+this._expandedTimeTranslation=this._centerX-this._centerTime*this._expandedRate;
+this._expandedScreenTranslation=this._centerTime-this._centerX/this._expandedRate;
+this._rightTimeTranslation=(c+a)-(ct+b)*this._rightRate;
+this._rightScreenTranslation=(ct+b)-(c+a)/this._rightRate;
+
+this._updateMappedValues();
+}
+
+
+Timeplot.MagnifyingTimeGeometry.prototype.actLinear=function(){
+this._mode="lin";
+this._map=this._linMap;
+this.reset();
+}
+
+
+Timeplot.MagnifyingTimeGeometry.prototype.actMagnifying=function(){
+this._mode="Magnifying";
+this._map=this._MagnifyingMap;
+this.reset();
+}
+
+
+Timeplot.MagnifyingTimeGeometry.prototype.toggle=function(){
+if(this._mode=="Magnifying"){
+this.actLinear();
+}else{
+this.actMagnifying();
+}
+}
+
+
+
+/* color.js */
+
+
+
+
+
+
+Timeplot.Color=function(color){
+this._fromHex(color);
+};
+
+Timeplot.Color.prototype={
+
+
+set:function(r,g,b,a){
+this.r=r;
+this.g=g;
+this.b=b;
+this.a=(a)?a:1.0;
+return this.check();
+},
+
+
+transparency:function(a){
+this.a=a;
+return this.check();
+},
+
+
+lighten:function(level){
+var color=new Timeplot.Color();
+return color.set(
+this.r+=parseInt(level,10),
+this.g+=parseInt(level,10),
+this.b+=parseInt(level,10)
+);
+},
+
+
+darken:function(level){
+var color=new Timeplot.Color();
+return color.set(
+this.r-=parseInt(level,10),
+this.g-=parseInt(level,10),
+this.b-=parseInt(level,10)
+);
+},
+
+
+check:function(){
+if(this.r>255){
+this.r=255;
+}else if(this.r<0){
+this.r=0;
+}
+if(this.g>255){
+this.g=255;
+}else if(this.g<0){
+this.g=0;
+}
+if(this.b>255){
+this.b=255;
+}else if(this.b<0){
+this.b=0;
+}
+if(this.a>1.0){
+this.a=1.0;
+}else if(this.a<0.0){
+this.a=0.0;
+}
+return this;
+},
+
+
+toString:function(alpha){
+var a=(alpha)?alpha:((this.a)?this.a:1.0);
+return'rgba('+this.r+','+this.g+','+this.b+','+a+')';
+},
+
+
+toHexString:function(){
+return"#"+this._toHex(this.r)+this._toHex(this.g)+this._toHex(this.b);
+},
+
+
+_fromHex:function(color){
+if(/^#?([\da-f]{3}|[\da-f]{6})$/i.test(color)){
+color=color.replace(/^#/,'').replace(/^([\da-f])([\da-f])([\da-f])$/i,"$1$1$2$2$3$3");
+this.r=parseInt(color.substr(0,2),16);
+this.g=parseInt(color.substr(2,2),16);
+this.b=parseInt(color.substr(4,2),16);
+}else if(/^rgb *\( *\d{0,3} *, *\d{0,3} *, *\d{0,3} *\)$/i.test(color)){
+color=color.match(/^rgb *\( *(\d{0,3}) *, *(\d{0,3}) *, *(\d{0,3}) *\)$/i);
+this.r=parseInt(color[1],10);
+this.g=parseInt(color[2],10);
+this.b=parseInt(color[3],10);
+}
+this.a=1.0;
+return this.check();
+},
+
+
+_toHex:function(dec){
+var hex="0123456789ABCDEF"
+if(dec<0)return"00";
+if(dec>255)return"FF";
+var i=Math.floor(dec/16);
+var j=dec%16;
+return hex.charAt(i)+hex.charAt(j);
+}
+
+};
+
+/* math.js */
+
+
+
+Timeplot.Math={
+
+
+range:function(f){
+var F=f.length;
+var min=Number.MAX_VALUE;
+var max=Number.MIN_VALUE;
+
+for(var t=0;t<F;t++){
+var value=f[t];
+if(value<min){
+min=value;
+}
+if(value>max){
+max=value;
+}
+}
+
+return{
+min:min,
+max:max
+}
+},
+
+
+movingAverage:function(f,size){
+var F=f.length;
+var g=new Array(F);
+for(var n=0;n<F;n++){
+var value=0;
+for(var m=n-size;m<n+size;m++){
+if(m<0){
+var v=f[0];
+}else if(m>=F){
+var v=g[n-1];
+}else{
+var v=f[m];
+}
+value+=v;
+}
+g[n]=value/(2*size);
+}
+return g;
+},
+
+
+integral:function(f){
+var F=f.length;
+
+var g=new Array(F);
+var sum=0;
+
+for(var t=0;t<F;t++){
+sum+=f[t];
+g[t]=sum;
+}
+
+return g;
+},
+
+
+normalize:function(f){
+var F=f.length;
+var sum=0.0;
+
+for(var t=0;t<F;t++){
+sum+=f[t];
+}
+
+for(var t=0;t<F;t++){
+f[t]/=sum;
+}
+
+return f;
+},
+
+
+convolution:function(f,g){
+var F=f.length;
+var G=g.length;
+
+var c=new Array(F);
+
+for(var m=0;m<F;m++){
+var r=0;
+var end=(m+G<F)?m+G:F;
+for(var n=m;n<end;n++){
+var a=f[n-G];
+var b=g[n-m];
+r+=a*b;
+}
+c[m]=r;
+}
+
+return c;
+},
+
+
+
+
+
+
+
+heavyside:function(size){
+var f=new Array(size);
+var value=1/size;
+for(var t=0;t<size;t++){
+f[t]=value;
+}
+return f;
+},
+
+
+gaussian:function(size,threshold){
+with(Math){
+var radius=size/2;
+var variance=radius*radius/log(threshold);
+var g=new Array(size);
+for(var t=0;t<size;t++){
+var l=t-radius;
+g[t]=exp(-variance*l*l);
+}
+}
+
+return this.normalize(g);
+},
+
+
+
+
+round:function(x,n){
+with(Math){
+if(abs(x)>1){
+var l=floor(log(x)/log(10));
+var d=round(exp((l-n+1)*log(10)));
+var y=round(round(x/d)*d);
+return y;
+}else{
+log("FIXME(SM): still to implement for 0 < abs(x) < 1");
+return x;
+}
+}
+},
+
+
+tanh:function(x){
+if(x>5){
+return 1;
+}else if(x<5){
+return-1;
+}else{
+var expx2=Math.exp(2*x);
+return(expx2-1)/(expx2+1);
+}
+},
+
+
+isClose:function(a,b,value){
+return(a&&b&&Math.abs(a.x-b.x)<value&&Math.abs(a.y-b.y)<value);
+}
+
+}
+
+/* processor.js */
+
+
+
+
+
+Timeplot.Operator={
+
+
+sum:function(data,params){
+return Timeplot.Math.integral(data.values);
+},
+
+
+average:function(data,params){
+var size=("size"in params)?params.size:30;
+var result=Timeplot.Math.movingAverage(data.values,size);
+return result;
+}
+}
+
+
+
+
+Timeplot.Processor=function(dataSource,operator,params){
+this._dataSource=dataSource;
+this._operator=operator;
+this._params=params;
+
+this._data={
+times:new Array(),
+values:new Array()
+};
+
+this._range={
+earliestDate:null,
+latestDate:null,
+min:0,
+max:0
+};
+
+var processor=this;
+this._processingListener={
+onAddMany:function(){processor._process();},
+onClear:function(){processor._clear();}
+}
+this.addListener(this._processingListener);
+};
+
+Timeplot.Processor.prototype={
+
+_clear:function(){
+this.removeListener(this._processingListener);
+this._dataSource._clear();
+},
+
+_process:function(){
+
+
+
+
+var data=this._dataSource.getData();
+var range=this._dataSource.getRange();
+
+var newValues=this._operator(data,this._params);
+var newValueRange=Timeplot.Math.range(newValues);
+
+this._data={
+times:data.times,
+values:newValues
+};
+
+this._range={
+earliestDate:range.earliestDate,
+latestDate:range.latestDate,
+min:newValueRange.min,
+max:newValueRange.max
+};
+},
+
+getRange:function(){
+return this._range;
+},
+
+getData:function(){
+return this._data;
+},
+
+getValue:Timeplot.DataSource.prototype.getValue,
+
+addListener:function(listener){
+this._dataSource.addListener(listener);
+},
+
+removeListener:function(listener){
+this._dataSource.removeListener(listener);
+}
+}
diff --git a/site/app/webroot/js/slimbox/slimbox.js b/site/app/webroot/js/slimbox/slimbox.js
new file mode 100644
index 0000000..815f2ba
--- /dev/null
+++ b/site/app/webroot/js/slimbox/slimbox.js
@@ -0,0 +1,257 @@
+/*
+ Slimbox v1.41 - The ultimate lightweight Lightbox clone
+ by Christophe Beyls (http://www.digitalia.be) - MIT-style license.
+ Inspired by the original Lightbox v2 by Lokesh Dhakar.
+
+ Mozilla additions by Wil Clouser <clouserw@mozilla.com>
+*/
+
+var Lightbox = {
+
+ init: function(options){
+ this.options = $extend({
+ resizeDuration: 100,
+ resizeTransition: false, // default transition
+ initialWidth: 250,
+ initialHeight: 250,
+ animateCaption: true,
+ showCounter: true
+ }, options || {});
+
+ this.anchors = [];
+ $each(document.links, function(el){
+ if (el.rel && el.rel.test(/^lightbox/i)){
+ el.onclick = this.click.pass(el, this);
+ this.anchors.push(el);
+ }
+ }, this);
+ this.eventKeyDown = this.keyboardListener.bindAsEventListener(this);
+ this.eventPosition = this.position.bind(this);
+
+ this.overlay = new Element('div', {'id': 'lbOverlay'}).injectInside(document.body);
+
+ this.center = new Element('div', {'id': 'lbCenter', 'styles': {'width': this.options.initialWidth, 'height': this.options.initialHeight, 'marginLeft': -(this.options.initialWidth/2), 'display': 'none'}}).injectInside(document.body);
+ this.image = new Element('div', {'id': 'lbImage'}).injectInside(this.center);
+ this.prevLink = new Element('a', {'id': 'lbPrevLink', 'href': '#', 'styles': {'display': 'none'}}).injectInside(this.image);
+ this.nextLink = this.prevLink.clone().setProperty('id', 'lbNextLink').injectInside(this.image);
+ this.prevLink.onclick = this.previous.bind(this);
+ this.nextLink.onclick = this.next.bind(this);
+
+ this.bottomContainer = new Element('div', {'id': 'lbBottomContainer', 'styles': {'display': 'none'}}).injectInside(document.body);
+ this.bottom = new Element('div', {'id': 'lbBottom'}).injectInside(this.bottomContainer);
+ // Mozilla addition
+ this.previewContainerContainer = new Element('div', {'id': 'lbPreviewContainerContainer'}).injectInside(this.bottom);
+ this.previewContainer = new Element('div', {'id': 'lbPreviewContainer'}).injectInside(this.previewContainerContainer);
+ // End Mozilla addition
+ new Element('a', {'id': 'lbCloseLink', 'href': '#'}).injectInside(this.bottom).onclick = this.overlay.onclick = this.close.bind(this);
+ this.caption = new Element('div', {'id': 'lbCaption'}).injectInside(this.bottom);
+ this.number = new Element('div', {'id': 'lbNumber'}).injectInside(this.bottom);
+ new Element('div', {'styles': {'clear': 'both'}}).injectInside(this.bottom);
+
+ var nextEffect = this.nextEffect.bind(this);
+ this.fx = {
+ overlay: this.overlay.effect('opacity', {duration: 500}).hide(),
+ resize: this.center.effects($extend({duration: this.options.resizeDuration, onComplete: nextEffect}, this.options.resizeTransition ? {transition: this.options.resizeTransition} : {})),
+ image: this.image.effect('opacity', {duration: 500, onComplete: nextEffect}),
+ bottom: this.bottom.effect('margin-top', {duration: 300, onComplete: nextEffect})
+ };
+
+ this.preloadPrev = new Image();
+ this.preloadNext = new Image();
+ },
+
+ click: function(link){
+ if (link.rel.length == 8) return this.show(link.href, link.title);
+
+ var j, imageNum, images = [];
+ this.anchors.each(function(el){
+ if (el.rel == link.rel){
+ for (j = 0; j < images.length; j++) if(images[j][0] == el.href) break;
+ if (j == images.length){
+ images.push([el.href, el.title]);
+ if (el.href == link.href) imageNum = j;
+ }
+ }
+ }, this);
+ return this.open(images, imageNum);
+ },
+
+ show: function(url, title){
+ return this.open([[url, title]], 0);
+ },
+
+ open: function(images, imageNum){
+ this.images = images;
+ this.position();
+ this.setup(true);
+ this.top = window.getScrollTop() + (window.getHeight() / 15);
+ this.center.setStyles({top: this.top, display: ''});
+ this.fx.overlay.start(0.8);
+ return this.changeImage(imageNum);
+ },
+
+ position: function(){
+ this.overlay.setStyles({'top': window.getScrollTop(), 'height': window.getHeight()});
+ },
+
+ setup: function(open){
+ var elements = $A(document.getElementsByTagName('object'));
+ elements.extend(document.getElementsByTagName(window.ie ? 'select' : 'embed'));
+ elements.each(function(el){
+ if (open) el.lbBackupStyle = el.style.visibility;
+ el.style.visibility = open ? 'hidden' : el.lbBackupStyle;
+ });
+ var fn = open ? 'addEvent' : 'removeEvent';
+ window[fn]('scroll', this.eventPosition)[fn]('resize', this.eventPosition);
+ document[fn]('keydown', this.eventKeyDown);
+ this.step = 0;
+ // Mozilla addition
+ this.previews = [];
+ this.fillPreviewContainer();
+ // End Mozilla addition
+ },
+
+ keyboardListener: function(event){
+ switch (event.keyCode){
+ case 27: case 88: case 67: this.close(); break;
+ case 37: case 80: this.previous(); break;
+ case 39: case 78: this.next();
+ }
+ },
+
+ previous: function(){
+ return this.changeImage(this.activeImage-1);
+ },
+
+ next: function(){
+ return this.changeImage(this.activeImage+1);
+ },
+
+ changeImage: function(imageNum){
+ if (this.step || (imageNum < 0) || (imageNum >= this.images.length)) return false;
+ this.step = 1;
+ this.activeImage = imageNum;
+
+ this.bottomContainer.style.display = this.prevLink.style.display = this.nextLink.style.display = 'none';
+ this.fx.image.hide();
+ this.center.className = 'lbLoading';
+
+ // Mozilla addition
+ this.updatePreviewImage();
+ // End Mozilla addition
+
+ this.preload = new Image();
+ this.preload.onload = this.nextEffect.bind(this);
+ this.preload.src = this.images[imageNum][0];
+ return false;
+ },
+
+ nextEffect: function(){
+ switch (this.step++){
+ case 1:
+ this.center.className = '';
+ this.image.style.backgroundImage = 'url('+this.images[this.activeImage][0]+')';
+ this.image.style.width = this.bottom.style.width = this.preload.width+'px';
+ this.image.style.height = this.prevLink.style.height = this.nextLink.style.height = this.preload.height+'px';
+
+ // Mozilla addition
+ if (this.previews.length > 1) {
+ if (this.preload.width < (this.previews.length * 75 + 100)) { // totally arbitrary numbers
+ this.image.style.width = this.bottom.style.width = this.previews.length * 75 + 100 +'px';
+ }
+ }
+ // End Mozilla addition
+
+ this.caption.setHTML(this.images[this.activeImage][1] || '');
+ this.number.setHTML((!this.options.showCounter || (this.images.length == 1)) ? '' : 'Image '+(this.activeImage+1)+' of '+this.images.length);
+
+ if (this.activeImage) this.preloadPrev.src = this.images[this.activeImage-1][0];
+ if (this.activeImage != (this.images.length - 1)) this.preloadNext.src = this.images[this.activeImage+1][0];
+ if (this.center.clientHeight != this.image.offsetHeight){
+ this.fx.resize.start({height: this.image.offsetHeight});
+ break;
+ }
+ this.step++;
+ case 2:
+ if (this.center.clientWidth != this.image.offsetWidth){
+ this.fx.resize.start({width: this.image.offsetWidth, marginLeft: -this.image.offsetWidth/2});
+ break;
+ }
+ this.step++;
+ case 3:
+ this.bottomContainer.setStyles({top: this.top + this.center.clientHeight, height: 0, marginLeft: this.center.style.marginLeft, display: ''});
+ this.fx.image.start(1);
+ break;
+ case 4:
+ if (this.options.animateCaption){
+ this.fx.bottom.set(-this.bottom.offsetHeight);
+ this.bottomContainer.style.height = '';
+ this.fx.bottom.start(0);
+ break;
+ }
+ this.bottomContainer.style.height = '';
+ case 5:
+ if (this.activeImage) this.prevLink.style.display = '';
+ if (this.activeImage != (this.images.length - 1)) this.nextLink.style.display = '';
+ this.step = 0;
+ }
+ },
+
+ // Mozilla addition
+ fillPreviewContainer: function() {
+
+ this.previews = [];
+ $('lbPreviewContainer').empty();
+
+ if (this.images.length > 1) {
+ for (x in this.images) {
+ if (this.images[x][0]) { // sometimes this is undefined...
+ this.previews[x] = new Image();
+ this.previews[x].src = this.images[x][0];
+ if (x == this.activeImage) {
+ this.previews[x].addClass('active');
+ }
+
+ this.previews[x].addClass('lbPreview');
+ this.previews[x].setProperty('href', '#');
+ this.previews[x].setProperty('id', 'lbPreview' + x);
+ this.previews[x].setProperty('onclick', 'Lightbox.changeImage(' + x + ')');
+
+ this.previews[x].injectInside(this.previewContainer);
+ }
+ }
+ this.previewContainer.setStyle('width', this.previews.length * 75 + "px");
+ }
+ },
+
+ // Just puts the active CSS class on the activeImage
+ updatePreviewImage: function() {
+ $$('img.lbPreview').forEach(function(item, index) { item.removeClass('active') } );
+
+ var current = $('lbPreview' + this.activeImage);
+
+ if (current)
+ current.addClass('active');
+ },
+ // End Mozilla addition
+
+ close: function(){
+ if (this.step < 0) return;
+ this.step = -1;
+ if (this.preload){
+ this.preload.onload = Class.empty;
+ this.preload = null;
+ }
+ // Mozilla addition
+ if (this.previews) {
+ this.previews = [];
+ }
+ // End Mozilla addition
+ for (var f in this.fx) this.fx[f].stop();
+ this.center.style.display = this.bottomContainer.style.display = 'none';
+ this.fx.overlay.chain(this.setup.pass(false, this)).start(0);
+ return false;
+ }
+};
+
+window.addEvent('domready', Lightbox.init.bind(Lightbox));
diff --git a/site/app/webroot/js/stats/colors.js b/site/app/webroot/js/stats/colors.js
new file mode 100755
index 0000000..c369ebf
--- /dev/null
+++ b/site/app/webroot/js/stats/colors.js
@@ -0,0 +1,34 @@
+var colors = {
+ counter: 0,
+ colors: [
+ '#3366CC', // blue
+ '#9966CC', // purple
+ '#66CCCC', // green
+ '#FF9933', // orange
+ '#CC3300', // red
+ '#999933', // yellow
+ '#666666', // gray
+ '#3399CC', // blue
+ '#CC99CC', // purple
+ '#66CC99', // green
+ '#CC6666', // red
+ '#009933', // green
+ '#663333' // red
+ ],
+
+ getNext: function() {
+ if (this.counter > colors.length)
+ this.resetCounter();
+
+ var color = this.colors[this.counter];
+
+ this.counter++;
+
+ return color;
+ },
+
+ resetCounter: function() {
+ this.counter = 0;
+ }
+
+}; \ No newline at end of file
diff --git a/site/app/webroot/js/stats/dropdowns.js b/site/app/webroot/js/stats/dropdowns.js
new file mode 100755
index 0000000..f2087a9
--- /dev/null
+++ b/site/app/webroot/js/stats/dropdowns.js
@@ -0,0 +1,443 @@
+var totalDropdowns = 0;
+
+/**
+ * Initializes settings for new dropdown
+ *
+ * @param options object Any non-default config values
+ */
+Dropdown = function(options) {
+ if (!options)
+ options = {};
+
+ var config = {
+ 'id': (options.id ? options.id : ''),
+ 'color': (options.color ? options.color : ''),
+ 'title': (options.title ? options.title : ''),
+ 'type': (options.type ? options.type : ''),
+ 'itemsToggle': (typeof options.itemsToggle != 'undefined' ? options.itemsToggle : false),
+ 'removable': (typeof options.removable != 'undefined' ? options.removable : true),
+ 'removeOnNewTimeplot': (typeof options.removeOnNewTimeplot != 'undefined' ? options.removeOnNewTimeplot : true),
+ 'hasColorbox': (typeof options.hasColorbox != 'undefined' ? options.hasColorbox : true),
+ 'onChange': (options.onChange ? options.onChange : null),
+ 'dropdownContainerObject': (options.dropdownContainerObject ? options.dropdownContainerObject : 'plotSelection.dropdowns'),
+ 'parentDOM': (options.parentDOM ? options.parentDOM : 'plot-selection')
+ };
+
+ this.config = config;
+
+ // Insert dropdown into DOM
+ this.insert();
+};
+
+Dropdown.prototype = {
+ selectedItem: null,
+ callString: '',
+
+ /**
+ * Generates and inserts the new dropdown with the next available plot
+ * color and id.
+ */
+ insert: function() {
+ // Get next available plot color if not specified
+ if (!this.config.color && this.config.hasColorbox)
+ this.config.color = colors.getNext();
+
+ totalDropdowns++;
+
+ // Get next available plot id if not specified
+ if (!this.config.id)
+ this.config.id = 'plot' + totalDropdowns;
+
+ // Set call string for easier reference
+ this.callString = this.config.dropdownContainerObject + "['" + this.config.id + "']";
+
+ // Build HTML
+ var dropdown = '<div id="' + this.config.id + '" class="plot-dropdown ';
+ dropdown += this.config.type;
+ if (this.config.itemsToggle)
+ dropdown += ' toggle';
+ dropdown += '">';
+ if (this.config.hasColorbox) {
+ dropdown += '<div class="colorbox ';
+ if (this.config.removable) {
+ dropdown += 'removable" title="' + localized['statistics_js_dropdowns_removeplot'] + '" ';
+ dropdown += 'onclick="' + this.callString + '.remove(false, \'plotSelection.remove(this);\');';
+ }
+ dropdown += '" style="background-color: ' + this.config.color + ';"></div>';
+ }
+ dropdown += '<a onclick="' + this.callString + '.toggle();">';
+ dropdown += '<div class="selected"><div class="selected-text">';
+ dropdown += '<span class="selected-prefix" style="color: ' + this.config.color + ';"></span>';
+ dropdown += '<span class="selected-name">';
+ if (this.config.title != '')
+ dropdown += this.config.title;
+ dropdown += '</span></div></div>';
+ dropdown += '</a></div>';
+
+ // Append the new dropdown
+ $('#' + this.config.parentDOM).append(dropdown);
+ },
+
+ /**
+ * Removes the dropdown from the DOM
+ *
+ * @param newTimeplot boolean Whether this is being called because of a new
+ * timeplot creation.
+ * @param callback string A callback function for after the removal
+ */
+ remove: function(newTimeplot, callback) {
+ if (newTimeplot && !this.config.removeOnNewTimeplot)
+ return false;
+
+ $('#' + this.config.id).remove();
+
+ if (callback)
+ eval(callback);
+
+ return true;
+ },
+
+ /**
+ * Opens the dropdown if closed and closes the dropdown if open
+ */
+ toggle: function() {
+ if ($('#' + this.config.id + ' > ul').is(':hidden'))
+ this.open();
+ else
+ this.close();
+ },
+
+ /**
+ * Opens the dropdown
+ */
+ open: function() {
+ // Close any open dropdowns
+ this.closeAll();
+
+ $('#' + this.config.id).addClass('menu-open');
+ $('#' + this.config.id + ' > ul.level1').slideDown('normal', function() {
+ // Add listener to close the dropdown if user clicks off of the menu
+ $(document).click(offClickHandler);
+ });
+ },
+
+ /**
+ * Close only this dropdown
+ */
+ close: function() {
+ var id = this.config.id;
+
+ // Remove offClick listener
+ $(document).unbind('click', offClickHandler);
+
+ $('#' + id + ' > ul').slideUp();
+ $('#' + id).removeClass('menu-open');
+ },
+
+ /**
+ * Close all open dropdowns
+ */
+ closeAll: function() {
+ // Remove offClick listener
+ $(document).unbind('click', offClickHandler);
+
+ // Close all open dropdowns in order of hierarchy
+ $('.plot-dropdown > ul.level3:visible').animate({width: 'hide'}, 'fast');
+ $('.plot-dropdown > ul.level2:visible').animate({width: 'hide'}, 'fast');
+ $('.plot-dropdown > ul.level1:visible').slideUp('fast');
+ $('.plot-dropdown').removeClass('menu-open');
+ },
+
+ /**
+ * Updates the dropdown box DOM with the currently selected item
+ */
+ updateSelection: function() {
+ var id = this.config.id;
+
+ $('#' + id + ' .selected-prefix').html(this.selectedItem.prefix);
+ $('#' + id + ' .selected-name').html(this.selectedItem.name);
+ $('#' + id + ' .selected-name').attr('title', this.selectedItem.tooltip);
+
+ // Close dropdown
+ this.close();
+
+ // Execute any onChange events the dropdown has
+ if (this.config.onChange)
+ eval(this.config.onChange);
+ },
+
+ /*************************************************************************/
+
+ menus: {},
+
+ /**
+ * Add a new menu to this dropdown
+ *
+ * @param options object Any non-default config values for the menu
+ */
+ addMenu: function(options) {
+ var menu = new Dropdown.Menu(this, options);
+ this.menus[menu.config.id] = menu;
+
+ return menu;
+ }
+
+};
+
+var ignoreNextOffClick = false;
+/**
+ * Handles an offClick event fire
+ */
+function offClickHandler() {
+ if (ignoreNextOffClick)
+ ignoreNextOffClick = false;
+ else
+ Dropdown.prototype.closeAll();
+}
+
+/**
+ * Initialize the new menu settings
+ *
+ * @param dropdown object Reference to dropdown object
+ * @param options object Any non-default config values
+ */
+Dropdown.Menu = function Dropdown_Menu(dropdown, options) {
+ // Save reference to dropdown object
+ this.dropdown = dropdown;
+
+ // Set menu config defaults
+ if (!options)
+ options = {};
+
+ var config = {
+ 'level': (options.level ? options.level : 1),
+ 'name': (options.name ? options.name : ''),
+ 'scrolling': (typeof options.scrolling != 'undefined' ? options.scrolling : false),
+ 'showNoneForLevel1': (typeof options.showNoneForLevel1 != 'undefined' ? options.showNoneForLevel1 : true)
+ };
+
+ this.config = config;
+
+ // Insert menu into DOM
+ this.insert();
+};
+
+Dropdown.Menu.prototype = {
+ callString: '',
+
+ /**
+ * Insert the new menu into the DOM
+ */
+ insert: function() {
+ // Generate menu id
+ this.config.id = this.dropdown.config.id + '_' + this.config.name;
+
+ // Set callString for easier reference
+ this.callString = this.dropdown.callString + ".menus['" + this.config.id + "']";
+
+ // Build HTML
+ var menu = '<ul id="' + this.config.id + '" class="level' + this.config.level;
+ if (this.config.scrolling)
+ menu += ' scrolling';
+ menu += '"></ul>';
+
+ // Append the new menu
+ $('#' + this.dropdown.config.id).append(menu);
+
+ // If level 1, show <none> as first menu item and select it
+ if (this.config.level == 1 && this.config.showNoneForLevel1)
+ this.addItem({'name': '<span class="none">&lt;' + localized['statistics_js_dropdowns_none'] + '&gt;</span>'}).select();
+ },
+
+ /**
+ * Shows a menu or submenu
+ *
+ * @param a object The link object that called the method.
+ */
+ show: function(a) {
+ // Only show if the submenu is not already open
+ if ($('#' + this.config.id).is(':hidden')) {
+ $(a).addClass('active-item');
+ $('#' + this.config.id).animate({width: 'show'});
+ }
+ },
+
+ /**
+ * Hides a menu or submenu
+ */
+ hide: function(trigger) {
+ if (trigger)
+ var except = ':not(#' + $(trigger).attr('opens') + ')';
+ else
+ var except = '';
+
+ if (this.config.level < 3) {
+ $('.plot-dropdown > ul.level3:visible' + except).animate({width: 'hide'}, 'fast');
+ $('.plot-dropdown > ul.level3 .active-item').removeClass('active-item');
+ $('.plot-dropdown > ul.level2 .active-item').removeClass('active-item');
+ }
+
+ if (this.config.level < 2) {
+ $('.plot-dropdown > ul.level2:visible' + except).animate({width: 'hide'}, 'fast');
+ $('.plot-dropdown > ul .active-item').removeClass('active-item');
+ }
+ },
+
+ /*************************************************************************/
+
+ items: {},
+
+ /**
+ * Add a new item to this menu
+ *
+ * @param options object Any non-default config values for the new item
+ */
+ addItem: function(options) {
+ var item = new Dropdown.Menu.Item(this, options);
+ this.items[item.config.id] = item;
+
+ return item;
+ },
+
+ addDivider: function() {
+ // Build HTML
+ var divider = '<li class="menu-divider"></li>';
+
+ $('#' + this.config.id).append(divider);
+ }
+};
+
+/**
+ * Initialize the new item settings
+ *
+ * @param menu object Reference to the parent menu object
+ * @param options object Any non-default config values
+ */
+Dropdown.Menu.Item = function Dropdown_Menu_Item(menu, options) {
+ // Save reference to menu object
+ this.menu = menu;
+
+ // Set item config defaults
+ if (!options)
+ options = {};
+
+ var config = {
+ 'value': (options.value ? options.value : ''),
+ 'name': (options.name ? options.name : ''),
+ 'nameChecked': (options.nameChecked ? options.nameChecked : ''),
+ 'nameUnchecked': (options.nameUnchecked ? options.nameUnchecked : ''),
+ 'tooltip': (options.tooltip ? options.tooltip : ''),
+ 'checked': (typeof options.checked != 'undefined' ? options.checked : false),
+ 'isSubmenu': (typeof options.isSubmenu != 'undefined' ? options.isSubmenu : false),
+ 'prefix': (options.prefix ? options.prefix : ''),
+ 'onSelect': (options.onSelect ? options.onSelect : null),
+ 'addValueToClass': (typeof options.addValueToClass != 'undefined' ? options.addValueToClass : false),
+ 'indented': (typeof options.indented != 'undefined' ? options.indented : false)
+ };
+
+ this.config = config;
+
+ // Insert item into DOM
+ this.insert();
+};
+
+Dropdown.Menu.Item.prototype = {
+ callString: '',
+
+ /**
+ * Inserts the new item into the DOM
+ */
+ insert: function() {
+ // Generate item id
+ this.config.id = this.menu.config.id + '_' + this.config.value;
+
+ // Set callString for easier reference
+ this.callString = this.menu.callString + ".items['" + this.config.id + "']";
+
+ // Build HTML
+ var item = '<li id="' + this.config.id + '" class="plot-item';
+ if (this.config.isSubmenu)
+ item += ' submenu';
+ if (this.config.addValueToClass)
+ item += ' ' + this.config.value;
+ if (this.config.checked)
+ item += ' checked';
+ if (this.config.indented)
+ item += ' indented';
+ item += '"><a title="' + this.config.tooltip + '" ';
+
+ if (this.config.isSubmenu) {
+ // Create the submenu
+ this.submenu = this.menu.dropdown.addMenu({
+ 'name': this.config.value,
+ 'level': (this.menu.config.level + 1),
+ 'scrolling': this.menu.config.scrolling
+ });
+
+ item += 'opens="' + this.submenu.config.id + '" ';
+
+ // Submenu items show their submenus on click and mouseover
+ item += 'onclick="ignoreNextOffClick = true;';
+ item += this.submenu.callString + '.show(this);" ';
+ item += 'onmouseover="' + this.menu.callString + '.hide(this); ';
+ item += this.submenu.callString + '.show(this);">';
+ }
+ else {
+ // regular items close any open submenus on mouseover and select themselves on click
+ item += 'onmouseover="' + this.menu.callString + '.hide();" ';
+ item += 'onclick="' + this.callString + '.select(this);">';
+ }
+
+ if (this.menu.dropdown.config.itemsToggle)
+ item += '<div class="item-toggle-icon"></div>';
+
+ item += '<span class="item-name">' + this.config.name + '</span></a></li>';
+
+ $('#' + this.menu.config.id).append(item);
+ },
+
+ /**
+ * Selects the current item in the dropdown and calls to update the dropdown
+ * DOM
+ *
+ * @param a object DOM link that called the selection. Not used here but may
+ * be used in an onSelect callback. (Optional)
+ */
+ select: function(a) {
+ if (!this.menu.dropdown.config.itemsToggle) {
+ this.menu.dropdown.selectedItem = this.config;
+
+ this.menu.dropdown.updateSelection();
+ }
+ else {
+ ignoreNextOffClick = true;
+
+ if (this.config.checked) {
+ this.config.checked = false;
+ $('#' + this.config.id).removeClass('checked');
+
+ if (this.config.nameUnchecked != '') {
+ this.config.name = this.config.nameUnchecked;
+ this.refreshDOM();
+ }
+ }
+ else {
+ this.config.checked = true;
+ $('#' + this.config.id).addClass('checked');
+
+ if (this.config.nameChecked != '') {
+ this.config.name = this.config.nameChecked;
+ this.refreshDOM();
+ }
+ }
+ }
+
+ // Execute any onSelect events the item has
+ if (this.config.onSelect)
+ eval(this.config.onSelect);
+ },
+
+ refreshDOM: function() {
+ $('#' + this.config.id + ' .item-name').html(this.config.name);
+ }
+};
diff --git a/site/app/webroot/js/stats/plot-selection.js b/site/app/webroot/js/stats/plot-selection.js
new file mode 100755
index 0000000..805e3b9
--- /dev/null
+++ b/site/app/webroot/js/stats/plot-selection.js
@@ -0,0 +1,380 @@
+var plotSelection = {
+ summary: {}, // JSON summary retrieved with field names and other data
+ dropdowns: {},
+
+ /**************************************
+ * Dropdown Data Utilities *
+ *************************************/
+
+ /**
+ * Loads plotSelection.summary data from JSON
+ */
+ loadSummary: function() {
+ $.getJSON(statsURL + 'json/' + addonID + '/summary', function(data) {
+ plotSelection.summary = data;
+ });
+
+ },
+
+ /**************************************
+ * Dropdown Creation Utilities *
+ *************************************/
+
+ addPlotSelector: function() {
+ var dropdown = new Dropdown({
+ 'id': 'plot-selector',
+ 'type': 'big-menu',
+ 'onChange': 'Plots.determinePlot();',
+ 'hasColorbox': false,
+ 'parentDOM': 'plot-selector-area',
+ 'removeOnNewTimeplot': false
+ });
+
+ this.dropdowns[dropdown.config.id] = dropdown;
+
+ var menu = this.dropdowns[dropdown.config.id].addMenu({
+ 'name': 'plotselectionmenu',
+ 'showNoneForLevel1': false
+ });
+
+ menu.addItem({'value': 'summary', 'name': localized['statistics_js_plotselection_selector_summary']}).select();
+ menu.addItem({'value': 'downloads', 'name': localized['statistics_js_plotselection_selector_downloads']});
+ menu.addItem({'value': 'updatepings', 'name': localized['statistics_js_plotselection_selector_adu']});
+ menu.addItem({'value': 'version', 'name': localized['statistics_js_plotselection_selector_version'], 'indented': true});
+ menu.addItem({'value': 'application', 'name': localized['statistics_js_plotselection_selector_application'], 'indented': true});
+ menu.addItem({'value': 'status', 'name': localized['statistics_js_plotselection_selector_status'], 'indented': true});
+ menu.addItem({'value': 'os', 'name': localized['statistics_js_plotselection_selector_os'], 'indented': true});
+ //menu.addItem({'value': 'custom', 'name': localized['statistics_js_plotselection_selector_custom']});
+ },
+
+ addGroupBySelector: function() {
+ var group_drop = new Dropdown({
+ 'id': 'group-by-selector',
+ 'type': 'group-by',
+ 'onChange': 'Plots.determinePlot();',
+ 'hasColorbox': false,
+ 'parentDOM': 'plot-selector-area',
+ 'removeOnNewTimeplot': false
+ });
+ this.dropdowns['group-by-selector'] = group_drop;
+ var menu = group_drop.addMenu({
+ 'name': 'group-by-selection-menu',
+ 'showNoneForLevel1': false
+ });
+
+ menu.addItem({'value': 'date', 'name': localized['statistics_js_groupby_selector_date']}).select();
+ menu.addItem({'value': 'week', 'name': localized['statistics_js_groupby_selector_week']});
+ menu.addItem({'value': 'month', 'name': localized['statistics_js_groupby_selector_month']});
+ menu.addItem({'value': 'week_over_week', 'name':localized['statistics_js_groupby_selector_week_over_week']});
+
+ $('#group-by-selector').hide();
+ },
+
+ getGroupByValue: function() {
+ return (!this.dropdowns['group-by-selector']) ? 'date' :
+ this.dropdowns['group-by-selector'].selectedItem.value;
+ },
+
+ addAdditionalDropdown: function() {
+ var type = plotSelection.dropdowns['plot-selector'].selectedItem.value;
+
+ if (type == 'custom')
+ this.addCustomDropdown();
+ else
+ this.addDefinedDropdown();
+ },
+
+ /**
+ * Adds a custom dropdown with menus and submenus from summary
+ */
+ addCustomDropdown: function() {
+ // Add dropdown
+ var dropdown = new Dropdown({
+ 'type': 'custom', 'removeOnNewTimeplot': true
+ });
+
+ this.dropdowns[dropdown.config.id] = dropdown;
+
+ // Add data type menu
+ var typeMenu = this.dropdowns[dropdown.config.id].addMenu({
+ 'type': 'custom'
+ });
+
+ $.each(this.summary.updatepings.plotFields, function(field, values) {
+ // Add data type items
+ var typeItem = typeMenu.addItem({
+ 'value': field,
+ 'name': plotSelection.summary.prettyNames[field],
+ 'isSubmenu': true
+ });
+
+ // Loop through values (versions, statuses, app names, etc)
+ $.each(values, function(item, count) {
+ if (typeof count != 'object') {
+ // If not an object, regular menu item
+ typeItem.submenu.addItem({
+ 'value': item,
+ 'name': item,
+ 'tooltip': sprintf(localized['statistics_js_plotselection_foundinrange'], count)
+ });
+ }
+ else {
+ // If an object, it's an application
+
+ // Filter GUID to make for better id=""
+ var filtered = item.replace(/[\s\@\.\?\{\}\-\"%<>]/g, '_');
+
+ // Add application name item
+ var appName = (item in plotSelection.summary.prettyNames ? plotSelection.summary.prettyNames[item] : plotSelection.summary.prettyNames['unknown'] + ' ' + item);
+
+ var appItem = typeItem.submenu.addItem({
+ 'value': filtered,
+ 'name': appName,
+ 'tooltip': 'GUID: ' + item,
+ 'isSubmenu': true
+ });
+
+ // Loop through application versions
+ $.each(count, function(appVersion, appCount) {
+ // Add item for application version
+ appItem.submenu.addItem({
+ 'value': appVersion,
+ 'name': appVersion,
+ 'tooltip': sprintf(localized['statistics_js_plotselection_foundinrange'], appCount)
+ });
+ });
+ }
+ });
+ });
+ },
+
+ addDefinedDropdowns: function() {
+ this.addOptionsDropdown();
+
+ for (var i = 2; i < 8; i++) {
+ if (Plots.availableFields[i]) {
+ this.addDefinedDropdown(i);
+ }
+ }
+
+ },
+
+ addDefinedDropdown: function(selectedIndex) {
+ var type = this.dropdowns['plot-selector'].selectedItem.value;
+
+ var dropdown = new Dropdown({
+ 'type': type,
+ 'onChange': 'plotSelection.definedChanged(this);'
+ });
+
+ this.dropdowns[dropdown.config.id] = dropdown;
+
+ var menu = this.dropdowns[dropdown.config.id].addMenu({
+ 'name': type,
+ 'scrolling': true
+ });
+
+ var item;
+
+ if (type == 'application') {
+ var appMenus = {};
+ }
+
+ for (var j = 2; j < Plots.availableFields.length; j++) {
+ if (type == 'application') {
+ var appInfo = this.getApplicationName(Plots.availableFields[j]);
+
+ if (!appMenus[appInfo.guid]) {
+ // Filter GUID to make for better id=""
+ var filtered = appInfo.guid.replace(/[\s\@\.\?\{\}\-\"%<>]/g, '_');
+
+ // Add application name item
+ var appName = (appInfo.guid in plotSelection.summary.prettyNames ? plotSelection.summary.prettyNames[appInfo.guid] : plotSelection.summary.prettyNames['unknown'] + ' ' + appInfo.guid);
+
+ appMenus[appInfo.guid] = menu.addItem({
+ 'value': filtered,
+ 'name': appName,
+ 'tooltip': 'GUID: ' + appInfo.guid,
+ 'isSubmenu': true
+ });
+ }
+
+ item = appMenus[appInfo.guid].submenu.addItem({
+ 'value': Plots.availableFields[j],
+ 'name': appInfo.itemName,
+ 'tooltip': appInfo.itemTooltip,
+ 'prefix': (plotSelection.summary.shortNames[type] ? plotSelection.summary.shortNames[type] + ':' : '')
+ });
+ }
+ else
+ item = menu.addItem({
+ 'value': Plots.availableFields[j],
+ 'name': Plots.availableFields[j],
+ 'prefix': (plotSelection.summary.shortNames[type] ? plotSelection.summary.shortNames[type] + ':' : '')
+ });
+
+
+ if (selectedIndex == j)
+ item.select();
+ }
+ },
+
+ getApplicationName: function(guid) {
+ var appParts = guid.split('/');
+ if (plotSelection.summary.shortNames[plotSelection.summary.prettyNames[appParts[0]]]) {
+ var itemName = plotSelection.summary.shortNames[plotSelection.summary.prettyNames[appParts[0]]] + '&nbsp;' + appParts[1];
+ var itemTooltip = appParts[0] + ' (' + plotSelection.summary.prettyNames[appParts[0]] + ')';
+ }
+ else {
+ var itemName = plotSelection.summary.shortNames['unknown'] + '&nbsp;' + appParts[1];
+ var itemTooltip = appParts[0] + ' (' + plotSelection.summary.prettyNames['unknown'] + ')';
+ }
+
+ return {'guid': appParts[0], 'version': appParts[1], 'itemName': itemName, 'itemTooltip': itemTooltip};
+ },
+
+ definedChanged: function(dropdown) {
+ // Remove existing plot
+ Plots.defined.removePlot(dropdown.config.id);
+
+ // If not clearing the plot, add the new selected plot
+ if (dropdown.selectedItem.value != '') {
+ Plots.defined.addPlot(dropdown.config.id, Plots.availableFields.indexOf(dropdown.selectedItem.value), dropdown.config.color);
+ }
+ },
+
+ addOptionsDropdown: function() {
+ var type = this.dropdowns['plot-selector'].selectedItem.value;
+
+ var dropdown = new Dropdown({
+ 'id': 'options',
+ 'type': 'options',
+ 'title': '<img src="' + $('#options-cog').attr('src') + '" />',
+ 'removeOnNewTimeplot': true,
+ 'removable': false,
+ 'hasColorbox': false,
+ 'itemsToggle': true,
+ 'parentDOM': 'options-area'
+ });
+
+ this.dropdowns[dropdown.config.id] = dropdown;
+
+ var menu = this.dropdowns[dropdown.config.id].addMenu({
+ 'name': 'options',
+ 'showNoneForLevel1': false
+ });
+
+ if (type != 'summary' && type != 'downloads') {
+ menu.addItem({
+ 'value': 'count',
+ 'name': localized['statistics_js_plotselection_options_count_name_checked'],
+ 'nameChecked': localized['statistics_js_plotselection_options_count_name_checked'],
+ 'nameUnchecked': localized['statistics_js_plotselection_options_count_name_unchecked'],
+ 'tooltip': localized['statistics_js_plotselection_options_count_tooltip'],
+ 'checked': true,
+ 'onSelect': 'plotSelection.togglePlot(this);',
+ 'addValueToClass': true
+ });
+ }
+
+ if (type != 'summary') {
+ menu.addItem({
+ 'value': 'events-firefox',
+ 'name': localized['statistics_js_plotselection_options_events_firefox_name_checked'],
+ 'nameChecked': localized['statistics_js_plotselection_options_events_firefox_name_checked'],
+ 'nameUnchecked': localized['statistics_js_plotselection_options_events_firefox_name_unchecked'],
+ 'tooltip': localized['statistics_js_plotselection_options_events_firefox_tooltip'],
+ 'checked': true,
+ 'onSelect': 'plotSelection.toggleEventPlot(this);',
+ 'addValueToClass': true
+ });
+
+ var addonItem = menu.addItem({
+ 'value': 'events-addon',
+ 'name': sprintf(localized['statistics_js_plotselection_options_events_addon_name_checked'], addonName),
+ 'nameChecked': sprintf(localized['statistics_js_plotselection_options_events_addon_name_checked'], addonName),
+ 'nameUnchecked': sprintf(localized['statistics_js_plotselection_options_events_addon_name_unchecked'], addonName),
+ 'tooltip': localized['statistics_js_plotselection_options_events_addon_tooltip'],
+ 'checked': true,
+ 'onSelect': 'plotSelection.toggleEventPlot(this);',
+ 'addValueToClass': true
+ });
+ $('#' + addonItem.config.id + ' .item-toggle-icon').html('<img src="' + $('#addon-icon').attr('src') + '" width="16" height="16" />');
+ }
+
+ if (type != 'summary' && type != 'downloads') {
+ menu.addItem({
+ 'value': 'add-plot',
+ 'name': localized['statistics_js_plotselection_options_addplot_name'],
+ 'tooltip': localized['statistics_js_plotselection_options_addplot_tooltip'],
+ 'onSelect': 'plotSelection.addAdditionalDropdown();',
+ 'addValueToClass': true
+ });
+ }
+
+ if (type != 'summary')
+ menu.addDivider();
+
+ menu.addItem({
+ 'value': 'resize',
+ 'name': localized['statistics_js_plotselection_options_resize_name_unchecked'],
+ 'nameChecked': localized['statistics_js_plotselection_options_resize_name_checked'],
+ 'nameUnchecked': localized['statistics_js_plotselection_options_resize_name_unchecked'],
+ 'tooltip': localized['statistics_js_plotselection_options_resize_tooltip'],
+ 'onSelect': 'plotSelection.resizePlot(this);',
+ 'addValueToClass': true
+ });
+
+ /*menu.addItem({
+ 'value': 'rss',
+ 'name': 'Subscribe to Graph',
+ 'tooltip': 'Subscribe to this graph for daily updates',
+ 'addValueToClass': true
+ });*/
+
+ var csvItem = menu.addItem({
+ 'value': 'csv',
+ 'name': localized['statistics_js_plotselection_options_csv_name'],
+ 'tooltip': localized['statistics_js_plotselection_options_csv_tooltip'],
+ 'addValueToClass': true
+ });
+ $('#' + csvItem.config.id + ' a').attr('href', Plots.currentCSV);
+ },
+
+ togglePlot: function(item) {
+ if (item.config.checked)
+ Plots.defined.addPlot(item.config.value, 1, '#000000');
+ else
+ Plots.defined.removePlot(item.config.value);
+ },
+
+ toggleEventPlot: function(item) {
+ if (item.config.checked)
+ Plots.defined.addEventPlot(item.config.value);
+ else
+ Plots.defined.removePlot(item.config.value);
+ },
+
+ resizePlot: function(item) {
+ if (item.config.checked)
+ Plots.resizePlot(350);
+ else
+ Plots.resizePlot(150);
+ },
+
+ remove: function(dropdown) {
+ Plots.defined.removePlot(dropdown.config.id);
+ plotSelection.dropdowns[dropdown.config.id] = null;
+ },
+
+ removeAll: function() {
+ colors.resetCounter();
+
+ $.each(plotSelection.dropdowns, function(dropdown_id, object) {
+ if (plotSelection.dropdowns[dropdown_id] != null) {
+ if (plotSelection.dropdowns[dropdown_id].remove(true))
+ plotSelection.dropdowns[dropdown_id] = null;
+ }
+ });
+ }
+};
diff --git a/site/app/webroot/js/stats/plot-tables.js b/site/app/webroot/js/stats/plot-tables.js
new file mode 100644
index 0000000..106c3e6
--- /dev/null
+++ b/site/app/webroot/js/stats/plot-tables.js
@@ -0,0 +1,191 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * l.m.orchard <lorchard@mozilla.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/**
+ * Machinery to dynamically build tables based on incoming plot data.
+ */
+var PlotsTables = (function() {
+
+ var MAX_ROWS = 28;
+
+ var source_names = [
+ 'downloads', 'updatepings', 'count', 'events-firefox', 'events-addon'
+ ];
+ var event_names = [
+ 'onAddMany', 'onAddOne', 'onClear'
+ ];
+
+ return {
+
+ init: function() {
+ return this;
+ },
+
+ summary_downloads_onAddMany: function(source) {
+ // Clear any existing tables when the summary comes up.
+ $('#stats-table').hide();
+ $('#stats-table-instance').remove();
+ },
+
+ week_over_week_count_onAddMany: function(source) {
+ // Clear any existing tables when week-over-week comes up
+ $('#stats-table').hide();
+ $('#stats-table-instance').remove();
+ },
+
+ defined_count_onAddMany: function(source) {
+
+ // Set the URL for the download link.
+ $('#stats-table>a').attr('href', Plots.currentCSV);
+
+ // Convert all the events into an array of arrays.
+ var data_rows = [],
+ evt, i_evt = source.getAllEventIterator();
+ while (evt = i_evt.next()) {
+ data_rows.push(
+ [ evt.getTime() ].concat( evt.getValues() )
+ );
+ }
+
+ // Sort the rows in reverse-chronological order and take
+ // the latest MAX_ROWS off the top.
+ data_rows.sort(function(b,a) {
+ var a=a[0], b=b[0];
+ return (a==b) ? 0 : ( (a<b) ? -1 : 1 );
+ });
+ data_rows = data_rows.slice(0, MAX_ROWS);
+
+ // Instantiate a clone from the hidden stats table template.
+ var stats_table = $('#stats-table>.template')
+ .clone().removeClass('template')
+ .attr('id', 'stats-table-instance');
+
+ // Fill in the header with the available fields.
+ var header = stats_table.find('tr.header'),
+ h_col = header.find('th').remove();
+ for (var i=0,field; field=Plots.availableFields[i]; i++) {
+ if (field.substr(0,1) == '{') {
+ // Try to pretty up headers that look like app GUIDs
+ field = plotSelection
+ .getApplicationName(field)['itemName'];
+ }
+ h_col.clone().html(field).appendTo(header);
+ }
+
+ // Mark the first/last headers for CSS.
+ header
+ .find('th:first').addClass('first').end()
+ .find('th:last').addClass('last');
+
+ // Remove any existing table and insert the new one.
+ $('#stats-table-instance').remove();
+ $('#stats-table').append(stats_table).show();
+
+ // Get localized date format and un-escape it.
+ var date_fmt = localized.date.replace(/&#37;/g,'%');
+
+ // Wrap the table population in a self-calling timeout function
+ // in order to keep the browser from completely freezing during
+ // the process. Also provides cheap loading animation as rows
+ // flow in.
+ var tmpl_row = stats_table.find('tr.row').remove();
+ var is_even_row = false;
+ (function() {
+
+ // Try getting a data row, bail out if none left.
+ var values = data_rows.shift();
+ if (!values) {
+ // Tag the first and last rows.
+ stats_table
+ .find('tr:first').addClass('first').end()
+ .find('tr:last').addClass('last').end();
+ return;
+ }
+
+ // Format the date using the localized format
+ values[0] = values[0].strftime(date_fmt);
+
+ // Clone a new row and populate it with the values.
+ var row = tmpl_row.clone(),
+ col = row.find('td.col').remove();
+ for (var j=0,value; value=values[j]; j++) {
+ col.clone().text(value).appendTo(row);
+ }
+
+ // Set the even/odd row class and mark first/last columns.
+ row.addClass( is_even_row ? 'even' : 'odd' )
+ .find('td:first').addClass('first').end()
+ .find('td:last').addClass('last');
+ is_even_row = !is_even_row;
+
+ // Finally, add the row to the table and schedule a call for
+ // the next row.
+ stats_table.append(row);
+ setTimeout(arguments.callee, 0);
+
+ })();
+
+ },
+
+ addListeners: function(kind, dataSources) {
+ for (var i=0,name; name=source_names[i]; i++) {
+ var source = dataSources[name];
+ if (source) this.addListener(kind, name, source);
+ }
+ },
+
+ addListener: function(kind, source_name, source) {
+ var listener = {},
+ fn_pre = kind + '_' + source_name;
+ for (var i=0,evt_name; evt_name=event_names[i]; i++) {
+ var fn = fn_pre + '_' + evt_name;
+ if (this[fn])
+ listener[evt_name] = this.makeListener(fn, source);
+ }
+ source.addListener(listener);
+ },
+
+ makeListener: function(fn, source) {
+ var that = this;
+ return function() {
+ return that[fn](source)
+ }
+ },
+
+ EOF: null
+ }
+})().init();
diff --git a/site/app/webroot/js/stats/plots.js b/site/app/webroot/js/stats/plots.js
new file mode 100755
index 0000000..48f792e
--- /dev/null
+++ b/site/app/webroot/js/stats/plots.js
@@ -0,0 +1,577 @@
+var Plots = {
+ timeplot_id: '',
+ timeplotCount: 0,
+ timeplot: null,
+ availableFields: [],
+ currentCSV: '',
+
+ determinePlot: function() {
+ var selected = plotSelection.dropdowns['plot-selector'].selectedItem.value;
+ var group_by = plotSelection.getGroupByValue();
+
+ // Remove current plot selections
+ plotSelection.removeAll();
+
+ // Make sure summary-specific options are shown or hidden as approp.
+ this.summary.updateOptionsVisibility();
+
+ if (selected == 'summary')
+ this.summary.initialize();
+ else if (selected == 'custom')
+ Plots.customPlot();
+ else
+ Plots.defined.initialize();
+ },
+
+ newTimeplot: function() {
+ if (this.timeplot_id != '') {
+ $('#' + this.timeplot_id).remove();
+ this.timeplot = null;
+ }
+ this.timeplotCount++;
+
+ $('#not-enough-data').hide();
+
+ this.timeplot_id = 'timeplot' + this.timeplotCount;
+ $('#timeplot-container').append('<div id="' + this.timeplot_id + '" class="timeplot"></div>');
+ },
+
+ summary: {
+ dataSources: {},
+ timeGeometry: {},
+ valueGeometry: {},
+ plotInfo: {},
+ zoomLevel: 0,
+
+ initialize: function() {
+ this.dataSources = {
+ 'downloads': new Timeplot.DefaultEventSource(),
+ 'updatepings': new Timeplot.DefaultEventSource()
+ };
+
+ PlotsTables.addListeners('summary', this.dataSources);
+
+ this.valueGeometry = {
+ 'downloads': {
+ 'gridColor': '#000000',
+ 'axisLabelsPlacement': 'left'
+ },
+ 'updatepings': {
+ 'gridColor': '#9966CC',
+ 'axisLabelsPlacement': 'right'
+ }
+ };
+
+ this.timeGeometry = {
+ 'gridColor': '#000000',
+ 'axisLabelsPlacement': 'bottom',
+ 'min': this.getInitialMinDate()
+ };
+
+ this.plotInfo = {
+ 'downloads': {
+ 'id': 'downloads',
+ 'dataSource': new Timeplot.ColumnSource(this.dataSources['downloads'], 1),
+ 'valueGeometry': new Timeplot.DefaultValueGeometry(this.valueGeometry['downloads']),
+ 'showValues': true,
+ 'dotColor': '#33AAFF',
+ 'dotRadius': 3.0,
+ 'lineColor': '#33AAFF',
+ 'lineWidth': 3.0
+ },
+ 'updatepings': {
+ 'id': 'updatepings',
+ 'dataSource': new Timeplot.ColumnSource(this.dataSources['updatepings'], 1),
+ 'valueGeometry': new Timeplot.DefaultValueGeometry(this.valueGeometry['updatepings']),
+ 'showValues': true,
+ 'dotColor': '#EE3322',
+ 'dotRadius': 3.0,
+ 'lineColor': '#EE3322',
+ 'lineWidth': 3.0
+ }
+ };
+
+ this.plot();
+ this.zoomLevel = 0;
+ this.updateButtonVisibility();
+ },
+
+ plot: function() {
+ var timeGeometry = new Timeplot.DefaultTimeGeometry(this.timeGeometry);
+
+ this.plotInfo['downloads'].timeGeometry = timeGeometry;
+ this.plotInfo['updatepings'].timeGeometry = timeGeometry;
+
+ var plotInfo = [
+ Timeplot.createPlotInfo(this.plotInfo['downloads']),
+ Timeplot.createPlotInfo(this.plotInfo['updatepings'])
+ ];
+
+ Plots.newTimeplot();
+ Plots.timeplot = Timeplot.create(document.getElementById(Plots.timeplot_id), plotInfo);
+ Plots.timeplot.loadText(statsURL + 'csv/' + addonID + '/downloads', ",", this.dataSources['downloads']);
+ Plots.timeplot.loadText(statsURL + 'csv/' + addonID + '/updatepings', ",", this.dataSources['updatepings']);
+ },
+
+ zoomIn: function() {
+ this.zoomLevel++;
+ this.updateButtonVisibility();
+
+ var date = this.timeGeometry.min;
+ var matches = /^(\d{4})-(\d{2})-(\d{2})$/.exec(date);
+
+ if (matches[2] != 12)
+ var newDate = matches[1] + '-' + this.leadingZero(parseInt(matches[2]) + 1) + '-01';
+ else
+ var newDate = (parseInt(matches[1]) + 1) + '-01-01'
+
+ this.timeGeometry.min = newDate;
+
+ this.plot();
+ },
+
+ zoomOut: function() {
+ this.zoomLevel--;
+ this.updateButtonVisibility();
+
+ var date = this.timeGeometry.min;
+ var matches = /^(\d{4})-(\d{2})-(\d{2})$/.exec(date);
+
+ if (matches[2] != 1)
+ var newDate = matches[1] + '-' + this.leadingZero(parseInt(matches[2]) - 1) + '-01';
+ else
+ var newDate = (parseInt(matches[1]) - 1) + '-12-01'
+
+ this.timeGeometry.min = newDate;
+ this.updateDotRadius();
+
+ this.plot();
+ },
+
+ updateOptionsVisibility: function() {
+ var plotType = plotSelection.dropdowns['plot-selector'].selectedItem.value;
+
+ if (plotType == 'summary') {
+ $('#weeks-legend').hide();
+ $('#summary-legend').show();
+ $('#summary-options').show();
+ $('#group-by-selector').hide();
+ }
+ else {
+ $('#weeks-legend').hide();
+ $('#summary-legend').hide();
+ $('#summary-options').hide();
+ $('#group-by-selector').show();
+ }
+ },
+
+ updateButtonVisibility: function() {
+ if (this.zoomLevel >= 0)
+ $('#zoom-in').addClass('disabled');
+ else
+ $('#zoom-in').removeClass('disabled');
+ },
+
+ updateDotRadius: function() {
+ if (this.zoomLevel >= -1 && this.zoomLevel <= 1) {
+ this.plotInfo['downloads'].dotRadius = 3.0;
+ this.plotInfo['updatepings'].dotRadius = 3.0;
+ }
+ else if (this.zoomLevel >= -3 && this.zoomLevel <= 3) {
+ this.plotInfo['downloads'].dotRadius = 2.0;
+ this.plotInfo['updatepings'].dotRadius = 2.0;
+ }
+ else {
+ this.plotInfo['downloads'].dotRadius = 1.0;
+ this.plotInfo['updatepings'].dotRadius = 1.0;
+ }
+ },
+
+ getInitialMinDate: function() {
+ var currentTime = new Date();
+ var year = currentTime.getFullYear();
+ var month = currentTime.getMonth() + 1;
+ var day = currentTime.getDate();
+
+ if (day < 15) {
+ if (month == 1) {
+ month = 12;
+ year--;
+ }
+ else
+ month--;
+ day = 15;
+ }
+ else if (day >= 15) {
+ day = 1;
+ }
+
+ var date = year + '-' + this.leadingZero(month) + '-' + this.leadingZero(day);
+
+ return date;
+
+ },
+
+ leadingZero: function(number) {
+ return (number < 10 ? '0' + number : number);
+ }
+ },
+
+ defined: {
+ dataSources: {},
+ timeGeometry: {},
+ valueGeometry: {},
+ plotInfo: {},
+
+ initialize: function() {
+ var type = plotSelection.dropdowns['plot-selector'].selectedItem.value;
+ Plots.currentCSV = statsURL + 'csv/' + addonID + '/' + type;
+
+ // If there's a value for the group-by selector, add it as a
+ // parameter to the CSV URL to invoke it server-side.
+ var group_by = plotSelection.getGroupByValue();
+
+ if ('week_over_week' == group_by) {
+ if ('updatepings' == type || 'downloads' == type) {
+ $('#weeks-legend').show();
+ return this.plotWeekOverWeek();
+ } else {
+ // HACK: Until I can figure out how to disable the Compare
+ // by: Week option for views not supported for it
+ group_by = 'week';
+ }
+ }
+
+ $('#weeks-legend').hide();
+ if (group_by) Plots.currentCSV += '?group_by=' + group_by;
+
+ this.dataSources = {
+ 'count': new Timeplot.DefaultEventSource(),
+ 'events-firefox': new Timeplot.DefaultEventSource(),
+ 'events-addon': new Timeplot.DefaultEventSource()
+ };
+
+ PlotsTables.addListeners('defined', this.dataSources);
+
+ this.valueGeometry = {
+ 'gridColor': '#000000',
+ 'axisLabelsPlacement': 'left',
+ 'min': 0
+ };
+
+ var min = '2007-07-01';
+ if (type == 'downloads' && plotSelection.summary.downloads.availableDates)
+ min = plotSelection.summary.downloads.availableDates[0];
+ else if (plotSelection.summary.updatepings.availableDates)
+ min = plotSelection.summary.updatepings.availableDates[0];
+
+ this.timeGeometry = {
+ 'gridColor': '#000000',
+ 'axisLabelsPlacement': 'top',
+ 'min': min
+ };
+
+ this.plotInfo = {
+ 'count': {
+ 'id': 'count',
+ 'dataSource': new Timeplot.ColumnSource(this.dataSources['count'], 1),
+ 'showValues': true,
+ 'dotColor': '#000000',
+ 'lineColor': '#000000',
+ 'fillColor': '#000000'
+ },
+ 'events-firefox': {
+ 'id': 'events-firefox',
+ 'eventSource': this.dataSources['events-firefox'],
+ 'lineColor': '#000000'
+ },
+ 'events-addon': {
+ 'id': 'events-addon',
+ 'eventSource': this.dataSources['events-addon'],
+ 'lineColor': '#000000'
+ },
+ 'default': {
+ 'showValues': true
+ }
+ };
+
+ if (type == 'downloads' || type == 'updatepings') {
+ if (type == 'downloads') {
+ var dark = '#3366CC';
+ var light = '#3399CC';
+ }
+ else if (type == 'updatepings') {
+ var dark = '#9966CC';
+ var light = '#CC99CC';
+ }
+
+ this.plotInfo['count'].fillColor = dark;
+ this.plotInfo['count'].dotColor = null;
+ this.plotInfo['count'].fillGradient = false;
+
+ this.plotInfo['events-firefox'].lineColor = light;
+ this.plotInfo['events-addon'].lineColor = light;
+ }
+
+ this.plot();
+ },
+
+ plot: function() {
+ var timeGeometry = new Timeplot.DefaultTimeGeometry(this.timeGeometry);
+ var valueGeometry = new Timeplot.DefaultValueGeometry(this.valueGeometry);
+
+ this.plotInfo['count'].timeGeometry = timeGeometry;
+ this.plotInfo['count'].valueGeometry = valueGeometry;
+ this.plotInfo['events-firefox'].timeGeometry = timeGeometry;
+ this.plotInfo['events-addon'].timeGeometry = timeGeometry;
+ this.plotInfo['default'].timeGeometry = timeGeometry;
+ this.plotInfo['default'].valueGeometry = valueGeometry;
+
+ var plotInfo = [
+ Timeplot.createPlotInfo(this.plotInfo['count']),
+ Timeplot.createPlotInfo(this.plotInfo['events-firefox']),
+ Timeplot.createPlotInfo(this.plotInfo['events-addon'])
+ ];
+
+ Plots.newTimeplot();
+ Plots.timeplot = Timeplot.create(document.getElementById(Plots.timeplot_id), plotInfo);
+ Plots.timeplot.loadText(Plots.currentCSV, ",", this.dataSources['count'], parseFields);
+ Plots.timeplot.loadXML(statsURL + 'xml/events/firefox', this.dataSources['events-firefox']);
+ Plots.timeplot.loadXML(statsURL + 'xml/events/addon/' + addonID, this.dataSources['events-addon']);
+ },
+
+ /**
+ * Construct a plot consisting of 2 different weeks' data overlaid on
+ * the same graph.
+ */
+ plotWeekOverWeek: function() {
+
+ var type = plotSelection.dropdowns['plot-selector'].selectedItem.value;
+ Plots.currentCSV = statsURL + 'csv/' + addonID + '/' + type;
+
+ this.dataSources = {
+ 'count': new Timeplot.DefaultEventSource(),
+ };
+
+ PlotsTables.addListeners('week_over_week', this.dataSources);
+
+ var date_parser = Timeline.NativeDateUnit.getParser('iso8601');
+
+ // Collect Mondays from the set of available dates.
+ var available_dates = plotSelection
+ .summary[ (type=='downloads') ? 'downloads' : 'updatepings' ]
+ .availableDates;
+ var dates = [];
+ var DAY_MONDAY = 1;
+ for (idx in available_dates) {
+ // The available dates data is a little weird - it's an object
+ // with numerical properties, instead of an array.
+ if (available_dates.hasOwnProperty(idx)) {
+ var date = date_parser(available_dates[idx]);
+ if (date.getDay() == DAY_MONDAY)
+ dates.push(available_dates[idx]);
+ }
+ }
+
+ // Set up empty ranges set.
+ var ranges = {
+ week1: { min: '', max: '' },
+ week2: { min: '', max: '' }
+ };
+
+ var WEEK = ( 1000 * 60 * 60 * 24 * 7 );
+
+ if ( $('#weeks-legend .template').length ) {
+
+ // The date selection dropdowns still contain unpopulated
+ // templates, so set up the defaults and populate the dropdowns
+
+ ranges['week2']['min'] = date_parser(dates[dates.length - 1]);
+ ranges['week2']['max'] = new Date(ranges['week2']['min'].getTime() + WEEK);
+ ranges['week1']['min'] = date_parser(dates[dates.length - 2]);
+ ranges['week1']['max'] = new Date(ranges['week1']['min'].getTime() + WEEK);
+
+ var weeks = ['week1', 'week2'];
+ for (var i=0, week; week=weeks[i]; i++) {
+
+ // Convert the selection template into a concrete element
+ var tmpl = $('#'+week+'-selection select.template');
+ if (!tmpl.length) continue;
+ tmpl.remove().removeClass('template');
+
+ // Convert the current min date to string for comparison.
+ var min_str = ranges[week]['min'].strftime('%Y-%m-%d');
+
+ // Now populate the selection element with options cloned
+ // and populated from available dates.
+ var t_opt = tmpl.find('option').remove();
+ for (var j=0,date; date=dates[j]; j++) {
+ var opt = t_opt.clone();
+
+ var dp = date.split('-');
+ opt.text([dp[1], dp[2], dp[0]].join('/'))
+ .attr('value', date)
+ .appendTo(tmpl);
+
+ if (date == min_str)
+ opt.attr('selected', 'selected');
+ }
+
+ // Finally inject the populated selector into the DOM and
+ // wire up an onChange handler to reload the plot.
+ tmpl.appendTo('#'+week+'-selection')
+ .change(function() { Plots.determinePlot() });
+ }
+
+ } else {
+
+ // The date selection dropdowns are populated, so set ranges
+ // from the selected values.
+
+ var weeks = ['week1', 'week2'];
+ for (var i=0, week; week=weeks[i]; i++) {
+ var opt = $('#'+week+'-selection select')[0];
+ var date = opt.options[opt.selectedIndex].value;
+ ranges[week]['min'] = date_parser(date);
+ ranges[week]['max'] = new Date(ranges[week]['min'].getTime() + WEEK);
+ }
+
+ }
+
+ // Assemble the time geometries from the selected time ranges.
+ this.timeGeometries = {
+ 'week1': {
+ 'min': ranges['week1']['min'],
+ 'max': ranges['week1']['max'],
+ 'gridColor': '#CC6666',
+ 'axisLabelsPlacement': 'bottom'
+ },
+ 'week2': {
+ 'min': ranges['week2']['min'],
+ 'max': ranges['week2']['max'],
+ 'gridColor': '#6666CC',
+ 'axisLabelsPlacement': 'top'
+ }
+ };
+
+ // Both time ranges share the same value geometry
+ this.valueGeometry = {
+ 'gridColor': '#000000',
+ 'axisLabelsPlacement': 'left',
+ 'min': 0
+ };
+
+ // Construct the plot info structures for each of the overlaid sets.
+ Plots.newTimeplot();
+ Plots.timeplot = Timeplot.create(document.getElementById(Plots.timeplot_id), [
+ Timeplot.createPlotInfo({
+ 'id': 'week1-plot',
+ 'dataSource':
+ new Timeplot.ColumnSource(this.dataSources['count'], 1),
+ 'timeGeometry':
+ new Timeplot.DefaultTimeGeometry(this.timeGeometries['week1']),
+ 'valueGeometry':
+ new Timeplot.DefaultValueGeometry(this.valueGeometry),
+ 'showValues': true,
+ 'dotColor': '#CC6666',
+ 'dotRadius': 3.0,
+ 'lineColor': '#CC6666',
+ 'lineWidth': 3.0,
+ 'fillColor': false
+ }),
+ Timeplot.createPlotInfo({
+ 'id': 'week2-plot',
+ 'dataSource':
+ new Timeplot.ColumnSource(this.dataSources['count'], 1),
+ 'timeGeometry':
+ new Timeplot.DefaultTimeGeometry(this.timeGeometries['week2']),
+ 'valueGeometry':
+ new Timeplot.DefaultValueGeometry(this.valueGeometry),
+ 'showValues': true,
+ 'dotColor': '#6666CC',
+ 'dotRadius': 3.0,
+ 'lineColor': '#6666CC',
+ 'lineWidth': 3.0,
+ 'fillColor': false
+ })
+ ]);
+
+ // Finally, queue up a load for the plot data.
+ Plots.timeplot.loadText(
+ Plots.currentCSV,
+ ",",
+ this.dataSources['count'],
+ parseFields
+ );
+
+ },
+
+ addPlot: function(plotName, column, color) {
+ if (plotName in this.plotInfo)
+ var plotInfo = this.plotInfo[plotName];
+ else {
+ var plotInfo = this.plotInfo['default'];
+ plotInfo.id = plotName;
+ plotInfo.dataSource = new Timeplot.ColumnSource(this.dataSources['count'], column);
+ plotInfo.dotColor = color;
+ plotInfo.lineColor = color;
+ plotInfo.fillColor = color;
+ }
+
+ return Plots.timeplot.addPlot(Timeplot.createPlotInfo(plotInfo), true);
+ },
+
+ addEventPlot: function(plotName) {
+ return Plots.timeplot.addPlot(Timeplot.createPlotInfo(this.plotInfo[plotName]), true);
+ },
+
+ removePlot: function(plotName) {
+ return Plots.timeplot.removePlot(plotName);
+ }
+ },
+
+ customPlot: function() {
+ plotSelection.addCustomDropdown();
+ },
+
+ resizePlot: function(newHeight) {
+ $('#' + Plots.timeplot_id).height(newHeight);
+ Plots.timeplot.repaint();
+ }
+};
+
+function parseFields(data) {
+ if (data != '') {
+ var lineCount = (data.split("\n").length - 9);
+
+ if (lineCount > 1) {
+ // Enough data
+ $('#not-enough-data').hide();
+
+ var start = data.indexOf('Fields: [');
+ var end = data.indexOf(']', start);
+ var fields = data.substring(start + 9, end);
+
+ var fieldArray = fields.split(';');
+
+ Plots.availableFields = [];
+
+ for (var i = 0; i < fieldArray.length; i++) {
+ Plots.availableFields[i] = fieldArray[i];
+ }
+
+ plotSelection.addDefinedDropdowns();
+ }
+ else {
+ // Not enough data
+ $('#not-enough-data').show();
+
+ if (Plots.timeplot_id != '') {
+ $('#' + Plots.timeplot_id).remove();
+ Plots.timeplot = null;
+ }
+ }
+ }
+
+ return data;
+}
diff --git a/site/app/webroot/js/stats/stats.js b/site/app/webroot/js/stats/stats.js
new file mode 100644
index 0000000..a90b98e
--- /dev/null
+++ b/site/app/webroot/js/stats/stats.js
@@ -0,0 +1,65 @@
+/**
+ * Redirect to new add-on
+ */
+function changeAddon(item) {
+ window.location = statsURL + 'addon/' + item.value;
+}
+
+/**
+ * sprintf() implementation for Javascript
+ * http://jan.moesen.nu/code/javascript/sprintf-and-printf-in-javascript/
+ */
+function sprintf()
+{
+ if (!arguments || arguments.length < 1 || !RegExp)
+ {
+ return;
+ }
+ var str = arguments[0];
+ str = str.replace('&#37;', '%');
+ var re = /([^%]*)%('.|0|\x20)?(-)?(\d+)?(\.\d+)?(%|b|c|d|u|f|o|s|x|X)(.*)/;
+ var a = b = [], numSubstitutions = 0, numMatches = 0;
+ while (a = re.exec(str))
+ {
+ var leftpart = a[1], pPad = a[2], pJustify = a[3], pMinLength = a[4];
+ var pPrecision = a[5], pType = a[6], rightPart = a[7];
+
+ //alert(a + '\n' + [a[0], leftpart, pPad, pJustify, pMinLength, pPrecision);
+
+ numMatches++;
+ if (pType == '%')
+ {
+ subst = '%';
+ }
+ else
+ {
+ numSubstitutions++;
+ if (numSubstitutions >= arguments.length)
+ {
+ alert('Error! Not enough function arguments (' + (arguments.length - 1) + ', excluding the string)\nfor the number of substitution parameters in string (' + numSubstitutions + ' so far).');
+ }
+ var param = arguments[numSubstitutions];
+ var pad = '';
+ if (pPad && pPad.substr(0,1) == "'") pad = leftpart.substr(1,1);
+ else if (pPad) pad = pPad;
+ var justifyRight = true;
+ if (pJustify && pJustify === "-") justifyRight = false;
+ var minLength = -1;
+ if (pMinLength) minLength = parseInt(pMinLength);
+ var precision = -1;
+ if (pPrecision && pType == 'f') precision = parseInt(pPrecision.substring(1));
+ var subst = param;
+ if (pType == 'b') subst = parseInt(param).toString(2);
+ else if (pType == 'c') subst = String.fromCharCode(parseInt(param));
+ else if (pType == 'd') subst = parseInt(param) ? parseInt(param) : 0;
+ else if (pType == 'u') subst = Math.abs(param);
+ else if (pType == 'f') subst = (precision > -1) ? Math.round(parseFloat(param) * Math.pow(10, precision)) / Math.pow(10, precision): parseFloat(param);
+ else if (pType == 'o') subst = parseInt(param).toString(8);
+ else if (pType == 's') subst = param;
+ else if (pType == 'x') subst = ('' + parseInt(param).toString(16)).toLowerCase();
+ else if (pType == 'X') subst = ('' + parseInt(param).toString(16)).toUpperCase();
+ }
+ str = leftpart + subst + rightPart;
+ }
+ return str;
+}
diff --git a/site/app/webroot/js/strftime-min-1.3.js b/site/app/webroot/js/strftime-min-1.3.js
new file mode 100644
index 0000000..8207714
--- /dev/null
+++ b/site/app/webroot/js/strftime-min-1.3.js
@@ -0,0 +1 @@
+Date.ext={};Date.ext.util={};Date.ext.util.xPad=function(x,pad,r){if(typeof (r)=="undefined"){r=10}for(;parseInt(x,10)<r&&r>1;r/=10){x=pad.toString()+x}return x.toString()};Date.prototype.locale="en-GB";if(document.getElementsByTagName("html")&&document.getElementsByTagName("html")[0].lang){Date.prototype.locale=document.getElementsByTagName("html")[0].lang}Date.ext.locales={};Date.ext.locales.en={a:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],A:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],b:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],B:["January","February","March","April","May","June","July","August","September","October","November","December"],c:"%a %d %b %Y %T %Z",p:["AM","PM"],P:["am","pm"],x:"%d/%m/%y",X:"%T"};Date.ext.locales["en-US"]=Date.ext.locales.en;Date.ext.locales["en-US"].c="%a %d %b %Y %r %Z";Date.ext.locales["en-US"].x="%D";Date.ext.locales["en-US"].X="%r";Date.ext.locales["en-GB"]=Date.ext.locales.en;Date.ext.locales["en-AU"]=Date.ext.locales["en-GB"];Date.ext.formats={a:function(d){return Date.ext.locales[d.locale].a[d.getDay()]},A:function(d){return Date.ext.locales[d.locale].A[d.getDay()]},b:function(d){return Date.ext.locales[d.locale].b[d.getMonth()]},B:function(d){return Date.ext.locales[d.locale].B[d.getMonth()]},c:"toLocaleString",C:function(d){return Date.ext.util.xPad(parseInt(d.getFullYear()/100,10),0)},d:["getDate","0"],e:["getDate"," "],g:function(d){return Date.ext.util.xPad(parseInt(Date.ext.util.G(d)/100,10),0)},G:function(d){var y=d.getFullYear();var V=parseInt(Date.ext.formats.V(d),10);var W=parseInt(Date.ext.formats.W(d),10);if(W>V){y++}else{if(W===0&&V>=52){y--}}return y},H:["getHours","0"],I:function(d){var I=d.getHours()%12;return Date.ext.util.xPad(I===0?12:I,0)},j:function(d){var ms=d-new Date(""+d.getFullYear()+"/1/1 GMT");ms+=d.getTimezoneOffset()*60000;var doy=parseInt(ms/60000/60/24,10)+1;return Date.ext.util.xPad(doy,0,100)},m:function(d){return Date.ext.util.xPad(d.getMonth()+1,0)},M:["getMinutes","0"],p:function(d){return Date.ext.locales[d.locale].p[d.getHours()>=12?1:0]},P:function(d){return Date.ext.locales[d.locale].P[d.getHours()>=12?1:0]},S:["getSeconds","0"],u:function(d){var dow=d.getDay();return dow===0?7:dow},U:function(d){var doy=parseInt(Date.ext.formats.j(d),10);var rdow=6-d.getDay();var woy=parseInt((doy+rdow)/7,10);return Date.ext.util.xPad(woy,0)},V:function(d){var woy=parseInt(Date.ext.formats.W(d),10);var dow1_1=(new Date(""+d.getFullYear()+"/1/1")).getDay();var idow=woy+(dow1_1>4||dow1_1<=1?0:1);if(idow==53&&(new Date(""+d.getFullYear()+"/12/31")).getDay()<4){idow=1}else{if(idow===0){idow=Date.ext.formats.V(new Date(""+(d.getFullYear()-1)+"/12/31"))}}return Date.ext.util.xPad(idow,0)},w:"getDay",W:function(d){var doy=parseInt(Date.ext.formats.j(d),10);var rdow=7-Date.ext.formats.u(d);var woy=parseInt((doy+rdow)/7,10);return Date.ext.util.xPad(woy,0,10)},y:function(d){return Date.ext.util.xPad(d.getFullYear()%100,0)},Y:"getFullYear",z:function(d){var o=d.getTimezoneOffset();var H=Date.ext.util.xPad(parseInt(Math.abs(o/60),10),0);var M=Date.ext.util.xPad(o%60,0);return(o>0?"-":"+")+H+M},Z:function(d){return d.toString().replace(/^.*\(([^)]+)\)$/,"$1")},"%":function(d){return"%"}};Date.ext.aggregates={c:"locale",D:"%m/%d/%y",h:"%b",n:"\n",r:"%I:%M:%S %p",R:"%H:%M",t:"\t",T:"%H:%M:%S",x:"locale",X:"locale"};Date.ext.aggregates.z=Date.ext.formats.z(new Date());Date.ext.aggregates.Z=Date.ext.formats.Z(new Date());Date.ext.unsupported={};Date.prototype.strftime=function(fmt){if(!(this.locale in Date.ext.locales)){if(this.locale.replace(/-[a-zA-Z]+$/,"") in Date.ext.locales){this.locale=this.locale.replace(/-[a-zA-Z]+$/,"")}else{this.locale="en-GB"}}var d=this;while(fmt.match(/%[cDhnrRtTxXzZ]/)){fmt=fmt.replace(/%([cDhnrRtTxXzZ])/g,function(m0,m1){var f=Date.ext.aggregates[m1];return(f=="locale"?Date.ext.locales[d.locale][m1]:f)})}var str=fmt.replace(/%([aAbBCdegGHIjmMpPSuUVwWyY%])/g,function(m0,m1){var f=Date.ext.formats[m1];if(typeof (f)=="string"){return d[f]()}else{if(typeof (f)=="function"){return f.call(d,d)}else{if(typeof (f)=="object"&&typeof (f[0])=="string"){return Date.ext.util.xPad(d[f[0]](),f[1])}else{return m1}}}});d=null;return str};
diff --git a/site/app/webroot/js/vendors.php b/site/app/webroot/js/vendors.php
new file mode 100644
index 0000000..7c28ad9
--- /dev/null
+++ b/site/app/webroot/js/vendors.php
@@ -0,0 +1,36 @@
+<?php
+/* SVN FILE: $Id: vendors.php,v 1.1.1.1 2006/08/14 23:54:57 sancus%off.net Exp $ */
+/**
+ * Short description for file.
+ *
+ * This file includes js vendor-files from /vendor/ directory if they need to
+ * be accessible to the public.
+ *
+ * PHP versions 4 and 5
+ *
+ * CakePHP : Rapid Development Framework <http://www.cakephp.org/>
+ * Copyright (c) 2006, Cake Software Foundation, Inc.
+ * 1785 E. Sahara Avenue, Suite 490-204
+ * Las Vegas, Nevada 89104
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright Copyright (c) 2006, Cake Software Foundation, Inc.
+ * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP Project
+ * @package cake
+ * @subpackage cake.app.webroot.js
+ * @since CakePHP v 0.2.9
+ * @version $Revision: 1.1.1.1 $
+ * @modifiedby $LastChangedBy: phpnut $
+ * @lastmodified $Date: 2006/08/14 23:54:57 $
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+/**
+ * Enter description here...
+ */
+ if (is_file('../../vendors/javascript/' . $_GET['file']) && (preg_match('/(.+)\\.js/', $_GET['file']))) {
+ readfile('../../vendors/javascript/' . $_GET['file']);
+ }
+?>
diff --git a/site/app/webroot/kodak/kodak_extension.html b/site/app/webroot/kodak/kodak_extension.html
new file mode 100644
index 0000000..5e02396
--- /dev/null
+++ b/site/app/webroot/kodak/kodak_extension.html
@@ -0,0 +1,15 @@
+<html>
+<script language="JavaScript" type="text/javascript" src="../js/__utm.js"></script>
+<script type="text/javascript">
+ function redirect() {
+ if( document.referrer.match(/^https?:\/\/[^\/]*\.mozilla\.com\/?.*/) ){
+ window.location.href='http://releases.mozilla.com/kodak/2.0.0.1/extension/kodak-gallery.xpi';
+ } else {
+ window.location.href='http://addons.mozilla.org/';
+ }
+ }
+</script>
+
+<body onload="redirect()">
+</body>
+</html>
diff --git a/site/app/webroot/licenses/0.txt b/site/app/webroot/licenses/0.txt
new file mode 100644
index 0000000..7714141
--- /dev/null
+++ b/site/app/webroot/licenses/0.txt
@@ -0,0 +1,470 @@
+ MOZILLA PUBLIC LICENSE
+ Version 1.1
+
+ ---------------
+
+1. Definitions.
+
+ 1.0.1. "Commercial Use" means distribution or otherwise making the
+ Covered Code available to a third party.
+
+ 1.1. "Contributor" means each entity that creates or contributes to
+ the creation of Modifications.
+
+ 1.2. "Contributor Version" means the combination of the Original
+ Code, prior Modifications used by a Contributor, and the Modifications
+ made by that particular Contributor.
+
+ 1.3. "Covered Code" means the Original Code or Modifications or the
+ combination of the Original Code and Modifications, in each case
+ including portions thereof.
+
+ 1.4. "Electronic Distribution Mechanism" means a mechanism generally
+ accepted in the software development community for the electronic
+ transfer of data.
+
+ 1.5. "Executable" means Covered Code in any form other than Source
+ Code.
+
+ 1.6. "Initial Developer" means the individual or entity identified
+ as the Initial Developer in the Source Code notice required by Exhibit
+ A.
+
+ 1.7. "Larger Work" means a work which combines Covered Code or
+ portions thereof with code not governed by the terms of this License.
+
+ 1.8. "License" means this document.
+
+ 1.8.1. "Licensable" means having the right to grant, to the maximum
+ extent possible, whether at the time of the initial grant or
+ subsequently acquired, any and all of the rights conveyed herein.
+
+ 1.9. "Modifications" means any addition to or deletion from the
+ substance or structure of either the Original Code or any previous
+ Modifications. When Covered Code is released as a series of files, a
+ Modification is:
+ A. Any addition to or deletion from the contents of a file
+ containing Original Code or previous Modifications.
+
+ B. Any new file that contains any part of the Original Code or
+ previous Modifications.
+
+ 1.10. "Original Code" means Source Code of computer software code
+ which is described in the Source Code notice required by Exhibit A as
+ Original Code, and which, at the time of its release under this
+ License is not already Covered Code governed by this License.
+
+ 1.10.1. "Patent Claims" means any patent claim(s), now owned or
+ hereafter acquired, including without limitation, method, process,
+ and apparatus claims, in any patent Licensable by grantor.
+
+ 1.11. "Source Code" means the preferred form of the Covered Code for
+ making modifications to it, including all modules it contains, plus
+ any associated interface definition files, scripts used to control
+ compilation and installation of an Executable, or source code
+ differential comparisons against either the Original Code or another
+ well known, available Covered Code of the Contributor's choice. The
+ Source Code can be in a compressed or archival form, provided the
+ appropriate decompression or de-archiving software is widely available
+ for no charge.
+
+ 1.12. "You" (or "Your") means an individual or a legal entity
+ exercising rights under, and complying with all of the terms of, this
+ License or a future version of this License issued under Section 6.1.
+ For legal entities, "You" includes any entity which controls, is
+ controlled by, or is under common control with You. For purposes of
+ this definition, "control" means (a) the power, direct or indirect,
+ to cause the direction or management of such entity, whether by
+ contract or otherwise, or (b) ownership of more than fifty percent
+ (50%) of the outstanding shares or beneficial ownership of such
+ entity.
+
+2. Source Code License.
+
+ 2.1. The Initial Developer Grant.
+ The Initial Developer hereby grants You a world-wide, royalty-free,
+ non-exclusive license, subject to third party intellectual property
+ claims:
+ (a) under intellectual property rights (other than patent or
+ trademark) Licensable by Initial Developer to use, reproduce,
+ modify, display, perform, sublicense and distribute the Original
+ Code (or portions thereof) with or without Modifications, and/or
+ as part of a Larger Work; and
+
+ (b) under Patents Claims infringed by the making, using or
+ selling of Original Code, to make, have made, use, practice,
+ sell, and offer for sale, and/or otherwise dispose of the
+ Original Code (or portions thereof).
+
+ (c) the licenses granted in this Section 2.1(a) and (b) are
+ effective on the date Initial Developer first distributes
+ Original Code under the terms of this License.
+
+ (d) Notwithstanding Section 2.1(b) above, no patent license is
+ granted: 1) for code that You delete from the Original Code; 2)
+ separate from the Original Code; or 3) for infringements caused
+ by: i) the modification of the Original Code or ii) the
+ combination of the Original Code with other software or devices.
+
+ 2.2. Contributor Grant.
+ Subject to third party intellectual property claims, each Contributor
+ hereby grants You a world-wide, royalty-free, non-exclusive license
+
+ (a) under intellectual property rights (other than patent or
+ trademark) Licensable by Contributor, to use, reproduce, modify,
+ display, perform, sublicense and distribute the Modifications
+ created by such Contributor (or portions thereof) either on an
+ unmodified basis, with other Modifications, as Covered Code
+ and/or as part of a Larger Work; and
+
+ (b) under Patent Claims infringed by the making, using, or
+ selling of Modifications made by that Contributor either alone
+ and/or in combination with its Contributor Version (or portions
+ of such combination), to make, use, sell, offer for sale, have
+ made, and/or otherwise dispose of: 1) Modifications made by that
+ Contributor (or portions thereof); and 2) the combination of
+ Modifications made by that Contributor with its Contributor
+ Version (or portions of such combination).
+
+ (c) the licenses granted in Sections 2.2(a) and 2.2(b) are
+ effective on the date Contributor first makes Commercial Use of
+ the Covered Code.
+
+ (d) Notwithstanding Section 2.2(b) above, no patent license is
+ granted: 1) for any code that Contributor has deleted from the
+ Contributor Version; 2) separate from the Contributor Version;
+ 3) for infringements caused by: i) third party modifications of
+ Contributor Version or ii) the combination of Modifications made
+ by that Contributor with other software (except as part of the
+ Contributor Version) or other devices; or 4) under Patent Claims
+ infringed by Covered Code in the absence of Modifications made by
+ that Contributor.
+
+3. Distribution Obligations.
+
+ 3.1. Application of License.
+ The Modifications which You create or to which You contribute are
+ governed by the terms of this License, including without limitation
+ Section 2.2. The Source Code version of Covered Code may be
+ distributed only under the terms of this License or a future version
+ of this License released under Section 6.1, and You must include a
+ copy of this License with every copy of the Source Code You
+ distribute. You may not offer or impose any terms on any Source Code
+ version that alters or restricts the applicable version of this
+ License or the recipients' rights hereunder. However, You may include
+ an additional document offering the additional rights described in
+ Section 3.5.
+
+ 3.2. Availability of Source Code.
+ Any Modification which You create or to which You contribute must be
+ made available in Source Code form under the terms of this License
+ either on the same media as an Executable version or via an accepted
+ Electronic Distribution Mechanism to anyone to whom you made an
+ Executable version available; and if made available via Electronic
+ Distribution Mechanism, must remain available for at least twelve (12)
+ months after the date it initially became available, or at least six
+ (6) months after a subsequent version of that particular Modification
+ has been made available to such recipients. You are responsible for
+ ensuring that the Source Code version remains available even if the
+ Electronic Distribution Mechanism is maintained by a third party.
+
+ 3.3. Description of Modifications.
+ You must cause all Covered Code to which You contribute to contain a
+ file documenting the changes You made to create that Covered Code and
+ the date of any change. You must include a prominent statement that
+ the Modification is derived, directly or indirectly, from Original
+ Code provided by the Initial Developer and including the name of the
+ Initial Developer in (a) the Source Code, and (b) in any notice in an
+ Executable version or related documentation in which You describe the
+ origin or ownership of the Covered Code.
+
+ 3.4. Intellectual Property Matters
+ (a) Third Party Claims.
+ If Contributor has knowledge that a license under a third party's
+ intellectual property rights is required to exercise the rights
+ granted by such Contributor under Sections 2.1 or 2.2,
+ Contributor must include a text file with the Source Code
+ distribution titled "LEGAL" which describes the claim and the
+ party making the claim in sufficient detail that a recipient will
+ know whom to contact. If Contributor obtains such knowledge after
+ the Modification is made available as described in Section 3.2,
+ Contributor shall promptly modify the LEGAL file in all copies
+ Contributor makes available thereafter and shall take other steps
+ (such as notifying appropriate mailing lists or newsgroups)
+ reasonably calculated to inform those who received the Covered
+ Code that new knowledge has been obtained.
+
+ (b) Contributor APIs.
+ If Contributor's Modifications include an application programming
+ interface and Contributor has knowledge of patent licenses which
+ are reasonably necessary to implement that API, Contributor must
+ also include this information in the LEGAL file.
+
+ (c) Representations.
+ Contributor represents that, except as disclosed pursuant to
+ Section 3.4(a) above, Contributor believes that Contributor's
+ Modifications are Contributor's original creation(s) and/or
+ Contributor has sufficient rights to grant the rights conveyed by
+ this License.
+
+ 3.5. Required Notices.
+ You must duplicate the notice in Exhibit A in each file of the Source
+ Code. If it is not possible to put such notice in a particular Source
+ Code file due to its structure, then You must include such notice in a
+ location (such as a relevant directory) where a user would be likely
+ to look for such a notice. If You created one or more Modification(s)
+ You may add your name as a Contributor to the notice described in
+ Exhibit A. You must also duplicate this License in any documentation
+ for the Source Code where You describe recipients' rights or ownership
+ rights relating to Covered Code. You may choose to offer, and to
+ charge a fee for, warranty, support, indemnity or liability
+ obligations to one or more recipients of Covered Code. However, You
+ may do so only on Your own behalf, and not on behalf of the Initial
+ Developer or any Contributor. You must make it absolutely clear than
+ any such warranty, support, indemnity or liability obligation is
+ offered by You alone, and You hereby agree to indemnify the Initial
+ Developer and every Contributor for any liability incurred by the
+ Initial Developer or such Contributor as a result of warranty,
+ support, indemnity or liability terms You offer.
+
+ 3.6. Distribution of Executable Versions.
+ You may distribute Covered Code in Executable form only if the
+ requirements of Section 3.1-3.5 have been met for that Covered Code,
+ and if You include a notice stating that the Source Code version of
+ the Covered Code is available under the terms of this License,
+ including a description of how and where You have fulfilled the
+ obligations of Section 3.2. The notice must be conspicuously included
+ in any notice in an Executable version, related documentation or
+ collateral in which You describe recipients' rights relating to the
+ Covered Code. You may distribute the Executable version of Covered
+ Code or ownership rights under a license of Your choice, which may
+ contain terms different from this License, provided that You are in
+ compliance with the terms of this License and that the license for the
+ Executable version does not attempt to limit or alter the recipient's
+ rights in the Source Code version from the rights set forth in this
+ License. If You distribute the Executable version under a different
+ license You must make it absolutely clear that any terms which differ
+ from this License are offered by You alone, not by the Initial
+ Developer or any Contributor. You hereby agree to indemnify the
+ Initial Developer and every Contributor for any liability incurred by
+ the Initial Developer or such Contributor as a result of any such
+ terms You offer.
+
+ 3.7. Larger Works.
+ You may create a Larger Work by combining Covered Code with other code
+ not governed by the terms of this License and distribute the Larger
+ Work as a single product. In such a case, You must make sure the
+ requirements of this License are fulfilled for the Covered Code.
+
+4. Inability to Comply Due to Statute or Regulation.
+
+ If it is impossible for You to comply with any of the terms of this
+ License with respect to some or all of the Covered Code due to
+ statute, judicial order, or regulation then You must: (a) comply with
+ the terms of this License to the maximum extent possible; and (b)
+ describe the limitations and the code they affect. Such description
+ must be included in the LEGAL file described in Section 3.4 and must
+ be included with all distributions of the Source Code. Except to the
+ extent prohibited by statute or regulation, such description must be
+ sufficiently detailed for a recipient of ordinary skill to be able to
+ understand it.
+
+5. Application of this License.
+
+ This License applies to code to which the Initial Developer has
+ attached the notice in Exhibit A and to related Covered Code.
+
+6. Versions of the License.
+
+ 6.1. New Versions.
+ Netscape Communications Corporation ("Netscape") may publish revised
+ and/or new versions of the License from time to time. Each version
+ will be given a distinguishing version number.
+
+ 6.2. Effect of New Versions.
+ Once Covered Code has been published under a particular version of the
+ License, You may always continue to use it under the terms of that
+ version. You may also choose to use such Covered Code under the terms
+ of any subsequent version of the License published by Netscape. No one
+ other than Netscape has the right to modify the terms applicable to
+ Covered Code created under this License.
+
+ 6.3. Derivative Works.
+ If You create or use a modified version of this License (which you may
+ only do in order to apply it to code which is not already Covered Code
+ governed by this License), You must (a) rename Your license so that
+ the phrases "Mozilla", "MOZILLAPL", "MOZPL", "Netscape",
+ "MPL", "NPL" or any confusingly similar phrase do not appear in your
+ license (except to note that your license differs from this License)
+ and (b) otherwise make it clear that Your version of the license
+ contains terms which differ from the Mozilla Public License and
+ Netscape Public License. (Filling in the name of the Initial
+ Developer, Original Code or Contributor in the notice described in
+ Exhibit A shall not of themselves be deemed to be modifications of
+ this License.)
+
+7. DISCLAIMER OF WARRANTY.
+
+ COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ WITHOUT LIMITATION, WARRANTIES THAT THE COVERED CODE IS FREE OF
+ DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR NON-INFRINGING.
+ THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED CODE
+ IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT,
+ YOU (NOT THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE
+ COST OF ANY NECESSARY SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER
+ OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO USE OF
+ ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER.
+
+8. TERMINATION.
+
+ 8.1. This License and the rights granted hereunder will terminate
+ automatically if You fail to comply with terms herein and fail to cure
+ such breach within 30 days of becoming aware of the breach. All
+ sublicenses to the Covered Code which are properly granted shall
+ survive any termination of this License. Provisions which, by their
+ nature, must remain in effect beyond the termination of this License
+ shall survive.
+
+ 8.2. If You initiate litigation by asserting a patent infringement
+ claim (excluding declatory judgment actions) against Initial Developer
+ or a Contributor (the Initial Developer or Contributor against whom
+ You file such action is referred to as "Participant") alleging that:
+
+ (a) such Participant's Contributor Version directly or indirectly
+ infringes any patent, then any and all rights granted by such
+ Participant to You under Sections 2.1 and/or 2.2 of this License
+ shall, upon 60 days notice from Participant terminate prospectively,
+ unless if within 60 days after receipt of notice You either: (i)
+ agree in writing to pay Participant a mutually agreeable reasonable
+ royalty for Your past and future use of Modifications made by such
+ Participant, or (ii) withdraw Your litigation claim with respect to
+ the Contributor Version against such Participant. If within 60 days
+ of notice, a reasonable royalty and payment arrangement are not
+ mutually agreed upon in writing by the parties or the litigation claim
+ is not withdrawn, the rights granted by Participant to You under
+ Sections 2.1 and/or 2.2 automatically terminate at the expiration of
+ the 60 day notice period specified above.
+
+ (b) any software, hardware, or device, other than such Participant's
+ Contributor Version, directly or indirectly infringes any patent, then
+ any rights granted to You by such Participant under Sections 2.1(b)
+ and 2.2(b) are revoked effective as of the date You first made, used,
+ sold, distributed, or had made, Modifications made by that
+ Participant.
+
+ 8.3. If You assert a patent infringement claim against Participant
+ alleging that such Participant's Contributor Version directly or
+ indirectly infringes any patent where such claim is resolved (such as
+ by license or settlement) prior to the initiation of patent
+ infringement litigation, then the reasonable value of the licenses
+ granted by such Participant under Sections 2.1 or 2.2 shall be taken
+ into account in determining the amount or value of any payment or
+ license.
+
+ 8.4. In the event of termination under Sections 8.1 or 8.2 above,
+ all end user license agreements (excluding distributors and resellers)
+ which have been validly granted by You or any distributor hereunder
+ prior to termination shall survive termination.
+
+9. LIMITATION OF LIABILITY.
+
+ UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT
+ (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL YOU, THE INITIAL
+ DEVELOPER, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF COVERED CODE,
+ OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE LIABLE TO ANY PERSON FOR
+ ANY INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY
+ CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF GOODWILL,
+ WORK STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER
+ COMMERCIAL DAMAGES OR LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN
+ INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF
+ LIABILITY SHALL NOT APPLY TO LIABILITY FOR DEATH OR PERSONAL INJURY
+ RESULTING FROM SUCH PARTY'S NEGLIGENCE TO THE EXTENT APPLICABLE LAW
+ PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO NOT ALLOW THE
+ EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO
+ THIS EXCLUSION AND LIMITATION MAY NOT APPLY TO YOU.
+
+10. U.S. GOVERNMENT END USERS.
+
+ The Covered Code is a "commercial item," as that term is defined in
+ 48 C.F.R. 2.101 (Oct. 1995), consisting of "commercial computer
+ software" and "commercial computer software documentation," as such
+ terms are used in 48 C.F.R. 12.212 (Sept. 1995). Consistent with 48
+ C.F.R. 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (June 1995),
+ all U.S. Government End Users acquire Covered Code with only those
+ rights set forth herein.
+
+11. MISCELLANEOUS.
+
+ This License represents the complete agreement concerning subject
+ matter hereof. If any provision of this License is held to be
+ unenforceable, such provision shall be reformed only to the extent
+ necessary to make it enforceable. This License shall be governed by
+ California law provisions (except to the extent applicable law, if
+ any, provides otherwise), excluding its conflict-of-law provisions.
+ With respect to disputes in which at least one party is a citizen of,
+ or an entity chartered or registered to do business in the United
+ States of America, any litigation relating to this License shall be
+ subject to the jurisdiction of the Federal Courts of the Northern
+ District of California, with venue lying in Santa Clara County,
+ California, with the losing party responsible for costs, including
+ without limitation, court costs and reasonable attorneys' fees and
+ expenses. The application of the United Nations Convention on
+ Contracts for the International Sale of Goods is expressly excluded.
+ Any law or regulation which provides that the language of a contract
+ shall be construed against the drafter shall not apply to this
+ License.
+
+12. RESPONSIBILITY FOR CLAIMS.
+
+ As between Initial Developer and the Contributors, each party is
+ responsible for claims and damages arising, directly or indirectly,
+ out of its utilization of rights under this License and You agree to
+ work with Initial Developer and Contributors to distribute such
+ responsibility on an equitable basis. Nothing herein is intended or
+ shall be deemed to constitute any admission of liability.
+
+13. MULTIPLE-LICENSED CODE.
+
+ Initial Developer may designate portions of the Covered Code as
+ "Multiple-Licensed". "Multiple-Licensed" means that the Initial
+ Developer permits you to utilize portions of the Covered Code under
+ Your choice of the NPL or the alternative licenses, if any, specified
+ by the Initial Developer in the file described in Exhibit A.
+
+EXHIBIT A -Mozilla Public License.
+
+ ``The contents of this file are subject to the Mozilla Public License
+ Version 1.1 (the "License"); you may not use this file except in
+ compliance with the License. You may obtain a copy of the License at
+ http://www.mozilla.org/MPL/
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
+ License for the specific language governing rights and limitations
+ under the License.
+
+ The Original Code is ______________________________________.
+
+ The Initial Developer of the Original Code is ________________________.
+ Portions created by ______________________ are Copyright (C) ______
+ _______________________. All Rights Reserved.
+
+ Contributor(s): ______________________________________.
+
+ Alternatively, the contents of this file may be used under the terms
+ of the _____ license (the "[___] License"), in which case the
+ provisions of [______] License are applicable instead of those
+ above. If you wish to allow use of your version of this file only
+ under the terms of the [____] License and not to allow others to use
+ your version of this file under the MPL, indicate your decision by
+ deleting the provisions above and replace them with the notice and
+ other provisions required by the [___] License. If you do not delete
+ the provisions above, a recipient may use your version of this file
+ under either the MPL or the [___] License."
+
+ [NOTE: The text of this Exhibit A may differ slightly from the text of
+ the notices in the Source Code files of the Original Code. You should
+ use the text of this Exhibit A rather than the text found in the
+ Original Code Source Code for Your Modifications.]
+
diff --git a/site/app/webroot/licenses/1.txt b/site/app/webroot/licenses/1.txt
new file mode 100644
index 0000000..d511905
--- /dev/null
+++ b/site/app/webroot/licenses/1.txt
@@ -0,0 +1,339 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Lesser General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) year name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.
diff --git a/site/app/webroot/licenses/2.txt b/site/app/webroot/licenses/2.txt
new file mode 100644
index 0000000..94a9ed0
--- /dev/null
+++ b/site/app/webroot/licenses/2.txt
@@ -0,0 +1,674 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+ The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users. We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors. You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+ To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights. Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received. You must make sure that they, too, receive
+or can get the source code. And you must show them these terms so they
+know their rights.
+
+ Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+ For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software. For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+ Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so. This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software. The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable. Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products. If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+ Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary. To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ TERMS AND CONDITIONS
+
+ 0. Definitions.
+
+ "This License" refers to version 3 of the GNU General Public License.
+
+ "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+ "The Program" refers to any copyrightable work licensed under this
+License. Each licensee is addressed as "you". "Licensees" and
+"recipients" may be individuals or organizations.
+
+ To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy. The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+ A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+ To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+ To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+ An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+ 1. Source Code.
+
+ The "source code" for a work means the preferred form of the work
+for making modifications to it. "Object code" means any non-source
+form of a work.
+
+ A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+ The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+ The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+ The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+ The Corresponding Source for a work in source code form is that
+same work.
+
+ 2. Basic Permissions.
+
+ All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+ You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force. You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright. Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+ Conveying under any other circumstances is permitted solely under
+the conditions stated below. Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+ No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+ When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+ 4. Conveying Verbatim Copies.
+
+ You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+ You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+ 5. Conveying Modified Source Versions.
+
+ You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+ a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+
+ b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under section
+ 7. This requirement modifies the requirement in section 4 to
+ "keep intact all notices".
+
+ c) You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable section 7
+ additional terms, to the whole of the work, and all its parts,
+ regardless of how they are packaged. This License gives no
+ permission to license the work in any other way, but it does not
+ invalidate such permission if you have separately received it.
+
+ d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your
+ work need not make them do so.
+
+ A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+ 6. Conveying Non-Source Forms.
+
+ You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+ a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+
+ b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the
+ Corresponding Source from a network server at no charge.
+
+ c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially, and
+ only if you received the object code with such an offer, in accord
+ with subsection 6b.
+
+ d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+
+ e) Convey the object code using peer-to-peer transmission, provided
+ you inform other peers where the object code and Corresponding
+ Source of the work are being offered to the general public at no
+ charge under subsection 6d.
+
+ A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+ A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling. In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage. For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product. A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+ "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source. The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+ If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+ The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed. Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+ Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+ 7. Additional Terms.
+
+ "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+ When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+ Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+ a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+
+ b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+
+ c) Prohibiting misrepresentation of the origin of that material, or
+ requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+
+ d) Limiting the use for publicity purposes of names of licensors or
+ authors of the material; or
+
+ e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+
+ f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions of
+ it) with contractual assumptions of liability to the recipient, for
+ any liability that these contractual assumptions directly impose on
+ those licensors and authors.
+
+ All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+ If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+ Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+ 8. Termination.
+
+ You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+ However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+ Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+ 9. Acceptance Not Required for Having Copies.
+
+ You are not required to accept this License in order to receive or
+run a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+ 10. Automatic Licensing of Downstream Recipients.
+
+ Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
+
+ An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+ You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License. For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+ 11. Patents.
+
+ A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based. The
+work thus licensed is called the contributor's "contributor version".
+
+ A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version. For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+ In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement). To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+ If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients. "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+ If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+ A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License. You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+ Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+ 12. No Surrender of Others' Freedom.
+
+ If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all. For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+ 13. Use with the GNU Affero General Public License.
+
+ Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work. The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+ 14. Revised Versions of this License.
+
+ The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation. If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+ If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+ Later license versions may give you additional or different
+permissions. However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+ 15. Disclaimer of Warranty.
+
+ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. Limitation of Liability.
+
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+ 17. Interpretation of Sections 15 and 16.
+
+ If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+Also add information on how to contact you by electronic and paper mail.
+
+ If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+ <program> Copyright (C) <year> <name of author>
+ This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+ You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+<http://www.gnu.org/licenses/>.
+
+ The GNU General Public License does not permit incorporating your program
+into proprietary programs. If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License. But first, please read
+<http://www.gnu.org/philosophy/why-not-lgpl.html>.
diff --git a/site/app/webroot/licenses/3.txt b/site/app/webroot/licenses/3.txt
new file mode 100644
index 0000000..602bfc9
--- /dev/null
+++ b/site/app/webroot/licenses/3.txt
@@ -0,0 +1,504 @@
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL. It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+ This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it. You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+ When we speak of free software, we are referring to freedom of use,
+not price. Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+ To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights. These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+ For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you. You must make sure that they, too, receive or can get the source
+code. If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it. And you must show them these terms so they know their rights.
+
+ We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+ To protect each distributor, we want to make it very clear that
+there is no warranty for the free library. Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+
+ Finally, software patents pose a constant threat to the existence of
+any free program. We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder. Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+ Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License. This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License. We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+ When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library. The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom. The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+ We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License. It also provides other free software developers Less
+of an advantage over competing non-free programs. These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries. However, the Lesser license provides advantages in certain
+special circumstances.
+
+ For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard. To achieve this, non-free programs must be
+allowed to use the library. A more frequent case is that a free
+library does the same job as widely used non-free libraries. In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+ In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software. For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+ Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+ The precise terms and conditions for copying, distribution and
+modification follow. Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library". The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+
+ GNU LESSER GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+ A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+ The "Library", below, refers to any such software library or work
+which has been distributed under these terms. A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language. (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+ "Source code" for a work means the preferred form of the work for
+making modifications to it. For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+ Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it). Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+ 1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+ You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+ 2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) The modified work must itself be a software library.
+
+ b) You must cause the files modified to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ c) You must cause the whole of the work to be licensed at no
+ charge to all third parties under the terms of this License.
+
+ d) If a facility in the modified Library refers to a function or a
+ table of data to be supplied by an application program that uses
+ the facility, other than as an argument passed when the facility
+ is invoked, then you must make a good faith effort to ensure that,
+ in the event an application does not supply such function or
+ table, the facility still operates, and performs whatever part of
+ its purpose remains meaningful.
+
+ (For example, a function in a library to compute square roots has
+ a purpose that is entirely well-defined independent of the
+ application. Therefore, Subsection 2d requires that any
+ application-supplied function or table used by this function must
+ be optional: if the application does not supply it, the square
+ root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library. To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License. (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.) Do not make any other change in
+these notices.
+
+ Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+ This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+ 4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+ If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library". Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+ However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library". The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+ When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library. The
+threshold for this to be true is not precisely defined by law.
+
+ If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work. (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+ Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+ 6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+ You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License. You must supply a copy of this License. If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License. Also, you must do one
+of these things:
+
+ a) Accompany the work with the complete corresponding
+ machine-readable source code for the Library including whatever
+ changes were used in the work (which must be distributed under
+ Sections 1 and 2 above); and, if the work is an executable linked
+ with the Library, with the complete machine-readable "work that
+ uses the Library", as object code and/or source code, so that the
+ user can modify the Library and then relink to produce a modified
+ executable containing the modified Library. (It is understood
+ that the user who changes the contents of definitions files in the
+ Library will not necessarily be able to recompile the application
+ to use the modified definitions.)
+
+ b) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (1) uses at run time a
+ copy of the library already present on the user's computer system,
+ rather than copying library functions into the executable, and (2)
+ will operate properly with a modified version of the library, if
+ the user installs one, as long as the modified version is
+ interface-compatible with the version that the work was made with.
+
+ c) Accompany the work with a written offer, valid for at
+ least three years, to give the same user the materials
+ specified in Subsection 6a, above, for a charge no more
+ than the cost of performing this distribution.
+
+ d) If distribution of the work is made by offering access to copy
+ from a designated place, offer equivalent access to copy the above
+ specified materials from the same place.
+
+ e) Verify that the user has already received a copy of these
+ materials or that you have already sent this user a copy.
+
+ For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it. However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+ It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system. Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+ 7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+ a) Accompany the combined library with a copy of the same work
+ based on the Library, uncombined with any other library
+ facilities. This must be distributed under the terms of the
+ Sections above.
+
+ b) Give prominent notice with the combined library of the fact
+ that part of it is a work based on the Library, and explaining
+ where to find the accompanying uncombined form of the same work.
+
+ 8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License. Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License. However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+ 9. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Library or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+ 10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+
+ 11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all. For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded. In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+ 13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation. If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+ 14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission. For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this. Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+ NO WARRANTY
+
+ 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Libraries
+
+ If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change. You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+ To apply these terms, attach the following notices to the library. It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the library's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the
+ library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+ <signature of Ty Coon>, 1 April 1990
+ Ty Coon, President of Vice
+
+That's all there is to it!
+
+
diff --git a/site/app/webroot/licenses/4.txt b/site/app/webroot/licenses/4.txt
new file mode 100644
index 0000000..cca7fc2
--- /dev/null
+++ b/site/app/webroot/licenses/4.txt
@@ -0,0 +1,165 @@
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+
+ This version of the GNU Lesser General Public License incorporates
+the terms and conditions of version 3 of the GNU General Public
+License, supplemented by the additional permissions listed below.
+
+ 0. Additional Definitions.
+
+ As used herein, "this License" refers to version 3 of the GNU Lesser
+General Public License, and the "GNU GPL" refers to version 3 of the GNU
+General Public License.
+
+ "The Library" refers to a covered work governed by this License,
+other than an Application or a Combined Work as defined below.
+
+ An "Application" is any work that makes use of an interface provided
+by the Library, but which is not otherwise based on the Library.
+Defining a subclass of a class defined by the Library is deemed a mode
+of using an interface provided by the Library.
+
+ A "Combined Work" is a work produced by combining or linking an
+Application with the Library. The particular version of the Library
+with which the Combined Work was made is also called the "Linked
+Version".
+
+ The "Minimal Corresponding Source" for a Combined Work means the
+Corresponding Source for the Combined Work, excluding any source code
+for portions of the Combined Work that, considered in isolation, are
+based on the Application, and not on the Linked Version.
+
+ The "Corresponding Application Code" for a Combined Work means the
+object code and/or source code for the Application, including any data
+and utility programs needed for reproducing the Combined Work from the
+Application, but excluding the System Libraries of the Combined Work.
+
+ 1. Exception to Section 3 of the GNU GPL.
+
+ You may convey a covered work under sections 3 and 4 of this License
+without being bound by section 3 of the GNU GPL.
+
+ 2. Conveying Modified Versions.
+
+ If you modify a copy of the Library, and, in your modifications, a
+facility refers to a function or data to be supplied by an Application
+that uses the facility (other than as an argument passed when the
+facility is invoked), then you may convey a copy of the modified
+version:
+
+ a) under this License, provided that you make a good faith effort to
+ ensure that, in the event an Application does not supply the
+ function or data, the facility still operates, and performs
+ whatever part of its purpose remains meaningful, or
+
+ b) under the GNU GPL, with none of the additional permissions of
+ this License applicable to that copy.
+
+ 3. Object Code Incorporating Material from Library Header Files.
+
+ The object code form of an Application may incorporate material from
+a header file that is part of the Library. You may convey such object
+code under terms of your choice, provided that, if the incorporated
+material is not limited to numerical parameters, data structure
+layouts and accessors, or small macros, inline functions and templates
+(ten or fewer lines in length), you do both of the following:
+
+ a) Give prominent notice with each copy of the object code that the
+ Library is used in it and that the Library and its use are
+ covered by this License.
+
+ b) Accompany the object code with a copy of the GNU GPL and this license
+ document.
+
+ 4. Combined Works.
+
+ You may convey a Combined Work under terms of your choice that,
+taken together, effectively do not restrict modification of the
+portions of the Library contained in the Combined Work and reverse
+engineering for debugging such modifications, if you also do each of
+the following:
+
+ a) Give prominent notice with each copy of the Combined Work that
+ the Library is used in it and that the Library and its use are
+ covered by this License.
+
+ b) Accompany the Combined Work with a copy of the GNU GPL and this license
+ document.
+
+ c) For a Combined Work that displays copyright notices during
+ execution, include the copyright notice for the Library among
+ these notices, as well as a reference directing the user to the
+ copies of the GNU GPL and this license document.
+
+ d) Do one of the following:
+
+ 0) Convey the Minimal Corresponding Source under the terms of this
+ License, and the Corresponding Application Code in a form
+ suitable for, and under terms that permit, the user to
+ recombine or relink the Application with a modified version of
+ the Linked Version to produce a modified Combined Work, in the
+ manner specified by section 6 of the GNU GPL for conveying
+ Corresponding Source.
+
+ 1) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (a) uses at run time
+ a copy of the Library already present on the user's computer
+ system, and (b) will operate properly with a modified version
+ of the Library that is interface-compatible with the Linked
+ Version.
+
+ e) Provide Installation Information, but only if you would otherwise
+ be required to provide such information under section 6 of the
+ GNU GPL, and only to the extent that such information is
+ necessary to install and execute a modified version of the
+ Combined Work produced by recombining or relinking the
+ Application with a modified version of the Linked Version. (If
+ you use option 4d0, the Installation Information must accompany
+ the Minimal Corresponding Source and Corresponding Application
+ Code. If you use option 4d1, you must provide the Installation
+ Information in the manner specified by section 6 of the GNU GPL
+ for conveying Corresponding Source.)
+
+ 5. Combined Libraries.
+
+ You may place library facilities that are a work based on the
+Library side by side in a single library together with other library
+facilities that are not Applications and are not covered by this
+License, and convey such a combined library under terms of your
+choice, if you do both of the following:
+
+ a) Accompany the combined library with a copy of the same work based
+ on the Library, uncombined with any other library facilities,
+ conveyed under the terms of this License.
+
+ b) Give prominent notice with the combined library that part of it
+ is a work based on the Library, and explaining where to find the
+ accompanying uncombined form of the same work.
+
+ 6. Revised Versions of the GNU Lesser General Public License.
+
+ The Free Software Foundation may publish revised and/or new versions
+of the GNU Lesser General Public License from time to time. Such new
+versions will be similar in spirit to the present version, but may
+differ in detail to address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Library as you received it specifies that a certain numbered version
+of the GNU Lesser General Public License "or any later version"
+applies to it, you have the option of following the terms and
+conditions either of that published version or of any later version
+published by the Free Software Foundation. If the Library as you
+received it does not specify a version number of the GNU Lesser
+General Public License, you may choose any version of the GNU Lesser
+General Public License ever published by the Free Software Foundation.
+
+ If the Library as you received it specifies that a proxy can decide
+whether future versions of the GNU Lesser General Public License shall
+apply, that proxy's public statement of acceptance of any version is
+permanent authorization for you to choose that version for the
+Library.
diff --git a/site/app/webroot/licenses/5.txt b/site/app/webroot/licenses/5.txt
new file mode 100644
index 0000000..7029925
--- /dev/null
+++ b/site/app/webroot/licenses/5.txt
@@ -0,0 +1,21 @@
+The MIT License
+
+Copyright (c) <year> <copyright holders>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/site/app/webroot/licenses/6.txt b/site/app/webroot/licenses/6.txt
new file mode 100644
index 0000000..8818fb2
--- /dev/null
+++ b/site/app/webroot/licenses/6.txt
@@ -0,0 +1,56 @@
+The BSD License
+
+ The following is a BSD license template. To generate your own license,
+ change the values of OWNER, ORGANIZATION and YEAR from their original
+ values as given here, and substitute your own. Also, you may optionally
+ omit clause 3 and still be OSD conformant.
+
+ Note: On January 9th, 2008 the OSI Board approved the "Simplified BSD
+ License" variant used by FreeBSD and others, which omits the final
+ "no-endorsement" clause and is thus roughly equivalent to the MIT License.
+
+ Historical Note: The original license used on BSD Unix had four clauses.
+ The advertising clause (the third of four clauses) required you to
+ acknowledge use of U.C. Berkeley code in your advertising of any product
+ using that code. It was officially rescinded by the Director of the Office
+ of Technology Licensing of the University of California on July 22nd,
+ 1999. He states that clause 3 is "hereby deleted in its entirety." The
+ four clause license has not been approved by OSI. The license below does
+ not contain the advertising clause.
+
+ This prelude is not part of the license.
+
+<OWNER> = Regents of the University of California
+<ORGANIZATION> = University of California, Berkeley
+<YEAR> = 1998
+
+In the original BSD license, both occurrences of the phrase "COPYRIGHT HOLDERS
+AND CONTRIBUTORS" in the disclaimer read "REGENTS AND CONTRIBUTORS".
+
+Here is the license template:
+
+Copyright (c) <YEAR>, <OWNER>
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ * 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.
+ * Neither the name of the <ORGANIZATION> 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 COPYRIGHT HOLDER 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.
diff --git a/site/app/webroot/newsletter/.htaccess b/site/app/webroot/newsletter/.htaccess
new file mode 100644
index 0000000..adcfc5e
--- /dev/null
+++ b/site/app/webroot/newsletter/.htaccess
@@ -0,0 +1,4 @@
+RewriteEngine On
+
+RewriteRule unsubscribe http://list-manage.com/unsubscribe?u=168bf22f976f5a68fe5770d19&id=65a473e3bf [L]
+RewriteRule .* http://list-manage.com/subscribe.phtml?id=65a473e3bf [L] \ No newline at end of file
diff --git a/site/app/webroot/newsletter/banner.png b/site/app/webroot/newsletter/banner.png
new file mode 100644
index 0000000..5ea5e7d
--- /dev/null
+++ b/site/app/webroot/newsletter/banner.png
Binary files differ
diff --git a/site/app/webroot/sample/icon.gif b/site/app/webroot/sample/icon.gif
new file mode 100644
index 0000000..490ee66
--- /dev/null
+++ b/site/app/webroot/sample/icon.gif
Binary files differ
diff --git a/site/app/webroot/sample/screenshot.gif b/site/app/webroot/sample/screenshot.gif
new file mode 100644
index 0000000..0bd9351
--- /dev/null
+++ b/site/app/webroot/sample/screenshot.gif
Binary files differ
diff --git a/site/app/webroot/sample/screenshot2.gif b/site/app/webroot/sample/screenshot2.gif
new file mode 100644
index 0000000..6cc5a89
--- /dev/null
+++ b/site/app/webroot/sample/screenshot2.gif
Binary files differ
diff --git a/site/app/webroot/sample/screenshot3.gif b/site/app/webroot/sample/screenshot3.gif
new file mode 100644
index 0000000..bc5a9d9
--- /dev/null
+++ b/site/app/webroot/sample/screenshot3.gif
Binary files differ
diff --git a/site/app/webroot/services/blocklist.php b/site/app/webroot/services/blocklist.php
new file mode 100644
index 0000000..8e088bf
--- /dev/null
+++ b/site/app/webroot/services/blocklist.php
@@ -0,0 +1,461 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Mike Morgan <morgamic@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+
+
+/**
+ * CONFIG
+ *
+ * Require site config.
+ */
+require_once(dirname(__FILE__).'/../../config/config.php');
+require_once(dirname(__FILE__).'/../../config/constants.php');
+
+
+
+/**
+ * VARIABLES
+ *
+ * Initialize, set up and clean variables.
+ */
+
+// Required variables that we need to run the script.
+$required_vars = array('reqVersion', // Used as a marker for the current URI scheme, in case it changes later.
+ 'appGuid', // GUID of the client requesting the blocklist.
+ 'appVersion'); // Version of the client requesting the blocklist (not used).
+
+// Debug flag.
+$debug = isset($_GET['debug']) ? true : false;
+
+// Test flag.
+$test = isset($_GET['test']) ? true : false;
+
+// Array to hold errors for debugging.
+$errors = array();
+
+// Iterate through required variables, and escape/assign them as necessary.
+foreach ($required_vars as $var) {
+ if (empty($_GET[$var])) {
+ $errors[] = 'Required variable '.$var.' not set.'; // set debug error
+ }
+}
+
+
+
+// If we have all of our data, clean it up for our queries.
+if (empty($errors)) {
+
+ /**
+ * DATABASE
+ *
+ * Connect to and select proper database. By default the update script uses SHADOW.
+ *
+ * In order for testing to work, we can add a query variable specifying that the incoming request is for testing only.
+ */
+
+ // Are we trying to run a test? If so, use the test db.
+ if ($test) {
+ $dbh = @mysql_connect(TEST_DB_HOST.':'.TEST_DB_PORT,TEST_DB_USER,TEST_DB_PASS);
+
+ if (!is_resource($dbh)) {
+ $errors[] = 'MySQL connection to TEST DB failed.';
+ } elseif (!@mysql_select_db(TEST_DB_NAME, $dbh)) {
+ $errors[] = 'Could not select TEST database '.TEST_DB_NAME.'.';
+ }
+
+ // Otherwise, we're going to use SHADOW (our read-only db server).
+ } else {
+ $dbh = @mysql_connect(SHADOW_DB_HOST.':'.SHADOW_DB_PORT,SHADOW_DB_USER,SHADOW_DB_PASS);
+
+ if (!is_resource($dbh)) {
+ $errors[] = 'MySQL connection to SHADOW DB failed.';
+ } elseif (!@mysql_select_db(SHADOW_DB_NAME, $dbh)) {
+ $errors[] = 'Could not select SHADOW database '.SHADOW_DB_NAME.'.';
+ }
+ }
+
+ // Iterate through required variables, and escape/assign them as necessary.
+ foreach ($required_vars as $var) {
+ $sql[$var] = mysql_real_escape_string($_GET[$var]);
+ }
+
+ /*
+ * QUERIES
+ *
+ * All of our variables are cleaned.
+ * Retrieve extension and plugin blocklist data (two queries).
+ */
+ $blitems_q = "
+ SELECT
+ blitems.id as itemId,
+ blitems.guid as itemGuid,
+ blitems.min as itemMin,
+ blitems.max as itemMax,
+ blitems.os as os,
+ blapps.id as appId,
+ blapps.blitem_id as appItemId,
+ blapps.guid as appGuid,
+ blapps.min as appMin,
+ blapps.max as appMax
+ FROM
+ blitems
+ LEFT JOIN blapps on blitems.id = blapps.blitem_id
+ WHERE
+ blapps.guid = '{$sql['appGuid']}'
+ OR blapps.guid IS NULL
+ ORDER BY
+ itemGuid, appGuid, itemMin, appMin
+ ";
+
+ $blitems_r = mysql_query($blitems_q);
+
+ if (!$blitems_r) {
+ $errors[] = 'MySQL query for blocklisted extensions failed.';
+ }
+
+ // If we have blocklisted extensions, arrange data for rendering.
+ if (mysql_num_rows($blitems_r)==0) {
+ $errors[] = 'No extensions are blocklisted for given application GUID and Version.';
+ } else {
+ // Array used for storing extensions stuff.
+ $blocklist = array();
+
+ // Array used for storing emItem metadata.
+ $blocklistMeta = array();
+
+ while ($row = mysql_fetch_array($blitems_r, MYSQL_ASSOC)) {
+
+ // Escape data results for display, which is the only place it goes.
+ foreach ($row as $key=>$val) {
+ $row[$key] = htmlentities($val, ENT_QUOTES, 'UTF-8');
+ }
+
+ // Store any per-emItem meta here (right now `os` is the only
+ // thing). Only do so if it hasn't been stored yet.
+ if (!empty($row['os']) && empty($blocklistMeta[$row['itemGuid']]['os'])) {
+ $blocklistMeta[$row['itemGuid']]['os'] = $row['os'];
+ }
+
+ // If we have item itemMin/itemMax values or an appId possible ranges, we create
+ // hashes for each itemId and its related range.
+ //
+ // Since itemGuids can have different itemIds, they are the first hash. Each
+ // itemId is effectively an item's versionRange. For each one of these we create
+ // a corresponding array containing the range values, which could be NULL.
+ if (!empty($row['itemMin']) && !empty($row['itemMax']) || !empty($row['appItemId'])) {
+ $blocklist['items'][$row['itemGuid']][$row['itemId']] = array(
+ 'itemMin' => $row['itemMin'],
+ 'itemMax' => $row['itemMax']
+ );
+
+ // Otherwise, our items array only contains a top-level containing the itemGuid.
+ //
+ // Doing so tells our template to terminate the item with /> because there is
+ // nothing left to display.
+ } else {
+ $blocklist['items'][$row['itemGuid']] = null;
+ }
+
+ // If we retrieved non-null blapp data, store it in the apps array.
+ //
+ // These are referenced later by their foreign key relationship to items (appItemId).
+ if ($row['appItemId']) {
+ $blocklist['apps'][$row['itemGuid']][$row['appItemId']][$row['appGuid']][] = array(
+ 'appMin' => $row['appMin'],
+ 'appMax' => $row['appMax']
+ );
+ }
+ }
+ }
+
+ $blplugins_q = "
+ SELECT
+ p.name,
+ p.description,
+ p.filename,
+ p.min,
+ p.max,
+ p.os,
+ p.xpcomabi
+ FROM
+ blplugins p
+ WHERE
+ (p.guid = '{$sql['appGuid']}' OR p.guid IS NULL)
+ ";
+
+ $blplugins_r = mysql_query($blplugins_q);
+
+ if (!$blplugins_r) {
+ $errors[] = 'MySQL query for blocklisted plugins failed.';
+ }
+
+ // If we have blocklisted plugins, arrange data for rendering.
+ if (mysql_num_rows($blplugins_r)==0) {
+ $errors[] = 'No plugins are blocklisted for given application GUID and Version.';
+ } else {
+
+ // Dummy object so we can include the component gracefully.
+ class Object { }
+
+ // Require version compare component from AMO.
+ require_once(dirname(__FILE__).'/../../controllers/components/versioncompare.php');
+
+ // Array used for storing plugins stuff.
+ $pluginItems = array();
+
+ while ($row = mysql_fetch_array($blplugins_r, MYSQL_ASSOC)) {
+
+ // Escape data results for display, which is the only place it goes.
+ foreach ($row as $key=>$val) {
+ $row[$key] = htmlentities($val, ENT_QUOTES, 'UTF-8');
+ }
+
+ // Request version 2 and lower ignores targetApplication entries for plugins
+ if ($sql['reqVersion'] <= 2) {
+ // Assign pluginItems to blocklist array if the client version is
+ // within the version range for the plugin item entry. If the
+ // version isn't within the range, we don't want to block that
+ // plugin.
+ $v = new VersioncompareComponent();
+ if ($v->versionBetween($sql['appVersion'],$row['min'],$row['max'])) {
+ $pluginItems[] = $row;
+ }
+ } else {
+ $pluginItems[] = $row;
+ }
+ }
+ }
+}
+
+
+
+/**
+ * DEBUG
+ *
+ * If we get here, something went wrong. For testing purposes, we can
+ * optionally display errors based on $_GET['debug'].
+ *
+ * By default, no errors are ever displayed because humans do not read this
+ * script.
+ *
+ * Until there is some sort of API for how clients handle errors,
+ * things should remain this way.
+ */
+if ($debug) {
+ echo '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">';
+ echo '<html lang="en">';
+
+ echo '<head>';
+ echo '<title>blocklist.php Debug Information</title>';
+ echo '<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">';
+ echo '</head>';
+
+ echo '<body>';
+
+ echo '<h1>Parameters</h1>';
+ echo '<pre>';
+ $out = array();
+ foreach ($_GET as $key=>$val) {
+ $out[$key] = strip_tags(htmlentities($val));
+ }
+ print_r($out);
+ echo '</pre>';
+
+ if (!empty($query)) {
+ echo '<h1>Query</h1>';
+ echo '<pre>';
+ echo $query;
+ echo '</pre>';
+ }
+
+ if (!empty($blocklist)) {
+ echo '<h1>Result - blocklist</h1>';
+ echo '<pre>';
+ print_r($blocklist);
+ echo '</pre>';
+ }
+
+ if (!empty($pluginItems)) {
+ echo '<h1>Result - pluginItems</h1>';
+ echo '<pre>';
+ print_r($pluginItems);
+ echo '</pre>';
+ }
+
+
+ if (!empty($errors) && is_array($errors)) {
+ echo '<h1>Errors Found</h1>';
+ echo '<pre>';
+ print_r($errors);
+ echo '</pre>';
+ } else {
+ echo '<h1>No Errors Found</h1>';
+ }
+
+ echo '</body>';
+
+ echo '</html>';
+ exit;
+}
+
+
+
+/**
+ * XML
+ *
+ * Form up our XML output and deliver it to the user.
+ * If we get here, we have to deliver a parsable RDF.
+ */
+header('Content-type: text/xml');
+echo "<?xml version=\"1.0\"?>\n";
+echo "<blocklist xmlns=\"http://www.mozilla.org/2006/addons-blocklist\">\n";
+
+if (!empty($blocklist) && is_array($blocklist)) {
+ echo " <emItems>\n";
+
+ // Iterate through our items, but only if we have some.
+ foreach ($blocklist['items'] as $itemGuid=>$item) {
+
+ $itemOs = null;
+
+ // Show the os info if it exists for this item.
+ if (!empty($blocklistMeta[$itemGuid]['os'])) {
+ $itemOs = " os=\"{$blocklistMeta[$itemGuid]['os']}\"";
+ }
+
+ // If we get an array, there's more to it than just the item GUID. We'll have to pull it out.
+ if (!empty($item) && is_array($item)) {
+
+ echo " <emItem id=\"{$itemGuid}\"{$itemOs}>\n";
+
+ // Each item has version ranges -- what versions of that item are blocked.
+ foreach ($item as $itemId=>$itemRange) {
+
+ // If there is app-specific info, leave the versionRange open.
+ if (!empty($blocklist['apps'][$itemGuid][$itemId])) {
+ echo " <versionRange";
+
+ // Display the min/max only if they exist.
+ if ($itemRange['itemMin'] && $itemRange['itemMax']) {
+ echo " minVersion=\"{$itemRange['itemMin']}\" maxVersion=\"{$itemRange['itemMax']}\"";
+ }
+ echo ">\n";
+
+ // Show each application and their version ranges.
+ foreach ($blocklist['apps'][$itemGuid][$itemId] as $appGuid=>$app) {
+ echo " <targetApplication";
+
+ // Only show the appGuid if it exists. If it doesn't, it means the add-on was banned
+ // for all possible applications.
+ if (!empty($appGuid)) {
+ echo " id=\"{$appGuid}\"";
+ }
+ echo ">\n";
+
+ // Show app version ranges that will be blocked.
+ foreach ($app as $appRange) {
+ if (!empty($appRange['appMin']) && !empty($appRange['appMax'])) {
+ echo " <versionRange minVersion=\"{$appRange['appMin']}\" maxVersion=\"{$appRange['appMax']}\"/>\n";
+ }
+ }
+ echo " </targetApplication>\n";
+ }
+ echo " </versionRange>\n";
+
+ // If there is no app-specific info, close it off and we're on to the next emItem.
+ } else {
+ echo " <versionRange";
+ if ($itemRange['itemMin'] && $itemRange['itemMax']) {
+ echo " minVersion=\"{$itemRange['itemMin']}\" maxVersion=\"{$itemRange['itemMax']}\"";
+ }
+ echo "/>\n";
+ }
+ }
+ echo " </emItem>\n";
+
+ // If we get a string, then we have a uber-blocked add-on guid. Show it and terminate the element.
+ } else {
+ echo " <emItem id=\"{$itemGuid}\"{$itemOs}/>\n";
+ }
+ }
+ echo " </emItems>\n";
+}
+
+if (!empty($pluginItems) && is_array($pluginItems)) {
+ echo "<pluginItems>\n";
+ foreach ($pluginItems as $pluginItem) {
+ $pluginOs = null;
+ $pluginAbi = null;
+
+ if (!empty($pluginItem['os'])) {
+ $pluginOs = " os=\"{$pluginItem['os']}\"";
+ }
+
+ if (!empty($pluginItem['xpcomabi'])) {
+ $pluginAbi = " xpcomabi=\"{$pluginItem['xpcomabi']}\"";
+ }
+ echo " <pluginItem{$pluginOs}{$pluginAbi}>\n";
+
+ if (!empty($pluginItem['name'])) {
+ echo " <match name=\"name\" exp=\"{$pluginItem['name']}\"/>\n";
+ }
+
+ if (!empty($pluginItem['description'])) {
+ echo " <match name=\"description\" exp=\"{$pluginItem['description']}\"/>\n";
+ }
+
+ if (!empty($pluginItem['filename'])) {
+ echo " <match name=\"filename\" exp=\"{$pluginItem['filename']}\"/>\n";
+ }
+
+ if ($sql['reqVersion'] > 2) {
+ echo " <versionRange>\n";
+ echo " <targetApplication id=\"{$sql['appGuid']}\">\n";
+ echo " <versionRange minVersion=\"{$pluginItem['min']}\" maxVersion=\"{$pluginItem['max']}\"/>\n";
+ echo " </targetApplication>\n";
+ echo " </versionRange>\n";
+ }
+
+ echo " </pluginItem>\n";
+ }
+ echo "</pluginItems>\n";
+}
+
+echo "</blocklist>\n";
+exit;
+?>
diff --git a/site/app/webroot/services/functions.php b/site/app/webroot/services/functions.php
new file mode 100644
index 0000000..1df1cb3
--- /dev/null
+++ b/site/app/webroot/services/functions.php
@@ -0,0 +1,76 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Mike Morgan <morgamic@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/**
+ * Determine the os_id based on passed OS or guess based on UA string.
+ * @param string|null $os
+ * @return int|bool $id id of the OS in the AMO database
+ */
+function get_os_id($appOS=null)
+{
+
+ if (is_null($appOS) && !empty($_GET['appOS']) && ctype_alpha($_GET['appOS'])) {
+ $appOS = $_GET['appOS'];
+ }
+
+ // possible matches
+ $os = array(
+ 'linux'=>PLATFORM_LINUX,
+ 'bsd'=>PLATFORM_BSD,
+ 'darwin'=>PLATFORM_MAC,
+ 'winnt'=>PLATFORM_WIN,
+ 'sunos'=>PLATFORM_SUN
+ );
+
+ // Check for a match.
+ $appOS = strtolower($appOS);
+ foreach ($os as $string=>$id) {
+ if ($appOS==$string) {
+ return $id;
+ }
+
+ if (strpos($appOS,$string)!==false) {
+ return $id;
+ }
+ }
+
+ // If we get here, there is no defined OS and the query will instead rely
+ // on "ALL" (1) in the OR
+ return false;
+}
+?>
diff --git a/site/app/webroot/services/install.php b/site/app/webroot/services/install.php
new file mode 100644
index 0000000..ba70ab4
--- /dev/null
+++ b/site/app/webroot/services/install.php
@@ -0,0 +1,233 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Justin Scott <fligtar@mozilla.com>
+ * Wil Clouser <clouserw@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ Whitelist redirect add-on installation service (originally bug 400046)
+
+ To work properly, an allowed site should link to this service like so:
+ https://addons.mozilla.org/services/install.php?addon_id={addon_id}
+
+ If the add-on is not hosted on AMO, it should be given an addon_key instead.
+
+ Properties of the add-on entries:
+ name [required]: Pretty name to display in xpinstall dialog and div
+ xpi: url of the xpi [xpi OR link is required]
+ link: url of the manual installation page [xpi OR link is required]
+ hash: the file hash for installTrigger
+ icon: the icon URL for xpinstall dialog
+ referrers: array of allowed referrer regex
+
+ XPI links must either be SSL or use a hash to verify that the user is getting the add-on they're supposed to.
+
+ @todo if this is going to become widely used or expanded it should have some l10n work done
+
+*/
+define('REGEX_MOZILLA', '/^https?:\/\/[^\/]*\.?mozilla\.(com|org)\/?.*/');
+define('REGEX_LOCALHOST', '/https?:\/\/[^\/]*\.?localhost.*/');
+define('REGEX_PERSONAS', '/https?:\/\/[^\/]*\.?getpersonas\.com\/?.*/');
+
+// If an add-on's referrers property is set, defaults will not be used unless specified
+$default_referrers = array('document.referrer.match('.REGEX_MOZILLA.')',
+ 'document.referrer.match('.REGEX_LOCALHOST.')');
+
+$addons = array(
+ /* Firefox Updated Page add-ons */
+ 'glubble' => array(
+ 'name' => 'Glubble',
+ 'xpi' => 'https://addons.mozilla.org/en-US/firefox/downloads/latest/5881',
+ 'icon' => 'https://addons.mozilla.org/en-US/firefox/images/addon_icon/5881'
+ ),
+ 'googletoolbar' => array(
+ 'name' => 'Google Toolbar',
+ 'link' => 'http://tools.google.com/tools/firefox/toolbar/FT3/intl/en/install.html'
+ ),
+
+ // Stumbleupon also used in Firefox 3 Get Personal
+ 138 => array(
+ 'name' => 'StumbleUpon',
+ 'xpi' => 'https://addons.mozilla.org/en-US/firefox/downloads/latest/138',
+ 'icon' => 'https://addons.mozilla.org/en-US/firefox/images/addon_icon/138'
+ ),
+
+ // Foxytunes also used in Firefox 3 Get Personal
+ 219 => array(
+ 'name' => 'Foxytunes',
+ 'xpi' => 'https://addons.mozilla.org/en-US/firefox/downloads/latest/219',
+ 'icon' => 'https://addons.mozilla.org/en-US/firefox/images/addon_icon/219'
+ ),
+
+ // Forecastfox also used in Firefox 3 Get Personal
+ 398 => array(
+ 'name' => 'Forecastfox',
+ 'xpi' => 'https://addons.mozilla.org/en-US/firefox/downloads/latest/398',
+ 'icon' => 'https://addons.mozilla.org/en-US/firefox/images/addon_icon/398'
+ ),
+ 424 => array(
+ 'name' => 'Wizz RSS News Reader',
+ 'link' => 'https://addons.mozilla.org/en-US/firefox/addons/policy/0/424/19068',
+ 'icon' => 'https://addons.mozilla.org/en-US/firefox/images/addon_icon/424'
+ ),
+ 1407 => array(
+ 'name' => 'Clipmarks',
+ 'xpi' => 'https://addons.mozilla.org/en-US/firefox/downloads/latest/1407'
+ ),
+
+ // Foxmarks also used in Firefox 3 Get Personal
+ 2410 => array(
+ 'name' => 'Foxmarks',
+ 'xpi' => 'https://addons.mozilla.org/en-US/firefox/downloads/latest/2410',
+ 'icon' => 'https://addons.mozilla.org/en-US/firefox/images/addon_icon/2410'
+ ),
+ 3348 => array(
+ 'name' => 'Pronto Shopping Messenger',
+ 'xpi' => 'https://addons.mozilla.org/en-US/firefox/downloads/latest/3348'
+ ),
+ 3945 => array(
+ 'name' => 'Fotofox',
+ 'xpi' => 'https://addons.mozilla.org/en-US/firefox/downloads/latest/3945'
+ ),
+
+ /* Firefox 3 Get Personal page */
+ // Forecastfox (see above)
+
+ 5202 => array(
+ 'name' => 'eBay Companion',
+ 'xpi' => 'https://addons.mozilla.org/en-US/firefox/downloads/latest/5202/platform:5/',
+ 'icon' => 'https://addons.mozilla.org/en-US/firefox/images/addon_icon/5202'
+ ),
+
+ // Stumbleupon (see above)
+
+ // Foxmarks (see above)
+
+ // Foxytunes (see above)
+
+ /* Other */
+ 'personas' => array(
+ 'name' => 'Personas for Firefox',
+ 'xpi' => 'https://addons.mozilla.org/en-US/firefox/downloads/latest/10900',
+ 'icon' => 'https://addons.mozilla.org/en-US/firefox/images/addon_icon/10900/1236031798',
+ 'referrers' => array_merge($default_referrers, array(
+ 'document.referrer.match('.REGEX_PERSONAS.')'
+ ))
+ ),
+
+ 'weave' => array(
+ 'name' => 'Weave',
+ 'xpi' => 'https://addons.mozilla.org/en-US/firefox/downloads/latest/10868',
+ 'icon' => 'https://addons.mozilla.org/en-US/firefox/images/addon_icon/10868/1236131155'
+ )
+ );
+
+
+ // If we have an addon_id, use it. Otherwise, look for an addon_key.
+ if (!empty($_GET['addon_id'])) {
+ $addon = $addons[$_GET['addon_id']];
+ } elseif (!empty($_GET['addon_key'])) {
+ $addon = $addons[$_GET['addon_key']];
+ }
+
+ // We have a link to another page where the add-on is available. Redirect them
+ // to that page.
+ if (!empty($addon['link'])) {
+ header("Location: {$addon['link']}");
+ exit;
+ }
+
+ // There was no external link, and there is no xpi information - they've asked
+ // for an invalid or unavailable xpi. Send a 404.
+ if (empty($addon['xpi'])) {
+ header('HTTP/1.0 404 Not Found', true, 404);
+ exit;
+ }
+
+
+?>
+
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<title>AMO Install Service</title>
+<script language="JavaScript" type="text/javascript" src="/js/__utm.js"></script>
+<script type="text/javascript">
+ function install() {
+ if (<?=implode(' || ', (!empty($addon['referrers']) ? $addon['referrers'] : $default_referrers))?>) {
+ var params = {
+ <?php
+ echo "'".htmlentities($addon['name'])."': {";
+ echo "URL: '".htmlentities($addon['xpi'])."',";
+ echo !empty($addon['icon']) ? "IconURL: '".htmlentities($addon['icon'])."'," : '';
+ echo !empty($addon['hash']) ? "Hash: '".htmlentities($addon['hash'])."'," : '';
+ ?>
+ toString: function () { return this.URL; }
+ }
+ };
+ InstallTrigger.install(params, goBack);
+ } else {
+ window.location.href = 'https://addons.mozilla.org/';
+ }
+ }
+
+ function goBack() {
+ history.back();
+ }
+</script>
+
+<style type="text/css">
+ .manualinstall {
+ text-align: center;
+ color: #b94413;
+ font-family:arial,verdana,sans-serif;
+ padding: 20px;
+ font-size: 17px;
+ }
+ .manualinstall a {
+ color: #b94413;
+ font-weight: bold;
+ }
+</style>
+</head>
+
+<body onload="install()">
+ <div class="manualinstall">
+ If you are not prompted to install <?=$addon['name']?> in a moment, please <a href="<?=(!empty($addon['xpi']) ? $addon['xpi'] : $addon['link'])?>">click here</a>.
+ </div>
+</body>
+</html>
+
diff --git a/site/app/webroot/services/monitor.php b/site/app/webroot/services/monitor.php
new file mode 100644
index 0000000..fc530f6
--- /dev/null
+++ b/site/app/webroot/services/monitor.php
@@ -0,0 +1,133 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Wil Clouser <clouserw@mozilla.com>
+ * Justin Scott <fligtar@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/**
+ * This is a lightweight page designed to be monitored with a program like nagios. I
+ * don't want to duplicate the test suite, but I do want something that we can hit
+ * pretty often. If there is a problem, this will throw a 500 error.
+ *
+ */
+
+// Never cache this page
+header('Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0, private');
+header('Pragma: no-cache');
+
+// Grab the site config
+require_once('../../config/config.php');
+require_once('../../config/constants.php');
+
+global $results, $shadow_databases;
+
+// Check Main Database
+ $dbh = @mysql_connect(DB_HOST.':'.DB_PORT,DB_USER,DB_PASS);
+ testo('Connect to MAIN database ('.DB_HOST.')', is_resource($dbh));
+ testo('Select MAIN database ('.DB_NAME.')', @mysql_select_db(DB_NAME, $dbh));
+ unset ($dbh);
+
+// Check Shadow Databases
+ if (!empty($shadow_databases)) {
+ foreach ($shadow_databases as $k => $shadow_database) {
+ $dbh = @mysql_connect($shadow_database['DB_HOST'].':'.$shadow_database['DB_PORT'],$shadow_database['DB_USER'],$shadow_database['DB_PASS']);
+ testo("Connect to SHADOW database {$k} @ {$shadow_database['DB_WEIGHT']} ({$shadow_database['DB_HOST']})", is_resource($dbh));
+ testo("Select SHADOW database {$k} @ {$shadow_database['DB_WEIGHT']} ({$shadow_database['DB_NAME']})", @mysql_select_db($shadow_database['DB_NAME'], $dbh));
+ unset ($dbh);
+ }
+ }
+ elseif (defined('SHADOW_DB_NAME')) {
+ $dbh = @mysql_connect(SHADOW_DB_HOST.':'.SHADOW_DB_PORT,SHADOW_DB_USER,SHADOW_DB_PASS);
+ testo('Connect to SHADOW database ('.SHADOW_DB_HOST.')', is_resource($dbh));
+ testo('Select SHADOW database ('.SHADOW_DB_NAME.')', @mysql_select_db(SHADOW_DB_NAME, $dbh));
+ unset ($dbh);
+ }
+
+// Check Memcache
+ testo('Memcache is installed', class_exists('Memcache'));
+ testo('Memcache is configured', (is_array($memcache_config) && !empty($memcache_config)));
+
+ if (class_exists('Memcache')) {
+ $_memcache = new Memcache();
+
+ $total = 0;
+ foreach ($memcache_config as $host=>$options) {
+ testo("Memcache server ({$host}) is responding", $_memcache->addServer($host, $options['port'], $options['persistent'], $options['weight'], $options['timeout'], $options['retry_interval']));
+ $total++;
+ }
+
+ $_memcache->close();
+
+ testo("At least 2 memcache servers? ({$total})", ($total>=2));
+ }
+
+// Print out all our results
+ foreach ($results as $result) {
+
+ if ($result['result'] === 'FAILED') {
+ echo "<b style=\"color:red;\">{$result['message']}: {$result['result']}</b><br />\n";
+ } else {
+ echo "{$result['message']}: {$result['result']}<br />\n";
+ }
+
+ }
+
+ echo '<hr />';
+ echo '<p>What are we actually testing? <a href="http://viewvc.svn.mozilla.org/vc/addons/trunk/site/app/webroot/services/monitor.php?view=markup">Check the source</a>';
+ echo '<p>Want more tests? <a href="/tests/">Hit the test suite</a></p>';
+
+
+// Functions
+ /**
+ * To use as a general message function, pass two strings
+ * To use to trigger errors, pass a message and a boolean
+ */
+ function testo($message, $result) {
+ global $results;
+
+ // If they passed in a boolean, we convert it to a string
+ if (is_bool($result)) {
+ $result = ($result ? 'success' : 'FAILED');
+ }
+
+ $results[] = array( 'message' => $message, 'result' => $result );
+
+ if ($result === 'FAILED') {
+ header("HTTP/1.0 500 Internal Server Error");
+ }
+ }
+
+?>
diff --git a/site/app/webroot/services/pfs.php b/site/app/webroot/services/pfs.php
new file mode 100644
index 0000000..455e5fb
--- /dev/null
+++ b/site/app/webroot/services/pfs.php
@@ -0,0 +1,435 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Vladimir Vukicevic <vladimir@pobox.com>
+ * Doron Rosenberg <doronr@us.ibm.com>
+ * Johnny Stenback <jst@mozilla.org>
+ * Mike Morgan <morgamic@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/**
+ * Plugin Finder Service
+ *
+ * The purpose of this script is to determine a matching plugin based on mime-type
+ * for an embedded HTML object, then return the correct information for a corresponding plugin.
+ *
+ * @package remora
+ * @subpackage docs
+ * @TODO figure out database structure for plugin addontype
+ * @TODO clean this ____ up and make the script depend on the database
+ *
+ */
+
+/**
+ * Set variables. We are allowing these to come in since they are compared to regular
+ * expressions eventually anyway. So yes, we are aware they are coming from $_GET.
+ */
+$mimetype = isset($_GET['mimetype']) ? $_GET['mimetype'] : null;
+$reqTargetAppGuid = isset($_GET['appID']) ? $_GET['appID'] : null;
+$reqTargetAppVersion = isset($_GET['appVersion']) ? $_GET['appVersion'] : null;
+$clientOS = isset($_GET['clientOS']) ? $_GET['clientOS'] : null;
+$chromeLocale = isset($_GET['chromeLocale']) ? $_GET['chromeLocale'] : null;
+
+// Set the version string, which is stored in appRelease, not appVersion (see bug 433615)
+$appRelease = isset($_GET['appRelease']) ? $_GET['appRelease'] : null;
+
+/**
+ * Only execute if we have proper variables passed from the client.
+ */
+if (!empty($mimetype) &&
+ !empty($reqTargetAppGuid) &&
+ !empty($reqTargetAppVersion) &&
+ !empty($clientOS) &&
+ !empty($chromeLocale)) {
+
+ /**
+ * Figure out what plugins we've got, and what plugins we know where
+ * to get.
+ */
+ $name = '';
+ $guid = '-1';
+ $version = '';
+ $iconUrl = '';
+ $XPILocation = '';
+ $InstallerLocation = '';
+ $InstallerHash = '';
+ $InstallerShowsUI = 'true';
+ $manualInstallationURL = '';
+ $licenseURL = '';
+ $needsRestart = 'true';
+
+ /**
+ * Begin our huge and embarrassing if-else statement.
+ */
+ if (($mimetype == 'application/x-shockwave-flash' ||
+ $mimetype == 'application/futuresplash') &&
+ preg_match('/^(Win|(PPC|Intel) Mac OS X|Linux.+i\d86)|SunOs/i', $clientOS)) {
+ // We really want the regexp for Linux to be /Linux(?! x86_64)/ but
+ // for now we can't tell 32-bit linux appart from 64-bit linux, so
+ // feed all x86_64 users the flash player, even if it's a 32-bit
+ // plugin
+
+ // We've got flash plugin installers for Win and Linux (x86),
+ // present those to the user, and for Mac users, tell them where
+ // they can go to get the installer.
+
+ $name = 'Adobe Flash Player';
+ $manualInstallationURL = 'http://www.adobe.com/go/getflashplayer';
+
+ // Don't use a https URL for the license here, per request from
+ // Macromedia.
+ if ($chromeLocale != 'ja-JP') {
+ $licenseURL = 'http://www.adobe.com/go/eula_flashplayer';
+ } else {
+ $licenseURL = 'http://www.adobe.com/go/eula_flashplayer_jp';
+ }
+
+ if (preg_match('/^Windows NT 6\.0/', $clientOS)) {
+ $guid = '{4cfaef8a-a6c9-41a0-8e6f-967eb8f49143}';
+ $XPILocation = null;
+ $licenseURL = null;
+ } else if (preg_match('/^Win/', $clientOS)) {
+ $guid = '{4cfaef8a-a6c9-41a0-8e6f-967eb8f49143}';
+ $XPILocation = 'http://fpdownload.macromedia.com/get/flashplayer/xpi/current/flashplayer-win.xpi';
+ $InstallerShowsUI = 'false';
+ } else if (preg_match('/^Linux/', $clientOS)) {
+ $guid = '{7a646d7b-0202-4491-9151-cf66fa0722b2}';
+ $XPILocation = 'http://fpdownload.macromedia.com/get/flashplayer/xpi/current/flashplayer-linux.xpi';
+ $InstallerShowsUI = 'false';
+ } else if (preg_match('/^(PPC|Intel) Mac OS X/', $clientOS)) {
+ $guid = '{89977581-9028-4be0-b151-7c4f9bcd3211}';
+ $XPILocation = 'http://fpdownload.macromedia.com/get/flashplayer/xpi/current/flashplayer-mac.xpi';
+ } else if (preg_match('/^SunOs/i', $clientOS)) {
+ $guid = '{0ae66efd-e183-431a-ab51-3af2c278a3dd}';
+ if (preg_match('/sun4u/i', $clientOS)) {
+ $XPILocation = 'http://download.macromedia.com/pub/flashplayer/xpi/current/flashplayer-solaris-sparc.xpi';
+ } else {
+ $XPILocation = 'http://download.macromedia.com/pub/flashplayer/xpi/current/flashplayer-solaris-x86.xpi';
+ }
+ }
+ } elseif ($mimetype == 'application/x-director' &&
+ preg_match('/^(Win|PPC Mac OS X)/', $clientOS)) {
+ $name = 'Macromedia Shockwave Player';
+ $manualInstallationURL = 'http://www.adobe.com/go/getshockwave/';
+ $version = '10.1';
+
+ // Even though the shockwave installer is not a silent installer, we
+ // need to show its EULA here since we've got a slimmed down
+ // installer that doesn't do that itself.
+ if ($chromeLocale != 'ja-JP') {
+ $licenseURL = 'http://www.adobe.com/go/eula_shockwaveplayer';
+ } else {
+ $licenseURL = 'http://www.adobe.com/go/eula_shockwaveplayer_jp';
+ }
+
+ if (preg_match('/^Win/', $clientOS)) {
+ $guid = '{45f2a22c-4029-4209-8b3d-1421b989633f}';
+
+ if ($chromeLocale == 'ja-JP') {
+ $XPILocation = 'https://www.macromedia.com/go/xpi_shockwaveplayerj_win';
+ } else {
+ $XPILocation = 'https://www.macromedia.com/go/xpi_shockwaveplayer_win';
+ }
+ } else if (preg_match('/^PPC Mac OS X/', $clientOS)) {
+ $guid = '{49141640-b629-4d57-a539-b521c4a99eff}';
+
+ if ($chromeLocale == 'ja-JP') {
+ $XPILocation = 'https://www.macromedia.com/go/xpi_shockwaveplayerj_macosx';
+ } else {
+ $XPILocation = 'https://www.macromedia.com/go/xpi_shockwaveplayer_macosx';
+ }
+ }
+ } elseif (($mimetype == 'audio/x-pn-realaudio-plugin' ||
+ $mimetype == 'audio/x-pn-realaudio') &&
+ preg_match('/^(Win|Linux|PPC Mac OS X)/', $clientOS)) {
+ $name = 'Real Player';
+ $version = '10.5';
+ $manualInstallationURL = 'http://www.real.com';
+
+ if (preg_match('/^Win/', $clientOS)) {
+ $XPILocation = 'http://forms.real.com/real/player/download.html?type=firefox';
+ $guid = '{d586351c-cb55-41a7-8e7b-4aaac5172d39}';
+ } else {
+ $guid = '{269eb771-59de-4702-9209-ca97ce522f6d}';
+ }
+ } elseif (preg_match('/^(application\/(sdp|x-(mpeg|rtsp|sdp))|audio\/(3gpp(2)?|AMR|aiff|basic|mid(i)?|mp4|mpeg|vnd\.qcelp|wav|x-(aiff|m4(a|b|p)|midi|mpeg|wav))|image\/(pict|png|tiff|x-(macpaint|pict|png|quicktime|sgi|targa|tiff))|video\/(3gpp(2)?|flc|mp4|mpeg|quicktime|sd-video|x-mpeg))$/', $mimetype) &&
+ preg_match('/^(Win|PPC Mac OS X)/', $clientOS)) {
+ //
+ // Well, we don't have a plugin that can handle any of those
+ // mimetypes, but the Apple Quicktime plugin can. Point the user to
+ // the Quicktime download page.
+ //
+
+ $name = 'Apple Quicktime';
+ $guid = '{a42bb825-7eee-420f-8ee7-834062b6fefd}';
+ $InstallerShowsUI = 'true';
+ $manualInstallationURL = 'http://www.apple.com/quicktime/download/';
+ } elseif (preg_match('/^application\/x-java-((applet|bean)(;jpi-version=1\.5|;version=(1\.(1(\.[1-3])?|(2|4)(\.[1-2])?|3(\.1)?|5)))?|vm)$/', $mimetype) &&
+ preg_match('/^(Win|Linux|PPC Mac OS X)/', $clientOS)) {
+ // We serve up the Java plugin for the following mimetypes:
+ //
+ // application/x-java-vm
+ // application/x-java-applet;jpi-version=1.5
+ // application/x-java-bean;jpi-version=1.5
+ // application/x-java-applet;version=1.3
+ // application/x-java-bean;version=1.3
+ // application/x-java-applet;version=1.2.2
+ // application/x-java-bean;version=1.2.2
+ // application/x-java-applet;version=1.2.1
+ // application/x-java-bean;version=1.2.1
+ // application/x-java-applet;version=1.4.2
+ // application/x-java-bean;version=1.4.2
+ // application/x-java-applet;version=1.5
+ // application/x-java-bean;version=1.5
+ // application/x-java-applet;version=1.3.1
+ // application/x-java-bean;version=1.3.1
+ // application/x-java-applet;version=1.4
+ // application/x-java-bean;version=1.4
+ // application/x-java-applet;version=1.4.1
+ // application/x-java-bean;version=1.4.1
+ // application/x-java-applet;version=1.2
+ // application/x-java-bean;version=1.2
+ // application/x-java-applet;version=1.1.3
+ // application/x-java-bean;version=1.1.3
+ // application/x-java-applet;version=1.1.2
+ // application/x-java-bean;version=1.1.2
+ // application/x-java-applet;version=1.1.1
+ // application/x-java-bean;version=1.1.1
+ // application/x-java-applet;version=1.1
+ // application/x-java-bean;version=1.1
+ // application/x-java-applet
+ // application/x-java-bean
+ //
+ //
+ // We don't have a Java plugin to offer here, but Sun's got one for
+ // Windows. For other platforms we know where to get one, point the
+ // user to the JRE download page.
+ //
+
+ $name = 'Java Runtime Environment';
+ $version = '';
+ $manualInstallationURL = 'http://java.com/firefoxjre';
+ $InstallerShowsUI = 'false';
+
+ // For now, send Vista users to a manual download page.
+ //
+ // This is a temp fix for bug 366129 until vista has a non-manual
+ // solution.
+ if (preg_match('/^Windows NT 6\.0/', $clientOS)) {
+ $guid = '{fbe640ef-4375-4f45-8d79-767d60bf75b8}';
+ $InstallerLocation = 'http://java.com/firefoxjre_exe';
+ $InstallerHash = 'sha1:89a78d34a36d7e25cc32b1a507a2cd6fb87dd40a';
+ $needsRestart = 'false';
+ } elseif (preg_match('/^Win/', $clientOS)) {
+ $guid = '{92a550f2-dfd2-4d2f-a35d-a98cfda73595}';
+ $InstallerLocation = 'http://java.com/firefoxjre_exe';
+ $InstallerHash = 'sha1:89a78d34a36d7e25cc32b1a507a2cd6fb87dd40a';
+ $XPILocation = 'http://java.com/jre-install.xpi';
+ } else {
+ $guid = '{fbe640ef-4375-4f45-8d79-767d60bf75b8}';
+ }
+ } elseif (($mimetype == 'application/pdf' ||
+ $mimetype == 'application/vnd.fdf' ||
+ $mimetype == 'application/vnd.adobe.xfdf' ||
+ $mimetype == 'application/vnd.adobe.xdp+xml' ||
+ $mimetype == 'application/vnd.adobe.xfd+xml') &&
+ preg_match('/^(Win|PPC Mac OS X|Linux(?! x86_64))/', $clientOS)) {
+ $name = 'Adobe Acrobat Plug-In';
+ $guid = '{d87cd824-67cb-4547-8587-616c70318095}';
+ $manualInstallationURL = 'http://www.adobe.com/products/acrobat/readstep.html';
+ } elseif ($mimetype == 'application/x-mtx' &&
+ preg_match('/^(Win|PPC Mac OS X)/', $clientOS)) {
+ $name = 'Viewpoint Media Player';
+ $guid = '{03f998b2-0e00-11d3-a498-00104b6eb52e}';
+ $manualInstallationURL = 'http://www.viewpoint.com/pub/products/vmp.html';
+ } elseif (preg_match('/^(application\/(asx|x-(mplayer2|ms-wmp))|video\/x-ms-(asf(-plugin)?|wm(p|v|x)?|wvx)|audio\/x-ms-w(ax|ma))$/', $mimetype)) {
+ // We serve up the Windows Media Player plugin for the following mimetypes:
+ //
+ // application/asx
+ // application/x-mplayer2
+ // audio/x-ms-wax
+ // audio/x-ms-wma
+ // video/x-ms-asf
+ // video/x-ms-asf-plugin
+ // video/x-ms-wm
+ // video/x-ms-wmp
+ // video/x-ms-wmv
+ // video/x-ms-wmx
+ // video/x-ms-wvx
+ //
+ // For all windows users who don't have the WMP 11 plugin, give them a
+ // link for it.
+ if (preg_match('/^Win/', $clientOS)) {
+ $name = 'Windows Media Player';
+ $version = '11';
+ $guid = '{cff1240a-fd24-4b9f-8183-ccd96e5300d0}';
+ $manualInstallationURL = 'http://port25.technet.com/pages/windows-media-player-firefox-plugin-download.aspx';
+
+ // For OSX users -- added Intel to this since flip4mac is a UB.
+ // Contact at MS was okay w/ this, plus MS points to this anyway.
+ } elseif (preg_match('/^(PPC|Intel) Mac OS X/', $clientOS)) {
+ $name = 'Flip4Mac';
+ $version = '2.1';
+ $guid = '{cff0240a-fd24-4b9f-8183-ccd96e5300d0}';
+ $manualInstallationURL = 'http://www.flip4mac.com/wmv_download.htm';
+ }
+ } elseif ($mimetype == 'application/x-xstandard' && preg_match('/^(Win|PPC Mac OS X)/', $clientOS)) {
+ $name = 'XStandard XHTML WYSIWYG Editor';
+ $guid = '{3563d917-2f44-4e05-8769-47e655e92361}';
+ $iconUrl = 'http://xstandard.com/images/xicon32x32.gif';
+ $XPILocation = 'http://xstandard.com/download/xstandard.xpi';
+ $InstallerShowsUI = 'false';
+ $manualInstallationURL = 'http://xstandard.com/download/';
+ $licenseURL = 'http://xstandard.com/license/';
+ } elseif ($mimetype == 'application/x-dnl' && preg_match('/^Win/', $clientOS)) {
+ $name = 'DNL Reader';
+ $guid = '{ce9317a3-e2f8-49b9-9b3b-a7fb5ec55161}';
+ $version = '5.5';
+ $iconUrl = 'http://digitalwebbooks.com/reader/dwb16.gif';
+ $XPILocation = 'http://digitalwebbooks.com/reader/xpinst.xpi';
+ $InstallerShowsUI = 'false';
+ $manualInstallationURL = 'http://digitalwebbooks.com/reader/';
+ } elseif ($mimetype == 'application/x-videoegg-loader' && preg_match('/^Win/', $clientOS)) {
+ $name = 'VideoEgg Publisher';
+ $guid = '{b8b881f0-2e07-11db-a98b-0800200c9a66}';
+ $iconUrl = 'http://videoegg.com/favicon.ico';
+ $XPILocation = 'http://update.videoegg.com/Install/Windows/Initial/VideoEggPublisher.xpi';
+ $InstallerShowsUI = 'true';
+ $manualInstallationURL = 'http://www.videoegg.com/';
+ } elseif ($mimetype == 'video/divx' && preg_match('/^Win/', $clientOS)) {
+ $name = 'DivX Web Player';
+ $guid = '{a8b771f0-2e07-11db-a98b-0800200c9a66}';
+ $iconUrl = 'http://images.divx.com/divx/player/webplayer.png';
+ $XPILocation = 'http://download.divx.com/player/DivXWebPlayer.xpi';
+ $InstallerShowsUI = 'false';
+ $licenseURL = 'http://go.divx.com/plugin/license/';
+ $manualInstallationURL = 'http://go.divx.com/plugin/download/';
+ } elseif ($mimetype == 'video/divx' && preg_match('/^(PPC|Intel) Mac OS X/', $clientOS)) {
+ $name = 'DivX Web Player';
+ $guid = '{a8b771f0-2e07-11db-a98b-0800200c9a66}';
+ $iconUrl = 'http://images.divx.com/divx/player/webplayer.png';
+ $XPILocation = 'http://download.divx.com/player/DivXWebPlayerMac.xpi';
+ $InstallerShowsUI = 'false';
+ $licenseURL = 'http://go.divx.com/plugin/license/';
+ $manualInstallationURL = 'http://go.divx.com/plugin/download/';
+ }
+ // End ridiculously huge and embarrassing if-else block.
+
+}
+// End our PFS block.
+
+
+
+/**
+ * Set up our plugin array based on what we've found.
+ */
+$plugin = array();
+$plugin['mimetype'] = !empty($mimetype) ? $mimetype : '-1';
+$plugin['name'] = !empty($name) ? $name : '-1';
+$plugin['guid'] = !empty($guid) ? $guid : '-1';
+$plugin['version'] = !empty($version) ? $version : null;
+$plugin['iconUrl'] = !empty($iconUrl) ? $iconUrl : null;
+$plugin['XPILocation'] = !empty($XPILocation) ? $XPILocation : null;
+$plugin['InstallerLocation'] = !empty($InstallerLocation) ? $InstallerLocation: null;
+$plugin['InstallerHash'] = !empty($InstallerHash) ? $InstallerHash : null;
+$plugin['InstallerShowsUI'] = !empty($InstallerShowsUI) ? $InstallerShowsUI : null;
+$plugin['manualInstallationURL'] = !empty($manualInstallationURL) ? $manualInstallationURL : null;
+$plugin['licenseURL'] = !empty($licenseURL) ? $licenseURL : null;
+$plugin['needsRestart'] = !empty($needsRestart) ? $needsRestart : 'true';
+
+/**
+ * If we have Firefox 3, force fallback to the manual install URL.
+ *
+ * This is a one-off fix for bug 433592.
+ */
+if (!empty($appRelease) && preg_match('/^3\..+/', $appRelease)) {
+ $plugin['XPILocation'] = null;
+ $plugin['InstallerLocation'] = null;
+ $plugin['InstallerHash'] = null;
+ $plugin['licenseURL'] = null;
+}
+
+
+
+/**
+ * XML OUTPUT
+ *
+ * If we're here, we've set our $plugin array (for better or worse) and it has
+ * at least set indexes for all output (no notices).
+ *
+ * Default values like -1 for name/guid will tell the browser that PFS doesn't know about that mime-type.
+ */
+
+// Encode $plugin data for XML output.
+$xml = array();
+foreach ($plugin as $key=>$val) {
+ $xml[$key] = htmlentities($val,ENT_QUOTES,'UTF-8');
+}
+
+header('Content-type: text/xml');
+echo <<<XML
+<?xml version="1.0"?>
+<RDF:RDF xmlns:RDF="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:pfs="http://www.mozilla.org/2004/pfs-rdf#">
+
+<RDF:Description about="urn:mozilla:plugin-results:{$xml['mimetype']}">
+ <pfs:plugins><RDF:Seq>
+ <RDF:li resource="urn:mozilla:plugin:{$xml['guid']}"/>
+ </RDF:Seq></pfs:plugins>
+</RDF:Description>
+
+<RDF:Description about="urn:mozilla:plugin:{$xml['guid']}">
+ <pfs:updates><RDF:Seq>
+ <RDF:li resource="urn:mozilla:plugin:{$xml['guid']}:{$xml['version']}"/>
+ </RDF:Seq></pfs:updates>
+</RDF:Description>
+
+<RDF:Description about="urn:mozilla:plugin:{$xml['guid']}:{$xml['version']}">
+ <pfs:name>{$xml['name']}</pfs:name>
+ <pfs:requestedMimetype>{$xml['mimetype']}</pfs:requestedMimetype>
+ <pfs:guid>{$xml['guid']}</pfs:guid>
+ <pfs:version>{$xml['version']}</pfs:version>
+ <pfs:IconUrl>{$xml['iconUrl']}</pfs:IconUrl>
+ <pfs:InstallerLocation>{$xml['InstallerLocation']}</pfs:InstallerLocation>
+ <pfs:InstallerHash>{$xml['InstallerHash']}</pfs:InstallerHash>
+ <pfs:XPILocation>{$xml['XPILocation']}</pfs:XPILocation>
+ <pfs:InstallerShowsUI>{$xml['InstallerShowsUI']}</pfs:InstallerShowsUI>
+ <pfs:manualInstallationURL>{$xml['manualInstallationURL']}</pfs:manualInstallationURL>
+ <pfs:licenseURL>{$xml['licenseURL']}</pfs:licenseURL>
+ <pfs:needsRestart>{$xml['needsRestart']}</pfs:needsRestart>
+</RDF:Description>
+
+</RDF:RDF>
+XML;
+?>
diff --git a/site/app/webroot/services/update.php b/site/app/webroot/services/update.php
new file mode 100644
index 0000000..f31ff85
--- /dev/null
+++ b/site/app/webroot/services/update.php
@@ -0,0 +1,420 @@
+<?php
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is addons.mozilla.org site.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Mike Morgan <morgamic@mozilla.com>
+ * Justin Scott <fligtar@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/**
+ * VersionCheck.php is a dynamic RDF that compares version information for
+ * extensions and determines whether or not an update is needed. If an update
+ * is needed, the correct update file is referenced based on the AMO database
+ * and repository. The script is set to die silently instead of echoing errors
+ * clients don't use anyway. For testing, if you would like to debug, supply
+ * the script with ?debug=true
+ *
+ * @package amo
+ * @subpackage pub
+ */
+
+
+/**
+ * CONFIG
+ *
+ * Require site config.
+ */
+require_once('../../config/config.php');
+require_once('../../config/constants.php');
+require_once('./functions.php');
+
+
+
+/**
+ * VARIABLES
+ *
+ * Initialize, set up and clean variables.
+ */
+
+// Required variables that we need to run the script.
+$required_vars = array('reqVersion',
+ 'id',
+ 'version',
+ 'appID',
+ 'appVersion');
+
+// Mapping of addontypes to addontype_id.
+// These are used in the urn, and should not be localized.
+// We are using lower-case strings to be consistent with currently installed add-ons.
+$addontypes = array(
+ ADDON_EXTENSION => 'extension',
+ ADDON_THEME => 'theme',
+ ADDON_DICT => 'extension',
+ ADDON_SEARCH => 'search',
+ ADDON_LPAPP => 'item',
+ ADDON_LPADDON => 'extension',
+ ADDON_PLUGIN => 'plugin'
+);
+
+// Debug flag.
+$debug = isset($_GET['debug']) ? true : false;
+
+// Test flag.
+$test = isset($_GET['test']) ? true : false;
+
+// Array to hold errors for debugging.
+$errors = array();
+
+// Set OS. get_os_id() can only return an int.
+$sql['os_id'] = get_os_id();
+
+// Iterate through required variables, and escape/assign them as necessary.
+foreach ($required_vars as $var) {
+ if (empty($_GET[$var])) {
+ $errors[] = 'Required variable '.$var.' not set.'; // set debug error
+ }
+}
+
+// Determine if we're detecting installed add-ons for a Facebook user
+$detect_installed = !empty($_COOKIE['AMOfbUser']);
+
+/**
+ * DATABASE
+ *
+ * Connect to and select proper database. By default the update script uses SHADOW.
+ *
+ * In order for testing to work, we can add a query variable specifying that the incoming request is for testing only.
+ */
+
+// Are we trying to run a test? If so, use the test db.
+if ($test) {
+ $dbh = @mysql_connect(TEST_DB_HOST.':'.TEST_DB_PORT,TEST_DB_USER,TEST_DB_PASS);
+
+ if (!is_resource($dbh)) {
+ $errors[] = 'MySQL connection to TEST DB failed.';
+ } elseif (!@mysql_select_db(TEST_DB_NAME, $dbh)) {
+ $errors[] = 'Could not select TEST database '.TEST_DB_NAME.'.';
+ }
+
+// If we're trying to detect installed add-ons, we need write access
+} elseif ($detect_installed) {
+ $dbh = @mysql_connect(DB_HOST.':'.DB_PORT,DB_USER,DB_PASS);
+
+ if (!is_resource($dbh)) {
+ $errors[] = 'MySQL connection to DB failed.';
+ } elseif (!@mysql_select_db(DB_NAME, $dbh)) {
+ $errors[] = 'Could not select database '.DB_NAME.'.';
+ }
+
+// Otherwise, we're going to use SHADOW (our read-only db server).
+} else {
+ $dbh = @mysql_connect(SHADOW_DB_HOST.':'.SHADOW_DB_PORT,SHADOW_DB_USER,SHADOW_DB_PASS);
+
+ if (!is_resource($dbh)) {
+ $errors[] = 'MySQL connection to SHADOW DB failed.';
+ } elseif (!@mysql_select_db(SHADOW_DB_NAME, $dbh)) {
+ $errors[] = 'Could not select SHADOW database '.SHADOW_DB_NAME.'.';
+ }
+}
+
+
+
+/*
+ * QUERIES
+ *
+ * Our variables are there and we're connected to the database.
+ * Now we can format our data for SQL then attempt to retrieve update information.
+ */
+if (empty($errors) && !$detect_installed) {
+
+ // Iterate through required variables, and escape/assign them as necessary.
+ foreach ($required_vars as $var) {
+ $sql[$var] = mysql_real_escape_string($_GET[$var]);
+ }
+
+ /**
+ * Determine whether the add-on is hosted on AMO and if so, if it's public
+ * or in the sandbox.
+ */
+
+ $id_query = "
+ SELECT
+ id,
+ status
+ FROM
+ addons
+ WHERE
+ guid = '{$sql['id']}' AND
+ inactive = 0
+ LIMIT 1
+ ";
+
+ $id_res = mysql_query($id_query);
+
+ if (!$id_res) {
+ $errors[] = 'Add-on GUID not found in database.';
+ }
+ else {
+ // Add-on GUID was found in the db
+ $addon = mysql_fetch_array($id_res, MYSQL_ASSOC);
+
+ if ($addon['status'] == STATUS_PUBLIC) {
+ // If public, we only pull public files
+ $where = 'WHERE files.status = '.STATUS_PUBLIC;
+ }
+ else {
+ // Otherwise, we pull the appropriate file and find the same version
+ // currently in use for updated compatibility information
+ $where = "WHERE files.status > ".STATUS_NULL." AND versions.version = '{$sql['version']}'";
+ }
+
+ $os_query = ($sql['os_id']) ? " OR files.platform_id = {$sql['os_id']}" : ''; // Set up os_id.
+
+ // Query for possible updates.
+ //
+ // The query sorts by version.vid, which is an auto_increment primary key for that table.
+ $query = "
+ SELECT
+ addons.guid as guid,
+ addons.id as id,
+ addons.addontype_id as type,
+ applications.guid as appguid,
+ appmin.version as min,
+ appmax.version as max,
+ files.id as file_id,
+ files.hash,
+ files.filename,
+ versions.id as version_id,
+ versions.releasenotes,
+ versions.version as version
+ FROM
+ versions
+ INNER JOIN addons ON addons.id = versions.addon_id AND addons.id = {$addon['id']}
+ INNER JOIN applications_versions ON applications_versions.version_id = versions.id
+ INNER JOIN applications ON applications_versions.application_id = applications.id AND applications.guid = '{$sql['appID']}'
+ INNER JOIN appversions appmin ON appmin.id = applications_versions.min
+ INNER JOIN appversions appmax ON appmax.id = applications_versions.max
+ INNER JOIN files ON files.version_id = versions.id AND (files.platform_id = ".PLATFORM_ALL."{$os_query})
+ {$where}
+ ORDER BY
+ versions.id DESC
+ LIMIT 1
+ ";
+
+ $res = mysql_query($query);
+
+ if (!$res) {
+ // Possibly failed because version does not exist on AMO
+ $errors[] = 'MySQL query for update information failed.';
+ } else {
+ $data = mysql_fetch_array($res,MYSQL_ASSOC);
+
+ if (!empty($data['file_id'])) {
+ /**
+ * Note that if you're in a dev environment you'll want to set FILE_HOST to your local machine.
+ * I did not want to include logic here for DEV or not DEV mostly because this script doesn't
+ * need any extra crap in it.
+ *
+ * If you want to test updates, change your config and set up a web dir with public files in it.
+ */
+ $data['uri'] = FILES_HOST . '/' . $data['id'] . '/' . $data['filename'];
+ }
+
+ if (!empty($data['type'])) {
+ $data['type'] = $addontypes[$data['type']];
+ }
+ }
+ }
+}
+// If we're detecting installed add-ons, record the user id and add-on GUID
+// We don't return any updates regardless of their existance when doing this
+elseif ($detect_installed) {
+ $sequence = mysql_real_escape_string($_COOKIE['AMOfbSequence']);
+ $fb_user = mysql_real_escape_string($_COOKIE['AMOfbUser']);
+ $addon_guid = mysql_real_escape_string($_GET['id']);
+ $disabled = ($_GET['status'] == 'userDisabled') ? 1 : 0;
+
+ // Delete any add-ons from a previous detection sequence
+ mysql_query("DELETE FROM facebook_detected WHERE fb_user = '{$fb_user}' AND sequence != '{$sequence}'");
+
+ $insert = mysql_query("INSERT INTO facebook_detected (fb_user, addon_guid, disabled, sequence, created) VALUES ('{$fb_user}', '{$addon_guid}', '{$disabled}', '{$sequence}', NOW())");
+
+ if (!$insert)
+ $errors[] = 'MySQL query to log add-on GUID failed.';
+
+ // We don't want this cached so that real update checks can function properly
+ header('Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0, private');
+ header('Pragma: no-cache');
+}
+
+
+/*
+ * DEBUG
+ *
+ * If we get here, something went wrong. For testing purposes, we can
+ * optionally display errors based on $_GET['debug'].
+ *
+ * By default, no errors are ever displayed because humans do not read this
+ * script.
+ *
+ * Until there is some sort of API for how clients handle errors,
+ * things should remain this way.
+ */
+if (defined('DEV') && $debug == true) {
+ echo '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">';
+ echo '<html lang="en">';
+
+ echo '<head>';
+ echo '<title>VersionCheck.php Debug Information</title>';
+ echo '<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">';
+ echo '</head>';
+
+ echo '<body>';
+
+ echo '<h1>Parameters</h1>';
+ echo '<pre>';
+ $out = array();
+ foreach ($_GET as $key=>$val) {
+ $out[$key] = strip_tags(htmlentities($val));
+ }
+ print_r($out);
+ echo '</pre>';
+
+ if (!empty($query)) {
+ echo '<h1>Query</h1>';
+ echo '<pre>';
+ echo strip_tags(htmlentities($id_query));
+ echo '<br />';
+ echo strip_tags(htmlentities($query));
+ echo '</pre>';
+ }
+
+ if (!empty($data)) {
+ echo '<h1>Result</h1>';
+ echo '<pre>';
+ foreach ($data as $key=>$val) {
+ $data_esc[$key] = strip_tags(htmlentities($val));
+ }
+ print_r($data_esc);
+ echo '</pre>';
+ }
+
+ if (!empty($errors) && is_array($errors)) {
+ echo '<h1>Errors Found</h1>';
+ echo '<pre>';
+ foreach ($errors as $key=>$val) {
+ $errors_esc[$key] = strip_tags(htmlentities($val));
+ }
+ print_r($errors_esc);
+ echo '</pre>';
+ } else {
+ echo '<h1>No Errors Found</h1>';
+ }
+
+ echo '</body>';
+
+ echo '</html>';
+ exit;
+}
+
+
+
+/**
+ * OUTPUT
+ *
+ * Generate our XML output. We are assuming that we did not have to echo debug information.
+ *
+ * We will encode using UTF-8 for all update metadata, and display an empty XML document if there were no updates found.
+ */
+header('Cache-Control: public, max-age=3600');
+header('Last-modified: ' . gmdate("D, j M Y H:i:s", time()) . " GMT");
+header('Expires: ' . gmdate("D, j M Y H:i:s", time() + 3600) . " GMT");
+header('Content-type: text/xml');
+
+echo <<<XMLHEADER
+<?xml version="1.0"?>
+<RDF:RDF xmlns:RDF="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:em="http://www.mozilla.org/2004/em-rdf#">
+XMLHEADER;
+
+// If have our update array, encode it then display the XML for the update.
+if (isset($data) && is_array($data) && !empty($data)) {
+
+foreach ($data as $key=>$val) {
+ $update[$key]=htmlentities($val,ENT_QUOTES,'UTF-8');
+}
+
+$hash = '';
+if (!empty($update['hash'])) {
+ $hash = "<em:updateHash>{$update['hash']}</em:updateHash>";
+}
+
+$updateInfoURL = '';
+if (!empty($update['releasenotes'])) {
+ /**
+ * The locale is included as an additional parameter so that if the Firefox
+ * locale is not supported by AMO, there's not a 404
+ */
+ $updateInfoURL = "<em:updateInfoURL>".SITE_URL."/versions/updateInfo/{$update['version_id']}/%APP_LOCALE%/</em:updateInfoURL>";
+}
+
+echo <<<XMLBODY
+<RDF:Description about="urn:mozilla:{$update['type']}:{$update['guid']}">
+ <em:updates>
+ <RDF:Seq>
+ <RDF:li resource="urn:mozilla:{$update['type']}:{$update['guid']}:{$update['version']}"/>
+ </RDF:Seq>
+ </em:updates>
+</RDF:Description>
+
+<RDF:Description about="urn:mozilla:{$update['type']}:{$update['guid']}:{$update['version']}">
+ <em:version>{$update['version']}</em:version>
+ <em:targetApplication>
+ <RDF:Description>
+ <em:id>{$update['appguid']}</em:id>
+ <em:minVersion>{$update['min']}</em:minVersion>
+ <em:maxVersion>{$update['max']}</em:maxVersion>
+ <em:updateLink>{$update['uri']}</em:updateLink>
+ {$updateInfoURL}
+ {$hash}
+ </RDF:Description>
+ </em:targetApplication>
+</RDF:Description>
+XMLBODY;
+
+}
+
+echo <<<XMLFOOTER
+</RDF:RDF>
+XMLFOOTER;
+?>
diff --git a/site/cake/LICENSE.txt b/site/cake/LICENSE.txt
new file mode 100644
index 0000000..4787242
--- /dev/null
+++ b/site/cake/LICENSE.txt
@@ -0,0 +1,24 @@
+The MIT License
+
+CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
+Copyright 2005-2007, Cake Software Foundation, Inc.
+ 1785 E. Sahara Avenue, Suite 490-204
+ Las Vegas, Nevada 89104
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE. \ No newline at end of file
diff --git a/site/cake/VERSION.txt b/site/cake/VERSION.txt
new file mode 100644
index 0000000..4f47b75
--- /dev/null
+++ b/site/cake/VERSION.txt
@@ -0,0 +1,9 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////////////
+// +---------------------------------------------------------------------------------------------------+ //
+// + $Id: VERSION.txt 6305 2008-01-02 02:33:56Z phpnut $
+// + Last Modified: $Date: 2008-01-01 20:33:56 -0600 (Tue, 01 Jan 2008) $
+// + Modified By: $LastChangedBy: phpnut $
+// +---------------------------------------------------------------------------------------------------+ //
+///////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+1.1.19.6305 \ No newline at end of file
diff --git a/site/cake/app_controller.php b/site/cake/app_controller.php
new file mode 100644
index 0000000..82ef51f
--- /dev/null
+++ b/site/cake/app_controller.php
@@ -0,0 +1,42 @@
+<?php
+/* SVN FILE: $Id: app_controller.php 6305 2008-01-02 02:33:56Z phpnut $ */
+/**
+ * Short description for file.
+ *
+ * This file is application-wide controller file. You can put all
+ * application-wide controller-related methods here.
+ *
+ * PHP versions 4 and 5
+ *
+ * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
+ * Copyright 2005-2008, Cake Software Foundation, Inc.
+ * 1785 E. Sahara Avenue, Suite 490-204
+ * Las Vegas, Nevada 89104
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
+ * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
+ * @package cake
+ * @subpackage cake.cake
+ * @since CakePHP(tm) v 0.2.9
+ * @version $Revision: 6305 $
+ * @modifiedby $LastChangedBy: phpnut $
+ * @lastmodified $Date: 2008-01-01 20:33:56 -0600 (Tue, 01 Jan 2008) $
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+/**
+ * This is a placeholder class.
+ * Create the same file in app/app_controller.php
+ *
+ * Add your application-wide methods in the class below, your controllers
+ * will inherit them.
+ *
+ * @package cake
+ * @subpackage cake.cake
+ */
+class AppController extends Controller {
+}
+?> \ No newline at end of file
diff --git a/site/cake/app_model.php b/site/cake/app_model.php
new file mode 100644
index 0000000..e605856
--- /dev/null
+++ b/site/cake/app_model.php
@@ -0,0 +1,42 @@
+<?php
+/* SVN FILE: $Id: app_model.php 6305 2008-01-02 02:33:56Z phpnut $ */
+/**
+ * Application model for Cake.
+ *
+ * This file is application-wide model file. You can put all
+ * application-wide model-related methods here.
+ *
+ * PHP versions 4 and 5
+ *
+ * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
+ * Copyright 2005-2008, Cake Software Foundation, Inc.
+ * 1785 E. Sahara Avenue, Suite 490-204
+ * Las Vegas, Nevada 89104
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
+ * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
+ * @package cake
+ * @subpackage cake.cake
+ * @since CakePHP(tm) v 0.2.9
+ * @version $Revision: 6305 $
+ * @modifiedby $LastChangedBy: phpnut $
+ * @lastmodified $Date: 2008-01-01 20:33:56 -0600 (Tue, 01 Jan 2008) $
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+/**
+ * Application model for Cake.
+ *
+ * This is a placeholder class.
+ * Create the same file in app/app_model.php
+ * Add your application-wide methods to the class, your models will inherit them.
+ *
+ * @package cake
+ * @subpackage cake.cake
+ */
+class AppModel extends Model {
+}
+?> \ No newline at end of file
diff --git a/site/cake/basics.php b/site/cake/basics.php
new file mode 100644
index 0000000..fc96c39
--- /dev/null
+++ b/site/cake/basics.php
@@ -0,0 +1,1169 @@
+<?php
+/* SVN FILE: $Id: basics.php 6305 2008-01-02 02:33:56Z phpnut $ */
+/**
+ * Basic Cake functionality.
+ *
+ * Core functions for including other source files, loading models and so forth.
+ *
+ * PHP versions 4 and 5
+ *
+ * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
+ * Copyright 2005-2008, Cake Software Foundation, Inc.
+ * 1785 E. Sahara Avenue, Suite 490-204
+ * Las Vegas, Nevada 89104
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
+ * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
+ * @package cake
+ * @subpackage cake.cake
+ * @since CakePHP(tm) v 0.2.9
+ * @version $Revision: 6305 $
+ * @modifiedby $LastChangedBy: phpnut $
+ * @lastmodified $Date: 2008-01-01 20:33:56 -0600 (Tue, 01 Jan 2008) $
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+/**
+ * Basic defines for timing functions.
+ */
+ define('SECOND', 1);
+ define('MINUTE', 60 * SECOND);
+ define('HOUR', 60 * MINUTE);
+ define('DAY', 24 * HOUR);
+ define('WEEK', 7 * DAY);
+ define('MONTH', 30 * DAY);
+ define('YEAR', 365 * DAY);
+/**
+ * Patch for PHP < 4.3
+ */
+ if (!function_exists("ob_get_clean")) {
+ function ob_get_clean() {
+ $ob_contents = ob_get_contents();
+ ob_end_clean();
+ return $ob_contents;
+ }
+ }
+/**
+ * Patch for PHP < 4.3
+ */
+ if (version_compare(phpversion(), '5.0') < 0) {
+ eval ('
+ function clone($object) {
+ return $object;
+ }');
+ }
+/**
+ * Computes the difference of arrays using keys for comparison
+ *
+ * @param array
+ * @param array
+ * @return array
+ */
+ if (!function_exists('array_diff_key')) {
+ function array_diff_key() {
+ $valuesDiff = array();
+
+ if (func_num_args() < 2) {
+ return false;
+ }
+
+ foreach (func_get_args() as $param) {
+ if (!is_array($param)) {
+ return false;
+ }
+ }
+
+ $args = func_get_args();
+ foreach ($args[0] as $valueKey => $valueData) {
+ for ($i = 1; $i < func_num_args(); $i++) {
+ if (isset($args[$i][$valueKey])) {
+ continue 2;
+ }
+ }
+ $valuesDiff[$valueKey] = $valueData;
+ }
+ return $valuesDiff;
+ }
+ }
+/**
+ * Computes the intersection of arrays using keys for comparison
+ *
+ * @param array
+ * @param array
+ * @return array
+ */
+ if (!function_exists('array_intersect_key')) {
+ function array_intersect_key($arr1, $arr2) {
+ $res = array();
+ foreach ($arr1 as $key=>$value) {
+ if (array_key_exists($key, $arr2)) {
+ $res[$key] = $arr1[$key];
+ }
+ }
+ return $res;
+ }
+ }
+/**
+ * Loads all models.
+ */
+ function loadModels() {
+ if (!class_exists('Model')) {
+ require LIBS . 'model' . DS . 'model.php';
+ }
+ $path = Configure::getInstance();
+ if (!class_exists('AppModel')) {
+ if (file_exists(APP . 'app_model.php')) {
+ require(APP . 'app_model.php');
+ } else {
+ require(CAKE . 'app_model.php');
+ }
+ if (phpversion() < 5 && function_exists("overload")) {
+ overload('AppModel');
+ }
+ }
+
+ foreach ($path->modelPaths as $path) {
+ foreach (listClasses($path)as $model_fn) {
+ list($name) = explode('.', $model_fn);
+ $className = Inflector::camelize($name);
+
+ if (!class_exists($className)) {
+ require($path . $model_fn);
+
+ if (phpversion() < 5 && function_exists("overload")) {
+ overload($className);
+ }
+ }
+ }
+ }
+ }
+/**
+ * Loads all plugin models.
+ *
+ * @param string $plugin Name of plugin
+ * @return
+ */
+ function loadPluginModels($plugin) {
+ if (!class_exists('AppModel')) {
+ loadModel();
+ }
+ $pluginAppModel = Inflector::camelize($plugin . '_app_model');
+ $pluginAppModelFile = APP . 'plugins' . DS . $plugin . DS . $plugin . '_app_model.php';
+ if (!class_exists($pluginAppModel)) {
+ if (file_exists($pluginAppModelFile)) {
+ require($pluginAppModelFile);
+ } else {
+ die('Plugins must have a class named ' . $pluginAppModel);
+ }
+ if (phpversion() < 5 && function_exists("overload")) {
+ overload($pluginAppModel);
+ }
+ }
+
+ $pluginModelDir = APP . 'plugins' . DS . $plugin . DS . 'models' . DS;
+
+ foreach (listClasses($pluginModelDir)as $modelFileName) {
+ list($name) = explode('.', $modelFileName);
+ $className = Inflector::camelize($name);
+
+ if (!class_exists($className)) {
+ require($pluginModelDir . $modelFileName);
+
+ if (phpversion() < 5 && function_exists("overload")) {
+ overload($className);
+ }
+ }
+ }
+ }
+/**
+ * Loads custom view class.
+ *
+ */
+ function loadView($viewClass) {
+ if (!class_exists($viewClass . 'View')) {
+ $paths = Configure::getInstance();
+ $file = Inflector::underscore($viewClass) . '.php';
+
+ foreach ($paths->viewPaths as $path) {
+ if (file_exists($path . $file)) {
+ return require($path . $file);
+ }
+ }
+
+ if ($viewFile = fileExistsInPath(LIBS . 'view' . DS . $file)) {
+ if (file_exists($viewFile)) {
+ require($viewFile);
+ return true;
+ } else {
+ return false;
+ }
+ }
+ }
+ }
+/**
+ * Loads a model by CamelCase name.
+ */
+ function loadModel($name = null) {
+ if (!class_exists('Model')) {
+ require LIBS . 'model' . DS . 'model.php';
+ }
+ if (!class_exists('AppModel')) {
+ if (file_exists(APP . 'app_model.php')) {
+ require(APP . 'app_model.php');
+ } else {
+ require(CAKE . 'app_model.php');
+ }
+ if (phpversion() < 5 && function_exists("overload")) {
+ overload('AppModel');
+ }
+ }
+
+ if (!is_null($name) && !class_exists($name)) {
+ $className = $name;
+ $name = Inflector::underscore($name);
+ $paths = Configure::getInstance();
+
+ foreach ($paths->modelPaths as $path) {
+ if (file_exists($path . $name . '.php')) {
+ require($path . $name . '.php');
+ if (phpversion() < 5 && function_exists("overload")) {
+ overload($className);
+ }
+ return true;
+ }
+ }
+ return false;
+ } else {
+ return true;
+ }
+ }
+/**
+ * Loads all controllers.
+ */
+ function loadControllers() {
+ $paths = Configure::getInstance();
+ if (!class_exists('AppController')) {
+ if (file_exists(APP . 'app_controller.php')) {
+ require(APP . 'app_controller.php');
+ } else {
+ require(CAKE . 'app_controller.php');
+ }
+ }
+ $loadedControllers = array();
+
+ foreach ($paths->controllerPaths as $path) {
+ foreach (listClasses($path) as $controller) {
+ list($name) = explode('.', $controller);
+ $className = Inflector::camelize(str_replace('_controller', '', $name));
+
+ if (loadController($className)) {
+ $loadedControllers[$controller] = $className;
+ }
+ }
+ }
+ return $loadedControllers;
+ }
+/**
+ * Loads a controller and its helper libraries.
+ *
+ * @param string $name Name of controller
+ * @return boolean Success
+ */
+ function loadController($name) {
+ $paths = Configure::getInstance();
+ if (!class_exists('AppController')) {
+ if (file_exists(APP . 'app_controller.php')) {
+ require(APP . 'app_controller.php');
+ } else {
+ require(CAKE . 'app_controller.php');
+ }
+ }
+
+ if ($name === null) {
+ return true;
+ }
+
+ if (!class_exists($name . 'Controller')) {
+ $name = Inflector::underscore($name);
+
+ foreach ($paths->controllerPaths as $path) {
+ if (file_exists($path . $name . '_controller.php')) {
+ require($path . $name . '_controller.php');
+ return true;
+ }
+ }
+
+ if ($controller_fn = fileExistsInPath(LIBS . 'controller' . DS . $name . '_controller.php')) {
+ if (file_exists($controller_fn)) {
+ require($controller_fn);
+ return true;
+ } else {
+ return false;
+ }
+ }
+ } else {
+ return false;
+ }
+ }
+/**
+ * Loads a plugin's controller.
+ *
+ * @param string $plugin Name of plugin
+ * @param string $controller Name of controller to load
+ * @return boolean Success
+ */
+ function loadPluginController($plugin, $controller) {
+ $pluginAppController = Inflector::camelize($plugin . '_app_controller');
+ $pluginAppControllerFile = APP . 'plugins' . DS . $plugin . DS . $plugin . '_app_controller.php';
+ if (!class_exists($pluginAppController)) {
+ if (file_exists($pluginAppControllerFile)) {
+ require($pluginAppControllerFile);
+ } else {
+ return false;
+ }
+ }
+
+ if (empty($controller)) {
+ if (!class_exists($plugin . 'Controller')) {
+ if (file_exists(APP . 'plugins' . DS . $plugin . DS . 'controllers' . DS . $plugin . '_controller.php')) {
+ require(APP . 'plugins' . DS . $plugin . DS . 'controllers' . DS . $plugin . '_controller.php');
+ return true;
+ }
+ }
+ }
+
+ if (!class_exists($controller . 'Controller')) {
+ $controller = Inflector::underscore($controller);
+ $file = APP . 'plugins' . DS . $plugin . DS . 'controllers' . DS . $controller . '_controller.php';
+
+ if (file_exists($file)) {
+ require($file);
+ return true;
+ } elseif (!class_exists(Inflector::camelize($plugin . '_controller'))) {
+ if (file_exists(APP . 'plugins' . DS . $plugin . DS . 'controllers' . DS . $plugin . '_controller.php')) {
+ require(APP . 'plugins' . DS . $plugin . DS . 'controllers' . DS . $plugin . '_controller.php');
+ return true;
+ } else {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+/**
+ * Loads a helper
+ *
+ * @param string $name Name of helper
+ * @return boolean Success
+ */
+ function loadHelper($name) {
+ $paths = Configure::getInstance();
+
+ if ($name === null) {
+ return true;
+ }
+
+ if (!class_exists($name . 'Helper')) {
+ $name=Inflector::underscore($name);
+
+ foreach ($paths->helperPaths as $path) {
+ if (file_exists($path . $name . '.php')) {
+ require($path . $name . '.php');
+ return true;
+ }
+ }
+
+ if ($helper_fn = fileExistsInPath(LIBS . 'view' . DS . 'helpers' . DS . $name . '.php')) {
+ if (file_exists($helper_fn)) {
+ require($helper_fn);
+ return true;
+ } else {
+ return false;
+ }
+ }
+ } else {
+ return true;
+ }
+ }
+/**
+ * Loads a plugin's helper
+ *
+ * @param string $plugin Name of plugin
+ * @param string $helper Name of helper to load
+ * @return boolean Success
+ */
+ function loadPluginHelper($plugin, $helper) {
+ if (!class_exists($helper . 'Helper')) {
+ $helper = Inflector::underscore($helper);
+ $file = APP . 'plugins' . DS . $plugin . DS . 'views' . DS . 'helpers' . DS . $helper . '.php';
+ if (file_exists($file)) {
+ require($file);
+ return true;
+ } else {
+ return false;
+ }
+ } else {
+ return true;
+ }
+ }
+/**
+ * Loads a component
+ *
+ * @param string $name Name of component
+ * @return boolean Success
+ */
+ function loadComponent($name) {
+ $paths = Configure::getInstance();
+
+ if ($name === null) {
+ return true;
+ }
+
+ if (!class_exists($name . 'Component')) {
+ $name=Inflector::underscore($name);
+
+ foreach ($paths->componentPaths as $path) {
+ if (file_exists($path . $name . '.php')) {
+ require($path . $name . '.php');
+ return true;
+ }
+ }
+
+ if ($component_fn = fileExistsInPath(LIBS . 'controller' . DS . 'components' . DS . $name . '.php')) {
+ if (file_exists($component_fn)) {
+ require($component_fn);
+ return true;
+ } else {
+ return false;
+ }
+ }
+ } else {
+ return true;
+ }
+ }
+/**
+ * Loads a plugin's component
+ *
+ * @param string $plugin Name of plugin
+ * @param string $helper Name of component to load
+ * @return boolean Success
+ */
+ function loadPluginComponent($plugin, $component) {
+ if (!class_exists($component . 'Component')) {
+ $component = Inflector::underscore($component);
+ $file = APP . 'plugins' . DS . $plugin . DS . 'controllers' . DS . 'components' . DS . $component . '.php';
+ if (file_exists($file)) {
+ require($file);
+ return true;
+ } else {
+ return false;
+ }
+ } else {
+ return true;
+ }
+ }
+/**
+ * Returns an array of filenames of PHP files in given directory.
+ *
+ * @param string $path Path to scan for files
+ * @return array List of files in directory
+ */
+ function listClasses($path) {
+ $dir = opendir($path);
+ $classes=array();
+ while (false !== ($file = readdir($dir))) {
+ if ((substr($file, -3, 3) == 'php') && substr($file, 0, 1) != '.') {
+ $classes[] = $file;
+ }
+ }
+ closedir($dir);
+ return $classes;
+ }
+/**
+ * Loads configuration files
+ *
+ * @return boolean Success
+ */
+ function config() {
+ $args = func_get_args();
+ foreach ($args as $arg) {
+ if (('database' == $arg) && file_exists(CONFIGS . $arg . '.php')) {
+ include_once(CONFIGS . $arg . '.php');
+ } elseif (file_exists(CONFIGS . $arg . '.php')) {
+ include_once(CONFIGS . $arg . '.php');
+
+ if (count($args) == 1) {
+ return true;
+ }
+ } else {
+ if (count($args) == 1) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+/**
+ * Loads component/components from LIBS.
+ *
+ * Example:
+ * <code>
+ * uses('flay', 'time');
+ * </code>
+ *
+ * @uses LIBS
+ */
+ function uses() {
+ $args = func_get_args();
+ foreach ($args as $arg) {
+ require_once(LIBS . strtolower($arg) . '.php');
+ }
+ }
+/**
+ * Require given files in the VENDORS directory. Takes optional number of parameters.
+ *
+ * @param string $name Filename without the .php part.
+ *
+ */
+ function vendor($name) {
+ $args = func_get_args();
+ foreach ($args as $arg) {
+ if (file_exists(APP . 'vendors' . DS . $arg . '.php')) {
+ require_once(APP . 'vendors' . DS . $arg . '.php');
+ } else {
+ require_once(VENDORS . $arg . '.php');
+ }
+ }
+ }
+/**
+ * Prints out debug information about given variable.
+ *
+ * Only runs if DEBUG level is non-zero.
+ *
+ * @param boolean $var Variable to show debug information for.
+ * @param boolean $show_html If set to true, the method prints the debug data in a screen-friendly way.
+ */
+ function debug($var = false, $showHtml = false) {
+ if (Configure::read() > 0) {
+ print "\n<pre class=\"cake_debug\">\n";
+ ob_start();
+ print_r($var);
+ $var = ob_get_clean();
+
+ if ($showHtml) {
+ $var = str_replace('<', '&lt;', str_replace('>', '&gt;', $var));
+ }
+ print "{$var}\n</pre>\n";
+ }
+ }
+/**
+ * Returns microtime for execution time checking
+ *
+ * @return integer
+ */
+ if (!function_exists('getMicrotime')) {
+ function getMicrotime() {
+ list($usec, $sec) = explode(" ", microtime());
+ return ((float)$usec + (float)$sec);
+ }
+ }
+/**
+ * Sorts given $array by key $sortby.
+ *
+ * @param array $array
+ * @param string $sortby
+ * @param string $order Sort order asc/desc (ascending or descending).
+ * @param integer $type
+ * @return mixed
+ */
+ if (!function_exists('sortByKey')) {
+ function sortByKey(&$array, $sortby, $order = 'asc', $type = SORT_NUMERIC) {
+ if (!is_array($array)) {
+ return null;
+ }
+
+ foreach ($array as $key => $val) {
+ $sa[$key] = $val[$sortby];
+ }
+
+ if ($order == 'asc') {
+ asort($sa, $type);
+ } else {
+ arsort($sa, $type);
+ }
+
+ foreach ($sa as $key => $val) {
+ $out[] = $array[$key];
+ }
+ return $out;
+ }
+ }
+/**
+ * Combines given identical arrays by using the first array's values as keys,
+ * and the second one's values as values. (Implemented for back-compatibility with PHP4)
+ *
+ * @param array $a1
+ * @param array $a2
+ * @return mixed Outputs either combined array or false.
+ */
+ if (!function_exists('array_combine')) {
+ function array_combine($a1, $a2) {
+ $a1 = array_values($a1);
+ $a2 = array_values($a2);
+ $c1 = count($a1);
+ $c2 = count($a2);
+
+ if ($c1 != $c2) {
+ return false;
+ }
+ if ($c1 <= 0) {
+ return false;
+ }
+
+ $output=array();
+ for ($i = 0; $i < $c1; $i++) {
+ $output[$a1[$i]] = $a2[$i];
+ }
+ return $output;
+ }
+ }
+/**
+ * Convenience method for htmlspecialchars.
+ *
+ * @param string $text
+ * @return string
+ */
+ function h($text) {
+ if (is_array($text)) {
+ return array_map('h', $text);
+ }
+ return htmlspecialchars($text);
+ }
+/**
+ * Returns an array of all the given parameters.
+ *
+ * Example:
+ * <code>
+ * a('a', 'b')
+ * </code>
+ *
+ * Would return:
+ * <code>
+ * array('a', 'b')
+ * </code>
+ *
+ * @return array
+ */
+ function a() {
+ $args = func_get_args();
+ return $args;
+ }
+/**
+ * Constructs associative array from pairs of arguments.
+ *
+ * Example:
+ * <code>
+ * aa('a','b')
+ * </code>
+ *
+ * Would return:
+ * <code>
+ * array('a'=>'b')
+ * </code>
+ *
+ * @return array
+ */
+ function aa() {
+ $args = func_get_args();
+ for ($l = 0, $c = count($args); $l < $c; $l++) {
+ if ($l + 1 < count($args)) {
+ $a[$args[$l]] = $args[$l + 1];
+ } else {
+ $a[$args[$l]] = null;
+ }
+ $l++;
+ }
+ return $a;
+ }
+/**
+ * Convenience method for echo().
+ *
+ * @param string $text String to echo
+ */
+ function e($text) {
+ echo $text;
+ }
+/**
+ * Convenience method for strtolower().
+ *
+ * @param string $str String to lowercase
+ */
+ function low($str) {
+ return strtolower($str);
+ }
+/**
+ * Convenience method for strtoupper().
+ *
+ * @param string $str String to uppercase
+ */
+ function up($str) {
+ return strtoupper($str);
+ }
+/**
+ * Convenience method for str_replace().
+ *
+ * @param string $search String to be replaced
+ * @param string $replace String to insert
+ * @param string $subject String to search
+ */
+ function r($search, $replace, $subject) {
+ return str_replace($search, $replace, $subject);
+ }
+/**
+ * Print_r convenience function, which prints out <PRE> tags around
+ * the output of given array. Similar to debug().
+ *
+ * @see debug()
+ * @param array $var
+ */
+ function pr($var) {
+ if (Configure::read() > 0) {
+ echo "<pre>";
+ print_r($var);
+ echo "</pre>";
+ }
+ }
+/**
+ * Display parameter
+ *
+ * @param mixed $p Parameter as string or array
+ * @return string
+ */
+ function params($p) {
+ if (!is_array($p) || count($p) == 0) {
+ return null;
+ } else {
+ if (is_array($p[0]) && count($p) == 1) {
+ return $p[0];
+ } else {
+ return $p;
+ }
+ }
+ }
+/**
+ * Merge a group of arrays
+ *
+ * @param array First array
+ * @param array Second array
+ * @param array Third array
+ * @param array Etc...
+ * @return array All array parameters merged into one
+ */
+ function am() {
+ $r = array();
+ foreach (func_get_args()as $a) {
+ if (!is_array($a)) {
+ $a = array($a);
+ }
+ $r = array_merge($r, $a);
+ }
+ return $r;
+ }
+/**
+ * Returns the REQUEST_URI from the server environment, or, failing that,
+ * constructs a new one, using the PHP_SELF constant and other variables.
+ *
+ * @return string URI
+ */
+ function setUri() {
+ if (env('HTTP_X_REWRITE_URL')) {
+ $uri = env('HTTP_X_REWRITE_URL');
+ } elseif (env('REQUEST_URI')) {
+ $uri = env('REQUEST_URI');
+ } else {
+ if (env('argv')) {
+ $uri = env('argv');
+
+ if (defined('SERVER_IIS')) {
+ $uri = BASE_URL . $uri[0];
+ } else {
+ $uri = env('PHP_SELF') . '/' . $uri[0];
+ }
+ } else {
+ $uri = env('PHP_SELF') . '/' . env('QUERY_STRING');
+ }
+ }
+ return $uri;
+ }
+/**
+ * Gets an environment variable from available sources.
+ * Used as a backup if $_SERVER/$_ENV are disabled.
+ *
+ * @param string $key Environment variable name.
+ * @return string Environment variable setting.
+ */
+ function env($key) {
+
+ if ($key == 'HTTPS') {
+ if (isset($_SERVER) && !empty($_SERVER)) {
+ return (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on');
+ } else {
+ return (strpos(env('SCRIPT_URI'), 'https://') === 0);
+ }
+ }
+
+ if (isset($_SERVER[$key])) {
+ return $_SERVER[$key];
+ } elseif (isset($_ENV[$key])) {
+ return $_ENV[$key];
+ } elseif (getenv($key) !== false) {
+ return getenv($key);
+ }
+
+ if ($key == 'SCRIPT_FILENAME' && defined('SERVER_IIS') && SERVER_IIS === true) {
+ return str_replace('\\\\', '\\', env('PATH_TRANSLATED') );
+ }
+
+ if ($key == 'DOCUMENT_ROOT') {
+ $offset = 0;
+ if (!strpos(env('SCRIPT_NAME'), '.php')) {
+ $offset = 4;
+ }
+ return substr(env('SCRIPT_FILENAME'), 0, strlen(env('SCRIPT_FILENAME')) - (strlen(env('SCRIPT_NAME')) + $offset));
+ }
+ if ($key == 'PHP_SELF') {
+ return r(env('DOCUMENT_ROOT'), '', env('SCRIPT_FILENAME'));
+ }
+ return null;
+ }
+/**
+ * Returns contents of a file as a string.
+ *
+ * @param string $fileName Name of the file.
+ * @param boolean $useIncludePath Wheter the function should use the include path or not.
+ * @return mixed Boolean false or contents of required file.
+ */
+ if (!function_exists('file_get_contents')) {
+ function file_get_contents($fileName, $useIncludePath = false) {
+ $res=fopen($fileName, 'rb', $useIncludePath);
+
+ if ($res === false) {
+ trigger_error('file_get_contents() failed to open stream: No such file or directory', E_USER_WARNING);
+ return false;
+ }
+ clearstatcache();
+
+ if ($fileSize = @filesize($fileName)) {
+ $data = fread($res, $fileSize);
+ } else {
+ $data = '';
+
+ while (!feof($res)) {
+ $data .= fread($res, 8192);
+ }
+ }
+ return "$data\n";
+ }
+ }
+/**
+ * Writes data into file.
+ *
+ * If file exists, it will be overwritten. If data is an array, it will be join()ed with an empty string.
+ *
+ * @param string $fileName File name.
+ * @param mixed $data String or array.
+ */
+ if (!function_exists('file_put_contents')) {
+ function file_put_contents($fileName, $data) {
+ if (is_array($data)) {
+ $data = join('', $data);
+ }
+ $res = @fopen($fileName, 'w+b');
+ if ($res) {
+ $write = @fwrite($res, $data);
+ if ($write === false) {
+ return false;
+ } else {
+ return $write;
+ }
+ }
+ }
+ }
+/**
+ * Reads/writes temporary data to cache files or session.
+ *
+ * @param string $path File path within /tmp to save the file.
+ * @param mixed $data The data to save to the temporary file.
+ * @param mixed $expires A valid strtotime string when the data expires.
+ * @param string $target The target of the cached data; either 'cache' or 'public'.
+ * @return mixed The contents of the temporary file.
+ */
+ function cache($path, $data = null, $expires = '+1 day', $target = 'cache') {
+ $now = time();
+ if (!is_numeric($expires)) {
+ $expires = strtotime($expires, $now);
+ }
+
+ switch(strtolower($target)) {
+ case 'cache':
+ $filename = CACHE . $path;
+ break;
+ case 'public':
+ $filename = WWW_ROOT . $path;
+ break;
+ }
+
+ $timediff = $expires - $now;
+ $filetime = false;
+ if (file_exists($filename)) {
+ $filetime = @filemtime($filename);
+ }
+
+ if ($data === null) {
+ // Read data from file
+ if (file_exists($filename) && $filetime !== false) {
+ if ($filetime + $timediff < $now) {
+ // File has expired
+ @unlink($filename);
+ } else {
+ $data = file_get_contents($filename);
+ }
+ }
+ } else {
+ file_put_contents($filename, $data);
+ }
+ return $data;
+ }
+/**
+ * Used to delete files in the cache directories, or clear contents of cache directories
+ *
+ * @param mixed $params As String name to be searched for deletion, if name is a directory all files in directory will be deleted.
+ * If array, names to be searched for deletion.
+ * If clearCache() without params, all files in app/tmp/cache/views will be deleted
+ *
+ * @param string $type Directory in tmp/cache defaults to view directory
+ * @param string $ext The file extension you are deleting
+ * @return true if files found and deleted false otherwise
+ */
+ function clearCache($params = null, $type = 'views', $ext = '.php') {
+ if (is_string($params) || $params === null) {
+ $params = preg_replace('/\/\//', '/', $params);
+ $cache = CACHE . $type . DS . $params;
+
+ if (is_file($cache . $ext)) {
+ @unlink($cache . $ext);
+ return true;
+ } elseif (is_dir($cache)) {
+ $files = glob("$cache*");
+
+ if ($files === false) {
+ return false;
+ }
+
+ foreach ($files as $file) {
+ if (is_file($file)) {
+ @unlink($file);
+ }
+ }
+ return true;
+ } else {
+ $cache = CACHE . $type . DS . '*' . $params . '*' . $ext;
+ $files = glob($cache);
+
+ if ($files === false) {
+ return false;
+ }
+ foreach ($files as $file) {
+ if (is_file($file)) {
+ @unlink($file);
+ }
+ }
+ return true;
+ }
+ } elseif (is_array($params)) {
+ foreach ($params as $key => $file) {
+ $file = preg_replace('/\/\//', '/', $file);
+ $cache = CACHE . $type . DS . '*' . $file . '*' . $ext;
+ $files[] = glob($cache);
+ }
+
+ if (!empty($files)) {
+ foreach ($files as $key => $delete) {
+ if (is_array($delete)) {
+ foreach ($delete as $file) {
+ if (is_file($file)) {
+ @unlink($file);
+ }
+ }
+ }
+ }
+ return true;
+ } else {
+ return false;
+ }
+ } else {
+ return false;
+ }
+ }
+/**
+ * Recursively strips slashes from all values in an array
+ *
+ * @param unknown_type $value
+ * @return unknown
+ */
+ function stripslashes_deep($value) {
+ if (is_array($value)) {
+ $return = array_map('stripslashes_deep', $value);
+ return $return;
+ } else {
+ $return = stripslashes($value);
+ return $return ;
+ }
+ }
+/**
+ * Returns a translated string if one is found,
+ * or the submitted message if not found.
+ *
+ * @param unknown_type $msg
+ * @param unknown_type $return
+ * @return unknown
+ * @todo Not implemented fully till 2.0
+ */
+ function __($msg, $return = null) {
+ if (is_null($return)) {
+ echo($msg);
+ } else {
+ return $msg;
+ }
+ }
+/**
+ * Counts the dimensions of an array
+ *
+ * @param array $array
+ * @return int The number of dimensions in $array
+ */
+ function countdim($array) {
+ if (is_array(reset($array))) {
+ $return = countdim(reset($array)) + 1;
+ } else {
+ $return = 1;
+ }
+ return $return;
+ }
+/**
+ * Shortcut to Log::write.
+ */
+ function LogError($message) {
+ if (!class_exists('CakeLog')) {
+ uses('cake_log');
+ }
+ $bad = array("\n", "\r", "\t");
+ $good = ' ';
+ CakeLog::write('error', str_replace($bad, $good, $message));
+ }
+/**
+ * Searches include path for files
+ *
+ * @param string $file
+ * @return Full path to file if exists, otherwise false
+ */
+ function fileExistsInPath($file) {
+ $paths = explode(PATH_SEPARATOR, ini_get('include_path'));
+ foreach ($paths as $path) {
+ $fullPath = $path . DIRECTORY_SEPARATOR . $file;
+
+ if (file_exists($fullPath)) {
+ return $fullPath;
+ } elseif (file_exists($file)) {
+ return $file;
+ }
+ }
+ return false;
+ }
+/**
+ * Convert forward slashes to underscores and removes first and last underscores in a string
+ *
+ * @param string
+ * @return string with underscore remove from start and end of string
+ */
+ function convertSlash($string) {
+ $string = trim($string,"/");
+ $string = preg_replace('/\/\//', '/', $string);
+ $string = str_replace('/', '_', $string);
+ return $string;
+ }
+
+/**
+ * chmod recursively on a directory
+ *
+ * @param string $path
+ * @param int $mode
+ * @return boolean
+ */
+ function chmodr($path, $mode = 0755) {
+ if (!is_dir($path)) {
+ return chmod($path, $mode);
+ }
+ $dir = opendir($path);
+
+ while ($file = readdir($dir)) {
+ if ($file != '.' && $file != '..') {
+ $fullpath = $path . '/' . $file;
+
+ if (!is_dir($fullpath)) {
+ if (!chmod($fullpath, $mode)) {
+ return false;
+ }
+ } else {
+ if (!chmodr($fullpath, $mode)) {
+ return false;
+ }
+ }
+ }
+ }
+ closedir($dir);
+
+ if (chmod($path, $mode)) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+/**
+ * removed the plugin name from the base url
+ *
+ * @param string $base
+ * @param string $plugin
+ * @return base url with plugin name removed if present
+ */
+ function strip_plugin($base, $plugin) {
+ if ($plugin != null) {
+ $base = preg_replace('/' . $plugin . '/', '', $base);
+ $base = str_replace('//', '', $base);
+ $pos1 = strrpos($base, '/');
+ $char = strlen($base) - 1;
+
+ if ($pos1 == $char) {
+ $base = substr($base, 0, $char);
+ }
+ }
+ return $base;
+ }
+/**
+ * Wraps ternary operations. If $condition is a non-empty value, $val1 is returned, otherwise $val2.
+ *
+ * @param mixed $condition Conditional expression
+ * @param mixed $val1
+ * @param mixed $val2
+ * @return mixed $val1 or $val2, depending on whether $condition evaluates to a non-empty expression.
+ */
+ function ife($condition, $val1 = null, $val2 = null) {
+ if (!empty($condition)) {
+ return $val1;
+ }
+ return $val2;
+ }
+?> \ No newline at end of file
diff --git a/site/cake/bootstrap.php b/site/cake/bootstrap.php
new file mode 100644
index 0000000..9932324
--- /dev/null
+++ b/site/cake/bootstrap.php
@@ -0,0 +1,104 @@
+<?php
+/* SVN FILE: $Id: bootstrap.php 6305 2008-01-02 02:33:56Z phpnut $ */
+/**
+ * Basic Cake functionality.
+ *
+ * Core functions for including other source files, loading models and so forth.
+ *
+ * PHP versions 4 and 5
+ *
+ * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
+ * Copyright 2005-2008, Cake Software Foundation, Inc.
+ * 1785 E. Sahara Avenue, Suite 490-204
+ * Las Vegas, Nevada 89104
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
+ * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
+ * @package cake
+ * @subpackage cake.cake
+ * @since CakePHP(tm) v 0.2.9
+ * @version $Revision: 6305 $
+ * @modifiedby $LastChangedBy: phpnut $
+ * @lastmodified $Date: 2008-01-01 20:33:56 -0600 (Tue, 01 Jan 2008) $
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+/**
+ * Configuration, directory layout and standard libraries
+ */
+ if (!isset($bootstrap)) {
+ require CORE_PATH . 'cake' . DS . 'basics.php';
+ require APP_PATH . 'config' . DS . 'core.php';
+ require CORE_PATH . 'cake' . DS . 'config' . DS . 'paths.php';
+ }
+ $TIME_START = getMicrotime();
+ require LIBS . 'object.php';
+ require LIBS . 'session.php';
+ require LIBS . 'security.php';
+ require LIBS . 'inflector.php';
+ require LIBS . 'configure.php';
+ $paths = Configure::getInstance();
+/**
+ * Enter description here...
+ */
+ if (empty($uri) && defined('BASE_URL')) {
+ $uri = setUri();
+
+ if ($uri === '/' || $uri === '/index.php' || $uri === '/'.APP_DIR.'/') {
+ $_GET['url'] = '/';
+ $url = '/';
+ } else {
+ if (strpos($uri, 'index.php') !== false) {
+ $uri = r('?', '', $uri);
+ $elements=explode('/index.php', $uri);
+ } else {
+ $elements = explode('/?', $uri);
+ }
+
+ if (!empty($elements[1])) {
+ $_GET['url'] = $elements[1];
+ $url = $elements[1];
+ } else {
+ $_GET['url'] = '/';
+ $url = '/';
+ }
+ }
+ } else {
+ if (empty($_GET['url'])) {
+ $url = null;
+ } else {
+ $url = $_GET['url'];
+ }
+ }
+
+ if (strpos($url, 'ccss/') === 0) {
+ include WWW_ROOT . DS . 'css.php';
+ die();
+ }
+
+ Configure::write('debug', DEBUG);
+
+ require CAKE . 'dispatcher.php';
+
+ if (defined('CACHE_CHECK') && CACHE_CHECK === true) {
+ if (empty($uri)) {
+ $uri = setUri();
+ }
+ $filename=CACHE . 'views' . DS . convertSlash($uri) . '.php';
+
+ if (file_exists($filename)) {
+ uses(DS . 'controller' . DS . 'component', DS . 'view' . DS . 'view');
+ $v = null;
+ $view = new View($v);
+ $view->renderCache($filename, $TIME_START);
+ } elseif (file_exists(CACHE . 'views' . DS . convertSlash($uri) . '_index.php')) {
+ uses(DS . 'controller' . DS . 'component', DS . 'view' . DS . 'view');
+ $v = null;
+ $view = new View($v);
+ $view->renderCache(CACHE . 'views' . DS . convertSlash($uri) . '_index.php', $TIME_START);
+ }
+ }
+?> \ No newline at end of file
diff --git a/site/cake/config/config.php b/site/cake/config/config.php
new file mode 100644
index 0000000..4e0af37
--- /dev/null
+++ b/site/cake/config/config.php
@@ -0,0 +1,28 @@
+<?php
+/* SVN FILE: $Id: config.php 6305 2008-01-02 02:33:56Z phpnut $ */
+/**
+ * Core Configurations.
+ *
+ * PHP versions 4 and 5
+ *
+ * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
+ * Copyright 2005-2008, Cake Software Foundation, Inc.
+ * 1785 E. Sahara Avenue, Suite 490-204
+ * Las Vegas, Nevada 89104
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
+ * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
+ * @package cake
+ * @subpackage cake.app.config
+ * @since CakePHP(tm) v 1.1.11.4062
+ * @version $Revision: 6305 $
+ * @modifiedby $LastChangedBy: phpnut $
+ * @lastmodified $Date: 2008-01-01 20:33:56 -0600 (Tue, 01 Jan 2008) $
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+$config['Cake.version'] = '1.1.19.6305';
+?> \ No newline at end of file
diff --git a/site/cake/config/paths.php b/site/cake/config/paths.php
new file mode 100644
index 0000000..740c4f2
--- /dev/null
+++ b/site/cake/config/paths.php
@@ -0,0 +1,175 @@
+<?php
+/* SVN FILE: $Id: paths.php 6305 2008-01-02 02:33:56Z phpnut $ */
+/**
+ * Short description for file.
+ *
+ * In this file you set paths to different directories used by Cake.
+ *
+ * PHP versions 4 and 5
+ *
+ * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
+ * Copyright 2005-2008, Cake Software Foundation, Inc.
+ * 1785 E. Sahara Avenue, Suite 490-204
+ * Las Vegas, Nevada 89104
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
+ * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
+ * @package cake
+ * @subpackage cake.cake.app.config
+ * @since CakePHP(tm) v 0.2.9
+ * @version $Revision: 6305 $
+ * @modifiedby $LastChangedBy: phpnut $
+ * @lastmodified $Date: 2008-01-01 20:33:56 -0600 (Tue, 01 Jan 2008) $
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+/**
+ * If the index.php file is used instead of an .htaccess file
+ * or if the user can not set the web root to use the public
+ * directory we will define ROOT there, otherwise we set it
+ * here.
+ */
+ if (!defined('ROOT')) {
+ define ('ROOT', '../');
+ }
+ if (!defined('WEBROOT_DIR')) {
+ define ('WEBROOT_DIR', 'webroot');
+ }
+/**
+ * Path to the application's directory.
+ */
+ define ('CAKE', CORE_PATH.'cake'.DS);
+/**
+ * Path to the application's directory.
+ */
+ define ('APP', ROOT.DS.APP_DIR.DS);
+/**
+ * Path to the application's models directory.
+ */
+ define ('MODELS', APP.'models'.DS);
+/**
+ * Path to the application's controllers directory.
+ */
+ define ('CONTROLLERS', APP.'controllers'.DS);
+/**
+ * Path to the application's controllers directory.
+ */
+ define ('COMPONENTS', CONTROLLERS.'components'.DS);
+/**
+ * Path to the application's views directory.
+ */
+ define ('VIEWS', APP.'views'.DS);
+/**
+ * Path to the application's helpers directory.
+ */
+ define ('HELPERS', VIEWS.'helpers'.DS);
+/**
+ * Path to the application's view's layouts directory.
+ */
+ define ('LAYOUTS', VIEWS.'layouts'.DS);
+/**
+ * Path to the application's view's elements directory.
+ * It's supposed to hold pieces of PHP/HTML that are used on multiple pages
+ * and are not linked to a particular layout (like polls, footers and so on).
+ */
+ define ('ELEMENTS', VIEWS.'elements'.DS);
+/**
+ * Path to the configuration files directory.
+ */
+ define ('CONFIGS', APP.'config'.DS);
+/**
+ * Path to the libs directory.
+ */
+ define ('INFLECTIONS', CAKE.'config'.DS.'inflections'.DS);
+/**
+ * Path to the libs directory.
+ */
+ define ('LIBS', CAKE.'libs'.DS);
+/**
+ * Path to the public directory.
+ */
+ define ('CSS', WWW_ROOT.'css'.DS);
+/**
+ * Path to the public directory.
+ */
+ define ('JS', WWW_ROOT.'js'.DS);
+/**
+ * Path to the scripts direcotry.
+ */
+ define('SCRIPTS', CAKE.'scripts'.DS);
+/**
+ * Path to the tests directory.
+ */
+ define ('TESTS', APP.'tests'.DS);
+/**
+ * Path to the controller test directory.
+ */
+ define ('CONTROLLER_TESTS', TESTS.'cases'.DS.'controllers'.DS);
+/**
+ * Path to the components test directory.
+ */
+ define ('COMPONENT_TESTS', TESTS.'cases'.DS.'components'.DS);
+/**
+ * Path to the helpers test directory.
+ */
+ define ('HELPER_TESTS', TESTS.'cases'.DS.'views'.DS.'helpers'.DS);
+/**
+ * Path to the models' test directory.
+ */
+ define ('MODEL_TESTS', TESTS.'cases'.DS.'models'.DS);
+/**
+ * Path to the lib test directory.
+ */
+ define ('LIB_TESTS', TESTS.'lib'.DS);
+/**
+ * Path to the temporary files directory.
+ */
+ define ('TMP', APP.'tmp'.DS);
+/**
+ * Path to the logs directory.
+ */
+ define ('LOGS', TMP.'logs'.DS);
+/**
+ * Path to the cache files directory. It can be shared between hosts in a multi-server setup.
+ */
+ define('CACHE', TMP.'cache'.DS);
+/**
+ * Path to the vendors directory.
+ */
+ define ('VENDORS', CAKE_CORE_INCLUDE_PATH.DS.'vendors'.DS);
+/**
+ * Path to the Pear directory
+ * The purporse is to make it easy porting Pear libs into Cake
+ * without setting the include_path PHP variable.
+ */
+ define ('PEAR', VENDORS.'Pear'.DS);
+/**
+ * Full url prefix
+ */
+ $s = null;
+ if (env('HTTPS')) {
+ $s ='s';
+ }
+
+ $httpHost = env('HTTP_HOST');
+
+ if (isset($httpHost)) {
+ define('FULL_BASE_URL', 'http'.$s.'://'.$httpHost);
+ }
+ unset($httpHost, $s);
+/**
+ * Web path to the public images directory.
+ */
+ define ('IMAGES_URL', 'img/');
+/**
+ * Web path to the CSS files directory.
+ */
+ define ('CSS_URL', 'css/');
+/**
+ * Web path to the js files directory.
+ */
+ define ('JS_URL', 'js/');
+?> \ No newline at end of file
diff --git a/site/cake/dispatcher.php b/site/cake/dispatcher.php
new file mode 100644
index 0000000..aa0f310
--- /dev/null
+++ b/site/cake/dispatcher.php
@@ -0,0 +1,429 @@
+<?php
+/* SVN FILE: $Id: dispatcher.php 6305 2008-01-02 02:33:56Z phpnut $ */
+/**
+ * Dispatcher takes the URL information, parses it for paramters and
+ * tells the involved controllers what to do.
+ *
+ * This is the heart of Cake's operation.
+ *
+ * PHP versions 4 and 5
+ *
+ * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
+ * Copyright 2005-2008, Cake Software Foundation, Inc.
+ * 1785 E. Sahara Avenue, Suite 490-204
+ * Las Vegas, Nevada 89104
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
+ * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
+ * @package cake
+ * @subpackage cake.cake
+ * @since CakePHP(tm) v 0.2.9
+ * @version $Revision: 6305 $
+ * @modifiedby $LastChangedBy: phpnut $
+ * @lastmodified $Date: 2008-01-01 20:33:56 -0600 (Tue, 01 Jan 2008) $
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+/**
+ * List of helpers to include
+ */
+ uses('router', DS.'controller'.DS.'controller');
+/**
+ * Dispatcher translates URLs to controller-action-paramter triads.
+ *
+ * Dispatches the request, creating appropriate models and controllers.
+ *
+ * @package cake
+ * @subpackage cake.cake
+ */
+class Dispatcher extends Object {
+/**
+ * Base URL
+ * @var string
+ */
+ var $base = false;
+/**
+ * @var string
+ */
+ var $admin = false;
+/**
+ * @var string
+ */
+ var $webservices = null;
+/**
+ * @var string
+ */
+ var $plugin = null;
+/**
+ * Constructor.
+ */
+ function __construct() {
+ parent::__construct();
+ }
+/**
+ * Dispatches and invokes given URL, handing over control to the involved controllers, and then renders the results (if autoRender is set).
+ *
+ * If no controller of given name can be found, invoke() shows error messages in
+ * the form of Missing Controllers information. It does the same with Actions (methods of Controllers are called
+ * Actions).
+ *
+ * @param string $url URL information to work on.
+ * @param array $additionalParams Settings array ("bare", "return"),
+ * which is melded with the GET and POST params.
+ * @return boolean Success
+ */
+ function dispatch($url, $additionalParams=array()) {
+ $params = array_merge($this->parseParams($url), $additionalParams);
+ $missingController = false;
+ $missingAction = false;
+ $missingView = false;
+ $privateAction = false;
+ $this->base = $this->baseUrl();
+
+ if (empty($params['controller'])) {
+ $missingController = true;
+ } else {
+ $ctrlName = Inflector::camelize($params['controller']);
+ $ctrlClass = $ctrlName.'Controller';
+
+ if (!loadController($ctrlName)) {
+ $pluginName = Inflector::camelize($params['action']);
+ if (!loadPluginController(Inflector::underscore($ctrlName), $pluginName)) {
+ if (preg_match('/([\\.]+)/', $ctrlName)) {
+ return $this->cakeError('error404', array(
+ array('url' => strtolower($ctrlName),
+ 'message' => 'Was not found on this server',
+ 'base' => $this->base)));
+ } elseif (!class_exists($ctrlClass)) {
+ $missingController = true;
+ } else {
+ $params['plugin'] = null;
+ $this->plugin = null;
+ }
+ } else {
+ $params['plugin'] = Inflector::underscore($ctrlName);
+ }
+ } else {
+ $params['plugin'] = null;
+ $this->plugin = null;
+ }
+ }
+
+ if (isset($params['plugin'])) {
+ $plugin = $params['plugin'];
+ $pluginName = Inflector::camelize($params['action']);
+ $pluginClass = $pluginName.'Controller';
+ $ctrlClass = $pluginClass;
+ $oldAction = $params['action'];
+ $params = $this->_restructureParams($params);
+ $this->plugin = $plugin;
+ loadPluginModels($plugin);
+ $this->base = $this->base.'/'.Inflector::underscore($ctrlName);
+
+ if (empty($params['controller']) || !class_exists($pluginClass)) {
+ $params['controller'] = Inflector::underscore($ctrlName);
+ $ctrlClass = $ctrlName.'Controller';
+ if (!is_null($params['action'])) {
+ array_unshift($params['pass'], $params['action']);
+ }
+ $params['action'] = $oldAction;
+ }
+ }
+
+ if (empty($params['action'])) {
+ $params['action'] = 'index';
+ }
+
+ if (defined('CAKE_ADMIN')) {
+ if (isset($params[CAKE_ADMIN])) {
+ $this->admin = '/'.CAKE_ADMIN ;
+ $url = preg_replace('/'.CAKE_ADMIN.'(\/|$)/', '', $url);
+ $params['action'] = CAKE_ADMIN.'_'.$params['action'];
+ } elseif (strpos($params['action'], CAKE_ADMIN) === 0) {
+ $privateAction = true;
+ }
+ }
+
+ if ($missingController) {
+ return $this->cakeError('missingController', array(
+ array('className' => Inflector::camelize($params['controller']."Controller"),
+ 'webroot' => $this->webroot,
+ 'url' => $url,
+ 'base' => $this->base)));
+ } else {
+ $controller =& new $ctrlClass();
+ }
+
+ $classMethods = get_class_methods($controller);
+ $classVars = get_object_vars($controller);
+
+ if ((in_array($params['action'], $classMethods) || in_array(strtolower($params['action']), $classMethods)) && strpos($params['action'], '_', 0) === 0) {
+ $privateAction = true;
+ }
+
+ if (!in_array($params['action'], $classMethods) && !in_array(strtolower($params['action']), $classMethods)) {
+ $missingAction = true;
+ }
+
+ if (in_array(strtolower($params['action']), array('object', 'tostring', 'requestaction', 'log',
+ 'cakeerror', 'constructclasses', 'redirect',
+ 'set', 'setaction', 'validate', 'validateerrors',
+ 'render', 'referer', 'flash', 'flashout',
+ 'generatefieldnames', 'postconditions', 'cleanupfields',
+ 'beforefilter', 'beforerender', 'afterfilter'))) {
+ $missingAction = true;
+ }
+
+ if (in_array('return', array_keys($params)) && $params['return'] == 1) {
+ $controller->autoRender = false;
+ }
+
+ $controller->base = $this->base;
+ $base = strip_plugin($this->base, $this->plugin);
+ if (defined("BASE_URL")) {
+ $controller->here = $base . $this->admin . $url;
+ } else {
+ $controller->here = $base . $this->admin . '/' . $url;
+ }
+ $controller->webroot = $this->webroot;
+ $controller->params = $params;
+ $controller->action = $params['action'];
+
+ if (!empty($controller->params['data'])) {
+ $controller->data =& $controller->params['data'];
+ } else {
+ $controller->data = null;
+ }
+
+ if (!empty($controller->params['pass'])) {
+ $controller->passed_args =& $controller->params['pass'];
+ $controller->passedArgs =& $controller->params['pass'];
+ } else {
+ $controller->passed_args = null;
+ $controller->passedArgs = null;
+ }
+
+ if (!empty($params['bare'])) {
+ $controller->autoLayout = !$params['bare'];
+ } else {
+ $controller->autoLayout = $controller->autoLayout;
+ }
+
+ $controller->webservices = $params['webservices'];
+ $controller->plugin = $this->plugin;
+
+ if (!is_null($controller->webservices)) {
+ array_push($controller->components, $controller->webservices);
+ array_push($controller->helpers, $controller->webservices);
+ $component =& new Component($controller);
+ }
+ $controller->_initComponents();
+ $controller->constructClasses();
+
+ if ($missingAction && !in_array('scaffold', array_keys($classVars))) {
+ $this->start($controller);
+ return $this->cakeError('missingAction', array(
+ array('className' => Inflector::camelize($params['controller']."Controller"),
+ 'action' => $params['action'],
+ 'webroot' => $this->webroot,
+ 'url' => $url,
+ 'base' => $this->base)));
+ }
+
+ if ($privateAction) {
+ $this->start($controller);
+ return $this->cakeError('privateAction', array(
+ array('className' => Inflector::camelize($params['controller']."Controller"),
+ 'action' => $params['action'],
+ 'webroot' => $this->webroot,
+ 'url' => $url,
+ 'base' => $this->base)));
+ }
+ return $this->_invoke($controller, $params, $missingAction);
+ }
+/**
+ * Invokes given controller's render action if autoRender option is set. Otherwise the contents of the operation are returned as a string.
+ *
+ * @param object $controller
+ * @param array $params
+ * @param boolean $missingAction
+ * @return string
+ */
+ function _invoke (&$controller, $params, $missingAction = false) {
+ $this->start($controller);
+ $classVars = get_object_vars($controller);
+
+ if ($missingAction && in_array('scaffold', array_keys($classVars))) {
+ uses(DS.'controller'.DS.'scaffold');
+ return new Scaffold($controller, $params);
+ } else {
+ $output = call_user_func_array(array(&$controller, $params['action']), empty($params['pass'])? array(): $params['pass']);
+ }
+ if ($controller->autoRender) {
+ $output = $controller->render();
+ }
+ $controller->output =& $output;
+ $controller->afterFilter();
+ return $controller->output;
+ }
+/**
+ * Starts up a controller
+ *
+ * @param object $controller
+ */
+ function start(&$controller) {
+ if (!empty($controller->beforeFilter)) {
+ if (is_array($controller->beforeFilter)) {
+
+ foreach ($controller->beforeFilter as $filter) {
+ if (is_callable(array($controller,$filter)) && $filter != 'beforeFilter') {
+ $controller->$filter();
+ }
+ }
+ } else {
+ if (is_callable(array($controller, $controller->beforeFilter)) && $controller->beforeFilter != 'beforeFilter') {
+ $controller->{$controller->beforeFilter}();
+ }
+ }
+ }
+ $controller->beforeFilter();
+
+ foreach ($controller->components as $c) {
+ $path = preg_split('/\/|\./', $c);
+ $c = $path[count($path) - 1];
+ if (isset($controller->{$c}) && is_object($controller->{$c}) && is_callable(array($controller->{$c}, 'startup'))) {
+ $controller->{$c}->startup($controller);
+ }
+ }
+ }
+
+/**
+ * Returns array of GET and POST parameters. GET parameters are taken from given URL.
+ *
+ * @param string $from_url URL to mine for parameter information.
+ * @return array Parameters found in POST and GET.
+ */
+ function parseParams($from_url) {
+ $Route = new Router();
+ include CONFIGS.'routes.php';
+ $params = $Route->parse ($from_url);
+
+ if (ini_get('magic_quotes_gpc') == 1) {
+ if (!empty($_POST)) {
+ $params['form'] = stripslashes_deep($_POST);
+ }
+ } else {
+ $params['form'] = $_POST;
+ }
+
+ if (isset($params['form']['data'])) {
+ $params['data'] = $Route->stripEscape($params['form']['data']);
+ }
+
+ if (isset($_GET)) {
+ if (ini_get('magic_quotes_gpc') == 1) {
+ $params['url'] = stripslashes_deep($_GET);
+ } else {
+ $params['url'] = $_GET;
+ }
+ }
+
+ foreach ($_FILES as $name => $data) {
+ if ($name != 'data') {
+ $params['form'][$name] = $data;
+ }
+ }
+
+ if (isset($_FILES['data'])) {
+ foreach ($_FILES['data'] as $key => $data) {
+
+ foreach ($data as $model => $fields) {
+
+ foreach ($fields as $field => $value) {
+ $params['data'][$model][$field][$key] = $value;
+ }
+ }
+ }
+ }
+ $params['bare'] = empty($params['ajax'])? (empty($params['bare'])? 0: 1): 1;
+ $params['webservices'] = empty($params['webservices']) ? null : $params['webservices'];
+ return $params;
+ }
+/**
+ * Returns a base URL.
+ *
+ * @return string Base URL
+ */
+ function baseUrl() {
+ $htaccess = null;
+ $base = $this->admin;
+ $this->webroot = '';
+
+ if (defined('BASE_URL')) {
+ $base = BASE_URL.$this->admin;
+ }
+
+ $docRoot = env('DOCUMENT_ROOT');
+ $scriptName = env('PHP_SELF');
+ $r = null;
+ $appDirName = str_replace('/', '\/', preg_quote(APP_DIR));
+ $webrootDirName = str_replace('/', '\/', preg_quote(WEBROOT_DIR));
+
+ if (preg_match('/'.$appDirName.'\\'.DS.$webrootDirName.'/', $docRoot)) {
+ $this->webroot = '/';
+
+ if (preg_match('/^(.*)\/index\.php$/', $scriptName, $r)) {
+
+ if (!empty($r[1])) {
+ return $base.$r[1];
+ }
+ }
+ } else {
+ if (defined('BASE_URL')) {
+ $webroot = setUri();
+ $htaccess = preg_replace('/(?:'.APP_DIR.'\\/(.*)|index\\.php(.*))/i', '', $webroot).APP_DIR.'/'.$webrootDirName.'/';
+ }
+
+ if (preg_match('/^(.*)\\/'.$appDirName.'\\/'.$webrootDirName.'\\/index\\.php$/', $scriptName, $regs)) {
+
+ if (APP_DIR === 'app') {
+ $appDir = null;
+ } else {
+ $appDir = '/'.APP_DIR;
+ }
+ !empty($htaccess)? $this->webroot = $htaccess : $this->webroot = $regs[1].$appDir.'/';
+ return $base.$regs[1].$appDir;
+
+ } elseif (preg_match('/^(.*)\\/'.$webrootDirName.'([^\/i]*)|index\\\.php$/', $scriptName, $regs)) {
+ !empty($htaccess)? $this->webroot = $htaccess : $this->webroot = $regs[0].'/';
+ return $base.$regs[0];
+
+ } else {
+ !empty($htaccess)? $this->webroot = $htaccess : $this->webroot = '/';
+ return $base;
+ }
+ }
+ return $base;
+ }
+/**
+ * Enter description here...
+ *
+ * @param unknown_type $params
+ * @return unknown
+ */
+ function _restructureParams($params) {
+ $params['controller'] = $params['action'];
+
+ if (isset($params['pass'][0])) {
+ $params['action'] = $params['pass'][0];
+ array_shift($params['pass']);
+ } else {
+ $params['action'] = null;
+ }
+ return $params;
+ }
+}
+?> \ No newline at end of file
diff --git a/site/cake/libs/cache.php b/site/cake/libs/cache.php
new file mode 100644
index 0000000..487828c
--- /dev/null
+++ b/site/cake/libs/cache.php
@@ -0,0 +1,137 @@
+<?php
+/* SVN FILE: $Id: cache.php 6305 2008-01-02 02:33:56Z phpnut $ */
+/**
+ * Caching for Cake.
+ *
+ *
+ * PHP versions 4 and 5
+ *
+ * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
+ * Copyright 2005-2008, Cake Software Foundation, Inc.
+ * 1785 E. Sahara Avenue, Suite 490-204
+ * Las Vegas, Nevada 89104
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
+ * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
+ * @package cake
+ * @subpackage cake.cake.libs
+ * @since CakePHP(tm) v 0.2.9
+ * @version $Revision: 6305 $
+ * @modifiedby $LastChangedBy: phpnut $
+ * @lastmodified $Date: 2008-01-01 20:33:56 -0600 (Tue, 01 Jan 2008) $
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+/**
+ * Included libraries.
+ *
+ */
+ if (!class_exists('Model')) {
+ uses(DS . 'model' . DS . 'model');
+ }
+/**
+ * Caching for Cake.
+ *
+ *
+ * @package cake
+ * @subpackage cake.cake.libs
+ */
+class Cache extends Model{
+/**
+ * Identifier. Either an MD5 string or NULL.
+ *
+ * @var string
+ */
+ var $id = null;
+/**
+ * Content container for cache data.
+ *
+ * @var unknown_type
+ */
+ var $data = null;
+/**
+ * Content to be cached.
+ *
+ * @var unknown_type
+ */
+ var $for_caching = null;
+/**
+ * Name of the database table used for caching.
+ *
+ * @var string
+ */
+ var $useTable = 'cache';
+/**
+ * Constructor. Generates an md5'ed id for internal use. Calls the constructor on Model as well.
+ *
+ * @param unknown_type $id
+ */
+ function __construct($id) {
+ $this->id = (md5($id));
+ parent::__construct($this->id);
+ }
+/**
+ * Returns this object's id after setting it. If called without parameters the current object's id is returned.
+ *
+ * @param unknown_type $id
+ * @return unknown
+ */
+ function id($id = null) {
+ if (!$id) {
+ return $this->id;
+ }
+ return ($this->id = $id);
+ }
+/**
+ * Store given content in cache database.
+ *
+ * @param string $content Content to keep in cache.
+ * @param int $keep_for Number of seconds to keep data in cache.
+ * @return boolean Success
+ */
+ function remember($content, $keep_for = CACHE_PAGES_FOR) {
+ $data = addslashes($this->for_caching . $content);
+ $expire = date("Y-m-d H:i:s", time() + ($keep_for > 0 ? $keep_for : 999999999));
+ return $this->query("REPLACE {$this->useTable} (id,data,expire) VALUES ('{$this->id}', '{$data}', '{$expire}')");
+ }
+/**
+ * Returns content from the Cache object itself, if the Cache object has a non-empty data property.
+ * Else from the database cache.
+ *
+ * @return unknown
+ */
+ function restore() {
+ if (empty($this->data['data'])) {
+ return $this->find("id='{$this->id}' AND expire>NOW()");
+ }
+ return $this->data['data'];
+ }
+/**
+ * Returns true if the cache data property has current (non-stale) content for given id.
+ *
+ * @return boolean
+ */
+ function has() {
+ return is_array($this->data = $this->find("id='{$this->id}' AND expire>NOW()"));
+ }
+/**
+ * Appends $string to the for_caching property of the Cache object.
+ *
+ * @param string $string
+ */
+ function append($string) {
+ $this->for_caching .= $string;
+ }
+/**
+ * Clears the cache database table.
+ *
+ * @return unknown
+ */
+ function clear() {
+ return $this->query("DELETE FROM {$this->useTable}");
+ }
+}
+?> \ No newline at end of file
diff --git a/site/cake/libs/cake_log.php b/site/cake/libs/cake_log.php
new file mode 100644
index 0000000..48f6f91
--- /dev/null
+++ b/site/cake/libs/cake_log.php
@@ -0,0 +1,57 @@
+<?php
+/* SVN FILE: $Id: cake_log.php 6305 2008-01-02 02:33:56Z phpnut $ */
+/**
+ * Logging.
+ *
+ * Log messages to text files.
+ *
+ * PHP versions 4 and 5
+ *
+ * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
+ * Copyright 2005-2008, Cake Software Foundation, Inc.
+ * 1785 E. Sahara Avenue, Suite 490-204
+ * Las Vegas, Nevada 89104
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
+ * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
+ * @package cake
+ * @subpackage cake.cake.libs
+ * @since CakePHP(tm) v 0.2.9
+ * @version $Revision: 6305 $
+ * @modifiedby $LastChangedBy: phpnut $
+ * @lastmodified $Date: 2008-01-01 20:33:56 -0600 (Tue, 01 Jan 2008) $
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+/**
+ * Included libraries.
+ *
+ */
+ if (!class_exists('File')) {
+ uses('file');
+ }
+/**
+ * Logs messages to text files
+ *
+ * @package cake
+ * @subpackage cake.cake.libs
+ */
+class CakeLog{
+/**
+ * Writes given message to a log file in the logs directory.
+ *
+ * @param string $type Type of log, becomes part of the log's filename
+ * @param string $msg Message to log
+ * @return boolean Success
+ */
+ function write($type, $msg) {
+ $filename = LOGS . $type . '.log';
+ $output = date('Y-m-d H:i:s') . ' ' . ucfirst($type) . ': ' . $msg . "\n";
+ $log = new File($filename);
+ return $log->append($output);
+ }
+}
+?> \ No newline at end of file
diff --git a/site/cake/libs/class_registry.php b/site/cake/libs/class_registry.php
new file mode 100644
index 0000000..c9a4f58
--- /dev/null
+++ b/site/cake/libs/class_registry.php
@@ -0,0 +1,117 @@
+<?php
+/* SVN FILE: $Id: class_registry.php 6305 2008-01-02 02:33:56Z phpnut $ */
+/**
+ * Class collections.
+ *
+ * A repository for class objects, each registered with a key.
+ *
+ * PHP versions 4 and 5
+ *
+ * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
+ * Copyright 2005-2008, Cake Software Foundation, Inc.
+ * 1785 E. Sahara Avenue, Suite 490-204
+ * Las Vegas, Nevada 89104
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
+ * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
+ * @package cake
+ * @subpackage cake.cake.libs
+ * @since CakePHP(tm) v 0.9.2
+ * @version $Revision: 6305 $
+ * @modifiedby $LastChangedBy: phpnut $
+ * @lastmodified $Date: 2008-01-01 20:33:56 -0600 (Tue, 01 Jan 2008) $
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+/**
+ * Class Collections.
+ *
+ * A repository for class objects, each registered with a key.
+ * If you try to add an object with the same key twice, nothing will come of it.
+ * If you need a second instance of an object, give it another key.
+ *
+ * @package cake
+ * @subpackage cake.cake.libs
+ */
+class ClassRegistry{
+/**
+ * Names of classes with their objects.
+ *
+ * @var array
+ * @access private
+ */
+ var $_objects = array();
+/**
+ * Return a singleton instance of the ClassRegistry.
+ *
+ * @return ClassRegistry instance
+ */
+ function &getInstance() {
+ static $instance = array();
+ if (!$instance) {
+ $instance[0] = &new ClassRegistry;
+ }
+ return $instance[0];
+ }
+/**
+ * Add $object to the registry, associating it with the name $key.
+ *
+ * @param string $key
+ * @param mixed $object
+ */
+ function addObject($key, &$object) {
+ $_this =& ClassRegistry::getInstance();
+ $key = strtolower($key);
+ if (array_key_exists($key, $_this->_objects) === false) {
+ $_this->_objects[$key] = &$object;
+ }
+ }
+/**
+ * Remove object which corresponds to given key.
+ *
+ * @param string $key
+ * @return void
+ */
+ function removeObject($key) {
+ $_this =& ClassRegistry::getInstance();
+ $key = strtolower($key);
+ if (array_key_exists($key, $_this->_objects) === true) {
+ unset($_this->_objects[$key]);
+ }
+ }
+/**
+ * Returns true if given key is present in the ClassRegistry.
+ *
+ * @param string $key Key to look for
+ * @return boolean Success
+ */
+ function isKeySet($key) {
+ $_this =& ClassRegistry::getInstance();
+ $key = strtolower($key);
+ return array_key_exists($key, $_this->_objects);
+ }
+/**
+ * Get all keys from the regisrty.
+ *
+ * @return array
+ */
+ function keys() {
+ $_this =& ClassRegistry::getInstance();
+ return array_keys($_this->_objects);
+ }
+/**
+ * Return object which corresponds to given key.
+ *
+ * @param string $key
+ * @return mixed
+ */
+ function &getObject($key) {
+ $_this =& ClassRegistry::getInstance();
+ $key = strtolower($key);
+ return $_this->_objects[$key];
+ }
+}
+?> \ No newline at end of file
diff --git a/site/cake/libs/configure.php b/site/cake/libs/configure.php
new file mode 100644
index 0000000..4b9f0b7
--- /dev/null
+++ b/site/cake/libs/configure.php
@@ -0,0 +1,354 @@
+<?php
+/* SVN FILE: $Id: configure.php 6305 2008-01-02 02:33:56Z phpnut $ */
+/**
+ * Short description for file.
+ *
+ * Long description for file
+ *
+ * PHP versions 4 and 5
+ *
+ * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
+ * Copyright 2005-2008, Cake Software Foundation, Inc.
+ * 1785 E. Sahara Avenue, Suite 490-204
+ * Las Vegas, Nevada 89104
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
+ * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
+ * @package cake
+ * @subpackage cake.cake.libs
+ * @since CakePHP(tm) v 1.0.0.2363
+ * @version $Revision: 6305 $
+ * @modifiedby $LastChangedBy: phpnut $
+ * @lastmodified $Date: 2008-01-01 20:33:56 -0600 (Tue, 01 Jan 2008) $
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+/**
+ * Short description for file.
+ *
+ * Long description for file
+ *
+ * @package cake
+ * @subpackage cake.cake.libs
+ */
+class Configure extends Object {
+/**
+ * Hold array with paths to view files
+ *
+ * @var array
+ * @access public
+ */
+ var $viewPaths = array();
+/**
+ * Hold array with paths to controller files
+ *
+ * @var array
+ * @access public
+ */
+ var $controllerPaths = array();
+/**
+ * Enter description here...
+ *
+ * @var array
+ * @access public
+ */
+ var $modelPaths = array();
+/**
+ * Enter description here...
+ *
+ * @var array
+ * @access public
+ */
+ var $helperPaths = array();
+/**
+ * Enter description here...
+ *
+ * @var array
+ * @access public
+ */
+ var $componentPaths = array();
+/**
+ * Enter description here...
+ *
+ * @var integer
+ * @access public
+ */
+ var $debug = null;
+/**
+ * Return a singleton instance of Configure.
+ *
+ * @return Configure instance
+ * @access public
+ */
+ function &getInstance() {
+ static $instance = array();
+ if (!$instance) {
+ $instance[0] =& new Configure;
+ $instance[0]->__loadBootstrap();
+ }
+ return $instance[0];
+ }
+/**
+ * Used to write a dynamic var in the Configure instance.
+ *
+ * Usage
+ * Configure::write('One.key1', 'value of the Configure::One[key1]');
+ * Configure::write(array('One.key1' => 'value of the Configure::One[key1]'));
+ * Configure::write('One', array('key1'=>'value of the Configure::One[key1]', 'key2'=>'value of the Configure::One[key2]');
+ * Configure::write(array('One.key1' => 'value of the Configure::One[key1]', 'One.key2' => 'value of the Configure::One[key2]'));
+ *
+ * @param array $config
+ * @return void
+ * @access public
+ */
+ function write($config, $value = null) {
+ $_this =& Configure::getInstance();
+
+ if (!is_array($config) && $value !== null) {
+ $name = $_this->__configVarNames($config);
+
+ if (count($name) > 1) {
+ $_this->{$name[0]}[$name[1]] = $value;
+ } else {
+ $_this->{$name[0]} = $value;
+ }
+ } else {
+
+ foreach ($config as $names => $value) {
+ $name = $_this->__configVarNames($names);
+ if (count($name) > 1) {
+ $_this->{$name[0]}[$name[1]] = $value;
+ } else {
+ $_this->{$name[0]} = $value;
+ }
+ }
+ }
+
+ if ($config == 'debug' || (is_array($config) && in_array('debug', $config))) {
+ if ($_this->debug) {
+ error_reporting(E_ALL);
+
+ if (function_exists('ini_set')) {
+ ini_set('display_errors', 1);
+ }
+ } else {
+ error_reporting(0);
+ }
+ }
+ }
+/**
+ * Used to read Configure::$var
+ *
+ * Usage
+ * Configure::read('Name'); will return all values for Name
+ * Configure::read('Name.key'); will return only the value of Configure::Name[key]
+ *
+ * @param string $var
+ * @return string value of Configure::$var
+ * @access public
+ */
+ function read($var = 'debug') {
+ $_this =& Configure::getInstance();
+ if ($var === 'debug') {
+ if (!isset($_this->debug)) {
+ $_this->debug = DEBUG;
+ }
+ return $_this->debug;
+ }
+
+ $name = $_this->__configVarNames($var);
+ if (count($name) > 1) {
+ if (isset($_this->{$name[0]}[$name[1]])) {
+ return $_this->{$name[0]}[$name[1]];
+ }
+ return null;
+ } else {
+ if (isset($_this->{$name[0]})) {
+ return $_this->{$name[0]};
+ }
+ return null;
+ }
+ }
+/**
+ * Used to delete a var from the Configure instance.
+ *
+ * Usage:
+ * Configure::delete('Name'); will delete the entire Configure::Name
+ * Configure::delete('Name.key'); will delete only the Configure::Name[key]
+ *
+ * @param string $var the var to be deleted
+ * @return void
+ * @access public
+ */
+ function delete($var = null) {
+ $_this =& Configure::getInstance();
+
+ $name = $_this->__configVarNames($var);
+ if (count($name) > 1) {
+ unset($_this->{$name[0]}[$name[1]]);
+ } else {
+ unset($_this->{$name[0]});
+ }
+ }
+/**
+ * Will load a file from app/config/configure_file.php
+ * variables in the files should be formated like:
+ * $config['name'] = 'value';
+ * These will be used to create dynamic Configure vars.
+ *
+ * Usage Configure::load('configure_file');
+ *
+ * @param string $fileName name of file to load, extension must be .php and only the name should be used, not the extenstion
+ * @return Configure::write
+ * @access public
+ */
+ function load($fileName) {
+ $_this =& Configure::getInstance();
+
+ if (!file_exists(CONFIGS . $fileName . '.php')) {
+ trigger_error("Configure::load() - $fileName.php not found", E_USER_WARNING);
+ return false;
+ }
+ include(CONFIGS . $fileName . '.php');
+ if (!isset($config)) {
+ trigger_error("Configure::load() - no variable \$config found in $fileName.php", E_USER_WARNING);
+ return false;
+ }
+ return $_this->write($config);
+ }
+
+/**
+ * Used to determine the current version of CakePHP
+ *
+ * Usage Configure::version();
+ *
+ * @return string Current version of CakePHP
+ * @access public
+ */
+ function version() {
+ $_this =& Configure::getInstance();
+ if (!isset($_this->Cake['version'])) {
+ require(CORE_PATH . 'cake' . DS . 'config' . DS . 'config.php');
+ $_this->write($config);
+ }
+ return $_this->Cake['version'];
+ }
+/**
+ * Checks $name for dot notation to create dynamic Configure::$var as an array when needed.
+ *
+ * @param mixed $name
+ * @return array
+ * @access private
+ */
+ function __configVarNames($name) {
+ if (is_string($name)) {
+ if (strpos($name, ".")) {
+ $name = explode(".", $name);
+ } else {
+ $name = array($name);
+ }
+ }
+ return $name;
+ }
+/**
+ * Sets the var modelPaths
+ *
+ * @param array $modelPaths
+ * @access private
+ */
+ function __buildModelPaths($modelPaths) {
+ $_this =& Configure::getInstance();
+ $_this->modelPaths[] = MODELS;
+ if (isset($modelPaths)) {
+ foreach ($modelPaths as $value) {
+ $_this->modelPaths[] = $value;
+ }
+ }
+ }
+/**
+ * Sets the var viewPaths
+ *
+ * @param array $viewPaths
+ * @access private
+ */
+ function __buildViewPaths($viewPaths) {
+ $_this =& Configure::getInstance();
+ $_this->viewPaths[] = VIEWS;
+ if (isset($viewPaths)) {
+ foreach ($viewPaths as $value) {
+ $_this->viewPaths[] = $value;
+ }
+ }
+ }
+/**
+ * Sets the var controllerPaths
+ *
+ * @param array $controllerPaths
+ * @access private
+ */
+ function __buildControllerPaths($controllerPaths) {
+ $_this =& Configure::getInstance();
+ $_this->controllerPaths[] = CONTROLLERS;
+ if (isset($controllerPaths)) {
+ foreach ($controllerPaths as $value) {
+ $_this->controllerPaths[] = $value;
+ }
+ }
+ }
+/**
+ * Sets the var helperPaths
+ *
+ * @param array $helperPaths
+ * @access private
+ */
+ function __buildHelperPaths($helperPaths) {
+ $_this =& Configure::getInstance();
+ $_this->helperPaths[] = HELPERS;
+ if (isset($helperPaths)) {
+ foreach ($helperPaths as $value) {
+ $_this->helperPaths[] = $value;
+ }
+ }
+ }
+/**
+ * Sets the var componentPaths
+ *
+ * @param array $componentPaths
+ * @access private
+ */
+ function __buildComponentPaths($componentPaths) {
+ $_this =& Configure::getInstance();
+ $_this->componentPaths[] = COMPONENTS;
+ if (isset($componentPaths)) {
+ foreach ($componentPaths as $value) {
+ $_this->componentPaths[] = $value;
+ }
+ }
+ }
+/**
+ * Loads the app/config/bootstrap.php
+ * If the alternative paths are set in this file
+ * they will be added to the paths vars
+ *
+ * @access private
+ */
+ function __loadBootstrap() {
+ $_this =& Configure::getInstance();
+ $_this->write('Session.checkAgent', true);
+ $modelPaths = null;
+ $viewPaths = null;
+ $controllerPaths = null;
+ $helperPaths = null;
+ $componentPaths = null;
+ require APP_PATH . 'config' . DS . 'bootstrap.php';
+ $_this->__buildModelPaths($modelPaths);
+ $_this->__buildViewPaths($viewPaths);
+ $_this->__buildControllerPaths($controllerPaths);
+ $_this->__buildHelperPaths($helperPaths);
+ $_this->__buildComponentPaths($componentPaths);
+ }
+}
+?> \ No newline at end of file
diff --git a/site/cake/libs/controller/component.php b/site/cake/libs/controller/component.php
new file mode 100644
index 0000000..363cfca
--- /dev/null
+++ b/site/cake/libs/controller/component.php
@@ -0,0 +1,139 @@
+<?php
+/* SVN FILE: $Id: component.php 6305 2008-01-02 02:33:56Z phpnut $ */
+/**
+ *
+ * PHP versions 4 and 5
+ *
+ * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
+ * Copyright 2005-2008, Cake Software Foundation, Inc.
+ * 1785 E. Sahara Avenue, Suite 490-204
+ * Las Vegas, Nevada 89104
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
+ * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
+ * @package cake
+ * @subpackage cake.cake.libs.controller
+ * @since CakePHP(tm) v TBD
+ * @version $Revision: 6305 $
+ * @modifiedby $LastChangedBy: phpnut $
+ * @lastmodified $Date: 2008-01-01 20:33:56 -0600 (Tue, 01 Jan 2008) $
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+/**
+ * Component
+ *
+ * Used to create instances of applications components
+ *
+ * @package cake
+ * @subpackage cake.cake.libs.controller
+ */
+class Component extends Object {
+/**
+ * Instance Controller
+ *
+ * @var object
+ * @access private
+ */
+ var $__controller = null;
+/**
+ * Constructor
+ */
+ function __construct() {
+ }
+/**
+ * Used to initialize the components for current controller
+ *
+ * @param object $controller
+ * @access public
+ */
+ function init(&$controller) {
+ $this->__controller =& $controller;
+
+ if ($this->__controller->components !== false) {
+ $loaded = array();
+ $this->__controller->components = array_merge(array('Session'), $this->__controller->components);
+ $loaded = $this->__loadComponents($loaded, $this->__controller->components);
+
+ foreach (array_keys($loaded)as $component) {
+ $tempComponent =& $loaded[$component];
+
+ if (isset($tempComponent->components) && is_array($tempComponent->components)) {
+ foreach ($tempComponent->components as $subComponent) {
+ $this->__controller->{$component}->{$subComponent} =& $loaded[$subComponent];
+ }
+ }
+ if (is_callable(array($tempComponent, 'initialize'))) {
+ $tempComponent->initialize($controller);
+ }
+ }
+ }
+ }
+
+/**
+ * Enter description here...
+ *
+ * @param array $loaded
+ * @param array $components
+ * @return loaded components
+ * @access private
+ */
+ function &__loadComponents(&$loaded, $components) {
+ foreach ($components as $component) {
+ $parts = preg_split('/\/|\./', $component);
+
+ if (count($parts) === 1) {
+ $plugin = $this->__controller->plugin;
+ } else {
+ $plugin = Inflector::underscore($parts['0']);
+ $component = $parts[count($parts) - 1];
+ }
+
+ $componentCn = $component . 'Component';
+
+ if (in_array($component, array_keys($loaded)) !== true) {
+
+ if (!class_exists($componentCn)) {
+
+ if (is_null($plugin) || !loadPluginComponent($plugin, $component)) {
+
+ if (!loadComponent($component)) {
+ $this->cakeError('missingComponentFile', array(array(
+ 'className' => $this->__controller->name,
+ 'component' => $component,
+ 'file' => Inflector::underscore($component) . '.php',
+ 'base' => $this->__controller->base)));
+ exit();
+ }
+ }
+
+ if (!class_exists($componentCn)) {
+ $this->cakeError('missingComponentClass', array(array(
+ 'className' => $this->__controller->name,
+ 'component' => $component,
+ 'file' => Inflector::underscore($component) . '.php',
+ 'base' => $this->__controller->base)));
+ exit();
+ }
+ }
+
+ if ($componentCn == 'SessionComponent') {
+ $param = strip_plugin($this->__controller->base, $this->__controller->plugin) . '/';
+ } else {
+ $param = null;
+ }
+ $this->__controller->{$component} =& new $componentCn($param);
+ $loaded[$component] =& $this->__controller->{$component};
+
+ if (isset($this->__controller->{$component}->components) && is_array($this->__controller->{$component}->components)) {
+ $loaded =& $this->__loadComponents($loaded, $this->__controller->{$component}->components);
+ }
+ }
+ }
+ return $loaded;
+ }
+}
+?> \ No newline at end of file
diff --git a/site/cake/libs/controller/components/acl.php b/site/cake/libs/controller/components/acl.php
new file mode 100644
index 0000000..5f335cd
--- /dev/null
+++ b/site/cake/libs/controller/components/acl.php
@@ -0,0 +1,196 @@
+<?php
+/* SVN FILE: $Id: acl.php 6305 2008-01-02 02:33:56Z phpnut $ */
+/**
+ * Access Control List factory class.
+ *
+ * Permissions system.
+ *
+ * PHP versions 4 and 5
+ *
+ * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
+ * Copyright 2005-2008, Cake Software Foundation, Inc.
+ * 1785 E. Sahara Avenue, Suite 490-204
+ * Las Vegas, Nevada 89104
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
+ * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
+ * @package cake
+ * @subpackage cake.cake.libs.controller.components
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @version $Revision: 6305 $
+ * @modifiedby $LastChangedBy: phpnut $
+ * @lastmodified $Date: 2008-01-01 20:33:56 -0600 (Tue, 01 Jan 2008) $
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+/**
+ * Access Control List factory class.
+ *
+ * Looks for ACL implementation class in core config, and returns an instance of that class.
+ *
+ * @package cake
+ * @subpackage cake.cake.libs.controller.components
+ */
+class AclComponent extends Object {
+/**
+ * Instance of ACL_CLASSNAME set in app/config/core.php
+ *
+ * @var object
+ */
+ var $_instance = null;
+/**
+ * Enter description here...
+ *
+ * @var boolean
+ */
+ var $controller = true;
+/**
+ * Constructor.
+ *
+ * Will return an instance of the correct ACL class.
+ */
+ function __construct() {
+ $this->getACL();
+ }
+/**
+ * Static function used to gain an instance of the correct ACL class.
+ *
+ * @return object instance of ACL_CLASSNAME set in app/config/core.php
+ * @access public
+ */
+ function &getACL() {
+ if ($this->_instance == null) {
+ uses('controller' . DS . 'components' . DS . ACL_FILENAME);
+ $classname = ACL_CLASSNAME;
+ $this->_instance = new $classname;
+ }
+
+ if ($classname == 'DB_ACL') {
+ $this->Aro = new Aro();
+ $this->Aco = new Aco();
+ }
+ return $this->_instance;
+ }
+/**
+ * Empty class defintion, to be overridden in subclasses.
+ *
+ * @access public
+ */
+ function _initACL() {
+ }
+/**
+ * Pass-thru function for ACL check instance.
+ *
+ * @param string $aro
+ * @param string $aco
+ * @param string $action : default = *
+ * @return boolean
+ * @access public
+ */
+ function check($aro, $aco, $action = "*") {
+ return $this->_instance->check($aro, $aco, $action);
+ }
+/**
+ * Pass-thru function for ACL allow instance.
+ *
+ * @param string $aro
+ * @param string $aco
+ * @param string $action : default = *
+ * @return boolean
+ * @access public
+ */
+ function allow($aro, $aco, $action = "*") {
+ return $this->_instance->allow($aro, $aco, $action);
+ }
+/**
+ * Pass-thru function for ACL deny instance.
+ *
+ * @param string $aro
+ * @param string $aco
+ * @param string $action : default = *
+ * @return boolean
+ * @abstract public
+ */
+ function deny($aro, $aco, $action = "*") {
+ return $this->_instance->deny($aro, $aco, $action);
+ }
+/**
+ * Pass-thru function for ACL inherit instance.
+ *
+ * @return boolean
+ * @abstract public
+ */
+ function inherit($aro, $aco, $action = "*") {
+ return $this->_instance->inherit($aro, $aco, $action);
+ }
+/**
+ * Pass-thru function for ACL grant instance.
+ *
+ * @param string $aro
+ * @param string $aco
+ * @param string $action : default = *
+ * @return boolean
+ * @access public
+ */
+ function grant($aro, $aco, $action = "*") {
+ return $this->_instance->grant($aro, $aco, $action);
+ }
+/**
+ * Pass-thru function for ACL grant instance.
+ *
+ * @param string $aro
+ * @param string $aco
+ * @param string $action : default = *
+ * @return boolean
+ * @access public
+ */
+ function revoke($aro, $aco, $action = "*") {
+ return $this->_instance->revoke($aro, $aco, $action);
+ }
+/**
+ * Sets the current ARO instance to object from getAro
+ *
+ * @param string $id
+ * @return boolean
+ * @access public
+ */
+ function setAro($id) {
+ return $this->Aro = $this->_instance->getAro($id);
+ }
+/**
+* Sets the current ACO instance to object from getAco
+ *
+ * @param string $id
+ * @return boolean
+ * @access public
+ */
+ function setAco($id) {
+ return $this->Aco = $this->_instance->getAco($id);
+ }
+/**
+ * Pass-thru function for ACL getAro instance
+ * that gets an ARO object from the given id or alias
+ *
+ * @param string $id
+ * @return object Aro
+ * @access public
+ */
+ function getAro($id) {
+ return $this->_instance->getAro($id);
+ }
+/**
+ * Pass-thru function for ACL getAco instance.
+ * that gets an ACO object from the given id or alias
+ *
+ * @param string $id
+ * @return object Aco
+ * @access public
+ */
+ function getAco($id) {
+ return $this->_instance->getAco($id);
+ }
+}
+?> \ No newline at end of file
diff --git a/site/cake/libs/controller/components/acl_base.php b/site/cake/libs/controller/components/acl_base.php
new file mode 100644
index 0000000..7895fe8
--- /dev/null
+++ b/site/cake/libs/controller/components/acl_base.php
@@ -0,0 +1,63 @@
+<?php
+/* SVN FILE: $Id: acl_base.php 6305 2008-01-02 02:33:56Z phpnut $ */
+/**
+ * Access Control List abstract class.
+ *
+ * Long description for file
+ *
+ * PHP versions 4 and 5
+ *
+ * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
+ * Copyright 2005-2008, Cake Software Foundation, Inc.
+ * 1785 E. Sahara Avenue, Suite 490-204
+ * Las Vegas, Nevada 89104
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
+ * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
+ * @package cake
+ * @subpackage cake.cake.libs.controller.components
+ * @since CakePHP(tm) v 0.10.0.1232
+ * @version $Revision: 6305 $
+ * @modifiedby $LastChangedBy: phpnut $
+ * @lastmodified $Date: 2008-01-01 20:33:56 -0600 (Tue, 01 Jan 2008) $
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+/**
+ * Access Control List abstract class. Not to be instantiated.
+ * Subclasses of this class are used by AclComponent to perform ACL checks in Cake.
+ *
+ * @package cake
+ * @subpackage cake.cake.libs.controller.components
+ * @abstract
+ */
+class AclBase extends Object {
+/**
+ * This class should never be instantiated, just subclassed.
+ *
+ * No instantiations or constructor calls (even statically)
+ *
+ * @return AclBase
+ * @abstract
+ */
+ function __construct() {
+ if (strcasecmp(get_class($this), "AclBase") == 0 || !is_subclass_of($this, "AclBase")) {
+ trigger_error("[acl_base] The AclBase class constructor has been called, or the class was instantiated. This class must remain abstract. Please refer to the Cake docs for ACL configuration.", E_USER_ERROR);
+ return null;
+ }
+ }
+/**
+ * Empty method to be overridden in subclasses
+ *
+ * @param string $aro
+ * @param string $aco
+ * @param string $action
+ * @abstract
+ */
+ function check($aro, $aco, $action = "*") {
+ }
+}
+?> \ No newline at end of file
diff --git a/site/cake/libs/controller/components/dbacl/db_acl.php b/site/cake/libs/controller/components/dbacl/db_acl.php
new file mode 100644
index 0000000..bab6125
--- /dev/null
+++ b/site/cake/libs/controller/components/dbacl/db_acl.php
@@ -0,0 +1,310 @@
+<?php
+/* SVN FILE: $Id: db_acl.php 6305 2008-01-02 02:33:56Z phpnut $ */
+/**
+ * This is core configuration file.
+ *
+ * Use it to configure core behaviour ofCake.
+ *
+ * PHP versions 4 and 5
+ *
+ * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
+ * Copyright 2005-2008, Cake Software Foundation, Inc.
+ * 1785 E. Sahara Avenue, Suite 490-204
+ * Las Vegas, Nevada 89104
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
+ * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
+ * @package cake
+ * @subpackage cake.cake.libs.controller.componenets.dbacl
+ * @since CakePHP(tm) v 0.2.9
+ * @version $Revision: 6305 $
+ * @modifiedby $LastChangedBy: phpnut $
+ * @lastmodified $Date: 2008-01-01 20:33:56 -0600 (Tue, 01 Jan 2008) $
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+if (!defined('ACL_DATABASE')) {
+ define('ACL_DATABASE', 'default');
+}
+uses('controller' . DS . 'components' . DS . 'acl_base');
+uses('controller' . DS . 'components' . DS . 'dbacl' . DS . 'models' . DS . 'aclnode');
+uses('controller' . DS . 'components' . DS . 'dbacl' . DS . 'models' . DS . 'aco');
+uses('controller' . DS . 'components' . DS . 'dbacl' . DS . 'models' . DS . 'acoaction');
+uses('controller' . DS . 'components' . DS . 'dbacl' . DS . 'models' . DS . 'aro');
+uses('controller' . DS . 'components' . DS . 'dbacl' . DS . 'models' . DS . 'aros_aco');
+/**
+ * In this file you can extend the AclBase.
+ *
+ * @package cake
+ * @subpackage cake.cake.libs.controller.components.dbacl
+ */
+class DB_ACL extends AclBase {
+/**
+ * Enter description here...
+ *
+ */
+ function __construct() {
+ }
+/**
+ * Enter description here...
+ *
+ * @param string $aro
+ * @param string $aco
+ * @param string $action
+ * @return boolean
+ * @access public
+ */
+ function check($aro, $aco, $action = "*") {
+ $Perms = new ArosAco();
+ $Aro = new Aro();
+ $Aco = new Aco();
+
+ if ($aro == null || $aco == null) {
+ return false;
+ }
+
+ $permKeys = $this->_getAcoKeys($Perms->loadInfo());
+ $aroPath = $Aro->getPath($aro);
+ $tmpAcoPath = $Aco->getPath($aco);
+
+ if ($tmpAcoPath === null) {
+ return false;
+ }
+ $tmpAcoPath = array_reverse($tmpAcoPath);
+ $acoPath = array();
+
+ if ($action != '*' && !in_array('_' . $action, $permKeys)) {
+ trigger_error('ACO permissions key "' . $action . '" does not exist in DB_ACL::check()', E_USER_NOTICE);
+ return false;
+ }
+
+ foreach ($tmpAcoPath as $a) {
+ $acoPath[] = $a['Aco']['id'];
+ }
+
+ for ($i = count($aroPath) - 1; $i >= 0; $i--) {
+ $perms = $Perms->findAll(array('ArosAco.aro_id' => $aroPath[$i]['Aro']['id'],
+ 'ArosAco.aco_id' => $acoPath), null,
+ 'Aco.lft desc');
+ if ($perms == null || count($perms) == 0) {
+ continue;
+ } else {
+ foreach ($perms as $perm) {
+ if ($action == '*') {
+ // ARO must be cleared for ALL ACO actions
+ foreach ($permKeys as $key) {
+ if (isset($perm['ArosAco'])) {
+ if ($perm['ArosAco'][$key] != 1) {
+ return false;
+ }
+ }
+ }
+ return true;
+
+ } else {
+ switch($perm['ArosAco']['_' . $action]) {
+ case -1:
+ return false;
+ case 0:
+ continue;
+ break;
+ case 1:
+ return true;
+ break;
+ }
+ }
+ }
+ }
+ }
+ return false;
+ }
+/**
+ * Enter description here...
+ *
+ * @param string $aro
+ * @param string $aco
+ * @param string $action
+ * @param integer $value
+ * @return boolean
+ * @access public
+ */
+ function allow($aro, $aco, $action = "*", $value = 1) {
+ $Perms = new ArosAco();
+ $perms = $this->getAclLink($aro, $aco);
+ $permKeys = $this->_getAcoKeys($Perms->loadInfo());
+ $save = array();
+
+ if ($perms == false) {
+ trigger_error('DB_ACL::allow() - Invalid node', E_USER_WARNING);
+ return false;
+ }
+
+ if (isset($perms[0])) {
+ $save = $perms[0]['ArosAco'];
+ }
+
+ if ($action == "*") {
+ $permKeys = $this->_getAcoKeys($Perms->loadInfo());
+
+ foreach ($permKeys as $key) {
+ $save[$key] = $value;
+ }
+ } else {
+ if (in_array('_' . $action, $permKeys)) {
+ $save['_' . $action] = $value;
+ } else {
+ trigger_error('DB_ACL::allow() - Invalid ACO action', E_USER_WARNING);
+ return false;
+ }
+ }
+
+ $save['aro_id'] = $perms['aro'];
+ $save['aco_id'] = $perms['aco'];
+
+ if ($perms['link'] != null && count($perms['link']) > 0) {
+ $save['id'] = $perms['link'][0]['ArosAco']['id'];
+ }
+ return $Perms->save(array('ArosAco' => $save));
+ }
+/**
+ * Enter description here...
+ *
+ * @param string $aro
+ * @param string $aco
+ * @param string $action
+ * @return boolean
+ * @access public
+ */
+ function deny($aro, $aco, $action = "*") {
+ return $this->allow($aro, $aco, $action, -1);
+ }
+/**
+ * Enter description here...
+ *
+ * @param string $aro
+ * @param string $aco
+ * @param string $action
+ * @return boolean
+ * @access public
+ */
+ function inherit($aro, $aco, $action = "*") {
+ return $this->allow($aro, $aco, $action, 0);
+ }
+/**
+ * Enter description here...
+ *
+ * @param string $aro
+ * @param string $aco
+ * @param string $action
+ * @return boolean
+ * @access public
+ */
+ function grant($aro, $aco, $action = "*") {
+ return $this->allow($aro, $aco, $action);
+ }
+/**
+ * Enter description here...
+ *
+ * @param string $aro
+ * @param string $aco
+ * @param string $action
+ * @return boolean
+ * @access public
+ */
+ function revoke($aro, $aco, $action = "*") {
+ return $this->deny($aro, $aco, $action);
+ }
+/**
+ * Get an ARO object from the given id or alias
+ *
+ * @param mixed $id
+ * @return object Aro
+ * @access public
+ */
+ function getAro($id = null) {
+ return $this->__getObject($id, 'Aro');
+ }
+/**
+ * Get an ACO object from the given id or alias
+ *
+ * @param mixed $id
+ * @return object Aco
+ * @access public
+ */
+ function getAco($id = null) {
+ return $this->__getObject($id, 'Aco');
+ }
+ function __getObject($id = null, $object) {
+ if ($id == null) {
+ trigger_error('Null id provided in DB_ACL::get' . $object, E_USER_WARNING);
+ return null;
+ }
+
+ $obj = new $object;
+
+ if (is_numeric($id)) {
+ $key = 'foreign_key';
+ if ($object == 'Aco') {
+ $key = 'object_id';
+ }
+
+ $conditions = array($object . '.' . $key => $id);
+ } else {
+ $conditions = array($object . '.alias' => $id);
+ }
+
+ $tmp = $obj->find($conditions);
+ $obj->id = $tmp[$object]['id'];
+ return $obj;
+ }
+/**
+ * Get an array of access-control links between the given Aro and Aco
+ *
+ * @param mixed $aro
+ * @param mixed $aco
+ * @return array
+ * @access public
+ */
+ function getAclLink($aro, $aco) {
+ $Aro = new Aro();
+ $Aco = new Aco();
+ $Link = new ArosAco();
+
+ $obj = array();
+ $obj['Aro'] = $Aro->find($Aro->_resolveID($aro));
+ $obj['Aco'] = $Aco->find($Aco->_resolveID($aco));
+ $obj['Aro'] = $obj['Aro']['Aro'];
+ $obj['Aco'] = $obj['Aco']['Aco'];
+
+ if ($obj['Aro'] == null || count($obj['Aro']) == 0 || $obj['Aco'] == null || count($obj['Aco']) == 0) {
+ return false;
+ }
+ return array('aro' => $obj['Aro']['id'],
+ 'aco' => $obj['Aco']['id'],
+ 'link' => $Link->findAll(array(
+ 'ArosAco.aro_id' => $obj['Aro']['id'],
+ 'ArosAco.aco_id' => $obj['Aco']['id'])));
+ }
+/**
+ * Enter description here...
+ *
+ * @param object $keys
+ * @return array
+ * @access protected
+ */
+ function _getAcoKeys($keys) {
+ $newKeys = array();
+ $keys = $keys->value;
+
+ foreach ($keys as $key) {
+ if ($key['name'] != 'id' && $key['name'] != 'aro_id' && $key['name'] != 'aco_id') {
+ $newKeys[] = $key['name'];
+ }
+ }
+ return $newKeys;
+ }
+}
+?> \ No newline at end of file
diff --git a/site/cake/libs/controller/components/dbacl/models/aclnode.php b/site/cake/libs/controller/components/dbacl/models/aclnode.php
new file mode 100644
index 0000000..7306a79
--- /dev/null
+++ b/site/cake/libs/controller/components/dbacl/models/aclnode.php
@@ -0,0 +1,309 @@
+<?php
+/* SVN FILE: $Id: aclnode.php 6305 2008-01-02 02:33:56Z phpnut $ */
+/**
+ * Short description for file.
+ *
+ * Long description for file
+ *
+ * PHP versions 4 and 5
+ *
+ * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
+ * Copyright 2005-2008, Cake Software Foundation, Inc.
+ * 1785 E. Sahara Avenue, Suite 490-204
+ * Las Vegas, Nevada 89104
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
+ * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
+ * @package cake
+ * @subpackage cake.cake.libs.controller.components.dbacl.models
+ * @since CakePHP(tm) v 0.10.0.1232
+ * @version $Revision: 6305 $
+ * @modifiedby $LastChangedBy: phpnut $
+ * @lastmodified $Date: 2008-01-01 20:33:56 -0600 (Tue, 01 Jan 2008) $
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+/**
+ * Load AppModel class
+ */
+loadModel();
+/**
+ * Short description for file.
+ *
+ * Long description for file
+ *
+ * @package cake
+ * @subpackage cake.cake.libs.controller.components.dbacl.models
+ *
+ */
+class AclNode extends AppModel {
+/**
+ * Database configuration to use
+ *
+ * @var string
+ */
+ var $useDbConfig = ACL_DATABASE;
+/**
+ * Cache Queries
+ *
+ * @var boolean
+ */
+ var $cacheQueries = false;
+/**
+ * Creates a new ARO/ACO node
+ *
+ * @param int $linkId
+ * @param mixed $parentId
+ * @param string $alias
+ * @return boolean True on success, false on fail
+ * @access public
+ */
+ function create($linkId = 0, $parentId = null, $alias = '') {
+ parent::create();
+ if (strtolower(get_class($this)) == "aclnode") {
+ trigger_error("[acl_base] The AclBase class constructor has been called, or the class was instantiated. This class must remain abstract. Please refer to the Cake docs for ACL configuration.", E_USER_ERROR);
+ return null;
+ }
+ extract ($this->__dataVars());
+
+ if ($parentId == null || $parentId === 0) {
+ $parent = $this->find(null, 'MAX(rght) as rght', null, -1);
+ $parent['lft'] = $parent[0]['rght'];
+
+ if ($parent[0]['rght'] == null || !$parent[0]['rght']) {
+ $parent['lft'] = 0;
+ }
+ } else {
+ $parent = $this->find($this->_resolveID($parentId), null, null, 0);
+ if ($parent == null || count($parent) == 0) {
+ trigger_error("Null parent in {$class}::create()", E_USER_WARNING);
+ return null;
+ }
+ $parent = $parent[$class];
+ $this->_syncTable(1, $parent['lft'], $parent['lft']);
+ }
+ $return = $this->save(array($class => array($secondary_id => $linkId,
+ 'alias' => $alias,
+ 'lft' => $parent['lft'] + 1,
+ 'rght' => $parent['lft'] + 2)));
+ $this->id = $this->getLastInsertID();
+ return $return;
+ }
+/**
+ * Get the ARO/ACO ID with the given alias
+ *
+ * @param mixed $alias The alias of an ARO/ACO node
+ * @return mixed The ID of an ARO/ACO node, or false if not found.
+ * @access public
+ */
+ function id($alias) {
+ extract($this->__dataVars());
+ return $this->find(array($this->name . '.alias' => $alias), array($secondary_id), null, -1);
+ }
+/**
+ * Deletes the ARO/ACO node with the given ID
+ *
+ * @param mixed $id The id or alias of an ARO/ACO node
+ * @return boolean True on success, false on fail
+ * @access public
+ */
+ function delete($id) {
+ extract ($this->__dataVars());
+ $db =& ConnectionManager::getDataSource($this->useDbConfig);
+
+ $result = $this->find($this->_resolveID($id));
+ $object = $result[$class];
+ if ($object == null || count($object) == 0) {
+ return false;
+ }
+
+ $children = $this->findAll(array("{$class}.rght" => "< {$result[$class]['rght']}", "{$class}.lft" => "> {$result[$class]['lft']}"), 'id', null, null, null, -1);
+ $idList = Set::extract($children, '{n}.' . $class . '.id');
+ $idList[] = $result[$class]['id'];
+
+ $this->ArosAco->query('DELETE FROM ' . $db->fullTableName($this->ArosAco) . " WHERE {$class}_id in (" . implode(', ', $idList) . ')');
+
+ $table = $db->fullTableName($this);
+ $this->query("DELETE FROM {$table} WHERE {$table}.lft >= {$result[$class]['lft']} AND {$table}.rght <= {$result[$class]['rght']}");
+
+ $shift = 1 + $result[$class]['rght'] - $result[$class]['lft'];
+ $this->query('UPDATE ' . $table . ' SET ' . $db->name('rght') . ' = ' . $db->name('rght') . ' - ' . $shift . ' WHERE ' . $db->name('rght') . ' > ' . $result[$class]['rght']);
+ $this->query('UPDATE ' . $table . ' SET ' . $db->name('lft') . ' = ' . $db->name('lft') . ' - ' . $shift . ' WHERE ' . $db->name('lft') . ' > ' . $result[$class]['lft']);
+ return true;
+ }
+/**
+ * Sets the parent of the given node
+ *
+ * @param mixed $parentId
+ * @param mixed $id
+ * @return boolean True on success, false on failure
+ * @access public
+ */
+ function setParent($parentId = null, $id = null) {
+ if (strtolower(get_class($this)) == "aclnode") {
+ trigger_error("[acl_base] The AclBase class constructor has been called, or the class was instantiated. This class must remain abstract. Please refer to the Cake docs for ACL configuration.", E_USER_ERROR);
+ return null;
+ }
+ extract ($this->__dataVars());
+
+ if ($id == null && $this->id == false) {
+ return false;
+ } elseif ($id == null) {
+ $id = $this->id;
+ }
+ $object = $this->find($this->_resolveID($id), null, null, 0);
+
+ if ($object == null || count($object) == 0) {
+ return false;
+ }
+ $object = $object[$class];
+ $parent = $this->getParent($id);
+
+ if (($parent == null && $parentId == null) || ($parentId == $parent[$class][$secondary_id] && $parentId != null) || ($parentId == $parent[$class]['alias'] && $parentId != null)) {
+ return false;
+ }
+
+ if ($parentId == null) {
+ $newParent = $this->find(null, 'MAX(rght) as lft', null, -1);
+ $newParent = $newParent[0];
+ $newParent['rght'] = $newParent['lft'];
+ } else {
+ $newParent = $this->find($this->_resolveID($parentId), null, null, 0);
+ $newParent = $newParent[$class];
+ }
+
+ if ($parentId != null && $newParent['lft'] <= $object['lft'] && $newParent['rght'] >= $object['rght']) {
+ return false;
+ }
+ $this->_syncTable(0, $object['lft'], $object['lft']);
+
+ if ($object['lft'] < $newParent['lft']) {
+ $newParent['lft'] = $newParent['lft'] - 2;
+ $newParent['rght'] = $newParent['rght'] - 2;
+ }
+
+ if ($parentId != null) {
+ $this->_syncTable(1, $newParent['lft'], $newParent['lft']);
+ }
+ $object['lft'] = $newParent['lft'] + 1;
+ $object['rght'] = $newParent['lft'] + 2;
+ $this->save(array($class => $object));
+
+ if ($newParent['lft'] == 0) {
+ $this->_syncTable(2, $newParent['lft'], $newParent['lft']);
+ }
+ return true;
+ }
+/**
+ * Get the parent node of the given Aro or Aco
+ *
+ * @param moxed $id
+ * @return array
+ * @access public
+ */
+ function getParent($id) {
+ $path = $this->getPath($id);
+ if ($path == null || count($path) < 2) {
+ return null;
+ } else {
+ return $path[count($path) - 2];
+ }
+ }
+/**
+ * Gets the path to the given Aro or Aco
+ *
+ * @param mixed $id
+ * @return array
+ * @access public
+ */
+ function getPath($id) {
+ if (strtolower(get_class($this)) == "aclnode") {
+ trigger_error("[acl_base] The AclBase class constructor has been called, or the class was instantiated. This class must remain abstract. Please refer to the Cake docs for ACL configuration.", E_USER_ERROR);
+ return null;
+ }
+ extract ($this->__dataVars());
+ $item = $this->find($this->_resolveID($id), null, null, 0);
+
+ if ($item == null || count($item) == 0) {
+ return null;
+ }
+ return $this->findAll(array($class . '.lft' => '<= ' . $item[$class]['lft'], $class . '.rght' => '>= ' . $item[$class]['rght']), null, array($class . '.lft' => 'ASC'), null, null, 0);
+ }
+/**
+ * Get the child nodes of the given Aro or Aco
+ *
+ * @param mixed $id
+ * @return array
+ * @access public
+ */
+ function getChildren($id) {
+ if (strtolower(get_class($this)) == "aclnode") {
+ trigger_error("[acl_base] The AclBase class constructor has been called, or the class was instantiated. This class must remain abstract. Please refer to the Cake docs for ACL configuration.", E_USER_ERROR);
+ return null;
+ }
+
+ extract ($this->__dataVars());
+ $item = $this->find($this->_resolveID($id), null, null, 0);
+ return $this->findAll(array($class . '.lft' => '> ' . $item[$class]['lft'], $class . '.rght' => '< ' . $item[$class]['rght']), null, null, null, null, null, 0);
+ }
+/**
+ * Gets a conditions array to find an Aro or Aco, based on the given id or alias
+ *
+ * @param mixed $id
+ * @return array Conditions array for a find/findAll call
+ * @access public
+ */
+ function _resolveID($id) {
+ extract($this->__dataVars());
+ $key = (is_numeric($id) ? $secondary_id : 'alias');
+ return array($this->name . '.' . $key => $id);
+ }
+/**
+ * Shifts the left and right values of the aro/aco tables
+ * when a node is added or removed
+ *
+ * @param unknown_type $dir
+ * @param unknown_type $lft
+ * @param unknown_type $rght
+ * @access protected
+ */
+ function _syncTable($dir, $lft, $rght) {
+ $db =& ConnectionManager::getDataSource($this->useDbConfig);
+
+ if ($dir == 2) {
+ $shift = 1;
+ $dir = '+';
+ } else {
+ $shift = 2;
+
+ if ($dir > 0) {
+ $dir = '+';
+ } else {
+ $dir = '-';
+ }
+ }
+ $db->query('UPDATE ' . $db->fullTableName($this) . ' SET ' . $db->name('rght') . ' = ' . $db->name('rght') . ' ' . $dir . ' ' . $shift . ' WHERE ' . $db->name('rght') . ' > ' . $rght);
+ $db->query('UPDATE ' . $db->fullTableName($this) . ' SET ' . $db->name('lft') . ' = ' . $db->name('lft') . ' ' . $dir . ' ' . $shift . ' WHERE ' . $db->name('lft') . ' > ' . $lft);
+ }
+/**
+ * Infers data based on the currently-intantiated subclass.
+ *
+ * @return array
+ * @access private
+ */
+ function __dataVars() {
+ $vars = array();
+ $class = strtolower(get_class($this));
+ if ($class == 'aro') {
+ $vars['secondary_id'] = 'foreign_key';
+ } else {
+ $vars['secondary_id'] = 'object_id';
+ }
+ $vars['class'] = ucwords($class);
+ return $vars;
+ }
+}
+?> \ No newline at end of file
diff --git a/site/cake/libs/controller/components/dbacl/models/aco.php b/site/cake/libs/controller/components/dbacl/models/aco.php
new file mode 100644
index 0000000..b4a0112
--- /dev/null
+++ b/site/cake/libs/controller/components/dbacl/models/aco.php
@@ -0,0 +1,52 @@
+<?php
+/* SVN FILE: $Id: aco.php 6305 2008-01-02 02:33:56Z phpnut $ */
+/**
+ * Short description for file.
+ *
+ * Long description for file
+ *
+ * PHP versions 4 and 5
+ *
+ * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
+ * Copyright 2005-2008, Cake Software Foundation, Inc.
+ * 1785 E. Sahara Avenue, Suite 490-204
+ * Las Vegas, Nevada 89104
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
+ * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
+ * @package cake
+ * @subpackage cake.cake.libs.controller.components.dbacl.models
+ * @since CakePHP(tm) v 0.10.0.1232
+ * @version $Revision: 6305 $
+ * @modifiedby $LastChangedBy: phpnut $
+ * @lastmodified $Date: 2008-01-01 20:33:56 -0600 (Tue, 01 Jan 2008) $
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+/**
+ * Short description for file.
+ *
+ * Long description for file
+ *
+ * @package cake
+ * @subpackage cake.cake.libs.controller.components.dbacl.models
+ *
+ */
+class Aco extends AclNode{
+/**
+ * Model name
+ *
+ * @var string
+ */
+ var $name = 'Aco';
+/**
+ * Has many association
+ *
+ * @var array
+ */
+ var $hasMany = array('ArosAco');
+}
+?> \ No newline at end of file
diff --git a/site/cake/libs/controller/components/dbacl/models/acoaction.php b/site/cake/libs/controller/components/dbacl/models/acoaction.php
new file mode 100644
index 0000000..803e345
--- /dev/null
+++ b/site/cake/libs/controller/components/dbacl/models/acoaction.php
@@ -0,0 +1,56 @@
+<?php
+/* SVN FILE: $Id: acoaction.php 6305 2008-01-02 02:33:56Z phpnut $ */
+/**
+ * Short description for file.
+ *
+ * Long description for file
+ *
+ * PHP versions 4 and 5
+ *
+ * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
+ * Copyright 2005-2008, Cake Software Foundation, Inc.
+ * 1785 E. Sahara Avenue, Suite 490-204
+ * Las Vegas, Nevada 89104
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
+ * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
+ * @package cake
+ * @subpackage cake.cake.libs.controller.components.dbacl.models
+ * @since CakePHP(tm) v 0.10.0.1232
+ * @version $Revision: 6305 $
+ * @modifiedby $LastChangedBy: phpnut $
+ * @lastmodified $Date: 2008-01-01 20:33:56 -0600 (Tue, 01 Jan 2008) $
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+/**
+ * Short description.
+ */
+loadModel();
+/**
+ * Short description for file.
+ *
+ * Long description for file
+ *
+ * @package cake
+ * @subpackage cake.cake.libs.controller.components.dbacl.models
+ *
+ */
+class AcoAction extends AppModel {
+/**
+ * Model name
+ *
+ * @var string
+ */
+ var $name = 'AcoAction';
+/**
+ * Belongs to association
+ *
+ * @var string
+ */
+ var $belongsTo = 'Aco';
+}
+?> \ No newline at end of file
diff --git a/site/cake/libs/controller/components/dbacl/models/aro.php b/site/cake/libs/controller/components/dbacl/models/aro.php
new file mode 100644
index 0000000..09d431a
--- /dev/null
+++ b/site/cake/libs/controller/components/dbacl/models/aro.php
@@ -0,0 +1,52 @@
+<?php
+/* SVN FILE: $Id: aro.php 6305 2008-01-02 02:33:56Z phpnut $ */
+/**
+ * Short description for file.
+ *
+ * Long description for file
+ *
+ * PHP versions 4 and 5
+ *
+ * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
+ * Copyright 2005-2008, Cake Software Foundation, Inc.
+ * 1785 E. Sahara Avenue, Suite 490-204
+ * Las Vegas, Nevada 89104
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
+ * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
+ * @package cake
+ * @subpackage cake.cake.libs.controller.components.dbacl.models
+ * @since CakePHP(tm) v 0.10.0.1232
+ * @version $Revision: 6305 $
+ * @modifiedby $LastChangedBy: phpnut $
+ * @lastmodified $Date: 2008-01-01 20:33:56 -0600 (Tue, 01 Jan 2008) $
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+/**
+ * Short description for file.
+ *
+ * Long description for file
+ *
+ * @package cake
+ * @subpackage cake.cake.libs.controller.components.dbacl.models
+ *
+ */
+class Aro extends AclNode {
+/**
+ * Model name
+ *
+ * @var string
+ */
+ var $name = 'Aro';
+/**
+ * Has many association
+ *
+ * @var array
+ */
+ var $hasMany = array('ArosAco');
+}
+?> \ No newline at end of file
diff --git a/site/cake/libs/controller/components/dbacl/models/aros_aco.php b/site/cake/libs/controller/components/dbacl/models/aros_aco.php
new file mode 100644
index 0000000..819ead9
--- /dev/null
+++ b/site/cake/libs/controller/components/dbacl/models/aros_aco.php
@@ -0,0 +1,63 @@
+<?php
+/* SVN FILE: $Id: aros_aco.php 6305 2008-01-02 02:33:56Z phpnut $ */
+/**
+ * Short description for file.
+ *
+ * Long description for file
+ *
+ * PHP versions 4 and 5
+ *
+ * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
+ * Copyright 2005-2008, Cake Software Foundation, Inc.
+ * 1785 E. Sahara Avenue, Suite 490-204
+ * Las Vegas, Nevada 89104
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
+ * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
+ * @package cake
+ * @subpackage cake.cake.libs.controller.components.dbacl.models
+ * @since CakePHP(tm) v 0.10.0.1232
+ * @version $Revision: 6305 $
+ * @modifiedby $LastChangedBy: phpnut $
+ * @lastmodified $Date: 2008-01-01 20:33:56 -0600 (Tue, 01 Jan 2008) $
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+/**
+ * Short description for file.
+ *
+ * Long description for file
+ *
+ * @package cake
+ * @subpackage cake.cake.libs.controller.components.dbacl.models
+ */
+class ArosAco extends AppModel {
+/**
+ * Cache Queries
+ *
+ * @var boolean
+ */
+ var $cacheQueries = false;
+/**
+ * Model name
+ *
+ * @var string
+ */
+ var $name = 'ArosAco';
+/**
+ * Table this model uses
+ *
+ * @var string
+ */
+ var $useTable = 'aros_acos';
+/**
+ * Belongs to association
+ *
+ * @var array
+ */
+ var $belongsTo = array('Aro', 'Aco');
+}
+?> \ No newline at end of file
diff --git a/site/cake/libs/controller/components/iniacl/ini_acl.php b/site/cake/libs/controller/components/iniacl/ini_acl.php
new file mode 100644
index 0000000..d578807
--- /dev/null
+++ b/site/cake/libs/controller/components/iniacl/ini_acl.php
@@ -0,0 +1,184 @@
+<?php
+/* SVN FILE: $Id: ini_acl.php 6305 2008-01-02 02:33:56Z phpnut $ */
+/**
+ * This is core configuration file.
+ *
+ * Use it to configure core behaviour ofCake.
+ *
+ * PHP versions 4 and 5
+ *
+ * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
+ * Copyright 2005-2008, Cake Software Foundation, Inc.
+ * 1785 E. Sahara Avenue, Suite 490-204
+ * Las Vegas, Nevada 89104
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
+ * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
+ * @package cake
+ * @subpackage cake.cake.libs.controller.componenets.iniacl
+ * @since CakePHP(tm) v 0.2.9
+ * @version $Revision: 6305 $
+ * @modifiedby $LastChangedBy: phpnut $
+ * @lastmodified $Date: 2008-01-01 20:33:56 -0600 (Tue, 01 Jan 2008) $
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+/**
+ * load AclBase
+ */
+uses('controller/components/acl_base');
+/**
+ * In this file you can extend the AclBase.
+ *
+ * @package cake
+ * @subpackage cake.cake.libs.controller.componenets.iniacl
+ */
+class INI_ACL extends AclBase {
+/**
+ * Array with configuration, parsed from ini file
+ *
+ * @var array
+ */
+ var $config = null;
+/**
+ * Constructor
+ *
+ */
+ function __construct() {
+ }
+
+/**
+ * Main ACL check function. Checks to see if the ARO (access request object) has access to the ACO (access control object).
+ * Looks at the acl.ini.php file for permissions (see instructions in/config/acl.ini.php).
+ *
+ * @param string $aro
+ * @param string $aco
+ * @return boolean
+ * @access public
+ */
+ function check($aro, $aco, $acoAction = null) {
+ if ($this->config == null) {
+ $this->config = $this->readConfigFile(CONFIGS . 'acl.ini.php');
+ }
+ $aclConfig = $this->config;
+
+ //First, if the user is specifically denied, then DENY
+ if (isset($aclConfig[$aro]['deny'])) {
+ $userDenies = $this->arrayTrim(explode(",", $aclConfig[$aro]['deny']));
+
+ if (array_search($aco, $userDenies)) {
+ //echo "User Denied!";
+ return false;
+ }
+ }
+
+ //Second, if the user is specifically allowed, then ALLOW
+ if (isset($aclConfig[$aro]['allow'])) {
+ $userAllows = $this->arrayTrim(explode(",", $aclConfig[$aro]['allow']));
+
+ if (array_search($aco, $userAllows)) {
+ //echo "User Allowed!";
+ return true;
+ }
+ }
+
+ //Check group permissions
+ if (isset($aclConfig[$aro]['groups'])) {
+ $userGroups = $this->arrayTrim(explode(",", $aclConfig[$aro]['groups']));
+
+ foreach ($userGroups as $group) {
+ //If such a group exists,
+ if (array_key_exists($group, $aclConfig)) {
+ //If the group is specifically denied, then DENY
+ if (isset($aclConfig[$group]['deny'])) {
+ $groupDenies=$this->arrayTrim(explode(",", $aclConfig[$group]['deny']));
+
+ if (array_search($aco, $groupDenies)) {
+ //echo("Group Denied!");
+ return false;
+ }
+ }
+
+ //If the group is specifically allowed, then ALLOW
+ if (isset($aclConfig[$group]['allow'])) {
+ $groupAllows = $this->arrayTrim(explode(",", $aclConfig[$group]['allow']));
+
+ if (array_search($aco, $groupAllows)) {
+ //echo("Group Allowed!");
+ return true;
+ }
+ }
+ }
+ }
+ }
+
+ //Default, DENY
+ //echo("DEFAULT: DENY.");
+ return false;
+ }
+
+/**
+ * Parses an INI file and returns an array that reflects the INI file's section structure. Double-quote friendly.
+ *
+ * @param string $fileName
+ * @return array
+ */
+ function readConfigFile($fileName) {
+ $fileLineArray = file($fileName);
+
+ foreach ($fileLineArray as $fileLine) {
+ $dataLine = trim($fileLine);
+ $firstChar = substr($dataLine, 0, 1);
+
+ if ($firstChar != ';' && $dataLine != '') {
+ if ($firstChar == '[' && substr($dataLine, -1, 1) == ']') {
+ $sectionName = preg_replace('/[\[\]]/', '', $dataLine);
+ } else {
+ $delimiter = strpos($dataLine, '=');
+
+ if ($delimiter > 0) {
+ $key = strtolower(trim(substr($dataLine, 0, $delimiter)));
+ $value = trim(substr($dataLine, $delimiter + 1));
+
+ if (substr($value, 0, 1) == '"' && substr($value, -1) == '"') {
+ $value = substr($value, 1, -1);
+ }
+
+ $iniSetting[$sectionName][$key]=stripcslashes($value);
+ } else {
+ if (!isset($sectionName)) {
+ $sectionName = '';
+ }
+
+ $iniSetting[$sectionName][strtolower(trim($dataLine))]='';
+ }
+ }
+ } else {
+ }
+ }
+
+ return $iniSetting;
+ }
+
+/**
+ * Removes trailing spaces on all array elements (to prepare for searching)
+ *
+ * @param array $array
+ * @return array
+ */
+ function arrayTrim($array) {
+ foreach ($array as $element) {
+ $element = trim($element);
+ }
+
+ //Adding this element keeps array_search from returning 0:
+ //0 is the first key, which may be correct, but 0 is interpreted as false.
+ //Adding this element makes all the keys be positive integers.
+ array_unshift($array, "");
+ return $array;
+ }
+}
+?> \ No newline at end of file
diff --git a/site/cake/libs/controller/components/request_handler.php b/site/cake/libs/controller/components/request_handler.php
new file mode 100644
index 0000000..5dd7953
--- /dev/null
+++ b/site/cake/libs/controller/components/request_handler.php
@@ -0,0 +1,412 @@
+<?php
+/* SVN FILE: $Id: request_handler.php 6305 2008-01-02 02:33:56Z phpnut $ */
+/**
+ * Request object for handling alternative HTTP requests
+ *
+ * Alternative HTTP requests can come from wireless units like mobile phones, palmtop computers, and the like.
+ * These units have no use for Ajax requests, and this Component can tell how Cake should respond to the different
+ * needs of a handheld computer and a desktop machine.
+ *
+ * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
+ * Copyright 2005-2008, Cake Software Foundation, Inc.
+ * 1785 E. Sahara Avenue, Suite 490-204
+ * Las Vegas, Nevada 89104
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
+ * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
+ * @package cake
+ * @subpackage cake.cake.libs.controller.components
+ * @since CakePHP(tm) v 0.10.4.1076
+ * @version $Revision: 6305 $
+ * @modifiedby $LastChangedBy: phpnut $
+ * @lastmodified $Date: 2008-01-01 20:33:56 -0600 (Tue, 01 Jan 2008) $
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+if (!defined('REQUEST_MOBILE_UA')) {
+ define('REQUEST_MOBILE_UA',
+ '(AvantGo|BlackBerry|DoCoMo|NetFront|Nokia|PalmOS|PalmSource|portalmmm|Plucker|ReqwirelessWeb|SonyEricsson|Symbian|UP\.Browser|Windows CE|Xiino)');
+}
+/**
+ * Request object for handling alternative HTTP requests
+ *
+ * @package cake
+ * @subpackage cake.cake.libs.controller.components
+ *
+ */
+class RequestHandlerComponent extends Object{
+/**
+ * Enter description here...
+ *
+ * @var object
+ * @access public
+ */
+ var $controller = true;
+/**
+ * The layout that will be switched to for Ajax requests
+ *
+ * @var string
+ * @access public
+ * @see RequestHandler::setAjax()
+ */
+ var $ajaxLayout = 'ajax';
+/**
+ * Determines whether or not callbacks will be fired on this component
+ *
+ * @var boolean
+ * @access public
+ */
+ var $disableStartup = false;
+/**
+ * Friendly content-type mappings used to set response types and determine
+ * request types. Can be modified with RequestHandler::setContent()
+ *
+ * @var array
+ * @access private
+ * @see RequestHandlerComponent::setContent
+ */
+ var $__requestContent = array(
+ 'js' => 'text/javascript',
+ 'css' => 'text/css',
+ 'html' => 'text/html',
+ 'form' => 'application/x-www-form-urlencoded',
+ 'file' => 'multipart/form-data',
+ 'xhtml' => array('application/xhtml+xml', 'application/xhtml', 'text/xhtml'),
+ 'xml' => array('application/xml', 'text/xml'),
+ 'rss' => 'application/rss+xml',
+ 'atom' => 'application/atom+xml'
+ );
+/**
+ * Content-types accepted by the client. If extension parsing is enabled in the
+ * Router, and an extension is detected, the corresponding content-type will be
+ * used as the overriding primary content-type accepted.
+ *
+ * @var array
+ * @access private
+ */
+ var $__acceptTypes = array();
+/**
+ * Constructor. Parses the accepted content types accepted by the client using
+ * HTTP_ACCEPT
+ *
+ * @access public
+ * @return void
+ */
+ function __construct() {
+ $this->__acceptTypes = explode(',', env('HTTP_ACCEPT'));
+
+ foreach ($this->__acceptTypes as $i => $type) {
+ if (strpos($type, ';')) {
+ $type = explode(';', $type);
+ $this->__acceptTypes[$i] = $type[0];
+ }
+ }
+ parent::__construct();
+ }
+/**
+ * Startup
+ *
+ * @param object A reference to the controller
+ * @return null
+ * @access public
+ */
+ function startup(&$controller) {
+ if ($this->disableStartup) {
+ return;
+ }
+ $this->setAjax($controller);
+ }
+/**
+ * Sets a controller's layout based on whether or not the current call is Ajax
+ *
+ * Add UTF-8 header for IE6 on XPsp2 bug if RequestHandlerComponent::isAjax()
+ *
+ * @param object The controller object
+ * @return null
+ * @access public
+ */
+ function setAjax(&$controller) {
+ if ($this->isAjax()) {
+ $controller->layout = $this->ajaxLayout;
+ // Add UTF-8 header for IE6 on XPsp2 bug
+ header ('Content-Type: text/html; charset=UTF-8');
+ }
+ }
+/**
+ * Returns true if the current call is from Ajax, false otherwise
+ *
+ * @return bool True if call is Ajax
+ * @access public
+ */
+ function isAjax() {
+ if (env('HTTP_X_REQUESTED_WITH') != null) {
+ return env('HTTP_X_REQUESTED_WITH') == "XMLHttpRequest";
+ } else {
+ return false;
+ }
+ }
+/**
+ * Returns true if the current call accepts an XML response, false otherwise
+ *
+ * @return bool True if client accepts an XML response
+ * @access public
+ */
+ function isXml() {
+ return $this->accepts('xml');
+ }
+/**
+ * Returns true if the current call accepts an RSS response, false otherwise
+ *
+ * @return bool True if client accepts an RSS response
+ * @access public
+ */
+ function isRss() {
+ return $this->accepts('rss');
+ }
+/**
+ * Returns true if the current call accepts an RSS response, false otherwise
+ *
+ * @return bool True if client accepts an RSS response
+ * @access public
+ */
+ function isAtom() {
+ return $this->accepts('atom');
+ }
+/**
+ * Returns true if the current call a POST request
+ *
+ * @return bool True if call is a POST
+ * @access public
+ */
+ function isPost() {
+ return (strtolower(env('REQUEST_METHOD')) == 'post');
+ }
+/**
+ * Returns true if the current call a PUT request
+ *
+ * @return bool True if call is a PUT
+ * @access public
+ */
+ function isPut() {
+ return (strtolower(env('REQUEST_METHOD')) == 'put');
+ }
+/**
+ * Returns true if the current call a GET request
+ *
+ * @return bool True if call is a GET
+ * @access public
+ */
+ function isGet() {
+ return (strtolower(env('REQUEST_METHOD')) == 'get');
+ }
+/**
+ * Returns true if the current call a DELETE request
+ *
+ * @return bool True if call is a DELETE
+ * @access public
+ */
+ function isDelete() {
+ return (strtolower(env('REQUEST_METHOD')) == 'delete');
+ }
+/**
+ * Gets Prototype version if call is Ajax, otherwise empty string.
+ * The Prototype library sets a special "Prototype version" HTTP header.
+ *
+ * @return string Prototype version of component making Ajax call
+ * @access public
+ */
+ function getAjaxVersion() {
+ if (env('HTTP_X_PROTOTYPE_VERSION') != null) {
+ return env('HTTP_X_PROTOTYPE_VERSION');
+ }
+ return false;
+ }
+/**
+ * Adds/sets the Content-type(s) for the given name
+ *
+ * @param string $name The name of the Content-type, i.e. "html", "xml", "css"
+ * @param mixed $type The Content-type or array of Content-types assigned to the name
+ * @return void
+ * @access public
+ */
+ function setContent($name, $type) {
+ $this->__requestContent[$name] = $type;
+ }
+/**
+ * Gets the server name from which this request was referred
+ *
+ * @return string Server address
+ * @access public
+ */
+ function getReferrer() {
+ if (env('HTTP_HOST') != null) {
+ $sess_host = env('HTTP_HOST');
+ }
+
+ if (env('HTTP_X_FORWARDED_HOST') != null) {
+ $sess_host = env('HTTP_X_FORWARDED_HOST');
+ }
+ return trim(preg_replace('/:.*/', '', $sess_host));
+ }
+/**
+ * Gets remote client IP
+ *
+ * @return string Client IP address
+ * @access public
+ */
+ function getClientIP() {
+ if (env('HTTP_X_FORWARDED_FOR') != null) {
+ $ipaddr = preg_replace('/,.*/', '', env('HTTP_X_FORWARDED_FOR'));
+ } else {
+ if (env('HTTP_CLIENT_IP') != null) {
+ $ipaddr = env('HTTP_CLIENT_IP');
+ } else {
+ $ipaddr = env('REMOTE_ADDR');
+ }
+ }
+
+ if (env('HTTP_CLIENTADDRESS') != null) {
+ $tmpipaddr = env('HTTP_CLIENTADDRESS');
+
+ if (!empty($tmpipaddr)) {
+ $ipaddr = preg_replace('/,.*/', '', $tmpipaddr);
+ }
+ }
+ return trim($ipaddr);
+ }
+/**
+ * Returns true if user agent string matches a mobile web browser
+ *
+ * @return bool True if user agent is a mobile web browser
+ * @access public
+ */
+ function isMobile() {
+ return (preg_match('/' . REQUEST_MOBILE_UA . '/i', env('HTTP_USER_AGENT')) > 0);
+ }
+/**
+ * Strips extra whitespace from output
+ *
+ * @param string $str
+ * @return string
+ * @access public
+ */
+ function stripWhitespace($str) {
+ $r = preg_replace('/[\n\r\t]+/', '', $str);
+ return preg_replace('/\s{2,}/', ' ', $r);
+ }
+/**
+ * Strips image tags from output
+ *
+ * @param string $str
+ * @return string
+ * @access public
+ */
+ function stripImages($str) {
+ $str = preg_replace('/(<a[^>]*>)(<img[^>]+alt=")([^"]*)("[^>]*>)(<\/a>)/i', '$1$3$5<br />', $str);
+ $str = preg_replace('/(<img[^>]+alt=")([^"]*)("[^>]*>)/i', '$2<br />', $str);
+ $str = preg_replace('/<img[^>]*>/i', '', $str);
+ return $str;
+ }
+/**
+ * Strips scripts and stylesheets from output
+ *
+ * @param string $str
+ * @return string
+ * @access public
+ */
+ function stripScripts($str) {
+ return preg_replace('/(<link[^>]+rel="[^"]*stylesheet"[^>]*>|<img[^>]*>|style="[^"]*")|<script[^>]*>.*?<\/script>|<style[^>]*>.*?<\/style>|<!--.*?-->/i', '', $str);
+ }
+/**
+ * Strips extra whitespace, images, scripts and stylesheets from output
+ *
+ * @param string $str
+ * @return string
+ * @access public
+ */
+ function stripAll($str) {
+ $str = $this->stripWhitespace($str);
+ $str = $this->stripImages($str);
+ $str = $this->stripScripts($str);
+ return $str;
+ }
+/**
+ * Strips the specified tags from output
+ *
+ * @return string
+ * @access public
+ */
+ function stripTags() {
+ $params = params(func_get_args());
+ $str = $params[0];
+
+ for ($i = 1; $i < count($params); $i++) {
+ $str = preg_replace('/<' . $params[$i] . '[^>]*>/i', '', $str);
+ $str = preg_replace('/<\/' . $params[$i] . '[^>]*>/i', '', $str);
+ }
+ return $str;
+ }
+
+/**
+ * Determines which content types the client accepts
+ *
+ * @param mixed $type Can be null (or no parameter), a string type name, or an
+ * array of types
+ * @return mixed If null or no parameter is passed, returns an array of content
+ * types the client accepts. If a string is passed, returns true
+ * if the client accepts it. If an array is passed, returns true
+ * if the client accepts one or more elements in the array.
+ * @access public
+ */
+ function accepts($type = null) {
+ if ($type == null) {
+ return $this->__acceptTypes;
+ } elseif (is_array($type)) {
+ foreach ($type as $t) {
+ if ($this->accepts($t) == true) {
+ return true;
+ }
+ }
+ return false;
+ } elseif (is_string($type)) {
+ // If client only accepts */*, then assume default HTML browser
+ if ($type == 'html' && $this->__acceptTypes === array('*/*')) {
+ return true;
+ }
+
+ if (!in_array($type, array_keys($this->__requestContent))) {
+ return false;
+ }
+
+ $content = $this->__requestContent[$type];
+
+ if (is_array($content)) {
+ foreach ($content as $c) {
+ if (in_array($c, $this->__acceptTypes)) {
+ return true;
+ }
+ }
+ } else {
+ if (in_array($content, $this->__acceptTypes)) {
+ return true;
+ }
+ }
+ }
+ }
+/**
+ * Determines which content types the client prefers
+ *
+ * @param mixed $type
+ * @returns mixed
+ * @access public
+ */
+ function prefers($type = null) {
+ if ($type == null) {
+ return $this->accepts(null);
+ }
+ }
+}
+?> \ No newline at end of file
diff --git a/site/cake/libs/controller/components/security.php b/site/cake/libs/controller/components/security.php
new file mode 100644
index 0000000..e040737
--- /dev/null
+++ b/site/cake/libs/controller/components/security.php
@@ -0,0 +1,202 @@
+<?php
+/* SVN FILE: $Id: security.php 6305 2008-01-02 02:33:56Z phpnut $ */
+/**
+ * Short description for file.
+ *
+ * Long description for file
+ *
+ * PHP versions 4 and 5
+ *
+ * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
+ * Copyright 2005-2008, Cake Software Foundation, Inc.
+ * 1785 E. Sahara Avenue, Suite 490-204
+ * Las Vegas, Nevada 89104
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
+ * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
+ * @package cake
+ * @subpackage cake.cake.libs.controller.components
+ * @since CakePHP(tm) v 0.10.8.2156
+ * @version $Revision: 6305 $
+ * @modifiedby $LastChangedBy: phpnut $
+ * @lastmodified $Date: 2008-01-01 20:33:56 -0600 (Tue, 01 Jan 2008) $
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+/**
+ * Short description for file.
+ *
+ * Long description for file
+ *
+ * @package cake
+ * @subpackage cake.cake.libs.controller.components
+ */
+class SecurityComponent extends Object {
+/**
+ * Holds an instance of the core Security object
+ *
+ * @var object Security
+ * @access public
+ */
+ var $Security = null;
+/**
+ * The controller method that will be called if this request is black-hole'd
+ *
+ * @var string
+ * @access public
+ */
+ var $blackHoleCallback = null;
+/**
+ * List of controller actions for which a POST request is required
+ *
+ * @var array
+ * @access public
+ * @see SecurityComponent::requirePost()
+ */
+ var $requirePost = array();
+/**
+ * List of actions that require a valid authentication key
+ *
+ * @var array
+ * @access public
+ * @see SecurityComponent::requireAuth()
+ */
+ var $requireAuth = array();
+/**
+ * Controllers from which actions of the current controller are allowed to receive
+ * requests.
+ *
+ * @var array
+ * @see SecurityComponent::requireAuth()
+ */
+ var $allowedControllers = array();
+/**
+ * Actions from which actions of the current controller are allowed to receive
+ * requests.
+ *
+ * @var array
+ * @see SecurityComponent::requireAuth()
+ */
+ var $allowedActions = array();
+/**
+ * Other components used by the Security component
+ *
+ * @var array
+ * @access public
+ */
+ var $components = array('RequestHandler', 'Session');
+/**
+ * Security class constructor
+ */
+ function __construct () {
+ $this->Security = Security::getInstance();
+ }
+/**
+ * Component startup. All security checking happens here.
+ *
+ * @param object $controller
+ * @return unknown
+ * @access public
+ */
+ function startup(&$controller) {
+ if (is_array($this->requirePost) && !empty($this->requirePost)) {
+
+ if (in_array($controller->action, $this->requirePost)) {
+
+ if (!$this->RequestHandler->isPost()) {
+
+ if (!$this->blackHole($controller)) {
+ return null;
+ }
+ }
+ }
+ }
+
+ if (is_array($this->requireAuth) && !empty($this->requireAuth) && !empty($controller->params['form'])) {
+ if (in_array($controller->action, $this->requireAuth)) {
+
+ if (!isset($controller->params['data']['_Token'])) {
+
+ if (!$this->blackHole($controller)) {
+ return null;
+ }
+ }
+ $token = $controller->params['data']['_Token']['key'];
+
+ if ($this->Session->check('_Token')) {
+ $tData = $this->Session->read('_Token');
+ if (!(intval($tData['expires']) > strtotime('now')) || $tData['key'] !== $token) {
+
+ if (!$this->blackHole($controller)) {
+ return null;
+ }
+ }
+
+ if (!empty($tData['allowedControllers']) && !in_array($controller->params['controller'], $tData['allowedControllers']) ||!empty($tData['allowedActions']) && !in_array($controller->params['action'], $tData['allowedActions'])) {
+ if (!$this->blackHole($controller)) {
+ return null;
+ }
+ }
+ } else {
+ if (!$this->blackHole($controller)) {
+ return null;
+ }
+ }
+ }
+ }
+
+ if (!isset($controller->params['requested']) || $controller->params['requested'] != 1) {
+ // Add auth key for new form posts
+ $authKey = Security::generateAuthKey();
+ $expires = strtotime('+'.Security::inactiveMins().' minutes');
+ $token = array(
+ 'key' => $authKey,
+ 'expires' => $expires,
+ 'allowedControllers' => $this->allowedControllers,
+ 'allowedActions' => $this->allowedActions
+ );
+ if (!isset($controller->params['data'])) {
+ $controller->params['data'] = array();
+ }
+ $controller->params['_Token'] = $token;
+ $this->Session->write('_Token', $token);
+ }
+ }
+/**
+ * Black-hole an invalid request with a 404 error or custom callback
+ *
+ * @param object $controller
+ * @return callback in controller
+ * @access public
+ */
+ function blackHole(&$controller) {
+ if ($this->blackHoleCallback == null) {
+ header('HTTP/1.0 404 Not Found');
+ exit();
+ } elseif (method_exists($controller, $this->blackHoleCallback)) {
+ return $controller->{$this->blackHoleCallback}();
+ }
+ }
+/**
+ * Sets the actions that require a POST request, or empty for all actions
+ *
+ * @access public
+ * @return void
+ */
+ function requirePost() {
+ $this->requirePost = func_get_args();
+ }
+/**
+ * Sets the actions that require an authenticated request, or empty for all actions
+ *
+ * @access public
+ * @return void
+ */
+ function requireAuth() {
+ $this->requireAuth = func_get_args();
+ }
+}
+?> \ No newline at end of file
diff --git a/site/cake/libs/controller/components/session.php b/site/cake/libs/controller/components/session.php
new file mode 100644
index 0000000..a3348e6
--- /dev/null
+++ b/site/cake/libs/controller/components/session.php
@@ -0,0 +1,375 @@
+<?php
+/* SVN FILE: $Id: session.php 6305 2008-01-02 02:33:56Z phpnut $ */
+/**
+ * Short description for file.
+ *
+ * Long description for file
+ * Patches: 2 MOZILLA patches
+ *
+ * PHP versions 4 and 5
+ *
+ * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
+ * Copyright 2005-2008, Cake Software Foundation, Inc.
+ * 1785 E. Sahara Avenue, Suite 490-204
+ * Las Vegas, Nevada 89104
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
+ * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
+ * @package cake
+ * @subpackage cake.cake.libs.controller.components
+ * @since CakePHP(tm) v 0.10.0.1232
+ * @version $Revision: 6305 $
+ * @modifiedby $LastChangedBy: phpnut $
+ * @lastmodified $Date: 2008-01-01 20:33:56 -0600 (Tue, 01 Jan 2008) $
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+/**
+ * Session Component.
+ *
+ * Session handling from the controller.
+ *
+ * @package cake
+ * @subpackage cake.cake.libs.controller.components
+ *
+ */
+class SessionComponent extends CakeSession {
+/**
+ * Used to determine if methods implementation is used, or bypassed
+ *
+ * @var boolean
+ * @access private
+ */
+ var $__active = true;
+/**
+ * Used to determine if Session has been started
+ *
+ * @var boolean
+ * @access private
+ */
+ var $__started = false;
+/**
+ * Used to determine if request are from an Ajax request
+ *
+ * @var boolean
+ * @access private
+ */
+ var $__bare = 0;
+
+ var $__controller = null;
+/**
+ * Class constructor
+ *
+ * @param string $base The base path for the Session
+ */
+ function __construct($base = null) {
+ if ((!defined('AUTO_SESSION') || AUTO_SESSION === true)
+/** BEGIN MOZILLA PATCH **/
+ || isset($_COOKIE[CAKE_SESSION_COOKIE])) {
+/** END MOZILLA PATCH **/
+ parent::__construct($base);
+ } else {
+ $this->__active = false;
+ }
+ }
+/**
+ * Initializes the component, gets a reference to Controller::$param['bare'].
+ *
+ * @param object $controller A reference to the controller
+ * @access public
+ */
+ function initialize(&$controller) {
+ if (isset($controller->params['bare'])) {
+ $this->__bare = $controller->params['bare'];
+ }
+
+ $this->__controller = $controller;
+ }
+/**
+ * Startup method.
+ *
+ * @param object $controller Instantiating controller
+ * @access public
+ */
+ function startup(&$controller) {
+ if ($this->__started === false) {
+ $this->__start();
+ }
+ }
+/**
+ * Starts Session on if 'Session.start' is set to false in core.php
+ *
+ * @param string $base The base path for the Session
+ * @access public
+ */
+ function activate($base = null) {
+ if ($this->__active === true) {
+ return;
+ }
+ parent::__construct($base);
+ $this->__active = true;
+ }
+/**
+ * Used to write a value to a session key.
+ *
+ * In your controller: $this->Session->write('Controller.sessKey', 'session value');
+ *
+ * @param string $name The name of the key your are setting in the session.
+ * This should be in a Controller.key format for better organizing
+ * @param string $value The value you want to store in a session.
+ * @access public
+ */
+ function write($name, $value = null) {
+ if ($this->__active === true) {
+ $this->__start();
+ if (is_array($name)) {
+ foreach ($name as $key => $value) {
+ if (parent::write($key, $value) === false) {
+ return false;
+ }
+ }
+ return true;
+ }
+ if (parent::write($name, $value) === false) {
+ return false;
+ }
+ return true;
+ }
+ return false;
+ }
+/**
+ * Used to read a session values for a key or return values for all keys.
+ *
+ * In your controller: $this->Session->read('Controller.sessKey');
+ * Calling the method without a param will return all session vars
+ *
+ * @param string $name the name of the session key you want to read
+ * @return mixed value from the session vars
+ * @access public
+ */
+ function read($name = null) {
+ if ($this->__active === true) {
+ $this->__start();
+ return parent::read($name);
+ }
+ return false;
+ }
+/**
+ * Used to delete a session variable.
+ *
+ * In your controller: $this->Session->del('Controller.sessKey');
+ *
+ * @param string $name the name of the session key you want to delete
+ * @return boolean true is session variable is set and can be deleted, false is variable was not set.
+ * @access public
+ */
+ function del($name) {
+ if ($this->__active === true) {
+ $this->__start();
+ return parent::del($name);
+ }
+ return false;
+ }
+/**
+ * Wrapper for SessionComponent::del();
+ *
+ * In your controller: $this->Session->delete('Controller.sessKey');
+ *
+ * @param string $name the name of the session key you want to delete
+ * @return boolean true is session variable is set and can be deleted, false is variable was not set.
+ * @access public
+ */
+ function delete($name) {
+ if ($this->__active === true) {
+ $this->__start();
+ return $this->del($name);
+ }
+ return false;
+ }
+/**
+ * Used to check if a session variable is set
+ *
+ * In your controller: $this->Session->check('Controller.sessKey');
+ *
+ * @param string $name the name of the session key you want to check
+ * @return boolean true is session variable is set, false if not
+ * @access public
+ */
+ function check($name) {
+ if ($this->__active === true) {
+ $this->__start();
+ return parent::check($name);
+ }
+ return false;
+ }
+/**
+ * Used to determine the last error in a session.
+ *
+ * In your controller: $this->Session->error();
+ *
+ * @return string Last session error
+ * @access public
+ */
+ function error() {
+ if ($this->__active === true) {
+ $this->__start();
+ return parent::error();
+ }
+ return false;
+ }
+/**
+ * Used to set a session variable that can be used to output messages in the view.
+ *
+ * In your controller: $this->Session->setFlash('This has been saved');
+ *
+ * Additional params below can be passed to customize the output, or the Message.[key]
+ *
+ * @param string $message Message to be flashed
+ * @param string $layout Layout to wrap flash message in
+ * @param array $params Parameters to be sent to layout as view variables
+ * @param string $key Message key, default is 'flash'
+ * @access public
+ */
+ function setFlash($message, $layout = 'default', $params = array(), $key = 'flash') {
+ if ($this->__active === true) {
+ $this->__start();
+ $this->write('Message.' . $key, compact('message', 'layout', 'params'));
+ }
+ }
+/**
+ * Used to renew a session id
+ *
+ * In your controller: $this->Session->renew();
+ *
+ * @access public
+ */
+ function renew() {
+ if ($this->__active === true) {
+ $this->__start();
+ parent::renew();
+ }
+ }
+/**
+ * Used to check for a valid session.
+ *
+ * In your controller: $this->Session->valid();
+ *
+ * @return boolean true is session is valid, false is session is invalid
+ * @access public
+ */
+ function valid() {
+ if ($this->__active === true) {
+ $this->__start();
+ return parent::valid();
+ }
+ return false;
+ }
+/**
+ * Used to destroy sessions
+ *
+ * In your controller: $this->Session->destroy();
+ *
+ * @access public
+ */
+ function destroy() {
+ if ($this->__active === true) {
+ $this->__start();
+ parent::destroy();
+ }
+ }
+/**
+ * Returns Session id
+ *
+ * If $id is passed in a beforeFilter, the Session will be started
+ * with the specified id
+ *
+ * @param $id string
+ * @return string
+ * @access public
+ */
+ function id($id = null) {
+ return parent::id($id);
+ }
+/**
+ * Starts Session if SessionComponent is used in Controller::beforeFilter(),
+ * or is called from
+ * MOZILLA PATCH: I added the check for $_COOKIE being set, and the calls to
+ * checkValid().
+ *
+ * @access private
+ */
+ function __start(){
+ // Only start a session if our cookie is set. see start() for more details.
+ if (isset($_COOKIE[CAKE_SESSION_COOKIE])) {
+ //echo 'cookie is set';
+ if ($this->__started === false) {
+ if ($this->__bare === 0) {
+ if (!$this->id() && parent::start()) {
+ $this->__started = true;
+ $this->checkValid();
+ } else {
+ $this->__started = parent::start();
+ $this->checkValid();
+ }
+ }
+ }
+ }
+ return $this->__started;
+ }
+
+/** BEGIN MOZILLA PATCH (@author clouserw@mozilla.com)**/
+/**
+ * Manually start a session. CakePHP wants to start a session for every visitor which
+ * is nuts. In __start() we only activate the session starting code if the AMO
+ * cookie is set. That means that we need to set the cookie manually for the
+ * sessions we do want - that's this function.
+ */
+ function start($expireTime) {
+ // the strip_plugin() stuff is taken from cake/libs/controller/component.php.
+ // Session is a special case in cake and gets special init info. Without
+ // this we end up setting a cookie with '/' for a path and trying to destory
+ // a cookie with a different path. If all parameters aren't the same,
+ // the browser won't destroy the cookie.
+ $this->activate(strip_plugin($this->__controller->base, $this->__controller->plugin) . '/');
+ $this->__started = parent::start($expireTime);
+ return $this->__started;
+ }
+
+/**
+ * Manually end a session. When a user logs out, CakePHP doesn't delete the cookie.
+ * Since the cookie is set when they come back, normally they would automatically get a new
+ * session (from the __start()) function. I added the checkValid() calls in
+ * __start() to fix this.
+ */
+ function stop() {
+ if ($this->__active === true) {
+ $this->destroy();
+ $this->__active = false;
+ return true;
+ }
+ return false;
+ }
+
+/**
+ * Verify a session can be traced to an actual user. CakePHP checks for a valid
+ * session, but it doesn't actually make sure it's connected to a user. This means
+ * anyone could make a cookie named CAKE_SESSION_COOKIE and it would be considered valid.
+ * This function invalidates the cookie if it's not connected to a user.
+ */
+ function checkValid() {
+ parent::_checkValid();
+
+ if ($this->valid) {
+ if ($this->read('User') == null) {
+ $this->stop();
+ }
+ }
+
+ }
+/** END MOZILLA PATCH **/
+
+}
+?>
diff --git a/site/cake/libs/controller/controller.php b/site/cake/libs/controller/controller.php
new file mode 100644
index 0000000..71c8d15
--- /dev/null
+++ b/site/cake/libs/controller/controller.php
@@ -0,0 +1,998 @@
+<?php
+/* SVN FILE: $Id: controller.php 6305 2008-01-02 02:33:56Z phpnut $ */
+/**
+ * Base controller class.
+ *
+ * PHP versions 4 and 5
+ *
+ * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
+ * Copyright 2005-2008, Cake Software Foundation, Inc.
+ * 1785 E. Sahara Avenue, Suite 490-204
+ * Las Vegas, Nevada 89104
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
+ * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
+ * @package cake
+ * @subpackage cake.cake.libs.controller
+ * @since CakePHP(tm) v 0.2.9
+ * @version $Revision: 6305 $
+ * @modifiedby $LastChangedBy: phpnut $
+ * @lastmodified $Date: 2008-01-01 20:33:56 -0600 (Tue, 01 Jan 2008) $
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+/**
+ * Include files
+ */
+ uses(DS . 'controller' . DS . 'component', DS . 'view' . DS . 'view');
+/**
+ * Controller
+ *
+ * Application controller (controllers are where you put all the actual code)
+ * Provides basic functionality, such as rendering views (aka displaying templates).
+ * Automatically selects model name from on singularized object class name
+ * and creates the model object if proper class exists.
+ *
+ * @package cake
+ * @subpackage cake.cake.libs.controller
+ *
+ */
+class Controller extends Object{
+/**
+ * Name of the controller.
+ *
+ * @var string
+ * @access public
+ */
+ var $name = null;
+/**
+ * Stores the current URL (for links etc.)
+ *
+ * @var string
+ * @access public
+ */
+ var $here = null;
+/**
+ * The webroot of the application
+ *
+ * @var string
+ * @access public
+ */
+ var $webroot = null;
+/**
+ * Action to be performed.
+ *
+ * @var string
+ * @access public
+ */
+ var $action = null;
+/**
+ * An array of names of models the particular controller wants to use.
+ *
+ * @var mixed A single name as a string or a list of names as an array.
+ * @access protected
+ */
+ var $uses = false;
+/**
+ * An array of names of built-in helpers to include.
+ *
+ * @var mixed A single name as a string or a list of names as an array.
+ * @access protected
+ */
+ var $helpers = array('Html');
+/**
+ * Parameters received in the current request, i.e. GET and POST data
+ *
+ * @var array
+ * @access public
+ */
+ var $params = array();
+/**
+ * POST'ed model data
+ *
+ * @var array
+ * @access public
+ */
+ var $data = array();
+/**
+ * Directory where controllers views are stored
+ * Normaly this is automatically set
+ *
+ * @var string
+ * @access public
+ */
+ var $viewPath = null;
+/**
+ * Variables for the view
+ *
+ * @var array
+ * @access public
+ */
+ var $viewVars = array();
+/**
+ * Web page title
+ *
+ * @var boolean
+ * @access public
+ */
+ var $pageTitle = false;
+/**
+ * An array of model objects.
+ *
+ * @var array Array of model objects.
+ * @access public
+ */
+ var $modelNames = array();
+/**
+ * Base url path
+ *
+ * @var string
+ * @access public
+ */
+ var $base = null;
+/**
+ * Layout file to use (see /app/views/layouts/default.thtml)
+ *
+ * @var string
+ * @access public
+ */
+ var $layout = 'default';
+/**
+ * Automatically render the view (the dispatcher checks for this variable before running render())
+ *
+ * @var boolean
+ * @access public
+ */
+ var $autoRender = true;
+/**
+ * Automatically render the layout
+ *
+ * @var boolean
+ * @access public
+ */
+ var $autoLayout = true;
+/**
+ * Array of components a controller will use
+ *
+ * @var array
+ * @access public
+ */
+ var $components = array();
+/**
+ * The name of the View class a controller sends output to
+ *
+ * @var string
+ * @access public
+ */
+ var $view = 'View';
+/**
+ * File extension for view templates. Defaults to Cake's conventional ".thtml".
+ *
+ * @var string
+ * @access public
+ */
+ var $ext = '.thtml';
+/**
+ * Instance of $view class create by a controller
+ *
+ * @var object
+ * @access private
+ */
+ var $__viewClass = null;
+/**
+ * The output of the requested action. Contains either a variable
+ * returned from the action, or the data of the rendered view;
+ * You can use this var in Child classes afterFilter() to alter output.
+ *
+ * @var string
+ * @access public
+ */
+ var $output = null;
+/**
+ * Automatically set to the name of a plugin.
+ *
+ * @var string
+ * @access public
+ */
+ var $plugin = null;
+/**
+ * Used to set methods a controller will allow the View to cache
+ *
+ * @var mixed
+ * @access public
+ */
+ var $cacheAction = false;
+/**
+ * Used to create cached instances of models a controller uses.
+ * When set to true all models related to the controller will be cached,
+ * this can increase performance in many cases
+ *
+ * @var boolean
+ * @access public
+ */
+ var $persistModel = false;
+/**
+ * Replaced with Controller::beforeFilter();
+ *
+ * @deprecated will not be avialable after 1.1.x.x
+ */
+ var $beforeFilter = null;
+/**
+ * Replaced with Router::parseExtensions();
+ *
+ * @deprecated will not be avialable after 1.1.x.x
+ */
+ var $webservices = null;
+/**
+ * Constructor.
+ */
+ function __construct() {
+ if ($this->name === null) {
+ $r = null;
+
+ if (!preg_match('/(.*)Controller/i', get_class($this), $r)) {
+ die ("Controller::__construct() : Can't get or parse my own class name, exiting.");
+ }
+ $this->name = $r[1];
+ }
+
+ if ($this->viewPath == null) {
+ $this->viewPath = Inflector::underscore($this->name);
+ }
+
+ $this->modelClass = Inflector::classify($this->name);
+ $this->modelKey = Inflector::underscore($this->modelClass);
+
+ if (is_subclass_of($this, 'AppController')) {
+ $appVars = get_class_vars('AppController');
+ $uses = $appVars['uses'];
+ $merge = array('components', 'helpers');
+
+ if ($uses == $this->uses && !empty($this->uses)) {
+ array_unshift($this->uses, $this->modelClass);
+ } elseif ($this->uses !== null || $this->uses !== false) {
+ $merge[] = 'uses';
+ }
+
+ foreach ($merge as $var) {
+ if (isset($appVars[$var]) && !empty($appVars[$var]) && is_array($this->{$var})) {
+ $this->{$var} = array_merge($this->{$var}, array_diff($appVars[$var], $this->{$var}));
+ }
+ }
+ }
+ parent::__construct();
+ }
+
+ function _initComponents() {
+ $component = new Component();
+ $component->init($this);
+ }
+/**
+ * Loads and instantiates models required by this controller.
+ * If Controller::persistModel; is true, controller will create cached model instances on first request,
+ * additional request will used cached models
+ *
+ * @return mixed true when single model found and instance created error returned if models not found.
+ * @access public
+ */
+ function constructClasses() {
+ if ($this->uses === null || ($this->uses === array())) {
+ return false;
+ }
+ if (empty($this->passedArgs) || !isset($this->passedArgs['0'])) {
+ $id = false;
+ } else {
+ $id = $this->passedArgs['0'];
+ }
+ $cached = false;
+ $object = null;
+
+ if ($this->persistModel === true) {
+ uses('neat_array');
+ }
+ if ($this->uses === false) {
+ if (!class_exists($this->modelClass)) {
+ loadModel($this->modelClass);
+ }
+ }
+
+ if (class_exists($this->modelClass) && ($this->uses === false)) {
+ if ($this->persistModel === true) {
+ $cached = $this->_persist($this->modelClass, null, $object);
+ }
+
+ if (($cached === false)) {
+ $model =& new $this->modelClass($id);
+ $this->modelNames[] = $this->modelClass;
+ $this->{$this->modelClass} =& $model;
+
+ if ($this->persistModel === true) {
+ $this->_persist($this->modelClass, true, $model);
+ $registry = ClassRegistry::getInstance();
+ $this->_persist($this->modelClass . 'registry', true, $registry->_objects, 'registry');
+ }
+ } else {
+ $this->_persist($this->modelClass . 'registry', true, $object, 'registry');
+ $this->_persist($this->modelClass, true, $object);
+ $this->modelNames[] = $this->modelClass;
+ }
+ return true;
+ } elseif ($this->uses === false) {
+ return $this->cakeError('missingModel', array(array('className' => $this->modelClass, 'webroot' => '', 'base' => $this->base)));
+ }
+
+ if ($this->uses) {
+ $uses = is_array($this->uses) ? $this->uses : array($this->uses);
+ $this->modelClass = $uses[0];
+
+ foreach ($uses as $modelClass) {
+ $id = false;
+ $cached = false;
+ $object = null;
+ $modelKey = Inflector::underscore($modelClass);
+
+ if (!class_exists($modelClass)) {
+ loadModel($modelClass);
+ }
+
+ if (class_exists($modelClass)) {
+ if ($this->persistModel === true) {
+ $cached = $this->_persist($modelClass, null, $object);
+ }
+
+ if (($cached === false)) {
+ $model =& new $modelClass($id);
+ $this->modelNames[] = $modelClass;
+ $this->{$modelClass} =& $model;
+
+ if ($this->persistModel === true) {
+ $this->_persist($modelClass, true, $model);
+ $registry = ClassRegistry::getInstance();
+ $this->_persist($modelClass . 'registry', true, $registry->_objects, 'registry');
+ }
+ } else {
+ $this->_persist($modelClass . 'registry', true, $object, 'registry');
+ $this->_persist($modelClass, true, $object);
+ $this->modelNames[] = $modelClass;
+ }
+ } else {
+ return $this->cakeError('missingModel', array(array('className' => $modelClass, 'webroot' => '', 'base' => $this->base)));
+ }
+ }
+ return true;
+ }
+ }
+/**
+ * Redirects to given $url, after turning off $this->autoRender.
+ * Please notice that the script execution is not stopped after the redirect.
+ *
+ * @param string $url
+ * @param integer $status
+ * @access public
+ */
+ function redirect($url, $status = null) {
+ $this->autoRender = false;
+ $pos = strpos($url, '://');
+ $base = strip_plugin($this->base, $this->plugin);
+ if ($pos === false) {
+ if (strpos($url, '/') !== 0) {
+ $url = '/' . $url;
+ }
+ $url = FULL_BASE_URL . $base . $url;
+ }
+
+ if (function_exists('session_write_close')) {
+ session_write_close();
+ }
+
+ if (!empty($status)) {
+ $codes = array(
+ 100 => "HTTP/1.1 100 Continue",
+ 101 => "HTTP/1.1 101 Switching Protocols",
+ 200 => "HTTP/1.1 200 OK",
+ 201 => "HTTP/1.1 201 Created",
+ 202 => "HTTP/1.1 202 Accepted",
+ 203 => "HTTP/1.1 203 Non-Authoritative Information",
+ 204 => "HTTP/1.1 204 No Content",
+ 205 => "HTTP/1.1 205 Reset Content",
+ 206 => "HTTP/1.1 206 Partial Content",
+ 300 => "HTTP/1.1 300 Multiple Choices",
+ 301 => "HTTP/1.1 301 Moved Permanently",
+ 302 => "HTTP/1.1 302 Found",
+ 303 => "HTTP/1.1 303 See Other",
+ 304 => "HTTP/1.1 304 Not Modified",
+ 305 => "HTTP/1.1 305 Use Proxy",
+ 307 => "HTTP/1.1 307 Temporary Redirect",
+ 400 => "HTTP/1.1 400 Bad Request",
+ 401 => "HTTP/1.1 401 Unauthorized",
+ 402 => "HTTP/1.1 402 Payment Required",
+ 403 => "HTTP/1.1 403 Forbidden",
+ 404 => "HTTP/1.1 404 Not Found",
+ 405 => "HTTP/1.1 405 Method Not Allowed",
+ 406 => "HTTP/1.1 406 Not Acceptable",
+ 407 => "HTTP/1.1 407 Proxy Authentication Required",
+ 408 => "HTTP/1.1 408 Request Time-out",
+ 409 => "HTTP/1.1 409 Conflict",
+ 410 => "HTTP/1.1 410 Gone",
+ 411 => "HTTP/1.1 411 Length Required",
+ 412 => "HTTP/1.1 412 Precondition Failed",
+ 413 => "HTTP/1.1 413 Request Entity Too Large",
+ 414 => "HTTP/1.1 414 Request-URI Too Large",
+ 415 => "HTTP/1.1 415 Unsupported Media Type",
+ 416 => "HTTP/1.1 416 Requested range not satisfiable",
+ 417 => "HTTP/1.1 417 Expectation Failed",
+ 500 => "HTTP/1.1 500 Internal Server Error",
+ 501 => "HTTP/1.1 501 Not Implemented",
+ 502 => "HTTP/1.1 502 Bad Gateway",
+ 503 => "HTTP/1.1 503 Service Unavailable",
+ 504 => "HTTP/1.1 504 Gateway Time-out"
+ );
+ if (is_string($status)) {
+ $codes = array_combine(array_values($codes), array_keys($codes));
+ }
+ if (isset($codes[$status])) {
+ $code = ife(is_numeric($status), $status, $codes[$status]);
+ $msg = ife(is_string($status), $status, $codes[$status]);
+ $status = "HTTP/1.1 {$code} {$msg}";
+ } else {
+ $status = null;
+ }
+ }
+ if (!empty($status)) {
+ header($status);
+ }
+ header('Location: ' . $url);
+ if (!empty($status) && ($status >= 300 && $status < 400)) {
+ header($status);
+ }
+ }
+/**
+ * Saves a variable to use inside a template.
+ *
+ * @param mixed $one A string or an array of data.
+ * @param mixed $two Value in case $one is a string (which then works as the key). Unused if $one is an associative array, otherwise serves as the values to $one's keys.
+ * @return mixed string or array of variables set
+ * @access public
+ */
+ function set($one, $two = null) {
+ if (is_array($one)) {
+ if (is_array($two)) {
+ return $this->_setArray(array_combine($one, $two));
+ } else {
+ return $this->_setArray($one);
+ }
+ } else {
+ return $this->_setArray(array($one => $two));
+ }
+ }
+/**
+ * Internally redirects one action to another
+ *
+ * @param string $action The new action to be redirected to
+ * @param mixed Any other parameters passed to this method will be passed as
+ * parameters to the new action.
+ * @access public
+ */
+ function setAction($action) {
+ $this->action = $action;
+ $args = func_get_args();
+ unset($args[0]);
+ call_user_func_array(array(&$this, $action), $args);
+ }
+/**
+ * Returns number of errors in a submitted FORM.
+ *
+ * @return int Number of errors
+ * @access public
+ */
+ function validate() {
+ $args = func_get_args();
+ $errors = call_user_func_array(array(&$this, 'validateErrors'), $args);
+
+ if ($errors === false) {
+ return 0;
+ }
+ return count($errors);
+ }
+/**
+ * Validates a FORM according to the rules set up in the Model.
+ *
+ * @return int Number of errors
+ * @access public
+ */
+ function validateErrors() {
+ $objects = func_get_args();
+ if (!count($objects)) {
+ return false;
+ }
+
+ $errors = array();
+ foreach ($objects as $object) {
+ $errors = array_merge($errors, $this->{$object->name}->invalidFields($object->data));
+ }
+ return $this->validationErrors = (count($errors) ? $errors : false);
+ }
+/**
+ * Gets an instance of the view object and prepares it for rendering the output, then
+ * asks the view to actualy do the job.
+ *
+ * @param string $action
+ * @param string $layout
+ * @param string $file
+ * @return controllers related views
+ * @access public
+ */
+ function render($action = null, $layout = null, $file = null) {
+ $viewClass = $this->view;
+ if ($this->view != 'View') {
+ $viewClass = $this->view . 'View';
+ loadView($this->view);
+ }
+ $this->beforeRender();
+ $this->__viewClass =& new $viewClass($this);
+
+ if (!empty($this->modelNames)) {
+ $models = array();
+ foreach ($this->modelNames as $currentModel) {
+ if (isset($this->$currentModel) && is_a($this->$currentModel, 'Model')) {
+ $models[] = Inflector::underscore($currentModel);
+ }
+ if (isset($this->$currentModel) && is_a($this->$currentModel, 'Model') && !empty($this->$currentModel->validationErrors)) {
+ $this->__viewClass->validationErrors[Inflector::camelize($currentModel)] =& $this->$currentModel->validationErrors;
+ }
+ }
+ $models = array_diff(ClassRegistry::keys(), $models);
+ foreach ($models as $currentModel) {
+ if (ClassRegistry::isKeySet($currentModel)) {
+ $currentObject =& ClassRegistry::getObject($currentModel);
+ if (is_a($currentObject, 'Model') && !empty($currentObject->validationErrors)) {
+ $this->__viewClass->validationErrors[Inflector::camelize($currentModel)] =& $currentObject->validationErrors;
+ }
+ }
+ }
+ }
+ $this->autoRender = false;
+ return $this->__viewClass->render($action, $layout, $file);
+ }
+/**
+ * Gets the referring URL of this request
+ *
+ * @param string $default Default URL to use if HTTP_REFERER cannot be read from headers
+ * @param boolean $local If true, restrict referring URLs to local server
+ * @access public
+ */
+ function referer($default = null, $local = false) {
+ $ref = env('HTTP_REFERER');
+ $base = FULL_BASE_URL . $this->webroot;
+
+ if ($ref != null && (defined(FULL_BASE_URL) || FULL_BASE_URL)) {
+ if (strpos($ref, $base) === 0) {
+ return substr($ref, strlen($base) - 1);
+ } elseif (!$local) {
+ return $ref;
+ }
+ }
+
+ if ($default != null) {
+ return $default;
+ } else {
+ return '/';
+ }
+ }
+/**
+ * Sets data for this view. Will set title if the key "title" is in given $data array.
+ *
+ * @param array $data Array of
+ * @access protected
+ */
+ function _setArray($data) {
+ foreach ($data as $name => $value) {
+ if ($name == 'title') {
+ $this->_setTitle($value);
+ } else {
+ $this->viewVars[$name] = $value;
+ }
+ }
+ }
+/**
+ * Set the title element of the page.
+ *
+ * @param string $pageTitle Text for the title
+ * @access private
+ */
+ function _setTitle($pageTitle) {
+ $this->pageTitle = $pageTitle;
+ }
+/**
+ * Shows a message to the user $time seconds, then redirects to $url if DEBUG == 0. If DEBUG > 0, warnings and SQL output may halt redirection.
+ * Uses flash.thtml as a layout for the messages
+ *
+ * @param string $message Message to display to the user
+ * @param string $url Relative URL to redirect to after the time expires
+ * @param int $time seconds to show the message
+ * @access public
+ */
+ function flash($message, $url, $pause = 1) {
+ $this->autoRender = false;
+ $this->autoLayout = false;
+ $this->set('url', $this->base . $url);
+ $this->set('message', $message);
+ $this->set('pause', $pause);
+ $this->set('page_title', $message);
+
+ if (file_exists(VIEWS . 'layouts' . DS . 'flash.thtml')) {
+ $flash = VIEWS . 'layouts' . DS . 'flash.thtml';
+ } elseif ($flash = fileExistsInPath(LIBS . 'view' . DS . 'templates' . DS . "layouts" . DS . 'flash.thtml')) {
+ }
+ $this->render(null, false, $flash);
+ }
+/**
+ * Replaced with Controller::flash();
+ * @deprecated will not be avialable after 1.1.x.x
+ */
+ function flashOut($message, $url, $pause = 1) {
+ trigger_error('(Controller::flashOut()) Deprecated: Use Controller::flash() instead', E_USER_WARNING);
+ $this->autoRender = false;
+ $this->autoLayout = false;
+ $this->set('url', $url);
+ $this->set('message', $message);
+ $this->set('pause', $pause);
+ $this->set('page_title', $message);
+
+ if (file_exists(VIEWS . 'layouts' . DS . 'flash.thtml')) {
+ $flash = VIEWS . 'layouts' . DS . 'flash.thtml';
+ } elseif ($flash = fileExistsInPath(LIBS . 'view' . DS . 'templates' . DS . "layouts" . DS . 'flash.thtml')) {
+ }
+ $this->render(null, false, $flash);
+ }
+/**
+ * This function creates a $fieldNames array for the view to use.
+ *
+ * @param array $data
+ * @param boolean $doCreateOptions
+ * @return field name arrays for the view
+ * @access public
+ */
+ function generateFieldNames($data = null, $doCreateOptions = true) {
+ $fieldNames = array();
+ $model = $this->modelClass;
+ $modelKey = $this->modelKey;
+ $table = $this->{$model}->table;
+ $objRegistryModel =& ClassRegistry::getObject($modelKey);
+
+ foreach ($objRegistryModel->_tableInfo->value as $tabl) {
+ if ($objRegistryModel->isForeignKey($tabl['name'])) {
+ if (false !== strpos($tabl['name'], "_id")) {
+ $niceName = substr($tabl['name'], 0, strpos($tabl['name'], "_id" ));
+ } else {
+ $niceName = $niceName = $tabl['name'];
+ }
+ $fkNames = $this->{$model}->keyToTable[$tabl['name']];
+ $fieldNames[$tabl['name']]['table'] = $fkNames[0];
+ $fieldNames[$tabl['name']]['prompt'] = Inflector::humanize($niceName);
+ $fieldNames[$tabl['name']]['model'] = $fkNames[1];
+ $fieldNames[$tabl['name']]['modelKey'] = $this->{$model}->tableToModel[$fieldNames[$tabl['name']]['table']];
+ $fieldNames[$tabl['name']]['controller'] = Inflector::pluralize($this->{$model}->tableToModel[$fkNames[0]]);
+ $fieldNames[$tabl['name']]['foreignKey'] = true;
+
+ } elseif ('created' != $tabl['name'] && 'updated' != $tabl['name']) {
+ $fieldNames[$tabl['name']]['prompt'] = Inflector::humanize($tabl['name']);
+ } elseif ('created' == $tabl['name']) {
+ $fieldNames[$tabl['name']]['prompt'] = 'Created';
+ } elseif ('updated' == $tabl['name']) {
+ $fieldNames[$tabl['name']]['prompt'] = 'Modified';
+ }
+ $fieldNames[$tabl['name']]['tagName'] = $model . '/' . $tabl['name'];
+ $validationFields = $objRegistryModel->validate;
+
+ if (isset($validationFields[$tabl['name']])) {
+ if (VALID_NOT_EMPTY == $validationFields[$tabl['name']]) {
+ $fieldNames[$tabl['name']]['required'] = true;
+ $fieldNames[$tabl['name']]['errorMsg'] = "Required Field";
+ }
+ }
+ $lParenPos = strpos($tabl['type'], '(');
+ $rParenPos = strpos($tabl['type'], ')');
+
+ if (false != $lParenPos) {
+ $type = substr($tabl['type'], 0, $lParenPos);
+ $fieldLength = substr($tabl['type'], $lParenPos + 1, $rParenPos - $lParenPos - 1);
+ } else {
+ $type = $tabl['type'];
+ }
+
+ switch($type) {
+ case "text":
+ $fieldNames[$tabl['name']]['type'] = 'area';
+ break;
+ case "string":
+ if (isset($fieldNames[$tabl['name']]['foreignKey'])) {
+ $fieldNames[$tabl['name']]['type'] = 'select';
+ $fieldNames[$tabl['name']]['options'] = array();
+ $otherModel =& ClassRegistry::getObject(Inflector::underscore($fieldNames[$tabl['name']]['modelKey']));
+
+ if (is_object($otherModel)) {
+ if ($doCreateOptions) {
+ $otherDisplayField = $otherModel->getDisplayField();
+ $otherModel->recursive = 0;
+ $rec = $otherModel->findAll();
+
+ foreach ($rec as $pass) {
+ foreach ($pass as $key => $value) {
+ if ($key == $this->{$model}->tableToModel[$fieldNames[$tabl['name']]['table']] && isset($value[$otherModel->primaryKey]) && isset($value[$otherDisplayField])) {
+ $fieldNames[$tabl['name']]['options'][$value[$otherModel->primaryKey]] = $value[$otherDisplayField];
+ }
+ }
+ }
+ }
+ $fieldNames[$tabl['name']]['selected'] = $data[$model][$tabl['name']];
+ }
+ } else {
+ $fieldNames[$tabl['name']]['type'] = 'input';
+ }
+ break;
+ case "boolean":
+ $fieldNames[$tabl['name']]['type'] = 'checkbox';
+ break;
+ case "integer":
+ case "float":
+ if (strcmp($tabl['name'], $this->$model->primaryKey) == 0) {
+ $fieldNames[$tabl['name']]['type'] = 'hidden';
+ } elseif (isset($fieldNames[$tabl['name']]['foreignKey'])) {
+ $fieldNames[$tabl['name']]['type'] = 'select';
+ $fieldNames[$tabl['name']]['options'] = array();
+ $otherModel =& ClassRegistry::getObject(Inflector::underscore($fieldNames[$tabl['name']]['modelKey']));
+
+ if (is_object($otherModel)) {
+ if ($doCreateOptions) {
+ $otherDisplayField = $otherModel->getDisplayField();
+ $otherModel->recursive = 0;
+ $rec = $otherModel->findAll();
+
+ foreach ($rec as $pass) {
+ foreach ($pass as $key => $value) {
+ if ($key == $this->{$model}->tableToModel[$fieldNames[$tabl['name']]['table']] && isset($value[$otherModel->primaryKey]) && isset($value[$otherDisplayField])) {
+ $fieldNames[$tabl['name']]['options'][$value[$otherModel->primaryKey]] = $value[$otherDisplayField];
+ }
+ }
+ }
+ }
+ $fieldNames[$tabl['name']]['selected'] = $data[$model][$tabl['name']];
+ }
+ } else {
+ $fieldNames[$tabl['name']]['type'] = 'input';
+ }
+ break;
+ case "enum":
+ $fieldNames[$tabl['name']]['type'] = 'select';
+ $fieldNames[$tabl['name']]['options'] = array();
+ $enumValues = split(',', $fieldLength);
+
+ foreach ($enumValues as $enum) {
+ $enum = trim($enum, "'");
+ $fieldNames[$tabl['name']]['options'][$enum] = $enum;
+ }
+
+ $fieldNames[$tabl['name']]['selected'] = $data[$model][$tabl['name']];
+ break;
+ case "date":
+ case "datetime":
+ case "time":
+ case "year":
+ if (0 != strncmp("created", $tabl['name'], 7) && 0 != strncmp("modified", $tabl['name'], 8)) {
+ $fieldNames[$tabl['name']]['type'] = $type;
+ }
+
+ if (isset($data[$model][$tabl['name']])) {
+ $fieldNames[$tabl['name']]['selected'] = $data[$model][$tabl['name']];
+ } else {
+ $fieldNames[$tabl['name']]['selected'] = null;
+ }
+
+ break;
+ default:
+ break;
+ }
+ }
+
+ foreach ($objRegistryModel->hasAndBelongsToMany as $relation => $relData) {
+ $modelName = $relData['className'];
+ $manyAssociation = $relation;
+ $modelKeyM = Inflector::underscore($modelName);
+ $modelObject =& new $modelName();
+
+ if ($doCreateOptions) {
+ $otherDisplayField = $modelObject->getDisplayField();
+ $fieldNames[$relation]['model'] = $modelName;
+ $fieldNames[$relation]['prompt'] = "Related " . Inflector::humanize(Inflector::pluralize($relation));
+ $fieldNames[$relation]['type'] = "selectMultiple";
+ $fieldNames[$relation]['tagName'] = $manyAssociation . '/' . $manyAssociation;
+ $modelObject->recursive = 0;
+ $rec = $modelObject->findAll();
+
+ foreach ($rec as $pass) {
+ foreach ($pass as $key => $value) {
+ if ($key == $modelName && isset($value[$modelObject->primaryKey]) && isset($value[$otherDisplayField])) {
+ $fieldNames[$relation]['options'][$value[$modelObject->primaryKey]] = $value[$otherDisplayField];
+ }
+ }
+ }
+
+ if (isset($data[$manyAssociation])) {
+ foreach ($data[$manyAssociation] as $key => $row) {
+ $fieldNames[$relation]['selected'][$row[$modelObject->primaryKey]] = $row[$modelObject->primaryKey];
+ }
+ }
+ }
+ }
+ return $fieldNames;
+ }
+/**
+ * Converts POST'ed model data to a model conditions array, suitable for a find or findAll Model query
+ *
+ * @param array $data POST'ed data organized by model and field
+ * @return array An array of model conditions
+ * @access public
+ */
+ function postConditions($data) {
+ if (!is_array($data) || empty($data)) {
+ return null;
+ }
+ $conditions = array();
+
+ foreach ($data as $model => $fields) {
+ foreach ($fields as $field => $value) {
+ $conditions[$model . '.' . $field] = $value;
+ }
+ }
+ return $conditions;
+ }
+/**
+ * Cleans up the date fields of current Model.
+ *
+ * @param string $modelName
+ * @access public
+ */
+ function cleanUpFields($modelName = null) {
+ if ($modelName == null) {
+ $modelName = $this->modelClass;
+ }
+
+ foreach ($this->{$modelName}->_tableInfo->value as $field) {
+ if ('date' == $field['type'] && isset($this->params['data'][$modelName][$field['name'] . '_year'])) {
+ $newDate = $this->params['data'][$modelName][$field['name'] . '_year'] . '-';
+ $newDate .= $this->params['data'][$modelName][$field['name'] . '_month'] . '-';
+ $newDate .= $this->params['data'][$modelName][$field['name'] . '_day'];
+ unset($this->params['data'][$modelName][$field['name'] . '_year']);
+ unset($this->params['data'][$modelName][$field['name'] . '_month']);
+ unset($this->params['data'][$modelName][$field['name'] . '_day']);
+ unset($this->params['data'][$modelName][$field['name'] . '_hour']);
+ unset($this->params['data'][$modelName][$field['name'] . '_min']);
+ unset($this->params['data'][$modelName][$field['name'] . '_meridian']);
+ $this->params['data'][$modelName][$field['name']] = $newDate;
+ $this->data[$modelName][$field['name']] = $newDate;
+
+ } elseif ('datetime' == $field['type'] && isset($this->params['data'][$modelName][$field['name'] . '_year'])) {
+ $hour = $this->params['data'][$modelName][$field['name'] . '_hour'];
+
+ if ($hour != 12 && (isset($this->params['data'][$modelName][$field['name'] . '_meridian']) && 'pm' == $this->params['data'][$modelName][$field['name'] . '_meridian'])) {
+ $hour = $hour + 12;
+ }
+
+ $newDate = $this->params['data'][$modelName][$field['name'] . '_year'] . '-';
+ $newDate .= $this->params['data'][$modelName][$field['name'] . '_month'] . '-';
+ $newDate .= $this->params['data'][$modelName][$field['name'] . '_day'] . ' ';
+ $newDate .= $hour . ':' . $this->params['data'][$modelName][$field['name'] . '_min'] . ':00';
+ unset($this->params['data'][$modelName][$field['name'] . '_year']);
+ unset($this->params['data'][$modelName][$field['name'] . '_month']);
+ unset($this->params['data'][$modelName][$field['name'] . '_day']);
+ unset($this->params['data'][$modelName][$field['name'] . '_hour']);
+ unset($this->params['data'][$modelName][$field['name'] . '_min']);
+ unset($this->params['data'][$modelName][$field['name'] . '_meridian']);
+ $this->params['data'][$modelName][$field['name']] = $newDate;
+ $this->data[$modelName][$field['name']] = $newDate;
+
+ } elseif ('time' == $field['type'] && isset($this->params['data'][$modelName][$field['name'] . '_hour'])) {
+ $hour = $this->params['data'][$modelName][$field['name'] . '_hour'];
+
+ if ($hour != 12 && (isset($this->params['data'][$modelName][$field['name'] . '_meridian']) && 'pm' == $this->params['data'][$modelName][$field['name'] . '_meridian'])) {
+ $hour = $hour + 12;
+ }
+ if ($hour == 12 && (isset($this->params['data'][$modelName][$field['name'] . '_meridian']) && 'am' == $this->params['data'][$modelName][$field['name'] . '_meridian'])) {
+ $hour = '00';
+ }
+
+ $newDate = $hour . ':' . $this->params['data'][$modelName][$field['name'] . '_min'] . ':00';
+ unset($this->params['data'][$modelName][$field['name'] . '_hour']);
+ unset($this->params['data'][$modelName][$field['name'] . '_min']);
+ unset($this->params['data'][$modelName][$field['name'] . '_meridian']);
+ $this->params['data'][$modelName][$field['name']] = $newDate;
+ $this->data[$modelName][$field['name']] = $newDate;
+ }
+ }
+ }
+/**
+ * Called before the controller action. Overridden in subclasses.
+ *
+ * @access public
+ */
+ function beforeFilter() {
+ }
+/**
+ * Called after the controller action is run, but before the view is rendered. Overridden in subclasses.
+ *
+ * @access public
+ */
+ function beforeRender() {
+ }
+/**
+ * Called after the controller action is run and rendered. Overridden in subclasses.
+ *
+ * @access public
+ */
+ function afterFilter() {
+ }
+/**
+ * This method should be overridden in child classes.
+ *
+ * @param string $method name of method called example index, edit, etc.
+ * @return boolean
+ * @access protected
+ */
+ function _beforeScaffold($method) {
+ return true;
+ }
+/**
+ * This method should be overridden in child classes.
+ *
+ * @param string $method name of method called either edit or update.
+ * @return boolean
+ * @access protected
+ */
+ function _afterScaffoldSave($method) {
+ return true;
+ }
+/**
+ * This method should be overridden in child classes.
+ *
+ * @param string $method name of method called either edit or update.
+ * @return boolean
+ * @access protected
+ */
+ function _afterScaffoldSaveError($method) {
+ return true;
+ }
+/**
+ * This method should be overridden in child classes.
+ * If not it will render a scaffold error.
+ * Method MUST return true in child classes
+ *
+ * @param string $method name of method called example index, edit, etc.
+ * @return boolean
+ * @access protected
+ */
+ function _scaffoldError($method) {
+ return false;
+ }
+/**
+ * Used to convert HABTM data into an array for selectTag
+ *
+ * @param array $data
+ * @param string $key
+ * @return array
+ * @access protected
+ */
+ function _selectedArray($data, $key = 'id') {
+ $array = array();
+ if (!empty($data)) {
+ foreach ($data as $var) {
+ $array[$var[$key]] = $var[$key];
+ }
+ }
+ return $array;
+ }
+}
+?> \ No newline at end of file
diff --git a/site/cake/libs/controller/pages_controller.php b/site/cake/libs/controller/pages_controller.php
new file mode 100644
index 0000000..25ba84f
--- /dev/null
+++ b/site/cake/libs/controller/pages_controller.php
@@ -0,0 +1,105 @@
+<?php
+/* SVN FILE: $Id: pages_controller.php 6305 2008-01-02 02:33:56Z phpnut $ */
+
+/**
+ * Short description for file.
+ *
+ * This file is application-wide controller file. You can put all
+ * application-wide controller-related methods here.
+ *
+ * PHP versions 4 and 5
+ *
+ * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
+ * Copyright 2005-2008, Cake Software Foundation, Inc.
+ * 1785 E. Sahara Avenue, Suite 490-204
+ * Las Vegas, Nevada 89104
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
+ * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
+ * @package cake
+ * @subpackage cake.cake.libs.controller
+ * @since CakePHP(tm) v 0.2.9
+ * @version $Revision: 6305 $
+ * @modifiedby $LastChangedBy: phpnut $
+ * @lastmodified $Date: 2008-01-01 20:33:56 -0600 (Tue, 01 Jan 2008) $
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+
+/**
+ * Short description for class.
+ *
+ * This file is application-wide controller file. You can put all
+ * application-wide controller-related methods here.
+ *
+ * Add your application-wide methods in the class below, your controllers
+ * will inherit them.
+ *
+ * @package cake
+ * @subpackage cake.cake.libs.controller
+ */
+class PagesController extends AppController{
+
+/**
+ * Enter description here...
+ *
+ * @var unknown_type
+ */
+ var $name = 'Pages';
+
+/**
+ * Enter description here...
+ *
+ * @var unknown_type
+ */
+ var $helpers = array('Html');
+
+/**
+ * This controller does not use a model
+ *
+ * @var $uses
+ */
+ var $uses = array();
+
+/**
+ * Displays a view
+ *
+ */
+ function display() {
+ if (!func_num_args()) {
+ $this->redirect('/');
+ }
+
+ $path=func_get_args();
+
+ if (!count($path)) {
+ $this->redirect('/');
+ }
+
+ $count =count($path);
+ $page =null;
+ $subpage=null;
+ $title =null;
+
+ if (!empty($path[0])) {
+ $page = $path[0];
+ }
+
+ if (!empty($path[1])) {
+ $subpage = $path[1];
+ }
+
+ if (!empty($path[$count - 1])) {
+ $title = ucfirst($path[$count - 1]);
+ }
+
+ $this->set('page', $page);
+ $this->set('subpage', $subpage);
+ $this->set('title', $title);
+ $this->render(join('/', $path));
+ }
+}
+?> \ No newline at end of file
diff --git a/site/cake/libs/controller/scaffold.php b/site/cake/libs/controller/scaffold.php
new file mode 100644
index 0000000..e625df5
--- /dev/null
+++ b/site/cake/libs/controller/scaffold.php
@@ -0,0 +1,432 @@
+<?php
+/* SVN FILE: $Id: scaffold.php 6305 2008-01-02 02:33:56Z phpnut $ */
+/**
+ * Scaffold.
+ *
+ * Automatic forms and actions generation for rapid web application development.
+ *
+ * PHP versions 4 and 5
+ *
+ * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
+ * Copyright 2005-2008, Cake Software Foundation, Inc.
+ * 1785 E. Sahara Avenue, Suite 490-204
+ * Las Vegas, Nevada 89104
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
+ * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
+ * @package cake
+ * @subpackage cake.cake.libs.controller
+ * @since Cake v 0.10.0.1076
+ * @version $Revision: 6305 $
+ * @modifiedby $LastChangedBy: phpnut $
+ * @lastmodified $Date: 2008-01-01 20:33:56 -0600 (Tue, 01 Jan 2008) $
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+/**
+ * Scaffolding is a set of automatic views, forms and controllers for starting web development work faster.
+ *
+ * Scaffold inspects your database tables, and making educated guesses, sets up a
+ * number of pages for each of your Models. These pages have data forms that work,
+ * and afford the web developer an early look at the data, and the possibility to over-ride
+ * scaffolded actions with custom-made ones.
+ *
+ * @package cake
+ * @subpackage cake.cake.libs.controller
+ */
+class Scaffold extends Object{
+/**
+ * Name of view to render
+ *
+ * @var string
+ */
+ var $actionView = null;
+/**
+ * Class name of model
+ *
+ * @var unknown_type
+ */
+ var $modelKey = null;
+/**
+ * Controller object
+ *
+ * @var Controller
+ */
+ var $controllerClass = null;
+/**
+ * Name of scaffolded Model
+ *
+ * @var string
+ */
+ var $modelName = null;
+/**
+ * Title HTML element for current scaffolded view
+ *
+ * @var string
+ */
+ var $scaffoldTitle = null;
+/**
+ * Base URL
+ *
+ * @var string
+ */
+ var $base = false;
+/**
+ * Construct and set up given controller with given parameters.
+ *
+ * @param object $controller instance of controller
+ * @param array $params
+ */
+ function __construct(&$controller, $params) {
+ $this->controllerClass =& $controller;
+ $this->actionView = $controller->action;
+ $this->modelKey = ucwords(Inflector::singularize($controller->name));
+ $this->scaffoldTitle = Inflector::humanize($this->modelKey);
+ $this->viewPath = Inflector::underscore($controller->name);
+ $this->controllerClass->pageTitle = $this->scaffoldTitle;
+ $this->controllerClass->pageTitle = 'Scaffold :: ' . Inflector::humanize($controller->action) . ' :: ' .
+ Inflector::humanize(Inflector::pluralize($this->modelKey));
+ $this->__scaffold($params);
+ }
+/**
+ * Renders a view view of scaffolded Model.
+ *
+ * @param array $params
+ * @return A rendered view of a row from Models database table
+ * @access private
+ */
+ function __scaffoldView($params) {
+ if ($this->controllerClass->_beforeScaffold('view')) {
+
+ if (isset($params['pass'][0])) {
+ $this->controllerClass->{$this->modelKey}->id = $params['pass'][0];
+
+ } elseif (isset($this->controllerClass->Session) && $this->controllerClass->Session->valid != false) {
+ $this->controllerClass->Session->setFlash('No id set for ' . Inflector::humanize($this->modelKey) . '::view().');
+ $this->controllerClass->redirect('/' . Inflector::underscore($this->controllerClass->viewPath));
+
+ } else {
+ return $this->controllerClass->flash('No id set for ' . Inflector::humanize($this->modelKey) . '::view().',
+ '/' . Inflector::underscore($this->controllerClass->viewPath));
+ }
+
+ $this->controllerClass->params['data'] = $this->controllerClass->{$this->modelKey}->read();
+ $this->controllerClass->set('data', $this->controllerClass->params['data']);
+ $this->controllerClass->set('fieldNames',$this->controllerClass->generateFieldNames(
+ $this->controllerClass->params['data'], false));
+
+ if (file_exists(APP . 'views' . DS . $this->viewPath . DS . 'scaffold.view.thtml')) {
+ return $this->controllerClass->render($this->actionView, '',
+ APP . 'views' . DS . $this->viewPath . DS . 'scaffold.view.thtml');
+
+ } elseif (file_exists(APP . 'views' . DS . 'scaffold' . DS . 'scaffold.view.thtml')) {
+ return $this->controllerClass->render($this->actionView, '',
+ APP . 'views' . DS . 'scaffold' . DS . 'scaffold.view.thtml');
+ } else {
+ return $this->controllerClass->render($this->actionView, '',
+ LIBS . 'view' . DS . 'templates' . DS . 'scaffolds' . DS . 'view.thtml');
+ }
+ } elseif ($this->controllerClass->_scaffoldError('view') === false) {
+ return $this->__scaffoldError();
+ }
+ }
+/**
+ * Renders List view of scaffolded Model.
+ *
+ * @param array $params
+ * @return A rendered view listing rows from Models database table
+ * @access private
+ */
+ function __scaffoldIndex($params) {
+ if ($this->controllerClass->_beforeScaffold('index')) {
+ $this->controllerClass->set('fieldNames', $this->controllerClass->generateFieldNames(null, false));
+ $this->controllerClass->{$this->modelKey}->recursive = 0;
+ $this->controllerClass->set('data', $this->controllerClass->{$this->modelKey}->findAll());
+
+ if (file_exists(APP . 'views' . DS . $this->viewPath . DS . 'scaffold.index.thtml')) {
+ return $this->controllerClass->render($this->actionView, '',
+ APP . 'views' . DS . $this->viewPath . DS . 'scaffold.index.thtml');
+
+ } elseif (file_exists(APP . 'views' . DS . 'scaffold' . DS . 'scaffold.index.thtml')) {
+ return $this->controllerClass->render($this->actionView, '',
+ APP . 'views' . DS . 'scaffold' . DS . 'scaffold.index.thtml');
+ } else {
+ return $this->controllerClass->render($this->actionView, '',
+ LIBS . 'view' . DS . 'templates' . DS . 'scaffolds' . DS . 'index.thtml');
+ }
+ } elseif ($this->controllerClass->_scaffoldError('index') === false) {
+ return $this->__scaffoldError();
+ }
+ }
+/**
+ * Renders an Add or Edit view for scaffolded Model.
+ *
+ * @param array $params
+ * @param string $params add or edit
+ * @return A rendered view with a form to edit or add a record in the Models database table
+ * @access private
+ */
+ function __scaffoldForm($params = array(), $type) {
+ $thtml = 'edit';
+ $form = 'Edit';
+
+ if ($type === 'add') {
+ $thtml = 'add';
+ $form = 'Add';
+ }
+
+ if ($this->controllerClass->_beforeScaffold($type)) {
+ if ($type == 'edit') {
+
+ if (isset($params['pass'][0])) {
+ $this->controllerClass->{$this->modelKey}->id = $params['pass'][0];
+
+ } elseif (isset($this->controllerClass->Session) && $this->controllerClass->Session->valid != false) {
+ $this->controllerClass->Session->setFlash('No id set for ' . Inflector::humanize($this->modelKey) . '::edit().');
+ $this->controllerClass->redirect('/' . Inflector::underscore($this->controllerClass->viewPath));
+
+ } else {
+ return $this->controllerClass->flash('No id set for ' . Inflector::humanize($this->modelKey) . '::edit().',
+ '/' . Inflector::underscore($this->controllerClass->viewPath));
+ }
+
+ $this->controllerClass->params['data']=$this->controllerClass->{$this->modelKey}->read();
+ $this->controllerClass->set('fieldNames', $this->controllerClass->generateFieldNames(
+ $this->controllerClass->params['data']));
+ $this->controllerClass->set('data', $this->controllerClass->params['data']);
+ } else {
+ $this->controllerClass->set('fieldNames', $this->controllerClass->generateFieldNames());
+ }
+ $this->controllerClass->set('type', $form);
+
+ if (file_exists(APP . 'views' . DS . $this->viewPath . DS . 'scaffold.' . $thtml . '.thtml')) {
+ return $this->controllerClass->render($this->actionView, '',
+ APP . 'views' . DS . $this->viewPath . DS . 'scaffold.' . $thtml . '.thtml');
+ } elseif (file_exists(APP . 'views' . DS . 'scaffold' . DS . 'scaffold.' . $thtml . '.thtml')) {
+ return $this->controllerClass->render($this->actionView, '',
+ APP . 'views' . DS . 'scaffold' . DS . 'scaffold.' . $thtml . '.thtml');
+ } else {
+ return $this->controllerClass->render($this->actionView, '',
+ LIBS . 'view' . DS . 'templates' . DS . 'scaffolds' . DS . 'edit.thtml');
+ }
+ } elseif ($this->controllerClass->_scaffoldError($type) === false) {
+ return $this->__scaffoldError();
+ }
+ }
+/**
+ * Saves or updates a model.
+ *
+ * @param array $params
+ * @param string $type create or update
+ * @return success on save/update, add/edit form if data is empty or error if save or update fails
+ * @access private
+ */
+ function __scaffoldSave($params = array(), $type) {
+ $thtml = 'edit';
+ $form = 'Edit';
+ $success = 'updated';
+ $formError = 'edit';
+
+ if ($this->controllerClass->_beforeScaffold($type)) {
+ if (empty($this->controllerClass->params['data'])) {
+ if ($type === 'create') {
+ $formError = 'add';
+ }
+ return $this->__scaffoldForm($params, $formError);
+ }
+ $this->controllerClass->set('fieldNames', $this->controllerClass->generateFieldNames());
+ $this->controllerClass->cleanUpFields();
+
+ if ($type == 'create') {
+ $this->controllerClass->{$this->modelKey}->create();
+ $thtml = 'add';
+ $form = 'Add';
+ $success = 'saved';
+ }
+
+ if ($this->controllerClass->{$this->modelKey}->save($this->controllerClass->params['data'])) {
+
+ if ($this->controllerClass->_afterScaffoldSave($type)) {
+
+ if (isset($this->controllerClass->Session) && $this->controllerClass->Session->valid != false) {
+ $this->controllerClass->Session->setFlash('The ' . Inflector::humanize($this->modelKey) . ' has been ' . $success . '.');
+ $this->controllerClass->redirect('/' . Inflector::underscore($this->controllerClass->viewPath));
+ } else {
+ return $this->controllerClass->flash('The ' . Inflector::humanize($this->modelKey) . ' has been ' . $success . '.',
+ '/' . Inflector::underscore($this->controllerClass->viewPath));
+ }
+ } else {
+ return $this->controllerClass->_afterScaffoldSaveError($type);
+ }
+ } else {
+ if (isset($this->controllerClass->Session) && $this->controllerClass->Session->valid != false) {
+ $this->controllerClass->Session->setFlash('Please correct errors below.');
+ }
+ $this->controllerClass->set('data', $this->controllerClass->params['data']);
+ $this->controllerClass->set('fieldNames',
+ $this->controllerClass->generateFieldNames($this->__rebuild($this->controllerClass->params['data'])));
+ $this->controllerClass->validateErrors($this->controllerClass->{$this->modelKey});
+ $this->controllerClass->set('type', $form);
+
+ if (file_exists(APP . 'views' . DS . $this->viewPath . DS . 'scaffolds' . DS . 'scaffold.' . $thtml . '.thtml')) {
+ return $this->controllerClass->render($this->actionView, '',
+ APP . 'views' . DS . $this->viewPath . DS . 'scaffolds' . DS . 'scaffold.' . $thtml . '.thtml');
+ } elseif (file_exists(APP . 'views' . DS . 'scaffold' . DS . 'scaffold.' . $thtml . '.thtml')) {
+ return $this->controllerClass->render($this->actionView, '',
+ APP . 'views' . DS . 'scaffold' . DS . 'scaffold.' . $thtml . '.thtml');
+ } else {
+ return $this->controllerClass->render($this->actionView, '',
+ LIBS . 'view' . DS . 'templates' . DS . 'scaffolds' . DS . 'edit.thtml');
+ }
+ }
+ } elseif ($this->controllerClass->_scaffoldError($type) === false) {
+ return $this->__scaffoldError();
+ }
+ }
+/**
+ * Performs a delete on given scaffolded Model.
+ *
+ * @param array $params
+ * @return success on delete error if delete fails
+ * @access private
+ */
+ function __scaffoldDelete($params = array()) {
+ if ($this->controllerClass->_beforeScaffold('delete')) {
+ $id = $params['pass'][0];
+
+ if ($this->controllerClass->{$this->modelKey}->del($id)) {
+
+ if (isset($this->controllerClass->Session) && $this->controllerClass->Session->valid != false) {
+ $this->controllerClass->Session->setFlash('The ' . Inflector::humanize($this->modelKey) . ' with id: ' . $id . ' has been deleted.');
+ $this->controllerClass->redirect('/' . Inflector::underscore($this->controllerClass->viewPath));
+ } else {
+ return $this->controllerClass->flash('The ' . Inflector::humanize($this->modelKey) . ' with id: ' . $id . ' has been deleted.',
+ '/' . Inflector::underscore($this->controllerClass->viewPath));
+ }
+ } else {
+ if (isset($this->controllerClass->Session) && $this->controllerClass->Session->valid != false) {
+ $this->controllerClass->Session->setFlash('There was an error deleting the ' . Inflector::humanize($this->modelKey) . ' with the id ' . $id);
+ $this->controllerClass->redirect('/' . Inflector::underscore($this->controllerClass->viewPath));
+ } else {
+ return $this->controllerClass->flash('There was an error deleting the ' . Inflector::humanize($this->modelKey) . ' with the id ' . $id,
+ '/' . Inflector::underscore($this->controllerClass->viewPath));
+ }
+ }
+ } elseif ($this->controllerClass->_scaffoldError('delete') === false) {
+ return $this->__scaffoldError();
+ }
+ }
+/**
+ * Enter description here...
+ *
+ * @return unknown
+ */
+ function __scaffoldError() {
+ if (file_exists(APP . 'views' . DS . $this->viewPath . DS . 'scaffolds' . DS . 'scaffold.error.thtml')) {
+ return $this->controllerClass->render($this->actionView, '',
+ APP . 'views' . DS . $this->viewPath . DS . 'scaffolds' . DS . 'scaffold.error.thtml');
+ } elseif (file_exists(APP . 'views' . DS . 'scaffold' . DS . 'scaffold.error.thtml')) {
+ return $this->controllerClass->render($this->actionView, '',
+ APP . 'views' . DS . 'scaffold' . DS . 'scaffold.error.thtml');
+ } else {
+ return $this->controllerClass->render($this->actionView, '',
+ LIBS . 'view' . DS . 'templates' . DS . 'errors' . DS . 'scaffold_error.thtml');
+ }
+ }
+/**
+ * When forms are submited the arrays need to be rebuilt if
+ * an error occured, here the arrays are rebuilt to structure needed
+ *
+ * @param array $params data passed to forms
+ * @return array rebuilds the association arrays to pass back to Controller::generateFieldNames()
+ */
+ function __rebuild($params) {
+ foreach ($params as $model => $field) {
+ if (!empty($field) && is_array($field)) {
+ $match = array_keys($field);
+
+ if ($model == $match[0]) {
+ $count = 0;
+
+ foreach ($field[$model] as $value) {
+ $params[$model][$count][$this->controllerClass->{$this->modelKey}->{$model}->primaryKey] = $value;
+ $count++;
+ }
+ unset ($params[$model][$model]);
+ }
+ }
+ }
+ return $params;
+ }
+/**
+ * When methods are now present in a controller
+ * scaffoldView is used to call default Scaffold methods if:
+ * <code>
+ * var $scaffold;
+ * </code>
+ * is placed in the controller's class definition.
+ *
+ * @param string $url
+ * @param string $controller_class
+ * @param array $params
+ * @since Cake v 0.10.0.172
+ * @access private
+ */
+ function __scaffold($params) {
+ if (!in_array('Form', $this->controllerClass->helpers)) {
+ $this->controllerClass->helpers[] = 'Form';
+ }
+ if ($this->controllerClass->constructClasses()) {
+ $db =& ConnectionManager::getDataSource($this->controllerClass->{$this->modelKey}->useDbConfig);
+
+ if (isset($db)) {
+ if ($params['action'] === 'index' || $params['action'] === 'list' || $params['action'] === 'view'
+ || $params['action'] === 'add' || $params['action'] === 'create'
+ || $params['action'] === 'edit' || $params['action'] === 'update'
+ || $params['action'] === 'delete') {
+
+ switch($params['action']) {
+ case 'index':
+ $this->__scaffoldIndex($params);
+ break;
+ case 'view':
+ $this->__scaffoldView($params);
+ break;
+ case 'list':
+ $this->__scaffoldIndex($params);
+ break;
+ case 'add':
+ $this->__scaffoldForm($params, 'add');
+ break;
+ case 'edit':
+ $this->__scaffoldForm($params, 'edit');
+ break;
+ case 'create':
+ $this->__scaffoldSave($params, 'create');
+ break;
+ case 'update':
+ $this->__scaffoldSave($params, 'update');
+ break;
+ case 'delete':
+ $this->__scaffoldDelete($params);
+ break;
+ }
+ } else {
+ return $this->cakeError('missingAction',
+ array(array('className' => Inflector::camelize($params['controller'] . "Controller"),
+ 'base' => $this->controllerClass->base,
+ 'action' => $params['action'],
+ 'webroot' => $this->controllerClass->webroot)));
+ }
+ } else {
+ return $this->cakeError('missingDatabase', array(array('webroot' => $this->controllerClass->webroot)));
+ }
+ } else {
+ return $this->cakeError('missingModel', array(array('className' => $this->modelKey, 'webroot' => '', 'base' => $this->base)));
+ }
+ }
+}
+?> \ No newline at end of file
diff --git a/site/cake/libs/error.php b/site/cake/libs/error.php
new file mode 100644
index 0000000..af13128
--- /dev/null
+++ b/site/cake/libs/error.php
@@ -0,0 +1,347 @@
+<?php
+/* SVN FILE: $Id: error.php 6305 2008-01-02 02:33:56Z phpnut $ */
+/**
+ * Short description for file.
+ *
+ * Long description for file
+ *
+ * PHP versions 4 and 5
+ *
+ * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
+ * Copyright 2005-2008, Cake Software Foundation, Inc.
+ * 1785 E. Sahara Avenue, Suite 490-204
+ * Las Vegas, Nevada 89104
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
+ * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
+ * @package cake
+ * @subpackage cake.cake.libs
+ * @since CakePHP(tm) v 0.10.5.1732
+ * @version $Revision: 6305 $
+ * @modifiedby $LastChangedBy: phpnut $
+ * @lastmodified $Date: 2008-01-01 20:33:56 -0600 (Tue, 01 Jan 2008) $
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+uses('sanitize');
+/**
+ * Short description for file.
+ *
+ * Long description for file
+ *
+ * @package cake
+ * @subpackage cake.cake.libs
+ */
+class ErrorHandler extends Object {
+ var $controller = null;
+
+/**
+ * Class constructor.
+ *
+ * @param string $method
+ * @param array $messages
+ * @return unknown
+ */
+ function __construct($method, $messages) {
+ parent::__construct();
+ static $__previousError = null;
+ $allow = array('.', '/', '_', ' ', '-', '~');
+ if (substr(PHP_OS,0,3) == "WIN") {
+ $allow = array_merge($allow, array('\\', ':') );
+ }
+ $clean = new Sanitize();
+ $messages = $clean->paranoid($messages, $allow);
+ if (!class_exists('Dispatcher')) {
+ require CAKE . 'dispatcher.php';
+ }
+ $this->__dispatch =& new Dispatcher();
+
+ if ($__previousError != array($method, $messages)) {
+ $__previousError = array($method, $messages);
+
+ if (!class_exists('AppController')) {
+ loadController(null);
+ }
+
+ $this->controller =& new AppController();
+ if (!empty($this->controller->uses)) {
+ $this->controller->constructClasses();
+ }
+ $this->controller->_initComponents();
+ $this->controller->cacheAction = false;
+ $this->__dispatch->start($this->controller);
+
+ if (method_exists($this->controller, 'apperror')) {
+ return $this->controller->appError($method, $messages);
+ }
+ } else {
+ $this->controller =& new Controller();
+ $this->controller->cacheAction = false;
+ }
+ if (Configure::read() > 0 || $method == 'error') {
+ call_user_func_array(array(&$this, $method), $messages);
+ } else {
+ call_user_func_array(array(&$this, 'error404'), $messages);
+ }
+ }
+/**
+ * Displays an error page (e.g. 404 Not found).
+ *
+ * @param array $params
+ */
+ function error($params) {
+ extract($params);
+ $this->controller->base = $base;
+ $this->controller->webroot = $this->_webroot();
+ $this->controller->viewPath='errors';
+ $this->controller->set(array('code' => $code,
+ 'name' => $name,
+ 'message' => $message,
+ 'title' => $code . ' ' . $name));
+ $this->controller->render('error404');
+ exit();
+ }
+/**
+ * Convenience method to display a 404 page.
+ *
+ * @param array $params
+ */
+ function error404($params) {
+ extract($params);
+
+ if (!isset($url)) {
+ $url = $action;
+ }
+ if (!isset($message)) {
+ $message = '';
+ }
+ if (!isset($base)) {
+ $base = '';
+ }
+
+ header("HTTP/1.0 404 Not Found");
+ $this->error(array('code' => '404',
+ 'name' => 'Not found',
+ 'message' => sprintf("The requested address %s was not found on this server.", $url, $message),
+ 'base' => $base));
+ exit();
+ }
+/**
+ * Renders the Missing Controller web page.
+ *
+ * @param array $params
+ */
+ function missingController($params) {
+ extract($params);
+ $this->controller->base = $base;
+ $this->controller->webroot = $webroot;
+ $this->controller->viewPath ='errors';
+ $controllerName = str_replace('Controller', '', $className);
+ $this->controller->set(array('controller' => $className,
+ 'controllerName' => $controllerName,
+ 'title' => 'Missing Controller'));
+ $this->controller->render('missingController');
+ exit();
+ }
+/**
+ * Renders the Missing Action web page.
+ *
+ * @param array $params
+ */
+ function missingAction($params) {
+ extract($params);
+ $this->controller->base = $base;
+ $this->controller->webroot = $webroot;
+ $this->controller->viewPath = 'errors';
+ $this->controller->set(array('controller' => $className,
+ 'action' => $action,
+ 'title' => 'Missing Method in Controller'));
+ $this->controller->render('missingAction');
+ exit();
+ }
+/**
+ * Renders the Private Action web page.
+ *
+ * @param array $params
+ */
+ function privateAction($params) {
+ extract($params);
+ $this->controller->base = $base;
+ $this->controller->webroot = $webroot;
+ $this->controller->viewPath = 'errors';
+ $this->controller->set(array('controller' => $className,
+ 'action' => $action,
+ 'title' => 'Trying to access private method in class'));
+ $this->controller->render('privateAction');
+ exit();
+ }
+/**
+ * Renders the Missing Table web page.
+ *
+ * @param array $params
+ */
+ function missingTable($params) {
+ extract($params);
+ $this->controller->viewPath = 'errors';
+ $this->controller->webroot = $this->_webroot();
+ $this->controller->set(array('model' => $className,
+ 'table' => $table,
+ 'title' => 'Missing Database Table'));
+ $this->controller->render('missingTable');
+ exit();
+ }
+/**
+ * Renders the Missing Database web page.
+ *
+ * @param array $params
+ */
+ function missingDatabase($params = array()) {
+ extract($params);
+ $this->controller->viewPath = 'errors';
+ $this->controller->webroot = $this->_webroot();
+ $this->controller->set(array('title' => 'Scaffold Missing Database Connection'));
+ $this->controller->render('missingScaffolddb');
+ exit();
+ }
+/**
+ * Renders the Missing View web page.
+ *
+ * @param array $params
+ */
+ function missingView($params) {
+ extract($params);
+ $this->controller->base = $base;
+ $this->controller->viewPath = 'errors';
+ $this->controller->webroot = $this->_webroot();
+ $this->controller->set(array('controller' => $className,
+ 'action' => $action,
+ 'file' => $file,
+ 'title' => 'Missing View'));
+ $this->controller->render('missingView');
+ exit();
+ }
+/**
+ * Renders the Missing Layout web page.
+ *
+ * @param array $params
+ */
+ function missingLayout($params) {
+ extract($params);
+ $this->controller->base = $base;
+ $this->controller->viewPath = 'errors';
+ $this->controller->webroot = $this->_webroot();
+ $this->controller->layout = 'default';
+ $this->controller->set(array('file' => $file,
+ 'title' => 'Missing Layout'));
+ $this->controller->render('missingLayout');
+ exit();
+ }
+/**
+ * Renders the Database Connection web page.
+ *
+ * @param array $params
+ */
+ function missingConnection($params) {
+ extract($params);
+ $this->controller->viewPath = 'errors';
+ $this->controller->webroot = $this->_webroot();
+ $this->controller->set(array('model' => $className,
+ 'title' => 'Missing Database Connection'));
+ $this->controller->render('missingConnection');
+ exit();
+ }
+/**
+ * Renders the Missing Helper file web page.
+ *
+ * @param array $params
+ */
+ function missingHelperFile($params) {
+ extract($params);
+ $this->controller->base = $base;
+ $this->controller->viewPath = 'errors';
+ $this->controller->webroot = $this->_webroot();
+ $this->controller->set(array('helperClass' => Inflector::camelize($helper) . "Helper",
+ 'file' => $file,
+ 'title' => 'Missing Helper File'));
+ $this->controller->render('missingHelperFile');
+ exit();
+ }
+/**
+ * Renders the Missing Helper class web page.
+ *
+ * @param array $params
+ */
+ function missingHelperClass($params) {
+ extract($params);
+ $this->controller->base = $base;
+ $this->controller->viewPath = 'errors';
+ $this->controller->webroot = $this->_webroot();
+ $this->controller->set(array('helperClass' => Inflector::camelize($helper) . "Helper",
+ 'file' => $file,
+ 'title' => 'Missing Helper Class'));
+ $this->controller->render('missingHelperClass');
+ exit();
+ }
+/**
+ * Renders the Missing Component file web page.
+ *
+ * @param array $params
+ */
+ function missingComponentFile($params) {
+ extract($params);
+ $this->controller->base = $base;
+ $this->controller->viewPath = 'errors';
+ $this->controller->webroot = $this->_webroot();
+ $this->controller->set(array('controller' => $className,
+ 'component' => $component,
+ 'file' => $file,
+ 'title' => 'Missing Component File'));
+ $this->controller->render('missingComponentFile');
+ exit();
+ }
+/**
+ * Renders the Missing Component class web page.
+ *
+ * @param array $params
+ */
+ function missingComponentClass($params) {
+ extract($params);
+ $this->controller->base = $base;
+ $this->controller->viewPath = 'errors';
+ $this->controller->webroot = $this->_webroot();
+ $this->controller->set(array('controller' => $className,
+ 'component' => $component,
+ 'file' => $file,
+ 'title' => 'Missing Component Class'));
+ $this->controller->render('missingComponentClass');
+ exit();
+ }
+/**
+ * Renders the Missing Model class web page.
+ *
+ * @param unknown_type $params
+ */
+ function missingModel($params) {
+ extract($params);
+ $this->controller->base = $base;
+ $this->controller->viewPath = 'errors';
+ $this->controller->webroot = $this->_webroot();
+ $this->controller->set(array('model' => $className,
+ 'title' => 'Missing Model'));
+ $this->controller->render('missingModel');
+ exit();
+ }
+/**
+ * Path to the web root.
+ *
+ * @return string full web root path
+ */
+ function _webroot() {
+ $this->__dispatch->baseUrl();
+ return $this->__dispatch->webroot;
+ }
+}
+?> \ No newline at end of file
diff --git a/site/cake/libs/file.php b/site/cake/libs/file.php
new file mode 100644
index 0000000..709eaf0
--- /dev/null
+++ b/site/cake/libs/file.php
@@ -0,0 +1,293 @@
+<?php
+/* SVN FILE: $Id: file.php 6305 2008-01-02 02:33:56Z phpnut $ */
+/**
+ * Convenience class for reading, writing and appending to files.
+ *
+ * PHP versions 4 and 5
+ *
+ * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
+ * Copyright 2005-2008, Cake Software Foundation, Inc.
+ * 1785 E. Sahara Avenue, Suite 490-204
+ * Las Vegas, Nevada 89104
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
+ * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
+ * @package cake
+ * @subpackage cake.cake.libs
+ * @since CakePHP(tm) v 0.2.9
+ * @version $Revision: 6305 $
+ * @modifiedby $LastChangedBy: phpnut $
+ * @lastmodified $Date: 2008-01-01 20:33:56 -0600 (Tue, 01 Jan 2008) $
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+/**
+ * Included libraries.
+ *
+ */
+ if (!class_exists('Object')) {
+ uses ('object');
+ }
+
+ if (!class_exists('Folder')) {
+ uses ('folder');
+ }
+/**
+ * Convenience class for reading, writing and appending to files.
+ *
+ * @package cake
+ * @subpackage cake.cake.libs
+ */
+class File extends Object{
+/**
+ * Folder of the File
+ *
+ * @var Folder
+ */
+ var $folder = null;
+/**
+ * Filename
+ *
+ * @var string
+ */
+ var $name = null;
+/**
+ * Constructor
+ *
+ * @param string $path
+ * @param boolean $create Create file if it does not exist
+ * @return File
+ */
+ function __construct($path, $create = false) {
+ parent::__construct();
+ $this->folder = new Folder(dirname($path), $create);
+ $this->name = basename($path);
+ if (!$this->exists()) {
+ if ($create === true) {
+ if (!$this->create()) {
+ return false;
+ }
+ } else {
+ return false;
+ }
+ }
+ }
+/**
+ * Return the contents of this File as a string.
+ *
+ * @return string Contents
+ */
+ function read() {
+ $contents = file_get_contents($this->getFullPath());
+ return $contents;
+ }
+/**
+ * Append given data string to this File.
+ *
+ * @param string $data Data to write
+ * @return boolean Success
+ */
+ function append($data) {
+ return $this->write($data, 'a');
+ }
+/**
+ * Write given data to this File.
+ *
+ * @param string $data Data to write to this File.
+ * @param string $mode Mode of writing. {@link http://php.net/fwrite See fwrite()}.
+ * @return boolean Success
+ */
+ function write($data, $mode = 'w') {
+ $file = $this->getFullPath();
+ if (!($handle = fopen($file, $mode))) {
+ print ("[File] Could not open $file with mode $mode!");
+ return false;
+ }
+
+ if (!fwrite($handle, $data)) {
+ return false;
+ }
+
+ if (!fclose($handle)) {
+ return false;
+ }
+ return true;
+ }
+/**
+ * Get md5 Checksum of file with previous check of Filesize
+ *
+ * @param string $force Data to write to this File.
+ * @return string md5 Checksum {@link http://php.net/md5_file See md5_file()}
+ */
+ function getMd5($force = false) {
+ $md5 = '';
+ if ($force == true || $this->getSize(false) < MAX_MD5SIZE) {
+ $md5 = md5_file($this->getFullPath());
+ }
+ return $md5;
+ }
+/**
+ * Returns the Filesize, either in bytes or in human-readable format.
+ *
+ * @param boolean $humanReadeble Data to write to this File.
+ * @return string|int filesize as int or as a human-readable string
+ */
+ function getSize() {
+ $size = filesize($this->getFullPath());
+ return $size;
+ }
+/**
+ * Returns the File extension.
+ *
+ * @return string The Fileextension
+ */
+ function getExt() {
+ $ext = '';
+ $parts = explode('.', $this->getName());
+
+ if (count($parts) > 1) {
+ $ext = array_pop($parts);
+ } else {
+ $ext = '';
+ }
+ return $ext;
+ }
+/**
+ * Returns the filename.
+ *
+ * @return string The Filename
+ */
+ function getName() {
+ return $this->name;
+ }
+/**
+ * Returns the File's owner.
+ *
+ * @return int the Fileowner
+ */
+ function getOwner() {
+ $fileowner = fileowner($this->getFullPath());
+ return $fileowner;
+ }
+/**
+ * Returns the File group.
+ *
+ * @return int the Filegroup
+ */
+ function getGroup() {
+ $filegroup = filegroup($this->getFullPath());
+ return $filegroup;
+ }
+/**
+ * Creates the File.
+ *
+ * @return boolean Success
+ */
+ function create() {
+ $dir = $this->folder->pwd();
+
+ if (file_exists($dir) && is_dir($dir) && is_writable($dir) && !$this->exists()) {
+ if (!touch($this->getFullPath())) {
+ print ('[File] Could not create '.$this->getName().'!');
+ return false;
+ } else {
+ return true;
+ }
+ } else {
+ print ('[File] Could not create '.$this->getName().'!');
+ return false;
+ }
+ }
+/**
+ * Returns true if the File exists.
+ *
+ * @return boolean
+ */
+ function exists() {
+ $exists = file_exists($this->getFullPath());
+ return $exists;
+ }
+/**
+ * Deletes the File.
+ *
+ * @return boolean
+ */
+ function delete() {
+ $unlink = unlink($this->getFullPath());
+ return $unlink;
+ }
+/**
+ * Returns true if the File is writable.
+ *
+ * @return boolean
+ */
+ function writable() {
+ $writable = is_writable($this->getFullPath());
+ return $writable;
+ }
+/**
+ * Returns true if the File is executable.
+ *
+ * @return boolean
+ */
+ function executable() {
+ $executable = is_executable($this->getFullPath());
+ return $executable;
+ }
+/**
+ * Returns true if the File is readable.
+ *
+ * @return boolean
+ */
+ function readable() {
+ $readable = is_readable($this->getFullPath());
+ return $readable;
+ }
+/**
+ * Returns last access time.
+ *
+ * @return int timestamp
+ */
+ function lastAccess() {
+ $fileatime = fileatime($this->getFullPath());
+ return $fileatime;
+ }
+/**
+ * Returns last modified time.
+ *
+ * @return int timestamp
+ */
+ function lastChange() {
+ $filemtime = filemtime($this->getFullPath());
+ return $filemtime;
+ }
+/**
+ * Returns the current folder.
+ *
+ * @return Folder
+ */
+ function getFolder() {
+ return $this->folder;
+ }
+/**
+ * Returns the "chmod" (permissions) of the File.
+ *
+ * @return string
+ */
+ function getChmod() {
+ $substr = substr(sprintf('%o', fileperms($this->getFullPath())), -4);
+ return $substr;
+ }
+/**
+ * Returns the full path of the File.
+ *
+ * @return string
+ */
+ function getFullPath() {
+ return $this->folder->slashTerm($this->folder->pwd()) . $this->getName();
+ }
+}
+?> \ No newline at end of file
diff --git a/site/cake/libs/flay.php b/site/cake/libs/flay.php
new file mode 100644
index 0000000..cf09686
--- /dev/null
+++ b/site/cake/libs/flay.php
@@ -0,0 +1,278 @@
+<?php
+/* SVN FILE: $Id: flay.php 6305 2008-01-02 02:33:56Z phpnut $ */
+/**
+ * Text-to-HTML parser.
+ *
+ * Text-to-html parser, similar to {@link http://textism.com/tools/textile/ Textile} or {@link http://www.whytheluckystiff.net/ruby/redcloth/ RedCloth}.
+ *
+ * PHP versions 4 and 5
+ *
+ * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
+ * Copyright 2005-2008, Cake Software Foundation, Inc.
+ * 1785 E. Sahara Avenue, Suite 490-204
+ * Las Vegas, Nevada 89104
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
+ * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
+ * @package cake
+ * @subpackage cake.cake.libs
+ * @since CakePHP(tm) v 0.2.9
+ * @version $Revision: 6305 $
+ * @modifiedby $LastChangedBy: phpnut $
+ * @lastmodified $Date: 2008-01-01 20:33:56 -0600 (Tue, 01 Jan 2008) $
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+/**
+ * Included libraries.
+ *
+ */
+ if (!class_exists('Object')) {
+ uses ('object');
+ }
+/**
+ * Text-to-HTML parser.
+ *
+ * Text-to-html parser, similar to Textile or RedCloth, only with a little different syntax.
+ *
+ * @package cake
+ * @subpackage cake.cake.libs
+ */
+class Flay extends Object{
+/**
+ * Text to be parsed.
+ *
+ * @var string
+ */
+ var $text = null;
+/**
+ * Set this to allow HTML in the markup.
+ *
+ * @var boolean
+ */
+ var $allow_html = false;
+/**
+ * Constructor.
+ *
+ * @param string $text
+ */
+ function __construct($text = null) {
+ $this->text = $text;
+ parent::__construct();
+ }
+/**
+ * Returns given text translated to HTML using the Flay syntax.
+ *
+ * @param string $text String to format
+ * @param boolean $bare Set this to only do <p> transforms and > to &gt;, no typography additions.
+ * @param boolean $allowHtml Set this to trim whitespace and disable all HTML
+ * @return string Formatted text
+ */
+ function toHtml($text = null, $bare = false, $allowHtml = false) {
+ if (empty($text) && empty($this->text)) {
+ return false;
+ }
+ $text = $text ? $text : $this->text;
+ // trim whitespace and disable all HTML
+ if ($allowHtml) {
+ $text = trim($text);
+ } else {
+ $text = str_replace('<', '&lt;', str_replace('>', '&gt;', trim($text)));
+ }
+
+ if (!$bare) {
+ // multi-paragraph functions
+ $text=preg_replace('#(?:[\n]{0,2})"""(.*)"""(?:[\n]{0,2})#s', "\n\n%BLOCKQUOTE%\n\n\\1\n\n%ENDBLOCKQUOTE%\n\n", $text);
+ $text=preg_replace('#(?:[\n]{0,2})===(.*)===(?:[\n]{0,2})#s', "\n\n%CENTER%\n\n\\1\n\n%ENDCENTER%\n\n", $text);
+ }
+
+ // pre-parse newlines
+ $text=preg_replace("#\r\n#", "\n", $text);
+ $text=preg_replace("#[\n]{2,}#", "%PARAGRAPH%", $text);
+ $text=preg_replace('#[\n]{1}#', "%LINEBREAK%", $text);
+ $out ='';
+
+ foreach (split('%PARAGRAPH%', $text)as $line) {
+ if ($line) {
+ if (!$bare) {
+ $links = array();
+ $regs = null;
+
+ if (preg_match_all('#\[([^\[]{4,})\]#', $line, $regs)) {
+ foreach ($regs[1] as $reg) {
+ $links[] = $reg;
+ $line = str_replace("[{$reg}]", '%LINK' . (count($links) - 1) . '%', $line);
+ }
+ }
+ // bold
+ $line = ereg_replace("\*([^\*]*)\*", "<strong>\\1</strong>", $line);
+ // italic
+ $line = ereg_replace("_([^_]*)_", "<em>\\1</em>", $line);
+ }
+ // entities
+ $line = str_replace(' - ', ' &ndash; ', $line);
+ $line = str_replace(' -- ', ' &mdash; ', $line);
+ $line = str_replace('(C)', '&copy;', $line);
+ $line = str_replace('(R)', '&reg;', $line);
+ $line = str_replace('(TM)', '&trade;', $line);
+ // guess e-mails
+ $emails = null;
+ if (preg_match_all("#([_A-Za-z0-9+-+]+(?:\.[_A-Za-z0-9+-]+)*@[A-Za-z0-9-]+(?:\.[A-Za-z0-9-]+)*)#", $line, $emails)) {
+ foreach ($emails[1] as $email) {
+ $line = str_replace($email, "<a href=\"mailto:{$email}\">{$email}</a>", $line);
+ }
+ }
+
+ if (!$bare) {
+ $urls = null;
+ if (preg_match_all("#((?:http|https|ftp|nntp)://[^ ]+)#", $line, $urls)) {
+ foreach ($urls[1] as $url) {
+ $line = str_replace($url, "<a href=\"{$url}\">{$url}</a>", $line);
+ }
+ }
+
+ if (preg_match_all("#(www\.[^\n\%\ ]+[^\n\%\,\.\ ])#", $line, $urls)) {
+ foreach ($urls[1] as $url) {
+ $line = str_replace($url, "<a href=\"http://{$url}\">{$url}</a>", $line);
+ }
+ }
+
+ if (count($links)) {
+ for ($ii = 0; $ii < count($links); $ii++) {
+ if (preg_match("#^(http|https|ftp|nntp)://#", $links[$ii])) {
+ $prefix = null;
+ } else {
+ $prefix = 'http://';
+ }
+ if (preg_match('#^[^\ ]+\.(jpg|jpeg|gif|png)$#', $links[$ii])) {
+ $with = "<img src=\"{$prefix}{$links[$ii]}\" alt=\"\" />";
+ } elseif (preg_match('#^([^\]\ ]+)(?:\ ([^\]]+))?$#', $links[$ii], $regs)) {
+ if (isset($regs[2])) {
+ if (preg_match('#\.(jpg|jpeg|gif|png)$#', $regs[2])) {
+ $body = "<img src=\"{$prefix}{$regs[2]}\" alt=\"\" />";
+ } else {
+ $body = $regs[2];
+ }
+ } else {
+ $body = $links[$ii];
+ }
+ $with = "<a href=\"{$prefix}{$regs[1]}\" target=\"_blank\">{$body}</a>";
+ } else {
+ $with = $prefix . $links[$ii];
+ }
+ $line = str_replace("%LINK{$ii}%", $with, $line);
+ }
+ }
+ }
+ $out .= str_replace('%LINEBREAK%', "<br />\n", "<p>{$line}</p>\n");
+ }
+ }
+
+ if (!$bare) {
+ $out = str_replace('<p>%BLOCKQUOTE%</p>', "<blockquote>", $out);
+ $out = str_replace('<p>%ENDBLOCKQUOTE%</p>', "</blockquote>", $out);
+ $out = str_replace('<p>%CENTER%</p>', "<center>", $out);
+ $out = str_replace('<p>%ENDCENTER%</p>', "</center>", $out);
+ }
+ return $out;
+ }
+/**
+ * Return the words of the string as an array.
+ *
+ * @param string $string
+ * @return array Array of words
+ */
+ function extractWords($string) {
+ $split = preg_split('/[\s,\.:\/="!\(\)<>~\[\]]+/', $string);
+ return $split;
+ }
+/**
+ * Return given string with words in array colorMarked, up to a number of times (defaults to 5).
+ *
+ * @param array $words Words to look for and markup
+ * @param string $string String to look in
+ * @param integer $max_snippets Max number of snippets to extract
+ * @return string
+ * @see colorMark
+ */
+ function markedSnippets($words, $string, $max_snippets = 5) {
+ $string = strip_tags($string);
+ $snips = array();
+ $rest = $string;
+ foreach ($words as $word) {
+ if (preg_match_all("/[\s,]+.{0,40}{$word}.{0,40}[\s,]+/i", $rest, $r)) {
+ foreach ($r as $result) {
+ $rest = str_replace($result, '', $rest);
+ }
+ $snips = array_merge($snips, $r[0]);
+ }
+ }
+
+ if (count($snips) > $max_snippets) {
+ $snips = array_slice($snips, 0, $max_snippets);
+ }
+ $joined = join(' <b>...</b> ', $snips);
+ $snips = $joined ? "<b>...</b> {$joined} <b>...</b>" : substr($string, 0, 80) . '<b>...</b>';
+ return $this->colorMark($words, $snips);
+ }
+/**
+ * Returns string with EM elements with color classes added.
+ *
+ * @param array $words Array of words to be colorized
+ * @param string $string Text in which the words might be found
+ * @return string
+ */
+ function colorMark($words, $string) {
+ $colors=array('yl', 'gr', 'rd', 'bl', 'fu', 'cy');
+ $nextColorIndex = 0;
+ foreach ($words as $word) {
+ $string = preg_replace("/({$word})/i", '<em class="' . $colors[$nextColorIndex % count($colors)] . "\">\\1</em>", $string);
+ $nextColorIndex++;
+ }
+ return $string;
+ }
+/**
+ * Returns given text with tags stripped out.
+ *
+ * @param string $text
+ * @return string
+ */
+ function toClean($text) {
+ $strip = strip_tags(html_entity_decode($text, ENT_QUOTES));
+ return $strip;
+ }
+/**
+ * Return parsed text with tags stripped out.
+ *
+ * @param string $text
+ * @return string
+ */
+ function toParsedAndClean($text) {
+ return $this->toClean(Flay::toHtml($text));
+ }
+/**
+ * Return a fragment of a text, up to $length characters long, with an ellipsis after it.
+ *
+ * @param string $text Text to be truncated.
+ * @param integer $length Max length of text.
+ * @param string $ellipsis Sign to print after truncated text.
+ * @return string
+ */
+ function fragment($text, $length, $ellipsis = '...') {
+ $soft = $length - 5;
+ $hard = $length + 5;
+ $rx = '/(.{' . $soft . ',' . $hard . '})[\s,\.:\/="!\(\)<>~\[\]]+.*/';
+
+ if (preg_match($rx, $text, $r)) {
+ $out = $r[1];
+ } else {
+ $out = substr($text, 0, $length);
+ }
+ $out = $out . (strlen($out) < strlen($text) ? $ellipsis : null);
+ return $out;
+ }
+}
+?> \ No newline at end of file
diff --git a/site/cake/libs/folder.php b/site/cake/libs/folder.php
new file mode 100644
index 0000000..965c37e
--- /dev/null
+++ b/site/cake/libs/folder.php
@@ -0,0 +1,328 @@
+<?php
+/* SVN FILE: $Id: folder.php 6305 2008-01-02 02:33:56Z phpnut $ */
+/**
+ * Convenience class for handling directories.
+ *
+ * PHP versions 4 and 5
+ *
+ * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
+ * Copyright 2005-2008, Cake Software Foundation, Inc.
+ * 1785 E. Sahara Avenue, Suite 490-204
+ * Las Vegas, Nevada 89104
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
+ * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
+ * @package cake
+ * @subpackage cake.cake.libs
+ * @since CakePHP(tm) v 0.2.9
+ * @version $Revision: 6305 $
+ * @modifiedby $LastChangedBy: phpnut $
+ * @lastmodified $Date: 2008-01-01 20:33:56 -0600 (Tue, 01 Jan 2008) $
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+/**
+ * Included libraries.
+ *
+ */
+ if (!class_exists('Object')) {
+ uses ('object');
+ }
+/**
+ * Folder structure browser, lists folders and files.
+ *
+ * Long description for class
+ *
+ * @package cake
+ * @subpackage cake.cake.libs
+ */
+class Folder extends Object{
+/**
+ * Path to Folder.
+ *
+ * @var string
+ */
+ var $path = null;
+/**
+ * Sortedness.
+ *
+ * @var boolean
+ */
+ var $sort = false;
+/**
+ * Constructor.
+ *
+ * @param string $path
+ * @param boolean $path
+ */
+ function __construct($path = false, $create = false, $mode = false) {
+ parent::__construct();
+ if (empty($path)) {
+ $path = getcwd();
+ }
+
+ if (!file_exists($path) && $create == true) {
+ $this->mkdirr($path, $mode);
+ }
+ $this->cd($path);
+ }
+/**
+ * Return current path.
+ *
+ * @return string Current path
+ */
+ function pwd() {
+ return $this->path;
+ }
+/**
+ * Change directory to $desired_path.
+ *
+ * @param string $desired_path Path to the directory to change to
+ * @return string The new path. Returns false on failure
+ */
+ function cd($desiredPath) {
+ $desiredPath = realpath($desiredPath);
+ $newPath = $this->isAbsolute($desiredPath) ? $desiredPath : $this->addPathElement($this->path, $desiredPath);
+ $isDir = (is_dir($newPath) && file_exists($newPath)) ? $this->path = $newPath : false;
+ return $isDir;
+ }
+/**
+ * Returns an array of the contents of the current directory, or false on failure.
+ * The returned array holds two arrays: one of dirs and one of files.
+ *
+ * @param boolean $sort
+ * @param boolean $noDotFiles
+ * @return array
+ */
+ function ls($sort = true, $noDotFiles = false) {
+ $dirs = $files = array();
+ $dir = opendir($this->path);
+ if ($dir) {
+ while (false !== ($n = readdir($dir))) {
+ if ((!preg_match('#^\.+$#', $n) && $noDotFiles == false) || ($noDotFiles == true && !preg_match('#^\.(.*)$#', $n))) {
+ if (is_dir($this->addPathElement($this->path, $n))) {
+ $dirs[] = $n;
+ } else {
+ $files[] = $n;
+ }
+ }
+ }
+
+ if ($sort || $this->sort) {
+ sort ($dirs);
+ sort ($files);
+ }
+ closedir ($dir);
+ }
+ return array($dirs,$files);
+ }
+/**
+ * Returns an array of all matching files in current directory.
+ *
+ * @param string $pattern Preg_match pattern (Defaults to: .*)
+ * @return array
+ */
+ function find($regexp_pattern = '.*') {
+ $data = $this->ls();
+
+ if (!is_array($data)) {
+ return array();
+ }
+
+ list($dirs, $files) = $data;
+ $found = array();
+
+ foreach ($files as $file) {
+ if (preg_match("/^{$regexp_pattern}$/i", $file)) {
+ $found[] = $file;
+ }
+ }
+ return $found;
+ }
+/**
+ * Returns an array of all matching files in and below current directory.
+ *
+ * @param string $pattern Preg_match pattern (Defaults to: .*)
+ * @return array Files matching $pattern
+ */
+ function findRecursive($pattern = '.*') {
+ $startsOn = $this->path;
+ $out = $this->_findRecursive($pattern);
+ $this->cd($startsOn);
+ return $out;
+ }
+/**
+ * Private helper function for findRecursive.
+ *
+ * @param string $pattern
+ * @return array Files matching pattern
+ * @access private
+ */
+ function _findRecursive($pattern) {
+ list($dirs, $files) = $this->ls();
+
+ $found = array();
+ foreach ($files as $file) {
+ if (preg_match("/^{$pattern}$/i", $file)) {
+ $found[] = $this->addPathElement($this->path, $file);
+ }
+ }
+ $start = $this->path;
+ foreach ($dirs as $dir) {
+ $this->cd($this->addPathElement($start, $dir));
+ $found = array_merge($found, $this->findRecursive($pattern));
+ }
+ return $found;
+ }
+/**
+ * Returns true if given $path is a Windows path.
+ *
+ * @param string $path Path to check
+ * @return boolean
+ * @static
+ */
+ function isWindowsPath($path) {
+ $match = preg_match('#^[A-Z]:\\\#i', $path) ? true : false;
+ return $match;
+ }
+/**
+ * Returns true if given $path is an absolute path.
+ *
+ * @param string $path Path to check
+ * @return boolean
+ * @static
+ */
+ function isAbsolute($path) {
+ $match = preg_match('#^\/#', $path) || preg_match('#^[A-Z]:\\\#i', $path);
+ return $match;
+ }
+/**
+ * Returns true if given $path ends in a slash (i.e. is slash-terminated).
+ *
+ * @param string $path Path to check
+ * @return boolean
+ * @static
+ */
+ function isSlashTerm($path) {
+ $match = preg_match('#[\\\/]$#', $path) ? true : false;
+ return $match;
+ }
+/**
+ * Returns a correct set of slashes for given $path. (\\ for Windows paths and / for other paths.)
+ *
+ * @param string $path Path to check
+ * @return string Set of slashes ("\\" or "/")
+ * @static
+ */
+ function correctSlashFor($path) {
+ return $this->isWindowsPath($path) ? '\\' : '/';
+ }
+/**
+ * Returns $path with added terminating slash (corrected for Windows or other OS).
+ *
+ * @param string $path Path to check
+ * @return string
+ * @static
+ */
+function slashTerm($path) {
+ return $path . ($this->isSlashTerm($path) ? null : $this->correctSlashFor($path));
+ }
+/**
+ * Returns $path with $element added, with correct slash in-between.
+ *
+ * @param string $path
+ * @param string $element
+ * @return string
+ * @static
+ */
+ function addPathElement($path, $element) {
+ return $this->slashTerm($path) . $element;
+ }
+/**
+ * Returns true if the File is in a given CakePath.
+ *
+ * @return boolean
+ */
+ function inCakePath($path = '') {
+ $dir = substr($this->slashTerm(ROOT), 0, -1);
+ $newdir = $this->slashTerm($dir . $path);
+ return $this->inPath($newdir);
+ }
+/**
+ * Returns true if the File is in given path.
+ *
+ * @return boolean
+ */
+ function inPath($path = '') {
+ $dir = substr($this->slashTerm($path), 0, -1);
+ $return = preg_match('/^' . preg_quote($this->slashTerm($dir), '/') . '(.*)/', $this->slashTerm($this->pwd()));
+ if ($return == 1) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+/**
+ * Create a directory structure recursively.
+ *
+ * @param string $pathname The directory structure to create
+ * @return bool Returns TRUE on success, FALSE on failure
+ */
+ function mkdirr($pathname, $mode = null) {
+ if (is_dir($pathname) || empty($pathname)) {
+ return true;
+ }
+
+ if (is_file($pathname)) {
+ trigger_error('mkdirr() File exists', E_USER_WARNING);
+ return false;
+ }
+ $nextPathname = substr($pathname, 0, strrpos($pathname, DIRECTORY_SEPARATOR));
+
+ if ($this->mkdirr($nextPathname, $mode)) {
+ if (!file_exists($pathname)) {
+ umask (0);
+ $mkdir = mkdir($pathname, $mode);
+ return $mkdir;
+ }
+ }
+ return false;
+ }
+/**
+ * Returns the size in bytes of this Folder.
+ *
+ * @param string $directory Path to directory
+ */
+ function dirsize() {
+ $size = 0;
+ $directory = $this->slashTerm($this->path);
+ $stack = array($directory);
+ $count = count($stack);
+ for ($i = 0, $j = $count; $i < $j; ++$i) {
+ if (is_file($stack[$i])) {
+ $size += filesize($stack[$i]);
+ } elseif (is_dir($stack[$i])) {
+ $dir = dir($stack[$i]);
+
+ while (false !== ($entry = $dir->read())) {
+ if ($entry == '.' || $entry == '..') {
+ continue;
+ }
+ $add = $stack[$i] . $entry;
+
+ if (is_dir($stack[$i] . $entry)) {
+ $add = $this->slashTerm($add);
+ }
+ $stack[ ]= $add;
+ }
+ $dir->close();
+ }
+ $j = count($stack);
+ }
+ return $size;
+ }
+}
+?> \ No newline at end of file
diff --git a/site/cake/libs/inflector.php b/site/cake/libs/inflector.php
new file mode 100644
index 0000000..012a6c8
--- /dev/null
+++ b/site/cake/libs/inflector.php
@@ -0,0 +1,437 @@
+<?php
+/* SVN FILE: $Id: inflector.php 6305 2008-01-02 02:33:56Z phpnut $ */
+/**
+ * Pluralize and singularize English words.
+ *
+ * Used by Cake's naming conventions throughout the framework.
+ *
+ * PHP versions 4 and 5
+ *
+ * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
+ * Copyright 2005-2008, Cake Software Foundation, Inc.
+ * 1785 E. Sahara Avenue, Suite 490-204
+ * Las Vegas, Nevada 89104
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
+ * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
+ * @package cake
+ * @subpackage cake.cake.libs
+ * @since CakePHP(tm) v 0.2.9
+ * @version $Revision: 6305 $
+ * @modifiedby $LastChangedBy: phpnut $
+ * @lastmodified $Date: 2008-01-01 20:33:56 -0600 (Tue, 01 Jan 2008) $
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+/**
+ * Included libraries.
+ *
+ */
+ if (!class_exists('Object')) {
+ uses('object');
+ }
+ uses('Set');
+/**
+ * Pluralize and singularize English words.
+ *
+ * Inflector pluralizes and singularizes English nouns.
+ * Used by Cake's naming conventions throughout the framework.
+ * Test with $i = new Inflector(); $i->test();
+ *
+ * @package cake
+ * @subpackage cake.cake.libs
+ */
+class Inflector extends Object {
+/**
+ * Constructor.
+ *
+ */
+ function __construct() {
+ parent::__construct();
+ }
+/**
+ * Gets a reference to the Inflector object instance
+ *
+ * @return object
+ * @access public
+ */
+ function &getInstance() {
+ static $instance = array();
+
+ if (!isset($instance[0]) || !$instance[0]) {
+ $instance[0] =& new Inflector();
+ }
+
+ return $instance[0];
+ }
+/**
+ * Initializes plural inflection rules
+ *
+ * @access protected
+ */
+ function __initPluralRules() {
+ $_this =& Inflector::getInstance();
+ $corePluralRules = array('/(s)tatus$/i' => '\1\2tatuses',
+ '/(quiz)$/i' => '\1zes',
+ '/^(ox)$/i' => '\1\2en',
+ '/([m|l])ouse$/i' => '\1ice',
+ '/(matr|vert|ind)(ix|ex)$/i' => '\1ices',
+ '/(x|ch|ss|sh)$/i' => '\1es',
+ '/([^aeiouy]|qu)y$/i' => '\1ies',
+ '/(hive)$/i' => '\1s',
+ '/(?:([^f])fe|([lr])f)$/i' => '\1\2ves',
+ '/sis$/i' => 'ses',
+ '/([ti])um$/i' => '\1a',
+ '/(p)erson$/i' => '\1eople',
+ '/(m)an$/i' => '\1en',
+ '/(c)hild$/i' => '\1hildren',
+ '/(buffal|tomat)o$/i' => '\1\2oes',
+ '/(alumn|bacill|cact|foc|fung|nucle|radi|stimul|syllab|termin|vir)us$/i' => '\1i',
+ '/us$/' => 'uses',
+ '/(alias)$/i' => '\1es',
+ '/(ax|cri|test)is$/i' => '\1es',
+ '/s$/' => 's',
+ '/$/' => 's',);
+
+ $coreUninflectedPlural = array('.*[nrlm]ese', '.*deer', '.*fish', '.*measles', '.*ois', '.*pox', '.*sheep', 'Amoyese',
+ 'bison', 'Borghese', 'bream', 'breeches', 'britches', 'buffalo', 'cantus', 'carp', 'chassis', 'clippers',
+ 'cod', 'coitus', 'Congoese', 'contretemps', 'corps', 'debris', 'diabetes', 'djinn', 'eland', 'elk',
+ 'equipment', 'Faroese', 'flounder', 'Foochowese', 'gallows', 'Genevese', 'Genoese', 'Gilbertese', 'graffiti',
+ 'headquarters', 'herpes', 'hijinks', 'Hottentotese', 'information', 'innings', 'jackanapes', 'Kiplingese',
+ 'Kongoese', 'Lucchese', 'mackerel', 'Maltese', 'media', 'mews', 'moose', 'mumps', 'Nankingese', 'news',
+ 'nexus', 'Niasese', 'Pekingese', 'Piedmontese', 'pincers', 'Pistoiese', 'pliers', 'Portuguese', 'proceedings',
+ 'rabies', 'rice', 'rhinoceros', 'salmon', 'Sarawakese', 'scissors', 'sea[- ]bass', 'series', 'Shavese', 'shears',
+ 'siemens', 'species', 'swine', 'testes', 'trousers', 'trout', 'tuna', 'Vermontese', 'Wenchowese',
+ 'whiting', 'wildebeest', 'Yengeese',);
+
+ $coreIrregularPlural = array('atlas' => 'atlases',
+ 'beef' => 'beefs',
+ 'brother' => 'brothers',
+ 'child' => 'children',
+ 'corpus' => 'corpuses',
+ 'cow' => 'cows',
+ 'ganglion' => 'ganglions',
+ 'genie' => 'genies',
+ 'genus' => 'genera',
+ 'graffito' => 'graffiti',
+ 'hoof' => 'hoofs',
+ 'loaf' => 'loaves',
+ 'man' => 'men',
+ 'money' => 'monies',
+ 'mongoose' => 'mongooses',
+ 'move' => 'moves',
+ 'mythos' => 'mythoi',
+ 'numen' => 'numina',
+ 'occiput' => 'occiputs',
+ 'octopus' => 'octopuses',
+ 'opus' => 'opuses',
+ 'ox' => 'oxen',
+ 'penis' => 'penises',
+ 'person' => 'people',
+ 'sex' => 'sexes',
+ 'soliloquy' => 'soliloquies',
+ 'testis' => 'testes',
+ 'trilby' => 'trilbys',
+ 'turf' => 'turfs',);
+
+ $pluralRules = $corePluralRules;
+ $uninflected = $coreUninflectedPlural;
+ $irregular = $coreIrregularPlural;
+
+ if (file_exists(CONFIGS . 'inflections.php')) {
+ include(CONFIGS.'inflections.php');
+ $pluralRules = Set::pushDiff($pluralRules, $corePluralRules);
+ $uninflected = Set::pushDiff($uninflectedPlural, $coreUninflectedPlural);
+ $irregular = Set::pushDiff($irregularPlural, $coreIrregularPlural);
+ }
+ $_this->pluralRules = array('pluralRules' => $pluralRules, 'uninflected' => $uninflected, 'irregular' => $irregular);
+ $_this->pluralized = array();
+ }
+/**
+ * Return $word in plural form.
+ *
+ * @param string $word Word in singular
+ * @return string Word in plural
+ * @access public
+ * @static
+ */
+ function pluralize($word) {
+
+ $_this =& Inflector::getInstance();
+ if (!isset($_this->pluralRules) || empty($_this->pluralRules)) {
+ $_this->__initPluralRules();
+ }
+
+ if (isset($_this->pluralized[$word])) {
+ return $_this->pluralized[$word];
+ }
+
+ extract($_this->pluralRules);
+ if (!isset($regexUninflected) || !isset($regexIrregular)) {
+ $regexUninflected = __enclose(join( '|', $uninflected));
+ $regexIrregular = __enclose(join( '|', array_keys($irregular)));
+ $_this->pluralRules['regexUninflected'] = $regexUninflected;
+ $_this->pluralRules['regexIrregular'] = $regexIrregular;
+ }
+
+ if (preg_match('/(.*)\\b(' . $regexIrregular . ')$/i', $word, $regs)) {
+ $_this->pluralized[$word] = $regs[1] . substr($word, 0, 1) . substr($irregular[strtolower($regs[2])], 1);
+ return $_this->pluralized[$word];
+ }
+
+ if (preg_match('/^(' . $regexUninflected . ')$/i', $word, $regs)) {
+ $_this->pluralized[$word] = $word;
+ return $word;
+ }
+
+ foreach ($pluralRules as $rule => $replacement) {
+ if (preg_match($rule, $word)) {
+ $_this->pluralized[$word] = preg_replace($rule, $replacement, $word);
+ return $_this->pluralized[$word];
+ }
+ }
+ $_this->pluralized[$word] = $word;
+ return $word;
+ }
+/**
+ * Initializes singular inflection rules
+ *
+ * @access protected
+ */
+ function __initSingularRules() {
+
+ $_this =& Inflector::getInstance();
+ $coreSingularRules = array('/(s)tatuses$/i' => '\1\2tatus',
+ '/^(.*)(menu)s$/i' => '\1\2',
+ '/(quiz)zes$/i' => '\\1',
+ '/(matr)ices$/i' => '\1ix',
+ '/(vert|ind)ices$/i' => '\1ex',
+ '/^(ox)en/i' => '\1',
+ '/(alias)(es)*$/i' => '\1',
+ '/(alumn|bacill|cact|foc|fung|nucle|radi|stimul|syllab|termin|viri?)i$/i' => '\1us',
+ '/(cris|ax|test)es$/i' => '\1is',
+ '/(shoe)s$/i' => '\1',
+ '/(o)es$/i' => '\1',
+ '/ouses$/' => 'ouse',
+ '/uses$/' => 'us',
+ '/([m|l])ice$/i' => '\1ouse',
+ '/(x|ch|ss|sh)es$/i' => '\1',
+ '/(m)ovies$/i' => '\1\2ovie',
+ '/(s)eries$/i' => '\1\2eries',
+ '/([^aeiouy]|qu)ies$/i' => '\1y',
+ '/([lr])ves$/i' => '\1f',
+ '/(tive)s$/i' => '\1',
+ '/(hive)s$/i' => '\1',
+ '/(drive)s$/i' => '\1',
+ '/([^f])ves$/i' => '\1fe',
+ '/(^analy)ses$/i' => '\1sis',
+ '/((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$/i' => '\1\2sis',
+ '/([ti])a$/i' => '\1um',
+ '/(p)eople$/i' => '\1\2erson',
+ '/(m)en$/i' => '\1an',
+ '/(c)hildren$/i' => '\1\2hild',
+ '/(n)ews$/i' => '\1\2ews',
+ '/^(.*us)$/' => '\\1',
+ '/s$/i' => '');
+
+ $coreUninflectedSingular = array('.*[nrlm]ese', '.*deer', '.*fish', '.*measles', '.*ois', '.*pox', '.*sheep', '.*ss', 'Amoyese',
+ 'bison', 'Borghese', 'bream', 'breeches', 'britches', 'buffalo', 'cantus', 'carp', 'chassis', 'clippers',
+ 'cod', 'coitus', 'Congoese', 'contretemps', 'corps', 'debris', 'diabetes', 'djinn', 'eland', 'elk',
+ 'equipment', 'Faroese', 'flounder', 'Foochowese', 'gallows', 'Genevese', 'Genoese', 'Gilbertese', 'graffiti',
+ 'headquarters', 'herpes', 'hijinks', 'Hottentotese', 'information', 'innings', 'jackanapes', 'Kiplingese',
+ 'Kongoese', 'Lucchese', 'mackerel', 'Maltese', 'media', 'mews', 'moose', 'mumps', 'Nankingese', 'news',
+ 'nexus', 'Niasese', 'Pekingese', 'Piedmontese', 'pincers', 'Pistoiese', 'pliers', 'Portuguese', 'proceedings',
+ 'rabies', 'rice', 'rhinoceros', 'salmon', 'Sarawakese', 'scissors', 'sea[- ]bass', 'series', 'Shavese', 'shears',
+ 'siemens', 'species', 'swine', 'testes', 'trousers', 'trout', 'tuna', 'Vermontese', 'Wenchowese',
+ 'whiting', 'wildebeest', 'Yengeese',);
+
+ $coreIrregularSingular = array('atlases' => 'atlas',
+ 'beefs' => 'beef',
+ 'brothers' => 'brother',
+ 'children' => 'child',
+ 'corpuses' => 'corpus',
+ 'cows' => 'cow',
+ 'ganglions' => 'ganglion',
+ 'genies' => 'genie',
+ 'genera' => 'genus',
+ 'graffiti' => 'graffito',
+ 'hoofs' => 'hoof',
+ 'loaves' => 'loaf',
+ 'men' => 'man',
+ 'monies' => 'money',
+ 'mongooses' => 'mongoose',
+ 'moves' => 'move',
+ 'mythoi' => 'mythos',
+ 'numina' => 'numen',
+ 'occiputs' => 'occiput',
+ 'octopuses' => 'octopus',
+ 'opuses' => 'opus',
+ 'oxen' => 'ox',
+ 'penises' => 'penis',
+ 'people' => 'person',
+ 'sexes' => 'sex',
+ 'soliloquies' => 'soliloquy',
+ 'testes' => 'testis',
+ 'trilbys' => 'trilby',
+ 'turfs' => 'turf',);
+
+ $singularRules = $coreSingularRules;
+ $uninflected = $coreUninflectedSingular;
+ $irregular = $coreIrregularSingular;
+
+ if (file_exists(CONFIGS . 'inflections.php')) {
+ include(CONFIGS.'inflections.php');
+ $singularRules = Set::pushDiff($singularRules, $coreSingularRules);
+ $uninflected = Set::pushDiff($uninflectedSingular, $coreUninflectedSingular);
+ $irregular = Set::pushDiff($irregularSingular, $coreIrregularSingular);
+ }
+ $_this->singularRules = array('singularRules' => $singularRules, 'uninflected' => $uninflected, 'irregular' => $irregular);
+ $_this->singularized = array();
+ }
+/**
+ * Return $word in singular form.
+ *
+ * @param string $word Word in plural
+ * @return string Word in singular
+ * @access public
+ * @static
+ */
+ function singularize($word) {
+ $_this =& Inflector::getInstance();
+ if (!isset($_this->singularRules) || empty($_this->singularRules)) {
+ $_this->__initSingularRules();
+ }
+
+ if (isset($_this->singularized[$word])) {
+ return $_this->singularized[$word];
+ }
+
+ extract($_this->singularRules);
+ if (!isset($regexUninflected) || !isset($regexIrregular)) {
+ $regexUninflected = __enclose(join( '|', $uninflected));
+ $regexIrregular = __enclose(join( '|', array_keys($irregular)));
+ $_this->singularRules['regexUninflected'] = $regexUninflected;
+ $_this->singularRules['regexIrregular'] = $regexIrregular;
+ }
+
+ if (preg_match('/(.*)\\b(' . $regexIrregular . ')$/i', $word, $regs)) {
+ $_this->singularized[$word] = $regs[1] . substr($word, 0, 1) . substr($irregular[strtolower($regs[2])], 1);
+ return $_this->singularized[$word];
+ }
+
+ if (preg_match('/^(' . $regexUninflected . ')$/i', $word, $regs)) {
+ $_this->singularized[$word] = $word;
+ return $word;
+ }
+
+ foreach ($singularRules as $rule => $replacement) {
+ if (preg_match($rule, $word)) {
+ $_this->singularized[$word] = preg_replace($rule, $replacement, $word);
+ return $_this->singularized[$word];
+ }
+ }
+ $_this->singularized[$word] = $word;
+ return $word;
+ }
+/**
+ * Returns given $lower_case_and_underscored_word as a camelCased word.
+ *
+ * @param string $lower_case_and_underscored_word Word to camelize
+ * @return string Camelized word. likeThis.
+ * @access public
+ * @static
+ */
+ function camelize($lowerCaseAndUnderscoredWord) {
+ $replace = str_replace(" ", "", ucwords(str_replace("_", " ", $lowerCaseAndUnderscoredWord)));
+ return $replace;
+ }
+/**
+ * Returns an underscore-syntaxed ($like_this_dear_reader) version of the $camel_cased_word.
+ *
+ * @param string $camel_cased_word Camel-cased word to be "underscorized"
+ * @return string Underscore-syntaxed version of the $camel_cased_word
+ * @access public
+ * @static
+ */
+ function underscore($camelCasedWord) {
+ $replace = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $camelCasedWord));
+ return $replace;
+ }
+/**
+ * Returns a human-readable string from $lower_case_and_underscored_word,
+ * by replacing underscores with a space, and by upper-casing the initial characters.
+ *
+ * @param string $lower_case_and_underscored_word String to be made more readable
+ * @return string Human-readable string
+ * @access public
+ * @static
+ */
+ function humanize($lowerCaseAndUnderscoredWord) {
+ $replace = ucwords(str_replace("_", " ", $lowerCaseAndUnderscoredWord));
+ return $replace;
+ }
+/**
+ * Returns corresponding table name for given $class_name. ("posts" for the model class "Post").
+ *
+ * @param string $class_name Name of class to get database table name for
+ * @return string Name of the database table for given class
+ * @access public
+ * @static
+ */
+ function tableize($className) {
+ $replace = Inflector::pluralize(Inflector::underscore($className));
+ return $replace;
+ }
+/**
+ * Returns Cake model class name ("Post" for the database table "posts".) for given database table.
+ *
+ * @param string $tableName Name of database table to get class name for
+ * @return string
+ * @access public
+ * @static
+ */
+ function classify($tableName) {
+ $replace = Inflector::camelize(Inflector::singularize($tableName));
+ return $replace;
+ }
+/**
+ * Returns camelBacked version of a string.
+ *
+ * @param string $string
+ * @return string
+ * @access public
+ * @static
+ */
+ function variable($string) {
+ $string = Inflector::camelize(Inflector::underscore($string));
+ $replace = strtolower(substr($string, 0, 1));
+ $variable = preg_replace('/\\w/', $replace, $string, 1);
+ return $variable;
+ }
+/**
+ * Returns a string with all spaces converted to $replacement and non word characters removed.
+ *
+ * @param string $string
+ * @param string $replacement
+ * @return string
+ * @access public
+ * @static
+ */
+ function slug($string, $replacement = '_') {
+ $string = preg_replace(array('/[^\w\s]/', '/\\s+/') , array(' ', $replacement), $string);
+ return $string;
+ }
+}
+/**
+ * Enclose a string for preg matching.
+ *
+ * @param string $string String to enclose
+ * @return string Enclosed string
+ */
+ function __enclose($string) {
+ return '(?:' . $string . ')';
+ }
+?> \ No newline at end of file
diff --git a/site/cake/libs/legacy.php b/site/cake/libs/legacy.php
new file mode 100644
index 0000000..48fc927
--- /dev/null
+++ b/site/cake/libs/legacy.php
@@ -0,0 +1,70 @@
+<?php
+/* SVN FILE: $Id: legacy.php 6305 2008-01-02 02:33:56Z phpnut $ */
+/**
+ * Backwards compatibility functions.
+ *
+ * With this hack you can use clone() in PHP4 code
+ * use "clone($object)" not "clone $object"! the former works in both PHP4 and PHP5
+ *
+ * PHP versions 4 and 5
+ *
+ * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
+ * Copyright 2005-2008, Cake Software Foundation, Inc.
+ * 1785 E. Sahara Avenue, Suite 490-204
+ * Las Vegas, Nevada 89104
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
+ * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
+ * @package cake
+ * @subpackage cake.cake.libs
+ * @since CakePHP(tm) v 0.2.9
+ * @version $Revision: 6305 $
+ * @modifiedby $LastChangedBy: phpnut $
+ * @lastmodified $Date: 2008-01-01 20:33:56 -0600 (Tue, 01 Jan 2008) $
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+ if (version_compare(phpversion(), '5.0') < 0) {
+ if (!function_exists("clone")) {
+ eval ('
+ function clone($object) {
+ return $object;
+ }');
+ }
+ }
+/**
+ * Replace file_get_contents()
+ *
+ * @internal resource_context is not supported
+ * @since PHP 5
+ * require PHP 4.0.0 (user_error)
+ *
+ * @param unknown_type $filename
+ * @param unknown_type $incpath
+ * @return unknown
+ */
+ if (!function_exists('file_get_contents')) {
+ function file_get_contents($filename, $incpath = false) {
+ if (false === $fh = fopen($filename, 'rb', $incpath)) {
+ user_error('file_get_contents() failed to open stream: No such file or directory', E_USER_WARNING);
+ return false;
+ }
+ clearstatcache();
+
+ if ($fsize = @filesize($filename)) {
+ $data = fread($fh, $fsize);
+ } else {
+ $data='';
+
+ while (!feof($fh)) {
+ $data .= fread($fh, 8192);
+ }
+ }
+ fclose ($fh);
+ return $data;
+ }
+}
+?> \ No newline at end of file
diff --git a/site/cake/libs/model/connection_manager.php b/site/cake/libs/model/connection_manager.php
new file mode 100644
index 0000000..df7829c
--- /dev/null
+++ b/site/cake/libs/model/connection_manager.php
@@ -0,0 +1,243 @@
+<?php
+/* SVN FILE: $Id: connection_manager.php 6305 2008-01-02 02:33:56Z phpnut $ */
+
+/**
+ * Short description for file.
+ *
+ * Long description for file
+ *
+ * PHP versions 4 and 5
+ *
+ * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
+ * Copyright 2005-2008, Cake Software Foundation, Inc.
+ * 1785 E. Sahara Avenue, Suite 490-204
+ * Las Vegas, Nevada 89104
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
+ * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
+ * @package cake
+ * @subpackage cake.cake.libs.model
+ * @since CakePHP(tm) v 0.10.x.1402
+ * @version $Revision: 6305 $
+ * @modifiedby $LastChangedBy: phpnut $
+ * @lastmodified $Date: 2008-01-01 20:33:56 -0600 (Tue, 01 Jan 2008) $
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+
+/**
+ * Manages loaded instances of DataSource objects
+ *
+ * Long description for file
+ *
+ * @package cake
+ * @subpackage cake.cake.libs.model
+ */
+
+uses ('model' . DS . 'datasources' . DS . 'datasource');
+config('database');
+
+class ConnectionManager extends Object {
+
+/**
+ * Holds a loaded instance of the Connections object
+ *
+ * @var class:Connections
+ * @access public
+ */
+ var $config = null;
+/**
+ * Holds instances DataSource objects
+ *
+ * @var array
+ * @access private
+ */
+ var $_dataSources = array();
+/**
+ * Contains a list of all file and class names used in Connection settings
+ *
+ * @var array
+ * @access private
+ */
+ var $_connectionsEnum = array();
+/**
+ * Constructor.
+ *
+ */
+ function __construct() {
+ if (class_exists('DATABASE_CONFIG')) {
+ $this->config = new DATABASE_CONFIG();
+ }
+ }
+/**
+ * Gets a reference to the ConnectionManger object instance
+ *
+ * @return object
+ */
+ function &getInstance() {
+ static $instance = array();
+
+ if (!isset($instance[0]) || !$instance[0]) {
+ $instance[0] = &new ConnectionManager();
+ }
+
+ return $instance[0];
+ }
+/**
+ * Gets a reference to a DataSource object
+ *
+ * @param string $name The name of the DataSource, as defined in app/config/connections
+ * @return object
+ */
+ function &getDataSource($name) {
+ $_this =& ConnectionManager::getInstance();
+
+ if (in_array($name, array_keys($_this->_dataSources))) {
+ return $_this->_dataSources[$name];
+ }
+
+ $connections = $_this->enumConnectionObjects();
+ if (in_array($name, array_keys($connections))) {
+ $conn = $connections[$name];
+ $class = $conn['classname'];
+ $_this->loadDataSource($name);
+ $_this->_dataSources[$name] =& new $class($_this->config->{$name});
+ $_this->_dataSources[$name]->configKeyName = $name;
+ } else {
+ trigger_error(sprintf(__("ConnectionManager::getDataSource - Non-existent data source %s", true), $name), E_USER_ERROR);
+ return null;
+ }
+
+ return $_this->_dataSources[$name];
+ }
+/**
+ * Gets a DataSource name from an object reference
+ *
+ * @param object $source
+ * @return string
+ */
+ function getSourceName(&$source) {
+ $_this =& ConnectionManager::getInstance();
+
+ $names = array_keys($_this->_dataSources);
+ for ($i = 0; $i < count($names); $i++) {
+ if ($_this->_dataSources[$names[$i]] === $source) {
+ return $names[$i];
+ }
+ }
+ return null;
+ }
+/**
+ * Loads the DataSource class for the given connection name
+ *
+ * @param mixed $connName A string name of the connection, as defined in Connections config,
+ * or an array containing the file and class name of the object.
+ * @return boolean True on success, null on failure or false if the class is already loaded
+ */
+ function loadDataSource($connName) {
+ $_this =& ConnectionManager::getInstance();
+
+ if (is_array($connName)) {
+ $conn = $connName;
+ } else {
+ $connections = $_this->enumConnectionObjects();
+ $conn = $connections[$connName];
+ }
+
+ if (isset($conn['parent']) && !empty($conn['parent'])) {
+ $_this->loadDataSource($conn['parent']);
+ }
+
+ if (class_exists($conn['classname'])) {
+ return false;
+ }
+
+ if (file_exists(MODELS . DS . $conn['filename'] . '.php')) {
+ require (MODELS . DS . $conn['filename'] . '.php');
+ } elseif (fileExistsInPath(LIBS . 'model' . DS . $conn['filename'] . '.php')) {
+ require (LIBS . 'model' . DS . $conn['filename'] . '.php');
+ } else {
+ trigger_error(sprintf(__('Unable to load DataSource file %s.php', true), $conn['filename']), E_USER_ERROR);
+ return null;
+ }
+ }
+/**
+ * Gets a list of class and file names associated with the user-defined DataSource connections
+ *
+ * @return array An associative array of elements where the key is the connection name
+ * (as defined in Connections), and the value is an array with keys 'filename' and 'classname'.
+ */
+ function enumConnectionObjects() {
+ $_this =& ConnectionManager::getInstance();
+
+ if (!empty($_this->_connectionsEnum)) {
+ return $_this->_connectionsEnum;
+ }
+ $connections = get_object_vars($_this->config);
+
+ if ($connections != null) {
+ foreach ($connections as $name => $config) {
+ $_this->_connectionsEnum[$name] = $_this->__getDriver($config);
+ }
+ return $_this->_connectionsEnum;
+ } else {
+ $_this->cakeError('missingConnection', array(array('className' => 'ConnectionManager')));
+ }
+ }
+/**
+ * Dynamically creates a DataSource object at runtime, with the given name and settings
+ *
+ * @param string $name The DataSource name
+ * @param array $config The DataSource configuration settings
+ * @return object A reference to the DataSource object, or null if creation failed
+ */
+ function &create($name = '', $config = array()) {
+ $_this =& ConnectionManager::getInstance();
+
+ if (empty($name) || empty($config) || array_key_exists($name, $_this->_connectionsEnum)) {
+ $null = null;
+ return $null;
+ }
+
+ $_this->config->{$name} = $config;
+ $_this->_connectionsEnum[$name] = $_this->__getDriver($config);
+ return $_this->getDataSource($name);
+ }
+/**
+ * Private method
+ *
+ * Returns the file and class name for the given driver
+ */
+ function __getDriver($config) {
+ $_this =& ConnectionManager::getInstance();
+
+ if (!isset($config['datasource'])) {
+ $config['datasource'] = 'dbo';
+ }
+
+ if (isset($config['driver']) && $config['driver'] != null && !empty($config['driver'])) {
+ $filename = $config['datasource'] . DS . $config['datasource'] . '_' . $config['driver'];
+ $classname = Inflector::camelize(strtolower($config['datasource'] . '_' . $config['driver']));
+ $parent = $_this->__getDriver(array('datasource' => $config['datasource']));
+ } else {
+ $filename = 'datasources' . DS . $config['datasource'] . '_source';
+ $classname = Inflector::camelize(strtolower($config['datasource'] . '_source'));
+ $parent = null;
+ }
+ return array('filename' => $filename, 'classname' => $classname, 'parent' => $parent);
+ }
+/**
+ * Destructor.
+ *
+ */
+ function __destruct() {
+ if (CAKE_SESSION_SAVE == 'database' && function_exists('session_write_close')) {
+ session_write_close();
+ }
+ }
+}
+
+?> \ No newline at end of file
diff --git a/site/cake/libs/model/datasources/datasource.php b/site/cake/libs/model/datasources/datasource.php
new file mode 100644
index 0000000..c58b59d
--- /dev/null
+++ b/site/cake/libs/model/datasources/datasource.php
@@ -0,0 +1,492 @@
+<?php
+/* SVN FILE: $Id: datasource.php 6305 2008-01-02 02:33:56Z phpnut $ */
+/**
+ * DataSource base class
+ *
+ * Long description for file
+ *
+ * PHP versions 4 and 5
+ *
+ * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
+ * Copyright 2005-2008, Cake Software Foundation, Inc.
+ * 1785 E. Sahara Avenue, Suite 490-204
+ * Las Vegas, Nevada 89104
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
+ * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
+ * @package cake
+ * @subpackage cake.cake.libs.model.datasources
+ * @since CakePHP(tm) v 0.10.5.1790
+ * @version $Revision: 6305 $
+ * @modifiedby $LastChangedBy: phpnut $
+ * @lastmodified $Date: 2008-01-01 20:33:56 -0600 (Tue, 01 Jan 2008) $
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+/**
+ * DataSource base class
+ *
+ * Long description for file
+ *
+ * @package cake
+ * @subpackage cake.cake.libs.model.datasources
+ */
+class DataSource extends Object {
+/**
+ * Are we connected to the DataSource?
+ *
+ * @var boolean
+ * @access public
+ */
+ var $connected = false;
+/**
+ * Print debug info?
+ *
+ * @var boolean
+ * @access public
+ */
+ var $debug = false;
+/**
+ * Print full query debug info?
+ *
+ * @var boolean
+ * @access public
+ */
+ var $fullDebug = false;
+/**
+ * Error description of last query
+ *
+ * @var unknown_type
+ * @access public
+ */
+ var $error = null;
+/**
+ * String to hold how many rows were affected by the last SQL operation.
+ *
+ * @var string
+ * @access public
+ */
+ var $affected = null;
+/**
+ * Number of rows in current resultset
+ *
+ * @var int
+ * @access public
+ */
+ var $numRows = null;
+/**
+ * Time the last query took
+ *
+ * @var int
+ * @access public
+ */
+ var $took = null;
+/**
+ * Enter description here...
+ *
+ * @var array
+ * @access private
+ */
+ var $_result = null;
+/**
+ * Queries count.
+ *
+ * @var int
+ * @access private
+ */
+ var $_queriesCnt = 0;
+/**
+ * Total duration of all queries.
+ *
+ * @var unknown_type
+ * @access private
+ */
+ var $_queriesTime = null;
+/**
+ * Log of queries executed by this DataSource
+ *
+ * @var unknown_type
+ * @access private
+ */
+ var $_queriesLog = array();
+/**
+ * Maximum number of items in query log, to prevent query log taking over
+ * too much memory on large amounts of queries -- I we've had problems at
+ * >6000 queries on one system.
+ *
+ * @var int Maximum number of queries in the queries log.
+ * @access private
+ */
+ var $_queriesLogMax = 200;
+/**
+ * Caches serialzed results of executed queries
+ *
+ * @var array Maximum number of queries in the queries log.
+ * @access private
+ */
+ var $_queryCache = array();
+/**
+ * The default configuration of a specific DataSource
+ *
+ * @var array
+ * @access public
+ */
+ var $_baseConfig = array();
+/**
+ * Holds references to descriptions loaded by the DataSource
+ *
+ * @var array
+ * @access private
+ */
+ var $__descriptions = array();
+/**
+ * Holds a list of sources (tables) contained in the DataSource
+ *
+ * @var array
+ * @access protected
+ */
+ var $_sources = null;
+/**
+ * A reference to the physical connection of this DataSource
+ *
+ * @var array
+ * @access public
+ */
+ var $connection = null;
+/**
+ * The DataSource configuration
+ *
+ * @var array
+ * @access public
+ */
+ var $config = array();
+/**
+ * The DataSource configuration key name
+ *
+ * @var string
+ * @access public
+ */
+ var $configKeyName = null;
+/**
+ * Whether or not this DataSource is in the middle of a transaction
+ *
+ * @var boolean
+ * @access protected
+ */
+ var $_transactionStarted = false;
+/**
+ * Enter description here...
+ *
+ * @var boolean
+ */
+ var $cacheSources = true;
+/**
+ * Constructor.
+ */
+ function __construct() {
+ parent::__construct();
+ if (func_num_args() > 0) {
+ $this->setConfig(func_get_arg(0));
+ }
+ }
+/**
+ * Caches/returns cached results for child instances
+ *
+ * @return array
+ */
+ function listSources($data = null) {
+ if ($this->cacheSources === false) {
+ return null;
+ }
+ if ($this->_sources != null) {
+ return $this->_sources;
+ }
+
+ if (Configure::read() > 0) {
+ $expires = "+30 seconds";
+ } else {
+ $expires = "+999 days";
+ }
+
+ if ($data != null) {
+ $data = serialize($data);
+ }
+ $filename = ConnectionManager::getSourceName($this) . '_' . preg_replace("/[^A-Za-z0-9_-]/", "_", $this->config['database']) . '_list';
+ $new = cache('models' . DS . $filename, $data, $expires);
+
+ if ($new != null) {
+ $new = unserialize($new);
+ $this->_sources = $new;
+ }
+ return $new;
+ }
+/**
+ * Convenience method for DboSource::listSources(). Returns source names in lowercase.
+ *
+ * @return array
+ */
+ function sources() {
+ $return = array_map('strtolower', $this->listSources());
+ return $return;
+ }
+/**
+ * Returns a Model description (metadata) or null if none found.
+ *
+ * @param Model $model
+ * @return mixed
+ */
+ function describe($model) {
+ if ($this->cacheSources === false) {
+ return null;
+ }
+ if (isset($this->__descriptions[$model->tablePrefix . $model->table])) {
+ return $this->__descriptions[$model->tablePrefix . $model->table];
+ }
+ $cache = $this->__cacheDescription($model->tablePrefix . $model->table);
+
+ if ($cache !== null) {
+ $this->__descriptions[$model->tablePrefix . $model->table] =& $cache;
+ return $cache;
+ }
+ return null;
+ }
+/**
+ * Converts column types to basic types
+ *
+ * @param string $real Real column type (i.e. "varchar(255)")
+ * @return string Abstract column type (i.e. "string")
+ */
+ function column($real) {
+ return false;
+ }
+/**
+ * To-be-overridden in subclasses.
+ *
+ * @param unknown_type $model
+ * @param unknown_type $fields
+ * @param unknown_type $values
+ * @return unknown
+ */
+ function create(&$model, $fields = null, $values = null) {
+ return false;
+ }
+/**
+ * To-be-overridden in subclasses.
+ *
+ * @param unknown_type $model
+ * @param unknown_type $queryData
+ * @return unknown
+ */
+ function read(&$model, $queryData = array()) {
+ return false;
+ }
+/**
+ * To-be-overridden in subclasses.
+ *
+ * @param unknown_type $model
+ * @param unknown_type $fields
+ * @param unknown_type $values
+ * @return unknown
+ */
+ function update(&$model, $fields = null, $values = null) {
+ return false;
+ }
+/**
+ * To-be-overridden in subclasses.
+ *
+ * @param unknown_type $model
+ * @param unknown_type $id
+ */
+ function delete(&$model, $id = null) {
+ if ($id == null) {
+ $id = $model->id;
+ }
+ }
+/**
+ * Returns the ID generated from the previous INSERT operation.
+ *
+ * @param unknown_type $source
+ * @return in
+ */
+ function lastInsertId($source = null) {
+ return false;
+ }
+/**
+ * Returns the ID generated from the previous INSERT operation.
+ *
+ * @param unknown_type $source
+ * @return in
+ */
+ function lastNumRows($source = null) {
+ return false;
+ }
+/**
+ * Returns the ID generated from the previous INSERT operation.
+ *
+ * @param unknown_type $source
+ * @return in
+ */
+ function lastAffected($source = null) {
+ return false;
+ }
+/**
+ * Returns true if the DataSource supports the given interface (method)
+ *
+ * @param string $interface The name of the interface (method)
+ * @return boolean True on success
+ */
+ function isInterfaceSupported($interface) {
+ $methods = get_class_methods(get_class($this));
+ $methods = strtolower(implode('|', $methods));
+ $methods = explode('|', $methods);
+ $return = in_array(strtolower($interface), $methods);
+ return $return;
+ }
+/**
+ * Sets the configuration for the DataSource
+ *
+ * @param array $config The configuration array
+ * @return void
+ */
+ function setConfig($config) {
+ if (is_array($this->_baseConfig)) {
+ $this->config = $this->_baseConfig;
+ foreach ($config as $key => $val) {
+ $this->config[$key] = $val;
+ }
+ }
+ }
+/**
+ * Cache the DataSource description
+ *
+ * @param string $object The name of the object (model) to cache
+ * @param mixed $data The description of the model, usually a string or array
+ * @return void
+ */
+ function __cacheDescription($object, $data = null) {
+ if ($this->cacheSources === false) {
+ return null;
+ }
+ if (Configure::read() > 0) {
+ $expires = "+15 seconds";
+ } else {
+ $expires = "+999 days";
+ }
+
+ if ($data !== null) {
+ $this->__descriptions[$object] =& $data;
+ $cache = serialize($data);
+ } else {
+ $cache = null;
+ }
+ $new = cache('models' . DS . ConnectionManager::getSourceName($this) . '_' . $object, $cache, $expires);
+
+ if ($new != null) {
+ $new = unserialize($new);
+ }
+ return $new;
+ }
+/**
+ * Enter description here...
+ *
+ * @param unknown_type $query
+ * @param unknown_type $data
+ * @param unknown_type $association
+ * @param unknown_type $assocData
+ * @param Model $model
+ * @param Model $linkModel
+ * @param array $stack
+ * @return unknown
+ */
+ function insertQueryData($query, $data, $association, $assocData, &$model, &$linkModel, $stack) {
+ $keys = array('{$__cakeID__$}', '{$__cakeForeignKey__$}');
+
+ foreach ($keys as $key) {
+ $val = null;
+
+ if (strpos($query, $key) !== false) {
+ switch($key) {
+ case '{$__cakeID__$}':
+ if (isset($data[$model->name]) || isset($data[$association])) {
+ if (isset($data[$model->name][$model->primaryKey])) {
+ $val = $data[$model->name][$model->primaryKey];
+ } elseif (isset($data[$association][$model->primaryKey])) {
+ $val = $data[$association][$model->primaryKey];
+ }
+ } else {
+ $found = false;
+ foreach (array_reverse($stack) as $assoc) {
+ if (isset($data[$assoc]) && isset($data[$assoc][$model->primaryKey])) {
+ $val = $data[$assoc][$model->primaryKey];
+ $found = true;
+ break;
+ }
+ }
+ if (!$found) {
+ $val = '';
+ }
+ }
+ break;
+ case '{$__cakeForeignKey__$}':
+ foreach ($model->__associations as $id => $name) {
+ foreach ($model->$name as $assocName => $assoc) {
+ if ($assocName === $association) {
+ if (isset($assoc['foreignKey'])) {
+ $foreignKey = $assoc['foreignKey'];
+
+ if (isset($data[$model->name][$foreignKey])) {
+ $val = $data[$model->name][$foreignKey];
+ } elseif (isset($data[$association][$foreignKey])) {
+ $val = $data[$association][$foreignKey];
+ } else {
+ $found = false;
+ foreach (array_reverse($stack) as $assoc) {
+ if (isset($data[$assoc]) && isset($data[$assoc][$foreignKey])) {
+ $val = $data[$assoc][$foreignKey];
+ $found = true;
+ break;
+ }
+ }
+ if (!$found) {
+ $val = '';
+ }
+ }
+ }
+ break 3;
+ }
+ }
+ }
+ break;
+ }
+ if (empty($val) && $val !== '0') {
+ return false;
+ }
+ $query = r($key, $this->value($val, $model->getColumnType($model->primaryKey)), $query);
+ }
+ }
+ return $query;
+ }
+/**
+ * To-be-overridden in subclasses.
+ *
+ * @param unknown_type $model
+ * @param unknown_type $key
+ * @return unknown
+ */
+ function resolveKey($model, $key) {
+ return $model->name . $key;
+ }
+/**
+ * Closes the current datasource.
+ *
+ */
+ function __destruct() {
+ if ($this->connected) {
+ $this->close();
+ }
+ }
+}
+?> \ No newline at end of file
diff --git a/site/cake/libs/model/datasources/dbo_source.php b/site/cake/libs/model/datasources/dbo_source.php
new file mode 100644
index 0000000..150b0e7
--- /dev/null
+++ b/site/cake/libs/model/datasources/dbo_source.php
@@ -0,0 +1,1894 @@
+<?php
+/* SVN FILE: $Id: dbo_source.php 6305 2008-01-02 02:33:56Z phpnut $ */
+/**
+ * Short description for file.
+ *
+ * Long description for file
+ *
+ * PHP versions 4 and 5
+ *
+ * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
+ * Copyright 2005-2008, Cake Software Foundation, Inc.
+ * 1785 E. Sahara Avenue, Suite 490-204
+ * Las Vegas, Nevada 89104
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
+ * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
+ * @package cake
+ * @subpackage cake.cake.libs.model.datasources
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @version $Revision: 6305 $
+ * @modifiedby $LastChangedBy: phpnut $
+ * @lastmodified $Date: 2008-01-01 20:33:56 -0600 (Tue, 01 Jan 2008) $
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+uses('set');
+/**
+ * DboSource
+ *
+ * Creates DBO-descendant objects from a given db connection configuration
+ *
+ * @package cake
+ * @subpackage cake.cake.libs.model.datasources
+ */
+class DboSource extends DataSource {
+/**
+ * Description string for this Database Data Source.
+ *
+ * @var unknown_type
+ */
+ var $description = "Database Data Source";
+/**
+ * index definition, standard cake, primary, index, unique
+ *
+ * @var array
+ */
+ var $index = array('PRI'=> 'primary', 'MUL'=> 'index', 'UNI'=>'unique');
+/**
+ * Enter description here...
+ *
+ * @var unknown_type
+ */
+ var $startQuote = null;
+/**
+ * Enter description here...
+ *
+ * @var unknown_type
+ */
+ var $endQuote = null;
+/**
+ * Enter description here...
+ *
+ * @var unknown_type
+ */
+ var $alias = 'AS ';
+/**
+ * Enter description here...
+ *
+ * @var unknown_type
+ */
+ var $goofyLimit = false;
+/**
+ * Enter description here...
+ *
+ * @var unknown_type
+ */
+ var $__bypass = false;
+/**
+ * The set of valid SQL operations usable in a WHERE statement
+ *
+ * @var array
+ */
+ var $__sqlOps = array('like', 'ilike', 'or', 'not', 'in', 'between', 'regexp', 'similar to');
+/**
+ * Constructor
+ */
+ function __construct($config = null, $autoConnect = true) {
+ $this->debug = Configure::read() > 0;
+ $this->fullDebug = Configure::read() > 1;
+ parent::__construct($config);
+
+ if ($autoConnect) {
+ return $this->connect();
+ } else {
+ return true;
+ }
+ }
+/**
+ * Reconnects to database server with optional new settings
+ *
+ * @param array $config An array defining the new configuration settings
+ * @return boolean True on success, false on failure
+ */
+ function reconnect($config = null) {
+ $this->disconnect();
+ if ($config != null) {
+ $this->config = array_merge($this->_baseConfig, $config);
+ }
+ return $this->connect();
+ }
+/**
+ * Prepares a value, or an array of values for database queries by quoting and escaping them.
+ *
+ * @param mixed $data A value or an array of values to prepare.
+ * @return mixed Prepared value or array of values.
+ */
+ function value($data, $column = null) {
+ if (is_array($data)) {
+ $out = array();
+ $keys = array_keys($data);
+ $count = count($data);
+ for ($i = 0; $i < $count; $i++) {
+ $out[$keys[$i]] = $this->value($data[$keys[$i]]);
+ }
+ return $out;
+ } elseif (in_array($data, array('{$__cakeID__$}', '{$__cakeForeignKey__$}'), true)) {
+ return $data;
+ } else {
+ return null;
+ }
+ }
+/**
+ * Executes given SQL statement.
+ *
+ * @param string $sql SQL statement
+ * @return unknown
+ */
+ function rawQuery($sql) {
+ $this->took = $this->error = $this->numRows = false;
+ return $this->execute($sql);
+ }
+/**
+ * Queries the database with given SQL statement, and obtains some metadata about the result
+ * (rows affected, timing, any errors, number of rows in resultset). The query is also logged.
+ * If DEBUG is set, the log is shown all the time, else it is only shown on errors.
+ *
+ * @param string $sql
+ * @return unknown
+ */
+ function execute($sql) {
+ $t = getMicrotime();
+ $this->_result = $this->_execute($sql);
+ $this->affected = $this->lastAffected();
+ $this->took = round((getMicrotime() - $t) * 1000, 0);
+ $this->error = $this->lastError();
+ $this->numRows = $this->lastNumRows($this->_result);
+
+ if ($this->fullDebug && Configure::read() > 1) {
+ $this->logQuery($sql);
+ }
+
+ if ($this->error) {
+ $this->showQuery($sql);
+ return false;
+ } else {
+ return $this->_result;
+ }
+ }
+/**
+ * DataSource Query abstraction
+ *
+ * @return resource Result resource identifier
+ */
+ function query() {
+ $args = func_get_args();
+ $fields = null;
+ $order = null;
+ $limit = null;
+ $page = null;
+ $recursive = null;
+
+ if (count($args) == 1) {
+ return $this->fetchAll($args[0]);
+
+ } elseif (count($args) > 1 && (strpos(strtolower($args[0]), 'findby') === 0 || strpos(strtolower($args[0]), 'findallby') === 0)) {
+ $params = $args[1];
+
+ if (strpos(strtolower($args[0]), 'findby') === 0) {
+ $all = false;
+ $field = Inflector::underscore(preg_replace('/findBy/i', '', $args[0]));
+ } else {
+ $all = true;
+ $field = Inflector::underscore(preg_replace('/findAllBy/i', '', $args[0]));
+ }
+
+ $or = (strpos($field, '_or_') !== false);
+ if ($or) {
+ $field = explode('_or_', $field);
+ } else {
+ $field = explode('_and_', $field);
+ }
+ $off = count($field) - 1;
+
+ if (isset($params[1 + $off])) {
+ $fields = $params[1 + $off];
+ }
+
+ if (isset($params[2 + $off])) {
+ $order = $params[2 + $off];
+ }
+
+ if (!array_key_exists(0, $params)) {
+ return false;
+ }
+
+ $c = 0;
+ $query = array();
+ foreach ($field as $f) {
+ if (!is_array($params[$c]) && !empty($params[$c]) && $params[$c] !== true && $params[$c] !== false) {
+ $query[$args[2]->alias . '.' . $f] = '= ' . $params[$c];
+ } else {
+ $query[$args[2]->alias . '.' . $f] = $params[$c];
+ }
+ $c++;
+ }
+
+ if ($or) {
+ $query = array('OR' => $query);
+ }
+
+ if ($all) {
+
+ if (isset($params[3 + $off])) {
+ $limit = $params[3 + $off];
+ }
+
+ if (isset($params[4 + $off])) {
+ $page = $params[4 + $off];
+ }
+
+ if (isset($params[5 + $off])) {
+ $recursive = $params[5 + $off];
+ }
+ return $args[2]->findAll($query, $fields, $order, $limit, $page, $recursive);
+ } else {
+ if (isset($params[3 + $off])) {
+ $recursive = $params[3 + $off];
+ }
+ return $args[2]->find($query, $fields, $order, $recursive);
+ }
+ } else {
+ if (isset($args[1]) && $args[1] === true) {
+ return $this->fetchAll($args[0], true);
+ }
+ return $this->fetchAll($args[0], false);
+ }
+ }
+/**
+ * Returns a row from current resultset as an array .
+ *
+ * @return array The fetched row as an array
+ */
+ function fetchRow($sql = null) {
+
+ if (!empty($sql) && is_string($sql) && strlen($sql) > 5) {
+ if (!$this->execute($sql)) {
+ return null;
+ }
+ }
+
+ if (is_resource($this->_result) || is_object($this->_result)) {
+ $this->resultSet($this->_result);
+ $resultRow = $this->fetchResult();
+ return $resultRow;
+ } else {
+ return null;
+ }
+ }
+/**
+ * Returns an array of all result rows for a given SQL query.
+ * Returns false if no rows matched.
+ *
+ * @param string $sql SQL statement
+ * @param boolean $cache Enables returning/storing cached query results
+ * @return array Array of resultset rows, or false if no rows matched
+ */
+ function fetchAll($sql, $cache = true, $modelName = null) {
+ if ($cache && isset($this->_queryCache[$sql])) {
+ if (preg_match('/^\s*select/i', $sql)) {
+ return $this->_queryCache[$sql];
+ }
+ }
+
+ if ($this->execute($sql)) {
+ $out = array();
+
+ while ($item = $this->fetchRow()) {
+ $out[] = $item;
+ }
+
+ if ($cache) {
+ if (strpos(trim(strtolower($sql)), 'select') !== false) {
+ $this->_queryCache[$sql] = $out;
+ }
+ }
+ return $out;
+
+ } else {
+ return false;
+ }
+ }
+/**
+ * Returns a single field of the first of query results for a given SQL query, or false if empty.
+ *
+ * @param string $name Name of the field
+ * @param string $sql SQL query
+ * @return unknown
+ */
+ function field($name, $sql) {
+ $data = $this->fetchRow($sql);
+
+ if (!isset($data[$name]) || empty($data[$name])) {
+ return false;
+ } else {
+ return $data[$name];
+ }
+ }
+/**
+ * Returns a quoted name of $data for use in an SQL statement.
+ * Strips fields out of SQL functions before quoting.
+ *
+ * @param string $data
+ * @return string SQL field
+ */
+ function name($data) {
+ if (preg_match_all('/([^(]*)\((.*)\)(.*)/', $data, $fields)) {
+ $fields = Set::extract($fields, '{n}.0');
+ if (!empty($fields[1])) {
+ if (!empty($fields[2])) {
+ return $fields[1] . '(' . $this->name($fields[2]) . ')' . $fields[3];
+ } else {
+ return $fields[1] . '()' . $fields[3];
+ }
+ }
+ }
+ if ($data == '*') {
+ return '*';
+ }
+ $data = $this->startQuote . str_replace('.', $this->endQuote . '.' . $this->startQuote, $data) . $this->endQuote;
+ $data = str_replace($this->startQuote . $this->startQuote, $this->startQuote, $data);
+
+ if (!empty($this->endQuote) && $this->endQuote == $this->startQuote) {
+ $oddMatches = substr_count($data, $this->endQuote);
+ if ($oddMatches % 2 == 1) {
+ $data = trim($data, $this->endQuote);
+ }
+ }
+ return str_replace($this->endQuote . $this->endQuote, $this->endQuote, $data);
+ }
+/**
+ * Checks if it's connected to the database
+ *
+ * @return boolean True if the database is connected, else false
+ */
+ function isConnected() {
+ return $this->connected;
+ }
+/**
+ * Outputs the contents of the queries log.
+ *
+ * @param boolean $sorted
+ */
+ function showLog($sorted = false) {
+ if ($sorted) {
+ $log = sortByKey($this->_queriesLog, 'took', 'desc', SORT_NUMERIC);
+ } else {
+ $log = $this->_queriesLog;
+ }
+
+ if ($this->_queriesCnt > 1) {
+ $text = 'queries';
+ } else {
+ $text = 'query';
+ }
+
+ if (php_sapi_name() != 'cli') {
+ print ("<table class=\"cakeSqlLog\" id=\"cakeSqlLog_" . preg_replace('/[^A-Za-z0-9_]/', '_', uniqid(time(), true)) . "\" summary=\"Cake SQL Log\" cellspacing=\"0\" border = \"0\">\n<caption>{$this->_queriesCnt} {$text} took {$this->_queriesTime} ms</caption>\n");
+ print ("<thead>\n<tr><th>Nr</th><th>Query</th><th>Error</th><th>Affected</th><th>Num. rows</th><th>Took (ms)</th></tr>\n</thead>\n<tbody>\n");
+
+ foreach ($log as $k => $i) {
+ print ("<tr><td>" . ($k + 1) . "</td><td>" . h($i['query']) . "</td><td>{$i['error']}</td><td style = \"text-align: right\">{$i['affected']}</td><td style = \"text-align: right\">{$i['numRows']}</td><td style = \"text-align: right\">{$i['took']}</td></tr>\n");
+ }
+ print ("</tbody></table>\n");
+ } else {
+ foreach ($log as $k => $i) {
+ print (($k + 1) . ". {$i['query']} {$i['error']}\n");
+ }
+ }
+ }
+/**
+ * Log given SQL query.
+ *
+ * @param string $sql SQL statement
+ * @todo: Add hook to log errors instead of returning false
+ */
+ function logQuery($sql) {
+ $this->_queriesCnt++;
+ $this->_queriesTime += $this->took;
+ $this->_queriesLog[] = array('query' => $sql,
+ 'error' => $this->error,
+ 'affected' => $this->affected,
+ 'numRows' => $this->numRows,
+ 'took' => $this->took
+ );
+ if (count($this->_queriesLog) > $this->_queriesLogMax) {
+ array_pop($this->_queriesLog);
+ }
+ if ($this->error) {
+ return false;
+ }
+ }
+/**
+ * Output information about an SQL query. The SQL statement, number of rows in resultset,
+ * and execution time in microseconds. If the query fails, an error is output instead.
+ *
+ * @param string $sql Query to show information on.
+ */
+ function showQuery($sql) {
+ $error = $this->error;
+ if (strlen($sql) > 200 && !$this->fullDebug && Configure::read() > 1) {
+ $sql = substr($sql, 0, 200) . '[...]';
+ }
+
+ if (($this->debug || $error) && Configure::read() > 0) {
+ e("<p style = \"text-align:left\"><b>Query:</b> {$sql} ");
+ if ($error) {
+ trigger_error("<span style = \"color:Red;text-align:left\"><b>SQL Error:</b> {$this->error}</span>", E_USER_WARNING);
+ } else {
+ e("<small>[Aff:{$this->affected} Num:{$this->numRows} Took:{$this->took}ms]</small>");
+ }
+ print ('</p>');
+ }
+ }
+/**
+ * Gets full table name including prefix
+ *
+ * @param mixed $model
+ * @param boolean $quote
+ * @return string Full quoted table name
+ */
+ function fullTableName($model, $quote = true) {
+ if (is_object($model)) {
+ $table = $model->tablePrefix . $model->table;
+ } elseif (isset($this->config['prefix'])) {
+ $table = $this->config['prefix'] . strval($model);
+ } else {
+ $table = strval($model);
+ }
+ if ($quote) {
+ return $this->name($table);
+ }
+ return $table;
+ }
+/**
+ * The "C" in CRUD
+ *
+ * @param Model $model
+ * @param array $fields
+ * @param array $values
+ * @return boolean Success
+ */
+ function create(&$model, $fields = null, $values = null) {
+ $fieldInsert = array();
+ $valueInsert = array();
+ $id = null;
+
+ if ($fields == null) {
+ unset($fields, $values);
+ $fields = array_keys($model->data);
+ $values = array_values($model->data);
+ }
+ $count = count($fields);
+
+ for ($i = 0; $i < $count; $i++) {
+ $fieldInsert[] = $this->name($fields[$i]);
+ if ($fields[$i] == $model->primaryKey) {
+ $id = $values[$i];
+ }
+ }
+ $count = count($values);
+
+ for ($i = 0; $i < $count; $i++) {
+ $valueInsert[] = $this->value($values[$i], $model->getColumnType($fields[$i]));
+ }
+
+ if ($this->execute('INSERT INTO ' . $this->fullTableName($model) . ' (' . join(',', $fieldInsert). ') VALUES (' . join(',', $valueInsert) . ')')) {
+ if (empty($id)) {
+ $id = $this->lastInsertId($this->fullTableName($model, false), $model->primaryKey);
+ }
+ $model->setInsertID($id);
+ $model->id = $id;
+ return true;
+ } else {
+ $model->onError();
+ return false;
+ }
+ }
+/**
+ * The "R" in CRUD
+ *
+ * @param Model $model
+ * @param array $queryData
+ * @param integer $recursive Number of levels of association
+ * @return unknown
+ */
+ function read(&$model, $queryData = array(), $recursive = null) {
+
+ $this->__scrubQueryData($queryData);
+ $null = null;
+ $array = array();
+ $linkedModels = array();
+ $this->__bypass = false;
+
+ if ($recursive === null && isset($queryData['recursive'])) {
+ $recursive = $queryData['recursive'];
+ }
+
+ if (!is_null($recursive)) {
+ $_recursive = $model->recursive;
+ $model->recursive = $recursive;
+ }
+
+ if (!empty($queryData['fields'])) {
+ $this->__bypass = true;
+ $queryData['fields'] = $this->fields($model, null, $queryData['fields']);
+ } else {
+ $queryData['fields'] = $this->fields($model);
+ }
+
+ foreach ($model->__associations as $type) {
+ foreach ($model->{$type} as $assoc => $assocData) {
+ if ($model->recursive > -1) {
+ $linkModel =& $model->{$assoc};
+
+ $external = isset($assocData['external']);
+ if ($model->alias == $linkModel->alias && $type != 'hasAndBelongsToMany' && $type != 'hasMany') {
+ if (true === $this->generateSelfAssociationQuery($model, $linkModel, $type, $assoc, $assocData, $queryData, $external, $null)) {
+ $linkedModels[] = $type . '/' . $assoc;
+ }
+ } else {
+ if ($model->useDbConfig == $linkModel->useDbConfig) {
+ if (true === $this->generateAssociationQuery($model, $linkModel, $type, $assoc, $assocData, $queryData, $external, $null)) {
+ $linkedModels[] = $type . '/' . $assoc;
+ }
+ }
+ }
+ }
+ }
+ }
+ // Build final query SQL
+ $query = $this->generateAssociationQuery($model, $null, null, null, null, $queryData, false, $null);
+ $resultSet = $this->fetchAll($query, $model->cacheQueries, $model->alias);
+
+ if ($resultSet === false) {
+ $model->onError();
+ return false;
+ }
+
+ $filtered = $this->__filterResults($resultSet, $model);
+
+ if ($model->recursive > 0) {
+ foreach ($model->__associations as $type) {
+ foreach ($model->{$type} as $assoc => $assocData) {
+ $db = null;
+ $linkModel =& $model->{$assoc};
+
+ if (!in_array($type . '/' . $assoc, $linkedModels)) {
+ if ($model->useDbConfig == $linkModel->useDbConfig) {
+ $db =& $this;
+ } else {
+ $db =& ConnectionManager::getDataSource($linkModel->useDbConfig);
+ }
+ } elseif ($model->recursive > 1 && ($type == 'belongsTo' || $type == 'hasOne')) {
+ // Do recursive joins on belongsTo and hasOne relationships
+ $db =& $this;
+ } else {
+ unset ($db);
+ }
+
+ if (isset($db) && $db != null) {
+ $stack = array($assoc);
+ $db->queryAssociation($model, $linkModel, $type, $assoc, $assocData, $array, true, $resultSet, $model->recursive - 1, $stack);
+ unset($db);
+ }
+ }
+ }
+ $this->__filterResults($resultSet, $model, $filtered);
+ }
+
+ if (!is_null($recursive)) {
+ $model->recursive = $_recursive;
+ }
+ return $resultSet;
+ }
+/**
+ * Private method. Passes association results thru afterFind filter of corresponding model
+ *
+ * @param unknown_type $results
+ * @param unknown_type $model
+ * @param unknown_type $filtered
+ * @return unknown
+ */
+ function __filterResults(&$results, &$model, $filtered = array()) {
+
+ $filtering = array();
+ $associations = array_merge($model->belongsTo, $model->hasOne, $model->hasMany, $model->hasAndBelongsToMany);
+ $count = count($results);
+
+ for ($i = 0; $i < $count; $i++) {
+ if (is_array($results[$i])) {
+ $keys = array_keys($results[$i]);
+ $count2 = count($keys);
+
+ for ($j = 0; $j < $count2; $j++) {
+ $className = $key = $keys[$j];
+
+ if ($model->alias != $className && !in_array($key, $filtered)) {
+ if (!in_array($key, $filtering)) {
+ $filtering[] = $key;
+ }
+
+ if (isset($model->{$className}) && is_object($model->{$className})) {
+ $data = $model->{$className}->afterFind(array(array($key => $results[$i][$key])), false);
+ }
+ if (isset($data[0][$key])) {
+ $results[$i][$key] = $data[0][$key];
+ }
+ }
+ }
+ }
+ }
+ return $filtering;
+ }
+/**
+ * Enter description here...
+ *
+ * @param Model $model
+ * @param unknown_type $linkModel
+ * @param string $type Association type
+ * @param unknown_type $association
+ * @param unknown_type $assocData
+ * @param unknown_type $queryData
+ * @param unknown_type $external
+ * @param unknown_type $resultSet
+ * @param integer $recursive Number of levels of association
+ * @param array $stack
+ */
+ function queryAssociation(&$model, &$linkModel, $type, $association, $assocData, &$queryData, $external = false, &$resultSet, $recursive, $stack) {
+
+ if ($query = $this->generateAssociationQuery($model, $linkModel, $type, $association, $assocData, $queryData, $external, $resultSet)) {
+ if (!isset($resultSet) || !is_array($resultSet)) {
+ if (Configure::read() > 0) {
+ e('<div style = "font: Verdana bold 12px; color: #FF0000">SQL Error in model ' . $model->alias . ': ');
+ if (isset($this->error) && $this->error != null) {
+ e($this->error);
+ }
+ e('</div>');
+ }
+ return null;
+ }
+ $count = count($resultSet);
+
+ if ($type === 'hasMany' && (!isset($assocData['limit']) || empty($assocData['limit']))) {
+ $ins = $fetch = array();
+ for ($i = 0; $i < $count; $i++) {
+ if ($in = $this->insertQueryData('{$__cakeID__$}', $resultSet[$i], $association, $assocData, $model, $linkModel, $stack)) {
+ $ins[] = $in;
+ }
+ }
+
+ if (!empty($ins)) {
+ $query = r('{$__cakeID__$}', join(', ', $ins), $query);
+ $fetch = $this->fetchAll($query, $model->cacheQueries, $model->alias);
+ }
+
+ if (!empty($fetch) && is_array($fetch)) {
+ if ($recursive > 0) {
+
+ foreach ($linkModel->__associations as $type1) {
+ foreach ($linkModel->{$type1} as $assoc1 => $assocData1) {
+
+ $deepModel =& $linkModel->{$assocData1['className']};
+ if ($deepModel->alias != $model->alias) {
+ $tmpStack = $stack;
+ $tmpStack[] = $assoc1;
+ if ($linkModel->useDbConfig == $deepModel->useDbConfig) {
+ $db =& $this;
+ } else {
+ $db =& ConnectionManager::getDataSource($deepModel->useDbConfig);
+ }
+ $db->queryAssociation($linkModel, $deepModel, $type1, $assoc1, $assocData1, $queryData, true, $fetch, $recursive - 1, $tmpStack);
+ }
+ }
+ }
+ }
+ }
+ return $this->__mergeHasMany($resultSet, $fetch, $association, $model, $linkModel, $recursive);
+ }
+ for ($i = 0; $i < $count; $i++) {
+
+ $row =& $resultSet[$i];
+ $q = $this->insertQueryData($query, $resultSet[$i], $association, $assocData, $model, $linkModel, $stack);
+
+ if ($q != false) {
+ $fetch = $this->fetchAll($q, $model->cacheQueries, $model->alias);
+ } else {
+ $fetch = null;
+ }
+
+ if (!empty($fetch) && is_array($fetch)) {
+ if ($recursive > 0) {
+
+ foreach ($linkModel->__associations as $type1) {
+ foreach ($linkModel->{$type1} as $assoc1 => $assocData1) {
+
+ $deepModel =& $linkModel->{$assocData1['className']};
+ if ($deepModel->alias != $model->alias) {
+ $tmpStack = $stack;
+ $tmpStack[] = $assoc1;
+ if ($linkModel->useDbConfig == $deepModel->useDbConfig) {
+ $db =& $this;
+ } else {
+ $db =& ConnectionManager::getDataSource($deepModel->useDbConfig);
+ }
+ $db->queryAssociation($linkModel, $deepModel, $type1, $assoc1, $assocData1, $queryData, true, $fetch, $recursive - 1, $tmpStack);
+ }
+ }
+ }
+ }
+ $this->__mergeAssociation($resultSet[$i], $fetch, $association, $type);
+ $resultSet[$i][$association] = $linkModel->afterfind($resultSet[$i][$association]);
+
+ } else {
+ $tempArray[0][$association] = false;
+ $this->__mergeAssociation($resultSet[$i], $tempArray, $association, $type);
+ }
+ }
+ }
+ }
+
+ function __mergeHasMany(&$resultSet, $merge, $association, &$model, &$linkModel) {
+ foreach ($resultSet as $i => $value) {
+ $count = 0;
+ $merged[$association] = array();
+ foreach ($merge as $j => $data) {
+ if (isset($value[$model->alias]) && $value[$model->alias][$model->primaryKey] === $data[$association][$model->hasMany[$association]['foreignKey']]) {
+ if (count($data) > 1) {
+ $data = array_merge($data[$association], $data);
+ unset($data[$association]);
+ foreach ($data as $key => $name) {
+ if (is_numeric($key)) {
+ $data[$association][] = $name;
+ unset($data[$key]);
+ }
+ }
+ $merged[$association][] = $data;
+ } else {
+ $merged[$association][] = $data[$association];
+ }
+ }
+ $count++;
+ }
+ if (isset($value[$model->alias])) {
+ $resultSet[$i] = Set::pushDiff($resultSet[$i], $merged);
+ unset($merged);
+ }
+ }
+ }
+/**
+ * Enter description here...
+ *
+ * @param unknown_type $data
+ * @param unknown_type $merge
+ * @param unknown_type $association
+ * @param unknown_type $type
+ */
+ function __mergeAssociation(&$data, $merge, $association, $type) {
+
+ if (isset($merge[0]) && !isset($merge[0][$association])) {
+ $association = Inflector::pluralize($association);
+ }
+
+ if ($type == 'belongsTo' || $type == 'hasOne') {
+ if (isset($merge[$association])) {
+ $data[$association] = $merge[$association][0];
+ } else {
+ if (count($merge[0][$association]) > 1) {
+ foreach ($merge[0] as $assoc => $data2) {
+ if ($assoc != $association) {
+ $merge[0][$association][$assoc] = $data2;
+ }
+ }
+ }
+ if (!isset($data[$association])) {
+ if ($merge[0][$association] != null) {
+ $data[$association] = $merge[0][$association];
+ } else {
+ $data[$association] = array();
+ }
+ } else {
+ if (is_array($merge[0][$association])) {
+ foreach ($data[$association] as $k => $v) {
+ if (!is_array($v)) {
+ $dataAssocTmp[$k] = $v;
+ }
+ }
+
+ foreach ($merge[0][$association] as $k => $v) {
+ if (!is_array($v)) {
+ $mergeAssocTmp[$k] = $v;
+ }
+ }
+
+ if (array_keys($merge[0]) === array_keys($data)) {
+ $data[$association][$association] = $merge[0][$association];
+ } else {
+ $diff = Set::diff($dataAssocTmp, $mergeAssocTmp);
+ $data[$association] = array_merge($merge[0][$association], $diff);
+ }
+ }
+ }
+ }
+ } else {
+ if ($merge[0][$association] === false) {
+ if (!isset($data[$association])) {
+ $data[$association] = array();
+ }
+ } else {
+ foreach ($merge as $i => $row) {
+ if (count($row) == 1) {
+ $data[$association][] = $row[$association];
+ } else {
+ $tmp = array_merge($row[$association], $row);
+ unset($tmp[$association]);
+ $data[$association][] = $tmp;
+ }
+ }
+ }
+ }
+ }
+/**
+ * Enter description here...
+ *
+ * @param unknown_type $model
+ * @param unknown_type $linkModel
+ * @param unknown_type $type
+ * @param unknown_type $association
+ * @param unknown_type $assocData
+ * @param unknown_type $queryData
+ * @param unknown_type $external
+ * @param unknown_type $resultSet
+ * @return unknown
+ */
+ function generateSelfAssociationQuery(&$model, &$linkModel, $type, $association = null, $assocData = array(), &$queryData, $external = false, &$resultSet) {
+ $alias = $association;
+ if (empty($alias) && !empty($linkModel)) {
+ $alias = $linkModel->alias;
+ }
+
+ if (!isset($queryData['selfJoin'])) {
+ $queryData['selfJoin'] = array();
+
+ $self = array(
+ 'fields' => $this->fields($model, null, $queryData['fields']),
+ 'joins' => array(array(
+ 'table' => $this->fullTableName($linkModel),
+ 'alias' => $alias,
+ 'type' => 'LEFT',
+ 'conditions' => array(
+ $model->escapeField($assocData['foreignKey']) => '{$__cakeIdentifier[' . "{$alias}.{$linkModel->primaryKey}" . ']__$}'))
+ ),
+ 'table' => $this->fullTableName($model),
+ 'alias' => $model->alias,
+ 'limit' => $queryData['limit'],
+ 'offset' => $queryData['offset'],
+ 'conditions'=> $queryData['conditions'],
+ 'order' => $queryData['order']
+ );
+
+ if (!empty($assocData['conditions'])) {
+ $self['joins'][0]['conditions'] = trim($this->conditions(array_merge($self['joins'][0]['conditions'], (array)$assocData['conditions']), true, false));
+ }
+
+ if (!empty($queryData['joins'])) {
+ foreach ($queryData['joins'] as $join) {
+ $self['joins'][] = $join;
+ }
+ }
+
+ if ($this->__bypass === false) {
+ $self['fields'] = array_merge($self['fields'], $this->fields($linkModel, $alias, (isset($assocData['fields']) ? $assocData['fields'] : '')));
+ }
+
+ if (!in_array($self, $queryData['selfJoin'])) {
+ $queryData['selfJoin'][] = $self;
+ return true;
+ }
+
+ } elseif (isset($linkModel)) {
+ return $this->generateAssociationQuery($model, $linkModel, $type, $association, $assocData, $queryData, $external, $resultSet);
+
+ } else {
+ $result = $queryData['selfJoin'][0];
+ if (!empty($queryData['joins'])) {
+ foreach ($queryData['joins'] as $join) {
+ if (!in_array($join, $result['joins'])) {
+ $result['joins'][] = $join;
+ }
+ }
+ }
+ if (!empty($queryData['conditions'])) {
+ $result['conditions'] = trim($this->conditions(array_merge((array)$result['conditions'], $assocData['conditions']), true, false));
+ }
+ if (!empty($queryData['fields'])) {
+ $result['fields'] = array_unique(array_merge($result['fields'], $queryData['fields']));
+ }
+ $sql = $this->buildStatement($result, $model);
+ return $sql;
+ }
+ }
+/**
+ * Enter description here...
+ *
+ * @param Model $model
+ * @param unknown_type $linkModel
+ * @param unknown_type $type
+ * @param unknown_type $association
+ * @param unknown_type $assocData
+ * @param unknown_type $queryData
+ * @param unknown_type $external
+ * @param unknown_type $resultSet
+ * @return unknown
+ */
+ function generateAssociationQuery(&$model, &$linkModel, $type, $association = null, $assocData = array(), &$queryData, $external = false, &$resultSet) {
+ $this->__scrubQueryData($queryData);
+ $this->__scrubQueryData($assocData);
+ $joinedOnSelf = false;
+
+ if (empty($queryData['fields'])) {
+ $queryData['fields'] = $this->fields($model, $model->alias);
+ } elseif (!empty($model->hasMany) && $model->recursive > -1) {
+ $assocFields = $this->fields($model, $model->alias, array("{$model->alias}.{$model->primaryKey}"));
+ $passedFields = $this->fields($model, $model->alias, $queryData['fields']);
+
+ if (count($passedFields) === 1) {
+ $match = strpos($passedFields[0], $assocFields[0]);
+ $match1 = strpos($passedFields[0], 'COUNT(');
+ if ($match === false && $match1 === false) {
+ $queryData['fields'] = array_unique(array_merge($passedFields, $assocFields));
+ } else {
+ $queryData['fields'] = $passedFields;
+ }
+ } else {
+ $queryData['fields'] = array_unique(array_merge($passedFields, $assocFields));
+ }
+ unset($assocFields, $passedFields);
+ }
+
+ if ($linkModel == null) {
+ if (array_key_exists('selfJoin', $queryData)) {
+ return $this->generateSelfAssociationQuery($model, $linkModel, $type, $association, $assocData, $queryData, $external, $resultSet);
+ } else {
+ return $this->buildStatement(array(
+ 'fields' => array_unique($queryData['fields']),
+ 'table' => $this->fullTableName($model),
+ 'alias' => $model->alias,
+ 'limit' => $queryData['limit'],
+ 'offset' => $queryData['offset'],
+ 'joins' => $queryData['joins'],
+ 'conditions' => $queryData['conditions'],
+ 'order' => $queryData['order']), $model
+ );
+ }
+ }
+ $alias = $association;
+
+ if ($model->alias == $linkModel->alias) {
+ $joinedOnSelf = true;
+ }
+
+ if ($external && isset($assocData['finderQuery'])) {
+ if (!empty($assocData['finderQuery'])) {
+ return $assocData['finderQuery'];
+ }
+ }
+
+ if ((!$external && in_array($type, array('hasOne', 'belongsTo')) && $this->__bypass === false) || $external) {
+ $fields = $this->fields($linkModel, $alias, $assocData['fields']);
+ } else {
+ $fields = array();
+ }
+ $limit = '';
+
+ if (isset($assocData['limit'])) {
+ if ((!isset($assocData['offset']) || (empty($assocData['offset']))) && isset($assocData['page'])) {
+ $assocData['offset'] = ($assocData['page'] - 1) * $assocData['limit'];
+ } elseif (!isset($assocData['offset'])) {
+ $assocData['offset'] = null;
+ }
+ $limit = $this->limit($assocData['limit'], $assocData['offset']);
+ }
+
+ switch($type) {
+ case 'hasOne':
+ case 'belongsTo':
+ if ($external) {
+ if ($type == 'hasOne') {
+ $conditions = $this->__mergeConditions($assocData['conditions'], array("{$alias}.{$assocData['foreignKey']}" => '{$__cakeID__$}'));
+ } elseif ($type == 'belongsTo') {
+ $conditions = $this->__mergeConditions($assocData['conditions'], array("{$alias}.{$linkModel->primaryKey}" => '{$__cakeForeignKey__$}'));
+ }
+ $query = array_merge($assocData, array(
+ 'conditions' => $conditions,
+ 'table' => $this->fullTableName($linkModel),
+ 'fields' => $fields,
+ 'alias' => $alias
+ ));
+
+ if ($type == 'belongsTo') {
+ // Dunno if we should be doing this for hasOne also...?
+ // Or maybe not doing it at all...?
+ $query = array_merge($query, array('order' => $assocData['order'], 'limit' => $limit));
+ }
+ } else {
+ if ($type == 'hasOne') {
+ $conditions = $this->__mergeConditions($assocData['conditions'], array("{$alias}.{$assocData['foreignKey']}" => '{$__cakeIdentifier[' . "{$model->alias}.{$model->primaryKey}" . ']__$}'));
+ } elseif ($type == 'belongsTo') {
+ $conditions = $this->__mergeConditions($assocData['conditions'], array("{$model->alias}.{$assocData['foreignKey']}" => '{$__cakeIdentifier[' . "{$alias}.{$linkModel->primaryKey}" . ']__$}'));
+ }
+
+ $join = array(
+ 'table' => $this->fullTableName($linkModel),
+ 'alias' => $alias,
+ 'type' => 'LEFT',
+ 'conditions' => trim($this->conditions($conditions, true, false))
+ );
+
+ $queryData['fields'] = array_merge($queryData['fields'], $fields);
+
+ if (!empty($assocData['order'])) {
+ $queryData['order'][] = $assocData['order'];
+ }
+ if (!in_array($join, $queryData['joins'])) {
+ $queryData['joins'][] = $join;
+ }
+ return true;
+ }
+ break;
+ case 'hasMany':
+ $assocData['fields'] = array_unique(array_merge(
+ $this->fields($linkModel, $alias, $assocData['fields']),
+ $this->fields($linkModel, $alias, array("{$alias}.{$assocData['foreignKey']}"))
+ ));
+
+ $query = array(
+ 'conditions' => $this->__mergeConditions(array("{$alias}.{$assocData['foreignKey']}" => array('{$__cakeID__$}')), $assocData['conditions']),
+ 'fields' => $assocData['fields'],
+ 'table' => $this->fullTableName($linkModel),
+ 'alias' => $alias,
+ 'order' => $assocData['order'],
+ 'limit' => $limit
+ );
+ break;
+ case 'hasAndBelongsToMany':
+ $joinTbl = $this->fullTableName($assocData['joinTable']);
+ $joinFields = array();
+ $joinAssoc = null;
+ $joinAlias = $joinTbl;
+
+ if (isset($assocData['with']) && !empty($assocData['with'])) {
+ $joinAssoc = $joinAlias = $model->{$assocData['with']}->name;
+ $joinFields = $model->{$assocData['with']}->loadInfo();
+ $joinFields = $joinFields->extract('{n}.name');
+
+ if (is_array($joinFields) && !empty($joinFields) && count($joinFields) > 2) {
+ $joinFields = $this->fields($model->{$assocData['with']}, $model->{$assocData['with']}->name, $joinFields);
+ } else {
+ $joinFields = array();
+ $joinAssoc = null;
+ $joinAlias = $joinTbl;
+ }
+ }
+
+ $query = array(
+ 'conditions' => $assocData['conditions'],
+ 'limit' => $limit,
+ 'table' => $this->fullTableName($linkModel),
+ 'alias' => $alias,
+ 'fields' => array_merge($this->fields($linkModel, $alias, $assocData['fields']), $joinFields),
+ 'order' => $assocData['order'],
+ 'joins' => array(array(
+ 'table' => $joinTbl,
+ 'alias' => $joinAssoc,
+ 'conditions' => array(
+ array("{$joinAlias}.{$assocData['foreignKey']}" => '{$__cakeID__$}'),
+ array("{$joinAlias}.{$assocData['associationForeignKey']}" => '{$__cakeIdentifier['."{$alias}.{$linkModel->primaryKey}".']__$}')
+ ))
+ )
+ );
+ break;
+ }
+ if (isset($query)) {
+ return $this->buildStatement($query, $model);
+ }
+ return null;
+ }
+
+ function buildJoinStatement($join) {
+ $data = array_merge(array(
+ 'type' => null,
+ 'alias' => null,
+ 'table' => 'join_table',
+ 'conditions' => array()
+ ), $join);
+
+ if (!empty($data['alias'])) {
+ $data['alias'] = $this->alias . $this->name($data['alias']);
+ }
+ if (!empty($data['conditions'])) {
+ $data['conditions'] = trim($this->conditions($data['conditions'], true, false));
+ }
+ return $this->renderJoinStatement($data);
+ }
+
+ function buildStatement($query, $model) {
+ $query = array_merge(array('offset' => null, 'joins' => array()), $query);
+ if (!empty($query['joins'])) {
+ for ($i = 0; $i < count($query['joins']); $i++) {
+ if (is_array($query['joins'][$i])) {
+ $query['joins'][$i] = $this->buildJoinStatement($query['joins'][$i]);
+ }
+ }
+ }
+ return $this->renderStatement(array(
+ 'conditions' => $this->conditions($query['conditions']),
+ 'fields' => join(', ', $query['fields']),
+ 'table' => $query['table'],
+ 'alias' => $this->alias . $this->name($query['alias']),
+ 'order' => $this->order($query['order']),
+ 'limit' => $this->limit($query['limit'], $query['offset']),
+ 'joins' => join(' ', $query['joins'])
+ ));
+ }
+
+ function renderJoinStatement($data) {
+ extract($data);
+ return trim("{$type} JOIN {$table} {$alias} ON ({$conditions})");
+ }
+
+ function renderStatement($data) {
+ extract($data);
+ return "SELECT {$fields} FROM {$table} {$alias} {$joins} {$conditions} {$order} {$limit}";
+ }
+/**
+ * Private method
+ *
+ * @return array
+ */
+ function __mergeConditions($query, $assoc) {
+ if (!empty($assoc)) {
+ if (is_array($query)) {
+ return array_merge((array)$assoc, $query);
+ } else {
+ if (!empty($query)) {
+ $query = array($query);
+ if (is_array($assoc)) {
+ $query = array_merge($query, $assoc);
+ } else {
+ $query[] = $assoc;
+ }
+ return $query;
+ } else {
+ return $assoc;
+ }
+ }
+ }
+ return $query;
+ }
+/**
+ * Generates and executes an SQL UPDATE statement for given model, fields, and values.
+ *
+ * @param Model $model
+ * @param array $fields
+ * @param array $values
+ * @param mixed $conditions
+ * @return array
+ */
+ function update(&$model, $fields = array(), $values = null, $conditions = null) {
+ $updates = array();
+
+ if ($values == null) {
+ $combined = $fields;
+ } else {
+ $combined = array_combine($fields, $values);
+ }
+
+ foreach ($combined as $field => $value) {
+ if ($value === null) {
+ $updates[] = $this->name($field) . ' = NULL';
+ } else {
+ $update = $this->name($field) . ' = ';
+ if ($conditions == null) {
+ $update .= $this->value($value, $model->getColumnType($field));
+ } else {
+ $update .= $value;
+ }
+ $updates[] = $update;
+ }
+ }
+ $conditions = $this->defaultConditions($model, $conditions);
+
+ if ($conditions === false) {
+ return false;
+ }
+ $fields = join(',', $updates);
+ $table = $this->fullTableName($model);
+ $conditions = $this->conditions($conditions);
+
+ if (!$this->execute("UPDATE {$table} SET {$fields} {$conditions}")) {
+ $model->onError();
+ return false;
+ }
+ return true;
+ }
+/**
+ * Generates and executes an SQL DELETE statement for given id on given model.
+ *
+ * @param Model $model
+ * @param mixed $conditions
+ * @return boolean Success
+ */
+ function delete(&$model, $conditions = null) {
+ $query = $this->defaultConditions($model, $conditions);
+
+ if ($query === false) {
+ return false;
+ }
+
+ $table = $this->fullTableName($model);
+ $conditions = $this->conditions($query);
+
+ if ($this->execute("DELETE FROM {$table} {$conditions}") === false) {
+ $model->onError();
+ return false;
+ }
+ return true;
+ }
+/**
+ * Creates a default set of conditions from the model if $conditions is null/empty.
+ *
+ * @param object $model
+ * @param mixed $conditions
+ * @return mixed
+ */
+ function defaultConditions(&$model, $conditions) {
+ if (!empty($conditions)) {
+ return $conditions;
+ }
+ if (!$model->exists()) {
+ return false;
+ }
+ return array($model->primaryKey => (array)$model->getID());
+ }
+/**
+ * Returns a key formatted like a string Model.fieldname(i.e. Post.title, or Country.name)
+ *
+ * @param unknown_type $model
+ * @param unknown_type $key
+ * @param unknown_type $assoc
+ * @return string
+ */
+ function resolveKey($model, $key, $assoc = null) {
+ if (empty($assoc)) {
+ $assoc = $model->alias;
+ }
+ if (!strpos('.', $key)) {
+ return $this->name($model->alias) . '.' . $this->name($key);
+ }
+ return $key;
+ }
+/**
+ * Returns the column type of a given
+ *
+ * @param Model $model
+ * @param string $field
+ */
+ function getColumnType(&$model, $field) {
+ return $model->getColumnType($field);
+ }
+/**
+ * Private helper method to remove query metadata in given data array.
+ *
+ * @param array $data
+ */
+ function __scrubQueryData(&$data) {
+ foreach (array('conditions', 'fields', 'joins', 'order', 'limit', 'offset') as $key) {
+ if (!isset($data[$key]) || empty($data[$key])) {
+ $data[$key] = array();
+ }
+ }
+ }
+/**
+ * Generates the fields list of an SQL query.
+ *
+ * @param Model $model
+ * @param string $alias Alias tablename
+ * @param mixed $fields
+ * @param boolean $quote If false, returns fields array unquoted
+ * @return array
+ */
+ function fields(&$model, $alias = null, $fields = array(), $quote = true) {
+ if (empty($alias)) {
+ $alias = $model->alias;
+ }
+
+ if (!is_array($fields)) {
+ if (!empty($fields)) {
+ $depth = 0;
+ $offset = 0;
+ $buffer = '';
+ $results = array();
+ $length = strlen($fields);
+
+ while ($offset <= $length) {
+ $tmpOffset = -1;
+ $offsets = array(strpos($fields, ',', $offset), strpos($fields, '(', $offset), strpos($fields, ')', $offset));
+ for ($i = 0; $i < 3; $i++) {
+ if ($offsets[$i] !== false && ($offsets[$i] < $tmpOffset || $tmpOffset == -1)) {
+ $tmpOffset = $offsets[$i];
+ }
+ }
+ if ($tmpOffset !== -1) {
+ $buffer .= substr($fields, $offset, ($tmpOffset - $offset));
+ if ($fields{$tmpOffset} == ',' && $depth == 0) {
+ $results[] = $buffer;
+ $buffer = '';
+ } else {
+ $buffer .= $fields{$tmpOffset};
+ }
+ if ($fields{$tmpOffset} == '(') {
+ $depth++;
+ }
+ if ($fields{$tmpOffset} == ')') {
+ $depth--;
+ }
+ $offset = ++$tmpOffset;
+ } else {
+ $results[] = $buffer . substr($fields, $offset);
+ $offset = $length + 1;
+ }
+ }
+ if (empty($results) && !empty($buffer)) {
+ $results[] = $buffer;
+ }
+
+ if (!empty($results)) {
+ $fields = array_map('trim', $results);
+ } else {
+ $fields = array();
+ }
+ }
+ }
+ if (empty($fields)) {
+ $fieldData = $model->loadInfo();
+ $fields = $fieldData->extract('{n}.name');
+ } else {
+ $fields = array_filter($fields);
+ }
+
+ if (!$quote) {
+ return $fields;
+ }
+ $count = count($fields);
+
+ if ($count >= 1 && !in_array($fields[0], array('*', 'COUNT(*)'))) {
+ for ($i = 0; $i < $count; $i++) {
+ if (!preg_match('/^.+\\(.*\\)/', $fields[$i])) {
+ $prepend = '';
+
+ if (strpos($fields[$i], 'DISTINCT') !== false) {
+ $prepend = 'DISTINCT ';
+ $fields[$i] = trim(str_replace('DISTINCT', '', $fields[$i]));
+ }
+ $dot = strpos($fields[$i], '.');
+
+ if ($dot === false) {
+ $fields[$i] = $prepend . $this->name($alias) . '.' . $this->name($fields[$i]);
+ } else {
+ $comma = strpos($fields[$i], ',');
+ if ($comma === false) {
+ $build = explode('.', $fields[$i]);
+ if (!Set::numeric($build)) {
+ $fields[$i] = $prepend . $this->name($build[0]) . '.' . $this->name($build[1]);
+ }
+ } else {
+ $comma = explode(',', $fields[$i]);
+ foreach ($comma as $string) {
+ $build = explode('.', $string);
+ if (!Set::numeric($build)) {
+ $value[] = $prepend . $this->name(trim($build[0])) . '.' . $this->name(trim($build[1]));
+ }
+ }
+ $fields[$i] = implode(', ', $value);
+ }
+ }
+ } elseif (preg_match('/\(([\.\w]+)\)/', $fields[$i], $field)) {
+ if (isset($field[1])) {
+ if (strpos($field[1], '.') === false) {
+ $field[1] = $this->name($alias) . '.' . $this->name($field[1]);
+ } else {
+ $field[0] = explode('.', $field[1]);
+ if (!Set::numeric($field[0])) {
+ $field[0] = join('.', array_map(array($this, 'name'), $field[0]));
+ $fields[$i] = preg_replace('/\(' . $field[1] . '\)/', '(' . $field[0] . ')', $fields[$i], 1);
+ }
+ }
+ }
+ }
+ }
+ }
+ return $fields;
+ }
+/**
+ * Creates a WHERE clause by parsing given conditions data.
+ *
+ * @param mixed $conditions Array or string of conditions
+ * @return string SQL fragment
+ */
+ function conditions($conditions, $quoteValues = true, $where = true) {
+ $clause = $out = '';
+ if (is_string($conditions) || empty($conditions) || $conditions === true) {
+ if (empty($conditions) || trim($conditions) == '' || $conditions === true) {
+ if ($where) {
+ return ' WHERE 1 = 1';
+ }
+ return '1 = 1';
+ }
+ if (!preg_match('/^WHERE\\x20|^GROUP\\x20BY\\x20|^HAVING\\x20|^ORDER\\x20BY\\x20/i', $conditions, $match)) {
+ if ($where) {
+ $clause = ' WHERE ';
+ }
+ }
+ if (trim($conditions) == '') {
+ $conditions = ' 1 = 1';
+ } else {
+ $conditions = $this->__quoteFields($conditions);
+ }
+ return $clause . $conditions;
+ } else {
+ if ($where) {
+ $clause = ' WHERE ';
+ }
+ if (!empty($conditions)) {
+ $out = $this->conditionKeysToString($conditions, $quoteValues);
+ }
+ if (empty($out) || empty($conditions)) {
+ return $clause . ' 1 = 1';
+ }
+ return $clause . join(' AND ', $out);
+ }
+ }
+/**
+ * Creates a WHERE clause by parsing given conditions array. Used by DboSource::conditions().
+ *
+ * @param array $conditions Array or string of conditions
+ * @return string SQL fragment
+ */
+ function conditionKeysToString($conditions, $quoteValues = true) {
+ $c = 0;
+ $data = $not = null;
+ $out = array();
+ $bool = array('and', 'or', 'not', 'and not', 'or not', 'xor', '||', '&&');
+ $join = ' AND ';
+
+ foreach ($conditions as $key => $value) {
+ if (is_numeric($key) && empty($value)) {
+ continue;
+ } elseif (is_numeric($key) && is_string($value)) {
+ $out[] = $not . $this->__quoteFields($value);
+ } elseif (in_array(strtolower(trim($key)), $bool)) {
+ $join = ' ' . strtoupper($key) . ' ';
+ $value = $this->conditionKeysToString($value, $quoteValues);
+ if (strpos($join, 'NOT') !== false) {
+ if (strtoupper(trim($key)) == 'NOT') {
+ $key = 'AND ' . $key;
+ }
+ $not = 'NOT ';
+ } else {
+ $not = null;
+ }
+ $out[] = $not . '((' . join(') ' . strtoupper($key) . ' (', $value) . '))';
+ } else {
+ if (is_string($value) && preg_match('/^\{\$__cakeIdentifier\[(.*)\]__\$}$/', $value, $identifier) && isset($identifier[1])) {
+ $data .= $this->name($key) . ' = ' . $this->name($identifier[1]);
+ } elseif (is_array($value) && !empty($value)) {
+ $keys = array_keys($value);
+ if ($keys[0] === 0) {
+ $data = $this->name($key) . ' IN (';
+ if (strpos($value[0], '-!') === 0) {
+ $value[0] = str_replace('-!', '', $value[0]);
+ $data .= $value[0];
+ $data .= ')';
+ } else {
+ if ($quoteValues) {
+ foreach ($value as $valElement) {
+ $data .= $this->value($valElement) . ', ';
+ }
+ }
+ $data[strlen($data) - 2] = ')';
+ }
+ } else {
+ $ret = $this->conditionKeysToString($value, $quoteValues);
+ if (count($ret) > 1) {
+ $out[] = '(' . join(') AND (', $ret) . ')';
+ } elseif (isset($ret[0])) {
+ $out[] = $ret[0];
+ }
+ }
+ } elseif (is_numeric($key) && !empty($value)) {
+ $data = $this->__quoteFields($value);
+ } elseif ($value === null || (is_array($value) && empty($value))) {
+ $data = $this->name($key) . ' IS NULL';
+ } elseif ($value === false || $value === true) {
+ $data = $this->name($key) . " = " . $this->value($value, 'boolean');
+ } elseif ($value === '') {
+ $data = $this->name($key) . " = ''";
+ } elseif (preg_match('/^([a-z]+\\([a-z0-9]*\\)\\x20+|(?:' . join('\\x20)|(?:', $this->__sqlOps) . '\\x20)|<[>=]?(?![^>]+>)\\x20?|[>=!]{1,3}(?!<)\\x20?)?(.*)/is', $value, $match)) {
+ if (preg_match('/(\\x20[\\w]*\\x20)/', $key, $regs)) {
+ $clause = $regs['1'];
+ $key = preg_replace('/' . $regs['1'] . '/', '', $key);
+ }
+
+ $not = false;
+ $mValue = trim($match['1']);
+ if (empty($match['1'])) {
+ $match['1'] = ' = ';
+ } elseif (empty($mValue)) {
+ $match['1'] = ' = ';
+ $match['2'] = $match['0'];
+ } elseif (!isset($match['2'])) {
+ $match['1'] = ' = ';
+ $match['2'] = $match['0'];
+ } elseif (strtolower($mValue) == 'not') {
+ $not = $this->conditionKeysToString(array($mValue => array($key => $match[2])), $quoteValues);
+ }
+
+ if ($not) {
+ $data = $not[0];
+ } elseif (strpos($match['2'], '-!') === 0) {
+ $match['2'] = str_replace('-!', '', $match['2']);
+ $data = $this->name($key) . ' ' . $match['1'] . ' ' . $match['2'];
+ } else {
+ if (!empty($match['2']) && $quoteValues) {
+ if (!preg_match('/[A-Za-z]+\\([a-z0-9]*\\),?\\x20+/', $match['2'])) {
+ $match['2'] = $this->value($match['2']);
+ }
+ $match['2'] = str_replace(' AND ', "' AND '", $match['2']);
+ }
+ $data = $this->__quoteFields($key);
+ if ($data === $key) {
+ $data = $this->name($key) . ' ' . $match['1'] . ' ' . $match['2'];
+ } else {
+ $data = $data . ' ' . $match['1'] . ' ' . $match['2'];
+ }
+ }
+ }
+
+ if ($data != null) {
+ $out[] = $data;
+ $data = null;
+ }
+ }
+ $c++;
+ }
+ return $out;
+ }
+/**
+ * Quotes Model.fields
+ *
+ * @param string $conditions
+ * @return string or false if no match
+ * @access private
+ */
+ function __quoteFields($conditions) {
+ $start = null;
+ $end = null;
+ $original = $conditions;
+
+ if (!empty($this->startQuote)) {
+ $start = preg_quote($this->startQuote);
+ }
+
+ if (!empty($this->endQuote)) {
+ $end = preg_quote($this->endQuote);
+ }
+ $conditions = str_replace(array($start, $end), '', $conditions);
+ preg_match_all('/(?:[\'\"][^\'\"\\\]*(?:\\\.[^\'\"\\\]*)*[\'\"])|([a-z0-9_' . $start . $end . ']*\\.[a-z0-9_' . $start . $end . ']*)/i', $conditions, $replace, PREG_PATTERN_ORDER);
+
+ if (isset($replace['1']['0'])) {
+ $pregCount = count($replace['1']);
+
+ for ($i = 0; $i < $pregCount; $i++) {
+ if (!empty($replace['1'][$i]) && !is_numeric($replace['1'][$i])) {
+ $conditions = preg_replace('/\b' . preg_quote($replace['1'][$i]) . '\b/', $this->name($replace['1'][$i]), $conditions);
+ }
+ }
+ return $conditions;
+ }
+ return $original;
+ }
+/**
+ * Returns a limit statement in the correct format for the particular database.
+ *
+ * @param integer $limit Limit of results returned
+ * @param integer $offset Offset from which to start results
+ * @return string SQL limit/offset statement
+ */
+ function limit($limit, $offset = null) {
+ if ($limit) {
+ $rt = '';
+ if (!strpos(strtolower($limit), 'limit') || strpos(strtolower($limit), 'limit') === 0) {
+ $rt = ' LIMIT';
+ }
+
+ if ($offset) {
+ $rt .= ' ' . $offset . ',';
+ }
+
+ $rt .= ' ' . $limit;
+ return $rt;
+ }
+ return null;
+ }
+/**
+ * Returns an ORDER BY clause as a string.
+ *
+ * @param string $key Field reference, as a key (i.e. Post.title)
+ * @param string $direction Direction (ASC or DESC)
+ * @return string ORDER BY clause
+ */
+ function order($keys, $direction = 'ASC') {
+ if (is_string($keys) && strpos($keys, ',') && !preg_match('/\(.+\,.+\)/', $keys)) {
+ $keys = explode(',', $keys);
+ array_map('trim', $keys);
+ }
+
+ if (is_array($keys)) {
+ foreach ($keys as $key => $val) {
+ if (is_numeric($key) && empty($val)) {
+ unset ($keys[$key]);
+ }
+ }
+ }
+
+ if (empty($keys) || (is_array($keys) && count($keys) && isset($keys[0]) && empty($keys[0]))) {
+ return '';
+ }
+
+ if (is_array($keys)) {
+ if (Set::countDim($keys) > 1) {
+ $new = array();
+
+ foreach ($keys as $val) {
+ $val = $this->order($val);
+ $new[] = $val;
+ }
+
+ $keys = $new;
+ }
+
+ foreach ($keys as $key => $value) {
+ if (is_numeric($key)) {
+ $value = ltrim(str_replace('ORDER BY ', '', $this->order($value)));
+ $key = $value;
+
+ if (!preg_match('/\\x20ASC|\\x20DESC/i', $key)) {
+ $value = ' ' . $direction;
+ } else {
+ $value = '';
+ }
+ } else {
+ $value = ' ' . $value;
+ }
+
+ if (!preg_match('/^.+\\(.*\\)/', $key) && !strpos($key, ',')) {
+ $dir = '';
+ $hasDir = preg_match('/\\x20ASC|\\x20DESC/i', $key, $dir);
+
+ if ($hasDir) {
+ $dir = $dir[0];
+ $key = preg_replace('/\\x20ASC|\\x20DESC/i', '', $key);
+ } else {
+ $dir = '';
+ }
+ $key = trim($this->name(trim($key)) . ' ' . trim($dir));
+ }
+ $order[] = $this->order($key . $value);
+ }
+
+ return ' ORDER BY ' . trim(str_replace('ORDER BY', '', join(',', $order)));
+ } else {
+ $keys = preg_replace('/ORDER\\x20BY/i', '', $keys);
+
+ if (strpos($keys, '.')) {
+ preg_match_all('/([a-zA-Z0-9_]{1,})\\.([a-zA-Z0-9_]{1,})/', $keys, $result,
+ PREG_PATTERN_ORDER);
+ $pregCount = count($result['0']);
+
+ for ($i = 0; $i < $pregCount; $i++) {
+ $keys = preg_replace('/' . $result['0'][$i] . '/', $this->name($result['0'][$i]), $keys);
+ }
+
+ if (preg_match('/\\x20ASC|\\x20DESC/i', $keys)) {
+ return ' ORDER BY ' . $keys;
+ } else {
+ return ' ORDER BY ' . $keys . ' ' . $direction;
+ }
+ } elseif (preg_match('/(\\x20ASC|\\x20DESC)/i', $keys, $match)) {
+ $direction = $match['1'];
+ $keys = preg_replace('/' . $match['1'] . '/', '', $keys);
+ return ' ORDER BY ' . $keys . $direction;
+ } else {
+ $direction = ' ' . $direction;
+ }
+ return ' ORDER BY ' . $keys . $direction;
+ }
+ }
+/**
+ * Disconnects database, kills the connection and says the connection is closed,
+ * and if DEBUG is turned on, the log for this object is shown.
+ *
+ */
+ function close() {
+ if (Configure::read() > 1) {
+ $this->showLog();
+ }
+ $this->disconnect();
+ }
+/**
+ * Checks if the specified table contains any record matching specified SQL
+ *
+ * @param Model $model Model to search
+ * @param string $sql SQL WHERE clause (condition only, not the "WHERE" part)
+ * @return boolean True if the table has a matching record, else false
+ */
+ function hasAny($model, $sql) {
+ // bug 478041, escaping the fields properly
+ $sql = $this->conditions($sql);
+ $pk = $model->escapeField($model->primaryKey);
+ $table = $this->fullTableName($model) . ' ' . $this->alias . $this->name($model->name);
+ $where = $sql ? $sql : 'WHERE 1 = 1';
+ $out = $this->fetchRow("SELECT COUNT({$pk}) {$this->alias} count FROM {$table} {$where}");
+
+ if (is_array($out)) {
+ return $out[0]['count'];
+ } else {
+ return false;
+ }
+ }
+/**
+ * Gets the length of a database-native column description, or null if no length
+ *
+ * @param string $real Real database-layer column type (i.e. "varchar(255)")
+ * @return integer An integer representing the length of the column
+ */
+ function length($real) {
+ $col = str_replace(array(')', 'unsigned'), '', $real);
+ $limit = null;
+
+ if (strpos($col, '(') !== false) {
+ list($col, $limit) = explode('(', $col);
+ }
+
+ if ($limit != null) {
+ return intval($limit);
+ }
+ return null;
+ }
+/**
+ * Translates between PHP boolean values and Database (faked) boolean values
+ *
+ * @param mixed $data Value to be translated
+ * @return mixed Converted boolean value
+ */
+ function boolean($data) {
+ if ($data === true || $data === false) {
+ if ($data === true) {
+ return 1;
+ }
+ return 0;
+
+ } else {
+ if (!empty($data)) {
+ return true;
+ }
+ return false;
+ }
+ }
+/**
+ * Destructor. Closes connection to the database.
+ *
+ */
+ function __destruct() {
+ if ($this->_transactionStarted) {
+ $null = null;
+ $this->rollback($null);
+ }
+ parent::__destruct();
+ }
+/**
+ * Inserts multiple values into a join table
+ *
+ * @param string $table
+ * @param string $fields
+ * @param array $values
+ */
+ function insertMulti($table, $fields, $values) {
+ $values = implode(', ', $values);
+ $this->query("INSERT INTO {$table} ({$fields}) VALUES {$values}");
+ }
+/**
+ * Returns an array of the indexes in given datasource name.
+ *
+ * @param string $model Name of model to inspect
+ * @return array Fields in table. Keys are column and unique
+ */
+ function index($model) {
+ return false;
+ }
+/**
+ * Generate a create syntax from CakeSchema
+ *
+ * @param object $schema An instance of a subclass of CakeSchema
+ * @param string $table Optional. If specified only the table name given will be generated.
+ * Otherwise, all tables defined in the schema are generated.
+ * @return string
+ */
+ function createSchema($schema, $table = null) {
+ return false;
+ }
+/**
+ * Generate a alter syntax from CakeSchema::compare()
+ *
+ * @param unknown_type $schema
+ * @return unknown
+ */
+ function alterSchema($compare, $table = null) {
+ return false;
+ }
+/**
+ * Generate a drop syntax from CakeSchema
+ *
+ * @param object $schema An instance of a subclass of CakeSchema
+ * @param string $table Optional. If specified only the table name given will be generated.
+ * Otherwise, all tables defined in the schema are generated.
+ * @return string
+ */
+ function dropSchema($schema, $table = null) {
+ return false;
+ }
+/**
+ * Generate a column schema string
+ *
+ * @param array $column An array structured like the following: array('name'=>'value', 'type'=>'value'[, options]),
+ * where options can be 'default', 'length', or 'key'.
+ * @return string
+ */
+ function buildColumn($column) {
+ return false;
+ }
+/**
+ * Format indexes for create table
+ *
+ * @param array $indexes
+ * @return string
+ */
+ function buildIndex($indexes) {
+ return false;
+ }
+}
+?>
diff --git a/site/cake/libs/model/dbo/dbo_adodb.php b/site/cake/libs/model/dbo/dbo_adodb.php
new file mode 100644
index 0000000..5017e26
--- /dev/null
+++ b/site/cake/libs/model/dbo/dbo_adodb.php
@@ -0,0 +1,437 @@
+<?php
+/* SVN FILE: $Id: dbo_adodb.php 6305 2008-01-02 02:33:56Z phpnut $ */
+
+/**
+ * AdoDB layer for DBO.
+ *
+ * Long description for file
+ *
+ * PHP versions 4 and 5
+ *
+ * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
+ * Copyright 2005-2008, Cake Software Foundation, Inc.
+ * 1785 E. Sahara Avenue, Suite 490-204
+ * Las Vegas, Nevada 89104
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
+ * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
+ * @package cake
+ * @subpackage cake.cake.libs.model.dbo
+ * @since CakePHP(tm) v 0.2.9
+ * @version $Revision: 6305 $
+ * @modifiedby $LastChangedBy: phpnut $
+ * @lastmodified $Date: 2008-01-01 20:33:56 -0600 (Tue, 01 Jan 2008) $
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+
+/**
+ * Include AdoDB files.
+ */
+vendor ('adodb' . DS . 'adodb.inc');
+
+/**
+ * AdoDB DBO implementation.
+ *
+ * Database abstraction implementation for the AdoDB library.
+ *
+ * @package cake
+ * @subpackage cake.cake.libs.model.dbo
+ */
+class DboAdodb extends DboSource {
+/**
+ * Enter description here...
+ *
+ * @var string
+ */
+ var $description = "ADOdb DBO Driver";
+
+/**
+ * ADOConnection object with which we connect.
+ *
+ * @var ADOConnection The connection object.
+ * @access private
+ */
+ var $_adodb = null;
+
+/**
+ * Array translating ADOdb column MetaTypes to cake-supported metatypes
+ *
+ * @var array
+ * @access private
+ */
+ var $_adodb_column_types = array(
+ 'C' => 'string',
+ 'X' => 'text',
+ 'D' => 'date',
+ 'T' => 'timestamp',
+ 'L' => 'boolean',
+ 'N' => 'float',
+ 'I' => 'integer',
+ 'R' => 'integer', // denotes auto-increment or counter field
+ 'B' => 'binary'
+ );
+
+/**
+ * Connects to the database using options in the given configuration array.
+ *
+ * @param array $config Configuration array for connecting
+ */
+ function connect() {
+ $config = $this->config;
+ $persistent = strrpos($config['connect'], '|p');
+
+ if ($persistent === false) {
+ $adodb_driver = $config['connect'];
+ $connect = 'Connect';
+ } else {
+ $adodb_driver = substr($config['connect'], 0, $persistent);
+ $connect = 'PConnect';
+ }
+
+ $this->_adodb = NewADOConnection($adodb_driver);
+
+ $this->startQuote = $this->_adodb->nameQuote;
+ $this->endQuote = $this->_adodb->nameQuote;
+
+ $this->connected = $this->_adodb->$connect($config['host'], $config['login'], $config['password'], $config['database']);
+ return $this->connected;
+ }
+/**
+ * Disconnects from database.
+ *
+ * @return boolean True if the database could be disconnected, else false
+ */
+ function disconnect() {
+ return $this->_adodb->Close();
+ }
+/**
+ * Executes given SQL statement.
+ *
+ * @param string $sql SQL statement
+ * @return resource Result resource identifier
+ */
+ function _execute($sql) {
+ global $ADODB_FETCH_MODE;
+ $ADODB_FETCH_MODE = ADODB_FETCH_ASSOC;
+ return $this->_adodb->execute($sql);
+ }
+/**
+ * Returns a row from given resultset as an array .
+ *
+ * @return array The fetched row as an array
+ */
+/**
+ * Returns a row from current resultset as an array .
+ *
+ * @return array The fetched row as an array
+ */
+ function fetchRow($sql = null) {
+
+ if (!empty($sql) && is_string($sql) && strlen($sql) > 5) {
+ if (!$this->execute($sql)) {
+ return null;
+ }
+ }
+
+ if (!is_object($this->_result) || $this->_result->EOF) {
+ return null;
+ } else {
+ $resultRow = $this->_result->FetchRow();
+ $this->resultSet($resultRow);
+ return $this->fetchResult();
+ }
+ }
+/**
+ * Begin a transaction
+ *
+ * @param unknown_type $model
+ * @return boolean True on success, false on fail
+ * (i.e. if the database/model does not support transactions).
+ */
+ function begin(&$model) {
+ if (parent::begin($model)) {
+ if ($this->_adodb->BeginTrans()) {
+ $this->_transactionStarted = true;
+ return true;
+ }
+ }
+ return false;
+ }
+/**
+ * Commit a transaction
+ *
+ * @param unknown_type $model
+ * @return boolean True on success, false on fail
+ * (i.e. if the database/model does not support transactions,
+ * or a transaction has not started).
+ */
+ function commit(&$model) {
+ if (parent::commit($model)) {
+ $this->_transactionStarted = false;
+ return $this->_adodb->CommitTrans();
+ }
+ return false;
+ }
+/**
+ * Rollback a transaction
+ *
+ * @param unknown_type $model
+ * @return boolean True on success, false on fail
+ * (i.e. if the database/model does not support transactions,
+ * or a transaction has not started).
+ */
+ function rollback(&$model) {
+ if (parent::rollback($model)) {
+ return $this->_adodb->RollbackTrans();
+ }
+ return false;
+ }
+/**
+ * Returns an array of tables in the database. If there are no tables, an error is raised and the application exits.
+ *
+ * @return array Array of tablenames in the database
+ */
+ function listSources() {
+ $tables = $this->_adodb->MetaTables('TABLES');
+
+ if (!sizeof($tables) > 0) {
+ trigger_error(ERROR_NO_TABLE_LIST, E_USER_NOTICE);
+ exit;
+ }
+
+ return $tables;
+ }
+/**
+ * Returns an array of the fields in the table used by the given model.
+ *
+ * @param AppModel $model Model object
+ * @return array Fields in table. Keys are name and type
+ */
+ function describe(&$model) {
+ $cache = parent::describe($model);
+ if ($cache != null) {
+ return $cache;
+ }
+
+ $fields = false;
+ $cols = $this->_adodb->MetaColumns($this->fullTableName($model, false));
+
+ foreach ($cols as $column) {
+ $fields[$column->name] = array(
+ 'type' => $this->column($column->type)
+ );
+ }
+
+ $this->__cacheDescription($this->fullTableName($model, false), $fields);
+ return $fields;
+ }
+/**
+ * Returns a formatted error message from previous database operation.
+ *
+ * @return string Error message
+ */
+ function lastError() {
+ return $this->_adodb->ErrorMsg();
+ }
+/**
+ * Returns number of affected rows in previous database operation, or false if no previous operation exists.
+ *
+ * @return int Number of affected rows
+ */
+ function lastAffected() {
+ return $this->_adodb->Affected_Rows();
+ }
+/**
+ * Returns number of rows in previous resultset, or false if no previous resultset exists.
+ *
+ * @return int Number of rows in resultset
+ */
+ function lastNumRows() {
+ return $this->_result ? $this->_result->RecordCount() : false;
+ }
+/**
+ * Returns the ID generated from the previous INSERT operation.
+ *
+ * @return int
+ *
+ * @Returns the last autonumbering ID inserted. Returns false if function not supported.
+ */
+ function lastInsertId() {
+ return $this->_adodb->Insert_ID();
+ }
+
+/**
+ * Returns a LIMIT statement in the correct format for the particular database.
+ *
+ * @param int $limit Limit of results returned
+ * @param int $offset Offset from which to start results
+ * @return string SQL limit/offset statement
+ * @todo Please change output string to whatever select your database accepts. adodb doesn't allow us to get the correct limit string out of it.
+ */
+ function limit($limit, $offset = null) {
+ if (empty($limit)) {
+ return null;
+ }
+ return " LIMIT {$limit}" . ($offset ? "{$offset}" : null);
+ // please change to whatever select your database accepts
+ // adodb doesn't allow us to get the correct limit string out of it
+ }
+
+/**
+ * Converts database-layer column types to basic types
+ *
+ * @param string $real Real database-layer column type (i.e. "varchar(255)")
+ * @return string Abstract column type (i.e. "string")
+ */
+ function column($real) {
+ if (isset($this->_result)) {
+ $adodb_metatyper = &$this->_result;
+ } else {
+ $adodb_metatyper = &$this->_adodb->execute('Select 1');
+ }
+
+ $interpreted_type = $adodb_metatyper->MetaType($real);
+ if (!isset($this->_adodb_column_types[$interpreted_type])) {
+ return 'text';
+ }
+
+ return $this->_adodb_column_types[$interpreted_type];
+ }
+/**
+ * Returns a quoted and escaped string of $data for use in an SQL statement.
+ *
+ * @param string $data String to be prepared for use in an SQL statement
+ * @param string $column_type The type of the column into which this data will be inserted
+ * @param boolean $safe Whether or not numeric data should be handled automagically if no column data is provided
+ * @return string Quoted and escaped data
+ */
+ function value($data, $column = null, $safe = false) {
+ $parent = parent::value($data, $column, $safe);
+ if ($parent != null) {
+ return $parent;
+ }
+
+ if ($data === null) {
+ return 'NULL';
+ }
+
+ if ($data === '') {
+ return "''";
+ }
+ return $this->_adodb->qstr($data);
+ }
+/**
+ * Generates the fields list of an SQL query.
+ *
+ * @param Model $model
+ * @param string $alias Alias tablename
+ * @param mixed $fields
+ * @return array
+ */
+ function fields(&$model, $alias = null, $fields = null, $quote = true) {
+ if (empty($alias)) {
+ $alias = $model->name;
+ }
+
+ if (!is_array($fields)) {
+ if ($fields != null) {
+ if (strpos($fields, ',')) {
+ $fields = explode(',', $fields);
+ } else {
+ $fields = array($fields);
+ }
+ $fields = array_map('trim', $fields);
+ } else {
+ foreach ($model->_tableInfo->value as $field) {
+ $fields[] = $field['name'];
+ }
+ }
+ }
+
+ $count = count($fields);
+
+ if ($count >= 1 && $fields[0] != '*' && strpos($fields[0], 'COUNT(*)') === false) {
+ for ($i = 0; $i < $count; $i++) {
+ if (!preg_match('/^.+\\(.*\\)/', $fields[$i])) {
+ $prepend = '';
+ if (strpos($fields[$i], 'DISTINCT') !== false) {
+ $prepend = 'DISTINCT ';
+ $fields[$i] = trim(r('DISTINCT', '', $fields[$i]));
+ }
+
+ $dot = strrpos($fields[$i], '.');
+ if ($dot === false) {
+ $fields[$i] = $prepend . $this->name($alias) . '.' . $this->name($fields[$i]) . ' AS ' . $this->name($alias . '__' . $fields[$i]);
+ } else {
+ $build = explode('.', $fields[$i]);
+ $fields[$i] = $prepend . $this->name($build[0]) . '.' . $this->name($build[1]) . ' AS ' . $this->name($build[0] . '__' . $build[1]);
+ }
+ }
+ }
+ }
+ return $fields;
+ }
+/**
+ * Enter description here...
+ *
+ * @param unknown_type $results
+ */
+ function resultSet(&$results) {
+ $num_fields = count($results);
+ $fields = array_keys($results);
+ $this->results =& $results;
+ $this->map = array();
+ $index = 0;
+ $j = 0;
+
+ while ($j < $num_fields) {
+ $columnName = $fields[$j];
+
+ if (strpos($columnName, '__')) {
+ $parts = explode('__', $columnName);
+ $this->map[$index++] = array($parts[0], $parts[1]);
+ } else {
+ $this->map[$index++] = array(0, $columnName);
+ }
+ $j++;
+ }
+ }
+/**
+ * Fetches the next row from the current result set
+ *
+ * @return unknown
+ */
+ function fetchResult() {
+ if (!empty($this->results) && $row = $this->results) {
+ $resultRow = array();
+ $fields = array_keys($row);
+ $count = count($fields);
+ $i = 0;
+ for ($i = 0; $i < $count; $i++) { //$row as $index => $field) {
+ list($table, $column) = $this->map[$i];
+ $resultRow[$table][$column] = $row[$fields[$i]];
+ }
+ return $resultRow;
+ } else {
+ return false;
+ }
+ }
+/**
+ * Inserts multiple values into a join table
+ *
+ * @param string $table
+ * @param string $fields
+ * @param array $values
+ */
+ function insertMulti($table, $fields, $values) {
+ $count = count($values);
+ for ($x = 0; $x < $count; $x++) {
+ $this->query("INSERT INTO {$table} ({$fields}) VALUES {$values[$x]}");
+ }
+ }
+}
+?> \ No newline at end of file
diff --git a/site/cake/libs/model/dbo/dbo_mssql.php b/site/cake/libs/model/dbo/dbo_mssql.php
new file mode 100644
index 0000000..9273280
--- /dev/null
+++ b/site/cake/libs/model/dbo/dbo_mssql.php
@@ -0,0 +1,604 @@
+<?php
+/* SVN FILE: $Id: dbo_mssql.php 6305 2008-01-02 02:33:56Z phpnut $ */
+
+/**
+ * MS SQL layer for DBO
+ *
+ * Long description for file
+ *
+ * PHP versions 4 and 5
+ *
+ * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
+ * Copyright 2005-2008, Cake Software Foundation, Inc.
+ * 1785 E. Sahara Avenue, Suite 490-204
+ * Las Vegas, Nevada 89104
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
+ * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
+ * @package cake
+ * @subpackage cake.cake.libs.model.dbo
+ * @since CakePHP(tm) v 0.10.5.1790
+ * @version $Revision: 6305 $
+ * @modifiedby $LastChangedBy: phpnut $
+ * @lastmodified $Date: 2008-01-01 20:33:56 -0600 (Tue, 01 Jan 2008) $
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+
+/**
+ * Short description for class.
+ *
+ * Long description for class
+ *
+ * @package cake
+ * @subpackage cake.cake.libs.model.dbo
+ */
+class DboMssql extends DboSource {
+/**
+ * Driver description
+ *
+ * @var string
+ */
+ var $description = "MS SQL DBO Driver";
+/**
+ * Starting quote character for quoted identifiers
+ *
+ * @var string
+ */
+ var $startQuote = "[";
+/**
+ * Ending quote character for quoted identifiers
+ *
+ * @var string
+ */
+ var $endQuote = "]";
+ /**
+ * Creates a map between field aliases and numeric indexes. Workaround for the
+ * SQL Server driver's 30-character column name limitation.
+ *
+ * @var array
+ */
+ var $__fieldMappings = array();
+/**
+ * Base configuration settings for MS SQL driver
+ *
+ * @var array
+ */
+ var $_baseConfig = array(
+ 'persistent' => true,
+ 'host' => 'localhost',
+ 'login' => 'root',
+ 'password' => '',
+ 'database' => 'cake',
+ 'port' => '1433',
+ 'connect' => 'mssql_pconnect'
+ );
+/**
+ * MS SQL column definition
+ *
+ * @var array
+ */
+ var $columns = array(
+ 'primary_key' => array('name' => 'int IDENTITY (1, 1) NOT NULL'),
+ 'string' => array('name' => 'varchar', 'limit' => '255'),
+ 'text' => array('name' => 'text'),
+ 'integer' => array('name' => 'int', 'formatter' => 'intval'),
+ 'float' => array('name' => 'float', 'formatter' => 'floatval'),
+ 'datetime' => array('name' => 'datetime', 'format' => 'Y-m-d H:i:s', 'formatter' => 'date'),
+ 'timestamp' => array('name' => 'timestamp', 'format' => 'Y-m-d H:i:s', 'formatter' => 'date'),
+ 'time' => array('name' => 'datetime', 'format' => 'H:i:s', 'formatter' => 'date'),
+ 'date' => array('name' => 'datetime', 'format' => 'Y-m-d', 'formatter' => 'date'),
+ 'binary' => array('name' => 'image'),
+ 'boolean' => array('name' => 'bit')
+ );
+/**
+ * MS SQL DBO driver constructor; sets SQL Server error reporting defaults
+ *
+ * @param array $config Configuration data from app/config/databases.php
+ * @return boolean True if connected successfully, false on error
+ */
+ function __construct($config, $autoConnect = true) {
+ if ($autoConnect) {
+ if (!function_exists('mssql_min_message_severity')) {
+ trigger_error("PHP SQL Server interface is not installed, cannot continue. For troubleshooting information, see http://php.net/mssql/", E_USER_WARNING);
+ }
+ mssql_min_message_severity(15);
+ mssql_min_error_severity(2);
+ }
+ return parent::__construct($config, $autoConnect);
+ }
+/**
+ * Connects to the database using options in the given configuration array.
+ *
+ * @return boolean True if the database could be connected, else false
+ */
+ function connect() {
+ $config = $this->config;
+
+ $os = env('OS');
+ if (!empty($os) && strpos($os, 'Windows') !== false) {
+ $sep = ',';
+ } else {
+ $sep = ':';
+ }
+ $connect = 'mssql_connect';
+ if ($config['persistent']) {
+ $connect = 'mssql_pconnect';
+ }
+ $this->connected = false;
+
+ if (is_numeric($config['port'])) {
+ $port = $sep . $config['port']; // Port number
+ } elseif ($config['port'] === null) {
+ $port = ''; // No port - SQL Server 2005
+ } else {
+ $port = '\\' . $config['port']; // Named pipe
+ }
+ $this->connection = $connect($config['host'] . $port, $config['login'], $config['password']);
+
+ if (mssql_select_db($config['database'], $this->connection)) {
+ $this->connected = true;
+ }
+ }
+/**
+ * Disconnects from database.
+ *
+ * @return boolean True if the database could be disconnected, else false
+ */
+ function disconnect() {
+ @mssql_free_result($this->results);
+ $this->connected = !@mssql_close($this->connection);
+ return !$this->connected;
+ }
+/**
+ * Executes given SQL statement.
+ *
+ * @param string $sql SQL statement
+ * @return resource Result resource identifier
+ * @access protected
+ */
+ function _execute($sql) {
+ return mssql_query($sql, $this->connection);
+ }
+/**
+ * Returns an array of sources (tables) in the database.
+ *
+ * @return array Array of tablenames in the database
+ */
+ function listSources() {
+ $cache = parent::listSources();
+
+ if ($cache != null) {
+ return $cache;
+ }
+
+ $result = $this->fetchAll('SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES');
+
+ if (!$result || empty($result)) {
+ return array();
+ } else {
+ $tables = array();
+
+ foreach ($result as $table) {
+ $tables[] = $table[0]['TABLE_NAME'];
+ }
+
+ parent::listSources($tables);
+ return $tables;
+ }
+ }
+/**
+ * Returns an array of the fields in given table name.
+ *
+ * @param Model $model Model object to describe
+ * @return array Fields in table. Keys are name and type
+ */
+ function describe(&$model) {
+ $cache = parent::describe($model);
+
+ if ($cache != null) {
+ return $cache;
+ }
+
+ $fields = false;
+ $cols = $this->fetchAll("SELECT COLUMN_NAME as Field, DATA_TYPE as Type, COL_LENGTH('" . $this->fullTableName($model, false) . "', COLUMN_NAME) as Length, IS_NULLABLE As [Null], COLUMN_DEFAULT as [Default], COLUMNPROPERTY(OBJECT_ID('" . $this->fullTableName($model, false) . "'), COLUMN_NAME, 'IsIdentity') as [Key], NUMERIC_SCALE as Size FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = '" . $this->fullTableName($model, false) . "'", false);
+
+ foreach ($cols as $column) {
+ $fields[$column[0]['Field']] = array(
+ 'type' => $this->column($column[0]['Type']),
+ 'null' => (strtoupper($column[0]['Null']) == 'YES'),
+ 'default' => $column[0]['Default'],
+ 'length' => $this->length($column[0]['Type']),
+ );
+ }
+ $this->__cacheDescription($this->fullTableName($model, false), $fields);
+ return $fields;
+ }
+/**
+ * Returns a quoted and escaped string of $data for use in an SQL statement.
+ *
+ * @param string $data String to be prepared for use in an SQL statement
+ * @param string $column The column into which this data will be inserted
+ * @param boolean $safe Whether or not numeric data should be handled automagically if no column data is provided
+ * @return string Quoted and escaped data
+ */
+ function value($data, $column = null, $safe = false) {
+ $parent = parent::value($data, $column, $safe);
+
+ if ($parent != null) {
+ return $parent;
+ }
+ if ($data === null) {
+ return 'NULL';
+ }
+ if ($data === '') {
+ return "''";
+ }
+
+ switch($column) {
+ case 'boolean':
+ $data = $this->boolean((bool)$data);
+ break;
+ case 'datetime':
+ if ($data && (($timestamp = strtotime($data)) !== false)) {
+ $data = date('Y-m-d\TH:i:s', $timestamp);
+ }
+ break;
+ default:
+ if (get_magic_quotes_gpc()) {
+ $data = stripslashes(str_replace("'", "''", $data));
+ } else {
+ $data = str_replace("'", "''", $data);
+ }
+ break;
+ }
+
+ if (in_array($column, array('integer', 'float')) && is_numeric($data)) {
+ return $data;
+ }
+ return "'" . $data . "'";
+ }
+/**
+ * Generates the fields list of an SQL query.
+ *
+ * @param Model $model
+ * @param string $alias Alias tablename
+ * @param mixed $fields
+ * @return array
+ */
+ function fields(&$model, $alias = null, $fields = array(), $quote = true) {
+ if (empty($alias)) {
+ $alias = $model->name;
+ }
+ $fields = parent::fields($model, $alias, $fields, false);
+ $count = count($fields);
+
+ if ($count >= 1 && $fields[0] != '*' && strpos($fields[0], 'COUNT(*)') === false) {
+ for ($i = 0; $i < $count; $i++) {
+ $dot = strrpos($fields[$i], '.');
+ $fieldAlias = count($this->__fieldMappings);
+
+ if ($dot === false && !preg_match('/\s+AS\s+/i', $fields[$i])) {
+ $this->__fieldMappings[$alias . '__' . $fieldAlias] = $alias . '.' . $fields[$i];
+ $fields[$i] = $this->name($alias) . '.' . $this->name($fields[$i]) . ' AS ' . $this->name($alias . '__' . $fieldAlias);
+ } elseif (!preg_match('/\s+AS\s+/i', $fields[$i])) {
+ $build = explode('.', $fields[$i]);
+ $this->__fieldMappings[$build[0] . '__' . $fieldAlias] = $build[0] . '.' . $build[1];
+ $fields[$i] = $this->name($build[0]) . '.' . $this->name($build[1]) . ' AS ' . $this->name($build[0] . '__' . $fieldAlias);
+ }
+ }
+ }
+ return $fields;
+ }
+/**
+ * Begin a transaction
+ *
+ * @param unknown_type $model
+ * @return boolean True on success, false on fail
+ * (i.e. if the database/model does not support transactions).
+ */
+ function begin(&$model) {
+ if (parent::begin($model)) {
+ if ($this->execute('BEGIN TRANSACTION')) {
+ $this->_transactionStarted = true;
+ return true;
+ }
+ }
+ return false;
+ }
+/**
+ * Commit a transaction
+ *
+ * @param unknown_type $model
+ * @return boolean True on success, false on fail
+ * (i.e. if the database/model does not support transactions,
+ * or a transaction has not started).
+ */
+ function commit(&$model) {
+ if (parent::commit($model)) {
+ $this->_transactionStarted = false;
+ return $this->execute('COMMIT');
+ }
+ return false;
+ }
+/**
+ * Rollback a transaction
+ *
+ * @param unknown_type $model
+ * @return boolean True on success, false on fail
+ * (i.e. if the database/model does not support transactions,
+ * or a transaction has not started).
+ */
+ function rollback(&$model) {
+ if (parent::rollback($model)) {
+ return $this->execute('ROLLBACK');
+ }
+ return false;
+ }
+/**
+ * Removes Identity (primary key) column from update data before returning to parent
+ *
+ * @param Model $model
+ * @param array $fields
+ * @param array $values
+ * @return array
+ */
+ function update(&$model, $fields = array(), $values = array()) {
+ foreach ($fields as $i => $field) {
+ if ($field == $model->primaryKey) {
+ unset ($fields[$i]);
+ unset ($values[$i]);
+ break;
+ }
+ }
+ return parent::update($model, $fields, $values);
+ }
+/**
+ * Returns a formatted error message from previous database operation.
+ *
+ * @return string Error message with error number
+ */
+ function lastError() {
+ $error = mssql_get_last_message($this->connection);
+
+ if ($error) {
+ if (strpos(strtolower($error), 'changed database') === false) {
+ return $error;
+ }
+ }
+ return null;
+ }
+/**
+ * Returns number of affected rows in previous database operation. If no previous operation exists,
+ * this returns false.
+ *
+ * @return int Number of affected rows
+ */
+ function lastAffected() {
+ if ($this->_result) {
+ return mssql_rows_affected($this->connection);
+ }
+ return null;
+ }
+/**
+ * Returns number of rows in previous resultset. If no previous resultset exists,
+ * this returns false.
+ *
+ * @return int Number of rows in resultset
+ */
+ function lastNumRows() {
+ if ($this->_result) {
+ return @mssql_num_rows($this->_result);
+ }
+ return null;
+ }
+/**
+ * Returns the ID generated from the previous INSERT operation.
+ *
+ * @param unknown_type $source
+ * @return in
+ */
+ function lastInsertId($source = null) {
+ $id = $this->fetchRow('SELECT SCOPE_IDENTITY() AS insertID', false);
+ return $id[0]['insertID'];
+ }
+/**
+ * Returns a limit statement in the correct format for the particular database.
+ *
+ * @param int $limit Limit of results returned
+ * @param int $offset Offset from which to start results
+ * @return string SQL limit/offset statement
+ */
+ function limit($limit, $offset = null) {
+ if ($limit) {
+ $rt = '';
+ if (!strpos(strtolower($limit), 'top') || strpos(strtolower($limit), 'top') === 0) {
+ $rt = ' TOP';
+ }
+ $rt .= ' ' . $limit;
+ if (is_int($offset) && $offset > 0) {
+ $rt .= ' OFFSET ' . $offset;
+ }
+ return $rt;
+ }
+ return null;
+ }
+/**
+ * Converts database-layer column types to basic types
+ *
+ * @param string $real Real database-layer column type (i.e. "varchar(255)")
+ * @return string Abstract column type (i.e. "string")
+ */
+ function column($real) {
+ if (is_array($real)) {
+ $col = $real['name'];
+
+ if (isset($real['limit'])) {
+ $col .= '(' . $real['limit'] . ')';
+ }
+ return $col;
+ }
+ $col = str_replace(')', '', $real);
+ $limit = null;
+ @list($col, $limit) = explode('(', $col);
+
+ if (in_array($col, array('date', 'time', 'datetime', 'timestamp'))) {
+ return $col;
+ }
+
+ if ($col == 'bit') {
+ return 'boolean';
+ }
+
+ if (strpos($col, 'int') !== false || $col == 'numeric') {
+ return 'integer';
+ }
+
+ if (strpos($col, 'char') !== false) {
+ return 'string';
+ }
+
+ if (strpos($col, 'text') !== false) {
+ return 'text';
+ }
+
+ if (strpos($col, 'binary') !== false || $col == 'image') {
+ return 'binary';
+ }
+
+ if (in_array($col, array('float', 'real', 'decimal'))) {
+ return 'float';
+ }
+ return 'text';
+ }
+/**
+ * Enter description here...
+ *
+ * @param unknown_type $results
+ */
+ function resultSet(&$results) {
+ $this->results =& $results;
+ $this->map = array();
+ $num_fields = mssql_num_fields($results);
+ $index = 0;
+ $j = 0;
+
+ while ($j < $num_fields) {
+ $column = mssql_field_name($results, $j);
+
+ if (strpos($column, '__')) {
+ if (isset($this->__fieldMappings[$column]) && strpos($this->__fieldMappings[$column], '.')) {
+ $map = explode('.', $this->__fieldMappings[$column]);
+ } elseif (isset($this->__fieldMappings[$column])) {
+ $map = array(0, $this->__fieldMappings[$column]);
+ } else {
+ $map = array(0, $column);
+ }
+ $this->map[$index++] = $map;
+ } else {
+ $this->map[$index++] = array(0, $column);
+ }
+ $j++;
+ }
+ }
+/**
+ * Builds final SQL statement
+ *
+ * @param array $data Query data
+ * @return string
+ */
+ function renderStatement($data) {
+ extract($data);
+ if (preg_match('/offset\s+([0-9]+)/i', $limit, $offset)) {
+ $limit = preg_replace('/\s*offset.*$/i', '', $limit);
+ preg_match('/top\s+([0-9]+)/i', $limit, $limitVal);
+ $offset = intval($offset[1]) + intval($limitVal[1]);
+ $rOrder = $this->__switchSort($order);
+ list($order2, $rOrder) = array($this->__mapFields($order), $this->__mapFields($rOrder));
+ return "SELECT * FROM (SELECT {$limit} * FROM (SELECT TOP {$offset} {$fields} FROM {$table} {$alias} {$joins} {$conditions} {$order}) AS Set1 {$rOrder}) AS Set2 {$order2}";
+ } else {
+ return "SELECT {$limit} {$fields} FROM {$table} {$alias} {$joins} {$conditions} {$order}";
+ }
+ }
+/**
+ * Reverses the sort direction of ORDER statements to get paging offsets to work correctly
+ *
+ * @param string $order
+ * @return string
+ * @access private
+ */
+ function __switchSort($order) {
+ $order = preg_replace('/\s+ASC/i', '__tmp_asc__', $order);
+ $order = preg_replace('/\s+DESC/i', ' ASC', $order);
+ return preg_replace('/__tmp_asc__/', ' DESC', $order);
+ }
+/**
+ * Translates field names used for filtering and sorting to shortened names using the field map
+ *
+ * @param string $sql A snippet of SQL representing an ORDER or WHERE statement
+ * @return string The value of $sql with field names replaced
+ * @access private
+ */
+ function __mapFields($sql) {
+ if (empty($sql) || empty($this->__fieldMappings)) {
+ return $sql;
+ }
+ foreach ($this->__fieldMappings as $key => $val) {
+ $sql = preg_replace('/' . preg_quote($val) . '/', $this->name($key), $sql);
+ $sql = preg_replace('/' . preg_quote($this->name($val)) . '/', $this->name($key), $sql);
+ }
+ return $sql;
+ }
+/**
+ * Returns an array of all result rows for a given SQL query.
+ * Returns false if no rows matched.
+ *
+ * @param string $sql SQL statement
+ * @param boolean $cache Enables returning/storing cached query results
+ * @return array Array of resultset rows, or false if no rows matched
+ */
+ function read(&$model, $queryData = array(), $recursive = null) {
+ $results = parent::read($model, $queryData, $recursive);
+ $this->__fieldMappings = array();
+ $this->__fieldMapBase = null;
+ return $results;
+ }
+/**
+ * Fetches the next row from the current result set
+ *
+ * @return unknown
+ */
+ function fetchResult() {
+ if ($row = mssql_fetch_row($this->results)) {
+ $resultRow = array();
+ $i = 0;
+
+ foreach ($row as $index => $field) {
+ list($table, $column) = $this->map[$index];
+ $resultRow[$table][$column] = $row[$index];
+ $i++;
+ }
+ return $resultRow;
+ } else {
+ return false;
+ }
+ }
+/**
+ * Inserts multiple values into a join table
+ *
+ * @param string $table
+ * @param string $fields
+ * @param array $values
+ */
+ function insertMulti($table, $fields, $values) {
+ $count = count($values);
+ for ($x = 0; $x < $count; $x++) {
+ $this->query("INSERT INTO {$table} ({$fields}) VALUES {$values[$x]}");
+ }
+ }
+
+}
+?>
diff --git a/site/cake/libs/model/dbo/dbo_mysql.php b/site/cake/libs/model/dbo/dbo_mysql.php
new file mode 100644
index 0000000..3123e74
--- /dev/null
+++ b/site/cake/libs/model/dbo/dbo_mysql.php
@@ -0,0 +1,679 @@
+<?php
+/* SVN FILE: $Id: dbo_mysql.php 6305 2008-01-02 02:33:56Z phpnut $ */
+/**
+ * MySQL layer for DBO
+ *
+ * Long description for file
+ *
+ * PHP versions 4 and 5
+ *
+ * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
+ * Copyright 2005-2008, Cake Software Foundation, Inc.
+ * 1785 E. Sahara Avenue, Suite 490-204
+ * Las Vegas, Nevada 89104
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
+ * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
+ * @package cake
+ * @subpackage cake.cake.libs.model.dbo
+ * @since CakePHP(tm) v 0.10.5.1790
+ * @version $Revision: 6305 $
+ * @modifiedby $LastChangedBy: phpnut $
+ * @lastmodified $Date: 2008-01-01 20:33:56 -0600 (Tue, 01 Jan 2008) $
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+
+/**
+ * Short description for class.
+ *
+ * Long description for class
+ *
+ * @package cake
+ * @subpackage cake.cake.libs.model.dbo
+ */
+class DboMysql extends DboSource {
+/**
+ * Enter description here...
+ *
+ * @var unknown_type
+ */
+ var $description = "MySQL DBO Driver";
+/**
+ * Enter description here...
+ *
+ * @var unknown_type
+ */
+ var $startQuote = "`";
+/**
+ * Enter description here...
+ *
+ * @var unknown_type
+ */
+ var $endQuote = "`";
+/**
+ * Base configuration settings for MySQL driver
+ *
+ * @var array
+ */
+ var $_baseConfig = array(
+ 'persistent' => true,
+ 'host' => 'localhost',
+ 'login' => 'root',
+ 'password' => '',
+ 'database' => 'cake',
+ 'port' => '3306',
+ 'connect' => 'mysql_pconnect'
+ );
+/**
+ * MySQL column definition
+ *
+ * @var array
+ */
+ var $columns = array(
+ 'primary_key' => array('name' => 'int(11) DEFAULT NULL auto_increment'),
+ 'string' => array('name' => 'varchar', 'limit' => '255'),
+ 'text' => array('name' => 'text'),
+ 'integer' => array('name' => 'int', 'limit' => '11', 'formatter' => 'intval'),
+ 'float' => array('name' => 'float', 'formatter' => 'floatval'),
+ 'datetime' => array('name' => 'datetime', 'format' => 'Y-m-d H:i:s', 'formatter' => 'date'),
+ 'timestamp' => array('name' => 'timestamp', 'format' => 'Y-m-d H:i:s', 'formatter' => 'date'),
+ 'time' => array('name' => 'time', 'format' => 'H:i:s', 'formatter' => 'date'),
+ 'date' => array('name' => 'date', 'format' => 'Y-m-d', 'formatter' => 'date'),
+ 'binary' => array('name' => 'blob'),
+ 'boolean' => array('name' => 'tinyint', 'limit' => '1')
+ );
+/**
+ * Connects to the database using options in the given configuration array.
+ *
+ * @return boolean True if the database could be connected, else false
+ */
+ function connect() {
+ $config = $this->config;
+ $connect = $config['connect'];
+ $this->connected = false;
+
+ if (!$config['persistent'] || $config['connect'] === 'mysql_connect') {
+ $this->connection = mysql_connect($config['host'] . ':' . $config['port'], $config['login'], $config['password'], true);
+ } else {
+ $this->connection = $connect($config['host'] . ':' . $config['port'], $config['login'], $config['password']);
+ }
+
+ if (mysql_select_db($config['database'], $this->connection)) {
+ $this->connected = true;
+ }
+
+ if (isset($config['encoding']) && !empty($config['encoding'])) {
+ $this->setEncoding($config['encoding']);
+ }
+
+ return $this->connected;
+ }
+/**
+ * Disconnects from database.
+ *
+ * @return boolean True if the database could be disconnected, else false
+ */
+ function disconnect() {
+ @mysql_free_result($this->results);
+ $this->connected = !@mysql_close($this->connection);
+ return !$this->connected;
+ }
+/**
+ * Executes given SQL statement.
+ *
+ * @param string $sql SQL statement
+ * @return resource Result resource identifier
+ * @access protected
+ */
+ function _execute($sql) {
+ return mysql_query($sql, $this->connection);
+ }
+/**
+ * Returns an array of sources (tables) in the database.
+ *
+ * @return array Array of tablenames in the database
+ */
+ function listSources() {
+ $cache = parent::listSources();
+ if ($cache != null) {
+ return $cache;
+ }
+ $result = $this->_execute('SHOW TABLES FROM ' . $this->name($this->config['database']) . ';');
+
+ if (!$result) {
+ return array();
+ } else {
+ $tables = array();
+
+ while ($line = mysql_fetch_array($result)) {
+ $tables[] = $line[0];
+ }
+ parent::listSources($tables);
+ return $tables;
+ }
+ }
+/**
+ * Returns an array of the fields in given table name.
+ *
+ * @param string $tableName Name of database table to inspect
+ * @return array Fields in table. Keys are name and type
+ */
+ function describe(&$model) {
+ $cache = parent::describe($model);
+ if ($cache != null) {
+ return $cache;
+ }
+ $fields = false;
+ $cols = $this->query('DESCRIBE ' . $this->fullTableName($model));
+
+ foreach ($cols as $column) {
+ $colKey = array_keys($column);
+ if (isset($column[$colKey[0]]) && !isset($column[0])) {
+ $column[0] = $column[$colKey[0]];
+ }
+ if (isset($column[0])) {
+ $fields[$column[0]['Field']] = array(
+ 'type' => $this->column($column[0]['Type']),
+ 'null' => ($column[0]['Null'] == 'YES' ? true : false),
+ 'default' => $column[0]['Default'],
+ 'length' => $this->length($column[0]['Type']),
+ );
+ if(!empty($column[0]['Key']) && isset($this->index[$column[0]['Key']])) {
+ $fields[$column[0]['Field']]['key'] = $this->index[$column[0]['Key']];
+ }
+ if(!empty($column[0]['Extra'])) {
+ $fields[$column[0]['Field']]['extra'] = $column[0]['Extra'];
+ }
+ }
+ }
+ $this->__cacheDescription($this->fullTableName($model, false), $fields);
+ return $fields;
+ }
+/**
+ * Returns a quoted and escaped string of $data for use in an SQL statement.
+ *
+ * @param string $data String to be prepared for use in an SQL statement
+ * @param string $column The column into which this data will be inserted
+ * @param boolean $safe Whether or not numeric data should be handled automagically if no column data is provided
+ * @return string Quoted and escaped data
+ */
+ function value($data, $column = null, $safe = false) {
+ $parent = parent::value($data, $column, $safe);
+
+ if ($parent != null) {
+ return $parent;
+ }
+
+ if ($data === null) {
+ return 'NULL';
+ }
+
+ if ($data === '') {
+ return "''";
+ }
+
+ switch ($column) {
+ case 'boolean':
+ $data = $this->boolean((bool)$data);
+ break;
+ case 'integer' :
+ case 'float' :
+ case null :
+ if (is_numeric($data) && strpos($data, ',') === false && $data[0] != '0' && strpos($data, 'e') === false) {
+ break;
+ }
+ default:
+ $data = "'" . mysql_real_escape_string($data, $this->connection) . "'";
+ break;
+ }
+
+ return $data;
+ }
+/**
+ * Begin a transaction
+ *
+ * @param unknown_type $model
+ * @return boolean True on success, false on fail
+ * (i.e. if the database/model does not support transactions).
+ */
+ function begin(&$model) {
+ if (parent::begin($model)) {
+ if ($this->execute('START TRANSACTION')) {
+ $this->_transactionStarted = true;
+ return true;
+ }
+ }
+ return false;
+ }
+/**
+ * Commit a transaction
+ *
+ * @param unknown_type $model
+ * @return boolean True on success, false on fail
+ * (i.e. if the database/model does not support transactions,
+ * or a transaction has not started).
+ */
+ function commit(&$model) {
+ if (parent::commit($model)) {
+ $this->_transactionStarted = false;
+ return $this->execute('COMMIT');
+ }
+ return false;
+ }
+/**
+ * Rollback a transaction
+ *
+ * @param unknown_type $model
+ * @return boolean True on success, false on fail
+ * (i.e. if the database/model does not support transactions,
+ * or a transaction has not started).
+ */
+ function rollback(&$model) {
+ //if (parent::rollback($model)) {
+ return $this->execute('ROLLBACK');
+ //}
+ return false;
+ }
+/**
+ * Returns a formatted error message from previous database operation.
+ *
+ * @return string Error message with error number
+ */
+ function lastError() {
+ if (mysql_errno($this->connection)) {
+ return mysql_errno($this->connection).': '.mysql_error($this->connection);
+ }
+ return null;
+ }
+/**
+ * Returns number of affected rows in previous database operation. If no previous operation exists,
+ * this returns false.
+ *
+ * @return int Number of affected rows
+ */
+ function lastAffected() {
+ if ($this->_result) {
+ return mysql_affected_rows($this->connection);
+ }
+ return null;
+ }
+/**
+ * Returns number of rows in previous resultset. If no previous resultset exists,
+ * this returns false.
+ *
+ * @return int Number of rows in resultset
+ */
+ function lastNumRows() {
+ if ($this->_result and is_resource($this->_result)) {
+ return @mysql_num_rows($this->_result);
+ }
+ return null;
+ }
+/**
+ * Returns the ID generated from the previous INSERT operation.
+ *
+ * @param unknown_type $source
+ * @return in
+ */
+ function lastInsertId($source = null) {
+ $id = $this->fetchRow('SELECT LAST_INSERT_ID() AS insertID', false);
+ if ($id !== false && !empty($id) && !empty($id[0]) && isset($id[0]['insertID'])) {
+ return $id[0]['insertID'];
+ }
+
+ return null;
+ }
+/**
+ * Converts database-layer column types to basic types
+ *
+ * @param string $real Real database-layer column type (i.e. "varchar(255)")
+ * @return string Abstract column type (i.e. "string")
+ */
+ function column($real) {
+ if (is_array($real)) {
+ $col = $real['name'];
+ if (isset($real['limit'])) {
+ $col .= '('.$real['limit'].')';
+ }
+ return $col;
+ }
+
+ $col = r(')', '', $real);
+ $limit = $this->length($real);
+ @list($col,$vals) = explode('(', $col);
+
+ if (in_array($col, array('date', 'time', 'datetime', 'timestamp'))) {
+ return $col;
+ }
+ if ($col == 'tinyint' && $limit == 1) {
+ return 'boolean';
+ }
+ if (strpos($col, 'int') !== false) {
+ return 'integer';
+ }
+ if (strpos($col, 'char') !== false || $col == 'tinytext') {
+ return 'string';
+ }
+ if (strpos($col, 'text') !== false) {
+ return 'text';
+ }
+ if (strpos($col, 'blob') !== false) {
+ return 'binary';
+ }
+ if (in_array($col, array('float', 'double', 'decimal'))) {
+ return 'float';
+ }
+ if (strpos($col, 'enum') !== false) {
+ return "enum($vals)";
+ }
+ if ($col == 'boolean') {
+ return $col;
+ }
+ return 'text';
+ }
+/**
+ * Gets the length of a database-native column description, or null if no length
+ *
+ * @param string $real Real database-layer column type (i.e. "varchar(255)")
+ * @return int An integer representing the length of the column
+ */
+ function length($real) {
+ $col = r(array(')', 'unsigned'), '', $real);
+ $limit = null;
+
+ if (strpos($col, '(') !== false) {
+ list($col, $limit) = explode('(', $col);
+ }
+
+ if ($limit != null) {
+ return intval($limit);
+ }
+ return null;
+ }
+/**
+ * Enter description here...
+ *
+ * @param unknown_type $results
+ */
+ function resultSet(&$results) {
+ $this->results =& $results;
+ $this->map = array();
+ $num_fields = mysql_num_fields($results);
+ $index = 0;
+ $j = 0;
+
+ while ($j < $num_fields) {
+
+ $column = mysql_fetch_field($results,$j);
+ if (!empty($column->table)) {
+ $this->map[$index++] = array($column->table, $column->name);
+ } else {
+ $this->map[$index++] = array(0, $column->name);
+ }
+ $j++;
+ }
+ }
+/**
+ * Fetches the next row from the current result set
+ *
+ * @return unknown
+ */
+ function fetchResult() {
+ if ($row = mysql_fetch_row($this->results)) {
+ $resultRow = array();
+ $i = 0;
+ foreach ($row as $index => $field) {
+ list($table, $column) = $this->map[$index];
+ $resultRow[$table][$column] = $row[$index];
+ $i++;
+ }
+ return $resultRow;
+ } else {
+ return false;
+ }
+ }
+/**
+ * Sets the database encoding
+ *
+ * @param string $enc Database encoding
+ * @return void
+ */
+ function setEncoding($enc) {
+ return $this->_execute('SET NAMES ' . $enc) != false;
+ }
+/**
+ * Gets the database encoding
+ *
+ * @return string The database encoding
+ */
+ function getEncoding() {
+ return mysql_client_encoding($this->connection);
+ }
+/**
+ * Returns an array of the indexes in given table name.
+ *
+ * @param string $model Name of model to inspect
+ * @return array Fields in table. Keys are column and unique
+ */
+ function index($model) {
+ $index = array();
+ $table = $this->fullTableName($model, false);
+ if($table) {
+ $indexes = $this->query('SHOW INDEX FROM ' . $table);
+ $keys = Set::extract($indexes, '{n}.STATISTICS');
+ foreach ($keys as $i => $key) {
+ if(!isset($index[$key['Key_name']])) {
+ $index[$key['Key_name']]['column'] = $key['Column_name'];
+ $index[$key['Key_name']]['unique'] = ife($key['Non_unique'] == 0, 1, 0);
+ } else {
+ if(!is_array($index[$key['Key_name']]['column'])) {
+ $col[] = $index[$key['Key_name']]['column'];
+ }
+ $col[] = $key['Column_name'];
+ $index[$key['Key_name']]['column'] = $col;
+ }
+ }
+ }
+ return $index;
+ }
+/**
+ * Generate a MySQL schema for the given Schema object
+ *
+ * @param object $schema An instance of a subclass of CakeSchema
+ * @param string $table Optional. If specified only the table name given will be generated.
+ * Otherwise, all tables defined in the schema are generated.
+ * @return string
+ */
+ function createSchema($schema, $table = null) {
+ if (!is_a($schema, 'CakeSchema')) {
+ trigger_error(__('Invalid schema object', true), E_USER_WARNING);
+ return null;
+ }
+ $out = '';
+ foreach ($schema->tables as $curTable => $columns) {
+ if (!$table || $table == $curTable) {
+ $out .= 'CREATE TABLE ' . $this->fullTableName($curTable) . " (\n";
+ $cols = $colList = $index = array();
+ $primary = null;
+ foreach ($columns as $name => $col) {
+ if (is_string($col)) {
+ $col = array('type' => $col);
+ }
+ if (isset($col['key']) && $col['key'] == 'primary') {
+ $primary = $name;
+ }
+ if($name !== 'indexes') {
+ $col['name'] = $name;
+ if(!isset($col['type'])) {
+ $col['type'] = 'string';
+ }
+ $cols[] = $this->buildColumn($col);
+ } else {
+ $index[] = $this->buildIndex($col);
+ }
+
+ }
+ if(empty($index) && !empty($primary)) {
+ $col = array('PRIMARY' => array('column'=> $primary, 'unique' => 1));
+ $index[] = $this->buildIndex($col);
+ }
+ $out .= "\t" . join(",\n\t", $cols) . ",\n\t". join(",\n\t", $index) . "\n);\n\n";
+ }
+ }
+ return $out;
+ }
+/**
+ * Generate a MySQL Alter Table syntax for the given Schema comparison
+ *
+ * @param unknown_type $schema
+ * @return unknown
+ */
+ function alterSchema($compare, $table = null) {
+ if(!is_array($compare)) {
+ return false;
+ }
+ $out = '';
+ $colList = array();
+ foreach($compare as $curTable => $types) {
+ if (!$table || $table == $curTable) {
+ $out .= 'ALTER TABLE ' . $this->fullTableName($curTable) . " \n";
+ foreach($types as $type => $column) {
+ switch($type) {
+ case 'add':
+ foreach($column as $field => $col) {
+ $col['name'] = $field;
+ $alter = 'ADD '.$this->buildColumn($col);
+ if(isset($col['after'])) {
+ $alter .= ' AFTER '. $this->name($col['after']);
+ }
+ $colList[] = $alter;
+ }
+ break;
+ case 'drop':
+ foreach($column as $field => $col) {
+ $col['name'] = $field;
+ $colList[] = 'DROP '.$this->name($field);
+ }
+ break;
+ case 'change':
+ foreach($column as $field => $col) {
+ if(!isset($col['name'])) {
+ $col['name'] = $field;
+ }
+ $colList[] = 'CHANGE '. $this->name($field).' '.$this->buildColumn($col);
+ }
+ break;
+ }
+ }
+ $out .= "\t" . join(",\n\t", $colList) . ";\n\n";
+ }
+ }
+ return $out;
+ }
+/**
+ * Generate a MySQL Drop table for the given Schema object
+ *
+ * @param object $schema An instance of a subclass of CakeSchema
+ * @param string $table Optional. If specified only the table name given will be generated.
+ * Otherwise, all tables defined in the schema are generated.
+ * @return string
+ */
+ function dropSchema($schema, $table = null) {
+ if (!is_a($schema, 'CakeSchema')) {
+ trigger_error(__('Invalid schema object', true), E_USER_WARNING);
+ return null;
+ }
+ $out = '';
+ foreach ($schema->tables as $curTable => $columns) {
+ if (!$table || $table == $curTable) {
+ $out .= 'DROP TABLE IF EXISTS ' . $this->fullTableName($curTable) . ";\n";
+ }
+ }
+ return $out;
+ }
+/**
+ * Generate a MySQL-native column schema string
+ *
+ * @param array $column An array structured like the following: array('name'=>'value', 'type'=>'value'[, options]),
+ * where options can be 'default', 'length', or 'key'.
+ * @return string
+ */
+ function buildColumn($column) {
+ $name = $type = null;
+ $column = am(array('null' => true), $column);
+ extract($column);
+
+ if (empty($name) || empty($type)) {
+ trigger_error('Column name or type not defined in schema', E_USER_WARNING);
+ return null;
+ }
+
+ if (!isset($this->columns[$type])) {
+ trigger_error("Column type {$type} does not exist", E_USER_WARNING);
+ return null;
+ }
+
+ $real = $this->columns[$type];
+ $out = $this->name($name) . ' ' . $real['name'];
+
+ if (isset($real['limit']) || isset($real['length']) || isset($column['limit']) || isset($column['length'])) {
+ if (isset($column['length'])) {
+ $length = $column['length'];
+ } elseif (isset($column['limit'])) {
+ $length = $column['limit'];
+ } elseif (isset($real['length'])) {
+ $length = $real['length'];
+ } else {
+ $length = $real['limit'];
+ }
+ $out .= '(' . $length . ')';
+ }
+ if (isset($column['key']) && $column['key'] == 'primary' && (isset($column['extra']) && $column['extra'] == 'auto_increment')) {
+ $out .= ' NOT NULL AUTO_INCREMENT';
+ } elseif (isset($column['key']) && $column['key'] == 'primary') {
+ $out .= ' NOT NULL';
+ } elseif (isset($column['default']) && isset($column['null']) && $column['null'] == false) {
+ $out .= ' DEFAULT ' . $this->value($column['default'], $type) . ' NOT NULL';
+ } elseif (isset($column['default'])) {
+ $out .= ' DEFAULT ' . $this->value($column['default'], $type);
+ } elseif (isset($column['null']) && $column['null'] == true) {
+ $out .= ' DEFAULT NULL';
+ } elseif (isset($column['null']) && $column['null'] == false) {
+ $out .= ' NOT NULL';
+ }
+
+ return $out;
+ }
+/**
+ * Format indexes for create table
+ *
+ * @param array $indexes
+ * @return string
+ */
+ function buildIndex($indexes) {
+ $join = array();
+ foreach ($indexes as $name => $value) {
+ $out = '';
+ if ($name == 'PRIMARY') {
+ $out .= 'PRIMARY ';
+ $name = null;
+ } else {
+ if (!empty($value['unique'])) {
+ $out .= 'UNIQUE ';
+ }
+ }
+ if (is_array($value['column'])) {
+ $out .= 'KEY '. $name .' (' . join(', ', array_map(array(&$this, 'name'), $value['column'])) . ')';
+ } else {
+ $out .= 'KEY '. $name .' (' . $this->name($value['column']) . ')';
+ }
+ $join[] = $out;
+ }
+ return join(",\n\t", $join);
+ }
+}
+?>
diff --git a/site/cake/libs/model/dbo/dbo_mysqli.php b/site/cake/libs/model/dbo/dbo_mysqli.php
new file mode 100644
index 0000000..1712446
--- /dev/null
+++ b/site/cake/libs/model/dbo/dbo_mysqli.php
@@ -0,0 +1,441 @@
+<?php
+/* SVN FILE: $Id: dbo_mysqli.php 6305 2008-01-02 02:33:56Z phpnut $ */
+/**
+ * MySQLi layer for DBO
+ *
+ * Long description for file
+ *
+ * PHP versions 4 and 5
+ *
+ * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
+ * Copyright 2005-2008, Cake Software Foundation, Inc.
+ * 1785 E. Sahara Avenue, Suite 490-204
+ * Las Vegas, Nevada 89104
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
+ * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
+ * @package cake
+ * @subpackage cake.cake.libs.model.dbo
+ * @since CakePHP(tm) v 1.1.4.2974
+ * @version $Revision: 6305 $
+ * @modifiedby $LastChangedBy: phpnut $
+ * @lastmodified $Date: 2008-01-01 20:33:56 -0600 (Tue, 01 Jan 2008) $
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+
+/**
+ * Short description for class.
+ *
+ * Long description for class
+ *
+ * @package cake
+ * @subpackage cake.cake.libs.model.dbo
+ */
+class DboMysqli extends DboSource {
+/**
+ * Enter description here...
+ *
+ * @var unknown_type
+ */
+ var $description = "Mysqli DBO Driver";
+/**
+ * Enter description here...
+ *
+ * @var unknown_type
+ */
+ var $startQuote = "`";
+/**
+ * Enter description here...
+ *
+ * @var unknown_type
+ */
+ var $endQuote = "`";
+/**
+ * Base configuration settings for Mysqli driver
+ *
+ * @var array
+ */
+ var $_baseConfig = array('persistent' => true,
+ 'host' => 'localhost',
+ 'login' => 'root',
+ 'password' => '',
+ 'database' => 'cake',
+ 'port' => '3306',
+ 'connect' => 'mysqli_connect');
+/**
+ * Mysqli column definition
+ *
+ * @var array
+ */
+ var $columns = array('primary_key' => array('name' => 'int(11) DEFAULT NULL auto_increment'),
+ 'string' => array('name' => 'varchar', 'limit' => '255'),
+ 'text' => array('name' => 'text'),
+ 'integer' => array('name' => 'int', 'limit' => '11', 'formatter' => 'intval'),
+ 'float' => array('name' => 'float', 'formatter' => 'floatval'),
+ 'datetime' => array('name' => 'datetime', 'format' => 'Y-m-d H:i:s', 'formatter' => 'date'),
+ 'timestamp' => array('name' => 'timestamp', 'format' => 'Y-m-d H:i:s', 'formatter' => 'date'),
+ 'time' => array('name' => 'time', 'format' => 'H:i:s', 'formatter' => 'date'),
+ 'date' => array('name' => 'date', 'format' => 'Y-m-d', 'formatter' => 'date'),
+ 'binary' => array('name' => 'blob'),
+ 'boolean' => array('name' => 'tinyint', 'limit' => '1'));
+/**
+ * Connects to the database using options in the given configuration array.
+ *
+ * @return boolean True if the database could be connected, else false
+ */
+ function connect() {
+ $config = $this->config;
+ $this->connected = false;
+ $this->connection = mysqli_connect($config['host'], $config['login'], $config['password'], $config['database'], $config['port']);
+
+ if ($this->connection !== false) {
+ $this->connected = true;
+ }
+
+ if (!empty($config['encoding'])) {
+ $this->setEncoding($config['encoding']);
+ }
+ return $this->connected;
+ }
+/**
+ * Disconnects from database.
+ *
+ * @return boolean True if the database could be disconnected, else false
+ */
+ function disconnect() {
+ @mysqli_free_result($this->results);
+ $this->connected = !@mysqli_close($this->connection);
+ return !$this->connected;
+ }
+/**
+ * Executes given SQL statement.
+ *
+ * @param string $sql SQL statement
+ * @return resource Result resource identifier
+ * @access protected
+ */
+ function _execute($sql) {
+ return mysqli_query($this->connection, $sql);
+ }
+/**
+ * Returns an array of sources (tables) in the database.
+ *
+ * @return array Array of tablenames in the database
+ */
+ function listSources() {
+ $cache = parent::listSources();
+ if ($cache != null) {
+ return $cache;
+ }
+ $result = $this->_execute('SHOW TABLES FROM ' . $this->name($this->config['database']) . ';');
+
+ if (!$result) {
+ return array();
+ } else {
+ $tables = array();
+
+ while ($line = mysqli_fetch_array($result)) {
+ $tables[] = $line[0];
+ }
+ parent::listSources($tables);
+ return $tables;
+ }
+ }
+/**
+ * Returns an array of the fields in given table name.
+ *
+ * @param string $tableName Name of database table to inspect
+ * @return array Fields in table. Keys are name and type
+ */
+ function describe(&$model) {
+
+ $cache = parent::describe($model);
+ if ($cache != null) {
+ return $cache;
+ }
+
+ $fields = false;
+ $cols = $this->query('DESCRIBE ' . $this->fullTableName($model));
+
+ foreach ($cols as $column) {
+ $colKey = array_keys($column);
+ if (isset($column[$colKey[0]]) && !isset($column[0])) {
+ $column[0] = $column[$colKey[0]];
+ }
+ if (isset($column[0])) {
+ $fields[$column[0]['Field']] = array(
+ 'type' => $this->column($column[0]['Type']),
+ 'null' => ($column[0]['Null'] == 'YES' ? true : false),
+ 'default' => $column[0]['Default'],
+ 'length' => $this->length($column[0]['Type'])
+ );
+ }
+ }
+
+ $this->__cacheDescription($this->fullTableName($model, false), $fields);
+ return $fields;
+ }
+/**
+ * Returns a quoted and escaped string of $data for use in an SQL statement.
+ *
+ * @param string $data String to be prepared for use in an SQL statement
+ * @param string $column The column into which this data will be inserted
+ * @param boolean $safe Whether or not numeric data should be handled automagically if no column data is provided
+ * @return string Quoted and escaped data
+ */
+ function value($data, $column = null, $safe = false) {
+ $parent = parent::value($data, $column, $safe);
+
+ if ($parent != null) {
+ return $parent;
+ }
+
+ if ($data === null) {
+ return 'NULL';
+ }
+
+ if ($data === '') {
+ return "''";
+ }
+
+ switch ($column) {
+ case 'boolean':
+ $data = $this->boolean((bool)$data);
+ break;
+ case 'integer' :
+ case 'float' :
+ case null :
+ if (is_numeric($data) && strpos($data, ',') === false && $data[0] != '0' && strpos($data, 'e') === false) {
+ break;
+ }
+ default:
+ $data = "'" . mysqli_real_escape_string($this->connection, $data) . "'";
+ break;
+ }
+
+ return $data;
+ }
+/**
+ * Begin a transaction
+ *
+ * @param unknown_type $model
+ * @return boolean True on success, false on fail
+ * (i.e. if the database/model does not support transactions).
+ */
+ function begin(&$model) {
+ if (parent::begin($model)) {
+ if ($this->execute('START TRANSACTION')) {
+ $this->_transactionStarted = true;
+ return true;
+ }
+ }
+ return false;
+ }
+/**
+ * Commit a transaction
+ *
+ * @param unknown_type $model
+ * @return boolean True on success, false on fail
+ * (i.e. if the database/model does not support transactions,
+ * or a transaction has not started).
+ */
+ function commit(&$model) {
+ if (parent::commit($model)) {
+ $this->_transactionStarted = false;
+ return $this->execute('COMMIT');
+ }
+ return false;
+ }
+/**
+ * Rollback a transaction
+ *
+ * @param unknown_type $model
+ * @return boolean True on success, false on fail
+ * (i.e. if the database/model does not support transactions,
+ * or a transaction has not started).
+ */
+ function rollback(&$model) {
+ if (parent::rollback($model)) {
+ return $this->execute('ROLLBACK');
+ }
+ return false;
+ }
+/**
+ * Returns a formatted error message from previous database operation.
+ *
+ * @return string Error message with error number
+ */
+ function lastError() {
+ if (mysqli_errno($this->connection)) {
+ return mysqli_errno($this->connection).': '.mysqli_error($this->connection);
+ }
+ return null;
+ }
+/**
+ * Returns number of affected rows in previous database operation. If no previous operation exists,
+ * this returns false.
+ *
+ * @return int Number of affected rows
+ */
+ function lastAffected() {
+ if ($this->_result) {
+ return mysqli_affected_rows($this->connection);
+ }
+ return null;
+ }
+/**
+ * Returns number of rows in previous resultset. If no previous resultset exists,
+ * this returns false.
+ *
+ * @return int Number of rows in resultset
+ */
+ function lastNumRows() {
+ if ($this->_result and is_object($this->_result)) {
+ return @mysqli_num_rows($this->_result);
+ }
+ return null;
+ }
+/**
+ * Returns the ID generated from the previous INSERT operation.
+ *
+ * @param unknown_type $source
+ * @return in
+ */
+ function lastInsertId($source = null) {
+ $id = $this->fetchRow('SELECT LAST_INSERT_ID() AS insertID', false);
+ if ($id !== false && !empty($id) && !empty($id[0]) && isset($id[0]['insertID'])) {
+ return $id[0]['insertID'];
+ }
+
+ return null;
+ }
+/**
+ * Converts database-layer column types to basic types
+ *
+ * @param string $real Real database-layer column type (i.e. "varchar(255)")
+ * @return string Abstract column type (i.e. "string")
+ */
+ function column($real) {
+ if (is_array($real)) {
+ $col = $real['name'];
+ if (isset($real['limit'])) {
+ $col .= '('.$real['limit'].')';
+ }
+ return $col;
+ }
+
+ $col = r(')', '', $real);
+ $limit = $this->length($real);
+ @list($col,$vals) = explode('(', $col);
+
+ if (in_array($col, array('date', 'time', 'datetime', 'timestamp'))) {
+ return $col;
+ }
+ if ($col == 'tinyint' && $limit == 1) {
+ return 'boolean';
+ }
+ if (strpos($col, 'int') !== false) {
+ return 'integer';
+ }
+ if (strpos($col, 'char') !== false || $col == 'tinytext') {
+ return 'string';
+ }
+ if (strpos($col, 'text') !== false) {
+ return 'text';
+ }
+ if (strpos($col, 'blob') !== false) {
+ return 'binary';
+ }
+ if (in_array($col, array('float', 'double', 'decimal'))) {
+ return 'float';
+ }
+ if (strpos($col, 'enum') !== false) {
+ return "enum($vals)";
+ }
+ if ($col == 'boolean') {
+ return $col;
+ }
+ return 'text';
+ }
+/**
+ * Gets the length of a database-native column description, or null if no length
+ *
+ * @param string $real Real database-layer column type (i.e. "varchar(255)")
+ * @return int An integer representing the length of the column
+ */
+ function length($real) {
+ $col = r(array(')', 'unsigned'), '', $real);
+ $limit = null;
+
+ if (strpos($col, '(') !== false) {
+ list($col, $limit) = explode('(', $col);
+ }
+
+ if ($limit != null) {
+ return intval($limit);
+ }
+ return null;
+ }
+/**
+ * Enter description here...
+ *
+ * @param unknown_type $results
+ */
+ function resultSet(&$results) {
+ $this->results =& $results;
+ $this->map = array();
+ $num_fields = mysqli_num_fields($results);
+ $index = 0;
+ $j = 0;
+ while ($j < $num_fields) {
+ $column = mysqli_fetch_field_direct($results, $j);
+ if (!empty($column->table)) {
+ $this->map[$index++] = array($column->table, $column->name);
+ } else {
+ $this->map[$index++] = array(0, $column->name);
+ }
+ $j++;
+ }
+ }
+/**
+ * Fetches the next row from the current result set
+ *
+ * @return unknown
+ */
+ function fetchResult() {
+ if ($row = mysqli_fetch_row($this->results)) {
+ $resultRow = array();
+ $i = 0;
+ foreach ($row as $index => $field) {
+ @list($table, $column) = $this->map[$index];
+ $resultRow[$table][$column] = $row[$index];
+ $i++;
+ }
+ return $resultRow;
+ } else {
+ return false;
+ }
+ }
+/**
+ * Sets the database encoding
+ *
+ * @param string $enc Database encoding
+ * @return void
+ */
+ function setEncoding($enc) {
+ return $this->_execute('SET NAMES ' . $enc) != false;
+ }
+/**
+ * Gets the database encoding
+ *
+ * @return string The database encoding
+ */
+ function getEncoding() {
+ return mysqli_client_encoding($this->connection);
+ }
+}
+?> \ No newline at end of file
diff --git a/site/cake/libs/model/dbo/dbo_odbc.php b/site/cake/libs/model/dbo/dbo_odbc.php
new file mode 100644
index 0000000..a0a5193
--- /dev/null
+++ b/site/cake/libs/model/dbo/dbo_odbc.php
@@ -0,0 +1,437 @@
+<?php
+/* SVN FILE: $Id: dbo_odbc.php 6305 2008-01-02 02:33:56Z phpnut $ */
+
+/**
+ * ODBC for DBO
+ *
+ * Long description for file
+ *
+ * PHP versions 4 and 5
+ *
+ * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
+ * Copyright 2005-2008, Cake Software Foundation, Inc.
+ * 1785 E. Sahara Avenue, Suite 490-204
+ * Las Vegas, Nevada 89104
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
+ * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
+ * @package cake
+ * @subpackage cake.cake.libs.model.dbo
+ * @since CakePHP(tm) v 0.10.5.1790
+ * @version $Revision: 6305 $
+ * @modifiedby $LastChangedBy: phpnut $
+ * @lastmodified $Date: 2008-01-01 20:33:56 -0600 (Tue, 01 Jan 2008) $
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+
+/**
+ * Short description for class.
+ *
+ * Long description for class
+ *
+ * @package cake
+ * @subpackage cake.cake.libs.model.dbo
+ */
+class DboOdbc extends DboSource{
+
+/**
+ * Driver description
+ *
+ * @var string
+ */
+ var $description = "ODBC DBO Driver";
+
+/**
+ * Table/column starting quote
+ *
+ * @var string
+ */
+ var $startQuote = "`";
+
+/**
+ * Table/column end quote
+ *
+ * @var string
+ */
+ var $endQuote = "`";
+
+/**
+ * Driver base configuration
+ *
+ * @var array
+ */
+ var $_baseConfig = array('persistent' => true,
+ 'login' => 'root',
+ 'password' => '',
+ 'database' => 'cake',
+ 'connect' => 'odbc_pconnect'
+ );
+
+/**
+ * Enter description here...
+ *
+ * @var unknown_type
+ */
+
+ var $columns = array();
+
+ // var $columns = array('primary_key' => array('name' => 'int(11) DEFAULT NULL auto_increment'),
+ // 'string' => array('name' => 'varchar', 'limit' => '255'),
+ // 'text' => array('name' => 'text'),
+ // 'integer' => array('name' => 'int', 'limit' => '11'),
+ // 'float' => array('name' => 'float'),
+ // 'datetime' => array('name' => 'datetime', 'format' => 'Y-m-d h:i:s', 'formatter' => 'date'),
+ // 'timestamp' => array('name' => 'datetime', 'format' => 'Y-m-d h:i:s', 'formatter' => 'date'),
+ // 'time' => array('name' => 'time', 'format' => 'h:i:s', 'formatter' => 'date'),
+ // 'date' => array('name' => 'date', 'format' => 'Y-m-d', 'formatter' => 'date'),
+ // 'binary' => array('name' => 'blob'),
+ // 'boolean' => array('name' => 'tinyint', 'limit' => '1'));
+
+/**
+ * Connects to the database using options in the given configuration array.
+ *
+ * @return boolean True if the database could be connected, else false
+ */
+ function connect() {
+ $config = $this->config;
+ $connect = $config['connect'];
+
+ $this->connected = false;
+ $this->connection = $connect($config['database'], $config['login'], $config['password']);
+
+ if ($this->connection) {
+ $this->connected = true;
+ }
+
+ return $this->connected;
+ }
+
+/**
+ * Disconnects from database.
+ *
+ * @return boolean True if the database could be disconnected, else false
+ */
+ function disconnect() {
+ return @odbc_close($this->connection);
+ }
+/**
+ * Executes given SQL statement.
+ *
+ * @param string $sql SQL statement
+ * @return resource Result resource identifier
+ * @access protected
+ */
+ function _execute($sql) {
+ return odbc_exec($this->connection, $sql);
+ }
+/**
+ * Returns an array of sources (tables) in the database.
+ *
+ * @return array Array of tablenames in the database
+ */
+ function listSources() {
+
+ $cache = parent::listSources();
+ if ($cache != null) {
+ return $cache;
+ }
+
+ /*$result = odbc_tables($this->connection);
+ if (function_exists('odbc_fetch_row')) {
+ echo 'GOOD';
+ } else {
+ echo 'BAD';
+ }*/
+
+ $result = odbc_tables($this->connection);
+
+ $tables = array();
+ while (odbc_fetch_row($result)) {
+ array_push($tables, odbc_result($result, "TABLE_NAME"));
+ }
+
+ parent::listSources($tables);
+ return $tables;
+ }
+/**
+ * Returns an array of the fields in given table name.
+ *
+ * @param Model $model Model object to describe
+ * @return array Fields in table. Keys are name and type
+ */
+ function &describe(&$model) {
+ $cache=parent::describe($model);
+
+ if ($cache != null) {
+ return $cache;
+ }
+
+ $fields = array();
+ $sql = 'SELECT * FROM ' . $this->fullTableName($model);
+ $result = odbc_exec($this->connection, $sql);
+
+ $count = odbc_num_fields($result);
+
+ for ($i = 1; $i <= $count; $i++) {
+ $cols[$i - 1] = odbc_field_name($result, $i);
+ }
+
+ foreach ($cols as $column) {
+ $type = odbc_field_type(odbc_exec($this->connection, "SELECT " . $column . " FROM " . $this->fullTableName($model)), 1);
+ $fields[$column] = array('type' => $type);
+ }
+
+ $this->__cacheDescription($model->tablePrefix . $model->table, $fields);
+ return $fields;
+ }
+
+ function name($data) {
+ if ($data == '*') {
+ return '*';
+ }
+
+ $pos = strpos($data, '`');
+
+ if ($pos === false) {
+ $data = '' . str_replace('.', '.', $data) . '';
+ //$data = '`'. str_replace('.', '`.`', $data) .'`';
+ }
+
+ return $data;
+ }
+
+/**
+ * Returns a quoted and escaped string of $data for use in an SQL statement.
+ *
+ * @param string $data String to be prepared for use in an SQL statement
+ * @param string $column The column into which this data will be inserted
+ * @return string Quoted and escaped
+ * @todo Add logic that formats/escapes data based on column type
+ */
+ function value($data, $column = null) {
+ $parent=parent::value($data, $column);
+
+ if ($parent != null) {
+ return $parent;
+ }
+
+ if ($data === null) {
+ return 'NULL';
+ }
+
+ // $data = mysql_real_escape_string($data, $this->connection);
+
+ if (!is_numeric($data)) {
+ $return = "'" . $data . "'";
+ } else {
+ $return = $data;
+ }
+
+ return $return;
+ }
+
+/**
+ * Not sure about this one, MySQL needs it but does ODBC? Safer just to leave it
+ * Translates between PHP boolean values and MySQL (faked) boolean values
+ *
+ * @param mixed $data Value to be translated
+ * @return mixed Converted boolean value
+ */
+ function boolean($data) {
+ if ($data === true || $data === false) {
+ if ($data === true) {
+ return 1;
+ }
+
+ return 0;
+ } else {
+ if (intval($data !== 0)) {
+ return true;
+ }
+
+ return false;
+ }
+ }
+
+/**
+ * Begin a transaction
+ *
+ * @param unknown_type $model
+ * @return boolean True on success, false on fail
+ * (i.e. if the database/model does not support transactions).
+ */
+ function begin(&$model) {
+ if (parent::begin($model)) {
+ if (odbc_autocommit($this->connection, false)) {
+ $this->_transactionStarted = true;
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+/**
+ * Commit a transaction
+ *
+ * @param unknown_type $model
+ * @return boolean True on success, false on fail
+ * (i.e. if the database/model does not support transactions,
+ * or a transaction has not started).
+ */
+ function commit(&$model) {
+ if (parent::commit($model)) {
+ if (odbc_commit($this->connection)) {
+ $this->_transactionStarted = false;
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+/**
+ * Rollback a transaction
+ *
+ * @param unknown_type $model
+ * @return boolean True on success, false on fail
+ * (i.e. if the database/model does not support transactions,
+ * or a transaction has not started).
+ */
+ function rollback(&$model) {
+ if (parent::rollback($model)) {
+ $this->_transactionStarted=false;
+ return odbc_rollback($this->connection);
+ }
+
+ return false;
+ }
+
+/**
+ * Returns a formatted error message from previous database operation.
+ *
+ * @return string Error message with error number
+ */
+ function lastError() {
+ if (odbc_error($this->connection)) {
+ return odbc_error($this->connection) . ': ' . odbc_errormsg($this->connection);
+ }
+
+ return null;
+ }
+
+/**
+ * Returns number of affected rows in previous database operation. If no previous operation exists,
+ * this returns false.
+ *
+ * @return int Number of affected rows
+ */
+ function lastAffected() {
+ if ($this->_result) {
+ return null;
+ }
+
+ return null;
+ }
+
+/**
+ * Returns number of rows in previous resultset. If no previous resultset exists,
+ * this returns false.
+ *
+ * @return int Number of rows in resultset
+ */
+ function lastNumRows() {
+ if ($this->_result) {
+ return@odbc_num_rows($this->_result);
+ }
+
+ return null;
+ }
+
+/**
+ * Returns the ID generated from the previous INSERT operation.
+ *
+ * @param unknown_type $source
+ * @return int
+ */
+ function lastInsertId($source = null) {
+ $result=$this->fetchRow('SELECT @@IDENTITY');
+ return $result[0];
+ }
+
+/**
+ * Enter description here...
+ *
+ * @param string $real Real database-layer column type (i.e. "varchar(255)")
+ */
+ function column($real) {
+ if (is_array($real)) {
+ $col=$real['name'];
+
+ if (isset($real['limit'])) {
+ $col .= '(' . $real['limit'] . ')';
+ }
+
+ return $col;
+ }
+
+ return $real;
+ }
+
+/**
+ * Enter description here...
+ *
+ * @param unknown_type $results
+ */
+ function resultSet(&$results) {
+ $this->results=&$results;
+ $this->map=array();
+ $num_fields =odbc_num_fields($results);
+ $index =0;
+ $j =0;
+
+ while ($j < $num_fields) {
+ $column = odbc_fetch_array($results, $j);
+
+ if (!empty($column->table)) {
+ $this->map[$index++] = array($column->table,
+ $column->name);
+ } else {
+ echo array(0,
+ $column->name);
+
+ $this->map[$index++]=array(0,
+ $column->name);
+ }
+
+ $j++;
+ }
+ }
+
+/**
+ * Fetches the next row from the current result set
+ *
+ * @return unknown
+ */
+ function fetchResult() {
+ if ($row = odbc_fetch_row($this->results)) {
+ $resultRow=array();
+ $i=0;
+
+ foreach ($row as $index => $field) {
+ list($table, $column) = $this->map[$index];
+ $resultRow[$table][$column]=$row[$index];
+ $i++;
+ }
+
+ return $resultRow;
+ } else {
+ return false;
+ }
+ }
+}
+?> \ No newline at end of file
diff --git a/site/cake/libs/model/dbo/dbo_pear.php b/site/cake/libs/model/dbo/dbo_pear.php
new file mode 100644
index 0000000..2ca4860
--- /dev/null
+++ b/site/cake/libs/model/dbo/dbo_pear.php
@@ -0,0 +1,241 @@
+<?php
+/* SVN FILE: $Id: dbo_pear.php 6305 2008-01-02 02:33:56Z phpnut $ */
+
+/**
+ * {@link http://pear.php.net/package/DB PEAR::DB} layer for DBO.
+ *
+ * Long description for file
+ *
+ * PHP versions 4 and 5
+ *
+ * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
+ * Copyright 2005-2008, Cake Software Foundation, Inc.
+ * 1785 E. Sahara Avenue, Suite 490-204
+ * Las Vegas, Nevada 89104
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
+ * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
+ * @package cake
+ * @subpackage cake.cake.libs.model.dbo
+ * @since CakePHP(tm) v 0.2.9
+ * @version $Revision: 6305 $
+ * @modifiedby $LastChangedBy: phpnut $
+ * @lastmodified $Date: 2008-01-01 20:33:56 -0600 (Tue, 01 Jan 2008) $
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+
+/**
+ * Create an include path required PEAR libraries.
+ */
+ini_set('include_path', ini_get('include_path') . PATH_SEPARATOR . PEAR);
+vendor ('Pear/DB');
+
+/**
+ * {@link http://pear.php.net/package/DB PEAR::DB} layer for DBO.
+ *
+ * Long description for class
+ *
+ * @package cake
+ * @subpackage cake.cake.libs.model.dbo
+ */
+class DboPear extends DboSource{
+
+/**
+ * PEAR::DB object with which we connect.
+ *
+ * @var DB The connection object.
+ * @access private
+ */
+ var $_pear = null;
+
+/**
+ * Connects to the database using options in the given configuration array.
+ *
+ * @param array $config Configuration array for connecting
+ * @return boolean True if the database could be connected, else false
+ */
+ function connect($config) {
+ $this->config =$config;
+ $dsn =$config['driver'] . '://' . $config['login'] . ':' . $config['password'] . '@'
+ . $config['host'] . '/' . $config['database'];
+ $options=array('debug' => Configure::read() - 1,
+ 'portability' => DB_PORTABILITY_ALL,);
+
+ $this->_pear =&DB::connect($dsn, $options);
+ $this->connected=$this->_pear ? true : false;
+ return !(PEAR::isError($this->_pear));
+ }
+
+/**
+ * Disconnects from database.
+ *
+ * @return boolean True if the database could be disconnected, else false
+ */
+ function disconnect() {
+ die (__('Please implement DBO::disconnect() first.'));
+ }
+
+/**
+ * Executes given SQL statement.
+ *
+ * @param string $sql SQL statement
+ * @return resource Result resource identifier
+ */
+ function execute($sql) {
+ return $this->_pear->query($sql);
+ }
+
+/**
+ * Returns a row from given resultset as an array .
+ *
+ * @return array The fetched row as an array
+ */
+ function fetchRow($sql = null) {
+ if (!empty($sql) && is_string($sql) && strlen($sql) > 5) {
+ if (!$this->execute($sql)) {
+ return null;
+ }
+ }
+ return $this->_result->fetchRow(DB_FETCHMODE_ASSOC);
+ }
+
+/**
+ * Returns an array of tables in the database. If there are no tables, an error is raised and the application exits.
+ * :WARNING: :TODO: POSTGRESQL & MYSQL ONLY! PEAR::DB doesn't support universal table listing.
+ *
+ * @return array Array of tablenames in the database
+ */
+ function tablesList() {
+ $driver=$this->config['driver'];
+ $tables=array();
+
+ if ('postgres' == $driver) {
+ $sql ="SELECT a.relname AS name
+ FROM pg_class a, pg_user b
+ WHERE ( relkind = 'r') and relname !~ '^pg_' AND relname !~ '^sql_'
+ AND relname !~ '^xin[vx][0-9]+' AND b.usesysid = a.relowner
+ AND NOT (EXISTS (SELECT viewname FROM pg_views WHERE viewname=a.relname));";
+
+ $result=$this->all($sql);
+
+ foreach ($result as $item) {
+ $tables[] = $item['name'];
+ }
+ } elseif ('mysql' == $driver) {
+ $result=array();
+ $result=mysql_list_tables($this->config['database']);
+
+ while ($item = mysql_fetch_array($result)) {
+ $tables[] = $item[0];
+ }
+ } else {
+ die (__('Please implement DBO_Pear::tablesList() for your database driver.'));
+ }
+
+ if (!$result) {
+ trigger_error(ERROR_NO_TABLE_LIST, E_USER_ERROR);
+ exit;
+ } else {
+ return $tables;
+ }
+ }
+
+/**
+ * Returns an array of the fields in given table name.
+ *
+ * @param string $tableName Name of database table to inspect
+ * @return array Fields in table. Keys are name and type
+ */
+ function fields($tableName) {
+ $data =$this->_pear->tableInfo($tableName);
+ $fields=false;
+
+ foreach ($data as $item) {
+ $fields[] = array('name' => $item['name'],
+ 'type' => $item['type']);
+ }
+
+ return $fields;
+ }
+
+/**
+ * Returns a quoted and escaped string of $data for use in an SQL statement.
+ *
+ * @param string $data String to be prepared for use in an SQL statement
+ * @return string Quoted and escaped
+ */
+ function prepareValue($data) {
+ return $this->_pear->quoteSmart($data);
+ }
+
+/**
+ * Returns a formatted error message from previous database operation.
+ *
+ * @return string Error message
+ */
+ function lastError() {
+ return PEAR::isError($this->_result) ? $this->_result->getMessage() : null;
+ }
+
+/**
+ * Returns number of affected rows in previous database operation. If no previous operation exists, this returns false.
+ *
+ * @return int Number of affected rows
+ */
+ function lastAffected() {
+ return $this->_pear->affectedRows();
+ }
+
+/**
+ * Returns number of rows in previous resultset. If no previous resultset exists,
+ * this returns false.
+ *
+ * @return int Number of rows in resultset
+ */
+ function lastNumRows() {
+ if (method_exists($this->_result, 'numRows')) {
+ return $this->_result->numRows();
+ } else {
+ return false;
+ }
+ }
+
+/**
+ * Returns the ID generated from the previous INSERT operation.
+ *
+ * @param string $table Name of the database table
+ * @return int
+ */
+ function lastInsertId($table) {
+ return $this->field('id', "SELECT MAX(id) FROM {$table}");
+ }
+
+/**
+ * Returns a limit statement in the correct format for the particular database.
+ *
+ * @param int $limit Limit of results returned
+ * @param int $offset Offset from which to start results
+ * @return string SQL limit/offset statement
+ */
+ function selectLimit($limit, $offset = '0') {
+ return ' ' . $this->_pear->modifyLimitQuery('', $offset, $limit);
+ }
+/**
+ * Inserts multiple values into a join table
+ *
+ * @param string $table
+ * @param string $fields
+ * @param array $values
+ */
+ function insertMulti($table, $fields, $values) {
+ $count = count($values);
+ for ($x = 0; $x < $count; $x++) {
+ $this->query("INSERT INTO {$table} ({$fields}) VALUES {$values[$x]}");
+ }
+ }
+}
+?> \ No newline at end of file
diff --git a/site/cake/libs/model/dbo/dbo_postgres.php b/site/cake/libs/model/dbo/dbo_postgres.php
new file mode 100644
index 0000000..a2eb7bd
--- /dev/null
+++ b/site/cake/libs/model/dbo/dbo_postgres.php
@@ -0,0 +1,595 @@
+<?php
+/* SVN FILE: $Id: dbo_postgres.php 6305 2008-01-02 02:33:56Z phpnut $ */
+
+/**
+ * PostgreSQL layer for DBO.
+ *
+ * Long description for file
+ *
+ * PHP versions 4 and 5
+ *
+ * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
+ * Copyright 2005-2008, Cake Software Foundation, Inc.
+ * 1785 E. Sahara Avenue, Suite 490-204
+ * Las Vegas, Nevada 89104
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
+ * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
+ * @package cake
+ * @subpackage cake.cake.libs.model.dbo
+ * @since CakePHP(tm) v 0.9.1.114
+ * @version $Revision: 6305 $
+ * @modifiedby $LastChangedBy: phpnut $
+ * @lastmodified $Date: 2008-01-01 20:33:56 -0600 (Tue, 01 Jan 2008) $
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+
+/**
+ * PostgreSQL layer for DBO.
+ *
+ * Long description for class
+ *
+ * @package cake
+ * @subpackage cake.cake.libs.model.dbo
+ */
+class DboPostgres extends DboSource {
+
+ var $description = "PostgreSQL DBO Driver";
+
+ var $_baseConfig = array(
+ 'connect' => 'pg_pconnect',
+ 'persistent' => true,
+ 'host' => 'localhost',
+ 'login' => 'root',
+ 'password' => '',
+ 'database' => 'cake',
+ 'schema' => 'public',
+ 'port' => 5432,
+ 'encoding' => ''
+ );
+
+ var $columns = array(
+ 'primary_key' => array('name' => 'serial NOT NULL'),
+ 'string' => array('name' => 'varchar', 'limit' => '255'),
+ 'text' => array('name' => 'text'),
+ 'integer' => array('name' => 'integer', 'formatter' => 'intval'),
+ 'float' => array('name' => 'float', 'formatter' => 'floatval'),
+ 'datetime' => array('name' => 'timestamp', 'format' => 'Y-m-d H:i:s', 'formatter' => 'date'),
+ 'timestamp' => array('name' => 'timestamp', 'format' => 'Y-m-d H:i:s', 'formatter' => 'date'),
+ 'time' => array('name' => 'time', 'format' => 'H:i:s', 'formatter' => 'date'),
+ 'date' => array('name' => 'date', 'format' => 'Y-m-d', 'formatter' => 'date'),
+ 'binary' => array('name' => 'bytea'),
+ 'boolean' => array('name' => 'boolean'),
+ 'number' => array('name' => 'numeric'),
+ 'inet' => array('name' => 'inet')
+ );
+
+ var $startQuote = '"';
+
+ var $endQuote = '"';
+/**
+ * Contains mappings of custom auto-increment sequences, if a table uses a sequence name
+ * other than what is dictated by convention.
+ *
+ * @var array
+ */
+ var $_sequenceMap = array();
+/**
+ * Connects to the database using options in the given configuration array.
+ *
+ * @return True if successfully connected.
+ */
+ function connect() {
+
+ $config = $this->config;
+ $connect = $config['connect'];
+ $this->connection = $connect("host='{$config['host']}' port='{$config['port']}' dbname='{$config['database']}' user='{$config['login']}' password='{$config['password']}'");
+
+ if ($this->connection) {
+ $this->connected = true;
+ $this->_execute("SET search_path TO " . $config['schema']);
+ } else {
+ $this->connected = false;
+ }
+ if (!empty($config['encoding'])) {
+ $this->setEncoding($config['encoding']);
+ }
+
+ return $this->connected;
+ }
+
+/**
+ * Disconnects from database.
+ *
+ * @return boolean True if the database could be disconnected, else false
+ */
+ function disconnect() {
+ @pg_free_result($this->results);
+ $this->connected = !@pg_close($this->connection);
+ return !$this->connected;
+ }
+
+/**
+ * Executes given SQL statement.
+ *
+ * @param string $sql SQL statement
+ * @return resource Result resource identifier
+ */
+ function _execute($sql) {
+ return pg_query($this->connection, $sql);
+ }
+/**
+ * Returns an array of tables in the database. If there are no tables, an error is raised and the application exits.
+ *
+ * @return array Array of tablenames in the database
+ */
+ function listSources() {
+ $cache = parent::listSources();
+
+ if ($cache != null) {
+ return $cache;
+ }
+
+ $schema = $this->config['schema'];
+ $sql = "SELECT table_name as name FROM INFORMATION_SCHEMA.tables WHERE table_schema = '{$schema}';";
+ $result = $this->fetchAll($sql);
+
+ if (!$result) {
+ return array();
+ } else {
+ $tables = array();
+
+ foreach ($result as $item) {
+ $tables[] = $item[0]['name'];
+ }
+
+ parent::listSources($tables);
+ return $tables;
+ }
+ }
+
+/**
+ * Returns an array of the fields in given table name.
+ *
+ * @param string $tableName Name of database table to inspect
+ * @return array Fields in table. Keys are name and type
+ */
+ function &describe(&$model) {
+ if (isset($model->sequence)) {
+ $this->_sequenceMap[$this->fullTableName($model, false)] = $model->sequence;
+ }
+
+ $cache = parent::describe($model);
+ if ($cache != null) {
+ return $cache;
+ }
+
+ $fields = false;
+ $cols = $this->fetchAll("SELECT DISTINCT column_name AS name, data_type AS type, is_nullable AS null, column_default AS default, ordinal_position AS position, character_maximum_length AS char_length, character_octet_length AS oct_length FROM information_schema.columns WHERE table_name =" . $this->value($model->tablePrefix . $model->table) . " ORDER BY position");
+
+ foreach ($cols as $column) {
+ $colKey = array_keys($column);
+
+ if (isset($column[$colKey[0]]) && !isset($column[0])) {
+ $column[0] = $column[$colKey[0]];
+ }
+
+ if (isset($column[0])) {
+ $c = $column[0];
+ if (strpos($c['default'], 'nextval(') === 0) {
+ $c['default'] = null;
+ }
+ if (!empty($c['char_length'])) {
+ $length = intval($c['char_length']);
+ } elseif (!empty($c['oct_length'])) {
+ $length = intval($c['oct_length']);
+ } else {
+ $length = $this->length($c['type']);
+ }
+ $fields[$c['name']] = array(
+ 'type' => $this->column($c['type']),
+ 'null' => ($c['null'] == 'NO' ? false : true),
+ 'default' => $c['default'],
+ 'length' => $length
+ );
+ }
+ }
+ $this->__cacheDescription($model->tablePrefix . $model->table, $fields);
+ return $fields;
+ }
+/**
+ * Returns a quoted and escaped string of $data for use in an SQL statement.
+ *
+ * @param string $data String to be prepared for use in an SQL statement
+ * @param string $column The column into which this data will be inserted
+ * @return string Quoted and escaped
+ * @todo Add logic that formats/escapes data based on column type
+ */
+ function value($data, $column = null) {
+
+ $parent = parent::value($data, $column);
+ if ($parent != null) {
+ return $parent;
+ }
+
+ if ($data === null) {
+ return 'NULL';
+ }
+
+ switch($column) {
+ case 'inet':
+ if (!strlen($data)) {
+ return 'DEFAULT';
+ } else {
+ $data = pg_escape_string($data);
+ }
+ break;
+ case 'integer':
+ if ($data === '') {
+ return 'DEFAULT';
+ } else {
+ $data = pg_escape_string($data);
+ }
+ break;
+ case 'binary':
+ $data = pg_escape_bytea($data);
+
+ break;
+ case 'boolean':
+ default:
+ if ($data === true) {
+ return 'TRUE';
+ } elseif ($data === false) {
+ return 'FALSE';
+ }
+ $data = pg_escape_string($data);
+ break;
+ }
+ return "'" . $data . "'";
+ }
+
+/**
+ * Begin a transaction
+ *
+ * @param unknown_type $model
+ * @return boolean True on success, false on fail
+ * (i.e. if the database/model does not support transactions).
+ */
+ function begin(&$model) {
+ if (parent::begin($model)) {
+ if ($this->execute('BEGIN')) {
+ $this->_transactionStarted = true;
+ return true;
+ }
+ }
+ return false;
+ }
+
+/**
+ * Commit a transaction
+ *
+ * @param unknown_type $model
+ * @return boolean True on success, false on fail
+ * (i.e. if the database/model does not support transactions,
+ * or a transaction has not started).
+ */
+ function commit(&$model) {
+ if (parent::commit($model)) {
+ $this->_transactionStarted = false;
+ return $this->execute('COMMIT');
+ }
+ return false;
+ }
+
+/**
+ * Rollback a transaction
+ *
+ * @param unknown_type $model
+ * @return boolean True on success, false on fail
+ * (i.e. if the database/model does not support transactions,
+ * or a transaction has not started).
+ */
+ function rollback(&$model) {
+ if (parent::rollback($model)) {
+ return $this->execute('ROLLBACK');
+ }
+ return false;
+ }
+
+/**
+ * Returns a formatted error message from previous database operation.
+ *
+ * @return string Error message
+ */
+ function lastError() {
+ $last_error = pg_last_error($this->connection);
+ if ($last_error) {
+ return $last_error;
+ }
+ return null;
+ }
+
+/**
+ * Returns number of affected rows in previous database operation. If no previous operation exists, this returns false.
+ *
+ * @return int Number of affected rows
+ */
+ function lastAffected() {
+ if ($this->_result) {
+ $return = pg_affected_rows($this->_result);
+ return $return;
+ }
+ return false;
+ }
+/**
+ * Returns number of rows in previous resultset. If no previous resultset exists,
+ * this returns false.
+ *
+ * @return int Number of rows in resultset
+ */
+ function lastNumRows() {
+ if ($this->_result) {
+ $return = pg_num_rows($this->_result);
+ return $return;
+ }
+ return false;
+ }
+/**
+ * Returns the ID generated from the previous INSERT operation.
+ *
+ * @param string $source Name of the database table
+ * @param string $field Name of the ID database field. Defaults to "id"
+ * @return int
+ */
+ function lastInsertId($source, $field = 'id') {
+ foreach ($this->__descriptions[$source] as $name => $sourceinfo) {
+ if (strcasecmp($name, $field) == 0) {
+ break;
+ }
+ }
+
+ if (isset($this->_sequenceMap[$source])) {
+ $seq = $this->_sequenceMap[$source];
+ } elseif (preg_match('/^nextval\(\'(\w+)\'/', $sourceinfo['default'], $matches)) {
+ $seq = $matches[1];
+ } else {
+ $seq = "{$source}_{$field}_seq";
+ }
+
+ $res = $this->rawQuery("SELECT last_value AS max FROM \"{$seq}\"");
+ $data = $this->fetchRow($res);
+ return $data[0]['max'];
+ }
+/**
+ * Generates the fields list of an SQL query.
+ *
+ * @param Model $model
+ * @param string $alias Alias tablename
+ * @param mixed $fields
+ * @return array
+ */
+ function fields(&$model, $alias = null, $fields = array(), $quote = true) {
+ if (empty($alias)) {
+ $alias = $model->name;
+ }
+ $fields = parent::fields($model, $alias, $fields, false);
+
+ if (!$quote) {
+ return $fields;
+ }
+ $count = count($fields);
+
+ if ($count >= 1 && $fields[0] != '*' && strpos($fields[0], 'COUNT(*)') === false) {
+ for ($i = 0; $i < $count; $i++) {
+ if (!preg_match('/^.+\\(.*\\)/', $fields[$i]) && !preg_match('/\s+AS\s+/', $fields[$i])) {
+ $prepend = '';
+ if (strpos($fields[$i], 'DISTINCT') !== false) {
+ $prepend = 'DISTINCT ';
+ $fields[$i] = trim(r('DISTINCT', '', $fields[$i]));
+ }
+
+ $dot = strrpos($fields[$i], '.');
+ if ($dot === false) {
+ $fields[$i] = $prepend . $this->name($alias) . '.' . $this->name($fields[$i]) . ' AS ' . $this->name($alias . '__' . $fields[$i]);
+ } else {
+ $build = explode('.', $fields[$i]);
+ $fields[$i] = $prepend . $this->name($build[0]) . '.' . $this->name($build[1]) . ' AS ' . $this->name($build[0] . '__' . $build[1]);
+ }
+ }
+ }
+ }
+ return $fields;
+ }
+/**
+ * Returns a limit statement in the correct format for the particular database.
+ *
+ * @param int $limit Limit of results returned
+ * @param int $offset Offset from which to start results
+ * @return string SQL limit/offset statement
+ */
+ function limit($limit, $offset = null) {
+ if ($limit) {
+ $rt = '';
+ if (!strpos(strtolower($limit), 'limit') || strpos(strtolower($limit), 'limit') === 0) {
+ $rt = ' LIMIT';
+ }
+
+ $rt .= ' ' . $limit;
+ if ($offset) {
+ $rt .= ' OFFSET ' . $offset;
+ }
+
+ return $rt;
+ }
+ return null;
+ }
+/**
+ * Converts database-layer column types to basic types
+ *
+ * @param string $real Real database-layer column type (i.e. "varchar(255)")
+ * @return string Abstract column type (i.e. "string")
+ */
+ function column($real) {
+ if (is_array($real)) {
+ $col = $real['name'];
+ if (isset($real['limit'])) {
+ $col .= '(' . $real['limit'] . ')';
+ }
+ return $col;
+ }
+
+ $col = r(')', '', $real);
+ $limit = null;
+ @list($col, $limit) = explode('(', $col);
+
+ if (in_array($col, array('date', 'time'))) {
+ return $col;
+ }
+ if (strpos($col, 'timestamp') !== false) {
+ return 'datetime';
+ }
+ if ($col == 'inet') {
+ return('inet');
+ }
+ if ($col == 'boolean') {
+ return 'boolean';
+ }
+ if (strpos($col, 'int') !== false && $col != 'interval') {
+ return 'integer';
+ }
+ if (strpos($col, 'char') !== false) {
+ return 'string';
+ }
+ if (strpos($col, 'text') !== false) {
+ return 'text';
+ }
+ if (strpos($col, 'bytea') !== false) {
+ return 'binary';
+ }
+ if (in_array($col, array('float', 'float4', 'float8', 'double', 'double precision', 'decimal', 'real', 'numeric'))) {
+ return 'float';
+ }
+ return 'text';
+ }
+/**
+ * Gets the length of a database-native column description, or null if no length
+ *
+ * @param string $real Real database-layer column type (i.e. "varchar(255)")
+ * @return int An integer representing the length of the column
+ */
+ function length($real) {
+ $col = r(array(')', 'unsigned'), '', $real);
+ $limit = null;
+
+ if (strpos($col, '(') !== false) {
+ list($col, $limit) = explode('(', $col);
+ }
+
+ if ($limit != null) {
+ return intval($limit);
+ }
+ return null;
+ }
+/**
+ * Enter description here...
+ *
+ * @param unknown_type $results
+ */
+ function resultSet(&$results) {
+ $this->results =& $results;
+ $this->map = array();
+ $num_fields = pg_num_fields($results);
+ $index = 0;
+ $j = 0;
+
+ while ($j < $num_fields) {
+ $columnName = pg_field_name($results, $j);
+
+ if (strpos($columnName, '__')) {
+ $parts = explode('__', $columnName);
+ $this->map[$index++] = array($parts[0], $parts[1]);
+ } else {
+ $this->map[$index++] = array(0, $columnName);
+ }
+ $j++;
+ }
+ }
+/**
+ * Fetches the next row from the current result set
+ *
+ * @return unknown
+ */
+ function fetchResult() {
+ if ($row = pg_fetch_row($this->results)) {
+ $resultRow = array();
+ $i = 0;
+
+ foreach ($row as $index => $field) {
+ list($table, $column) = $this->map[$index];
+ $resultRow[$table][$column] = $row[$index];
+ $i++;
+ }
+ return $resultRow;
+ } else {
+ return false;
+ }
+ }
+/**
+ * Translates between PHP boolean values and PostgreSQL boolean values
+ *
+ * @param mixed $data Value to be translated
+ * @param boolean $quote True to quote value, false otherwise
+ * @return mixed Converted boolean value
+ */
+ function boolean($data, $quote = true) {
+ $result = null;
+
+ if ($data === true || $data === false) {
+ $result = $data;
+ } elseif (is_string($data) && !is_numeric($data)) {
+ if (strpos(low($data), 't') !== false) {
+ $result = true;
+ } else {
+ $result = false;
+ }
+ } else {
+ $result = (bool)$data;
+ }
+ return $result;
+ }
+/**
+ * Sets the database encoding
+ *
+ * @param mixed $enc Database encoding
+ * @return boolean True on success, false on failure
+ */
+ function setEncoding($enc) {
+ return pg_set_client_encoding($this->connection, $enc) == 0;
+ }
+/**
+ * Gets the database encoding
+ *
+ * @return string The database encoding
+ */
+ function getEncoding() {
+ return pg_client_encoding($this->connection);
+ }
+/**
+ * Inserts multiple values into a join table
+ *
+ * @param string $table
+ * @param string $fields
+ * @param array $values
+ */
+ function insertMulti($table, $fields, $values) {
+ $count = count($values);
+ for ($x = 0; $x < $count; $x++) {
+ $this->query("INSERT INTO {$table} ({$fields}) VALUES {$values[$x]}");
+ }
+ }
+}
+?> \ No newline at end of file
diff --git a/site/cake/libs/model/dbo/dbo_sqlite.php b/site/cake/libs/model/dbo/dbo_sqlite.php
new file mode 100644
index 0000000..d298750
--- /dev/null
+++ b/site/cake/libs/model/dbo/dbo_sqlite.php
@@ -0,0 +1,409 @@
+<?php
+/* SVN FILE: $Id: dbo_sqlite.php 6305 2008-01-02 02:33:56Z phpnut $ */
+
+/**
+ * SQLite layer for DBO
+ *
+ * Long description for file
+ *
+ * PHP versions 4 and 5
+ *
+ * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
+ * Copyright 2005-2008, Cake Software Foundation, Inc.
+ * 1785 E. Sahara Avenue, Suite 490-204
+ * Las Vegas, Nevada 89104
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
+ * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
+ * @package cake
+ * @subpackage cake.cake.libs.model.dbo
+ * @since CakePHP(tm) v 0.9.0
+ * @version $Revision: 6305 $
+ * @modifiedby $LastChangedBy: phpnut $
+ * @lastmodified $Date: 2008-01-01 20:33:56 -0600 (Tue, 01 Jan 2008) $
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+/**
+ * DBO implementation for the SQLite DBMS.
+ *
+ * Long description for class
+ *
+ * @package cake
+ * @subpackage cake.cake.libs.model.dbo
+ */
+class DboSqlite extends DboSource {
+
+/**
+ * Enter description here...
+ *
+ * @var unknown_type
+ */
+ var $description = "SQLite DBO Driver";
+/**
+ * Enter description here...
+ *
+ * @var unknown_type
+ */
+ var $startQuote = '"';
+/**
+ * Enter description here...
+ *
+ * @var unknown_type
+ */
+ var $endQuote = '"';
+/**
+ * Base configuration settings for SQLite driver
+ *
+ * @var array
+ */
+ var $_baseConfig = array(
+ 'persistent' => true,
+ 'database' => null,
+ 'connect' => 'sqlite_popen'
+ );
+/**
+ * SQLite column definition
+ *
+ * @var array
+ */
+ var $columns = array(
+ 'primary_key' => array('name' => 'integer primary key'),
+ 'string' => array('name' => 'varchar', 'limit' => '255'),
+ 'text' => array('name' => 'text'),
+ 'integer' => array('name' => 'integer', 'limit' => '11', 'formatter' => 'intval'),
+ 'float' => array('name' => 'float', 'formatter' => 'floatval'),
+ 'datetime' => array('name' => 'timestamp', 'format' => 'YmdHis', 'formatter' => 'date'),
+ 'timestamp' => array('name' => 'timestamp', 'format' => 'YmdHis', 'formatter' => 'date'),
+ 'time' => array('name' => 'timestamp', 'format' => 'His', 'formatter' => 'date'),
+ 'date' => array('name' => 'date', 'format' => 'Ymd', 'formatter' => 'date'),
+ 'binary' => array('name' => 'blob'),
+ 'boolean' => array('name' => 'integer', 'limit' => '1')
+ );
+/**
+ * Connects to the database using config['database'] as a filename.
+ *
+ * @param array $config Configuration array for connecting
+ * @return mixed
+ */
+ function connect() {
+ $config = $this->config;
+ $this->connection = $config['connect']($config['database']);
+ $this->connected = is_resource($this->connection);
+ return $this->connected;
+ }
+/**
+ * Disconnects from database.
+ *
+ * @return boolean True if the database could be disconnected, else false
+ */
+ function disconnect() {
+ @sqlite_close($this->connection);
+ $this->connected = false;
+ return $this->connected;
+ }
+/**
+ * Executes given SQL statement.
+ *
+ * @param string $sql SQL statement
+ * @return resource Result resource identifier
+ */
+ function _execute($sql) {
+ return sqlite_query($this->connection, $sql);
+ }
+/**
+ * Returns an array of tables in the database. If there are no tables, an error is raised and the application exits.
+ *
+ * @return array Array of tablenames in the database
+ */
+ function listSources() {
+ $db = $this->config['database'];
+ $this->config['database'] = basename($this->config['database']);
+
+ $cache = parent::listSources();
+ if ($cache != null) {
+ return $cache;
+ }
+
+ $result = $this->fetchAll("SELECT name FROM sqlite_master WHERE type='table' ORDER BY name;");
+
+ if (!$result || empty($result)) {
+ return array();
+ } else {
+ $tables = array();
+ foreach ($result as $table) {
+ $tables[] = $table[0]['name'];
+ }
+ parent::listSources($tables);
+
+ $this->config['database'] = $db;
+ return $tables;
+ }
+ $this->config['database'] = $db;
+ return array();
+ }
+/**
+ * Returns an array of the fields in given table name.
+ *
+ * @param string $tableName Name of database table to inspect
+ * @return array Fields in table. Keys are name and type
+ */
+ function describe(&$model) {
+ $cache = parent::describe($model);
+ if ($cache != null) {
+ return $cache;
+ }
+ $fields = array();
+ $result = $this->fetchAll('PRAGMA table_info(' . $model->tablePrefix . $model->table . ')');
+
+ foreach ($result as $column) {
+ $fields[$column[0]['name']] = array(
+ 'type' => $this->column($column[0]['type']),
+ 'null' => ! $column[0]['notnull'],
+ 'default' => $column[0]['dflt_value']
+ );
+ }
+
+ $this->__cacheDescription($model->tablePrefix . $model->table, $fields);
+ return $fields;
+ }
+/**
+ * Returns a quoted and escaped string of $data for use in an SQL statement.
+ *
+ * @param string $data String to be prepared for use in an SQL statement
+ * @return string Quoted and escaped
+ */
+ function value ($data, $column = null, $safe = false) {
+ $parent = parent::value($data, $column, $safe);
+
+ if ($parent != null) {
+ return $parent;
+ }
+
+ if ($data === null) {
+ return 'NULL';
+ }
+
+ if ($data === '') {
+ return "''";
+ }
+
+ switch ($column) {
+ case 'boolean':
+ $data = $this->boolean((bool)$data);
+ break;
+ default:
+ $data = sqlite_escape_string($data);
+ break;
+ }
+ return "'" . $data . "'";
+ }
+/**
+ * Begin a transaction
+ *
+ * @param unknown_type $model
+ * @return boolean True on success, false on fail
+ * (i.e. if the database/model does not support transactions).
+ */
+ function begin (&$model) {
+ if (parent::begin($model)) {
+ if ($this->execute('BEGIN')) {
+ $this->_transactionStarted = true;
+ return true;
+ }
+ }
+ return false;
+ }
+/**
+ * Commit a transaction
+ *
+ * @param unknown_type $model
+ * @return boolean True on success, false on fail
+ * (i.e. if the database/model does not support transactions,
+ * or a transaction has not started).
+ */
+ function commit (&$model) {
+ if (parent::commit($model)) {
+ $this->_transactionStarted = false;
+ return $this->execute('COMMIT');
+ }
+ return false;
+ }
+/**
+ * Rollback a transaction
+ *
+ * @param unknown_type $model
+ * @return boolean True on success, false on fail
+ * (i.e. if the database/model does not support transactions,
+ * or a transaction has not started).
+ */
+ function rollback (&$model) {
+ if (parent::rollback($model)) {
+ return $this->execute('ROLLBACK');
+ }
+ return false;
+ }
+/**
+ * Returns a formatted error message from previous database operation.
+ *
+ * @return string Error message
+ */
+ function lastError() {
+ $error = sqlite_last_error($this->connection);
+ if ($error) {
+ return $error.': '.sqlite_error_string($error);
+ }
+ return null;
+ }
+/**
+ * Returns number of affected rows in previous database operation. If no previous operation exists, this returns false.
+ *
+ * @return int Number of affected rows
+ */
+ function lastAffected() {
+ if ($this->_result) {
+ return sqlite_changes($this->connection);
+ }
+ return false;
+ }
+/**
+ * Returns number of rows in previous resultset. If no previous resultset exists,
+ * this returns false.
+ *
+ * @return int Number of rows in resultset
+ */
+ function lastNumRows() {
+ if ($this->_result) {
+ sqlite_num_rows($this->_result);
+ }
+ return false;
+ }
+/**
+ * Returns the ID generated from the previous INSERT operation.
+ *
+ * @return int
+ */
+ function lastInsertId() {
+ return sqlite_last_insert_rowid($this->connection);
+ }
+/**
+ * Converts database-layer column types to basic types
+ *
+ * @param string $real Real database-layer column type (i.e. "varchar(255)")
+ * @return string Abstract column type (i.e. "string")
+ */
+ function column($real) {
+ if (is_array($real)) {
+ $col = $real['name'];
+ if (isset($real['limit'])) {
+ $col .= '('.$real['limit'].')';
+ }
+ return $col;
+ }
+
+ $col = low(r(')', '', $real));
+ $limit = null;
+ @list($col, $limit) = explode('(', $col);
+
+ if (in_array($col, array('text', 'integer', 'float', 'boolean', 'timestamp', 'datetime'))) {
+ return $col;
+ }
+ if (strpos($col, 'varchar') !== false) {
+ return 'string';
+ }
+ if (in_array($col, array('blob', 'clob'))) {
+ return 'binary';
+ }
+ if (strpos($col, 'numeric') !== false) {
+ return 'float';
+ }
+
+ return 'text';
+ }
+/**
+ * Enter description here...
+ *
+ * @param unknown_type $results
+ */
+ function resultSet(&$results) {
+ $this->results =& $results;
+ $this->map = array();
+ $num_fields = sqlite_num_fields($results);
+ $index = 0;
+ $j = 0;
+
+ while ($j < $num_fields) {
+ $columnName = str_replace('"', '', sqlite_field_name($results, $j));
+
+ if (strpos($columnName, '.')) {
+ $parts = explode('.', $columnName);
+ $this->map[$index++] = array($parts[0], $parts[1]);
+ } else {
+ $this->map[$index++] = array(0, $columnName);
+ }
+ $j++;
+ }
+ }
+/**
+ * Fetches the next row from the current result set
+ *
+ * @return unknown
+ */
+ function fetchResult() {
+ if ($row = sqlite_fetch_array($this->results, SQLITE_ASSOC)) {
+ $resultRow = array();
+ $i = 0;
+
+ foreach ($row as $index => $field) {
+ if (strpos($index, '.')) {
+ list($table, $column) = explode('.', str_replace('"', '', $index));
+ $resultRow[$table][$column] = $row[$index];
+ } else {
+ $resultRow[0][str_replace('"', '', $index)] = $row[$index];
+ }
+ $i++;
+ }
+ return $resultRow;
+ } else {
+ return false;
+ }
+ }
+/**
+ * Returns a limit statement in the correct format for the particular database.
+ *
+ * @param int $limit Limit of results returned
+ * @param int $offset Offset from which to start results
+ * @return string SQL limit/offset statement
+ */
+ function limit ($limit, $offset = null) {
+ if ($limit) {
+ $rt = '';
+ if (!strpos(strtolower($limit), 'limit') || strpos(strtolower($limit), 'limit') === 0) {
+ $rt = ' LIMIT';
+ }
+ $rt .= ' ' . $limit;
+ if ($offset) {
+ $rt .= ' OFFSET ' . $offset;
+ }
+ return $rt;
+ }
+ return null;
+ }
+/**
+ * Inserts multiple values into a join table
+ *
+ * @param string $table
+ * @param string $fields
+ * @param array $values
+ */
+ function insertMulti($table, $fields, $values) {
+ $count = count($values);
+ for ($x = 0; $x < $count; $x++) {
+ $this->query("INSERT INTO {$table} ({$fields}) VALUES {$values[$x]}");
+ }
+ }
+}
+?> \ No newline at end of file
diff --git a/site/cake/libs/model/model.php b/site/cake/libs/model/model.php
new file mode 100644
index 0000000..12ea100
--- /dev/null
+++ b/site/cake/libs/model/model.php
@@ -0,0 +1,42 @@
+<?php
+/* SVN FILE: $Id: model.php 6305 2008-01-02 02:33:56Z phpnut $ */
+/**
+ * Object-relational mapper.
+ *
+ * DBO-backed object data model, for mapping database tables to Cake objects.
+ *
+ * PHP versions 4 and 5
+ *
+ * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
+ * Copyright 2005-2008, Cake Software Foundation, Inc.
+ * 1785 E. Sahara Avenue, Suite 490-204
+ * Las Vegas, Nevada 89104
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
+ * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
+ * @package cake
+ * @subpackage cake.cake.libs.model
+ * @since CakePHP(tm) v 0.10.0.0
+ * @version $Revision: 6305 $
+ * @modifiedby $LastChangedBy: phpnut $
+ * @lastmodified $Date: 2008-01-01 20:33:56 -0600 (Tue, 01 Jan 2008) $
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+/**
+ * Load the model class based on the version of PHP.
+ *
+ */
+if (phpversion() < 5) {
+ require(LIBS . 'model' . DS . 'model_php4.php');
+
+ if (function_exists("overload")) {
+ overload("Model");
+ }
+} else {
+ require(LIBS . 'model' . DS . 'model_php5.php');
+}
+?> \ No newline at end of file
diff --git a/site/cake/libs/model/model_php4.php b/site/cake/libs/model/model_php4.php
new file mode 100644
index 0000000..8340dab
--- /dev/null
+++ b/site/cake/libs/model/model_php4.php
@@ -0,0 +1,1712 @@
+<?php
+/* SVN FILE: $Id: model_php4.php 6305 2008-01-02 02:33:56Z phpnut $ */
+/**
+ * Object-relational mapper.
+ *
+ * DBO-backed object data model, for mapping database tables to Cake objects.
+ *
+ * PHP versions 4
+ *
+ * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
+ * Copyright 2005-2008, Cake Software Foundation, Inc.
+ * 1785 E. Sahara Avenue, Suite 490-204
+ * Las Vegas, Nevada 89104
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
+ * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
+ * @package cake
+ * @subpackage cake.cake.libs.model
+ * @since CakePHP(tm) v 0.10.0.0
+ * @version $Revision: 6305 $
+ * @modifiedby $LastChangedBy: phpnut $
+ * @lastmodified $Date: 2008-01-01 20:33:56 -0600 (Tue, 01 Jan 2008) $
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+/**
+ * Included libs
+ */
+uses('class_registry', 'validators', 'model' . DS . 'connection_manager', 'set');
+/**
+ * Object-relational mapper.
+ *
+ * DBO-backed object data model.
+ * Automatically selects a database table name based on a pluralized lowercase object class name
+ * (i.e. class 'User' => table 'users'; class 'Man' => table 'men')
+ * The table is required to have at least 'id auto_increment', 'created datetime',
+ * and 'modified datetime' fields.
+ *
+ * @package cake
+ * @subpackage cake.cake.libs.model
+ */
+class Model extends Object{
+/**
+ * The name of the DataSource connection that this Model uses
+ *
+ * @var string
+ * @access public
+ */
+ var $useDbConfig = 'default';
+/**
+ * Custom database table name.
+ *
+ * @var string
+ * @access public
+ */
+ var $useTable = null;
+/**
+ * Custom display field name. Display fields are used by Scaffold, in SELECT boxes' OPTION elements.
+ *
+ * @var string
+ * @access public
+ */
+ var $displayField = null;
+
+/**
+ * Value of the primary key ID of the record that this model is currently pointing to
+ *
+ * @var string
+ * @access public
+ */
+ var $id = false;
+/**
+ * Container for the data that this model gets from persistent storage (the database).
+ *
+ * @var array
+ * @access public
+ */
+ var $data = array();
+/**
+ * Table name for this Model.
+ *
+ * @var string
+ * @access public
+ */
+ var $table = false;
+/**
+ * The name of the ID field for this Model.
+ *
+ * @var string
+ * @access public
+ */
+ var $primaryKey = null;
+/**
+ * Table metadata
+ *
+ * @var array
+ * @access protected
+ */
+ var $_tableInfo = null;
+/**
+ * List of validation rules. Append entries for validation as ('field_name' => '/^perl_compat_regexp$/')
+ * that have to match with preg_match(). Use these rules with Model::validate()
+ *
+ * @var array
+ * @access public
+ */
+ var $validate = array();
+/**
+ * Errors in validation
+ * @var array
+ * @access public
+ */
+ var $validationErrors = array();
+/**
+ * Database table prefix for tables in model.
+ *
+ * @var string
+ * @access public
+ */
+ var $tablePrefix = null;
+/**
+ * Name of the model.
+ *
+ * @var string
+ * @access public
+ */
+ var $name = null;
+/**
+ * Name of the current model.
+ *
+ * @var string
+ * @access public
+ */
+ var $currentModel = null;
+/**
+ * List of table names included in the Model description. Used for associations.
+ *
+ * @var array
+ * @access public
+ */
+ var $tableToModel = array();
+/**
+ * List of Model names by used tables. Used for associations.
+ *
+ * @var array
+ * @access public
+ */
+ var $modelToTable = array();
+/**
+ * List of Foreign Key names to used tables. Used for associations.
+ *
+ * @var array
+ * @access public
+ */
+ var $keyToTable = array();
+/**
+ * Alias name for model.
+ *
+ * @var array
+ * @access public
+ */
+ var $alias = null;
+/**
+ * Whether or not transactions for this model should be logged
+ *
+ * @var boolean
+ * @access public
+ */
+ var $logTransactions = false;
+/**
+ * Whether or not to enable transactions for this model (i.e. BEGIN/COMMIT/ROLLBACK)
+ *
+ * @var boolean
+ * @access public
+ */
+ var $transactional = false;
+/**
+ * Whether or not to cache queries for this model. This enables in-memory
+ * caching only, the results are not stored beyond this execution.
+ *
+ * @var boolean
+ * @access public
+ */
+ var $cacheQueries = true;
+/**
+ * belongsTo association
+ *
+ * @var array
+ * @access public
+ */
+ var $belongsTo = array();
+/**
+ * hasOne association
+ *
+ * @var array
+ * @access public
+ */
+ var $hasOne = array();
+/**
+ * hasMany association
+ *
+ * @var array
+ * @access public
+ */
+ var $hasMany = array();
+/**
+ * hasAndBelongsToMany association
+ *
+ * @var array
+ * @access public
+ */
+ var $hasAndBelongsToMany = array();
+/**
+ * Depth of recursive association
+ *
+ * @var int
+ * @access public
+ */
+ var $recursive = 1;
+/**
+ * Whitelist of fields allowed to be saved
+ *
+ * @var array
+ */
+ var $whitelist = array();
+/**
+ * Enter description here...
+ *
+ * @var boolean
+ */
+ var $cacheSources = true;
+/**
+ * Default association keys
+ *
+ * @var array
+ * @access private
+ */
+ var $__associationKeys = array('belongsTo' => array('className', 'foreignKey', 'conditions', 'fields', 'order', 'counterCache'),
+ 'hasOne' => array('className', 'foreignKey','conditions', 'fields','order', 'dependent'),
+ 'hasMany' => array('className', 'foreignKey', 'conditions', 'fields', 'order', 'limit', 'offset', 'dependent', 'exclusive', 'finderQuery', 'counterQuery'),
+ 'hasAndBelongsToMany' => array('className', 'joinTable', 'foreignKey', 'associationForeignKey', 'conditions', 'fields', 'order', 'limit', 'offset', 'unique', 'finderQuery', 'deleteQuery', 'insertQuery'));
+/**
+ * Holds provided/generated association key names and other data for all associations
+ *
+ * @var array
+ * @access private
+ */
+ var $__associations = array('belongsTo', 'hasOne', 'hasMany', 'hasAndBelongsToMany');
+/**
+ * The last inserted ID of the data that this model created
+ *
+ * @var int
+ * @access private
+ */
+ var $__insertID = null;
+/**
+ * The number of records returned by the last query
+ *
+ * @var int
+ * @access private
+ */
+ var $__numRows = null;
+/**
+ * The number of records affected by the last query
+ *
+ * @var int
+ * @access private
+ */
+ var $__affectedRows = null;
+/**
+ * Holds model associations temporarily to allow for dynamic (un)binding
+ *
+ * @var array
+ * @access private
+ */
+ var $__backAssociation = array();
+/**
+ * Constructor. Binds the Model's database table to the object.
+ *
+ * @param integer $id
+ * @param string $table Name of database table to use.
+ * @param DataSource $ds DataSource connection object.
+ */
+ function __construct($id = false, $table = null, $ds = null) {
+ parent::__construct();
+
+ if (is_array($id) && isset($id['name'])) {
+ $options = array_merge(array('id' => false, 'table' => null, 'ds' => null, 'alias' => null), $id);
+ list($id, $table, $ds) = array($options['id'], $options['table'], $options['ds']);
+ $this->name = $options['name'];
+ }
+
+ if ($this->name === null) {
+ $this->name = get_class($this);
+ }
+
+ if ($this->primaryKey === null) {
+ $this->primaryKey = 'id';
+ }
+
+ if (isset($options['alias']) || !empty($options['alias'])) {
+ $this->alias = $options['alias'];
+ unset($options);
+ } else {
+ $this->alias = $this->name;
+ }
+ ClassRegistry::addObject($this->alias, $this);
+
+ $this->id = $id;
+ unset($id);
+
+ if ($table === false) {
+ $this->useTable = false;
+ } elseif ($table) {
+ $this->useTable = $table;
+ }
+
+ if ($this->useTable !== false) {
+ $this->setDataSource($ds);
+
+ if ($this->useTable === null) {
+ $this->useTable = Inflector::tableize($this->name);
+ }
+
+ if (in_array('settableprefix', get_class_methods($this))) {
+ $this->setTablePrefix();
+ }
+
+ $this->setSource($this->useTable);
+ $this->__createLinks();
+
+ if ($this->displayField == null) {
+ if ($this->hasField('title')) {
+ $this->displayField = 'title';
+ }
+
+ if ($this->hasField('name')) {
+ $this->displayField = 'name';
+ }
+
+ if ($this->displayField == null) {
+ $this->displayField = $this->primaryKey;
+ }
+ }
+ }
+ }
+
+/**
+ * PHP4 Only
+ *
+ * Handles custom method calls, like findBy<field> for DB models,
+ * and custom RPC calls for remote data sources
+ *
+ * @param unknown_type $method
+ * @param unknown_type $params
+ * @param unknown_type $return
+ * @return unknown
+ * @access protected
+ */
+ function __call($method, $params, &$return) {
+ $db =& ConnectionManager::getDataSource($this->useDbConfig);
+ $return = $db->query($method, $params, $this);
+ if (isset($this->__backAssociation)) {
+ $this->__resetAssociations();
+ }
+ return true;
+ }
+/**
+ * Bind model associations on the fly.
+ *
+ * @param array $params
+ * @return true
+ * @access public
+ */
+ function bindModel($params) {
+ foreach ($params as $assoc => $model) {
+ $this->__backAssociation[$assoc] = $this->{$assoc};
+
+ foreach ($model as $key => $value) {
+ $assocName = $key;
+
+ if (is_numeric($key)) {
+ $assocName = $value;
+ $value = array();
+ }
+ $modelName = $assocName;
+ $this->{$assoc}[$assocName] = $value;
+ }
+ }
+ $this->__createLinks();
+ return true;
+ }
+/**
+ * Turn off associations on the fly.
+ *
+ * @param array $params
+ * @return true
+ * @access public
+ */
+ function unbindModel($params) {
+ foreach ($params as $assoc => $models) {
+ $this->__backAssociation[$assoc] = $this->{$assoc};
+
+ foreach ($models as $model) {
+ $this->__backAssociation = array_merge($this->__backAssociation, $this->{$assoc});
+ unset ($this->{$assoc}[$model]);
+ }
+ }
+ return true;
+ }
+/**
+ * Private helper method to create a set of associations.
+ *
+ * @access private
+ */
+ function __createLinks() {
+
+ foreach ($this->__associations as $type) {
+ if (!is_array($this->{$type})) {
+ $this->{$type} = explode(',', $this->{$type});
+
+ foreach ($this->{$type} as $i => $className) {
+ $className = trim($className);
+ unset ($this->{$type}[$i]);
+ $this->{$type}[$className] = array();
+ }
+ }
+
+ foreach ($this->{$type} as $assoc => $value) {
+ if (is_numeric($assoc)) {
+ unset ($this->{$type}[$assoc]);
+ $assoc = $value;
+ $value = array();
+ $this->{$type}[$assoc] = $value;
+ }
+
+ $className = $assoc;
+
+ if (isset($value['className']) && !empty($value['className'])) {
+ $className = $value['className'];
+ }
+ $this->__constructLinkedModel($assoc, $className);
+ }
+ }
+
+ foreach ($this->__associations as $type) {
+ $this->__generateAssociation($type);
+ }
+ }
+
+/**
+ * Private helper method to create associated models of given class.
+ * @param string $assoc
+ * @param string $className Class name
+ * @param string $type Type of assocation
+ * @access private
+ */
+ function __constructLinkedModel($assoc, $className) {
+ if(empty($className)) {
+ $className = $assoc;
+ }
+
+ if (!class_exists($className)) {
+ loadModel($className);
+ }
+ $colKey = Inflector::underscore($className);
+ $model = array('name' => $className, 'alias' => $assoc);
+
+ if (ClassRegistry::isKeySet($colKey)) {
+ $this->{$assoc} =& ClassRegistry::getObject($colKey);
+ $this->{$className} =& $this->{$assoc};
+ } else {
+ $this->{$assoc} =& new $className($model);
+ $this->{$className} =& $this->{$assoc};
+ }
+ $this->tableToModel[$this->{$assoc}->table] = $className;
+ $this->modelToTable[$assoc] = $this->{$assoc}->table;
+ }
+/**
+ * Build array-based association from string.
+ *
+ * @param string $type "Belongs", "One", "Many", "ManyTo"
+ * @access private
+ */
+ function __generateAssociation($type) {
+ foreach ($this->{$type}as $assocKey => $assocData) {
+ $class = $assocKey;
+
+ foreach ($this->__associationKeys[$type] as $key) {
+ if (!isset($this->{$type}[$assocKey][$key]) || $this->{$type}[$assocKey][$key] == null) {
+ $data = '';
+
+ switch($key) {
+ case 'fields':
+ $data = '';
+ break;
+
+ case 'foreignKey':
+ $data = Inflector::singularize($this->table) . '_id';
+
+ if ($type == 'belongsTo') {
+ $data = Inflector::singularize($this->{$class}->table) . '_id';
+ }
+ break;
+
+ case 'associationForeignKey':
+ $data = Inflector::singularize($this->{$class}->table) . '_id';
+ break;
+
+ case 'joinTable':
+ $tables = array($this->table, $this->{$class}->table);
+ sort ($tables);
+ $data = $tables[0] . '_' . $tables[1];
+ break;
+
+ case 'className':
+ $data = $class;
+ break;
+ }
+
+ $this->{$type}[$assocKey][$key] = $data;
+ }
+
+ if ($key == 'foreignKey' && !isset($this->keyToTable[$this->{$type}[$assocKey][$key]])) {
+ $this->keyToTable[$this->{$type}[$assocKey][$key]][0] = $this->{$class}->table;
+ $this->keyToTable[$this->{$type}[$assocKey][$key]][1] = $this->{$class}->alias;
+ }
+ }
+ }
+ }
+/**
+ * Sets a custom table for your controller class. Used by your controller to select a database table.
+ *
+ * @param string $tableName Name of the custom table
+ * @access public
+ */
+ function setSource($tableName) {
+ $this->setDataSource($this->useDbConfig);
+ $db =& ConnectionManager::getDataSource($this->useDbConfig);
+ $db->cacheSources = $this->cacheSources;
+
+ if ($db->isInterfaceSupported('listSources')) {
+ $sources = $db->listSources();
+ if (is_array($sources) && !in_array(low($this->tablePrefix . $tableName), array_map('low', $sources))) {
+ return $this->cakeError('missingTable', array(array(
+ 'className' => $this->alias,
+ 'table' => $this->tablePrefix . $tableName)));
+
+ }
+ $this->_tableInfo = null;
+ }
+ $this->table = $this->useTable = $tableName;
+ $this->tableToModel[$this->table] = $this->alias;
+ $this->loadInfo();
+ }
+/**
+ * This function does two things: 1) it scans the array $one for the primary key,
+ * and if that's found, it sets the current id to the value of $one[id].
+ * For all other keys than 'id' the keys and values of $one are copied to the 'data' property of this object.
+ * 2) Returns an array with all of $one's keys and values.
+ * (Alternative indata: two strings, which are mangled to
+ * a one-item, two-dimensional array using $one for a key and $two as its value.)
+ *
+ * @param mixed $one Array or string of data
+ * @param string $two Value string for the alternative indata method
+ * @return array
+ * @access public
+ */
+ function set($one, $two = null) {
+ if (is_array($one)) {
+ if (countdim($one) == 1) {
+ $data = array($this->alias => $one);
+ } else {
+ $data = $one;
+ }
+ } else {
+ $data = array($this->alias => array($one => $two));
+ }
+
+ foreach ($data as $n => $v) {
+ if (is_array($v)) {
+
+ foreach ($v as $x => $y) {
+ if (empty($this->whitelist) || (in_array($x, $this->whitelist) || $n !== $this->alias)) {
+ if (isset($this->validationErrors[$x])) {
+ unset ($this->validationErrors[$x]);
+ }
+
+ if ($n == $this->name || is_array($y)) {
+ if ($x === $this->primaryKey) {
+ $this->id = $y;
+ }
+ $this->data[$n][$x] = $y;
+ }
+ }
+ }
+ }
+ }
+ return $data;
+ }
+/**
+ * Returns an array of table metadata (column names and types) from the database.
+ *
+ * @return array Array of table metadata
+ * @access public
+ */
+ function loadInfo() {
+ $db =& ConnectionManager::getDataSource($this->useDbConfig);
+ $db->cacheSources = $this->cacheSources;
+
+ if (!is_object($this->_tableInfo) && $db->isInterfaceSupported('describe') && $this->useTable !== false) {
+ $info = new Set($db->describe($this));
+
+ foreach($info->value as $field => $value) {
+ $fields[] = am(array('name'=> $field), $value);
+ }
+ unset($info);
+ $this->_tableInfo = new Set($fields);
+ } elseif ($this->useTable === false) {
+ $this->_tableInfo = new Set();
+ }
+ return $this->_tableInfo;
+ }
+/**
+ * Returns an associative array of field names and column types.
+ *
+ * @return array
+ * @access public
+ */
+ function getColumnTypes() {
+ $columns = $this->loadInfo();
+ $columns = $columns->value;
+ $db =& ConnectionManager::getDataSource($this->useDbConfig);
+ $cols = array();
+
+ foreach ($columns as $col) {
+ $cols[$col['name']] = $col['type'];
+ }
+ return $cols;
+ }
+/**
+ * Returns the column type of a column in the model
+ *
+ * @param string $column The name of the model column
+ * @return string
+ * @access public
+ */
+ function getColumnType($column) {
+ $columns = $this->loadInfo();
+ $columns = $columns->value;
+ $cols = array();
+
+ foreach ($columns as $col) {
+ if ($col['name'] == $column) {
+ return $col['type'];
+ }
+ }
+ return null;
+ }
+/**
+ * Returns true if this Model has given field in its database table.
+ *
+ * @param string $name Name of field to look for
+ * @return boolean
+ * @access public
+ */
+ function hasField($name) {
+ if (is_array($name)) {
+ foreach ($name as $n) {
+ if ($this->hasField($n)) {
+ return $n;
+ }
+ }
+ return false;
+ }
+
+ if (empty($this->_tableInfo)) {
+ $this->loadInfo();
+ }
+
+ if ($this->_tableInfo != null) {
+ return in_array($name, $this->_tableInfo->extract('{n}.name'));
+ }
+ return false;
+ }
+/**
+ * Initializes the model for writing a new record.
+ *
+ * @return boolean True
+ * @access public
+ */
+ function create() {
+ $this->id = false;
+ unset ($this->data);
+ $this->data = $this->validationErrors = array();
+ return true;
+ }
+/**
+ * @deprecated
+ */
+ function setId($id) {
+ $this->id = $id;
+ }
+/**
+ * Use query() instead.
+ * @deprecated
+ */
+ function findBySql($sql) {
+ return $this->query($sql);
+ }
+/**
+ * Returns a list of fields from the database
+ *
+ * @param mixed $id The ID of the record to read
+ * @param mixed $fields String of single fieldname, or an array of fieldnames.
+ * @return array Array of database fields
+ * @access public
+ */
+ function read($fields = null, $id = null) {
+ $this->validationErrors = array();
+
+ if ($id != null) {
+ $this->id = $id;
+ }
+
+ $id = $this->id;
+
+ if (is_array($this->id)) {
+ $id = $this->id[0];
+ }
+
+ if ($this->id !== null && $this->id !== false) {
+ $db =& ConnectionManager::getDataSource($this->useDbConfig);
+ $field = $db->name($this->alias) . '.' . $db->name($this->primaryKey);
+ return $this->find($field . ' = ' . $db->value($id, $this->getColumnType($this->primaryKey)), $fields);
+ } else {
+ return false;
+ }
+ }
+/**
+ * Returns contents of a field in a query matching given conditions.
+ *
+ * @param string $name Name of field to get
+ * @param array $conditions SQL conditions (defaults to NULL)
+ * @param string $order SQL ORDER BY fragment
+ * @return field contents
+ * @access public
+ */
+ function field($name, $conditions = null, $order = null) {
+ if ($conditions === null && $this->id !== false) {
+ $conditions = array($this->alias . '.' . $this->primaryKey => $this->id);
+ }
+
+ if ($data = $this->find($conditions, $name, $order, 0)) {
+
+ if (strpos($name, '.') === false) {
+ if (isset($data[$this->alias][$name])) {
+ return $data[$this->alias][$name];
+ } else {
+ return false;
+ }
+ } else {
+ $name = explode('.', $name);
+
+ if (isset($data[$name[0]][$name[1]])) {
+ return $data[$name[0]][$name[1]];
+ } else {
+ return false;
+ }
+ }
+ } else {
+ return false;
+ }
+ }
+/**
+ * Saves a single field to the database.
+ *
+ * @param string $name Name of the table field
+ * @param mixed $value Value of the field
+ * @param boolean $validate Whether or not this model should validate before saving (defaults to false)
+ * @return boolean True on success save
+ * @access public
+ */
+ function saveField($name, $value, $validate = false) {
+ return $this->save(array($this->alias => array($name => $value)), $validate);
+ }
+/**
+ * Saves model data to the database.
+ * By default, validation occurs before save.
+ *
+ * @param array $data Data to save.
+ * @param boolean $validate If set, validation will be done before the save
+ * @param array $fieldList List of fields to allow to be written
+ * @return boolean success
+ * @access public
+ */
+ function save($data = null, $validate = true, $fieldList = array()) {
+ $db =& ConnectionManager::getDataSource($this->useDbConfig);
+ $_whitelist = $this->whitelist;
+
+ if (!empty($fieldList)) {
+ $this->whitelist = $fieldList;
+ } elseif ($fieldList === null) {
+ $this->whitelist = array();
+ }
+
+ if ($data) {
+ if (countdim($data) == 1) {
+ $this->set(array($this->alias => $data));
+ } else {
+ $this->set($data);
+ }
+ }
+
+ if ($validate && !$this->validates()) {
+ $this->whitelist = $_whitelist;
+ return false;
+ }
+
+ if (!$this->beforeSave()) {
+ $this->whitelist = $_whitelist;
+ return false;
+ }
+ $fields = $values = array();
+
+ if (count($this->data) > 1) {
+ $weHaveMulti = true;
+ $joined = false;
+ } else {
+ $weHaveMulti = false;
+ }
+
+ foreach ($this->data as $n => $v) {
+ if (isset($weHaveMulti) && isset($v[$n]) && in_array($n, array_keys($this->hasAndBelongsToMany))) {
+ $joined[] = $v;
+ } else {
+ if ($n === $this->alias) {
+ foreach (array('created', 'updated', 'modified') as $field) {
+ if (array_key_exists($field, $v) && (empty($v[$field]) || $v[$field] === null)) {
+ unset($v[$field]);
+ }
+ }
+
+ foreach ($v as $x => $y) {
+ if ($this->hasField($x)) {
+ $fields[] = $x;
+ $values[] = $y;
+ }
+ }
+ }
+ }
+ }
+ $exists = $this->exists();
+
+ if (!$exists && $this->hasField('created') && !in_array('created', $fields)) {
+ $fields[] = 'created';
+ $values[] = date('Y-m-d H:i:s');
+ }
+
+ if ($this->hasField('modified') && !in_array('modified', $fields)) {
+ $fields[] = 'modified';
+ $values[] = date('Y-m-d H:i:s');
+ }
+
+ if ($this->hasField('updated') && !in_array('updated', $fields)) {
+ $fields[] = 'updated';
+ $values[] = date('Y-m-d H:i:s');
+ }
+
+ if (!$exists) {
+ $this->id = false;
+ }
+ $this->whitelist = $_whitelist;
+
+ if (count($fields)) {
+ if (!empty($this->id)) {
+ if ($db->update($this, $fields, $values)) {
+ if (!empty($joined)) {
+ $this->__saveMulti($joined, $this->id);
+ }
+
+ $this->afterSave();
+ $this->data = false;
+ $this->_clearCache();
+ return true;
+ } else {
+ return false;
+ }
+ } else {
+ if ($db->create($this, $fields, $values)) {
+ if (!empty($joined)) {
+ $this->__saveMulti($joined, $this->id);
+ }
+
+ $this->afterSave();
+ $this->data = false;
+ $this->_clearCache();
+ $this->validationErrors = array();
+ return true;
+ } else {
+ return false;
+ }
+ }
+ } else {
+ return false;
+ }
+ }
+/**
+ * Saves model hasAndBelongsToMany data to the database.
+ *
+ * @param array $joined Data to save.
+ * @param string $id
+ * @return void
+ * @access private
+ */
+ function __saveMulti($joined, $id) {
+ $db =& ConnectionManager::getDataSource($this->useDbConfig);
+ foreach ($joined as $x => $y) {
+ foreach ($y as $assoc => $value) {
+ if (isset($this->hasAndBelongsToMany[$assoc])) {
+ $joinTable[$assoc] = $this->hasAndBelongsToMany[$assoc]['joinTable'];
+ $mainKey[$assoc] = $this->hasAndBelongsToMany[$assoc]['foreignKey'];
+ $keys[] = $this->hasAndBelongsToMany[$assoc]['foreignKey'];
+ $keys[] = $this->hasAndBelongsToMany[$assoc]['associationForeignKey'];
+ $fields[$assoc] = join(',', $keys);
+ unset($keys);
+
+ foreach ($value as $update) {
+ if (!empty($update)) {
+ $values[] = $db->value($id, $this->getColumnType($this->primaryKey));
+ $values[] = $db->value($update);
+ $values = join(',', $values);
+ $newValues[] = "({$values})";
+ unset ($values);
+ }
+ }
+
+ if (!empty($newValues)) {
+ $newValue[$assoc] = $newValues;
+ unset($newValues);
+ } else {
+ $newValue[$assoc] = array();
+ }
+ }
+ }
+ }
+
+ if (isset($joinTable)) {
+ $total = count($joinTable);
+
+ if (is_array($newValue)) {
+ foreach ($newValue as $loopAssoc => $val) {
+ $db =& ConnectionManager::getDataSource($this->useDbConfig);
+ $table = $db->name($db->fullTableName($joinTable[$loopAssoc]));
+ $db->query("DELETE FROM {$table} WHERE {$mainKey[$loopAssoc]} = '{$id}'");
+
+ if (!empty($newValue[$loopAssoc])) {
+ $secondCount = count($newValue[$loopAssoc]);
+ for ($x = 0; $x < $secondCount; $x++) {
+ $db->query("INSERT INTO {$table} ({$fields[$loopAssoc]}) VALUES {$newValue[$loopAssoc][$x]}");
+ }
+ }
+ }
+ }
+ }
+ }
+/**
+ * Synonym for del().
+ *
+ * @param mixed $id
+ * @see function del
+ * @return boolean True on success
+ * @access public
+ */
+ function remove($id = null, $cascade = true) {
+ return $this->del($id, $cascade);
+ }
+/**
+ * Removes record for given id. If no id is given, the current id is used. Returns true on success.
+ *
+ * @param mixed $id Id of record to delete
+ * @return boolean True on success
+ * @access public
+ */
+ function del($id = null, $cascade = true) {
+ if ($id) {
+ $this->id = $id;
+ }
+ $id = $this->id;
+
+ if ($this->exists() && $this->beforeDelete()) {
+ $db =& ConnectionManager::getDataSource($this->useDbConfig);
+
+ $this->_deleteMulti($id);
+ $this->_deleteHasMany($id, $cascade);
+ $this->_deleteHasOne($id, $cascade);
+ $this->id = $id;
+
+ if ($db->delete($this)) {
+ $this->afterDelete();
+ $this->_clearCache();
+ $this->id = false;
+ return true;
+ }
+ }
+
+ return false;
+ }
+/**
+ * Alias for del()
+ *
+ * @param mixed $id Id of record to delete
+ * @return boolean True on success
+ * @access public
+ */
+ function delete($id = null, $cascade = true) {
+ return $this->del($id, $cascade);
+ }
+/**
+ * Cascades model deletes to hasMany relationships.
+ *
+ * @param string $id
+ * @return null
+ * @access protected
+ */
+ function _deleteHasMany($id, $cascade) {
+ if (!empty($this->__backAssociation)) {
+ $savedAssociatons = $this->__backAssociation;
+ $this->__backAssociation = array();
+ }
+ foreach ($this->hasMany as $assoc => $data) {
+ if ($data['dependent'] === true && $cascade === true) {
+ $model =& $this->{$data['className']};
+ $field = $model->escapeField($data['foreignKey']);
+ $model->recursive = 0;
+ $records = $model->findAll("$field = '$id'", $model->primaryKey, null, null);
+
+ if ($records != false) {
+ foreach ($records as $record) {
+ $model->del($record[$data['className']][$model->primaryKey]);
+ }
+ }
+ }
+ }
+ if (isset($savedAssociatons)) {
+ $this->__backAssociation = $savedAssociatons;
+ }
+ }
+/**
+ * Cascades model deletes to hasOne relationships.
+ *
+ * @param string $id
+ * @return null
+ * @access protected
+ */
+ function _deleteHasOne($id, $cascade) {
+ if (!empty($this->__backAssociation)) {
+ $savedAssociatons = $this->__backAssociation;
+ $this->__backAssociation = array();
+ }
+ foreach ($this->hasOne as $assoc => $data) {
+ if ($data['dependent'] === true && $cascade === true) {
+ $model =& $this->{$data['className']};
+ $field = $model->escapeField($data['foreignKey']);
+ $model->recursive = 0;
+ $records = $model->findAll("$field = '$id'", $model->primaryKey, null, null);
+
+ if ($records != false) {
+ foreach ($records as $record) {
+ $model->del($record[$data['className']][$model->primaryKey]);
+ }
+ }
+ }
+ }
+ if (isset($savedAssociatons)) {
+ $this->__backAssociation = $savedAssociatons;
+ }
+ }
+/**
+ * Cascades model deletes to HABTM join keys.
+ *
+ * @param string $id
+ * @return null
+ * @access protected
+ */
+ function _deleteMulti($id) {
+ $db =& ConnectionManager::getDataSource($this->useDbConfig);
+ foreach ($this->hasAndBelongsToMany as $assoc => $data) {
+ $db->execute("DELETE FROM " . $db->name($db->fullTableName($data['joinTable'])) . " WHERE " . $db->name($data['foreignKey']) . " = '{$id}'");
+ }
+ }
+/**
+ * Returns true if a record with set id exists.
+ *
+ * @return boolean True if such a record exists
+ * @access public
+ */
+ function exists() {
+ if ($this->id) {
+ $id = $this->id;
+
+ if (is_array($id)) {
+ $id = $id[0];
+ }
+
+ $db =& ConnectionManager::getDataSource($this->useDbConfig);
+ return $db->hasAny($this, array($this->primaryKey => $id));
+ }
+ return false;
+ }
+/**
+ * Returns true if a record that meets given conditions exists
+ *
+ * @param array $conditions SQL conditions array
+ * @return boolean True if such a record exists
+ * @access public
+ */
+ function hasAny($conditions = null) {
+ return ($this->findCount($conditions) != false);
+ }
+/**
+ * Return a single row as a resultset array.
+ * By using the $recursive parameter, the call can access further "levels of association" than
+ * the ones this model is directly associated to.
+ *
+ * @param array $conditions SQL conditions array
+ * @param mixed $fields Either a single string of a field name, or an array of field names
+ * @param string $order SQL ORDER BY conditions (e.g. "price DESC" or "name ASC")
+ * @param int $recursive The number of levels deep to fetch associated records
+ * @return array Array of records
+ * @access public
+ */
+ function find($conditions = null, $fields = null, $order = null, $recursive = null) {
+ $data = $this->findAll($conditions, $fields, $order, 1, null, $recursive);
+
+ if (empty($data[0])) {
+ return false;
+ }
+
+ return $data[0];
+ }
+/**
+ * Returns a resultset array with specified fields from database matching given conditions.
+ * By using the $recursive parameter, the call can access further "levels of association" than
+ * the ones this model is directly associated to.
+ *
+ * @param mixed $conditions SQL conditions as a string or as an array('field' =>'value',...)
+ * @param mixed $fields Either a single string of a field name, or an array of field names
+ * @param string $order SQL ORDER BY conditions (e.g. "price DESC" or "name ASC")
+ * @param int $limit SQL LIMIT clause, for calculating items per page.
+ * @param int $page Page number, for accessing paged data
+ * @param int $recursive The number of levels deep to fetch associated records
+ * @return array Array of records
+ * @access public
+ */
+ function findAll($conditions = null, $fields = null, $order = null, $limit = null, $page = 1, $recursive = null) {
+
+ $db =& ConnectionManager::getDataSource($this->useDbConfig);
+ $this->id = $this->getID();
+ $offset = null;
+
+ if ($page > 1 && $limit != null) {
+ $offset = ($page - 1) * $limit;
+ }
+
+ if ($order == null) {
+ $order = array();
+ } else {
+ $order = array($order);
+ }
+
+ $queryData = array('conditions' => $conditions,
+ 'fields' => $fields,
+ 'joins' => array(),
+ 'limit' => $limit,
+ 'offset' => $offset,
+ 'order' => $order
+ );
+
+ $ret = $this->beforeFind($queryData);
+ if (is_array($ret)) {
+ $queryData = $ret;
+ } elseif ($ret === false) {
+ return null;
+ }
+
+ $return = $this->afterFind($db->read($this, $queryData, $recursive));
+
+ if (!empty($this->__backAssociation)) {
+ $this->__resetAssociations();
+ }
+
+ return $return;
+ }
+/**
+ * Method is called only when bindTo<ModelName>() is used.
+ * This resets the association arrays for the model back
+ * to the original as set in the model.
+ *
+ * @return boolean
+ * @access private
+ */
+ function __resetAssociations() {
+ foreach ($this->__associations as $type) {
+ if (isset($this->__backAssociation[$type])) {
+ $this->{$type} = $this->__backAssociation[$type];
+ }
+ }
+
+ $this->__backAssociation = array();
+ return true;
+ }
+/**
+ * Runs a direct query against the bound DataSource, and returns the result.
+ *
+ * @param string $data Query data
+ * @return array
+ * @access public
+ */
+ function execute($data) {
+ $db =& ConnectionManager::getDataSource($this->useDbConfig);
+ $data = $db->fetchAll($data, $this->cacheQueries);
+
+ foreach ($data as $key => $value) {
+ foreach ($this->tableToModel as $key1 => $value1) {
+ if (isset($data[$key][$key1])) {
+ $newData[$key][$value1] = $data[$key][$key1];
+ }
+ }
+ }
+
+ if (!empty($newData)) {
+ return $newData;
+ }
+
+ return $data;
+ }
+/**
+ * Returns number of rows matching given SQL condition.
+ *
+ * @param array $conditions SQL conditions array for findAll
+ * @param int $recursize The number of levels deep to fetch associated records
+ * @return int Number of matching rows
+ * @see Model::findAll
+ * @access public
+ */
+ function findCount($conditions = null, $recursive = 0) {
+ $db =& ConnectionManager::getDataSource($this->useDbConfig);
+
+ list($data) = $this->findAll($conditions, 'COUNT(*) AS ' . $db->name('count'), null, null, 1, $recursive);
+
+ if (isset($data[0]['count'])) {
+ return $data[0]['count'];
+ } elseif (isset($data[$this->alias]['count'])) {
+ return $data[$this->alias]['count'];
+ }
+
+ return false;
+ }
+/**
+ * Special findAll variation for tables joined to themselves.
+ * The table needs the fields id and parent_id to work.
+ *
+ * @param array $conditions Conditions for the findAll() call
+ * @param array $fields Fields for the findAll() call
+ * @param string $sort SQL ORDER BY statement
+ * @return array
+ * @access public
+ * @todo Perhaps create a Component with this logic
+ */
+ function findAllThreaded($conditions = null, $fields = null, $sort = null) {
+ return $this->__doThread(Model::findAll($conditions, $fields, $sort), null);
+ }
+/**
+ * Private, recursive helper method for findAllThreaded.
+ *
+ * @param array $data Results of find operation
+ * @param string $root NULL or id for root node of operation
+ * @param integer $index last processed index of $data
+ * @return array Threaded results
+ * @access private
+ * @see Model::findAllThreaded()
+ */
+ function __doThread($data, $root, $index = 0) {
+ $out = array();
+ $sizeOf = sizeof($data);
+
+ for ($ii = $index; $ii < $sizeOf; $ii++) {
+ if (($data[$ii][$this->alias]['parent_id'] == $root) || (($root === null) && ($data[$ii][$this->alias]['parent_id'] == '0'))) {
+ $tmp = $data[$ii];
+
+ if (isset($data[$ii][$this->alias][$this->primaryKey])) {
+ $tmp['children'] = $this->__doThread($data, $data[$ii][$this->alias][$this->primaryKey], $ii);
+ } else {
+ $tmp['children'] = null;
+ }
+
+ $out[] = $tmp;
+ }
+ }
+
+ return $out;
+ }
+/**
+ * Returns an array with keys "prev" and "next" that holds the id's of neighbouring data,
+ * which is useful when creating paged lists.
+ *
+ * @param string $conditions SQL conditions for matching rows
+ * @param string $field Field name (parameter for findAll)
+ * @param unknown_type $value
+ * @return array Array with keys "prev" and "next" that holds the id's
+ * @access public
+ */
+ function findNeighbours($conditions = null, $field, $value) {
+ $db =& ConnectionManager::getDataSource($this->useDbConfig);
+
+ if (!is_null($conditions)) {
+ $conditions = $conditions . ' AND ';
+ }
+
+ @list($prev) = Model::findAll($conditions . $field . ' < ' . $db->value($value), $field, $field . ' DESC', 1, null, 0);
+ @list($next) = Model::findAll($conditions . $field . ' > ' . $db->value($value), $field, $field . ' ASC', 1, null, 0);
+
+ if (!isset($prev)) {
+ $prev = null;
+ }
+
+ if (!isset($next)) {
+ $next = null;
+ }
+
+ return array('prev' => $prev, 'next' => $next);
+ }
+/**
+ * Returns a resultset for given SQL statement. Generic SQL queries should be made with this method.
+ *
+ * @param string $sql SQL statement
+ * @return array Resultset
+ * @access public
+ */
+ function query() {
+ $params = func_get_args();
+ $db =& ConnectionManager::getDataSource($this->useDbConfig);
+ return call_user_func_array(array(&$db, 'query'), $params);
+ }
+/**
+ * Returns true if all fields pass validation, otherwise false.
+ *
+ * @param array $data POST data
+ * @return boolean True if there are no errors
+ * @access public
+ */
+ function validates($data = array()) {
+ $errors = $this->invalidFields($data);
+ return count($errors) == 0;
+ }
+/**
+ * Returns an array of invalid fields.
+ *
+ * @param array $data
+ * @return array Array of invalid fields or boolean case any error occurs
+ * @access public
+ */
+ function invalidFields($data = array()) {
+ if (empty($data)) {
+ $data = $this->data;
+ }
+
+ if (!$this->beforeValidate()) {
+ return $this->validationErrors;
+ }
+
+ if (!isset($this->validate)) {
+ return $this->validationErrors;
+ }
+
+ if (!empty($data)) {
+ $data = $data;
+ } elseif (isset($this->data)) {
+ $data = $this->data;
+ }
+
+ if (isset($data[$this->alias])) {
+ $data = $data[$this->alias];
+ }
+
+ foreach ($this->validate as $field_name => $validator) {
+ if (isset($data[$field_name]) && !preg_match($validator, $data[$field_name])) {
+ $this->invalidate($field_name);
+ }
+ }
+ return $this->validationErrors;
+ }
+/**
+ * Sets a field as invalid
+ *
+ * @param string $field The name of the field to invalidate
+ * @return void
+ * @access public
+ */
+ function invalidate($field) {
+ if (!is_array($this->validationErrors)) {
+ $this->validationErrors = array();
+ }
+ $this->validationErrors[$field] = 1;
+ }
+/**
+ * Returns true if given field name is a foreign key in this Model.
+ *
+ * @param string $field Returns true if the input string ends in "_id"
+ * @return True if the field is a foreign key listed in the belongsTo array.
+ * @access public
+ */
+ function isForeignKey($field) {
+ $foreignKeys = array();
+
+ if (count($this->belongsTo)) {
+ foreach ($this->belongsTo as $assoc => $data) {
+ $foreignKeys[] = $data['foreignKey'];
+ }
+ }
+ return (bool)(in_array($field, $foreignKeys));
+ }
+/**
+ * Gets the display field for this model
+ *
+ * @return string The name of the display field for this Model (i.e. 'name', 'title').
+ * @access public
+ */
+ function getDisplayField() {
+ return $this->displayField;
+ }
+/**
+ * Returns a resultset array with specified fields from database matching given conditions.
+ * Method can be used to generate option lists for SELECT elements.
+ *
+ * @param mixed $conditions SQL conditions as a string or as an array('field' =>'value',...)
+ * @param string $order SQL ORDER BY conditions (e.g. "price DESC" or "name ASC")
+ * @param int $limit SQL LIMIT clause, for calculating items per page
+ * @param string $keyPath A string path to the key, i.e. "{n}.Post.id"
+ * @param string $valuePath A string path to the value, i.e. "{n}.Post.title"
+ * @return array An associative array of records, where the id is the key, and the display field is the value
+ * @access public
+ */
+ function generateList($conditions = null, $order = null, $limit = null, $keyPath = null, $valuePath = null) {
+ if ($keyPath == null && $valuePath == null && $this->hasField($this->displayField)) {
+ $fields = array($this->primaryKey, $this->displayField);
+ } else {
+ $fields = null;
+ }
+ $recursive = $this->recursive;
+
+ if ($recursive >= 1) {
+ $this->recursive = -1;
+ }
+ $result = $this->findAll($conditions, $fields, $order, $limit);
+ $this->recursive = $recursive;
+
+ if (!$result) {
+ return false;
+ }
+
+ if ($keyPath == null) {
+ $keyPath = '{n}.' . $this->alias . '.' . $this->primaryKey;
+ }
+
+ if ($valuePath == null) {
+ $valuePath = '{n}.' . $this->alias . '.' . $this->displayField;
+ }
+
+ $keys = Set::extract($result, $keyPath);
+ $vals = Set::extract($result, $valuePath);
+
+ if (!empty($keys) && !empty($vals)) {
+ $return = array_combine($keys, $vals);
+ return $return;
+ }
+ return null;
+ }
+/**
+ * Escapes the field name and prepends the model name. Escaping will be done according to the current database driver's rules.
+ *
+ * @param unknown_type $field
+ * @return string The name of the escaped field for this Model (i.e. id becomes `Post`.`id`).
+ * @access public
+ */
+ function escapeField($field) {
+ $db =& ConnectionManager::getDataSource($this->useDbConfig);
+ return $db->name($this->alias) . '.' . $db->name($field);
+ }
+/**
+ * Returns the current record's ID
+ *
+ * @param unknown_type $list
+ * @return mixed The ID of the current record
+ * @access public
+ */
+ function getID($list = 0) {
+ if (!is_array($this->id)) {
+ return $this->id;
+ }
+
+ if (count($this->id) == 0) {
+ return false;
+ }
+
+ if (isset($this->id[$list])) {
+ return $this->id[$list];
+ }
+
+ foreach ($this->id as $id) {
+ return $id;
+ }
+
+ return false;
+ }
+/**
+ * Returns the ID of the last record this Model inserted
+ *
+ * @return mixed
+ * @access public
+ */
+ function getLastInsertID() {
+ return $this->getInsertID();
+ }
+/**
+ * Returns the ID of the last record this Model inserted
+ *
+ * @return mixed
+ * @access public
+ */
+ function getInsertID() {
+ return $this->__insertID;
+ }
+/**
+ * Sets the ID of the last record this Model inserted
+ *
+ * @param mixed $id
+ * @return void
+ */
+ function setInsertID($id) {
+ $this->__insertID = $id;
+ }
+/**
+ * Returns the number of rows returned from the last query
+ *
+ * @return int
+ * @access public
+ */
+ function getNumRows() {
+ $db =& ConnectionManager::getDataSource($this->useDbConfig);
+ return $db->lastNumRows();
+ }
+/**
+ * Returns the number of rows affected by the last query
+ *
+ * @return int
+ * @access public
+ */
+ function getAffectedRows() {
+ $db =& ConnectionManager::getDataSource($this->useDbConfig);
+ return $db->lastAffected();
+ }
+/**
+ * Sets the DataSource to which this model is bound
+ *
+ * @param string $dataSource The name of the DataSource, as defined in Connections.php
+ * @return boolean True on success
+ * @access public
+ */
+ function setDataSource($dataSource = null) {
+ if ($dataSource != null) {
+ $this->useDbConfig = $dataSource;
+ }
+ $db =& ConnectionManager::getDataSource($this->useDbConfig);
+
+ if (!empty($db->config['prefix']) && $this->tablePrefix === null) {
+ $this->tablePrefix = $db->config['prefix'];
+ }
+
+ if (empty($db) || $db == null || !is_object($db)) {
+ return $this->cakeError('missingConnection', array(array('className' => $this->alias)));
+ }
+ }
+/**
+ * Before find callback
+ *
+ * @param array $queryData Data used to execute this query, i.e. conditions, order, etc.
+ * @return boolean True if the operation should continue, false if it should abort
+ * @access public
+ */
+ function beforeFind(&$queryData) {
+ return true;
+ }
+/**
+ * After find callback. Can be used to modify any results returned by find and findAll.
+ *
+ * @param mixed $results The results of the find operation
+ * @return mixed Result of the find operation
+ * @access public
+ */
+ function afterFind($results) {
+ return $results;
+ }
+/**
+ * Before save callback
+ *
+ * @return boolean True if the operation should continue, false if it should abort
+ * @access public
+ */
+ function beforeSave() {
+ return true;
+ }
+/**
+ * After save callback
+ *
+ * @return boolean
+ * @access public
+ */
+ function afterSave() {
+ return true;
+ }
+/**
+ * Before delete callback
+ *
+ * @return boolean True if the operation should continue, false if it should abort
+ * @access public
+ */
+ function beforeDelete() {
+ return true;
+ }
+/**
+ * After delete callback
+ *
+ * @return boolean
+ * @access public
+ */
+ function afterDelete() {
+ return true;
+ }
+/**
+ * Before validate callback
+ *
+ * @return boolean
+ * @access public
+ */
+ function beforeValidate() {
+ return true;
+ }
+/**
+ * DataSource error callback
+ *
+ * @return void
+ */
+ function onError() {
+ }
+/**
+ * Private method. Clears cache for this model
+ *
+ * @param string $type If null this deletes cached views if CACHE_CHECK is true
+ * Will be used to allow deleting query cache also
+ * @return boolean true on delete
+ * @access protected
+ */
+ function _clearCache($type = null) {
+ if ($type === null) {
+ if (defined('CACHE_CHECK') && CACHE_CHECK === true) {
+ $assoc[] = strtolower(Inflector::pluralize($this->alias));
+
+ foreach ($this->__associations as $key => $association) {
+ foreach ($this->$association as $key => $className) {
+ $check = strtolower(Inflector::pluralize($className['className']));
+
+ if (!in_array($check, $assoc)) {
+ $assoc[] = strtolower(Inflector::pluralize($className['className']));
+ }
+ }
+ }
+ clearCache($assoc);
+ return true;
+ }
+ } else {
+ //Will use for query cache deleting
+ }
+ }
+/**
+ * Called when serializing a model
+ *
+ * @return array
+ * @access public
+ */
+ function __sleep() {
+ $return = array_keys(get_object_vars($this));
+ return $return;
+ }
+/**
+ * Called when unserializing a model
+ *
+ * @return void
+ * @access public
+ */
+ function __wakeup() {
+ }
+}
+// --- PHP4 Only
+overload ('Model');
+// --- PHP4 Only
+
+?> \ No newline at end of file
diff --git a/site/cake/libs/model/model_php5.php b/site/cake/libs/model/model_php5.php
new file mode 100644
index 0000000..27e522f
--- /dev/null
+++ b/site/cake/libs/model/model_php5.php
@@ -0,0 +1,1701 @@
+<?php
+/* SVN FILE: $Id: model_php5.php 6305 2008-01-02 02:33:56Z phpnut $ */
+/**
+ * Object-relational mapper.
+ *
+ * DBO-backed object data model, for mapping database tables to Cake objects.
+ *
+ * PHP versions 5
+ *
+ * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
+ * Copyright 2005-2008, Cake Software Foundation, Inc.
+ * 1785 E. Sahara Avenue, Suite 490-204
+ * Las Vegas, Nevada 89104
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
+ * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
+ * @package cake
+ * @subpackage cake.cake.libs.model
+ * @since CakePHP(tm) v 0.10.0.0
+ * @version $Revision: 6305 $
+ * @modifiedby $LastChangedBy: phpnut $
+ * @lastmodified $Date: 2008-01-01 20:33:56 -0600 (Tue, 01 Jan 2008) $
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+/**
+ * Included libs
+ */
+uses('class_registry', 'validators', 'model' . DS . 'connection_manager', 'set');
+/**
+ * Object-relational mapper.
+ *
+ * DBO-backed object data model.
+ * Automatically selects a database table name based on a pluralized lowercase object class name
+ * (i.e. class 'User' => table 'users'; class 'Man' => table 'men')
+ * The table is required to have at least 'id auto_increment', 'created datetime',
+ * and 'modified datetime' fields.
+ *
+ * @package cake
+ * @subpackage cake.cake.libs.model
+ */
+class Model extends Object{
+/**
+ * The name of the DataSource connection that this Model uses
+ *
+ * @var string
+ * @access public
+ */
+ var $useDbConfig = 'default';
+/**
+ * Custom database table name.
+ *
+ * @var string
+ * @access public
+ */
+ var $useTable = null;
+/**
+ * Custom display field name. Display fields are used by Scaffold, in SELECT boxes' OPTION elements.
+ *
+ * @var string
+ * @access public
+ */
+ var $displayField = null;
+
+/**
+ * Value of the primary key ID of the record that this model is currently pointing to
+ *
+ * @var string
+ * @access public
+ */
+ var $id = false;
+/**
+ * Container for the data that this model gets from persistent storage (the database).
+ *
+ * @var array
+ * @access public
+ */
+ var $data = array();
+/**
+ * Table name for this Model.
+ *
+ * @var string
+ * @access public
+ */
+ var $table = false;
+/**
+ * The name of the ID field for this Model.
+ *
+ * @var string
+ * @access public
+ */
+ var $primaryKey = null;
+/**
+ * Table metadata
+ *
+ * @var array
+ * @access protected
+ */
+ var $_tableInfo = null;
+/**
+ * List of validation rules. Append entries for validation as ('field_name' => '/^perl_compat_regexp$/')
+ * that have to match with preg_match(). Use these rules with Model::validate()
+ *
+ * @var array
+ * @access public
+ */
+ var $validate = array();
+/**
+ * Errors in validation
+ * @var array
+ * @access public
+ */
+ var $validationErrors = array();
+/**
+ * Database table prefix for tables in model.
+ *
+ * @var string
+ * @access public
+ */
+ var $tablePrefix = null;
+/**
+ * Name of the model.
+ *
+ * @var string
+ * @access public
+ */
+ var $name = null;
+/**
+ * Name of the current model.
+ *
+ * @var string
+ * @access public
+ */
+ var $currentModel = null;
+/**
+ * List of table names included in the Model description. Used for associations.
+ *
+ * @var array
+ * @access public
+ */
+ var $tableToModel = array();
+/**
+ * List of Model names by used tables. Used for associations.
+ *
+ * @var array
+ * @access public
+ */
+ var $modelToTable = array();
+/**
+ * List of Foreign Key names to used tables. Used for associations.
+ *
+ * @var array
+ * @access public
+ */
+ var $keyToTable = array();
+/**
+ * Alias name for model.
+ *
+ * @var array
+ * @access public
+ */
+ var $alias = null;
+/**
+ * Whether or not transactions for this model should be logged
+ *
+ * @var boolean
+ * @access public
+ */
+ var $logTransactions = false;
+/**
+ * Whether or not to enable transactions for this model (i.e. BEGIN/COMMIT/ROLLBACK)
+ *
+ * @var boolean
+ * @access public
+ */
+ var $transactional = false;
+/**
+ * Whether or not to cache queries for this model. This enables in-memory
+ * caching only, the results are not stored beyond this execution.
+ *
+ * @var boolean
+ * @access public
+ */
+ var $cacheQueries = true;
+/**
+ * belongsTo association
+ *
+ * @var array
+ * @access public
+ */
+ var $belongsTo = array();
+/**
+ * hasOne association
+ *
+ * @var array
+ * @access public
+ */
+ var $hasOne = array();
+/**
+ * hasMany association
+ *
+ * @var array
+ * @access public
+ */
+ var $hasMany = array();
+/**
+ * hasAndBelongsToMany association
+ *
+ * @var array
+ * @access public
+ */
+ var $hasAndBelongsToMany = array();
+/**
+ * Depth of recursive association
+ *
+ * @var int
+ * @access public
+ */
+ var $recursive = 1;
+/**
+ * Whitelist of fields allowed to be saved
+ *
+ * @var array
+ */
+ var $whitelist = array();
+/**
+ * Enter description here...
+ *
+ * @var boolean
+ */
+ var $cacheSources = true;
+/**
+ * Default association keys
+ *
+ * @var array
+ * @access private
+ */
+ var $__associationKeys = array('belongsTo' => array('className', 'foreignKey', 'conditions', 'fields', 'order', 'counterCache'),
+ 'hasOne' => array('className', 'foreignKey','conditions', 'fields','order', 'dependent'),
+ 'hasMany' => array('className', 'foreignKey', 'conditions', 'fields', 'order', 'limit', 'offset', 'dependent', 'exclusive', 'finderQuery', 'counterQuery'),
+ 'hasAndBelongsToMany' => array('className', 'joinTable', 'foreignKey', 'associationForeignKey', 'conditions', 'fields', 'order', 'limit', 'offset', 'unique', 'finderQuery', 'deleteQuery', 'insertQuery'));
+/**
+ * Holds provided/generated association key names and other data for all associations
+ *
+ * @var array
+ * @access private
+ */
+ var $__associations = array('belongsTo', 'hasOne', 'hasMany', 'hasAndBelongsToMany');
+/**
+ * The last inserted ID of the data that this model created
+ *
+ * @var int
+ * @access private
+ */
+ var $__insertID = null;
+/**
+ * The number of records returned by the last query
+ *
+ * @var int
+ * @access private
+ */
+ var $__numRows = null;
+/**
+ * The number of records affected by the last query
+ *
+ * @var int
+ * @access private
+ */
+ var $__affectedRows = null;
+/**
+ * Holds model associations temporarily to allow for dynamic (un)binding
+ *
+ * @var array
+ * @access private
+ */
+ var $__backAssociation = array();
+/**
+ * Constructor. Binds the Model's database table to the object.
+ *
+ * @param integer $id
+ * @param string $table Name of database table to use.
+ * @param DataSource $ds DataSource connection object.
+ */
+ function __construct($id = false, $table = null, $ds = null) {
+ parent::__construct();
+
+ if (is_array($id) && isset($id['name'])) {
+ $options = array_merge(array('id' => false, 'table' => null, 'ds' => null, 'alias' => null), $id);
+ list($id, $table, $ds) = array($options['id'], $options['table'], $options['ds']);
+ $this->name = $options['name'];
+ }
+
+ if ($this->name === null) {
+ $this->name = get_class($this);
+ }
+
+ if ($this->primaryKey === null) {
+ $this->primaryKey = 'id';
+ }
+
+ if (isset($options['alias']) || !empty($options['alias'])) {
+ $this->alias = $options['alias'];
+ unset($options);
+ } else {
+ $this->alias = $this->name;
+ }
+ ClassRegistry::addObject($this->alias, $this);
+
+ $this->id = $id;
+ unset($id);
+
+ if ($table === false) {
+ $this->useTable = false;
+ } elseif ($table) {
+ $this->useTable = $table;
+ }
+
+ if ($this->useTable !== false) {
+ $this->setDataSource($ds);
+
+ if ($this->useTable === null) {
+ $this->useTable = Inflector::tableize($this->name);
+ }
+
+ if (in_array('settableprefix', get_class_methods($this))) {
+ $this->setTablePrefix();
+ }
+
+ $this->setSource($this->useTable);
+ $this->__createLinks();
+
+ if ($this->displayField == null) {
+ if ($this->hasField('title')) {
+ $this->displayField = 'title';
+ }
+
+ if ($this->hasField('name')) {
+ $this->displayField = 'name';
+ }
+
+ if ($this->displayField == null) {
+ $this->displayField = $this->primaryKey;
+ }
+ }
+ }
+ }
+
+/**
+ * Handles custom method calls, like findBy<field> for DB models,
+ * and custom RPC calls for remote data sources
+ *
+ * @param unknown_type $method
+ * @param array $params
+ * @return unknown
+ * @access protected
+ */
+ function __call($method, $params) {
+ $db =& ConnectionManager::getDataSource($this->useDbConfig);
+ return $db->query($method, $params, $this);
+ }
+/**
+ * Bind model associations on the fly.
+ *
+ * @param array $params
+ * @return true
+ * @access public
+ */
+ function bindModel($params) {
+ foreach ($params as $assoc => $model) {
+ $this->__backAssociation[$assoc] = $this->{$assoc};
+
+ foreach ($model as $key => $value) {
+ $assocName = $key;
+
+ if (is_numeric($key)) {
+ $assocName = $value;
+ $value = array();
+ }
+ $modelName = $assocName;
+ $this->{$assoc}[$assocName] = $value;
+ }
+ }
+ $this->__createLinks();
+ return true;
+ }
+/**
+ * Turn off associations on the fly.
+ *
+ * @param array $params
+ * @return true
+ * @access public
+ */
+ function unbindModel($params) {
+ foreach ($params as $assoc => $models) {
+ $this->__backAssociation[$assoc] = $this->{$assoc};
+
+ foreach ($models as $model) {
+ $this->__backAssociation = array_merge($this->__backAssociation, $this->{$assoc});
+ unset ($this->{$assoc}[$model]);
+ }
+ }
+ return true;
+ }
+/**
+ * Private helper method to create a set of associations.
+ *
+ * @access private
+ */
+ function __createLinks() {
+
+ foreach ($this->__associations as $type) {
+ if (!is_array($this->{$type})) {
+ $this->{$type} = explode(',', $this->{$type});
+
+ foreach ($this->{$type} as $i => $className) {
+ $className = trim($className);
+ unset ($this->{$type}[$i]);
+ $this->{$type}[$className] = array();
+ }
+ }
+
+ foreach ($this->{$type} as $assoc => $value) {
+ if (is_numeric($assoc)) {
+ unset ($this->{$type}[$assoc]);
+ $assoc = $value;
+ $value = array();
+ $this->{$type}[$assoc] = $value;
+ }
+
+ $className = $assoc;
+
+ if (isset($value['className']) && !empty($value['className'])) {
+ $className = $value['className'];
+ }
+ $this->__constructLinkedModel($assoc, $className);
+ }
+ }
+
+ foreach ($this->__associations as $type) {
+ $this->__generateAssociation($type);
+ }
+ }
+
+/**
+ * Private helper method to create associated models of given class.
+ * @param string $assoc
+ * @param string $className Class name
+ * @param string $type Type of assocation
+ * @access private
+ */
+ function __constructLinkedModel($assoc, $className) {
+ if(empty($className)) {
+ $className = $assoc;
+ }
+
+ if (!class_exists($className)) {
+ loadModel($className);
+ }
+ $colKey = Inflector::underscore($className);
+ $model = array('name' => $className, 'alias' => $assoc);
+
+ if (ClassRegistry::isKeySet($colKey)) {
+ $this->{$assoc} = ClassRegistry::getObject($colKey);
+ $this->{$className} = $this->{$assoc};
+ } else {
+ $this->{$assoc} = new $className($model);
+ $this->{$className} = $this->{$assoc};
+ }
+ $this->tableToModel[$this->{$assoc}->table] = $className;
+ $this->modelToTable[$assoc] = $this->{$assoc}->table;
+ }
+/**
+ * Build array-based association from string.
+ *
+ * @param string $type "Belongs", "One", "Many", "ManyTo"
+ * @access private
+ */
+ function __generateAssociation($type) {
+ foreach ($this->{$type}as $assocKey => $assocData) {
+ $class = $assocKey;
+
+ foreach ($this->__associationKeys[$type] as $key) {
+ if (!isset($this->{$type}[$assocKey][$key]) || $this->{$type}[$assocKey][$key] == null) {
+ $data = '';
+
+ switch($key) {
+ case 'fields':
+ $data = '';
+ break;
+
+ case 'foreignKey':
+ $data = Inflector::singularize($this->table) . '_id';
+
+ if ($type == 'belongsTo') {
+ $data = Inflector::singularize($this->{$class}->table) . '_id';
+ }
+ break;
+
+ case 'associationForeignKey':
+ $data = Inflector::singularize($this->{$class}->table) . '_id';
+ break;
+
+ case 'joinTable':
+ $tables = array($this->table, $this->{$class}->table);
+ sort ($tables);
+ $data = $tables[0] . '_' . $tables[1];
+ break;
+
+ case 'className':
+ $data = $class;
+ break;
+ }
+
+ $this->{$type}[$assocKey][$key] = $data;
+ }
+
+ if ($key == 'foreignKey' && !isset($this->keyToTable[$this->{$type}[$assocKey][$key]])) {
+ $this->keyToTable[$this->{$type}[$assocKey][$key]][0] = $this->{$class}->table;
+ $this->keyToTable[$this->{$type}[$assocKey][$key]][1] = $this->{$class}->alias;
+ }
+ }
+ }
+ }
+/**
+ * Sets a custom table for your controller class. Used by your controller to select a database table.
+ *
+ * @param string $tableName Name of the custom table
+ * @access public
+ */
+ function setSource($tableName) {
+ $this->setDataSource($this->useDbConfig);
+ $db =& ConnectionManager::getDataSource($this->useDbConfig);
+ $db->cacheSources = $this->cacheSources;
+
+ if ($db->isInterfaceSupported('listSources')) {
+ $sources = $db->listSources();
+ if (is_array($sources) && !in_array(low($this->tablePrefix . $tableName), array_map('low', $sources))) {
+ return $this->cakeError('missingTable', array(array(
+ 'className' => $this->alias,
+ 'table' => $this->tablePrefix . $tableName)));
+
+ }
+ $this->_tableInfo = null;
+ }
+ $this->table = $this->useTable = $tableName;
+ $this->tableToModel[$this->table] = $this->alias;
+ $this->loadInfo();
+ }
+/**
+ * This function does two things: 1) it scans the array $one for the primary key,
+ * and if that's found, it sets the current id to the value of $one[id].
+ * For all other keys than 'id' the keys and values of $one are copied to the 'data' property of this object.
+ * 2) Returns an array with all of $one's keys and values.
+ * (Alternative indata: two strings, which are mangled to
+ * a one-item, two-dimensional array using $one for a key and $two as its value.)
+ *
+ * @param mixed $one Array or string of data
+ * @param string $two Value string for the alternative indata method
+ * @return array
+ * @access public
+ */
+ function set($one, $two = null) {
+ if (is_array($one)) {
+ if (countdim($one) == 1) {
+ $data = array($this->alias => $one);
+ } else {
+ $data = $one;
+ }
+ } else {
+ $data = array($this->alias => array($one => $two));
+ }
+
+ foreach ($data as $n => $v) {
+ if (is_array($v)) {
+
+ foreach ($v as $x => $y) {
+ if (empty($this->whitelist) || (in_array($x, $this->whitelist) || $n !== $this->alias)) {
+ if (isset($this->validationErrors[$x])) {
+ unset ($this->validationErrors[$x]);
+ }
+
+ if ($n == $this->name || is_array($y)) {
+ if ($x === $this->primaryKey) {
+ $this->id = $y;
+ }
+ $this->data[$n][$x] = $y;
+ }
+ }
+ }
+ }
+ }
+ return $data;
+ }
+/**
+ * Returns an array of table metadata (column names and types) from the database.
+ *
+ * @return array Array of table metadata
+ * @access public
+ */
+ function loadInfo() {
+ $db =& ConnectionManager::getDataSource($this->useDbConfig);
+ $db->cacheSources = $this->cacheSources;
+
+ if (!is_object($this->_tableInfo) && $db->isInterfaceSupported('describe') && $this->useTable !== false) {
+ $info = new Set($db->describe($this));
+
+ foreach($info->value as $field => $value) {
+ $fields[] = am(array('name'=> $field), $value);
+ }
+ unset($info);
+ $this->_tableInfo = new Set($fields);
+ } elseif ($this->useTable === false) {
+ $this->_tableInfo = new Set();
+ }
+ return $this->_tableInfo;
+ }
+/**
+ * Returns an associative array of field names and column types.
+ *
+ * @return array
+ * @access public
+ */
+ function getColumnTypes() {
+ $columns = $this->loadInfo();
+ $columns = $columns->value;
+ $db =& ConnectionManager::getDataSource($this->useDbConfig);
+ $cols = array();
+
+ foreach ($columns as $col) {
+ $cols[$col['name']] = $col['type'];
+ }
+ return $cols;
+ }
+/**
+ * Returns the column type of a column in the model
+ *
+ * @param string $column The name of the model column
+ * @return string
+ * @access public
+ */
+ function getColumnType($column) {
+ $columns = $this->loadInfo();
+ $columns = $columns->value;
+ $cols = array();
+
+ foreach ($columns as $col) {
+ if ($col['name'] == $column) {
+ return $col['type'];
+ }
+ }
+ return null;
+ }
+/**
+ * Returns true if this Model has given field in its database table.
+ *
+ * @param string $name Name of field to look for
+ * @return boolean
+ * @access public
+ */
+ function hasField($name) {
+ if (is_array($name)) {
+ foreach ($name as $n) {
+ if ($this->hasField($n)) {
+ return $n;
+ }
+ }
+ return false;
+ }
+
+ if (empty($this->_tableInfo)) {
+ $this->loadInfo();
+ }
+
+ if ($this->_tableInfo != null) {
+ return in_array($name, $this->_tableInfo->extract('{n}.name'));
+ }
+ return false;
+ }
+/**
+ * Initializes the model for writing a new record.
+ *
+ * @return boolean True
+ * @access public
+ */
+ function create() {
+ $this->id = false;
+ unset ($this->data);
+ $this->data = $this->validationErrors = array();
+ return true;
+ }
+/**
+ * @deprecated
+ */
+ function setId($id) {
+ $this->id = $id;
+ }
+/**
+ * Use query() instead.
+ * @deprecated
+ */
+ function findBySql($sql) {
+ return $this->query($sql);
+ }
+/**
+ * Returns a list of fields from the database
+ *
+ * @param mixed $id The ID of the record to read
+ * @param mixed $fields String of single fieldname, or an array of fieldnames.
+ * @return array Array of database fields
+ * @access public
+ */
+ function read($fields = null, $id = null) {
+ $this->validationErrors = array();
+
+ if ($id != null) {
+ $this->id = $id;
+ }
+
+ $id = $this->id;
+
+ if (is_array($this->id)) {
+ $id = $this->id[0];
+ }
+
+ if ($this->id !== null && $this->id !== false) {
+ $db =& ConnectionManager::getDataSource($this->useDbConfig);
+ $field = $db->name($this->alias) . '.' . $db->name($this->primaryKey);
+ return $this->find($field . ' = ' . $db->value($id, $this->getColumnType($this->primaryKey)), $fields);
+ } else {
+ return false;
+ }
+ }
+/**
+ * Returns contents of a field in a query matching given conditions.
+ *
+ * @param string $name Name of field to get
+ * @param array $conditions SQL conditions (defaults to NULL)
+ * @param string $order SQL ORDER BY fragment
+ * @return field contents
+ * @access public
+ */
+ function field($name, $conditions = null, $order = null) {
+ if ($conditions === null && $this->id !== false) {
+ $conditions = array($this->alias . '.' . $this->primaryKey => $this->id);
+ }
+
+ if ($data = $this->find($conditions, $name, $order, 0)) {
+
+ if (strpos($name, '.') === false) {
+ if (isset($data[$this->alias][$name])) {
+ return $data[$this->alias][$name];
+ } else {
+ return false;
+ }
+ } else {
+ $name = explode('.', $name);
+
+ if (isset($data[$name[0]][$name[1]])) {
+ return $data[$name[0]][$name[1]];
+ } else {
+ return false;
+ }
+ }
+ } else {
+ return false;
+ }
+ }
+/**
+ * Saves a single field to the database.
+ *
+ * @param string $name Name of the table field
+ * @param mixed $value Value of the field
+ * @param boolean $validate Whether or not this model should validate before saving (defaults to false)
+ * @return boolean True on success save
+ * @access public
+ */
+ function saveField($name, $value, $validate = false) {
+ return $this->save(array($this->alias => array($name => $value)), $validate);
+ }
+/**
+ * Saves model data to the database.
+ * By default, validation occurs before save.
+ *
+ * @param array $data Data to save.
+ * @param boolean $validate If set, validation will be done before the save
+ * @param array $fieldList List of fields to allow to be written
+ * @return boolean success
+ * @access public
+ */
+ function save($data = null, $validate = true, $fieldList = array()) {
+ $db =& ConnectionManager::getDataSource($this->useDbConfig);
+ $_whitelist = $this->whitelist;
+
+ if (!empty($fieldList)) {
+ $this->whitelist = $fieldList;
+ } elseif ($fieldList === null) {
+ $this->whitelist = array();
+ }
+
+ if ($data) {
+ if (countdim($data) == 1) {
+ $this->set(array($this->alias => $data));
+ } else {
+ $this->set($data);
+ }
+ }
+
+ if ($validate && !$this->validates()) {
+ $this->whitelist = $_whitelist;
+ return false;
+ }
+
+ if (!$this->beforeSave()) {
+ $this->whitelist = $_whitelist;
+ return false;
+ }
+ $fields = $values = array();
+
+ if (count($this->data) > 1) {
+ $weHaveMulti = true;
+ $joined = false;
+ } else {
+ $weHaveMulti = false;
+ }
+
+ foreach ($this->data as $n => $v) {
+ if (isset($weHaveMulti) && isset($v[$n]) && in_array($n, array_keys($this->hasAndBelongsToMany))) {
+ $joined[] = $v;
+ } else {
+ if ($n === $this->alias) {
+ foreach (array('created', 'updated', 'modified') as $field) {
+ if (array_key_exists($field, $v) && (empty($v[$field]) || $v[$field] === null)) {
+ unset($v[$field]);
+ }
+ }
+
+ foreach ($v as $x => $y) {
+ if ($this->hasField($x)) {
+ $fields[] = $x;
+ $values[] = $y;
+ }
+ }
+ }
+ }
+ }
+ $exists = $this->exists();
+
+ if (!$exists && $this->hasField('created') && !in_array('created', $fields)) {
+ $fields[] = 'created';
+ $values[] = date('Y-m-d H:i:s');
+ }
+
+ if ($this->hasField('modified') && !in_array('modified', $fields)) {
+ $fields[] = 'modified';
+ $values[] = date('Y-m-d H:i:s');
+ }
+
+ if ($this->hasField('updated') && !in_array('updated', $fields)) {
+ $fields[] = 'updated';
+ $values[] = date('Y-m-d H:i:s');
+ }
+
+ if (!$exists) {
+ $this->id = false;
+ }
+ $this->whitelist = $_whitelist;
+
+ if (count($fields)) {
+ if (!empty($this->id)) {
+ if ($db->update($this, $fields, $values)) {
+ if (!empty($joined)) {
+ $this->__saveMulti($joined, $this->id);
+ }
+
+ $this->afterSave();
+ $this->data = false;
+ $this->_clearCache();
+ return true;
+ } else {
+ return false;
+ }
+ } else {
+ if ($db->create($this, $fields, $values)) {
+ if (!empty($joined)) {
+ $this->__saveMulti($joined, $this->id);
+ }
+
+ $this->afterSave();
+ $this->data = false;
+ $this->_clearCache();
+ $this->validationErrors = array();
+ return true;
+ } else {
+ return false;
+ }
+ }
+ } else {
+ return false;
+ }
+ }
+/**
+ * Saves model hasAndBelongsToMany data to the database.
+ *
+ * @param array $joined Data to save.
+ * @param string $id
+ * @return void
+ * @access private
+ */
+ function __saveMulti($joined, $id) {
+ $db =& ConnectionManager::getDataSource($this->useDbConfig);
+ foreach ($joined as $x => $y) {
+ foreach ($y as $assoc => $value) {
+ if (isset($this->hasAndBelongsToMany[$assoc])) {
+ $joinTable[$assoc] = $this->hasAndBelongsToMany[$assoc]['joinTable'];
+ $mainKey[$assoc] = $this->hasAndBelongsToMany[$assoc]['foreignKey'];
+ $keys[] = $this->hasAndBelongsToMany[$assoc]['foreignKey'];
+ $keys[] = $this->hasAndBelongsToMany[$assoc]['associationForeignKey'];
+ $fields[$assoc] = join(',', $keys);
+ unset($keys);
+
+ foreach ($value as $update) {
+ if (!empty($update)) {
+ $values[] = $db->value($id, $this->getColumnType($this->primaryKey));
+ $values[] = $db->value($update);
+ $values = join(',', $values);
+ $newValues[] = "({$values})";
+ unset ($values);
+ }
+ }
+
+ if (!empty($newValues)) {
+ $newValue[$assoc] = $newValues;
+ unset($newValues);
+ } else {
+ $newValue[$assoc] = array();
+ }
+ }
+ }
+ }
+
+ if (isset($joinTable)) {
+ $total = count($joinTable);
+
+ if (is_array($newValue)) {
+ foreach ($newValue as $loopAssoc => $val) {
+ $db =& ConnectionManager::getDataSource($this->useDbConfig);
+ $table = $db->name($db->fullTableName($joinTable[$loopAssoc]));
+ $db->query("DELETE FROM {$table} WHERE {$mainKey[$loopAssoc]} = '{$id}'");
+
+ if (!empty($newValue[$loopAssoc])) {
+ $secondCount = count($newValue[$loopAssoc]);
+ for ($x = 0; $x < $secondCount; $x++) {
+ $db->query("INSERT INTO {$table} ({$fields[$loopAssoc]}) VALUES {$newValue[$loopAssoc][$x]}");
+ }
+ }
+ }
+ }
+ }
+ }
+/**
+ * Synonym for del().
+ *
+ * @param mixed $id
+ * @see function del
+ * @return boolean True on success
+ * @access public
+ */
+ function remove($id = null, $cascade = true) {
+ return $this->del($id, $cascade);
+ }
+/**
+ * Removes record for given id. If no id is given, the current id is used. Returns true on success.
+ *
+ * @param mixed $id Id of record to delete
+ * @return boolean True on success
+ * @access public
+ */
+ function del($id = null, $cascade = true) {
+ if ($id) {
+ $this->id = $id;
+ }
+ $id = $this->id;
+
+ if ($this->exists() && $this->beforeDelete()) {
+ $db =& ConnectionManager::getDataSource($this->useDbConfig);
+
+ $this->_deleteMulti($id);
+ $this->_deleteHasMany($id, $cascade);
+ $this->_deleteHasOne($id, $cascade);
+ $this->id = $id;
+
+ if ($db->delete($this)) {
+ $this->afterDelete();
+ $this->_clearCache();
+ $this->id = false;
+ return true;
+ }
+ }
+
+ return false;
+ }
+/**
+ * Alias for del()
+ *
+ * @param mixed $id Id of record to delete
+ * @return boolean True on success
+ * @access public
+ */
+ function delete($id = null, $cascade = true) {
+ return $this->del($id, $cascade);
+ }
+/**
+ * Cascades model deletes to hasMany relationships.
+ *
+ * @param string $id
+ * @return null
+ * @access protected
+ */
+ function _deleteHasMany($id, $cascade) {
+ if (!empty($this->__backAssociation)) {
+ $savedAssociatons = $this->__backAssociation;
+ $this->__backAssociation = array();
+ }
+ foreach ($this->hasMany as $assoc => $data) {
+ if ($data['dependent'] === true && $cascade === true) {
+ $model =& $this->{$data['className']};
+ $field = $model->escapeField($data['foreignKey']);
+ $model->recursive = 0;
+ $records = $model->findAll("$field = '$id'", $model->primaryKey, null, null);
+
+ if ($records != false) {
+ foreach ($records as $record) {
+ $model->del($record[$data['className']][$model->primaryKey]);
+ }
+ }
+ }
+ }
+ if (isset($savedAssociatons)) {
+ $this->__backAssociation = $savedAssociatons;
+ }
+ }
+/**
+ * Cascades model deletes to hasOne relationships.
+ *
+ * @param string $id
+ * @return null
+ * @access protected
+ */
+ function _deleteHasOne($id, $cascade) {
+ if (!empty($this->__backAssociation)) {
+ $savedAssociatons = $this->__backAssociation;
+ $this->__backAssociation = array();
+ }
+ foreach ($this->hasOne as $assoc => $data) {
+ if ($data['dependent'] === true && $cascade === true) {
+ $model =& $this->{$data['className']};
+ $field = $model->escapeField($data['foreignKey']);
+ $model->recursive = 0;
+ $records = $model->findAll("$field = '$id'", $model->primaryKey, null, null);
+
+ if ($records != false) {
+ foreach ($records as $record) {
+ $model->del($record[$data['className']][$model->primaryKey]);
+ }
+ }
+ }
+ }
+ if (isset($savedAssociatons)) {
+ $this->__backAssociation = $savedAssociatons;
+ }
+ }
+/**
+ * Cascades model deletes to HABTM join keys.
+ *
+ * @param string $id
+ * @return null
+ * @access protected
+ */
+ function _deleteMulti($id) {
+ $db =& ConnectionManager::getDataSource($this->useDbConfig);
+ foreach ($this->hasAndBelongsToMany as $assoc => $data) {
+ $db->execute("DELETE FROM " . $db->name($db->fullTableName($data['joinTable'])) . " WHERE " . $db->name($data['foreignKey']) . " = '{$id}'");
+ }
+ }
+/**
+ * Returns true if a record with set id exists.
+ *
+ * @return boolean True if such a record exists
+ * @access public
+ */
+ function exists() {
+ if ($this->id) {
+ $id = $this->id;
+
+ if (is_array($id)) {
+ $id = $id[0];
+ }
+
+ $db =& ConnectionManager::getDataSource($this->useDbConfig);
+ return $db->hasAny($this, array($this->primaryKey => $id));
+ }
+ return false;
+ }
+/**
+ * Returns true if a record that meets given conditions exists
+ *
+ * @param array $conditions SQL conditions array
+ * @return boolean True if such a record exists
+ * @access public
+ */
+ function hasAny($conditions = null) {
+ return ($this->findCount($conditions) != false);
+ }
+/**
+ * Return a single row as a resultset array.
+ * By using the $recursive parameter, the call can access further "levels of association" than
+ * the ones this model is directly associated to.
+ *
+ * @param array $conditions SQL conditions array
+ * @param mixed $fields Either a single string of a field name, or an array of field names
+ * @param string $order SQL ORDER BY conditions (e.g. "price DESC" or "name ASC")
+ * @param int $recursive The number of levels deep to fetch associated records
+ * @return array Array of records
+ * @access public
+ */
+ function find($conditions = null, $fields = null, $order = null, $recursive = null) {
+ $data = $this->findAll($conditions, $fields, $order, 1, null, $recursive);
+
+ if (empty($data[0])) {
+ return false;
+ }
+
+ return $data[0];
+ }
+/**
+ * Returns a resultset array with specified fields from database matching given conditions.
+ * By using the $recursive parameter, the call can access further "levels of association" than
+ * the ones this model is directly associated to.
+ *
+ * @param mixed $conditions SQL conditions as a string or as an array('field' =>'value',...)
+ * @param mixed $fields Either a single string of a field name, or an array of field names
+ * @param string $order SQL ORDER BY conditions (e.g. "price DESC" or "name ASC")
+ * @param int $limit SQL LIMIT clause, for calculating items per page.
+ * @param int $page Page number, for accessing paged data
+ * @param int $recursive The number of levels deep to fetch associated records
+ * @return array Array of records
+ * @access public
+ */
+ function findAll($conditions = null, $fields = null, $order = null, $limit = null, $page = 1, $recursive = null) {
+
+ $db =& ConnectionManager::getDataSource($this->useDbConfig);
+ $this->id = $this->getID();
+ $offset = null;
+
+ if ($page > 1 && $limit != null) {
+ $offset = ($page - 1) * $limit;
+ }
+
+ if ($order == null) {
+ $order = array();
+ } else {
+ $order = array($order);
+ }
+
+ $queryData = array('conditions' => $conditions,
+ 'fields' => $fields,
+ 'joins' => array(),
+ 'limit' => $limit,
+ 'offset' => $offset,
+ 'order' => $order
+ );
+
+ $ret = $this->beforeFind($queryData);
+ if (is_array($ret)) {
+ $queryData = $ret;
+ } elseif ($ret === false) {
+ return null;
+ }
+
+ $return = $this->afterFind($db->read($this, $queryData, $recursive));
+
+ if (!empty($this->__backAssociation)) {
+ $this->__resetAssociations();
+ }
+
+ return $return;
+ }
+/**
+ * Method is called only when bindTo<ModelName>() is used.
+ * This resets the association arrays for the model back
+ * to the original as set in the model.
+ *
+ * @return boolean
+ * @access private
+ */
+ function __resetAssociations() {
+ foreach ($this->__associations as $type) {
+ if (isset($this->__backAssociation[$type])) {
+ $this->{$type} = $this->__backAssociation[$type];
+ }
+ }
+
+ $this->__backAssociation = array();
+ return true;
+ }
+/**
+ * Runs a direct query against the bound DataSource, and returns the result.
+ *
+ * @param string $data Query data
+ * @return array
+ * @access public
+ */
+ function execute($data) {
+ $db =& ConnectionManager::getDataSource($this->useDbConfig);
+ $data = $db->fetchAll($data, $this->cacheQueries);
+
+ foreach ($data as $key => $value) {
+ foreach ($this->tableToModel as $key1 => $value1) {
+ if (isset($data[$key][$key1])) {
+ $newData[$key][$value1] = $data[$key][$key1];
+ }
+ }
+ }
+
+ if (!empty($newData)) {
+ return $newData;
+ }
+
+ return $data;
+ }
+/**
+ * Returns number of rows matching given SQL condition.
+ *
+ * @param array $conditions SQL conditions array for findAll
+ * @param int $recursize The number of levels deep to fetch associated records
+ * @return int Number of matching rows
+ * @see Model::findAll
+ * @access public
+ */
+ function findCount($conditions = null, $recursive = 0) {
+ $db =& ConnectionManager::getDataSource($this->useDbConfig);
+
+ list($data) = $this->findAll($conditions, 'COUNT(*) AS ' . $db->name('count'), null, null, 1, $recursive);
+
+ if (isset($data[0]['count'])) {
+ return $data[0]['count'];
+ } elseif (isset($data[$this->alias]['count'])) {
+ return $data[$this->alias]['count'];
+ }
+
+ return false;
+ }
+/**
+ * Special findAll variation for tables joined to themselves.
+ * The table needs the fields id and parent_id to work.
+ *
+ * @param array $conditions Conditions for the findAll() call
+ * @param array $fields Fields for the findAll() call
+ * @param string $sort SQL ORDER BY statement
+ * @return array
+ * @access public
+ * @todo Perhaps create a Component with this logic
+ */
+ function findAllThreaded($conditions = null, $fields = null, $sort = null) {
+ return $this->__doThread(Model::findAll($conditions, $fields, $sort), null);
+ }
+/**
+ * Private, recursive helper method for findAllThreaded.
+ *
+ * @param array $data Results of find operation
+ * @param string $root NULL or id for root node of operation
+ * @param integer $index last processed index of $data
+ * @return array Threaded results
+ * @access private
+ * @see Model::findAllThreaded()
+ */
+ function __doThread($data, $root, $index = 0) {
+ $out = array();
+ $sizeOf = sizeof($data);
+
+ for ($ii = $index; $ii < $sizeOf; $ii++) {
+ if (($data[$ii][$this->alias]['parent_id'] == $root) || (($root === null) && ($data[$ii][$this->alias]['parent_id'] == '0'))) {
+ $tmp = $data[$ii];
+
+ if (isset($data[$ii][$this->alias][$this->primaryKey])) {
+ $tmp['children'] = $this->__doThread($data, $data[$ii][$this->alias][$this->primaryKey], $ii);
+ } else {
+ $tmp['children'] = null;
+ }
+
+ $out[] = $tmp;
+ }
+ }
+
+ return $out;
+ }
+/**
+ * Returns an array with keys "prev" and "next" that holds the id's of neighbouring data,
+ * which is useful when creating paged lists.
+ *
+ * @param string $conditions SQL conditions for matching rows
+ * @param string $field Field name (parameter for findAll)
+ * @param unknown_type $value
+ * @return array Array with keys "prev" and "next" that holds the id's
+ * @access public
+ */
+ function findNeighbours($conditions = null, $field, $value) {
+ $db =& ConnectionManager::getDataSource($this->useDbConfig);
+
+ if (!is_null($conditions)) {
+ $conditions = $conditions . ' AND ';
+ }
+
+ @list($prev) = Model::findAll($conditions . $field . ' < ' . $db->value($value), $field, $field . ' DESC', 1, null, 0);
+ @list($next) = Model::findAll($conditions . $field . ' > ' . $db->value($value), $field, $field . ' ASC', 1, null, 0);
+
+ if (!isset($prev)) {
+ $prev = null;
+ }
+
+ if (!isset($next)) {
+ $next = null;
+ }
+
+ return array('prev' => $prev, 'next' => $next);
+ }
+/**
+ * Returns a resultset for given SQL statement. Generic SQL queries should be made with this method.
+ *
+ * @param string $sql SQL statement
+ * @return array Resultset
+ * @access public
+ */
+ function query() {
+ $params = func_get_args();
+ $db =& ConnectionManager::getDataSource($this->useDbConfig);
+ return call_user_func_array(array(&$db, 'query'), $params);
+ }
+/**
+ * Returns true if all fields pass validation, otherwise false.
+ *
+ * @param array $data POST data
+ * @return boolean True if there are no errors
+ * @access public
+ */
+ function validates($data = array()) {
+ $errors = $this->invalidFields($data);
+ return count($errors) == 0;
+ }
+/**
+ * Returns an array of invalid fields.
+ *
+ * @param array $data
+ * @return array Array of invalid fields or boolean case any error occurs
+ * @access public
+ */
+ function invalidFields($data = array()) {
+ if (empty($data)) {
+ $data = $this->data;
+ }
+
+ if (!$this->beforeValidate()) {
+ return $this->validationErrors;
+ }
+
+ if (!isset($this->validate)) {
+ return $this->validationErrors;
+ }
+
+ if (!empty($data)) {
+ $data = $data;
+ } elseif (isset($this->data)) {
+ $data = $this->data;
+ }
+
+ if (isset($data[$this->alias])) {
+ $data = $data[$this->alias];
+ }
+
+ foreach ($this->validate as $field_name => $validator) {
+ if (isset($data[$field_name]) && !preg_match($validator, $data[$field_name])) {
+ $this->invalidate($field_name);
+ }
+ }
+ return $this->validationErrors;
+ }
+/**
+ * Sets a field as invalid
+ *
+ * @param string $field The name of the field to invalidate
+ * @return void
+ * @access public
+ */
+ function invalidate($field) {
+ if (!is_array($this->validationErrors)) {
+ $this->validationErrors = array();
+ }
+ $this->validationErrors[$field] = 1;
+ }
+/**
+ * Returns true if given field name is a foreign key in this Model.
+ *
+ * @param string $field Returns true if the input string ends in "_id"
+ * @return True if the field is a foreign key listed in the belongsTo array.
+ * @access public
+ */
+ function isForeignKey($field) {
+ $foreignKeys = array();
+
+ if (count($this->belongsTo)) {
+ foreach ($this->belongsTo as $assoc => $data) {
+ $foreignKeys[] = $data['foreignKey'];
+ }
+ }
+ return (bool)(in_array($field, $foreignKeys));
+ }
+/**
+ * Gets the display field for this model
+ *
+ * @return string The name of the display field for this Model (i.e. 'name', 'title').
+ * @access public
+ */
+ function getDisplayField() {
+ return $this->displayField;
+ }
+/**
+ * Returns a resultset array with specified fields from database matching given conditions.
+ * Method can be used to generate option lists for SELECT elements.
+ *
+ * @param mixed $conditions SQL conditions as a string or as an array('field' =>'value',...)
+ * @param string $order SQL ORDER BY conditions (e.g. "price DESC" or "name ASC")
+ * @param int $limit SQL LIMIT clause, for calculating items per page
+ * @param string $keyPath A string path to the key, i.e. "{n}.Post.id"
+ * @param string $valuePath A string path to the value, i.e. "{n}.Post.title"
+ * @return array An associative array of records, where the id is the key, and the display field is the value
+ * @access public
+ */
+ function generateList($conditions = null, $order = null, $limit = null, $keyPath = null, $valuePath = null) {
+ if ($keyPath == null && $valuePath == null && $this->hasField($this->displayField)) {
+ $fields = array($this->primaryKey, $this->displayField);
+ } else {
+ $fields = null;
+ }
+ $recursive = $this->recursive;
+
+ if ($recursive >= 1) {
+ $this->recursive = -1;
+ }
+ $result = $this->findAll($conditions, $fields, $order, $limit);
+ $this->recursive = $recursive;
+
+ if (!$result) {
+ return false;
+ }
+
+ if ($keyPath == null) {
+ $keyPath = '{n}.' . $this->alias . '.' . $this->primaryKey;
+ }
+
+ if ($valuePath == null) {
+ $valuePath = '{n}.' . $this->alias . '.' . $this->displayField;
+ }
+
+ $keys = Set::extract($result, $keyPath);
+ $vals = Set::extract($result, $valuePath);
+
+ if (!empty($keys) && !empty($vals)) {
+ $return = array_combine($keys, $vals);
+ return $return;
+ }
+ return null;
+ }
+/**
+ * Escapes the field name and prepends the model name. Escaping will be done according to the current database driver's rules.
+ *
+ * @param unknown_type $field
+ * @return string The name of the escaped field for this Model (i.e. id becomes `Post`.`id`).
+ * @access public
+ */
+ function escapeField($field) {
+ $db =& ConnectionManager::getDataSource($this->useDbConfig);
+ return $db->name($this->alias) . '.' . $db->name($field);
+ }
+/**
+ * Returns the current record's ID
+ *
+ * @param unknown_type $list
+ * @return mixed The ID of the current record
+ * @access public
+ */
+ function getID($list = 0) {
+ if (!is_array($this->id)) {
+ return $this->id;
+ }
+
+ if (count($this->id) == 0) {
+ return false;
+ }
+
+ if (isset($this->id[$list])) {
+ return $this->id[$list];
+ }
+
+ foreach ($this->id as $id) {
+ return $id;
+ }
+
+ return false;
+ }
+/**
+ * Returns the ID of the last record this Model inserted
+ *
+ * @return mixed
+ * @access public
+ */
+ function getLastInsertID() {
+ return $this->getInsertID();
+ }
+/**
+ * Returns the ID of the last record this Model inserted
+ *
+ * @return mixed
+ * @access public
+ */
+ function getInsertID() {
+ return $this->__insertID;
+ }
+/**
+ * Sets the ID of the last record this Model inserted
+ *
+ * @param mixed $id
+ * @return void
+ */
+ function setInsertID($id) {
+ $this->__insertID = $id;
+ }
+/**
+ * Returns the number of rows returned from the last query
+ *
+ * @return int
+ * @access public
+ */
+ function getNumRows() {
+ $db =& ConnectionManager::getDataSource($this->useDbConfig);
+ return $db->lastNumRows();
+ }
+/**
+ * Returns the number of rows affected by the last query
+ *
+ * @return int
+ * @access public
+ */
+ function getAffectedRows() {
+ $db =& ConnectionManager::getDataSource($this->useDbConfig);
+ return $db->lastAffected();
+ }
+/**
+ * Sets the DataSource to which this model is bound
+ *
+ * @param string $dataSource The name of the DataSource, as defined in Connections.php
+ * @return boolean True on success
+ * @access public
+ */
+ function setDataSource($dataSource = null) {
+ if ($dataSource != null) {
+ $this->useDbConfig = $dataSource;
+ }
+ $db =& ConnectionManager::getDataSource($this->useDbConfig);
+
+ if (!empty($db->config['prefix']) && $this->tablePrefix === null) {
+ $this->tablePrefix = $db->config['prefix'];
+ }
+
+ if (empty($db) || $db == null || !is_object($db)) {
+ return $this->cakeError('missingConnection', array(array('className' => $this->alias)));
+ }
+ }
+/**
+ * Before find callback
+ *
+ * @param array $queryData Data used to execute this query, i.e. conditions, order, etc.
+ * @return boolean True if the operation should continue, false if it should abort
+ * @access public
+ */
+ function beforeFind(&$queryData) {
+ return true;
+ }
+/**
+ * After find callback. Can be used to modify any results returned by find and findAll.
+ *
+ * @param mixed $results The results of the find operation
+ * @return mixed Result of the find operation
+ * @access public
+ */
+ function afterFind($results) {
+ return $results;
+ }
+/**
+ * Before save callback
+ *
+ * @return boolean True if the operation should continue, false if it should abort
+ * @access public
+ */
+ function beforeSave() {
+ return true;
+ }
+/**
+ * After save callback
+ *
+ * @return boolean
+ * @access public
+ */
+ function afterSave() {
+ return true;
+ }
+/**
+ * Before delete callback
+ *
+ * @return boolean True if the operation should continue, false if it should abort
+ * @access public
+ */
+ function beforeDelete() {
+ return true;
+ }
+/**
+ * After delete callback
+ *
+ * @return boolean
+ * @access public
+ */
+ function afterDelete() {
+ return true;
+ }
+/**
+ * Before validate callback
+ *
+ * @return boolean
+ * @access public
+ */
+ function beforeValidate() {
+ return true;
+ }
+/**
+ * DataSource error callback
+ *
+ * @return void
+ */
+ function onError() {
+ }
+/**
+ * Private method. Clears cache for this model
+ *
+ * @param string $type If null this deletes cached views if CACHE_CHECK is true
+ * Will be used to allow deleting query cache also
+ * @return boolean true on delete
+ * @access protected
+ */
+ function _clearCache($type = null) {
+ if ($type === null) {
+ if (defined('CACHE_CHECK') && CACHE_CHECK === true) {
+ $assoc[] = strtolower(Inflector::pluralize($this->alias));
+
+ foreach ($this->__associations as $key => $association) {
+ foreach ($this->$association as $key => $className) {
+ $check = strtolower(Inflector::pluralize($className['className']));
+
+ if (!in_array($check, $assoc)) {
+ $assoc[] = strtolower(Inflector::pluralize($className['className']));
+ }
+ }
+ }
+ clearCache($assoc);
+ return true;
+ }
+ } else {
+ //Will use for query cache deleting
+ }
+ }
+/**
+ * Called when serializing a model
+ *
+ * @return array
+ * @access public
+ */
+ function __sleep() {
+ $return = array_keys(get_object_vars($this));
+ return $return;
+ }
+/**
+ * Called when unserializing a model
+ *
+ * @return void
+ * @access public
+ */
+ function __wakeup() {
+ }
+}
+?> \ No newline at end of file
diff --git a/site/cake/libs/neat_array.php b/site/cake/libs/neat_array.php
new file mode 100644
index 0000000..6295f2b
--- /dev/null
+++ b/site/cake/libs/neat_array.php
@@ -0,0 +1,318 @@
+<?php
+/* SVN FILE: $Id: neat_array.php 6305 2008-01-02 02:33:56Z phpnut $ */
+/**
+ * Library of array functions for Cake.
+ *
+ * Internal use only.
+ *
+ * PHP versions 4 and 5
+ *
+ * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
+ * Copyright 2005-2008, Cake Software Foundation, Inc.
+ * 1785 E. Sahara Avenue, Suite 490-204
+ * Las Vegas, Nevada 89104
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
+ * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
+ * @package cake
+ * @subpackage cake.cake.libs
+ * @since CakePHP(tm) v 0.2.9
+ * @version $Revision: 6305 $
+ * @modifiedby $LastChangedBy: phpnut $
+ * @lastmodified $Date: 2008-01-01 20:33:56 -0600 (Tue, 01 Jan 2008) $
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+/**
+ * Class used for internal manipulation of multi-dimensional arrays (arrays of arrays).
+ *
+ * Long description for class
+ *
+ * @package cake
+ * @subpackage cake.cake.libs
+ */
+class NeatArray{
+/**
+ * Value of NeatArray.
+ *
+ * @var array
+ * @access public
+ */
+ var $value;
+/**
+ * Constructor. Defaults to an empty array.
+ *
+ * @param array $value
+ * @access public
+ * @uses NeatArray::value
+ */
+ function NeatArray($value = array()) {
+ $this->value = $value;
+ }
+/**
+ * Finds and returns records with $fieldName equal to $value from this NeatArray.
+ *
+ * @param string $fieldName
+ * @param string $value
+ * @return mixed
+ * @access public
+ * @uses NeatArray::value
+ */
+ function findIn($fieldName, $value) {
+ if (!is_array($this->value)) {
+ return false;
+ }
+ $out = false;
+ $keys = array_keys($this->value);
+ $count = sizeof($keys);
+
+ for ($i = 0; $i < $count; $i++) {
+ if (isset($this->value[$keys[$i]][$fieldName]) && ($this->value[$keys[$i]][$fieldName] == $value))
+ {
+ $out[$keys[$i]] = $this->value[$keys[$i]];
+ }
+ }
+ return $out;
+ }
+/**
+ * Checks if $this->value is an array, and removes all empty elements.
+ *
+ * @access public
+ * @uses NeatArray::value
+ */
+ function cleanup() {
+ $out = is_array($this->value) ? array(): null;
+ foreach ($this->value as $k => $v) {
+ if ($v == "0") {
+ $out[$k] = $v;
+ } elseif ($v) {
+ $out[$k] = $v;
+ }
+ }
+ $this->value=$out;
+ }
+/**
+ * Adds elements from given array to itself.
+ *
+ * @param string $value
+ * @return bool
+ * @access public
+ * @uses NeatArray::value
+ */
+ function add($value) {
+ return ($this->value = $this->plus($value)) ? true : false;
+ }
+/**
+ * Returns itself merged with given array.
+ *
+ * @param array $value Array to add to NeatArray.
+ * @return array
+ * @access public
+ * @uses NeatArray::value
+ */
+ function plus($value) {
+ $merge = array_merge($this->value, (is_array($value) ? $value : array($value)));
+ return $merge;
+ }
+/**
+ * Counts repeating strings and returns an array of totals.
+ *
+ * @param int $sortedBy A value of 1 sorts by values, a value of 2 sorts by keys. Defaults to null (no sorting).
+ * @return array
+ * @access public
+ * @uses NeatArray::value
+ */
+ function totals($sortedBy = 1, $reverse = true) {
+ $out = array();
+ foreach ($this->value as $val) {
+ isset($out[$val]) ? $out[$val]++ : $out[$val] = 1;
+ }
+
+ if ($sortedBy == 1) {
+ $reverse ? arsort($out, SORT_NUMERIC) : asort($out, SORT_NUMERIC);
+ }
+
+ if ($sortedBy == 2) {
+ $reverse ? krsort($out, SORT_STRING) : ksort($out, SORT_STRING);
+ }
+ return $out;
+ }
+/**
+ * Performs an array_filter() on the contents of this NeatArray.
+ *
+ * @param string $with Name of callback function to perform on each element of this NeatArray.
+ * @return array
+ */
+ function filter($with) {
+ return $this->value = array_filter($this->value, $with);
+ }
+/**
+ * Passes each of its values through a specified function or method.
+ * Think of PHP's {@link http://php.net/array_walk array_walk()}.
+ *
+ * @param string $with Name of callback function
+ * @return array Returns value of NeatArray::value
+ * @access public
+ * @uses NeatArray::value
+ */
+ function walk($with) {
+ array_walk($this->value, $with);
+ return $this->value;
+ }
+/**
+ * Apply $template to all elements of this NeatArray, and return the array itself.
+ *
+ * @param string $template {@link http://php.net/sprintf sprintf()}-compatible string to be applied to all values of this NeatArray.
+ * @return array
+ */
+ function sprintf($template) {
+ $count = count($this->value);
+ for ($ii = 0; $ii < $count; $ii++) {
+ $this->value[$ii] = sprintf($template, $this->value[$ii]);
+ }
+ return $this->value;
+ }
+/**
+ * Extracts a value from all array items.
+ *
+ * @return array
+ * @access public
+ * @uses NeatArray::value
+ */
+ function extract($name) {
+ $out = array();
+ foreach ($this->value as $val) {
+ if (isset($val[$name]))
+ $out[]=$val[$name];
+ }
+ return $out;
+ }
+/**
+ * Returns a list of unique elements.
+ *
+ * @return array
+ */
+ function unique() {
+ $unique = array_unique($this->value);
+ return $unique;
+ }
+/**
+ * Removes duplicate elements from the value and returns it.
+ *
+ * @return array
+ */
+ function makeUnique() {
+ return $this->value = array_unique($this->value);
+ }
+/**
+ * Joins an array with myself using a key (like a join between database tables).
+ *
+ * Example:
+ *
+ * $alice = array('id'=>'1', 'name'=>'Alice');
+ * $bob = array('id'=>'2', 'name'=>'Bob');
+ *
+ * $users = new NeatArray(array($alice, $bob));
+ *
+ * $born = array
+ * (
+ * array('user_id'=>'1', 'born'=>'1980'),
+ * array('user_id'=>'2', 'born'=>'1976')
+ * );
+ *
+ * $users->joinWith($born, 'id', 'user_id');
+ *
+ * Result:
+ *
+ * $users->value == array
+ * (
+ * array('id'=>'1', 'name'=>'Alice', 'born'=>'1980'),
+ * array('id'=>'2', 'name'=>'Bob', 'born'=>'1976')
+ * );
+ *
+ * @param array $his The array to join with myself.
+ * @param string $onMine Key to use on myself.
+ * @param string $onHis Key to use on him.
+ * @return array
+ */
+ function joinWith($his, $onMine, $onHis = null) {
+ if (empty($onHis)) {
+ $onHis = $onMine;
+ }
+ $his = new NeatArray($his);
+ $out = array();
+
+ foreach ($this->value as $key => $val) {
+ if ($fromHis = $his->findIn($onHis, $val[$onMine])) {
+ list($fromHis) = array_values($fromHis);
+ $out[$key] = array_merge($val, $fromHis);
+ } else {
+ $out[$key] = $val;
+ }
+ }
+ return $this->value = $out;
+ }
+/**
+ * Enter description here...
+ * @todo Explain this function. almost looks like it creates a tree
+ *
+ * @param string $root
+ * @param string $idKey
+ * @param string $parentIdKey
+ * @param string $childrenKey
+ * @return array
+ */
+ function threaded($root = null, $idKey = 'id', $parentIdKey = 'parent_id', $childrenKey = 'children') {
+ $out = array();
+ $sizeof = sizeof($this->value);
+
+ for ($ii = 0; $ii < $sizeof; $ii++) {
+ if ($this->value[$ii][$parentIdKey] == $root) {
+ $tmp = $this->value[$ii];
+ $tmp[$childrenKey]=isset($this->value[$ii][$idKey])
+ ? $this->threaded($this->value[$ii][$idKey], $idKey, $parentIdKey, $childrenKey) : null;
+ $out[] = $tmp;
+ }
+ }
+ return $out;
+ }
+/**
+ * Array multi search
+ *
+ * @param string $search_value
+ * @param array $the_array
+ * @return array
+ * @link http://php.net/array_search#47116
+ */
+ function multi_search($search_value, $the_array = null) {
+ if ($the_array == null) {
+ $the_array = $this->value;
+ }
+
+ if (is_array($the_array)) {
+ foreach ($the_array as $key => $value) {
+ $result = $this->multi_search($search_value, $value);
+
+ if (is_array($result)) {
+ $return = $result;
+ array_unshift($return, $key);
+ return $return;
+ } elseif ($result == true) {
+ $return[]=$key;
+ return $return;
+ }
+ }
+ return false;
+ } else {
+ if ($search_value == $the_array) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+ }
+}
+?> \ No newline at end of file
diff --git a/site/cake/libs/neat_string.php b/site/cake/libs/neat_string.php
new file mode 100644
index 0000000..53f011a
--- /dev/null
+++ b/site/cake/libs/neat_string.php
@@ -0,0 +1,88 @@
+<?php
+/* SVN FILE: $Id: neat_string.php 6305 2008-01-02 02:33:56Z phpnut $ */
+/**
+ * String handling methods.
+ *
+ * Random passwords, splitting strings into arrays, removing Cyrillic characters, stripping whitespace.
+ *
+ * PHP versions 4 and 5
+ *
+ * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
+ * Copyright 2005-2008, Cake Software Foundation, Inc.
+ * 1785 E. Sahara Avenue, Suite 490-204
+ * Las Vegas, Nevada 89104
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
+ * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
+ * @package cake
+ * @subpackage cake.cake.libs
+ * @since CakePHP(tm) v 0.2.9
+ * @version $Revision: 6305 $
+ * @modifiedby $LastChangedBy: phpnut $
+ * @lastmodified $Date: 2008-01-01 20:33:56 -0600 (Tue, 01 Jan 2008) $
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+/**
+ * String handling methods.
+ *
+ * Random passwords, splitting strings into arrays, removing Cyrillic characters, stripping whitespace.
+ *
+ * @package cake
+ * @subpackage cake.cake.libs
+ */
+class NeatString{
+/**
+ * Returns an array with each of the non-empty characters in $string as an element.
+ *
+ * @param string $string
+ * @return array
+ */
+ function toArray($string) {
+ $split = preg_split('//', $string, -1, PREG_SPLIT_NO_EMPTY);
+ return $split;
+ }
+/**
+ * Returns string with Cyrillic characters translated to Roman ones.
+ *
+ * @param string $string
+ * @return string
+ */
+ function toRoman($string) {
+ $pl = array('ą','ć','ę','ł','ń','ó','ś','ź','ż','Ą','Ć','Ę','�?','Ń','Ó','Ś','Ź','Ż');
+ $ro = array('a','c','e','l','n','o','s','z','z','A','C','E','L','N','O','S','Z','Z');
+ $replace = str_replace($pl, $ro, $string);
+ return $replace;
+ }
+/**
+ * Returns string as lowercase with whitespace removed.
+ *
+ * @param string $string
+ * @return string
+ */
+ function toCompressed($string) {
+ $whitespace = array("\n", " ", "\r", "\0", "\x0B", " ");
+ $replace = strtolower(str_replace($whitespace, '', $string));
+ return $replace;
+ }
+/**
+ * Returns a random password.
+ *
+ * @param integer $length Length of generated password
+ * @param string $available_chars List of characters to use in password
+ * @return string Generated password
+ */
+ function randomPassword($length, $available_chars = 'ABDEFHKMNPRTWXYABDEFHKMNPRTWXY23456789') {
+ $chars = preg_split('//', $available_chars, -1, PREG_SPLIT_NO_EMPTY);
+ $char_count = count($chars);
+ $out = '';
+ for ($ii = 0; $ii < $length; $ii++) {
+ $out .= $chars[rand(1, $char_count)-1];
+ }
+ return $out;
+ }
+}
+?> \ No newline at end of file
diff --git a/site/cake/libs/object.php b/site/cake/libs/object.php
new file mode 100644
index 0000000..cb522fc
--- /dev/null
+++ b/site/cake/libs/object.php
@@ -0,0 +1,259 @@
+<?php
+/* SVN FILE: $Id: object.php 6305 2008-01-02 02:33:56Z phpnut $ */
+/**
+ * Object class, allowing __construct and __destruct in PHP4.
+ *
+ * Also includes methods for logging and the special method RequestAction,
+ * to call other Controllers' Actions from anywhere.
+ *
+ * PHP versions 4 and 5
+ *
+ * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
+ * Copyright 2005-2008, Cake Software Foundation, Inc.
+ * 1785 E. Sahara Avenue, Suite 490-204
+ * Las Vegas, Nevada 89104
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
+ * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
+ * @package cake
+ * @subpackage cake.cake.libs
+ * @since CakePHP(tm) v 0.2.9
+ * @version $Revision: 6305 $
+ * @modifiedby $LastChangedBy: phpnut $
+ * @lastmodified $Date: 2008-01-01 20:33:56 -0600 (Tue, 01 Jan 2008) $
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+/**
+ * Object class, allowing __construct and __destruct in PHP4.
+ *
+ * Also includes methods for logging and the special method RequestAction,
+ * to call other Controllers' Actions from anywhere.
+ *
+ * @package cake
+ * @subpackage cake.cake.libs
+ */
+class Object{
+/**
+ * Log object
+ *
+ * @var object
+ * @access protected
+ */
+ var $_log = null;
+/**
+ * A hack to support __construct() on PHP 4
+ * Hint: descendant classes have no PHP4 class_name() constructors,
+ * so this constructor gets called first and calls the top-layer __construct()
+ * which (if present) should call parent::__construct()
+ *
+ * @return Object
+ * @access public
+ */
+ function Object() {
+ $args = func_get_args();
+ if (method_exists($this, '__destruct')) {
+ register_shutdown_function (array(&$this, '__destruct'));
+ }
+ call_user_func_array(array(&$this, '__construct'), $args);
+ }
+/**
+ * Class constructor, overridden in descendant classes.
+ *
+ * @abstract
+ * @access public
+ */
+ function __construct() {
+ }
+
+/**
+ * Object-to-string conversion.
+ * Each class can override this method as necessary.
+ *
+ * @return string The name of this class
+ * @access public
+ */
+ function toString() {
+ $class = get_class($this);
+ return $class;
+ }
+/**
+ * Calls a controller's method from any location. Allows for
+ * controllers to communicate with each other.
+ *
+ * @param string $url URL in the form of Cake URL ("/controller/method/parameter")
+ * @param array $extra If array includes the key "return" it sets the AutoRender to true.
+ * @return boolean Success
+ * @access public
+ */
+ function requestAction($url, $extra = array()) {
+ if (!empty($url)) {
+ $dispatcher =& new Dispatcher();
+ if (isset($this->plugin)) {
+ $extra['plugin'] = $this->plugin;
+ }
+ if (in_array('return', $extra, true)) {
+ $extra['return'] = 0;
+ $extra['bare'] = 1;
+ $extra['requested'] = 1;
+ ob_start();
+ $out = $dispatcher->dispatch($url, $extra);
+ $out = ob_get_clean();
+ return $out;
+ } else {
+ $extra['return'] = 1;
+ $extra['bare'] = 1;
+ $extra['requested'] = 1;
+ return $dispatcher->dispatch($url, $extra);
+ }
+ } else {
+ return false;
+ }
+ }
+/**
+ * API for logging events.
+ *
+ * @param string $msg Log message
+ * @param int $type Error type constant. Defined in app/config/core.php.
+ * @access
+ */
+ function log($msg, $type = LOG_ERROR) {
+ if (!class_exists('CakeLog')) {
+ uses('cake_log');
+ }
+
+ if (is_null($this->_log)) {
+ $this->_log = new CakeLog();
+ }
+
+ if (!is_string($msg)) {
+ ob_start();
+ print_r ($msg);
+ $msg=ob_get_contents();
+ ob_end_clean();
+ }
+
+ switch($type) {
+ case LOG_DEBUG:
+ return $this->_log->write('debug', $msg);
+ break;
+ default:
+ return $this->_log->write('error', $msg);
+ break;
+ }
+ }
+/**
+ * Used to report user friendly errors.
+ * If there is a file app/error.php this file will be loaded
+ * error.php is the AppError class it should extend ErrorHandler class.
+ *
+ * @param string $method Method to be called in the error class (AppError or ErrorHandler classes)
+ * @param array $messages Message that is to be displayed by the error class
+ * @return error message
+ * @access public
+ */
+ function cakeError($method, $messages) {
+ if (!class_exists('ErrorHandler')) {
+ uses('error');
+ if (file_exists(APP . 'error.php')) {
+ include_once (APP . 'error.php');
+ }
+ }
+
+ if (class_exists('AppError')) {
+ $error = new AppError($method, $messages);
+ } else {
+ $error = new ErrorHandler($method, $messages);
+ }
+ return $error;
+ }
+/**
+ * Checks for a persistent class file, if found file is opened and true returned
+ * If file is not found a file is created and false returned
+ *
+ * There are many uses for this method, see manual for examples also art of
+ * the cache system
+ *
+ * @param string $name name of class to persist
+ * @param boolean $return
+ * @param object $object
+ * @param string $type
+ * @return boolean
+ * @todo add examples to manual
+ * @access protected
+ */
+ function _persist($name, $return = null, &$object, $type = null) {
+ $file = CACHE . 'persistent' . DS . strtolower($name) . '.php';
+ if ($return === null) {
+ if (!file_exists($file)) {
+ return false;
+ } else {
+ return true;
+ }
+ }
+
+ if (!file_exists($file)) {
+ $this->_savePersistent($name, $object);
+ return false;
+ } else {
+ $this->__openPersistent($name, $type);
+ return true;
+ }
+ }
+/**
+ * You should choose a unique name for the persistent file
+ *
+ * There are many uses for this method, see manual for examples also part of
+ * the cache system
+ *
+ * @param string $name name used for object to cache
+ * @param object $object the object to persist
+ * @return true on save, throws error if file can not be created
+ * @access protected
+ */
+ function _savePersistent($name, &$object) {
+ $file = 'persistent' . DS . strtolower($name) . '.php';
+ $objectArray = array(&$object);
+ $data = str_replace('\\', '\\\\', serialize($objectArray));
+ $data = '<?php $' . $name . ' = \'' . str_replace('\'', '\\\'', $data) . '\' ?>';
+ cache($file, $data, '+1 day');
+ }
+/**
+ * Open the persistent class file for reading
+ * Used by Object::_persist(), part of the cache
+ * system
+ *
+ * @param string $name Name of the persistant file
+ * @param string $type
+ * @access private
+ */
+ function __openPersistent($name, $type = null) {
+ $file = CACHE . 'persistent' . DS . strtolower($name) . '.php';
+ include($file);
+
+ switch($type) {
+ case 'registry':
+ $vars = unserialize(${$name});
+ foreach ($vars['0'] as $key => $value) {
+ loadModel(Inflector::classify($key));
+ }
+ unset($vars);
+ $vars = unserialize(${$name});
+ foreach ($vars['0'] as $key => $value) {
+ ClassRegistry::addObject($key, $value);
+ unset ($value);
+ }
+ unset($vars);
+ break;
+ default:
+ $vars = unserialize(${$name});
+ $this->{$name} = $vars['0'];
+ unset($vars);
+ break;
+ }
+ }
+}
+?> \ No newline at end of file
diff --git a/site/cake/libs/router.php b/site/cake/libs/router.php
new file mode 100644
index 0000000..143fa2b
--- /dev/null
+++ b/site/cake/libs/router.php
@@ -0,0 +1,230 @@
+<?php
+/* SVN FILE: $Id: router.php 6305 2008-01-02 02:33:56Z phpnut $ */
+/**
+ * Parses the request URL into controller, action, and parameters.
+ *
+ * PHP versions 4 and 5
+ *
+ * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
+ * Copyright 2005-2008, Cake Software Foundation, Inc.
+ * 1785 E. Sahara Avenue, Suite 490-204
+ * Las Vegas, Nevada 89104
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
+ * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
+ * @package cake
+ * @subpackage cake.cake.libs
+ * @since CakePHP(tm) v 0.2.9
+ * @version $Revision: 6305 $
+ * @modifiedby $LastChangedBy: phpnut $
+ * @lastmodified $Date: 2008-01-01 20:33:56 -0600 (Tue, 01 Jan 2008) $
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+/**
+ * Included libraries.
+ *
+ */
+ if (!class_exists('Object')) {
+ uses ('object');
+ }
+/**
+ * Parses the request URL into controller, action, and parameters.
+ *
+ * @package cake
+ * @subpackage cake.cake.libs
+ */
+class Router extends Object {
+/**
+ * Array of routes
+ *
+ * @var array
+ * @access public
+ */
+ var $routes = array();
+/**
+ * CAKE_ADMIN route
+ *
+ * @var array
+ * @access private
+ */
+ var $__admin = null;
+/**
+ * Constructor
+ *
+ * @access public
+ */
+ function __construct() {
+ if (defined('CAKE_ADMIN')) {
+ $admin = CAKE_ADMIN;
+ if (!empty($admin)) {
+ $this->__admin = array('/:' . $admin . '/:controller/:action/* (default)',
+ '/^(?:\/(?:(' . $admin . ')(?:\\/([a-zA-Z0-9_\\-\\.\\;\\:]+)(?:\\/([a-zA-Z0-9_\\-\\.\\;\\:]+)(?:[\\/\\?](.*))?)?)?))[\/]*$/',
+ array($admin, 'controller', 'action'), array());
+ }
+ }
+ }
+/**
+ * Returns this object's routes array. Returns false if there are no routes available.
+ *
+ * @param string $route An empty string, or a route string "/"
+ * @param array $default NULL or an array describing the default route
+ * @return array Array of routes
+ */
+ function connect($route, $default = null) {
+ $parsed = $names = array();
+
+ if (defined('CAKE_ADMIN') && $default == null) {
+ if ($route == CAKE_ADMIN) {
+ $this->routes[] = $this->__admin;
+ $this->__admin = null;
+ }
+ }
+ $r = null;
+ if (($route == '') || ($route == '/')) {
+ $regexp='/^[\/]*$/';
+ $this->routes[] = array($route, $regexp, array(), $default);
+ } else {
+ $elements = array();
+
+ foreach (explode('/', $route)as $element) {
+ if (trim($element))
+ $elements[] = $element;
+ }
+
+ if (!count($elements)) {
+ return false;
+ }
+
+ foreach ($elements as $element) {
+
+ if (preg_match('/^:(.+)$/', $element, $r)) {
+ $parsed[]='(?:\/([^\/]+))?';
+ $names[] =$r[1];
+ } elseif (preg_match('/^\*$/', $element, $r)) {
+ $parsed[] = '(?:\/(.*))?';
+ } else {
+ $parsed[] = '/' . $element;
+ }
+ }
+
+ $regexp='#^' . join('', $parsed) . '[\/]*$#';
+ $this->routes[] = array($route, $regexp, $names, $default);
+ }
+ return $this->routes;
+ }
+/**
+ * Parses given URL and returns an array of controllers, action and parameters
+ * taken from that URL.
+ *
+ * @param string $url URL to be parsed
+ * @return array
+ * @access public
+ */
+ function parse($url) {
+ if (ini_get('magic_quotes_gpc') == 1) {
+ $url = stripslashes_deep($url);
+ }
+
+ if ($url && ('/' != $url[0])) {
+ if (!defined('SERVER_IIS')) {
+ $url = '/' . $url;
+ }
+ }
+ $out = array('pass'=>array());
+ $r = null;
+ $default_route = array('/:controller/:action/* (default)',
+ '/^(?:\/(?:([a-zA-Z0-9_\\-\\.\\;\\:]+)(?:\\/([a-zA-Z0-9_\\-\\.\\;\\:]+)(?:[\\/\\?](.*))?)?))[\\/]*$/',
+ array('controller', 'action'), array());
+
+ if (defined('CAKE_ADMIN') && $this->__admin != null) {
+ $this->routes[]=$this->__admin;
+ $this->__admin =null;
+ }
+ $this->connect('/bare/:controller/:action/*', array('bare' => '1'));
+ $this->connect('/ajax/:controller/:action/*', array('bare' => '1'));
+
+ if (defined('WEBSERVICES') && WEBSERVICES == 'on') {
+ $this->connect('/rest/:controller/:action/*', array('webservices' => 'Rest'));
+ $this->connect('/rss/:controller/:action/*', array('webservices' => 'Rss'));
+ $this->connect('/soap/:controller/:action/*', array('webservices' => 'Soap'));
+ $this->connect('/xml/:controller/:action/*', array('webservices' => 'Xml'));
+ $this->connect('/xmlrpc/:controller/:action/*', array('webservices' => 'XmlRpc'));
+ }
+ $this->routes[] = $default_route;
+
+ if (strpos($url, '?') !== false) {
+ $url = substr($url, 0, strpos($url, '?'));
+ }
+
+ foreach ($this->routes as $route) {
+ list($route, $regexp, $names, $defaults) = $route;
+
+ if (preg_match($regexp, $url, $r)) {
+ // remove the first element, which is the url
+ array_shift ($r);
+ // hack, pre-fill the default route names
+ foreach ($names as $name) {
+ $out[$name] = null;
+ }
+ $ii=0;
+
+ if (is_array($defaults)) {
+ foreach ($defaults as $name => $value) {
+ if (preg_match('#[a-zA-Z_\-]#i', $name)) {
+ $out[$name] = $this->stripEscape($value);
+ } else {
+ $out['pass'][] = $this->stripEscape($value);
+ }
+ }
+ }
+
+ foreach ($r as $found) {
+ // if $found is a named url element (i.e. ':action')
+ if (isset($names[$ii])) {
+ $out[$names[$ii]] = $found;
+ } else {
+ // unnamed elements go in as 'pass'
+ $found = explode('/', $found);
+ $pass = array();
+ foreach ($found as $key => $value) {
+ if ($value == "0") {
+ $pass[$key] = $this->stripEscape($value);
+ } elseif ($value) {
+ $pass[$key] = $this->stripEscape($value);
+ }
+ }
+ $out['pass'] = am($out['pass'], $pass);
+ }
+ $ii++;
+ }
+ break;
+ }
+ }
+ return $out;
+ }
+ function stripEscape($param) {
+ if (!is_array($param) || empty($param)) {
+ if (is_bool($param)) {
+ return $param;
+ }
+
+ $return = preg_replace('/^[\\t ]*(?:-!)+/', '', $param);
+ return $return;
+ }
+ foreach ($param as $key => $value) {
+ if (is_string($value)) {
+ $return[$key] = preg_replace('/^[\\t ]*(?:-!)+/', '', $value);
+ } else {
+ foreach ($value as $array => $string) {
+ $return[$key][$array] = $this->stripEscape($string);
+ }
+ }
+ }
+ return $return;
+ }
+}
+?> \ No newline at end of file
diff --git a/site/cake/libs/sanitize.php b/site/cake/libs/sanitize.php
new file mode 100644
index 0000000..81941ff
--- /dev/null
+++ b/site/cake/libs/sanitize.php
@@ -0,0 +1,245 @@
+<?php
+/* SVN FILE: $Id: sanitize.php 6305 2008-01-02 02:33:56Z phpnut $ */
+/**
+ * Washes strings from unwanted noise.
+ *
+ * Helpful methods to make unsafe strings usable.
+ *
+ * PHP versions 4 and 5
+ *
+ * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
+ * Copyright 2005-2008, Cake Software Foundation, Inc.
+ * 1785 E. Sahara Avenue, Suite 490-204
+ * Las Vegas, Nevada 89104
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
+ * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
+ * @package cake
+ * @subpackage cake.cake.libs
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @version $Revision: 6305 $
+ * @modifiedby $LastChangedBy: phpnut $
+ * @lastmodified $Date: 2008-01-01 20:33:56 -0600 (Tue, 01 Jan 2008) $
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+/**
+ * Data Sanitization.
+ *
+ * Removal of alpahnumeric characters, SQL-safe slash-added strings, HTML-friendly strings,
+ * and all of the above on arrays.
+ *
+ * @package cake
+ * @subpackage cake.cake.libs
+ */
+class Sanitize{
+/**
+ * Removes any non-alphanumeric characters.
+ *
+ * @param string $string
+ * @return string
+ * @access public
+ */
+ function paranoid($string, $allowed = array()) {
+ $allow = null;
+ if (!empty($allowed)) {
+ foreach ($allowed as $value) {
+ $allow .= "\\$value";
+ }
+ }
+
+ if (is_array($string)) {
+ foreach ($string as $key => $clean) {
+ $cleaned[$key] = preg_replace("/[^{$allow}a-zA-Z0-9]/", "", $clean);
+ }
+ } else {
+ $cleaned = preg_replace("/[^{$allow}a-zA-Z0-9]/", "", $string);
+ }
+ return $cleaned;
+ }
+/**
+ * Makes a string SQL-safe by adding slashes (if needed).
+ *
+ * @param string $string
+ * @return string
+ * @access public
+ */
+ function sql($string) {
+ if (!ini_get('magic_quotes_gpc')) {
+ $string = addslashes($string);
+ }
+ return $string;
+ }
+/**
+ * Returns given string safe for display as HTML. Renders entities.
+ *
+ * @param string $string
+ * @param boolean $remove If true, the string is stripped of all HTML tags
+ * @return string
+ * @access public
+ */
+ function html($string, $remove = false) {
+ if ($remove) {
+ $string = strip_tags($string);
+ } else {
+ $patterns = array("/\&/", "/%/", "/</", "/>/", '/"/', "/'/", "/\(/", "/\)/", "/\+/", "/-/");
+ $replacements = array("&amp;", "&#37;", "&lt;", "&gt;", "&quot;", "&#39;", "&#40;", "&#41;", "&#43;", "&#45;");
+ $string = preg_replace($patterns, $replacements, $string);
+ }
+ return $string;
+ }
+/**
+ * Recursively sanitizes given array of data for safe input.
+ *
+ * @param mixed $toClean
+ * @return mixed
+ * @access public
+ */
+ function cleanArray(&$toClean) {
+ return $this->cleanArrayR($toClean);
+ }
+/**
+ * Method used for recursively sanitizing arrays of data
+ * for safe input
+ *
+ * @param array $toClean
+ * @return array The clean array
+ * @access public
+ */
+ function cleanArrayR(&$toClean) {
+ if (is_array($toClean)) {
+ while (list($k, $v) = each($toClean)) {
+ if (is_array($toClean[$k])) {
+ $this->cleanArray($toClean[$k]);
+ } else {
+ $toClean[$k] = $this->cleanValue($v);
+ }
+ }
+ } else {
+ return null;
+ }
+ }
+/**
+ * Do we really need to sanitize array keys? If so, we can use this code...
+ function cleanKey($key) {
+ if ($key == "")
+ {
+ return "";
+ }
+ //URL decode and convert chars to HTML entities
+ $key = htmlspecialchars(urldecode($key));
+ //Remove ..
+ $key = preg_replace( "/\.\./", "", $key );
+ //Remove __FILE__, etc.
+ $key = preg_replace( "/\_\_(.+?)\_\_/", "", $key );
+ //Trim word chars, '.', '-', '_'
+ $key = preg_replace( "/^([\w\.\-\_]+)$/", "$1", $key );
+ return $key;
+ }
+ */
+
+/**
+ * Method used by cleanArray() to sanitize array nodes.
+ *
+ * @param string $val
+ * @return string
+ * @access public
+ */
+ function cleanValue($val) {
+ if ($val == "") {
+ return "";
+ }
+ //Replace odd spaces with safe ones
+ $val = str_replace(" ", " ", $val);
+ $val = str_replace(chr(0xCA), "", $val);
+ //Encode any HTML to entities.
+ $val = $this->html($val);
+ //Double-check special chars and replace carriage returns with new lines
+ $val = preg_replace("/\\\$/", "$", $val);
+ $val = preg_replace("/\r\n/", "\n", $val);
+ $val = str_replace("!", "!", $val);
+ $val = str_replace("'", "'", $val);
+ //Allow unicode (?)
+ $val = preg_replace("/&amp;#([0-9]+);/s", "&#\\1;", $val);
+ //Add slashes for SQL
+ $val = $this->sql($val);
+ //Swap user-inputted backslashes (?)
+ $val = preg_replace("/\\\(?!&amp;#|\?#)/", "\\", $val);
+ return $val;
+ }
+
+/**
+ * Formats column data from definition in DBO's $columns array
+ *
+ * @param Model $model The model containing the data to be formatted
+ * @return void
+ * @access public
+ */
+ function formatColumns(&$model) {
+ foreach ($model->data as $name => $values) {
+ if ($name == $model->name) {
+ $curModel =& $model;
+ } elseif (isset($model->{$name}) && is_object($model->{$name}) && is_subclass_of($model->{$name}, 'Model')) {
+ $curModel =& $model->{$name};
+ } else {
+ $curModel = null;
+ }
+
+ if ($curModel != null) {
+ foreach ($values as $column => $data) {
+ $colType = $curModel->getColumnType($column);
+
+ if ($colType != null) {
+ $db =& ConnectionManager::getDataSource($curModel->useDbConfig);
+ $colData = $db->columns[$colType];
+
+ if (isset($colData['limit']) && strlen(strval($data)) > $colData['limit']) {
+ $data = substr(strval($data), 0, $colData['limit']);
+ }
+
+ if (isset($colData['formatter']) || isset($colData['format'])) {
+
+ switch(strtolower($colData['formatter'])) {
+ case 'date':
+ $data = date($colData['format'], strtotime($data));
+ break;
+ case 'sprintf':
+ $data = sprintf($colData['format'], $data);
+ break;
+ case 'intval':
+ $data = intval($data);
+ break;
+ case 'floatval':
+ $data = floatval($data);
+ break;
+ }
+ }
+ $model->data[$name][$column]=$data;
+ /*
+ switch($colType) {
+ case 'integer':
+ case 'int':
+ return $data;
+ break;
+ case 'string':
+ case 'text':
+ case 'binary':
+ case 'date':
+ case 'time':
+ case 'datetime':
+ case 'timestamp':
+ case 'date':
+ return "'" . $data . "'";
+ break;
+ }
+ */
+ }
+ }
+ }
+ }
+ }
+}
+?> \ No newline at end of file
diff --git a/site/cake/libs/security.php b/site/cake/libs/security.php
new file mode 100644
index 0000000..4c1a559
--- /dev/null
+++ b/site/cake/libs/security.php
@@ -0,0 +1,151 @@
+<?php
+/* SVN FILE: $Id: security.php 6305 2008-01-02 02:33:56Z phpnut $ */
+/**
+ * Security Class
+ *
+ * This class is a singleton class that contains
+ * functions for hasing and security.
+ *
+ * PHP versions 4 and 5
+ *
+ * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
+ * Copyright 2005-2008, Cake Software Foundation, Inc.
+ * 1785 E. Sahara Avenue, Suite 490-204
+ * Las Vegas, Nevada 89104
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
+ * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
+ * @package cake
+ * @subpackage cake.cake.libs
+ * @since CakePHP(tm) v .0.10.0.1233
+ * @version $Revision: 6305 $
+ * @modifiedby $LastChangedBy: phpnut $
+ * @lastmodified $Date: 2008-01-01 20:33:56 -0600 (Tue, 01 Jan 2008) $
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+/**
+ * Security Class
+ *
+ * This class is a singleton class that contains functions for hasing and security.
+ *
+ * @package cake
+ * @subpackage cake.cake.libs
+ */
+class Security extends Object {
+/**
+ * Singleton method to retrieve the instance of the Security class
+ *
+ * @return object Security
+ * @access public
+ */
+ function &getInstance() {
+ static $instance = array();
+ if (!$instance) {
+ $instance[0] = &new Security;
+ }
+ return $instance[0];
+ }
+/**
+ * Returns inactive minutes constant based on cake the security level
+ *
+ * @return integer
+ * @access public
+ */
+ function inactiveMins() {
+ switch(CAKE_SECURITY) {
+ case 'high':
+ return 10;
+ break;
+ case 'medium':
+ return 100;
+ break;
+ case 'low':
+ default:
+ return 300;
+ break;
+ }
+ }
+/**
+ * Generates a unique authkey
+ *
+ * @return mixed
+ * @access public
+ */
+ function generateAuthKey() {
+ $_this =& Security::getInstance();
+ return $_this->hash(uniqid(rand(), true));
+ }
+/**
+ * Validates the authkey
+ *
+ * @param mixed $authKey
+ * @return boolean
+ * @access public
+ */
+ function validateAuthKey($authKey) {
+ return true;
+ }
+/**
+ * Generates a hash of a string using a php built in hashing function
+ *
+ * @param string $string The string to be hashed
+ * @param string $type The hashing algorithm
+ * @return string
+ * @access public
+ */
+ function hash($string, $type = 'sha1') {
+ $type = strtolower($type);
+ if ($type == 'sha1') {
+ if (function_exists('sha1')) {
+ $return = sha1($string);
+ return $return;
+ } else {
+ $type = 'sha256';
+ }
+ }
+
+ if ($type == 'sha256') {
+ if (function_exists('mhash')) {
+ $return = bin2hex(mhash(MHASH_SHA256, $string));
+ return $return;
+ } else {
+ $type = 'md5';
+ }
+ }
+
+ if ($type == 'md5') {
+ $return = md5($string);
+ return $return;
+ }
+ }
+/**
+ * Function that ciphers a text using a key
+ *
+ * @param string $text
+ * @param string $key
+ * @return string
+ * @access public
+ */
+ function cipher($text, $key) {
+ if (!defined('CIPHER_SEED')) {
+ //This is temporary will change later
+ define('CIPHER_SEED', '76859309657453542496749683645');
+ }
+ srand (CIPHER_SEED);
+ $out = '';
+
+ for ($i = 0; $i < strlen($text); $i++) {
+ for ($j = 0; $j < ord(substr($key, $i % strlen($key), 1)); $j++) {
+ $toss = rand(0, 255);
+ }
+ $mask = rand(0, 255);
+ $out .= chr(ord(substr($text, $i, 1)) ^ $mask);
+ }
+ return $out;
+ }
+}
+?> \ No newline at end of file
diff --git a/site/cake/libs/session.php b/site/cake/libs/session.php
new file mode 100644
index 0000000..cab0498
--- /dev/null
+++ b/site/cake/libs/session.php
@@ -0,0 +1,777 @@
+<?php
+/* SVN FILE: $Id: session.php 6305 2008-01-02 02:33:56Z phpnut $ */
+/**
+ * Session class for Cake.
+ *
+ * Cake abstracts the handling of sessions.
+ * There are several convenient methods to access session information.
+ * This class is the implementation of those methods.
+ * They are mostly used by the Session Component.
+ *
+ * PHP versions 4 and 5
+ *
+ * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
+ * Copyright 2005-2008, Cake Software Foundation, Inc.
+ * 1785 E. Sahara Avenue, Suite 490-204
+ * Las Vegas, Nevada 89104
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
+ * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
+ * @package cake
+ * @subpackage cake.cake.libs
+ * @since CakePHP(tm) v .0.10.0.1222
+ * @version $Revision: 6305 $
+ * @modifiedby $LastChangedBy: phpnut $
+ * @lastmodified $Date: 2008-01-01 20:33:56 -0600 (Tue, 01 Jan 2008) $
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+/**
+ * Database name for cake sessions.
+ *
+ */
+ if (!defined('CAKE_SESSION_TABLE')) {
+ define('CAKE_SESSION_TABLE', 'cake_sessions');
+ }
+
+ if (CAKE_SESSION_SAVE === 'database') {
+ uses('model' . DS . 'connection_manager');
+ }
+ uses('set');
+/**
+ * Session class for Cake.
+ *
+ * Cake abstracts the handling of sessions. There are several convenient methods to access session information.
+ * This class is the implementation of those methods. They are mostly used by the Session Component.
+ *
+ * @package cake
+ * @subpackage cake.cake.libs
+ */
+class CakeSession extends Object {
+/**
+ * True if the Session is still valid
+ *
+ * @var boolean
+ * @access public
+ */
+ var $valid = false;
+/**
+ * Error messages for this session
+ *
+ * @var array
+ * @access public
+ */
+ var $error = false;
+/**
+ * User agent string
+ *
+ * @var string
+ * @access protected
+ */
+ var $_userAgent = '';
+/**
+ * Path to where the session is active.
+ *
+ * @var string
+ * @access public
+ */
+ var $path = false;
+/**
+ * Error number of last occurred error
+ *
+ * @var integer
+ * @access public
+ */
+ var $lastError = null;
+/**
+ * CAKE_SECURITY setting, "high", "medium", or "low".
+ *
+ * @var string
+ * @access public
+ */
+ var $security = null;
+/**
+ * Start time for this session.
+ *
+ * @var integer
+ * @access public
+ */
+ var $time = false;
+/**
+ * Time when this session becomes invalid.
+ *
+ * @var integer
+ * @access public
+ */
+ var $sessionTime = false;
+/**
+ * Keeps track of keys to watch for writes on
+ *
+ * @var array
+ * @access public
+ */
+ var $watchKeys = array();
+/**
+ * Current Session id
+ *
+ * @var string
+ * @access public
+ */
+ var $id = null;
+/**
+ * Constructor.
+ *
+ * @param string $base The base path for the Session
+ * @param boolean $start Should session be started right now
+ * @access public
+ */
+ function __construct($base = null, $start = true) {
+ if (Configure::read('Session.checkAgent') === true) {
+ if (env('HTTP_USER_AGENT') != null) {
+ $this->_userAgent = md5(env('HTTP_USER_AGENT') . CAKE_SESSION_STRING);
+ }
+ }
+ $this->time = time();
+
+ if ($start === true) {
+ $this->host = env('HTTP_HOST');
+
+ if (empty($base) || strpos($base, '?') === 0 || strpos($base, 'index.php') === 0) {
+ $this->path = '/';
+ } else {
+ $this->path = $base;
+ }
+
+ if (strpos($this->host, ':') !== false) {
+ $this->host = substr($this->host, 0, strpos($this->host, ':'));
+ }
+
+ $this->sessionTime = $this->time + (Security::inactiveMins() * CAKE_SESSION_TIMEOUT);
+ $this->security = CAKE_SECURITY;
+ }
+ parent::__construct();
+ }
+/**
+ * Starts the Session.
+ *
+ * @param string $cookieLifeTime How long for the cookie
+ * @return boolean True if variable is there
+ * @access public
+ */
+ /** BEGIN MOZILLA PATCH (@author rdoherty@mozilla.com)**/
+ function start($cookieLifeTime = null) {
+ if (function_exists('session_write_close')) {
+ session_write_close();
+ }
+
+ $this->__initSession($cookieLifeTime);
+ /** END MOZILLA PATCH **/
+ return $this->__startSession();
+ }
+/**
+ * Determine if Session has been started.
+ *
+ * @access public
+ */
+ function started(){
+ if (isset($_SESSION)) {
+ return true;
+ }
+ return false;
+ }
+/**
+ * Returns true if given variable is set in session.
+ *
+ * @param string $name Variable name to check for
+ * @return boolean True if variable is there
+ * @access public
+ */
+ function check($name) {
+ $var = $this->__validateKeys($name);
+ if (empty($var)) {
+ return false;
+ }
+ $result = Set::extract($_SESSION, $var);
+ return isset($result);
+ }
+/**
+ *
+ * @param id $name string
+ * @return string Session id
+ * @access public
+ */
+ function id($id = null) {
+ if ($id) {
+ $this->id = $id;
+ session_id($this->id);
+ }
+ if (isset($_SESSION)) {
+ return session_id();
+ } else {
+ return $this->id;
+ }
+ }
+/**
+ * Temp method until we are able to remove the last eval().
+ * Builds an expression to fetch a session variable with specified name.
+ *
+ * @param string $name Name of variable (in dot notation)
+ * @access private
+ */
+ function __sessionVarNames($name) {
+ if (is_string($name) && preg_match("/^[ 0-9a-zA-Z._-]*$/", $name)) {
+ if (strpos($name, ".")) {
+ $names = explode(".", $name);
+ } else {
+ $names = array($name);
+ }
+ $expression = "\$_SESSION";
+ foreach ($names as $item) {
+ $expression .= is_numeric($item) ? "[$item]" : "['$item']";
+ }
+ return $expression;
+ }
+ $this->__setError(3, "$name is not a string");
+ return false;
+ }
+/**
+ * Removes a variable from session.
+ *
+ * @param string $name Session variable to remove
+ * @return boolean Success
+ * @access public
+ */
+ function del($name) {
+ if ($this->check($name)) {
+ if ($var = $this->__validateKeys($name)) {
+ if (in_array($var, $this->watchKeys)) {
+ trigger_error('Deleting session key {' . $var . '}', E_USER_NOTICE);
+ }
+ $this->__overwrite($_SESSION, Set::remove($_SESSION, $var));
+ return ($this->check($var) == false);
+ }
+ }
+ $this->__setError(2, "$name doesn't exist");
+ return false;
+ }
+/**
+ * Used to write new data to _SESSION, since PHP doesn't like us setting the _SESSION var itself
+ *
+ * @param array $old Set of old variables => values
+ * @param array $new New set of variable => value
+ * @access private
+ */
+ function __overwrite(&$old, $new) {
+ if(!empty($old)) {
+ foreach ($old as $key => $var) {
+ if (!isset($new[$key])) {
+ unset($old[$key]);
+ }
+ }
+ }
+ foreach ($new as $key => $var) {
+ $old[$key] = $var;
+ }
+ }
+/**
+ * Return error description for given error number.
+ *
+ * @param integer $errorNumber Error to set
+ * @return string Error as string
+ * @access private
+ */
+ function __error($errorNumber) {
+ if (!is_array($this->error) || !array_key_exists($errorNumber, $this->error)) {
+ return false;
+ } else {
+ return $this->error[$errorNumber];
+ }
+ }
+/**
+ * Returns last occurred error as a string, if any.
+ *
+ * @return mixed Error description as a string, or false.
+ * @access public
+ */
+ function error() {
+ if ($this->lastError) {
+ return $this->__error($this->lastError);
+ } else {
+ return false;
+ }
+ }
+/**
+ * Returns true if session is valid.
+ *
+ * @return boolean Success
+ * @access public
+ */
+ function valid() {
+ if ($this->read('Config')) {
+ if (Configure::read('Session.checkAgent') === false || $this->_userAgent == $this->read("Config.userAgent") && $this->time <= $this->read("Config.time")) {
+ if ($this->error === false) {
+ $this->valid = true;
+ }
+ } else {
+ $this->valid = false;
+ $this->__setError(1, "Session Highjacking Attempted !!!");
+ }
+ }
+ return $this->valid;
+ }
+/**
+ * Returns given session variable, or all of them, if no parameters given.
+ *
+ * @param mixed $name The name of the session variable (or a path as sent to Set.extract)
+ * @return mixed The value of the session variable
+ * @access public
+ */
+ function read($name = null) {
+ if (is_null($name)) {
+ return $this->__returnSessionVars();
+ }
+ if (empty($name)) {
+ return false;
+ }
+ $result = Set::extract($_SESSION, $name);
+
+ if (!is_null($result)) {
+ return $result;
+ }
+ $this->__setError(2, "$name doesn't exist");
+ return null;
+ }
+/**
+ * Returns all session variables.
+ *
+ * @return mixed Full $_SESSION array, or false on error.
+ * @access private
+ */
+ function __returnSessionVars() {
+ if (!empty($_SESSION)) {
+ return $_SESSION;
+ }
+ $this->__setError(2, "No Session vars set");
+ return false;
+ }
+/**
+ * Tells Session to write a notification when a certain session path or subpath is written to
+ *
+ * @param mixed $var The variable path to watch
+ * @access public
+ */
+ function watch($var) {
+ $var = $this->__validateKeys($var);
+ if (empty($var)) {
+ return false;
+ }
+ $this->watchKeys[] = $var;
+ }
+/**
+ * Tells Session to stop watching a given key path
+ *
+ * @param mixed $var The variable path to watch
+ * @access public
+ */
+ function ignore($var) {
+ $var = $this->__validateKeys($var);
+ if (!in_array($var, $this->watchKeys)) {
+ return;
+ }
+ foreach ($this->watchKeys as $i => $key) {
+ if ($key == $var) {
+ unset($this->watchKeys[$i]);
+ $this->watchKeys = array_values($this->watchKeys);
+ return;
+ }
+ }
+ }
+/**
+ * Writes value to given session variable name.
+ *
+ * @param mixed $name Name of variable
+ * @param string $value Value to write
+ * @return boolean True if the write was successful, false if the write failed
+ * @access public
+ */
+ function write($name, $value) {
+ $var = $this->__validateKeys($name);
+
+ if (empty($var)) {
+ return false;
+ }
+ if (in_array($var, $this->watchKeys)) {
+ trigger_error('Writing session key {' . $var . '}: ' . print_r($value), E_USER_NOTICE);
+ }
+ $this->__overwrite($_SESSION, Set::insert($_SESSION, $var, $value));
+ return (Set::extract($_SESSION, $var) === $value);
+ }
+/**
+ * Helper method to destroy invalid sessions.
+ *
+ * @access public
+ */
+ function destroy() {
+ $sessionpath = session_save_path();
+ if (empty($sessionpath)) {
+ $sessionpath = "/tmp";
+ }
+
+ if (isset($_COOKIE[session_name()])) {
+ setcookie(CAKE_SESSION_COOKIE, '', time() - 42000, $this->path);
+ }
+
+ $_SESSION = array();
+ $file = $sessionpath . DS . "sess_" . session_id();
+ @session_destroy();
+ @unlink ($file);
+ $this->__construct($this->path);
+ $this->renew();
+ }
+/**
+ * Helper method to initialize a session, based on Cake core settings.
+ *
+ * @param int $cookieLifeTime how long the cookie should live in seconds
+ * @access private
+ */
+ /** BEGIN MOZILLA PATCH (@author rdoherty@mozilla.com)**/
+ function __initSession($cookieLifeTime = null) {
+ /** END MOZILLA PATCH (@author clouserw@mozilla.com)**/
+ switch($this->security) {
+ case 'high':
+ $this->cookieLifeTime = 0;
+ if (function_exists('ini_set')) {
+ ini_set('session.referer_check', $this->host);
+ }
+ break;
+ case 'medium':
+ $this->cookieLifeTime = 7 * 86400;
+ if (function_exists('ini_set')) {
+ ini_set('session.referer_check', $this->host);
+ }
+ break;
+ case 'low':
+ default:
+ $this->cookieLifeTime = 788940000;
+ break;
+ }
+
+ /** BEGIN MOZILLA PATCH (@author rdoherty@mozilla.com)**/
+ if($cookieLifeTime) {
+ $this->cookieLifeTime = $cookieLifeTime;
+ }
+ /** END MOZILLA PATCH **/
+
+ switch(CAKE_SESSION_SAVE) {
+ case 'cake':
+ if (!isset($_SESSION)) {
+ if (function_exists('ini_set')) {
+ ini_set('session.use_trans_sid', 0);
+ ini_set('url_rewriter.tags', '');
+ ini_set('session.serialize_handler', 'php');
+ ini_set('session.use_cookies', 1);
+ ini_set('session.name', CAKE_SESSION_COOKIE);
+ ini_set('session.cookie_lifetime', $this->cookieLifeTime);
+ ini_set('session.cookie_path', $this->path);
+ ini_set('session.auto_start', 0);
+ ini_set('session.save_path', TMP . 'sessions');
+ }
+ }
+ break;
+ case 'database':
+ if (!isset($_SESSION)) {
+ if (function_exists('ini_set')) {
+ ini_set('session.use_trans_sid', 0);
+ ini_set('url_rewriter.tags', '');
+ ini_set('session.save_handler', 'user');
+ ini_set('session.serialize_handler', 'php');
+ ini_set('session.use_cookies', 1);
+ ini_set('session.name', CAKE_SESSION_COOKIE);
+ ini_set('session.cookie_lifetime', $this->cookieLifeTime);
+ ini_set('session.cookie_path', $this->path);
+ ini_set('session.auto_start', 0);
+ }
+ }
+ session_set_save_handler(array('CakeSession','__open'),
+ array('CakeSession', '__close'),
+ array('CakeSession', '__read'),
+ array('CakeSession', '__write'),
+ array('CakeSession', '__destroy'),
+ array('CakeSession', '__gc'));
+ break;
+ case 'php':
+ if (!isset($_SESSION)) {
+ if (function_exists('ini_set')) {
+ ini_set('session.use_trans_sid', 0);
+ ini_set('session.name', CAKE_SESSION_COOKIE);
+ ini_set('session.cookie_lifetime', $this->cookieLifeTime);
+ ini_set('session.cookie_path', $this->path);
+ }
+ }
+ break;
+ default:
+ if (!isset($_SESSION)) {
+ $config = CONFIGS . CAKE_SESSION_SAVE . '.php';
+
+ if (is_file($config)) {
+ require_once ($config);
+ }
+ }
+ break;
+ }
+ }
+/**
+ * Helper method to start a session
+ *
+ * @access private
+ */
+ function __startSession() {
+ if (headers_sent()) {
+ if (!isset($_SESSION)) {
+ $_SESSION = array();
+ }
+ return false;
+ } elseif (!isset($_SESSION)) {
+ session_cache_limiter ("must-revalidate");
+ session_start();
+ header ('P3P: CP="NOI ADM DEV PSAi COM NAV OUR OTRo STP IND DEM"');
+ return true;
+ } else {
+ return true;
+ }
+ }
+/**
+ * Helper method to create a new session.
+ *
+ * @access protected
+ */
+ function _checkValid() {
+ if ($this->read('Config')) {
+ if (Configure::read('Session.checkAgent') === false || $this->_userAgent == $this->read("Config.userAgent") && $this->time <= $this->read("Config.time")) {
+ $time = $this->read("Config.time");
+ $this->write("Config.time", $this->sessionTime);
+
+ if ($this->security === 'high') {
+ $check = $this->read("Config.timeout");
+ $check = $check - 1;
+ $this->write("Config.timeout", $check);
+
+ if (time() > ($time - (Security::inactiveMins() * CAKE_SESSION_TIMEOUT) + 2) || $check < 1) {
+ $this->renew();
+ $this->write('Config.timeout', 10);
+ }
+ }
+ $this->valid = true;
+ } else {
+ $this->destroy();
+ $this->valid = false;
+ $this->__setError(1, "Session Highjacking Attempted !!!");
+ }
+ } else {
+ srand ((double)microtime() * 1000000);
+ $this->write("Config.userAgent", $this->_userAgent);
+ $this->write("Config.time", $this->sessionTime);
+ $this->write('Config.rand', rand());
+ $this->write('Config.timeout', 10);
+ $this->valid = true;
+ $this->__setError(1, "Session is valid");
+ }
+ }
+/**
+ * Helper method to restart a session.
+ *
+ * @access private
+ */
+ function __regenerateId() {
+ $oldSessionId = session_id();
+ if ($oldSessionId) {
+ $sessionpath = session_save_path();
+ if (empty($sessionpath)) {
+ $sessionpath = "/tmp";
+ }
+
+ if (isset($_COOKIE[session_name()])) {
+ setcookie(CAKE_SESSION_COOKIE, '', time() - 42000, $this->path);
+ }
+ session_regenerate_id();
+ $newSessid = session_id();
+
+ if (function_exists('session_write_close')) {
+ session_write_close();
+ }
+ $this->__initSession();
+ session_id($oldSessionId);
+ session_start();
+ session_destroy();
+ $file = $sessionpath . DS . "sess_$oldSessionId";
+ @unlink($file);
+ $this->__initSession();
+ session_id($newSessid);
+ session_start();
+ }
+ }
+/**
+ * Restarts this session.
+ *
+ * @access public
+ */
+ function renew() {
+ /** BEGIN MOZILLA PATCH (@author fwenzel@mozilla.com) **/
+ // if we (legitimately) regenerate the session ID during a POST request,
+ // we need to remember the old ID, so we can check the secret submitted
+ // by the user against it.
+ if ($_SERVER['REQUEST_METHOD'] == 'POST') {
+ global $csrf_old_session_id;
+ $csrf_old_session_id = session_id();
+ }
+ /** END MOZILLA PATCH **/
+ $this->__regenerateId();
+ }
+/**
+ * Validate that the $name is in correct dot notation
+ * example: $name = 'ControllerName.key';
+ *
+ * @param string $name Session key names as string.
+ * @return mixed false is $name is not correct format, or $name if it is correct
+ * @access private
+ */
+ function __validateKeys($name) {
+ if (is_string($name) && preg_match("/^[ 0-9a-zA-Z._-]*$/", $name)) {
+ return $name;
+ }
+ $this->__setError(3, "$name is not a string");
+ return false;
+ }
+/**
+ * Helper method to set an internal error message.
+ *
+ * @param integer $errorNumber Number of the error
+ * @param string $errorMessage Description of the error
+ * @access private
+ */
+ function __setError($errorNumber, $errorMessage) {
+ if ($this->error === false) {
+ $this->error = array();
+ }
+ $this->error[$errorNumber] = $errorMessage;
+ $this->lastError = $errorNumber;
+ }
+/**
+ * Method called on open of a database session.
+ *
+ * @return boolean Success
+ * @access private
+ */
+ function __open() {
+ return true;
+ }
+/**
+ * Method called on close of a database session.
+ *
+ * @return boolean Success
+ * @access private
+ */
+ function __close() {
+ $probability = mt_rand(1, 150);
+ if ($probability <= 3) {
+ CakeSession::__gc();
+ }
+ return true;
+ }
+/**
+ * Method used to read from a database session.
+ *
+ * @param mixed $key The key of the value to read
+ * @return mixed The value of the key or false if it does not exist
+ * @access private
+ */
+ function __read($key) {
+ $db =& ConnectionManager::getDataSource('default');
+ $table = $db->fullTableName(CAKE_SESSION_TABLE, false);
+ $row = $db->query("SELECT " . $db->name($table.'.data') . " FROM " . $db->name($table) . " WHERE " . $db->name($table.'.id') . " = " . $db->value($key), false);
+
+ if ($row && !isset($row[0][$table]) && isset($row[0][0])) {
+ $table = 0;
+ }
+
+ if ($row && $row[0][$table]['data']) {
+ return $row[0][$table]['data'];
+ } else {
+ return false;
+ }
+ }
+/**
+ * Helper function called on write for database sessions.
+ *
+ * @param mixed $key The name of the var
+ * @param mixed $value The value of the var
+ * @return boolean Success
+ * @access private
+ */
+ function __write($key, $value) {
+ $db =& ConnectionManager::getDataSource('default');
+ $table = $db->fullTableName(CAKE_SESSION_TABLE);
+
+ switch(CAKE_SECURITY) {
+ case 'high':
+ $factor = 10;
+ break;
+ case 'medium':
+ $factor = 100;
+ break;
+ case 'low':
+ $factor = 300;
+ break;
+ default:
+ $factor = 10;
+ break;
+ }
+ $expires = time() + CAKE_SESSION_TIMEOUT * $factor;
+ $row = $db->query("SELECT COUNT(id) AS count FROM " . $db->name($table) . " WHERE "
+ . $db->name('id') . " = "
+ . $db->value($key), false);
+
+ if ($row[0][0]['count'] > 0) {
+ $db->execute("UPDATE " . $db->name($table) . " SET " . $db->name('data') . " = "
+ . $db->value($value) . ", " . $db->name('expires') . " = "
+ . $db->value($expires) . " WHERE " . $db->name('id') . " = "
+ . $db->value($key));
+ } else {
+ $db->execute("INSERT INTO " . $db->name($table) . " (" . $db->name('data') . ","
+ . $db->name('expires') . "," . $db->name('id')
+ . ") VALUES (" . $db->value($value) . ", " . $db->value($expires) . ", "
+ . $db->value($key) . ")");
+ }
+ return true;
+ }
+/**
+ * Method called on the destruction of a database session.
+ *
+ * @param int $key Key that uniquely identifies session in database
+ * @return boolean Success
+ * @access private
+ */
+ function __destroy($key) {
+ $db =& ConnectionManager::getDataSource('default');
+ $table = $db->fullTableName(CAKE_SESSION_TABLE);
+ $db->execute("DELETE FROM " . $db->name($table) . " WHERE " . $db->name($table.'.id') . " = " . $db->value($key, 'integer'));
+ return true;
+ }
+/**
+ * Helper function called on gc for database sessions.
+ *
+ * @param int $expires Timestamp (defaults to current time)
+ * @return boolean Success
+ * @access private
+ */
+ function __gc($expires = null) {
+ $db =& ConnectionManager::getDataSource('default');
+ $table = $db->fullTableName(CAKE_SESSION_TABLE);
+ $db->execute("DELETE FROM " . $db->name($table) . " WHERE " . $db->name($table.'.expires') . " < ". $db->value(time()));
+ return true;
+ }
+}
+?>
diff --git a/site/cake/libs/set.php b/site/cake/libs/set.php
new file mode 100644
index 0000000..66a99b4
--- /dev/null
+++ b/site/cake/libs/set.php
@@ -0,0 +1,805 @@
+<?php
+/* SVN FILE: $Id: set.php 6305 2008-01-02 02:33:56Z phpnut $ */
+/**
+ * Library of array functions for Cake.
+ *
+ * PHP versions 4 and 5
+ *
+ * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
+ * Copyright 2005-2008, Cake Software Foundation, Inc.
+ * 1785 E. Sahara Avenue, Suite 490-204
+ * Las Vegas, Nevada 89104
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
+ * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
+ * @package cake
+ * @subpackage cake.cake.libs
+ * @since CakePHP(tm) v 1.2.0
+ * @version $Revision: 6305 $
+ * @modifiedby $LastChangedBy: phpnut $
+ * @lastmodified $Date: 2008-01-01 20:33:56 -0600 (Tue, 01 Jan 2008) $
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+/**
+ * Class used for manipulation of arrays.
+ *
+ * Long description for class
+ *
+ * @package cake
+ * @subpackage cake.cake.libs
+ */
+class Set extends Object {
+/**
+ * Value of the Set object.
+ *
+ * @var array
+ * @access public
+ */
+ var $value = array();
+/**
+ * Constructor. Defaults to an empty array.
+ *
+ * @access public
+ */
+ function __construct() {
+ if (func_num_args() == 1 && is_array(func_get_arg(0))) {
+ $this->value = func_get_arg(0);
+ } else {
+ $this->value = func_get_args();
+ }
+ }
+/**
+ * Returns the contents of the Set object
+ *
+ * @return array
+ * @access public
+ */
+ function &get() {
+ return $this->value;
+ }
+/**
+ * This function can be thought of as a hybrid between PHP's array_merge and array_merge_recursive. The difference
+ * to the two is that if an array key contains another array then the function behaves recursive (unlike array_merge)
+ * but does not do if for keys containing strings (unlike array_merge_recursive). See the unit test for more information.
+ *
+ * Note: This function will work with an unlimited amount of arguments and typecasts non-array parameters into arrays.
+ *
+ * @param array $arr1 Array to be merged
+ * @param array $arr2 Array to merge with
+ * @return array Merged array
+ * @access public
+ */
+ function merge($arr1, $arr2 = null) {
+ $args = func_get_args();
+
+ if (is_a($this, 'set')) {
+ $backtrace = debug_backtrace();
+ $previousCall = strtolower($backtrace[1]['class'].'::'.$backtrace[1]['function']);
+ if ($previousCall != 'set::merge') {
+ $r =& $this->value;
+ array_unshift($args, null);
+ }
+ }
+ if (!isset($r)) {
+ $r = (array)current($args);
+ }
+
+ while (($arg = next($args)) !== false) {
+ if (is_a($arg, 'set')) {
+ $arg = $arg->get();
+ }
+
+ foreach ((array)$arg as $key => $val) {
+ if (is_array($val) && isset($r[$key]) && is_array($r[$key])) {
+ $r[$key] = Set::merge($r[$key], $val);
+ } elseif (is_int($key)) {
+ $r[] = $val;
+ } else {
+ $r[$key] = $val;
+ }
+ }
+ }
+ return $r;
+ }
+/**
+ * Filters empty elements out of a route array, excluding '0'.
+ *
+ * @param mixed $var Either an array to filter, or value when in callback
+ * @param boolean $isArray Force to tell $var is an array when $var is empty
+ * @return mixed Either filtered array, or true/false when in callback
+ * @access public
+ */
+ function filter($var, $isArray = false) {
+ if (is_array($var) && (!empty($var) || $isArray)) {
+ return array_filter($var, array('Set', 'filter'));
+ } else {
+ if ($var === 0 || $var === '0' || !empty($var)) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+ }
+/**
+ * Pushes the differences in $array2 onto the end of $array
+ *
+ * @param mixed $array Original array
+ * @param mixed $array2 Differences to push
+ * @return array Combined array
+ * @access public
+ */
+ function pushDiff($array = null, $array2 = null) {
+ if ($array2 !== null && is_array($array2)) {
+ foreach ($array2 as $key => $value) {
+ if (!array_key_exists($key, $array)) {
+ $array[$key] = $value;
+ } else {
+ if (is_array($value)) {
+ $array[$key] = Set::pushDiff($array[$key], $array2[$key]);
+ }
+ }
+ }
+ return $array;
+ }
+
+ if (!isset($this->value)) {
+ $this->value = array();
+ }
+ $this->value = Set::pushDiff($this->value, Set::__array($array));
+ return $this->value;
+ }
+/**
+ * Maps the contents of the Set object to an object hierarchy.
+ * Maintains numeric keys as arrays of objects
+ *
+ * @param string $class A class name of the type of object to map to
+ * @param string $tmp A temporary class name used as $class if $class is an array
+ * @return object Hierarchical object
+ * @access public
+ */
+ function map($class = 'stdClass', $tmp = 'stdClass') {
+ if (is_array($class)) {
+ $val = $class;
+ $class = $tmp;
+ } elseif (is_a($this, 'set')) {
+ $val = $this->get();
+ }
+
+ if (empty($val) || $val == null) {
+ return null;
+ }
+ return Set::__map($val, $class);
+ }
+
+/**
+ * Get the array value of $array. If $array is null, it will return
+ * the current array Set holds. If it is an object of type Set, it
+ * will return its value. If it is another object, its object variables.
+ * If it is anything else but an array, it will return an array whose first
+ * element is $array.
+ *
+ * @param mixed $array Data from where to get the array.
+ * @return array Array from $array.
+ * @access private
+ */
+ function __array($array) {
+ if ($array == null) {
+ $array = $this->value;
+ } elseif (is_object($array) && (is_a($array, 'set'))) {
+ $array = $array->get();
+ } elseif (is_object($array)) {
+ $array = get_object_vars($array);
+ } elseif (!is_array($array)) {
+ $array = array($array);
+ }
+ return $array;
+ }
+
+/**
+ * Maps the given value as an object. If $value is an object,
+ * it returns $value. Otherwise it maps $value as an object of
+ * type $class, and if primary assign _name_ $key on first array.
+ * If $value is not empty, it will be used to set properties of
+ * returned object (recursively). If $key is numeric will maintain array
+ * structure
+ *
+ * @param mixed $value Value to map
+ * @param string $class Class name
+ * @param boolean $primary whether to assign first array key as the _name_
+ * @return mixed Mapped object
+ * @access private
+ */
+ function __map(&$array, $class, $primary = false) {
+ if ($class === true) {
+ $out = new stdClass;
+ } else {
+ $out = new $class;
+ }
+ if (is_array($array)) {
+ $keys = array_keys($array);
+ foreach ($array as $key => $value) {
+ if($keys[0] === $key && $class !== true) {
+ $primary = true;
+ }
+ if (is_numeric($key)) {
+ if (is_object($out) && is_array($value)) {
+ $out = get_object_vars($out);
+ }
+ $out[$key] = Set::__map($value, $class, true);
+ } elseif ($primary === true && is_array($value)) {
+ $out->_name_ = $key;
+ $primary = false;
+ foreach($value as $key2 => $value2) {
+ $out->{$key2} = Set::__map($value2, $class);
+ }
+ } else {
+ $out->{$key} = Set::__map($value, $class);
+ }
+ }
+ } else {
+ $out = $array;
+ }
+ return $out;
+ }
+/**
+ * Checks to see if all the values in the array are numeric
+ *
+ * @param array $array The array to check. If null, the value of the current Set object
+ * @return boolean true if values are numeric, false otherwise
+ * @access public
+ */
+ function numeric($array = null) {
+ if ($array == null && (is_a($this, 'set') || is_a($this, 'Set'))) {
+ $array = $this->get();
+ }
+
+ $numeric = true;
+ $keys = array_keys($array);
+ $count = count($keys);
+ for ($i = 0; $i < $count; $i++) {
+ if (!is_numeric($array[$keys[$i]])) {
+ $numeric = false;
+ break;
+ }
+ }
+ return $numeric;
+ }
+/**
+ * Return a value from an array list if the key exists.
+ *
+ * If a comma separated $list is passed arrays are numeric with the key of the first being 0
+ * $list = 'no, yes' would translate to $list = array(0 => 'no', 1 => 'yes');
+ *
+ * If an array is used, keys can be strings example: array('no' => 0, 'yes' => 1);
+ *
+ * $list defaults to 0 = no 1 = yes if param is not passed
+ *
+ * @param mixed $select Key in $list to return
+ * @param mixed $list can be an array or a comma-separated list.
+ * @return string the value of the array key or null if no match
+ * @access public
+ */
+ function enum($select, $list = null) {
+ if (empty($list) && is_a($this, 'Set')) {
+ $list = $this->get();
+ } elseif (empty($list)) {
+ $list = array('no', 'yes');
+ }
+
+ $return = null;
+ $list = Set::normalize($list, false);
+
+ if (array_key_exists($select, $list)) {
+ $return = $list[$select];
+ }
+ return $return;
+ }
+/**
+ * Returns a series of values extracted from an array, formatted in a format string.
+ *
+ * @param array $data Source array from which to extract the data
+ * @param string $format Format string into which values will be inserted, see sprintf()
+ * @param array $keys An array containing one or more Set::extract()-style key paths
+ * @return array An array of strings extracted from $keys and formatted with $format
+ * @access public
+ */
+ function format($data, $format, $keys) {
+
+ $extracted = array();
+ $count = count($keys);
+
+ if (!$count) {
+ return;
+ }
+
+ for ($i = 0; $i < $count; $i++) {
+ $extracted[] = Set::extract($data, $keys[$i]);
+ }
+ $out = array();
+ $data = $extracted;
+ $count = count($data[0]);
+
+ if (preg_match_all('/\{([0-9]+)\}/msi', $format, $keys2) && isset($keys2[1])) {
+ $keys = $keys2[1];
+ $format = preg_split('/\{([0-9]+)\}/msi', $format);
+ $count2 = count($format);
+
+ for ($j = 0; $j < $count; $j++) {
+ $formatted = '';
+ for ($i = 0; $i <= $count2; $i++) {
+ if (isset($format[$i])) {
+ $formatted .= $format[$i];
+ }
+ if (isset($keys[$i]) && isset($data[$keys[$i]][$j])) {
+ $formatted .= $data[$keys[$i]][$j];
+ }
+ }
+ $out[] = $formatted;
+ }
+ } else {
+ $count2 = count($data);
+ for ($j = 0; $j < $count; $j++) {
+ $args = array();
+ for ($i = 0; $i < $count2; $i++) {
+ if (isset($data[$i][$j])) {
+ $args[] = $data[$i][$j];
+ }
+ }
+ $out[] = vsprintf($format, $args);
+ }
+ }
+ return $out;
+ }
+/**
+ * Gets a value from an array or object that maps a given path.
+ * The special {n}, as seen in the Model::generateList method, is taken care of here.
+ *
+ * @param array $data Array from where to extract
+ * @param mixed $path As an array, or as a dot-separated string.
+ * @return array Extracted data
+ * @access public
+ */
+ function extract($data, $path = null) {
+ if ($path === null && is_a($this, 'set')) {
+ $path = $data;
+ $data = $this->get();
+ }
+ if (is_object($data)) {
+ $data = get_object_vars($data);
+ }
+
+ if (!is_array($path)) {
+ if (strpos($path, '/') !== 0 && strpos($path, './') === false) {
+ $path = explode('.', $path);
+ } else {
+ }
+ }
+ $tmp = array();
+ if (!is_array($path) || empty($path)) {
+ return null;
+ }
+
+ foreach ($path as $i => $key) {
+ if (is_numeric($key) && intval($key) > 0 || $key == '0') {
+ if (isset($data[intval($key)])) {
+ $data = $data[intval($key)];
+ } else {
+ return null;
+ }
+ } elseif ($key == '{n}') {
+ foreach ($data as $j => $val) {
+ if (is_int($j)) {
+ $tmpPath = array_slice($path, $i + 1);
+ if (empty($tmpPath)) {
+ $tmp[] = $val;
+ } else {
+ $tmp[] = Set::extract($val, $tmpPath);
+ }
+ }
+ }
+ return $tmp;
+ } else {
+ if (isset($data[$key])) {
+ $data = $data[$key];
+ } else {
+ return null;
+ }
+ }
+ }
+ return $data;
+ }
+/**
+ * Inserts $data into an array as defined by $path.
+ *
+ * @param mixed $list Where to insert into
+ * @param mixed $path A dot-separated string.
+ * @param array $data Data to insert
+ * @return array
+ * @access public
+ */
+ function insert($list, $path, $data = null) {
+ if (empty($data) && is_a($this, 'Set')) {
+ $data = $path;
+ $path = $list;
+ $list =& $this->get();
+ }
+ if (!is_array($path)) {
+ $path = explode('.', $path);
+ }
+ $_list =& $list;
+
+ foreach ($path as $i => $key) {
+ if (is_numeric($key) && intval($key) > 0 || $key == '0') {
+ $key = intval($key);
+ }
+ if ($i == count($path) - 1) {
+ $_list[$key] = $data;
+ } else {
+ if (!isset($_list[$key])) {
+ $_list[$key] = array();
+ }
+ $_list =& $_list[$key];
+ }
+ }
+ return $list;
+ }
+/**
+ * Removes an element from a Set or array as defined by $path.
+ *
+ * @param mixed $list From where to remove
+ * @param mixed $path A dot-separated string.
+ * @return array Array with $path removed from its value
+ * @access public
+ */
+ function remove($list, $path = null) {
+ if (empty($path) && is_a($this, 'Set')) {
+ $path = $list;
+ $list =& $this->get();
+ }
+ if (!is_array($path)) {
+ $path = explode('.', $path);
+ }
+ $_list =& $list;
+
+ foreach ($path as $i => $key) {
+ if (is_numeric($key) && intval($key) > 0 || $key == '0') {
+ $key = intval($key);
+ }
+ if ($i == count($path) - 1) {
+ unset($_list[$key]);
+ } else {
+ if (!isset($_list[$key])) {
+ return $list;
+ }
+ $_list =& $_list[$key];
+ }
+ }
+
+ if (is_a($this, 'Set')) {
+ $this->value = $list;
+ return $this;
+ } else {
+ return $list;
+ }
+ }
+/**
+ * Checks if a particular path is set in an array
+ *
+ * @param mixed $data Data to check on
+ * @param mixed $path A dot-separated string.
+ * @return boolean true if path is found, false otherwise
+ * @access public
+ */
+ function check($data, $path = null) {
+ if (empty($path) && is_a($this, 'Set')) {
+ $path = $data;
+ $data = $this->get();
+ }
+ if (!is_array($path)) {
+ $path = explode('.', $path);
+ }
+
+ foreach ($path as $i => $key) {
+ if (is_numeric($key) && intval($key) > 0 || $key == '0') {
+ $key = intval($key);
+ }
+ if ($i == count($path) - 1) {
+ return isset($data[$key]);
+ } else {
+ if (!isset($data[$key])) {
+ return false;
+ }
+ $data =& $data[$key];
+ }
+ }
+ return true;
+ }
+/**
+ * Computes the difference between a Set and an array, two Sets, or two arrays
+ *
+ * @param mixed $val1 First value
+ * @param mixed $val2 Second value
+ * @return array Computed difference
+ * @access public
+ */
+ function diff($val1, $val2 = null) {
+ if ($val2 == null && (is_a($this, 'set') || is_a($this, 'Set'))) {
+ $val2 = $val1;
+ $val1 = $this->get();
+ }
+
+ if (is_object($val2) && (is_a($val2, 'set') || is_a($val2, 'Set'))) {
+ $val2 = $val2->get();
+ }
+ $out = array();
+
+ if (empty($val1)) {
+ return (array)$val2;
+ } elseif (empty($val2)) {
+ return (array)$val1;
+ }
+
+ foreach ($val1 as $key => $val) {
+ if (array_key_exists($key, $val2) && $val2[$key] != $val) {
+ $out[$key] = $val;
+ } elseif (!array_key_exists($key, $val2)) {
+ $out[$key] = $val;
+ }
+ unset($val2[$key]);
+ }
+
+ foreach ($val2 as $key => $val) {
+ if (!array_key_exists($key, $out)) {
+ $out[$key] = $val;
+ }
+ }
+ return $out;
+ }
+/**
+ * Determines if two Sets or arrays are equal
+ *
+ * @param array $val1 First value
+ * @param array $val2 Second value
+ * @return boolean true if they are equal, false otherwise
+ * @access public
+ */
+ function isEqual($val1, $val2 = null) {
+ if ($val2 == null && (is_a($this, 'set') || is_a($this, 'Set'))) {
+ $val2 = $val1;
+ $val1 = $this->get();
+ }
+
+ return ($val1 == $val2);
+ }
+/**
+ * Determines if one Set or array contains the exact keys and values of another.
+ *
+ * @param array $val1 First value
+ * @param array $val2 Second value
+ * @return boolean true if $val1 contains $val2, false otherwise
+ * @access public
+ */
+ function contains($val1, $val2 = null) {
+ if ($val2 == null && is_a($this, 'set')) {
+ $val2 = $val1;
+ $val1 = $this->get();
+ } elseif ($val2 != null && is_object($val2) && is_a($val2, 'set')) {
+ $val2 = $val2->get();
+ }
+
+ foreach ($val2 as $key => $val) {
+ if (is_numeric($key)) {
+ if (!in_array($val, $val1)) {
+ return false;
+ }
+ } else {
+ if (!isset($val1[$key]) || $val1[$key] != $val) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+/**
+ * Counts the dimensions of an array. If $all is set to false (which is the default) it will
+ * only consider the dimension of the first element in the array.
+ *
+ * @param array $array Array to count dimensions on
+ * @param boolean $all Set to true to count the dimension considering all elements in array
+ * @param integer $count Start the dimension count at this number
+ * @return integer The number of dimensions in $array
+ * @access public
+ */
+ function countDim($array = null, $all = false, $count = 0) {
+ if ($array === null) {
+ $array = $this->get();
+ } elseif (is_object($array) && is_a($array, 'set')) {
+ $array = $array->get();
+ }
+ if ($all) {
+ $depth = array($count);
+ if (is_array($array) && reset($array) !== false) {
+ foreach ($array as $value) {
+ $depth[] = Set::countDim($value, true, $count + 1);
+ }
+ }
+ $return = max($depth);
+ } else {
+ if (is_array(reset($array))) {
+ $return = Set::countDim(reset($array)) + 1;
+ } else {
+ $return = 1;
+ }
+ }
+ return $return;
+ }
+/**
+ * Normalizes a string or array list.
+ *
+ * @param mixed $list List to normalize
+ * @param boolean $assoc If true, $list will be converted to an associative array
+ * @param string $sep If $list is a string, it will be split into an array with $sep
+ * @param boolean $trim If true, separated strings will be trimmed
+ * @return array
+ * @access public
+ */
+ function normalize($list, $assoc = true, $sep = ',', $trim = true) {
+ if (is_string($list)) {
+ $list = explode($sep, $list);
+ if ($trim) {
+ $list = array_map('trim', $list);
+ }
+ if ($assoc) {
+ return Set::normalize($list);
+ }
+ } elseif (is_array($list)) {
+ $keys = array_keys($list);
+ $count = count($keys);
+ $numeric = true;
+
+ if (!$assoc) {
+ for ($i = 0; $i < $count; $i++) {
+ if (!is_int($keys[$i])) {
+ $numeric = false;
+ break;
+ }
+ }
+ }
+ if (!$numeric || $assoc) {
+ $newList = array();
+ for ($i = 0; $i < $count; $i++) {
+ if (is_int($keys[$i])) {
+ $newList[$list[$keys[$i]]] = null;
+ } else {
+ $newList[$keys[$i]] = $list[$keys[$i]];
+ }
+ }
+ $list = $newList;
+ }
+ }
+ return $list;
+ }
+/**
+ * Creates an associative array using a $path1 as the path to build its keys, and optionally
+ * $path2 as path to get the values. If $path2 is not specified, all values will be initialized
+ * to null (useful for Set::merge). You can optionally group the values by what is obtained when
+ * following the path specified in $groupPath.
+ *
+ * @param array $data Array from where to extract keys and values
+ * @param mixed $path1 As an array, or as a dot-separated string.
+ * @param mixed $path2 As an array, or as a dot-separated string.
+ * @param string $groupPath As an array, or as a dot-separated string.
+ * @return array Combined array
+ * @access public
+ */
+ function combine($data, $path1 = null, $path2 = null, $groupPath = null) {
+ if (is_a($this, 'set') && is_string($data) && is_string($path1) && is_string($path2)) {
+ $groupPath = $path2;
+ $path2 = $path1;
+ $path1 = $data;
+ $data = $this->get();
+
+ } elseif (is_a($this, 'set') && is_string($data) && empty($path2)) {
+ $path2 = $path1;
+ $path1 = $data;
+ $data = $this->get();
+ }
+
+ if (is_object($data)) {
+ $data = get_object_vars($data);
+ }
+
+ if (is_array($path1)) {
+ $format = array_shift($path1);
+ $keys = Set::format($data, $format, $path1);
+ } else {
+ $keys = Set::extract($data, $path1);
+ }
+
+ if (!empty($path2) && is_array($path2)) {
+ $format = array_shift($path2);
+ $vals = Set::format($data, $format, $path2);
+
+ } elseif (!empty($path2)) {
+ $vals = Set::extract($data, $path2);
+
+ } else {
+ $count = count($keys);
+ for ($i = 0; $i < $count; $i++) {
+ $vals[$i] = null;
+ }
+ }
+
+ if ($groupPath != null) {
+ $group = Set::extract($data, $groupPath);
+ if (!empty($group)) {
+ $c = count($keys);
+ for ($i = 0; $i < $c; $i++) {
+ if (!isset($group[$i])) {
+ $group[$i] = 0;
+ }
+ if (!isset($out[$group[$i]])) {
+ $out[$group[$i]] = array();
+ }
+ $out[$group[$i]][$keys[$i]] = $vals[$i];
+ }
+ return $out;
+ }
+ }
+
+ return array_combine($keys, $vals);
+ }
+/**
+ * Converts an object into an array
+ *
+ * @param object $object
+ * @return array
+ */
+ function reverse($object) {
+ if (is_a($object, 'xmlnode') || is_a($object, 'XMLNode')) {
+ if ($object->name != Inflector::underscore($this->name)) {
+ if (is_object($object->child(Inflector::underscore($this->name)))) {
+ $object = $object->child(Inflector::underscore($this->name));
+ $object = $object->attributes;
+ } else {
+ return null;
+ }
+ }
+ } else {
+ $out = array();
+ if (is_object($object)) {
+ $keys = get_object_vars($object);
+ if (isset($keys['_name_'])) {
+ $identity = $keys['_name_'];
+ unset($keys['_name_']);
+ }
+ $new = array();
+ foreach ($keys as $key => $value) {
+ if (is_array($value)) {
+ $new[$key] = (array)Set::reverse($value);
+ } else {
+ $new[$key] = Set::reverse($value);
+ }
+ }
+ if (isset($identity)) {
+ $out[$identity] = $new;
+ } else {
+ $out = $new;
+ }
+ } elseif (is_array($object)) {
+ foreach ($object as $key => $value) {
+ $out[$key] = Set::reverse($value);
+ }
+ } else {
+ $out = $object;
+ }
+ return $out;
+ }
+ return $object;
+ }
+}
+?> \ No newline at end of file
diff --git a/site/cake/libs/validators.php b/site/cake/libs/validators.php
new file mode 100644
index 0000000..02a7004
--- /dev/null
+++ b/site/cake/libs/validators.php
@@ -0,0 +1,45 @@
+<?php
+/* SVN FILE: $Id: validators.php 6305 2008-01-02 02:33:56Z phpnut $ */
+/**
+ * Tort Validators
+ *
+ * Used to validate data in Models.
+ *
+ * PHP versions 4 and 5
+ *
+ * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
+ * Copyright 2005-2008, Cake Software Foundation, Inc.
+ * 1785 E. Sahara Avenue, Suite 490-204
+ * Las Vegas, Nevada 89104
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
+ * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
+ * @package cake
+ * @subpackage cake.cake.libs
+ * @since CakePHP(tm) v 0.2.9
+ * @version $Revision: 6305 $
+ * @modifiedby $LastChangedBy: phpnut $
+ * @lastmodified $Date: 2008-01-01 20:33:56 -0600 (Tue, 01 Jan 2008) $
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+/**
+ * Not empty.
+ */
+ define('VALID_NOT_EMPTY', '/.+/');
+/**
+ * Numbers [0-9] only.
+ */
+ define('VALID_NUMBER', '/^[-+]?\\b[0-9]*\\.?[0-9]+\\b$/');
+/**
+ * A valid email address.
+ */
+ define('VALID_EMAIL', '/\\A(?:^([a-z0-9][a-z0-9_\\-\\.\\+]*)@([a-z0-9][a-z0-9\\.\\-]{0,63}\\.(com|org|net|biz|info|name|net|pro|aero|coop|museum|[a-z]{2,4}))$)\\z/i');
+/**
+ * A valid year (1000-2999).
+ */
+ define('VALID_YEAR', '/^[12][0-9]{3}$/');
+?> \ No newline at end of file
diff --git a/site/cake/libs/view/helper.php b/site/cake/libs/view/helper.php
new file mode 100644
index 0000000..6dad823
--- /dev/null
+++ b/site/cake/libs/view/helper.php
@@ -0,0 +1,167 @@
+<?php
+/* SVN FILE: $Id: helper.php 6305 2008-01-02 02:33:56Z phpnut $ */
+/**
+ * Backend for helpers.
+ *
+ * Internal methods for the Helpers.
+ *
+ * PHP versions 4 and 5
+ *
+ * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
+ * Copyright 2005-2008, Cake Software Foundation, Inc.
+ * 1785 E. Sahara Avenue, Suite 490-204
+ * Las Vegas, Nevada 89104
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
+ * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
+ * @package cake
+ * @subpackage cake.cake.libs.view
+ * @since CakePHP(tm) v 0.2.9
+ * @version $Revision: 6305 $
+ * @modifiedby $LastChangedBy: phpnut $
+ * @lastmodified $Date: 2008-01-01 20:33:56 -0600 (Tue, 01 Jan 2008) $
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+/**
+ * Backend for helpers.
+ *
+ * Long description for class
+ *
+ * @package cake
+ * @subpackage cake.cake.libs.view
+ */
+class Helper extends Object {
+/**
+ * Holds tag templates.
+ *
+ * @access public
+ * @var array
+ */
+ var $tags = array('link' => '<a href="%s" %s>%s</a>',
+ 'mailto' => '<a href="mailto:%s" %s>%s</a>',
+ 'form' => '<form %s>',
+ 'input' => '<input name="data[%s][%s]" %s/>',
+ 'textarea' => '<textarea name="data[%s][%s]" %s>%s</textarea>',
+ 'hidden' => '<input type="hidden" name="data[%s][%s]" %s/>',
+ 'textarea' => '<textarea name="data[%s][%s]" %s>%s</textarea>',
+ 'checkbox' => '<input type="checkbox" name="data[%s][%s]" %s/>',
+ 'radio' => '<input type="radio" name="data[%s][%s]" id="%s" %s/>%s',
+ 'selectstart' => '<select name="data[%s][%s]" %s>',
+ 'selectmultiplestart' => '<select name="data[%s][%s][]" %s>',
+ 'selectempty' => '<option value="" %s>&nbsp;</option>',
+ 'selectoption' => '<option value="%s" %s>%s</option>',
+ 'selectend' => '</select>',
+ 'password' => '<input type="password" name="data[%s][%s]" %s/>',
+ 'file' => '<input type="file" name="data[%s][%s]" %s/>',
+ 'file_no_model' => '<input type="file" name="%s" %s/>',
+ 'submit' => '<input type="submit" %s/>',
+ 'image' => '<img src="%s" %s/>',
+ 'tableheader' => '<th%s>%s</th>',
+ 'tableheaderrow' => '<tr%s>%s</tr>',
+ 'tablecell' => '<td%s>%s</td>',
+ 'tablerow' => '<tr%s>%s</tr>',
+ 'block' => '<div%s>%s</div>',
+ 'blockstart' => '<div%s>',
+ 'blockend' => '</div>',
+ 'css' => '<link rel="%s" type="text/css" href="%s" %s/>',
+ 'style' => '<style type="text/css"%s>%s</style>',
+ 'charset' => '<meta http-equiv="Content-Type" content="text/html; charset=%s"/>',
+ 'javascriptblock' => '<script type="text/javascript">%s</script>',
+ 'javascriptlink' => '<script type="text/javascript" src="%s"></script>');
+/**
+ * Parses custom config/tags.ini.php and merges with $this->tags.
+ *
+ * @return html tags used by helpers
+ */
+ function loadConfig() {
+
+ if (file_exists(APP . 'config' . DS . 'tags.ini.php')) {
+ $tags = $this->readConfigFile(APP . 'config' . DS . 'tags.ini.php');
+ $this->tags = am($this->tags, $tags);
+ }
+ return $this->tags;
+ }
+/**
+ * Decides whether to output or return a string.
+ *
+ * Based on AUTO_OUTPUT and $return's value, this method decides whether to
+ * output a string, or return it.
+ *
+ * @param string $str String to be output or returned.
+ * @param boolean $return Whether this method should return a value or output it.
+ * @return mixed Either string or echos the value, depends on AUTO_OUTPUT and $return.
+ */
+ function output($str, $return = false) {
+ if (AUTO_OUTPUT && $return === false) {
+ echo $str;
+ } else {
+ return $str;
+ }
+ }
+/**
+ * Assigns values to tag templates.
+ *
+ * Finds a tag template by $keyName, and replaces $values's keys with
+ * $values's keys.
+ *
+ * @param string $keyName Name of the key in the tag array.
+ * @param array $values Values to be inserted into tag.
+ * @return string Tag with inserted values.
+ */
+ function assign($keyName, $values) {
+ return str_replace('%%' . array_keys($values) . '%%', array_values($values), $this->tags[$keyName]);
+ }
+/**
+ * Returns an array of settings in given INI file.
+ *
+ * @param string $fileName ini file to read
+ * @return array of lines from the $fileName
+ */
+ function readConfigFile($fileName) {
+ $fileLineArray = file($fileName);
+
+ foreach ($fileLineArray as $fileLine) {
+ $dataLine = trim($fileLine);
+ $firstChar = substr($dataLine, 0, 1);
+
+ if ($firstChar != ';' && $dataLine != '') {
+ if ($firstChar == '[' && substr($dataLine, -1, 1) == ']') {
+ // [section block] we might use this later do not know for sure
+ // this could be used to add a key with the section block name
+ // but it adds another array level
+ } else {
+ $delimiter = strpos($dataLine, '=');
+
+ if ($delimiter > 0) {
+ $key = strtolower(trim(substr($dataLine, 0, $delimiter)));
+ $value = trim(stripcslashes(substr($dataLine, $delimiter + 1)));
+
+ if (substr($value, 0, 1) == '"' && substr($value, -1) == '"') {
+ $value = substr($value, 1, -1);
+ }
+
+ $iniSetting[$key] = $value;
+
+ } else {
+ $iniSetting[strtolower(trim($dataLine))] = '';
+ }
+ }
+ } else {
+ }
+ }
+
+ return $iniSetting;
+ }
+/**
+ * After render callback. Overridden in subclasses.
+ *
+ * @return void
+ */
+ function afterRender() {
+ }
+}
+?>
diff --git a/site/cake/libs/view/helpers/ajax.php b/site/cake/libs/view/helpers/ajax.php
new file mode 100644
index 0000000..36c185b
--- /dev/null
+++ b/site/cake/libs/view/helpers/ajax.php
@@ -0,0 +1,853 @@
+<?php
+/* SVN FILE: $Id: ajax.php 6305 2008-01-02 02:33:56Z phpnut $ */
+/**
+ * Helper for AJAX operations.
+ *
+ * Helps doing AJAX using the Prototype library.
+ *
+ * PHP versions 4 and 5
+ *
+ * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
+ * Copyright 2005-2008, Cake Software Foundation, Inc.
+ * 1785 E. Sahara Avenue, Suite 490-204
+ * Las Vegas, Nevada 89104
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
+ * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
+ * @package cake
+ * @subpackage cake.cake.libs.view.helpers
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @version $Revision: 6305 $
+ * @modifiedby $LastChangedBy: phpnut $
+ * @lastmodified $Date: 2008-01-01 20:33:56 -0600 (Tue, 01 Jan 2008) $
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+/**
+ * AjaxHelper library.
+ *
+ * Helps doing AJAX using the Prototype library.
+ *
+ * @package cake
+ * @subpackage cake.cake.libs.view.helpers
+ */
+class AjaxHelper extends Helper {
+/**
+ * Included helpers.
+ *
+ * @var array
+ * @access public
+ */
+ var $helpers = array('Html', 'Javascript');
+/**
+ * Names of Javascript callback functions.
+ *
+ * @var array
+ * @access public
+ */
+ var $callbacks = array('uninitialized', 'loading', 'loaded', 'interactive', 'complete', 'success', 'failure');
+/**
+ * Names of AJAX options.
+ *
+ * @var array
+ * @access public
+ */
+ var $ajaxOptions = array('type', 'confirm', 'condition', 'before', 'after', 'fallback', 'update', 'loading', 'loaded', 'interactive', 'complete', 'with', 'url', 'method', 'position', 'form', 'parameters', 'evalScripts', 'asynchronous', 'onComplete', 'onUninitialized', 'onLoading', 'onLoaded', 'onInteractive', 'success', 'failure', 'onSuccess', 'onFailure', 'insertion', 'requestHeaders');
+/**
+ * Options for draggable.
+ *
+ * @var array
+ * @access public
+ */
+ var $dragOptions = array('handle', 'revert', 'constraint', 'change', 'ghosting');
+/**
+ * Options for droppable.
+ *
+ * @var array
+ * @access public
+ */
+ var $dropOptions = array('accept', 'containment', 'overlap', 'greedy', 'hoverclass', 'onHover', 'onDrop');
+/**
+ * Options for sortable.
+ *
+ * @var array
+ * @access public
+ */
+ var $sortOptions = array('tag', 'only', 'overlap', 'constraint', 'containment', 'handle', 'hoverclass', 'ghosting', 'dropOnEmpty', 'onUpdate', 'onChange');
+/**
+ * Options for slider.
+ *
+ * @var array
+ * @access public
+ */
+ var $sliderOptions = array('axis', 'increment', 'maximum', 'minimum', 'alignX', 'alignY', 'sliderValue', 'disabled', 'handleImage', 'handleDisabled', 'values', 'onSlide', 'onChange');
+/**
+ * Options for in-place editor.
+ *
+ * @var array
+ * @access public
+ */
+ var $editorOptions = array('okText', 'cancelText', 'savingText', 'formId', 'externalControl', 'rows', 'cols', 'size', 'highlightcolor', 'highlightendcolor', 'savingClassName', 'formClassName', 'loadTextURL', 'loadingText', 'callback', 'ajaxOptions', 'clickToEditText');
+/**
+ * Options for auto-complete editor.
+ *
+ * @var array
+ * @access public
+ */
+ var $autoCompleteOptions = array('paramName', 'tokens', 'frequency', 'minChars', 'indicator', 'updateElement', 'afterUpdateElement', 'onShow', 'onHide');
+/**
+ * Output buffer for Ajax update content
+ *
+ * @var array
+ * @access private
+ */
+ var $__ajaxBuffer = array();
+/**
+ * Returns link to remote action
+ *
+ * Returns a link to a remote action defined by <i>options[url]</i>
+ * (using the urlFor format) that's called in the background using
+ * XMLHttpRequest. The result of that request can then be inserted into a
+ * DOM object whose id can be specified with <i>options[update]</i>.
+ *
+ * Examples:
+ * <code>
+ * $ajax->link("Delete this post", "/posts/delete/{$post['Post']['id']}"
+ * array("update" => "posts", "loading"=>"Element.show('loading');", "complete"=>"Element.hide('loading');"),
+ * "Are you sure you want to delte this post?");
+ * $ajax->link($html->img("refresh"), '/emails/refresh',
+ * array("update" => "posts", "loading"=>"Element.show('loading');", "complete"=>"Element.hide('loading');"),
+ * null, false);
+ * </code>
+ *
+ * By default, these remote requests are processed asynchronous during
+ * which various callbacks can be triggered (for progress indicators and
+ * the likes).
+ *
+ * The callbacks that may be specified are:
+ *
+ * - <i>loading</i>:: Called when the remote document is being
+ * loaded with data by the browser.
+ * - <i>loaded</i>:: Called when the browser has finished loading
+ * the remote document.
+ * - <i>interactive</i>:: Called when the user can interact with the
+ * remote document, even though it has not
+ * finished loading.
+ * - <i>complete</i>:: Called when the request is complete.
+ *
+ * If you for some reason or another need synchronous processing (that'll
+ * block the browser while the request is happening), you can specify
+ * <i>$options['type'] = synchronous</i>.
+ *
+ * You can customize further browser side call logic by passing
+ * in Javascript code snippets via some optional parameters. In
+ * their order of use these are:
+ *
+ * - <i>confirm</i> :: Adds confirmation dialog.
+ * - <i>condition</i> :: Perform remote request conditionally
+ * by this expression. Use this to
+ * describe browser-side conditions when
+ * request should not be initiated.
+ * - <i>before</i> :: Called before request is initiated.
+ * - <i>after</i> :: Called immediately after request was
+ * initiated and before <i>loading</i>.
+ *
+ * @link http://wiki.script.aculo.us/scriptaculous/show/Ajax.Updater
+ * @param string $title Title of link
+ * @param string $href href string "/products/view/12"
+ * @param array $options Options for JavaScript function
+ * @param string $confirm Confirmation message. Calls up a JavaScript confirm() message.
+ * @param boolean $escapeTitle Escaping the title string to HTML entities
+ * @return HTML code for link to remote action
+ * @access public
+ */
+ function link($title, $href = null, $options = array(), $confirm = null, $escapeTitle = true) {
+ if (!isset($href)) {
+ $href = $title;
+ }
+
+ if (!isset($options['url'])) {
+ $options['url'] = $href;
+ }
+
+ if (isset($confirm)) {
+ $options['confirm'] = $confirm;
+ unset($confirm);
+ }
+ $htmlOptions = $this->__getHtmlOptions($options);
+
+ if (empty($options['fallback']) || !isset($options['fallback'])) {
+ $options['fallback'] = $href;
+ }
+
+ if (!isset($htmlOptions['id'])) {
+ $htmlOptions['id'] = 'link' . intval(rand());
+ }
+
+ if (!isset($htmlOptions['onclick'])) {
+ $htmlOptions['onclick'] = '';
+ }
+ $htmlOptions['onclick'] .= ' event.returnValue = false; return false;';
+ $return = $this->Html->link($title, $href, $htmlOptions, null, $escapeTitle);
+ $script = $this->Javascript->event("'{$htmlOptions['id']}'", "click", $this->remoteFunction($options));
+
+ if (is_string($script)) {
+ $return .= $script;
+ }
+ return $return;
+ }
+/**
+ * Creates JavaScript function for remote AJAX call
+ *
+ * This function creates the javascript needed to make a remote call
+ * it is primarily used as a helper for link.
+ *
+ * @link http://wiki.script.aculo.us/scriptaculous/show/Ajax.Updater
+ * @see link() for docs on options parameter.
+ * @param array $options options for javascript
+ * @return string html code for link to remote action
+ * @access public
+ */
+ function remoteFunction($options = null) {
+ if (isset($options['update'])) {
+ if (!is_array($options['update'])) {
+ $func = "new Ajax.Updater('{$options['update']}',";
+ } else {
+ $func = "new Ajax.Updater(document.createElement('div'),";
+ }
+ if (!isset($options['requestHeaders'])) {
+ $options['requestHeaders'] = array();
+ }
+ if (is_array($options['update'])) {
+ $options['update'] = join(' ', $options['update']);
+ }
+ $options['requestHeaders']['X-Update'] = $options['update'];
+ } else {
+ $func = "new Ajax.Request(";
+ }
+
+ $func .= "'" . $this->Html->url(isset($options['url']) ? $options['url'] : "") . "'";
+ $func .= ", " . $this->__optionsForAjax($options) . ")";
+
+ if (isset($options['before'])) {
+ $func = "{$options['before']}; $func";
+ }
+
+ if (isset($options['after'])) {
+ $func = "$func; {$options['after']};";
+ }
+
+ if (isset($options['condition'])) {
+ $func = "if ({$options['condition']}) { $func; }";
+ }
+
+ if (isset($options['confirm'])) {
+ $func = "if (confirm('" . $this->Javascript->escapeString($options['confirm'])
+ . "')) { $func; } else { event.returnValue = false; return false; }";
+ }
+ return $func;
+ }
+/**
+ * Periodically call remote url via AJAX.
+ *
+ * Periodically calls the specified url (<i>options['url']</i>) every <i>options['frequency']</i> seconds (default is 10).
+ * Usually used to update a specified div (<i>options['update']</i>) with the results of the remote call.
+ * The options for specifying the target with url and defining callbacks is the same as link.
+ *
+ * @link http://wiki.script.aculo.us/scriptaculous/show/Ajax.Updater
+ * @param array $options Callback options
+ * @return string Javascript codeblock
+ * @access public
+ */
+ function remoteTimer($options = null) {
+ $frequency=(isset($options['frequency'])) ? $options['frequency'] : 10;
+ $code="new PeriodicalExecuter(function() {" . $this->remoteFunction($options) . "}, $frequency)";
+ return $this->Javascript->codeBlock($code);
+ }
+/**
+ * Returns form tag that will submit using Ajax.
+ *
+ * Returns a form tag that will submit using XMLHttpRequest in the background instead of the regular
+ * reloading POST arrangement. Even though it's using Javascript to serialize the form elements, the form submission
+ * will work just like a regular submission as viewed by the receiving side (all elements available in params).
+ * The options for defining callbacks is the same as link().
+ *
+ * @param array $params Form target
+ * @param array $type How form data is posted: 'get' or 'post'
+ * @param array $options Callback/HTML options
+ * @return string JavaScript/HTML code
+ * @access public
+ */
+ function form($params = null, $type = 'post', $options = array()) {
+ if (is_array($params)) {
+ extract($params, EXTR_OVERWRITE);
+
+ if (!isset($action)) {
+ $action = null;
+ }
+
+ if (!isset($type)) {
+ $type = 'post';
+ }
+
+ if (!isset($options)) {
+ $options = array();
+ }
+ } else {
+ $action = $params;
+ }
+ $htmlOptions = $this->__getHtmlOptions($options);
+ $htmlOptions['action'] = $action;
+
+ if (!isset($htmlOptions['id'])) {
+ $htmlOptions['id'] = 'form' . intval(rand());
+ }
+ $htmlOptions['onsubmit']="event.returnValue = false; return false;";
+
+ if (!isset($options['with'])) {
+ $options['with'] = "Form.serialize('{$htmlOptions['id']}')";
+ }
+ $options['url']=$action;
+
+ return $this->Html->formTag($htmlOptions['action'], $type, $htmlOptions)
+ . $this->Javascript->event("'" . $htmlOptions['id']. "'", "submit", $this->remoteFunction($options));
+ }
+/**
+ * Returns a button input tag that will submit using Ajax
+ *
+ * Returns a button input tag that will submit form using XMLHttpRequest in the background instead of regular
+ * reloading POST arrangement. <i>options</i> argument is the same as in <i>form_remote_tag</i>
+ *
+ * @param string $title Input button title
+ * @param array $options Callback options
+ * @return string Ajaxed input button
+ * @access public
+ */
+ function submit($title = 'Submit', $options = array()) {
+ $htmlOptions =$this->__getHtmlOptions($options);
+ $htmlOptions['value']=$title;
+
+ if (!isset($options['with'])) {
+ $options['with'] = 'Form.serialize(Event.element(event).form)';
+ }
+
+ if (!isset($htmlOptions['id'])) {
+ $htmlOptions['id'] = 'submit' . intval(rand());
+ }
+ $htmlOptions['onclick']="event.returnValue = false; return false;";
+ return $this->Html->submit($title, $htmlOptions)
+ . $this->Javascript->event('"' . $htmlOptions['id'] . '"', 'click', $this->remoteFunction($options));
+ }
+/**
+ * Observe field and call ajax on change.
+ *
+ * Observes the field with the DOM ID specified by <i>field_id</i> and makes
+ * an Ajax when its contents have changed.
+ *
+ * Required +options+ are:
+ * - <i>frequency</i>:: The frequency (in seconds) at which changes to
+ * this field will be detected.
+ * - <i>url</i>:: @see urlFor() -style options for the action to call
+ * when the field has changed.
+ *
+ * Additional options are:
+ * - <i>update</i>:: Specifies the DOM ID of the element whose
+ * innerHTML should be updated with the
+ * XMLHttpRequest response text.
+ * - <i>with</i>:: A Javascript expression specifying the
+ * parameters for the XMLHttpRequest. This defaults
+ * to Form.Element.serialize('$field_id'), which can be
+ * accessed from params['form']['field_id'].
+ *
+ * @see link().
+ * @param string $field_id DOM ID of field to observe
+ * @param array $options ajax options
+ * @return string ajax script
+ * @access public
+ */
+ function observeField($field_id, $options = array()) {
+ if (!isset($options['with'])) {
+ $options['with'] = "Form.Element.serialize('$field_id')";
+ }
+ return $this->Javascript->codeBlock($this->_buildObserver('Form.Element.Observer', $field_id, $options));
+ }
+/**
+ * Observe entire form and call ajax on change.
+ *
+ * Like @see observeField(), but operates on an entire form identified by the
+ * DOM ID <b>form_id</b>. <b>options</b> are the same as <b>observe_field</b>, except
+ * the default value of the <i>with</i> option evaluates to the
+ * serialized (request string) value of the form.
+ *
+ * @param string $field_id DOM ID of field to observe
+ * @param array $options ajax options
+ * @return string ajax script
+ * @access public
+ */
+ function observeForm($field_id, $options = array()) {
+ if (!isset($options['with'])) {
+ $options['with'] = 'Form.serialize("' . $field_id . '")';
+ }
+ return $this->Javascript->codeBlock($this->_buildObserver('Form.Observer', $field_id, $options));
+ }
+/**
+ * Create a text field with Autocomplete.
+ *
+ * Creates an autocomplete field with the given ID and options.
+ *
+ * options['with'] defaults to "Form.Element.serialize('$field_id')",
+ * but can be any valid javascript expression defining the
+ *
+ * @link http://wiki.script.aculo.us/scriptaculous/show/Ajax.Autocompleter
+ * @param string $field_id DOM ID of field to observe
+ * @param string $url URL for the autocomplete action
+ * @param array $options Ajax options
+ * @return string Ajax script
+ * @access public
+ */
+ function autoComplete($field, $url = "", $options = array()) {
+ $var = '';
+ if (isset($options['var'])) {
+ $var = 'var ' . $options['var'] . ' = ';
+ unset($options['var']);
+ }
+
+ if (!isset($options['id'])) {
+ $options['id'] = Inflector::camelize(r("/", "_", $field));
+ }
+ $divOptions = array('id' => $options['id'] . "_autoComplete", 'class' => isset($options['class']) ? $options['class'] : 'auto_complete');
+
+ if (isset($options['div_id'])) {
+ $divOptions['id'] = $options['div_id'];
+ unset($options['div_id']);
+ }
+ $htmlOptions = $this->__getHtmlOptions($options);
+ $htmlOptions['autocomplete'] = "off";
+
+ foreach ($this->autoCompleteOptions as $opt) {
+ unset($htmlOptions[$opt]);
+ }
+
+ if (isset($options['tokens'])) {
+ if (is_array($options['tokens'])) {
+ $options['tokens'] = $this->Javascript->object($options['tokens']);
+ } else {
+ $options['tokens'] = '"' . $options['tokens'] . '"';
+ }
+ }
+ $options = $this->_optionsToString($options, array('paramName', 'indicator'));
+ $options = $this->_buildOptions($options, $this->autoCompleteOptions);
+ return $this->Html->input($field, $htmlOptions) . "\n" .
+ $this->Html->tag('div', $divOptions, true) . "</div>\n" .
+ $this->Javascript->codeBlock("{$var}new Ajax.Autocompleter('" . $htmlOptions['id']
+ . "', '" . $divOptions['id'] . "', '" . $this->Html->url($url) . "', " .
+ $options . ");");
+ }
+/**
+ * Setup a Draggable Element.
+ * For a reference on the options for this function, check out
+ *
+ * @link http://wiki.script.aculo.us/scriptaculous/show/Draggable
+ * @param sting $id the DOM id to enable
+ * @param array $options a set of options
+ * @return string Javascript::codeBlock();
+ * @access public
+ */
+ function drag($id, $options = array()) {
+ return $this->Javascript->codeBlock("new Draggable('$id', " . $this->_optionsForDraggable($options) . ");");
+ }
+/**
+ * Creates an Ajax-updateable DIV element
+ *
+ * @param string $id options for javascript
+ * @param array $options a set of options
+ * @return string HTML code
+ * @access public
+ */
+ function div($id, $options = array()) {
+ if (env('HTTP_X_UPDATE') != null) {
+ $divs = explode(' ', env('HTTP_X_UPDATE'));
+ if (in_array($id, $divs)) {
+ @ob_end_clean();
+ ob_start();
+ return '';
+ }
+ }
+ $attr = $this->Html->_parseAttributes(am($options, array('id' => $id)));
+ return $this->output(sprintf($this->tags['blockstart'], $attr));
+ }
+/**
+ * Closes an Ajax-updateable DIV element
+ *
+ * @param string $id The DOM ID of the element
+ * @return string HTML code
+ * @access public
+ */
+ function divEnd($id) {
+ if (env('HTTP_X_UPDATE') != null) {
+ $divs = explode(' ', env('HTTP_X_UPDATE'));
+ if (in_array($id, $divs)) {
+ $this->__ajaxBuffer[$id] = ob_get_contents();
+ ob_end_clean();
+ return '';
+ }
+ }
+ return $this->output($this->tags['blockend']);
+ }
+/**
+ * Protectd helper method to return an array of options for draggable.
+ *
+ * @param array $options
+ * @return array
+ * @access protected
+ */
+ function _optionsForDraggable($options) {
+ $options = $this->_optionsToString($options, array('handle', 'constraint'));
+ return $this->_buildOptions($options, $this->dragOptions);
+ }
+/**
+ * Setup a droppable element
+ * For a reference on the options for this function, check out
+ *
+ * @link http://wiki.script.aculo.us/scriptaculous/show/Droppables.add
+ * @param string $id
+ * @param array $options
+ * @return array
+ * @access public
+ */
+ function drop($id, $options = array()) {
+ $options = $this->_optionsForDroppable($options);
+ return $this->Javascript->codeBlock("Droppables.add('$id', $options);");
+ }
+/**
+ * Protected helper method to return an array of options for droppable.
+ *
+ * @param string $options
+ * @return string String of Javascript array definition
+ * @access protected
+ */
+ function _optionsForDroppable($options) {
+ $options = $this->_optionsToString($options, array('accept', 'overlap', 'hoverclass'));
+ return $this->_buildOptions($options, $this->dropOptions);
+ }
+/**
+ * Setup a remote droppable element.
+ *
+ * @link http://wiki.script.aculo.us/scriptaculous/show/Droppables.add
+ * @see link() and remoteFunction()
+ * @param string $id DOM id of droppable
+ * @param array $options ame as drop()
+ * @param array $ajaxOptions same as remoteFunction()
+ * @return string Javascript::codeBlock()
+ * @access public
+ */
+ function dropRemote($id, $options = array(), $ajaxOptions = array()) {
+ $options['onDrop'] = "function(element) {" . $this->remoteFunction($ajaxOptions) . "}";
+ $options = $this->_optionsForDroppable($options);
+ return $this->Javascript->codeBlock("Droppables.add('$id', $options);");
+ }
+/**
+ * Makes a slider control.
+ *
+ * @link http://wiki.script.aculo.us/scriptaculous/show/Slider
+ * @param string $id DOM ID of slider handle
+ * @param string $track_id DOM ID of slider track
+ * @param array $options Array of options to control the slider
+ * @return string Javascript::codeBlock()
+ * @access public
+ */
+ function slider($id, $track_id, $options = array()) {
+ $options = $this->_optionsToString($options, array('axis', 'handleImage', 'handleDisabled'));
+
+ if (isset($options['change'])) {
+ $options['onChange'] = $options['change'];
+ unset($options['change']);
+ }
+
+ if (isset($options['slide'])) {
+ $options['onSlide'] = $options['slide'];
+ unset($options['slide']);
+ }
+
+ $options = $this->_buildOptions($options, $this->sliderOptions);
+ return $this->Javascript->codeBlock("var $id = new Control.Slider('$id', '$track_id', $options);");
+ }
+/**
+ * Makes an Ajax In Place editor control.
+ *
+ * @link http://wiki.script.aculo.us/scriptaculous/show/Ajax.InPlaceEditor
+ * @param string $id DOM ID of input element
+ * @param string $url Postback URL of saved data
+ * @param array $options Array of options to control the editor, including ajaxOptions (see link).
+ * @return string Javascript::codeBlock()
+ * @access public
+ */
+ function editor($id, $url, $options = array()) {
+ $url = $this->Html->url($url);
+ $options['ajaxOptions'] = $this->__optionsForAjax($options);
+
+ foreach ($this->ajaxOptions as $opt) {
+ if (isset($options[$opt])) {
+ unset($options[$opt]);
+ }
+ }
+
+ if (isset($options['callback'])) {
+ $options['callback'] = 'function(form, value) {' . $options['callback'] . '}';
+ }
+
+ $options = $this->_optionsToString($options, array('okText', 'cancelText', 'savingText', 'formId', 'externalControl', 'highlightcolor', 'highlightendcolor', 'savingClassName', 'formClassName', 'loadTextURL', 'loadingText', 'clickToEditText'));
+ $options = $this->_buildOptions($options, $this->editorOptions);
+ return $this->Javascript->codeBlock("new Ajax.InPlaceEditor('{$id}', '{$url}', {$options});");
+ }
+/**
+ * Makes a list or group of floated objects sortable.
+ *
+ * @link http://wiki.script.aculo.us/scriptaculous/show/Sortable.create
+ * @param string $id DOM ID of parent
+ * @param array $options Array of options to control sort
+ * @return string Javascript::codeBlock()
+ * @access public
+ */
+ function sortable($id, $options = array()) {
+ if (!empty($options['url'])) {
+ $options['with'] = "Sortable.serialize('$id')";
+ $options['onUpdate'] = 'function(sortable) {' . $this->remoteFunction($options) . '}';
+ }
+
+ $options = $this->__optionsForSortable($options);
+ return $this->Javascript->codeBlock("Sortable.create('$id', $options);");
+ }
+/**
+ * Private method; generates sortables code from array options
+ *
+ * @param array $options
+ * @return string String of Javascript array definition
+ * @access private
+ */
+ function __optionsForSortable($options) {
+ $options = $this->_optionsToString($options, array('handle', 'tag', 'constraint', 'ghosting', 'only', 'hoverclass'));
+ return $this->_buildOptions($options, $this->sortOptions);
+ }
+/**
+ * Private helper function for Ajax.
+ *
+ * @param array $options
+ * @return string String of Javascript array definition
+ * @access private
+ */
+ function __optionsForAjax($options = array()) {
+
+ if (isset($options['indicator'])) {
+ if (isset($options['loading'])) {
+ $options['loading'] .= "Element.show('{$options['indicator']}');";
+ } else {
+ $options['loading'] = "Element.show('{$options['indicator']}');";
+ }
+ if (isset($options['complete'])) {
+ $options['complete'] .= "Element.hide('{$options['indicator']}');";
+ } else {
+ $options['complete'] = "Element.hide('{$options['indicator']}');";
+ }
+ unset($options['indicator']);
+ }
+
+ $jsOptions = am(
+ array('asynchronous' => 'true', 'evalScripts' => 'true'),
+ $this->_buildCallbacks($options)
+ );
+ $options = $this->_optionsToString($options, array('method'));
+
+ foreach ($options as $key => $value) {
+ switch($key) {
+ case 'type':
+ $jsOptions['asynchronous'] = ife(($value == 'synchronous'), 'false', 'true');
+ break;
+ case 'evalScripts':
+ $jsOptions['evalScripts'] = ife($value, 'true', 'false');
+ break;
+ case 'position':
+ $jsOptions['insertion'] = "Insertion." . Inflector::camelize($options['position']);
+ break;
+ case 'with':
+ $jsOptions['parameters'] = $options['with'];
+ break;
+ case 'form':
+ $jsOptions['parameters'] = 'Form.serialize(this)';
+ break;
+ case 'requestHeaders':
+ $keys = array();
+ foreach ($value as $key => $val) {
+ $keys[] = "'" . $key . "'";
+ $keys[] = "'" . $val . "'";
+ }
+ $jsOptions['requestHeaders'] = '[' . join(', ', $keys) . ']';
+ break;
+ }
+ }
+ return $this->_buildOptions($jsOptions, $this->ajaxOptions);
+ }
+/**
+ * Private Method to return a string of html options
+ * option data as a JavaScript options hash.
+ *
+ * @param array $options Options in the shape of keys and values
+ * @param array $extra Array of legal keys in this options context
+ * @return array Array of html options
+ * @access private
+ */
+ function __getHtmlOptions($options, $extra = array()) {
+ foreach ($this->ajaxOptions as $key) {
+ if (isset($options[$key])) {
+ unset($options[$key]);
+ }
+ }
+
+ foreach ($extra as $key) {
+ if (isset($options[$key])) {
+ unset($options[$key]);
+ }
+ }
+ return $options;
+ }
+/**
+ * Protected Method to return a string of JavaScript with the given
+ * option data as a JavaScript options hash.
+ *
+ * @param array $options Options in the shape of keys and values
+ * @param array $acceptable Array of legal keys in this options context
+ * @return string String of Javascript array definition
+ * @access protected
+ */
+ function _buildOptions($options, $acceptable) {
+ if (is_array($options)) {
+ $out = array();
+
+ foreach ($options as $k => $v) {
+ if (in_array($k, $acceptable)) {
+ $out[] = "$k:$v";
+ }
+ }
+
+ $out = join(', ', $out);
+ $out = '{' . $out . '}';
+ return $out;
+ } else {
+ return false;
+ }
+ }
+/**
+ * Protected Method to return JavaScript text for an observer...
+ *
+ * @param string $klass Name of JavaScript class
+ * @param string $name
+ * @param array $options Ajax options
+ * @return string Formatted JavaScript
+ * @access protected
+ */
+ function _buildObserver($klass, $name, $options = null) {
+ if (!isset($options['with']) && isset($options['update'])) {
+ $options['with'] = 'value';
+ }
+
+ $callback = $this->remoteFunction($options);
+ $javascript = "new $klass('$name', ";
+ $javascript .= (isset($options['frequency']) ? $options['frequency'] : 2) . ", function(element, value) {";
+ $javascript .= "$callback})";
+ return $javascript;
+ }
+/**
+ * Protected Method to return JavaScript text for all callbacks...
+ *
+ * @param array $options
+ * @return array
+ * @access protected
+ */
+ function _buildCallbacks($options) {
+ $callbacks = array();
+
+ foreach ($this->callbacks as $callback) {
+ if (isset($options[$callback])) {
+ $name = 'on' . ucfirst($callback);
+ $code = $options[$callback];
+ $callbacks[$name] = "function(request) {" . $code . "}";
+ }
+ }
+ return $callbacks;
+ }
+/**
+ * Protected Method to return a string of JavaScript with a string representation
+ * of given options array.
+ *
+ * @param array $options Ajax options array
+ * @param array $stringOpts Options as strings in an array
+ * @access private
+ * @return array
+ * @access protected
+ */
+ function _optionsToString($options, $stringOpts = array()) {
+ foreach ($stringOpts as $option) {
+ if (isset($options[$option]) && !$options[$option][0] != "'") {
+ if ($options[$option] === true || $options[$option] === 'true') {
+ $options[$option] = 'true';
+ } elseif ($options[$option] === false || $options[$option] === 'false') {
+ $options[$option] = 'false';
+ } else {
+ $options[$option] = "'{$options[$option]}'";
+ }
+ }
+ }
+ return $options;
+ }
+/**
+ * afterRender callback
+ *
+ * @return array
+ * @access public
+ */
+ function afterRender() {
+ if (env('HTTP_X_UPDATE') != null && count($this->__ajaxBuffer) > 0) {
+ $data = array();
+ $divs = explode(' ', env('HTTP_X_UPDATE'));
+
+ foreach ($this->__ajaxBuffer as $key => $val) {
+ if (in_array($key, $divs)) {
+ $data[] = $key . ':"' . rawurlencode($val) . '"';
+ }
+ }
+
+ $out = 'var __ajaxUpdater__ = {' . join(', ', $data) . '};' . "\n";
+ $out .= 'for (n in __ajaxUpdater__) { if (typeof __ajaxUpdater__[n] == "string" && $(n)) Element.update($(n), unescape(decodeURIComponent(__ajaxUpdater__[n]))); }';
+
+ @ob_end_clean();
+ e($this->Javascript->codeBlock($out));
+ exit();
+ }
+ }
+/**
+ * Replaced by AjaxHelper::link()
+ *
+ * @deprecated will not be avialable after 1.1.x.x
+ */
+ function linkToRemote($title, $options = array(), $html_options = array()) {
+ trigger_error('Deprecated function: use AjaxHelper::link', E_USER_WARNING);
+ $href = '#';
+
+ if (!empty($options['fallback']) && isset($options['fallback'])) {
+ $href = $options['fallback'];
+ }
+
+ if (isset($html_options['id'])) {
+ return $this->Html->link($title, $href, $html_options) .
+ $this->Javascript->event("$('{$html_options['id']}')", "click", $this->remoteFunction($options));
+ } else {
+ $html_options['onclick'] = $this->remoteFunction($options) . "; event.returnValue = false; return false;";
+ return $this->Html->link($title, $href, $html_options);
+ }
+ }
+}
+
+?> \ No newline at end of file
diff --git a/site/cake/libs/view/helpers/cache.php b/site/cake/libs/view/helpers/cache.php
new file mode 100644
index 0000000..a5ac934
--- /dev/null
+++ b/site/cake/libs/view/helpers/cache.php
@@ -0,0 +1,266 @@
+<?php
+/* SVN FILE: $Id: cache.php 6305 2008-01-02 02:33:56Z phpnut $ */
+/**
+ * Short description for file.
+ *
+ * Long description for file
+ *
+ * PHP versions 4 and 5
+ *
+ * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
+ * Copyright 2005-2008, Cake Software Foundation, Inc.
+ * 1785 E. Sahara Avenue, Suite 490-204
+ * Las Vegas, Nevada 89104
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
+ * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
+ * @package cake
+ * @subpackage cake.cake.libs.view.helpers
+ * @since CakePHP(tm) v 1.0.0.2277
+ * @version $Revision: 6305 $
+ * @modifiedby $LastChangedBy: phpnut $
+ * @lastmodified $Date: 2008-01-01 20:33:56 -0600 (Tue, 01 Jan 2008) $
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+/**
+ * Short description for file.
+ *
+ * Long description for file
+ *
+ * @package cake
+ * @subpackage cake.cake.libs.view.helpers
+ */
+class CacheHelper extends Helper{
+/**
+ * Array of strings replaced in cached views.
+ * The strings are found between <cake:nocache><cake:nocache> in views
+ *
+ * @var array
+ * @access private
+ */
+ var $__replace = array();
+/**
+ * Array of string that are replace with there var replace above.
+ * The strings are any content inside <cake:nocache><cake:nocache> and includes the tags in views
+ *
+ * @var array
+ * @access private
+ */
+ var $__match = array();
+/**
+ * holds the View object passed in final call to CacheHelper::cache()
+ *
+ * @var object
+ * @access public
+ */
+ var $view;
+/**
+ * Main method used to cache a view
+ *
+ * @param string $file File to cache
+ * @param string $out output to cache
+ * @param boolean $cache
+ * @return view ouput
+ */
+ function cache($file, $out, $cache = false) {
+ if (is_array($this->cacheAction)) {
+ $check = str_replace('/', '_', $this->here);
+ $replace = str_replace('/', '_', $this->base);
+ $match = str_replace($this->base, '', $this->here);
+ $match = str_replace('//', '/', $match);
+ $match = str_replace('/' . $this->controllerName . '/', '', $match);
+ $check = str_replace($replace, '', $check);
+ $check = str_replace('_' . $this->controllerName . '_', '', $check);
+ $check = convertSlash($check);
+ $check = preg_replace('/^_+/', '', $check);
+ $keys = str_replace('/', '_', array_keys($this->cacheAction));
+ $found = array_keys($this->cacheAction);
+ $index = null;
+ $count = 0;
+
+ foreach ($keys as $key => $value) {
+ if (strpos($check, $value) === 0) {
+ $index = $found[$count];
+ break;
+ }
+ $count++;
+ }
+
+ if (isset($index)) {
+ $pos1 = strrpos($match, '/');
+ $char = strlen($match) - 1;
+
+ if ($pos1 == $char) {
+ $match = substr($match, 0, $char);
+ }
+
+ $key = $match;
+ } elseif ($this->action == 'index') {
+ $index = 'index';
+ }
+ if (isset($this->cacheAction[$index])) {
+ $cacheTime = $this->cacheAction[$index];
+ } else {
+ $cacheTime = 0;
+ }
+ } else {
+ $cacheTime = $this->cacheAction;
+ }
+
+ if ($cacheTime != '' && $cacheTime > 0) {
+ $this->__parseFile($file, $out);
+
+ if ($cache === true) {
+ $cached = $this->__parseOutput($out);
+ $this->__writeFile($cached, $cacheTime);
+ }
+ return $out;
+ } else {
+ return $out;
+ }
+ }
+/**
+ * Parse file searching for no cache tags
+ *
+ * @param string $file
+ * @param boolean $cache
+ * @access private
+ */
+ function __parseFile($file, $cache) {
+ if (is_file($file)) {
+ $file = file_get_contents($file);
+ } elseif ($file = fileExistsInPath($file)) {
+ $file = file_get_contents($file);
+ }
+
+ preg_match_all('/(<cake:nocache>(?<=<cake:nocache>)[\\s\\S]*?(?=<\/cake:nocache>)<\/cake:nocache>)/i', $cache, $oresult, PREG_PATTERN_ORDER);
+ preg_match_all('/(?<=<cake:nocache>)([\\s\\S]*?)(?=<\/cake:nocache>)/i', $file, $result, PREG_PATTERN_ORDER);
+
+ if (!empty($result['0'])) {
+ $count = 0;
+
+ foreach ($result['0'] as $result) {
+ if (isset($oresult['0'][$count])) {
+ $this->__replace[] = $result;
+ $this->__match[] = $oresult['0'][$count];
+ }
+ $count++;
+ }
+ }
+ }
+/**
+ * Parse the output and replace cache tags
+ *
+ * @param sting $cache
+ * @return string with all replacements made to <cake:nocache><cake:nocache>
+ * @access private
+ */
+ function __parseOutput($cache) {
+ $count = 0;
+ if (!empty($this->__match)) {
+
+ foreach ($this->__match as $found) {
+ $original = $cache;
+ $length = strlen($found);
+ $position = 0;
+
+ for ($i = 1; $i <= 1; $i++) {
+ $position = strpos($cache, $found, $position);
+
+ if ($position !== false) {
+ $cache = substr($original, 0, $position);
+ $cache .= $this->__replace[$count];
+ $cache .= substr($original, $position + $length);
+ } else {
+ break;
+ }
+ }
+ $count++;
+ }
+ return $cache;
+ }
+ return $cache;
+ }
+/**
+ * Write a cached version of the file
+ *
+ * @param string $content
+ * @param sting $timestamp
+ * @return cached view
+ * @access private
+ */
+ function __writeFile($content, $timestamp) {
+ $now = time();
+
+ if (is_numeric($timestamp)) {
+ $cacheTime = $now + $timestamp;
+ } else {
+ $cacheTime = strtotime($timestamp, $now);
+ }
+
+ $cache = convertSlash($this->here);
+ if (empty($cache)) {
+ return;
+ }
+
+ $cache = $cache . '.php';
+ $file = '<!--cachetime:' . $cacheTime . '--><?php';
+ if (empty($this->plugin)) {
+ $file .= '
+ loadController(\'' . $this->view->name. '\');
+ loadModels();
+ ';
+ } else {
+ $file .= '
+ if (!class_exists(\'AppController\')) {
+ if (file_exists(\'' . APP . 'app_controller.php\')) {
+ require(\''. APP . 'app_controller.php\');
+ } else {
+ require(\''.CAKE . 'app_controller.php\');
+ }
+ }
+ loadPluginController(\''.$this->plugin.'\',\''.$this->view->name.'\');
+ loadPluginModels(\''.$this->plugin.'\');
+ ';
+ }
+ $file .= '$this->controller = new ' . $this->view->name . 'Controller();
+ $this->controller->plugin = \''.$this->plugin.'\';
+ $this->controller->_initComponents();
+ $this->helpers = unserialize(\'' . serialize($this->view->helpers) . '\');
+ $this->base = \'' . $this->view->base . '\';
+ $this->layout = \'' . $this->view->layout. '\';
+ $this->webroot = \'' . $this->view->webroot . '\';
+ $this->here = \'' . $this->view->here . '\';
+ $this->params = unserialize(stripslashes(\'' . addslashes(serialize($this->view->params)) . '\'));
+ $this->action = unserialize(\'' . serialize($this->view->action) . '\');
+ $this->data = unserialize(stripslashes(\'' . addslashes(serialize($this->view->data)) . '\'));
+ $this->themeWeb = \'' . $this->view->themeWeb . '\';
+ $this->plugin = \'' . $this->view->plugin . '\';
+ $loadedHelpers = array();
+ $loadedHelpers = $this->_loadHelpers($loadedHelpers, $this->helpers);
+ foreach (array_keys($loadedHelpers) as $helper)
+ {
+ $replace = strtolower(substr($helper, 0, 1));
+ $camelBackedHelper = preg_replace(\'/\\w/\', $replace, $helper, 1);
+ ${$camelBackedHelper} =& $loadedHelpers[$helper];
+
+ if (isset(${$camelBackedHelper}->helpers) && is_array(${$camelBackedHelper}->helpers))
+ {
+ foreach (${$camelBackedHelper}->helpers as $subHelper)
+ {
+ ${$camelBackedHelper}->{$subHelper} =& $loadedHelpers[$subHelper];
+ }
+ }
+ $this->loaded[$camelBackedHelper] = (${$camelBackedHelper});
+ }
+ ?>';
+ $content = preg_replace("/(<\\?xml)/", "<?php echo '$1';?>",$content);
+ $file .= $content;
+ return cache('views' . DS . $cache, $file, $timestamp);
+ }
+}
+?> \ No newline at end of file
diff --git a/site/cake/libs/view/helpers/form.php b/site/cake/libs/view/helpers/form.php
new file mode 100644
index 0000000..dbc8dc7
--- /dev/null
+++ b/site/cake/libs/view/helpers/form.php
@@ -0,0 +1,491 @@
+<?php
+/* SVN FILE: $Id: form.php 6305 2008-01-02 02:33:56Z phpnut $ */
+/**
+ * Automatic generation of HTML FORMs from given data.
+ *
+ * Used for scaffolding.
+ *
+ * PHP versions 4 and 5
+ *
+ * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
+ * Copyright 2005-2008, Cake Software Foundation, Inc.
+ * 1785 E. Sahara Avenue, Suite 490-204
+ * Las Vegas, Nevada 89104
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
+ * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
+ * @package cake
+ * @subpackage cake.cake.libs.view.helpers
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @version $Revision: 6305 $
+ * @modifiedby $LastChangedBy: phpnut $
+ * @lastmodified $Date: 2008-01-01 20:33:56 -0600 (Tue, 01 Jan 2008) $
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+/**
+ * Tag template for a div with a class attribute.
+ */
+ define('TAG_DIV', '<div class="%s">%s</div>');
+/**
+ * Tag template for a paragraph with a class attribute.
+ */
+ define('TAG_P_CLASS', '<p class="%s">%s</p>');
+/**
+ * Tag template for a label with a for attribute.
+ */
+ define('TAG_LABEL', '<label for="%s">%s</label>');
+/**
+ * Tag template for a fieldset with a legend tag inside.
+ */
+ define('TAG_FIELDSET', '<fieldset><legend>%s</legend>%s</label>');
+/**
+ * Form helper library.
+ *
+ * Automatic generation of HTML FORMs from given data.
+ *
+ * @package cake
+ * @subpackage cake.cake.libs.view.helpers
+ */
+class FormHelper extends Helper{
+/**
+ * Included helpers.
+ *
+ * @var array
+ * @access public
+ */
+ var $helpers = array('Html');
+/**
+ * Returns a formatted error message for given FORM field, NULL if no errors.
+ *
+ * @param string $field This should be "Modelname/fieldname"
+ * @return bool If there are errors this method returns true, else false.
+ * @access public
+ */
+ function isFieldError($field) {
+ $error=1;
+ $this->Html->setFormTag($field);
+
+ if ($error == $this->Html->tagIsInvalid($this->Html->model, $this->Html->field)) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+/**
+ * Returns a formatted LABEL element for HTML FORMs.
+ *
+ * @param string $tagName This should be "Modelname/fieldname"
+ * @param string $text Text that will appear in the label field.
+ * @return string The formatted LABEL element
+ * @access public
+ */
+ function labelTag($tagName, $text) {
+ return sprintf(TAG_LABEL, Inflector::camelize(str_replace('/', '_', $tagName)), $text);
+ }
+/**
+ * Returns a formatted DIV tag for HTML FORMs.
+ *
+ * @param string $class CSS class name of the div element.
+ * @param string $text String content that will appear inside the div element.
+ * @return string The formatted DIV element
+ * @access public
+ */
+ function divTag($class, $text) {
+ return sprintf(TAG_DIV, $class, $text);
+ }
+/**
+ * Returns a formatted P tag with class for HTML FORMs.
+ *
+ * @param string $class CSS class name of the p element.
+ * @param string $text Text that will appear inside the p element.
+ * @return string The formatted P element
+ * @access public
+ */
+ function pTag($class, $text) {
+ return sprintf(TAG_P_CLASS, $class, $text);
+ }
+/**
+ * Returns a formatted INPUT tag for HTML FORMs.
+ *
+ * @param string $tagName This should be "Modelname/fieldname"
+ * @param string $prompt Text that will appear in the label field.
+ * @param bool $required True if this field is a required field.
+ * @param string $errorMsg Text that will appear if an error has occurred.
+ * @param int $size Size attribute for INPUT element
+ * @param array $htmlOptions HTML options array.
+ * @return string The formatted INPUT element, with a label and wrapped in a div.
+ * @access public
+ */
+ function generateInputDiv($tagName, $prompt, $required = false, $errorMsg = null, $size = 20, $htmlOptions = null) {
+ $htmlAttributes = $htmlOptions;
+ $htmlAttributes['size'] = $size;
+ $str = $this->Html->input($tagName, $htmlAttributes);
+ $strLabel = $this->labelTag($tagName, $prompt);
+ $divClass = "optional";
+ if ($required) {
+ $divClass = "required";
+ }
+ $strError = "";
+
+ if ($this->isFieldError($tagName)) {
+ $strError = $this->pTag('error', $errorMsg);
+ $divClass = sprintf("%s error", $divClass);
+ }
+ $divTagInside = sprintf("%s %s %s", $strError, $strLabel, $str);
+ return $this->divTag($divClass, $divTagInside);
+ }
+/**
+ * Returns a formatted CHECKBOX tag inside a DIV for HTML FORMs.
+ *
+ * @param string $tagName This should be "Modelname/fieldname"
+ * @param string $prompt Text that will appear in the label field.
+ * @param bool $required True if this field is a required field.
+ * @param string $errorMsg Text that will appear if an error has occurred.
+ * @param array $htmlOptions HTML options array.
+ * @return string The formatted checkbox div
+ * @access public
+ */
+ function generateCheckboxDiv($tagName, $prompt, $required = false, $errorMsg = null, $htmlOptions = null) {
+ $htmlOptions['class'] = "inputCheckbox";
+ $str = $this->Html->checkbox($tagName, null, $htmlOptions);
+ $strLabel = $this->labelTag($tagName, $prompt);
+ $divClass = "optional";
+ if ($required) {
+ $divClass = "required";
+ }
+ $strError = "";
+
+ if ($this->isFieldError($tagName)) {
+ $strError = $this->pTag('error', $errorMsg);
+ $divClass = sprintf("%s error", $divClass);
+ }
+ $divTagInside = sprintf("%s %s %s", $strError, $strLabel, $str);
+ return $this->divTag($divClass, $divTagInside);
+ }
+/**
+ * Returns a formatted date option element for HTML FORMs.
+ *
+ * @param string $tagName This should be "Modelname/fieldname"
+ * @param string $prompt Text that will appear in the label field.
+ * @param bool $required True if this field is a required field.
+ * @param string $errorMsg Text that will appear if an error has occurred.
+ * @param int $size Not used.
+ * @param array $htmlOptions HTML options array
+ * @return string Date option wrapped in a div.
+ * @todo Remove the $size parameter from this method.
+ * @access public
+ */
+ function generateDate($tagName, $prompt, $required = false, $errorMsg = null, $size = 20, $htmlOptions = null, $selected = null) {
+ $str = $this->Html->dateTimeOptionTag($tagName, 'MDY', 'NONE', $selected, $htmlOptions);
+ $strLabel = $this->labelTag($tagName, $prompt);
+ $divClass = "optional";
+ if ($required) {
+ $divClass = "required";
+ }
+ $strError = "";
+
+ if ($this->isFieldError($tagName)) {
+ $strError = $this->pTag('error', $errorMsg);
+ $divClass = sprintf("%s error", $divClass);
+ }
+ $divTagInside = sprintf("%s %s %s", $strError, $strLabel, $str);
+ $requiredDiv = $this->divTag($divClass, $divTagInside);
+ return $this->divTag("date", $requiredDiv);
+ }
+/**
+ * Returns a formatted date option element for HTML FORMs.
+ *
+ * @param string $tagName This should be "Modelname/fieldname"
+ * @param string $prompt Text that will appear in the label field.
+ * @param bool $required True if this field is a required field.
+ * @param string $errorMsg Text that will appear if an error has occurred.
+ * @param int $size Not used.
+ * @param array $htmlOptions HTML options array
+ * @return string Date option wrapped in a div.
+ * @todo Remove the $size parameter from this method.
+ * @access public
+ */
+ function generateTime($tagName, $prompt, $required = false, $errorMsg = null, $size = 20, $htmlOptions = null, $selected = null) {
+ $str = $this->Html->dateTimeOptionTag($tagName, 'NONE', '24', $selected, $htmlOptions);
+ $strLabel = $this->labelTag($tagName, $prompt);
+ $divClass = "optional";
+ if ($required) {
+ $divClass = "required";
+ }
+ $strError = "";
+
+ if ($this->isFieldError($tagName)) {
+ $strError = $this->pTag('error', $errorMsg);
+ $divClass = sprintf("%s error", $divClass);
+ }
+ $divTagInside = sprintf("%s %s %s", $strError, $strLabel, $str);
+ $requiredDiv = $this->divTag($divClass, $divTagInside);
+ return $this->divTag("time", $requiredDiv);
+ }
+/**
+ * Returns a formatted year option element for HTML FORMs.
+ *
+ * @param string $tagName This should be "Modelname/fieldname"
+ * @param string $prompt Text that will appear in the label field.
+ * @param bool $required True if this field is a required field.
+ * @param string $errorMsg Text that will appear if an error has occurred.
+ * @param int $size Not used.
+ * @param array $htmlOptions HTML options array
+ * @return string Date option wrapped in a div.
+ * @todo Remove the $size parameter from this method.
+ * @access public
+ */
+ function generateYear($tagName, $prompt, $required = false, $errorMsg = null, $size = 20, $htmlOptions = null, $selected = null) {
+ $str = $this->Html->dateTimeOptionTag($tagName, 'Y', 'NONE', $selected, $htmlOptions);
+ $strLabel = $this->labelTag($tagName, $prompt);
+ $divClass = "optional";
+ if ($required) {
+ $divClass = "required";
+ }
+ $strError = "";
+
+ if ($this->isFieldError($tagName)) {
+ $strError = $this->pTag('error', $errorMsg);
+ $divClass = sprintf("%s error", $divClass);
+ }
+ $divTagInside = sprintf("%s %s %s", $strError, $strLabel, $str);
+ $requiredDiv = $this->divTag($divClass, $divTagInside);
+ return $this->divTag("year", $requiredDiv);
+ }
+/**
+ * Returns a formatted datetime option element for HTML FORMs.
+ *
+ * @param string $tagName This should be "Modelname/fieldname"
+ * @param string $prompt Text that will appear in the label field.
+ * @param bool $required True if this field is required.
+ * @param string $errorMsg Text that will appear if an error has occurred.
+ * @param int $size Not used.
+ * @param array $htmlOptions HTML options array
+ * @param array $selected Selected index in the dateTimeOption tag.
+ * @return string The formatted datetime option element wrapped in a div.
+ * @todo Remove the $size parameter from this method.
+ * @access public
+ */
+ function generateDateTime($tagName, $prompt, $required = false, $errorMsg = null, $size = 20, $htmlOptions = null, $selected = null) {
+ $str = $this->Html->dateTimeOptionTag($tagName, 'MDY', '12', $selected, $htmlOptions);
+ $strLabel = $this->labelTag($tagName, $prompt);
+ $divClass = "optional";
+ if ($required) {
+ $divClass = "required";
+ }
+ $strError = "";
+
+ if ($this->isFieldError($tagName)) {
+ $strError = $this->pTag('error', $errorMsg);
+ $divClass = sprintf("%s error", $divClass);
+ }
+ $divTagInside = sprintf("%s %s %s", $strError, $strLabel, $str);
+ $requiredDiv = $this->divTag($divClass, $divTagInside);
+ return $this->divTag("date", $requiredDiv);
+ }
+/**
+ * Returns a formatted TEXTAREA inside a DIV for use with HTML forms.
+ *
+ * @param string $tagName This should be "Modelname/fieldname"
+ * @param string $prompt Text that will appear in the label field.
+ * @param boolean $required True if this field is required.
+ * @param string $errorMsg ext that will appear if an error has occurred.
+ * @param integer $cols Number of columns.
+ * @param integer $rows Number of rows.
+ * @param array $htmlOptions HTML options array.
+ * @return string The formatted TEXTAREA element, wrapped in a div.
+ * @access public
+ */
+ function generateAreaDiv($tagName, $prompt, $required = false, $errorMsg = null, $cols = 60, $rows = 10, $htmlOptions = null) {
+ $htmlAttributes = $htmlOptions;
+ $htmlAttributes['cols'] = $cols;
+ $htmlAttributes['rows'] = $rows;
+ $str = $this->Html->textarea($tagName, $htmlAttributes);
+ $strLabel = $this->labelTag($tagName, $prompt);
+ $divClass = "optional";
+
+ if ($required) {
+ $divClass="required";
+ }
+ $strError = "";
+
+ if ($this->isFieldError($tagName)) {
+ $strError = $this->pTag('error', $errorMsg);
+ $divClass = sprintf("%s error", $divClass);
+ }
+ $divTagInside = sprintf("%s %s %s", $strError, $strLabel, $str);
+ return $this->divTag($divClass, $divTagInside);
+ }
+/**
+ * Returns a formatted SELECT tag for HTML FORMs.
+ *
+ * @param string $tagName This should be "Modelname/fieldname"
+ * @param string $prompt Text that will appear in the label field
+ * @param array $options Options to be contained in SELECT element
+ * @param string $selected Currently selected item
+ * @param array $selectAttr Array of HTML attributes for the SELECT element
+ * @param array $optionAttr Array of HTML attributes for the OPTION elements
+ * @param bool $required True if this field is required
+ * @param string $errorMsg Text that will appear if an error has occurred
+ * @return string The formatted INPUT element, wrapped in a div
+ * @access public
+ */
+ function generateSelectDiv($tagName, $prompt, $options, $selected = null, $selectAttr = null, $optionAttr = null, $required = false, $errorMsg = null) {
+ $str = $this->Html->selectTag($tagName, $options, $selected, $selectAttr, $optionAttr);
+ $strLabel = $this->labelTag($tagName, $prompt);
+ $divClass = "optional";
+
+ if ($required) {
+ $divClass = "required";
+ }
+ $strError = "";
+
+ if ($this->isFieldError($tagName)) {
+ $strError=$this->pTag('error', $errorMsg);
+ $divClass=sprintf("%s error", $divClass);
+ }
+ $divTagInside = sprintf("%s %s %s", $strError, $strLabel, $str);
+ return $this->divTag($divClass, $divTagInside);
+ }
+/**
+ * Returns a formatted submit widget for HTML FORMs.
+ *
+ * @param string $displayText Text that will appear on the widget
+ * @param array $htmlOptions HTML options array
+ * @return string The formatted submit widget
+ * @access public
+ */
+ function generateSubmitDiv($displayText, $htmlOptions = null) {
+ return $this->divTag('submit', $this->Html->submit($displayText, $htmlOptions));
+ }
+/**
+ * Generates a form to go onto a HtmlHelper object.
+ *
+ * @param array $fields An array of form field definitions
+ * @param boolean $readOnly True if the form should be rendered as READONLY
+ * @return string The completed form specified by the $fields parameter
+ * @access public
+ */
+ function generateFields($fields, $readOnly = false) {
+ $strFormFields = '';
+
+ foreach ($fields as $field) {
+ if (isset($field['type'])) {
+
+ if (!isset($field['required'])) {
+ $field['required'] = false;
+ }
+
+ if (!isset($field['errorMsg'])) {
+ $field['errorMsg'] = null;
+ }
+
+ if (!isset($field['htmlOptions'])) {
+ $field['htmlOptions'] = array();
+ }
+
+ if ($readOnly) {
+ $field['htmlOptions']['READONLY'] = "readonly";
+ }
+
+ switch($field['type']) {
+ case "input":
+ if (!isset($field['size'])) {
+ $field['size'] = 40;
+ }
+ $strFormFields = $strFormFields . $this->generateInputDiv($field['tagName'], $field['prompt'],
+ $field['required'], $field['errorMsg'], $field['size'], $field['htmlOptions']);
+ break;
+ case "checkbox":
+ $strFormFields = $strFormFields . $this->generateCheckboxDiv($field['tagName'], $field['prompt'],
+ $field['required'], $field['errorMsg'], $field['htmlOptions']);
+ break;
+ case "select":
+ case "selectMultiple":
+ if ("selectMultiple" == $field['type']) {
+ $field['selectAttr']['multiple'] = 'multiple';
+ $field['selectAttr']['class'] = 'selectMultiple';
+ }
+
+ if (!isset($field['selected'])) {
+ $field['selected'] = null;
+ }
+
+ if (!isset($field['selectAttr'])) {
+ $field['selectAttr'] = null;
+ }
+
+ if (!isset($field['optionsAttr'])) {
+ $field['optionsAttr'] = null;
+ }
+
+ if ($readOnly) {
+ $field['selectAttr']['DISABLED'] = true;
+ }
+
+ if (!isset($field['options'])) {
+ $field['options'] = null;
+ }
+ $strFormFields = $strFormFields . $this->generateSelectDiv($field['tagName'], $field['prompt'], $field['options'],
+ $field['selected'], $field['selectAttr'], $field['optionsAttr'], $field['required'], $field['errorMsg']);
+ break;
+ case "area":
+ if (!isset($field['rows'])) {
+ $field['rows'] = 10;
+ }
+
+ if (!isset($field['cols'])) {
+ $field['cols'] = 60;
+ }
+ $strFormFields = $strFormFields . $this->generateAreaDiv($field['tagName'], $field['prompt'],
+ $field['required'], $field['errorMsg'], $field['cols'], $field['rows'], $field['htmlOptions']);
+ break;
+ case "fieldset":
+ $strFieldsetFields = $this->generateFields($field['fields']);
+ $strFieldSet = sprintf(' <fieldset><legend>%s</legend><div class="notes"><h4>%s</h4><p class="last">%s</p></div>%s</fieldset>',
+ $field['legend'], $field['noteHeading'], $field['note'], $strFieldsetFields);
+ $strFormFields = $strFormFields . $strFieldSet;
+ break;
+ case "hidden":
+ if (!isset($field['value'])) {
+ $field['value'] = null;
+ }
+ $strFormFields = $strFormFields . $this->Html->hidden($field['tagName'], $field['value']);
+ break;
+ case "date":
+ if (!isset($field['selected'])) {
+ $field['selected'] = null;
+ }
+ $strFormFields = $strFormFields . $this->generateDate($field['tagName'], $field['prompt'], $field['required'], $field['errorMsg'], null, $field['htmlOptions'], $field['selected']);
+ break;
+ case "datetime":
+ if (!isset($field['selected'])) {
+ $field['selected'] = null;
+ }
+ $strFormFields = $strFormFields . $this->generateDateTime($field['tagName'], $field['prompt'], $field['required'], $field['errorMsg'], null, $field['htmlOptions'], $field['selected']);
+ break;
+ case "time":
+ if (!isset($field['selected'])) {
+ $field['selected'] = null;
+ }
+ $strFormFields = $strFormFields . $this->generateTime($field['tagName'], $field['prompt'], $field['required'], $field['errorMsg'], null, $field['htmlOptions'], $field['selected']);
+ break;
+ case "year":
+ if (!isset($field['selected'])) {
+ $field['selected'] = null;
+ }
+ $strFormFields = $strFormFields . $this->generateYear($field['tagName'], $field['prompt'], $field['required'], $field['errorMsg'], null, $field['htmlOptions'], $field['selected']);
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ return $strFormFields;
+ }
+}
+?> \ No newline at end of file
diff --git a/site/cake/libs/view/helpers/html.php b/site/cake/libs/view/helpers/html.php
new file mode 100644
index 0000000..a69c7dd
--- /dev/null
+++ b/site/cake/libs/view/helpers/html.php
@@ -0,0 +1,1257 @@
+<?php
+/* SVN FILE: $Id: html.php 6305 2008-01-02 02:33:56Z phpnut $ */
+/**
+ * Html Helper class file.
+ *
+ * Simplifies the construction of HTML elements.
+ *
+ * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
+ * Copyright 2005-2008, Cake Software Foundation, Inc.
+ * 1785 E. Sahara Avenue, Suite 490-204
+ * Las Vegas, Nevada 89104
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
+ * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
+ * @package cake
+ * @subpackage cake.cake.libs.view.helpers
+ * @since CakePHP(tm) v 0.9.1
+ * @version $Revision: 6305 $
+ * @modifiedby $LastChangedBy: phpnut $
+ * @lastmodified $Date: 2008-01-01 20:33:56 -0600 (Tue, 01 Jan 2008) $
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+/**
+ * Html Helper class for easy use of HTML widgets.
+ *
+ * HtmlHelper encloses all methods needed while working with HTML pages.
+ *
+ * @package cake
+ * @subpackage cake.cake.libs.view.helpers
+ */
+class HtmlHelper extends Helper {
+/**
+ * Base URL
+ *
+ * @var string
+ * @access public
+ */
+ var $base = null;
+/**
+ * URL to current action.
+ *
+ * @var string
+ * @access public
+ */
+ var $here = null;
+/**
+ * Parameter array.
+ *
+ * @var array
+ * @access public
+ */
+ var $params = array();
+/**
+ * Current action.
+ *
+ * @var string
+ * @access public
+ */
+ var $action = null;
+/**
+ * Controller::data;
+ *
+ * @var array
+ * @access public
+ */
+ var $data = null;
+/**
+ * Name of model this helper is attached to.
+ *
+ * @var string
+ * @access public
+ */
+ var $model = null;
+/**
+ *
+ * @var string
+ * @access public
+ */
+ var $field = null;
+/**
+ * Breadcrumbs.
+ *
+ * @var array
+ * @access protected
+ */
+ var $_crumbs = array();
+/**
+ * Adds a link to the breadcrumbs array.
+ *
+ * @param string $name Text for link
+ * @param string $link URL for link
+ * @return void
+ * @access public
+ */
+ function addCrumb($name, $link) {
+ $this->_crumbs[] = array($name, $link);
+ }
+/**
+ * Returns a charset META-tag.
+ *
+ * @param string $charset
+ * @param boolean $return Wheter this method should return a value or output it. This overrides AUTO_OUTPUT.
+ * @return mixed Either string or echos the value, depends on AUTO_OUTPUT and $return.
+ * @access public
+ */
+ function charset($charset = null, $return = false) {
+ if (is_null($charset)) {
+ $charset = 'utf-8';
+ }
+ return $this->output(sprintf($this->tags['charset'], $charset), $return);
+ }
+/**
+ * Finds URL for specified action.
+ *
+ * Returns an URL pointing to a combination of controller and action. Param
+ * $url can be:
+ * + Empty - the method will find adress to actuall controller/action.
+ * + '/' - the method will find base URL of application.
+ * + A combination of controller/action - the method will find url for it.
+ *
+ * @param string $url Cake-relative URL, like "/products/edit/92" or "/presidents/elect/4"
+ * @param boolean $return Wheter this method should return a value or output it. This overrides AUTO_OUTPUT.
+ * @return mixed Either string or echos the value, depends on AUTO_OUTPUT and $return.
+ * @access public
+ */
+ function url($url = null, $return = false) {
+ if (isset($this->plugin)) {
+ $base = strip_plugin($this->base, $this->plugin);
+ } else {
+ $base = $this->base;
+ }
+
+ if (empty($url)) {
+ return $this->here;
+ } elseif ($url{0} == '/') {
+ $output = $base . $url;
+ } else {
+ $output = $base . '/' . Inflector::underscore($this->params['controller']) . '/' . $url;
+ }
+
+ return $this->output($output, $return);
+ }
+/**
+ * Creates an HTML link.
+ *
+ * If $url starts with "http://" this is treated as an external link. Else,
+ * it is treated as a path to controller/action and parsed with the
+ * HtmlHelper::url() method.
+ *
+ * If the $url is empty, $title is used instead.
+ *
+ * @param string $title The content of the A tag.
+ * @param string $url Cake-relative URL, or external URL (starts with http://)
+ * @param array $htmlAttributes Array of HTML attributes.
+ * @param string $confirmMessage Confirmation message.
+ * @param boolean $escapeTitle Whether or not the text in the $title variable should be HTML escaped.
+ * @param boolean $return Wheter this method should return a value or output it. This overrides AUTO_OUTPUT.
+ * @return mixed Either string or echos the value, depends on AUTO_OUTPUT and $return.
+ * @access public
+ */
+ function link($title, $url = null, $htmlAttributes = array(), $confirmMessage = false, $escapeTitle = true, $return = false) {
+ if ($escapeTitle === true) {
+ $title = htmlspecialchars($title, ENT_QUOTES);
+ } elseif (is_string($escapeTitle)) {
+ $title = htmlentities($title, ENT_QUOTES);
+ }
+ $url = $url ? $url : $title;
+
+ if ($confirmMessage) {
+ $confirmMessage = str_replace("'", "\'", $confirmMessage);
+ $confirmMessage = str_replace('"', '\"', $confirmMessage);
+ $htmlAttributes['onclick']="return confirm('{$confirmMessage}');";
+ }
+
+ if (((strpos($url, '://')) || (strpos($url, 'javascript:') === 0) || (strpos($url, 'mailto:') === 0) || substr($url,0,1) == '#')) {
+ $output = sprintf($this->tags['link'], $url, $this->_parseAttributes($htmlAttributes), $title);
+ } else {
+ $output = sprintf($this->tags['link'], $this->url($url, true), $this->_parseAttributes($htmlAttributes), $title);
+ }
+ return $this->output($output, $return);
+ }
+/**
+ * Creates a submit widget.
+ *
+ * @param string $caption Text on submit button
+ * @param array $htmlAttributes Array of HTML attributes.
+ * @param boolean $return Wheter this method should return a value or output it. This overrides AUTO_OUTPUT.
+ * @return mixed Either string or echos the value, depends on AUTO_OUTPUT and $return.
+ * @access public
+ */
+ function submit($caption = 'Submit', $htmlAttributes = array(), $return = false) {
+ $htmlAttributes['value'] = $caption;
+ return $this->output(sprintf($this->tags['submit'], $this->_parseAttributes($htmlAttributes, null, '', ' ')), $return);
+ }
+/**
+ * Creates a password input widget.
+ *
+ * @param string $fieldName Name of a field, like this "Modelname/fieldname"
+ * @param array $htmlAttributes Array of HTML attributes.
+ * @param boolean $return Wheter this method should return a value or output it. This overrides AUTO_OUTPUT.
+ * @return mixed Either string or echos the value, depends on AUTO_OUTPUT and $return.
+ * @access public
+ */
+ function password($fieldName, $htmlAttributes = array(), $return = false) {
+ $this->setFormTag($fieldName);
+ if (!isset($htmlAttributes['value'])) {
+ $htmlAttributes['value'] = $this->tagValue($fieldName);
+ }
+ if (!isset($htmlAttributes['id'])) {
+ $htmlAttributes['id'] = $this->model . Inflector::camelize($this->field);
+ }
+
+ if ($this->tagIsInvalid($this->model, $this->field)) {
+ if (isset($htmlAttributes['class']) && trim($htmlAttributes['class']) != "") {
+ $htmlAttributes['class'] .= ' form_error';
+ } else {
+ $htmlAttributes['class'] = 'form_error';
+ }
+ }
+ return $this->output(sprintf($this->tags['password'], $this->model, $this->field, $this->_parseAttributes($htmlAttributes, null, ' ', ' ')), $return);
+ }
+/**
+ * Creates a textarea widget.
+ *
+ * @param string $fieldName Name of a field, like this "Modelname/fieldname"
+ * @param array $htmlAttributes Array of HTML attributes.
+ * @param boolean $return Wheter this method should return a value or output it. This overrides AUTO_OUTPUT.
+ * @return mixed Either string or echos the value, depends on AUTO_OUTPUT and $return.
+ * @access public
+ */
+ function textarea($fieldName, $htmlAttributes = array(), $return = false) {
+ $this->setFormTag($fieldName);
+ $value = $this->tagValue($fieldName);
+ if (!empty($htmlAttributes['value'])) {
+ $value = $htmlAttributes['value'];
+ unset($htmlAttributes['value']);
+ }
+ if (!isset($htmlAttributes['id'])) {
+ $htmlAttributes['id'] = $this->model . Inflector::camelize($this->field);
+ }
+
+ if ($this->tagIsInvalid($this->model, $this->field)) {
+ if (isset($htmlAttributes['class']) && trim($htmlAttributes['class']) != "") {
+ $htmlAttributes['class'] .= ' form_error';
+ } else {
+ $htmlAttributes['class'] = 'form_error';
+ }
+ }
+ return $this->output(sprintf($this->tags['textarea'], $this->model, $this->field, $this->_parseAttributes($htmlAttributes, null, ' '), $value), $return);
+ }
+/**
+ * Creates a checkbox widget.
+ *
+ * @param string $fieldName Name of a field, like this "Modelname/fieldname"
+ * @deprecated string $title
+ * @param array $htmlAttributes Array of HTML attributes.
+ * @param boolean $return Wheter this method should return a value or output it. This overrides AUTO_OUTPUT.
+ * @return mixed Either string or echos the value, depends on AUTO_OUTPUT and $return.
+ * @access public
+ */
+ function checkbox($fieldName, $title = null, $htmlAttributes = array(), $return = false) {
+ $value = $this->tagValue($fieldName);
+ $notCheckedValue = 0;
+
+ if (!isset($htmlAttributes['id'])) {
+ $htmlAttributes['id'] = $this->model . Inflector::camelize($this->field);
+ }
+
+ if (isset($htmlAttributes['checked'])) {
+ if ($htmlAttributes['checked'] == 'checked' || intval($htmlAttributes['checked']) === 1 || $htmlAttributes['checked'] === true) {
+ $htmlAttributes['checked'] = 'checked';
+ } else {
+ $htmlAttributes['checked'] = null;
+ $notCheckedValue = -1;
+ }
+ } else {
+ if (isset($htmlAttributes['value']) || (!class_exists($this->model) && !loadModel($this->model))) {
+ $htmlAttributes['checked'] = ($htmlAttributes['value'] == $value) ? 'checked' : null;
+
+ if ($htmlAttributes['value'] == '0') {
+ $notCheckedValue = -1;
+ }
+ } else {
+ $model = new $this->model;
+ $db =& ConnectionManager::getDataSource($model->useDbConfig);
+ $value = $db->boolean($value);
+ $htmlAttributes['checked'] = $value ? 'checked' : null;
+ $htmlAttributes['value'] = 1;
+ }
+ }
+
+ $output = $this->hidden($fieldName, array('value' => $notCheckedValue, 'id' => $htmlAttributes['id'] . '_'), true);
+ $output .= sprintf($this->tags['checkbox'], $this->model, $this->field, $this->_parseAttributes($htmlAttributes, null, '', ' '));
+ return $this->output($output, $return);
+ }
+/**
+ * Creates a link element for CSS stylesheets.
+ *
+ * @param string $path Path to CSS file
+ * @param string $rel Rel attribute. Defaults to "stylesheet".
+ * @param array $htmlAttributes Array of HTML attributes.
+ * @param boolean $return Wheter this method should return a value or output it. This overrides AUTO_OUTPUT.
+ * @return mixed Either string or echos the value, depends on AUTO_OUTPUT and $return.
+ * @access public
+ */
+ function css($path, $rel = 'stylesheet', $htmlAttributes = array(), $return = false) {
+ $url = "{$this->webroot}" . (COMPRESS_CSS ? 'c' : '') . $this->themeWeb . CSS_URL . $path . ".css";
+
+ if ($rel == 'import') {
+ return $this->output(sprintf($this->tags['style'], $this->parseHtmlOptions($htmlAttributes, null, '', ' '), '@import url(' . $url . ');'), $return);
+ } else {
+ return $this->output(sprintf($this->tags['css'], $rel, $url, $this->parseHtmlOptions($htmlAttributes, null, '', ' ')), $return);
+ }
+ }
+/**
+ * Creates file input widget.
+ *
+ * @param string $fieldName Name of a field, like this "Modelname/fieldname"
+ * @param array $htmlAttributes Array of HTML attributes.
+ * @param boolean $return Wheter this method should return a valueor output it. This overrides AUTO_OUTPUT.
+ * @return mixed Either string or echos the value, depends on AUTO_OUTPUT and $return.
+ * @access public
+ */
+ function file($fieldName, $htmlAttributes = array(), $return = false) {
+ if (strpos($fieldName, '/')) {
+ $this->setFormTag($fieldName);
+ if (!isset($htmlAttributes['id'])) {
+ $htmlAttributes['id'] = $this->model . Inflector::camelize($this->field);
+ }
+ return $this->output(sprintf($this->tags['file'], $this->model, $this->field, $this->_parseAttributes($htmlAttributes, null, '', ' ')), $return);
+ }
+ return $this->output(sprintf($this->tags['file_no_model'], $fieldName, $this->_parseAttributes($htmlAttributes, null, '', ' ')), $return);
+ }
+/**
+ * Returns the breadcrumb trail as a sequence of &raquo;-separated links.
+ *
+ * @param string $separator Text to separate crumbs.
+ * @param string $startText This will be the first crumb, if false it defaults to first crumb in array
+ * @param boolean $return Wheter this method should return a value or output it. This overrides AUTO_OUTPUT.
+ * @return mixed Either string or echos the value, depends on AUTO_OUTPUT and $return. If $this->_crumbs is empty, return null.
+ * @access public
+ */
+ function getCrumbs($separator = '&raquo;', $startText = false, $return = false) {
+ if (count($this->_crumbs)) {
+ $out = array();
+ if ($startText) {
+ $out[] = $this->link($startText, '/');
+ }
+
+ foreach ($this->_crumbs as $crumb) {
+ $out[] = $this->link($crumb[0], $crumb[1]);
+ }
+ return $this->output(join($separator, $out), $return);
+ } else {
+ return null;
+ }
+ }
+/**
+ * Creates a hidden input field.
+ *
+ * @param string $fieldName Name of a field, like this "Modelname/fieldname"
+ * @param array $htmlAttributes Array of HTML attributes.
+ * @param boolean $return Wheter this method should return a value or output it. This overrides AUTO_OUTPUT.
+ * @return mixed Either string or echos the value, depends on AUTO_OUTPUT and $return.
+ * @access public
+ */
+ function hidden($fieldName, $htmlAttributes = array(), $return = false) {
+ $this->setFormTag($fieldName);
+ if (!isset($htmlAttributes['value'])) {
+ $htmlAttributes['value'] = $this->tagValue($fieldName);
+ }
+ if (!isset($htmlAttributes['id'])) {
+ $htmlAttributes['id'] = $this->model . Inflector::camelize($this->field);
+ }
+ return $this->output(sprintf($this->tags['hidden'], $this->model, $this->field, $this->_parseAttributes($htmlAttributes, null, ' ', ' ')), $return);
+ }
+/**
+ * Creates a formatted IMG element.
+ *
+ * @param string $path Path to the image file, relative to the webroot/img/ directory.
+ * @param array $htmlAttributes Array of HTML attributes.
+ * @param boolean $return Wheter this method should return a value or output it. This overrides AUTO_OUTPUT.
+ * @return mixed Either string or echos the value, depends on AUTO_OUTPUT and $return.
+ * @access public
+ */
+ function image($path, $htmlAttributes = array(), $return = false) {
+ if (strpos($path, '://')) {
+ $url = $path;
+ } else {
+ $url = $this->webroot . $this->themeWeb . IMAGES_URL . $path;
+ }
+ return $this->output(sprintf($this->tags['image'], $url, $this->parseHtmlOptions($htmlAttributes, null, '', ' ')), $return);
+ }
+/**
+ * Creates a text input widget.
+ *
+ * @param string $fieldNamem Name of a field, like this "Modelname/fieldname"
+ * @param array $htmlAttributes Array of HTML attributes.
+ * @param boolean $return Wheter this method should return a value or output it. This overrides AUTO_OUTPUT.
+ * @return mixed Either string or echos the value, depends on AUTO_OUTPUT and $return.
+ * @access public
+ */
+ function input($fieldName, $htmlAttributes = array(), $return = false) {
+ $this->setFormTag($fieldName);
+ if (!isset($htmlAttributes['value'])) {
+ $htmlAttributes['value'] = $this->tagValue($fieldName);
+ }
+
+ if (!isset($htmlAttributes['type'])) {
+ $htmlAttributes['type'] = 'text';
+ }
+
+ if (!isset($htmlAttributes['id'])) {
+ $htmlAttributes['id'] = $this->model . Inflector::camelize($this->field);
+ }
+
+ if ($this->tagIsInvalid($this->model, $this->field)) {
+ if (isset($htmlAttributes['class']) && trim($htmlAttributes['class']) != "") {
+ $htmlAttributes['class'] .= ' form_error';
+ } else {
+ $htmlAttributes['class'] = 'form_error';
+ }
+ }
+ return $this->output(sprintf($this->tags['input'], $this->model, $this->field, $this->_parseAttributes($htmlAttributes, null, ' ', ' ')), $return);
+ }
+ /**
+ * Returns a formatted SELECT element.
+ *
+ * @param string $fieldName Name attribute of the SELECT
+ * @param array $optionElements Array of the OPTION elements (as 'value'=>'Text' pairs) to be used in the SELECT element
+ * @param mixed $selected Selected option
+ * @param array $selectAttr Array of HTML options for the opening SELECT element
+ * @param array $optionAttr Array of HTML options for the enclosed OPTION elements
+ * @param boolean $show_empty If true, the empty select option is shown
+ * @param boolean $return Whether this method should return a value
+ * @return string Formatted SELECT element
+ * @access public
+ */
+ function selectTag($fieldName, $optionElements, $selected = null, $selectAttr = array(), $optionAttr = null, $showEmpty = true, $return = false) {
+ $this->setFormTag($fieldName);
+ if ($this->tagIsInvalid($this->model, $this->field)) {
+ if (isset($selectAttr['class']) && trim($selectAttr['class']) != "") {
+ $selectAttr['class'] .= ' form_error';
+ } else {
+ $selectAttr['class'] = 'form_error';
+ }
+ }
+ if (!isset($selectAttr['id'])) {
+ $selectAttr['id'] = $this->model . Inflector::camelize($this->field);
+ }
+
+ if (!is_array($optionElements)) {
+ return null;
+ }
+
+ if (!isset($selected)) {
+ $selected = $this->tagValue($fieldName);
+ }
+
+ if (isset($selectAttr) && array_key_exists("multiple", $selectAttr)) {
+ $select[] = sprintf($this->tags['selectmultiplestart'], $this->model, $this->field, $this->parseHtmlOptions($selectAttr));
+ } else {
+ $select[] = sprintf($this->tags['selectstart'], $this->model, $this->field, $this->parseHtmlOptions($selectAttr));
+ }
+
+ if ($showEmpty == true) {
+ $select[] = sprintf($this->tags['selectempty'], $this->parseHtmlOptions($optionAttr));
+ }
+
+ foreach ($optionElements as $name => $title) {
+ $optionsHere = $optionAttr;
+
+ if (($selected != null) && ($selected == $name)) {
+ $optionsHere['selected'] = 'selected';
+ } elseif (is_array($selected) && in_array($name, $selected)) {
+ $optionsHere['selected'] = 'selected';
+ }
+
+ $select[] = sprintf($this->tags['selectoption'], $name, $this->parseHtmlOptions($optionsHere), h($title));
+ }
+
+ $select[] = sprintf($this->tags['selectend']);
+ return $this->output(implode("\n", $select), $return);
+ }
+/**
+ * Creates a set of radio widgets.
+ *
+ * @param string $fieldName Name of a field, like this "Modelname/fieldname"
+ * @param array $options Radio button options array
+ * @param array $inbetween String that separates the radio buttons.
+ * @param array $htmlAttributes Array of HTML attributes.
+ * @param boolean $return Wheter this method should return a value or output it. This overrides AUTO_OUTPUT.
+ * @return mixed Either string or echos the value, depends on AUTO_OUTPUT and $return.
+ * @access public
+ */
+ function radio($fieldName, $options, $inbetween = null, $htmlAttributes = array(), $return = false) {
+
+ $this->setFormTag($fieldName);
+ $value = isset($htmlAttributes['value']) ? $htmlAttributes['value'] : $this->tagValue($fieldName);
+ $out = array();
+
+ foreach ($options as $optValue => $optTitle) {
+ $optionsHere = array('value' => $optValue);
+ if ($value !== false && $optValue == $value) {
+ $optionsHere['checked'] = 'checked';
+ }
+ $parsedOptions = $this->parseHtmlOptions(array_merge($htmlAttributes, $optionsHere), null, '', ' ');
+ $individualTagName = "{$this->field}_{$optValue}";
+ $out[] = sprintf($this->tags['radio'], $this->model, $this->field, $individualTagName, $parsedOptions, $optTitle);
+ }
+
+ $out = join($inbetween, $out);
+ return $this->output($out ? $out : null, $return);
+ }
+/**
+ * Returns a SELECT element for days.
+ *
+ * @param string $tagName Prefix name for the SELECT element
+ * @deprecated string $value
+ * @param string $selected Option which is selected.
+ * @param array $optionAttr Attribute array for the option elements.
+ * @param boolean $showEmpty Show/hide the empty select option
+ * @return mixed
+ * @access public
+ */
+ function dayOptionTag($tagName, $value = null, $selected = null, $selectAttr = null, $optionAttr = null, $showEmpty = true) {
+ if (empty($selected) && $this->tagValue($tagName)) {
+ $selected = date('d', strtotime($this->tagValue($tagName)));
+ }
+ $dayValue = empty($selected) ? ($showEmpty == true ? NULL : date('d')) : $selected;
+ $days = array('01' => '1', '02' => '2', '03' => '3', '04' => '4', '05' => '5', '06' => '6', '07' => '7', '08' => '8', '09' => '9', '10' => '10', '11' => '11', '12' => '12', '13' => '13', '14' => '14', '15' => '15', '16' => '16', '17' => '17', '18' => '18', '19' => '19', '20' => '20', '21' => '21', '22' => '22', '23' => '23', '24' => '24', '25' => '25', '26' => '26', '27' => '27', '28' => '28', '29' => '29', '30' => '30', '31' => '31');
+ $option = $this->selectTag($tagName . "_day", $days, $dayValue, $selectAttr, $optionAttr, $showEmpty);
+ return $option;
+ }
+/**
+ * Returns a SELECT element for years
+ *
+ * @param string $tagName Prefix name for the SELECT element
+ * @deprecated string $value
+ * @param integer $minYear First year in sequence
+ * @param integer $maxYear Last year in sequence
+ * @param string $selected Option which is selected.
+ * @param array $optionAttr Attribute array for the option elements.
+ * @param boolean $showEmpty Show/hide the empty select option
+ * @return mixed
+ * @access public
+ */
+ function yearOptionTag($tagName, $value = null, $minYear = null, $maxYear = null, $selected = null, $selectAttr = null, $optionAttr = null, $showEmpty = true) {
+ if (empty($selected) && ($this->tagValue($tagName))) {
+ $selected = date('Y', strtotime($this->tagValue($tagName)));
+ }
+
+ $yearValue = empty($selected) ? ($showEmpty ? NULL : date('Y')) : $selected;
+ $currentYear = date('Y');
+ $maxYear = is_null($maxYear) ? $currentYear + 11 : $maxYear + 1;
+ $minYear = is_null($minYear) ? $currentYear - 60 : $minYear;
+
+ if ($minYear > $maxYear) {
+ $tmpYear = $minYear;
+ $minYear = $maxYear;
+ $maxYear = $tmpYear;
+ }
+
+ $minYear = $currentYear < $minYear ? $currentYear : $minYear;
+ $maxYear = $currentYear > $maxYear ? $currentYear : $maxYear;
+
+ for ($yearCounter = $minYear; $yearCounter < $maxYear; $yearCounter++) {
+ $years[$yearCounter] = $yearCounter;
+ }
+
+ return $this->selectTag($tagName . "_year", $years, $yearValue, $selectAttr, $optionAttr, $showEmpty);
+ }
+/**
+ * Returns a SELECT element for months.
+ *
+ * @param string $tagName Prefix name for the SELECT element
+ * @deprecated string $value
+ * @param string $selected Option which is selected.
+ * @param array $optionAttr Attribute array for the option elements.
+ * @param boolean $showEmpty Show/hide the empty select option
+ * @return mixed
+ * @access public
+ */
+ function monthOptionTag($tagName, $value = null, $selected = null, $selectAttr = null, $optionAttr = null, $showEmpty = true) {
+ if (empty($selected) && ($this->tagValue($tagName))) {
+ $selected = date('m', strtotime($this->tagValue($tagName)));
+ }
+ $monthValue = empty($selected) ? ($showEmpty ? NULL : date('m')) : $selected;
+ $months = array('01' => 'January', '02' => 'February', '03' => 'March', '04' => 'April', '05' => 'May', '06' => 'June', '07' => 'July', '08' => 'August', '09' => 'September', '10' => 'October', '11' => 'November', '12' => 'December');
+
+ return $this->selectTag($tagName . "_month", $months, $monthValue, $selectAttr, $optionAttr, $showEmpty);
+ }
+/**
+ * Returns a SELECT element for hours.
+ *
+ * @param string $tagName Prefix name for the SELECT element
+ * @deprecated string $value
+ * @param boolean $format24Hours True for 24 hours format
+ * @param string $selected Option which is selected.
+ * @param array $optionAttr Attribute array for the option elements.
+ * @return mixed
+ * @access public
+ */
+ function hourOptionTag($tagName, $value = null, $format24Hours = false, $selected = null, $selectAttr = null, $optionAttr = null, $showEmpty = true) {
+ if (empty($selected) && ($this->tagValue($tagName))) {
+ if ($format24Hours) {
+ $selected = date('H', strtotime($this->tagValue($tagName)));
+ } else {
+ $selected = date('g', strtotime($this->tagValue($tagName)));
+ }
+ }
+ if ($format24Hours) {
+ $hourValue = empty($selected) ? ($showEmpty ? NULL : date('H')) : $selected;
+ } else {
+ $hourValue = empty($selected) ? ($showEmpty ? NULL : date('g')) : $selected;
+ if (isset($selected) && intval($hourValue) == 0 && !$showEmpty) {
+ $hourValue = 12;
+ }
+ }
+
+ if ($format24Hours) {
+ $hours = array('00' => '00', '01' => '01', '02' => '02', '03' => '03', '04' => '04', '05' => '05', '06' => '06', '07' => '07', '08' => '08', '09' => '09', '10' => '10', '11' => '11', '12' => '12', '13' => '13', '14' => '14', '15' => '15', '16' => '16', '17' => '17', '18' => '18', '19' => '19', '20' => '20', '21' => '21', '22' => '22', '23' => '23');
+ } else {
+ $hours = array('01' => '1', '02' => '2', '03' => '3', '04' => '4', '05' => '5', '06' => '6', '07' => '7', '08' => '8', '09' => '9', '10' => '10', '11' => '11', '12' => '12');
+ }
+
+ $option = $this->selectTag($tagName . "_hour", $hours, $hourValue, $selectAttr, $optionAttr, $showEmpty);
+ return $option;
+ }
+/**
+ * Returns a SELECT element for minutes.
+ *
+ * @param string $tagName Prefix name for the SELECT element
+ * @deprecated string $value
+ * @param string $selected Option which is selected.
+ * @param array $optionAttr Attribute array for the option elements.
+ * @return mixed
+ * @access public
+ */
+ function minuteOptionTag($tagName, $value = null, $selected = null, $selectAttr = null, $optionAttr = null, $showEmpty = true) {
+ if (empty($selected) && ($this->tagValue($tagName))) {
+ $selected = date('i', strtotime($this->tagValue($tagName)));
+ }
+ $minValue = empty($selected) ? ($showEmpty ? NULL : date('i')) : $selected;
+
+ for ($minCount = 0; $minCount < 60; $minCount++) {
+ $mins[sprintf('%02d', $minCount)] = sprintf('%02d', $minCount);
+ }
+ $option = $this->selectTag($tagName . "_min", $mins, $minValue, $selectAttr, $optionAttr, $showEmpty);
+ return $option;
+ }
+
+/**
+ * Returns a SELECT element for AM or PM.
+ *
+ * @param string $tagName Prefix name for the SELECT element
+ * @deprecated string $value
+ * @param string $selected Option which is selected.
+ * @param array $optionAttr Attribute array for the option elements.
+ * @return mixed
+ * @access public
+ */
+ function meridianOptionTag($tagName, $value = null, $selected = null, $selectAttr = null, $optionAttr = null, $showEmpty = true) {
+ if (empty($selected) && ($this->tagValue($tagName))) {
+ $selected = date('a', strtotime($this->tagValue($tagName)));
+ }
+ $merValue = empty($selected) ? ($showEmpty ? NULL : date('a')) : $selected;
+ $meridians = array('am' => 'am', 'pm' => 'pm');
+
+ $option = $this->selectTag($tagName . "_meridian", $meridians, $merValue, $selectAttr, $optionAttr, $showEmpty);
+ return $option;
+ }
+/**
+ * Returns a set of SELECT elements for a full datetime setup: day, month and year, and then time.
+ *
+ * @param string $tagName Prefix name for the SELECT element
+ * @param string $dateFormat DMY, MDY, YMD or NONE.
+ * @param string $timeFormat 12, 24, NONE
+ * @param string $selected Option which is selected.
+ * @param array $optionAttr Attribute array for the option elements.
+ * @return string The HTML formatted OPTION element
+ * @access public
+ */
+ function dateTimeOptionTag($tagName, $dateFormat = 'DMY', $timeFormat = '12', $selected = null, $selectAttr = null, $optionAttr = null, $showEmpty = true) {
+ $day = null;
+ $month = null;
+ $year = null;
+ $hour = null;
+ $min = null;
+ $meridian = null;
+
+ if (empty($selected)) {
+ $selected = $this->tagValue($tagName);
+ }
+
+ if (!empty($selected)) {
+
+ if (is_int($selected)) {
+ $selected = strftime('%Y-%m-%d %H:%M:%S', $selected);
+ }
+
+ $meridian = 'am';
+ $pos = strpos($selected, '-');
+ if ($pos !== false) {
+ $date = explode('-', $selected);
+ $days = explode(' ', $date[2]);
+ $day = $days[0];
+ $month = $date[1];
+ $year = $date[0];
+ } else {
+ $days[1] = $selected;
+ }
+
+ if ($timeFormat != 'NONE' && !empty($timeFormat)) {
+ $time = explode(':', $days[1]);
+ $check = str_replace(':', '', $days[1]);
+
+ if (($check > 115959) && $timeFormat == '12') {
+ $time[0] = $time[0] - 12;
+ $meridian = 'pm';
+ } elseif ($time[0] > 12) {
+ $meridian = 'pm';
+ }
+
+ $hour = $time[0];
+ $min = $time[1];
+ }
+ }
+
+ $elements = array('Day','Month','Year','Hour','Minute','Meridian');
+ if (isset($selectAttr['id'])) {
+ if (is_string($selectAttr['id'])) {
+ // build out an array version
+ foreach ($elements as $element) {
+ $selectAttrName = 'select' . $element . 'Attr';
+ ${$selectAttrName} = $selectAttr;
+ ${$selectAttrName}['id'] = $selectAttr['id'] . $element;
+ }
+ } elseif (is_array($selectAttr['id'])) {
+ // check for missing ones and build selectAttr for each element
+ foreach ($elements as $element) {
+ $selectAttrName = 'select' . $element . 'Attr';
+ ${$selectAttrName} = $selectAttr;
+ ${$selectAttrName}['id'] = $selectAttr['id'][strtolower($element)];
+ }
+ }
+ } else {
+ // build the selectAttrName with empty id's to pass
+ foreach ($elements as $element) {
+ $selectAttrName = 'select' . $element . 'Attr';
+ ${$selectAttrName} = $selectAttr;
+ }
+ }
+
+ switch($dateFormat) {
+ case 'DMY': // so uses the new selex
+ $opt = $this->dayOptionTag($tagName, null, $day, $selectDayAttr, $optionAttr, $showEmpty) . '-' .
+ $this->monthOptionTag($tagName, null, $month, $selectMonthAttr, $optionAttr, $showEmpty) . '-' . $this->yearOptionTag($tagName, null, null, null, $year, $selectYearAttr, $optionAttr, $showEmpty);
+ break;
+ case 'MDY':
+ $opt = $this->monthOptionTag($tagName, null, $month, $selectMonthAttr, $optionAttr, $showEmpty) . '-' .
+ $this->dayOptionTag($tagName, null, $day, $selectDayAttr, $optionAttr, $showEmpty) . '-' . $this->yearOptionTag($tagName, null, null, null, $year, $selectYearAttr, $optionAttr, $showEmpty);
+ break;
+ case 'YMD':
+ $opt = $this->yearOptionTag($tagName, null, null, null, $year, $selectYearAttr, $optionAttr, $showEmpty) . '-' .
+ $this->monthOptionTag($tagName, null, $month, $selectMonthAttr, $optionAttr, $showEmpty) . '-' .
+ $this->dayOptionTag($tagName, null, $day, $selectDayAttr, $optionAttr, $showEmpty);
+ break;
+ case 'Y':
+ $opt = $this->yearOptionTag($tagName, null, null, null, $selected, $selectYearAttr, $optionAttr, $showEmpty);
+ break;
+ case 'NONE':
+ default:
+ $opt = '';
+ break;
+ }
+
+ switch($timeFormat) {
+ case '24':
+ $opt .= $this->hourOptionTag($tagName, null, true, $hour, $selectHourAttr, $optionAttr, $showEmpty) . ':' .
+ $this->minuteOptionTag($tagName, null, $min, $selectMinuteAttr, $optionAttr, $showEmpty);
+ break;
+ case '12':
+ $opt .= $this->hourOptionTag($tagName, null, false, $hour, $selectHourAttr, $optionAttr, $showEmpty) . ':' .
+ $this->minuteOptionTag($tagName, null, $min, $selectMinuteAttr, $optionAttr, $showEmpty) . ' ' .
+ $this->meridianOptionTag($tagName, null, $meridian, $selectMeridianAttr, $optionAttr, $showEmpty);
+ break;
+ case 'NONE':
+ default:
+ $opt .= '';
+ break;
+ }
+ return $opt;
+ }
+/**
+ * Returns a row of formatted and named TABLE headers.
+ *
+ * @param array $names Array of tablenames.
+ * @param array $trOptions HTML options for TR elements.
+ * @param array $thOptions HTML options for TH elements.
+ * @param boolean $return Wheter this method should return a value
+ * @return string
+ * @access public
+ */
+ function tableHeaders($names, $trOptions = null, $thOptions = null, $return = false) {
+ $out = array();
+ foreach ($names as $arg) {
+ $out[] = sprintf($this->tags['tableheader'], $this->parseHtmlOptions($thOptions), $arg);
+ }
+
+ $data = sprintf($this->tags['tablerow'], $this->parseHtmlOptions($trOptions), join(' ', $out));
+ return $this->output($data, $return);
+ }
+/**
+ * Returns a formatted string of table rows (TR's with TD's in them).
+ *
+ * @param array $data Array of table data
+ * @param array $oddTrOptionsHTML options for odd TR elements
+ * @param array $evenTrOptionsHTML options for even TR elements
+ * @param boolean $return Wheter this method should return a value
+ * @return string Formatted HTML
+ * @access public
+ */
+ function tableCells($data, $oddTrOptions = null, $evenTrOptions = null, $return = false) {
+ if (empty($data[0]) || !is_array($data[0])) {
+ $data = array($data);
+ }
+ static $count = 0;
+
+ foreach ($data as $line) {
+ $count++;
+ $cellsOut = array();
+
+ foreach ($line as $cell) {
+ $cellsOut[] = sprintf($this->tags['tablecell'], null, $cell);
+ }
+ $options = $this->parseHtmlOptions($count % 2 ? $oddTrOptions : $evenTrOptions);
+ $out[] = sprintf($this->tags['tablerow'], $options, join(' ', $cellsOut));
+ }
+ return $this->output(join("\n", $out), $return);
+ }
+/**
+ * Generates a nested unordered list tree from an array.
+ *
+ * @param array $data
+ * @param array $htmlAttributes
+ * @param string $bodyKey
+ * @param string $childrenKey
+ * @param boolean $return Wheter this method should return a value or output it. This overrides AUTO_OUTPUT.
+ * @return mixed Either string or echos the value, depends on AUTO_OUTPUT and $return. If $this->_crumbs is empty, return null.
+ * @access public
+ */
+ function guiListTree($data, $htmlAttributes = array(), $bodyKey = 'body', $childrenKey = 'children', $return = false) {
+ $out="<ul" . $this->_parseAttributes($htmlAttributes) . ">\n";
+ foreach ($data as $item) {
+ $out .= "<li>{$item[$bodyKey]}\n";
+ if (isset($item[$childrenKey]) && is_array($item[$childrenKey]) && count($item[$childrenKey])) {
+ $out .= $this->guiListTree($item[$childrenKey], $htmlAttributes, $bodyKey, $childrenKey);
+ }
+ $out .= "</li>\n";
+ }
+ $out .= "</ul>\n";
+ return $this->output($out, $return);
+ }
+/**
+ * Returns value of $fieldName. False if the tag does not exist.
+ *
+ * @param string $fieldName Fieldname as "Modelname/fieldname" string
+ * @return string htmlspecialchars Value of the named tag.
+ * @access public
+ */
+ function tagValue($fieldName, $escape = false) {
+ $this->setFormTag($fieldName);
+ if (isset($this->params['data'][$this->model][$this->field])) {
+ return ife($escape, h($this->params['data'][$this->model][$this->field]), $this->params['data'][$this->model][$this->field]);
+ } elseif (isset($this->data[$this->model][$this->field])) {
+ return ife($escape, h($this->data[$this->model][$this->field]), $this->data[$this->model][$this->field]);
+ }
+ return false;
+ }
+/**
+ * Returns false if given FORM field has no errors. Otherwise it returns the constant set in the array Model->validationErrors.
+ *
+ * @param string $model Model name as string
+ * @param string $field Fieldname as string
+ * @return boolean True on errors.
+ * @access public
+ */
+ function tagIsInvalid($model, $field) {
+ return empty($this->validationErrors[$model][$field]) ? 0 : $this->validationErrors[$model][$field];
+ }
+/**
+ * Returns number of errors in a submitted FORM.
+ *
+ * @return int Number of errors
+ * @access public
+ */
+ function validate() {
+ $args = func_get_args();
+ $errors = call_user_func_array(array(&$this, 'validateErrors'), $args);
+ return count($errors);
+ }
+/**
+ * Validates a FORM according to the rules set up in the Model.
+ *
+ * @return int Number of errors
+ * @access public
+ */
+ function validateErrors() {
+ $objects = func_get_args();
+ if (!count($objects)) {
+ return false;
+ }
+
+ $errors = array();
+ foreach ($objects as $object) {
+ $errors = array_merge($errors, $object->invalidFields($object->data));
+ }
+ return $this->validationErrors = (count($errors) ? $errors : false);
+ }
+/**
+ * Returns a formatted error message for given FORM field, NULL if no errors.
+ *
+ * @param string $field A field name, like "Modelname/fieldname"
+ * @param string $text Error message
+ * @return string If there are errors this method returns an error message, else NULL.
+ * @access public
+ */
+ function tagErrorMsg($field, $text) {
+ $error = 1;
+ $this->setFormTag($field);
+ if ($error == $this->tagIsInvalid($this->model, $this->field)) {
+ return sprintf('<div class="error_message">%s</div>', is_array($text) ? (empty($text[$error - 1]) ? 'Error in field' : $text[$error - 1]) : $text);
+ } else {
+ return null;
+ }
+ }
+/**
+ * Sets this helper's model and field properties to the slash-separated value-pair in $tagValue.
+ *
+ * @param string $tagValue A field name, like "Modelname/fieldname"
+ * @return
+ * @access public
+ */
+ function setFormTag($tagValue) {
+ return list($this->model, $this->field) = explode("/", $tagValue);
+ }
+/**
+ * Returns a space-delimited string with items of the $options array. If a
+ * key of $options array happens to be one of:
+ * + 'compact'
+ * + 'checked'
+ * + 'declare'
+ * + 'readonly'
+ * + 'disabled'
+ * + 'selected'
+ * + 'defer'
+ * + 'ismap'
+ * + 'nohref'
+ * + 'noshade'
+ * + 'nowrap'
+ * + 'multiple'
+ * + 'noresize'
+ *
+ * And its value is one of:
+ * + 1
+ * + true
+ * + 'true'
+ *
+ * Then the value will be reset to be identical with key's name.
+ * If the value is not one of these 3, the parameter is not output.
+ *
+ * @param array $options Array of options.
+ * @param array $exclude Array of options to be excluded.
+ * @param string $insertBefore String to be inserted before options.
+ * @param string $insertAfter String to be inserted ater options.
+ * @return string
+ * @access protected
+ */
+ function _parseAttributes($options, $exclude = null, $insertBefore = ' ', $insertAfter = null) {
+ if (is_array($options)) {
+ $default = array (
+ 'escape' => true
+ );
+ $options = am($default, $options);
+ if (!is_array($exclude)) {
+ $exclude = array();
+ }
+ $exclude = am($exclude, array('escape'));
+ $keys = array_diff(array_keys($options), $exclude);
+ $values = array_intersect_key(array_values($options), $keys);
+ $escape = $options['escape'];
+ $attributes = array();
+ foreach ($keys as $index => $key) {
+ $attributes[] = $this->__formatAttribute($key, $values[$index], $escape);
+ }
+ $out = implode(' ', $attributes);
+ } else {
+ $out = $options;
+ }
+ return $out ? $insertBefore . $out . $insertAfter : '';
+ }
+/**
+ * @param string $key
+ * @param string $value
+ * @return string
+ * @access private
+ */
+ function __formatAttribute($key, $value, $escape = true) {
+ $attribute = '';
+ $attributeFormat = '%s="%s"';
+ $minimizedAttributes = array('compact', 'checked', 'declare', 'readonly', 'disabled', 'selected', 'defer', 'ismap', 'nohref', 'noshade', 'nowrap', 'multiple', 'noresize');
+
+ if (in_array($key, $minimizedAttributes)) {
+ if ($value === 1 || $value === true || $value === 'true' || $value == $key) {
+ $attribute = sprintf($attributeFormat, $key, $key);
+ }
+ } else {
+ $attribute = sprintf($attributeFormat, $key, ife($escape, h($value), $value));
+ }
+ return $attribute;
+ }
+/**
+ * @deprecated Name changed to 'textarea'. Version 0.9.2.
+ * @see HtmlHelper::textarea()
+ */
+ function areaTag($tagName, $cols = 60, $rows = 10, $htmlAttributes = array(), $return = false) {
+ $htmlAttributes['cols']=$cols;
+ $htmlAttributes['rows']=$rows;
+ return $this->textarea($tagName, $htmlAttributes, $return);
+ }
+/**
+ * @deprecated Name changed to 'charset'. Version 0.9.2.
+ * @see HtmlHelper::charset()
+ */
+ function charsetTag($charset, $return = false) {
+ return $this->charset($charset, $return);
+ }
+/**
+ * @deprecated Name changed to 'checkbox'. Version 0.9.2.
+ * @see HtmlHelper::checkbox()
+ */
+ function checkboxTag($fieldName, $title = null, $htmlAttributes = array(), $return = false) {
+ return $this->checkbox($fieldName, $title, $htmlAttributes, $return);
+ }
+/**
+ * @deprecated Name changed to 'css'. Version 0.9.2.
+ * @see HtmlHelper::css()
+ */
+ function cssTag($path, $rel = 'stylesheet', $htmlAttributes = array(), $return = false) {
+ return $this->css($path, $rel, $htmlAttributes, $return);
+ }
+/**
+ * @deprecated Name changed to 'file'. Version 0.9.2.
+ * @see HtmlHelper::file()
+ */
+ function fileTag($fieldName, $htmlAttributes = array(), $return = false) {
+ return $this->file($fieldName, $htmlAttributes, $return);
+ }
+/**
+ * @deprecated Name changed to 'hidden'. Version 0.9.2.
+ * @see HtmlHelper::hidden()
+ */
+ function hiddenTag($tagName, $value = null, $htmlOptions = null) {
+ $this->setFormTag($tagName);
+ $htmlOptions['value'] = $value ? $value : $this->tagValue($tagName);
+ return $this->output(sprintf($this->tags['hidden'], $this->model, $this->field, $this->parseHtmlOptions($htmlOptions, null, '', ' ')));
+ }
+/**
+ * @deprecated Name changed to 'image'. Version 0.9.2.
+ * @see HtmlHelper::image()
+ */
+ function imageTag($path, $alt = null, $htmlAttributes = array(), $return = false) {
+ $htmlAttributes['alt'] = $alt;
+ return $this->image($path, $htmlAttributes, $return);
+ }
+/**
+ * @deprecated Name changed to 'input'. Version 0.9.2.
+ * @see HtmlHelper::input()
+ */
+ function inputTag($tagName, $size = 20, $htmlOptions = null) {
+ $this->setFormTag($tagName);
+ $htmlOptions['value'] = isset($htmlOptions['value']) ? $htmlOptions['value'] : $this->tagValue($tagName);
+ $this->tagIsInvalid($this->model, $this->field) ? $htmlOptions['class'] = 'form_error' : null;
+ return $this->output(sprintf($this->tags['input'], $this->model, $this->field, $this->parseHtmlOptions($htmlOptions, null, '', ' ')));
+ }
+/**
+ * @deprecated Unified with 'link'. Version 0.9.2.
+ * @see HtmlHelper::link()
+ */
+ function linkOut($title, $url = null, $htmlAttributes = array(), $escapeTitle = true, $return = false) {
+ return $this->link($title, $url, $htmlAttributes, false, $escapeTitle, $return);
+ }
+/**
+ * @deprecated Unified with 'link'. Version 0.9.2.
+ * @see HtmlHelper::link()
+ */
+ function linkTo($title, $url, $htmlAttributes = array(), $confirmMessage = false, $escapeTitle = true, $return = false) {
+ return $this->link($title, $url, $htmlAttributes, $confirmMessage, $escapeTitle, $return);
+ }
+/**
+ * @deprecated Name changed to '_parseAttributes'. Version 0.9.2.
+ * @see HtmlHelper::_parseAttributes()
+ */
+ function parseHtmlOptions($options, $exclude = null, $insertBefore = ' ', $insertAfter = null) {
+ if (!is_array($exclude))
+ $exclude=array();
+
+ if (is_array($options)) {
+ $out=array();
+
+ foreach ($options as $k => $v) {
+ if (!in_array($k, $exclude)) {
+ $out[] = "{$k}=\"{$v}\"";
+ }
+ }
+ $out = join(' ', $out);
+ return $out ? $insertBefore . $out . $insertAfter : null;
+ } else {
+ return $options ? $insertBefore . $options . $insertAfter : null;
+ }
+ }
+/**
+ * @deprecated Name changed to 'password'. Version 0.9.2.
+ * @see HtmlHelper::password()
+ */
+ function passwordTag($fieldName, $size = 20, $htmlAttributes = array(), $return = false) {
+ $args = func_get_args();
+ return call_user_func_array(array(&$this,
+ "password"), $args);
+ }
+/**
+ * @deprecated Name changed to 'radio'. Version 0.9.2.
+ * @see HtmlHelper::radio()
+ */
+ function radioTags($fieldName, $options, $inbetween = null, $htmlAttributes = array(), $return = false) {
+ return $this->radio($fieldName, $options, $inbetween, $htmlAttributes, $return);
+ }
+/**
+ * @deprecated Name changed to 'url'. Version 0.9.2.
+ * @see HtmlHelper::url()
+ */
+ function urlFor($url) {
+ return $this->url($url);
+ }
+/**
+ * @deprecated Name changed to 'submit'. Version 0.9.2.
+ * @see HtmlHelper::submit()
+ */
+ function submitTag() {
+ $args = func_get_args();
+ return call_user_func_array(array(&$this, "submit"), $args);
+ }
+/*************************************************************************
+ * Moved methods
+ *************************************************************************/
+/**
+ * @deprecated Moved to TextHelper. Version 0.9.2.
+ */
+ function trim() {
+ die("Method HtmlHelper::trim() was moved to TextHelper::trim().");
+ }
+/**
+ * @deprecated Moved to JavascriptHelper. Version 0.9.2.
+ */
+ function javascriptIncludeTag($url) {
+ die("Method HtmlHelper::javascriptIncludeTag() was moved to JavascriptHelper::link().");
+ }
+/**
+ * @deprecated Moved to JavascriptHelper. Version 0.9.2.
+ */
+ function javascriptTag($script) {
+ die("Method HtmlHelper::javascriptTag() was moved to JavascriptHelper::codeBlock().");
+ }
+/**
+ * This is very WYSIWYG unfriendly, use HtmlHelper::url() to get contents of "action" attribute. Version 0.9.2.
+ * @deprecated Version 0.9.2. Will not be available after 1.1.x.x
+ * @see FormHelper::create()
+ */
+ function formTag($target = null, $type = 'post', $htmlAttributes = array()) {
+ $htmlAttributes['action']=$this->urlFor ($target);
+ $htmlAttributes['method']=$type == 'get' ? 'get' : 'post';
+ $type == 'file' ? $htmlAttributes['enctype'] = 'multipart/form-data' : null;
+
+ $append = '';
+
+ if (isset($this->params['_Token']) && !empty($this->params['_Token'])) {
+ $append .= '<p style="display: inline; margin: 0px; padding: 0px;">';
+ $append .= $this->hidden('_Token/key', array('value' => $this->params['_Token']['key'], 'id' => '_TokenKey' . mt_rand()), true);
+ $append .= '</p>';
+ }
+
+ return sprintf($this->tags['form'], $this->parseHtmlOptions($htmlAttributes, null, '')) . $append;
+ }
+/**
+ * This should be done using a content filter.
+ * @deprecated Version 0.9.2. Will not be available after 1.1.x.x
+ */
+ function linkEmail($title, $email = null, $options = null) {
+ // if no $email, then title contains the email.
+ if (empty($email))
+ $email=$title;
+
+ $match=array();
+
+ // does the address contain extra attributes?
+ preg_match('!^(.*)(\?.*)$!', $email, $match);
+
+ // plaintext
+ if (empty($options['encode']) || !empty($match[2])) {
+ return sprintf($this->tags['mailto'], $email, $this->parseHtmlOptions($options), $title);
+ }
+ // encoded to avoid spiders
+ else {
+ $email_encoded=null;
+
+ for ($ii = 0; $ii < strlen($email); $ii++) {
+ if (preg_match('!\w!', $email[$ii])) {
+ $email_encoded .= '%' . bin2hex($email[$ii]);
+ } else {
+ $email_encoded .= $email[$ii];
+ }
+ }
+
+ $title_encoded=null;
+
+ for ($ii = 0; $ii < strlen($title); $ii++) {
+ $title_encoded .= preg_match('/^[A-Za-z0-9]$/', $title[$ii])
+ ? '&#x' . bin2hex($title[$ii]) . ';' : $title[$ii];
+ }
+
+ return sprintf($this->tags['mailto'], $email_encoded,
+ $this->parseHtmlOptions($options, array('encode')), $title_encoded);
+ }
+ }
+
+/**
+ * @deprecated Version 0.9.2. Will not be available after 1.1.x.x
+ */
+ function tag($name, $options = null, $open = false) {
+ $tag = "<$name " . $this->parseHtmlOptions($options);
+ $tag .= $open ? ">" : " >";
+ return $tag;
+ }
+/**
+ * @deprecated Version 0.9.2. Will not be available after 1.1.x.x
+ */
+ function contentTag($name, $content, $options = null) {
+ return "<$name " . $this->parseHtmlOptions($options) . ">$content</$name>";
+ }
+
+}
+?>
diff --git a/site/cake/libs/view/helpers/javascript.php b/site/cake/libs/view/helpers/javascript.php
new file mode 100644
index 0000000..1a07a72
--- /dev/null
+++ b/site/cake/libs/view/helpers/javascript.php
@@ -0,0 +1,317 @@
+<?php
+/* SVN FILE: $Id: javascript.php 6305 2008-01-02 02:33:56Z phpnut $ */
+/**
+ * Javascript Helper class file.
+ *
+ * PHP versions 4 and 5
+ *
+ * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
+ * Copyright 2005-2008, Cake Software Foundation, Inc.
+ * 1785 E. Sahara Avenue, Suite 490-204
+ * Las Vegas, Nevada 89104
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
+ * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
+ * @package cake
+ * @subpackage cake.cake.libs.view.helpers
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @version $Revision: 6305 $
+ * @modifiedby $LastChangedBy: phpnut $
+ * @lastmodified $Date: 2008-01-01 20:33:56 -0600 (Tue, 01 Jan 2008) $
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+/**
+ * Javascript Helper class for easy use of JavaScript.
+ *
+ * JavascriptHelper encloses all methods needed while working with JavaScript.
+ *
+ * @package cake
+ * @subpackage cake.cake.libs.view.helpers
+ */
+class JavascriptHelper extends Helper{
+ var $_cachedEvents = array();
+ var $_cacheEvents = false;
+ var $_cacheToFile = false;
+ var $_cacheAll = false;
+ var $_rules = array();
+/**
+ * Returns a JavaScript script tag.
+ *
+ * @param string $script The JavaScript to be wrapped in SCRIPT tags.
+ * @param boolean $allowCache Allows the script to be cached if non-event caching is active
+ * @return string The full SCRIPT element, with the JavaScript inside it.
+ * @access public
+ */
+ function codeBlock($script, $allowCache = true) {
+ if ($this->_cacheEvents && $this->_cacheAll && $allowCache) {
+ $this->_cachedEvents[] = $script;
+ } else {
+ return sprintf($this->tags['javascriptblock'], $script);
+ }
+ }
+/**
+ * Returns a JavaScript include tag (SCRIPT element)
+ *
+ * @param string $url URL to JavaScript file.
+ * @return string
+ * @access public
+ */
+ function link($url) {
+ if (strpos($url, '.js') === false) {
+ $url .= ".js";
+ }
+ return sprintf($this->tags['javascriptlink'], $this->webroot . $this->themeWeb . JS_URL . $url);
+ }
+/**
+ * Returns a JavaScript include tag for an externally-hosted script
+ *
+ * @param string $url URL to JavaScript file.
+ * @return string
+ * @access public
+ */
+ function linkOut($url) {
+ if (strpos($url, '.js') === false && strpos($url, '?') === false) {
+ $url .= '.js';
+ }
+ return sprintf($this->tags['javascriptlink'], $url);
+ }
+/**
+ * Escape carriage returns and single and double quotes for JavaScript segments.
+ *
+ * @param string $script string that might have javascript elements
+ * @return string escaped string
+ * @access public
+ */
+ function escapeScript($script) {
+ $script = r(array("\r\n", "\n", "\r"), '\n', $script);
+ $script = r(array('"', "'"), array('\"', "\\'"), $script);
+ return $script;
+ }
+/**
+ * Escape a string to be JavaScript friendly.
+ *
+ * List of escaped ellements:
+ * + "\r\n" => '\n'
+ * + "\r" => '\n'
+ * + "\n" => '\n'
+ * + '"' => '\"'
+ * + "'" => "\\'"
+ *
+ * @param string $script String that needs to get escaped.
+ * @return string Escaped string.
+ * @access public
+ */
+ function escapeString($string) {
+ $escape = array("\r\n" => '\n', "\r" => '\n', "\n" => '\n', '"' => '\"', "'" => "\\'");
+ return r(array_keys($escape), array_values($escape), $string);
+ }
+/**
+ * Attach an event to an element. Used with the Prototype library.
+ *
+ * @param string $object Object to be observed
+ * @param string $event event to observe
+ * @param string $observer function to call
+ * @param boolean $useCapture default true
+ * @return boolean true on success
+ * @access public
+ */
+ function event($object, $event, $observer = null, $useCapture = false) {
+
+ if ($useCapture == true) {
+ $useCapture = "true";
+ } else {
+ $useCapture = "false";
+ }
+
+ if ($object == 'window' || strpos($object, '$(') !== false || strpos($object, '"') !== false || strpos($object, '\'') !== false) {
+ $b = "Event.observe($object, '$event', function(event) { $observer }, $useCapture);";
+ } else {
+ $chars = array('#', ' ', ', ', '.', ':');
+ $found = false;
+ foreach ($chars as $char) {
+ if (strpos($object, $char) !== false) {
+ $found = true;
+ break;
+ }
+ }
+ if ($found) {
+ $this->_rules[$object] = $event;
+ } else {
+ $b = "Event.observe(\$('$object'), '$event', function(event) { $observer }, $useCapture);";
+ }
+ }
+
+ if (isset($b) && !empty($b)) {
+ if ($this->_cacheEvents === true) {
+ $this->_cachedEvents[] = $b;
+ return;
+ } else {
+ return $this->codeBlock($b);
+ }
+ }
+ }
+/**
+ * Cache JavaScript events created with event()
+ *
+ * @param boolean $file If true, code will be written to a file
+ * @param boolean $all If true, all code written with JavascriptHelper will be sent to a file
+ * @return void
+ * @access public
+ */
+ function cacheEvents($file = false, $all = false) {
+ $this->_cacheEvents = true;
+ $this->_cacheToFile = $file;
+ $this->_cacheAll = $all;
+ }
+/**
+ * Write cached JavaScript events
+ *
+ * @return string
+ * @access public
+ */
+ function writeEvents() {
+
+ $rules = array();
+ if (!empty($this->_rules)) {
+ foreach ($this->_rules as $sel => $event) {
+ $rules[] = "\t'{$sel}': function(element, event) {\n\t\t{$event}\n\t}";
+ }
+ $this->_cacheEvents = true;
+ }
+
+ if ($this->_cacheEvents) {
+
+ $this->_cacheEvents = false;
+ $events = $this->_cachedEvents;
+ $data = implode("\n", $events);
+ $this->_cachedEvents = array();
+
+ if (!empty($rules)) {
+ $data .= "\n\nvar SelectorRules = {\n" . implode(",\n\n", $rules) . "\n}\n";
+ $data .= "\nEventSelectors.start(SelectorRules);\n";
+ }
+
+ if (!empty($events) || !empty($rules)) {
+ if ($this->_cacheToFile) {
+ $filename = md5($data);
+ if (!file_exists(JS . $filename . '.js')) {
+ cache(r(WWW_ROOT, '', JS) . $filename . '.js', $data, '+999 days', 'public');
+ }
+ return $this->link($filename);
+ } else {
+ return $this->codeBlock("\n" . $data . "\n");
+ }
+ }
+ }
+ }
+/**
+ * Includes the Prototype Javascript library (and anything else) inside a single script tag.
+ *
+ * Note: The recommended approach is to copy the contents of
+ * javascripts into your application's
+ * public/javascripts/ directory, and use @see javascriptIncludeTag() to
+ * create remote script links.
+ *
+ * @param string $script name of script to include
+ * @return string script with all javascript in/javascripts folder
+ * @access public
+ */
+ function includeScript($script = "") {
+ if ($script == "") {
+ $dh = opendir(JS);
+ while (false !== ($filename = readdir($dh))) {
+ $files[] = $filename;
+ }
+ sort($files);
+ $javascript = '';
+ foreach ($files as $file) {
+ if (substr($file, -3) == '.js') {
+ $javascript .= file_get_contents(JS . "{$file}") . "\n\n";
+ }
+ }
+ } else {
+ $javascript = file_get_contents(JS . "$script.js") . "\n\n";
+ }
+ return $this->codeBlock("\n\n" . $javascript);
+ }
+/**
+ * Generates a JavaScript object in JavaScript Object Notation (JSON)
+ * from an array
+ *
+ * @param array $data Data to be converted
+ * @param boolean $block Wraps return value in a <script/> block if true
+ * @param string $prefix Prepends the string to the returned data
+ * @param string $postfix Appends the string to the returned data
+ * @param array $stringKeys A list of array keys to be treated as a string
+ * @param boolean $quoteKeys If false, treats $stringKey as a list of keys *not* to be quoted
+ * @param string $q The type of quote to use
+ * @return string A JSON code block
+ * @access public
+ */
+ function object($data = array(), $block = false, $prefix = '', $postfix = '', $stringKeys = array(), $quoteKeys = true, $q = "\"") {
+ if (is_object($data)) {
+ $data = get_object_vars($data);
+ }
+
+ $out = array();
+ $key = array();
+
+ if (is_array($data)) {
+ $keys = array_keys($data);
+ }
+
+ $numeric = true;
+ if (!empty($keys)) {
+ $numeric = (array_values($keys) === array_keys(array_values($keys)));
+ }
+
+ foreach ($data as $key => $val) {
+ if (is_array($val) || is_object($val)) {
+ $val = $this->object($val, false, '', '', $stringKeys, $quoteKeys, $q);
+ } else {
+ if ((!count($stringKeys) && !is_numeric($val) && !is_bool($val)) || ($quoteKeys && in_array($key, $stringKeys, true)) || (!$quoteKeys && !in_array($key, $stringKeys, true))) {
+ $val = $q . $this->escapeString($val) . $q;
+ }
+ if ($val === null) {
+ $val = 'null';
+ }
+ if (is_bool($val)) {
+ $val = ife($val, 'true', 'false');
+ }
+ }
+
+ if (!$numeric) {
+ $val = $q . $key . $q . ':' . $val;
+ }
+
+ $out[] = $val;
+ }
+
+ if (!$numeric) {
+ $rt = '{' . join(', ', $out) . '}';
+ } else {
+ $rt = '[' . join(', ', $out) . ']';
+ }
+ $rt = $prefix . $rt . $postfix;
+
+ if ($block) {
+ $rt = $this->codeBlock($rt);
+ }
+
+ return $rt;
+ }
+/**
+ * AfterRender callback. Writes any cached events to the view, or to a temp file.
+ *
+ * @return void
+ * @access public
+ */
+ function afterRender() {
+ echo $this->writeEvents();
+ }
+}
+?> \ No newline at end of file
diff --git a/site/cake/libs/view/helpers/number.php b/site/cake/libs/view/helpers/number.php
new file mode 100644
index 0000000..0484d77
--- /dev/null
+++ b/site/cake/libs/view/helpers/number.php
@@ -0,0 +1,88 @@
+<?php
+/* SVN FILE: $Id: number.php 6305 2008-01-02 02:33:56Z phpnut $ */
+/**
+ * Number Helper.
+ *
+ * Methods to make numbers more readable.
+ *
+ * PHP versions 4 and 5
+ *
+ * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
+ * Copyright 2005-2008, Cake Software Foundation, Inc.
+ * 1785 E. Sahara Avenue, Suite 490-204
+ * Las Vegas, Nevada 89104
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
+ * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
+ * @package cake
+ * @subpackage cake.cake.libs.view.helpers
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @version $Revision: 6305 $
+ * @modifiedby $LastChangedBy: phpnut $
+ * @lastmodified $Date: 2008-01-01 20:33:56 -0600 (Tue, 01 Jan 2008) $
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+/**
+ * Number helper library.
+ *
+ * Methods to make numbers more readable.
+ *
+ * @package cake
+ * @subpackage cake.cake.libs.view.helpers
+ */
+class NumberHelper extends Helper {
+/**
+ * Formats a number with a level of precision.
+ *
+ * @param float $number A floating point number.
+ * @param integer $precision The precision of the returned number.
+ * @return float Enter description here...
+ * @access public
+ */
+ function precision($number, $precision = 3) {
+ return sprintf("%01.{$precision}f", $number);
+ }
+
+/**
+ * Returns a formatted-for-humans file size.
+ *
+ * @param integer $length Size in bytes
+ * @return string Human readable size
+ * @access public
+ */
+ function toReadableSize($size) {
+ switch($size) {
+ case 0:
+ return '0 Bytes';
+ case 1:
+ return '1 Byte';
+ case $size < 1024:
+ return $size . ' Bytes';
+ case $size < 1024 * 1024:
+ return NumberHelper::precision($size / 1024, 0) . ' KB';
+ case $size < 1024 * 1024 * 1024:
+ return NumberHelper::precision($size / 1024 / 1024, 2) . ' MB';
+ case $size < 1024 * 1024 * 1024 * 1024:
+ return NumberHelper::precision($size / 1024 / 1024 / 1024, 2) . ' GB';
+ case $size < 1024 * 1024 * 1024 * 1024 * 1024:
+ return NumberHelper::precision($size / 1024 / 1024 / 1024 / 1024, 2) . ' TB';
+ }
+ }
+
+/**
+ * Formats a number into a percentage string.
+ *
+ * @param float $number A floating point number
+ * @param integer $precision The precision of the returned number
+ * @return string Percentage string
+ * @access public
+ */
+ function toPercentage($number, $precision = 2) {
+ return NumberHelper::precision($number, $precision) . '%';
+ }
+}
+?> \ No newline at end of file
diff --git a/site/cake/libs/view/helpers/session.php b/site/cake/libs/view/helpers/session.php
new file mode 100644
index 0000000..7b987b1
--- /dev/null
+++ b/site/cake/libs/view/helpers/session.php
@@ -0,0 +1,198 @@
+<?php
+/* SVN FILE: $Id: session.php 6305 2008-01-02 02:33:56Z phpnut $ */
+/**
+ * Short description for file.
+ *
+ * Long description for file
+ *
+ * PHP versions 4 and 5
+ *
+ * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
+ * Copyright 2005-2008, Cake Software Foundation, Inc.
+ * 1785 E. Sahara Avenue, Suite 490-204
+ * Las Vegas, Nevada 89104
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
+ * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
+ * @package cake
+ * @subpackage cake.cake.libs.view.helpers
+ * @since CakePHP(tm) v 1.1.7.3328
+ * @version $Revision: 6305 $
+ * @modifiedby $LastChangedBy: phpnut $
+ * @lastmodified $Date: 2008-01-01 20:33:56 -0600 (Tue, 01 Jan 2008) $
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+/**
+ * Session Helper.
+ *
+ * Session reading from the view.
+ *
+ * @package cake
+ * @subpackage cake.cake.libs.view.helpers
+ *
+ */
+if(!class_exists('cakesession')) {
+ uses('session');
+}
+class SessionHelper extends CakeSession {
+/**
+ * List of helpers used by this helper
+ *
+ * @var array
+ */
+ var $helpers = null;
+/**
+ * Used to determine if methods implementation is used, or bypassed
+ *
+ * @var boolean
+ */
+ var $__active = true;
+/**
+ * Class constructor
+ *
+ * @param string $base
+ */
+ function __construct($base = null) {
+ if (!defined('AUTO_SESSION') || AUTO_SESSION === true) {
+ parent::__construct($base, false);
+ } else {
+ $this->__active = false;
+ }
+ }
+/**
+ * Turn sessions on if 'Session.start' is set to false in core.php
+ *
+ * @param string $base
+ */
+ function activate($base = null) {
+ $this->__active = true;
+ }
+/**
+ * Used to read a session values set in a controller for a key or return values for all keys.
+ *
+ * In your view: $session->read('Controller.sessKey');
+ * Calling the method without a param will return all session vars
+ *
+ * @param string $name the name of the session key you want to read
+ *
+ * @return values from the session vars
+ * @access public
+ */
+ function read($name = null) {
+ if ($this->__active === true && $this->__start()) {
+ return parent::read($name);
+ }
+ return false;
+ }
+/**
+ * Used to check is a session key has been set
+ *
+ * In your view: $session->check('Controller.sessKey');
+ *
+ * @param string $name
+ * @return boolean
+ * @access public
+ */
+ function check($name) {
+ if ($this->__active === true && $this->__start()) {
+ return parent::check($name);
+ }
+ return false;
+ }
+/**
+ * Returns last error encountered in a session
+ *
+ * In your view: $session->error();
+ *
+ * @return string last error
+ * @access public
+ */
+ function error() {
+ if ($this->__active === true && $this->__start()) {
+ return parent::error();
+ }
+ return false;
+ }
+/**
+ * Used to render the message set in Controller::Session::setFlash()
+ *
+ * In your view: $session->flash('somekey');
+ * Will default to flash if no param is passed
+ *
+ * @param string $key The [Message.]key you are rendering in the view.
+ * @return string Will echo the value if $key is set, or false if not set.
+ * @access public
+ */
+ function flash($key = 'flash') {
+ if ($this->__active === true && $this->__start()) {
+ if (parent::check('Message.' . $key)) {
+ $flash = parent::read('Message.' . $key);
+
+ if ($flash['layout'] == 'default') {
+ $out = '<div id="' . $key . 'Message" class="message">' . $flash['message'] . '</div>';
+ } elseif ($flash['layout'] == '' || $flash['layout'] == null) {
+ $out = $flash['message'];
+ } else {
+ $view =& ClassRegistry::getObject('view');
+ list($tmpLayout, $tmpVars, $tmpTitle) = array($view->layout, $view->viewVars, $view->pageTitle);
+ list($view->layout, $view->viewVars, $view->pageTitle) = array($flash['layout'], $flash['params'], '');
+ $out = $view->renderLayout($flash['message']);
+ list($view->layout, $view->viewVars, $view->pageTitle) = array($tmpLayout, $tmpVars, $tmpTitle);
+ }
+ e($out);
+ parent::del('Message.' . $key);
+ return true;
+ }
+ }
+ return false;
+ }
+/**
+ * Used to check is a session is valid in a view
+ *
+ * @return boolean
+ * @access public
+ */
+ function valid() {
+ if ($this->__active === true && $this->__start()) {
+ return parent::valid();
+ }
+ }
+/**
+ * Override CakeSession::write().
+ * This method should not be used in a view
+ *
+ * @return boolean
+ * @access public
+ */
+ function write() {
+ trigger_error(__('You can not write to a Session from the view', true), E_USER_WARNING);
+ }
+/**
+ * Session id
+ *
+ * @return string Session id
+ * @access public
+ */
+ function id() {
+ return parent::id();
+ }
+/**
+ * Determine if Session has been started
+ * and attempt to start it if not
+ *
+ * @return boolean true if Session is already started, false if
+ * Session could not be started
+ * @access public
+ */
+ function __start() {
+ if(!parent::started()) {
+ parent::start();
+ }
+ return true;
+ }
+}
+?> \ No newline at end of file
diff --git a/site/cake/libs/view/helpers/text.php b/site/cake/libs/view/helpers/text.php
new file mode 100644
index 0000000..4b67afa
--- /dev/null
+++ b/site/cake/libs/view/helpers/text.php
@@ -0,0 +1,238 @@
+<?php
+/* SVN FILE: $Id: text.php 6305 2008-01-02 02:33:56Z phpnut $ */
+/**
+ * Text Helper
+ *
+ * Text manipulations: Highlight, excerpt, truncate, strip of links, convert email addresses to mailto: links...
+ *
+ * PHP versions 4 and 5
+ *
+ * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
+ * Copyright 2005-2008, Cake Software Foundation, Inc.
+ * 1785 E. Sahara Avenue, Suite 490-204
+ * Las Vegas, Nevada 89104
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
+ * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
+ * @package cake
+ * @subpackage cake.cake.libs.view.helpers
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @version $Revision: 6305 $
+ * @modifiedby $LastChangedBy: phpnut $
+ * @lastmodified $Date: 2008-01-01 20:33:56 -0600 (Tue, 01 Jan 2008) $
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+/**
+ * Included libraries.
+ *
+ */
+if (!class_exists('Flay')) {
+ uses('flay');
+}
+if (!class_exists('HtmlHelper')) {
+ uses('view' . DS . 'helpers' . DS . 'html');
+}
+/**
+ * Text helper library.
+ *
+ * Text manipulations: Highlight, excerpt, truncate, strip of links, convert email addresses to mailto: links...
+ *
+ * @package cake
+ * @subpackage cake.cake.libs.view.helpers
+ */
+class TextHelper extends Helper{
+/**
+ * Highlights a given phrase in a text.
+ *
+ * @param string $text Text to search the phrase in
+ * @param string $phrase The phrase that will be searched
+ * @param string $highlighter The piece of html with that the phrase will be highlighted
+ * @return string The highlighted text
+ * @access public
+ */
+ function highlight($text, $phrase, $highlighter = '<span class="highlight">\1</span>') {
+ if (empty($phrase))
+ return $text;
+
+ if (is_array($phrase)) {
+ $replace=array();
+ $with=array();
+
+ foreach ($phrase as $key => $value) {
+ if (empty($key)) {
+ $key =$value;
+ $value=$highlighter;
+ }
+
+ $replace[]='|(' . $key . ')|i';
+ $with[]=empty($value) ? $highlighter : $value;
+ }
+
+ return preg_replace($replace, $with, $text);
+ } else {
+ return preg_replace("|({$phrase})|i", $highlighter, $text);
+ }
+ }
+/**
+ * Strips given text of all links (<a href=....)
+ *
+ * @param string $text Text
+ * @return string The text without links
+ * @access public
+ */
+ function stripLinks($text) {
+ return preg_replace('|<a.*>(.*)<\/a>|im', '\1', $text);
+ }
+/**
+ * Adds links (<a href=....) to a given text, by finding text that begins with
+ * strings like http:// and ftp://.
+ *
+ * @param string $text Text to add links to
+ * @param array $htmlOptions Array of HTML options.
+ * @return string The text with links
+ * @access public
+ */
+ function autoLinkUrls($text, $htmlOptions = array()) {
+ $options='array(';
+
+ foreach ($htmlOptions as $option => $value) {
+ $options .= "'$option' => '$value', ";
+ }
+
+ $options .= ')';
+
+ $text = preg_replace_callback('#(?<!href="|">)((?:http|https|ftp|nntp)://[^ <]+)#i',
+ create_function('$matches',
+ '$Html = new HtmlHelper(); $Html->tags = $Html->loadConfig(); return $Html->link($matches[0], $matches[0],' . $options . ');'),
+ $text);
+ return preg_replace_callback('#(?<!href="|">)(?<!http://|https://|ftp://|nntp://)(www\.[^\n\%\ <]+[^<\n\%\,\.\ <])#i',
+ create_function('$matches',
+ '$Html = new HtmlHelper(); $Html->tags = $Html->loadConfig(); return $Html->link($matches[0], "http://" . $matches[0],' . $options . ');'),
+ $text);
+ }
+/**
+ * Adds email links (<a href="mailto:....) to a given text.
+ *
+ * @param string $text Text
+ * @param array $htmlOptions Array of HTML options.
+ * @return string The text with links
+ * @access public
+ */
+ function autoLinkEmails($text, $htmlOptions = array()) {
+ $options='array(';
+
+ foreach ($htmlOptions as $option => $value) {
+ $options .= "'$option' => '$value', ";
+ }
+
+ $options .= ')';
+
+ return preg_replace_callback(
+ '#([_A-Za-z0-9+-]+(?:\.[_A-Za-z0-9+-]+)*@[A-Za-z0-9-]+(?:\.[A-Za-z0-9-]+)*)#',
+ create_function('$matches',
+ '$Html = new HtmlHelper(); $Html->tags = $Html->loadConfig(); return $Html->linkEmail($matches[0], $matches[0],' . $options . ');'),
+ $text);
+ }
+/**
+ * Convert all links and email adresses to HTML links.
+ *
+ * @param string $text Text
+ * @param array $htmlOptions Array of HTML options.
+ * @return string The text with links
+ * @access public
+ */
+ function autoLink($text, $htmlOptions = array()) {
+ return $this->autoLinkEmails($this->autoLinkUrls($text, $htmlOptions), $htmlOptions);
+ }
+/**
+ * Truncates text.
+ *
+ * Cuts a string to the length of $length and replaces the last characters
+ * with the ending if the text is longer than length.
+ *
+ * @param string $text String to truncate.
+ * @param integer $length Length of returned string, including ellipsis.
+ * @param string $ending Ending to be appended to the trimmed string.
+ * @param boolean $exact If false, $test will not be cut mid-word
+ * @return string Trimmed string.
+ * @access public
+ */
+ function truncate($text, $length, $ending = '...', $exact = true) {
+ if (strlen($text) <= $length) {
+ return $text;
+ } else {
+ $truncate=substr($text, 0, $length - strlen($ending));
+
+ if (!$exact) {
+ $spacepos=strrpos($truncate, ' ');
+
+ if (isset($spacepos)) {
+ return substr($truncate, 0, $spacepos) . $ending;
+ }
+ }
+
+ return $truncate . $ending;
+ }
+ }
+/**
+ * Alias for truncate().
+ *
+ * @see TextHelper::truncate()
+ * @return Text::truncate()
+ * @access public
+ */
+ function trim() {
+ $args=func_get_args();
+ return call_user_func_array(array(&$this,
+ "truncate"), $args);
+ }
+/**
+ * Extracts an excerpt from the text surrounding the phrase with a number of characters on each side determined by radius.
+ *
+ * @param string $text String to search the phrase in
+ * @param string $phrase Phrase that will be searched for
+ * @param integer $radius The amount of characters that will be returned on each side of the founded phrase
+ * @param string $ending Ending that will be appended
+ * @return string
+ * @access public
+ */
+ function excerpt($text, $phrase, $radius = 100, $ending = "...") {
+ if (empty($text) or empty($phrase))
+ return $this->truncate($text, $radius * 2, $ending);
+
+ if ($radius < strlen($phrase))
+ $radius=strlen($phrase);
+
+ $pos =strpos($text, $phrase);
+ $startPos=$pos <= $radius ? 0 : $pos - $radius;
+ $endPos =$pos + strlen($phrase) + $radius >= strlen($text)
+ ? strlen($text) : $pos + strlen($phrase) + $radius;
+
+ $excerpt =substr($text, $startPos, $endPos - $startPos);
+
+ if ($startPos != 0)
+ $excerpt=substr_replace($excerpt, $ending, 0, strlen($phrase));
+
+ if ($endPos != strlen($text))
+ $excerpt=substr_replace($excerpt, $ending, -strlen($phrase));
+
+ return $excerpt;
+ }
+/**
+ * Text-to-html parser, similar to Textile or RedCloth, only with a little different syntax.
+ *
+ * @param string $text String to "flay"
+ * @param boolean $allowHtml Set to true if if html is allowed
+ * @return string "Flayed" text
+ * @todo Change this. We need a real Textile parser.
+ * @access public
+ */
+ function flay($text, $allowHtml = false) {
+ return Flay::toHtml($text, false, $allowHtml);
+ }
+}
+?> \ No newline at end of file
diff --git a/site/cake/libs/view/helpers/time.php b/site/cake/libs/view/helpers/time.php
new file mode 100644
index 0000000..e4fd82d
--- /dev/null
+++ b/site/cake/libs/view/helpers/time.php
@@ -0,0 +1,397 @@
+<?php
+/* SVN FILE: $Id: time.php 6305 2008-01-02 02:33:56Z phpnut $ */
+/**
+ * Time Helper class file.
+ *
+ * PHP versions 4 and 5
+ *
+ * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
+ * Copyright 2005-2008, Cake Software Foundation, Inc.
+ * 1785 E. Sahara Avenue, Suite 490-204
+ * Las Vegas, Nevada 89104
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
+ * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
+ * @package cake
+ * @subpackage cake.cake.libs.view.helpers
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @version $Revision: 6305 $
+ * @modifiedby $LastChangedBy: phpnut $
+ * @lastmodified $Date: 2008-01-01 20:33:56 -0600 (Tue, 01 Jan 2008) $
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+/**
+ * Time Helper class for easy use of time data.
+ *
+ * Manipulation of time data.
+ *
+ * @package cake
+ * @subpackage cake.cake.libs.view.helpers
+ */
+class TimeHelper extends Helper {
+/**
+ * Returns given string trimmed to given length, adding an ending (default: "..") if necessary.
+ *
+ * @param string $string String to trim
+ * @param integer $length Length of returned string, excluding ellipsis
+ * @param string $ending Ending to be appended after trimmed string
+ * @return string Trimmed string
+ * @access public
+ */
+ function trim($string, $length, $ending = '..') {
+ return substr($string, 0, $length) . (strlen($string) > $length ? $ending : null);
+ }
+/**
+ * Returns a UNIX timestamp, given either a UNIX timestamp or a valid strtotime() date string.
+ *
+ * @param string $date_string Datetime string
+ * @return string Formatted date string
+ * @access public
+ */
+ function fromString($date_string) {
+ if (is_integer($date_string) || is_numeric($date_string)) {
+ return intval($date_string);
+ } else {
+ return strtotime($date_string);
+ }
+ }
+/**
+ * Returns a nicely formatted date string for given Datetime string.
+ *
+ * @param string $date_string Datetime string or Unix timestamp
+ * @param boolean $return Whether this method should return a value or output it. This overrides AUTO_OUTPUT.
+ * @return string Formatted date string
+ * @access public
+ */
+ function nice($date_string = null, $return = false) {
+ if ($date_string != null) {
+ $date = $this->fromString($date_string);
+ } else {
+ $date = time();
+ }
+
+ $ret = date("D, M jS Y, H:i", $date);
+ return $this->output($ret, $return);
+ }
+/**
+ * Returns a formatted descriptive date string for given datetime string.
+ *
+ * If the given date is today, the returned string could be "Today, 16:54".
+ * If the given date was yesterday, the returned string could be "Yesterday, 16:54".
+ * If $date_string's year is the current year, the returned string does not
+ * include mention of the year.
+ *
+ * @param string $date_string Datetime string or Unix timestamp
+ * @param boolean $return Whether this method should return a value or output it. This overrides AUTO_OUTPUT.
+ * @return string Described, relative date string
+ * @access public
+ */
+ function niceShort($date_string = null, $return = false) {
+ $date = $date_string ? $this->fromString($date_string) : time();
+ $y = $this->isThisYear($date) ? '' : ' Y';
+
+ if ($this->isToday($date)) {
+ $ret = "Today, " . date("H:i", $date);
+ } elseif ($this->wasYesterday($date)) {
+ $ret = "Yesterday, " . date("H:i", $date);
+ } else {
+ $ret = date("M jS{$y}, H:i", $date);
+ }
+
+ return $this->output($ret, $return);
+ }
+/**
+ * Returns true if given datetime string is today.
+ *
+ * @param string $date_string Datetime string or Unix timestamp
+ * @param boolean $return Whether this method should return a value or output it. This overrides AUTO_OUTPUT.
+ * @return boolean True if datetime string is today
+ * @access public
+ */
+ function isToday($date_string, $return = false) {
+ $date = $this->fromString($date_string);
+ $ret = date('Y-m-d', $date) == date('Y-m-d', time());
+ return $this->output($ret, $return);
+ }
+/**
+ * Returns a partial SQL string to search for all records between two dates.
+ *
+ * @param string $date_string Datetime string or Unix timestamp
+ * @param string $end Datetime string or Unix timestamp
+ * @param string $field_name Name of database field to compare with
+ * @param boolean $return Whether this method should return a value or output it. This overrides AUTO_OUTPUT.
+ * @return string Partial SQL string.
+ * @access public
+ */
+ function daysAsSql($begin, $end, $field_name, $return = false) {
+ $begin = $this->fromString($begin);
+ $end = $this->fromString($end);
+ $begin = date('Y-m-d', $begin) . ' 00:00:00';
+ $end = date('Y-m-d', $end) . ' 23:59:59';
+
+ return $this->output("($field_name >= '$begin') AND ($field_name <= '$end')", $return);
+ }
+/**
+ * Returns a partial SQL string to search for all records between two times
+ * occurring on the same day.
+ *
+ * @param string $date_string Datetime string or Unix timestamp
+ * @param string $field_name Name of database field to compare with
+ * @param boolean $return Whether this method should return a value or output it. This overrides AUTO_OUTPUT.
+ * @return string Partial SQL string.
+ * @access public
+ */
+ function dayAsSql($date_string, $field_name, $return = false) {
+ $date = $this->fromString($date_string);
+ $ret = $this->daysAsSql($date_string, $date_string, $field_name);
+ return $this->output($ret, $return);
+ }
+/**
+ * Returns true if given datetime string is within current year.
+ *
+ * @param string $date_string Datetime string or Unix timestamp
+ * @param boolean $return Whether this method should return a value or output it. This overrides AUTO_OUTPUT.
+ * @return boolean True if datetime string is within current year
+ * @access public
+ */
+ function isThisYear($date_string, $return = false) {
+ $date = $this->fromString($date_string);
+ $ret = date('Y', $date) == date('Y', time());
+ return $this->output($ret, $return);
+ }
+/**
+ * Returns true if given datetime string was yesterday.
+ *
+ * @param string $date_string Datetime string or Unix timestamp
+ * @param boolean $return Whether this method should return a value or output it. This overrides AUTO_OUTPUT.
+ * @return boolean True if datetime string was yesterday
+ * @access public
+ */
+ function wasYesterday($date_string, $return = false) {
+ $date = $this->fromString($date_string);
+ $ret = date('Y-m-d', $date) == date('Y-m-d', strtotime('yesterday'));
+ return $this->output($ret, $return);
+ }
+/**
+ * Returns true if given datetime string is tomorrow.
+ *
+ * @param string $date_string Datetime string or Unix timestamp
+ * @param boolean $return Whether this method should return a value or output it. This overrides AUTO_OUTPUT.
+ * @return boolean True if datetime string was yesterday
+ * @access public
+ */
+ function isTomorrow($date_string, $return = false) {
+ $date = $this->fromString($date_string);
+ $ret = date('Y-m-d', $date) == date('Y-m-d', strtotime('tomorrow'));
+ return $this->output($ret, $return);
+ }
+/**
+ * Returns a UNIX timestamp from a textual datetime description. Wrapper for PHP function strtotime().
+ *
+ * @param string $date_string Datetime string to be represented as a Unix timestamp
+ * @param boolean $return Whether this method should return a value or output it. This overrides AUTO_OUTPUT.
+ * @return int Unix timestamp
+ * @access public
+ */
+ function toUnix($date_string, $return = false) {
+ $ret = strtotime($date_string);
+ return $this->output($ret, $return);
+ }
+/**
+ * Returns a date formatted for Atom RSS feeds.
+ *
+ * @param string $date_string Datetime string or Unix timestamp
+ * @param boolean $return Whether this method should return a value or output it. This overrides AUTO_OUTPUT.
+ * @return string Formatted date string
+ * @access public
+ */
+ function toAtom($date_string, $return = false) {
+ $date = $this->fromString($date_string);
+ $ret = date('Y-m-d\TH:i:s\Z', $date);
+ return $this->output($ret, $return);
+ }
+/**
+ * Formats date for RSS feeds
+ *
+ * @param string $date_string Datetime string or Unix timestamp
+ * @param boolean $return Whether this method should return a value or output it. This overrides AUTO_OUTPUT.
+ * @return string Formatted date string
+ * @access public
+ */
+ function toRSS($date_string, $return = false) {
+ $date = $this->fromString($date_string);
+ $ret = date("r", $date);
+ return $this->output($ret, $return);
+ }
+/**
+ * Returns either a relative date or a formatted date depending
+ * on the difference between the current time and given datetime.
+ * $datetime should be in a <i>strtotime</i>-parsable format, like MySQL's datetime datatype.
+ *
+ * Relative dates look something like this:
+ * 3 weeks, 4 days ago
+ * 15 seconds ago
+ * Formatted dates look like this:
+ * on 02/18/2004
+ *
+ * The returned string includes 'ago' or 'on' and assumes you'll properly add a word
+ * like 'Posted ' before the function output.
+ *
+ * @param string $date_string Datetime string or Unix timestamp
+ * @param string $format Default format if timestamp is used in $date_string
+ * @param string $backwards False if $date_string is in the past, true if in the future
+ * @param boolean $return Whether this method should return a value or output it. This overrides AUTO_OUTPUT.
+ * @return string Relative time string.
+ * @access public
+ */
+ function timeAgoInWords($datetime_string, $format = 'j/n/y', $backwards = false, $return = false) {
+ $datetime = $this->fromString($datetime_string);
+
+ $in_seconds = $datetime;
+ if ($backwards) {
+ $diff = $in_seconds - time();
+ } else {
+ $diff = time() - $in_seconds;
+ }
+
+ $months = floor($diff / 2419200);
+ $diff -= $months * 2419200;
+ $weeks = floor($diff / 604800);
+ $diff -= $weeks * 604800;
+ $days = floor($diff / 86400);
+ $diff -= $days * 86400;
+ $hours = floor($diff / 3600);
+ $diff -= $hours * 3600;
+ $minutes = floor($diff / 60);
+ $diff -= $minutes * 60;
+ $seconds = $diff;
+
+ if ($months > 0) {
+ // over a month old, just show date (mm/dd/yyyy format)
+ $relative_date = 'on ' . date($format, $in_seconds);
+ $old = true;
+ } else {
+ $relative_date = '';
+ $old = false;
+
+ if ($weeks > 0) {
+ // weeks and days
+ $relative_date .= ($relative_date ? ', ' : '') . $weeks . ' week' . ($weeks > 1 ? 's' : '');
+ $relative_date .= $days > 0 ? ($relative_date ? ', ' : '') . $days . ' day' . ($days > 1 ? 's' : '') : '';
+ } elseif ($days > 0) {
+ // days and hours
+ $relative_date .= ($relative_date ? ', ' : '') . $days . ' day' . ($days > 1 ? 's' : '');
+ $relative_date .= $hours > 0 ? ($relative_date ? ', ' : '') . $hours . ' hour' . ($hours > 1 ? 's' : '') : '';
+ } elseif ($hours > 0) {
+ // hours and minutes
+ $relative_date .= ($relative_date ? ', ' : '') . $hours . ' hour' . ($hours > 1 ? 's' : '');
+ $relative_date .= $minutes > 0 ? ($relative_date ? ', ' : '') . $minutes . ' minute' . ($minutes > 1 ? 's' : '') : '';
+ } elseif ($minutes > 0) {
+ // minutes only
+ $relative_date .= ($relative_date ? ', ' : '') . $minutes . ' minute' . ($minutes > 1 ? 's' : '');
+ } else {
+ // seconds only
+ $relative_date .= ($relative_date ? ', ' : '') . $seconds . ' second' . ($seconds != 1 ? 's' : '');
+ }
+ }
+
+ $ret = $relative_date;
+
+ // show relative date and add proper verbiage
+ if (!$backwards && !$old) {
+ $ret .= ' ago';
+ }
+ return $this->output($ret, $return);
+ }
+/**
+ * Alias for timeAgoInWords
+ *
+ * @param string $date_string Datetime string or Unix timestamp
+ * @param string $format Default format if timestamp is used in $date_string
+ * @param boolean $return Whether this method should return a value or output it. This overrides AUTO_OUTPUT.
+ * @return string Relative time string.
+ * @see Time::timeAgoInWords()
+ * @access public
+ */
+ function relativeTime($datetime_string, $format = 'j/n/y', $return = false) {
+ $date = strtotime($datetime_string);
+
+ if (strtotime("now") > $date) {
+ $ret = $this->timeAgoInWords($datetime_string, $format, false);
+ } else {
+ $ret = $this->timeAgoInWords($datetime_string, $format, true);
+ }
+
+ return $this->output($ret, $return);
+ }
+/**
+ * Returns true if specified datetime was within the interval specified, else false.
+ *
+ * @param mixed $timeInterval the numeric value with space then time type. Example of valid types: 6 hours, 2 days, 1 minute.
+ * @param mixed $date_string the datestring or unix timestamp to compare
+ * @param boolean $return Whether this method should return a value or output it. This overrides AUTO_OUTPUT.
+ * @return boolean
+ * @access public
+ */
+ function wasWithinLast($timeInterval, $date_string, $return = false) {
+ $date = $this->fromString($date_string);
+ $result = preg_split('/\\s/', $timeInterval);
+ $numInterval = $result[0];
+ $textInterval = $result[1];
+ $currentTime = floor(time());
+ $seconds = ($currentTime - floor($date));
+
+ switch($textInterval) {
+ case "seconds":
+ case "second":
+ $timePeriod = $seconds;
+ $ret = $return;
+ break;
+ case "minutes":
+ case "minute":
+ $minutes = floor($seconds / 60);
+ $timePeriod = $minutes;
+ break;
+ case "hours":
+ case "hour":
+ $hours = floor($seconds / 3600);
+ $timePeriod = $hours;
+ break;
+ case "days":
+ case "day":
+ $days = floor($seconds / 86400);
+ $timePeriod = $days;
+ break;
+ case "weeks":
+ case "week":
+ $weeks = floor($seconds / 604800);
+ $timePeriod = $weeks;
+ break;
+ case "months":
+ case "month":
+ $months = floor($seconds / 2629743.83);
+ $timePeriod = $months;
+ break;
+ case "years":
+ case "year":
+ $years = floor($seconds / 31556926);
+ $timePeriod = $years;
+ break;
+ default:
+ $days = floor($seconds / 86400);
+ $timePeriod = $days;
+ break;
+ }
+ if ($timePeriod <= $numInterval) {
+ $ret = true;
+ } else {
+ $ret = false;
+ }
+ return $this->output($ret, $return);
+ }
+}
+?> \ No newline at end of file
diff --git a/site/cake/libs/view/templates/elements/dump.thtml b/site/cake/libs/view/templates/elements/dump.thtml
new file mode 100644
index 0000000..203414d
--- /dev/null
+++ b/site/cake/libs/view/templates/elements/dump.thtml
@@ -0,0 +1,32 @@
+<?php
+/* SVN FILE: $Id: dump.thtml 6305 2008-01-02 02:33:56Z phpnut $ */
+/**
+ *
+ * PHP versions 4 and 5
+ *
+ * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
+ * Copyright 2005-2008, Cake Software Foundation, Inc.
+ * 1785 E. Sahara Avenue, Suite 490-204
+ * Las Vegas, Nevada 89104
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
+ * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
+ * @package cake
+ * @subpackage cake.cake.libs.view.templates.elements
+ * @since CakePHP(tm) v 0.10.5.1782
+ * @version $Revision: 6305 $
+ * @modifiedby $LastChangedBy: phpnut $
+ * @lastmodified $Date: 2008-01-01 20:33:56 -0600 (Tue, 01 Jan 2008) $
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+?>
+<div>
+ <h2>Controller dump:</h2>
+ <pre>
+ <?php print_r($this->controller); ?>
+ </pre>
+</div> \ No newline at end of file
diff --git a/site/cake/libs/view/templates/errors/error404.thtml b/site/cake/libs/view/templates/errors/error404.thtml
new file mode 100644
index 0000000..986cb1a
--- /dev/null
+++ b/site/cake/libs/view/templates/errors/error404.thtml
@@ -0,0 +1,28 @@
+<?php
+/* SVN FILE: $Id: error404.thtml 6305 2008-01-02 02:33:56Z phpnut $ */
+/**
+ *
+ * PHP versions 4 and 5
+ *
+ * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
+ * Copyright 2005-2008, Cake Software Foundation, Inc.
+ * 1785 E. Sahara Avenue, Suite 490-204
+ * Las Vegas, Nevada 89104
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
+ * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
+ * @package cake
+ * @subpackage cake.cake.libs.view.templates.errors
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @version $Revision: 6305 $
+ * @modifiedby $LastChangedBy: phpnut $
+ * @lastmodified $Date: 2008-01-01 20:33:56 -0600 (Tue, 01 Jan 2008) $
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+?>
+<h1><?php echo $name; ?></h1>
+<p><?php echo $message; ?></p> \ No newline at end of file
diff --git a/site/cake/libs/view/templates/errors/missing_action.thtml b/site/cake/libs/view/templates/errors/missing_action.thtml
new file mode 100644
index 0000000..db91d34
--- /dev/null
+++ b/site/cake/libs/view/templates/errors/missing_action.thtml
@@ -0,0 +1,37 @@
+<?php
+/* SVN FILE: $Id: missing_action.thtml 6305 2008-01-02 02:33:56Z phpnut $ */
+/**
+ *
+ * PHP versions 4 and 5
+ *
+ * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
+ * Copyright 2005-2008, Cake Software Foundation, Inc.
+ * 1785 E. Sahara Avenue, Suite 490-204
+ * Las Vegas, Nevada 89104
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
+ * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
+ * @package cake
+ * @subpackage cake.cake.libs.view.templates.errors
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @version $Revision: 6305 $
+ * @modifiedby $LastChangedBy: phpnut $
+ * @lastmodified $Date: 2008-01-01 20:33:56 -0600 (Tue, 01 Jan 2008) $
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+?>
+<h1>Missing Method in <?php echo $controller;?></h1>
+<p class="error">You are seeing this error because the action <em><?php echo $action;?></em> is not defined in controller <em><?php echo $controller;?></em></p>
+<p><span class="notice">If you want to customize this error message, create <?php echo APP_DIR.DS."views/errors/missing_action.thtml"; ?>.</span></p>
+<p><span class="notice"><strong>Fatal</strong>: Confirm you have created the <?php echo $controller;?>::<?php echo $action;?>() in file : <?php echo APP_DIR.DS."controllers".DS.Inflector::underscore($controller).".php"; ?></p>
+<p>&lt;?php<br />
+class <?php echo $controller;?> extends AppController {<br />
+&nbsp;&nbsp;&nbsp;<strong>function <?php echo $action;?>() {<br />
+&nbsp;&nbsp;&nbsp;}</strong><br />
+}<br />
+?&gt;<br />
+</p> \ No newline at end of file
diff --git a/site/cake/libs/view/templates/errors/missing_component_class.thtml b/site/cake/libs/view/templates/errors/missing_component_class.thtml
new file mode 100644
index 0000000..3bd40b1
--- /dev/null
+++ b/site/cake/libs/view/templates/errors/missing_component_class.thtml
@@ -0,0 +1,36 @@
+<?php
+/* SVN FILE: $Id: missing_component_class.thtml 6305 2008-01-02 02:33:56Z phpnut $ */
+/**
+ *
+ * PHP versions 4 and 5
+ *
+ * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
+ * Copyright 2005-2008, Cake Software Foundation, Inc.
+ * 1785 E. Sahara Avenue, Suite 490-204
+ * Las Vegas, Nevada 89104
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
+ * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
+ * @package cake
+ * @subpackage cake.cake.libs.view.templates.errors
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @version $Revision: 6305 $
+ * @modifiedby $LastChangedBy: phpnut $
+ * @lastmodified $Date: 2008-01-01 20:33:56 -0600 (Tue, 01 Jan 2008) $
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+?>
+<h1>Missing Component Class</h1>
+<p class="error">You are seeing this error because the component class <em><?php echo $component."Component";?></em>
+you have set in <?php echo $controller."Controller";?> can't be found or doesn't exist.</em></p>
+<p><span class="notice"><strong>Notice:</strong> If you want to customize this error message, create <?php echo APP_DIR.DS."views/errors/missing_component_class.thtml"; ?>.</span></p>
+<p><span class="notice"><strong>Fatal</strong>: Create the class below in file : <?php echo APP_DIR.DS."controllers".DS."components".DS.$file; ?></p>
+<p>&lt;?php<br />
+class <?php echo $component;?>Component extends Object {<br />
+}<br />
+?&gt;<br />
+</p> \ No newline at end of file
diff --git a/site/cake/libs/view/templates/errors/missing_component_file.thtml b/site/cake/libs/view/templates/errors/missing_component_file.thtml
new file mode 100644
index 0000000..0d2ec30
--- /dev/null
+++ b/site/cake/libs/view/templates/errors/missing_component_file.thtml
@@ -0,0 +1,35 @@
+<?php
+/* SVN FILE: $Id: missing_component_file.thtml 6305 2008-01-02 02:33:56Z phpnut $ */
+/**
+ *
+ * PHP versions 4 and 5
+ *
+ * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
+ * Copyright 2005-2008, Cake Software Foundation, Inc.
+ * 1785 E. Sahara Avenue, Suite 490-204
+ * Las Vegas, Nevada 89104
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
+ * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
+ * @package cake
+ * @subpackage cake.cake.libs.view.templates.errors
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @version $Revision: 6305 $
+ * @modifiedby $LastChangedBy: phpnut $
+ * @lastmodified $Date: 2008-01-01 20:33:56 -0600 (Tue, 01 Jan 2008) $
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+?>
+<h1>Missing Component File</h1>
+<p class="error">You are seeing this error because the component file can't be found or doesn't exist.</p>
+<p><span class="notice"><strong>Notice:</strong> If you want to customize this error message, create <?php echo APP_DIR.DS."views/errors/missing_component_file.thtml"; ?>.</span></p>
+<p><span class="notice"><strong>Fatal</strong>: Create the class below in file : <?php echo APP_DIR.DS."controllers".DS."components".DS.$file; ?></p>
+<p>&lt;?php<br />
+class <?php echo $component;?>Component extends Object {<br />
+
+}<br />
+?&gt;<br /> </p> \ No newline at end of file
diff --git a/site/cake/libs/view/templates/errors/missing_connection.thtml b/site/cake/libs/view/templates/errors/missing_connection.thtml
new file mode 100644
index 0000000..0c01595
--- /dev/null
+++ b/site/cake/libs/view/templates/errors/missing_connection.thtml
@@ -0,0 +1,30 @@
+<?php
+/* SVN FILE: $Id: missing_connection.thtml 6305 2008-01-02 02:33:56Z phpnut $ */
+/**
+ *
+ * PHP versions 4 and 5
+ *
+ * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
+ * Copyright 2005-2008, Cake Software Foundation, Inc.
+ * 1785 E. Sahara Avenue, Suite 490-204
+ * Las Vegas, Nevada 89104
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
+ * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
+ * @package cake
+ * @subpackage cake.cake.libs.view.templates.errors
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @version $Revision: 6305 $
+ * @modifiedby $LastChangedBy: phpnut $
+ * @lastmodified $Date: 2008-01-01 20:33:56 -0600 (Tue, 01 Jan 2008) $
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+?>
+<h1>Requires a Database Connection</h1>
+<p class="error">Missing Database Connection: <?php echo $model;?> requires a database connection</p>
+<p><span class="notice"><strong>Notice:</strong> If you want to customize this error message, create <?php echo APP_DIR.DS."views/errors/missing_database.thtml"; ?>.</span></p>
+<p><span class="notice"><strong>Fatal</strong>: Confirm you have created the file : <?php echo APP_DIR.DS."config".DS."database.php"; ?></p> \ No newline at end of file
diff --git a/site/cake/libs/view/templates/errors/missing_controller.thtml b/site/cake/libs/view/templates/errors/missing_controller.thtml
new file mode 100644
index 0000000..d480732
--- /dev/null
+++ b/site/cake/libs/view/templates/errors/missing_controller.thtml
@@ -0,0 +1,36 @@
+<?php
+/* SVN FILE: $Id: missing_controller.thtml 6305 2008-01-02 02:33:56Z phpnut $ */
+/**
+ *
+ * PHP versions 4 and 5
+ *
+ * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
+ * Copyright 2005-2008, Cake Software Foundation, Inc.
+ * 1785 E. Sahara Avenue, Suite 490-204
+ * Las Vegas, Nevada 89104
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
+ * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
+ * @package cake
+ * @subpackage cake.cake.libs.view.templates.errors
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @version $Revision: 6305 $
+ * @modifiedby $LastChangedBy: phpnut $
+ * @lastmodified $Date: 2008-01-01 20:33:56 -0600 (Tue, 01 Jan 2008) $
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+?>
+<h1>Missing controller</h1>
+<p class="error">You are seeing this error because controller <em><?php echo $controller;?></em> could not be found.</p>
+<p><span class="notice"><strong>Notice:</strong> If you want to customize this error message, create <?php echo APP_DIR.DS."views/errors/missing_controller.thtml"; ?>.</span></p>
+<p><span class="notice"><strong>Fatal</strong>: Create the class below in file : <?php echo APP_DIR.DS."controllers".DS.Inflector::underscore($controller).".php"; ?></p>
+<p>&lt;?php<br />
+class <?php echo $controller;?> extends AppController {<br />
+&nbsp;&nbsp;&nbsp;var $name = '<?php echo $controllerName;?>';<br />
+}<br />
+?&gt;<br />
+</p> \ No newline at end of file
diff --git a/site/cake/libs/view/templates/errors/missing_helper_class.thtml b/site/cake/libs/view/templates/errors/missing_helper_class.thtml
new file mode 100644
index 0000000..0d588c5
--- /dev/null
+++ b/site/cake/libs/view/templates/errors/missing_helper_class.thtml
@@ -0,0 +1,35 @@
+<?php
+/* SVN FILE: $Id: missing_helper_class.thtml 6305 2008-01-02 02:33:56Z phpnut $ */
+/**
+ *
+ * PHP versions 4 and 5
+ *
+ * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
+ * Copyright 2005-2008, Cake Software Foundation, Inc.
+ * 1785 E. Sahara Avenue, Suite 490-204
+ * Las Vegas, Nevada 89104
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
+ * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
+ * @package cake
+ * @subpackage cake.cake.libs.view.templates.errors
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @version $Revision: 6305 $
+ * @modifiedby $LastChangedBy: phpnut $
+ * @lastmodified $Date: 2008-01-01 20:33:56 -0600 (Tue, 01 Jan 2008) $
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+?>
+<h1>Missing Helper Class</h1>
+<p class="error">You are seeing this error because the view helper class <?php echo $helperClass;?> can't be found or doesn't exist.</p>
+<p><span class="notice"><strong>Notice:</strong> If you want to customize this error message, create <?php echo APP_DIR.DS."views/errors/missing_helper_class.thtml"; ?>.</span></p>
+<p><span class="notice"><strong>Fatal</strong>: Create the class below in file : <?php echo APP_DIR.DS."views".DS."helpers".DS.$file; ?></p>
+<p>&lt;?php<br />
+class <?php echo $helperClass;?> extends Helper {<br />
+}<br />
+?&gt;<br />
+</p> \ No newline at end of file
diff --git a/site/cake/libs/view/templates/errors/missing_helper_file.thtml b/site/cake/libs/view/templates/errors/missing_helper_file.thtml
new file mode 100644
index 0000000..a9e6508
--- /dev/null
+++ b/site/cake/libs/view/templates/errors/missing_helper_file.thtml
@@ -0,0 +1,35 @@
+<?php
+/* SVN FILE: $Id: missing_helper_file.thtml 6305 2008-01-02 02:33:56Z phpnut $ */
+/**
+ *
+ * PHP versions 4 and 5
+ *
+ * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
+ * Copyright 2005-2008, Cake Software Foundation, Inc.
+ * 1785 E. Sahara Avenue, Suite 490-204
+ * Las Vegas, Nevada 89104
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
+ * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
+ * @package cake
+ * @subpackage cake.cake.libs.view.templates.errors
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @version $Revision: 6305 $
+ * @modifiedby $LastChangedBy: phpnut $
+ * @lastmodified $Date: 2008-01-01 20:33:56 -0600 (Tue, 01 Jan 2008) $
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+?>
+<h1>Missing Helper File</h1>
+<p class="error">You are seeing this error because the view helper file <?php echo APP_DIR.DS."views".DS."helpers".DS.$file; ?> can't be found or doesn't exist.</p>
+<p><span class="notice"><strong>Notice:</strong> If you want to customize this error message, create <?php echo APP_DIR.DS."views/errors/missing_helper_file.thtml"; ?>.</span></p>
+<p><span class="notice"><strong>Fatal</strong>: Create the class below in file : <?php echo APP_DIR.DS."views".DS."helpers".DS.$file; ?></p>
+<p>&lt;?php<br />
+class <?php echo $helperClass;?> extends Helper {<br />
+}<br />
+?&gt;<br />
+</p> \ No newline at end of file
diff --git a/site/cake/libs/view/templates/errors/missing_layout.thtml b/site/cake/libs/view/templates/errors/missing_layout.thtml
new file mode 100644
index 0000000..e35eb30
--- /dev/null
+++ b/site/cake/libs/view/templates/errors/missing_layout.thtml
@@ -0,0 +1,30 @@
+<?php
+/* SVN FILE: $Id: missing_layout.thtml 6305 2008-01-02 02:33:56Z phpnut $ */
+/**
+ *
+ * PHP versions 4 and 5
+ *
+ * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
+ * Copyright 2005-2008, Cake Software Foundation, Inc.
+ * 1785 E. Sahara Avenue, Suite 490-204
+ * Las Vegas, Nevada 89104
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
+ * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
+ * @package cake
+ * @subpackage cake.cake.libs.view.templates.errors
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @version $Revision: 6305 $
+ * @modifiedby $LastChangedBy: phpnut $
+ * @lastmodified $Date: 2008-01-01 20:33:56 -0600 (Tue, 01 Jan 2008) $
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+?>
+<h1>Missing Layout</h1>
+<p class="error">You are seeing this error because the layout file <?php echo $file;?> can't be found or doesn't exist.</p>
+<p><span class="notice"><strong>Notice:</strong> If you want to customize this error message, create <?php echo APP_DIR.DS."views/errors/missing_layout.thtml"; ?>.</span></p>
+<p><span class="notice"><strong>Fatal</strong>: Confirm you have created the file : <?php echo $file;?></p> \ No newline at end of file
diff --git a/site/cake/libs/view/templates/errors/missing_model.thtml b/site/cake/libs/view/templates/errors/missing_model.thtml
new file mode 100644
index 0000000..9fdb6bb
--- /dev/null
+++ b/site/cake/libs/view/templates/errors/missing_model.thtml
@@ -0,0 +1,36 @@
+<?php
+/* SVN FILE: $Id: missing_model.thtml 6305 2008-01-02 02:33:56Z phpnut $ */
+/**
+ *
+ * PHP versions 4 and 5
+ *
+ * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
+ * Copyright 2005-2008, Cake Software Foundation, Inc.
+ * 1785 E. Sahara Avenue, Suite 490-204
+ * Las Vegas, Nevada 89104
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
+ * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
+ * @package cake
+ * @subpackage cake.cake.libs.view.templates.errors
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @version $Revision: 6305 $
+ * @modifiedby $LastChangedBy: phpnut $
+ * @lastmodified $Date: 2008-01-01 20:33:56 -0600 (Tue, 01 Jan 2008) $
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+?>
+<h1>Missing Model</h1>
+<p class="error">No class found for the <em><?php echo $model;?></em> model</p>
+<p><span class="notice"><strong>Notice:</strong> If you want to customize this error message, create <?php echo APP_DIR.DS."views/errors/missing_model.thtml"; ?>.</span></p>
+<p><span class="notice"><strong>Fatal</strong>: Create the class below in file : <?php echo "app".DS."models".DS.Inflector::underscore($model).".php"; ?></p>
+<p>&lt;?php<br />
+class <?php echo $model;?> extends AppModel {<br />
+&nbsp;&nbsp;&nbsp;var $name = '<?php echo $model;?>';<br />
+}<br />
+?&gt;<br />
+</p> \ No newline at end of file
diff --git a/site/cake/libs/view/templates/errors/missing_scaffolddb.thtml b/site/cake/libs/view/templates/errors/missing_scaffolddb.thtml
new file mode 100644
index 0000000..842ab17
--- /dev/null
+++ b/site/cake/libs/view/templates/errors/missing_scaffolddb.thtml
@@ -0,0 +1,30 @@
+<?php
+/* SVN FILE: $Id: missing_scaffolddb.thtml 6305 2008-01-02 02:33:56Z phpnut $ */
+/**
+ *
+ * PHP versions 4 and 5
+ *
+ * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
+ * Copyright 2005-2008, Cake Software Foundation, Inc.
+ * 1785 E. Sahara Avenue, Suite 490-204
+ * Las Vegas, Nevada 89104
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
+ * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
+ * @package cake
+ * @subpackage cake.cake.libs.view.templates.errors
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @version $Revision: 6305 $
+ * @modifiedby $LastChangedBy: phpnut $
+ * @lastmodified $Date: 2008-01-01 20:33:56 -0600 (Tue, 01 Jan 2008) $
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+?>
+<h1>Scaffold Requires a Database Connection</h1>
+<p class="error">Missing Database Connection: Scaffold Does not work without a database connection</p>
+<p><span class="notice"><strong>Notice:</strong> If you want to customize this error message, create <?php echo APP_DIR.DS."views/errors/missing_scaffolddb.thtml"; ?>.</span></p>
+<p><span class="notice"><strong>Fatal</strong>: Confirm you have created the file : <?php echo APP_DIR.DS."config".DS."database.php"; ?></p> \ No newline at end of file
diff --git a/site/cake/libs/view/templates/errors/missing_table.thtml b/site/cake/libs/view/templates/errors/missing_table.thtml
new file mode 100644
index 0000000..209ca9b
--- /dev/null
+++ b/site/cake/libs/view/templates/errors/missing_table.thtml
@@ -0,0 +1,29 @@
+<?php
+/* SVN FILE: $Id: missing_table.thtml 6305 2008-01-02 02:33:56Z phpnut $ */
+/**
+ *
+ * PHP versions 4 and 5
+ *
+ * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
+ * Copyright 2005-2008, Cake Software Foundation, Inc.
+ * 1785 E. Sahara Avenue, Suite 490-204
+ * Las Vegas, Nevada 89104
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
+ * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
+ * @package cake
+ * @subpackage cake.cake.libs.view.templates.errors
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @version $Revision: 6305 $
+ * @modifiedby $LastChangedBy: phpnut $
+ * @lastmodified $Date: 2008-01-01 20:33:56 -0600 (Tue, 01 Jan 2008) $
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+?>
+<h1>Missing Database Table</h1>
+<p class="error">No Database table for model <?php echo $model;?> (expected "<?php echo $table;?>"), create it first.</p>
+<p><span class="notice"><strong>Notice:</strong> If you want to customize this error message, create <?php echo APP_DIR.DS."views/errors/missing_table.thtml"; ?>.</span></p>
diff --git a/site/cake/libs/view/templates/errors/missing_view.thtml b/site/cake/libs/view/templates/errors/missing_view.thtml
new file mode 100644
index 0000000..a7a70da
--- /dev/null
+++ b/site/cake/libs/view/templates/errors/missing_view.thtml
@@ -0,0 +1,30 @@
+<?php
+/* SVN FILE: $Id: missing_view.thtml 6305 2008-01-02 02:33:56Z phpnut $ */
+/**
+ *
+ * PHP versions 4 and 5
+ *
+ * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
+ * Copyright 2005-2008, Cake Software Foundation, Inc.
+ * 1785 E. Sahara Avenue, Suite 490-204
+ * Las Vegas, Nevada 89104
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
+ * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
+ * @package cake
+ * @subpackage cake.cake.libs.view.templates.errors
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @version $Revision: 6305 $
+ * @modifiedby $LastChangedBy: phpnut $
+ * @lastmodified $Date: 2008-01-01 20:33:56 -0600 (Tue, 01 Jan 2008) $
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+?>
+<h1>Missing view</h1>
+<p class="error">You are seeing this error because the view for <em><?php echo $controller.'Controller';?>::<?php echo $action;?>()</em> could not be found.</p>
+<p><span class="notice">If you want to customize this error message, create <?php echo APP_DIR.DS."views/errors/missing_view.thtml"; ?>.</span></p>
+<p><span class="notice"><strong>Fatal</strong>: Confirm you have created the file : <?php echo $file;?></p> \ No newline at end of file
diff --git a/site/cake/libs/view/templates/errors/private_action.thtml b/site/cake/libs/view/templates/errors/private_action.thtml
new file mode 100644
index 0000000..05845ed
--- /dev/null
+++ b/site/cake/libs/view/templates/errors/private_action.thtml
@@ -0,0 +1,29 @@
+<?php
+/* SVN FILE: $Id: private_action.thtml 6305 2008-01-02 02:33:56Z phpnut $ */
+/**
+ *
+ * PHP versions 4 and 5
+ *
+ * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
+ * Copyright 2005-2008, Cake Software Foundation, Inc.
+ * 1785 E. Sahara Avenue, Suite 490-204
+ * Las Vegas, Nevada 89104
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
+ * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
+ * @package cake
+ * @subpackage cake.cake.libs.view.templates.errors
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @version $Revision: 6305 $
+ * @modifiedby $LastChangedBy: phpnut $
+ * @lastmodified $Date: 2008-01-01 20:33:56 -0600 (Tue, 01 Jan 2008) $
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+?>
+<h1>Private Method in <?php echo $controller;?></h1>
+<p class="error">You are seeing this error because the private class method <em><?php echo $action;?></em> should not be accessed directly</p>
+<p><span class="notice"><strong>Notice:</strong> If you want to customize this error message, create <?php echo APP_DIR.DS."views/errors/private_action.thtml"; ?>.</span></p>
diff --git a/site/cake/libs/view/templates/errors/scaffold_error.thtml b/site/cake/libs/view/templates/errors/scaffold_error.thtml
new file mode 100644
index 0000000..fe05686
--- /dev/null
+++ b/site/cake/libs/view/templates/errors/scaffold_error.thtml
@@ -0,0 +1,33 @@
+<?php
+/* SVN FILE: $Id: scaffold_error.thtml 6305 2008-01-02 02:33:56Z phpnut $ */
+/**
+ *
+ * PHP versions 4 and 5
+ *
+ * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
+ * Copyright 2005-2008, Cake Software Foundation, Inc.
+ * 1785 E. Sahara Avenue, Suite 490-204
+ * Las Vegas, Nevada 89104
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
+ * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
+ * @package cake
+ * @subpackage cake.cake.libs.view.templates.errors
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @version $Revision: 6305 $
+ * @modifiedby $LastChangedBy: phpnut $
+ * @lastmodified $Date: 2008-01-01 20:33:56 -0600 (Tue, 01 Jan 2008) $
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+?>
+<h1>Scaffold Error</h1>
+<p class="error">Your must implement the following method in your controller</p>
+<p><span class="notice"><strong>Notice:</strong> If you want to customize this error message, create <?php echo APP_DIR.DS."views/errors/scaffold_error.thtml"; ?>.</span></p>
+<p>
+&nbsp;&nbsp;&nbsp;function _scaffoldError() {<br />
+&nbsp;&nbsp;&nbsp;}<br />
+</p> \ No newline at end of file
diff --git a/site/cake/libs/view/templates/layouts/ajax.thtml b/site/cake/libs/view/templates/layouts/ajax.thtml
new file mode 100644
index 0000000..16e9e96
--- /dev/null
+++ b/site/cake/libs/view/templates/layouts/ajax.thtml
@@ -0,0 +1,27 @@
+<?php
+/* SVN FILE: $Id: ajax.thtml 6305 2008-01-02 02:33:56Z phpnut $ */
+/**
+ *
+ * PHP versions 4 and 5
+ *
+ * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
+ * Copyright 2005-2008, Cake Software Foundation, Inc.
+ * 1785 E. Sahara Avenue, Suite 490-204
+ * Las Vegas, Nevada 89104
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
+ * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
+ * @package cake
+ * @subpackage cake.cake.libs.view.templates.layouts
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @version $Revision: 6305 $
+ * @modifiedby $LastChangedBy: phpnut $
+ * @lastmodified $Date: 2008-01-01 20:33:56 -0600 (Tue, 01 Jan 2008) $
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+?>
+<?php echo $content_for_layout; ?> \ No newline at end of file
diff --git a/site/cake/libs/view/templates/layouts/default.thtml b/site/cake/libs/view/templates/layouts/default.thtml
new file mode 100644
index 0000000..b60fe84
--- /dev/null
+++ b/site/cake/libs/view/templates/layouts/default.thtml
@@ -0,0 +1,58 @@
+<?php
+/* SVN FILE: $Id: default.thtml 6305 2008-01-02 02:33:56Z phpnut $ */
+/**
+ *
+ * PHP versions 4 and 5
+ *
+ * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
+ * Copyright 2005-2008, Cake Software Foundation, Inc.
+ * 1785 E. Sahara Avenue, Suite 490-204
+ * Las Vegas, Nevada 89104
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
+ * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
+ * @package cake
+ * @subpackage cake.cake.libs.view.templates.pages
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @version $Revision: 6305 $
+ * @modifiedby $LastChangedBy: phpnut $
+ * @lastmodified $Date: 2008-01-01 20:33:56 -0600 (Tue, 01 Jan 2008) $
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<title>CakePHP(tm) : <?php echo $title_for_layout; ?></title>
+<?php echo $html->charset(); ?>
+<link rel="icon" href="<?php echo $this->webroot . 'favicon.ico'; ?>" type="image/x-icon" />
+<link rel="shortcut icon" href="<?php echo $this->webroot . 'favicon.ico'; ?>" type="image/x-icon" />
+<?php echo $html->css('cake.generic'); ?>
+</head>
+<body>
+ <div id="container">
+ <div id="header">
+ <h1>CakePHP Rapid Development</h1>
+ </div>
+ <div id="content">
+ <?php if ($session->check('Message.flash'))
+ {
+ $session->flash();
+ }
+ echo $content_for_layout;
+ ?>
+ </div>
+ <div id="footer">
+ &nbsp;
+ <a href="http://www.cakephp.org/" target="_new">
+ <?php echo $html->image('cake.power.png', array('alt'=>"CakePHP(tm) : Rapid Development Framework", 'border'=>"0")); ?>
+ </a>
+ </div>
+ </div>
+ <?php echo $cakeDebug; ?>
+</body>
+</html> \ No newline at end of file
diff --git a/site/cake/libs/view/templates/layouts/flash.thtml b/site/cake/libs/view/templates/layouts/flash.thtml
new file mode 100644
index 0000000..0d4db86
--- /dev/null
+++ b/site/cake/libs/view/templates/layouts/flash.thtml
@@ -0,0 +1,45 @@
+<?php
+/* SVN FILE: $Id: flash.thtml 6305 2008-01-02 02:33:56Z phpnut $ */
+/**
+ *
+ * PHP versions 4 and 5
+ *
+ * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
+ * Copyright 2005-2008, Cake Software Foundation, Inc.
+ * 1785 E. Sahara Avenue, Suite 490-204
+ * Las Vegas, Nevada 89104
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
+ * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
+ * @package cake
+ * @subpackage cake.cake.libs.view.templates.layouts
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @version $Revision: 6305 $
+ * @modifiedby $LastChangedBy: phpnut $
+ * @lastmodified $Date: 2008-01-01 20:33:56 -0600 (Tue, 01 Jan 2008) $
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<title><?php echo $page_title; ?></title>
+<?php echo $html->charset(); ?>
+
+<?php if (Configure::read() == 0) { ?>
+<meta http-equiv="Refresh" content="<?php echo $pause; ?>;url=<?php echo $url; ?>"/>
+<?php } ?>
+<style><!--
+P { text-align:center; font:bold 1.1em sans-serif }
+A { color:#444; text-decoration:none }
+A:HOVER { text-decoration: underline; color:#44E }
+--></style>
+</head>
+<body>
+<p><a href="<?php echo $url; ?>"><?php echo $message; ?></a></p>
+</body>
+</html> \ No newline at end of file
diff --git a/site/cake/libs/view/templates/pages/home.thtml b/site/cake/libs/view/templates/pages/home.thtml
new file mode 100644
index 0000000..39cda0a
--- /dev/null
+++ b/site/cake/libs/view/templates/pages/home.thtml
@@ -0,0 +1,75 @@
+<?php
+/* SVN FILE: $Id: home.thtml 6305 2008-01-02 02:33:56Z phpnut $ */
+/**
+ *
+ * PHP versions 4 and 5
+ *
+ * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
+ * Copyright 2005-2008, Cake Software Foundation, Inc.
+ * 1785 E. Sahara Avenue, Suite 490-204
+ * Las Vegas, Nevada 89104
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
+ * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
+ * @package cake
+ * @subpackage cake.cake.libs.view.templates.pages
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @version $Revision: 6305 $
+ * @modifiedby $LastChangedBy: phpnut $
+ * @lastmodified $Date: 2008-01-01 20:33:56 -0600 (Tue, 01 Jan 2008) $
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+?>
+<p class="notice">Your database configuration file is <?php echo file_exists(CONFIGS.'database.php') ?' present.' . $filePresent = ' ' : ' not present.'; ?></p>
+<?php if (!empty($filePresent)):?>
+<?php uses('model' . DS . 'connection_manager'); $db = ConnectionManager::getInstance(); ?>
+<?php $connected = $db->getDataSource('default'); ?>
+<p class="notice">Cake<?php echo $connected->isConnected() ? ' is able to' : ' is not able to';?> connect to the database.</p>
+<br />
+<?php endif; ?>
+<h2>CakePHP release information is on CakeForge</h2>
+<a href="https://trac.cakephp.org/wiki/notes/1.1.x.x">Read the release notes and get the latest version</a>
+<h2>Editing this Page</h2>
+<p>
+To change the content of this page, create: /app/views/pages/home.thtml.<br />
+To change its layout, create: /app/views/layouts/default.thtml.<br />
+<a href="http://manual.cakephp.org/">See the views section of the manual for more info</a><br />
+You can also add some CSS styles for your pages at: app/webroot/css/.
+</p>
+<h2>More about Cake</h2>
+<p>
+CakePHP is a rapid development framework for PHP which uses commonly known design patterns like
+Active Record, Association Data Mapping, Front Controller and MVC.
+</p>
+<p>
+Our primary goal is to provide a structured framework that enables PHP users at all levels
+to rapidly develop robust web applications, without any loss to flexibility.
+</p>
+<ul>
+ <li><a href="http://www.cakefoundation.org/">Cake Software Foundation</a>
+ <ul><li>Promoting development related to CakePHP</li></ul></li>
+ <li><a href="http://bakery.cakephp.org">The Bakery</a>
+ <ul><li>Everything CakePHP</li></ul></li>
+ <li><a href="http://astore.amazon.com/cakesoftwaref-20/">Book Store</a>
+ <ul><li>Recommended Software Books</li></ul></li>
+ <li><a href="http://www.cafepress.com/cakefoundation">CakeSchwag</a>
+ <ul><li>Get your own CakePHP gear - Doughnate to Cake</li></ul></li>
+ <li><a href="http://www.cakephp.org">CakePHP</a>
+ <ul><li>The Rapid Development Framework</li></ul></li>
+ <li><a href="http://manual.cakephp.org">CakePHP Manual</a>
+ <ul><li>Your Rapid Development Cookbook</li></ul></li>
+ <li><a href="http://api.cakephp.org">CakePHP API</a>
+ <ul><li>Docblock Your Best Friend</li></ul></li>
+ <li><a href="http://www.cakeforge.org">CakeForge</a>
+ <ul><li>Open Development for CakePHP</li></ul></li>
+ <li><a href="https://trac.cakephp.org/">CakePHP Trac</a>
+ <ul><li>For the Development of CakePHP (Tickets, SVN browser, Roadmap, Changelogs)</li></ul></li>
+ <li><a href="http://groups-beta.google.com/group/cake-php">CakePHP Google Group</a>
+ <ul><li>Community mailing list</li></ul></li>
+ <li><a href="irc://irc.freenode.net/cakephp">irc.freenode.net #cakephp</a>
+ <ul><li>Live chat about CakePHP</li></ul></li>
+</ul> \ No newline at end of file
diff --git a/site/cake/libs/view/templates/scaffolds/add.thtml b/site/cake/libs/view/templates/scaffolds/add.thtml
new file mode 100644
index 0000000..2c9852d
--- /dev/null
+++ b/site/cake/libs/view/templates/scaffolds/add.thtml
@@ -0,0 +1,40 @@
+<?php
+/* SVN FILE: $Id: add.thtml 6305 2008-01-02 02:33:56Z phpnut $ */
+/**
+ *
+ * PHP versions 4 and 5
+ *
+ * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
+ * Copyright 2005-2008, Cake Software Foundation, Inc.
+ * 1785 E. Sahara Avenue, Suite 490-204
+ * Las Vegas, Nevada 89104
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
+ * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
+ * @package cake
+ * @subpackage cake.cake.libs.view.templates.scaffolds
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @version $Revision: 6305 $
+ * @modifiedby $LastChangedBy: phpnut $
+ * @lastmodified $Date: 2008-01-01 20:33:56 -0600 (Tue, 01 Jan 2008) $
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+?>
+<h1>New <?php echo Inflector::humanize($this->name)?></h1>
+<?php
+if (is_null($this->plugin)) {
+ $path = '/';
+} else {
+ $path = '/'.$this->plugin.'/';
+}
+echo $html->formTag($path. Inflector::underscore($this->name).'/create');
+echo $form->generateFields( $fieldNames );
+echo $form->generateSubmitDiv( 'Add' );?>
+</form>
+<ul class='actions'>
+<?php echo "<li>".$html->link('List '.Inflector::humanize($this->name), $path.$this->viewPath.'/index')."</li>"; ?>
+</ul> \ No newline at end of file
diff --git a/site/cake/libs/view/templates/scaffolds/edit.thtml b/site/cake/libs/view/templates/scaffolds/edit.thtml
new file mode 100644
index 0000000..056000f
--- /dev/null
+++ b/site/cake/libs/view/templates/scaffolds/edit.thtml
@@ -0,0 +1,56 @@
+<?php
+/* SVN FILE: $Id: edit.thtml 6305 2008-01-02 02:33:56Z phpnut $ */
+/**
+ *
+ * PHP versions 4 and 5
+ *
+ * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
+ * Copyright 2005-2008, Cake Software Foundation, Inc.
+ * 1785 E. Sahara Avenue, Suite 490-204
+ * Las Vegas, Nevada 89104
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
+ * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
+ * @package cake
+ * @subpackage cake.cake.libs.view.templates.scaffolds
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @version $Revision: 6305 $
+ * @modifiedby $LastChangedBy: phpnut $
+ * @lastmodified $Date: 2008-01-01 20:33:56 -0600 (Tue, 01 Jan 2008) $
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+$modelName = ucwords(Inflector::singularize($this->name));
+$modelKey = $modelName;
+if (is_null($this->plugin)) {
+ $path = '/';
+} else {
+ $path = '/'.$this->plugin.'/';
+}?>
+<h1><?php echo $type.' '.Inflector::humanize($modelName);?></h1>
+<?php
+if ($type == 'Edit') {
+ echo $html->formTag($path . Inflector::underscore($this->name) .'/update');
+} else {
+ echo $html->formTag($path. Inflector::underscore($this->name).'/create');
+}
+echo $form->generateFields( $fieldNames );
+echo $form->generateSubmitDiv( 'Save' ); ?>
+</form>
+<ul class='actions'>
+<?php
+if ($type == 'Edit') {
+ echo "<li>".$html->link('Delete '.Inflector::humanize($modelName), $path.$this->viewPath.'/delete/'.$data[$modelKey][$this->controller->{$modelName}->primaryKey])."</li>";
+}
+echo "<li>".$html->link('List '.Inflector::humanize($modelName), $path.$this->viewPath.'/index')."</li>";
+if ($type == 'Edit') {
+ foreach ($fieldNames as $field => $value) {
+ if (isset($value['foreignKey'])) {
+ echo "<li>".$html->link( "View ".Inflector::humanize($value['controller']), $path.Inflector::underscore($value['controller'])."/view/".$data[$modelKey][$field] )."</li>";
+ }
+ }
+}?>
+</ul> \ No newline at end of file
diff --git a/site/cake/libs/view/templates/scaffolds/index.thtml b/site/cake/libs/view/templates/scaffolds/index.thtml
new file mode 100644
index 0000000..0b6283a
--- /dev/null
+++ b/site/cake/libs/view/templates/scaffolds/index.thtml
@@ -0,0 +1,95 @@
+<?php
+/* SVN FILE: $Id: index.thtml 6305 2008-01-02 02:33:56Z phpnut $ */
+/**
+ *
+ * PHP versions 4 and 5
+ *
+ * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
+ * Copyright 2005-2008, Cake Software Foundation, Inc.
+ * 1785 E. Sahara Avenue, Suite 490-204
+ * Las Vegas, Nevada 89104
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
+ * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
+ * @package cake
+ * @subpackage cake.cake.libs.view.templates.scaffolds
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @version $Revision: 6305 $
+ * @modifiedby $LastChangedBy: phpnut $
+ * @lastmodified $Date: 2008-01-01 20:33:56 -0600 (Tue, 01 Jan 2008) $
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+?>
+<h1>List <?php echo Inflector::humanize($this->name)?></h1>
+<?php
+$model = ucwords(Inflector::singularize($this->name));
+$modelKey = $model;
+$humanName = Inflector::humanize($this->name);
+$humanSingularName = Inflector::singularize( $humanName );
+if (is_null($this->plugin)) {
+ $path = '/';
+} else {
+ $path = '/'.$this->plugin.'/';
+}
+if (!empty($this->controller->{$model}->modelToTable)) {
+ foreach ($this->controller->{$model}->modelToTable as $key => $value) {
+ $alias[] = $key;
+ }
+}?>
+<table class="inav" cellpadding="0" cellspacing="0">
+<thead>
+<tr>
+<?php
+foreach ($fieldNames as $fieldName) {?>
+ <th><?php echo $fieldName['prompt'];?></th>
+<?php }?>
+<th>Actions</th>
+</tr>
+</thead>
+<tbody>
+<?php
+$iRowIndex = 0;
+if (is_array($data)) {
+ foreach ($data as $row) {
+ if ($iRowIndex++ % 2 == 0) {
+ echo "<tr>";
+ } else {
+ echo "<tr class='altRow'>";
+ }
+ $count = 0;
+ foreach ($fieldNames as $field=>$value) { ?>
+ <td>
+<?php
+ if (isset($value['foreignKey'])) {
+ $otherModelKey = Inflector::underscore($value['modelKey']);
+ $otherControllerName = $value['controller'];
+ $otherModelObject =& ClassRegistry::getObject( $otherModelKey );
+ if (is_object($otherModelObject)) {
+ $displayText = $row[$alias[$count]][ $otherModelObject->getDisplayField() ];
+ } else {
+ $displayText = $row[$alias[$count]][$field];
+ }
+ echo $html->link( $displayText, $path.Inflector::underscore($otherControllerName)."/view/".$row[$modelKey][$field] );
+ $count++;
+ } else {
+ echo $row[$modelKey][$field];
+ }?>
+ </td>
+<?php } ?>
+ <td class="listactions"><?php echo $html->link('View',$path.$this->viewPath."/view/{$row[$modelKey][$this->controller->{$model}->primaryKey]}/")?>
+ <?php echo $html->link('Edit',$path.$this->viewPath."/edit/{$row[$modelKey][$this->controller->{$model}->primaryKey]}/")?>
+ <?php echo $html->link('Delete',$path.$this->viewPath."/delete/{$row[$modelKey][$this->controller->{$model}->primaryKey]}/", null, 'Are you sure you want to delete id '.$row[$modelKey][$this->controller->{$model}->primaryKey].' ?')?>
+ </td>
+ </tr>
+<?php
+ }
+}?>
+</tbody>
+</table>
+<ul class="actions">
+ <li><?php echo $html->link('New '.$humanSingularName, $path.$this->viewPath.'/add'); ?></li>
+</ul> \ No newline at end of file
diff --git a/site/cake/libs/view/templates/scaffolds/view.thtml b/site/cake/libs/view/templates/scaffolds/view.thtml
new file mode 100644
index 0000000..e00d2ee
--- /dev/null
+++ b/site/cake/libs/view/templates/scaffolds/view.thtml
@@ -0,0 +1,166 @@
+<?php
+/* SVN FILE: $Id: view.thtml 6305 2008-01-02 02:33:56Z phpnut $ */
+/**
+ *
+ * PHP versions 4 and 5
+ *
+ * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
+ * Copyright 2005-2008, Cake Software Foundation, Inc.
+ * 1785 E. Sahara Avenue, Suite 490-204
+ * Las Vegas, Nevada 89104
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
+ * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
+ * @package cake
+ * @subpackage cake.cake.libs.view.templates.scaffolds
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @version $Revision: 6305 $
+ * @modifiedby $LastChangedBy: phpnut $
+ * @lastmodified $Date: 2008-01-01 20:33:56 -0600 (Tue, 01 Jan 2008) $
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+?>
+<?php
+$modelName = ucwords(Inflector::singularize($this->name));
+$modelKey = Inflector::underscore($modelName);
+$objModel =& ClassRegistry::getObject($modelKey);
+if (is_null($this->plugin)) {
+ $path = '/';
+} else {
+ $path = '/'.$this->plugin.'/';
+}
+if (!empty($objModel->modelToTable)) {
+ foreach ($objModel->modelToTable as $key => $value) {
+ $alias[] = $key;
+ }
+ $count = 0;
+}?>
+<h1>View
+<?php echo Inflector::humanize($modelName)?>
+</h1>
+<dl>
+<?php
+foreach ($fieldNames as $field => $value) {
+ echo "<dt>".$value['prompt']."</dt>";
+ if (isset($value['foreignKey'])) {
+ $otherModelObject =& ClassRegistry::getObject(Inflector::underscore($objModel->tableToModel[$value['table']]));
+ $displayField = $otherModelObject->getDisplayField();
+ $displayText = $data[$alias[$count]][$displayField];
+ if (!empty($data[$objModel->tableToModel[$objModel->table]][$field]) && (isset($displayText))) {
+ echo "<dd>".$html->link($displayText, $path.Inflector::underscore($value['controller']).'/view/'
+ .$data[$objModel->tableToModel[$objModel->table]][$field] )."</dd>";
+ } else {
+ echo "<dd>&nbsp;</dd>";
+ }
+ $count++;
+ } else {
+ if ( !empty($data[$objModel->tableToModel[$objModel->table]][$field])) {
+ echo "<dd>".$data[$objModel->tableToModel[$objModel->table]][$field]."</dd>";
+ } else {
+ echo "<dd>&nbsp;</dd>";
+ }
+ }
+}?>
+</dl>
+<ul class='actions'>
+<?php
+echo "<li>".$html->link('Edit '.Inflector::humanize($objModel->name), $path.$this->viewPath.'/edit/'.$data[$objModel->tableToModel[$objModel->table]][$this->controller->{$modelName}->primaryKey])."</li>";
+echo "<li>".$html->link('Delete '.Inflector::humanize($objModel->name), $path.$this->viewPath.'/delete/'.$data[$objModel->tableToModel[$objModel->table]][$this->controller->{$modelName}->primaryKey], null, 'Are you sure you want to delete id '.$data[$objModel->tableToModel[$objModel->table]][$this->controller->{$modelName}->primaryKey].' ?')."</li>";
+echo "<li>".$html->link('List '.Inflector::humanize($objModel->name), $path.$this->viewPath.'/index')."</li>";
+echo "<li>".$html->link('New '.Inflector::humanize($objModel->name), $path.$this->viewPath.'/add')."</li>";
+
+foreach ( $fieldNames as $field => $value ) {
+ if ( isset( $value['foreignKey'] ) ) {
+ echo "<li>".$html->link( "List ".Inflector::humanize($value['controller']), $path.Inflector::underscore($value['controller'])."/index/")."</li>";
+ }
+}?>
+</ul>
+
+<!--hasOne relationships -->
+<?php
+foreach ($objModel->hasOne as $association => $relation) {
+ $model = $relation['className'];
+ $otherModelName = $objModel->tableToModel[$objModel->{$model}->table];
+ $controller = Inflector::pluralize($model);
+ $new = true;
+ echo "<div class='related'><H2>Related ".Inflector::humanize($association)."</H2>";
+ echo "<dl>";
+ if (isset($data[$association]) && is_array($data[$association])) {
+ foreach ($data[$association] as $field => $value) {
+ if (isset($value)) {
+ echo "<dt>".Inflector::humanize($field)."</dt>";
+ if (!empty($value)) {
+ echo "<dd>".$value."</dd>";
+ } else {
+ echo "<dd>&nbsp;</dd>";
+ }
+ $new = null;
+ }
+ }
+ echo "</dl>";
+ if ($new == null) {
+ echo "<ul class='actions'><li>".$html->link('Edit '.Inflector::humanize($association),$path.Inflector::underscore($controller)."/edit/{$data[$association][$objModel->{$model}->primaryKey]}")."</li></ul></div>";
+ } else {
+ echo "<ul class='actions'><li>".$html->link('New '.Inflector::humanize($association),$path.Inflector::underscore($controller)."/add/{$data[$association][$objModel->{$model}->primaryKey]}")."</li></ul></div>";
+ }
+ }
+}
+?>
+
+<!-- HAS MANY AND HASANDBELONGSTOMANY -->
+<?php
+$relations = array_merge($objModel->hasMany, $objModel->hasAndBelongsToMany);
+foreach ($relations as $association => $relation) {
+ $model = $relation['className'];
+ $count = 0;
+ $otherModelName = Inflector::singularize($model);
+ $controller = Inflector::pluralize($model);
+
+ echo "<div class='related'><H2>Related ".Inflector::humanize(Inflector::pluralize($association))."</H2>";
+ if (isset($data[$association][0]) && is_array($data[$association])) {?>
+ <table class="inav" cellspacing="0">
+ <tr>
+<?php
+ $bFound = false;
+ foreach ($data[$association][0] as $column=>$value) {
+ echo "<th>".Inflector::humanize($column)."</th>";
+ }?>
+ <th>Actions</th>
+ </tr>
+<?php
+ foreach ($data[$association] as $row) {
+ echo "<tr>";
+ foreach ($row as $column=>$value) {
+ echo "<td>".$value."</td>";
+ }
+ if (isset($this->controller->{$modelName}->{$association})) {?>
+ <td class="listactions"><?php echo $html->link('View',$path.Inflector::underscore($controller).
+ "/view/{$row[$this->controller->{$modelName}->{$association}->primaryKey]}/")?>
+ <?php echo $html->link('Edit',$path.Inflector::underscore($controller).
+ "/edit/{$row[$this->controller->{$modelName}->{$association}->primaryKey]}/")?>
+ <?php echo $html->link('Delete',$path.Inflector::underscore($controller).
+ "/delete/{$row[$this->controller->{$modelName}->{$association}->primaryKey]}/", null, 'Are you sure you want to delete id '.$row[$this->controller->{$modelName}->{$association}->primaryKey].' ?')?>
+ </td>
+<?php
+ } else {?>
+ <td class="listactions"><?php echo $html->link('View',$path.Inflector::underscore($controller).
+ "/view/{$row[$this->controller->{$modelName}->primaryKey]}/")?>
+ <?php echo $html->link('Edit',$path.Inflector::underscore($controller).
+ "/edit/{$row[$this->controller->{$modelName}->primaryKey]}/")?>
+ <?php echo $html->link('Delete',$path.Inflector::underscore($controller).
+ "/delete/{$row[$this->controller->{$modelName}->primaryKey]}/", null, 'Are you sure you want to delete id '.$row[$this->controller->{$modelName}->primaryKey].' ?')?>
+ </td>
+<?php
+ }
+ echo "</tr>";
+ }?>
+ </table>
+<?php }?>
+<ul class="actions">
+<?php echo "<li>".$html->link('New '.Inflector::humanize($association),$path.Inflector::underscore($controller)."/add/")."</li>";?>
+</ul></div>
+<?php }?> \ No newline at end of file
diff --git a/site/cake/libs/view/view.php b/site/cake/libs/view/view.php
new file mode 100644
index 0000000..46700ad
--- /dev/null
+++ b/site/cake/libs/view/view.php
@@ -0,0 +1,765 @@
+<?php
+/* SVN FILE: $Id: view.php 6305 2008-01-02 02:33:56Z phpnut $ */
+/**
+ * Methods for displaying presentation data in the view.
+ *
+ * PHP versions 4 and 5
+ *
+ * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
+ * Copyright 2005-2008, Cake Software Foundation, Inc.
+ * 1785 E. Sahara Avenue, Suite 490-204
+ * Las Vegas, Nevada 89104
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
+ * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
+ * @package cake
+ * @subpackage cake.cake.libs.view
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @version $Revision: 6305 $
+ * @modifiedby $LastChangedBy: phpnut $
+ * @lastmodified $Date: 2008-01-01 20:33:56 -0600 (Tue, 01 Jan 2008) $
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+/**
+ * Included libraries.
+ */
+uses ('view' . DS . 'helper', 'class_registry');
+/**
+ * View, the V in the MVC triad.
+ *
+ * Class holding methods for displaying presentation data.
+ *
+ * @package cake
+ * @subpackage cake.cake.libs.view
+ */
+class View extends Object{
+/**
+ * Name of the controller.
+ *
+ * @var string Name of controller
+ * @access public
+ */
+ var $name = null;
+/**
+ * Stores the current URL (for links etc.)
+ *
+ * @var string Current URL
+ * @access public
+ */
+ var $here = null;
+/**
+ * Action to be performed.
+ *
+ * @var string Name of action
+ * @access public
+ */
+ var $action = null;
+/**
+ * An array of names of built-in helpers to include.
+ *
+ * @var mixed A single name as a string or a list of names as an array.
+ * @access public
+ */
+ var $helpers = array('Html');
+/**
+ * Path to View.
+ *
+ * @var string Path to View
+ * @access public
+ */
+ var $viewPath;
+/**
+ * Replaced with public var viewVars
+ * @access protected
+ * @deprecated
+ */
+ var $_viewVars = array();
+/**
+ * Variables for the view
+ *
+ * @var array
+ * @access public
+ */
+ var $viewVars = array();
+/**
+ * Title HTML element of this View.
+ *
+ * @var boolean
+ * @access public
+ */
+ var $pageTitle = false;
+/**
+ * Path parts for creating links in views.
+ *
+ * @var string Base URL
+ * @access public
+ */
+ var $base = null;
+/**
+ * Name of layout to use with this View.
+ *
+ * @var string
+ * @access public
+ */
+ var $layout = 'default';
+/**
+ * Turns on or off Cake's conventional mode of rendering views. On by default.
+ *
+ * @var boolean
+ * @access public
+ */
+ var $autoRender = true;
+/**
+ * Turns on or off Cake's conventional mode of finding layout files. On by default.
+ *
+ * @var boolean
+ * @access public
+ */
+ var $autoLayout = true;
+/**
+ * Array of parameter data
+ *
+ * @var array Parameter data
+ * @access public
+ */
+ var $params;
+/**
+ * True when the view has been rendered.
+ *
+ * @var boolean
+ * @access protected
+ */
+ var $_hasRendered = null;
+/**
+ * @deprecated will not be avialable after 1.1.x.x
+ */
+ var $controller = null;
+/**
+ * Array of loaded view helpers.
+ *
+ * @var array
+ * @access public
+ */
+ var $loaded = array();
+/**
+ * File extension. Defaults to Cake's conventional ".thtml".
+ *
+ * @var array
+ * @access public
+ */
+ var $ext = '.thtml';
+/**
+ * Sub-directory for this view file.
+ *
+ * @var string
+ * @access public
+ */
+ var $subDir = null;
+/**
+ * The directory where theme web accessible content is stored
+ *
+ * @var array
+ * @access public
+ */
+ var $themeWeb = null;
+/**
+ * Plugin name. A Plugin is a sub-application.
+ * This is used to set the correct paths for views
+ *
+ * @var string
+ * @access public
+ */
+ var $plugin = null;
+/**
+ * Creates system path to plugin: plugins . DS . plugin_name . DS
+ *
+ * @var string
+ */
+ var $pluginPath = null;
+/**
+ * Holds an array of plugin paths.
+ * VIEWS . $this->pluginPath
+ * APP . $this->pluginPath . views . DS
+ *
+ * @var array
+ */
+ var $pluginPaths = array();
+/**
+ * List of variables to collect from the associated controller
+ *
+ * @var array
+ * @access protected
+ */
+ var $_passedVars = array('viewVars', 'action', 'autoLayout', 'autoRender', 'ext', 'base', 'webroot', 'helpers', 'here', 'layout', 'modelNames', 'name', 'pageTitle', 'viewPath', 'params', 'data', 'webservices', 'plugin');
+/**
+ * Constructor
+ *
+ * Instance is created in Controller::render() and is never called directly
+ *
+ * @var object instance of the calling controller
+ */
+ function __construct(&$controller) {
+ if (is_object($controller)) {
+ $this->controller =& $controller;
+ $c = count($this->_passedVars);
+
+ for ($j = 0; $j < $c; $j++) {
+ $var = $this->_passedVars[$j];
+ $this->{$var} = $controller->{$var};
+ }
+ $this->_viewVars =& $this->viewVars;
+ }
+ if (!is_null($this->plugin)) {
+ $this->pluginPath = 'plugins'. DS . $this->plugin . DS;
+ $this->pluginPaths = array(
+ VIEWS . $this->pluginPath,
+ APP . $this->pluginPath . 'views' . DS,
+ );
+
+ }
+ parent::__construct();
+ ClassRegistry::addObject('view', $this);
+ }
+/**
+ * Renders view for given action and layout. If $file is given, that is used
+ * for a view filename (e.g. customFunkyView.thtml).
+ *
+ * @param string $action Name of action to render for
+ * @param string $layout Layout to use
+ * @param string $file Custom filename for view
+ * @return mixed returns an error if View::render() fails to find a related template.
+ * boolean on successful render
+ * @access public
+ */
+ function render($action = null, $layout = null, $file = null) {
+
+ if (isset($this->_hasRendered) && $this->_hasRendered) {
+ return true;
+ } else {
+ $this->_hasRendered = false;
+ }
+
+ if (!$action) {
+ $action = $this->action;
+ }
+ $tempLayout = $this->layout;
+
+ if ($layout) {
+ $this->setLayout($layout);
+ }
+
+ if ($file) {
+ $viewFileName = $file;
+ } else {
+ $viewFileName = $this->_getViewFileName($action);
+ }
+
+ if (!is_null($this->plugin) && is_null($file)) {
+ return $this->pluginView($action, $layout);
+ }
+
+ if (!is_file($viewFileName) && !fileExistsInPath($viewFileName) || $viewFileName === '/' || $viewFileName === '\\') {
+ if (strpos($action, 'missingAction') !== false) {
+ $errorAction = 'missingAction';
+ } else {
+ $errorAction = 'missingView';
+ }
+
+ foreach (array($this->name, 'errors') as $viewDir) {
+ $errorAction = Inflector::underscore($errorAction);
+
+ if (file_exists(VIEWS . $viewDir . DS . $errorAction . $this->ext)) {
+ $missingViewFileName = VIEWS . $viewDir . DS . $errorAction . $this->ext;
+ } elseif ($missingViewFileName = fileExistsInPath(LIBS . 'view' . DS . 'templates' . DS . $viewDir . DS . $errorAction . '.thtml')) {
+ } else {
+ $missingViewFileName = false;
+ }
+
+ $missingViewExists = is_file($missingViewFileName);
+
+ if ($missingViewExists) {
+ break;
+ }
+ }
+
+ if (strpos($action, 'missingView') === false) {
+ return $this->cakeError('missingView', array(array('className' => $this->controller->name,
+ 'action' => $action,
+ 'file' => $viewFileName,
+ 'base' => $this->base)));
+
+ $isFatal = isset($this->isFatal) ? $this->isFatal : false;
+
+ if (!$isFatal) {
+ $viewFileName = $missingViewFileName;
+ }
+ } else {
+ $missingViewExists = false;
+ }
+
+ if (!$missingViewExists || $isFatal) {
+ if (Configure::read() > 0) {
+ trigger_error(sprintf("No template file for view %s (expected %s), create it first'", $action, $viewFileName), E_USER_ERROR);
+ } else {
+ $this->error('404', 'Not found', sprintf("The requested address %s was not found on this server.", '', "missing view \"{$action}\""));
+ }
+ die();
+ }
+ }
+
+ if ($viewFileName && !$this->_hasRendered) {
+ if (substr($viewFileName, -5) === 'thtml') {
+ $out = View::_render($viewFileName, $this->viewVars);
+ } else {
+ $out = $this->_render($viewFileName, $this->viewVars);
+ }
+
+ if ($out !== false) {
+ if ($this->layout && $this->autoLayout) {
+ $out = $this->renderLayout($out);
+ if (isset($this->loaded['cache']) && ((isset($this->controller) && $this->controller->cacheAction != false)) && (defined('CACHE_CHECK') && CACHE_CHECK === true)) {
+ $replace = array('<cake:nocache>', '</cake:nocache>');
+ $out = str_replace($replace, '', $out);
+ }
+ }
+
+ print $out;
+ $this->setLayout($tempLayout);
+ $this->_hasRendered = true;
+ } else {
+ $out = $this->_render($viewFileName, $this->viewVars);
+ trigger_error(sprintf("Error in view %s, got: <blockquote>%s</blockquote>", $viewFileName, $out), E_USER_ERROR);
+ }
+ return true;
+ }
+ }
+/**
+ * Renders a piece of PHP with provided parameters and returns HTML, XML, or any other string.
+ *
+ * This realizes the concept of Elements, (or "partial layouts")
+ * and the $params array is used to send data to be used in the Element.
+ *
+ * @param string $name Name of template file in the/app/views/elements/ folder
+ * @param array $params Array of data to be made available to the for rendered view (i.e. the Element)
+ * @return string Rendered output
+ * @access public
+ */
+ function renderElement($name, $params = array()) {
+ if (isset($params['plugin'])) {
+ $this->plugin = $params['plugin'];
+ $this->pluginPath = 'plugins' . DS . $this->plugin . DS;
+ $this->pluginPaths = array(
+ VIEWS . $this->pluginPath,
+ APP . $this->pluginPath . 'views' . DS,
+ );
+ }
+
+ $paths = Configure::getInstance();
+ $viewPaths = am($this->pluginPaths, $paths->viewPaths);
+
+ $file = null;
+ foreach ($viewPaths as $path) {
+ if (file_exists($path . 'elements' . DS . $name . $this->ext)) {
+ $file = $path . 'elements' . DS . $name . $this->ext;
+ break;
+ } elseif (file_exists($path . 'elements' . DS . $name . '.ctp')) {
+ $file = $path . 'elements' . DS . $name . '.ctp';
+ break;
+ }
+ }
+
+ if (!is_null($file)) {
+ $params = array_merge_recursive($params, $this->loaded);
+ return $this->_render($file, array_merge($this->viewVars, $params), false);
+ }
+
+ if (!is_null($this->pluginPath)) {
+ $file = APP . $this->pluginPath . 'views' . DS . 'elements' . DS . $name . $this->ext;
+ } else {
+ $file = VIEWS . 'elements' . DS . $name . $this->ext;
+ }
+
+ if (Configure::read() > 0) {
+ return "Element Not Found: " . $file;
+ }
+ }
+/**
+ * Wrapper for View::renderElement();
+ *
+ * @param string $name Name of template file in the/app/views/elements/ folder
+ * @param array $params Array of data to be made available to the for rendered view (i.e. the Element)
+ * @return string View::renderElement()
+ * @access public
+ */
+ function element($name, $params = array()) {
+ return $this->renderElement($name, $params);
+ }
+/**
+ * Renders a layout. Returns output from _render(). Returns false on error.
+ *
+ * @param string $contentForLayout Content to render in a view, wrapped by the surrounding layout.
+ * @return mixed Rendered output, or false on error
+ * @access public
+ */
+ function renderLayout($contentForLayout) {
+ $layoutFilename = $this->_getLayoutFileName();
+
+ if (Configure::read() > 2 && $this->controller != null) {
+ $debug = View::_render(LIBS . 'view' . DS . 'templates' . DS . 'elements' . DS . 'dump.thtml', array('controller' => $this->controller), false);
+ } else {
+ $debug = '';
+ }
+
+ if ($this->pageTitle !== false) {
+ $pageTitle = $this->pageTitle;
+ } else {
+ $pageTitle = Inflector::humanize($this->viewPath);
+ }
+
+ $dataForLayout = array_merge($this->viewVars, array('title_for_layout' => $pageTitle,
+ 'content_for_layout' => $contentForLayout,
+ 'cakeDebug' => $debug));
+
+ if (is_file($layoutFilename)) {
+ if (empty($this->loaded) && !empty($this->helpers)) {
+ $loadHelpers = true;
+ } else {
+ $loadHelpers = false;
+ $dataForLayout = array_merge($dataForLayout, $this->loaded);
+ }
+
+ if (substr($layoutFilename, -5) === 'thtml') {
+ $out = View::_render($layoutFilename, $dataForLayout, $loadHelpers, true);
+ } else {
+ $out = $this->_render($layoutFilename, $dataForLayout, $loadHelpers);
+ }
+
+ if ($out === false) {
+ $out = $this->_render($layoutFilename, $dataForLayout);
+ trigger_error(sprintf("Error in layout %s, got: <blockquote>%s</blockquote>", $layoutFilename, $out), E_USER_ERROR);
+ return false;
+ } else {
+ return $out;
+ }
+ } else {
+ return $this->cakeError('missingLayout', array(array('layout' => $this->layout,
+ 'file' => $layoutFilename,
+ 'base' => $this->base)));
+ }
+ }
+/**
+ * Sets layout to be used when rendering.
+ *
+ * @param string $layout Name of layout.
+ * @return void
+ * @access public
+ * @deprecated in 1.2.x.x
+ */
+ function setLayout($layout) {
+ $this->layout = $layout;
+ }
+/**
+ * Displays an error page to the user. Uses layouts/error.html to render the page.
+ *
+ * @param int $code HTTP Error code (for instance: 404)
+ * @param string $name Name of the error (for instance: Not Found)
+ * @param string $message Error message as a web page
+ * @return rendered error message
+ * @access public
+ *
+ */
+ function error($code, $name, $message) {
+ header ("HTTP/1.0 {$code} {$name}");
+ print ($this->_render(VIEWS . 'layouts/error.thtml', array('code' => $code,
+ 'name' => $name,
+ 'message' => $message)));
+ }
+/**
+ * Returns filename of given action's template file (.thtml) as a string. CamelCased action names will be under_scored! This means that you can have LongActionNames that refer to long_action_names.thtml views.
+ *
+ * @param string $action Controller action to find template filename for
+ * @return string Template filename
+ * @access protected
+ */
+ function _getViewFileName($action) {
+ $action = Inflector::underscore($action);
+
+ if (!is_null($this->webservices)) {
+ $type = strtolower($this->webservices) . DS;
+ } else {
+ $type = null;
+ }
+
+ $position = strpos($action, '..');
+ if ($position !== false) {
+ $action = explode('/', $action);
+ $i = array_search('..', $action);
+ unset($action[$i - 1]);
+ unset($action[$i]);
+ $action = '..' . DS . implode(DS, $action);
+ }
+
+ $paths = Configure::getInstance();
+ $viewPaths = am($this->pluginPaths, $paths->viewPaths);
+
+ $name = $this->viewPath . DS . $this->subDir . $type . $action;
+ foreach ($viewPaths as $path) {
+ if (file_exists($path . $name . $this->ext)) {
+ return $path . $name . $this->ext;
+ } elseif (file_exists($path . $name . '.ctp')) {
+ return $path . $name . '.ctp';
+ }
+ }
+
+ if ($viewFileName = fileExistsInPath(LIBS . 'view' . DS . 'templates' . DS . 'errors' . DS . $type . $action . '.thtml')) {
+ return $viewFileName;
+ } elseif ($viewFileName = fileExistsInPath(LIBS . 'view' . DS . 'templates' . DS . $this->viewPath . DS . $type . $action . '.thtml')) {
+ return $viewFileName;
+ } else {
+ if (!is_null($this->pluginPath)) {
+ $viewFileName = APP . $this->pluginPath . 'views' . DS . $name . $this->ext;
+ } else {
+ $viewFileName = VIEWS . $name . $this->ext;
+ }
+ }
+ return $viewFileName;
+ }
+/**
+ * Returns layout filename for this template as a string.
+ *
+ * @return string Filename for layout file (.thtml).
+ * @access protected
+ */
+ function _getLayoutFileName() {
+ if (isset($this->webservices) && !is_null($this->webservices)) {
+ $type = strtolower($this->webservices) . DS;
+ } else {
+ $type = null;
+ }
+
+ $paths = Configure::getInstance();
+ $viewPaths = am($this->pluginPaths, $paths->viewPaths);
+
+ $name = $this->subDir . $type . $this->layout;
+ foreach ($viewPaths as $path) {
+ if (file_exists($path . 'layouts' . DS . $name . $this->ext)) {
+ return $path . 'layouts' . DS . $name . $this->ext;
+ } elseif (file_exists($path . 'layouts' . DS . $name . '.ctp')) {
+ return $path . 'layouts' . DS . $name . '.ctp';
+ }
+ }
+
+ if (!is_null($this->pluginPath)) {
+ $layoutFileName = APP . $this->pluginPath . 'views' . DS . 'layouts' . DS . $name . $this->ext;
+ } else {
+ $layoutFileName = VIEWS . 'layouts' . DS . $name . $this->ext;
+ }
+
+ $layoutFileName = fileExistsInPath(LIBS . 'view' . DS . 'templates' . DS . 'layouts' . DS . $type . $this->layout . '.thtml');
+ if (empty($layoutFileName) && !empty($type)) {
+ $layoutFileName = fileExistsInPath(LIBS . 'view' . DS . 'templates' . DS . 'layouts' . DS . $type . 'default.thtml');
+ }
+ return $layoutFileName;
+ }
+
+/**
+ * Renders and returns output for given view filename with its array of data.
+ *
+ * @param string $___viewFn Filename of the view
+ * @param array $___dataForView Data to include in rendered view
+ * @return string Rendered output
+ * @access protected
+ */
+ function _render($___viewFn, $___dataForView, $loadHelpers = true, $cached = false) {
+ if ($this->helpers != false && $loadHelpers === true) {
+ $loadedHelpers = array();
+ $loadedHelpers = $this->_loadHelpers($loadedHelpers, $this->helpers);
+
+ foreach (array_keys($loadedHelpers) as $helper) {
+ $replace = strtolower(substr($helper, 0, 1));
+ $camelBackedHelper = preg_replace('/\\w/', $replace, $helper, 1);
+
+ ${$camelBackedHelper} =& $loadedHelpers[$helper];
+
+ if (isset(${$camelBackedHelper}->helpers) && is_array(${$camelBackedHelper}->helpers)) {
+ foreach (${$camelBackedHelper}->helpers as $subHelper) {
+ ${$camelBackedHelper}->{$subHelper} =& $loadedHelpers[$subHelper];
+ }
+ }
+ $this->loaded[$camelBackedHelper] =& ${$camelBackedHelper};
+ }
+ }
+ extract($___dataForView, EXTR_SKIP);
+ $BASE = $this->base;
+ $params =& $this->params;
+
+ ob_start();
+
+ if (Configure::read() > 0) {
+ include ($___viewFn);
+ } else {
+ @include ($___viewFn);
+ }
+
+ if ($this->helpers != false && $loadHelpers === true) {
+ foreach ($loadedHelpers as $helper) {
+ if (is_object($helper)) {
+ if (is_subclass_of($helper, 'Helper') || is_subclass_of($helper, 'helper')) {
+ $helper->afterRender();
+ }
+ }
+ }
+ }
+ $out = ob_get_clean();
+
+ if (isset($this->loaded['cache']) && ((isset($this->controller) && $this->controller->cacheAction != false)) && (defined('CACHE_CHECK') && CACHE_CHECK === true)) {
+ if (is_a($this->loaded['cache'], 'CacheHelper')) {
+ $cache =& $this->loaded['cache'];
+
+ if ($cached === true) {
+ $cache->view = &$this;
+ }
+
+ $cache->base = $this->base;
+ $cache->here = $this->here;
+ $cache->action = $this->action;
+ $cache->controllerName = $this->params['controller'];
+ $cache->cacheAction = $this->controller->cacheAction;
+ $cache->cache($___viewFn, $out, $cached);
+ }
+ }
+ return $out;
+ }
+/**
+ * Loads helpers, with their dependencies.
+ *
+ * @param array $loaded List of helpers that are already loaded.
+ * @param array $helpers List of helpers to load.
+ * @return array
+ * @access protected
+ */
+ function &_loadHelpers(&$loaded, $helpers) {
+ static $tags;
+ $helpers[] = 'Session';
+ if (empty($tags)) {
+ $helperTags = new Helper();
+ $tags = $helperTags->loadConfig();
+ }
+
+ foreach ($helpers as $helper) {
+ $parts = preg_split('/\/|\./', $helper);
+
+ if (count($parts) === 1) {
+ $plugin = $this->plugin;
+ } else {
+ $plugin = Inflector::underscore($parts['0']);
+ $helper = $parts[count($parts) - 1];
+ }
+ $helperCn = $helper . 'Helper';
+
+ if (in_array($helper, array_keys($loaded)) !== true) {
+ if (!class_exists($helperCn)) {
+ if (is_null($plugin) || !loadPluginHelper($plugin, $helper)) {
+ if (!loadHelper($helper)) {
+ $this->cakeError('missingHelperFile', array(array(
+ 'helper' => $helper,
+ 'file' => Inflector::underscore($helper) . '.php',
+ 'base' => $this->base)));
+ exit();
+ }
+ }
+ if (!class_exists($helperCn)) {
+ $this->cakeError('missingHelperClass', array(array(
+ 'helper' => $helper,
+ 'file' => Inflector::underscore($helper) . '.php',
+ 'base' => $this->base)));
+ exit();
+ }
+ }
+
+ $camelBackedHelper = Inflector::variable($helper);
+
+ ${$camelBackedHelper} =& new $helperCn;
+ ${$camelBackedHelper}->view =& $this;
+ ${$camelBackedHelper}->tags = $tags;
+
+ $vars = array('base', 'webroot', 'here', 'params', 'action', 'data', 'themeWeb', 'plugin');
+ $c = count($vars);
+ for ($j = 0; $j < $c; $j++) {
+ ${$camelBackedHelper}->{$vars[$j]} = $this->{$vars[$j]};
+ }
+
+ if (!empty($this->validationErrors)) {
+ ${$camelBackedHelper}->validationErrors = $this->validationErrors;
+ }
+
+ $loaded[$helper] =& ${$camelBackedHelper};
+
+ if (isset(${$camelBackedHelper}->helpers) && is_array(${$camelBackedHelper}->helpers)) {
+ $loaded = &$this->_loadHelpers($loaded, ${$camelBackedHelper}->helpers);
+ }
+ }
+ }
+ return $loaded;
+ }
+/**
+ * Returns a plugin view
+ *
+ * @param string $action Name of action to render for
+ * @param string $layout Layout to use
+ * @return mixed View::render() if template is found, error if template is missing
+ * @access public
+ */
+ function pluginView($action, $layout) {
+ $viewFileName = APP . 'plugins' . DS . $this->plugin . DS . 'views' . DS . $this->viewPath . DS . $action . $this->ext;
+
+ if (file_exists($viewFileName)) {
+ $this->render($action, $layout, $viewFileName);
+ } else {
+ return $this->cakeError('missingView', array(array(
+ 'className' => $this->controller->name,
+ 'action' => $action,
+ 'file' => $viewFileName,
+ 'base' => $this->base)));
+ }
+ }
+/**
+ * Renders a cached view if timestamp in file is less or equal to current time.
+ *
+ * If $layout is xml content type will be set before rendering the cache
+ *
+ * @param string $filename
+ * @param int $timeStart
+ * @return mixed outputs view, or returns void if timestamp has expired
+ * @access public
+ */
+ function renderCache($filename, $timeStart) {
+ ob_start();
+ include ($filename);
+
+ if (Configure::read() > 0 && $this->layout != 'xml') {
+ echo "<!-- Cached Render Time: " . round(getMicrotime() - $timeStart, 4) . "s -->";
+ }
+ $out = ob_get_clean();
+
+ if (preg_match('/^<!--cachetime:(\\d+)-->/', $out, $match)) {
+ if (time() >= $match['1']) {
+ @unlink($filename);
+ unset ($out);
+ return;
+ } else {
+ if ($this->layout === 'xml') {
+ header('Content-type: text/xml');
+ }
+ $out = str_replace('<!--cachetime:'.$match['1'].'-->', '', $out);
+ e($out);
+ die();
+ }
+ }
+ }
+}
+?> \ No newline at end of file
diff --git a/site/cake/scripts/acl.php b/site/cake/scripts/acl.php
new file mode 100644
index 0000000..cc10ce4
--- /dev/null
+++ b/site/cake/scripts/acl.php
@@ -0,0 +1,853 @@
+#!/usr/bin/php -q
+<?php
+/* SVN FILE: $Id: acl.php 6305 2008-01-02 02:33:56Z phpnut $ */
+/**
+ * Short description for file.
+ *
+ * Long description for file
+ *
+ * PHP versions 4 and 5
+ *
+ * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
+ * Copyright 2005-2008, Cake Software Foundation, Inc.
+ * 1785 E. Sahara Avenue, Suite 490-204
+ * Las Vegas, Nevada 89104
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
+ * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
+ * @package cake
+ * @subpackage cake.cake.scripts
+ * @since CakePHP(tm) v 0.10.0.1232
+ * @version $Revision: 6305 $
+ * @modifiedby $LastChangedBy: phpnut $
+ * @lastmodified $Date: 2008-01-01 20:33:56 -0600 (Tue, 01 Jan 2008) $
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+/**
+ * Enter description here...
+ */
+ define ('DS', DIRECTORY_SEPARATOR);
+ if (function_exists('ini_set')) {
+ ini_set('display_errors', '1');
+ ini_set('error_reporting', '7');
+ ini_set('max_execution_time',0);
+ }
+
+ $app = 'app';
+ $core = null;
+ $root = dirname(dirname(dirname(__FILE__)));
+ $here = $argv[0];
+ $dataSource = 'default';
+ $unset = array();
+ for ($i = 1; $i < count($argv); $i++) {
+ // Process command-line modifiers here
+ switch (strtolower($argv[$i])) {
+ case '-app':
+ $app = $argv[$i + 1];
+ $unset[$i] = $argv[$i];
+ $unset[$i + 1] = $argv[$i + 1];
+ break;
+ case '-core':
+ $core = $argv[$i + 1];
+ $unset[$i] = $argv[$i];
+ $unset[$i + 1] = $argv[$i + 1];
+ break;
+ case '-root':
+ $root = $argv[$i + 1];
+ $unset[$i] = $argv[$i];
+ $unset[$i + 1] = $argv[$i + 1];
+ break;
+ case '-datasource':
+ $dataSource = $argv[$i + 1];
+ $unset[$i] = $argv[$i];
+ $unset[$i + 1] = $argv[$i + 1];
+ break;
+ }
+ }
+
+ if (strlen($app) && $app[0] == DS) {
+ $cnt = substr_count($root, DS);
+ $app = str_repeat('..' . DS, $cnt) . $app;
+ }
+ define ('ROOT', $root.DS);
+ define ('APP_DIR', $app);
+ define ('DEBUG', 1);;
+ define('CAKE_CORE_INCLUDE_PATH', ROOT);
+ define('DATASOURCE', $dataSource);
+
+ if (function_exists('ini_set')) {
+ ini_set('include_path',ini_get('include_path').
+ PATH_SEPARATOR.CAKE_CORE_INCLUDE_PATH.DS.
+ PATH_SEPARATOR.CORE_PATH.DS.
+ PATH_SEPARATOR.ROOT.DS.APP_DIR.DS.
+ PATH_SEPARATOR.APP_DIR.DS.
+ PATH_SEPARATOR.APP_PATH);
+ define('APP_PATH', null);
+ define('CORE_PATH', null);
+ } else {
+ define('APP_PATH', ROOT . DS . APP_DIR . DS);
+ define('CORE_PATH', CAKE_CORE_INCLUDE_PATH . DS);
+ }
+
+ require ('cake'.DS.'basics.php');
+ require ('cake'.DS.'config'.DS.'paths.php');
+ require (CONFIGS.'core.php');
+ uses ('object', 'configure', 'neat_array', 'session', 'security', 'inflector', 'model'.DS.'connection_manager',
+ 'model'.DS.'datasources'.DS.'dbo_source', 'model'.DS.'model');
+ require(CAKE.'app_model.php');
+ uses ('controller'.DS.'components'.DS.'acl', 'controller'.DS.'components'.DS.'dbacl'.DS.'models'.DS.'aclnode',
+ 'controller'.DS.'components'.DS.'dbacl'.DS.'models'.DS.'aco', 'controller'.DS.'components'.DS.'dbacl'.DS.'models'.DS.'acoaction',
+ 'controller'.DS.'components'.DS.'dbacl'.DS.'models'.DS.'aro');
+ //Get and format args: first arg is the name of the script.
+ $serverArgs = $argv;
+ if (!empty($unset)) {
+ $serverArgs = array_values(array_diff($argv, $unset));
+ }
+
+ $wasted = array_shift($serverArgs);
+ $command = array_shift($serverArgs);
+ $args = $serverArgs;
+ $aclCLI = new AclCLI ($command, $args);
+/**
+ * @package cake
+ * @subpackage cake.cake.scritps
+ */
+class AclCLI {
+/**
+ * Enter description here...
+ *
+ * @var unknown_type
+ */
+ var $stdin;
+/**
+ * Enter description here...
+ *
+ * @var unknown_type
+ */
+ var $stdout;
+/**
+ * Enter description here...
+ *
+ * @var unknown_type
+ */
+ var $stderr;
+/**
+ * Enter description here...
+ *
+ * @var unknown_type
+ */
+ var $acl;
+/**
+ * Enter description here...
+ *
+ * @var unknown_type
+ */
+ var $args;
+/**
+ * Enter description here...
+ *
+ * @var unknown_type
+ */
+ var $dataSource = 'default';
+/**
+ * Enter description here...
+ *
+ * @param unknown_type $command
+ * @param unknown_type $args
+ * @return AclCLI
+ */
+ function AclCLI($command, $args) {
+ $this->__construct($command, $args);
+ }
+/**
+ * Enter description here...
+ *
+ * @param unknown_type $command
+ * @param unknown_type $args
+ */
+ function __construct ($command, $args) {
+ $this->stdin = fopen('php://stdin', 'r');
+ $this->stdout = fopen('php://stdout', 'w');
+ $this->stderr = fopen('php://stderr', 'w');
+
+ if (ACL_CLASSNAME != 'DB_ACL') {
+ $out = "--------------------------------------------------\n";
+ $out .= "Error: Your current Cake configuration is set to \n";
+ $out .= "an ACL implementation other than DB. Please change \n";
+ $out .= "your core config to reflect your decision to use \n";
+ $out .= "DB_ACL before attempting to use this script.\n";
+ $out .= "--------------------------------------------------\n";
+ $out .= "Current ACL Classname: " . ACL_CLASSNAME . "\n";
+ $out .= "--------------------------------------------------\n";
+ fwrite($this->stderr, $out);
+ exit();
+ }
+
+ if (!in_array($command, array('help'))) {
+ if (!file_exists(CONFIGS.'database.php')) {
+ $this->stdout('');
+ $this->stdout('Your database configuration was not found.');
+ $this->stdout('Take a moment to create one:');
+ $this->doDbConfig();
+ }
+ require_once (CONFIGS.'database.php');
+
+ if (!in_array($command, array('initdb'))) {
+ $this->dataSource = DATASOURCE;
+ $this->Acl = new AclComponent();
+ $this->args = $args;
+ $this->db =& ConnectionManager::getDataSource($this->dataSource);
+ }
+ }
+
+ switch ($command) {
+ case 'create':
+ $this->create();
+ break;
+ case 'delete':
+ $this->delete();
+ break;
+ case 'setParent':
+ $this->setParent();
+ break;
+ case 'getPath':
+ $this->getPath();
+ break;
+ case 'grant':
+ $this->grant();
+ break;
+ case 'deny':
+ $this->deny();
+ break;
+ case 'inherit':
+ $this->inherit();
+ break;
+ case 'view':
+ $this->view();
+ break;
+ case 'initdb':
+ $this->initdb();
+ break;
+ case 'upgrade':
+ $this->upgradedb();
+ break;
+ case 'help':
+ $this->help();
+ break;
+ default:
+ fwrite($this->stderr, "Unknown ACL command '$command'.\nFor usage, try 'php acl.php help'.\n\n");
+ break;
+ }
+ }
+/**
+ * Enter description here...
+ *
+ */
+ function create() {
+ $this->checkArgNumber(4, 'create');
+ $this->checkNodeType();
+ extract($this->__dataVars());
+
+ $parent = (is_numeric($this->args[2])) ? intval($this->args[2]) : $this->args[2];
+ if (!$this->Acl->{$class}->create(intval($this->args[1]), $parent, $this->args[3])) {
+ $this->displayError("Parent Node Not Found", "There was an error creating the ".$class.", probably couldn't find the parent node.\n If you wish to create a new root node, specify the <parent_id> as '0'.");
+ }
+ $this->stdout("New $class '".$this->args[3]."' created.\n\n");
+ }
+/**
+ * Enter description here...
+ *
+ */
+ function delete() {
+ $this->checkArgNumber(2, 'delete');
+ $this->checkNodeType();
+ extract($this->__dataVars());
+ if (!$this->Acl->{$class}->delete($this->args[1])) {
+ $this->displayError("Node Not Deleted", "There was an error deleting the ".$class.". Check that the node exists.\n");
+ }
+ $this->stdout("{$class} deleted.\n\n");
+ }
+
+/**
+ * Enter description here...
+ *
+ */
+ function setParent() {
+ $this->checkArgNumber(3, 'setParent');
+ $this->checkNodeType();
+ extract($this->__dataVars());
+ if (!$this->Acl->{$class}->setParent($this->args[2], $this->args[1])) {
+ $this->stdout("Error in setting new parent. Please make sure the parent node exists, and is not a descendant of the node specified.\n");
+ } else {
+ $this->stdout("Node parent set to ".$this->args[2]."\n\n");
+ }
+ }
+/**
+ * Enter description here...
+ *
+ */
+ function getPath() {
+ $this->checkArgNumber(2, 'getPath');
+ $this->checkNodeType();
+ extract($this->__dataVars());
+ $id = (is_numeric($this->args[2])) ? intval($this->args[1]) : $this->args[1];
+ $nodes = $this->Acl->{$class}->getPath($id);
+ if (empty($nodes)) {
+ $this->displayError("Supplied Node '".$this->args[1]."' not found", "No tree returned.");
+ }
+ for ($i = 0; $i < count($nodes); $i++) {
+ $this->stdout(str_repeat(' ', $i) . "[" . $nodes[$i][$class]['id'] . "]" . $nodes[$i][$class]['alias'] . "\n");
+ }
+ }
+/**
+ * Enter description here...
+ *
+ */
+ function grant() {
+ $this->checkArgNumber(3, 'grant');
+ //add existence checks for nodes involved
+ $aro = $this->args[0];
+ if (is_numeric($aro)) {
+ $aro = intval($aro);
+ }
+ $aco = $this->args[1];
+ if (is_numeric($aco)) {
+ $aco = intval($aco);
+ }
+ if ($this->Acl->allow($aro, $aco, $this->args[2])) {
+ $this->stdout("Permission granted.\n");
+ } else {
+ $this->stdout("Permission could not be granted.\n");
+ }
+ }
+/**
+ * Enter description here...
+ *
+ */
+ function deny() {
+ $this->checkArgNumber(3, 'deny');
+ //add existence checks for nodes involved
+ $aro = (is_numeric($this->args[0])) ? intval($this->args[0]) : $this->args[0];
+ $aco = (is_numeric($this->args[1])) ? intval($this->args[1]) : $this->args[1];
+ $aro = $this->args[0];
+ if (is_numeric($aro)) {
+ $aro = intval($aro);
+ }
+ $aco = $this->args[1];
+ if (is_numeric($aco)) {
+ $aco = intval($aco);
+ }
+ if ($this->Acl->deny($aro, $aco, $this->args[2])) {
+ $this->stdout("Permission denied.\n");
+ } else {
+ $this->stdout("Permission could not be denied.\n");
+ }
+ }
+/**
+ * Enter description here...
+ *
+ */
+ function inherit() {
+ $this->checkArgNumber(3, 'inherit');
+ $aro = $this->args[0];
+ if (is_numeric($aro)) {
+ $aro = intval($aro);
+ }
+ $aco = $this->args[1];
+ if (is_numeric($aco)) {
+ $aco = intval($aco);
+ }
+ if ($this->Acl->inherit($aro, $aco, $this->args[2])) {
+ $this->stdout("Permission inherited.\n");
+ } else {
+ $this->stdout("Permission could not be inherited.\n");
+ }
+ }
+/**
+ * Enter description here...
+ *
+ */
+ function view() {
+ $this->checkArgNumber(1, 'view');
+ $this->checkNodeType();
+ extract($this->__dataVars());
+ if (!is_null($this->args[1])) {
+ $conditions = $this->Acl->{$class}->_resolveID($this->args[1]);
+ } else {
+ $conditions = null;
+ }
+ $nodes = $this->Acl->{$class}->findAll($conditions, null, 'lft ASC');
+ if (empty($nodes)) {
+ $this->displayError($this->args[1]." not found", "No tree returned.");
+ }
+ $right = array();
+
+ $this->stdout($class . " tree:\n");
+ $this->stdout("------------------------------------------------\n");
+
+ for ($i = 0; $i < count($nodes); $i++) {
+ if (count($right) > 0) {
+ while ($right[count($right)-1] < $nodes[$i][$class]['rght']) {
+ if ($right[count($right)-1]) {
+ array_pop($right);
+ } else {
+ break;
+ }
+ }
+ }
+ $this->stdout(str_repeat(' ',count($right)) . "[" . $nodes[$i][$class]['id'] . "]" . $nodes[$i][$class]['alias']."\n");
+ $right[] = $nodes[$i][$class]['rght'];
+ }
+ $this->stdout("------------------------------------------------\n");
+ }
+/**
+ * Enter description here...
+ *
+ */
+ function initdb() {
+ $db =& ConnectionManager::getDataSource($this->dataSource);
+ $this->stdout("Initializing Database...\n");
+ $this->stdout("Creating access control objects table (acos)...\n");
+ $sql = " CREATE TABLE ".$db->fullTableName('acos')." (
+ ".$db->name('id')." ".$db->column($db->columns['primary_key']).",
+ ".$db->name('object_id')." ".$db->column($db->columns['integer'])." default NULL,
+ ".$db->name('alias')." ".$db->column($db->columns['string'])." NOT NULL default '',
+ ".$db->name('lft')." ".$db->column($db->columns['integer'])." default NULL,
+ ".$db->name('rght')." ".$db->column($db->columns['integer'])." default NULL,
+ PRIMARY KEY (".$db->name('id').")
+ );";
+ if ($db->query($sql) === false) {
+ die("Error: " . $db->lastError() . "\n\n");
+ }
+
+ $this->stdout("Creating access request objects table (aros)...\n");
+ $sql2 = "CREATE TABLE ".$db->fullTableName('aros')." (
+ ".$db->name('id')." ".$db->column($db->columns['primary_key']).",
+ ".$db->name('foreign_key')." ".$db->column($db->columns['integer'])." default NULL,
+ ".$db->name('alias')." ".$db->column($db->columns['string'])." NOT NULL default '',
+ ".$db->name('lft')." ".$db->column($db->columns['integer'])." default NULL,
+ ".$db->name('rght')." ".$db->column($db->columns['integer'])." default NULL,
+ PRIMARY KEY (".$db->name('id').")
+ );";
+ if ($db->query($sql2) === false) {
+ die("Error: " . $db->lastError() . "\n\n");
+ }
+
+ $this->stdout("Creating relationships table (aros_acos)...\n");
+ $sql3 = "CREATE TABLE ".$db->fullTableName('aros_acos')." (
+ ".$db->name('id')." ".$db->column($db->columns['primary_key']).",
+ ".$db->name('aro_id')." ".$db->column($db->columns['integer'])." default NULL,
+ ".$db->name('aco_id')." ".$db->column($db->columns['integer'])." default NULL,
+ ".$db->name('_create')." ".$db->column($db->columns['integer'])." NOT NULL default '0',
+ ".$db->name('_read')." ".$db->column($db->columns['integer'])." NOT NULL default '0',
+ ".$db->name('_update')." ".$db->column($db->columns['integer'])." NOT NULL default '0',
+ ".$db->name('_delete')." ".$db->column($db->columns['integer'])." NOT NULL default '0',
+ PRIMARY KEY (".$db->name('id').")
+ );";
+ if ($db->query($sql3) === false) {
+ die("Error: " . $db->lastError() . "\n\n");
+ }
+
+ $this->stdout("\nDone.\n");
+ }
+
+/**
+ * Enter description here...
+ *
+ */
+ function upgradedb() {
+ $db =& ConnectionManager::getDataSource($this->dataSource);
+ $this->stdout("Initializing Database...\n");
+ $this->stdout("Upgrading table (aros)...\n");
+ $sql = "ALTER TABLE ".$db->fullTableName('aros')."
+ CHANGE ".$db->name('user_id')."
+ ".$db->name('foreign_key')."
+ INT( 10 ) UNSIGNED NULL DEFAULT NULL;";
+ $sql .= "ALTER TABLE " . $db->name('aros_acos') . " CHANGE " . $db->name('_create')
+ . " " . $db->name('_create') . " CHAR(2) NOT NULL DEFAULT '0';";
+ $sql .= "ALTER TABLE " . $db->name('aros_acos') . " CHANGE " . $db->name('_update')
+ . " " . $db->name('_update') . " CHAR(2) NOT NULL DEFAULT '0';";
+ $sql .= "ALTER TABLE " . $db->name('aros_acos') . " CHANGE " . $db->name('_read')
+ . " " . $db->name('_read') . " CHAR(2) NOT NULL DEFAULT '0';";
+ $sql .= "ALTER TABLE " . $db->name('aros_acos') . " CHANGE " . $db->name('_delete')
+ . " " . $db->name('_delete') . " CHAR(2) NOT NULL DEFAULT '0';";
+ if ($db->query($sql) === false) {
+ die("Error: " . $db->lastError() . "\n\n");
+ }
+ $this->stdout("\nDatabase upgrade is complete.\n");
+ }
+
+/**
+ * Enter description here...
+ *
+ */
+ function help() {
+ $out = "Usage: php acl.php <command> <arg1> <arg2>...\n";
+ $out .= "-----------------------------------------------\n";
+ $out .= "Commands:\n";
+ $out .= "\n";
+ $out .= "\tcreate aro|aco <link_id> <parent_id> <alias>\n";
+ $out .= "\t\tCreates a new ACL object under the parent specified by <parent_id>, an id/alias (see\n";
+ $out .= "\t\t'view'). The link_id allows you to link a user object to Cake's\n";
+ $out .= "\t\tACL structures. The alias parameter allows you to address your object\n";
+ $out .= "\t\tusing a non-integer ID. Example: \"\$php acl.php create aro 57 0 John\"\n";
+ $out .= "\t\twould create a new ARO object at the root of the tree, linked to 57\n";
+ $out .= "\t\tin your users table, with an internal alias 'John'.";
+ $out .= "\n";
+ $out .= "\n";
+ $out .= "\tdelete aro|aco <id>\n";
+ $out .= "\t\tDeletes the ACL object with the specified ID (see 'view').\n";
+ $out .= "\n";
+ $out .= "\n";
+ $out .= "\tsetParent aro|aco <id> <parent_id>\n";
+ $out .= "\t\tUsed to set the parent of the ACL object specified by <id> to the ID\n";
+ $out .= "\t\tspecified by <parent_id>.\n";
+ $out .= "\n";
+ $out .= "\n";
+ $out .= "\tgetPath aro|aco <id>\n";
+ $out .= "\t\tReturns the path to the ACL object specified by <id>. This command is\n";
+ $out .= "\t\tis useful in determining the inhertiance of permissions for a certain\n";
+ $out .= "\t\tobject in the tree.\n";
+ $out .= "\n";
+ $out .= "\n";
+ $out .= "\tgrant <Aro.alias|Aro.foreign_key> <Aco.alias|Aco.object_id> <aco_action>\n";
+ $out .= "\t\tUse this command to grant ACL permissions. Once executed, the ARO\n";
+ $out .= "\t\tspecified (and its children, if any) will have ALLOW access to the\n";
+ $out .= "\t\tspecified ACO action (and the ACO's children, if any).\n";
+ $out .= "\t\tIf an integer is passed permissions will be granted based on the foreign_key or object_id.\n";
+ $out .= "\n";
+ $out .= "\n";
+ $out .= "\tdeny <Aro.alias|Aro.foreign_key> <Aco.alias|Aco.object_id> <aco_action>\n";
+ $out .= "\t\tUse this command to deny ACL permissions. Once executed, the ARO\n";
+ $out .= "\t\tspecified (and its children, if any) will have DENY access to the\n";
+ $out .= "\t\tspecified ACO action (and the ACO's children, if any).\n";
+ $out .= "\t\tIf an integer is passed permissions will be denied based on the foreign_key or object_id.\n";
+ $out .= "\n";
+ $out .= "\n";
+ $out .= "\tinherit <Aro.alias|Aro.foreign_key> <Aco.alias|Aco.object_id> <aco_action>\n";
+ $out .= "\t\tUse this command to force a child ARO object to inherit its\n";
+ $out .= "\t\tpermissions settings from its parent.\n";
+ $out .= "\t\tIf an integer is passed permissions will be inherited based on the foreign_key or object_id.\n";
+ $out .= "\n";
+ $out .= "\n";
+ $out .= "\tview aro|aco [id]\n";
+ $out .= "\t\tThe view command will return the ARO or ACO tree. The optional\n";
+ $out .= "\t\tid/alias parameter allows you to return only a portion of the requested\n";
+ $out .= "\t\ttree.\n";
+ $out .= "\n";
+ $out .= "\n";
+ $out .= "\tinitdb\n";
+ $out .= "\t\tUse this command to create the database tables needed to use DB ACL.\n";
+ $out .= "\n";
+ $out .= "\n";
+ $out .= "\thelp\n";
+ $out .= "\t\tDisplays this help message.\n";
+ $out .= "\n";
+ $out .= "\n";
+ $this->stdout($out);
+ }
+/**
+ * Enter description here...
+ *
+ * @param unknown_type $title
+ * @param unknown_type $msg
+ */
+ function displayError($title, $msg) {
+ $out = "\n";
+ $out .= "Error: $title\n";
+ $out .= "$msg\n";
+ $out .= "\n";
+ $this->stdout($out);
+ exit();
+ }
+
+/**
+ * Enter description here...
+ *
+ * @param unknown_type $expectedNum
+ * @param unknown_type $command
+ */
+ function checkArgNumber($expectedNum, $command) {
+ if (count($this->args) < $expectedNum) {
+ $this->displayError('Wrong number of parameters: '.count($this->args), 'Please type \'php acl.php help\' for help on usage of the '.$command.' command.');
+ }
+ }
+/**
+ * Enter description here...
+ *
+ */
+ function checkNodeType() {
+ if ($this->args[0] != 'aco' && $this->args[0] != 'aro') {
+ $this->displayError("Missing/Unknown node type: '".$this->args[0]."'", 'Please specify which ACL object type you wish to create.');
+ }
+ }
+/**
+ * Enter description here...
+ *
+ * @param unknown_type $type
+ * @param unknown_type $id
+ * @return unknown
+ */
+ function nodeExists($type, $id) {
+ //$this->stdout("Check to see if $type with ID = $id exists...\n");
+ extract($this->__dataVars($type));
+ $conditions = $this->Acl->{$class}->_resolveID($id);
+ $possibility = $this->Acl->{$class}->findAll($conditions);
+ return $possibility;
+ }
+
+/**
+ * Enter description here...
+ *
+ * @param unknown_type $type
+ * @return unknown
+ */
+ function __dataVars($type = null) {
+ if ($type == null) {
+ $type = $this->args[0];
+ }
+
+ $vars = array();
+ $class = ucwords($type);
+ $vars['secondary_id'] = ($class == 'aro' ? 'foreign_key' : 'object_id');
+ $vars['data_name'] = $type;
+ $vars['table_name'] = $type . 's';
+ $vars['class'] = $class;
+ return $vars;
+ }
+/**
+ * Database configuration setup.
+ *
+ */
+ function doDbConfig() {
+ $this->hr();
+ $this->stdout('Database Configuration:');
+ $this->hr();
+
+ $driver = '';
+
+ while ($driver == '') {
+ $driver = $this->getInput('What database driver would you like to use?', array('mysql','mysqli','mssql','sqlite','postgres', 'odbc'), 'mysql');
+ if ($driver == '') {
+ $this->stdout('The database driver supplied was empty. Please supply a database driver.');
+ }
+ }
+
+ switch($driver) {
+ case 'mysql':
+ $connect = 'mysql_connect';
+ break;
+ case 'mysqli':
+ $connect = 'mysqli_connect';
+ break;
+ case 'mssql':
+ $connect = 'mssql_connect';
+ break;
+ case 'sqlite':
+ $connect = 'sqlite_open';
+ break;
+ case 'postgres':
+ $connect = 'pg_connect';
+ break;
+ case 'odbc':
+ $connect = 'odbc_connect';
+ break;
+ default:
+ $this->stdout('The connection parameter could not be set.');
+ break;
+ }
+
+ $host = '';
+
+ while ($host == '') {
+ $host = $this->getInput('What is the hostname for the database server?', null, 'localhost');
+ if ($host == '') {
+ $this->stdout('The host name you supplied was empty. Please supply a hostname.');
+ }
+ }
+ $login = '';
+
+ while ($login == '') {
+ $login = $this->getInput('What is the database username?', null, 'root');
+
+ if ($login == '') {
+ $this->stdout('The database username you supplied was empty. Please try again.');
+ }
+ }
+ $password = '';
+ $blankPassword = false;
+
+ while ($password == '' && $blankPassword == false) {
+ $password = $this->getInput('What is the database password?');
+ if ($password == '') {
+ $blank = $this->getInput('The password you supplied was empty. Use an empty password?', array('y', 'n'), 'n');
+ if ($blank == 'y')
+ {
+ $blankPassword = true;
+ }
+ }
+ }
+ $database = '';
+
+ while ($database == '') {
+ $database = $this->getInput('What is the name of the database you will be using?', null, 'cake');
+
+ if ($database == '') {
+ $this->stdout('The database name you supplied was empty. Please try again.');
+ }
+ }
+
+ $prefix = '';
+
+ while ($prefix == '') {
+ $prefix = $this->getInput('Enter a table prefix?', null, 'n');
+ }
+ if (low($prefix) == 'n') {
+ $prefix = '';
+ }
+
+ $this->stdout('');
+ $this->hr();
+ $this->stdout('The following database configuration will be created:');
+ $this->hr();
+ $this->stdout("Driver: $driver");
+ $this->stdout("Connection: $connect");
+ $this->stdout("Host: $host");
+ $this->stdout("User: $login");
+ $this->stdout("Pass: " . str_repeat('*', strlen($password)));
+ $this->stdout("Database: $database");
+ $this->stdout("Table prefix: $prefix");
+ $this->hr();
+ $looksGood = $this->getInput('Look okay?', array('y', 'n'), 'y');
+
+ if (low($looksGood) == 'y' || low($looksGood) == 'yes') {
+ $this->bakeDbConfig($driver, $connect, $host, $login, $password, $database, $prefix);
+ } else {
+ $this->stdout('Bake Aborted.');
+ }
+ }
+/**
+ * Creates a database configuration file for Bake.
+ *
+ * @param string $host
+ * @param string $login
+ * @param string $password
+ * @param string $database
+ */
+ function bakeDbConfig( $driver, $connect, $host, $login, $password, $database, $prefix) {
+ $out = "<?php\n";
+ $out .= "class DATABASE_CONFIG {\n\n";
+ $out .= "\tvar \$default = array(\n";
+ $out .= "\t\t'driver' => '{$driver}',\n";
+ $out .= "\t\t'connect' => '{$connect}',\n";
+ $out .= "\t\t'host' => '{$host}',\n";
+ $out .= "\t\t'login' => '{$login}',\n";
+ $out .= "\t\t'password' => '{$password}',\n";
+ $out .= "\t\t'database' => '{$database}', \n";
+ $out .= "\t\t'prefix' => '{$prefix}' \n";
+ $out .= "\t);\n";
+ $out .= "}\n";
+ $out .= "?>";
+ $filename = CONFIGS.'database.php';
+ $this->__createFile($filename, $out);
+ }
+/**
+ * Prompts the user for input, and returns it.
+ *
+ * @param string $prompt Prompt text.
+ * @param mixed $options Array or string of options.
+ * @param string $default Default input value.
+ * @return Either the default value, or the user-provided input.
+ */
+ function getInput($prompt, $options = null, $default = null) {
+ if (!is_array($options)) {
+ $print_options = '';
+ } else {
+ $print_options = '(' . implode('/', $options) . ')';
+ }
+
+ if ($default == null) {
+ $this->stdout('');
+ $this->stdout($prompt . " $print_options \n" . '> ', false);
+ } else {
+ $this->stdout('');
+ $this->stdout($prompt . " $print_options \n" . "[$default] > ", false);
+ }
+ $result = trim(fgets($this->stdin));
+
+ if ($default != null && empty($result)) {
+ return $default;
+ } else {
+ return $result;
+ }
+ }
+/**
+ * Outputs to the stdout filehandle.
+ *
+ * @param string $string String to output.
+ * @param boolean $newline If true, the outputs gets an added newline.
+ */
+ function stdout($string, $newline = true) {
+ if ($newline) {
+ fwrite($this->stdout, $string . "\n");
+ } else {
+ fwrite($this->stdout, $string);
+ }
+ }
+/**
+ * Outputs to the stderr filehandle.
+ *
+ * @param string $string Error text to output.
+ */
+ function stderr($string) {
+ fwrite($this->stderr, $string);
+ }
+/**
+ * Outputs a series of minus characters to the standard output, acts as a visual separator.
+ *
+ */
+ function hr() {
+ $this->stdout('---------------------------------------------------------------');
+ }
+/**
+ * Creates a file at given path.
+ *
+ * @param string $path Where to put the file.
+ * @param string $contents Content to put in the file.
+ * @return Success
+ */
+ function __createFile ($path, $contents) {
+ $path = str_replace('//', '/', $path);
+ echo "\nCreating file $path\n";
+ if (is_file($path) && $this->interactive === true) {
+ fwrite($this->stdout, "File exists, overwrite?" . " {$path} (y/n/q):");
+ $key = trim(fgets($this->stdin));
+
+ if ($key=='q') {
+ fwrite($this->stdout, "Quitting.\n");
+ exit;
+ } elseif ($key == 'a') {
+ $this->dont_ask = true;
+ } elseif ($key == 'y') {
+ } else {
+ fwrite($this->stdout, "Skip" . " {$path}\n");
+ return false;
+ }
+ }
+
+ if ($f = fopen($path, 'w')) {
+ fwrite($f, $contents);
+ fclose($f);
+ fwrite($this->stdout, "Wrote" . "{$path}\n");
+ return true;
+ } else {
+ fwrite($this->stderr, "Error! Could not write to" . " {$path}.\n");
+ return false;
+ }
+ }
+}
+?> \ No newline at end of file
diff --git a/site/cake/scripts/bake.php b/site/cake/scripts/bake.php
new file mode 100644
index 0000000..4633ca5
--- /dev/null
+++ b/site/cake/scripts/bake.php
@@ -0,0 +1,2635 @@
+#!/usr/bin/php -q
+<?php
+/* SVN FILE: $Id: bake.php 6305 2008-01-02 02:33:56Z phpnut $ */
+/**
+ * Command-line code generation utility to automate programmer chores.
+ *
+ * Bake is CakePHP's code generation script, which can help you kickstart
+ * application development by writing fully functional skeleton controllers,
+ * models, and views. Going further, Bake can also write Unit Tests for you.
+ *
+ * PHP versions 4 and 5
+ *
+ * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
+ * Copyright 2005-2008, Cake Software Foundation, Inc.
+ * 1785 E. Sahara Avenue, Suite 490-204
+ * Las Vegas, Nevada 89104
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
+ * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
+ * @package cake
+ * @subpackage cake.cake.scripts.bake
+ * @since CakePHP(tm) v 0.10.0.1232
+ * @version $Revision: 6305 $
+ * @modifiedby $LastChangedBy: phpnut $
+ * @lastmodified $Date: 2008-01-01 20:33:56 -0600 (Tue, 01 Jan 2008) $
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+ define ('DS', DIRECTORY_SEPARATOR);
+ if (function_exists('ini_set')) {
+ ini_set('display_errors', '1');
+ ini_set('error_reporting', '7');
+ ini_set('max_execution_time',0);
+ }
+
+ $app = null;
+ $root = dirname(dirname(dirname(__FILE__)));
+ $core = null;
+ $here = $argv[0];
+ $help = null;
+ $project = null;
+
+ for ($i = 1; $i < count($argv); $i += 2) {
+ switch ($argv[$i]) {
+ case '-a':
+ case '-app':
+ $app = $argv[$i + 1];
+ break;
+ case '-c':
+ case '-core':
+ $core = $argv[$i + 1];
+ break;
+ case '-r':
+ case '-root':
+ $root = $argv[$i + 1];
+ break;
+ case '-h':
+ case '-help':
+ $help = true;
+ break;
+ case '-p':
+ case '-project':
+ $project = true;
+ $projectPath = $argv[$i + 1];
+ $app = $argv[$i + 1];
+ break;
+ }
+ }
+
+ if (!$app && isset($argv[1])) {
+ $app = $argv[1];
+ } elseif (!$app) {
+ $app = 'app';
+ }
+ if (!is_dir($app)) {
+ $project = true;
+ $projectPath = $app;
+
+ }
+ if ($project) {
+ $app = $projectPath;
+ }
+
+ $shortPath = str_replace($root, '', $app);
+ $shortPath = str_replace('..'.DS, '', $shortPath);
+ $shortPath = str_replace(DS.DS, DS, $shortPath);
+
+ $pathArray = explode(DS, $shortPath);
+ if (end($pathArray) != '') {
+ $appDir = array_pop($pathArray);
+ } else {
+ array_pop($pathArray);
+ $appDir = array_pop($pathArray);
+ }
+ $rootDir = implode(DS, $pathArray);
+ $rootDir = str_replace(DS.DS, DS, $rootDir);
+
+ if (!$rootDir) {
+ $rootDir = $root;
+ $projectPath = $root.DS.$appDir;
+ }
+
+ define ('ROOT', $rootDir);
+ define ('APP_DIR', $appDir);
+ define ('DEBUG', 1);
+
+ if (!empty($core)) {
+ define('CAKE_CORE_INCLUDE_PATH', dirname($core));
+ } else {
+ define('CAKE_CORE_INCLUDE_PATH', $root);
+ }
+
+ if (function_exists('ini_set')) {
+ ini_set('include_path',ini_get('include_path').
+ PATH_SEPARATOR.CAKE_CORE_INCLUDE_PATH.DS.
+ PATH_SEPARATOR.ROOT.DS.APP_DIR.DS);
+ define('APP_PATH', null);
+ define('CORE_PATH', null);
+ } else {
+ define('APP_PATH', ROOT . DS . APP_DIR . DS);
+ define('CORE_PATH', CAKE_CORE_INCLUDE_PATH . DS);
+ }
+
+ require_once (CORE_PATH.'cake'.DS.'basics.php');
+ require_once (CORE_PATH.'cake'.DS.'config'.DS.'paths.php');
+ require_once (CORE_PATH.'cake'.DS.'scripts'.DS.'templates'.DS.'skel'.DS.'config'.DS.'core.php');
+ require_once (CORE_PATH.'cake'.DS.'dispatcher.php');
+ uses('object', 'session', 'security', 'configure', 'inflector', 'model'.DS.'connection_manager');
+
+ $pattyCake = new Bake();
+ if ($help === true)
+ {
+ $pattyCake->help();
+ exit();
+ }
+ if ($project === true)
+ {
+ $pattyCake->project($projectPath);
+ exit();
+ }
+ $pattyCake->main();
+/**
+ * Bake is a command-line code generation utility for automating programmer chores.
+ *
+ * @package cake
+ * @subpackage cake.cake.scripts
+ */
+class Bake {
+
+/**
+ * Standard input stream.
+ *
+ * @var filehandle
+ */
+ var $stdin;
+/**
+ * Standard output stream.
+ *
+ * @var filehandle
+ */
+ var $stdout;
+/**
+ * Standard error stream.
+ *
+ * @var filehandle
+ */
+ var $stderr;
+/**
+ * Associated controller name.
+ *
+ * @var string
+ */
+ var $controllerName = null;
+/**
+ * If true, Bake will ask for permission to perform actions.
+ *
+ * @var boolean
+ */
+ var $interactive = false;
+
+ var $__modelAlias = false;
+/**
+ * Private helper function for constructor
+ * @access private
+ */
+ function __construct() {
+ $this->stdin = fopen('php://stdin', 'r');
+ $this->stdout = fopen('php://stdout', 'w');
+ $this->stderr = fopen('php://stderr', 'w');
+ $this->welcome();
+ }
+/**
+ * Constructor.
+ *
+ * @return Bake
+ */
+ function Bake() {
+ return $this->__construct();
+ }
+/**
+ * Main-loop method.
+ *
+ */
+ function main() {
+
+ $this->stdout('');
+ $this->stdout('');
+ $this->stdout('Baking...');
+ $this->hr();
+ $this->stdout('Name: '. APP_DIR);
+ $this->stdout('Path: '. ROOT.DS.APP_DIR);
+ $this->hr();
+
+ if (!file_exists(CONFIGS.'database.php')) {
+ $this->stdout('');
+ $this->stdout('Your database configuration was not found. Take a moment to create one:');
+ $this->doDbConfig();
+ }
+ require_once (CONFIGS.'database.php');
+ $this->stdout('[M]odel');
+ $this->stdout('[C]ontroller');
+ $this->stdout('[V]iew');
+ $invalidSelection = true;
+
+ while ($invalidSelection) {
+ $classToBake = strtoupper($this->getInput('What would you like to Bake?', array('M', 'V', 'C')));
+ switch($classToBake) {
+ case 'M':
+ $invalidSelection = false;
+ $this->doModel();
+ break;
+ case 'V':
+ $invalidSelection = false;
+ $this->doView();
+ break;
+ case 'C':
+ $invalidSelection = false;
+ $this->doController();
+ break;
+ default:
+ $this->stdout('You have made an invalid selection. Please choose a type of class to Bake by entering M, V, or C.');
+ }
+ }
+ }
+/**
+ * Database configuration setup.
+ *
+ */
+ function doDbConfig() {
+ $this->hr();
+ $this->stdout('Database Configuration:');
+ $this->hr();
+
+ $driver = '';
+
+ while ($driver == '') {
+ $driver = $this->getInput('What database driver would you like to use?', array('mysql','mysqli','mssql','sqlite','postgres', 'odbc'), 'mysql');
+ if ($driver == '') {
+ $this->stdout('The database driver supplied was empty. Please supply a database driver.');
+ }
+ }
+
+ switch($driver) {
+ case 'mysql':
+ $connect = 'mysql_connect';
+ break;
+ case 'mysqli':
+ $connect = 'mysqli_connect';
+ break;
+ case 'mssql':
+ $connect = 'mssql_connect';
+ break;
+ case 'sqlite':
+ $connect = 'sqlite_open';
+ break;
+ case 'postgres':
+ $connect = 'pg_connect';
+ break;
+ case 'odbc':
+ $connect = 'odbc_connect';
+ break;
+ default:
+ $this->stdout('The connection parameter could not be set.');
+ break;
+ }
+
+ $host = '';
+
+ while ($host == '') {
+ $host = $this->getInput('What is the hostname for the database server?', null, 'localhost');
+ if ($host == '') {
+ $this->stdout('The host name you supplied was empty. Please supply a hostname.');
+ }
+ }
+ $login = '';
+
+ while ($login == '') {
+ $login = $this->getInput('What is the database username?', null, 'root');
+
+ if ($login == '') {
+ $this->stdout('The database username you supplied was empty. Please try again.');
+ }
+ }
+ $password = '';
+ $blankPassword = false;
+
+ while ($password == '' && $blankPassword == false) {
+ $password = $this->getInput('What is the database password?');
+ if ($password == '') {
+ $blank = $this->getInput('The password you supplied was empty. Use an empty password?', array('y', 'n'), 'n');
+ if ($blank == 'y')
+ {
+ $blankPassword = true;
+ }
+ }
+ }
+ $database = '';
+
+ while ($database == '') {
+ $database = $this->getInput('What is the name of the database you will be using?', null, 'cake');
+
+ if ($database == '') {
+ $this->stdout('The database name you supplied was empty. Please try again.');
+ }
+ }
+
+ $prefix = '';
+
+ while ($prefix == '') {
+ $prefix = $this->getInput('Enter a table prefix?', null, 'n');
+ }
+ if (low($prefix) == 'n') {
+ $prefix = '';
+ }
+
+ $this->stdout('');
+ $this->hr();
+ $this->stdout('The following database configuration will be created:');
+ $this->hr();
+ $this->stdout("Driver: $driver");
+ $this->stdout("Connection: $connect");
+ $this->stdout("Host: $host");
+ $this->stdout("User: $login");
+ $this->stdout("Pass: " . str_repeat('*', strlen($password)));
+ $this->stdout("Database: $database");
+ $this->stdout("Table prefix: $prefix");
+ $this->hr();
+ $looksGood = $this->getInput('Look okay?', array('y', 'n'), 'y');
+
+ if (low($looksGood) == 'y' || low($looksGood) == 'yes') {
+ $this->bakeDbConfig($driver, $connect, $host, $login, $password, $database, $prefix);
+ } else {
+ $this->stdout('Bake Aborted.');
+ }
+ }
+/**
+ * Action to create a Model.
+ *
+ */
+ function doModel()
+ {
+ $this->hr();
+ $this->stdout('Model Bake:');
+ $this->hr();
+ $this->interactive = true;
+
+ $useTable = null;
+ $primaryKey = 'id';
+ $validate = array();
+ $associations = array();
+ $useDbConfig = 'default';
+ $this->__doList($useDbConfig);
+
+
+ $enteredModel = '';
+
+ while ($enteredModel == '') {
+ $enteredModel = $this->getInput('Enter a number from the list above, or type in the name of another model.');
+
+ if ($enteredModel == '' || intval($enteredModel) > count($this->__modelNames)) {
+ $this->stdout('Error:');
+ $this->stdout("The model name you supplied was empty, or the number \nyou selected was not an option. Please try again.");
+ $enteredModel = '';
+ }
+ }
+
+ if (intval($enteredModel) > 0 && intval($enteredModel) <= count($this->__modelNames)) {
+ $currentModelName = $this->__modelNames[intval($enteredModel) - 1];
+ } else {
+ $currentModelName = $enteredModel;
+ }
+
+ $db =& ConnectionManager::getDataSource($useDbConfig);
+
+ $useTable = Inflector::tableize($currentModelName);
+ $fullTableName = $db->fullTableName($useTable, false);
+ if (array_search($useTable, $this->__tables) === false) {
+ $this->stdout("\nGiven your model named '$currentModelName', Cake would expect a database table named '" . $fullTableName . "'.");
+ $tableIsGood = $this->getInput('do you want to use this table?', array('y','n'), 'y');
+ }
+
+ if (low($tableIsGood) == 'n' || low($tableIsGood) == 'no') {
+ $useTable = $this->getInput('What is the name of the table (enter "null" to use NO table)?');
+ }
+ $tableIsGood = false;
+ while ($tableIsGood == false && low($useTable) != 'null') {
+ if (is_array($this->__tables) && !in_array($useTable, $this->__tables)) {
+ $fullTableName = $db->fullTableName($useTable, false);
+ $this->stdout($fullTableName . ' does not exist.');
+ $useTable = $this->getInput('What is the name of the table (enter "null" to use NO table)?');
+ $tableIsGood = false;
+ } else {
+ $tableIsGood = true;
+ }
+ }
+ $wannaDoValidation = $this->getInput('Would you like to supply validation criteria for the fields in your model?', array('y','n'), 'y');
+
+ if (in_array($useTable, $this->__tables)) {
+ loadModel();
+ $tempModel = new Model(false, $useTable);
+ $modelFields = $db->describe($tempModel);
+
+ if (!array_key_exists('id', $modelFields)) {
+ foreach ($modelFields as $name => $field) {
+ break;
+ }
+ $primaryKey = $this->getInput('What is the primaryKey?', null, $name);
+ }
+ }
+ $validate = array();
+
+ if (array_search($useTable, $this->__tables) !== false && (low($wannaDoValidation) == 'y' || low($wannaDoValidation) == 'yes')) {
+ foreach ($modelFields as $name => $field) {
+ $this->stdout('');
+ $prompt = 'Name: ' . $name . "\n";
+ $prompt .= 'Type: ' . $field['type'] . "\n";
+ $prompt .= '---------------------------------------------------------------'."\n";
+ $prompt .= 'Please select one of the following validation options:'."\n";
+ $prompt .= '---------------------------------------------------------------'."\n";
+ $prompt .= "1- VALID_NOT_EMPTY\n";
+ $prompt .= "2- VALID_EMAIL\n";
+ $prompt .= "3- VALID_NUMBER\n";
+ $prompt .= "4- VALID_YEAR\n";
+ $prompt .= "5- Do not do any validation on this field.\n\n";
+ $prompt .= "... or enter in a valid regex validation string.\n\n";
+
+ if ($field['null'] == 1 || $name == $primaryKey || $name == 'created' || $name == 'modified') {
+ $validation = $this->getInput($prompt, null, '5');
+ } else {
+ $validation = $this->getInput($prompt, null, '1');
+ }
+
+ switch ($validation) {
+ case '1':
+ $validate[$name] = 'VALID_NOT_EMPTY';
+ break;
+ case '2':
+ $validate[$name] = 'VALID_EMAIL';
+ break;
+ case '3':
+ $validate[$name] = 'VALID_NUMBER';
+ break;
+ case '4':
+ $validate[$name] = 'VALID_YEAR';
+ break;
+ case '5':
+ break;
+ default:
+ $validate[$name] = $validation;
+ break;
+ }
+ }
+ }
+
+ $wannaDoAssoc = $this->getInput('Would you like to define model associations (hasMany, hasOne, belongsTo, etc.)?', array('y','n'), 'y');
+
+ if ((low($wannaDoAssoc) == 'y' || low($wannaDoAssoc) == 'yes')) {
+ $this->stdout('One moment while I try to detect any associations...');
+ $possibleKeys = array();
+ $i = 0;
+ foreach ($modelFields as $name => $field) {
+ $offset = strpos($name, '_id');
+ if ($name != $primaryKey && $offset !== false) {
+ $tmpModelName = $this->__modelNameFromKey($name);
+ $associations['belongsTo'][$i]['alias'] = $tmpModelName;
+ $associations['belongsTo'][$i]['className'] = $tmpModelName;
+ $associations['belongsTo'][$i]['foreignKey'] = $name;
+ $i++;
+ }
+ }
+ $i = 0;
+ $j = 0;
+ foreach ($this->__tables as $otherTable) {
+ $tempOtherModel = & new Model(false, $otherTable);
+ $modelFieldsTemp = $db->describe($tempOtherModel);
+ foreach ($modelFieldsTemp as $name => $field) {
+ if ($field['type'] == 'integer' || $field['type'] == 'string') {
+ $possibleKeys[$otherTable][] = $name;
+ }
+ if ($name != $primaryKey && $name == $this->__modelKey($currentModelName)) {
+ $tmpModelName = $this->__modelName($otherTable);
+ $associations['hasOne'][$j]['alias'] = $tmpModelName;
+ $associations['hasOne'][$j]['className'] = $tmpModelName;
+ $associations['hasOne'][$j]['foreignKey'] = $name;
+
+ $associations['hasMany'][$j]['alias'] = $tmpModelName;
+ $associations['hasMany'][$j]['className'] = $tmpModelName;
+ $associations['hasMany'][$j]['foreignKey'] = $name;
+ $j++;
+ }
+ }
+ $offset = strpos($otherTable, $useTable . '_');
+ if ($offset !== false) {
+ $offset = strlen($useTable . '_');
+ $tmpModelName = $this->__modelName(substr($otherTable, $offset));
+ $associations['hasAndBelongsToMany'][$i]['alias'] = $tmpModelName;
+ $associations['hasAndBelongsToMany'][$i]['className'] = $tmpModelName;
+ $associations['hasAndBelongsToMany'][$i]['foreignKey'] = $this->__modelKey($currentModelName);
+ $associations['hasAndBelongsToMany'][$i]['associationForeignKey'] = $this->__modelKey($tmpModelName);
+ $associations['hasAndBelongsToMany'][$i]['joinTable'] = $otherTable;
+ $i++;
+ }
+ $offset = strpos($otherTable, '_' . $useTable);
+ if ($offset !== false) {
+ $tmpModelName = $this->__modelName(substr($otherTable, 0, $offset));
+ $associations['hasAndBelongsToMany'][$i]['alias'] = $tmpModelName;
+ $associations['hasAndBelongsToMany'][$i]['className'] = $tmpModelName;
+ $associations['hasAndBelongsToMany'][$i]['foreignKey'] = $this->__modelKey($currentModelName);
+ $associations['hasAndBelongsToMany'][$i]['associationForeignKey'] = $this->__modelKey($tmpModelName);
+ $associations['hasAndBelongsToMany'][$i]['joinTable'] = $otherTable;
+ $i++;
+ }
+ }
+ $this->stdout('Done.');
+ $this->hr();
+ if (empty($associations)) {
+ $this->stdout('None found.');
+ } else {
+ $this->stdout('Please confirm the following associations:');
+ $this->hr();
+ if (!empty($associations['belongsTo'])) {
+ $count = count($associations['belongsTo']);
+ for ($i = 0; $i < $count; $i++) {
+ if ($currentModelName == $associations['belongsTo'][$i]['alias']) {
+ $response = $this->getInput("{$currentModelName} belongsTo {$associations['belongsTo'][$i]['alias']}\nThis looks like a self join. Do you want to specify an alternate association alias?", array('y','n'), 'y');
+ if ('y' == low($response) || 'yes' == low($response)) {
+ $associations['belongsTo'][$i]['alias'] = $this->getInput("So what is the alias?", null, $associations['belongsTo'][$i]['alias']);
+ }
+ if ($currentModelName != $associations['belongsTo'][$i]['alias']) {
+ $response = $this->getInput("$currentModelName belongsTo {$associations['belongsTo'][$i]['alias']}?", array('y','n'), 'y');
+ } else {
+ $response = 'n';
+ }
+ } else {
+ $response = $this->getInput("$currentModelName belongsTo {$associations['belongsTo'][$i]['alias']}?", array('y','n'), 'y');
+ }
+ if ('n' == low($response) || 'no' == low($response)) {
+ unset($associations['belongsTo'][$i]);
+ }
+ }
+ $associations['belongsTo'] = array_merge($associations['belongsTo']);
+ }
+
+ if (!empty($associations['hasOne'])) {
+ $count = count($associations['hasOne']);
+ for ($i = 0; $i < $count; $i++) {
+ if ($currentModelName == $associations['hasOne'][$i]['alias']) {
+ $response = $this->getInput("{$currentModelName} hasOne {$associations['hasOne'][$i]['alias']}\nThis looks like a self join. Do you want to specify an alternate association alias?", array('y','n'), 'y');
+ if ('y' == low($response) || 'yes' == low($response)) {
+ $associations['hasOne'][$i]['alias'] = $this->getInput("So what is the alias?", null, $associations['hasOne'][$i]['alias']);
+ }
+ if ($currentModelName != $associations['hasOne'][$i]['alias']) {
+ $response = $this->getInput("$currentModelName hasOne {$associations['hasOne'][$i]['alias']}?", array('y','n'), 'y');
+ } else {
+ $response = 'n';
+ }
+ } else {
+ $response = $this->getInput("$currentModelName hasOne {$associations['hasOne'][$i]['alias']}?", array('y','n'), 'y');
+ }
+ if ('n' == low($response) || 'no' == low($response)) {
+ unset($associations['hasOne'][$i]);
+ }
+ }
+ $associations['hasOne'] = array_merge($associations['hasOne']);
+ }
+
+ if (!empty($associations['hasMany'])) {
+ $count = count($associations['hasMany']);
+ for ($i = 0; $i < $count; $i++) {
+ if ($currentModelName == $associations['hasMany'][$i]['alias']) {
+ $response = $this->getInput("{$currentModelName} hasMany {$associations['hasMany'][$i]['alias']}\nThis looks like a self join. Do you want to specify an alternate association alias?", array('y','n'), 'y');
+ if ('y' == low($response) || 'yes' == low($response)) {
+ $associations['hasMany'][$i]['alias'] = $this->getInput("So what is the alias?", null, $associations['hasMany'][$i]['alias']);
+ }
+ if ($currentModelName != $associations['hasMany'][$i]['alias']) {
+ $response = $this->getInput("$currentModelName hasMany {$associations['hasMany'][$i]['alias']}?", array('y','n'), 'y');
+ } else {
+ $response = 'n';
+ }
+ } else {
+ $response = $this->getInput("$currentModelName hasMany {$associations['hasMany'][$i]['alias']}?", array('y','n'), 'y');
+ }
+ if ('n' == low($response) || 'no' == low($response)) {
+ unset($associations['hasMany'][$i]);
+ }
+ }
+ $associations['hasMany'] = array_merge($associations['hasMany']);
+ }
+
+ if (!empty($associations['hasAndBelongsToMany'])) {
+ $count = count($associations['hasAndBelongsToMany']);
+ for ($i = 0; $i < $count; $i++) {
+ if ($currentModelName == $associations['hasAndBelongsToMany'][$i]['alias']) {
+ $response = $this->getInput("{$currentModelName} hasAndBelongsToMany {$associations['hasAndBelongsToMany'][$i]['alias']}\nThis looks like a self join. Do you want to specify an alternate association alias?", array('y','n'), 'y');
+ if ('y' == low($response) || 'yes' == low($response)) {
+ $associations['hasAndBelongsToMany'][$i]['alias'] = $this->getInput("So what is the alias?", null, $associations['hasAndBelongsToMany'][$i]['alias']);
+ }
+ if ($currentModelName != $associations['hasAndBelongsToMany'][$i]['alias']) {
+ $response = $this->getInput("$currentModelName hasAndBelongsToMany {$associations['hasAndBelongsToMany'][$i]['alias']}?", array('y','n'), 'y');
+ } else {
+ $response = 'n';
+ }
+ } else {
+ $response = $this->getInput("$currentModelName hasAndBelongsToMany {$associations['hasAndBelongsToMany'][$i]['alias']}?", array('y','n'), 'y');
+ }
+ if ('n' == low($response) || 'no' == low($response)) {
+ unset($associations['hasAndBelongsToMany'][$i]);
+ }
+ }
+ $associations['hasAndBelongsToMany'] = array_merge($associations['hasAndBelongsToMany']);
+ }
+ }
+ $wannaDoMoreAssoc = $this->getInput('Would you like to define some additional model associations?', array('y','n'), 'y');
+
+ while ((low($wannaDoMoreAssoc) == 'y' || low($wannaDoMoreAssoc) == 'yes')) {
+ $assocs = array(1=>'belongsTo', 2=>'hasOne', 3=>'hasMany', 4=>'hasAndBelongsToMany');
+ $bad = true;
+ while ($bad) {
+ $this->stdout('What is the association type?');
+ $prompt = "1- belongsTo\n";
+ $prompt .= "2- hasOne\n";
+ $prompt .= "3- hasMany\n";
+ $prompt .= "4- hasAndBelongsToMany\n";
+ $assocType = intval($this->getInput($prompt, null, null));
+
+ if (intval($assocType) < 1 || intval($assocType) > 4) {
+ $this->stdout('The selection you entered was invalid. Please enter a number between 1 and 4.');
+ } else {
+ $bad = false;
+ }
+ }
+ $this->stdout('For the following options be very careful to match your setup exactly. Any spelling mistakes will cause errors.');
+ $this->hr();
+ $associationName = $this->getInput('What is the name of this association?');
+ $className = $this->getInput('What className will '.$associationName.' use?', null, $associationName );
+ $suggestedForeignKey = null;
+ if ($assocType == '1') {
+ $showKeys = $possibleKeys[$useTable];
+ $suggestedForeignKey = $this->__modelKey($associationName);
+ } else {
+ $otherTable = Inflector::tableize($className);
+ if (in_array($otherTable, $this->__tables)) {
+ if ($assocType < '4') {
+ $showKeys = $possibleKeys[$otherTable];
+ } else {
+ $showKeys = null;
+ }
+ } else {
+ $otherTable = $this->getInput('What is the table for this class?');
+ $showKeys = $possibleKeys[$otherTable];
+ }
+ $suggestedForeignKey = $this->__modelKey($currentModelName);
+ }
+ if (!empty($showKeys)) {
+ $this->stdout('A helpful List of possible keys');
+ for ($i = 0; $i < count($showKeys); $i++) {
+ $this->stdout($i + 1 . ". " . $showKeys[$i]);
+ }
+ $foreignKey = $this->getInput('What is the foreignKey? Choose a number.');
+ if (intval($foreignKey) > 0 && intval($foreignKey) <= $i ) {
+ $foreignKey = $showKeys[intval($foreignKey) - 1];
+ }
+ }
+ if (!isset($foreignKey)) {
+ $foreignKey = $this->getInput('What is the foreignKey? Specify your own.', null, $suggestedForeignKey);
+ }
+ if ($assocType == '4') {
+ $associationForeignKey = $this->getInput('What is the associationForeignKey?', null, $this->__modelKey($currentModelName));
+ $joinTable = $this->getInput('What is the joinTable?');
+ }
+ $associations[$assocs[$assocType]] = array_values($associations[$assocs[$assocType]]);
+ $count = count($associations[$assocs[$assocType]]);
+ $i = ($count > 0) ? $count : 0;
+ $associations[$assocs[$assocType]][$i]['alias'] = $associationName;
+ $associations[$assocs[$assocType]][$i]['className'] = $className;
+ $associations[$assocs[$assocType]][$i]['foreignKey'] = $foreignKey;
+ if ($assocType == '4') {
+ $associations[$assocs[$assocType]][$i]['associationForeignKey'] = $associationForeignKey;
+ $associations[$assocs[$assocType]][$i]['joinTable'] = $joinTable;
+ }
+ $wannaDoMoreAssoc = $this->getInput('Define another association?', array('y','n'), 'y');
+ }
+ }
+ $this->stdout('');
+ $this->hr();
+ $this->stdout('The following model will be created:');
+ $this->hr();
+ $this->stdout("Model Name: $currentModelName");
+ $this->stdout("DB Connection: " . ($usingDefault ? 'default' : $useDbConfig));
+ $this->stdout("DB Table: " . $fullTableName);
+ if ($primaryKey != 'id') {
+ $this->stdout("Primary Key: " . $primaryKey);
+ }
+ $this->stdout("Validation: " . print_r($validate, true));
+
+ if (!empty($associations)) {
+ $this->stdout("Associations:");
+
+ if (count($associations['belongsTo'])) {
+ for ($i = 0; $i < count($associations['belongsTo']); $i++) {
+ $this->stdout(" $currentModelName belongsTo {$associations['belongsTo'][$i]['alias']}");
+ }
+ }
+
+ if (count($associations['hasOne'])) {
+ for ($i = 0; $i < count($associations['hasOne']); $i++) {
+ $this->stdout(" $currentModelName hasOne {$associations['hasOne'][$i]['alias']}");
+ }
+ }
+
+ if (count($associations['hasMany'])) {
+ for ($i = 0; $i < count($associations['hasMany']); $i++) {
+ $this->stdout(" $currentModelName hasMany {$associations['hasMany'][$i]['alias']}");
+ }
+ }
+
+ if (count($associations['hasAndBelongsToMany'])) {
+ for ($i = 0; $i < count($associations['hasAndBelongsToMany']); $i++) {
+ $this->stdout(" $currentModelName hasAndBelongsToMany {$associations['hasAndBelongsToMany'][$i]['alias']}");
+ }
+ }
+ }
+ $this->hr();
+ $looksGood = $this->getInput('Look okay?', array('y','n'), 'y');
+
+ if (low($looksGood) == 'y' || low($looksGood) == 'yes') {
+ if ($useTable == Inflector::tableize($currentModelName)) {
+ $useTable = null;
+ }
+ $this->bakeModel($currentModelName, $useDbConfig, $useTable, $primaryKey, $validate, $associations);
+
+ if ($this->doUnitTest()) {
+ $this->bakeUnitTest('model', $currentModelName);
+ }
+ } else {
+ $this->stdout('Bake Aborted.');
+ }
+ }
+/**
+ * Action to create a View.
+ *
+ */
+ function doView() {
+ $this->hr();
+ $this->stdout('View Bake:');
+ $this->hr();
+ $uses = array();
+ $wannaUseSession = 'y';
+ $wannaDoScaffold = 'y';
+
+
+ $useDbConfig = 'default';
+ $this->__doList($useDbConfig, 'Controllers');
+
+ $enteredController = '';
+
+ while ($enteredController == '') {
+ $enteredController = $this->getInput('Enter a number from the list above, or type in the name of another controller.');
+
+ if ($enteredController == '' || intval($enteredController) > count($this->__controllerNames)) {
+ $this->stdout('Error:');
+ $this->stdout("The Controller name you supplied was empty, or the number \nyou selected was not an option. Please try again.");
+ $enteredController = '';
+ }
+ }
+
+ if (intval($enteredController) > 0 && intval($enteredController) <= count($this->__controllerNames) ) {
+ $controllerName = $this->__controllerNames[intval($enteredController) - 1];
+ } else {
+ $controllerName = Inflector::camelize($enteredController);
+ }
+
+ $controllerPath = low(Inflector::underscore($controllerName));
+
+ $doItInteractive = $this->getInput("Would you like bake to build your views interactively?\nWarning: Choosing no will overwrite {$controllerClassName} views if it exist.", array('y','n'), 'y');
+
+ if (low($doItInteractive) == 'y' || low($doItInteractive) == 'yes') {
+ $this->interactive = true;
+ $wannaDoScaffold = $this->getInput("Would you like to create some scaffolded views (index, add, view, edit) for this controller?\nNOTE: Before doing so, you'll need to create your controller and model classes (including associated models).", array('y','n'), 'n');
+ }
+
+ $admin = null;
+ $admin_url = null;
+ if (low($wannaDoScaffold) == 'y' || low($wannaDoScaffold) == 'yes') {
+ $wannaDoAdmin = $this->getInput("Would you like to create the views for admin routing?", array('y','n'), 'n');
+ }
+
+ if ((low($wannaDoAdmin) == 'y' || low($wannaDoAdmin) == 'yes')) {
+ require(CONFIGS.'core.php');
+ if (defined('CAKE_ADMIN')) {
+ $admin = CAKE_ADMIN . '_';
+ $admin_url = '/'.CAKE_ADMIN;
+ } else {
+ $adminRoute = '';
+ $this->stdout('You need to enable CAKE_ADMIN in /app/config/core.php to use admin routing.');
+ $this->stdout('What would you like the admin route to be?');
+ $this->stdout('Example: www.example.com/admin/controller');
+ while ($adminRoute == '') {
+ $adminRoute = $this->getInput("What would you like the admin route to be?", null, 'admin');
+ }
+ if ($this->__addAdminRoute($adminRoute) !== true) {
+ $this->stdout('Unable to write to /app/config/core.php.');
+ $this->stdout('You need to enable CAKE_ADMIN in /app/config/core.php to use admin routing.');
+ exit();
+ } else {
+ $admin = $adminRoute . '_';
+ $admin_url = '/'.$adminRoute;
+ }
+ }
+ }
+ if (low($wannaDoScaffold) == 'y' || low($wannaDoScaffold) == 'yes') {
+ $file = CONTROLLERS . $controllerPath . '_controller.php';
+
+ if (!file_exists($file)) {
+ $shortPath = str_replace(ROOT, null, $file);
+ $shortPath = str_replace('../', '', $shortPath);
+ $shortPath = str_replace('//', '/', $shortPath);
+ $this->stdout('');
+ $this->stdout("The file '$shortPath' could not be found.\nIn order to scaffold, you'll need to first create the controller. ");
+ $this->stdout('');
+ die();
+ } else {
+ uses('controller'.DS.'controller');
+ loadController($controllerName);
+ if ($admin) {
+ $this->__bakeViews($controllerName, $controllerPath, $admin, $admin_url);
+ }
+ $this->__bakeViews($controllerName, $controllerPath, null, null);
+
+ $this->hr();
+ $this->stdout('');
+ $this->stdout('View Scaffolding Complete.'."\n");
+ }
+ } else {
+ $actionName = '';
+
+ while ($actionName == '') {
+ $actionName = $this->getInput('Action Name? (use camelCased function name)');
+
+ if ($actionName == '') {
+ $this->stdout('The action name you supplied was empty. Please try again.');
+ }
+ }
+ $this->stdout('');
+ $this->hr();
+ $this->stdout('The following view will be created:');
+ $this->hr();
+ $this->stdout("Controller Name: $controllerName");
+ $this->stdout("Action Name: $actionName");
+ $this->stdout("Path: app/views/" . $controllerPath . DS . Inflector::underscore($actionName) . '.thtml');
+ $this->hr();
+ $looksGood = $this->getInput('Look okay?', array('y','n'), 'y');
+
+ if (low($looksGood) == 'y' || low($looksGood) == 'yes') {
+ $this->bakeView($controllerName, $actionName);
+ } else {
+ $this->stdout('Bake Aborted.');
+ }
+ }
+ }
+
+ function __bakeViews($controllerName, $controllerPath, $admin= null, $admin_url = null) {
+ $controllerClassName = $controllerName.'Controller';
+ $controllerObj = & new $controllerClassName();
+
+ if (!in_array('Html', $controllerObj->helpers)) {
+ $controllerObj->helpers[] = 'Html';
+ }
+ if (!in_array('Form', $controllerObj->helpers)) {
+ $controllerObj->helpers[] = 'Form';
+ }
+
+ $controllerObj->constructClasses();
+ $currentModelName = $controllerObj->modelClass;
+ $this->__modelClass = $currentModelName;
+ $modelKey = Inflector::underscore($currentModelName);
+ $modelObj =& ClassRegistry::getObject($modelKey);
+ $singularName = $this->__singularName($currentModelName);
+ $pluralName = $this->__pluralName($currentModelName);
+ $singularHumanName = $this->__singularHumanName($currentModelName);
+ $pluralHumanName = $this->__pluralHumanName($controllerName);
+
+ $fieldNames = $controllerObj->generateFieldNames(null, false);
+ $indexView = null;
+
+ if (!empty($modelObj->alias)) {
+ foreach ($modelObj->alias as $key => $value) {
+ $alias[] = $key;
+ }
+ }
+ $indexView .= "<div class=\"{$pluralName}\">\n";
+ $indexView .= "<h2>List " . $pluralHumanName . "</h2>\n\n";
+ $indexView .= "<table cellpadding=\"0\" cellspacing=\"0\">\n";
+ $indexView .= "<tr>\n";
+
+ foreach ($fieldNames as $fieldName) {
+ $indexView .= "\t<th>".$fieldName['prompt']."</th>\n";
+ }
+ $indexView .= "\t<th>Actions</th>\n";
+ $indexView .= "</tr>\n";
+ $indexView .= "<?php foreach (\${$pluralName} as \${$singularName}): ?>\n";
+ $indexView .= "<tr>\n";
+ $count = 0;
+ foreach ($fieldNames as $field => $value) {
+ if (isset($value['foreignKey'])) {
+ $otherModelName = $this->__modelName($value['model']);
+ $otherModelKey = Inflector::underscore($otherModelName);
+ $otherModelObj =& ClassRegistry::getObject($otherModelKey);
+ $otherControllerName = $this->__controllerName($otherModelName);
+ $otherControllerPath = $this->__controllerPath($otherControllerName);
+ if (is_object($otherModelObj)) {
+ $displayField = $otherModelObj->getDisplayField();
+ $indexView .= "\t<td>&nbsp;<?php echo \$html->link(\$".$singularName."['{$alias[$count]}']['{$displayField}'], '{$admin_url}/" . $otherControllerPath . "/view/' .\$".$singularName."['{$alias[$count]}']['{$otherModelObj->primaryKey}'])?></td>\n";
+ } else {
+ $indexView .= "\t<td><?php echo \$".$singularName."['{$modelObj->name}']['{$field}']; ?></td>\n";
+ }
+ $count++;
+ } else {
+ $indexView .= "\t<td><?php echo \$".$singularName."['{$modelObj->name}']['{$field}']; ?></td>\n";
+ }
+ }
+ $indexView .= "\t<td class=\"actions\">\n";
+ $indexView .= "\t\t<?php echo \$html->link('View','{$admin_url}/{$controllerPath}/view/' . \$".$singularName."['{$modelObj->name}']['{$modelObj->primaryKey}'])?>\n";
+ $indexView .= "\t\t<?php echo \$html->link('Edit','{$admin_url}/{$controllerPath}/edit/' . \$".$singularName."['{$modelObj->name}']['{$modelObj->primaryKey}'])?>\n";
+ $indexView .= "\t\t<?php echo \$html->link('Delete','{$admin_url}/{$controllerPath}/delete/' . \$".$singularName."['{$modelObj->name}']['{$modelObj->primaryKey}'], null, 'Are you sure you want to delete id ' . \$".$singularName."['{$modelObj->name}']['{$modelObj->primaryKey}'])?>\n";
+ $indexView .= "\t</td>\n";
+ $indexView .= "</tr>\n";
+ $indexView .= "<?php endforeach; ?>\n";
+ $indexView .= "</table>\n\n";
+ $indexView .= "<ul class=\"actions\">\n";
+ $indexView .= "\t<li><?php echo \$html->link('New {$singularHumanName}', '{$admin_url}/{$controllerPath}/add'); ?></li>\n";
+ $indexView .= "</ul>\n";
+ $indexView .= "</div>";
+ $viewView = null;
+ $viewView .= "<div class=\"{$singularName}\">\n";
+ $viewView .= "<h2>View " . $singularHumanName . "</h2>\n\n";
+ $viewView .= "<dl>\n";
+ $count = 0;
+ foreach ($fieldNames as $field => $value) {
+ $viewView .= "\t<dt>" . $value['prompt'] . "</dt>\n";
+ if (isset($value['foreignKey'])) {
+ $otherModelName = $this->__modelName($value['model']);
+ $otherModelKey = Inflector::underscore($otherModelName);
+ $otherModelObj =& ClassRegistry::getObject($otherModelKey);
+ $otherControllerName = $this->__controllerName($otherModelName);
+ $otherControllerPath = $this->__controllerPath($otherControllerName);
+ $displayField = $otherModelObj->getDisplayField();
+ $viewView .= "\t<dd>&nbsp;<?php echo \$html->link(\$".$singularName."['{$alias[$count]}']['{$displayField}'], '{$admin_url}/" . $otherControllerPath . "/view/' .\$".$singularName."['{$alias[$count]}']['{$otherModelObj->primaryKey}'])?></dd>\n";
+ $count++;
+ } else {
+ $viewView .= "\t<dd>&nbsp;<?php echo \$".$singularName."['{$modelObj->name}']['{$field}']?></dd>\n";
+ }
+ }
+ $viewView .= "</dl>\n";
+ $viewView .= "<ul class=\"actions\">\n";
+ $viewView .= "\t<li><?php echo \$html->link('Edit " . $singularHumanName . "', '{$admin_url}/{$controllerPath}/edit/' . \$".$singularName."['{$modelObj->name}']['{$modelObj->primaryKey}']) ?> </li>\n";
+ $viewView .= "\t<li><?php echo \$html->link('Delete " . $singularHumanName . "', '{$admin_url}/{$controllerPath}/delete/' . \$".$singularName."['{$modelObj->name}']['{$modelObj->primaryKey}'], null, 'Are you sure you want to delete: id ' . \$".$singularName."['{$modelObj->name}']['{$modelObj->primaryKey}'] . '?') ?> </li>\n";
+ $viewView .= "\t<li><?php echo \$html->link('List " . $pluralHumanName ."', '{$admin_url}/{$controllerPath}/index') ?> </li>\n";
+ $viewView .= "\t<li><?php echo \$html->link('New " . $singularHumanName . "', '{$admin_url}/{$controllerPath}/add') ?> </li>\n";
+ foreach ( $fieldNames as $field => $value ) {
+ if ( isset( $value['foreignKey'] ) ) {
+ $otherModelName = $this->__modelName($value['model']);
+ if ($otherModelName != $currentModelName) {
+ $otherControllerName = $this->__controllerName($otherModelName);
+ $otherControllerPath = $this->__controllerPath($otherControllerName);
+ $otherSingularHumanName = $this->__singularHumanName($value['controller']);
+ $otherPluralHumanName = $this->__pluralHumanName($value['controller']);
+ $viewView .= "\t<li><?php echo \$html->link('List " . $otherSingularHumanName . "', '{$admin_url}/" . $otherControllerPath . "/index/')?> </li>\n";
+ $viewView .= "\t<li><?php echo \$html->link('New " . $otherPluralHumanName . "', '{$admin_url}/" . $otherControllerPath . "/add/')?> </li>\n";
+ }
+ }
+ }
+ $viewView .= "</ul>\n\n";
+
+ $viewView .= "</div>\n";
+
+
+ foreach ($modelObj->hasOne as $associationName => $relation) {
+ $new = true;
+
+ $otherModelName = $this->__modelName($relation['className']);
+ $otherControllerName = $this->__controllerName($otherModelName);
+ $otherControllerPath = $this->__controllerPath($otherControllerName);
+ $otherSingularName = $this->__singularName($associationName);
+ $otherPluralHumanName = $this->__pluralHumanName($associationName);
+ $otherSingularHumanName = $this->__singularHumanName($associationName);
+
+ $viewView .= "<div class=\"related\">\n";
+ $viewView .= "<h3>Related " . $otherPluralHumanName . "</h3>\n";
+ $viewView .= "<?php if (!empty(\$".$singularName."['{$associationName}'])): ?>\n";
+ $viewView .= "<dl>\n";
+ $viewView .= "\t<?php foreach (\$".$singularName."['{$associationName}'] as \$field => \$value): ?>\n";
+ $viewView .= "\t\t<dt><?php echo \$field ?></dt>\n";
+ $viewView .= "\t\t<dd>&nbsp;<?php echo \$value ?></dd>\n";
+ $viewView .= "\t<?php endforeach; ?>\n";
+ $viewView .= "</dl>\n";
+ $viewView .= "<?php endif; ?>\n";
+ $viewView .= "<ul class=\"actions\">\n";
+ $viewView .= "\t<li><?php echo \$html->link('Edit " . $otherSingularHumanName . "', '{$admin_url}/" .$otherControllerPath."/edit/' . \$".$singularName."['{$associationName}']['" . $modelObj->{$otherModelName}->primaryKey . "']);?></li>\n";
+ $viewView .= "\t<li><?php echo \$html->link('New " . $otherSingularHumanName . "', '{$admin_url}/" .$otherControllerPath."/add/');?> </li>\n";
+ $viewView .= "</ul>\n";
+ $viewView .= "</div>\n";
+ }
+ $relations = array_merge($modelObj->hasMany, $modelObj->hasAndBelongsToMany);
+
+ foreach ($relations as $associationName => $relation) {
+ $otherModelName = $this->__modelName($relation['className']);
+ $otherControllerName = $this->__controllerName($otherModelName);
+ $otherControllerPath = $this->__controllerPath($otherControllerName);
+ $otherSingularName = $this->__singularName($associationName);
+ $otherPluralHumanName = $this->__pluralHumanName($associationName);
+ $otherSingularHumanName = $this->__singularHumanName($associationName);
+ $otherModelKey = Inflector::underscore($otherModelName);
+ $otherModelObj =& ClassRegistry::getObject($otherModelKey);
+
+ $viewView .= "<div class=\"related\">\n";
+ $viewView .= "<h3>Related " . $otherPluralHumanName . "</h3>\n";
+ $viewView .= "<?php if (!empty(\$".$singularName."['{$associationName}'])):?>\n";
+ $viewView .= "<table cellpadding=\"0\" cellspacing=\"0\">\n";
+ $viewView .= "<tr>\n";
+ $viewView .= "<?php foreach (\$".$singularName."['{$associationName}']['0'] as \$column => \$value): ?>\n";
+ $viewView .= "<th><?php echo \$column?></th>\n";
+ $viewView .= "<?php endforeach; ?>\n";
+ $viewView .= "<th>Actions</th>\n";
+ $viewView .= "</tr>\n";
+ $viewView .= "<?php foreach (\$".$singularName."['{$associationName}'] as \$".$otherSingularName."):?>\n";
+ $viewView .= "<tr>\n";
+ $viewView .= "\t<?php foreach (\$".$otherSingularName." as \$column => \$value):?>\n";
+ $viewView .= "\t\t<td><?php echo \$value;?></td>\n";
+ $viewView .= "\t<?php endforeach;?>\n";
+ $viewView .= "\t<td class=\"actions\">\n";
+ $viewView .= "\t\t<?php echo \$html->link('View', '{$admin_url}/" . $otherControllerPath . "/view/' . \$".$otherSingularName."['{$otherModelObj->primaryKey}']);?>\n";
+ $viewView .= "\t\t<?php echo \$html->link('Edit', '{$admin_url}/" . $otherControllerPath . "/edit/' . \$".$otherSingularName."['{$otherModelObj->primaryKey}']);?>\n";
+ $viewView .= "\t\t<?php echo \$html->link('Delete', '{$admin_url}/" . $otherControllerPath . "/delete/' . \$".$otherSingularName."['{$otherModelObj->primaryKey}'], null, 'Are you sure you want to delete: id ' . \$".$otherSingularName."['{$otherModelObj->primaryKey}'] . '?');?>\n";
+ $viewView .= "\t</td>\n";
+ $viewView .= "</tr>\n";
+ $viewView .= "<?php endforeach; ?>\n";
+ $viewView .= "</table>\n";
+ $viewView .= "<?php endif; ?>\n\n";
+ $viewView .= "<ul class=\"actions\">\n";
+ $viewView .= "\t<li><?php echo \$html->link('New " . $otherSingularHumanName . "', '{$admin_url}/" .$otherControllerPath."/add/');?> </li>\n";
+ $viewView .= "</ul>\n";
+
+ $viewView .= "</div>\n";
+ }
+ $addView = null;
+ $addView .= "<h2>New " . $singularHumanName . "</h2>\n";
+ $addView .= "<form action=\"<?php echo \$html->url('{$admin_url}/{$controllerPath}/add'); ?>\" method=\"post\">\n";
+ $addView .= $this->generateFields($controllerObj->generateFieldNames(null, true));
+ $addView .= $this->generateSubmitDiv('Add');
+ $addView .= "</form>\n";
+ $addView .= "<ul class=\"actions\">\n";
+ $addView .= "<li><?php echo \$html->link('List {$pluralHumanName}', '{$admin_url}/{$controllerPath}/index')?></li>\n";
+ foreach ($modelObj->belongsTo as $associationName => $relation) {
+ $otherModelName = $this->__modelName($associationName);
+ if ($otherModelName != $currentModelName) {
+ $otherControllerName = $this->__controllerName($otherModelName);
+ $otherControllerPath = $this->__controllerPath($otherControllerName);
+ $otherSingularName = $this->__singularName($associationName);
+ $otherPluralName = $this->__pluralHumanName($associationName);
+ $addView .= "<li><?php echo \$html->link('View " . $otherPluralName . "', '{$admin_url}/" .$otherControllerPath."/index/');?></li>\n";
+ $addView .= "<li><?php echo \$html->link('Add " . $otherPluralName . "', '{$admin_url}/" .$otherControllerPath."/add/');?></li>\n";
+ }
+ }
+ $addView .= "</ul>\n";
+ $editView = null;
+ $editView .= "<h2>Edit " . $singularHumanName . "</h2>\n";
+ $editView .= "<form action=\"<?php echo \$html->url('{$admin_url}/{$controllerPath}/edit/'.\$html->tagValue('{$modelObj->name}/{$modelObj->primaryKey}')); ?>\" method=\"post\">\n";
+ $editView .= $this->generateFields($controllerObj->generateFieldNames(null, true));
+ $editView .= "<?php echo \$html->hidden('{$modelObj->name}/{$modelObj->primaryKey}')?>\n";
+ $editView .= $this->generateSubmitDiv('Save');
+ $editView .= "</form>\n";
+ $editView .= "<ul class=\"actions\">\n";
+ $editView .= "<li><?php echo \$html->link('Delete','{$admin_url}/{$controllerPath}/delete/' . \$html->tagValue('{$modelObj->name}/{$modelObj->primaryKey}'), null, 'Are you sure you want to delete: id ' . \$html->tagValue('{$modelObj->name}/{$modelObj->primaryKey}'));?>\n";
+ $editView .= "<li><?php echo \$html->link('List {$pluralHumanName}', '{$admin_url}/{$controllerPath}/index')?></li>\n";
+ foreach ($modelObj->belongsTo as $associationName => $relation) {
+ $otherModelName = $this->__modelName($associationName);
+ if ($otherModelName != $currentModelName) {
+ $otherControllerName = $this->__controllerName($otherModelName);
+ $otherControllerPath = $this->__controllerPath($otherControllerName);
+ $otherSingularName = $this->__singularName($associationName);
+ $otherPluralName = $this->__pluralHumanName($associationName);
+ $editView .= "<li><?php echo \$html->link('View " . $otherPluralName . "', '{$admin_url}/" .$otherControllerPath."/index/');?></li>\n";
+ $editView .= "<li><?php echo \$html->link('Add " . $otherPluralName . "', '{$admin_url}/" .$otherControllerPath."/add/');?></li>\n";
+ }
+ }
+ $editView .= "</ul>\n";
+
+ if (!file_exists(VIEWS.$controllerPath)) {
+ mkdir(VIEWS.$controllerPath);
+ }
+ $filename = VIEWS . $controllerPath . DS . $admin . 'index.thtml';
+ $this->__createFile($filename, $indexView);
+ $filename = VIEWS . $controllerPath . DS . $admin . 'view.thtml';
+ $this->__createFile($filename, $viewView);
+ $filename = VIEWS . $controllerPath . DS . $admin . 'add.thtml';
+ $this->__createFile($filename, $addView);
+ $filename = VIEWS . $controllerPath . DS . $admin . 'edit.thtml';
+ $this->__createFile($filename, $editView);
+ }
+/**
+ * Action to create a Controller.
+ *
+ */
+ function doController() {
+ $this->hr();
+ $this->stdout('Controller Bake:');
+ $this->hr();
+ $uses = array();
+ $helpers = array();
+ $components = array();
+ $wannaUseSession = 'y';
+ $wannaDoScaffolding = 'y';
+
+ $useDbConfig = 'default';
+ $this->__doList($useDbConfig, 'Controllers');
+
+ $enteredController = '';
+
+ while ($enteredController == '') {
+ $enteredController = $this->getInput('Enter a number from the list above, or type in the name of another controller.');
+
+ if ($enteredController == '' || intval($enteredController) > count($this->__controllerNames)) {
+ $this->stdout('Error:');
+ $this->stdout("The Controller name you supplied was empty, or the number \nyou selected was not an option. Please try again.");
+ $enteredController = '';
+ }
+ }
+
+ if (intval($enteredController) > 0 && intval($enteredController) <= count($this->__controllerNames) ) {
+ $controllerName = $this->__controllerNames[intval($enteredController) - 1];
+ } else {
+ $controllerName = Inflector::camelize($enteredController);
+ }
+
+ $controllerPath = low(Inflector::underscore($controllerName));
+
+ $doItInteractive = $this->getInput("Would you like bake to build your controller interactively?\nWarning: Choosing no will overwrite {$controllerClassName} controller if it exist.", array('y','n'), 'y');
+
+ if (low($doItInteractive) == 'y' || low($doItInteractive) == 'yes') {
+ $this->interactive = true;
+
+ $wannaUseScaffold = $this->getInput("Would you like to use scaffolding?", array('y','n'), 'y');
+
+ if (low($wannaUseScaffold) == 'n' || low($wannaUseScaffold) == 'no') {
+
+ $wannaDoScaffolding = $this->getInput("Would you like to include some basic class methods (index(), add(), view(), edit())?", array('y','n'), 'n');
+
+ if (low($wannaDoScaffolding) == 'y' || low($wannaDoScaffolding) == 'yes') {
+ $wannaDoAdmin = $this->getInput("Would you like to create the methods for admin routing?", array('y','n'), 'n');
+ }
+
+ $wannaDoUses = $this->getInput("Would you like this controller to use other models besides '" . $this->__modelName($controllerName) . "'?", array('y','n'), 'n');
+
+ if (low($wannaDoUses) == 'y' || low($wannaDoUses) == 'yes') {
+ $usesList = $this->getInput("Please provide a comma separated list of the classnames of other models you'd like to use.\nExample: 'Author, Article, Book'");
+ $usesListTrimmed = str_replace(' ', '', $usesList);
+ $uses = explode(',', $usesListTrimmed);
+ }
+ $wannaDoHelpers = $this->getInput("Would you like this controller to use other helpers besides HtmlHelper and FormHelper?", array('y','n'), 'n');
+
+ if (low($wannaDoHelpers) == 'y' || low($wannaDoHelpers) == 'yes') {
+ $helpersList = $this->getInput("Please provide a comma separated list of the other helper names you'd like to use.\nExample: 'Ajax, Javascript, Time'");
+ $helpersListTrimmed = str_replace(' ', '', $helpersList);
+ $helpers = explode(',', $helpersListTrimmed);
+ }
+ $wannaDoComponents = $this->getInput("Would you like this controller to use any components?", array('y','n'), 'n');
+
+ if (low($wannaDoComponents) == 'y' || low($wannaDoComponents) == 'yes') {
+ $componentsList = $this->getInput("Please provide a comma separated list of the component names you'd like to use.\nExample: 'Acl, MyNiftyHelper'");
+ $componentsListTrimmed = str_replace(' ', '', $componentsList);
+ $components = explode(',', $componentsListTrimmed);
+ }
+
+ $wannaUseSession = $this->getInput("Would you like to use Sessions?", array('y','n'), 'y');
+ } else {
+ $wannaDoScaffolding = 'n';
+ }
+ } else {
+ $wannaDoScaffolding = $this->getInput("Would you like to include some basic class methods (index(), add(), view(), edit())?", array('y','n'), 'y');
+
+ if (low($wannaDoScaffolding) == 'y' || low($wannaDoScaffolding) == 'yes') {
+ $wannaDoAdmin = $this->getInput("Would you like to create the methods for admin routing?", array('y','n'), 'y');
+ }
+ }
+
+ $admin = null;
+ $admin_url = null;
+ if ((low($wannaDoAdmin) == 'y' || low($wannaDoAdmin) == 'yes')) {
+ require(CONFIGS.'core.php');
+ if (defined('CAKE_ADMIN')) {
+ $admin = CAKE_ADMIN.'_';
+ $admin_url = '/'.CAKE_ADMIN;
+ } else {
+ $adminRoute = '';
+ $this->stdout('You need to enable CAKE_ADMIN in /app/config/core.php to use admin routing.');
+ $this->stdout('What would you like the admin route to be?');
+ $this->stdout('Example: www.example.com/admin/controller');
+ while ($adminRoute == '') {
+ $adminRoute = $this->getInput("What would you like the admin route to be?", null, 'admin');
+ }
+ if ($this->__addAdminRoute($adminRoute) !== true) {
+ $this->stdout('Unable to write to /app/config/core.php.');
+ $this->stdout('You need to enable CAKE_ADMIN in /app/config/core.php to use admin routing.');
+ exit();
+ } else {
+ $admin = $adminRoute . '_';
+ $admin_url = '/'.$adminRoute;
+ }
+ }
+ }
+
+ if (low($wannaDoScaffolding) == 'y' || low($wannaDoScaffolding) == 'yes') {
+ $actions = $this->__bakeActions($controllerName, null, null, $wannaUseSession);
+ if ($admin) {
+ $actions .= $this->__bakeActions($controllerName, $admin, $admin_url, $wannaUseSession);
+ }
+ }
+
+ if ($this->interactive === true) {
+ $this->stdout('');
+ $this->hr();
+ $this->stdout('The following controller will be created:');
+ $this->hr();
+ $this->stdout("Controller Name: $controllerName");
+ if (low($wannaUseScaffold) == 'y' || low($wannaUseScaffold) == 'yes') {
+ $this->stdout(" var \$scaffold;");
+ }
+ if (count($uses)) {
+ $this->stdout("Uses: ", false);
+
+ foreach ($uses as $use) {
+ if ($use != $uses[count($uses) - 1]) {
+ $this->stdout(ucfirst($use) . ", ", false);
+ } else {
+ $this->stdout(ucfirst($use));
+ }
+ }
+ }
+
+ if (count($helpers)) {
+ $this->stdout("Helpers: ", false);
+
+ foreach ($helpers as $help) {
+ if ($help != $helpers[count($helpers) - 1]) {
+ $this->stdout(ucfirst($help) . ", ", false);
+ } else {
+ $this->stdout(ucfirst($help));
+ }
+ }
+ }
+
+ if (count($components)) {
+ $this->stdout("Components: ", false);
+
+ foreach ($components as $comp) {
+ if ($comp != $components[count($components) - 1]) {
+ $this->stdout(ucfirst($comp) . ", ", false);
+ } else {
+ $this->stdout(ucfirst($comp));
+ }
+ }
+ }
+ $this->hr();
+ $looksGood = $this->getInput('Look okay?', array('y','n'), 'y');
+
+ if (low($looksGood) == 'y' || low($looksGood) == 'yes') {
+ $this->bakeController($controllerName, $uses, $helpers, $components, $actions, $wannaUseScaffold);
+
+ if ($this->doUnitTest()) {
+ $this->bakeUnitTest('controller', $controllerName);
+ }
+ } else {
+ $this->stdout('Bake Aborted.');
+ }
+ } else {
+ $this->bakeController($controllerName, $uses, $helpers, $components, $actions, $wannaUseScaffold);
+ if ($this->doUnitTest()) {
+ $this->bakeUnitTest('controller', $controllerName);
+ }
+ exit();
+ }
+ }
+
+ function __bakeActions($controllerName, $admin = null, $admin_url = null, $wannaUseSession = 'y') {
+ $currentModelName = $this->__modelName($controllerName);
+ loadModel($currentModelName);
+ $modelObj =& new $currentModelName();
+ $controllerPath = $this->__controllerPath($controllerName);
+ $pluralName = $this->__pluralName($currentModelName);
+ $singularName = $this->__singularName($currentModelName);
+ $singularHumanName = $this->__singularHumanName($currentModelName);
+ $pluralHumanName = $this->__pluralHumanName($controllerName);
+ if (!class_exists($currentModelName)) {
+ $this->stdout('You must have a model for this class to build scaffold methods. Please try again.');
+ exit;
+ }
+ $actions .= "\n";
+ $actions .= "\tfunction {$admin}index() {\n";
+ $actions .= "\t\t\$this->{$currentModelName}->recursive = 0;\n";
+ $actions .= "\t\t\$this->set('{$pluralName}', \$this->{$currentModelName}->findAll());\n";
+ $actions .= "\t}\n";
+ $actions .= "\n";
+ $actions .= "\tfunction {$admin}view(\$id = null) {\n";
+ $actions .= "\t\tif (!\$id) {\n";
+ if (low($wannaUseSession) == 'y' || low($wannaUseSession) == 'yes') {
+ $actions .= "\t\t\t\$this->Session->setFlash('Invalid id for {$singularHumanName}.');\n";
+ $actions .= "\t\t\t\$this->redirect('{$admin_url}/{$controllerPath}/index');\n";
+ } else {
+ $actions .= "\t\t\t\$this->flash('Invalid id for {$singularHumanName}', '{$admin_url}/{$controllerPath}/index');\n";
+ }
+ $actions .= "\t\t}\n";
+ $actions .= "\t\t\$this->set('".$singularName."', \$this->{$currentModelName}->read(null, \$id));\n";
+ $actions .= "\t}\n";
+ $actions .= "\n";
+ $actions .= "\tfunction {$admin}add() {\n";
+ $actions .= "\t\tif (empty(\$this->data)) {\n";
+
+ foreach ($modelObj->hasAndBelongsToMany as $associationName => $relation) {
+ if (!empty($associationName)) {
+ $otherModelName = $this->__modelName($associationName);
+ $otherSingularName = $this->__singularName($associationName);
+ $otherPluralName = $this->__pluralName($associationName);
+ $selectedOtherPluralName = 'selected' . ucfirst($otherPluralName);
+ $actions .= "\t\t\t\$this->set('{$otherPluralName}', \$this->{$currentModelName}->{$otherModelName}->generateList());\n";
+ $actions .= "\t\t\t\$this->set('{$selectedOtherPluralName}', null);\n";
+ }
+ }
+ foreach ($modelObj->belongsTo as $associationName => $relation) {
+ if (!empty($associationName)) {
+ $otherModelName = $this->__modelName($associationName);
+ $otherSingularName = $this->__singularName($associationName);
+ $otherPluralName = $this->__pluralName($associationName);
+ $actions .= "\t\t\t\$this->set('{$otherPluralName}', \$this->{$currentModelName}->{$otherModelName}->generateList());\n";
+ }
+ }
+ $actions .= "\t\t\t\$this->render();\n";
+ $actions .= "\t\t} else {\n";
+ $actions .= "\t\t\t\$this->cleanUpFields();\n";
+ $actions .= "\t\t\tif (\$this->{$currentModelName}->save(\$this->data)) {\n";
+ if (low($wannaUseSession) == 'y' || low($wannaUseSession) == 'yes') {
+ $actions .= "\t\t\t\t\$this->Session->setFlash('The ".$this->__singularHumanName($currentModelName)." has been saved');\n";
+ $actions .= "\t\t\t\t\$this->redirect('{$admin_url}/{$controllerPath}/index');\n";
+ } else {
+ $actions .= "\t\t\t\t\$this->flash('{$currentModelName} saved.', '{$admin_url}/{$controllerPath}/index');\n";
+ }
+ $actions .= "\t\t\t} else {\n";
+ if (low($wannaUseSession) == 'y' || low($wannaUseSession) == 'yes') {
+ $actions .= "\t\t\t\t\$this->Session->setFlash('Please correct errors below.');\n";
+ }
+
+ foreach ($modelObj->hasAndBelongsToMany as $associationName => $relation) {
+ if (!empty($associationName)) {
+ $otherModelName = $this->__modelName($associationName);
+ $otherSingularName = $this->__singularName($associationName);
+ $otherPluralName = $this->__pluralName($associationName);
+ $selectedOtherPluralName = 'selected' . ucfirst($otherPluralName);
+ $actions .= "\t\t\t\t\$this->set('{$otherPluralName}', \$this->{$currentModelName}->{$otherModelName}->generateList());\n";
+ $actions .= "\t\t\t\tif (empty(\$this->data['{$associationName}']['{$associationName}'])) { \$this->data['{$associationName}']['{$associationName}'] = null; }\n";
+ $actions .= "\t\t\t\t\$this->set('{$selectedOtherPluralName}', \$this->data['{$associationName}']['{$associationName}']);\n";
+ }
+ }
+ foreach ($modelObj->belongsTo as $associationName => $relation) {
+ if (!empty($associationName)) {
+ $otherModelName = $this->__modelName($associationName);
+ $otherSingularName = $this->__singularName($associationName);
+ $otherPluralName = $this->__pluralName($associationName);
+ $actions .= "\t\t\t\t\$this->set('{$otherPluralName}', \$this->{$currentModelName}->{$otherModelName}->generateList());\n";
+ }
+ }
+ $actions .= "\t\t\t}\n";
+ $actions .= "\t\t}\n";
+ $actions .= "\t}\n";
+ $actions .= "\n";
+ $actions .= "\tfunction {$admin}edit(\$id = null) {\n";
+ $actions .= "\t\tif (empty(\$this->data)) {\n";
+ $actions .= "\t\t\tif (!\$id) {\n";
+ if (low($wannaUseSession) == 'y' || low($wannaUseSession) == 'yes') {
+ $actions .= "\t\t\t\t\$this->Session->setFlash('Invalid id for {$singularHumanName}');\n";
+ $actions .= "\t\t\t\t\$this->redirect('{$admin_url}/{$controllerPath}/index');\n";
+ } else {
+ $actions .= "\t\t\t\t\$this->flash('Invalid id for {$singularHumanName}', '{$admin_url}/{$controllerPath}/index');\n";
+ }
+ $actions .= "\t\t\t}\n";
+ $actions .= "\t\t\t\$this->data = \$this->{$currentModelName}->read(null, \$id);\n";
+
+ foreach ($modelObj->hasAndBelongsToMany as $associationName => $relation) {
+ if (!empty($associationName)) {
+ $otherModelName = $this->__modelName($associationName);
+ $otherSingularName = $this->__singularName($associationName);
+ $otherPluralName = $this->__pluralName($associationName);
+ $otherModelKey = Inflector::underscore($otherModelName);
+ $otherModelObj =& ClassRegistry::getObject($otherModelKey);
+ $selectedOtherPluralName = 'selected' . ucfirst($otherPluralName);
+ $actions .= "\t\t\t\$this->set('{$otherPluralName}', \$this->{$currentModelName}->{$otherModelName}->generateList());\n";
+ $actions .= "\t\t\tif (empty(\$this->data['{$associationName}'])) { \$this->data['{$associationName}'] = null; }\n";
+ $actions .= "\t\t\t\$this->set('{$selectedOtherPluralName}', \$this->_selectedArray(\$this->data['{$associationName}']));\n";
+ }
+ }
+ foreach ($modelObj->belongsTo as $associationName => $relation) {
+ if (!empty($associationName)) {
+ $otherModelName = $this->__modelName($associationName);
+ $otherSingularName = $this->__singularName($associationName);
+ $otherPluralName = $this->__pluralName($associationName);
+ $actions .= "\t\t\t\$this->set('{$otherPluralName}', \$this->{$currentModelName}->{$otherModelName}->generateList());\n";
+ }
+ }
+ $actions .= "\t\t} else {\n";
+ $actions .= "\t\t\t\$this->cleanUpFields();\n";
+ $actions .= "\t\t\tif (\$this->{$currentModelName}->save(\$this->data)) {\n";
+ if (low($wannaUseSession) == 'y' || low($wannaUseSession) == 'yes') {
+ $actions .= "\t\t\t\t\$this->Session->setFlash('The ".Inflector::humanize($currentModelName)." has been saved');\n";
+ $actions .= "\t\t\t\t\$this->redirect('{$admin_url}/{$controllerPath}/index');\n";
+ } else {
+ $actions .= "\t\t\t\t\$this->flash('{$currentModelName} saved.', '{$admin_url}/{$controllerPath}/index');\n";
+ }
+ $actions .= "\t\t\t} else {\n";
+ if (low($wannaUseSession) == 'y' || low($wannaUseSession) == 'yes') {
+ $actions .= "\t\t\t\t\$this->Session->setFlash('Please correct errors below.');\n";
+ }
+
+ foreach ($modelObj->hasAndBelongsToMany as $associationName => $relation) {
+ if (!empty($associationName)) {
+ $otherModelName = $this->__modelName($associationName);
+ $otherSingularName = $this->__singularName($associationName);
+ $otherPluralName = $this->__pluralName($associationName);
+ $selectedOtherPluralName = 'selected' . ucfirst($otherPluralName);
+ $actions .= "\t\t\t\t\$this->set('{$otherPluralName}', \$this->{$currentModelName}->{$otherModelName}->generateList());\n";
+ $actions .= "\t\t\t\tif (empty(\$this->data['{$associationName}']['{$associationName}'])) { \$this->data['{$associationName}']['{$associationName}'] = null; }\n";
+ $actions .= "\t\t\t\t\$this->set('{$selectedOtherPluralName}', \$this->data['{$associationName}']['{$associationName}']);\n";
+ }
+ }
+ foreach ($modelObj->belongsTo as $associationName => $relation) {
+ if (!empty($associationName)) {
+ $otherModelName = $this->__modelName($associationName);
+ $otherSingularName = $this->__singularName($associationName);
+ $otherPluralName = $this->__pluralName($associationName);
+ $actions .= "\t\t\t\t\$this->set('{$otherPluralName}', \$this->{$currentModelName}->{$otherModelName}->generateList());\n";
+ }
+ }
+ $actions .= "\t\t\t}\n";
+ $actions .= "\t\t}\n";
+ $actions .= "\t}\n";
+ $actions .= "\n";
+ $actions .= "\tfunction {$admin}delete(\$id = null) {\n";
+ $actions .= "\t\tif (!\$id) {\n";
+ if (low($wannaUseSession) == 'y' || low($wannaUseSession) == 'yes') {
+ $actions .= "\t\t\t\$this->Session->setFlash('Invalid id for {$singularHumanName}');\n";
+ $actions .= "\t\t\t\$this->redirect('{$admin_url}/{$controllerPath}/index');\n";
+ } else {
+ $actions .= "\t\t\t\$this->flash('Invalid id for {$singularHumanName}', '{$admin_url}/{$controllerPath}/index');\n";
+ }
+ $actions .= "\t\t}\n";
+ $actions .= "\t\tif (\$this->{$currentModelName}->del(\$id)) {\n";
+ if (low($wannaUseSession) == 'y' || low($wannaUseSession) == 'yes') {
+ $actions .= "\t\t\t\$this->Session->setFlash('The ".$this->__singularHumanName($currentModelName)." deleted: id '.\$id.'');\n";
+ $actions .= "\t\t\t\$this->redirect('{$admin_url}/{$controllerPath}/index');\n";
+ } else {
+ $actions .= "\t\t\t\$this->flash('{$currentModelName} deleted: id '.\$id.'.', '{$admin_url}/{$controllerPath}/index');\n";
+ }
+ $actions .= "\t\t}\n";
+ $actions .= "\t}\n";
+ $actions .= "\n";
+ return $actions;
+ }
+/**
+ * Action to create a Unit Test.
+ *
+ * @return Success
+ */
+ function doUnitTest() {
+ if (is_dir(VENDORS.'simpletest') || is_dir(ROOT.DS.APP_DIR.DS.'vendors'.DS.'simpletest')) {
+ return true;
+ }
+ $unitTest = $this->getInput('Cake test suite not installed. Do you want to bake unit test files anyway?', array('y','n'), 'y');
+ $result = low($unitTest) == 'y' || low($unitTest) == 'yes';
+
+ if ($result) {
+ $this->stdout("\nYou can download the Cake test suite from http://cakeforge.org/projects/testsuite/", true);
+ }
+ return $result;
+ }
+/**
+ * Creates a database configuration file for Bake.
+ *
+ * @param string $host
+ * @param string $login
+ * @param string $password
+ * @param string $database
+ */
+ function bakeDbConfig( $driver, $connect, $host, $login, $password, $database, $prefix) {
+ $out = "<?php\n";
+ $out .= "class DATABASE_CONFIG {\n\n";
+ $out .= "\tvar \$default = array(\n";
+ $out .= "\t\t'driver' => '{$driver}',\n";
+ $out .= "\t\t'connect' => '{$connect}',\n";
+ $out .= "\t\t'host' => '{$host}',\n";
+ $out .= "\t\t'login' => '{$login}',\n";
+ $out .= "\t\t'password' => '{$password}',\n";
+ $out .= "\t\t'database' => '{$database}', \n";
+ $out .= "\t\t'prefix' => '{$prefix}' \n";
+ $out .= "\t);\n";
+ $out .= "}\n";
+ $out .= "?>";
+ $filename = CONFIGS.'database.php';
+ $this->__createFile($filename, $out);
+ }
+/**
+ * Assembles and writes a Model file.
+ *
+ * @param string $name
+ * @param object $useDbConfig
+ * @param string $useTable
+ * @param string $primaryKey
+ * @param array $validate
+ * @param array $associations
+ */
+ function bakeModel($name, $useDbConfig = 'default', $useTable = null, $primaryKey = 'id', $validate=array(), $associations=array()) {
+ $out = "<?php\n";
+ $out .= "class {$name} extends AppModel {\n\n";
+ $out .= "\tvar \$name = '{$name}';\n";
+
+ if ($useDbConfig != 'default') {
+ $out .= "\tvar \$useDbConfig = '$useDbConfig';\n";
+ }
+
+ if ($useTable != null) {
+ $out .= "\tvar \$useTable = '$useTable';\n";
+ }
+
+ if ($primaryKey != 'id') {
+ $out .= "\tvar \$primaryKey = '$primaryKey';\n";
+ }
+
+
+ if (count($validate)) {
+ $out .= "\tvar \$validate = array(\n";
+ $keys = array_keys($validate);
+ for ($i = 0; $i < count($validate); $i++) {
+ $out .= "\t\t'" . $keys[$i] . "' => " . $validate[$keys[$i]] . ",\n";
+ }
+ $out .= "\t);\n";
+ }
+ $out .= "\n";
+
+ if (!empty($associations)) {
+ $out.= "\t//The Associations below have been created with all possible keys, those that are not needed can be removed\n";
+ if (!empty($associations['belongsTo'])) {
+ $out .= "\tvar \$belongsTo = array(\n";
+
+ for ($i = 0; $i < count($associations['belongsTo']); $i++) {
+ $out .= "\t\t\t'{$associations['belongsTo'][$i]['alias']}' =>\n";
+ $out .= "\t\t\t\tarray('className' => '{$associations['belongsTo'][$i]['className']}',\n";
+ $out .= "\t\t\t\t\t\t'foreignKey' => '{$associations['belongsTo'][$i]['foreignKey']}',\n";
+ $out .= "\t\t\t\t\t\t'conditions' => '',\n";
+ $out .= "\t\t\t\t\t\t'fields' => '',\n";
+ $out .= "\t\t\t\t\t\t'order' => '',\n";
+ $out .= "\t\t\t\t\t\t'counterCache' => ''\n";
+ $out .= "\t\t\t\t),\n\n";
+ }
+ $out .= "\t);\n\n";
+ }
+
+ if (!empty($associations['hasOne'])) {
+ $out .= "\tvar \$hasOne = array(\n";
+
+ for ($i = 0; $i < count($associations['hasOne']); $i++) {
+ $out .= "\t\t\t'{$associations['hasOne'][$i]['alias']}' =>\n";
+ $out .= "\t\t\t\tarray('className' => '{$associations['hasOne'][$i]['className']}',\n";
+ $out .= "\t\t\t\t\t\t'foreignKey' => '{$associations['hasOne'][$i]['foreignKey']}',\n";
+ $out .= "\t\t\t\t\t\t'conditions' => '',\n";
+ $out .= "\t\t\t\t\t\t'fields' => '',\n";
+ $out .= "\t\t\t\t\t\t'order' => '',\n";
+ $out .= "\t\t\t\t\t\t'dependent' => ''\n";
+ $out .= "\t\t\t\t),\n\n";
+ }
+ $out .= "\t);\n\n";
+ }
+
+ if (!empty($associations['hasMany'])) {
+ $out .= "\tvar \$hasMany = array(\n";
+
+ for ($i = 0; $i < count($associations['hasMany']); $i++) {
+ $out .= "\t\t\t'{$associations['hasMany'][$i]['alias']}' =>\n";
+ $out .= "\t\t\t\tarray('className' => '{$associations['hasMany'][$i]['className']}',\n";
+ $out .= "\t\t\t\t\t\t'foreignKey' => '{$associations['hasMany'][$i]['foreignKey']}',\n";
+ $out .= "\t\t\t\t\t\t'conditions' => '',\n";
+ $out .= "\t\t\t\t\t\t'fields' => '',\n";
+ $out .= "\t\t\t\t\t\t'order' => '',\n";
+ $out .= "\t\t\t\t\t\t'limit' => '',\n";
+ $out .= "\t\t\t\t\t\t'offset' => '',\n";
+ $out .= "\t\t\t\t\t\t'dependent' => '',\n";
+ $out .= "\t\t\t\t\t\t'exclusive' => '',\n";
+ $out .= "\t\t\t\t\t\t'finderQuery' => '',\n";
+ $out .= "\t\t\t\t\t\t'counterQuery' => ''\n";
+ $out .= "\t\t\t\t),\n\n";
+ }
+ $out .= "\t);\n\n";
+ }
+
+ if (!empty($associations['hasAndBelongsToMany'])) {
+ $out .= "\tvar \$hasAndBelongsToMany = array(\n";
+
+ for ($i = 0; $i < count($associations['hasAndBelongsToMany']); $i++) {
+ $out .= "\t\t\t'{$associations['hasAndBelongsToMany'][$i]['alias']}' =>\n";
+ $out .= "\t\t\t\tarray('className' => '{$associations['hasAndBelongsToMany'][$i]['className']}',\n";
+ $out .= "\t\t\t\t\t\t'joinTable' => '{$associations['hasAndBelongsToMany'][$i]['joinTable']}',\n";
+ $out .= "\t\t\t\t\t\t'foreignKey' => '{$associations['hasAndBelongsToMany'][$i]['foreignKey']}',\n";
+ $out .= "\t\t\t\t\t\t'associationForeignKey' => '{$associations['hasAndBelongsToMany'][$i]['associationForeignKey']}',\n";
+ $out .= "\t\t\t\t\t\t'conditions' => '',\n";
+ $out .= "\t\t\t\t\t\t'fields' => '',\n";
+ $out .= "\t\t\t\t\t\t'order' => '',\n";
+ $out .= "\t\t\t\t\t\t'limit' => '',\n";
+ $out .= "\t\t\t\t\t\t'offset' => '',\n";
+ $out .= "\t\t\t\t\t\t'unique' => '',\n";
+ $out .= "\t\t\t\t\t\t'finderQuery' => '',\n";
+ $out .= "\t\t\t\t\t\t'deleteQuery' => '',\n";
+ $out .= "\t\t\t\t\t\t'insertQuery' => ''\n";
+ $out .= "\t\t\t\t),\n\n";
+ }
+ $out .= "\t);\n\n";
+ }
+ }
+ $out .= "}\n";
+ $out .= "?>";
+ $filename = MODELS.Inflector::underscore($name) . '.php';
+ $this->__createFile($filename, $out);
+ }
+/**
+ * Assembles and writes a View file.
+ *
+ * @param string $controllerName
+ * @param string $actionName
+ * @param string $content
+ */
+ function bakeView($controllerName, $actionName, $content = '') {
+ $out = "<h2>{$actionName}</h2>\n";
+ $out .= $content;
+ if (!file_exists(VIEWS.$this->__controllerPath($controllerName))) {
+ mkdir(VIEWS.$this->__controllerPath($controllerName));
+ }
+ $filename = VIEWS . $this->__controllerPath($controllerName) . DS . Inflector::underscore($actionName) . '.thtml';
+ $this->__createFile($filename, $out);
+ }
+/**
+ * Assembles and writes a Controller file.
+ *
+ * @param string $controllerName
+ * @param array $uses
+ * @param array $helpers
+ * @param array $components
+ * @param string $actions
+ */
+ function bakeController($controllerName, $uses, $helpers, $components, $actions = '', $wannaUseScaffold = 'y') {
+ $out = "<?php\n";
+ $out .= "class $controllerName" . "Controller extends AppController {\n\n";
+ $out .= "\tvar \$name = '$controllerName';\n";
+ if (low($wannaUseScaffold) == 'y' || low($wannaUseScaffold) == 'yes') {
+ $out .= "\tvar \$scaffold;\n";
+ } else {
+
+ if (count($uses)) {
+ $out .= "\tvar \$uses = array('" . $this->__modelName($controllerName) . "', ";
+
+ foreach ($uses as $use) {
+ if ($use != $uses[count($uses) - 1]) {
+ $out .= "'" . $this->__modelName($use) . "', ";
+ } else {
+ $out .= "'" . $this->__modelName($use) . "'";
+ }
+ }
+ $out .= ");\n";
+ }
+
+ $out .= "\tvar \$helpers = array('Html', 'Form' ";
+ if (count($helpers)) {
+ foreach ($helpers as $help) {
+ if ($help != $helpers[count($helpers) - 1]) {
+ $out .= ", '" . Inflector::camelize($help) . "'";
+ } else {
+ $out .= ", '" . Inflector::camelize($help) . "'";
+ }
+ }
+ }
+ $out .= ");\n";
+
+ if (count($components)) {
+ $out .= "\tvar \$components = array(";
+
+ foreach ($components as $comp) {
+ if ($comp != $components[count($components) - 1]) {
+ $out .= "'" . Inflector::camelize($comp) . "', ";
+ } else {
+ $out .= "'" . Inflector::camelize($comp) . "'";
+ }
+ }
+ $out .= ");\n";
+ }
+ }
+ $out .= $actions;
+ $out .= "}\n";
+ $out .= "?>";
+ $filename = CONTROLLERS . $this->__controllerPath($controllerName) . '_controller.php';
+ $this->__createFile($filename, $out);
+ }
+/**
+ * Assembles and writes a unit test file.
+ *
+ * @param string $type One of "model", and "controller".
+ * @param string $className
+ */
+ function bakeUnitTest($type, $className) {
+ $out = '<?php '."\n\n";
+ $error = false;
+ switch ($type) {
+ case 'model':
+ $out .= "loadModel('$className');\n\n";
+ $out .= "class {$className}TestCase extends UnitTestCase {\n";
+ $out .= "\tvar \$object = null;\n\n";
+ $out .= "\tfunction setUp() {\n\t\t\$this->object = new {$className}();\n";
+ $out .= "\t}\n\n\tfunction tearDown() {\n\t\tunset(\$this->object);\n\t}\n";
+ $out .= "\n\t/*\n\tfunction testMe() {\n";
+ $out .= "\t\t\$result = \$this->object->doSomething();\n";
+ $out .= "\t\t\$expected = 1;\n";
+ $out .= "\t\t\$this->assertEqual(\$result, \$expected);\n\t}\n\t*/\n}";
+ $path = MODEL_TESTS;
+ $filename = $this->__singularName($className).'.test.php';
+ break;
+ case 'controller':
+ $out .= "loadController('$className');\n\n";
+ $out .= "class {$className}ControllerTestCase extends UnitTestCase {\n";
+ $out .= "\tvar \$object = null;\n\n";
+ $out .= "\tfunction setUp() {\n\t\t\$this->object = new {$className}Controller();\n";
+ $out .= "\t}\n\n\tfunction tearDown() {\n\t\tunset(\$this->object);\n\t}\n";
+ $out .= "\n\t/*\n\tfunction testMe() {\n";
+ $out .= "\t\t\$result = \$this->object->doSomething();\n";
+ $out .= "\t\t\$expected = 1;\n";
+ $out .= "\t\t\$this->assertEqual(\$result, \$expected);\n\t}\n\t*/\n}";
+ $path = CONTROLLER_TESTS;
+ $filename = $this->__pluralName($className).'_controller.test.php';
+ break;
+ default:
+ $error = true;
+ break;
+ }
+ $out .= "\n?>";
+
+ if (!$error) {
+ $this->stdout("Baking unit test for $className...");
+ $path = explode(DS, $path);
+ foreach ($path as $i => $val) {
+ if ($val == '' || $val == '../') {
+ unset($path[$i]);
+ }
+ }
+ $path = implode(DS, $path);
+ $unixPath = DS;
+ if (strpos(PHP_OS, 'WIN') === 0) {
+ $unixPath = null;
+ }
+ if (!is_dir($unixPath.$path)) {
+ $create = $this->getInput("Unit test directory does not exist. Create it?", array('y','n'), 'y');
+ if (low($create) == 'y' || low($create) == 'yes') {
+ $build = array();
+
+ foreach (explode(DS, $path) as $i => $dir) {
+ $build[] = $dir;
+ if (!is_dir($unixPath.implode(DS, $build))) {
+ mkdir($unixPath.implode(DS, $build));
+ }
+ }
+ } else {
+ return false;
+ }
+ }
+ $this->__createFile($unixPath.$path.DS.$filename, $out);
+ }
+ }
+/**
+ * Prompts the user for input, and returns it.
+ *
+ * @param string $prompt Prompt text.
+ * @param mixed $options Array or string of options.
+ * @param string $default Default input value.
+ * @return Either the default value, or the user-provided input.
+ */
+ function getInput($prompt, $options = null, $default = null) {
+ if (!is_array($options)) {
+ $print_options = '';
+ } else {
+ $print_options = '(' . implode('/', $options) . ')';
+ }
+
+ if ($default == null) {
+ $this->stdout('');
+ $this->stdout($prompt . " $print_options \n" . '> ', false);
+ } else {
+ $this->stdout('');
+ $this->stdout($prompt . " $print_options \n" . "[$default] > ", false);
+ }
+ $result = fgets($this->stdin);
+
+ if($result === false){
+ exit;
+ }
+ $result = trim($result);
+
+ if ($default != null && empty($result)) {
+ return $default;
+ } else {
+ return $result;
+ }
+ }
+/**
+ * Outputs to the stdout filehandle.
+ *
+ * @param string $string String to output.
+ * @param boolean $newline If true, the outputs gets an added newline.
+ */
+ function stdout($string, $newline = true) {
+ if ($newline) {
+ fwrite($this->stdout, $string . "\n");
+ } else {
+ fwrite($this->stdout, $string);
+ }
+ }
+/**
+ * Outputs to the stderr filehandle.
+ *
+ * @param string $string Error text to output.
+ */
+ function stderr($string) {
+ fwrite($this->stderr, $string, true);
+ }
+/**
+ * Outputs a series of minus characters to the standard output, acts as a visual separator.
+ *
+ */
+ function hr() {
+ $this->stdout('---------------------------------------------------------------');
+ }
+/**
+ * Creates a file at given path.
+ *
+ * @param string $path Where to put the file.
+ * @param string $contents Content to put in the file.
+ * @return Success
+ */
+ function __createFile ($path, $contents) {
+ $path = str_replace('//', '/', $path);
+ echo "\nCreating file $path\n";
+ if (is_file($path) && $this->interactive === true) {
+ fwrite($this->stdout, __("File exists, overwrite?", true). " {$path} (y/n/q):");
+ $key = trim(fgets($this->stdin));
+
+ if ($key=='q') {
+ fwrite($this->stdout, __("Quitting.", true) ."\n");
+ exit;
+ } elseif ($key == 'a') {
+ $this->dont_ask = true;
+ } elseif ($key == 'y') {
+ } else {
+ fwrite($this->stdout, __("Skip", true) ." {$path}\n");
+ return false;
+ }
+ }
+
+ if ($f = fopen($path, 'w')) {
+ fwrite($f, $contents);
+ fclose($f);
+ fwrite($this->stdout, __("Wrote", true) ."{$path}\n");
+ return true;
+ } else {
+ fwrite($this->stderr, __("Error! Could not write to", true)." {$path}.\n");
+ return false;
+ }
+ }
+/**
+ * Takes an array of database fields, and generates an HTML form for a View.
+ * This is an extraction from the Scaffold functionality.
+ *
+ * @param array $fields
+ * @param boolean $readOnly
+ * @return Generated HTML and PHP.
+ */
+ function generateFields( $fields, $readOnly = false ) {
+ $strFormFields = '';
+ foreach ( $fields as $field ) {
+ if (isset( $field['type'])) {
+ if (!isset($field['required'])) {
+ $field['required'] = false;
+ }
+
+ if (!isset( $field['errorMsg'])) {
+ $field['errorMsg'] = null;
+ }
+
+ if (!isset( $field['htmlOptions'])) {
+ $field['htmlOptions'] = array();
+ }
+
+ if ( $readOnly ) {
+ $field['htmlOptions']['READONLY'] = "readonly";
+ }
+
+ switch( $field['type'] ) {
+ case "input" :
+ if (!isset( $field['size'])) {
+ $field['size'] = 60;
+ }
+ $strFormFields = $strFormFields.$this->generateInputDiv( $field['tagName'], $field['prompt'], $field['required'], $field['errorMsg'], $field['size'], $field['htmlOptions'] );
+ break;
+ case "checkbox" :
+ $strFormFields = $strFormFields.$this->generateCheckboxDiv( $field['tagName'], $field['prompt'], $field['required'], $field['errorMsg'], $field['htmlOptions'] );
+ break;
+ case "select";
+ case "selectMultiple";
+ if ( "selectMultiple" == $field['type'] ) {
+ $field['selectAttr']['multiple'] = 'multiple';
+ $field['selectAttr']['class'] = 'selectMultiple';
+ }
+ if (!isset( $field['selected'])) {
+ $field['selected'] = null;
+ }
+ if (!isset( $field['selectAttr'])) {
+ $field['selectAttr'] = null;
+ }
+ if (!isset( $field['optionsAttr'])) {
+ $field['optionsAttr'] = null;
+ }
+ if ($readOnly) {
+ $field['selectAttr']['DISABLED'] = true;
+ }
+ if (!isset( $field['options'])) {
+ $field['options'] = null;
+ }
+ $this->__modelAlias = null;
+ if (isset($field['foreignKey'])) {
+ $modelKey = Inflector::underscore($this->__modelClass);
+ $modelObj =& ClassRegistry::getObject($modelKey);
+ foreach ($modelObj->belongsTo as $associationName => $value) {
+ if ($field['model'] == $value['className']) {
+ $this->__modelAlias = $this->__modelName($associationName);
+ break;
+ }
+ }
+ }
+ $strFormFields = $strFormFields.$this->generateSelectDiv( $field['tagName'], $field['prompt'], $field['options'], $field['selected'], $field['selectAttr'], $field['optionsAttr'], $field['required'], $field['errorMsg'] );
+ break;
+ case "area";
+ if (!isset( $field['rows'])) {
+ $field['rows'] = 10;
+ }
+ if (!isset( $field['cols'])) {
+ $field['cols'] = 60;
+ }
+ $strFormFields = $strFormFields.$this->generateAreaDiv( $field['tagName'], $field['prompt'], $field['required'], $field['errorMsg'], $field['cols'], $field['rows'], $field['htmlOptions'] );
+ break;
+ case "fieldset";
+ $strFieldsetFields = $this->generateFields( $field['fields'] );
+ $strFieldSet = sprintf( '
+ <fieldset><legend>%s</legend><div class="notes"><h4>%s</h4><p class="last">%s</p></div>%s</fieldset>',
+ $field['legend'], $field['noteHeading'], $field['note'], $strFieldsetFields );
+ $strFormFields = $strFormFields.$strFieldSet;
+ break;
+ case "hidden";
+ //$strFormFields = $strFormFields . $this->Html->hiddenTag( $field['tagName']);
+ break;
+ case "date":
+ if (!isset($field['selected'])) {
+ $field['selected'] = null;
+ }
+ $strFormFields = $strFormFields . $this->generateDate($field['tagName'], $field['prompt'], $field['required'], $field['errorMsg'], null, $field['htmlOptions'], $field['selected']);
+ break;
+ case "datetime":
+ if (!isset($field['selected'])) {
+ $field['selected'] = null;
+ }
+ $strFormFields = $strFormFields . $this->generateDateTime($field['tagName'], $field['prompt'], $field['required'], $field['errorMsg'], null, $field['htmlOptions'], $field['selected']);
+ break;
+ case "time":
+ if (!isset($field['selected'])) {
+ $field['selected'] = null;
+ }
+ $strFormFields = $strFormFields . $this->generateTime($field['tagName'], $field['prompt'], $field['required'], $field['errorMsg'], null, $field['htmlOptions'], $field['selected']);
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ return $strFormFields;
+ }
+/**
+ * Generates PHP code for a View file that makes a textarea.
+ *
+ * @param string $tagName
+ * @param string $prompt
+ * @param boolean $required
+ * @param string $errorMsg
+ * @param integer $cols
+ * @param integer $rows
+ * @param array $htmlOptions
+ * @return Generated HTML and PHP.
+ */
+ function generateAreaDiv($tagName, $prompt, $required=false, $errorMsg=null, $cols=60, $rows=10, $htmlOptions=null ) {
+ $htmlAttributes = $htmlOptions;
+ $htmlAttributes['cols'] = $cols;
+ $htmlAttributes['rows'] = $rows;
+ $str = "\t<?php echo \$html->textarea('{$tagName}', " . $this->__attributesToArray($htmlAttributes) . ");?>\n";
+ $str .= "\t<?php echo \$html->tagErrorMsg('{$tagName}', 'Please enter the {$prompt}.');?>\n";
+ $strLabel = "\n\t<?php echo \$form->labelTag( '{$tagName}', '{$prompt}' );?>\n";
+ $divClass = "optional";
+
+ if ( $required ) {
+ $divClass = "required";
+ }
+ $strError = "";
+ $divTagInside = sprintf( "%s %s %s", $strError, $strLabel, $str );
+ return $this->divTag( $divClass, $divTagInside );
+ }
+/**
+ * Generates PHP code for a View file that makes a checkbox, wrapped in a DIV.
+ *
+ * @param string $tagName
+ * @param string $prompt
+ * @param boolean $required
+ * @param string $errorMsg
+ * @param array $htmlOptions
+ * @return Generated HTML and PHP.
+ */
+ function generateCheckboxDiv($tagName, $prompt, $required=false, $errorMsg=null, $htmlOptions=null ) {
+ $htmlAttributes = $htmlOptions;
+ $strLabel = "\n\t<?php echo \$html->checkbox('{$tagName}', null, " . $this->__attributesToArray($htmlAttributes) . ");?>\n";
+ $strLabel .= "\t<?php echo \$form->labelTag('{$tagName}', '{$prompt}');?>\n";
+ $str = "\t<?php echo \$html->tagErrorMsg('{$tagName}', 'Please check the {$prompt}.');?>\n";
+ $divClass = "optional";
+
+ if ($required) {
+ $divClass = "required";
+ }
+ $strError = "";
+ $divTagInside = sprintf( "%s %s %s", $strError, $strLabel, $str);
+ return $this->divTag( $divClass, $divTagInside );
+ }
+/**
+ * Generates PHP code for a View file that makes a date-picker, wrapped in a DIV.
+ *
+ * @param string $tagName
+ * @param string $prompt
+ * @param boolean $required
+ * @param string $errorMsg
+ * @param integer $size
+ * @param array $htmlOptions
+ * @param string $selected
+ * @return Generated HTML and PHP.
+ */
+ function generateDate($tagName, $prompt, $required=false, $errorMsg=null, $size=20, $htmlOptions=null, $selected=null ) {
+ $str = "\t<?php echo \$html->dateTimeOptionTag('{$tagName}', 'MDY' , 'NONE', \$html->tagValue('{$tagName}'), " . $this->__attributesToArray($htmlOptions) . ");?>\n";
+ $str .= "\t<?php echo \$html->tagErrorMsg('{$tagName}', 'Please select the {$prompt}.');?>\n";
+ $strLabel = "\n\t<?php echo \$form->labelTag('{$tagName}', '{$prompt}');?>\n";
+ $divClass = "optional";
+
+ if ($required) {
+ $divClass = "required";
+ }
+ $strError = "";
+ $divTagInside = sprintf( "%s %s %s", $strError, $strLabel, $str );
+ return $this->divTag( $divClass, $divTagInside );
+ }
+/**
+ * Generates PHP code for a View file that makes a time-picker, wrapped in a DIV.
+ *
+ * @param string $tagName
+ * @param string $prompt
+ * @param boolean $required
+ * @param string $errorMsg
+ * @param integer $size
+ * @param array $htmlOptions
+ * @param string $selected
+ * @return Generated HTML and PHP.
+ */
+ function generateTime($tagName, $prompt, $required = false, $errorMsg = null, $size = 20, $htmlOptions = null, $selected = null) {
+ $str = "\n\t\<?php echo \$html->dateTimeOptionTag('{$tagName}', 'NONE', '24', \$html->tagValue('{$tagName}'), " . $this->__attributesToArray($htmlOptions) . ");?>\n";
+ $strLabel = "\n\t<?php echo \$form->labelTag('{$tagName}', '{$prompt}');?>\n";
+ $divClass = "optional";
+ if ($required) {
+ $divClass = "required";
+ }
+ $strError = "";
+ $divTagInside = sprintf("%s %s %s", $strError, $strLabel, $str);
+ return $this->divTag($divClass, $divTagInside);
+ }
+/**
+ * EGenerates PHP code for a View file that makes a datetime-picker, wrapped in a DIV.
+ *
+ * @param string $tagName
+ * @param string $prompt
+ * @param boolean $required
+ * @param string $errorMsg
+ * @param integer $size
+ * @param array $htmlOptions
+ * @param string $selected
+ * @return Generated HTML and PHP.
+ */
+ function generateDateTime($tagName, $prompt, $required=false, $errorMsg=null, $size=20, $htmlOptions=null, $selected = null ) {
+ $str = "\t<?php echo \$html->dateTimeOptionTag('{$tagName}', 'MDY' , '12', \$html->tagValue('{$tagName}'), " . $this->__attributesToArray($htmlOptions) . ");?>\n";
+ $str .= "\t<?php echo \$html->tagErrorMsg('{$tagName}', 'Please select the {$prompt}.');?>\n";
+ $strLabel = "\n\t<?php echo \$form->labelTag('{$tagName}', '{$prompt}');?>\n";
+ $divClass = "optional";
+
+ if ($required) {
+ $divClass = "required";
+ }
+ $strError = "";
+ $divTagInside = sprintf( "%s %s %s", $strError, $strLabel, $str );
+ return $this->divTag( $divClass, $divTagInside );
+ }
+/**
+ * Generates PHP code for a View file that makes an INPUT field, wrapped in a DIV.
+ *
+ * @param string $tagName
+ * @param string $prompt
+ * @param boolean $required
+ * @param string $errorMsg
+ * @param integer $size
+ * @param array $htmlOptions
+ * @return Generated HTML and PHP.
+ */
+ function generateInputDiv($tagName, $prompt, $required=false, $errorMsg=null, $size=20, $htmlOptions=null ) {
+ $htmlAttributes = $htmlOptions;
+ $htmlAttributes['size'] = $size;
+ $str = "\t<?php echo \$html->input('{$tagName}', " . $this->__attributesToArray($htmlAttributes) . ");?>\n";
+ $str .= "\t<?php echo \$html->tagErrorMsg('{$tagName}', 'Please enter the {$prompt}.');?>\n";
+ $strLabel = "\n\t<?php echo \$form->labelTag('{$tagName}', '{$prompt}');?>\n";
+ $divClass = "optional";
+
+ if ($required) {
+ $divClass = "required";
+ }
+ $strError = "";
+ $divTagInside = sprintf( "%s %s %s", $strError, $strLabel, $str );
+ return $this->divTag( $divClass, $divTagInside );
+ }
+
+/**
+ * Generates PHP code for a View file that makes a SELECT box, wrapped in a DIV.
+ *
+ * @param string $tagName
+ * @param string $prompt
+ * @param array $options
+ * @param string $selected
+ * @param array $selectAttr
+ * @param array $optionAttr
+ * @param boolean $required
+ * @param string $errorMsg
+ * @return Generated HTML and PHP.
+ */
+ function generateSelectDiv($tagName, $prompt, $options, $selected=null, $selectAttr=null, $optionAttr=null, $required=false, $errorMsg=null) {
+
+ if ($this->__modelAlias) {
+ $pluralName = $this->__pluralName($this->__modelAlias);
+ } else {
+ $tagArray = explode('/', $tagName);
+ $pluralName = $this->__pluralName($this->__modelNameFromKey($tagArray[1]));
+ }
+ $showEmpty = 'true';
+ if ($required) {
+ $showEmpty = 'false';
+ }
+ if ($selectAttr['multiple'] != 'multiple') {
+ $str = "\t<?php echo \$html->selectTag('{$tagName}', " . "\${$pluralName}, \$html->tagValue('{$tagName}'), " . $this->__attributesToArray($selectAttr) . ", " . $this->__attributesToArray($optionAttr) . ", " . $showEmpty . ");?>\n";
+ $str .= "\t<?php echo \$html->tagErrorMsg('{$tagName}', 'Please select the {$prompt}.') ?>\n";
+ } else {
+ $selectedPluralName = 'selected' . ucfirst($pluralName);
+ $selectAttr = am(array('multiple' => 'multiple', 'class' => 'selectMultiple'), $selectAttr);
+ $str = "\t<?php echo \$html->selectTag('{$tagName}', \${$pluralName}, \${$selectedPluralName}, " . $this->__attributesToArray($selectAttr) . ", " . $this->__attributesToArray($optionAttr) . ", " . $showEmpty . ");?>\n";
+ $str .= "\t<?php echo \$html->tagErrorMsg('{$tagName}', 'Please select the {$prompt}.');?>\n";
+ }
+ $strLabel = "\n\t<?php echo \$form->labelTag('{$tagName}', '{$prompt}');?>\n";
+ $divClass = "optional";
+
+ if ($required) {
+ $divClass = "required";
+ }
+ $strError = "";
+ $divTagInside = sprintf( "%s %s %s", $strError, $strLabel, $str );
+ return $this->divTag( $divClass, $divTagInside );
+ }
+/**
+ * Generates PHP code for a View file that makes a submit button, wrapped in a DIV.
+ *
+ * @param string $displayText
+ * @param array $htmlOptions
+ * @return Generated HTML.
+ */
+ function generateSubmitDiv($displayText, $htmlOptions = null) {
+ $str = "\n\t<?php echo \$html->submit('{$displayText}');?>\n";
+ $divTagInside = sprintf( "%s", $str );
+ return $this->divTag( 'submit', $divTagInside);
+ }
+/**
+ * Returns the text wrapped in an HTML DIV, followed by a newline.
+ *
+ * @param string $class
+ * @param string $text
+ * @return Generated HTML.
+ */
+ function divTag($class, $text) {
+ return sprintf('<div class="%s">%s</div>', $class, $text ) . "\n";
+ }
+/**
+ * Parses the HTML attributes array, which is a common data structure in View files.
+ * Returns PHP code for initializing this array in a View file.
+ *
+ * @param array $htmlAttributes
+ * @return Generated PHP code.
+ */
+ function __attributesToArray($htmlAttributes) {
+ if (is_array($htmlAttributes)) {
+ $keys = array_keys($htmlAttributes);
+ $vals = array_values($htmlAttributes);
+ $out = "array(";
+
+ for ($i = 0; $i < count($htmlAttributes); $i++) {
+ if (substr($vals[$i], 0, 1) != '$') {
+ $out .= "'{$keys[$i]}' => '{$vals[$i]}', ";
+ } else {
+ $out .= "'{$keys[$i]}' => {$vals[$i]}, ";
+ }
+ }
+ if (substr($out, -2, 1) == ',') {
+ $out = substr($out, 0, strlen($out) - 2);
+ }
+ $out .= ")";
+ return $out;
+ } else {
+ return 'array()';
+ }
+ }
+/**
+ * Outputs usage text on the standard output.
+ *
+ */
+ function help() {
+ $this->stdout('CakePHP Bake:');
+ $this->hr();
+ $this->stdout('The Bake script generates controllers, views and models for your application.');
+ $this->stdout('If run with no command line arguments, Bake guides the user through the class');
+ $this->stdout('creation process. You can customize the generation process by telling Bake');
+ $this->stdout('where different parts of your application are using command line arguments.');
+ $this->stdout('');
+ $this->hr('');
+ $this->stdout('usage: php bake.php [command] [path...]');
+ $this->stdout('');
+ $this->stdout('commands:');
+ $this->stdout(' -app [path...] Absolute path to Cake\'s app Folder.');
+ $this->stdout(' -core [path...] Absolute path to Cake\'s cake Folder.');
+ $this->stdout(' -help Shows this help message.');
+ $this->stdout(' -project [path...] Generates a new app folder in the path supplied.');
+ $this->stdout(' -root [path...] Absolute path to Cake\'s \app\webroot Folder.');
+ $this->stdout('');
+ }
+/**
+ * Checks that given project path does not already exist, and
+ * finds the app directory in it. Then it calls __buildDirLayout() with that information.
+ *
+ * @param string $projectPath
+ */
+ function project($projectPath = null) {
+ if ($projectPath != '') {
+ while ($this->__checkPath($projectPath) === true && $this->__checkPath(CONFIGS) === true) {
+ $response = $this->getInput('Bake -app in '.$projectPath, array('y','n'), 'y');
+ if (low($response) == 'y') {
+ $this->main();
+ exit();
+ } else {
+ $projectPath = $this->getInput("What is the full path for this app including the app directory name?\nExample: ".ROOT.DS."myapp", null, ROOT.DS.'myapp');
+ }
+ }
+ } else {
+ while ($projectPath == '') {
+ $projectPath = $this->getInput("What is the full path for this app including the app directory name?\nExample: ".ROOT.DS."myapp", null, ROOT.DS.'myapp');
+
+ if ($projectPath == '') {
+ $this->stdout('The directory path you supplied was empty. Please try again.');
+ }
+ }
+ }
+ while ($newPath != 'y' && ($this->__checkPath($projectPath) === true || $projectPath == '')) {
+ $newPath = $this->getInput('Directory '.$projectPath.' exists. Overwrite (y) or insert a new path', null, 'y');
+ if ($newPath != 'y') {
+ $projectPath = $newPath;
+ }
+ while ($projectPath == '') {
+ $projectPath = $this->getInput('The directory path you supplied was empty. Please try again.');
+ }
+ }
+ $parentPath = explode(DS, $projectPath);
+ $count = count($parentPath);
+ $appName = $parentPath[$count - 1];
+ if ($appName == '') {
+ $appName = $parentPath[$count - 2];
+ }
+ $this->__buildDirLayout($projectPath, $appName);
+ exit();
+ }
+/**
+ * Returns true if given path is a directory.
+ *
+ * @param string $projectPath
+ * @return True if given path is a directory.
+ */
+ function __checkPath($projectPath) {
+ if (is_dir($projectPath)) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+/**
+ * Looks for a skeleton template of a Cake application,
+ * and if not found asks the user for a path. When there is a path
+ * this method will make a deep copy of the skeleton to the project directory.
+ * A default home page will be added, and the tmp file storage will be chmod'ed to 0777.
+ *
+ * @param string $projectPath
+ * @param string $appName
+ */
+ function __buildDirLayout($projectPath, $appName) {
+ $skel = '';
+ if ($this->__checkPath(CAKE_CORE_INCLUDE_PATH.DS.'cake'.DS.'scripts'.DS.'templates'.DS.'skel') === true) {
+ $skel = CAKE_CORE_INCLUDE_PATH.DS.'cake'.DS.'scripts'.DS.'templates'.DS.'skel';
+ } else {
+
+ while ($skel == '') {
+ $skel = $this->getInput("What is the full path for the cake install app directory?\nExample: ", null, ROOT.'myapp'.DS);
+
+ if ($skel == '') {
+ $this->stdout('The directory path you supplied was empty. Please try again.');
+ } else {
+ while ($this->__checkPath($skel) === false) {
+ $skel = $this->getInput('Directory path does not exist please choose another:');
+ }
+ }
+ }
+ }
+ $this->stdout('');
+ $this->hr();
+ $this->stdout("Skel Directory: $skel");
+ $this->stdout("Will be copied to:");
+ $this->stdout("New App Directory: $projectPath");
+ $this->hr();
+ $looksGood = $this->getInput('Look okay?', array('y', 'n', 'q'), 'y');
+
+ if (low($looksGood) == 'y' || low($looksGood) == 'yes') {
+ $verboseOuptut = $this->getInput('Do you want verbose output?', array('y', 'n'), 'n');
+ $verbose = false;
+
+ if (low($verboseOuptut) == 'y' || low($verboseOuptut) == 'yes') {
+ $verbose = true;
+ }
+ $this->__copydirr($skel, $projectPath, 0755, $verbose);
+ $this->hr();
+ $this->stdout('Created: '.$projectPath);
+ $this->hr();
+ $this->stdout('Creating welcome page');
+ $this->hr();
+ $this->__defaultHome($projectPath, $appName);
+ $this->stdout('Welcome page created');
+ if (chmodr($projectPath.DS.'tmp', 0777) === false) {
+ $this->stdout('Could not set permissions on '. $projectPath.DS.'tmp'.DS.'*');
+ $this->stdout('You must manually check that these directories can be wrote to by the server');
+ }
+ return;
+ } elseif (low($looksGood) == 'q' || low($looksGood) == 'quit') {
+ $this->stdout('Bake Aborted.');
+ } else {
+ $this->project();
+ }
+ }
+/**
+ * Recursive directory copy.
+ *
+ * @param string $fromDir
+ * @param string $toDir
+ * @param octal $chmod
+ * @param boolean $verbose
+ * @return Success.
+ */
+ function __copydirr($fromDir, $toDir, $chmod = 0755, $verbose = false) {
+ $errors=array();
+ $messages=array();
+
+ uses('folder');
+ $folder = new Folder($toDir, true, 0755);
+
+ if (!is_writable($toDir)) {
+ $errors[]='target '.$toDir.' is not writable';
+ }
+
+ if (!is_dir($fromDir)) {
+ $errors[]='source '.$fromDir.' is not a directory';
+ }
+
+ if (!empty($errors)) {
+ if ($verbose) {
+ foreach ($errors as $err) {
+ $this->stdout('Error: '.$err);
+ }
+ }
+ return false;
+ }
+ $exceptions=array('.','..','.svn');
+ $handle = opendir($fromDir);
+
+ while (false!==($item = readdir($handle))) {
+ if (!in_array($item,$exceptions)) {
+ $from = $folder->addPathElement($fromDir, $item);
+ $to = $folder->addPathElement($toDir, $item);
+ if (is_file($from)) {
+ if (@copy($from, $to)) {
+ chmod($to, $chmod);
+ touch($to, filemtime($from));
+ $messages[]='File copied from '.$from.' to '.$to;
+ } else {
+ $errors[]='cannot copy file from '.$from.' to '.$to;
+ }
+ }
+
+ if (is_dir($from)) {
+ if (@mkdir($to)) {
+ chmod($to,$chmod);
+ $messages[]='Directory created: '.$to;
+ } else {
+ $errors[]='cannot create directory '.$to;
+ }
+ $this->__copydirr($from,$to,$chmod,$verbose);
+ }
+ }
+ }
+ closedir($handle);
+
+ if ($verbose) {
+ foreach ($errors as $err) {
+ $this->stdout('Error: '.$err);
+ }
+ foreach ($messages as $msg) {
+ $this->stdout($msg);
+ }
+ }
+ return true;
+ }
+
+ function __addAdminRoute($name) {
+ $file = file_get_contents(CONFIGS.'core.php');
+ if (preg_match('%([/\\t\\x20]*define\\(\'CAKE_ADMIN\',[\\t\\x20\'a-z]*\\);)%', $file, $match)) {
+ $result = str_replace($match[0], 'define(\'CAKE_ADMIN\', \''.$name.'\');', $file);
+
+ if (file_put_contents(CONFIGS.'core.php', $result)) {
+ return true;
+ } else {
+ return false;
+ }
+ } else {
+ return false;
+ }
+ }
+/**
+ * Outputs an ASCII art banner to standard output.
+ *
+ */
+ function welcome()
+ {
+ $this->stdout('');
+ $this->stdout(' ___ __ _ _ ___ __ _ _ __ __ __ _ _ ___ ');
+ $this->stdout('| |__| |_/ |__ |__] |__| |__] |__] |__| |_/ |__ ');
+ $this->stdout('|___ | | | \_ |___ | | | | |__] | | | \_ |___ ');
+ $this->hr();
+ $this->stdout('');
+ }
+/**
+ * Writes a file with a default home page to the project.
+ *
+ * @param string $dir
+ * @param string $app
+ */
+ function __defaultHome($dir, $app) {
+ $path = $dir.DS.'views'.DS.'pages'.DS;
+ include(CAKE_CORE_INCLUDE_PATH.DS.'cake'.DS.'scripts'.DS.'templates'.DS.'views'.DS.'home.thtml');
+ $this->__createFile($path.'home.thtml', $output);
+ }
+/**
+ * creates the proper pluralize controller for the url
+ *
+ * @param string $name must be a controller name in pluralized form
+ * @return string $name
+ */
+ function __controllerPath($name) {
+ return low(Inflector::underscore($name));
+ }
+/**
+ * creates the proper pluralize controller class name.
+ *
+ * @param string $name
+ * @return string $name
+ */
+ function __controllerName($name) {
+ return Inflector::pluralize(Inflector::camelize($name));
+ }
+/**
+ * creates the proper singular model name.
+ *
+ * @param string $name
+ * @return string $name
+ */
+ function __modelName($name) {
+ return Inflector::camelize(Inflector::singularize($name));
+ }
+/**
+ * creates the proper singular model key for associations.
+ *
+ * @param string $name
+ * @return string $name
+ */
+ function __modelKey($name) {
+ return Inflector::underscore(Inflector::singularize($name)).'_id';
+ }
+/**
+ * creates the proper model name from a foreign key.
+ *
+ * @param string $key
+ * @return string $name
+ */
+ function __modelNameFromKey($key) {
+ $name = str_replace('_id', '',$key);
+ return $this->__modelName($name);
+ }
+/**
+ * creates the singular name for use in views.
+ *
+ * @param string $name
+ * @return string $name
+ */
+ function __singularName($name) {
+ return Inflector::variable(Inflector::singularize($name));
+ }
+/**
+ * creates the plural name for views.
+ *
+ * @param string $name
+ * @return string $name
+ */
+ function __pluralName($name) {
+ return Inflector::variable(Inflector::pluralize($name));
+ }
+/**
+ * creates the singular human name used in views
+ *
+ * @param string $name
+ * @return string $name
+ */
+ function __singularHumanName($name) {
+ return Inflector::humanize(Inflector::underscore(Inflector::singularize($name)));
+ }
+/**
+ * creates the plural humna name used in views
+ *
+ * @param string $name
+ * @return string $name
+ */
+ function __pluralHumanName($name) {
+ return Inflector::humanize(Inflector::underscore(Inflector::pluralize($name)));
+ }
+/**
+ * outputs the a list of possible models or controllers from database
+ *
+ * @param string $useDbConfig
+ * @param string $type = Models or Controllers
+ * @return output
+ */
+ function __doList($useDbConfig = 'default', $type = 'Models') {
+ $db =& ConnectionManager::getDataSource($useDbConfig);
+ $usePrefix = empty($db->config['prefix']) ? '' : $db->config['prefix'];
+ if ($usePrefix) {
+ $tables = array();
+ foreach ($db->listSources() as $table) {
+ if (!strncmp($table, $usePrefix, strlen($usePrefix))) {
+ $tables[] = substr($table, strlen($usePrefix));
+ }
+ }
+ } else {
+ $tables = $db->listSources();
+ }
+ $this->__tables = $tables;
+ $this->stdout('Possible '.$type.' based on your current database:');
+ $this->__controllerNames = array();
+ $this->__modelNames = array();
+ $count = count($tables);
+ for ($i = 0; $i < $count; $i++) {
+ if (low($type) == 'controllers') {
+ $this->__controllerNames[] = $this->__controllerName($this->__modelName($tables[$i]));
+ $this->stdout($i + 1 . ". " . $this->__controllerNames[$i]);
+ } else {
+ $this->__modelNames[] = $this->__modelName($tables[$i]);
+ $this->stdout($i + 1 . ". " . $this->__modelNames[$i]);
+ }
+ }
+ }
+
+}
+?> \ No newline at end of file
diff --git a/site/cake/scripts/templates/skel/.htaccess b/site/cake/scripts/templates/skel/.htaccess
new file mode 100644
index 0000000..00d12ab
--- /dev/null
+++ b/site/cake/scripts/templates/skel/.htaccess
@@ -0,0 +1,5 @@
+<IfModule mod_rewrite.c>
+ RewriteEngine on
+ RewriteRule ^$ webroot/ [L]
+ RewriteRule (.*) webroot/$1 [L]
+ </IfModule> \ No newline at end of file
diff --git a/site/cake/scripts/templates/skel/app_controller.php b/site/cake/scripts/templates/skel/app_controller.php
new file mode 100644
index 0000000..b64414e
--- /dev/null
+++ b/site/cake/scripts/templates/skel/app_controller.php
@@ -0,0 +1,41 @@
+<?php
+/* SVN FILE: $Id: app_controller.php 6305 2008-01-02 02:33:56Z phpnut $ */
+/**
+ * Short description for file.
+ *
+ * This file is application-wide controller file. You can put all
+ * application-wide controller-related methods here.
+ *
+ * PHP versions 4 and 5
+ *
+ * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
+ * Copyright 2005-2008, Cake Software Foundation, Inc.
+ * 1785 E. Sahara Avenue, Suite 490-204
+ * Las Vegas, Nevada 89104
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
+ * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
+ * @package cake
+ * @subpackage cake.app
+ * @since CakePHP(tm) v 0.2.9
+ * @version $Revision: 6305 $
+ * @modifiedby $LastChangedBy: phpnut $
+ * @lastmodified $Date: 2008-01-01 20:33:56 -0600 (Tue, 01 Jan 2008) $
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+/**
+ * Short description for class.
+ *
+ * Add your application-wide methods in the class below, your controllers
+ * will inherit them.
+ *
+ * @package cake
+ * @subpackage cake.app
+ */
+class AppController extends Controller {
+}
+?> \ No newline at end of file
diff --git a/site/cake/scripts/templates/skel/app_model.php b/site/cake/scripts/templates/skel/app_model.php
new file mode 100644
index 0000000..f0c7a19
--- /dev/null
+++ b/site/cake/scripts/templates/skel/app_model.php
@@ -0,0 +1,43 @@
+<?php
+/* SVN FILE: $Id: app_model.php 6305 2008-01-02 02:33:56Z phpnut $ */
+
+/**
+ * Application model for Cake.
+ *
+ * This file is application-wide model file. You can put all
+ * application-wide model-related methods here.
+ *
+ * PHP versions 4 and 5
+ *
+ * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
+ * Copyright 2005-2008, Cake Software Foundation, Inc.
+ * 1785 E. Sahara Avenue, Suite 490-204
+ * Las Vegas, Nevada 89104
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
+ * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
+ * @package cake
+ * @subpackage cake.app
+ * @since CakePHP(tm) v 0.2.9
+ * @version $Revision: 6305 $
+ * @modifiedby $LastChangedBy: phpnut $
+ * @lastmodified $Date: 2008-01-01 20:33:56 -0600 (Tue, 01 Jan 2008) $
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+
+/**
+ * Application model for Cake.
+ *
+ * Add your application-wide methods in the class below, your models
+ * will inherit them.
+ *
+ * @package cake
+ * @subpackage cake.app
+ */
+class AppModel extends Model{
+}
+?> \ No newline at end of file
diff --git a/site/cake/scripts/templates/skel/config/acl.ini.php b/site/cake/scripts/templates/skel/config/acl.ini.php
new file mode 100644
index 0000000..9b70a17
--- /dev/null
+++ b/site/cake/scripts/templates/skel/config/acl.ini.php
@@ -0,0 +1,76 @@
+;<?php die() ?>
+; SVN FILE: $Id: acl.ini.php 6305 2008-01-02 02:33:56Z phpnut $
+;/**
+; * Short description for file.
+; *
+; *
+; * PHP versions 4 and 5
+; *
+; * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
+; * Copyright 2005-2008, Cake Software Foundation, Inc.
+; * 1785 E. Sahara Avenue, Suite 490-204
+; * Las Vegas, Nevada 89104
+; *
+; * Licensed under The MIT License
+; * Redistributions of files must retain the above copyright notice.
+; *
+; * @filesource
+; * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
+; * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
+; * @package cake
+; * @subpackage cake.app.config
+; * @since CakePHP(tm) v 0.10.0.1076
+; * @version $Revision: 6305 $
+; * @modifiedby $LastChangedBy: phpnut $
+; * @lastmodified $Date: 2008-01-01 20:33:56 -0600 (Tue, 01 Jan 2008) $
+; * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+; */
+
+; acl.ini.php - Cake ACL Configuration
+; ---------------------------------------------------------------------
+; Use this file to specify user permissions.
+; aco = access control object (something in your application)
+; aro = access request object (something requesting access)
+;
+; User records are added as follows:
+;
+; [uid]
+; groups = group1, group2, group3
+; allow = aco1, aco2, aco3
+; deny = aco4, aco5, aco6
+;
+; Group records are added in a similar manner:
+;
+; [gid]
+; allow = aco1, aco2, aco3
+; deny = aco4, aco5, aco6
+;
+; The allow, deny, and groups sections are all optional.
+; NOTE: groups names *cannot* ever be the same as usernames!
+;
+; ACL permissions are checked in the following order:
+; 1. Check for user denies (and DENY if specified)
+; 2. Check for user allows (and ALLOW if specified)
+; 3. Gather user's groups
+; 4. Check group denies (and DENY if specified)
+; 5. Check group allows (and ALLOW if specified)
+; 6. If no aro, aco, or group information is found, DENY
+;
+; ---------------------------------------------------------------------
+
+;-------------------------------------
+;Users
+;-------------------------------------
+
+[username-goes-here]
+groups = group1, group2
+deny = aco1, aco2
+allow = aco3, aco4
+
+;-------------------------------------
+;Groups
+;-------------------------------------
+
+[groupname-goes-here]
+deny = aco5, aco6
+allow = aco7, aco8 \ No newline at end of file
diff --git a/site/cake/scripts/templates/skel/config/bootstrap.php b/site/cake/scripts/templates/skel/config/bootstrap.php
new file mode 100644
index 0000000..4773581
--- /dev/null
+++ b/site/cake/scripts/templates/skel/config/bootstrap.php
@@ -0,0 +1,46 @@
+<?php
+/* SVN FILE: $Id: bootstrap.php 6305 2008-01-02 02:33:56Z phpnut $ */
+/**
+ * Short description for file.
+ *
+ * Long description for file
+ *
+ * PHP versions 4 and 5
+ *
+ * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
+ * Copyright 2005-2008, Cake Software Foundation, Inc.
+ * 1785 E. Sahara Avenue, Suite 490-204
+ * Las Vegas, Nevada 89104
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
+ * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
+ * @package cake
+ * @subpackage cake.app.config
+ * @since CakePHP(tm) v 0.10.8.2117
+ * @version $Revision: 6305 $
+ * @modifiedby $LastChangedBy: phpnut $
+ * @lastmodified $Date: 2008-01-01 20:33:56 -0600 (Tue, 01 Jan 2008) $
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+/**
+ *
+ * This file is loaded automatically by the app/webroot/index.php file after the core bootstrap.php is loaded
+ * This is an application wide file to load any function that is not used within a class define.
+ * You can also use this to include or require any files in your application.
+ *
+ */
+/**
+ * The settings below can be used to set additional paths to models, views and controllers.
+ * This is related to Ticket #470 (https://trac.cakephp.org/ticket/470)
+ *
+ * $modelPaths = array('full path to models', 'second full path to models', 'etc...');
+ * $viewPaths = array('this path to views', 'second full path to views', 'etc...');
+ * $controllerPaths = array('this path to controllers', 'second full path to controllers', 'etc...');
+ *
+ */
+//EOF
+?> \ No newline at end of file
diff --git a/site/cake/scripts/templates/skel/config/core.php b/site/cake/scripts/templates/skel/config/core.php
new file mode 100644
index 0000000..779feac
--- /dev/null
+++ b/site/cake/scripts/templates/skel/config/core.php
@@ -0,0 +1,146 @@
+<?php
+/* SVN FILE: $Id: core.php 6305 2008-01-02 02:33:56Z phpnut $ */
+/**
+ * This is core configuration file.
+ *
+ * Use it to configure core behaviour ofCake.
+ *
+ * PHP versions 4 and 5
+ *
+ * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
+ * Copyright 2005-2008, Cake Software Foundation, Inc.
+ * 1785 E. Sahara Avenue, Suite 490-204
+ * Las Vegas, Nevada 89104
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
+ * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
+ * @package cake
+ * @subpackage cake.app.config
+ * @since CakePHP(tm) v 0.2.9
+ * @version $Revision: 6305 $
+ * @modifiedby $LastChangedBy: phpnut $
+ * @lastmodified $Date: 2008-01-01 20:33:56 -0600 (Tue, 01 Jan 2008) $
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+/**
+ * If you do not have mod rewrite on your system
+ * or if you prefer to use CakePHP pretty urls.
+ * uncomment the line below.
+ * Note: If you do have mod rewrite but prefer the
+ * CakePHP pretty urls, you also have to remove the
+ * .htaccess files
+ * release/.htaccess
+ * release/app/.htaccess
+ * release/app/webroot/.htaccess
+ */
+// define ('BASE_URL', env('SCRIPT_NAME'));
+/**
+ * Set debug level here:
+ * - 0: production
+ * - 1: development
+ * - 2: full debug with sql
+ * - 3: full debug with sql and dump of the current object
+ *
+ * In production, the "flash messages" redirect after a time interval.
+ * With the other debug levels you get to click the "flash message" to continue.
+ *
+ */
+ define('DEBUG', 1);
+/**
+ * Turn of caching checking wide.
+ * You must still use the controller var cacheAction inside you controller class.
+ * You can either set it controller wide, or in each controller method.
+ * use var $cacheAction = true; or in the controller method $this->cacheAction = true;
+ */
+ define('CACHE_CHECK', false);
+/**
+ * Error constant. Used for differentiating error logging and debugging.
+ * Currently PHP supports LOG_DEBUG
+ */
+ define('LOG_ERROR', 2);
+/**
+ * CakePHP includes 3 types of session saves
+ * database or file. Set this to your preferred method.
+ * If you want to use your own save handler place it in
+ * app/config/name.php DO NOT USE file or database as the name.
+ * and use just the name portion below.
+ *
+ * Setting this to cake will save files to /cakedistro/tmp directory
+ * Setting it to php will use the php default save path
+ * Setting it to database will use the database
+ *
+ */
+ define('CAKE_SESSION_SAVE', 'php');
+/**
+ * If using you own table name for storing sessions
+ * set the table name here.
+ * DO NOT INCLUDE PREFIX IF YOU HAVE SET ONE IN database.php
+ *
+ */
+ define('CAKE_SESSION_TABLE', 'cake_sessions');
+/**
+ * Set a random string of used in session.
+ *
+ */
+ define('CAKE_SESSION_STRING', 'DYhG93b0qyJfIxfs2guVoUubWwvniR2G0FgaC9mi');
+/**
+ * Set the name of session cookie
+ *
+ */
+ define('CAKE_SESSION_COOKIE', 'CAKEPHP');
+/**
+ * Set level of Cake security.
+ *
+ */
+ define('CAKE_SECURITY', 'high');
+/**
+ * Set Cake Session time out.
+ * If CAKE_SECURITY define is set
+ * high: multiplied by 10
+ * medium: is multiplied by 100
+ * low is: multiplied by 300
+ *
+ * Number below is seconds.
+ */
+ define('CAKE_SESSION_TIMEOUT', '120');
+/**
+ * Uncomment the define below to use cake built in admin routes.
+ * You can set this value to anything you want.
+ * All methods related to the admin route should be prefixed with the
+ * name you set CAKE_ADMIN to.
+ * For example: admin_index, admin_edit
+ */
+// define('CAKE_ADMIN', 'admin');
+/**
+ * The define below is used to turn cake built webservices
+ * on or off. Default setting is off.
+ */
+ define('WEBSERVICES', 'off');
+/**
+ * Compress output CSS (removing comments, whitespace, repeating tags etc.)
+ * This requires a/var/cache directory to be writable by the web server (caching).
+ * To use, prefix the CSS link URL with '/ccss/' instead of '/css/' or use Controller::cssTag().
+ */
+ define('COMPRESS_CSS', false);
+/**
+ * If set to true, helpers would output data instead of returning it.
+ */
+ define('AUTO_OUTPUT', false);
+/**
+ * If set to false, session would not automatically be started.
+ */
+ define('AUTO_SESSION', true);
+/**
+ * Set the max size of file to use md5() .
+ */
+ define('MAX_MD5SIZE', (5 * 1024) * 1024);
+/**
+ * To use Access Control Lists with Cake...
+ */
+ define('ACL_CLASSNAME', 'DB_ACL');
+ define('ACL_FILENAME', 'dbacl' . DS . 'db_acl');
+?> \ No newline at end of file
diff --git a/site/cake/scripts/templates/skel/config/database.php.default b/site/cake/scripts/templates/skel/config/database.php.default
new file mode 100644
index 0000000..a13556b
--- /dev/null
+++ b/site/cake/scripts/templates/skel/config/database.php.default
@@ -0,0 +1,74 @@
+<?php
+/* SVN FILE: $Id: database.php.default 6305 2008-01-02 02:33:56Z phpnut $ */
+/**
+ * This is core configuration file.
+ *
+ * Use it to configure core behaviour ofCake.
+ *
+ * PHP versions 4 and 5
+ *
+ * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
+ * Copyright 2005-2008, Cake Software Foundation, Inc.
+ * 1785 E. Sahara Avenue, Suite 490-204
+ * Las Vegas, Nevada 89104
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
+ * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
+ * @package cake
+ * @subpackage cake.app.config
+ * @since CakePHP(tm) v 0.2.9
+ * @version $Revision: 6305 $
+ * @modifiedby $LastChangedBy: phpnut $
+ * @lastmodified $Date: 2008-01-01 20:33:56 -0600 (Tue, 01 Jan 2008) $
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+/**
+ * In this file you set up your database connection details.
+ *
+ * @package cake
+ * @subpackage cake.config
+ */
+/**
+ * Database configuration class.
+ * You can specify multiple configurations for production, development and testing.
+ *
+ * driver =>
+ * mysql, postgres, sqlite, adodb-drivername, pear-drivername
+ *
+ * connect =>
+ * MySQL set the connect to either mysql_pconnect of mysql_connect
+ * PostgreSQL set the connect to either pg_pconnect of pg_connect
+ * SQLite set the connect to sqlite_popen sqlite_open
+ * ADOdb set the connect to one of these
+ * (http://phplens.com/adodb/supported.databases.html) and
+ * append it '|p' for persistent connection. (mssql|p for example, or just mssql for not persistent)
+ *
+ * host =>
+ * the host you connect to the database
+ * MySQL 'localhost' to add a port number use 'localhost:port#'
+ * PostgreSQL 'localhost' to add a port number use 'localhost port=5432'
+ *
+ */
+class DATABASE_CONFIG
+{
+ var $default = array('driver' => 'mysql',
+ 'connect' => 'mysql_connect',
+ 'host' => 'localhost',
+ 'login' => 'user',
+ 'password' => 'password',
+ 'database' => 'project_name',
+ 'prefix' => '');
+
+ var $test = array('driver' => 'mysql',
+ 'connect' => 'mysql_connect',
+ 'host' => 'localhost',
+ 'login' => 'user',
+ 'password' => 'password',
+ 'database' => 'project_name-test',
+ 'prefix' => '');
+}
+?> \ No newline at end of file
diff --git a/site/cake/scripts/templates/skel/config/inflections.php b/site/cake/scripts/templates/skel/config/inflections.php
new file mode 100644
index 0000000..e6ae0b1
--- /dev/null
+++ b/site/cake/scripts/templates/skel/config/inflections.php
@@ -0,0 +1,72 @@
+<?php
+/* SVN FILE: $Id: inflections.php 6305 2008-01-02 02:33:56Z phpnut $ */
+/**
+ * Custom Inflected Words.
+ *
+ * This file is used to hold words that are not matched in the normail Inflector::pluralize() and
+ * Inflector::singularize()
+ *
+ * PHP versions 4 and %
+ *
+ * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
+ * Copyright 2005-2008, Cake Software Foundation, Inc.
+ * 1785 E. Sahara Avenue, Suite 490-204
+ * Las Vegas, Nevada 89104
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
+ * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
+ * @package cake
+ * @subpackage cake.app.config
+ * @since CakePHP(tm) v 1.0.0.2312
+ * @version $Revision: 6305 $
+ * @modifiedby $LastChangedBy: phpnut $
+ * @lastmodified $Date: 2008-01-01 20:33:56 -0600 (Tue, 01 Jan 2008) $
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+/**
+ * This is a key => value array of regex used to match words.
+ * If key matches then the value is returned.
+ *
+ * $pluralRules = array('/(s)tatus$/i' => '\1\2tatuses', '/^(ox)$/i' => '\1\2en', '/([m|l])ouse$/i' => '\1ice');
+ */
+ $pluralRules = array();
+/**
+ * This is a key only array of plural words that should not be inflected.
+ * Notice the last comma
+ *
+ * $uninflectedPlural = array('.*[nrlm]ese', '.*deer', '.*fish', '.*measles', '.*ois', '.*pox');
+ */
+ $uninflectedPlural = array();
+/**
+ * This is a key => value array of plural irregular words.
+ * If key matches then the value is returned.
+ *
+ * $irregularPlural = array('atlas' => 'atlases', 'beef' => 'beefs', 'brother' => 'brothers')
+ */
+ $irregularPlural = array();
+/**
+ * This is a key => value array of regex used to match words.
+ * If key matches then the value is returned.
+ *
+ * $singularRules = array('/(s)tatuses$/i' => '\1\2tatus', '/(matr)ices$/i' =>'\1ix','/(vert|ind)ices$/i')
+ */
+ $singularRules = array();
+/**
+ * This is a key only array of singular words that should not be inflected.
+ * You should not have to change this value below if you do change it use same format
+ * as the $uninflectedPlural above.
+ */
+ $uninflectedSingular = $uninflectedPlural;
+/**
+ * This is a key => value array of singular irregular words.
+ * Most of the time this will be a reverse of the above $irregularPlural array
+ * You should not have to change this value below if you do change it use same format
+ *
+ * $irregularSingular = array('atlases' => 'atlas', 'beefs' => 'beef', 'brothers' => 'brother')
+ */
+ $irregularSingular = array_flip($irregularPlural);
+?> \ No newline at end of file
diff --git a/site/cake/scripts/templates/skel/config/routes.php b/site/cake/scripts/templates/skel/config/routes.php
new file mode 100644
index 0000000..a6b0fb6
--- /dev/null
+++ b/site/cake/scripts/templates/skel/config/routes.php
@@ -0,0 +1,46 @@
+<?php
+/* SVN FILE: $Id: routes.php 6305 2008-01-02 02:33:56Z phpnut $ */
+/**
+ * Short description for file.
+ *
+ * In this file, you set up routes to your controllers and their actions.
+ * Routes are very important mechanism that allows you to freely connect
+ * different urls to chosen controllers and their actions (functions).
+ *
+ * PHP versions 4 and 5
+ *
+ * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
+ * Copyright 2005-2008, Cake Software Foundation, Inc.
+ * 1785 E. Sahara Avenue, Suite 490-204
+ * Las Vegas, Nevada 89104
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
+ * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
+ * @package cake
+ * @subpackage cake.app.config
+ * @since CakePHP(tm) v 0.2.9
+ * @version $Revision: 6305 $
+ * @modifiedby $LastChangedBy: phpnut $
+ * @lastmodified $Date: 2008-01-01 20:33:56 -0600 (Tue, 01 Jan 2008) $
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+/**
+ * Here, we are connecting '/' (base path) to controller called 'Pages',
+ * its action called 'display', and we pass a param to select the view file
+ * to use (in this case, /app/views/pages/home.thtml)...
+ */
+ $Route->connect('/', array('controller' => 'pages', 'action' => 'display', 'home'));
+/**
+ * ...and connect the rest of 'Pages' controller's urls.
+ */
+ $Route->connect('/pages/*', array('controller' => 'pages', 'action' => 'display'));
+/**
+ * Then we connect url '/test' to our test controller. This is helpfull in
+ * developement.
+ */
+ $Route->connect('/tests', array('controller' => 'tests', 'action' => 'index'));
+?> \ No newline at end of file
diff --git a/site/cake/scripts/templates/skel/config/sql/db_acl.sql b/site/cake/scripts/templates/skel/config/sql/db_acl.sql
new file mode 100644
index 0000000..8c7aae8
--- /dev/null
+++ b/site/cake/scripts/templates/skel/config/sql/db_acl.sql
@@ -0,0 +1,30 @@
+CREATE TABLE `acos` (
+ `id` int(11) NOT NULL auto_increment,
+ `model` varchar(255) NOT NULL default '',
+ `object_id` int(11) default NULL,
+ `alias` varchar(255) NOT NULL default '',
+ `lft` int(11) default NULL,
+ `rght` int(11) default NULL,
+ PRIMARY KEY (`id`)
+);
+
+CREATE TABLE `aros` (
+ `id` int(11) NOT NULL auto_increment,
+ `model` varchar(255) NOT NULL default '',
+ `user_id` int(11) default NULL,
+ `alias` varchar(255) NOT NULL default '',
+ `lft` int(11) default NULL,
+ `rght` int(11) default NULL,
+ PRIMARY KEY (`id`)
+);
+
+CREATE TABLE `aros_acos` (
+ `id` int(11) NOT NULL auto_increment,
+ `aro_id` int(11) default NULL,
+ `aco_id` int(11) default NULL,
+ `_create` int(1) NOT NULL default '0',
+ `_read` int(1) NOT NULL default '0',
+ `_update` int(1) NOT NULL default '0',
+ `_delete` int(11) NOT NULL default '0',
+ PRIMARY KEY (`id`)
+);
diff --git a/site/cake/scripts/templates/skel/config/sql/sessions.sql b/site/cake/scripts/templates/skel/config/sql/sessions.sql
new file mode 100644
index 0000000..7166ae4
--- /dev/null
+++ b/site/cake/scripts/templates/skel/config/sql/sessions.sql
@@ -0,0 +1,11 @@
+-- @copyright Copyright 2005-2007, Cake Software Foundation, Inc.
+-- @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
+-- @since CakePHP v 0.10.8.1997
+-- @version $Revision: 4409 $
+
+CREATE TABLE cake_sessions (
+ id varchar(255) NOT NULL default '',
+ data text,
+ expires int(11) default NULL,
+ PRIMARY KEY (id)
+); \ No newline at end of file
diff --git a/site/cake/scripts/templates/skel/controllers/pages_controller.php b/site/cake/scripts/templates/skel/controllers/pages_controller.php
new file mode 100644
index 0000000..5877f16
--- /dev/null
+++ b/site/cake/scripts/templates/skel/controllers/pages_controller.php
@@ -0,0 +1,105 @@
+<?php
+/* SVN FILE: $Id: pages_controller.php 6305 2008-01-02 02:33:56Z phpnut $ */
+
+/**
+ * Short description for file.
+ *
+ * This file is application-wide controller file. You can put all
+ * application-wide controller-related methods here.
+ *
+ * PHP versions 4 and 5
+ *
+ * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
+ * Copyright 2005-2008, Cake Software Foundation, Inc.
+ * 1785 E. Sahara Avenue, Suite 490-204
+ * Las Vegas, Nevada 89104
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
+ * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
+ * @package cake
+ * @subpackage cake.app.controllers
+ * @since CakePHP(tm) v 0.2.9
+ * @version $Revision: 6305 $
+ * @modifiedby $LastChangedBy: phpnut $
+ * @lastmodified $Date: 2008-01-01 20:33:56 -0600 (Tue, 01 Jan 2008) $
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+
+/**
+ * Short description for class.
+ *
+ * This file is application-wide controller file. You can put all
+ * application-wide controller-related methods here.
+ *
+ * Add your application-wide methods in the class below, your controllers
+ * will inherit them.
+ *
+ * @package cake
+ * @subpackage cake.app.controllers
+ */
+class PagesController extends AppController{
+
+/**
+ * Enter description here...
+ *
+ * @var unknown_type
+ */
+ var $name = 'Pages';
+
+/**
+ * Enter description here...
+ *
+ * @var unknown_type
+ */
+ var $helpers = array('Html');
+
+/**
+ * This controller does not use a model
+ *
+ * @var $uses
+ */
+ var $uses = null;
+
+/**
+ * Displays a view
+ *
+ */
+ function display() {
+ if (!func_num_args()) {
+ $this->redirect('/');
+ }
+
+ $path=func_get_args();
+
+ if (!count($path)) {
+ $this->redirect('/');
+ }
+
+ $count =count($path);
+ $page =null;
+ $subpage=null;
+ $title =null;
+
+ if (!empty($path[0])) {
+ $page = $path[0];
+ }
+
+ if (!empty($path[1])) {
+ $subpage = $path[1];
+ }
+
+ if (!empty($path[$count - 1])) {
+ $title = ucfirst($path[$count - 1]);
+ }
+
+ $this->set('page', $page);
+ $this->set('subpage', $subpage);
+ $this->set('title', $title);
+ $this->render(join('/', $path));
+ }
+}
+?> \ No newline at end of file
diff --git a/site/cake/scripts/templates/skel/index.php b/site/cake/scripts/templates/skel/index.php
new file mode 100644
index 0000000..efb5404
--- /dev/null
+++ b/site/cake/scripts/templates/skel/index.php
@@ -0,0 +1,26 @@
+<?php
+/* SVN FILE: $Id: index.php 6305 2008-01-02 02:33:56Z phpnut $ */
+/**
+ * PHP versions 4 and 5
+ *
+ * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
+ * Copyright 2005-2008, Cake Software Foundation, Inc.
+ * 1785 E. Sahara Avenue, Suite 490-204
+ * Las Vegas, Nevada 89104
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
+ * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
+ * @package cake
+ * @subpackage cake.app
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @version $Revision: 6305 $
+ * @modifiedby $LastChangedBy: phpnut $
+ * @lastmodified $Date: 2008-01-01 20:33:56 -0600 (Tue, 01 Jan 2008) $
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+require 'webroot' . DIRECTORY_SEPARATOR . 'index.php';
+?> \ No newline at end of file
diff --git a/site/cake/scripts/templates/skel/views/layouts/ajax.thtml b/site/cake/scripts/templates/skel/views/layouts/ajax.thtml
new file mode 100644
index 0000000..b88590f
--- /dev/null
+++ b/site/cake/scripts/templates/skel/views/layouts/ajax.thtml
@@ -0,0 +1,30 @@
+<?php
+/* SVN FILE: $Id: ajax.thtml 6305 2008-01-02 02:33:56Z phpnut $ */
+
+/**
+ *
+ *
+ *
+ * PHP versions 4 and 5
+ *
+ * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
+ * Copyright 2005-2008, Cake Software Foundation, Inc.
+ * 1785 E. Sahara Avenue, Suite 490-204
+ * Las Vegas, Nevada 89104
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
+ * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
+ * @package cake
+ * @subpackage cake.cake.libs.view.templates.layouts
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @version $Revision: 6305 $
+ * @modifiedby $LastChangedBy: phpnut $
+ * @lastmodified $Date: 2008-01-01 20:33:56 -0600 (Tue, 01 Jan 2008) $
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+?>
+<?php echo $content_for_layout; ?> \ No newline at end of file
diff --git a/site/cake/scripts/templates/skel/views/layouts/default.thtml b/site/cake/scripts/templates/skel/views/layouts/default.thtml
new file mode 100644
index 0000000..0172200
--- /dev/null
+++ b/site/cake/scripts/templates/skel/views/layouts/default.thtml
@@ -0,0 +1,30 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<title>CakePHP(tm) : <?php echo $title_for_layout;?></title>
+<link rel="icon" href="<?php echo $this->webroot . 'favicon.ico';?>" type="image/x-icon" />
+<link rel="shortcut icon" href="<?php echo $this->webroot . 'favicon.ico';?>" type="image/x-icon" />
+<?php echo $html->css('cake.generic');?>
+</head>
+<body>
+ <div id="container">
+ <div id="header">
+ <h1>CakePHP Rapid Development</h1>
+ </div>
+ <div id="content">
+ <?php if ($session->check('Message.flash'))
+ {
+ $session->flash();
+ }
+ echo $content_for_layout;
+ ?>
+ </div>
+ <div id="footer">
+ &nbsp;
+ <a href="http://www.cakephp.org/" target="_new">
+ <?php echo $html->image('cake.power.png', array('alt'=>"CakePHP(tm) : Rapid Development Framework", 'border'=>"0"));?>
+ </a>
+ </div>
+ </div>
+</body>
+</html> \ No newline at end of file
diff --git a/site/cake/scripts/templates/skel/views/layouts/flash.thtml b/site/cake/scripts/templates/skel/views/layouts/flash.thtml
new file mode 100644
index 0000000..85d1b4c
--- /dev/null
+++ b/site/cake/scripts/templates/skel/views/layouts/flash.thtml
@@ -0,0 +1,50 @@
+<?php
+/* SVN FILE: $Id: flash.thtml 6305 2008-01-02 02:33:56Z phpnut $ */
+
+/**
+ *
+ *
+ *
+ * PHP versions 4 and 5
+ *
+ * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
+ * Copyright 2005-2008, Cake Software Foundation, Inc.
+ * 1785 E. Sahara Avenue, Suite 490-204
+ * Las Vegas, Nevada 89104
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
+ * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
+ * @package cake
+ * @subpackage cake.cake.libs.view.templates.layouts
+ * @since CakePHP(tm) v 0.10.0.1076
+ * @version $Revision: 6305 $
+ * @modifiedby $LastChangedBy: phpnut $
+ * @lastmodified $Date: 2008-01-01 20:33:56 -0600 (Tue, 01 Jan 2008) $
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<title><?php echo $page_title?></title>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+<?php if (Configure::read() == 0) { ?>
+<meta http-equiv="Refresh" content="<?php echo $pause?>;url=<?php echo $url?>"/>
+<?php } ?>
+<style><!--
+P { text-align:center; font:bold 1.1em sans-serif }
+A { color:#444; text-decoration:none }
+A:HOVER { text-decoration: underline; color:#44E }
+--></style>
+</head>
+
+<body>
+
+<p><a href="<?php echo $url?>"><?php echo $message?></a></p>
+
+</body>
+</html> \ No newline at end of file
diff --git a/site/cake/scripts/templates/skel/webroot/.htaccess b/site/cake/scripts/templates/skel/webroot/.htaccess
new file mode 100644
index 0000000..8ca27c0
--- /dev/null
+++ b/site/cake/scripts/templates/skel/webroot/.htaccess
@@ -0,0 +1,6 @@
+<IfModule mod_rewrite.c>
+ RewriteEngine On
+ RewriteCond %{REQUEST_FILENAME} !-d
+ RewriteCond %{REQUEST_FILENAME} !-f
+ RewriteRule ^(.*)$ index.php?url=$1 [QSA,L]
+</IfModule> \ No newline at end of file
diff --git a/site/cake/scripts/templates/skel/webroot/css.php b/site/cake/scripts/templates/skel/webroot/css.php
new file mode 100644
index 0000000..ad86d39
--- /dev/null
+++ b/site/cake/scripts/templates/skel/webroot/css.php
@@ -0,0 +1,100 @@
+<?php
+/* SVN FILE: $Id: css.php 6305 2008-01-02 02:33:56Z phpnut $ */
+/**
+ * Short description for file.
+ *
+ * Long description for file
+ *
+ * PHP versions 4 and 5
+ *
+ * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
+ * Copyright 2005-2008, Cake Software Foundation, Inc.
+ * 1785 E. Sahara Avenue, Suite 490-204
+ * Las Vegas, Nevada 89104
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
+ * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
+ * @package cake
+ * @subpackage cake.app.webroot
+ * @since CakePHP(tm) v 0.2.9
+ * @version $Revision: 6305 $
+ * @modifiedby $LastChangedBy: phpnut $
+ * @lastmodified $Date: 2008-01-01 20:33:56 -0600 (Tue, 01 Jan 2008) $
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+/**
+ * Enter description here...
+ */
+ require(CONFIGS . 'paths.php');
+ require(CAKE . 'basics.php');
+ require(LIBS . 'folder.php');
+ require(LIBS . 'file.php');
+ require(LIBS . 'legacy.php');
+/**
+ * Enter description here...
+ *
+ * @param unknown_type $path
+ * @param unknown_type $name
+ * @return unknown
+ */
+ function make_clean_css($path, $name) {
+ require(VENDORS . 'csspp' . DS . 'csspp.php');
+ $data =file_get_contents($path);
+ $csspp =new csspp();
+ $output=$csspp->compress($data);
+ $ratio =100 - (round(strlen($output) / strlen($data), 3) * 100);
+ $output=" /* file: $name, ratio: $ratio% */ " . $output;
+ return $output;
+ }
+/**
+ * Enter description here...
+ *
+ * @param unknown_type $path
+ * @param unknown_type $content
+ * @return unknown
+ */
+ function write_css_cache($path, $content) {
+ if (!is_dir(dirname($path))) {
+ mkdir(dirname($path));
+ }
+ $cache=new File($path);
+ return $cache->write($content);
+ }
+
+ if (preg_match('|\.\.|', $url) || !preg_match('|^ccss/(.+)$|i', $url, $regs)) {
+ die('Wrong file name.');
+ }
+
+ $filename = 'css/' . $regs[1];
+ $filepath = CSS . $regs[1];
+ $cachepath = CACHE . 'css' . DS . str_replace(array('/','\\'), '-', $regs[1]);
+
+ if (!file_exists($filepath)) {
+ die('Wrong file name.');
+ }
+
+ if (file_exists($cachepath)) {
+ $templateModified=filemtime($filepath);
+ $cacheModified =filemtime($cachepath);
+
+ if ($templateModified > $cacheModified) {
+ $output=make_clean_css($filepath, $filename);
+ write_css_cache($cachepath, $output);
+ } else {
+ $output = file_get_contents($cachepath);
+ }
+ } else {
+ $output=make_clean_css($filepath, $filename);
+ write_css_cache($cachepath, $output);
+ }
+ header("Date: " . date("D, j M Y G:i:s ", $templateModified) . 'GMT');
+ header("Content-Type: text/css");
+ header("Expires: " . gmdate("D, j M Y H:i:s", time() + DAY) . " GMT");
+ header("Cache-Control: cache"); // HTTP/1.1
+ header("Pragma: cache"); // HTTP/1.0
+ print $output;
+?> \ No newline at end of file
diff --git a/site/cake/scripts/templates/skel/webroot/css/cake.generic.css b/site/cake/scripts/templates/skel/webroot/css/cake.generic.css
new file mode 100644
index 0000000..491dc7a
--- /dev/null
+++ b/site/cake/scripts/templates/skel/webroot/css/cake.generic.css
@@ -0,0 +1,251 @@
+*{
+margin:0;
+padding:0;
+}
+
+body{
+font-family:"frutiger linotype","lucida grande",helvetica,arial,sans-serif;
+text-align:center;
+color:#333;
+font-size: 76%;
+}
+
+/* General Style Info */
+a{
+color:#003d4c;
+text-decoration:underline;
+}
+a:hover{
+color:#003d4c;
+text-decoration:none;
+}
+
+a img{
+border:none;
+}
+
+h1, h2, h3, h4{
+font-weight:normal;
+}
+
+h1{
+color: #003d4c;
+margin:0.3em 0;
+font-size: 180%;
+}
+
+h2{
+color:#c6c65b;
+padding-top: 1em;
+margin:0.3em 0;
+font-size: 180%;
+}
+
+h3{
+color:#c6c65b;
+padding-top:2em;
+font-size: 140%;
+}
+
+h4{
+color:#c6c65b;
+padding-top:0.5em;
+font-weight:normal;
+}
+
+em {
+font-size: 12px;
+}
+
+ul, li {
+margin: 0 12px;
+}
+
+/* Layout */
+
+#container{
+text-align:left;
+}
+
+#header{
+margin-top: 1em;
+padding: 4px 20px;
+}
+
+#content{
+clear:both;
+padding: 0px 40px 10px 40px;
+background-color: #fff;
+color: #333;
+}
+#footer{
+clear:both;
+padding: 6px 10px;
+text-align: right;
+}
+
+/* tables */
+
+table {
+width: 100%;
+border-top: 1px solid #ccc;
+border-left: 1px solid #ccc;
+border-bottom: 1px solid #ccc;
+color:#333;
+background-color: #fff;
+clear:both;
+padding: 0;
+margin: 0 0 2em 0;
+white-space: normal;
+}
+th {
+background-color: #e2e2e2;
+border-top: 1px solid #fff;
+border-left: 1px solid #fff;
+border-right: 1px solid #003d4c;
+border-bottom: 1px solid #003d4c;
+text-align: center;
+padding:1px 4px;
+}
+table tr td {
+border-right: 1px solid #ddd;
+padding:4px 4px;
+vertical-align:top;
+text-align: center;
+}
+table tr.altRow td {
+background: #f4f4f4;
+}
+table td.actions {
+ white-space: nowrap;
+}
+#cakeSqlLog td {
+text-align: left;
+padding: 4px 8px;
+background: #fff;
+border-bottom: 2px solid #ccc;
+}
+
+/* scaffold show */
+
+div.related {
+clear:both;
+display:block;
+}
+dl {
+line-height:2em;
+margin:0em 1em;
+float:left;
+width: 400px;
+}
+dt {
+font-weight: bold;
+vertical-align:top;
+}
+dd {
+margin-left:10em;
+margin-top:-2em;
+vertical-align:top;
+}
+
+/* notices and errors */
+
+#flashMessage, .error, .error_message {
+color:#900;
+font-size: 16px;
+background-color: #fff;
+margin: 8px 0px;
+font-weight: bold;
+}
+.error_message {
+clear: both;
+}
+.error em {
+font-size: 18px;
+color: #003d4c;
+}
+.notice {
+color: #656565;
+font-size: 14px;
+background-color: #f4f4f4;
+padding: 0.5em;
+margin: 1em 0;
+display:block;
+}
+.tip {
+color: #656565;
+background-color: #ddd;
+}
+
+/* forms */
+
+form {
+margin-top: 2em;
+}
+form div{
+vertical-align: text-top;
+margin-left: 1em;
+margin-bottom:2em;
+}
+form div.date{
+margin-left: 0em;
+}
+label {
+display: block;
+float:left;
+width: 140px;
+font-size: 14px;
+padding-right: 20px;
+}
+input[type=checkbox] {
+float: left;
+clear: left;
+margin: 2px 6px 7px 2px;
+}
+input, textarea {
+clear: both;
+display:block;
+font-size: 14px;
+font-family: inherit;
+}
+select {
+clear: both;
+vertical-align: text-bottom;
+font-size: 14px;
+font-family: inherit;
+}
+option {
+font-size: 14px;
+font-family: inherit;
+padding: 0 0.3em;
+}
+input[type=submit] {
+display: inline;
+vertical-align: bottom;
+}
+div.required {
+clear: both;
+color:#222;
+font-weight:bold;
+}
+div.optional {
+clear: both;
+color:#555;
+}
+div.submit {
+clear: both;
+margin-top: 40px;
+margin-left: 140px;
+}
+/* action links */
+ul.actions {
+float: left;
+margin-left:20px;
+width: 200px;
+}
+ul.actions li {
+margin-top: 4px;
+}
+pre {
+padding: 1em;
+} \ No newline at end of file
diff --git a/site/cake/scripts/templates/skel/webroot/favicon.ico b/site/cake/scripts/templates/skel/webroot/favicon.ico
new file mode 100644
index 0000000..1bc32bd
--- /dev/null
+++ b/site/cake/scripts/templates/skel/webroot/favicon.ico
Binary files differ
diff --git a/site/cake/scripts/templates/skel/webroot/img/cake.power.png b/site/cake/scripts/templates/skel/webroot/img/cake.power.png
new file mode 100644
index 0000000..699ef80
--- /dev/null
+++ b/site/cake/scripts/templates/skel/webroot/img/cake.power.png
Binary files differ
diff --git a/site/cake/scripts/templates/skel/webroot/index.php b/site/cake/scripts/templates/skel/webroot/index.php
new file mode 100644
index 0000000..5617bd4
--- /dev/null
+++ b/site/cake/scripts/templates/skel/webroot/index.php
@@ -0,0 +1,87 @@
+<?php
+/* SVN FILE: $Id: index.php 6305 2008-01-02 02:33:56Z phpnut $ */
+/**
+ * Short description for file.
+ *
+ * Long description for file
+ *
+ * PHP versions 4 and 5
+ *
+ * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
+ * Copyright 2005-2008, Cake Software Foundation, Inc.
+ * 1785 E. Sahara Avenue, Suite 490-204
+ * Las Vegas, Nevada 89104
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
+ * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
+ * @package cake
+ * @subpackage cake.app.webroot
+ * @since CakePHP(tm) v 0.2.9
+ * @version $Revision: 6305 $
+ * @modifiedby $LastChangedBy: phpnut $
+ * @lastmodified $Date: 2008-01-01 20:33:56 -0600 (Tue, 01 Jan 2008) $
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+/**
+ * Do not change
+ */
+ if (!defined('DS')) {
+ define('DS', DIRECTORY_SEPARATOR);
+ }
+/**
+ * These defines should only be edited if you have cake installed in
+ * a directory layout other than the way it is distributed.
+ * Each define has a commented line of code that explains what you would change.
+ *
+ */
+ if (!defined('ROOT')) {
+ //define('ROOT', 'FULL PATH TO DIRECTORY WHERE APP DIRECTORY IS LOCATED DO NOT ADD A TRAILING DIRECTORY SEPARATOR';
+ //You should also use the DS define to seperate your directories
+ define('ROOT', dirname(dirname(dirname(__FILE__))));
+ }
+ if (!defined('APP_DIR')) {
+ //define('APP_DIR', 'DIRECTORY NAME OF APPLICATION';
+ define('APP_DIR', basename(dirname(dirname(__FILE__))));
+ }
+/**
+ * This only needs to be changed if the cake installed libs are located
+ * outside of the distributed directory structure.
+ */
+ if (!defined('CAKE_CORE_INCLUDE_PATH')) {
+ //define ('CAKE_CORE_INCLUDE_PATH', FULL PATH TO DIRECTORY WHERE CAKE CORE IS INSTALLED DO NOT ADD A TRAILING DIRECTORY SEPARATOR';
+ //You should also use the DS define to seperate your directories
+ define('CAKE_CORE_INCLUDE_PATH', ROOT);
+ }
+///////////////////////////////
+//DO NOT EDIT BELOW THIS LINE//
+///////////////////////////////
+ if (!defined('WEBROOT_DIR')) {
+ define('WEBROOT_DIR', basename(dirname(__FILE__)));
+ }
+ if (!defined('WWW_ROOT')) {
+ define('WWW_ROOT', dirname(__FILE__) . DS);
+ }
+ if (!defined('CORE_PATH')) {
+ if (function_exists('ini_set')) {
+ ini_set('include_path', CAKE_CORE_INCLUDE_PATH . PATH_SEPARATOR . ROOT . DS . APP_DIR . DS . PATH_SEPARATOR . ini_get('include_path'));
+ define('APP_PATH', null);
+ define('CORE_PATH', null);
+ } else {
+ define('APP_PATH', ROOT . DS . APP_DIR . DS);
+ define('CORE_PATH', CAKE_CORE_INCLUDE_PATH . DS);
+ }
+ }
+ require CORE_PATH . 'cake' . DS . 'bootstrap.php';
+ if (isset($_GET['url']) && $_GET['url'] === 'favicon.ico') {
+ } else {
+ $Dispatcher = new Dispatcher();
+ $Dispatcher->dispatch($url);
+ }
+ if (Configure::read() > 0) {
+ echo "<!-- " . round(getMicrotime() - $TIME_START, 4) . "s -->";
+ }
+?> \ No newline at end of file
diff --git a/site/cake/scripts/templates/skel/webroot/js/vendors.php b/site/cake/scripts/templates/skel/webroot/js/vendors.php
new file mode 100644
index 0000000..c85f3a6
--- /dev/null
+++ b/site/cake/scripts/templates/skel/webroot/js/vendors.php
@@ -0,0 +1,43 @@
+<?php
+/* SVN FILE: $Id: vendors.php 6305 2008-01-02 02:33:56Z phpnut $ */
+/**
+ * Short description for file.
+ *
+ * This file includes js vendor-files from /vendor/ directory if they need to
+ * be accessible to the public.
+ *
+ * PHP versions 4 and 5
+ *
+ * CakePHP(tm) : Rapid Development Framework <http://www.cakephp.org/>
+ * Copyright 2005-2008, Cake Software Foundation, Inc.
+ * 1785 E. Sahara Avenue, Suite 490-204
+ * Las Vegas, Nevada 89104
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
+ * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
+ * @package cake
+ * @subpackage cake.app.webroot.js
+ * @since CakePHP(tm) v 0.2.9
+ * @version $Revision: 6305 $
+ * @modifiedby $LastChangedBy: phpnut $
+ * @lastmodified $Date: 2008-01-01 20:33:56 -0600 (Tue, 01 Jan 2008) $
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+/**
+ * Enter description here...
+ */
+$file = $_GET['file'];
+$pos = strpos($file, '..');
+if ($pos === false) {
+ if (is_file('../../vendors/javascript/'.$file) && (preg_match('/(\/.+)\\.js/', $file)))
+ {
+ readfile('../../vendors/javascript/'.$file);
+ }
+} else {
+ header('HTTP/1.1 404 Not Found');
+}
+?> \ No newline at end of file
diff --git a/site/cake/scripts/templates/views/home.thtml b/site/cake/scripts/templates/views/home.thtml
new file mode 100644
index 0000000..d107e55
--- /dev/null
+++ b/site/cake/scripts/templates/views/home.thtml
@@ -0,0 +1,16 @@
+<?php
+$output = "<p class=\"notice\">Your database configuration file is <?php echo file_exists(CONFIGS.'database.php') ?' present.' . \$filePresent = ' ' : ' not present.'; ?></p>\n";
+$output .= "<?php if (!empty(\$filePresent)):?>\n";
+$output .= "<?php uses('model' . DS . 'connection_manager'); \$db = ConnectionManager::getInstance(); ?>\n";
+$output .= "<?php \$connected = \$db->getDataSource('default'); ?>\n";
+$output .= "<p class=\"notice\">Cake<?php echo \$connected->isConnected() ? ' is able to' : ' is not able to';?> connect to the database.</p>\n";
+$output .= "<br />\n";
+$output .= "<?php endif; ?>\n";
+$output .= "<h1>Sweet, \"".Inflector::humanize($app)."\" got Baked by CakePHP!</h1>\n";
+$output .= "<h2>Editing this Page</h2>\n";
+$output .= "<p>\n";
+$output .= "To change the content of this page, edit: ".$dir.DS."views".DS."pages".DS."home.thtml.<br />\n";
+$output .= "To change its layout, edit: ".$dir.DS."views".DS."layouts".DS."default.thtml.<br />\n";
+$output .= "You can also add some CSS styles for your pages at: ".$dir.DS."webroot/css/.\n";
+$output .= "</p>\n";
+?> \ No newline at end of file
diff --git a/site/index.php b/site/index.php
new file mode 100644
index 0000000..396ddf7
--- /dev/null
+++ b/site/index.php
@@ -0,0 +1,77 @@
+<?php
+/* SVN FILE: $Id: index.php 2951 2006-05-25 22:12:33Z phpnut $ */
+/**
+ * Requests collector.
+ *
+ * This file collects requests if:
+ * - no mod_rewrite is avilable or .htaccess files are not supported
+ * -/public is not set as a web root.
+ *
+ * PHP versions 4 and 5
+ *
+ * CakePHP : Rapid Development Framework <http://www.cakephp.org/>
+ * Copyright (c) 2006, Cake Software Foundation, Inc.
+ * 1785 E. Sahara Avenue, Suite 490-204
+ * Las Vegas, Nevada 89104
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright Copyright (c) 2006, Cake Software Foundation, Inc.
+ * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP Project
+ * @package cake
+ * @since CakePHP v 0.2.9
+ * @version $Revision: 2951 $
+ * @modifiedby $LastChangedBy: phpnut $
+ * @lastmodified $Date: 2006-05-25 17:12:33 -0500 (Thu, 25 May 2006) $
+ * @license http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+/**
+ * Get Cake's root directory
+ */
+ define('APP_DIR', 'app');
+ define('DS', DIRECTORY_SEPARATOR);
+ define('ROOT', dirname(__FILE__));
+ define('WEBROOT_DIR', 'webroot');
+ define('WWW_ROOT', ROOT . DS . APP_DIR . DS . WEBROOT_DIR . DS);
+/**
+ * This only needs to be changed if the cake installed libs are located
+ * outside of the distributed directory structure.
+ */
+ if (!defined('CAKE_CORE_INCLUDE_PATH')) {
+ //define ('CAKE_CORE_INCLUDE_PATH', FULL PATH TO DIRECTORY WHERE CAKE CORE IS INSTALLED DO NOT ADD A TRAILING DIRECTORY SEPARATOR';
+ define('CAKE_CORE_INCLUDE_PATH', ROOT);
+ }
+ if (function_exists('ini_set')) {
+ ini_set('include_path', ini_get('include_path') . PATH_SEPARATOR . CAKE_CORE_INCLUDE_PATH . PATH_SEPARATOR . ROOT . DS . APP_DIR . DS);
+ define('APP_PATH', null);
+ define('CORE_PATH', null);
+ } else {
+ define('APP_PATH', ROOT . DS . APP_DIR . DS);
+ define('CORE_PATH', CAKE_CORE_INCLUDE_PATH . DS);
+ }
+ require CORE_PATH . 'cake' . DS . 'basics.php';
+ require APP_PATH . 'config' . DS . 'core.php';
+ require CORE_PATH . 'cake' . DS . 'config' . DS . 'paths.php';
+ $bootstrap=true;
+ $uri =setUri();
+/**
+ * As mod_rewrite (or .htaccess files) is not working, we need to take care
+ * of what would normally be rewritten, i.e. the static files in app/webroot/
+ */
+ if ($uri === '/' || $uri === '/index.php') {
+ $_GET['url'] = '/';
+ require APP_DIR . DS . WEBROOT_DIR . DS . 'index.php';
+ } else {
+ $elements=explode('/index.php', $uri);
+
+ if (!empty($elements[1])) {
+ $path = $elements[1];
+ } else {
+ $path = '/';
+ }
+ $_GET['url']=$path;
+ require APP_DIR . DS . WEBROOT_DIR . DS . 'index.php';
+ }
+?> \ No newline at end of file
diff --git a/site/vendors/facebook/facebook.php b/site/vendors/facebook/facebook.php
new file mode 100644
index 0000000..fd1d515
--- /dev/null
+++ b/site/vendors/facebook/facebook.php
@@ -0,0 +1,243 @@
+<?php
+//
+// +---------------------------------------------------------------------------+
+// | Facebook Platform PHP5 client |
+// +---------------------------------------------------------------------------+
+// | Copyright (c) 2007 Facebook, Inc. |
+// | 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. |
+// | |
+// | THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. |
+// +---------------------------------------------------------------------------+
+// | For help with this library, contact developers-help@facebook.com |
+// +---------------------------------------------------------------------------+
+//
+
+include_once 'facebookapi_php5_restlib.php';
+
+class Facebook {
+ public $api_client;
+
+ public $api_key;
+ public $secret;
+
+ public $fb_params;
+ public $user;
+
+ public function __construct($api_key, $secret) {
+ $this->api_key = $api_key;
+ $this->secret = $secret;
+
+ $this->api_client = new FacebookRestClient($api_key, $secret);
+
+ $this->validate_fb_params();
+ if (isset($this->fb_params['friends'])) {
+ $this->api_client->friends_list = explode(',', $this->fb_params['friends']);
+ }
+ if (isset($this->fb_params['added'])) {
+ $this->api_client->added = $this->fb_params['added'];
+ }
+ }
+
+ public function validate_fb_params() {
+ $this->fb_params = $this->get_valid_fb_params($_POST, 48*3600, 'fb_sig');
+ if (!$this->fb_params) {
+ $this->fb_params = $this->get_valid_fb_params($_GET, 48*3600, 'fb_sig');
+ }
+ if ($this->fb_params) {
+ // If we got any fb_params passed in at all, then either:
+ // - they included an fb_user / fb_session_key, which we should assume to be correct
+ // - they didn't include an fb_user / fb_session_key, which means the user doesn't have a
+ // valid session and if we want to get one we'll need to use require_login(). (Calling
+ // set_user with null values for user/session_key will work properly.)
+ // Note that we should *not* use our cookies in this scenario, since they may be referring to
+ // the wrong user.
+ $user = isset($this->fb_params['user']) ? $this->fb_params['user'] : null;
+ $session_key = isset($this->fb_params['session_key']) ? $this->fb_params['session_key'] : null;
+ $expires = isset($this->fb_params['expires']) ? $this->fb_params['expires'] : null;
+ $this->set_user($user, $session_key, $expires);
+ } else if (!empty($_COOKIE) && $cookies = $this->get_valid_fb_params($_COOKIE, null, $this->api_key)) {
+ // use $api_key . '_' as a prefix for the cookies in case there are
+ // multiple facebook clients on the same domain.
+ $this->set_user($cookies['user'], $cookies['session_key']);
+ } else if (isset($_GET['auth_token']) && $session = $this->do_get_session($_GET['auth_token'])) {
+ $this->set_user($session['uid'], $session['session_key'], $session['expires']);
+ }
+
+ return !empty($this->fb_params);
+ }
+
+ public function do_get_session($auth_token) {
+ try {
+ return $this->api_client->auth_getSession($auth_token);
+ } catch (FacebookRestClientException $e) {
+ // API_EC_PARAM means we don't have a logged in user, otherwise who
+ // knows what it means, so just throw it.
+ if ($e->getCode() != FacebookAPIErrorCodes::API_EC_PARAM) {
+ throw $e;
+ }
+ }
+ }
+
+ public function redirect($url) {
+ if ($this->in_fb_canvas()) {
+ echo '<fb:redirect url="' . $url . '"/>';
+ } else if (preg_match('/^https?:\/\/([^\/]*\.)?facebook\.com(:\d+)?/i', $url)) {
+ // make sure facebook.com url's load in the full frame so that we don't
+ // get a frame within a frame.
+ echo "<script type=\"text/javascript\">\ntop.location.href = \"$url\";\n</script>";
+ } else {
+ header('Location: ' . $url);
+ }
+ exit;
+ }
+
+ public function in_frame() {
+ return isset($this->fb_params['in_canvas']) || isset($this->fb_params['in_iframe']);
+ }
+ public function in_fb_canvas() {
+ return isset($this->fb_params['in_canvas']);
+ }
+
+ public function get_loggedin_user() {
+ return $this->user;
+ }
+
+ public static function current_url() {
+ return 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
+ }
+
+ public function require_login() {
+ if ($user = $this->get_loggedin_user()) {
+ return $user;
+ }
+ $this->redirect($this->get_login_url(self::current_url(), $this->in_frame()));
+ }
+
+ public function require_install() {
+ // this was renamed, keeping for compatibility's sake
+ return $this->require_add();
+ }
+
+ public function require_add() {
+ if ($user = $this->get_loggedin_user()) {
+ if ($this->fb_params['added']) {
+ return $user;
+ }
+ }
+ $this->redirect($this->get_add_url(self::current_url()));
+ }
+
+ public function require_frame() {
+ if (!$this->in_frame()) {
+ $this->redirect($this->get_login_url(self::current_url(), true));
+ }
+ }
+
+ public static function get_facebook_url($subdomain='www') {
+ return 'http://' . $subdomain . '.facebook.com';
+ }
+
+ public function get_install_url($next=null) {
+ // this was renamed, keeping for compatibility's sake
+ return $this->get_add_url($next);
+ }
+
+ public function get_add_url($next=null) {
+ return self::get_facebook_url().'/add.php?api_key='.$this->api_key .
+ ($next ? '&next=' . urlencode($next) : '');
+ }
+
+ public function get_login_url($next, $canvas) {
+ return self::get_facebook_url().'/login.php?v=1.0&api_key=' . $this->api_key .
+ ($next ? '&next=' . urlencode($next) : '') .
+ ($canvas ? '&canvas' : '');
+ }
+
+ public static function generate_sig($params_array, $secret) {
+ $str = '';
+
+ ksort($params_array);
+ // Note: make sure that the signature parameter is not already included in
+ // $params_array.
+ foreach ($params_array as $k=>$v) {
+ $str .= "$k=$v";
+ }
+ $str .= $secret;
+
+ return md5($str);
+ }
+
+ public function set_user($user, $session_key, $expires=null) {
+ if (!$this->in_fb_canvas() && (!isset($_COOKIE[$this->api_key . '_user'])
+ || $_COOKIE[$this->api_key . '_user'] != $user)) {
+ $cookies = array();
+ $cookies['user'] = $user;
+ $cookies['session_key'] = $session_key;
+ $sig = self::generate_sig($cookies, $this->secret);
+ foreach ($cookies as $name => $val) {
+ setcookie($this->api_key . '_' . $name, $val, (int)$expires);
+ $_COOKIE[$this->api_key . '_' . $name] = $val;
+ }
+ setcookie($this->api_key, $sig, (int)$expires);
+ $_COOKIE[$this->api_key] = $sig;
+ }
+ $this->user = $user;
+ $this->api_client->session_key = $session_key;
+ }
+
+ /**
+ * Tries to undo the badness of magic quotes as best we can
+ * @param string $val Should come directly from $_GET, $_POST, etc.
+ * @return string val without added slashes
+ */
+ public static function no_magic_quotes($val) {
+ if (get_magic_quotes_gpc()) {
+ return stripslashes($val);
+ } else {
+ return $val;
+ }
+ }
+
+ public function get_valid_fb_params($params, $timeout=null, $namespace='fb_sig') {
+ $prefix = $namespace . '_';
+ $prefix_len = strlen($prefix);
+ $fb_params = array();
+ foreach ($params as $name => $val) {
+ if (strpos($name, $prefix) === 0) {
+ $fb_params[substr($name, $prefix_len)] = self::no_magic_quotes($val);
+ }
+ }
+ if ($timeout && (!isset($fb_params['time']) || time() - $fb_params['time'] > $timeout)) {
+ return array();
+ }
+ if (!isset($params[$namespace]) || !$this->verify_signature($fb_params, $params[$namespace])) {
+ return array();
+ }
+ return $fb_params;
+ }
+
+ public function verify_signature($fb_params, $expected_sig) {
+ return self::generate_sig($fb_params, $this->secret) == $expected_sig;
+ }
+}
+
+?>
diff --git a/site/vendors/facebook/facebookapi_php5_restlib.php b/site/vendors/facebook/facebookapi_php5_restlib.php
new file mode 100644
index 0000000..9ff6532
--- /dev/null
+++ b/site/vendors/facebook/facebookapi_php5_restlib.php
@@ -0,0 +1,1553 @@
+<?php
+//
+// +---------------------------------------------------------------------------+
+// | Facebook Platform PHP5 client |
+// +---------------------------------------------------------------------------+
+// | Copyright (c) 2007 Facebook, Inc. |
+// | 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. |
+// | |
+// | THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. |
+// +---------------------------------------------------------------------------+
+// | For help with this library, contact developers-help@facebook.com |
+// +---------------------------------------------------------------------------+
+//
+
+class FacebookRestClient {
+ public $secret;
+ public $session_key;
+ public $api_key;
+ public $friends_list; // to save making the friends.get api call, this will get prepopulated on canvas pages
+ public $added; // to save making the users.isAppAdded api call, this will get prepopulated on canvas pages
+
+ /**
+ * Create the client.
+ * @param string $session_key if you haven't gotten a session key yet, leave
+ * this as null and then set it later by just
+ * directly accessing the $session_key member
+ * variable.
+ */
+ public function __construct($api_key, $secret, $session_key=null) {
+ $this->secret = $secret;
+ $this->session_key = $session_key;
+ $this->api_key = $api_key;
+ $this->last_call_id = 0;
+ $this->server_addr = Facebook::get_facebook_url('api') . '/restserver.php';
+ if (!empty($GLOBALS['facebook_config']['debug'])) {
+ $this->cur_id = 0;
+ ?>
+<script type="text/javascript">
+var types = ['params', 'xml', 'php', 'sxml'];
+function toggleDisplay(id, type) {
+ for each (var t in types) {
+ if (t != type || document.getElementById(t + id).style.display == 'block') {
+ document.getElementById(t + id).style.display = 'none';
+ } else {
+ document.getElementById(t + id).style.display = 'block';
+ }
+ }
+ return false;
+}
+</script>
+<?php
+ }
+ }
+
+ /**
+ * Returns the session information available after current user logs in.
+ * @param string $auth_token the token returned by auth_createToken or
+ * passed back to your callback_url.
+ * @return assoc array containing session_key, uid
+ */
+ public function auth_getSession($auth_token) {
+ $result = $this->call_method('facebook.auth.getSession', array('auth_token'=>$auth_token));
+ $this->session_key = $result['session_key'];
+ if (isset($result['secret']) && $result['secret']) {
+ // desktop apps have a special secret
+ $this->secret = $result['secret'];
+ }
+ return $result;
+ }
+
+ /**
+ * Returns events according to the filters specified.
+ * @param int $uid Optional: User associated with events.
+ * A null parameter will default to the session user.
+ * @param array $eids Optional: Filter by these event ids.
+ * A null parameter will get all events for the user.
+ * @param int $start_time Optional: Filter with this UTC as lower bound.
+ * A null or zero parameter indicates no lower bound.
+ * @param int $end_time Optional: Filter with this UTC as upper bound.
+ * A null or zero parameter indicates no upper bound.
+ * @param string $rsvp_status Optional: Only show events where the given uid
+ * has this rsvp status. This only works if you have specified a value for
+ * $uid. Values are as in events.getMembers. Null indicates to ignore
+ * rsvp status when filtering.
+ * @return array of events
+ */
+ public function events_get($uid, $eids, $start_time, $end_time, $rsvp_status) {
+ return $this->call_method('facebook.events.get',
+ array(
+ 'uid' => $uid,
+ 'eids' => $eids,
+ 'start_time' => $start_time,
+ 'end_time' => $end_time,
+ 'rsvp_status' => $rsvp_status));
+ }
+
+ /**
+ * Returns membership list data associated with an event
+ * @param int $eid : event id
+ * @return assoc array of four membership lists, with keys 'attending',
+ * 'unsure', 'declined', and 'not_replied'
+ */
+ public function events_getMembers($eid) {
+ return $this->call_method('facebook.events.getMembers',
+ array('eid' => $eid));
+ }
+
+ /**
+ * Makes an FQL query. This is a generalized way of accessing all the data
+ * in the API, as an alternative to most of the other method calls. More
+ * info at http://developers.facebook.com/documentation.php?v=1.0&doc=fql
+ * @param string $query the query to evaluate
+ * @return generalized array representing the results
+ */
+ public function fql_query($query) {
+ return $this->call_method('facebook.fql.query',
+ array('query' => $query));
+ }
+
+ public function feed_publishStoryToUser($title, $body,
+ $image_1=null, $image_1_link=null,
+ $image_2=null, $image_2_link=null,
+ $image_3=null, $image_3_link=null,
+ $image_4=null, $image_4_link=null) {
+ return $this->call_method('facebook.feed.publishStoryToUser',
+ array('title' => $title,
+ 'body' => $body,
+ 'image_1' => $image_1,
+ 'image_1_link' => $image_1_link,
+ 'image_2' => $image_2,
+ 'image_2_link' => $image_2_link,
+ 'image_3' => $image_3,
+ 'image_3_link' => $image_3_link,
+ 'image_4' => $image_4,
+ 'image_4_link' => $image_4_link));
+ }
+
+ public function feed_publishActionOfUser($title, $body,
+ $image_1=null, $image_1_link=null,
+ $image_2=null, $image_2_link=null,
+ $image_3=null, $image_3_link=null,
+ $image_4=null, $image_4_link=null) {
+ return $this->call_method('facebook.feed.publishActionOfUser',
+ array('title' => $title,
+ 'body' => $body,
+ 'image_1' => $image_1,
+ 'image_1_link' => $image_1_link,
+ 'image_2' => $image_2,
+ 'image_2_link' => $image_2_link,
+ 'image_3' => $image_3,
+ 'image_3_link' => $image_3_link,
+ 'image_4' => $image_4,
+ 'image_4_link' => $image_4_link));
+ }
+
+ public function feed_publishTemplatizedAction($actor_id, $title_template, $title_data,
+ $body_template, $body_data, $body_general,
+ $image_1=null, $image_1_link=null,
+ $image_2=null, $image_2_link=null,
+ $image_3=null, $image_3_link=null,
+ $image_4=null, $image_4_link=null,
+ $target_ids='') {
+ return $this->call_method('facebook.feed.publishTemplatizedAction',
+ array('actor_id' => $actor_id,
+ 'title_template' => $title_template,
+ 'title_data' => $title_data,
+ 'body_template' => $body_template,
+ 'body_data' => $body_data,
+ 'body_general' => $body_general,
+ 'image_1' => $image_1,
+ 'image_1_link' => $image_1_link,
+ 'image_2' => $image_2,
+ 'image_2_link' => $image_2_link,
+ 'image_3' => $image_3,
+ 'image_3_link' => $image_3_link,
+ 'image_4' => $image_4,
+ 'image_4_link' => $image_4_link,
+ 'target_ids' => $target_ids));
+ }
+
+ /**
+ * Returns whether or not pairs of users are friends.
+ * Note that the Facebook friend relationship is symmetric.
+ * @param array $uids1: array of ids (id_1, id_2,...) of some length X
+ * @param array $uids2: array of ids (id_A, id_B,...) of SAME length X
+ * @return array of uid pairs with bool, true if pair are friends, e.g.
+ * array( 0 => array('uid1' => id_1, 'uid2' => id_A, 'are_friends' => 1),
+ * 1 => array('uid1' => id_2, 'uid2' => id_B, 'are_friends' => 0)
+ * ...)
+ */
+ public function friends_areFriends($uids1, $uids2) {
+ return $this->call_method('facebook.friends.areFriends',
+ array('uids1'=>$uids1, 'uids2'=>$uids2));
+ }
+
+ /**
+ * Returns the friends of the current session user.
+ * @return array of friends
+ */
+ public function friends_get() {
+ if (isset($this->friends_list)) {
+ return $this->friends_list;
+ }
+ return $this->call_method('facebook.friends.get', array());
+ }
+
+ /**
+ * Returns the friends of the session user, who are also users
+ * of the calling application.
+ * @return array of friends
+ */
+ public function friends_getAppUsers() {
+ return $this->call_method('facebook.friends.getAppUsers', array());
+ }
+
+ /**
+ * Returns groups according to the filters specified.
+ * @param int $uid Optional: User associated with groups.
+ * A null parameter will default to the session user.
+ * @param array $gids Optional: group ids to query.
+ * A null parameter will get all groups for the user.
+ * @return array of groups
+ */
+ public function groups_get($uid, $gids) {
+ return $this->call_method('facebook.groups.get',
+ array(
+ 'uid' => $uid,
+ 'gids' => $gids));
+ }
+
+ /**
+ * Returns the membership list of a group
+ * @param int $gid : Group id
+ * @return assoc array of four membership lists, with keys
+ * 'members', 'admins', 'officers', and 'not_replied'
+ */
+ public function groups_getMembers($gid) {
+ return $this->call_method('facebook.groups.getMembers',
+ array('gid' => $gid));
+ }
+
+ /**
+ * Returns the outstanding notifications for the session user.
+ * @return assoc array of
+ * notification count objects for 'messages', 'pokes' and 'shares',
+ * a uid list of 'friend_requests', a gid list of 'group_invites',
+ * and an eid list of 'event_invites'
+ */
+ public function notifications_get() {
+ return $this->call_method('facebook.notifications.get', array());
+ }
+
+ /**
+ * Sends an email notification to the specified user.
+ * @return string url which you should send the logged in user to to finalize the message.
+ */
+ public function notifications_send($to_ids, $notification, $email='') {
+ return $this->call_method('facebook.notifications.send',
+ array('to_ids' => $to_ids, 'notification' => $notification, 'email' => $email));
+ }
+
+ /**
+ * Returns the requested info fields for the requested set of pages
+ * @param array $page_ids an array of page ids
+ * @param array $fields an array of strings describing the info fields desired
+ * @param int $uid Optionally, limit results to pages of which this user is a fan.
+ * @param string type limits results to a particular type of page.
+ * @return array of pages
+ */
+ public function pages_getInfo($page_ids, $fields, $uid, $type) {
+ return $this->call_method('facebook.pages.getInfo', array('page_ids' => $page_ids, 'fields' => $fields, 'uid' => $uid, 'type' => $type));
+ }
+
+ /**
+ * Returns true if logged in user is an admin for the passed page
+ * @param int $page_id target page id
+ * @return boolean
+ */
+ public function pages_isAdmin($page_id) {
+ return $this->call_method('facebook.pages.isAdmin', array('page_id' => $page_id));
+ }
+
+ /**
+ * Returns whether or not the page corresponding to the current session object has the app installed
+ * @return boolean
+ */
+ public function pages_isAppAdded() {
+ if (isset($this->added)) {
+ return $this->added;
+ }
+ return $this->call_method('facebook.pages.isAppAdded', array());
+ }
+
+ /**
+ * Returns true if logged in user is a fan for the passed page
+ * @param int $page_id target page id
+ * @param int $uid user to compare. If empty, the logged in user.
+ * @return bool
+ */
+ public function pages_isFan($page_id, $uid) {
+ return $this->call_method('facebook.pages.isFan', array('page_id' => $page_id, 'uid' => $uid));
+ }
+
+ /**
+ * Returns photos according to the filters specified.
+ * @param int $subj_id Optional: Filter by uid of user tagged in the photos.
+ * @param int $aid Optional: Filter by an album, as returned by
+ * photos_getAlbums.
+ * @param array $pids Optional: Restrict to a list of pids
+ * Note that at least one of these parameters needs to be specified, or an
+ * error is returned.
+ * @return array of photo objects.
+ */
+ public function photos_get($subj_id, $aid, $pids) {
+ return $this->call_method('facebook.photos.get',
+ array('subj_id' => $subj_id, 'aid' => $aid, 'pids' => $pids));
+ }
+
+ /**
+ * Returns the albums created by the given user.
+ * @param int $uid Optional: the uid of the user whose albums you want.
+ * A null value will return the albums of the session user.
+ * @param array $aids Optional: a list of aids to restrict the query.
+ * Note that at least one of the (uid, aids) parameters must be specified.
+ * @returns an array of album objects.
+ */
+ public function photos_getAlbums($uid, $aids) {
+ return $this->call_method('facebook.photos.getAlbums',
+ array('uid' => $uid,
+ 'aids' => $aids));
+ }
+
+ /**
+ * Returns the tags on all photos specified.
+ * @param string $pids : a list of pids to query
+ * @return array of photo tag objects, with include pid, subject uid,
+ * and two floating-point numbers (xcoord, ycoord) for tag pixel location
+ */
+ public function photos_getTags($pids) {
+ return $this->call_method('facebook.photos.getTags',
+ array('pids' => $pids));
+ }
+
+ /**
+ * Returns the requested info fields for the requested set of users
+ * @param array $uids an array of user ids
+ * @param array $fields an array of strings describing the info fields desired
+ * @return array of users
+ */
+ public function users_getInfo($uids, $fields) {
+ return $this->call_method('facebook.users.getInfo', array('uids' => $uids, 'fields' => $fields));
+ }
+
+ /**
+ * Returns the user corresponding to the current session object.
+ * @return integer uid
+ */
+ public function users_getLoggedInUser() {
+ return $this->call_method('facebook.users.getLoggedInUser', array());
+ }
+
+
+ /**
+ * Returns whether or not the user corresponding to the current session object has the app installed
+ * @return boolean
+ */
+ public function users_isAppAdded() {
+ if (isset($this->added)) {
+ return $this->added;
+ }
+ return $this->call_method('facebook.users.isAppAdded', array());
+ }
+
+ /**
+ * Sets the FBML for the profile of the user attached to this session
+ * @param string $markup The FBML that describes the profile presence of this app for the user
+ * @param int $uid The user
+ * @param string $profile Profile FBML
+ * @param string $profile_action Profile action FBML
+ * @param string $mobile_profile Mobile profile FBML
+ * @return array A list of strings describing any compile errors for the submitted FBML
+ */
+ function profile_setFBML($markup, $uid = null, $profile='', $profile_action='', $mobile_profile='') {
+ return $this->call_method('facebook.profile.setFBML', array('markup' => $markup,
+ 'uid' => $uid,
+ 'profile' => $profile,
+ 'profile_action' => $profile_action,
+ 'mobile_profile' => $mobile_profile));
+ }
+
+ public function profile_getFBML($uid) {
+ return $this->call_method('facebook.profile.getFBML', array('uid' => $uid));
+ }
+
+ public function fbml_refreshImgSrc($url) {
+ return $this->call_method('facebook.fbml.refreshImgSrc', array('url' => $url));
+ }
+
+ public function fbml_refreshRefUrl($url) {
+ return $this->call_method('facebook.fbml.refreshRefUrl', array('url' => $url));
+ }
+
+ public function fbml_setRefHandle($handle, $fbml) {
+ return $this->call_method('facebook.fbml.setRefHandle', array('handle' => $handle, 'fbml' => $fbml));
+ }
+
+ /**
+ * Get all the marketplace categories
+ *
+ * @return array A list of category names
+ */
+ function marketplace_getCategories() {
+ return $this->call_method('facebook.marketplace.getCategories', array());
+ }
+
+ /**
+ * Get all the marketplace subcategories for a particular category
+ *
+ * @param category The category for which we are pulling subcategories
+ * @return array A list of subcategory names
+ */
+ function marketplace_getSubCategories($category) {
+ return $this->call_method('facebook.marketplace.getSubCategories', array('category' => $category));
+ }
+
+ /**
+ * Get listings by either listing_id or user
+ *
+ * @param listing_ids An array of listing_ids (optional)
+ * @param uids An array of user ids (optional)
+ * @return array The data for matched listings
+ */
+ function marketplace_getListings($listing_ids, $uids) {
+ return $this->call_method('facebook.marketplace.getListings', array('listing_ids' => $listing_ids, 'uids' => $uids));
+ }
+
+ /**
+ * Search for Marketplace listings. All arguments are optional, though at least
+ * one must be filled out to retrieve results.
+ *
+ * @param category The category in which to search (optional)
+ * @param subcategory The subcategory in which to search (optional)
+ * @param query A query string (optional)
+ * @return array The data for matched listings
+ */
+ function marketplace_search($category, $subcategory, $query) {
+ return $this->call_method('facebook.marketplace.search', array('category' => $category, 'subcategory' => $subcategory, 'query' => $query));
+ }
+
+ /**
+ * Remove a listing from Marketplace
+ *
+ * @param listing_id The id of the listing to be removed
+ * @param status 'SUCCESS', 'NOT_SUCCESS', or 'DEFAULT'
+ * @return bool True on success
+ */
+ function marketplace_removeListing($listing_id, $status='DEFAULT') {
+ return $this->call_method('facebook.marketplace.removeListing',
+ array('listing_id'=>$listing_id,
+ 'status'=>$status));
+ }
+
+ /**
+ * Create/modify a Marketplace listing for the loggedinuser
+ *
+ * @param int listing_id The id of a listing to be modified, 0 for a new listing.
+ * @param show_on_profile bool Should we show this listing on the user's profile
+ * @param listing_attrs array An array of the listing data
+ * @return int The listing_id (unchanged if modifying an existing listing)
+ */
+ function marketplace_createListing($listing_id, $show_on_profile, $attrs) {
+ return $this->call_method('facebook.marketplace.createListing',
+ array('listing_id'=>$listing_id,
+ 'show_on_profile'=>$show_on_profile,
+ 'listing_attrs'=>json_encode($attrs)));
+ }
+
+
+ /////////////////////////////////////////////////////////////////////////////
+ // Data Store API
+
+ /**
+ * Set a user preference.
+ *
+ * @param pref_id preference identifier (0-200)
+ * @param value preferece's value
+ * @error
+ * API_EC_DATA_DATABASE_ERROR
+ * API_EC_PARAM
+ * API_EC_DATA_QUOTA_EXCEEDED
+ * API_EC_DATA_UNKNOWN_ERROR
+ */
+ public function data_setUserPreference($pref_id, $value) {
+ return $this->call_method
+ ('facebook.data.setUserPreference',
+ array('pref_id' => $pref_id,
+ 'value' => $value));
+ }
+
+ /**
+ * Set a user's all preferences for this application.
+ *
+ * @param values preferece values in an associative arrays
+ * @param replace whether to replace all existing preferences or
+ * merge into them.
+ * @error
+ * API_EC_DATA_DATABASE_ERROR
+ * API_EC_PARAM
+ * API_EC_DATA_QUOTA_EXCEEDED
+ * API_EC_DATA_UNKNOWN_ERROR
+ */
+ public function data_setUserPreferences($values, $replace = false) {
+ return $this->call_method
+ ('facebook.data.setUserPreferences',
+ array('values' => json_encode($values),
+ 'replace' => $replace));
+ }
+
+ /**
+ * Get a user preference.
+ *
+ * @param pref_id preference identifier (0-200)
+ * @return preference's value
+ * @error
+ * API_EC_DATA_DATABASE_ERROR
+ * API_EC_PARAM
+ * API_EC_DATA_QUOTA_EXCEEDED
+ * API_EC_DATA_UNKNOWN_ERROR
+ */
+ public function data_getUserPreference($pref_id) {
+ return $this->call_method
+ ('facebook.data.getUserPreference',
+ array('pref_id' => $pref_id));
+ }
+
+ /**
+ * Get a user preference.
+ *
+ * @return preference values
+ * @error
+ * API_EC_DATA_DATABASE_ERROR
+ * API_EC_DATA_QUOTA_EXCEEDED
+ * API_EC_DATA_UNKNOWN_ERROR
+ */
+ public function data_getUserPreferences() {
+ return $this->call_method
+ ('facebook.data.getUserPreferences',
+ array());
+ }
+
+ /**
+ * Create a new object type.
+ *
+ * @param name object type's name
+ * @error
+ * API_EC_DATA_DATABASE_ERROR
+ * API_EC_DATA_OBJECT_ALREADY_EXISTS
+ * API_EC_PARAM
+ * API_EC_PERMISSION
+ * API_EC_DATA_INVALID_OPERATION
+ * API_EC_DATA_QUOTA_EXCEEDED
+ * API_EC_DATA_UNKNOWN_ERROR
+ */
+ public function data_createObjectType($name) {
+ return $this->call_method
+ ('facebook.data.createObjectType',
+ array('name' => $name));
+ }
+
+ /**
+ * Delete an object type.
+ *
+ * @param obj_type object type's name
+ * @error
+ * API_EC_DATA_DATABASE_ERROR
+ * API_EC_DATA_OBJECT_NOT_FOUND
+ * API_EC_PARAM
+ * API_EC_PERMISSION
+ * API_EC_DATA_INVALID_OPERATION
+ * API_EC_DATA_QUOTA_EXCEEDED
+ * API_EC_DATA_UNKNOWN_ERROR
+ */
+ public function data_dropObjectType($obj_type) {
+ return $this->call_method
+ ('facebook.data.dropObjectType',
+ array('obj_type' => $obj_type));
+ }
+
+ /**
+ * Rename an object type.
+ *
+ * @param obj_type object type's name
+ * @param new_name new object type's name
+ * @error
+ * API_EC_DATA_DATABASE_ERROR
+ * API_EC_DATA_OBJECT_NOT_FOUND
+ * API_EC_DATA_OBJECT_ALREADY_EXISTS
+ * API_EC_PARAM
+ * API_EC_PERMISSION
+ * API_EC_DATA_INVALID_OPERATION
+ * API_EC_DATA_QUOTA_EXCEEDED
+ * API_EC_DATA_UNKNOWN_ERROR
+ */
+ public function data_renameObjectType($obj_type, $new_name) {
+ return $this->call_method
+ ('facebook.data.renameObjectType',
+ array('obj_type' => $obj_type,
+ 'new_name' => $new_name));
+ }
+
+ /**
+ * Add a new property to an object type.
+ *
+ * @param obj_type object type's name
+ * @param prop_name name of the property to add
+ * @param prop_type 1: integer; 2: string; 3: text blob
+ * @error
+ * API_EC_DATA_DATABASE_ERROR
+ * API_EC_DATA_OBJECT_ALREADY_EXISTS
+ * API_EC_PARAM
+ * API_EC_PERMISSION
+ * API_EC_DATA_INVALID_OPERATION
+ * API_EC_DATA_QUOTA_EXCEEDED
+ * API_EC_DATA_UNKNOWN_ERROR
+ */
+ public function data_defineObjectProperty($obj_type, $prop_name, $prop_type) {
+ return $this->call_method
+ ('facebook.data.defineObjectProperty',
+ array('obj_type' => $obj_type,
+ 'prop_name' => $prop_name,
+ 'prop_type' => $prop_type));
+ }
+
+ /**
+ * Remove a previously defined property from an object type.
+ *
+ * @param obj_type object type's name
+ * @param prop_name name of the property to remove
+ * @error
+ * API_EC_DATA_DATABASE_ERROR
+ * API_EC_DATA_OBJECT_NOT_FOUND
+ * API_EC_PARAM
+ * API_EC_PERMISSION
+ * API_EC_DATA_INVALID_OPERATION
+ * API_EC_DATA_QUOTA_EXCEEDED
+ * API_EC_DATA_UNKNOWN_ERROR
+ */
+ public function data_undefineObjectProperty($obj_type, $prop_name) {
+ return $this->call_method
+ ('facebook.data.undefineObjectProperty',
+ array('obj_type' => $obj_type,
+ 'prop_name' => $prop_name));
+ }
+
+ /**
+ * Rename a previously defined property of an object type.
+ *
+ * @param obj_type object type's name
+ * @param prop_name name of the property to rename
+ * @param new_name new name to use
+ * @error
+ * API_EC_DATA_DATABASE_ERROR
+ * API_EC_DATA_OBJECT_NOT_FOUND
+ * API_EC_DATA_OBJECT_ALREADY_EXISTS
+ * API_EC_PARAM
+ * API_EC_PERMISSION
+ * API_EC_DATA_INVALID_OPERATION
+ * API_EC_DATA_QUOTA_EXCEEDED
+ * API_EC_DATA_UNKNOWN_ERROR
+ */
+ public function data_renameObjectProperty($obj_type, $prop_name,
+ $new_name) {
+ return $this->call_method
+ ('facebook.data.renameObjectProperty',
+ array('obj_type' => $obj_type,
+ 'prop_name' => $prop_name,
+ 'new_name' => $new_name));
+ }
+
+ /**
+ * Retrieve a list of all object types that have defined for the application.
+ *
+ * @return a list of object type names
+ * @error
+ * API_EC_DATA_DATABASE_ERROR
+ * API_EC_PERMISSION
+ * API_EC_DATA_QUOTA_EXCEEDED
+ * API_EC_DATA_UNKNOWN_ERROR
+ */
+ public function data_getObjectTypes() {
+ return $this->call_method
+ ('facebook.data.getObjectTypes',
+ array());
+ }
+
+ /**
+ * Get definitions of all properties of an object type.
+ *
+ * @param obj_type object type's name
+ * @return pairs of property name and property types
+ * @error
+ * API_EC_DATA_DATABASE_ERROR
+ * API_EC_PARAM
+ * API_EC_PERMISSION
+ * API_EC_DATA_OBJECT_NOT_FOUND
+ * API_EC_DATA_QUOTA_EXCEEDED
+ * API_EC_DATA_UNKNOWN_ERROR
+ */
+ public function data_getObjectType($obj_type) {
+ return $this->call_method
+ ('facebook.data.getObjectType',
+ array('obj_type' => $obj_type));
+ }
+
+ /**
+ * Create a new object.
+ *
+ * @param obj_type object type's name
+ * @param properties (optional) properties to set initially
+ * @return newly created object's id
+ * @error
+ * API_EC_DATA_DATABASE_ERROR
+ * API_EC_PARAM
+ * API_EC_PERMISSION
+ * API_EC_DATA_INVALID_OPERATION
+ * API_EC_DATA_QUOTA_EXCEEDED
+ * API_EC_DATA_UNKNOWN_ERROR
+ */
+ public function data_createObject($obj_type, $properties = null) {
+ return $this->call_method
+ ('facebook.data.createObject',
+ array('obj_type' => $obj_type,
+ 'properties' => json_encode($properties)));
+ }
+
+ /**
+ * Update an existing object.
+ *
+ * @param obj_id object's id
+ * @param properties new properties
+ * @param replace true for replacing existing properties; false for merging
+ * @error
+ * API_EC_DATA_DATABASE_ERROR
+ * API_EC_DATA_OBJECT_NOT_FOUND
+ * API_EC_PARAM
+ * API_EC_PERMISSION
+ * API_EC_DATA_INVALID_OPERATION
+ * API_EC_DATA_QUOTA_EXCEEDED
+ * API_EC_DATA_UNKNOWN_ERROR
+ */
+ public function data_updateObject($obj_id, $properties, $replace = false) {
+ return $this->call_method
+ ('facebook.data.updateObject',
+ array('obj_id' => $obj_id,
+ 'properties' => json_encode($properties),
+ 'replace' => $replace));
+ }
+
+ /**
+ * Delete an existing object.
+ *
+ * @param obj_id object's id
+ * @error
+ * API_EC_DATA_DATABASE_ERROR
+ * API_EC_DATA_OBJECT_NOT_FOUND
+ * API_EC_PARAM
+ * API_EC_PERMISSION
+ * API_EC_DATA_INVALID_OPERATION
+ * API_EC_DATA_QUOTA_EXCEEDED
+ * API_EC_DATA_UNKNOWN_ERROR
+ */
+ public function data_deleteObject($obj_id) {
+ return $this->call_method
+ ('facebook.data.deleteObject',
+ array('obj_id' => $obj_id));
+ }
+
+ /**
+ * Delete a list of objects.
+ *
+ * @param obj_ids objects to delete
+ * @error
+ * API_EC_DATA_DATABASE_ERROR
+ * API_EC_PARAM
+ * API_EC_PERMISSION
+ * API_EC_DATA_INVALID_OPERATION
+ * API_EC_DATA_QUOTA_EXCEEDED
+ * API_EC_DATA_UNKNOWN_ERROR
+ */
+ public function data_deleteObjects($obj_ids) {
+ return $this->call_method
+ ('facebook.data.deleteObjects',
+ array('obj_ids' => json_encode($obj_ids)));
+ }
+
+ /**
+ * Get a single property value of an object.
+ *
+ * @param obj_id object's id
+ * @param prop_name individual property's name
+ * @return individual property's value
+ * @error
+ * API_EC_DATA_DATABASE_ERROR
+ * API_EC_DATA_OBJECT_NOT_FOUND
+ * API_EC_PARAM
+ * API_EC_PERMISSION
+ * API_EC_DATA_INVALID_OPERATION
+ * API_EC_DATA_QUOTA_EXCEEDED
+ * API_EC_DATA_UNKNOWN_ERROR
+ */
+ public function data_getObjectProperty($obj_id, $prop_name) {
+ return $this->call_method
+ ('facebook.data.getObjectProperty',
+ array('obj_id' => $obj_id,
+ 'prop_name' => $prop_name));
+ }
+
+ /**
+ * Get properties of an object.
+ *
+ * @param obj_id object's id
+ * @param prop_names (optional) properties to return; null for all.
+ * @return specified properties of an object
+ * @error
+ * API_EC_DATA_DATABASE_ERROR
+ * API_EC_DATA_OBJECT_NOT_FOUND
+ * API_EC_PARAM
+ * API_EC_PERMISSION
+ * API_EC_DATA_INVALID_OPERATION
+ * API_EC_DATA_QUOTA_EXCEEDED
+ * API_EC_DATA_UNKNOWN_ERROR
+ */
+ public function data_getObject($obj_id, $prop_names = null) {
+ return $this->call_method
+ ('facebook.data.getObject',
+ array('obj_id' => $obj_id,
+ 'prop_names' => json_encode($prop_names)));
+ }
+
+ /**
+ * Get properties of a list of objects.
+ *
+ * @param obj_ids object ids
+ * @param prop_names (optional) properties to return; null for all.
+ * @return specified properties of an object
+ * @error
+ * API_EC_DATA_DATABASE_ERROR
+ * API_EC_DATA_OBJECT_NOT_FOUND
+ * API_EC_PARAM
+ * API_EC_PERMISSION
+ * API_EC_DATA_INVALID_OPERATION
+ * API_EC_DATA_QUOTA_EXCEEDED
+ * API_EC_DATA_UNKNOWN_ERROR
+ */
+ public function data_getObjects($obj_ids, $prop_names = null) {
+ return $this->call_method
+ ('facebook.data.getObjects',
+ array('obj_ids' => json_encode($obj_ids),
+ 'prop_names' => json_encode($prop_names)));
+ }
+
+ /**
+ * Set a single property value of an object.
+ *
+ * @param obj_id object's id
+ * @param prop_name individual property's name
+ * @param prop_value new value to set
+ * @error
+ * API_EC_DATA_DATABASE_ERROR
+ * API_EC_DATA_OBJECT_NOT_FOUND
+ * API_EC_PARAM
+ * API_EC_PERMISSION
+ * API_EC_DATA_INVALID_OPERATION
+ * API_EC_DATA_QUOTA_EXCEEDED
+ * API_EC_DATA_UNKNOWN_ERROR
+ */
+ public function data_setObjectProperty($obj_id, $prop_name,
+ $prop_value) {
+ return $this->call_method
+ ('facebook.data.setObjectProperty',
+ array('obj_id' => $obj_id,
+ 'prop_name' => $prop_name,
+ 'prop_value' => $prop_value));
+ }
+
+ /**
+ * Read hash value by key.
+ *
+ * @param obj_type object type's name
+ * @param key hash key
+ * @param prop_name (optional) individual property's name
+ * @return hash value
+ * @error
+ * API_EC_DATA_DATABASE_ERROR
+ * API_EC_PARAM
+ * API_EC_PERMISSION
+ * API_EC_DATA_INVALID_OPERATION
+ * API_EC_DATA_QUOTA_EXCEEDED
+ * API_EC_DATA_UNKNOWN_ERROR
+ */
+ public function data_getHashValue($obj_type, $key, $prop_name = null) {
+ return $this->call_method
+ ('facebook.data.getHashValue',
+ array('obj_type' => $obj_type,
+ 'key' => $key,
+ 'prop_name' => $prop_name));
+ }
+
+ /**
+ * Write hash value by key.
+ *
+ * @param obj_type object type's name
+ * @param key hash key
+ * @param value hash value
+ * @param prop_name (optional) individual property's name
+ * @error
+ * API_EC_DATA_DATABASE_ERROR
+ * API_EC_PARAM
+ * API_EC_PERMISSION
+ * API_EC_DATA_INVALID_OPERATION
+ * API_EC_DATA_QUOTA_EXCEEDED
+ * API_EC_DATA_UNKNOWN_ERROR
+ */
+ public function data_setHashValue($obj_type, $key, $value, $prop_name = null) {
+ return $this->call_method
+ ('facebook.data.setHashValue',
+ array('obj_type' => $obj_type,
+ 'key' => $key,
+ 'value' => $value,
+ 'prop_name' => $prop_name));
+ }
+
+ /**
+ * Increase a hash value by specified increment atomically.
+ *
+ * @param obj_type object type's name
+ * @param key hash key
+ * @param prop_name individual property's name
+ * @param increment (optional) default is 1
+ * @return incremented hash value
+ * @error
+ * API_EC_DATA_DATABASE_ERROR
+ * API_EC_PARAM
+ * API_EC_PERMISSION
+ * API_EC_DATA_INVALID_OPERATION
+ * API_EC_DATA_QUOTA_EXCEEDED
+ * API_EC_DATA_UNKNOWN_ERROR
+ */
+ public function data_incHashValue($obj_type, $key, $prop_name, $increment = 1) {
+ return $this->call_method
+ ('facebook.data.incHashValue',
+ array('obj_type' => $obj_type,
+ 'key' => $key,
+ 'prop_name' => $prop_name,
+ 'increment' => $increment));
+ }
+
+ /**
+ * Remove a hash key and its values.
+ *
+ * @param obj_type object type's name
+ * @param key hash key
+ * @error
+ * API_EC_DATA_DATABASE_ERROR
+ * API_EC_PARAM
+ * API_EC_PERMISSION
+ * API_EC_DATA_INVALID_OPERATION
+ * API_EC_DATA_QUOTA_EXCEEDED
+ * API_EC_DATA_UNKNOWN_ERROR
+ */
+ public function data_removeHashKey($obj_type, $key) {
+ return $this->call_method
+ ('facebook.data.removeHashKey',
+ array('obj_type' => $obj_type,
+ 'key' => $key));
+ }
+
+ /**
+ * Remove hash keys and their values.
+ *
+ * @param obj_type object type's name
+ * @param keys hash keys
+ * @error
+ * API_EC_DATA_DATABASE_ERROR
+ * API_EC_PARAM
+ * API_EC_PERMISSION
+ * API_EC_DATA_INVALID_OPERATION
+ * API_EC_DATA_QUOTA_EXCEEDED
+ * API_EC_DATA_UNKNOWN_ERROR
+ */
+ public function data_removeHashKeys($obj_type, $keys) {
+ return $this->call_method
+ ('facebook.data.removeHashKeys',
+ array('obj_type' => $obj_type,
+ 'keys' => json_encode($keys)));
+ }
+
+
+ /**
+ * Define an object association.
+ *
+ * @param name name of this association
+ * @param assoc_type 1: one-way 2: two-way symmetric 3: two-way asymmetric
+ * @param assoc_info1 needed info about first object type
+ * @param assoc_info2 needed info about second object type
+ * @param inverse (optional) name of reverse association
+ * @error
+ * API_EC_DATA_DATABASE_ERROR
+ * API_EC_DATA_OBJECT_ALREADY_EXISTS
+ * API_EC_PARAM
+ * API_EC_PERMISSION
+ * API_EC_DATA_INVALID_OPERATION
+ * API_EC_DATA_QUOTA_EXCEEDED
+ * API_EC_DATA_UNKNOWN_ERROR
+ */
+ public function data_defineAssociation($name, $assoc_type, $assoc_info1,
+ $assoc_info2, $inverse = null) {
+ return $this->call_method
+ ('facebook.data.defineAssociation',
+ array('name' => $name,
+ 'assoc_type' => $assoc_type,
+ 'assoc_info1' => json_encode($assoc_info1),
+ 'assoc_info2' => json_encode($assoc_info2),
+ 'inverse' => $inverse));
+ }
+
+ /**
+ * Undefine an object association.
+ *
+ * @param name name of this association
+ * @error
+ * API_EC_DATA_DATABASE_ERROR
+ * API_EC_DATA_OBJECT_NOT_FOUND
+ * API_EC_PARAM
+ * API_EC_PERMISSION
+ * API_EC_DATA_INVALID_OPERATION
+ * API_EC_DATA_QUOTA_EXCEEDED
+ * API_EC_DATA_UNKNOWN_ERROR
+ */
+ public function data_undefineAssociation($name) {
+ return $this->call_method
+ ('facebook.data.undefineAssociation',
+ array('name' => $name));
+ }
+
+ /**
+ * Rename an object association or aliases.
+ *
+ * @param name name of this association
+ * @param new_name (optional) new name of this association
+ * @param new_alias1 (optional) new alias for object type 1
+ * @param new_alias2 (optional) new alias for object type 2
+ * @error
+ * API_EC_DATA_DATABASE_ERROR
+ * API_EC_DATA_OBJECT_ALREADY_EXISTS
+ * API_EC_DATA_OBJECT_NOT_FOUND
+ * API_EC_PARAM
+ * API_EC_PERMISSION
+ * API_EC_DATA_INVALID_OPERATION
+ * API_EC_DATA_QUOTA_EXCEEDED
+ * API_EC_DATA_UNKNOWN_ERROR
+ */
+ public function data_renameAssociation($name, $new_name, $new_alias1 = null,
+ $new_alias2 = null) {
+ return $this->call_method
+ ('facebook.data.renameAssociation',
+ array('name' => $name,
+ 'new_name' => $new_name,
+ 'new_alias1' => $new_alias1,
+ 'new_alias2' => $new_alias2));
+ }
+
+ /**
+ * Get definition of an object association.
+ *
+ * @param name name of this association
+ * @return specified association
+ * @error
+ * API_EC_DATA_DATABASE_ERROR
+ * API_EC_DATA_OBJECT_NOT_FOUND
+ * API_EC_PARAM
+ * API_EC_PERMISSION
+ * API_EC_DATA_QUOTA_EXCEEDED
+ * API_EC_DATA_UNKNOWN_ERROR
+ */
+ public function data_getAssociationDefinition($name) {
+ return $this->call_method
+ ('facebook.data.getAssociationDefinition',
+ array('name' => $name));
+ }
+
+ /**
+ * Get definition of all associations.
+ *
+ * @return all defined associations
+ * @error
+ * API_EC_DATA_DATABASE_ERROR
+ * API_EC_PERMISSION
+ * API_EC_DATA_QUOTA_EXCEEDED
+ * API_EC_DATA_UNKNOWN_ERROR
+ */
+ public function data_getAssociationDefinitions() {
+ return $this->call_method
+ ('facebook.data.getAssociationDefinitions',
+ array());
+ }
+
+ /**
+ * Create or modify an association between two objects.
+ *
+ * @param name name of association
+ * @param obj_id1 id of first object
+ * @param obj_id2 id of second object
+ * @param data (optional) extra string data to store
+ * @param assoc_time (optional) extra time data; default to creation time
+ * @error
+ * API_EC_DATA_DATABASE_ERROR
+ * API_EC_PARAM
+ * API_EC_PERMISSION
+ * API_EC_DATA_INVALID_OPERATION
+ * API_EC_DATA_QUOTA_EXCEEDED
+ * API_EC_DATA_UNKNOWN_ERROR
+ */
+ public function data_setAssociation($name, $obj_id1, $obj_id2, $data = null,
+ $assoc_time = null) {
+ return $this->call_method
+ ('facebook.data.setAssociation',
+ array('name' => $name,
+ 'obj_id1' => $obj_id1,
+ 'obj_id2' => $obj_id2,
+ 'data' => $data,
+ 'assoc_time' => $assoc_time));
+ }
+
+ /**
+ * Create or modify associations between objects.
+ *
+ * @param assocs associations to set
+ * @param name (optional) name of association
+ * @error
+ * API_EC_DATA_DATABASE_ERROR
+ * API_EC_PARAM
+ * API_EC_PERMISSION
+ * API_EC_DATA_INVALID_OPERATION
+ * API_EC_DATA_QUOTA_EXCEEDED
+ * API_EC_DATA_UNKNOWN_ERROR
+ */
+ public function data_setAssociations($assocs, $name = null) {
+ return $this->call_method
+ ('facebook.data.setAssociations',
+ array('assocs' => json_encode($assocs),
+ 'name' => $name));
+ }
+
+ /**
+ * Remove an association between two objects.
+ *
+ * @param name name of association
+ * @param obj_id1 id of first object
+ * @param obj_id2 id of second object
+ * @error
+ * API_EC_DATA_DATABASE_ERROR
+ * API_EC_DATA_OBJECT_NOT_FOUND
+ * API_EC_PARAM
+ * API_EC_PERMISSION
+ * API_EC_DATA_QUOTA_EXCEEDED
+ * API_EC_DATA_UNKNOWN_ERROR
+ */
+ public function data_removeAssociation($name, $obj_id1, $obj_id2) {
+ return $this->call_method
+ ('facebook.data.removeAssociation',
+ array('name' => $name,
+ 'obj_id1' => $obj_id1,
+ 'obj_id2' => $obj_id2));
+ }
+
+ /**
+ * Remove associations between objects by specifying pairs of object ids.
+ *
+ * @param assocs associations to remove
+ * @param name (optional) name of association
+ * @error
+ * API_EC_DATA_DATABASE_ERROR
+ * API_EC_DATA_OBJECT_NOT_FOUND
+ * API_EC_PARAM
+ * API_EC_PERMISSION
+ * API_EC_DATA_QUOTA_EXCEEDED
+ * API_EC_DATA_UNKNOWN_ERROR
+ */
+ public function data_removeAssociations($assocs, $name = null) {
+ return $this->call_method
+ ('facebook.data.removeAssociations',
+ array('assocs' => json_encode($assocs),
+ 'name' => $name));
+ }
+
+ /**
+ * Remove associations between objects by specifying one object id.
+ *
+ * @param name name of association
+ * @param obj_id who's association to remove
+ * @error
+ * API_EC_DATA_DATABASE_ERROR
+ * API_EC_DATA_OBJECT_NOT_FOUND
+ * API_EC_PARAM
+ * API_EC_PERMISSION
+ * API_EC_DATA_INVALID_OPERATION
+ * API_EC_DATA_QUOTA_EXCEEDED
+ * API_EC_DATA_UNKNOWN_ERROR
+ */
+ public function data_removeAssociatedObjects($name, $obj_id) {
+ return $this->call_method
+ ('facebook.data.removeAssociatedObjects',
+ array('name' => $name,
+ 'obj_id' => $obj_id));
+ }
+
+ /**
+ * Retrieve a list of associated objects.
+ *
+ * @param name name of association
+ * @param obj_id who's association to retrieve
+ * @param no_data only return object ids
+ * @return associated objects
+ * @error
+ * API_EC_DATA_DATABASE_ERROR
+ * API_EC_DATA_OBJECT_NOT_FOUND
+ * API_EC_PARAM
+ * API_EC_PERMISSION
+ * API_EC_DATA_INVALID_OPERATION
+ * API_EC_DATA_QUOTA_EXCEEDED
+ * API_EC_DATA_UNKNOWN_ERROR
+ */
+ public function data_getAssociatedObjects($name, $obj_id, $no_data = true) {
+ return $this->call_method
+ ('facebook.data.getAssociatedObjects',
+ array('name' => $name,
+ 'obj_id' => $obj_id,
+ 'no_data' => $no_data));
+ }
+
+ /**
+ * Count associated objects.
+ *
+ * @param name name of association
+ * @param obj_id who's association to retrieve
+ * @return associated object's count
+ * @error
+ * API_EC_DATA_DATABASE_ERROR
+ * API_EC_DATA_OBJECT_NOT_FOUND
+ * API_EC_PARAM
+ * API_EC_PERMISSION
+ * API_EC_DATA_INVALID_OPERATION
+ * API_EC_DATA_QUOTA_EXCEEDED
+ * API_EC_DATA_UNKNOWN_ERROR
+ */
+ public function data_getAssociatedObjectCount($name, $obj_id) {
+ return $this->call_method
+ ('facebook.data.getAssociatedObjectCount',
+ array('name' => $name,
+ 'obj_id' => $obj_id));
+ }
+
+ /**
+ * Get a list of associated object counts.
+ *
+ * @param name name of association
+ * @param obj_ids whose association to retrieve
+ * @return associated object counts
+ * @error
+ * API_EC_DATA_DATABASE_ERROR
+ * API_EC_DATA_OBJECT_NOT_FOUND
+ * API_EC_PARAM
+ * API_EC_PERMISSION
+ * API_EC_DATA_INVALID_OPERATION
+ * API_EC_DATA_QUOTA_EXCEEDED
+ * API_EC_DATA_UNKNOWN_ERROR
+ */
+ public function data_getAssociatedObjectCounts($name, $obj_ids) {
+ return $this->call_method
+ ('facebook.data.getAssociatedObjectCounts',
+ array('name' => $name,
+ 'obj_ids' => json_encode($obj_ids)));
+ }
+
+ /**
+ * Find all associations between two objects.
+ *
+ * @param obj_id1 id of first object
+ * @param obj_id2 id of second object
+ * @param no_data only return association names without data
+ * @return all associations between objects
+ * @error
+ * API_EC_DATA_DATABASE_ERROR
+ * API_EC_PARAM
+ * API_EC_PERMISSION
+ * API_EC_DATA_QUOTA_EXCEEDED
+ * API_EC_DATA_UNKNOWN_ERROR
+ */
+ public function data_getAssociations($obj_id1, $obj_id2, $no_data = true) {
+ return $this->call_method
+ ('facebook.data.getAssociations',
+ array('obj_id1' => $obj_id1,
+ 'obj_id2' => $obj_id2,
+ 'no_data' => $no_data));
+ }
+
+ /* UTILITY FUNCTIONS */
+
+ public function call_method($method, $params) {
+ $xml = $this->post_request($method, $params);
+ $sxml = simplexml_load_string($xml);
+ $result = self::convert_simplexml_to_array($sxml);
+ if (!empty($GLOBALS['facebook_config']['debug'])) {
+ // output the raw xml and its corresponding php object, for debugging:
+ print '<div style="margin: 10px 30px; padding: 5px; border: 2px solid black; background: gray; color: white; font-size: 12px; font-weight: bold;">';
+ $this->cur_id++;
+ print $this->cur_id . ': Called ' . $method . ', show ' .
+ '<a href=# onclick="return toggleDisplay(' . $this->cur_id . ', \'params\');">Params</a> | '.
+ '<a href=# onclick="return toggleDisplay(' . $this->cur_id . ', \'xml\');">XML</a> | '.
+ '<a href=# onclick="return toggleDisplay(' . $this->cur_id . ', \'sxml\');">SXML</a> | '.
+ '<a href=# onclick="return toggleDisplay(' . $this->cur_id . ', \'php\');">PHP</a>';
+ print '<pre id="params'.$this->cur_id.'" style="display: none; overflow: auto;">'.print_r($params, true).'</pre>';
+ print '<pre id="xml'.$this->cur_id.'" style="display: none; overflow: auto;">'.htmlspecialchars($xml).'</pre>';
+ print '<pre id="php'.$this->cur_id.'" style="display: none; overflow: auto;">'.print_r($result, true).'</pre>';
+ print '<pre id="sxml'.$this->cur_id.'" style="display: none; overflow: auto;">'.print_r($sxml, true).'</pre>';
+ print '</div>';
+ }
+ if (is_array($result) && isset($result['error_code'])) {
+ throw new FacebookRestClientException($result['error_msg'], $result['error_code']);
+ }
+ return $result;
+ }
+
+ public function post_request($method, $params) {
+ $params['method'] = $method;
+ $params['session_key'] = $this->session_key;
+ $params['api_key'] = $this->api_key;
+ $params['call_id'] = microtime(true);
+ if ($params['call_id'] <= $this->last_call_id) {
+ $params['call_id'] = $this->last_call_id + 0.001;
+ }
+ $this->last_call_id = $params['call_id'];
+ if (!isset($params['v'])) {
+ $params['v'] = '1.0';
+ }
+ $post_params = array();
+ foreach ($params as $key => &$val) {
+ if (is_array($val)) $val = implode(',', $val);
+ $post_params[] = $key.'='.urlencode($val);
+ }
+ $secret = $this->secret;
+ $post_params[] = 'sig='.Facebook::generate_sig($params, $secret);
+ $post_string = implode('&', $post_params);
+
+ if (function_exists('curl_init')) {
+ // Use CURL if installed...
+ $ch = curl_init();
+ curl_setopt($ch, CURLOPT_URL, $this->server_addr);
+ curl_setopt($ch, CURLOPT_POSTFIELDS, $post_string);
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+ curl_setopt($ch, CURLOPT_USERAGENT, 'Facebook API PHP5 Client 1.1 (curl) ' . phpversion());
+ $result = curl_exec($ch);
+ curl_close($ch);
+ } else {
+ // Non-CURL based version...
+ $context =
+ array('http' =>
+ array('method' => 'POST',
+ 'header' => 'Content-type: application/x-www-form-urlencoded'."\r\n".
+ 'User-Agent: Facebook API PHP5 Client 1.1 (non-curl) '.phpversion()."\r\n".
+ 'Content-length: ' . strlen($post_string),
+ 'content' => $post_string));
+ $contextid=stream_context_create($context);
+ $sock=fopen($this->server_addr, 'r', false, $contextid);
+ if ($sock) {
+ $result='';
+ while (!feof($sock))
+ $result.=fgets($sock, 4096);
+
+ fclose($sock);
+ }
+ }
+ return $result;
+ }
+
+ public static function convert_simplexml_to_array($sxml) {
+ $arr = array();
+ if ($sxml) {
+ foreach ($sxml as $k => $v) {
+ if ($sxml['list']) {
+ $arr[] = self::convert_simplexml_to_array($v);
+ } else {
+ $arr[$k] = self::convert_simplexml_to_array($v);
+ }
+ }
+ }
+ if (sizeof($arr) > 0) {
+ return $arr;
+ } else {
+ return (string)$sxml;
+ }
+ }
+}
+
+class FacebookRestClientException extends Exception {
+}
+
+// Supporting methods and values------
+
+/**
+ * Error codes and descriptions for the Facebook API.
+ */
+
+class FacebookAPIErrorCodes {
+
+ const API_EC_SUCCESS = 0;
+
+ /*
+ * GENERAL ERRORS
+ */
+ const API_EC_UNKNOWN = 1;
+ const API_EC_SERVICE = 2;
+ const API_EC_METHOD = 3;
+ const API_EC_TOO_MANY_CALLS = 4;
+ const API_EC_BAD_IP = 5;
+
+ /*
+ * PARAMETER ERRORS
+ */
+ const API_EC_PARAM = 100;
+ const API_EC_PARAM_API_KEY = 101;
+ const API_EC_PARAM_SESSION_KEY = 102;
+ const API_EC_PARAM_CALL_ID = 103;
+ const API_EC_PARAM_SIGNATURE = 104;
+ const API_EC_PARAM_USER_ID = 110;
+ const API_EC_PARAM_USER_FIELD = 111;
+ const API_EC_PARAM_SOCIAL_FIELD = 112;
+ const API_EC_PARAM_ALBUM_ID = 120;
+
+ /*
+ * USER PERMISSIONS ERRORS
+ */
+ const API_EC_PERMISSION = 200;
+ const API_EC_PERMISSION_USER = 210;
+ const API_EC_PERMISSION_ALBUM = 220;
+ const API_EC_PERMISSION_PHOTO = 221;
+
+ const FQL_EC_PARSER = 601;
+ const FQL_EC_UNKNOWN_FIELD = 602;
+ const FQL_EC_UNKNOWN_TABLE = 603;
+ const FQL_EC_NOT_INDEXABLE = 604;
+
+ /**
+ * DATA STORE API ERRORS
+ */
+ const API_EC_DATA_UNKNOWN_ERROR = 800;
+ const API_EC_DATA_INVALID_OPERATION = 801;
+ const API_EC_DATA_QUOTA_EXCEEDED = 802;
+ const API_EC_DATA_OBJECT_NOT_FOUND = 803;
+ const API_EC_DATA_OBJECT_ALREADY_EXISTS = 804;
+ const API_EC_DATA_DATABASE_ERROR = 805;
+
+ public static $api_error_descriptions = array(
+ API_EC_SUCCESS => 'Success',
+ API_EC_UNKNOWN => 'An unknown error occurred',
+ API_EC_SERVICE => 'Service temporarily unavailable',
+ API_EC_METHOD => 'Unknown method',
+ API_EC_TOO_MANY_CALLS => 'Application request limit reached',
+ API_EC_BAD_IP => 'Unauthorized source IP address',
+ API_EC_PARAM => 'Invalid parameter',
+ API_EC_PARAM_API_KEY => 'Invalid API key',
+ API_EC_PARAM_SESSION_KEY => 'Session key invalid or no longer valid',
+ API_EC_PARAM_CALL_ID => 'Call_id must be greater than previous',
+ API_EC_PARAM_SIGNATURE => 'Incorrect signature',
+ API_EC_PARAM_USER_ID => 'Invalid user id',
+ API_EC_PARAM_USER_FIELD => 'Invalid user info field',
+ API_EC_PARAM_SOCIAL_FIELD => 'Invalid user field',
+ API_EC_PARAM_ALBUM_ID => 'Invalid album id',
+ API_EC_PERMISSION => 'Permissions error',
+ API_EC_PERMISSION_USER => 'User not visible',
+ API_EC_PERMISSION_ALBUM => 'Album not visible',
+ API_EC_PERMISSION_PHOTO => 'Photo not visible',
+ FQL_EC_PARSER => 'FQL: Parser Error',
+ FQL_EC_UNKNOWN_FIELD => 'FQL: Unknown Field',
+ FQL_EC_UNKNOWN_TABLE => 'FQL: Unknown Table',
+ FQL_EC_NOT_INDEXABLE => 'FQL: Statement not indexable',
+ FQL_EC_UNKNOWN_FUNCTION => 'FQL: Attempted to call unknown function',
+ FQL_EC_INVALID_PARAM => 'FQL: Invalid parameter passed in',
+ API_EC_DATA_UNKNOWN_ERROR => 'Unknown data store API error',
+ API_EC_DATA_INVALID_OPERATION => 'Invalid operation',
+ API_EC_DATA_QUOTA_EXCEEDED => 'Data store allowable quota was exceeded',
+ API_EC_DATA_OBJECT_NOT_FOUND => 'Specified object cannot be found',
+ API_EC_DATA_OBJECT_ALREADY_EXISTS => 'Specified object already exists',
+ API_EC_DATA_DATABASE_ERROR => 'A database error occurred. Please try again',
+ );
+}
+
+$profile_field_array = array(
+ "about_me",
+ "activities",
+ "affiliations",
+ "birthday",
+ "books",
+ "current_location",
+ "education_history",
+ "first_name",
+ "hometown_location",
+ "hs_info",
+ "interests",
+ "is_app_user",
+ "last_name",
+ "meeting_for",
+ "meeting_sex",
+ "movies",
+ "music",
+ "name",
+ "notes_count",
+ "pic",
+ "pic_big",
+ "pic_small",
+ "political",
+ "profile_update_time",
+ "quotes",
+ "relationship_status",
+ "religion",
+ "sex",
+ "significant_other_id",
+ "status",
+ "timezone",
+ "tv",
+ "wall_count",
+ "work_history");
+?>
diff --git a/site/vendors/phpQuery/Callback.php b/site/vendors/phpQuery/Callback.php
new file mode 100644
index 0000000..5d34f9f
--- /dev/null
+++ b/site/vendors/phpQuery/Callback.php
@@ -0,0 +1,38 @@
+<?php
+/**
+ * Callback class implementing ParamStructures, pattern similar to Currying.
+ *
+ * @link http://code.google.com/p/phpquery/wiki/Callbacks#Param_Structures
+ * @author Tobiasz Cudnik
+ */
+class Callback {
+ public $callback = null;
+ public $params = null;
+ public function __construct($callback, $param1 = null, $param2 = null, $param3 = null) {
+ $params = func_get_args();
+ $params = array_slice($params, 1);
+ if ($callback instanceof Callback) {
+ // TODO implement recurention
+ } else {
+ $this->callback = $callback;
+ $this->params = $params;
+ }
+ }
+ // TODO test me !!!
+ public function param() {
+ $params = func_get_args();
+ return new Callback($this->callback, $this->params+$params);
+ }
+}
+class CallbackReference extends Callback{
+ /**
+ *
+ * @param $reference
+ * @param $paramIndex
+ * @todo implement $paramIndex; param index choose which callback param will be passed to reference
+ */
+ public function __construct(&$reference, $name = null){
+ $this->callback =& $reference;
+ }
+}
+class CallbackParam {} \ No newline at end of file
diff --git a/site/vendors/phpQuery/DOMDocumentWrapper.php b/site/vendors/phpQuery/DOMDocumentWrapper.php
new file mode 100644
index 0000000..29ac79d
--- /dev/null
+++ b/site/vendors/phpQuery/DOMDocumentWrapper.php
@@ -0,0 +1,606 @@
+<?php
+/**
+ * DOMDocumentWrapper class simplifies work with DOMDocument.
+ *
+ * Know bug:
+ * - in XHTML fragments, <br /> changes to <br clear="none" />
+ *
+ * @todo check XML catalogs compatibility
+ * @author Tobiasz Cudnik <tobiasz.cudnik/gmail.com>
+ * @package phpQuery
+ */
+class DOMDocumentWrapper {
+ /**
+ * @var DOMDocument
+ */
+ public $document;
+ public $id;
+ /**
+ * @todo Rewrite as method and quess if null.
+ * @var unknown_type
+ */
+ public $contentType = '';
+ public $xpath;
+ public $events = array();
+ public $eventsNodes = array();
+ public $eventsGlobal = array();
+ /**
+ * @TODO iframes support http://code.google.com/p/phpquery/issues/detail?id=28
+ * @var unknown_type
+ */
+ public $frames = array();
+ /**
+ * Document root, by default equals to document itself.
+ * Used by documentFragments.
+ *
+ * @var DOMNode
+ */
+ public $root;
+ public $isDocumentFragment;
+ public $isXML = false;
+ public $isXHTML = false;
+ public $isHTML = false;
+ public $charset;
+ public function __construct($markup = null, $contentType = null, $newDocumentID = null) {
+ if (isset($markup))
+ $this->load($markup, $contentType, $newDocumentID);
+ }
+ public function load($markup, $contentType = null, $newDocumentID = null) {
+ $id = $newDocumentID
+ ? $newDocumentID
+ : md5(microtime());
+ phpQuery::$documents[$id] = $this;
+ $this->contentType = strtolower($contentType);
+ if ($markup instanceof DOMDOCUMENT) {
+ $this->document = $markup;
+ $this->root = $this->document;
+ $this->charset = $this->document->encoding;
+ // TODO isDocumentFragment
+ } else {
+ $loaded = $this->loadMarkup($markup);
+ }
+ if ($loaded) {
+ $this->xpath = new DOMXPath($this->document);
+ $this->afterMarkupLoad();
+ // remember last loaded document
+ return phpQuery::selectDocument($id);
+ }
+ }
+ protected function afterMarkupLoad() {
+ if ($this->isXHTML) {
+ $this->xpath->registerNamespace("html", "http://www.w3.org/1999/xhtml");
+ }
+ }
+ protected function loadMarkup($markup) {
+ $loaded = false;
+ if ($this->contentType) {
+ self::debug("Load markup for content type {$this->contentType}");
+ // content determined by contentType
+ list($contentType, $charset) = $this->contentTypeToArray($this->contentType);
+ switch($contentType) {
+ case 'text/html':
+ $loaded = $this->loadMarkupHTML($markup, $charset);
+ break;
+ case 'text/xml':
+ case 'application/xhtml+xml':
+ $loaded = $this->loadMarkupXML($markup, $charset);
+ break;
+ default:
+ // for feeds or anything that sometimes doesn't use text/xml
+ if (strpos('xml', $this->contentType) !== false)
+ $loaded = $this->loadMarkupXML($markup, $charset);
+ else
+ phpQuery::debug("Could not determine document type from content type '{$this->contentType}'");
+ }
+ } else {
+ // content type autodetection
+ if ($this->isXML($markup)) {
+ $loaded = $this->loadMarkupXML($markup);
+ if (! $loaded && $this->isXHTML) {
+ phpQuery::debug('Loading as XML failed, trying to load as HTML');
+ $loaded = $this->loadMarkupHTML($markup);
+ }
+ } else {
+ $loaded = $this->loadMarkupHTML($markup);
+ }
+ }
+ return $loaded;
+ }
+ protected function loadMarkupReset() {
+ $this->isXML = $this->isXHTML = $this->isHTML = false;
+ }
+ protected function documentCreate($charset, $version = '1.0') {
+ if (! $version)
+ $version = '1.0';
+ $this->document = new DOMDocument($version, $charset);
+ $this->charset = $this->document->encoding;
+// $this->document->encoding = $charset;
+ $this->document->formatOutput = true;
+ $this->document->preserveWhiteSpace = true;
+ }
+ protected function loadMarkupHTML($markup, $requestedCharset = null) {
+ if (phpQuery::$debug)
+ phpQuery::debug('Full markup load (HTML): '.substr($markup, 0, 250));
+ $this->loadMarkupReset();
+ $this->isHTML = true;
+ if (!isset($this->isDocumentFragment))
+ $this->isDocumentFragment = self::isDocumentFragmentHTML($markup);
+ $charset = null;
+ $documentCharset = $this->charsetFromHTML($markup);
+ if ($documentCharset) {
+ $charset = $documentCharset;
+ $markup = $this->charsetFixHTML($markup);
+ } else if ($requestedCharset) {
+ $charset = $requestedCharset;
+ }
+ if (! $charset)
+ $charset = phpQuery::$defaultCharset;
+ if ($requestedCharset && $documentCharset && $requestedCharset != $documentCharset) {
+ // TODO place for charset conversion
+ // http://code.google.com/p/phpquery/issues/detail?id=86
+// $charset = $requestedCharset;
+ }
+ $return = false;
+ if ($this->isDocumentFragment) {
+ phpQuery::debug("Full markup load (HTML), DocumentFragment detected, using charset '$charset'");
+ $return = $this->documentFragmentLoadMarkup($this, $charset, $markup);
+ } else {
+ if (! $documentCharset) {
+ phpQuery::debug("Full markup load (HTML), appending charset '$charset'");
+ $markup = $this->charsetAppendToHTML($markup, $charset);
+ } else {
+ $charset = $documentCharset;
+ phpQuery::debug("Full markup load (HTML), using document's charset '{$charset}'");
+ }
+ $this->documentCreate($charset);
+ $return = phpQuery::$debug === 2
+ ? $this->document->loadHTML($markup)
+ : @$this->document->loadHTML($markup);
+ if ($return)
+ $this->root = $this->document;
+ }
+ if ($return && ! $this->contentType)
+ $this->contentType = 'text/html';
+ return $return;
+ }
+ protected function loadMarkupXML($markup, $requestedCharset = null) {
+ if (phpQuery::$debug)
+ phpQuery::debug('Full markup load (XML): '.substr($markup, 0, 250));
+ $this->loadMarkupReset();
+ $this->isXML = true;
+ // check agains XHTML in contentType or markup
+ $isContentTypeXHTML = $this->isXHTML();
+ $isMarkupXHTML = $this->isXHTML($markup);
+ if ($isContentTypeXHTML || $isMarkupXHTML) {
+ self::debug('Full markup load (XML), XHTML detected');
+ $this->isXHTML = true;
+ }
+ // determine document fragment
+ if (! isset($this->isDocumentFragment))
+ $this->isDocumentFragment = $this->isXHTML
+ ? self::isDocumentFragmentXHTML($markup)
+ : self::isDocumentFragmentXML($markup);
+ // this charset will be used
+ $charset = null;
+ // charset from XML declaration @var string
+ $documentCharset = $this->charsetFromXML($markup);
+ if (! $documentCharset) {
+ if ($this->isXHTML) {
+ // this is XHTML, try to get charset from content-type meta header
+ $documentCharset = $this->charsetFromHTML($markup);
+ if ($documentCharset) {
+ phpQuery::debug("Full markup load (XML), appending XHTML charset '$documentCharset'");
+ $this->charsetAppendToXML($markup, $documentCharset);
+ $charset = $documentCharset;
+ }
+ }
+ if (! $documentCharset) {
+ // if still no document charset...
+ $charset = $requestedCharset;
+ }
+ } else if ($requestedCharset) {
+ $charset = $requestedCharset;
+ }
+ if (! $charset) {
+ $charset = phpQuery::$defaultCharset;
+ }
+ if ($requestedCharset && $documentCharset && $requestedCharset != $documentCharset) {
+ // TODO place for charset conversion
+// $charset = $requestedCharset;
+ }
+ $return = false;
+ if ($this->isDocumentFragment) {
+ phpQuery::debug("Full markup load (XML), DocumentFragment detected, using charset '$charset'");
+ $return = $this->documentFragmentLoadMarkup($this, $charset, $markup);
+ } else {
+ // FIXME ???
+ if ($isContentTypeXHTML && ! $isMarkupXHTML)
+ if (! $documentCharset) {
+ phpQuery::debug("Full markup load (XML), appending charset '$charset'");
+ $markup = $this->charsetAppendToXML($markup, $charset);
+ }
+ // see http://pl2.php.net/manual/en/book.dom.php#78929
+ // LIBXML_DTDLOAD (>= PHP 5.1)
+ // does XML ctalogues works with LIBXML_NONET
+ // $this->document->resolveExternals = true;
+ // TODO test LIBXML_COMPACT for performance improvement
+ // create document
+ $this->documentCreate($charset);
+ if (phpversion() < 5.1) {
+ $this->document->resolveExternals = true;
+ $return = phpQuery::$debug === 2
+ ? $this->document->loadXML($markup)
+ : @$this->document->loadXML($markup);
+ } else {
+ /** @link http://pl2.php.net/manual/en/libxml.constants.php */
+ $libxmlStatic = phpQuery::$debug === 2
+ ? LIBXML_DTDLOAD|LIBXML_DTDATTR|LIBXML_NONET
+ : LIBXML_DTDLOAD|LIBXML_DTDATTR|LIBXML_NONET|LIBXML_NOWARNING|LIBXML_NOERROR;
+ $return = $this->document->loadXML($markup, $libxmlStatic);
+// if (! $return)
+// $return = $this->document->loadHTML($markup);
+ }
+ if ($return)
+ $this->root = $this->document;
+ }
+ if ($return) {
+ if (! $this->contentType) {
+ if ($this->isXHTML)
+ $this->contentType = 'application/xhtml+xml';
+ else
+ $this->contentType = 'text/xml';
+ }
+ return $return;
+ } else {
+ throw new Exception("Error loading XML markup");
+ }
+ }
+ protected function isXHTML($markup = null) {
+ if (! isset($markup)) {
+ return strpos($this->contentType, 'xhtml') !== false;
+ }
+ // XXX ok ?
+ return strpos($markup, "<!DOCTYPE html") !== false;
+// return stripos($doctype, 'xhtml') !== false;
+// $doctype = isset($dom->doctype) && is_object($dom->doctype)
+// ? $dom->doctype->publicId
+// : self::$defaultDoctype;
+ }
+ protected function isXML($markup) {
+// return strpos($markup, '<?xml') !== false && stripos($markup, 'xhtml') === false;
+ return strpos($markup, '<'.'?xml') !== false;
+ }
+ protected function contentTypeToArray($contentType) {
+ $matches = explode(';', trim(strtolower($contentType)));
+ if (isset($matches[1])) {
+ $matches[1] = explode('=', $matches[1]);
+ // strip 'charset='
+ $matches[1] = isset($matches[1][1]) && trim($matches[1][1])
+ ? $matches[1][1]
+ : $matches[1][0];
+ } else
+ $matches[1] = null;
+ return $matches;
+ }
+ /**
+ *
+ * @param $markup
+ * @return array contentType, charset
+ */
+ protected function contentTypeFromHTML($markup) {
+ $matches = array();
+ // find meta tag
+ preg_match('@<meta[^>]+http-equiv\\s*=\\s*(["|\'])Content-Type\\1([^>]+?)>@i',
+ $markup, $matches
+ );
+ if (! isset($matches[0]))
+ return array(null, null);
+ // get attr 'content'
+ preg_match('@content\\s*=\\s*(["|\'])(.+?)\\1@', $matches[0], $matches);
+ if (! isset($matches[0]))
+ return array(null, null);
+ return $this->contentTypeToArray($matches[2]);
+ }
+ protected function charsetFromHTML($markup) {
+ $contentType = $this->contentTypeFromHTML($markup);
+ return $contentType[1];
+ }
+ protected function charsetFromXML($markup) {
+ $matches;
+ // find declaration
+ preg_match('@<'.'?xml[^>]+encoding\\s*=\\s*(["|\'])(.*?)\\1@i',
+ $markup, $matches
+ );
+ return isset($matches[2])
+ ? strtolower($matches[2])
+ : null;
+ }
+ /**
+ * Repositions meta[type=charset] at the start of head. Bypasses DOMDocument bug.
+ *
+ * @link http://code.google.com/p/phpquery/issues/detail?id=80
+ * @param $html
+ */
+ protected function charsetFixHTML($markup) {
+ $matches = array();
+ // find meta tag
+ preg_match('@\s*<meta[^>]+http-equiv\\s*=\\s*(["|\'])Content-Type\\1([^>]+?)>@i',
+ $markup, $matches, PREG_OFFSET_CAPTURE
+ );
+ if (! isset($matches[0]))
+ return;
+ $metaContentType = $matches[0][0];
+ $markup = substr($markup, 0, $matches[0][1])
+ .substr($markup, $matches[0][1]+strlen($metaContentType));
+ $headStart = stripos($markup, '<head>');
+ $markup = substr($markup, 0, $headStart+6).$metaContentType
+ .substr($markup, $headStart+6);
+ return $markup;
+ }
+ protected function charsetAppendToHTML($html, $charset, $xhtml = false) {
+ $meta = '<meta http-equiv="Content-Type" content="text/html;charset='
+ .$charset.'" '
+ .($xhtml ? '/' : '')
+ .'>';
+ if (strpos($html, '<head') === false) {
+ if (strpos($html, '<html') === false) {
+ return $meta.$html;
+ } else {
+ return preg_replace(
+ '@<html(.*?)(?(?<!\?)>)@s',
+ "<html\\1><head>{$meta}</head>",
+ $html
+ );
+ }
+ } else {
+ return preg_replace(
+ '@<head(.*?)(?(?<!\?)>)@s',
+ '<head\\1>'.$meta,
+ $html
+ );
+ }
+ }
+ protected function charsetAppendToXML($markup, $charset) {
+ $declaration = '<'.'?xml version="1.0" encoding="'.$charset.'"?'.'>';
+ return $declaration.$markup;
+ }
+ public static function isDocumentFragmentHTML($markup) {
+ return stripos($markup, '<html') === false && stripos($markup, '<!doctype') === false;
+ }
+ public static function isDocumentFragmentXML($markup) {
+ return stripos($markup, '<'.'?xml') === false;
+ }
+ public static function isDocumentFragmentXHTML($markup) {
+ return self::isDocumentFragmentHTML($markup);
+ }
+ public function importAttr($value) {
+ // TODO
+ }
+ /**
+ *
+ * @param $source
+ * @param $target
+ * @param $sourceCharset
+ * @return array Array of imported nodes.
+ */
+ public function import($source, $sourceCharset = null) {
+ // TODO charset conversions
+ $return = array();
+ if ($source instanceof DOMNODE && !($source instanceof DOMNODELIST))
+ $source = array($source);
+ if (is_array($source) || $source instanceof DOMNODELIST) {
+ // dom nodes
+ self::debug('Importing nodes to document');
+ foreach($source as $node)
+ $return[] = $this->document->importNode($node, true);
+ } else {
+ // string markup
+ $fake = $this->documentFragmentCreate($source, $sourceCharset);
+ if ($fake === false)
+ throw new Exception("Error loading documentFragment markup");
+ else
+ return $this->import($fake->root->childNodes);
+ }
+ return $return;
+ }
+ /**
+ * Creates new document fragment.
+ *
+ * @param $source
+ * @return DOMDocumentWrapper
+ */
+ protected function documentFragmentCreate($source, $charset = null) {
+ $fake = new DOMDocumentWrapper();
+ $fake->contentType = $this->contentType;
+ $fake->isXML = $this->isXML;
+ $fake->isHTML = $this->isHTML;
+ $fake->isXHTML = $this->isXHTML;
+ $fake->root = $fake->document;
+ if (! $charset)
+ $charset = $this->charset;
+// $fake->documentCreate($this->charset);
+ if ($source instanceof DOMNODE && !($source instanceof DOMNODELIST))
+ $source = array($source);
+ if (is_array($source) || $source instanceof DOMNODELIST) {
+ // dom nodes
+ // load fake document
+ if (! $this->documentFragmentLoadMarkup($fake, $charset))
+ return false;
+ $nodes = $fake->import($source);
+ foreach($nodes as $node)
+ $fake->root->appendChild($node);
+ } else {
+ // string markup
+ $this->documentFragmentLoadMarkup($fake, $charset, $source);
+ }
+ return $fake;
+ }
+ /**
+ *
+ * @param $document DOMDocumentWrapper
+ * @param $markup
+ * @return $document
+ */
+ private function documentFragmentLoadMarkup($fragment, $charset, $markup = null) {
+ // TODO error handling
+ // TODO copy doctype
+ // tempolary turn off
+ $fragment->isDocumentFragment = false;
+ if ($fragment->isXML) {
+ if ($fragment->isXHTML) {
+ // add FAKE element to set default namespace
+ $fragment->loadMarkupXML('<?xml version="1.0" encoding="'.$charset.'"?>'
+ .'<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" '
+ .'"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">'
+ .'<fake xmlns="http://www.w3.org/1999/xhtml">'.$markup.'</fake>');
+ $fragment->root = $fragment->document->firstChild->nextSibling;
+ } else {
+ $fragment->loadMarkupXML('<?xml version="1.0" encoding="'.$charset.'"?><fake>'.$markup.'</fake>');
+ $fragment->root = $fragment->document->firstChild;
+ }
+ } else {
+ $markup2 = phpQuery::$defaultDoctype.'<html><head><meta http-equiv="Content-Type" content="text/html;charset='
+ .$charset.'"></head>';
+ $noBody = strpos($markup, '<body') === false;
+ if ($noBody)
+ $markup2 .= '<body>';
+ $markup2 .= $markup;
+ if ($noBody)
+ $markup2 .= '</body>';
+ $markup2 .= '</html>';
+ $fragment->loadMarkupHTML($markup2);
+ // TODO resolv body tag merging issue
+ $fragment->root = $noBody
+ ? $fragment->document->firstChild->nextSibling->firstChild->nextSibling
+ : $fragment->document->firstChild->nextSibling->firstChild->nextSibling;
+ }
+ if (! $fragment->root)
+ return false;
+ $fragment->isDocumentFragment = true;
+ return true;
+ }
+ protected function documentFragmentToMarkup($fragment) {
+ phpQuery::debug('documentFragmentToMarkup');
+ $tmp = $fragment->isDocumentFragment;
+ $fragment->isDocumentFragment = false;
+ $markup = $fragment->markup();
+ if ($fragment->isXML) {
+ $markup = substr($markup, 0, strrpos($markup, '</fake>'));
+ if ($fragment->isXHTML) {
+ $markup = substr($markup, strpos($markup, '<fake')+43);
+ } else {
+ $markup = substr($markup, strpos($markup, '<fake>')+6);
+ }
+ } else {
+ $markup = substr($markup, strpos($markup, '<body>')+6);
+ $markup = substr($markup, 0, strrpos($markup, '</body>'));
+ }
+ $fragment->isDocumentFragment = $tmp;
+ if (phpQuery::$debug)
+ phpQuery::debug('documentFragmentToMarkup: '.substr($markup, 0, 150));
+ return $markup;
+ }
+ /**
+ * Return document markup, starting with optional $node as root.
+ *
+ * @param $node DOMNode|DOMNodeList
+ * @return string
+ */
+ public function markup($nodes = null, $innerMarkup = false) {
+ if (isset($nodes) && count($nodes) == 1 && $nodes[0] instanceof DOMDOCUMENT)
+ $nodes = null;
+ if (isset($nodes)) {
+ $markup = '';
+ if (!is_array($nodes) && !($nodes instanceof DOMNODELIST) )
+ $nodes = array($nodes);
+ if ($this->isDocumentFragment && ! $innerMarkup)
+ foreach($nodes as $i => $node)
+ if ($node->isSameNode($this->root)) {
+ // var_dump($node);
+ $nodes = array_slice($nodes, 0, $i)
+ + phpQuery::DOMNodeListToArray($node->childNodes)
+ + array_slice($nodes, $i+1);
+ }
+ if ($this->isXML && ! $innerMarkup) {
+ self::debug("Getting outerXML with charset '{$this->charset}'");
+ // we need outerXML, so we can benefit from
+ // $node param support in saveXML()
+ foreach($nodes as $node)
+ $markup .= $this->document->saveXML($node);
+ } else {
+ $loop = array();
+ if ($innerMarkup)
+ foreach($nodes as $node)
+ foreach($node->childNodes as $child)
+ $loop[] = $child;
+ else
+ $loop = $nodes;
+ self::debug("Getting markup, moving selected nodes (".count($loop).") to new DocumentFragment");
+ $fake = $this->documentFragmentCreate($loop);
+ $markup = $this->documentFragmentToMarkup($fake);
+ }
+ if ($this->isXHTML) {
+ self::debug("Fixing XHTML");
+ $markup = self::markupFixXHTML($markup);
+ }
+ self::debug("Markup: ".substr($markup, 0, 250));
+ return $markup;
+ } else {
+ if ($this->isDocumentFragment) {
+ // documentFragment, html only...
+ self::debug("Getting markup, DocumentFragment detected");
+// return $this->markup(
+//// $this->document->getElementsByTagName('body')->item(0)
+// $this->document->root, true
+// );
+ $markup = $this->documentFragmentToMarkup($this);
+ // no need for markupFixXHTML, as it's done thought markup($nodes) method
+ return $markup;
+ } else {
+ self::debug("Getting markup (".($this->isXML?'XML':'HTML')."), final with charset '{$this->charset}'");
+ $markup = $this->isXML
+ ? $this->document->saveXML()
+ : $this->document->saveHTML();
+ if ($this->isXHTML) {
+ self::debug("Fixing XHTML");
+ $markup = self::markupFixXHTML($markup);
+ }
+ self::debug("Markup: ".substr($markup, 0, 250));
+ return $markup;
+ }
+ }
+ }
+ protected static function markupFixXHTML($markup) {
+ $markup = self::expandEmptyTag('script', $markup);
+ $markup = self::expandEmptyTag('select', $markup);
+ $markup = self::expandEmptyTag('textarea', $markup);
+ return $markup;
+ }
+ public static function debug($text) {
+ phpQuery::debug($text);
+ }
+ /**
+ * expandEmptyTag
+ *
+ * @param $tag
+ * @param $xml
+ * @return unknown_type
+ * @author mjaque at ilkebenson dot com
+ * @link http://pl2.php.net/manual/en/domdocument.savehtml.php#81256
+ */
+ public static function expandEmptyTag($tag, $xml){
+ $indice = 0;
+ while ($indice< strlen($xml)){
+ $pos = strpos($xml, "<$tag ", $indice);
+ if ($pos){
+ $posCierre = strpos($xml, ">", $pos);
+ if ($xml[$posCierre-1] == "/"){
+ $xml = substr_replace($xml, "></$tag>", $posCierre-1, 2);
+ }
+ $indice = $posCierre;
+ }
+ else break;
+ }
+ return $xml;
+ }
+} \ No newline at end of file
diff --git a/site/vendors/phpQuery/DOMEvent.php b/site/vendors/phpQuery/DOMEvent.php
new file mode 100644
index 0000000..8c7dfe8
--- /dev/null
+++ b/site/vendors/phpQuery/DOMEvent.php
@@ -0,0 +1,107 @@
+<?php
+/**
+ * DOMEvent class.
+ *
+ * Based on
+ * @link http://developer.mozilla.org/En/DOM:event
+ * @author Tobiasz Cudnik <tobiasz.cudnik/gmail.com>
+ * @package phpQuery
+ * @todo implement ArrayAccess ?
+ */
+class DOMEvent {
+ /**
+ * Returns a boolean indicating whether the event bubbles up through the DOM or not.
+ *
+ * @var unknown_type
+ */
+ public $bubbles = true;
+ /**
+ * Returns a boolean indicating whether the event is cancelable.
+ *
+ * @var unknown_type
+ */
+ public $cancelable = true;
+ /**
+ * Returns a reference to the currently registered target for the event.
+ *
+ * @var unknown_type
+ */
+ public $currentTarget;
+ /**
+ * Returns detail about the event, depending on the type of event.
+ *
+ * @var unknown_type
+ * @link http://developer.mozilla.org/en/DOM/event.detail
+ */
+ public $detail; // ???
+ /**
+ * Used to indicate which phase of the event flow is currently being evaluated.
+ *
+ * NOT IMPLEMENTED
+ *
+ * @var unknown_type
+ * @link http://developer.mozilla.org/en/DOM/event.eventPhase
+ */
+ public $eventPhase; // ???
+ /**
+ * The explicit original target of the event (Mozilla-specific).
+ *
+ * NOT IMPLEMENTED
+ *
+ * @var unknown_type
+ */
+ public $explicitOriginalTarget; // moz only
+ /**
+ * The original target of the event, before any retargetings (Mozilla-specific).
+ *
+ * NOT IMPLEMENTED
+ *
+ * @var unknown_type
+ */
+ public $originalTarget; // moz only
+ /**
+ * Identifies a secondary target for the event.
+ *
+ * @var unknown_type
+ */
+ public $relatedTarget;
+ /**
+ * Returns a reference to the target to which the event was originally dispatched.
+ *
+ * @var unknown_type
+ */
+ public $target;
+ /**
+ * Returns the time that the event was created.
+ *
+ * @var unknown_type
+ */
+ public $timeStamp;
+ /**
+ * Returns the name of the event (case-insensitive).
+ */
+ public $type;
+ public $runDefault = true;
+ public $data = null;
+ public function __construct($data) {
+ foreach($data as $k => $v) {
+ $this->$k = $v;
+ }
+ if (! $this->timeStamp)
+ $this->timeStamp = time();
+ }
+ /**
+ * Cancels the event (if it is cancelable).
+ *
+ */
+ public function preventDefault() {
+ $this->runDefault = false;
+ }
+ /**
+ * Stops the propagation of events further along in the DOM.
+ *
+ */
+ public function stopPropagation() {
+ $this->bubbles = false;
+ }
+} \ No newline at end of file
diff --git a/site/vendors/phpQuery/LICENSE b/site/vendors/phpQuery/LICENSE
new file mode 100644
index 0000000..b1b9855
--- /dev/null
+++ b/site/vendors/phpQuery/LICENSE
@@ -0,0 +1,19 @@
+
+ The MIT License
+Copyright (c) <year> <copyright holders>
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
diff --git a/site/vendors/phpQuery/Zend/Exception.php b/site/vendors/phpQuery/Zend/Exception.php
new file mode 100644
index 0000000..599d8a0
--- /dev/null
+++ b/site/vendors/phpQuery/Zend/Exception.php
@@ -0,0 +1,30 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+
+/**
+ * @category Zend
+ * @package Zend
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Exception extends Exception
+{}
+
diff --git a/site/vendors/phpQuery/Zend/Http/Client.php b/site/vendors/phpQuery/Zend/Http/Client.php
new file mode 100644
index 0000000..876fb96
--- /dev/null
+++ b/site/vendors/phpQuery/Zend/Http/Client.php
@@ -0,0 +1,1186 @@
+<?php
+
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Http
+ * @subpackage Client
+ * @version $Id: Client.php 9906 2008-07-02 21:20:10Z shahar $
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+/**
+ * @see Zend_Loader
+ */
+require_once 'Zend/Loader.php';
+
+
+/**
+ * @see Zend_Uri
+ */
+require_once 'Zend/Uri.php';
+
+
+/**
+ * @see Zend_Http_Client_Adapter_Interface
+ */
+require_once 'Zend/Http/Client/Adapter/Interface.php';
+
+
+/**
+ * @see Zend_Http_Response
+ */
+require_once 'Zend/Http/Response.php';
+
+/**
+ * Zend_Http_Client is an implemetation of an HTTP client in PHP. The client
+ * supports basic features like sending different HTTP requests and handling
+ * redirections, as well as more advanced features like proxy settings, HTTP
+ * authentication and cookie persistance (using a Zend_Http_CookieJar object)
+ *
+ * @todo Implement proxy settings
+ * @category Zend
+ * @package Zend_Http
+ * @subpackage Client
+ * @throws Zend_Http_Client_Exception
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Http_Client
+{
+ /**
+ * HTTP request methods
+ */
+ const GET = 'GET';
+ const POST = 'POST';
+ const PUT = 'PUT';
+ const HEAD = 'HEAD';
+ const DELETE = 'DELETE';
+ const TRACE = 'TRACE';
+ const OPTIONS = 'OPTIONS';
+ const CONNECT = 'CONNECT';
+
+ /**
+ * Supported HTTP Authentication methods
+ */
+ const AUTH_BASIC = 'basic';
+ //const AUTH_DIGEST = 'digest'; <-- not implemented yet
+
+ /**
+ * HTTP protocol versions
+ */
+ const HTTP_1 = '1.1';
+ const HTTP_0 = '1.0';
+
+ /**
+ * POST data encoding methods
+ */
+ const ENC_URLENCODED = 'application/x-www-form-urlencoded';
+ const ENC_FORMDATA = 'multipart/form-data';
+
+ /**
+ * Configuration array, set using the constructor or using ::setConfig()
+ *
+ * @var array
+ */
+ protected $config = array(
+ 'maxredirects' => 5,
+ 'strictredirects' => false,
+ 'useragent' => 'Zend_Http_Client',
+ 'timeout' => 10,
+ 'adapter' => 'Zend_Http_Client_Adapter_Socket',
+ 'httpversion' => self::HTTP_1,
+ 'keepalive' => false,
+ 'storeresponse' => true,
+ 'strict' => true
+ );
+
+ /**
+ * The adapter used to preform the actual connection to the server
+ *
+ * @var Zend_Http_Client_Adapter_Interface
+ */
+ protected $adapter = null;
+
+ /**
+ * Request URI
+ *
+ * @var Zend_Uri_Http
+ */
+ protected $uri;
+
+ /**
+ * Associative array of request headers
+ *
+ * @var array
+ */
+ protected $headers = array();
+
+ /**
+ * HTTP request method
+ *
+ * @var string
+ */
+ protected $method = self::GET;
+
+ /**
+ * Associative array of GET parameters
+ *
+ * @var array
+ */
+ protected $paramsGet = array();
+
+ /**
+ * Assiciative array of POST parameters
+ *
+ * @var array
+ */
+ protected $paramsPost = array();
+
+ /**
+ * Request body content type (for POST requests)
+ *
+ * @var string
+ */
+ protected $enctype = null;
+
+ /**
+ * The raw post data to send. Could be set by setRawData($data, $enctype).
+ *
+ * @var string
+ */
+ protected $raw_post_data = null;
+
+ /**
+ * HTTP Authentication settings
+ *
+ * Expected to be an associative array with this structure:
+ * $this->auth = array('user' => 'username', 'password' => 'password', 'type' => 'basic')
+ * Where 'type' should be one of the supported authentication types (see the AUTH_*
+ * constants), for example 'basic' or 'digest'.
+ *
+ * If null, no authentication will be used.
+ *
+ * @var array|null
+ */
+ protected $auth;
+
+ /**
+ * File upload arrays (used in POST requests)
+ *
+ * An associative array, where each element is of the format:
+ * 'name' => array('filename.txt', 'text/plain', 'This is the actual file contents')
+ *
+ * @var array
+ */
+ protected $files = array();
+
+ /**
+ * The client's cookie jar
+ *
+ * @var Zend_Http_CookieJar
+ */
+ protected $cookiejar = null;
+
+ /**
+ * The last HTTP request sent by the client, as string
+ *
+ * @var string
+ */
+ protected $last_request = null;
+
+ /**
+ * The last HTTP response received by the client
+ *
+ * @var Zend_Http_Response
+ */
+ protected $last_response = null;
+
+ /**
+ * Redirection counter
+ *
+ * @var int
+ */
+ protected $redirectCounter = 0;
+
+ /**
+ * Fileinfo magic database resource
+ *
+ * This varaiable is populated the first time _detectFileMimeType is called
+ * and is then reused on every call to this method
+ *
+ * @var resource
+ */
+ static protected $_fileInfoDb = null;
+
+ /**
+ * Contructor method. Will create a new HTTP client. Accepts the target
+ * URL and optionally configuration array.
+ *
+ * @param Zend_Uri_Http|string $uri
+ * @param array $config Configuration key-value pairs.
+ */
+ public function __construct($uri = null, $config = null)
+ {
+ if ($uri !== null) $this->setUri($uri);
+ if ($config !== null) $this->setConfig($config);
+ }
+
+ /**
+ * Set the URI for the next request
+ *
+ * @param Zend_Uri_Http|string $uri
+ * @return Zend_Http_Client
+ * @throws Zend_Http_Client_Exception
+ */
+ public function setUri($uri)
+ {
+ if (is_string($uri)) {
+ $uri = Zend_Uri::factory($uri);
+ }
+
+ if (!$uri instanceof Zend_Uri_Http) {
+ /** @see Zend_Http_Client_Exception */
+ require_once 'Zend/Http/Client/Exception.php';
+ throw new Zend_Http_Client_Exception('Passed parameter is not a valid HTTP URI.');
+ }
+
+ // We have no ports, set the defaults
+ if (! $uri->getPort()) {
+ $uri->setPort(($uri->getScheme() == 'https' ? 443 : 80));
+ }
+
+ $this->uri = $uri;
+
+ return $this;
+ }
+
+ /**
+ * Get the URI for the next request
+ *
+ * @param boolean $as_string If true, will return the URI as a string
+ * @return Zend_Uri_Http|string
+ */
+ public function getUri($as_string = false)
+ {
+ if ($as_string && $this->uri instanceof Zend_Uri_Http) {
+ return $this->uri->__toString();
+ } else {
+ return $this->uri;
+ }
+ }
+
+ /**
+ * Set configuration parameters for this HTTP client
+ *
+ * @param array $config
+ * @return Zend_Http_Client
+ * @throws Zend_Http_Client_Exception
+ */
+ public function setConfig($config = array())
+ {
+ if (! is_array($config)) {
+ /** @see Zend_Http_Client_Exception */
+ require_once 'Zend/Http/Client/Exception.php';
+ throw new Zend_Http_Client_Exception('Expected array parameter, given ' . gettype($config));
+ }
+
+ foreach ($config as $k => $v)
+ $this->config[strtolower($k)] = $v;
+
+ return $this;
+ }
+
+ /**
+ * Set the next request's method
+ *
+ * Validated the passed method and sets it. If we have files set for
+ * POST requests, and the new method is not POST, the files are silently
+ * dropped.
+ *
+ * @param string $method
+ * @return Zend_Http_Client
+ * @throws Zend_Http_Client_Exception
+ */
+ public function setMethod($method = self::GET)
+ {
+ $regex = '/^[^\x00-\x1f\x7f-\xff\(\)<>@,;:\\\\"\/\[\]\?={}\s]+$/';
+ if (! preg_match($regex, $method)) {
+ /** @see Zend_Http_Client_Exception */
+ require_once 'Zend/Http/Client/Exception.php';
+ throw new Zend_Http_Client_Exception("'{$method}' is not a valid HTTP request method.");
+ }
+
+ if ($method == self::POST && $this->enctype === null)
+ $this->setEncType(self::ENC_URLENCODED);
+
+ $this->method = $method;
+
+ return $this;
+ }
+
+ /**
+ * Set one or more request headers
+ *
+ * This function can be used in several ways to set the client's request
+ * headers:
+ * 1. By providing two parameters: $name as the header to set (eg. 'Host')
+ * and $value as it's value (eg. 'www.example.com').
+ * 2. By providing a single header string as the only parameter
+ * eg. 'Host: www.example.com'
+ * 3. By providing an array of headers as the first parameter
+ * eg. array('host' => 'www.example.com', 'x-foo: bar'). In This case
+ * the function will call itself recursively for each array item.
+ *
+ * @param string|array $name Header name, full header string ('Header: value')
+ * or an array of headers
+ * @param mixed $value Header value or null
+ * @return Zend_Http_Client
+ * @throws Zend_Http_Client_Exception
+ */
+ public function setHeaders($name, $value = null)
+ {
+ // If we got an array, go recusive!
+ if (is_array($name)) {
+ foreach ($name as $k => $v) {
+ if (is_string($k)) {
+ $this->setHeaders($k, $v);
+ } else {
+ $this->setHeaders($v, null);
+ }
+ }
+ } else {
+ // Check if $name needs to be split
+ if ($value === null && (strpos($name, ':') > 0))
+ list($name, $value) = explode(':', $name, 2);
+
+ // Make sure the name is valid if we are in strict mode
+ if ($this->config['strict'] && (! preg_match('/^[a-zA-Z0-9-]+$/', $name))) {
+ /** @see Zend_Http_Client_Exception */
+ require_once 'Zend/Http/Client/Exception.php';
+ throw new Zend_Http_Client_Exception("{$name} is not a valid HTTP header name");
+ }
+
+ $normalized_name = strtolower($name);
+
+ // If $value is null or false, unset the header
+ if ($value === null || $value === false) {
+ unset($this->headers[$normalized_name]);
+
+ // Else, set the header
+ } else {
+ // Header names are storred lowercase internally.
+ if (is_string($value)) $value = trim($value);
+ $this->headers[$normalized_name] = array($name, $value);
+ }
+ }
+
+ return $this;
+ }
+
+ /**
+ * Get the value of a specific header
+ *
+ * Note that if the header has more than one value, an array
+ * will be returned.
+ *
+ * @param string $key
+ * @return string|array|null The header value or null if it is not set
+ */
+ public function getHeader($key)
+ {
+ $key = strtolower($key);
+ if (isset($this->headers[$key])) {
+ return $this->headers[$key][1];
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Set a GET parameter for the request. Wrapper around _setParameter
+ *
+ * @param string|array $name
+ * @param string $value
+ * @return Zend_Http_Client
+ */
+ public function setParameterGet($name, $value = null)
+ {
+ if (is_array($name)) {
+ foreach ($name as $k => $v)
+ $this->_setParameter('GET', $k, $v);
+ } else {
+ $this->_setParameter('GET', $name, $value);
+ }
+
+ return $this;
+ }
+
+ /**
+ * Set a POST parameter for the request. Wrapper around _setParameter
+ *
+ * @param string|array $name
+ * @param string $value
+ * @return Zend_Http_Client
+ */
+ public function setParameterPost($name, $value = null)
+ {
+ if (is_array($name)) {
+ foreach ($name as $k => $v)
+ $this->_setParameter('POST', $k, $v);
+ } else {
+ $this->_setParameter('POST', $name, $value);
+ }
+
+ return $this;
+ }
+
+ /**
+ * Set a GET or POST parameter - used by SetParameterGet and SetParameterPost
+ *
+ * @param string $type GET or POST
+ * @param string $name
+ * @param string $value
+ * @return null
+ */
+ protected function _setParameter($type, $name, $value)
+ {
+ $parray = array();
+ $type = strtolower($type);
+ switch ($type) {
+ case 'get':
+ $parray = &$this->paramsGet;
+ break;
+ case 'post':
+ $parray = &$this->paramsPost;
+ break;
+ }
+
+ if ($value === null) {
+ if (isset($parray[$name])) unset($parray[$name]);
+ } else {
+ $parray[$name] = $value;
+ }
+ }
+
+ /**
+ * Get the number of redirections done on the last request
+ *
+ * @return int
+ */
+ public function getRedirectionsCount()
+ {
+ return $this->redirectCounter;
+ }
+
+ /**
+ * Set HTTP authentication parameters
+ *
+ * $type should be one of the supported types - see the self::AUTH_*
+ * constants.
+ *
+ * To enable authentication:
+ * <code>
+ * $this->setAuth('shahar', 'secret', Zend_Http_Client::AUTH_BASIC);
+ * </code>
+ *
+ * To disable authentication:
+ * <code>
+ * $this->setAuth(false);
+ * </code>
+ *
+ * @see http://www.faqs.org/rfcs/rfc2617.html
+ * @param string|false $user User name or false disable authentication
+ * @param string $password Password
+ * @param string $type Authentication type
+ * @return Zend_Http_Client
+ * @throws Zend_Http_Client_Exception
+ */
+ public function setAuth($user, $password = '', $type = self::AUTH_BASIC)
+ {
+ // If we got false or null, disable authentication
+ if ($user === false || $user === null) {
+ $this->auth = null;
+
+ // Else, set up authentication
+ } else {
+ // Check we got a proper authentication type
+ if (! defined('self::AUTH_' . strtoupper($type))) {
+ /** @see Zend_Http_Client_Exception */
+ require_once 'Zend/Http/Client/Exception.php';
+ throw new Zend_Http_Client_Exception("Invalid or not supported authentication type: '$type'");
+ }
+
+ $this->auth = array(
+ 'user' => (string) $user,
+ 'password' => (string) $password,
+ 'type' => $type
+ );
+ }
+
+ return $this;
+ }
+
+ /**
+ * Set the HTTP client's cookie jar.
+ *
+ * A cookie jar is an object that holds and maintains cookies across HTTP requests
+ * and responses.
+ *
+ * @param Zend_Http_CookieJar|boolean $cookiejar Existing cookiejar object, true to create a new one, false to disable
+ * @return Zend_Http_Client
+ * @throws Zend_Http_Client_Exception
+ */
+ public function setCookieJar($cookiejar = true)
+ {
+ if (! class_exists('Zend_Http_CookieJar'))
+ require_once 'Zend/Http/CookieJar.php';
+
+ if ($cookiejar instanceof Zend_Http_CookieJar) {
+ $this->cookiejar = $cookiejar;
+ } elseif ($cookiejar === true) {
+ $this->cookiejar = new Zend_Http_CookieJar();
+ } elseif (! $cookiejar) {
+ $this->cookiejar = null;
+ } else {
+ /** @see Zend_Http_Client_Exception */
+ require_once 'Zend/Http/Client/Exception.php';
+ throw new Zend_Http_Client_Exception('Invalid parameter type passed as CookieJar');
+ }
+
+ return $this;
+ }
+
+ /**
+ * Return the current cookie jar or null if none.
+ *
+ * @return Zend_Http_CookieJar|null
+ */
+ public function getCookieJar()
+ {
+ return $this->cookiejar;
+ }
+
+ /**
+ * Add a cookie to the request. If the client has no Cookie Jar, the cookies
+ * will be added directly to the headers array as "Cookie" headers.
+ *
+ * @param Zend_Http_Cookie|string $cookie
+ * @param string|null $value If "cookie" is a string, this is the cookie value.
+ * @return Zend_Http_Client
+ * @throws Zend_Http_Client_Exception
+ */
+ public function setCookie($cookie, $value = null)
+ {
+ if (! class_exists('Zend_Http_Cookie'))
+ require_once 'Zend/Http/Cookie.php';
+
+ if (is_array($cookie)) {
+ foreach ($cookie as $c => $v) {
+ if (is_string($c)) {
+ $this->setCookie($c, $v);
+ } else {
+ $this->setCookie($v);
+ }
+ }
+
+ return $this;
+ }
+
+ if ($value !== null) $value = urlencode($value);
+
+ if (isset($this->cookiejar)) {
+ if ($cookie instanceof Zend_Http_Cookie) {
+ $this->cookiejar->addCookie($cookie);
+ } elseif (is_string($cookie) && $value !== null) {
+ $cookie = Zend_Http_Cookie::fromString("{$cookie}={$value}", $this->uri);
+ $this->cookiejar->addCookie($cookie);
+ }
+ } else {
+ if ($cookie instanceof Zend_Http_Cookie) {
+ $name = $cookie->getName();
+ $value = $cookie->getValue();
+ $cookie = $name;
+ }
+
+ if (preg_match("/[=,; \t\r\n\013\014]/", $cookie)) {
+ /** @see Zend_Http_Client_Exception */
+ require_once 'Zend/Http/Client/Exception.php';
+ throw new Zend_Http_Client_Exception("Cookie name cannot contain these characters: =,; \t\r\n\013\014 ({$cookie})");
+ }
+
+ $value = addslashes($value);
+
+ if (! isset($this->headers['cookie'])) $this->headers['cookie'] = array('Cookie', '');
+ $this->headers['cookie'][1] .= $cookie . '=' . $value . '; ';
+ }
+
+ return $this;
+ }
+
+ /**
+ * Set a file to upload (using a POST request)
+ *
+ * Can be used in two ways:
+ *
+ * 1. $data is null (default): $filename is treated as the name if a local file which
+ * will be read and sent. Will try to guess the content type using mime_content_type().
+ * 2. $data is set - $filename is sent as the file name, but $data is sent as the file
+ * contents and no file is read from the file system. In this case, you need to
+ * manually set the content-type ($ctype) or it will default to
+ * application/octet-stream.
+ *
+ * @param string $filename Name of file to upload, or name to save as
+ * @param string $formname Name of form element to send as
+ * @param string $data Data to send (if null, $filename is read and sent)
+ * @param string $ctype Content type to use (if $data is set and $ctype is
+ * null, will be application/octet-stream)
+ * @return Zend_Http_Client
+ * @throws Zend_Http_Client_Exception
+ */
+ public function setFileUpload($filename, $formname, $data = null, $ctype = null)
+ {
+ if ($data === null) {
+ if (($data = @file_get_contents($filename)) === false) {
+ /** @see Zend_Http_Client_Exception */
+ require_once 'Zend/Http/Client/Exception.php';
+ throw new Zend_Http_Client_Exception("Unable to read file '{$filename}' for upload");
+ }
+
+ if (! $ctype) $ctype = $this->_detectFileMimeType($filename);
+ }
+
+ // Force enctype to multipart/form-data
+ $this->setEncType(self::ENC_FORMDATA);
+
+ $this->files[$formname] = array(basename($filename), $ctype, $data);
+
+ return $this;
+ }
+
+ /**
+ * Set the encoding type for POST data
+ *
+ * @param string $enctype
+ * @return Zend_Http_Client
+ */
+ public function setEncType($enctype = self::ENC_URLENCODED)
+ {
+ $this->enctype = $enctype;
+
+ return $this;
+ }
+
+ /**
+ * Set the raw (already encoded) POST data.
+ *
+ * This function is here for two reasons:
+ * 1. For advanced user who would like to set their own data, already encoded
+ * 2. For backwards compatibilty: If someone uses the old post($data) method.
+ * this method will be used to set the encoded data.
+ *
+ * @param string $data
+ * @param string $enctype
+ * @return Zend_Http_Client
+ */
+ public function setRawData($data, $enctype = null)
+ {
+ $this->raw_post_data = $data;
+ $this->setEncType($enctype);
+
+ return $this;
+ }
+
+ /**
+ * Clear all GET and POST parameters
+ *
+ * Should be used to reset the request parameters if the client is
+ * used for several concurrent requests.
+ *
+ * @return Zend_Http_Client
+ */
+ public function resetParameters()
+ {
+ // Reset parameter data
+ $this->paramsGet = array();
+ $this->paramsPost = array();
+ $this->files = array();
+ $this->raw_post_data = null;
+
+ // Clear outdated headers
+ if (isset($this->headers['content-type'])) unset($this->headers['content-type']);
+ if (isset($this->headers['content-length'])) unset($this->headers['content-length']);
+
+ return $this;
+ }
+
+ /**
+ * Get the last HTTP request as string
+ *
+ * @return string
+ */
+ public function getLastRequest()
+ {
+ return $this->last_request;
+ }
+
+ /**
+ * Get the last HTTP response received by this client
+ *
+ * If $config['storeresponse'] is set to false, or no response was
+ * stored yet, will return null
+ *
+ * @return Zend_Http_Response or null if none
+ */
+ public function getLastResponse()
+ {
+ return $this->last_response;
+ }
+
+ /**
+ * Load the connection adapter
+ *
+ * While this method is not called more than one for a client, it is
+ * seperated from ->request() to preserve logic and readability
+ *
+ * @param Zend_Http_Client_Adapter_Interface|string $adapter
+ * @return null
+ * @throws Zend_Http_Client_Exception
+ */
+ public function setAdapter($adapter)
+ {
+ if (is_string($adapter)) {
+ try {
+ Zend_Loader::loadClass($adapter);
+ } catch (Zend_Exception $e) {
+ /** @see Zend_Http_Client_Exception */
+ require_once 'Zend/Http/Client/Exception.php';
+ throw new Zend_Http_Client_Exception("Unable to load adapter '$adapter': {$e->getMessage()}");
+ }
+
+ $adapter = new $adapter;
+ }
+
+ if (! $adapter instanceof Zend_Http_Client_Adapter_Interface) {
+ /** @see Zend_Http_Client_Exception */
+ require_once 'Zend/Http/Client/Exception.php';
+ throw new Zend_Http_Client_Exception('Passed adapter is not a HTTP connection adapter');
+ }
+
+ $this->adapter = $adapter;
+ $config = $this->config;
+ unset($config['adapter']);
+ $this->adapter->setConfig($config);
+ }
+
+ /**
+ * Send the HTTP request and return an HTTP response object
+ *
+ * @param string $method
+ * @return Zend_Http_Response
+ * @throws Zend_Http_Client_Exception
+ */
+ public function request($method = null)
+ {
+ if (! $this->uri instanceof Zend_Uri_Http) {
+ /** @see Zend_Http_Client_Exception */
+ require_once 'Zend/Http/Client/Exception.php';
+ throw new Zend_Http_Client_Exception('No valid URI has been passed to the client');
+ }
+
+ if ($method) $this->setMethod($method);
+ $this->redirectCounter = 0;
+ $response = null;
+
+ // Make sure the adapter is loaded
+ if ($this->adapter == null) $this->setAdapter($this->config['adapter']);
+
+ // Send the first request. If redirected, continue.
+ do {
+ // Clone the URI and add the additional GET parameters to it
+ $uri = clone $this->uri;
+ if (! empty($this->paramsGet)) {
+ $query = $uri->getQuery();
+ if (! empty($query)) $query .= '&';
+ $query .= http_build_query($this->paramsGet, null, '&');
+
+ $uri->setQuery($query);
+ }
+
+ $body = $this->_prepareBody();
+ $headers = $this->_prepareHeaders();
+
+ // Open the connection, send the request and read the response
+ $this->adapter->connect($uri->getHost(), $uri->getPort(),
+ ($uri->getScheme() == 'https' ? true : false));
+
+ $this->last_request = $this->adapter->write($this->method,
+ $uri, $this->config['httpversion'], $headers, $body);
+
+ $response = $this->adapter->read();
+ if (! $response) {
+ /** @see Zend_Http_Client_Exception */
+ require_once 'Zend/Http/Client/Exception.php';
+ throw new Zend_Http_Client_Exception('Unable to read response, or response is empty');
+ }
+
+ $response = Zend_Http_Response::fromString($response);
+ if ($this->config['storeresponse']) $this->last_response = $response;
+
+ // Load cookies into cookie jar
+ if (isset($this->cookiejar)) $this->cookiejar->addCookiesFromResponse($response, $uri);
+
+ // If we got redirected, look for the Location header
+ if ($response->isRedirect() && ($location = $response->getHeader('location'))) {
+
+ // Check whether we send the exact same request again, or drop the parameters
+ // and send a GET request
+ if ($response->getStatus() == 303 ||
+ ((! $this->config['strictredirects']) && ($response->getStatus() == 302 ||
+ $response->getStatus() == 301))) {
+
+ $this->resetParameters();
+ $this->setMethod(self::GET);
+ }
+
+ // If we got a well formed absolute URI
+ if (Zend_Uri_Http::check($location)) {
+ $this->setHeaders('host', null);
+ $this->setUri($location);
+
+ } else {
+
+ // Split into path and query and set the query
+ if (strpos($location, '?') !== false) {
+ list($location, $query) = explode('?', $location, 2);
+ } else {
+ $query = '';
+ }
+ $this->uri->setQuery($query);
+
+ // Else, if we got just an absolute path, set it
+ if(strpos($location, '/') === 0) {
+ $this->uri->setPath($location);
+
+ // Else, assume we have a relative path
+ } else {
+ // Get the current path directory, removing any trailing slashes
+ $path = $this->uri->getPath();
+ $path = rtrim(substr($path, 0, strrpos($path, '/')), "/");
+ $this->uri->setPath($path . '/' . $location);
+ }
+ }
+ ++$this->redirectCounter;
+
+ } else {
+ // If we didn't get any location, stop redirecting
+ break;
+ }
+
+ } while ($this->redirectCounter < $this->config['maxredirects']);
+
+ return $response;
+ }
+
+ /**
+ * Prepare the request headers
+ *
+ * @return array
+ */
+ protected function _prepareHeaders()
+ {
+ $headers = array();
+
+ // Set the host header
+ if (! isset($this->headers['host'])) {
+ $host = $this->uri->getHost();
+
+ // If the port is not default, add it
+ if (! (($this->uri->getScheme() == 'http' && $this->uri->getPort() == 80) ||
+ ($this->uri->getScheme() == 'https' && $this->uri->getPort() == 443))) {
+ $host .= ':' . $this->uri->getPort();
+ }
+
+ $headers[] = "Host: {$host}";
+ }
+
+ // Set the connection header
+ if (! isset($this->headers['connection'])) {
+ if (! $this->config['keepalive']) $headers[] = "Connection: close";
+ }
+
+ // Set the Accept-encoding header if not set - depending on whether
+ // zlib is available or not.
+ if (! isset($this->headers['accept-encoding'])) {
+ if (function_exists('gzinflate')) {
+ $headers[] = 'Accept-encoding: gzip, deflate';
+ } else {
+ $headers[] = 'Accept-encoding: identity';
+ }
+ }
+
+ // Set the content-type header
+ if ($this->method == self::POST &&
+ (! isset($this->headers['content-type']) && isset($this->enctype))) {
+
+ $headers[] = "Content-type: {$this->enctype}";
+ }
+
+ // Set the user agent header
+ if (! isset($this->headers['user-agent']) && isset($this->config['useragent'])) {
+ $headers[] = "User-agent: {$this->config['useragent']}";
+ }
+
+ // Set HTTP authentication if needed
+ if (is_array($this->auth)) {
+ $auth = self::encodeAuthHeader($this->auth['user'], $this->auth['password'], $this->auth['type']);
+ $headers[] = "Authorization: {$auth}";
+ }
+
+ // Load cookies from cookie jar
+ if (isset($this->cookiejar)) {
+ $cookstr = $this->cookiejar->getMatchingCookies($this->uri,
+ true, Zend_Http_CookieJar::COOKIE_STRING_CONCAT);
+
+ if ($cookstr) $headers[] = "Cookie: {$cookstr}";
+ }
+
+ // Add all other user defined headers
+ foreach ($this->headers as $header) {
+ list($name, $value) = $header;
+ if (is_array($value))
+ $value = implode(', ', $value);
+
+ $headers[] = "$name: $value";
+ }
+
+ return $headers;
+ }
+
+ /**
+ * Prepare the request body (for POST and PUT requests)
+ *
+ * @return string
+ * @throws Zend_Http_Client_Exception
+ */
+ protected function _prepareBody()
+ {
+ // According to RFC2616, a TRACE request should not have a body.
+ if ($this->method == self::TRACE) {
+ return '';
+ }
+
+ // If we have raw_post_data set, just use it as the body.
+ if (isset($this->raw_post_data)) {
+ $this->setHeaders('Content-length', strlen($this->raw_post_data));
+ return $this->raw_post_data;
+ }
+
+ $body = '';
+
+ // If we have files to upload, force enctype to multipart/form-data
+ if (count ($this->files) > 0) $this->setEncType(self::ENC_FORMDATA);
+
+ // If we have POST parameters or files, encode and add them to the body
+ if (count($this->paramsPost) > 0 || count($this->files) > 0) {
+ switch($this->enctype) {
+ case self::ENC_FORMDATA:
+ // Encode body as multipart/form-data
+ $boundary = '---ZENDHTTPCLIENT-' . md5(microtime());
+ $this->setHeaders('Content-type', self::ENC_FORMDATA . "; boundary={$boundary}");
+
+ // Get POST parameters and encode them
+ $params = $this->_getParametersRecursive($this->paramsPost);
+ foreach ($params as $pp) {
+ $body .= self::encodeFormData($boundary, $pp[0], $pp[1]);
+ }
+
+ // Encode files
+ foreach ($this->files as $name => $file) {
+ $fhead = array('Content-type' => $file[1]);
+ $body .= self::encodeFormData($boundary, $name, $file[2], $file[0], $fhead);
+ }
+
+ $body .= "--{$boundary}--\r\n";
+ break;
+
+ case self::ENC_URLENCODED:
+ // Encode body as application/x-www-form-urlencoded
+ $this->setHeaders('Content-type', self::ENC_URLENCODED);
+ $body = http_build_query($this->paramsPost, '', '&');
+ break;
+
+ default:
+ /** @see Zend_Http_Client_Exception */
+ require_once 'Zend/Http/Client/Exception.php';
+ throw new Zend_Http_Client_Exception("Cannot handle content type '{$this->enctype}' automatically." .
+ " Please use Zend_Http_Client::setRawData to send this kind of content.");
+ break;
+ }
+ }
+
+ // Set the content-length if we have a body or if request is POST/PUT
+ if ($body || $this->method == self::POST || $this->method == self::PUT) {
+ $this->setHeaders('Content-length', strlen($body));
+ }
+
+ return $body;
+ }
+
+ /**
+ * Helper method that gets a possibly multi-level parameters array (get or
+ * post) and flattens it.
+ *
+ * The method returns an array of (key, value) pairs (because keys are not
+ * necessarily unique. If one of the parameters in as array, it will also
+ * add a [] suffix to the key.
+ *
+ * @param array $parray The parameters array
+ * @param bool $urlencode Whether to urlencode the name and value
+ * @return array
+ */
+ protected function _getParametersRecursive($parray, $urlencode = false)
+ {
+ if (! is_array($parray)) return $parray;
+ $parameters = array();
+
+ foreach ($parray as $name => $value) {
+ if ($urlencode) $name = urlencode($name);
+
+ // If $value is an array, iterate over it
+ if (is_array($value)) {
+ $name .= ($urlencode ? '%5B%5D' : '[]');
+ foreach ($value as $subval) {
+ if ($urlencode) $subval = urlencode($subval);
+ $parameters[] = array($name, $subval);
+ }
+ } else {
+ if ($urlencode) $value = urlencode($value);
+ $parameters[] = array($name, $value);
+ }
+ }
+
+ return $parameters;
+ }
+
+ /**
+ * Attempt to detect the MIME type of a file using available extensions
+ *
+ * This method will try to detect the MIME type of a file. If the fileinfo
+ * extension is available, it will be used. If not, the mime_magic
+ * extension which is deprected but is still available in many PHP setups
+ * will be tried.
+ *
+ * If neither extension is available, the default application/octet-stream
+ * MIME type will be returned
+ *
+ * @param string $file File path
+ * @return string MIME type
+ */
+ protected function _detectFileMimeType($file)
+ {
+ $type = null;
+
+ // First try with fileinfo functions
+ if (function_exists('finfo_open')) {
+ if (self::$_fileInfoDb === null) {
+ self::$_fileInfoDb = @finfo_open(FILEINFO_MIME);
+ }
+
+ if (self::$_fileInfoDb) {
+ $type = finfo_file(self::$_fileInfoDb, $file);
+ }
+
+ } elseif (function_exists('mime_content_type')) {
+ $type = mime_content_type($file);
+ }
+
+ // Fallback to the default application/octet-stream
+ if (! $type) {
+ $type = 'application/octet-stream';
+ }
+
+ return $type;
+ }
+
+ /**
+ * Encode data to a multipart/form-data part suitable for a POST request.
+ *
+ * @param string $boundary
+ * @param string $name
+ * @param mixed $value
+ * @param string $filename
+ * @param array $headers Associative array of optional headers @example ("Content-transfer-encoding" => "binary")
+ * @return string
+ */
+ public static function encodeFormData($boundary, $name, $value, $filename = null, $headers = array()) {
+ $ret = "--{$boundary}\r\n" .
+ 'Content-disposition: form-data; name="' . $name .'"';
+
+ if ($filename) $ret .= '; filename="' . $filename . '"';
+ $ret .= "\r\n";
+
+ foreach ($headers as $hname => $hvalue) {
+ $ret .= "{$hname}: {$hvalue}\r\n";
+ }
+ $ret .= "\r\n";
+
+ $ret .= "{$value}\r\n";
+
+ return $ret;
+ }
+
+ /**
+ * Create a HTTP authentication "Authorization:" header according to the
+ * specified user, password and authentication method.
+ *
+ * @see http://www.faqs.org/rfcs/rfc2617.html
+ * @param string $user
+ * @param string $password
+ * @param string $type
+ * @return string
+ * @throws Zend_Http_Client_Exception
+ */
+ public static function encodeAuthHeader($user, $password, $type = self::AUTH_BASIC)
+ {
+ $authHeader = null;
+
+ switch ($type) {
+ case self::AUTH_BASIC:
+ // In basic authentication, the user name cannot contain ":"
+ if (strpos($user, ':') !== false) {
+ /** @see Zend_Http_Client_Exception */
+ require_once 'Zend/Http/Client/Exception.php';
+ throw new Zend_Http_Client_Exception("The user name cannot contain ':' in 'Basic' HTTP authentication");
+ }
+
+ $authHeader = 'Basic ' . base64_encode($user . ':' . $password);
+ break;
+
+ //case self::AUTH_DIGEST:
+ /**
+ * @todo Implement digest authentication
+ */
+ // break;
+
+ default:
+ /** @see Zend_Http_Client_Exception */
+ require_once 'Zend/Http/Client/Exception.php';
+ throw new Zend_Http_Client_Exception("Not a supported HTTP authentication type: '$type'");
+ }
+
+ return $authHeader;
+ }
+}
diff --git a/site/vendors/phpQuery/Zend/Http/Client/Adapter/Exception.php b/site/vendors/phpQuery/Zend/Http/Client/Adapter/Exception.php
new file mode 100644
index 0000000..dfbe904
--- /dev/null
+++ b/site/vendors/phpQuery/Zend/Http/Client/Adapter/Exception.php
@@ -0,0 +1,33 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Http
+ * @subpackage Client_Adapter_Exception
+ * @version $Id: Exception.php 8064 2008-02-16 10:58:39Z thomas $
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+require_once 'Zend/Http/Client/Exception.php';
+
+/**
+ * @category Zend
+ * @package Zend_Http
+ * @subpackage Client_Adapter
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Http_Client_Adapter_Exception extends Zend_Http_Client_Exception
+{}
diff --git a/site/vendors/phpQuery/Zend/Http/Client/Adapter/Interface.php b/site/vendors/phpQuery/Zend/Http/Client/Adapter/Interface.php
new file mode 100644
index 0000000..a3623ad
--- /dev/null
+++ b/site/vendors/phpQuery/Zend/Http/Client/Adapter/Interface.php
@@ -0,0 +1,78 @@
+<?php
+
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Http
+ * @subpackage Client_Adapter
+ * @version $Id: Interface.php 8064 2008-02-16 10:58:39Z thomas $
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+/**
+ * An interface description for Zend_Http_Client_Adapter classes.
+ *
+ * These classes are used as connectors for Zend_Http_Client, performing the
+ * tasks of connecting, writing, reading and closing connection to the server.
+ *
+ * @category Zend
+ * @package Zend_Http
+ * @subpackage Client_Adapter
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+interface Zend_Http_Client_Adapter_Interface
+{
+ /**
+ * Set the configuration array for the adapter
+ *
+ * @param array $config
+ */
+ public function setConfig($config = array());
+
+ /**
+ * Connect to the remote server
+ *
+ * @param string $host
+ * @param int $port
+ * @param boolean $secure
+ */
+ public function connect($host, $port = 80, $secure = false);
+
+ /**
+ * Send request to the remote server
+ *
+ * @param string $method
+ * @param Zend_Uri_Http $url
+ * @param string $http_ver
+ * @param array $headers
+ * @param string $body
+ * @return string Request as text
+ */
+ public function write($method, $url, $http_ver = '1.1', $headers = array(), $body = '');
+
+ /**
+ * Read response from server
+ *
+ * @return string
+ */
+ public function read();
+
+ /**
+ * Close the connection to the server
+ *
+ */
+ public function close();
+}
diff --git a/site/vendors/phpQuery/Zend/Http/Client/Adapter/Proxy.php b/site/vendors/phpQuery/Zend/Http/Client/Adapter/Proxy.php
new file mode 100644
index 0000000..4f69601
--- /dev/null
+++ b/site/vendors/phpQuery/Zend/Http/Client/Adapter/Proxy.php
@@ -0,0 +1,268 @@
+<?php
+
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Http
+ * @subpackage Client_Adapter
+ * @version $Id: Proxy.php 9868 2008-07-02 06:47:38Z shahar $
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+require_once 'Zend/Uri/Http.php';
+require_once 'Zend/Http/Client.php';
+require_once 'Zend/Http/Client/Adapter/Socket.php';
+
+/**
+ * HTTP Proxy-supporting Zend_Http_Client adapter class, based on the default
+ * socket based adapter.
+ *
+ * Should be used if proxy HTTP access is required. If no proxy is set, will
+ * fall back to Zend_Http_Client_Adapter_Socket behavior. Just like the
+ * default Socket adapter, this adapter does not require any special extensions
+ * installed.
+ *
+ * @category Zend
+ * @package Zend_Http
+ * @subpackage Client_Adapter
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Http_Client_Adapter_Proxy extends Zend_Http_Client_Adapter_Socket
+{
+ /**
+ * Parameters array
+ *
+ * @var array
+ */
+ protected $config = array(
+ 'ssltransport' => 'ssl',
+ 'proxy_host' => '',
+ 'proxy_port' => 8080,
+ 'proxy_user' => '',
+ 'proxy_pass' => '',
+ 'proxy_auth' => Zend_Http_Client::AUTH_BASIC,
+ 'persistent' => false
+ );
+
+ /**
+ * Whether HTTPS CONNECT was already negotiated with the proxy or not
+ *
+ * @var boolean
+ */
+ protected $negotiated = false;
+
+ /**
+ * Connect to the remote server
+ *
+ * Will try to connect to the proxy server. If no proxy was set, will
+ * fall back to the target server (behave like regular Socket adapter)
+ *
+ * @param string $host
+ * @param int $port
+ * @param boolean $secure
+ * @param int $timeout
+ */
+ public function connect($host, $port = 80, $secure = false)
+ {
+ // If no proxy is set, fall back to Socket adapter
+ if (! $this->config['proxy_host']) return parent::connect($host, $port, $secure);
+
+ // Go through a proxy - the connection is actually to the proxy server
+ $host = $this->config['proxy_host'];
+ $port = $this->config['proxy_port'];
+
+ // If we are connected to the wrong proxy, disconnect first
+ if (($this->connected_to[0] != $host || $this->connected_to[1] != $port)) {
+ if (is_resource($this->socket)) $this->close();
+ }
+
+ // Now, if we are not connected, connect
+ if (! is_resource($this->socket) || ! $this->config['keepalive']) {
+ $this->socket = @fsockopen($host, $port, $errno, $errstr, (int) $this->config['timeout']);
+ if (! $this->socket) {
+ $this->close();
+ require_once 'Zend/Http/Client/Adapter/Exception.php';
+ throw new Zend_Http_Client_Adapter_Exception(
+ 'Unable to Connect to proxy server ' . $host . ':' . $port . '. Error #' . $errno . ': ' . $errstr);
+ }
+
+ // Set the stream timeout
+ if (!stream_set_timeout($this->socket, (int) $this->config['timeout'])) {
+ require_once 'Zend/Http/Client/Adapter/Exception.php';
+ throw new Zend_Http_Client_Adapter_Exception('Unable to set the connection timeout');
+ }
+
+ // Update connected_to
+ $this->connected_to = array($host, $port);
+ }
+ }
+
+ /**
+ * Send request to the proxy server
+ *
+ * @param string $method
+ * @param Zend_Uri_Http $uri
+ * @param string $http_ver
+ * @param array $headers
+ * @param string $body
+ * @return string Request as string
+ */
+ public function write($method, $uri, $http_ver = '1.1', $headers = array(), $body = '')
+ {
+ // If no proxy is set, fall back to default Socket adapter
+ if (! $this->config['proxy_host']) return parent::write($method, $uri, $http_ver, $headers, $body);
+
+ // Make sure we're properly connected
+ if (! $this->socket) {
+ require_once 'Zend/Http/Client/Adapter/Exception.php';
+ throw new Zend_Http_Client_Adapter_Exception("Trying to write but we are not connected");
+ }
+
+ $host = $this->config['proxy_host'];
+ $port = $this->config['proxy_port'];
+
+ if ($this->connected_to[0] != $host || $this->connected_to[1] != $port) {
+ require_once 'Zend/Http/Client/Adapter/Exception.php';
+ throw new Zend_Http_Client_Adapter_Exception("Trying to write but we are connected to the wrong proxy server");
+ }
+
+ // Add Proxy-Authorization header
+ if ($this->config['proxy_user'] && ! isset($headers['proxy-authorization']))
+ $headers['proxy-authorization'] = Zend_Http_Client::encodeAuthHeader(
+ $this->config['proxy_user'], $this->config['proxy_pass'], $this->config['proxy_auth']
+ );
+
+ // if we are proxying HTTPS, preform CONNECT handshake with the proxy
+ if ($uri->getScheme() == 'https' && (! $this->negotiated)) {
+ $this->connectHandshake($uri->getHost(), $uri->getPort(), $http_ver, $headers);
+ $this->negotiated = true;
+ }
+
+ // Save request method for later
+ $this->method = $method;
+
+ // Build request headers
+ $request = "{$method} {$uri->__toString()} HTTP/{$http_ver}\r\n";
+
+ // Add all headers to the request string
+ foreach ($headers as $k => $v) {
+ if (is_string($k)) $v = "$k: $v";
+ $request .= "$v\r\n";
+ }
+
+ // Add the request body
+ $request .= "\r\n" . $body;
+
+ // Send the request
+ if (! @fwrite($this->socket, $request)) {
+ require_once 'Zend/Http/Client/Adapter/Exception.php';
+ throw new Zend_Http_Client_Adapter_Exception("Error writing request to proxy server");
+ }
+
+ return $request;
+ }
+
+ /**
+ * Preform handshaking with HTTPS proxy using CONNECT method
+ *
+ * @param string $host
+ * @param integer $port
+ * @param string $http_ver
+ * @param array $headers
+ */
+ protected function connectHandshake($host, $port = 443, $http_ver = '1.1', array &$headers = array())
+ {
+ $request = "CONNECT $host:$port HTTP/$http_ver\r\n" .
+ "Host: " . $this->config['proxy_host'] . "\r\n";
+
+ // Add the user-agent header
+ if (isset($this->config['useragent'])) {
+ $request .= "User-agent: " . $this->config['useragent'] . "\r\n";
+ }
+
+ // If the proxy-authorization header is set, send it to proxy but remove
+ // it from headers sent to target host
+ if (isset($headers['proxy-authorization'])) {
+ $request .= "Proxy-authorization: " . $headers['proxy-authorization'] . "\r\n";
+ unset($headers['proxy-authorization']);
+ }
+
+ $request .= "\r\n";
+
+ // Send the request
+ if (! @fwrite($this->socket, $request)) {
+ require_once 'Zend/Http/Client/Adapter/Exception.php';
+ throw new Zend_Http_Client_Adapter_Exception("Error writing request to proxy server");
+ }
+
+ // Read response headers only
+ $response = '';
+ $gotStatus = false;
+ while ($line = @fgets($this->socket)) {
+ $gotStatus = $gotStatus || (strpos($line, 'HTTP') !== false);
+ if ($gotStatus) {
+ $response .= $line;
+ if (!chop($line)) break;
+ }
+ }
+
+ // Check that the response from the proxy is 200
+ if (Zend_Http_Response::extractCode($response) != 200) {
+ require_once 'Zend/Http/Client/Adapter/Exception.php';
+ throw new Zend_Http_Client_Adapter_Exception("Unable to connect to HTTPS proxy. Server response: " . $response);
+ }
+
+ // If all is good, switch socket to secure mode. We have to fall back
+ // through the different modes
+ $modes = array(
+ STREAM_CRYPTO_METHOD_TLS_CLIENT,
+ STREAM_CRYPTO_METHOD_SSLv3_CLIENT,
+ STREAM_CRYPTO_METHOD_SSLv23_CLIENT,
+ STREAM_CRYPTO_METHOD_SSLv2_CLIENT
+ );
+
+ $success = false;
+ foreach($modes as $mode) {
+ $success = stream_socket_enable_crypto($this->socket, true, $mode);
+ if ($success) break;
+ }
+
+ if (! $success) {
+ require_once 'Zend/Http/Client/Adapter/Exception.php';
+ throw new Zend_Http_Client_Adapter_Exception("Unable to connect to" .
+ " HTTPS server through proxy: could not negotiate secure connection.");
+ }
+ }
+
+ /**
+ * Close the connection to the server
+ *
+ */
+ public function close()
+ {
+ parent::close();
+ $this->negotiated = false;
+ }
+
+ /**
+ * Destructor: make sure the socket is disconnected
+ *
+ */
+ public function __destruct()
+ {
+ if ($this->socket) $this->close();
+ }
+}
diff --git a/site/vendors/phpQuery/Zend/Http/Client/Adapter/Socket.php b/site/vendors/phpQuery/Zend/Http/Client/Adapter/Socket.php
new file mode 100644
index 0000000..01b6ef3
--- /dev/null
+++ b/site/vendors/phpQuery/Zend/Http/Client/Adapter/Socket.php
@@ -0,0 +1,332 @@
+<?php
+
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Http
+ * @subpackage Client_Adapter
+ * @version $Id: Socket.php 9870 2008-07-02 07:28:04Z shahar $
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+require_once 'Zend/Uri/Http.php';
+require_once 'Zend/Http/Client/Adapter/Interface.php';
+
+/**
+ * A sockets based (stream_socket_client) adapter class for Zend_Http_Client. Can be used
+ * on almost every PHP environment, and does not require any special extensions.
+ *
+ * @category Zend
+ * @package Zend_Http
+ * @subpackage Client_Adapter
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Http_Client_Adapter_Socket implements Zend_Http_Client_Adapter_Interface
+{
+ /**
+ * The socket for server connection
+ *
+ * @var resource|null
+ */
+ protected $socket = null;
+
+ /**
+ * What host/port are we connected to?
+ *
+ * @var array
+ */
+ protected $connected_to = array(null, null);
+
+ /**
+ * Parameters array
+ *
+ * @var array
+ */
+ protected $config = array(
+ 'persistent' => false,
+ 'ssltransport' => 'ssl',
+ 'sslcert' => null,
+ 'sslpassphrase' => null
+ );
+
+ /**
+ * Request method - will be set by write() and might be used by read()
+ *
+ * @var string
+ */
+ protected $method = null;
+
+ /**
+ * Adapter constructor, currently empty. Config is set using setConfig()
+ *
+ */
+ public function __construct()
+ {
+ }
+
+ /**
+ * Set the configuration array for the adapter
+ *
+ * @param array $config
+ */
+ public function setConfig($config = array())
+ {
+ if (! is_array($config)) {
+ require_once 'Zend/Http/Client/Adapter/Exception.php';
+ throw new Zend_Http_Client_Adapter_Exception(
+ '$config expects an array, ' . gettype($config) . ' recieved.');
+ }
+
+ foreach ($config as $k => $v) {
+ $this->config[strtolower($k)] = $v;
+ }
+ }
+
+ /**
+ * Connect to the remote server
+ *
+ * @param string $host
+ * @param int $port
+ * @param boolean $secure
+ * @param int $timeout
+ */
+ public function connect($host, $port = 80, $secure = false)
+ {
+ // If the URI should be accessed via SSL, prepend the Hostname with ssl://
+ $host = ($secure ? $this->config['ssltransport'] : 'tcp') . '://' . $host;
+
+ // If we are connected to the wrong host, disconnect first
+ if (($this->connected_to[0] != $host || $this->connected_to[1] != $port)) {
+ if (is_resource($this->socket)) $this->close();
+ }
+
+ // Now, if we are not connected, connect
+ if (! is_resource($this->socket) || ! $this->config['keepalive']) {
+ $context = stream_context_create();
+ if ($secure) {
+ if ($this->config['sslcert'] !== null) {
+ if (! stream_context_set_option($context, 'ssl', 'local_cert',
+ $this->config['sslcert'])) {
+ require_once 'Zend/Http/Client/Adapter/Exception.php';
+ throw new Zend_Http_Client_Adapter_Exception('Unable to set sslcert option');
+ }
+ }
+ if ($this->config['sslpassphrase'] !== null) {
+ if (! stream_context_set_option($context, 'ssl', 'passphrase',
+ $this->config['sslpassphrase'])) {
+ require_once 'Zend/Http/Client/Adapter/Exception.php';
+ throw new Zend_Http_Client_Adapter_Exception('Unable to set sslpassphrase option');
+ }
+ }
+ }
+
+ $flags = STREAM_CLIENT_CONNECT;
+ if ($this->config['persistent']) $flags |= STREAM_CLIENT_PERSISTENT;
+
+ $this->socket = @stream_socket_client($host . ':' . $port,
+ $errno,
+ $errstr,
+ (int) $this->config['timeout'],
+ $flags,
+ $context);
+ if (! $this->socket) {
+ $this->close();
+ require_once 'Zend/Http/Client/Adapter/Exception.php';
+ throw new Zend_Http_Client_Adapter_Exception(
+ 'Unable to Connect to ' . $host . ':' . $port . '. Error #' . $errno . ': ' . $errstr);
+ }
+
+ // Set the stream timeout
+ if (! stream_set_timeout($this->socket, (int) $this->config['timeout'])) {
+ require_once 'Zend/Http/Client/Adapter/Exception.php';
+ throw new Zend_Http_Client_Adapter_Exception('Unable to set the connection timeout');
+ }
+
+ // Update connected_to
+ $this->connected_to = array($host, $port);
+ }
+ }
+
+ /**
+ * Send request to the remote server
+ *
+ * @param string $method
+ * @param Zend_Uri_Http $uri
+ * @param string $http_ver
+ * @param array $headers
+ * @param string $body
+ * @return string Request as string
+ */
+ public function write($method, $uri, $http_ver = '1.1', $headers = array(), $body = '')
+ {
+ // Make sure we're properly connected
+ if (! $this->socket) {
+ require_once 'Zend/Http/Client/Adapter/Exception.php';
+ throw new Zend_Http_Client_Adapter_Exception('Trying to write but we are not connected');
+ }
+
+ $host = $uri->getHost();
+ $host = (strtolower($uri->getScheme()) == 'https' ? $this->config['ssltransport'] : 'tcp') . '://' . $host;
+ if ($this->connected_to[0] != $host || $this->connected_to[1] != $uri->getPort()) {
+ require_once 'Zend/Http/Client/Adapter/Exception.php';
+ throw new Zend_Http_Client_Adapter_Exception('Trying to write but we are connected to the wrong host');
+ }
+
+ // Save request method for later
+ $this->method = $method;
+
+ // Build request headers
+ $path = $uri->getPath();
+ if ($uri->getQuery()) $path .= '?' . $uri->getQuery();
+ $request = "{$method} {$path} HTTP/{$http_ver}\r\n";
+ foreach ($headers as $k => $v) {
+ if (is_string($k)) $v = ucfirst($k) . ": $v";
+ $request .= "$v\r\n";
+ }
+
+ // Add the request body
+ $request .= "\r\n" . $body;
+
+ // Send the request
+ if (! @fwrite($this->socket, $request)) {
+ require_once 'Zend/Http/Client/Adapter/Exception.php';
+ throw new Zend_Http_Client_Adapter_Exception('Error writing request to server');
+ }
+
+ return $request;
+ }
+
+ /**
+ * Read response from server
+ *
+ * @return string
+ */
+ public function read()
+ {
+ // First, read headers only
+ $response = '';
+ $gotStatus = false;
+ while ($line = @fgets($this->socket)) {
+ $gotStatus = $gotStatus || (strpos($line, 'HTTP') !== false);
+ if ($gotStatus) {
+ $response .= $line;
+ if (!chop($line)) break;
+ }
+ }
+
+ $statusCode = Zend_Http_Response::extractCode($response);
+
+ // Handle 100 and 101 responses internally by restarting the read again
+ if ($statusCode == 100 || $statusCode == 101) return $this->read();
+
+ /**
+ * Responses to HEAD requests and 204 or 304 responses are not expected
+ * to have a body - stop reading here
+ */
+ if ($statusCode == 304 || $statusCode == 204 ||
+ $this->method == Zend_Http_Client::HEAD) return $response;
+
+ // Check headers to see what kind of connection / transfer encoding we have
+ $headers = Zend_Http_Response::extractHeaders($response);
+
+ // if the connection is set to close, just read until socket closes
+ if (isset($headers['connection']) && $headers['connection'] == 'close') {
+ while ($buff = @fread($this->socket, 8192)) {
+ $response .= $buff;
+ }
+
+ $this->close();
+
+ // Else, if we got a transfer-encoding header (chunked body)
+ } elseif (isset($headers['transfer-encoding'])) {
+ if ($headers['transfer-encoding'] == 'chunked') {
+ do {
+ $chunk = '';
+ $line = @fgets($this->socket);
+ $chunk .= $line;
+
+ $hexchunksize = ltrim(chop($line), '0');
+ $hexchunksize = strlen($hexchunksize) ? strtolower($hexchunksize) : 0;
+
+ $chunksize = hexdec(chop($line));
+ if (dechex($chunksize) != $hexchunksize) {
+ @fclose($this->socket);
+ require_once 'Zend/Http/Client/Adapter/Exception.php';
+ throw new Zend_Http_Client_Adapter_Exception('Invalid chunk size "' .
+ $hexchunksize . '" unable to read chunked body');
+ }
+
+ $left_to_read = $chunksize;
+ while ($left_to_read > 0) {
+ $line = @fread($this->socket, $left_to_read);
+ $chunk .= $line;
+ $left_to_read -= strlen($line);
+ }
+
+ $chunk .= @fgets($this->socket);
+ $response .= $chunk;
+ } while ($chunksize > 0);
+ } else {
+ throw new Zend_Http_Client_Adapter_Exception('Cannot handle "' .
+ $headers['transfer-encoding'] . '" transfer encoding');
+ }
+
+ // Else, if we got the content-length header, read this number of bytes
+ } elseif (isset($headers['content-length'])) {
+ $left_to_read = $headers['content-length'];
+ $chunk = '';
+ while ($left_to_read > 0) {
+ $chunk = @fread($this->socket, $left_to_read);
+ $left_to_read -= strlen($chunk);
+ $response .= $chunk;
+ }
+
+ // Fallback: just read the response (should not happen)
+ } else {
+ while ($buff = @fread($this->socket, 8192)) {
+ $response .= $buff;
+ }
+
+ $this->close();
+ }
+
+ return $response;
+ }
+
+ /**
+ * Close the connection to the server
+ *
+ */
+ public function close()
+ {
+ if (is_resource($this->socket)) @fclose($this->socket);
+ $this->socket = null;
+ $this->connected_to = array(null, null);
+ }
+
+ /**
+ * Destructor: make sure the socket is disconnected
+ *
+ * If we are in persistent TCP mode, will not close the connection
+ *
+ */
+ public function __destruct()
+ {
+ if (! $this->config['persistent']) {
+ if ($this->socket) $this->close();
+ }
+ }
+}
diff --git a/site/vendors/phpQuery/Zend/Http/Client/Adapter/Test.php b/site/vendors/phpQuery/Zend/Http/Client/Adapter/Test.php
new file mode 100644
index 0000000..ce5c468
--- /dev/null
+++ b/site/vendors/phpQuery/Zend/Http/Client/Adapter/Test.php
@@ -0,0 +1,193 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Http
+ * @subpackage Client_Adapter
+ * @version $Id: Test.php 8064 2008-02-16 10:58:39Z thomas $
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+require_once 'Zend/Uri/Http.php';
+require_once 'Zend/Http/Response.php';
+require_once 'Zend/Http/Client/Adapter/Interface.php';
+
+/**
+ * A testing-purposes adapter.
+ *
+ * Should be used to test all components that rely on Zend_Http_Client,
+ * without actually performing an HTTP request. You should instantiate this
+ * object manually, and then set it as the client's adapter. Then, you can
+ * set the expected response using the setResponse() method.
+ *
+ * @category Zend
+ * @package Zend_Http
+ * @subpackage Client_Adapter
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Http_Client_Adapter_Test implements Zend_Http_Client_Adapter_Interface
+{
+ /**
+ * Parameters array
+ *
+ * @var array
+ */
+ protected $config = array();
+
+ /**
+ * Buffer of responses to be returned by the read() method. Can be
+ * set using setResponse() and addResponse().
+ *
+ * @var array
+ */
+ protected $responses = array("HTTP/1.1 400 Bad Request\r\n\r\n");
+
+ /**
+ * Current position in the response buffer
+ *
+ * @var integer
+ */
+ protected $responseIndex = 0;
+
+ /**
+ * Adapter constructor, currently empty. Config is set using setConfig()
+ *
+ */
+ public function __construct()
+ { }
+
+ /**
+ * Set the configuration array for the adapter
+ *
+ * @param array $config
+ */
+ public function setConfig($config = array())
+ {
+ if (! is_array($config)) {
+ require_once 'Zend/Http/Client/Adapter/Exception.php';
+ throw new Zend_Http_Client_Adapter_Exception(
+ '$config expects an array, ' . gettype($config) . ' recieved.');
+ }
+
+ foreach ($config as $k => $v) {
+ $this->config[strtolower($k)] = $v;
+ }
+ }
+
+ /**
+ * Connect to the remote server
+ *
+ * @param string $host
+ * @param int $port
+ * @param boolean $secure
+ * @param int $timeout
+ */
+ public function connect($host, $port = 80, $secure = false)
+ { }
+
+ /**
+ * Send request to the remote server
+ *
+ * @param string $method
+ * @param Zend_Uri_Http $uri
+ * @param string $http_ver
+ * @param array $headers
+ * @param string $body
+ * @return string Request as string
+ */
+ public function write($method, $uri, $http_ver = '1.1', $headers = array(), $body = '')
+ {
+ $host = $uri->getHost();
+ $host = (strtolower($uri->getScheme()) == 'https' ? 'sslv2://' . $host : $host);
+
+ // Build request headers
+ $path = $uri->getPath();
+ if ($uri->getQuery()) $path .= '?' . $uri->getQuery();
+ $request = "{$method} {$path} HTTP/{$http_ver}\r\n";
+ foreach ($headers as $k => $v) {
+ if (is_string($k)) $v = ucfirst($k) . ": $v";
+ $request .= "$v\r\n";
+ }
+
+ // Add the request body
+ $request .= "\r\n" . $body;
+
+ // Do nothing - just return the request as string
+
+ return $request;
+ }
+
+ /**
+ * Return the response set in $this->setResponse()
+ *
+ * @return string
+ */
+ public function read()
+ {
+ if ($this->responseIndex >= count($this->responses)) {
+ $this->responseIndex = 0;
+ }
+ return $this->responses[$this->responseIndex++];
+ }
+
+ /**
+ * Close the connection (dummy)
+ *
+ */
+ public function close()
+ { }
+
+ /**
+ * Set the HTTP response(s) to be returned by this adapter
+ *
+ * @param Zend_Http_Response|array|string $response
+ */
+ public function setResponse($response)
+ {
+ if ($response instanceof Zend_Http_Response) {
+ $response = $response->asString();
+ }
+
+ $this->responses = (array)$response;
+ $this->responseIndex = 0;
+ }
+
+ /**
+ * Add another response to the response buffer.
+ *
+ * @param string $response
+ */
+ public function addResponse($response)
+ {
+ $this->responses[] = $response;
+ }
+
+ /**
+ * Sets the position of the response buffer. Selects which
+ * response will be returned on the next call to read().
+ *
+ * @param integer $index
+ */
+ public function setResponseIndex($index)
+ {
+ if ($index < 0 || $index >= count($this->responses)) {
+ require_once 'Zend/Http/Client/Adapter/Exception.php';
+ throw new Zend_Http_Client_Adapter_Exception(
+ 'Index out of range of response buffer size');
+ }
+ $this->responseIndex = $index;
+ }
+}
diff --git a/site/vendors/phpQuery/Zend/Http/Client/Exception.php b/site/vendors/phpQuery/Zend/Http/Client/Exception.php
new file mode 100644
index 0000000..70c8e01
--- /dev/null
+++ b/site/vendors/phpQuery/Zend/Http/Client/Exception.php
@@ -0,0 +1,33 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Http
+ * @subpackage Client_Exception
+ * @version $Id: Exception.php 8064 2008-02-16 10:58:39Z thomas $
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+require_once 'Zend/Http/Exception.php';
+
+/**
+ * @category Zend
+ * @package Zend_Http
+ * @subpackage Client
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Http_Client_Exception extends Zend_Http_Exception
+{}
diff --git a/site/vendors/phpQuery/Zend/Http/Cookie.php b/site/vendors/phpQuery/Zend/Http/Cookie.php
new file mode 100644
index 0000000..e22d0f0
--- /dev/null
+++ b/site/vendors/phpQuery/Zend/Http/Cookie.php
@@ -0,0 +1,327 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Http
+ * @subpackage Cookie
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com/)
+ * @version $Id: Cookie.php 9098 2008-03-30 19:29:10Z thomas $
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+require_once 'Zend/Uri/Http.php';
+
+/**
+ * Zend_Http_Cookie is a class describing an HTTP cookie and all it's parameters.
+ *
+ * Zend_Http_Cookie is a class describing an HTTP cookie and all it's parameters. The
+ * class also enables validating whether the cookie should be sent to the server in
+ * a specified scenario according to the request URI, the expiry time and whether
+ * session cookies should be used or not. Generally speaking cookies should be
+ * contained in a Cookiejar object, or instantiated manually and added to an HTTP
+ * request.
+ *
+ * See http://wp.netscape.com/newsref/std/cookie_spec.html for some specs.
+ *
+ * @category Zend
+ * @package Zend_Http
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com/)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Http_Cookie
+{
+ /**
+ * Cookie name
+ *
+ * @var string
+ */
+ protected $name;
+
+ /**
+ * Cookie value
+ *
+ * @var string
+ */
+ protected $value;
+
+ /**
+ * Cookie expiry date
+ *
+ * @var int
+ */
+ protected $expires;
+
+ /**
+ * Cookie domain
+ *
+ * @var string
+ */
+ protected $domain;
+
+ /**
+ * Cookie path
+ *
+ * @var string
+ */
+ protected $path;
+
+ /**
+ * Whether the cookie is secure or not
+ *
+ * @var boolean
+ */
+ protected $secure;
+
+ /**
+ * Cookie object constructor
+ *
+ * @todo Add validation of each one of the parameters (legal domain, etc.)
+ *
+ * @param string $name
+ * @param string $value
+ * @param int $expires
+ * @param string $domain
+ * @param string $path
+ * @param bool $secure
+ */
+ public function __construct($name, $value, $domain, $expires = null, $path = null, $secure = false)
+ {
+ if (preg_match("/[=,; \t\r\n\013\014]/", $name)) {
+ require_once 'Zend/Http/Exception.php';
+ throw new Zend_Http_Exception("Cookie name cannot contain these characters: =,; \\t\\r\\n\\013\\014 ({$name})");
+ }
+
+ if (! $this->name = (string) $name) {
+ require_once 'Zend/Http/Exception.php';
+ throw new Zend_Http_Exception('Cookies must have a name');
+ }
+
+ if (! $this->domain = (string) $domain) {
+ require_once 'Zend/Http/Exception.php';
+ throw new Zend_Http_Exception('Cookies must have a domain');
+ }
+
+ $this->value = (string) $value;
+ $this->expires = ($expires === null ? null : (int) $expires);
+ $this->path = ($path ? $path : '/');
+ $this->secure = $secure;
+ }
+
+ /**
+ * Get Cookie name
+ *
+ * @return string
+ */
+ public function getName()
+ {
+ return $this->name;
+ }
+
+ /**
+ * Get cookie value
+ *
+ * @return string
+ */
+ public function getValue()
+ {
+ return $this->value;
+ }
+
+ /**
+ * Get cookie domain
+ *
+ * @return string
+ */
+ public function getDomain()
+ {
+ return $this->domain;
+ }
+
+ /**
+ * Get the cookie path
+ *
+ * @return string
+ */
+ public function getPath()
+ {
+ return $this->path;
+ }
+
+ /**
+ * Get the expiry time of the cookie, or null if no expiry time is set
+ *
+ * @return int|null
+ */
+ public function getExpiryTime()
+ {
+ return $this->expires;
+ }
+
+ /**
+ * Check whether the cookie should only be sent over secure connections
+ *
+ * @return boolean
+ */
+ public function isSecure()
+ {
+ return $this->secure;
+ }
+
+ /**
+ * Check whether the cookie has expired
+ *
+ * Always returns false if the cookie is a session cookie (has no expiry time)
+ *
+ * @param int $now Timestamp to consider as "now"
+ * @return boolean
+ */
+ public function isExpired($now = null)
+ {
+ if ($now === null) $now = time();
+ if (is_int($this->expires) && $this->expires < $now) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Check whether the cookie is a session cookie (has no expiry time set)
+ *
+ * @return boolean
+ */
+ public function isSessionCookie()
+ {
+ return ($this->expires === null);
+ }
+
+ /**
+ * Checks whether the cookie should be sent or not in a specific scenario
+ *
+ * @param string|Zend_Uri_Http $uri URI to check against (secure, domain, path)
+ * @param boolean $matchSessionCookies Whether to send session cookies
+ * @param int $now Override the current time when checking for expiry time
+ * @return boolean
+ */
+ public function match($uri, $matchSessionCookies = true, $now = null)
+ {
+ if (is_string ($uri)) {
+ $uri = Zend_Uri_Http::factory($uri);
+ }
+
+ // Make sure we have a valid Zend_Uri_Http object
+ if (! ($uri->valid() && ($uri->getScheme() == 'http' || $uri->getScheme() =='https'))) {
+ require_once 'Zend/Http/Exception.php';
+ throw new Zend_Http_Exception('Passed URI is not a valid HTTP or HTTPS URI');
+ }
+
+ // Check that the cookie is secure (if required) and not expired
+ if ($this->secure && $uri->getScheme() != 'https') return false;
+ if ($this->isExpired($now)) return false;
+ if ($this->isSessionCookie() && ! $matchSessionCookies) return false;
+
+ // Validate domain and path
+ // Domain is validated using tail match, while path is validated using head match
+ $domain_preg = preg_quote($this->getDomain(), "/");
+ if (! preg_match("/{$domain_preg}$/", $uri->getHost())) return false;
+ $path_preg = preg_quote($this->getPath(), "/");
+ if (! preg_match("/^{$path_preg}/", $uri->getPath())) return false;
+
+ // If we didn't die until now, return true.
+ return true;
+ }
+
+ /**
+ * Get the cookie as a string, suitable for sending as a "Cookie" header in an
+ * HTTP request
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return $this->name . '=' . urlencode($this->value) . ';';
+ }
+
+ /**
+ * Generate a new Cookie object from a cookie string
+ * (for example the value of the Set-Cookie HTTP header)
+ *
+ * @param string $cookieStr
+ * @param Zend_Uri_Http|string $ref_uri Reference URI for default values (domain, path)
+ * @return Zend_Http_Cookie A new Zend_Http_Cookie object or false on failure.
+ */
+ public static function fromString($cookieStr, $ref_uri = null)
+ {
+ // Set default values
+ if (is_string($ref_uri)) {
+ $ref_uri = Zend_Uri_Http::factory($ref_uri);
+ }
+
+ $name = '';
+ $value = '';
+ $domain = '';
+ $path = '';
+ $expires = null;
+ $secure = false;
+ $parts = explode(';', $cookieStr);
+
+ // If first part does not include '=', fail
+ if (strpos($parts[0], '=') === false) return false;
+
+ // Get the name and value of the cookie
+ list($name, $value) = explode('=', trim(array_shift($parts)), 2);
+ $name = trim($name);
+ $value = urldecode(trim($value));
+
+ // Set default domain and path
+ if ($ref_uri instanceof Zend_Uri_Http) {
+ $domain = $ref_uri->getHost();
+ $path = $ref_uri->getPath();
+ $path = substr($path, 0, strrpos($path, '/'));
+ }
+
+ // Set other cookie parameters
+ foreach ($parts as $part) {
+ $part = trim($part);
+ if (strtolower($part) == 'secure') {
+ $secure = true;
+ continue;
+ }
+
+ $keyValue = explode('=', $part, 2);
+ if (count($keyValue) == 2) {
+ list($k, $v) = $keyValue;
+ switch (strtolower($k)) {
+ case 'expires':
+ $expires = strtotime($v);
+ break;
+ case 'path':
+ $path = $v;
+ break;
+ case 'domain':
+ $domain = $v;
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ if ($name !== '') {
+ return new Zend_Http_Cookie($name, $value, $domain, $expires, $path, $secure);
+ } else {
+ return false;
+ }
+ }
+}
diff --git a/site/vendors/phpQuery/Zend/Http/CookieJar.php b/site/vendors/phpQuery/Zend/Http/CookieJar.php
new file mode 100644
index 0000000..c11174e
--- /dev/null
+++ b/site/vendors/phpQuery/Zend/Http/CookieJar.php
@@ -0,0 +1,350 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Http
+ * @subpackage CookieJar
+ * @version $Id: CookieJar.php 9098 2008-03-30 19:29:10Z thomas $
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com/)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+require_once "Zend/Uri.php";
+require_once "Zend/Http/Cookie.php";
+require_once "Zend/Http/Response.php";
+
+/**
+ * A Zend_Http_CookieJar object is designed to contain and maintain HTTP cookies, and should
+ * be used along with Zend_Http_Client in order to manage cookies across HTTP requests and
+ * responses.
+ *
+ * The class contains an array of Zend_Http_Cookie objects. Cookies can be added to the jar
+ * automatically from a request or manually. Then, the jar can find and return the cookies
+ * needed for a specific HTTP request.
+ *
+ * A special parameter can be passed to all methods of this class that return cookies: Cookies
+ * can be returned either in their native form (as Zend_Http_Cookie objects) or as strings -
+ * the later is suitable for sending as the value of the "Cookie" header in an HTTP request.
+ * You can also choose, when returning more than one cookie, whether to get an array of strings
+ * (by passing Zend_Http_CookieJar::COOKIE_STRING_ARRAY) or one unified string for all cookies
+ * (by passing Zend_Http_CookieJar::COOKIE_STRING_CONCAT).
+ *
+ * @link http://wp.netscape.com/newsref/std/cookie_spec.html for some specs.
+ *
+ * @category Zend
+ * @package Zend_Http
+ * @subpackage CookieJar
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com/)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Http_CookieJar
+{
+ /**
+ * Return cookie(s) as a Zend_Http_Cookie object
+ *
+ */
+ const COOKIE_OBJECT = 0;
+
+ /**
+ * Return cookie(s) as a string (suitable for sending in an HTTP request)
+ *
+ */
+ const COOKIE_STRING_ARRAY = 1;
+
+ /**
+ * Return all cookies as one long string (suitable for sending in an HTTP request)
+ *
+ */
+ const COOKIE_STRING_CONCAT = 2;
+
+ /**
+ * Array storing cookies
+ *
+ * Cookies are stored according to domain and path:
+ * $cookies
+ * + www.mydomain.com
+ * + /
+ * - cookie1
+ * - cookie2
+ * + /somepath
+ * - othercookie
+ * + www.otherdomain.net
+ * + /
+ * - alsocookie
+ *
+ * @var array
+ */
+ protected $cookies = array();
+
+ /**
+ * Construct a new CookieJar object
+ *
+ */
+ public function __construct()
+ { }
+
+ /**
+ * Add a cookie to the jar. Cookie should be passed either as a Zend_Http_Cookie object
+ * or as a string - in which case an object is created from the string.
+ *
+ * @param Zend_Http_Cookie|string $cookie
+ * @param Zend_Uri_Http|string $ref_uri Optional reference URI (for domain, path, secure)
+ */
+ public function addCookie($cookie, $ref_uri = null)
+ {
+ if (is_string($cookie)) {
+ $cookie = Zend_Http_Cookie::fromString($cookie, $ref_uri);
+ }
+
+ if ($cookie instanceof Zend_Http_Cookie) {
+ $domain = $cookie->getDomain();
+ $path = $cookie->getPath();
+ if (! isset($this->cookies[$domain])) $this->cookies[$domain] = array();
+ if (! isset($this->cookies[$domain][$path])) $this->cookies[$domain][$path] = array();
+ $this->cookies[$domain][$path][$cookie->getName()] = $cookie;
+ } else {
+ require_once 'Zend/Http/Exception.php';
+ throw new Zend_Http_Exception('Supplient argument is not a valid cookie string or object');
+ }
+ }
+
+ /**
+ * Parse an HTTP response, adding all the cookies set in that response
+ * to the cookie jar.
+ *
+ * @param Zend_Http_Response $response
+ * @param Zend_Uri_Http|string $ref_uri Requested URI
+ */
+ public function addCookiesFromResponse($response, $ref_uri)
+ {
+ if (! $response instanceof Zend_Http_Response) {
+ require_once 'Zend/Http/Exception.php';
+ throw new Zend_Http_Exception('$response is expected to be a Response object, ' .
+ gettype($response) . ' was passed');
+ }
+
+ $cookie_hdrs = $response->getHeader('Set-Cookie');
+
+ if (is_array($cookie_hdrs)) {
+ foreach ($cookie_hdrs as $cookie) {
+ $this->addCookie($cookie, $ref_uri);
+ }
+ } elseif (is_string($cookie_hdrs)) {
+ $this->addCookie($cookie_hdrs, $ref_uri);
+ }
+ }
+
+ /**
+ * Get all cookies in the cookie jar as an array
+ *
+ * @param int $ret_as Whether to return cookies as objects of Zend_Http_Cookie or as strings
+ * @return array|string
+ */
+ public function getAllCookies($ret_as = self::COOKIE_OBJECT)
+ {
+ $cookies = $this->_flattenCookiesArray($this->cookies, $ret_as);
+ return $cookies;
+ }
+
+ /**
+ * Return an array of all cookies matching a specific request according to the request URI,
+ * whether session cookies should be sent or not, and the time to consider as "now" when
+ * checking cookie expiry time.
+ *
+ * @param string|Zend_Uri_Http $uri URI to check against (secure, domain, path)
+ * @param boolean $matchSessionCookies Whether to send session cookies
+ * @param int $ret_as Whether to return cookies as objects of Zend_Http_Cookie or as strings
+ * @param int $now Override the current time when checking for expiry time
+ * @return array|string
+ */
+ public function getMatchingCookies($uri, $matchSessionCookies = true,
+ $ret_as = self::COOKIE_OBJECT, $now = null)
+ {
+ if (is_string($uri)) $uri = Zend_Uri::factory($uri);
+ if (! $uri instanceof Zend_Uri_Http) {
+ require_once 'Zend/Http/Exception.php';
+ throw new Zend_Http_Exception("Invalid URI string or object passed");
+ }
+
+ // Set path
+ $path = $uri->getPath();
+ $path = substr($path, 0, strrpos($path, '/'));
+ if (! $path) $path = '/';
+
+ // First, reduce the array of cookies to only those matching domain and path
+ $cookies = $this->_matchDomain($uri->getHost());
+ $cookies = $this->_matchPath($cookies, $path);
+ $cookies = $this->_flattenCookiesArray($cookies, self::COOKIE_OBJECT);
+
+ // Next, run Cookie->match on all cookies to check secure, time and session mathcing
+ $ret = array();
+ foreach ($cookies as $cookie)
+ if ($cookie->match($uri, $matchSessionCookies, $now))
+ $ret[] = $cookie;
+
+ // Now, use self::_flattenCookiesArray again - only to convert to the return format ;)
+ $ret = $this->_flattenCookiesArray($ret, $ret_as);
+
+ return $ret;
+ }
+
+ /**
+ * Get a specific cookie according to a URI and name
+ *
+ * @param Zend_Uri_Http|string $uri The uri (domain and path) to match
+ * @param string $cookie_name The cookie's name
+ * @param int $ret_as Whether to return cookies as objects of Zend_Http_Cookie or as strings
+ * @return Zend_Http_Cookie|string
+ */
+ public function getCookie($uri, $cookie_name, $ret_as = self::COOKIE_OBJECT)
+ {
+ if (is_string($uri)) {
+ $uri = Zend_Uri::factory($uri);
+ }
+
+ if (! $uri instanceof Zend_Uri_Http) {
+ require_once 'Zend/Http/Exception.php';
+ throw new Zend_Http_Exception('Invalid URI specified');
+ }
+
+ // Get correct cookie path
+ $path = $uri->getPath();
+ $path = substr($path, 0, strrpos($path, '/'));
+ if (! $path) $path = '/';
+
+ if (isset($this->cookies[$uri->getHost()][$path][$cookie_name])) {
+ $cookie = $this->cookies[$uri->getHost()][$path][$cookie_name];
+
+ switch ($ret_as) {
+ case self::COOKIE_OBJECT:
+ return $cookie;
+ break;
+
+ case self::COOKIE_STRING_ARRAY:
+ case self::COOKIE_STRING_CONCAT:
+ return $cookie->__toString();
+ break;
+
+ default:
+ require_once 'Zend/Http/Exception.php';
+ throw new Zend_Http_Exception("Invalid value passed for \$ret_as: {$ret_as}");
+ break;
+ }
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Helper function to recursivly flatten an array. Shoud be used when exporting the
+ * cookies array (or parts of it)
+ *
+ * @param Zend_Http_Cookie|array $ptr
+ * @param int $ret_as What value to return
+ * @return array|string
+ */
+ protected function _flattenCookiesArray($ptr, $ret_as = self::COOKIE_OBJECT) {
+ if (is_array($ptr)) {
+ $ret = ($ret_as == self::COOKIE_STRING_CONCAT ? '' : array());
+ foreach ($ptr as $item) {
+ if ($ret_as == self::COOKIE_STRING_CONCAT) {
+ $ret .= $this->_flattenCookiesArray($item, $ret_as);
+ } else {
+ $ret = array_merge($ret, $this->_flattenCookiesArray($item, $ret_as));
+ }
+ }
+ return $ret;
+ } elseif ($ptr instanceof Zend_Http_Cookie) {
+ switch ($ret_as) {
+ case self::COOKIE_STRING_ARRAY:
+ return array($ptr->__toString());
+ break;
+
+ case self::COOKIE_STRING_CONCAT:
+ return $ptr->__toString();
+ break;
+
+ case self::COOKIE_OBJECT:
+ default:
+ return array($ptr);
+ break;
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * Return a subset of the cookies array matching a specific domain
+ *
+ * Returned array is actually an array of pointers to items in the $this->cookies array.
+ *
+ * @param string $domain
+ * @return array
+ */
+ protected function _matchDomain($domain) {
+ $ret = array();
+
+ foreach (array_keys($this->cookies) as $cdom) {
+ $regex = "/" . preg_quote($cdom, "/") . "$/i";
+ if (preg_match($regex, $domain)) $ret[$cdom] = &$this->cookies[$cdom];
+ }
+
+ return $ret;
+ }
+
+ /**
+ * Return a subset of a domain-matching cookies that also match a specified path
+ *
+ * Returned array is actually an array of pointers to items in the $passed array.
+ *
+ * @param array $dom_array
+ * @param string $path
+ * @return array
+ */
+ protected function _matchPath($domains, $path) {
+ $ret = array();
+ if (substr($path, -1) != '/') $path .= '/';
+
+ foreach ($domains as $dom => $paths_array) {
+ foreach (array_keys($paths_array) as $cpath) {
+ $regex = "|^" . preg_quote($cpath, "|") . "|i";
+ if (preg_match($regex, $path)) {
+ if (! isset($ret[$dom])) $ret[$dom] = array();
+ $ret[$dom][$cpath] = &$paths_array[$cpath];
+ }
+ }
+ }
+
+ return $ret;
+ }
+
+ /**
+ * Create a new CookieJar object and automatically load into it all the
+ * cookies set in an Http_Response object. If $uri is set, it will be
+ * considered as the requested URI for setting default domain and path
+ * of the cookie.
+ *
+ * @param Zend_Http_Response $response HTTP Response object
+ * @param Zend_Uri_Http|string $uri The requested URI
+ * @return Zend_Http_CookieJar
+ * @todo Add the $uri functionality.
+ */
+ public static function fromResponse(Zend_Http_Response $response, $ref_uri)
+ {
+ $jar = new self();
+ $jar->addCookiesFromResponse($response, $ref_uri);
+ return $jar;
+ }
+}
diff --git a/site/vendors/phpQuery/Zend/Http/Exception.php b/site/vendors/phpQuery/Zend/Http/Exception.php
new file mode 100644
index 0000000..76e2a8d
--- /dev/null
+++ b/site/vendors/phpQuery/Zend/Http/Exception.php
@@ -0,0 +1,33 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Http
+ * @subpackage Exception
+ * @version $Id: Exception.php 8064 2008-02-16 10:58:39Z thomas $
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+require_once 'Zend/Exception.php';
+
+/**
+ * @category Zend
+ * @package Zend_Http
+ * @subpackage Client
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Http_Exception extends Zend_Exception
+{}
diff --git a/site/vendors/phpQuery/Zend/Http/Response.php b/site/vendors/phpQuery/Zend/Http/Response.php
new file mode 100644
index 0000000..73b27e4
--- /dev/null
+++ b/site/vendors/phpQuery/Zend/Http/Response.php
@@ -0,0 +1,625 @@
+<?php
+
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Http
+ * @subpackage Response
+ * @version $Id: Response.php 11175 2008-09-01 08:39:10Z yoshida@zend.co.jp $
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+/**
+ * Zend_Http_Response represents an HTTP 1.0 / 1.1 response message. It
+ * includes easy access to all the response's different elemts, as well as some
+ * convenience methods for parsing and validating HTTP responses.
+ *
+ * @package Zend_Http
+ * @subpackage Response
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Http_Response
+{
+ /**
+ * List of all known HTTP response codes - used by responseCodeAsText() to
+ * translate numeric codes to messages.
+ *
+ * @var array
+ */
+ protected static $messages = array(
+ // Informational 1xx
+ 100 => 'Continue',
+ 101 => 'Switching Protocols',
+
+ // Success 2xx
+ 200 => 'OK',
+ 201 => 'Created',
+ 202 => 'Accepted',
+ 203 => 'Non-Authoritative Information',
+ 204 => 'No Content',
+ 205 => 'Reset Content',
+ 206 => 'Partial Content',
+
+ // Redirection 3xx
+ 300 => 'Multiple Choices',
+ 301 => 'Moved Permanently',
+ 302 => 'Found', // 1.1
+ 303 => 'See Other',
+ 304 => 'Not Modified',
+ 305 => 'Use Proxy',
+ // 306 is deprecated but reserved
+ 307 => 'Temporary Redirect',
+
+ // Client Error 4xx
+ 400 => 'Bad Request',
+ 401 => 'Unauthorized',
+ 402 => 'Payment Required',
+ 403 => 'Forbidden',
+ 404 => 'Not Found',
+ 405 => 'Method Not Allowed',
+ 406 => 'Not Acceptable',
+ 407 => 'Proxy Authentication Required',
+ 408 => 'Request Timeout',
+ 409 => 'Conflict',
+ 410 => 'Gone',
+ 411 => 'Length Required',
+ 412 => 'Precondition Failed',
+ 413 => 'Request Entity Too Large',
+ 414 => 'Request-URI Too Long',
+ 415 => 'Unsupported Media Type',
+ 416 => 'Requested Range Not Satisfiable',
+ 417 => 'Expectation Failed',
+
+ // Server Error 5xx
+ 500 => 'Internal Server Error',
+ 501 => 'Not Implemented',
+ 502 => 'Bad Gateway',
+ 503 => 'Service Unavailable',
+ 504 => 'Gateway Timeout',
+ 505 => 'HTTP Version Not Supported',
+ 509 => 'Bandwidth Limit Exceeded'
+ );
+
+ /**
+ * The HTTP version (1.0, 1.1)
+ *
+ * @var string
+ */
+ protected $version;
+
+ /**
+ * The HTTP response code
+ *
+ * @var int
+ */
+ protected $code;
+
+ /**
+ * The HTTP response code as string
+ * (e.g. 'Not Found' for 404 or 'Internal Server Error' for 500)
+ *
+ * @var string
+ */
+ protected $message;
+
+ /**
+ * The HTTP response headers array
+ *
+ * @var array
+ */
+ protected $headers = array();
+
+ /**
+ * The HTTP response body
+ *
+ * @var string
+ */
+ protected $body;
+
+ /**
+ * HTTP response constructor
+ *
+ * In most cases, you would use Zend_Http_Response::fromString to parse an HTTP
+ * response string and create a new Zend_Http_Response object.
+ *
+ * NOTE: The constructor no longer accepts nulls or empty values for the code and
+ * headers and will throw an exception if the passed values do not form a valid HTTP
+ * responses.
+ *
+ * If no message is passed, the message will be guessed according to the response code.
+ *
+ * @param int $code Response code (200, 404, ...)
+ * @param array $headers Headers array
+ * @param string $body Response body
+ * @param string $version HTTP version
+ * @param string $message Response code as text
+ * @throws Zend_Http_Exception
+ */
+ public function __construct($code, $headers, $body = null, $version = '1.1', $message = null)
+ {
+ // Make sure the response code is valid and set it
+ if (self::responseCodeAsText($code) === null) {
+ require_once 'Zend/Http/Exception.php';
+ throw new Zend_Http_Exception("{$code} is not a valid HTTP response code");
+ }
+
+ $this->code = $code;
+
+ // Make sure we got valid headers and set them
+ if (! is_array($headers)) {
+ require_once 'Zend/Http/Exception.php';
+ throw new Zend_Http_Exception('No valid headers were passed');
+ }
+
+ foreach ($headers as $name => $value) {
+ if (is_int($name))
+ list($name, $value) = explode(": ", $value, 1);
+
+ $this->headers[ucwords(strtolower($name))] = $value;
+ }
+
+ // Set the body
+ $this->body = $body;
+
+ // Set the HTTP version
+ if (! preg_match('|^\d\.\d$|', $version)) {
+ require_once 'Zend/Http/Exception.php';
+ throw new Zend_Http_Exception("Invalid HTTP response version: $version");
+ }
+
+ $this->version = $version;
+
+ // If we got the response message, set it. Else, set it according to
+ // the response code
+ if (is_string($message)) {
+ $this->message = $message;
+ } else {
+ $this->message = self::responseCodeAsText($code);
+ }
+ }
+
+ /**
+ * Check whether the response is an error
+ *
+ * @return boolean
+ */
+ public function isError()
+ {
+ $restype = floor($this->code / 100);
+ if ($restype == 4 || $restype == 5) {
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * Check whether the response in successful
+ *
+ * @return boolean
+ */
+ public function isSuccessful()
+ {
+ $restype = floor($this->code / 100);
+ if ($restype == 2 || $restype == 1) { // Shouldn't 3xx count as success as well ???
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * Check whether the response is a redirection
+ *
+ * @return boolean
+ */
+ public function isRedirect()
+ {
+ $restype = floor($this->code / 100);
+ if ($restype == 3) {
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * Get the response body as string
+ *
+ * This method returns the body of the HTTP response (the content), as it
+ * should be in it's readable version - that is, after decoding it (if it
+ * was decoded), deflating it (if it was gzip compressed), etc.
+ *
+ * If you want to get the raw body (as transfered on wire) use
+ * $this->getRawBody() instead.
+ *
+ * @return string
+ */
+ public function getBody()
+ {
+ $body = '';
+
+ // Decode the body if it was transfer-encoded
+ switch ($this->getHeader('transfer-encoding')) {
+
+ // Handle chunked body
+ case 'chunked':
+ $body = self::decodeChunkedBody($this->body);
+ break;
+
+ // No transfer encoding, or unknown encoding extension:
+ // return body as is
+ default:
+ $body = $this->body;
+ break;
+ }
+
+ // Decode any content-encoding (gzip or deflate) if needed
+ switch (strtolower($this->getHeader('content-encoding'))) {
+
+ // Handle gzip encoding
+ case 'gzip':
+ $body = self::decodeGzip($body);
+ break;
+
+ // Handle deflate encoding
+ case 'deflate':
+ $body = self::decodeDeflate($body);
+ break;
+
+ default:
+ break;
+ }
+
+ return $body;
+ }
+
+ /**
+ * Get the raw response body (as transfered "on wire") as string
+ *
+ * If the body is encoded (with Transfer-Encoding, not content-encoding -
+ * IE "chunked" body), gzip compressed, etc. it will not be decoded.
+ *
+ * @return string
+ */
+ public function getRawBody()
+ {
+ return $this->body;
+ }
+
+ /**
+ * Get the HTTP version of the response
+ *
+ * @return string
+ */
+ public function getVersion()
+ {
+ return $this->version;
+ }
+
+ /**
+ * Get the HTTP response status code
+ *
+ * @return int
+ */
+ public function getStatus()
+ {
+ return $this->code;
+ }
+
+ /**
+ * Return a message describing the HTTP response code
+ * (Eg. "OK", "Not Found", "Moved Permanently")
+ *
+ * @return string
+ */
+ public function getMessage()
+ {
+ return $this->message;
+ }
+
+ /**
+ * Get the response headers
+ *
+ * @return array
+ */
+ public function getHeaders()
+ {
+ return $this->headers;
+ }
+
+ /**
+ * Get a specific header as string, or null if it is not set
+ *
+ * @param string$header
+ * @return string|array|null
+ */
+ public function getHeader($header)
+ {
+ $header = ucwords(strtolower($header));
+ if (! is_string($header) || ! isset($this->headers[$header])) return null;
+
+ return $this->headers[$header];
+ }
+
+ /**
+ * Get all headers as string
+ *
+ * @param boolean $status_line Whether to return the first status line (IE "HTTP 200 OK")
+ * @param string $br Line breaks (eg. "\n", "\r\n", "<br />")
+ * @return string
+ */
+ public function getHeadersAsString($status_line = true, $br = "\n")
+ {
+ $str = '';
+
+ if ($status_line) {
+ $str = "HTTP/{$this->version} {$this->code} {$this->message}{$br}";
+ }
+
+ // Iterate over the headers and stringify them
+ foreach ($this->headers as $name => $value)
+ {
+ if (is_string($value))
+ $str .= "{$name}: {$value}{$br}";
+
+ elseif (is_array($value)) {
+ foreach ($value as $subval) {
+ $str .= "{$name}: {$subval}{$br}";
+ }
+ }
+ }
+
+ return $str;
+ }
+
+ /**
+ * Get the entire response as string
+ *
+ * @param string $br Line breaks (eg. "\n", "\r\n", "<br />")
+ * @return string
+ */
+ public function asString($br = "\n")
+ {
+ return $this->getHeadersAsString(true, $br) . $br . $this->getRawBody();
+ }
+
+ /**
+ * A convenience function that returns a text representation of
+ * HTTP response codes. Returns 'Unknown' for unknown codes.
+ * Returns array of all codes, if $code is not specified.
+ *
+ * Conforms to HTTP/1.1 as defined in RFC 2616 (except for 'Unknown')
+ * See http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10 for reference
+ *
+ * @param int $code HTTP response code
+ * @param boolean $http11 Use HTTP version 1.1
+ * @return string
+ */
+ public static function responseCodeAsText($code = null, $http11 = true)
+ {
+ $messages = self::$messages;
+ if (! $http11) $messages[302] = 'Moved Temporarily';
+
+ if ($code === null) {
+ return $messages;
+ } elseif (isset($messages[$code])) {
+ return $messages[$code];
+ } else {
+ return 'Unknown';
+ }
+ }
+
+ /**
+ * Extract the response code from a response string
+ *
+ * @param string $response_str
+ * @return int
+ */
+ public static function extractCode($response_str)
+ {
+ preg_match("|^HTTP/[\d\.x]+ (\d+)|", $response_str, $m);
+
+ if (isset($m[1])) {
+ return (int) $m[1];
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Extract the HTTP message from a response
+ *
+ * @param string $response_str
+ * @return string
+ */
+ public static function extractMessage($response_str)
+ {
+ preg_match("|^HTTP/[\d\.x]+ \d+ ([^\r\n]+)|", $response_str, $m);
+
+ if (isset($m[1])) {
+ return $m[1];
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Extract the HTTP version from a response
+ *
+ * @param string $response_str
+ * @return string
+ */
+ public static function extractVersion($response_str)
+ {
+ preg_match("|^HTTP/([\d\.x]+) \d+|", $response_str, $m);
+
+ if (isset($m[1])) {
+ return $m[1];
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Extract the headers from a response string
+ *
+ * @param string $response_str
+ * @return array
+ */
+ public static function extractHeaders($response_str)
+ {
+ $headers = array();
+
+ // First, split body and headers
+ $parts = preg_split('|(?:\r?\n){2}|m', $response_str, 2);
+ if (! $parts[0]) return $headers;
+
+ // Split headers part to lines
+ $lines = explode("\n", $parts[0]);
+ unset($parts);
+ $last_header = null;
+
+ foreach($lines as $line) {
+ $line = trim($line, "\r\n");
+ if ($line == "") break;
+
+ if (preg_match("|^([\w-]+):\s+(.+)|", $line, $m)) {
+ unset($last_header);
+ $h_name = strtolower($m[1]);
+ $h_value = $m[2];
+
+ if (isset($headers[$h_name])) {
+ if (! is_array($headers[$h_name])) {
+ $headers[$h_name] = array($headers[$h_name]);
+ }
+
+ $headers[$h_name][] = $h_value;
+ } else {
+ $headers[$h_name] = $h_value;
+ }
+ $last_header = $h_name;
+ } elseif (preg_match("|^\s+(.+)$|", $line, $m) && $last_header !== null) {
+ if (is_array($headers[$last_header])) {
+ end($headers[$last_header]);
+ $last_header_key = key($headers[$last_header]);
+ $headers[$last_header][$last_header_key] .= $m[1];
+ } else {
+ $headers[$last_header] .= $m[1];
+ }
+ }
+ }
+
+ return $headers;
+ }
+
+ /**
+ * Extract the body from a response string
+ *
+ * @param string $response_str
+ * @return string
+ */
+ public static function extractBody($response_str)
+ {
+ $parts = preg_split('|(?:\r?\n){2}|m', $response_str, 2);
+ if (isset($parts[1])) {
+ return $parts[1];
+ } else {
+ return '';
+ }
+ }
+
+ /**
+ * Decode a "chunked" transfer-encoded body and return the decoded text
+ *
+ * @param string $body
+ * @return string
+ */
+ public static function decodeChunkedBody($body)
+ {
+ $decBody = '';
+
+ while (trim($body)) {
+ if (! preg_match("/^([\da-fA-F]+)[^\r\n]*\r\n/sm", $body, $m)) {
+ require_once 'Zend/Http/Exception.php';
+ throw new Zend_Http_Exception("Error parsing body - doesn't seem to be a chunked message");
+ }
+
+ $length = hexdec(trim($m[1]));
+ $cut = strlen($m[0]);
+
+ $decBody .= substr($body, $cut, $length);
+ $body = substr($body, $cut + $length + 2);
+ }
+
+ return $decBody;
+ }
+
+ /**
+ * Decode a gzip encoded message (when Content-encoding = gzip)
+ *
+ * Currently requires PHP with zlib support
+ *
+ * @param string $body
+ * @return string
+ */
+ public static function decodeGzip($body)
+ {
+ if (! function_exists('gzinflate')) {
+ require_once 'Zend/Http/Exception.php';
+ throw new Zend_Http_Exception('Unable to decode gzipped response ' .
+ 'body: perhaps the zlib extension is not loaded?');
+ }
+
+ return gzinflate(substr($body, 10));
+ }
+
+ /**
+ * Decode a zlib deflated message (when Content-encoding = deflate)
+ *
+ * Currently requires PHP with zlib support
+ *
+ * @param string $body
+ * @return string
+ */
+ public static function decodeDeflate($body)
+ {
+ if (! function_exists('gzuncompress')) {
+ require_once 'Zend/Http/Exception.php';
+ throw new Zend_Http_Exception('Unable to decode deflated response ' .
+ 'body: perhaps the zlib extension is not loaded?');
+ }
+
+ return gzuncompress($body);
+ }
+
+ /**
+ * Create a new Zend_Http_Response object from a string
+ *
+ * @param string $response_str
+ * @return Zend_Http_Response
+ */
+ public static function fromString($response_str)
+ {
+ $code = self::extractCode($response_str);
+ $headers = self::extractHeaders($response_str);
+ $body = self::extractBody($response_str);
+ $version = self::extractVersion($response_str);
+ $message = self::extractMessage($response_str);
+
+ return new Zend_Http_Response($code, $headers, $body, $version, $message);
+ }
+}
diff --git a/site/vendors/phpQuery/Zend/Json/Decoder.php b/site/vendors/phpQuery/Zend/Json/Decoder.php
new file mode 100644
index 0000000..b9bf8ba
--- /dev/null
+++ b/site/vendors/phpQuery/Zend/Json/Decoder.php
@@ -0,0 +1,457 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Json
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+/**
+ * @see Zend_Json
+ */
+require_once 'Zend/Json.php';
+
+/**
+ * @see Zend_Json_Exception
+ */
+require_once 'Zend/Json/Exception.php';
+
+
+/**
+ * Decode JSON encoded string to PHP variable constructs
+ *
+ * @category Zend
+ * @package Zend_Json
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Json_Decoder
+{
+ /**
+ * Parse tokens used to decode the JSON object. These are not
+ * for public consumption, they are just used internally to the
+ * class.
+ */
+ const EOF = 0;
+ const DATUM = 1;
+ const LBRACE = 2;
+ const LBRACKET = 3;
+ const RBRACE = 4;
+ const RBRACKET = 5;
+ const COMMA = 6;
+ const COLON = 7;
+
+ /**
+ * Use to maintain a "pointer" to the source being decoded
+ *
+ * @var string
+ */
+ protected $_source;
+
+ /**
+ * Caches the source length
+ *
+ * @var int
+ */
+ protected $_sourceLength;
+
+ /**
+ * The offset within the souce being decoded
+ *
+ * @var int
+ *
+ */
+ protected $_offset;
+
+ /**
+ * The current token being considered in the parser cycle
+ *
+ * @var int
+ */
+ protected $_token;
+
+ /**
+ * Flag indicating how objects should be decoded
+ *
+ * @var int
+ * @access protected
+ */
+ protected $_decodeType;
+
+ /**
+ * Constructor
+ *
+ * @param string $source String source to decode
+ * @param int $decodeType How objects should be decoded -- see
+ * {@link Zend_Json::TYPE_ARRAY} and {@link Zend_Json::TYPE_OBJECT} for
+ * valid values
+ * @return void
+ */
+ protected function __construct($source, $decodeType)
+ {
+ // Set defaults
+ $this->_source = $source;
+ $this->_sourceLength = strlen($source);
+ $this->_token = self::EOF;
+ $this->_offset = 0;
+
+ // Normalize and set $decodeType
+ if (!in_array($decodeType, array(Zend_Json::TYPE_ARRAY, Zend_Json::TYPE_OBJECT)))
+ {
+ $decodeType = Zend_Json::TYPE_ARRAY;
+ }
+ $this->_decodeType = $decodeType;
+
+ // Set pointer at first token
+ $this->_getNextToken();
+ }
+
+ /**
+ * Decode a JSON source string
+ *
+ * Decodes a JSON encoded string. The value returned will be one of the
+ * following:
+ * - integer
+ * - float
+ * - boolean
+ * - null
+ * - StdClass
+ * - array
+ * - array of one or more of the above types
+ *
+ * By default, decoded objects will be returned as associative arrays; to
+ * return a StdClass object instead, pass {@link Zend_Json::TYPE_OBJECT} to
+ * the $objectDecodeType parameter.
+ *
+ * Throws a Zend_Json_Exception if the source string is null.
+ *
+ * @static
+ * @access public
+ * @param string $source String to be decoded
+ * @param int $objectDecodeType How objects should be decoded; should be
+ * either or {@link Zend_Json::TYPE_ARRAY} or
+ * {@link Zend_Json::TYPE_OBJECT}; defaults to TYPE_ARRAY
+ * @return mixed
+ * @throws Zend_Json_Exception
+ */
+ public static function decode($source = null, $objectDecodeType = Zend_Json::TYPE_ARRAY)
+ {
+ if (null === $source) {
+ throw new Zend_Json_Exception('Must specify JSON encoded source for decoding');
+ } elseif (!is_string($source)) {
+ throw new Zend_Json_Exception('Can only decode JSON encoded strings');
+ }
+
+ $decoder = new self($source, $objectDecodeType);
+
+ return $decoder->_decodeValue();
+ }
+
+
+ /**
+ * Recursive driving rountine for supported toplevel tops
+ *
+ * @return mixed
+ */
+ protected function _decodeValue()
+ {
+ switch ($this->_token) {
+ case self::DATUM:
+ $result = $this->_tokenValue;
+ $this->_getNextToken();
+ return($result);
+ break;
+ case self::LBRACE:
+ return($this->_decodeObject());
+ break;
+ case self::LBRACKET:
+ return($this->_decodeArray());
+ break;
+ default:
+ return null;
+ break;
+ }
+ }
+
+ /**
+ * Decodes an object of the form:
+ * { "attribute: value, "attribute2" : value,...}
+ *
+ * If Zend_Json_Encoder was used to encode the original object then
+ * a special attribute called __className which specifies a class
+ * name that should wrap the data contained within the encoded source.
+ *
+ * Decodes to either an array or StdClass object, based on the value of
+ * {@link $_decodeType}. If invalid $_decodeType present, returns as an
+ * array.
+ *
+ * @return array|StdClass
+ */
+ protected function _decodeObject()
+ {
+ $members = array();
+ $tok = $this->_getNextToken();
+
+ while ($tok && $tok != self::RBRACE) {
+ if ($tok != self::DATUM || ! is_string($this->_tokenValue)) {
+ throw new Zend_Json_Exception('Missing key in object encoding: ' . $this->_source);
+ }
+
+ $key = $this->_tokenValue;
+ $tok = $this->_getNextToken();
+
+ if ($tok != self::COLON) {
+ throw new Zend_Json_Exception('Missing ":" in object encoding: ' . $this->_source);
+ }
+
+ $tok = $this->_getNextToken();
+ $members[$key] = $this->_decodeValue();
+ $tok = $this->_token;
+
+ if ($tok == self::RBRACE) {
+ break;
+ }
+
+ if ($tok != self::COMMA) {
+ throw new Zend_Json_Exception('Missing "," in object encoding: ' . $this->_source);
+ }
+
+ $tok = $this->_getNextToken();
+ }
+
+ switch ($this->_decodeType) {
+ case Zend_Json::TYPE_OBJECT:
+ // Create new StdClass and populate with $members
+ $result = new StdClass();
+ foreach ($members as $key => $value) {
+ $result->$key = $value;
+ }
+ break;
+ case Zend_Json::TYPE_ARRAY:
+ default:
+ $result = $members;
+ break;
+ }
+
+ $this->_getNextToken();
+ return $result;
+ }
+
+ /**
+ * Decodes a JSON array format:
+ * [element, element2,...,elementN]
+ *
+ * @return array
+ */
+ protected function _decodeArray()
+ {
+ $result = array();
+ $starttok = $tok = $this->_getNextToken(); // Move past the '['
+ $index = 0;
+
+ while ($tok && $tok != self::RBRACKET) {
+ $result[$index++] = $this->_decodeValue();
+
+ $tok = $this->_token;
+
+ if ($tok == self::RBRACKET || !$tok) {
+ break;
+ }
+
+ if ($tok != self::COMMA) {
+ throw new Zend_Json_Exception('Missing "," in array encoding: ' . $this->_source);
+ }
+
+ $tok = $this->_getNextToken();
+ }
+
+ $this->_getNextToken();
+ return($result);
+ }
+
+
+ /**
+ * Removes whitepsace characters from the source input
+ */
+ protected function _eatWhitespace()
+ {
+ if (preg_match(
+ '/([\t\b\f\n\r ])*/s',
+ $this->_source,
+ $matches,
+ PREG_OFFSET_CAPTURE,
+ $this->_offset)
+ && $matches[0][1] == $this->_offset)
+ {
+ $this->_offset += strlen($matches[0][0]);
+ }
+ }
+
+
+ /**
+ * Retrieves the next token from the source stream
+ *
+ * @return int Token constant value specified in class definition
+ */
+ protected function _getNextToken()
+ {
+ $this->_token = self::EOF;
+ $this->_tokenValue = null;
+ $this->_eatWhitespace();
+
+ if ($this->_offset >= $this->_sourceLength) {
+ return(self::EOF);
+ }
+
+ $str = $this->_source;
+ $str_length = $this->_sourceLength;
+ $i = $this->_offset;
+ $start = $i;
+
+ switch ($str{$i}) {
+ case '{':
+ $this->_token = self::LBRACE;
+ break;
+ case '}':
+ $this->_token = self::RBRACE;
+ break;
+ case '[':
+ $this->_token = self::LBRACKET;
+ break;
+ case ']':
+ $this->_token = self::RBRACKET;
+ break;
+ case ',':
+ $this->_token = self::COMMA;
+ break;
+ case ':':
+ $this->_token = self::COLON;
+ break;
+ case '"':
+ $result = '';
+ do {
+ $i++;
+ if ($i >= $str_length) {
+ break;
+ }
+
+ $chr = $str{$i};
+ if ($chr == '\\') {
+ $i++;
+ if ($i >= $str_length) {
+ break;
+ }
+ $chr = $str{$i};
+ switch ($chr) {
+ case '"' :
+ $result .= '"';
+ break;
+ case '\\':
+ $result .= '\\';
+ break;
+ case '/' :
+ $result .= '/';
+ break;
+ case 'b' :
+ $result .= chr(8);
+ break;
+ case 'f' :
+ $result .= chr(12);
+ break;
+ case 'n' :
+ $result .= chr(10);
+ break;
+ case 'r' :
+ $result .= chr(13);
+ break;
+ case 't' :
+ $result .= chr(9);
+ break;
+ case '\'' :
+ $result .= '\'';
+ break;
+ default:
+ throw new Zend_Json_Exception("Illegal escape "
+ . "sequence '" . $chr . "'");
+ }
+ } elseif ($chr == '"') {
+ break;
+ } else {
+ $result .= $chr;
+ }
+ } while ($i < $str_length);
+
+ $this->_token = self::DATUM;
+ //$this->_tokenValue = substr($str, $start + 1, $i - $start - 1);
+ $this->_tokenValue = $result;
+ break;
+ case 't':
+ if (($i+ 3) < $str_length && substr($str, $start, 4) == "true") {
+ $this->_token = self::DATUM;
+ }
+ $this->_tokenValue = true;
+ $i += 3;
+ break;
+ case 'f':
+ if (($i+ 4) < $str_length && substr($str, $start, 5) == "false") {
+ $this->_token = self::DATUM;
+ }
+ $this->_tokenValue = false;
+ $i += 4;
+ break;
+ case 'n':
+ if (($i+ 3) < $str_length && substr($str, $start, 4) == "null") {
+ $this->_token = self::DATUM;
+ }
+ $this->_tokenValue = NULL;
+ $i += 3;
+ break;
+ }
+
+ if ($this->_token != self::EOF) {
+ $this->_offset = $i + 1; // Consume the last token character
+ return($this->_token);
+ }
+
+ $chr = $str{$i};
+ if ($chr == '-' || $chr == '.' || ($chr >= '0' && $chr <= '9')) {
+ if (preg_match('/-?([0-9])*(\.[0-9]*)?((e|E)((-|\+)?)[0-9]+)?/s',
+ $str, $matches, PREG_OFFSET_CAPTURE, $start) && $matches[0][1] == $start) {
+
+ $datum = $matches[0][0];
+
+ if (is_numeric($datum)) {
+ if (preg_match('/^0\d+$/', $datum)) {
+ throw new Zend_Json_Exception("Octal notation not supported by JSON (value: $datum)");
+ } else {
+ $val = intval($datum);
+ $fVal = floatval($datum);
+ $this->_tokenValue = ($val == $fVal ? $val : $fVal);
+ }
+ } else {
+ throw new Zend_Json_Exception("Illegal number format: $datum");
+ }
+
+ $this->_token = self::DATUM;
+ $this->_offset = $start + strlen($datum);
+ }
+ } else {
+ throw new Zend_Json_Exception('Illegal Token');
+ }
+
+ return($this->_token);
+ }
+}
+
diff --git a/site/vendors/phpQuery/Zend/Json/Encoder.php b/site/vendors/phpQuery/Zend/Json/Encoder.php
new file mode 100644
index 0000000..ce2024a
--- /dev/null
+++ b/site/vendors/phpQuery/Zend/Json/Encoder.php
@@ -0,0 +1,431 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Json
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+
+/**
+ * Zend_Json_Exception
+ */
+require_once 'Zend/Json/Exception.php';
+
+
+/**
+ * Encode PHP constructs to JSON
+ *
+ * @category Zend
+ * @package Zend_Json
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Json_Encoder
+{
+ /**
+ * Whether or not to check for possible cycling
+ *
+ * @var boolean
+ */
+ protected $_cycleCheck;
+
+ /**
+ * Additional options used during encoding
+ *
+ * @var array
+ */
+ protected $_options = array();
+
+ /**
+ * Array of visited objects; used to prevent cycling.
+ *
+ * @var array
+ */
+ protected $_visited = array();
+
+ /**
+ * Constructor
+ *
+ * @param boolean $cycleCheck Whether or not to check for recursion when encoding
+ * @param array $options Additional options used during encoding
+ * @return void
+ */
+ protected function __construct($cycleCheck = false, $options = array())
+ {
+ $this->_cycleCheck = $cycleCheck;
+ $this->_options = $options;
+ }
+
+ /**
+ * Use the JSON encoding scheme for the value specified
+ *
+ * @param mixed $value The value to be encoded
+ * @param boolean $cycleCheck Whether or not to check for possible object recursion when encoding
+ * @param array $options Additional options used during encoding
+ * @return string The encoded value
+ */
+ public static function encode($value, $cycleCheck = false, $options = array())
+ {
+ $encoder = new self(($cycleCheck) ? true : false, $options);
+
+ return $encoder->_encodeValue($value);
+ }
+
+ /**
+ * Recursive driver which determines the type of value to be encoded
+ * and then dispatches to the appropriate method. $values are either
+ * - objects (returns from {@link _encodeObject()})
+ * - arrays (returns from {@link _encodeArray()})
+ * - basic datums (e.g. numbers or strings) (returns from {@link _encodeDatum()})
+ *
+ * @param $value mixed The value to be encoded
+ * @return string Encoded value
+ */
+ protected function _encodeValue(&$value)
+ {
+ if (is_object($value)) {
+ return $this->_encodeObject($value);
+ } else if (is_array($value)) {
+ return $this->_encodeArray($value);
+ }
+
+ return $this->_encodeDatum($value);
+ }
+
+
+
+ /**
+ * Encode an object to JSON by encoding each of the public properties
+ *
+ * A special property is added to the JSON object called '__className'
+ * that contains the name of the class of $value. This is used to decode
+ * the object on the client into a specific class.
+ *
+ * @param $value object
+ * @return string
+ * @throws Zend_Json_Exception If recursive checks are enabled and the object has been serialized previously
+ */
+ protected function _encodeObject(&$value)
+ {
+ if ($this->_cycleCheck) {
+ if ($this->_wasVisited($value)) {
+
+ if (isset($this->_options['silenceCyclicalExceptions'])
+ && $this->_options['silenceCyclicalExceptions']===true) {
+
+ return '"* RECURSION (' . get_class($value) . ') *"';
+
+ } else {
+ throw new Zend_Json_Exception(
+ 'Cycles not supported in JSON encoding, cycle introduced by '
+ . 'class "' . get_class($value) . '"'
+ );
+ }
+ }
+
+ $this->_visited[] = $value;
+ }
+
+ $props = '';
+ foreach (get_object_vars($value) as $name => $propValue) {
+ if (isset($propValue)) {
+ $props .= ','
+ . $this->_encodeValue($name)
+ . ':'
+ . $this->_encodeValue($propValue);
+ }
+ }
+
+ return '{"__className":"' . get_class($value) . '"'
+ . $props . '}';
+ }
+
+
+ /**
+ * Determine if an object has been serialized already
+ *
+ * @param mixed $value
+ * @return boolean
+ */
+ protected function _wasVisited(&$value)
+ {
+ if (in_array($value, $this->_visited, true)) {
+ return true;
+ }
+
+ return false;
+ }
+
+
+ /**
+ * JSON encode an array value
+ *
+ * Recursively encodes each value of an array and returns a JSON encoded
+ * array string.
+ *
+ * Arrays are defined as integer-indexed arrays starting at index 0, where
+ * the last index is (count($array) -1); any deviation from that is
+ * considered an associative array, and will be encoded as such.
+ *
+ * @param $array array
+ * @return string
+ */
+ protected function _encodeArray(&$array)
+ {
+ $tmpArray = array();
+
+ // Check for associative array
+ if (!empty($array) && (array_keys($array) !== range(0, count($array) - 1))) {
+ // Associative array
+ $result = '{';
+ foreach ($array as $key => $value) {
+ $key = (string) $key;
+ $tmpArray[] = $this->_encodeString($key)
+ . ':'
+ . $this->_encodeValue($value);
+ }
+ $result .= implode(',', $tmpArray);
+ $result .= '}';
+ } else {
+ // Indexed array
+ $result = '[';
+ $length = count($array);
+ for ($i = 0; $i < $length; $i++) {
+ $tmpArray[] = $this->_encodeValue($array[$i]);
+ }
+ $result .= implode(',', $tmpArray);
+ $result .= ']';
+ }
+
+ return $result;
+ }
+
+
+ /**
+ * JSON encode a basic data type (string, number, boolean, null)
+ *
+ * If value type is not a string, number, boolean, or null, the string
+ * 'null' is returned.
+ *
+ * @param $value mixed
+ * @return string
+ */
+ protected function _encodeDatum(&$value)
+ {
+ $result = 'null';
+
+ if (is_int($value) || is_float($value)) {
+ $result = (string)$value;
+ } elseif (is_string($value)) {
+ $result = $this->_encodeString($value);
+ } elseif (is_bool($value)) {
+ $result = $value ? 'true' : 'false';
+ }
+
+ return $result;
+ }
+
+
+ /**
+ * JSON encode a string value by escaping characters as necessary
+ *
+ * @param $value string
+ * @return string
+ */
+ protected function _encodeString(&$string)
+ {
+ // Escape these characters with a backslash:
+ // " \ / \n \r \t \b \f
+ $search = array('\\', "\n", "\t", "\r", "\b", "\f", '"');
+ $replace = array('\\\\', '\\n', '\\t', '\\r', '\\b', '\\f', '\"');
+ $string = str_replace($search, $replace, $string);
+
+ // Escape certain ASCII characters:
+ // 0x08 => \b
+ // 0x0c => \f
+ $string = str_replace(array(chr(0x08), chr(0x0C)), array('\b', '\f'), $string);
+
+ return '"' . $string . '"';
+ }
+
+
+ /**
+ * Encode the constants associated with the ReflectionClass
+ * parameter. The encoding format is based on the class2 format
+ *
+ * @param $cls ReflectionClass
+ * @return string Encoded constant block in class2 format
+ */
+ private static function _encodeConstants(ReflectionClass $cls)
+ {
+ $result = "constants : {";
+ $constants = $cls->getConstants();
+
+ $tmpArray = array();
+ if (!empty($constants)) {
+ foreach ($constants as $key => $value) {
+ $tmpArray[] = "$key: " . self::encode($value);
+ }
+
+ $result .= implode(', ', $tmpArray);
+ }
+
+ return $result . "}";
+ }
+
+
+ /**
+ * Encode the public methods of the ReflectionClass in the
+ * class2 format
+ *
+ * @param $cls ReflectionClass
+ * @return string Encoded method fragment
+ *
+ */
+ private static function _encodeMethods(ReflectionClass $cls)
+ {
+ $methods = $cls->getMethods();
+ $result = 'methods:{';
+
+ $started = false;
+ foreach ($methods as $method) {
+ if (! $method->isPublic() || !$method->isUserDefined()) {
+ continue;
+ }
+
+ if ($started) {
+ $result .= ',';
+ }
+ $started = true;
+
+ $result .= '' . $method->getName(). ':function(';
+
+ if ('__construct' != $method->getName()) {
+ $parameters = $method->getParameters();
+ $paramCount = count($parameters);
+ $argsStarted = false;
+
+ $argNames = "var argNames=[";
+ foreach ($parameters as $param) {
+ if ($argsStarted) {
+ $result .= ',';
+ }
+
+ $result .= $param->getName();
+
+ if ($argsStarted) {
+ $argNames .= ',';
+ }
+
+ $argNames .= '"' . $param->getName() . '"';
+
+ $argsStarted = true;
+ }
+ $argNames .= "];";
+
+ $result .= "){"
+ . $argNames
+ . 'var result = ZAjaxEngine.invokeRemoteMethod('
+ . "this, '" . $method->getName()
+ . "',argNames,arguments);"
+ . 'return(result);}';
+ } else {
+ $result .= "){}";
+ }
+ }
+
+ return $result . "}";
+ }
+
+
+ /**
+ * Encode the public properties of the ReflectionClass in the class2
+ * format.
+ *
+ * @param $cls ReflectionClass
+ * @return string Encode properties list
+ *
+ */
+ private static function _encodeVariables(ReflectionClass $cls)
+ {
+ $properties = $cls->getProperties();
+ $propValues = get_class_vars($cls->getName());
+ $result = "variables:{";
+ $cnt = 0;
+
+ $tmpArray = array();
+ foreach ($properties as $prop) {
+ if (! $prop->isPublic()) {
+ continue;
+ }
+
+ $tmpArray[] = $prop->getName()
+ . ':'
+ . self::encode($propValues[$prop->getName()]);
+ }
+ $result .= implode(',', $tmpArray);
+
+ return $result . "}";
+ }
+
+ /**
+ * Encodes the given $className into the class2 model of encoding PHP
+ * classes into JavaScript class2 classes.
+ * NOTE: Currently only public methods and variables are proxied onto
+ * the client machine
+ *
+ * @param $className string The name of the class, the class must be
+ * instantiable using a null constructor
+ * @param $package string Optional package name appended to JavaScript
+ * proxy class name
+ * @return string The class2 (JavaScript) encoding of the class
+ * @throws Zend_Json_Exception
+ */
+ public static function encodeClass($className, $package = '')
+ {
+ $cls = new ReflectionClass($className);
+ if (! $cls->isInstantiable()) {
+ throw new Zend_Json_Exception("$className must be instantiable");
+ }
+
+ return "Class.create('$package$className',{"
+ . self::_encodeConstants($cls) .","
+ . self::_encodeMethods($cls) .","
+ . self::_encodeVariables($cls) .'});';
+ }
+
+
+ /**
+ * Encode several classes at once
+ *
+ * Returns JSON encoded classes, using {@link encodeClass()}.
+ *
+ * @param array $classNames
+ * @param string $package
+ * @return string
+ */
+ public static function encodeClasses(array $classNames, $package = '')
+ {
+ $result = '';
+ foreach ($classNames as $className) {
+ $result .= self::encodeClass($className, $package);
+ }
+
+ return $result;
+ }
+
+}
+
diff --git a/site/vendors/phpQuery/Zend/Json/Exception.php b/site/vendors/phpQuery/Zend/Json/Exception.php
new file mode 100644
index 0000000..5b99095
--- /dev/null
+++ b/site/vendors/phpQuery/Zend/Json/Exception.php
@@ -0,0 +1,36 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Json
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+
+/**
+ * Zend_Exception
+ */
+require_once 'Zend/Exception.php';
+
+
+/**
+ * @category Zend
+ * @package Zend_Json
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Json_Exception extends Zend_Exception
+{}
+
diff --git a/site/vendors/phpQuery/Zend/Loader.php b/site/vendors/phpQuery/Zend/Loader.php
new file mode 100644
index 0000000..a487ab0
--- /dev/null
+++ b/site/vendors/phpQuery/Zend/Loader.php
@@ -0,0 +1,258 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Loader
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id: Loader.php 10454 2008-07-26 06:25:51Z ralph $
+ */
+
+/**
+ * Static methods for loading classes and files.
+ *
+ * @category Zend
+ * @package Zend_Loader
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Loader
+{
+ /**
+ * Loads a class from a PHP file. The filename must be formatted
+ * as "$class.php".
+ *
+ * If $dirs is a string or an array, it will search the directories
+ * in the order supplied, and attempt to load the first matching file.
+ *
+ * If $dirs is null, it will split the class name at underscores to
+ * generate a path hierarchy (e.g., "Zend_Example_Class" will map
+ * to "Zend/Example/Class.php").
+ *
+ * If the file was not found in the $dirs, or if no $dirs were specified,
+ * it will attempt to load it from PHP's include_path.
+ *
+ * @param string $class - The full class name of a Zend component.
+ * @param string|array $dirs - OPTIONAL Either a path or an array of paths
+ * to search.
+ * @return void
+ * @throws Zend_Exception
+ */
+ public static function loadClass($class, $dirs = null)
+ {
+ if (class_exists($class, false) || interface_exists($class, false)) {
+ return;
+ }
+
+ if ((null !== $dirs) && !is_string($dirs) && !is_array($dirs)) {
+ require_once 'Zend/Exception.php';
+ throw new Zend_Exception('Directory argument must be a string or an array');
+ }
+
+ // autodiscover the path from the class name
+ $file = str_replace('_', DIRECTORY_SEPARATOR, $class) . '.php';
+ if (!empty($dirs)) {
+ // use the autodiscovered path
+ $dirPath = dirname($file);
+ if (is_string($dirs)) {
+ $dirs = explode(PATH_SEPARATOR, $dirs);
+ }
+ foreach ($dirs as $key => $dir) {
+ if ($dir == '.') {
+ $dirs[$key] = $dirPath;
+ } else {
+ $dir = rtrim($dir, '\\/');
+ $dirs[$key] = $dir . DIRECTORY_SEPARATOR . $dirPath;
+ }
+ }
+ $file = basename($file);
+ self::loadFile($file, $dirs, true);
+ } else {
+ self::_securityCheck($file);
+ include_once $file;
+ }
+
+ if (!class_exists($class, false) && !interface_exists($class, false)) {
+ require_once 'Zend/Exception.php';
+ throw new Zend_Exception("File \"$file\" does not exist or class \"$class\" was not found in the file");
+ }
+ }
+
+ /**
+ * Loads a PHP file. This is a wrapper for PHP's include() function.
+ *
+ * $filename must be the complete filename, including any
+ * extension such as ".php". Note that a security check is performed that
+ * does not permit extended characters in the filename. This method is
+ * intended for loading Zend Framework files.
+ *
+ * If $dirs is a string or an array, it will search the directories
+ * in the order supplied, and attempt to load the first matching file.
+ *
+ * If the file was not found in the $dirs, or if no $dirs were specified,
+ * it will attempt to load it from PHP's include_path.
+ *
+ * If $once is TRUE, it will use include_once() instead of include().
+ *
+ * @param string $filename
+ * @param string|array $dirs - OPTIONAL either a path or array of paths
+ * to search.
+ * @param boolean $once
+ * @return boolean
+ * @throws Zend_Exception
+ */
+ public static function loadFile($filename, $dirs = null, $once = false)
+ {
+ self::_securityCheck($filename);
+
+ /**
+ * Search in provided directories, as well as include_path
+ */
+ $incPath = false;
+ if (!empty($dirs) && (is_array($dirs) || is_string($dirs))) {
+ if (is_array($dirs)) {
+ $dirs = implode(PATH_SEPARATOR, $dirs);
+ }
+ $incPath = get_include_path();
+ set_include_path($dirs . PATH_SEPARATOR . $incPath);
+ }
+
+ /**
+ * Try finding for the plain filename in the include_path.
+ */
+ if ($once) {
+ include_once $filename;
+ } else {
+ include $filename;
+ }
+
+ /**
+ * If searching in directories, reset include_path
+ */
+ if ($incPath) {
+ set_include_path($incPath);
+ }
+
+ return true;
+ }
+
+ /**
+ * Returns TRUE if the $filename is readable, or FALSE otherwise.
+ * This function uses the PHP include_path, where PHP's is_readable()
+ * does not.
+ *
+ * @param string $filename
+ * @return boolean
+ */
+ public static function isReadable($filename)
+ {
+ if (!$fh = @fopen($filename, 'r', true)) {
+ return false;
+ }
+ @fclose($fh);
+ return true;
+ }
+
+ /**
+ * spl_autoload() suitable implementation for supporting class autoloading.
+ *
+ * Attach to spl_autoload() using the following:
+ * <code>
+ * spl_autoload_register(array('Zend_Loader', 'autoload'));
+ * </code>
+ *
+ * @param string $class
+ * @return string|false Class name on success; false on failure
+ */
+ public static function autoload($class)
+ {
+ try {
+ self::loadClass($class);
+ return $class;
+ } catch (Exception $e) {
+ return false;
+ }
+ }
+
+ /**
+ * Register {@link autoload()} with spl_autoload()
+ *
+ * @param string $class (optional)
+ * @param boolean $enabled (optional)
+ * @return void
+ * @throws Zend_Exception if spl_autoload() is not found
+ * or if the specified class does not have an autoload() method.
+ */
+ public static function registerAutoload($class = 'Zend_Loader', $enabled = true)
+ {
+ if (!function_exists('spl_autoload_register')) {
+ require_once 'Zend/Exception.php';
+ throw new Zend_Exception('spl_autoload does not exist in this PHP installation');
+ }
+
+ self::loadClass($class);
+ $methods = get_class_methods($class);
+ if (!in_array('autoload', (array) $methods)) {
+ require_once 'Zend/Exception.php';
+ throw new Zend_Exception("The class \"$class\" does not have an autoload() method");
+ }
+
+ if ($enabled === true) {
+ spl_autoload_register(array($class, 'autoload'));
+ } else {
+ spl_autoload_unregister(array($class, 'autoload'));
+ }
+ }
+
+ /**
+ * Ensure that filename does not contain exploits
+ *
+ * @param string $filename
+ * @return void
+ * @throws Zend_Exception
+ */
+ protected static function _securityCheck($filename)
+ {
+ /**
+ * Security check
+ */
+ if (preg_match('/[^a-z0-9\\/\\\\_.-]/i', $filename)) {
+ require_once 'Zend/Exception.php';
+ throw new Zend_Exception('Security check: Illegal character in filename');
+ }
+ }
+
+ /**
+ * Attempt to include() the file.
+ *
+ * include() is not prefixed with the @ operator because if
+ * the file is loaded and contains a parse error, execution
+ * will halt silently and this is difficult to debug.
+ *
+ * Always set display_errors = Off on production servers!
+ *
+ * @param string $filespec
+ * @param boolean $once
+ * @return boolean
+ * @deprecated Since 1.5.0; use loadFile() instead
+ */
+ protected static function _includeFile($filespec, $once = false)
+ {
+ if ($once) {
+ return include_once $filespec;
+ } else {
+ return include $filespec ;
+ }
+ }
+}
diff --git a/site/vendors/phpQuery/Zend/Registry.php b/site/vendors/phpQuery/Zend/Registry.php
new file mode 100644
index 0000000..62d9ceb
--- /dev/null
+++ b/site/vendors/phpQuery/Zend/Registry.php
@@ -0,0 +1,195 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Registry
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id: Registry.php 8064 2008-02-16 10:58:39Z thomas $
+ */
+
+/**
+ * Generic storage class helps to manage global data.
+ *
+ * @category Zend
+ * @package Zend_Registry
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Registry extends ArrayObject
+{
+ /**
+ * Class name of the singleton registry object.
+ * @var string
+ */
+ private static $_registryClassName = 'Zend_Registry';
+
+ /**
+ * Registry object provides storage for shared objects.
+ * @var Zend_Registry
+ */
+ private static $_registry = null;
+
+ /**
+ * Retrieves the default registry instance.
+ *
+ * @return Zend_Registry
+ */
+ public static function getInstance()
+ {
+ if (self::$_registry === null) {
+ self::init();
+ }
+
+ return self::$_registry;
+ }
+
+ /**
+ * Set the default registry instance to a specified instance.
+ *
+ * @param Zend_Registry $registry An object instance of type Zend_Registry,
+ * or a subclass.
+ * @return void
+ * @throws Zend_Exception if registry is already initialized.
+ */
+ public static function setInstance(Zend_Registry $registry)
+ {
+ if (self::$_registry !== null) {
+ require_once 'Zend/Exception.php';
+ throw new Zend_Exception('Registry is already initialized');
+ }
+
+ self::setClassName(get_class($registry));
+ self::$_registry = $registry;
+ }
+
+ /**
+ * Initialize the default registry instance.
+ *
+ * @return void
+ */
+ protected static function init()
+ {
+ self::setInstance(new self::$_registryClassName());
+ }
+
+ /**
+ * Set the class name to use for the default registry instance.
+ * Does not affect the currently initialized instance, it only applies
+ * for the next time you instantiate.
+ *
+ * @param string $registryClassName
+ * @return void
+ * @throws Zend_Exception if the registry is initialized or if the
+ * class name is not valid.
+ */
+ public static function setClassName($registryClassName = 'Zend_Registry')
+ {
+ if (self::$_registry !== null) {
+ require_once 'Zend/Exception.php';
+ throw new Zend_Exception('Registry is already initialized');
+ }
+
+ if (!is_string($registryClassName)) {
+ require_once 'Zend/Exception.php';
+ throw new Zend_Exception("Argument is not a class name");
+ }
+
+ /**
+ * @see Zend_Loader
+ */
+ require_once 'Zend/Loader.php';
+ Zend_Loader::loadClass($registryClassName);
+
+ self::$_registryClassName = $registryClassName;
+ }
+
+ /**
+ * Unset the default registry instance.
+ * Primarily used in tearDown() in unit tests.
+ * @returns void
+ */
+ public static function _unsetInstance()
+ {
+ self::$_registry = null;
+ }
+
+ /**
+ * getter method, basically same as offsetGet().
+ *
+ * This method can be called from an object of type Zend_Registry, or it
+ * can be called statically. In the latter case, it uses the default
+ * static instance stored in the class.
+ *
+ * @param string $index - get the value associated with $index
+ * @return mixed
+ * @throws Zend_Exception if no entry is registerd for $index.
+ */
+ public static function get($index)
+ {
+ $instance = self::getInstance();
+
+ if (!$instance->offsetExists($index)) {
+ require_once 'Zend/Exception.php';
+ throw new Zend_Exception("No entry is registered for key '$index'");
+ }
+
+ return $instance->offsetGet($index);
+ }
+
+ /**
+ * setter method, basically same as offsetSet().
+ *
+ * This method can be called from an object of type Zend_Registry, or it
+ * can be called statically. In the latter case, it uses the default
+ * static instance stored in the class.
+ *
+ * @param string $index The location in the ArrayObject in which to store
+ * the value.
+ * @param mixed $value The object to store in the ArrayObject.
+ * @return void
+ */
+ public static function set($index, $value)
+ {
+ $instance = self::getInstance();
+ $instance->offsetSet($index, $value);
+ }
+
+ /**
+ * Returns TRUE if the $index is a named value in the registry,
+ * or FALSE if $index was not found in the registry.
+ *
+ * @param string $index
+ * @return boolean
+ */
+ public static function isRegistered($index)
+ {
+ if (self::$_registry === null) {
+ return false;
+ }
+ return self::$_registry->offsetExists($index);
+ }
+
+ /**
+ * @param string $index
+ * @returns mixed
+ *
+ * Workaround for http://bugs.php.net/bug.php?id=40442 (ZF-960).
+ */
+ public function offsetExists($index)
+ {
+ return array_key_exists($index, $this);
+ }
+
+}
diff --git a/site/vendors/phpQuery/Zend/Uri.php b/site/vendors/phpQuery/Zend/Uri.php
new file mode 100644
index 0000000..4c5776b
--- /dev/null
+++ b/site/vendors/phpQuery/Zend/Uri.php
@@ -0,0 +1,164 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Uri
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id: Uri.php 9656 2008-06-10 16:21:13Z dasprid $
+ */
+
+/**
+ * @see Zend_Loader
+ */
+require_once 'Zend/Loader.php';
+
+/**
+ * Abstract class for all Zend_Uri handlers
+ *
+ * @category Zend
+ * @package Zend_Uri
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+abstract class Zend_Uri
+{
+ /**
+ * Scheme of this URI (http, ftp, etc.)
+ *
+ * @var string
+ */
+ protected $_scheme = '';
+
+ /**
+ * Return a string representation of this URI.
+ *
+ * @see getUri()
+ * @return string
+ */
+ public function __toString()
+ {
+ return $this->getUri();
+ }
+
+ /**
+ * Convenience function, checks that a $uri string is well-formed
+ * by validating it but not returning an object. Returns TRUE if
+ * $uri is a well-formed URI, or FALSE otherwise.
+ *
+ * @param string $uri The URI to check
+ * @return boolean
+ */
+ public static function check($uri)
+ {
+ try {
+ $uri = self::factory($uri);
+ } catch (Exception $e) {
+ return false;
+ }
+
+ return $uri->valid();
+ }
+
+ /**
+ * Create a new Zend_Uri object for a URI. If building a new URI, then $uri should contain
+ * only the scheme (http, ftp, etc). Otherwise, supply $uri with the complete URI.
+ *
+ * @param string $uri The URI form which a Zend_Uri instance is created
+ * @throws Zend_Uri_Exception When an empty string was supplied for the scheme
+ * @throws Zend_Uri_Exception When an illegal scheme is supplied
+ * @throws Zend_Uri_Exception When the scheme is not supported
+ * @return Zend_Uri
+ * @link http://www.faqs.org/rfcs/rfc2396.html
+ */
+ public static function factory($uri = 'http')
+ {
+ // Separate the scheme from the scheme-specific parts
+ $uri = explode(':', $uri, 2);
+ $scheme = strtolower($uri[0]);
+ $schemeSpecific = isset($uri[1]) === true ? $uri[1] : '';
+
+ if (strlen($scheme) === 0) {
+ require_once 'Zend/Uri/Exception.php';
+ throw new Zend_Uri_Exception('An empty string was supplied for the scheme');
+ }
+
+ // Security check: $scheme is used to load a class file, so only alphanumerics are allowed.
+ if (ctype_alnum($scheme) === false) {
+ require_once 'Zend/Uri/Exception.php';
+ throw new Zend_Uri_Exception('Illegal scheme supplied, only alphanumeric characters are permitted');
+ }
+
+ /**
+ * Create a new Zend_Uri object for the $uri. If a subclass of Zend_Uri exists for the
+ * scheme, return an instance of that class. Otherwise, a Zend_Uri_Exception is thrown.
+ */
+ switch ($scheme) {
+ case 'http':
+ // Break intentionally omitted
+ case 'https':
+ $className = 'Zend_Uri_Http';
+ break;
+
+ case 'mailto':
+ // TODO
+ default:
+ require_once 'Zend/Uri/Exception.php';
+ throw new Zend_Uri_Exception("Scheme \"$scheme\" is not supported");
+ break;
+ }
+
+ Zend_Loader::loadClass($className);
+ $schemeHandler = new $className($scheme, $schemeSpecific);
+
+ return $schemeHandler;
+ }
+
+ /**
+ * Get the URI's scheme
+ *
+ * @return string|false Scheme or false if no scheme is set.
+ */
+ public function getScheme()
+ {
+ if (empty($this->_scheme) === false) {
+ return $this->_scheme;
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Zend_Uri and its subclasses cannot be instantiated directly.
+ * Use Zend_Uri::factory() to return a new Zend_Uri object.
+ *
+ * @param string $scheme The scheme of the URI
+ * @param string $schemeSpecific The scheme-specific part of the URI
+ */
+ abstract protected function __construct($scheme, $schemeSpecific = '');
+
+ /**
+ * Return a string representation of this URI.
+ *
+ * @return string
+ */
+ abstract public function getUri();
+
+ /**
+ * Returns TRUE if this URI is valid, or FALSE otherwise.
+ *
+ * @return boolean
+ */
+ abstract public function valid();
+}
diff --git a/site/vendors/phpQuery/Zend/Uri/Exception.php b/site/vendors/phpQuery/Zend/Uri/Exception.php
new file mode 100644
index 0000000..d327f3c
--- /dev/null
+++ b/site/vendors/phpQuery/Zend/Uri/Exception.php
@@ -0,0 +1,37 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Uri
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id: Exception.php 9656 2008-06-10 16:21:13Z dasprid $
+ */
+
+/**
+ * @see Zend_Exception
+ */
+require_once 'Zend/Exception.php';
+
+/**
+ * Exceptions for Zend_Uri
+ *
+ * @category Zend
+ * @package Zend_Uri
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Uri_Exception extends Zend_Exception
+{
+}
diff --git a/site/vendors/phpQuery/Zend/Uri/Http.php b/site/vendors/phpQuery/Zend/Uri/Http.php
new file mode 100644
index 0000000..7cf5887
--- /dev/null
+++ b/site/vendors/phpQuery/Zend/Uri/Http.php
@@ -0,0 +1,702 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Uri
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id: Http.php 9656 2008-06-10 16:21:13Z dasprid $
+ */
+
+/**
+ * @see Zend_Uri
+ */
+require_once 'Zend/Uri.php';
+
+/**
+ * @see Zend_Validate_Hostname
+ */
+require_once 'Zend/Validate/Hostname.php';
+
+/**
+ * HTTP(S) URI handler
+ *
+ * @category Zend
+ * @package Zend_Uri
+ * @uses Zend_Uri
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Uri_Http extends Zend_Uri
+{
+ /**
+ * HTTP username
+ *
+ * @var string
+ */
+ protected $_username = '';
+
+ /**
+ * HTTP password
+ *
+ * @var string
+ */
+ protected $_password = '';
+
+ /**
+ * HTTP host
+ *
+ * @var string
+ */
+ protected $_host = '';
+
+ /**
+ * HTTP post
+ *
+ * @var string
+ */
+ protected $_port = '';
+
+ /**
+ * HTTP part
+ *
+ * @var string
+ */
+ protected $_path = '';
+
+ /**
+ * HTTP query
+ *
+ * @var string
+ */
+ protected $_query = '';
+
+ /**
+ * HTTP fragment
+ *
+ * @var string
+ */
+ protected $_fragment = '';
+
+ /**
+ * Regular expression grammar rules for validation; values added by constructor
+ *
+ * @var array
+ */
+ protected $_regex = array();
+
+ /**
+ * Constructor accepts a string $scheme (e.g., http, https) and a scheme-specific part of the URI
+ * (e.g., example.com/path/to/resource?query=param#fragment)
+ *
+ * @param string $scheme The scheme of the URI
+ * @param string $schemeSpecific The scheme-specific part of the URI
+ * @throws Zend_Uri_Exception When the URI is not valid
+ */
+ protected function __construct($scheme, $schemeSpecific = '')
+ {
+ // Set the scheme
+ $this->_scheme = $scheme;
+
+ // Set up grammar rules for validation via regular expressions. These
+ // are to be used with slash-delimited regular expression strings.
+ $this->_regex['alphanum'] = '[^\W_]';
+ $this->_regex['escaped'] = '(?:%[\da-fA-F]{2})';
+ $this->_regex['mark'] = '[-_.!~*\'()\[\]]';
+ $this->_regex['reserved'] = '[;\/?:@&=+$,]';
+ $this->_regex['unreserved'] = '(?:' . $this->_regex['alphanum'] . '|' . $this->_regex['mark'] . ')';
+ $this->_regex['segment'] = '(?:(?:' . $this->_regex['unreserved'] . '|' . $this->_regex['escaped']
+ . '|[:@&=+$,;])*)';
+ $this->_regex['path'] = '(?:\/' . $this->_regex['segment'] . '?)+';
+ $this->_regex['uric'] = '(?:' . $this->_regex['reserved'] . '|' . $this->_regex['unreserved'] . '|'
+ . $this->_regex['escaped'] . ')';
+ // If no scheme-specific part was supplied, the user intends to create
+ // a new URI with this object. No further parsing is required.
+ if (strlen($schemeSpecific) === 0) {
+ return;
+ }
+
+ // Parse the scheme-specific URI parts into the instance variables.
+ $this->_parseUri($schemeSpecific);
+
+ // Validate the URI
+ if ($this->valid() === false) {
+ require_once 'Zend/Uri/Exception.php';
+ throw new Zend_Uri_Exception('Invalid URI supplied');
+ }
+ }
+
+ /**
+ * Creates a Zend_Uri_Http from the given string
+ *
+ * @param string $uri String to create URI from, must start with
+ * 'http://' or 'https://'
+ * @throws InvalidArgumentException When the given $uri is not a string or
+ * does not start with http:// or https://
+ * @throws Zend_Uri_Exception When the given $uri is invalid
+ * @return Zend_Uri_Http
+ */
+ public static function fromString($uri)
+ {
+ if (is_string($uri) === false) {
+ throw new InvalidArgumentException('$uri is not a string');
+ }
+
+ $uri = explode(':', $uri, 2);
+ $scheme = strtolower($uri[0]);
+ $schemeSpecific = isset($uri[1]) === true ? $uri[1] : '';
+
+ if (in_array($scheme, array('http', 'https')) === false) {
+ throw new Zend_Uri_Exception("Invalid scheme: '$scheme'");
+ }
+
+ $schemeHandler = new Zend_Uri_Http($scheme, $schemeSpecific);
+ return $schemeHandler;
+ }
+
+ /**
+ * Parse the scheme-specific portion of the URI and place its parts into instance variables.
+ *
+ * @param string $schemeSpecific The scheme-specific portion to parse
+ * @throws Zend_Uri_Exception When scheme-specific decoposition fails
+ * @throws Zend_Uri_Exception When authority decomposition fails
+ * @return void
+ */
+ protected function _parseUri($schemeSpecific)
+ {
+ // High-level decomposition parser
+ $pattern = '~^((//)([^/?#]*))([^?#]*)(\?([^#]*))?(#(.*))?$~';
+ $status = @preg_match($pattern, $schemeSpecific, $matches);
+ if ($status === false) {
+ require_once 'Zend/Uri/Exception.php';
+ throw new Zend_Uri_Exception('Internal error: scheme-specific decomposition failed');
+ }
+
+ // Failed decomposition; no further processing needed
+ if ($status === false) {
+ return;
+ }
+
+ // Save URI components that need no further decomposition
+ $this->_path = isset($matches[4]) === true ? $matches[4] : '';
+ $this->_query = isset($matches[6]) === true ? $matches[6] : '';
+ $this->_fragment = isset($matches[8]) === true ? $matches[8] : '';
+
+ // Additional decomposition to get username, password, host, and port
+ $combo = isset($matches[3]) === true ? $matches[3] : '';
+ $pattern = '~^(([^:@]*)(:([^@]*))?@)?([^:]+)(:(.*))?$~';
+ $status = @preg_match($pattern, $combo, $matches);
+ if ($status === false) {
+ require_once 'Zend/Uri/Exception.php';
+ throw new Zend_Uri_Exception('Internal error: authority decomposition failed');
+ }
+
+ // Failed decomposition; no further processing needed
+ if ($status === false) {
+ return;
+ }
+
+ // Save remaining URI components
+ $this->_username = isset($matches[2]) === true ? $matches[2] : '';
+ $this->_password = isset($matches[4]) === true ? $matches[4] : '';
+ $this->_host = isset($matches[5]) === true ? $matches[5] : '';
+ $this->_port = isset($matches[7]) === true ? $matches[7] : '';
+
+ }
+
+ /**
+ * Returns a URI based on current values of the instance variables. If any
+ * part of the URI does not pass validation, then an exception is thrown.
+ *
+ * @throws Zend_Uri_Exception When one or more parts of the URI are invalid
+ * @return string
+ */
+ public function getUri()
+ {
+ if ($this->valid() === false) {
+ require_once 'Zend/Uri/Exception.php';
+ throw new Zend_Uri_Exception('One or more parts of the URI are invalid');
+ }
+
+ $password = strlen($this->_password) > 0 ? ":$this->_password" : '';
+ $auth = strlen($this->_username) > 0 ? "$this->_username$password@" : '';
+ $port = strlen($this->_port) > 0 ? ":$this->_port" : '';
+ $query = strlen($this->_query) > 0 ? "?$this->_query" : '';
+ $fragment = strlen($this->_fragment) > 0 ? "#$this->_fragment" : '';
+
+ return $this->_scheme
+ . '://'
+ . $auth
+ . $this->_host
+ . $port
+ . $this->_path
+ . $query
+ . $fragment;
+ }
+
+ /**
+ * Validate the current URI from the instance variables. Returns true if and only if all
+ * parts pass validation.
+ *
+ * @return boolean
+ */
+ public function valid()
+ {
+ // Return true if and only if all parts of the URI have passed validation
+ return $this->validateUsername()
+ and $this->validatePassword()
+ and $this->validateHost()
+ and $this->validatePort()
+ and $this->validatePath()
+ and $this->validateQuery()
+ and $this->validateFragment();
+ }
+
+ /**
+ * Returns the username portion of the URL, or FALSE if none.
+ *
+ * @return string
+ */
+ public function getUsername()
+ {
+ return strlen($this->_username) > 0 ? $this->_username : false;
+ }
+
+ /**
+ * Returns true if and only if the username passes validation. If no username is passed,
+ * then the username contained in the instance variable is used.
+ *
+ * @param string $username The HTTP username
+ * @throws Zend_Uri_Exception When username validation fails
+ * @return boolean
+ * @link http://www.faqs.org/rfcs/rfc2396.html
+ */
+ public function validateUsername($username = null)
+ {
+ if ($username === null) {
+ $username = $this->_username;
+ }
+
+ // If the username is empty, then it is considered valid
+ if (strlen($username) === 0) {
+ return true;
+ }
+
+ // Check the username against the allowed values
+ $status = @preg_match('/^(' . $this->_regex['alphanum'] . '|' . $this->_regex['mark'] . '|'
+ . $this->_regex['escaped'] . '|[;:&=+$,])+$/', $username);
+ if ($status === false) {
+ require_once 'Zend/Uri/Exception.php';
+ throw new Zend_Uri_Exception('Internal error: username validation failed');
+ }
+
+ return $status === 1;
+ }
+
+ /**
+ * Sets the username for the current URI, and returns the old username
+ *
+ * @param string $username The HTTP username
+ * @throws Zend_Uri_Exception When $username is not a valid HTTP username
+ * @return string
+ */
+ public function setUsername($username)
+ {
+ if ($this->validateUsername($username) === false) {
+ require_once 'Zend/Uri/Exception.php';
+ throw new Zend_Uri_Exception("Username \"$username\" is not a valid HTTP username");
+ }
+
+ $oldUsername = $this->_username;
+ $this->_username = $username;
+
+ return $oldUsername;
+ }
+
+ /**
+ * Returns the password portion of the URL, or FALSE if none.
+ *
+ * @return string
+ */
+ public function getPassword()
+ {
+ return strlen($this->_password) > 0 ? $this->_password : false;
+ }
+
+ /**
+ * Returns true if and only if the password passes validation. If no password is passed,
+ * then the password contained in the instance variable is used.
+ *
+ * @param string $password The HTTP password
+ * @throws Zend_Uri_Exception When password validation fails
+ * @return boolean
+ * @link http://www.faqs.org/rfcs/rfc2396.html
+ */
+ public function validatePassword($password = null)
+ {
+ if ($password === null) {
+ $password = $this->_password;
+ }
+
+ // If the password is empty, then it is considered valid
+ if (strlen($password) === 0) {
+ return true;
+ }
+
+ // If the password is nonempty, but there is no username, then it is considered invalid
+ if (strlen($password) > 0 and strlen($this->_username) === 0) {
+ return false;
+ }
+
+ // Check the password against the allowed values
+ $status = @preg_match('/^(' . $this->_regex['alphanum'] . '|' . $this->_regex['mark'] . '|'
+ . $this->_regex['escaped'] . '|[;:&=+$,])+$/', $password);
+ if ($status === false) {
+ require_once 'Zend/Uri/Exception.php';
+ throw new Zend_Uri_Exception('Internal error: password validation failed.');
+ }
+
+ return $status == 1;
+ }
+
+ /**
+ * Sets the password for the current URI, and returns the old password
+ *
+ * @param string $password The HTTP password
+ * @throws Zend_Uri_Exception When $password is not a valid HTTP password
+ * @return string
+ */
+ public function setPassword($password)
+ {
+ if ($this->validatePassword($password) === false) {
+ require_once 'Zend/Uri/Exception.php';
+ throw new Zend_Uri_Exception("Password \"$password\" is not a valid HTTP password.");
+ }
+
+ $oldPassword = $this->_password;
+ $this->_password = $password;
+
+ return $oldPassword;
+ }
+
+ /**
+ * Returns the domain or host IP portion of the URL, or FALSE if none.
+ *
+ * @return string
+ */
+ public function getHost()
+ {
+ return strlen($this->_host) > 0 ? $this->_host : false;
+ }
+
+ /**
+ * Returns true if and only if the host string passes validation. If no host is passed,
+ * then the host contained in the instance variable is used.
+ *
+ * @param string $host The HTTP host
+ * @return boolean
+ * @uses Zend_Filter
+ */
+ public function validateHost($host = null)
+ {
+ if ($host === null) {
+ $host = $this->_host;
+ }
+
+ // If the host is empty, then it is considered invalid
+ if (strlen($host) === 0) {
+ return false;
+ }
+
+ // Check the host against the allowed values; delegated to Zend_Filter.
+ $validate = new Zend_Validate_Hostname(Zend_Validate_Hostname::ALLOW_ALL);
+
+ return $validate->isValid($host);
+ }
+
+ /**
+ * Sets the host for the current URI, and returns the old host
+ *
+ * @param string $host The HTTP host
+ * @throws Zend_Uri_Exception When $host is nota valid HTTP host
+ * @return string
+ */
+ public function setHost($host)
+ {
+ if ($this->validateHost($host) === false) {
+ require_once 'Zend/Uri/Exception.php';
+ throw new Zend_Uri_Exception("Host \"$host\" is not a valid HTTP host");
+ }
+
+ $oldHost = $this->_host;
+ $this->_host = $host;
+
+ return $oldHost;
+ }
+
+ /**
+ * Returns the TCP port, or FALSE if none.
+ *
+ * @return string
+ */
+ public function getPort()
+ {
+ return strlen($this->_port) > 0 ? $this->_port : false;
+ }
+
+ /**
+ * Returns true if and only if the TCP port string passes validation. If no port is passed,
+ * then the port contained in the instance variable is used.
+ *
+ * @param string $port The HTTP port
+ * @return boolean
+ */
+ public function validatePort($port = null)
+ {
+ if ($port === null) {
+ $port = $this->_port;
+ }
+
+ // If the port is empty, then it is considered valid
+ if (strlen($port) === 0) {
+ return true;
+ }
+
+ // Check the port against the allowed values
+ return ctype_digit((string) $port) and 1 <= $port and $port <= 65535;
+ }
+
+ /**
+ * Sets the port for the current URI, and returns the old port
+ *
+ * @param string $port The HTTP port
+ * @throws Zend_Uri_Exception When $port is not a valid HTTP port
+ * @return string
+ */
+ public function setPort($port)
+ {
+ if ($this->validatePort($port) === false) {
+ require_once 'Zend/Uri/Exception.php';
+ throw new Zend_Uri_Exception("Port \"$port\" is not a valid HTTP port.");
+ }
+
+ $oldPort = $this->_port;
+ $this->_port = $port;
+
+ return $oldPort;
+ }
+
+ /**
+ * Returns the path and filename portion of the URL, or FALSE if none.
+ *
+ * @return string
+ */
+ public function getPath()
+ {
+ return strlen($this->_path) > 0 ? $this->_path : '/';
+ }
+
+ /**
+ * Returns true if and only if the path string passes validation. If no path is passed,
+ * then the path contained in the instance variable is used.
+ *
+ * @param string $path The HTTP path
+ * @throws Zend_Uri_Exception When path validation fails
+ * @return boolean
+ */
+ public function validatePath($path = null)
+ {
+ if ($path === null) {
+ $path = $this->_path;
+ }
+
+ // If the path is empty, then it is considered valid
+ if (strlen($path) === 0) {
+ return true;
+ }
+
+ // Determine whether the path is well-formed
+ $pattern = '/^' . $this->_regex['path'] . '$/';
+ $status = @preg_match($pattern, $path);
+ if ($status === false) {
+ require_once 'Zend/Uri/Exception.php';
+ throw new Zend_Uri_Exception('Internal error: path validation failed');
+ }
+
+ return (boolean) $status;
+ }
+
+ /**
+ * Sets the path for the current URI, and returns the old path
+ *
+ * @param string $path The HTTP path
+ * @throws Zend_Uri_Exception When $path is not a valid HTTP path
+ * @return string
+ */
+ public function setPath($path)
+ {
+ if ($this->validatePath($path) === false) {
+ require_once 'Zend/Uri/Exception.php';
+ throw new Zend_Uri_Exception("Path \"$path\" is not a valid HTTP path");
+ }
+
+ $oldPath = $this->_path;
+ $this->_path = $path;
+
+ return $oldPath;
+ }
+
+ /**
+ * Returns the query portion of the URL (after ?), or FALSE if none.
+ *
+ * @return string
+ */
+ public function getQuery()
+ {
+ return strlen($this->_query) > 0 ? $this->_query : false;
+ }
+
+ /**
+ * Returns true if and only if the query string passes validation. If no query is passed,
+ * then the query string contained in the instance variable is used.
+ *
+ * @param string $query The query to validate
+ * @throws Zend_Uri_Exception When query validation fails
+ * @return boolean
+ * @link http://www.faqs.org/rfcs/rfc2396.html
+ */
+ public function validateQuery($query = null)
+ {
+ if ($query === null) {
+ $query = $this->_query;
+ }
+
+ // If query is empty, it is considered to be valid
+ if (strlen($query) === 0) {
+ return true;
+ }
+
+ // Determine whether the query is well-formed
+ $pattern = '/^' . $this->_regex['uric'] . '*$/';
+ $status = @preg_match($pattern, $query);
+ if ($status === false) {
+ require_once 'Zend/Uri/Exception.php';
+ throw new Zend_Uri_Exception('Internal error: query validation failed');
+ }
+
+ return $status == 1;
+ }
+
+ /**
+ * Set the query string for the current URI, and return the old query
+ * string This method accepts both strings and arrays.
+ *
+ * @param string|array $query The query string or array
+ * @throws Zend_Uri_Exception When $query is not a valid query string
+ * @return string Old query string
+ */
+ public function setQuery($query)
+ {
+ $oldQuery = $this->_query;
+
+ // If query is empty, set an empty string
+ if (empty($query) === true) {
+ $this->_query = '';
+ return $oldQuery;
+ }
+
+ // If query is an array, make a string out of it
+ if (is_array($query) === true) {
+ $query = http_build_query($query, '', '&');
+ } else {
+ // If it is a string, make sure it is valid. If not parse and encode it
+ $query = (string) $query;
+ if ($this->validateQuery($query) === false) {
+ parse_str($query, $queryArray);
+ $query = http_build_query($queryArray, '', '&');
+ }
+ }
+
+ // Make sure the query is valid, and set it
+ if ($this->validateQuery($query) === false) {
+ require_once 'Zend/Uri/Exception.php';
+ throw new Zend_Uri_Exception("'$query' is not a valid query string");
+ }
+
+ $this->_query = $query;
+
+ return $oldQuery;
+ }
+
+ /**
+ * Returns the fragment portion of the URL (after #), or FALSE if none.
+ *
+ * @return string|false
+ */
+ public function getFragment()
+ {
+ return strlen($this->_fragment) > 0 ? $this->_fragment : false;
+ }
+
+ /**
+ * Returns true if and only if the fragment passes validation. If no fragment is passed,
+ * then the fragment contained in the instance variable is used.
+ *
+ * @param string $fragment Fragment of an URI
+ * @throws Zend_Uri_Exception When fragment validation fails
+ * @return boolean
+ * @link http://www.faqs.org/rfcs/rfc2396.html
+ */
+ public function validateFragment($fragment = null)
+ {
+ if ($fragment === null) {
+ $fragment = $this->_fragment;
+ }
+
+ // If fragment is empty, it is considered to be valid
+ if (strlen($fragment) === 0) {
+ return true;
+ }
+
+ // Determine whether the fragment is well-formed
+ $pattern = '/^' . $this->_regex['uric'] . '*$/';
+ $status = @preg_match($pattern, $fragment);
+ if ($status === false) {
+ require_once 'Zend/Uri/Exception.php';
+ throw new Zend_Uri_Exception('Internal error: fragment validation failed');
+ }
+
+ return (boolean) $status;
+ }
+
+ /**
+ * Sets the fragment for the current URI, and returns the old fragment
+ *
+ * @param string $fragment Fragment of the current URI
+ * @throws Zend_Uri_Exception When $fragment is not a valid HTTP fragment
+ * @return string
+ */
+ public function setFragment($fragment)
+ {
+ if ($this->validateFragment($fragment) === false) {
+ require_once 'Zend/Uri/Exception.php';
+ throw new Zend_Uri_Exception("Fragment \"$fragment\" is not a valid HTTP fragment");
+ }
+
+ $oldFragment = $this->_fragment;
+ $this->_fragment = $fragment;
+
+ return $oldFragment;
+ }
+}
diff --git a/site/vendors/phpQuery/Zend/Validate/Abstract.php b/site/vendors/phpQuery/Zend/Validate/Abstract.php
new file mode 100644
index 0000000..1c11d54
--- /dev/null
+++ b/site/vendors/phpQuery/Zend/Validate/Abstract.php
@@ -0,0 +1,348 @@
+<?php
+
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Validate
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id: Abstract.php 10648 2008-08-04 20:58:06Z matthew $
+ */
+
+
+/**
+ * @see Zend_Validate_Interface
+ */
+require_once 'Zend/Validate/Interface.php';
+
+
+/**
+ * @category Zend
+ * @package Zend_Validate
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+abstract class Zend_Validate_Abstract implements Zend_Validate_Interface
+{
+ /**
+ * The value to be validated
+ *
+ * @var mixed
+ */
+ protected $_value;
+
+ /**
+ * Additional variables available for validation failure messages
+ *
+ * @var array
+ */
+ protected $_messageVariables = array();
+
+ /**
+ * Validation failure message template definitions
+ *
+ * @var array
+ */
+ protected $_messageTemplates = array();
+
+ /**
+ * Array of validation failure messages
+ *
+ * @var array
+ */
+ protected $_messages = array();
+
+ /**
+ * Flag indidcating whether or not value should be obfuscated in error
+ * messages
+ * @var bool
+ */
+ protected $_obscureValue = false;
+
+ /**
+ * Array of validation failure message codes
+ *
+ * @var array
+ * @deprecated Since 1.5.0
+ */
+ protected $_errors = array();
+
+ /**
+ * Translation object
+ * @var Zend_Translate
+ */
+ protected $_translator;
+
+ /**
+ * Default translation object for all validate objects
+ * @var Zend_Translate
+ */
+ protected static $_defaultTranslator;
+
+ /**
+ * Returns array of validation failure messages
+ *
+ * @return array
+ */
+ public function getMessages()
+ {
+ return $this->_messages;
+ }
+
+ /**
+ * Returns an array of the names of variables that are used in constructing validation failure messages
+ *
+ * @return array
+ */
+ public function getMessageVariables()
+ {
+ return array_keys($this->_messageVariables);
+ }
+
+ /**
+ * Sets the validation failure message template for a particular key
+ *
+ * @param string $messageString
+ * @param string $messageKey OPTIONAL
+ * @return Zend_Validate_Abstract Provides a fluent interface
+ * @throws Zend_Validate_Exception
+ */
+ public function setMessage($messageString, $messageKey = null)
+ {
+ if ($messageKey === null) {
+ $keys = array_keys($this->_messageTemplates);
+ $messageKey = current($keys);
+ }
+ if (!isset($this->_messageTemplates[$messageKey])) {
+ require_once 'Zend/Validate/Exception.php';
+ throw new Zend_Validate_Exception("No message template exists for key '$messageKey'");
+ }
+ $this->_messageTemplates[$messageKey] = $messageString;
+ return $this;
+ }
+
+ /**
+ * Sets validation failure message templates given as an array, where the array keys are the message keys,
+ * and the array values are the message template strings.
+ *
+ * @param array $messages
+ * @return Zend_Validate_Abstract
+ */
+ public function setMessages(array $messages)
+ {
+ foreach ($messages as $key => $message) {
+ $this->setMessage($message, $key);
+ }
+ return $this;
+ }
+
+ /**
+ * Magic function returns the value of the requested property, if and only if it is the value or a
+ * message variable.
+ *
+ * @param string $property
+ * @return mixed
+ * @throws Zend_Validate_Exception
+ */
+ public function __get($property)
+ {
+ if ($property == 'value') {
+ return $this->_value;
+ }
+ if (array_key_exists($property, $this->_messageVariables)) {
+ return $this->{$this->_messageVariables[$property]};
+ }
+ /**
+ * @see Zend_Validate_Exception
+ */
+ require_once 'Zend/Validate/Exception.php';
+ throw new Zend_Validate_Exception("No property exists by the name '$property'");
+ }
+
+ /**
+ * Constructs and returns a validation failure message with the given message key and value.
+ *
+ * Returns null if and only if $messageKey does not correspond to an existing template.
+ *
+ * If a translator is available and a translation exists for $messageKey,
+ * the translation will be used.
+ *
+ * @param string $messageKey
+ * @param string $value
+ * @return string
+ */
+ protected function _createMessage($messageKey, $value)
+ {
+ if (!isset($this->_messageTemplates[$messageKey])) {
+ return null;
+ }
+
+ $message = $this->_messageTemplates[$messageKey];
+
+ if (null !== ($translator = $this->getTranslator())) {
+ if ($translator->isTranslated($message)) {
+ $message = $translator->translate($message);
+ } elseif ($translator->isTranslated($messageKey)) {
+ $message = $translator->translate($messageKey);
+ }
+ }
+
+ if ($this->getObscureValue()) {
+ $value = str_repeat('*', strlen($value));
+ }
+
+ $message = str_replace('%value%', (string) $value, $message);
+ foreach ($this->_messageVariables as $ident => $property) {
+ $message = str_replace("%$ident%", $this->$property, $message);
+ }
+ return $message;
+ }
+
+ /**
+ * @param string $messageKey OPTIONAL
+ * @param string $value OPTIONAL
+ * @return void
+ */
+ protected function _error($messageKey = null, $value = null)
+ {
+ if ($messageKey === null) {
+ $keys = array_keys($this->_messageTemplates);
+ $messageKey = current($keys);
+ }
+ if ($value === null) {
+ $value = $this->_value;
+ }
+ $this->_errors[] = $messageKey;
+ $this->_messages[$messageKey] = $this->_createMessage($messageKey, $value);
+ }
+
+ /**
+ * Sets the value to be validated and clears the messages and errors arrays
+ *
+ * @param mixed $value
+ * @return void
+ */
+ protected function _setValue($value)
+ {
+ $this->_value = $value;
+ $this->_messages = array();
+ $this->_errors = array();
+ }
+
+ /**
+ * Returns array of validation failure message codes
+ *
+ * @return array
+ * @deprecated Since 1.5.0
+ */
+ public function getErrors()
+ {
+ return $this->_errors;
+ }
+
+ /**
+ * Set flag indicating whether or not value should be obfuscated in messages
+ *
+ * @param bool $flag
+ * @return Zend_Validate_Abstract
+ */
+ public function setObscureValue($flag)
+ {
+ $this->_obscureValue = (bool) $flag;
+ return $this;
+ }
+
+ /**
+ * Retrieve flag indicating whether or not value should be obfuscated in
+ * messages
+ *
+ * @return bool
+ */
+ public function getObscureValue()
+ {
+ return $this->_obscureValue;
+ }
+
+ /**
+ * Set translation object
+ *
+ * @param Zend_Translate|Zend_Translate_Adapter|null $translator
+ * @return Zend_Validate_Abstract
+ */
+ public function setTranslator($translator = null)
+ {
+ if ((null === $translator) || ($translator instanceof Zend_Translate_Adapter)) {
+ $this->_translator = $translator;
+ } elseif ($translator instanceof Zend_Translate) {
+ $this->_translator = $translator->getAdapter();
+ } else {
+ require_once 'Zend/Validate/Exception.php';
+ throw new Zend_Validate_Exception('Invalid translator specified');
+ }
+ return $this;
+ }
+
+ /**
+ * Return translation object
+ *
+ * @return Zend_Translate_Adapter|null
+ */
+ public function getTranslator()
+ {
+ if (null === $this->_translator) {
+ return self::getDefaultTranslator();
+ }
+
+ return $this->_translator;
+ }
+
+ /**
+ * Set default translation object for all validate objects
+ *
+ * @param Zend_Translate|Zend_Translate_Adapter|null $translator
+ * @return void
+ */
+ public static function setDefaultTranslator($translator = null)
+ {
+ if ((null === $translator) || ($translator instanceof Zend_Translate_Adapter)) {
+ self::$_defaultTranslator = $translator;
+ } elseif ($translator instanceof Zend_Translate) {
+ self::$_defaultTranslator = $translator->getAdapter();
+ } else {
+ require_once 'Zend/Validate/Exception.php';
+ throw new Zend_Validate_Exception('Invalid translator specified');
+ }
+ }
+
+ /**
+ * Get default translation object for all validate objects
+ *
+ * @return Zend_Translate_Adapter|null
+ */
+ public static function getDefaultTranslator()
+ {
+ if (null === self::$_defaultTranslator) {
+ require_once 'Zend/Registry.php';
+ if (Zend_Registry::isRegistered('Zend_Translate')) {
+ $translator = Zend_Registry::get('Zend_Translate');
+ if ($translator instanceof Zend_Translate_Adapter) {
+ return $translator;
+ } elseif ($translator instanceof Zend_Translate) {
+ return $translator->getAdapter();
+ }
+ }
+ }
+ return self::$_defaultTranslator;
+ }
+}
diff --git a/site/vendors/phpQuery/Zend/Validate/Alnum.php b/site/vendors/phpQuery/Zend/Validate/Alnum.php
new file mode 100644
index 0000000..36b0adc
--- /dev/null
+++ b/site/vendors/phpQuery/Zend/Validate/Alnum.php
@@ -0,0 +1,120 @@
+<?php
+
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Validate
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id: Alnum.php 8064 2008-02-16 10:58:39Z thomas $
+ */
+
+
+/**
+ * @see Zend_Validate_Abstract
+ */
+require_once 'Zend/Validate/Abstract.php';
+
+
+/**
+ * @category Zend
+ * @package Zend_Validate
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Validate_Alnum extends Zend_Validate_Abstract
+{
+ /**
+ * Validation failure message key for when the value contains non-alphabetic or non-digit characters
+ */
+ const NOT_ALNUM = 'notAlnum';
+
+ /**
+ * Validation failure message key for when the value is an empty string
+ */
+ const STRING_EMPTY = 'stringEmpty';
+
+ /**
+ * Whether to allow white space characters; off by default
+ *
+ * @var boolean
+ */
+ public $allowWhiteSpace;
+
+ /**
+ * Alphanumeric filter used for validation
+ *
+ * @var Zend_Filter_Alnum
+ */
+ protected static $_filter = null;
+
+ /**
+ * Validation failure message template definitions
+ *
+ * @var array
+ */
+ protected $_messageTemplates = array(
+ self::NOT_ALNUM => "'%value%' has not only alphabetic and digit characters",
+ self::STRING_EMPTY => "'%value%' is an empty string"
+ );
+
+ /**
+ * Sets default option values for this instance
+ *
+ * @param boolean $allowWhiteSpace
+ * @return void
+ */
+ public function __construct($allowWhiteSpace = false)
+ {
+ $this->allowWhiteSpace = (boolean) $allowWhiteSpace;
+ }
+
+ /**
+ * Defined by Zend_Validate_Interface
+ *
+ * Returns true if and only if $value contains only alphabetic and digit characters
+ *
+ * @param string $value
+ * @return boolean
+ */
+ public function isValid($value)
+ {
+ $valueString = (string) $value;
+
+ $this->_setValue($valueString);
+
+ if ('' === $valueString) {
+ $this->_error(self::STRING_EMPTY);
+ return false;
+ }
+
+ if (null === self::$_filter) {
+ /**
+ * @see Zend_Filter_Alnum
+ */
+ require_once 'Zend/Filter/Alnum.php';
+ self::$_filter = new Zend_Filter_Alnum();
+ }
+
+ self::$_filter->allowWhiteSpace = $this->allowWhiteSpace;
+
+ if ($valueString !== self::$_filter->filter($valueString)) {
+ $this->_error(self::NOT_ALNUM);
+ return false;
+ }
+
+ return true;
+ }
+
+}
diff --git a/site/vendors/phpQuery/Zend/Validate/Alpha.php b/site/vendors/phpQuery/Zend/Validate/Alpha.php
new file mode 100644
index 0000000..0f2298e
--- /dev/null
+++ b/site/vendors/phpQuery/Zend/Validate/Alpha.php
@@ -0,0 +1,120 @@
+<?php
+
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Validate
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id: Alpha.php 8064 2008-02-16 10:58:39Z thomas $
+ */
+
+
+/**
+ * @see Zend_Validate_Abstract
+ */
+require_once 'Zend/Validate/Abstract.php';
+
+
+/**
+ * @category Zend
+ * @package Zend_Validate
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Validate_Alpha extends Zend_Validate_Abstract
+{
+ /**
+ * Validation failure message key for when the value contains non-alphabetic characters
+ */
+ const NOT_ALPHA = 'notAlpha';
+
+ /**
+ * Validation failure message key for when the value is an empty string
+ */
+ const STRING_EMPTY = 'stringEmpty';
+
+ /**
+ * Whether to allow white space characters; off by default
+ *
+ * @var boolean
+ */
+ public $allowWhiteSpace;
+
+ /**
+ * Alphabetic filter used for validation
+ *
+ * @var Zend_Filter_Alpha
+ */
+ protected static $_filter = null;
+
+ /**
+ * Validation failure message template definitions
+ *
+ * @var array
+ */
+ protected $_messageTemplates = array(
+ self::NOT_ALPHA => "'%value%' has not only alphabetic characters",
+ self::STRING_EMPTY => "'%value%' is an empty string"
+ );
+
+ /**
+ * Sets default option values for this instance
+ *
+ * @param boolean $allowWhiteSpace
+ * @return void
+ */
+ public function __construct($allowWhiteSpace = false)
+ {
+ $this->allowWhiteSpace = (boolean) $allowWhiteSpace;
+ }
+
+ /**
+ * Defined by Zend_Validate_Interface
+ *
+ * Returns true if and only if $value contains only alphabetic characters
+ *
+ * @param string $value
+ * @return boolean
+ */
+ public function isValid($value)
+ {
+ $valueString = (string) $value;
+
+ $this->_setValue($valueString);
+
+ if ('' === $valueString) {
+ $this->_error(self::STRING_EMPTY);
+ return false;
+ }
+
+ if (null === self::$_filter) {
+ /**
+ * @see Zend_Filter_Alpha
+ */
+ require_once 'Zend/Filter/Alpha.php';
+ self::$_filter = new Zend_Filter_Alpha();
+ }
+
+ self::$_filter->allowWhiteSpace = $this->allowWhiteSpace;
+
+ if ($valueString !== self::$_filter->filter($valueString)) {
+ $this->_error(self::NOT_ALPHA);
+ return false;
+ }
+
+ return true;
+ }
+
+}
diff --git a/site/vendors/phpQuery/Zend/Validate/Barcode.php b/site/vendors/phpQuery/Zend/Validate/Barcode.php
new file mode 100644
index 0000000..d51f11b
--- /dev/null
+++ b/site/vendors/phpQuery/Zend/Validate/Barcode.php
@@ -0,0 +1,99 @@
+<?php
+
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Validate
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id: Barcode.php 8211 2008-02-20 14:29:24Z darby $
+ */
+
+
+/**
+ * @see Zend_Validate_Abstract
+ */
+require_once 'Zend/Validate/Abstract.php';
+
+
+/**
+ * @category Zend
+ * @package Zend_Validate
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Validate_Barcode extends Zend_Validate_Abstract
+{
+ /**
+ * Barcode validator
+ *
+ * @var Zend_Validate_Abstract
+ */
+ protected $_barcodeValidator;
+
+ /**
+ * Generates the standard validator object
+ *
+ * @param string $barcodeType - Barcode validator to use
+ * @return void
+ * @throws Zend_Validate_Exception
+ */
+ public function __construct($barcodeType)
+ {
+ $this->setType($barcodeType);
+ }
+
+ /**
+ * Sets a new barcode validator
+ *
+ * @param string $barcodeType - Barcode validator to use
+ * @return void
+ * @throws Zend_Validate_Exception
+ */
+ public function setType($barcodeType)
+ {
+ switch (strtolower($barcodeType)) {
+ case 'upc':
+ case 'upc-a':
+ $className = 'UpcA';
+ break;
+ case 'ean13':
+ case 'ean-13':
+ $className = 'Ean13';
+ break;
+ default:
+ require_once 'Zend/Validate/Exception.php';
+ throw new Zend_Validate_Exception("Barcode type '$barcodeType' is not supported'");
+ break;
+ }
+
+ require_once 'Zend/Validate/Barcode/' . $className . '.php';
+
+ $class = 'Zend_Validate_Barcode_' . $className;
+ $this->_barcodeValidator = new $class;
+ }
+
+ /**
+ * Defined by Zend_Validate_Interface
+ *
+ * Returns true if and only if $value contains a valid barcode
+ *
+ * @param string $value
+ * @return boolean
+ */
+ public function isValid($value)
+ {
+ return call_user_func(array($this->_barcodeValidator, 'isValid'), $value);
+ }
+}
diff --git a/site/vendors/phpQuery/Zend/Validate/Barcode/Ean13.php b/site/vendors/phpQuery/Zend/Validate/Barcode/Ean13.php
new file mode 100644
index 0000000..7be797d
--- /dev/null
+++ b/site/vendors/phpQuery/Zend/Validate/Barcode/Ean13.php
@@ -0,0 +1,100 @@
+<?php
+
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Validate
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id: Ean13.php 8210 2008-02-20 14:09:05Z andries $
+ */
+
+
+/**
+ * @see Zend_Validate_Abstract
+ */
+require_once 'Zend/Validate/Abstract.php';
+
+
+/**
+ * @category Zend
+ * @package Zend_Validate
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Validate_Barcode_Ean13 extends Zend_Validate_Abstract
+{
+ /**
+ * Validation failure message key for when the value is
+ * an invalid barcode
+ */
+ const INVALID = 'invalid';
+
+ /**
+ * Validation failure message key for when the value is
+ * not 13 characters long
+ */
+ const INVALID_LENGTH = 'invalidLength';
+
+ /**
+ * Validation failure message template definitions
+ *
+ * @var array
+ */
+ protected $_messageTemplates = array(
+ self::INVALID => "'%value%' is an invalid EAN-13 barcode",
+ self::INVALID_LENGTH => "'%value%' should be 13 characters",
+ );
+
+ /**
+ * Defined by Zend_Validate_Interface
+ *
+ * Returns true if and only if $value contains a valid barcode
+ *
+ * @param string $value
+ * @return boolean
+ */
+ public function isValid($value)
+ {
+ $valueString = (string) $value;
+ $this->_setValue($valueString);
+
+ if (strlen($valueString) !== 13) {
+ $this->_error(self::INVALID_LENGTH);
+ return false;
+ }
+
+ $barcode = strrev(substr($valueString, 0, -1));
+ $oddSum = 0;
+ $evenSum = 0;
+
+ for ($i = 0; $i < 12; $i++) {
+ if ($i % 2 === 0) {
+ $oddSum += $barcode[$i] * 3;
+ } elseif ($i % 2 === 1) {
+ $evenSum += $barcode[$i];
+ }
+ }
+
+ $calculation = ($oddSum + $evenSum) % 10;
+ $checksum = ($calculation === 0) ? 0 : 10 - $calculation;
+
+ if ($valueString[12] != $checksum) {
+ $this->_error(self::INVALID);
+ return false;
+ }
+
+ return true;
+ }
+}
diff --git a/site/vendors/phpQuery/Zend/Validate/Barcode/UpcA.php b/site/vendors/phpQuery/Zend/Validate/Barcode/UpcA.php
new file mode 100644
index 0000000..c584e81
--- /dev/null
+++ b/site/vendors/phpQuery/Zend/Validate/Barcode/UpcA.php
@@ -0,0 +1,100 @@
+<?php
+
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Validate
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id: UpcA.php 8210 2008-02-20 14:09:05Z andries $
+ */
+
+
+/**
+ * @see Zend_Validate_Abstract
+ */
+require_once 'Zend/Validate/Abstract.php';
+
+
+/**
+ * @category Zend
+ * @package Zend_Validate
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Validate_Barcode_UpcA extends Zend_Validate_Abstract
+{
+ /**
+ * Validation failure message key for when the value is
+ * an invalid barcode
+ */
+ const INVALID = 'invalid';
+
+ /**
+ * Validation failure message key for when the value is
+ * not 12 characters long
+ */
+ const INVALID_LENGTH = 'invalidLength';
+
+ /**
+ * Validation failure message template definitions
+ *
+ * @var array
+ */
+ protected $_messageTemplates = array(
+ self::INVALID => "'%value%' is an invalid UPC-A barcode",
+ self::INVALID_LENGTH => "'%value%' should be 12 characters",
+ );
+
+ /**
+ * Defined by Zend_Validate_Interface
+ *
+ * Returns true if and only if $value contains a valid barcode
+ *
+ * @param string $value
+ * @return boolean
+ */
+ public function isValid($value)
+ {
+ $valueString = (string) $value;
+ $this->_setValue($valueString);
+
+ if (strlen($valueString) !== 12) {
+ $this->_error(self::INVALID_LENGTH);
+ return false;
+ }
+
+ $barcode = substr($valueString, 0, -1);
+ $oddSum = 0;
+ $evenSum = 0;
+
+ for ($i = 0; $i < 11; $i++) {
+ if ($i % 2 === 0) {
+ $oddSum += $barcode[$i] * 3;
+ } elseif ($i % 2 === 1) {
+ $evenSum += $barcode[$i];
+ }
+ }
+
+ $calculation = ($oddSum + $evenSum) % 10;
+ $checksum = ($calculation === 0) ? 0 : 10 - $calculation;
+
+ if ($valueString[11] != $checksum) {
+ $this->_error(self::INVALID);
+ return false;
+ }
+
+ return true;
+ }
+}
diff --git a/site/vendors/phpQuery/Zend/Validate/Between.php b/site/vendors/phpQuery/Zend/Validate/Between.php
new file mode 100644
index 0000000..bb0b726
--- /dev/null
+++ b/site/vendors/phpQuery/Zend/Validate/Between.php
@@ -0,0 +1,200 @@
+<?php
+
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Validate
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id: Between.php 8064 2008-02-16 10:58:39Z thomas $
+ */
+
+
+/**
+ * @see Zend_Validate_Abstract
+ */
+require_once 'Zend/Validate/Abstract.php';
+
+
+/**
+ * @category Zend
+ * @package Zend_Validate
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Validate_Between extends Zend_Validate_Abstract
+{
+ /**
+ * Validation failure message key for when the value is not between the min and max, inclusively
+ */
+ const NOT_BETWEEN = 'notBetween';
+
+ /**
+ * Validation failure message key for when the value is not strictly between the min and max
+ */
+ const NOT_BETWEEN_STRICT = 'notBetweenStrict';
+
+ /**
+ * Validation failure message template definitions
+ *
+ * @var array
+ */
+ protected $_messageTemplates = array(
+ self::NOT_BETWEEN => "'%value%' is not between '%min%' and '%max%', inclusively",
+ self::NOT_BETWEEN_STRICT => "'%value%' is not strictly between '%min%' and '%max%'"
+ );
+
+ /**
+ * Additional variables available for validation failure messages
+ *
+ * @var array
+ */
+ protected $_messageVariables = array(
+ 'min' => '_min',
+ 'max' => '_max'
+ );
+
+ /**
+ * Minimum value
+ *
+ * @var mixed
+ */
+ protected $_min;
+
+ /**
+ * Maximum value
+ *
+ * @var mixed
+ */
+ protected $_max;
+
+ /**
+ * Whether to do inclusive comparisons, allowing equivalence to min and/or max
+ *
+ * If false, then strict comparisons are done, and the value may equal neither
+ * the min nor max options
+ *
+ * @var boolean
+ */
+ protected $_inclusive;
+
+ /**
+ * Sets validator options
+ *
+ * @param mixed $min
+ * @param mixed $max
+ * @param boolean $inclusive
+ * @return void
+ */
+ public function __construct($min, $max, $inclusive = true)
+ {
+ $this->setMin($min)
+ ->setMax($max)
+ ->setInclusive($inclusive);
+ }
+
+ /**
+ * Returns the min option
+ *
+ * @return mixed
+ */
+ public function getMin()
+ {
+ return $this->_min;
+ }
+
+ /**
+ * Sets the min option
+ *
+ * @param mixed $min
+ * @return Zend_Validate_Between Provides a fluent interface
+ */
+ public function setMin($min)
+ {
+ $this->_min = $min;
+ return $this;
+ }
+
+ /**
+ * Returns the max option
+ *
+ * @return mixed
+ */
+ public function getMax()
+ {
+ return $this->_max;
+ }
+
+ /**
+ * Sets the max option
+ *
+ * @param mixed $max
+ * @return Zend_Validate_Between Provides a fluent interface
+ */
+ public function setMax($max)
+ {
+ $this->_max = $max;
+ return $this;
+ }
+
+ /**
+ * Returns the inclusive option
+ *
+ * @return boolean
+ */
+ public function getInclusive()
+ {
+ return $this->_inclusive;
+ }
+
+ /**
+ * Sets the inclusive option
+ *
+ * @param boolean $inclusive
+ * @return Zend_Validate_Between Provides a fluent interface
+ */
+ public function setInclusive($inclusive)
+ {
+ $this->_inclusive = $inclusive;
+ return $this;
+ }
+
+ /**
+ * Defined by Zend_Validate_Interface
+ *
+ * Returns true if and only if $value is between min and max options, inclusively
+ * if inclusive option is true.
+ *
+ * @param mixed $value
+ * @return boolean
+ */
+ public function isValid($value)
+ {
+ $this->_setValue($value);
+
+ if ($this->_inclusive) {
+ if ($this->_min > $value || $value > $this->_max) {
+ $this->_error(self::NOT_BETWEEN);
+ return false;
+ }
+ } else {
+ if ($this->_min >= $value || $value >= $this->_max) {
+ $this->_error(self::NOT_BETWEEN_STRICT);
+ return false;
+ }
+ }
+ return true;
+ }
+
+}
diff --git a/site/vendors/phpQuery/Zend/Validate/Ccnum.php b/site/vendors/phpQuery/Zend/Validate/Ccnum.php
new file mode 100644
index 0000000..227a4ec
--- /dev/null
+++ b/site/vendors/phpQuery/Zend/Validate/Ccnum.php
@@ -0,0 +1,111 @@
+<?php
+
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Validate
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id: Ccnum.php 8064 2008-02-16 10:58:39Z thomas $
+ */
+
+
+/**
+ * @see Zend_Validate_Abstract
+ */
+require_once 'Zend/Validate/Abstract.php';
+
+
+/**
+ * @category Zend
+ * @package Zend_Validate
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Validate_Ccnum extends Zend_Validate_Abstract
+{
+ /**
+ * Validation failure message key for when the value is not of valid length
+ */
+ const LENGTH = 'ccnumLength';
+
+ /**
+ * Validation failure message key for when the value fails the mod-10 checksum
+ */
+ const CHECKSUM = 'ccnumChecksum';
+
+ /**
+ * Digits filter for input
+ *
+ * @var Zend_Filter_Digits
+ */
+ protected static $_filter = null;
+
+ /**
+ * Validation failure message template definitions
+ *
+ * @var array
+ */
+ protected $_messageTemplates = array(
+ self::LENGTH => "'%value%' must contain between 13 and 19 digits",
+ self::CHECKSUM => "Luhn algorithm (mod-10 checksum) failed on '%value%'"
+ );
+
+ /**
+ * Defined by Zend_Validate_Interface
+ *
+ * Returns true if and only if $value follows the Luhn algorithm (mod-10 checksum)
+ *
+ * @param string $value
+ * @return boolean
+ */
+ public function isValid($value)
+ {
+ $this->_setValue($value);
+
+ if (null === self::$_filter) {
+ /**
+ * @see Zend_Filter_Digits
+ */
+ require_once 'Zend/Filter/Digits.php';
+ self::$_filter = new Zend_Filter_Digits();
+ }
+
+ $valueFiltered = self::$_filter->filter($value);
+
+ $length = strlen($valueFiltered);
+
+ if ($length < 13 || $length > 19) {
+ $this->_error(self::LENGTH);
+ return false;
+ }
+
+ $sum = 0;
+ $weight = 2;
+
+ for ($i = $length - 2; $i >= 0; $i--) {
+ $digit = $weight * $valueFiltered[$i];
+ $sum += floor($digit / 10) + $digit % 10;
+ $weight = $weight % 2 + 1;
+ }
+
+ if ((10 - $sum % 10) % 10 != $valueFiltered[$length - 1]) {
+ $this->_error(self::CHECKSUM, $valueFiltered);
+ return false;
+ }
+
+ return true;
+ }
+
+}
diff --git a/site/vendors/phpQuery/Zend/Validate/Date.php b/site/vendors/phpQuery/Zend/Validate/Date.php
new file mode 100644
index 0000000..220b0ee
--- /dev/null
+++ b/site/vendors/phpQuery/Zend/Validate/Date.php
@@ -0,0 +1,250 @@
+<?php
+
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Validate
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id: Date.php 11046 2008-08-25 13:58:52Z thomas $
+ */
+
+
+/**
+ * @see Zend_Validate_Abstract
+ */
+require_once 'Zend/Validate/Abstract.php';
+
+
+/**
+ * @category Zend
+ * @package Zend_Validate
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Validate_Date extends Zend_Validate_Abstract
+{
+ /**
+ * Validation failure message key for when the value does not follow the YYYY-MM-DD format
+ */
+ const NOT_YYYY_MM_DD = 'dateNotYYYY-MM-DD';
+
+ /**
+ * Validation failure message key for when the value does not appear to be a valid date
+ */
+ const INVALID = 'dateInvalid';
+
+ /**
+ * Validation failure message key for when the value does not fit the given dateformat or locale
+ */
+ const FALSEFORMAT = 'dateFalseFormat';
+
+ /**
+ * Validation failure message template definitions
+ *
+ * @var array
+ */
+ protected $_messageTemplates = array(
+ self::NOT_YYYY_MM_DD => "'%value%' is not of the format YYYY-MM-DD",
+ self::INVALID => "'%value%' does not appear to be a valid date",
+ self::FALSEFORMAT => "'%value%' does not fit given date format"
+ );
+
+ /**
+ * Optional format
+ *
+ * @var string|null
+ */
+ protected $_format;
+
+ /**
+ * Optional locale
+ *
+ * @var string|Zend_Locale|null
+ */
+ protected $_locale;
+
+ /**
+ * Sets validator options
+ *
+ * @param string $format OPTIONAL
+ * @param string|Zend_Locale $locale OPTIONAL
+ * @return void
+ */
+ public function __construct($format = null, $locale = null)
+ {
+ $this->setFormat($format);
+ $this->setLocale($locale);
+ }
+
+ /**
+ * Returns the locale option
+ *
+ * @return string|Zend_Locale|null
+ */
+ public function getLocale()
+ {
+ return $this->_locale;
+ }
+
+ /**
+ * Sets the locale option
+ *
+ * @param string|Zend_Locale $locale
+ * @return Zend_Validate_Date provides a fluent interface
+ */
+ public function setLocale($locale = null)
+ {
+ if ($locale === null) {
+ $this->_locale = null;
+ return $this;
+ }
+
+ require_once 'Zend/Locale.php';
+ if (!Zend_Locale::isLocale($locale, true)) {
+ if (!Zend_Locale::isLocale($locale, false)) {
+ require_once 'Zend/Validate/Exception.php';
+ throw new Zend_Validate_Exception("The locale '$locale' is no known locale");
+ }
+
+ $locale = new Zend_Locale($locale);
+ }
+
+ $this->_locale = (string) $locale;
+ return $this;
+ }
+
+ /**
+ * Returns the locale option
+ *
+ * @return string|null
+ */
+ public function getFormat()
+ {
+ return $this->_format;
+ }
+
+ /**
+ * Sets the format option
+ *
+ * @param string $format
+ * @return Zend_Validate_Date provides a fluent interface
+ */
+ public function setFormat($format = null)
+ {
+ $this->_format = $format;
+ return $this;
+ }
+
+ /**
+ * Defined by Zend_Validate_Interface
+ *
+ * Returns true if $value is a valid date of the format YYYY-MM-DD
+ * If optional $format or $locale is set the date format is checked
+ * according to Zend_Date, see Zend_Date::isDate()
+ *
+ * @param string $value
+ * @return boolean
+ */
+ public function isValid($value)
+ {
+ $valueString = (string) $value;
+
+ $this->_setValue($valueString);
+
+ if (($this->_format !== null) or ($this->_locale !== null)) {
+ require_once 'Zend/Date.php';
+ if (!Zend_Date::isDate($value, $this->_format, $this->_locale)) {
+ if ($this->_checkFormat($value) === false) {
+ $this->_error(self::FALSEFORMAT);
+ } else {
+ $this->_error(self::INVALID);
+ }
+ return false;
+ }
+ } else {
+ if (!preg_match('/^\d{4}-\d{2}-\d{2}$/', $valueString)) {
+ $this->_error(self::NOT_YYYY_MM_DD);
+ return false;
+ }
+
+ list($year, $month, $day) = sscanf($valueString, '%d-%d-%d');
+
+ if (!checkdate($month, $day, $year)) {
+ $this->_error(self::INVALID);
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * Check if the given date fits the given format
+ *
+ * @param string $value Date to check
+ * @return boolean False when date does not fit the format
+ */
+ private function _checkFormat($value)
+ {
+ try {
+ require_once 'Zend/Locale/Format.php';
+ $parsed = Zend_Locale_Format::getDate($value, array(
+ 'date_format' => $this->_format, 'format_type' => 'iso',
+ 'fix_date' => false));
+ if (isset($parsed['year']) and ((strpos(strtoupper($this->_format), 'YY') !== false) and
+ (strpos(strtoupper($this->_format), 'YYYY') === false))) {
+ $parsed['year'] = Zend_Date::_century($parsed['year']);
+ }
+ } catch (Exception $e) {
+ // Date can not be parsed
+ return false;
+ }
+
+ if (((strpos($this->_format, 'Y') !== false) or (strpos($this->_format, 'y') !== false)) and
+ (!isset($parsed['year']))) {
+ // Year expected but not found
+ return false;
+ }
+
+ if ((strpos($this->_format, 'M') !== false) and (!isset($parsed['month']))) {
+ // Month expected but not found
+ return false;
+ }
+
+ if ((strpos($this->_format, 'd') !== false) and (!isset($parsed['day']))) {
+ // Day expected but not found
+ return false;
+ }
+
+ if (((strpos($this->_format, 'H') !== false) or (strpos($this->_format, 'h') !== false)) and
+ (!isset($parsed['hour']))) {
+ // Hour expected but not found
+ return false;
+ }
+
+ if ((strpos($this->_format, 'm') !== false) and (!isset($parsed['minute']))) {
+ // Minute expected but not found
+ return false;
+ }
+
+ if ((strpos($this->_format, 's') !== false) and (!isset($parsed['second']))) {
+ // Second expected but not found
+ return false;
+ }
+
+ // Date fits the format
+ return true;
+ }
+}
diff --git a/site/vendors/phpQuery/Zend/Validate/Digits.php b/site/vendors/phpQuery/Zend/Validate/Digits.php
new file mode 100644
index 0000000..c42ec0a
--- /dev/null
+++ b/site/vendors/phpQuery/Zend/Validate/Digits.php
@@ -0,0 +1,100 @@
+<?php
+
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Validate
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id: Digits.php 8064 2008-02-16 10:58:39Z thomas $
+ */
+
+
+/**
+ * @see Zend_Validate_Abstract
+ */
+require_once 'Zend/Validate/Abstract.php';
+
+
+/**
+ * @category Zend
+ * @package Zend_Validate
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Validate_Digits extends Zend_Validate_Abstract
+{
+ /**
+ * Validation failure message key for when the value contains non-digit characters
+ */
+ const NOT_DIGITS = 'notDigits';
+
+ /**
+ * Validation failure message key for when the value is an empty string
+ */
+ const STRING_EMPTY = 'stringEmpty';
+
+ /**
+ * Digits filter used for validation
+ *
+ * @var Zend_Filter_Digits
+ */
+ protected static $_filter = null;
+
+ /**
+ * Validation failure message template definitions
+ *
+ * @var array
+ */
+ protected $_messageTemplates = array(
+ self::NOT_DIGITS => "'%value%' contains not only digit characters",
+ self::STRING_EMPTY => "'%value%' is an empty string"
+ );
+
+ /**
+ * Defined by Zend_Validate_Interface
+ *
+ * Returns true if and only if $value only contains digit characters
+ *
+ * @param string $value
+ * @return boolean
+ */
+ public function isValid($value)
+ {
+ $valueString = (string) $value;
+
+ $this->_setValue($valueString);
+
+ if ('' === $valueString) {
+ $this->_error(self::STRING_EMPTY);
+ return false;
+ }
+
+ if (null === self::$_filter) {
+ /**
+ * @see Zend_Filter_Digits
+ */
+ require_once 'Zend/Filter/Digits.php';
+ self::$_filter = new Zend_Filter_Digits();
+ }
+
+ if ($valueString !== self::$_filter->filter($valueString)) {
+ $this->_error(self::NOT_DIGITS);
+ return false;
+ }
+
+ return true;
+ }
+
+}
diff --git a/site/vendors/phpQuery/Zend/Validate/EmailAddress.php b/site/vendors/phpQuery/Zend/Validate/EmailAddress.php
new file mode 100644
index 0000000..d8e9595
--- /dev/null
+++ b/site/vendors/phpQuery/Zend/Validate/EmailAddress.php
@@ -0,0 +1,245 @@
+<?php
+
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Validate
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id: EmailAddress.php 8985 2008-03-21 21:37:24Z matthew $
+ */
+
+
+/**
+ * @see Zend_Validate_Abstract
+ */
+require_once 'Zend/Validate/Abstract.php';
+
+
+/**
+ * @see Zend_Validate_Hostname
+ */
+require_once 'Zend/Validate/Hostname.php';
+
+
+/**
+ * @category Zend
+ * @package Zend_Validate
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Validate_EmailAddress extends Zend_Validate_Abstract
+{
+
+ const INVALID = 'emailAddressInvalid';
+ const INVALID_HOSTNAME = 'emailAddressInvalidHostname';
+ const INVALID_MX_RECORD = 'emailAddressInvalidMxRecord';
+ const DOT_ATOM = 'emailAddressDotAtom';
+ const QUOTED_STRING = 'emailAddressQuotedString';
+ const INVALID_LOCAL_PART = 'emailAddressInvalidLocalPart';
+
+ /**
+ * @var array
+ */
+ protected $_messageTemplates = array(
+ self::INVALID => "'%value%' is not a valid email address in the basic format local-part@hostname",
+ self::INVALID_HOSTNAME => "'%hostname%' is not a valid hostname for email address '%value%'",
+ self::INVALID_MX_RECORD => "'%hostname%' does not appear to have a valid MX record for the email address '%value%'",
+ self::DOT_ATOM => "'%localPart%' not matched against dot-atom format",
+ self::QUOTED_STRING => "'%localPart%' not matched against quoted-string format",
+ self::INVALID_LOCAL_PART => "'%localPart%' is not a valid local part for email address '%value%'"
+ );
+
+ /**
+ * @var array
+ */
+ protected $_messageVariables = array(
+ 'hostname' => '_hostname',
+ 'localPart' => '_localPart'
+ );
+
+ /**
+ * Local object for validating the hostname part of an email address
+ *
+ * @var Zend_Validate_Hostname
+ */
+ public $hostnameValidator;
+
+ /**
+ * Whether we check for a valid MX record via DNS
+ *
+ * @var boolean
+ */
+ protected $_validateMx = false;
+
+ /**
+ * @var string
+ */
+ protected $_hostname;
+
+ /**
+ * @var string
+ */
+ protected $_localPart;
+
+ /**
+ * Instantiates hostname validator for local use
+ *
+ * You can pass a bitfield to determine what types of hostnames are allowed.
+ * These bitfields are defined by the ALLOW_* constants in Zend_Validate_Hostname
+ * The default is to allow DNS hostnames only
+ *
+ * @param integer $allow OPTIONAL
+ * @param bool $validateMx OPTIONAL
+ * @param Zend_Validate_Hostname $hostnameValidator OPTIONAL
+ * @return void
+ */
+ public function __construct($allow = Zend_Validate_Hostname::ALLOW_DNS, $validateMx = false, Zend_Validate_Hostname $hostnameValidator = null)
+ {
+ $this->setValidateMx($validateMx);
+ $this->setHostnameValidator($hostnameValidator, $allow);
+ }
+
+ /**
+ * @param Zend_Validate_Hostname $hostnameValidator OPTIONAL
+ * @param int $allow OPTIONAL
+ * @return void
+ */
+ public function setHostnameValidator(Zend_Validate_Hostname $hostnameValidator = null, $allow = Zend_Validate_Hostname::ALLOW_DNS)
+ {
+ if ($hostnameValidator === null) {
+ $hostnameValidator = new Zend_Validate_Hostname($allow);
+ }
+ $this->hostnameValidator = $hostnameValidator;
+ }
+
+ /**
+ * Whether MX checking via dns_get_mx is supported or not
+ *
+ * This currently only works on UNIX systems
+ *
+ * @return boolean
+ */
+ public function validateMxSupported()
+ {
+ return function_exists('dns_get_mx');
+ }
+
+ /**
+ * Set whether we check for a valid MX record via DNS
+ *
+ * This only applies when DNS hostnames are validated
+ *
+ * @param boolean $allowed Set allowed to true to validate for MX records, and false to not validate them
+ */
+ public function setValidateMx($allowed)
+ {
+ $this->_validateMx = (bool) $allowed;
+ }
+
+ /**
+ * Defined by Zend_Validate_Interface
+ *
+ * Returns true if and only if $value is a valid email address
+ * according to RFC2822
+ *
+ * @link http://www.ietf.org/rfc/rfc2822.txt RFC2822
+ * @link http://www.columbia.edu/kermit/ascii.html US-ASCII characters
+ * @param string $value
+ * @return boolean
+ */
+ public function isValid($value)
+ {
+ $valueString = (string) $value;
+
+ $this->_setValue($valueString);
+
+ // Split email address up
+ if (!preg_match('/^(.+)@([^@]+)$/', $valueString, $matches)) {
+ $this->_error(self::INVALID);
+ return false;
+ }
+
+ $this->_localPart = $matches[1];
+ $this->_hostname = $matches[2];
+
+ // Match hostname part
+ $hostnameResult = $this->hostnameValidator->setTranslator($this->getTranslator())
+ ->isValid($this->_hostname);
+ if (!$hostnameResult) {
+ $this->_error(self::INVALID_HOSTNAME);
+
+ // Get messages and errors from hostnameValidator
+ foreach ($this->hostnameValidator->getMessages() as $message) {
+ $this->_messages[] = $message;
+ }
+ foreach ($this->hostnameValidator->getErrors() as $error) {
+ $this->_errors[] = $error;
+ }
+ }
+
+ // MX check on hostname via dns_get_record()
+ if ($this->_validateMx) {
+ if ($this->validateMxSupported()) {
+ $result = dns_get_mx($this->_hostname, $mxHosts);
+ if (count($mxHosts) < 1) {
+ $hostnameResult = false;
+ $this->_error(self::INVALID_MX_RECORD);
+ }
+ } else {
+ /**
+ * MX checks are not supported by this system
+ * @see Zend_Validate_Exception
+ */
+ require_once 'Zend/Validate/Exception.php';
+ throw new Zend_Validate_Exception('Internal error: MX checking not available on this system');
+ }
+ }
+
+ // First try to match the local part on the common dot-atom format
+ $localResult = false;
+
+ // Dot-atom characters are: 1*atext *("." 1*atext)
+ // atext: ALPHA / DIGIT / and "!", "#", "$", "%", "&", "'", "*",
+ // "-", "/", "=", "?", "^", "_", "`", "{", "|", "}", "~"
+ $atext = 'a-zA-Z0-9\x21\x23\x24\x25\x26\x27\x2a\x2b\x2d\x2f\x3d\x3f\x5e\x5f\x60\x7b\x7c\x7d';
+ if (preg_match('/^[' . $atext . ']+(\x2e+[' . $atext . ']+)*$/', $this->_localPart)) {
+ $localResult = true;
+ } else {
+ // Try quoted string format
+
+ // Quoted-string characters are: DQUOTE *([FWS] qtext/quoted-pair) [FWS] DQUOTE
+ // qtext: Non white space controls, and the rest of the US-ASCII characters not
+ // including "\" or the quote character
+ $noWsCtl = '\x01-\x08\x0b\x0c\x0e-\x1f\x7f';
+ $qtext = $noWsCtl . '\x21\x23-\x5b\x5d-\x7e';
+ $ws = '\x20\x09';
+ if (preg_match('/^\x22([' . $ws . $qtext . '])*[$ws]?\x22$/', $this->_localPart)) {
+ $localResult = true;
+ } else {
+ $this->_error(self::DOT_ATOM);
+ $this->_error(self::QUOTED_STRING);
+ $this->_error(self::INVALID_LOCAL_PART);
+ }
+ }
+
+ // If both parts valid, return true
+ if ($localResult && $hostnameResult) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+}
diff --git a/site/vendors/phpQuery/Zend/Validate/Exception.php b/site/vendors/phpQuery/Zend/Validate/Exception.php
new file mode 100644
index 0000000..a38077e
--- /dev/null
+++ b/site/vendors/phpQuery/Zend/Validate/Exception.php
@@ -0,0 +1,37 @@
+<?php
+
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Validate
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id: Exception.php 8064 2008-02-16 10:58:39Z thomas $
+ */
+
+
+/**
+ * @see Zend_Exception
+ */
+require_once 'Zend/Exception.php';
+
+
+/**
+ * @category Zend
+ * @package Zend_Validate
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Validate_Exception extends Zend_Exception
+{}
diff --git a/site/vendors/phpQuery/Zend/Validate/File/Count.php b/site/vendors/phpQuery/Zend/Validate/File/Count.php
new file mode 100644
index 0000000..a49131f
--- /dev/null
+++ b/site/vendors/phpQuery/Zend/Validate/File/Count.php
@@ -0,0 +1,229 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Validate
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id: $
+ */
+
+/**
+ * @see Zend_Validate_Abstract
+ */
+require_once 'Zend/Validate/Abstract.php';
+
+/**
+ * Validator for counting all given files
+ *
+ * @category Zend
+ * @package Zend_Validate
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Validate_File_Count extends Zend_Validate_Abstract
+{
+ /**#@+
+ * @const string Error constants
+ */
+ const TOO_MUCH = 'fileCountTooMuch';
+ const TOO_LESS = 'fileCountTooLess';
+ /**#@-*/
+
+ /**
+ * @var array Error message templates
+ */
+ protected $_messageTemplates = array(
+ self::TOO_MUCH => "Too much files, only '%value%' are allowed",
+ self::TOO_LESS => "Too less files, minimum '%value%' must be given"
+ );
+
+ /**
+ * @var array Error message template variables
+ */
+ protected $_messageVariables = array(
+ 'min' => '_min',
+ 'max' => '_max'
+ );
+
+ /**
+ * Minimum file count
+ *
+ * If null, there is no minimum file count
+ *
+ * @var integer
+ */
+ protected $_min;
+
+ /**
+ * Maximum file count
+ *
+ * If null, there is no maximum file count
+ *
+ * @var integer|null
+ */
+ protected $_max;
+
+ /**
+ * Internal file array
+ * @var array
+ */
+ protected $_files;
+
+ /**
+ * Sets validator options
+ *
+ * Min limits the file count, when used with max=null it is the maximum file count
+ * It also accepts an array with the keys 'min' and 'max'
+ *
+ * @param integer|array $min Minimum file count
+ * @param integer $max Maximum file count
+ * @return void
+ */
+ public function __construct($min, $max = null)
+ {
+ $this->_files = array();
+ if (is_array($min) === true) {
+ if (isset($min['max']) === true) {
+ $max = $min['max'];
+ }
+
+ if (isset($min['min']) === true) {
+ $min = $min['min'];
+ }
+
+ if (isset($min[0]) === true) {
+ if (count($min) === 2) {
+ $max = $min[1];
+ $min = $min[0];
+ } else {
+ $max = $min[0];
+ $min = null;
+ }
+ }
+ }
+
+ if (empty($max) === true) {
+ $max = $min;
+ $min = null;
+ }
+
+ $this->setMin($min);
+ $this->setMax($max);
+ }
+
+ /**
+ * Returns the minimum file count
+ *
+ * @return integer
+ */
+ public function getMin()
+ {
+ $min = $this->_min;
+
+ return $min;
+ }
+
+ /**
+ * Sets the minimum file count
+ *
+ * @param integer $min The minimum file count
+ * @return Zend_Validate_File_Size Provides a fluent interface
+ * @throws Zend_Validate_Exception When min is greater than max
+ */
+ public function setMin($min)
+ {
+ if ($min === null) {
+ $this->_min = null;
+ } else if (($this->_max !== null) and ($min > $this->_max)) {
+ require_once 'Zend/Validate/Exception.php';
+ throw new Zend_Validate_Exception('The minimum must be less than or equal to the maximum file count, but '
+ . " {$min} > {$this->_max}");
+ } else {
+ $this->_min = max(0, (integer) $min);
+ }
+
+ return $this;
+ }
+
+ /**
+ * Returns the maximum file count
+ *
+ * @return integer|null
+ */
+ public function getMax()
+ {
+ return $this->_max;
+ }
+
+ /**
+ * Sets the maximum file count
+ *
+ * @param integer|null $max The maximum file count
+ * @throws Zend_Validate_Exception When max is smaller than min
+ * @return Zend_Validate_StringLength Provides a fluent interface
+ */
+ public function setMax($max)
+ {
+ if ($max === null) {
+ $this->_max = null;
+ } else if (($this->_min !== null) and ($max < $this->_min)) {
+ require_once 'Zend/Validate/Exception.php';
+ throw new Zend_Validate_Exception("The maximum must be greater than or equal to the minimum file count, but "
+ . "{$max} < {$this->_min}");
+ } else {
+ $this->_max = (integer) $max;
+ }
+
+ return $this;
+ }
+
+ /**
+ * Defined by Zend_Validate_Interface
+ *
+ * Returns true if and only if the file count of all checked files is at least min and
+ * not bigger than max (when max is not null). Attention: When checking with set min you
+ * must give all files with the first call, otherwise you will get an false.
+ *
+ * @param string|array $value Filenames to check for count
+ * @param array $file File data from Zend_File_Transfer
+ * @return boolean
+ */
+ public function isValid($value, $file = null)
+ {
+ if (is_string($value)) {
+ $value = array($value);
+ }
+
+ foreach ($value as $file) {
+ if (!isset($this->_files[$file])) {
+ $this->_files[$file] = $file;
+ }
+ }
+
+ if (($this->_max !== null) && (count($this->_files) > $this->_max)) {
+ $this->_value = $this->_max;
+ $this->_error(self::TOO_MUCH);
+ return false;
+ }
+
+ if (($this->_min !== null) && (count($this->_files) < $this->_min)) {
+ $this->_value = $this->_min;
+ $this->_error(self::TOO_LESS);
+ return false;
+ }
+
+ return true;
+ }
+}
diff --git a/site/vendors/phpQuery/Zend/Validate/File/Exists.php b/site/vendors/phpQuery/Zend/Validate/File/Exists.php
new file mode 100644
index 0000000..268090b
--- /dev/null
+++ b/site/vendors/phpQuery/Zend/Validate/File/Exists.php
@@ -0,0 +1,192 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Validate
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id: $
+ */
+
+/**
+ * @see Zend_Validate_Abstract
+ */
+require_once 'Zend/Validate/Abstract.php';
+
+/**
+ * Validator which checks if the file already exists in the directory
+ *
+ * @category Zend
+ * @package Zend_Validate
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Validate_File_Exists extends Zend_Validate_Abstract
+{
+ /**
+ * @const string Error constants
+ */
+ const DOES_NOT_EXIST = 'fileExistsDoesNotExist';
+
+ /**
+ * @var array Error message templates
+ */
+ protected $_messageTemplates = array(
+ self::DOES_NOT_EXIST => "The file '%value%' does not exist"
+ );
+
+ /**
+ * Internal list of directories
+ * @var string
+ */
+ protected $_directory = '';
+
+ /**
+ * @var array Error message template variables
+ */
+ protected $_messageVariables = array(
+ 'directory' => '_directory'
+ );
+
+ /**
+ * Sets validator options
+ *
+ * @param string|array $directory
+ * @return void
+ */
+ public function __construct($directory = array())
+ {
+ $this->setDirectory($directory);
+ }
+
+ /**
+ * Returns the set file directories which are checked
+ *
+ * @param boolean $asArray Returns the values as array, when false an concated string is returned
+ * @return string
+ */
+ public function getDirectory($asArray = false)
+ {
+ $asArray = (bool) $asArray;
+ $directory = (string) $this->_directory;
+ if ($asArray) {
+ $directory = explode(',', $directory);
+ }
+
+ return $directory;
+ }
+
+ /**
+ * Sets the file directory which will be checked
+ *
+ * @param string|array $directory The directories to validate
+ * @return Zend_Validate_File_Extension Provides a fluent interface
+ */
+ public function setDirectory($directory)
+ {
+ $this->_directory = null;
+ $this->addDirectory($directory);
+ return $this;
+ }
+
+ /**
+ * Adds the file directory which will be checked
+ *
+ * @param string|array $directory The directory to add for validation
+ * @return Zend_Validate_File_Extension Provides a fluent interface
+ */
+ public function addDirectory($directory)
+ {
+ $directories = $this->getDirectory(true);
+ if (is_string($directory)) {
+ $directory = explode(',', $directory);
+ }
+
+ foreach ($directory as $content) {
+ if (empty($content) || !is_string($content)) {
+ continue;
+ }
+
+ $directories[] = trim($content);
+ }
+ $directories = array_unique($directories);
+
+ // Sanity check to ensure no empty values
+ foreach ($directories as $key => $dir) {
+ if (empty($dir)) {
+ unset($directories[$key]);
+ }
+ }
+
+ $this->_directory = implode(',', $directories);
+
+ return $this;
+ }
+
+ /**
+ * Defined by Zend_Validate_Interface
+ *
+ * Returns true if and only if the file already exists in the set directories
+ *
+ * @param string $value Real file to check for existance
+ * @param array $file File data from Zend_File_Transfer
+ * @return boolean
+ */
+ public function isValid($value, $file = null)
+ {
+ $directories = $this->getDirectory(true);
+ if (($file !== null) and (!empty($file['destination']))) {
+ $directories[] = $file['destination'];
+ } else if (!isset($file['name'])) {
+ $file['name'] = $value;
+ }
+
+ $check = false;
+ foreach ($directories as $directory) {
+ if (empty($directory)) {
+ continue;
+ }
+
+ $check = true;
+ if (!file_exists($directory . DIRECTORY_SEPARATOR . $file['name'])) {
+ $this->_throw($file, self::DOES_NOT_EXIST);
+ return false;
+ }
+ }
+
+ if (!$check) {
+ $this->_throw($file, self::DOES_NOT_EXIST);
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Throws an error of the given type
+ *
+ * @param string $file
+ * @param string $errorType
+ * @return false
+ */
+ protected function _throw($file, $errorType)
+ {
+ if ($file !== null) {
+ $this->_value = $file['name'];
+ }
+
+ $this->_error($errorType);
+ return false;
+ }
+}
diff --git a/site/vendors/phpQuery/Zend/Validate/File/Extension.php b/site/vendors/phpQuery/Zend/Validate/File/Extension.php
new file mode 100644
index 0000000..62577b3
--- /dev/null
+++ b/site/vendors/phpQuery/Zend/Validate/File/Extension.php
@@ -0,0 +1,204 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Validate
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id: $
+ */
+
+/**
+ * @see Zend_Validate_Abstract
+ */
+require_once 'Zend/Validate/Abstract.php';
+
+/**
+ * Validator for the file extension of a file
+ *
+ * @category Zend
+ * @package Zend_Validate
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Validate_File_Extension extends Zend_Validate_Abstract
+{
+ /**
+ * @const string Error constants
+ */
+ const FALSE_EXTENSION = 'fileExtensionFalse';
+ const NOT_FOUND = 'fileExtensionNotFound';
+
+ /**
+ * @var array Error message templates
+ */
+ protected $_messageTemplates = array(
+ self::FALSE_EXTENSION => "The file '%value%' has a false extension",
+ self::NOT_FOUND => "The file '%value%' was not found"
+ );
+
+ /**
+ * Internal list of extensions
+ * @var string
+ */
+ protected $_extension = '';
+
+ /**
+ * Validate case sensitive
+ *
+ * @var boolean
+ */
+ protected $_case = false;
+
+ /**
+ * @var array Error message template variables
+ */
+ protected $_messageVariables = array(
+ 'extension' => '_extension'
+ );
+
+ /**
+ * Sets validator options
+ *
+ * @param string|array $extension
+ * @param boolean $case If true validation is done case sensitive
+ * @return void
+ */
+ public function __construct($extension, $case = false)
+ {
+ $this->_case = (boolean) $case;
+ $this->setExtension($extension);
+ }
+
+ /**
+ * Returns the set file extension
+ *
+ * @param boolean $asArray Returns the values as array, when false an concated string is returned
+ * @return string
+ */
+ public function getExtension($asArray = false)
+ {
+ $asArray = (bool) $asArray;
+ $extension = (string) $this->_extension;
+ if ($asArray) {
+ $extension = explode(',', $extension);
+ }
+
+ return $extension;
+ }
+
+ /**
+ * Sets the file extensions
+ *
+ * @param string|array $extension The extensions to validate
+ * @return Zend_Validate_File_Extension Provides a fluent interface
+ */
+ public function setExtension($extension)
+ {
+ $this->_extension = null;
+ $this->addExtension($extension);
+ return $this;
+ }
+
+ /**
+ * Adds the file extensions
+ *
+ * @param string|array $extension The extensions to add for validation
+ * @return Zend_Validate_File_Extension Provides a fluent interface
+ */
+ public function addExtension($extension)
+ {
+ $extensions = $this->getExtension(true);
+ if (is_string($extension)) {
+ $extension = explode(',', $extension);
+ }
+
+ foreach ($extension as $content) {
+ if (empty($content) || !is_string($content)) {
+ continue;
+ }
+
+ $extensions[] = trim($content);
+ }
+ $extensions = array_unique($extensions);
+
+ // Sanity check to ensure no empty values
+ foreach ($extensions as $key => $ext) {
+ if (empty($ext)) {
+ unset($extensions[$key]);
+ }
+ }
+
+ $this->_extension = implode(',', $extensions);
+
+ return $this;
+ }
+
+ /**
+ * Defined by Zend_Validate_Interface
+ *
+ * Returns true if and only if the fileextension of $value is included in the
+ * set extension list
+ *
+ * @param string $value Real file to check for extension
+ * @param array $file File data from Zend_File_Transfer
+ * @return boolean
+ */
+ public function isValid($value, $file = null)
+ {
+ // Is file readable ?
+ if (!@is_readable($value)) {
+ $this->_throw($file, self::NOT_FOUND);
+ return false;
+ }
+
+ if ($file !== null) {
+ $info['extension'] = substr($file['name'], strpos($file['name'], '.') + 1);
+ } else {
+ $info = @pathinfo($value);
+ }
+
+ $extensions = $this->getExtension(true);
+
+ if ($this->_case and (in_array($info['extension'], $extensions))) {
+ return true;
+ } else if (!$this->_case) {
+ foreach ($extensions as $extension) {
+ if (strtolower($extension) == strtolower($info['extension'])) {
+ return true;
+ }
+ }
+ }
+
+ $this->_throw($file, self::FALSE_EXTENSION);
+ return false;
+ }
+
+ /**
+ * Throws an error of the given type
+ *
+ * @param string $file
+ * @param string $errorType
+ * @return false
+ */
+ protected function _throw($file, $errorType)
+ {
+ if ($file !== null) {
+ $this->_value = $file['name'];
+ }
+
+ $this->_error($errorType);
+ return false;
+ }
+}
diff --git a/site/vendors/phpQuery/Zend/Validate/File/FilesSize.php b/site/vendors/phpQuery/Zend/Validate/File/FilesSize.php
new file mode 100644
index 0000000..e8b060d
--- /dev/null
+++ b/site/vendors/phpQuery/Zend/Validate/File/FilesSize.php
@@ -0,0 +1,156 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Validate
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id: $
+ */
+
+/**
+ * @see Zend_Validate_File_Size
+ */
+require_once 'Zend/Validate/File/Size.php';
+
+/**
+ * Validator for the size of all files which will be validated in sum
+ *
+ * @category Zend
+ * @package Zend_Validate
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Validate_File_FilesSize extends Zend_Validate_File_Size
+{
+ /**
+ * @const string Error constants
+ */
+ const TOO_BIG = 'fileFilesSizeTooBig';
+ const TOO_SMALL = 'fileFilesSizeTooSmall';
+ const NOT_READABLE = 'fileFilesSizeNotReadable';
+
+ /**
+ * @var array Error message templates
+ */
+ protected $_messageTemplates = array(
+ self::TOO_BIG => "The files in sum exceed the maximum allowed size",
+ self::TOO_SMALL => "All files are in sum smaller than required",
+ self::NOT_READABLE => "One or more files can not be read"
+ );
+
+ /**
+ * @var array Error message template variables
+ */
+ protected $_messageVariables = array(
+ 'min' => '_min',
+ 'max' => '_max'
+ );
+
+ /**
+ * Minimum filesize
+ *
+ * @var integer
+ */
+ protected $_min;
+
+ /**
+ * Maximum filesize
+ *
+ * @var integer|null
+ */
+ protected $_max;
+
+ /**
+ * Internal file array
+ *
+ * @var array
+ */
+ protected $_files;
+
+ /**
+ * Internal file size counter
+ *
+ * @var integer
+ */
+ protected $_size;
+
+ /**
+ * Sets validator options
+ *
+ * Min limits the used diskspace for all files, when used with max=null it is the maximum filesize
+ * It also accepts an array with the keys 'min' and 'max'
+ *
+ * @param integer|array $min Minimum diskspace for all files
+ * @param integer $max Maximum diskspace for all files
+ * @return void
+ */
+ public function __construct($min, $max = null)
+ {
+ $this->_files = array();
+ $this->_size = 0;
+ parent::__construct($min, $max);
+ }
+
+ /**
+ * Defined by Zend_Validate_Interface
+ *
+ * Returns true if and only if the disk usage of all files is at least min and
+ * not bigger than max (when max is not null).
+ *
+ * @param string|array $value Real file to check for size
+ * @param array $file File data from Zend_File_Transfer
+ * @return boolean
+ */
+ public function isValid($value, $file = null)
+ {
+ if (is_string($value)) {
+ $value = array($value);
+ }
+
+ foreach ($value as $files) {
+ // Is file readable ?
+ if (!@is_readable($files)) {
+ $this->_throw($file, self::NOT_READABLE);
+ return false;
+ }
+
+ if (!isset($this->_files[$files])) {
+ $this->_files[$files] = $files;
+ } else {
+ // file already counted... do not count twice
+ continue;
+ }
+
+ // limited to 2GB files
+ $size = @filesize($files);
+ $this->_size += $size;
+ $this->_setValue($this->_size);
+ if (($this->_max !== null) && ($this->_max < $this->_size)) {
+ $this->_throw($file, self::TOO_BIG);
+ }
+ }
+
+ // Check that aggregate files are >= minimum size
+ if (($this->_min !== null) && ($this->_size < $this->_min)) {
+ $this->_throw($file, self::TOO_SMALL);
+ }
+
+ if (count($this->_messages) > 0) {
+ return false;
+ } else {
+ return true;
+ }
+ }
+}
diff --git a/site/vendors/phpQuery/Zend/Validate/File/ImageSize.php b/site/vendors/phpQuery/Zend/Validate/File/ImageSize.php
new file mode 100644
index 0000000..6c27ef6
--- /dev/null
+++ b/site/vendors/phpQuery/Zend/Validate/File/ImageSize.php
@@ -0,0 +1,335 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Validate
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id: $
+ */
+
+/**
+ * @see Zend_Validate_Abstract
+ */
+require_once 'Zend/Validate/Abstract.php';
+
+/**
+ * Validator for the image size of a image file
+ *
+ * @category Zend
+ * @package Zend_Validate
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Validate_File_ImageSize extends Zend_Validate_Abstract
+{
+ /**
+ * @const string Error constants
+ */
+ const WIDTH_TOO_BIG = 'fileImageSizeWidthTooBig';
+ const WIDTH_TOO_SMALL = 'fileImageSizeWidthTooSmall';
+ const HEIGHT_TOO_BIG = 'fileImageSizeHeightTooBig';
+ const HEIGHT_TOO_SMALL = 'fileImageSizeHeightTooSmall';
+ const NOT_DETECTED = 'fileImageSizeNotDetected';
+ const NOT_READABLE = 'fileImageSizeNotReadable';
+
+ /**
+ * @var array Error message template
+ */
+ protected $_messageTemplates = array(
+ self::WIDTH_TOO_BIG => "Width of the image '%value%' is bigger than allowed",
+ self::WIDTH_TOO_SMALL => "Width of the image '%value%' is smaller than allowed",
+ self::HEIGHT_TOO_BIG => "Height of the image '%value%' is bigger than allowed",
+ self::HEIGHT_TOO_SMALL => "Height of the image '%value%' is smaller than allowed",
+ self::NOT_DETECTED => "Size of the image '%value%' could not be detected",
+ self::NOT_READABLE => "The image '%value%' can not be read"
+ );
+
+ /**
+ * @var array Error message template variables
+ */
+ protected $_messageVariables = array(
+ 'minwidth' => '_minwidth',
+ 'maxwidth' => '_maxwidth',
+ 'minheight' => '_minheight',
+ 'maxheight' => '_maxheight'
+ );
+
+ /**
+ * Minimum image width
+ *
+ * @var integer
+ */
+ protected $_minwidth;
+
+ /**
+ * Maximum image width
+ *
+ * @var integer
+ */
+ protected $_maxwidth;
+
+ /**
+ * Minimum image height
+ *
+ * @var integer
+ */
+ protected $_minheight;
+
+ /**
+ * Maximum image height
+ *
+ * @var integer
+ */
+ protected $_maxheight;
+
+ /**
+ * Sets validator options
+ *
+ * Min limits the filesize, when used with max=null if is the maximum filesize
+ * It also accepts an array with the keys 'min' and 'max'
+ *
+ * @param integer|array $max Maximum filesize
+ * @param integer $max Maximum filesize
+ * @return void
+ */
+ public function __construct($minwidth = 0, $minheight = 0, $maxwidth = null, $maxheight = null)
+ {
+ if (is_array($minwidth) === true) {
+ if (isset($minwidth['maxheight']) === true) {
+ $maxheight = $minwidth['maxheight'];
+ }
+
+ if (isset($minwidth['minheight']) === true) {
+ $minheight = $minwidth['minheight'];
+ }
+
+ if (isset($minwidth['maxwidth']) === true) {
+ $maxwidth = $minwidth['maxwidth'];
+ }
+
+ if (isset($minwidth['minwidth']) === true) {
+ $minwidth = $minwidth['minwidth'];
+ }
+
+ if (isset($minwidth[0]) === true) {
+ $maxheight = $minwidth[3];
+ $maxwidth = $minwidth[2];
+ $minheight = $minwidth[1];
+ $minwidth = $minwidth[0];
+ }
+ }
+
+ $this->setImageMin($minwidth, $minheight);
+ $this->setImageMax($maxwidth, $maxheight);
+ }
+
+ /**
+ * Returns the set minimum image sizes
+ *
+ * @return array
+ */
+ public function getImageMin()
+ {
+ return array($this->_minwidth, $this->_minheight);
+ }
+
+ /**
+ * Returns the set maximum image sizes
+ *
+ * @return array
+ */
+ public function getImageMax()
+ {
+ return array($this->_maxwidth, $this->_maxheight);
+ }
+
+ /**
+ * Returns the set image width sizes
+ *
+ * @return array
+ */
+ public function getImageWidth()
+ {
+ return array($this->_minwidth, $this->_maxwidth);
+ }
+
+ /**
+ * Returns the set image height sizes
+ *
+ * @return array
+ */
+ public function getImageHeight()
+ {
+ return array($this->_minheight, $this->_maxheight);
+ }
+
+ /**
+ * Sets the minimum image size
+ *
+ * @param integer $minwidth The minimum image width
+ * @param integer $minheight The minimum image height
+ * @throws Zend_Validate_Exception When minwidth is greater than maxwidth
+ * @throws Zend_Validate_Exception When minheight is greater than maxheight
+ * @return Zend_Validate_File_ImageSize Provides a fluent interface
+ */
+ public function setImageMin($minwidth, $minheight)
+ {
+ if (($this->_maxwidth !== null) and ($minwidth > $this->_maxwidth)) {
+ require_once 'Zend/Validate/Exception.php';
+ throw new Zend_Validate_Exception("The minimum image width must be less than or equal to the "
+ . " maximum image width, but {$minwidth} > {$this->_maxwidth}");
+ }
+
+ if (($this->_maxheight !== null) and ($minheight > $this->_maxheight)) {
+ require_once 'Zend/Validate/Exception.php';
+ throw new Zend_Validate_Exception("The minimum image height must be less than or equal to the "
+ . " maximum image height, but {$minheight} > {$this->_maxheight}");
+ }
+
+ $this->_minwidth = max(0, (integer) $minwidth);
+ $this->_minheight = max(0, (integer) $minheight);
+ return $this;
+ }
+
+ /**
+ * Sets the maximum image size
+ *
+ * @param integer $maxwidth The maximum image width
+ * @param integer $maxheight The maximum image height
+ * @throws Zend_Validate_Exception When maxwidth is smaller than minwidth
+ * @throws Zend_Validate_Exception When maxheight is smaller than minheight
+ * @return Zend_Validate_StringLength Provides a fluent interface
+ */
+ public function setImageMax($maxwidth, $maxheight)
+ {
+ if ($maxwidth === null) {
+ $tempwidth = null;
+ } else if (($this->_minwidth !== null) and ($maxwidth < $this->_minwidth)) {
+ require_once 'Zend/Validate/Exception.php';
+ throw new Zend_Validate_Exception("The maximum image width must be greater than or equal to the "
+ . "minimum image width, but {$maxwidth} < {$this->_minwidth}");
+ } else {
+ $tempwidth = (integer) $maxwidth;
+ }
+
+ if ($maxheight === null) {
+ $tempheight = null;
+ } else if (($this->_minheight !== null) and ($maxheight < $this->_minheight)) {
+ require_once 'Zend/Validate/Exception.php';
+ throw new Zend_Validate_Exception("The maximum image height must be greater than or equal to the "
+ . "minimum image height, but {$maxheight} < {$this->_minwidth}");
+ } else {
+ $tempheight = (integer) $maxheight;
+ }
+
+ $this->_maxwidth = $tempwidth;
+ $this->_maxheight = $tempheight;
+ return $this;
+ }
+
+ /**
+ * Sets the mimimum and maximum image width
+ *
+ * @param integer $minwidth The minimum image width
+ * @param integer $maxwidth The maximum image width
+ * @return Zend_Validate_File_ImageSize Provides a fluent interface
+ */
+ public function setImageWidth($minwidth, $maxwidth)
+ {
+ $this->setImageMin($minwidth, $this->_minheight);
+ $this->setImageMax($maxwidth, $this->_maxheight);
+ return $this;
+ }
+
+ /**
+ * Sets the mimimum and maximum image height
+ *
+ * @param integer $minheight The minimum image height
+ * @param integer $maxheight The maximum image height
+ * @return Zend_Validate_File_ImageSize Provides a fluent interface
+ */
+ public function setImageHeight($minheight, $maxheight)
+ {
+ $this->setImageMin($this->_minwidth, $minheight);
+ $this->setImageMax($this->_maxwidth, $maxheight);
+ return $this;
+ }
+
+ /**
+ * Defined by Zend_Validate_Interface
+ *
+ * Returns true if and only if the imagesize of $value is at least min and
+ * not bigger than max
+ *
+ * @param string $value Real file to check for image size
+ * @param array $file File data from Zend_File_Transfer
+ * @return boolean
+ */
+ public function isValid($value, $file = null)
+ {
+ // Is file readable ?
+ if (@is_readable($value) === false) {
+ $this->_throw($file, self::NOT_READABLE);
+ return false;
+ }
+
+ $size = @getimagesize($value);
+ $this->_setValue($file);
+
+ if (empty($size) or ($size[0] === 0) or ($size[1] === 0)) {
+ $this->_throw($file, self::NOT_DETECTED);
+ return false;
+ }
+
+ if ($size[0] < $this->_minwidth) {
+ $this->_throw($file, self::WIDTH_TOO_SMALL);
+ }
+
+ if ($size[1] < $this->_minheight) {
+ $this->_throw($file, self::HEIGHT_TOO_SMALL);
+ }
+
+ if (($this->_maxwidth !== null) and ($this->_maxwidth < $size[0])) {
+ $this->_throw($file, self::WIDTH_TOO_BIG);
+ }
+
+ if (($this->_maxheight !== null) and ($this->_maxheight < $size[1])) {
+ $this->_throw($file, self::HEIGHT_TOO_BIG);
+ }
+
+ if (count($this->_messages) > 0) {
+ return false;
+ } else {
+ return true;
+ }
+ }
+
+ /**
+ * Throws an error of the given type
+ *
+ * @param string $file
+ * @param string $errorType
+ * @return false
+ */
+ protected function _throw($file, $errorType)
+ {
+ if ($file !== null) {
+ $this->_value = $file['name'];
+ }
+
+ $this->_error($errorType);
+ return false;
+ }
+}
diff --git a/site/vendors/phpQuery/Zend/Validate/File/MimeType.php b/site/vendors/phpQuery/Zend/Validate/File/MimeType.php
new file mode 100644
index 0000000..8f7e9cd
--- /dev/null
+++ b/site/vendors/phpQuery/Zend/Validate/File/MimeType.php
@@ -0,0 +1,200 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Validate
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id: $
+ */
+
+/**
+ * @see Zend_Validate_Abstract
+ */
+require_once 'Zend/Validate/Abstract.php';
+
+/**
+ * Validator for the mime type of a file
+ *
+ * @category Zend
+ * @package Zend_Validate
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Validate_File_MimeType extends Zend_Validate_Abstract
+{
+ const FALSE_TYPE = 'fileMimeTypeFalse';
+ const NOT_DETECTED = 'fileMimeTypeNotDetected';
+ const NOT_READABLE = 'fileMimeTypeNotReadable';
+
+ /**
+ * @var array
+ */
+ protected $_messageTemplates = array(
+ self::FALSE_TYPE => "The file '%value%' has a false mimetype",
+ self::NOT_DETECTED => "The mimetype of file '%value%' has not been detected",
+ self::NOT_READABLE => "The file '%value%' can not be read"
+ );
+
+ /**
+ * @var array
+ */
+ protected $_messageVariables = array(
+ 'mimetype' => '_mimetype'
+ );
+
+ /**
+ * Mimetypes
+ *
+ * If null, there is no mimetype
+ *
+ * @var string|null
+ */
+ protected $_mimetype;
+
+ /**
+ * Sets validator options
+ *
+ * Mimetype to accept
+ *
+ * @param string|array $mimetype MimeType
+ * @return void
+ */
+ public function __construct($mimetype)
+ {
+ $this->setMimeType($mimetype);
+ }
+
+ /**
+ * Returns the set mimetypes
+ *
+ * @param boolean $asArray Returns the values as array, when false an concated string is returned
+ * @return integer
+ */
+ public function getMimeType($asArray = false)
+ {
+ $asArray = (bool) $asArray;
+ $mimetype = (string) $this->_mimetype;
+ if ($asArray) {
+ $mimetype = explode(',', $mimetype);
+ }
+
+ return $mimetype;
+ }
+
+ /**
+ * Sets the mimetypes
+ *
+ * @param string|array $mimetype The mimetypes to validate
+ * @return Zend_Validate_File_Extension Provides a fluent interface
+ */
+ public function setMimeType($mimetype)
+ {
+ $this->_mimetype = null;
+ $this->addMimeType($mimetype);
+ return $this;
+ }
+
+ /**
+ * Adds the mimetypes
+ *
+ * @param string|array $mimetype The mimetypes to add for validation
+ * @return Zend_Validate_File_Extension Provides a fluent interface
+ */
+ public function addMimeType($mimetype)
+ {
+ $mimetypes = $this->getMimeType(true);
+ if (is_string($mimetype)) {
+ $mimetype = explode(',', $mimetype);
+ }
+
+ foreach ($mimetype as $content) {
+ if (empty($content) || !is_string($content)) {
+ continue;
+ }
+ $mimetypes[] = trim($content);
+ }
+ $mimetypes = array_unique($mimetypes);
+
+ // Sanity check to ensure no empty values
+ foreach ($mimetypes as $key => $mt) {
+ if (empty($mt)) {
+ unset($mimetypes[$key]);
+ }
+ }
+
+ $this->_mimetype = implode(',', $mimetypes);
+
+ return $this;
+ }
+
+ /**
+ * Defined by Zend_Validate_Interface
+ *
+ * Returns true if the mimetype of the file matches the given ones. Also parts
+ * of mimetypes can be checked. If you give for example "image" all image
+ * mime types will be accepted like "image/gif", "image/jpeg" and so on.
+ *
+ * @param string $value Real file to check for mimetype
+ * @param array $file File data from Zend_File_Transfer
+ * @return boolean
+ */
+ public function isValid($value, $file = null)
+ {
+ // Is file readable ?
+ if (!@is_readable($value)) {
+ $this->_throw($file, self::NOT_READABLE);
+ return false;
+ }
+
+ if ($file !== null) {
+ $info['type'] = $file['type'];
+ } else {
+ $this->_throw($file, self::NOT_DETECTED);
+ return false;
+ }
+
+ $mimetype = $this->getMimeType(true);
+ if (in_array($info['type'], $mimetype)) {
+ return true;
+ }
+
+ foreach($mimetype as $mime) {
+ $types = explode('/', $info['type']);
+ if (in_array($mime, $types)) {
+ return true;
+ }
+ }
+
+ $this->_throw($file, self::FALSE_TYPE);
+ return false;
+ }
+
+ /**
+ * Throws an error of the given type
+ *
+ * @param string $file
+ * @param string $errorType
+ * @return false
+ */
+ protected function _throw($file, $errorType)
+ {
+ if ($file !== null) {
+ $this->_value = $file['name'];
+ }
+
+ $this->_error($errorType);
+ return false;
+ }
+}
diff --git a/site/vendors/phpQuery/Zend/Validate/File/NotExists.php b/site/vendors/phpQuery/Zend/Validate/File/NotExists.php
new file mode 100644
index 0000000..2b812fc
--- /dev/null
+++ b/site/vendors/phpQuery/Zend/Validate/File/NotExists.php
@@ -0,0 +1,86 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Validate
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id: $
+ */
+
+/**
+ * @see Zend_Validate_File_Exists
+ */
+require_once 'Zend/Validate/File/Exists.php';
+
+/**
+ * Validator which checks if the destination file does not exist
+ *
+ * @category Zend
+ * @package Zend_Validate
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Validate_File_NotExists extends Zend_Validate_File_Exists
+{
+ /**
+ * @const string Error constants
+ */
+ const DOES_EXIST = 'fileNotExistsDoesExist';
+
+ /**
+ * @var array Error message templates
+ */
+ protected $_messageTemplates = array(
+ self::DOES_EXIST => "The file '%value%' does exist"
+ );
+
+ /**
+ * Defined by Zend_Validate_Interface
+ *
+ * Returns true if and only if the file does not exist in the set destinations
+ *
+ * @param string $value Real file to check for
+ * @param array $file File data from Zend_File_Transfer
+ * @return boolean
+ */
+ public function isValid($value, $file = null)
+ {
+ $directories = $this->getDirectory(true);
+ if (($file !== null) and (!empty($file['destination']))) {
+ $directories[] = $file['destination'];
+ } else if (!isset($file['name'])) {
+ $file['name'] = $value;
+ }
+
+ foreach ($directories as $directory) {
+ if (empty($directory)) {
+ continue;
+ }
+
+ $check = true;
+ if (file_exists($directory . DIRECTORY_SEPARATOR . $file['name'])) {
+ $this->_throw($file, self::DOES_EXIST);
+ return false;
+ }
+ }
+
+ if (!isset($check)) {
+ $this->_throw($file, self::DOES_EXIST);
+ return false;
+ }
+
+ return true;
+ }
+}
diff --git a/site/vendors/phpQuery/Zend/Validate/File/Size.php b/site/vendors/phpQuery/Zend/Validate/File/Size.php
new file mode 100644
index 0000000..2adaeb3
--- /dev/null
+++ b/site/vendors/phpQuery/Zend/Validate/File/Size.php
@@ -0,0 +1,308 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Validate
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id: $
+ */
+
+/**
+ * @see Zend_Validate_Abstract
+ */
+require_once 'Zend/Validate/Abstract.php';
+
+/**
+ * Validator for the maximum size of a file up to a max of 2GB
+ *
+ * @category Zend
+ * @package Zend_Validate
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Validate_File_Size extends Zend_Validate_Abstract
+{
+ /**#@+
+ * @const string Error constants
+ */
+ const TOO_BIG = 'fileSizeTooBig';
+ const TOO_SMALL = 'fileSizeTooSmall';
+ const NOT_FOUND = 'fileSizeNotFound';
+ /**#@-*/
+
+ /**
+ * @var array Error message templates
+ */
+ protected $_messageTemplates = array(
+ self::TOO_BIG => "The file '%value%' is bigger than allowed",
+ self::TOO_SMALL => "The file '%value%' is smaller than allowed",
+ self::NOT_FOUND => "The file '%value%' could not be found"
+ );
+
+ /**
+ * @var array Error message template variables
+ */
+ protected $_messageVariables = array(
+ 'min' => '_min',
+ 'max' => '_max'
+ );
+
+ /**
+ * Minimum filesize
+ * @var integer
+ */
+ protected $_min;
+
+ /**
+ * Maximum filesize
+ *
+ * If null, there is no maximum filesize
+ *
+ * @var integer|null
+ */
+ protected $_max;
+
+ /**
+ * Sets validator options
+ *
+ * Min limits the filesize, when used with max=null it is the maximum filesize
+ * It also accepts an array with the keys 'min' and 'max'
+ *
+ * @param integer|array $min Minimum filesize
+ * @param integer $max Maximum filesize
+ * @return void
+ */
+ public function __construct($min, $max = null)
+ {
+ if (is_array($min)) {
+ $count = count($min);
+ if (array_key_exists('min', $min)) {
+ if (array_key_exists('max', $min)) {
+ $max = $min['max'];
+ }
+
+ $min = $min['min'];
+ } elseif ($count === 2) {
+ $minValue = array_shift($min);
+ $max = array_shift($min);
+ $min = $minValue;
+ } elseif($count === 1) {
+ $min = array_shift($min);
+ $max = null;
+ } else {
+ $min = 0;
+ $max = null;
+ }
+ }
+
+ if (empty($max)) {
+ $max = $min;
+ $min = 0;
+ }
+
+ $this->setMin($min);
+ $this->setMax($max);
+ }
+
+ /**
+ * Returns the minimum filesize
+ *
+ * @param boolean $unit Return the value with unit, when false the plan bytes will be returned
+ * @return integer
+ */
+ public function getMin($unit = true)
+ {
+ $unit = (bool) $unit;
+ $min = $this->_min;
+ if ($unit) {
+ $min = $this->_toByteString($min);
+ }
+ return $min;
+ }
+
+ /**
+ * Sets the minimum filesize
+ *
+ * @param integer $min The minimum filesize
+ * @return Zend_Validate_File_Size Provides a fluent interface
+ * @throws Zend_Validate_Exception When min is greater than max
+ */
+ public function setMin($min)
+ {
+ $min = (integer) $this->_fromByteString($min);
+ if (($this->_max !== null) && ($min > $this->_max)) {
+ require_once 'Zend/Validate/Exception.php';
+ throw new Zend_Validate_Exception("The minimum must be less than or equal to the maximum filesize, but $min >"
+ . " {$this->_max}");
+ }
+
+ $this->_min = max(0, $min);
+ return $this;
+ }
+
+ /**
+ * Returns the maximum filesize
+ *
+ * @param boolean $unit Return the value with unit, when false the plan bytes will be returned
+ * @return integer|null
+ */
+ public function getMax($unit = true)
+ {
+ $unit = (bool) $unit;
+ $max = $this->_max;
+ if ($unit) {
+ $max = $this->_toByteString($max);
+ }
+ return $max;
+ }
+
+ /**
+ * Sets the maximum filesize
+ *
+ * @param integer|null $max The maximum filesize
+ * @return Zend_Validate_StringLength Provides a fluent interface
+ * @throws Zend_Validate_Exception When max is smaller than min
+ */
+ public function setMax($max)
+ {
+ $max = (integer) $this->_fromByteString($max);
+ if (($this->_min !== null) && ($max < $this->_min)) {
+ require_once 'Zend/Validate/Exception.php';
+ throw new Zend_Validate_Exception("The maximum must be greater than or equal to the minimum filesize, but "
+ . "$max < {$this->_min}");
+ } else {
+ $this->_max = $max;
+ }
+
+ return $this;
+ }
+
+ /**
+ * Defined by Zend_Validate_Interface
+ *
+ * Returns true if and only if the filesize of $value is at least min and
+ * not bigger than max (when max is not null).
+ *
+ * @param string $value Real file to check for size
+ * @param array $file File data from Zend_File_Transfer
+ * @return boolean
+ */
+ public function isValid($value, $file = null)
+ {
+ // Is file readable ?
+ if (!@is_readable($value)) {
+ $this->_throw($file, self::NOT_FOUND);
+ return false;
+ }
+
+ // limited to 4GB files
+ $size = sprintf("%u",@filesize($value));
+ $this->_setValue($size);
+
+ // Check to see if it's smaller than min size
+ if (($this->_min !== null) && ($size < $this->_min)) {
+ $this->_throw($file, self::TOO_SMALL);
+ }
+
+ // Check to see if it's larger than max size
+ if (($this->_max !== null) && ($this->_max < $size)) {
+ $this->_throw($file, self::TOO_BIG);
+ }
+
+ if (count($this->_messages) > 0) {
+ return false;
+ } else {
+ return true;
+ }
+ }
+
+ /**
+ * Returns the formatted size
+ *
+ * @param integer $size
+ * @return string
+ */
+ protected function _toByteString($size)
+ {
+ $sizes = array('B', 'kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB');
+ for ($i=0; $size > 1024 && $i < 9; $i++) {
+ $size /= 1024;
+ }
+ return round($size, 2).$sizes[$i];
+ }
+
+ /**
+ * Returns the unformatted size
+ *
+ * @param string $size
+ * @return integer
+ */
+ protected function _fromByteString($size)
+ {
+ if (is_numeric($size)) {
+ return (integer) $size;
+ }
+
+ $type = trim(substr($size, -2));
+ $value = substr($size, 0, -2);
+ switch (strtoupper($type)) {
+ case 'YB':
+ $value *= (1024 * 1024 * 1024 * 1024 * 1024 * 1024 * 1024 * 1024);
+ break;
+ case 'ZB':
+ $value *= (1024 * 1024 * 1024 * 1024 * 1024 * 1024 * 1024);
+ break;
+ case 'EB':
+ $value *= (1024 * 1024 * 1024 * 1024 * 1024 * 1024);
+ break;
+ case 'PB':
+ $value *= (1024 * 1024 * 1024 * 1024 * 1024);
+ break;
+ case 'TB':
+ $value *= (1024 * 1024 * 1024 * 1024);
+ break;
+ case 'GB':
+ $value *= (1024 * 1024 * 1024);
+ break;
+ case 'MB':
+ $value *= (1024 * 1024);
+ break;
+ case 'KB':
+ $value *= 1024;
+ break;
+ default:
+ break;
+ }
+
+ return $value;
+ }
+
+ /**
+ * Throws an error of the given type
+ *
+ * @param string $file
+ * @param string $errorType
+ * @return false
+ */
+ protected function _throw($file, $errorType)
+ {
+ if ($file !== null) {
+ $this->_value = $file['name'];
+ }
+
+ $this->_error($errorType);
+ return false;
+ }
+}
diff --git a/site/vendors/phpQuery/Zend/Validate/File/Upload.php b/site/vendors/phpQuery/Zend/Validate/File/Upload.php
new file mode 100644
index 0000000..a56cf14
--- /dev/null
+++ b/site/vendors/phpQuery/Zend/Validate/File/Upload.php
@@ -0,0 +1,216 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Validate
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id: $
+ */
+
+/**
+ * @see Zend_Validate_Abstract
+ */
+require_once 'Zend/Validate/Abstract.php';
+
+/**
+ * Validator for the maximum size of a file up to a max of 2GB
+ *
+ * @category Zend
+ * @package Zend_Validate
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Validate_File_Upload extends Zend_Validate_Abstract
+{
+ /**@#+
+ * @const string Error constants
+ */
+ const INI_SIZE = 'fileUploadErrorIniSize';
+ const FORM_SIZE = 'fileUploadErrorFormSize';
+ const PARTIAL = 'fileUploadErrorPartial';
+ const NO_FILE = 'fileUploadErrorNoFile';
+ const NO_TMP_DIR = 'fileUploadErrorNoTmpDir';
+ const CANT_WRITE = 'fileUploadErrorCantWrite';
+ const EXTENSION = 'fileUploadErrorExtension';
+ const ATTACK = 'fileUploadErrorAttack';
+ const FILE_NOT_FOUND = 'fileUploadErrorFileNotFound';
+ const UNKNOWN = 'fileUploadErrorUnknown';
+ /**@#-*/
+
+ /**
+ * @var array Error message templates
+ */
+ protected $_messageTemplates = array(
+ self::INI_SIZE => "The file '%value%' exceeds the defined ini size",
+ self::FORM_SIZE => "The file '%value%' exceeds the defined form size",
+ self::PARTIAL => "The file '%value%' was only partially uploaded",
+ self::NO_FILE => "The file '%value%' was not uploaded",
+ self::NO_TMP_DIR => "No temporary directory was found for the file '%value%'",
+ self::CANT_WRITE => "The file '%value%' can't be written",
+ self::EXTENSION => "The extension returned an error while uploading the file '%value%'",
+ self::ATTACK => "The file '%value%' was illegal uploaded, possible attack",
+ self::FILE_NOT_FOUND => "The file '%value%' was not found",
+ self::UNKNOWN => "Unknown error while uploading the file '%value%'"
+ );
+
+ /**
+ * Internal array of files
+ * @var array
+ */
+ protected $_files = array();
+
+ /**
+ * Sets validator options
+ *
+ * The array $files must be given in syntax of Zend_File_Transfer to be checked
+ * If no files are given the $_FILES array will be used automatically.
+ * NOTE: This validator will only work with HTTP POST uploads!
+ *
+ * @param array $files Array of files in syntax of Zend_File_Transfer
+ * @return void
+ */
+ public function __construct($files = array())
+ {
+ $this->setFiles($files);
+ }
+
+ /**
+ * Returns the array of set files
+ *
+ * @param string $files (Optional) The file to return in detail
+ * @return array
+ * @throws Zend_Validate_Exception If file is not found
+ */
+ public function getFiles($file = null)
+ {
+ if ($file !== null) {
+ $return = array();
+ foreach ($this->_files as $name => $content) {
+ if ($name === $file) {
+ $return[$file] = $this->_files[$name];
+ }
+
+ if ($content['name'] === $file) {
+ $return[$name] = $this->_files[$name];
+ }
+ }
+
+ if (count($return) === 0) {
+ require_once 'Zend/Validate/Exception.php';
+ throw new Zend_Validate_Exception("The file '$file' was not found");
+ }
+
+ return $return;
+ }
+
+ return $this->_files;
+ }
+
+ /**
+ * Sets the minimum filesize
+ *
+ * @param array $files The files to check in syntax of Zend_File_Transfer
+ * @return Zend_Validate_File_Upload Provides a fluent interface
+ */
+ public function setFiles($files = array())
+ {
+ if (count($files) === 0) {
+ $this->_files = $_FILES;
+ } else {
+ $this->_files = $files;
+ }
+ return $this;
+ }
+
+ /**
+ * Defined by Zend_Validate_Interface
+ *
+ * Returns true if and only if the file was uploaded without errors
+ *
+ * @param string $value Single file to check for upload errors, when giving null the $_FILES array
+ * from initialization will be used
+ * @return boolean
+ */
+ public function isValid($value)
+ {
+ if (array_key_exists($value, $this->_files)) {
+ $files[$value] = $this->_files[$value];
+ } else {
+ foreach ($this->_files as $file => $content) {
+ if ($content['name'] === $value) {
+ $files[$file] = $this->_files[$file];
+ }
+
+ if ($content['tmp_name'] === $value) {
+ $files[$file] = $this->_files[$file];
+ }
+ }
+ }
+
+ if (empty($files)) {
+ $this->_error(self::FILE_NOT_FOUND);
+ return false;
+ }
+
+ foreach ($files as $file => $content) {
+ $this->_value = $file;
+ switch($content['error']) {
+ case 0:
+ if (!is_uploaded_file($content['tmp_name'])) {
+ $this->_error(self::ATTACK);
+ }
+ break;
+
+ case 1:
+ $this->_error(self::INI_SIZE);
+ break;
+
+ case 2:
+ $this->_error(self::FORM_SIZE);
+ break;
+
+ case 3:
+ $this->_error(self::PARTIAL);
+ break;
+
+ case 4:
+ $this->_error(self::NO_FILE);
+ break;
+
+ case 6:
+ $this->_error(self::NO_TMP_DIR);
+ break;
+
+ case 7:
+ $this->_error(self::CANT_WRITE);
+ break;
+
+ case 8:
+ $this->_error(self::EXTENSION);
+ break;
+
+ default:
+ $this->_error(self::UNKNOWN);
+ break;
+ }
+ }
+
+ if (count($this->_messages) > 0) {
+ return false;
+ } else {
+ return true;
+ }
+ }
+}
diff --git a/site/vendors/phpQuery/Zend/Validate/Float.php b/site/vendors/phpQuery/Zend/Validate/Float.php
new file mode 100644
index 0000000..0405161
--- /dev/null
+++ b/site/vendors/phpQuery/Zend/Validate/Float.php
@@ -0,0 +1,75 @@
+<?php
+
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Validate
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id: Float.php 8714 2008-03-09 20:03:45Z thomas $
+ */
+
+
+/**
+ * @see Zend_Validate_Abstract
+ */
+require_once 'Zend/Validate/Abstract.php';
+
+
+/**
+ * @category Zend
+ * @package Zend_Validate
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Validate_Float extends Zend_Validate_Abstract
+{
+
+ const NOT_FLOAT = 'notFloat';
+
+ /**
+ * @var array
+ */
+ protected $_messageTemplates = array(
+ self::NOT_FLOAT => "'%value%' does not appear to be a float"
+ );
+
+ /**
+ * Defined by Zend_Validate_Interface
+ *
+ * Returns true if and only if $value is a floating-point value
+ *
+ * @param string $value
+ * @return boolean
+ */
+ public function isValid($value)
+ {
+ $valueString = (string) $value;
+
+ $this->_setValue($valueString);
+
+ $locale = localeconv();
+
+ $valueFiltered = str_replace($locale['thousands_sep'], '', $valueString);
+ $valueFiltered = str_replace($locale['decimal_point'], '.', $valueFiltered);
+
+ if (strval(floatval($valueFiltered)) != $valueFiltered) {
+ $this->_error();
+ return false;
+ }
+
+ return true;
+ }
+
+}
diff --git a/site/vendors/phpQuery/Zend/Validate/GreaterThan.php b/site/vendors/phpQuery/Zend/Validate/GreaterThan.php
new file mode 100644
index 0000000..35e658c
--- /dev/null
+++ b/site/vendors/phpQuery/Zend/Validate/GreaterThan.php
@@ -0,0 +1,114 @@
+<?php
+
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Validate
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id: GreaterThan.php 8064 2008-02-16 10:58:39Z thomas $
+ */
+
+
+/**
+ * @see Zend_Validate_Abstract
+ */
+require_once 'Zend/Validate/Abstract.php';
+
+
+/**
+ * @category Zend
+ * @package Zend_Validate
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Validate_GreaterThan extends Zend_Validate_Abstract
+{
+
+ const NOT_GREATER = 'notGreaterThan';
+
+ /**
+ * @var array
+ */
+ protected $_messageTemplates = array(
+ self::NOT_GREATER => "'%value%' is not greater than '%min%'"
+ );
+
+ /**
+ * @var array
+ */
+ protected $_messageVariables = array(
+ 'min' => '_min'
+ );
+
+ /**
+ * Minimum value
+ *
+ * @var mixed
+ */
+ protected $_min;
+
+ /**
+ * Sets validator options
+ *
+ * @param mixed $min
+ * @return void
+ */
+ public function __construct($min)
+ {
+ $this->setMin($min);
+ }
+
+ /**
+ * Returns the min option
+ *
+ * @return mixed
+ */
+ public function getMin()
+ {
+ return $this->_min;
+ }
+
+ /**
+ * Sets the min option
+ *
+ * @param mixed $min
+ * @return Zend_Validate_GreaterThan Provides a fluent interface
+ */
+ public function setMin($min)
+ {
+ $this->_min = $min;
+ return $this;
+ }
+
+ /**
+ * Defined by Zend_Validate_Interface
+ *
+ * Returns true if and only if $value is greater than min option
+ *
+ * @param mixed $value
+ * @return boolean
+ */
+ public function isValid($value)
+ {
+ $this->_setValue($value);
+
+ if ($this->_min >= $value) {
+ $this->_error();
+ return false;
+ }
+ return true;
+ }
+
+}
diff --git a/site/vendors/phpQuery/Zend/Validate/Hex.php b/site/vendors/phpQuery/Zend/Validate/Hex.php
new file mode 100644
index 0000000..9512eda
--- /dev/null
+++ b/site/vendors/phpQuery/Zend/Validate/Hex.php
@@ -0,0 +1,74 @@
+<?php
+
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Validate
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id: Hex.php 8064 2008-02-16 10:58:39Z thomas $
+ */
+
+
+/**
+ * @see Zend_Validate_Abstract
+ */
+require_once 'Zend/Validate/Abstract.php';
+
+
+/**
+ * @category Zend
+ * @package Zend_Validate
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Validate_Hex extends Zend_Validate_Abstract
+{
+ /**
+ * Validation failure message key for when the value contains characters other than hexadecimal digits
+ */
+ const NOT_HEX = 'notHex';
+
+ /**
+ * Validation failure message template definitions
+ *
+ * @var array
+ */
+ protected $_messageTemplates = array(
+ self::NOT_HEX => "'%value%' has not only hexadecimal digit characters"
+ );
+
+ /**
+ * Defined by Zend_Validate_Interface
+ *
+ * Returns true if and only if $value contains only hexadecimal digit characters
+ *
+ * @param string $value
+ * @return boolean
+ */
+ public function isValid($value)
+ {
+ $valueString = (string) $value;
+
+ $this->_setValue($valueString);
+
+ if (!ctype_xdigit($valueString)) {
+ $this->_error();
+ return false;
+ }
+
+ return true;
+ }
+
+}
diff --git a/site/vendors/phpQuery/Zend/Validate/Hostname.php b/site/vendors/phpQuery/Zend/Validate/Hostname.php
new file mode 100644
index 0000000..ea79c24
--- /dev/null
+++ b/site/vendors/phpQuery/Zend/Validate/Hostname.php
@@ -0,0 +1,444 @@
+<?php
+
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Validate
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id: Hostname.php 9195 2008-04-10 17:35:30Z jokke $
+ */
+
+
+/**
+ * @see Zend_Validate_Abstract
+ */
+require_once 'Zend/Validate/Abstract.php';
+
+/**
+ * @see Zend_Loader
+ */
+require_once 'Zend/Loader.php';
+
+/**
+ * @see Zend_Validate_Ip
+ */
+require_once 'Zend/Validate/Ip.php';
+
+/**
+ * Please note there are two standalone test scripts for testing IDN characters due to problems
+ * with file encoding.
+ *
+ * The first is tests/Zend/Validate/HostnameTestStandalone.php which is designed to be run on
+ * the command line.
+ *
+ * The second is tests/Zend/Validate/HostnameTestForm.php which is designed to be run via HTML
+ * to allow users to test entering UTF-8 characters in a form.
+ *
+ * @category Zend
+ * @package Zend_Validate
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Validate_Hostname extends Zend_Validate_Abstract
+{
+
+ const IP_ADDRESS_NOT_ALLOWED = 'hostnameIpAddressNotAllowed';
+ const UNKNOWN_TLD = 'hostnameUnknownTld';
+ const INVALID_DASH = 'hostnameDashCharacter';
+ const INVALID_HOSTNAME_SCHEMA = 'hostnameInvalidHostnameSchema';
+ const UNDECIPHERABLE_TLD = 'hostnameUndecipherableTld';
+ const INVALID_HOSTNAME = 'hostnameInvalidHostname';
+ const INVALID_LOCAL_NAME = 'hostnameInvalidLocalName';
+ const LOCAL_NAME_NOT_ALLOWED = 'hostnameLocalNameNotAllowed';
+
+ /**
+ * @var array
+ */
+ protected $_messageTemplates = array(
+ self::IP_ADDRESS_NOT_ALLOWED => "'%value%' appears to be an IP address, but IP addresses are not allowed",
+ self::UNKNOWN_TLD => "'%value%' appears to be a DNS hostname but cannot match TLD against known list",
+ self::INVALID_DASH => "'%value%' appears to be a DNS hostname but contains a dash (-) in an invalid position",
+ self::INVALID_HOSTNAME_SCHEMA => "'%value%' appears to be a DNS hostname but cannot match against hostname schema for TLD '%tld%'",
+ self::UNDECIPHERABLE_TLD => "'%value%' appears to be a DNS hostname but cannot extract TLD part",
+ self::INVALID_HOSTNAME => "'%value%' does not match the expected structure for a DNS hostname",
+ self::INVALID_LOCAL_NAME => "'%value%' does not appear to be a valid local network name",
+ self::LOCAL_NAME_NOT_ALLOWED => "'%value%' appears to be a local network name but local network names are not allowed"
+ );
+
+ /**
+ * @var array
+ */
+ protected $_messageVariables = array(
+ 'tld' => '_tld'
+ );
+
+ /**
+ * Allows Internet domain names (e.g., example.com)
+ */
+ const ALLOW_DNS = 1;
+
+ /**
+ * Allows IP addresses
+ */
+ const ALLOW_IP = 2;
+
+ /**
+ * Allows local network names (e.g., localhost, www.localdomain)
+ */
+ const ALLOW_LOCAL = 4;
+
+ /**
+ * Allows all types of hostnames
+ */
+ const ALLOW_ALL = 7;
+
+ /**
+ * Whether IDN domains are validated
+ *
+ * @var boolean
+ */
+ private $_validateIdn = true;
+
+ /**
+ * Whether TLDs are validated against a known list
+ *
+ * @var boolean
+ */
+ private $_validateTld = true;
+
+ /**
+ * Bit field of ALLOW constants; determines which types of hostnames are allowed
+ *
+ * @var integer
+ */
+ protected $_allow;
+
+ /**
+ * Bit field of CHECK constants; determines what additional hostname checks to make
+ *
+ * @var unknown_type
+ */
+ // protected $_check;
+
+ /**
+ * Array of valid top-level-domains
+ *
+ * @var array
+ * @see ftp://data.iana.org/TLD/tlds-alpha-by-domain.txt List of all TLDs by domain
+ */
+ protected $_validTlds = array(
+ 'ac', 'ad', 'ae', 'aero', 'af', 'ag', 'ai', 'al', 'am', 'an', 'ao',
+ 'aq', 'ar', 'arpa', 'as', 'asia', 'at', 'au', 'aw', 'ax', 'az', 'ba', 'bb',
+ 'bd', 'be', 'bf', 'bg', 'bh', 'bi', 'biz', 'bj', 'bm', 'bn', 'bo',
+ 'br', 'bs', 'bt', 'bv', 'bw', 'by', 'bz', 'ca', 'cat', 'cc', 'cd',
+ 'cf', 'cg', 'ch', 'ci', 'ck', 'cl', 'cm', 'cn', 'co', 'com', 'coop',
+ 'cr', 'cu', 'cv', 'cx', 'cy', 'cz', 'de', 'dj', 'dk', 'dm', 'do',
+ 'dz', 'ec', 'edu', 'ee', 'eg', 'er', 'es', 'et', 'eu', 'fi', 'fj',
+ 'fk', 'fm', 'fo', 'fr', 'ga', 'gb', 'gd', 'ge', 'gf', 'gg', 'gh',
+ 'gi', 'gl', 'gm', 'gn', 'gov', 'gp', 'gq', 'gr', 'gs', 'gt', 'gu',
+ 'gw', 'gy', 'hk', 'hm', 'hn', 'hr', 'ht', 'hu', 'id', 'ie', 'il',
+ 'im', 'in', 'info', 'int', 'io', 'iq', 'ir', 'is', 'it', 'je', 'jm',
+ 'jo', 'jobs', 'jp', 'ke', 'kg', 'kh', 'ki', 'km', 'kn', 'kp', 'kr', 'kw',
+ 'ky', 'kz', 'la', 'lb', 'lc', 'li', 'lk', 'lr', 'ls', 'lt', 'lu',
+ 'lv', 'ly', 'ma', 'mc', 'md', 'me', 'mg', 'mh', 'mil', 'mk', 'ml', 'mm',
+ 'mn', 'mo', 'mobi', 'mp', 'mq', 'mr', 'ms', 'mt', 'mu', 'museum', 'mv',
+ 'mw', 'mx', 'my', 'mz', 'na', 'name', 'nc', 'ne', 'net', 'nf', 'ng',
+ 'ni', 'nl', 'no', 'np', 'nr', 'nu', 'nz', 'om', 'org', 'pa', 'pe',
+ 'pf', 'pg', 'ph', 'pk', 'pl', 'pm', 'pn', 'pr', 'pro', 'ps', 'pt',
+ 'pw', 'py', 'qa', 're', 'ro', 'rs', 'ru', 'rw', 'sa', 'sb', 'sc', 'sd',
+ 'se', 'sg', 'sh', 'si', 'sj', 'sk', 'sl', 'sm', 'sn', 'so', 'sr',
+ 'st', 'su', 'sv', 'sy', 'sz', 'tc', 'td', 'tel', 'tf', 'tg', 'th', 'tj',
+ 'tk', 'tl', 'tm', 'tn', 'to', 'tp', 'tr', 'travel', 'tt', 'tv', 'tw',
+ 'tz', 'ua', 'ug', 'uk', 'um', 'us', 'uy', 'uz', 'va', 'vc', 've',
+ 'vg', 'vi', 'vn', 'vu', 'wf', 'ws', 'ye', 'yt', 'yu', 'za', 'zm',
+ 'zw'
+ );
+
+ /**
+ * @var string
+ */
+ protected $_tld;
+
+ /**
+ * Sets validator options
+ *
+ * @param integer $allow OPTIONAL Set what types of hostname to allow (default ALLOW_DNS)
+ * @param boolean $validateIdn OPTIONAL Set whether IDN domains are validated (default true)
+ * @param boolean $validateTld OPTIONAL Set whether the TLD element of a hostname is validated (default true)
+ * @param Zend_Validate_Ip $ipValidator OPTIONAL
+ * @return void
+ * @see http://www.iana.org/cctld/specifications-policies-cctlds-01apr02.htm Technical Specifications for ccTLDs
+ */
+ public function __construct($allow = self::ALLOW_DNS, $validateIdn = true, $validateTld = true, Zend_Validate_Ip $ipValidator = null)
+ {
+ // Set allow options
+ $this->setAllow($allow);
+
+ // Set validation options
+ $this->_validateIdn = $validateIdn;
+ $this->_validateTld = $validateTld;
+
+ $this->setIpValidator($ipValidator);
+ }
+
+ /**
+ * @param Zend_Validate_Ip $ipValidator OPTIONAL
+ * @return void;
+ */
+ public function setIpValidator(Zend_Validate_Ip $ipValidator = null)
+ {
+ if ($ipValidator === null) {
+ $ipValidator = new Zend_Validate_Ip();
+ }
+ $this->_ipValidator = $ipValidator;
+ }
+
+ /**
+ * Returns the allow option
+ *
+ * @return integer
+ */
+ public function getAllow()
+ {
+ return $this->_allow;
+ }
+
+ /**
+ * Sets the allow option
+ *
+ * @param integer $allow
+ * @return Zend_Validate_Hostname Provides a fluent interface
+ */
+ public function setAllow($allow)
+ {
+ $this->_allow = $allow;
+ return $this;
+ }
+
+ /**
+ * Set whether IDN domains are validated
+ *
+ * This only applies when DNS hostnames are validated
+ *
+ * @param boolean $allowed Set allowed to true to validate IDNs, and false to not validate them
+ */
+ public function setValidateIdn ($allowed)
+ {
+ $this->_validateIdn = (bool) $allowed;
+ }
+
+ /**
+ * Set whether the TLD element of a hostname is validated
+ *
+ * This only applies when DNS hostnames are validated
+ *
+ * @param boolean $allowed Set allowed to true to validate TLDs, and false to not validate them
+ */
+ public function setValidateTld ($allowed)
+ {
+ $this->_validateTld = (bool) $allowed;
+ }
+
+ /**
+ * Sets the check option
+ *
+ * @param integer $check
+ * @return Zend_Validate_Hostname Provides a fluent interface
+ */
+ /*
+ public function setCheck($check)
+ {
+ $this->_check = $check;
+ return $this;
+ }
+ */
+
+ /**
+ * Defined by Zend_Validate_Interface
+ *
+ * Returns true if and only if the $value is a valid hostname with respect to the current allow option
+ *
+ * @param string $value
+ * @throws Zend_Validate_Exception if a fatal error occurs for validation process
+ * @return boolean
+ */
+ public function isValid($value)
+ {
+ $valueString = (string) $value;
+
+ $this->_setValue($valueString);
+
+ // Check input against IP address schema
+ if ($this->_ipValidator->setTranslator($this->getTranslator())->isValid($valueString)) {
+ if (!($this->_allow & self::ALLOW_IP)) {
+ $this->_error(self::IP_ADDRESS_NOT_ALLOWED);
+ return false;
+ } else{
+ return true;
+ }
+ }
+
+ // Check input against DNS hostname schema
+ $domainParts = explode('.', $valueString);
+ if ((count($domainParts) > 1) && (strlen($valueString) >= 4) && (strlen($valueString) <= 254)) {
+ $status = false;
+
+ do {
+ // First check TLD
+ if (preg_match('/([a-z]{2,10})$/i', end($domainParts), $matches)) {
+
+ reset($domainParts);
+
+ // Hostname characters are: *(label dot)(label dot label); max 254 chars
+ // label: id-prefix [*ldh{61} id-prefix]; max 63 chars
+ // id-prefix: alpha / digit
+ // ldh: alpha / digit / dash
+
+ // Match TLD against known list
+ $this->_tld = strtolower($matches[1]);
+ if ($this->_validateTld) {
+ if (!in_array($this->_tld, $this->_validTlds)) {
+ $this->_error(self::UNKNOWN_TLD);
+ $status = false;
+ break;
+ }
+ }
+
+ /**
+ * Match against IDN hostnames
+ * @see Zend_Validate_Hostname_Interface
+ */
+ $labelChars = 'a-z0-9';
+ $utf8 = false;
+ $classFile = 'Zend/Validate/Hostname/' . ucfirst($this->_tld) . '.php';
+ if ($this->_validateIdn) {
+ if (Zend_Loader::isReadable($classFile)) {
+
+ // Load additional characters
+ $className = 'Zend_Validate_Hostname_' . ucfirst($this->_tld);
+ Zend_Loader::loadClass($className);
+ $labelChars .= call_user_func(array($className, 'getCharacters'));
+ $utf8 = true;
+ }
+ }
+
+ // Keep label regex short to avoid issues with long patterns when matching IDN hostnames
+ $regexLabel = '/^[' . $labelChars . '\x2d]{1,63}$/i';
+ if ($utf8) {
+ $regexLabel .= 'u';
+ }
+
+ // Check each hostname part
+ $valid = true;
+ foreach ($domainParts as $domainPart) {
+
+ // Check dash (-) does not start, end or appear in 3rd and 4th positions
+ if (strpos($domainPart, '-') === 0 ||
+ (strlen($domainPart) > 2 && strpos($domainPart, '-', 2) == 2 && strpos($domainPart, '-', 3) == 3) ||
+ strrpos($domainPart, '-') === strlen($domainPart) - 1) {
+
+ $this->_error(self::INVALID_DASH);
+ $status = false;
+ break 2;
+ }
+
+ // Check each domain part
+ $status = @preg_match($regexLabel, $domainPart);
+ if ($status === false) {
+ /**
+ * Regex error
+ * @see Zend_Validate_Exception
+ */
+ require_once 'Zend/Validate/Exception.php';
+ throw new Zend_Validate_Exception('Internal error: DNS validation failed');
+ } elseif ($status === 0) {
+ $valid = false;
+ }
+ }
+
+ // If all labels didn't match, the hostname is invalid
+ if (!$valid) {
+ $this->_error(self::INVALID_HOSTNAME_SCHEMA);
+ $status = false;
+ }
+
+ } else {
+ // Hostname not long enough
+ $this->_error(self::UNDECIPHERABLE_TLD);
+ $status = false;
+ }
+ } while (false);
+
+ // If the input passes as an Internet domain name, and domain names are allowed, then the hostname
+ // passes validation
+ if ($status && ($this->_allow & self::ALLOW_DNS)) {
+ return true;
+ }
+ } else {
+ $this->_error(self::INVALID_HOSTNAME);
+ }
+
+ // Check input against local network name schema; last chance to pass validation
+ $regexLocal = '/^(([a-zA-Z0-9\x2d]{1,63}\x2e)*[a-zA-Z0-9\x2d]{1,63}){1,254}$/';
+ $status = @preg_match($regexLocal, $valueString);
+ if (false === $status) {
+ /**
+ * Regex error
+ * @see Zend_Validate_Exception
+ */
+ require_once 'Zend/Validate/Exception.php';
+ throw new Zend_Validate_Exception('Internal error: local network name validation failed');
+ }
+
+ // If the input passes as a local network name, and local network names are allowed, then the
+ // hostname passes validation
+ $allowLocal = $this->_allow & self::ALLOW_LOCAL;
+ if ($status && $allowLocal) {
+ return true;
+ }
+
+ // If the input does not pass as a local network name, add a message
+ if (!$status) {
+ $this->_error(self::INVALID_LOCAL_NAME);
+ }
+
+ // If local network names are not allowed, add a message
+ if ($status && !$allowLocal) {
+ $this->_error(self::LOCAL_NAME_NOT_ALLOWED);
+ }
+
+ return false;
+ }
+
+ /**
+ * Throws an exception if a regex for $type does not exist
+ *
+ * @param string $type
+ * @throws Zend_Validate_Exception
+ * @return Zend_Validate_Hostname Provides a fluent interface
+ */
+ /*
+ protected function _checkRegexType($type)
+ {
+ if (!isset($this->_regex[$type])) {
+ require_once 'Zend/Validate/Exception.php';
+ throw new Zend_Validate_Exception("'$type' must be one of ('" . implode(', ', array_keys($this->_regex))
+ . "')");
+ }
+ return $this;
+ }
+ */
+
+}
diff --git a/site/vendors/phpQuery/Zend/Validate/Hostname/At.php b/site/vendors/phpQuery/Zend/Validate/Hostname/At.php
new file mode 100644
index 0000000..fff6bf2
--- /dev/null
+++ b/site/vendors/phpQuery/Zend/Validate/Hostname/At.php
@@ -0,0 +1,50 @@
+<?php
+
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Validate
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id: At.php 8064 2008-02-16 10:58:39Z thomas $
+ */
+
+
+/**
+ * @see Zend_Validate_Hostname_Interface
+ */
+require_once 'Zend/Validate/Hostname/Interface.php';
+
+
+/**
+ * @category Zend
+ * @package Zend_Validate
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Validate_Hostname_At implements Zend_Validate_Hostname_Interface
+{
+
+ /**
+ * Returns UTF-8 characters allowed in DNS hostnames for the specified Top-Level-Domain
+ *
+ * @see http://www.nic.at/en/service/technical_information/idn/charset_converter/ Austria (.AT)
+ * @return string
+ */
+ static function getCharacters()
+ {
+ return '\x{00EO}-\x{00F6}\x{00F8}-\x{00FF}\x{0153}\x{0161}\x{017E}';
+ }
+
+} \ No newline at end of file
diff --git a/site/vendors/phpQuery/Zend/Validate/Hostname/Ch.php b/site/vendors/phpQuery/Zend/Validate/Hostname/Ch.php
new file mode 100644
index 0000000..72fae7b
--- /dev/null
+++ b/site/vendors/phpQuery/Zend/Validate/Hostname/Ch.php
@@ -0,0 +1,50 @@
+<?php
+
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Validate
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id: Ch.php 8064 2008-02-16 10:58:39Z thomas $
+ */
+
+
+/**
+ * @see Zend_Validate_Hostname_Interface
+ */
+require_once 'Zend/Validate/Hostname/Interface.php';
+
+
+/**
+ * @category Zend
+ * @package Zend_Validate
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Validate_Hostname_Ch implements Zend_Validate_Hostname_Interface
+{
+
+ /**
+ * Returns UTF-8 characters allowed in DNS hostnames for the specified Top-Level-Domain
+ *
+ * @see https://nic.switch.ch/reg/ocView.action?res=EF6GW2JBPVTG67DLNIQXU234MN6SC33JNQQGI7L6#anhang1 Switzerland (.CH)
+ * @return string
+ */
+ static function getCharacters()
+ {
+ return '\x{00EO}-\x{00F6}\x{00F8}-\x{00FF}\x{0153}';
+ }
+
+} \ No newline at end of file
diff --git a/site/vendors/phpQuery/Zend/Validate/Hostname/De.php b/site/vendors/phpQuery/Zend/Validate/Hostname/De.php
new file mode 100644
index 0000000..cfea068
--- /dev/null
+++ b/site/vendors/phpQuery/Zend/Validate/Hostname/De.php
@@ -0,0 +1,58 @@
+<?php
+
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Validate
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id: De.php 8064 2008-02-16 10:58:39Z thomas $
+ */
+
+
+/**
+ * @see Zend_Validate_Hostname_Interface
+ */
+require_once 'Zend/Validate/Hostname/Interface.php';
+
+
+/**
+ * @category Zend
+ * @package Zend_Validate
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Validate_Hostname_De implements Zend_Validate_Hostname_Interface
+{
+
+ /**
+ * Returns UTF-8 characters allowed in DNS hostnames for the specified Top-Level-Domain
+ *
+ * @see http://www.denic.de/en/domains/idns/liste.html Germany (.DE) alllowed characters
+ * @return string
+ */
+ static function getCharacters()
+ {
+ return '\x{00E1}\x{00E0}\x{0103}\x{00E2}\x{00E5}\x{00E4}\x{00E3}\x{0105}\x{0101}\x{00E6}\x{0107}' .
+ '\x{0109}\x{010D}\x{010B}\x{00E7}\x{010F}\x{0111}\x{00E9}\x{00E8}\x{0115}\x{00EA}\x{011B}' .
+ '\x{00EB}\x{0117}\x{0119}\x{0113}\x{011F}\x{011D}\x{0121}\x{0123}\x{0125}\x{0127}\x{00ED}' .
+ '\x{00EC}\x{012D}\x{00EE}\x{00EF}\x{0129}\x{012F}\x{012B}\x{0131}\x{0135}\x{0137}\x{013A}' .
+ '\x{013E}\x{013C}\x{0142}\x{0144}\x{0148}\x{00F1}\x{0146}\x{014B}\x{00F3}\x{00F2}\x{014F}' .
+ '\x{00F4}\x{00F6}\x{0151}\x{00F5}\x{00F8}\x{014D}\x{0153}\x{0138}\x{0155}\x{0159}\x{0157}' .
+ '\x{015B}\x{015D}\x{0161}\x{015F}\x{0165}\x{0163}\x{0167}\x{00FA}\x{00F9}\x{016D}\x{00FB}' .
+ '\x{016F}\x{00FC}\x{0171}\x{0169}\x{0173}\x{016B}\x{0175}\x{00FD}\x{0177}\x{00FF}\x{017A}' .
+ '\x{017E}\x{017C}\x{00F0}\x{00FE}';
+ }
+
+} \ No newline at end of file
diff --git a/site/vendors/phpQuery/Zend/Validate/Hostname/Fi.php b/site/vendors/phpQuery/Zend/Validate/Hostname/Fi.php
new file mode 100644
index 0000000..a28ba56
--- /dev/null
+++ b/site/vendors/phpQuery/Zend/Validate/Hostname/Fi.php
@@ -0,0 +1,50 @@
+<?php
+
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Validate
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id: Fi.php 8064 2008-02-16 10:58:39Z thomas $
+ */
+
+
+/**
+ * @see Zend_Validate_Hostname_Interface
+ */
+require_once 'Zend/Validate/Hostname/Interface.php';
+
+
+/**
+ * @category Zend
+ * @package Zend_Validate
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Validate_Hostname_Fi implements Zend_Validate_Hostname_Interface
+{
+
+ /**
+ * Returns UTF-8 characters allowed in DNS hostnames for the specified Top-Level-Domain
+ *
+ * @see http://www.ficora.fi/en/index/palvelut/fiverkkotunnukset/aakkostenkaytto.html Finland (.FI)
+ * @return string
+ */
+ static function getCharacters()
+ {
+ return '\x{00E5}\x{00E4}\x{00F6}';
+ }
+
+} \ No newline at end of file
diff --git a/site/vendors/phpQuery/Zend/Validate/Hostname/Hu.php b/site/vendors/phpQuery/Zend/Validate/Hostname/Hu.php
new file mode 100644
index 0000000..e6f9795
--- /dev/null
+++ b/site/vendors/phpQuery/Zend/Validate/Hostname/Hu.php
@@ -0,0 +1,50 @@
+<?php
+
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Validate
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id: Hu.php 8064 2008-02-16 10:58:39Z thomas $
+ */
+
+
+/**
+ * @see Zend_Validate_Hostname_Interface
+ */
+require_once 'Zend/Validate/Hostname/Interface.php';
+
+
+/**
+ * @category Zend
+ * @package Zend_Validate
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Validate_Hostname_Hu implements Zend_Validate_Hostname_Interface
+{
+
+ /**
+ * Returns UTF-8 characters allowed in DNS hostnames for the specified Top-Level-Domain
+ *
+ * @see http://www.domain.hu/domain/English/szabalyzat.html Hungary (.HU)
+ * @return string
+ */
+ static function getCharacters()
+ {
+ return '\x{00E1}\x{00E9}\x{00ED}\x{00F3}\x{00F6}\x{0151}\x{00FA}\x{00FC}\x{0171}';
+ }
+
+} \ No newline at end of file
diff --git a/site/vendors/phpQuery/Zend/Validate/Hostname/Interface.php b/site/vendors/phpQuery/Zend/Validate/Hostname/Interface.php
new file mode 100644
index 0000000..4426d8b
--- /dev/null
+++ b/site/vendors/phpQuery/Zend/Validate/Hostname/Interface.php
@@ -0,0 +1,52 @@
+<?php
+
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Validate
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id: Interface.php 8064 2008-02-16 10:58:39Z thomas $
+ */
+
+
+/**
+ * @category Zend
+ * @package Zend_Validate
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+interface Zend_Validate_Hostname_Interface
+{
+
+ /**
+ * Returns UTF-8 characters allowed in DNS hostnames for the specified Top-Level-Domain
+ *
+ * UTF-8 characters should be written as four character hex codes \x{XXXX}
+ * For example é (lowercase e with acute) is represented by the hex code \x{00E9}
+ *
+ * You only need to include lower-case equivalents of characters since the hostname
+ * check is case-insensitive
+ *
+ * Please document the supported TLDs in the documentation file at:
+ * manual/en/module_specs/Zend_Validate-Hostname.xml
+ *
+ * @see http://en.wikipedia.org/wiki/Internationalized_domain_name
+ * @see http://www.iana.org/cctld/ Country-Code Top-Level Domains (TLDs)
+ * @see http://www.columbia.edu/kermit/utf8-t1.html UTF-8 characters
+ * @return string
+ */
+ static function getCharacters();
+
+} \ No newline at end of file
diff --git a/site/vendors/phpQuery/Zend/Validate/Hostname/Li.php b/site/vendors/phpQuery/Zend/Validate/Hostname/Li.php
new file mode 100644
index 0000000..0739c93
--- /dev/null
+++ b/site/vendors/phpQuery/Zend/Validate/Hostname/Li.php
@@ -0,0 +1,50 @@
+<?php
+
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Validate
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id: Li.php 8064 2008-02-16 10:58:39Z thomas $
+ */
+
+
+/**
+ * @see Zend_Validate_Hostname_Interface
+ */
+require_once 'Zend/Validate/Hostname/Interface.php';
+
+
+/**
+ * @category Zend
+ * @package Zend_Validate
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Validate_Hostname_Li implements Zend_Validate_Hostname_Interface
+{
+
+ /**
+ * Returns UTF-8 characters allowed in DNS hostnames for the specified Top-Level-Domain
+ *
+ * @see https://nic.switch.ch/reg/ocView.action?res=EF6GW2JBPVTG67DLNIQXU234MN6SC33JNQQGI7L6#anhang1 Liechtenstein (.LI)
+ * @return string
+ */
+ static function getCharacters()
+ {
+ return '\x{00EO}-\x{00F6}\x{00F8}-\x{00FF}\x{0153}';
+ }
+
+} \ No newline at end of file
diff --git a/site/vendors/phpQuery/Zend/Validate/Hostname/No.php b/site/vendors/phpQuery/Zend/Validate/Hostname/No.php
new file mode 100644
index 0000000..d0d4c67
--- /dev/null
+++ b/site/vendors/phpQuery/Zend/Validate/Hostname/No.php
@@ -0,0 +1,52 @@
+<?php
+
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Validate
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id: No.php 8064 2008-02-16 10:58:39Z thomas $
+ */
+
+
+/**
+ * @see Zend_Validate_Hostname_Interface
+ */
+require_once 'Zend/Validate/Hostname/Interface.php';
+
+
+/**
+ * @category Zend
+ * @package Zend_Validate
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Validate_Hostname_No implements Zend_Validate_Hostname_Interface
+{
+
+ /**
+ * Returns UTF-8 characters allowed in DNS hostnames for the specified Top-Level-Domain
+ *
+ * @see http://www.norid.no/domeneregistrering/idn/idn_nyetegn.en.html Norway (.NO)
+ * @return string
+ */
+ static function getCharacters()
+ {
+ return '\x00E1\x00E0\x00E4\x010D\x00E7\x0111\x00E9\x00E8\x00EA\x\x014B' .
+ '\x0144\x00F1\x00F3\x00F2\x00F4\x00F6\x0161\x0167\x00FC\x017E\x00E6' .
+ '\x00F8\x00E5';
+ }
+
+}
diff --git a/site/vendors/phpQuery/Zend/Validate/Hostname/Se.php b/site/vendors/phpQuery/Zend/Validate/Hostname/Se.php
new file mode 100644
index 0000000..6f181cb
--- /dev/null
+++ b/site/vendors/phpQuery/Zend/Validate/Hostname/Se.php
@@ -0,0 +1,50 @@
+<?php
+
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Validate
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id: Se.php 8064 2008-02-16 10:58:39Z thomas $
+ */
+
+
+/**
+ * @see Zend_Validate_Hostname_Interface
+ */
+require_once 'Zend/Validate/Hostname/Interface.php';
+
+
+/**
+ * @category Zend
+ * @package Zend_Validate
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Validate_Hostname_Se implements Zend_Validate_Hostname_Interface
+{
+
+ /**
+ * Returns UTF-8 characters allowed in DNS hostnames for the specified Top-Level-Domain
+ *
+ * @see http://www.iis.se/english/IDN_campaignsite.shtml?lang=en Sweden (.SE)
+ * @return string
+ */
+ static function getCharacters()
+ {
+ return '\x{00E5}\x{00E4}\x{00F6}\x{00FC}\x{00E9}';
+ }
+
+} \ No newline at end of file
diff --git a/site/vendors/phpQuery/Zend/Validate/Identical.php b/site/vendors/phpQuery/Zend/Validate/Identical.php
new file mode 100644
index 0000000..02a5366
--- /dev/null
+++ b/site/vendors/phpQuery/Zend/Validate/Identical.php
@@ -0,0 +1,117 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Validate
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id: Identical.php 8118 2008-02-18 16:10:32Z matthew $
+ */
+
+/** Zend_Validate_Abstract */
+require_once 'Zend/Validate/Abstract.php';
+
+/**
+ * @category Zend
+ * @package Zend_Validate
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Validate_Identical extends Zend_Validate_Abstract
+{
+ /**#@+
+ * Error codes
+ * @const string
+ */
+ const NOT_SAME = 'notSame';
+ const MISSING_TOKEN = 'missingToken';
+ /**#@-*/
+
+ /**
+ * Error messages
+ * @var array
+ */
+ protected $_messageTemplates = array(
+ self::NOT_SAME => 'Tokens do not match',
+ self::MISSING_TOKEN => 'No token was provided to match against',
+ );
+
+ /**
+ * Original token against which to validate
+ * @var string
+ */
+ protected $_token;
+
+ /**
+ * Sets validator options
+ *
+ * @param string $token
+ * @return void
+ */
+ public function __construct($token = null)
+ {
+ if (null !== $token) {
+ $this->setToken($token);
+ }
+ }
+
+ /**
+ * Set token against which to compare
+ *
+ * @param string $token
+ * @return Zend_Validate_Identical
+ */
+ public function setToken($token)
+ {
+ $this->_token = (string) $token;
+ return $this;
+ }
+
+ /**
+ * Retrieve token
+ *
+ * @return string
+ */
+ public function getToken()
+ {
+ return $this->_token;
+ }
+
+ /**
+ * Defined by Zend_Validate_Interface
+ *
+ * Returns true if and only if a token has been set and the provided value
+ * matches that token.
+ *
+ * @param string $value
+ * @return boolean
+ */
+ public function isValid($value)
+ {
+ $this->_setValue($value);
+ $token = $this->getToken();
+
+ if (empty($token)) {
+ $this->_error(self::MISSING_TOKEN);
+ return false;
+ }
+
+ if ($value !== $token) {
+ $this->_error(self::NOT_SAME);
+ return false;
+ }
+
+ return true;
+ }
+}
diff --git a/site/vendors/phpQuery/Zend/Validate/InArray.php b/site/vendors/phpQuery/Zend/Validate/InArray.php
new file mode 100644
index 0000000..1c7725a
--- /dev/null
+++ b/site/vendors/phpQuery/Zend/Validate/InArray.php
@@ -0,0 +1,138 @@
+<?php
+
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Validate
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id: InArray.php 8064 2008-02-16 10:58:39Z thomas $
+ */
+
+
+/**
+ * @see Zend_Validate_Abstract
+ */
+require_once 'Zend/Validate/Abstract.php';
+
+
+/**
+ * @category Zend
+ * @package Zend_Validate
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Validate_InArray extends Zend_Validate_Abstract
+{
+
+ const NOT_IN_ARRAY = 'notInArray';
+
+ /**
+ * @var array
+ */
+ protected $_messageTemplates = array(
+ self::NOT_IN_ARRAY => "'%value%' was not found in the haystack"
+ );
+
+ /**
+ * Haystack of possible values
+ *
+ * @var array
+ */
+ protected $_haystack;
+
+ /**
+ * Whether a strict in_array() invocation is used
+ *
+ * @var boolean
+ */
+ protected $_strict;
+
+ /**
+ * Sets validator options
+ *
+ * @param array $haystack
+ * @param boolean $strict
+ * @return void
+ */
+ public function __construct(array $haystack, $strict = false)
+ {
+ $this->setHaystack($haystack)
+ ->setStrict($strict);
+ }
+
+ /**
+ * Returns the haystack option
+ *
+ * @return mixed
+ */
+ public function getHaystack()
+ {
+ return $this->_haystack;
+ }
+
+ /**
+ * Sets the haystack option
+ *
+ * @param mixed $haystack
+ * @return Zend_Validate_InArray Provides a fluent interface
+ */
+ public function setHaystack(array $haystack)
+ {
+ $this->_haystack = $haystack;
+ return $this;
+ }
+
+ /**
+ * Returns the strict option
+ *
+ * @return boolean
+ */
+ public function getStrict()
+ {
+ return $this->_strict;
+ }
+
+ /**
+ * Sets the strict option
+ *
+ * @param boolean $strict
+ * @return Zend_Validate_InArray Provides a fluent interface
+ */
+ public function setStrict($strict)
+ {
+ $this->_strict = $strict;
+ return $this;
+ }
+
+ /**
+ * Defined by Zend_Validate_Interface
+ *
+ * Returns true if and only if $value is contained in the haystack option. If the strict
+ * option is true, then the type of $value is also checked.
+ *
+ * @param mixed $value
+ * @return boolean
+ */
+ public function isValid($value)
+ {
+ $this->_setValue($value);
+ if (!in_array($value, $this->_haystack, $this->_strict)) {
+ $this->_error();
+ return false;
+ }
+ return true;
+ }
+
+}
diff --git a/site/vendors/phpQuery/Zend/Validate/Int.php b/site/vendors/phpQuery/Zend/Validate/Int.php
new file mode 100644
index 0000000..0bde2cb
--- /dev/null
+++ b/site/vendors/phpQuery/Zend/Validate/Int.php
@@ -0,0 +1,75 @@
+<?php
+
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Validate
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id: Int.php 8064 2008-02-16 10:58:39Z thomas $
+ */
+
+
+/**
+ * @see Zend_Validate_Abstract
+ */
+require_once 'Zend/Validate/Abstract.php';
+
+
+/**
+ * @category Zend
+ * @package Zend_Validate
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Validate_Int extends Zend_Validate_Abstract
+{
+
+ const NOT_INT = 'notInt';
+
+ /**
+ * @var array
+ */
+ protected $_messageTemplates = array(
+ self::NOT_INT => "'%value%' does not appear to be an integer"
+ );
+
+ /**
+ * Defined by Zend_Validate_Interface
+ *
+ * Returns true if and only if $value is a valid integer
+ *
+ * @param string $value
+ * @return boolean
+ */
+ public function isValid($value)
+ {
+ $valueString = (string) $value;
+
+ $this->_setValue($valueString);
+
+ $locale = localeconv();
+
+ $valueFiltered = str_replace($locale['decimal_point'], '.', $valueString);
+ $valueFiltered = str_replace($locale['thousands_sep'], '', $valueFiltered);
+
+ if (strval(intval($valueFiltered)) != $valueFiltered) {
+ $this->_error();
+ return false;
+ }
+
+ return true;
+ }
+
+}
diff --git a/site/vendors/phpQuery/Zend/Validate/Interface.php b/site/vendors/phpQuery/Zend/Validate/Interface.php
new file mode 100644
index 0000000..4fcd525
--- /dev/null
+++ b/site/vendors/phpQuery/Zend/Validate/Interface.php
@@ -0,0 +1,71 @@
+<?php
+
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Validate
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id: Interface.php 8064 2008-02-16 10:58:39Z thomas $
+ */
+
+
+/**
+ * @category Zend
+ * @package Zend_Validate
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+interface Zend_Validate_Interface
+{
+ /**
+ * Returns true if and only if $value meets the validation requirements
+ *
+ * If $value fails validation, then this method returns false, and
+ * getMessages() will return an array of messages that explain why the
+ * validation failed.
+ *
+ * @param mixed $value
+ * @return boolean
+ * @throws Zend_Valid_Exception If validation of $value is impossible
+ */
+ public function isValid($value);
+
+ /**
+ * Returns an array of messages that explain why the most recent isValid()
+ * call returned false. The array keys are validation failure message identifiers,
+ * and the array values are the corresponding human-readable message strings.
+ *
+ * If isValid() was never called or if the most recent isValid() call
+ * returned true, then this method returns an empty array.
+ *
+ * @return array
+ */
+ public function getMessages();
+
+ /**
+ * Returns an array of message codes that explain why a previous isValid() call
+ * returned false.
+ *
+ * If isValid() was never called or if the most recent isValid() call
+ * returned true, then this method returns an empty array.
+ *
+ * This is now the same as calling array_keys() on the return value from getMessages().
+ *
+ * @return array
+ * @deprecated Since 1.5.0
+ */
+ public function getErrors();
+
+}
diff --git a/site/vendors/phpQuery/Zend/Validate/Ip.php b/site/vendors/phpQuery/Zend/Validate/Ip.php
new file mode 100644
index 0000000..3f40696
--- /dev/null
+++ b/site/vendors/phpQuery/Zend/Validate/Ip.php
@@ -0,0 +1,70 @@
+<?php
+
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Validate
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id: Ip.php 8064 2008-02-16 10:58:39Z thomas $
+ */
+
+
+/**
+ * @see Zend_Validate_Abstract
+ */
+require_once 'Zend/Validate/Abstract.php';
+
+
+/**
+ * @category Zend
+ * @package Zend_Validate
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Validate_Ip extends Zend_Validate_Abstract
+{
+
+ const NOT_IP_ADDRESS = 'notIpAddress';
+
+ /**
+ * @var array
+ */
+ protected $_messageTemplates = array(
+ self::NOT_IP_ADDRESS => "'%value%' does not appear to be a valid IP address"
+ );
+
+ /**
+ * Defined by Zend_Validate_Interface
+ *
+ * Returns true if and only if $value is a valid IP address
+ *
+ * @param mixed $value
+ * @return boolean
+ */
+ public function isValid($value)
+ {
+ $valueString = (string) $value;
+
+ $this->_setValue($valueString);
+
+ if (ip2long($valueString) === false) {
+ $this->_error();
+ return false;
+ }
+
+ return true;
+ }
+
+}
diff --git a/site/vendors/phpQuery/Zend/Validate/LessThan.php b/site/vendors/phpQuery/Zend/Validate/LessThan.php
new file mode 100644
index 0000000..9f7b72c
--- /dev/null
+++ b/site/vendors/phpQuery/Zend/Validate/LessThan.php
@@ -0,0 +1,113 @@
+<?php
+
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Validate
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id: LessThan.php 8064 2008-02-16 10:58:39Z thomas $
+ */
+
+
+/**
+ * @see Zend_Validate_Abstract
+ */
+require_once 'Zend/Validate/Abstract.php';
+
+
+/**
+ * @category Zend
+ * @package Zend_Validate
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Validate_LessThan extends Zend_Validate_Abstract
+{
+
+ const NOT_LESS = 'notLessThan';
+
+ /**
+ * @var array
+ */
+ protected $_messageTemplates = array(
+ self::NOT_LESS => "'%value%' is not less than '%max%'"
+ );
+
+ /**
+ * @var array
+ */
+ protected $_messageVariables = array(
+ 'max' => '_max'
+ );
+
+ /**
+ * Maximum value
+ *
+ * @var mixed
+ */
+ protected $_max;
+
+ /**
+ * Sets validator options
+ *
+ * @param mixed $max
+ * @return void
+ */
+ public function __construct($max)
+ {
+ $this->setMax($max);
+ }
+
+ /**
+ * Returns the max option
+ *
+ * @return mixed
+ */
+ public function getMax()
+ {
+ return $this->_max;
+ }
+
+ /**
+ * Sets the max option
+ *
+ * @param mixed $max
+ * @return Zend_Validate_LessThan Provides a fluent interface
+ */
+ public function setMax($max)
+ {
+ $this->_max = $max;
+ return $this;
+ }
+
+ /**
+ * Defined by Zend_Validate_Interface
+ *
+ * Returns true if and only if $value is less than max option
+ *
+ * @param mixed $value
+ * @return boolean
+ */
+ public function isValid($value)
+ {
+ $this->_setValue($value);
+ if ($this->_max <= $value) {
+ $this->_error();
+ return false;
+ }
+ return true;
+ }
+
+}
diff --git a/site/vendors/phpQuery/Zend/Validate/NotEmpty.php b/site/vendors/phpQuery/Zend/Validate/NotEmpty.php
new file mode 100644
index 0000000..dcf3662
--- /dev/null
+++ b/site/vendors/phpQuery/Zend/Validate/NotEmpty.php
@@ -0,0 +1,74 @@
+<?php
+
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Validate
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id: NotEmpty.php 10356 2008-07-24 15:14:56Z matthew $
+ */
+
+
+/**
+ * @see Zend_Validate_Abstract
+ */
+require_once 'Zend/Validate/Abstract.php';
+
+
+/**
+ * @category Zend
+ * @package Zend_Validate
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Validate_NotEmpty extends Zend_Validate_Abstract
+{
+
+ const IS_EMPTY = 'isEmpty';
+
+ /**
+ * @var array
+ */
+ protected $_messageTemplates = array(
+ self::IS_EMPTY => "Value is empty, but a non-empty value is required"
+ );
+
+ /**
+ * Defined by Zend_Validate_Interface
+ *
+ * Returns true if and only if $value is not an empty value.
+ *
+ * @param string $value
+ * @return boolean
+ */
+ public function isValid($value)
+ {
+ $this->_setValue((string) $value);
+
+ if (is_string($value)
+ && (('' === $value)
+ || preg_match('/^\s+$/s', $value))
+ ) {
+ $this->_error();
+ return false;
+ } elseif (!is_string($value) && empty($value)) {
+ $this->_error();
+ return false;
+ }
+
+ return true;
+ }
+
+}
diff --git a/site/vendors/phpQuery/Zend/Validate/Regex.php b/site/vendors/phpQuery/Zend/Validate/Regex.php
new file mode 100644
index 0000000..1566f07
--- /dev/null
+++ b/site/vendors/phpQuery/Zend/Validate/Regex.php
@@ -0,0 +1,125 @@
+<?php
+
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Validate
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id: Regex.php 8064 2008-02-16 10:58:39Z thomas $
+ */
+
+
+/**
+ * @see Zend_Validate_Abstract
+ */
+require_once 'Zend/Validate/Abstract.php';
+
+
+/**
+ * @category Zend
+ * @package Zend_Validate
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Validate_Regex extends Zend_Validate_Abstract
+{
+
+ const NOT_MATCH = 'regexNotMatch';
+
+ /**
+ * @var array
+ */
+ protected $_messageTemplates = array(
+ self::NOT_MATCH => "'%value%' does not match against pattern '%pattern%'"
+ );
+
+ /**
+ * @var array
+ */
+ protected $_messageVariables = array(
+ 'pattern' => '_pattern'
+ );
+
+ /**
+ * Regular expression pattern
+ *
+ * @var string
+ */
+ protected $_pattern;
+
+ /**
+ * Sets validator options
+ *
+ * @param string $pattern
+ * @return void
+ */
+ public function __construct($pattern)
+ {
+ $this->setPattern($pattern);
+ }
+
+ /**
+ * Returns the pattern option
+ *
+ * @return string
+ */
+ public function getPattern()
+ {
+ return $this->_pattern;
+ }
+
+ /**
+ * Sets the pattern option
+ *
+ * @param string $pattern
+ * @return Zend_Validate_Regex Provides a fluent interface
+ */
+ public function setPattern($pattern)
+ {
+ $this->_pattern = (string) $pattern;
+ return $this;
+ }
+
+ /**
+ * Defined by Zend_Validate_Interface
+ *
+ * Returns true if and only if $value matches against the pattern option
+ *
+ * @param string $value
+ * @throws Zend_Validate_Exception if there is a fatal error in pattern matching
+ * @return boolean
+ */
+ public function isValid($value)
+ {
+ $valueString = (string) $value;
+
+ $this->_setValue($valueString);
+
+ $status = @preg_match($this->_pattern, $valueString);
+ if (false === $status) {
+ /**
+ * @see Zend_Validate_Exception
+ */
+ require_once 'Zend/Validate/Exception.php';
+ throw new Zend_Validate_Exception("Internal error matching pattern '$this->_pattern' against value '$valueString'");
+ }
+ if (!$status) {
+ $this->_error();
+ return false;
+ }
+ return true;
+ }
+
+}
diff --git a/site/vendors/phpQuery/Zend/Validate/StringLength.php b/site/vendors/phpQuery/Zend/Validate/StringLength.php
new file mode 100644
index 0000000..c43f2ca
--- /dev/null
+++ b/site/vendors/phpQuery/Zend/Validate/StringLength.php
@@ -0,0 +1,180 @@
+<?php
+
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Validate
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id: StringLength.php 8064 2008-02-16 10:58:39Z thomas $
+ */
+
+
+/**
+ * @see Zend_Validate_Abstract
+ */
+require_once 'Zend/Validate/Abstract.php';
+
+
+/**
+ * @category Zend
+ * @package Zend_Validate
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Validate_StringLength extends Zend_Validate_Abstract
+{
+
+ const TOO_SHORT = 'stringLengthTooShort';
+ const TOO_LONG = 'stringLengthTooLong';
+
+ /**
+ * @var array
+ */
+ protected $_messageTemplates = array(
+ self::TOO_SHORT => "'%value%' is less than %min% characters long",
+ self::TOO_LONG => "'%value%' is greater than %max% characters long"
+ );
+
+ /**
+ * @var array
+ */
+ protected $_messageVariables = array(
+ 'min' => '_min',
+ 'max' => '_max'
+ );
+
+ /**
+ * Minimum length
+ *
+ * @var integer
+ */
+ protected $_min;
+
+ /**
+ * Maximum length
+ *
+ * If null, there is no maximum length
+ *
+ * @var integer|null
+ */
+ protected $_max;
+
+ /**
+ * Sets validator options
+ *
+ * @param integer $min
+ * @param integer $max
+ * @return void
+ */
+ public function __construct($min = 0, $max = null)
+ {
+ $this->setMin($min);
+ $this->setMax($max);
+ }
+
+ /**
+ * Returns the min option
+ *
+ * @return integer
+ */
+ public function getMin()
+ {
+ return $this->_min;
+ }
+
+ /**
+ * Sets the min option
+ *
+ * @param integer $min
+ * @throws Zend_Validate_Exception
+ * @return Zend_Validate_StringLength Provides a fluent interface
+ */
+ public function setMin($min)
+ {
+ if (null !== $this->_max && $min > $this->_max) {
+ /**
+ * @see Zend_Validate_Exception
+ */
+ require_once 'Zend/Validate/Exception.php';
+ throw new Zend_Validate_Exception("The minimum must be less than or equal to the maximum length, but $min >"
+ . " $this->_max");
+ }
+ $this->_min = max(0, (integer) $min);
+ return $this;
+ }
+
+ /**
+ * Returns the max option
+ *
+ * @return integer|null
+ */
+ public function getMax()
+ {
+ return $this->_max;
+ }
+
+ /**
+ * Sets the max option
+ *
+ * @param integer|null $max
+ * @throws Zend_Validate_Exception
+ * @return Zend_Validate_StringLength Provides a fluent interface
+ */
+ public function setMax($max)
+ {
+ if (null === $max) {
+ $this->_max = null;
+ } else if ($max < $this->_min) {
+ /**
+ * @see Zend_Validate_Exception
+ */
+ require_once 'Zend/Validate/Exception.php';
+ throw new Zend_Validate_Exception("The maximum must be greater than or equal to the minimum length, but "
+ . "$max < $this->_min");
+ } else {
+ $this->_max = (integer) $max;
+ }
+
+ return $this;
+ }
+
+ /**
+ * Defined by Zend_Validate_Interface
+ *
+ * Returns true if and only if the string length of $value is at least the min option and
+ * no greater than the max option (when the max option is not null).
+ *
+ * @param string $value
+ * @return boolean
+ */
+ public function isValid($value)
+ {
+ $valueString = (string) $value;
+ $this->_setValue($valueString);
+ $length = iconv_strlen($valueString);
+ if ($length < $this->_min) {
+ $this->_error(self::TOO_SHORT);
+ }
+ if (null !== $this->_max && $this->_max < $length) {
+ $this->_error(self::TOO_LONG);
+ }
+ if (count($this->_messages)) {
+ return false;
+ } else {
+ return true;
+ }
+ }
+
+}
diff --git a/site/vendors/phpQuery/bootstrap.example.php b/site/vendors/phpQuery/bootstrap.example.php
new file mode 100644
index 0000000..4fafe1a
--- /dev/null
+++ b/site/vendors/phpQuery/bootstrap.example.php
@@ -0,0 +1,14 @@
+<?php
+/**
+ * Example of phpQuery bootstrap file.
+ *
+ * This file is executed everytime phpQuery is included. Use it to set all
+ * your personal needs in the library.
+ *
+ * To activate this file, delete '.example' from filename.
+ */
+// probably you want to use one of those functions here
+//phpQuery::ajaxAllowHost();
+//phpQuery::ajaxAllowURL();
+//phpQuery::plugin();
+?> \ No newline at end of file
diff --git a/site/vendors/phpQuery/compat/mbstring.php b/site/vendors/phpQuery/compat/mbstring.php
new file mode 100644
index 0000000..409129e
--- /dev/null
+++ b/site/vendors/phpQuery/compat/mbstring.php
@@ -0,0 +1,88 @@
+<?php
+// -- Multibyte Compatibility functions ---------------------------------------
+// http://svn.iphonewebdev.com/lace/lib/mb_compat.php
+
+/**
+ * mb_internal_encoding()
+ *
+ * Included for mbstring pseudo-compatability.
+ */
+if (!function_exists('mb_internal_encoding'))
+{
+ function mb_internal_encoding($enc) {return true; }
+}
+
+/**
+ * mb_regex_encoding()
+ *
+ * Included for mbstring pseudo-compatability.
+ */
+if (!function_exists('mb_regex_encoding'))
+{
+ function mb_regex_encoding($enc) {return true; }
+}
+
+/**
+ * mb_strlen()
+ *
+ * Included for mbstring pseudo-compatability.
+ */
+if (!function_exists('mb_strlen'))
+{
+ function mb_strlen($str)
+ {
+ return strlen($str);
+ }
+}
+
+/**
+ * mb_strpos()
+ *
+ * Included for mbstring pseudo-compatability.
+ */
+if (!function_exists('mb_strpos'))
+{
+ function mb_strpos($haystack, $needle, $offset=0)
+ {
+ return strpos($haystack, $needle, $offset);
+ }
+}
+/**
+ * mb_stripos()
+ *
+ * Included for mbstring pseudo-compatability.
+ */
+if (!function_exists('mb_stripos'))
+{
+ function mb_stripos($haystack, $needle, $offset=0)
+ {
+ return stripos($haystack, $needle, $offset);
+ }
+}
+
+/**
+ * mb_substr()
+ *
+ * Included for mbstring pseudo-compatability.
+ */
+if (!function_exists('mb_substr'))
+{
+ function mb_substr($str, $start, $length=0)
+ {
+ return substr($str, $start, $length);
+ }
+}
+
+/**
+ * mb_substr_count()
+ *
+ * Included for mbstring pseudo-compatability.
+ */
+if (!function_exists('mb_substr_count'))
+{
+ function mb_substr_count($haystack, $needle)
+ {
+ return substr_count($haystack, $needle);
+ }
+}
+
diff --git a/site/vendors/phpQuery/phpQuery.php b/site/vendors/phpQuery/phpQuery.php
new file mode 100644
index 0000000..79e50ee
--- /dev/null
+++ b/site/vendors/phpQuery/phpQuery.php
@@ -0,0 +1,1074 @@
+<?php
+/**
+ * phpQuery is a server-side, chainable, CSS3 selector driven
+ * Document Object Model (DOM) API based on jQuery JavaScript Library.
+ *
+ * @version 0.9.5 RC1
+ * @link http://code.google.com/p/phpquery/
+ * @link http://phpquery-library.blogspot.com/
+ * @link http://jquery.com/
+ * @author Tobiasz Cudnik <tobiasz.cudnik/gmail.com>
+ * @license http://www.opensource.org/licenses/mit-license.php MIT License
+ * @package phpQuery
+ */
+
+// class names for instanceof
+// TODO move them as class constants into phpQuery
+define('DOMDOCUMENT', 'DOMDocument');
+define('DOMELEMENT', 'DOMElement');
+define('DOMNODELIST', 'DOMNodeList');
+define('DOMNODE', 'DOMNode');
+require_once(dirname(__FILE__).'/DOMEvent.php');
+require_once(dirname(__FILE__).'/DOMDocumentWrapper.php');
+require_once(dirname(__FILE__).'/phpQueryEvents.php');
+require_once(dirname(__FILE__).'/Callback.php');
+require_once(dirname(__FILE__).'/phpQueryObject.php');
+require_once(dirname(__FILE__).'/compat/mbstring.php');
+/**
+ * Static namespace for phpQuery functions.
+ *
+ * @author Tobiasz Cudnik <tobiasz.cudnik/gmail.com>
+ * @package phpQuery
+ */
+abstract class phpQuery {
+ public static $debug = false;
+ public static $documents = array();
+ public static $defaultDocumentID = null;
+// public static $defaultDoctype = 'html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"';
+ /**
+ * Applies only to HTML.
+ *
+ * @var unknown_type
+ */
+ public static $defaultDoctype = '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+"http://www.w3.org/TR/html4/loose.dtd">';
+ public static $defaultCharset = 'UTF-8';
+ /**
+ * Static namespace for plugins.
+ *
+ * @var object
+ */
+ public static $plugins = array();
+ /**
+ * List of loaded plugins.
+ *
+ * @var unknown_type
+ */
+ public static $pluginsLoaded = array();
+ public static $pluginsMethods = array();
+ public static $pluginsStaticMethods = array();
+ /**
+ * Hosts allowed for AJAX connections.
+ * Dot '.' means $_SERVER['HTTP_HOST'] (if any).
+ *
+ * @var array
+ */
+ public static $ajaxAllowedHosts = array(
+ '.'
+ );
+ /**
+ * AJAX settings.
+ *
+ * @var array
+ * XXX should it be static or not ?
+ */
+ public static $ajaxSettings = array(
+ 'url' => '',//TODO
+ 'global' => true,
+ 'type' => "GET",
+ 'timeout' => null,
+ 'contentType' => "application/x-www-form-urlencoded",
+ 'processData' => true,
+// 'async' => true,
+ 'data' => null,
+ 'username' => null,
+ 'password' => null,
+ 'accepts' => array(
+ 'xml' => "application/xml, text/xml",
+ 'html' => "text/html",
+ 'script' => "text/javascript, application/javascript",
+ 'json' => "application/json, text/javascript",
+ 'text' => "text/plain",
+ '_default' => "*/*"
+ )
+ );
+ public static $lastModified = null;
+ public static $active = 0;
+ public static $dumpCount = 0;
+ /**
+ * Multi-purpose function.
+ * Use pq() as shortcut.
+ *
+ * In below examples, $pq is any result of pq(); function.
+ *
+ * 1. Import markup into existing document (without any attaching):
+ * - Import into selected document:
+ * pq('<div/>') // DOESNT accept text nodes at beginning of input string !
+ * - Import into document with ID from $pq->getDocumentID():
+ * pq('<div/>', $pq->getDocumentID())
+ * - Import into same document as DOMNode belongs to:
+ * pq('<div/>', DOMNode)
+ * - Import into document from phpQuery object:
+ * pq('<div/>', $pq)
+ *
+ * 2. Run query:
+ * - Run query on last selected document:
+ * pq('div.myClass')
+ * - Run query on document with ID from $pq->getDocumentID():
+ * pq('div.myClass', $pq->getDocumentID())
+ * - Run query on same document as DOMNode belongs to and use node(s)as root for query:
+ * pq('div.myClass', DOMNode)
+ * - Run query on document from phpQuery object
+ * and use object's stack as root node(s) for query:
+ * pq('div.myClass', $pq)
+ *
+ * @param string|DOMNode|DOMNodeList|array $arg1 HTML markup, CSS Selector, DOMNode or array of DOMNodes
+ * @param string|phpQueryObject|DOMNode $context DOM ID from $pq->getDocumentID(), phpQuery object (determines also query root) or DOMNode (determines also query root)
+ *
+ * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery|false
+ * phpQuery object or false in case of error.
+ */
+ public static function pq($arg1, $context = null) {
+ if ($arg1 instanceof DOMNODE && ! isset($context)) {
+ foreach(phpQuery::$documents as $documentWrapper) {
+ if ($documentWrapper->document->isSameNode($arg1->ownerDocument)) {
+ $context = $documentWrapper->id;
+ }
+ }
+ }
+ if (! $context) {
+ $domId = self::$defaultDocumentID;
+ if (! $domId)
+ throw new Exception("Can't use last created DOM, because there isn't any. Use phpQuery::newDocument() first.");
+// } else if (is_object($context) && ($context instanceof PHPQUERY || is_subclass_of($context, 'phpQueryObject')))
+ } else if (is_object($context) && $context instanceof phpQueryObject)
+ $domId = $context->getDocumentID();
+ else if ($context instanceof DOMDOCUMENT) {
+ $domId = self::getDocumentID($context);
+ if (! $domId) {
+ //throw new Exception('Orphaned DOMDocument');
+ $domId = self::newDocument($context)->getDocumentID();
+ }
+ } else if ($context instanceof DOMNODE) {
+ $domId = self::getDocumentID($context);
+ if (! $domId) {
+ throw new Exception('Orphaned DOMNode');
+// $domId = self::newDocument($context->ownerDocument);
+ }
+ } else
+ $domId = $context;
+ if ($arg1 instanceof phpQueryObject) {
+// if (is_object($arg1) && (get_class($arg1) == 'phpQueryObject' || $arg1 instanceof PHPQUERY || is_subclass_of($arg1, 'phpQueryObject'))) {
+ /**
+ * Return $arg1 or import $arg1 stack if document differs:
+ * pq(pq('<div/>'))
+ */
+ if ($arg1->getDocumentID() == $domId)
+ return $arg1;
+ $class = get_class($arg1);
+ // support inheritance by passing old object to overloaded constructor
+ $phpQuery = $class != 'phpQuery'
+ ? new $class($arg1, $domId)
+ : new phpQueryObject($domId);
+ $phpQuery->elements = array();
+ foreach($arg1->elements as $node)
+ $phpQuery->elements[] = $phpQuery->document->importNode($node, true);
+ return $phpQuery;
+ } else if ($arg1 instanceof DOMNODE || (is_array($arg1) && isset($arg1[0]) && $arg[0] instanceof DOMNODE)) {
+ /*
+ * Wrap DOM nodes with phpQuery object, import into document when needed:
+ * pq(array($domNode1, $domNode2))
+ */
+ $phpQuery = new phpQueryObject($domId);
+ if (!($arg1 instanceof DOMNODELIST) && ! is_array($arg1))
+ $arg1 = array($arg1);
+ $phpQuery->elements = array();
+ foreach($arg1 as $node)
+ $phpQuery->elements[] = ! $node->ownerDocument->isSameNode($phpQuery->document)
+ ? $phpQuery->document->importNode($node, true)
+ : $node;
+ return $phpQuery;
+ } else if (self::isMarkup($arg1)) {
+ /**
+ * Import HTML:
+ * pq('<div/>')
+ */
+ $phpQuery = new phpQueryObject($domId);
+ return $phpQuery->newInstance(
+ $phpQuery->documentWrapper->import($arg1)
+ );
+ } else {
+ /**
+ * Run CSS query:
+ * pq('div.myClass')
+ */
+ $phpQuery = new phpQueryObject($domId);
+// if ($context && ($context instanceof PHPQUERY || is_subclass_of($context, 'phpQueryObject')))
+ if ($context && $context instanceof phpQueryObject)
+ $phpQuery->elements = $context->elements;
+ else if ($context && $context instanceof DOMNODELIST) {
+ $phpQuery->elements = array();
+ foreach($context as $node)
+ $phpQuery->elements[] = $node;
+ } else if ($context && $context instanceof DOMNODE)
+ $phpQuery->elements = array($context);
+ return $phpQuery->find($arg1);
+ }
+ }
+ /**
+ * Sets default document to $id. Document has to be loaded prior
+ * to using this method.
+ * $id can be retrived via getDocumentID() or getDocumentIDRef().
+ *
+ * @param unknown_type $id
+ */
+ public static function selectDocument($id) {
+ $id = self::getDocumentID($id);
+ self::debug("Selecting document '$id' as default one");
+ self::$defaultDocumentID = self::getDocumentID($id);
+ }
+ /**
+ * Returns document with id $id or last used as phpQueryObject.
+ * $id can be retrived via getDocumentID() or getDocumentIDRef().
+ * Chainable.
+ *
+ * @see phpQuery::selectDocument()
+ * @param unknown_type $id
+ * @return phpQueryObject|queryTemplatesFetch|queryTemplatesParse|queryTemplatesPickup
+ */
+ public static function getDocument($id = null) {
+ if ($id)
+ phpQuery::selectDocument($id);
+ else
+ $id = phpQuery::$defaultDocumentID;
+ return new phpQueryObject($id);
+ }
+ /**
+ * Creates new document from markup.
+ * Chainable.
+ *
+ * @param unknown_type $markup
+ * @return phpQueryObject|queryTemplatesFetch|queryTemplatesParse|queryTemplatesPickup
+ * @TODO support DOMDocument
+ */
+ public static function newDocument($markup = null, $contentType = null) {
+ if (! $markup)
+ $markup = '';
+ $documentID = phpQuery::createDocumentWrapper($markup, $contentType);
+ return new phpQueryObject($documentID);
+ }
+ public static function newDocumentHTML($markup = null, $charset = 'utf-8') {
+ if (!isset($charset))
+ $charset = self::$defaultCharset;
+ return self::newDocument($markup, "text/html;charset=$charset");
+ }
+ public static function newDocumentXML($markup = null, $charset = 'utf-8') {
+ return self::newDocument($markup, "text/xml;charset=$charset");
+ }
+ public static function newDocumentXHTML($markup = null, $charset = 'utf-8') {
+ return self::newDocument($markup, "application/xhtml+xml;charset=$charset");
+ }
+ public static function newDocumentPHP($markup = null, $contentType = "text/html;charset=utf-8") {
+ $markup = phpQuery::phpToMarkup($markup);
+ return self::newDocument($markup, $contentType);
+ }
+ public static function phpToMarkup($php, $charset = 'utf-8') {
+ $regexes = array(
+ '@(<(?!\\?)(?:[^>]|\\?>)+\\w+\\s*=\\s*)(\')([^\']*)<?php?(.*?)(?:\\?>)([^\']*)\'@s',
+ '@(<(?!\\?)(?:[^>]|\\?>)+\\w+\\s*=\\s*)(")([^"]*)<?php?(.*?)(?:\\?>)([^"]*)"@s',
+ );
+ foreach($regexes as $regex)
+ while (preg_match($regex, $php, $matches)) {
+ $php = preg_replace_callback(
+ $regex,
+ create_function('$m, $charset = "'.$charset.'"',
+ 'return $m[1].$m[2]
+ .htmlspecialchars("<?php".$m[4]."?>", ENT_QUOTES|ENT_NOQUOTES, $charset)
+ .$m[5].$m[2];'
+ ),
+ $php
+ );
+}
+ $regex = '@(^|>[^<]*)+?(<\?php(.*?)(\?>))@s';
+//preg_match_all($regex, $php, $matches);
+//var_dump($matches);
+ $php = preg_replace($regex, '\\1<php><!-- \\3 --></php>', $php);
+ return $php;
+ }
+ /**
+ * Converts document markup containing PHP code generated by phpQuery::php()
+ * into valid (executable) PHP code syntax.
+ *
+ * @param string|phpQueryObject $content
+ * @return string PHP code.
+ */
+ public static function markupToPHP($content) {
+ if ($content instanceof phpQueryObject)
+ $content = $content->markupOuter();
+ /* <php>...</php> to <?php...? > */
+ $content = preg_replace_callback(
+ '@<php>\s*<!--(.*?)-->\s*</php>@s',
+ create_function('$m',
+ 'return "<'.'?php ".htmlspecialchars_decode($m[1])." ?'.'>";'
+ ),
+ $content
+ );
+ /* <node attr='< ?php ? >'> extra space added to save highlighters */
+ $regexes = array(
+ '@(<(?!\\?)(?:[^>]|\\?>)+\\w+\\s*=\\s*)(\')([^\']*)(?:&lt;|%3C)\\?(?:php)?(.*?)(?:\\?(?:&gt;|%3E))([^\']*)\'@s',
+ '@(<(?!\\?)(?:[^>]|\\?>)+\\w+\\s*=\\s*)(")([^"]*)(?:&lt;|%3C)\\?(?:php)?(.*?)(?:\\?(?:&gt;|%3E))([^"]*)"@s',
+ );
+ foreach($regexes as $regex)
+ while (preg_match($regex, $content))
+ $content = preg_replace_callback(
+ $regex,
+ create_function('$m',
+ 'return $m[1].$m[2].$m[3]."<?php "
+ .str_replace(
+ array("%20", "%3E", "%09", "&#10;", "&#9;", "%7B", "%24", "%7D", "%22", "%5B", "%5D"),
+ array(" ", ">", " ", "\n", " ", "{", "$", "}", \'"\', "[", "]"),
+ htmlspecialchars_decode($m[4])
+ )
+ ." ?>".$m[5].$m[2];'
+ ),
+ $content
+ );
+ return $content;
+ }
+ /**
+ * Creates new document from file $file.
+ * Chainable.
+ *
+ * @param string $file URLs allowed. See File wrapper page at php.net for more supported sources.
+ * @return phpQueryObject|queryTemplatesFetch|queryTemplatesParse|queryTemplatesPickup
+ */
+ public static function newDocumentFile($file, $contentType = null) {
+ $documentID = self::createDocumentWrapper(
+ file_get_contents($file), $contentType
+ );
+ return new phpQueryObject($documentID);
+ }
+ public static function newDocumentFileHTML($file, $charset = 'utf-8') {
+ return self::newDocumentFile($file, "text/html;charset=$charset");
+ }
+ public static function newDocumentFileXML($file, $charset = 'utf-8') {
+ return self::newDocumentFile($file, "text/xml;charset=$charset");
+ }
+ public static function newDocumentFileXHTML($file, $charset = 'utf-8') {
+ return self::newDocumentFile($file, "application/xhtml+xml;charset=$charset");
+ }
+ public static function newDocumentFilePHP($file, $contentType = null) {
+ return self::newDocumentPHP(file_get_contents($file), $contentType);
+ }
+ /**
+ * Reuses existing DOMDocument object.
+ * Chainable.
+ *
+ * @param $document DOMDocument
+ * @return phpQueryObject|queryTemplatesFetch|queryTemplatesParse|queryTemplatesPick
+ * up
+ */
+ public static function loadDocument($document) {
+ // TODO
+ die('TODO loadDocument');
+ }
+ /**
+ * Enter description here...
+ *
+ * @param unknown_type $html
+ * @param unknown_type $domId
+ * @return unknown New DOM ID
+ * @todo support PHP tags in input
+ * @todo support passing DOMDocument object from self::loadDocument
+ */
+ protected static function createDocumentWrapper($html, $contentType = null, $documentID = null) {
+ if (function_exists('domxml_open_mem')) {
+ throw new Exception("Old PHP4 DOM XML extension detected. phpQuery won't work until this extension is enabled.");
+ return null;
+ }
+ $id = $documentID
+ ? $documentID
+ : md5(microtime());
+ $document = null;
+ if ($html instanceof DOMDOCUMENT) {
+ // TODO support cloning of DOMDocumentWrapper
+ if (self::getDocumentID($html)) {
+ // document already exists in phpQuery::$documents, make a copy
+ $document = clone $html;
+ } else {
+ // new document, add it to phpQuery::$documents
+ $wrapper = new DOMDocumentWrapper($html, $contentType);
+ }
+ } else {
+ $wrapper = new DOMDocumentWrapper($html, $contentType);
+ }
+ $wrapper->id = $id;
+ // create document
+ phpQuery::$documents[$id] = $wrapper;
+ // remember last loaded document
+ return self::$defaultDocumentID = $id;
+ }
+ /**
+ * Deprecated, use phpQuery::plugin() instead.
+ *
+ * @deprecated
+ * @param $class
+ * @param $file
+ * @return unknown_type
+ */
+ public static function extend($class, $file = null) {
+ return self::plugin($class, $file);
+ }
+ /**
+ * Extend phpQuery with $class from $file.
+ *
+ * @param string $class Extending class name. Real class name can be prepended phpQuery_.
+ * @param string $file Filename to include. Defaults to "{$class}.php".
+ */
+ public static function plugin($class, $file = null) {
+ // TODO $class checked agains phpQuery_$class
+// if (strpos($class, 'phpQuery') === 0)
+// $class = substr($class, 8);
+ if (in_array($class, self::$pluginsLoaded))
+ return true;
+ if (! $file)
+ $file = $class.'.php';
+ $objectClassExists = class_exists('phpQueryObjectPlugin_'.$class);
+ $staticClassExists = class_exists('phpQueryPlugin_'.$class);
+ if (! $objectClassExists && ! $staticClassExists)
+ require_once($file);
+ self::$pluginsLoaded[] = $class;
+ // static methods
+ if (class_exists('phpQueryPlugin_'.$class)) {
+ $realClass = 'phpQueryPlugin_'.$class;
+ $vars = get_class_vars($realClass);
+ $loop = isset($vars['phpQueryMethods'])
+ && ! is_null($vars['phpQueryMethods'])
+ ? $vars['phpQueryMethods']
+ : get_class_methods($realClass);
+ foreach($loop as $method) {
+ if ($method == '__initialize')
+ continue;
+ if (! is_callable(array($realClass, $method)))
+ continue;
+ if (isset(self::$pluginsStaticMethods[$method])) {
+ throw new Exception("Duplicate method '{$method}' from plugin '{$c}' conflicts with same method from plugin '".self::$pluginsStaticMethods[$method]."'");
+ return;
+ }
+ self::$pluginsStaticMethods[$method] = $class;
+ }
+ if (method_exists($realClass, '__initialize'))
+ call_user_func_array(array($realClass, '__initialize'), array());
+ }
+ // object methods
+ if (class_exists('phpQueryObjectPlugin_'.$class)) {
+ $realClass = 'phpQueryObjectPlugin_'.$class;
+ $vars = get_class_vars($realClass);
+ $loop = isset($vars['phpQueryMethods'])
+ && ! is_null($vars['phpQueryMethods'])
+ ? $vars['phpQueryMethods']
+ : get_class_methods($realClass);
+ foreach($loop as $method) {
+ if (! is_callable(array($realClass, $method)))
+ continue;
+ if (isset(self::$pluginsMethods[$method])) {
+ throw new Exception("Duplicate method '{$method}' from plugin '{$c}' conflicts with same method from plugin '".self::$pluginsMethods[$method]."'");
+ return;
+ }
+ self::$pluginsMethods[$method] = $class;
+ }
+ }
+ return true;
+ }
+ /**
+ * Unloades all or specified document from memory.
+ *
+ * @param mixed $documentID @see phpQuery::getDocumentID() for supported types.
+ */
+ public static function unloadDocuments($id = null) {
+ if (isset($id)) {
+ if ($id = self::getDocumentID($id))
+ unset(phpQuery::$documents[$id]);
+ } else {
+ foreach(phpQuery::$documents as $k => $v) {
+ unset(phpQuery::$documents[$k]);
+ }
+ }
+ }
+ /**
+ * Parses phpQuery object or HTML result against PHP tags and makes them active.
+ *
+ * @param phpQuery|string $content
+ * @deprecated
+ * @return string
+ */
+ public static function unsafePHPTags($content) {
+ return self::markupToPHP($content);
+ }
+ public static function DOMNodeListToArray($DOMNodeList) {
+ $array = array();
+ if (! $DOMNodeList)
+ return $array;
+ foreach($DOMNodeList as $node)
+ $array[] = $node;
+ return $array;
+ }
+ /**
+ * Checks if $input is HTML string, which has to start with '<'.
+ *
+ * @deprecated
+ * @param String $input
+ * @return Bool
+ * @todo still used ?
+ */
+ public static function isMarkup($input) {
+ return substr(trim($input), 0, 1) == '<';
+ }
+ public static function debug($text) {
+ if (self::$debug)
+ print var_dump($text);
+ }
+ /**
+ * Make an AJAX request.
+ *
+ * @param array See $options http://docs.jquery.com/Ajax/jQuery.ajax#toptions
+ * Additional options are:
+ * 'document' - document for global events, @see phpQuery::getDocumentID()
+ * 'referer' - implemented
+ * 'requested_with' - TODO; not implemented (X-Requested-With)
+ * @return Zend_Http_Client
+ * @link http://docs.jquery.com/Ajax/jQuery.ajax
+ *
+ * @TODO $options['cache']
+ * @TODO $options['processData']
+ * @TODO support callbackStructure like each() and map()
+ */
+ public static function ajax($options = array(), $xhr = null) {
+ $options = array_merge(
+ self::$ajaxSettings, $options
+ );
+ $documentID = isset($options['document'])
+ ? self::getDocumentID($options['document'])
+ : null;
+ if ($xhr) {
+ // reuse existing XHR object, but clean it up
+ $client = $xhr;
+// $client->setParameterPost(null);
+// $client->setParameterGet(null);
+ $client->setAuth(false);
+ $client->setHeaders("If-Modified-Since", null);
+ $client->setHeaders("Referer", null);
+ $client->resetParameters();
+ } else {
+ // create new XHR object
+ require_once('Zend/Http/Client.php');
+ $client = new Zend_Http_Client();
+ $client->setCookieJar();
+ }
+ if (isset($options['timeout']))
+ $client->setConfig(array(
+ 'timeout' => $options['timeout'],
+ ));
+// 'maxredirects' => 0,
+ foreach(self::$ajaxAllowedHosts as $k => $host)
+ if ($host == '.' && isset($_SERVER['HTTP_HOST']))
+ self::$ajaxAllowedHosts[$k] = $_SERVER['HTTP_HOST'];
+ $host = parse_url($options['url'], PHP_URL_HOST);
+ if (! in_array($host, self::$ajaxAllowedHosts)) {
+ throw new Exception("Request not permitted, host '$host' not present in phpQuery::\$ajaxAllowedHosts");
+ return false;
+ }
+ $client->setUri($options['url']);
+ $client->setMethod(strtoupper($options['type']));
+ if (isset($options['referer']) && $options['referer'])
+ $client->setHeaders('Referer', $options['referer']);
+ $client->setHeaders(array(
+// 'content-type' => $options['contentType'],
+ 'User-Agent' => 'Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9a8) Gecko/2007100619 GranParadiso/3.0a8',
+ // TODO custom charset
+ 'Accept-Charset' => 'ISO-8859-1,utf-8;q=0.7,*;q=0.7',
+// 'Connection' => 'keep-alive',
+// 'Accept' => 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
+ 'Accept-Language' => 'en-us,en;q=0.5',
+ ));
+ if ($options['username'])
+ $client->setAuth($options['username'], $options['password']);
+ if (isset($options['ifModified']) && $options['ifModified'])
+ $client->setHeaders("If-Modified-Since",
+ self::$lastModified
+ ? self::$lastModified
+ : "Thu, 01 Jan 1970 00:00:00 GMT"
+ );
+ $client->setHeaders("Accept",
+ isset($options['dataType'])
+ && isset(self::$ajaxSettings['accepts'][ $options['dataType'] ])
+ ? self::$ajaxSettings['accepts'][ $options['dataType'] ].", */*"
+ : self::$ajaxSettings['accepts']['_default']
+ );
+ // TODO $options['processData']
+ if ($options['data'] instanceof phpQueryObject) {
+ $serialized = $options['data']->serializeArray($options['data']);
+ $options['data'] = array();
+ foreach($serialized as $r)
+ $options['data'][ $r['name'] ] = $r['value'];
+ }
+ if (strtolower($options['type']) == 'get') {
+ $client->setParameterGet($options['data']);
+ } else if (strtolower($options['type']) == 'post') {
+ $client->setEncType($options['contentType']);
+ $client->setParameterPost($options['data']);
+ }
+ if (self::$active == 0 && $options['global'])
+ phpQueryEvents::trigger($documentID, 'ajaxStart');
+ self::$active++;
+ // beforeSend callback
+ if (isset($options['beforeSend']) && $options['beforeSend'])
+ phpQuery::callbackRun($options['beforeSend'], array($client));
+ // ajaxSend event
+ if ($options['global'])
+ phpQueryEvents::trigger($documentID, 'ajaxSend', array($client, $options));
+ if (phpQuery::$debug) {
+ self::debug("{$options['type']}: {$options['url']}\n");
+ self::debug("Options: <pre>".var_export($options, true)."</pre>\n");
+// if ($client->getCookieJar())
+// self::debug("Cookies: <pre>".var_export($client->getCookieJar()->getMatchingCookies($options['url']), true)."</pre>\n");
+ }
+ // request
+ $response = $client->request();
+ if (phpQuery::$debug) {
+ self::debug('Status: '.$response->getStatus().' / '.$response->getMessage());
+ self::debug($client->getLastRequest());
+ self::debug($response->getHeaders());
+ }
+ if ($response->isSuccessful()) {
+ // XXX tempolary
+ self::$lastModified = $response->getHeader('Last-Modified');
+ if (isset($options['success']) && $options['success'])
+ phpQuery::callbackRun($options['success'], array($response->getBody(), $response->getStatus()));
+ if ($options['global'])
+ phpQueryEvents::trigger($documentID, 'ajaxSuccess', array($client, $options));
+ } else {
+ if (isset($options['error']) && $options['error'])
+ phpQuery::callbackRun($options['error'], array($client, $response->getStatus(), $response->getMessage()));
+ if ($options['global'])
+ phpQueryEvents::trigger($documentID, 'ajaxError', array($client, /*$response->getStatus(),*/$response->getMessage(), $options));
+ }
+ if (isset($options['complete']) && $options['complete'])
+ phpQuery::callbackRun($options['complete'], array($client, $response->getStatus()));
+ if ($options['global'])
+ phpQueryEvents::trigger($documentID, 'ajaxComplete', array($client, $options));
+ if ($options['global'] && ! --self::$active)
+ phpQueryEvents::trigger($documentID, 'ajaxStop');
+ return $client;
+// if (is_null($domId))
+// $domId = self::$defaultDocumentID ? self::$defaultDocumentID : false;
+// return new phpQueryAjaxResponse($response, $domId);
+ }
+ /**
+ * Enter description here...
+ *
+ * @param array|phpQuery $data
+ *
+ */
+ public static function param($data) {
+ return http_build_query($data, null, '&');
+ }
+
+ public static function get($url, $data = null, $callback = null, $type = null) {
+ if (!is_array($data)) {
+ $callback = $data;
+ $data = null;
+ }
+ // TODO some array_values on this shit
+ return phpQuery::ajax(array(
+ 'type' => 'GET',
+ 'url' => $url,
+ 'data' => $data,
+ 'success' => $callback,
+ 'dataType' => $type,
+ ));
+ }
+
+ public static function post($url, $data = null, $callback = null, $type = null) {
+ if (!is_array($data)) {
+ $callback = $data;
+ $data = null;
+ }
+ return phpQuery::ajax(array(
+ 'type' => 'POST',
+ 'url' => $url,
+ 'data' => $data,
+ 'success' => $callback,
+ 'dataType' => $type,
+ ));
+ }
+ public static function ajaxSetup($options) {
+ self::$ajaxSettings = array_merge(
+ self::$ajaxSettings,
+ $options
+ );
+ }
+ public static function ajaxAllowHost($host1, $host2 = null, $host3 = null) {
+ $loop = is_array($host1)
+ ? $host1
+ : func_get_args();
+ foreach($loop as $host) {
+ if ($host && ! in_array($host, phpQuery::$ajaxAllowedHosts)) {
+ phpQuery::$ajaxAllowedHosts[] = $host;
+ }
+ }
+ }
+ public static function ajaxAllowURL($url1, $url2 = null, $url3 = null) {
+ $loop = is_array($url1)
+ ? $url1
+ : func_get_args();
+ foreach($loop as $url)
+ phpQuery::ajaxAllowHost(parse_url($url, PHP_URL_HOST));
+ }
+ /**
+ * Returns JSON representation of $data.
+ *
+ * @static
+ * @param mixed $data
+ * @return string
+ */
+ public static function toJSON($data) {
+ if (function_exists('json_encode'))
+ return json_encode($data);
+ require_once('Zend/Json/Encoder');
+ return Zend_Json_Encoder::encode($data);
+ }
+ /**
+ * Parses JSON into proper PHP type.
+ *
+ * @static
+ * @param string $json
+ * @return mixed
+ */
+ public static function parseJSON($json) {
+ if (function_exists('json_decode'))
+ return json_decode($json, true);
+ require_once('Zend/Json/Decoder');
+ return Zend_Json_Decoder::decode($json);
+ }
+ /**
+ * Returns source's document ID.
+ *
+ * @param $source DOMNode|phpQueryObject
+ * @return string
+ */
+ public static function getDocumentID($source) {
+ if ($source instanceof DOMDOCUMENT) {
+ foreach(phpQuery::$documents as $id => $document) {
+ if ($source->isSameNode($document['document']))
+ return $id;
+ }
+ } else if ($source instanceof DOMNODE) {
+ foreach(phpQuery::$documents as $id => $document) {
+ if ($source->ownerDocument->isSameNode($document['document']))
+ return $id;
+ }
+ } else if ($source instanceof phpQueryObject)
+ return $source->getDocumentID();
+ else if (is_string($source) && isset(phpQuery::$documents[$source]))
+ return $source;
+ }
+ /**
+ * Get DOMDocument object related to $source.
+ * Returns null if such document doesn't exist.
+ *
+ * @param $source DOMNode|phpQueryObject|string
+ * @return string
+ */
+ public static function getDOMDocument($source) {
+ if ($source instanceof DOMDOCUMENT)
+ return $source;
+ $source = self::getDocumentID($source);
+ return $source
+ ? self::$documents[$id]['document']
+ : null;
+ }
+
+ // UTILITIES
+ // http://docs.jquery.com/Utilities
+
+ /**
+ *
+ * @return unknown_type
+ * @link http://docs.jquery.com/Utilities/jQuery.makeArray
+ */
+ public static function makeArray($obj) {
+ $array = array();
+ if (is_object($object) && $object instanceof DOMNODELIST) {
+ foreach($object as $value)
+ $array[] = $value;
+ } else if (is_object($object) && ! ($object instanceof Iterator)) {
+ foreach(get_object_vars($object) as $name => $value)
+ $array[0][$name] = $value;
+ } else {
+ foreach($object as $name => $value)
+ $array[0][$name] = $value;
+ }
+ return $array;
+ }
+ public static function inArray($value, $array) {
+ return in_array($value, $array);
+ }
+ /**
+ *
+ * @param $object
+ * @param $callback
+ * @return unknown_type
+ * @link http://docs.jquery.com/Utilities/jQuery.each
+ */
+ public static function each($object, $callback, $param1 = null, $param2 = null, $param3 = null) {
+ $paramStructure = null;
+ if (func_num_args() > 2) {
+ $paramStructure = func_get_args();
+ $paramStructure = array_slice($paramStructure, 2);
+ }
+ if (is_object($object) && ! ($object instanceof Iterator)) {
+ foreach(get_object_vars($object) as $name => $value)
+ phpQuery::callbackRun($callback, array($name, $value), $paramStructure);
+ } else {
+ foreach($object as $name => $value)
+ phpQuery::callbackRun($callback, array($name, $value), $paramStructure);
+ }
+ }
+ /**
+ *
+ * @link http://docs.jquery.com/Utilities/jQuery.map
+ */
+ public static function map($array, $callback, $param1 = null, $param2 = null, $param3 = null) {
+ $result = array();
+ $paramStructure = null;
+ if (func_num_args() > 2) {
+ $paramStructure = func_get_args();
+ $paramStructure = array_slice($paramStructure, 2);
+ }
+ foreach($array as $v) {
+ $vv = phpQuery::callbackRun($callback, array($v), $paramStructure);
+// $callbackArgs = $args;
+// foreach($args as $i => $arg) {
+// $callbackArgs[$i] = $arg instanceof CallbackParam
+// ? $v
+// : $arg;
+// }
+// $vv = call_user_func_array($callback, $callbackArgs);
+ if (is_array($vv)) {
+ foreach($vv as $vvv)
+ $result[] = $vvv;
+ } else if ($vv !== null) {
+ $result[] = $vv;
+ }
+ }
+ return $result;
+ }
+ /**
+ *
+ * @param $callback Callback
+ * @param $params
+ * @param $paramStructure
+ * @return unknown_type
+ */
+ public static function callbackRun($callback, $params = null, $paramStructure = null) {
+ if (! $callback)
+ return;
+ if ($callback instanceof CallbackReference) {
+ // TODO support ParamStructure to select which $param push to reference
+ if (isset($params[0]))
+ $callback->callback = $params[0];
+ return true;
+ }
+ if ($callback instanceof Callback) {
+ $paramStructure = $callback->params;
+ $callback = $callback->callback;
+ }
+ if (! $paramStructure)
+ return call_user_func_array($callback, $params);
+ $p = 0;
+ foreach($paramStructure as $i => $v) {
+ $paramStructure[$i] = $v instanceof CallbackParam
+ ? $params[$p++]
+ : $v;
+ }
+ return call_user_func_array($callback, $paramStructure);
+ }
+ /**
+ * Merge 2 phpQuery objects.
+ * @param array $one
+ * @param array $two
+ * @protected
+ * @todo node lists, phpQueryObject
+ */
+ public static function merge($one, $two) {
+ $elements = $one->elements;
+ foreach($two->elements as $node) {
+ $exists = false;
+ foreach($elements as $node2) {
+ if ($node2->isSameNode($node))
+ $exists = true;
+ }
+ if (! $exists)
+ $elements[] = $node;
+ }
+ return $elements;
+// $one = $one->newInstance();
+// $one->elements = $elements;
+// return $one;
+ }
+ /**
+ *
+ * @param $array
+ * @param $callback
+ * @param $invert
+ * @return unknown_type
+ * @link http://docs.jquery.com/Utilities/jQuery.grep
+ */
+ public static function grep($array, $callback, $invert = false) {
+ $result = array();
+ foreach($array as $k => $v) {
+ $r = call_user_func_array($callback, array($v, $k));
+ if ($r === !(bool)$invert)
+ $result[] = $v;
+ }
+ return $result;
+ }
+ public static function unique($array) {
+ return array_unique($array);
+ }
+ /**
+ *
+ * @param $function
+ * @return unknown_type
+ * @TODO there are problems with non-static methods, second parameter pass it
+ * but doesnt verify is method is really callable
+ */
+ public static function isFunction($function) {
+ return is_callable($function);
+ }
+ public static function trim($str) {
+ return trim($str);
+ }
+ /* PLUGINS NAMESPACE */
+ /**
+ *
+ * @param $url
+ * @param $callback
+ * @param $param1
+ * @param $param2
+ * @param $param3
+ * @return phpQueryObject
+ */
+ public static function browserGet($url, $callback, $param1 = null, $param2 = null, $param3 = null) {
+ if (self::plugin('WebBrowser')) {
+ $params = func_get_args();
+ return self::callbackRun(array(self::$plugins, 'browserGet'), $params);
+ } else {
+ self::debug('WebBrowser plugin not available...');
+ }
+ }
+ /**
+ *
+ * @param $url
+ * @param $data
+ * @param $callback
+ * @param $param1
+ * @param $param2
+ * @param $param3
+ * @return phpQueryObject
+ */
+ public static function browserPost($url, $data, $callback, $param1 = null, $param2 = null, $param3 = null) {
+ if (self::plugin('WebBrowser')) {
+ $params = func_get_args();
+ return self::callbackRun(array(self::$plugins, 'browserPost'), $params);
+ } else {
+ self::debug('WebBrowser plugin not available...');
+ }
+ }
+ /**
+ *
+ * @param $ajaxSettings
+ * @param $callback
+ * @param $param1
+ * @param $param2
+ * @param $param3
+ * @return phpQueryObject
+ */
+ public static function browser($ajaxSettings, $callback, $param1 = null, $param2 = null, $param3 = null) {
+ if (self::plugin('WebBrowser')) {
+ $params = func_get_args();
+ return self::callbackRun(array(self::$plugins, 'browser'), $params);
+ } else {
+ self::debug('WebBrowser plugin not available...');
+ }
+ }
+ /**
+ *
+ * @param $code
+ * @return string
+ */
+ public static function php($code) {
+ return self::code('php', $code);
+ }
+ /**
+ *
+ * @param $type
+ * @param $code
+ * @return string
+ */
+ public static function code($type, $code) {
+ return "<$type><!-- ".trim($code)." --></$type>";
+ }
+}
+/**
+ * Plugins static namespace class.
+ *
+ * @author Tobiasz Cudnik <tobiasz.cudnik/gmail.com>
+ * @package phpQuery
+ * @todo move plugin methods here (as statics)
+ */
+class phpQueryPlugins {
+ public function __call($method, $args) {
+ if (isset(phpQuery::$pluginsStaticMethods[$method])) {
+ $class = phpQuery::$pluginsStaticMethods[$method];
+ $realClass = "phpQueryPlugin_$class";
+ $return = call_user_func_array(
+ array($realClass, $method),
+ $args
+ );
+ return isset($return)
+ ? $return
+ : $this;
+ } else
+ throw new Exception("Method '{$method}' doesnt exist");
+ }
+}
+/**
+ * Shortcut to phpQuery::pq($arg1, $context)
+ * Chainable.
+ *
+ * @see phpQuery::pq()
+ * @return phpQueryObject|queryTemplatesFetch|queryTemplatesParse|queryTemplatesPickup
+ * @author Tobiasz Cudnik <tobiasz.cudnik/gmail.com>
+ * @package phpQuery
+ */
+function pq($arg1, $context = null) {
+ $args = func_get_args();
+ return call_user_func_array(
+ array('phpQuery', 'pq'),
+ $args
+ );
+}
+// add plugins dir and Zend framework to include path
+set_include_path(
+ get_include_path()
+ .PATH_SEPARATOR.dirname(__FILE__).'/'
+ .PATH_SEPARATOR.dirname(__FILE__).'/plugins/'
+);
+// why ? no __call nor __get for statics in php...
+// XXX __callStatic will be available in PHP 5.3
+phpQuery::$plugins = new phpQueryPlugins();
+// include bootstrap file (personal library config)
+if (file_exists(dirname(__FILE__).'/bootstrap.php'))
+ require_once dirname(__FILE__).'/bootstrap.php'; \ No newline at end of file
diff --git a/site/vendors/phpQuery/phpQueryEvents.php b/site/vendors/phpQuery/phpQueryEvents.php
new file mode 100644
index 0000000..532167c
--- /dev/null
+++ b/site/vendors/phpQuery/phpQueryEvents.php
@@ -0,0 +1,153 @@
+<?php
+/**
+ * Event handling class.
+ *
+ * @author Tobiasz Cudnik
+ * @package phpQuery
+ * @static
+ */
+abstract class phpQueryEvents {
+ /**
+ * Trigger a type of event on every matched element.
+ *
+ * @param DOMNode|phpQueryObject|string $document
+ * @param unknown_type $type
+ * @param unknown_type $data
+ *
+ * @TODO exclusive events (with !)
+ * @TODO global events (test)
+ * @TODO support more than event in $type (space-separated)
+ */
+ public static function trigger($document, $type, $data = array(), $node = null) {
+ // trigger: function(type, data, elem, donative, extra) {
+ $documentID = phpQuery::getDocumentID($document);
+ $namespace = null;
+ if (strpos($type, '.') !== false)
+ list($name, $namespace) = explode('.', $type);
+ else
+ $name = $type;
+ if (! $node) {
+ if (self::issetGlobal($documentID, $type)) {
+ $pq = phpQuery::getDocument($documentID);
+ // TODO check add($pq->document)
+ $pq->find('*')->add($pq->document)
+ ->trigger($type, $data);
+ }
+ } else {
+ if (isset($data[0]) && $data[0] instanceof DOMEvent) {
+ $event = $data[0];
+ $event->relatedTarget = $event->target;
+ $event->target = $node;
+ $data = array_slice($data, 1);
+ } else {
+ $event = new DOMEvent(array(
+ 'type' => $type,
+ 'target' => $node,
+ 'timeStamp' => time(),
+ ));
+ }
+ while($node) {
+ phpQuery::debug("Triggering event '{$type}' on node ".phpQueryObject::whois($node)."\n");
+ $event->currentTarget = $node;
+ $eventNode = self::getNode($documentID, $node);
+ if (isset($eventNode->eventHandlers)) {
+ foreach($eventNode->eventHandlers as $eventType => $handlers) {
+ $eventNamespace = null;
+ if (strpos($type, '.') !== false)
+ list($eventName, $eventNamespace) = explode('.', $eventType);
+ else
+ $eventName = $eventType;
+ if ($name != $eventName)
+ continue;
+ if ($namespace && $eventNamespace && $namespace != $eventNamespace)
+ continue;
+ foreach($handlers as $handler) {
+ $event->data = $handler['data']
+ ? $handler['data']
+ : null;
+ $params = array_merge(array($event), $data);
+ $return = phpQuery::callbackRun($handler['callback'], $params);
+ if ($return === false) {
+ $event->bubbles = false;
+ }
+ }
+ }
+ }
+ // to bubble or not to bubble...
+ if (! $event->bubbles)
+ break;
+ $node = $node->parentNode;
+ }
+ }
+ }
+ /**
+ * Binds a handler to one or more events (like click) for each matched element.
+ * Can also bind custom events.
+ *
+ * @param DOMNode|phpQueryObject|string $document
+ * @param unknown_type $type
+ * @param unknown_type $data Optional
+ * @param unknown_type $callback
+ *
+ * @TODO support '!' (exclusive) events
+ * @TODO support more than event in $type (space-separated)
+ * @TODO support binding to global events
+ */
+ public static function add($document, $node, $type, $data, $callback = null) {
+ phpQuery::debug("Binding '$type' event");
+ $documentID = phpQuery::getDocumentID($document);
+// if (is_null($callback) && is_callable($data)) {
+// $callback = $data;
+// $data = null;
+// }
+ $eventNode = self::getNode($documentID, $node);
+ if (! $eventNode)
+ $eventNode = self::setNode($documentID, $node);
+ if (!isset($eventNode->eventHandlers[$type]))
+ $eventNode->eventHandlers[$type] = array();
+ $eventNode->eventHandlers[$type][] = array(
+ 'callback' => $callback,
+ 'data' => $data,
+ );
+ }
+ /**
+ * Enter description here...
+ *
+ * @param DOMNode|phpQueryObject|string $document
+ * @param unknown_type $type
+ * @param unknown_type $callback
+ *
+ * @TODO namespace events
+ * @TODO support more than event in $type (space-separated)
+ */
+ public static function remove($document, $node, $type = null, $callback = null) {
+ $documentID = phpQuery::getDocumentID($document);
+ $eventNode = self::getNode($documentID, $node);
+ if (is_object($eventNode) && isset($eventNode->eventHandlers[$type])) {
+ if ($callback) {
+ foreach($eventNode->eventHandlers[$type] as $k => $handler)
+ if ($handler['callback'] == $callback)
+ unset($eventNode->eventHandlers[$type][$k]);
+ } else {
+ unset($eventNode->eventHandlers[$type]);
+ }
+ }
+ }
+ protected static function getNode($documentID, $node) {
+ foreach(phpQuery::$documents[$documentID]->eventsNodes as $eventNode) {
+ if ($node->isSameNode($eventNode))
+ return $eventNode;
+ }
+ }
+ protected static function setNode($documentID, $node) {
+ phpQuery::$documents[$documentID]->eventsNodes[] = $node;
+ return phpQuery::$documents[$documentID]->eventsNodes[
+ count(phpQuery::$documents[$documentID]->eventsNodes)-1
+ ];
+ }
+ protected static function issetGlobal($documentID, $type) {
+ return isset(phpQuery::$documents[$documentID])
+ ? in_array($type, phpQuery::$documents[$documentID]->eventsGlobal)
+ : false;
+ }
+} \ No newline at end of file
diff --git a/site/vendors/phpQuery/phpQueryObject.php b/site/vendors/phpQuery/phpQueryObject.php
new file mode 100644
index 0000000..016133d
--- /dev/null
+++ b/site/vendors/phpQuery/phpQueryObject.php
@@ -0,0 +1,3134 @@
+<?php
+/**
+ * Class representing phpQuery objects.
+ *
+ * @author Tobiasz Cudnik <tobiasz.cudnik/gmail.com>
+ * @package phpQuery
+ * @method phpQueryObject clone() clone()
+ * @method phpQueryObject empty() empty()
+ * @method phpQueryObject next() next($selector = null)
+ * @method phpQueryObject prev() prev($selector = null)
+ * @property Int $length
+ */
+class phpQueryObject
+ implements Iterator, Countable, ArrayAccess {
+ public $documentID = null;
+ /**
+ * DOMDocument class.
+ *
+ * @var DOMDocument
+ */
+ public $document = null;
+ public $charset = null;
+ /**
+ *
+ * @var DOMDocumentWrapper
+ */
+ public $documentWrapper = null;
+ /**
+ * XPath interface.
+ *
+ * @var DOMXPath
+ */
+ public $xpath = null;
+ /**
+ * Stack of selected elements.
+ * @TODO refactor to ->nodes
+ * @var array
+ */
+ public $elements = array();
+ /**
+ * @access private
+ */
+ protected $elementsBackup = array();
+ /**
+ * @access private
+ */
+ protected $previous = null;
+ /**
+ * @access private
+ * @TODO deprecate
+ */
+ protected $root = array();
+ /**
+ * Indicated if doument is just a fragment (no <html> tag).
+ *
+ * Every document is realy a full document, so even documentFragments can
+ * be queried against <html>, but getDocument(id)->htmlOuter() will return
+ * only contents of <body>.
+ *
+ * @var bool
+ */
+ public $documentFragment = true;
+ /**
+ * Iterator interface helper
+ * @access private
+ */
+ protected $elementsInterator = array();
+ /**
+ * Iterator interface helper
+ * @access private
+ */
+ protected $valid = false;
+ /**
+ * Iterator interface helper
+ * @access private
+ */
+ protected $current = null;
+ /**
+ * Enter description here...
+ *
+ * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery
+ */
+ public function __construct($documentID) {
+ $id = $documentID instanceof self
+ ? $documentID->getDocumentID()
+ : $documentID;
+ if (! isset(phpQuery::$documents[$id] )) {
+ throw new Exception("Document with ID '{$id}' isn't loaded. Use phpQuery::newDocument(\$html) or phpQuery::newDocumentFile(\$file) first.");
+ return;
+ }
+ $this->documentID = $id;
+ $this->documentWrapper =& phpQuery::$documents[$id];
+ $this->document =& $this->documentWrapper->document;
+ $this->xpath =& $this->documentWrapper->xpath;
+ $this->charset =& $this->documentWrapper->charset;
+ $this->documentFragment =& $this->documentWrapper->isDocumentFragment;
+ // TODO check $this->DOM->documentElement;
+// $this->root = $this->document->documentElement;
+ $this->root =& $this->documentWrapper->root;
+// $this->toRoot();
+ $this->elements = array($this->root);
+ }
+ /**
+ *
+ * @access private
+ * @param $attr
+ * @return unknown_type
+ */
+ public function __get($attr) {
+ switch($attr) {
+ // FIXME doesnt work at all ?
+ case 'length':
+ return $this->size();
+ break;
+ default:
+ return $this->$attr;
+ }
+ }
+ /**
+ * Saves actual object to $var by reference.
+ * Useful when need to break chain.
+ * @param phpQueryObject $var
+ * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery
+ */
+ public function toReference(&$var) {
+ return $var = $this;
+ }
+ public function documentFragment($state = null) {
+ if ($state) {
+ phpQuery::$documents[$this->getDocumentID()]['documentFragment'] = $state;
+ return $this;
+ }
+ return $this->documentFragment;
+ }
+ /**
+ * @access private
+ * @TODO documentWrapper
+ */
+ protected function isRoot( $node) {
+// return $node instanceof DOMDOCUMENT || $node->tagName == 'html';
+ return $node instanceof DOMDOCUMENT
+ || ($node instanceof DOMELEMENT && $node->tagName == 'html')
+ || $this->root->isSameNode($node);
+ }
+ /**
+ * @access private
+ */
+ protected function stackIsRoot() {
+ return $this->size() == 1 && $this->isRoot($this->elements[0]);
+ }
+ /**
+ * Enter description here...
+ * NON JQUERY METHOD
+ *
+ * Watch out, it doesn't creates new instance, can be reverted with end().
+ *
+ * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery
+ */
+ public function toRoot() {
+ $this->elements = array($this->root);
+ return $this;
+// return $this->newInstance(array($this->root));
+ }
+ /**
+ * Saves object's DocumentID to $var by reference.
+ * <code>
+ * $myDocumentId;
+ * phpQuery::newDocument('<div/>')
+ * ->getDocumentIDRef($myDocumentId)
+ * ->find('div')->...
+ * </code>
+ *
+ * @param unknown_type $domId
+ * @see phpQuery::newDocument
+ * @see phpQuery::newDocumentFile
+ * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery
+ */
+ public function getDocumentIDRef(&$documentID) {
+ $documentID = $this->getDocumentID();
+ return $this;
+ }
+ /**
+ * Returns object with stack set to document root.
+ *
+ * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery
+ */
+ public function getDocument() {
+ return phpQuery::getDocument($this->getDocumentID());
+ }
+ /**
+ *
+ * @return DOMDocument
+ */
+ public function getDOMDocument() {
+ return $this->document;
+ }
+ /**
+ * Get object's Document ID.
+ *
+ * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery
+ */
+ public function getDocumentID() {
+ return $this->documentID;
+ }
+ /**
+ * Unloads whole document from memory.
+ * CAUTION! None further operations will be possible on this document.
+ * All objects refering to it will be useless.
+ *
+ * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery
+ */
+ public function unloadDocument() {
+ phpQuery::unloadDocuments($this->getDocumentID());
+ }
+ public function isHTML() {
+ return $this->documentWrapper->isHTML;
+ }
+ public function isXHTML() {
+ return $this->documentWrapper->isXHTML;
+ }
+ public function isXML() {
+ return $this->documentWrapper->isXML;
+ }
+ /**
+ * Enter description here...
+ *
+ * @link http://docs.jquery.com/Ajax/serialize
+ * @return string
+ */
+ public function serialize() {
+ return phpQuery::param($this->serializeArray());
+ }
+
+ /**
+ * Enter description here...
+ *
+ * @link http://docs.jquery.com/Ajax/serializeArray
+ * @return array
+ */
+ public function serializeArray($submit = null) {
+ $source = $this->filter('form, input, select, textarea')
+ ->find('input, select, textarea')
+ ->andSelf()
+ ->not('form');
+ $return = array();
+// $source->dumpDie();
+ foreach($source as $input) {
+ $input = phpQuery::pq($input);
+ if ($input->is('[disabled]'))
+ continue;
+ if (!$input->is('[name]'))
+ continue;
+ if ($input->is('[type=checkbox]') && !$input->is('[checked]'))
+ continue;
+ // jquery diff
+ if ($submit && $input->is('[type=submit]')) {
+ if ($submit instanceof DOMELEMENT && ! $input->elements[0]->isSameNode($submit))
+ continue;
+ else if (is_string($submit) && $input->attr('name') != $submit)
+ continue;
+ }
+ $return[] = array(
+ 'name' => $input->attr('name'),
+ 'value' => $input->val(),
+ );
+ }
+ return $return;
+ }
+ /**
+ * @access private
+ */
+ protected function debug($in) {
+ if (! phpQuery::$debug )
+ return;
+ print('<pre>');
+ print_r($in);
+ // file debug
+// file_put_contents(dirname(__FILE__).'/phpQuery.log', print_r($in, true)."\n", FILE_APPEND);
+ // quite handy debug trace
+// if ( is_array($in))
+// print_r(array_slice(debug_backtrace(), 3));
+ print("</pre>\n");
+ }
+ /**
+ * @access private
+ */
+ protected function isRegexp($pattern) {
+ return in_array(
+ $pattern[ mb_strlen($pattern)-1 ],
+ array('^','*','$')
+ );
+ }
+ /**
+ * Determines if $char is really a char.
+ *
+ * @param string $char
+ * @return bool
+ * @todo rewrite me to charcode range ! ;)
+ * @access private
+ */
+ protected function isChar($char) {
+ return extension_loaded('mbstring')
+ ? mb_eregi('\w', $char)
+ : preg_match('@\w@', $char);
+ }
+ /**
+ * @access private
+ */
+ protected function parseSelector( $query) {
+ // clean spaces
+ // TODO include this inside parsing ?
+ $query = trim(
+ preg_replace('@\s+@', ' ',
+ preg_replace('@\s*(>|\\+|~)\s*@', '\\1', $query)
+ )
+ );
+ $queries = array(array());
+ if (! $query)
+ return $queries;
+ $return =& $queries[0];
+ $specialChars = array('>',' ');
+// $specialCharsMapping = array('/' => '>');
+ $specialCharsMapping = array();
+ $strlen = mb_strlen($query);
+ $classChars = array('.', '-');
+ $pseudoChars = array('-');
+ $tagChars = array('*', '|', '-');
+ // split multibyte string
+ // http://code.google.com/p/phpquery/issues/detail?id=76
+ $_query = array();
+ for ($i=0; $i<$strlen; $i++)
+ $_query[] = mb_substr($query, $i, 1);
+ $query = $_query;
+ // it works, but i dont like it...
+ $i = 0;
+ while( $i < $strlen) {
+ $c = $query[$i];
+ $tmp = '';
+ // TAG
+ if ($this->isChar($c) || in_array($c, $tagChars)) {
+ while(isset($query[$i])
+ && ($this->isChar($query[$i]) || in_array($query[$i], $tagChars))) {
+ $tmp .= $query[$i];
+ $i++;
+ }
+ $return[] = $tmp;
+ // IDs
+ } else if ( $c == '#') {
+ $i++;
+ while( isset($query[$i]) && ($this->isChar($query[$i]) || $query[$i] == '-')) {
+ $tmp .= $query[$i];
+ $i++;
+ }
+ $return[] = '#'.$tmp;
+ // SPECIAL CHARS
+ } else if (in_array($c, $specialChars)) {
+ $return[] = $c;
+ $i++;
+ // MAPPED SPECIAL MULTICHARS
+// } else if ( $c.$query[$i+1] == '//') {
+// $return[] = ' ';
+// $i = $i+2;
+ // MAPPED SPECIAL CHARS
+ } else if ( isset($specialCharsMapping[$c])) {
+ $return[] = $specialCharsMapping[$c];
+ $i++;
+ // COMMA
+ } else if ( $c == ',') {
+ $queries[] = array();
+ $return =& $queries[ count($queries)-1 ];
+ $i++;
+ while( isset($query[$i]) && $query[$i] == ' ')
+ $i++;
+ // CLASSES
+ } else if ($c == '.') {
+ while( isset($query[$i]) && ($this->isChar($query[$i]) || in_array($query[$i], $classChars))) {
+ $tmp .= $query[$i];
+ $i++;
+ }
+ $return[] = $tmp;
+ // ~ General Sibling Selector
+ } else if ($c == '~') {
+ $spaceAllowed = true;
+ $tmp .= $query[$i++];
+ while( isset($query[$i])
+ && ($this->isChar($query[$i])
+ || in_array($query[$i], $classChars)
+ || $query[$i] == '*'
+ || ($query[$i] == ' ' && $spaceAllowed)
+ )) {
+ if ($query[$i] != ' ')
+ $spaceAllowed = false;
+ $tmp .= $query[$i];
+ $i++;
+ }
+ $return[] = $tmp;
+ // + Adjacent sibling selectors
+ } else if ($c == '+') {
+ $spaceAllowed = true;
+ $tmp .= $query[$i++];
+ while( isset($query[$i])
+ && ($this->isChar($query[$i])
+ || in_array($query[$i], $classChars)
+ || $query[$i] == '*'
+ || ($spaceAllowed && $query[$i] == ' ')
+ )) {
+ if ($query[$i] != ' ')
+ $spaceAllowed = false;
+ $tmp .= $query[$i];
+ $i++;
+ }
+ $return[] = $tmp;
+ // ATTRS
+ } else if ($c == '[') {
+ $stack = 1;
+ $tmp .= $c;
+ while( isset($query[++$i])) {
+ $tmp .= $query[$i];
+ if ( $query[$i] == '[') {
+ $stack++;
+ } else if ( $query[$i] == ']') {
+ $stack--;
+ if (! $stack )
+ break;
+ }
+ }
+ $return[] = $tmp;
+ $i++;
+ // PSEUDO CLASSES
+ } else if ($c == ':') {
+ $stack = 1;
+ $tmp .= $query[$i++];
+ while( isset($query[$i]) && ($this->isChar($query[$i]) || in_array($query[$i], $pseudoChars))) {
+ $tmp .= $query[$i];
+ $i++;
+ }
+ // with arguments ?
+ if ( isset($query[$i]) && $query[$i] == '(') {
+ $tmp .= $query[$i];
+ $stack = 1;
+ while( isset($query[++$i])) {
+ $tmp .= $query[$i];
+ if ( $query[$i] == '(') {
+ $stack++;
+ } else if ( $query[$i] == ')') {
+ $stack--;
+ if (! $stack )
+ break;
+ }
+ }
+ $return[] = $tmp;
+ $i++;
+ } else {
+ $return[] = $tmp;
+ }
+ } else {
+ $i++;
+ }
+ }
+ foreach($queries as $k => $q) {
+ if (isset($q[0])) {
+ if (isset($q[0][0]) && $q[0][0] == ':')
+ array_unshift($queries[$k], '*');
+ if ($q[0] != '>')
+ array_unshift($queries[$k], ' ');
+ }
+ }
+ return $queries;
+ }
+
+ /**
+ * Return matched DOM nodes.
+ *
+ * @param int $index
+ * @return array|DOMElement Single DOMElement or array of DOMElement.
+ */
+ public function get($index = null, $callback1 = null, $callback2 = null, $callback3 = null) {
+ $return = isset($index)
+ ? (isset($this->elements[$index]) ? $this->elements[$index] : null)
+ : $this->elements;
+ // pass thou callbacks
+ $args = func_get_args();
+ $args = array_slice($args, 1);
+ foreach($args as $callback) {
+ if (is_array($return))
+ foreach($return as $k => $v)
+ $return[$k] = phpQuery::callbackRun($callback, array($v));
+ else
+ $return = phpQuery::callbackRun($callback, array($return));
+ }
+ return $return;
+ }
+ /**
+ * Return matched DOM nodes.
+ * jQuery difference.
+ *
+ * @param int $index
+ * @return array|string Returns string if $index != null
+ * @todo implement callbacks
+ * @todo return only arrays ?
+ * @todo maybe other name...
+ */
+ public function getString($index = null, $callback1 = null, $callback2 = null, $callback3 = null) {
+ if ($index)
+ $return = $this->eq($index)->text();
+ else {
+ $return = array();
+ for($i = 0; $i < $this->size(); $i++) {
+ $return[] = $this->eq($i)->text();
+ }
+ }
+ // pass thou callbacks
+ $args = func_get_args();
+ $args = array_slice($args, 1);
+ foreach($args as $callback) {
+ $return = phpQuery::callbackRun($callback, array($return));
+ }
+ return $return;
+ }
+ /**
+ * Return matched DOM nodes.
+ * jQuery difference.
+ *
+ * @param int $index
+ * @return array|string Returns string if $index != null
+ * @todo implement callbacks
+ * @todo return only arrays ?
+ * @todo maybe other name...
+ */
+ public function getStrings($index = null, $callback1 = null, $callback2 = null, $callback3 = null) {
+ if ($index)
+ $return = $this->eq($index)->text();
+ else {
+ $return = array();
+ for($i = 0; $i < $this->size(); $i++) {
+ $return[] = $this->eq($i)->text();
+ }
+ // pass thou callbacks
+ $args = func_get_args();
+ $args = array_slice($args, 1);
+ }
+ foreach($args as $callback) {
+ if (is_array($return))
+ foreach($return as $k => $v)
+ $return[$k] = phpQuery::callbackRun($callback, array($v));
+ else
+ $return = phpQuery::callbackRun($callback, array($return));
+ }
+ return $return;
+ }
+ /**
+ * Returns new instance of actual class.
+ *
+ * @param array $newStack Optional. Will replace old stack with new and move old one to history.c
+ */
+ public function newInstance($newStack = null) {
+ $class = get_class($this);
+ // support inheritance by passing old object to overloaded constructor
+ $new = $class != 'phpQuery'
+ ? new $class($this, $this->getDocumentID())
+ : new phpQueryObject($this->getDocumentID());
+ $new->previous = $this;
+ if (is_null($newStack)) {
+ $new->elements = $this->elements;
+ if ($this->elementsBackup)
+ $this->elements = $this->elementsBackup;
+ } else {
+ $new->elements = $newStack;
+ }
+ return $new;
+ }
+
+ /**
+ * Enter description here...
+ *
+ * In the future, when PHP will support XLS 2.0, then we would do that this way:
+ * contains(tokenize(@class, '\s'), "something")
+ * @param unknown_type $class
+ * @param unknown_type $node
+ * @return boolean
+ * @access private
+ */
+ protected function matchClasses( $class, $node) {
+ // multi-class
+ if ( mb_strpos($class, '.', 1)) {
+ $classes = explode('.', substr($class, 1));
+ $classesCount = count( $classes );
+ $nodeClasses = explode(' ', $node->getAttribute('class') );
+ $nodeClassesCount = count( $nodeClasses );
+ if ( $classesCount > $nodeClassesCount )
+ return false;
+ $diff = count(
+ array_diff(
+ $classes,
+ $nodeClasses
+ )
+ );
+ if (! $diff )
+ return true;
+ // single-class
+ } else {
+ return in_array(
+ // strip leading dot from class name
+ substr($class, 1),
+ // get classes for element as array
+ explode(' ', $node->getAttribute('class') )
+ );
+ }
+ }
+ /**
+ * @access private
+ */
+ protected function runQuery( $XQuery, $selector = null, $compare = null) {
+ if ( $compare && ! method_exists($this, $compare) )
+ return false;
+ $stack = array();
+ if (! $this->elements )
+ $this->debug('Stack empty, skipping...');
+ // XXX foreach($this->stack(1) ???
+ foreach($this->elements as $k => $stackNode) {
+ $detachAfter = false;
+ // to work on detached nodes we need temporary place them somewhere
+ // thats because context xpath queries sucks ;]
+ $testNode = $stackNode;
+ while ($testNode) {
+ if (! $testNode->parentNode && ! $this->isRoot($testNode)) {
+ $this->root->appendChild($testNode);
+ $detachAfter = $testNode;
+ break;
+ }
+ $testNode = isset($testNode->parentNode)
+ ? $testNode->parentNode
+ : null;
+ }
+ // TODO tmp
+ $xpath = $this->documentWrapper->isXHTML
+ ? $this->getNodeXpath($stackNode, 'html')
+ : $this->getNodeXpath($stackNode);
+ // FIXME deam...
+ $query = $XQuery == '//' && $xpath == '/html[1]'
+ ? '//*'
+ : $xpath.$XQuery;
+ $this->debug("XPATH: {$query}");
+ // run query, get elements
+ $nodes = $this->xpath->query($query);
+ $this->debug("QUERY FETCHED");
+ if (! $nodes->length )
+ $this->debug('Nothing found');
+ $debug = array();
+ foreach($nodes as $node) {
+ $matched = false;
+ if ( $compare) {
+ phpQuery::$debug ?
+ $this->debug("Found: ".$this->whois( $node ).", comparing with {$compare}()")
+ : null;
+ $phpQueryDebug = phpQuery::$debug;
+ phpQuery::$debug = false;
+ // TODO ??? use phpQuery::callbackRun()
+ if (call_user_func_array(array($this, $compare), array($selector, $node)))
+ $matched = true;
+ phpQuery::$debug = $phpQueryDebug;
+ } else {
+ $matched = true;
+ }
+ if ( $matched) {
+ if (phpQuery::$debug)
+ $debug[] = $this->whois( $node );
+ $stack[] = $node;
+ }
+ }
+ if (phpQuery::$debug) {
+ $this->debug("Matched ".count($debug).": ".implode(', ', $debug));
+ }
+ if ($detachAfter)
+ $this->root->removeChild($detachAfter);
+ }
+ $this->elements = $stack;
+ }
+ /**
+ * Enter description here...
+ *
+ * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery
+ */
+ public function find( $selectors, $context = null, $noHistory = false) {
+ if (!$noHistory)
+ // backup last stack /for end()/
+ $this->elementsBackup = $this->elements;
+ // allow to define context
+ if ($context) {
+ if (! is_array($context) && $context instanceof DOMELEMENT)
+ $this->elements = array($context);
+ else if ( is_array($context)) {
+ $this->elements = array();
+ foreach ($context as $e)
+ if ($c instanceof DOMELEMENT)
+ $this->elements[] = $c;
+
+ } else if ( $context instanceof self )
+ $this->elements = $context->elements;
+ }
+ $queries = $this->parseSelector($selectors);
+ $this->debug(array('FIND',$selectors,$queries));
+ $XQuery = '';
+ // remember stack state because of multi-queries
+ $oldStack = $this->elements;
+ // here we will be keeping found elements
+ $stack = array();
+ foreach($queries as $selector) {
+ $this->elements = $oldStack;
+ $delimiterBefore = false;
+ foreach($selector as $s) {
+ // TAG
+ $isTag = extension_loaded('mbstring')
+ ? mb_ereg_match('^[\w|\||-]+$', $s) || $s == '*'
+ : preg_match('@^[\w|\||-]+$@', $s) || $s == '*';
+ if ($isTag) {
+ if ($this->isXML()) {
+ // namespace support
+ if (mb_strpos($s, '|') !== false) {
+ list($ns, $tag) = explode('|', $s);
+ $XQuery .= "$ns:$tag";
+ } else if ($s == '*') {
+ $XQuery .= "*";
+ } else {
+ $XQuery .= "*[local-name()='$s']";
+ }
+ } else {
+ $XQuery .= $s;
+ }
+ // ID
+ } else if ( $s[0] == '#') {
+ if ( $delimiterBefore )
+ $XQuery .= '*';
+ $XQuery .= "[@id='".substr($s, 1)."']";
+ // ATTRIBUTES
+ } else if ($s[0] == '[') {
+ if ( $delimiterBefore )
+ $XQuery .= '*';
+ // strip side brackets
+ $attr = trim($s, '][');
+ $execute = false;
+ // attr with specifed value
+ if (mb_strpos( $s, '=' )) {
+ list($attr, $value) = explode('=', $attr);
+ $value = trim($value, "'\"");
+ if ($this->isRegexp($attr)) {
+ // cut regexp character
+ $attr = substr($attr, 0, -1);
+ $execute = true;
+ $XQuery .= "[@{$attr}]";
+ } else {
+ $XQuery .= "[@{$attr}='{$value}']";
+ }
+ // attr without specified value
+ } else {
+ $XQuery .= "[@{$attr}]";
+ }
+ if ($execute) {
+ $this->runQuery($XQuery, $s, 'is');
+ $XQuery = '';
+ if (! $this->length() )
+ break;
+ }
+ // CLASSES
+ } else if ( $s[0] == '.') {
+ // TODO use return $this->find("./self::*[contains(concat(\" \",@class,\" \"), \" $class \")]");
+ // thx wizDom ;)
+ if ( $delimiterBefore )
+ $XQuery .= '*';
+ $XQuery .= '[@class]';
+ $this->runQuery($XQuery, $s, 'matchClasses');
+ $XQuery = '';
+ if (! $this->length() )
+ break;
+ // ~ General Sibling Selector
+ } else if ( $s[0] == '~') {
+ $this->runQuery($XQuery);
+ $XQuery = '';
+ $this->elements = $this
+ ->siblings(
+ substr($s, 1)
+ )->elements;
+ if (! $this->length() )
+ break;
+ // + Adjacent sibling selectors
+ } else if ( $s[0] == '+') {
+ // TODO /following-sibling::
+ $this->runQuery($XQuery);
+ $XQuery = '';
+ $subSelector = substr($s, 1);
+ $subElements = $this->elements;
+ $this->elements = array();
+ foreach($subElements as $node) {
+ // search first DOMElement sibling
+ $test = $node->nextSibling;
+ while($test && ! ($test instanceof DOMELEMENT))
+ $test = $test->nextSibling;
+ if ($test && $this->is($subSelector, $test))
+ $this->elements[] = $test;
+ }
+ if (! $this->length() )
+ break;
+ // PSEUDO CLASSES
+ } else if ( $s[0] == ':') {
+ // TODO optimization for :first :last
+ if ( $XQuery) {
+ $this->runQuery($XQuery);
+ $XQuery = '';
+ }
+ if (! $this->length() )
+ break;
+ $this->pseudoClasses($s);
+ if (! $this->length() )
+ break;
+ // DIRECT DESCENDANDS
+ } else if ( $s == '>') {
+ $XQuery .= '/';
+ $delimiterBefore = 2;
+ } else {
+ $XQuery .= '//';
+ $delimiterBefore = 2;
+ }
+ $delimiterBefore = $delimiterBefore === 2
+ ? true : false;
+ }
+ // run query if any
+ if ( $XQuery && $XQuery != '//') {
+ $this->runQuery($XQuery);
+ $XQuery = '';
+// if (! $this->length() )
+// break;
+ }
+ foreach($this->elements as $node )
+ if (! $this->elementsContainsNode($node, $stack) )
+ $stack[] = $node;
+ }
+ $this->elements = $stack;
+ return $this->newInstance();
+ }
+
+ /**
+ * @todo create API for classes with pseudoselectors
+ * @access private
+ */
+ protected function pseudoClasses($class) {
+ // TODO clean args parsing ?
+ $class = ltrim($class, ':');
+ $haveArgs = mb_strpos($class, '(');
+ if ($haveArgs !== false) {
+ $args = substr($class, $haveArgs+1, -1);
+ $class = substr($class, 0, $haveArgs);
+ }
+ switch($class) {
+ case 'even':
+ case 'odd':
+ $stack = array();
+ foreach($this->elements as $i => $node) {
+ if ($class == 'even' && ($i%2) == 0)
+ $stack[] = $node;
+ else if ( $class == 'odd' && $i % 2 )
+ $stack[] = $node;
+ }
+ $this->elements = $stack;
+ break;
+ case 'eq':
+ $k = intval($args);
+ $this->elements = isset( $this->elements[$k] )
+ ? array( $this->elements[$k] )
+ : array();
+ break;
+ case 'gt':
+ $this->elements = array_slice($this->elements, $args+1);
+ break;
+ case 'lt':
+ $this->elements = array_slice($this->elements, 0, $args+1);
+ break;
+ case 'first':
+ if (isset($this->elements[0]))
+ $this->elements = array($this->elements[0]);
+ break;
+ case 'last':
+ if ($this->elements)
+ $this->elements = array($this->elements[count($this->elements)-1]);
+ break;
+ /*case 'parent':
+ $stack = array();
+ foreach($this->elements as $node) {
+ if ( $node->childNodes->length )
+ $stack[] = $node;
+ }
+ $this->elements = $stack;
+ break;*/
+ case 'contains':
+ $text = trim($args, "\"'");
+ $stack = array();
+ foreach($this->elements as $node) {
+ if (mb_stripos($node->textContent, $text) === false)
+ continue;
+ $stack[] = $node;
+ }
+ $this->elements = $stack;
+ break;
+ case 'not':
+ $selector = self::unQuote($args);
+ $this->elements = $this->not($selector)->stack();
+ break;
+ case 'slice':
+ // TODO jQuery difference ?
+ $args = exlode(',',
+ str_replace(', ', ',', trim($args, "\"'"))
+ );
+ $start = $args[0];
+ $end = isset($args[1])
+ ? $args[1]
+ : null;
+ if ($end > 0)
+ $end = $end-$start;
+ $this->elements = array_slice($this->elements, $start, $end);
+ break;
+ case 'has':
+ $selector = trim($args, "\"'");
+ $stack = array();
+ foreach($this->stack(1) as $el) {
+ if ($this->find($selector, $el, true)->length)
+ $stack[] = $el;
+ }
+ $this->elements = $stack;
+ break;
+ case 'submit':
+ case 'reset':
+ $this->elements = phpQuery::merge(
+ $this->map(array($this, 'is'),
+ "input[type=$class]", new CallbackParam()
+ ),
+ $this->map(array($this, 'is'),
+ "button[type=$class]", new CallbackParam()
+ )
+ );
+ break;
+// $stack = array();
+// foreach($this->elements as $node)
+// if ($node->is('input[type=submit]') || $node->is('button[type=submit]'))
+// $stack[] = $el;
+// $this->elements = $stack;
+ case 'input':
+ $this->elements = $this->map(
+ array($this, 'is'),
+ 'input', new CallbackParam()
+ )->elements;
+ break;
+ case 'password':
+ case 'checkbox':
+ case 'radio':
+ case 'hidden':
+ case 'image':
+ case 'file':
+ $this->elements = $this->map(
+ array($this, 'is'),
+ "input[type=$class]", new CallbackParam()
+ )->elements;
+ break;
+ case 'parent':
+ $this->elements = $this->map(
+ create_function('$node', '
+ return $node instanceof DOMELEMENT && $node->childNodes->length
+ ? $node : null;')
+ )->elements;
+ break;
+ case 'empty':
+ $this->elements = $this->map(
+ create_function('$node', '
+ return $node instanceof DOMELEMENT && $node->childNodes->length
+ ? null : $node;')
+ )->elements;
+ break;
+ case 'disabled':
+ case 'selected':
+ case 'checked':
+ $this->elements = $this->map(
+ array($this, 'is'),
+ "[$class]", new CallbackParam()
+ )->elements;
+ break;
+ case 'enabled':
+ $this->elements = $this->map(
+ create_function('$node', '
+ return pq($node)->not(":disabled") ? $node : null;')
+ )->elements;
+ break;
+ case 'header':
+ $this->elements = $this->map(
+ create_function('$node',
+ '$isHeader = isset($node->tagName) && in_array($node->tagName, array(
+ "h1", "h2", "h3", "h4", "h5", "h6", "h7"
+ ));
+ return $isHeader
+ ? $node
+ : null;')
+ )->elements;
+// $this->elements = $this->map(
+// create_function('$node', '$node = pq($node);
+// return $node->is("h1")
+// || $node->is("h2")
+// || $node->is("h3")
+// || $node->is("h4")
+// || $node->is("h5")
+// || $node->is("h6")
+// || $node->is("h7")
+// ? $node
+// : null;')
+// )->elements;
+ break;
+ case 'only-child':
+ $this->elements = $this->map(
+ create_function('$node',
+ 'return pq($node)->siblings()->size() == 0 ? $node : null;')
+ )->elements;
+ break;
+ case 'first-child':
+ $this->elements = $this->map(
+ create_function('$node', 'return pq($node)->prevAll()->size() == 0 ? $node : null;')
+ )->elements;
+ break;
+ case 'last-child':
+ $this->elements = $this->map(
+ create_function('$node', 'return pq($node)->nextAll()->size() == 0 ? $node : null;')
+ )->elements;
+ break;
+ case 'nth-child':
+ $param = trim($args, "\"'");
+ if (! $param)
+ break;
+ // nth-child(n+b) to nth-child(1n+b)
+ if ($param{0} == 'n')
+ $param = '1'.$param;
+ // :nth-child(index/even/odd/equation)
+ if ($param == 'even' || $param == 'odd')
+ $mapped = $this->map(
+ create_function('$node, $param',
+ '$index = pq($node)->prevAll()->size()+1;
+ if ($param == "even" && ($index%2) == 0)
+ return $node;
+ else if ($param == "odd" && $index%2 == 1)
+ return $node;
+ else
+ return null;'),
+ new CallbackParam(), $param
+ );
+ else if (mb_strlen($param) > 1 && $param{1} == 'n')
+ // an+b
+ $mapped = $this->map(
+ create_function('$node, $param',
+ '$prevs = pq($node)->prevAll()->size();
+ $index = 1+$prevs;
+ $b = mb_strlen($param) > 3
+ ? $param{3}
+ : 0;
+ $a = $param{0};
+ if ($b && $param{2} == "-")
+ $b = -$b;
+ if ($a > 0) {
+ return ($index-$b)%$a == 0
+ ? $node
+ : null;
+ phpQuery::debug($a."*".floor($index/$a)."+$b-1 == ".($a*floor($index/$a)+$b-1)." ?= $prevs");
+ return $a*floor($index/$a)+$b-1 == $prevs
+ ? $node
+ : null;
+ } else if ($a == 0)
+ return $index == $b
+ ? $node
+ : null;
+ else
+ // negative value
+ return $index <= $b
+ ? $node
+ : null;
+// if (! $b)
+// return $index%$a == 0
+// ? $node
+// : null;
+// else
+// return ($index-$b)%$a == 0
+// ? $node
+// : null;
+ '),
+ new CallbackParam(), $param
+ );
+ else
+ // index
+ $mapped = $this->map(
+ create_function('$node, $index',
+ '$prevs = pq($node)->prevAll()->size();
+ if ($prevs && $prevs == $index-1)
+ return $node;
+ else if (! $prevs && $index == 1)
+ return $node;
+ else
+ return null;'),
+ new CallbackParam(), $param
+ );
+ $this->elements = $mapped->elements;
+ break;
+ default:
+ $this->debug("Unknown pseudoclass '{$class}', skipping...");
+ }
+ }
+ /**
+ * @access private
+ */
+ protected function __pseudoClassParam($paramsString) {
+ // TODO;
+ }
+ /**
+ * Enter description here...
+ *
+ * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery
+ */
+ public function is($selector, $nodes = null) {
+ phpQuery::debug(array("Is:", $selector));
+ if (! $selector)
+ return false;
+ $oldStack = $this->elements;
+ $returnArray = false;
+ if ($nodes && is_array($nodes)) {
+ $this->elements = $nodes;
+ } else if ($nodes)
+ $this->elements = array($nodes);
+ $this->filter($selector, true);
+ $stack = $this->elements;
+ $this->elements = $oldStack;
+ if ($nodes)
+ return $stack ? $stack : null;
+ return (bool)count($stack);
+ }
+
+ /**
+ * Enter description here...
+ * jQuery difference.
+ *
+ * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery
+ * @link http://docs.jquery.com/Traversing/filter
+ */
+ public function filterCallback($callback, $_skipHistory = false) {
+ if (! $_skipHistory) {
+ $this->elementsBackup = $this->elements;
+ $this->debug(array("Filtering:", $selectors));
+ }
+ $newStack = array();
+ foreach($this->elements as $index => $node) {
+ if (false !== phpQuery::callbackRun($callback, array($index, $node)))
+ $newStack[] = $node;
+ }
+ $this->elements = $newStack;
+ return $_skipHistory
+ ? $this
+ : $this->newInstance();
+ }
+ /**
+ * Enter description here...
+ *
+ * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery
+ * @link http://docs.jquery.com/Traversing/filter
+ */
+ public function filter($selectors, $_skipHistory = false) {
+ if (! $_skipHistory)
+ $this->elementsBackup = $this->elements;
+ $notSimpleSelector = array(' ', '>', '~', '+', '/');
+ if (! is_array($selectors))
+ $selectors = $this->parseSelector($selectors);
+ if (! $_skipHistory)
+ $this->debug(array("Filtering:", $selectors));
+ $finalStack = array();
+ foreach($selectors as $selector) {
+ $stack = array();
+ if (! $selector)
+ break;
+ // avoid first space or /
+ if (in_array($selector[0], $notSimpleSelector))
+ $selector = array_slice($selector, 1);
+ // PER NODE selector chunks
+ foreach($this->stack() as $node) {
+ $break = false;
+ foreach($selector as $s) {
+ if (!($node instanceof DOMELEMENT)) {
+ // all besides DOMElement
+ if ( $s[0] == '[') {
+ $attr = trim($s, '[]');
+ if ( mb_strpos($attr, '=')) {
+ list( $attr, $val ) = explode('=', $attr);
+ if ($attr == 'nodeType' && $node->nodeType != $val)
+ $break = true;
+ }
+ } else
+ $break = true;
+ } else {
+ // DOMElement only
+ // ID
+ if ( $s[0] == '#') {
+ if ( $node->getAttribute('id') != substr($s, 1) )
+ $break = true;
+ // CLASSES
+ } else if ( $s[0] == '.') {
+ if (! $this->matchClasses( $s, $node ) )
+ $break = true;
+ // ATTRS
+ } else if ( $s[0] == '[') {
+ // strip side brackets
+ $attr = trim($s, '[]');
+ if (mb_strpos($attr, '=')) {
+ list($attr, $val) = explode('=', $attr);
+ $val = self::unQuote($val);
+ if ($attr == 'nodeType') {
+ if ($val != $node->nodeType)
+ $break = true;
+ } else if ($this->isRegexp($attr)) {
+ $val = extension_loaded('mbstring')
+ ? quotemeta(trim($val, '"\''))
+ : preg_quote(trim($val, '"\''), '@');
+ // switch last character
+ switch( substr($attr, -1)) {
+ // quotemeta used insted of preg_quote
+ // http://code.google.com/p/phpquery/issues/detail?id=76
+ case '^':
+ $pattern = '^'.$val;
+ break;
+ case '*':
+ $pattern = '.*'.$val.'.*';
+ break;
+ case '$':
+ $pattern = '.*'.$val.'$';
+ break;
+ }
+ // cut last character
+ $attr = substr($attr, 0, -1);
+ $isMatch = extension_loaded('mbstring')
+ ? mb_ereg_match($pattern, $node->getAttribute($attr))
+ : preg_match("@{$pattern}@", $node->getAttribute($attr));
+ if (! $isMatch)
+ $break = true;
+ } else if ($node->getAttribute($attr) != $val)
+ $break = true;
+ } else if (! $node->hasAttribute($attr))
+ $break = true;
+ // PSEUDO CLASSES
+ } else if ( $s[0] == ':') {
+ // skip
+ // TAG
+ } else if (trim($s)) {
+ if ($s != '*') {
+ // TODO namespaces
+ if (isset($node->tagName)) {
+ if ($node->tagName != $s)
+ $break = true;
+ } else if ($s == 'html' && ! $this->isRoot($node))
+ $break = true;
+ }
+ // AVOID NON-SIMPLE SELECTORS
+ } else if (in_array($s, $notSimpleSelector)) {
+ $break = true;
+ $this->debug(array('Skipping non simple selector', $selector));
+ }
+ }
+ if ($break)
+ break;
+ }
+ // if element passed all chunks of selector - add it to new stack
+ if (! $break )
+ $stack[] = $node;
+ }
+ $tmpStack = $this->elements;
+ $this->elements = $stack;
+ // PER ALL NODES selector chunks
+ foreach($selector as $s)
+ // PSEUDO CLASSES
+ if ($s[0] == ':')
+ $this->pseudoClasses($s);
+ foreach($this->elements as $node)
+ // XXX it should be merged without duplicates
+ // but jQuery doesnt do that
+ $finalStack[] = $node;
+ $this->elements = $tmpStack;
+ }
+ $this->elements = $finalStack;
+ if ($_skipHistory) {
+ return $this;
+ } else {
+ $this->debug("Stack length after filter(): ".count($finalStack));
+ return $this->newInstance();
+ }
+ }
+ /**
+ *
+ * @param $value
+ * @return unknown_type
+ * @TODO implement in all methods using passed parameters
+ */
+ protected static function unQuote($value) {
+ return $value[0] == '\'' || $value[0] == '"'
+ ? substr($value, 1, -1)
+ : $value;
+ }
+ /**
+ * Enter description here...
+ *
+ * @link http://docs.jquery.com/Ajax/load
+ * @return phpQuery|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery
+ * @todo Support $selector
+ */
+ public function load($url, $data = null, $callback = null) {
+ if ($data && ! is_array($data)) {
+ $callback = $data;
+ $data = null;
+ }
+ if (mb_strpos($url, ' ') !== false) {
+ $matches = null;
+ if (extension_loaded('mbstring'))
+ mb_ereg('^([^ ]+) (.*)$', $url, $matches);
+ else
+ preg_match('^([^ ]+) (.*)$', $url, $matches);
+ $url = $matches[1];
+ $selector = $matches[2];
+ // FIXME this sucks, pass as callback param
+ $this->_loadSelector = $selector;
+ }
+ $ajax = array(
+ 'url' => $url,
+ 'type' => $data ? 'POST' : 'GET',
+ 'data' => $data,
+ 'complete' => $callback,
+ 'success' => array($this, '__loadSuccess')
+ );
+ phpQuery::ajax($ajax);
+ return $this;
+ }
+ /**
+ * @access private
+ * @param $html
+ * @return unknown_type
+ */
+ public function __loadSuccess($html) {
+ if ($this->_loadSelector) {
+ $html = phpQuery::newDocument($html)->find($this->_loadSelector);
+ unset($this->_loadSelector);
+ }
+ foreach($this->stack(1) as $node) {
+ phpQuery::pq($node, $this->getDocumentID())
+ ->markup($html);
+ }
+ }
+ /**
+ * Enter description here...
+ *
+ * @return phpQuery|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery
+ * @todo
+ */
+ public function css() {
+ // TODO
+ return $this;
+ }
+ /**
+ * @todo
+ *
+ */
+ public function show(){
+ // TODO
+ return $this;
+ }
+ /**
+ * @todo
+ *
+ */
+ public function hide(){
+ // TODO
+ return $this;
+ }
+ /**
+ * Trigger a type of event on every matched element.
+ *
+ * @param unknown_type $type
+ * @param unknown_type $data
+ * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery
+ * @TODO support more than event in $type (space-separated)
+ */
+ public function trigger($type, $data = array()) {
+ foreach($this->elements as $node)
+ phpQueryEvents::trigger($this->getDocumentID(), $type, $data, $node);
+ return $this;
+ }
+ /**
+ * This particular method triggers all bound event handlers on an element (for a specific event type) WITHOUT executing the browsers default actions.
+ *
+ * @param unknown_type $type
+ * @param unknown_type $data
+ * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery
+ * @TODO
+ */
+ public function triggerHandler($type, $data = array()) {
+ // TODO;
+ }
+ /**
+ * Binds a handler to one or more events (like click) for each matched element.
+ * Can also bind custom events.
+ *
+ * @param unknown_type $type
+ * @param unknown_type $data Optional
+ * @param unknown_type $callback
+ * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery
+ * @TODO support '!' (exclusive) events
+ * @TODO support more than event in $type (space-separated)
+ */
+ public function bind($type, $data, $callback = null) {
+ // TODO check if $data is callable, not using is_callable
+ if (! isset($callback)) {
+ $callback = $data;
+ $data = null;
+ }
+ foreach($this->elements as $node)
+ phpQueryEvents::add($this->getDocumentID(), $node, $type, $data, $callback);
+ return $this;
+ }
+ /**
+ * Enter description here...
+ *
+ * @param unknown_type $type
+ * @param unknown_type $callback
+ * @return unknown
+ * @TODO namespace events
+ * @TODO support more than event in $type (space-separated)
+ */
+ public function unbind($type = null, $callback = null) {
+ foreach($this->elements as $node)
+ phpQueryEvents::remove($this->getDocumentID(), $node, $type, $callback);
+ return $this;
+ }
+ /**
+ * Enter description here...
+ *
+ * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery
+ */
+ public function change($callback = null) {
+ if ($callback)
+ return $this->bind('change', $callback);
+ return $this->trigger('change');
+ }
+ /**
+ * Enter description here...
+ *
+ * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery
+ */
+ public function submit($callback = null) {
+ if ($callback)
+ return $this->bind('submit', $callback);
+ return $this->trigger('submit');
+ }
+ /**
+ * Enter description here...
+ *
+ * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery
+ */
+ public function click($callback = null) {
+ if ($callback)
+ return $this->bind('click', $callback);
+ return $this->trigger('click');
+ }
+ /**
+ * Enter description here...
+ *
+ * @param String|phpQuery
+ * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery
+ */
+ public function wrapAllOld($wrapper) {
+ $wrapper = pq($wrapper)->_clone();
+ if (! $wrapper->length() || ! $this->length() )
+ return $this;
+ $wrapper->insertBefore($this->elements[0]);
+ $deepest = $wrapper->elements[0];
+ while($deepest->firstChild && $deepest->firstChild instanceof DOMELEMENT)
+ $deepest = $deepest->firstChild;
+ pq($deepest)->append($this);
+ return $this;
+ }
+
+ /**
+ * Enter description here...
+ *
+ * TODO testme...
+ * @param String|phpQuery
+ * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery
+ */
+ public function wrapAll($wrapper) {
+ if (! $this->length())
+ return $this;
+ return phpQuery::pq($wrapper, $this->getDocumentID())
+ ->clone()
+ ->insertBefore($this->get(0))
+ ->map(array($this, '___wrapAllCallback'))
+ ->append($this);
+ }
+ /**
+ *
+ * @param $node
+ * @return unknown_type
+ * @access private
+ */
+ public function ___wrapAllCallback($node) {
+ $deepest = $node;
+ while($deepest->firstChild && $deepest->firstChild instanceof DOMELEMENT)
+ $deepest = $deepest->firstChild;
+ return $deepest;
+ }
+
+ /**
+ * Enter description here...
+ * NON JQUERY METHOD
+ *
+ * @param String|phpQuery
+ * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery
+ */
+ public function wrapAllPHP($codeBefore, $codeAfter) {
+ return $this
+ ->slice(0, 1)
+ ->beforePHP($codeBefore)
+ ->end()
+ ->slice(-1)
+ ->afterPHP($codeAfter)
+ ->end();
+ }
+
+ /**
+ * Enter description here...
+ *
+ * @param String|phpQuery
+ * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery
+ */
+ public function wrap($wrapper) {
+ foreach($this->stack() as $node)
+ phpQuery::pq($node, $this->getDocumentID())->wrapAll($wrapper);
+ return $this;
+ }
+
+ /**
+ * Enter description here...
+ *
+ * @param String|phpQuery
+ * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery
+ */
+ public function wrapPHP($codeBefore, $codeAfter) {
+ foreach($this->stack() as $node)
+ phpQuery::pq($node, $this->getDocumentID())->wrapAllPHP($codeBefore, $codeAfter);
+ return $this;
+ }
+
+ /**
+ * Enter description here...
+ *
+ * @param String|phpQuery
+ * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery
+ */
+ public function wrapInner($wrapper) {
+ foreach($this->stack() as $node)
+ phpQuery::pq($node, $this->getDocumentID())->contents()->wrapAll($wrapper);
+ return $this;
+ }
+
+ /**
+ * Enter description here...
+ *
+ * @param String|phpQuery
+ * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery
+ */
+ public function wrapInnerPHP($codeBefore, $codeAfter) {
+ // TODO test this
+ foreach($this->stack(1) as $node)
+ phpQuery::pq($node, $this->getDocumentID())->contents()
+ ->wrapAllPHP($codeBefore, $codeBefore);
+ }
+
+ /**
+ * Enter description here...
+ *
+ * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery
+ * @testme Support for text nodes
+ */
+ public function contents() {
+ $stack = array();
+ foreach($this->stack(1) as $el) {
+ // FIXME (fixed) http://code.google.com/p/phpquery/issues/detail?id=56
+// if (! isset($el->childNodes))
+// continue;
+ foreach($el->childNodes as $node) {
+ $stack[] = $node;
+ }
+ }
+ return $this->newInstance($stack);
+ }
+ /**
+ * Enter description here...
+ *
+ * jQuery difference.
+ *
+ * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery
+ */
+ public function contentsUnwrap() {
+ foreach($this->stack(1) as $node) {
+ if (! $node->parentNode )
+ continue;
+ $childNodes = array();
+ // any modification in DOM tree breaks childNodes iteration, so cache them first
+ foreach($node->childNodes as $chNode )
+ $childNodes[] = $chNode;
+ foreach($childNodes as $chNode )
+// $node->parentNode->appendChild($chNode);
+ $node->parentNode->insertBefore($chNode, $node);
+ $node->parentNode->removeChild($node);
+ }
+ return $this;
+ }
+ /**
+ * Enter description here...
+ *
+ * jQuery difference.
+ */
+ public function switchWith($markup) {
+ $markup = pq($markup, $this->getDocumentID());
+ $content = null;
+ foreach($this->stack(1) as $node) {
+ pq($node)
+ ->contents()->toReference($content)->end()
+ ->replaceWith($markup->clone()->append($content));
+ }
+ return $this;
+ }
+
+ /**
+ * Enter description here...
+ *
+ * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery
+ */
+ public function eq($num) {
+ $oldStack = $this->elements;
+ $this->elementsBackup = $this->elements;
+ $this->elements = array();
+ if ( isset($oldStack[$num]) )
+ $this->elements[] = $oldStack[$num];
+ return $this->newInstance();
+ }
+
+ /**
+ * Enter description here...
+ *
+ * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery
+ */
+ public function size() {
+ return count($this->elements);
+ }
+
+ /**
+ * Enter description here...
+ *
+ * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery
+ * @deprecated Use length as attribute
+ */
+ public function length() {
+ return $this->size();
+ }
+ public function count() {
+ return $this->size();
+ }
+
+ /**
+ * Enter description here...
+ *
+ * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery
+ * @todo $level
+ */
+ public function end($level = 1) {
+// $this->elements = array_pop( $this->history );
+// return $this;
+// $this->previous->DOM = $this->DOM;
+// $this->previous->XPath = $this->XPath;
+ return $this->previous
+ ? $this->previous
+ : $this;
+ }
+ /**
+ * Enter description here...
+ * Normal use ->clone() .
+ *
+ * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery
+ * @access private
+ */
+ public function _clone() {
+ $newStack = array();
+ //pr(array('copy... ', $this->whois()));
+ //$this->dumpHistory('copy');
+ $this->elementsBackup = $this->elements;
+ foreach($this->elements as $node) {
+ $newStack[] = $node->cloneNode(true);
+ }
+ $this->elements = $newStack;
+ return $this->newInstance();
+ }
+
+ /**
+ * Enter description here...
+ *
+ * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery
+ */
+ public function replaceWithPHP($code) {
+ return $this->replaceWith(phpQuery::php($code));
+ }
+
+ /**
+ * Enter description here...
+ *
+ * @param String|phpQuery $content
+ * @link http://docs.jquery.com/Manipulation/replaceWith#content
+ * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery
+ */
+ public function replaceWith($content) {
+ return $this->after($content)->remove();
+ }
+
+ /**
+ * Enter description here...
+ *
+ * @param String $selector
+ * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery
+ * @todo this works ?
+ */
+ public function replaceAll($selector) {
+ foreach(phpQuery::pq($selector, $this->getDocumentID()) as $node)
+ phpQuery::pq($node, $this->getDocumentID())
+ ->after($this->_clone())
+ ->remove();
+ return $this;
+ }
+
+ /**
+ * Enter description here...
+ *
+ * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery
+ */
+ public function remove($selector = null) {
+ $loop = $selector
+ ? $this->filter($selector)->elements
+ : $this->elements;
+ foreach($loop as $node) {
+ if (! $node->parentNode )
+ continue;
+ if (isset($node->tagName))
+ $this->debug("Removing '{$node->tagName}'");
+ $node->parentNode->removeChild( $node );
+ }
+ return $this;
+ }
+ protected function markupEvents($newMarkup, $oldMarkup, $node) {
+ if ($node->tagName == 'textarea' && $newMarkup != $oldMarkup) {
+ $event = new DOMEvent(array(
+ 'target' => $node,
+ 'type' => 'change'
+ ));
+ phpQueryEvents::trigger($this->getDocumentID(),
+ $event->type, array($event), $node
+ );
+ }
+ }
+ /**
+ * jQuey difference
+ *
+ * @param $markup
+ * @return unknown_type
+ * @TODO trigger change event for textarea
+ */
+ public function markup($markup = null, $callback1 = null, $callback2 = null, $callback3 = null) {
+ $args = func_get_args();
+ if ($this->documentWrapper->isXML)
+ return call_user_func_array(array($this, 'xml'), $args);
+ else
+ return call_user_func_array(array($this, 'html'), $args);
+ }
+ /**
+ * jQuey difference
+ *
+ * @param $markup
+ * @return unknown_type
+ */
+ public function markupOuter($callback1 = null, $callback2 = null, $callback3 = null) {
+ $args = func_get_args();
+ if ($this->documentWrapper->isXML)
+ return call_user_func_array(array($this, 'xmlOuter'), $args);
+ else
+ return call_user_func_array(array($this, 'htmlOuter'), $args);
+ }
+ /**
+ * Enter description here...
+ *
+ * @param unknown_type $html
+ * @return string|phpQuery|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery
+ * @TODO force html result
+ */
+ public function html($html = null, $callback1 = null, $callback2 = null, $callback3 = null) {
+ if (isset($html)) {
+ // INSERT
+ $nodes = $this->documentWrapper->import($html);
+ $this->empty();
+ foreach($this->stack(1) as $alreadyAdded => $node) {
+ // for now, limit events for textarea
+ if (($this->isXHTML() || $this->isHTML()) && $node->tagName == 'textarea')
+ $oldHtml = pq($node, $this->getDocumentID())->markup();
+ foreach($nodes as $newNode) {
+ $node->appendChild($alreadyAdded
+ ? $newNode->cloneNode(true)
+ : $newNode
+ );
+ }
+ // for now, limit events for textarea
+ if (($this->isXHTML() || $this->isHTML()) && $node->tagName == 'textarea')
+ $this->markupEvents($html, $oldHtml, $node);
+ }
+ return $this;
+ } else {
+ // FETCH
+ $return = $this->documentWrapper->markup($this->elements, true);
+ $args = func_get_args();
+ foreach(array_slice($args, 1) as $callback) {
+ $return = phpQuery::callbackRun($callback, array($return));
+ }
+ return $return;
+ }
+ }
+ /**
+ * @TODO force xml result
+ */
+ public function xml($xml = null, $callback1 = null, $callback2 = null, $callback3 = null) {
+ $args = func_get_args();
+ return call_user_func_array(array($this, 'html'), $args);
+ }
+ /**
+ * Enter description here...
+ * @TODO force html result
+ *
+ * @return String
+ */
+ public function htmlOuter($callback1 = null, $callback2 = null, $callback3 = null) {
+ $markup = $this->documentWrapper->markup($this->elements);
+ // pass thou callbacks
+ $args = func_get_args();
+ foreach($args as $callback) {
+ $markup = phpQuery::callbackRun($callback, array($markup));
+ }
+ return $markup;
+ }
+ /**
+ * @TODO force xml result
+ */
+ public function xmlOuter($callback1 = null, $callback2 = null, $callback3 = null) {
+ $args = func_get_args();
+ return call_user_func_array(array($this, 'htmlOuter'), $args);
+ }
+ public function __toString() {
+ return $this->htmlOuter();
+ }
+ /**
+ * Just like html(), but returns markup with VALID (dangerous) PHP tags.
+ *
+ * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery
+ * @todo support returning markup with PHP tags when called without param
+ */
+ public function php($code = null) {
+// TODO
+// $args = func_get_args();
+ return $code
+ ? $this->markup(phpQuery::php($code))
+ : phpQuery::markupToPHP($this->markupOuter());
+ }
+ /**
+ * Enter description here...
+ *
+ * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery
+ */
+ public function children($selector = null) {
+ $stack = array();
+ foreach($this->stack(1) as $node) {
+// foreach($node->getElementsByTagName('*') as $newNode) {
+ foreach($node->childNodes as $newNode) {
+ if ($newNode->nodeType != 1)
+ continue;
+ if ($selector && ! $this->is($selector, $newNode))
+ continue;
+ if ($this->elementsContainsNode($newNode, $stack))
+ continue;
+ $stack[] = $newNode;
+ }
+ }
+ $this->elementsBackup = $this->elements;
+ $this->elements = $stack;
+ return $this->newInstance();
+ }
+
+ /**
+ * Enter description here...
+ *
+ * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery
+ */
+ public function ancestors($selector = null) {
+ return $this->children( $selector );
+ }
+
+ /**
+ * Enter description here...
+ *
+ * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery
+ */
+ public function append( $content) {
+ return $this->insert($content, __FUNCTION__);
+ }
+ /**
+ * Enter description here...
+ *
+ * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery
+ */
+ public function appendPHP( $content) {
+ return $this->insert("<php><!-- {$content} --></php>", 'append');
+ }
+ /**
+ * Enter description here...
+ *
+ * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery
+ */
+ public function appendTo( $seletor) {
+ return $this->insert($seletor, __FUNCTION__);
+ }
+
+ /**
+ * Enter description here...
+ *
+ * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery
+ */
+ public function prepend( $content) {
+ return $this->insert($content, __FUNCTION__);
+ }
+ /**
+ * Enter description here...
+ *
+ * @todo accept many arguments, which are joined, arrays maybe also
+ * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery
+ */
+ public function prependPHP( $content) {
+ return $this->insert("<php><!-- {$content} --></php>", 'prepend');
+ }
+ /**
+ * Enter description here...
+ *
+ * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery
+ */
+ public function prependTo( $seletor) {
+ return $this->insert($seletor, __FUNCTION__);
+ }
+
+ /**
+ * Enter description here...
+ *
+ * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery
+ */
+ public function before( $content) {
+ return $this->insert($content, __FUNCTION__);
+ }
+ /**
+ * Enter description here...
+ *
+ * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery
+ */
+ public function beforePHP( $content) {
+ return $this->insert("<php><!-- {$content} --></php>", 'before');
+ }
+ /**
+ * Enter description here...
+ *
+ * @param String|phpQuery
+ * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery
+ */
+ public function insertBefore( $seletor) {
+ return $this->insert($seletor, __FUNCTION__);
+ }
+
+ /**
+ * Enter description here...
+ *
+ * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery
+ */
+ public function after( $content) {
+ return $this->insert($content, __FUNCTION__);
+ }
+ /**
+ * Enter description here...
+ *
+ * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery
+ */
+ public function afterPHP( $content) {
+ return $this->insert("<php><!-- {$content} --></php>", 'after');
+ }
+ /**
+ * Enter description here...
+ *
+ * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery
+ */
+ public function insertAfter( $seletor) {
+ return $this->insert($seletor, __FUNCTION__);
+ }
+
+ /**
+ * Internal insert method. Don't use it.
+ *
+ * @param unknown_type $target
+ * @param unknown_type $type
+ * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery
+ * @access private
+ */
+ public function insert($target, $type) {
+ $this->debug("Inserting data with '{$type}'");
+ $to = false;
+ switch( $type) {
+ case 'appendTo':
+ case 'prependTo':
+ case 'insertBefore':
+ case 'insertAfter':
+ $to = true;
+ }
+ switch(gettype( $target )) {
+ case 'string':
+ $insertFrom = $insertTo = array();
+ if ($to) {
+ // INSERT TO
+ $insertFrom = $this->elements;
+ if (phpQuery::isMarkup( $target )) {
+ // $target is new markup, import it
+ $insertTo = $this->documentWrapper->import($target);
+ // insert into selected element
+ } else {
+ // $tagret is a selector
+ $thisStack = $this->elements;
+ $this->toRoot();
+ $insertTo = $this->find($target)->elements;
+ $this->elements = $thisStack;
+ }
+ } else {
+ // INSERT FROM
+ $insertTo = $this->elements;
+ $insertFrom = $this->documentWrapper->import($target);
+ }
+ break;
+ case 'object':
+ $insertFrom = $insertTo = array();
+ // phpQuery
+ if ($target instanceof self) {
+ if ($to) {
+ $insertTo = $target->elements;
+ if ($this->documentFragment && $this->stackIsRoot())
+ // get all body children
+// $loop = $this->find('body > *')->elements;
+ // TODO test it, test it hard...
+// $loop = $this->newInstance($this->root)->find('> *')->elements;
+ $loop = $this->root->childNodes;
+ else
+ $loop = $this->elements;
+ // import nodes if needed
+ $insertFrom = $this->getDocumentID() == $target->getDocumentID()
+ ? $loop
+ : $target->documentWrapper->import($loop);
+ } else {
+ $insertTo = $this->elements;
+ if ( $target->documentFragment && $target->stackIsRoot() )
+ // get all body children
+// $loop = $target->find('body > *')->elements;
+ $loop = $target->root->childNodes;
+ else
+ $loop = $target->elements;
+ // import nodes if needed
+ $insertFrom = $this->getDocumentID() == $target->getDocumentID()
+ ? $loop
+ : $this->documentWrapper->import($loop);
+ }
+ // DOMNODE
+ } elseif ($target instanceof DOMNODE) {
+ // import node if needed
+// if ( $target->ownerDocument != $this->DOM )
+// $target = $this->DOM->importNode($target, true);
+ if ( $to) {
+ $insertTo = array($target);
+ if ($this->documentFragment && $this->stackIsRoot())
+ // get all body children
+ $loop = $this->root->childNodes;
+// $loop = $this->find('body > *')->elements;
+ else
+ $loop = $this->elements;
+ foreach($loop as $fromNode)
+ // import nodes if needed
+ $insertFrom[] = ! $fromNode->ownerDocument->isSameNode($target->ownerDocument)
+ ? $target->ownerDocument->importNode($fromNode, true)
+ : $fromNode;
+ } else {
+ // import node if needed
+ if (! $target->ownerDocument->isSameNode($this->document))
+ $target = $this->document->importNode($target, true);
+ $insertTo = $this->elements;
+ $insertFrom[] = $target;
+ }
+ }
+ break;
+ }
+ phpQuery::debug("From ".count($insertFrom)."; To ".count($insertTo)." nodes");
+ foreach($insertTo as $insertNumber => $toNode) {
+ // we need static relative elements in some cases
+ switch( $type) {
+ case 'prependTo':
+ case 'prepend':
+ $firstChild = $toNode->firstChild;
+ break;
+ case 'insertAfter':
+ case 'after':
+ $nextSibling = $toNode->nextSibling;
+ break;
+ }
+ foreach($insertFrom as $fromNode) {
+ // clone if inserted already before
+ $insert = $insertNumber
+ ? $fromNode->cloneNode(true)
+ : $fromNode;
+ switch( $type) {
+ case 'appendTo':
+ case 'append':
+// $toNode->insertBefore(
+// $fromNode,
+// $toNode->lastChild->nextSibling
+// );
+ $toNode->appendChild($insert);
+ break;
+ case 'prependTo':
+ case 'prepend':
+ $toNode->insertBefore(
+ $insert,
+ $firstChild
+ );
+ break;
+ case 'insertBefore':
+ case 'before':
+ if (! $toNode->parentNode)
+ throw new Exception("No parentNode, can't do {$type}()");
+ else
+ $toNode->parentNode->insertBefore(
+ $insert,
+ $toNode
+ );
+ break;
+ case 'insertAfter':
+ case 'after':
+ if (! $toNode->parentNode)
+ throw new Exception("No parentNode, can't do {$type}()");
+ else
+ $toNode->parentNode->insertBefore(
+ $insert,
+ $nextSibling
+ );
+ break;
+ }
+ }
+ }
+ return $this;
+ }
+ /**
+ * Enter description here...
+ *
+ * @return Int
+ */
+ public function index($subject) {
+ $index = -1;
+ $subject = $subject instanceof phpQueryObject
+ ? $subject->elements[0]
+ : $subject;
+ foreach($this->newInstance() as $k => $node) {
+ if ($node->isSameNode($subject))
+ $index = $k;
+ }
+ return $index;
+ }
+
+ /**
+ * Enter description here...
+ *
+ * @param unknown_type $start
+ * @param unknown_type $end
+ *
+ * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery
+ * @testme
+ */
+ public function slice($start, $end = null) {
+// $last = count($this->elements)-1;
+// $end = $end
+// ? min($end, $last)
+// : $last;
+// if ($start < 0)
+// $start = $last+$start;
+// if ($start > $last)
+// return array();
+ if ($end > 0)
+ $end = $end-$start;
+ return $this->newInstance(
+ array_slice($this->elements, $start, $end)
+ );
+ }
+
+ /**
+ * Enter description here...
+ *
+ * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery
+ */
+ public function reverse() {
+ $this->elementsBackup = $this->elements;
+ $this->elements = array_reverse($this->elements);
+ return $this->newInstance();
+ }
+
+ /**
+ * Return joined text content.
+ * @return String
+ */
+ public function text($text = null, $callback1 = null, $callback2 = null, $callback3 = null) {
+ if (isset($text))
+ return $this->html(htmlspecialchars($text));
+ $args = func_get_args();
+ $args = array_slice($args, 1);
+ $return = '';
+ foreach($this->elements as $node) {
+ $text = $node->textContent;
+ if (count($this->elements) > 1 && $node->textContent)
+ $text .= "\n";
+ foreach($args as $callback) {
+ $text = phpQuery::callbackRun($callback, array($text));
+ }
+ $return .= $text;
+ }
+ return $return;
+ }
+ /**
+ * Enter description here...
+ *
+ * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery
+ */
+ public function plugin($class, $file = null) {
+ phpQuery::plugin($class, $file);
+ return $this;
+ }
+ /**
+ * Deprecated, use $pq->plugin() instead.
+ *
+ * @deprecated
+ * @param $class
+ * @param $file
+ * @return unknown_type
+ */
+ public static function extend($class, $file = null) {
+ return $this->plugin($class, $file);
+ }
+ /**
+ *
+ * @access private
+ * @param $method
+ * @param $args
+ * @return unknown_type
+ */
+ public function __call($method, $args) {
+ $aliasMethods = array('clone', 'empty');
+ if (isset(phpQuery::$pluginsMethods[$method])) {
+ array_unshift($args, $this);
+ $class = phpQuery::$pluginsMethods[$method];
+ $realClass = "phpQueryObjectPlugin_$class";
+ $return = call_user_func_array(
+ array($realClass, $method),
+ $args
+ );
+ return is_null($return)
+ ? $this
+ : $return;
+ } else if (in_array($method, $aliasMethods)) {
+ return call_user_func_array(array($this, '_'.$method), $args);
+ } else
+ throw new Exception("Method '{$method}' doesnt exist");
+ }
+
+ /**
+ * Safe rename of next().
+ *
+ * Use it ONLY when need to call next() on an iterated object (in same time).
+ * Normaly there is no need to do such thing ;)
+ *
+ * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery
+ * @access private
+ */
+ public function _next($selector = null) {
+ return $this->newInstance(
+ $this->getElementSiblings('nextSibling', $selector, true)
+ );
+ }
+ /**
+ * Use prev() and next().
+ *
+ * @deprecated
+ * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery
+ * @access private
+ */
+ public function _prev($selector = null) {
+ return $this->prev($selector);
+ }
+ /**
+ * Enter description here...
+ *
+ * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery
+ */
+ public function prev($selector = null) {
+ return $this->newInstance(
+ $this->getElementSiblings('previousSibling', $selector, true)
+ );
+ }
+
+ /**
+ * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery
+ * @todo
+ */
+ public function prevAll($selector = null) {
+ return $this->newInstance(
+ $this->getElementSiblings('previousSibling', $selector)
+ );
+ }
+
+ /**
+ * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery
+ * @todo FIXME: returns source elements insted of next siblings
+ */
+ public function nextAll($selector = null) {
+ return $this->newInstance(
+ $this->getElementSiblings('nextSibling', $selector)
+ );
+ }
+ /**
+ * @access private
+ */
+ protected function getElementSiblings($direction, $selector = null, $limitToOne = false) {
+ $stack = array();
+ $count = 0;
+ foreach($this->stack(1) as $node) {
+ $test = $node;
+ while( isset($test->{$direction}) && $test->{$direction}) {
+ $test = $test->{$direction};
+ if (! $test instanceof DOMELEMENT)
+ continue;
+ $stack[] = $test;
+ if ($limitToOne)
+ break;
+ }
+ }
+ if ($selector) {
+ $stackOld = $this->elements;
+ $this->elements = $stack;
+ $stack = $this->filter($selector, true)->stack();
+ $this->elements = $stackOld;
+ }
+ return $stack;
+ }
+
+ /**
+ * Enter description here...
+ *
+ * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery
+ */
+ public function siblings($selector = null) {
+ $stack = array();
+ $siblings = array_merge(
+ $this->getElementSiblings('previousSibling', $selector),
+ $this->getElementSiblings('nextSibling', $selector)
+ );
+ foreach($siblings as $node) {
+ if (! $this->elementsContainsNode($node, $stack))
+ $stack[] = $node;
+ }
+ return $this->newInstance($stack);
+ }
+
+ /**
+ * Enter description here...
+ *
+ * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery
+ */
+ public function not($selector = null) {
+ phpQuery::debug(array('not', $selector));
+ $stack = array();
+ if ($selector instanceof self || $selector instanceof DOMNODE) {
+ foreach($this->elements as $node) {
+ if ($selector instanceof self) {
+ // XXX check all nodes ?
+ if (count($selector->elements) && ! $selector->elements[0]->isSameNode($node))
+ $stack[] = $node;
+ } else if ($selector instanceof DOMNODE) {
+ if (! $selector->isSameNode($node))
+ $stack[] = $node;
+ } else {
+ if (! $this->is($selector))
+ $stack[] = $node;
+ }
+ }
+ } else {
+ $orgStack = $this->stack();
+ $matched = $this->filter($selector, true)->stack();
+// $matched = array();
+// // simulate OR in filter() instead of AND 5y
+// foreach($this->parseSelector($selector) as $s) {
+// $matched = array_merge($matched,
+// $this->filter(array($s))->stack()
+// );
+// }
+ foreach($orgStack as $node)
+ if (! $this->elementsContainsNode($node, $matched))
+ $stack[] = $node;
+ }
+ return $this->newInstance($stack);
+ }
+
+ /**
+ * Enter description here...
+ *
+ * @param string|phpQueryObject
+ * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery
+ */
+ public function add($selector = null) {
+ if (! $selector)
+ return $this;
+ $stack = array();
+ $this->elementsBackup = $this->elements;
+ $found = phpQuery::pq($selector, $this->getDocumentID());
+ $this->merge($found->elements);
+ return $this->newInstance();
+ }
+ /**
+ * @access private
+ */
+ protected function merge() {
+ foreach(func_get_args() as $nodes)
+ foreach($nodes as $newNode )
+ if (! $this->elementsContainsNode($newNode) )
+ $this->elements[] = $newNode;
+ }
+ /**
+ * @access private
+ * TODO refactor to stackContainsNode
+ */
+ protected function elementsContainsNode($nodeToCheck, $elementsStack = null) {
+ $loop = ! is_null($elementsStack)
+ ? $elementsStack
+ : $this->elements;
+ foreach($loop as $node) {
+ if ( $node->isSameNode( $nodeToCheck ) )
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Enter description here...
+ *
+ * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery
+ */
+ public function parent($selector = null) {
+ $stack = array();
+ foreach($this->elements as $node )
+ if ( $node->parentNode && ! $this->elementsContainsNode($node->parentNode, $stack) )
+ $stack[] = $node->parentNode;
+ $this->elementsBackup = $this->elements;
+ $this->elements = $stack;
+ if ( $selector )
+ $this->filter($selector, true);
+ return $this->newInstance();
+ }
+
+ /**
+ * Enter description here...
+ *
+ * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery
+ */
+ public function parents($selector = null) {
+ $stack = array();
+ if (! $this->elements )
+ $this->debug('parents() - stack empty');
+ foreach($this->elements as $node) {
+ $test = $node;
+ while( $test->parentNode) {
+ $test = $test->parentNode;
+ if ($this->isRoot($test))
+ break;
+ if (! $this->elementsContainsNode($test, $stack)) {
+ $stack[] = $test;
+ continue;
+ }
+ }
+ }
+ $this->elementsBackup = $this->elements;
+ $this->elements = $stack;
+ if ( $selector )
+ $this->filter($selector, true);
+ return $this->newInstance();
+ }
+
+ /**
+ * Internal stack iterator.
+ *
+ * @access private
+ */
+ public function stack($nodeTypes = null) {
+ if (!isset($nodeTypes))
+ return $this->elements;
+ if (!is_array($nodeTypes))
+ $nodeTypes = array($nodeTypes);
+ $return = array();
+ foreach($this->elements as $node)
+ if (in_array($node->nodeType, $nodeTypes))
+ $return[] = $node;
+ return $return;
+ }
+ // TODO phpdoc; $oldAttr is result of hasAttribute, before any changes
+ protected function attrEvents($attr, $oldAttr, $oldValue, $node) {
+ // skip events for XML documents
+ if (! $this->isXHTML() && ! $this->isHTML())
+ return;
+ $event = null;
+ // identify
+ $isInputValue = $node->tagName == 'input'
+ && (
+ in_array($node->getAttribute('type'),
+ array('text', 'password', 'hidden'))
+ || !$node->getAttribute('type')
+ );
+ $isRadio = $node->tagName == 'input'
+ && $node->getAttribute('type') == 'radio';
+ $isCheckbox = $node->tagName == 'input'
+ && $node->getAttribute('type') == 'checkbox';
+ $isOption = $node->tagName == 'option';
+ if ($isInputValue && $attr == 'value' && $oldValue != $node->getAttribute($attr)) {
+ $event = new DOMEvent(array(
+ 'target' => $node,
+ 'type' => 'change'
+ ));
+ } else if (($isRadio || $isCheckbox) && $attr == 'checked' && (
+ // check
+ (! $oldAttr && $node->hasAttribute($attr))
+ // un-check
+ || (! $node->hasAttribute($attr) && $oldAttr)
+ )) {
+ $event = new DOMEvent(array(
+ 'target' => $node,
+ 'type' => 'change'
+ ));
+ } else if ($isOption && $node->parentNode && $attr == 'selected' && (
+ // select
+ (! $oldAttr && $node->hasAttribute($attr))
+ // un-select
+ || (! $node->hasAttribute($attr) && $oldAttr)
+ )) {
+ $event = new DOMEvent(array(
+ 'target' => $node->parentNode,
+ 'type' => 'change'
+ ));
+ }
+ if ($event) {
+ phpQueryEvents::trigger($this->getDocumentID(),
+ $event->type, array($event), $node
+ );
+ }
+ }
+ public function attr($attr = null, $value = null) {
+ foreach($this->stack(1) as $node) {
+ if (! is_null($value)) {
+ $loop = $attr == '*'
+ ? $this->getNodeAttrs($node)
+ : array($attr);
+ foreach($loop as $a) {
+ $oldValue = $node->getAttribute($a);
+ $oldAttr = $node->hasAttribute($a);
+ // TODO raises an error when charset other than UTF-8
+ // while document's charset is also not UTF-8
+ @$node->setAttribute($a, $value);
+ $this->attrEvents($a, $oldAttr, $oldValue, $node);
+ }
+ } else if ($attr == '*') {
+ // jQuery difference
+ $return = array();
+ foreach($node->attributes as $n => $v)
+ $return[$n] = $v->value;
+ return $return;
+ } else
+ return $node->hasAttribute($attr)
+ ? $node->getAttribute($attr)
+ : null;
+ }
+ return $this;
+ }
+
+ /**
+ * Enter description here...
+ * jQuery difference.
+ *
+ * @param string $attr
+ * @param mixed $value
+ * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery
+ * @todo use attr() function (encoding issues etc).
+ */
+ public function attrPrepend($attr, $value) {
+ foreach($this->stack(1) as $node )
+ $node->setAttribute($attr,
+ $value.$node->getAttribute($attr)
+ );
+ return $this;
+ }
+
+ /**
+ * Enter description here...
+ * jQuery difference.
+ *
+ * @param string $attr
+ * @param mixed $value
+ * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery
+ * @todo use attr() function (encoding issues etc).
+ */
+ public function attrAppend($attr, $value) {
+ foreach($this->stack(1) as $node )
+ $node->setAttribute($attr,
+ $node->getAttribute($attr).$value
+ );
+ return $this;
+ }
+ /**
+ * @access private
+ */
+ protected function getNodeAttrs($node) {
+ $return = array();
+ foreach($node->attributes as $n => $o)
+ $return[] = $n;
+ return $return;
+ }
+ /**
+ * Enter description here...
+ *
+ * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery
+ * @todo check CDATA ???
+ */
+ public function attrPHP($attr, $code) {
+ if (! is_null($code)) {
+ $value = '<'.'?php '.$code.' ?'.'>';
+ // TODO tempolary solution
+ // http://code.google.com/p/phpquery/issues/detail?id=17
+// if (function_exists('mb_detect_encoding') && mb_detect_encoding($value) == 'ASCII')
+// $value = mb_convert_encoding($value, 'UTF-8', 'HTML-ENTITIES');
+ }
+ foreach($this->stack(1) as $node) {
+ if (! is_null( $value )) {
+// $attrNode = $this->DOM->createAttribute($attr);
+ $node->setAttribute($attr, $value);
+// $attrNode->value = $value;
+// $node->appendChild($attrNode);
+ } else if ( $attr == '*') {
+ // jQuery diff
+ $return = array();
+ foreach($node->attributes as $n => $v)
+ $return[$n] = $v->value;
+ return $return;
+ } else
+ return $node->getAttribute($attr);
+ }
+ return $this;
+ }
+
+ /**
+ * Enter description here...
+ *
+ * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery
+ */
+ public function removeAttr($attr) {
+ foreach($this->stack(1) as $node) {
+ $loop = $attr == '*'
+ ? $this->getNodeAttrs($node)
+ : array($attr);
+ foreach($loop as $a) {
+ $oldValue = $node->getAttribute($a);
+ $node->removeAttribute($a);
+ $this->attrEvents($a, $oldValue, null, $node);
+ }
+ }
+ return $this;
+ }
+
+ /**
+ * Return form element value.
+ *
+ * @return String Fields value.
+ */
+ public function val($val = null) {
+ if (! isset($val)) {
+ if ($this->eq(0)->is('select')) {
+ $selected = $this->eq(0)->find('option[selected=selected]');
+ if ($selected->is('[value]'))
+ return $selected->attr('value');
+ else
+ return $selected->text();
+ } else if ($this->eq(0)->is('textarea'))
+ return $this->eq(0)->markup();
+ else
+ return $this->eq(0)->attr('value');
+ } else {
+ $_val = null;
+ foreach($this->stack(1) as $node) {
+ $node = pq($node, $this->getDocumentID());
+ if (is_array($val) && in_array($node->attr('type'), array('checkbox', 'radio'))) {
+ $isChecked = in_array($node->attr('value'), $val)
+ || in_array($node->attr('name'), $val);
+ if ($isChecked)
+ $node->attr('checked', 'checked');
+ else
+ $node->removeAttr('checked');
+ } else if ($node->get(0)->tagName == 'select') {
+ if (! isset($_val))
+ $_val = is_array($val)
+ ? $val : array($val);
+ foreach($node['option']->stack(1) as $option) {
+ $option = pq($option, $this->getDocumentID());
+ $selected = false;
+ // XXX: workaround for string comparsion, see issue #96
+ // http://code.google.com/p/phpquery/issues/detail?id=96
+ $optionValue = $option->attr('value');
+ $optionText = $option->text();
+ $optionTextLenght = mb_strlen($optionText);
+ foreach($_val as $v)
+ if ($optionValue == $v)
+ $selected = true;
+ else if ($optionText == $v && $optionTextLenght == mb_strlen($v))
+ $selected = true;
+ if ($selected)
+ $option->attr('selected', 'selected');
+ else
+ $option->removeAttr('selected');
+ }
+ } else if ($node->get(0)->tagName == 'textarea')
+ $node->markup($val);
+ else
+ $node->attr('value', $val);
+ }
+ }
+ return $this;
+ }
+
+ /**
+ * Enter description here...
+ *
+ * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery
+ */
+ public function andSelf() {
+ if ( $this->previous )
+ $this->elements = array_merge($this->elements, $this->previous->elements);
+ return $this;
+ }
+
+ /**
+ * Enter description here...
+ *
+ * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery
+ */
+ public function addClass( $className) {
+ if (! $className)
+ return $this;
+ foreach($this->stack(1) as $node) {
+ if (! $this->is(".$className", $node))
+ $node->setAttribute(
+ 'class',
+ trim($node->getAttribute('class').' '.$className)
+ );
+ }
+ return $this;
+ }
+
+ /**
+ * Enter description here...
+ *
+ * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery
+ */
+ public function addClassPHP( $className) {
+ foreach($this->stack(1) as $node) {
+ $classes = $node->getAttribute('class');
+ $newValue = $classes
+ ? $classes.' <'.'?php '.$className.' ?'.'>'
+ : '<'.'?php '.$className.' ?'.'>';
+ $node->setAttribute('class', $newValue);
+ }
+ return $this;
+ }
+
+ /**
+ * Enter description here...
+ *
+ * @param string $className
+ * @return bool
+ */
+ public function hasClass($className) {
+ foreach($this->stack(1) as $node) {
+ if ( $this->is(".$className", $node))
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Enter description here...
+ *
+ * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery
+ */
+ public function removeClass($className) {
+ foreach($this->stack(1) as $node) {
+ $classes = explode( ' ', $node->getAttribute('class'));
+ if ( in_array($className, $classes)) {
+ $classes = array_diff($classes, array($className));
+ if ( $classes )
+ $node->setAttribute('class', implode(' ', $classes));
+ else
+ $node->removeAttribute('class');
+ }
+ }
+ return $this;
+ }
+
+ /**
+ * Enter description here...
+ *
+ * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery
+ */
+ public function toggleClass($className) {
+ foreach($this->stack(1) as $node) {
+ if ( $this->is( $node, '.'.$className ))
+ $this->removeClass($className);
+ else
+ $this->addClass($className);
+ }
+ return $this;
+ }
+
+ /**
+ * Proper name without underscore (just ->empty()) also works.
+ *
+ * Removes all child nodes from the set of matched elements.
+ *
+ * Example:
+ * pq("p")._empty()
+ *
+ * HTML:
+ * <p>Hello, <span>Person</span> <a href="#">and person</a></p>
+ *
+ * Result:
+ * [ <p></p> ]
+ *
+ * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery
+ * @access private
+ */
+ public function _empty() {
+ foreach($this->stack(1) as $node) {
+ // thx to 'dave at dgx dot cz'
+ $node->nodeValue = '';
+ }
+ return $this;
+ }
+
+ /**
+ * Enter description here...
+ *
+ * @param array|string $callback Expects $node as first param, $index as second
+ * @param array $scope External variables passed to callback. Use compact('varName1', 'varName2'...) and extract($scope)
+ * @param array $arg1 Will ba passed as third and futher args to callback.
+ * @param array $arg2 Will ba passed as fourth and futher args to callback, and so on...
+ * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery
+ */
+ public function each($callback, $param1 = null, $param2 = null, $param3 = null) {
+ $paramStructure = null;
+ if (func_num_args() > 1) {
+ $paramStructure = func_get_args();
+ $paramStructure = array_slice($paramStructure, 1);
+ }
+ foreach($this->elements as $v)
+ phpQuery::callbackRun($callback, array($v), $paramStructure);
+ return $this;
+ }
+
+ /**
+ * Enter description here...
+ *
+ * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery
+ * @todo add $scope and $args as in each() ???
+ */
+ public function map($callback, $param1 = null, $param2 = null, $param3 = null) {
+// $stack = array();
+//// foreach($this->newInstance() as $node) {
+// foreach($this->newInstance() as $node) {
+// $result = call_user_func($callback, $node);
+// if ($result)
+// $stack[] = $result;
+// }
+ $params = func_get_args();
+ array_unshift($params, $this->elements);
+ return $this->newInstance(
+ call_user_func_array(array('phpQuery', 'map'), $params)
+// phpQuery::map($this->elements, $callback)
+ );
+ }
+
+ // INTERFACE IMPLEMENTATIONS
+
+ // ITERATOR INTERFACE
+ // TODO IteratorAggregate ???
+ /**
+ * @access private
+ */
+ public function rewind(){
+ $this->debug('iterating foreach');
+// phpQuery::selectDocument($this->getDocumentID());
+ $this->elementsBackup = $this->elements;
+ $this->elementsInterator = $this->elements;
+ $this->valid = isset( $this->elements[0] )
+ ? 1 : 0;
+// $this->elements = $this->valid
+// ? array($this->elements[0])
+// : array();
+ $this->current = 0;
+ }
+ /**
+ * @access private
+ */
+ public function current(){
+ return $this->elementsInterator[ $this->current ];
+ }
+ /**
+ * @access private
+ */
+ public function key(){
+ return $this->current;
+ }
+ /**
+ * Double-function method.
+ *
+ * First: main iterator interface method.
+ * Second: Returning next sibling, alias for _next().
+ *
+ * Proper functionality is choosed automagicaly.
+ *
+ * @see phpQueryObject::_next()
+ * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery
+ */
+ public function next($cssSelector = null){
+// if ($cssSelector || $this->valid)
+// return $this->_next($cssSelector);
+ $this->valid = isset( $this->elementsInterator[ $this->current+1 ] )
+ ? true
+ : false;
+ if (! $this->valid && $this->elementsInterator) {
+ $this->elementsInterator = null;
+ } else if ($this->valid) {
+ $this->current++;
+ } else {
+ return $this->_next($cssSelector);
+ }
+ }
+ /**
+ * @access private
+ */
+ public function valid(){
+ return $this->valid;
+ }
+ // ITERATOR INTERFACE END
+ // ARRAYACCESS INTERFACE
+ /**
+ * @access private
+ */
+ public function offsetExists($offset) {
+ return $this->find($offset)->size() > 0;
+ }
+ /**
+ * @access private
+ */
+ public function offsetGet($offset) {
+ return $this->find($offset);
+ }
+ /**
+ * @access private
+ */
+ public function offsetSet($offset, $value) {
+// $this->find($offset)->replaceWith($value);
+ $this->find($offset)->html($value);
+ }
+ /**
+ * @access private
+ */
+ public function offsetUnset($offset) {
+ // empty
+ throw new Exception("Can't do unset, use array interface only for calling queries and replacing HTML.");
+ }
+ // ARRAYACCESS INTERFACE END
+ /**
+ * Returns node's XPath.
+ *
+ * @param unknown_type $oneNode
+ * @return string
+ * @TODO use native getNodePath is avaible
+ * @access private
+ */
+ protected function getNodeXpath($oneNode = null, $namespace = null) {
+ $return = array();
+ $loop = $oneNode
+ ? array($oneNode)
+ : $this->elements;
+// if ($namespace)
+// $namespace .= ':';
+ foreach($loop as $node) {
+ if ($node instanceof DOMDOCUMENT) {
+ $return[] = '';
+ continue;
+ }
+ $xpath = array();
+ while(! ($node instanceof DOMDOCUMENT)) {
+ $i = 1;
+ $sibling = $node;
+ while($sibling->previousSibling) {
+ $sibling = $sibling->previousSibling;
+ $isElement = $sibling instanceof DOMELEMENT;
+ if ( $isElement && $sibling->tagName == $node->tagName )
+ $i++;
+ }
+ $xpath[] = $this->isXML()
+ ? "*[local-name()='{$node->tagName}'][{$i}]"
+ : "{$node->tagName}[{$i}]";
+ $node = $node->parentNode;
+ }
+ $xpath = join('/', array_reverse($xpath));
+ $return[] = '/'.$xpath;
+ }
+ return $oneNode
+ ? $return[0]
+ : $return;
+ }
+ // HELPERS
+ public function whois($oneNode = null) {
+ $return = array();
+ $loop = $oneNode
+ ? array( $oneNode )
+ : $this->elements;
+ foreach($loop as $node) {
+ $return[] = isset($node->tagName)
+ ? $node->tagName
+ .($node->getAttribute('id')
+ ? '#'.$node->getAttribute('id'):'')
+ .($node->getAttribute('class')
+ ? '.'.join('.', split(' ', $node->getAttribute('class'))):'')
+ .($node->getAttribute('name')
+ ? '[name="'.$node->getAttribute('name').'"]':'')
+ : ($node instanceof DOMTEXT
+ ? "text: '".substr(str_replace("\n", '', $node->textContent), 0, 15)."'"
+ : get_class($node)
+ );
+ }
+ return $oneNode
+ ? $return[0]
+ : $return;
+ }
+ /**
+ * Dump htmlOuter and preserve chain. Usefull for debugging.
+ *
+ * @return phpQueryObject|QueryTemplatesSource|QueryTemplatesParse|QueryTemplatesSourceQuery|QueryTemplatesPhpQuery
+ *
+ */
+ public function dump() {
+ print 'DUMP #'.(phpQuery::$dumpCount++).' ';
+ $debug = phpQuery::$debug;
+ phpQuery::$debug = false;
+// print __FILE__.':'.__LINE__."\n";
+ var_dump($this->htmlOuter());
+ return $this;
+ }
+ public function dumpWhois() {
+ print 'DUMP #'.(phpQuery::$dumpCount++).' ';
+ $debug = phpQuery::$debug;
+ phpQuery::$debug = false;
+// print __FILE__.':'.__LINE__."\n";
+ var_dump('whois', $this->whois());
+ phpQuery::$debug = $debug;
+ return $this;
+ }
+ public function dumpLength() {
+ print 'DUMP #'.(phpQuery::$dumpCount++).' ';
+ $debug = phpQuery::$debug;
+ phpQuery::$debug = false;
+// print __FILE__.':'.__LINE__."\n";
+ var_dump('length', $this->length());
+ phpQuery::$debug = $debug;
+ return $this;
+ }
+ public function dumpTree() {
+ print 'DUMP #'.(phpQuery::$dumpCount++).' ';
+ $debug = phpQuery::$debug;
+ phpQuery::$debug = false;
+ foreach($this->stack() as $node)
+ print $this->__dumpTree($node);
+ phpQuery::$debug = $debug;
+ return $this;
+ }
+ private function __dumpTree($node, $intend = 0) {
+ $return = str_repeat(' ', $intend);
+ $return .= $this->whois($node)."\n";
+ if (isset($node->childNodes))
+ foreach($node->childNodes as $chNode)
+ $return .= $this->__dumpTree($chNode, $intend+1);
+ return $return;
+ }
+ /**
+ * Dump htmlOuter and stop script execution. Usefull for debugging.
+ *
+ */
+ public function dumpDie() {
+ print __FILE__.':'.__LINE__;
+ var_dump($this->htmlOuter());
+ die();
+ }
+}
diff --git a/site/vendors/phpQuery/plugins/Scripts.php b/site/vendors/phpQuery/plugins/Scripts.php
new file mode 100644
index 0000000..665ea8c
--- /dev/null
+++ b/site/vendors/phpQuery/plugins/Scripts.php
@@ -0,0 +1,48 @@
+<?php
+/**
+ * phpQuery plugin class extending phpQuery object.
+ * Methods from this class are callable on every phpQuery object.
+ *
+ * Class name prefix 'phpQueryObjectPlugin_' must be preserved.
+ */
+abstract class phpQueryObjectPlugin_Scripts {
+ /**
+ * Limit binded methods.
+ *
+ * null means all public.
+ * array means only specified ones.
+ *
+ * @var array|null
+ */
+ public static $phpQueryMethods = null;
+ public static $config = array();
+ /**
+ * Enter description here...
+ *
+ * @param phpQueryObject $self
+ */
+ public static function script($self, $arg1) {
+ $params = func_get_args();
+ $params = array_slice($params, 2);
+ $return = null;
+ $config = self::$config;
+ if ($arg1 != '__config' && file_exists(dirname(__FILE__)."/Scripts/$arg1.php")) {
+ phpQuery::debug("Loading script '$arg1'");
+ require dirname(__FILE__)."/Scripts/$arg1.php";
+ } else {
+ phpQuery::debug("Requested script '$arg1' doesn't exist");
+ }
+ return $return
+ ? $return
+ : $self;
+ }
+}
+abstract class phpQueryPlugin_Scripts {
+ public static function __initialize() {
+ if (file_exists(dirname(__FILE__)."/Scripts/__config.php")) {
+ include dirname(__FILE__)."/Scripts/__config.php";
+ phpQueryObjectPlugin_Scripts::$config = $config;
+ }
+ }
+}
+?> \ No newline at end of file
diff --git a/site/vendors/phpQuery/plugins/Scripts/__config.example.php b/site/vendors/phpQuery/plugins/Scripts/__config.example.php
new file mode 100644
index 0000000..db80652
--- /dev/null
+++ b/site/vendors/phpQuery/plugins/Scripts/__config.example.php
@@ -0,0 +1,10 @@
+<?php
+/**
+ * This file hosts config for Scripts plugin.
+ *
+ * To active this file, selete '.example' from filename.
+ */
+$config = array(
+ 'google_login' => array('login@mail', 'password'),
+);
+?> \ No newline at end of file
diff --git a/site/vendors/phpQuery/plugins/Scripts/example.php b/site/vendors/phpQuery/plugins/Scripts/example.php
new file mode 100644
index 0000000..a8f45f4
--- /dev/null
+++ b/site/vendors/phpQuery/plugins/Scripts/example.php
@@ -0,0 +1,14 @@
+<?php
+/**
+ * Example script for phpQuery Script plugin
+ *
+ * Avaible are 4 variables:
+ * - $self Represents $this
+ * - $params Represents parameters passed to script() method (without script name)
+ * - $return If not null, will be used as method result
+ * - $config Content of __config.php file
+ *
+ * By default each script returns $self aka $this.
+ */
+$return = $self->find($params[0]);
+?> \ No newline at end of file
diff --git a/site/vendors/phpQuery/plugins/Scripts/fix_webroot.php b/site/vendors/phpQuery/plugins/Scripts/fix_webroot.php
new file mode 100644
index 0000000..a7cac9e
--- /dev/null
+++ b/site/vendors/phpQuery/plugins/Scripts/fix_webroot.php
@@ -0,0 +1,16 @@
+<?php
+$selector = 'img[src], link[href], script[src]';
+$filter = ':not([href^=<?php])'
+ .':not([src^=<?php])'
+ .':not([href^=http://])'
+ .':not([src^=http://])'
+ .':not([src^=/])';
+foreach($self[$selector]->filter($filter) as $el) {
+ $el = pq($el, $self->getDocumentID());
+ // imgs and scripts
+ if ( $el->is('img') || $el->is('script') )
+ $el->attr('src', $params[0].$el->attr('src'));
+ // css
+ if ( $el->is('link') )
+ $el->attr('href', $params[0].$el->attr('href'));
+} \ No newline at end of file
diff --git a/site/vendors/phpQuery/plugins/Scripts/google_login.php b/site/vendors/phpQuery/plugins/Scripts/google_login.php
new file mode 100644
index 0000000..ca9be9b
--- /dev/null
+++ b/site/vendors/phpQuery/plugins/Scripts/google_login.php
@@ -0,0 +1,47 @@
+<?php
+/**
+ * Automated google account login.
+ * Uses __config.php to keep login data.
+ *
+ * @package phpQuery.Plugins.Scripts
+ * @author Tobiasz Cudnik <tobiasz.cudnik/gmail.com>
+ */
+phpQuery::ajaxAllowHost(
+ 'code.google.com',
+ 'google.com', 'www.google.com',
+ 'mail.google.com',
+ 'docs.google.com',
+ 'reader.google.com'
+);
+if (! function_exists('ndfasui8923')) {
+ function ndfasui8923($browser, $scope) {
+ extract($scope);
+ $browser
+ ->WebBrowser()
+ ->find('#Email')
+ ->val($config['google_login'][0])->end()
+ ->find('#Passwd')
+ ->val($config['google_login'][1])
+ ->parents('form')
+ ->submit();
+ }
+ $ndfasui8923 = new Callback('ndfasui8923', new CallbackParam, compact(
+ 'config', 'self', 'return', 'params'
+ ));
+}
+phpQuery::extend('WebBrowser');
+$self->document->xhr = phpQuery::$plugins->browserGet(
+ 'https://www.google.com/accounts/Login',
+ $ndfasui8923
+);
+//$self->document->xhr = phpQuery::$plugins->browserGet('https://www.google.com/accounts/Login', create_function('$browser', "
+// \$browser
+// ->WebBrowser()
+// ->find('#Email')
+// ->val('{$config['google_login'][0]}')->end()
+// ->find('#Passwd')
+// ->val('".str_replace("'", "\\'", $config['google_login'][1])."')
+// ->parents('form')
+// ->submit();"
+//));
+?> \ No newline at end of file
diff --git a/site/vendors/phpQuery/plugins/Scripts/print_source.php b/site/vendors/phpQuery/plugins/Scripts/print_source.php
new file mode 100644
index 0000000..03d8061
--- /dev/null
+++ b/site/vendors/phpQuery/plugins/Scripts/print_source.php
@@ -0,0 +1,9 @@
+<?php
+/**
+ * Script outputs document markup and changes HTML special chars to entities.
+ *
+ * @author Tobiasz Cudnik <tobiasz.cudnik/gmail.com>
+ */
+/** @var phpQueryObject */
+$self = $self;
+$return = htmlspecialchars($self); \ No newline at end of file
diff --git a/site/vendors/phpQuery/plugins/Scripts/print_websafe.php b/site/vendors/phpQuery/plugins/Scripts/print_websafe.php
new file mode 100644
index 0000000..4f48bd7
--- /dev/null
+++ b/site/vendors/phpQuery/plugins/Scripts/print_websafe.php
@@ -0,0 +1,13 @@
+<?php
+/**
+ * Script makes content safe for printing as web page and not redirecting client.
+ *
+ * @author Tobiasz Cudnik <tobiasz.cudnik/gmail.com>
+ */
+/** @var phpQueryObject */
+$self = $self;
+$self
+ ->find('script')
+ ->add('meta[http-equiv=refresh]')
+ ->add('meta[http-equiv=Refresh]')
+ ->remove(); \ No newline at end of file
diff --git a/site/vendors/phpQuery/plugins/WebBrowser.php b/site/vendors/phpQuery/plugins/WebBrowser.php
new file mode 100644
index 0000000..778b888
--- /dev/null
+++ b/site/vendors/phpQuery/plugins/WebBrowser.php
@@ -0,0 +1,385 @@
+<?php
+/**
+ * WebBrowser plugin.
+ *
+ */
+class phpQueryObjectPlugin_WebBrowser {
+ /**
+ * Limit binded methods to specified ones.
+ *
+ * @var array
+ */
+ public static $phpQueryMethods = null;
+ /**
+ * Enter description here...
+ *
+ * @param phpQueryObject $self
+ * @todo support 'reset' event
+ */
+ public static function WebBrowser($self, $callback = null, $location = null) {
+ $self = $self->_clone()->toRoot();
+ $location = $location
+ ? $location
+ // TODO use document.location
+ : $self->document->xhr->getUri(true);
+ // FIXME tmp
+ $self->document->WebBrowserCallback = $callback;
+ if (! $location)
+ throw new Exception('Location needed to activate WebBrowser plugin !');
+ else {
+ $self->bind('click', array($location, $callback), array('phpQueryPlugin_WebBrowser', 'hadleClick'));
+ $self->bind('submit', array($location, $callback), array('phpQueryPlugin_WebBrowser', 'handleSubmit'));
+ }
+ }
+ public static function downloadTo($self, $dir = null, $filename = null) {
+ $url = null;
+ if ($self->is('a[href]'))
+ $url = $self->attr('href');
+ else if ($self->find('a')->length)
+ $url = $self->find('a')->attr('href');
+ if ($url) {
+ $url = resolve_url($self->document->location, $url);
+ if (! $dir)
+ $dir = getcwd();
+ if (! $filename) {
+ $matches = null;
+ preg_match('@/([^/]+)$@', $url, $matches);
+ $filename = $matches[1];
+ }
+ $path = rtrim($dir, '/').'/'.$filename;
+ // TODO use AJAX instead of file_get_contents
+ file_put_contents($path, file_get_contents($url));
+ }
+ return $self;
+ }
+ public static function location($self, $url = null) {
+ // TODO if ! $url return actual location ???
+ $xhr = isset($self->document->xhr)
+ ? $self->document->xhr
+ : null;
+ $xhr = phpQuery::ajax(array(
+ 'url' => $url,
+ ), $xhr);
+ $return = false;
+ if ($xhr->getLastResponse()->isSuccessful()) {
+ $return = phpQueryPlugin_WebBrowser::browserReceive($xhr);
+ if (isset($self->document->WebBrowserCallback))
+ phpQuery::callbackRun(
+ $self->document->WebBrowserCallback,
+ array($return)
+ );
+ }
+ return $return;
+ }
+}
+class phpQueryPlugin_WebBrowser {
+ /**
+ *
+ * @param $url
+ * @param $callback
+ * @param $param1
+ * @param $param2
+ * @param $param3
+ * @return Zend_Http_Client
+ */
+ public static function browserGet($url, $callback,
+ $param1 = null, $param2 = null, $param3 = null) {
+ phpQuery::debug("[WebBrowser] GET: $url");
+ self::authorizeHost($url);
+ $xhr = phpQuery::ajax(array(
+ 'type' => 'GET',
+ 'url' => $url,
+ 'dataType' => 'html',
+ ));
+ $paramStructure = null;
+ if (func_num_args() > 2) {
+ $paramStructure = func_get_args();
+ $paramStructure = array_slice($paramStructure, 2);
+ }
+ if ($xhr->getLastResponse()->isSuccessful()) {
+ phpQuery::callbackRun($callback,
+ array(self::browserReceive($xhr)),
+ $paramStructure
+ );
+// phpQuery::callbackRun($callback, array(
+// self::browserReceive($xhr)//->WebBrowser($callback)
+// ));
+ return $xhr;
+ } else {
+ throw new Exception("[WebBrowser] GET request failed; url: $url");
+ return false;
+ }
+ }
+ /**
+ *
+ * @param $url
+ * @param $data
+ * @param $callback
+ * @param $param1
+ * @param $param2
+ * @param $param3
+ * @return Zend_Http_Client
+ */
+ public static function browserPost($url, $data, $callback,
+ $param1 = null, $param2 = null, $param3 = null) {
+ self::authorizeHost($url);
+ $xhr = phpQuery::ajax(array(
+ 'type' => 'POST',
+ 'url' => $url,
+ 'dataType' => 'html',
+ 'data' => $data,
+ ));
+ $paramStructure = null;
+ if (func_num_args() > 3) {
+ $paramStructure = func_get_args();
+ $paramStructure = array_slice($paramStructure, 3);
+ }
+ if ($xhr->getLastResponse()->isSuccessful()) {
+ phpQuery::callbackRun($callback,
+ array(self::browserReceive($xhr)),
+ $paramStructure
+ );
+// phpQuery::callbackRun($callback, array(
+// self::browserReceive($xhr)//->WebBrowser($callback)
+// ));
+ return $xhr;
+ } else
+ return false;
+ }
+ /**
+ *
+ * @param $ajaxSettings
+ * @param $callback
+ * @param $param1
+ * @param $param2
+ * @param $param3
+ * @return Zend_Http_Client
+ */
+ public static function browser($ajaxSettings, $callback,
+ $param1 = null, $param2 = null, $param3 = null) {
+ self::authorizeHost($ajaxSettings['url']);
+ $xhr = phpQuery::ajax(
+ self::ajaxSettingsPrepare($ajaxSettings)
+ );
+ $paramStructure = null;
+ if (func_num_args() > 2) {
+ $paramStructure = func_get_args();
+ $paramStructure = array_slice($paramStructure, 2);
+ }
+ if ($xhr->getLastResponse()->isSuccessful()) {
+ phpQuery::callbackRun($callback,
+ array(self::browserReceive($xhr)),
+ $paramStructure
+ );
+// phpQuery::callbackRun($callback, array(
+// self::browserReceive($xhr)//->WebBrowser($callback)
+// ));
+ return $xhr;
+ } else
+ return false;
+ }
+ protected static function authorizeHost($url) {
+ $host = parse_url($url, PHP_URL_HOST);
+ if ($host)
+ phpQuery::ajaxAllowHost($host);
+ }
+ protected static function ajaxSettingsPrepare($settings) {
+ unset($settings['success']);
+ unset($settings['error']);
+ return $settings;
+ }
+ /**
+ * @param Zend_Http_Client $xhr
+ */
+ public static function browserReceive($xhr) {
+ phpQuery::debug("[WebBrowser] Received from ".$xhr->getUri(true));
+ // TODO handle meta redirects
+ $body = $xhr->getLastResponse()->getBody();
+
+ // XXX error ???
+ if (strpos($body, '<!doctype html>') !== false) {
+ $body = '<html>'
+ .str_replace('<!doctype html>', '', $body)
+ .'</html>';
+ }
+ $pq = phpQuery::newDocument($body);
+ $pq->document->xhr = $xhr;
+ $pq->document->location = $xhr->getUri(true);
+ $refresh = $pq->find('meta[http-equiv=refresh]')
+ ->add('meta[http-equiv=Refresh]');
+ if ($refresh->size()) {
+// print htmlspecialchars(var_export($xhr->getCookieJar()->getAllCookies(), true));
+// print htmlspecialchars(var_export($xhr->getLastResponse()->getHeader('Set-Cookie'), true));
+ phpQuery::debug("Meta redirect... '{$refresh->attr('content')}'\n");
+ // there is a refresh, so get the new url
+ $content = $refresh->attr('content');
+ $urlRefresh = substr($content, strpos($content, '=')+1);
+ $urlRefresh = trim($urlRefresh, '\'"');
+ // XXX not secure ?!
+ phpQuery::ajaxAllowURL($urlRefresh);
+// $urlRefresh = urldecode($urlRefresh);
+ // make ajax call, passing last $xhr object to preserve important stuff
+ $xhr = phpQuery::ajax(array(
+ 'type' => 'GET',
+ 'url' => $urlRefresh,
+ 'dataType' => 'html',
+ ), $xhr);
+ if ($xhr->getLastResponse()->isSuccessful()) {
+ // if all is ok, repeat this method...
+ return call_user_func_array(
+ array('phpQueryPlugin_WebBrowser', 'browserReceive'), array($xhr)
+ );
+ }
+ } else
+ return $pq;
+ }
+ public static function hadleClick($e) {
+ $node = phpQuery::pq($e->target);
+ $type = null;
+ if ($node->is('a[href]')) {
+ // TODO document.location
+ $xhr = isset($node->document->xhr)
+ ? $node->document->xhr
+ : null;
+ $xhr = phpQuery::ajax(array(
+ 'url' => resolve_url($e->data[0], $node->attr('href')),
+ 'referer' => $node->document->location,
+ ), $xhr);
+ // TODO support extended callbacks
+ if ($xhr->getLastResponse()->isSuccessful() && $e->data[1])
+ phpQuery::callbackRun($e->data[1], array(
+ self::browserReceive($xhr)
+ ));
+ } else if ($node->is(':submit') && $node->parents('form')->size())
+ $node->parents('form')->trigger('submit', array($e));
+ }
+ /**
+ * Enter description here...
+ *
+ * @param unknown_type $e
+ * @TODO trigger submit for form after form's submit button has a click event
+ */
+ public static function handleSubmit($e) {
+ $node = phpQuery::pq($e->target);
+ if (!$node->is('form') || !$node->is('[action]'))
+ return;
+ // TODO document.location
+ $xhr = isset($node->document->xhr)
+ ? $node->document->xhr
+ : null;
+ $submit = pq($e->relatedTarget)->is(':submit')
+ ? $e->relatedTarget
+ // will this work ?
+// : $node->find(':submit:first')->get(0);
+ : $node->find('*:submit:first')->get(0);
+ $data = array();
+ foreach($node->serializeArray($submit) as $r)
+ // XXXt.c maybe $node->not(':submit')->add($sumit) would be better ?
+// foreach($node->serializeArray($submit) as $r)
+ $data[ $r['name'] ] = $r['value'];
+ $options = array(
+ 'type' => $node->attr('method')
+ ? $node->attr('method')
+ : 'GET',
+ 'url' => resolve_url($e->data[0], $node->attr('action')),
+ 'data' => $data,
+ 'referer' => $node->document->location,
+// 'success' => $e->data[1],
+ );
+ if ($node->attr('enctype'))
+ $options['contentType'] = $node->attr('enctype');
+ $xhr = phpQuery::ajax($options, $xhr);
+ // TODO support extended callbacks
+ if ($xhr->getLastResponse()->isSuccessful() && $e->data[1])
+ phpQuery::callbackRun($e->data[1], array(
+ self::browserReceive($xhr)
+ ));
+ }
+
+}
+/**
+ *
+ * @param unknown_type $parsed
+ * @return unknown
+ * @link http://www.php.net/manual/en/function.parse-url.php
+ * @author stevenlewis at hotmail dot com
+ */
+function glue_url($parsed)
+ {
+ if (! is_array($parsed)) return false;
+ $uri = isset($parsed['scheme']) ? $parsed['scheme'].':'.((strtolower($parsed['scheme']) == 'mailto') ? '':'//'): '';
+ $uri .= isset($parsed['user']) ? $parsed['user'].($parsed['pass']? ':'.$parsed['pass']:'').'@':'';
+ $uri .= isset($parsed['host']) ? $parsed['host'] : '';
+ $uri .= isset($parsed['port']) ? ':'.$parsed['port'] : '';
+ if(isset($parsed['path']))
+ {
+ $uri .= (substr($parsed['path'],0,1) == '/')?$parsed['path']:'/'.$parsed['path'];
+ }
+ $uri .= isset($parsed['query']) ? '?'.$parsed['query'] : '';
+ $uri .= isset($parsed['fragment']) ? '#'.$parsed['fragment'] : '';
+ return $uri;
+ }
+/**
+ * Enter description here...
+ *
+ * @param unknown_type $base
+ * @param unknown_type $url
+ * @return unknown
+ * @author adrian-php at sixfingeredman dot net
+ */
+ function resolve_url($base, $url) {
+ if (!strlen($base)) return $url;
+ // Step 2
+ if (!strlen($url)) return $base;
+ // Step 3
+ if (preg_match('!^[a-z]+:!i', $url)) return $url;
+ $base = parse_url($base);
+ if ($url{0} == "#") {
+ // Step 2 (fragment)
+ $base['fragment'] = substr($url, 1);
+ return unparse_url($base);
+ }
+ unset($base['fragment']);
+ unset($base['query']);
+ if (substr($url, 0, 2) == "//") {
+ // Step 4
+ return unparse_url(array(
+ 'scheme'=>$base['scheme'],
+ 'path'=>substr($url,2),
+ ));
+ } else if ($url{0} == "/") {
+ // Step 5
+ $base['path'] = $url;
+ } else {
+ // Step 6
+ $path = explode('/', $base['path']);
+ $url_path = explode('/', $url);
+ // Step 6a: drop file from base
+ array_pop($path);
+ // Step 6b, 6c, 6e: append url while removing "." and ".." from
+ // the directory portion
+ $end = array_pop($url_path);
+ foreach ($url_path as $segment) {
+ if ($segment == '.') {
+ // skip
+ } else if ($segment == '..' && $path && $path[sizeof($path)-1] != '..') {
+ array_pop($path);
+ } else {
+ $path[] = $segment;
+ }
+ }
+ // Step 6d, 6f: remove "." and ".." from file portion
+ if ($end == '.') {
+ $path[] = '';
+ } else if ($end == '..' && $path && $path[sizeof($path)-1] != '..') {
+ $path[sizeof($path)-1] = '';
+ } else {
+ $path[] = $end;
+ }
+ // Step 6h
+ $base['path'] = join('/', $path);
+
+ }
+ // Step 7
+ return glue_url($base);
+} \ No newline at end of file
diff --git a/site/vendors/phpQuery/plugins/example.php b/site/vendors/phpQuery/plugins/example.php
new file mode 100644
index 0000000..732f05c
--- /dev/null
+++ b/site/vendors/phpQuery/plugins/example.php
@@ -0,0 +1,75 @@
+<?php
+/**
+ * Example of phpQuery plugin.
+ *
+ * Load it like this:
+ * phpQuery::plugin('example')
+ * phpQuery::plugin('example', 'example.php')
+ * pq('ul')->plugin('example')
+ * pq('ul')->plugin('example', 'example.php')
+ *
+ * Plugin classes are never intialized, just method calls are forwarded
+ * in static way from phpQuery.
+ *
+ * Have fun writing plugins :)
+ */
+
+/**
+ * phpQuery plugin class extending phpQuery object.
+ * Methods from this class are callable on every phpQuery object.
+ *
+ * Class name prefix 'phpQueryObjectPlugin_' must be preserved.
+ */
+abstract class phpQueryObjectPlugin_example {
+ /**
+ * Limit binded methods.
+ *
+ * null means all public.
+ * array means only specified ones.
+ *
+ * @var array|null
+ */
+ public static $phpQueryMethods = null;
+ /**
+ * Enter description here...
+ *
+ * @param phpQueryObject $self
+ */
+ public static function example($self, $arg1) {
+ // this method can be called on any phpQuery object, like this:
+ // pq('div')->example('$arg1 Value')
+
+ // do something
+ $self->append('Im just an example !');
+ // change stack of result object
+ return $self->find('div');
+ }
+ protected static function helperFunction() {
+ // this method WONT be avaible as phpQuery method,
+ // because it isn't publicly callable
+ }
+}
+
+/**
+ * phpQuery plugin class extending phpQuery static namespace.
+ * Methods from this class are callable as follows:
+ * phpQuery::$plugins->staticMethod()
+ *
+ * Class name prefix 'phpQueryPlugin_' must be preserved.
+ */
+abstract class phpQueryPlugin_example {
+ /**
+ * Limit binded methods.
+ *
+ * null means all public.
+ * array means only specified ones.
+ *
+ * @var array|null
+ */
+ public static $phpQueryMethods = null;
+ public static function staticMethod() {
+ // this method can be called within phpQuery class namespace, like this:
+ // phpQuery::$plugins->staticMethod()
+ }
+}
+?> \ No newline at end of file
diff --git a/site/vendors/phpmailer/ChangeLog.txt b/site/vendors/phpmailer/ChangeLog.txt
new file mode 100644
index 0000000..a4570e0
--- /dev/null
+++ b/site/vendors/phpmailer/ChangeLog.txt
@@ -0,0 +1,252 @@
+ChangeLog
+
+Version 2.0.0 (Sun, Dec 02 2007)
+* implemented updated EncodeQP (thanks to coolbru, aka Marcus Bointon)
+* finished all testing, all known bugs corrected, enhancements tested
+- note: designed for PHP4, but will work with PHP5 (not compatible with
+ E_STRICT) ... full PHP5 version of PHPMailer released separately.
+ PHP5 version will NOT work with PHP4.
+
+Version 2.0.0 rc2 (Fri, Nov 16 2007), interim release
+* implements new property to control VERP in class.smtp.php
+ example (requires instantiating class.smtp.php):
+ $mail->do_verp = true;
+* POP-before-SMTP functionality included, thanks to Richard Davey
+ (see class.pop3.php & pop3_before_smtp_test.php for examples)
+* included example showing how to use PHPMailer with GMAIL
+* fixed the missing Cc in SendMail() and Mail()
+
+******************
+A note on sending bulk emails:
+
+If the email you are sending is not personalized, consider using the
+"undisclosed-recipient:;" strategy. That is, put all of your recipients
+in the Bcc field and set the To field to "undisclosed-recipients:;".
+It's a lot faster (only one send) and saves quite a bit on resources.
+Contrary to some opinions, this will not get you listed in spam engines -
+it's a legitimate way for you to send emails.
+
+A partial example for use with PHPMailer:
+
+$mail->AddAddress("undisclosed-recipients:;");
+$mail->AddBCC("email1@anydomain.com,email2@anyotherdomain.com,email3@anyalternatedomain.com");
+
+Many email service providers restrict the number of emails that can be sent
+in any given time period. Often that is between 50 - 60 emails maximum
+per hour or per send session.
+
+If that's the case, then break up your Bcc lists into chunks that are one
+less than your limit, and put a pause in your script.
+*******************
+
+Version 2.0.0 rc1 (Thu, Nov 08 2007), interim release
+* dramatically simplified using inline graphics ... it's fully automated and requires no user input
+* added automatic document type detection for attachments and pictures
+* added MsgHTML() function to replace Body tag for HTML emails
+* fixed the SendMail security issues (input validation vulnerability)
+* enhanced the AddAddresses functionality so that the "Name" portion is used in the email address
+* removed the need to use the AltBody method (set from the HTML, or default text used)
+* set the PHP Mail() function as the default (still support SendMail, SMTP Mail)
+* removed the need to set the IsHTML property (set automatically)
+* added Estonian language file by Indrek P&auml;ri
+* added header injection patch
+* added "set" method to permit users to create their own pseudo-properties like 'X-Headers', etc.
+ example of use:
+ $mail->set('X-Priority', '3');
+ $mail->set('X-MSMail-Priority', 'Normal');
+* fixed warning message in SMTP get_lines method
+* added TLS/SSL SMTP support
+ example of use:
+ $mail = new PHPMailer();
+ $mail->Mailer = "smtp";
+ $mail->Host = "smtp.example.com";
+ $mail->SMTPSecure = "tls"; // option
+ //$mail->SMTPSecure = "ssl"; // option
+ ...
+ $mail->Send();
+* PHPMailer has been tested with PHP4 (4.4.7) and PHP5 (5.2.7)
+* Works with PHP installed as a module or as CGI-PHP
+- NOTE: will NOT work with PHP5 in E_STRICT error mode
+
+Version 1.73 (Sun, Jun 10 2005)
+* Fixed denial of service bug: http://www.cybsec.com/vuln/PHPMailer-DOS.pdf
+* Now has a total of 20 translations
+* Fixed alt attachments bug: http://tinyurl.com/98u9k
+
+Version 1.72 (Wed, May 25 2004)
+* Added Dutch, Swedish, Czech, Norwegian, and Turkish translations.
+* Received: Removed this method because spam filter programs like
+SpamAssassin reject this header.
+* Fixed error count bug.
+* SetLanguage default is now "language/".
+* Fixed magic_quotes_runtime bug.
+
+Version 1.71 (Tue, Jul 28 2003)
+* Made several speed enhancements
+* Added German and Italian translation files
+* Fixed HELO/AUTH bugs on keep-alive connects
+* Now provides an error message if language file does not load
+* Fixed attachment EOL bug
+* Updated some unclear documentation
+* Added additional tests and improved others
+
+Version 1.70 (Mon, Jun 20 2003)
+* Added SMTP keep-alive support
+* Added IsError method for error detection
+* Added error message translation support (SetLanguage)
+* Refactored many methods to increase library performance
+* Hello now sends the newer EHLO message before HELO as per RFC 2821
+* Removed the boundary class and replaced it with GetBoundary
+* Removed queue support methods
+* New $Hostname variable
+* New Message-ID header
+* Received header reformat
+* Helo variable default changed to $Hostname
+* Removed extra spaces in Content-Type definition (#667182)
+* Return-Path should be set to Sender when set
+* Adds Q or B encoding to headers when necessary
+* quoted-encoding should now encode NULs \000
+* Fixed encoding of body/AltBody (#553370)
+* Adds "To: undisclosed-recipients:;" when all recipients are hidden (BCC)
+* Multiple bug fixes
+
+Version 1.65 (Fri, Aug 09 2002)
+* Fixed non-visible attachment bug (#585097) for Outlook
+* SMTP connections are now closed after each transaction
+* Fixed SMTP::Expand return value
+* Converted SMTP class documentation to phpDocumentor format
+
+Version 1.62 (Wed, Jun 26 2002)
+* Fixed multi-attach bug
+* Set proper word wrapping
+* Reduced memory use with attachments
+* Added more debugging
+* Changed documentation to phpDocumentor format
+
+Version 1.60 (Sat, Mar 30 2002)
+* Sendmail pipe and address patch (Christian Holtje)
+* Added embedded image and read confirmation support (A. Ognio)
+* Added unit tests
+* Added SMTP timeout support (*nix only)
+* Added possibly temporary PluginDir variable for SMTP class
+* Added LE message line ending variable
+* Refactored boundary and attachment code
+* Eliminated SMTP class warnings
+* Added SendToQueue method for future queuing support
+
+Version 1.54 (Wed, Dec 19 2001)
+* Add some queuing support code
+* Fixed a pesky multi/alt bug
+* Messages are no longer forced to have "To" addresses
+
+Version 1.50 (Thu, Nov 08 2001)
+* Fix extra lines when not using SMTP mailer
+* Set WordWrap variable to int with a zero default
+
+Version 1.47 (Tue, Oct 16 2001)
+* Fixed Received header code format
+* Fixed AltBody order error
+* Fixed alternate port warning
+
+Version 1.45 (Tue, Sep 25 2001)
+* Added enhanced SMTP debug support
+* Added support for multiple ports on SMTP
+* Added Received header for tracing
+* Fixed AddStringAttachment encoding
+* Fixed possible header name quote bug
+* Fixed wordwrap() trim bug
+* Couple other small bug fixes
+
+Version 1.41 (Wed, Aug 22 2001)
+* Fixed AltBody bug w/o attachments
+* Fixed rfc_date() for certain mail servers
+
+Version 1.40 (Sun, Aug 12 2001)
+* Added multipart/alternative support (AltBody)
+* Documentation update
+* Fixed bug in Mercury MTA
+
+Version 1.29 (Fri, Aug 03 2001)
+* Added AddStringAttachment() method
+* Added SMTP authentication support
+
+Version 1.28 (Mon, Jul 30 2001)
+* Fixed a typo in SMTP class
+* Fixed header issue with Imail (win32) SMTP server
+* Made fopen() calls for attachments use "rb" to fix win32 error
+
+Version 1.25 (Mon, Jul 02 2001)
+* Added RFC 822 date fix (Patrice)
+* Added improved error handling by adding a $ErrorInfo variable
+* Removed MailerDebug variable (obsolete with new error handler)
+
+Version 1.20 (Mon, Jun 25 2001)
+* Added quoted-printable encoding (Patrice)
+* Set Version as public and removed PrintVersion()
+* Changed phpdoc to only display public variables and methods
+
+Version 1.19 (Thu, Jun 21 2001)
+* Fixed MS Mail header bug
+* Added fix for Bcc problem with mail(). *Does not work on Win32*
+ (See PHP bug report: http://www.php.net/bugs.php?id=11616)
+* mail() no longer passes a fifth parameter when not needed
+
+Version 1.15 (Fri, Jun 15 2001)
+[Note: these changes contributed by Patrice Fournier]
+* Changed all remaining \n to \r\n
+* Bcc: header no longer writen to message except
+when sent directly to sendmail
+* Added a small message to non-MIME compliant mail reader
+* Added Sender variable to change the Sender email
+used in -f for sendmail/mail and in 'MAIL FROM' for smtp mode
+* Changed boundary setting to a place it will be set only once
+* Removed transfer encoding for whole message when using multipart
+* Message body now uses Encoding in multipart messages
+* Can set encoding and type to attachments 7bit, 8bit
+and binary attachment are sent as is, base64 are encoded
+* Can set Encoding to base64 to send 8 bits body
+through 7 bits servers
+
+Version 1.10 (Tue, Jun 12 2001)
+* Fixed win32 mail header bug (printed out headers in message body)
+
+Version 1.09 (Fri, Jun 08 2001)
+* Changed date header to work with Netscape mail programs
+* Altered phpdoc documentation
+
+Version 1.08 (Tue, Jun 05 2001)
+* Added enhanced error-checking
+* Added phpdoc documentation to source
+
+Version 1.06 (Fri, Jun 01 2001)
+* Added optional name for file attachments
+
+Version 1.05 (Tue, May 29 2001)
+* Code cleanup
+* Eliminated sendmail header warning message
+* Fixed possible SMTP error
+
+Version 1.03 (Thu, May 24 2001)
+* Fixed problem where qmail sends out duplicate messages
+
+Version 1.02 (Wed, May 23 2001)
+* Added multiple recipient and attachment Clear* methods
+* Added Sendmail public variable
+* Fixed problem with loading SMTP library multiple times
+
+Version 0.98 (Tue, May 22 2001)
+* Fixed problem with redundant mail hosts sending out multiple messages
+* Added additional error handler code
+* Added AddCustomHeader() function
+* Added support for Microsoft mail client headers (affects priority)
+* Fixed small bug with Mailer variable
+* Added PrintVersion() function
+
+Version 0.92 (Tue, May 15 2001)
+* Changed file names to class.phpmailer.php and class.smtp.php to match
+ current PHP class trend.
+* Fixed problem where body not being printed when a message is attached
+* Several small bug fixes
+
+Version 0.90 (Tue, April 17 2001)
+* Intial public release
diff --git a/site/vendors/phpmailer/LICENSE b/site/vendors/phpmailer/LICENSE
new file mode 100644
index 0000000..03851a3
--- /dev/null
+++ b/site/vendors/phpmailer/LICENSE
@@ -0,0 +1,504 @@
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL. It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+ This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it. You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+ When we speak of free software, we are referring to freedom of use,
+not price. Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+ To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights. These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+ For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you. You must make sure that they, too, receive or can get the source
+code. If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it. And you must show them these terms so they know their rights.
+
+ We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+ To protect each distributor, we want to make it very clear that
+there is no warranty for the free library. Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+
+ Finally, software patents pose a constant threat to the existence of
+any free program. We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder. Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+ Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License. This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License. We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+ When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library. The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom. The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+ We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License. It also provides other free software developers Less
+of an advantage over competing non-free programs. These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries. However, the Lesser license provides advantages in certain
+special circumstances.
+
+ For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard. To achieve this, non-free programs must be
+allowed to use the library. A more frequent case is that a free
+library does the same job as widely used non-free libraries. In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+ In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software. For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+ Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+ The precise terms and conditions for copying, distribution and
+modification follow. Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library". The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+
+ GNU LESSER GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+ A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+ The "Library", below, refers to any such software library or work
+which has been distributed under these terms. A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language. (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+ "Source code" for a work means the preferred form of the work for
+making modifications to it. For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+ Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it). Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+ 1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+ You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+ 2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) The modified work must itself be a software library.
+
+ b) You must cause the files modified to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ c) You must cause the whole of the work to be licensed at no
+ charge to all third parties under the terms of this License.
+
+ d) If a facility in the modified Library refers to a function or a
+ table of data to be supplied by an application program that uses
+ the facility, other than as an argument passed when the facility
+ is invoked, then you must make a good faith effort to ensure that,
+ in the event an application does not supply such function or
+ table, the facility still operates, and performs whatever part of
+ its purpose remains meaningful.
+
+ (For example, a function in a library to compute square roots has
+ a purpose that is entirely well-defined independent of the
+ application. Therefore, Subsection 2d requires that any
+ application-supplied function or table used by this function must
+ be optional: if the application does not supply it, the square
+ root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library. To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License. (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.) Do not make any other change in
+these notices.
+
+ Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+ This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+ 4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+ If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library". Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+ However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library". The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+ When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library. The
+threshold for this to be true is not precisely defined by law.
+
+ If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work. (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+ Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+ 6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+ You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License. You must supply a copy of this License. If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License. Also, you must do one
+of these things:
+
+ a) Accompany the work with the complete corresponding
+ machine-readable source code for the Library including whatever
+ changes were used in the work (which must be distributed under
+ Sections 1 and 2 above); and, if the work is an executable linked
+ with the Library, with the complete machine-readable "work that
+ uses the Library", as object code and/or source code, so that the
+ user can modify the Library and then relink to produce a modified
+ executable containing the modified Library. (It is understood
+ that the user who changes the contents of definitions files in the
+ Library will not necessarily be able to recompile the application
+ to use the modified definitions.)
+
+ b) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (1) uses at run time a
+ copy of the library already present on the user's computer system,
+ rather than copying library functions into the executable, and (2)
+ will operate properly with a modified version of the library, if
+ the user installs one, as long as the modified version is
+ interface-compatible with the version that the work was made with.
+
+ c) Accompany the work with a written offer, valid for at
+ least three years, to give the same user the materials
+ specified in Subsection 6a, above, for a charge no more
+ than the cost of performing this distribution.
+
+ d) If distribution of the work is made by offering access to copy
+ from a designated place, offer equivalent access to copy the above
+ specified materials from the same place.
+
+ e) Verify that the user has already received a copy of these
+ materials or that you have already sent this user a copy.
+
+ For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it. However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+ It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system. Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+ 7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+ a) Accompany the combined library with a copy of the same work
+ based on the Library, uncombined with any other library
+ facilities. This must be distributed under the terms of the
+ Sections above.
+
+ b) Give prominent notice with the combined library of the fact
+ that part of it is a work based on the Library, and explaining
+ where to find the accompanying uncombined form of the same work.
+
+ 8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License. Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License. However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+ 9. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Library or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+ 10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+
+ 11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all. For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded. In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+ 13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation. If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+ 14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission. For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this. Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+ NO WARRANTY
+
+ 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Libraries
+
+ If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change. You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+ To apply these terms, attach the following notices to the library. It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the library's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the
+ library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+ <signature of Ty Coon>, 1 April 1990
+ Ty Coon, President of Vice
+
+That's all there is to it!
+
+
diff --git a/site/vendors/phpmailer/README b/site/vendors/phpmailer/README
new file mode 100644
index 0000000..900c630
--- /dev/null
+++ b/site/vendors/phpmailer/README
@@ -0,0 +1,121 @@
+PHPMailer
+Full Featured Email Transfer Class for PHP
+==========================================
+
+** NOTE:
+
+As of November 2007, PHPMailer has a new project team headed by industry
+veteran Andy Prevost (codeworxtech). The first release in more than two
+years will focus on fixes, adding ease-of-use enhancements, provide
+basic compatibility with PHP4 and PHP5 using PHP5 backwards compatibility
+features. A new release is planned before year-end 2007 that will provide
+full compatiblity with PHP4 and PHP5, as well as more bug fixes.
+
+We are looking for project developers to assist in restoring PHPMailer to
+its leadership position. Our goals are to simplify use of PHPMailer, provide
+good documentation and examples, and retain backward compatibility to level
+1.7.3 standards.
+
+If you are interested in helping out, visit http://sourceforge.net/phpmailer
+and indicate your interest.
+
+**
+
+http://phpmailer.sourceforge.net/
+
+This software is licenced under the LGPL. Please read LICENSE for information on the
+software availability and distribution.
+
+Class Features:
+- Send emails with multiple TOs, CCs, BCCs and REPLY-TOs
+- Redundant SMTP servers
+- Multipart/alternative emails for mail clients that do not read HTML email
+- Support for 8bit, base64, binary, and quoted-printable encoding
+- Uses the same methods as the very popular AspEmail active server (COM) component
+- SMTP authentication
+- Native language support
+- Word wrap, and more!
+
+Why you might need it:
+
+Many PHP developers utilize email in their code. The only PHP function
+that supports this is the mail() function. However, it does not expose
+any of the popular features that many email clients use nowadays like
+HTML-based emails and attachments. There are two proprietary
+development tools out there that have all the functionality built into
+easy to use classes: AspEmail(tm) and AspMail. Both of these
+programs are COM components only available on Windows. They are also a
+little pricey for smaller projects.
+
+Since I do Linux development I’ve missed these tools for my PHP coding.
+So I built a version myself that implements the same methods (object
+calls) that the Windows-based components do. It is open source and the
+LGPL license allows you to place the class in your proprietary PHP
+projects.
+
+
+Installation:
+
+Copy class.phpmailer.php into your php.ini include_path. If you are
+using the SMTP mailer then place class.smtp.php in your path as well.
+In the language directory you will find several files like
+phpmailer.lang-en.php. If you look right before the .php extension
+that there are two letters. These represent the language type of the
+translation file. For instance "en" is the English file and "br" is
+the Portuguese file. Chose the file that best fits with your language
+and place it in the PHP include path. If your language is English
+then you have nothing more to do. If it is a different language then
+you must point PHPMailer to the correct translation. To do this, call
+the PHPMailer SetLanguage method like so:
+
+// To load the Portuguese version
+$mail->SetLanguage("br", "/optional/path/to/language/directory/");
+
+That's it. You should now be ready to use PHPMailer!
+
+
+A Simple Example:
+
+<?php
+require("class.phpmailer.php");
+
+$mail = new PHPMailer();
+
+$mail->IsSMTP(); // set mailer to use SMTP
+$mail->Host = "smtp1.example.com;smtp2.example.com"; // specify main and backup server
+$mail->SMTPAuth = true; // turn on SMTP authentication
+$mail->Username = "jswan"; // SMTP username
+$mail->Password = "secret"; // SMTP password
+
+$mail->From = "from@example.com";
+$mail->FromName = "Mailer";
+$mail->AddAddress("josh@example.net", "Josh Adams");
+$mail->AddAddress("ellen@example.com"); // name is optional
+$mail->AddReplyTo("info@example.com", "Information");
+
+$mail->WordWrap = 50; // set word wrap to 50 characters
+$mail->AddAttachment("/var/tmp/file.tar.gz"); // add attachments
+$mail->AddAttachment("/tmp/image.jpg", "new.jpg"); // optional name
+$mail->IsHTML(true); // set email format to HTML
+
+$mail->Subject = "Here is the subject";
+$mail->Body = "This is the HTML message body <b>in bold!</b>";
+$mail->AltBody = "This is the body in plain text for non-HTML mail clients";
+
+if(!$mail->Send())
+{
+ echo "Message could not be sent. <p>";
+ echo "Mailer Error: " . $mail->ErrorInfo;
+ exit;
+}
+
+echo "Message has been sent";
+?>
+
+CHANGELOG
+
+See ChangeLog.txt
+
+Download: http://sourceforge.net/project/showfiles.php?group_id=26031
+
+Andy Prevost
diff --git a/site/vendors/phpmailer/class.phpmailer.php b/site/vendors/phpmailer/class.phpmailer.php
new file mode 100644
index 0000000..f9245c2
--- /dev/null
+++ b/site/vendors/phpmailer/class.phpmailer.php
@@ -0,0 +1,1856 @@
+<?php
+/*~ class.phpmailer.php
+.---------------------------------------------------------------------------.
+| Software: PHPMailer - PHP email class |
+| Version: 2.0.0 rc3 |
+| Contact: via sourceforge.net support pages (also www.codeworxtech.com) |
+| Info: http://phpmailer.sourceforge.net |
+| Support: http://sourceforge.net/projects/phpmailer/ |
+| ------------------------------------------------------------------------- |
+| Author: Andy Prevost (project admininistrator) |
+| Author: Brent R. Matzelle (original founder) |
+| Copyright (c) 2004-2007, Andy Prevost. All Rights Reserved. |
+| Copyright (c) 2001-2003, Brent R. Matzelle |
+| ------------------------------------------------------------------------- |
+| License: Distributed under the Lesser General Public License (LGPL) |
+| http://www.gnu.org/copyleft/lesser.html |
+| This program is distributed in the hope that it will be useful - WITHOUT |
+| ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
+| FITNESS FOR A PARTICULAR PURPOSE. |
+| ------------------------------------------------------------------------- |
+| We offer a number of paid services (www.codeworxtech.com): |
+| - Web Hosting on highly optimized fast and secure servers |
+| - Technology Consulting |
+| - Oursourcing (highly qualified programmers and graphic designers) |
+'---------------------------------------------------------------------------'
+
+/**
+ * PHPMailer - PHP email transport class
+ * @package PHPMailer
+ * @author Andy Prevost
+ * @copyright 2004 - 2007 Andy Prevost
+ */
+
+class PHPMailer {
+
+ /////////////////////////////////////////////////
+ // PROPERTIES, PUBLIC
+ /////////////////////////////////////////////////
+
+ /**
+ * Email priority (1 = High, 3 = Normal, 5 = low).
+ * @var int
+ */
+ var $Priority = 3;
+
+ /**
+ * Sets the CharSet of the message.
+ * @var string
+ */
+ var $CharSet = 'iso-8859-1';
+
+ /**
+ * Sets the Content-type of the message.
+ * @var string
+ */
+ var $ContentType = 'text/plain';
+
+ /**
+ * Sets the Encoding of the message. Options for this are "8bit",
+ * "7bit", "binary", "base64", and "quoted-printable".
+ * @var string
+ */
+ var $Encoding = '8bit';
+
+ /**
+ * Holds the most recent mailer error message.
+ * @var string
+ */
+ var $ErrorInfo = '';
+
+ /**
+ * Sets the From email address for the message.
+ * @var string
+ */
+ var $From = 'root@localhost';
+
+ /**
+ * Sets the From name of the message.
+ * @var string
+ */
+ var $FromName = 'Root User';
+
+ /**
+ * Sets the Sender email (Return-Path) of the message. If not empty,
+ * will be sent via -f to sendmail or as 'MAIL FROM' in smtp mode.
+ * @var string
+ */
+ var $Sender = '';
+
+ /**
+ * Sets the Subject of the message.
+ * @var string
+ */
+ var $Subject = '';
+
+ /**
+ * Sets the Body of the message. This can be either an HTML or text body.
+ * If HTML then run IsHTML(true).
+ * @var string
+ */
+ var $Body = '';
+
+ /**
+ * Sets the text-only body of the message. This automatically sets the
+ * email to multipart/alternative. This body can be read by mail
+ * clients that do not have HTML email capability such as mutt. Clients
+ * that can read HTML will view the normal Body.
+ * @var string
+ */
+ var $AltBody = '';
+
+ /**
+ * Sets word wrapping on the body of the message to a given number of
+ * characters.
+ * @var int
+ */
+ var $WordWrap = 0;
+
+ /**
+ * Method to send mail: ("mail", "sendmail", or "smtp").
+ * @var string
+ */
+ var $Mailer = 'mail';
+
+ /**
+ * Sets the path of the sendmail program.
+ * @var string
+ */
+ var $Sendmail = '/usr/sbin/sendmail';
+
+ /**
+ * Path to PHPMailer plugins. This is now only useful if the SMTP class
+ * is in a different directory than the PHP include path.
+ * @var string
+ */
+ var $PluginDir = '';
+
+ /**
+ * Holds PHPMailer version.
+ * @var string
+ */
+ var $Version = "2.0.0 rc3";
+
+ /**
+ * Sets the email address that a reading confirmation will be sent.
+ * @var string
+ */
+ var $ConfirmReadingTo = '';
+
+ /**
+ * Sets the hostname to use in Message-Id and Received headers
+ * and as default HELO string. If empty, the value returned
+ * by SERVER_NAME is used or 'localhost.localdomain'.
+ * @var string
+ */
+ var $Hostname = '';
+
+ /////////////////////////////////////////////////
+ // PROPERTIES FOR SMTP
+ /////////////////////////////////////////////////
+
+ /**
+ * Sets the SMTP hosts. All hosts must be separated by a
+ * semicolon. You can also specify a different port
+ * for each host by using this format: [hostname:port]
+ * (e.g. "smtp1.example.com:25;smtp2.example.com").
+ * Hosts will be tried in order.
+ * @var string
+ */
+ var $Host = 'localhost';
+
+ /**
+ * Sets the default SMTP server port.
+ * @var int
+ */
+ var $Port = 25;
+
+ /**
+ * Sets the SMTP HELO of the message (Default is $Hostname).
+ * @var string
+ */
+ var $Helo = '';
+
+ /**
+ * Sets connection prefix.
+ * Options are "", "ssl" or "tls"
+ * @var string
+ */
+ var $SMTPSecure = "";
+
+ /**
+ * Sets SMTP authentication. Utilizes the Username and Password variables.
+ * @var bool
+ */
+ var $SMTPAuth = false;
+
+ /**
+ * Sets SMTP username.
+ * @var string
+ */
+ var $Username = '';
+
+ /**
+ * Sets SMTP password.
+ * @var string
+ */
+ var $Password = '';
+
+ /**
+ * Sets the SMTP server timeout in seconds. This function will not
+ * work with the win32 version.
+ * @var int
+ */
+ var $Timeout = 10;
+
+ /**
+ * Sets SMTP class debugging on or off.
+ * @var bool
+ */
+ var $SMTPDebug = false;
+
+ /**
+ * Prevents the SMTP connection from being closed after each mail
+ * sending. If this is set to true then to close the connection
+ * requires an explicit call to SmtpClose().
+ * @var bool
+ */
+ var $SMTPKeepAlive = false;
+
+ /**
+ * Provides the ability to have the TO field process individual
+ * emails, instead of sending to entire TO addresses
+ * @var bool
+ */
+ var $SingleTo = false;
+
+ /////////////////////////////////////////////////
+ // PROPERTIES, PRIVATE
+ /////////////////////////////////////////////////
+
+ var $smtp = NULL;
+ var $to = array();
+ var $cc = array();
+ var $bcc = array();
+ var $ReplyTo = array();
+ var $attachment = array();
+ var $CustomHeader = array();
+ var $message_type = '';
+ var $boundary = array();
+ var $language = array();
+ var $error_count = 0;
+ var $LE = "\n";
+
+ /////////////////////////////////////////////////
+ // METHODS, VARIABLES
+ /////////////////////////////////////////////////
+
+ /**
+ * Sets message type to HTML.
+ * @param bool $bool
+ * @return void
+ */
+ function IsHTML($bool) {
+ if($bool == true) {
+ $this->ContentType = 'text/html';
+ } else {
+ $this->ContentType = 'text/plain';
+ }
+ }
+
+ /**
+ * Sets Mailer to send message using SMTP.
+ * @return void
+ */
+ function IsSMTP() {
+ $this->Mailer = 'smtp';
+ }
+
+ /**
+ * Sets Mailer to send message using PHP mail() function.
+ * @return void
+ */
+ function IsMail() {
+ $this->Mailer = 'mail';
+ }
+
+ /**
+ * Sets Mailer to send message using the $Sendmail program.
+ * @return void
+ */
+ function IsSendmail() {
+ $this->Mailer = 'sendmail';
+ }
+
+ /**
+ * Sets Mailer to send message using the qmail MTA.
+ * @return void
+ */
+ function IsQmail() {
+ $this->Sendmail = '/var/qmail/bin/sendmail';
+ $this->Mailer = 'sendmail';
+ }
+
+ /////////////////////////////////////////////////
+ // METHODS, RECIPIENTS
+ /////////////////////////////////////////////////
+
+ /**
+ * Adds a "To" address.
+ * @param string $address
+ * @param string $name
+ * @return void
+ */
+ function AddAddress($address, $name = '') {
+ $cur = count($this->to);
+ $this->to[$cur][0] = trim($address);
+ $this->to[$cur][1] = $name;
+ }
+
+ /**
+ * Adds a "Cc" address. Note: this function works
+ * with the SMTP mailer on win32, not with the "mail"
+ * mailer.
+ * @param string $address
+ * @param string $name
+ * @return void
+ */
+ function AddCC($address, $name = '') {
+ $cur = count($this->cc);
+ $this->cc[$cur][0] = trim($address);
+ $this->cc[$cur][1] = $name;
+ }
+
+ /**
+ * Adds a "Bcc" address. Note: this function works
+ * with the SMTP mailer on win32, not with the "mail"
+ * mailer.
+ * @param string $address
+ * @param string $name
+ * @return void
+ */
+ function AddBCC($address, $name = '') {
+ $cur = count($this->bcc);
+ $this->bcc[$cur][0] = trim($address);
+ $this->bcc[$cur][1] = $name;
+ }
+
+ /**
+ * Adds a "Reply-To" address.
+ * @param string $address
+ * @param string $name
+ * @return void
+ */
+ function AddReplyTo($address, $name = '') {
+ $cur = count($this->ReplyTo);
+ $this->ReplyTo[$cur][0] = trim($address);
+ $this->ReplyTo[$cur][1] = $name;
+ }
+
+ /////////////////////////////////////////////////
+ // METHODS, MAIL SENDING
+ /////////////////////////////////////////////////
+
+ /**
+ * Creates message and assigns Mailer. If the message is
+ * not sent successfully then it returns false. Use the ErrorInfo
+ * variable to view description of the error.
+ * @return bool
+ */
+ function Send() {
+ $header = '';
+ $body = '';
+ $result = true;
+
+ if((count($this->to) + count($this->cc) + count($this->bcc)) < 1) {
+ $this->SetError($this->Lang('provide_address'));
+ return false;
+ }
+
+ /* Set whether the message is multipart/alternative */
+ if(!empty($this->AltBody)) {
+ $this->ContentType = 'multipart/alternative';
+ }
+
+ $this->error_count = 0; // reset errors
+ $this->SetMessageType();
+ $header .= $this->CreateHeader();
+ $body = $this->CreateBody();
+
+ if($body == '') {
+ return false;
+ }
+
+ /* Choose the mailer */
+ switch($this->Mailer) {
+ case 'sendmail':
+ $result = $this->SendmailSend($header, $body);
+ break;
+ case 'smtp':
+ $result = $this->SmtpSend($header, $body);
+ break;
+ case 'mail':
+ $result = $this->MailSend($header, $body);
+ break;
+ default:
+ $result = $this->MailSend($header, $body);
+ break;
+ //$this->SetError($this->Mailer . $this->Lang('mailer_not_supported'));
+ //$result = false;
+ //break;
+ }
+
+ return $result;
+ }
+
+ /**
+ * Sends mail using the $Sendmail program.
+ * @access private
+ * @return bool
+ */
+ function SendmailSend($header, $body) {
+ if ($this->Sender != '') {
+ $sendmail = sprintf("%s -oi -f %s -t", escapeshellcmd($this->Sendmail), escapeshellarg($this->Sender));
+ } else {
+ $sendmail = sprintf("%s -oi -t", escapeshellcmd($this->Sendmail));
+ }
+
+ if(!@$mail = popen($sendmail, 'w')) {
+ $this->SetError($this->Lang('execute') . $this->Sendmail);
+ return false;
+ }
+
+ fputs($mail, $header);
+ fputs($mail, $body);
+
+ $result = pclose($mail) >> 8 & 0xFF;
+ if($result != 0) {
+ $this->SetError($this->Lang('execute') . $this->Sendmail);
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Sends mail using the PHP mail() function.
+ * @access private
+ * @return bool
+ */
+ function MailSend($header, $body) {
+
+ $to = '';
+ for($i = 0; $i < count($this->to); $i++) {
+ if($i != 0) { $to .= ', '; }
+ $to .= $this->AddrFormat($this->to[$i]);
+ }
+
+ $toArr = split(',', $to);
+
+ if ($this->Sender != '' && strlen(ini_get('safe_mode'))< 1) {
+ $old_from = ini_get('sendmail_from');
+ ini_set('sendmail_from', $this->Sender);
+ $params = sprintf("-oi -f %s", $this->Sender);
+ if ($this->SingleTo === true && count($toArr) > 1) {
+ foreach ($toArr as $key => $val) {
+ $rt = @mail($val, $this->EncodeHeader($this->SecureHeader($this->Subject)), $body, $header, $params);
+ }
+ } else {
+ $rt = @mail($to, $this->EncodeHeader($this->SecureHeader($this->Subject)), $body, $header, $params);
+ }
+ } else {
+ if ($this->SingleTo === true && count($toArr) > 1) {
+ foreach ($toArr as $key => $val) {
+ $rt = @mail($val, $this->EncodeHeader($this->SecureHeader($this->Subject)), $body, $header, $params);
+ }
+ } else {
+ $rt = @mail($to, $this->EncodeHeader($this->SecureHeader($this->Subject)), $body, $header);
+ }
+ }
+
+ if (isset($old_from)) {
+ ini_set('sendmail_from', $old_from);
+ }
+
+ if(!$rt) {
+ $this->SetError($this->Lang('instantiate'));
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Sends mail via SMTP using PhpSMTP (Author:
+ * Chris Ryan). Returns bool. Returns false if there is a
+ * bad MAIL FROM, RCPT, or DATA input.
+ * @access private
+ * @return bool
+ */
+ function SmtpSend($header, $body) {
+ include_once($this->PluginDir . 'class.smtp.php');
+ $error = '';
+ $bad_rcpt = array();
+
+ if(!$this->SmtpConnect()) {
+ return false;
+ }
+
+ $smtp_from = ($this->Sender == '') ? $this->From : $this->Sender;
+ if(!$this->smtp->Mail($smtp_from)) {
+ $error = $this->Lang('from_failed') . $smtp_from;
+ $this->SetError($error);
+ $this->smtp->Reset();
+ return false;
+ }
+
+ /* Attempt to send attach all recipients */
+ for($i = 0; $i < count($this->to); $i++) {
+ if(!$this->smtp->Recipient($this->to[$i][0])) {
+ $bad_rcpt[] = $this->to[$i][0];
+ }
+ }
+ for($i = 0; $i < count($this->cc); $i++) {
+ if(!$this->smtp->Recipient($this->cc[$i][0])) {
+ $bad_rcpt[] = $this->cc[$i][0];
+ }
+ }
+ for($i = 0; $i < count($this->bcc); $i++) {
+ if(!$this->smtp->Recipient($this->bcc[$i][0])) {
+ $bad_rcpt[] = $this->bcc[$i][0];
+ }
+ }
+
+ if(count($bad_rcpt) > 0) { // Create error message
+ for($i = 0; $i < count($bad_rcpt); $i++) {
+ if($i != 0) {
+ $error .= ', ';
+ }
+ $error .= $bad_rcpt[$i];
+ }
+ $error = $this->Lang('recipients_failed') . $error;
+ $this->SetError($error);
+ $this->smtp->Reset();
+ return false;
+ }
+
+ if(!$this->smtp->Data($header . $body)) {
+ $this->SetError($this->Lang('data_not_accepted'));
+ $this->smtp->Reset();
+ return false;
+ }
+ if($this->SMTPKeepAlive == true) {
+ $this->smtp->Reset();
+ } else {
+ $this->SmtpClose();
+ }
+
+ return true;
+ }
+
+ /**
+ * Initiates a connection to an SMTP server. Returns false if the
+ * operation failed.
+ * @access private
+ * @return bool
+ */
+ function SmtpConnect() {
+ if($this->smtp == NULL) {
+ $this->smtp = new SMTP();
+ }
+
+ $this->smtp->do_debug = $this->SMTPDebug;
+ $hosts = explode(';', $this->Host);
+ $index = 0;
+ $connection = ($this->smtp->Connected());
+
+ /* Retry while there is no connection */
+ while($index < count($hosts) && $connection == false) {
+ $hostinfo = array();
+ if(eregi('^(.+):([0-9]+)$', $hosts[$index], $hostinfo)) {
+ $host = $hostinfo[1];
+ $port = $hostinfo[2];
+ } else {
+ $host = $hosts[$index];
+ $port = $this->Port;
+ }
+
+ if($this->smtp->Connect(((!empty($this->SMTPSecure))?$this->SMTPSecure.'://':'').$host, $port, $this->Timeout)) {
+ if ($this->Helo != '') {
+ $this->smtp->Hello($this->Helo);
+ } else {
+ $this->smtp->Hello($this->ServerHostname());
+ }
+
+ $connection = true;
+ if($this->SMTPAuth) {
+ if(!$this->smtp->Authenticate($this->Username, $this->Password)) {
+ $this->SetError($this->Lang('authenticate'));
+ $this->smtp->Reset();
+ $connection = false;
+ }
+ }
+ }
+ $index++;
+ }
+ if(!$connection) {
+ $this->SetError($this->Lang('connect_host'));
+ }
+
+ return $connection;
+ }
+
+ /**
+ * Closes the active SMTP session if one exists.
+ * @return void
+ */
+ function SmtpClose() {
+ if($this->smtp != NULL) {
+ if($this->smtp->Connected()) {
+ $this->smtp->Quit();
+ $this->smtp->Close();
+ }
+ }
+ }
+
+ /**
+ * Sets the language for all class error messages. Returns false
+ * if it cannot load the language file. The default language type
+ * is English.
+ * @param string $lang_type Type of language (e.g. Portuguese: "br")
+ * @param string $lang_path Path to the language file directory
+ * @access public
+ * @return bool
+ */
+ function SetLanguage($lang_type, $lang_path = 'language/') {
+ if(file_exists($lang_path.'phpmailer.lang-'.$lang_type.'.php')) {
+ include($lang_path.'phpmailer.lang-'.$lang_type.'.php');
+ } elseif (file_exists($lang_path.'phpmailer.lang-en.php')) {
+ include($lang_path.'phpmailer.lang-en.php');
+ } else {
+ $this->SetError('Could not load language file');
+ return false;
+ }
+ $this->language = $PHPMAILER_LANG;
+
+ return true;
+ }
+
+ /////////////////////////////////////////////////
+ // METHODS, MESSAGE CREATION
+ /////////////////////////////////////////////////
+
+ /**
+ * Creates recipient headers.
+ * @access private
+ * @return string
+ */
+ function AddrAppend($type, $addr) {
+ $addr_str = $type . ': ';
+ $addr_str .= $this->AddrFormat($addr[0]);
+ if(count($addr) > 1) {
+ for($i = 1; $i < count($addr); $i++) {
+ $addr_str .= ', ' . $this->AddrFormat($addr[$i]);
+ }
+ }
+ $addr_str .= $this->LE;
+
+ return $addr_str;
+ }
+
+ /**
+ * Formats an address correctly.
+ * @access private
+ * @return string
+ */
+ function AddrFormat($addr) {
+ if(empty($addr[1])) {
+ $formatted = $this->SecureHeader($addr[0]);
+ } else {
+ $formatted = $this->EncodeHeader($this->SecureHeader($addr[1]), 'phrase') . " <" . $this->SecureHeader($addr[0]) . ">";
+ }
+
+ return $formatted;
+ }
+
+ /**
+ * Wraps message for use with mailers that do not
+ * automatically perform wrapping and for quoted-printable.
+ * Original written by philippe.
+ * @access private
+ * @return string
+ */
+ function WrapText($message, $length, $qp_mode = false) {
+ $soft_break = ($qp_mode) ? sprintf(" =%s", $this->LE) : $this->LE;
+ // If utf-8 encoding is used, we will need to make sure we don't
+ // split multibyte characters when we wrap
+ $is_utf8 = (strtolower($this->CharSet) == "utf-8");
+
+ $message = $this->FixEOL($message);
+ if (substr($message, -1) == $this->LE) {
+ $message = substr($message, 0, -1);
+ }
+
+ $line = explode($this->LE, $message);
+ $message = '';
+ for ($i=0 ;$i < count($line); $i++) {
+ $line_part = explode(' ', $line[$i]);
+ $buf = '';
+ for ($e = 0; $e<count($line_part); $e++) {
+ $word = $line_part[$e];
+ if ($qp_mode and (strlen($word) > $length)) {
+ $space_left = $length - strlen($buf) - 1;
+ if ($e != 0) {
+ if ($space_left > 20) {
+ $len = $space_left;
+ if ($is_utf8) {
+ $len = $this->UTF8CharBoundary($word, $len);
+ } elseif (substr($word, $len - 1, 1) == "=") {
+ $len--;
+ } elseif (substr($word, $len - 2, 1) == "=") {
+ $len -= 2;
+ }
+ $part = substr($word, 0, $len);
+ $word = substr($word, $len);
+ $buf .= ' ' . $part;
+ $message .= $buf . sprintf("=%s", $this->LE);
+ } else {
+ $message .= $buf . $soft_break;
+ }
+ $buf = '';
+ }
+ while (strlen($word) > 0) {
+ $len = $length;
+ if ($is_utf8) {
+ $len = $this->UTF8CharBoundary($word, $len);
+ } elseif (substr($word, $len - 1, 1) == "=") {
+ $len--;
+ } elseif (substr($word, $len - 2, 1) == "=") {
+ $len -= 2;
+ }
+ $part = substr($word, 0, $len);
+ $word = substr($word, $len);
+
+ if (strlen($word) > 0) {
+ $message .= $part . sprintf("=%s", $this->LE);
+ } else {
+ $buf = $part;
+ }
+ }
+ } else {
+ $buf_o = $buf;
+ $buf .= ($e == 0) ? $word : (' ' . $word);
+
+ if (strlen($buf) > $length and $buf_o != '') {
+ $message .= $buf_o . $soft_break;
+ $buf = $word;
+ }
+ }
+ }
+ $message .= $buf . $this->LE;
+ }
+
+ return $message;
+ }
+
+ /**
+ * Finds last character boundary prior to maxLength in a utf-8
+ * quoted (printable) encoded string.
+ * Original written by Colin Brown.
+ *
+ * @access private
+ *
+ * @param string $encodedText utf-8 QP text
+ * @param int $maxLength find last character boundary prior to this length
+ *
+ * @return int
+ */
+ function UTF8CharBoundary($encodedText, $maxLength)
+ {
+ $foundSplitPos = false;
+ $lookBack = 3;
+
+ while (!$foundSplitPos)
+ {
+ $lastChunk = substr($encodedText, $maxLength - $lookBack, $lookBack);
+ $encodedCharPos = strpos($lastChunk, "=");
+
+ if ($encodedCharPos !== false) {
+ // Found start of encoded character byte within $lookBack block.
+ // Check the encoded byte value (the 2 chars after the '=')
+ $hex = substr($encodedText, $maxLength - $lookBack + $encodedCharPos + 1, 2);
+ $dec = hexdec($hex);
+ if ($dec < 128)
+ {
+ // Single byte character.
+
+ // If the encoded char was found at pos 0, it will fit
+ // otherwise reduce maxLength to start of the encoded char
+ $maxLength = ($encodedCharPos == 0) ? $maxLength :
+ $maxLength - ($lookBack - $encodedCharPos);
+ $foundSplitPos = true;
+ }
+ elseif ($dec >= 192)
+ {
+ // First byte of a multi byte character
+
+ // Reduce maxLength to split at start of character
+ $maxLength = $maxLength - ($lookBack - $encodedCharPos);
+ $foundSplitPos = true;
+ }
+ elseif ($dec < 192)
+ {
+ // Middle byte of a multi byte character, look further back
+ $lookBack += 3;
+ }
+ } else {
+ // No encoded character found
+ $foundSplitPos = true;
+ }
+ }
+
+ return $maxLength;
+ }
+
+ /**
+ * Set the body wrapping.
+ * @access private
+ * @return void
+ */
+ function SetWordWrap() {
+ if($this->WordWrap < 1) {
+ return;
+ }
+
+ switch($this->message_type) {
+ case 'alt':
+ /* fall through */
+ case 'alt_attachments':
+ $this->AltBody = $this->WrapText($this->AltBody, $this->WordWrap);
+ break;
+ default:
+ $this->Body = $this->WrapText($this->Body, $this->WordWrap);
+ break;
+ }
+ }
+
+ /**
+ * Assembles message header.
+ * @access private
+ * @return string
+ */
+ function CreateHeader() {
+ $result = '';
+
+ /* Set the boundaries */
+ $uniq_id = md5(uniqid(time()));
+ $this->boundary[1] = 'b1_' . $uniq_id;
+ $this->boundary[2] = 'b2_' . $uniq_id;
+
+ $result .= $this->HeaderLine('Date', $this->RFCDate());
+ if($this->Sender == '') {
+ $result .= $this->HeaderLine('Return-Path', trim($this->From));
+ } else {
+ $result .= $this->HeaderLine('Return-Path', trim($this->Sender));
+ }
+
+ /* To be created automatically by mail() */
+ if($this->Mailer != 'mail') {
+ if(count($this->to) > 0) {
+ $result .= $this->AddrAppend('To', $this->to);
+ } elseif (count($this->cc) == 0) {
+ $result .= $this->HeaderLine('To', 'undisclosed-recipients:;');
+ }
+ if(count($this->cc) > 0) {
+ $result .= $this->AddrAppend('Cc', $this->cc);
+ }
+ }
+
+ $from = array();
+ $from[0][0] = trim($this->From);
+ $from[0][1] = $this->FromName;
+ $result .= $this->AddrAppend('From', $from);
+
+ /* sendmail and mail() extract Cc from the header before sending */
+ if((($this->Mailer == 'sendmail') || ($this->Mailer == 'mail')) && (count($this->cc) > 0)) {
+ $result .= $this->AddrAppend('Cc', $this->cc);
+ }
+
+ /* sendmail and mail() extract Bcc from the header before sending */
+ if((($this->Mailer == 'sendmail') || ($this->Mailer == 'mail')) && (count($this->bcc) > 0)) {
+ $result .= $this->AddrAppend('Bcc', $this->bcc);
+ }
+
+ if(count($this->ReplyTo) > 0) {
+ $result .= $this->AddrAppend('Reply-To', $this->ReplyTo);
+ }
+
+ /* mail() sets the subject itself */
+ if($this->Mailer != 'mail') {
+ $result .= $this->HeaderLine('Subject', $this->EncodeHeader($this->SecureHeader($this->Subject)));
+ }
+
+ $result .= sprintf("Message-ID: <%s@%s>%s", $uniq_id, $this->ServerHostname(), $this->LE);
+ $result .= $this->HeaderLine('X-Priority', $this->Priority);
+ $result .= $this->HeaderLine('X-Mailer', 'PHPMailer (phpmailer.sourceforge.net) [version ' . $this->Version . ']');
+
+ if($this->ConfirmReadingTo != '') {
+ $result .= $this->HeaderLine('Disposition-Notification-To', '<' . trim($this->ConfirmReadingTo) . '>');
+ }
+
+ // Add custom headers
+ for($index = 0; $index < count($this->CustomHeader); $index++) {
+ $result .= $this->HeaderLine(trim($this->CustomHeader[$index][0]), $this->EncodeHeader(trim($this->CustomHeader[$index][1])));
+ }
+ $result .= $this->HeaderLine('MIME-Version', '1.0');
+
+ switch($this->message_type) {
+ case 'plain':
+ $result .= $this->HeaderLine('Content-Transfer-Encoding', $this->Encoding);
+ $result .= sprintf("Content-Type: %s; charset=\"%s\"", $this->ContentType, $this->CharSet);
+ break;
+ case 'attachments':
+ /* fall through */
+ case 'alt_attachments':
+ if($this->InlineImageExists()){
+ $result .= sprintf("Content-Type: %s;%s\ttype=\"text/html\";%s\tboundary=\"%s\"%s", 'multipart/related', $this->LE, $this->LE, $this->boundary[1], $this->LE);
+ } else {
+ $result .= $this->HeaderLine('Content-Type', 'multipart/mixed;');
+ $result .= $this->TextLine("\tboundary=\"" . $this->boundary[1] . '"');
+ }
+ break;
+ case 'alt':
+ $result .= $this->HeaderLine('Content-Type', 'multipart/alternative;');
+ $result .= $this->TextLine("\tboundary=\"" . $this->boundary[1] . '"');
+ break;
+ }
+
+ if($this->Mailer != 'mail') {
+ $result .= $this->LE.$this->LE;
+ }
+
+ return $result;
+ }
+
+ /**
+ * Assembles the message body. Returns an empty string on failure.
+ * @access private
+ * @return string
+ */
+ function CreateBody() {
+ $result = '';
+
+ $this->SetWordWrap();
+
+ switch($this->message_type) {
+ case 'alt':
+ $result .= $this->GetBoundary($this->boundary[1], '', 'text/plain', '');
+ $result .= $this->EncodeString($this->AltBody, $this->Encoding);
+ $result .= $this->LE.$this->LE;
+ $result .= $this->GetBoundary($this->boundary[1], '', 'text/html', '');
+ $result .= $this->EncodeString($this->Body, $this->Encoding);
+ $result .= $this->LE.$this->LE;
+ $result .= $this->EndBoundary($this->boundary[1]);
+ break;
+ case 'plain':
+ $result .= $this->EncodeString($this->Body, $this->Encoding);
+ break;
+ case 'attachments':
+ $result .= $this->GetBoundary($this->boundary[1], '', '', '');
+ $result .= $this->EncodeString($this->Body, $this->Encoding);
+ $result .= $this->LE;
+ $result .= $this->AttachAll();
+ break;
+ case 'alt_attachments':
+ $result .= sprintf("--%s%s", $this->boundary[1], $this->LE);
+ $result .= sprintf("Content-Type: %s;%s" . "\tboundary=\"%s\"%s", 'multipart/alternative', $this->LE, $this->boundary[2], $this->LE.$this->LE);
+ $result .= $this->GetBoundary($this->boundary[2], '', 'text/plain', '') . $this->LE; // Create text body
+ $result .= $this->EncodeString($this->AltBody, $this->Encoding);
+ $result .= $this->LE.$this->LE;
+ $result .= $this->GetBoundary($this->boundary[2], '', 'text/html', '') . $this->LE; // Create the HTML body
+ $result .= $this->EncodeString($this->Body, $this->Encoding);
+ $result .= $this->LE.$this->LE;
+ $result .= $this->EndBoundary($this->boundary[2]);
+ $result .= $this->AttachAll();
+ break;
+ }
+ if($this->IsError()) {
+ $result = '';
+ }
+
+ return $result;
+ }
+
+ /**
+ * Returns the start of a message boundary.
+ * @access private
+ */
+ function GetBoundary($boundary, $charSet, $contentType, $encoding) {
+ $result = '';
+ if($charSet == '') {
+ $charSet = $this->CharSet;
+ }
+ if($contentType == '') {
+ $contentType = $this->ContentType;
+ }
+ if($encoding == '') {
+ $encoding = $this->Encoding;
+ }
+ $result .= $this->TextLine('--' . $boundary);
+ $result .= sprintf("Content-Type: %s; charset = \"%s\"", $contentType, $charSet);
+ $result .= $this->LE;
+ $result .= $this->HeaderLine('Content-Transfer-Encoding', $encoding);
+ $result .= $this->LE;
+
+ return $result;
+ }
+
+ /**
+ * Returns the end of a message boundary.
+ * @access private
+ */
+ function EndBoundary($boundary) {
+ return $this->LE . '--' . $boundary . '--' . $this->LE;
+ }
+
+ /**
+ * Sets the message type.
+ * @access private
+ * @return void
+ */
+ function SetMessageType() {
+ if(count($this->attachment) < 1 && strlen($this->AltBody) < 1) {
+ $this->message_type = 'plain';
+ } else {
+ if(count($this->attachment) > 0) {
+ $this->message_type = 'attachments';
+ }
+ if(strlen($this->AltBody) > 0 && count($this->attachment) < 1) {
+ $this->message_type = 'alt';
+ }
+ if(strlen($this->AltBody) > 0 && count($this->attachment) > 0) {
+ $this->message_type = 'alt_attachments';
+ }
+ }
+ }
+
+ /* Returns a formatted header line.
+ * @access private
+ * @return string
+ */
+ function HeaderLine($name, $value) {
+ return $name . ': ' . $value . $this->LE;
+ }
+
+ /**
+ * Returns a formatted mail line.
+ * @access private
+ * @return string
+ */
+ function TextLine($value) {
+ return $value . $this->LE;
+ }
+
+ /////////////////////////////////////////////////
+ // CLASS METHODS, ATTACHMENTS
+ /////////////////////////////////////////////////
+
+ /**
+ * Adds an attachment from a path on the filesystem.
+ * Returns false if the file could not be found
+ * or accessed.
+ * @param string $path Path to the attachment.
+ * @param string $name Overrides the attachment name.
+ * @param string $encoding File encoding (see $Encoding).
+ * @param string $type File extension (MIME) type.
+ * @return bool
+ */
+ function AddAttachment($path, $name = '', $encoding = 'base64', $type = 'application/octet-stream') {
+ if(!@is_file($path)) {
+ $this->SetError($this->Lang('file_access') . $path);
+ return false;
+ }
+
+ $filename = basename($path);
+ if($name == '') {
+ $name = $filename;
+ }
+
+ $cur = count($this->attachment);
+ $this->attachment[$cur][0] = $path;
+ $this->attachment[$cur][1] = $filename;
+ $this->attachment[$cur][2] = $name;
+ $this->attachment[$cur][3] = $encoding;
+ $this->attachment[$cur][4] = $type;
+ $this->attachment[$cur][5] = false; // isStringAttachment
+ $this->attachment[$cur][6] = 'attachment';
+ $this->attachment[$cur][7] = 0;
+
+ return true;
+ }
+
+ /**
+ * Attaches all fs, string, and binary attachments to the message.
+ * Returns an empty string on failure.
+ * @access private
+ * @return string
+ */
+ function AttachAll() {
+ /* Return text of body */
+ $mime = array();
+
+ /* Add all attachments */
+ for($i = 0; $i < count($this->attachment); $i++) {
+ /* Check for string attachment */
+ $bString = $this->attachment[$i][5];
+ if ($bString) {
+ $string = $this->attachment[$i][0];
+ } else {
+ $path = $this->attachment[$i][0];
+ }
+
+ $filename = $this->attachment[$i][1];
+ $name = $this->attachment[$i][2];
+ $encoding = $this->attachment[$i][3];
+ $type = $this->attachment[$i][4];
+ $disposition = $this->attachment[$i][6];
+ $cid = $this->attachment[$i][7];
+
+ $mime[] = sprintf("--%s%s", $this->boundary[1], $this->LE);
+ $mime[] = sprintf("Content-Type: %s; name=\"%s\"%s", $type, $name, $this->LE);
+ $mime[] = sprintf("Content-Transfer-Encoding: %s%s", $encoding, $this->LE);
+
+ if($disposition == 'inline') {
+ $mime[] = sprintf("Content-ID: <%s>%s", $cid, $this->LE);
+ }
+
+ $mime[] = sprintf("Content-Disposition: %s; filename=\"%s\"%s", $disposition, $name, $this->LE.$this->LE);
+
+ /* Encode as string attachment */
+ if($bString) {
+ $mime[] = $this->EncodeString($string, $encoding);
+ if($this->IsError()) {
+ return '';
+ }
+ $mime[] = $this->LE.$this->LE;
+ } else {
+ $mime[] = $this->EncodeFile($path, $encoding);
+ if($this->IsError()) {
+ return '';
+ }
+ $mime[] = $this->LE.$this->LE;
+ }
+ }
+
+ $mime[] = sprintf("--%s--%s", $this->boundary[1], $this->LE);
+
+ return join('', $mime);
+ }
+
+ /**
+ * Encodes attachment in requested format. Returns an
+ * empty string on failure.
+ * @access private
+ * @return string
+ */
+ function EncodeFile ($path, $encoding = 'base64') {
+ if(!@$fd = fopen($path, 'rb')) {
+ $this->SetError($this->Lang('file_open') . $path);
+ return '';
+ }
+ $magic_quotes = get_magic_quotes_runtime();
+ set_magic_quotes_runtime(0);
+ $file_buffer = fread($fd, filesize($path));
+ $file_buffer = $this->EncodeString($file_buffer, $encoding);
+ fclose($fd);
+ set_magic_quotes_runtime($magic_quotes);
+
+ return $file_buffer;
+ }
+
+ /**
+ * Encodes string to requested format. Returns an
+ * empty string on failure.
+ * @access private
+ * @return string
+ */
+ function EncodeString ($str, $encoding = 'base64') {
+ $encoded = '';
+ switch(strtolower($encoding)) {
+ case 'base64':
+ /* chunk_split is found in PHP >= 3.0.6 */
+ $encoded = chunk_split(base64_encode($str), 76, $this->LE);
+ break;
+ case '7bit':
+ case '8bit':
+ $encoded = $this->FixEOL($str);
+ if (substr($encoded, -(strlen($this->LE))) != $this->LE)
+ $encoded .= $this->LE;
+ break;
+ case 'binary':
+ $encoded = $str;
+ break;
+ case 'quoted-printable':
+ $encoded = $this->EncodeQP($str);
+ break;
+ default:
+ $this->SetError($this->Lang('encoding') . $encoding);
+ break;
+ }
+ return $encoded;
+ }
+
+ /**
+ * Encode a header string to best of Q, B, quoted or none.
+ * @access private
+ * @return string
+ */
+ function EncodeHeader ($str, $position = 'text') {
+ $x = 0;
+
+ switch (strtolower($position)) {
+ case 'phrase':
+ if (!preg_match('/[\200-\377]/', $str)) {
+ /* Can't use addslashes as we don't know what value has magic_quotes_sybase. */
+ $encoded = addcslashes($str, "\0..\37\177\\\"");
+ if (($str == $encoded) && !preg_match('/[^A-Za-z0-9!#$%&\'*+\/=?^_`{|}~ -]/', $str)) {
+ return ($encoded);
+ } else {
+ return ("\"$encoded\"");
+ }
+ }
+ $x = preg_match_all('/[^\040\041\043-\133\135-\176]/', $str, $matches);
+ break;
+ case 'comment':
+ $x = preg_match_all('/[()"]/', $str, $matches);
+ /* Fall-through */
+ case 'text':
+ default:
+ $x += preg_match_all('/[\000-\010\013\014\016-\037\177-\377]/', $str, $matches);
+ break;
+ }
+
+ if ($x == 0) {
+ return ($str);
+ }
+
+ $maxlen = 75 - 7 - strlen($this->CharSet);
+ /* Try to select the encoding which should produce the shortest output */
+ if (strlen($str)/3 < $x) {
+ $encoding = 'B';
+ if (function_exists('mb_strlen') && $this->HasMultiBytes($str)) {
+ // Use a custom function which correctly encodes and wraps long
+ // multibyte strings without breaking lines within a character
+ $encoded = $this->Base64EncodeWrapMB($str);
+ } else {
+ $encoded = base64_encode($str);
+ $maxlen -= $maxlen % 4;
+ $encoded = trim(chunk_split($encoded, $maxlen, "\n"));
+ }
+ } else {
+ $encoding = 'Q';
+ $encoded = $this->EncodeQ($str, $position);
+ $encoded = $this->WrapText($encoded, $maxlen, true);
+ $encoded = str_replace('='.$this->LE, "\n", trim($encoded));
+ }
+
+ $encoded = preg_replace('/^(.*)$/m', " =?".$this->CharSet."?$encoding?\\1?=", $encoded);
+ $encoded = trim(str_replace("\n", $this->LE, $encoded));
+
+ return $encoded;
+ }
+
+ /**
+ * Checks if a string contains multibyte characters.
+ *
+ * @access private
+ *
+ * @param string $str multi-byte text to wrap encode
+ *
+ * @return bool
+ */
+ function HasMultiBytes($str)
+ {
+ if (function_exists('mb_strlen')) {
+ return (strlen($str) > mb_strlen($str, $this->CharSet));
+ } else {
+ // Assume no multibytes (we can't handle without mbstring functions anyway)
+ return False;
+ }
+ }
+
+ /**
+ * Correctly encodes and wraps long multibyte strings for mail headers
+ * without breaking lines within a character.
+ *
+ * Adapted from a function by paravoid at http://uk.php.net/manual/en/function.mb-encode-mimeheader.php
+ *
+ * @access private
+ *
+ * @param string $str multi-byte text to wrap encode
+ *
+ * @return string
+ */
+ function Base64EncodeWrapMB($str)
+ {
+ $start = "=?".$this->CharSet."?B?";
+ $end = "?=";
+ $encoded = "";
+
+ $mb_length = mb_strlen($str, $this->CharSet);
+ // Each line must have length <= 75, including $start and $end
+ $length = 75 - strlen($start) - strlen($end);
+ // Average multi-byte ratio
+ $ratio = $mb_length / strlen($str);
+ // Base64 has a 4:3 ratio
+ $offset = $avgLength = floor($length * $ratio * .75);
+
+ for ($i = 0; $i < $mb_length; $i += $offset)
+ {
+ $lookBack = 0;
+
+ do {
+ $offset = $avgLength - $lookBack;
+ $chunk = mb_substr($str, $i, $offset, $this->CharSet);
+ $chunk = base64_encode($chunk);
+ $lookBack++;
+ }
+ while (strlen($chunk) > $length);
+
+ $encoded .= $chunk . $this->LE;
+ }
+
+ // Chomp the last linefeed
+ $encoded = substr($encoded, 0, -strlen($this->LE));
+
+ return $encoded;
+ }
+
+ /**
+ * Encode string to quoted-printable.
+ * @access private
+ * @return string
+ */
+ function EncodeQP( $input = '', $line_max = 76, $space_conv = false ) {
+ $hex = array('0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F');
+ $lines = preg_split('/(?:\r\n|\r|\n)/', $input);
+ $eol = "\r\n";
+ $escape = '=';
+ $output = '';
+ while( list(, $line) = each($lines) ) {
+ $linlen = strlen($line);
+ $newline = '';
+ for($i = 0; $i < $linlen; $i++) {
+ $c = substr( $line, $i, 1 );
+ $dec = ord( $c );
+ if ( ( $i == 0 ) && ( $dec == 46 ) ) { // convert first point in the line into =2E
+ $c = '=2E';
+ }
+ if ( $dec == 32 ) {
+ if ( $i == ( $linlen - 1 ) ) { // convert space at eol only
+ $c = '=20';
+ } else if ( $space_conv ) {
+ $c = '=20';
+ }
+ } elseif ( ($dec == 61) || ($dec < 32 ) || ($dec > 126) ) { // always encode "\t", which is *not* required
+ $h2 = floor($dec/16);
+ $h1 = floor($dec%16);
+ $c = $escape.$hex[$h2].$hex[$h1];
+ }
+ if ( (strlen($newline) + strlen($c)) >= $line_max ) { // CRLF is not counted
+ $output .= $newline.$escape.$eol; // soft line break; " =\r\n" is okay
+ $newline = '';
+ // check if newline first character will be point or not
+ if ( $dec == 46 ) {
+ $c = '=2E';
+ }
+ }
+ $newline .= $c;
+ } // end of for
+ $output .= $newline.$eol;
+ } // end of while
+ return trim($output);
+ }
+
+ /**
+ * Encode string to q encoding.
+ * @access private
+ * @return string
+ */
+ function EncodeQ ($str, $position = 'text') {
+ /* There should not be any EOL in the string */
+ $encoded = preg_replace("[\r\n]", '', $str);
+
+ switch (strtolower($position)) {
+ case 'phrase':
+ $encoded = preg_replace("/([^A-Za-z0-9!*+\/ -])/e", "'='.sprintf('%02X', ord('\\1'))", $encoded);
+ break;
+ case 'comment':
+ $encoded = preg_replace("/([\(\)\"])/e", "'='.sprintf('%02X', ord('\\1'))", $encoded);
+ case 'text':
+ default:
+ /* Replace every high ascii, control =, ? and _ characters */
+ $encoded = preg_replace('/([\000-\011\013\014\016-\037\075\077\137\177-\377])/e',
+ "'='.sprintf('%02X', ord('\\1'))", $encoded);
+ break;
+ }
+
+ /* Replace every spaces to _ (more readable than =20) */
+ $encoded = str_replace(' ', '_', $encoded);
+
+ return $encoded;
+ }
+
+ /**
+ * Adds a string or binary attachment (non-filesystem) to the list.
+ * This method can be used to attach ascii or binary data,
+ * such as a BLOB record from a database.
+ * @param string $string String attachment data.
+ * @param string $filename Name of the attachment.
+ * @param string $encoding File encoding (see $Encoding).
+ * @param string $type File extension (MIME) type.
+ * @return void
+ */
+ function AddStringAttachment($string, $filename, $encoding = 'base64', $type = 'application/octet-stream') {
+ /* Append to $attachment array */
+ $cur = count($this->attachment);
+ $this->attachment[$cur][0] = $string;
+ $this->attachment[$cur][1] = $filename;
+ $this->attachment[$cur][2] = $filename;
+ $this->attachment[$cur][3] = $encoding;
+ $this->attachment[$cur][4] = $type;
+ $this->attachment[$cur][5] = true; // isString
+ $this->attachment[$cur][6] = 'attachment';
+ $this->attachment[$cur][7] = 0;
+ }
+
+ /**
+ * Adds an embedded attachment. This can include images, sounds, and
+ * just about any other document. Make sure to set the $type to an
+ * image type. For JPEG images use "image/jpeg" and for GIF images
+ * use "image/gif".
+ * @param string $path Path to the attachment.
+ * @param string $cid Content ID of the attachment. Use this to identify
+ * the Id for accessing the image in an HTML form.
+ * @param string $name Overrides the attachment name.
+ * @param string $encoding File encoding (see $Encoding).
+ * @param string $type File extension (MIME) type.
+ * @return bool
+ */
+ function AddEmbeddedImage($path, $cid, $name = '', $encoding = 'base64', $type = 'application/octet-stream') {
+
+ if(!@is_file($path)) {
+ $this->SetError($this->Lang('file_access') . $path);
+ return false;
+ }
+
+ $filename = basename($path);
+ if($name == '') {
+ $name = $filename;
+ }
+
+ /* Append to $attachment array */
+ $cur = count($this->attachment);
+ $this->attachment[$cur][0] = $path;
+ $this->attachment[$cur][1] = $filename;
+ $this->attachment[$cur][2] = $name;
+ $this->attachment[$cur][3] = $encoding;
+ $this->attachment[$cur][4] = $type;
+ $this->attachment[$cur][5] = false;
+ $this->attachment[$cur][6] = 'inline';
+ $this->attachment[$cur][7] = $cid;
+
+ return true;
+ }
+
+ /**
+ * Returns true if an inline attachment is present.
+ * @access private
+ * @return bool
+ */
+ function InlineImageExists() {
+ $result = false;
+ for($i = 0; $i < count($this->attachment); $i++) {
+ if($this->attachment[$i][6] == 'inline') {
+ $result = true;
+ break;
+ }
+ }
+
+ return $result;
+ }
+
+ /////////////////////////////////////////////////
+ // CLASS METHODS, MESSAGE RESET
+ /////////////////////////////////////////////////
+
+ /**
+ * Clears all recipients assigned in the TO array. Returns void.
+ * @return void
+ */
+ function ClearAddresses() {
+ $this->to = array();
+ }
+
+ /**
+ * Clears all recipients assigned in the CC array. Returns void.
+ * @return void
+ */
+ function ClearCCs() {
+ $this->cc = array();
+ }
+
+ /**
+ * Clears all recipients assigned in the BCC array. Returns void.
+ * @return void
+ */
+ function ClearBCCs() {
+ $this->bcc = array();
+ }
+
+ /**
+ * Clears all recipients assigned in the ReplyTo array. Returns void.
+ * @return void
+ */
+ function ClearReplyTos() {
+ $this->ReplyTo = array();
+ }
+
+ /**
+ * Clears all recipients assigned in the TO, CC and BCC
+ * array. Returns void.
+ * @return void
+ */
+ function ClearAllRecipients() {
+ $this->to = array();
+ $this->cc = array();
+ $this->bcc = array();
+ }
+
+ /**
+ * Clears all previously set filesystem, string, and binary
+ * attachments. Returns void.
+ * @return void
+ */
+ function ClearAttachments() {
+ $this->attachment = array();
+ }
+
+ /**
+ * Clears all custom headers. Returns void.
+ * @return void
+ */
+ function ClearCustomHeaders() {
+ $this->CustomHeader = array();
+ }
+
+ /////////////////////////////////////////////////
+ // CLASS METHODS, MISCELLANEOUS
+ /////////////////////////////////////////////////
+
+ /**
+ * Adds the error message to the error container.
+ * Returns void.
+ * @access private
+ * @return void
+ */
+ function SetError($msg) {
+ $this->error_count++;
+ $this->ErrorInfo = $msg;
+ }
+
+ /**
+ * Returns the proper RFC 822 formatted date.
+ * @access private
+ * @return string
+ */
+ function RFCDate() {
+ $tz = date('Z');
+ $tzs = ($tz < 0) ? '-' : '+';
+ $tz = abs($tz);
+ $tz = (int)($tz/3600)*100 + ($tz%3600)/60;
+ $result = sprintf("%s %s%04d", date('D, j M Y H:i:s'), $tzs, $tz);
+
+ return $result;
+ }
+
+ /**
+ * Returns the appropriate server variable. Should work with both
+ * PHP 4.1.0+ as well as older versions. Returns an empty string
+ * if nothing is found.
+ * @access private
+ * @return mixed
+ */
+ function ServerVar($varName) {
+ global $HTTP_SERVER_VARS;
+ global $HTTP_ENV_VARS;
+
+ if(!isset($_SERVER)) {
+ $_SERVER = $HTTP_SERVER_VARS;
+ if(!isset($_SERVER['REMOTE_ADDR'])) {
+ $_SERVER = $HTTP_ENV_VARS; // must be Apache
+ }
+ }
+
+ if(isset($_SERVER[$varName])) {
+ return $_SERVER[$varName];
+ } else {
+ return '';
+ }
+ }
+
+ /**
+ * Returns the server hostname or 'localhost.localdomain' if unknown.
+ * @access private
+ * @return string
+ */
+ function ServerHostname() {
+ if ($this->Hostname != '') {
+ $result = $this->Hostname;
+ } elseif ($this->ServerVar('SERVER_NAME') != '') {
+ $result = $this->ServerVar('SERVER_NAME');
+ } else {
+ $result = 'localhost.localdomain';
+ }
+
+ return $result;
+ }
+
+ /**
+ * Returns a message in the appropriate language.
+ * @access private
+ * @return string
+ */
+ function Lang($key) {
+ if(count($this->language) < 1) {
+ $this->SetLanguage('en'); // set the default language
+ }
+
+ if(isset($this->language[$key])) {
+ return $this->language[$key];
+ } else {
+ return 'Language string failed to load: ' . $key;
+ }
+ }
+
+ /**
+ * Returns true if an error occurred.
+ * @return bool
+ */
+ function IsError() {
+ return ($this->error_count > 0);
+ }
+
+ /**
+ * Changes every end of line from CR or LF to CRLF.
+ * @access private
+ * @return string
+ */
+ function FixEOL($str) {
+ $str = str_replace("\r\n", "\n", $str);
+ $str = str_replace("\r", "\n", $str);
+ $str = str_replace("\n", $this->LE, $str);
+ return $str;
+ }
+
+ /**
+ * Adds a custom header.
+ * @return void
+ */
+ function AddCustomHeader($custom_header) {
+ $this->CustomHeader[] = explode(':', $custom_header, 2);
+ }
+
+ /**
+ * Evaluates the message and returns modifications for inline images and backgrounds
+ * @access public
+ * @return $message
+ */
+ function MsgHTML($message) {
+ preg_match_all("/(src|background)=\"(.*)\"/Ui", $message, $images);
+ if(isset($images[2])) {
+ foreach($images[2] as $i => $url) {
+ $filename = basename($url);
+ $directory = dirname($url);
+ $cid = 'cid:' . md5($filename);
+ $fileParts = split("\.", $filename);
+ $ext = $fileParts[1];
+ $mimeType = $this->_mime_types($ext);
+ $message = preg_replace("/".$images[1][$i]."=\"".preg_quote($url, '/')."\"/Ui", $images[1][$i]."=\"".$cid."\"", $message);
+ $this->AddEmbeddedImage($url, md5($filename), $filename, 'base64', $mimeType);
+ }
+ }
+ $this->IsHTML(true);
+ $this->Body = $message;
+ $textMsg = trim(strip_tags($message));
+ if ( !empty($textMsg) && empty($this->AltBody) ) {
+ $this->AltBody = $textMsg;
+ }
+ if ( empty($this->AltBody) ) {
+ $this->AltBody = 'To view this email message, open the email in with HTML compatibility!' . "\n\n";
+ }
+ }
+
+ /**
+ * Gets the mime type of the embedded or inline image
+ * @access private
+ * @return mime type of ext
+ */
+ function _mime_types($ext = '') {
+ $mimes = array(
+ 'hqx' => 'application/mac-binhex40',
+ 'cpt' => 'application/mac-compactpro',
+ 'doc' => 'application/msword',
+ 'bin' => 'application/macbinary',
+ 'dms' => 'application/octet-stream',
+ 'lha' => 'application/octet-stream',
+ 'lzh' => 'application/octet-stream',
+ 'exe' => 'application/octet-stream',
+ 'class' => 'application/octet-stream',
+ 'psd' => 'application/octet-stream',
+ 'so' => 'application/octet-stream',
+ 'sea' => 'application/octet-stream',
+ 'dll' => 'application/octet-stream',
+ 'oda' => 'application/oda',
+ 'pdf' => 'application/pdf',
+ 'ai' => 'application/postscript',
+ 'eps' => 'application/postscript',
+ 'ps' => 'application/postscript',
+ 'smi' => 'application/smil',
+ 'smil' => 'application/smil',
+ 'mif' => 'application/vnd.mif',
+ 'xls' => 'application/vnd.ms-excel',
+ 'ppt' => 'application/vnd.ms-powerpoint',
+ 'wbxml' => 'application/vnd.wap.wbxml',
+ 'wmlc' => 'application/vnd.wap.wmlc',
+ 'dcr' => 'application/x-director',
+ 'dir' => 'application/x-director',
+ 'dxr' => 'application/x-director',
+ 'dvi' => 'application/x-dvi',
+ 'gtar' => 'application/x-gtar',
+ 'php' => 'application/x-httpd-php',
+ 'php4' => 'application/x-httpd-php',
+ 'php3' => 'application/x-httpd-php',
+ 'phtml' => 'application/x-httpd-php',
+ 'phps' => 'application/x-httpd-php-source',
+ 'js' => 'application/x-javascript',
+ 'swf' => 'application/x-shockwave-flash',
+ 'sit' => 'application/x-stuffit',
+ 'tar' => 'application/x-tar',
+ 'tgz' => 'application/x-tar',
+ 'xhtml' => 'application/xhtml+xml',
+ 'xht' => 'application/xhtml+xml',
+ 'zip' => 'application/zip',
+ 'mid' => 'audio/midi',
+ 'midi' => 'audio/midi',
+ 'mpga' => 'audio/mpeg',
+ 'mp2' => 'audio/mpeg',
+ 'mp3' => 'audio/mpeg',
+ 'aif' => 'audio/x-aiff',
+ 'aiff' => 'audio/x-aiff',
+ 'aifc' => 'audio/x-aiff',
+ 'ram' => 'audio/x-pn-realaudio',
+ 'rm' => 'audio/x-pn-realaudio',
+ 'rpm' => 'audio/x-pn-realaudio-plugin',
+ 'ra' => 'audio/x-realaudio',
+ 'rv' => 'video/vnd.rn-realvideo',
+ 'wav' => 'audio/x-wav',
+ 'bmp' => 'image/bmp',
+ 'gif' => 'image/gif',
+ 'jpeg' => 'image/jpeg',
+ 'jpg' => 'image/jpeg',
+ 'jpe' => 'image/jpeg',
+ 'png' => 'image/png',
+ 'tiff' => 'image/tiff',
+ 'tif' => 'image/tiff',
+ 'css' => 'text/css',
+ 'html' => 'text/html',
+ 'htm' => 'text/html',
+ 'shtml' => 'text/html',
+ 'txt' => 'text/plain',
+ 'text' => 'text/plain',
+ 'log' => 'text/plain',
+ 'rtx' => 'text/richtext',
+ 'rtf' => 'text/rtf',
+ 'xml' => 'text/xml',
+ 'xsl' => 'text/xml',
+ 'mpeg' => 'video/mpeg',
+ 'mpg' => 'video/mpeg',
+ 'mpe' => 'video/mpeg',
+ 'qt' => 'video/quicktime',
+ 'mov' => 'video/quicktime',
+ 'avi' => 'video/x-msvideo',
+ 'movie' => 'video/x-sgi-movie',
+ 'doc' => 'application/msword',
+ 'word' => 'application/msword',
+ 'xl' => 'application/excel',
+ 'eml' => 'message/rfc822'
+ );
+ return ( ! isset($mimes[strtolower($ext)])) ? 'application/x-unknown-content-type' : $mimes[strtolower($ext)];
+ }
+
+ /**
+ * Set (or reset) Class Objects (variables)
+ *
+ * Usage Example:
+ * $page->set('X-Priority', '3');
+ *
+ * @access public
+ * @param string $name Parameter Name
+ * @param mixed $value Parameter Value
+ * NOTE: will not work with arrays, there are no arrays to set/reset
+ */
+ function set ( $name, $value = '' ) {
+ if ( isset($this->$name) ) {
+ $this->$name = $value;
+ } else {
+ $this->SetError('Cannot set or reset variable ' . $name);
+ return false;
+ }
+ }
+
+ /**
+ * Read a file from a supplied filename and return it.
+ *
+ * @access public
+ * @param string $filename Parameter File Name
+ */
+ function getFile($filename) {
+ $return = '';
+ if ($fp = fopen($filename, 'rb')) {
+ while (!feof($fp)) {
+ $return .= fread($fp, 1024);
+ }
+ fclose($fp);
+ return $return;
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Strips newlines to prevent header injection.
+ * @access private
+ * @param string $str String
+ * @return string
+ */
+ function SecureHeader($str) {
+ $str = trim($str);
+ $str = str_replace("\r", "", $str);
+ $str = str_replace("\n", "", $str);
+ return $str;
+ }
+
+}
+
+?>
diff --git a/site/vendors/phpmailer/class.pop3.php b/site/vendors/phpmailer/class.pop3.php
new file mode 100644
index 0000000..af1e63b
--- /dev/null
+++ b/site/vendors/phpmailer/class.pop3.php
@@ -0,0 +1,437 @@
+<?php
+/*~ class.pop3.php
+.---------------------------------------------------------------------------.
+| Software: PHPMailer - PHP email class |
+| Version: 2.0.0 rc2 |
+| Contact: via sourceforge.net support pages (also www.codeworxtech.com) |
+| Info: http://phpmailer.sourceforge.net |
+| Support: http://sourceforge.net/projects/phpmailer/ |
+| ------------------------------------------------------------------------- |
+| Author: Andy Prevost (project admininistrator) |
+| Author: Brent R. Matzelle (original founder) |
+| Copyright (c) 2004-2007, Andy Prevost. All Rights Reserved. |
+| Copyright (c) 2001-2003, Brent R. Matzelle |
+| ------------------------------------------------------------------------- |
+| License: Distributed under the Lesser General Public License (LGPL) |
+| http://www.gnu.org/copyleft/lesser.html |
+| This program is distributed in the hope that it will be useful - WITHOUT |
+| ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
+| FITNESS FOR A PARTICULAR PURPOSE. |
+| ------------------------------------------------------------------------- |
+| We offer a number of paid services (www.codeworxtech.com): |
+| - Web Hosting on highly optimized fast and secure servers |
+| - Technology Consulting |
+| - Oursourcing (highly qualified programmers and graphic designers) |
+'---------------------------------------------------------------------------'
+
+/**
+ * POP Before SMTP Authentication Class
+ * Version 1.0
+ *
+ * Author: Richard Davey (rich@corephp.co.uk)
+ * License: LGPL, see PHPMailer License
+ *
+ * Specifically for PHPMailer to allow POP before SMTP authentication.
+ * Does not yet work with APOP - if you have an APOP account, contact me
+ * and we can test changes to this script.
+ *
+ * This class is based on the structure of the SMTP class by Chris Ryan
+ *
+ * This class is rfc 1939 compliant and implements all the commands
+ * required for POP3 connection, authentication and disconnection.
+ *
+ * @package PHPMailer
+ * @author Richard Davey
+ */
+
+class POP3
+{
+ /**
+ * Default POP3 port
+ * @var int
+ */
+ var $POP3_PORT = 110;
+
+ /**
+ * Default Timeout
+ * @var int
+ */
+ var $POP3_TIMEOUT = 30;
+
+ /**
+ * POP3 Carriage Return + Line Feed
+ * @var string
+ */
+ var $CRLF = "\r\n";
+
+ /**
+ * Displaying Debug warnings? (0 = now, 1+ = yes)
+ * @var int
+ */
+ var $do_debug = 2;
+
+ /**
+ * POP3 Mail Server
+ * @var string
+ */
+ var $host;
+
+ /**
+ * POP3 Port
+ * @var int
+ */
+ var $port;
+
+ /**
+ * POP3 Timeout Value
+ * @var int
+ */
+ var $tval;
+
+ /**
+ * POP3 Username
+ * @var string
+ */
+ var $username;
+
+ /**
+ * POP3 Password
+ * @var string
+ */
+ var $password;
+
+ /**#@+
+ * @access private
+ */
+ var $pop_conn;
+ var $connected;
+ var $error; // Error log array
+ /**#@-*/
+
+ /**
+ * Constructor, sets the initial values
+ *
+ * @return POP3
+ */
+ function POP3 ()
+ {
+ $this->pop_conn = 0;
+ $this->connected = false;
+ $this->error = null;
+ }
+
+ /**
+ * Combination of public events - connect, login, disconnect
+ *
+ * @param string $host
+ * @param integer $port
+ * @param integer $tval
+ * @param string $username
+ * @param string $password
+ */
+ function Authorise ($host, $port = false, $tval = false, $username, $password, $debug_level = 0)
+ {
+ $this->host = $host;
+
+ // If no port value is passed, retrieve it
+ if ($port == false)
+ {
+ $this->port = $this->POP3_PORT;
+ }
+ else
+ {
+ $this->port = $port;
+ }
+
+ // If no port value is passed, retrieve it
+ if ($tval == false)
+ {
+ $this->tval = $this->POP3_TIMEOUT;
+ }
+ else
+ {
+ $this->tval = $tval;
+ }
+
+ $this->do_debug = $debug_level;
+ $this->username = $username;
+ $this->password = $password;
+
+ // Refresh the error log
+ $this->error = null;
+
+ // Connect
+ $result = $this->Connect($this->host, $this->port, $this->tval);
+
+ if ($result)
+ {
+ $login_result = $this->Login($this->username, $this->password);
+
+ if ($login_result)
+ {
+ $this->Disconnect();
+
+ return true;
+ }
+
+ }
+
+ // We need to disconnect regardless if the login succeeded
+ $this->Disconnect();
+
+ return false;
+ }
+
+ /**
+ * Connect to the POP3 server
+ *
+ * @param string $host
+ * @param integer $port
+ * @param integer $tval
+ * @return boolean
+ */
+ function Connect ($host, $port = false, $tval = 30)
+ {
+ // Are we already connected?
+ if ($this->connected)
+ {
+ return true;
+ }
+
+ /*
+ On Windows this will raise a PHP Warning error if the hostname doesn't exist.
+ Rather than supress it with @fsockopen, let's capture it cleanly instead
+ */
+
+ set_error_handler(array(&$this, 'catchWarning'));
+
+ // Connect to the POP3 server
+ $this->pop_conn = fsockopen($host, // POP3 Host
+ $port, // Port #
+ $errno, // Error Number
+ $errstr, // Error Message
+ $tval); // Timeout (seconds)
+
+ // Restore the error handler
+ restore_error_handler();
+
+ // Does the Error Log now contain anything?
+ if ($this->error && $this->do_debug >= 1)
+ {
+ $this->displayErrors();
+ }
+
+ // Did we connect?
+ if ($this->pop_conn == false)
+ {
+ // It would appear not...
+ $this->error = array(
+ 'error' => "Failed to connect to server $host on port $port",
+ 'errno' => $errno,
+ 'errstr' => $errstr
+ );
+
+ if ($this->do_debug >= 1)
+ {
+ $this->displayErrors();
+ }
+
+ return false;
+ }
+
+ // Increase the stream time-out
+
+ // Check for PHP 4.3.0 or later
+ if (version_compare(phpversion(), '4.3.0', 'ge'))
+ {
+ stream_set_timeout($this->pop_conn, $tval, 0);
+ }
+ else
+ {
+ // Does not work on Windows
+ if (substr(PHP_OS, 0, 3) !== 'WIN')
+ {
+ socket_set_timeout($this->pop_conn, $tval, 0);
+ }
+ }
+
+ // Get the POP3 server response
+ $pop3_response = $this->getResponse();
+
+ // Check for the +OK
+ if ($this->checkResponse($pop3_response))
+ {
+ // The connection is established and the POP3 server is talking
+ $this->connected = true;
+ return true;
+ }
+
+ }
+
+ /**
+ * Login to the POP3 server (does not support APOP yet)
+ *
+ * @param string $username
+ * @param string $password
+ * @return boolean
+ */
+ function Login ($username = '', $password = '')
+ {
+ if ($this->connected == false)
+ {
+ $this->error = 'Not connected to POP3 server';
+
+ if ($this->do_debug >= 1)
+ {
+ $this->displayErrors();
+ }
+ }
+
+ if (empty($username))
+ {
+ $username = $this->username;
+ }
+
+ if (empty($password))
+ {
+ $password = $this->password;
+ }
+
+ $pop_username = "USER $username" . $this->CRLF;
+ $pop_password = "PASS $password" . $this->CRLF;
+
+ // Send the Username
+ $this->sendString($pop_username);
+ $pop3_response = $this->getResponse();
+
+ if ($this->checkResponse($pop3_response))
+ {
+ // Send the Password
+ $this->sendString($pop_password);
+ $pop3_response = $this->getResponse();
+
+ if ($this->checkResponse($pop3_response))
+ {
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ /**
+ * Disconnect from the POP3 server
+ */
+ function Disconnect ()
+ {
+ $this->sendString('QUIT');
+
+ fclose($this->pop_conn);
+ }
+
+ /*
+ ---------------
+ Private Methods
+ ---------------
+ */
+
+ /**
+ * Get the socket response back.
+ * $size is the maximum number of bytes to retrieve
+ *
+ * @param integer $size
+ * @return string
+ */
+ function getResponse ($size = 128)
+ {
+ $pop3_response = fgets($this->pop_conn, $size);
+
+ return $pop3_response;
+ }
+
+ /**
+ * Send a string down the open socket connection to the POP3 server
+ *
+ * @param string $string
+ * @return integer
+ */
+ function sendString ($string)
+ {
+ $bytes_sent = fwrite($this->pop_conn, $string, strlen($string));
+
+ return $bytes_sent;
+
+ }
+
+ /**
+ * Checks the POP3 server response for +OK or -ERR
+ *
+ * @param string $string
+ * @return boolean
+ */
+ function checkResponse ($string)
+ {
+ if (substr($string, 0, 3) !== '+OK')
+ {
+ $this->error = array(
+ 'error' => "Server reported an error: $string",
+ 'errno' => 0,
+ 'errstr' => ''
+ );
+
+ if ($this->do_debug >= 1)
+ {
+ $this->displayErrors();
+ }
+
+ return false;
+ }
+ else
+ {
+ return true;
+ }
+
+ }
+
+ /**
+ * If debug is enabled, display the error message array
+ *
+ */
+ function displayErrors ()
+ {
+ echo '<pre>';
+
+ foreach ($this->error as $single_error)
+ {
+ print_r($single_error);
+ }
+
+ echo '</pre>';
+ }
+
+ /**
+ * Takes over from PHP for the socket warning handler
+ *
+ * @param integer $errno
+ * @param string $errstr
+ * @param string $errfile
+ * @param integer $errline
+ */
+ function catchWarning ($errno, $errstr, $errfile, $errline)
+ {
+ $this->error[] = array(
+ 'error' => "Connecting to the POP3 server raised a PHP warning: ",
+ 'errno' => $errno,
+ 'errstr' => $errstr
+ );
+ }
+
+ // End of class
+}
+?>
diff --git a/site/vendors/phpmailer/class.smtp.php b/site/vendors/phpmailer/class.smtp.php
new file mode 100644
index 0000000..57088b5
--- /dev/null
+++ b/site/vendors/phpmailer/class.smtp.php
@@ -0,0 +1,1062 @@
+<?php
+/*~ class.smtp.php
+.---------------------------------------------------------------------------.
+| Software: PHPMailer - PHP email class |
+| Version: 2.0.0 rc1 |
+| Contact: via sourceforge.net support pages (also www.codeworxtech.com) |
+| Info: http://phpmailer.sourceforge.net |
+| Support: http://sourceforge.net/projects/phpmailer/ |
+| ------------------------------------------------------------------------- |
+| Author: Andy Prevost (project admininistrator) |
+| Author: Brent R. Matzelle (original founder) |
+| Copyright (c) 2004-2007, Andy Prevost. All Rights Reserved. |
+| Copyright (c) 2001-2003, Brent R. Matzelle |
+| ------------------------------------------------------------------------- |
+| License: Distributed under the Lesser General Public License (LGPL) |
+| http://www.gnu.org/copyleft/lesser.html |
+| This program is distributed in the hope that it will be useful - WITHOUT |
+| ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
+| FITNESS FOR A PARTICULAR PURPOSE. |
+| ------------------------------------------------------------------------- |
+| We offer a number of paid services (www.codeworxtech.com): |
+| - Web Hosting on highly optimized fast and secure servers |
+| - Technology Consulting |
+| - Oursourcing (highly qualified programmers and graphic designers) |
+'---------------------------------------------------------------------------'
+
+/**
+ * SMTP is rfc 821 compliant and implements all the rfc 821 SMTP
+ * commands except TURN which will always return a not implemented
+ * error. SMTP also provides some utility methods for sending mail
+ * to an SMTP server.
+ * @package PHPMailer
+ * @author Chris Ryan
+ */
+
+class SMTP
+{
+ /**
+ * SMTP server port
+ * @var int
+ */
+ var $SMTP_PORT = 25;
+
+ /**
+ * SMTP reply line ending
+ * @var string
+ */
+ var $CRLF = "\r\n";
+
+ /**
+ * Sets whether debugging is turned on
+ * @var bool
+ */
+ var $do_debug; # the level of debug to perform
+
+ /**
+ * Sets VERP use on/off (default is off)
+ * @var bool
+ */
+ var $do_verp = false;
+
+ /**#@+
+ * @access private
+ */
+ var $smtp_conn; # the socket to the server
+ var $error; # error if any on the last call
+ var $helo_rply; # the reply the server sent to us for HELO
+ /**#@-*/
+
+ /**
+ * Initialize the class so that the data is in a known state.
+ * @access public
+ * @return void
+ */
+ function SMTP() {
+ $this->smtp_conn = 0;
+ $this->error = null;
+ $this->helo_rply = null;
+
+ $this->do_debug = 0;
+ }
+
+ /*************************************************************
+ * CONNECTION FUNCTIONS *
+ ***********************************************************/
+
+ /**
+ * Connect to the server specified on the port specified.
+ * If the port is not specified use the default SMTP_PORT.
+ * If tval is specified then a connection will try and be
+ * established with the server for that number of seconds.
+ * If tval is not specified the default is 30 seconds to
+ * try on the connection.
+ *
+ * SMTP CODE SUCCESS: 220
+ * SMTP CODE FAILURE: 421
+ * @access public
+ * @return bool
+ */
+ function Connect($host,$port=0,$tval=30) {
+ # set the error val to null so there is no confusion
+ $this->error = null;
+
+ # make sure we are __not__ connected
+ if($this->connected()) {
+ # ok we are connected! what should we do?
+ # for now we will just give an error saying we
+ # are already connected
+ $this->error = array("error" => "Already connected to a server");
+ return false;
+ }
+
+ if(empty($port)) {
+ $port = $this->SMTP_PORT;
+ }
+
+ #connect to the smtp server
+ $this->smtp_conn = fsockopen($host, # the host of the server
+ $port, # the port to use
+ $errno, # error number if any
+ $errstr, # error message if any
+ $tval); # give up after ? secs
+ # verify we connected properly
+ if(empty($this->smtp_conn)) {
+ $this->error = array("error" => "Failed to connect to server",
+ "errno" => $errno,
+ "errstr" => $errstr);
+ if($this->do_debug >= 1) {
+ echo "SMTP -> ERROR: " . $this->error["error"] .
+ ": $errstr ($errno)" . $this->CRLF;
+ }
+ return false;
+ }
+
+ # sometimes the SMTP server takes a little longer to respond
+ # so we will give it a longer timeout for the first read
+ // Windows still does not have support for this timeout function
+ if(substr(PHP_OS, 0, 3) != "WIN")
+ socket_set_timeout($this->smtp_conn, $tval, 0);
+
+ # get any announcement stuff
+ $announce = $this->get_lines();
+
+ # set the timeout of any socket functions at 1/10 of a second
+ //if(function_exists("socket_set_timeout"))
+ // socket_set_timeout($this->smtp_conn, 0, 100000);
+
+ if($this->do_debug >= 2) {
+ echo "SMTP -> FROM SERVER:" . $this->CRLF . $announce;
+ }
+
+ return true;
+ }
+
+ /**
+ * Performs SMTP authentication. Must be run after running the
+ * Hello() method. Returns true if successfully authenticated.
+ * @access public
+ * @return bool
+ */
+ function Authenticate($username, $password) {
+ // Start authentication
+ fputs($this->smtp_conn,"AUTH LOGIN" . $this->CRLF);
+
+ $rply = $this->get_lines();
+ $code = substr($rply,0,3);
+
+ if($code != 334) {
+ $this->error =
+ array("error" => "AUTH not accepted from server",
+ "smtp_code" => $code,
+ "smtp_msg" => substr($rply,4));
+ if($this->do_debug >= 1) {
+ echo "SMTP -> ERROR: " . $this->error["error"] .
+ ": " . $rply . $this->CRLF;
+ }
+ return false;
+ }
+
+ // Send encoded username
+ fputs($this->smtp_conn, base64_encode($username) . $this->CRLF);
+
+ $rply = $this->get_lines();
+ $code = substr($rply,0,3);
+
+ if($code != 334) {
+ $this->error =
+ array("error" => "Username not accepted from server",
+ "smtp_code" => $code,
+ "smtp_msg" => substr($rply,4));
+ if($this->do_debug >= 1) {
+ echo "SMTP -> ERROR: " . $this->error["error"] .
+ ": " . $rply . $this->CRLF;
+ }
+ return false;
+ }
+
+ // Send encoded password
+ fputs($this->smtp_conn, base64_encode($password) . $this->CRLF);
+
+ $rply = $this->get_lines();
+ $code = substr($rply,0,3);
+
+ if($code != 235) {
+ $this->error =
+ array("error" => "Password not accepted from server",
+ "smtp_code" => $code,
+ "smtp_msg" => substr($rply,4));
+ if($this->do_debug >= 1) {
+ echo "SMTP -> ERROR: " . $this->error["error"] .
+ ": " . $rply . $this->CRLF;
+ }
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Returns true if connected to a server otherwise false
+ * @access private
+ * @return bool
+ */
+ function Connected() {
+ if(!empty($this->smtp_conn)) {
+ $sock_status = socket_get_status($this->smtp_conn);
+ if($sock_status["eof"]) {
+ # hmm this is an odd situation... the socket is
+ # valid but we are not connected anymore
+ if($this->do_debug >= 1) {
+ echo "SMTP -> NOTICE:" . $this->CRLF .
+ "EOF caught while checking if connected";
+ }
+ $this->Close();
+ return false;
+ }
+ return true; # everything looks good
+ }
+ return false;
+ }
+
+ /**
+ * Closes the socket and cleans up the state of the class.
+ * It is not considered good to use this function without
+ * first trying to use QUIT.
+ * @access public
+ * @return void
+ */
+ function Close() {
+ $this->error = null; # so there is no confusion
+ $this->helo_rply = null;
+ if(!empty($this->smtp_conn)) {
+ # close the connection and cleanup
+ fclose($this->smtp_conn);
+ $this->smtp_conn = 0;
+ }
+ }
+
+ /***************************************************************
+ * SMTP COMMANDS *
+ *************************************************************/
+
+ /**
+ * Issues a data command and sends the msg_data to the server
+ * finializing the mail transaction. $msg_data is the message
+ * that is to be send with the headers. Each header needs to be
+ * on a single line followed by a <CRLF> with the message headers
+ * and the message body being seperated by and additional <CRLF>.
+ *
+ * Implements rfc 821: DATA <CRLF>
+ *
+ * SMTP CODE INTERMEDIATE: 354
+ * [data]
+ * <CRLF>.<CRLF>
+ * SMTP CODE SUCCESS: 250
+ * SMTP CODE FAILURE: 552,554,451,452
+ * SMTP CODE FAILURE: 451,554
+ * SMTP CODE ERROR : 500,501,503,421
+ * @access public
+ * @return bool
+ */
+ function Data($msg_data) {
+ $this->error = null; # so no confusion is caused
+
+ if(!$this->connected()) {
+ $this->error = array(
+ "error" => "Called Data() without being connected");
+ return false;
+ }
+
+ fputs($this->smtp_conn,"DATA" . $this->CRLF);
+
+ $rply = $this->get_lines();
+ $code = substr($rply,0,3);
+
+ if($this->do_debug >= 2) {
+ echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply;
+ }
+
+ if($code != 354) {
+ $this->error =
+ array("error" => "DATA command not accepted from server",
+ "smtp_code" => $code,
+ "smtp_msg" => substr($rply,4));
+ if($this->do_debug >= 1) {
+ echo "SMTP -> ERROR: " . $this->error["error"] .
+ ": " . $rply . $this->CRLF;
+ }
+ return false;
+ }
+
+ # the server is ready to accept data!
+ # according to rfc 821 we should not send more than 1000
+ # including the CRLF
+ # characters on a single line so we will break the data up
+ # into lines by \r and/or \n then if needed we will break
+ # each of those into smaller lines to fit within the limit.
+ # in addition we will be looking for lines that start with
+ # a period '.' and append and additional period '.' to that
+ # line. NOTE: this does not count towards are limit.
+
+ # normalize the line breaks so we know the explode works
+ $msg_data = str_replace("\r\n","\n",$msg_data);
+ $msg_data = str_replace("\r","\n",$msg_data);
+ $lines = explode("\n",$msg_data);
+
+ # we need to find a good way to determine is headers are
+ # in the msg_data or if it is a straight msg body
+ # currently I am assuming rfc 822 definitions of msg headers
+ # and if the first field of the first line (':' sperated)
+ # does not contain a space then it _should_ be a header
+ # and we can process all lines before a blank "" line as
+ # headers.
+ $field = substr($lines[0],0,strpos($lines[0],":"));
+ $in_headers = false;
+ if(!empty($field) && !strstr($field," ")) {
+ $in_headers = true;
+ }
+
+ $max_line_length = 998; # used below; set here for ease in change
+
+ while(list(,$line) = @each($lines)) {
+ $lines_out = null;
+ if($line == "" && $in_headers) {
+ $in_headers = false;
+ }
+ # ok we need to break this line up into several
+ # smaller lines
+ while(strlen($line) > $max_line_length) {
+ $pos = strrpos(substr($line,0,$max_line_length)," ");
+
+ # Patch to fix DOS attack
+ if(!$pos) {
+ $pos = $max_line_length - 1;
+ }
+
+ $lines_out[] = substr($line,0,$pos);
+ $line = substr($line,$pos + 1);
+ # if we are processing headers we need to
+ # add a LWSP-char to the front of the new line
+ # rfc 822 on long msg headers
+ if($in_headers) {
+ $line = "\t" . $line;
+ }
+ }
+ $lines_out[] = $line;
+
+ # now send the lines to the server
+ while(list(,$line_out) = @each($lines_out)) {
+ if(strlen($line_out) > 0)
+ {
+ if(substr($line_out, 0, 1) == ".") {
+ $line_out = "." . $line_out;
+ }
+ }
+ fputs($this->smtp_conn,$line_out . $this->CRLF);
+ }
+ }
+
+ # ok all the message data has been sent so lets get this
+ # over with aleady
+ fputs($this->smtp_conn, $this->CRLF . "." . $this->CRLF);
+
+ $rply = $this->get_lines();
+ $code = substr($rply,0,3);
+
+ if($this->do_debug >= 2) {
+ echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply;
+ }
+
+ if($code != 250) {
+ $this->error =
+ array("error" => "DATA not accepted from server",
+ "smtp_code" => $code,
+ "smtp_msg" => substr($rply,4));
+ if($this->do_debug >= 1) {
+ echo "SMTP -> ERROR: " . $this->error["error"] .
+ ": " . $rply . $this->CRLF;
+ }
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Expand takes the name and asks the server to list all the
+ * people who are members of the _list_. Expand will return
+ * back and array of the result or false if an error occurs.
+ * Each value in the array returned has the format of:
+ * [ <full-name> <sp> ] <path>
+ * The definition of <path> is defined in rfc 821
+ *
+ * Implements rfc 821: EXPN <SP> <string> <CRLF>
+ *
+ * SMTP CODE SUCCESS: 250
+ * SMTP CODE FAILURE: 550
+ * SMTP CODE ERROR : 500,501,502,504,421
+ * @access public
+ * @return string array
+ */
+ function Expand($name) {
+ $this->error = null; # so no confusion is caused
+
+ if(!$this->connected()) {
+ $this->error = array(
+ "error" => "Called Expand() without being connected");
+ return false;
+ }
+
+ fputs($this->smtp_conn,"EXPN " . $name . $this->CRLF);
+
+ $rply = $this->get_lines();
+ $code = substr($rply,0,3);
+
+ if($this->do_debug >= 2) {
+ echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply;
+ }
+
+ if($code != 250) {
+ $this->error =
+ array("error" => "EXPN not accepted from server",
+ "smtp_code" => $code,
+ "smtp_msg" => substr($rply,4));
+ if($this->do_debug >= 1) {
+ echo "SMTP -> ERROR: " . $this->error["error"] .
+ ": " . $rply . $this->CRLF;
+ }
+ return false;
+ }
+
+ # parse the reply and place in our array to return to user
+ $entries = explode($this->CRLF,$rply);
+ while(list(,$l) = @each($entries)) {
+ $list[] = substr($l,4);
+ }
+
+ return $list;
+ }
+
+ /**
+ * Sends the HELO command to the smtp server.
+ * This makes sure that we and the server are in
+ * the same known state.
+ *
+ * Implements from rfc 821: HELO <SP> <domain> <CRLF>
+ *
+ * SMTP CODE SUCCESS: 250
+ * SMTP CODE ERROR : 500, 501, 504, 421
+ * @access public
+ * @return bool
+ */
+ function Hello($host="") {
+ $this->error = null; # so no confusion is caused
+
+ if(!$this->connected()) {
+ $this->error = array(
+ "error" => "Called Hello() without being connected");
+ return false;
+ }
+
+ # if a hostname for the HELO was not specified determine
+ # a suitable one to send
+ if(empty($host)) {
+ # we need to determine some sort of appopiate default
+ # to send to the server
+ $host = "localhost";
+ }
+
+ // Send extended hello first (RFC 2821)
+ if(!$this->SendHello("EHLO", $host))
+ {
+ if(!$this->SendHello("HELO", $host))
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Sends a HELO/EHLO command.
+ * @access private
+ * @return bool
+ */
+ function SendHello($hello, $host) {
+ fputs($this->smtp_conn, $hello . " " . $host . $this->CRLF);
+
+ $rply = $this->get_lines();
+ $code = substr($rply,0,3);
+
+ if($this->do_debug >= 2) {
+ echo "SMTP -> FROM SERVER: " . $this->CRLF . $rply;
+ }
+
+ if($code != 250) {
+ $this->error =
+ array("error" => $hello . " not accepted from server",
+ "smtp_code" => $code,
+ "smtp_msg" => substr($rply,4));
+ if($this->do_debug >= 1) {
+ echo "SMTP -> ERROR: " . $this->error["error"] .
+ ": " . $rply . $this->CRLF;
+ }
+ return false;
+ }
+
+ $this->helo_rply = $rply;
+
+ return true;
+ }
+
+ /**
+ * Gets help information on the keyword specified. If the keyword
+ * is not specified then returns generic help, ussually contianing
+ * A list of keywords that help is available on. This function
+ * returns the results back to the user. It is up to the user to
+ * handle the returned data. If an error occurs then false is
+ * returned with $this->error set appropiately.
+ *
+ * Implements rfc 821: HELP [ <SP> <string> ] <CRLF>
+ *
+ * SMTP CODE SUCCESS: 211,214
+ * SMTP CODE ERROR : 500,501,502,504,421
+ * @access public
+ * @return string
+ */
+ function Help($keyword="") {
+ $this->error = null; # to avoid confusion
+
+ if(!$this->connected()) {
+ $this->error = array(
+ "error" => "Called Help() without being connected");
+ return false;
+ }
+
+ $extra = "";
+ if(!empty($keyword)) {
+ $extra = " " . $keyword;
+ }
+
+ fputs($this->smtp_conn,"HELP" . $extra . $this->CRLF);
+
+ $rply = $this->get_lines();
+ $code = substr($rply,0,3);
+
+ if($this->do_debug >= 2) {
+ echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply;
+ }
+
+ if($code != 211 && $code != 214) {
+ $this->error =
+ array("error" => "HELP not accepted from server",
+ "smtp_code" => $code,
+ "smtp_msg" => substr($rply,4));
+ if($this->do_debug >= 1) {
+ echo "SMTP -> ERROR: " . $this->error["error"] .
+ ": " . $rply . $this->CRLF;
+ }
+ return false;
+ }
+
+ return $rply;
+ }
+
+ /**
+ * Starts a mail transaction from the email address specified in
+ * $from. Returns true if successful or false otherwise. If True
+ * the mail transaction is started and then one or more Recipient
+ * commands may be called followed by a Data command.
+ *
+ * Implements rfc 821: MAIL <SP> FROM:<reverse-path> <CRLF>
+ *
+ * SMTP CODE SUCCESS: 250
+ * SMTP CODE SUCCESS: 552,451,452
+ * SMTP CODE SUCCESS: 500,501,421
+ * @access public
+ * @return bool
+ */
+ function Mail($from) {
+ $this->error = null; # so no confusion is caused
+
+ if(!$this->connected()) {
+ $this->error = array(
+ "error" => "Called Mail() without being connected");
+ return false;
+ }
+
+ $useVerp = ($this->do_verp ? "XVERP" : "");
+ fputs($this->smtp_conn,"MAIL FROM:<" . $from . ">" . $useVerp . $this->CRLF);
+
+ $rply = $this->get_lines();
+ $code = substr($rply,0,3);
+
+ if($this->do_debug >= 2) {
+ echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply;
+ }
+
+ if($code != 250) {
+ $this->error =
+ array("error" => "MAIL not accepted from server",
+ "smtp_code" => $code,
+ "smtp_msg" => substr($rply,4));
+ if($this->do_debug >= 1) {
+ echo "SMTP -> ERROR: " . $this->error["error"] .
+ ": " . $rply . $this->CRLF;
+ }
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Sends the command NOOP to the SMTP server.
+ *
+ * Implements from rfc 821: NOOP <CRLF>
+ *
+ * SMTP CODE SUCCESS: 250
+ * SMTP CODE ERROR : 500, 421
+ * @access public
+ * @return bool
+ */
+ function Noop() {
+ $this->error = null; # so no confusion is caused
+
+ if(!$this->connected()) {
+ $this->error = array(
+ "error" => "Called Noop() without being connected");
+ return false;
+ }
+
+ fputs($this->smtp_conn,"NOOP" . $this->CRLF);
+
+ $rply = $this->get_lines();
+ $code = substr($rply,0,3);
+
+ if($this->do_debug >= 2) {
+ echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply;
+ }
+
+ if($code != 250) {
+ $this->error =
+ array("error" => "NOOP not accepted from server",
+ "smtp_code" => $code,
+ "smtp_msg" => substr($rply,4));
+ if($this->do_debug >= 1) {
+ echo "SMTP -> ERROR: " . $this->error["error"] .
+ ": " . $rply . $this->CRLF;
+ }
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Sends the quit command to the server and then closes the socket
+ * if there is no error or the $close_on_error argument is true.
+ *
+ * Implements from rfc 821: QUIT <CRLF>
+ *
+ * SMTP CODE SUCCESS: 221
+ * SMTP CODE ERROR : 500
+ * @access public
+ * @return bool
+ */
+ function Quit($close_on_error=true) {
+ $this->error = null; # so there is no confusion
+
+ if(!$this->connected()) {
+ $this->error = array(
+ "error" => "Called Quit() without being connected");
+ return false;
+ }
+
+ # send the quit command to the server
+ fputs($this->smtp_conn,"quit" . $this->CRLF);
+
+ # get any good-bye messages
+ $byemsg = $this->get_lines();
+
+ if($this->do_debug >= 2) {
+ echo "SMTP -> FROM SERVER:" . $this->CRLF . $byemsg;
+ }
+
+ $rval = true;
+ $e = null;
+
+ $code = substr($byemsg,0,3);
+ if($code != 221) {
+ # use e as a tmp var cause Close will overwrite $this->error
+ $e = array("error" => "SMTP server rejected quit command",
+ "smtp_code" => $code,
+ "smtp_rply" => substr($byemsg,4));
+ $rval = false;
+ if($this->do_debug >= 1) {
+ echo "SMTP -> ERROR: " . $e["error"] . ": " .
+ $byemsg . $this->CRLF;
+ }
+ }
+
+ if(empty($e) || $close_on_error) {
+ $this->Close();
+ }
+
+ return $rval;
+ }
+
+ /**
+ * Sends the command RCPT to the SMTP server with the TO: argument of $to.
+ * Returns true if the recipient was accepted false if it was rejected.
+ *
+ * Implements from rfc 821: RCPT <SP> TO:<forward-path> <CRLF>
+ *
+ * SMTP CODE SUCCESS: 250,251
+ * SMTP CODE FAILURE: 550,551,552,553,450,451,452
+ * SMTP CODE ERROR : 500,501,503,421
+ * @access public
+ * @return bool
+ */
+ function Recipient($to) {
+ $this->error = null; # so no confusion is caused
+
+ if(!$this->connected()) {
+ $this->error = array(
+ "error" => "Called Recipient() without being connected");
+ return false;
+ }
+
+ fputs($this->smtp_conn,"RCPT TO:<" . $to . ">" . $this->CRLF);
+
+ $rply = $this->get_lines();
+ $code = substr($rply,0,3);
+
+ if($this->do_debug >= 2) {
+ echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply;
+ }
+
+ if($code != 250 && $code != 251) {
+ $this->error =
+ array("error" => "RCPT not accepted from server",
+ "smtp_code" => $code,
+ "smtp_msg" => substr($rply,4));
+ if($this->do_debug >= 1) {
+ echo "SMTP -> ERROR: " . $this->error["error"] .
+ ": " . $rply . $this->CRLF;
+ }
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Sends the RSET command to abort and transaction that is
+ * currently in progress. Returns true if successful false
+ * otherwise.
+ *
+ * Implements rfc 821: RSET <CRLF>
+ *
+ * SMTP CODE SUCCESS: 250
+ * SMTP CODE ERROR : 500,501,504,421
+ * @access public
+ * @return bool
+ */
+ function Reset() {
+ $this->error = null; # so no confusion is caused
+
+ if(!$this->connected()) {
+ $this->error = array(
+ "error" => "Called Reset() without being connected");
+ return false;
+ }
+
+ fputs($this->smtp_conn,"RSET" . $this->CRLF);
+
+ $rply = $this->get_lines();
+ $code = substr($rply,0,3);
+
+ if($this->do_debug >= 2) {
+ echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply;
+ }
+
+ if($code != 250) {
+ $this->error =
+ array("error" => "RSET failed",
+ "smtp_code" => $code,
+ "smtp_msg" => substr($rply,4));
+ if($this->do_debug >= 1) {
+ echo "SMTP -> ERROR: " . $this->error["error"] .
+ ": " . $rply . $this->CRLF;
+ }
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Starts a mail transaction from the email address specified in
+ * $from. Returns true if successful or false otherwise. If True
+ * the mail transaction is started and then one or more Recipient
+ * commands may be called followed by a Data command. This command
+ * will send the message to the users terminal if they are logged
+ * in.
+ *
+ * Implements rfc 821: SEND <SP> FROM:<reverse-path> <CRLF>
+ *
+ * SMTP CODE SUCCESS: 250
+ * SMTP CODE SUCCESS: 552,451,452
+ * SMTP CODE SUCCESS: 500,501,502,421
+ * @access public
+ * @return bool
+ */
+ function Send($from) {
+ $this->error = null; # so no confusion is caused
+
+ if(!$this->connected()) {
+ $this->error = array(
+ "error" => "Called Send() without being connected");
+ return false;
+ }
+
+ fputs($this->smtp_conn,"SEND FROM:" . $from . $this->CRLF);
+
+ $rply = $this->get_lines();
+ $code = substr($rply,0,3);
+
+ if($this->do_debug >= 2) {
+ echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply;
+ }
+
+ if($code != 250) {
+ $this->error =
+ array("error" => "SEND not accepted from server",
+ "smtp_code" => $code,
+ "smtp_msg" => substr($rply,4));
+ if($this->do_debug >= 1) {
+ echo "SMTP -> ERROR: " . $this->error["error"] .
+ ": " . $rply . $this->CRLF;
+ }
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Starts a mail transaction from the email address specified in
+ * $from. Returns true if successful or false otherwise. If True
+ * the mail transaction is started and then one or more Recipient
+ * commands may be called followed by a Data command. This command
+ * will send the message to the users terminal if they are logged
+ * in and send them an email.
+ *
+ * Implements rfc 821: SAML <SP> FROM:<reverse-path> <CRLF>
+ *
+ * SMTP CODE SUCCESS: 250
+ * SMTP CODE SUCCESS: 552,451,452
+ * SMTP CODE SUCCESS: 500,501,502,421
+ * @access public
+ * @return bool
+ */
+ function SendAndMail($from) {
+ $this->error = null; # so no confusion is caused
+
+ if(!$this->connected()) {
+ $this->error = array(
+ "error" => "Called SendAndMail() without being connected");
+ return false;
+ }
+
+ fputs($this->smtp_conn,"SAML FROM:" . $from . $this->CRLF);
+
+ $rply = $this->get_lines();
+ $code = substr($rply,0,3);
+
+ if($this->do_debug >= 2) {
+ echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply;
+ }
+
+ if($code != 250) {
+ $this->error =
+ array("error" => "SAML not accepted from server",
+ "smtp_code" => $code,
+ "smtp_msg" => substr($rply,4));
+ if($this->do_debug >= 1) {
+ echo "SMTP -> ERROR: " . $this->error["error"] .
+ ": " . $rply . $this->CRLF;
+ }
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Starts a mail transaction from the email address specified in
+ * $from. Returns true if successful or false otherwise. If True
+ * the mail transaction is started and then one or more Recipient
+ * commands may be called followed by a Data command. This command
+ * will send the message to the users terminal if they are logged
+ * in or mail it to them if they are not.
+ *
+ * Implements rfc 821: SOML <SP> FROM:<reverse-path> <CRLF>
+ *
+ * SMTP CODE SUCCESS: 250
+ * SMTP CODE SUCCESS: 552,451,452
+ * SMTP CODE SUCCESS: 500,501,502,421
+ * @access public
+ * @return bool
+ */
+ function SendOrMail($from) {
+ $this->error = null; # so no confusion is caused
+
+ if(!$this->connected()) {
+ $this->error = array(
+ "error" => "Called SendOrMail() without being connected");
+ return false;
+ }
+
+ fputs($this->smtp_conn,"SOML FROM:" . $from . $this->CRLF);
+
+ $rply = $this->get_lines();
+ $code = substr($rply,0,3);
+
+ if($this->do_debug >= 2) {
+ echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply;
+ }
+
+ if($code != 250) {
+ $this->error =
+ array("error" => "SOML not accepted from server",
+ "smtp_code" => $code,
+ "smtp_msg" => substr($rply,4));
+ if($this->do_debug >= 1) {
+ echo "SMTP -> ERROR: " . $this->error["error"] .
+ ": " . $rply . $this->CRLF;
+ }
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * This is an optional command for SMTP that this class does not
+ * support. This method is here to make the RFC821 Definition
+ * complete for this class and __may__ be implimented in the future
+ *
+ * Implements from rfc 821: TURN <CRLF>
+ *
+ * SMTP CODE SUCCESS: 250
+ * SMTP CODE FAILURE: 502
+ * SMTP CODE ERROR : 500, 503
+ * @access public
+ * @return bool
+ */
+ function Turn() {
+ $this->error = array("error" => "This method, TURN, of the SMTP ".
+ "is not implemented");
+ if($this->do_debug >= 1) {
+ echo "SMTP -> NOTICE: " . $this->error["error"] . $this->CRLF;
+ }
+ return false;
+ }
+
+ /**
+ * Verifies that the name is recognized by the server.
+ * Returns false if the name could not be verified otherwise
+ * the response from the server is returned.
+ *
+ * Implements rfc 821: VRFY <SP> <string> <CRLF>
+ *
+ * SMTP CODE SUCCESS: 250,251
+ * SMTP CODE FAILURE: 550,551,553
+ * SMTP CODE ERROR : 500,501,502,421
+ * @access public
+ * @return int
+ */
+ function Verify($name) {
+ $this->error = null; # so no confusion is caused
+
+ if(!$this->connected()) {
+ $this->error = array(
+ "error" => "Called Verify() without being connected");
+ return false;
+ }
+
+ fputs($this->smtp_conn,"VRFY " . $name . $this->CRLF);
+
+ $rply = $this->get_lines();
+ $code = substr($rply,0,3);
+
+ if($this->do_debug >= 2) {
+ echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply;
+ }
+
+ if($code != 250 && $code != 251) {
+ $this->error =
+ array("error" => "VRFY failed on name '$name'",
+ "smtp_code" => $code,
+ "smtp_msg" => substr($rply,4));
+ if($this->do_debug >= 1) {
+ echo "SMTP -> ERROR: " . $this->error["error"] .
+ ": " . $rply . $this->CRLF;
+ }
+ return false;
+ }
+ return $rply;
+ }
+
+ /*******************************************************************
+ * INTERNAL FUNCTIONS *
+ ******************************************************************/
+
+ /**
+ * Read in as many lines as possible
+ * either before eof or socket timeout occurs on the operation.
+ * With SMTP we can tell if we have more lines to read if the
+ * 4th character is '-' symbol. If it is a space then we don't
+ * need to read anything else.
+ * @access private
+ * @return string
+ */
+ function get_lines() {
+ $data = "";
+ while($str = @fgets($this->smtp_conn,515)) {
+ if($this->do_debug >= 4) {
+ echo "SMTP -> get_lines(): \$data was \"$data\"" .
+ $this->CRLF;
+ echo "SMTP -> get_lines(): \$str is \"$str\"" .
+ $this->CRLF;
+ }
+ $data .= $str;
+ if($this->do_debug >= 4) {
+ echo "SMTP -> get_lines(): \$data is \"$data\"" . $this->CRLF;
+ }
+ # if the 4th character is a space then we are done reading
+ # so just break the loop
+ if(substr($str,3,1) == " ") { break; }
+ }
+ return $data;
+ }
+
+}
+
+
+ ?>
diff --git a/site/vendors/phpmailer/docs/extending.html b/site/vendors/phpmailer/docs/extending.html
new file mode 100644
index 0000000..f7c3200
--- /dev/null
+++ b/site/vendors/phpmailer/docs/extending.html
@@ -0,0 +1,148 @@
+<html>
+<head>
+<title>Examples using phpmailer</title>
+</head>
+
+<body bgcolor="#FFFFFF">
+
+<h2>Examples using phpmailer</h2>
+
+<h3>1. Advanced Example</h3>
+<p>
+
+This demonstrates sending out multiple email messages with binary attachments
+from a MySQL database with multipart/alternative support.<p>
+<table cellpadding="4" border="1" width="80%">
+<tr>
+<td bgcolor="#CCCCCC">
+<pre>
+require("class.phpmailer.php");
+
+$mail = new phpmailer();
+
+$mail->From = "list@example.com";
+$mail->FromName = "List manager";
+$mail->Host = "smtp1.example.com;smtp2.example.com";
+$mail->Mailer = "smtp";
+
+@MYSQL_CONNECT("localhost","root","password");
+@mysql_select_db("my_company");
+$query  = "SELECT full_name, email, photo FROM employee WHERE id=$id";
+$result = @MYSQL_QUERY($query);
+
+while ($row = mysql_fetch_array ($result))
+{
+ // HTML body
+ $body = "Hello &lt;font size=\"4\"&gt;" . $row["full_name"] . "&lt;/font&gt;, &lt;p&gt;";
+ $body .= "&lt;i&gt;Your&lt;/i&gt; personal photograph to this message.&lt;p&gt;";
+ $body .= "Sincerely, &lt;br&gt;";
+ $body .= "phpmailer List manager";
+
+ // Plain text body (for mail clients that cannot read HTML)
+ $text_body = "Hello " . $row["full_name"] . ", \n\n";
+ $text_body .= "Your personal photograph to this message.\n\n";
+ $text_body .= "Sincerely, \n";
+ $text_body .= "phpmailer List manager";
+
+ $mail->Body = $body;
+ $mail->AltBody = $text_body;
+ $mail->AddAddress($row["email"], $row["full_name"]);
+ $mail->AddStringAttachment($row["photo"], "YourPhoto.jpg");
+
+ if(!$mail->Send())
+ echo "There has been a mail error sending to " . $row["email"] . "&lt;br&gt;";
+
+ // Clear all addresses and attachments for next loop
+ $mail->ClearAddresses();
+ $mail->ClearAttachments();
+}
+</pre>
+</td>
+</tr>
+</table>
+<p>
+
+<h3>2. Extending phpmailer</h3>
+<p>
+
+Extending classes with inheritance is one of the most
+powerful features of object-oriented
+programming. It allows you to make changes to the
+original class for your
+own personal use without hacking the original
+classes. Plus, it is very
+easy to do. I've provided an example:
+
+<p>
+Here's a class that extends the phpmailer class and sets the defaults
+for the particular site:<br>
+PHP include file: <b>mail.inc.php</b>
+<p>
+
+<table cellpadding="4" border="1" width="80%">
+<tr>
+<td bgcolor="#CCCCCC">
+<pre>
+require("class.phpmailer.php");
+
+class my_phpmailer extends phpmailer {
+ // Set default variables for all new objects
+ var $From = "from@example.com";
+ var $FromName = "Mailer";
+ var $Host = "smtp1.example.com;smtp2.example.com";
+ var $Mailer = "smtp"; // Alternative to IsSMTP()
+ var $WordWrap = 75;
+
+ // Replace the default error_handler
+ function error_handler($msg) {
+ print("My Site Error");
+ print("Description:");
+ printf("%s", $msg);
+ exit;
+ }
+
+ // Create an additional function
+ function do_something($something) {
+ // Place your new code here
+ }
+}
+</td>
+</tr>
+</table>
+<br>
+
+Now here's a normal PHP page in the site, which will have all the defaults set
+above:<br>
+Normal PHP file: <b>mail_test.php</b>
+<p>
+
+<table cellpadding="4" border="1" width="80%">
+<tr>
+<td bgcolor="#CCCCCC">
+<pre>
+require("mail.inc.php");
+
+// Instantiate your new class
+$mail = new my_phpmailer;
+
+// Now you only need to add the necessary stuff
+$mail->AddAddress("josh@example.com", "Josh Adams");
+$mail->Subject = "Here is the subject";
+$mail->Body = "This is the message body";
+$mail->AddAttachment("c:/temp/11-10-00.zip", "new_name.zip"); // optional name
+
+if(!$mail->Send())
+{
+ echo "There was an error sending the message";
+ exit;
+}
+
+echo "Message was sent successfully";
+</pre>
+</td>
+</tr>
+</table>
+</p>
+
+</body>
+</html>
diff --git a/site/vendors/phpmailer/docs/faq.html b/site/vendors/phpmailer/docs/faq.html
new file mode 100644
index 0000000..18dfafd
--- /dev/null
+++ b/site/vendors/phpmailer/docs/faq.html
@@ -0,0 +1,66 @@
+<html>
+<head>
+<title>phpmailer FAQ</title>
+</head>
+
+<body bgcolor="#FFFFFF">
+
+<h2>phpmailer FAQ</h2>
+
+<p>
+<b>I'm using the SMTP mailer and I keep on getting a timeout message
+well before the X seconds I set it for. What gives?</b>
+<br>
+PHP versions 4.0.4pl1 and earlier have a bug in which sockets timeout
+early. You can fix this by re-compiling PHP 4.0.4pl1 with this fix:
+<a href="timeoutfix.diff">timeoutfix.diff</a>. Otherwise you can wait
+for the new PHP release.
+</p>
+
+<p>
+<b>I am concerned that using include files will take up too much
+processing time on my computer. How can I make it run faster?</b>
+<br>
+PHP by itself is very fast. Much faster than ASP or JSP running on
+the same type of server. This is because it has very little overhead compared
+to its competitors and it pre-compiles all of
+its code before it runs each script (in PHP4). However, all of
+this compiling and re-compiling can take up a lot of valuable
+computer resources. However, there are programs out there that compile
+PHP code and store it in memory (or on mmaped files) to reduce the
+processing immensely. Two of these: <a href="http://apc.communityconnect.com">APC
+(Alternative PHP Cache)</a> and <a href="http://bwcache.bware.it/index.htm">Afterburner</a>
+(<a href="http://www.mm4.de/php4win/mod_php4_win32/">Win32 download</a>)
+are excellent free tools that do just this. If you have the money
+you might also try <a href="http://www.zend.com">Zend Cache</a>, it is
+even faster than the open source varieties. All of these tools make your
+scripts run faster while also reducing the load on your server. I have tried
+them myself and they are quite stable too.
+</p>
+
+
+<p>
+<b>What mailer gives me the best performance?</b>
+<br>
+On a single machine the mail() or sendmail mailers give you the best
+performance because they do not have the added overhead of SMTP.
+If you have you have your mail server on a another machine then
+SMTP is your only option, but you do get the benefit of redundant
+mail servers.
+</p>
+
+<p>
+<b>When I try to attach a file with on my server I get a
+"Could not find {file} on filesystem error". Why is this?</b>
+<br>
+If you are using a Unix machine this is probably because the user
+running your web server does not have read access to the directory
+in question. If you are using Windows, then the problem probably is
+that you have used single backslashes to denote directories ("\").
+A single backslash has a special meaning to PHP so these are not
+valid. Instead use double backslashes ("\\") or a single forward
+slash ("/").
+</p>
+
+</body>
+</html> \ No newline at end of file
diff --git a/site/vendors/phpmailer/docs/pop3_article.txt b/site/vendors/phpmailer/docs/pop3_article.txt
new file mode 100644
index 0000000..379c44e
--- /dev/null
+++ b/site/vendors/phpmailer/docs/pop3_article.txt
@@ -0,0 +1,39 @@
+This is built for PHP Mailer 1.72 and was not tested with any previous version. It was developed under PHP 4.3.11 (E_ALL). It works under PHP 5 and 5.1 with E_ALL, but not in Strict mode due to var deprecation (but then neither does PHP Mailer either!). It follows the RFC 1939 standard explicitly and is fully commented.
+
+With that noted, here is how to implement it:
+Install the class file
+
+I didn't want to modify the PHP Mailer classes at all, so you will have to include/require this class along with the base one. It can sit quite happily in the phpmailer-1.72 directory:
+[geshi lang=php] require 'phpmailer-1.72/class.phpmailer.php'; require 'phpmailer-1.72/class.pop3.php'; [/geshi]
+When you need it, create your POP3 object
+
+Right before I invoke PHP Mailer I activate the POP3 authorisation. POP3 before SMTP is a process whereby you login to your web hosts POP3 mail server BEFORE sending out any emails via SMTP. The POP3 logon 'verifies' your ability to send email by SMTP, which typically otherwise blocks you. On my web host (Pair Networks) a single POP3 logon is enough to 'verify' you for 90 minutes. Here is some sample PHP code that activates the POP3 logon and then sends an email via PHP Mailer:
+[geshi lang=php] Authorise('pop3.example.com', 110, 30, 'mailer', 'password', 1); $mail = new PHPMailer(); $mail->SMTPDebug = 2; $mail->IsSMTP(); $mail->IsHTML(false); $mail->Host = 'relay.example.com'; $mail->From = 'mailer@example.com'; $mail->FromName = 'Example Mailer'; $mail->Subject = 'My subject'; $mail->Body = 'Hello world'; $mail->AddAddress('rich@corephp.co.uk', 'Richard Davey'); if (!$mail->Send()) { echo $mail->ErrorInfo; } ?> [/geshi]
+
+The PHP Mailer parts of this code should be obvious to anyone who has used PHP Mailer before. One thing to note - you almost certainly will not need to use SMTP Authentication *and* POP3 before SMTP together. The Authorisation method is a proxy method to all of the others within that class. There are Connect, Logon and Disconnect methods available, but I wrapped them in the single Authorisation one to make things easier.
+The Parameters
+
+The Authorise parameters are as follows:
+[geshi lang=php]$pop->Authorise('pop3.example.com', 110, 30, 'mailer', 'password', 1);[/geshi]
+
+ 1. pop3.example.com - The POP3 Mail Server Name (hostname or IP address)
+ 2. 110 - The POP3 Port on which to connect (default is usually 110, but check with your host)
+ 3. 30 - A connection time-out value (in seconds)
+ 4. mailer - The POP3 Username required to logon
+ 5. password - The POP3 Password required to logon
+ 6. 1 - The class debug level (0 = off, 1+ = debug output is echoed to the browser)
+
+Final Comments + the Download
+
+1) This class does not support APOP connections. This is only because I did not have an APOP server to test with, but if you'd like to see that added just contact me.
+
+2) Opening and closing lots of POP3 connections can be quite a resource/network drain. If you need to send a whole batch of emails then just perform the authentication once at the start, and then loop through your mail sending script. Providing this process doesn't take longer than the verification period lasts on your POP3 server, you should be fine. With my host that period is 90 minutes, i.e. plenty of time.
+
+3) If you have heavy requirements for this script (i.e. send a LOT of email on a frequent basis) then I would advise seeking out an alternative sending method (direct SMTP ideally). If this isn't possible then you could modify this class so the 'last authorised' date is recorded somewhere (MySQL, Flat file, etc) meaning you only open a new connection if the old one has expired, saving you precious overhead.
+
+4) There are lots of other POP3 classes for PHP available. However most of them implement the full POP3 command set, where-as this one is purely for authentication, and much lighter as a result. However using any of the other POP3 classes to just logon to your server would have the same net result. At the end of the day, use whatever method you feel most comfortable with.
+Download
+
+Here is the full class file plus my test script: POP_before_SMTP_PHPMailer.zip (4 KB) - Please note that it does not include PHPMailer itself.
+
+My thanks to Chris Ryan for the inspiration (even if indirectly, via his SMTP class)
diff --git a/site/vendors/phpmailer/docs/timeoutfix.diff b/site/vendors/phpmailer/docs/timeoutfix.diff
new file mode 100644
index 0000000..8821f00
--- /dev/null
+++ b/site/vendors/phpmailer/docs/timeoutfix.diff
@@ -0,0 +1,23 @@
+*** /usr/local/src/php-4.0.4pl1/ext/standard/fsock.c.old Mon Mar 26 13:07:40 2001
+--- /usr/local/src/php-4.0.4pl1/ext/standard/fsock.c Mon Mar 26 13:12:03 2001
+***************
+*** 559,564 ****
+--- 559,565 ----
+
+ static void php_sockread_total(php_sockbuf *sock, size_t maxread)
+ {
++ sock->timeout_event = 0;
+ while(!sock->eof && TOREAD(sock) < maxread && !sock->timeout_event) {
+ php_sockread_internal(sock);
+ }
+***************
+*** 619,624 ****
+--- 620,627 ----
+ }
+
+ SEARCHCR();
++
++ sock->timeout_event = 0;
+
+ if(!p) {
+ if(sock->is_blocked) {
diff --git a/site/vendors/phpmailer/docs/use_gmail.txt b/site/vendors/phpmailer/docs/use_gmail.txt
new file mode 100644
index 0000000..e72d799
--- /dev/null
+++ b/site/vendors/phpmailer/docs/use_gmail.txt
@@ -0,0 +1,40 @@
+<?php
+
+// example on using PHPMailer with GMAIL
+
+include("class.phpmailer.php");
+include("class.smtp.php");
+
+$mail=new PHPMailer();
+
+$mail->IsSMTP();
+$mail->SMTPAuth = true; // enable SMTP authentication
+$mail->SMTPSecure = "ssl"; // sets the prefix to the servier
+$mail->Host = "smtp.gmail.com"; // sets GMAIL as the SMTP server
+$mail->Port = 465; // set the SMTP port
+
+$mail->Username = "yourname@gmail.com"; // GMAIL username
+$mail->Password = "password"; // GMAIL password
+
+$mail->From = "replyto@yourdomain.com";
+$mail->FromName = "Webmaster";
+$mail->Subject = "This is the subject";
+$mail->Body = "Hi,<br>This is the HTML BODY<br>"; //HTML Body
+$mail->AltBody = "This is the body when user views in plain text format"; //Text Body
+
+$mail->WordWrap = 50; // set word wrap
+
+$mail->AddAddress("username@domain.com","First Last");
+$mail->AddReplyTo("replyto@yourdomain.com","Webmaster");
+$mail->AddAttachment("/path/to/file.zip"); // attachment
+$mail->AddAttachment("/path/to/image.jpg", "new.jpg"); // attachment
+
+$mail->IsHTML(true); // send as HTML
+
+if(!$mail->Send()) {
+ echo "Mailer Error: " . $mail->ErrorInfo;
+} else {
+ echo "Message has been sent";
+}
+
+?>
diff --git a/site/vendors/phpmailer/examples/contents.html b/site/vendors/phpmailer/examples/contents.html
new file mode 100644
index 0000000..70c7e30
--- /dev/null
+++ b/site/vendors/phpmailer/examples/contents.html
@@ -0,0 +1,12 @@
+<body background="images/bkgrnd.gif" style="margin: 0px;">
+<div style="width: 640px; font-family: Arial, Helvetica, sans-serif; font-size: 11px;">
+<div align="center"><img src="images/phpmailer.gif" style="height: 90px; width: 340px"></div><br>
+<br>
+&nbsp;This is a test of PHPMailer v2.0.0 rc1.<br>
+<br>
+This particular example uses <strong>HTML</strong>, with a &lt;div&gt; tag and inline<br>
+styles.<br>
+<br>
+Also note the use of the PHPMailer at the top with no specific code to handle
+including it in the body of the email.</div>
+</body>
diff --git a/site/vendors/phpmailer/examples/images/bkgrnd.gif b/site/vendors/phpmailer/examples/images/bkgrnd.gif
new file mode 100644
index 0000000..bc89624
--- /dev/null
+++ b/site/vendors/phpmailer/examples/images/bkgrnd.gif
Binary files differ
diff --git a/site/vendors/phpmailer/examples/images/phpmailer.gif b/site/vendors/phpmailer/examples/images/phpmailer.gif
new file mode 100644
index 0000000..5e26971
--- /dev/null
+++ b/site/vendors/phpmailer/examples/images/phpmailer.gif
Binary files differ
diff --git a/site/vendors/phpmailer/examples/images/phpmailer.png b/site/vendors/phpmailer/examples/images/phpmailer.png
new file mode 100644
index 0000000..abe0101
--- /dev/null
+++ b/site/vendors/phpmailer/examples/images/phpmailer.png
Binary files differ
diff --git a/site/vendors/phpmailer/examples/images/phpmailer_mini.gif b/site/vendors/phpmailer/examples/images/phpmailer_mini.gif
new file mode 100644
index 0000000..dc7d782
--- /dev/null
+++ b/site/vendors/phpmailer/examples/images/phpmailer_mini.gif
Binary files differ
diff --git a/site/vendors/phpmailer/examples/index.html b/site/vendors/phpmailer/examples/index.html
new file mode 100644
index 0000000..0c61b5e
--- /dev/null
+++ b/site/vendors/phpmailer/examples/index.html
@@ -0,0 +1,73 @@
+<p>The example file &quot;test1.php&quot; contents include:</p>
+<div style="width: 600px; background-color: #CCCCCC;">
+<code>
+&lt;?php<br>
+<br>
+include_once('../class.phpmailer.php');<br>
+<br>
+$mail = new PHPMailer();<br>
+<br>
+$body = $mail->getFile('contents.html');<br>
+<br>
+$body = eregi_replace("[\]",'',$body);<br>
+$subject = eregi_replace("[\]",'',$subject);<br>
+<br>
+$mail->From = "name@yourdomain.com";<br>
+$mail->FromName = "First Last";<br>
+<br>
+$mail->Subject = "PHPMailer Test Subject";<br>
+<br>
+$mail->AltBody = "To view the message, please use an HTML compatible email viewer!"; // optional, comment out and test<br>
+<br>
+$mail->MsgHTML($body);<br>
+<br>
+$mail->AddAddress("whoto@otherdomain.com", "John Doe");<br>
+<br>
+if(!$mail->Send()) {<br>
+ echo 'Failed to send mail';<br>
+} else {<br>
+ echo 'Mail sent';<br>
+}<br>
+<br>
+?&gt;
+</code>
+</div>
+<br>
+Although you could use full compabitility with PHPMailer 1.7.3, this example
+shows how to use the new features. If you view 'contents.html', you will note
+that there is a background image used in the &lt;body tag as well as an image used
+with a regular &lt;img tag. Here&#39;s what the HTML file looks like:<br>
+<br>
+<div style="width: 600px; background-color: #CCCCCC;">
+<code>
+&lt;body background="images/bkgrnd.gif" style="margin: 0px;"&gt;<br>
+&lt;div style="width: 640px; font-family: Arial, Helvetica, sans-serif; font-size: 11px;"&gt;<br>
+&lt;div align="center"&gt;&lt;img src="images/phpmailer.gif" style="height: 90px; width: 340px"&gt;&lt;/div&gt;&lt;br&gt;<br>
+&lt;br&gt;<br>
+&nbsp;This is a test of PHPMailer v2.0.0 rc1.&lt;br&gt;<br>
+&lt;br&gt;<br>
+This particular example uses &lt;strong&gt;HTML&lt;/strong&gt;, with a &lt;div&gt; tag and inline&lt;br&gt;<br>
+styles.&lt;br&gt;<br>
+&lt;br&gt;<br>
+Also note the use of the PHPMailer at the top with no specific code to handle<br>
+including it in the body of the email.&lt;/div&gt;<br>
+&lt;/body&gt;<br>
+</code>
+</div>
+<br>
+A few things to notice in the PHP script that generates the email:
+<ul>
+ <li>the use of $mail-&gt;AltBody is completely optional. If not used, PHPMailer
+ will use the HTML text with htmlentities().</li>
+ <li>the background= and &lt;img src= images were processed without any directives
+ or methods from the PHP script</li>
+ <li>there is no specific code to define the image type ... that is handled
+ automatically by PHPMailer when it parses the images</li>
+ <li>we are using a new class method '$mail->MsgHTML($body)' ... that is what will handle the parsing of the images and creating the AltBody text</li>
+</ul>
+<p>Of course, you can still use PHPMailer the same way you have in the past.
+That provides full compatibility with all existing scripts, while new scripts
+can take advantage of the new features.</p>
+<p>Modify test1.php now with your own email address and try it out.</p>
+To see what the email SHOULD look like in your HTML compatible email viewer: <a href="contents.html">click here</a><br>
+
diff --git a/site/vendors/phpmailer/examples/pop3_before_smtp_test.php b/site/vendors/phpmailer/examples/pop3_before_smtp_test.php
new file mode 100644
index 0000000..794b2a2
--- /dev/null
+++ b/site/vendors/phpmailer/examples/pop3_before_smtp_test.php
@@ -0,0 +1,39 @@
+<html>
+<head>
+<title>POP before SMTP Test</title>
+</head>
+
+<body>
+
+<pre>
+<?php
+ require 'class.phpmailer.php';
+ require 'class.pop3.php';
+
+ $pop = new POP3();
+ $pop->Authorise('pop3.example.com', 110, 30, 'mailer', 'password', 1);
+
+ $mail = new PHPMailer();
+
+ $mail->IsSMTP();
+ $mail->SMTPDebug = 2;
+ $mail->IsHTML(false);
+
+ $mail->Host = 'relay.example.com';
+
+ $mail->From = 'mailer@example.com';
+ $mail->FromName = 'Example Mailer';
+
+ $mail->Subject = 'My subject';
+ $mail->Body = 'Hello world';
+ $mail->AddAddress('name@anydomain.com', 'First Last');
+
+ if (!$mail->Send())
+ {
+ echo $mail->ErrorInfo;
+ }
+?>
+</pre>
+
+</body>
+</html>
diff --git a/site/vendors/phpmailer/examples/test1.php b/site/vendors/phpmailer/examples/test1.php
new file mode 100644
index 0000000..063c2c7
--- /dev/null
+++ b/site/vendors/phpmailer/examples/test1.php
@@ -0,0 +1,28 @@
+<?php
+
+include_once('../class.phpmailer.php');
+
+$mail = new PHPMailer();
+
+$body = $mail->getFile('contents.html');
+
+$body = eregi_replace("[\]",'',$body);
+
+$mail->From = "name@yourdomain.com";
+$mail->FromName = "First Last";
+
+$mail->Subject = "PHPMailer Test Subject";
+
+$mail->AltBody = "To view the message, please use an HTML compatible email viewer!"; // optional, comment out and test
+
+$mail->MsgHTML($body);
+
+$mail->AddAddress("whoto@otherdomain.com", "John Doe");
+
+if(!$mail->Send()) {
+ echo 'Failed to send mail';
+} else {
+ echo 'Mail sent';
+}
+
+?>
diff --git a/site/vendors/phpmailer/language/phpmailer.lang-br.php b/site/vendors/phpmailer/language/phpmailer.lang-br.php
new file mode 100644
index 0000000..39141d6
--- /dev/null
+++ b/site/vendors/phpmailer/language/phpmailer.lang-br.php
@@ -0,0 +1,21 @@
+<?php
+/**
+ * PHPMailer language file.
+ * Portuguese Version
+ * By Paulo Henrique Garcia - paulo@controllerweb.com.br
+ */
+
+$PHPMAILER_LANG = array();
+$PHPMAILER_LANG["provide_address"] = 'Você deve fornecer pelo menos um endereço de destinatário de email.';
+$PHPMAILER_LANG["mailer_not_supported"] = ' mailer não suportado.';
+$PHPMAILER_LANG["execute"] = 'Não foi possível executar: ';
+$PHPMAILER_LANG["instantiate"] = 'Não foi possível instanciar a função mail.';
+$PHPMAILER_LANG["authenticate"] = 'Erro de SMTP: Não foi possível autenticar.';
+$PHPMAILER_LANG["from_failed"] = 'Os endereços de rementente a seguir falharam: ';
+$PHPMAILER_LANG["recipients_failed"] = 'Erro de SMTP: Os endereços de destinatário a seguir falharam: ';
+$PHPMAILER_LANG["data_not_accepted"] = 'Erro de SMTP: Dados não aceitos.';
+$PHPMAILER_LANG["connect_host"] = 'Erro de SMTP: Não foi possível conectar com o servidor SMTP.';
+$PHPMAILER_LANG["file_access"] = 'Não foi possível acessar o arquivo: ';
+$PHPMAILER_LANG["file_open"] = 'Erro de Arquivo: Não foi possível abrir o arquivo: ';
+$PHPMAILER_LANG["encoding"] = 'Codificação desconhecida: ';
+?>
diff --git a/site/vendors/phpmailer/language/phpmailer.lang-ca.php b/site/vendors/phpmailer/language/phpmailer.lang-ca.php
new file mode 100644
index 0000000..29a464c
--- /dev/null
+++ b/site/vendors/phpmailer/language/phpmailer.lang-ca.php
@@ -0,0 +1,22 @@
+<?php
+/**
+ * PHPMailer language file.
+ * Catalan Version
+ * By Ivan: web AT microstudi DOT com
+ */
+
+$PHPMAILER_LANG = array();
+
+$PHPMAILER_LANG["provide_address"] = 'S\'ha de proveir almenys una adreça d\'email com a destinatari.';
+$PHPMAILER_LANG["mailer_not_supported"] = ' mailer no està suportat';
+$PHPMAILER_LANG["execute"] = 'No es pot executar: ';
+$PHPMAILER_LANG["instantiate"] = 'No s\'ha pogut crear una instància de la funció Mail.';
+$PHPMAILER_LANG["authenticate"] = 'Error SMTP: No s\'hapogut autenticar.';
+$PHPMAILER_LANG["from_failed"] = 'La(s) següent(s) adreces de remitent han fallat: ';
+$PHPMAILER_LANG["recipients_failed"] = 'Error SMTP: Els següents destinataris han fallat: ';
+$PHPMAILER_LANG["data_not_accepted"] = 'Error SMTP: Dades no acceptades.';
+$PHPMAILER_LANG["connect_host"] = 'Error SMTP: No es pot connectar al servidor SMTP.';
+$PHPMAILER_LANG["file_access"] = 'No es pot accedir a l\'arxiu: ';
+$PHPMAILER_LANG["file_open"] = 'Error d\'Arxiu: No es pot obrir l\'arxiu: ';
+$PHPMAILER_LANG["encoding"] = 'Codificació desconeguda: ';
+?> \ No newline at end of file
diff --git a/site/vendors/phpmailer/language/phpmailer.lang-cz.php b/site/vendors/phpmailer/language/phpmailer.lang-cz.php
new file mode 100644
index 0000000..eee630a
--- /dev/null
+++ b/site/vendors/phpmailer/language/phpmailer.lang-cz.php
@@ -0,0 +1,24 @@
+<?php
+/**
+ * PHPMailer language file.
+ * Czech Version
+ */
+
+$PHPMAILER_LANG = array();
+
+$PHPMAILER_LANG["provide_address"] = 'Musíte zadat alespoò jednu ' .
+ 'emailovou adresu pøíjemce.';
+$PHPMAILER_LANG["mailer_not_supported"] = ' mailový klient není podporován.';
+$PHPMAILER_LANG["execute"] = 'Nelze provést: ';
+$PHPMAILER_LANG["instantiate"] = 'Nelze vytvoøit instanci emailové funkce.';
+$PHPMAILER_LANG["authenticate"] = 'SMTP Error: Chyba autentikace.';
+$PHPMAILER_LANG["from_failed"] = 'Následující adresa From je nesprávná: ';
+$PHPMAILER_LANG["recipients_failed"] = 'SMTP Error: Adresy pøíjemcù ' .
+ 'nejsou správné ' .
+$PHPMAILER_LANG["data_not_accepted"] = 'SMTP Error: Data nebyla pøijata';
+$PHPMAILER_LANG["connect_host"] = 'SMTP Error: Nelze navázat spojení se ' .
+ ' SMTP serverem.';
+$PHPMAILER_LANG["file_access"] = 'Soubor nenalezen: ';
+$PHPMAILER_LANG["file_open"] = 'File Error: Nelze otevøít soubor pro ètení: ';
+$PHPMAILER_LANG["encoding"] = 'Neznámé kódování: ';
+?> \ No newline at end of file
diff --git a/site/vendors/phpmailer/language/phpmailer.lang-de.php b/site/vendors/phpmailer/language/phpmailer.lang-de.php
new file mode 100644
index 0000000..7c5f7a5
--- /dev/null
+++ b/site/vendors/phpmailer/language/phpmailer.lang-de.php
@@ -0,0 +1,23 @@
+<?php
+/**
+ * PHPMailer language file.
+ * German Version
+ */
+
+$PHPMAILER_LANG = array();
+
+$PHPMAILER_LANG["provide_address"] = 'Bitte geben Sie mindestens eine ' .
+ 'Empf&auml;nger Emailadresse an.';
+$PHPMAILER_LANG["mailer_not_supported"] = ' mailer wird nicht unterst&uuml;tzt.';
+$PHPMAILER_LANG["execute"] = 'Konnte folgenden Befehl nicht ausf&uuml;hren: ';
+$PHPMAILER_LANG["instantiate"] = 'Mail Funktion konnte nicht initialisiert werden.';
+$PHPMAILER_LANG["authenticate"] = 'SMTP Fehler: Authentifizierung fehlgeschlagen.';
+$PHPMAILER_LANG["from_failed"] = 'Die folgende Absenderadresse ist nicht korrekt: ';
+$PHPMAILER_LANG["recipients_failed"] = 'SMTP Fehler: Die folgenden ' .
+ 'Empf&auml;nger sind nicht korrekt: ';
+$PHPMAILER_LANG["data_not_accepted"] = 'SMTP Fehler: Daten werden nicht akzeptiert.';
+$PHPMAILER_LANG["connect_host"] = 'SMTP Fehler: Konnte keine Verbindung zum SMTP-Host herstellen.';
+$PHPMAILER_LANG["file_access"] = 'Zugriff auf folgende Datei fehlgeschlagen: ';
+$PHPMAILER_LANG["file_open"] = 'Datei Fehler: konnte folgende Datei nicht &ouml;ffnen: ';
+$PHPMAILER_LANG["encoding"] = 'Unbekanntes Encoding-Format: ';
+?>
diff --git a/site/vendors/phpmailer/language/phpmailer.lang-dk.php b/site/vendors/phpmailer/language/phpmailer.lang-dk.php
new file mode 100644
index 0000000..c5d33b5
--- /dev/null
+++ b/site/vendors/phpmailer/language/phpmailer.lang-dk.php
@@ -0,0 +1,24 @@
+<?php
+/**
+ * PHPMailer language file.
+ * Danish Version
+ * Author: Mikael Stokkebro <info@stokkebro.dk>
+ */
+
+$PHPMAILER_LANG = array();
+
+$PHPMAILER_LANG["provide_address"] = 'Du skal indtaste mindst en ' .
+ 'modtagers emailadresse.';
+$PHPMAILER_LANG["mailer_not_supported"] = ' mailer understøttes ikke.';
+$PHPMAILER_LANG["execute"] = 'Kunne ikke køre: ';
+$PHPMAILER_LANG["instantiate"] = 'Kunne ikke initialisere email funktionen.';
+$PHPMAILER_LANG["authenticate"] = 'SMTP fejl: Kunne ikke logge på.';
+$PHPMAILER_LANG["from_failed"] = 'Følgende afsenderadresse er forkert: ';
+$PHPMAILER_LANG["recipients_failed"] = 'SMTP fejl: Følgende' .
+ 'modtagere er forkerte: ';
+$PHPMAILER_LANG["data_not_accepted"] = 'SMTP fejl: Data kunne ikke accepteres.';
+$PHPMAILER_LANG["connect_host"] = 'SMTP fejl: Kunne ikke tilslutte SMTP serveren.';
+$PHPMAILER_LANG["file_access"] = 'Ingen adgang til fil: ';
+$PHPMAILER_LANG["file_open"] = 'Fil fejl: Kunne ikke åbne filen: ';
+$PHPMAILER_LANG["encoding"] = 'Ukendt encode-format: ';
+?> \ No newline at end of file
diff --git a/site/vendors/phpmailer/language/phpmailer.lang-en.php b/site/vendors/phpmailer/language/phpmailer.lang-en.php
new file mode 100644
index 0000000..14b677f
--- /dev/null
+++ b/site/vendors/phpmailer/language/phpmailer.lang-en.php
@@ -0,0 +1,23 @@
+<?php
+/**
+ * PHPMailer language file.
+ * English Version
+ */
+
+$PHPMAILER_LANG = array();
+
+$PHPMAILER_LANG["provide_address"] = 'You must provide at least one ' .
+ 'recipient email address.';
+$PHPMAILER_LANG["mailer_not_supported"] = ' mailer is not supported.';
+$PHPMAILER_LANG["execute"] = 'Could not execute: ';
+$PHPMAILER_LANG["instantiate"] = 'Could not instantiate mail function.';
+$PHPMAILER_LANG["authenticate"] = 'SMTP Error: Could not authenticate.';
+$PHPMAILER_LANG["from_failed"] = 'The following From address failed: ';
+$PHPMAILER_LANG["recipients_failed"] = 'SMTP Error: The following ' .
+ 'recipients failed: ';
+$PHPMAILER_LANG["data_not_accepted"] = 'SMTP Error: Data not accepted.';
+$PHPMAILER_LANG["connect_host"] = 'SMTP Error: Could not connect to SMTP host.';
+$PHPMAILER_LANG["file_access"] = 'Could not access file: ';
+$PHPMAILER_LANG["file_open"] = 'File Error: Could not open file: ';
+$PHPMAILER_LANG["encoding"] = 'Unknown encoding: ';
+?>
diff --git a/site/vendors/phpmailer/language/phpmailer.lang-es.php b/site/vendors/phpmailer/language/phpmailer.lang-es.php
new file mode 100644
index 0000000..2a496fa
--- /dev/null
+++ b/site/vendors/phpmailer/language/phpmailer.lang-es.php
@@ -0,0 +1,23 @@
+<?php
+/**
+ * PHPMailer language file.
+ * Versión en español
+ */
+
+$PHPMAILER_LANG = array();
+
+$PHPMAILER_LANG["provide_address"] = 'Debe proveer al menos una ' .
+ 'dirección de email como destinatario.';
+$PHPMAILER_LANG["mailer_not_supported"] = ' mailer no está soportado.';
+$PHPMAILER_LANG["execute"] = 'No puedo ejecutar: ';
+$PHPMAILER_LANG["instantiate"] = 'No pude crear una instancia de la función Mail.';
+$PHPMAILER_LANG["authenticate"] = 'Error SMTP: No se pudo autentificar.';
+$PHPMAILER_LANG["from_failed"] = 'La(s) siguiente(s) direcciones de remitente fallaron: ';
+$PHPMAILER_LANG["recipients_failed"] = 'Error SMTP: Los siguientes ' .
+ 'destinatarios fallaron: ';
+$PHPMAILER_LANG["data_not_accepted"] = 'Error SMTP: Datos no aceptados.';
+$PHPMAILER_LANG["connect_host"] = 'Error SMTP: No puedo conectar al servidor SMTP.';
+$PHPMAILER_LANG["file_access"] = 'No puedo acceder al archivo: ';
+$PHPMAILER_LANG["file_open"] = 'Error de Archivo: No puede abrir el archivo: ';
+$PHPMAILER_LANG["encoding"] = 'Codificación desconocida: ';
+?> \ No newline at end of file
diff --git a/site/vendors/phpmailer/language/phpmailer.lang-et.php b/site/vendors/phpmailer/language/phpmailer.lang-et.php
new file mode 100644
index 0000000..c6d2240
--- /dev/null
+++ b/site/vendors/phpmailer/language/phpmailer.lang-et.php
@@ -0,0 +1,22 @@
+<?php
+/**
+ * PHPMailer language file.
+ * Estonian Version
+ * By Indrek P&auml;ri
+ */
+
+$PHPMAILER_LANG = array();
+
+$PHPMAILER_LANG["provide_address"] = 'Te peate m&auml;&auml;rama v&auml;hemalt &uuml;he saaja e-posti aadressi.';
+$PHPMAILER_LANG["mailer_not_supported"] = ' maileri tugi puudub.';
+$PHPMAILER_LANG["execute"] = 'Tegevus eba&otilde;nnestus: ';
+$PHPMAILER_LANG["instantiate"] = 'mail funktiooni k&auml;ivitamine eba&otilde;nnestus.';
+$PHPMAILER_LANG["authenticate"] = 'SMTP Viga: Autoriseerimise viga.';
+$PHPMAILER_LANG["from_failed"] = 'J&auml;rgnev saatja e-posti aadress on vigane: ';
+$PHPMAILER_LANG["recipients_failed"] = 'SMTP Viga: J&auml;rgnevate saajate e-posti aadressid on vigased: ';
+$PHPMAILER_LANG["data_not_accepted"] = 'SMTP Viga: Vigased andmed.';
+$PHPMAILER_LANG["connect_host"] = 'SMTP Viga: Ei &otilde;nnestunud luua &uuml;hendust SMTP serveriga.';
+$PHPMAILER_LANG["file_access"] = 'Pole piisavalt &otilde;iguseid j&auml;rgneva faili avamiseks: ';
+$PHPMAILER_LANG["file_open"] = 'Faili Viga: Faili avamine eba&otilde;nnestus: ';
+$PHPMAILER_LANG["encoding"] = 'Tundmatu Unknown kodeering: ';
+?>
diff --git a/site/vendors/phpmailer/language/phpmailer.lang-fi.php b/site/vendors/phpmailer/language/phpmailer.lang-fi.php
new file mode 100644
index 0000000..cdb4fc2
--- /dev/null
+++ b/site/vendors/phpmailer/language/phpmailer.lang-fi.php
@@ -0,0 +1,23 @@
+<?php
+/**
+ * PHPMailer language file.
+ * Finnish Version
+ * By Jyry Kuukanen
+ */
+
+$PHPMAILER_LANG = array();
+
+$PHPMAILER_LANG["provide_address"] = 'Aseta v&auml;hint&auml;&auml;n yksi vastaanottajan ' .
+ 's&auml;hk&ouml;postiosoite.';
+$PHPMAILER_LANG["mailer_not_supported"] = 'postiv&auml;litintyyppi&auml; ei tueta.';
+$PHPMAILER_LANG["execute"] = 'Suoritus ep&auml;onnistui: ';
+$PHPMAILER_LANG["instantiate"] = 'mail-funktion luonti ep&auml;onnistui.';
+$PHPMAILER_LANG["authenticate"] = 'SMTP-virhe: k&auml;ytt&auml;j&auml;tunnistus ep&auml;onnistui.';
+$PHPMAILER_LANG["from_failed"] = 'Seuraava l&auml;hett&auml;j&auml;n osoite on virheellinen: ';
+$PHPMAILER_LANG["recipients_failed"] = 'SMTP-virhe: seuraava vastaanottaja osoite on virheellinen.';
+$PHPMAILER_LANG["data_not_accepted"] = 'SMTP-virhe: data on virheellinen.';
+$PHPMAILER_LANG["connect_host"] = 'SMTP-virhe: yhteys palvelimeen ei onnistu.';
+$PHPMAILER_LANG["file_access"] = 'Seuraavaan tiedostoon ei ole oikeuksia: ';
+$PHPMAILER_LANG["file_open"] = 'Tiedostovirhe: Ei voida avata tiedostoa: ';
+$PHPMAILER_LANG["encoding"] = 'Tuntematon koodaustyyppi: ';
+?> \ No newline at end of file
diff --git a/site/vendors/phpmailer/language/phpmailer.lang-fo.php b/site/vendors/phpmailer/language/phpmailer.lang-fo.php
new file mode 100644
index 0000000..fb257ad
--- /dev/null
+++ b/site/vendors/phpmailer/language/phpmailer.lang-fo.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * PHPMailer language file.
+ * Faroese Version [language of the Faroe Islands, a Danish dominion]
+ * This file created: 11-06-2004
+ * Supplied by Dávur Sørensen [www.profo-webdesign.dk]
+ */
+
+$PHPMAILER_LANG = array();
+
+$PHPMAILER_LANG["provide_address"] = 'Tú skal uppgeva minst ' .
+ 'móttakara-emailadressu(r).';
+$PHPMAILER_LANG["mailer_not_supported"] = ' er ikki supporterað.';
+$PHPMAILER_LANG["execute"] = 'Kundi ikki útføra: ';
+$PHPMAILER_LANG["instantiate"] = 'Kuni ikki instantiera mail funktión.';
+$PHPMAILER_LANG["authenticate"] = 'SMTP feilur: Kundi ikki góðkenna.';
+$PHPMAILER_LANG["from_failed"] = 'fylgjandi Frá/From adressa miseydnaðist: ';
+$PHPMAILER_LANG["recipients_failed"] = 'SMTP Feilur: Fylgjandi ' .
+ 'móttakarar miseydnaðust: ';
+$PHPMAILER_LANG["data_not_accepted"] = 'SMTP feilur: Data ikki góðkent.';
+$PHPMAILER_LANG["connect_host"] = 'SMTP feilur: Kundi ikki knýta samband við SMTP vert.';
+$PHPMAILER_LANG["file_access"] = 'Kundi ikki tilganga fílu: ';
+$PHPMAILER_LANG["file_open"] = 'Fílu feilur: Kundi ikki opna fílu: ';
+$PHPMAILER_LANG["encoding"] = 'Ókend encoding: ';
+?>
diff --git a/site/vendors/phpmailer/language/phpmailer.lang-fr.php b/site/vendors/phpmailer/language/phpmailer.lang-fr.php
new file mode 100644
index 0000000..ea4008f
--- /dev/null
+++ b/site/vendors/phpmailer/language/phpmailer.lang-fr.php
@@ -0,0 +1,24 @@
+<?php
+/**
+ * PHPMailer language file.
+ * French Version
+ * bruno@ioda-net.ch 09.08.2003
+ */
+
+$PHPMAILER_LANG = array();
+
+$PHPMAILER_LANG["provide_address"] = 'Vous devez fournir au moins ' .
+ 'une adresse de destinataire.';
+$PHPMAILER_LANG["mailer_not_supported"] = ' mailer non supporté.';
+$PHPMAILER_LANG["execute"] = 'Ne peut pas lancer l\'exécution: ';
+$PHPMAILER_LANG["instantiate"] = 'Impossible d\'instancier la fonction mail.';
+$PHPMAILER_LANG["authenticate"] = 'SMTP Erreur: Echec de l\'authentification.';
+$PHPMAILER_LANG["from_failed"] = 'L\'adresse From suivante a échoué : ';
+$PHPMAILER_LANG["recipients_failed"] = 'SMTP Erreur: Les destinataires ' .
+ 'suivants sont en erreur : ';
+$PHPMAILER_LANG["data_not_accepted"] = 'SMTP Erreur: Data non acceptée.';
+$PHPMAILER_LANG["connect_host"] = 'SMTP Erreur: Impossible de connecter le serveur SMTP .';
+$PHPMAILER_LANG["file_access"] = 'N\'arrive pas à accéder au fichier: ';
+$PHPMAILER_LANG["file_open"] = 'Erreur Fichier: ouverture impossible: ';
+$PHPMAILER_LANG["encoding"] = 'Encodage inconnu: ';
+?>
diff --git a/site/vendors/phpmailer/language/phpmailer.lang-hu.php b/site/vendors/phpmailer/language/phpmailer.lang-hu.php
new file mode 100644
index 0000000..ff17a6b
--- /dev/null
+++ b/site/vendors/phpmailer/language/phpmailer.lang-hu.php
@@ -0,0 +1,23 @@
+<?php
+/**
+ * PHPMailer language file.
+ * Hungarian Version
+ */
+
+$PHPMAILER_LANG = array();
+
+$PHPMAILER_LANG["provide_address"] = 'Meg kell adnod legalább egy ' .
+ 'címzett email címet.';
+$PHPMAILER_LANG["mailer_not_supported"] = ' levelezõ nem támogatott.';
+$PHPMAILER_LANG["execute"] = 'Nem tudtam végrehajtani: ';
+$PHPMAILER_LANG["instantiate"] = 'Nem sikerült példányosítani a mail funkciót.';
+$PHPMAILER_LANG["authenticate"] = 'SMTP Hiba: Sikertelen autentikáció.';
+$PHPMAILER_LANG["from_failed"] = 'Az alábbi Feladó cím hibás: ';
+$PHPMAILER_LANG["recipients_failed"] = 'SMTP Hiba: Az alábbi ' .
+ 'címzettek hibásak: ';
+$PHPMAILER_LANG["data_not_accepted"] = 'SMTP Hiba: Nem elfogadható adat.';
+$PHPMAILER_LANG["connect_host"] = 'SMTP Hiba: Nem tudtam csatlakozni az SMTP host-hoz.';
+$PHPMAILER_LANG["file_access"] = 'Nem sikerült elérni a következõ fájlt: ';
+$PHPMAILER_LANG["file_open"] = 'Fájl Hiba: Nem sikerült megnyitni a következõ fájlt: ';
+$PHPMAILER_LANG["encoding"] = 'Ismeretlen kódolás: ';
+?> \ No newline at end of file
diff --git a/site/vendors/phpmailer/language/phpmailer.lang-it.php b/site/vendors/phpmailer/language/phpmailer.lang-it.php
new file mode 100644
index 0000000..16edbf0
--- /dev/null
+++ b/site/vendors/phpmailer/language/phpmailer.lang-it.php
@@ -0,0 +1,28 @@
+<?php
+/**
+* PHPMailer language file.
+* Italian version
+* @package PHPMailer
+* @author Ilias Bartolini <brain79@inwind.it>
+*/
+
+$PHPMAILER_LANG = array();
+
+$PHPMAILER_LANG["provide_address"] = 'Deve essere fornito almeno un'.
+ ' indirizzo ricevente';
+$PHPMAILER_LANG["mailer_not_supported"] = 'Mailer non supportato';
+$PHPMAILER_LANG["execute"] = "Impossibile eseguire l'operazione: ";
+$PHPMAILER_LANG["instantiate"] = 'Impossibile istanziare la funzione mail';
+$PHPMAILER_LANG["authenticate"] = 'SMTP Error: Impossibile autenticarsi.';
+$PHPMAILER_LANG["from_failed"] = 'I seguenti indirizzi mittenti hanno'.
+ ' generato errore: ';
+$PHPMAILER_LANG["recipients_failed"] = 'SMTP Error: I seguenti indirizzi'.
+ 'destinatari hanno generato errore: ';
+$PHPMAILER_LANG["data_not_accepted"] = 'SMTP Error: Data non accettati dal'.
+ 'server.';
+$PHPMAILER_LANG["connect_host"] = 'SMTP Error: Impossibile connettersi'.
+ ' all\'host SMTP.';
+$PHPMAILER_LANG["file_access"] = 'Impossibile accedere al file: ';
+$PHPMAILER_LANG["file_open"] = 'File Error: Impossibile aprire il file: ';
+$PHPMAILER_LANG["encoding"] = 'Encoding set dei caratteri sconosciuto: ';
+?>
diff --git a/site/vendors/phpmailer/language/phpmailer.lang-ja.php b/site/vendors/phpmailer/language/phpmailer.lang-ja.php
new file mode 100644
index 0000000..9e90d63
--- /dev/null
+++ b/site/vendors/phpmailer/language/phpmailer.lang-ja.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * PHPMailer language file.
+ * Japanese Version
+ * By Mitsuhiro Yoshida - http://mitstek.com/
+ * This file is written in EUC-JP.
+ */
+
+$PHPMAILER_LANG = array();
+
+$PHPMAILER_LANG["provide_address"] = '¾¯¤Ê¤¯¤È¤â1¤Ä¥á¡¼¥ë¥¢¥É¥ì¥¹¤ò' .
+ '»ØÄꤹ¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£';
+$PHPMAILER_LANG["mailer_not_supported"] = ' ¥á¡¼¥é¡¼¤¬¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤Þ¤»¤ó¡£';
+$PHPMAILER_LANG["execute"] = '¼Â¹Ô¤Ç¤­¤Þ¤»¤ó¤Ç¤·¤¿: ';
+$PHPMAILER_LANG["instantiate"] = '¥á¡¼¥ë´Ø¿ô¤¬Àµ¾ï¤ËÆ°ºî¤·¤Þ¤»¤ó¤Ç¤·¤¿¡£';
+$PHPMAILER_LANG["authenticate"] = 'SMTP¥¨¥é¡¼: ǧ¾Ú¤Ç¤­¤Þ¤»¤ó¤Ç¤·¤¿¡£';
+$PHPMAILER_LANG["from_failed"] = '¼¡¤ÎFrom¥¢¥É¥ì¥¹¤Ë´Ö°ã¤¤¤¬¤¢¤ê¤Þ¤¹: ';
+$PHPMAILER_LANG["recipients_failed"] = 'SMTP¥¨¥é¡¼: ¼¡¤Î¼õ¿®¼Ô¥¢¥É¥ì¥¹¤Ë ' .
+ '´Ö°ã¤¤¤¬¤¢¤ê¤Þ¤¹: ';
+$PHPMAILER_LANG["data_not_accepted"] = 'SMTP¥¨¥é¡¼: ¥Ç¡¼¥¿¤¬¼õ¤±ÉÕ¤±¤é¤ì¤Þ¤»¤ó¤Ç¤·¤¿¡£';
+$PHPMAILER_LANG["connect_host"] = 'SMTP¥¨¥é¡¼: SMTP¥Û¥¹¥È¤ËÀܳ¤Ç¤­¤Þ¤»¤ó¤Ç¤·¤¿¡£';
+$PHPMAILER_LANG["file_access"] = '¥Õ¥¡¥¤¥ë¤Ë¥¢¥¯¥»¥¹¤Ç¤­¤Þ¤»¤ó: ';
+$PHPMAILER_LANG["file_open"] = '¥Õ¥¡¥¤¥ë¥¨¥é¡¼: ¥Õ¥¡¥¤¥ë¤ò³«¤±¤Þ¤»¤ó: ';
+$PHPMAILER_LANG["encoding"] = 'ÉÔÌÀ¤Ê¥¨¥ó¥³¡¼¥Ç¥£¥ó¥°: ';
+?> \ No newline at end of file
diff --git a/site/vendors/phpmailer/language/phpmailer.lang-nl.php b/site/vendors/phpmailer/language/phpmailer.lang-nl.php
new file mode 100644
index 0000000..eef11f0
--- /dev/null
+++ b/site/vendors/phpmailer/language/phpmailer.lang-nl.php
@@ -0,0 +1,23 @@
+<?php
+/**
+ * PHPMailer language file.
+ * Dutch Version
+ */
+
+$PHPMAILER_LANG = array();
+
+$PHPMAILER_LANG["provide_address"] = 'Er moet tenmiste &eacute;&eacute;n ' .
+ 'ontvanger emailadres opgegeven worden.';
+$PHPMAILER_LANG["mailer_not_supported"] = ' mailer wordt niet ondersteund.';
+$PHPMAILER_LANG["execute"] = 'Kon niet uitvoeren: ';
+$PHPMAILER_LANG["instantiate"] = 'Kon mail functie niet initialiseren.';
+$PHPMAILER_LANG["authenticate"] = 'SMTP Fout: authenticatie mislukt.';
+$PHPMAILER_LANG["from_failed"] = 'De volgende afzender adressen zijn mislukt: ';
+$PHPMAILER_LANG["recipients_failed"] = 'SMTP Fout: De volgende ' .
+ 'ontvangers zijn mislukt: ';
+$PHPMAILER_LANG["data_not_accepted"] = 'SMTP Fout: Data niet geaccepteerd.';
+$PHPMAILER_LANG["connect_host"] = 'SMTP Fout: Kon niet verbinden met SMTP host.';
+$PHPMAILER_LANG["file_access"] = 'Kreeg geen toegang tot bestand: ';
+$PHPMAILER_LANG["file_open"] = 'Bestandsfout: Kon bestand niet openen: ';
+$PHPMAILER_LANG["encoding"] = 'Onbekende codering: ';
+?> \ No newline at end of file
diff --git a/site/vendors/phpmailer/language/phpmailer.lang-no.php b/site/vendors/phpmailer/language/phpmailer.lang-no.php
new file mode 100644
index 0000000..972fac4
--- /dev/null
+++ b/site/vendors/phpmailer/language/phpmailer.lang-no.php
@@ -0,0 +1,23 @@
+<?php
+/**
+ * PHPMailer language file.
+ * Norwegian Version
+ */
+
+$PHPMAILER_LANG = array();
+
+$PHPMAILER_LANG["provide_address"] = 'Du må ha med minst en' .
+ 'mottager adresse.';
+$PHPMAILER_LANG["mailer_not_supported"] = ' mailer er ikke supportert.';
+$PHPMAILER_LANG["execute"] = 'Kunne ikke utføre: ';
+$PHPMAILER_LANG["instantiate"] = 'Kunne ikke instantiate mail funksjonen.';
+$PHPMAILER_LANG["authenticate"] = 'SMTP Feil: Kunne ikke authentisere.';
+$PHPMAILER_LANG["from_failed"] = 'Følgende Fra feilet: ';
+$PHPMAILER_LANG["recipients_failed"] = 'SMTP Feil: Følgende' .
+ 'mottagere feilet: ';
+$PHPMAILER_LANG["data_not_accepted"] = 'SMTP Feil: Data ble ikke akseptert.';
+$PHPMAILER_LANG["connect_host"] = 'SMTP Feil: Kunne ikke koble til SMTP host.';
+$PHPMAILER_LANG["file_access"] = 'Kunne ikke få tilgang til filen: ';
+$PHPMAILER_LANG["file_open"] = 'Fil feil: Kunne ikke åpne filen: ';
+$PHPMAILER_LANG["encoding"] = 'Ukjent encoding: ';
+?>
diff --git a/site/vendors/phpmailer/language/phpmailer.lang-pl.php b/site/vendors/phpmailer/language/phpmailer.lang-pl.php
new file mode 100644
index 0000000..960f2ff
--- /dev/null
+++ b/site/vendors/phpmailer/language/phpmailer.lang-pl.php
@@ -0,0 +1,24 @@
+<?php
+/**
+ * PHPMailer language file.
+ * Polish Version, encoding: windows-1250
+ * translated from english lang file ver. 1.72
+ */
+
+$PHPMAILER_LANG = array();
+
+$PHPMAILER_LANG["provide_address"] = 'Nale¿y podaæ prawid³owy adres email Odbiorcy.';
+$PHPMAILER_LANG["mailer_not_supported"] = 'Wybrana metoda wysy³ki wiadomoœci nie jest obs³ugiwana.';
+$PHPMAILER_LANG["execute"] = 'Nie mo¿na uruchomiæ: ';
+$PHPMAILER_LANG["instantiate"] = 'Nie mo¿na wywo³aæ funkcji mail(). SprawdŸ konfiguracjê serwera.';
+$PHPMAILER_LANG["authenticate"] = 'B³¹d SMTP: Nie mo¿na przeprowadziæ autentykacji.';
+$PHPMAILER_LANG["from_failed"] = 'Nastêpuj¹cy adres Nadawcy jest jest nieprawid³owy: ';
+$PHPMAILER_LANG["recipients_failed"] = 'B³¹d SMTP: Nastêpuj¹cy ' .
+ 'odbiorcy s¹ nieprawid³owi: ';
+$PHPMAILER_LANG["data_not_accepted"] = 'B³¹d SMTP: Dane nie zosta³y przyjête.';
+$PHPMAILER_LANG["connect_host"] = 'B³¹d SMTP: Nie mo¿na po³¹czyæ siê z wybranym hostem.';
+$PHPMAILER_LANG["file_access"] = 'Brak dostêpu do pliku: ';
+$PHPMAILER_LANG["file_open"] = 'Nie mo¿na otworzyæ pliku: ';
+$PHPMAILER_LANG["encoding"] = 'Nieznany sposób kodowania znaków: ';
+
+?> \ No newline at end of file
diff --git a/site/vendors/phpmailer/language/phpmailer.lang-ro.php b/site/vendors/phpmailer/language/phpmailer.lang-ro.php
new file mode 100644
index 0000000..871eac0
--- /dev/null
+++ b/site/vendors/phpmailer/language/phpmailer.lang-ro.php
@@ -0,0 +1,23 @@
+<?php
+/**
+ * PHPMailer language file.
+ * Romanian Version
+ * @package PHPMailer
+ * @author Catalin Constantin <catalin@dazoot.ro>
+ */
+
+$PHPMAILER_LANG = array();
+
+$PHPMAILER_LANG["provide_address"] = 'Trebuie sa adaugati cel putin un recipient (adresa de mail).';
+$PHPMAILER_LANG["mailer_not_supported"] = ' mailer nu este suportat.';
+$PHPMAILER_LANG["execute"] = 'Nu pot executa: ';
+$PHPMAILER_LANG["instantiate"] = 'Nu am putut instantia functia mail.';
+$PHPMAILER_LANG["authenticate"] = 'Eroare SMTP: Nu a functionat autentificarea.';
+$PHPMAILER_LANG["from_failed"] = 'Urmatoarele adrese From au dat eroare: ';
+$PHPMAILER_LANG["recipients_failed"] = 'Eroare SMTP: Urmatoarele adrese de mail au dat eroare: ';
+$PHPMAILER_LANG["data_not_accepted"] = 'Eroare SMTP: Continutul mailului nu a fost acceptat.';
+$PHPMAILER_LANG["connect_host"] = 'Eroare SMTP: Nu m-am putut conecta la adresa SMTP.';
+$PHPMAILER_LANG["file_access"] = 'Nu pot accesa fisierul: ';
+$PHPMAILER_LANG["file_open"] = 'Eroare de fisier: Nu pot deschide fisierul: ';
+$PHPMAILER_LANG["encoding"] = 'Encodare necunoscuta: ';
+?>
diff --git a/site/vendors/phpmailer/language/phpmailer.lang-ru.php b/site/vendors/phpmailer/language/phpmailer.lang-ru.php
new file mode 100644
index 0000000..3caf528
--- /dev/null
+++ b/site/vendors/phpmailer/language/phpmailer.lang-ru.php
@@ -0,0 +1,23 @@
+<?php
+/**
+ * PHPMailer language file.
+ * Russian Version by Alexey Chumakov <alex@chumakov.ru>
+ */
+
+$PHPMAILER_LANG = array();
+$PHPMAILER_LANG["provide_address"] = 'Ïîæàëóéñòà, ââåäèòå õîòÿ áû îäèí àäðåñ e-mail ' .
+ 'ïîëó÷àòåëÿ.';
+$PHPMAILER_LANG["mailer_not_supported"] = ' - ïî÷òîâûé ñåðâåð íå ïîääåðæèâàåòñÿ.';
+$PHPMAILER_LANG["execute"] = 'Íåâîçìîæíî âûïîëíèòü êîìàíäó: ';
+$PHPMAILER_LANG["instantiate"] = 'Íåâîçìîæíî çàïóñòèòü ôóíêöèþ mail.';
+$PHPMAILER_LANG["authenticate"] = 'Îøèáêà SMTP: îøèáêà àâòîðèçàöèè.';
+$PHPMAILER_LANG["from_failed"] = 'Íåâåðíûé àäðåñ îòïðàâèòåëÿ: ';
+$PHPMAILER_LANG["recipients_failed"] = 'Îøèáêà SMTP: îòïðàâêà ïî ñëåäóþùèì ' .
+ 'àäðåñàì ïîëó÷àòåëåé íå óäàëàñü: ';
+$PHPMAILER_LANG["data_not_accepted"] = 'Îøèáêà SMTP: äàííûå íå ïðèíÿòû.';
+$PHPMAILER_LANG["connect_host"] = 'Îøèáêà SMTP: íå óäàåòñÿ ïîäêëþ÷èòüñÿ ê ñåðâåðó SMTP.';
+$PHPMAILER_LANG["file_access"] = 'Íåò äîñòóïà ê ôàéëó: ';
+$PHPMAILER_LANG["file_open"] = 'Ôàéëîâàÿ îøèáêà: íå óäàåòñÿ îòêðûòü ôàéë: ';
+$PHPMAILER_LANG["encoding"] = 'Íåèçâåñòíûé âèä êîäèðîâêè: ';
+?>
+
diff --git a/site/vendors/phpmailer/language/phpmailer.lang-se.php b/site/vendors/phpmailer/language/phpmailer.lang-se.php
new file mode 100644
index 0000000..e41778b
--- /dev/null
+++ b/site/vendors/phpmailer/language/phpmailer.lang-se.php
@@ -0,0 +1,24 @@
+<?php
+/**
+ * PHPMailer language file.
+ * Swedish Version
+ * Author: Johan Linnér <johan@linner.biz>
+ */
+
+$PHPMAILER_LANG = array();
+
+$PHPMAILER_LANG["provide_address"] = 'Du måste ange minst en ' .
+ 'mottagares e-postadress.';
+$PHPMAILER_LANG["mailer_not_supported"] = ' mailer stöds inte.';
+$PHPMAILER_LANG["execute"] = 'Kunde inte köra: ';
+$PHPMAILER_LANG["instantiate"] = 'Kunde inte initiera e-postfunktion.';
+$PHPMAILER_LANG["authenticate"] = 'SMTP fel: Kunde inte autentisera.';
+$PHPMAILER_LANG["from_failed"] = 'Följande avsändaradress är felaktig: ';
+$PHPMAILER_LANG["recipients_failed"] = 'SMTP fel: Följande ' .
+ 'mottagare är felaktig: ';
+$PHPMAILER_LANG["data_not_accepted"] = 'SMTP fel: Data accepterades inte.';
+$PHPMAILER_LANG["connect_host"] = 'SMTP fel: Kunde inte ansluta till SMTP-server.';
+$PHPMAILER_LANG["file_access"] = 'Ingen åtkomst till fil: ';
+$PHPMAILER_LANG["file_open"] = 'Fil fel: Kunde inte öppna fil: ';
+$PHPMAILER_LANG["encoding"] = 'Okänt encode-format: ';
+?> \ No newline at end of file
diff --git a/site/vendors/phpmailer/language/phpmailer.lang-tr.php b/site/vendors/phpmailer/language/phpmailer.lang-tr.php
new file mode 100644
index 0000000..05bf6a2
--- /dev/null
+++ b/site/vendors/phpmailer/language/phpmailer.lang-tr.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * PHPMailer dil dosyasý.
+ * Türkçe Versiyonu
+ * ÝZYAZILIM - Elçin Özel - Can Yýlmaz - Mehmet Benlioðlu
+ */
+
+$PHPMAILER_LANG = array();
+
+$PHPMAILER_LANG["provide_address"] = 'En az bir tane mail adresi belirtmek zorundasýnýz ' .
+ 'alýcýnýn email adresi.';
+$PHPMAILER_LANG["mailer_not_supported"] = ' mailler desteklenmemektedir.';
+$PHPMAILER_LANG["execute"] = 'Çalýþtýrýlamýyor: ';
+$PHPMAILER_LANG["instantiate"] = 'Örnek mail fonksiyonu yaratýlamadý.';
+$PHPMAILER_LANG["authenticate"] = 'SMTP Hatasý: Doðrulanamýyor.';
+$PHPMAILER_LANG["from_failed"] = 'Baþarýsýz olan gönderici adresi: ';
+$PHPMAILER_LANG["recipients_failed"] = 'SMTP Hatasý: ' .
+ 'alýcýlara ulaþmadý: ';
+$PHPMAILER_LANG["data_not_accepted"] = 'SMTP Hatasý: Veri kabul edilmedi.';
+$PHPMAILER_LANG["connect_host"] = 'SMTP Hatasý: SMTP hosta baðlanýlamýyor.';
+$PHPMAILER_LANG["file_access"] = 'Dosyaya eriþilemiyor: ';
+$PHPMAILER_LANG["file_open"] = 'Dosya Hatasý: Dosya açýlamýyor: ';
+$PHPMAILER_LANG["encoding"] = 'Bilinmeyen þifreleme: ';
+
+?> \ No newline at end of file
diff --git a/site/vendors/phpmailer/phpdoc/PHPMailer/PHPMailer.html b/site/vendors/phpmailer/phpdoc/PHPMailer/PHPMailer.html
new file mode 100644
index 0000000..87be402
--- /dev/null
+++ b/site/vendors/phpmailer/phpdoc/PHPMailer/PHPMailer.html
@@ -0,0 +1,1475 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+ <html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <!-- template designed by Marco Von Ballmoos -->
+ <title>Docs For Class PHPMailer</title>
+ <link rel="stylesheet" href="../media/stylesheet.css" />
+ <meta http-equiv='Content-Type' content='text/html; charset=iso-8859-1'/>
+ </head>
+ <body>
+ <div class="page-body">
+<h2 class="class-name">Class PHPMailer</h2>
+
+<a name="sec-description"></a>
+<div class="info-box">
+ <div class="info-box-title">Description</div>
+ <div class="nav-bar">
+ <span class="disabled">Description</span> |
+ <a href="#sec-var-summary">Vars</a> (<a href="#sec-vars">details</a>)
+ | <a href="#sec-method-summary">Methods</a> (<a href="#sec-methods">details</a>)
+
+ </div>
+ <div class="info-box-body">
+ <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">PHPMailer - PHP email transport class</p>
+ <ul class="tags">
+ <li><span class="field">copyright:</span> <p>2001 - 2003 Brent R. Matzelle</p></li>
+ <li><span class="field">author:</span> <p>Brent R. Matzelle</p></li>
+ </ul>
+ <p class="notes">
+ Located in <a class="field" href="_class_phpmailer_php.html">Program_Root/class.phpmailer.php</a> (line <span class="field">20</span>)
+ </p>
+
+
+ <pre></pre>
+
+ </div>
+</div>
+
+
+ <a name="sec-var-summary"></a>
+ <div class="info-box">
+ <div class="info-box-title">Variable Summary</span></div>
+ <div class="nav-bar">
+ <a href="#sec-description">Description</a> |
+ <span class="disabled">Vars</span> (<a href="#sec-vars">details</a>)
+ |
+ <a href="#sec-method-summary">Methods</a> (<a href="#sec-methods">details</a>)
+
+ </div>
+ <div class="info-box-body">
+ <div class="var-summary">
+ <div class="var-title">
+ <span class="var-type">string</span>
+ <a href="#$AltBody" title="details" class="var-name">$AltBody</a>
+ </div>
+ <div class="var-title">
+ <span class="var-type">string</span>
+ <a href="#$Body" title="details" class="var-name">$Body</a>
+ </div>
+ <div class="var-title">
+ <span class="var-type">string</span>
+ <a href="#$CharSet" title="details" class="var-name">$CharSet</a>
+ </div>
+ <div class="var-title">
+ <span class="var-type">string</span>
+ <a href="#$ConfirmReadingTo" title="details" class="var-name">$ConfirmReadingTo</a>
+ </div>
+ <div class="var-title">
+ <span class="var-type">string</span>
+ <a href="#$ContentType" title="details" class="var-name">$ContentType</a>
+ </div>
+ <div class="var-title">
+ <span class="var-type">string</span>
+ <a href="#$Encoding" title="details" class="var-name">$Encoding</a>
+ </div>
+ <div class="var-title">
+ <span class="var-type">string</span>
+ <a href="#$ErrorInfo" title="details" class="var-name">$ErrorInfo</a>
+ </div>
+ <div class="var-title">
+ <span class="var-type">string</span>
+ <a href="#$From" title="details" class="var-name">$From</a>
+ </div>
+ <div class="var-title">
+ <span class="var-type">string</span>
+ <a href="#$FromName" title="details" class="var-name">$FromName</a>
+ </div>
+ <div class="var-title">
+ <span class="var-type">string</span>
+ <a href="#$Helo" title="details" class="var-name">$Helo</a>
+ </div>
+ <div class="var-title">
+ <span class="var-type">string</span>
+ <a href="#$Host" title="details" class="var-name">$Host</a>
+ </div>
+ <div class="var-title">
+ <span class="var-type">string</span>
+ <a href="#$Hostname" title="details" class="var-name">$Hostname</a>
+ </div>
+ <div class="var-title">
+ <span class="var-type">string</span>
+ <a href="#$Mailer" title="details" class="var-name">$Mailer</a>
+ </div>
+ <div class="var-title">
+ <span class="var-type">string</span>
+ <a href="#$Password" title="details" class="var-name">$Password</a>
+ </div>
+ <div class="var-title">
+ <span class="var-type">string</span>
+ <a href="#$PluginDir" title="details" class="var-name">$PluginDir</a>
+ </div>
+ <div class="var-title">
+ <span class="var-type">int</span>
+ <a href="#$Port" title="details" class="var-name">$Port</a>
+ </div>
+ <div class="var-title">
+ <span class="var-type">int</span>
+ <a href="#$Priority" title="details" class="var-name">$Priority</a>
+ </div>
+ <div class="var-title">
+ <span class="var-type">string</span>
+ <a href="#$Sender" title="details" class="var-name">$Sender</a>
+ </div>
+ <div class="var-title">
+ <span class="var-type">string</span>
+ <a href="#$Sendmail" title="details" class="var-name">$Sendmail</a>
+ </div>
+ <div class="var-title">
+ <span class="var-type">bool</span>
+ <a href="#$SMTPAuth" title="details" class="var-name">$SMTPAuth</a>
+ </div>
+ <div class="var-title">
+ <span class="var-type">bool</span>
+ <a href="#$SMTPDebug" title="details" class="var-name">$SMTPDebug</a>
+ </div>
+ <div class="var-title">
+ <span class="var-type">bool</span>
+ <a href="#$SMTPKeepAlive" title="details" class="var-name">$SMTPKeepAlive</a>
+ </div>
+ <div class="var-title">
+ <span class="var-type">string</span>
+ <a href="#$Subject" title="details" class="var-name">$Subject</a>
+ </div>
+ <div class="var-title">
+ <span class="var-type">int</span>
+ <a href="#$Timeout" title="details" class="var-name">$Timeout</a>
+ </div>
+ <div class="var-title">
+ <span class="var-type">string</span>
+ <a href="#$Username" title="details" class="var-name">$Username</a>
+ </div>
+ <div class="var-title">
+ <span class="var-type">string</span>
+ <a href="#$Version" title="details" class="var-name">$Version</a>
+ </div>
+ <div class="var-title">
+ <span class="var-type">int</span>
+ <a href="#$WordWrap" title="details" class="var-name">$WordWrap</a>
+ </div>
+ </div>
+ </div>
+ </div>
+
+ <a name="sec-method-summary"></a>
+ <div class="info-box">
+ <div class="info-box-title">Method Summary</span></div>
+ <div class="nav-bar">
+ <a href="#sec-description">Description</a> |
+ <a href="#sec-var-summary">Vars</a> (<a href="#sec-vars">details</a>)
+
+ |
+ <span class="disabled">Methods</span> (<a href="#sec-methods">details</a>)
+ </div>
+ <div class="info-box-body">
+ <div class="method-summary">
+
+ <div class="method-definition">
+ <span class="method-result">void</span>
+ <a href="#AddAddress" title="details" class="method-name">AddAddress</a>
+ (<span class="var-type">string</span>&nbsp;<span class="var-name">$address</span>, [<span class="var-type">string</span>&nbsp;<span class="var-name">$name</span> = <span class="var-default">""</span>])
+ </div>
+
+ <div class="method-definition">
+ <span class="method-result">bool</span>
+ <a href="#AddAttachment" title="details" class="method-name">AddAttachment</a>
+ (<span class="var-type">string</span>&nbsp;<span class="var-name">$path</span>, [<span class="var-type">string</span>&nbsp;<span class="var-name">$name</span> = <span class="var-default">""</span>], [<span class="var-type">string</span>&nbsp;<span class="var-name">$encoding</span> = <span class="var-default">"base64"</span>], [<span class="var-type">string</span>&nbsp;<span class="var-name">$type</span> = <span class="var-default">"application/octet-stream"</span>])
+ </div>
+
+ <div class="method-definition">
+ <span class="method-result">void</span>
+ <a href="#AddBCC" title="details" class="method-name">AddBCC</a>
+ (<span class="var-type">string</span>&nbsp;<span class="var-name">$address</span>, [<span class="var-type">string</span>&nbsp;<span class="var-name">$name</span> = <span class="var-default">""</span>])
+ </div>
+
+ <div class="method-definition">
+ <span class="method-result">void</span>
+ <a href="#AddCC" title="details" class="method-name">AddCC</a>
+ (<span class="var-type">string</span>&nbsp;<span class="var-name">$address</span>, [<span class="var-type">string</span>&nbsp;<span class="var-name">$name</span> = <span class="var-default">""</span>])
+ </div>
+
+ <div class="method-definition">
+ <span class="method-result">void</span>
+ <a href="#AddCustomHeader" title="details" class="method-name">AddCustomHeader</a>
+ (<span class="var-type">mixed</span>&nbsp;<span class="var-name">$custom_header</span>)
+ </div>
+
+ <div class="method-definition">
+ <span class="method-result">bool</span>
+ <a href="#AddEmbeddedImage" title="details" class="method-name">AddEmbeddedImage</a>
+ (<span class="var-type">string</span>&nbsp;<span class="var-name">$path</span>, <span class="var-type">string</span>&nbsp;<span class="var-name">$cid</span>, [<span class="var-type">string</span>&nbsp;<span class="var-name">$name</span> = <span class="var-default">""</span>], [<span class="var-type">string</span>&nbsp;<span class="var-name">$encoding</span> = <span class="var-default">"base64"</span>], [<span class="var-type">string</span>&nbsp;<span class="var-name">$type</span> = <span class="var-default">"application/octet-stream"</span>])
+ </div>
+
+ <div class="method-definition">
+ <span class="method-result">void</span>
+ <a href="#AddReplyTo" title="details" class="method-name">AddReplyTo</a>
+ (<span class="var-type">string</span>&nbsp;<span class="var-name">$address</span>, [<span class="var-type">string</span>&nbsp;<span class="var-name">$name</span> = <span class="var-default">""</span>])
+ </div>
+
+ <div class="method-definition">
+ <span class="method-result">void</span>
+ <a href="#AddStringAttachment" title="details" class="method-name">AddStringAttachment</a>
+ (<span class="var-type">string</span>&nbsp;<span class="var-name">$string</span>, <span class="var-type">string</span>&nbsp;<span class="var-name">$filename</span>, [<span class="var-type">string</span>&nbsp;<span class="var-name">$encoding</span> = <span class="var-default">"base64"</span>], [<span class="var-type">string</span>&nbsp;<span class="var-name">$type</span> = <span class="var-default">"application/octet-stream"</span>])
+ </div>
+
+ <div class="method-definition">
+ <span class="method-result">void</span>
+ <a href="#ClearAddresses" title="details" class="method-name">ClearAddresses</a>
+ ()
+ </div>
+
+ <div class="method-definition">
+ <span class="method-result">void</span>
+ <a href="#ClearAllRecipients" title="details" class="method-name">ClearAllRecipients</a>
+ ()
+ </div>
+
+ <div class="method-definition">
+ <span class="method-result">void</span>
+ <a href="#ClearAttachments" title="details" class="method-name">ClearAttachments</a>
+ ()
+ </div>
+
+ <div class="method-definition">
+ <span class="method-result">void</span>
+ <a href="#ClearBCCs" title="details" class="method-name">ClearBCCs</a>
+ ()
+ </div>
+
+ <div class="method-definition">
+ <span class="method-result">void</span>
+ <a href="#ClearCCs" title="details" class="method-name">ClearCCs</a>
+ ()
+ </div>
+
+ <div class="method-definition">
+ <span class="method-result">void</span>
+ <a href="#ClearCustomHeaders" title="details" class="method-name">ClearCustomHeaders</a>
+ ()
+ </div>
+
+ <div class="method-definition">
+ <span class="method-result">void</span>
+ <a href="#ClearReplyTos" title="details" class="method-name">ClearReplyTos</a>
+ ()
+ </div>
+
+ <div class="method-definition">
+ <span class="method-result">bool</span>
+ <a href="#IsError" title="details" class="method-name">IsError</a>
+ ()
+ </div>
+
+ <div class="method-definition">
+ <span class="method-result">void</span>
+ <a href="#IsHTML" title="details" class="method-name">IsHTML</a>
+ (<span class="var-type">bool</span>&nbsp;<span class="var-name">$bool</span>)
+ </div>
+
+ <div class="method-definition">
+ <span class="method-result">void</span>
+ <a href="#IsMail" title="details" class="method-name">IsMail</a>
+ ()
+ </div>
+
+ <div class="method-definition">
+ <span class="method-result">void</span>
+ <a href="#IsQmail" title="details" class="method-name">IsQmail</a>
+ ()
+ </div>
+
+ <div class="method-definition">
+ <span class="method-result">void</span>
+ <a href="#IsSendmail" title="details" class="method-name">IsSendmail</a>
+ ()
+ </div>
+
+ <div class="method-definition">
+ <span class="method-result">void</span>
+ <a href="#IsSMTP" title="details" class="method-name">IsSMTP</a>
+ ()
+ </div>
+
+ <div class="method-definition">
+ <span class="method-result">bool</span>
+ <a href="#Send" title="details" class="method-name">Send</a>
+ ()
+ </div>
+
+ <div class="method-definition">
+ <span class="method-result">bool</span>
+ <a href="#SetLanguage" title="details" class="method-name">SetLanguage</a>
+ (<span class="var-type">string</span>&nbsp;<span class="var-name">$lang_type</span>, [<span class="var-type">string</span>&nbsp;<span class="var-name">$lang_path</span> = <span class="var-default">""</span>])
+ </div>
+
+ <div class="method-definition">
+ <span class="method-result">void</span>
+ <a href="#SmtpClose" title="details" class="method-name">SmtpClose</a>
+ ()
+ </div>
+ </div>
+ </div>
+ </div>
+
+ <a name="sec-vars"></a>
+ <div class="info-box">
+ <div class="info-box-title">Variables</div>
+ <div class="nav-bar">
+ <a href="#sec-description">Description</a> |
+ <a href="#sec-var-summary">Vars</a> (<span class="disabled">details</span>)
+
+
+ |
+ <a href="#sec-method-summary">Methods</a> (<a href="#sec-methods">details</a>)
+
+ </div>
+ <div class="info-box-body">
+ <a name="var$AltBody" id="$AltBody"><!-- --></A>
+<div class="evenrow">
+
+ <div class="var-header">
+ <span class="var-title">
+ <span class="var-type">string</span>
+ <span class="var-name">$AltBody</span>
+ = <span class="var-default"> &quot;&quot;</span> (line <span class="line-number">96</span>)
+ </span>
+ </div>
+
+ <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Sets the text-only body of the message. This automatically sets the email to multipart/alternative. This body can be read by mail clients that do not have HTML email capability such as mutt. Clients that can read HTML will view the normal Body.</p>
+
+
+
+
+
+</div>
+<a name="var$Body" id="$Body"><!-- --></A>
+<div class="oddrow">
+
+ <div class="var-header">
+ <span class="var-title">
+ <span class="var-type">string</span>
+ <span class="var-name">$Body</span>
+ = <span class="var-default"> &quot;&quot;</span> (line <span class="line-number">87</span>)
+ </span>
+ </div>
+
+ <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Sets the Body of the message. This can be either an HTML or text body.</p>
+<p class="description"><p>If HTML then run IsHTML(true).</p></p>
+
+
+
+
+
+</div>
+<a name="var$CharSet" id="$CharSet"><!-- --></A>
+<div class="evenrow">
+
+ <div class="var-header">
+ <span class="var-title">
+ <span class="var-type">string</span>
+ <span class="var-name">$CharSet</span>
+ = <span class="var-default"> &quot;iso-8859-1&quot;</span> (line <span class="line-number">36</span>)
+ </span>
+ </div>
+
+ <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Sets the CharSet of the message.</p>
+
+
+
+
+
+</div>
+<a name="var$ConfirmReadingTo" id="$ConfirmReadingTo"><!-- --></A>
+<div class="oddrow">
+
+ <div class="var-header">
+ <span class="var-title">
+ <span class="var-type">string</span>
+ <span class="var-name">$ConfirmReadingTo</span>
+ = <span class="var-default"> &quot;&quot;</span> (line <span class="line-number">134</span>)
+ </span>
+ </div>
+
+ <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Sets the email address that a reading confirmation will be sent.</p>
+
+
+
+
+
+</div>
+<a name="var$ContentType" id="$ContentType"><!-- --></A>
+<div class="evenrow">
+
+ <div class="var-header">
+ <span class="var-title">
+ <span class="var-type">string</span>
+ <span class="var-name">$ContentType</span>
+ = <span class="var-default"> &quot;text/plain&quot;</span> (line <span class="line-number">42</span>)
+ </span>
+ </div>
+
+ <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Sets the Content-type of the message.</p>
+
+
+
+
+
+</div>
+<a name="var$Encoding" id="$Encoding"><!-- --></A>
+<div class="oddrow">
+
+ <div class="var-header">
+ <span class="var-title">
+ <span class="var-type">string</span>
+ <span class="var-name">$Encoding</span>
+ = <span class="var-default"> &quot;8bit&quot;</span> (line <span class="line-number">49</span>)
+ </span>
+ </div>
+
+ <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Sets the Encoding of the message. Options for this are &quot;8bit&quot;, &quot;7bit&quot;, &quot;binary&quot;, &quot;base64&quot;, and &quot;quoted-printable&quot;.</p>
+
+
+
+
+
+</div>
+<a name="var$ErrorInfo" id="$ErrorInfo"><!-- --></A>
+<div class="evenrow">
+
+ <div class="var-header">
+ <span class="var-title">
+ <span class="var-type">string</span>
+ <span class="var-name">$ErrorInfo</span>
+ = <span class="var-default"> &quot;&quot;</span> (line <span class="line-number">55</span>)
+ </span>
+ </div>
+
+ <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Holds the most recent mailer error message.</p>
+
+
+
+
+
+</div>
+<a name="var$From" id="$From"><!-- --></A>
+<div class="oddrow">
+
+ <div class="var-header">
+ <span class="var-title">
+ <span class="var-type">string</span>
+ <span class="var-name">$From</span>
+ = <span class="var-default"> &quot;root@localhost&quot;</span> (line <span class="line-number">61</span>)
+ </span>
+ </div>
+
+ <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Sets the From email address for the message.</p>
+
+
+
+
+
+</div>
+<a name="var$FromName" id="$FromName"><!-- --></A>
+<div class="evenrow">
+
+ <div class="var-header">
+ <span class="var-title">
+ <span class="var-type">string</span>
+ <span class="var-name">$FromName</span>
+ = <span class="var-default"> &quot;Root User&quot;</span> (line <span class="line-number">67</span>)
+ </span>
+ </div>
+
+ <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Sets the From name of the message.</p>
+
+
+
+
+
+</div>
+<a name="var$Helo" id="$Helo"><!-- --></A>
+<div class="oddrow">
+
+ <div class="var-header">
+ <span class="var-title">
+ <span class="var-type">string</span>
+ <span class="var-name">$Helo</span>
+ = <span class="var-default"> &quot;&quot;</span> (line <span class="line-number">169</span>)
+ </span>
+ </div>
+
+ <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Sets the SMTP HELO of the message (Default is $Hostname).</p>
+
+
+
+
+
+</div>
+<a name="var$Host" id="$Host"><!-- --></A>
+<div class="evenrow">
+
+ <div class="var-header">
+ <span class="var-title">
+ <span class="var-type">string</span>
+ <span class="var-name">$Host</span>
+ = <span class="var-default"> &quot;localhost&quot;</span> (line <span class="line-number">157</span>)
+ </span>
+ </div>
+
+ <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Sets the SMTP hosts. All hosts must be separated by a semicolon. You can also specify a different port for each host by using this format: [hostname:port] (e.g. &quot;smtp1.example.com:25;smtp2.example.com&quot;).</p>
+<p class="description"><p>Hosts will be tried in order.</p></p>
+
+
+
+
+
+</div>
+<a name="var$Hostname" id="$Hostname"><!-- --></A>
+<div class="oddrow">
+
+ <div class="var-header">
+ <span class="var-title">
+ <span class="var-type">string</span>
+ <span class="var-name">$Hostname</span>
+ = <span class="var-default"> &quot;&quot;</span> (line <span class="line-number">142</span>)
+ </span>
+ </div>
+
+ <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Sets the hostname to use in Message-Id and Received headers and as default HELO string. If empty, the value returned by SERVER_NAME is used or 'localhost.localdomain'.</p>
+
+
+
+
+
+</div>
+<a name="var$Mailer" id="$Mailer"><!-- --></A>
+<div class="evenrow">
+
+ <div class="var-header">
+ <span class="var-title">
+ <span class="var-type">string</span>
+ <span class="var-name">$Mailer</span>
+ = <span class="var-default"> &quot;mail&quot;</span> (line <span class="line-number">109</span>)
+ </span>
+ </div>
+
+ <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Method to send mail: (&quot;mail&quot;, &quot;sendmail&quot;, or &quot;smtp&quot;).</p>
+
+
+
+
+
+</div>
+<a name="var$Password" id="$Password"><!-- --></A>
+<div class="oddrow">
+
+ <div class="var-header">
+ <span class="var-title">
+ <span class="var-type">string</span>
+ <span class="var-name">$Password</span>
+ = <span class="var-default"> &quot;&quot;</span> (line <span class="line-number">187</span>)
+ </span>
+ </div>
+
+ <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Sets SMTP password.</p>
+
+
+
+
+
+</div>
+<a name="var$PluginDir" id="$PluginDir"><!-- --></A>
+<div class="evenrow">
+
+ <div class="var-header">
+ <span class="var-title">
+ <span class="var-type">string</span>
+ <span class="var-name">$PluginDir</span>
+ = <span class="var-default"> &quot;&quot;</span> (line <span class="line-number">122</span>)
+ </span>
+ </div>
+
+ <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Path to PHPMailer plugins. This is now only useful if the SMTP class is in a different directory than the PHP include path.</p>
+
+
+
+
+
+</div>
+<a name="var$Port" id="$Port"><!-- --></A>
+<div class="oddrow">
+
+ <div class="var-header">
+ <span class="var-title">
+ <span class="var-type">int</span>
+ <span class="var-name">$Port</span>
+ = <span class="var-default"> 25</span> (line <span class="line-number">163</span>)
+ </span>
+ </div>
+
+ <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Sets the default SMTP server port.</p>
+
+
+
+
+
+</div>
+<a name="var$Priority" id="$Priority"><!-- --></A>
+<div class="evenrow">
+
+ <div class="var-header">
+ <span class="var-title">
+ <span class="var-type">int</span>
+ <span class="var-name">$Priority</span>
+ = <span class="var-default"> 3</span> (line <span class="line-number">30</span>)
+ </span>
+ </div>
+
+ <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Email priority (1 = High, 3 = Normal, 5 = low).</p>
+
+
+
+
+
+</div>
+<a name="var$Sender" id="$Sender"><!-- --></A>
+<div class="oddrow">
+
+ <div class="var-header">
+ <span class="var-title">
+ <span class="var-type">string</span>
+ <span class="var-name">$Sender</span>
+ = <span class="var-default"> &quot;&quot;</span> (line <span class="line-number">74</span>)
+ </span>
+ </div>
+
+ <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Sets the Sender email (Return-Path) of the message. If not empty, will be sent via -f to sendmail or as 'MAIL FROM' in smtp mode.</p>
+
+
+
+
+
+</div>
+<a name="var$Sendmail" id="$Sendmail"><!-- --></A>
+<div class="evenrow">
+
+ <div class="var-header">
+ <span class="var-title">
+ <span class="var-type">string</span>
+ <span class="var-name">$Sendmail</span>
+ = <span class="var-default"> &quot;/usr/sbin/sendmail&quot;</span> (line <span class="line-number">115</span>)
+ </span>
+ </div>
+
+ <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Sets the path of the sendmail program.</p>
+
+
+
+
+
+</div>
+<a name="var$SMTPAuth" id="$SMTPAuth"><!-- --></A>
+<div class="oddrow">
+
+ <div class="var-header">
+ <span class="var-title">
+ <span class="var-type">bool</span>
+ <span class="var-name">$SMTPAuth</span>
+ = <span class="var-default"> false</span> (line <span class="line-number">175</span>)
+ </span>
+ </div>
+
+ <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Sets SMTP authentication. Utilizes the Username and Password variables.</p>
+
+
+
+
+
+</div>
+<a name="var$SMTPDebug" id="$SMTPDebug"><!-- --></A>
+<div class="evenrow">
+
+ <div class="var-header">
+ <span class="var-title">
+ <span class="var-type">bool</span>
+ <span class="var-name">$SMTPDebug</span>
+ = <span class="var-default"> false</span> (line <span class="line-number">200</span>)
+ </span>
+ </div>
+
+ <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Sets SMTP class debugging on or off.</p>
+
+
+
+
+
+</div>
+<a name="var$SMTPKeepAlive" id="$SMTPKeepAlive"><!-- --></A>
+<div class="oddrow">
+
+ <div class="var-header">
+ <span class="var-title">
+ <span class="var-type">bool</span>
+ <span class="var-name">$SMTPKeepAlive</span>
+ = <span class="var-default"> false</span> (line <span class="line-number">208</span>)
+ </span>
+ </div>
+
+ <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Prevents the SMTP connection from being closed after each mail sending. If this is set to true then to close the connection requires an explicit call to SmtpClose().</p>
+
+
+
+
+
+</div>
+<a name="var$Subject" id="$Subject"><!-- --></A>
+<div class="evenrow">
+
+ <div class="var-header">
+ <span class="var-title">
+ <span class="var-type">string</span>
+ <span class="var-name">$Subject</span>
+ = <span class="var-default"> &quot;&quot;</span> (line <span class="line-number">80</span>)
+ </span>
+ </div>
+
+ <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Sets the Subject of the message.</p>
+
+
+
+
+
+</div>
+<a name="var$Timeout" id="$Timeout"><!-- --></A>
+<div class="oddrow">
+
+ <div class="var-header">
+ <span class="var-title">
+ <span class="var-type">int</span>
+ <span class="var-name">$Timeout</span>
+ = <span class="var-default"> 10</span> (line <span class="line-number">194</span>)
+ </span>
+ </div>
+
+ <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Sets the SMTP server timeout in seconds. This function will not work with the win32 version.</p>
+
+
+
+
+
+</div>
+<a name="var$Username" id="$Username"><!-- --></A>
+<div class="evenrow">
+
+ <div class="var-header">
+ <span class="var-title">
+ <span class="var-type">string</span>
+ <span class="var-name">$Username</span>
+ = <span class="var-default"> &quot;&quot;</span> (line <span class="line-number">181</span>)
+ </span>
+ </div>
+
+ <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Sets SMTP username.</p>
+
+
+
+
+
+</div>
+<a name="var$Version" id="$Version"><!-- --></A>
+<div class="oddrow">
+
+ <div class="var-header">
+ <span class="var-title">
+ <span class="var-type">string</span>
+ <span class="var-name">$Version</span>
+ = <span class="var-default"> &quot;1.71&quot;</span> (line <span class="line-number">128</span>)
+ </span>
+ </div>
+
+ <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Holds PHPMailer version.</p>
+
+
+
+
+
+</div>
+<a name="var$WordWrap" id="$WordWrap"><!-- --></A>
+<div class="evenrow">
+
+ <div class="var-header">
+ <span class="var-title">
+ <span class="var-type">int</span>
+ <span class="var-name">$WordWrap</span>
+ = <span class="var-default"> 0</span> (line <span class="line-number">103</span>)
+ </span>
+ </div>
+
+ <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Sets word wrapping on the body of the message to a given number of characters.</p>
+
+
+
+
+
+</div>
+
+ </div>
+ </div>
+
+ <a name="sec-methods"></a>
+ <div class="info-box">
+ <div class="info-box-title">Methods</div>
+ <div class="nav-bar">
+ <a href="#sec-description">Description</a> |
+ <a href="#sec-var-summary">Vars</a> (<a href="#sec-vars">details</a>)
+ <a href="#sec-method-summary">Methods</a> (<span class="disabled">details</span>)
+
+ </div>
+ <div class="info-box-body">
+ <A NAME='method_detail'></A>
+<a name="methodAddAddress" id="AddAddress"><!-- --></a>
+<div class="oddrow">
+
+ <div class="method-header">
+ <span class="method-title">AddAddress</span> (line <span class="line-number">287</span>)
+ </div>
+
+ <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Adds a &quot;To&quot; address.</p>
+
+ <div class="method-signature">
+ <span class="method-result">void</span>
+ <span class="method-name">
+ AddAddress
+ </span>
+ (<span class="var-type">string</span>&nbsp;<span class="var-name">$address</span>, [<span class="var-type">string</span>&nbsp;<span class="var-name">$name</span> = <span class="var-default">""</span>])
+ </div>
+
+ <ul class="parameters">
+ <li>
+ <span class="var-type">string</span>
+ <span class="var-name">$address</span> </li>
+ <li>
+ <span class="var-type">string</span>
+ <span class="var-name">$name</span> </li>
+ </ul>
+
+
+ </div>
+<a name="methodAddAttachment" id="AddAttachment"><!-- --></a>
+<div class="evenrow">
+
+ <div class="method-header">
+ <span class="method-title">AddAttachment</span> (line <span class="line-number">1000</span>)
+ </div>
+
+ <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Adds an attachment from a path on the filesystem.</p>
+<p class="description"><p>Returns false if the file could not be found or accessed.</p></p>
+
+ <div class="method-signature">
+ <span class="method-result">bool</span>
+ <span class="method-name">
+ AddAttachment
+ </span>
+ (<span class="var-type">string</span>&nbsp;<span class="var-name">$path</span>, [<span class="var-type">string</span>&nbsp;<span class="var-name">$name</span> = <span class="var-default">""</span>], [<span class="var-type">string</span>&nbsp;<span class="var-name">$encoding</span> = <span class="var-default">"base64"</span>], [<span class="var-type">string</span>&nbsp;<span class="var-name">$type</span> = <span class="var-default">"application/octet-stream"</span>])
+ </div>
+
+ <ul class="parameters">
+ <li>
+ <span class="var-type">string</span>
+ <span class="var-name">$path</span><span class="var-description">: <p>Path to the attachment.</p></span> </li>
+ <li>
+ <span class="var-type">string</span>
+ <span class="var-name">$name</span><span class="var-description">: <p>Overrides the attachment name.</p></span> </li>
+ <li>
+ <span class="var-type">string</span>
+ <span class="var-name">$encoding</span><span class="var-description">: <p>File encoding (see $Encoding).</p></span> </li>
+ <li>
+ <span class="var-type">string</span>
+ <span class="var-name">$type</span><span class="var-description">: <p>File extension (MIME) type.</p></span> </li>
+ </ul>
+
+
+ </div>
+<a name="methodAddBCC" id="AddBCC"><!-- --></a>
+<div class="oddrow">
+
+ <div class="method-header">
+ <span class="method-title">AddBCC</span> (line <span class="line-number">315</span>)
+ </div>
+
+ <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Adds a &quot;Bcc&quot; address. Note: this function works with the SMTP mailer on win32, not with the &quot;mail&quot; mailer.</p>
+
+ <div class="method-signature">
+ <span class="method-result">void</span>
+ <span class="method-name">
+ AddBCC
+ </span>
+ (<span class="var-type">string</span>&nbsp;<span class="var-name">$address</span>, [<span class="var-type">string</span>&nbsp;<span class="var-name">$name</span> = <span class="var-default">""</span>])
+ </div>
+
+ <ul class="parameters">
+ <li>
+ <span class="var-type">string</span>
+ <span class="var-name">$address</span> </li>
+ <li>
+ <span class="var-type">string</span>
+ <span class="var-name">$name</span> </li>
+ </ul>
+
+
+ </div>
+<a name="methodAddCC" id="AddCC"><!-- --></a>
+<div class="evenrow">
+
+ <div class="method-header">
+ <span class="method-title">AddCC</span> (line <span class="line-number">301</span>)
+ </div>
+
+ <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Adds a &quot;Cc&quot; address. Note: this function works with the SMTP mailer on win32, not with the &quot;mail&quot; mailer.</p>
+
+ <div class="method-signature">
+ <span class="method-result">void</span>
+ <span class="method-name">
+ AddCC
+ </span>
+ (<span class="var-type">string</span>&nbsp;<span class="var-name">$address</span>, [<span class="var-type">string</span>&nbsp;<span class="var-name">$name</span> = <span class="var-default">""</span>])
+ </div>
+
+ <ul class="parameters">
+ <li>
+ <span class="var-type">string</span>
+ <span class="var-name">$address</span> </li>
+ <li>
+ <span class="var-type">string</span>
+ <span class="var-name">$name</span> </li>
+ </ul>
+
+
+ </div>
+<a name="methodAddCustomHeader" id="AddCustomHeader"><!-- --></a>
+<div class="oddrow">
+
+ <div class="method-header">
+ <span class="method-title">AddCustomHeader</span> (line <span class="line-number">1525</span>)
+ </div>
+
+ <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Adds a custom header.</p>
+
+ <div class="method-signature">
+ <span class="method-result">void</span>
+ <span class="method-name">
+ AddCustomHeader
+ </span>
+ (<span class="var-type">mixed</span>&nbsp;<span class="var-name">$custom_header</span>)
+ </div>
+
+
+
+ </div>
+<a name="methodAddEmbeddedImage" id="AddEmbeddedImage"><!-- --></a>
+<div class="evenrow">
+
+ <div class="method-header">
+ <span class="method-title">AddEmbeddedImage</span> (line <span class="line-number">1275</span>)
+ </div>
+
+ <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Adds an embedded attachment. This can include images, sounds, and just about any other document. Make sure to set the $type to an image type. For JPEG images use &quot;image/jpeg&quot; and for GIF images use &quot;image/gif&quot;.</p>
+
+ <div class="method-signature">
+ <span class="method-result">bool</span>
+ <span class="method-name">
+ AddEmbeddedImage
+ </span>
+ (<span class="var-type">string</span>&nbsp;<span class="var-name">$path</span>, <span class="var-type">string</span>&nbsp;<span class="var-name">$cid</span>, [<span class="var-type">string</span>&nbsp;<span class="var-name">$name</span> = <span class="var-default">""</span>], [<span class="var-type">string</span>&nbsp;<span class="var-name">$encoding</span> = <span class="var-default">"base64"</span>], [<span class="var-type">string</span>&nbsp;<span class="var-name">$type</span> = <span class="var-default">"application/octet-stream"</span>])
+ </div>
+
+ <ul class="parameters">
+ <li>
+ <span class="var-type">string</span>
+ <span class="var-name">$path</span><span class="var-description">: <p>Path to the attachment.</p></span> </li>
+ <li>
+ <span class="var-type">string</span>
+ <span class="var-name">$cid</span><span class="var-description">: <p>Content ID of the attachment. Use this to identify the Id for accessing the image in an HTML form.</p></span> </li>
+ <li>
+ <span class="var-type">string</span>
+ <span class="var-name">$name</span><span class="var-description">: <p>Overrides the attachment name.</p></span> </li>
+ <li>
+ <span class="var-type">string</span>
+ <span class="var-name">$encoding</span><span class="var-description">: <p>File encoding (see $Encoding).</p></span> </li>
+ <li>
+ <span class="var-type">string</span>
+ <span class="var-name">$type</span><span class="var-description">: <p>File extension (MIME) type.</p></span> </li>
+ </ul>
+
+
+ </div>
+<a name="methodAddReplyTo" id="AddReplyTo"><!-- --></a>
+<div class="oddrow">
+
+ <div class="method-header">
+ <span class="method-title">AddReplyTo</span> (line <span class="line-number">327</span>)
+ </div>
+
+ <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Adds a &quot;Reply-to&quot; address.</p>
+
+ <div class="method-signature">
+ <span class="method-result">void</span>
+ <span class="method-name">
+ AddReplyTo
+ </span>
+ (<span class="var-type">string</span>&nbsp;<span class="var-name">$address</span>, [<span class="var-type">string</span>&nbsp;<span class="var-name">$name</span> = <span class="var-default">""</span>])
+ </div>
+
+ <ul class="parameters">
+ <li>
+ <span class="var-type">string</span>
+ <span class="var-name">$address</span> </li>
+ <li>
+ <span class="var-type">string</span>
+ <span class="var-name">$name</span> </li>
+ </ul>
+
+
+ </div>
+<a name="methodAddStringAttachment" id="AddStringAttachment"><!-- --></a>
+<div class="evenrow">
+
+ <div class="method-header">
+ <span class="method-title">AddStringAttachment</span> (line <span class="line-number">1248</span>)
+ </div>
+
+ <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Adds a string or binary attachment (non-filesystem) to the list.</p>
+<p class="description"><p>This method can be used to attach ascii or binary data, such as a BLOB record from a database.</p></p>
+
+ <div class="method-signature">
+ <span class="method-result">void</span>
+ <span class="method-name">
+ AddStringAttachment
+ </span>
+ (<span class="var-type">string</span>&nbsp;<span class="var-name">$string</span>, <span class="var-type">string</span>&nbsp;<span class="var-name">$filename</span>, [<span class="var-type">string</span>&nbsp;<span class="var-name">$encoding</span> = <span class="var-default">"base64"</span>], [<span class="var-type">string</span>&nbsp;<span class="var-name">$type</span> = <span class="var-default">"application/octet-stream"</span>])
+ </div>
+
+ <ul class="parameters">
+ <li>
+ <span class="var-type">string</span>
+ <span class="var-name">$string</span><span class="var-description">: <p>String attachment data.</p></span> </li>
+ <li>
+ <span class="var-type">string</span>
+ <span class="var-name">$filename</span><span class="var-description">: <p>Name of the attachment.</p></span> </li>
+ <li>
+ <span class="var-type">string</span>
+ <span class="var-name">$encoding</span><span class="var-description">: <p>File encoding (see $Encoding).</p></span> </li>
+ <li>
+ <span class="var-type">string</span>
+ <span class="var-name">$type</span><span class="var-description">: <p>File extension (MIME) type.</p></span> </li>
+ </ul>
+
+
+ </div>
+<a name="methodClearAddresses" id="ClearAddresses"><!-- --></a>
+<div class="oddrow">
+
+ <div class="method-header">
+ <span class="method-title">ClearAddresses</span> (line <span class="line-number">1329</span>)
+ </div>
+
+ <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Clears all recipients assigned in the TO array. Returns void.</p>
+
+ <div class="method-signature">
+ <span class="method-result">void</span>
+ <span class="method-name">
+ ClearAddresses
+ </span>
+ ()
+ </div>
+
+
+
+ </div>
+<a name="methodClearAllRecipients" id="ClearAllRecipients"><!-- --></a>
+<div class="evenrow">
+
+ <div class="method-header">
+ <span class="method-title">ClearAllRecipients</span> (line <span class="line-number">1362</span>)
+ </div>
+
+ <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Clears all recipients assigned in the TO, CC and BCC array. Returns void.</p>
+
+ <div class="method-signature">
+ <span class="method-result">void</span>
+ <span class="method-name">
+ ClearAllRecipients
+ </span>
+ ()
+ </div>
+
+
+
+ </div>
+<a name="methodClearAttachments" id="ClearAttachments"><!-- --></a>
+<div class="oddrow">
+
+ <div class="method-header">
+ <span class="method-title">ClearAttachments</span> (line <span class="line-number">1373</span>)
+ </div>
+
+ <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Clears all previously set filesystem, string, and binary attachments. Returns void.</p>
+
+ <div class="method-signature">
+ <span class="method-result">void</span>
+ <span class="method-name">
+ ClearAttachments
+ </span>
+ ()
+ </div>
+
+
+
+ </div>
+<a name="methodClearBCCs" id="ClearBCCs"><!-- --></a>
+<div class="evenrow">
+
+ <div class="method-header">
+ <span class="method-title">ClearBCCs</span> (line <span class="line-number">1345</span>)
+ </div>
+
+ <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Clears all recipients assigned in the BCC array. Returns void.</p>
+
+ <div class="method-signature">
+ <span class="method-result">void</span>
+ <span class="method-name">
+ ClearBCCs
+ </span>
+ ()
+ </div>
+
+
+
+ </div>
+<a name="methodClearCCs" id="ClearCCs"><!-- --></a>
+<div class="oddrow">
+
+ <div class="method-header">
+ <span class="method-title">ClearCCs</span> (line <span class="line-number">1337</span>)
+ </div>
+
+ <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Clears all recipients assigned in the CC array. Returns void.</p>
+
+ <div class="method-signature">
+ <span class="method-result">void</span>
+ <span class="method-name">
+ ClearCCs
+ </span>
+ ()
+ </div>
+
+
+
+ </div>
+<a name="methodClearCustomHeaders" id="ClearCustomHeaders"><!-- --></a>
+<div class="evenrow">
+
+ <div class="method-header">
+ <span class="method-title">ClearCustomHeaders</span> (line <span class="line-number">1381</span>)
+ </div>
+
+ <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Clears all custom headers. Returns void.</p>
+
+ <div class="method-signature">
+ <span class="method-result">void</span>
+ <span class="method-name">
+ ClearCustomHeaders
+ </span>
+ ()
+ </div>
+
+
+
+ </div>
+<a name="methodClearReplyTos" id="ClearReplyTos"><!-- --></a>
+<div class="oddrow">
+
+ <div class="method-header">
+ <span class="method-title">ClearReplyTos</span> (line <span class="line-number">1353</span>)
+ </div>
+
+ <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Clears all recipients assigned in the ReplyTo array. Returns void.</p>
+
+ <div class="method-signature">
+ <span class="method-result">void</span>
+ <span class="method-name">
+ ClearReplyTos
+ </span>
+ ()
+ </div>
+
+
+
+ </div>
+<a name="methodIsError" id="IsError"><!-- --></a>
+<div class="evenrow">
+
+ <div class="method-header">
+ <span class="method-title">IsError</span> (line <span class="line-number">1505</span>)
+ </div>
+
+ <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Returns true if an error occurred.</p>
+
+ <div class="method-signature">
+ <span class="method-result">bool</span>
+ <span class="method-name">
+ IsError
+ </span>
+ ()
+ </div>
+
+
+
+ </div>
+<a name="methodIsHTML" id="IsHTML"><!-- --></a>
+<div class="oddrow">
+
+ <div class="method-header">
+ <span class="method-title">IsHTML</span> (line <span class="line-number">236</span>)
+ </div>
+
+ <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Sets message type to HTML.</p>
+
+ <div class="method-signature">
+ <span class="method-result">void</span>
+ <span class="method-name">
+ IsHTML
+ </span>
+ (<span class="var-type">bool</span>&nbsp;<span class="var-name">$bool</span>)
+ </div>
+
+ <ul class="parameters">
+ <li>
+ <span class="var-type">bool</span>
+ <span class="var-name">$bool</span> </li>
+ </ul>
+
+
+ </div>
+<a name="methodIsMail" id="IsMail"><!-- --></a>
+<div class="evenrow">
+
+ <div class="method-header">
+ <span class="method-title">IsMail</span> (line <span class="line-number">255</span>)
+ </div>
+
+ <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Sets Mailer to send message using PHP mail() function.</p>
+
+ <div class="method-signature">
+ <span class="method-result">void</span>
+ <span class="method-name">
+ IsMail
+ </span>
+ ()
+ </div>
+
+
+
+ </div>
+<a name="methodIsQmail" id="IsQmail"><!-- --></a>
+<div class="oddrow">
+
+ <div class="method-header">
+ <span class="method-title">IsQmail</span> (line <span class="line-number">271</span>)
+ </div>
+
+ <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Sets Mailer to send message using the qmail MTA.</p>
+
+ <div class="method-signature">
+ <span class="method-result">void</span>
+ <span class="method-name">
+ IsQmail
+ </span>
+ ()
+ </div>
+
+
+
+ </div>
+<a name="methodIsSendmail" id="IsSendmail"><!-- --></a>
+<div class="evenrow">
+
+ <div class="method-header">
+ <span class="method-title">IsSendmail</span> (line <span class="line-number">263</span>)
+ </div>
+
+ <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Sets Mailer to send message using the $Sendmail program.</p>
+
+ <div class="method-signature">
+ <span class="method-result">void</span>
+ <span class="method-name">
+ IsSendmail
+ </span>
+ ()
+ </div>
+
+
+
+ </div>
+<a name="methodIsSMTP" id="IsSMTP"><!-- --></a>
+<div class="oddrow">
+
+ <div class="method-header">
+ <span class="method-title">IsSMTP</span> (line <span class="line-number">247</span>)
+ </div>
+
+ <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Sets Mailer to send message using SMTP.</p>
+
+ <div class="method-signature">
+ <span class="method-result">void</span>
+ <span class="method-name">
+ IsSMTP
+ </span>
+ ()
+ </div>
+
+
+
+ </div>
+<a name="methodSend" id="Send"><!-- --></a>
+<div class="evenrow">
+
+ <div class="method-header">
+ <span class="method-title">Send</span> (line <span class="line-number">344</span>)
+ </div>
+
+ <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Creates message and assigns Mailer. If the message is not sent successfully then it returns false. Use the ErrorInfo variable to view description of the error.</p>
+
+ <div class="method-signature">
+ <span class="method-result">bool</span>
+ <span class="method-name">
+ Send
+ </span>
+ ()
+ </div>
+
+
+
+ </div>
+<a name="methodSetLanguage" id="SetLanguage"><!-- --></a>
+<div class="oddrow">
+
+ <div class="method-header">
+ <span class="method-title">SetLanguage</span> (line <span class="line-number">599</span>)
+ </div>
+
+ <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Sets the language for all class error messages. Returns false if it cannot load the language file. The default language type is English.</p>
+ <ul class="tags">
+ <li><span class="field">access:</span> public</li>
+ </ul>
+
+ <div class="method-signature">
+ <span class="method-result">bool</span>
+ <span class="method-name">
+ SetLanguage
+ </span>
+ (<span class="var-type">string</span>&nbsp;<span class="var-name">$lang_type</span>, [<span class="var-type">string</span>&nbsp;<span class="var-name">$lang_path</span> = <span class="var-default">""</span>])
+ </div>
+
+ <ul class="parameters">
+ <li>
+ <span class="var-type">string</span>
+ <span class="var-name">$lang_type</span><span class="var-description">: <p>Type of language (e.g. Portuguese: &quot;br&quot;)</p></span> </li>
+ <li>
+ <span class="var-type">string</span>
+ <span class="var-name">$lang_path</span><span class="var-description">: <p>Path to the language file directory</p></span> </li>
+ </ul>
+
+
+ </div>
+<a name="methodSmtpClose" id="SmtpClose"><!-- --></a>
+<div class="evenrow">
+
+ <div class="method-header">
+ <span class="method-title">SmtpClose</span> (line <span class="line-number">579</span>)
+ </div>
+
+ <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Closes the active SMTP session if one exists.</p>
+
+ <div class="method-signature">
+ <span class="method-result">void</span>
+ <span class="method-name">
+ SmtpClose
+ </span>
+ ()
+ </div>
+
+
+
+ </div>
+
+ </div>
+ </div>
+
+ <p class="notes" id="credit">
+ Documention generated on Mon, 28 Jul 2003 23:25:49 -0400 by <a href="http://www.phpdoc.org" target="_blank">phpDocumentor 1.2.0</a>
+ </p>
+ </div></body>
+</html> \ No newline at end of file
diff --git a/site/vendors/phpmailer/phpdoc/PHPMailer/SMTP.html b/site/vendors/phpmailer/phpdoc/PHPMailer/SMTP.html
new file mode 100644
index 0000000..4fdecb1
--- /dev/null
+++ b/site/vendors/phpmailer/phpdoc/PHPMailer/SMTP.html
@@ -0,0 +1,734 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+ <html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <!-- template designed by Marco Von Ballmoos -->
+ <title>Docs For Class SMTP</title>
+ <link rel="stylesheet" href="../media/stylesheet.css" />
+ <meta http-equiv='Content-Type' content='text/html; charset=iso-8859-1'/>
+ </head>
+ <body>
+ <div class="page-body">
+<h2 class="class-name">Class SMTP</h2>
+
+<a name="sec-description"></a>
+<div class="info-box">
+ <div class="info-box-title">Description</div>
+ <div class="nav-bar">
+ <span class="disabled">Description</span> |
+ <a href="#sec-var-summary">Vars</a> (<a href="#sec-vars">details</a>)
+ | <a href="#sec-method-summary">Methods</a> (<a href="#sec-methods">details</a>)
+
+ </div>
+ <div class="info-box-body">
+ <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">SMTP is rfc 821 compliant and implements all the rfc 821 SMTP commands except TURN which will always return a not implemented error. SMTP also provides some utility methods for sending mail to an SMTP server.</p>
+ <ul class="tags">
+ <li><span class="field">author:</span> <p>Chris Ryan</p></li>
+ </ul>
+ <p class="notes">
+ Located in <a class="field" href="_class_smtp_php.html">Program_Root/class.smtp.php</a> (line <span class="field">24</span>)
+ </p>
+
+
+ <pre></pre>
+
+ </div>
+</div>
+
+
+ <a name="sec-var-summary"></a>
+ <div class="info-box">
+ <div class="info-box-title">Variable Summary</span></div>
+ <div class="nav-bar">
+ <a href="#sec-description">Description</a> |
+ <span class="disabled">Vars</span> (<a href="#sec-vars">details</a>)
+ |
+ <a href="#sec-method-summary">Methods</a> (<a href="#sec-methods">details</a>)
+
+ </div>
+ <div class="info-box-body">
+ <div class="var-summary">
+ <div class="var-title">
+ <span class="var-type">string</span>
+ <a href="#$CRLF" title="details" class="var-name">$CRLF</a>
+ </div>
+ <div class="var-title">
+ <span class="var-type">bool</span>
+ <a href="#$do_debug" title="details" class="var-name">$do_debug</a>
+ </div>
+ <div class="var-title">
+ <span class="var-type">int</span>
+ <a href="#$SMTP_PORT" title="details" class="var-name">$SMTP_PORT</a>
+ </div>
+ </div>
+ </div>
+ </div>
+
+ <a name="sec-method-summary"></a>
+ <div class="info-box">
+ <div class="info-box-title">Method Summary</span></div>
+ <div class="nav-bar">
+ <a href="#sec-description">Description</a> |
+ <a href="#sec-var-summary">Vars</a> (<a href="#sec-vars">details</a>)
+
+ |
+ <span class="disabled">Methods</span> (<a href="#sec-methods">details</a>)
+ </div>
+ <div class="info-box-body">
+ <div class="method-summary">
+
+ <div class="method-definition">
+ <span class="method-result">void</span>
+ <a href="#SMTP" title="details" class="method-name">SMTP</a>
+ ()
+ </div>
+
+ <div class="method-definition">
+ <span class="method-result">bool</span>
+ <a href="#Authenticate" title="details" class="method-name">Authenticate</a>
+ (<span class="var-type">mixed</span>&nbsp;<span class="var-name">$username</span>, <span class="var-type">mixed</span>&nbsp;<span class="var-name">$password</span>)
+ </div>
+
+ <div class="method-definition">
+ <span class="method-result">void</span>
+ <a href="#Close" title="details" class="method-name">Close</a>
+ ()
+ </div>
+
+ <div class="method-definition">
+ <span class="method-result">bool</span>
+ <a href="#Connect" title="details" class="method-name">Connect</a>
+ (<span class="var-type">mixed</span>&nbsp;<span class="var-name">$host</span>, <span class="var-type">mixed</span>&nbsp;<span class="var-name">$port</span>, [<span class="var-type">mixed</span>&nbsp;<span class="var-name">$tval</span> = <span class="var-default">30</span>])
+ </div>
+
+ <div class="method-definition">
+ <span class="method-result">bool</span>
+ <a href="#Data" title="details" class="method-name">Data</a>
+ (<span class="var-type">mixed</span>&nbsp;<span class="var-name">$msg_data</span>)
+ </div>
+
+ <div class="method-definition">
+ <span class="method-result">string</span>
+ <a href="#Expand" title="details" class="method-name">Expand</a>
+ (<span class="var-type">mixed</span>&nbsp;<span class="var-name">$name</span>)
+ </div>
+
+ <div class="method-definition">
+ <span class="method-result">bool</span>
+ <a href="#Hello" title="details" class="method-name">Hello</a>
+ ([<span class="var-type">mixed</span>&nbsp;<span class="var-name">$host</span> = <span class="var-default">""</span>])
+ </div>
+
+ <div class="method-definition">
+ <span class="method-result">string</span>
+ <a href="#Help" title="details" class="method-name">Help</a>
+ ([<span class="var-type">mixed</span>&nbsp;<span class="var-name">$keyword</span> = <span class="var-default">""</span>])
+ </div>
+
+ <div class="method-definition">
+ <span class="method-result">bool</span>
+ <a href="#Mail" title="details" class="method-name">Mail</a>
+ (<span class="var-type">mixed</span>&nbsp;<span class="var-name">$from</span>)
+ </div>
+
+ <div class="method-definition">
+ <span class="method-result">bool</span>
+ <a href="#Noop" title="details" class="method-name">Noop</a>
+ ()
+ </div>
+
+ <div class="method-definition">
+ <span class="method-result">bool</span>
+ <a href="#Quit" title="details" class="method-name">Quit</a>
+ ([<span class="var-type">mixed</span>&nbsp;<span class="var-name">$close_on_error</span> = <span class="var-default">true</span>])
+ </div>
+
+ <div class="method-definition">
+ <span class="method-result">bool</span>
+ <a href="#Recipient" title="details" class="method-name">Recipient</a>
+ (<span class="var-type">mixed</span>&nbsp;<span class="var-name">$to</span>)
+ </div>
+
+ <div class="method-definition">
+ <span class="method-result">bool</span>
+ <a href="#Reset" title="details" class="method-name">Reset</a>
+ ()
+ </div>
+
+ <div class="method-definition">
+ <span class="method-result">bool</span>
+ <a href="#Send" title="details" class="method-name">Send</a>
+ (<span class="var-type">mixed</span>&nbsp;<span class="var-name">$from</span>)
+ </div>
+
+ <div class="method-definition">
+ <span class="method-result">bool</span>
+ <a href="#SendAndMail" title="details" class="method-name">SendAndMail</a>
+ (<span class="var-type">mixed</span>&nbsp;<span class="var-name">$from</span>)
+ </div>
+
+ <div class="method-definition">
+ <span class="method-result">bool</span>
+ <a href="#SendOrMail" title="details" class="method-name">SendOrMail</a>
+ (<span class="var-type">mixed</span>&nbsp;<span class="var-name">$from</span>)
+ </div>
+
+ <div class="method-definition">
+ <span class="method-result">bool</span>
+ <a href="#Turn" title="details" class="method-name">Turn</a>
+ ()
+ </div>
+
+ <div class="method-definition">
+ <span class="method-result">int</span>
+ <a href="#Verify" title="details" class="method-name">Verify</a>
+ (<span class="var-type">mixed</span>&nbsp;<span class="var-name">$name</span>)
+ </div>
+ </div>
+ </div>
+ </div>
+
+ <a name="sec-vars"></a>
+ <div class="info-box">
+ <div class="info-box-title">Variables</div>
+ <div class="nav-bar">
+ <a href="#sec-description">Description</a> |
+ <a href="#sec-var-summary">Vars</a> (<span class="disabled">details</span>)
+
+
+ |
+ <a href="#sec-method-summary">Methods</a> (<a href="#sec-methods">details</a>)
+
+ </div>
+ <div class="info-box-body">
+ <a name="var$CRLF" id="$CRLF"><!-- --></A>
+<div class="oddrow">
+
+ <div class="var-header">
+ <span class="var-title">
+ <span class="var-type">string</span>
+ <span class="var-name">$CRLF</span>
+ = <span class="var-default"> &quot;\r\n&quot;</span> (line <span class="line-number">36</span>)
+ </span>
+ </div>
+
+ <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">SMTP reply line ending</p>
+
+
+
+
+
+</div>
+<a name="var$do_debug" id="$do_debug"><!-- --></A>
+<div class="evenrow">
+
+ <div class="var-header">
+ <span class="var-title">
+ <span class="var-type">bool</span>
+ <span class="var-name">$do_debug</span>
+ (line <span class="line-number">42</span>)
+ </span>
+ </div>
+
+ <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Sets whether debugging is turned on</p>
+
+
+
+
+
+</div>
+<a name="var$SMTP_PORT" id="$SMTP_PORT"><!-- --></A>
+<div class="oddrow">
+
+ <div class="var-header">
+ <span class="var-title">
+ <span class="var-type">int</span>
+ <span class="var-name">$SMTP_PORT</span>
+ = <span class="var-default"> 25</span> (line <span class="line-number">30</span>)
+ </span>
+ </div>
+
+ <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">SMTP server port</p>
+
+
+
+
+
+</div>
+
+ </div>
+ </div>
+
+ <a name="sec-methods"></a>
+ <div class="info-box">
+ <div class="info-box-title">Methods</div>
+ <div class="nav-bar">
+ <a href="#sec-description">Description</a> |
+ <a href="#sec-var-summary">Vars</a> (<a href="#sec-vars">details</a>)
+ <a href="#sec-method-summary">Methods</a> (<span class="disabled">details</span>)
+
+ </div>
+ <div class="info-box-body">
+ <A NAME='method_detail'></A>
+<a name="methodSMTP" id="SMTP"><!-- --></a>
+<div class="evenrow">
+
+ <div class="method-header">
+ <span class="method-title">Constructor SMTP</span> (line <span class="line-number">57</span>)
+ </div>
+
+ <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Initialize the class so that the data is in a known state.</p>
+ <ul class="tags">
+ <li><span class="field">access:</span> public</li>
+ </ul>
+
+ <div class="method-signature">
+ <span class="method-result">void</span>
+ <span class="method-name">
+ SMTP
+ </span>
+ ()
+ </div>
+
+
+
+ </div>
+<a name="methodAuthenticate" id="Authenticate"><!-- --></a>
+<div class="oddrow">
+
+ <div class="method-header">
+ <span class="method-title">Authenticate</span> (line <span class="line-number">144</span>)
+ </div>
+
+ <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Performs SMTP authentication. Must be run after running the Hello() method. Returns true if successfully authenticated.</p>
+ <ul class="tags">
+ <li><span class="field">access:</span> public</li>
+ </ul>
+
+ <div class="method-signature">
+ <span class="method-result">bool</span>
+ <span class="method-name">
+ Authenticate
+ </span>
+ (<span class="var-type">mixed</span>&nbsp;<span class="var-name">$username</span>, <span class="var-type">mixed</span>&nbsp;<span class="var-name">$password</span>)
+ </div>
+
+
+
+ </div>
+<a name="methodClose" id="Close"><!-- --></a>
+<div class="evenrow">
+
+ <div class="method-header">
+ <span class="method-title">Close</span> (line <span class="line-number">232</span>)
+ </div>
+
+ <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Closes the socket and cleans up the state of the class.</p>
+<p class="description"><p>It is not considered good to use this function without first trying to use QUIT.</p></p>
+ <ul class="tags">
+ <li><span class="field">access:</span> public</li>
+ </ul>
+
+ <div class="method-signature">
+ <span class="method-result">void</span>
+ <span class="method-name">
+ Close
+ </span>
+ ()
+ </div>
+
+
+
+ </div>
+<a name="methodConnect" id="Connect"><!-- --></a>
+<div class="oddrow">
+
+ <div class="method-header">
+ <span class="method-title">Connect</span> (line <span class="line-number">82</span>)
+ </div>
+
+ <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Connect to the server specified on the port specified.</p>
+<p class="description"><p>If the port is not specified use the default SMTP_PORT. If tval is specified then a connection will try and be established with the server for that number of seconds. If tval is not specified the default is 30 seconds to try on the connection.</p><p>SMTP CODE SUCCESS: 220 SMTP CODE FAILURE: 421</p></p>
+ <ul class="tags">
+ <li><span class="field">access:</span> public</li>
+ </ul>
+
+ <div class="method-signature">
+ <span class="method-result">bool</span>
+ <span class="method-name">
+ Connect
+ </span>
+ (<span class="var-type">mixed</span>&nbsp;<span class="var-name">$host</span>, <span class="var-type">mixed</span>&nbsp;<span class="var-name">$port</span>, [<span class="var-type">mixed</span>&nbsp;<span class="var-name">$tval</span> = <span class="var-default">30</span>])
+ </div>
+
+
+
+ </div>
+<a name="methodData" id="Data"><!-- --></a>
+<div class="evenrow">
+
+ <div class="method-header">
+ <span class="method-title">Data</span> (line <span class="line-number">266</span>)
+ </div>
+
+ <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Issues a data command and sends the msg_data to the server</p>
+<p class="description"><p>finializing the mail transaction. $msg_data is the message that is to be send with the headers. Each header needs to be on a single line followed by a &lt;CRLF&gt; with the message headers and the message body being seperated by and additional &lt;CRLF&gt;.</p><p>Implements rfc 821: DATA &lt;CRLF&gt;</p><p>SMTP CODE INTERMEDIATE: 354 [data] &lt;CRLF&gt;.&lt;CRLF&gt; SMTP CODE SUCCESS: 250 SMTP CODE FAILURE: 552,554,451,452 SMTP CODE FAILURE: 451,554 SMTP CODE ERROR : 500,501,503,421</p></p>
+ <ul class="tags">
+ <li><span class="field">access:</span> public</li>
+ </ul>
+
+ <div class="method-signature">
+ <span class="method-result">bool</span>
+ <span class="method-name">
+ Data
+ </span>
+ (<span class="var-type">mixed</span>&nbsp;<span class="var-name">$msg_data</span>)
+ </div>
+
+
+
+ </div>
+<a name="methodExpand" id="Expand"><!-- --></a>
+<div class="oddrow">
+
+ <div class="method-header">
+ <span class="method-title">Expand</span> (line <span class="line-number">399</span>)
+ </div>
+
+ <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Expand takes the name and asks the server to list all the people who are members of the _list_. Expand will return back and array of the result or false if an error occurs.</p>
+<p class="description"><p>Each value in the array returned has the format of: [ &lt;full-name&gt; &lt;sp&gt; ] &lt;path&gt; The definition of &lt;path&gt; is defined in rfc 821</p><p>Implements rfc 821: EXPN &lt;SP&gt; &lt;string&gt; &lt;CRLF&gt;</p><p>SMTP CODE SUCCESS: 250 SMTP CODE FAILURE: 550 SMTP CODE ERROR : 500,501,502,504,421</p></p>
+ <ul class="tags">
+ <li><span class="field">return:</span> <p>array</p></li>
+ <li><span class="field">access:</span> public</li>
+ </ul>
+
+ <div class="method-signature">
+ <span class="method-result">string</span>
+ <span class="method-name">
+ Expand
+ </span>
+ (<span class="var-type">mixed</span>&nbsp;<span class="var-name">$name</span>)
+ </div>
+
+
+
+ </div>
+<a name="methodHello" id="Hello"><!-- --></a>
+<div class="evenrow">
+
+ <div class="method-header">
+ <span class="method-title">Hello</span> (line <span class="line-number">450</span>)
+ </div>
+
+ <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Sends the HELO command to the smtp server.</p>
+<p class="description"><p>This makes sure that we and the server are in the same known state.</p><p>Implements from rfc 821: HELO &lt;SP&gt; &lt;domain&gt; &lt;CRLF&gt;</p><p>SMTP CODE SUCCESS: 250 SMTP CODE ERROR : 500, 501, 504, 421</p></p>
+ <ul class="tags">
+ <li><span class="field">access:</span> public</li>
+ </ul>
+
+ <div class="method-signature">
+ <span class="method-result">bool</span>
+ <span class="method-name">
+ Hello
+ </span>
+ ([<span class="var-type">mixed</span>&nbsp;<span class="var-name">$host</span> = <span class="var-default">""</span>])
+ </div>
+
+
+
+ </div>
+<a name="methodHelp" id="Help"><!-- --></a>
+<div class="oddrow">
+
+ <div class="method-header">
+ <span class="method-title">Help</span> (line <span class="line-number">524</span>)
+ </div>
+
+ <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Gets help information on the keyword specified. If the keyword</p>
+<p class="description"><p>is not specified then returns generic help, ussually contianing A list of keywords that help is available on. This function returns the results back to the user. It is up to the user to handle the returned data. If an error occurs then false is returned with $this-&gt;error set appropiately.</p><p>Implements rfc 821: HELP [ &lt;SP&gt; &lt;string&gt; ] &lt;CRLF&gt;</p><p>SMTP CODE SUCCESS: 211,214 SMTP CODE ERROR : 500,501,502,504,421</p></p>
+ <ul class="tags">
+ <li><span class="field">access:</span> public</li>
+ </ul>
+
+ <div class="method-signature">
+ <span class="method-result">string</span>
+ <span class="method-name">
+ Help
+ </span>
+ ([<span class="var-type">mixed</span>&nbsp;<span class="var-name">$keyword</span> = <span class="var-default">""</span>])
+ </div>
+
+
+
+ </div>
+<a name="methodMail" id="Mail"><!-- --></a>
+<div class="evenrow">
+
+ <div class="method-header">
+ <span class="method-title">Mail</span> (line <span class="line-number">576</span>)
+ </div>
+
+ <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Starts a mail transaction from the email address specified in $from. Returns true if successful or false otherwise. If True the mail transaction is started and then one or more Recipient commands may be called followed by a Data command.</p>
+<p class="description"><p>Implements rfc 821: MAIL &lt;SP&gt; FROM:&lt;reverse-path&gt; &lt;CRLF&gt;</p><p>SMTP CODE SUCCESS: 250 SMTP CODE SUCCESS: 552,451,452 SMTP CODE SUCCESS: 500,501,421</p></p>
+ <ul class="tags">
+ <li><span class="field">access:</span> public</li>
+ </ul>
+
+ <div class="method-signature">
+ <span class="method-result">bool</span>
+ <span class="method-name">
+ Mail
+ </span>
+ (<span class="var-type">mixed</span>&nbsp;<span class="var-name">$from</span>)
+ </div>
+
+
+
+ </div>
+<a name="methodNoop" id="Noop"><!-- --></a>
+<div class="oddrow">
+
+ <div class="method-header">
+ <span class="method-title">Noop</span> (line <span class="line-number">618</span>)
+ </div>
+
+ <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Sends the command NOOP to the SMTP server.</p>
+<p class="description"><p>Implements from rfc 821: NOOP &lt;CRLF&gt;</p><p>SMTP CODE SUCCESS: 250 SMTP CODE ERROR : 500, 421</p></p>
+ <ul class="tags">
+ <li><span class="field">access:</span> public</li>
+ </ul>
+
+ <div class="method-signature">
+ <span class="method-result">bool</span>
+ <span class="method-name">
+ Noop
+ </span>
+ ()
+ </div>
+
+
+
+ </div>
+<a name="methodQuit" id="Quit"><!-- --></a>
+<div class="evenrow">
+
+ <div class="method-header">
+ <span class="method-title">Quit</span> (line <span class="line-number">661</span>)
+ </div>
+
+ <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Sends the quit command to the server and then closes the socket if there is no error or the $close_on_error argument is true.</p>
+<p class="description"><p>Implements from rfc 821: QUIT &lt;CRLF&gt;</p><p>SMTP CODE SUCCESS: 221 SMTP CODE ERROR : 500</p></p>
+ <ul class="tags">
+ <li><span class="field">access:</span> public</li>
+ </ul>
+
+ <div class="method-signature">
+ <span class="method-result">bool</span>
+ <span class="method-name">
+ Quit
+ </span>
+ ([<span class="var-type">mixed</span>&nbsp;<span class="var-name">$close_on_error</span> = <span class="var-default">true</span>])
+ </div>
+
+
+
+ </div>
+<a name="methodRecipient" id="Recipient"><!-- --></a>
+<div class="oddrow">
+
+ <div class="method-header">
+ <span class="method-title">Recipient</span> (line <span class="line-number">715</span>)
+ </div>
+
+ <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Sends the command RCPT to the SMTP server with the TO: argument of $to.</p>
+<p class="description"><p>Returns true if the recipient was accepted false if it was rejected.</p><p>Implements from rfc 821: RCPT &lt;SP&gt; TO:&lt;forward-path&gt; &lt;CRLF&gt;</p><p>SMTP CODE SUCCESS: 250,251 SMTP CODE FAILURE: 550,551,552,553,450,451,452 SMTP CODE ERROR : 500,501,503,421</p></p>
+ <ul class="tags">
+ <li><span class="field">access:</span> public</li>
+ </ul>
+
+ <div class="method-signature">
+ <span class="method-result">bool</span>
+ <span class="method-name">
+ Recipient
+ </span>
+ (<span class="var-type">mixed</span>&nbsp;<span class="var-name">$to</span>)
+ </div>
+
+
+
+ </div>
+<a name="methodReset" id="Reset"><!-- --></a>
+<div class="evenrow">
+
+ <div class="method-header">
+ <span class="method-title">Reset</span> (line <span class="line-number">759</span>)
+ </div>
+
+ <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Sends the RSET command to abort and transaction that is currently in progress. Returns true if successful false otherwise.</p>
+<p class="description"><p>Implements rfc 821: RSET &lt;CRLF&gt;</p><p>SMTP CODE SUCCESS: 250 SMTP CODE ERROR : 500,501,504,421</p></p>
+ <ul class="tags">
+ <li><span class="field">access:</span> public</li>
+ </ul>
+
+ <div class="method-signature">
+ <span class="method-result">bool</span>
+ <span class="method-name">
+ Reset
+ </span>
+ ()
+ </div>
+
+
+
+ </div>
+<a name="methodSend" id="Send"><!-- --></a>
+<div class="oddrow">
+
+ <div class="method-header">
+ <span class="method-title">Send</span> (line <span class="line-number">808</span>)
+ </div>
+
+ <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Starts a mail transaction from the email address specified in</p>
+<p class="description"><p>$from. Returns true if successful or false otherwise. If True the mail transaction is started and then one or more Recipient commands may be called followed by a Data command. This command will send the message to the users terminal if they are logged in.</p><p>Implements rfc 821: SEND &lt;SP&gt; FROM:&lt;reverse-path&gt; &lt;CRLF&gt;</p><p>SMTP CODE SUCCESS: 250 SMTP CODE SUCCESS: 552,451,452 SMTP CODE SUCCESS: 500,501,502,421</p></p>
+ <ul class="tags">
+ <li><span class="field">access:</span> public</li>
+ </ul>
+
+ <div class="method-signature">
+ <span class="method-result">bool</span>
+ <span class="method-name">
+ Send
+ </span>
+ (<span class="var-type">mixed</span>&nbsp;<span class="var-name">$from</span>)
+ </div>
+
+
+
+ </div>
+<a name="methodSendAndMail" id="SendAndMail"><!-- --></a>
+<div class="evenrow">
+
+ <div class="method-header">
+ <span class="method-title">SendAndMail</span> (line <span class="line-number">856</span>)
+ </div>
+
+ <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Starts a mail transaction from the email address specified in</p>
+<p class="description"><p>$from. Returns true if successful or false otherwise. If True the mail transaction is started and then one or more Recipient commands may be called followed by a Data command. This command will send the message to the users terminal if they are logged in and send them an email.</p><p>Implements rfc 821: SAML &lt;SP&gt; FROM:&lt;reverse-path&gt; &lt;CRLF&gt;</p><p>SMTP CODE SUCCESS: 250 SMTP CODE SUCCESS: 552,451,452 SMTP CODE SUCCESS: 500,501,502,421</p></p>
+ <ul class="tags">
+ <li><span class="field">access:</span> public</li>
+ </ul>
+
+ <div class="method-signature">
+ <span class="method-result">bool</span>
+ <span class="method-name">
+ SendAndMail
+ </span>
+ (<span class="var-type">mixed</span>&nbsp;<span class="var-name">$from</span>)
+ </div>
+
+
+
+ </div>
+<a name="methodSendOrMail" id="SendOrMail"><!-- --></a>
+<div class="oddrow">
+
+ <div class="method-header">
+ <span class="method-title">SendOrMail</span> (line <span class="line-number">904</span>)
+ </div>
+
+ <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Starts a mail transaction from the email address specified in</p>
+<p class="description"><p>$from. Returns true if successful or false otherwise. If True the mail transaction is started and then one or more Recipient commands may be called followed by a Data command. This command will send the message to the users terminal if they are logged in or mail it to them if they are not.</p><p>Implements rfc 821: SOML &lt;SP&gt; FROM:&lt;reverse-path&gt; &lt;CRLF&gt;</p><p>SMTP CODE SUCCESS: 250 SMTP CODE SUCCESS: 552,451,452 SMTP CODE SUCCESS: 500,501,502,421</p></p>
+ <ul class="tags">
+ <li><span class="field">access:</span> public</li>
+ </ul>
+
+ <div class="method-signature">
+ <span class="method-result">bool</span>
+ <span class="method-name">
+ SendOrMail
+ </span>
+ (<span class="var-type">mixed</span>&nbsp;<span class="var-name">$from</span>)
+ </div>
+
+
+
+ </div>
+<a name="methodTurn" id="Turn"><!-- --></a>
+<div class="evenrow">
+
+ <div class="method-header">
+ <span class="method-title">Turn</span> (line <span class="line-number">949</span>)
+ </div>
+
+ <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">This is an optional command for SMTP that this class does not support. This method is here to make the RFC821 Definition complete for this class and __may__ be implimented in the future</p>
+<p class="description"><p>Implements from rfc 821: TURN &lt;CRLF&gt;</p><p>SMTP CODE SUCCESS: 250 SMTP CODE FAILURE: 502 SMTP CODE ERROR : 500, 503</p></p>
+ <ul class="tags">
+ <li><span class="field">access:</span> public</li>
+ </ul>
+
+ <div class="method-signature">
+ <span class="method-result">bool</span>
+ <span class="method-name">
+ Turn
+ </span>
+ ()
+ </div>
+
+
+
+ </div>
+<a name="methodVerify" id="Verify"><!-- --></a>
+<div class="oddrow">
+
+ <div class="method-header">
+ <span class="method-title">Verify</span> (line <span class="line-number">971</span>)
+ </div>
+
+ <!-- ========== Info from phpDoc block ========= -->
+<p class="short-description">Verifies that the name is recognized by the server.</p>
+<p class="description"><p>Returns false if the name could not be verified otherwise the response from the server is returned.</p><p>Implements rfc 821: VRFY &lt;SP&gt; &lt;string&gt; &lt;CRLF&gt;</p><p>SMTP CODE SUCCESS: 250,251 SMTP CODE FAILURE: 550,551,553 SMTP CODE ERROR : 500,501,502,421</p></p>
+ <ul class="tags">
+ <li><span class="field">access:</span> public</li>
+ </ul>
+
+ <div class="method-signature">
+ <span class="method-result">int</span>
+ <span class="method-name">
+ Verify
+ </span>
+ (<span class="var-type">mixed</span>&nbsp;<span class="var-name">$name</span>)
+ </div>
+
+
+
+ </div>
+
+ </div>
+ </div>
+
+ <p class="notes" id="credit">
+ Documention generated on Mon, 28 Jul 2003 23:25:50 -0400 by <a href="http://www.phpdoc.org" target="_blank">phpDocumentor 1.2.0</a>
+ </p>
+ </div></body>
+</html> \ No newline at end of file
diff --git a/site/vendors/phpmailer/phpdoc/PHPMailer/_class_phpmailer_php.html b/site/vendors/phpmailer/phpdoc/PHPMailer/_class_phpmailer_php.html
new file mode 100644
index 0000000..f7bde2c
--- /dev/null
+++ b/site/vendors/phpmailer/phpdoc/PHPMailer/_class_phpmailer_php.html
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+ <html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <!-- template designed by Marco Von Ballmoos -->
+ <title>Docs for page class.phpmailer.php</title>
+ <link rel="stylesheet" href="../media/stylesheet.css" />
+ <meta http-equiv='Content-Type' content='text/html; charset=iso-8859-1'/>
+ </head>
+ <body>
+ <div class="page-body">
+<h2 class="file-name">Program_Root/class.phpmailer.php</h2>
+
+<a name="sec-description"></a>
+<div class="info-box">
+ <div class="info-box-title">Description</div>
+ <div class="nav-bar">
+ <span class="disabled">Description</span> |
+ <a href="#sec-classes">Classes</a>
+ </div>
+ <div class="info-box-body">
+ <!-- ========== Info from phpDoc block ========= -->
+
+ </div>
+</div>
+
+ <a name="sec-classes"></a>
+ <div class="info-box">
+ <div class="info-box-title">Classes</div>
+ <div class="nav-bar">
+ <a href="#sec-description">Description</a> |
+ <span class="disabled">Classes</span>
+ </div>
+ <div class="info-box-body">
+ <table cellpadding="2" cellspacing="0" class="class-table">
+ <tr>
+ <th class="class-table-header">Class</th>
+ <th class="class-table-header">Description</th>
+ </tr>
+ <tr>
+ <td style="padding-right: 2em; vertical-align: top">
+ <a href="../PHPMailer/PHPMailer.html">PHPMailer</a>
+ </td>
+ <td>
+ PHPMailer - PHP email transport class
+ </td>
+ </tr>
+ </table>
+ </div>
+ </div>
+
+
+
+
+
+ <p class="notes" id="credit">
+ Documention generated on Mon, 28 Jul 2003 23:25:49 -0400 by <a href="http://www.phpdoc.org" target="_blank">phpDocumentor 1.2.0</a>
+ </p>
+ </div></body>
+</html> \ No newline at end of file
diff --git a/site/vendors/phpmailer/phpdoc/PHPMailer/_class_smtp_php.html b/site/vendors/phpmailer/phpdoc/PHPMailer/_class_smtp_php.html
new file mode 100644
index 0000000..1b7d1b5
--- /dev/null
+++ b/site/vendors/phpmailer/phpdoc/PHPMailer/_class_smtp_php.html
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+ <html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <!-- template designed by Marco Von Ballmoos -->
+ <title>Docs for page class.smtp.php</title>
+ <link rel="stylesheet" href="../media/stylesheet.css" />
+ <meta http-equiv='Content-Type' content='text/html; charset=iso-8859-1'/>
+ </head>
+ <body>
+ <div class="page-body">
+<h2 class="file-name">Program_Root/class.smtp.php</h2>
+
+<a name="sec-description"></a>
+<div class="info-box">
+ <div class="info-box-title">Description</div>
+ <div class="nav-bar">
+ <span class="disabled">Description</span> |
+ <a href="#sec-classes">Classes</a>
+ </div>
+ <div class="info-box-body">
+ <!-- ========== Info from phpDoc block ========= -->
+
+ </div>
+</div>
+
+ <a name="sec-classes"></a>
+ <div class="info-box">
+ <div class="info-box-title">Classes</div>
+ <div class="nav-bar">
+ <a href="#sec-description">Description</a> |
+ <span class="disabled">Classes</span>
+ </div>
+ <div class="info-box-body">
+ <table cellpadding="2" cellspacing="0" class="class-table">
+ <tr>
+ <th class="class-table-header">Class</th>
+ <th class="class-table-header">Description</th>
+ </tr>
+ <tr>
+ <td style="padding-right: 2em; vertical-align: top">
+ <a href="../PHPMailer/SMTP.html">SMTP</a>
+ </td>
+ <td>
+ SMTP is rfc 821 compliant and implements all the rfc 821 SMTP commands except TURN which will always return a not implemented error. SMTP also provides some utility methods for sending mail to an SMTP server.
+ </td>
+ </tr>
+ </table>
+ </div>
+ </div>
+
+
+
+
+
+ <p class="notes" id="credit">
+ Documention generated on Mon, 28 Jul 2003 23:25:50 -0400 by <a href="http://www.phpdoc.org" target="_blank">phpDocumentor 1.2.0</a>
+ </p>
+ </div></body>
+</html> \ No newline at end of file
diff --git a/site/vendors/phpmailer/phpdoc/blank.html b/site/vendors/phpmailer/phpdoc/blank.html
new file mode 100644
index 0000000..4382bc9
--- /dev/null
+++ b/site/vendors/phpmailer/phpdoc/blank.html
@@ -0,0 +1,13 @@
+<html>
+<head>
+ <title>Generated Documentation</title>
+ <link rel="stylesheet" href="media/stylesheet.css" />
+ <meta http-equiv='Content-Type' content='text/html; charset=iso-8859-1'/>
+</head>
+<body>
+<div align="center"><h1>Generated Documentation</h1></div>
+<b>Welcome to default!</b><br />
+<br />
+This documentation was generated by <a href="http://www.phpdoc.org">phpDocumentor v1.2.0</a><br />
+</body>
+</html> \ No newline at end of file
diff --git a/site/vendors/phpmailer/phpdoc/classtrees_PHPMailer.html b/site/vendors/phpmailer/phpdoc/classtrees_PHPMailer.html
new file mode 100644
index 0000000..f8a48da
--- /dev/null
+++ b/site/vendors/phpmailer/phpdoc/classtrees_PHPMailer.html
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+ <html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <!-- template designed by Marco Von Ballmoos -->
+ <title></title>
+ <link rel="stylesheet" href="media/stylesheet.css" />
+ <meta http-equiv='Content-Type' content='text/html; charset=iso-8859-1'/>
+ </head>
+ <body>
+
+<!-- Start of Class Data -->
+<H2>
+
+</H2>
+<h2>Root class PHPMailer</h2>
+<ul>
+<li><a href="PHPMailer/PHPMailer.html">PHPMailer</a></li></ul>
+
+<h2>Root class SMTP</h2>
+<ul>
+<li><a href="PHPMailer/SMTP.html">SMTP</a></li></ul>
+
+ <p class="notes" id="credit">
+ Documention generated on Mon, 28 Jul 2003 23:25:49 -0400 by <a href="http://www.phpdoc.org" target="_blank">phpDocumentor 1.2.0</a>
+ </p>
+ </body>
+</html> \ No newline at end of file
diff --git a/site/vendors/phpmailer/phpdoc/elementindex.html b/site/vendors/phpmailer/phpdoc/elementindex.html
new file mode 100644
index 0000000..7f65a76
--- /dev/null
+++ b/site/vendors/phpmailer/phpdoc/elementindex.html
@@ -0,0 +1,734 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+ <html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <!-- template designed by Marco Von Ballmoos -->
+ <title></title>
+ <link rel="stylesheet" href="media/stylesheet.css" />
+ <meta http-equiv='Content-Type' content='text/html; charset=iso-8859-1'/>
+ </head>
+ <body>
+ <a name="top"></a>
+<h2>Full index</h2>
+<h3>Package indexes</h3>
+<ul>
+ <li><a href="elementindex_PHPMailer.html">PHPMailer</a></li>
+</ul>
+<br />
+<div class="index-letter-menu">
+ <a class="index-letter" href="elementindex.html#a">a</a>
+ <a class="index-letter" href="elementindex.html#b">b</a>
+ <a class="index-letter" href="elementindex.html#c">c</a>
+ <a class="index-letter" href="elementindex.html#d">d</a>
+ <a class="index-letter" href="elementindex.html#e">e</a>
+ <a class="index-letter" href="elementindex.html#f">f</a>
+ <a class="index-letter" href="elementindex.html#h">h</a>
+ <a class="index-letter" href="elementindex.html#i">i</a>
+ <a class="index-letter" href="elementindex.html#m">m</a>
+ <a class="index-letter" href="elementindex.html#n">n</a>
+ <a class="index-letter" href="elementindex.html#p">p</a>
+ <a class="index-letter" href="elementindex.html#q">q</a>
+ <a class="index-letter" href="elementindex.html#r">r</a>
+ <a class="index-letter" href="elementindex.html#s">s</a>
+ <a class="index-letter" href="elementindex.html#t">t</a>
+ <a class="index-letter" href="elementindex.html#u">u</a>
+ <a class="index-letter" href="elementindex.html#v">v</a>
+ <a class="index-letter" href="elementindex.html#w">w</a>
+</div>
+
+ <a name="a"></a>
+ <div class="index-letter-section">
+ <div style="float: left" class="index-letter-title">a</div>
+ <div style="float: right"><a href="#top">top</a></div>
+ <div style="clear: both"></div>
+ </div>
+ <dl>
+ <dt class="field">
+ <span class="var-title">$AltBody</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/PHPMailer.html#var$AltBody">PHPMailer::$AltBody</a> in class.phpmailer.php</div>
+ <div class="index-item-description">Sets the text-only body of the message. This automatically sets the email to multipart/alternative. This body can be read by mail clients that do not have HTML email capability such as mutt. Clients that can read HTML will view the normal Body.</div>
+ </dd>
+ <dt class="field">
+ <span class="method-title">AddAddress</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/PHPMailer.html#methodAddAddress">PHPMailer::AddAddress()</a> in class.phpmailer.php</div>
+ <div class="index-item-description">Adds a &quot;To&quot; address.</div>
+ </dd>
+ <dt class="field">
+ <span class="method-title">AddAttachment</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/PHPMailer.html#methodAddAttachment">PHPMailer::AddAttachment()</a> in class.phpmailer.php</div>
+ <div class="index-item-description">Adds an attachment from a path on the filesystem.</div>
+ </dd>
+ <dt class="field">
+ <span class="method-title">AddBCC</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/PHPMailer.html#methodAddBCC">PHPMailer::AddBCC()</a> in class.phpmailer.php</div>
+ <div class="index-item-description">Adds a &quot;Bcc&quot; address. Note: this function works with the SMTP mailer on win32, not with the &quot;mail&quot; mailer.</div>
+ </dd>
+ <dt class="field">
+ <span class="method-title">AddCC</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/PHPMailer.html#methodAddCC">PHPMailer::AddCC()</a> in class.phpmailer.php</div>
+ <div class="index-item-description">Adds a &quot;Cc&quot; address. Note: this function works with the SMTP mailer on win32, not with the &quot;mail&quot; mailer.</div>
+ </dd>
+ <dt class="field">
+ <span class="method-title">AddCustomHeader</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/PHPMailer.html#methodAddCustomHeader">PHPMailer::AddCustomHeader()</a> in class.phpmailer.php</div>
+ <div class="index-item-description">Adds a custom header.</div>
+ </dd>
+ <dt class="field">
+ <span class="method-title">AddEmbeddedImage</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/PHPMailer.html#methodAddEmbeddedImage">PHPMailer::AddEmbeddedImage()</a> in class.phpmailer.php</div>
+ <div class="index-item-description">Adds an embedded attachment. This can include images, sounds, and just about any other document. Make sure to set the $type to an image type. For JPEG images use &quot;image/jpeg&quot; and for GIF images use &quot;image/gif&quot;.</div>
+ </dd>
+ <dt class="field">
+ <span class="method-title">AddReplyTo</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/PHPMailer.html#methodAddReplyTo">PHPMailer::AddReplyTo()</a> in class.phpmailer.php</div>
+ <div class="index-item-description">Adds a &quot;Reply-to&quot; address.</div>
+ </dd>
+ <dt class="field">
+ <span class="method-title">AddStringAttachment</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/PHPMailer.html#methodAddStringAttachment">PHPMailer::AddStringAttachment()</a> in class.phpmailer.php</div>
+ <div class="index-item-description">Adds a string or binary attachment (non-filesystem) to the list.</div>
+ </dd>
+ <dt class="field">
+ <span class="method-title">Authenticate</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/SMTP.html#methodAuthenticate">SMTP::Authenticate()</a> in class.smtp.php</div>
+ <div class="index-item-description">Performs SMTP authentication. Must be run after running the Hello() method. Returns true if successfully authenticated.</div>
+ </dd>
+ </dl>
+ <a name="b"></a>
+ <div class="index-letter-section">
+ <div style="float: left" class="index-letter-title">b</div>
+ <div style="float: right"><a href="#top">top</a></div>
+ <div style="clear: both"></div>
+ </div>
+ <dl>
+ <dt class="field">
+ <span class="var-title">$Body</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/PHPMailer.html#var$Body">PHPMailer::$Body</a> in class.phpmailer.php</div>
+ <div class="index-item-description">Sets the Body of the message. This can be either an HTML or text body.</div>
+ </dd>
+ </dl>
+ <a name="c"></a>
+ <div class="index-letter-section">
+ <div style="float: left" class="index-letter-title">c</div>
+ <div style="float: right"><a href="#top">top</a></div>
+ <div style="clear: both"></div>
+ </div>
+ <dl>
+ <dt class="field">
+ <span class="var-title">$CharSet</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/PHPMailer.html#var$CharSet">PHPMailer::$CharSet</a> in class.phpmailer.php</div>
+ <div class="index-item-description">Sets the CharSet of the message.</div>
+ </dd>
+ <dt class="field">
+ <span class="var-title">$ConfirmReadingTo</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/PHPMailer.html#var$ConfirmReadingTo">PHPMailer::$ConfirmReadingTo</a> in class.phpmailer.php</div>
+ <div class="index-item-description">Sets the email address that a reading confirmation will be sent.</div>
+ </dd>
+ <dt class="field">
+ <span class="var-title">$ContentType</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/PHPMailer.html#var$ContentType">PHPMailer::$ContentType</a> in class.phpmailer.php</div>
+ <div class="index-item-description">Sets the Content-type of the message.</div>
+ </dd>
+ <dt class="field">
+ <span class="var-title">$CRLF</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/SMTP.html#var$CRLF">SMTP::$CRLF</a> in class.smtp.php</div>
+ <div class="index-item-description">SMTP reply line ending</div>
+ </dd>
+ <dt class="field">
+ <span class="include-title">class.phpmailer.php</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/_class_phpmailer_php.html">class.phpmailer.php</a> in class.phpmailer.php</div>
+ </dd>
+ <dt class="field">
+ <span class="include-title">class.smtp.php</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/_class_smtp_php.html">class.smtp.php</a> in class.smtp.php</div>
+ </dd>
+ <dt class="field">
+ <span class="method-title">ClearAddresses</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/PHPMailer.html#methodClearAddresses">PHPMailer::ClearAddresses()</a> in class.phpmailer.php</div>
+ <div class="index-item-description">Clears all recipients assigned in the TO array. Returns void.</div>
+ </dd>
+ <dt class="field">
+ <span class="method-title">ClearAllRecipients</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/PHPMailer.html#methodClearAllRecipients">PHPMailer::ClearAllRecipients()</a> in class.phpmailer.php</div>
+ <div class="index-item-description">Clears all recipients assigned in the TO, CC and BCC array. Returns void.</div>
+ </dd>
+ <dt class="field">
+ <span class="method-title">ClearAttachments</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/PHPMailer.html#methodClearAttachments">PHPMailer::ClearAttachments()</a> in class.phpmailer.php</div>
+ <div class="index-item-description">Clears all previously set filesystem, string, and binary attachments. Returns void.</div>
+ </dd>
+ <dt class="field">
+ <span class="method-title">ClearBCCs</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/PHPMailer.html#methodClearBCCs">PHPMailer::ClearBCCs()</a> in class.phpmailer.php</div>
+ <div class="index-item-description">Clears all recipients assigned in the BCC array. Returns void.</div>
+ </dd>
+ <dt class="field">
+ <span class="method-title">ClearCCs</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/PHPMailer.html#methodClearCCs">PHPMailer::ClearCCs()</a> in class.phpmailer.php</div>
+ <div class="index-item-description">Clears all recipients assigned in the CC array. Returns void.</div>
+ </dd>
+ <dt class="field">
+ <span class="method-title">ClearCustomHeaders</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/PHPMailer.html#methodClearCustomHeaders">PHPMailer::ClearCustomHeaders()</a> in class.phpmailer.php</div>
+ <div class="index-item-description">Clears all custom headers. Returns void.</div>
+ </dd>
+ <dt class="field">
+ <span class="method-title">ClearReplyTos</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/PHPMailer.html#methodClearReplyTos">PHPMailer::ClearReplyTos()</a> in class.phpmailer.php</div>
+ <div class="index-item-description">Clears all recipients assigned in the ReplyTo array. Returns void.</div>
+ </dd>
+ <dt class="field">
+ <span class="method-title">Close</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/SMTP.html#methodClose">SMTP::Close()</a> in class.smtp.php</div>
+ <div class="index-item-description">Closes the socket and cleans up the state of the class.</div>
+ </dd>
+ <dt class="field">
+ <span class="method-title">Connect</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/SMTP.html#methodConnect">SMTP::Connect()</a> in class.smtp.php</div>
+ <div class="index-item-description">Connect to the server specified on the port specified.</div>
+ </dd>
+ </dl>
+ <a name="d"></a>
+ <div class="index-letter-section">
+ <div style="float: left" class="index-letter-title">d</div>
+ <div style="float: right"><a href="#top">top</a></div>
+ <div style="clear: both"></div>
+ </div>
+ <dl>
+ <dt class="field">
+ <span class="var-title">$do_debug</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/SMTP.html#var$do_debug">SMTP::$do_debug</a> in class.smtp.php</div>
+ <div class="index-item-description">Sets whether debugging is turned on</div>
+ </dd>
+ <dt class="field">
+ <span class="method-title">Data</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/SMTP.html#methodData">SMTP::Data()</a> in class.smtp.php</div>
+ <div class="index-item-description">Issues a data command and sends the msg_data to the server</div>
+ </dd>
+ </dl>
+ <a name="e"></a>
+ <div class="index-letter-section">
+ <div style="float: left" class="index-letter-title">e</div>
+ <div style="float: right"><a href="#top">top</a></div>
+ <div style="clear: both"></div>
+ </div>
+ <dl>
+ <dt class="field">
+ <span class="var-title">$Encoding</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/PHPMailer.html#var$Encoding">PHPMailer::$Encoding</a> in class.phpmailer.php</div>
+ <div class="index-item-description">Sets the Encoding of the message. Options for this are &quot;8bit&quot;, &quot;7bit&quot;, &quot;binary&quot;, &quot;base64&quot;, and &quot;quoted-printable&quot;.</div>
+ </dd>
+ <dt class="field">
+ <span class="var-title">$ErrorInfo</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/PHPMailer.html#var$ErrorInfo">PHPMailer::$ErrorInfo</a> in class.phpmailer.php</div>
+ <div class="index-item-description">Holds the most recent mailer error message.</div>
+ </dd>
+ <dt class="field">
+ <span class="method-title">Expand</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/SMTP.html#methodExpand">SMTP::Expand()</a> in class.smtp.php</div>
+ <div class="index-item-description">Expand takes the name and asks the server to list all the people who are members of the _list_. Expand will return back and array of the result or false if an error occurs.</div>
+ </dd>
+ </dl>
+ <a name="f"></a>
+ <div class="index-letter-section">
+ <div style="float: left" class="index-letter-title">f</div>
+ <div style="float: right"><a href="#top">top</a></div>
+ <div style="clear: both"></div>
+ </div>
+ <dl>
+ <dt class="field">
+ <span class="var-title">$From</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/PHPMailer.html#var$From">PHPMailer::$From</a> in class.phpmailer.php</div>
+ <div class="index-item-description">Sets the From email address for the message.</div>
+ </dd>
+ <dt class="field">
+ <span class="var-title">$FromName</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/PHPMailer.html#var$FromName">PHPMailer::$FromName</a> in class.phpmailer.php</div>
+ <div class="index-item-description">Sets the From name of the message.</div>
+ </dd>
+ </dl>
+ <a name="h"></a>
+ <div class="index-letter-section">
+ <div style="float: left" class="index-letter-title">h</div>
+ <div style="float: right"><a href="#top">top</a></div>
+ <div style="clear: both"></div>
+ </div>
+ <dl>
+ <dt class="field">
+ <span class="var-title">$Helo</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/PHPMailer.html#var$Helo">PHPMailer::$Helo</a> in class.phpmailer.php</div>
+ <div class="index-item-description">Sets the SMTP HELO of the message (Default is $Hostname).</div>
+ </dd>
+ <dt class="field">
+ <span class="var-title">$Host</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/PHPMailer.html#var$Host">PHPMailer::$Host</a> in class.phpmailer.php</div>
+ <div class="index-item-description">Sets the SMTP hosts. All hosts must be separated by a semicolon. You can also specify a different port for each host by using this format: [hostname:port] (e.g. &quot;smtp1.example.com:25;smtp2.example.com&quot;).</div>
+ </dd>
+ <dt class="field">
+ <span class="var-title">$Hostname</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/PHPMailer.html#var$Hostname">PHPMailer::$Hostname</a> in class.phpmailer.php</div>
+ <div class="index-item-description">Sets the hostname to use in Message-Id and Received headers and as default HELO string. If empty, the value returned by SERVER_NAME is used or 'localhost.localdomain'.</div>
+ </dd>
+ <dt class="field">
+ <span class="method-title">Hello</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/SMTP.html#methodHello">SMTP::Hello()</a> in class.smtp.php</div>
+ <div class="index-item-description">Sends the HELO command to the smtp server.</div>
+ </dd>
+ <dt class="field">
+ <span class="method-title">Help</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/SMTP.html#methodHelp">SMTP::Help()</a> in class.smtp.php</div>
+ <div class="index-item-description">Gets help information on the keyword specified. If the keyword</div>
+ </dd>
+ </dl>
+ <a name="i"></a>
+ <div class="index-letter-section">
+ <div style="float: left" class="index-letter-title">i</div>
+ <div style="float: right"><a href="#top">top</a></div>
+ <div style="clear: both"></div>
+ </div>
+ <dl>
+ <dt class="field">
+ <span class="method-title">IsError</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/PHPMailer.html#methodIsError">PHPMailer::IsError()</a> in class.phpmailer.php</div>
+ <div class="index-item-description">Returns true if an error occurred.</div>
+ </dd>
+ <dt class="field">
+ <span class="method-title">IsHTML</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/PHPMailer.html#methodIsHTML">PHPMailer::IsHTML()</a> in class.phpmailer.php</div>
+ <div class="index-item-description">Sets message type to HTML.</div>
+ </dd>
+ <dt class="field">
+ <span class="method-title">IsMail</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/PHPMailer.html#methodIsMail">PHPMailer::IsMail()</a> in class.phpmailer.php</div>
+ <div class="index-item-description">Sets Mailer to send message using PHP mail() function.</div>
+ </dd>
+ <dt class="field">
+ <span class="method-title">IsQmail</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/PHPMailer.html#methodIsQmail">PHPMailer::IsQmail()</a> in class.phpmailer.php</div>
+ <div class="index-item-description">Sets Mailer to send message using the qmail MTA.</div>
+ </dd>
+ <dt class="field">
+ <span class="method-title">IsSendmail</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/PHPMailer.html#methodIsSendmail">PHPMailer::IsSendmail()</a> in class.phpmailer.php</div>
+ <div class="index-item-description">Sets Mailer to send message using the $Sendmail program.</div>
+ </dd>
+ <dt class="field">
+ <span class="method-title">IsSMTP</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/PHPMailer.html#methodIsSMTP">PHPMailer::IsSMTP()</a> in class.phpmailer.php</div>
+ <div class="index-item-description">Sets Mailer to send message using SMTP.</div>
+ </dd>
+ </dl>
+ <a name="m"></a>
+ <div class="index-letter-section">
+ <div style="float: left" class="index-letter-title">m</div>
+ <div style="float: right"><a href="#top">top</a></div>
+ <div style="clear: both"></div>
+ </div>
+ <dl>
+ <dt class="field">
+ <span class="var-title">$Mailer</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/PHPMailer.html#var$Mailer">PHPMailer::$Mailer</a> in class.phpmailer.php</div>
+ <div class="index-item-description">Method to send mail: (&quot;mail&quot;, &quot;sendmail&quot;, or &quot;smtp&quot;).</div>
+ </dd>
+ <dt class="field">
+ <span class="method-title">Mail</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/SMTP.html#methodMail">SMTP::Mail()</a> in class.smtp.php</div>
+ <div class="index-item-description">Starts a mail transaction from the email address specified in $from. Returns true if successful or false otherwise. If True the mail transaction is started and then one or more Recipient commands may be called followed by a Data command.</div>
+ </dd>
+ </dl>
+ <a name="n"></a>
+ <div class="index-letter-section">
+ <div style="float: left" class="index-letter-title">n</div>
+ <div style="float: right"><a href="#top">top</a></div>
+ <div style="clear: both"></div>
+ </div>
+ <dl>
+ <dt class="field">
+ <span class="method-title">Noop</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/SMTP.html#methodNoop">SMTP::Noop()</a> in class.smtp.php</div>
+ <div class="index-item-description">Sends the command NOOP to the SMTP server.</div>
+ </dd>
+ </dl>
+ <a name="p"></a>
+ <div class="index-letter-section">
+ <div style="float: left" class="index-letter-title">p</div>
+ <div style="float: right"><a href="#top">top</a></div>
+ <div style="clear: both"></div>
+ </div>
+ <dl>
+ <dt class="field">
+ <span class="var-title">$Password</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/PHPMailer.html#var$Password">PHPMailer::$Password</a> in class.phpmailer.php</div>
+ <div class="index-item-description">Sets SMTP password.</div>
+ </dd>
+ <dt class="field">
+ <span class="var-title">$PluginDir</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/PHPMailer.html#var$PluginDir">PHPMailer::$PluginDir</a> in class.phpmailer.php</div>
+ <div class="index-item-description">Path to PHPMailer plugins. This is now only useful if the SMTP class is in a different directory than the PHP include path.</div>
+ </dd>
+ <dt class="field">
+ <span class="var-title">$Port</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/PHPMailer.html#var$Port">PHPMailer::$Port</a> in class.phpmailer.php</div>
+ <div class="index-item-description">Sets the default SMTP server port.</div>
+ </dd>
+ <dt class="field">
+ <span class="var-title">$Priority</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/PHPMailer.html#var$Priority">PHPMailer::$Priority</a> in class.phpmailer.php</div>
+ <div class="index-item-description">Email priority (1 = High, 3 = Normal, 5 = low).</div>
+ </dd>
+ <dt class="field">
+ PHPMailer
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/PHPMailer.html">PHPMailer</a> in class.phpmailer.php</div>
+ <div class="index-item-description">PHPMailer - PHP email transport class</div>
+ </dd>
+ </dl>
+ <a name="q"></a>
+ <div class="index-letter-section">
+ <div style="float: left" class="index-letter-title">q</div>
+ <div style="float: right"><a href="#top">top</a></div>
+ <div style="clear: both"></div>
+ </div>
+ <dl>
+ <dt class="field">
+ <span class="method-title">Quit</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/SMTP.html#methodQuit">SMTP::Quit()</a> in class.smtp.php</div>
+ <div class="index-item-description">Sends the quit command to the server and then closes the socket if there is no error or the $close_on_error argument is true.</div>
+ </dd>
+ </dl>
+ <a name="r"></a>
+ <div class="index-letter-section">
+ <div style="float: left" class="index-letter-title">r</div>
+ <div style="float: right"><a href="#top">top</a></div>
+ <div style="clear: both"></div>
+ </div>
+ <dl>
+ <dt class="field">
+ <span class="method-title">Recipient</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/SMTP.html#methodRecipient">SMTP::Recipient()</a> in class.smtp.php</div>
+ <div class="index-item-description">Sends the command RCPT to the SMTP server with the TO: argument of $to.</div>
+ </dd>
+ <dt class="field">
+ <span class="method-title">Reset</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/SMTP.html#methodReset">SMTP::Reset()</a> in class.smtp.php</div>
+ <div class="index-item-description">Sends the RSET command to abort and transaction that is currently in progress. Returns true if successful false otherwise.</div>
+ </dd>
+ </dl>
+ <a name="s"></a>
+ <div class="index-letter-section">
+ <div style="float: left" class="index-letter-title">s</div>
+ <div style="float: right"><a href="#top">top</a></div>
+ <div style="clear: both"></div>
+ </div>
+ <dl>
+ <dt class="field">
+ <span class="var-title">$Sender</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/PHPMailer.html#var$Sender">PHPMailer::$Sender</a> in class.phpmailer.php</div>
+ <div class="index-item-description">Sets the Sender email (Return-Path) of the message. If not empty, will be sent via -f to sendmail or as 'MAIL FROM' in smtp mode.</div>
+ </dd>
+ <dt class="field">
+ <span class="var-title">$Sendmail</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/PHPMailer.html#var$Sendmail">PHPMailer::$Sendmail</a> in class.phpmailer.php</div>
+ <div class="index-item-description">Sets the path of the sendmail program.</div>
+ </dd>
+ <dt class="field">
+ <span class="var-title">$SMTPAuth</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/PHPMailer.html#var$SMTPAuth">PHPMailer::$SMTPAuth</a> in class.phpmailer.php</div>
+ <div class="index-item-description">Sets SMTP authentication. Utilizes the Username and Password variables.</div>
+ </dd>
+ <dt class="field">
+ <span class="var-title">$SMTPDebug</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/PHPMailer.html#var$SMTPDebug">PHPMailer::$SMTPDebug</a> in class.phpmailer.php</div>
+ <div class="index-item-description">Sets SMTP class debugging on or off.</div>
+ </dd>
+ <dt class="field">
+ <span class="var-title">$SMTPKeepAlive</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/PHPMailer.html#var$SMTPKeepAlive">PHPMailer::$SMTPKeepAlive</a> in class.phpmailer.php</div>
+ <div class="index-item-description">Prevents the SMTP connection from being closed after each mail sending. If this is set to true then to close the connection requires an explicit call to SmtpClose().</div>
+ </dd>
+ <dt class="field">
+ <span class="var-title">$SMTP_PORT</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/SMTP.html#var$SMTP_PORT">SMTP::$SMTP_PORT</a> in class.smtp.php</div>
+ <div class="index-item-description">SMTP server port</div>
+ </dd>
+ <dt class="field">
+ <span class="var-title">$Subject</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/PHPMailer.html#var$Subject">PHPMailer::$Subject</a> in class.phpmailer.php</div>
+ <div class="index-item-description">Sets the Subject of the message.</div>
+ </dd>
+ <dt class="field">
+ <span class="method-title">Send</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/SMTP.html#methodSend">SMTP::Send()</a> in class.smtp.php</div>
+ <div class="index-item-description">Starts a mail transaction from the email address specified in</div>
+ </dd>
+ <dt class="field">
+ <span class="method-title">Send</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/PHPMailer.html#methodSend">PHPMailer::Send()</a> in class.phpmailer.php</div>
+ <div class="index-item-description">Creates message and assigns Mailer. If the message is not sent successfully then it returns false. Use the ErrorInfo variable to view description of the error.</div>
+ </dd>
+ <dt class="field">
+ <span class="method-title">SendAndMail</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/SMTP.html#methodSendAndMail">SMTP::SendAndMail()</a> in class.smtp.php</div>
+ <div class="index-item-description">Starts a mail transaction from the email address specified in</div>
+ </dd>
+ <dt class="field">
+ <span class="method-title">SendOrMail</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/SMTP.html#methodSendOrMail">SMTP::SendOrMail()</a> in class.smtp.php</div>
+ <div class="index-item-description">Starts a mail transaction from the email address specified in</div>
+ </dd>
+ <dt class="field">
+ <span class="method-title">SetLanguage</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/PHPMailer.html#methodSetLanguage">PHPMailer::SetLanguage()</a> in class.phpmailer.php</div>
+ <div class="index-item-description">Sets the language for all class error messages. Returns false if it cannot load the language file. The default language type is English.</div>
+ </dd>
+ <dt class="field">
+ <span class="method-title">SMTP</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/SMTP.html#methodSMTP">SMTP::SMTP()</a> in class.smtp.php</div>
+ <div class="index-item-description">Initialize the class so that the data is in a known state.</div>
+ </dd>
+ <dt class="field">
+ SMTP
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/SMTP.html">SMTP</a> in class.smtp.php</div>
+ <div class="index-item-description">SMTP is rfc 821 compliant and implements all the rfc 821 SMTP commands except TURN which will always return a not implemented error. SMTP also provides some utility methods for sending mail to an SMTP server.</div>
+ </dd>
+ <dt class="field">
+ <span class="method-title">SmtpClose</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/PHPMailer.html#methodSmtpClose">PHPMailer::SmtpClose()</a> in class.phpmailer.php</div>
+ <div class="index-item-description">Closes the active SMTP session if one exists.</div>
+ </dd>
+ </dl>
+ <a name="t"></a>
+ <div class="index-letter-section">
+ <div style="float: left" class="index-letter-title">t</div>
+ <div style="float: right"><a href="#top">top</a></div>
+ <div style="clear: both"></div>
+ </div>
+ <dl>
+ <dt class="field">
+ <span class="var-title">$Timeout</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/PHPMailer.html#var$Timeout">PHPMailer::$Timeout</a> in class.phpmailer.php</div>
+ <div class="index-item-description">Sets the SMTP server timeout in seconds. This function will not work with the win32 version.</div>
+ </dd>
+ <dt class="field">
+ <span class="method-title">Turn</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/SMTP.html#methodTurn">SMTP::Turn()</a> in class.smtp.php</div>
+ <div class="index-item-description">This is an optional command for SMTP that this class does not support. This method is here to make the RFC821 Definition complete for this class and __may__ be implimented in the future</div>
+ </dd>
+ </dl>
+ <a name="u"></a>
+ <div class="index-letter-section">
+ <div style="float: left" class="index-letter-title">u</div>
+ <div style="float: right"><a href="#top">top</a></div>
+ <div style="clear: both"></div>
+ </div>
+ <dl>
+ <dt class="field">
+ <span class="var-title">$Username</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/PHPMailer.html#var$Username">PHPMailer::$Username</a> in class.phpmailer.php</div>
+ <div class="index-item-description">Sets SMTP username.</div>
+ </dd>
+ </dl>
+ <a name="v"></a>
+ <div class="index-letter-section">
+ <div style="float: left" class="index-letter-title">v</div>
+ <div style="float: right"><a href="#top">top</a></div>
+ <div style="clear: both"></div>
+ </div>
+ <dl>
+ <dt class="field">
+ <span class="var-title">$Version</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/PHPMailer.html#var$Version">PHPMailer::$Version</a> in class.phpmailer.php</div>
+ <div class="index-item-description">Holds PHPMailer version.</div>
+ </dd>
+ <dt class="field">
+ <span class="method-title">Verify</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/SMTP.html#methodVerify">SMTP::Verify()</a> in class.smtp.php</div>
+ <div class="index-item-description">Verifies that the name is recognized by the server.</div>
+ </dd>
+ </dl>
+ <a name="w"></a>
+ <div class="index-letter-section">
+ <div style="float: left" class="index-letter-title">w</div>
+ <div style="float: right"><a href="#top">top</a></div>
+ <div style="clear: both"></div>
+ </div>
+ <dl>
+ <dt class="field">
+ <span class="var-title">$WordWrap</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/PHPMailer.html#var$WordWrap">PHPMailer::$WordWrap</a> in class.phpmailer.php</div>
+ <div class="index-item-description">Sets word wrapping on the body of the message to a given number of characters.</div>
+ </dd>
+ </dl>
+
+<div class="index-letter-menu">
+ <a class="index-letter" href="elementindex.html#a">a</a>
+ <a class="index-letter" href="elementindex.html#b">b</a>
+ <a class="index-letter" href="elementindex.html#c">c</a>
+ <a class="index-letter" href="elementindex.html#d">d</a>
+ <a class="index-letter" href="elementindex.html#e">e</a>
+ <a class="index-letter" href="elementindex.html#f">f</a>
+ <a class="index-letter" href="elementindex.html#h">h</a>
+ <a class="index-letter" href="elementindex.html#i">i</a>
+ <a class="index-letter" href="elementindex.html#m">m</a>
+ <a class="index-letter" href="elementindex.html#n">n</a>
+ <a class="index-letter" href="elementindex.html#p">p</a>
+ <a class="index-letter" href="elementindex.html#q">q</a>
+ <a class="index-letter" href="elementindex.html#r">r</a>
+ <a class="index-letter" href="elementindex.html#s">s</a>
+ <a class="index-letter" href="elementindex.html#t">t</a>
+ <a class="index-letter" href="elementindex.html#u">u</a>
+ <a class="index-letter" href="elementindex.html#v">v</a>
+ <a class="index-letter" href="elementindex.html#w">w</a>
+</div> </body>
+</html> \ No newline at end of file
diff --git a/site/vendors/phpmailer/phpdoc/elementindex_PHPMailer.html b/site/vendors/phpmailer/phpdoc/elementindex_PHPMailer.html
new file mode 100644
index 0000000..e62d5ed
--- /dev/null
+++ b/site/vendors/phpmailer/phpdoc/elementindex_PHPMailer.html
@@ -0,0 +1,731 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+ <html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <!-- template designed by Marco Von Ballmoos -->
+ <title></title>
+ <link rel="stylesheet" href="media/stylesheet.css" />
+ <meta http-equiv='Content-Type' content='text/html; charset=iso-8859-1'/>
+ </head>
+ <body>
+ <a name="top"></a>
+<h2>[PHPMailer] element index</h2>
+<a href="elementindex.html">All elements</a>
+<br />
+<div class="index-letter-menu">
+ <a class="index-letter" href="elementindex_PHPMailer.html#a">a</a>
+ <a class="index-letter" href="elementindex_PHPMailer.html#b">b</a>
+ <a class="index-letter" href="elementindex_PHPMailer.html#c">c</a>
+ <a class="index-letter" href="elementindex_PHPMailer.html#d">d</a>
+ <a class="index-letter" href="elementindex_PHPMailer.html#e">e</a>
+ <a class="index-letter" href="elementindex_PHPMailer.html#f">f</a>
+ <a class="index-letter" href="elementindex_PHPMailer.html#h">h</a>
+ <a class="index-letter" href="elementindex_PHPMailer.html#i">i</a>
+ <a class="index-letter" href="elementindex_PHPMailer.html#m">m</a>
+ <a class="index-letter" href="elementindex_PHPMailer.html#n">n</a>
+ <a class="index-letter" href="elementindex_PHPMailer.html#p">p</a>
+ <a class="index-letter" href="elementindex_PHPMailer.html#q">q</a>
+ <a class="index-letter" href="elementindex_PHPMailer.html#r">r</a>
+ <a class="index-letter" href="elementindex_PHPMailer.html#s">s</a>
+ <a class="index-letter" href="elementindex_PHPMailer.html#t">t</a>
+ <a class="index-letter" href="elementindex_PHPMailer.html#u">u</a>
+ <a class="index-letter" href="elementindex_PHPMailer.html#v">v</a>
+ <a class="index-letter" href="elementindex_PHPMailer.html#w">w</a>
+</div>
+
+ <a name="a"></a>
+ <div class="index-letter-section">
+ <div style="float: left" class="index-letter-title">a</div>
+ <div style="float: right"><a href="#top">top</a></div>
+ <div style="clear: both"></div>
+ </div>
+ <dl>
+ <dt class="field">
+ <span class="var-title">$AltBody</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/PHPMailer.html#var$AltBody">PHPMailer::$AltBody</a> in class.phpmailer.php</div>
+ <div class="index-item-description">Sets the text-only body of the message. This automatically sets the email to multipart/alternative. This body can be read by mail clients that do not have HTML email capability such as mutt. Clients that can read HTML will view the normal Body.</div>
+ </dd>
+ <dt class="field">
+ <span class="method-title">AddAddress</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/PHPMailer.html#methodAddAddress">PHPMailer::AddAddress()</a> in class.phpmailer.php</div>
+ <div class="index-item-description">Adds a &quot;To&quot; address.</div>
+ </dd>
+ <dt class="field">
+ <span class="method-title">AddAttachment</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/PHPMailer.html#methodAddAttachment">PHPMailer::AddAttachment()</a> in class.phpmailer.php</div>
+ <div class="index-item-description">Adds an attachment from a path on the filesystem.</div>
+ </dd>
+ <dt class="field">
+ <span class="method-title">AddBCC</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/PHPMailer.html#methodAddBCC">PHPMailer::AddBCC()</a> in class.phpmailer.php</div>
+ <div class="index-item-description">Adds a &quot;Bcc&quot; address. Note: this function works with the SMTP mailer on win32, not with the &quot;mail&quot; mailer.</div>
+ </dd>
+ <dt class="field">
+ <span class="method-title">AddCC</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/PHPMailer.html#methodAddCC">PHPMailer::AddCC()</a> in class.phpmailer.php</div>
+ <div class="index-item-description">Adds a &quot;Cc&quot; address. Note: this function works with the SMTP mailer on win32, not with the &quot;mail&quot; mailer.</div>
+ </dd>
+ <dt class="field">
+ <span class="method-title">AddCustomHeader</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/PHPMailer.html#methodAddCustomHeader">PHPMailer::AddCustomHeader()</a> in class.phpmailer.php</div>
+ <div class="index-item-description">Adds a custom header.</div>
+ </dd>
+ <dt class="field">
+ <span class="method-title">AddEmbeddedImage</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/PHPMailer.html#methodAddEmbeddedImage">PHPMailer::AddEmbeddedImage()</a> in class.phpmailer.php</div>
+ <div class="index-item-description">Adds an embedded attachment. This can include images, sounds, and just about any other document. Make sure to set the $type to an image type. For JPEG images use &quot;image/jpeg&quot; and for GIF images use &quot;image/gif&quot;.</div>
+ </dd>
+ <dt class="field">
+ <span class="method-title">AddReplyTo</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/PHPMailer.html#methodAddReplyTo">PHPMailer::AddReplyTo()</a> in class.phpmailer.php</div>
+ <div class="index-item-description">Adds a &quot;Reply-to&quot; address.</div>
+ </dd>
+ <dt class="field">
+ <span class="method-title">AddStringAttachment</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/PHPMailer.html#methodAddStringAttachment">PHPMailer::AddStringAttachment()</a> in class.phpmailer.php</div>
+ <div class="index-item-description">Adds a string or binary attachment (non-filesystem) to the list.</div>
+ </dd>
+ <dt class="field">
+ <span class="method-title">Authenticate</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/SMTP.html#methodAuthenticate">SMTP::Authenticate()</a> in class.smtp.php</div>
+ <div class="index-item-description">Performs SMTP authentication. Must be run after running the Hello() method. Returns true if successfully authenticated.</div>
+ </dd>
+ </dl>
+ <a name="b"></a>
+ <div class="index-letter-section">
+ <div style="float: left" class="index-letter-title">b</div>
+ <div style="float: right"><a href="#top">top</a></div>
+ <div style="clear: both"></div>
+ </div>
+ <dl>
+ <dt class="field">
+ <span class="var-title">$Body</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/PHPMailer.html#var$Body">PHPMailer::$Body</a> in class.phpmailer.php</div>
+ <div class="index-item-description">Sets the Body of the message. This can be either an HTML or text body.</div>
+ </dd>
+ </dl>
+ <a name="c"></a>
+ <div class="index-letter-section">
+ <div style="float: left" class="index-letter-title">c</div>
+ <div style="float: right"><a href="#top">top</a></div>
+ <div style="clear: both"></div>
+ </div>
+ <dl>
+ <dt class="field">
+ <span class="var-title">$CharSet</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/PHPMailer.html#var$CharSet">PHPMailer::$CharSet</a> in class.phpmailer.php</div>
+ <div class="index-item-description">Sets the CharSet of the message.</div>
+ </dd>
+ <dt class="field">
+ <span class="var-title">$ConfirmReadingTo</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/PHPMailer.html#var$ConfirmReadingTo">PHPMailer::$ConfirmReadingTo</a> in class.phpmailer.php</div>
+ <div class="index-item-description">Sets the email address that a reading confirmation will be sent.</div>
+ </dd>
+ <dt class="field">
+ <span class="var-title">$ContentType</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/PHPMailer.html#var$ContentType">PHPMailer::$ContentType</a> in class.phpmailer.php</div>
+ <div class="index-item-description">Sets the Content-type of the message.</div>
+ </dd>
+ <dt class="field">
+ <span class="var-title">$CRLF</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/SMTP.html#var$CRLF">SMTP::$CRLF</a> in class.smtp.php</div>
+ <div class="index-item-description">SMTP reply line ending</div>
+ </dd>
+ <dt class="field">
+ <span class="include-title">class.phpmailer.php</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/_class_phpmailer_php.html">class.phpmailer.php</a> in class.phpmailer.php</div>
+ </dd>
+ <dt class="field">
+ <span class="include-title">class.smtp.php</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/_class_smtp_php.html">class.smtp.php</a> in class.smtp.php</div>
+ </dd>
+ <dt class="field">
+ <span class="method-title">ClearAddresses</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/PHPMailer.html#methodClearAddresses">PHPMailer::ClearAddresses()</a> in class.phpmailer.php</div>
+ <div class="index-item-description">Clears all recipients assigned in the TO array. Returns void.</div>
+ </dd>
+ <dt class="field">
+ <span class="method-title">ClearAllRecipients</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/PHPMailer.html#methodClearAllRecipients">PHPMailer::ClearAllRecipients()</a> in class.phpmailer.php</div>
+ <div class="index-item-description">Clears all recipients assigned in the TO, CC and BCC array. Returns void.</div>
+ </dd>
+ <dt class="field">
+ <span class="method-title">ClearAttachments</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/PHPMailer.html#methodClearAttachments">PHPMailer::ClearAttachments()</a> in class.phpmailer.php</div>
+ <div class="index-item-description">Clears all previously set filesystem, string, and binary attachments. Returns void.</div>
+ </dd>
+ <dt class="field">
+ <span class="method-title">ClearBCCs</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/PHPMailer.html#methodClearBCCs">PHPMailer::ClearBCCs()</a> in class.phpmailer.php</div>
+ <div class="index-item-description">Clears all recipients assigned in the BCC array. Returns void.</div>
+ </dd>
+ <dt class="field">
+ <span class="method-title">ClearCCs</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/PHPMailer.html#methodClearCCs">PHPMailer::ClearCCs()</a> in class.phpmailer.php</div>
+ <div class="index-item-description">Clears all recipients assigned in the CC array. Returns void.</div>
+ </dd>
+ <dt class="field">
+ <span class="method-title">ClearCustomHeaders</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/PHPMailer.html#methodClearCustomHeaders">PHPMailer::ClearCustomHeaders()</a> in class.phpmailer.php</div>
+ <div class="index-item-description">Clears all custom headers. Returns void.</div>
+ </dd>
+ <dt class="field">
+ <span class="method-title">ClearReplyTos</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/PHPMailer.html#methodClearReplyTos">PHPMailer::ClearReplyTos()</a> in class.phpmailer.php</div>
+ <div class="index-item-description">Clears all recipients assigned in the ReplyTo array. Returns void.</div>
+ </dd>
+ <dt class="field">
+ <span class="method-title">Close</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/SMTP.html#methodClose">SMTP::Close()</a> in class.smtp.php</div>
+ <div class="index-item-description">Closes the socket and cleans up the state of the class.</div>
+ </dd>
+ <dt class="field">
+ <span class="method-title">Connect</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/SMTP.html#methodConnect">SMTP::Connect()</a> in class.smtp.php</div>
+ <div class="index-item-description">Connect to the server specified on the port specified.</div>
+ </dd>
+ </dl>
+ <a name="d"></a>
+ <div class="index-letter-section">
+ <div style="float: left" class="index-letter-title">d</div>
+ <div style="float: right"><a href="#top">top</a></div>
+ <div style="clear: both"></div>
+ </div>
+ <dl>
+ <dt class="field">
+ <span class="var-title">$do_debug</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/SMTP.html#var$do_debug">SMTP::$do_debug</a> in class.smtp.php</div>
+ <div class="index-item-description">Sets whether debugging is turned on</div>
+ </dd>
+ <dt class="field">
+ <span class="method-title">Data</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/SMTP.html#methodData">SMTP::Data()</a> in class.smtp.php</div>
+ <div class="index-item-description">Issues a data command and sends the msg_data to the server</div>
+ </dd>
+ </dl>
+ <a name="e"></a>
+ <div class="index-letter-section">
+ <div style="float: left" class="index-letter-title">e</div>
+ <div style="float: right"><a href="#top">top</a></div>
+ <div style="clear: both"></div>
+ </div>
+ <dl>
+ <dt class="field">
+ <span class="var-title">$Encoding</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/PHPMailer.html#var$Encoding">PHPMailer::$Encoding</a> in class.phpmailer.php</div>
+ <div class="index-item-description">Sets the Encoding of the message. Options for this are &quot;8bit&quot;, &quot;7bit&quot;, &quot;binary&quot;, &quot;base64&quot;, and &quot;quoted-printable&quot;.</div>
+ </dd>
+ <dt class="field">
+ <span class="var-title">$ErrorInfo</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/PHPMailer.html#var$ErrorInfo">PHPMailer::$ErrorInfo</a> in class.phpmailer.php</div>
+ <div class="index-item-description">Holds the most recent mailer error message.</div>
+ </dd>
+ <dt class="field">
+ <span class="method-title">Expand</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/SMTP.html#methodExpand">SMTP::Expand()</a> in class.smtp.php</div>
+ <div class="index-item-description">Expand takes the name and asks the server to list all the people who are members of the _list_. Expand will return back and array of the result or false if an error occurs.</div>
+ </dd>
+ </dl>
+ <a name="f"></a>
+ <div class="index-letter-section">
+ <div style="float: left" class="index-letter-title">f</div>
+ <div style="float: right"><a href="#top">top</a></div>
+ <div style="clear: both"></div>
+ </div>
+ <dl>
+ <dt class="field">
+ <span class="var-title">$From</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/PHPMailer.html#var$From">PHPMailer::$From</a> in class.phpmailer.php</div>
+ <div class="index-item-description">Sets the From email address for the message.</div>
+ </dd>
+ <dt class="field">
+ <span class="var-title">$FromName</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/PHPMailer.html#var$FromName">PHPMailer::$FromName</a> in class.phpmailer.php</div>
+ <div class="index-item-description">Sets the From name of the message.</div>
+ </dd>
+ </dl>
+ <a name="h"></a>
+ <div class="index-letter-section">
+ <div style="float: left" class="index-letter-title">h</div>
+ <div style="float: right"><a href="#top">top</a></div>
+ <div style="clear: both"></div>
+ </div>
+ <dl>
+ <dt class="field">
+ <span class="var-title">$Helo</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/PHPMailer.html#var$Helo">PHPMailer::$Helo</a> in class.phpmailer.php</div>
+ <div class="index-item-description">Sets the SMTP HELO of the message (Default is $Hostname).</div>
+ </dd>
+ <dt class="field">
+ <span class="var-title">$Host</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/PHPMailer.html#var$Host">PHPMailer::$Host</a> in class.phpmailer.php</div>
+ <div class="index-item-description">Sets the SMTP hosts. All hosts must be separated by a semicolon. You can also specify a different port for each host by using this format: [hostname:port] (e.g. &quot;smtp1.example.com:25;smtp2.example.com&quot;).</div>
+ </dd>
+ <dt class="field">
+ <span class="var-title">$Hostname</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/PHPMailer.html#var$Hostname">PHPMailer::$Hostname</a> in class.phpmailer.php</div>
+ <div class="index-item-description">Sets the hostname to use in Message-Id and Received headers and as default HELO string. If empty, the value returned by SERVER_NAME is used or 'localhost.localdomain'.</div>
+ </dd>
+ <dt class="field">
+ <span class="method-title">Hello</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/SMTP.html#methodHello">SMTP::Hello()</a> in class.smtp.php</div>
+ <div class="index-item-description">Sends the HELO command to the smtp server.</div>
+ </dd>
+ <dt class="field">
+ <span class="method-title">Help</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/SMTP.html#methodHelp">SMTP::Help()</a> in class.smtp.php</div>
+ <div class="index-item-description">Gets help information on the keyword specified. If the keyword</div>
+ </dd>
+ </dl>
+ <a name="i"></a>
+ <div class="index-letter-section">
+ <div style="float: left" class="index-letter-title">i</div>
+ <div style="float: right"><a href="#top">top</a></div>
+ <div style="clear: both"></div>
+ </div>
+ <dl>
+ <dt class="field">
+ <span class="method-title">IsError</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/PHPMailer.html#methodIsError">PHPMailer::IsError()</a> in class.phpmailer.php</div>
+ <div class="index-item-description">Returns true if an error occurred.</div>
+ </dd>
+ <dt class="field">
+ <span class="method-title">IsHTML</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/PHPMailer.html#methodIsHTML">PHPMailer::IsHTML()</a> in class.phpmailer.php</div>
+ <div class="index-item-description">Sets message type to HTML.</div>
+ </dd>
+ <dt class="field">
+ <span class="method-title">IsMail</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/PHPMailer.html#methodIsMail">PHPMailer::IsMail()</a> in class.phpmailer.php</div>
+ <div class="index-item-description">Sets Mailer to send message using PHP mail() function.</div>
+ </dd>
+ <dt class="field">
+ <span class="method-title">IsQmail</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/PHPMailer.html#methodIsQmail">PHPMailer::IsQmail()</a> in class.phpmailer.php</div>
+ <div class="index-item-description">Sets Mailer to send message using the qmail MTA.</div>
+ </dd>
+ <dt class="field">
+ <span class="method-title">IsSendmail</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/PHPMailer.html#methodIsSendmail">PHPMailer::IsSendmail()</a> in class.phpmailer.php</div>
+ <div class="index-item-description">Sets Mailer to send message using the $Sendmail program.</div>
+ </dd>
+ <dt class="field">
+ <span class="method-title">IsSMTP</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/PHPMailer.html#methodIsSMTP">PHPMailer::IsSMTP()</a> in class.phpmailer.php</div>
+ <div class="index-item-description">Sets Mailer to send message using SMTP.</div>
+ </dd>
+ </dl>
+ <a name="m"></a>
+ <div class="index-letter-section">
+ <div style="float: left" class="index-letter-title">m</div>
+ <div style="float: right"><a href="#top">top</a></div>
+ <div style="clear: both"></div>
+ </div>
+ <dl>
+ <dt class="field">
+ <span class="var-title">$Mailer</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/PHPMailer.html#var$Mailer">PHPMailer::$Mailer</a> in class.phpmailer.php</div>
+ <div class="index-item-description">Method to send mail: (&quot;mail&quot;, &quot;sendmail&quot;, or &quot;smtp&quot;).</div>
+ </dd>
+ <dt class="field">
+ <span class="method-title">Mail</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/SMTP.html#methodMail">SMTP::Mail()</a> in class.smtp.php</div>
+ <div class="index-item-description">Starts a mail transaction from the email address specified in $from. Returns true if successful or false otherwise. If True the mail transaction is started and then one or more Recipient commands may be called followed by a Data command.</div>
+ </dd>
+ </dl>
+ <a name="n"></a>
+ <div class="index-letter-section">
+ <div style="float: left" class="index-letter-title">n</div>
+ <div style="float: right"><a href="#top">top</a></div>
+ <div style="clear: both"></div>
+ </div>
+ <dl>
+ <dt class="field">
+ <span class="method-title">Noop</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/SMTP.html#methodNoop">SMTP::Noop()</a> in class.smtp.php</div>
+ <div class="index-item-description">Sends the command NOOP to the SMTP server.</div>
+ </dd>
+ </dl>
+ <a name="p"></a>
+ <div class="index-letter-section">
+ <div style="float: left" class="index-letter-title">p</div>
+ <div style="float: right"><a href="#top">top</a></div>
+ <div style="clear: both"></div>
+ </div>
+ <dl>
+ <dt class="field">
+ <span class="var-title">$Password</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/PHPMailer.html#var$Password">PHPMailer::$Password</a> in class.phpmailer.php</div>
+ <div class="index-item-description">Sets SMTP password.</div>
+ </dd>
+ <dt class="field">
+ <span class="var-title">$PluginDir</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/PHPMailer.html#var$PluginDir">PHPMailer::$PluginDir</a> in class.phpmailer.php</div>
+ <div class="index-item-description">Path to PHPMailer plugins. This is now only useful if the SMTP class is in a different directory than the PHP include path.</div>
+ </dd>
+ <dt class="field">
+ <span class="var-title">$Port</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/PHPMailer.html#var$Port">PHPMailer::$Port</a> in class.phpmailer.php</div>
+ <div class="index-item-description">Sets the default SMTP server port.</div>
+ </dd>
+ <dt class="field">
+ <span class="var-title">$Priority</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/PHPMailer.html#var$Priority">PHPMailer::$Priority</a> in class.phpmailer.php</div>
+ <div class="index-item-description">Email priority (1 = High, 3 = Normal, 5 = low).</div>
+ </dd>
+ <dt class="field">
+ PHPMailer
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/PHPMailer.html">PHPMailer</a> in class.phpmailer.php</div>
+ <div class="index-item-description">PHPMailer - PHP email transport class</div>
+ </dd>
+ </dl>
+ <a name="q"></a>
+ <div class="index-letter-section">
+ <div style="float: left" class="index-letter-title">q</div>
+ <div style="float: right"><a href="#top">top</a></div>
+ <div style="clear: both"></div>
+ </div>
+ <dl>
+ <dt class="field">
+ <span class="method-title">Quit</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/SMTP.html#methodQuit">SMTP::Quit()</a> in class.smtp.php</div>
+ <div class="index-item-description">Sends the quit command to the server and then closes the socket if there is no error or the $close_on_error argument is true.</div>
+ </dd>
+ </dl>
+ <a name="r"></a>
+ <div class="index-letter-section">
+ <div style="float: left" class="index-letter-title">r</div>
+ <div style="float: right"><a href="#top">top</a></div>
+ <div style="clear: both"></div>
+ </div>
+ <dl>
+ <dt class="field">
+ <span class="method-title">Recipient</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/SMTP.html#methodRecipient">SMTP::Recipient()</a> in class.smtp.php</div>
+ <div class="index-item-description">Sends the command RCPT to the SMTP server with the TO: argument of $to.</div>
+ </dd>
+ <dt class="field">
+ <span class="method-title">Reset</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/SMTP.html#methodReset">SMTP::Reset()</a> in class.smtp.php</div>
+ <div class="index-item-description">Sends the RSET command to abort and transaction that is currently in progress. Returns true if successful false otherwise.</div>
+ </dd>
+ </dl>
+ <a name="s"></a>
+ <div class="index-letter-section">
+ <div style="float: left" class="index-letter-title">s</div>
+ <div style="float: right"><a href="#top">top</a></div>
+ <div style="clear: both"></div>
+ </div>
+ <dl>
+ <dt class="field">
+ <span class="var-title">$Sender</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/PHPMailer.html#var$Sender">PHPMailer::$Sender</a> in class.phpmailer.php</div>
+ <div class="index-item-description">Sets the Sender email (Return-Path) of the message. If not empty, will be sent via -f to sendmail or as 'MAIL FROM' in smtp mode.</div>
+ </dd>
+ <dt class="field">
+ <span class="var-title">$Sendmail</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/PHPMailer.html#var$Sendmail">PHPMailer::$Sendmail</a> in class.phpmailer.php</div>
+ <div class="index-item-description">Sets the path of the sendmail program.</div>
+ </dd>
+ <dt class="field">
+ <span class="var-title">$SMTPAuth</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/PHPMailer.html#var$SMTPAuth">PHPMailer::$SMTPAuth</a> in class.phpmailer.php</div>
+ <div class="index-item-description">Sets SMTP authentication. Utilizes the Username and Password variables.</div>
+ </dd>
+ <dt class="field">
+ <span class="var-title">$SMTPDebug</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/PHPMailer.html#var$SMTPDebug">PHPMailer::$SMTPDebug</a> in class.phpmailer.php</div>
+ <div class="index-item-description">Sets SMTP class debugging on or off.</div>
+ </dd>
+ <dt class="field">
+ <span class="var-title">$SMTPKeepAlive</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/PHPMailer.html#var$SMTPKeepAlive">PHPMailer::$SMTPKeepAlive</a> in class.phpmailer.php</div>
+ <div class="index-item-description">Prevents the SMTP connection from being closed after each mail sending. If this is set to true then to close the connection requires an explicit call to SmtpClose().</div>
+ </dd>
+ <dt class="field">
+ <span class="var-title">$SMTP_PORT</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/SMTP.html#var$SMTP_PORT">SMTP::$SMTP_PORT</a> in class.smtp.php</div>
+ <div class="index-item-description">SMTP server port</div>
+ </dd>
+ <dt class="field">
+ <span class="var-title">$Subject</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/PHPMailer.html#var$Subject">PHPMailer::$Subject</a> in class.phpmailer.php</div>
+ <div class="index-item-description">Sets the Subject of the message.</div>
+ </dd>
+ <dt class="field">
+ <span class="method-title">Send</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/SMTP.html#methodSend">SMTP::Send()</a> in class.smtp.php</div>
+ <div class="index-item-description">Starts a mail transaction from the email address specified in</div>
+ </dd>
+ <dt class="field">
+ <span class="method-title">Send</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/PHPMailer.html#methodSend">PHPMailer::Send()</a> in class.phpmailer.php</div>
+ <div class="index-item-description">Creates message and assigns Mailer. If the message is not sent successfully then it returns false. Use the ErrorInfo variable to view description of the error.</div>
+ </dd>
+ <dt class="field">
+ <span class="method-title">SendAndMail</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/SMTP.html#methodSendAndMail">SMTP::SendAndMail()</a> in class.smtp.php</div>
+ <div class="index-item-description">Starts a mail transaction from the email address specified in</div>
+ </dd>
+ <dt class="field">
+ <span class="method-title">SendOrMail</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/SMTP.html#methodSendOrMail">SMTP::SendOrMail()</a> in class.smtp.php</div>
+ <div class="index-item-description">Starts a mail transaction from the email address specified in</div>
+ </dd>
+ <dt class="field">
+ <span class="method-title">SetLanguage</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/PHPMailer.html#methodSetLanguage">PHPMailer::SetLanguage()</a> in class.phpmailer.php</div>
+ <div class="index-item-description">Sets the language for all class error messages. Returns false if it cannot load the language file. The default language type is English.</div>
+ </dd>
+ <dt class="field">
+ <span class="method-title">SMTP</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/SMTP.html#methodSMTP">SMTP::SMTP()</a> in class.smtp.php</div>
+ <div class="index-item-description">Initialize the class so that the data is in a known state.</div>
+ </dd>
+ <dt class="field">
+ SMTP
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/SMTP.html">SMTP</a> in class.smtp.php</div>
+ <div class="index-item-description">SMTP is rfc 821 compliant and implements all the rfc 821 SMTP commands except TURN which will always return a not implemented error. SMTP also provides some utility methods for sending mail to an SMTP server.</div>
+ </dd>
+ <dt class="field">
+ <span class="method-title">SmtpClose</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/PHPMailer.html#methodSmtpClose">PHPMailer::SmtpClose()</a> in class.phpmailer.php</div>
+ <div class="index-item-description">Closes the active SMTP session if one exists.</div>
+ </dd>
+ </dl>
+ <a name="t"></a>
+ <div class="index-letter-section">
+ <div style="float: left" class="index-letter-title">t</div>
+ <div style="float: right"><a href="#top">top</a></div>
+ <div style="clear: both"></div>
+ </div>
+ <dl>
+ <dt class="field">
+ <span class="var-title">$Timeout</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/PHPMailer.html#var$Timeout">PHPMailer::$Timeout</a> in class.phpmailer.php</div>
+ <div class="index-item-description">Sets the SMTP server timeout in seconds. This function will not work with the win32 version.</div>
+ </dd>
+ <dt class="field">
+ <span class="method-title">Turn</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/SMTP.html#methodTurn">SMTP::Turn()</a> in class.smtp.php</div>
+ <div class="index-item-description">This is an optional command for SMTP that this class does not support. This method is here to make the RFC821 Definition complete for this class and __may__ be implimented in the future</div>
+ </dd>
+ </dl>
+ <a name="u"></a>
+ <div class="index-letter-section">
+ <div style="float: left" class="index-letter-title">u</div>
+ <div style="float: right"><a href="#top">top</a></div>
+ <div style="clear: both"></div>
+ </div>
+ <dl>
+ <dt class="field">
+ <span class="var-title">$Username</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/PHPMailer.html#var$Username">PHPMailer::$Username</a> in class.phpmailer.php</div>
+ <div class="index-item-description">Sets SMTP username.</div>
+ </dd>
+ </dl>
+ <a name="v"></a>
+ <div class="index-letter-section">
+ <div style="float: left" class="index-letter-title">v</div>
+ <div style="float: right"><a href="#top">top</a></div>
+ <div style="clear: both"></div>
+ </div>
+ <dl>
+ <dt class="field">
+ <span class="var-title">$Version</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/PHPMailer.html#var$Version">PHPMailer::$Version</a> in class.phpmailer.php</div>
+ <div class="index-item-description">Holds PHPMailer version.</div>
+ </dd>
+ <dt class="field">
+ <span class="method-title">Verify</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/SMTP.html#methodVerify">SMTP::Verify()</a> in class.smtp.php</div>
+ <div class="index-item-description">Verifies that the name is recognized by the server.</div>
+ </dd>
+ </dl>
+ <a name="w"></a>
+ <div class="index-letter-section">
+ <div style="float: left" class="index-letter-title">w</div>
+ <div style="float: right"><a href="#top">top</a></div>
+ <div style="clear: both"></div>
+ </div>
+ <dl>
+ <dt class="field">
+ <span class="var-title">$WordWrap</span>
+ </dt>
+ <dd class="index-item-body">
+ <div class="index-item-details"><a href="PHPMailer/PHPMailer.html#var$WordWrap">PHPMailer::$WordWrap</a> in class.phpmailer.php</div>
+ <div class="index-item-description">Sets word wrapping on the body of the message to a given number of characters.</div>
+ </dd>
+ </dl>
+
+<div class="index-letter-menu">
+ <a class="index-letter" href="elementindex_PHPMailer.html#a">a</a>
+ <a class="index-letter" href="elementindex_PHPMailer.html#b">b</a>
+ <a class="index-letter" href="elementindex_PHPMailer.html#c">c</a>
+ <a class="index-letter" href="elementindex_PHPMailer.html#d">d</a>
+ <a class="index-letter" href="elementindex_PHPMailer.html#e">e</a>
+ <a class="index-letter" href="elementindex_PHPMailer.html#f">f</a>
+ <a class="index-letter" href="elementindex_PHPMailer.html#h">h</a>
+ <a class="index-letter" href="elementindex_PHPMailer.html#i">i</a>
+ <a class="index-letter" href="elementindex_PHPMailer.html#m">m</a>
+ <a class="index-letter" href="elementindex_PHPMailer.html#n">n</a>
+ <a class="index-letter" href="elementindex_PHPMailer.html#p">p</a>
+ <a class="index-letter" href="elementindex_PHPMailer.html#q">q</a>
+ <a class="index-letter" href="elementindex_PHPMailer.html#r">r</a>
+ <a class="index-letter" href="elementindex_PHPMailer.html#s">s</a>
+ <a class="index-letter" href="elementindex_PHPMailer.html#t">t</a>
+ <a class="index-letter" href="elementindex_PHPMailer.html#u">u</a>
+ <a class="index-letter" href="elementindex_PHPMailer.html#v">v</a>
+ <a class="index-letter" href="elementindex_PHPMailer.html#w">w</a>
+</div> </body>
+</html> \ No newline at end of file
diff --git a/site/vendors/phpmailer/phpdoc/errors.html b/site/vendors/phpmailer/phpdoc/errors.html
new file mode 100644
index 0000000..d5781a0
--- /dev/null
+++ b/site/vendors/phpmailer/phpdoc/errors.html
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+ <html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <!-- template designed by Marco Von Ballmoos -->
+ <title>phpDocumentor Parser Errors and Warnings</title>
+ <link rel="stylesheet" href="media/stylesheet.css" />
+ <meta http-equiv='Content-Type' content='text/html; charset=iso-8859-1'/>
+ </head>
+ <body>
+ <a href="#Post-parsing">Post-parsing</a><br>
+<a href="#class.smtp.php">class.smtp.php</a><br>
+<h1>class.phpmailer.php</h1>
+<h2>Warnings:</h2><br>
+<b>Warning on line 1530</b> - no @package tag was used in a DocBlock for file C:\dev\phpDocumentor-1.2.0\Classes\class.phpmailer.php<br>
+<h1>class.smtp.php</h1>
+<h2>Warnings:</h2><br>
+<b>Warning on line 1039</b> - no @package tag was used in a DocBlock for file C:\dev\phpDocumentor-1.2.0\Classes\class.smtp.php<br>
+ <p class="notes" id="credit">
+ Documention generated on Mon, 28 Jul 2003 23:25:50 -0400 by <a href="http://www.phpdoc.org" target="_blank">phpDocumentor 1.2.0</a>
+ </p>
+ </body>
+</html> \ No newline at end of file
diff --git a/site/vendors/phpmailer/phpdoc/index.html b/site/vendors/phpmailer/phpdoc/index.html
new file mode 100644
index 0000000..f2b2c7a
--- /dev/null
+++ b/site/vendors/phpmailer/phpdoc/index.html
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!DOCTYPE html
+ PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//FR"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">
+ <html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+ <!-- Generated by phpDocumentor on Mon, 28 Jul 2003 23:25:49 -0400 -->
+ <title>Generated Documentation</title>
+ <meta http-equiv='Content-Type' content='text/html; charset=iso-8859-1'/>
+</head>
+
+<FRAMESET rows='100,*'>
+ <FRAME src='packages.html' name='left_top' frameborder="1" bordercolor="#999999">
+ <FRAMESET cols='25%,*'>
+ <FRAME src='li_PHPMailer.html' name='left_bottom' frameborder="1" bordercolor="#999999">
+ <FRAME src='blank.html' name='right' frameborder="1" bordercolor="#999999">
+ </FRAMESET>
+ <NOFRAMES>
+ <H2>Frame Alert</H2>
+ <P>This document is designed to be viewed using the frames feature.
+ If you see this message, you are using a non-frame-capable web client.</P>
+ </NOFRAMES>
+</FRAMESET>
+</HTML> \ No newline at end of file
diff --git a/site/vendors/phpmailer/phpdoc/li_PHPMailer.html b/site/vendors/phpmailer/phpdoc/li_PHPMailer.html
new file mode 100644
index 0000000..ec8456a
--- /dev/null
+++ b/site/vendors/phpmailer/phpdoc/li_PHPMailer.html
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+ <html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <!-- template designed by Marco Von Ballmoos -->
+ <title></title>
+ <link rel="stylesheet" href="media/stylesheet.css" />
+ <meta http-equiv='Content-Type' content='text/html; charset=iso-8859-1'/>
+ </head>
+ <body>
+ <div class="package-title">PHPMailer</div>
+<div class="package-details">
+
+ <dl class="tree">
+
+ <dt class="folder-title">Description</dt>
+ <dd>
+ <a href='classtrees_PHPMailer.html' target='right'>Class trees</a><br />
+ <a href='elementindex_PHPMailer.html' target='right'>Index of elements</a><br />
+ </dd>
+
+
+
+ <dt class="folder-title">Classes</dt>
+ <dd><a href='PHPMailer/PHPMailer.html' target='right'>PHPMailer</a></dd>
+ <dd><a href='PHPMailer/SMTP.html' target='right'>SMTP</a></dd>
+ <dt class="folder-title">Files</dt>
+ <dd><a href='PHPMailer/_class_phpmailer_php.html' target='right'>class.phpmailer.php</a></dd>
+ <dd><a href='PHPMailer/_class_smtp_php.html' target='right'>class.smtp.php</a></dd>
+
+
+ </dl>
+</div>
+<p class="notes"><a href="http://www.phpdoc.org" target="_blank">phpDocumentor v <span class="field">1.2.0</span></a></p>
+</BODY>
+</HTML> \ No newline at end of file
diff --git a/site/vendors/phpmailer/phpdoc/media/banner.css b/site/vendors/phpmailer/phpdoc/media/banner.css
new file mode 100644
index 0000000..f2149eb
--- /dev/null
+++ b/site/vendors/phpmailer/phpdoc/media/banner.css
@@ -0,0 +1,32 @@
+body
+{
+ background-color: #CCCCFF;
+ margin: 0px;
+ padding: 0px;
+}
+
+/* Banner (top bar) classes */
+
+.banner { }
+
+.banner-menu
+{
+ clear: both;
+ padding: .5em;
+ border-top: 2px solid #6666AA;
+}
+
+.banner-title
+{
+ text-align: right;
+ font-size: 20pt;
+ font-weight: bold;
+ margin: .2em;
+}
+
+.package-selector
+{
+ background-color: #AAAADD;
+ border: 1px solid black;
+ color: yellow;
+}
diff --git a/site/vendors/phpmailer/phpdoc/media/stylesheet.css b/site/vendors/phpmailer/phpdoc/media/stylesheet.css
new file mode 100644
index 0000000..7a81139
--- /dev/null
+++ b/site/vendors/phpmailer/phpdoc/media/stylesheet.css
@@ -0,0 +1,133 @@
+a { color: #336699; text-decoration: none; }
+a:hover { color: #6699CC; text-decoration: underline; }
+a:active { color: #6699CC; text-decoration: underline; }
+
+body, table { font-family: Georgia, Times New Roman, Times, serif; font-size: 10pt }
+p, li { line-height: 140% }
+a img { border: 0px; }
+dd { margin-left: 0px; padding-left: 1em; }
+
+/* Page layout/boxes */
+
+.info-box {}
+.info-box-title { margin: 1em 0em 0em 0em; padding: .25em; font-weight: normal; font-size: 14pt; border: 2px solid #999999; background-color: #CCCCFF }
+.info-box-body { border: 1px solid #999999; padding: .5em; }
+.nav-bar { font-size: 8pt; white-space: nowrap; text-align: right; padding: .2em; margin: 0em 0em 1em 0em; }
+
+.oddrow { background-color: #F8F8F8; border: 1px solid #AAAAAA; padding: .5em; margin-bottom: 1em}
+.evenrow { border: 1px solid #AAAAAA; padding: .5em; margin-bottom: 1em}
+
+.page-body { max-width: 800px; margin: auto; }
+.tree dl { margin: 0px }
+
+/* Index formatting classes */
+
+.index-item-body { margin-top: .5em; margin-bottom: .5em}
+.index-item-description { margin-top: .25em }
+.index-item-details { font-weight: normal; font-style: italic; font-size: 8pt }
+.index-letter-section { background-color: #EEEEEE; border: 1px dotted #999999; padding: .5em; margin-bottom: 1em}
+.index-letter-title { font-size: 12pt; font-weight: bold }
+.index-letter-menu { text-align: center; margin: 1em }
+.index-letter { font-size: 12pt }
+
+/* Docbook classes */
+
+.description {}
+.short-description { font-weight: bold; color: #666666; }
+.tags { padding-left: 0em; margin-left: 3em; color: #666666; list-style-type: square; }
+.parameters { padding-left: 0em; margin-left: 3em; font-style: italic; list-style-type: square; }
+.redefinitions { font-size: 8pt; padding-left: 0em; margin-left: 2em; }
+.package { }
+.package-title { font-weight: bold; font-size: 14pt; border-bottom: 1px solid black }
+.package-details { font-size: 85%; }
+.sub-package { font-weight: bold; font-size: 120% }
+.tutorial { border-width: thin; border-color: #0066ff }
+.tutorial-nav-box { width: 100%; border: 1px solid #999999; background-color: #F8F8F8; }
+.nav-button-disabled { color: #999999; }
+.nav-button:active,
+.nav-button:focus,
+.nav-button:hover { background-color: #DDDDDD; outline: 1px solid #999999; text-decoration: none }
+.folder-title { font-style: italic }
+
+/* Generic formatting */
+
+.field { font-weight: bold; }
+.detail { font-size: 8pt; }
+.notes { font-style: italic; font-size: 8pt; }
+.separator { background-color: #999999; height: 2px; }
+.warning { color: #FF6600; }
+.disabled { font-style: italic; color: #999999; }
+
+/* Code elements */
+
+.line-number { }
+
+.class-table { width: 100%; }
+.class-table-header { border-bottom: 1px dotted #666666; text-align: left}
+.class-name { color: #000000; font-weight: bold; }
+
+.method-summary { padding-left: 1em; font-size: 8pt }
+.method-header { }
+.method-definition { margin-bottom: .3em }
+.method-title { font-weight: bold; }
+.method-name { font-weight: bold; }
+.method-signature { font-size: 85%; color: #666666; margin: .5em 0em }
+.method-result { font-style: italic; }
+
+.var-summary { padding-left: 1em; font-size: 8pt; }
+.var-header { }
+.var-title { margin-bottom: .3em }
+.var-type { font-style: italic; }
+.var-name { font-weight: bold; }
+.var-default {}
+.var-description { font-weight: normal; color: #000000; }
+
+.include-title { }
+.include-type { font-style: italic; }
+.include-name { font-weight: bold; }
+
+.const-title { }
+.const-name { font-weight: bold; }
+
+/* Syntax highlighting */
+
+.src-code { border: 1px solid #336699; padding: 1em; background-color: #EEEEEE; }
+
+.src-comm { color: green; }
+.src-id { }
+.src-inc { color: #0000FF; }
+.src-key { color: #0000FF; }
+.src-num { color: #CC0000; }
+.src-str { color: #66cccc; }
+.src-sym { font-weight: bold; }
+.src-var { }
+
+.src-php { font-weight: bold; }
+
+.src-doc { color: #009999 }
+.src-doc-close-template { color: #0000FF }
+.src-doc-coretag { color: #0099FF; font-weight: bold }
+.src-doc-inlinetag { color: #0099FF }
+.src-doc-internal { color: #6699cc }
+.src-doc-tag { color: #0080CC }
+.src-doc-template { color: #0000FF }
+.src-doc-type { font-style: italic }
+.src-doc-var { font-style: italic }
+
+/* tutorial */
+
+.authors { }
+.author { font-style: italic; font-weight: bold }
+.author-blurb { margin: .5em 0em .5em 2em; font-size: 85%; font-weight: normal; font-style: normal }
+.example { border: 1px dashed #999999; background-color: #EEEEEE; padding: .5em }
+.listing { border: 1px dashed #999999; background-color: #EEEEEE; padding: .5em; white-space: nowrap }
+.release-info { font-size: 85%; font-style: italic; margin: 1em 0em }
+.ref-title-box { }
+.ref-title { }
+.ref-purpose { font-style: italic; color: #666666 }
+.ref-synopsis { }
+.title { font-weight: bold; margin: 1em 0em 0em 0em; padding: .25em; border: 2px solid #999999; background-color: #CCCCFF }
+.cmd-synopsis { margin: 1em 0em }
+.cmd-title { font-weight: bold }
+.toc { margin-left: 2em; padding-left: 0em }
+
diff --git a/site/vendors/phpmailer/phpdoc/packages.html b/site/vendors/phpmailer/phpdoc/packages.html
new file mode 100644
index 0000000..fdf40b0
--- /dev/null
+++ b/site/vendors/phpmailer/phpdoc/packages.html
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+ <html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <!-- template designed by Marco Von Ballmoos -->
+ <title></title>
+ <link rel="stylesheet" href="media/stylesheet.css" />
+ <link rel="stylesheet" href="media/banner.css" />
+ <meta http-equiv='Content-Type' content='text/html; charset=iso-8859-1'/>
+ </head>
+ <body>
+ <div class="banner">
+ <div class="banner-title">PHPMailer</div>
+ <div class="banner-menu">
+ <table cellpadding="0" cellspacing="0" style="width: 100%">
+ <tr>
+ <td>
+ </td>
+ <td style="width: 2em">&nbsp;</td>
+ <td style="text-align: right">
+ </td>
+ </tr>
+ </table>
+ </div>
+ </div>
+ </body>
+ </html> \ No newline at end of file
diff --git a/site/vendors/phpmailer/test/phpmailer_test.php b/site/vendors/phpmailer/test/phpmailer_test.php
new file mode 100644
index 0000000..22d6f42
--- /dev/null
+++ b/site/vendors/phpmailer/test/phpmailer_test.php
@@ -0,0 +1,572 @@
+<?php
+/*******************
+ Unit Test
+ Type: phpmailer class
+********************/
+
+$INCLUDE_DIR = "../";
+
+require("phpunit.php");
+require($INCLUDE_DIR . "class.phpmailer.php");
+error_reporting(E_ALL);
+
+/**
+ * Performs authentication tests
+ */
+class phpmailerTest extends TestCase
+{
+ /**
+ * Holds the default phpmailer instance.
+ * @private
+ * @type object
+ */
+ var $Mail = false;
+
+ /**
+ * Holds the SMTP mail host.
+ * @public
+ * @type string
+ */
+ var $Host = "";
+
+ /**
+ * Holds the change log.
+ * @private
+ * @type string array
+ */
+ var $ChangeLog = array();
+
+ /**
+ * Holds the note log.
+ * @private
+ * @type string array
+ */
+ var $NoteLog = array();
+
+ /**
+ * Class constuctor.
+ */
+ function phpmailerTest($name) {
+ /* must define this constructor */
+ $this->TestCase( $name );
+ }
+
+ /**
+ * Run before each test is started.
+ */
+ function setUp() {
+ global $global_vars;
+ global $INCLUDE_DIR;
+
+ $this->Mail = new PHPMailer();
+
+ $this->Mail->Priority = 3;
+ $this->Mail->Encoding = "8bit";
+ $this->Mail->CharSet = "iso-8859-1";
+ $this->Mail->From = "unit_test@phpmailer.sf.net";
+ $this->Mail->FromName = "Unit Tester";
+ $this->Mail->Sender = "";
+ $this->Mail->Subject = "Unit Test";
+ $this->Mail->Body = "";
+ $this->Mail->AltBody = "";
+ $this->Mail->WordWrap = 0;
+ $this->Mail->Host = $global_vars["mail_host"];
+ $this->Mail->Port = 25;
+ $this->Mail->Helo = "localhost.localdomain";
+ $this->Mail->SMTPAuth = false;
+ $this->Mail->Username = "";
+ $this->Mail->Password = "";
+ $this->Mail->PluginDir = $INCLUDE_DIR;
+ $this->Mail->AddReplyTo("no_reply@phpmailer.sf.net", "Reply Guy");
+ $this->Mail->Sender = "unit_test@phpmailer.sf.net";
+
+ if(strlen($this->Mail->Host) > 0)
+ $this->Mail->Mailer = "smtp";
+ else
+ {
+ $this->Mail->Mailer = "mail";
+ $this->Sender = "unit_test@phpmailer.sf.net";
+ }
+
+ global $global_vars;
+ $this->SetAddress($global_vars["mail_to"], "Test User");
+ if(strlen($global_vars["mail_cc"]) > 0)
+ $this->SetAddress($global_vars["mail_cc"], "Carbon User", "cc");
+ }
+
+ /**
+ * Run after each test is completed.
+ */
+ function tearDown() {
+ // Clean global variables
+ $this->Mail = NULL;
+ $this->ChangeLog = array();
+ $this->NoteLog = array();
+ }
+
+
+ /**
+ * Build the body of the message in the appropriate format.
+ * @private
+ * @returns void
+ */
+ function BuildBody() {
+ $this->CheckChanges();
+
+ // Determine line endings for message
+ if($this->Mail->ContentType == "text/html" || strlen($this->Mail->AltBody) > 0)
+ {
+ $eol = "<br/>";
+ $bullet = "<li>";
+ $bullet_start = "<ul>";
+ $bullet_end = "</ul>";
+ }
+ else
+ {
+ $eol = "\n";
+ $bullet = " - ";
+ $bullet_start = "";
+ $bullet_end = "";
+ }
+
+ $ReportBody = "";
+
+ $ReportBody .= "---------------------" . $eol;
+ $ReportBody .= "Unit Test Information" . $eol;
+ $ReportBody .= "---------------------" . $eol;
+ $ReportBody .= "phpmailer version: " . $this->Mail->Version . $eol;
+ $ReportBody .= "Content Type: " . $this->Mail->ContentType . $eol;
+
+ if(strlen($this->Mail->Host) > 0)
+ $ReportBody .= "Host: " . $this->Mail->Host . $eol;
+
+ // If attachments then create an attachment list
+ if(count($this->Mail->attachment) > 0)
+ {
+ $ReportBody .= "Attachments:" . $eol;
+ $ReportBody .= $bullet_start;
+ for($i = 0; $i < count($this->Mail->attachment); $i++)
+ {
+ $ReportBody .= $bullet . "Name: " . $this->Mail->attachment[$i][1] . ", ";
+ $ReportBody .= "Encoding: " . $this->Mail->attachment[$i][3] . ", ";
+ $ReportBody .= "Type: " . $this->Mail->attachment[$i][4] . $eol;
+ }
+ $ReportBody .= $bullet_end . $eol;
+ }
+
+ // If there are changes then list them
+ if(count($this->ChangeLog) > 0)
+ {
+ $ReportBody .= "Changes" . $eol;
+ $ReportBody .= "-------" . $eol;
+
+ $ReportBody .= $bullet_start;
+ for($i = 0; $i < count($this->ChangeLog); $i++)
+ {
+ $ReportBody .= $bullet . $this->ChangeLog[$i][0] . " was changed to [" .
+ $this->ChangeLog[$i][1] . "]" . $eol;
+ }
+ $ReportBody .= $bullet_end . $eol . $eol;
+ }
+
+ // If there are notes then list them
+ if(count($this->NoteLog) > 0)
+ {
+ $ReportBody .= "Notes" . $eol;
+ $ReportBody .= "-----" . $eol;
+
+ $ReportBody .= $bullet_start;
+ for($i = 0; $i < count($this->NoteLog); $i++)
+ {
+ $ReportBody .= $bullet . $this->NoteLog[$i] . $eol;
+ }
+ $ReportBody .= $bullet_end;
+ }
+
+ // Re-attach the original body
+ $this->Mail->Body .= $eol . $eol . $ReportBody;
+ }
+
+ /**
+ * Check which default settings have been changed for the report.
+ * @private
+ * @returns void
+ */
+ function CheckChanges() {
+ if($this->Mail->Priority != 3)
+ $this->AddChange("Priority", $this->Mail->Priority);
+ if($this->Mail->Encoding != "8bit")
+ $this->AddChange("Encoding", $this->Mail->Encoding);
+ if($this->Mail->CharSet != "iso-8859-1")
+ $this->AddChange("CharSet", $this->Mail->CharSet);
+ if($this->Mail->Sender != "")
+ $this->AddChange("Sender", $this->Mail->Sender);
+ if($this->Mail->WordWrap != 0)
+ $this->AddChange("WordWrap", $this->Mail->WordWrap);
+ if($this->Mail->Mailer != "mail")
+ $this->AddChange("Mailer", $this->Mail->Mailer);
+ if($this->Mail->Port != 25)
+ $this->AddChange("Port", $this->Mail->Port);
+ if($this->Mail->Helo != "localhost.localdomain")
+ $this->AddChange("Helo", $this->Mail->Helo);
+ if($this->Mail->SMTPAuth)
+ $this->AddChange("SMTPAuth", "true");
+ }
+
+ /**
+ * Adds a change entry.
+ * @private
+ * @returns void
+ */
+ function AddChange($sName, $sNewValue) {
+ $cur = count($this->ChangeLog);
+ $this->ChangeLog[$cur][0] = $sName;
+ $this->ChangeLog[$cur][1] = $sNewValue;
+ }
+
+ /**
+ * Adds a simple note to the message.
+ * @public
+ * @returns void
+ */
+ function AddNote($sValue) {
+ $this->NoteLog[] = $sValue;
+ }
+
+ /**
+ * Adds all of the addresses
+ * @public
+ * @returns void
+ */
+ function SetAddress($sAddress, $sName = "", $sType = "to") {
+ switch($sType)
+ {
+ case "to":
+ $this->Mail->AddAddress($sAddress, $sName);
+ break;
+ case "cc":
+ $this->Mail->AddCC($sAddress, $sName);
+ break;
+ case "bcc":
+ $this->Mail->AddBCC($sAddress, $sName);
+ break;
+ }
+ }
+
+ /////////////////////////////////////////////////
+ // UNIT TESTS
+ /////////////////////////////////////////////////
+
+ /**
+ * Try a plain message.
+ */
+ function test_WordWrap() {
+
+ $this->Mail->WordWrap = 40;
+ $my_body = "Here is the main body of this message. It should " .
+ "be quite a few lines. It should be wrapped at the " .
+ "40 characters. Make sure that it is.";
+ $nBodyLen = strlen($my_body);
+ $my_body .= "\n\nThis is the above body length: " . $nBodyLen;
+
+ $this->Mail->Body = $my_body;
+ $this->Mail->Subject .= ": Wordwrap";
+
+ $this->BuildBody();
+ $this->assert($this->Mail->Send(), $this->Mail->ErrorInfo);
+ }
+
+ /**
+ * Try a plain message.
+ */
+ function test_Low_Priority() {
+
+ $this->Mail->Priority = 5;
+ $this->Mail->Body = "Here is the main body. There should be " .
+ "a reply to address in this message.";
+ $this->Mail->Subject .= ": Low Priority";
+ $this->Mail->AddReplyTo("nobody@nobody.com", "Nobody (Unit Test)");
+
+ $this->BuildBody();
+ $this->assert($this->Mail->Send(), $this->Mail->ErrorInfo);
+ }
+
+ /**
+ * Simple plain file attachment test.
+ */
+ function test_Multiple_Plain_FileAttachment() {
+
+ $this->Mail->Body = "Here is the text body";
+ $this->Mail->Subject .= ": Plain + Multiple FileAttachments";
+
+ if(!$this->Mail->AddAttachment("test.png"))
+ {
+ $this->assert(false, $this->Mail->ErrorInfo);
+ return;
+ }
+
+ if(!$this->Mail->AddAttachment("phpmailer_test.php", "test.txt"))
+ {
+ $this->assert(false, $this->Mail->ErrorInfo);
+ return;
+ }
+
+ $this->BuildBody();
+ $this->assert($this->Mail->Send(), $this->Mail->ErrorInfo);
+ }
+
+ /**
+ * Simple plain string attachment test.
+ */
+ function test_Plain_StringAttachment() {
+
+ $this->Mail->Body = "Here is the text body";
+ $this->Mail->Subject .= ": Plain + StringAttachment";
+
+ $sAttachment = "These characters are the content of the " .
+ "string attachment.\nThis might be taken from a ".
+ "database or some other such thing. ";
+
+ $this->Mail->AddStringAttachment($sAttachment, "string_attach.txt");
+
+ $this->BuildBody();
+ $this->assert($this->Mail->Send(), $this->Mail->ErrorInfo);
+ }
+
+ /**
+ * Plain quoted-printable message.
+ */
+ function test_Quoted_Printable() {
+
+ $this->Mail->Body = "Here is the main body";
+ $this->Mail->Subject .= ": Plain + Quoted-printable";
+ $this->Mail->Encoding = "quoted-printable";
+
+ $this->BuildBody();
+ $this->assert($this->Mail->Send(), $this->Mail->ErrorInfo);
+ }
+
+ /**
+ * Try a plain message.
+ */
+ function test_Html() {
+
+ $this->Mail->IsHTML(true);
+ $this->Mail->Subject .= ": HTML only";
+
+ $this->Mail->Body = "This is a <b>test message</b> written in HTML. </br>" .
+ "Go to <a href=\"http://phpmailer.sourceforge.net/\">" .
+ "http://phpmailer.sourceforge.net/</a> for new versions of " .
+ "phpmailer. <p/> Thank you!";
+
+ $this->BuildBody();
+ $this->assert($this->Mail->Send(), $this->Mail->ErrorInfo);
+ }
+
+ /**
+ * Simple HTML and attachment test
+ */
+ function test_HTML_Attachment() {
+
+ $this->Mail->Body = "This is the <b>HTML</b> part of the email.";
+ $this->Mail->Subject .= ": HTML + Attachment";
+ $this->Mail->IsHTML(true);
+
+ if(!$this->Mail->AddAttachment("phpmailer_test.php", "test_attach.txt"))
+ {
+ $this->assert(false, $this->Mail->ErrorInfo);
+ return;
+ }
+
+ $this->BuildBody();
+ $this->assert($this->Mail->Send(), $this->Mail->ErrorInfo);
+ }
+
+ /**
+ * An embedded attachment test.
+ */
+ function test_Embedded_Image() {
+
+ $this->Mail->Body = "Embedded Image: <img alt=\"phpmailer\" src=\"cid:my-attach\">" .
+ "Here is an image!</a>";
+ $this->Mail->Subject .= ": Embedded Image";
+ $this->Mail->IsHTML(true);
+
+ if(!$this->Mail->AddEmbeddedImage("test.png", "my-attach", "test.png",
+ "base64", "image/png"))
+ {
+ $this->assert(false, $this->Mail->ErrorInfo);
+ return;
+ }
+
+ $this->BuildBody();
+ $this->assert($this->Mail->Send(), $this->Mail->ErrorInfo);
+ }
+
+ /**
+ * An embedded attachment test.
+ */
+ function test_Multi_Embedded_Image() {
+
+ $this->Mail->Body = "Embedded Image: <img alt=\"phpmailer\" src=\"cid:my-attach\">" .
+ "Here is an image!</a>";
+ $this->Mail->Subject .= ": Embedded Image + Attachment";
+ $this->Mail->IsHTML(true);
+
+ if(!$this->Mail->AddEmbeddedImage("test.png", "my-attach", "test.png",
+ "base64", "image/png"))
+ {
+ $this->assert(false, $this->Mail->ErrorInfo);
+ return;
+ }
+
+ if(!$this->Mail->AddAttachment("phpmailer_test.php", "test.txt"))
+ {
+ $this->assert(false, $this->Mail->ErrorInfo);
+ return;
+ }
+
+ $this->BuildBody();
+ $this->assert($this->Mail->Send(), $this->Mail->ErrorInfo);
+ }
+
+ /**
+ * Simple multipart/alternative test.
+ */
+ function test_AltBody() {
+
+ $this->Mail->Body = "This is the <b>HTML</b> part of the email.";
+ $this->Mail->AltBody = "Here is the text body of this message. " .
+ "It should be quite a few lines. It should be wrapped at the " .
+ "40 characters. Make sure that it is.";
+ $this->Mail->WordWrap = 40;
+ $this->AddNote("This is a mulipart alternative email");
+ $this->Mail->Subject .= ": AltBody + Word Wrap";
+
+ $this->BuildBody();
+ $this->assert($this->Mail->Send(), $this->Mail->ErrorInfo);
+ }
+
+ /**
+ * Simple HTML and attachment test
+ */
+ function test_AltBody_Attachment() {
+
+ $this->Mail->Body = "This is the <b>HTML</b> part of the email.";
+ $this->Mail->AltBody = "This is the text part of the email.";
+ $this->Mail->Subject .= ": AltBody + Attachment";
+ $this->Mail->IsHTML(true);
+
+ if(!$this->Mail->AddAttachment("phpmailer_test.php", "test_attach.txt"))
+ {
+ $this->assert(false, $this->Mail->ErrorInfo);
+ return;
+ }
+
+ $this->BuildBody();
+ $this->assert($this->Mail->Send(), $this->Mail->ErrorInfo);
+
+ $fp = fopen("message.txt", "w");
+ fwrite($fp, $this->Mail->CreateHeader() . $this->Mail->CreateBody());
+ fclose($fp);
+ }
+
+ function test_MultipleSend() {
+ $this->Mail->Body = "Sending two messages without keepalive";
+ $this->BuildBody();
+ $subject = $this->Mail->Subject;
+
+ $this->Mail->Subject = $subject . ": SMTP 1";
+ $this->assert($this->Mail->Send(), $this->Mail->ErrorInfo);
+
+ $this->Mail->Subject = $subject . ": SMTP 2";
+ $this->assert($this->Mail->Send(), $this->Mail->ErrorInfo);
+ }
+
+ function test_SmtpKeepAlive() {
+ $this->Mail->Body = "This was done using the SMTP keep-alive.";
+ $this->BuildBody();
+ $subject = $this->Mail->Subject;
+
+ $this->Mail->SMTPKeepAlive = true;
+ $this->Mail->Subject = $subject . ": SMTP keep-alive 1";
+ $this->assert($this->Mail->Send(), $this->Mail->ErrorInfo);
+
+ $this->Mail->Subject = $subject . ": SMTP keep-alive 2";
+ $this->assert($this->Mail->Send(), $this->Mail->ErrorInfo);
+ $this->Mail->SmtpClose();
+ }
+
+ /**
+ * Tests this denial of service attack:
+ * http://www.cybsec.com/vuln/PHPMailer-DOS.pdf
+ */
+ function test_DenialOfServiceAttack() {
+ $this->Mail->Body = "This should no longer cause a denial of service.";
+ $this->BuildBody();
+
+ $this->Mail->Subject = str_repeat("A", 998);
+ $this->assert($this->Mail->Send(), $this->Mail->ErrorInfo);
+ }
+
+ function test_Error() {
+ $this->Mail->Subject .= ": This should be sent";
+ $this->BuildBody();
+ $this->Mail->ClearAllRecipients(); // no addresses should cause an error
+ $this->assert($this->Mail->IsError() == false, "Error found");
+ $this->assert($this->Mail->Send() == false, "Send succeeded");
+ $this->assert($this->Mail->IsError(), "No error found");
+ $this->assertEquals('You must provide at least one ' .
+ 'recipient email address.', $this->Mail->ErrorInfo);
+ $this->Mail->AddAddress(get("mail_to"));
+ $this->assert($this->Mail->Send(), "Send failed");
+ }
+}
+
+/**
+ * Create and run test instance.
+ */
+
+if(isset($HTTP_GET_VARS))
+ $global_vars = $HTTP_GET_VARS;
+else
+ $global_vars = $_REQUEST;
+
+if(isset($global_vars["submitted"]))
+{
+ echo "Test results:<br>";
+ $suite = new TestSuite( "phpmailerTest" );
+
+ $testRunner = new TestRunner;
+ $testRunner->run($suite);
+ echo "<hr noshade/>";
+}
+
+function get($sName) {
+ global $global_vars;
+ if(isset($global_vars[$sName]))
+ return $global_vars[$sName];
+ else
+ return "";
+}
+
+?>
+
+<html>
+<body>
+<h3>phpmailer Unit Test</h3>
+By entering a SMTP hostname it will automatically perform tests with SMTP.
+
+<form name="phpmailer_unit" action="phpmailer_test.php" method="get">
+<input type="hidden" name="submitted" value="1"/>
+To Address: <input type="text" size="50" name="mail_to" value="<?php echo get("mail_to"); ?>"/>
+<br/>
+Cc Address: <input type="text" size="50" name="mail_cc" value="<?php echo get("mail_cc"); ?>"/>
+<br/>
+SMTP Hostname: <input type="text" size="50" name="mail_host" value="<?php echo get("mail_host"); ?>"/>
+<p/>
+<input type="submit" value="Run Test"/>
+
+</form>
+</body>
+</html>
diff --git a/site/vendors/phpmailer/test/phpunit.php b/site/vendors/phpmailer/test/phpunit.php
new file mode 100644
index 0000000..1d50868
--- /dev/null
+++ b/site/vendors/phpmailer/test/phpunit.php
@@ -0,0 +1,376 @@
+<?php
+//
+// PHP framework for testing, based on the design of "JUnit".
+//
+// Written by Fred Yankowski <fred@ontosys.com>
+// OntoSys, Inc <http://www.OntoSys.com>
+//
+// $Id: phpunit.php,v 1.1 2002/03/30 19:32:17 bmatzelle Exp $
+
+// Copyright (c) 2000 Fred Yankowski
+
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use, copy,
+// modify, merge, publish, distribute, sublicense, and/or sell copies
+// of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+// SOFTWARE.
+//
+error_reporting(E_ERROR | E_WARNING | E_PARSE | E_NOTICE |
+ E_CORE_ERROR | E_CORE_WARNING);
+
+/*
+interface Test {
+ function run(&$aTestResult);
+ function countTestCases();
+}
+*/
+
+function trace($msg) {
+ return;
+ print($msg);
+ flush();
+}
+
+
+class Exception {
+ /* Emulate a Java exception, sort of... */
+ var $message;
+ function Exception($message) {
+ $this->message = $message;
+ }
+ function getMessage() {
+ return $this->message;
+ }
+}
+
+class Assert {
+ function assert($boolean, $message=0) {
+ if (! $boolean)
+ $this->fail($message);
+ }
+
+ function assertEquals($expected, $actual, $message=0) {
+ if ($expected != $actual) {
+ $this->failNotEquals($expected, $actual, "expected", $message);
+ }
+ }
+
+ function assertRegexp($regexp, $actual, $message=false) {
+ if (! preg_match($regexp, $actual)) {
+ $this->failNotEquals($regexp, $actual, "pattern", $message);
+ }
+ }
+
+ function failNotEquals($expected, $actual, $expected_label, $message=0) {
+ // Private function for reporting failure to match.
+ $str = $message ? ($message . ' ') : '';
+ $str .= "($expected_label/actual)<br>";
+ $htmlExpected = htmlspecialchars($expected);
+ $htmlActual = htmlspecialchars($actual);
+ $str .= sprintf("<pre>%s\n--------\n%s</pre>",
+ $htmlExpected, $htmlActual);
+ $this->fail($str);
+ }
+}
+
+class TestCase extends Assert /* implements Test */ {
+ /* Defines context for running tests. Specific context -- such as
+ instance variables, global variables, global state -- is defined
+ by creating a subclass that specializes the setUp() and
+ tearDown() methods. A specific test is defined by a subclass
+ that specializes the runTest() method. */
+ var $fName;
+ var $fResult;
+ var $fExceptions = array();
+
+ function TestCase($name) {
+ $this->fName = $name;
+ }
+
+ function run($testResult=0) {
+ /* Run this single test, by calling the run() method of the
+ TestResult object which will in turn call the runBare() method
+ of this object. That complication allows the TestResult object
+ to do various kinds of progress reporting as it invokes each
+ test. Create/obtain a TestResult object if none was passed in.
+ Note that if a TestResult object was passed in, it must be by
+ reference. */
+ if (! $testResult)
+ $testResult = $this->_createResult();
+ $this->fResult = $testResult;
+ $testResult->run(&$this);
+ $this->fResult = 0;
+ return $testResult;
+ }
+
+ function countTestCases() {
+ return 1;
+ }
+
+ function runTest() {
+ $name = $this->name();
+ // Since isset($this->$name) is false, no way to run defensive checks
+ $this->$name();
+ }
+
+ function setUp() /* expect override */ {
+ //print("TestCase::setUp()<br>\n");
+ }
+
+ function tearDown() /* possible override */ {
+ //print("TestCase::tearDown()<br>\n");
+ }
+
+ ////////////////////////////////////////////////////////////////
+
+
+ function _createResult() /* protected */ {
+ /* override this to use specialized subclass of TestResult */
+ return new TestResult;
+ }
+
+ function fail($message=0) {
+ //printf("TestCase::fail(%s)<br>\n", ($message) ? $message : '');
+ /* JUnit throws AssertionFailedError here. We just record the
+ failure and carry on */
+ $this->fExceptions[] = new Exception(&$message);
+ }
+
+ function error($message) {
+ /* report error that requires correction in the test script
+ itself, or (heaven forbid) in this testing infrastructure */
+ printf('<b>ERROR: ' . $message . '</b><br>');
+ $this->fResult->stop();
+ }
+
+ function failed() {
+ return count($this->fExceptions);
+ }
+
+ function getExceptions() {
+ return $this->fExceptions;
+ }
+
+ function name() {
+ return $this->fName;
+ }
+
+ function runBare() {
+ $this->setup();
+ $this->runTest();
+ $this->tearDown();
+ }
+}
+
+
+class TestSuite /* implements Test */ {
+ /* Compose a set of Tests (instances of TestCase or TestSuite), and
+ run them all. */
+ var $fTests = array();
+
+ function TestSuite($classname=false) {
+ if ($classname) {
+ // Find all methods of the given class whose name starts with
+ // "test" and add them to the test suite. We are just _barely_
+ // able to do this with PHP's limited introspection... Note
+ // that PHP seems to store method names in lower case, and we
+ // have to avoid the constructor function for the TestCase class
+ // superclass. This will fail when $classname starts with
+ // "Test" since that will have a constructor method that will
+ // get matched below and then treated (incorrectly) as a test
+ // method. So don't name any TestCase subclasses as "Test..."!
+ if (floor(phpversion()) >= 4) {
+ // PHP4 introspection, submitted by Dylan Kuhn
+ $names = get_class_methods($classname);
+ while (list($key, $method) = each($names)) {
+ if (preg_match('/^test/', $method) && $method != "testcase") {
+ $this->addTest(new $classname($method));
+ }
+ }
+ }
+ else {
+ $dummy = new $classname("dummy");
+ $names = (array) $dummy;
+ while (list($key, $value) = each($names)) {
+ $type = gettype($value);
+ if ($type == "user function" && preg_match('/^test/', $key)
+ && $key != "testcase") {
+ $this->addTest(new $classname($key));
+ }
+ }
+ }
+ }
+ }
+
+ function addTest($test) {
+ /* Add TestCase or TestSuite to this TestSuite */
+ $this->fTests[] = $test;
+ }
+
+ function run(&$testResult) {
+ /* Run all TestCases and TestSuites comprising this TestSuite,
+ accumulating results in the given TestResult object. */
+ reset($this->fTests);
+ while (list($na, $test) = each($this->fTests)) {
+ if ($testResult->shouldStop())
+ break;
+ $test->run(&$testResult);
+ }
+ }
+
+ function countTestCases() {
+ /* Number of TestCases comprising this TestSuite (including those
+ in any constituent TestSuites) */
+ $count = 0;
+ reset($fTests);
+ while (list($na, $test_case) = each($this->fTests)) {
+ $count += $test_case->countTestCases();
+ }
+ return $count;
+ }
+}
+
+
+class TestFailure {
+ /* Record failure of a single TestCase, associating it with the
+ exception(s) that occurred */
+ var $fFailedTestName;
+ var $fExceptions;
+
+ function TestFailure(&$test, &$exceptions) {
+ $this->fFailedTestName = $test->name();
+ $this->fExceptions = $exceptions;
+ }
+
+ function getExceptions() {
+ return $this->fExceptions;
+ }
+ function getTestName() {
+ return $this->fFailedTestName;
+ }
+}
+
+
+class TestResult {
+ /* Collect the results of running a set of TestCases. */
+ var $fFailures = array();
+ var $fRunTests = 0;
+ var $fStop = false;
+
+ function TestResult() { }
+
+ function _endTest($test) /* protected */ {
+ /* specialize this for end-of-test action, such as progress
+ reports */
+ }
+
+ function getFailures() {
+ return $this->fFailures;
+ }
+
+ function run($test) {
+ /* Run a single TestCase in the context of this TestResult */
+ $this->_startTest($test);
+ $this->fRunTests++;
+
+ $test->runBare();
+
+ /* this is where JUnit would catch AssertionFailedError */
+ $exceptions = $test->getExceptions();
+ if ($exceptions)
+ $this->fFailures[] = new TestFailure(&$test, &$exceptions);
+ $this->_endTest($test);
+ }
+
+ function countTests() {
+ return $this->fRunTests;
+ }
+
+ function shouldStop() {
+ return $this->fStop;
+ }
+
+ function _startTest($test) /* protected */ {
+ /* specialize this for start-of-test actions */
+ }
+
+ function stop() {
+ /* set indication that the test sequence should halt */
+ $fStop = true;
+ }
+
+ function countFailures() {
+ return count($this->fFailures);
+ }
+}
+
+
+class TextTestResult extends TestResult {
+ /* Specialize TestResult to produce text/html report */
+ function TextTestResult() {
+ $this->TestResult(); // call superclass constructor
+ }
+
+ function report() {
+ /* report result of test run */
+ $nRun = $this->countTests();
+ $nFailures = $this->countFailures();
+ printf("<p>%s test%s run<br>", $nRun, ($nRun == 1) ? '' : 's');
+ printf("%s failure%s.<br>\n", $nFailures, ($nFailures == 1) ? '' : 's');
+ if ($nFailures == 0)
+ return;
+
+ print("<ol>\n");
+ $failures = $this->getFailures();
+ while (list($i, $failure) = each($failures)) {
+ $failedTestName = $failure->getTestName();
+ printf("<li>%s\n", $failedTestName);
+
+ $exceptions = $failure->getExceptions();
+ print("<ul>");
+ while (list($na, $exception) = each($exceptions))
+ printf("<li>%s\n", $exception->getMessage());
+ print("</ul>");
+ }
+ print("</ol>\n");
+ }
+
+ function _startTest($test) {
+ printf("%s ", $test->name());
+ flush();
+ }
+
+ function _endTest($test) {
+ $outcome = $test->failed()
+ ? "<font color=\"red\">FAIL</font>"
+ : "<font color=\"green\">ok</font>";
+ printf("$outcome<br>\n");
+ flush();
+ }
+}
+
+
+class TestRunner {
+ /* Run a suite of tests and report results. */
+ function run($suite) {
+ $result = new TextTestResult;
+ $suite->run($result);
+ $result->report();
+ }
+}
+
+?>
diff --git a/site/vendors/phpmailer/test/test.png b/site/vendors/phpmailer/test/test.png
new file mode 100644
index 0000000..02de5a7
--- /dev/null
+++ b/site/vendors/phpmailer/test/test.png
Binary files differ
diff --git a/site/vendors/recaptcha/LICENSE b/site/vendors/recaptcha/LICENSE
new file mode 100644
index 0000000..b612f71
--- /dev/null
+++ b/site/vendors/recaptcha/LICENSE
@@ -0,0 +1,22 @@
+Copyright (c) 2007 reCAPTCHA -- http://recaptcha.net
+AUTHORS:
+ Mike Crawford
+ Ben Maurer
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/site/vendors/recaptcha/README b/site/vendors/recaptcha/README
new file mode 100644
index 0000000..21f1a27
--- /dev/null
+++ b/site/vendors/recaptcha/README
@@ -0,0 +1,7 @@
+reCAPTCHA README
+================
+
+The reCAPTCHA PHP Lirary helps you use the reCAPTCHA API. Documentation
+for this library can be found at
+
+ http://recaptcha.net/plugins/php
diff --git a/site/vendors/recaptcha/example-captcha.php b/site/vendors/recaptcha/example-captcha.php
new file mode 100644
index 0000000..1c4ca5f
--- /dev/null
+++ b/site/vendors/recaptcha/example-captcha.php
@@ -0,0 +1,37 @@
+<html>
+ <body>
+ <form action="" method="post">
+<?php
+
+require_once('recaptchalib.php');
+
+// Get a key from http://recaptcha.net/api/getkey
+$publickey = "";
+$privatekey = "";
+
+# the response from reCAPTCHA
+$resp = null;
+# the error code from reCAPTCHA, if any
+$error = null;
+
+# was there a reCAPTCHA response?
+if ($_POST["recaptcha_response_field"]) {
+ $resp = recaptcha_check_answer ($privatekey,
+ $_SERVER["REMOTE_ADDR"],
+ $_POST["recaptcha_challenge_field"],
+ $_POST["recaptcha_response_field"]);
+
+ if ($resp->is_valid) {
+ echo "You got it!";
+ } else {
+ # set the error code so that we can display it
+ $error = $resp->error;
+ }
+}
+echo recaptcha_get_html($publickey, $error);
+?>
+ <br/>
+ <input type="submit" value="submit" />
+ </form>
+ </body>
+</html>
diff --git a/site/vendors/recaptcha/example-mailhide.php b/site/vendors/recaptcha/example-mailhide.php
new file mode 100644
index 0000000..e389eb9
--- /dev/null
+++ b/site/vendors/recaptcha/example-mailhide.php
@@ -0,0 +1,17 @@
+<html><body>
+<?
+require_once ("recaptchalib.php");
+
+// get a key at http://mailhide.recaptcha.net/apikey
+$mailhide_pubkey = '';
+$mailhide_privkey = '';
+
+?>
+
+The Mailhide version of example@example.com is
+<? echo recaptcha_mailhide_html ($mailhide_pubkey, $mailhide_privkey, "example@example.com"); ?>. <br>
+
+The url for the email is:
+<? echo recaptcha_mailhide_url ($mailhide_pubkey, $mailhide_privkey, "example@example.com"); ?> <br>
+
+</body></html>
diff --git a/site/vendors/recaptcha/recaptchalib.php b/site/vendors/recaptcha/recaptchalib.php
new file mode 100644
index 0000000..897c509
--- /dev/null
+++ b/site/vendors/recaptcha/recaptchalib.php
@@ -0,0 +1,277 @@
+<?php
+/*
+ * This is a PHP library that handles calling reCAPTCHA.
+ * - Documentation and latest version
+ * http://recaptcha.net/plugins/php/
+ * - Get a reCAPTCHA API Key
+ * http://recaptcha.net/api/getkey
+ * - Discussion group
+ * http://groups.google.com/group/recaptcha
+ *
+ * Copyright (c) 2007 reCAPTCHA -- http://recaptcha.net
+ * AUTHORS:
+ * Mike Crawford
+ * Ben Maurer
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+/**
+ * The reCAPTCHA server URL's
+ */
+define("RECAPTCHA_API_SERVER", "http://api.recaptcha.net");
+define("RECAPTCHA_API_SECURE_SERVER", "https://api-secure.recaptcha.net");
+define("RECAPTCHA_VERIFY_SERVER", "api-verify.recaptcha.net");
+
+/**
+ * Encodes the given data into a query string format
+ * @param $data - array of string elements to be encoded
+ * @return string - encoded request
+ */
+function _recaptcha_qsencode ($data) {
+ $req = "";
+ foreach ( $data as $key => $value )
+ $req .= $key . '=' . urlencode( stripslashes($value) ) . '&';
+
+ // Cut the last '&'
+ $req=substr($req,0,strlen($req)-1);
+ return $req;
+}
+
+
+
+/**
+ * Submits an HTTP POST to a reCAPTCHA server
+ * @param string $host
+ * @param string $path
+ * @param array $data
+ * @param int port
+ * @return array response
+ */
+function _recaptcha_http_post($host, $path, $data, $port = 80) {
+
+ $req = _recaptcha_qsencode ($data);
+
+ $http_request = "POST $path HTTP/1.0\r\n";
+ $http_request .= "Host: $host\r\n";
+ $http_request .= "Content-Type: application/x-www-form-urlencoded;\r\n";
+ $http_request .= "Content-Length: " . strlen($req) . "\r\n";
+ $http_request .= "User-Agent: reCAPTCHA/PHP\r\n";
+ $http_request .= "\r\n";
+ $http_request .= $req;
+
+ $response = '';
+ if( false == ( $fs = @fsockopen($host, $port, $errno, $errstr, 10) ) ) {
+ die ('Could not open socket');
+ }
+
+ fwrite($fs, $http_request);
+
+ while ( !feof($fs) )
+ $response .= fgets($fs, 1160); // One TCP-IP packet
+ fclose($fs);
+ $response = explode("\r\n\r\n", $response, 2);
+
+ return $response;
+}
+
+
+
+/**
+ * Gets the challenge HTML (javascript and non-javascript version).
+ * This is called from the browser, and the resulting reCAPTCHA HTML widget
+ * is embedded within the HTML form it was called from.
+ * @param string $pubkey A public key for reCAPTCHA
+ * @param string $error The error given by reCAPTCHA (optional, default is null)
+ * @param boolean $use_ssl Should the request be made over ssl? (optional, default is false)
+
+ * @return string - The HTML to be embedded in the user's form.
+ */
+function recaptcha_get_html ($pubkey, $error = null, $use_ssl = false)
+{
+ if ($pubkey == null || $pubkey == '') {
+ die ("To use reCAPTCHA you must get an API key from <a href='http://recaptcha.net/api/getkey'>http://recaptcha.net/api/getkey</a>");
+ }
+
+ if ($use_ssl) {
+ $server = RECAPTCHA_API_SECURE_SERVER;
+ } else {
+ $server = RECAPTCHA_API_SERVER;
+ }
+
+ $errorpart = "";
+ if ($error) {
+ $errorpart = "&amp;error=" . $error;
+ }
+ return '<script type="text/javascript" src="'. $server . '/challenge?k=' . $pubkey . $errorpart . '"></script>
+
+ <noscript>
+ <iframe src="'. $server . '/noscript?k=' . $pubkey . $errorpart . '" height="300" width="500" frameborder="0"></iframe><br/>
+ <textarea name="recaptcha_challenge_field" rows="3" cols="40"></textarea>
+ <input type="hidden" name="recaptcha_response_field" value="manual_challenge"/>
+ </noscript>';
+}
+
+
+
+
+/**
+ * A ReCaptchaResponse is returned from recaptcha_check_answer()
+ */
+class ReCaptchaResponse {
+ var $is_valid;
+ var $error;
+}
+
+
+/**
+ * Calls an HTTP POST function to verify if the user's guess was correct
+ * @param string $privkey
+ * @param string $remoteip
+ * @param string $challenge
+ * @param string $response
+ * @param array $extra_params an array of extra variables to post to the server
+ * @return ReCaptchaResponse
+ */
+function recaptcha_check_answer ($privkey, $remoteip, $challenge, $response, $extra_params = array())
+{
+ if ($privkey == null || $privkey == '') {
+ die ("To use reCAPTCHA you must get an API key from <a href='http://recaptcha.net/api/getkey'>http://recaptcha.net/api/getkey</a>");
+ }
+
+ if ($remoteip == null || $remoteip == '') {
+ die ("For security reasons, you must pass the remote ip to reCAPTCHA");
+ }
+
+
+
+ //discard spam submissions
+ if ($challenge == null || strlen($challenge) == 0 || $response == null || strlen($response) == 0) {
+ $recaptcha_response = new ReCaptchaResponse();
+ $recaptcha_response->is_valid = false;
+ $recaptcha_response->error = 'incorrect-captcha-sol';
+ return $recaptcha_response;
+ }
+
+ $response = _recaptcha_http_post (RECAPTCHA_VERIFY_SERVER, "/verify",
+ array (
+ 'privatekey' => $privkey,
+ 'remoteip' => $remoteip,
+ 'challenge' => $challenge,
+ 'response' => $response
+ ) + $extra_params
+ );
+
+ $answers = explode ("\n", $response [1]);
+ $recaptcha_response = new ReCaptchaResponse();
+
+ if (trim ($answers [0]) == 'true') {
+ $recaptcha_response->is_valid = true;
+ }
+ else {
+ $recaptcha_response->is_valid = false;
+ $recaptcha_response->error = $answers [1];
+ }
+ return $recaptcha_response;
+
+}
+
+/**
+ * gets a URL where the user can sign up for reCAPTCHA. If your application
+ * has a configuration page where you enter a key, you should provide a link
+ * using this function.
+ * @param string $domain The domain where the page is hosted
+ * @param string $appname The name of your application
+ */
+function recaptcha_get_signup_url ($domain = null, $appname = null) {
+ return "http://recaptcha.net/api/getkey?" . _recaptcha_qsencode (array ('domain' => $domain, 'app' => $appname));
+}
+
+function _recaptcha_aes_pad($val) {
+ $block_size = 16;
+ $numpad = $block_size - (strlen ($val) % $block_size);
+ return str_pad($val, strlen ($val) + $numpad, chr($numpad));
+}
+
+/* Mailhide related code */
+
+function _recaptcha_aes_encrypt($val,$ky) {
+ if (! function_exists ("mcrypt_encrypt")) {
+ die ("To use reCAPTCHA Mailhide, you need to have the mcrypt php module installed.");
+ }
+ $mode=MCRYPT_MODE_CBC;
+ $enc=MCRYPT_RIJNDAEL_128;
+ $val=_recaptcha_aes_pad($val);
+ return mcrypt_encrypt($enc, $ky, $val, $mode, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0");
+}
+
+
+function _recaptcha_mailhide_urlbase64 ($x) {
+ return strtr(base64_encode ($x), '+/', '-_');
+}
+
+/* gets the reCAPTCHA Mailhide url for a given email, public key and private key */
+function recaptcha_mailhide_url($pubkey, $privkey, $email) {
+ if ($pubkey == '' || $pubkey == null || $privkey == "" || $privkey == null) {
+ die ("To use reCAPTCHA Mailhide, you have to sign up for a public and private key, " .
+ "you can do so at <a href='http://mailhide.recaptcha.net/apikey'>http://mailhide.recaptcha.net/apikey</a>");
+ }
+
+
+ $ky = pack('H*', $privkey);
+ $cryptmail = _recaptcha_aes_encrypt ($email, $ky);
+
+ return "http://mailhide.recaptcha.net/d?k=" . $pubkey . "&c=" . _recaptcha_mailhide_urlbase64 ($cryptmail);
+}
+
+/**
+ * gets the parts of the email to expose to the user.
+ * eg, given johndoe@example,com return ["john", "example.com"].
+ * the email is then displayed as john...@example.com
+ */
+function _recaptcha_mailhide_email_parts ($email) {
+ $arr = preg_split("/@/", $email );
+
+ if (strlen ($arr[0]) <= 4) {
+ $arr[0] = substr ($arr[0], 0, 1);
+ } else if (strlen ($arr[0]) <= 6) {
+ $arr[0] = substr ($arr[0], 0, 3);
+ } else {
+ $arr[0] = substr ($arr[0], 0, 4);
+ }
+ return $arr;
+}
+
+/**
+ * Gets html to display an email address given a public an private key.
+ * to get a key, go to:
+ *
+ * http://mailhide.recaptcha.net/apikey
+ */
+function recaptcha_mailhide_html($pubkey, $privkey, $email) {
+ $emailparts = _recaptcha_mailhide_email_parts ($email);
+ $url = recaptcha_mailhide_url ($pubkey, $privkey, $email);
+
+ return htmlentities($emailparts[0]) . "<a href='" . htmlentities ($url) .
+ "' onclick=\"window.open('" . htmlentities ($url) . "', '', 'toolbar=0,scrollbars=0,location=0,statusbar=0,menubar=0,resizable=0,width=500,height=300'); return false;\" title=\"Reveal this e-mail address\">...</a>@" . htmlentities ($emailparts [1]);
+
+}
+
+
+?>
diff --git a/site/vendors/simpletest/HELP_MY_TESTS_DONT_WORK_ANYMORE b/site/vendors/simpletest/HELP_MY_TESTS_DONT_WORK_ANYMORE
new file mode 100644
index 0000000..8ac9cf2
--- /dev/null
+++ b/site/vendors/simpletest/HELP_MY_TESTS_DONT_WORK_ANYMORE
@@ -0,0 +1,348 @@
+Simple Test interface changes
+=============================
+Because the SimpleTest tool set is still evolving it is likely that tests
+written with earlier versions will fail with the newest ones. The most
+dramatic changes are in the alpha releases. Here is a list of possible
+problems and their fixes...
+
+No method getRelativeUrls() or getAbsoluteUrls()
+------------------------------------------------
+These methods were always a bit weird anyway, and
+the new parsing of the base tag makes them more so.
+They have been replaced with getUrls() instead. If
+you want the old functionality then simply chop
+off the current domain from getUrl().
+
+Method setWildcard() removed in mocks
+-------------------------------------
+Even setWildcard() has been removed in 1.0.1beta now.
+If you want to test explicitely for a '*' string, then
+simply pass in new IdenticalExpectation('*') instead.
+
+No method _getTest() on mocks
+-----------------------------
+This has finally been removed. It was a pretty esoteric
+flex point anyway. It was there to allow the mocks to
+work with other test tools, but no one does this.
+
+No method assertError(), assertNoErrors(), swallowErrors()
+----------------------------------------------------------
+These have been deprecated in 1.0.1beta in favour of
+expectError() and expectException(). assertNoErrors() is
+redundant if you use expectError() as failures are now reported
+immediately.
+
+No method TestCase::signal()
+----------------------------
+This has been deprecated in favour of triggering an error or
+throwing an exception. Deprecated as of 1.0.1beta.
+
+No method TestCase::sendMessage()
+---------------------------------
+This has been deprecated as of 1.0.1beta.
+
+Failure to connect now emits failures
+-------------------------------------
+It used to be that you would have to use the
+getTransferError() call on the web tester to see if
+there was a socket level error in a fetch. This check
+is now always carried out by the WebTestCase unless
+the fetch is prefaced with WebTestCase::ignoreErrors().
+The ignore directive only lasts for test case fetching
+action such as get() and click().
+
+No method SimpleTestOptions::ignore()
+-------------------------------------
+This is deprecated in version 1.0.1beta and has been moved
+to SimpleTest::ignore() as that is more readable. In
+addition, parent classes are also ignored automatically.
+If you are using PHP5 you can skip this directive simply
+by marking your test case as abstract.
+
+No method assertCopy()
+----------------------
+This is deprecated in 1.0.1 in favour of assertClone().
+The assertClone() method is slightly different in that
+the objects must be identical, but without being a
+reference. It is thus not a strict inversion of
+assertReference().
+
+Constructor wildcard override has no effect in mocks
+----------------------------------------------------
+As of 1.0.1beta this is now set with setWildcard() instead
+of in the constructor.
+
+No methods setStubBaseClass()/getStubBaseClass()
+------------------------------------------------
+As mocks are now used instead of stubs, these methods
+stopped working and are now removed as of the 1.0.1beta
+release. The mock objects may be freely used instead.
+
+No method addPartialMockCode()
+------------------------------
+The ability to insert arbitrary partial mock code
+has been removed. This was a low value feature
+causing needless complications. It was removed
+in the 1.0.1beta release.
+
+No method setMockBaseClass()
+----------------------------
+The ability to change the mock base class has been
+scheduled for removal and is deprecated since the
+1.0.1beta version. This was a rarely used feature
+except as a workaround for PHP5 limitations. As
+these limitations are being resolved it's hoped
+that the bundled mocks can be used directly.
+
+No class Stub
+-------------
+Server stubs are deprecated from 1.0.1 as the mocks now
+have exactly the same interface. Just use mock objects
+instead.
+
+No class SimpleTestOptions
+--------------------------
+This was replced by the shorter SimpleTest in 1.0.1beta1
+and is since deprecated.
+
+No file simple_test.php
+-----------------------
+This was renamed test_case.php in 1.0.1beta to more accurately
+reflect it's purpose. This file should never be directly
+included in test suites though, as it's part of the
+underlying mechanics and has a tendency to be refactored.
+
+No class WantedPatternExpectation
+---------------------------------
+This was deprecated in 1.0.1alpha in favour of the simpler
+name PatternExpectation.
+
+No class NoUnwantedPatternExpectation
+-------------------------------------
+This was deprecated in 1.0.1alpha in favour of the simpler
+name NoPatternExpectation.
+
+No method assertNoUnwantedPattern()
+-----------------------------------
+This has been renamed to assertNoPattern() in 1.0.1alpha and
+the old form is deprecated.
+
+No method assertWantedPattern()
+-------------------------------
+This has been renamed to assertPattern() in 1.0.1alpha and
+the old form is deprecated.
+
+No method assertExpectation()
+-----------------------------
+This was renamed as assert() in 1.0.1alpha and the old form
+has been deprecated.
+
+No class WildcardExpectation
+----------------------------
+This was a mostly internal class for the mock objects. It was
+renamed AnythingExpectation to bring it closer to JMock and
+NMock in version 1.0.1alpha.
+
+Missing UnitTestCase::assertErrorPattern()
+------------------------------------------
+This method is deprecated for version 1.0.1 onwards.
+This method has been subsumed by assertError() that can now
+take an expectation. Simply pass a PatternExpectation
+into assertError() to simulate the old behaviour.
+
+No HTML when matching page elements
+-----------------------------------
+This behaviour has been switched to using plain text as if it
+were seen by the user of the browser. This means that HTML tags
+are suppressed, entities are converted and whitespace is
+normalised. This should make it easier to match items in forms.
+Also images are replaced with their "alt" text so that they
+can be matched as well.
+
+No method SimpleRunner::_getTestCase()
+--------------------------------------
+This was made public as getTestCase() in 1.0RC2.
+
+No method restartSession()
+--------------------------
+This was renamed to restart() in the WebTestCase, SimpleBrowser
+and the underlying SimpleUserAgent in 1.0RC2. Because it was
+undocumented anyway, no attempt was made at backward
+compatibility.
+
+My custom test case ignored by tally()
+--------------------------------------
+The _assertTrue method has had it's signature changed due to a bug
+in the PHP 5.0.1 release. You must now use getTest() from within
+that method to get the test case. Mock compatibility with other
+unit testers is now deprecated as of 1.0.1alpha as PEAR::PHPUnit2
+should soon have mock support of it's own.
+
+Broken code extending SimpleRunner
+----------------------------------
+This was replaced with SimpleScorer so that I could use the runner
+name in another class. This happened in RC1 development and there
+is no easy backward compatibility fix. The solution is simply to
+extend SimpleScorer instead.
+
+Missing method getBaseCookieValue()
+-----------------------------------
+This was renamed getCurrentCookieValue() in RC1.
+
+Missing files from the SimpleTest suite
+---------------------------------------
+Versions of SimpleTest prior to Beta6 required a SIMPLE_TEST constant
+to point at the SimpleTest folder location before any of the toolset
+was loaded. This is no longer documented as it is now unnecessary
+for later versions. If you are using an earlier version you may
+need this constant. Consult the documentation that was bundled with
+the release that you are using or upgrade to Beta6 or later.
+
+No method SimpleBrowser::getCurrentUrl()
+--------------------------------------
+This is replaced with the more versatile showRequest() for
+debugging. It only existed in this context for version Beta5.
+Later versions will have SimpleBrowser::getHistory() for tracking
+paths through pages. It is renamed as getUrl() since 1.0RC1.
+
+No method Stub::setStubBaseClass()
+----------------------------------
+This method has finally been removed in 1.0RC1. Use
+SimpleTestOptions::setStubBaseClass() instead.
+
+No class CommandLineReporter
+----------------------------
+This was renamed to TextReporter in Beta3 and the deprecated version
+was removed in 1.0RC1.
+
+No method requireReturn()
+-------------------------
+This was deprecated in Beta3 and is now removed.
+
+No method expectCookie()
+------------------------
+This method was abruptly removed in Beta4 so as to simplify the internals
+until another mechanism can replace it. As a workaround it is necessary
+to assert that the cookie has changed by setting it before the page
+fetch and then assert the desired value.
+
+No method clickSubmitByFormId()
+-------------------------------
+This method had an incorrect name as no button was involved. It was
+renamed to submitByFormId() in Beta4 and the old version deprecated.
+Now removed.
+
+No method paintStart() or paintEnd()
+------------------------------------
+You should only get this error if you have subclassed the lower level
+reporting and test runner machinery. These methods have been broken
+down into events for test methods, events for test cases and events
+for group tests. The new methods are...
+
+paintStart() --> paintMethodStart(), paintCaseStart(), paintGroupStart()
+paintEnd() --> paintMethodEnd(), paintCaseEnd(), paintGroupEnd()
+
+This change was made in Beta3, ironically to make it easier to subclass
+the inner machinery. Simply duplicating the code you had in the previous
+methods should provide a temporary fix.
+
+No class TestDisplay
+--------------------
+This has been folded into SimpleReporter in Beta3 and is now deprecated.
+It was removed in RC1.
+
+No method WebTestCase::fetch()
+------------------------------
+This was renamed get() in Alpha8. It is removed in Beta3.
+
+No method submit()
+------------------
+This has been renamed clickSubmit() in Beta1. The old method was
+removed in Beta2.
+
+No method clearHistory()
+------------------------
+This method is deprecated in Beta2 and removed in RC1.
+
+No method getCallCount()
+------------------------
+This method has been deprecated since Beta1 and has now been
+removed. There are now more ways to set expectations on counts
+and so this method should be unecessery. Removed in RC1.
+
+Cannot find file *
+------------------
+The following public name changes have occoured...
+
+simple_html_test.php --> reporter.php
+simple_mock.php --> mock_objects.php
+simple_unit.php --> unit_tester.php
+simple_web.php --> web_tester.php
+
+The old names were deprecated in Alpha8 and removed in Beta1.
+
+No method attachObserver()
+--------------------------
+Prior to the Alpha8 release the old internal observer pattern was
+gutted and replaced with a visitor. This is to trade flexibility of
+test case expansion against the ease of writing user interfaces.
+
+Code such as...
+
+$test = &new MyTestCase();
+$test->attachObserver(new TestHtmlDisplay());
+$test->run();
+
+...should be rewritten as...
+
+$test = &new MyTestCase();
+$test->run(new HtmlReporter());
+
+If you previously attached multiple observers then the workaround
+is to run the tests twice, once with each, until they can be combined.
+For one observer the old method is simulated in Alpha 8, but is
+removed in Beta1.
+
+No class TestHtmlDisplay
+------------------------
+This class has been renamed to HtmlReporter in Alpha8. It is supported,
+but deprecated in Beta1 and removed in Beta2. If you have subclassed
+the display for your own design, then you will have to extend this
+class (HtmlReporter) instead.
+
+If you have accessed the event queue by overriding the notify() method
+then I am afraid you are in big trouble :(. The reporter is now
+carried around the test suite by the runner classes and the methods
+called directly. In the unlikely event that this is a problem and
+you don't want to upgrade the test tool then simplest is to write your
+own runner class and invoke the tests with...
+
+$test->accept(new MyRunner(new MyReporter()));
+
+...rather than the run method. This should be easier to extend
+anyway and gives much more control. Even this method is overhauled
+in Beta3 where the runner class can be set within the test case. Really
+the best thing to do is to upgrade to this version as whatever you were
+trying to achieve before should now be very much easier.
+
+Missing set options method
+--------------------------
+All test suite options are now in one class called SimpleTestOptions.
+This means that options are set differently...
+
+GroupTest::ignore() --> SimpleTestOptions::ignore()
+Mock::setMockBaseClass() --> SimpleTestOptions::setMockBaseClass()
+
+These changed in Alpha8 and the old versions are now removed in RC1.
+
+No method setExpected*()
+------------------------
+The mock expectations changed their names in Alpha4 and the old names
+ceased to be supported in Alpha8. The changes are...
+
+setExpectedArguments() --> expectArguments()
+setExpectedArgumentsSequence() --> expectArgumentsAt()
+setExpectedCallCount() --> expectCallCount()
+setMaximumCallCount() --> expectMaximumCallCount()
+
+The parameters remained the same.
diff --git a/site/vendors/simpletest/LICENSE b/site/vendors/simpletest/LICENSE
new file mode 100644
index 0000000..09f465a
--- /dev/null
+++ b/site/vendors/simpletest/LICENSE
@@ -0,0 +1,502 @@
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL. It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+ This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it. You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+ When we speak of free software, we are referring to freedom of use,
+not price. Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+ To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights. These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+ For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you. You must make sure that they, too, receive or can get the source
+code. If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it. And you must show them these terms so they know their rights.
+
+ We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+ To protect each distributor, we want to make it very clear that
+there is no warranty for the free library. Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+
+ Finally, software patents pose a constant threat to the existence of
+any free program. We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder. Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+ Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License. This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License. We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+ When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library. The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom. The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+ We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License. It also provides other free software developers Less
+of an advantage over competing non-free programs. These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries. However, the Lesser license provides advantages in certain
+special circumstances.
+
+ For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard. To achieve this, non-free programs must be
+allowed to use the library. A more frequent case is that a free
+library does the same job as widely used non-free libraries. In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+ In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software. For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+ Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+ The precise terms and conditions for copying, distribution and
+modification follow. Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library". The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+
+ GNU LESSER GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+ A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+ The "Library", below, refers to any such software library or work
+which has been distributed under these terms. A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language. (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+ "Source code" for a work means the preferred form of the work for
+making modifications to it. For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+ Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it). Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+ 1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+ You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+ 2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) The modified work must itself be a software library.
+
+ b) You must cause the files modified to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ c) You must cause the whole of the work to be licensed at no
+ charge to all third parties under the terms of this License.
+
+ d) If a facility in the modified Library refers to a function or a
+ table of data to be supplied by an application program that uses
+ the facility, other than as an argument passed when the facility
+ is invoked, then you must make a good faith effort to ensure that,
+ in the event an application does not supply such function or
+ table, the facility still operates, and performs whatever part of
+ its purpose remains meaningful.
+
+ (For example, a function in a library to compute square roots has
+ a purpose that is entirely well-defined independent of the
+ application. Therefore, Subsection 2d requires that any
+ application-supplied function or table used by this function must
+ be optional: if the application does not supply it, the square
+ root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library. To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License. (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.) Do not make any other change in
+these notices.
+
+ Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+ This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+ 4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+ If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library". Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+ However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library". The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+ When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library. The
+threshold for this to be true is not precisely defined by law.
+
+ If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work. (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+ Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+ 6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+ You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License. You must supply a copy of this License. If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License. Also, you must do one
+of these things:
+
+ a) Accompany the work with the complete corresponding
+ machine-readable source code for the Library including whatever
+ changes were used in the work (which must be distributed under
+ Sections 1 and 2 above); and, if the work is an executable linked
+ with the Library, with the complete machine-readable "work that
+ uses the Library", as object code and/or source code, so that the
+ user can modify the Library and then relink to produce a modified
+ executable containing the modified Library. (It is understood
+ that the user who changes the contents of definitions files in the
+ Library will not necessarily be able to recompile the application
+ to use the modified definitions.)
+
+ b) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (1) uses at run time a
+ copy of the library already present on the user's computer system,
+ rather than copying library functions into the executable, and (2)
+ will operate properly with a modified version of the library, if
+ the user installs one, as long as the modified version is
+ interface-compatible with the version that the work was made with.
+
+ c) Accompany the work with a written offer, valid for at
+ least three years, to give the same user the materials
+ specified in Subsection 6a, above, for a charge no more
+ than the cost of performing this distribution.
+
+ d) If distribution of the work is made by offering access to copy
+ from a designated place, offer equivalent access to copy the above
+ specified materials from the same place.
+
+ e) Verify that the user has already received a copy of these
+ materials or that you have already sent this user a copy.
+
+ For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it. However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+ It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system. Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+ 7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+ a) Accompany the combined library with a copy of the same work
+ based on the Library, uncombined with any other library
+ facilities. This must be distributed under the terms of the
+ Sections above.
+
+ b) Give prominent notice with the combined library of the fact
+ that part of it is a work based on the Library, and explaining
+ where to find the accompanying uncombined form of the same work.
+
+ 8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License. Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License. However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+ 9. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Library or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+ 10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+
+ 11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all. For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded. In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+ 13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation. If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+ 14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission. For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this. Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+ NO WARRANTY
+
+ 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Libraries
+
+ If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change. You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+ To apply these terms, attach the following notices to the library. It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the library's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the
+ library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+ <signature of Ty Coon>, 1 April 1990
+ Ty Coon, President of Vice
+
+That's all there is to it!
diff --git a/site/vendors/simpletest/README b/site/vendors/simpletest/README
new file mode 100644
index 0000000..c52e3f7
--- /dev/null
+++ b/site/vendors/simpletest/README
@@ -0,0 +1,108 @@
+SimpleTest
+==========
+You probably got this package from...
+http://simpletest.sourceforge.net/projects/simpletest/
+
+If there is no licence agreement with this package please download
+a version from the location above. You must read and accept that
+licence to use this software. The file is titled simply LICENSE.
+
+What is it? It's a framework for unit testing, web site testing and
+mock objects for PHP 4.2.0+ (and PHP 5.0 to 5.3 without E_STRICT).
+
+If you have used JUnit, you will find this PHP unit testing version very
+similar. Also included is a mock objects and server stubs generator.
+The stubs can have return values set for different arguments, can have
+sequences set also by arguments and can return items by reference.
+The mocks inherit all of this functionality and can also have
+expectations set, again in sequences and for different arguments.
+
+A web tester similar in concept to JWebUnit is also included. There is no
+JavaScript or tables support, but forms, authentication, cookies and
+frames are handled.
+
+You can see a release schedule at http://www.lastcraft.com/overview.php
+which is also copied to the documentation folder with this release.
+A full PHPDocumenter API documentation exists at
+http://simpletest.sourceforge.net/.
+
+The user interface is minimal
+in the extreme, but a lot of information flows from the test suite.
+After version 1.0 we will release a better web UI, but we are leaving XUL
+and GTk versions to volunteers as everybody has their own opinion
+on a good GUI, and we don't want to discourage development by shipping
+one with the toolkit. YOucan download an Eclipse plug-in separately.
+
+You are looking at a second full release. The unit tests for SimpleTest
+itself can be run here...
+
+simpletest/test/unit_tests.php
+
+And tests involving live network connections as well are here...
+
+simpletest/test/all_tests.php
+
+The full tests will typically overrun the 8Mb limit often allowed
+to a PHP process. A workaround is to run the tests on the command
+with a custom php.ini file if you do not have access to your server
+version.
+
+You will have to edit the all_tests.php file if you are accesssing
+the internet through a proxy server. See the comments in all_tests.php
+for instructions.
+
+The full tests read some test data from the LastCraft site. If the site
+is down or has been modified for a later version then you will get
+spurious errors. A unit_tests.php failure on the other hand would be
+very serious. As far as we know we haven't yet managed to check in any
+unit test failures, so please correct us if you find one.
+
+Even if all of the tests run please verify that your existing test suites
+also function as expected. If they don't see the file...
+
+HELP_MY_TESTS_DONT_WORK_ANYMORE
+
+This contains information on interface changes. It also points out
+deprecated interfaces, so you should read this even if all of
+your current tests appear to run.
+
+There is a documentation folder which contains the core reference information
+in English and French, although this information is fairly basic.
+You can find a tutorial on...
+
+http://www.lastcraft.com/first_test_tutorial.php
+
+...to get you started and this material will eventually become included
+with the project documentation. A French translation exists at...
+
+http://www.onpk.net/index.php/2005/01/12/254-tutoriel-simpletest-decouvrir-les-tests-unitaires.
+
+If you download and use, and possibly even extend this tool, please let us
+know. Any feedback, even bad, is always welcome and we will work to get
+your suggestions into the next release. Ideally please send your
+comments to...
+
+simpletest-support@lists.sourceforge.net
+
+...so that others can read them too. We usually try to respond within 48
+hours.
+
+There is no change log except at Sourceforge. You can visit the
+release notes to see the completed TODO list after each cycle and also the
+status of any bugs, but if the bug is recent then it will be fixed in SVN only.
+The SVN check-ins always have all the tests passing and so SVN snapshots should
+be pretty usable, although the code may not look so good internally.
+
+Oh, yes. It is called "Simple" because it should be simple to
+use. We intend to add a complete set of tools for a test first
+and "test as you code" type of development. "Simple" does not
+mean "Lite" in this context.
+
+Thanks to everyone who has sent comments and offered suggestions. They
+really are invaluable, but sadly you are too many to mention in full.
+Thanks to all on the advanced PHP forum on SitePoint, especially Harry
+Feucks. Early adopters are always an inspiration.
+
+Marcus Baker, Jason Sweat, Travis Swicegood, Perrick Penet and Edward Z. Yang.
+--
+marcus@lastcraft.com
diff --git a/site/vendors/simpletest/VERSION b/site/vendors/simpletest/VERSION
new file mode 100644
index 0000000..7f20734
--- /dev/null
+++ b/site/vendors/simpletest/VERSION
@@ -0,0 +1 @@
+1.0.1 \ No newline at end of file
diff --git a/site/vendors/simpletest/authentication.php b/site/vendors/simpletest/authentication.php
new file mode 100644
index 0000000..c56d11b
--- /dev/null
+++ b/site/vendors/simpletest/authentication.php
@@ -0,0 +1,238 @@
+<?php
+/**
+ * Base include file for SimpleTest
+ * @package SimpleTest
+ * @subpackage WebTester
+ * @version $Id: authentication.php 1720 2008-04-07 02:32:43Z lastcraft $
+ */
+/**
+ * include http class
+ */
+require_once(dirname(__FILE__) . '/http.php');
+
+/**
+ * Represents a single security realm's identity.
+ * @package SimpleTest
+ * @subpackage WebTester
+ */
+class SimpleRealm {
+ var $_type;
+ var $_root;
+ var $_username;
+ var $_password;
+
+ /**
+ * Starts with the initial entry directory.
+ * @param string $type Authentication type for this
+ * realm. Only Basic authentication
+ * is currently supported.
+ * @param SimpleUrl $url Somewhere in realm.
+ * @access public
+ */
+ function SimpleRealm($type, $url) {
+ $this->_type = $type;
+ $this->_root = $url->getBasePath();
+ $this->_username = false;
+ $this->_password = false;
+ }
+
+ /**
+ * Adds another location to the realm.
+ * @param SimpleUrl $url Somewhere in realm.
+ * @access public
+ */
+ function stretch($url) {
+ $this->_root = $this->_getCommonPath($this->_root, $url->getPath());
+ }
+
+ /**
+ * Finds the common starting path.
+ * @param string $first Path to compare.
+ * @param string $second Path to compare.
+ * @return string Common directories.
+ * @access private
+ */
+ function _getCommonPath($first, $second) {
+ $first = explode('/', $first);
+ $second = explode('/', $second);
+ for ($i = 0; $i < min(count($first), count($second)); $i++) {
+ if ($first[$i] != $second[$i]) {
+ return implode('/', array_slice($first, 0, $i)) . '/';
+ }
+ }
+ return implode('/', $first) . '/';
+ }
+
+ /**
+ * Sets the identity to try within this realm.
+ * @param string $username Username in authentication dialog.
+ * @param string $username Password in authentication dialog.
+ * @access public
+ */
+ function setIdentity($username, $password) {
+ $this->_username = $username;
+ $this->_password = $password;
+ }
+
+ /**
+ * Accessor for current identity.
+ * @return string Last succesful username.
+ * @access public
+ */
+ function getUsername() {
+ return $this->_username;
+ }
+
+ /**
+ * Accessor for current identity.
+ * @return string Last succesful password.
+ * @access public
+ */
+ function getPassword() {
+ return $this->_password;
+ }
+
+ /**
+ * Test to see if the URL is within the directory
+ * tree of the realm.
+ * @param SimpleUrl $url URL to test.
+ * @return boolean True if subpath.
+ * @access public
+ */
+ function isWithin($url) {
+ if ($this->_isIn($this->_root, $url->getBasePath())) {
+ return true;
+ }
+ if ($this->_isIn($this->_root, $url->getBasePath() . $url->getPage() . '/')) {
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Tests to see if one string is a substring of
+ * another.
+ * @param string $part Small bit.
+ * @param string $whole Big bit.
+ * @return boolean True if the small bit is
+ * in the big bit.
+ * @access private
+ */
+ function _isIn($part, $whole) {
+ return strpos($whole, $part) === 0;
+ }
+}
+
+/**
+ * Manages security realms.
+ * @package SimpleTest
+ * @subpackage WebTester
+ */
+class SimpleAuthenticator {
+ var $_realms;
+
+ /**
+ * Clears the realms.
+ * @access public
+ */
+ function SimpleAuthenticator() {
+ $this->restartSession();
+ }
+
+ /**
+ * Starts with no realms set up.
+ * @access public
+ */
+ function restartSession() {
+ $this->_realms = array();
+ }
+
+ /**
+ * Adds a new realm centered the current URL.
+ * Browsers vary wildly on their behaviour in this
+ * regard. Mozilla ignores the realm and presents
+ * only when challenged, wasting bandwidth. IE
+ * just carries on presenting until a new challenge
+ * occours. SimpleTest tries to follow the spirit of
+ * the original standards committee and treats the
+ * base URL as the root of a file tree shaped realm.
+ * @param SimpleUrl $url Base of realm.
+ * @param string $type Authentication type for this
+ * realm. Only Basic authentication
+ * is currently supported.
+ * @param string $realm Name of realm.
+ * @access public
+ */
+ function addRealm($url, $type, $realm) {
+ $this->_realms[$url->getHost()][$realm] = new SimpleRealm($type, $url);
+ }
+
+ /**
+ * Sets the current identity to be presented
+ * against that realm.
+ * @param string $host Server hosting realm.
+ * @param string $realm Name of realm.
+ * @param string $username Username for realm.
+ * @param string $password Password for realm.
+ * @access public
+ */
+ function setIdentityForRealm($host, $realm, $username, $password) {
+ if (isset($this->_realms[$host][$realm])) {
+ $this->_realms[$host][$realm]->setIdentity($username, $password);
+ }
+ }
+
+ /**
+ * Finds the name of the realm by comparing URLs.
+ * @param SimpleUrl $url URL to test.
+ * @return SimpleRealm Name of realm.
+ * @access private
+ */
+ function _findRealmFromUrl($url) {
+ if (! isset($this->_realms[$url->getHost()])) {
+ return false;
+ }
+ foreach ($this->_realms[$url->getHost()] as $name => $realm) {
+ if ($realm->isWithin($url)) {
+ return $realm;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Presents the appropriate headers for this location.
+ * @param SimpleHttpRequest $request Request to modify.
+ * @param SimpleUrl $url Base of realm.
+ * @access public
+ */
+ function addHeaders(&$request, $url) {
+ if ($url->getUsername() && $url->getPassword()) {
+ $username = $url->getUsername();
+ $password = $url->getPassword();
+ } elseif ($realm = $this->_findRealmFromUrl($url)) {
+ $username = $realm->getUsername();
+ $password = $realm->getPassword();
+ } else {
+ return;
+ }
+ $this->addBasicHeaders($request, $username, $password);
+ }
+
+ /**
+ * Presents the appropriate headers for this
+ * location for basic authentication.
+ * @param SimpleHttpRequest $request Request to modify.
+ * @param string $username Username for realm.
+ * @param string $password Password for realm.
+ * @access public
+ * @static
+ */
+ function addBasicHeaders(&$request, $username, $password) {
+ if ($username && $password) {
+ $request->addHeaderLine(
+ 'Authorization: Basic ' . base64_encode("$username:$password"));
+ }
+ }
+}
+?> \ No newline at end of file
diff --git a/site/vendors/simpletest/autorun.php b/site/vendors/simpletest/autorun.php
new file mode 100644
index 0000000..7d97d2d
--- /dev/null
+++ b/site/vendors/simpletest/autorun.php
@@ -0,0 +1,87 @@
+<?php
+/**
+ * Autorunner which runs all tests cases found in a file
+ * that includes this module.
+ * @package SimpleTest
+ * @version $Id: autorun.php 1721 2008-04-07 19:27:10Z lastcraft $
+ */
+require_once dirname(__FILE__) . '/unit_tester.php';
+require_once dirname(__FILE__) . '/mock_objects.php';
+require_once dirname(__FILE__) . '/collector.php';
+require_once dirname(__FILE__) . '/default_reporter.php';
+
+$GLOBALS['SIMPLETEST_AUTORUNNER_INITIAL_CLASSES'] = get_declared_classes();
+register_shutdown_function('simpletest_autorun');
+
+/**
+ * Exit handler to run all recent test cases if no test has
+ * so far been run. Uses the DefaultReporter which can have
+ * it's output controlled with SimpleTest::prefer().
+ */
+function simpletest_autorun() {
+ if (tests_have_run()) {
+ return;
+ }
+ $candidates = array_intersect(
+ capture_new_classes(),
+ classes_defined_in_initial_file());
+ $loader = new SimpleFileLoader();
+ $suite = $loader->createSuiteFromClasses(
+ basename(initial_file()),
+ $loader->selectRunnableTests($candidates));
+ $result = $suite->run(new DefaultReporter());
+ if (SimpleReporter::inCli()) {
+ exit($result ? 0 : 1);
+ }
+}
+
+/**
+ * Checks the current test context to see if a test has
+ * ever been run.
+ * @return boolean True if tests have run.
+ */
+function tests_have_run() {
+ if ($context = SimpleTest::getContext()) {
+ return (boolean)$context->getTest();
+ }
+ return false;
+}
+
+/**
+ * The first autorun file.
+ * @return string Filename of first autorun script.
+ */
+function initial_file() {
+ static $file = false;
+ if (! $file) {
+ $file = reset(get_included_files());
+ }
+ return $file;
+}
+
+/**
+ * Just the classes from the first autorun script. May
+ * get a few false positives, as it just does a regex based
+ * on following the word "class".
+ * @return array List of all possible classes in first
+ * autorun script.
+ */
+function classes_defined_in_initial_file() {
+ if (preg_match_all('/\bclass\s+(\w+)/i', file_get_contents(initial_file()), $matches)) {
+ return array_map('strtolower', $matches[1]);
+ }
+ return array();
+}
+
+/**
+ * Every class since the first autorun include. This
+ * is safe enough if require_once() is alwyas used.
+ * @return array Class names.
+ */
+function capture_new_classes() {
+ global $SIMPLETEST_AUTORUNNER_INITIAL_CLASSES;
+ return array_map('strtolower', array_diff(get_declared_classes(),
+ $SIMPLETEST_AUTORUNNER_INITIAL_CLASSES ?
+ $SIMPLETEST_AUTORUNNER_INITIAL_CLASSES : array()));
+}
+?> \ No newline at end of file
diff --git a/site/vendors/simpletest/browser.php b/site/vendors/simpletest/browser.php
new file mode 100644
index 0000000..e2a1fe1
--- /dev/null
+++ b/site/vendors/simpletest/browser.php
@@ -0,0 +1,1098 @@
+<?php
+/**
+ * Base include file for SimpleTest
+ * @package SimpleTest
+ * @subpackage WebTester
+ * @version $Id: browser.php 1723 2008-04-08 00:34:10Z lastcraft $
+ */
+
+/**#@+
+ * include other SimpleTest class files
+ */
+require_once(dirname(__FILE__) . '/simpletest.php');
+require_once(dirname(__FILE__) . '/http.php');
+require_once(dirname(__FILE__) . '/encoding.php');
+require_once(dirname(__FILE__) . '/page.php');
+require_once(dirname(__FILE__) . '/selector.php');
+require_once(dirname(__FILE__) . '/frames.php');
+require_once(dirname(__FILE__) . '/user_agent.php');
+/**#@-*/
+
+if (!defined('DEFAULT_MAX_NESTED_FRAMES')) {
+ define('DEFAULT_MAX_NESTED_FRAMES', 3);
+}
+
+/**
+ * Browser history list.
+ * @package SimpleTest
+ * @subpackage WebTester
+ */
+class SimpleBrowserHistory {
+ var $_sequence;
+ var $_position;
+
+ /**
+ * Starts empty.
+ * @access public
+ */
+ function SimpleBrowserHistory() {
+ $this->_sequence = array();
+ $this->_position = -1;
+ }
+
+ /**
+ * Test for no entries yet.
+ * @return boolean True if empty.
+ * @access private
+ */
+ function _isEmpty() {
+ return ($this->_position == -1);
+ }
+
+ /**
+ * Test for being at the beginning.
+ * @return boolean True if first.
+ * @access private
+ */
+ function _atBeginning() {
+ return ($this->_position == 0) && ! $this->_isEmpty();
+ }
+
+ /**
+ * Test for being at the last entry.
+ * @return boolean True if last.
+ * @access private
+ */
+ function _atEnd() {
+ return ($this->_position + 1 >= count($this->_sequence)) && ! $this->_isEmpty();
+ }
+
+ /**
+ * Adds a successfully fetched page to the history.
+ * @param SimpleUrl $url URL of fetch.
+ * @param SimpleEncoding $parameters Any post data with the fetch.
+ * @access public
+ */
+ function recordEntry($url, $parameters) {
+ $this->_dropFuture();
+ array_push(
+ $this->_sequence,
+ array('url' => $url, 'parameters' => $parameters));
+ $this->_position++;
+ }
+
+ /**
+ * Last fully qualified URL for current history
+ * position.
+ * @return SimpleUrl URL for this position.
+ * @access public
+ */
+ function getUrl() {
+ if ($this->_isEmpty()) {
+ return false;
+ }
+ return $this->_sequence[$this->_position]['url'];
+ }
+
+ /**
+ * Parameters of last fetch from current history
+ * position.
+ * @return SimpleFormEncoding Post parameters.
+ * @access public
+ */
+ function getParameters() {
+ if ($this->_isEmpty()) {
+ return false;
+ }
+ return $this->_sequence[$this->_position]['parameters'];
+ }
+
+ /**
+ * Step back one place in the history. Stops at
+ * the first page.
+ * @return boolean True if any previous entries.
+ * @access public
+ */
+ function back() {
+ if ($this->_isEmpty() || $this->_atBeginning()) {
+ return false;
+ }
+ $this->_position--;
+ return true;
+ }
+
+ /**
+ * Step forward one place. If already at the
+ * latest entry then nothing will happen.
+ * @return boolean True if any future entries.
+ * @access public
+ */
+ function forward() {
+ if ($this->_isEmpty() || $this->_atEnd()) {
+ return false;
+ }
+ $this->_position++;
+ return true;
+ }
+
+ /**
+ * Ditches all future entries beyond the current
+ * point.
+ * @access private
+ */
+ function _dropFuture() {
+ if ($this->_isEmpty()) {
+ return;
+ }
+ while (! $this->_atEnd()) {
+ array_pop($this->_sequence);
+ }
+ }
+}
+
+/**
+ * Simulated web browser. This is an aggregate of
+ * the user agent, the HTML parsing, request history
+ * and the last header set.
+ * @package SimpleTest
+ * @subpackage WebTester
+ */
+class SimpleBrowser {
+ var $_user_agent;
+ var $_page;
+ var $_history;
+ var $_ignore_frames;
+ var $_maximum_nested_frames;
+
+ /**
+ * Starts with a fresh browser with no
+ * cookie or any other state information. The
+ * exception is that a default proxy will be
+ * set up if specified in the options.
+ * @access public
+ */
+ function SimpleBrowser() {
+ $this->_user_agent = &$this->_createUserAgent();
+ $this->_user_agent->useProxy(
+ SimpleTest::getDefaultProxy(),
+ SimpleTest::getDefaultProxyUsername(),
+ SimpleTest::getDefaultProxyPassword());
+ $this->_page = &new SimplePage();
+ $this->_history = &$this->_createHistory();
+ $this->_ignore_frames = false;
+ $this->_maximum_nested_frames = DEFAULT_MAX_NESTED_FRAMES;
+ }
+
+ /**
+ * Creates the underlying user agent.
+ * @return SimpleFetcher Content fetcher.
+ * @access protected
+ */
+ function &_createUserAgent() {
+ $user_agent = &new SimpleUserAgent();
+ return $user_agent;
+ }
+
+ /**
+ * Creates a new empty history list.
+ * @return SimpleBrowserHistory New list.
+ * @access protected
+ */
+ function &_createHistory() {
+ $history = &new SimpleBrowserHistory();
+ return $history;
+ }
+
+ /**
+ * Disables frames support. Frames will not be fetched
+ * and the frameset page will be used instead.
+ * @access public
+ */
+ function ignoreFrames() {
+ $this->_ignore_frames = true;
+ }
+
+ /**
+ * Enables frames support. Frames will be fetched from
+ * now on.
+ * @access public
+ */
+ function useFrames() {
+ $this->_ignore_frames = false;
+ }
+
+ /**
+ * Switches off cookie sending and recieving.
+ * @access public
+ */
+ function ignoreCookies() {
+ $this->_user_agent->ignoreCookies();
+ }
+
+ /**
+ * Switches back on the cookie sending and recieving.
+ * @access public
+ */
+ function useCookies() {
+ $this->_user_agent->useCookies();
+ }
+
+ /**
+ * Parses the raw content into a page. Will load further
+ * frame pages unless frames are disabled.
+ * @param SimpleHttpResponse $response Response from fetch.
+ * @param integer $depth Nested frameset depth.
+ * @return SimplePage Parsed HTML.
+ * @access private
+ */
+ function &_parse($response, $depth = 0) {
+ $page = &$this->_buildPage($response);
+ if ($this->_ignore_frames || ! $page->hasFrames() || ($depth > $this->_maximum_nested_frames)) {
+ return $page;
+ }
+ $frameset = &new SimpleFrameset($page);
+ foreach ($page->getFrameset() as $key => $url) {
+ $frame = &$this->_fetch($url, new SimpleGetEncoding(), $depth + 1);
+ $frameset->addFrame($frame, $key);
+ }
+ return $frameset;
+ }
+
+ /**
+ * Assembles the parsing machinery and actually parses
+ * a single page. Frees all of the builder memory and so
+ * unjams the PHP memory management.
+ * @param SimpleHttpResponse $response Response from fetch.
+ * @return SimplePage Parsed top level page.
+ * @access protected
+ */
+ function &_buildPage($response) {
+ $builder = &new SimplePageBuilder();
+ $page = &$builder->parse($response);
+ $builder->free();
+ unset($builder);
+ return $page;
+ }
+
+ /**
+ * Fetches a page. Jointly recursive with the _parse()
+ * method as it descends a frameset.
+ * @param string/SimpleUrl $url Target to fetch.
+ * @param SimpleEncoding $encoding GET/POST parameters.
+ * @param integer $depth Nested frameset depth protection.
+ * @return SimplePage Parsed page.
+ * @access private
+ */
+ function &_fetch($url, $encoding, $depth = 0) {
+ $response = &$this->_user_agent->fetchResponse($url, $encoding);
+ if ($response->isError()) {
+ $page = &new SimplePage($response);
+ } else {
+ $page = &$this->_parse($response, $depth);
+ }
+ return $page;
+ }
+
+ /**
+ * Fetches a page or a single frame if that is the current
+ * focus.
+ * @param SimpleUrl $url Target to fetch.
+ * @param SimpleEncoding $parameters GET/POST parameters.
+ * @return string Raw content of page.
+ * @access private
+ */
+ function _load($url, $parameters) {
+ $frame = $url->getTarget();
+ if (! $frame || ! $this->_page->hasFrames() || (strtolower($frame) == '_top')) {
+ return $this->_loadPage($url, $parameters);
+ }
+ return $this->_loadFrame(array($frame), $url, $parameters);
+ }
+
+ /**
+ * Fetches a page and makes it the current page/frame.
+ * @param string/SimpleUrl $url Target to fetch as string.
+ * @param SimplePostEncoding $parameters POST parameters.
+ * @return string Raw content of page.
+ * @access private
+ */
+ function _loadPage($url, $parameters) {
+ $this->_page = &$this->_fetch($url, $parameters);
+ $this->_history->recordEntry(
+ $this->_page->getUrl(),
+ $this->_page->getRequestData());
+ return $this->_page->getRaw();
+ }
+
+ /**
+ * Fetches a frame into the existing frameset replacing the
+ * original.
+ * @param array $frames List of names to drill down.
+ * @param string/SimpleUrl $url Target to fetch as string.
+ * @param SimpleFormEncoding $parameters POST parameters.
+ * @return string Raw content of page.
+ * @access private
+ */
+ function _loadFrame($frames, $url, $parameters) {
+ $page = &$this->_fetch($url, $parameters);
+ $this->_page->setFrame($frames, $page);
+ return $page->getRaw();
+ }
+
+ /**
+ * Removes expired and temporary cookies as if
+ * the browser was closed and re-opened.
+ * @param string/integer $date Time when session restarted.
+ * If omitted then all persistent
+ * cookies are kept.
+ * @access public
+ */
+ function restart($date = false) {
+ $this->_user_agent->restart($date);
+ }
+
+ /**
+ * Adds a header to every fetch.
+ * @param string $header Header line to add to every
+ * request until cleared.
+ * @access public
+ */
+ function addHeader($header) {
+ $this->_user_agent->addHeader($header);
+ }
+
+ /**
+ * Ages the cookies by the specified time.
+ * @param integer $interval Amount in seconds.
+ * @access public
+ */
+ function ageCookies($interval) {
+ $this->_user_agent->ageCookies($interval);
+ }
+
+ /**
+ * Sets an additional cookie. If a cookie has
+ * the same name and path it is replaced.
+ * @param string $name Cookie key.
+ * @param string $value Value of cookie.
+ * @param string $host Host upon which the cookie is valid.
+ * @param string $path Cookie path if not host wide.
+ * @param string $expiry Expiry date.
+ * @access public
+ */
+ function setCookie($name, $value, $host = false, $path = '/', $expiry = false) {
+ $this->_user_agent->setCookie($name, $value, $host, $path, $expiry);
+ }
+
+ /**
+ * Reads the most specific cookie value from the
+ * browser cookies.
+ * @param string $host Host to search.
+ * @param string $path Applicable path.
+ * @param string $name Name of cookie to read.
+ * @return string False if not present, else the
+ * value as a string.
+ * @access public
+ */
+ function getCookieValue($host, $path, $name) {
+ return $this->_user_agent->getCookieValue($host, $path, $name);
+ }
+
+ /**
+ * Reads the current cookies for the current URL.
+ * @param string $name Key of cookie to find.
+ * @return string Null if there is no current URL, false
+ * if the cookie is not set.
+ * @access public
+ */
+ function getCurrentCookieValue($name) {
+ return $this->_user_agent->getBaseCookieValue($name, $this->_page->getUrl());
+ }
+
+ /**
+ * Sets the maximum number of redirects before
+ * a page will be loaded anyway.
+ * @param integer $max Most hops allowed.
+ * @access public
+ */
+ function setMaximumRedirects($max) {
+ $this->_user_agent->setMaximumRedirects($max);
+ }
+
+ /**
+ * Sets the maximum number of nesting of framed pages
+ * within a framed page to prevent loops.
+ * @param integer $max Highest depth allowed.
+ * @access public
+ */
+ function setMaximumNestedFrames($max) {
+ $this->_maximum_nested_frames = $max;
+ }
+
+ /**
+ * Sets the socket timeout for opening a connection.
+ * @param integer $timeout Maximum time in seconds.
+ * @access public
+ */
+ function setConnectionTimeout($timeout) {
+ $this->_user_agent->setConnectionTimeout($timeout);
+ }
+
+ /**
+ * Sets proxy to use on all requests for when
+ * testing from behind a firewall. Set URL
+ * to false to disable.
+ * @param string $proxy Proxy URL.
+ * @param string $username Proxy username for authentication.
+ * @param string $password Proxy password for authentication.
+ * @access public
+ */
+ function useProxy($proxy, $username = false, $password = false) {
+ $this->_user_agent->useProxy($proxy, $username, $password);
+ }
+
+ /**
+ * Fetches the page content with a HEAD request.
+ * Will affect cookies, but will not change the base URL.
+ * @param string/SimpleUrl $url Target to fetch as string.
+ * @param hash/SimpleHeadEncoding $parameters Additional parameters for
+ * HEAD request.
+ * @return boolean True if successful.
+ * @access public
+ */
+ function head($url, $parameters = false) {
+ if (! is_object($url)) {
+ $url = new SimpleUrl($url);
+ }
+ if ($this->getUrl()) {
+ $url = $url->makeAbsolute($this->getUrl());
+ }
+ $response = &$this->_user_agent->fetchResponse($url, new SimpleHeadEncoding($parameters));
+ return ! $response->isError();
+ }
+
+ /**
+ * Fetches the page content with a simple GET request.
+ * @param string/SimpleUrl $url Target to fetch.
+ * @param hash/SimpleFormEncoding $parameters Additional parameters for
+ * GET request.
+ * @return string Content of page or false.
+ * @access public
+ */
+ function get($url, $parameters = false) {
+ if (! is_object($url)) {
+ $url = new SimpleUrl($url);
+ }
+ if ($this->getUrl()) {
+ $url = $url->makeAbsolute($this->getUrl());
+ }
+ return $this->_load($url, new SimpleGetEncoding($parameters));
+ }
+
+ /**
+ * Fetches the page content with a POST request.
+ * @param string/SimpleUrl $url Target to fetch as string.
+ * @param hash/SimpleFormEncoding $parameters POST parameters.
+ * @return string Content of page.
+ * @access public
+ */
+ function post($url, $parameters = false) {
+ if (! is_object($url)) {
+ $url = new SimpleUrl($url);
+ }
+ if ($this->getUrl()) {
+ $url = $url->makeAbsolute($this->getUrl());
+ }
+ return $this->_load($url, new SimplePostEncoding($parameters));
+ }
+
+ /**
+ * Equivalent to hitting the retry button on the
+ * browser. Will attempt to repeat the page fetch. If
+ * there is no history to repeat it will give false.
+ * @return string/boolean Content if fetch succeeded
+ * else false.
+ * @access public
+ */
+ function retry() {
+ $frames = $this->_page->getFrameFocus();
+ if (count($frames) > 0) {
+ $this->_loadFrame(
+ $frames,
+ $this->_page->getUrl(),
+ $this->_page->getRequestData());
+ return $this->_page->getRaw();
+ }
+ if ($url = $this->_history->getUrl()) {
+ $this->_page = &$this->_fetch($url, $this->_history->getParameters());
+ return $this->_page->getRaw();
+ }
+ return false;
+ }
+
+ /**
+ * Equivalent to hitting the back button on the
+ * browser. The browser history is unchanged on
+ * failure. The page content is refetched as there
+ * is no concept of content caching in SimpleTest.
+ * @return boolean True if history entry and
+ * fetch succeeded
+ * @access public
+ */
+ function back() {
+ if (! $this->_history->back()) {
+ return false;
+ }
+ $content = $this->retry();
+ if (! $content) {
+ $this->_history->forward();
+ }
+ return $content;
+ }
+
+ /**
+ * Equivalent to hitting the forward button on the
+ * browser. The browser history is unchanged on
+ * failure. The page content is refetched as there
+ * is no concept of content caching in SimpleTest.
+ * @return boolean True if history entry and
+ * fetch succeeded
+ * @access public
+ */
+ function forward() {
+ if (! $this->_history->forward()) {
+ return false;
+ }
+ $content = $this->retry();
+ if (! $content) {
+ $this->_history->back();
+ }
+ return $content;
+ }
+
+ /**
+ * Retries a request after setting the authentication
+ * for the current realm.
+ * @param string $username Username for realm.
+ * @param string $password Password for realm.
+ * @return boolean True if successful fetch. Note
+ * that authentication may still have
+ * failed.
+ * @access public
+ */
+ function authenticate($username, $password) {
+ if (! $this->_page->getRealm()) {
+ return false;
+ }
+ $url = $this->_page->getUrl();
+ if (! $url) {
+ return false;
+ }
+ $this->_user_agent->setIdentity(
+ $url->getHost(),
+ $this->_page->getRealm(),
+ $username,
+ $password);
+ return $this->retry();
+ }
+
+ /**
+ * Accessor for a breakdown of the frameset.
+ * @return array Hash tree of frames by name
+ * or index if no name.
+ * @access public
+ */
+ function getFrames() {
+ return $this->_page->getFrames();
+ }
+
+ /**
+ * Accessor for current frame focus. Will be
+ * false if no frame has focus.
+ * @return integer/string/boolean Label if any, otherwise
+ * the position in the frameset
+ * or false if none.
+ * @access public
+ */
+ function getFrameFocus() {
+ return $this->_page->getFrameFocus();
+ }
+
+ /**
+ * Sets the focus by index. The integer index starts from 1.
+ * @param integer $choice Chosen frame.
+ * @return boolean True if frame exists.
+ * @access public
+ */
+ function setFrameFocusByIndex($choice) {
+ return $this->_page->setFrameFocusByIndex($choice);
+ }
+
+ /**
+ * Sets the focus by name.
+ * @param string $name Chosen frame.
+ * @return boolean True if frame exists.
+ * @access public
+ */
+ function setFrameFocus($name) {
+ return $this->_page->setFrameFocus($name);
+ }
+
+ /**
+ * Clears the frame focus. All frames will be searched
+ * for content.
+ * @access public
+ */
+ function clearFrameFocus() {
+ return $this->_page->clearFrameFocus();
+ }
+
+ /**
+ * Accessor for last error.
+ * @return string Error from last response.
+ * @access public
+ */
+ function getTransportError() {
+ return $this->_page->getTransportError();
+ }
+
+ /**
+ * Accessor for current MIME type.
+ * @return string MIME type as string; e.g. 'text/html'
+ * @access public
+ */
+ function getMimeType() {
+ return $this->_page->getMimeType();
+ }
+
+ /**
+ * Accessor for last response code.
+ * @return integer Last HTTP response code received.
+ * @access public
+ */
+ function getResponseCode() {
+ return $this->_page->getResponseCode();
+ }
+
+ /**
+ * Accessor for last Authentication type. Only valid
+ * straight after a challenge (401).
+ * @return string Description of challenge type.
+ * @access public
+ */
+ function getAuthentication() {
+ return $this->_page->getAuthentication();
+ }
+
+ /**
+ * Accessor for last Authentication realm. Only valid
+ * straight after a challenge (401).
+ * @return string Name of security realm.
+ * @access public
+ */
+ function getRealm() {
+ return $this->_page->getRealm();
+ }
+
+ /**
+ * Accessor for current URL of page or frame if
+ * focused.
+ * @return string Location of current page or frame as
+ * a string.
+ */
+ function getUrl() {
+ $url = $this->_page->getUrl();
+ return $url ? $url->asString() : false;
+ }
+
+ /**
+ * Accessor for base URL of page if set via BASE tag
+ * @return string base URL
+ */
+ function getBaseUrl() {
+ $url = $this->_page->getBaseUrl();
+ return $url ? $url->asString() : false;
+ }
+
+ /**
+ * Accessor for raw bytes sent down the wire.
+ * @return string Original text sent.
+ * @access public
+ */
+ function getRequest() {
+ return $this->_page->getRequest();
+ }
+
+ /**
+ * Accessor for raw header information.
+ * @return string Header block.
+ * @access public
+ */
+ function getHeaders() {
+ return $this->_page->getHeaders();
+ }
+
+ /**
+ * Accessor for raw page information.
+ * @return string Original text content of web page.
+ * @access public
+ */
+ function getContent() {
+ return $this->_page->getRaw();
+ }
+
+ /**
+ * Accessor for plain text version of the page.
+ * @return string Normalised text representation.
+ * @access public
+ */
+ function getContentAsText() {
+ return $this->_page->getText();
+ }
+
+ /**
+ * Accessor for parsed title.
+ * @return string Title or false if no title is present.
+ * @access public
+ */
+ function getTitle() {
+ return $this->_page->getTitle();
+ }
+
+ /**
+ * Accessor for a list of all links in current page.
+ * @return array List of urls with scheme of
+ * http or https and hostname.
+ * @access public
+ */
+ function getUrls() {
+ return $this->_page->getUrls();
+ }
+
+ /**
+ * Sets all form fields with that name.
+ * @param string $label Name or label of field in forms.
+ * @param string $value New value of field.
+ * @return boolean True if field exists, otherwise false.
+ * @access public
+ */
+ function setField($label, $value, $position=false) {
+ return $this->_page->setField(new SimpleByLabelOrName($label), $value, $position);
+ }
+
+ /**
+ * Sets all form fields with that name. Will use label if
+ * one is available (not yet implemented).
+ * @param string $name Name of field in forms.
+ * @param string $value New value of field.
+ * @return boolean True if field exists, otherwise false.
+ * @access public
+ */
+ function setFieldByName($name, $value, $position=false) {
+ return $this->_page->setField(new SimpleByName($name), $value, $position);
+ }
+
+ /**
+ * Sets all form fields with that id attribute.
+ * @param string/integer $id Id of field in forms.
+ * @param string $value New value of field.
+ * @return boolean True if field exists, otherwise false.
+ * @access public
+ */
+ function setFieldById($id, $value) {
+ return $this->_page->setField(new SimpleById($id), $value);
+ }
+
+ /**
+ * Accessor for a form element value within the page.
+ * Finds the first match.
+ * @param string $label Field label.
+ * @return string/boolean A value if the field is
+ * present, false if unchecked
+ * and null if missing.
+ * @access public
+ */
+ function getField($label) {
+ return $this->_page->getField(new SimpleByLabelOrName($label));
+ }
+
+ /**
+ * Accessor for a form element value within the page.
+ * Finds the first match.
+ * @param string $name Field name.
+ * @return string/boolean A string if the field is
+ * present, false if unchecked
+ * and null if missing.
+ * @access public
+ */
+ function getFieldByName($name) {
+ return $this->_page->getField(new SimpleByName($name));
+ }
+
+ /**
+ * Accessor for a form element value within the page.
+ * @param string/integer $id Id of field in forms.
+ * @return string/boolean A string if the field is
+ * present, false if unchecked
+ * and null if missing.
+ * @access public
+ */
+ function getFieldById($id) {
+ return $this->_page->getField(new SimpleById($id));
+ }
+
+ /**
+ * Clicks the submit button by label. The owning
+ * form will be submitted by this.
+ * @param string $label Button label. An unlabeled
+ * button can be triggered by 'Submit'.
+ * @param hash $additional Additional form data.
+ * @return string/boolean Page on success.
+ * @access public
+ */
+ function clickSubmit($label = 'Submit', $additional = false) {
+ if (! ($form = &$this->_page->getFormBySubmit(new SimpleByLabel($label)))) {
+ return false;
+ }
+ $success = $this->_load(
+ $form->getAction(),
+ $form->submitButton(new SimpleByLabel($label), $additional));
+ return ($success ? $this->getContent() : $success);
+ }
+
+ /**
+ * Clicks the submit button by name attribute. The owning
+ * form will be submitted by this.
+ * @param string $name Button name.
+ * @param hash $additional Additional form data.
+ * @return string/boolean Page on success.
+ * @access public
+ */
+ function clickSubmitByName($name, $additional = false) {
+ if (! ($form = &$this->_page->getFormBySubmit(new SimpleByName($name)))) {
+ return false;
+ }
+ $success = $this->_load(
+ $form->getAction(),
+ $form->submitButton(new SimpleByName($name), $additional));
+ return ($success ? $this->getContent() : $success);
+ }
+
+ /**
+ * Clicks the submit button by ID attribute of the button
+ * itself. The owning form will be submitted by this.
+ * @param string $id Button ID.
+ * @param hash $additional Additional form data.
+ * @return string/boolean Page on success.
+ * @access public
+ */
+ function clickSubmitById($id, $additional = false) {
+ if (! ($form = &$this->_page->getFormBySubmit(new SimpleById($id)))) {
+ return false;
+ }
+ $success = $this->_load(
+ $form->getAction(),
+ $form->submitButton(new SimpleById($id), $additional));
+ return ($success ? $this->getContent() : $success);
+ }
+
+ /**
+ * Tests to see if a submit button exists with this
+ * label.
+ * @param string $label Button label.
+ * @return boolean True if present.
+ * @access public
+ */
+ function isSubmit($label) {
+ return (boolean)$this->_page->getFormBySubmit(new SimpleByLabel($label));
+ }
+
+ /**
+ * Clicks the submit image by some kind of label. Usually
+ * the alt tag or the nearest equivalent. The owning
+ * form will be submitted by this. Clicking outside of
+ * the boundary of the coordinates will result in
+ * a failure.
+ * @param string $label ID attribute of button.
+ * @param integer $x X-coordinate of imaginary click.
+ * @param integer $y Y-coordinate of imaginary click.
+ * @param hash $additional Additional form data.
+ * @return string/boolean Page on success.
+ * @access public
+ */
+ function clickImage($label, $x = 1, $y = 1, $additional = false) {
+ if (! ($form = &$this->_page->getFormByImage(new SimpleByLabel($label)))) {
+ return false;
+ }
+ $success = $this->_load(
+ $form->getAction(),
+ $form->submitImage(new SimpleByLabel($label), $x, $y, $additional));
+ return ($success ? $this->getContent() : $success);
+ }
+
+ /**
+ * Clicks the submit image by the name. Usually
+ * the alt tag or the nearest equivalent. The owning
+ * form will be submitted by this. Clicking outside of
+ * the boundary of the coordinates will result in
+ * a failure.
+ * @param string $name Name attribute of button.
+ * @param integer $x X-coordinate of imaginary click.
+ * @param integer $y Y-coordinate of imaginary click.
+ * @param hash $additional Additional form data.
+ * @return string/boolean Page on success.
+ * @access public
+ */
+ function clickImageByName($name, $x = 1, $y = 1, $additional = false) {
+ if (! ($form = &$this->_page->getFormByImage(new SimpleByName($name)))) {
+ return false;
+ }
+ $success = $this->_load(
+ $form->getAction(),
+ $form->submitImage(new SimpleByName($name), $x, $y, $additional));
+ return ($success ? $this->getContent() : $success);
+ }
+
+ /**
+ * Clicks the submit image by ID attribute. The owning
+ * form will be submitted by this. Clicking outside of
+ * the boundary of the coordinates will result in
+ * a failure.
+ * @param integer/string $id ID attribute of button.
+ * @param integer $x X-coordinate of imaginary click.
+ * @param integer $y Y-coordinate of imaginary click.
+ * @param hash $additional Additional form data.
+ * @return string/boolean Page on success.
+ * @access public
+ */
+ function clickImageById($id, $x = 1, $y = 1, $additional = false) {
+ if (! ($form = &$this->_page->getFormByImage(new SimpleById($id)))) {
+ return false;
+ }
+ $success = $this->_load(
+ $form->getAction(),
+ $form->submitImage(new SimpleById($id), $x, $y, $additional));
+ return ($success ? $this->getContent() : $success);
+ }
+
+ /**
+ * Tests to see if an image exists with this
+ * title or alt text.
+ * @param string $label Image text.
+ * @return boolean True if present.
+ * @access public
+ */
+ function isImage($label) {
+ return (boolean)$this->_page->getFormByImage(new SimpleByLabel($label));
+ }
+
+ /**
+ * Submits a form by the ID.
+ * @param string $id The form ID. No submit button value
+ * will be sent.
+ * @return string/boolean Page on success.
+ * @access public
+ */
+ function submitFormById($id) {
+ if (! ($form = &$this->_page->getFormById($id))) {
+ return false;
+ }
+ $success = $this->_load(
+ $form->getAction(),
+ $form->submit());
+ return ($success ? $this->getContent() : $success);
+ }
+
+ /**
+ * Finds a URL by label. Will find the first link
+ * found with this link text by default, or a later
+ * one if an index is given. The match ignores case and
+ * white space issues.
+ * @param string $label Text between the anchor tags.
+ * @param integer $index Link position counting from zero.
+ * @return string/boolean URL on success.
+ * @access public
+ */
+ function getLink($label, $index = 0) {
+ $urls = $this->_page->getUrlsByLabel($label);
+ if (count($urls) == 0) {
+ return false;
+ }
+ if (count($urls) < $index + 1) {
+ return false;
+ }
+ return $urls[$index];
+ }
+
+ /**
+ * Follows a link by label. Will click the first link
+ * found with this link text by default, or a later
+ * one if an index is given. The match ignores case and
+ * white space issues.
+ * @param string $label Text between the anchor tags.
+ * @param integer $index Link position counting from zero.
+ * @return string/boolean Page on success.
+ * @access public
+ */
+ function clickLink($label, $index = 0) {
+ $url = $this->getLink($label, $index);
+ if ($url === false) {
+ return false;
+ }
+ $this->_load($url, new SimpleGetEncoding());
+ return $this->getContent();
+ }
+
+ /**
+ * Finds a link by id attribute.
+ * @param string $id ID attribute value.
+ * @return string/boolean URL on success.
+ * @access public
+ */
+ function getLinkById($id) {
+ return $this->_page->getUrlById($id);
+ }
+
+ /**
+ * Follows a link by id attribute.
+ * @param string $id ID attribute value.
+ * @return string/boolean Page on success.
+ * @access public
+ */
+ function clickLinkById($id) {
+ if (! ($url = $this->getLinkById($id))) {
+ return false;
+ }
+ $this->_load($url, new SimpleGetEncoding());
+ return $this->getContent();
+ }
+
+ /**
+ * Clicks a visible text item. Will first try buttons,
+ * then links and then images.
+ * @param string $label Visible text or alt text.
+ * @return string/boolean Raw page or false.
+ * @access public
+ */
+ function click($label) {
+ $raw = $this->clickSubmit($label);
+ if (! $raw) {
+ $raw = $this->clickLink($label);
+ }
+ if (! $raw) {
+ $raw = $this->clickImage($label);
+ }
+ return $raw;
+ }
+
+ /**
+ * Tests to see if a click target exists.
+ * @param string $label Visible text or alt text.
+ * @return boolean True if target present.
+ * @access public
+ */
+ function isClickable($label) {
+ return $this->isSubmit($label) || ($this->getLink($label) !== false) || $this->isImage($label);
+ }
+}
+?> \ No newline at end of file
diff --git a/site/vendors/simpletest/collector.php b/site/vendors/simpletest/collector.php
new file mode 100644
index 0000000..5b8255d
--- /dev/null
+++ b/site/vendors/simpletest/collector.php
@@ -0,0 +1,122 @@
+<?php
+/**
+ * This file contains the following classes: {@link SimpleCollector},
+ * {@link SimplePatternCollector}.
+ *
+ * @author Travis Swicegood <development@domain51.com>
+ * @package SimpleTest
+ * @subpackage UnitTester
+ * @version $Id: collector.php 1723 2008-04-08 00:34:10Z lastcraft $
+ */
+
+/**
+ * The basic collector for {@link GroupTest}
+ *
+ * @see collect(), GroupTest::collect()
+ * @package SimpleTest
+ * @subpackage UnitTester
+ */
+class SimpleCollector {
+
+ /**
+ * Strips off any kind of slash at the end so as to normalise the path.
+ * @param string $path Path to normalise.
+ * @return string Path without trailing slash.
+ */
+ function _removeTrailingSlash($path) {
+ if (substr($path, -1) == DIRECTORY_SEPARATOR) {
+ return substr($path, 0, -1);
+ } elseif (substr($path, -1) == '/') {
+ return substr($path, 0, -1);
+ } else {
+ return $path;
+ }
+ }
+
+ /**
+ * Scans the directory and adds what it can.
+ * @param object $test Group test with {@link GroupTest::addTestFile()} method.
+ * @param string $path Directory to scan.
+ * @see _attemptToAdd()
+ */
+ function collect(&$test, $path) {
+ $path = $this->_removeTrailingSlash($path);
+ if ($handle = opendir($path)) {
+ while (($entry = readdir($handle)) !== false) {
+ if ($this->_isHidden($entry)) {
+ continue;
+ }
+ $this->_handle($test, $path . DIRECTORY_SEPARATOR . $entry);
+ }
+ closedir($handle);
+ }
+ }
+
+ /**
+ * This method determines what should be done with a given file and adds
+ * it via {@link GroupTest::addTestFile()} if necessary.
+ *
+ * This method should be overriden to provide custom matching criteria,
+ * such as pattern matching, recursive matching, etc. For an example, see
+ * {@link SimplePatternCollector::_handle()}.
+ *
+ * @param object $test Group test with {@link GroupTest::addTestFile()} method.
+ * @param string $filename A filename as generated by {@link collect()}
+ * @see collect()
+ * @access protected
+ */
+ function _handle(&$test, $file) {
+ if (is_dir($file)) {
+ return;
+ }
+ $test->addTestFile($file);
+ }
+
+ /**
+ * Tests for hidden files so as to skip them. Currently
+ * only tests for Unix hidden files.
+ * @param string $filename Plain filename.
+ * @return boolean True if hidden file.
+ * @access private
+ */
+ function _isHidden($filename) {
+ return strncmp($filename, '.', 1) == 0;
+ }
+}
+
+/**
+ * An extension to {@link SimpleCollector} that only adds files matching a
+ * given pattern.
+ *
+ * @package SimpleTest
+ * @subpackage UnitTester
+ * @see SimpleCollector
+ */
+class SimplePatternCollector extends SimpleCollector {
+ var $_pattern;
+
+ /**
+ *
+ * @param string $pattern Perl compatible regex to test name against
+ * See {@link http://us4.php.net/manual/en/reference.pcre.pattern.syntax.php PHP's PCRE}
+ * for full documentation of valid pattern.s
+ */
+ function SimplePatternCollector($pattern = '/php$/i') {
+ $this->_pattern = $pattern;
+ }
+
+ /**
+ * Attempts to add files that match a given pattern.
+ *
+ * @see SimpleCollector::_handle()
+ * @param object $test Group test with {@link GroupTest::addTestFile()} method.
+ * @param string $path Directory to scan.
+ * @access protected
+ */
+ function _handle(&$test, $filename) {
+ if (preg_match($this->_pattern, $filename)) {
+ parent::_handle($test, $filename);
+ }
+ }
+}
+?> \ No newline at end of file
diff --git a/site/vendors/simpletest/compatibility.php b/site/vendors/simpletest/compatibility.php
new file mode 100644
index 0000000..4e0f78a
--- /dev/null
+++ b/site/vendors/simpletest/compatibility.php
@@ -0,0 +1,173 @@
+<?php
+/**
+ * base include file for SimpleTest
+ * @package SimpleTest
+ * @version $Id: compatibility.php 1723 2008-04-08 00:34:10Z lastcraft $
+ */
+
+/**
+ * Static methods for compatibility between different
+ * PHP versions.
+ * @package SimpleTest
+ */
+class SimpleTestCompatibility {
+
+ /**
+ * Creates a copy whether in PHP5 or PHP4.
+ * @param object $object Thing to copy.
+ * @return object A copy.
+ * @access public
+ * @static
+ */
+ function copy($object) {
+ if (version_compare(phpversion(), '5') >= 0) {
+ eval('$copy = clone $object;');
+ return $copy;
+ }
+ return $object;
+ }
+
+ /**
+ * Identity test. Drops back to equality + types for PHP5
+ * objects as the === operator counts as the
+ * stronger reference constraint.
+ * @param mixed $first Test subject.
+ * @param mixed $second Comparison object.
+ * @return boolean True if identical.
+ * @access public
+ * @static
+ */
+ function isIdentical($first, $second) {
+ if (version_compare(phpversion(), '5') >= 0) {
+ return SimpleTestCompatibility::_isIdenticalType($first, $second);
+ }
+ if ($first != $second) {
+ return false;
+ }
+ return ($first === $second);
+ }
+
+ /**
+ * Recursive type test.
+ * @param mixed $first Test subject.
+ * @param mixed $second Comparison object.
+ * @return boolean True if same type.
+ * @access private
+ * @static
+ */
+ function _isIdenticalType($first, $second) {
+ if (gettype($first) != gettype($second)) {
+ return false;
+ }
+ if (is_object($first) && is_object($second)) {
+ if (get_class($first) != get_class($second)) {
+ return false;
+ }
+ return SimpleTestCompatibility::_isArrayOfIdenticalTypes(
+ get_object_vars($first),
+ get_object_vars($second));
+ }
+ if (is_array($first) && is_array($second)) {
+ return SimpleTestCompatibility::_isArrayOfIdenticalTypes($first, $second);
+ }
+ if ($first !== $second) {
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Recursive type test for each element of an array.
+ * @param mixed $first Test subject.
+ * @param mixed $second Comparison object.
+ * @return boolean True if identical.
+ * @access private
+ * @static
+ */
+ function _isArrayOfIdenticalTypes($first, $second) {
+ if (array_keys($first) != array_keys($second)) {
+ return false;
+ }
+ foreach (array_keys($first) as $key) {
+ $is_identical = SimpleTestCompatibility::_isIdenticalType(
+ $first[$key],
+ $second[$key]);
+ if (! $is_identical) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Test for two variables being aliases.
+ * @param mixed $first Test subject.
+ * @param mixed $second Comparison object.
+ * @return boolean True if same.
+ * @access public
+ * @static
+ */
+ function isReference(&$first, &$second) {
+ if (version_compare(phpversion(), '5', '>=') && is_object($first)) {
+ return ($first === $second);
+ }
+ if (is_object($first) && is_object($second)) {
+ $id = uniqid("test");
+ $first->$id = true;
+ $is_ref = isset($second->$id);
+ unset($first->$id);
+ return $is_ref;
+ }
+ $temp = $first;
+ $first = uniqid("test");
+ $is_ref = ($first === $second);
+ $first = $temp;
+ return $is_ref;
+ }
+
+ /**
+ * Test to see if an object is a member of a
+ * class hiearchy.
+ * @param object $object Object to test.
+ * @param string $class Root name of hiearchy.
+ * @return boolean True if class in hiearchy.
+ * @access public
+ * @static
+ */
+ function isA($object, $class) {
+ if (version_compare(phpversion(), '5') >= 0) {
+ if (! class_exists($class, false)) {
+ if (function_exists('interface_exists')) {
+ if (! interface_exists($class, false)) {
+ return false;
+ }
+ }
+ }
+ eval("\$is_a = \$object instanceof $class;");
+ return $is_a;
+ }
+ if (function_exists('is_a')) {
+ return is_a($object, $class);
+ }
+ return ((strtolower($class) == get_class($object))
+ or (is_subclass_of($object, $class)));
+ }
+
+ /**
+ * Sets a socket timeout for each chunk.
+ * @param resource $handle Socket handle.
+ * @param integer $timeout Limit in seconds.
+ * @access public
+ * @static
+ */
+ function setTimeout($handle, $timeout) {
+ if (function_exists('stream_set_timeout')) {
+ stream_set_timeout($handle, $timeout, 0);
+ } elseif (function_exists('socket_set_timeout')) {
+ socket_set_timeout($handle, $timeout, 0);
+ } elseif (function_exists('set_socket_timeout')) {
+ set_socket_timeout($handle, $timeout, 0);
+ }
+ }
+}
+?> \ No newline at end of file
diff --git a/site/vendors/simpletest/cookies.php b/site/vendors/simpletest/cookies.php
new file mode 100644
index 0000000..ed1c025
--- /dev/null
+++ b/site/vendors/simpletest/cookies.php
@@ -0,0 +1,380 @@
+<?php
+/**
+ * Base include file for SimpleTest
+ * @package SimpleTest
+ * @subpackage WebTester
+ * @version $Id: cookies.php 1723 2008-04-08 00:34:10Z lastcraft $
+ */
+
+/**#@+
+ * include other SimpleTest class files
+ */
+require_once(dirname(__FILE__) . '/url.php');
+/**#@-*/
+
+/**
+ * Cookie data holder. Cookie rules are full of pretty
+ * arbitary stuff. I have used...
+ * http://wp.netscape.com/newsref/std/cookie_spec.html
+ * http://www.cookiecentral.com/faq/
+ * @package SimpleTest
+ * @subpackage WebTester
+ */
+class SimpleCookie {
+ var $_host;
+ var $_name;
+ var $_value;
+ var $_path;
+ var $_expiry;
+ var $_is_secure;
+
+ /**
+ * Constructor. Sets the stored values.
+ * @param string $name Cookie key.
+ * @param string $value Value of cookie.
+ * @param string $path Cookie path if not host wide.
+ * @param string $expiry Expiry date as string.
+ * @param boolean $is_secure Currently ignored.
+ */
+ function SimpleCookie($name, $value = false, $path = false, $expiry = false, $is_secure = false) {
+ $this->_host = false;
+ $this->_name = $name;
+ $this->_value = $value;
+ $this->_path = ($path ? $this->_fixPath($path) : "/");
+ $this->_expiry = false;
+ if (is_string($expiry)) {
+ $this->_expiry = strtotime($expiry);
+ } elseif (is_integer($expiry)) {
+ $this->_expiry = $expiry;
+ }
+ $this->_is_secure = $is_secure;
+ }
+
+ /**
+ * Sets the host. The cookie rules determine
+ * that the first two parts are taken for
+ * certain TLDs and three for others. If the
+ * new host does not match these rules then the
+ * call will fail.
+ * @param string $host New hostname.
+ * @return boolean True if hostname is valid.
+ * @access public
+ */
+ function setHost($host) {
+ if ($host = $this->_truncateHost($host)) {
+ $this->_host = $host;
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Accessor for the truncated host to which this
+ * cookie applies.
+ * @return string Truncated hostname.
+ * @access public
+ */
+ function getHost() {
+ return $this->_host;
+ }
+
+ /**
+ * Test for a cookie being valid for a host name.
+ * @param string $host Host to test against.
+ * @return boolean True if the cookie would be valid
+ * here.
+ */
+ function isValidHost($host) {
+ return ($this->_truncateHost($host) === $this->getHost());
+ }
+
+ /**
+ * Extracts just the domain part that determines a
+ * cookie's host validity.
+ * @param string $host Host name to truncate.
+ * @return string Domain or false on a bad host.
+ * @access private
+ */
+ function _truncateHost($host) {
+ $tlds = SimpleUrl::getAllTopLevelDomains();
+ if (preg_match('/[a-z\-]+\.(' . $tlds . ')$/i', $host, $matches)) {
+ return $matches[0];
+ } elseif (preg_match('/[a-z\-]+\.[a-z\-]+\.[a-z\-]+$/i', $host, $matches)) {
+ return $matches[0];
+ }
+ return false;
+ }
+
+ /**
+ * Accessor for name.
+ * @return string Cookie key.
+ * @access public
+ */
+ function getName() {
+ return $this->_name;
+ }
+
+ /**
+ * Accessor for value. A deleted cookie will
+ * have an empty string for this.
+ * @return string Cookie value.
+ * @access public
+ */
+ function getValue() {
+ return $this->_value;
+ }
+
+ /**
+ * Accessor for path.
+ * @return string Valid cookie path.
+ * @access public
+ */
+ function getPath() {
+ return $this->_path;
+ }
+
+ /**
+ * Tests a path to see if the cookie applies
+ * there. The test path must be longer or
+ * equal to the cookie path.
+ * @param string $path Path to test against.
+ * @return boolean True if cookie valid here.
+ * @access public
+ */
+ function isValidPath($path) {
+ return (strncmp(
+ $this->_fixPath($path),
+ $this->getPath(),
+ strlen($this->getPath())) == 0);
+ }
+
+ /**
+ * Accessor for expiry.
+ * @return string Expiry string.
+ * @access public
+ */
+ function getExpiry() {
+ if (! $this->_expiry) {
+ return false;
+ }
+ return gmdate("D, d M Y H:i:s", $this->_expiry) . " GMT";
+ }
+
+ /**
+ * Test to see if cookie is expired against
+ * the cookie format time or timestamp.
+ * Will give true for a session cookie.
+ * @param integer/string $now Time to test against. Result
+ * will be false if this time
+ * is later than the cookie expiry.
+ * Can be either a timestamp integer
+ * or a cookie format date.
+ * @access public
+ */
+ function isExpired($now) {
+ if (! $this->_expiry) {
+ return true;
+ }
+ if (is_string($now)) {
+ $now = strtotime($now);
+ }
+ return ($this->_expiry < $now);
+ }
+
+ /**
+ * Ages the cookie by the specified number of
+ * seconds.
+ * @param integer $interval In seconds.
+ * @public
+ */
+ function agePrematurely($interval) {
+ if ($this->_expiry) {
+ $this->_expiry -= $interval;
+ }
+ }
+
+ /**
+ * Accessor for the secure flag.
+ * @return boolean True if cookie needs SSL.
+ * @access public
+ */
+ function isSecure() {
+ return $this->_is_secure;
+ }
+
+ /**
+ * Adds a trailing and leading slash to the path
+ * if missing.
+ * @param string $path Path to fix.
+ * @access private
+ */
+ function _fixPath($path) {
+ if (substr($path, 0, 1) != '/') {
+ $path = '/' . $path;
+ }
+ if (substr($path, -1, 1) != '/') {
+ $path .= '/';
+ }
+ return $path;
+ }
+}
+
+/**
+ * Repository for cookies. This stuff is a
+ * tiny bit browser dependent.
+ * @package SimpleTest
+ * @subpackage WebTester
+ */
+class SimpleCookieJar {
+ var $_cookies;
+
+ /**
+ * Constructor. Jar starts empty.
+ * @access public
+ */
+ function SimpleCookieJar() {
+ $this->_cookies = array();
+ }
+
+ /**
+ * Removes expired and temporary cookies as if
+ * the browser was closed and re-opened.
+ * @param string/integer $now Time to test expiry against.
+ * @access public
+ */
+ function restartSession($date = false) {
+ $surviving_cookies = array();
+ for ($i = 0; $i < count($this->_cookies); $i++) {
+ if (! $this->_cookies[$i]->getValue()) {
+ continue;
+ }
+ if (! $this->_cookies[$i]->getExpiry()) {
+ continue;
+ }
+ if ($date && $this->_cookies[$i]->isExpired($date)) {
+ continue;
+ }
+ $surviving_cookies[] = $this->_cookies[$i];
+ }
+ $this->_cookies = $surviving_cookies;
+ }
+
+ /**
+ * Ages all cookies in the cookie jar.
+ * @param integer $interval The old session is moved
+ * into the past by this number
+ * of seconds. Cookies now over
+ * age will be removed.
+ * @access public
+ */
+ function agePrematurely($interval) {
+ for ($i = 0; $i < count($this->_cookies); $i++) {
+ $this->_cookies[$i]->agePrematurely($interval);
+ }
+ }
+
+ /**
+ * Sets an additional cookie. If a cookie has
+ * the same name and path it is replaced.
+ * @param string $name Cookie key.
+ * @param string $value Value of cookie.
+ * @param string $host Host upon which the cookie is valid.
+ * @param string $path Cookie path if not host wide.
+ * @param string $expiry Expiry date.
+ * @access public
+ */
+ function setCookie($name, $value, $host = false, $path = '/', $expiry = false) {
+ $cookie = new SimpleCookie($name, $value, $path, $expiry);
+ if ($host) {
+ $cookie->setHost($host);
+ }
+ $this->_cookies[$this->_findFirstMatch($cookie)] = $cookie;
+ }
+
+ /**
+ * Finds a matching cookie to write over or the
+ * first empty slot if none.
+ * @param SimpleCookie $cookie Cookie to write into jar.
+ * @return integer Available slot.
+ * @access private
+ */
+ function _findFirstMatch($cookie) {
+ for ($i = 0; $i < count($this->_cookies); $i++) {
+ $is_match = $this->_isMatch(
+ $cookie,
+ $this->_cookies[$i]->getHost(),
+ $this->_cookies[$i]->getPath(),
+ $this->_cookies[$i]->getName());
+ if ($is_match) {
+ return $i;
+ }
+ }
+ return count($this->_cookies);
+ }
+
+ /**
+ * Reads the most specific cookie value from the
+ * browser cookies. Looks for the longest path that
+ * matches.
+ * @param string $host Host to search.
+ * @param string $path Applicable path.
+ * @param string $name Name of cookie to read.
+ * @return string False if not present, else the
+ * value as a string.
+ * @access public
+ */
+ function getCookieValue($host, $path, $name) {
+ $longest_path = '';
+ foreach ($this->_cookies as $cookie) {
+ if ($this->_isMatch($cookie, $host, $path, $name)) {
+ if (strlen($cookie->getPath()) > strlen($longest_path)) {
+ $value = $cookie->getValue();
+ $longest_path = $cookie->getPath();
+ }
+ }
+ }
+ return (isset($value) ? $value : false);
+ }
+
+ /**
+ * Tests cookie for matching against search
+ * criteria.
+ * @param SimpleTest $cookie Cookie to test.
+ * @param string $host Host must match.
+ * @param string $path Cookie path must be shorter than
+ * this path.
+ * @param string $name Name must match.
+ * @return boolean True if matched.
+ * @access private
+ */
+ function _isMatch($cookie, $host, $path, $name) {
+ if ($cookie->getName() != $name) {
+ return false;
+ }
+ if ($host && $cookie->getHost() && ! $cookie->isValidHost($host)) {
+ return false;
+ }
+ if (! $cookie->isValidPath($path)) {
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Uses a URL to sift relevant cookies by host and
+ * path. Results are list of strings of form "name=value".
+ * @param SimpleUrl $url Url to select by.
+ * @return array Valid name and value pairs.
+ * @access public
+ */
+ function selectAsPairs($url) {
+ $pairs = array();
+ foreach ($this->_cookies as $cookie) {
+ if ($this->_isMatch($cookie, $url->getHost(), $url->getPath(), $cookie->getName())) {
+ $pairs[] = $cookie->getName() . '=' . $cookie->getValue();
+ }
+ }
+ return $pairs;
+ }
+}
+?> \ No newline at end of file
diff --git a/site/vendors/simpletest/default_reporter.php b/site/vendors/simpletest/default_reporter.php
new file mode 100644
index 0000000..bd4c6a1
--- /dev/null
+++ b/site/vendors/simpletest/default_reporter.php
@@ -0,0 +1,133 @@
+<?php
+/**
+ * Optional include file for SimpleTest
+ * @package SimpleTest
+ * @subpackage UnitTester
+ * @version $Id: default_reporter.php 1704 2008-03-25 00:47:04Z lastcraft $
+ */
+
+/**#@+
+ * include other SimpleTest class files
+ */
+require_once(dirname(__FILE__) . '/simpletest.php');
+require_once(dirname(__FILE__) . '/scorer.php');
+require_once(dirname(__FILE__) . '/reporter.php');
+require_once(dirname(__FILE__) . '/xml.php');
+/**#@-*/
+
+/**
+ * Parser for command line arguments. Extracts
+ * the a specific test to run and engages XML
+ * reporting when necessary.
+ * @package SimpleTest
+ * @subpackage UnitTester
+ */
+class SimpleCommandLineParser {
+ var $_to_property = array(
+ 'case' => '_case', 'c' => '_case',
+ 'test' => '_test', 't' => '_test',
+ 'xml' => '_xml', 'x' => '_xml');
+ var $_case = '';
+ var $_test = '';
+ var $_xml = false;
+ var $_no_skips = false;
+
+ /**
+ * Parses raw command line arguments into object properties.
+ * @param string $arguments Raw commend line arguments.
+ */
+ function SimpleCommandLineParser($arguments) {
+ if (! is_array($arguments)) {
+ return;
+ }
+ foreach ($arguments as $i => $argument) {
+ if (preg_match('/^--?(test|case|t|c)=(.+)$/', $argument, $matches)) {
+ $property = $this->_to_property[$matches[1]];
+ $this->$property = $matches[2];
+ } elseif (preg_match('/^--?(test|case|t|c)$/', $argument, $matches)) {
+ $property = $this->_to_property[$matches[1]];
+ if (isset($arguments[$i + 1])) {
+ $this->$property = $arguments[$i + 1];
+ }
+ } elseif (preg_match('/^--?(xml|x)$/', $argument)) {
+ $this->_xml = true;
+ } elseif (preg_match('/^--?(no-skip|no-skips|s)$/', $argument)) {
+ $this->_no_skips = true;
+ }
+ }
+ }
+
+ /**
+ * Run only this test.
+ * @return string Test name to run.
+ * @access public
+ */
+ function getTest() {
+ return $this->_test;
+ }
+
+ /**
+ * Run only this test suite.
+ * @return string Test class name to run.
+ * @access public
+ */
+ function getTestCase() {
+ return $this->_case;
+ }
+
+ /**
+ * Output should be XML or not.
+ * @return boolean True if XML desired.
+ * @access public
+ */
+ function isXml() {
+ return $this->_xml;
+ }
+
+ /**
+ * Output should suppress skip messages.
+ * @return boolean True for no skips.
+ * @access public
+ */
+ function noSkips() {
+ return $this->_no_skips;
+ }
+}
+
+/**
+ * The default reporter used by SimpleTest's autorun
+ * feature. The actual reporters used are dependency
+ * injected and can be overridden.
+ * @package SimpleTest
+ * @subpackage UnitTester
+ */
+class DefaultReporter extends SimpleReporterDecorator {
+
+ /**
+ * Assembles the appopriate reporter for the environment.
+ */
+ function DefaultReporter() {
+ if (SimpleReporter::inCli()) {
+ global $argv;
+ $parser = new SimpleCommandLineParser($argv);
+ $interfaces = $parser->isXml() ? array('XmlReporter') : array('TextReporter');
+ $reporter = &new SelectiveReporter(
+ SimpleTest::preferred($interfaces),
+ $parser->getTestCase(),
+ $parser->getTest());
+ if ($parser->noSkips()) {
+ $reporter = &new NoSkipsReporter($reporter);
+ }
+ } else {
+ $reporter = &new SelectiveReporter(
+ SimpleTest::preferred('HtmlReporter'),
+ @$_GET['c'],
+ @$_GET['t']);
+ if (@$_GET['skips'] == 'no' || @$_GET['show-skips'] == 'no') {
+ $reporter = &new NoSkipsReporter($reporter);
+ }
+ }
+ $this->SimpleReporterDecorator($reporter);
+ }
+}
+?> \ No newline at end of file
diff --git a/site/vendors/simpletest/detached.php b/site/vendors/simpletest/detached.php
new file mode 100644
index 0000000..e323d8c
--- /dev/null
+++ b/site/vendors/simpletest/detached.php
@@ -0,0 +1,96 @@
+<?php
+/**
+ * base include file for SimpleTest
+ * @package SimpleTest
+ * @subpackage UnitTester
+ * @version $Id: detached.php 1723 2008-04-08 00:34:10Z lastcraft $
+ */
+
+/**#@+
+ * include other SimpleTest class files
+ */
+require_once(dirname(__FILE__) . '/xml.php');
+require_once(dirname(__FILE__) . '/shell_tester.php');
+/**#@-*/
+
+/**
+ * Runs an XML formated test in a separate process.
+ * @package SimpleTest
+ * @subpackage UnitTester
+ */
+class DetachedTestCase {
+ var $_command;
+ var $_dry_command;
+ var $_size;
+
+ /**
+ * Sets the location of the remote test.
+ * @param string $command Test script.
+ * @param string $dry_command Script for dry run.
+ * @access public
+ */
+ function DetachedTestCase($command, $dry_command = false) {
+ $this->_command = $command;
+ $this->_dry_command = $dry_command ? $dry_command : $command;
+ $this->_size = false;
+ }
+
+ /**
+ * Accessor for the test name for subclasses.
+ * @return string Name of the test.
+ * @access public
+ */
+ function getLabel() {
+ return $this->_command;
+ }
+
+ /**
+ * Runs the top level test for this class. Currently
+ * reads the data as a single chunk. I'll fix this
+ * once I have added iteration to the browser.
+ * @param SimpleReporter $reporter Target of test results.
+ * @returns boolean True if no failures.
+ * @access public
+ */
+ function run(&$reporter) {
+ $shell = &new SimpleShell();
+ $shell->execute($this->_command);
+ $parser = &$this->_createParser($reporter);
+ if (! $parser->parse($shell->getOutput())) {
+ trigger_error('Cannot parse incoming XML from [' . $this->_command . ']');
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Accessor for the number of subtests.
+ * @return integer Number of test cases.
+ * @access public
+ */
+ function getSize() {
+ if ($this->_size === false) {
+ $shell = &new SimpleShell();
+ $shell->execute($this->_dry_command);
+ $reporter = &new SimpleReporter();
+ $parser = &$this->_createParser($reporter);
+ if (! $parser->parse($shell->getOutput())) {
+ trigger_error('Cannot parse incoming XML from [' . $this->_dry_command . ']');
+ return false;
+ }
+ $this->_size = $reporter->getTestCaseCount();
+ }
+ return $this->_size;
+ }
+
+ /**
+ * Creates the XML parser.
+ * @param SimpleReporter $reporter Target of test results.
+ * @return SimpleTestXmlListener XML reader.
+ * @access protected
+ */
+ function &_createParser(&$reporter) {
+ return new SimpleTestXmlParser($reporter);
+ }
+}
+?> \ No newline at end of file
diff --git a/site/vendors/simpletest/docs/en/authentication_documentation.html b/site/vendors/simpletest/docs/en/authentication_documentation.html
new file mode 100644
index 0000000..8da2a7f
--- /dev/null
+++ b/site/vendors/simpletest/docs/en/authentication_documentation.html
@@ -0,0 +1,355 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>SimpleTest documentation for testing log-in and authentication</title>
+<link rel="stylesheet" type="text/css" href="docs.css" title="Styles">
+</head>
+<body>
+<div class="menu_back"><div class="menu">
+<a href="index.html">SimpleTest</a>
+ |
+ <a href="overview.html">Overview</a>
+ |
+ <a href="unit_test_documentation.html">Unit tester</a>
+ |
+ <a href="group_test_documentation.html">Group tests</a>
+ |
+ <a href="mock_objects_documentation.html">Mock objects</a>
+ |
+ <a href="partial_mocks_documentation.html">Partial mocks</a>
+ |
+ <a href="reporter_documentation.html">Reporting</a>
+ |
+ <a href="expectation_documentation.html">Expectations</a>
+ |
+ <a href="web_tester_documentation.html">Web tester</a>
+ |
+ <a href="form_testing_documentation.html">Testing forms</a>
+ |
+ <span class="chosen">Authentication</span>
+ |
+ <a href="browser_documentation.html">Scriptable browser</a>
+</div></div>
+<h1>Authentication documentation</h1>
+ This page...
+ <ul>
+<li>
+ Getting through <a href="#basic">Basic HTTP authentication</a>
+ </li>
+<li>
+ Testing <a href="#cookies">cookie based authentication</a>
+ </li>
+<li>
+ Managing <a href="#session">browser sessions</a> and timeouts
+ </li>
+</ul>
+<div class="content">
+
+ <p>
+ One of the trickiest, and yet most important, areas
+ of testing web sites is the security.
+ Testing these schemes is one of the core goals of
+ the SimpleTest web tester.
+ </p>
+
+ <p><a class="target" name="basic"><h2>Basic HTTP authentication</h2></a></p>
+ <p>
+ If you fetch a page protected by basic authentication then
+ rather than receiving content, you will instead get a 401
+ header.
+ We can illustrate this with this test...
+<pre>
+class AuthenticationTest extends WebTestCase {<strong>
+ function test401Header() {
+ $this-&gt;get('http://www.lastcraft.com/protected/');
+ $this-&gt;showHeaders();
+ }</strong>
+}
+</pre>
+ This allows us to see the challenge header...
+ <div class="demo">
+ <h1>File test</h1>
+<pre style="background-color: lightgray; color: black">
+HTTP/1.1 401 Authorization Required
+Date: Sat, 18 Sep 2004 19:25:18 GMT
+Server: Apache/1.3.29 (Unix) PHP/4.3.4
+WWW-Authenticate: Basic realm="SimpleTest basic authentication"
+Connection: close
+Content-Type: text/html; charset=iso-8859-1
+</pre>
+ <div style="padding: 8px; margin-top: 1em; background-color: green; color: white;">1/1 test cases complete.
+ <strong>0</strong> passes, <strong>0</strong> fails and <strong>0</strong> exceptions.</div>
+ </div>
+ We are trying to get away from visual inspection though, and so SimpleTest
+ allows to make automated assertions against the challenge.
+ Here is a thorough test of our header...
+<pre>
+class AuthenticationTest extends WebTestCase {
+ function test401Header() {
+ $this-&gt;get('http://www.lastcraft.com/protected/');<strong>
+ $this-&gt;assertAuthentication('Basic');
+ $this-&gt;assertResponse(401);
+ $this-&gt;assertRealm('SimpleTest basic authentication');</strong>
+ }
+}
+</pre>
+ Any one of these tests would normally do on it's own depending
+ on the amount of detail you want to see.
+ </p>
+ <p>
+ One theme that runs through SimpleTest is the ability to use
+ <span class="new_code">SimpleExpectation</span> objects wherever a simple
+ match is not enough.
+ If you want only an approximate match to the realm for
+ example, you can do this...
+<pre>
+class AuthenticationTest extends WebTestCase {
+ function test401Header() {
+ $this-&gt;get('http://www.lastcraft.com/protected/');
+ $this-&gt;assertRealm(<strong>new PatternExpectation('/simpletest/i')</strong>);
+ }
+}
+</pre>
+ Most of the time we are not interested in testing the
+ authentication itself, but want to get past it to test
+ the pages underneath.
+ As soon as the challenge has been issued we can reply with
+ an authentication response...
+<pre>
+class AuthenticationTest extends WebTestCase {
+ function testCanAuthenticate() {
+ $this-&gt;get('http://www.lastcraft.com/protected/');<strong>
+ $this-&gt;authenticate('Me', 'Secret');</strong>
+ $this-&gt;assertTitle(...);
+ }
+}
+</pre>
+ The username and password will now be sent with every
+ subsequent request to that directory and subdirectories.
+ You will have to authenticate again if you step outside
+ the authenticated directory, but SimpleTest is smart enough
+ to merge subdirectories into a common realm.
+ </p>
+ <p>
+ You can shortcut this step further by encoding the log in
+ details straight into the URL...
+<pre>
+class AuthenticationTest extends WebTestCase {
+ function testCanReadAuthenticatedPages() {
+ $this-&gt;get('http://<strong>Me:Secret@</strong>www.lastcraft.com/protected/');
+ $this-&gt;assertTitle(...);
+ }
+}
+</pre>
+ If your username or password has special characters, then you
+ will have to URL encode them or the request will not be parsed
+ correctly.
+ Also this header will not be sent on subsequent requests if
+ you request a page with a fully qualified URL.
+ If you navigate with relative URLs though, the authentication
+ information will be preserved.
+ </p>
+ <p>
+ Only basic authentication is currently supported and this is
+ only really secure in tandem with HTTPS connections.
+ This is usually enough to protect test server from prying eyes,
+ however.
+ Digest authentication and NTLM authentication may be added
+ in the future.
+ </p>
+
+ <p><a class="target" name="cookies"><h2>Cookies</h2></a></p>
+ <p>
+ Basic authentication doesn't give enough control over the
+ user interface for web developers.
+ More likely this functionality will be coded directly into
+ the web architecture using cookies and complicated timeouts.
+ </p>
+ <p>
+ Starting with a simple log-in form...
+<pre>
+&lt;form&gt;
+ Username:
+ &lt;input type="text" name="u" value="" /&gt;&lt;br /&gt;
+ Password:
+ &lt;input type="password" name="p" value="" /&gt;&lt;br /&gt;
+ &lt;input type="submit" value="Log in" /&gt;
+&lt;/form&gt;
+</pre>
+ Which looks like...
+ </p>
+ <p>
+ <form class="demo">
+ Username:
+ <input type="text" name="u" value=""><br>
+ Password:
+ <input type="password" name="p" value=""><br>
+ <input type="submit" value="Log in">
+ </form>
+ </p>
+ <p>
+ Let's suppose that in fetching this page a cookie has been
+ set with a session ID.
+ We are not going to fill the form in yet, just test that
+ we are tracking the user.
+ Here is the test...
+<pre>
+class LogInTest extends WebTestCase {
+ function testSessionCookieSetBeforeForm() {
+ $this-&gt;get('http://www.my-site.com/login.php');<strong>
+ $this-&gt;assertCookie('SID');</strong>
+ }
+}
+</pre>
+ All we are doing is confirming that the cookie is set.
+ As the value is likely to be rather cryptic it's not
+ really worth testing this with...
+<pre>
+class LogInTest extends WebTestCase {
+ function testSessionCookieIsCorrectPattern() {
+ $this-&gt;get('http://www.my-site.com/login.php');
+ $this-&gt;assertCookie('SID', <strong>new PatternExpectation('/[a-f0-9]{32}/i')</strong>);
+ }
+}
+</pre>
+ The rest of the test would be the same as any other form,
+ but we might want to confirm that we still have the same
+ cookie after log-in as before we entered.
+ We wouldn't want to lose track of this after all.
+ Here is a possible test for this...
+<pre>
+class LogInTest extends WebTestCase {
+ ...
+ function testSessionCookieSameAfterLogIn() {
+ $this-&gt;get('http://www.my-site.com/login.php');<strong>
+ $session = $this-&gt;getCookie('SID');
+ $this-&gt;setField('u', 'Me');
+ $this-&gt;setField('p', 'Secret');
+ $this-&gt;click('Log in');
+ $this-&gt;assertText('Welcome Me');
+ $this-&gt;assertCookie('SID', $session);</strong>
+ }
+}
+</pre>
+ This confirms that the session identifier is maintained
+ afer log-in.
+ </p>
+ <p>
+ We could even attempt to spoof our own system by setting
+ arbitrary cookies to gain access...
+<pre>
+class LogInTest extends WebTestCase {
+ ...
+ function testSessionCookieSameAfterLogIn() {
+ $this-&gt;get('http://www.my-site.com/login.php');<strong>
+ $this-&gt;setCookie('SID', 'Some other session');
+ $this-&gt;get('http://www.my-site.com/restricted.php');</strong>
+ $this-&gt;assertText('Access denied');
+ }
+}
+</pre>
+ Is your site protected from this attack?
+ </p>
+
+ <p><a class="target" name="session"><h2>Browser sessions</h2></a></p>
+ <p>
+ If you are testing an authentication system a critical piece
+ of behaviour is what happens when a user logs back in.
+ We would like to simulate closing and reopening a browser...
+<pre>
+class LogInTest extends WebTestCase {
+ ...
+ function testLoseAuthenticationAfterBrowserClose() {
+ $this-&gt;get('http://www.my-site.com/login.php');
+ $this-&gt;setField('u', 'Me');
+ $this-&gt;setField('p', 'Secret');
+ $this-&gt;click('Log in');
+ $this-&gt;assertText('Welcome Me');<strong>
+
+ $this-&gt;restart();
+ $this-&gt;get('http://www.my-site.com/restricted.php');
+ $this-&gt;assertText('Access denied');</strong>
+ }
+}
+</pre>
+ The <span class="new_code">WebTestCase::restart()</span> method will
+ preserve cookies that have unexpired timeouts, but throw away
+ those that are temporary or expired.
+ You can optionally specify the time and date that the restart
+ happened.
+ </p>
+ <p>
+ Expiring cookies can be a problem.
+ After all, if you have a cookie that expires after an hour,
+ you don't want to stall the test for an hour while the
+ cookie passes it's timeout.
+ </p>
+ <p>
+ To push the cookies over the hour limit you can age them
+ before you restart the session...
+<pre>
+class LogInTest extends WebTestCase {
+ ...
+ function testLoseAuthenticationAfterOneHour() {
+ $this-&gt;get('http://www.my-site.com/login.php');
+ $this-&gt;setField('u', 'Me');
+ $this-&gt;setField('p', 'Secret');
+ $this-&gt;click('Log in');
+ $this-&gt;assertText('Welcome Me');
+ <strong>
+ $this-&gt;ageCookies(3600);</strong>
+ $this-&gt;restart();
+ $this-&gt;get('http://www.my-site.com/restricted.php');
+ $this-&gt;assertText('Access denied');
+ }
+}
+</pre>
+ After the restart it will appear that cookies are an
+ hour older and any that pass their expiry will have
+ disappeared.
+ </p>
+
+ </div>
+ References and related information...
+ <ul>
+<li>
+ SimpleTest project page on <a href="http://sourceforge.net/projects/simpletest/">SourceForge</a>.
+ </li>
+<li>
+ SimpleTest download page on <a href="http://www.lastcraft.com/simple_test.php">LastCraft</a>.
+ </li>
+<li>
+ The <a href="http://simpletest.org/api/">developer's API for SimpleTest</a>
+ gives full detail on the classes and assertions available.
+ </li>
+</ul>
+<div class="menu_back"><div class="menu">
+<a href="index.html">SimpleTest</a>
+ |
+ <a href="overview.html">Overview</a>
+ |
+ <a href="unit_test_documentation.html">Unit tester</a>
+ |
+ <a href="group_test_documentation.html">Group tests</a>
+ |
+ <a href="mock_objects_documentation.html">Mock objects</a>
+ |
+ <a href="partial_mocks_documentation.html">Partial mocks</a>
+ |
+ <a href="reporter_documentation.html">Reporting</a>
+ |
+ <a href="expectation_documentation.html">Expectations</a>
+ |
+ <a href="web_tester_documentation.html">Web tester</a>
+ |
+ <a href="form_testing_documentation.html">Testing forms</a>
+ |
+ <span class="chosen">Authentication</span>
+ |
+ <a href="browser_documentation.html">Scriptable browser</a>
+</div></div>
+<div class="copyright">
+ Copyright<br>Marcus Baker 2006
+ </div>
+</body>
+</html>
diff --git a/site/vendors/simpletest/docs/en/browser_documentation.html b/site/vendors/simpletest/docs/en/browser_documentation.html
new file mode 100644
index 0000000..522f3a5
--- /dev/null
+++ b/site/vendors/simpletest/docs/en/browser_documentation.html
@@ -0,0 +1,447 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>SimpleTest documentation for the scriptable web browser component</title>
+<link rel="stylesheet" type="text/css" href="docs.css" title="Styles">
+</head>
+<body>
+<div class="menu_back"><div class="menu">
+<a href="index.html">SimpleTest</a>
+ |
+ <a href="overview.html">Overview</a>
+ |
+ <a href="unit_test_documentation.html">Unit tester</a>
+ |
+ <a href="group_test_documentation.html">Group tests</a>
+ |
+ <a href="mock_objects_documentation.html">Mock objects</a>
+ |
+ <a href="partial_mocks_documentation.html">Partial mocks</a>
+ |
+ <a href="reporter_documentation.html">Reporting</a>
+ |
+ <a href="expectation_documentation.html">Expectations</a>
+ |
+ <a href="web_tester_documentation.html">Web tester</a>
+ |
+ <a href="form_testing_documentation.html">Testing forms</a>
+ |
+ <a href="authentication_documentation.html">Authentication</a>
+ |
+ <span class="chosen">Scriptable browser</span>
+</div></div>
+<h1>PHP Scriptable Web Browser</h1>
+ This page...
+ <ul>
+<li>
+ Using the bundled <a href="#scripting">web browser in scripts</a>
+ </li>
+<li>
+ <a href="#debug">Debugging</a> failed pages
+ </li>
+<li>
+ Complex <a href="#unit">tests with multiple web browsers</a>
+ </li>
+</ul>
+<div class="content">
+
+ <p>
+ SimpleTest's web browser component can be used not just
+ outside of the <span class="new_code">WebTestCase</span> class, but also
+ independently of the SimpleTest framework itself.
+ </p>
+
+ <p><a class="target" name="scripting"><h2>The Scriptable Browser</h2></a></p>
+ <p>
+ You can use the web browser in PHP scripts to confirm
+ services are up and running, or to extract information
+ from them at a regular basis.
+ For example, here is a small script to extract the current number of
+ open PHP 5 bugs from the <a href="http://www.php.net/">PHP web site</a>...
+<pre>
+<strong>&lt;?php
+require_once('simpletest/browser.php');
+
+$browser = &amp;new SimpleBrowser();
+$browser-&gt;get('http://php.net/');
+$browser-&gt;click('reporting bugs');
+$browser-&gt;click('statistics');
+$page = $browser-&gt;click('PHP 5 bugs only');
+preg_match('/status=Open.*?by=Any.*?(\d+)&lt;\/a&gt;/', $page, $matches);
+print $matches[1];
+?&gt;</strong>
+</pre>
+ There are simpler methods to do this particular example in PHP
+ of course.
+ For example you can just use the PHP <span class="new_code">file()</span>
+ command against what here is a pretty fixed page.
+ However, using the web browser for scripts allows authentication,
+ correct handling of cookies, automatic loading of frames, redirects,
+ form submission and the ability to examine the page headers.
+ Such methods are fragile against a site that is constantly
+ evolving and you would want a more direct way of accessing
+ data in a permanent set up, but for simple tasks this can provide
+ a very rapid solution.
+ </p>
+ <p>
+ All of the navigation methods used in the
+ <a href="web_tester_documentation.html">WebTestCase</a>
+ are present in the <span class="new_code">SimpleBrowser</span> class, but
+ the assertions are replaced with simpler accessors.
+ Here is a full list of the page navigation methods...
+ <table><tbody>
+ <tr>
+<td><span class="new_code">addHeader($header)</span></td>
+<td>Adds a header to every fetch</td>
+</tr>
+ <tr>
+<td><span class="new_code">useProxy($proxy, $username, $password)</span></td>
+<td>Use this proxy from now on</td>
+</tr>
+ <tr>
+<td><span class="new_code">head($url, $parameters)</span></td>
+<td>Perform a HEAD request</td>
+</tr>
+ <tr>
+<td><span class="new_code">get($url, $parameters)</span></td>
+<td>Fetch a page with GET</td>
+</tr>
+ <tr>
+<td><span class="new_code">post($url, $parameters)</span></td>
+<td>Fetch a page with POST</td>
+</tr>
+ <tr>
+<td><span class="new_code">clickLink($label)</span></td>
+<td>Follows a link by label</td>
+</tr>
+ <tr>
+<td><span class="new_code">clickLinkById($id)</span></td>
+<td>Follows a link by attribute</td>
+</tr>
+ <tr>
+<td><span class="new_code">getUrl()</span></td>
+<td>Current URL of page or frame</td>
+</tr>
+ <tr>
+<td><span class="new_code">getTitle()</span></td>
+<td>Page title</td>
+</tr>
+ <tr>
+<td><span class="new_code">getContent()</span></td>
+<td>Raw page or frame</td>
+</tr>
+ <tr>
+<td><span class="new_code">getContentAsText()</span></td>
+<td>HTML removed except for alt text</td>
+</tr>
+ <tr>
+<td><span class="new_code">retry()</span></td>
+<td>Repeat the last request</td>
+</tr>
+ <tr>
+<td><span class="new_code">back()</span></td>
+<td>Use the browser back button</td>
+</tr>
+ <tr>
+<td><span class="new_code">forward()</span></td>
+<td>Use the browser forward button</td>
+</tr>
+ <tr>
+<td><span class="new_code">authenticate($username, $password)</span></td>
+<td>Retry page or frame after a 401 response</td>
+</tr>
+ <tr>
+<td><span class="new_code">restart($date)</span></td>
+<td>Restarts the browser for a new session</td>
+</tr>
+ <tr>
+<td><span class="new_code">ageCookies($interval)</span></td>
+<td>Ages the cookies by the specified time</td>
+</tr>
+ <tr>
+<td><span class="new_code">setCookie($name, $value)</span></td>
+<td>Sets an additional cookie</td>
+</tr>
+ <tr>
+<td><span class="new_code">getCookieValue($host, $path, $name)</span></td>
+<td>Reads the most specific cookie</td>
+</tr>
+ <tr>
+<td><span class="new_code">getCurrentCookieValue($name)</span></td>
+<td>Reads cookie for the current context</td>
+</tr>
+ </tbody></table>
+ The methods <span class="new_code">SimpleBrowser::useProxy()</span> and
+ <span class="new_code">SimpleBrowser::addHeader()</span> are special.
+ Once called they continue to apply to all subsequent fetches.
+ </p>
+ <p>
+ Navigating forms is similar to the
+ <a href="form_testing_documentation.html">WebTestCase form navigation</a>...
+ <table><tbody>
+ <tr>
+<td><span class="new_code">setField($name, $value)</span></td>
+<td>Sets all form fields with that name</td>
+</tr>
+ <tr>
+<td><span class="new_code">setFieldById($id, $value)</span></td>
+<td>Sets all form fields with that id</td>
+</tr>
+ <tr>
+<td><span class="new_code">getField($name)</span></td>
+<td>Accessor for a form element value</td>
+</tr>
+ <tr>
+<td><span class="new_code">getFieldById($id)</span></td>
+<td>Accessor for a form element value</td>
+</tr>
+ <tr>
+<td><span class="new_code">clickSubmit($label)</span></td>
+<td>Submits form by button label</td>
+</tr>
+ <tr>
+<td><span class="new_code">clickSubmitByName($name)</span></td>
+<td>Submits form by button attribute</td>
+</tr>
+ <tr>
+<td><span class="new_code">clickSubmitById($id)</span></td>
+<td>Submits form by button attribute</td>
+</tr>
+ <tr>
+<td><span class="new_code">clickImage($label, $x, $y)</span></td>
+<td>Clicks an input tag of type image by title or alt text</td>
+</tr>
+ <tr>
+<td><span class="new_code">clickImageByName($name, $x, $y)</span></td>
+<td>Clicks an input tag of type image by name</td>
+</tr>
+ <tr>
+<td><span class="new_code">clickImageById($id, $x, $y)</span></td>
+<td>Clicks an input tag of type image by ID attribute</td>
+</tr>
+ <tr>
+<td><span class="new_code">submitFormById($id)</span></td>
+<td>Submits by the form tag attribute</td>
+</tr>
+ </tbody></table>
+ At the moment there aren't any methods to list available forms
+ and fields.
+ This will probably be added to later versions of SimpleTest.
+ </p>
+ <p>
+ Within a page, individual frames can be selected.
+ If no selection is made then all the frames are merged together
+ in one large conceptual page.
+ The content of the current page will be a concatenation of all of the
+ frames in the order that they were specified in the "frameset"
+ tags.
+ <table><tbody>
+ <tr>
+<td><span class="new_code">getFrames()</span></td>
+<td>A dump of the current frame structure</td>
+</tr>
+ <tr>
+<td><span class="new_code">getFrameFocus()</span></td>
+<td>Current frame label or index</td>
+</tr>
+ <tr>
+<td><span class="new_code">setFrameFocusByIndex($choice)</span></td>
+<td>Select a frame numbered from 1</td>
+</tr>
+ <tr>
+<td><span class="new_code">setFrameFocus($name)</span></td>
+<td>Select frame by label</td>
+</tr>
+ <tr>
+<td><span class="new_code">clearFrameFocus()</span></td>
+<td>Treat all the frames as a single page</td>
+</tr>
+ </tbody></table>
+ When focused on a single frame, the content will come from
+ that frame only.
+ This includes links to click and forms to submit.
+ </p>
+
+ <p><a class="target" name="debug"><h2>What went wrong?</h2></a></p>
+ <p>
+ All of this functionality is great when we actually manage to fetch pages,
+ but that doesn't always happen.
+ To help figure out what went wrong, the browser has some methods to
+ aid in debugging...
+ <table><tbody>
+ <tr>
+<td><span class="new_code">setConnectionTimeout($timeout)</span></td>
+<td>Close the socket on overrun</td>
+</tr>
+ <tr>
+<td><span class="new_code">getRequest()</span></td>
+<td>Raw request header of page or frame</td>
+</tr>
+ <tr>
+<td><span class="new_code">getHeaders()</span></td>
+<td>Raw response header of page or frame</td>
+</tr>
+ <tr>
+<td><span class="new_code">getTransportError()</span></td>
+<td>Any socket level errors in the last fetch</td>
+</tr>
+ <tr>
+<td><span class="new_code">getResponseCode()</span></td>
+<td>HTTP response of page or frame</td>
+</tr>
+ <tr>
+<td><span class="new_code">getMimeType()</span></td>
+<td>Mime type of page or frame</td>
+</tr>
+ <tr>
+<td><span class="new_code">getAuthentication()</span></td>
+<td>Authentication type in 401 challenge header</td>
+</tr>
+ <tr>
+<td><span class="new_code">getRealm()</span></td>
+<td>Authentication realm in 401 challenge header</td>
+</tr>
+ <tr>
+<td><span class="new_code">setMaximumRedirects($max)</span></td>
+<td>Number of redirects before page is loaded anyway</td>
+</tr>
+ <tr>
+<td><span class="new_code">setMaximumNestedFrames($max)</span></td>
+<td>Protection against recursive framesets</td>
+</tr>
+ <tr>
+<td><span class="new_code">ignoreFrames()</span></td>
+<td>Disables frames support</td>
+</tr>
+ <tr>
+<td><span class="new_code">useFrames()</span></td>
+<td>Enables frames support</td>
+</tr>
+ <tr>
+<td><span class="new_code">ignoreCookies()</span></td>
+<td>Disables sending and receiving of cookies</td>
+</tr>
+ <tr>
+<td><span class="new_code">useCookies()</span></td>
+<td>Enables cookie support</td>
+</tr>
+ </tbody></table>
+ The methods <span class="new_code">SimpleBrowser::setConnectionTimeout()</span>
+ <span class="new_code">SimpleBrowser::setMaximumRedirects()</span>,
+ <span class="new_code">SimpleBrowser::setMaximumNestedFrames()</span>,
+ <span class="new_code">SimpleBrowser::ignoreFrames()</span>,
+ <span class="new_code">SimpleBrowser::useFrames()</span>,
+ <span class="new_code">SimpleBrowser::ignoreCookies()</span> and
+ <span class="new_code">SimpleBrowser::useCokies()</span> continue to apply
+ to every subsequent request.
+ The other methods are frames aware.
+ This means that if you have an individual frame that is not
+ loading, navigate to it using <span class="new_code">SimpleBrowser::setFrameFocus()</span>
+ and you can then use <span class="new_code">SimpleBrowser::getRequest()</span>, etc to
+ see what happened.
+ </p>
+
+ <p><a class="target" name="unit"><h2>Complex unit tests with multiple browsers</h2></a></p>
+ <p>
+ Anything that could be done in a
+ <a href="web_tester_documentation.html">WebTestCase</a> can
+ now be done in a <a href="unit_tester_documentation.html">UnitTestCase</a>.
+ This means that we can freely mix domain object testing with the
+ web interface...
+<pre>
+<strong>class TestOfRegistration extends UnitTestCase {
+ function testNewUserAddedToAuthenticator() {</strong>
+ $browser = &amp;new SimpleBrowser();
+ $browser-&gt;get('http://my-site.com/register.php');
+ $browser-&gt;setField('email', 'me@here');
+ $browser-&gt;setField('password', 'Secret');
+ $browser-&gt;click('Register');
+ <strong>
+ $authenticator = &amp;new Authenticator();
+ $member = &amp;$authenticator-&gt;findByEmail('me@here');
+ $this-&gt;assertEqual($member-&gt;getPassword(), 'Secret');
+ }
+}</strong>
+</pre>
+ While this may be a useful temporary expediency, I am not a fan
+ of this type of testing.
+ The testing has cut across application layers, make it twice as
+ likely it will need refactoring when the code changes.
+ </p>
+ <p>
+ A more useful case of where using the browser directly can be helpful
+ is where the <span class="new_code">WebTestCase</span> cannot cope.
+ An example is where two browsers are needed at the same time.
+ </p>
+ <p>
+ For example, say we want to disallow multiple simultaneous
+ usage of a site with the same username.
+ This test case will do the job...
+<pre>
+class TestOfSecurity extends UnitTestCase {
+ function testNoMultipleLoginsFromSameUser() {<strong>
+ $first = &amp;new SimpleBrowser();
+ $first-&gt;get('http://my-site.com/login.php');
+ $first-&gt;setField('name', 'Me');
+ $first-&gt;setField('password', 'Secret');
+ $first-&gt;click('Enter');
+ $this-&gt;assertEqual($first-&gt;getTitle(), 'Welcome');
+
+ $second = &amp;new SimpleBrowser();
+ $second-&gt;get('http://my-site.com/login.php');
+ $second-&gt;setField('name', 'Me');
+ $second-&gt;setField('password', 'Secret');
+ $second-&gt;click('Enter');
+ $this-&gt;assertEqual($second-&gt;getTitle(), 'Access Denied');</strong>
+ }
+}
+</pre>
+ You can also use the <span class="new_code">SimpleBrowser</span> class
+ directly when you want to write test cases using a different
+ test tool than SimpleTest.
+ </p>
+
+ </div>
+ References and related information...
+ <ul>
+<li>
+ SimpleTest project page on <a href="http://sourceforge.net/projects/simpletest/">SourceForge</a>.
+ </li>
+<li>
+ SimpleTest download page on <a href="http://www.lastcraft.com/simple_test.php">LastCraft</a>.
+ </li>
+<li>
+ The <a href="http://simpletest.org/api/">developer's API for SimpleTest</a>
+ gives full detail on the classes and assertions available.
+ </li>
+</ul>
+<div class="menu_back"><div class="menu">
+<a href="index.html">SimpleTest</a>
+ |
+ <a href="overview.html">Overview</a>
+ |
+ <a href="unit_test_documentation.html">Unit tester</a>
+ |
+ <a href="group_test_documentation.html">Group tests</a>
+ |
+ <a href="mock_objects_documentation.html">Mock objects</a>
+ |
+ <a href="partial_mocks_documentation.html">Partial mocks</a>
+ |
+ <a href="reporter_documentation.html">Reporting</a>
+ |
+ <a href="expectation_documentation.html">Expectations</a>
+ |
+ <a href="web_tester_documentation.html">Web tester</a>
+ |
+ <a href="form_testing_documentation.html">Testing forms</a>
+ |
+ <a href="authentication_documentation.html">Authentication</a>
+ |
+ <span class="chosen">Scriptable browser</span>
+</div></div>
+<div class="copyright">
+ Copyright<br>Marcus Baker 2006
+ </div>
+</body>
+</html>
diff --git a/site/vendors/simpletest/docs/en/docs.css b/site/vendors/simpletest/docs/en/docs.css
new file mode 100644
index 0000000..18368a0
--- /dev/null
+++ b/site/vendors/simpletest/docs/en/docs.css
@@ -0,0 +1,121 @@
+body {
+ padding-left: 3%;
+ padding-right: 3%;
+}
+h1, h2, h3 {
+ font-family: sans-serif;
+}
+h1 {
+ text-align: center;
+}
+pre {
+ font-family: "courier new", courier, typewriter, monospace;
+ font-size: 90%;
+ border: 1px solid;
+ border-color: #999966;
+ background-color: #ffffcc;
+ padding: 5px;
+ margin-left: 20px;
+ margin-right: 40px;
+}
+.code, .new_code, pre.new_code {
+ font-family: "courier new", courier, typewriter, monospace;
+ font-weight: bold;
+}
+div.copyright {
+ font-size: 80%;
+ color: gray;
+}
+div.copyright a {
+ margin-top: 1em;
+ color: gray;
+}
+ul.api {
+ border: 2px outset;
+ border-color: gray;
+ background-color: white;
+ margin: 5px;
+ margin-left: 5%;
+ margin-right: 5%;
+}
+ul.api li {
+ margin-top: 0.2em;
+ margin-bottom: 0.2em;
+ list-style: none;
+ text-indent: -3em;
+ padding-left: 1em;
+}
+div.demo {
+ border: 4px ridge;
+ border-color: gray;
+ padding: 10px;
+ margin: 5px;
+ margin-left: 20px;
+ margin-right: 40px;
+ background-color: white;
+}
+div.demo span.fail {
+ color: red;
+}
+div.demo span.pass {
+ color: green;
+}
+div.demo h1 {
+ font-size: 12pt;
+ text-align: left;
+ font-weight: bold;
+}
+div.menu {
+ text-align: center;
+}
+table {
+ border: 2px outset;
+ border-color: gray;
+ background-color: white;
+ margin: 5px;
+ margin-left: 5%;
+ margin-right: 5%;
+}
+td {
+ font-size: 90%;
+}
+.shell {
+ color: white;
+}
+pre.shell {
+ border: 4px ridge;
+ border-color: gray;
+ padding: 10px;
+ margin: 5px;
+ margin-left: 20px;
+ margin-right: 40px;
+ background-color: #000100;
+ color: #99ff99;
+ font-size: 90%;
+}
+pre.file {
+ color: black;
+ border: 1px solid;
+ border-color: black;
+ padding: 10px;
+ margin: 5px;
+ margin-left: 20px;
+ margin-right: 40px;
+ background-color: white;
+ font-size: 90%;
+}
+form.demo {
+ background-color: lightgray;
+ border: 4px outset;
+ border-color: lightgray;
+ padding: 10px;
+ margin-right: 40%;
+}
+dl, dd {
+ margin: 10px;
+ margin-left: 30px;
+}
+em {
+ font-weight: bold;
+ font-family: "courier new", courier, typewriter, monospace;
+}
diff --git a/site/vendors/simpletest/docs/en/expectation_documentation.html b/site/vendors/simpletest/docs/en/expectation_documentation.html
new file mode 100644
index 0000000..c3c959c
--- /dev/null
+++ b/site/vendors/simpletest/docs/en/expectation_documentation.html
@@ -0,0 +1,422 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>
+ Extending the SimpleTest unit tester with additional expectation classes
+ </title>
+<link rel="stylesheet" type="text/css" href="docs.css" title="Styles">
+</head>
+<body>
+<div class="menu_back"><div class="menu">
+<a href="index.html">SimpleTest</a>
+ |
+ <a href="overview.html">Overview</a>
+ |
+ <a href="unit_test_documentation.html">Unit tester</a>
+ |
+ <a href="group_test_documentation.html">Group tests</a>
+ |
+ <a href="mock_objects_documentation.html">Mock objects</a>
+ |
+ <a href="partial_mocks_documentation.html">Partial mocks</a>
+ |
+ <a href="reporter_documentation.html">Reporting</a>
+ |
+ <span class="chosen">Expectations</span>
+ |
+ <a href="web_tester_documentation.html">Web tester</a>
+ |
+ <a href="form_testing_documentation.html">Testing forms</a>
+ |
+ <a href="authentication_documentation.html">Authentication</a>
+ |
+ <a href="browser_documentation.html">Scriptable browser</a>
+</div></div>
+<h1>Expectation documentation</h1>
+ This page...
+ <ul>
+<li>
+ Using expectations for
+ <a href="#mock">more precise testing with mock objects</a>
+ </li>
+<li>
+ <a href="#behaviour">Changing mock object behaviour</a> with expectations
+ </li>
+<li>
+ <a href="#extending">Extending the expectations</a>
+ </li>
+<li>
+ Underneath SimpleTest <a href="#unit">uses expectation classes</a>
+ </li>
+</ul>
+<div class="content">
+ <p><a class="target" name="mock"><h2>More control over mock objects</h2></a></p>
+ <p>
+ The default behaviour of the
+ <a href="mock_objects_documentation.html">mock objects</a>
+ in
+ <a href="http://sourceforge.net/projects/simpletest/">SimpleTest</a>
+ is either an identical match on the argument or to allow any argument at all.
+ For almost all tests this is sufficient.
+ Sometimes, though, you want to weaken a test case.
+ </p>
+ <p>
+ One place where a test can be too tightly coupled is with
+ text matching.
+ Suppose we have a component that outputs a helpful error
+ message when something goes wrong.
+ You want to test that the correct error was sent, but the actual
+ text may be rather long.
+ If you test for the text exactly, then every time the exact wording
+ of the message changes, you will have to go back and edit the test suite.
+ </p>
+ <p>
+ For example, suppose we have a news service that has failed
+ to connect to its remote source.
+<pre>
+<strong>class NewsService {
+ ...
+ function publish(&amp;$writer) {
+ if (! $this-&gt;isConnected()) {
+ $writer-&gt;write('Cannot connect to news service "' .
+ $this-&gt;_name . '" at this time. ' .
+ 'Please try again later.');
+ }
+ ...
+ }
+}</strong>
+</pre>
+ Here it is sending its content to a
+ <span class="new_code">Writer</span> class.
+ We could test this behaviour with a
+ <span class="new_code">MockWriter</span> like so...
+<pre>
+class TestOfNewsService extends UnitTestCase {
+ ...
+ function testConnectionFailure() {<strong>
+ $writer = &amp;new MockWriter();
+ $writer-&gt;expectOnce('write', array(
+ 'Cannot connect to news service ' .
+ '"BBC News" at this time. ' .
+ 'Please try again later.'));
+
+ $service = &amp;new NewsService('BBC News');
+ $service-&gt;publish($writer);</strong>
+ }
+}
+</pre>
+ This is a good example of a brittle test.
+ If we decide to add additional instructions, such as
+ suggesting an alternative news source, we will break
+ our tests even though no underlying functionality
+ has been altered.
+ </p>
+ <p>
+ To get around this, we would like to do a regular expression
+ test rather than an exact match.
+ We can actually do this with...
+<pre>
+class TestOfNewsService extends UnitTestCase {
+ ...
+ function testConnectionFailure() {
+ $writer = &amp;new MockWriter();<strong>
+ $writer-&gt;expectOnce(
+ 'write',
+ array(new PatternExpectation('/cannot connect/i')));</strong>
+
+ $service = &amp;new NewsService('BBC News');
+ $service-&gt;publish($writer);
+ }
+}
+</pre>
+ Instead of passing in the expected parameter to the
+ <span class="new_code">MockWriter</span> we pass an
+ expectation class called
+ <span class="new_code">WantedPatternExpectation</span>.
+ The mock object is smart enough to recognise this as special
+ and to treat it differently.
+ Rather than simply comparing the incoming argument to this
+ object, it uses the expectation object itself to
+ perform the test.
+ </p>
+ <p>
+ The <span class="new_code">WantedPatternExpectation</span> takes
+ the regular expression to match in its constructor.
+ Whenever a comparison is made by the <span class="new_code">MockWriter</span>
+ against this expectation class, it will do a
+ <span class="new_code">preg_match()</span> with this pattern.
+ With our test case above, as long as "cannot connect"
+ appears in the text of the string, the mock will issue a pass
+ to the unit tester.
+ The rest of the text does not matter.
+ </p>
+ <p>
+ The possible expectation classes are...
+ <table><tbody>
+ <tr>
+<td><span class="new_code">AnythingExpectation</span></td>
+<td>Will always match</td>
+</tr>
+ <tr>
+<td><span class="new_code">EqualExpectation</span></td>
+<td>An equality, rather than the stronger identity comparison</td>
+</tr>
+ <tr>
+<td><span class="new_code">NotEqualExpectation</span></td>
+<td>An inequality comparison</td>
+</tr>
+ <tr>
+<td><span class="new_code">IndenticalExpectation</span></td>
+<td>The default mock object check which must match exactly</td>
+</tr>
+ <tr>
+<td><span class="new_code">NotIndenticalExpectation</span></td>
+<td>Inverts the mock object logic</td>
+</tr>
+ <tr>
+<td><span class="new_code">WithinMarginExpectation</span></td>
+<td>Compares a value to within a margin</td>
+</tr>
+ <tr>
+<td><span class="new_code">OutsideMarginExpectation</span></td>
+<td>Checks that a value is out side the margin</td>
+</tr>
+ <tr>
+<td><span class="new_code">PatternExpectation</span></td>
+<td>Uses a Perl Regex to match a string</td>
+</tr>
+ <tr>
+<td><span class="new_code">NoPatternExpectation</span></td>
+<td>Passes only if failing a Perl Regex</td>
+</tr>
+ <tr>
+<td><span class="new_code">IsAExpectation</span></td>
+<td>Checks the type or class name only</td>
+</tr>
+ <tr>
+<td><span class="new_code">NotAExpectation</span></td>
+<td>Opposite of the <span class="new_code">IsAExpectation</span>
+</td>
+</tr>
+ <tr>
+<td><span class="new_code">MethodExistsExpectation</span></td>
+<td>Checks a method is available on an object</td>
+</tr>
+ </tbody></table>
+ Most take the expected value in the constructor.
+ The exceptions are the pattern matchers, which take a regular expression,
+ and the <span class="new_code">IsAExpectation</span> and <span class="new_code">NotAExpectation</span> which takes a type
+ or class name as a string.
+ </p>
+ <p>
+ Some examples...
+ </p>
+ <p>
+<pre>
+$mock-&gt;expectOnce('method', array(new IdenticalExpectation(14)));
+</pre>
+ This is the same as <span class="new_code">$mock-&gt;expectOnce('method', array(14))</span>.
+<pre>
+$mock-&gt;expectOnce('method', array(new EqualExpectation(14)));
+</pre>
+ This is different from the previous version in that the string
+ <span class="new_code">"14"</span> as a parameter will also pass.
+ Sometimes the additional type checks of SimpleTest are too restrictive.
+<pre>
+$mock-&gt;expectOnce('method', array(new AnythingExpectation(14)));
+</pre>
+ This is the same as <span class="new_code">$mock-&gt;expectOnce('method', array('*'))</span>.
+<pre>
+$mock-&gt;expectOnce('method', array(new IdenticalExpectation('*')));
+</pre>
+ This is handy if you want to assert a literal <span class="new_code">"*"</span>.
+<pre>
+new NotIdenticalExpectation(14)
+</pre>
+ This matches on anything other than integer 14.
+ Even the string <span class="new_code">"14"</span> would pass.
+<pre>
+new WithinMarginExpectation(14.0, 0.001)
+</pre>
+ This will accept any value from 13.999 to 14.001 inclusive.
+ </p>
+
+ <p><a class="target" name="behaviour"><h2>Using expectations to control stubs</h2></a></p>
+ <p>
+ The expectation classes can be used not just for sending assertions
+ from mock objects, but also for selecting behaviour for the
+ <a href="mock_objects_documentation.html">mock objects</a>.
+ Anywhere a list of arguments is given, a list of expectation objects
+ can be inserted instead.
+ </p>
+ <p>
+ Suppose we want a mock authorisation server to simulate a successful login,
+ but only if it receives a valid session object.
+ We can do this as follows...
+<pre>
+Mock::generate('Authorisation');
+<strong>
+$authorisation = new MockAuthorisation();
+$authorisation-&gt;setReturnValue(
+ 'isAllowed',
+ true,
+ array(new IsAExpectation('Session', 'Must be a session')));
+$authorisation-&gt;setReturnValue('isAllowed', false);</strong>
+</pre>
+ We have set the default mock behaviour to return false when
+ <span class="new_code">isAllowed</span> is called.
+ When we call the method with a single parameter that
+ is a <span class="new_code">Session</span> object, it will return true.
+ We have also added a second parameter as a message.
+ This will be displayed as part of the mock object
+ failure message if this expectation is the cause of
+ a failure.
+ </p>
+ <p>
+ This kind of sophistication is rarely useful, but is included for
+ completeness.
+ </p>
+
+ <p><a class="target" name="extending"><h2>Creating your own expectations</h2></a></p>
+ <p>
+ The expectation classes have a very simple structure.
+ So simple that it is easy to create your own versions for
+ commonly used test logic.
+ </p>
+ <p>
+ As an example here is the creation of a class to test for
+ valid IP addresses.
+ In order to work correctly with the stubs and mocks the new
+ expectation class should extend
+ <span class="new_code">SimpleExpectation</span>...
+<pre>
+<strong>class ValidIp extends SimpleExpectation {
+
+ function test($ip) {
+ return (ip2long($ip) != -1);
+ }
+
+ function testMessage($ip) {
+ return "Address [$ip] should be a valid IP address";
+ }
+}</strong>
+</pre>
+ There are only two methods to implement.
+ The <span class="new_code">test()</span> method should
+ evaluate to true if the expectation is to pass, and
+ false otherwise.
+ The <span class="new_code">testMessage()</span> method
+ should simply return some helpful text explaining the test
+ that was carried out.
+ </p>
+ <p>
+ This class can now be used in place of the earlier expectation
+ classes.
+ </p>
+
+ <p><a class="target" name="unit"><h2>Under the bonnet of the unit tester</h2></a></p>
+ <p>
+ The <a href="http://sourceforge.net/projects/simpletest/">SimpleTest unit testing framework</a>
+ also uses the expectation classes internally for the
+ <a href="unit_test_documentation.html">UnitTestCase class</a>.
+ We can also take advantage of these mechanisms to reuse our
+ homebrew expectation classes within the test suites directly.
+ </p>
+ <p>
+ The most crude way of doing this is to use the
+ <span class="new_code">SimpleTest::assert()</span> method to
+ test against it directly...
+<pre>
+<strong>class TestOfNetworking extends UnitTestCase {
+ ...
+ function testGetValidIp() {
+ $server = &amp;new Server();
+ $this-&gt;assert(
+ new ValidIp(),
+ $server-&gt;getIp(),
+ 'Server IP address-&gt;%s');
+ }
+}</strong>
+</pre>
+ This is a little untidy compared with our usual
+ <span class="new_code">assert...()</span> syntax.
+ </p>
+ <p>
+ For such a simple case we would normally create a
+ separate assertion method on our test case rather
+ than bother using the expectation class.
+ If we pretend that our expectation is a little more
+ complicated for a moment, so that we want to reuse it,
+ we get...
+<pre>
+class TestOfNetworking extends UnitTestCase {
+ ...<strong>
+ function assertValidIp($ip, $message = '%s') {
+ $this-&gt;assert(new ValidIp(), $ip, $message);
+ }</strong>
+
+ function testGetValidIp() {
+ $server = &amp;new Server();<strong>
+ $this-&gt;assertValidIp(
+ $server-&gt;getIp(),
+ 'Server IP address-&gt;%s');</strong>
+ }
+}
+</pre>
+ It is unlikely we would ever need this degree of control
+ over the testing machinery.
+ It is rare to need the expectations for more than pattern
+ matching.
+ Also, complex expectation classes could make the tests
+ harder to read and debug.
+ These mechanisms are really of most use to authors of systems
+ that will extend the test framework to create their own tool set.
+ </p>
+
+ </div>
+ References and related information...
+ <ul>
+<li>
+ SimpleTest project page on <a href="http://sourceforge.net/projects/simpletest/">SourceForge</a>.
+ </li>
+<li>
+ SimpleTest download page on <a href="http://www.lastcraft.com/simple_test.php">LastCraft</a>.
+ </li>
+<li>
+ The expectations mimic the constraints in <a href="http://www.jmock.org/">JMock</a>.
+ </li>
+<li>
+ <a href="http://simpletest.org/api/">Full API for SimpleTest</a>
+ from the PHPDoc.
+ </li>
+</ul>
+<div class="menu_back"><div class="menu">
+<a href="index.html">SimpleTest</a>
+ |
+ <a href="overview.html">Overview</a>
+ |
+ <a href="unit_test_documentation.html">Unit tester</a>
+ |
+ <a href="group_test_documentation.html">Group tests</a>
+ |
+ <a href="mock_objects_documentation.html">Mock objects</a>
+ |
+ <a href="partial_mocks_documentation.html">Partial mocks</a>
+ |
+ <a href="reporter_documentation.html">Reporting</a>
+ |
+ <span class="chosen">Expectations</span>
+ |
+ <a href="web_tester_documentation.html">Web tester</a>
+ |
+ <a href="form_testing_documentation.html">Testing forms</a>
+ |
+ <a href="authentication_documentation.html">Authentication</a>
+ |
+ <a href="browser_documentation.html">Scriptable browser</a>
+</div></div>
+<div class="copyright">
+ Copyright<br>Marcus Baker 2006
+ </div>
+</body>
+</html>
diff --git a/site/vendors/simpletest/docs/en/form_testing_documentation.html b/site/vendors/simpletest/docs/en/form_testing_documentation.html
new file mode 100644
index 0000000..fe0fccc
--- /dev/null
+++ b/site/vendors/simpletest/docs/en/form_testing_documentation.html
@@ -0,0 +1,342 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Simple Test documentation for testing HTML forms</title>
+<link rel="stylesheet" type="text/css" href="docs.css" title="Styles">
+</head>
+<body>
+<div class="menu_back"><div class="menu">
+<a href="index.html">SimpleTest</a>
+ |
+ <a href="overview.html">Overview</a>
+ |
+ <a href="unit_test_documentation.html">Unit tester</a>
+ |
+ <a href="group_test_documentation.html">Group tests</a>
+ |
+ <a href="mock_objects_documentation.html">Mock objects</a>
+ |
+ <a href="partial_mocks_documentation.html">Partial mocks</a>
+ |
+ <a href="reporter_documentation.html">Reporting</a>
+ |
+ <a href="expectation_documentation.html">Expectations</a>
+ |
+ <a href="web_tester_documentation.html">Web tester</a>
+ |
+ <span class="chosen">Testing forms</span>
+ |
+ <a href="authentication_documentation.html">Authentication</a>
+ |
+ <a href="browser_documentation.html">Scriptable browser</a>
+</div></div>
+<h1>Form testing documentation</h1>
+ This page...
+ <ul>
+<li>
+ Changing form values and successfully
+ <a href="#submit">Submitting a simple form</a>
+ </li>
+<li>
+ Handling <a href="#multiple">widgets with multiple values</a>
+ by setting lists.
+ </li>
+<li>
+ Bypassing javascript to <a href="#hidden-field">set a hidden field</a>.
+ </li>
+<li>
+ <a href="#raw">Raw posting</a> when you don't have a button
+ to click.
+ </li>
+</ul>
+<div class="content">
+ <p><a class="target" name="submit"><h2>Submitting a simple form</h2></a></p>
+ <p>
+ When a page is fetched by the <span class="new_code">WebTestCase</span>
+ using <span class="new_code">get()</span> or
+ <span class="new_code">post()</span> the page content is
+ automatically parsed.
+ This results in any form controls that are inside &lt;form&gt; tags
+ being available from within the test case.
+ For example, if we have this snippet of HTML...
+<pre>
+&lt;form&gt;
+ &lt;input type="text" name="a" value="A default" /&gt;
+ &lt;input type="submit" value="Go" /&gt;
+&lt;/form&gt;
+</pre>
+ Which looks like this...
+ </p>
+ <p>
+ <form class="demo">
+ <input type="text" name="a" value="A default">
+ <input type="submit" value="Go">
+ </form>
+ </p>
+ <p>
+ We can navigate to this code, via the
+ <a href="http://www.lastcraft.com/form_testing_documentation.php">LastCraft</a>
+ site, with the following test...
+<pre>
+class SimpleFormTests extends WebTestCase {
+ <strong>
+ function testDefaultValue() {
+ $this-&gt;get('http://www.lastcraft.com/form_testing_documentation.php');
+ $this-&gt;assertField('a', 'A default');
+ }</strong>
+}
+</pre>
+ Immediately after loading the page all of the HTML controls are set at
+ their default values just as they would appear in the web browser.
+ The assertion tests that a HTML widget exists in the page with the
+ name "a" and that it is currently set to the value
+ "A default".
+ As usual, we could use a pattern expectation instead if a fixed
+ string.
+ </p>
+ <p>
+ We could submit the form straight away, but first we'll change
+ the value of the text field and only then submit it...
+<pre>
+class SimpleFormTests extends WebTestCase {
+
+ function testDefaultValue() {
+ $this-&gt;get('http://www.my-site.com/');
+ $this-&gt;assertField('a', 'A default');<strong>
+ $this-&gt;setField('a', 'New value');
+ $this-&gt;click('Go');</strong>
+ }
+}
+</pre>
+ Because we didn't specify a method attribute on the form tag, and
+ didn't specify an action either, the test case will follow
+ the usual browser behaviour of submitting the form data as a <em>GET</em>
+ request back to the same location.
+ SimpleTest tries to emulate typical browser behaviour as much as possible,
+ rather than attempting to catch missing attributes on tags.
+ This is because the target of the testing framework is the PHP application
+ logic, not syntax or other errors in the HTML code.
+ For HTML errors, other tools such as
+ <a href="http://www.w3.org/People/Raggett/tidy/">HTMLTidy</a> should be used.
+ </p>
+ <p>
+ If a field is not present in any form, or if an option is unavailable,
+ then <span class="new_code">WebTestCase::setField()</span> will return
+ <span class="new_code">false</span>.
+ For example, suppose we wish to verify that a "Superuser"
+ option is not present in this form...
+<pre>
+&lt;strong&gt;Select type of user to add:&lt;/strong&gt;
+&lt;select name="type"&gt;
+ &lt;option&gt;Subscriber&lt;/option&gt;
+ &lt;option&gt;Author&lt;/option&gt;
+ &lt;option&gt;Administrator&lt;/option&gt;
+&lt;/select&gt;
+</pre>
+ Which looks like...
+ </p>
+ <p>
+ <form class="demo">
+ <strong>Select type of user to add:</strong>
+ <select name="type">
+ <option>Subscriber</option>
+ <option>Author</option>
+ <option>Administrator</option>
+ </select>
+ </form>
+ </p>
+ <p>
+ The following test will confirm it...
+<pre>
+class SimpleFormTests extends WebTestCase {
+ ...
+ function testNoSuperuserChoiceAvailable() {<strong>
+ $this-&gt;get('http://www.lastcraft.com/form_testing_documentation.php');
+ $this-&gt;assertFalse($this-&gt;setField('type', 'Superuser'));</strong>
+ }
+}
+</pre>
+ The selection will not be changed on a failure to set
+ a widget value.
+ </p>
+ <p>
+ Here is the full list of widgets currently supported...
+ <ul>
+ <li>Text fields, including hidden and password fields.</li>
+ <li>Submit buttons including the button tag, although not yet reset buttons</li>
+ <li>Text area. This includes text wrapping behaviour.</li>
+ <li>Checkboxes, including multiple checkboxes in the same form.</li>
+ <li>Drop down selections, including multiple selects.</li>
+ <li>Radio buttons.</li>
+ <li>Images.</li>
+ </ul>
+ </p>
+ <p>
+ The browser emulation offered by SimpleTest mimics
+ the actions which can be perform by a user on a
+ standard HTML page. Javascript is not supported, and
+ it's unlikely that support will be added any time
+ soon.
+ </p>
+ <p>
+ Of particular note is that the Javascript idiom of
+ passing form results by setting a hidden field cannot
+ be performed using the normal SimpleTest
+ commands. See below for a way to test such forms.
+ </p>
+
+ <p><a class="target" name="multiple"><h2>Fields with multiple values</h2></a></p>
+ <p>
+ SimpleTest can cope with two types of multivalue controls: Multiple
+ selection drop downs, and multiple checkboxes with the same name
+ within a form.
+ The multivalue nature of these means that setting and testing
+ are slightly different.
+ Using checkboxes as an example...
+<pre>
+&lt;form class="demo"&gt;
+ &lt;strong&gt;Create privileges allowed:&lt;/strong&gt;
+ &lt;input type="checkbox" name="crud" value="c" checked&gt;&lt;br&gt;
+ &lt;strong&gt;Retrieve privileges allowed:&lt;/strong&gt;
+ &lt;input type="checkbox" name="crud" value="r" checked&gt;&lt;br&gt;
+ &lt;strong&gt;Update privileges allowed:&lt;/strong&gt;
+ &lt;input type="checkbox" name="crud" value="u" checked&gt;&lt;br&gt;
+ &lt;strong&gt;Destroy privileges allowed:&lt;/strong&gt;
+ &lt;input type="checkbox" name="crud" value="d" checked&gt;&lt;br&gt;
+ &lt;input type="submit" value="Enable Privileges"&gt;
+&lt;/form&gt;
+</pre>
+ Which renders as...
+ </p>
+ <p>
+ <form class="demo">
+ <strong>Create privileges allowed:</strong>
+ <input type="checkbox" name="crud" value="c" checked><br>
+ <strong>Retrieve privileges allowed:</strong>
+ <input type="checkbox" name="crud" value="r" checked><br>
+ <strong>Update privileges allowed:</strong>
+ <input type="checkbox" name="crud" value="u" checked><br>
+ <strong>Destroy privileges allowed:</strong>
+ <input type="checkbox" name="crud" value="d" checked><br>
+ <input type="submit" value="Enable Privileges">
+ </form>
+ </p>
+ <p>
+ If we wish to disable all but the retrieval privileges and
+ submit this information we can do it like this...
+<pre>
+class SimpleFormTests extends WebTestCase {
+ ...<strong>
+ function testDisableNastyPrivileges() {
+ $this-&gt;get('http://www.lastcraft.com/form_testing_documentation.php');
+ $this-&gt;assertField('crud', array('c', 'r', 'u', 'd'));
+ $this-&gt;setField('crud', array('r'));
+ $this-&gt;click('Enable Privileges');
+ }</strong>
+}
+</pre>
+ Instead of setting the field to a single value, we give it a list
+ of values.
+ We do the same when testing expected values.
+ We can then write other test code to confirm the effect of this, perhaps
+ by logging in as that user and attempting an update.
+ </p>
+
+ <p><a class="target" name="hidden-field"><h2>Forms which use javascript to set a hidden field</h2></a></p>
+ <p>
+ If you want to test a form which relies on javascript to set a hidden
+ field, you can't just call setField().
+ The following code will <em>not</em> work:
+<pre>
+class SimpleFormTests extends WebTestCase {
+ function testMyJavascriptForm() {
+ <strong>// This does *not* work</strong>
+ $this-&gt;setField('a_hidden_field', '123');
+ $this-&gt;clickSubmit('OK');
+ }
+}
+</pre>
+ Instead, you need to pass the additional form parameters to the
+ clickSubmit() method:
+<pre>
+class SimpleFormTests extends WebTestCase {
+ function testMyJavascriptForm() {
+ // Pass the hidden field value as an additional POST variable
+ <strong>$this-&gt;clickSubmit('OK', array('a_hidden_field'=&gt;'123'));</strong>
+ }
+
+}
+</pre>
+ </p>
+ <p>
+ Bear in mind that in doing this you're effectively stubbing out a
+ part of your software (the javascript code in the form), and
+ perhaps you might be better off using something like
+ <a href="http://selenium.openqa.org/">Selenium</a> to ensure a complete
+ acceptance test.
+ </p>
+
+ <p><a class="target" name="raw"><h2>Raw posting</h2></a></p>
+ <p>
+ If you want to test a form handler, but have not yet written
+ or do not have access to the form itself, you can create a
+ form submission by hand.
+<pre>
+class SimpleFormTests extends WebTestCase {
+ ...<strong>
+ function testAttemptedHack() {
+ $this-&gt;post(
+ 'http://www.my-site.com/add_user.php',
+ array('type' =&gt; 'superuser'));
+ $this-&gt;assertNoText('user created');
+ }</strong>
+}
+</pre>
+ By adding data to the <span class="new_code">WebTestCase::post()</span>
+ method, we are attempting to fetch the page as a form submission.
+ </p>
+
+ </div>
+ References and related information...
+ <ul>
+<li>
+ SimpleTest project page on <a href="http://sourceforge.net/projects/simpletest/">SourceForge</a>.
+ </li>
+<li>
+ SimpleTest download page on <a href="http://www.lastcraft.com/simple_test.php">LastCraft</a>.
+ </li>
+<li>
+ The <a href="http://simpletest.org/api/">developer's API for SimpleTest</a>
+ gives full detail on the classes and assertions available.
+ </li>
+</ul>
+<div class="menu_back"><div class="menu">
+<a href="index.html">SimpleTest</a>
+ |
+ <a href="overview.html">Overview</a>
+ |
+ <a href="unit_test_documentation.html">Unit tester</a>
+ |
+ <a href="group_test_documentation.html">Group tests</a>
+ |
+ <a href="mock_objects_documentation.html">Mock objects</a>
+ |
+ <a href="partial_mocks_documentation.html">Partial mocks</a>
+ |
+ <a href="reporter_documentation.html">Reporting</a>
+ |
+ <a href="expectation_documentation.html">Expectations</a>
+ |
+ <a href="web_tester_documentation.html">Web tester</a>
+ |
+ <span class="chosen">Testing forms</span>
+ |
+ <a href="authentication_documentation.html">Authentication</a>
+ |
+ <a href="browser_documentation.html">Scriptable browser</a>
+</div></div>
+<div class="copyright">
+ Copyright<br>Marcus Baker 2006
+ </div>
+</body>
+</html>
diff --git a/site/vendors/simpletest/docs/en/group_test_documentation.html b/site/vendors/simpletest/docs/en/group_test_documentation.html
new file mode 100644
index 0000000..a0c7884
--- /dev/null
+++ b/site/vendors/simpletest/docs/en/group_test_documentation.html
@@ -0,0 +1,386 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>SimpleTest for PHP test suites</title>
+<link rel="stylesheet" type="text/css" href="docs.css" title="Styles">
+</head>
+<body>
+<div class="menu_back"><div class="menu">
+<a href="index.html">SimpleTest</a>
+ |
+ <a href="overview.html">Overview</a>
+ |
+ <a href="unit_test_documentation.html">Unit tester</a>
+ |
+ <span class="chosen">Group tests</span>
+ |
+ <a href="mock_objects_documentation.html">Mock objects</a>
+ |
+ <a href="partial_mocks_documentation.html">Partial mocks</a>
+ |
+ <a href="reporter_documentation.html">Reporting</a>
+ |
+ <a href="expectation_documentation.html">Expectations</a>
+ |
+ <a href="web_tester_documentation.html">Web tester</a>
+ |
+ <a href="form_testing_documentation.html">Testing forms</a>
+ |
+ <a href="authentication_documentation.html">Authentication</a>
+ |
+ <a href="browser_documentation.html">Scriptable browser</a>
+</div></div>
+<h1>Test suite documentation</h1>
+ This page...
+ <ul>
+<li>
+ Different ways to <a href="#group">group tests</a> together.
+ </li>
+<li>
+ Combining group tests into <a href="#higher">larger groups</a>.
+ </li>
+<li>
+ Integrating <a href="#legacy">legacy test cases</a> from other
+ types of PHPUnit.
+ </li>
+</ul>
+<div class="content">
+ <p><a class="target" name="group"><h2>Grouping tests into suites</h2></a></p>
+ <p>
+ To run test cases as part of a group, the test cases should really
+ be placed in files without the runner code...
+<pre>
+<strong>&lt;?php
+ require_once('../classes/io.php');
+
+ class FileTester extends UnitTestCase {
+ ...
+ }
+
+ class SocketTester extends UnitTestCase {
+ ...
+ }
+?&gt;</strong>
+</pre>
+ As many cases as needed can appear in a single file.
+ They should include any code they need, such as the library
+ being tested, but none of the simple test libraries.
+ </p>
+ <p>
+ If you have extended any test cases, you can include them
+ as well. In PHP 4...
+<pre>
+&lt;?php
+ require_once('../classes/io.php');
+<strong>
+ class MyFileTestCase extends UnitTestCase {
+ ...
+ }
+ SimpleTest::ignore('MyFileTestCase');</strong>
+
+ class FileTester extends MyFileTestCase { ... }
+
+ class SocketTester extends UnitTestCase { ... }
+?&gt;
+</pre>
+ The <span class="new_code">FileTester</span> class does
+ not contain any actual tests, but is a base class for other
+ test cases.
+ For this reason we use the
+ <span class="new_code">SimpleTestOptions::ignore()</span> directive
+ to tell the upcoming group test to ignore it.
+ This directive can appear anywhere in the file and works
+ when a whole file of test cases is loaded (see below).
+ </p>
+ <p>
+ If you are using PHP 5, you do not need this special directive at all.
+ Simply mark any test cases that should not be run as abstract...
+<pre>
+<strong>abstract</strong> class MyFileTestCase extends UnitTestCase {
+ ...
+}
+
+class FileTester extends MyFileTestCase { ... }
+
+class SocketTester extends UnitTestCase { ... }
+</pre>
+ </p>
+ <p>
+ We will call this sample <em>file_test.php</em>.
+ Next we create a group test file, called say <em>my_group_test.php</em>.
+ You will think of a better name I am sure.
+ </p>
+ <p>
+ We will add the test file using a safe method...
+<pre>
+&lt;?php
+ require_once('simpletest/unit_tester.php');
+ require_once('simpletest/reporter.php');<strong>
+ require_once('file_test.php');
+
+ $test = &amp;new TestSuite('All file tests');
+ $test-&gt;addTestCase(new FileTestCase());
+ $test-&gt;run(new HtmlReporter());</strong>
+?&gt;
+</pre>
+ This instantiates the test case before the test suite is
+ run.
+ This could get a little expensive with a large number of test
+ cases, and can be surprising behaviour.
+ </p>
+ <p>
+ The main problem is that for every test case
+ that we add we will have
+ to <span class="new_code">require_once()</span> the test code
+ file and manually instantiate each and every test case.
+ </p>
+ <p>
+ We can save a lot of typing with...
+<pre>
+&lt;?php
+ require_once('simpletest/unit_tester.php');
+ require_once('simpletest/reporter.php');
+
+ $test = &amp;new TestSuite('All file tests');<strong>
+ $test-&gt;addTestFile('file_test.php');</strong>
+ $test-&gt;run(new HtmlReporter());
+?&amp;gt;
+</pre>
+ What happens here is that the <span class="new_code">TestSuite</span>
+ class has done the <span class="new_code">require_once()</span>
+ for us.
+ It then checks to see if any new test case classes
+ have been created by the new file and automatically adds
+ them to the group test.
+ Now all we have to do is add each new file.
+ </p>
+ <p>
+ No only that, but you can guarantee that the constructor is run
+ just before the first test method and, in PHP 5, the destructor
+ is run just after the last test method.
+ </p>
+ <p>
+ There are two things that could go wrong and which require care...
+ <ol>
+ <li>
+ The file could already have been parsed by PHP, and so no
+ new classes will have been added. You should make
+ sure that the test cases are only included in this file
+ and no others (Note : with the new <cite>autorun</cite>
+ functionnality, this problem has now been solved).
+ </li>
+ <li>
+ New test case extension classes that get included will be
+ placed in the group test and run also.
+ You will need to add a <span class="new_code">SimpleTestOptions::ignore()</span>
+ directive for these classes, or make sure that they are included
+ before the <span class="new_code">TestSuite::addTestFile()</span>
+ line, or make sure that they are abstract classes.
+ </li>
+ </ol>
+ </p>
+
+ <p><a class="target" name="higher"><h2>Composite suites</h2></a></p>
+ <p>
+ The above method places all of the test cases into one large group.
+ For larger projects though this may not be flexible enough; you
+ may want to group the tests in all sorts of ways.
+ </p>
+ <p>
+ To get a more flexible group test we can subclass
+ <span class="new_code">TestSuite</span> and then instantiate it as needed...
+<pre>
+&lt;?php
+ require_once('simpletest/unit_tester.php');
+ require_once('simpletest/reporter.php');
+ <strong>
+ class FileTestSuite extends TestSuite {
+ function FileTestSuite() {
+ $this-&gt;TestSuite('All file tests');
+ $this-&gt;addTestFile('file_test.php');
+ }
+ }</strong>
+?&gt;
+</pre>
+ This effectively names the test in the constructor and then
+ adds our test cases and a single group below.
+ Of course we can add more than one group at this point.
+ We can now invoke the tests from a separate runner file...
+<pre>
+&lt;?php
+ require_once('file_test_suite.php');
+ <strong>
+ $test = &amp;new FileTestSuite();
+ $test-&gt;run(new HtmlReporter());</strong>
+?&gt;
+</pre>
+ ...or we can group them into even larger group tests.
+ We can even mix groups and test cases freely as long as
+ we are careful about double includes...
+<pre>
+&lt;?php
+ <strong>
+ $test = &amp;new BigTestSuite('Big group');
+ $test-&gt;addTestFile('file_test_suite.php');
+ $test-&gt;addTestFile('some_test_case.php');</strong>
+ $test-&gt;run(new HtmlReporter());
+?&gt;
+</pre>
+ In the event of a double include, ony the first instance
+ of the test case will be run.
+ </p>
+ <p>
+ If we still wish to run the original group test, and we
+ don't want all of these little runner files, we can
+ put the test runner code around guard bars when we create
+ each group.
+<pre>
+&lt;?php
+ class FileTestSuite extends TestSuite {
+ function FileTestSuite() {
+ $this-&gt;TestSuite('All file tests');
+ $test-&gt;addTestFile('file_test.php');
+ }
+ }
+ <strong>
+ if (! defined('RUNNER')) {
+ define('RUNNER', true);</strong>
+ $test = &amp;new FileTestSuite();
+ $test-&gt;run(new HtmlReporter());
+ }
+?&gt;
+</pre>
+ This approach requires the guard to be set when including
+ the group test file, but this is still less hassle than
+ lots of separate runner files.
+ You include the same guard on the top level tests to make sure
+ that <span class="new_code">run()</span> will run once only
+ from the top level script that has been invoked.
+<pre>
+&lt;?php<strong>
+ define('RUNNER', true);</strong>
+ require_once('file_test_suite.php');
+
+ $test = &amp;new BigTestSuite('Big group');
+ $test-&gt;addTestCase(new FileTestSuite());
+ $test-&gt;addTestCase(...);
+ $test-&gt;run(new HtmlReporter());
+?&gt;
+</pre>
+ As with the normal test cases, a <span class="new_code">TestSuite</span> can
+ be loaded with the <span class="new_code">TestSuite::addTestFile()</span> method.
+<pre>
+&lt;?php
+ define('RUNNER', true);
+
+ $test = &amp;new BigTestSuite('Big group');<strong>
+ $test-&gt;addTestFile('file_test_suite.php');
+ $test-&gt;addTestFile(...);</strong>
+ $test-&gt;run(new HtmlReporter());
+?&gt;
+</pre>
+ </p>
+
+ <p><a class="target" name="legacy"><h2>Integrating legacy test cases</h2></a></p>
+ <p>
+ If you already have unit tests for your code or are extending external
+ classes that have tests, it is unlikely that all of the test cases
+ are in SimpleTest format.
+ Fortunately it is possible to incorporate test cases from other
+ unit testers directly into SimpleTest group tests.
+ </p>
+ <p>
+ Say we have the following
+ <a href="http://sourceforge.net/projects/phpunit">PhpUnit</a>
+ test case in the file <em>config_test.php</em>...
+<pre>
+<strong>class ConfigFileTest extends TestCase {
+ function ConfigFileTest() {
+ $this-&gt;TestCase('Config file test');
+ }
+
+ function testContents() {
+ $config = new ConfigFile('test.conf');
+ $this-&gt;assertRegexp('/me/', $config-&gt;getValue('username'));
+ }
+}</strong>
+</pre>
+ The group test can recognise this as long as we include
+ the appropriate adapter class before we add the test
+ file...
+<pre>
+&lt;?php
+ require_once('simpletest/unit_tester.php');
+ require_once('simpletest/reporter.php');<strong>
+ require_once('simpletest/adapters/phpunit_test_case.php');</strong>
+
+ $test = &amp;new TestSuite('All file tests');<strong>
+ $test-&gt;addTestFile('config_test.php');</strong>
+ $test-&gt;run(new HtmlReporter());
+?&gt;
+</pre>
+ There are only two adapters, the other is for the
+ <a href="http://pear.php.net/manual/en/package.php.phpunit.php">PEAR</a>
+ 1.0 unit tester...
+<pre>
+&lt;?php
+ require_once('simpletest/unit_tester.php');
+ require_once('simpletest/reporter.php');<strong>
+ require_once('simpletest/adapters/pear_test_case.php');</strong>
+
+ $test = &amp;new TestSuite('All file tests');<strong>
+ $test-&gt;addTestFile('some_pear_test_cases.php');</strong>
+ $test-&gt;run(new HtmlReporter());
+?&gt;
+</pre>
+ The PEAR test cases can be freely mixed with SimpleTest
+ ones even in the same test file,
+ but you cannot use SimpleTest assertions in the legacy
+ test case versions.
+ This is done as a check that you are not accidently making
+ your test cases completely dependent on SimpleTest.
+ You may want to do a PEAR release of your library for example,
+ which would mean shipping it with valid PEAR::PhpUnit test
+ cases.
+ </p>
+
+ </div>
+ References and related information...
+ <ul>
+<li>
+ SimpleTest project page on <a href="http://sourceforge.net/projects/simpletest/">SourceForge</a>.
+ </li>
+<li>
+ SimpleTest download page on <a href="http://www.lastcraft.com/simple_test.php">LastCraft</a>.
+ </li>
+</ul>
+<div class="menu_back"><div class="menu">
+<a href="index.html">SimpleTest</a>
+ |
+ <a href="overview.html">Overview</a>
+ |
+ <a href="unit_test_documentation.html">Unit tester</a>
+ |
+ <span class="chosen">Group tests</span>
+ |
+ <a href="mock_objects_documentation.html">Mock objects</a>
+ |
+ <a href="partial_mocks_documentation.html">Partial mocks</a>
+ |
+ <a href="reporter_documentation.html">Reporting</a>
+ |
+ <a href="expectation_documentation.html">Expectations</a>
+ |
+ <a href="web_tester_documentation.html">Web tester</a>
+ |
+ <a href="form_testing_documentation.html">Testing forms</a>
+ |
+ <a href="authentication_documentation.html">Authentication</a>
+ |
+ <a href="browser_documentation.html">Scriptable browser</a>
+</div></div>
+<div class="copyright">
+ Copyright<br>Marcus Baker 2006
+ </div>
+</body>
+</html>
diff --git a/site/vendors/simpletest/docs/en/index.html b/site/vendors/simpletest/docs/en/index.html
new file mode 100644
index 0000000..03b6c5c
--- /dev/null
+++ b/site/vendors/simpletest/docs/en/index.html
@@ -0,0 +1,538 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>
+ Download the Simple Test testing framework -
+ Unit tests and mock objects for PHP
+ </title>
+<link rel="stylesheet" type="text/css" href="docs.css" title="Styles">
+</head>
+<body>
+<div class="menu_back"><div class="menu">
+<span class="chosen">SimpleTest</span>
+ |
+ <a href="overview.html">Overview</a>
+ |
+ <a href="unit_test_documentation.html">Unit tester</a>
+ |
+ <a href="group_test_documentation.html">Group tests</a>
+ |
+ <a href="mock_objects_documentation.html">Mock objects</a>
+ |
+ <a href="partial_mocks_documentation.html">Partial mocks</a>
+ |
+ <a href="reporter_documentation.html">Reporting</a>
+ |
+ <a href="expectation_documentation.html">Expectations</a>
+ |
+ <a href="web_tester_documentation.html">Web tester</a>
+ |
+ <a href="form_testing_documentation.html">Testing forms</a>
+ |
+ <a href="authentication_documentation.html">Authentication</a>
+ |
+ <a href="browser_documentation.html">Scriptable browser</a>
+</div></div>
+<h1>Simple Test for PHP</h1>
+ This page...
+ <ul>
+<li>
+ <a href="#unit">Using unit tester</a>
+ with an example.
+ </li>
+<li>
+ <a href="#group">Grouping tests</a>
+ for testing with one click.
+ </li>
+<li>
+ <a href="#mock">Using mock objects</a>
+ to ease testing and gain tighter control.
+ </li>
+<li>
+ <a href="#web">Testing web pages</a>
+ at the browser level.
+ </li>
+</ul>
+<div class="content">
+
+
+ <p>
+ The following assumes that you are familiar with the concept
+ of unit testing as well as the PHP web development language.
+ It is a guide for the impatient new user of
+ <a href="https://sourceforge.net/project/showfiles.php?group_id=76550">SimpleTest</a>.
+ For fuller documentation, especially if you are new
+ to unit testing see the ongoing
+ <a href="unit_test_documentation.html">documentation</a>, and for
+ example test cases see the
+ <a href="http://www.lastcraft.com/first_test_tutorial.php">unit testing tutorial</a>.
+ </p>
+
+ <p><a class="target" name="unit"><h2>Using the tester quickly</h2></a></p>
+ <p>
+ Amongst software testing tools, a unit tester is the one
+ closest to the developer.
+ In the context of agile development the test code sits right
+ next to the source code as both are written simultaneously.
+ In this context SimpleTest aims to be a complete PHP developer
+ test solution and is called "Simple" because it
+ should be easy to use and extend.
+ It wasn't a good choice of name really.
+ It includes all of the typical functions you would expect from
+ <a href="http://www.junit.org/">JUnit</a> and the
+ <a href="http://sourceforge.net/projects/phpunit/">PHPUnit</a>
+ ports, and includes
+ <a href="http://www.mockobjects.com">mock objects</a>.
+ </p>
+ <p>
+ What makes this tool immediately useful to the PHP developer is the internal
+ web browser.
+ This allows tests that navigate web sites, fill in forms and test pages.
+ Being able to write these test in PHP means that it is easy to write
+ integrated tests.
+ An example might be confirming that a user was written to a database
+ after a signing up through the web site.
+ </p>
+ <p>
+ The quickest way to demonstrate SimpleTest is with an example.
+ </p>
+ <p>
+ Let us suppose we are testing a simple file logging class called
+ <span class="new_code">Log</span> in <em>classes/log.php</em>.
+ We start by creating a test script which we will call
+ <em>tests/log_test.php</em> and populate it as follows...
+<pre>
+&lt;?php
+<strong>require_once('simpletest/autorun.php');</strong>
+require_once('../classes/log.php');
+
+class TestOfLogging extends <strong>UnitTestCase</strong> {
+}
+?&gt;
+</pre>
+ Here the <em>simpletest</em> folder is either local or in the path.
+ You would have to edit these locations depending on where you
+ unpacked the toolset.
+ The "autorun.php" file does more than just include the
+ SimpleTest files, it also runs our test for us.
+ </p>
+ <p>
+ The <span class="new_code">TestOfLogging</span> is our first test case and it's
+ currently empty.
+ Each test case is a class that extends one of the SimpleTet base classes
+ and we can have as many of these in the file as we want.
+ </p>
+ <p>
+ With three lines of scaffolding, and our <span class="new_code">Log</span> class
+ include, we have a test suite.
+ No tests though.
+ </p>
+ <p>
+ For our first test, we'll assume that the <span class="new_code">Log</span> class
+ takes the file name to write to in the constructor, and we have
+ a temporary folder in which to place this file...
+<pre>
+&lt;?php
+require_once('simpletest/autorun.php');
+require_once('../classes/log.php');
+
+class TestOfLogging extends UnitTestCase {
+ function <strong>testLogCreatesNewFileOnFirstMessage()</strong> {
+ @unlink('/temp/test.log');
+ $log = new Log('/temp/test.log');
+ <strong>$this-&gt;assertFalse(file_exists('/temp/test.log'));</strong>
+ $log-&gt;message('Should write this to a file');
+ <strong>$this-&gt;assertTrue(file_exists('/temp/test.log'));</strong>
+ }
+}
+?&gt;
+</pre>
+ When a test case runs, it will search for any method that
+ starts with the string "test"
+ and execute that method.
+ If the method starts "test", it's a test.
+ Note the very long name <span class="new_code">testLogCreatesNewFileOnFirstMessage()</span>.
+ This is considered good style and makes the test output more readable.
+ </p>
+ <p>
+ We would normally have more than one test method in a test case,
+ but that's for later.
+ </p>
+ <p>
+ Assertions within the test methods trigger messages to the
+ test framework which displays the result immediately.
+ This immediate response is important, not just in the event
+ of the code causing a crash, but also so that
+ <span class="new_code">print</span> statements can display
+ their debugging content right next to the assertion concerned.
+ </p>
+ <p>
+ To see these results we have to actually run the tests.
+ No other code is necessary - we can just open the page
+ with our browser.
+ </p>
+ <p>
+ On failure the display looks like this...
+ <div class="demo">
+ <h1>TestOfLogging</h1>
+ <span class="fail">Fail</span>: testLogCreatesNewFileOnFirstMessage-&gt;True assertion failed.<br>
+ <div style="padding: 8px; margin-top: 1em; background-color: red; color: white;">1/1 test cases complete.
+ <strong>1</strong> passes and <strong>1</strong> fails.</div>
+ </div>
+ ...and if it passes like this...
+ <div class="demo">
+ <h1>TestOfLogging</h1>
+ <div style="padding: 8px; margin-top: 1em; background-color: green; color: white;">1/1 test cases complete.
+ <strong>2</strong> passes and <strong>0</strong> fails.</div>
+ </div>
+ And if you get this...
+ <div class="demo">
+ <b>Fatal error</b>: Failed opening required '../classes/log.php' (include_path='') in <b>/home/marcus/projects/lastcraft/tutorial_tests/Log/tests/log_test.php</b> on line <b>7</b>
+ </div>
+ it means you're missing the <em>classes/Log.php</em> file that could look like...
+<pre>
+&lt;?php<strong>
+class Log {
+ function Log($file_path) {
+ }
+
+ function message() {
+ }
+}</strong>
+?&gt;
+</pre>
+ It's fun to write the code after the test.
+ More than fun even -
+ this system is called "Test Driven Development".
+ </p>
+ <p>
+ For more information about <span class="new_code">UnitTestCase</span>, see
+ the <a href="unit_test_documentation.html">unit test documentation</a>.
+ </p>
+
+ <p><a class="target" name="group"><h2>Building test suites</h2></a></p>
+ <p>
+ It is unlikely in a real application that we will only ever run
+ one test case.
+ This means that we need a way of grouping cases into a test
+ script that can, if need be, run every test for the application.
+ </p>
+ <p>
+ Our first step is to create a new file called <em>tests/all_tests.php</em>
+ and insert the following code...
+<pre>
+&lt;?php
+<strong>require_once('simpletest/autorun.php');</strong>
+
+class AllTests extends <strong>TestSuite</strong> {
+ function AllTests() {
+ $this-&gt;TestSuite(<strong>'All tests'</strong>);
+ <strong>$this-&gt;addFile('log_test.php');</strong>
+ }
+}
+?&gt;
+</pre>
+ The "autorun" include allows our upcoming test suite
+ to be run just by invoking this script.
+ </p>
+ <p>
+ The <span class="new_code">TestSuite</span> subclass must chain it's constructor.
+ This limitation will be removed in future versions.
+ </p>
+ <p>
+ The method <span class="new_code">TestSuite::addFile()</span>
+ will include the test case file and read any new classes
+ that are descended from <span class="new_code">SimpleTestCase</span>.
+ <span class="new_code">UnitTestCase</span> is just one example of a class derived from
+ <span class="new_code">SimpleTestCase</span>, and you can create your own.
+ <span class="new_code">TestSuite::addFile()</span> can include other test suites.
+ </p>
+ <p>
+ The class will not be instantiated yet.
+ When the test suite runs it will construct each instance once
+ it reaches that test, then destroy it straight after.
+ This means that the constructor is run just before each run
+ of that test case, and the destructor is run before the next test case starts.
+ </p>
+ <p>
+ It is common to group test case code into superclasses which are not
+ supposed to run, but become the base classes of other tests.
+ For "autorun" to work properly the test case file should not blindly run
+ any other test case extensions that do not actually run tests.
+ This could result in extra test cases being counted during the test
+ run.
+ Hardly a major problem, but to avoid this inconvenience simply mark your
+ base class as <span class="new_code">abstract</span>.
+ SimpleTest won't run abstract classes.
+ If you are still using PHP4, then
+ a <span class="new_code">SimpleTestOptions::ignore()</span> directive
+ somewhere in the test case file will have the same effect.
+ </p>
+ <p>
+ Also, the test case file should not have been included
+ elsewhere or no cases will be added to this group test.
+ This would be a more serious error as if the test case classes are
+ already loaded by PHP the <span class="new_code">TestSuite::addFile()</span>
+ method will not detect them.
+ </p>
+ <p>
+ To display the results it is necessary only to invoke
+ <em>tests/all_tests.php</em> from the web server or the command line.
+ </p>
+ <p>
+ For more information about building test suites,
+ see the <a href="group_test_documentation.html">test suite documentation</a>.
+ </p>
+
+ <p><a class="target" name="mock"><h2>Using mock objects</h2></a></p>
+ <p>
+ Let's move further into the future and do something really complicated.
+ </p>
+ <p>
+ Assume that our logging class is tested and completed.
+ Assume also that we are testing another class that is
+ required to write log messages, say a
+ <span class="new_code">SessionPool</span>.
+ We want to test a method that will probably end up looking
+ like this...
+<pre><strong>
+class SessionPool {
+ ...
+ function logIn($username) {
+ ...
+ $this-&gt;_log-&gt;message("User $username logged in.");
+ ...
+ }
+ ...
+}
+</strong>
+</pre>
+ In the spirit of reuse, we are using our
+ <span class="new_code">Log</span> class.
+ A conventional test case might look like this...
+<pre>
+&lt;?php
+require_once('simpletest/autorun.php');
+require_once('../classes/log.php');
+<strong>require_once('../classes/session_pool.php');</strong>
+
+class <strong>TestOfSessionLogging</strong> extends UnitTestCase {
+
+ function setUp() {
+ <strong>@unlink('/temp/test.log');</strong>
+ }
+
+ function tearDown() {
+ <strong>@unlink('/temp/test.log');</strong>
+ }
+
+ function testLoggingInIsLogged() {
+ <strong>$log = new Log('/temp/test.log');
+ $session_pool = &amp;new SessionPool($log);
+ $session_pool-&gt;logIn('fred');</strong>
+ $messages = file('/temp/test.log');
+ $this-&gt;assertEqual($messages[0], "User fred logged in.<strong>\n</strong>");
+ }
+}
+?&gt;
+</pre>
+ We'll explain the <span class="new_code">setUp()</span> and <span class="new_code">tearDown()</span>
+ methods later.
+ </p>
+ <p>
+ This test case design is not all bad, but it could be improved.
+ We are spending time fiddling with log files which are
+ not part of our test.
+ We have created close ties with the <span class="new_code">Log</span> class and
+ this test.
+ What if we don't use files any more, but use ths
+ <em>syslog</em> library instead?
+ It means that our <span class="new_code">TestOfSessionLogging</span> test will
+ fail, even thouh it's not testing Logging.
+ </p>
+ <p>
+ It's fragile in smaller ways too.
+ Did you notice the extra carriage return in the message?
+ Was that added by the logger?
+ What if it also added a time stamp or other data?
+ </p>
+ <p>
+ The only part that we really want to test is that a particular
+ message was sent to the logger.
+ We can reduce coupling if we pass in a fake logging class
+ that simply records the message calls for testing, but
+ takes no action.
+ It would have to look exactly like our original though.
+ </p>
+ <p>
+ If the fake object doesn't write to a file then we save on deleting
+ the file before and after each test. We could save even more
+ test code if the fake object would kindly run the assertion for us.
+ <p>
+ </p>
+ Too good to be true?
+ We can create such an object easily...
+<pre>
+&lt;?php
+require_once('simpletest/autorun.php');
+require_once('../classes/log.php');
+require_once('../classes/session_pool.php');
+
+<strong>Mock::generate('Log');</strong>
+
+class TestOfSessionLogging extends UnitTestCase {
+
+ function testLoggingInIsLogged() {<strong>
+ $log = &amp;new MockLog();
+ $log-&gt;expectOnce('message', array('User fred logged in.'));</strong>
+ $session_pool = &amp;new SessionPool(<strong>$log</strong>);
+ $session_pool-&gt;logIn('fred');
+ }
+}
+?&gt;
+</pre>
+ The <span class="new_code">Mock::generate()</span> call code generated a new class
+ called <span class="new_code">MockLog</span>.
+ This looks like an identical clone, except that we can wire test code
+ to it.
+ That's what <span class="new_code">expectOnce()</span> does.
+ It says that if <span class="new_code">message()</span> is ever called on me, it had
+ better be with the parameter "User fred logged in.".
+ </p>
+ <p>
+ The test will be triggered when the call to
+ <span class="new_code">message()</span> is invoked on the
+ <span class="new_code">MockLog</span> object by <span class="new_code">SessionPool::logIn()</span> code.
+ The mock call will trigger a parameter comparison and then send the
+ resulting pass or fail event to the test display.
+ Wildcards can be included here too, so you don't have to test every parameter of
+ a call when you only want to test one.
+ </p>
+ <p>
+ If the mock reaches the end of the test case without the
+ method being called, the <span class="new_code">expectOnce()</span>
+ expectation will trigger a test failure.
+ In other words the mocks can detect the absence of
+ behaviour as well as the presence.
+ </p>
+ <p>
+ The mock objects in the SimpleTest suite can have arbitrary
+ return values set, sequences of returns, return values
+ selected according to the incoming arguments, sequences of
+ parameter expectations and limits on the number of times
+ a method is to be invoked.
+ </p>
+ <p>
+ For more information about mocking and stubbing, see the
+ <a href="mock_objects_documentation.html">mock objects documentation</a>.
+ </p>
+
+ <p><a class="target" name="web"><h2>Web page testing</h2></a></p>
+ <p>
+ One of the requirements of web sites is that they produce web
+ pages.
+ If you are building a project top-down and you want to fully
+ integrate testing along the way then you will want a way of
+ automatically navigating a site and examining output for
+ correctness.
+ This is the job of a web tester.
+ </p>
+ <p>
+ The web testing in SimpleTest is fairly primitive, as there is
+ no JavaScript.
+ Most other browser operations are simulated.
+ </p>
+ <p>
+ To give an idea here is a trivial example where a home
+ page is fetched, from which we navigate to an "about"
+ page and then test some client determined content.
+<pre>
+&lt;?php
+require_once('simpletest/autorun.php');
+<strong>require_once('simpletest/web_tester.php');</strong>
+
+class TestOfAbout extends <strong>WebTestCase</strong> {
+ function testOurAboutPageGivesFreeReignToOurEgo() {
+ <strong>$this-&gt;get('http://test-server/index.php');
+ $this-&gt;click('About');
+ $this-&gt;assertTitle('About why we are so great');
+ $this-&gt;assertText('We are really great');</strong>
+ }
+}
+?&gt;
+</pre>
+ With this code as an acceptance test, you can ensure that
+ the content always meets the specifications of both the
+ developers, and the other project stakeholders.
+ </p>
+ <p>
+ You can navigate forms too...
+<pre>
+&lt;?php
+require_once('simpletest/autorun.php');
+require_once('simpletest/web_tester.php');
+
+class TestOfRankings extends WebTestCase {
+ function testWeAreTopOfGoogle() {
+ $this-&gt;get('http://google.com/');
+ $this-&gt;setField('q', 'simpletest');
+ $this-&gt;click("I'm Feeling Lucky");
+ $this-&gt;assertTitle('SimpleTest - Unit Testing for PHP');
+ }
+}
+?&gt;
+</pre>
+ ...although this could violate Google's(tm) terms and conditions.
+ </p>
+ <p>
+ For more information about web testing, see the
+ <a href="browser_documentation.html">scriptable
+ browser documentation</a> and the
+ <a href="web_tester_documentation.html">WebTestCase</a>.
+ </p>
+ <p>
+ <a href="http://sourceforge.net/projects/simpletest/"><img src="http://sourceforge.net/sflogo.php?group_id=76550&amp;type=5" width="210" height="62" border="0" alt="SourceForge.net Logo"></a>
+ </p>
+
+ </div>
+ References and related information...
+ <ul>
+<li>
+ <a href="https://sourceforge.net/project/showfiles.php?group_id=76550&amp;release_id=153280">Download PHP Simple Test</a>
+ from <a href="http://sourceforge.net/projects/simpletest/">SourceForge</a>.
+ </li>
+<li>
+ The <a href="http://simpletest.org/api/">developer's API for SimpleTest</a>
+ gives full detail on the classes and assertions available.
+ </li>
+</ul>
+<div class="menu_back"><div class="menu">
+<span class="chosen">SimpleTest</span>
+ |
+ <a href="overview.html">Overview</a>
+ |
+ <a href="unit_test_documentation.html">Unit tester</a>
+ |
+ <a href="group_test_documentation.html">Group tests</a>
+ |
+ <a href="mock_objects_documentation.html">Mock objects</a>
+ |
+ <a href="partial_mocks_documentation.html">Partial mocks</a>
+ |
+ <a href="reporter_documentation.html">Reporting</a>
+ |
+ <a href="expectation_documentation.html">Expectations</a>
+ |
+ <a href="web_tester_documentation.html">Web tester</a>
+ |
+ <a href="form_testing_documentation.html">Testing forms</a>
+ |
+ <a href="authentication_documentation.html">Authentication</a>
+ |
+ <a href="browser_documentation.html">Scriptable browser</a>
+</div></div>
+<div class="copyright">
+ Copyright<br>Marcus Baker 2006
+ </div>
+</body>
+</html>
diff --git a/site/vendors/simpletest/docs/en/mock_objects_documentation.html b/site/vendors/simpletest/docs/en/mock_objects_documentation.html
new file mode 100644
index 0000000..c3d0022
--- /dev/null
+++ b/site/vendors/simpletest/docs/en/mock_objects_documentation.html
@@ -0,0 +1,757 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>SimpleTest for PHP mock objects documentation</title>
+<link rel="stylesheet" type="text/css" href="docs.css" title="Styles">
+</head>
+<body>
+<div class="menu_back"><div class="menu">
+<a href="index.html">SimpleTest</a>
+ |
+ <a href="overview.html">Overview</a>
+ |
+ <a href="unit_test_documentation.html">Unit tester</a>
+ |
+ <a href="group_test_documentation.html">Group tests</a>
+ |
+ <span class="chosen">Mock objects</span>
+ |
+ <a href="partial_mocks_documentation.html">Partial mocks</a>
+ |
+ <a href="reporter_documentation.html">Reporting</a>
+ |
+ <a href="expectation_documentation.html">Expectations</a>
+ |
+ <a href="web_tester_documentation.html">Web tester</a>
+ |
+ <a href="form_testing_documentation.html">Testing forms</a>
+ |
+ <a href="authentication_documentation.html">Authentication</a>
+ |
+ <a href="browser_documentation.html">Scriptable browser</a>
+</div></div>
+<h1>Mock objects documentation</h1>
+ This page...
+ <ul>
+<li>
+ <a href="#what">What are mock objects?</a>
+ </li>
+<li>
+ <a href="#creation">Creating mock objects</a>.
+ </li>
+<li>
+ <a href="#stub">Mocks as actors</a> or stubs.
+ </li>
+<li>
+ <a href="#expectations">Mocks as critics</a> with expectations.
+ </li>
+<li>
+ <a href="#approaches">Other approaches</a> including mock libraries.
+ </li>
+</ul>
+<div class="content">
+ <p><a class="target" name="what"><h2>What are mock objects?</h2></a></p>
+ <p>
+ Mock objects have two roles during a test case: actor and critic.
+ </p>
+ <p>
+ The actor behaviour is to simulate objects that are difficult to
+ set up or time consuming to set up for a test.
+ The classic example is a database connection.
+ Setting up a test database at the start of each test would slow
+ testing to a crawl and would require the installation of the
+ database engine and test data on the test machine.
+ If we can simulate the connection and return data of our
+ choosing we not only win on the pragmatics of testing, but can
+ also feed our code spurious data to see how it responds.
+ We can simulate databases being down or other extremes
+ without having to create a broken database for real.
+ In other words, we get greater control of the test environment.
+ </p>
+ <p>
+ If mock objects only behaved as actors they would simply be
+ known as server stubs.
+ This was originally a pattern named by Robert Binder (Testing
+ object-oriented systems: models, patterns, and tools,
+ Addison-Wesley) in 1999.
+ </p>
+ <p>
+ A server stub is a simulation of an object or component.
+ It should exactly replace a component in a system for test
+ or prototyping purposes, but remain lightweight.
+ This allows tests to run more quickly, or if the simulated
+ class has not been written, to run at all.
+ </p>
+ <p>
+ However, the mock objects not only play a part (by supplying chosen
+ return values on demand) they are also sensitive to the
+ messages sent to them (via expectations).
+ By setting expected parameters for a method call they act
+ as a guard that the calls upon them are made correctly.
+ If expectations are not met they save us the effort of
+ writing a failed test assertion by performing that duty on our
+ behalf.
+ </p>
+ <p>
+ In the case of an imaginary database connection they can
+ test that the query, say SQL, was correctly formed by
+ the object that is using the connection.
+ Set them up with fairly tight expectations and you will
+ hardly need manual assertions at all.
+ </p>
+
+ <p><a class="target" name="creation"><h2>Creating mock objects</h2></a></p>
+ <p>
+ In the same way that we create server stubs, all we need is an
+ existing class, say a database connection that looks like this...
+<pre>
+<strong>class DatabaseConnection {
+ function DatabaseConnection() {
+ }
+
+ function query() {
+ }
+
+ function selectQuery() {
+ }
+}</strong>
+</pre>
+ The class does not need to have been implemented yet.
+ To create a mock version of the class we need to include the
+ mock object library and run the generator...
+<pre>
+<strong>require_once('simpletest/unit_tester.php');
+require_once('simpletest/mock_objects.php');
+require_once('database_connection.php');
+
+Mock::generate('DatabaseConnection');</strong>
+</pre>
+ This generates a clone class called
+ <span class="new_code">MockDatabaseConnection</span>.
+ We can now create instances of the new class within
+ our test case...
+<pre>
+require_once('simpletest/unit_tester.php');
+require_once('simpletest/mock_objects.php');
+require_once('database_connection.php');
+
+Mock::generate('DatabaseConnection');
+<strong>
+class MyTestCase extends UnitTestCase {
+
+ function testSomething() {
+ $connection = &amp;new MockDatabaseConnection();
+ }
+}</strong>
+</pre>
+ Unlike the generated stubs the mock constructor needs a reference
+ to the test case so that it can dispatch passes and failures while
+ checking its expectations.
+ This means that mock objects can only be used within test cases.
+ Despite this their extra power means that stubs are hardly ever used
+ if mocks are available.
+ </p>
+ <p>
+ <a class="target" name="stub"><h2>Mocks as actors</h2></a>
+ </p>
+ <p>
+ The mock version of a class has all the methods of the original,
+ so that operations like
+ <span class="new_code">$connection-&gt;query()</span> are still
+ legal.
+ The return value will be <span class="new_code">null</span>,
+ but we can change that with...
+<pre>
+<strong>$connection-&gt;setReturnValue('query', 37)</strong>
+</pre>
+ Now every time we call
+ <span class="new_code">$connection-&gt;query()</span> we get
+ the result of 37.
+ We can set the return value to anything, say a hash of
+ imaginary database results or a list of persistent objects.
+ Parameters are irrelevant here, we always get the same
+ values back each time once they have been set up this way.
+ That may not sound like a convincing replica of a
+ database connection, but for the half a dozen lines of
+ a test method it is usually all you need.
+ </p>
+ <p>
+ We can also add extra methods to the mock when generating it
+ and choose our own class name...
+<pre>
+<strong>Mock::generate('DatabaseConnection', 'MyMockDatabaseConnection', array('setOptions'));</strong>
+</pre>
+ Here the mock will behave as if the <span class="new_code">setOptions()</span>
+ existed in the original class.
+ This is handy if a class has used the PHP <span class="new_code">overload()</span>
+ mechanism to add dynamic methods.
+ You can create a special mock to simulate this situation.
+ </p>
+ <p>
+ Things aren't always that simple though.
+ One common problem is iterators, where constantly returning
+ the same value could cause an endless loop in the object
+ being tested.
+ For these we need to set up sequences of values.
+ Let's say we have a simple iterator that looks like this...
+<pre>
+class Iterator {
+ function Iterator() {
+ }
+
+ function next() {
+ }
+}
+</pre>
+ This is about the simplest iterator you could have.
+ Assuming that this iterator only returns text until it
+ reaches the end, when it returns false, we can simulate it
+ with...
+<pre>
+Mock::generate('Iterator');
+
+class IteratorTest extends UnitTestCase() {
+
+ function testASequence() {<strong>
+ $iterator = &amp;new MockIterator();
+ $iterator-&gt;setReturnValue('next', false);
+ $iterator-&gt;setReturnValueAt(0, 'next', 'First string');
+ $iterator-&gt;setReturnValueAt(1, 'next', 'Second string');</strong>
+ ...
+ }
+}
+</pre>
+ When <span class="new_code">next()</span> is called on the
+ mock iterator it will first return "First string",
+ on the second call "Second string" will be returned
+ and on any other call <span class="new_code">false</span> will
+ be returned.
+ The sequenced return values take precedence over the constant
+ return value.
+ The constant one is a kind of default if you like.
+ </p>
+ <p>
+ Another tricky situation is an overloaded
+ <span class="new_code">get()</span> operation.
+ An example of this is an information holder with name/value pairs.
+ Say we have a configuration class like...
+<pre>
+class Configuration {
+ function Configuration() {
+ }
+
+ function getValue($key) {
+ }
+}
+</pre>
+ This is a classic situation for using mock objects as
+ actual configuration will vary from machine to machine,
+ hardly helping the reliability of our tests if we use it
+ directly.
+ The problem though is that all the data comes through the
+ <span class="new_code">getValue()</span> method and yet
+ we want different results for different keys.
+ Luckily the mocks have a filter system...
+<pre>
+<strong>$config = &amp;new MockConfiguration();
+$config-&gt;setReturnValue('getValue', 'primary', array('db_host'));
+$config-&gt;setReturnValue('getValue', 'admin', array('db_user'));
+$config-&gt;setReturnValue('getValue', 'secret', array('db_password'));</strong>
+</pre>
+ The extra parameter is a list of arguments to attempt
+ to match.
+ In this case we are trying to match only one argument which
+ is the look up key.
+ Now when the mock object has the
+ <span class="new_code">getValue()</span> method invoked
+ like this...
+<pre>
+$config-&gt;getValue('db_user')
+</pre>
+ ...it will return "admin".
+ It finds this by attempting to match the calling arguments
+ to its list of returns one after another until
+ a complete match is found.
+ </p>
+ <p>
+ You can set a default argument argument like so...
+<pre><strong>
+$config-&gt;setReturnValue('getValue', false, array('*'));</strong>
+</pre>
+ This is not the same as setting the return value without
+ any argument requirements like this...
+<pre><strong>
+$config-&gt;setReturnValue('getValue', false);</strong>
+</pre>
+ In the first case it will accept any single argument,
+ but exactly one is required.
+ In the second case any number of arguments will do and
+ it acts as a catchall after all other matches.
+ Note that if we add further single parameter options after
+ the wildcard in the first case, they will be ignored as the wildcard
+ will match first.
+ With complex parameter lists the ordering could be important
+ or else desired matches could be masked by earlier wildcard
+ ones.
+ Declare the most specific matches first if you are not sure.
+ </p>
+ <p>
+ There are times when you want a specific object to be
+ dished out by the mock rather than a copy.
+ The PHP4 copy semantics force us to use a different method
+ for this.
+ You might be simulating a container for example...
+<pre>
+class Thing {
+}
+
+class Vector {
+ function Vector() {
+ }
+
+ function get($index) {
+ }
+}
+</pre>
+ In this case you can set a reference into the mock's
+ return list...
+<pre>
+$thing = &amp;new Thing();<strong>
+$vector = &amp;new MockVector();
+$vector-&gt;setReturnReference('get', $thing, array(12));</strong>
+</pre>
+ With this arrangement you know that every time
+ <span class="new_code">$vector-&gt;get(12)</span> is
+ called it will return the same
+ <span class="new_code">$thing</span> each time.
+ This is compatible with PHP5 as well.
+ </p>
+ <p>
+ These three factors, timing, parameters and whether to copy,
+ can be combined orthogonally.
+ For example...
+<pre>
+$complex = &amp;new MockComplexThing();
+$stuff = &amp;new Stuff();<strong>
+$complex-&gt;setReturnReferenceAt(3, 'get', $stuff, array('*', 1));</strong>
+</pre>
+ This will return the <span class="new_code">$stuff</span> only on the third
+ call and only if two parameters were set the second of
+ which must be the integer 1.
+ That should cover most simple prototyping situations.
+ </p>
+ <p>
+ A final tricky case is one object creating another, known
+ as a factory pattern.
+ Suppose that on a successful query to our imaginary
+ database, a result set is returned as an iterator with
+ each call to <span class="new_code">next()</span> giving
+ one row until false.
+ This sounds like a simulation nightmare, but in fact it can all
+ be mocked using the mechanics above.
+ </p>
+ <p>
+ Here's how...
+<pre>
+Mock::generate('DatabaseConnection');
+Mock::generate('ResultIterator');
+
+class DatabaseTest extends UnitTestCase {
+
+ function testUserFinder() {<strong>
+ $result = &amp;new MockResultIterator();
+ $result-&gt;setReturnValue('next', false);
+ $result-&gt;setReturnValueAt(0, 'next', array(1, 'tom'));
+ $result-&gt;setReturnValueAt(1, 'next', array(3, 'dick'));
+ $result-&gt;setReturnValueAt(2, 'next', array(6, 'harry'));
+
+ $connection = &amp;new MockDatabaseConnection();
+ $connection-&gt;setReturnValue('query', false);
+ $connection-&gt;setReturnReference(
+ 'query',
+ $result,
+ array('select id, name from users'));</strong>
+
+ $finder = &amp;new UserFinder($connection);
+ $this-&gt;assertIdentical(
+ $finder-&gt;findNames(),
+ array('tom', 'dick', 'harry'));
+ }
+}
+</pre>
+ Now only if our
+ <span class="new_code">$connection</span> is called with the correct
+ <span class="new_code">query()</span> will the
+ <span class="new_code">$result</span> be returned that is
+ itself exhausted after the third call to <span class="new_code">next()</span>.
+ This should be enough
+ information for our <span class="new_code">UserFinder</span> class,
+ the class actually
+ being tested here, to come up with goods.
+ A very precise test and not a real database in sight.
+ </p>
+
+ <p><a class="target" name="expectations"><h2>Mocks as critics</h2></a></p>
+ <p>
+ Although the server stubs approach insulates your tests from
+ real world disruption, it is only half the benefit.
+ You can have the class under test receiving the required
+ messages, but is your new class sending correct ones?
+ Testing this can get messy without a mock objects library.
+ </p>
+ <p>
+ By way of example, suppose we have a
+ <span class="new_code">SessionPool</span> class that we
+ want to add logging to.
+ Rather than grow the original class into something more
+ complicated, we want to add this behaviour with a decorator (GOF).
+ The <span class="new_code">SessionPool</span> code currently looks
+ like this...
+<pre>
+<strong>class SessionPool {
+ function SessionPool() {
+ ...
+ }
+
+ function &amp;findSession($cookie) {
+ ...
+ }
+ ...
+}
+
+class Session {
+ ...
+}</strong>
+</pre>
+ While our logging code looks like this...
+<pre>
+<strong>
+class Log {
+ function Log() {
+ ...
+ }
+
+ function message() {
+ ...
+ }
+}
+
+class LoggingSessionPool {
+ function LoggingSessionPool(&amp;$session_pool, &amp;$log) {
+ ...
+ }
+
+ function &amp;findSession($cookie) {
+ ...
+ }
+ ...
+}</strong>
+</pre>
+ Out of all of this, the only class we want to test here
+ is the <span class="new_code">LoggingSessionPool</span>.
+ In particular we would like to check that the
+ <span class="new_code">findSession()</span> method is
+ called with the correct session ID in the cookie and that
+ it sent the message "Starting session $cookie"
+ to the logger.
+ </p>
+ <p>
+ Despite the fact that we are testing only a few lines of
+ production code, here is what we would have to do in a
+ conventional test case:
+ <ol>
+ <li>Create a log object.</li>
+ <li>Set a directory to place the log file.</li>
+ <li>Set the directory permissions so we can write the log.</li>
+ <li>Create a <span class="new_code">SessionPool</span> object.</li>
+ <li>Hand start a session, which probably does lot's of things.</li>
+ <li>Invoke <span class="new_code">findSession()</span>.</li>
+ <li>Read the new Session ID (hope there is an accessor!).</li>
+ <li>Raise a test assertion to confirm that the ID matches the cookie.</li>
+ <li>Read the last line of the log file.</li>
+ <li>Pattern match out the extra logging timestamps, etc.</li>
+ <li>Assert that the session message is contained in the text.</li>
+ </ol>
+ It is hardly surprising that developers hate writing tests
+ when they are this much drudgery.
+ To make things worse, every time the logging format changes or
+ the method of creating new sessions changes, we have to rewrite
+ parts of this test even though this test does not officially
+ test those parts of the system.
+ We are creating headaches for the writers of these other classes.
+ </p>
+ <p>
+ Instead, here is the complete test method using mock object magic...
+<pre>
+Mock::generate('Session');
+Mock::generate('SessionPool');
+Mock::generate('Log');
+
+class LoggingSessionPoolTest extends UnitTestCase {
+ ...
+ function testFindSessionLogging() {<strong>
+ $session = &amp;new MockSession();
+ $pool = &amp;new MockSessionPool();
+ $pool-&gt;setReturnReference('findSession', $session);
+ $pool-&gt;expectOnce('findSession', array('abc'));
+
+ $log = &amp;new MockLog();
+ $log-&gt;expectOnce('message', array('Starting session abc'));
+
+ $logging_pool = &amp;new LoggingSessionPool($pool, $log);
+ $this-&gt;assertReference($logging_pool-&gt;findSession('abc'), $session);</strong>
+ }
+}
+</pre>
+ We start by creating a dummy session.
+ We don't have to be too fussy about this as the check
+ for which session we want is done elsewhere.
+ We only need to check that it was the same one that came
+ from the session pool.
+ </p>
+ <p>
+ <span class="new_code">findSession()</span> is a factory
+ method the simulation of which is described <a href="#stub">above</a>.
+ The point of departure comes with the first
+ <span class="new_code">expectOnce()</span> call.
+ This line states that whenever
+ <span class="new_code">findSession()</span> is invoked on the
+ mock, it will test the incoming arguments.
+ If it receives the single argument of a string "abc"
+ then a test pass is sent to the unit tester, otherwise a fail is
+ generated.
+ This was the part where we checked that the right session was asked for.
+ The argument list follows the same format as the one for setting
+ return values.
+ You can have wildcards and sequences and the order of
+ evaluation is the same.
+ </p>
+ <p>
+ We use the same pattern to set up the mock logger.
+ We tell it that it should have
+ <span class="new_code">message()</span> invoked
+ once only with the argument "Starting session abc".
+ By testing the calling arguments, rather than the logger output,
+ we insulate the test from any display changes in the logger.
+ </p>
+ <p>
+ We start to run our tests when we create the new
+ <span class="new_code">LoggingSessionPool</span> and feed
+ it our preset mock objects.
+ Everything is now under our control.
+ </p>
+ <p>
+ This is still quite a bit of test code, but the code is very
+ strict.
+ If it still seems rather daunting there is a lot less of it
+ than if we tried this without mocks and this particular test,
+ interactions rather than output, is always more work to set
+ up.
+ More often you will be testing more complex situations without
+ needing this level or precision.
+ Also some of this can be refactored into a test case
+ <span class="new_code">setUp()</span> method.
+ </p>
+ <p>
+ Here is the full list of expectations you can set on a mock object
+ in <a href="http://www.lastcraft.com/simple_test.php">SimpleTest</a>...
+ <table>
+<thead>
+ <tr>
+<th>Expectation</th>
+<th>Needs <span class="new_code">tally()</span>
+</th>
+</tr>
+ </thead>
+<tbody>
+<tr>
+ <td><span class="new_code">expect($method, $args)</span></td>
+ <td style="text-align: center">No</td>
+ </tr>
+ <tr>
+ <td><span class="new_code">expectAt($timing, $method, $args)</span></td>
+ <td style="text-align: center">No</td>
+ </tr>
+ <tr>
+ <td><span class="new_code">expectCallCount($method, $count)</span></td>
+ <td style="text-align: center">Yes</td>
+ </tr>
+ <tr>
+ <td><span class="new_code">expectMaximumCallCount($method, $count)</span></td>
+ <td style="text-align: center">No</td>
+ </tr>
+ <tr>
+ <td><span class="new_code">expectMinimumCallCount($method, $count)</span></td>
+ <td style="text-align: center">Yes</td>
+ </tr>
+ <tr>
+ <td><span class="new_code">expectNever($method)</span></td>
+ <td style="text-align: center">No</td>
+ </tr>
+ <tr>
+ <td><span class="new_code">expectOnce($method, $args)</span></td>
+ <td style="text-align: center">Yes</td>
+ </tr>
+ <tr>
+ <td><span class="new_code">expectAtLeastOnce($method, $args)</span></td>
+ <td style="text-align: center">Yes</td>
+ </tr>
+ </tbody>
+</table>
+ Where the parameters are...
+ <dl>
+ <dt class="new_code">$method</dt>
+ <dd>The method name, as a string, to apply the condition to.</dd>
+ <dt class="new_code">$args</dt>
+ <dd>
+ The arguments as a list. Wildcards can be included in the same
+ manner as for <span class="new_code">setReturn()</span>.
+ This argument is optional for <span class="new_code">expectOnce()</span>
+ and <span class="new_code">expectAtLeastOnce()</span>.
+ </dd>
+ <dt class="new_code">$timing</dt>
+ <dd>
+ The only point in time to test the condition.
+ The first call starts at zero.
+ </dd>
+ <dt class="new_code">$count</dt>
+ <dd>The number of calls expected.</dd>
+ </dl>
+ The method <span class="new_code">expectMaximumCallCount()</span>
+ is slightly different in that it will only ever generate a failure.
+ It is silent if the limit is never reached.
+ </p>
+ <p>
+ Also if you have juste one call in your test, make sure you're using
+ <span class="new_code">expectOnce</span>.<br>
+ Using <span class="new_code">$mocked-&gt;expectAt(0, 'method', 'args);</span>
+ on its own will not be catched :
+ checking the arguments and the overall call count
+ are currently independant.
+ </p>
+ <p>
+ Like the assertions within test cases, all of the expectations
+ can take a message override as an extra parameter.
+ Also the original failure message can be embedded in the output
+ as "%s".
+ </p>
+
+ <p><a class="target" name="approaches"><h2>Other approaches</h2></a></p>
+ <p>
+ There are three approaches to creating mocks including the one
+ that SimpleTest employs.
+ Coding them by hand using a base class, generating them to
+ a file and dynamically generating them on the fly.
+ </p>
+ <p>
+ Mock objects generated with <a href="simple_test.html">SimpleTest</a>
+ are dynamic.
+ They are created at run time in memory, using
+ <span class="new_code">eval()</span>, rather than written
+ out to a file.
+ This makes the mocks easy to create, a one liner,
+ especially compared with hand
+ crafting them in a parallel class hierarchy.
+ The problem is that the behaviour is usually set up in the tests
+ themselves.
+ If the original objects change the mock versions
+ that the tests rely on can get out of sync.
+ This can happen with the parallel hierarchy approach as well,
+ but is far more quickly detected.
+ </p>
+ <p>
+ The solution, of course, is to add some real integration
+ tests.
+ You don't need very many and the convenience gained
+ from the mocks more than outweighs the small amount of
+ extra testing.
+ You cannot trust code that was only tested with mocks.
+ </p>
+ <p>
+ If you are still determined to build static libraries of mocks
+ because you want to simulate very specific behaviour, you can
+ achieve the same effect using the SimpleTest class generator.
+ In your library file, say <em>mocks/connection.php</em> for a
+ database connection, create a mock and inherit to override
+ special methods or add presets...
+<pre>
+&lt;?php
+ require_once('simpletest/mock_objects.php');
+ require_once('../classes/connection.php');
+<strong>
+ Mock::generate('Connection', 'BasicMockConnection');
+ class MockConnection extends BasicMockConnection {
+ function MockConnection() {
+ $this-&gt;BasicMockConnection();
+ $this-&gt;setReturn('query', false);
+ }
+ }</strong>
+?&gt;
+</pre>
+ The generate call tells the class generator to create
+ a class called <span class="new_code">BasicMockConnection</span>
+ rather than the usual <span class="new_code">MockConnection</span>.
+ We then inherit from this to get our version of
+ <span class="new_code">MockConnection</span>.
+ By intercepting in this way we can add behaviour, here setting
+ the default value of <span class="new_code">query()</span> to be false.
+ By using the default name we make sure that the mock class
+ generator will not recreate a different one when invoked elsewhere in the
+ tests.
+ It never creates a class if it already exists.
+ As long as the above file is included first then all tests
+ that generated <span class="new_code">MockConnection</span> should
+ now be using our one instead.
+ If we don't get the order right and the mock library
+ creates one first then the class creation will simply fail.
+ </p>
+ <p>
+ Use this trick if you find you have a lot of common mock behaviour
+ or you are getting frequent integration problems at later
+ stages of testing.
+ </p>
+
+ </div>
+ References and related information...
+ <ul>
+<li>
+ The original
+ <a href="http://www.mockobjects.com/">Mock objects</a> paper.
+ </li>
+<li>
+ SimpleTest project page on <a href="http://sourceforge.net/projects/simpletest/">SourceForge</a>.
+ </li>
+<li>
+ SimpleTest home page on <a href="http://www.lastcraft.com/simple_test.php">LastCraft</a>.
+ </li>
+</ul>
+<div class="menu_back"><div class="menu">
+<a href="index.html">SimpleTest</a>
+ |
+ <a href="overview.html">Overview</a>
+ |
+ <a href="unit_test_documentation.html">Unit tester</a>
+ |
+ <a href="group_test_documentation.html">Group tests</a>
+ |
+ <span class="chosen">Mock objects</span>
+ |
+ <a href="partial_mocks_documentation.html">Partial mocks</a>
+ |
+ <a href="reporter_documentation.html">Reporting</a>
+ |
+ <a href="expectation_documentation.html">Expectations</a>
+ |
+ <a href="web_tester_documentation.html">Web tester</a>
+ |
+ <a href="form_testing_documentation.html">Testing forms</a>
+ |
+ <a href="authentication_documentation.html">Authentication</a>
+ |
+ <a href="browser_documentation.html">Scriptable browser</a>
+</div></div>
+<div class="copyright">
+ Copyright<br>Marcus Baker 2006
+ </div>
+</body>
+</html>
diff --git a/site/vendors/simpletest/docs/en/overview.html b/site/vendors/simpletest/docs/en/overview.html
new file mode 100644
index 0000000..5bed89e
--- /dev/null
+++ b/site/vendors/simpletest/docs/en/overview.html
@@ -0,0 +1,486 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>
+ Overview and feature list for the SimpleTest PHP unit tester and web tester
+ </title>
+<link rel="stylesheet" type="text/css" href="docs.css" title="Styles">
+</head>
+<body>
+<div class="menu_back"><div class="menu">
+<a href="index.html">SimpleTest</a>
+ |
+ <span class="chosen">Overview</span>
+ |
+ <a href="unit_test_documentation.html">Unit tester</a>
+ |
+ <a href="group_test_documentation.html">Group tests</a>
+ |
+ <a href="mock_objects_documentation.html">Mock objects</a>
+ |
+ <a href="partial_mocks_documentation.html">Partial mocks</a>
+ |
+ <a href="reporter_documentation.html">Reporting</a>
+ |
+ <a href="expectation_documentation.html">Expectations</a>
+ |
+ <a href="web_tester_documentation.html">Web tester</a>
+ |
+ <a href="form_testing_documentation.html">Testing forms</a>
+ |
+ <a href="authentication_documentation.html">Authentication</a>
+ |
+ <a href="browser_documentation.html">Scriptable browser</a>
+</div></div>
+<h1>Overview of SimpleTest</h1>
+ This page...
+ <ul>
+<li>
+ <a href="#summary">Quick summary</a>
+ of the SimpleTest tool for PHP.
+ </li>
+<li>
+ <a href="#features">List of features</a>,
+ both current ones and those planned.
+ </li>
+<li>
+ There are plenty of <a href="#resources">unit testing resources</a>
+ on the web.
+ </li>
+</ul>
+<div class="content">
+ <p><a class="target" name="summary"><h2>What is SimpleTest?</h2></a></p>
+ <p>
+ The heart of SimpleTest is a testing framework built around
+ test case classes.
+ These are written as extensions of base test case classes,
+ each extended with methods that actually contain test code.
+ Top level test scripts then invoke the <span class="new_code">run()</span>
+ methods on every one of these test cases in order.
+ Each test method is written to invoke various assertions that
+ the developer expects to be true such as
+ <span class="new_code">assertEqual()</span>.
+ If the expectation is correct, then a successful result is dispatched to the
+ observing test reporter, but any failure triggers an alert
+ and a description of the mismatch.
+ </p>
+ <p>
+ A <a href="unit_test_documentation.html">test case</a> looks like this...
+<pre>
+&lt;?php
+require_once('simpletest/autorun.php');
+
+class <strong>MyTestCase</strong> extends UnitTestCase {
+ <strong>
+ function testCreatedLogFile() {
+ $log = &amp;new Log('my.log');
+ $log-&gt;message('Hello');
+ $this-&gt;assertTrue(file_exists('my.log'));
+ }</strong>
+}
+?&gt;
+</pre>
+ </p>
+ <p>
+ These tools are designed for the developer.
+ Tests are written in the PHP language itself more or less
+ as the application itself is built.
+ The advantage of using PHP itself as the testing language is that
+ there are no new languages to learn, testing can start straight away,
+ and the developer can test any part of the code.
+ Basically, all parts that can be accessed by the application code can also be
+ accessed by the test code, if they are in the same programming language.
+ </p>
+ <p>
+ The simplest type of test case is the
+ <a href="unit_tester_documentation.html">UnitTestCase</a>.
+ This class of test case includes standard tests for equality,
+ references and pattern matching.
+ All these test the typical expectations of what you would
+ expect the result of a function or method to be.
+ This is by far the most common type of test in the daily
+ routine of development, making up about 95% of test cases.
+ </p>
+ <p>
+ The top level task of a web application though is not to
+ produce correct output from its methods and objects, but
+ to generate web pages.
+ The <a href="web_tester_documentation.html">WebTestCase</a> class tests web
+ pages.
+ It simulates a web browser requesting a page, complete with
+ cookies, proxies, secure connections, authentication, forms, frames and most
+ navigation elements.
+ With this type of test case, the developer can assert that
+ information is present in the page and that forms and
+ sessions are handled correctly.
+ </p>
+ <p>
+ A <a href="web_tester_documentation.html">WebTestCase</a> looks like this...
+<pre>
+&lt;?php
+require_once('simpletest/autorun.php');
+require_once('simpletest/web_tester.php');
+
+class <strong>MySiteTest</strong> extends WebTestCase {
+ <strong>
+ function testHomePage() {
+ $this-&gt;get('http://www.my-site.com/index.php');
+ $this-&gt;assertTitle('My Home Page');
+ $this-&gt;clickLink('Contact');
+ $this-&gt;assertTitle('Contact me');
+ $this-&gt;assertPattern('/Email me at/');
+ }</strong>
+}
+?&gt;
+</pre>
+ </p>
+
+ <p><a class="target" name="features"><h2>Feature list</h2></a></p>
+ <p>
+ The following is a very rough outline of past and future features
+ and their expected point of release.
+ I am afraid it is liable to change without warning, as meeting the
+ milestones rather depends on time available.
+ Green stuff has been coded, but not necessarily released yet.
+ If you have a pressing need for a green but unreleased feature
+ then you should check-out the code from Sourceforge SVN directly.
+ <table>
+<thead>
+ <tr>
+<th>Feature</th>
+<th>Description</th>
+<th>Release</th>
+</tr>
+ </thead>
+<tbody>
+<tr>
+ <td>Unit test case</td>
+ <td>Core test case class and assertions</td>
+ <td style="color: green;">1.0</td>
+ </tr>
+ <tr>
+ <td>Html display</td>
+ <td>Simplest possible display</td>
+ <td style="color: green;">1.0</td>
+ </tr>
+ <tr>
+ <td>Autoloading of test cases</td>
+ <td>
+ Reading a file with test cases and loading them into a
+ group test automatically
+ </td>
+ <td style="color: green;">1.0</td>
+ </tr>
+ <tr>
+ <td>Mock objects</td>
+ <td>
+ Objects capable of simulating other objects removing
+ test dependencies
+ </td>
+ <td style="color: green;">1.0</td>
+ </tr>
+ <tr>
+ <td>Web test case</td>
+ <td>Allows link following and title tag matching</td>
+ <td style="color: green;">1.0</td>
+ </tr>
+ <tr>
+ <td>Partial mocks</td>
+ <td>
+ Mocking parts of a class for testing less than a class
+ or for complex simulations
+ </td>
+ <td style="color: green;">1.0</td>
+ </tr>
+ <tr>
+ <td>Web cookie handling</td>
+ <td>Correct handling of cookies when fetching pages</td>
+ <td style="color: green;">1.0</td>
+ </tr>
+ <tr>
+ <td>Following redirects</td>
+ <td>Page fetching automatically follows 300 redirects</td>
+ <td style="color: green;">1.0</td>
+ </tr>
+ <tr>
+ <td>Form parsing</td>
+ <td>Ability to submit simple forms and read default form values</td>
+ <td style="color: green;">1.0</td>
+ </tr>
+ <tr>
+ <td>Command line interface</td>
+ <td>Test display without the need of a web browser</td>
+ <td style="color: green;">1.0</td>
+ </tr>
+ <tr>
+ <td>Exposure of expectation classes</td>
+ <td>Can create precise tests with mocks as well as test cases</td>
+ <td style="color: green;">1.0</td>
+ </tr>
+ <tr>
+ <td>XML output and parsing</td>
+ <td>
+ Allows multi host testing and the integration of acceptance
+ testing extensions
+ </td>
+ <td style="color: green;">1.0</td>
+ </tr>
+ <tr>
+ <td>Browser component</td>
+ <td>
+ Exposure of lower level web browser interface for more
+ detailed test cases
+ </td>
+ <td style="color: green;">1.0</td>
+ </tr>
+ <tr>
+ <td>HTTP authentication</td>
+ <td>
+ Fetching protected web pages with basic authentication
+ only
+ </td>
+ <td style="color: green;">1.0</td>
+ </tr>
+ <tr>
+ <td>SSL support</td>
+ <td>Can connect to https: pages</td>
+ <td style="color: green;">1.0</td>
+ </tr>
+ <tr>
+ <td>Proxy support</td>
+ <td>Can connect via. common proxies</td>
+ <td style="color: green;">1.0</td>
+ </tr>
+ <tr>
+ <td>Frames support</td>
+ <td>Handling of frames in web test cases</td>
+ <td style="color: green;">1.0</td>
+ </tr>
+ <tr>
+ <td>File upload testing</td>
+ <td>Can simulate the input type file tag</td>
+ <td style="color: green;">1.0.1</td>
+ </tr>
+ <tr>
+ <td>Mocking interfaces</td>
+ <td>
+ Can generate mock objects to interfaces as well as classes
+ and class interfaces are carried for type hints
+ </td>
+ <td style="color: green;">1.0.1</td>
+ </tr>
+ <tr>
+ <td>Testing exceptions</td>
+ <td>Similar to testing PHP errors</td>
+ <td style="color: green;">1.0.1</td>
+ </tr>
+ <tr>
+ <td>HTML label support</td>
+ <td>Can access all controls using the visual label</td>
+ <td style="color: green;">1.0.1</td>
+ </tr>
+ <tr>
+ <td>Base tag support</td>
+ <td>Respects page base tag when clicking</td>
+ <td style="color: green;">1.0.1</td>
+ </tr>
+ <tr>
+ <td>PHP 5 E_STRICT compliant</td>
+ <td>PHP 5 only version that works with the E_STRICT error level</td>
+ <td style="color: red;">1.1</td>
+ </tr>
+ <tr>
+ <td>BDD style fixtures</td>
+ <td>Can import fixtures using a mixin like given() method</td>
+ <td style="color: red;">1.5</td>
+ </tr>
+ <tr>
+ <td>Reporting machinery enhancements</td>
+ <td>Improved message passing for better cooperation with IDEs</td>
+ <td style="color: red;">1.5</td>
+ </tr>
+ <tr>
+ <td>Fluent mock interface</td>
+ <td>More flexible and concise mock objects</td>
+ <td style="color: red;">1.6</td>
+ </tr>
+ <tr>
+ <td>Localisation</td>
+ <td>Messages abstracted and code generated</td>
+ <td style="color: red;">1.6</td>
+ </tr>
+ <tr>
+ <td>CSS selectors</td>
+ <td>HTML content can be examined using CSS selectors</td>
+ <td style="color: red;">1.7</td>
+ </tr>
+ <tr>
+ <td>HTML table assertions</td>
+ <td>Can match HTML or table elements to expectations</td>
+ <td style="color: red;">1.7</td>
+ </tr>
+ <tr>
+ <td>Unified acceptance testing model</td>
+ <td>Content searchable through selectors combined with expectations</td>
+ <td style="color: red;">1.7</td>
+ </tr>
+ <tr>
+ <td>DatabaseTestCase</td>
+ <td>SQL selectors and DB drivers</td>
+ <td style="color: red;">1.7</td>
+ </tr>
+ <tr>
+ <td>IFrame support</td>
+ <td>Reads IFrame content that can be refreshed</td>
+ <td style="color: red;">1.8</td>
+ </tr>
+ <tr>
+ <td>Alternate HTML parsers</td>
+ <td>Can detect compiled parsers for performance improvements</td>
+ <td style="color: red;">1.8</td>
+ </tr>
+ <tr>
+ <td>Integrated Selenium support</td>
+ <td>Easy to use built in Selenium driver and tutorial</td>
+ <td style="color: red;">1.9</td>
+ </tr>
+ <tr>
+ <td>Code coverage</td>
+ <td>Reports using the bundled tool when using XDebug</td>
+ <td style="color: red;">1.9</td>
+ </tr>
+ <tr>
+ <td>Deprecation of old methods</td>
+ <td>Simpler interface for SimpleTest2</td>
+ <td style="color: red;">2.0</td>
+ </tr>
+ <tr>
+ <td>Javascript suport</td>
+ <td>Use of PECL module to add Javascript to the native browser</td>
+ <td style="color: red;">3.0</td>
+ </tr>
+ </tbody>
+</table>
+ PHP5 migraton will start straight after the version 1.0.1 series,
+ whereupon only PHP 5.1+ will be supported.
+ SimpleTest is currently compatible with PHP 5, but will not
+ make use of all of the new features until version 1.1.
+ </p>
+
+ <p><a class="target" name="resources"><h2>Web resources for testing</h2></a></p>
+ <p>
+ Process is at least as important as tools.
+ The type of process that makes the heaviest use of a developer's
+ testing tool is of course
+ <a href="http://www.extremeprogramming.org/">Extreme Programming</a>.
+ This is one of the
+ <a href="http://www.agilealliance.com/articles/index">Agile Methodologies</a>
+ which combine various practices to "flatten the cost curve" of software development.
+ More extreme still is <a href="http://www.testdriven.com/modules/news/">Test Driven Development</a>,
+ where you very strictly adhere to the rule of no coding until you have a test.
+ If you're more of a planner, or believe that experience trumps evolution,
+ you may prefer the
+ <a href="http://www.therationaledge.com/content/dec_01/f_spiritOfTheRUP_pk.html">RUP</a> approach.
+ I haven't tried it, but even I can see that you will need test tools (see figure 9).
+ </p>
+ <p>
+ Most unit testers clone <a href="http://www.junit.org/">JUnit</a> to some degree,
+ as far as the interface at least. There is a wealth of information on the
+ JUnit site including the
+ <a href="http://junit.sourceforge.net/doc/faq/faq.htm">FAQ</a>
+ which contains plenty of general advice on testing.
+ Once you get bitten by the bug you will certainly appreciate the phrase
+ <a href="http://junit.sourceforge.net/doc/testinfected/testing.htm">test infected</a>
+ coined by Eric Gamma.
+ If you are still reviewing which unit tester to use you can find pretty complete
+ lists from
+ <a href="http://en.wikipedia.org/wiki/List_of_unit_testing_frameworks">Wikipedia</a>,
+ <a href="http://www.testingfaqs.org/t-unit.html">Software testing FAQ</a>,
+ and <a href="http://www.opensourcetesting.org/functional.php">Open source testing</a>.
+ </p>
+ <p>
+ There is still very little material on using mock objects, which is a shame
+ as unit testing without them is a lot more work.
+ The <a href="http://www.sidewize.com/company/mockobjects.pdf">original mock objects paper</a>
+ is very Java focused, but still worth a read.
+ The most authoritive sources are probably
+ <a href="http://mockobjects.com">the original mock objects site</a> and
+ <a href="http://jmock.org/">JMock</a>.
+ Java centric, but tucked away in PDFs they contain some deep knowledge on using mocks from the
+ extended experience of the concept inventors.
+ As a new technology there are plenty of discussions and debate on how to use mocks,
+ often on Wikis such as
+ <a href="http://xpdeveloper.com/cgi-bin/oldwiki.cgi?MockObjects">Extreme Tuesday</a>
+ or <a href="http://www.mockobjects.com/MocksObjectsPaper.html">www.mockobjects.com</a>
+ or <a href="http://c2.com/cgi/wiki?MockObject">the original C2 Wiki</a>.
+ Injecting mocks into a class is the main area of debate for which this
+ <a href="http://www-106.ibm.com/developerworks/java/library/j-mocktest.html">paper on IBM</a>
+ makes a good starting point.
+ </p>
+ <p>
+ There are plenty of web testing tools, but the scriptable ones
+ are mostly are written in Java and
+ tutorials and advice are rather thin on the ground.
+ The only hope is to look at the documentation for
+ <a href="http://httpunit.sourceforge.net/">HTTPUnit</a>,
+ <a href="http://htmlunit.sourceforge.net/">HTMLUnit</a>
+ or <a href="http://jwebunit.sourceforge.net/">JWebUnit</a> and hope for clues.
+ There are some XML driven test frameworks, but again most
+ require Java to run.
+ </p>
+ <p>
+ Most significant is a new generation of tools that run directly in the web browser
+ are now available.
+ These include
+ <a href="http://www.openqa.org/selenium/">Selenium</a> and
+ <a href="http://wtr.rubyforge.org/">Watir</a>.
+ They are non-trivial to set up and slow to run, but can essentially test anything.
+ As SimpleTest does not support JavaScript you would probably
+ have to look at these tools anyway if you have highly dynamic
+ pages.
+ </p>
+
+ </div>
+ References and related information...
+ <ul>
+<li>
+ <a href="unit_test_documentation.html">Documentation for SimpleTest</a>.
+ </li>
+<li>
+ <a href="http://www.lastcraft.com/first_test_tutorial.php">How to write PHP test cases</a>
+ is a fairly advanced tutorial.
+ </li>
+<li>
+ <a href="http://simpletest.org/api/">SimpleTest API</a> from phpdoc.
+ </li>
+</ul>
+<div class="menu_back"><div class="menu">
+<a href="index.html">SimpleTest</a>
+ |
+ <span class="chosen">Overview</span>
+ |
+ <a href="unit_test_documentation.html">Unit tester</a>
+ |
+ <a href="group_test_documentation.html">Group tests</a>
+ |
+ <a href="mock_objects_documentation.html">Mock objects</a>
+ |
+ <a href="partial_mocks_documentation.html">Partial mocks</a>
+ |
+ <a href="reporter_documentation.html">Reporting</a>
+ |
+ <a href="expectation_documentation.html">Expectations</a>
+ |
+ <a href="web_tester_documentation.html">Web tester</a>
+ |
+ <a href="form_testing_documentation.html">Testing forms</a>
+ |
+ <a href="authentication_documentation.html">Authentication</a>
+ |
+ <a href="browser_documentation.html">Scriptable browser</a>
+</div></div>
+<div class="copyright">
+ Copyright<br>Marcus Baker 2006
+ </div>
+</body>
+</html>
diff --git a/site/vendors/simpletest/docs/en/partial_mocks_documentation.html b/site/vendors/simpletest/docs/en/partial_mocks_documentation.html
new file mode 100644
index 0000000..4cae18c
--- /dev/null
+++ b/site/vendors/simpletest/docs/en/partial_mocks_documentation.html
@@ -0,0 +1,445 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>SimpleTest for PHP partial mocks documentation</title>
+<link rel="stylesheet" type="text/css" href="docs.css" title="Styles">
+</head>
+<body>
+<div class="menu_back"><div class="menu">
+<a href="index.html">SimpleTest</a>
+ |
+ <a href="overview.html">Overview</a>
+ |
+ <a href="unit_test_documentation.html">Unit tester</a>
+ |
+ <a href="group_test_documentation.html">Group tests</a>
+ |
+ <a href="mock_objects_documentation.html">Mock objects</a>
+ |
+ <span class="chosen">Partial mocks</span>
+ |
+ <a href="reporter_documentation.html">Reporting</a>
+ |
+ <a href="expectation_documentation.html">Expectations</a>
+ |
+ <a href="web_tester_documentation.html">Web tester</a>
+ |
+ <a href="form_testing_documentation.html">Testing forms</a>
+ |
+ <a href="authentication_documentation.html">Authentication</a>
+ |
+ <a href="browser_documentation.html">Scriptable browser</a>
+</div></div>
+<h1>Partial mock objects documentation</h1>
+ This page...
+ <ul>
+<li>
+ <a href="#inject">The mock injection problem</a>.
+ </li>
+<li>
+ Moving creation to a <a href="#creation">protected factory</a> method.
+ </li>
+<li>
+ <a href="#partial">Partial mocks</a> generate subclasses.
+ </li>
+<li>
+ Partial mocks <a href="#less">test less than a class</a>.
+ </li>
+</ul>
+<div class="content">
+
+ <p>
+ A partial mock is simply a pattern to alleviate a specific problem
+ in testing with mock objects,
+ that of getting mock objects into tight corners.
+ It's quite a limited tool and possibly not even a good idea.
+ It is included with SimpleTest because I have found it useful
+ on more than one occasion and has saved a lot of work at that point.
+ </p>
+
+ <p><a class="target" name="inject"><h2>The mock injection problem</h2></a></p>
+ <p>
+ When one object uses another it is very simple to just pass a mock
+ version in already set up with its expectations.
+ Things are rather tricker if one object creates another and the
+ creator is the one you want to test.
+ This means that the created object should be mocked, but we can
+ hardly tell our class under test to create a mock instead.
+ The tested class doesn't even know it is running inside a test
+ after all.
+ </p>
+ <p>
+ For example, suppose we are building a telnet client and it
+ needs to create a network socket to pass its messages.
+ The connection method might look something like...
+<pre>
+<strong>&lt;?php
+require_once('socket.php');
+
+class Telnet {
+ ...
+ function &amp;connect($ip, $port, $username, $password) {
+ $socket = &amp;new Socket($ip, $port);
+ $socket-&gt;read( ... );
+ ...
+ }
+}
+?&gt;</strong>
+</pre>
+ We would really like to have a mock object version of the socket
+ here, what can we do?
+ </p>
+ <p>
+ The first solution is to pass the socket in as a parameter,
+ forcing the creation up a level.
+ Having the client handle this is actually a very good approach
+ if you can manage it and should lead to factoring the creation from
+ the doing.
+ In fact, this is one way in which testing with mock objects actually
+ forces you to code more tightly focused solutions.
+ They improve your programming.
+ </p>
+ <p>
+ Here this would be...
+<pre>
+&lt;?php
+require_once('socket.php');
+
+class Telnet {
+ ...
+ <strong>function &amp;connect(&amp;$socket, $username, $password) {
+ $socket-&gt;read( ... );
+ ...
+ }</strong>
+}
+?&gt;
+</pre>
+ This means that the test code is typical for a test involving
+ mock objects.
+<pre>
+class TelnetTest extends UnitTestCase {
+ ...
+ function testConnection() {<strong>
+ $socket = &amp;new MockSocket($this);
+ ...
+ $telnet = &amp;new Telnet();
+ $telnet-&gt;connect($socket, 'Me', 'Secret');
+ ...</strong>
+ }
+}
+</pre>
+ It is pretty obvious though that one level is all you can go.
+ You would hardly want your top level application creating
+ every low level file, socket and database connection ever
+ needed.
+ It wouldn't know the constructor parameters anyway.
+ </p>
+ <p>
+ The next simplest compromise is to have the created object passed
+ in as an optional parameter...
+<pre>
+&lt;?php
+require_once('socket.php');
+
+class Telnet {
+ ...<strong>
+ function &amp;connect($ip, $port, $username, $password, $socket = false) {
+ if (!$socket) {
+ $socket = &amp;new Socket($ip, $port);
+ }
+ $socket-&gt;read( ... );</strong>
+ ...
+ return $socket;
+ }
+}
+?&gt;
+</pre>
+ For a quick solution this is usually good enough.
+ The test now looks almost the same as if the parameter
+ was formally passed...
+<pre>
+class TelnetTest extends UnitTestCase {
+ ...
+ function testConnection() {<strong>
+ $socket = &amp;new MockSocket($this);
+ ...
+ $telnet = &amp;new Telnet();
+ $telnet-&gt;connect('127.0.0.1', 21, 'Me', 'Secret', &amp;$socket);
+ ...</strong>
+ }
+}
+</pre>
+ The problem with this approach is its untidiness.
+ There is test code in the main class and parameters passed
+ in the test case that are never used.
+ This is a quick and dirty approach, but nevertheless effective
+ in most situations.
+ </p>
+ <p>
+ The next method is to pass in a factory object to do the creation...
+<pre>
+&lt;?php
+require_once('socket.php');
+
+class Telnet {<strong>
+ function Telnet(&amp;$network) {
+ $this-&gt;_network = &amp;$network;
+ }</strong>
+ ...
+ function &amp;connect($ip, $port, $username, $password) {<strong>
+ $socket = &amp;$this-&gt;_network-&gt;createSocket($ip, $port);
+ $socket-&gt;read( ... );</strong>
+ ...
+ return $socket;
+ }
+}
+?&gt;
+</pre>
+ This is probably the most highly factored answer as creation
+ is now moved into a small specialist class.
+ The networking factory can now be tested separately, but mocked
+ easily when we are testing the telnet class...
+<pre>
+class TelnetTest extends UnitTestCase {
+ ...
+ function testConnection() {<strong>
+ $socket = &amp;new MockSocket($this);
+ ...
+ $network = &amp;new MockNetwork($this);
+ $network-&gt;setReturnReference('createSocket', $socket);
+ $telnet = &amp;new Telnet($network);
+ $telnet-&gt;connect('127.0.0.1', 21, 'Me', 'Secret');
+ ...</strong>
+ }
+}
+</pre>
+ The downside is that we are adding a lot more classes to the
+ library.
+ Also we are passing a lot of factories around which will
+ make the code a little less intuitive.
+ The most flexible solution, but the most complex.
+ </p>
+ <p>
+ Is there a middle ground?
+ </p>
+
+ <p><a class="target" name="creation"><h2>Protected factory method</h2></a></p>
+ <p>
+ There is a way we can circumvent the problem without creating
+ any new application classes, but it involves creating a subclass
+ when we do the actual testing.
+ Firstly we move the socket creation into its own method...
+<pre>
+&lt;?php
+require_once('socket.php');
+
+class Telnet {
+ ...
+ function &amp;connect($ip, $port, $username, $password) {<strong>
+ $socket = &amp;$this-&gt;_createSocket($ip, $port);</strong>
+ $socket-&gt;read( ... );
+ ...
+ }<strong>
+
+ function &amp;_createSocket($ip, $port) {
+ return new Socket($ip, $port);
+ }</strong>
+}
+?&gt;
+</pre>
+ This is the only change we make to the application code.
+ </p>
+ <p>
+ For the test case we have to create a subclass so that
+ we can intercept the socket creation...
+<pre>
+<strong>class TelnetTestVersion extends Telnet {
+ var $_mock;
+
+ function TelnetTestVersion(&amp;$mock) {
+ $this-&gt;_mock = &amp;$mock;
+ $this-&gt;Telnet();
+ }
+
+ function &amp;_createSocket() {
+ return $this-&gt;_mock;
+ }
+}</strong>
+</pre>
+ Here I have passed the mock in the constructor, but a
+ setter would have done just as well.
+ Note that the mock was set into the object variable
+ before the constructor was chained.
+ This is necessary in case the constructor calls
+ <span class="new_code">connect()</span>.
+ Otherwise it could get a null value from
+ <span class="new_code">_createSocket()</span>.
+ </p>
+ <p>
+ After the completion of all of this extra work the
+ actual test case is fairly easy.
+ We just test our new class instead...
+<pre>
+class TelnetTest extends UnitTestCase {
+ ...
+ function testConnection() {<strong>
+ $socket = &amp;new MockSocket($this);
+ ...
+ $telnet = &amp;new TelnetTestVersion($socket);
+ $telnet-&gt;connect('127.0.0.1', 21, 'Me', 'Secret');
+ ...</strong>
+ }
+}
+</pre>
+ The new class is very simple of course.
+ It just sets up a return value, rather like a mock.
+ It would be nice if it also checked the incoming parameters
+ as well.
+ Just like a mock.
+ It seems we are likely to do this often, can
+ we automate the subclass creation?
+ </p>
+
+ <p><a class="target" name="partial"><h2>A partial mock</h2></a></p>
+ <p>
+ Of course the answer is "yes" or I would have stopped writing
+ this by now!
+ The previous test case was a lot of work, but we can
+ generate the subclass using a similar approach to the mock objects.
+ </p>
+ <p>
+ Here is the partial mock version of the test...
+<pre>
+<strong>Mock::generatePartial(
+ 'Telnet',
+ 'TelnetTestVersion',
+ array('_createSocket'));</strong>
+
+class TelnetTest extends UnitTestCase {
+ ...
+ function testConnection() {<strong>
+ $socket = &amp;new MockSocket($this);
+ ...
+ $telnet = &amp;new TelnetTestVersion($this);
+ $telnet-&gt;setReturnReference('_createSocket', $socket);
+ $telnet-&gt;Telnet();
+ $telnet-&gt;connect('127.0.0.1', 21, 'Me', 'Secret');
+ ...</strong>
+ }
+}
+</pre>
+ The partial mock is a subclass of the original with
+ selected methods "knocked out" with test
+ versions.
+ The <span class="new_code">generatePartial()</span> call
+ takes three parameters: the class to be subclassed,
+ the new test class name and a list of methods to mock.
+ </p>
+ <p>
+ Instantiating the resulting objects is slightly tricky.
+ The only constructor parameter of a partial mock is
+ the unit tester reference.
+ As with the normal mock objects this is needed for sending
+ test results in response to checked expectations.
+ </p>
+ <p>
+ The original constructor is not run yet.
+ This is necessary in case the constructor is going to
+ make use of the as yet unset mocked methods.
+ We set any return values at this point and then run the
+ constructor with its normal parameters.
+ This three step construction of "new", followed
+ by setting up the methods, followed by running the constructor
+ proper is what distinguishes the partial mock code.
+ </p>
+ <p>
+ Apart from construction, all of the mocked methods have
+ the same features as mock objects and all of the unmocked
+ methods behave as before.
+ We can set expectations very easily...
+<pre>
+class TelnetTest extends UnitTestCase {
+ ...
+ function testConnection() {
+ $socket = &amp;new MockSocket($this);
+ ...
+ $telnet = &amp;new TelnetTestVersion($this);
+ $telnet-&gt;setReturnReference('_createSocket', $socket);<strong>
+ $telnet-&gt;expectOnce('_createSocket', array('127.0.0.1', 21));</strong>
+ $telnet-&gt;Telnet();
+ $telnet-&gt;connect('127.0.0.1', 21, 'Me', 'Secret');
+ ...<strong>
+ $telnet-&gt;tally();</strong>
+ }
+}
+</pre>
+ </p>
+
+ <p><a class="target" name="less"><h2>Testing less than a class</h2></a></p>
+ <p>
+ The mocked out methods don't have to be factory methods,
+ they could be any sort of method.
+ In this way partial mocks allow us to take control of any part of
+ a class except the constructor.
+ We could even go as far as to mock every method
+ except one we actually want to test.
+ </p>
+ <p>
+ This last situation is all rather hypothetical, as I haven't
+ tried it.
+ I am open to the possibility, but a little worried that
+ forcing object granularity may be better for the code quality.
+ I personally use partial mocks as a way of overriding creation
+ or for occasional testing of the TemplateMethod pattern.
+ </p>
+ <p>
+ It's all going to come down to the coding standards of your
+ project to decide which mechanism you use.
+ </p>
+
+ </div>
+ References and related information...
+ <ul>
+<li>
+ SimpleTest project page on <a href="http://sourceforge.net/projects/simpletest/">SourceForge</a>.
+ </li>
+<li>
+ <a href="http://simpletest.org/api/">Full API for SimpleTest</a>
+ from the PHPDoc.
+ </li>
+<li>
+ The protected factory is described in
+ <a href="http://www-106.ibm.com/developerworks/java/library/j-mocktest.html">this paper from IBM</a>.
+ This is the only formal comment I have seen on this problem.
+ </li>
+</ul>
+<div class="menu_back"><div class="menu">
+<a href="index.html">SimpleTest</a>
+ |
+ <a href="overview.html">Overview</a>
+ |
+ <a href="unit_test_documentation.html">Unit tester</a>
+ |
+ <a href="group_test_documentation.html">Group tests</a>
+ |
+ <a href="mock_objects_documentation.html">Mock objects</a>
+ |
+ <span class="chosen">Partial mocks</span>
+ |
+ <a href="reporter_documentation.html">Reporting</a>
+ |
+ <a href="expectation_documentation.html">Expectations</a>
+ |
+ <a href="web_tester_documentation.html">Web tester</a>
+ |
+ <a href="form_testing_documentation.html">Testing forms</a>
+ |
+ <a href="authentication_documentation.html">Authentication</a>
+ |
+ <a href="browser_documentation.html">Scriptable browser</a>
+</div></div>
+<div class="copyright">
+ Copyright<br>Marcus Baker 2006
+ </div>
+</body>
+</html>
diff --git a/site/vendors/simpletest/docs/en/reporter_documentation.html b/site/vendors/simpletest/docs/en/reporter_documentation.html
new file mode 100644
index 0000000..87c89e4
--- /dev/null
+++ b/site/vendors/simpletest/docs/en/reporter_documentation.html
@@ -0,0 +1,519 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>SimpleTest for PHP test runner and display documentation</title>
+<link rel="stylesheet" type="text/css" href="docs.css" title="Styles">
+</head>
+<body>
+<div class="menu_back"><div class="menu">
+<a href="index.html">SimpleTest</a>
+ |
+ <a href="overview.html">Overview</a>
+ |
+ <a href="unit_test_documentation.html">Unit tester</a>
+ |
+ <a href="group_test_documentation.html">Group tests</a>
+ |
+ <a href="mock_objects_documentation.html">Mock objects</a>
+ |
+ <a href="partial_mocks_documentation.html">Partial mocks</a>
+ |
+ <span class="chosen">Reporting</span>
+ |
+ <a href="expectation_documentation.html">Expectations</a>
+ |
+ <a href="web_tester_documentation.html">Web tester</a>
+ |
+ <a href="form_testing_documentation.html">Testing forms</a>
+ |
+ <a href="authentication_documentation.html">Authentication</a>
+ |
+ <a href="browser_documentation.html">Scriptable browser</a>
+</div></div>
+<h1>Test reporter documentation</h1>
+ This page...
+ <ul>
+<li>
+ Displaying <a href="#html">results in HTML</a>
+ </li>
+<li>
+ Displaying and <a href="#other">reporting results</a>
+ in other formats
+ </li>
+<li>
+ Using <a href="#cli">SimpleTest from the command line</a>
+ </li>
+<li>
+ Using <a href="#xml">Using XML</a> for remote testing
+ </li>
+</ul>
+<div class="content">
+
+ <p>
+ SimpleTest pretty much follows the MVC pattern
+ (Model-View-Controller).
+ The reporter classes are the view and the model is your
+ test cases and their hiearchy.
+ The controller is mostly hidden from the user of
+ SimpleTest unless you want to change how the test cases
+ are actually run, in which case it is possible to
+ override the runner objects from within the test case.
+ As usual with MVC, the controller is mostly undefined
+ and there are other places to control the test run.
+ </p>
+
+ <p><a class="target" name="html"><h2>Reporting results in HTML</h2></a></p>
+ <p>
+ The default test display is minimal in the extreme.
+ It reports success and failure with the conventional red and
+ green bars and shows a breadcrumb trail of test groups
+ for every failed assertion.
+ Here's a fail...
+ <div class="demo">
+ <h1>File test</h1>
+ <span class="fail">Fail</span>: createnewfile-&gt;True assertion failed.<br>
+ <div style="padding: 8px; margin-top: 1em; background-color: red; color: white;">1/1 test cases complete.
+ <strong>0</strong> passes, <strong>1</strong> fails and <strong>0</strong> exceptions.</div>
+ </div>
+ And here all tests passed...
+ <div class="demo">
+ <h1>File test</h1>
+ <div style="padding: 8px; margin-top: 1em; background-color: green; color: white;">1/1 test cases complete.
+ <strong>1</strong> passes, <strong>0</strong> fails and <strong>0</strong> exceptions.</div>
+ </div>
+ The good news is that there are several points in the display
+ hiearchy for subclassing.
+ </p>
+ <p>
+ For web page based displays there is the
+ <span class="new_code">HtmlReporter</span> class with the following
+ signature...
+<pre>
+class HtmlReporter extends SimpleReporter {
+ public HtmlReporter($encoding) { ... }
+ public makeDry(boolean $is_dry) { ... }
+ public void paintHeader(string $test_name) { ... }
+ public void sendNoCacheHeaders() { ... }
+ public void paintFooter(string $test_name) { ... }
+ public void paintGroupStart(string $test_name, integer $size) { ... }
+ public void paintGroupEnd(string $test_name) { ... }
+ public void paintCaseStart(string $test_name) { ... }
+ public void paintCaseEnd(string $test_name) { ... }
+ public void paintMethodStart(string $test_name) { ... }
+ public void paintMethodEnd(string $test_name) { ... }
+ public void paintFail(string $message) { ... }
+ public void paintPass(string $message) { ... }
+ public void paintError(string $message) { ... }
+ public void paintException(string $message) { ... }
+ public void paintMessage(string $message) { ... }
+ public void paintFormattedMessage(string $message) { ... }
+ protected string _getCss() { ... }
+ public array getTestList() { ... }
+ public integer getPassCount() { ... }
+ public integer getFailCount() { ... }
+ public integer getExceptionCount() { ... }
+ public integer getTestCaseCount() { ... }
+ public integer getTestCaseProgress() { ... }
+}
+</pre>
+ Here is what some of these methods mean. First the display methods
+ that you will probably want to override...
+ <ul class="api">
+ <li>
+ <span class="new_code">HtmlReporter(string $encoding)</span><br>
+ is the constructor.
+ Note that the unit test sets up the link to the display
+ rather than the other way around.
+ The display is a mostly passive receiver of test events.
+ This allows easy adaption of the display for other test
+ systems beside unit tests, such as monitoring servers.
+ The encoding is the character encoding you wish to
+ display the test output in.
+ In order to correctly render debug output when
+ using the web tester, this should match the encoding
+ of the site you are trying to test.
+ The available character set strings are described in
+ the PHP <a href="http://www.php.net/manual/en/function.htmlentities.php">html_entities()</a>
+ function.
+ </li>
+ <li>
+ <span class="new_code">void paintHeader(string $test_name)</span><br>
+ is called once at the very start of the test when the first
+ start event arrives.
+ The first start event is usually delivered by the top level group
+ test and so this is where <span class="new_code">$test_name</span>
+ comes from.
+ It paints the page titles, CSS, body tag, etc.
+ It returns nothing (<span class="new_code">void</span>).
+ </li>
+ <li>
+ <span class="new_code">void paintFooter(string $test_name)</span><br>
+ Called at the very end of the test to close any tags opened
+ by the page header.
+ By default it also displays the red/green bar and the final
+ count of results.
+ Actually the end of the test happens when a test end event
+ comes in with the same name as the one that started it all
+ at the same level.
+ The tests nest you see.
+ Closing the last test finishes the display.
+ </li>
+ <li>
+ <span class="new_code">void paintMethodStart(string $test_name)</span><br>
+ is called at the start of each test method.
+ The name normally comes from method name.
+ The other test start events behave the same way except
+ that the group test one tells the reporter how large
+ it is in number of held test cases.
+ This is so that the reporter can display a progress bar
+ as the runner churns through the test cases.
+ </li>
+ <li>
+ <span class="new_code">void paintMethodEnd(string $test_name)</span><br>
+ backs out of the test started with the same name.
+ </li>
+ <li>
+ <span class="new_code">void paintFail(string $message)</span><br>
+ paints a failure.
+ By default it just displays the word fail, a breadcrumbs trail
+ showing the current test nesting and the message issued by
+ the assertion.
+ </li>
+ <li>
+ <span class="new_code">void paintPass(string $message)</span><br>
+ by default does nothing.
+ </li>
+ <li>
+ <span class="new_code">string _getCss()</span><br>
+ Returns the CSS styles as a string for the page header
+ method.
+ Additional styles have to be appended here if you are
+ not overriding the page header.
+ You will want to use this method in an overriden page header
+ if you want to include the original CSS.
+ </li>
+ </ul>
+ There are also some accessors to get information on the current
+ state of the test suite.
+ Use these to enrich the display...
+ <ul class="api">
+ <li>
+ <span class="new_code">array getTestList()</span><br>
+ is the first convenience method for subclasses.
+ Lists the current nesting of the tests as a list
+ of test names.
+ The first, most deeply nested test, is first in the
+ list and the current test method will be last.
+ </li>
+ <li>
+ <span class="new_code">integer getPassCount()</span><br>
+ returns the number of passes chalked up so far.
+ Needed for the display at the end.
+ </li>
+ <li>
+ <span class="new_code">integer getFailCount()</span><br>
+ is likewise the number of fails so far.
+ </li>
+ <li>
+ <span class="new_code">integer getExceptionCount()</span><br>
+ is likewise the number of errors so far.
+ </li>
+ <li>
+ <span class="new_code">integer getTestCaseCount()</span><br>
+ is the total number of test cases in the test run.
+ This includes the grouping tests themselves.
+ </li>
+ <li>
+ <span class="new_code">integer getTestCaseProgress()</span><br>
+ is the number of test cases completed so far.
+ </li>
+ </ul>
+ One simple modification is to get the HtmlReporter to display
+ the passes as well as the failures and errors...
+<pre>
+<strong>class ShowPasses extends HtmlReporter {
+
+ function paintPass($message) {
+ parent::paintPass($message);
+ print "&amp;&lt;span class=\"pass\"&gt;Pass&lt;/span&gt;: ";
+ $breadcrumb = $this-&gt;getTestList();
+ array_shift($breadcrumb);
+ print implode("-&amp;gt;", $breadcrumb);
+ print "-&amp;gt;$message&lt;br /&gt;\n";
+ }
+
+ function _getCss() {
+ return parent::_getCss() . ' .pass { color: green; }';
+ }
+}</strong>
+</pre>
+ </p>
+ <p>
+ One method that was glossed over was the <span class="new_code">makeDry()</span>
+ method.
+ If you run this method, with no parameters, on the reporter
+ before the test suite is run no actual test methods
+ will be called.
+ You will still get the events of entering and leaving the
+ test methods and test cases, but no passes or failures etc,
+ because the test code will not actually be executed.
+ </p>
+ <p>
+ The reason for this is to allow for more sophistcated
+ GUI displays that allow the selection of individual test
+ cases.
+ In order to build a list of possible tests they need a
+ report on the test structure for drawing, say a tree view
+ of the test suite.
+ With a reporter set to dry run that just sends drawing events
+ this is easily accomplished.
+ </p>
+
+ <p><a class="target" name="other"><h2>Extending the reporter</h2></a></p>
+ <p>
+ Rather than simply modifying the existing display, you might want to
+ produce a whole new HTML look, or even generate text or XML.
+ Rather than override every method in
+ <span class="new_code">HtmlReporter</span> we can take one
+ step up the class hiearchy to <span class="new_code">SimpleReporter</span>
+ in the <em>simple_test.php</em> source file.
+ </p>
+ <p>
+ A do nothing display, a blank canvas for your own creation, would
+ be...
+<pre>
+<strong>require_once('simpletest/simple_test.php');</strong>
+
+class MyDisplay extends SimpleReporter {<strong>
+ </strong>
+ function paintHeader($test_name) {
+ }
+
+ function paintFooter($test_name) {
+ }
+
+ function paintStart($test_name, $size) {<strong>
+ parent::paintStart($test_name, $size);</strong>
+ }
+
+ function paintEnd($test_name, $size) {<strong>
+ parent::paintEnd($test_name, $size);</strong>
+ }
+
+ function paintPass($message) {<strong>
+ parent::paintPass($message);</strong>
+ }
+
+ function paintFail($message) {<strong>
+ parent::paintFail($message);</strong>
+ }
+}
+</pre>
+ No output would come from this class until you add it.
+ </p>
+
+ <p><a class="target" name="cli"><h2>The command line reporter</h2></a></p>
+ <p>
+ SimpleTest also ships with a minimal command line reporter.
+ The interface mimics JUnit to some extent, but paints the
+ failure messages as they arrive.
+ To use the command line reporter simply substitute it
+ for the HTML version...
+<pre>
+&lt;?php
+require_once('simpletest/unit_tester.php');
+require_once('simpletest/reporter.php');
+
+$test = &amp;new TestSuite('File test');
+$test-&gt;addTestFile('tests/file_test.php');
+$test-&gt;run(<strong>new TextReporter()</strong>);
+?&gt;
+</pre>
+ Then invoke the test suite from the command line...
+<pre class="shell">
+php file_test.php
+</pre>
+ You will need the command line version of PHP installed
+ of course.
+ A passing test suite looks like this...
+<pre class="shell">
+File test
+OK
+Test cases run: 1/1, Failures: 0, Exceptions: 0
+</pre>
+ A failure triggers a display like this...
+<pre class="shell">
+File test
+1) True assertion failed.
+ in createnewfile
+FAILURES!!!
+Test cases run: 1/1, Failures: 1, Exceptions: 0
+</pre>
+ </p>
+ <p>
+ One of the main reasons for using a command line driven
+ test suite is of using the tester as part of some automated
+ process.
+ To function properly in shell scripts the test script should
+ return a non-zero exit code on failure.
+ If a test suite fails the value <span class="new_code">false</span>
+ is returned from the <span class="new_code">SimpleTest::run()</span>
+ method.
+ We can use that result to exit the script with the desired return
+ code...
+<pre>
+&lt;?php
+require_once('simpletest/unit_tester.php');
+require_once('simpletest/reporter.php');
+
+$test = &amp;new TestSuite('File test');
+$test-&gt;addTestFile('tests/file_test.php');
+<strong>exit ($test-&gt;run(new TextReporter()) ? 0 : 1);</strong>
+?&gt;
+</pre>
+ Of course we don't really want to create two test scripts,
+ a command line one and a web browser one, for each test suite.
+ The command line reporter includes a method to sniff out the
+ run time environment...
+<pre>
+&lt;?php
+require_once('simpletest/unit_tester.php');
+require_once('simpletest/reporter.php');
+
+$test = &amp;new TestSuite('File test');
+$test-&gt;addTestFile('tests/file_test.php');
+<strong>if (TextReporter::inCli()) {</strong>
+ exit ($test-&gt;run(new TextReporter()) ? 0 : 1);
+<strong>}</strong>
+$test-&gt;run(new HtmlReporter());
+?&gt;
+</pre>
+ This is the form used within SimpleTest itself.
+ </p>
+
+ <p><a class="target" name="xml"><h2>Remote testing</h2></a></p>
+ <p>
+ SimpleTest ships with an <span class="new_code">XmlReporter</span> class
+ used for internal communication.
+ When run the output looks like...
+<pre class="shell">
+&lt;?xml version="1.0"?&gt;
+&lt;run&gt;
+ &lt;group size="4"&gt;
+ &lt;name&gt;Remote tests&lt;/name&gt;
+ &lt;group size="4"&gt;
+ &lt;name&gt;Visual test with 48 passes, 48 fails and 4 exceptions&lt;/name&gt;
+ &lt;case&gt;
+ &lt;name&gt;testofunittestcaseoutput&lt;/name&gt;
+ &lt;test&gt;
+ &lt;name&gt;testofresults&lt;/name&gt;
+ &lt;pass&gt;This assertion passed&lt;/pass&gt;
+ &lt;fail&gt;This assertion failed&lt;/fail&gt;
+ &lt;/test&gt;
+ &lt;test&gt;
+ ...
+ &lt;/test&gt;
+ &lt;/case&gt;
+ &lt;/group&gt;
+ &lt;/group&gt;
+&lt;/run&gt;
+</pre>
+ You can make use of this format with the parser
+ supplied as part of SimpleTest itself.
+ This is called <span class="new_code">SimpleTestXmlParser</span> and
+ resides in <em>xml.php</em> within the SimpleTest package...
+<pre>
+&lt;?php
+require_once('simpletest/xml.php');
+
+...
+$parser = &amp;new SimpleTestXmlParser(new HtmlReporter());
+$parser-&gt;parse($test_output);
+?&gt;
+</pre>
+ The <span class="new_code">$test_output</span> should be the XML format
+ from the XML reporter, and could come from say a command
+ line run of a test case.
+ The parser sends events to the reporter just like any
+ other test run.
+ There are some odd occasions where this is actually useful.
+ </p>
+ <p>
+ A problem with large test suites is thet they can exhaust
+ the default 8Mb memory limit on a PHP process.
+ By having the test groups output in XML and run in
+ separate processes, the output can be reparsed to
+ aggregate the results into a much smaller footprint top level
+ test.
+ </p>
+ <p>
+ Because the XML output can come from anywhere, this opens
+ up the possibility of aggregating test runs from remote
+ servers.
+ A test case already exists to do this within the SimpleTest
+ framework, but it is currently experimental...
+<pre>
+&lt;?php
+<strong>require_once('../remote.php');</strong>
+require_once('../reporter.php');
+
+$test_url = ...;
+$dry_url = ...;
+
+$test = &amp;new TestSuite('Remote tests');
+$test-&gt;addTestCase(<strong>new RemoteTestCase($test_url, $dry_url)</strong>);
+$test-&gt;run(new HtmlReporter());
+?&gt;
+</pre>
+ The <span class="new_code">RemoteTestCase</span> takes the actual location
+ of the test runner, basically a web page in XML format.
+ It also takes the URL of a reporter set to do a dry run.
+ This is so that progress can be reported upward correctly.
+ The <span class="new_code">RemoteTestCase</span> can be added to test suites
+ just like any other group test.
+ </p>
+
+ </div>
+ References and related information...
+ <ul>
+<li>
+ SimpleTest project page on <a href="http://sourceforge.net/projects/simpletest/">SourceForge</a>.
+ </li>
+<li>
+ SimpleTest download page on <a href="http://www.lastcraft.com/simple_test.php">LastCraft</a>.
+ </li>
+<li>
+ The <a href="http://simpletest.org/api/">developer's API for SimpleTest</a>
+ gives full detail on the classes and assertions available.
+ </li>
+</ul>
+<div class="menu_back"><div class="menu">
+<a href="index.html">SimpleTest</a>
+ |
+ <a href="overview.html">Overview</a>
+ |
+ <a href="unit_test_documentation.html">Unit tester</a>
+ |
+ <a href="group_test_documentation.html">Group tests</a>
+ |
+ <a href="mock_objects_documentation.html">Mock objects</a>
+ |
+ <a href="partial_mocks_documentation.html">Partial mocks</a>
+ |
+ <span class="chosen">Reporting</span>
+ |
+ <a href="expectation_documentation.html">Expectations</a>
+ |
+ <a href="web_tester_documentation.html">Web tester</a>
+ |
+ <a href="form_testing_documentation.html">Testing forms</a>
+ |
+ <a href="authentication_documentation.html">Authentication</a>
+ |
+ <a href="browser_documentation.html">Scriptable browser</a>
+</div></div>
+<div class="copyright">
+ Copyright<br>Marcus Baker 2006
+ </div>
+</body>
+</html>
diff --git a/site/vendors/simpletest/docs/en/unit_test_documentation.html b/site/vendors/simpletest/docs/en/unit_test_documentation.html
new file mode 100644
index 0000000..bc43c82
--- /dev/null
+++ b/site/vendors/simpletest/docs/en/unit_test_documentation.html
@@ -0,0 +1,431 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>SimpleTest for PHP regression test documentation</title>
+<link rel="stylesheet" type="text/css" href="docs.css" title="Styles">
+</head>
+<body>
+<div class="menu_back"><div class="menu">
+<a href="index.html">SimpleTest</a>
+ |
+ <a href="overview.html">Overview</a>
+ |
+ <span class="chosen">Unit tester</span>
+ |
+ <a href="group_test_documentation.html">Group tests</a>
+ |
+ <a href="mock_objects_documentation.html">Mock objects</a>
+ |
+ <a href="partial_mocks_documentation.html">Partial mocks</a>
+ |
+ <a href="reporter_documentation.html">Reporting</a>
+ |
+ <a href="expectation_documentation.html">Expectations</a>
+ |
+ <a href="web_tester_documentation.html">Web tester</a>
+ |
+ <a href="form_testing_documentation.html">Testing forms</a>
+ |
+ <a href="authentication_documentation.html">Authentication</a>
+ |
+ <a href="browser_documentation.html">Scriptable browser</a>
+</div></div>
+<h1>PHP Unit Test documentation</h1>
+ This page...
+ <ul>
+<li>
+ <a href="#unit">Unit test cases</a> and basic assertions.
+ </li>
+<li>
+ <a href="#extending_unit">Extending test cases</a> to
+ customise them for your own project.
+ </li>
+<li>
+ <a href="#running_unit">Running a single case</a> as
+ a single script.
+ </li>
+</ul>
+<div class="content">
+ <p><a class="target" name="unit"><h2>Unit test cases</h2></a></p>
+ <p>
+ The core system is a regression testing framework built around
+ test cases.
+ A sample test case looks like this...
+<pre>
+<strong>class FileTestCase extends UnitTestCase {
+}</strong>
+</pre>
+ Actual tests are added as methods in the test case whose names
+ by default start with the string "test" and
+ when the test case is invoked all such methods are run in
+ the order that PHP introspection finds them.
+ As many test methods can be added as needed.
+ </p>
+ <p>
+ For example...
+<pre>
+require_once('simpletest/autorun.php');
+require_once('../classes/writer.php');
+
+class FileTestCase extends UnitTestCase {
+ function FileTestCase() {
+ $this-&gt;UnitTestCase('File test');
+ }<strong>
+
+ function setUp() {
+ @unlink('../temp/test.txt');
+ }
+
+ function tearDown() {
+ @unlink('../temp/test.txt');
+ }
+
+ function testCreation() {
+ $writer = &amp;new FileWriter('../temp/test.txt');
+ $writer-&gt;write('Hello');
+ $this-&gt;assertTrue(file_exists('../temp/test.txt'), 'File created');
+ }</strong>
+}
+</pre>
+ The constructor is optional and usually omitted.
+ Without a name, the class name is taken as the name of the test case.
+ </p>
+ <p>
+ Our only test method at the moment is <span class="new_code">testCreation()</span>
+ where we check that a file has been created by our
+ <span class="new_code">Writer</span> object.
+ We could have put the <span class="new_code">unlink()</span>
+ code into this method as well, but by placing it in
+ <span class="new_code">setUp()</span> and
+ <span class="new_code">tearDown()</span> we can use it with
+ other test methods that we add.
+ </p>
+ <p>
+ The <span class="new_code">setUp()</span> method is run
+ just before each and every test method.
+ <span class="new_code">tearDown()</span> is run just after
+ each and every test method.
+ </p>
+ <p>
+ You can place some test case set up into the constructor to
+ be run once for all the methods in the test case, but
+ you risk test inteference that way.
+ This way is slightly slower, but it is safer.
+ Note that if you come from a JUnit background this will not
+ be the behaviour you are used to.
+ JUnit surprisingly reinstantiates the test case for each test
+ method to prevent such interference.
+ SimpleTest requires the end user to use <span class="new_code">setUp()</span>, but
+ supplies additional hooks for library writers.
+ </p>
+ <p>
+ The means of reporting test results (see below) are by a
+ visiting display class
+ that is notified by various <span class="new_code">assert...()</span>
+ methods.
+ Here is the full list for the <span class="new_code">UnitTestCase</span>
+ class, the default for SimpleTest...
+ <table><tbody>
+ <tr>
+<td><span class="new_code">assertTrue($x)</span></td>
+<td>Fail if $x is false</td>
+</tr>
+ <tr>
+<td><span class="new_code">assertFalse($x)</span></td>
+<td>Fail if $x is true</td>
+</tr>
+ <tr>
+<td><span class="new_code">assertNull($x)</span></td>
+<td>Fail if $x is set</td>
+</tr>
+ <tr>
+<td><span class="new_code">assertNotNull($x)</span></td>
+<td>Fail if $x not set</td>
+</tr>
+ <tr>
+<td><span class="new_code">assertIsA($x, $t)</span></td>
+<td>Fail if $x is not the class or type $t</td>
+</tr>
+ <tr>
+<td><span class="new_code">assertNotA($x, $t)</span></td>
+<td>Fail if $x is of the class or type $t</td>
+</tr>
+ <tr>
+<td><span class="new_code">assertEqual($x, $y)</span></td>
+<td>Fail if $x == $y is false</td>
+</tr>
+ <tr>
+<td><span class="new_code">assertNotEqual($x, $y)</span></td>
+<td>Fail if $x == $y is true</td>
+</tr>
+ <tr>
+<td><span class="new_code">assertWithinMargin($x, $y, $m)</span></td>
+<td>Fail if abs($x - $y) &lt; $m is false</td>
+</tr>
+ <tr>
+<td><span class="new_code">assertOutsideMargin($x, $y, $m)</span></td>
+<td>Fail if abs($x - $y) &lt; $m is true</td>
+</tr>
+ <tr>
+<td><span class="new_code">assertIdentical($x, $y)</span></td>
+<td>Fail if $x == $y is false or a type mismatch</td>
+</tr>
+ <tr>
+<td><span class="new_code">assertNotIdentical($x, $y)</span></td>
+<td>Fail if $x == $y is true and types match</td>
+</tr>
+ <tr>
+<td><span class="new_code">assertReference($x, $y)</span></td>
+<td>Fail unless $x and $y are the same variable</td>
+</tr>
+ <tr>
+<td><span class="new_code">assertClone($x, $y)</span></td>
+<td>Fail unless $x and $y are identical copies</td>
+</tr>
+ <tr>
+<td><span class="new_code">assertPattern($p, $x)</span></td>
+<td>Fail unless the regex $p matches $x</td>
+</tr>
+ <tr>
+<td><span class="new_code">assertNoPattern($p, $x)</span></td>
+<td>Fail if the regex $p matches $x</td>
+</tr>
+ <tr>
+<td><span class="new_code">expectError($x)</span></td>
+<td>Swallows any upcoming matching error</td>
+</tr>
+ <tr>
+<td><span class="new_code">assert($e)</span></td>
+<td>Fail on failed <a href="expectation_documentation.html">expectation</a> object $e</td>
+</tr>
+ </tbody></table>
+ All assertion methods can take an optional description as a
+ last parameter.
+ This is to label the displayed result with.
+ If omitted a default message is sent instead, which is usually
+ sufficient.
+ This default message can still be embedded in your own message
+ if you include "%s" within the string.
+ All the assertions return true on a pass or false on failure.
+ </p>
+ <p>
+ Some examples...
+<pre>
+$variable = null;
+<strong>$this-&gt;assertNull($variable, 'Should be cleared');</strong>
+</pre>
+ ...will pass and normally show no message.
+ If you have
+ <a href="http://www.lastcraft.com/display_subclass_tutorial.php">set up the tester to display passes</a>
+ as well then the message will be displayed as is.
+<pre>
+<strong>$this-&gt;assertIdentical(0, false, 'Zero is not false [%s]');</strong>
+</pre>
+ This will fail as it performs a type
+ check, as well as a comparison, between the two values.
+ The "%s" part is replaced by the default
+ error message that would have been shown if we had not
+ supplied our own.
+<pre>
+$a = 1;
+$b = $a;
+<strong>$this-&gt;assertReference($a, $b);</strong>
+</pre>
+ Will fail as the variable <span class="new_code">$a</span> is a copy of <span class="new_code">$b</span>.
+<pre>
+<strong>$this-&gt;assertPattern('/hello/i', 'Hello world');</strong>
+</pre>
+ This will pass as using a case insensitive match the string
+ <span class="new_code">hello</span> is contained in <span class="new_code">Hello world</span>.
+<pre>
+<strong>$this-&gt;expectError();</strong>
+trigger_error('Catastrophe');
+</pre>
+ Here the check catches the "Catastrophe"
+ message without checking the text and passes.
+ This removes the error from the queue.
+<pre>
+<strong>$this-&gt;expectError('Catastrophe');</strong>
+trigger_error('Catastrophe');
+</pre>
+ The next error check tests not only the existence of the error,
+ but also the text which, here matches so another pass.
+ If any unchecked errors are left at the end of a test method then
+ an exception will be reported in the test.
+ </p>
+ <p>
+ Note that SimpleTest cannot catch compile time PHP errors.
+ </p>
+ <p>
+ The test cases also have some convenience methods for debugging
+ code or extending the suite...
+ <table><tbody>
+ <tr>
+<td><span class="new_code">setUp()</span></td>
+<td>Runs this before each test method</td>
+</tr>
+ <tr>
+<td><span class="new_code">tearDown()</span></td>
+<td>Runs this after each test method</td>
+</tr>
+ <tr>
+<td><span class="new_code">pass()</span></td>
+<td>Sends a test pass</td>
+</tr>
+ <tr>
+<td><span class="new_code">fail()</span></td>
+<td>Sends a test failure</td>
+</tr>
+ <tr>
+<td><span class="new_code">error()</span></td>
+<td>Sends an exception event</td>
+</tr>
+ <tr>
+<td><span class="new_code">signal($type, $payload)</span></td>
+<td>Sends a user defined message to the test reporter</td>
+</tr>
+ <tr>
+<td><span class="new_code">dump($var)</span></td>
+<td>Does a formatted <span class="new_code">print_r()</span> for quick and dirty debugging</td>
+</tr>
+ </tbody></table>
+ </p>
+
+ <p><a class="target" name="extending_unit"><h2>Extending test cases</h2></a></p>
+ <p>
+ Of course additional test methods can be added to create
+ specific types of test case, so as to extend framework...
+<pre>
+require_once('simpletest/autorun.php');
+<strong>
+class FileTester extends UnitTestCase {
+ function FileTester($name = false) {
+ $this-&gt;UnitTestCase($name);
+ }
+
+ function assertFileExists($filename, $message = '%s') {
+ $this-&gt;assertTrue(
+ file_exists($filename),
+ sprintf($message, 'File [$filename] existence check'));
+ }</strong>
+}
+</pre>
+ Here the SimpleTest library is held in a folder called
+ <em>simpletest</em> that is local.
+ Substitute your own path for this.
+ </p>
+ <p>
+ To prevent this test case being run accidently, it is
+ advisable to mark it as <span class="new_code">abstract</span>.
+ </p>
+ <p>
+ Alternatively you could add a
+ <span class="new_code">SimpleTestOptions::ignore('FileTester');</span>
+ directive in your code.
+ </p>
+ <p>
+ This new case can be now be inherited just like
+ a normal test case...
+<pre>
+class FileTestCase extends <strong>FileTester</strong> {
+
+ function setUp() {
+ @unlink('../temp/test.txt');
+ }
+
+ function tearDown() {
+ @unlink('../temp/test.txt');
+ }
+
+ function testCreation() {
+ $writer = &amp;new FileWriter('../temp/test.txt');
+ $writer-&gt;write('Hello');<strong>
+ $this-&gt;assertFileExists('../temp/test.txt');</strong>
+ }
+}
+</pre>
+ </p>
+ <p>
+ If you want a test case that does not have all of the
+ <span class="new_code">UnitTestCase</span> assertions,
+ only your own and a few basics,
+ you need to extend the <span class="new_code">SimpleTestCase</span>
+ class instead.
+ It is found in <em>simple_test.php</em> rather than
+ <em>unit_tester.php</em>.
+ See <a href="group_test_documentation.html">later</a> if you
+ want to incorporate other unit tester's
+ test cases in your test suites.
+ </p>
+
+ <p><a class="target" name="running_unit"><h2>Running a single test case</h2></a></p>
+ <p>
+ You won't often run single test cases except when bashing
+ away at a module that is having difficulty, and you don't
+ want to upset the main test suite.
+ With <em>autorun</em> no particular scaffolding is needed,
+ just launch your particular test file and you're ready to go.
+ </p>
+ <p>
+ You can even decide which reporter (for example,
+ <span class="new_code">TextReporter</span> or <span class="new_code">HtmlReporter</span>)
+ you prefer for a specific file when launched on its own...
+<pre>
+&lt;?php
+require_once('simpletest/autorun.php');<strong>
+SimpleTest :: prefer(new TextReporter());</strong>
+require_once('../classes/writer.php');
+
+class FileTestCase extends UnitTestCase {
+ ...
+}
+?&gt;
+</pre>
+ This script will run as is, but of course will output zero passes
+ and zero failures until test methods are added.
+ </p>
+
+ </div>
+ References and related information...
+ <ul>
+<li>
+ SimpleTest project page on <a href="http://sourceforge.net/projects/simpletest/">SourceForge</a>.
+ </li>
+<li>
+ SimpleTest download page on <a href="http://www.lastcraft.com/simple_test.php">LastCraft</a>.
+ </li>
+<li>
+ <a href="http://simpletest.org/api/">Full API for SimpleTest</a>
+ from the PHPDoc.
+ </li>
+</ul>
+<div class="menu_back"><div class="menu">
+<a href="index.html">SimpleTest</a>
+ |
+ <a href="overview.html">Overview</a>
+ |
+ <span class="chosen">Unit tester</span>
+ |
+ <a href="group_test_documentation.html">Group tests</a>
+ |
+ <a href="mock_objects_documentation.html">Mock objects</a>
+ |
+ <a href="partial_mocks_documentation.html">Partial mocks</a>
+ |
+ <a href="reporter_documentation.html">Reporting</a>
+ |
+ <a href="expectation_documentation.html">Expectations</a>
+ |
+ <a href="web_tester_documentation.html">Web tester</a>
+ |
+ <a href="form_testing_documentation.html">Testing forms</a>
+ |
+ <a href="authentication_documentation.html">Authentication</a>
+ |
+ <a href="browser_documentation.html">Scriptable browser</a>
+</div></div>
+<div class="copyright">
+ Copyright<br>Marcus Baker 2006
+ </div>
+</body>
+</html>
diff --git a/site/vendors/simpletest/docs/en/web_tester_documentation.html b/site/vendors/simpletest/docs/en/web_tester_documentation.html
new file mode 100644
index 0000000..2602dd5
--- /dev/null
+++ b/site/vendors/simpletest/docs/en/web_tester_documentation.html
@@ -0,0 +1,584 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Simple Test for PHP web script testing documentation</title>
+<link rel="stylesheet" type="text/css" href="docs.css" title="Styles">
+</head>
+<body>
+<div class="menu_back"><div class="menu">
+<a href="index.html">SimpleTest</a>
+ |
+ <a href="overview.html">Overview</a>
+ |
+ <a href="unit_test_documentation.html">Unit tester</a>
+ |
+ <a href="group_test_documentation.html">Group tests</a>
+ |
+ <a href="mock_objects_documentation.html">Mock objects</a>
+ |
+ <a href="partial_mocks_documentation.html">Partial mocks</a>
+ |
+ <a href="reporter_documentation.html">Reporting</a>
+ |
+ <a href="expectation_documentation.html">Expectations</a>
+ |
+ <span class="chosen">Web tester</span>
+ |
+ <a href="form_testing_documentation.html">Testing forms</a>
+ |
+ <a href="authentication_documentation.html">Authentication</a>
+ |
+ <a href="browser_documentation.html">Scriptable browser</a>
+</div></div>
+<h1>Web tester documentation</h1>
+ This page...
+ <ul>
+<li>
+ Successfully <a href="#fetch">fetching a web page</a>
+ </li>
+<li>
+ Testing the <a href="#content">page content</a>
+ </li>
+<li>
+ <a href="#navigation">Navigating a web site</a>
+ while testing
+ </li>
+<li>
+ <a href="#request">Raw request modifications</a> and debugging methods
+ </li>
+</ul>
+<div class="content">
+ <p><a class="target" name="fetch"><h2>Fetching a page</h2></a></p>
+ <p>
+ Testing classes is all very well, but PHP is predominately
+ a language for creating functionality within web pages.
+ How do we test the front end presentation role of our PHP
+ applications?
+ Well the web pages are just text, so we should be able to
+ examine them just like any other test data.
+ </p>
+ <p>
+ This leads to a tricky issue.
+ If we test at too low a level, testing for matching tags
+ in the page with pattern matching for example, our tests will
+ be brittle.
+ The slightest change in layout could break a large number of
+ tests.
+ If we test at too high a level, say using mock versions of a
+ template engine, then we lose the ability to automate some classes
+ of test.
+ For example, the interaction of forms and navigation will
+ have to be tested manually.
+ These types of test are extremely repetitive and error prone.
+ </p>
+ <p>
+ SimpleTest includes a special form of test case for the testing
+ of web page actions.
+ The <span class="new_code">WebTestCase</span> includes facilities
+ for navigation, content and cookie checks and form handling.
+ Usage of these test cases is similar to the
+ <a href="unit_tester_documentation.html">UnitTestCase</a>...
+<pre>
+<strong>class TestOfLastcraft extends WebTestCase {
+}</strong>
+</pre>
+ Here we are about to test the
+ <a href="http://www.lastcraft.com/">Last Craft</a> site itself.
+ If this test case is in a file called <em>lastcraft_test.php</em>
+ then it can be loaded in a runner script just like unit tests...
+<pre>
+&lt;?php
+require_once('simpletest/autorun.php');<strong>
+require_once('simpletest/web_tester.php');</strong>
+SimpleTest::prefer(new TextReporter());
+
+class WebTests extends TestSuite {
+ function WebTests() {
+ $this-&gt;TestSuite('Web site tests');<strong>
+ $this-&gt;addFile('lastcraft_test.php');</strong>
+ }
+}
+?&gt;
+</pre>
+ I am using the text reporter here to more clearly
+ distinguish the web content from the test output.
+ </p>
+ <p>
+ Nothing is being tested yet.
+ We can fetch the home page by using the
+ <span class="new_code">get()</span> method...
+<pre>
+class TestOfLastcraft extends WebTestCase {
+ <strong>
+ function testHomepage() {
+ $this-&gt;assertTrue($this-&gt;get('http://www.lastcraft.com/'));
+ }</strong>
+}
+</pre>
+ The <span class="new_code">get()</span> method will
+ return true only if page content was successfully
+ loaded.
+ It is a simple, but crude way to check that a web page
+ was actually delivered by the web server.
+ However that content may be a 404 response and yet
+ our <span class="new_code">get()</span> method will still return true.
+ </p>
+ <p>
+ Assuming that the web server for the Last Craft site is up
+ (sadly not always the case), we should see...
+<pre class="shell">
+Web site tests
+OK
+Test cases run: 1/1, Failures: 0, Exceptions: 0
+</pre>
+ All we have really checked is that any kind of page was
+ returned.
+ We don't yet know if it was the right one.
+ </p>
+
+ <p><a class="target" name="content"><h2>Testing page content</h2></a></p>
+ <p>
+ To confirm that the page we think we are on is actually the
+ page we are on, we need to verify the page content.
+<pre>
+class TestOfLastcraft extends WebTestCase {
+
+ function testHomepage() {<strong>
+ $this-&gt;get('http://www.lastcraft.com/');
+ $this-&gt;assertText('Why the last craft');</strong>
+ }
+}
+</pre>
+ The page from the last fetch is held in a buffer in
+ the test case, so there is no need to refer to it directly.
+ The pattern match is always made against the buffer.
+ </p>
+ <p>
+ Here is the list of possible content assertions...
+ <table><tbody>
+ <tr>
+<td><span class="new_code">assertTitle($title)</span></td>
+<td>Pass if title is an exact match</td>
+</tr>
+ <tr>
+<td><span class="new_code">assertText($text)</span></td>
+<td>Pass if matches visible and "alt" text</td>
+</tr>
+ <tr>
+<td><span class="new_code">assertNoText($text)</span></td>
+<td>Pass if doesn't match visible and "alt" text</td>
+</tr>
+ <tr>
+<td><span class="new_code">assertPattern($pattern)</span></td>
+<td>A Perl pattern match against the page content</td>
+</tr>
+ <tr>
+<td><span class="new_code">assertNoPattern($pattern)</span></td>
+<td>A Perl pattern match to not find content</td>
+</tr>
+ <tr>
+<td><span class="new_code">assertLink($label)</span></td>
+<td>Pass if a link with this text is present</td>
+</tr>
+ <tr>
+<td><span class="new_code">assertNoLink($label)</span></td>
+<td>Pass if no link with this text is present</td>
+</tr>
+ <tr>
+<td><span class="new_code">assertLinkById($id)</span></td>
+<td>Pass if a link with this id attribute is present</td>
+</tr>
+ <tr>
+<td><span class="new_code">assertNoLinkById($id)</span></td>
+<td>Pass if no link with this id attribute is present</td>
+</tr>
+ <tr>
+<td><span class="new_code">assertField($name, $value)</span></td>
+<td>Pass if an input tag with this name has this value</td>
+</tr>
+ <tr>
+<td><span class="new_code">assertFieldById($id, $value)</span></td>
+<td>Pass if an input tag with this id has this value</td>
+</tr>
+ <tr>
+<td><span class="new_code">assertResponse($codes)</span></td>
+<td>Pass if HTTP response matches this list</td>
+</tr>
+ <tr>
+<td><span class="new_code">assertMime($types)</span></td>
+<td>Pass if MIME type is in this list</td>
+</tr>
+ <tr>
+<td><span class="new_code">assertAuthentication($protocol)</span></td>
+<td>Pass if the current challenge is this protocol</td>
+</tr>
+ <tr>
+<td><span class="new_code">assertNoAuthentication()</span></td>
+<td>Pass if there is no current challenge</td>
+</tr>
+ <tr>
+<td><span class="new_code">assertRealm($name)</span></td>
+<td>Pass if the current challenge realm matches</td>
+</tr>
+ <tr>
+<td><span class="new_code">assertHeader($header, $content)</span></td>
+<td>Pass if a header was fetched matching this value</td>
+</tr>
+ <tr>
+<td><span class="new_code">assertNoHeader($header)</span></td>
+<td>Pass if a header was not fetched</td>
+</tr>
+ <tr>
+<td><span class="new_code">assertCookie($name, $value)</span></td>
+<td>Pass if there is currently a matching cookie</td>
+</tr>
+ <tr>
+<td><span class="new_code">assertNoCookie($name)</span></td>
+<td>Pass if there is currently no cookie of this name</td>
+</tr>
+ </tbody></table>
+ As usual with the SimpleTest assertions, they all return
+ false on failure and true on pass.
+ They also allow an optional test message and you can embed
+ the original test message inside using "%s" inside
+ your custom message.
+ </p>
+ <p>
+ So now we could instead test against the title tag with...
+<pre>
+<strong>$this-&gt;assertTitle('The Last Craft? Web developer tutorials on PHP, Extreme programming and Object Oriented development');</strong>
+</pre>
+ ...or, if that is too long and fragile...
+<pre>
+<strong>$this-&gt;assertTitle(new PatternExpectation('/The Last Craft/'));</strong>
+</pre>
+ As well as the simple HTML content checks we can check
+ that the MIME type is in a list of allowed types with...
+<pre>
+<strong>$this-&gt;assertMime(array('text/plain', 'text/html'));</strong>
+</pre>
+ More interesting is checking the HTTP response code.
+ Like the MIME type, we can assert that the response code
+ is in a list of allowed values...
+<pre>
+class TestOfLastcraft extends WebTestCase {
+
+ function testRedirects() {
+ $this-&gt;get('http://www.lastcraft.com/test/redirect.php');
+ $this-&gt;assertResponse(200);&lt;/strong&gt;
+ }
+}
+</pre>
+ Here we are checking that the fetch is successful by
+ allowing only a 200 HTTP response.
+ This test will pass, but it is not actually correct to do so.
+ There is no page, instead the server issues a redirect.
+ The <span class="new_code">WebTestCase</span> will
+ automatically follow up to three such redirects.
+ The tests are more robust this way and we are usually
+ interested in the interaction with the pages rather
+ than their delivery.
+ If the redirects are of interest then this ability must
+ be disabled...
+<pre>
+class TestOfLastcraft extends WebTestCase {
+
+ function testHomepage() {<strong>
+ $this-&gt;setMaximumRedirects(0);</strong>
+ $this-&gt;get('http://www.lastcraft.com/test/redirect.php');
+ $this-&gt;assertResponse(200);
+ }
+}
+</pre>
+ The assertion now fails as expected...
+<pre class="shell">
+Web site tests
+1) Expecting response in [200] got [302]
+ in testhomepage
+ in testoflastcraft
+ in lastcraft_test.php
+FAILURES!!!
+Test cases run: 1/1, Failures: 1, Exceptions: 0
+</pre>
+ We can modify the test to correctly assert redirects with...
+<pre>
+class TestOfLastcraft extends WebTestCase {
+
+ function testHomepage() {
+ $this-&gt;setMaximumRedirects(0);
+ $this-&gt;get('http://www.lastcraft.com/test/redirect.php');
+ $this-&gt;assertResponse(<strong>array(301, 302, 303, 307)</strong>);
+ }
+}
+</pre>
+ This now passes.
+ </p>
+
+ <p><a class="target" name="navigation"><h2>Navigating a web site</h2></a></p>
+ <p>
+ Users don't often navigate sites by typing in URLs, but by
+ clicking links and buttons.
+ Here we confirm that the contact details can be reached
+ from the home page...
+<pre>
+class TestOfLastcraft extends WebTestCase {
+ ...
+ function testContact() {
+ $this-&gt;get('http://www.lastcraft.com/');<strong>
+ $this-&gt;clickLink('About');
+ $this-&gt;assertTitle(new PatternExpectation('/About Last Craft/'));</strong>
+ }
+}
+</pre>
+ The parameter is the text of the link.
+ </p>
+ <p>
+ If the target is a button rather than an anchor tag, then
+ <span class="new_code">clickSubmit()</span> can be used
+ with the button title...
+<pre>
+<strong>$this-&gt;clickSubmit('Go!');</strong>
+</pre>
+ If you are not sure or don't care, the usual case, then just
+ use the <span class="new_code">click()</span> method...
+<pre>
+<strong>$this-&gt;click('Go!');</strong>
+</pre>
+ </p>
+ <p>
+ The list of navigation methods is...
+ <table><tbody>
+ <tr>
+<td><span class="new_code">getUrl()</span></td>
+<td>The current location</td>
+</tr>
+ <tr>
+<td><span class="new_code">get($url, $parameters)</span></td>
+<td>Send a GET request with these parameters</td>
+</tr>
+ <tr>
+<td><span class="new_code">post($url, $parameters)</span></td>
+<td>Send a POST request with these parameters</td>
+</tr>
+ <tr>
+<td><span class="new_code">head($url, $parameters)</span></td>
+<td>Send a HEAD request without replacing the page content</td>
+</tr>
+ <tr>
+<td><span class="new_code">retry()</span></td>
+<td>Reload the last request</td>
+</tr>
+ <tr>
+<td><span class="new_code">back()</span></td>
+<td>Like the browser back button</td>
+</tr>
+ <tr>
+<td><span class="new_code">forward()</span></td>
+<td>Like the browser forward button</td>
+</tr>
+ <tr>
+<td><span class="new_code">authenticate($name, $password)</span></td>
+<td>Retry after a challenge</td>
+</tr>
+ <tr>
+<td><span class="new_code">restart()</span></td>
+<td>Restarts the browser as if a new session</td>
+</tr>
+ <tr>
+<td><span class="new_code">getCookie($name)</span></td>
+<td>Gets the cookie value for the current context</td>
+</tr>
+ <tr>
+<td><span class="new_code">ageCookies($interval)</span></td>
+<td>Ages current cookies prior to a restart</td>
+</tr>
+ <tr>
+<td><span class="new_code">clearFrameFocus()</span></td>
+<td>Go back to treating all frames as one page</td>
+</tr>
+ <tr>
+<td><span class="new_code">clickSubmit($label)</span></td>
+<td>Click the first button with this label</td>
+</tr>
+ <tr>
+<td><span class="new_code">clickSubmitByName($name)</span></td>
+<td>Click the button with this name attribute</td>
+</tr>
+ <tr>
+<td><span class="new_code">clickSubmitById($id)</span></td>
+<td>Click the button with this ID attribute</td>
+</tr>
+ <tr>
+<td><span class="new_code">clickImage($label, $x, $y)</span></td>
+<td>Click an input tag of type image by title or alt text</td>
+</tr>
+ <tr>
+<td><span class="new_code">clickImageByName($name, $x, $y)</span></td>
+<td>Click an input tag of type image by name</td>
+</tr>
+ <tr>
+<td><span class="new_code">clickImageById($id, $x, $y)</span></td>
+<td>Click an input tag of type image by ID attribute</td>
+</tr>
+ <tr>
+<td><span class="new_code">submitFormById($id)</span></td>
+<td>Submit a form without the submit value</td>
+</tr>
+ <tr>
+<td><span class="new_code">clickLink($label, $index)</span></td>
+<td>Click an anchor by the visible label text</td>
+</tr>
+ <tr>
+<td><span class="new_code">clickLinkById($id)</span></td>
+<td>Click an anchor by the ID attribute</td>
+</tr>
+ <tr>
+<td><span class="new_code">getFrameFocus()</span></td>
+<td>The name of the currently selected frame</td>
+</tr>
+ <tr>
+<td><span class="new_code">setFrameFocusByIndex($choice)</span></td>
+<td>Focus on a frame counting from 1</td>
+</tr>
+ <tr>
+<td><span class="new_code">setFrameFocus($name)</span></td>
+<td>Focus on a frame by name</td>
+</tr>
+ </tbody></table>
+ </p>
+ <p>
+ The parameters in the <span class="new_code">get()</span>, <span class="new_code">post()</span> or
+ <span class="new_code">head()</span> methods are optional.
+ The HTTP HEAD fetch does not change the browser context, only loads
+ cookies.
+ This can be useful for when an image or stylesheet sets a cookie
+ for crafty robot blocking.
+ </p>
+ <p>
+ The <span class="new_code">retry()</span>, <span class="new_code">back()</span> and
+ <span class="new_code">forward()</span> commands work as they would on
+ your web browser.
+ They use the history to retry pages.
+ This can be handy for checking the effect of hitting the
+ back button on your forms.
+ </p>
+ <p>
+ The frame methods need a little explanation.
+ By default a framed page is treated just like any other.
+ Content will be searced for throughout the entire frameset,
+ so clicking a link will work no matter which frame
+ the anchor tag is in.
+ You can override this behaviour by focusing on a single
+ frame.
+ If you do that, all searches and actions will apply to that
+ frame alone, such as authentication and retries.
+ If a link or button is not in a focused frame then it cannot
+ be clicked.
+ </p>
+ <p>
+ Testing navigation on fixed pages only tells you when you
+ have broken an entire script.
+ For highly dynamic pages, such as for bulletin boards, this can
+ be crucial for verifying the correctness of the application.
+ For most applications though, the really tricky logic is usually in
+ the handling of forms and sessions.
+ Fortunately SimpleTest includes
+ <a href="form_testing_documentation.html">tools for testing web forms</a>
+ as well.
+ </p>
+
+ <p><a class="target" name="request"><h2>Modifying the request</h2></a></p>
+ <p>
+ Although SimpleTest does not have the goal of testing networking
+ problems, it does include some methods to modify and debug
+ the requests it makes.
+ Here is another method list...
+ <table><tbody>
+ <tr>
+<td><span class="new_code">getTransportError()</span></td>
+<td>The last socket error</td>
+</tr>
+ <tr>
+<td><span class="new_code">showRequest()</span></td>
+<td>Dump the outgoing request</td>
+</tr>
+ <tr>
+<td><span class="new_code">showHeaders()</span></td>
+<td>Dump the incoming headers</td>
+</tr>
+ <tr>
+<td><span class="new_code">showSource()</span></td>
+<td>Dump the raw HTML page content</td>
+</tr>
+ <tr>
+<td><span class="new_code">ignoreFrames()</span></td>
+<td>Do not load framesets</td>
+</tr>
+ <tr>
+<td><span class="new_code">setCookie($name, $value)</span></td>
+<td>Set a cookie from now on</td>
+</tr>
+ <tr>
+<td><span class="new_code">addHeader($header)</span></td>
+<td>Always add this header to the request</td>
+</tr>
+ <tr>
+<td><span class="new_code">setMaximumRedirects($max)</span></td>
+<td>Stop after this many redirects</td>
+</tr>
+ <tr>
+<td><span class="new_code">setConnectionTimeout($timeout)</span></td>
+<td>Kill the connection after this time between bytes</td>
+</tr>
+ <tr>
+<td><span class="new_code">useProxy($proxy, $name, $password)</span></td>
+<td>Make requests via this proxy URL</td>
+</tr>
+ </tbody></table>
+ These methods are principally for debugging.
+ </p>
+
+ </div>
+ References and related information...
+ <ul>
+<li>
+ SimpleTest project page on <a href="http://sourceforge.net/projects/simpletest/">SourceForge</a>.
+ </li>
+<li>
+ SimpleTest download page on <a href="http://www.lastcraft.com/simple_test.php">LastCraft</a>.
+ </li>
+<li>
+ The <a href="http://simpletest.org/api/">developer's API for SimpleTest</a>
+ gives full detail on the classes and assertions available.
+ </li>
+</ul>
+<div class="menu_back"><div class="menu">
+<a href="index.html">SimpleTest</a>
+ |
+ <a href="overview.html">Overview</a>
+ |
+ <a href="unit_test_documentation.html">Unit tester</a>
+ |
+ <a href="group_test_documentation.html">Group tests</a>
+ |
+ <a href="mock_objects_documentation.html">Mock objects</a>
+ |
+ <a href="partial_mocks_documentation.html">Partial mocks</a>
+ |
+ <a href="reporter_documentation.html">Reporting</a>
+ |
+ <a href="expectation_documentation.html">Expectations</a>
+ |
+ <span class="chosen">Web tester</span>
+ |
+ <a href="form_testing_documentation.html">Testing forms</a>
+ |
+ <a href="authentication_documentation.html">Authentication</a>
+ |
+ <a href="browser_documentation.html">Scriptable browser</a>
+</div></div>
+<div class="copyright">
+ Copyright<br>Marcus Baker 2006
+ </div>
+</body>
+</html>
diff --git a/site/vendors/simpletest/docs/fr/authentication_documentation.html b/site/vendors/simpletest/docs/fr/authentication_documentation.html
new file mode 100644
index 0000000..782a46b
--- /dev/null
+++ b/site/vendors/simpletest/docs/fr/authentication_documentation.html
@@ -0,0 +1,332 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Documentation Simple Test : tester l'authentification</title>
+<link rel="stylesheet" type="text/css" href="docs.css" title="Styles">
+</head>
+<body>
+<div class="menu_back"><div class="menu">
+<a href="index.html">SimpleTest</a>
+ |
+ <a href="overview.html">Overview</a>
+ |
+ <a href="unit_test_documentation.html">Unit tester</a>
+ |
+ <a href="group_test_documentation.html">Group tests</a>
+ |
+ <a href="mock_objects_documentation.html">Mock objects</a>
+ |
+ <a href="partial_mocks_documentation.html">Partial mocks</a>
+ |
+ <a href="reporter_documentation.html">Reporting</a>
+ |
+ <a href="expectation_documentation.html">Expectations</a>
+ |
+ <a href="web_tester_documentation.html">Web tester</a>
+ |
+ <a href="form_testing_documentation.html">Testing forms</a>
+ |
+ <a href="authentication_documentation.html">Authentication</a>
+ |
+ <a href="browser_documentation.html">Scriptable browser</a>
+</div></div>
+<h1>Documentation sur l'authentification</h1>
+ This page...
+ <ul>
+<li>
+ Passer au travers d'une <a href="#basique">authentification HTTP basique</a>
+ </li>
+<li>
+ Tester l'<a href="#cookies">authentification basée sur des cookies</a>
+ </li>
+<li>
+ Gérer les <a href="#session">sessions du navigateur</a> et les timeouts
+ </li>
+</ul>
+<div class="content">
+
+ <p>
+ Un des secteurs à la fois délicat et important lors d'un test
+ de site web reste la sécurité. Tester ces schémas est au coeur
+ des objectifs du testeur web de SimpleTest.
+ </p>
+
+ <p><a class="target" name="basique"><h2>Authentification HTTP basique</h2></a></p>
+ <p>
+ Si vous allez chercher une page web protégée
+ par une authentification basique, vous hériterez d'une entête 401.
+ Nous pouvons représenter ceci par ce test...
+<pre>
+class AuthenticationTest extends WebTestCase {<strong>
+ function test401Header() {
+ $this-&gt;get('http://www.lastcraft.com/protected/');
+ $this-&gt;showHeaders();
+ }</strong>
+}
+</pre>
+ Ce qui nous permet de voir les entêtes reçues...
+ <div class="demo">
+ <h1>File test</h1>
+<pre style="background-color: lightgray; color: black">
+HTTP/1.1 401 Authorization Required
+Date: Sat, 18 Sep 2004 19:25:18 GMT
+Server: Apache/1.3.29 (Unix) PHP/4.3.4
+WWW-Authenticate: Basic realm="SimpleTest basic authentication"
+Connection: close
+Content-Type: text/html; charset=iso-8859-1
+</pre>
+ <div style="padding: 8px; margin-top: 1em; background-color: green; color: white;">1/1 test cases complete.
+ <strong>0</strong> passes, <strong>0</strong> fails and <strong>0</strong> exceptions.</div>
+ </div>
+ Sauf que nous voulons éviter l'inspection visuelle,
+ on souhaite que SimpleTest puisse nous dire si oui ou non
+ la page est protégée. Voici un test en profondeur sur nos entêtes...
+<pre>
+class AuthenticationTest extends WebTestCase {
+ function test401Header() {
+ $this-&gt;get('http://www.lastcraft.com/protected/');<strong>
+ $this-&gt;assertAuthentication('Basic');
+ $this-&gt;assertResponse(401);
+ $this-&gt;assertRealm('SimpleTest basic authentication');</strong>
+ }
+}
+</pre>
+ N'importe laquelle de ces assertions suffirait,
+ tout dépend de la masse de détails que vous souhaitez voir.
+ </p>
+ <p>
+ La plupart du temps, nous ne souhaitons pas tester
+ l'authentification en elle-même, mais plutôt
+ les pages protégées par cette authentification.
+ Dès que la tentative d'authentification est reçue,
+ nous pouvons y répondre à l'aide d'une réponse d'authentification :
+<pre>
+class AuthenticationTest extends WebTestCase {
+ function testAuthentication() {
+ $this-&gt;get('http://www.lastcraft.com/protected/');<strong>
+ $this-&gt;authenticate('Me', 'Secret');</strong>
+ $this-&gt;assertTitle(...);
+ }
+}
+</pre>
+ Le nom d'utilisateur et le mot de passe seront désormais
+ envoyés à chaque requête vers ce répertoire
+ et ses sous-répertoires.
+ En revanche vous devrez vous authentifier à nouveau
+ si vous sortez de ce répertoire mais SimpleTest est assez
+ intelligent pour fusionner les sous-répertoires dans un même domaine.
+ </p>
+ <p>
+ Vous pouvez gagner une ligne en définissant
+ l'authentification au niveau de l'URL...
+<pre>
+class AuthenticationTest extends WebTestCase {
+ function testCanReadAuthenticatedPages() {
+ $this-&gt;get('http://<strong>Me:Secret@</strong>www.lastcraft.com/protected/');
+ $this-&gt;assertTitle(...);
+ }
+}
+</pre>
+ Si votre nom d'utilisateur ou mot de passe comporte
+ des caractères spéciaux, alors n'oubliez pas de les encoder,
+ sinon la requête ne sera pas analysée correctement.
+ De plus cette entête ne sera pas envoyée aux
+ sous requêtes si vous la définissez avec une URL absolue.
+ Par contre si vous naviguez avec des URL relatives,
+ l'information d'authentification sera préservée.
+ </p>
+ <p>
+ Pour l'instant, seule l'authentification de base est implémentée
+ et elle n'est réellement fiable qu'en tandem avec une connexion HTTPS.
+ C'est généralement suffisant pour protéger
+ le serveur testé des regards malveillants.
+ Les authentifications Digest et NTLM pourraient être ajoutées prochainement.
+ </p>
+
+ <p><a class="target" name="cookies"><h2>Cookies</h2></a></p>
+ <p>
+ L'authentification de base ne donne pas assez de contrôle
+ au développeur Web sur l'interface utilisateur.
+ Il y a de forte chance pour que cette fonctionnalité
+ soit codée directement dans l'architecture web
+ à grand renfort de cookies et de timeouts compliqués.
+ </p>
+ <p>
+ Commençons par un simple formulaire de connexion...
+<pre>
+&lt;form&gt;
+ Username:
+ &lt;input type="text" name="u" value="" /&gt;&lt;br /&gt;
+ Password:
+ &lt;input type="password" name="p" value="" /&gt;&lt;br /&gt;
+ &lt;input type="submit" value="Log in" /&gt;
+&lt;/form&gt;
+</pre>
+ Lequel doit ressembler à...
+ </p>
+ <p>
+ <form class="demo">
+ Username:
+ <input type="text" name="u" value=""><br>
+ Password:
+ <input type="password" name="p" value=""><br>
+ <input type="submit" value="Log in">
+ </form>
+ </p>
+ <p>
+ Supposons que, durant le chargement de la page,
+ un cookie ait été inscrit avec un numéro d'identifiant de session.
+ Nous n'allons pas encore remplir le formulaire,
+ juste tester que nous pistons bien l'utilisateur.
+ Voici le test...
+<pre>
+class LogInTest extends WebTestCase {
+ function testSessionCookieSetBeforeForm() {
+ $this-&gt;get('http://www.my-site.com/login.php');<strong>
+ $this-&gt;assertCookie('SID');</strong>
+ }
+}
+</pre>
+ Nous nous contentons ici de vérifier que le cookie a bien été défini.
+ Etant donné que sa valeur est plutôt énigmatique,
+ elle ne vaut pas la peine d'être testée.
+ </p>
+ <p>
+ Le reste du test est le même que dans n'importe quel autre formulaire,
+ mais nous pourrions souhaiter nous assurer
+ que le cookie n'a pas été modifié depuis la phase de connexion.
+ Voici comment cela pourrait être testé :
+<pre>
+class LogInTest extends WebTestCase {
+ ...
+ function testSessionCookieSameAfterLogIn() {
+ $this-&gt;get('http://www.my-site.com/login.php');<strong>
+ $session = $this-&gt;getCookie('SID');
+ $this-&gt;setField('u', 'Me');
+ $this-&gt;setField('p', 'Secret');
+ $this-&gt;clickSubmit('Log in');
+ $this-&gt;assertWantedPattern('/Welcome Me/');
+ $this-&gt;assertCookie('SID', $session);</strong>
+ }
+}
+</pre>
+ Ceci confirme que l'identifiant de session
+ est identique avant et après la connexion.
+ </p>
+ <p>
+ Nous pouvons même essayer de duper notre propre système
+ en créant un cookie arbitraire pour se connecter...
+<pre>
+class LogInTest extends WebTestCase {
+ ...
+ function testSessionCookieSameAfterLogIn() {
+ $this-&gt;get('http://www.my-site.com/login.php');<strong>
+ $this-&gt;setCookie('SID', 'Some other session');
+ $this-&gt;get('http://www.my-site.com/restricted.php');</strong>
+ $this-&gt;assertWantedPattern('/Access denied/');
+ }
+}
+</pre>
+ Votre site est-il protégé contre ce type d'attaque ?
+ </p>
+
+ <p><a class="target" name="session"><h2>Sessions de navigateur</h2></a></p>
+ <p>
+ Si vous testez un système d'authentification,
+ la reconnexion par un utilisateur est un point sensible.
+ Essayons de simuler ce qui se passe dans ce cas :
+<pre>
+class LogInTest extends WebTestCase {
+ ...
+ function testLoseAuthenticationAfterBrowserClose() {
+ $this-&gt;get('http://www.my-site.com/login.php');
+ $this-&gt;setField('u', 'Me');
+ $this-&gt;setField('p', 'Secret');
+ $this-&gt;clickSubmit('Log in');
+ $this-&gt;assertWantedPattern('/Welcome Me/');<strong>
+
+ $this-&gt;restart();
+ $this-&gt;get('http://www.my-site.com/restricted.php');
+ $this-&gt;assertWantedPattern('/Access denied/');</strong>
+ }
+}
+</pre>
+ La méthode <span class="new_code">WebTestCase::restart()</span> préserve les cookies
+ dont le timeout a expiré, mais conserve les cookies temporaires ou expirés.
+ Vous pouvez spécifier l'heure et la date de leur réactivation.
+ </p>
+ <p>
+ L'expiration des cookies peut être un problème.
+ Si vous avez un cookie qui doit expirer au bout d'une heure,
+ nous n'allons pas mettre le test en veille en attendant
+ que le cookie expire...
+ </p>
+ <p>
+ Afin de provoquer leur expiration,
+ vous pouvez dater manuellement les cookies,
+ avant le début de la session.
+<pre>
+class LogInTest extends WebTestCase {
+ ...
+ function testLoseAuthenticationAfterOneHour() {
+ $this-&gt;get('http://www.my-site.com/login.php');
+ $this-&gt;setField('u', 'Me');
+ $this-&gt;setField('p', 'Secret');
+ $this-&gt;clickSubmit('Log in');
+ $this-&gt;assertWantedPattern('/Welcome Me/');
+ <strong>
+ $this-&gt;ageCookies(3600);</strong>
+ $this-&gt;restart();
+ $this-&gt;get('http://www.my-site.com/restricted.php');
+ $this-&gt;assertWantedPattern('/Access denied/');
+ }
+}
+</pre>
+ Après le redémarrage, les cookies seront plus vieux
+ d'une heure et que tous ceux dont la date d'expiration
+ sera passée auront disparus.
+ </p>
+
+ </div>
+ References and related information...
+ <ul>
+<li>
+ La page du projet SimpleTest sur <a href="http://sourceforge.net/projects/simpletest/">SourceForge</a>.
+ </li>
+<li>
+ La page de téléchargement de SimpleTest sur <a href="http://www.lastcraft.com/simple_test.php">LastCraft</a>.
+ </li>
+<li>
+ <a href="http://simpletest.org/api/">L'API du développeur pour SimpleTest</a> donne tous les détails sur les classes et les assertions disponibles.
+ </li>
+</ul>
+<div class="menu_back"><div class="menu">
+<a href="index.html">SimpleTest</a>
+ |
+ <a href="overview.html">Overview</a>
+ |
+ <a href="unit_test_documentation.html">Unit tester</a>
+ |
+ <a href="group_test_documentation.html">Group tests</a>
+ |
+ <a href="mock_objects_documentation.html">Mock objects</a>
+ |
+ <a href="partial_mocks_documentation.html">Partial mocks</a>
+ |
+ <a href="reporter_documentation.html">Reporting</a>
+ |
+ <a href="expectation_documentation.html">Expectations</a>
+ |
+ <a href="web_tester_documentation.html">Web tester</a>
+ |
+ <a href="form_testing_documentation.html">Testing forms</a>
+ |
+ <a href="authentication_documentation.html">Authentication</a>
+ |
+ <a href="browser_documentation.html">Scriptable browser</a>
+</div></div>
+<div class="copyright">
+ Copyright<br>Marcus Baker 2006
+ </div>
+</body>
+</html>
diff --git a/site/vendors/simpletest/docs/fr/browser_documentation.html b/site/vendors/simpletest/docs/fr/browser_documentation.html
new file mode 100644
index 0000000..62abbbb
--- /dev/null
+++ b/site/vendors/simpletest/docs/fr/browser_documentation.html
@@ -0,0 +1,446 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Documentation SimpleTest : le composant de navigation web scriptable</title>
+<link rel="stylesheet" type="text/css" href="docs.css" title="Styles">
+</head>
+<body>
+<div class="menu_back"><div class="menu">
+<a href="index.html">SimpleTest</a>
+ |
+ <a href="overview.html">Overview</a>
+ |
+ <a href="unit_test_documentation.html">Unit tester</a>
+ |
+ <a href="group_test_documentation.html">Group tests</a>
+ |
+ <a href="mock_objects_documentation.html">Mock objects</a>
+ |
+ <a href="partial_mocks_documentation.html">Partial mocks</a>
+ |
+ <a href="reporter_documentation.html">Reporting</a>
+ |
+ <a href="expectation_documentation.html">Expectations</a>
+ |
+ <a href="web_tester_documentation.html">Web tester</a>
+ |
+ <a href="form_testing_documentation.html">Testing forms</a>
+ |
+ <a href="authentication_documentation.html">Authentication</a>
+ |
+ <a href="browser_documentation.html">Scriptable browser</a>
+</div></div>
+<h1>Documentation sur le navigateur scriptable</h1>
+ This page...
+ <ul>
+<li>
+ Utiliser le <a href="#scripting">navigateur web dans des scripts</a>
+ </li>
+<li>
+ <a href="#deboguer">Déboguer</a> les erreurs sur les pages
+ </li>
+<li>
+ <a href="#unit">Tests complexes avec des navigateurs web multiples</a>
+ </li>
+</ul>
+<div class="content">
+
+ <p>
+ Le composant de navigation web de SimpleTest peut être utilisé
+ non seulement à l'extérieur de la classe <span class="new_code">WebTestCase</span>,
+ mais aussi indépendamment du framework SimpleTest lui-même.
+ </p>
+
+ <p><a class="target" name="script"><h2>Le navigateur scriptable</h2></a></p>
+ <p>
+ Vous pouvez utiliser le navigateur web dans des scripts PHP
+ pour confirmer que des services marchent bien comme il faut
+ ou pour extraire des informations à partir de ceux-ci de façon régulière.
+ Par exemple, voici un petit script pour extraire
+ le nombre de bogues ouverts dans PHP 5 à partir
+ du <a href="http://www.php.net/">site web PHP</a>...
+<pre>
+&lt;?php
+ require_once('simpletest/browser.php');
+
+ $browser = &amp;new SimpleBrowser();
+ $browser-&gt;get('http://php.net/');
+ $browser-&gt;clickLink('reporting bugs');
+ $browser-&gt;clickLink('statistics');
+ $browser-&gt;clickLink('PHP 5 bugs only');
+ $page = $browser-&gt;getContent();
+ preg_match('/status=Open.*?by=Any.*?(\d+)&lt;\/a&gt;/', $page, $matches);
+ print $matches[1];
+?&gt;
+</pre>
+ Bien sûr Il y a des méthodes plus simple pour réaliser
+ cet exemple en PHP. Par exemple, vous pourriez juste
+ utiliser la commande PHP <span class="new_code">file()</span> sur ce qui est
+ ici une page fixe. Cependant, en utilisant des scripts
+ avec le navigateur web vous vous autorisez l'authentification,
+ la gestion des cookies, le chargement automatique des fenêtres,
+ les redirections, la transmission de formulaires et la capacité
+ d'examiner les entêtes. De telles méthodes sont fragiles dans
+ un site en constante évolution et vous voudrez employer une méthode
+ plus directe pour accéder aux données de façon permanente,
+ mais pour des tâches simples cette technique peut s'avérer
+ une solution très rapide.
+ </p>
+ <p>
+ Toutes les méthode de navigation utilisées dans <a href="web_tester_documentation.html">WebTestCase</a> sont présente dans la classe <span class="new_code">SimpleBrowser</span>, mais les assertions sont remplacées par de simples accesseurs. Voici une liste complète des méthodes de navigation de page à page...
+ <table><tbody>
+ <tr>
+<td><span class="new_code">addHeader($header)</span></td>
+<td>Ajouter une entête à chaque téléchargement</td>
+</tr>
+ <tr>
+<td><span class="new_code">useProxy($proxy, $username, $password)</span></td>
+<td>Utilise ce proxy à partir de maintenant</td>
+</tr>
+ <tr>
+<td><span class="new_code">head($url, $parameters)</span></td>
+<td>Effectue une requête HEAD</td>
+</tr>
+ <tr>
+<td><span class="new_code">get($url, $parameters)</span></td>
+<td>Télécharge une page avec un GET</td>
+</tr>
+ <tr>
+<td><span class="new_code">post($url, $parameters)</span></td>
+<td>Télécharge une page avec un POST</td>
+</tr>
+ <tr>
+<td><span class="new_code">clickLink($label)</span></td>
+<td>Suit un lien par son étiquette</td>
+</tr>
+ <tr>
+<td><span class="new_code">isLink($label)</span></td>
+<td>Vérifie l'existance d'un lien par son étiquette</td>
+</tr>
+ <tr>
+<td><span class="new_code">clickLinkById($id)</span></td>
+<td>Suit un lien par son attribut d'identification</td>
+</tr>
+ <tr>
+<td><span class="new_code">isLinkById($id)</span></td>
+<td>Vérifie l'existance d'un lien par son attribut d'identification</td>
+</tr>
+ <tr>
+<td><span class="new_code">getUrl()</span></td>
+<td>La page ou la fenêtre URL en cours</td>
+</tr>
+ <tr>
+<td><span class="new_code">getTitle()</span></td>
+<td>Le titre de la page</td>
+</tr>
+ <tr>
+<td><span class="new_code">getContent()</span></td>
+<td>Le page ou la fenêtre brute</td>
+</tr>
+ <tr>
+<td><span class="new_code">getContentAsText()</span></td>
+<td>Sans code HTML à l'exception du text "alt"</td>
+</tr>
+ <tr>
+<td><span class="new_code">retry()</span></td>
+<td>Répète la dernière requête</td>
+</tr>
+ <tr>
+<td><span class="new_code">back()</span></td>
+<td>Utilise le bouton "précédent" du navigateur</td>
+</tr>
+ <tr>
+<td><span class="new_code">forward()</span></td>
+<td>Utilise le bouton "suivant" du navigateur</td>
+</tr>
+ <tr>
+<td><span class="new_code">authenticate($username, $password)</span></td>
+<td>Retente la page ou la fenêtre après une réponse 401</td>
+</tr>
+ <tr>
+<td><span class="new_code">restart($date)</span></td>
+<td>Relance le navigateur pour une nouvelle session</td>
+</tr>
+ <tr>
+<td><span class="new_code">ageCookies($interval)</span></td>
+<td>Change la date des cookies</td>
+</tr>
+ <tr>
+<td><span class="new_code">setCookie($name, $value)</span></td>
+<td>Lance un nouveau cookie</td>
+</tr>
+ <tr>
+<td><span class="new_code">getCookieValue($host, $path, $name)</span></td>
+<td>Lit le cookie le plus spécifique</td>
+</tr>
+ <tr>
+<td><span class="new_code">getCurrentCookieValue($name)</span></td>
+<td>Lit le contenue du cookie en cours</td>
+</tr>
+ </tbody></table>
+ Les méthode <span class="new_code">SimpleBrowser::useProxy()</span> et
+ <span class="new_code">SimpleBrowser::addHeader()</span> sont spéciales.
+ Une fois appelées, elles continuent à s'appliquer sur les téléchargements suivants.
+ </p>
+ <p>
+ Naviguer dans les formulaires est similaire à la <a href="form_testing_documentation.html">navigation des formulaires via WebTestCase</a>...
+ <table><tbody>
+ <tr>
+<td><span class="new_code">setField($name, $value)</span></td>
+<td>Modifie tous les champs avec ce nom</td>
+</tr>
+ <tr>
+<td><span class="new_code">setFieldById($id, $value)</span></td>
+<td>Modifie tous les champs avec cet identifiant</td>
+</tr>
+ <tr>
+<td><span class="new_code">getField($name)</span></td>
+<td>Accesseur de la valeur d'un élément de formulaire</td>
+</tr>
+ <tr>
+<td><span class="new_code">getFieldById($id)</span></td>
+<td>Accesseur de la valeur de l'élément de formulaire avec cet identifiant</td>
+</tr>
+ <tr>
+<td><span class="new_code">clickSubmit($label)</span></td>
+<td>Transmet le formulaire avec l'étiquette de son bouton</td>
+</tr>
+ <tr>
+<td><span class="new_code">clickSubmitByName($name)</span></td>
+<td>Transmet le formulaire avec l'attribut de son bouton</td>
+</tr>
+ <tr>
+<td><span class="new_code">clickSubmitById($id)</span></td>
+<td>Transmet le formulaire avec l'identifiant de son bouton</td>
+</tr>
+ <tr>
+<td><span class="new_code">clickImage($label, $x, $y)</span></td>
+<td>Clique sur une balise input de type image par son titre (title="*") our son texte alternatif (alt="*")</td>
+</tr>
+ <tr>
+<td><span class="new_code">clickImageByName($name, $x, $y)</span></td>
+<td>Clique sur une balise input de type image par son attribut (name="*")</td>
+</tr>
+ <tr>
+<td><span class="new_code">clickImageById($id, $x, $y)</span></td>
+<td>Clique sur une balise input de type image par son identifiant (id="*")</td>
+</tr>
+ <tr>
+<td><span class="new_code">submitFormById($id)</span></td>
+<td>Transmet le formulaire par son identifiant propre</td>
+</tr>
+ </tbody></table>
+ Au jourd d'aujourd'hui il n'existe aucune méthode pour lister
+ les formulaires et les champs disponibles : ce sera probablement
+ ajouté dans des versions successives de SimpleTest.
+ </p>
+ <p>
+ A l'intérieur d'une page, les fenêtres individuelles peuvent être
+ sélectionnées. Si aucune sélection n'est réalisée alors
+ toutes les fenêtres sont fusionnées ensemble dans
+ une unique et grande page.
+ Le contenu de la page en cours sera une concaténation des
+ toutes les fenêtres dans l'ordre spécifié par les balises "frameset".
+ <table><tbody>
+ <tr>
+<td><span class="new_code">getFrames()</span></td>
+<td>Un déchargement de la structure de la fenêtre courante</td>
+</tr>
+ <tr>
+<td><span class="new_code">getFrameFocus()</span></td>
+<td>L'index ou l'étiquette de la fenêtre en courante</td>
+</tr>
+ <tr>
+<td><span class="new_code">setFrameFocusByIndex($choice)</span></td>
+<td>Sélectionne la fenêtre numérotée à partir de 1</td>
+</tr>
+ <tr>
+<td><span class="new_code">setFrameFocus($name)</span></td>
+<td>Sélectionne une fenêtre par son étiquette</td>
+</tr>
+ <tr>
+<td><span class="new_code">clearFrameFocus()</span></td>
+<td>Traite toutes les fenêtres comme une seule page</td>
+</tr>
+ </tbody></table>
+ Lorsqu'on est focalisé sur une fenêtre unique,
+ le contenu viendra de celle-ci uniquement.
+ Cela comprend les liens à cliquer et les formulaires à transmettre.
+ </p>
+
+ <p><a class="target" name="deboguer"><h2>Où sont les erreurs ?</h2></a></p>
+ <p>
+ Toute cette masse de fonctionnalités est géniale
+ lorsqu'on arrive à bien télécharger les pages,
+ mais ce n'est pas toujours évident.
+ Pour aider à découvrir les erreurs, le navigateur a aussi
+ des méthodes pour aider au débogage.
+ <table><tbody>
+ <tr>
+<td><span class="new_code">setConnectionTimeout($timeout)</span></td>
+<td>Ferme la socket avec un délai trop long</td>
+</tr>
+ <tr>
+<td><span class="new_code">getRequest()</span></td>
+<td>L'entête de la requête brute de la page ou de la fenêtre</td>
+</tr>
+ <tr>
+<td><span class="new_code">getHeaders()</span></td>
+<td>L'entête de réponse de la page ou de la fenêtre</td>
+</tr>
+ <tr>
+<td><span class="new_code">getTransportError()</span></td>
+<td>N'importe quel erreur au niveau de la socket dans le dernier téléchargement</td>
+</tr>
+ <tr>
+<td><span class="new_code">getResponseCode()</span></td>
+<td>La réponse HTTP de la page ou de la fenêtre</td>
+</tr>
+ <tr>
+<td><span class="new_code">getMimeType()</span></td>
+<td>Le type Mime de la page our de la fenêtre</td>
+</tr>
+ <tr>
+<td><span class="new_code">getAuthentication()</span></td>
+<td>Le type d'authentification dans l'entête d'une provocation 401</td>
+</tr>
+ <tr>
+<td><span class="new_code">getRealm()</span></td>
+<td>Le realm d'authentification dans l'entête d'une provocation 401</td>
+</tr>
+ <tr>
+<td><span class="new_code">setMaximumRedirects($max)</span></td>
+<td>Nombre de redirections avant que la page ne soit chargée automatiquement</td>
+</tr>
+ <tr>
+<td><span class="new_code">setMaximumNestedFrames($max)</span></td>
+<td>Protection contre des framesets récursifs</td>
+</tr>
+ <tr>
+<td><span class="new_code">ignoreFrames()</span></td>
+<td>Neutralise le support des fenêtres</td>
+</tr>
+ <tr>
+<td><span class="new_code">useFrames()</span></td>
+<td>Autorise le support des fenêtres</td>
+</tr>
+ </tbody></table>
+ Les méthodes <span class="new_code">SimpleBrowser::setConnectionTimeout()</span>,
+ <span class="new_code">SimpleBrowser::setMaximumRedirects()</span>,
+ <span class="new_code">SimpleBrowser::setMaximumNestedFrames()</span>,
+ <span class="new_code">SimpleBrowser::ignoreFrames()</span>
+ et <span class="new_code">SimpleBrowser::useFrames()</span> continuent à s'appliquer
+ sur toutes les requêtes suivantes.
+ Les autres méthodes tiennent compte des fenêtres.
+ Cela veut dire que si une fenêtre individuelle ne se charge pas,
+ il suffit de se diriger vers elle avec
+ <span class="new_code">SimpleBrowser::setFrameFocus()</span> : ensuite on utilisera
+ <span class="new_code">SimpleBrowser::getRequest()</span>, etc. pour voir ce qui se passe.
+ </p>
+
+ <p><a class="target" name="unit"><h2>Tests unitaires complexes avec des navigateurs multiples</h2></a></p>
+ <p>
+ Tout ce qui peut être fait dans
+ <a href="web_tester_documentation.html">WebTestCase</a> peut maintenant
+ être fait dans un <a href="unit_tester_documentation.html">UnitTestCase</a>.
+ Ce qui revient à dire que nous pouvons librement mélanger
+ des tests sur des objets de domaine avec l'interface web...
+<pre><strong>
+class TestOfRegistration extends UnitTestCase {
+ function testNewUserAddedToAuthenticator() {</strong>
+ $browser = &amp;new SimpleBrowser();
+ $browser-&gt;get('http://my-site.com/register.php');
+ $browser-&gt;setField('email', 'me@here');
+ $browser-&gt;setField('password', 'Secret');
+ $browser-&gt;clickSubmit('Register');
+ <strong>
+ $authenticator = &amp;new Authenticator();
+ $member = &amp;$authenticator-&gt;findByEmail('me@here');
+ $this-&gt;assertEqual($member-&gt;getPassword(), 'Secret');</strong>
+ }
+}
+</pre>
+ Bien que ça puisse être utile par convenance temporaire,
+ je ne suis pas fan de ce genre de test. Ce test s'applique
+ à plusieurs couches de l'application, ça implique qu'il est
+ plus que probable qu'il faudra le remanier lorsque le code changera.
+ </p>
+ <p>
+ Un cas plus utile d'utilisation directe du navigateur est
+ le moment où le <span class="new_code">WebTestCase</span> ne peut plus suivre.
+ Un exemple ? Quand deux navigateurs doivent être utilisés en même temps.
+ </p>
+ <p>
+ Par exemple, supposons que nous voulions interdire
+ des usages simultanés d'un site avec le même login d'identification.
+ Ce scénario de test le vérifie...
+<pre>
+class TestOfSecurity extends UnitTestCase {
+ function testNoMultipleLoginsFromSameUser() {
+ $first = &amp;new SimpleBrowser();
+ $first-&gt;get('http://my-site.com/login.php');
+ $first-&gt;setField('name', 'Me');
+ $first-&gt;setField('password', 'Secret');
+ $first-&gt;clickSubmit('Enter');
+ $this-&gt;assertEqual($first-&gt;getTitle(), 'Welcome');
+
+ $second = &amp;new SimpleBrowser();
+ $second-&gt;get('http://my-site.com/login.php');
+ $second-&gt;setField('name', 'Me');
+ $second-&gt;setField('password', 'Secret');
+ $second-&gt;clickSubmit('Enter');
+ $this-&gt;assertEqual($second-&gt;getTitle(), 'Access Denied');
+ }
+}
+</pre>
+ Vous pouvez aussi utiliser la classe <span class="new_code">SimpleBrowser</span>
+ quand vous souhaitez écrire des scénarios de test en utilisant
+ un autre outil que SimpleTest.
+ </p>
+
+ </div>
+ References and related information...
+ <ul>
+<li>
+ La page du projet SimpleTest sur
+ <a href="http://sourceforge.net/projects/simpletest/">SourceForge</a>.
+ </li>
+<li>
+ La page de téléchargement de SimpleTest sur
+ <a href="http://www.lastcraft.com/simple_test.php">LastCraft</a>.
+ </li>
+<li>
+ <a href="http://simpletest.org/api/">L'API de développeur pour SimpleTest</a>
+ donne tous les détails sur les classes et les assertions disponibles.
+ </li>
+</ul>
+<div class="menu_back"><div class="menu">
+<a href="index.html">SimpleTest</a>
+ |
+ <a href="overview.html">Overview</a>
+ |
+ <a href="unit_test_documentation.html">Unit tester</a>
+ |
+ <a href="group_test_documentation.html">Group tests</a>
+ |
+ <a href="mock_objects_documentation.html">Mock objects</a>
+ |
+ <a href="partial_mocks_documentation.html">Partial mocks</a>
+ |
+ <a href="reporter_documentation.html">Reporting</a>
+ |
+ <a href="expectation_documentation.html">Expectations</a>
+ |
+ <a href="web_tester_documentation.html">Web tester</a>
+ |
+ <a href="form_testing_documentation.html">Testing forms</a>
+ |
+ <a href="authentication_documentation.html">Authentication</a>
+ |
+ <a href="browser_documentation.html">Scriptable browser</a>
+</div></div>
+<div class="copyright">
+ Copyright<br>Marcus Baker 2006
+ </div>
+</body>
+</html>
diff --git a/site/vendors/simpletest/docs/fr/docs.css b/site/vendors/simpletest/docs/fr/docs.css
new file mode 100644
index 0000000..4917048
--- /dev/null
+++ b/site/vendors/simpletest/docs/fr/docs.css
@@ -0,0 +1,84 @@
+body {
+ padding-left: 3%;
+ padding-right: 3%;
+}
+pre {
+ font-family: "courier new", courier;
+ font-size: 80%;
+ border: 1px solid;
+ background-color: #cccccc;
+ padding: 5px;
+ margin-left: 5%;
+ margin-right: 8%;
+}
+.code, .new_code, pre.new_code {
+ font-weight: bold;
+}
+div.copyright {
+ font-size: 80%;
+ color: gray;
+}
+div.copyright a {
+ color: gray;
+}
+ul.api {
+ padding-left: 0em;
+ padding-right: 25%;
+}
+ul.api li {
+ margin-top: 0.2em;
+ margin-bottom: 0.2em;
+ list-style: none;
+ text-indent: -3em;
+ padding-left: 3em;
+}
+div.demo {
+ border: 4px ridge;
+ border-color: gray;
+ padding: 10px;
+ margin: 5px;
+ margin-left: 20px;
+ margin-right: 40px;
+ background-color: white;
+}
+div.demo span.fail {
+ color: red;
+}
+div.demo span.pass {
+ color: green;
+}
+div.demo h1 {
+ font-size: 12pt;
+ text-align: left;
+ font-weight: bold;
+}
+table {
+ border: 2px outset;
+ border-color: gray;
+ background-color: white;
+ margin: 5px;
+ margin-left: 5%;
+ margin-right: 5%;
+}
+td {
+ font-size: 80%;
+}
+.shell {
+ color: white;
+}
+pre.shell {
+ border: 4px ridge;
+ border-color: gray;
+ padding: 10px;
+ margin: 5px;
+ margin-left: 20px;
+ margin-right: 40px;
+ background-color: black;
+}
+form.demo {
+ background-color: lightgray;
+ border: 4px outset;
+ border-color: lightgray;
+ padding: 10px;
+ margin-right: 40%;
+}
diff --git a/site/vendors/simpletest/docs/fr/expectation_documentation.html b/site/vendors/simpletest/docs/fr/expectation_documentation.html
new file mode 100644
index 0000000..c9408a7
--- /dev/null
+++ b/site/vendors/simpletest/docs/fr/expectation_documentation.html
@@ -0,0 +1,383 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Documentation SimpleTest : étendre le testeur unitaire avec des classes d'attentes supplémentaires</title>
+<link rel="stylesheet" type="text/css" href="docs.css" title="Styles">
+</head>
+<body>
+<div class="menu_back"><div class="menu">
+<a href="index.html">SimpleTest</a>
+ |
+ <a href="overview.html">Overview</a>
+ |
+ <a href="unit_test_documentation.html">Unit tester</a>
+ |
+ <a href="group_test_documentation.html">Group tests</a>
+ |
+ <a href="mock_objects_documentation.html">Mock objects</a>
+ |
+ <a href="partial_mocks_documentation.html">Partial mocks</a>
+ |
+ <a href="reporter_documentation.html">Reporting</a>
+ |
+ <a href="expectation_documentation.html">Expectations</a>
+ |
+ <a href="web_tester_documentation.html">Web tester</a>
+ |
+ <a href="form_testing_documentation.html">Testing forms</a>
+ |
+ <a href="authentication_documentation.html">Authentication</a>
+ |
+ <a href="browser_documentation.html">Scriptable browser</a>
+</div></div>
+<h1>Documentation sur les attentes</h1>
+ This page...
+ <ul>
+<li>
+ Utiliser les attentes <a href="#fantaisie">pour des tests
+ plus précis avec des objets fantaisie</a>
+ </li>
+<li>
+ <a href="#comportement">Changer le comportement d'un objet fantaisie</a>
+ avec des attentes
+ </li>
+<li>
+ <a href="#etendre">Créer des attentes</a>
+ </li>
+<li>
+ Par dessous SimpleTest <a href="#unitaire">utilise des classes d'attente</a>
+ </li>
+</ul>
+<div class="content">
+ <p><a class="target" name="fantaisie"><h2>Plus de contrôle sur les objets fantaisie</h2></a></p>
+ <p>
+ Le comportement par défaut des
+ <a href="mock_objects_documentation.html">objets fantaisie</a> dans
+ <a href="http://sourceforge.net/projects/simpletest/">SimpleTest</a>
+ est soit une correspondance identique sur l'argument,
+ soit l'acceptation de n'importe quel argument.
+ Pour la plupart des tests, c'est suffisant.
+ Cependant il est parfois nécessaire de ramollir un scénario de test.
+ </p>
+ <p>
+ Un des endroits où un test peut être trop serré
+ est la reconnaissance textuelle. Prenons l'exemple
+ d'un composant qui produirait un message d'erreur
+ utile lorsque quelque chose plante. Il serait utile de tester
+ que l'erreur correcte est renvoyée,
+ mais le texte proprement dit risque d'être plutôt long.
+ Si vous testez le texte dans son ensemble alors
+ à chaque modification de ce même message
+ -- même un point ou une virgule -- vous aurez
+ à revenir sur la suite de test pour la modifier.
+ </p>
+ <p>
+ Voici un cas concret, nous avons un service d'actualités
+ qui a échoué dans sa tentative de connexion à sa source distante.
+<pre>
+<strong>class NewsService {
+ ...
+ function publish(&amp;$writer) {
+ if (! $this-&gt;isConnected()) {
+ $writer-&gt;write('Cannot connect to news service "' .
+ $this-&gt;_name . '" at this time. ' .
+ 'Please try again later.');
+ }
+ ...
+ }
+}</strong>
+</pre>
+ Là il envoie son contenu vers un classe <span class="new_code">Writer</span>.
+ Nous pourrions tester ce comportement avec un <span class="new_code">MockWriter</span>...
+<pre>
+class TestOfNewsService extends UnitTestCase {
+ ...
+ function testConnectionFailure() {<strong>
+ $writer = &amp;new MockWriter($this);
+ $writer-&gt;expectOnce('write', array(
+ 'Cannot connect to news service ' .
+ '"BBC News" at this time. ' .
+ 'Please try again later.'));
+
+ $service = &amp;new NewsService('BBC News');
+ $service-&gt;publish($writer);
+
+ $writer-&gt;tally();</strong>
+ }
+}
+</pre>
+ C'est un bon exemple d'un test fragile.
+ Si nous décidons d'ajouter des instructions complémentaires,
+ par exemple proposer une source d'actualités alternative,
+ nous casserons nos tests par la même occasion sans pourtant
+ avoir modifié une seule fonctionnalité.
+ </p>
+ <p>
+ Pour contourner ce problème, nous voudrions utiliser
+ un test avec une expression rationnelle plutôt
+ qu'une correspondance exacte. Nous pouvons y parvenir avec...
+<pre>
+class TestOfNewsService extends UnitTestCase {
+ ...
+ function testConnectionFailure() {
+ $writer = &amp;new MockWriter($this);<strong>
+ $writer-&gt;expectOnce(
+ 'write',
+ array(new WantedPatternExpectation('/cannot connect/i')));</strong>
+
+ $service = &amp;new NewsService('BBC News');
+ $service-&gt;publish($writer);
+
+ $writer-&gt;tally();
+ }
+}
+</pre>
+ Plutôt que de transmettre le paramètre attendu au <span class="new_code">MockWriter</span>,
+ nous envoyons une classe d'attente appelée <span class="new_code">WantedPatternExpectation</span>.
+ L'objet fantaisie est suffisamment élégant pour reconnaître
+ qu'il s'agit d'un truc spécial et pour le traiter différemment.
+ Plutôt que de comparer l'argument entrant à cet objet,
+ il utilise l'objet attente lui-même pour exécuter le test.
+ </p>
+ <p>
+ <span class="new_code">WantedPatternExpectation</span> utilise
+ l'expression rationnelle pour la comparaison avec son constructeur.
+ A chaque fois qu'une comparaison est fait à travers
+ <span class="new_code">MockWriter</span> par rapport à cette classe attente,
+ elle fera un <span class="new_code">preg_match()</span> avec ce motif.
+ Dans notre scénario de test ci-dessus, aussi longtemps
+ que la chaîne "cannot connect" apparaît dans le texte,
+ la fantaisie transmettra un succès au testeur unitaire.
+ Peu importe le reste du texte.
+ </p>
+ <p>
+ Les classes attente possibles sont...
+ <table><tbody>
+ <tr>
+<td><span class="new_code">EqualExpectation</span></td>
+<td>Une égalité, plutôt que la plus forte comparaison à l'identique</td>
+</tr>
+ <tr>
+<td><span class="new_code">NotEqualExpectation</span></td>
+<td>Une comparaison sur la non-égalité</td>
+</tr>
+ <tr>
+<td><span class="new_code">IndenticalExpectation</span></td>
+<td>La vérification par défaut de l'objet fantaisie qui doit correspondre exactement</td>
+</tr>
+ <tr>
+<td><span class="new_code">NotIndenticalExpectation</span></td>
+<td>Inverse la logique de l'objet fantaisie</td>
+</tr>
+ <tr>
+<td><span class="new_code">WantedPatternExpectation</span></td>
+<td>Utilise une expression rationnelle Perl pour comparer une chaîne</td>
+</tr>
+ <tr>
+<td><span class="new_code">NoUnwantedPatternExpectation</span></td>
+<td>Passe seulement si l'expression rationnelle Perl échoue</td>
+</tr>
+ <tr>
+<td><span class="new_code">IsAExpectation</span></td>
+<td>Vérifie le type ou le nom de la classe uniquement</td>
+</tr>
+ <tr>
+<td><span class="new_code">NotAExpectation</span></td>
+<td>L'opposé de <span class="new_code">IsAExpectation</span>
+</td>
+</tr>
+ <tr>
+<td><span class="new_code">MethodExistsExpectation</span></td>
+<td>Vérifie si la méthode est disponible sur un objet</td>
+</tr>
+ </tbody></table>
+ La plupart utilisent la valeur attendue dans le constructeur.
+ Les exceptions sont les vérifications sur motif,
+ qui utilisent une expression rationnelle, ainsi que
+ <span class="new_code">IsAExpectation</span> et <span class="new_code">NotAExpectation</span>,
+ qui prennent un type ou un nom de classe comme chaîne.
+ </p>
+
+ <p><a class="target" name="comportement"><h2>Utiliser les attentes pour contrôler les bouchons serveur</h2></a></p>
+ <p>
+ Les classes attente peuvent servir à autre chose
+ que l'envoi d'assertions depuis les objets fantaisie,
+ afin de choisir le comportement d'un
+ <a href="mock_objects_documentation.html">objet fantaisie</a>
+ ou celui d'un <a href="server_stubs_documentation.html">bouchon serveur</a>.
+ A chaque fois qu'une liste d'arguments est donnée,
+ une liste d'objets d'attente peut être insérée à la place.
+ </p>
+ <p>
+ Mettons que nous voulons qu'un bouchon serveur
+ d'autorisation simule une connexion réussie seulement
+ si il reçoit un objet de session valide.
+ Nous pouvons y arriver avec ce qui suit...
+<pre>
+Stub::generate('Authorisation');
+<strong>
+$authorisation = new StubAuthorisation();
+$authorisation-&gt;setReturnValue(
+ 'isAllowed',
+ true,
+ array(new IsAExpectation('Session', 'Must be a session')));
+$authorisation-&gt;setReturnValue('isAllowed', false);</strong>
+</pre>
+ Le comportement par défaut du bouchon serveur
+ est défini pour renvoyer <span class="new_code">false</span>
+ quand <span class="new_code">isAllowed</span> est appelé.
+ Lorsque nous appelons cette méthode avec un unique paramètre
+ qui est un objet <span class="new_code">Session</span>, il renverra <span class="new_code">true</span>.
+ Nous avons aussi ajouté un deuxième paramètre comme message.
+ Il sera affiché dans le message d'erreur de l'objet fantaisie
+ si l'attente est la cause de l'échec.
+ </p>
+ <p>
+ Ce niveau de sophistication est rarement utile :
+ il n'est inclut que pour être complet.
+ </p>
+
+ <p><a class="target" name="etendre"><h2>Créer vos propres attentes</h2></a></p>
+ <p>
+ Les classes d'attentes ont une structure très simple.
+ Tellement simple qu'il devient très simple de créer
+ vos propres version de logique pour des tests utilisés couramment.
+ </p>
+ <p>
+ Par exemple voici la création d'une classe pour tester
+ la validité d'adresses IP. Pour fonctionner correctement
+ avec les bouchons serveurs et les objets fantaisie,
+ cette nouvelle classe d'attente devrait étendre
+ <span class="new_code">SimpleExpectation</span>...
+<pre>
+<strong>class ValidIp extends SimpleExpectation {
+
+ function test($ip) {
+ return (ip2long($ip) != -1);
+ }
+
+ function testMessage($ip) {
+ return "Address [$ip] should be a valid IP address";
+ }
+}</strong>
+</pre>
+ Il n'y a véritablement que deux méthodes à mettre en place.
+ La méthode <span class="new_code">test()</span> devrait renvoyer un <span class="new_code">true</span>
+ si l'attente doit passer, et une erreur <span class="new_code">false</span>
+ dans le cas contraire. La méthode <span class="new_code">testMessage()</span>
+ ne devrait renvoyer que du texte utile à la compréhension du test en lui-même.
+ </p>
+ <p>
+ Cette classe peut désormais être employée à la place
+ des classes d'attente précédentes.
+ </p>
+
+ <p><a class="target" name="unitaire"><h2>Sous le capot du testeur unitaire</h2></a></p>
+ <p>
+ Le <a href="http://sourceforge.net/projects/simpletest/">framework
+ de test unitaire SimpleTest</a> utilise aussi dans son coeur
+ des classes d'attente pour
+ la <a href="unit_test_documentation.html">classe UnitTestCase</a>.
+ Nous pouvons aussi tirer parti de ces mécanismes pour réutiliser
+ nos propres classes attente à l'intérieur même des suites de test.
+ </p>
+ <p>
+ La méthode la plus directe est d'utiliser la méthode
+ <span class="new_code">SimpleTest::assertExpectation()</span> pour effectuer le test...
+<pre>
+<strong>class TestOfNetworking extends UnitTestCase {
+ ...
+ function testGetValidIp() {
+ $server = &amp;new Server();
+ $this-&gt;assertExpectation(
+ new ValidIp(),
+ $server-&gt;getIp(),
+ 'Server IP address-&gt;%s');
+ }
+}</strong>
+</pre>
+ C'est plutôt sale par rapport à notre syntaxe habituelle
+ du type <span class="new_code">assert...()</span>.
+ </p>
+ <p>
+ Pour un cas aussi simple, nous créons d'ordinaire une méthode
+ d'assertion distincte en utilisant la classe d'attente.
+ Supposons un instant que notre attente soit un peu plus
+ compliquée et que par conséquent nous souhaitions la réutiliser,
+ nous obtenons...
+<pre>
+class TestOfNetworking extends UnitTestCase {
+ ...<strong>
+ function assertValidIp($ip, $message = '%s') {
+ $this-&gt;assertExpectation(new ValidIp(), $ip, $message);
+ }</strong>
+
+ function testGetValidIp() {
+ $server = &amp;new Server();<strong>
+ $this-&gt;assertValidIp(
+ $server-&gt;getIp(),
+ 'Server IP address-&gt;%s');</strong>
+ }
+}
+</pre>
+ Il est peu probable que nous ayons besoin
+ de ce niveau de contrôle sur la machinerie de test.
+ Il est assez rare que le besoin d'une attente dépasse
+ le stade de la reconnaissance d'un motif.
+ De plus, les classes d'attente complexes peuvent rendre
+ les tests difficiles à lire et à déboguer.
+ Ces mécanismes sont véritablement là pour les auteurs
+ de système qui étendront le framework de test
+ pour leurs propres outils de test.
+ </p>
+
+ </div>
+ References and related information...
+ <ul>
+<li>
+ La page du projet SimpleTest sur
+ <a href="http://sourceforge.net/projects/simpletest/">SourceForge</a>.
+ </li>
+<li>
+ La page de téléchargement de SimpleTest sur
+ <a href="http://www.lastcraft.com/simple_test.php">LastCraft</a>.
+ </li>
+<li>
+ Les attentes imitent les contraintes dans
+ <a href="http://www.jmock.org/">JMock</a>.
+ </li>
+<li>
+ <a href="http://simpletest.org/api/">L'API complète pour SimpleTest</a>
+ réalisé avec PHPDoc.
+ </li>
+</ul>
+<div class="menu_back"><div class="menu">
+<a href="index.html">SimpleTest</a>
+ |
+ <a href="overview.html">Overview</a>
+ |
+ <a href="unit_test_documentation.html">Unit tester</a>
+ |
+ <a href="group_test_documentation.html">Group tests</a>
+ |
+ <a href="mock_objects_documentation.html">Mock objects</a>
+ |
+ <a href="partial_mocks_documentation.html">Partial mocks</a>
+ |
+ <a href="reporter_documentation.html">Reporting</a>
+ |
+ <a href="expectation_documentation.html">Expectations</a>
+ |
+ <a href="web_tester_documentation.html">Web tester</a>
+ |
+ <a href="form_testing_documentation.html">Testing forms</a>
+ |
+ <a href="authentication_documentation.html">Authentication</a>
+ |
+ <a href="browser_documentation.html">Scriptable browser</a>
+</div></div>
+<div class="copyright">
+ Copyright<br>Marcus Baker 2006
+ </div>
+</body>
+</html>
diff --git a/site/vendors/simpletest/docs/fr/form_testing_documentation.html b/site/vendors/simpletest/docs/fr/form_testing_documentation.html
new file mode 100644
index 0000000..4c30ef0
--- /dev/null
+++ b/site/vendors/simpletest/docs/fr/form_testing_documentation.html
@@ -0,0 +1,349 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Documentation SimpleTest : tester des formulaires HTML</title>
+<link rel="stylesheet" type="text/css" href="docs.css" title="Styles">
+</head>
+<body>
+<div class="menu_back"><div class="menu">
+<a href="index.html">SimpleTest</a>
+ |
+ <a href="overview.html">Overview</a>
+ |
+ <a href="unit_test_documentation.html">Unit tester</a>
+ |
+ <a href="group_test_documentation.html">Group tests</a>
+ |
+ <a href="mock_objects_documentation.html">Mock objects</a>
+ |
+ <a href="partial_mocks_documentation.html">Partial mocks</a>
+ |
+ <a href="reporter_documentation.html">Reporting</a>
+ |
+ <a href="expectation_documentation.html">Expectations</a>
+ |
+ <a href="web_tester_documentation.html">Web tester</a>
+ |
+ <a href="form_testing_documentation.html">Testing forms</a>
+ |
+ <a href="authentication_documentation.html">Authentication</a>
+ |
+ <a href="browser_documentation.html">Scriptable browser</a>
+</div></div>
+<h1>Documentation sur les tests de formulaire</h1>
+ This page...
+ <ul>
+<li>
+ Modifier les valeurs d'un formulaire et
+ <a href="#submit">réussir à transmettre un simple formulaire</a>
+ </li>
+<li>
+ Gérer des <a href="#multiple">objets à valeurs multiples</a>
+ en initialisant des listes.
+ </li>
+<li>
+ Le cas des formulaires utilisant Javascript pour
+ modifier <a href="#hidden-field">un champ caché</a>
+ </li>
+<li>
+ <a href="#brut">Envoi brut</a> quand il n'existe pas de bouton à cliquer.
+ </li>
+</ul>
+<div class="content">
+ <p><a class="target" name="submit"><h2>Valider un formulaire simple</h2></a></p>
+ <p>
+ Lorsqu'une page est téléchargée par <span class="new_code">WebTestCase</span>
+ en utilisant <span class="new_code">get()</span> ou <span class="new_code">post()</span>
+ le contenu de la page est automatiquement analysé.
+ De cette analyse découle le fait que toutes les commandes
+ à l'intérieur de la balise &lt;form&gt; sont disponibles
+ depuis l'intérieur du scénario de test.
+ Prenons par exemple cet extrait de code HTML...
+<pre>
+&lt;form&gt;
+ &lt;input type="text" name="a" value="A default" /&gt;
+ &lt;input type="submit" value="Go" /&gt;
+&lt;/form&gt;
+</pre>
+ Il ressemble à...
+ </p>
+ <p>
+ <form class="demo">
+ <input type="text" name="a" value="A default">
+ <input type="submit" value="Go">
+ </form>
+ </p>
+ <p>
+ Nous pouvons naviguer vers ce code, via le site
+ <a href="http://www.lastcraft.com/form_testing_documentation.php">LastCraft</a>,
+ avec le test suivant...
+<pre>
+class SimpleFormTests extends WebTestCase {
+ <strong>
+ function testDefaultValue() {
+ $this-&gt;get('http://www.lastcraft.com/form_testing_documentation.php');
+ $this-&gt;assertField('a', 'A default');
+ }</strong>
+}
+</pre>
+ Directement après le chargement de la page toutes les commandes HTML
+ sont initiées avec leur valeur par défaut, comme elles apparaîtraient
+ dans un navigateur web. L'assertion teste qu'un objet HTML
+ avec le nom "a" existe dans la page
+ et qu'il contient la valeur "A default".
+ </p>
+ <p>
+ Nous pourrions retourner le formulaire tout de suite,
+ mais d'abord nous allons changer la valeur du champ texte.
+ Ce n'est qu'après que nous le transmettrons...
+<pre>
+class SimpleFormTests extends WebTestCase {
+
+ function testDefaultValue() {
+ $this-&gt;get('http://www.my-site.com/');
+ $this-&gt;assertField('a', 'A default');<strong>
+ $this-&gt;setField('a', 'New value');
+ $this-&gt;clickSubmit('Go');</strong>
+ }
+}
+</pre>
+ Parce que nous n'avons spécifié ni attribut "method"
+ sur la balise form, ni attribut "action",
+ le scénario de test suivra le comportement classique d'un navigateur :
+ transmission des données avec une requête <em>GET</em>
+ vers la même page. SimpleTest essaie d'émuler
+ le comportement typique d'un navigateur autant que possible,
+ plutôt que d'essayer d'attraper des attributs manquants sur les balises.
+ La raison est simple : la cible d'un framework de test est
+ la logique d'une application PHP, pas les erreurs
+ -- de syntaxe ou autres -- du code HTML.
+ Pour les erreurs HTML, d'autres outils tel
+ <a href="http://www.w3.org/People/Raggett/tidy/">HTMLTidy</a>
+ devraient être employés.
+ </p>
+ <p>
+ Si un champ manque dans n'importe quel formulaire ou si
+ une option est indisponible alors <span class="new_code">WebTestCase::setField()</span>
+ renverra <span class="new_code">false</span>. Par exemple, supposons que
+ nous souhaitons vérifier qu'une option "Superuser"
+ n'est pas présente dans ce formulaire...
+<pre>
+&lt;strong&gt;Select type of user to add:&lt;/strong&gt;
+&lt;select name="type"&gt;
+ &lt;option&gt;Subscriber&lt;/option&gt;
+ &lt;option&gt;Author&lt;/option&gt;
+ &lt;option&gt;Administrator&lt;/option&gt;
+&lt;/select&gt;
+</pre>
+ Qui ressemble à...
+ </p>
+ <p>
+ <form class="demo">
+ <strong>Select type of user to add:</strong>
+ <select name="type">
+ <option>Subscriber</option>
+ <option>Author</option>
+ <option>Administrator</option>
+ </select>
+ </form>
+ </p>
+ <p>
+ Le test suivant le confirmera...
+<pre>
+class SimpleFormTests extends WebTestCase {
+ ...
+ function testNoSuperuserChoiceAvailable() {<strong>
+ $this-&gt;get('http://www.lastcraft.com/form_testing_documentation.php');
+ $this-&gt;assertFalse($this-&gt;setField('type', 'Superuser'));</strong>
+ }
+}
+</pre>
+ La sélection ne sera pas changée suite à un échec d'initialisation
+ d'une valeur sur un objet.
+ </p>
+ <p>
+ Voici la liste complète des objets supportés à aujourd'hui...
+ <ul>
+ <li>Champs texte, y compris les champs masqués (hidden) ou cryptés (password).</li>
+ <li>Boutons submit, en incluant aussi la balise button, mais pas encore les boutons reset</li>
+ <li>Aires texte (textarea) avec leur gestion des retours à la ligne (wrap).</li>
+ <li>Cases à cocher, y compris les cases à cocher multiples dans un même formulaire.</li>
+ <li>Listes à menu déroulant, y compris celles à sélections multiples.</li>
+ <li>Boutons radio.</li>
+ <li>Images.</li>
+ </ul>
+ </p>
+ <p>
+ Le navigateur proposé par SimpleTest émule les actions
+ qui peuvent être réalisées par un utilisateur sur
+ une page HTML standard. Javascript n'est pas supporté et
+ il y a peu de chance pour qu'il le soit prochainement.
+ </p>
+ <p>
+ Une attention particulière doit être porté aux techniques Javascript
+ qui changent la valeur d'un champ caché : elles ne peuvent pas être
+ réalisées avec les commandes classiques de SimpleTest.
+ Une méthode alternative est proposée plus loin.
+ </p>
+
+ <p><a class="target" name="multiple"><h2>Champs à valeurs multiples</h2></a></p>
+ <p>
+ SimpleTest peut gérer deux types de commandes à valeur multiple :
+ les menus déroulants à sélection multiple et les cases à cocher
+ avec le même nom à l'intérieur même d'un formulaire.
+ La nature de ceux-ci implique que leur initialisation
+ et leur test sont légèrement différents.
+ Voici un exemple avec des cases à cocher...
+<pre>
+&lt;form class="demo"&gt;
+ &lt;strong&gt;Create privileges allowed:&lt;/strong&gt;
+ &lt;input type="checkbox" name="crud" value="c" checked&gt;&lt;br&gt;
+ &lt;strong&gt;Retrieve privileges allowed:&lt;/strong&gt;
+ &lt;input type="checkbox" name="crud" value="r" checked&gt;&lt;br&gt;
+ &lt;strong&gt;Update privileges allowed:&lt;/strong&gt;
+ &lt;input type="checkbox" name="crud" value="u" checked&gt;&lt;br&gt;
+ &lt;strong&gt;Destroy privileges allowed:&lt;/strong&gt;
+ &lt;input type="checkbox" name="crud" value="d" checked&gt;&lt;br&gt;
+ &lt;input type="submit" value="Enable Privileges"&gt;
+&lt;/form&gt;
+</pre>
+ Qui se traduit par...
+ </p>
+ <p>
+ <form class="demo">
+ <strong>Create privileges allowed:</strong>
+ <input type="checkbox" name="crud" value="c" checked><br>
+ <strong>Retrieve privileges allowed:</strong>
+ <input type="checkbox" name="crud" value="r" checked><br>
+ <strong>Update privileges allowed:</strong>
+ <input type="checkbox" name="crud" value="u" checked><br>
+ <strong>Destroy privileges allowed:</strong>
+ <input type="checkbox" name="crud" value="d" checked><br>
+ <input type="submit" value="Enable Privileges">
+ </form>
+ </p>
+ <p>
+ Si nous souhaitons désactiver tous les privilèges sauf
+ ceux de téléchargement (Retrieve) et transmettre cette information,
+ nous pouvons y arriver par...
+<pre>
+class SimpleFormTests extends WebTestCase {
+ ...<strong>
+ function testDisableNastyPrivileges() {
+ $this-&gt;get('http://www.lastcraft.com/form_testing_documentation.php');
+ $this-&gt;assertField('crud', array('c', 'r', 'u', 'd'));
+ $this-&gt;setField('crud', array('r'));
+ $this-&gt;clickSubmit('Enable Privileges');
+ }</strong>
+}
+</pre>
+ Plutôt que d'initier le champ à une valeur unique,
+ nous lui donnons une liste de valeurs.
+ Nous faisons la même chose pour tester les valeurs attendues.
+ Nous pouvons écrire d'autres bouts de code de test
+ pour confirmer cet effet, peut-être en nous connectant
+ comme utilisateur et en essayant d'effectuer une mise à jour.
+ </p>
+
+ <p><a class="target" name="hidden-field"><h2>Formulaires utilisant Javascript pour changer un champ caché</h2></a></p>
+ <p>
+ Si vous souhaitez tester un formulaire dépendant de Javascript
+ pour la modification d'un champ caché, vous ne pouvez pas
+ simplement utiliser setField().
+ Le code suivant <em>ne fonctionnera pas</em> :
+<pre>
+class SimpleFormTests extends WebTestCase {
+ function testMyJavascriptForm() {
+ <strong>// Ne fonctionne *pas*</strong>
+ $this-&gt;setField('un_champ_caché', '123');
+ $this-&gt;clickSubmit('OK');
+ }
+}
+</pre>
+ A la place, vous aurez besoin d'ajouter le paramètre supplémentaire
+ du formulaire à la méthode clickSubmit() :
+<pre>
+class SimpleFormTests extends WebTestCase {
+ function testMyJavascriptForm() {
+ // Ajoute le champ caché comme variable POST supplémentaire
+ <strong>$this-&gt;clickSubmit('OK', array('un_champ_caché'=&gt;'123'));</strong>
+ }
+
+}
+</pre>
+ </p>
+ <p>
+ N'oubliez pas que de la sorte, vous êtes effectivement en train
+ de court-circuitez une partie de votre application (le code Javascript
+ dans le formulaire) et que peut-être serait-il plus prudent
+ d'utiliser un outil comme
+ <a href="http://selenium.openqa.org/">Selenium</a> pour mettre sur pied
+ un test de recette complet.
+ </p>
+
+ <p><a class="target" name="brut"><h2>Envoi brut</h2></a></p>
+ <p>
+ Si vous souhaitez tester un gestionnaire de formulaire
+ mais que vous ne l'avez pas écrit ou que vous n'y avez
+ pas encore accès, vous pouvez créer un envoi de formulaire à la main.
+<pre>
+class SimpleFormTests extends WebTestCase {
+ ...<strong>
+ function testAttemptedHack() {
+ $this-&gt;post(
+ 'http://www.my-site.com/add_user.php',
+ array('type' =&gt; 'superuser'));
+ $this-&gt;assertNoUnwantedPattern('/user created/i');
+ }</strong>
+}
+</pre>
+ En ajoutant des données à la méthode <span class="new_code">WebTestCase::post()</span>,
+ nous essayons de télécharger la page via la transmission d'un formulaire.
+ </p>
+
+ </div>
+ References and related information...
+ <ul>
+<li>
+ La page du projet SimpleTest sur
+ <a href="http://sourceforge.net/projects/simpletest/">SourceForge</a>.
+ </li>
+<li>
+ La page de téléchargement de SimpleTest sur
+ <a href="http://www.lastcraft.com/simple_test.php">LastCraft</a>.
+ </li>
+<li>
+ <a href="http://simpletest.org/api/">L'API du développeur pour SimpleTest</a>
+ donne tous les détails sur les classes et les assertions disponibles.
+ </li>
+</ul>
+<div class="menu_back"><div class="menu">
+<a href="index.html">SimpleTest</a>
+ |
+ <a href="overview.html">Overview</a>
+ |
+ <a href="unit_test_documentation.html">Unit tester</a>
+ |
+ <a href="group_test_documentation.html">Group tests</a>
+ |
+ <a href="mock_objects_documentation.html">Mock objects</a>
+ |
+ <a href="partial_mocks_documentation.html">Partial mocks</a>
+ |
+ <a href="reporter_documentation.html">Reporting</a>
+ |
+ <a href="expectation_documentation.html">Expectations</a>
+ |
+ <a href="web_tester_documentation.html">Web tester</a>
+ |
+ <a href="form_testing_documentation.html">Testing forms</a>
+ |
+ <a href="authentication_documentation.html">Authentication</a>
+ |
+ <a href="browser_documentation.html">Scriptable browser</a>
+</div></div>
+<div class="copyright">
+ Copyright<br>Marcus Baker 2006
+ </div>
+</body>
+</html>
diff --git a/site/vendors/simpletest/docs/fr/group_test_documentation.html b/site/vendors/simpletest/docs/fr/group_test_documentation.html
new file mode 100644
index 0000000..b993475
--- /dev/null
+++ b/site/vendors/simpletest/docs/fr/group_test_documentation.html
@@ -0,0 +1,398 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Documentation SimpleTest : Grouper des tests</title>
+<link rel="stylesheet" type="text/css" href="docs.css" title="Styles">
+</head>
+<body>
+<div class="menu_back"><div class="menu">
+<a href="index.html">SimpleTest</a>
+ |
+ <a href="overview.html">Overview</a>
+ |
+ <a href="unit_test_documentation.html">Unit tester</a>
+ |
+ <a href="group_test_documentation.html">Group tests</a>
+ |
+ <a href="mock_objects_documentation.html">Mock objects</a>
+ |
+ <a href="partial_mocks_documentation.html">Partial mocks</a>
+ |
+ <a href="reporter_documentation.html">Reporting</a>
+ |
+ <a href="expectation_documentation.html">Expectations</a>
+ |
+ <a href="web_tester_documentation.html">Web tester</a>
+ |
+ <a href="form_testing_documentation.html">Testing forms</a>
+ |
+ <a href="authentication_documentation.html">Authentication</a>
+ |
+ <a href="browser_documentation.html">Scriptable browser</a>
+</div></div>
+<h1>Documentation sur le groupement des tests</h1>
+ This page...
+ <ul>
+<li>
+ Plusieurs approches pour <a href="#group">grouper des tests</a> ensemble.
+ </li>
+<li>
+ Combiner des groupes des tests dans des
+ <a href="#plus-haut">groupes plus grands</a>.
+ </li>
+<li>
+ Intégrer des <a href="#heritage">scénarios de test hérités</a>
+ d'un autre type de PHPUnit.
+ </li>
+</ul>
+<div class="content">
+ <p><a class="target" name="grouper"><h2>Grouper des tests</h2></a></p>
+ <p>
+ Pour lancer les scénarios de tests en tant que groupe,
+ ils devraient être placés dans des fichiers sans le code du lanceur...
+<pre>
+<strong>&lt;?php
+ require_once('../classes/io.php');
+
+ class FileTester extends UnitTestCase {
+ ...
+ }
+
+ class SocketTester extends UnitTestCase {
+ ...
+ }
+?&gt;</strong>
+</pre>
+ Autant de scénarios que nécessaires peuvent être
+ mis dans un fichier unique. Ils doivent contenir
+ tout le code nécessaire, entre autres la bibliothèque testée,
+ mais aucune des bibliothèques de SimpleTest.
+ </p>
+ <p>
+ Si vous avez étendu l'un ou l'autre des scénarios de test,
+ vous pouvez aussi les inclure.
+<pre>
+&lt;?php
+ require_once('../classes/io.php');
+<strong>
+ class MyFileTestCase extends UnitTestCase {
+ ...
+ }
+ SimpleTestOptions::ignore('MyFileTestCase');</strong>
+
+ class FileTester extends MyFileTestCase {
+ ...
+ }
+
+ class SocketTester extends UnitTestCase {
+ ...
+ }
+?&gt;
+</pre>
+ La classe <span class="new_code">FileTester</span> ne contient aucun test véritable,
+ il s'agit d'une classe de base pour d'autres scénarios de test.
+ Pour cette raison nous utilisons la directive
+ <span class="new_code">SimpleTestOptions::ignore()</span> pour indiquer
+ au prochain groupe de tests de l'ignorer.
+ Cette directive peut se placer n'importe où dans le fichier
+ et fonctionne quand un fichier complet des scénarios de test
+ est chargé (cf. ci-dessous).
+ Nous l'appelons <em>file_test.php</em>.
+ </p>
+ <p>
+ Ensuite nous créons un fichier de groupe de tests,
+ disons <em>group_test.php</em>.
+ Vous penserez à un nom plus convaincant, j'en suis sûr.
+ Nous lui ajoutons le fichier de test avec une méthode sans risque...
+<pre>
+&lt;?php
+ require_once('simpletest/unit_tester.php');
+ require_once('simpletest/reporter.php');<strong>
+ require_once('file_test.php');
+
+ $test = &amp;new GroupTest('All file tests');
+ $test-&gt;addTestCase(new FileTestCase());
+ $test-&gt;run(new HtmlReporter());</strong>
+?&gt;
+</pre>
+ Ceci instancie le scénario de test avant que
+ la suite de test ne soit lancée.
+ Ça pourrait devenir assez onéreux avec
+ un grand nombre de scénarios de test :
+ il existe donc une autre méthode qui instancie
+ la classe uniquement quand elle devient nécessaire...
+<pre>
+&lt;?php
+ require_once('simpletest/unit_tester.php');
+ require_once('simpletest/reporter.php');
+ require_once('file_test.php');
+
+ $test = &amp;new GroupTest('All file tests');<strong>
+ $test-&gt;addTestClass('FileTestCase');</strong>
+ $test-&gt;run(new HtmlReporter());
+?&gt;
+</pre>
+ Le problème de cette technique est que pour
+ chaque scénario de test supplémentaire nous aurons à importer
+ (via <span class="new_code">require_once()</span>) le fichier de code de test
+ et à instancier manuellement chaque scénario de test.
+ Nous pouvons nous épargner beaucoup de dactylographie avec...
+<pre>
+&lt;?php
+ require_once('simpletest/unit_tester.php');
+ require_once('simpletest/reporter.php');
+
+ $test = &amp;new GroupTest('All file tests');<strong>
+ $test-&gt;addTestFile('file_test.php');</strong>
+ $test-&gt;run(new HtmlReporter());
+?&gt;
+</pre>
+ Voici ce qui vient de se passer :
+ la classe <span class="new_code">GroupTest</span> a réalisé le
+ <span class="new_code">require_once()</span> pour nous.
+ Ensuite elle vérifie si de nouvelles classes de scénario
+ de test ont été créées par ce nouveau fichier
+ et les ajoute automatiquement au groupe de tests.
+ Désormais tout ce qu'il nous reste à faire,
+ c'est d'ajouter chaque nouveau fichier.
+ </p>
+ <p>
+ Il y a deux choses qui peuvent planter
+ et qui demandent un minimum d'attention...
+ <ol>
+ <li>
+ Le fichier peut déjà avoir été analysé par PHP
+ et dans ce cas aucune classe ne sera ajoutée.
+ Pensez à bien vérifier que les scénarios de test
+ ne sont inclus que dans ce fichier et dans aucun autre
+ (Note : avec la nouvelle fonctionnalité <cite>autorun</cite>,
+ ce problème a maintenant été résolu).
+ </li>
+ <li>
+ Les nouvelles classes d'extension de scénario
+ de test qui sont incluses seront placées
+ dans le groupe de tests et exécutées par la même occasion.
+ Vous aurez à ajouter une directive
+ <span class="new_code">SimpleTestOptions::ignore()</span> pour ces classes
+ ou alors pensez à les ajouter avant la ligne
+ <span class="new_code">GroupTest::addTestFile()</span>.
+ </li>
+ </ol>
+ </p>
+
+ <p><a class="target" name="plus-haut"><h2>Groupements de plus haut niveau</h2></a></p>
+ <p>
+ La technique ci-dessus place tous les scénarios de test
+ dans un unique et grand groupe.
+ Sauf que pour des projets plus conséquents,
+ ce n'est probablement pas assez souple;
+ vous voudriez peut-être grouper les tests tout à fait différemment.
+ </p>
+ <p>
+ Pour obtenir un groupe de tests plus souple
+ nous pouvons sous classer <span class="new_code">GroupTest</span>
+ et ensuite l'instancier au cas par cas...
+<pre>
+&lt;?php
+ require_once('simpletest/unit_tester.php');
+ require_once('simpletest/reporter.php');
+ <strong>
+ class FileGroupTest extends GroupTest {
+ function FileGroupTest() {
+ $this-&gt;GroupTest('All file tests');
+ $this-&gt;addTestFile('file_test.php');
+ }
+ }</strong>
+?&gt;
+</pre>
+ Ceci nomme le test dans le constructeur
+ et ensuite ajoute à la fois nos scénarios
+ de test et un unique groupe en dessous.
+ Bien sûr nous pouvons ajouter plus d'un groupe à cet instant.
+ Nous pouvons maintenant invoquer les tests
+ à partir d'un autre fichier d'exécution...
+<pre>
+&lt;?php
+ require_once('file_group_test.php');
+ <strong>
+ $test = &amp;new FileGroupTest();
+ $test-&gt;run(new HtmlReporter());</strong>
+?&gt;
+</pre>
+ ...ou alors nous pouvons les grouper
+ dans un groupe de tests encore plus grand...
+<pre>
+&lt;?php
+ require_once('file_group_test.php');
+ <strong>
+ $test = &amp;new BigGroupTest('Big group');
+ $test-&gt;addTestCase(new FileGroupTest());
+ $test-&gt;addTestCase(...);
+ $test-&gt;run(new HtmlReporter());</strong>
+?&gt;
+</pre>
+ Si nous souhaitons lancer le groupe de tests original
+ sans utiliser ses petits fichiers d'exécution,
+ nous pouvons mettre le code du lanceur de test
+ derrière des barreaux quand nous créons chaque groupe.
+<pre>
+&lt;?php
+ class FileGroupTest extends GroupTest {
+ function FileGroupTest() {
+ $this-&gt;GroupTest('All file tests');
+ $test-&gt;addTestFile('file_test.php');
+ }
+ }
+ <strong>
+ if (! defined('RUNNER')) {
+ define('RUNNER', true);</strong>
+ $test = &amp;new FileGroupTest();
+ $test-&gt;run(new HtmlReporter());
+ }
+?&gt;
+</pre>
+ Cette approche exige aux barrières d'être activées
+ à l'inclusion du fichier de groupe de tests,
+ mais c'est quand même moins de tracas que beaucoup
+ de fichiers de lancement éparpillés.
+ Reste à inclure des barreaux identiques
+ au niveau supérieur afin de s'assurer que
+ le <span class="new_code">run()</span> ne sera lancé qu'une seule fois
+ à partir du script de haut niveau qui l'a invoqué.
+<pre>
+&lt;?php
+ define('RUNNER', true);
+
+ require_once('file_group_test.php');
+ $test = &amp;new BigGroupTest('Big group');
+ $test-&gt;addTestCase(new FileGroupTest());
+ $test-&gt;addTestCase(...);
+ $test-&gt;run(new HtmlReporter());
+?&gt;
+</pre>
+ Comme les scénarios de test normaux,
+ un <span class="new_code">GroupTest</span> peut être chargé avec la méthode
+ <span class="new_code">GroupTest::addTestFile()</span>.
+<pre>
+&lt;?php
+ define('RUNNER', true);
+
+ $test = &amp;new BigGroupTest('Big group');<strong>
+ $test-&gt;addTestFile('file_group_test.php');
+ $test-&gt;addTestFile(...);</strong>
+ $test-&gt;run(new HtmlReporter());
+?&gt;
+</pre>
+ </p>
+
+ <p><a class="target" name="heritage"><h2>Intégrer des scénarios de test hérités</h2></a></p>
+ <p>
+ Si vous avez déjà des tests unitaires pour votre code
+ ou alors si vous étendez des classes externes
+ qui ont déjà leurs propres tests, il y a peu de chances
+ pour que ceux-ci soient déjà au format SimpleTest.
+ Heureusement il est possible d'incorporer ces scénarios
+ de test en provenance d'autres testeurs unitaires
+ directement dans des groupes de test SimpleTest.
+ </p>
+ <p>
+ Par exemple, supposons que nous ayons
+ ce scénario de test prévu pour
+ <a href="http://sourceforge.net/projects/phpunit">PhpUnit</a>
+ dans le fichier <em>config_test.php</em>...
+<pre>
+<strong>class ConfigFileTest extends TestCase {
+ function ConfigFileTest() {
+ $this-&gt;TestCase('Config file test');
+ }
+
+ function testContents() {
+ $config = new ConfigFile('test.conf');
+ $this-&gt;assertRegexp('/me/', $config-&gt;getValue('username'));
+ }
+}</strong>
+</pre>
+ Le groupe de tests peut le reconnaître à partir
+ du moment où nous mettons l'adaptateur approprié
+ avant d'ajouter le fichier de test...
+<pre>
+&lt;?php
+ require_once('simpletest/unit_tester.php');
+ require_once('simpletest/reporter.php');<strong>
+ require_once('simpletest/adapters/phpunit_test_case.php');</strong>
+
+ $test = &amp;new GroupTest('All file tests');<strong>
+ $test-&gt;addTestFile('config_test.php');</strong>
+ $test-&gt;run(new HtmlReporter());
+?&gt;
+</pre>
+ Il n'y a que deux adaptateurs,
+ l'autre est pour le paquet testeur unitaire de
+ <a href="http://pear.php.net/manual/en/package.php.phpunit.php">PEAR</a>...
+<pre>
+&lt;?php
+ require_once('simpletest/unit_tester.php');
+ require_once('simpletest/reporter.php');<strong>
+ require_once('simpletest/adapters/pear_test_case.php');</strong>
+
+ $test = &amp;new GroupTest('All file tests');<strong>
+ $test-&gt;addTestFile('some_pear_test_cases.php');</strong>
+ $test-&gt;run(new HtmlReporter());
+?&gt;
+</pre>
+ Les scénarios de test de PEAR peuvent être
+ librement mélangés avec ceux de SimpleTest
+ mais vous ne pouvez pas utiliser les assertions
+ de SimpleTest au sein des versions héritées
+ des scénarios de test. La raison ?
+ Une simple vérification que vous ne rendez pas
+ par accident vos scénarios de test complètement
+ dépendants de SimpleTest.
+ Peut-être que vous souhaitez publier
+ votre bibliothèque sur PEAR par exemple :
+ ça voudrait dire la livrer avec des scénarios de
+ test compatibles avec PEAR::PhpUnit.
+ </p>
+
+ </div>
+ References and related information...
+ <ul>
+<li>
+ La page du projet SimpleTest sur
+ <a href="http://sourceforge.net/projects/simpletest/">SourceForge</a>.
+ </li>
+<li>
+ La page de téléchargement de SimpleTest sur
+ <a href="http://www.lastcraft.com/simple_test.php">LastCraft</a>.
+ </li>
+</ul>
+<div class="menu_back"><div class="menu">
+<a href="index.html">SimpleTest</a>
+ |
+ <a href="overview.html">Overview</a>
+ |
+ <a href="unit_test_documentation.html">Unit tester</a>
+ |
+ <a href="group_test_documentation.html">Group tests</a>
+ |
+ <a href="mock_objects_documentation.html">Mock objects</a>
+ |
+ <a href="partial_mocks_documentation.html">Partial mocks</a>
+ |
+ <a href="reporter_documentation.html">Reporting</a>
+ |
+ <a href="expectation_documentation.html">Expectations</a>
+ |
+ <a href="web_tester_documentation.html">Web tester</a>
+ |
+ <a href="form_testing_documentation.html">Testing forms</a>
+ |
+ <a href="authentication_documentation.html">Authentication</a>
+ |
+ <a href="browser_documentation.html">Scriptable browser</a>
+</div></div>
+<div class="copyright">
+ Copyright<br>Marcus Baker 2006
+ </div>
+</body>
+</html>
diff --git a/site/vendors/simpletest/docs/fr/index.html b/site/vendors/simpletest/docs/fr/index.html
new file mode 100644
index 0000000..a13cb57
--- /dev/null
+++ b/site/vendors/simpletest/docs/fr/index.html
@@ -0,0 +1,572 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>
+ Prise en main rapide de SimpleTest pour PHP -
+ Tests unitaire et objets fantaisie pour PHP
+ </title>
+<link rel="stylesheet" type="text/css" href="docs.css" title="Styles">
+</head>
+<body>
+<div class="menu_back"><div class="menu">
+<a href="index.html">SimpleTest</a>
+ |
+ <a href="overview.html">Overview</a>
+ |
+ <a href="unit_test_documentation.html">Unit tester</a>
+ |
+ <a href="group_test_documentation.html">Group tests</a>
+ |
+ <a href="mock_objects_documentation.html">Mock objects</a>
+ |
+ <a href="partial_mocks_documentation.html">Partial mocks</a>
+ |
+ <a href="reporter_documentation.html">Reporting</a>
+ |
+ <a href="expectation_documentation.html">Expectations</a>
+ |
+ <a href="web_tester_documentation.html">Web tester</a>
+ |
+ <a href="form_testing_documentation.html">Testing forms</a>
+ |
+ <a href="authentication_documentation.html">Authentication</a>
+ |
+ <a href="browser_documentation.html">Scriptable browser</a>
+</div></div>
+<h1>Prise en main rapide de SimpleTest</h1>
+ This page...
+ <ul>
+<li>
+ <a href="#unit">Utiliser le testeur rapidement</a>
+ avec un exemple.
+ </li>
+<li>
+ <a href="#group">Groupes de tests</a>
+ pour tester en un seul clic.
+ </li>
+<li>
+ <a href="#mock">Utiliser les objets fantaisie</a>
+ pour faciliter les tests et gagner en contrôle.
+ </li>
+<li>
+ <a href="#web">Tester des pages web</a>
+ au niveau de l'HTML.
+ </li>
+</ul>
+<div class="content">
+
+ <p>
+ Le présent article présuppose que vous soyez familier avec
+ le concept de tests unitaires ainsi que celui de développement
+ web avec le langage PHP. Il s'agit d'un guide pour le nouvel
+ et impatient utilisateur de
+ <a href="https://sourceforge.net/project/showfiles.php?group_id=76550">SimpleTest</a>.
+ Pour une documentation plus complète, particulièrement si
+ vous découvrez les tests unitaires, consultez la
+ <a href="http://www.lastcraft.com/unit_test_documentation.php">documentation
+ en cours</a>, et pour des exemples de scénarios de test,
+ consultez le
+ <a href="http://www.lastcraft.com/first_test_tutorial.php">tutorial
+ sur les tests unitaires</a>.
+ </p>
+
+ <p><a class="target" name="unit"><h2>Utiliser le testeur rapidement</h2></a></p>
+ <p>
+ Parmi les outils de test pour logiciel, le testeur unitaire
+ est le plus proche du développeur. Dans un contexte de
+ développement agile, le code de test se place juste à côté
+ du code source étant donné que tous les deux sont écrits
+ simultanément. Dans ce contexte, SimpleTest aspire à être
+ une solution complète de test pour un développeur PHP et
+ s'appelle "Simple" parce qu'elle devrait être simple à
+ utiliser et à étendre. Ce nom n'était pas vraiment un bon
+ choix. Non seulement cette solution inclut toutes les
+ fonctions classiques qu'on est en droit d'attendre de la
+ part des portages de <a href="http://www.junit.org/">JUnit</a> et des <a href="http://sourceforge.net/projects/phpunit/">PHPUnit</a>,
+ mais elle inclut aussi les <a href="http://www.mockobjects.com/">objets fantaisie ou
+ "mock objects"</a>.
+ </p>
+ <p>
+ Ce qui rend cet outil immédiatement utile pour un développeur PHP,
+ c'est son navigateur web interne.
+ Il permet des tests qui parcourent des sites web, remplissent
+ des formulaires et testent le contenu des pages.
+ Etre capable d'écrire ces tests en PHP veut dire qu'il devient
+ facile d'écrire des tests de recette (ou d'intégration).
+ Un exemple serait de confirmer qu'un utilisateur a bien été ajouté
+ dans une base de données après s'être enregistré sur une site web.
+ </p>
+ <p>
+ La démonstration la plus rapide : l'exemple
+ </p>
+ <p>
+ Supposons que nous sommes en train de tester une simple
+ classe de log dans un fichier : elle s'appelle
+ <span class="new_code">Log</span> dans <em>classes/Log.php</em>. Commençons
+ par créer un script de test, appelé
+ <em>tests/log_test.php</em>. Son contenu est le suivant...
+<pre>
+&lt;?php
+<strong>require_once('simpletest/autorun.php');</strong>
+require_once('../classes/log.php');
+
+class TestOfLogging extends <strong>UnitTestCase</strong> {
+}
+?&gt;
+</pre>
+ Ici le répertoire <em>simpletest</em> est soit dans le
+ dossier courant, soit dans les dossiers pour fichiers
+ inclus. Vous auriez à éditer ces arborescences suivant
+ l'endroit où vous avez installé SimpleTest.
+ Le fichier "autorun.php" fait plus que juste inclure
+ les éléments de SimpleTest : il lance aussi les tests pour nous.
+ </p>
+ <p>
+ <span class="new_code">TestOfLogging</span> est notre premier scénario de test
+ et il est pour l'instant vide.
+ Chaque scénario de test est une classe qui étend une des classes
+ de base de SimpleTest. Nous pouvons avoir autant de classes de ce type
+ que nous voulons.
+ </p>
+ <p>
+ Avec ces trois lignes d'échafaudage
+ l'inclusion de notre classe <span class="new_code">Log</span>, nous avons une suite
+ de tests. Mais pas encore de test !
+ </p>
+ <p>
+ Pour notre premier test, supposons que la classe <span class="new_code">Log</span>
+ prenne le nom du fichier à écrire au sein du constructeur,
+ et que nous avons un répertoire temporaire dans lequel placer
+ ce fichier.
+<pre>
+&lt;?php
+require_once('simpletest/autorun.php');
+require_once('../classes/log.php');
+
+class TestOfLogging extends UnitTestCase {
+ function <strong>testLogCreatesNewFileOnFirstMessage()</strong> {
+ @unlink('/temp/test.log');
+ $log = new Log('/temp/test.log');
+ <strong>$this-&gt;assertFalse(file_exists('/temp/test.log'));</strong>
+ $log-&gt;message('Should write this to a file');
+ <strong>$this-&gt;assertTrue(file_exists('/temp/test.log'));</strong>
+ }
+}
+?&gt;
+</pre>
+ Au lancement du scénario de test, toutes les méthodes qui
+ commencent avec la chaîne <span class="new_code">test</span> sont
+ identifiées puis exécutées.
+ Si la méthode commence par <span class="new_code">test</span>, c'est un test.
+ Remarquez bien le nom très long de notre exemple :
+ <span class="new_code">testLogCreatesNewFileOnFirstMessage()</span>.
+ C'est bel et bien délibéré : ce style est considéré désirable
+ et il rend la sortie du test plus lisible.
+ </p>
+ <p>
+ D'ordinaire nous avons bien plusieurs méthodes de tests.
+ Mais ce sera pour plus tard.
+ </p>
+ <p>
+ Les assertions dans les
+ méthodes de test envoient des messages vers le framework de
+ test qui affiche immédiatement le résultat. Cette réponse
+ immédiate est importante, non seulement lors d'un crash
+ causé par le code, mais aussi de manière à rapprocher
+ l'affichage de l'erreur au plus près du scénario de test
+ concerné via un appel à <span class="new_code">print</span>code&gt;.
+ </p>
+ <p>
+ Pour voir ces résultats lançons effectivement les tests.
+ Aucun autre code n'est nécessaire, il suffit d'ouvrir
+ la page dans un navigateur.
+ </p>
+ <p>
+ En cas échec, l'affichage ressemble à...
+ <div class="demo">
+ <h1>TestOfLogging</h1>
+ <span class="fail">Fail</span>: testcreatingnewfile-&gt;True assertion failed.<br>
+ <div style="padding: 8px; margin-top: 1em; background-color: red; color: white;">1/1 test cases complete.
+ <strong>1</strong> passes and <strong>1</strong> fails.</div>
+ </div>
+ ...et si ça passe, on obtient...
+ <div class="demo">
+ <h1>TestOfLogging</h1>
+ <div style="padding: 8px; margin-top: 1em; background-color: green; color: white;">1/1 test cases complete.
+ <strong>2</strong> passes and <strong>0</strong> fails.</div>
+ </div>
+ Et si vous obtenez ça...
+ <div class="demo">
+ <b>Fatal error</b>: Failed opening required '../classes/log.php' (include_path='') in <b>/home/marcus/projects/lastcraft/tutorial_tests/Log/tests/log_test.php</b> on line <b>7</b>
+ </div>
+ c'est qu'il vous manque le fichier <em>classes/Log.php</em>
+ qui pourrait ressembler à :
+<pre>
+&lt;?php<strong>
+class Log {
+ function Log($file_path) {
+ }
+
+ function message() {
+ }
+}</strong>
+?&gt;
+</pre>
+ C'est largement plus sympathique d'écrire le code après le test.
+ Plus que sympatique même - cette technique s'appelle
+ "Développement Piloté par les Tests" ou
+ "Test Driven Development" en anglais.
+ </p>
+ <p>
+ Pour plus de renseignements sur le testeur, voyez la
+ <a href="unit_test_documentation.html">documentation pour les tests de régression</a>.
+ </p>
+
+ <p><a class="target" name="group"><h2>Construire des groupes de tests</h2></a></p>
+ <p>
+ Il est peu probable que dans une véritable application on
+ ait uniquement besoin de passer un seul scénario de test.
+ Cela veut dire que nous avons besoin de grouper les
+ scénarios dans un script de test qui peut, si nécessaire,
+ lancer tous les tests de l'application.
+ </p>
+ <p>
+ Notre première étape est de créer un nouveau fichier appelé
+ <em>tests/all_tests.php</em> et d'y inclure le code suivant...
+<pre>
+&lt;?php
+<strong>require_once('simpletest/autorun.php');</strong>
+
+class AllTests extends <strong>TestSuite</strong> {
+ function AllTests() {
+ $this-&gt;TestSuite(<strong>'All tests'</strong>);
+ <strong>$this-&gt;addFile('log_test.php');</strong>
+ }
+}
+?&gt;
+</pre>
+ L'inclusion de "autorun" permettra à notre future suite
+ de tests d'être lancée juste en invoquant ce script.
+ </p>
+ <p>
+ La sous-classe <span class="new_code">TestSuite</span> doit chaîner
+ son constructeur. Cette limitation sera supprimée dans
+ les versions à venir.
+ </p>
+ <p>
+ The method <span class="new_code">TestSuite::addFile()</span>
+ will include the test case file and read any new classes
+ that are descended from <span class="new_code">SimpleTestCase</span>.
+
+ Cette méthode <span class="new_code">TestSuite::addTestFile()</span> va
+ inclure le fichier de scénarios de test et lire parmi
+ toutes les nouvelles classes créées celles qui sont issues
+ de <span class="new_code">SimpleTestCase</span>.
+ <span class="new_code">UnitTestCase</span> est juste un exemple de classe dérivée
+ depuis <span class="new_code">SimpleTestCase</span> et vous pouvez créer les vôtres.
+ <span class="new_code">TestSuite::addFile()</span> peut aussi inclure d'autres suites.
+ </p>
+ <p>
+ La classe ne sera pas encore instanciée.
+ Quand la suite de tests est lancée, elle construira chaque instance
+ une fois le test atteint, et le détuira juste ensuite.
+ Cela veut dire que le constructeur n'est lancé qu'une fois avant
+ chaque initialisation de ce scénario de test et que le destructeur
+ est lui aussi lancé avant que le test suivant ne commence.
+ </p>
+ <p>
+ Il est commun de grouper des scénarios de test dans des super-classes
+ qui ne sont pas sensées être lancées, mais qui deviennent une classe de base
+ pour d'autres tests.
+ Pour que "autorun" fonctionne proprement les fichiers
+ des scénarios de test ne devraient pas lancer aveuglement
+ d'autres extensions de scénarios de test qui ne lanceraient pas
+ effectivement des tests.
+ Cela pourrait aboutir à un mauvais comptages des scénarios de test
+ pendant la procédure.
+ Pas vraiement un problème majeure, mais pour éviter cet inconvénient
+ il suffit de marquer vos classes de base comme <span class="new_code">abstract</span>.
+ SimpleTest ne lance pas les classes abstraites. Et si vous utilisez encore
+ PHP4 alors une directive <span class="new_code">SimpleTestOptions::ignore()</span>
+ dans votre fichier de scénario de test aura le même effet.
+ </p>
+ <p>
+ Par ailleurs, le fichier avec le scénario de test ne devrait pas
+ avoir été inclus ailleurs. Sinon aucun scénario de test
+ ne sera inclus à ce groupe.
+ Ceci pourrait se transformer en un problème plus grave :
+ si des fichiers ont déjà été inclus par PHP alors la méthode
+ <span class="new_code">TestSuite::addFile()</span> ne les détectera pas.
+ </p>
+ <p>
+ Pour afficher les résultats, il est seulement nécessaire
+ d'invoquer <em>tests/all_tests.php</em> à partir du serveur
+ web.
+ </p>
+ <p>
+ Pour plus de renseignements des groupes de tests, voyez le
+ <a href="group_test_documentation.html">documentation sur le groupement des tests</a>.
+ </p>
+
+ <p><a class="target" name="mock"><h2>Utiliser les objets fantaisie</h2></a></p>
+ <p>
+ Avançons un peu plus dans le futur.
+ </p>
+ <p>
+ Supposons que notre class logging soit testée et terminée.
+ Supposons aussi que nous testons une autre classe qui ait
+ besoin d'écrire des messages de log, disons
+ <span class="new_code">SessionPool</span>. Nous voulons tester une méthode
+ qui ressemblera probablement à quelque chose comme...
+<pre><strong>
+class SessionPool {
+ ...
+ function logIn($username) {
+ ...
+ $this-&gt;_log-&gt;message('User $username logged in.');
+ ...
+ }
+ ...
+}
+</strong>
+</pre>
+ Avec le concept de "réutilisation de code" comme fil
+ conducteur, nous utilisons notre class <span class="new_code">Log</span>. Un
+ scénario de test classique ressemblera peut-être à...
+<pre>
+&lt;?php
+require_once('simpletest/autorun.php');
+require_once('../classes/log.php');
+<strong>require_once('../classes/session_pool.php');</strong>
+
+class <strong>TestOfSessionLogging</strong> extends UnitTestCase {
+
+ function setUp() {
+ <strong>@unlink('/temp/test.log');</strong>
+ }
+
+ function tearDown() {
+ <strong>@unlink('/temp/test.log');</strong>
+ }
+
+ function testLoggingInIsLogged() {
+ <strong>$log = new Log('/temp/test.log');
+ $session_pool = &amp;new SessionPool($log);
+ $session_pool-&gt;logIn('fred');</strong>
+ $messages = file('/temp/test.log');
+ $this-&gt;assertEqual($messages[0], "User fred logged in.<strong>\n</strong>");
+ }
+}
+?&gt;
+</pre>
+ Nous expliquerons les méthodes <span class="new_code">setUp()</span>
+ et <span class="new_code">tearDown()</span> plus tard.
+ </p>
+ <p>
+ Le design de ce scénario de test n'est pas complètement
+ mauvais, mais on peut l'améliorer. Nous passons du temps à
+ tripoter les fichiers de log qui ne font pas partie de
+ notre test.
+ Pire, nous avons créé des liens de proximité
+ entre la classe <span class="new_code">Log</span> et ce test. Que se
+ passerait-il si nous n'utilisions plus de fichiers, mais la
+ bibliothèque <em>syslog</em> à la place ?
+
+ Cela veut dire que notre test <span class="new_code">TestOfSessionLogging</span>
+ enverra un échec alors même qu'il ne teste pas Logging.
+ </p>
+ <p>
+ Il est aussi fragile sur des petites retouches. Avez-vous
+ remarqué le retour chariot supplémentaire à la fin du
+ message ? A-t-il été ajouté par le loggueur ? Et si il
+ ajoutait aussi un timestamp ou d'autres données ?
+ </p>
+ <p>
+ L'unique partie à tester réellement est l'envoi d'un
+ message précis au loggueur.
+ Nous pouvons réduire le couplage en
+ créant une fausse classe de logging : elle ne fait
+ qu'enregistrer le message pour le test, mais ne produit
+ aucun résultat. Sauf qu'elle doit ressembler exactement à
+ l'original.
+ </p>
+ <p>
+ Si l'objet fantaisie n'écrit pas dans un fichier alors nous
+ nous épargnons la suppression du fichier avant et après le
+ test. Nous pourrions même nous épargner quelques lignes de
+ code supplémentaires si l'objet fantaisie pouvait exécuter
+ l'assertion.
+ <p>
+ </p>
+ Trop beau pour être vrai ? Pas vraiement on peut créer un tel
+ objet très facilement...
+<pre>
+&lt;?php
+require_once('simpletest/autorun.php');
+require_once('../classes/log.php');
+require_once('../classes/session_pool.php');
+
+<strong>Mock::generate('Log');</strong>
+
+class TestOfSessionLogging extends UnitTestCase {
+
+ function testLoggingInIsLogged() {<strong>
+ $log = &amp;new MockLog();
+ $log-&gt;expectOnce('message', array('User fred logged in.'));</strong>
+ $session_pool = &amp;new SessionPool(<strong>$log</strong>);
+ $session_pool-&gt;logIn('fred');
+ }
+}
+?&gt;
+</pre>
+ L'appel <span class="new_code">Mock::generate()</span> a généré
+ une nouvelle classe appelé <span class="new_code">MockLog</span>.
+ Cela ressemble à un clone identique, sauf que nous pouvons
+ y adjoindre du code de test.
+ C'est ce que fait <span class="new_code">expectOnce()</span>.
+ Cela dit que si <span class="new_code">message()</span> m'est appelé,
+ il a intérêt à l'être avec le paramètre
+ "User fred logged in.".
+ </p>
+ <p>
+ L'appel <span class="new_code">tally()</span> est nécessaire pour annoncer à
+ l'objet fantaisie qu'il n'y aura plus d'appels ultérieurs.
+ Sans ça l'objet fantaisie pourrait attendre pendant une
+ éternité l'appel de la méthode sans jamais prévenir le
+ scénario de test. Les autres tests sont déclenchés
+ automatiquement quand l'appel à <span class="new_code">message()</span> est
+ invoqué sur l'objet <span class="new_code">MockLog</span> par le code
+ <span class="new_code">SessionPool::logIn()</span>.
+ L'appel <span class="new_code">mock</span> va déclencher une comparaison des
+ paramètres et ensuite envoyer le message "pass" ou "fail"
+ au test pour l'affichage. Des jokers peuvent être inclus
+ pour ne pas avoir à tester tous les paramètres d'un appel
+ alors que vous ne souhaitez qu'en tester un.
+ </p>
+ <p>
+ Les objets fantaisie dans la suite SimpleTest peuvent avoir
+ un ensemble de valeurs de sortie arbitraires, des séquences
+ de sorties, des valeurs de sortie sélectionnées à partir
+ des arguments d'entrée, des séquences de paramètres
+ attendus et des limites sur le nombre de fois qu'une
+ méthode peut être invoquée.
+ </p>
+ <p>
+ Pour que ce test fonctionne la librairie avec les objets
+ fantaisie doit être incluse dans la suite de tests, par
+ exemple dans <em>all_tests.php</em>.
+ </p>
+ <p>
+ Pour plus de renseignements sur les objets fantaisie, voyez le
+ <a href="mock_objects_documentation.html">documentation sur les objets fantaisie</a>.
+ </p>
+
+ <p><a class="target" name="web"><h2>Tester une page web</h2></a></p>
+ <p>
+ Une des exigences des sites web, c'est qu'ils produisent
+ des pages web. Si vous construisez un projet de A à Z et
+ que vous voulez intégrer des tests au fur et à mesure alors
+ vous voulez un outil qui puisse effectuer une navigation
+ automatique et en examiner le résultat. C'est le boulot
+ d'un testeur web.
+ </p>
+ <p>
+ Effectuer un test web via SimpleTest reste assez primitif :
+ il n'y a pas de javascript par exemple.
+ La plupart des autres opérations d'un navigateur sont simulées.
+ </p>
+ <p>
+ Pour vous donner une idée, voici un exemple assez trivial :
+ aller chercher une page web,
+ à partir de là naviguer vers la page "about"
+ et finalement tester un contenu déterminé par le client.
+<pre>
+&lt;?php
+require_once('simpletest/autorun.php');
+<strong>require_once('simpletest/web_tester.php');</strong>
+
+class TestOfAbout extends <strong>WebTestCase</strong> {
+ function testOurAboutPageGivesFreeReignToOurEgo() {
+ <strong>$this-&gt;get('http://test-server/index.php');
+ $this-&gt;click('About');
+ $this-&gt;assertTitle('About why we are so great');
+ $this-&gt;assertText('We are really great');</strong>
+ }
+}
+?&gt;
+</pre>
+ Avec ce code comme test de recette, vous pouvez vous
+ assurer que le contenu corresponde toujours aux
+ spécifications à la fois des développeurs et des autres
+ parties prenantes au projet.
+ </p>
+ <p>
+ Vous pouvez aussi naviguer à travers des formulaires...
+<pre>
+&lt;?php
+require_once('simpletest/autorun.php');
+require_once('simpletest/web_tester.php');
+
+class TestOfRankings extends WebTestCase {
+ function testWeAreTopOfGoogle() {
+ $this-&gt;get('http://google.com/');
+ $this-&gt;setField('q', 'simpletest');
+ $this-&gt;click("I'm Feeling Lucky");
+ $this-&gt;assertTitle('SimpleTest - Unit Testing for PHP');
+ }
+}
+?&gt;
+</pre>
+ ...même si cela pourrait constituer une violation
+ des documents juridiques de Google(tm).
+ </p>
+ <p>
+ Pour plus de renseignements sur comment tester une page web, voyez la
+ <a href="web_tester_documentation.html">documentation sur tester des scripts web</a>.
+ </p>
+ <p>
+ <a href="http://sourceforge.net/projects/simpletest/"><img src="http://sourceforge.net/sflogo.php?group_id=76550&amp;type=5" width="210" height="62" border="0" alt="SourceForge.net Logo"></a>
+ </p>
+
+ </div>
+ References and related information...
+ <ul>
+<li>
+ <a href="https://sourceforge.net/project/showfiles.php?group_id=76550&amp;release_id=153280">Télécharger PHP Simple Test</a>
+ depuis <a href="http://sourceforge.net/projects/simpletest/">SourceForge</a>.
+ </li>
+<li>
+ L'<a href="http://simpletest.org/api/">API de SimpleTest pour développeur</a>
+ donne tous les détails sur les classes et assertions existantes.
+ </li>
+</ul>
+<div class="menu_back"><div class="menu">
+<a href="index.html">SimpleTest</a>
+ |
+ <a href="overview.html">Overview</a>
+ |
+ <a href="unit_test_documentation.html">Unit tester</a>
+ |
+ <a href="group_test_documentation.html">Group tests</a>
+ |
+ <a href="mock_objects_documentation.html">Mock objects</a>
+ |
+ <a href="partial_mocks_documentation.html">Partial mocks</a>
+ |
+ <a href="reporter_documentation.html">Reporting</a>
+ |
+ <a href="expectation_documentation.html">Expectations</a>
+ |
+ <a href="web_tester_documentation.html">Web tester</a>
+ |
+ <a href="form_testing_documentation.html">Testing forms</a>
+ |
+ <a href="authentication_documentation.html">Authentication</a>
+ |
+ <a href="browser_documentation.html">Scriptable browser</a>
+</div></div>
+<div class="copyright">
+ Copyright<br>Marcus Baker 2006
+ </div>
+</body>
+</html>
diff --git a/site/vendors/simpletest/docs/fr/mock_objects_documentation.html b/site/vendors/simpletest/docs/fr/mock_objects_documentation.html
new file mode 100644
index 0000000..c03ac61
--- /dev/null
+++ b/site/vendors/simpletest/docs/fr/mock_objects_documentation.html
@@ -0,0 +1,778 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Documentation SimpleTest : les objets fantaise</title>
+<link rel="stylesheet" type="text/css" href="docs.css" title="Styles">
+</head>
+<body>
+<div class="menu_back"><div class="menu">
+<a href="index.html">SimpleTest</a>
+ |
+ <a href="overview.html">Overview</a>
+ |
+ <a href="unit_test_documentation.html">Unit tester</a>
+ |
+ <a href="group_test_documentation.html">Group tests</a>
+ |
+ <a href="mock_objects_documentation.html">Mock objects</a>
+ |
+ <a href="partial_mocks_documentation.html">Partial mocks</a>
+ |
+ <a href="reporter_documentation.html">Reporting</a>
+ |
+ <a href="expectation_documentation.html">Expectations</a>
+ |
+ <a href="web_tester_documentation.html">Web tester</a>
+ |
+ <a href="form_testing_documentation.html">Testing forms</a>
+ |
+ <a href="authentication_documentation.html">Authentication</a>
+ |
+ <a href="browser_documentation.html">Scriptable browser</a>
+</div></div>
+<h1>Documentation sur les objets fantaisie</h1>
+ This page...
+ <ul>
+<li>
+ <a href="#quoi">Que sont les objets fantaisie ?</a>
+ </li>
+<li>
+ <a href="#creation">Créer des objets fantaisie</a>.
+ </li>
+<li>
+ <a href="#bouchon">L'objet fantaisie - acteur</a> ou bouchon.
+ </li>
+<li>
+ <a href="#attentes">L'objet fantaisie - critique</a> avec des attentes.
+ </li>
+<li>
+ <a href="#approches">D'autres approches</a>
+ y compris des librairies d'objets fantaisie.
+ </li>
+<li>
+ Utiliser les objets fantaisie avec
+ <a href="#autres_testeurs">d'autres testeurs unitaires</a>.
+ </li>
+</ul>
+<div class="content">
+ <p><a class="target" name="quoi"><h2>Que sont les objets fantaisie ?</h2></a></p>
+ <p>
+ Les objets fantaisie - ou "mock objects" en anglais -
+ ont deux rôles pendant un scénario de test : acteur et critique.
+ </p>
+ <p>
+ Le comportement d'acteur est celui de simuler
+ des objets difficiles à initialiser ou trop consommateurs
+ en temps pendant un test.
+ Le cas classique est celui de la connexion à une base de données.
+ Mettre sur pied une base de données de test au lancement
+ de chaque test ralentirait considérablement les tests
+ et en plus exigerait l'installation d'un moteur
+ de base de données ainsi que des données sur la machine de test.
+ Si nous pouvons simuler la connexion
+ et renvoyer des données à notre guise
+ alors non seulement nous gagnons en pragmatisme
+ sur les tests mais en sus nous pouvons nourrir
+ notre base avec des données falsifiées
+ et voir comment il répond. Nous pouvons
+ simuler une base de données en suspens ou
+ d'autres cas extrêmes sans avoir à créer
+ une véritable panne de base de données.
+ En d'autres termes nous pouvons gagner
+ en contrôle sur l'environnement de test.
+ </p>
+ <p>
+ Si les objets fantaisie ne se comportaient que comme
+ des acteurs alors on les connaîtrait sous le nom de
+ <a href="server_stubs_documentation.html">bouchons serveur</a>.
+ </p>
+ <p>
+ Cependant non seulement les objets fantaisie jouent
+ un rôle (en fournissant à la demande les valeurs requises)
+ mais en plus ils sont aussi sensibles aux messages qui
+ leur sont envoyés (par le biais d'attentes).
+ En posant les paramètres attendus d'une méthode
+ ils agissent comme des gardiens :
+ un appel sur eux doit être réalisé correctement.
+ Si les attentes ne sont pas atteintes ils nous épargnent
+ l'effort de l'écriture d'une assertion de test avec
+ échec en réalisant cette tâche à notre place.
+ Dans le cas d'une connexion à une base de données
+ imaginaire ils peuvent tester si la requête, disons SQL,
+ a bien été formé par l'objet qui utilise cette connexion.
+ Mettez-les sur pied avec des attentes assez précises
+ et vous verrez que vous n'aurez presque plus d'assertion à écrire manuellement.
+ </p>
+
+ <p><a class="target" name="creation"><h2>Créer des objets fantaisie</h2></a></p>
+ <p>
+ Comme pour la création des bouchons serveur, tout ce dont
+ nous avons besoin c'est d'un classe existante.
+ La fameuse connexion à une base de données qui ressemblerait à...
+<pre>
+<strong>class DatabaseConnection {
+ function DatabaseConnection() {
+ }
+
+ function query() {
+ }
+
+ function selectQuery() {
+ }
+}</strong>
+</pre>
+ Cette classe n'a pas encore besoin d'être implémentée.
+ Pour en créer sa version fantaisie nous devons juste
+ inclure la librairie d'objet fantaisie puis lancer le générateur...
+<pre>
+<strong>require_once('simpletest/unit_tester.php');
+require_once('simpletest/mock_objects.php');
+require_once('database_connection.php');
+
+Mock::generate('DatabaseConnection');</strong>
+</pre>
+ Ceci génère une classe clone appelée <span class="new_code">MockDatabaseConnection</span>.
+ Nous pouvons désormais créer des instances de
+ cette nouvelle classe à l'intérieur même de notre scénario de test...
+<pre>
+require_once('simpletest/unit_tester.php');
+require_once('simpletest/mock_objects.php');
+require_once('database_connection.php');
+
+Mock::generate('DatabaseConnection');
+<strong>
+class MyTestCase extends UnitTestCase {
+
+ function testSomething() {
+ $connection = &amp;new MockDatabaseConnection($this);
+ }
+}</strong>
+</pre>
+ Contrairement aux bouchons, le constructeur
+ d'une classe fantaisie a besoin d'une référence au scénario
+ de test pour pouvoir transmettre les succès
+ et les échecs pendant qu'il vérifie les attentes.
+ Concrètement ça veut dire que les objets fantaisie
+ ne peuvent être utilisés qu'au sein d'un scénario de test.
+ Malgré tout, cette puissance supplémentaire implique
+ que les bouchons ne sont que rarement utilisés
+ si des objets fantaisie sont disponibles.
+ </p>
+
+ <p><a class="target" name="bouchon"><h2>Objets fantaisie en action</h2></a></p>
+ <p>
+ La version fantaisie d'une classe contient
+ toutes les méthodes de l'originale.
+ De la sorte une opération comme
+ <span class="new_code">$connection-&gt;query()</span>
+ est encore possible.
+ Tout comme avec les bouchons, nous pouvons remplacer
+ la valeur nulle renvoyée par défaut...
+<pre>
+<strong>$connection-&gt;setReturnValue('query', 37);</strong>
+</pre>
+ Désormais à chaque appel de
+ <span class="new_code">$connection-&gt;query()</span>
+ nous recevons comme résultat 37.
+ Tout comme avec les bouchons nous pouvons utiliser
+ des jokers et surcharger le paramètre joker.
+ Nous pouvons aussi ajouter des méthodes supplémentaires
+ à l'objet fantaisie lors de sa génération
+ et lui choisir un nom de classe qui lui soit propre...
+<pre>
+<strong>Mock::generate('DatabaseConnection', 'MyMockDatabaseConnection', array('setOptions'));</strong>
+</pre>
+ Ici l'objet fantaisie se comportera comme
+ si <span class="new_code">setOptions()</span> existait dans la classe originale.
+ C'est pratique si une classe a utilisé le mécanisme
+ <span class="new_code">overload()</span> de PHP pour ajouter des méthodes dynamiques.
+ Vous pouvez créer des fantaisies spéciales pour simuler cette situation.
+ </p>
+ <p>
+ Tous les modèles disponibles avec les bouchons serveur
+ le sont également avec les objets fantaisie...
+<pre>
+class Iterator {
+ function Iterator() {
+ }
+
+ function next() {
+ }
+}
+</pre>
+ Une nouvelle fois, supposons que cet itérateur
+ ne retourne que du texte jusqu'au moment où il atteint
+ son terme, quand il renvoie <span class="new_code">false</span>.
+ Nous pouvons le simuler avec...
+<pre>
+Mock::generate('Iterator');
+
+class IteratorTest extends UnitTestCase() {
+
+ function testASequence() {<strong>
+ $iterator = &amp;new MockIterator($this);
+ $iterator-&gt;setReturnValue('next', false);
+ $iterator-&gt;setReturnValueAt(0, 'next', 'First string');
+ $iterator-&gt;setReturnValueAt(1, 'next', 'Second string');</strong>
+ ...
+ }
+}
+</pre>
+ Au moment du premier appel à <span class="new_code">next()</span>
+ sur l'itérateur fantaisie il renverra tout d'abord
+ "First string", puis ce sera au tour de
+ "Second string" au deuxième appel
+ et ensuite pour tout appel suivant <span class="new_code">false</span>
+ sera renvoyé.
+ Ces valeurs renvoyées successivement sont prioritaires
+ sur la valeur constante retournée.
+ Cette dernière est un genre de valeur par défaut si vous voulez.
+ </p>
+ <p>
+ Reprenons aussi le conteneur d'information bouchonné
+ avec des pairs clef / valeur...
+<pre>
+class Configuration {
+ function Configuration() {
+ }
+
+ function getValue($key) {
+ }
+}
+</pre>
+ Il s'agit là d'une situation classique
+ d'utilisation d'objets fantaisie étant donné
+ que la configuration peut varier grandement de machine à machine :
+ ça contraint fortement la fiabilité de nos tests
+ si nous l'utilisons directement.
+ Le problème est que toutes les données nous parviennent
+ à travers la méthode <span class="new_code">getValue()</span>
+ et que nous voulons des résultats différents pour des clefs différentes.
+ Heureusement les objets fantaisie ont un système de filtrage...
+<pre>
+<strong>$config = &amp;new MockConfiguration($this);
+$config-&gt;setReturnValue('getValue', 'primary', array('db_host'));
+$config-&gt;setReturnValue('getValue', 'admin', array('db_user'));
+$config-&gt;setReturnValue('getValue', 'secret', array('db_password'));</strong>
+</pre>
+ Le paramètre en plus est une liste d'arguments
+ à faire correspondre. Dans ce cas nous essayons
+ de faire correspondre un unique argument :
+ en l'occurrence la clef recherchée.
+ Maintenant que la méthode <span class="new_code">getValue()</span>
+ est invoquée sur l'objet fantaisie...
+<pre>
+$config-&gt;getValue('db_user')
+</pre>
+ ...elle renverra "admin".
+ Elle le trouve en essayant de faire correspondre
+ les arguments entrants dans sa liste
+ d'arguments sortants les uns après les autres
+ jusqu'au moment où une correspondance exacte est atteinte.
+ </p>
+ <p>
+ Il y a des fois où vous souhaitez
+ qu'un objet spécifique soit servi par la fantaisie
+ plutôt qu'une copie.
+ De nouveau c'est identique au mécanisme des bouchons serveur...
+<pre>
+class Thing {
+}
+
+class Vector {
+ function Vector() {
+ }
+
+ function get($index) {
+ }
+}
+</pre>
+ Dans ce cas vous pouvez placer une référence
+ dans la liste renvoyée par l'objet fantaisie...
+<pre>
+$thing = new Thing();<strong>
+$vector = &amp;new MockVector($this);
+$vector-&gt;setReturnReference('get', $thing, array(12));</strong>
+</pre>
+ Avec cet arrangement vous savez qu'à chaque appel
+ de <span class="new_code">$vector-&gt;get(12)</span>
+ le même <span class="new_code">$thing</span> sera renvoyé.
+ </p>
+
+ <p><a class="target" name="attentes"><h2>Objets fantaisie en critique</h2></a></p>
+ <p>
+ Même si les bouchons serveur vous isolent
+ du désordre du monde réel, il ne s'agit là que
+ de la moitié du bénéfice potentiel.
+ Vous pouvez avoir une classe de test recevant
+ les messages ad hoc, mais est-ce que votre nouvelle classe
+ renvoie bien les bons ?
+ Le tester peut devenir cafouillis sans une librairie d'objets fantaisie.
+ </p>
+ <p>
+ Pour l'exemple, prenons une classe <span class="new_code">SessionPool</span>
+ à laquelle nous allons ajouter une fonction de log.
+ Plutôt que de complexifier la classe originale,
+ nous souhaitons ajouter ce comportement avec un décorateur (GOF).
+ Pour l'instant le code de <span class="new_code">SessionPool</span> ressemble à...
+<pre>
+<strong>class SessionPool {
+ function SessionPool() {
+ ...
+ }
+
+ function &amp;findSession($cookie) {
+ ...
+ }
+ ...
+}
+
+class Session {
+ ...
+}</strong>
+
+</pre>
+ Alors que pour notre code de log, nous avons...
+<pre><strong>
+class Log {
+ function Log() {
+ ...
+ }
+
+ function message() {
+ ...
+ }
+}
+
+class LoggingSessionPool {
+ function LoggingSessionPool(&amp;$session_pool, &amp;$log) {
+ ...
+ }
+
+ function &amp;findSession($cookie) {
+ ...
+ }
+ ...
+}</strong>
+</pre>
+ Dans tout ceci, la seule classe à tester est
+ <span class="new_code">LoggingSessionPool</span>. En particulier,
+ nous voulons vérifier que la méthode <span class="new_code">findSession()</span>
+ est appelée avec le bon identifiant de session au sein du cookie
+ et qu'elle renvoie bien le message "Starting session $cookie"
+ au loggueur.
+ </p>
+ <p>
+ Bien que nous ne testions que quelques lignes
+ de code de production, voici la liste des choses
+ à faire dans un scénario de test conventionnel :
+ <ol>
+ <li>Créer un objet de log.</li>
+ <li>Indiquer le répertoire d'écriture du fichier de log.</li>
+ <li>Modifier les droits sur le répertoire pour pouvoir y écrire le fichier.</li>
+ <li>Créer un objet <span class="new_code">SessionPool</span>.</li>
+ <li>Lancer une session, ce qui demande probablement pas mal de choses.</li>
+ <li>Invoquer <span class="new_code">findSession()</span>.</li>
+ <li>Lire le nouvel identifiant de session (en espérant qu'il existe un accesseur !).</li>
+ <li>Lever une assertion de test pour vérifier que cet identifiant correspond bien au cookie.</li>
+ <li>Lire la dernière ligne du fichier de log.</li>
+ <li>Supprimer avec une (ou plusieurs) expression rationnelle les timestamps de log en trop, etc.</li>
+ <li>Vérifier que le message de session est bien dans le texte.</li>
+ </ol>
+ Pas étonnant que les développeurs détestent
+ écrire des tests quand ils sont aussi ingrats.
+ Pour rendre les choses encore pire, à chaque fois que
+ le format de log change ou bien que la méthode de création
+ des sessions change, nous devons réécrire une partie
+ des tests alors même qu'ils ne testent pas ces parties
+ du système. Nous sommes en train de préparer
+ le cauchemar pour les développeurs de ces autres classes.
+ </p>
+ <p>
+ A la place, voici la méthode complète pour le test
+ avec un peu de magie via les objets fantaisie...
+<pre>
+Mock::generate('Session');
+Mock::generate('SessionPool');
+Mock::generate('Log');
+
+class LoggingSessionPoolTest extends UnitTestCase {
+ ...
+ function testFindSessionLogging() {<strong>
+ $session = &amp;new MockSession($this);
+ $pool = &amp;new MockSessionPool($this);
+ $pool-&gt;setReturnReference('findSession', $session);
+ $pool-&gt;expectOnce('findSession', array('abc'));
+
+ $log = &amp;new MockLog($this);
+ $log-&gt;expectOnce('message', array('Starting session abc'));
+
+ $logging_pool = &amp;new LoggingSessionPool($pool, $log);
+ $this-&gt;assertReference($logging_pool-&gt;findSession('abc'), $session);
+ $pool-&gt;tally();
+ $log-&gt;tally();</strong>
+ }
+}
+</pre>
+ Commençons par écrire une session simulacre.
+ Pas la peine d'être trop pointilleux avec
+ celle-ci puisque la vérification de la session
+ désirée est effectuée ailleurs. Nous avons
+ juste besoin de vérifier qu'il s'agit de
+ la même que celle qui vient du groupe commun des sessions.
+ </p>
+ <p>
+ <span class="new_code">findSession()</span> est un méthode fabrique
+ dont la simulation est décrite <a href="#stub">plus haut</a>.
+ Le point de départ vient avec le premier appel
+ <span class="new_code">expectOnce()</span>. Cette ligne indique
+ qu'à chaque fois que <span class="new_code">findSession()</span>
+ est invoqué sur l'objet fantaisie, il vérifiera
+ les arguments entrant. S'il ne reçoit
+ que la chaîne "abc" en tant qu'argument
+ alors un succès est envoyé au testeur unitaire,
+ sinon c'est un échec qui est généré.
+ Il s'agit là de la partie qui teste si nous avons bien
+ la bonne session. La liste des arguments suit
+ une format identique à celui qui précise les valeurs renvoyées.
+ Vous pouvez avoir des jokers et des séquences
+ et l'ordre de l'évaluation restera le même.
+ </p>
+ <p>
+ Si l'appel n'est jamais effectué alors n'est généré
+ ni le succès, ni l'échec. Pour contourner cette limitation,
+ nous devons dire à l'objet fantaisie que le test est terminé :
+ il pourra alors décider si les attentes ont été répondues.
+ L'assertion du testeur unitaire de ceci est déclenchée
+ par l'appel <span class="new_code">tally()</span> à la fin du test.
+ </p>
+ <p>
+ Nous utilisons le même modèle pour mettre sur pied
+ le loggueur fantaisie. Nous lui indiquons que <span class="new_code">message()</span>
+ devrait être invoqué une fois et une fois seulement
+ avec l'argument "Starting session abc".
+ En testant les arguments d'appel, plutôt que ceux de sortie du loggueur,
+ nous isolons le test de tout modification dans le loggueur.
+ </p>
+ <p>
+ Nous commençons le lancement nos tests à la création
+ du nouveau <span class="new_code">LoggingSessionPool</span>
+ et nous l'alimentons avec nos objets fantaisie juste créés.
+ Désormais tout est sous contrôle. Au final nous confirmons
+ que le <span class="new_code">$session</span> donné au décorateur est bien
+ celui reçu et prions les objets fantaisie de lancer leurs
+ tests de comptage d'appel interne avec les appels <span class="new_code">tally()</span>.
+ </p>
+ <p>
+ Il y a encore pas mal de code de test, mais ce code est très strict.
+ S'il vous semble encore terrifiant il l'est bien moins
+ que si nous avions essayé sans les objets fantaisie
+ et ce test en particulier, interactions plutôt que résultat,
+ est toujours plus difficile à mettre en place.
+ Le plus souvent vous aurez besoin de tester des situations
+ plus complexes sans ce niveau ni cette précision.
+ En outre une partie peut être remaniée avec la méthode
+ de scénario de test <span class="new_code">setUp()</span>.
+ </p>
+ <p>
+ Voici la liste complète des attentes que vous pouvez
+ placer sur un objet fantaisie avec
+ <a href="http://www.lastcraft.com/simple_test.php">SimpleTest</a>...
+ <table>
+<thead>
+ <tr>
+<th>Attente</th>
+<th>Nécessite <span class="new_code">tally()</span>
+</th>
+</tr>
+ </thead>
+<tbody>
+<tr>
+ <td><span class="new_code">expectArguments($method, $args)</span></td>
+ <td style="text-align: center">Non</td>
+ </tr>
+ <tr>
+ <td><span class="new_code">expectArgumentsAt($timing, $method, $args)</span></td>
+ <td style="text-align: center">Non</td>
+ </tr>
+ <tr>
+ <td><span class="new_code">expectCallCount($method, $count)</span></td>
+ <td style="text-align: center">Oui</td>
+ </tr>
+ <tr>
+ <td><span class="new_code">expectMaximumCallCount($method, $count)</span></td>
+ <td style="text-align: center">Non</td>
+ </tr>
+ <tr>
+ <td><span class="new_code">expectMinimumCallCount($method, $count)</span></td>
+ <td style="text-align: center">Oui</td>
+ </tr>
+ <tr>
+ <td><span class="new_code">expectNever($method)</span></td>
+ <td style="text-align: center">Non</td>
+ </tr>
+ <tr>
+ <td><span class="new_code">expectOnce($method, $args)</span></td>
+ <td style="text-align: center">Oui</td>
+ </tr>
+ <tr>
+ <td><span class="new_code">expectAtLeastOnce($method, $args)</span></td>
+ <td style="text-align: center">Oui</td>
+ </tr>
+ </tbody>
+</table>
+ Où les paramètres sont...
+ <dl>
+ <dt class="new_code">$method</dt>
+ <dd>Le nom de la méthode, sous la forme d'une chaîne,
+ à laquelle la condition doit être appliquée.</dd>
+ <dt class="new_code">$args</dt>
+ <dd>
+ Les arguments sous la forme d'une liste.
+ Les jokers peuvent être inclus de la même manière
+ qu'avec <span class="new_code">setReturn()</span>.
+ Cet argument est optionnel pour <span class="new_code">expectOnce()</span>
+ et <span class="new_code">expectAtLeastOnce()</span>.
+ </dd>
+ <dt class="new_code">$timing</dt>
+ <dd>
+ Le seul point dans le temps pour tester
+ la condition. Le premier appel commence à zéro.
+ </dd>
+ <dt class="new_code">$count</dt>
+ <dd>Le nombre d'appels attendu.</dd>
+ </dl>
+ La méthode <span class="new_code">expectMaximumCallCount()</span>
+ est légèrement différente dans le sens où elle ne pourra
+ générer qu'un échec. Elle reste silencieuse
+ si la limite n'est jamais atteinte.
+ </p>
+ <p>
+ Par ailleurs si vous avez just un appel dans votre test,
+ vérifiez bien que vous utiliser
+ <span class="new_code">expectOnce</span>.<br>
+ Utiliser <span class="new_code">$mocked-&gt;expectAt(0, 'method', 'args);</span>
+ tout seul ne sera pas pris en compte :
+ la vérification des arguments et le comptage total
+ sont pour l'instant encore indépendant.
+ </p>
+ <p>
+ Comme avec les assertions dans les scénarios de test,
+ toutes ces attentes peuvent accepter une surcharge de
+ message sous la forme d'un paramètre supplémentaire.
+ Par ailleurs le message d'échec original peut être inclus
+ dans le résultat avec "%s".
+ </p>
+
+ <p><a class="target" name="approches"><h2>D'autres approches</h2></a></p>
+ <p>
+ Il existe trois approches pour créer des objets
+ fantaisie en comprenant celle utilisée par SimpleTest.
+ Les coder à la main en utilisant une classe de base,
+ les générer dans un fichier ou les générer dynamiquement à la volée.
+ </p>
+ <p>
+ Les objets fantaisie générés avec
+ <a href="simple_test.html">SimpleTest</a> sont dynamiques.
+ Ils sont créés à l'exécution dans la mémoire,
+ grâce à <span class="new_code">eval()</span>, plutôt qu'écrits dans un fichier.
+ Cette opération les rend facile à créer,
+ en une seule ligne, surtout par rapport à leur création
+ à la main dans une hiérarchie de classe parallèle.
+ Le problème avec ce comportement tient généralement
+ dans la mise en place des tests proprement dits.
+ Si les objets originaux changent les versions fantaisie
+ sur lesquels reposent les tests, une désynchronisation peut subvenir.
+ Cela peut aussi arriver avec l'approche en hiérarchie parallèle,
+ mais c'est détecté beaucoup plus vite.
+ </p>
+ <p>
+ Bien sûr, la solution est d'ajouter de véritables tests d'intégration.
+ Vous n'en avez pas besoin de beaucoup
+ et le côté pratique des objets fantaisie fait plus
+ que compenser la petite dose de test supplémentaire.
+ Vous ne pouvez pas avoir confiance dans du code qui
+ ne serait testé que par des objets fantaisie.
+ </p>
+ <p>
+ Si vous restez déterminé de construire des librairies
+ statiques d'objets fantaisie parce que vous souhaitez
+ émuler un comportement très spécifique,
+ vous pouvez y parvenir grâce au générateur de classe de SimpleTest.
+ Dans votre fichier librairie, par exemple
+ <em>mocks/connection.php</em> pour une connexion à une base de données,
+ créer un objet fantaisie et provoquer l'héritage
+ pour hériter pour surcharger des méthodes spéciales
+ ou ajouter des préréglages...
+<pre>
+&lt;?php
+ require_once('simpletest/mock_objects.php');
+ require_once('../classes/connection.php');
+<strong>
+ Mock::generate('Connection', 'BasicMockConnection');
+ class MockConnection extends BasicMockConnection {
+ function MockConnection(&amp;$test, $wildcard = '*') {
+ $this-&gt;BasicMockConnection($test, $wildcard);
+ $this-&gt;setReturn('query', false);
+ }
+ }</strong>
+?&gt;
+</pre>
+ L'appel <span class="new_code">generate</span> dit au générateur de classe
+ d'en créer une appelée <span class="new_code">BasicMockConnection</span>
+ plutôt que la plus courante <span class="new_code">MockConnection</span>.
+ Ensuite nous héritons à partir de celle-ci pour obtenir
+ notre version de <span class="new_code">MockConnection</span>.
+ En interceptant de cette manière nous pouvons ajouter
+ un comportement, ici transformer la valeur par défaut de
+ <span class="new_code">query()</span> en "false".
+ En utilisant le nom par défaut nous garantissons
+ que le générateur de classe fantaisie n'en recréera
+ pas une autre différente si il est invoqué ailleurs
+ dans les tests. Il ne créera jamais de classe
+ si elle existe déjà. Aussi longtemps que le fichier
+ ci-dessus est inclus avant alors tous les tests qui
+ généraient <span class="new_code">MockConnection</span> devraient
+ utiliser notre version à présent. Par contre si
+ nous avons une erreur dans l'ordre et que la librairie
+ de fantaisie en crée une d'abord alors la création
+ de la classe échouera tout simplement.
+ </p>
+ <p>
+ Utiliser cette astuce si vous vous trouvez avec beaucoup
+ de comportement en commun sur les objets fantaisie
+ ou si vous avez de fréquents problèmes d'intégration
+ plus tard dans les étapes de test.
+ </p>
+
+ <p><a class="target" name="autres_testeurs"><h2>Je pense que SimpleTest pue !</h2></a></p>
+ <p>
+ Mais au moment d'écrire ces lignes c'est le seul
+ à gérer les objets fantaisie, donc vous êtes bloqué avec lui ?
+ </p>
+ <p>
+ Non, pas du tout.
+ <a href="simple_test.html">SimpleTest</a> est une boîte à outils
+ et parmi ceux-ci on trouve les objets fantaisie
+ qui peuvent être utilisés indépendamment.
+ Supposons que vous avez votre propre testeur unitaire favori
+ et que tous vos tests actuels l'utilisent.
+ Prétendez que vous avez appelé votre tester unitaire PHPUnit
+ (c'est ce que tout le monde a fait) et que la classe principale
+ de test ressemble à...
+<pre>
+class PHPUnit {
+ function PHPUnit() {
+ }
+
+ function assertion($message, $assertion) {
+ }
+ ...
+}
+</pre>
+ La seule chose que la méthode <span class="new_code">assertion()</span> réalise,
+ c'est de préparer une sortie embellie alors le paramètre boolien
+ de l'assertion sert à déterminer s'il s'agit d'une erreur ou d'un succès.
+ Supposons qu'elle est utilisée de la manière suivante...
+<pre>
+$unit_test = new PHPUnit();
+$unit_test&gt;assertion('I hope this file exists', file_exists('my_file'));
+</pre>
+ Comment utiliser les objets fantaisie avec ceci ?
+ </p>
+ <p>
+ Il y a une méthode protégée sur la classe de base
+ des objets fantaisie : elle s'appelle <span class="new_code">_assertTrue()</span>.
+ En surchargeant cette méthode nous pouvons utiliser
+ notre propre format d'assertion.
+ Nous commençons avec une sous-classe, dans <em>my_mock.php</em>...
+<pre>
+<strong>&lt;?php
+ require_once('simpletest/mock_objects.php');
+
+ class MyMock extends SimpleMock() {
+ function MyMock(&amp;$test, $wildcard) {
+ $this-&gt;SimpleMock($test, $wildcard);
+ }
+
+ function _assertTrue($assertion, $message) {
+ $test = &amp;$this-&gt;getTest();
+ $test-&gt;assertion($message, $assertion);
+ }
+ }
+?&gt;</strong>
+</pre>
+ Maintenant une instance de <span class="new_code">MyMock</span>
+ créera un objet qui parle le même langage que votre testeur.
+ Bien sûr le truc c'est que nous créons jamais un tel objet :
+ le générateur s'en chargera. Nous avons juste besoin
+ d'une ligne de code supplémentaire pour dire au générateur
+ d'utiliser vos nouveaux objets fantaisie...
+<pre>
+&lt;?php
+ require_once('simpletst/mock_objects.php');
+
+ class MyMock extends SimpleMock() {
+ function MyMock($test, $wildcard) {
+ $this-&gt;SimpleMock(&amp;$test, $wildcard);
+ }
+
+ function _assertTrue($assertion, $message , &amp;$test) {
+ $test-&gt;assertion($message, $assertion);
+ }
+ }<strong>
+ SimpleTestOptions::setMockBaseClass('MyMock');</strong>
+?&gt;
+</pre>
+ A partir de maintenant vous avez juste à inclure
+ <em>my_mock.php</em> à la place de la version par défaut
+ <em>simple_mock.php</em> et vous pouvez introduire
+ des objets fantaisie dans votre suite de tests existants.
+ </p>
+
+ </div>
+ References and related information...
+ <ul>
+<li>
+ L'article originel sur
+ <a href="http://www.mockobjects.com/">les objets fantaisie</a>.
+ </li>
+<li>
+ La page du projet SimpleTest sur
+ <a href="http://sourceforge.net/projects/simpletest/">SourceForge</a>.
+ </li>
+<li>
+ La page d'accueil de SimpleTest sur
+ <a href="http://www.lastcraft.com/simple_test.php">LastCraft</a>.
+ </li>
+</ul>
+<div class="menu_back"><div class="menu">
+<a href="index.html">SimpleTest</a>
+ |
+ <a href="overview.html">Overview</a>
+ |
+ <a href="unit_test_documentation.html">Unit tester</a>
+ |
+ <a href="group_test_documentation.html">Group tests</a>
+ |
+ <a href="mock_objects_documentation.html">Mock objects</a>
+ |
+ <a href="partial_mocks_documentation.html">Partial mocks</a>
+ |
+ <a href="reporter_documentation.html">Reporting</a>
+ |
+ <a href="expectation_documentation.html">Expectations</a>
+ |
+ <a href="web_tester_documentation.html">Web tester</a>
+ |
+ <a href="form_testing_documentation.html">Testing forms</a>
+ |
+ <a href="authentication_documentation.html">Authentication</a>
+ |
+ <a href="browser_documentation.html">Scriptable browser</a>
+</div></div>
+<div class="copyright">
+ Copyright<br>Marcus Baker 2006
+ </div>
+</body>
+</html>
diff --git a/site/vendors/simpletest/docs/fr/overview.html b/site/vendors/simpletest/docs/fr/overview.html
new file mode 100644
index 0000000..3225b96
--- /dev/null
+++ b/site/vendors/simpletest/docs/fr/overview.html
@@ -0,0 +1,318 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>
+ Aperçu et liste des fonctionnalités des testeurs unitaires PHP et web de SimpleTest PHP
+ </title>
+<link rel="stylesheet" type="text/css" href="docs.css" title="Styles">
+</head>
+<body>
+<div class="menu_back"><div class="menu">
+<a href="index.html">SimpleTest</a>
+ |
+ <a href="overview.html">Overview</a>
+ |
+ <a href="unit_test_documentation.html">Unit tester</a>
+ |
+ <a href="group_test_documentation.html">Group tests</a>
+ |
+ <a href="mock_objects_documentation.html">Mock objects</a>
+ |
+ <a href="partial_mocks_documentation.html">Partial mocks</a>
+ |
+ <a href="reporter_documentation.html">Reporting</a>
+ |
+ <a href="expectation_documentation.html">Expectations</a>
+ |
+ <a href="web_tester_documentation.html">Web tester</a>
+ |
+ <a href="form_testing_documentation.html">Testing forms</a>
+ |
+ <a href="authentication_documentation.html">Authentication</a>
+ |
+ <a href="browser_documentation.html">Scriptable browser</a>
+</div></div>
+<h1>Apercu de SimpleTest</h1>
+ This page...
+ <ul>
+<li>
+ <a href="#resume">Résumé rapide</a> de l'outil SimpleTest pour PHP.
+ </li>
+<li>
+ <a href="#fonctionnalites">La liste des fonctionnalites</a>, à la fois présentes et à venir.
+ </li>
+<li>
+ Il y a beaucoup de <a href="#ressources">ressources sur les tests unitaires</a> sur le web.
+ </li>
+</ul>
+<div class="content">
+ <p><a class="target" name="resume"><h2>Qu'est-ce que SimpleTest ?</h2></a></p>
+ <p>
+ Le coeur de SimpleTest est un framework de test construit autour de classes de scénarios de test. Celles-ci sont écrites comme des extensions des classes premières de scénarios de test, chacune élargie avec des méthodes qui contiennent le code de test effectif. Les scripts de test de haut niveau invoque la méthode <span class="new_code">run()</span> à chaque scénario de test successivement. Chaque méthode de test est écrite pour appeler des assertions diverses que le développeur suppose être vraies, <span class="new_code">assertEqual()</span> par exemple. Si l'assertion est correcte, alors un succès est expédié au rapporteur observant le test, mais toute erreur déclenche une alerte et une description de la dissension.
+ </p>
+ <p>
+ Un <a href="unit_test_documentation.html">scénario de test</a> ressemble à...
+<pre>
+class <strong>MyTestCase</strong> extends UnitTestCase {
+ <strong>
+ function testLog() {
+ $log = &amp;new Log('my.log');
+ $log-&gt;message('Hello');
+ $this-&gt;assertTrue(file_exists('my.log'));
+ }</strong>
+}
+</pre>
+ </p>
+ <p>
+ Ces outils sont conçus pour le développeur. Les tests sont écrits en PHP directement, plus ou moins simultanément avec la construction de l'application elle-même. L'avantage d'utiliser PHP lui-même comme langage de test est qu'il n'y a pas de nouveau langage à apprendre, les tests peuvent commencer directement et le développeur peut tester n'importe quelle partie du code. Plus simplement, toutes les parties qui peuvent être accédées par le code de l'application peuvent aussi être accédées par le code de test si ils sont tous les deux dans le même langage.
+ </p>
+ <p>
+ Le type de scénario de test le plus simple est le <span class="new_code">UnitTestCase</span>. Cette classe de scénario de test inclut les tests standards pour l'égalité, les références et l'appariement de motifs (via les expressions rationnelles). Ceux-ci testent ce que vous seriez en droit d'attendre du résultat d'une fonction ou d'une méthode. Il s'agit du type de test le plus commun pendant le quotidien du développeur, peut-être 95% des scénarios de test.
+ </p>
+ <p>
+ La tâche ultime d'une application web n'est cependant pas de produire une sortie correcte à partir de méthodes ou d'objets, mais plutôt de produire des pages web. La classe <span class="new_code">WebTestCase</span> teste des pages web. Elle simule un navigateur web demandant une page, de façon exhaustive : cookies, proxies, connexions sécurisées, authentification, formulaires, cadres et la plupart des éléments de navigation. Avec ce type de scénario de test, le développeur peut garantir que telle ou telle information est présente dans la page et que les formulaires ainsi que les sessions sont gérés comme il faut.
+ </p>
+ <p>
+ Un <a href="web_tester_documentation.html">scénario de test web</a> ressemble à...
+<pre>
+class <strong>MySiteTest</strong> extends WebTestCase {
+ <strong>
+ function testHomePage() {
+ $this-&gt;get('http://www.my-site.com/index.php');
+ $this-&gt;assertTitle('My Home Page');
+ $this-&gt;clickLink('Contact');
+ $this-&gt;assertTitle('Contact me');
+ $this-&gt;assertWantedPattern('/Email me at/');
+ }</strong>
+}
+</pre>
+ </p>
+
+ <p><a class="target" name="fonctionnalites"><h2>Liste des fonctionnalites</h2></a></p>
+ <p>
+ Ci-dessous vous trouverez un canevas assez brut des fonctionnalités à aujourd'hui et pour demain, sans oublier leur date approximative de publication. J'ai bien peur qu'il soit modifiable sans pré-avis étant donné que les jalons dépendent beaucoup sur le temps disponible. Les trucs en vert ont été codés, mais pas forcément déjà rendus public. Si vous avez une besoin pressant pour une fonctionnalité verte mais pas encore publique alors vous devriez retirer le code directement sur le CVS chez SourceFourge. Une fonctionnalitée publiée est indiqué par "Fini".
+ <table>
+<thead>
+ <tr>
+<th>Fonctionnalité</th>
+<th>Description</th>
+<th>Publication</th>
+</tr>
+ </thead>
+<tbody>
+<tr>
+ <td>Scénariot de test unitaire</td>
+ <td>Les classes de test et assertions de base</td>
+ <td style="color: green;">Fini</td>
+ </tr>
+ <tr>
+ <td>Affichage HTML</td>
+ <td>L'affichage le plus simple possible</td>
+ <td style="color: green;">Fini</td>
+ </tr>
+ <tr>
+ <td>Autochargement des scénarios de test</td>
+ <td>Lire un fichier avec des scénarios de test et les charger dans un groupe de tests automatiquement</td>
+ <td style="color: green;">Fini</td>
+ </tr>
+ <tr>
+ <td>Générateur de code d'objets fantaisie</td>
+ <td>Des objets capable de simuler d'autres objets, supprimant les dépendances dans les tests</td>
+ <td style="color: green;">Fini</td>
+ </tr>
+ <tr>
+ <td>Bouchons serveur</td>
+ <td>Des objets fantaisie sans résultat attendu à utiliser à l'extérieur des scénarios de test, pour le prototypage par exemple.</td>
+ <td style="color: green;">Fini</td>
+ </tr>
+ <tr>
+ <td>Intégration d'autres testeurs unitaires</td>
+ <td>
+ La capacité de lire et simuler d'autres scénarios de test en provenance de PHPUnit et de PEAR::Phpunit.</td>
+ <td style="color: green;">Fini</td>
+ </tr>
+ <tr>
+ <td>Scénario de test web</td>
+ <td>Appariement basique de motifs dans une page téléchargée.</td>
+ <td style="color: green;">Fini</td>
+ </tr>
+ <tr>
+ <td>Analyse de page HTML</td>
+ <td>Permet de suivre les liens et de trouver la balise de titre</td>
+ <td style="color: green;">Fini</td>
+ </tr>
+ <tr>
+ <td>Simulacre partiel</td>
+ <td>Simuler des parties d'une classe pour tester moins qu'une classe ou dans des cas complexes.</td>
+ <td style="color: green;">Fini</td>
+ </tr>
+ <tr>
+ <td>Gestion des cookies Web</td>
+ <td>Gestion correcte des cookies au téléchargement d'une page.</td>
+ <td style="color: green;">Fini</td>
+ </tr>
+ <tr>
+ <td>Suivi des redirections</td>
+ <td>Le téléchargement d'une page suit automatiquement une redirection 300.</td>
+ <td style="color: green;">Fini</td>
+ </tr>
+ <tr>
+ <td>Analyse d'un formulaire</td>
+ <td>La capacité de valider un formulaire simple et d'en lire les valeurs par défaut.</td>
+ <td style="color: green;">Fini</td>
+ </tr>
+ <tr>
+ <td>Interface en ligne de commande</td>
+ <td>Affiche le résultat des tests sans navigateur web.</td>
+ <td style="color: green;">Fini</td>
+ </tr>
+ <tr>
+ <td>Mise à nu des attentes d'une classe</td>
+ <td>Peut créer des tests précis avec des simulacres ainsi que des scénarios de test.</td>
+ <td style="color: green;">Fini</td>
+ </tr>
+ <tr>
+ <td>Sortie et analyse XML</td>
+ <td>Permet de tester sur plusieurs hôtes et d'intégrer des extensions d'acceptation de test.</td>
+ <td style="color: green;">Fini</td>
+ </tr>
+ <tr>
+ <td>Scénario de test en ligne de commande</td>
+ <td>Permet de tester des outils ou scripts en ligne de commande et de manier des fichiers.</td>
+ <td style="color: green;">Fini</td>
+ </tr>
+ <tr>
+ <td>Compatibilité avec PHP Documentor</td>
+ <td>Génération automatique et complète de la documentation au niveau des classes.</td>
+ <td style="color: green;">Fini</td>
+ </tr>
+ <tr>
+ <td>Interface navigateur</td>
+ <td>Mise à nu des niveaux bas de l'interface du navigateur web pour des scénarios de test plus précis.</td>
+ <td style="color: green;">Fini</td>
+ </tr>
+ <tr>
+ <td>Authentification HTTP</td>
+ <td>Téléchargement des pages web protégées avec une authentification basique seulement.</td>
+ <td style="color: green;">Fini</td>
+ </tr>
+ <tr>
+ <td>Boutons de navigation d'un navigateur</td>
+ <td>Arrière, avant et recommencer</td>
+ <td style="color: green;">Fini</td>
+ </tr>
+ <tr>
+ <td>Support de SSL</td>
+ <td>Peut se connecter à des pages de type https.</td>
+ <td style="color: green;">Fini</td>
+ </tr>
+ <tr>
+ <td>Support de proxy</td>
+ <td>Peut se connecter via des proxys communs</td>
+ <td style="color: green;">Fini</td>
+ </tr>
+ <tr>
+ <td>Support des cadres</td>
+ <td>Gère les cadres dans les scénarios de test web.</td>
+ <td style="color: green;">Fini</td>
+ </tr>
+ <tr>
+ <td>Test de l'upload de fichier</td>
+ <td>Peut simuler la balise input de type file</td>
+ <td style="color: red;">1.0.1</td>
+ </tr>
+ <tr>
+ <td>Amélioration sur la machinerie des rapports</td>
+ <td>Retouche sur la transmission des messages pour une meilleur coopération avec les IDEs</td>
+ <td style="color: red;">1.1</td>
+ </tr>
+ <tr>
+ <td>Amélioration de l'affichage des tests</td>
+ <td>Une meilleure interface graphique web, avec un arbre des scénarios de test.</td>
+ <td style="color: red;">1.1</td>
+ </tr>
+ <tr>
+ <td>Localisation</td>
+ <td>Abstraction des messages et génration du code à partir de fichiers XML.</td>
+ <td style="color: red;">1.1</td>
+ </tr>
+ <tr>
+ <td>Simulation d'interface</td>
+ <td>Peut générer des objets fantaisie tant vers des interfaces que vers des classes.</td>
+ <td style="color: red;">2.0</td>
+ </tr>
+ <tr>
+ <td>Test sur es exceptions</td>
+ <td>Dans le même esprit que sur les tests des erreurs PHP.</td>
+ <td style="color: red;">2.0</td>
+ </tr>
+ <tr>
+ <td>Rercherche d'éléments avec XPath</td>
+ <td>Peut utiliser Tidy HTML pour un appariement plus rapide et plus souple.</td>
+ <td style="color: red;">2.0</td>
+ </tr>
+ </tbody>
+</table>
+ La migration vers PHP5 commencera juste après la série des 1.0, à partir de là PHP4 ne sera plus supporté. SimpleTest est actuellement compatible avec PHP5 mais n'utilisera aucune des nouvelles fonctionnalités avant la version 2.
+ </p>
+
+ <p><a class="target" name="ressources"><h2>Ressources sur le web pour les tests</h2></a></p>
+ <p>
+ Le processus est au moins aussi important que les outils. Le type de procédure que fait un usage le plus intensif des outils de test pour développeur est bien sûr l'<a href="http://www.extremeprogramming.org/">Extreme Programming</a>. Il s'agit là d'une des <a href="http://www.agilealliance.com/articles/index">méthodes agiles</a> qui combinent plusieurs pratiques pour "lisser la courbe de coût" du développement logiciel. La plus extrème reste le <a href="http://www.testdriven.com/modules/news/">développement piloté par les tests</a>, où vous devez adhérer à la règle du <cite>pas de code avant d'avoir un test</cite>. Si vous êtes plutôt du genre planninficateur ou que vous estimez que l'expérience compte plus que l'évolution, vous préférerez peut-être l'approche <a href="http://www.therationaledge.com/content/dec_01/f_spiritOfTheRUP_pk.html">RUP</a>. Je ne l'ai pas testé mais je peux voir où vous aurez besoin d'outils de test (cf. illustration 9).
+ </p>
+ <p>
+ La plupart des testeurs unitaires sont dans une certaine mesure un clone de <a href="http://www.junit.org/">JUnit</a>, au moins dans l'interface. Il y a énormément d'information sur le site de JUnit, à commencer par la <a href="http://junit.sourceforge.net/doc/faq/faq.htm">FAQ</a> quie contient pas mal de conseils généraux sur les tests. Une fois mordu par le bogue vous apprécierez sûrement la phrase <a href="http://junit.sourceforge.net/doc/testinfected/testing.htm">infecté par les tests</a> trouvée par Eric Gamma. Si vous êtes encore en train de tergiverser sur un testeur unitaire, sachez que les choix principaux sont <a href="http://phpunit.sourceforge.net/">PHPUnit</a> et <a href="http://pear.php.net/manual/en/package.php.phpunit.php">Pear PHP::PHPUnit</a>. De nombreuses fonctionnalités de SimpleTest leurs font défaut, mais la version PEAR a d'ores et déjà été mise à jour pour PHP5. Elle est aussi recommandée si vous portez des scénarios de test existant depuis <a href="http://www.junit.org/">JUnit</a>.
+ </p>
+ <p>
+ Les développeurs de bibliothèque n'ont pas l'air de livrer très souvent des tests avec leur code : c'est bien dommage. Le code d'une bibliothèque qui inclut des tests peut être remanié avec plus de sécurité et le code de test sert de documentation additionnelle dans un format assez standard. Ceci peut épargner la pêche aux indices dans le code source lorsque qu'un problème survient, en particulier lors de la mise à jour d'une telle bibliothèque. Parmi les bibliothèques utilisant SimpleTest comme testeur unitaire on retrouve <a href="http://wact.sourceforge.net/">WACT</a> et <a href="http://sourceforge.net/projects/htmlsax">PEAR::XML_HTMLSax</a>.
+ </p>
+ <p>
+ Au jour d'aujourd'hui il manque tristement beaucoup de matière sur les objets fantaisie : dommage, surtout que tester unitairement sans eux représente pas mal de travail en plus. L'<a href="http://www.sidewize.com/company/mockobjects.pdf">article original sur les objets fantaisie</a> est très orienté Java, mais reste intéressant à lire. Etant donné qu'il s'agit d'une nouvelle technologie il y a beaucoup de discussions et de débats sur comment les utiliser, souvent sur des wikis comme <a href="http://xpdeveloper.com/cgi-bin/oldwiki.cgi?MockObjects">Extreme Tuesday</a> ou <a href="http://www.mockobjects.com/MocksObjectsPaper.html">www.mockobjects.com</a>ou <a href="http://c2.com/cgi/wiki?MockObject">the original C2 Wiki</a>. Injecter des objets fantaisie dans une classe est un des champs principaux du débat : cet <a href="http://www-106.ibm.com/developerworks/java/library/j-mocktest.html">article chez IBM</a> en est un bon point de départ.
+ </p>
+ <p>
+ Il y a énormement d'outils de test web mais la plupart sont écrits en Java. De plus les tutoriels et autres conseils sont plutôt rares. Votre seul espoir est de regarder directement la documentation pour <a href="http://httpunit.sourceforge.net/">HTTPUnit</a>, <a href="http://htmlunit.sourceforge.net/">HTMLUnit</a> ou <a href="http://jwebunit.sourceforge.net/">JWebUnit</a> et d'espérer y trouver pour des indices. Il y a aussi des frameworks basés sur XML, mais de nouveau la plupart ont besoin de Java pour tourner.
+ </p>
+
+ </div>
+ References and related information...
+ <ul>
+<li>
+ <a href="unit_test_documentation.html">Documentation pour SimpleTest</a>.
+ </li>
+<li>
+ <a href="http://www.lastcraft.com/first_test_tutorial.php">Comment écrire des scénarios de test en PHP</a> est un tutoriel plutôt avancé.
+ </li>
+<li>
+ <a href="http://simpletest.org/api/">L'API de SimpleTest</a> par phpdoc.
+ </li>
+</ul>
+<div class="menu_back"><div class="menu">
+<a href="index.html">SimpleTest</a>
+ |
+ <a href="overview.html">Overview</a>
+ |
+ <a href="unit_test_documentation.html">Unit tester</a>
+ |
+ <a href="group_test_documentation.html">Group tests</a>
+ |
+ <a href="mock_objects_documentation.html">Mock objects</a>
+ |
+ <a href="partial_mocks_documentation.html">Partial mocks</a>
+ |
+ <a href="reporter_documentation.html">Reporting</a>
+ |
+ <a href="expectation_documentation.html">Expectations</a>
+ |
+ <a href="web_tester_documentation.html">Web tester</a>
+ |
+ <a href="form_testing_documentation.html">Testing forms</a>
+ |
+ <a href="authentication_documentation.html">Authentication</a>
+ |
+ <a href="browser_documentation.html">Scriptable browser</a>
+</div></div>
+<div class="copyright">
+ Copyright<br>Marcus Baker 2006
+ </div>
+</body>
+</html>
diff --git a/site/vendors/simpletest/docs/fr/partial_mocks_documentation.html b/site/vendors/simpletest/docs/fr/partial_mocks_documentation.html
new file mode 100644
index 0000000..32a39c7
--- /dev/null
+++ b/site/vendors/simpletest/docs/fr/partial_mocks_documentation.html
@@ -0,0 +1,460 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Documentation SimpleTest : les objets fantaisie partiels</title>
+<link rel="stylesheet" type="text/css" href="docs.css" title="Styles">
+</head>
+<body>
+<div class="menu_back"><div class="menu">
+<a href="index.html">SimpleTest</a>
+ |
+ <a href="overview.html">Overview</a>
+ |
+ <a href="unit_test_documentation.html">Unit tester</a>
+ |
+ <a href="group_test_documentation.html">Group tests</a>
+ |
+ <a href="mock_objects_documentation.html">Mock objects</a>
+ |
+ <a href="partial_mocks_documentation.html">Partial mocks</a>
+ |
+ <a href="reporter_documentation.html">Reporting</a>
+ |
+ <a href="expectation_documentation.html">Expectations</a>
+ |
+ <a href="web_tester_documentation.html">Web tester</a>
+ |
+ <a href="form_testing_documentation.html">Testing forms</a>
+ |
+ <a href="authentication_documentation.html">Authentication</a>
+ |
+ <a href="browser_documentation.html">Scriptable browser</a>
+</div></div>
+<h1>Documentation sur les objets fantaisie partiels</h1>
+ This page...
+ <ul>
+<li>
+ <a href="#injection">Le problème de l'injection d'un objet fantaisie</a>.
+ </li>
+<li>
+ Déplacer la création vers une méthode <a href="#creation">fabrique protégée</a>.
+ </li>
+<li>
+ <a href="#partiel">L'objet fantaisie partiel</a> génère une sous-classe.
+ </li>
+<li>
+ Les objets fantaisie partiels <a href="#moins">testent moins qu'une classe</a>.
+ </li>
+</ul>
+<div class="content">
+
+ <p>
+ Un objet fantaisie partiel n'est ni plus ni moins
+ qu'un modèle de conception pour soulager un problème spécifique
+ du test avec des objets fantaisie, celui de placer
+ des objets fantaisie dans des coins serrés.
+ Il s'agit d'un outil assez limité et peut-être même
+ une idée pas si bonne que ça. Elle est incluse dans SimpleTest
+ pour la simple raison que je l'ai trouvée utile
+ à plus d'une occasion et qu'elle m'a épargnée
+ pas mal de travail dans ces moments-là.
+ </p>
+
+ <p><a class="target" name="injection"><h2>Le problème de l'injection dans un objet fantaisie</h2></a></p>
+ <p>
+ Quand un objet en utilise un autre il est très simple
+ d'y faire circuler une version fantaisie déjà prête
+ avec ses attentes. Les choses deviennent un peu plus délicates
+ si un objet en crée un autre et que le créateur est celui
+ que l'on souhaite tester. Cela revient à dire que l'objet
+ créé devrait être une fantaisie, mais nous pouvons
+ difficilement dire à notre classe sous test de créer
+ un objet fantaisie plutôt qu'un "vrai" objet.
+ La classe testée ne sait même pas qu'elle travaille dans un environnement de test.
+ </p>
+ <p>
+ Par exemple, supposons que nous sommes en train
+ de construire un client telnet et qu'il a besoin
+ de créer une socket réseau pour envoyer ses messages.
+ La méthode de connexion pourrait ressemble à quelque chose comme...
+<pre>
+<strong>&lt;?php
+require_once('socket.php');
+
+class Telnet {
+ ...
+ function &amp;connect($ip, $port, $username, $password) {
+ $socket = &amp;new Socket($ip, $port);
+ $socket-&gt;read( ... );
+ ...
+ }
+}
+?&gt;</strong>
+</pre>
+ Nous voudrions vraiment avoir une version fantaisie
+ de l'objet socket, que pouvons nous faire ?
+ </p>
+ <p>
+ La première solution est de passer la socket en
+ tant que paramètre, ce qui force la création
+ au niveau inférieur. Charger le client de cette tâche
+ est effectivement une bonne approche si c'est possible
+ et devrait conduire à un remaniement -- de la création
+ à partir de l'action. En fait, c'est là une des manières
+ avec lesquels tester en s'appuyant sur des objets fantaisie
+ vous force à coder des solutions plus resserrées sur leur objectif.
+ Ils améliorent votre programmation.
+ </p>
+ <p>
+ Voici ce que ça devrait être...
+<pre>
+&lt;?php
+require_once('socket.php');
+
+class Telnet {
+ ...
+ <strong>function &amp;connect(&amp;$socket, $username, $password) {
+ $socket-&gt;read( ... );
+ ...
+ }</strong>
+}
+?&gt;
+</pre>
+ Sous-entendu, votre code de test est typique d'un cas
+ de test avec un objet fantaisie.
+<pre>
+class TelnetTest extends UnitTestCase {
+ ...
+ function testConnection() {<strong>
+ $socket = &amp;new MockSocket($this);
+ ...
+ $telnet = &amp;new Telnet();
+ $telnet-&gt;connect($socket, 'Me', 'Secret');
+ ...</strong>
+ }
+}
+</pre>
+ C'est assez évident que vous ne pouvez descendre que d'un niveau.
+ Vous ne voudriez pas que votre application de haut niveau
+ crée tous les fichiers de bas niveau, sockets et autres connexions
+ à la base de données dont elle aurait besoin.
+ Elle ne connaîtrait pas les paramètres du constructeur de toute façon.
+ </p>
+ <p>
+ La solution suivante est de passer l'objet créé sous la forme
+ d'un paramètre optionnel...
+<pre>
+&lt;?php
+require_once('socket.php');
+
+class Telnet {
+ ...<strong>
+ function &amp;connect($ip, $port, $username, $password, $socket = false) {
+ if (!$socket) {
+ $socket = &amp;new Socket($ip, $port);
+ }
+ $socket-&gt;read( ... );</strong>
+ ...
+ return $socket;
+ }
+}
+?&gt;
+</pre>
+ Pour une solution rapide, c'est généralement suffisant.
+ Ensuite le test est très similaire : comme si le paramètre
+ était transmis formellement...
+<pre>
+class TelnetTest extends UnitTestCase {
+ ...
+ function testConnection() {<strong>
+ $socket = &amp;new MockSocket($this);
+ ...
+ $telnet = &amp;new Telnet();
+ $telnet-&gt;connect('127.0.0.1', 21, 'Me', 'Secret', &amp;$socket);
+ ...</strong>
+ }
+}
+</pre>
+ Le problème de cette approche tient dans son manque de netteté.
+ Il y a du code de test dans la classe principale et aussi
+ des paramètres transmis dans le scénario de test
+ qui ne sont jamais utilisés. Il s'agit là d'une approche
+ rapide et sale, mais qui ne reste pas moins efficace
+ dans la plupart des situations.
+ </p>
+ <p>
+ Une autre solution encore est de laisser un objet fabrique
+ s'occuper de la création...
+<pre>
+&lt;?php
+require_once('socket.php');
+
+class Telnet {<strong>
+ function Telnet(&amp;$network) {
+ $this-&gt;_network = &amp;$network;
+ }</strong>
+ ...
+ function &amp;connect($ip, $port, $username, $password) {<strong>
+ $socket = &amp;$this-&gt;_network-&gt;createSocket($ip, $port);
+ $socket-&gt;read( ... );</strong>
+ ...
+ return $socket;
+ }
+}
+?&gt;
+</pre>
+ Il s'agit là probablement de la réponse la plus travaillée
+ étant donné que la création est maintenant située
+ dans une petite classe spécialisée. La fabrique réseau
+ peut être testée séparément et utilisée en tant que fantaisie
+ quand nous testons la classe telnet...
+<pre>
+class TelnetTest extends UnitTestCase {
+ ...
+ function testConnection() {<strong>
+ $socket = &amp;new MockSocket($this);
+ ...
+ $network = &amp;new MockNetwork($this);
+ $network-&gt;setReturnReference('createSocket', $socket);
+ $telnet = &amp;new Telnet($network);
+ $telnet-&gt;connect('127.0.0.1', 21, 'Me', 'Secret');
+ ...</strong>
+ }
+}
+</pre>
+ Le problème reste que nous ajoutons beaucoup de classes
+ à la bibliothèque. Et aussi que nous utilisons beaucoup
+ de fabriques ce qui rend notre code un peu moins intuitif.
+ La solution la plus flexible, mais aussi la plus complexe.
+ </p>
+ <p>
+ Peut-on trouver un juste milieu ?
+ </p>
+
+ <p><a class="target" name="creation"><h2>Méthode fabrique protégée</h2></a></p>
+ <p>
+ Il existe une technique pour palier à ce problème
+ sans créer de nouvelle classe dans l'application;
+ par contre elle induit la création d'une sous-classe au moment du test.
+ Premièrement nous déplaçons la création de la socket dans sa propre méthode...
+<pre>
+&lt;?php
+require_once('socket.php');
+
+class Telnet {
+ ...
+ function &amp;connect($ip, $port, $username, $password) {<strong>
+ $socket = &amp;$this-&gt;_createSocket($ip, $port);</strong>
+ $socket-&gt;read( ... );
+ ...
+ }<strong>
+
+ function &amp;_createSocket($ip, $port) {
+ return new Socket($ip, $port);
+ }</strong>
+}
+?&gt;
+</pre>
+ Il s'agit là de la seule modification dans le code de l'application.
+ </p>
+ <p>
+ Pour le scénario de test, nous devons créer
+ une sous-classe de manière à intercepter la création de la socket...
+<pre>
+<strong>class TelnetTestVersion extends Telnet {
+ var $_mock;
+
+ function TelnetTestVersion(&amp;$mock) {
+ $this-&gt;_mock = &amp;$mock;
+ $this-&gt;Telnet();
+ }
+
+ function &amp;_createSocket() {
+ return $this-&gt;_mock;
+ }
+}</strong>
+</pre>
+ Ici j'ai déplacé la fantaisie dans le constructeur,
+ mais un setter aurait fonctionné tout aussi bien.
+ Notez bien que la fantaisie est placée dans une variable
+ d'objet avant que le constructeur ne soit attaché.
+ C'est nécessaire dans le cas où le constructeur appelle
+ <span class="new_code">connect()</span>.
+ Autrement il pourrait donner un valeur nulle à partir de
+ <span class="new_code">_createSocket()</span>.
+ </p>
+ <p>
+ Après la réalisation de tout ce travail supplémentaire
+ le scénario de test est assez simple.
+ Nous avons juste besoin de tester notre nouvelle classe à la place...
+<pre>
+class TelnetTest extends UnitTestCase {
+ ...
+ function testConnection() {<strong>
+ $socket = &amp;new MockSocket($this);
+ ...
+ $telnet = &amp;new TelnetTestVersion($socket);
+ $telnet-&gt;connect('127.0.0.1', 21, 'Me', 'Secret');
+ ...</strong>
+ }
+}
+</pre>
+ Cette nouvelle classe est très simple bien sûr.
+ Elle ne fait qu'initier une valeur renvoyée, à la manière
+ d'une fantaisie. Ce serait pas mal non plus si elle pouvait
+ vérifier les paramètres entrants.
+ Exactement comme un objet fantaisie.
+ Il se pourrait bien que nous ayons à réaliser cette astuce régulièrement :
+ serait-il possible d'automatiser la création de cette sous-classe ?
+ </p>
+
+ <p><a class="target" name="partiel"><h2>Un objet fantaisie partiel</h2></a></p>
+ <p>
+ Bien sûr la réponse est "oui"
+ ou alors j'aurais arrêté d'écrire depuis quelques temps déjà !
+ Le test précédent a représenté beaucoup de travail,
+ mais nous pouvons générer la sous-classe en utilisant
+ une approche à celle des objets fantaisie.
+ </p>
+ <p>
+ Voici donc une version avec objet fantaisie partiel du test...
+<pre>
+<strong>Mock::generatePartial(
+ 'Telnet',
+ 'TelnetTestVersion',
+ array('_createSocket'));</strong>
+
+class TelnetTest extends UnitTestCase {
+ ...
+ function testConnection() {<strong>
+ $socket = &amp;new MockSocket($this);
+ ...
+ $telnet = &amp;new TelnetTestVersion($this);
+ $telnet-&gt;setReturnReference('_createSocket', $socket);
+ $telnet-&gt;Telnet();
+ $telnet-&gt;connect('127.0.0.1', 21, 'Me', 'Secret');
+ ...</strong>
+ }
+}
+</pre>
+ La fantaisie partielle est une sous-classe de l'original
+ dont on aurait "remplacé" les méthodes sélectionnées
+ avec des versions de test. L'appel à <span class="new_code">generatePartial()</span>
+ nécessite trois paramètres : la classe à sous classer,
+ le nom de la nouvelle classe et une liste des méthodes à simuler.
+ </p>
+ <p>
+ Instancier les objets qui en résultent est plutôt délicat.
+ L'unique paramètre du constructeur d'un objet fantaisie partiel
+ est la référence du testeur unitaire.
+ Comme avec les objets fantaisie classiques c'est nécessaire
+ pour l'envoi des résultats de test en réponse à la vérification des attentes.
+ </p>
+ <p>
+ Une nouvelle fois le constructeur original n'est pas lancé.
+ Indispensable dans le cas où le constructeur aurait besoin
+ des méthodes fantaisie : elles n'ont pas encore été initiées !
+ Nous initions les valeurs retournées à cet instant et
+ ensuite lançons le constructeur avec ses paramètres normaux.
+ Cette construction en trois étapes de "new",
+ suivie par la mise en place des méthodes et ensuite
+ par la lancement du constructeur proprement dit est
+ ce qui distingue le code d'un objet fantaisie partiel.
+ </p>
+ <p>
+ A part pour leur construction, toutes ces méthodes
+ fantaisie ont les mêmes fonctionnalités que dans
+ le cas des objets fantaisie et toutes les méthodes
+ non fantaisie se comportent comme avant.
+ Nous pouvons mettre en place des attentes très facilement...
+<pre>
+class TelnetTest extends UnitTestCase {
+ ...
+ function testConnection() {
+ $socket = &amp;new MockSocket($this);
+ ...
+ $telnet = &amp;new TelnetTestVersion($this);
+ $telnet-&gt;setReturnReference('_createSocket', $socket);<strong>
+ $telnet-&gt;expectOnce('_createSocket', array('127.0.0.1', 21));</strong>
+ $telnet-&gt;Telnet();
+ $telnet-&gt;connect('127.0.0.1', 21, 'Me', 'Secret');
+ ...<strong>
+ $telnet-&gt;tally();</strong>
+ }
+}
+</pre>
+ </p>
+
+ <p><a class="target" name="moins"><h2>Tester moins qu'une classe</h2></a></p>
+ <p>
+ Les méthodes issues d'un objet fantaisie n'ont pas
+ besoin d'être des méthodes fabrique, Il peut s'agir
+ de n'importe quelle sorte de méthode.
+ Ainsi les objets fantaisie partiels nous permettent
+ de prendre le contrôle de n'importe quelle partie d'une classe,
+ le constructeur excepté. Nous pourrions même aller jusqu'à
+ créer des fantaisies sur toutes les méthodes à part celle
+ que nous voulons effectivement tester.
+ </p>
+ <p>
+ Cette situation est assez hypothétique, étant donné
+ que je ne l'ai jamais essayée. Je suis ouvert à cette possibilité,
+ mais je crains qu'en forçant la granularité d'un objet
+ on n'obtienne pas forcément un code de meilleur qualité.
+ Personnellement j'utilise les objets fantaisie partiels
+ comme moyen de passer outre la création ou alors
+ de temps en temps pour tester le modèle de conception TemplateMethod.
+ </p>
+ <p>
+ Pour choisir le mécanisme à utiliser, on en revient
+ toujours aux standards de code de votre projet.
+ </p>
+
+ </div>
+ References and related information...
+ <ul>
+<li>
+ La page du projet SimpleTest sur
+ <a href="http://sourceforge.net/projects/simpletest/">SourceForge</a>.
+ </li>
+<li>
+ <a href="http://simpletest.org/api/">L'API complète pour SimpleTest</a>
+ à partir de PHPDoc.
+ </li>
+<li>
+ La méthode fabrique protégée est décrite dans
+ <a href="http://www-106.ibm.com/developerworks/java/library/j-mocktest.html">
+ cet article d'IBM</a>. Il s'agit de l'unique papier
+ formel que j'ai vu sur ce problème.
+ </li>
+</ul>
+<div class="menu_back"><div class="menu">
+<a href="index.html">SimpleTest</a>
+ |
+ <a href="overview.html">Overview</a>
+ |
+ <a href="unit_test_documentation.html">Unit tester</a>
+ |
+ <a href="group_test_documentation.html">Group tests</a>
+ |
+ <a href="mock_objects_documentation.html">Mock objects</a>
+ |
+ <a href="partial_mocks_documentation.html">Partial mocks</a>
+ |
+ <a href="reporter_documentation.html">Reporting</a>
+ |
+ <a href="expectation_documentation.html">Expectations</a>
+ |
+ <a href="web_tester_documentation.html">Web tester</a>
+ |
+ <a href="form_testing_documentation.html">Testing forms</a>
+ |
+ <a href="authentication_documentation.html">Authentication</a>
+ |
+ <a href="browser_documentation.html">Scriptable browser</a>
+</div></div>
+<div class="copyright">
+ Copyright<br>Marcus Baker 2006
+ </div>
+</body>
+</html>
diff --git a/site/vendors/simpletest/docs/fr/reporter_documentation.html b/site/vendors/simpletest/docs/fr/reporter_documentation.html
new file mode 100644
index 0000000..0dc56ed
--- /dev/null
+++ b/site/vendors/simpletest/docs/fr/reporter_documentation.html
@@ -0,0 +1,534 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Documentation SimpleTest : le rapporteur de test</title>
+<link rel="stylesheet" type="text/css" href="docs.css" title="Styles">
+</head>
+<body>
+<div class="menu_back"><div class="menu">
+<a href="index.html">SimpleTest</a>
+ |
+ <a href="overview.html">Overview</a>
+ |
+ <a href="unit_test_documentation.html">Unit tester</a>
+ |
+ <a href="group_test_documentation.html">Group tests</a>
+ |
+ <a href="mock_objects_documentation.html">Mock objects</a>
+ |
+ <a href="partial_mocks_documentation.html">Partial mocks</a>
+ |
+ <a href="reporter_documentation.html">Reporting</a>
+ |
+ <a href="expectation_documentation.html">Expectations</a>
+ |
+ <a href="web_tester_documentation.html">Web tester</a>
+ |
+ <a href="form_testing_documentation.html">Testing forms</a>
+ |
+ <a href="authentication_documentation.html">Authentication</a>
+ |
+ <a href="browser_documentation.html">Scriptable browser</a>
+</div></div>
+<h1>Documentation sur le rapporteur de test</h1>
+ This page...
+ <ul>
+<li>
+ Afficher <a href="#html">les résultats en HTML</a>
+ </li>
+<li>
+ Afficher et <a href="#autres">rapporter les résultats</a>
+ dans d'autres formats
+ </li>
+<li>
+ Utilisé <a href="#cli">SimpleTest depuis la ligne de commande</a>
+ </li>
+<li>
+ <a href="#xml">Utiliser XML</a> pour des tests distants
+ </li>
+</ul>
+<div class="content">
+
+ <p>
+ SimpleTest suit plutôt plus que moins le modèle MVC (Modèle-Vue-Contrôleur).
+ Les classes "reporter" sont les vues et les modèles
+ sont vos scénarios de test et leur hiérarchie.
+ Le contrôleur est le plus souvent masqué à l'utilisateur
+ de SimpleTest à moins de vouloir changer la façon
+ dont les tests sont effectivement exécutés,
+ auquel cas il est possible de surcharger les objets
+ "runner" (ceux de l'exécuteur) depuis l'intérieur
+ d'un scénario de test. Comme d'habitude avec MVC,
+ le contrôleur est plutôt indéfini et il existe d'autres endroits
+ pour contrôler l'exécution des tests.
+ </p>
+
+ <p><a class="target" name="html"><h2>Les résultats rapportés au format HTML</h2></a></p>
+ <p>
+ L'affichage par défaut est minimal à l'extrême.
+ Il renvoie le succès ou l'échec avec les barres conventionnelles
+ - rouge et verte - et affichent une trace d'arborescence
+ des groupes de test pour chaque assertion erronée. Voici un tel échec...
+ <div class="demo">
+ <h1>File test</h1>
+ <span class="fail">Fail</span>: createnewfile-&gt;True assertion failed.<br>
+ <div style="padding: 8px; margin-top: 1em; background-color: red; color: white;">1/1 test cases complete.
+ <strong>0</strong> passes, <strong>1</strong> fails and <strong>0</strong> exceptions.</div>
+ </div>
+ Alors qu'ici tous les tests passent...
+ <div class="demo">
+ <h1>File test</h1>
+ <div style="padding: 8px; margin-top: 1em; background-color: green; color: white;">1/1 test cases complete.
+ <strong>1</strong> passes, <strong>0</strong> fails and <strong>0</strong> exceptions.</div>
+ </div>
+ La bonne nouvelle, c'est qu'il existe pas mal de points
+ dans la hiérarchie de l'affichage pour créer des sous-classes.
+ </p>
+ <p>
+ Pour l'affichage basé sur des pages web,
+ il y a la classe <span class="new_code">HtmlReporter</span> avec la signature suivante...
+<pre>
+class HtmlReporter extends SimpleReporter {
+ public HtmlReporter($encoding) { ... }
+ public makeDry(boolean $is_dry) { ... }
+ public void paintHeader(string $test_name) { ... }
+ public void sendNoCacheHeaders() { ... }
+ public void paintFooter(string $test_name) { ... }
+ public void paintGroupStart(string $test_name, integer $size) { ... }
+ public void paintGroupEnd(string $test_name) { ... }
+ public void paintCaseStart(string $test_name) { ... }
+ public void paintCaseEnd(string $test_name) { ... }
+ public void paintMethodStart(string $test_name) { ... }
+ public void paintMethodEnd(string $test_name) { ... }
+ public void paintFail(string $message) { ... }
+ public void paintPass(string $message) { ... }
+ public void paintError(string $message) { ... }
+ public void paintException(string $message) { ... }
+ public void paintMessage(string $message) { ... }
+ public void paintFormattedMessage(string $message) { ... }
+ protected string _getCss() { ... }
+ public array getTestList() { ... }
+ public integer getPassCount() { ... }
+ public integer getFailCount() { ... }
+ public integer getExceptionCount() { ... }
+ public integer getTestCaseCount() { ... }
+ public integer getTestCaseProgress() { ... }
+}
+</pre>
+ Voici ce que certaines de ces méthodes veulent dire.
+ Premièrement les méthodes d'affichage que vous voudrez probablement surcharger...
+ <ul class="api">
+ <li>
+ <span class="new_code">HtmlReporter(string $encoding)</span><br>
+ est le constructeur. Notez que le test unitaire initie
+ le lien à l'affichage plutôt que l'opposé.
+ L'affichage est principalement un receveur passif
+ des évènements de tests. Cela permet d'adapter
+ facilement l'affichage pour d'autres systèmes
+ en dehors des tests unitaires, tel le suivi
+ de la charge de serveurs.
+ L'"encoding" est le type d'encodage
+ que vous souhaitez utiliser pour l'affichage du test.
+ Pour pouvoir effectuer un rendu correct de la sortie
+ de débogage quand on utilise le testeur web,
+ il doit correspondre à l'encodage du site testé.
+ Les chaînes de caractères disponibles
+ sont indiquées dans la fonction PHP
+ <a href="http://www.php.net/manual/fr/function.htmlentities.php">html_entities()</a>.
+ </li>
+ <li>
+ <span class="new_code">void paintHeader(string $test_name)</span><br>
+ est appelé une fois, au début du test quand l'évènement
+ de démarrage survient. Le premier évènement de démarrage
+ est souvent délivré par le groupe de tests du niveau
+ le plus haut et donc c'est de là que le
+ <span class="new_code">$test_name</span> arrive.
+ Il peint les titres de la page, CSS, la balise "body", etc.
+ Il ne renvoie rien du tout (<span class="new_code">void</span>).
+ </li>
+ <li>
+ <span class="new_code">void paintFooter(string $test_name)</span><br>
+ est appelé à la toute fin du test pour fermer
+ les balises ouvertes par l'entête de la page.
+ Par défaut il affiche aussi la barre rouge ou verte
+ et le décompte final des résultats.
+ En fait la fin des tests arrive quand l'évènement
+ de fin de test arrive avec le même nom
+ que celui qui l'a initié au même niveau.
+ Le nid des tests en quelque sorte.
+ Fermer le dernier test finit l'affichage.
+ </li>
+ <li>
+ <span class="new_code">void paintMethodStart(string $test_name)</span><br>
+ est appelé au début de chaque méthode de test.
+ Normalement le nom vient de celui de la méthode.
+ Les autres évènements de départ de test
+ se comportent de la même manière sauf que
+ celui du groupe de tests indique au rapporteur
+ le nombre de scénarios de test qu'il contient.
+ De la sorte le rapporteur peut afficher une barre
+ de progrès au fur et à mesure que l'exécuteur
+ passe en revue les scénarios de test.
+ </li>
+ <li>
+ <span class="new_code">void paintMethodEnd(string $test_name)</span><br>
+ clôt le test lancé avec le même nom.
+ </li>
+ <li>
+ <span class="new_code">void paintFail(string $message)</span><br>
+ peint un échec. Par défaut il ne fait qu'afficher
+ le mot "fail", une trace d'arborescence
+ affichant la position du test en cours
+ et le message transmis par l'assertion.
+ </li>
+ <li>
+ <span class="new_code">void paintPass(string $message)</span><br>
+ ne fait rien, par défaut.
+ </li>
+ <li>
+ <span class="new_code">string _getCss()</span><br>
+ renvoie les styles CSS sous la forme d'une chaîne
+ à l'attention de la méthode d'entêtes d'une page.
+ Des styles additionnels peuvent être ajoutés ici
+ si vous ne surchargez pas les entêtes de la page.
+ Vous ne voudrez pas utiliser cette méthode dans
+ des entêtes d'une page surchargée si vous souhaitez
+ inclure le feuille de style CSS d'origine.
+ </li>
+ </ul>
+ Il y a aussi des accesseurs pour aller chercher l'information
+ sur l'état courant de la suite de test. Vous les utiliserez
+ pour enrichir l'affichage...
+ <ul class="api">
+ <li>
+ <span class="new_code">array getTestList()</span><br>
+ est la première méthode très commode pour les sous-classes.
+ Elle liste l'arborescence courante des tests
+ sous la forme d'une liste de noms de tests.
+ Le premier test -- celui le plus proche du coeur --
+ sera le premier dans la liste et la méthode de test
+ en cours sera la dernière.
+ </li>
+ <li>
+ <span class="new_code">integer getPassCount()</span><br>
+ renvoie le nombre de succès atteint. Il est nécessaire
+ pour l'affichage à la fin.
+ </li>
+ <li>
+ <span class="new_code">integer getFailCount()</span><br>
+ renvoie de la même manière le nombre d'échecs.
+ </li>
+ <li>
+ <span class="new_code">integer getExceptionCount()</span><br>
+ renvoie quant à lui le nombre d'erreurs.
+ </li>
+ <li>
+ <span class="new_code">integer getTestCaseCount()</span><br>
+ est le nombre total de scénarios lors de l'exécution des tests.
+ Il comprend aussi les tests groupés.
+ </li>
+ <li>
+ <span class="new_code">integer getTestCaseProgress()</span><br>
+ est le nombre de scénarios réalisés jusqu'à présent.
+ </li>
+ </ul>
+ Une modification simple : demander à l'HtmlReporter d'afficher
+ aussi bien les succès que les échecs et les erreurs...
+<pre><strong>
+class ShowPasses extends HtmlReporter {
+
+ function paintPass($message) {
+ parent::paintPass($message);
+ print "&amp;&lt;span class=\"pass\"&gt;Pass&lt;/span&gt;: ";
+ $breadcrumb = $this-&gt;getTestList();
+ array_shift($breadcrumb);
+ print implode("-&amp;gt;", $breadcrumb);
+ print "-&amp;gt;$message&lt;br /&gt;\n";
+ }
+
+ function _getCss() {
+ return parent::_getCss() . ' .pass { color: green; }';
+ }
+}</strong>
+</pre>
+ </p>
+ <p>
+ Une méthode qui a beaucoup fait jaser reste la méthode <span class="new_code">makeDry()</span>.
+ Si vous lancez cette méthode, sans paramètre,
+ sur le rapporteur avant que la suite de test
+ ne soit exécutée alors aucune méthode de test
+ ne sera appelée. Vous continuerez à avoir
+ les évènements entrants et sortants des méthodes
+ et scénarios de test, mais aucun succès ni échec ou erreur,
+ parce que le code de test ne sera pas exécuté.
+ </p>
+ <p>
+ La raison ? Pour permettre un affichage complexe
+ d'une IHM (ou GUI) qui permettrait la sélection
+ de scénarios de test individuels.
+ Afin de construire une liste de tests possibles,
+ ils ont besoin d'un rapport sur la structure du test
+ pour l'affichage, par exemple, d'une vue en arbre
+ de la suite de test. Avec un rapporteur lancé
+ sur une exécution sèche qui ne renverrait
+ que les évènements d'affichage, cela devient
+ facilement réalisable.
+ </p>
+
+ <p><a class="target" name="autre"><h2>Etendre le rapporteur</h2></a></p>
+ <p>
+ Plutôt que de modifier l'affichage existant,
+ vous voudrez peut-être produire une présentation HTML
+ complètement différente, ou même générer une version texte ou XML.
+ Plutôt que de surcharger chaque méthode dans
+ <span class="new_code">HtmlReporter</span> nous pouvons nous rendre
+ une étape plus haut dans la hiérarchie de classe vers
+ <span class="new_code">SimpleReporter</span> dans le fichier source <em>simple_test.php</em>.
+ </p>
+ <p>
+ Un affichage sans rien, un canevas vierge
+ pour votre propre création, serait...
+<pre><strong>
+require_once('simpletest/simple_test.php');</strong>
+
+class MyDisplay extends SimpleReporter {<strong>
+ </strong>
+ function paintHeader($test_name) {
+ }
+
+ function paintFooter($test_name) {
+ }
+
+ function paintStart($test_name, $size) {<strong>
+ parent::paintStart($test_name, $size);</strong>
+ }
+
+ function paintEnd($test_name, $size) {<strong>
+ parent::paintEnd($test_name, $size);</strong>
+ }
+
+ function paintPass($message) {<strong>
+ parent::paintPass($message);</strong>
+ }
+
+ function paintFail($message) {<strong>
+ parent::paintFail($message);</strong>
+ }
+}
+</pre>
+ Aucune sortie ne viendrait de cette classe jusqu'à un ajout de votre part.
+ </p>
+
+ <p><a class="target" name="cli"><h2>Le rapporteur en ligne de commande</h2></a></p>
+ <p>
+ SimpleTest est aussi livré avec un rapporteur
+ en ligne de commande, minime lui aussi.
+ L'interface imite celle de JUnit,
+ sauf qu'elle envoie les messages d'erreur au fur
+ et à mesure de leur arrivée.
+ Pour utiliser le rapporteur en ligne de commande,
+ il suffit de l'intervertir avec celui de la version HTML...
+<pre>
+&lt;?php
+require_once('simpletest/unit_tester.php');
+require_once('simpletest/reporter.php');
+
+$test = &amp;new GroupTest('File test');
+$test-&gt;addTestFile('tests/file_test.php');
+$test-&gt;run(<strong>new TextReporter()</strong>);
+?&gt;
+</pre>
+ Et ensuite d'invoquer la suite de test à partir d'une ligne de commande...
+<pre class="shell">
+php file_test.php
+</pre>
+ Bien sûr vous aurez besoin d'installer PHP
+ en ligne de commande. Une suite de test qui
+ passerait toutes ses assertions ressemble à...
+<pre class="shell">
+File test
+OK
+Test cases run: 1/1, Failures: 0, Exceptions: 0
+</pre>
+ Un échec déclenche un affichage comme...
+<pre class="shell">
+File test
+1) True assertion failed.
+ in createnewfile
+FAILURES!!!
+Test cases run: 1/1, Failures: 1, Exceptions: 0
+</pre>
+ </p>
+ <p>
+ Une des principales raisons pour utiliser
+ une suite de test en ligne de commande tient
+ dans l'utilisation possible du testeur avec
+ un processus automatisé. Pour fonctionner comme
+ il faut dans des scripts shell le script de test
+ devrait renvoyer un code de sortie non-nul suite à un échec.
+ Si une suite de test échoue la valeur <span class="new_code">false</span>
+ est renvoyée par la méthode <span class="new_code">SimpleTest::run()</span>.
+ Nous pouvons utiliser ce résultat pour terminer le script
+ avec la bonne valeur renvoyée...
+<pre>
+&lt;?php
+require_once('simpletest/unit_tester.php');
+require_once('simpletest/reporter.php');
+
+$test = &amp;new GroupTest('File test');
+$test-&gt;addTestFile('tests/file_test.php');<strong>
+exit ($test-&gt;run(new TextReporter()) ? 0 : 1);</strong>
+?&gt;
+</pre>
+ Bien sûr l'objectif n'est pas de créer deux scripts de test,
+ l'un en ligne de commande et l'autre pour un navigateur web,
+ pour chaque suite de test.
+ Le rapporteur en ligne de commande inclut
+ une méthode pour déterminer l'environnement d'exécution...
+<pre>
+&lt;?php
+require_once('simpletest/unit_tester.php');
+require_once('simpletest/reporter.php');
+
+$test = &amp;new GroupTest('File test');
+$test-&gt;addTestFile('tests/file_test.php');<strong>
+if (TextReporter::inCli()) {</strong>
+ exit ($test-&gt;run(new TextReporter()) ? 0 : 1);<strong>
+}</strong>
+$test-&gt;run(new HtmlReporter());
+?&gt;
+</pre>
+ Il s'agit là de la forme utilisée par SimpleTest lui-même.
+ </p>
+
+ <p><a class="target" name="xml"><h2>Test distant</h2></a></p>
+ <p>
+ SimpleTest est livré avec une classe <span class="new_code">XmlReporter</span>
+ utilisée pour de la communication interne.
+ Lors de son exécution, le résultat ressemble à...
+<pre class="shell">
+&lt;?xml version="1.0"?&gt;
+&lt;run&gt;
+ &lt;group size="4"&gt;
+ &lt;name&gt;Remote tests&lt;/name&gt;
+ &lt;group size="4"&gt;
+ &lt;name&gt;Visual test with 48 passes, 48 fails and 4 exceptions&lt;/name&gt;
+ &lt;case&gt;
+ &lt;name&gt;testofunittestcaseoutput&lt;/name&gt;
+ &lt;test&gt;
+ &lt;name&gt;testofresults&lt;/name&gt;
+ &lt;pass&gt;This assertion passed&lt;/pass&gt;
+ &lt;fail&gt;This assertion failed&lt;/fail&gt;
+ &lt;/test&gt;
+ &lt;test&gt;
+ ...
+ &lt;/test&gt;
+ &lt;/case&gt;
+ &lt;/group&gt;
+ &lt;/group&gt;
+&lt;/run&gt;
+</pre>
+ Vous pouvez utiliser ce format avec le parseur
+ fourni dans SimpleTest lui-même.
+ Il s'agit de <span class="new_code">SimpleTestXmlParser</span>
+ et se trouve <em>xml.php</em> à l'intérieur du paquet SimpleTest...
+<pre>
+&lt;?php
+require_once('simpletest/xml.php');
+
+...
+$parser = &amp;new SimpleTestXmlParser(new HtmlReporter());
+$parser-&gt;parse($test_output);
+?&gt;
+</pre>
+ <span class="new_code">$test_output</span> devrait être au format XML,
+ à partir du rapporteur XML, et pourrait venir
+ d'une exécution en ligne de commande d'un scénario de test.
+ Le parseur envoie des évènements au rapporteur exactement
+ comme tout autre exécution de test.
+ Il y a des occasions bizarres dans lesquelles c'est en fait très utile.
+ </p>
+ <p>
+ Un problème des très grandes suites de test,
+ c'est qu'elles peuvent venir à bout de la limite de mémoire
+ par défaut d'un process PHP - 8Mb.
+ En plaçant la sortie des groupes de test dans du XML
+ et leur exécution dans des process différents,
+ le résultat peut être parsé à nouveau pour agréger
+ les résultats avec moins d'impact sur le test au premier niveau.
+ </p>
+ <p>
+ Parce que la sortie XML peut venir de n'importe où,
+ ça ouvre des possibilités d'agrégation d'exécutions de test
+ depuis des serveur distants.
+ Un scénario de test pour le réaliser existe déjà
+ à l'intérieur du framework SimpleTest, mais il est encore expérimental...
+<pre>
+&lt;?php<strong>
+require_once('../remote.php');</strong>
+require_once('../reporter.php');
+
+$test_url = ...;
+$dry_url = ...;
+
+$test = &amp;new GroupTest('Remote tests');
+$test-&gt;addTestCase(<strong>new RemoteTestCase($test_url, $dry_url)</strong>);
+$test-&gt;run(new HtmlReporter());
+?&gt;
+</pre>
+ <span class="new_code">RemoteTestCase</span> prend la localisation réelle
+ du lanceur de test, tout simplement un page web au format XML.
+ Il prend aussi l'URL d'un rapporteur initié
+ pour effectuer une exécution sèche.
+ Cette technique est employée pour que les progrès
+ soient correctement rapportés vers le haut.
+ <span class="new_code">RemoteTestCase</span> peut être ajouté à
+ une suite de test comme n'importe quel autre groupe de tests.
+ </p>
+
+ </div>
+ References and related information...
+ <ul>
+<li>
+ La page du projet SimpleTest sur
+ <a href="http://sourceforge.net/projects/simpletest/">SourceForge</a>.
+ </li>
+<li>
+ La page de téléchargement de SimpleTest sur
+ <a href="http://www.lastcraft.com/simple_test.php">LastCraft</a>.
+ </li>
+<li>
+ L'<a href="http://simpletest.org/api/">API pour développeur de SimpleTest</a>
+ donne tous les détails sur les classes et les assertions disponibles.
+ </li>
+</ul>
+<div class="menu_back"><div class="menu">
+<a href="index.html">SimpleTest</a>
+ |
+ <a href="overview.html">Overview</a>
+ |
+ <a href="unit_test_documentation.html">Unit tester</a>
+ |
+ <a href="group_test_documentation.html">Group tests</a>
+ |
+ <a href="mock_objects_documentation.html">Mock objects</a>
+ |
+ <a href="partial_mocks_documentation.html">Partial mocks</a>
+ |
+ <a href="reporter_documentation.html">Reporting</a>
+ |
+ <a href="expectation_documentation.html">Expectations</a>
+ |
+ <a href="web_tester_documentation.html">Web tester</a>
+ |
+ <a href="form_testing_documentation.html">Testing forms</a>
+ |
+ <a href="authentication_documentation.html">Authentication</a>
+ |
+ <a href="browser_documentation.html">Scriptable browser</a>
+</div></div>
+<div class="copyright">
+ Copyright<br>Marcus Baker 2006
+ </div>
+</body>
+</html>
diff --git a/site/vendors/simpletest/docs/fr/server_stubs_documentation.html b/site/vendors/simpletest/docs/fr/server_stubs_documentation.html
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/site/vendors/simpletest/docs/fr/server_stubs_documentation.html
diff --git a/site/vendors/simpletest/docs/fr/unit_test_documentation.html b/site/vendors/simpletest/docs/fr/unit_test_documentation.html
new file mode 100644
index 0000000..ff54753
--- /dev/null
+++ b/site/vendors/simpletest/docs/fr/unit_test_documentation.html
@@ -0,0 +1,447 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Documentation SimpleTest pour les tests de régression en PHP</title>
+<link rel="stylesheet" type="text/css" href="docs.css" title="Styles">
+</head>
+<body>
+<div class="menu_back"><div class="menu">
+<a href="index.html">SimpleTest</a>
+ |
+ <a href="overview.html">Overview</a>
+ |
+ <a href="unit_test_documentation.html">Unit tester</a>
+ |
+ <a href="group_test_documentation.html">Group tests</a>
+ |
+ <a href="mock_objects_documentation.html">Mock objects</a>
+ |
+ <a href="partial_mocks_documentation.html">Partial mocks</a>
+ |
+ <a href="reporter_documentation.html">Reporting</a>
+ |
+ <a href="expectation_documentation.html">Expectations</a>
+ |
+ <a href="web_tester_documentation.html">Web tester</a>
+ |
+ <a href="form_testing_documentation.html">Testing forms</a>
+ |
+ <a href="authentication_documentation.html">Authentication</a>
+ |
+ <a href="browser_documentation.html">Scriptable browser</a>
+</div></div>
+<h1>Documentation sur les tests unitaires en PHP</h1>
+ This page...
+ <ul>
+<li>
+ <a href="#unitaire">Scénarios de test unitaire</a>
+ et opérations basiques.
+ </li>
+<li>
+ <a href="#extension_unitaire">Étendre des scénarios de test</a>
+ pour les personnaliser à votre propre projet.
+ </li>
+<li>
+ <a href="#lancement_unitaire">Lancer un scénario seul</a>
+ comme un script unique.
+ </li>
+</ul>
+<div class="content">
+ <p><a class="target" name="unitaire"><h2>Scénarios de tests unitaires</h2></a></p>
+ <p>
+ Le coeur du système est un framework de tests de régression
+ construit autour des scénarios de test.
+ Un exemple de scénario de test ressemble à...
+<pre>
+<strong>class FileTestCase extends UnitTestCase {
+}</strong>
+</pre>
+ Si aucun nom de test n'est fourni au moment
+ de la liaison avec le constructeur alors
+ le nom de la classe sera utilisé.
+ Il s'agit du nom qui sera affiché dans les résultats du test.
+ </p>
+ <p>
+ Les véritables tests sont ajoutés en tant que méthode
+ dans le scénario de test dont le nom par défaut
+ commence par la chaîne "test"
+ et quand le scénario de test est appelé toutes les méthodes
+ de ce type sont exécutées dans l'ordre utilisé
+ par l'introspection de PHP pour les trouver.
+ Peuvent être ajoutées autant de méthodes de test que nécessaires.
+ Par exemple...
+<pre>
+require_once('simpletest/autorun.php');
+require_once('../classes/writer.php');
+
+class FileTestCase extends UnitTestCase {
+ function FileTestCase() {
+ $this-&gt;UnitTestCase('File test');
+ }<strong>
+
+ function setUp() {
+ @unlink('../temp/test.txt');
+ }
+
+ function tearDown() {
+ @unlink('../temp/test.txt');
+ }
+
+ function testCreation() {
+ $writer = &amp;new FileWriter('../temp/test.txt');
+ $writer-&gt;write('Hello');
+ $this-&gt;assertTrue(file_exists('../temp/test.txt'), 'File created');
+ }</strong>
+}
+</pre>
+ Le constructeur est optionnel et souvent omis. Sans nom,
+ le nom de la classe est utilisé comme nom pour le scénario de test.
+ </p>
+ <p>
+ Notre unique méthode de test pour le moment est
+ <span class="new_code">testCreation()</span> où nous vérifions
+ qu'un fichier a bien été créé par notre objet
+ <span class="new_code">Writer</span>. Nous pourrions avoir mis
+ le code <span class="new_code">unlink()</span> dans cette méthode,
+ mais en la plaçant dans <span class="new_code">setUp()</span>
+ et <span class="new_code">tearDown()</span> nous pouvons l'utiliser
+ pour nos autres méthodes de test que nous ajouterons.
+ </p>
+ <p>
+ La méthode <span class="new_code">setUp()</span> est lancé
+ juste avant chaque méthode de test.
+ <span class="new_code">tearDown()</span> est lancé après chaque méthode de test.
+ </p>
+ <p>
+ Vous pouvez placer une initialisation de
+ scénario de test dans le constructeur afin qu'elle soit lancée
+ pour toutes les méthodes dans le scénario de test
+ mais dans un tel cas vous vous exposeriez à des interférences.
+ Cette façon de faire est légèrement moins rapide,
+ mais elle est plus sûre.
+ Notez que si vous arrivez avec des notions de JUnit,
+ il ne s'agit pas du comportement auquel vous êtes habitués.
+ Bizarrement JUnit re-instancie le scénario de test
+ pour chaque méthode de test pour se prévenir
+ d'une telle interférence.
+ SimpleTest demande à l'utilisateur final d'utiliser
+ <span class="new_code">setUp()</span>, mais fournit aux codeurs de bibliothèque d'autres crochets.
+ </p>
+ <p>
+ Pour rapporter les résultats de test,
+ le passage par une classe d'affichage - notifiée par
+ les différentes méthodes de type <span class="new_code">assert...()</span> -
+ est utilisée. En voici la liste complète pour
+ la classe <span class="new_code">UnitTestCase</span>,
+ celle par défaut dans SimpleTest...
+ <table><tbody>
+ <tr>
+<td><span class="new_code">assertTrue($x)</span></td>
+<td>Echoue si $x est faux</td>
+</tr>
+ <tr>
+<td><span class="new_code">assertFalse($x)</span></td>
+<td>Echoue si $x est vrai</td>
+</tr>
+ <tr>
+<td><span class="new_code">assertNull($x)</span></td>
+<td>Echoue si $x est initialisé</td>
+</tr>
+ <tr>
+<td><span class="new_code">assertNotNull($x)</span></td>
+<td>Echoue si $x n'est pas initialisé</td>
+</tr>
+ <tr>
+<td><span class="new_code">assertIsA($x, $t)</span></td>
+<td>Echoue si $x n'est pas de la classe ou du type $t</td>
+</tr>
+ <tr>
+<td><span class="new_code">assertEqual($x, $y)</span></td>
+<td>Echoue si $x == $y est faux</td>
+</tr>
+ <tr>
+<td><span class="new_code">assertNotEqual($x, $y)</span></td>
+<td>Echoue si $x == $y est vrai</td>
+</tr>
+ <tr>
+<td><span class="new_code">assertIdentical($x, $y)</span></td>
+<td>Echoue si $x === $y est faux</td>
+</tr>
+ <tr>
+<td><span class="new_code">assertNotIdentical($x, $y)</span></td>
+<td>Echoue si $x === $y est vrai</td>
+</tr>
+ <tr>
+<td><span class="new_code">assertReference($x, $y)</span></td>
+<td>Echoue sauf si $x et $y sont la même variable</td>
+</tr>
+ <tr>
+<td><span class="new_code">assertCopy($x, $y)</span></td>
+<td>Echoue si $x et $y sont la même variable</td>
+</tr>
+ <tr>
+<td><span class="new_code">assertWantedPattern($p, $x)</span></td>
+<td>Echoue sauf si l'expression rationnelle $p capture $x</td>
+</tr>
+ <tr>
+<td><span class="new_code">assertNoUnwantedPattern($p, $x)</span></td>
+<td>Echoue si l'expression rationnelle $p capture $x</td>
+</tr>
+ <tr>
+<td><span class="new_code">assertNoErrors()</span></td>
+<td>Echoue si une erreur PHP arrive</td>
+</tr>
+ <tr>
+<td><span class="new_code">assertError($x)</span></td>
+<td>Echoue si aucune erreur ou message incorrect de PHP n'arrive</td>
+</tr>
+ </tbody></table>
+ Toutes les méthodes d'assertion peuvent recevoir
+ une description optionnelle :
+ cette description sert pour étiqueter le résultat.
+ Sans elle, une message par défaut est envoyée à la place :
+ il est généralement suffisant.
+ Ce message par défaut peut encore être encadré
+ dans votre propre message si vous incluez "%s"
+ dans la chaîne.
+ Toutes les assertions renvoient vrai / true en cas de succès
+ et faux / false en cas d'échec.
+ </p>
+ <p>
+ D'autres exemples...
+<pre>
+<strong>$variable = null;
+$this-&gt;assertNull($variable, 'Should be cleared');</strong>
+</pre>
+ ...passera et normalement n'affichera aucun message.
+ Si vous avez <a href="http://www.lastcraft.com/display_subclass_tutorial.php">
+ configuré le testeur pour afficher aussi les succès</a>
+ alors le message sera affiché comme tel.
+<pre>
+<strong>$this-&gt;assertIdentical(0, false, 'Zero is not false [%s]');</strong>
+</pre>
+ Ceci échouera étant donné qu'il effectue une vérification
+ sur le type en plus d'une comparaison sur les deux valeurs.
+ La partie "%s" est remplacée par le message d'erreur
+ par défaut qui aurait été affiché si nous n'avions pas fourni le nôtre.
+ Cela nous permet d'emboîter les messages de test.
+<pre>
+<strong>$a = 1;
+$b = $a;
+$this-&gt;assertReference($a, $b);</strong>
+</pre>
+ Échouera étant donné que la variable <span class="new_code">$b</span>
+ est une copie de <span class="new_code">$a</span>.
+<pre>
+<strong>$this-&gt;assertWantedPattern('/hello/i', 'Hello world');</strong>
+</pre>
+ Là, ça passe puisque la recherche est insensible
+ à la casse et que donc <span class="new_code">hello</span>
+ est bien repérable dans <span class="new_code">Hello world</span>.
+<pre>
+<strong>trigger_error('Disaster');
+trigger_error('Catastrophe');
+$this-&gt;assertError();
+$this-&gt;assertError('Catastrophe');
+$this-&gt;assertNoErrors();</strong>
+</pre>
+ Ici, il y a besoin d'une petite explication :
+ toutes passent !
+ </p>
+ <p>
+ Les erreurs PHP dans SimpleTest sont piégées et
+ placées dans une queue. Ici la première vérification
+ d'erreur attrape le message "Disaster"
+ sans vérifier le texte et passe. Résultat :
+ l'erreur est supprimée de la queue.
+ La vérification suivante teste non seulement l'existence
+ de l'erreur mais aussi le texte qui correspond :
+ un autre succès. Désormais la queue est vide
+ et le dernier test passe aussi.
+ Si une autre erreur non vérifiée est encore
+ dans la queue à la fin de notre méthode de test
+ alors une exception sera rapportée dans le test.
+ Notez que SimpleTest ne peut pas attraper les erreurs PHP à la compilation.
+ </p>
+ <p>
+ Les scénarios de test peuvent utiliser des méthodes
+ bien pratiques pour déboguer le code ou pour étendre la suite...
+ <table><tbody>
+ <tr>
+<td><span class="new_code">setUp()</span></td>
+<td>Est lancée avant chaque méthode de test</td>
+</tr>
+ <tr>
+<td><span class="new_code">tearDown()</span></td>
+<td>Est lancée après chaque méthode de test</td>
+</tr>
+ <tr>
+<td><span class="new_code">pass()</span></td>
+<td>Envoie un succès</td>
+</tr>
+ <tr>
+<td><span class="new_code">fail()</span></td>
+<td>Envoie un échec</td>
+</tr>
+ <tr>
+<td><span class="new_code">error()</span></td>
+<td>Envoi un évènement exception</td>
+</tr>
+ <tr>
+<td><span class="new_code">sendMessage()</span></td>
+<td>Envoie un message d'état aux systèmes d'affichage qui le supporte</td>
+</tr>
+ <tr>
+<td><span class="new_code">signal($type, $payload)</span></td>
+<td>Envoie un message défini par l'utilisateur au rapporteur du test</td>
+</tr>
+ <tr>
+<td><span class="new_code">dump($var)</span></td>
+<td>Effectue un <span class="new_code">print_r()</span> formaté pour du déboguage rapide et grossier</td>
+</tr>
+ <tr>
+<td><span class="new_code">swallowErrors()</span></td>
+<td>Vide les erreurs de la queue</td>
+</tr>
+ </tbody></table>
+ </p>
+
+ <p><a class="target" name="extension_unitaire"><h2>Etendre les scénarios de test</h2></a></p>
+ <p>
+ Bien sûr des méthodes supplémentaires de test
+ peuvent être ajoutées pour créer d'autres types
+ de scénario de test afin d'étendre le framework...
+<pre>
+require_once('simpletest/autorun.php');
+<strong>
+class FileTester extends UnitTestCase {
+ function FileTester($name = false) {
+ $this-&gt;UnitTestCase($name);
+ }
+
+ function assertFileExists($filename, $message = '%s') {
+ $this-&gt;assertTrue(
+ file_exists($filename),
+ sprintf($message, 'File [$filename] existence check'));
+ }</strong>
+}
+</pre>
+ Ici la bibliothèque SimpleTest est localisée
+ dans un répertoire local appelé <em>simpletest</em>.
+ Pensez à le modifier pour votre propre environnement.
+ </p>
+ <p>
+ Alternativement vous pourriez utiliser dans votre code
+ un directive <span class="new_code">SimpleTestOptions::ignore('FileTester');</span>.
+ </p>
+ <p>
+ Ce nouveau scénario peut être hérité exactement
+ comme un scénario de test classique...
+<pre>
+class FileTestCase extends <strong>FileTester</strong> {
+
+ function setUp() {
+ @unlink('../temp/test.txt');
+ }
+
+ function tearDown() {
+ @unlink('../temp/test.txt');
+ }
+
+ function testCreation() {
+ $writer = &amp;new FileWriter('../temp/test.txt');
+ $writer-&gt;write('Hello');<strong>
+ $this-&gt;assertFileExists('../temp/test.txt');</strong>
+ }
+}
+</pre>
+ </p>
+ <p>
+ Si vous souhaitez un scénario de test sans
+ toutes les assertions de <span class="new_code">UnitTestCase</span>
+ mais uniquement avec les vôtres propres,
+ vous aurez besoin d'étendre la classe
+ <span class="new_code">SimpleTestCase</span> à la place.
+ Elle se trouve dans <em>simple_test.php</em>
+ en lieu et place de <em>unit_tester.php</em>.
+ A consulter <a href="group_test_documentation.html">plus tard</a>
+ si vous souhaitez incorporer les scénarios
+ d'autres testeurs unitaires dans votre suite de test.
+ </p>
+
+ <p><a class="target" name="lancement_unitaire"><h2>Lancer un unique scénario de test</h2></a></p>
+ <p>
+ Ce n'est pas souvent qu'il faille lancer des scénarios
+ avec un unique test. Sauf lorsqu'il s'agit de s'arracher
+ les cheveux sur un module à problème sans pour
+ autant désorganiser la suite de test principale.
+ Avec <em>autorun</em> aucun échafaudage particulier
+ n'est nécessaire, il suffit de lancer votre test et
+ vous y êtes.
+ </p>
+ <p>
+ Vous pouvez même décider quel rapporteur
+ (par exemple, <span class="new_code">TextReporter</span> ou <span class="new_code">HtmlReporter</span>)
+ vous préférez pour un fichier spécifique quand il est lancé
+ tout seul...
+<pre>
+&lt;?php
+require_once('simpletest/autorun.php');<strong>
+SimpleTest :: prefer(new TextReporter());</strong>
+require_once('../classes/writer.php');
+
+class FileTestCase extends UnitTestCase {
+ ...
+}
+?&gt;
+</pre>
+ Ce script sera lancé tel que mais il n'y aura
+ aucun succès ou échec avant que des méthodes de test soient ajoutées.
+ </p>
+
+ </div>
+ References and related information...
+ <ul>
+<li>
+ La page de SimpleTest sur
+ <a href="http://sourceforge.net/projects/simpletest/">SourceForge</a>.
+ </li>
+<li>
+ La page de téléchargement de SimpleTest sur
+ <a href="http://www.lastcraft.com/simple_test.php">LastCraft</a>.
+ </li>
+<li>
+ <a href="http://simpletest.org/api/">L'API complète de SimpleTest</a>
+ à partir de PHPDoc.
+ </li>
+</ul>
+<div class="menu_back"><div class="menu">
+<a href="index.html">SimpleTest</a>
+ |
+ <a href="overview.html">Overview</a>
+ |
+ <a href="unit_test_documentation.html">Unit tester</a>
+ |
+ <a href="group_test_documentation.html">Group tests</a>
+ |
+ <a href="mock_objects_documentation.html">Mock objects</a>
+ |
+ <a href="partial_mocks_documentation.html">Partial mocks</a>
+ |
+ <a href="reporter_documentation.html">Reporting</a>
+ |
+ <a href="expectation_documentation.html">Expectations</a>
+ |
+ <a href="web_tester_documentation.html">Web tester</a>
+ |
+ <a href="form_testing_documentation.html">Testing forms</a>
+ |
+ <a href="authentication_documentation.html">Authentication</a>
+ |
+ <a href="browser_documentation.html">Scriptable browser</a>
+</div></div>
+<div class="copyright">
+ Copyright<br>Marcus Baker 2006
+ </div>
+</body>
+</html>
diff --git a/site/vendors/simpletest/docs/fr/web_tester_documentation.html b/site/vendors/simpletest/docs/fr/web_tester_documentation.html
new file mode 100644
index 0000000..5bb5a9e
--- /dev/null
+++ b/site/vendors/simpletest/docs/fr/web_tester_documentation.html
@@ -0,0 +1,566 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Documentation SimpleTest : tester des scripts web</title>
+<link rel="stylesheet" type="text/css" href="docs.css" title="Styles">
+</head>
+<body>
+<div class="menu_back"><div class="menu">
+<a href="index.html">SimpleTest</a>
+ |
+ <a href="overview.html">Overview</a>
+ |
+ <a href="unit_test_documentation.html">Unit tester</a>
+ |
+ <a href="group_test_documentation.html">Group tests</a>
+ |
+ <a href="mock_objects_documentation.html">Mock objects</a>
+ |
+ <a href="partial_mocks_documentation.html">Partial mocks</a>
+ |
+ <a href="reporter_documentation.html">Reporting</a>
+ |
+ <a href="expectation_documentation.html">Expectations</a>
+ |
+ <a href="web_tester_documentation.html">Web tester</a>
+ |
+ <a href="form_testing_documentation.html">Testing forms</a>
+ |
+ <a href="authentication_documentation.html">Authentication</a>
+ |
+ <a href="browser_documentation.html">Scriptable browser</a>
+</div></div>
+<h1>Documentation sur le testeur web</h1>
+ This page...
+ <ul>
+<li>
+ Réussir à <a href="#telecharger">télécharger une page web</a>
+ </li>
+<li>
+ Tester le <a href="#contenu">contenu de la page</a>
+ </li>
+<li>
+ <a href="#navigation">Naviguer sur un site web</a> pendant le test
+ </li>
+<li>
+ Méthodes pour <a href="#requete">modifier une requête</a> et pour déboguer
+ </li>
+</ul>
+<div class="content">
+ <p><a class="target" name="telecharger"><h2>Télécharger une page</h2></a></p>
+ <p>
+ Tester des classes c'est très bien.
+ Reste que PHP est avant tout un langage
+ pour créer des fonctionnalités à l'intérieur de pages web.
+ Comment pouvons tester la partie de devant
+ -- celle de l'interface -- dans nos applications en PHP ?
+ Etant donné qu'une page web n'est constituée que de texte,
+ nous devrions pouvoir les examiner exactement
+ comme n'importe quelle autre donnée de test.
+ </p>
+ <p>
+ Cela nous amène à une situation délicate.
+ Si nous testons dans un niveau trop bas,
+ vérifier des balises avec un motif ad hoc par exemple,
+ nos tests seront trop fragiles. Le moindre changement
+ dans la présentation pourrait casser un grand nombre de test.
+ Si nos tests sont situés trop haut, en utilisant
+ une version fantaisie du moteur de template pour
+ donner un cas précis, alors nous perdons complètement
+ la capacité à automatiser certaines classes de test.
+ Par exemple, l'interaction entre des formulaires
+ et la navigation devra être testé manuellement.
+ Ces types de test sont extrêmement fastidieux
+ et plutôt sensibles aux erreurs.
+ </p>
+ <p>
+ SimpleTest comprend une forme spéciale de scénario
+ de test pour tester les actions d'une page web.
+ <span class="new_code">WebTestCase</span> inclut des facilités pour la navigation,
+ des vérifications sur le contenu
+ et les cookies ainsi que la gestion des formulaires.
+ Utiliser ces scénarios de test ressemble
+ fortement à <span class="new_code">UnitTestCase</span>...
+<pre>
+<strong>class TestOfLastcraft extends WebTestCase {
+}</strong>
+</pre>
+ Ici nous sommes sur le point de tester
+ le site de <a href="http://www.lastcraft.com/">Last Craft</a>.
+ Si ce scénario de test est situé dans un fichier appelé
+ <em>lastcraft_test.php</em> alors il peut être chargé
+ dans un script de lancement tout comme des tests unitaires...
+<pre>
+&lt;?php
+require_once('simpletest/autorun.php');<strong>
+require_once('simpletest/web_tester.php');</strong>
+SimpleTest::prefer(new TextReporter());
+
+class WebTests extends TestSuite {
+ function WebTests() {
+ $this-&gt;TestSuite('Web site tests');<strong>
+ $this-&gt;addFile('lastcraft_test.php');</strong>
+ }
+}
+?&gt;
+</pre>
+ J'utilise ici le rapporteur en mode texte
+ pour mieux distinguer le contenu au format HTML
+ du résultat du test proprement dit.
+ </p>
+ <p>
+ Rien n'est encore testé. Nous pouvons télécharger
+ la page d'accueil en utilisant la méthode <span class="new_code">get()</span>...
+<pre>
+class TestOfLastcraft extends WebTestCase {
+ <strong>
+ function testHomepage() {
+ $this-&gt;assertTrue($this-&gt;get('http://www.lastcraft.com/'));
+ }</strong>
+}
+</pre>
+ La méthode <span class="new_code">get()</span> renverra "true"
+ uniquement si le contenu de la page a bien été téléchargé.
+ C'est un moyen simple, mais efficace pour vérifier
+ qu'une page web a bien été délivré par le serveur web.
+ Cependant le contenu peut révéler être une erreur 404
+ et dans ce cas notre méthode <span class="new_code">get()</span> renverrait encore un succès.
+ </p>
+ <p>
+ En supposant que le serveur web pour le site Last Craft
+ soit opérationnel (malheureusement ce n'est pas toujours le cas),
+ nous devrions voir...
+<pre class="shell">
+Web site tests
+OK
+Test cases run: 1/1, Failures: 0, Exceptions: 0
+</pre>
+ Nous avons vérifié qu'une page, de n'importe quel type,
+ a bien été renvoyée. Nous ne savons pas encore
+ s'il s'agit de celle que nous souhaitions.
+ </p>
+
+ <p><a class="target" name="contenu"><h2>Tester le contenu d'une page</h2></a></p>
+ <p>
+ Pour obtenir la confirmation que la page téléchargée
+ est bien celle que nous attendions,
+ nous devons vérifier son contenu.
+<pre>
+class TestOfLastcraft extends WebTestCase {
+
+ function testHomepage() {<strong>
+ $this-&gt;get('http://www.lastcraft.com/');
+ $this-&gt;assertWantedPattern('/why the last craft/i');</strong>
+ }
+}
+</pre>
+ La page obtenue par le dernier téléchargement est
+ placée dans un buffer au sein même du scénario de test.
+ Il n'est donc pas nécessaire de s'y référer directement.
+ La correspondance du motif est toujours effectuée
+ par rapport à ce buffer.
+ </p>
+ <p>
+ Voici une liste possible d'assertions sur le contenu...
+ <table><tbody>
+ <tr>
+<td><span class="new_code">assertWantedPattern($pattern)</span></td>
+<td>Vérifier une correspondance sur le contenu via une expression rationnelle Perl</td>
+</tr>
+ <tr>
+<td><span class="new_code">assertNoUnwantedPattern($pattern)</span></td>
+<td>Une expression rationnelle Perl pour vérifier une absence</td>
+</tr>
+ <tr>
+<td><span class="new_code">assertTitle($title)</span></td>
+<td>Passe si le titre de la page correspond exactement</td>
+</tr>
+ <tr>
+<td><span class="new_code">assertLink($label)</span></td>
+<td>Passe si un lien avec ce texte est présent</td>
+</tr>
+ <tr>
+<td><span class="new_code">assertNoLink($label)</span></td>
+<td>Passe si aucun lien avec ce texte est présent</td>
+</tr>
+ <tr>
+<td><span class="new_code">assertLinkById($id)</span></td>
+<td>Passe si un lien avec cet attribut d'identification est présent</td>
+</tr>
+ <tr>
+<td><span class="new_code">assertField($name, $value)</span></td>
+<td>Passe si une balise input avec ce nom contient cette valeur</td>
+</tr>
+ <tr>
+<td><span class="new_code">assertFieldById($id, $value)</span></td>
+<td>Passe si une balise input avec cet identifiant contient cette valeur</td>
+</tr>
+ <tr>
+<td><span class="new_code">assertResponse($codes)</span></td>
+<td>Passe si la réponse HTTP trouve une correspondance dans la liste</td>
+</tr>
+ <tr>
+<td><span class="new_code">assertMime($types)</span></td>
+<td>Passe si le type MIME se retrouve dans cette liste</td>
+</tr>
+ <tr>
+<td><span class="new_code">assertAuthentication($protocol)</span></td>
+<td>Passe si l'authentification provoquée est de ce type de protocole</td>
+</tr>
+ <tr>
+<td><span class="new_code">assertNoAuthentication()</span></td>
+<td>Passe s'il n'y pas d'authentification provoquée en cours</td>
+</tr>
+ <tr>
+<td><span class="new_code">assertRealm($name)</span></td>
+<td>Passe si le domaine provoqué correspond</td>
+</tr>
+ <tr>
+<td><span class="new_code">assertHeader($header, $content)</span></td>
+<td>Passe si une entête téléchargée correspond à cette valeur</td>
+</tr>
+ <tr>
+<td><span class="new_code">assertNoUnwantedHeader($header)</span></td>
+<td>Passe si une entête n'a pas été téléchargé</td>
+</tr>
+ <tr>
+<td><span class="new_code">assertHeaderPattern($header, $pattern)</span></td>
+<td>Passe si une entête téléchargée correspond à cette expression rationnelle Perl</td>
+</tr>
+ <tr>
+<td><span class="new_code">assertCookie($name, $value)</span></td>
+<td>Passe s'il existe un cookie correspondant</td>
+</tr>
+ <tr>
+<td><span class="new_code">assertNoCookie($name)</span></td>
+<td>Passe s'il n'y a pas de cookie avec un tel nom</td>
+</tr>
+ </tbody></table>
+ Comme d'habitude avec les assertions de SimpleTest,
+ elles renvoient toutes "false" en cas d'échec
+ et "true" si c'est un succès.
+ Elles renvoient aussi un message de test optionnel :
+ vous pouvez l'ajouter dans votre propre message en utilisant "%s".
+ </p>
+ <p>
+ A présent nous pourrions effectué le test sur le titre uniquement...
+<pre>
+<strong>$this-&gt;assertTitle('The Last Craft?');</strong>
+</pre>
+ En plus d'une simple vérification sur le contenu HTML,
+ nous pouvons aussi vérifier que le type MIME est bien d'un type acceptable...
+<pre>
+<strong>$this-&gt;assertMime(array('text/plain', 'text/html'));</strong>
+</pre>
+ Plus intéressant encore est la vérification sur
+ le code de la réponse HTTP. Pareillement au type MIME,
+ nous pouvons nous assurer que le code renvoyé se trouve
+ bien dans un liste de valeurs possibles...
+<pre>
+class TestOfLastcraft extends WebTestCase {
+
+ function testHomepage() {
+ $this-&gt;get('http://simpletest.sourceforge.net/');<strong>
+ $this-&gt;assertResponse(200);</strong>
+ }
+}
+</pre>
+ Ici nous vérifions que le téléchargement s'est
+ bien terminé en ne permettant qu'une réponse HTTP 200.
+ Ce test passera, mais ce n'est pas la meilleure façon de procéder.
+ Il n'existe aucune page sur <em>http://simpletest.sourceforge.net/</em>,
+ à la place le serveur renverra une redirection vers
+ <em>http://www.lastcraft.com/simple_test.php</em>.
+ <span class="new_code">WebTestCase</span> suit automatiquement trois
+ de ces redirections. Les tests sont quelque peu plus
+ robustes de la sorte. Surtout qu'on est souvent plus intéressé
+ par l'interaction entre les pages que de leur simple livraison.
+ Si les redirections se révèlent être digne d'intérêt,
+ il reste possible de les supprimer...
+<pre>
+class TestOfLastcraft extends WebTestCase {
+
+ function testHomepage() {<strong>
+ $this-&gt;setMaximumRedirects(0);</strong>
+ $this-&gt;get('http://simpletest.sourceforge.net/');
+ $this-&gt;assertResponse(200);
+ }
+}
+</pre>
+ Alors l'assertion échoue comme prévue...
+<pre class="shell">
+Web site tests
+1) Expecting response in [200] got [302]
+ in testhomepage
+ in testoflastcraft
+ in lastcraft_test.php
+FAILURES!!!
+Test cases run: 1/1, Failures: 1, Exceptions: 0
+</pre>
+ Nous pouvons modifier le test pour accepter les redirections...
+<pre>
+class TestOfLastcraft extends WebTestCase {
+
+ function testHomepage() {
+ $this-&gt;setMaximumRedirects(0);
+ $this-&gt;get('http://simpletest.sourceforge.net/');
+ $this-&gt;assertResponse(<strong>array(301, 302, 303, 307)</strong>);
+ }
+}
+</pre>
+ Maitenant ça passe.
+ </p>
+
+ <p><a class="target" name="navigation"><h2>Navigeur dans un site web</h2></a></p>
+ <p>
+ Les utilisateurs ne naviguent pas souvent en tapant les URLs,
+ mais surtout en cliquant sur des liens et des boutons.
+ Ici nous confirmons que les informations sur le contact
+ peuvent être atteintes depuis la page d'accueil...
+<pre>
+class TestOfLastcraft extends WebTestCase {
+ ...
+ function testContact() {
+ $this-&gt;get('http://www.lastcraft.com/');<strong>
+ $this-&gt;clickLink('About');
+ $this-&gt;assertTitle('About Last Craft');</strong>
+ }
+}
+</pre>
+ Le paramètre est le texte du lien.
+ </p>
+ <p>
+ Il l'objectif est un bouton plutôt qu'une balise ancre,
+ alors <span class="new_code">clickSubmit()</span> doit être utilisé avec
+ le titre du bouton...
+<pre>
+<strong>$this-&gt;clickSubmit('Go!');</strong>
+</pre>
+ </p>
+ <p>
+ La liste des méthodes de navigation est...
+ <table><tbody>
+ <tr>
+<td><span class="new_code">get($url, $parameters)</span></td>
+<td>Envoie une requête GET avec ces paramètres</td>
+</tr>
+ <tr>
+<td><span class="new_code">post($url, $parameters)</span></td>
+<td>Envoie une requête POST avec ces paramètres</td>
+</tr>
+ <tr>
+<td><span class="new_code">head($url, $parameters)</span></td>
+<td>Envoie une requête HEAD sans remplacer le contenu de la page</td>
+</tr>
+ <tr>
+<td><span class="new_code">retry()</span></td>
+<td>Relance la dernière requête</td>
+</tr>
+ <tr>
+<td><span class="new_code">back()</span></td>
+<td>Identique au bouton "Précédent" du navigateur</td>
+</tr>
+ <tr>
+<td><span class="new_code">forward()</span></td>
+<td>Identique au bouton "Suivant" du navigateur</td>
+</tr>
+ <tr>
+<td><span class="new_code">authenticate($name, $password)</span></td>
+<td>Re-essaye avec une tentative d'authentification</td>
+</tr>
+ <tr>
+<td><span class="new_code">getFrameFocus()</span></td>
+<td>Le nom de la fenêtre en cours d'utilisation</td>
+</tr>
+ <tr>
+<td><span class="new_code">setFrameFocusByIndex($choice)</span></td>
+<td>Change le focus d'une fenêtre en commençant par 1</td>
+</tr>
+ <tr>
+<td><span class="new_code">setFrameFocus($name)</span></td>
+<td>Change le focus d'une fenêtre en utilisant son nom</td>
+</tr>
+ <tr>
+<td><span class="new_code">clearFrameFocus()</span></td>
+<td>Revient à un traitement de toutes les fenêtres comme une seule</td>
+</tr>
+ <tr>
+<td><span class="new_code">clickSubmit($label)</span></td>
+<td>Clique sur le premier bouton avec cette étiquette</td>
+</tr>
+ <tr>
+<td><span class="new_code">clickSubmitByName($name)</span></td>
+<td>Clique sur le bouton avec cet attribut de nom</td>
+</tr>
+ <tr>
+<td><span class="new_code">clickSubmitById($id)</span></td>
+<td>Clique sur le bouton avec cet attribut d'identification</td>
+</tr>
+ <tr>
+<td><span class="new_code">clickImage($label, $x, $y)</span></td>
+<td>Clique sur une balise input de type image par son titre (title="*") our son texte alternatif (alt="*")</td>
+</tr>
+ <tr>
+<td><span class="new_code">clickImageByName($name, $x, $y)</span></td>
+<td>Clique sur une balise input de type image par son attribut (name="*")</td>
+</tr>
+ <tr>
+<td><span class="new_code">clickImageById($id, $x, $y)</span></td>
+<td>Clique sur une balise input de type image par son identifiant (id="*")</td>
+</tr>
+ <tr>
+<td><span class="new_code">submitFormById($id)</span></td>
+<td>Soumet un formulaire sans valeur de soumission</td>
+</tr>
+ <tr>
+<td><span class="new_code">clickLink($label, $index)</span></td>
+<td>Clique sur une ancre avec ce texte d'étiquette visible</td>
+</tr>
+ <tr>
+<td><span class="new_code">clickLinkById($id)</span></td>
+<td>Clique sur une ancre avec cet attribut d'identification</td>
+</tr>
+ </tbody></table>
+ </p>
+ <p>
+ Les paramètres dans les méthodes <span class="new_code">get()</span>,
+ <span class="new_code">post()</span> et <span class="new_code">head()</span> sont optionnels.
+ Le téléchargement via HTTP HEAD ne modifie pas
+ le contexte du navigateur, il se limite au chargement des cookies.
+ Cela peut être utilise lorsqu'une image ou une feuille de style
+ initie un cookie pour bloquer un robot trop entreprenant.
+ </p>
+ <p>
+ Les commandes <span class="new_code">retry()</span>, <span class="new_code">back()</span>
+ et <span class="new_code">forward()</span> fonctionnent exactement comme
+ dans un navigateur. Elles utilisent l'historique pour
+ relancer les pages. Une technique bien pratique pour
+ vérifier les effets d'un bouton retour sur vos formulaires.
+ </p>
+ <p>
+ Les méthodes sur les fenêtres méritent une petite explication.
+ Par défaut, une page avec des fenêtres est traitée comme toutes
+ les autres. Le contenu sera vérifié à travers l'ensemble de
+ la "frameset", par conséquent un lien fonctionnera,
+ peu importe la fenêtre qui contient la balise ancre.
+ Vous pouvez outrepassé ce comportement en exigeant
+ le focus sur une unique fenêtre. Si vous réalisez cela,
+ toutes les recherches et toutes les actions se limiteront
+ à cette unique fenêtre, y compris les demandes d'authentification.
+ Si un lien ou un bouton n'est pas dans la fenêtre en focus alors
+ il ne peut pas être cliqué.
+ </p>
+ <p>
+ Tester la navigation sur des pages fixes ne vous alerte que
+ quand vous avez cassé un script entier.
+ Pour des pages fortement dynamiques,
+ un forum de discussion par exemple,
+ ça peut être crucial pour vérifier l'état de l'application.
+ Pour la plupart des applications cependant,
+ la logique vraiment délicate se situe dans la gestion
+ des formulaires et des sessions.
+ Heureusement SimpleTest aussi inclut
+ <a href="form_testing_documentation.html">
+ des outils pour tester des formulaires web</a>.
+ </p>
+
+ <p><a class="target" name="requete"><h2>Modifier la requête</h2></a></p>
+ <p>
+ Bien que SimpleTest n'ait pas comme objectif
+ de contrôler des erreurs réseau, il contient quand même
+ des méthodes pour modifier et déboguer les requêtes qu'il lance.
+ Voici une autre liste de méthode...
+ <table><tbody>
+ <tr>
+<td><span class="new_code">getTransportError()</span></td>
+<td>La dernière erreur de socket</td>
+</tr>
+ <tr>
+<td><span class="new_code">getUrl()</span></td>
+<td>La localisation courante</td>
+</tr>
+ <tr>
+<td><span class="new_code">showRequest()</span></td>
+<td>Déverse la requête sortante</td>
+</tr>
+ <tr>
+<td><span class="new_code">showHeaders()</span></td>
+<td>Déverse les entêtes d'entrée</td>
+</tr>
+ <tr>
+<td><span class="new_code">showSource()</span></td>
+<td>Déverse le contenu brut de la page HTML</td>
+</tr>
+ <tr>
+<td><span class="new_code">ignoreFrames()</span></td>
+<td>Ne recharge pas les framesets</td>
+</tr>
+ <tr>
+<td><span class="new_code">setCookie($name, $value)</span></td>
+<td>Initie un cookie à partir de maintenant</td>
+</tr>
+ <tr>
+<td><span class="new_code">addHeader($header)</span></td>
+<td>Ajoute toujours cette entête à la requête</td>
+</tr>
+ <tr>
+<td><span class="new_code">setMaximumRedirects($max)</span></td>
+<td>S'arrête après autant de redirections</td>
+</tr>
+ <tr>
+<td><span class="new_code">setConnectionTimeout($timeout)</span></td>
+<td>Termine la connexion après autant de temps entre les bytes</td>
+</tr>
+ <tr>
+<td><span class="new_code">useProxy($proxy, $name, $password)</span></td>
+<td>Effectue les requêtes à travers ce proxy d'URL</td>
+</tr>
+ </tbody></table>
+ </p>
+
+ </div>
+ References and related information...
+ <ul>
+<li>
+ La page du projet SimpleTest sur
+ <a href="http://sourceforge.net/projects/simpletest/">SourceForge</a>.
+ </li>
+<li>
+ La page de téléchargement de SimpleTest sur
+ <a href="http://www.lastcraft.com/simple_test.php">LastCraft</a>.
+ </li>
+<li>
+ <a href="http://simpletest.org/api/">L'API du développeur pour SimpleTest</a>
+ donne tous les détails sur les classes et les assertions disponibles.
+ </li>
+</ul>
+<div class="menu_back"><div class="menu">
+<a href="index.html">SimpleTest</a>
+ |
+ <a href="overview.html">Overview</a>
+ |
+ <a href="unit_test_documentation.html">Unit tester</a>
+ |
+ <a href="group_test_documentation.html">Group tests</a>
+ |
+ <a href="mock_objects_documentation.html">Mock objects</a>
+ |
+ <a href="partial_mocks_documentation.html">Partial mocks</a>
+ |
+ <a href="reporter_documentation.html">Reporting</a>
+ |
+ <a href="expectation_documentation.html">Expectations</a>
+ |
+ <a href="web_tester_documentation.html">Web tester</a>
+ |
+ <a href="form_testing_documentation.html">Testing forms</a>
+ |
+ <a href="authentication_documentation.html">Authentication</a>
+ |
+ <a href="browser_documentation.html">Scriptable browser</a>
+</div></div>
+<div class="copyright">
+ Copyright<br>Marcus Baker 2006
+ </div>
+</body>
+</html>
diff --git a/site/vendors/simpletest/dumper.php b/site/vendors/simpletest/dumper.php
new file mode 100644
index 0000000..2d75985
--- /dev/null
+++ b/site/vendors/simpletest/dumper.php
@@ -0,0 +1,360 @@
+<?php
+/**
+ * base include file for SimpleTest
+ * @package SimpleTest
+ * @subpackage UnitTester
+ * @version $Id: dumper.php 1723 2008-04-08 00:34:10Z lastcraft $
+ */
+/**
+ * does type matter
+ */
+if (! defined('TYPE_MATTERS')) {
+ define('TYPE_MATTERS', true);
+}
+
+/**
+ * Displays variables as text and does diffs.
+ * @package SimpleTest
+ * @subpackage UnitTester
+ */
+class SimpleDumper {
+
+ /**
+ * Renders a variable in a shorter form than print_r().
+ * @param mixed $value Variable to render as a string.
+ * @return string Human readable string form.
+ * @access public
+ */
+ function describeValue($value) {
+ $type = $this->getType($value);
+ switch($type) {
+ case "Null":
+ return "NULL";
+ case "Boolean":
+ return "Boolean: " . ($value ? "true" : "false");
+ case "Array":
+ return "Array: " . count($value) . " items";
+ case "Object":
+ return "Object: of " . get_class($value);
+ case "String":
+ return "String: " . $this->clipString($value, 200);
+ default:
+ return "$type: $value";
+ }
+ return "Unknown";
+ }
+
+ /**
+ * Gets the string representation of a type.
+ * @param mixed $value Variable to check against.
+ * @return string Type.
+ * @access public
+ */
+ function getType($value) {
+ if (! isset($value)) {
+ return "Null";
+ } elseif (is_bool($value)) {
+ return "Boolean";
+ } elseif (is_string($value)) {
+ return "String";
+ } elseif (is_integer($value)) {
+ return "Integer";
+ } elseif (is_float($value)) {
+ return "Float";
+ } elseif (is_array($value)) {
+ return "Array";
+ } elseif (is_resource($value)) {
+ return "Resource";
+ } elseif (is_object($value)) {
+ return "Object";
+ }
+ return "Unknown";
+ }
+
+ /**
+ * Creates a human readable description of the
+ * difference between two variables. Uses a
+ * dynamic call.
+ * @param mixed $first First variable.
+ * @param mixed $second Value to compare with.
+ * @param boolean $identical If true then type anomolies count.
+ * @return string Description of difference.
+ * @access public
+ */
+ function describeDifference($first, $second, $identical = false) {
+ if ($identical) {
+ if (! $this->_isTypeMatch($first, $second)) {
+ return "with type mismatch as [" . $this->describeValue($first) .
+ "] does not match [" . $this->describeValue($second) . "]";
+ }
+ }
+ $type = $this->getType($first);
+ if ($type == "Unknown") {
+ return "with unknown type";
+ }
+ $method = '_describe' . $type . 'Difference';
+ return $this->$method($first, $second, $identical);
+ }
+
+ /**
+ * Tests to see if types match.
+ * @param mixed $first First variable.
+ * @param mixed $second Value to compare with.
+ * @return boolean True if matches.
+ * @access private
+ */
+ function _isTypeMatch($first, $second) {
+ return ($this->getType($first) == $this->getType($second));
+ }
+
+ /**
+ * Clips a string to a maximum length.
+ * @param string $value String to truncate.
+ * @param integer $size Minimum string size to show.
+ * @param integer $position Centre of string section.
+ * @return string Shortened version.
+ * @access public
+ */
+ function clipString($value, $size, $position = 0) {
+ $length = strlen($value);
+ if ($length <= $size) {
+ return $value;
+ }
+ $position = min($position, $length);
+ $start = ($size/2 > $position ? 0 : $position - $size/2);
+ if ($start + $size > $length) {
+ $start = $length - $size;
+ }
+ $value = substr($value, $start, $size);
+ return ($start > 0 ? "..." : "") . $value . ($start + $size < $length ? "..." : "");
+ }
+
+ /**
+ * Creates a human readable description of the
+ * difference between two variables. The minimal
+ * version.
+ * @param null $first First value.
+ * @param mixed $second Value to compare with.
+ * @return string Human readable description.
+ * @access private
+ */
+ function _describeGenericDifference($first, $second) {
+ return "as [" . $this->describeValue($first) .
+ "] does not match [" .
+ $this->describeValue($second) . "]";
+ }
+
+ /**
+ * Creates a human readable description of the
+ * difference between a null and another variable.
+ * @param null $first First null.
+ * @param mixed $second Null to compare with.
+ * @param boolean $identical If true then type anomolies count.
+ * @return string Human readable description.
+ * @access private
+ */
+ function _describeNullDifference($first, $second, $identical) {
+ return $this->_describeGenericDifference($first, $second);
+ }
+
+ /**
+ * Creates a human readable description of the
+ * difference between a boolean and another variable.
+ * @param boolean $first First boolean.
+ * @param mixed $second Boolean to compare with.
+ * @param boolean $identical If true then type anomolies count.
+ * @return string Human readable description.
+ * @access private
+ */
+ function _describeBooleanDifference($first, $second, $identical) {
+ return $this->_describeGenericDifference($first, $second);
+ }
+
+ /**
+ * Creates a human readable description of the
+ * difference between a string and another variable.
+ * @param string $first First string.
+ * @param mixed $second String to compare with.
+ * @param boolean $identical If true then type anomolies count.
+ * @return string Human readable description.
+ * @access private
+ */
+ function _describeStringDifference($first, $second, $identical) {
+ if (is_object($second) || is_array($second)) {
+ return $this->_describeGenericDifference($first, $second);
+ }
+ $position = $this->_stringDiffersAt($first, $second);
+ $message = "at character $position";
+ $message .= " with [" .
+ $this->clipString($first, 200, $position) . "] and [" .
+ $this->clipString($second, 200, $position) . "]";
+ return $message;
+ }
+
+ /**
+ * Creates a human readable description of the
+ * difference between an integer and another variable.
+ * @param integer $first First number.
+ * @param mixed $second Number to compare with.
+ * @param boolean $identical If true then type anomolies count.
+ * @return string Human readable description.
+ * @access private
+ */
+ function _describeIntegerDifference($first, $second, $identical) {
+ if (is_object($second) || is_array($second)) {
+ return $this->_describeGenericDifference($first, $second);
+ }
+ return "because [" . $this->describeValue($first) .
+ "] differs from [" .
+ $this->describeValue($second) . "] by " .
+ abs($first - $second);
+ }
+
+ /**
+ * Creates a human readable description of the
+ * difference between two floating point numbers.
+ * @param float $first First float.
+ * @param mixed $second Float to compare with.
+ * @param boolean $identical If true then type anomolies count.
+ * @return string Human readable description.
+ * @access private
+ */
+ function _describeFloatDifference($first, $second, $identical) {
+ if (is_object($second) || is_array($second)) {
+ return $this->_describeGenericDifference($first, $second);
+ }
+ return "because [" . $this->describeValue($first) .
+ "] differs from [" .
+ $this->describeValue($second) . "] by " .
+ abs($first - $second);
+ }
+
+ /**
+ * Creates a human readable description of the
+ * difference between two arrays.
+ * @param array $first First array.
+ * @param mixed $second Array to compare with.
+ * @param boolean $identical If true then type anomolies count.
+ * @return string Human readable description.
+ * @access private
+ */
+ function _describeArrayDifference($first, $second, $identical) {
+ if (! is_array($second)) {
+ return $this->_describeGenericDifference($first, $second);
+ }
+ if (! $this->_isMatchingKeys($first, $second, $identical)) {
+ return "as key list [" .
+ implode(", ", array_keys($first)) . "] does not match key list [" .
+ implode(", ", array_keys($second)) . "]";
+ }
+ foreach (array_keys($first) as $key) {
+ if ($identical && ($first[$key] === $second[$key])) {
+ continue;
+ }
+ if (! $identical && ($first[$key] == $second[$key])) {
+ continue;
+ }
+ return "with member [$key] " . $this->describeDifference(
+ $first[$key],
+ $second[$key],
+ $identical);
+ }
+ return "";
+ }
+
+ /**
+ * Compares two arrays to see if their key lists match.
+ * For an identical match, the ordering and types of the keys
+ * is significant.
+ * @param array $first First array.
+ * @param array $second Array to compare with.
+ * @param boolean $identical If true then type anomolies count.
+ * @return boolean True if matching.
+ * @access private
+ */
+ function _isMatchingKeys($first, $second, $identical) {
+ $first_keys = array_keys($first);
+ $second_keys = array_keys($second);
+ if ($identical) {
+ return ($first_keys === $second_keys);
+ }
+ sort($first_keys);
+ sort($second_keys);
+ return ($first_keys == $second_keys);
+ }
+
+ /**
+ * Creates a human readable description of the
+ * difference between a resource and another variable.
+ * @param resource $first First resource.
+ * @param mixed $second Resource to compare with.
+ * @param boolean $identical If true then type anomolies count.
+ * @return string Human readable description.
+ * @access private
+ */
+ function _describeResourceDifference($first, $second, $identical) {
+ return $this->_describeGenericDifference($first, $second);
+ }
+
+ /**
+ * Creates a human readable description of the
+ * difference between two objects.
+ * @param object $first First object.
+ * @param mixed $second Object to compare with.
+ * @param boolean $identical If true then type anomolies count.
+ * @return string Human readable description.
+ * @access private
+ */
+ function _describeObjectDifference($first, $second, $identical) {
+ if (! is_object($second)) {
+ return $this->_describeGenericDifference($first, $second);
+ }
+ return $this->_describeArrayDifference(
+ get_object_vars($first),
+ get_object_vars($second),
+ $identical);
+ }
+
+ /**
+ * Find the first character position that differs
+ * in two strings by binary chop.
+ * @param string $first First string.
+ * @param string $second String to compare with.
+ * @return integer Position of first differing
+ * character.
+ * @access private
+ */
+ function _stringDiffersAt($first, $second) {
+ if (! $first || ! $second) {
+ return 0;
+ }
+ if (strlen($first) < strlen($second)) {
+ list($first, $second) = array($second, $first);
+ }
+ $position = 0;
+ $step = strlen($first);
+ while ($step > 1) {
+ $step = (integer)(($step + 1) / 2);
+ if (strncmp($first, $second, $position + $step) == 0) {
+ $position += $step;
+ }
+ }
+ return $position;
+ }
+
+ /**
+ * Sends a formatted dump of a variable to a string.
+ * @param mixed $variable Variable to display.
+ * @return string Output from print_r().
+ * @access public
+ * @static
+ */
+ function dump($variable) {
+ ob_start();
+ print_r($variable);
+ $formatted = ob_get_contents();
+ ob_end_clean();
+ return $formatted;
+ }
+}
+?> \ No newline at end of file
diff --git a/site/vendors/simpletest/eclipse.php b/site/vendors/simpletest/eclipse.php
new file mode 100644
index 0000000..0f1a4fc
--- /dev/null
+++ b/site/vendors/simpletest/eclipse.php
@@ -0,0 +1,307 @@
+<?php
+/**
+ * base include file for eclipse plugin
+ * @package SimpleTest
+ * @subpackage Eclipse
+ * @version $Id: eclipse.php 1723 2008-04-08 00:34:10Z lastcraft $
+ */
+/**#@+
+ * simpletest include files
+ */
+include_once 'unit_tester.php';
+include_once 'test_case.php';
+include_once 'invoker.php';
+include_once 'socket.php';
+include_once 'mock_objects.php';
+/**#@-*/
+
+/**
+ * base reported class for eclipse plugin
+ * @package SimpleTest
+ * @subpackage Eclipse
+ */
+class EclipseReporter extends SimpleScorer {
+
+ /**
+ * Reporter to be run inside of Eclipse interface.
+ * @param object $listener Eclipse listener (?).
+ * @param boolean $cc Whether to include test coverage.
+ */
+ function EclipseReporter(&$listener, $cc=false){
+ $this->_listener = &$listener;
+ $this->SimpleScorer();
+ $this->_case = "";
+ $this->_group = "";
+ $this->_method = "";
+ $this->_cc = $cc;
+ $this->_error = false;
+ $this->_fail = false;
+ }
+
+ /**
+ * Means to display human readable object comparisons.
+ * @return SimpleDumper Visual comparer.
+ */
+ function getDumper() {
+ return new SimpleDumper();
+ }
+
+ /**
+ * Localhost connection from Eclipse.
+ * @param integer $port Port to connect to Eclipse.
+ * @param string $host Normally localhost.
+ * @return SimpleSocket Connection to Eclipse.
+ */
+ function &createListener($port, $host="127.0.0.1"){
+ $tmplistener = &new SimpleSocket($host, $port, 5);
+ return $tmplistener;
+ }
+
+ /**
+ * Wraps the test in an output buffer.
+ * @param SimpleInvoker $invoker Current test runner.
+ * @return EclipseInvoker Decorator with output buffering.
+ * @access public
+ */
+ function &createInvoker(&$invoker){
+ $eclinvoker = &new EclipseInvoker($invoker, $this->_listener);
+ return $eclinvoker;
+ }
+
+ /**
+ * C style escaping.
+ * @param string $raw String with backslashes, quotes and whitespace.
+ * @return string Replaced with C backslashed tokens.
+ */
+ function escapeVal($raw){
+ $needle = array("\\","\"","/","\b","\f","\n","\r","\t");
+ $replace = array('\\\\','\"','\/','\b','\f','\n','\r','\t');
+ return str_replace($needle, $replace, $raw);
+ }
+
+ /**
+ * Stash the first passing item. Clicking the test
+ * item goes to first pass.
+ * @param string $message Test message, but we only wnat the first.
+ * @access public
+ */
+ function paintPass($message){
+ if (! $this->_pass){
+ $this->_message = $this->escapeVal($message);
+ }
+ $this->_pass = true;
+ }
+
+ /**
+ * Stash the first failing item. Clicking the test
+ * item goes to first fail.
+ * @param string $message Test message, but we only wnat the first.
+ * @access public
+ */
+ function paintFail($message){
+ //only get the first failure or error
+ if (! $this->_fail && ! $this->_error){
+ $this->_fail = true;
+ $this->_message = $this->escapeVal($message);
+ $this->_listener->write('{status:"fail",message:"'.$this->_message.'",group:"'.$this->_group.'",case:"'.$this->_case.'",method:"'.$this->_method.'"}');
+ }
+ }
+
+ /**
+ * Stash the first error. Clicking the test
+ * item goes to first error.
+ * @param string $message Test message, but we only wnat the first.
+ * @access public
+ */
+ function paintError($message){
+ if (! $this->_fail && ! $this->_error){
+ $this->_error = true;
+ $this->_message = $this->escapeVal($message);
+ $this->_listener->write('{status:"error",message:"'.$this->_message.'",group:"'.$this->_group.'",case:"'.$this->_case.'",method:"'.$this->_method.'"}');
+ }
+ }
+
+
+ /**
+ * Stash the first exception. Clicking the test
+ * item goes to first message.
+ * @param string $message Test message, but we only wnat the first.
+ * @access public
+ */
+ function paintException($exception){
+ if (! $this->_fail && ! $this->_error){
+ $this->_error = true;
+ $message = 'Unexpected exception of type[' . get_class($exception) .
+ '] with message [' . $exception->getMessage() . '] in [' .
+ $exception->getFile() .' line '. $exception->getLine() . ']';
+ $this->_message = $this->escapeVal($message);
+ $this->_listener->write(
+ '{status:"error",message:"' . $this->_message . '",group:"' .
+ $this->_group . '",case:"' . $this->_case . '",method:"' . $this->_method
+ . '"}');
+ }
+ }
+
+
+ /**
+ * We don't display any special header.
+ * @param string $test_name First test top level
+ * to start.
+ * @access public
+ */
+ function paintHeader($test_name) {
+ }
+
+ /**
+ * We don't display any special footer.
+ * @param string $test_name The top level test.
+ * @access public
+ */
+ function paintFooter($test_name) {
+ }
+
+ /**
+ * Paints nothing at the start of a test method, but stash
+ * the method name for later.
+ * @param string $test_name Name of test that is starting.
+ * @access public
+ */
+ function paintMethodStart($method) {
+ $this->_pass = false;
+ $this->_fail = false;
+ $this->_error = false;
+ $this->_method = $this->escapeVal($method);
+ }
+
+ /**
+ * Only send one message if the test passes, after that
+ * suppress the message.
+ * @param string $test_name Name of test that is ending.
+ * @access public
+ */
+ function paintMethodEnd($method){
+ if ($this->_fail || $this->_error || ! $this->_pass){
+ } else {
+ $this->_listener->write(
+ '{status:"pass",message:"' . $this->_message . '",group:"' .
+ $this->_group . '",case:"' . $this->_case . '",method:"' .
+ $this->_method . '"}');
+ }
+ }
+
+ /**
+ * Stashes the test case name for the later failure message.
+ * @param string $test_name Name of test or other label.
+ * @access public
+ */
+ function paintCaseStart($case){
+ $this->_case = $this->escapeVal($case);
+ }
+
+ /**
+ * Drops the name.
+ * @param string $test_name Name of test or other label.
+ * @access public
+ */
+ function paintCaseEnd($case){
+ $this->_case = "";
+ }
+
+ /**
+ * Stashes the name of the test suite. Starts test coverage
+ * if enabled.
+ * @param string $group Name of test or other label.
+ * @param integer $size Number of test cases starting.
+ * @access public
+ */
+ function paintGroupStart($group, $size){
+ $this->_group = $this->escapeVal($group);
+ if ($this->_cc){
+ if (extension_loaded('xdebug')){
+ xdebug_start_code_coverage(XDEBUG_CC_UNUSED | XDEBUG_CC_DEAD_CODE);
+ }
+ }
+ }
+
+ /**
+ * Paints coverage report if enabled.
+ * @param string $group Name of test or other label.
+ * @access public
+ */
+ function paintGroupEnd($group){
+ $this->_group = "";
+ $cc = "";
+ if ($this->_cc){
+ if (extension_loaded('xdebug')){
+ $arrfiles = xdebug_get_code_coverage();
+ xdebug_stop_code_coverage();
+ $thisdir = dirname(__FILE__);
+ $thisdirlen = strlen($thisdir);
+ foreach ($arrfiles as $index=>$file){
+ if (substr($index, 0, $thisdirlen)===$thisdir){
+ continue;
+ }
+ $lcnt = 0;
+ $ccnt = 0;
+ foreach ($file as $line){
+ if ($line == -2){
+ continue;
+ }
+ $lcnt++;
+ if ($line==1){
+ $ccnt++;
+ }
+ }
+ if ($lcnt > 0){
+ $cc .= round(($ccnt/$lcnt) * 100, 2) . '%';
+ }else{
+ $cc .= "0.00%";
+ }
+ $cc.= "\t". $index . "\n";
+ }
+ }
+ }
+ $this->_listener->write('{status:"coverage",message:"' .
+ EclipseReporter::escapeVal($cc) . '"}');
+ }
+}
+
+/**
+ * Invoker decorator for Eclipse. Captures output until
+ * the end of the test.
+ * @package SimpleTest
+ * @subpackage Eclipse
+ */
+class EclipseInvoker extends SimpleInvokerDecorator{
+ function EclipseInvoker(&$invoker, &$listener) {
+ $this->_listener = &$listener;
+ $this->SimpleInvokerDecorator($invoker);
+ }
+
+ /**
+ * Starts output buffering.
+ * @param string $method Test method to call.
+ * @access public
+ */
+ function before($method){
+ ob_start();
+ $this->_invoker->before($method);
+ }
+
+ /**
+ * Stops output buffering and send the captured output
+ * to the listener.
+ * @param string $method Test method to call.
+ * @access public
+ */
+ function after($method) {
+ $this->_invoker->after($method);
+ $output = ob_get_contents();
+ ob_end_clean();
+ if ($output !== ""){
+ $result = $this->_listener->write('{status:"info",message:"' .
+ EclipseReporter::escapeVal($output) . '"}');
+ }
+ }
+}
+?> \ No newline at end of file
diff --git a/site/vendors/simpletest/encoding.php b/site/vendors/simpletest/encoding.php
new file mode 100644
index 0000000..112fe33
--- /dev/null
+++ b/site/vendors/simpletest/encoding.php
@@ -0,0 +1,552 @@
+<?php
+/**
+ * base include file for SimpleTest
+ * @package SimpleTest
+ * @subpackage WebTester
+ * @version $Id: encoding.php 1723 2008-04-08 00:34:10Z lastcraft $
+ */
+
+/**#@+
+ * include other SimpleTest class files
+ */
+require_once(dirname(__FILE__) . '/socket.php');
+/**#@-*/
+
+/**
+ * Single post parameter.
+ * @package SimpleTest
+ * @subpackage WebTester
+ */
+class SimpleEncodedPair {
+ var $_key;
+ var $_value;
+
+ /**
+ * Stashes the data for rendering later.
+ * @param string $key Form element name.
+ * @param string $value Data to send.
+ */
+ function SimpleEncodedPair($key, $value) {
+ $this->_key = $key;
+ $this->_value = $value;
+ }
+
+ /**
+ * The pair as a single string.
+ * @return string Encoded pair.
+ * @access public
+ */
+ function asRequest() {
+ return urlencode($this->_key) . '=' . urlencode($this->_value);
+ }
+
+ /**
+ * The MIME part as a string.
+ * @return string MIME part encoding.
+ * @access public
+ */
+ function asMime() {
+ $part = 'Content-Disposition: form-data; ';
+ $part .= "name=\"" . $this->_key . "\"\r\n";
+ $part .= "\r\n" . $this->_value;
+ return $part;
+ }
+
+ /**
+ * Is this the value we are looking for?
+ * @param string $key Identifier.
+ * @return boolean True if matched.
+ * @access public
+ */
+ function isKey($key) {
+ return $key == $this->_key;
+ }
+
+ /**
+ * Is this the value we are looking for?
+ * @return string Identifier.
+ * @access public
+ */
+ function getKey() {
+ return $this->_key;
+ }
+
+ /**
+ * Is this the value we are looking for?
+ * @return string Content.
+ * @access public
+ */
+ function getValue() {
+ return $this->_value;
+ }
+}
+
+/**
+ * Single post parameter.
+ * @package SimpleTest
+ * @subpackage WebTester
+ */
+class SimpleAttachment {
+ var $_key;
+ var $_content;
+ var $_filename;
+
+ /**
+ * Stashes the data for rendering later.
+ * @param string $key Key to add value to.
+ * @param string $content Raw data.
+ * @param hash $filename Original filename.
+ */
+ function SimpleAttachment($key, $content, $filename) {
+ $this->_key = $key;
+ $this->_content = $content;
+ $this->_filename = $filename;
+ }
+
+ /**
+ * The pair as a single string.
+ * @return string Encoded pair.
+ * @access public
+ */
+ function asRequest() {
+ return '';
+ }
+
+ /**
+ * The MIME part as a string.
+ * @return string MIME part encoding.
+ * @access public
+ */
+ function asMime() {
+ $part = 'Content-Disposition: form-data; ';
+ $part .= 'name="' . $this->_key . '"; ';
+ $part .= 'filename="' . $this->_filename . '"';
+ $part .= "\r\nContent-Type: " . $this->_deduceMimeType();
+ $part .= "\r\n\r\n" . $this->_content;
+ return $part;
+ }
+
+ /**
+ * Attempts to figure out the MIME type from the
+ * file extension and the content.
+ * @return string MIME type.
+ * @access private
+ */
+ function _deduceMimeType() {
+ if ($this->_isOnlyAscii($this->_content)) {
+ return 'text/plain';
+ }
+ return 'application/octet-stream';
+ }
+
+ /**
+ * Tests each character is in the range 0-127.
+ * @param string $ascii String to test.
+ * @access private
+ */
+ function _isOnlyAscii($ascii) {
+ for ($i = 0, $length = strlen($ascii); $i < $length; $i++) {
+ if (ord($ascii[$i]) > 127) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Is this the value we are looking for?
+ * @param string $key Identifier.
+ * @return boolean True if matched.
+ * @access public
+ */
+ function isKey($key) {
+ return $key == $this->_key;
+ }
+
+ /**
+ * Is this the value we are looking for?
+ * @return string Identifier.
+ * @access public
+ */
+ function getKey() {
+ return $this->_key;
+ }
+
+ /**
+ * Is this the value we are looking for?
+ * @return string Content.
+ * @access public
+ */
+ function getValue() {
+ return $this->_filename;
+ }
+}
+
+/**
+ * Bundle of GET/POST parameters. Can include
+ * repeated parameters.
+ * @package SimpleTest
+ * @subpackage WebTester
+ */
+class SimpleEncoding {
+ var $_request;
+
+ /**
+ * Starts empty.
+ * @param array $query Hash of parameters.
+ * Multiple values are
+ * as lists on a single key.
+ * @access public
+ */
+ function SimpleEncoding($query = false) {
+ if (! $query) {
+ $query = array();
+ }
+ $this->clear();
+ $this->merge($query);
+ }
+
+ /**
+ * Empties the request of parameters.
+ * @access public
+ */
+ function clear() {
+ $this->_request = array();
+ }
+
+ /**
+ * Adds a parameter to the query.
+ * @param string $key Key to add value to.
+ * @param string/array $value New data.
+ * @access public
+ */
+ function add($key, $value) {
+ if ($value === false) {
+ return;
+ }
+ if (is_array($value)) {
+ foreach ($value as $item) {
+ $this->_addPair($key, $item);
+ }
+ } else {
+ $this->_addPair($key, $value);
+ }
+ }
+
+ /**
+ * Adds a new value into the request.
+ * @param string $key Key to add value to.
+ * @param string/array $value New data.
+ * @access private
+ */
+ function _addPair($key, $value) {
+ $this->_request[] = new SimpleEncodedPair($key, $value);
+ }
+
+ /**
+ * Adds a MIME part to the query. Does nothing for a
+ * form encoded packet.
+ * @param string $key Key to add value to.
+ * @param string $content Raw data.
+ * @param hash $filename Original filename.
+ * @access public
+ */
+ function attach($key, $content, $filename) {
+ $this->_request[] = new SimpleAttachment($key, $content, $filename);
+ }
+
+ /**
+ * Adds a set of parameters to this query.
+ * @param array/SimpleQueryString $query Multiple values are
+ * as lists on a single key.
+ * @access public
+ */
+ function merge($query) {
+ if (is_object($query)) {
+ $this->_request = array_merge($this->_request, $query->getAll());
+ } elseif (is_array($query)) {
+ foreach ($query as $key => $value) {
+ $this->add($key, $value);
+ }
+ }
+ }
+
+ /**
+ * Accessor for single value.
+ * @return string/array False if missing, string
+ * if present and array if
+ * multiple entries.
+ * @access public
+ */
+ function getValue($key) {
+ $values = array();
+ foreach ($this->_request as $pair) {
+ if ($pair->isKey($key)) {
+ $values[] = $pair->getValue();
+ }
+ }
+ if (count($values) == 0) {
+ return false;
+ } elseif (count($values) == 1) {
+ return $values[0];
+ } else {
+ return $values;
+ }
+ }
+
+ /**
+ * Accessor for listing of pairs.
+ * @return array All pair objects.
+ * @access public
+ */
+ function getAll() {
+ return $this->_request;
+ }
+
+ /**
+ * Renders the query string as a URL encoded
+ * request part.
+ * @return string Part of URL.
+ * @access protected
+ */
+ function _encode() {
+ $statements = array();
+ foreach ($this->_request as $pair) {
+ if ($statement = $pair->asRequest()) {
+ $statements[] = $statement;
+ }
+ }
+ return implode('&', $statements);
+ }
+}
+
+/**
+ * Bundle of GET parameters. Can include
+ * repeated parameters.
+ * @package SimpleTest
+ * @subpackage WebTester
+ */
+class SimpleGetEncoding extends SimpleEncoding {
+
+ /**
+ * Starts empty.
+ * @param array $query Hash of parameters.
+ * Multiple values are
+ * as lists on a single key.
+ * @access public
+ */
+ function SimpleGetEncoding($query = false) {
+ $this->SimpleEncoding($query);
+ }
+
+ /**
+ * HTTP request method.
+ * @return string Always GET.
+ * @access public
+ */
+ function getMethod() {
+ return 'GET';
+ }
+
+ /**
+ * Writes no extra headers.
+ * @param SimpleSocket $socket Socket to write to.
+ * @access public
+ */
+ function writeHeadersTo(&$socket) {
+ }
+
+ /**
+ * No data is sent to the socket as the data is encoded into
+ * the URL.
+ * @param SimpleSocket $socket Socket to write to.
+ * @access public
+ */
+ function writeTo(&$socket) {
+ }
+
+ /**
+ * Renders the query string as a URL encoded
+ * request part for attaching to a URL.
+ * @return string Part of URL.
+ * @access public
+ */
+ function asUrlRequest() {
+ return $this->_encode();
+ }
+}
+
+/**
+ * Bundle of URL parameters for a HEAD request.
+ * @package SimpleTest
+ * @subpackage WebTester
+ */
+class SimpleHeadEncoding extends SimpleGetEncoding {
+
+ /**
+ * Starts empty.
+ * @param array $query Hash of parameters.
+ * Multiple values are
+ * as lists on a single key.
+ * @access public
+ */
+ function SimpleHeadEncoding($query = false) {
+ $this->SimpleGetEncoding($query);
+ }
+
+ /**
+ * HTTP request method.
+ * @return string Always HEAD.
+ * @access public
+ */
+ function getMethod() {
+ return 'HEAD';
+ }
+}
+
+/**
+ * Bundle of POST parameters. Can include
+ * repeated parameters.
+ * @package SimpleTest
+ * @subpackage WebTester
+ */
+class SimplePostEncoding extends SimpleEncoding {
+
+ /**
+ * Starts empty.
+ * @param array $query Hash of parameters.
+ * Multiple values are
+ * as lists on a single key.
+ * @access public
+ */
+ function SimplePostEncoding($query = false) {
+ if (is_array($query) and $this->hasMoreThanOneLevel($query)) {
+ $query = $this->rewriteArrayWithMultipleLevels($query);
+ }
+ $this->SimpleEncoding($query);
+ }
+
+ function hasMoreThanOneLevel($query) {
+ foreach ($query as $key => $value) {
+ if (is_array($value)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ function rewriteArrayWithMultipleLevels($query) {
+ $query_ = array();
+ foreach ($query as $key => $value) {
+ if (is_array($value)) {
+ foreach ($value as $sub_key => $sub_value) {
+ $query_[$key."[".$sub_key."]"] = $sub_value;
+ }
+ } else {
+ $query_[$key] = $value;
+ }
+ }
+ if ($this->hasMoreThanOneLevel($query_)) {
+ $query_ = $this->rewriteArrayWithMultipleLevels($query_);
+ }
+
+ return $query_;
+ }
+
+
+ /**
+ * HTTP request method.
+ * @return string Always POST.
+ * @access public
+ */
+ function getMethod() {
+ return 'POST';
+ }
+
+ /**
+ * Dispatches the form headers down the socket.
+ * @param SimpleSocket $socket Socket to write to.
+ * @access public
+ */
+ function writeHeadersTo(&$socket) {
+ $socket->write("Content-Length: " . (integer)strlen($this->_encode()) . "\r\n");
+ $socket->write("Content-Type: application/x-www-form-urlencoded\r\n");
+ }
+
+ /**
+ * Dispatches the form data down the socket.
+ * @param SimpleSocket $socket Socket to write to.
+ * @access public
+ */
+ function writeTo(&$socket) {
+ $socket->write($this->_encode());
+ }
+
+ /**
+ * Renders the query string as a URL encoded
+ * request part for attaching to a URL.
+ * @return string Part of URL.
+ * @access public
+ */
+ function asUrlRequest() {
+ return '';
+ }
+}
+
+/**
+ * Bundle of POST parameters in the multipart
+ * format. Can include file uploads.
+ * @package SimpleTest
+ * @subpackage WebTester
+ */
+class SimpleMultipartEncoding extends SimplePostEncoding {
+ var $_boundary;
+
+ /**
+ * Starts empty.
+ * @param array $query Hash of parameters.
+ * Multiple values are
+ * as lists on a single key.
+ * @access public
+ */
+ function SimpleMultipartEncoding($query = false, $boundary = false) {
+ $this->SimplePostEncoding($query);
+ $this->_boundary = ($boundary === false ? uniqid('st') : $boundary);
+ }
+
+ /**
+ * Dispatches the form headers down the socket.
+ * @param SimpleSocket $socket Socket to write to.
+ * @access public
+ */
+ function writeHeadersTo(&$socket) {
+ $socket->write("Content-Length: " . (integer)strlen($this->_encode()) . "\r\n");
+ $socket->write("Content-Type: multipart/form-data, boundary=" . $this->_boundary . "\r\n");
+ }
+
+ /**
+ * Dispatches the form data down the socket.
+ * @param SimpleSocket $socket Socket to write to.
+ * @access public
+ */
+ function writeTo(&$socket) {
+ $socket->write($this->_encode());
+ }
+
+ /**
+ * Renders the query string as a URL encoded
+ * request part.
+ * @return string Part of URL.
+ * @access public
+ */
+ function _encode() {
+ $stream = '';
+ foreach ($this->_request as $pair) {
+ $stream .= "--" . $this->_boundary . "\r\n";
+ $stream .= $pair->asMime() . "\r\n";
+ }
+ $stream .= "--" . $this->_boundary . "--\r\n";
+ return $stream;
+ }
+}
+?> \ No newline at end of file
diff --git a/site/vendors/simpletest/errors.php b/site/vendors/simpletest/errors.php
new file mode 100644
index 0000000..5a07885
--- /dev/null
+++ b/site/vendors/simpletest/errors.php
@@ -0,0 +1,288 @@
+<?php
+/**
+ * base include file for SimpleTest
+ * @package SimpleTest
+ * @subpackage UnitTester
+ * @version $Id: errors.php 1672 2008-03-02 04:47:34Z edwardzyang $
+ */
+
+/**
+ * @ignore - PHP5 compatibility fix.
+ */
+if (! defined('E_STRICT')) {
+ define('E_STRICT', 2048);
+}
+
+/**#@+
+ * Includes SimpleTest files.
+ */
+require_once dirname(__FILE__) . '/invoker.php';
+require_once dirname(__FILE__) . '/test_case.php';
+require_once dirname(__FILE__) . '/expectation.php';
+/**#@-*/
+
+/**
+ * Extension that traps errors into an error queue.
+ * @package SimpleTest
+ * @subpackage UnitTester
+ */
+class SimpleErrorTrappingInvoker extends SimpleInvokerDecorator {
+
+ /**
+ * Stores the invoker to wrap.
+ * @param SimpleInvoker $invoker Test method runner.
+ */
+ function SimpleErrorTrappingInvoker(&$invoker) {
+ $this->SimpleInvokerDecorator($invoker);
+ }
+
+ /**
+ * Invokes a test method and dispatches any
+ * untrapped errors. Called back from
+ * the visiting runner.
+ * @param string $method Test method to call.
+ * @access public
+ */
+ function invoke($method) {
+ $queue = &$this->_createErrorQueue();
+ set_error_handler('SimpleTestErrorHandler');
+ parent::invoke($method);
+ restore_error_handler();
+ $queue->tally();
+ }
+
+ /**
+ * Wires up the error queue for a single test.
+ * @return SimpleErrorQueue Queue connected to the test.
+ * @access private
+ */
+ function &_createErrorQueue() {
+ $context = &SimpleTest::getContext();
+ $test = &$this->getTestCase();
+ $queue = &$context->get('SimpleErrorQueue');
+ $queue->setTestCase($test);
+ return $queue;
+ }
+}
+
+/**
+ * Error queue used to record trapped
+ * errors.
+ * @package SimpleTest
+ * @subpackage UnitTester
+ */
+class SimpleErrorQueue {
+ var $_queue;
+ var $_expectation_queue;
+ var $_test;
+ var $_using_expect_style = false;
+
+ /**
+ * Starts with an empty queue.
+ */
+ function SimpleErrorQueue() {
+ $this->clear();
+ }
+
+ /**
+ * Discards the contents of the error queue.
+ * @access public
+ */
+ function clear() {
+ $this->_queue = array();
+ $this->_expectation_queue = array();
+ }
+
+ /**
+ * Sets the currently running test case.
+ * @param SimpleTestCase $test Test case to send messages to.
+ * @access public
+ */
+ function setTestCase(&$test) {
+ $this->_test = &$test;
+ }
+
+ /**
+ * Sets up an expectation of an error. If this is
+ * not fulfilled at the end of the test, a failure
+ * will occour. If the error does happen, then this
+ * will cancel it out and send a pass message.
+ * @param SimpleExpectation $expected Expected error match.
+ * @param string $message Message to display.
+ * @access public
+ */
+ function expectError($expected, $message) {
+ $this->_using_expect_style = true;
+ array_push($this->_expectation_queue, array($expected, $message));
+ }
+
+ /**
+ * Adds an error to the front of the queue.
+ * @param integer $severity PHP error code.
+ * @param string $content Text of error.
+ * @param string $filename File error occoured in.
+ * @param integer $line Line number of error.
+ * @access public
+ */
+ function add($severity, $content, $filename, $line) {
+ $content = str_replace('%', '%%', $content);
+ if ($this->_using_expect_style) {
+ $this->_testLatestError($severity, $content, $filename, $line);
+ } else {
+ array_push(
+ $this->_queue,
+ array($severity, $content, $filename, $line));
+ }
+ }
+
+ /**
+ * Any errors still in the queue are sent to the test
+ * case. Any unfulfilled expectations trigger failures.
+ * @access public
+ */
+ function tally() {
+ while (list($severity, $message, $file, $line) = $this->extract()) {
+ $severity = $this->getSeverityAsString($severity);
+ $this->_test->error($severity, $message, $file, $line);
+ }
+ while (list($expected, $message) = $this->_extractExpectation()) {
+ $this->_test->assert($expected, false, "%s -> Expected error not caught");
+ }
+ }
+
+ /**
+ * Tests the error against the most recent expected
+ * error.
+ * @param integer $severity PHP error code.
+ * @param string $content Text of error.
+ * @param string $filename File error occoured in.
+ * @param integer $line Line number of error.
+ * @access private
+ */
+ function _testLatestError($severity, $content, $filename, $line) {
+ if ($expectation = $this->_extractExpectation()) {
+ list($expected, $message) = $expectation;
+ $this->_test->assert($expected, $content, sprintf(
+ $message,
+ "%s -> PHP error [$content] severity [" .
+ $this->getSeverityAsString($severity) .
+ "] in [$filename] line [$line]"));
+ } else {
+ $this->_test->error($severity, $content, $filename, $line);
+ }
+ }
+
+ /**
+ * Pulls the earliest error from the queue.
+ * @return mixed False if none, or a list of error
+ * information. Elements are: severity
+ * as the PHP error code, the error message,
+ * the file with the error, the line number
+ * and a list of PHP super global arrays.
+ * @access public
+ */
+ function extract() {
+ if (count($this->_queue)) {
+ return array_shift($this->_queue);
+ }
+ return false;
+ }
+
+ /**
+ * Pulls the earliest expectation from the queue.
+ * @return SimpleExpectation False if none.
+ * @access private
+ */
+ function _extractExpectation() {
+ if (count($this->_expectation_queue)) {
+ return array_shift($this->_expectation_queue);
+ }
+ return false;
+ }
+
+ /**
+ * @deprecated
+ */
+ function assertNoErrors($message) {
+ return $this->_test->assert(
+ new TrueExpectation(),
+ count($this->_queue) == 0,
+ sprintf($message, 'Should be no errors'));
+ }
+
+ /**
+ * @deprecated
+ */
+ function assertError($expected, $message) {
+ if (count($this->_queue) == 0) {
+ $this->_test->fail(sprintf($message, 'Expected error not found'));
+ return false;
+ }
+ list($severity, $content, $file, $line) = $this->extract();
+ $severity = $this->getSeverityAsString($severity);
+ return $this->_test->assert(
+ $expected,
+ $content,
+ sprintf($message, "Expected PHP error [$content] severity [$severity] in [$file] line [$line]"));
+ }
+
+ /**
+ * Converts an error code into it's string
+ * representation.
+ * @param $severity PHP integer error code.
+ * @return String version of error code.
+ * @access public
+ * @static
+ */
+ function getSeverityAsString($severity) {
+ static $map = array(
+ E_STRICT => 'E_STRICT',
+ E_ERROR => 'E_ERROR',
+ E_WARNING => 'E_WARNING',
+ E_PARSE => 'E_PARSE',
+ E_NOTICE => 'E_NOTICE',
+ E_CORE_ERROR => 'E_CORE_ERROR',
+ E_CORE_WARNING => 'E_CORE_WARNING',
+ E_COMPILE_ERROR => 'E_COMPILE_ERROR',
+ E_COMPILE_WARNING => 'E_COMPILE_WARNING',
+ E_USER_ERROR => 'E_USER_ERROR',
+ E_USER_WARNING => 'E_USER_WARNING',
+ E_USER_NOTICE => 'E_USER_NOTICE');
+ if (defined('E_RECOVERABLE_ERROR')) {
+ $map[E_RECOVERABLE_ERROR] = 'E_RECOVERABLE_ERROR';
+ }
+ if (defined('E_DEPRECATED')) {
+ $map[E_DEPRECATED] = 'E_DEPRECATED';
+ }
+ return $map[$severity];
+ }
+}
+
+/**
+ * Error handler that simply stashes any errors into the global
+ * error queue. Simulates the existing behaviour with respect to
+ * logging errors, but this feature may be removed in future.
+ * @param $severity PHP error code.
+ * @param $message Text of error.
+ * @param $filename File error occoured in.
+ * @param $line Line number of error.
+ * @param $super_globals Hash of PHP super global arrays.
+ * @static
+ * @access public
+ */
+function SimpleTestErrorHandler($severity, $message, $filename = null, $line = null, $super_globals = null, $mask = null) {
+ $severity = $severity & error_reporting();
+ if ($severity) {
+ restore_error_handler();
+ if (ini_get('log_errors')) {
+ $label = SimpleErrorQueue::getSeverityAsString($severity);
+ error_log("$label: $message in $filename on line $line");
+ }
+ $context = &SimpleTest::getContext();
+ $queue = &$context->get('SimpleErrorQueue');
+ $queue->add($severity, $message, $filename, $line);
+ set_error_handler('SimpleTestErrorHandler');
+ }
+ return true;
+}
+?> \ No newline at end of file
diff --git a/site/vendors/simpletest/exceptions.php b/site/vendors/simpletest/exceptions.php
new file mode 100644
index 0000000..c19a04e
--- /dev/null
+++ b/site/vendors/simpletest/exceptions.php
@@ -0,0 +1,198 @@
+<?php
+/**
+ * base include file for SimpleTest
+ * @package SimpleTest
+ * @subpackage UnitTester
+ * @version $Id: exceptions.php 1672 2008-03-02 04:47:34Z edwardzyang $
+ */
+
+/**#@+
+ * Include required SimpleTest files
+ */
+require_once dirname(__FILE__) . '/invoker.php';
+require_once dirname(__FILE__) . '/expectation.php';
+/**#@-*/
+
+/**
+ * Extension that traps exceptions and turns them into
+ * an error message. PHP5 only.
+ * @package SimpleTest
+ * @subpackage UnitTester
+ */
+class SimpleExceptionTrappingInvoker extends SimpleInvokerDecorator {
+
+ /**
+ * Stores the invoker to be wrapped.
+ * @param SimpleInvoker $invoker Test method runner.
+ */
+ function SimpleExceptionTrappingInvoker($invoker) {
+ $this->SimpleInvokerDecorator($invoker);
+ }
+
+ /**
+ * Invokes a test method whilst trapping expected
+ * exceptions. Any left over unthrown exceptions
+ * are then reported as failures.
+ * @param string $method Test method to call.
+ */
+ function invoke($method) {
+ $trap = SimpleTest::getContext()->get('SimpleExceptionTrap');
+ $trap->clear();
+ try {
+ $has_thrown = false;
+ parent::invoke($method);
+ } catch (Exception $exception) {
+ $has_thrown = true;
+ if (! $trap->isExpected($this->getTestCase(), $exception)) {
+ $this->getTestCase()->exception($exception);
+ }
+ $trap->clear();
+ }
+ if ($message = $trap->getOutstanding()) {
+ $this->getTestCase()->fail($message);
+ }
+ if ($has_thrown) {
+ try {
+ parent::getTestCase()->tearDown();
+ } catch (Exception $e) { }
+ }
+ }
+}
+
+/**
+ * Tests exceptions either by type or the exact
+ * exception. This could be improved to accept
+ * a pattern expectation to test the error
+ * message, but that will have to come later.
+ * @package SimpleTest
+ * @subpackage UnitTester
+ */
+class ExceptionExpectation extends SimpleExpectation {
+ private $expected;
+
+ /**
+ * Sets up the conditions to test against.
+ * If the expected value is a string, then
+ * it will act as a test of the class name.
+ * An exception as the comparison will
+ * trigger an identical match. Writing this
+ * down now makes it look doubly dumb. I hope
+ * come up with a better scheme later.
+ * @param mixed $expected A class name or an actual
+ * exception to compare with.
+ * @param string $message Message to display.
+ */
+ function __construct($expected, $message = '%s') {
+ $this->expected = $expected;
+ parent::__construct($message);
+ }
+
+ /**
+ * Carry out the test.
+ * @param Exception $compare Value to check.
+ * @return boolean True if matched.
+ */
+ function test($compare) {
+ if (is_string($this->expected)) {
+ return ($compare instanceof $this->expected);
+ }
+ if (get_class($compare) != get_class($this->expected)) {
+ return false;
+ }
+ return $compare->getMessage() == $this->expected->getMessage();
+ }
+
+ /**
+ * Create the message to display describing the test.
+ * @param Exception $compare Exception to match.
+ * @return string Final message.
+ */
+ function testMessage($compare) {
+ if (is_string($this->expected)) {
+ return "Exception [" . $this->describeException($compare) .
+ "] should be type [" . $this->expected . "]";
+ }
+ return "Exception [" . $this->describeException($compare) .
+ "] should match [" .
+ $this->describeException($this->expected) . "]";
+ }
+
+ /**
+ * Summary of an Exception object.
+ * @param Exception $compare Exception to describe.
+ * @return string Text description.
+ */
+ protected function describeException($exception) {
+ return get_class($exception) . ": " . $exception->getMessage();
+ }
+}
+
+/**
+ * Stores expected exceptions for when they
+ * get thrown. Saves the irritating try...catch
+ * block.
+ * @package SimpleTest
+ * @subpackage UnitTester
+ */
+class SimpleExceptionTrap {
+ private $expected;
+ private $message;
+
+ /**
+ * Clears down the queue ready for action.
+ */
+ function __construct() {
+ $this->clear();
+ }
+
+ /**
+ * Sets up an expectation of an exception.
+ * This has the effect of intercepting an
+ * exception that matches.
+ * @param SimpleExpectation $expected Expected exception to match.
+ * @param string $message Message to display.
+ * @access public
+ */
+ function expectException($expected = false, $message = '%s') {
+ if ($expected === false) {
+ $expected = new AnythingExpectation();
+ }
+ if (! SimpleExpectation::isExpectation($expected)) {
+ $expected = new ExceptionExpectation($expected);
+ }
+ $this->expected = $expected;
+ $this->message = $message;
+ }
+
+ /**
+ * Compares the expected exception with any
+ * in the queue. Issues a pass or fail and
+ * returns the state of the test.
+ * @param SimpleTestCase $test Test case to send messages to.
+ * @param Exception $exception Exception to compare.
+ * @return boolean False on no match.
+ */
+ function isExpected($test, $exception) {
+ if ($this->expected) {
+ return $test->assert($this->expected, $exception, $this->message);
+ }
+ return false;
+ }
+
+ /**
+ * Tests for any left over exception.
+ * @return string/false The failure message or false if none.
+ */
+ function getOutstanding() {
+ return sprintf($this->message, 'Failed to trap exception');
+ }
+
+ /**
+ * Discards the contents of the error queue.
+ */
+ function clear() {
+ $this->expected = false;
+ $this->message = false;
+ }
+}
+?> \ No newline at end of file
diff --git a/site/vendors/simpletest/expectation.php b/site/vendors/simpletest/expectation.php
new file mode 100644
index 0000000..194afd5
--- /dev/null
+++ b/site/vendors/simpletest/expectation.php
@@ -0,0 +1,895 @@
+<?php
+/**
+ * base include file for SimpleTest
+ * @package SimpleTest
+ * @subpackage UnitTester
+ * @version $Id: expectation.php 1723 2008-04-08 00:34:10Z lastcraft $
+ */
+
+/**#@+
+ * include other SimpleTest class files
+ */
+require_once(dirname(__FILE__) . '/dumper.php');
+require_once(dirname(__FILE__) . '/compatibility.php');
+/**#@-*/
+
+/**
+ * Assertion that can display failure information.
+ * Also includes various helper methods.
+ * @package SimpleTest
+ * @subpackage UnitTester
+ * @abstract
+ */
+class SimpleExpectation {
+ var $_dumper = false;
+ var $_message;
+
+ /**
+ * Creates a dumper for displaying values and sets
+ * the test message.
+ * @param string $message Customised message on failure.
+ */
+ function SimpleExpectation($message = '%s') {
+ $this->_message = $message;
+ }
+
+ /**
+ * Tests the expectation. True if correct.
+ * @param mixed $compare Comparison value.
+ * @return boolean True if correct.
+ * @access public
+ * @abstract
+ */
+ function test($compare) {
+ }
+
+ /**
+ * Returns a human readable test message.
+ * @param mixed $compare Comparison value.
+ * @return string Description of success
+ * or failure.
+ * @access public
+ * @abstract
+ */
+ function testMessage($compare) {
+ }
+
+ /**
+ * Overlays the generated message onto the stored user
+ * message. An additional message can be interjected.
+ * @param mixed $compare Comparison value.
+ * @param SimpleDumper $dumper For formatting the results.
+ * @return string Description of success
+ * or failure.
+ * @access public
+ */
+ function overlayMessage($compare, $dumper) {
+ $this->_dumper = $dumper;
+ return sprintf($this->_message, $this->testMessage($compare));
+ }
+
+ /**
+ * Accessor for the dumper.
+ * @return SimpleDumper Current value dumper.
+ * @access protected
+ */
+ function &_getDumper() {
+ if (! $this->_dumper) {
+ $dumper = &new SimpleDumper();
+ return $dumper;
+ }
+ return $this->_dumper;
+ }
+
+ /**
+ * Test to see if a value is an expectation object.
+ * A useful utility method.
+ * @param mixed $expectation Hopefully an Epectation
+ * class.
+ * @return boolean True if descended from
+ * this class.
+ * @access public
+ * @static
+ */
+ function isExpectation($expectation) {
+ return is_object($expectation) &&
+ SimpleTestCompatibility::isA($expectation, 'SimpleExpectation');
+ }
+}
+
+/**
+ * A wildcard expectation always matches.
+ * @package SimpleTest
+ * @subpackage MockObjects
+ */
+class AnythingExpectation extends SimpleExpectation {
+
+ /**
+ * Tests the expectation. Always true.
+ * @param mixed $compare Ignored.
+ * @return boolean True.
+ * @access public
+ */
+ function test($compare) {
+ return true;
+ }
+
+ /**
+ * Returns a human readable test message.
+ * @param mixed $compare Comparison value.
+ * @return string Description of success
+ * or failure.
+ * @access public
+ */
+ function testMessage($compare) {
+ $dumper = &$this->_getDumper();
+ return 'Anything always matches [' . $dumper->describeValue($compare) . ']';
+ }
+}
+
+/**
+ * An expectation that never matches.
+ * @package SimpleTest
+ * @subpackage MockObjects
+ */
+class FailedExpectation extends SimpleExpectation {
+
+ /**
+ * Tests the expectation. Always false.
+ * @param mixed $compare Ignored.
+ * @return boolean True.
+ * @access public
+ */
+ function test($compare) {
+ return false;
+ }
+
+ /**
+ * Returns a human readable test message.
+ * @param mixed $compare Comparison value.
+ * @return string Description of failure.
+ * @access public
+ */
+ function testMessage($compare) {
+ $dumper = &$this->_getDumper();
+ return 'Failed expectation never matches [' . $dumper->describeValue($compare) . ']';
+ }
+}
+
+/**
+ * An expectation that passes on boolean true.
+ * @package SimpleTest
+ * @subpackage MockObjects
+ */
+class TrueExpectation extends SimpleExpectation {
+
+ /**
+ * Tests the expectation.
+ * @param mixed $compare Should be true.
+ * @return boolean True on match.
+ * @access public
+ */
+ function test($compare) {
+ return (boolean)$compare;
+ }
+
+ /**
+ * Returns a human readable test message.
+ * @param mixed $compare Comparison value.
+ * @return string Description of success
+ * or failure.
+ * @access public
+ */
+ function testMessage($compare) {
+ $dumper = &$this->_getDumper();
+ return 'Expected true, got [' . $dumper->describeValue($compare) . ']';
+ }
+}
+
+/**
+ * An expectation that passes on boolean false.
+ * @package SimpleTest
+ * @subpackage MockObjects
+ */
+class FalseExpectation extends SimpleExpectation {
+
+ /**
+ * Tests the expectation.
+ * @param mixed $compare Should be false.
+ * @return boolean True on match.
+ * @access public
+ */
+ function test($compare) {
+ return ! (boolean)$compare;
+ }
+
+ /**
+ * Returns a human readable test message.
+ * @param mixed $compare Comparison value.
+ * @return string Description of success
+ * or failure.
+ * @access public
+ */
+ function testMessage($compare) {
+ $dumper = &$this->_getDumper();
+ return 'Expected false, got [' . $dumper->describeValue($compare) . ']';
+ }
+}
+
+/**
+ * Test for equality.
+ * @package SimpleTest
+ * @subpackage UnitTester
+ */
+class EqualExpectation extends SimpleExpectation {
+ var $_value;
+
+ /**
+ * Sets the value to compare against.
+ * @param mixed $value Test value to match.
+ * @param string $message Customised message on failure.
+ * @access public
+ */
+ function EqualExpectation($value, $message = '%s') {
+ $this->SimpleExpectation($message);
+ $this->_value = $value;
+ }
+
+ /**
+ * Tests the expectation. True if it matches the
+ * held value.
+ * @param mixed $compare Comparison value.
+ * @return boolean True if correct.
+ * @access public
+ */
+ function test($compare) {
+ return (($this->_value == $compare) && ($compare == $this->_value));
+ }
+
+ /**
+ * Returns a human readable test message.
+ * @param mixed $compare Comparison value.
+ * @return string Description of success
+ * or failure.
+ * @access public
+ */
+ function testMessage($compare) {
+ if ($this->test($compare)) {
+ return "Equal expectation [" . $this->_dumper->describeValue($this->_value) . "]";
+ } else {
+ return "Equal expectation fails " .
+ $this->_dumper->describeDifference($this->_value, $compare);
+ }
+ }
+
+ /**
+ * Accessor for comparison value.
+ * @return mixed Held value to compare with.
+ * @access protected
+ */
+ function _getValue() {
+ return $this->_value;
+ }
+}
+
+/**
+ * Test for inequality.
+ * @package SimpleTest
+ * @subpackage UnitTester
+ */
+class NotEqualExpectation extends EqualExpectation {
+
+ /**
+ * Sets the value to compare against.
+ * @param mixed $value Test value to match.
+ * @param string $message Customised message on failure.
+ * @access public
+ */
+ function NotEqualExpectation($value, $message = '%s') {
+ $this->EqualExpectation($value, $message);
+ }
+
+ /**
+ * Tests the expectation. True if it differs from the
+ * held value.
+ * @param mixed $compare Comparison value.
+ * @return boolean True if correct.
+ * @access public
+ */
+ function test($compare) {
+ return ! parent::test($compare);
+ }
+
+ /**
+ * Returns a human readable test message.
+ * @param mixed $compare Comparison value.
+ * @return string Description of success
+ * or failure.
+ * @access public
+ */
+ function testMessage($compare) {
+ $dumper = &$this->_getDumper();
+ if ($this->test($compare)) {
+ return "Not equal expectation passes " .
+ $dumper->describeDifference($this->_getValue(), $compare);
+ } else {
+ return "Not equal expectation fails [" .
+ $dumper->describeValue($this->_getValue()) .
+ "] matches";
+ }
+ }
+}
+
+/**
+ * Test for being within a range.
+ * @package SimpleTest
+ * @subpackage UnitTester
+ */
+class WithinMarginExpectation extends SimpleExpectation {
+ var $_upper;
+ var $_lower;
+
+ /**
+ * Sets the value to compare against and the fuzziness of
+ * the match. Used for comparing floating point values.
+ * @param mixed $value Test value to match.
+ * @param mixed $margin Fuzziness of match.
+ * @param string $message Customised message on failure.
+ * @access public
+ */
+ function WithinMarginExpectation($value, $margin, $message = '%s') {
+ $this->SimpleExpectation($message);
+ $this->_upper = $value + $margin;
+ $this->_lower = $value - $margin;
+ }
+
+ /**
+ * Tests the expectation. True if it matches the
+ * held value.
+ * @param mixed $compare Comparison value.
+ * @return boolean True if correct.
+ * @access public
+ */
+ function test($compare) {
+ return (($compare <= $this->_upper) && ($compare >= $this->_lower));
+ }
+
+ /**
+ * Returns a human readable test message.
+ * @param mixed $compare Comparison value.
+ * @return string Description of success
+ * or failure.
+ * @access public
+ */
+ function testMessage($compare) {
+ if ($this->test($compare)) {
+ return $this->_withinMessage($compare);
+ } else {
+ return $this->_outsideMessage($compare);
+ }
+ }
+
+ /**
+ * Creates a the message for being within the range.
+ * @param mixed $compare Value being tested.
+ * @access private
+ */
+ function _withinMessage($compare) {
+ return "Within expectation [" . $this->_dumper->describeValue($this->_lower) . "] and [" .
+ $this->_dumper->describeValue($this->_upper) . "]";
+ }
+
+ /**
+ * Creates a the message for being within the range.
+ * @param mixed $compare Value being tested.
+ * @access private
+ */
+ function _outsideMessage($compare) {
+ if ($compare > $this->_upper) {
+ return "Outside expectation " .
+ $this->_dumper->describeDifference($compare, $this->_upper);
+ } else {
+ return "Outside expectation " .
+ $this->_dumper->describeDifference($compare, $this->_lower);
+ }
+ }
+}
+
+/**
+ * Test for being outside of a range.
+ * @package SimpleTest
+ * @subpackage UnitTester
+ */
+class OutsideMarginExpectation extends WithinMarginExpectation {
+
+ /**
+ * Sets the value to compare against and the fuzziness of
+ * the match. Used for comparing floating point values.
+ * @param mixed $value Test value to not match.
+ * @param mixed $margin Fuzziness of match.
+ * @param string $message Customised message on failure.
+ * @access public
+ */
+ function OutsideMarginExpectation($value, $margin, $message = '%s') {
+ $this->WithinMarginExpectation($value, $margin, $message);
+ }
+
+ /**
+ * Tests the expectation. True if it matches the
+ * held value.
+ * @param mixed $compare Comparison value.
+ * @return boolean True if correct.
+ * @access public
+ */
+ function test($compare) {
+ return ! parent::test($compare);
+ }
+
+ /**
+ * Returns a human readable test message.
+ * @param mixed $compare Comparison value.
+ * @return string Description of success
+ * or failure.
+ * @access public
+ */
+ function testMessage($compare) {
+ if (! $this->test($compare)) {
+ return $this->_withinMessage($compare);
+ } else {
+ return $this->_outsideMessage($compare);
+ }
+ }
+}
+
+/**
+ * Test for reference.
+ * @package SimpleTest
+ * @subpackage UnitTester
+ */
+class ReferenceExpectation extends SimpleExpectation {
+ var $_value;
+
+ /**
+ * Sets the reference value to compare against.
+ * @param mixed $value Test reference to match.
+ * @param string $message Customised message on failure.
+ * @access public
+ */
+ function ReferenceExpectation(&$value, $message = '%s') {
+ $this->SimpleExpectation($message);
+ $this->_value =& $value;
+ }
+
+ /**
+ * Tests the expectation. True if it exactly
+ * references the held value.
+ * @param mixed $compare Comparison reference.
+ * @return boolean True if correct.
+ * @access public
+ */
+ function test(&$compare) {
+ return SimpleTestCompatibility::isReference($this->_value, $compare);
+ }
+
+ /**
+ * Returns a human readable test message.
+ * @param mixed $compare Comparison value.
+ * @return string Description of success
+ * or failure.
+ * @access public
+ */
+ function testMessage($compare) {
+ if ($this->test($compare)) {
+ return "Reference expectation [" . $this->_dumper->describeValue($this->_value) . "]";
+ } else {
+ return "Reference expectation fails " .
+ $this->_dumper->describeDifference($this->_value, $compare);
+ }
+ }
+
+ function _getValue() {
+ return $this->_value;
+ }
+}
+
+/**
+ * Test for identity.
+ * @package SimpleTest
+ * @subpackage UnitTester
+ */
+class IdenticalExpectation extends EqualExpectation {
+
+ /**
+ * Sets the value to compare against.
+ * @param mixed $value Test value to match.
+ * @param string $message Customised message on failure.
+ * @access public
+ */
+ function IdenticalExpectation($value, $message = '%s') {
+ $this->EqualExpectation($value, $message);
+ }
+
+ /**
+ * Tests the expectation. True if it exactly
+ * matches the held value.
+ * @param mixed $compare Comparison value.
+ * @return boolean True if correct.
+ * @access public
+ */
+ function test($compare) {
+ return SimpleTestCompatibility::isIdentical($this->_getValue(), $compare);
+ }
+
+ /**
+ * Returns a human readable test message.
+ * @param mixed $compare Comparison value.
+ * @return string Description of success
+ * or failure.
+ * @access public
+ */
+ function testMessage($compare) {
+ $dumper = &$this->_getDumper();
+ if ($this->test($compare)) {
+ return "Identical expectation [" . $dumper->describeValue($this->_getValue()) . "]";
+ } else {
+ return "Identical expectation [" . $dumper->describeValue($this->_getValue()) .
+ "] fails with [" .
+ $dumper->describeValue($compare) . "] " .
+ $dumper->describeDifference($this->_getValue(), $compare, TYPE_MATTERS);
+ }
+ }
+}
+
+/**
+ * Test for non-identity.
+ * @package SimpleTest
+ * @subpackage UnitTester
+ */
+class NotIdenticalExpectation extends IdenticalExpectation {
+
+ /**
+ * Sets the value to compare against.
+ * @param mixed $value Test value to match.
+ * @param string $message Customised message on failure.
+ * @access public
+ */
+ function NotIdenticalExpectation($value, $message = '%s') {
+ $this->IdenticalExpectation($value, $message);
+ }
+
+ /**
+ * Tests the expectation. True if it differs from the
+ * held value.
+ * @param mixed $compare Comparison value.
+ * @return boolean True if correct.
+ * @access public
+ */
+ function test($compare) {
+ return ! parent::test($compare);
+ }
+
+ /**
+ * Returns a human readable test message.
+ * @param mixed $compare Comparison value.
+ * @return string Description of success
+ * or failure.
+ * @access public
+ */
+ function testMessage($compare) {
+ $dumper = &$this->_getDumper();
+ if ($this->test($compare)) {
+ return "Not identical expectation passes " .
+ $dumper->describeDifference($this->_getValue(), $compare, TYPE_MATTERS);
+ } else {
+ return "Not identical expectation [" . $dumper->describeValue($this->_getValue()) . "] matches";
+ }
+ }
+}
+
+/**
+ * Test for a pattern using Perl regex rules.
+ * @package SimpleTest
+ * @subpackage UnitTester
+ */
+class PatternExpectation extends SimpleExpectation {
+ var $_pattern;
+
+ /**
+ * Sets the value to compare against.
+ * @param string $pattern Pattern to search for.
+ * @param string $message Customised message on failure.
+ * @access public
+ */
+ function PatternExpectation($pattern, $message = '%s') {
+ $this->SimpleExpectation($message);
+ $this->_pattern = $pattern;
+ }
+
+ /**
+ * Accessor for the pattern.
+ * @return string Perl regex as string.
+ * @access protected
+ */
+ function _getPattern() {
+ return $this->_pattern;
+ }
+
+ /**
+ * Tests the expectation. True if the Perl regex
+ * matches the comparison value.
+ * @param string $compare Comparison value.
+ * @return boolean True if correct.
+ * @access public
+ */
+ function test($compare) {
+ return (boolean)preg_match($this->_getPattern(), $compare);
+ }
+
+ /**
+ * Returns a human readable test message.
+ * @param mixed $compare Comparison value.
+ * @return string Description of success
+ * or failure.
+ * @access public
+ */
+ function testMessage($compare) {
+ if ($this->test($compare)) {
+ return $this->_describePatternMatch($this->_getPattern(), $compare);
+ } else {
+ $dumper = &$this->_getDumper();
+ return "Pattern [" . $this->_getPattern() .
+ "] not detected in [" .
+ $dumper->describeValue($compare) . "]";
+ }
+ }
+
+ /**
+ * Describes a pattern match including the string
+ * found and it's position.
+ * @param string $pattern Regex to match against.
+ * @param string $subject Subject to search.
+ * @access protected
+ */
+ function _describePatternMatch($pattern, $subject) {
+ preg_match($pattern, $subject, $matches);
+ $position = strpos($subject, $matches[0]);
+ $dumper = $this->_getDumper();
+ return "Pattern [$pattern] detected at character [$position] in [" .
+ $dumper->describeValue($subject) . "] as [" .
+ $matches[0] . "] in region [" .
+ $dumper->clipString($subject, 100, $position) . "]";
+ }
+}
+
+/**
+ * @package SimpleTest
+ * @subpackage UnitTester
+ * @deprecated
+ */
+class WantedPatternExpectation extends PatternExpectation {
+}
+
+/**
+ * Fail if a pattern is detected within the
+ * comparison.
+ * @package SimpleTest
+ * @subpackage UnitTester
+ */
+class NoPatternExpectation extends PatternExpectation {
+
+ /**
+ * Sets the reject pattern
+ * @param string $pattern Pattern to search for.
+ * @param string $message Customised message on failure.
+ * @access public
+ */
+ function NoPatternExpectation($pattern, $message = '%s') {
+ $this->PatternExpectation($pattern, $message);
+ }
+
+ /**
+ * Tests the expectation. False if the Perl regex
+ * matches the comparison value.
+ * @param string $compare Comparison value.
+ * @return boolean True if correct.
+ * @access public
+ */
+ function test($compare) {
+ return ! parent::test($compare);
+ }
+
+ /**
+ * Returns a human readable test message.
+ * @param string $compare Comparison value.
+ * @return string Description of success
+ * or failure.
+ * @access public
+ */
+ function testMessage($compare) {
+ if ($this->test($compare)) {
+ $dumper = &$this->_getDumper();
+ return "Pattern [" . $this->_getPattern() .
+ "] not detected in [" .
+ $dumper->describeValue($compare) . "]";
+ } else {
+ return $this->_describePatternMatch($this->_getPattern(), $compare);
+ }
+ }
+}
+
+/**
+ * @package SimpleTest
+ * @subpackage UnitTester
+ * @deprecated
+ */
+class UnwantedPatternExpectation extends NoPatternExpectation {
+}
+
+/**
+ * Tests either type or class name if it's an object.
+ * @package SimpleTest
+ * @subpackage UnitTester
+ */
+class IsAExpectation extends SimpleExpectation {
+ var $_type;
+
+ /**
+ * Sets the type to compare with.
+ * @param string $type Type or class name.
+ * @param string $message Customised message on failure.
+ * @access public
+ */
+ function IsAExpectation($type, $message = '%s') {
+ $this->SimpleExpectation($message);
+ $this->_type = $type;
+ }
+
+ /**
+ * Accessor for type to check against.
+ * @return string Type or class name.
+ * @access protected
+ */
+ function _getType() {
+ return $this->_type;
+ }
+
+ /**
+ * Tests the expectation. True if the type or
+ * class matches the string value.
+ * @param string $compare Comparison value.
+ * @return boolean True if correct.
+ * @access public
+ */
+ function test($compare) {
+ if (is_object($compare)) {
+ return SimpleTestCompatibility::isA($compare, $this->_type);
+ } else {
+ return (strtolower(gettype($compare)) == $this->_canonicalType($this->_type));
+ }
+ }
+
+ /**
+ * Coerces type name into a gettype() match.
+ * @param string $type User type.
+ * @return string Simpler type.
+ * @access private
+ */
+ function _canonicalType($type) {
+ $type = strtolower($type);
+ $map = array(
+ 'bool' => 'boolean',
+ 'float' => 'double',
+ 'real' => 'double',
+ 'int' => 'integer');
+ if (isset($map[$type])) {
+ $type = $map[$type];
+ }
+ return $type;
+ }
+
+ /**
+ * Returns a human readable test message.
+ * @param mixed $compare Comparison value.
+ * @return string Description of success
+ * or failure.
+ * @access public
+ */
+ function testMessage($compare) {
+ $dumper = &$this->_getDumper();
+ return "Value [" . $dumper->describeValue($compare) .
+ "] should be type [" . $this->_type . "]";
+ }
+}
+
+/**
+ * Tests either type or class name if it's an object.
+ * Will succeed if the type does not match.
+ * @package SimpleTest
+ * @subpackage UnitTester
+ */
+class NotAExpectation extends IsAExpectation {
+ var $_type;
+
+ /**
+ * Sets the type to compare with.
+ * @param string $type Type or class name.
+ * @param string $message Customised message on failure.
+ * @access public
+ */
+ function NotAExpectation($type, $message = '%s') {
+ $this->IsAExpectation($type, $message);
+ }
+
+ /**
+ * Tests the expectation. False if the type or
+ * class matches the string value.
+ * @param string $compare Comparison value.
+ * @return boolean True if different.
+ * @access public
+ */
+ function test($compare) {
+ return ! parent::test($compare);
+ }
+
+ /**
+ * Returns a human readable test message.
+ * @param mixed $compare Comparison value.
+ * @return string Description of success
+ * or failure.
+ * @access public
+ */
+ function testMessage($compare) {
+ $dumper = &$this->_getDumper();
+ return "Value [" . $dumper->describeValue($compare) .
+ "] should not be type [" . $this->_getType() . "]";
+ }
+}
+
+/**
+ * Tests for existance of a method in an object
+ * @package SimpleTest
+ * @subpackage UnitTester
+ */
+class MethodExistsExpectation extends SimpleExpectation {
+ var $_method;
+
+ /**
+ * Sets the value to compare against.
+ * @param string $method Method to check.
+ * @param string $message Customised message on failure.
+ * @access public
+ * @return void
+ */
+ function MethodExistsExpectation($method, $message = '%s') {
+ $this->SimpleExpectation($message);
+ $this->_method = &$method;
+ }
+
+ /**
+ * Tests the expectation. True if the method exists in the test object.
+ * @param string $compare Comparison method name.
+ * @return boolean True if correct.
+ * @access public
+ */
+ function test($compare) {
+ return (boolean)(is_object($compare) && method_exists($compare, $this->_method));
+ }
+
+ /**
+ * Returns a human readable test message.
+ * @param mixed $compare Comparison value.
+ * @return string Description of success
+ * or failure.
+ * @access public
+ */
+ function testMessage($compare) {
+ $dumper = &$this->_getDumper();
+ if (! is_object($compare)) {
+ return 'No method on non-object [' . $dumper->describeValue($compare) . ']';
+ }
+ $method = $this->_method;
+ return "Object [" . $dumper->describeValue($compare) .
+ "] should contain method [$method]";
+ }
+}
+?> \ No newline at end of file
diff --git a/site/vendors/simpletest/extensions/pear_test_case.php b/site/vendors/simpletest/extensions/pear_test_case.php
new file mode 100644
index 0000000..f5e5a7b
--- /dev/null
+++ b/site/vendors/simpletest/extensions/pear_test_case.php
@@ -0,0 +1,198 @@
+<?php
+ /**
+ * adapter for SimpleTest to use PEAR PHPUnit test cases
+ * @package SimpleTest
+ * @subpackage Extensions
+ * @version $Id: pear_test_case.php 1388 2006-11-10 20:59:59Z lastcraft $
+ */
+
+ /**#@+
+ * include SimpleTest files
+ */
+ require_once(dirname(__FILE__) . '/../dumper.php');
+ require_once(dirname(__FILE__) . '/../compatibility.php');
+ require_once(dirname(__FILE__) . '/../test_case.php');
+ require_once(dirname(__FILE__) . '/../expectation.php');
+ /**#@-*/
+
+ /**
+ * Adapter for PEAR PHPUnit test case to allow
+ * legacy PEAR test cases to be used with SimpleTest.
+ * @package SimpleTest
+ * @subpackage Extensions
+ */
+ class PHPUnit_TestCase extends SimpleTestCase {
+ var $_loosely_typed;
+
+ /**
+ * Constructor. Sets the test name.
+ * @param $label Test name to display.
+ * @public
+ */
+ function PHPUnit_TestCase($label = false) {
+ $this->SimpleTestCase($label);
+ $this->_loosely_typed = false;
+ }
+
+ /**
+ * Will test straight equality if set to loose
+ * typing, or identity if not.
+ * @param $first First value.
+ * @param $second Comparison value.
+ * @param $message Message to display.
+ * @public
+ */
+ function assertEquals($first, $second, $message = "%s", $delta = 0) {
+ if ($this->_loosely_typed) {
+ $expectation = &new EqualExpectation($first);
+ } else {
+ $expectation = &new IdenticalExpectation($first);
+ }
+ $this->assert($expectation, $second, $message);
+ }
+
+ /**
+ * Passes if the value tested is not null.
+ * @param $value Value to test against.
+ * @param $message Message to display.
+ * @public
+ */
+ function assertNotNull($value, $message = "%s") {
+ parent::assert(new TrueExpectation(), isset($value), $message);
+ }
+
+ /**
+ * Passes if the value tested is null.
+ * @param $value Value to test against.
+ * @param $message Message to display.
+ * @public
+ */
+ function assertNull($value, $message = "%s") {
+ parent::assert(new TrueExpectation(), !isset($value), $message);
+ }
+
+ /**
+ * In PHP5 the identity test tests for the same
+ * object. This is a reference test in PHP4.
+ * @param $first First object handle.
+ * @param $second Hopefully the same handle.
+ * @param $message Message to display.
+ * @public
+ */
+ function assertSame(&$first, &$second, $message = "%s") {
+ $dumper = &new SimpleDumper();
+ $message = sprintf(
+ $message,
+ "[" . $dumper->describeValue($first) .
+ "] and [" . $dumper->describeValue($second) .
+ "] should reference the same object");
+ return $this->assert(
+ new TrueExpectation(),
+ SimpleTestCompatibility::isReference($first, $second),
+ $message);
+ }
+
+ /**
+ * In PHP5 the identity test tests for the same
+ * object. This is a reference test in PHP4.
+ * @param $first First object handle.
+ * @param $second Hopefully a different handle.
+ * @param $message Message to display.
+ * @public
+ */
+ function assertNotSame(&$first, &$second, $message = "%s") {
+ $dumper = &new SimpleDumper();
+ $message = sprintf(
+ $message,
+ "[" . $dumper->describeValue($first) .
+ "] and [" . $dumper->describeValue($second) .
+ "] should not be the same object");
+ return $this->assert(
+ new falseExpectation(),
+ SimpleTestCompatibility::isReference($first, $second),
+ $message);
+ }
+
+ /**
+ * Sends pass if the test condition resolves true,
+ * a fail otherwise.
+ * @param $condition Condition to test true.
+ * @param $message Message to display.
+ * @public
+ */
+ function assertTrue($condition, $message = "%s") {
+ parent::assert(new TrueExpectation(), $condition, $message);
+ }
+
+ /**
+ * Sends pass if the test condition resolves false,
+ * a fail otherwise.
+ * @param $condition Condition to test false.
+ * @param $message Message to display.
+ * @public
+ */
+ function assertFalse($condition, $message = "%s") {
+ parent::assert(new FalseExpectation(), $condition, $message);
+ }
+
+ /**
+ * Tests a regex match. Needs refactoring.
+ * @param $pattern Regex to match.
+ * @param $subject String to search in.
+ * @param $message Message to display.
+ * @public
+ */
+ function assertRegExp($pattern, $subject, $message = "%s") {
+ $this->assert(new PatternExpectation($pattern), $subject, $message);
+ }
+
+ /**
+ * Tests the type of a value.
+ * @param $value Value to take type of.
+ * @param $type Hoped for type.
+ * @param $message Message to display.
+ * @public
+ */
+ function assertType($value, $type, $message = "%s") {
+ parent::assert(new TrueExpectation(), gettype($value) == strtolower($type), $message);
+ }
+
+ /**
+ * Sets equality operation to act as a simple equal
+ * comparison only, allowing a broader range of
+ * matches.
+ * @param $loosely_typed True for broader comparison.
+ * @public
+ */
+ function setLooselyTyped($loosely_typed) {
+ $this->_loosely_typed = $loosely_typed;
+ }
+
+ /**
+ * For progress indication during
+ * a test amongst other things.
+ * @return Usually one.
+ * @public
+ */
+ function countTestCases() {
+ return $this->getSize();
+ }
+
+ /**
+ * Accessor for name, normally just the class
+ * name.
+ * @public
+ */
+ function getName() {
+ return $this->getLabel();
+ }
+
+ /**
+ * Does nothing. For compatibility only.
+ * @param $name Dummy
+ * @public
+ */
+ function setName($name) {
+ }
+ }
+?>
diff --git a/site/vendors/simpletest/extensions/phpunit_test_case.php b/site/vendors/simpletest/extensions/phpunit_test_case.php
new file mode 100644
index 0000000..e038a49
--- /dev/null
+++ b/site/vendors/simpletest/extensions/phpunit_test_case.php
@@ -0,0 +1,96 @@
+<?php
+ /**
+ * adapter for SimpleTest to use PHPUnit test cases
+ * @package SimpleTest
+ * @subpackage Extensions
+ * @version $Id: phpunit_test_case.php 1530 2007-06-04 23:35:45Z lastcraft $
+ */
+
+ /**#@+
+ * include SimpleTest files
+ */
+ require_once(dirname(__FILE__) . '/../unit_tester.php');
+ require_once(dirname(__FILE__) . '/../expectation.php');
+ /**#@-*/
+
+ /**
+ * Adapter for sourceforge PHPUnit test case to allow
+ * legacy test cases to be used with SimpleTest.
+ * @package SimpleTest
+ * @subpackage Extensions
+ */
+ class TestCase extends SimpleTestCase {
+
+ /**
+ * Constructor. Sets the test name.
+ * @param $label Test name to display.
+ * @public
+ */
+ function TestCase($label = false) {
+ $this->SimpleTestCase($label);
+ }
+
+ /**
+ * Sends pass if the test condition resolves true,
+ * a fail otherwise.
+ * @param $condition Condition to test true.
+ * @param $message Message to display.
+ * @public
+ */
+ function assert($condition, $message = false) {
+ parent::assert(new TrueExpectation(), $condition, $message);
+ }
+
+ /**
+ * Will test straight equality if set to loose
+ * typing, or identity if not.
+ * @param $first First value.
+ * @param $second Comparison value.
+ * @param $message Message to display.
+ * @public
+ */
+ function assertEquals($first, $second, $message = false) {
+ parent::assert(new EqualExpectation($first), $second, $message);
+ }
+
+ /**
+ * Simple string equality.
+ * @param $first First value.
+ * @param $second Comparison value.
+ * @param $message Message to display.
+ * @public
+ */
+ function assertEqualsMultilineStrings($first, $second, $message = false) {
+ parent::assert(new EqualExpectation($first), $second, $message);
+ }
+
+ /**
+ * Tests a regex match.
+ * @param $pattern Regex to match.
+ * @param $subject String to search in.
+ * @param $message Message to display.
+ * @public
+ */
+ function assertRegexp($pattern, $subject, $message = false) {
+ parent::assert(new PatternExpectation($pattern), $subject, $message);
+ }
+
+ /**
+ * Sends an error which we interpret as a fail
+ * with a different message for compatibility.
+ * @param $message Message to display.
+ * @public
+ */
+ function error($message) {
+ parent::fail("Error triggered [$message]");
+ }
+
+ /**
+ * Accessor for name.
+ * @public
+ */
+ function name() {
+ return $this->getLabel();
+ }
+ }
+?>
diff --git a/site/vendors/simpletest/extensions/testdox.php b/site/vendors/simpletest/extensions/testdox.php
new file mode 100644
index 0000000..7db7c87
--- /dev/null
+++ b/site/vendors/simpletest/extensions/testdox.php
@@ -0,0 +1,42 @@
+<?php
+
+class TestDoxReporter extends SimpleReporter
+{
+ var $_test_case_pattern = '/^TestOf(.*)$/';
+
+ function TestDoxReporter($test_case_pattern = '/^TestOf(.*)$/') {
+ parent::SimpleScorer();
+ $this->_test_case_pattern = empty($test_case_pattern) ? '/^(.*)$/' : $test_case_pattern;
+ }
+
+ function paintCaseStart($test_name) {
+ preg_match($this->_test_case_pattern, $test_name, $matches);
+ if (!empty($matches[1])) {
+ echo $matches[1] . "\n";
+ } else {
+ echo $test_name . "\n";
+ }
+ }
+
+ function paintCaseEnd() {
+ echo "\n";
+ }
+
+ function paintMethodStart($test_name) {
+ if (!preg_match('/^test(.*)$/i', $test_name, $matches)) {
+ return;
+ }
+ $test_name = $matches[1];
+
+ $test_name = preg_replace('/([A-Z])([A-Z])/', '$1 $2', $test_name);
+ echo '- ' . strtolower(preg_replace('/([a-zA-Z])([A-Z0-9])/', '$1 $2', $test_name));
+ }
+
+ function paintMethodEnd() {
+ echo "\n";
+ }
+
+ function paintFail() {
+ echo " [FAILED]";
+ }
+}
diff --git a/site/vendors/simpletest/extensions/testdox/test.php b/site/vendors/simpletest/extensions/testdox/test.php
new file mode 100644
index 0000000..82c5b7d
--- /dev/null
+++ b/site/vendors/simpletest/extensions/testdox/test.php
@@ -0,0 +1,108 @@
+<?php
+// $Id: test.php 1641 2008-01-22 20:13:52Z pp11 $
+require_once dirname(__FILE__) . '/../../autorun.php';
+require_once dirname(__FILE__) . '/../testdox.php';
+
+// uncomment to see test dox in action
+//SimpleTest::prefer(new TestDoxReporter());
+
+class TestOfTestDoxReporter extends UnitTestCase
+{
+ function testIsAnInstanceOfSimpleScorerAndReporter() {
+ $dox = new TestDoxReporter();
+ $this->assertIsA($dox, 'SimpleScorer');
+ $this->assertIsA($dox, 'SimpleReporter');
+ }
+
+ function testOutputsNameOfTestCase() {
+ $dox = new TestDoxReporter();
+ ob_start();
+ $dox->paintCaseStart('TestOfTestDoxReporter');
+ $buffer = ob_get_clean();
+ $this->assertWantedPattern('/^TestDoxReporter/', $buffer);
+ }
+
+ function testOutputOfTestCaseNameFilteredByConstructParameter() {
+ $dox = new TestDoxReporter('/^(.*)Test$/');
+ ob_start();
+ $dox->paintCaseStart('SomeGreatWidgetTest');
+ $buffer = ob_get_clean();
+ $this->assertWantedPattern('/^SomeGreatWidget/', $buffer);
+ }
+
+ function testIfTest_case_patternIsEmptyAssumeEverythingMatches() {
+ $dox = new TestDoxReporter('');
+ ob_start();
+ $dox->paintCaseStart('TestOfTestDoxReporter');
+ $buffer = ob_get_clean();
+ $this->assertWantedPattern('/^TestOfTestDoxReporter/', $buffer);
+ }
+
+ function testEmptyLineInsertedWhenCaseEnds() {
+ $dox = new TestDoxReporter();
+ ob_start();
+ $dox->paintCaseEnd('TestOfTestDoxReporter');
+ $buffer = ob_get_clean();
+ $this->assertEqual("\n", $buffer);
+ }
+
+ function testPaintsTestMethodInTestDoxFormat() {
+ $dox = new TestDoxReporter();
+ ob_start();
+ $dox->paintMethodStart('testSomeGreatTestCase');
+ $buffer = ob_get_clean();
+ $this->assertEqual("- some great test case", $buffer);
+ unset($buffer);
+
+ $random = rand(100, 200);
+ ob_start();
+ $dox->paintMethodStart("testRandomNumberIs{$random}");
+ $buffer = ob_get_clean();
+ $this->assertEqual("- random number is {$random}", $buffer);
+ }
+
+ function testDoesNotOutputAnythingOnNoneTestMethods() {
+ $dox = new TestDoxReporter();
+ ob_start();
+ $dox->paintMethodStart('nonMatchingMethod');
+ $buffer = ob_get_clean();
+ $this->assertEqual('', $buffer);
+ }
+
+ function testPaintMethodAddLineBreak() {
+ $dox = new TestDoxReporter();
+ ob_start();
+ $dox->paintMethodEnd('someMethod');
+ $buffer = ob_get_clean();
+ $this->assertEqual("\n", $buffer);
+ $this->assertNoErrors();
+ }
+
+ function testProperlySpacesSingleLettersInMethodName() {
+ $dox = new TestDoxReporter();
+ ob_start();
+ $dox->paintMethodStart('testAVerySimpleAgainAVerySimpleMethod');
+ $buffer = ob_get_clean();
+ $this->assertEqual('- a very simple again a very simple method', $buffer);
+ }
+
+ function testOnFailureThisPrintsFailureNotice() {
+ $dox = new TestDoxReporter();
+ ob_start();
+ $dox->paintFail();
+ $buffer = ob_get_clean();
+ $this->assertEqual(' [FAILED]', $buffer);
+ }
+
+ function testWhenMatchingMethodNamesTestPrefixIsCaseInsensitive() {
+ $dox = new TestDoxReporter();
+ ob_start();
+ $dox->paintMethodStart('TESTSupportsAllUppercaseTestPrefixEvenThoughIDoNotKnowWhyYouWouldDoThat');
+ $buffer = ob_get_clean();
+ $this->assertEqual(
+ '- supports all uppercase test prefix even though i do not know why you would do that',
+ $buffer
+ );
+ }
+}
+
diff --git a/site/vendors/simpletest/form.php b/site/vendors/simpletest/form.php
new file mode 100644
index 0000000..cbef663
--- /dev/null
+++ b/site/vendors/simpletest/form.php
@@ -0,0 +1,355 @@
+<?php
+/**
+ * Base include file for SimpleTest.
+ * @package SimpleTest
+ * @subpackage WebTester
+ * @version $Id: form.php 1672 2008-03-02 04:47:34Z edwardzyang $
+ */
+
+/**#@+
+ * include SimpleTest files
+ */
+require_once(dirname(__FILE__) . '/tag.php');
+require_once(dirname(__FILE__) . '/encoding.php');
+require_once(dirname(__FILE__) . '/selector.php');
+/**#@-*/
+
+/**
+ * Form tag class to hold widget values.
+ * @package SimpleTest
+ * @subpackage WebTester
+ */
+class SimpleForm {
+ var $_method;
+ var $_action;
+ var $_encoding;
+ var $_default_target;
+ var $_id;
+ var $_buttons;
+ var $_images;
+ var $_widgets;
+ var $_radios;
+ var $_checkboxes;
+
+ /**
+ * Starts with no held controls/widgets.
+ * @param SimpleTag $tag Form tag to read.
+ * @param SimplePage $page Holding page.
+ */
+ function SimpleForm($tag, &$page) {
+ $this->_method = $tag->getAttribute('method');
+ $this->_action = $this->_createAction($tag->getAttribute('action'), $page);
+ $this->_encoding = $this->_setEncodingClass($tag);
+ $this->_default_target = false;
+ $this->_id = $tag->getAttribute('id');
+ $this->_buttons = array();
+ $this->_images = array();
+ $this->_widgets = array();
+ $this->_radios = array();
+ $this->_checkboxes = array();
+ }
+
+ /**
+ * Creates the request packet to be sent by the form.
+ * @param SimpleTag $tag Form tag to read.
+ * @return string Packet class.
+ * @access private
+ */
+ function _setEncodingClass($tag) {
+ if (strtolower($tag->getAttribute('method')) == 'post') {
+ if (strtolower($tag->getAttribute('enctype')) == 'multipart/form-data') {
+ return 'SimpleMultipartEncoding';
+ }
+ return 'SimplePostEncoding';
+ }
+ return 'SimpleGetEncoding';
+ }
+
+ /**
+ * Sets the frame target within a frameset.
+ * @param string $frame Name of frame.
+ * @access public
+ */
+ function setDefaultTarget($frame) {
+ $this->_default_target = $frame;
+ }
+
+ /**
+ * Accessor for method of form submission.
+ * @return string Either get or post.
+ * @access public
+ */
+ function getMethod() {
+ return ($this->_method ? strtolower($this->_method) : 'get');
+ }
+
+ /**
+ * Combined action attribute with current location
+ * to get an absolute form target.
+ * @param string $action Action attribute from form tag.
+ * @param SimpleUrl $base Page location.
+ * @return SimpleUrl Absolute form target.
+ */
+ function _createAction($action, &$page) {
+ if (($action === '') || ($action === false)) {
+ return $page->expandUrl($page->getUrl());
+ }
+ return $page->expandUrl(new SimpleUrl($action));;
+ }
+
+ /**
+ * Absolute URL of the target.
+ * @return SimpleUrl URL target.
+ * @access public
+ */
+ function getAction() {
+ $url = $this->_action;
+ if ($this->_default_target && ! $url->getTarget()) {
+ $url->setTarget($this->_default_target);
+ }
+ return $url;
+ }
+
+ /**
+ * Creates the encoding for the current values in the
+ * form.
+ * @return SimpleFormEncoding Request to submit.
+ * @access private
+ */
+ function _encode() {
+ $class = $this->_encoding;
+ $encoding = new $class();
+ for ($i = 0, $count = count($this->_widgets); $i < $count; $i++) {
+ $this->_widgets[$i]->write($encoding);
+ }
+ return $encoding;
+ }
+
+ /**
+ * ID field of form for unique identification.
+ * @return string Unique tag ID.
+ * @access public
+ */
+ function getId() {
+ return $this->_id;
+ }
+
+ /**
+ * Adds a tag contents to the form.
+ * @param SimpleWidget $tag Input tag to add.
+ * @access public
+ */
+ function addWidget(&$tag) {
+ if (strtolower($tag->getAttribute('type')) == 'submit') {
+ $this->_buttons[] = &$tag;
+ } elseif (strtolower($tag->getAttribute('type')) == 'image') {
+ $this->_images[] = &$tag;
+ } elseif ($tag->getName()) {
+ $this->_setWidget($tag);
+ }
+ }
+
+ /**
+ * Sets the widget into the form, grouping radio
+ * buttons if any.
+ * @param SimpleWidget $tag Incoming form control.
+ * @access private
+ */
+ function _setWidget(&$tag) {
+ if (strtolower($tag->getAttribute('type')) == 'radio') {
+ $this->_addRadioButton($tag);
+ } elseif (strtolower($tag->getAttribute('type')) == 'checkbox') {
+ $this->_addCheckbox($tag);
+ } else {
+ $this->_widgets[] = &$tag;
+ }
+ }
+
+ /**
+ * Adds a radio button, building a group if necessary.
+ * @param SimpleRadioButtonTag $tag Incoming form control.
+ * @access private
+ */
+ function _addRadioButton(&$tag) {
+ if (! isset($this->_radios[$tag->getName()])) {
+ $this->_widgets[] = &new SimpleRadioGroup();
+ $this->_radios[$tag->getName()] = count($this->_widgets) - 1;
+ }
+ $this->_widgets[$this->_radios[$tag->getName()]]->addWidget($tag);
+ }
+
+ /**
+ * Adds a checkbox, making it a group on a repeated name.
+ * @param SimpleCheckboxTag $tag Incoming form control.
+ * @access private
+ */
+ function _addCheckbox(&$tag) {
+ if (! isset($this->_checkboxes[$tag->getName()])) {
+ $this->_widgets[] = &$tag;
+ $this->_checkboxes[$tag->getName()] = count($this->_widgets) - 1;
+ } else {
+ $index = $this->_checkboxes[$tag->getName()];
+ if (! SimpleTestCompatibility::isA($this->_widgets[$index], 'SimpleCheckboxGroup')) {
+ $previous = &$this->_widgets[$index];
+ $this->_widgets[$index] = &new SimpleCheckboxGroup();
+ $this->_widgets[$index]->addWidget($previous);
+ }
+ $this->_widgets[$index]->addWidget($tag);
+ }
+ }
+
+ /**
+ * Extracts current value from form.
+ * @param SimpleSelector $selector Criteria to apply.
+ * @return string/array Value(s) as string or null
+ * if not set.
+ * @access public
+ */
+ function getValue($selector) {
+ for ($i = 0, $count = count($this->_widgets); $i < $count; $i++) {
+ if ($selector->isMatch($this->_widgets[$i])) {
+ return $this->_widgets[$i]->getValue();
+ }
+ }
+ foreach ($this->_buttons as $button) {
+ if ($selector->isMatch($button)) {
+ return $button->getValue();
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Sets a widget value within the form.
+ * @param SimpleSelector $selector Criteria to apply.
+ * @param string $value Value to input into the widget.
+ * @return boolean True if value is legal, false
+ * otherwise. If the field is not
+ * present, nothing will be set.
+ * @access public
+ */
+ function setField($selector, $value, $position=false) {
+ $success = false;
+ $_position = 0;
+ for ($i = 0, $count = count($this->_widgets); $i < $count; $i++) {
+ if ($selector->isMatch($this->_widgets[$i])) {
+ $_position++;
+ if ($position === false or $_position === (int)$position) {
+ if ($this->_widgets[$i]->setValue($value)) {
+ $success = true;
+ }
+ }
+ }
+ }
+ return $success;
+ }
+
+ /**
+ * Used by the page object to set widgets labels to
+ * external label tags.
+ * @param SimpleSelector $selector Criteria to apply.
+ * @access public
+ */
+ function attachLabelBySelector($selector, $label) {
+ for ($i = 0, $count = count($this->_widgets); $i < $count; $i++) {
+ if ($selector->isMatch($this->_widgets[$i])) {
+ if (method_exists($this->_widgets[$i], 'setLabel')) {
+ $this->_widgets[$i]->setLabel($label);
+ return;
+ }
+ }
+ }
+ }
+
+ /**
+ * Test to see if a form has a submit button.
+ * @param SimpleSelector $selector Criteria to apply.
+ * @return boolean True if present.
+ * @access public
+ */
+ function hasSubmit($selector) {
+ foreach ($this->_buttons as $button) {
+ if ($selector->isMatch($button)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Test to see if a form has an image control.
+ * @param SimpleSelector $selector Criteria to apply.
+ * @return boolean True if present.
+ * @access public
+ */
+ function hasImage($selector) {
+ foreach ($this->_images as $image) {
+ if ($selector->isMatch($image)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Gets the submit values for a selected button.
+ * @param SimpleSelector $selector Criteria to apply.
+ * @param hash $additional Additional data for the form.
+ * @return SimpleEncoding Submitted values or false
+ * if there is no such button
+ * in the form.
+ * @access public
+ */
+ function submitButton($selector, $additional = false) {
+ $additional = $additional ? $additional : array();
+ foreach ($this->_buttons as $button) {
+ if ($selector->isMatch($button)) {
+ $encoding = $this->_encode();
+ $button->write($encoding);
+ if ($additional) {
+ $encoding->merge($additional);
+ }
+ return $encoding;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Gets the submit values for an image.
+ * @param SimpleSelector $selector Criteria to apply.
+ * @param integer $x X-coordinate of click.
+ * @param integer $y Y-coordinate of click.
+ * @param hash $additional Additional data for the form.
+ * @return SimpleEncoding Submitted values or false
+ * if there is no such button in the
+ * form.
+ * @access public
+ */
+ function submitImage($selector, $x, $y, $additional = false) {
+ $additional = $additional ? $additional : array();
+ foreach ($this->_images as $image) {
+ if ($selector->isMatch($image)) {
+ $encoding = $this->_encode();
+ $image->write($encoding, $x, $y);
+ if ($additional) {
+ $encoding->merge($additional);
+ }
+ return $encoding;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Simply submits the form without the submit button
+ * value. Used when there is only one button or it
+ * is unimportant.
+ * @return hash Submitted values.
+ * @access public
+ */
+ function submit() {
+ return $this->_encode();
+ }
+}
+?> \ No newline at end of file
diff --git a/site/vendors/simpletest/frames.php b/site/vendors/simpletest/frames.php
new file mode 100644
index 0000000..ec098df
--- /dev/null
+++ b/site/vendors/simpletest/frames.php
@@ -0,0 +1,596 @@
+<?php
+/**
+ * Base include file for SimpleTest
+ * @package SimpleTest
+ * @subpackage WebTester
+ * @version $Id: frames.php 1672 2008-03-02 04:47:34Z edwardzyang $
+ */
+
+/**#@+
+ * include other SimpleTest class files
+ */
+require_once(dirname(__FILE__) . '/page.php');
+require_once(dirname(__FILE__) . '/user_agent.php');
+/**#@-*/
+
+/**
+ * A composite page. Wraps a frameset page and
+ * adds subframes. The original page will be
+ * mostly ignored. Implements the SimplePage
+ * interface so as to be interchangeable.
+ * @package SimpleTest
+ * @subpackage WebTester
+ */
+class SimpleFrameset {
+ var $_frameset;
+ var $_frames;
+ var $_focus;
+ var $_names;
+
+ /**
+ * Stashes the frameset page. Will make use of the
+ * browser to fetch the sub frames recursively.
+ * @param SimplePage $page Frameset page.
+ */
+ function SimpleFrameset(&$page) {
+ $this->_frameset = &$page;
+ $this->_frames = array();
+ $this->_focus = false;
+ $this->_names = array();
+ }
+
+ /**
+ * Adds a parsed page to the frameset.
+ * @param SimplePage $page Frame page.
+ * @param string $name Name of frame in frameset.
+ * @access public
+ */
+ function addFrame(&$page, $name = false) {
+ $this->_frames[] = &$page;
+ if ($name) {
+ $this->_names[$name] = count($this->_frames) - 1;
+ }
+ }
+
+ /**
+ * Replaces existing frame with another. If the
+ * frame is nested, then the call is passed down
+ * one level.
+ * @param array $path Path of frame in frameset.
+ * @param SimplePage $page Frame source.
+ * @access public
+ */
+ function setFrame($path, &$page) {
+ $name = array_shift($path);
+ if (isset($this->_names[$name])) {
+ $index = $this->_names[$name];
+ } else {
+ $index = $name - 1;
+ }
+ if (count($path) == 0) {
+ $this->_frames[$index] = &$page;
+ return;
+ }
+ $this->_frames[$index]->setFrame($path, $page);
+ }
+
+ /**
+ * Accessor for current frame focus. Will be
+ * false if no frame has focus. Will have the nested
+ * frame focus if any.
+ * @return array Labels or indexes of nested frames.
+ * @access public
+ */
+ function getFrameFocus() {
+ if ($this->_focus === false) {
+ return array();
+ }
+ return array_merge(
+ array($this->_getPublicNameFromIndex($this->_focus)),
+ $this->_frames[$this->_focus]->getFrameFocus());
+ }
+
+ /**
+ * Turns an internal array index into the frames list
+ * into a public name, or if none, then a one offset
+ * index.
+ * @param integer $subject Internal index.
+ * @return integer/string Public name.
+ * @access private
+ */
+ function _getPublicNameFromIndex($subject) {
+ foreach ($this->_names as $name => $index) {
+ if ($subject == $index) {
+ return $name;
+ }
+ }
+ return $subject + 1;
+ }
+
+ /**
+ * Sets the focus by index. The integer index starts from 1.
+ * If already focused and the target frame also has frames,
+ * then the nested frame will be focused.
+ * @param integer $choice Chosen frame.
+ * @return boolean True if frame exists.
+ * @access public
+ */
+ function setFrameFocusByIndex($choice) {
+ if (is_integer($this->_focus)) {
+ if ($this->_frames[$this->_focus]->hasFrames()) {
+ return $this->_frames[$this->_focus]->setFrameFocusByIndex($choice);
+ }
+ }
+ if (($choice < 1) || ($choice > count($this->_frames))) {
+ return false;
+ }
+ $this->_focus = $choice - 1;
+ return true;
+ }
+
+ /**
+ * Sets the focus by name. If already focused and the
+ * target frame also has frames, then the nested frame
+ * will be focused.
+ * @param string $name Chosen frame.
+ * @return boolean True if frame exists.
+ * @access public
+ */
+ function setFrameFocus($name) {
+ if (is_integer($this->_focus)) {
+ if ($this->_frames[$this->_focus]->hasFrames()) {
+ return $this->_frames[$this->_focus]->setFrameFocus($name);
+ }
+ }
+ if (in_array($name, array_keys($this->_names))) {
+ $this->_focus = $this->_names[$name];
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Clears the frame focus.
+ * @access public
+ */
+ function clearFrameFocus() {
+ $this->_focus = false;
+ $this->_clearNestedFramesFocus();
+ }
+
+ /**
+ * Clears the frame focus for any nested frames.
+ * @access private
+ */
+ function _clearNestedFramesFocus() {
+ for ($i = 0; $i < count($this->_frames); $i++) {
+ $this->_frames[$i]->clearFrameFocus();
+ }
+ }
+
+ /**
+ * Test for the presence of a frameset.
+ * @return boolean Always true.
+ * @access public
+ */
+ function hasFrames() {
+ return true;
+ }
+
+ /**
+ * Accessor for frames information.
+ * @return array/string Recursive hash of frame URL strings.
+ * The key is either a numerical
+ * index or the name attribute.
+ * @access public
+ */
+ function getFrames() {
+ $report = array();
+ for ($i = 0; $i < count($this->_frames); $i++) {
+ $report[$this->_getPublicNameFromIndex($i)] =
+ $this->_frames[$i]->getFrames();
+ }
+ return $report;
+ }
+
+ /**
+ * Accessor for raw text of either all the pages or
+ * the frame in focus.
+ * @return string Raw unparsed content.
+ * @access public
+ */
+ function getRaw() {
+ if (is_integer($this->_focus)) {
+ return $this->_frames[$this->_focus]->getRaw();
+ }
+ $raw = '';
+ for ($i = 0; $i < count($this->_frames); $i++) {
+ $raw .= $this->_frames[$i]->getRaw();
+ }
+ return $raw;
+ }
+
+ /**
+ * Accessor for plain text of either all the pages or
+ * the frame in focus.
+ * @return string Plain text content.
+ * @access public
+ */
+ function getText() {
+ if (is_integer($this->_focus)) {
+ return $this->_frames[$this->_focus]->getText();
+ }
+ $raw = '';
+ for ($i = 0; $i < count($this->_frames); $i++) {
+ $raw .= ' ' . $this->_frames[$i]->getText();
+ }
+ return trim($raw);
+ }
+
+ /**
+ * Accessor for last error.
+ * @return string Error from last response.
+ * @access public
+ */
+ function getTransportError() {
+ if (is_integer($this->_focus)) {
+ return $this->_frames[$this->_focus]->getTransportError();
+ }
+ return $this->_frameset->getTransportError();
+ }
+
+ /**
+ * Request method used to fetch this frame.
+ * @return string GET, POST or HEAD.
+ * @access public
+ */
+ function getMethod() {
+ if (is_integer($this->_focus)) {
+ return $this->_frames[$this->_focus]->getMethod();
+ }
+ return $this->_frameset->getMethod();
+ }
+
+ /**
+ * Original resource name.
+ * @return SimpleUrl Current url.
+ * @access public
+ */
+ function getUrl() {
+ if (is_integer($this->_focus)) {
+ $url = $this->_frames[$this->_focus]->getUrl();
+ $url->setTarget($this->_getPublicNameFromIndex($this->_focus));
+ } else {
+ $url = $this->_frameset->getUrl();
+ }
+ return $url;
+ }
+
+ /**
+ * Page base URL.
+ * @return SimpleUrl Current url.
+ * @access public
+ */
+ function getBaseUrl() {
+ if (is_integer($this->_focus)) {
+ $url = $this->_frames[$this->_focus]->getBaseUrl();
+ } else {
+ $url = $this->_frameset->getBaseUrl();
+ }
+ return $url;
+ }
+
+ /**
+ * Expands expandomatic URLs into fully qualified
+ * URLs for the frameset page.
+ * @param SimpleUrl $url Relative URL.
+ * @return SimpleUrl Absolute URL.
+ * @access public
+ */
+ function expandUrl($url) {
+ return $this->_frameset->expandUrl($url);
+ }
+
+ /**
+ * Original request data.
+ * @return mixed Sent content.
+ * @access public
+ */
+ function getRequestData() {
+ if (is_integer($this->_focus)) {
+ return $this->_frames[$this->_focus]->getRequestData();
+ }
+ return $this->_frameset->getRequestData();
+ }
+
+ /**
+ * Accessor for current MIME type.
+ * @return string MIME type as string; e.g. 'text/html'
+ * @access public
+ */
+ function getMimeType() {
+ if (is_integer($this->_focus)) {
+ return $this->_frames[$this->_focus]->getMimeType();
+ }
+ return $this->_frameset->getMimeType();
+ }
+
+ /**
+ * Accessor for last response code.
+ * @return integer Last HTTP response code received.
+ * @access public
+ */
+ function getResponseCode() {
+ if (is_integer($this->_focus)) {
+ return $this->_frames[$this->_focus]->getResponseCode();
+ }
+ return $this->_frameset->getResponseCode();
+ }
+
+ /**
+ * Accessor for last Authentication type. Only valid
+ * straight after a challenge (401).
+ * @return string Description of challenge type.
+ * @access public
+ */
+ function getAuthentication() {
+ if (is_integer($this->_focus)) {
+ return $this->_frames[$this->_focus]->getAuthentication();
+ }
+ return $this->_frameset->getAuthentication();
+ }
+
+ /**
+ * Accessor for last Authentication realm. Only valid
+ * straight after a challenge (401).
+ * @return string Name of security realm.
+ * @access public
+ */
+ function getRealm() {
+ if (is_integer($this->_focus)) {
+ return $this->_frames[$this->_focus]->getRealm();
+ }
+ return $this->_frameset->getRealm();
+ }
+
+ /**
+ * Accessor for outgoing header information.
+ * @return string Header block.
+ * @access public
+ */
+ function getRequest() {
+ if (is_integer($this->_focus)) {
+ return $this->_frames[$this->_focus]->getRequest();
+ }
+ return $this->_frameset->getRequest();
+ }
+
+ /**
+ * Accessor for raw header information.
+ * @return string Header block.
+ * @access public
+ */
+ function getHeaders() {
+ if (is_integer($this->_focus)) {
+ return $this->_frames[$this->_focus]->getHeaders();
+ }
+ return $this->_frameset->getHeaders();
+ }
+
+ /**
+ * Accessor for parsed title.
+ * @return string Title or false if no title is present.
+ * @access public
+ */
+ function getTitle() {
+ return $this->_frameset->getTitle();
+ }
+
+ /**
+ * Accessor for a list of all fixed links.
+ * @return array List of urls as strings.
+ * @access public
+ */
+ function getUrls() {
+ if (is_integer($this->_focus)) {
+ return $this->_frames[$this->_focus]->getUrls();
+ }
+ $urls = array();
+ foreach ($this->_frames as $frame) {
+ $urls = array_merge($urls, $frame->getUrls());
+ }
+ return array_values(array_unique($urls));
+ }
+
+ /**
+ * Accessor for URLs by the link label. Label will match
+ * regardess of whitespace issues and case.
+ * @param string $label Text of link.
+ * @return array List of links with that label.
+ * @access public
+ */
+ function getUrlsByLabel($label) {
+ if (is_integer($this->_focus)) {
+ return $this->_tagUrlsWithFrame(
+ $this->_frames[$this->_focus]->getUrlsByLabel($label),
+ $this->_focus);
+ }
+ $urls = array();
+ foreach ($this->_frames as $index => $frame) {
+ $urls = array_merge(
+ $urls,
+ $this->_tagUrlsWithFrame(
+ $frame->getUrlsByLabel($label),
+ $index));
+ }
+ return $urls;
+ }
+
+ /**
+ * Accessor for a URL by the id attribute. If in a frameset
+ * then the first link found with that ID attribute is
+ * returned only. Focus on a frame if you want one from
+ * a specific part of the frameset.
+ * @param string $id Id attribute of link.
+ * @return string URL with that id.
+ * @access public
+ */
+ function getUrlById($id) {
+ foreach ($this->_frames as $index => $frame) {
+ if ($url = $frame->getUrlById($id)) {
+ if (! $url->gettarget()) {
+ $url->setTarget($this->_getPublicNameFromIndex($index));
+ }
+ return $url;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Attaches the intended frame index to a list of URLs.
+ * @param array $urls List of SimpleUrls.
+ * @param string $frame Name of frame or index.
+ * @return array List of tagged URLs.
+ * @access private
+ */
+ function _tagUrlsWithFrame($urls, $frame) {
+ $tagged = array();
+ foreach ($urls as $url) {
+ if (! $url->getTarget()) {
+ $url->setTarget($this->_getPublicNameFromIndex($frame));
+ }
+ $tagged[] = $url;
+ }
+ return $tagged;
+ }
+
+ /**
+ * Finds a held form by button label. Will only
+ * search correctly built forms.
+ * @param SimpleSelector $selector Button finder.
+ * @return SimpleForm Form object containing
+ * the button.
+ * @access public
+ */
+ function &getFormBySubmit($selector) {
+ $form = &$this->_findForm('getFormBySubmit', $selector);
+ return $form;
+ }
+
+ /**
+ * Finds a held form by image using a selector.
+ * Will only search correctly built forms. The first
+ * form found either within the focused frame, or
+ * across frames, will be the one returned.
+ * @param SimpleSelector $selector Image finder.
+ * @return SimpleForm Form object containing
+ * the image.
+ * @access public
+ */
+ function &getFormByImage($selector) {
+ $form = &$this->_findForm('getFormByImage', $selector);
+ return $form;
+ }
+
+ /**
+ * Finds a held form by the form ID. A way of
+ * identifying a specific form when we have control
+ * of the HTML code. The first form found
+ * either within the focused frame, or across frames,
+ * will be the one returned.
+ * @param string $id Form label.
+ * @return SimpleForm Form object containing the matching ID.
+ * @access public
+ */
+ function &getFormById($id) {
+ $form = &$this->_findForm('getFormById', $id);
+ return $form;
+ }
+
+ /**
+ * General form finder. Will search all the frames or
+ * just the one in focus.
+ * @param string $method Method to use to find in a page.
+ * @param string $attribute Label, name or ID.
+ * @return SimpleForm Form object containing the matching ID.
+ * @access private
+ */
+ function &_findForm($method, $attribute) {
+ if (is_integer($this->_focus)) {
+ $form = &$this->_findFormInFrame(
+ $this->_frames[$this->_focus],
+ $this->_focus,
+ $method,
+ $attribute);
+ return $form;
+ }
+ for ($i = 0; $i < count($this->_frames); $i++) {
+ $form = &$this->_findFormInFrame(
+ $this->_frames[$i],
+ $i,
+ $method,
+ $attribute);
+ if ($form) {
+ return $form;
+ }
+ }
+ $null = null;
+ return $null;
+ }
+
+ /**
+ * Finds a form in a page using a form finding method. Will
+ * also tag the form with the frame name it belongs in.
+ * @param SimplePage $page Page content of frame.
+ * @param integer $index Internal frame representation.
+ * @param string $method Method to use to find in a page.
+ * @param string $attribute Label, name or ID.
+ * @return SimpleForm Form object containing the matching ID.
+ * @access private
+ */
+ function &_findFormInFrame(&$page, $index, $method, $attribute) {
+ $form = &$this->_frames[$index]->$method($attribute);
+ if (isset($form)) {
+ $form->setDefaultTarget($this->_getPublicNameFromIndex($index));
+ }
+ return $form;
+ }
+
+ /**
+ * Sets a field on each form in which the field is
+ * available.
+ * @param SimpleSelector $selector Field finder.
+ * @param string $value Value to set field to.
+ * @return boolean True if value is valid.
+ * @access public
+ */
+ function setField($selector, $value) {
+ if (is_integer($this->_focus)) {
+ $this->_frames[$this->_focus]->setField($selector, $value);
+ } else {
+ for ($i = 0; $i < count($this->_frames); $i++) {
+ $this->_frames[$i]->setField($selector, $value);
+ }
+ }
+ }
+
+ /**
+ * Accessor for a form element value within a page.
+ * @param SimpleSelector $selector Field finder.
+ * @return string/boolean A string if the field is
+ * present, false if unchecked
+ * and null if missing.
+ * @access public
+ */
+ function getField($selector) {
+ for ($i = 0; $i < count($this->_frames); $i++) {
+ $value = $this->_frames[$i]->getField($selector);
+ if (isset($value)) {
+ return $value;
+ }
+ }
+ return null;
+ }
+}
+?> \ No newline at end of file
diff --git a/site/vendors/simpletest/http.php b/site/vendors/simpletest/http.php
new file mode 100644
index 0000000..e6c6e89
--- /dev/null
+++ b/site/vendors/simpletest/http.php
@@ -0,0 +1,624 @@
+<?php
+/**
+ * base include file for SimpleTest
+ * @package SimpleTest
+ * @subpackage WebTester
+ * @version $Id: http.php 1722 2008-04-07 19:30:56Z lastcraft $
+ */
+
+/**#@+
+ * include other SimpleTest class files
+ */
+require_once(dirname(__FILE__) . '/socket.php');
+require_once(dirname(__FILE__) . '/cookies.php');
+require_once(dirname(__FILE__) . '/url.php');
+/**#@-*/
+
+/**
+ * Creates HTTP headers for the end point of
+ * a HTTP request.
+ * @package SimpleTest
+ * @subpackage WebTester
+ */
+class SimpleRoute {
+ var $_url;
+
+ /**
+ * Sets the target URL.
+ * @param SimpleUrl $url URL as object.
+ * @access public
+ */
+ function SimpleRoute($url) {
+ $this->_url = $url;
+ }
+
+ /**
+ * Resource name.
+ * @return SimpleUrl Current url.
+ * @access protected
+ */
+ function getUrl() {
+ return $this->_url;
+ }
+
+ /**
+ * Creates the first line which is the actual request.
+ * @param string $method HTTP request method, usually GET.
+ * @return string Request line content.
+ * @access protected
+ */
+ function _getRequestLine($method) {
+ return $method . ' ' . $this->_url->getPath() .
+ $this->_url->getEncodedRequest() . ' HTTP/1.0';
+ }
+
+ /**
+ * Creates the host part of the request.
+ * @return string Host line content.
+ * @access protected
+ */
+ function _getHostLine() {
+ $line = 'Host: ' . $this->_url->getHost();
+ if ($this->_url->getPort()) {
+ $line .= ':' . $this->_url->getPort();
+ }
+ return $line;
+ }
+
+ /**
+ * Opens a socket to the route.
+ * @param string $method HTTP request method, usually GET.
+ * @param integer $timeout Connection timeout.
+ * @return SimpleSocket New socket.
+ * @access public
+ */
+ function &createConnection($method, $timeout) {
+ $default_port = ('https' == $this->_url->getScheme()) ? 443 : 80;
+ $socket = &$this->_createSocket(
+ $this->_url->getScheme() ? $this->_url->getScheme() : 'http',
+ $this->_url->getHost(),
+ $this->_url->getPort() ? $this->_url->getPort() : $default_port,
+ $timeout);
+ if (! $socket->isError()) {
+ $socket->write($this->_getRequestLine($method) . "\r\n");
+ $socket->write($this->_getHostLine() . "\r\n");
+ $socket->write("Connection: close\r\n");
+ }
+ return $socket;
+ }
+
+ /**
+ * Factory for socket.
+ * @param string $scheme Protocol to use.
+ * @param string $host Hostname to connect to.
+ * @param integer $port Remote port.
+ * @param integer $timeout Connection timeout.
+ * @return SimpleSocket/SimpleSecureSocket New socket.
+ * @access protected
+ */
+ function &_createSocket($scheme, $host, $port, $timeout) {
+ if (in_array($scheme, array('https'))) {
+ $socket = &new SimpleSecureSocket($host, $port, $timeout);
+ } else {
+ $socket = &new SimpleSocket($host, $port, $timeout);
+ }
+ return $socket;
+ }
+}
+
+/**
+ * Creates HTTP headers for the end point of
+ * a HTTP request via a proxy server.
+ * @package SimpleTest
+ * @subpackage WebTester
+ */
+class SimpleProxyRoute extends SimpleRoute {
+ var $_proxy;
+ var $_username;
+ var $_password;
+
+ /**
+ * Stashes the proxy address.
+ * @param SimpleUrl $url URL as object.
+ * @param string $proxy Proxy URL.
+ * @param string $username Username for autentication.
+ * @param string $password Password for autentication.
+ * @access public
+ */
+ function SimpleProxyRoute($url, $proxy, $username = false, $password = false) {
+ $this->SimpleRoute($url);
+ $this->_proxy = $proxy;
+ $this->_username = $username;
+ $this->_password = $password;
+ }
+
+ /**
+ * Creates the first line which is the actual request.
+ * @param string $method HTTP request method, usually GET.
+ * @param SimpleUrl $url URL as object.
+ * @return string Request line content.
+ * @access protected
+ */
+ function _getRequestLine($method) {
+ $url = $this->getUrl();
+ $scheme = $url->getScheme() ? $url->getScheme() : 'http';
+ $port = $url->getPort() ? ':' . $url->getPort() : '';
+ return $method . ' ' . $scheme . '://' . $url->getHost() . $port .
+ $url->getPath() . $url->getEncodedRequest() . ' HTTP/1.0';
+ }
+
+ /**
+ * Creates the host part of the request.
+ * @param SimpleUrl $url URL as object.
+ * @return string Host line content.
+ * @access protected
+ */
+ function _getHostLine() {
+ $host = 'Host: ' . $this->_proxy->getHost();
+ $port = $this->_proxy->getPort() ? $this->_proxy->getPort() : 8080;
+ return "$host:$port";
+ }
+
+ /**
+ * Opens a socket to the route.
+ * @param string $method HTTP request method, usually GET.
+ * @param integer $timeout Connection timeout.
+ * @return SimpleSocket New socket.
+ * @access public
+ */
+ function &createConnection($method, $timeout) {
+ $socket = &$this->_createSocket(
+ $this->_proxy->getScheme() ? $this->_proxy->getScheme() : 'http',
+ $this->_proxy->getHost(),
+ $this->_proxy->getPort() ? $this->_proxy->getPort() : 8080,
+ $timeout);
+ if ($socket->isError()) {
+ return $socket;
+ }
+ $socket->write($this->_getRequestLine($method) . "\r\n");
+ $socket->write($this->_getHostLine() . "\r\n");
+ if ($this->_username && $this->_password) {
+ $socket->write('Proxy-Authorization: Basic ' .
+ base64_encode($this->_username . ':' . $this->_password) .
+ "\r\n");
+ }
+ $socket->write("Connection: close\r\n");
+ return $socket;
+ }
+}
+
+/**
+ * HTTP request for a web page. Factory for
+ * HttpResponse object.
+ * @package SimpleTest
+ * @subpackage WebTester
+ */
+class SimpleHttpRequest {
+ var $_route;
+ var $_encoding;
+ var $_headers;
+ var $_cookies;
+
+ /**
+ * Builds the socket request from the different pieces.
+ * These include proxy information, URL, cookies, headers,
+ * request method and choice of encoding.
+ * @param SimpleRoute $route Request route.
+ * @param SimpleFormEncoding $encoding Content to send with
+ * request.
+ * @access public
+ */
+ function SimpleHttpRequest(&$route, $encoding) {
+ $this->_route = &$route;
+ $this->_encoding = $encoding;
+ $this->_headers = array();
+ $this->_cookies = array();
+ }
+
+ /**
+ * Dispatches the content to the route's socket.
+ * @param integer $timeout Connection timeout.
+ * @return SimpleHttpResponse A response which may only have
+ * an error, but hopefully has a
+ * complete web page.
+ * @access public
+ */
+ function &fetch($timeout) {
+ $socket = &$this->_route->createConnection($this->_encoding->getMethod(), $timeout);
+ if (! $socket->isError()) {
+ $this->_dispatchRequest($socket, $this->_encoding);
+ }
+ $response = &$this->_createResponse($socket);
+ return $response;
+ }
+
+ /**
+ * Sends the headers.
+ * @param SimpleSocket $socket Open socket.
+ * @param string $method HTTP request method,
+ * usually GET.
+ * @param SimpleFormEncoding $encoding Content to send with request.
+ * @access private
+ */
+ function _dispatchRequest(&$socket, $encoding) {
+ foreach ($this->_headers as $header_line) {
+ $socket->write($header_line . "\r\n");
+ }
+ if (count($this->_cookies) > 0) {
+ $socket->write("Cookie: " . implode(";", $this->_cookies) . "\r\n");
+ }
+ $encoding->writeHeadersTo($socket);
+ $socket->write("\r\n");
+ $encoding->writeTo($socket);
+ }
+
+ /**
+ * Adds a header line to the request.
+ * @param string $header_line Text of full header line.
+ * @access public
+ */
+ function addHeaderLine($header_line) {
+ $this->_headers[] = $header_line;
+ }
+
+ /**
+ * Reads all the relevant cookies from the
+ * cookie jar.
+ * @param SimpleCookieJar $jar Jar to read
+ * @param SimpleUrl $url Url to use for scope.
+ * @access public
+ */
+ function readCookiesFromJar($jar, $url) {
+ $this->_cookies = $jar->selectAsPairs($url);
+ }
+
+ /**
+ * Wraps the socket in a response parser.
+ * @param SimpleSocket $socket Responding socket.
+ * @return SimpleHttpResponse Parsed response object.
+ * @access protected
+ */
+ function &_createResponse(&$socket) {
+ $response = &new SimpleHttpResponse(
+ $socket,
+ $this->_route->getUrl(),
+ $this->_encoding);
+ return $response;
+ }
+}
+
+/**
+ * Collection of header lines in the response.
+ * @package SimpleTest
+ * @subpackage WebTester
+ */
+class SimpleHttpHeaders {
+ var $_raw_headers;
+ var $_response_code;
+ var $_http_version;
+ var $_mime_type;
+ var $_location;
+ var $_cookies;
+ var $_authentication;
+ var $_realm;
+
+ /**
+ * Parses the incoming header block.
+ * @param string $headers Header block.
+ * @access public
+ */
+ function SimpleHttpHeaders($headers) {
+ $this->_raw_headers = $headers;
+ $this->_response_code = false;
+ $this->_http_version = false;
+ $this->_mime_type = '';
+ $this->_location = false;
+ $this->_cookies = array();
+ $this->_authentication = false;
+ $this->_realm = false;
+ foreach (split("\r\n", $headers) as $header_line) {
+ $this->_parseHeaderLine($header_line);
+ }
+ }
+
+ /**
+ * Accessor for parsed HTTP protocol version.
+ * @return integer HTTP error code.
+ * @access public
+ */
+ function getHttpVersion() {
+ return $this->_http_version;
+ }
+
+ /**
+ * Accessor for raw header block.
+ * @return string All headers as raw string.
+ * @access public
+ */
+ function getRaw() {
+ return $this->_raw_headers;
+ }
+
+ /**
+ * Accessor for parsed HTTP error code.
+ * @return integer HTTP error code.
+ * @access public
+ */
+ function getResponseCode() {
+ return (integer)$this->_response_code;
+ }
+
+ /**
+ * Returns the redirected URL or false if
+ * no redirection.
+ * @return string URL or false for none.
+ * @access public
+ */
+ function getLocation() {
+ return $this->_location;
+ }
+
+ /**
+ * Test to see if the response is a valid redirect.
+ * @return boolean True if valid redirect.
+ * @access public
+ */
+ function isRedirect() {
+ return in_array($this->_response_code, array(301, 302, 303, 307)) &&
+ (boolean)$this->getLocation();
+ }
+
+ /**
+ * Test to see if the response is an authentication
+ * challenge.
+ * @return boolean True if challenge.
+ * @access public
+ */
+ function isChallenge() {
+ return ($this->_response_code == 401) &&
+ (boolean)$this->_authentication &&
+ (boolean)$this->_realm;
+ }
+
+ /**
+ * Accessor for MIME type header information.
+ * @return string MIME type.
+ * @access public
+ */
+ function getMimeType() {
+ return $this->_mime_type;
+ }
+
+ /**
+ * Accessor for authentication type.
+ * @return string Type.
+ * @access public
+ */
+ function getAuthentication() {
+ return $this->_authentication;
+ }
+
+ /**
+ * Accessor for security realm.
+ * @return string Realm.
+ * @access public
+ */
+ function getRealm() {
+ return $this->_realm;
+ }
+
+ /**
+ * Writes new cookies to the cookie jar.
+ * @param SimpleCookieJar $jar Jar to write to.
+ * @param SimpleUrl $url Host and path to write under.
+ * @access public
+ */
+ function writeCookiesToJar(&$jar, $url) {
+ foreach ($this->_cookies as $cookie) {
+ $jar->setCookie(
+ $cookie->getName(),
+ $cookie->getValue(),
+ $url->getHost(),
+ $cookie->getPath(),
+ $cookie->getExpiry());
+ }
+ }
+
+ /**
+ * Called on each header line to accumulate the held
+ * data within the class.
+ * @param string $header_line One line of header.
+ * @access protected
+ */
+ function _parseHeaderLine($header_line) {
+ if (preg_match('/HTTP\/(\d+\.\d+)\s+(\d+)/i', $header_line, $matches)) {
+ $this->_http_version = $matches[1];
+ $this->_response_code = $matches[2];
+ }
+ if (preg_match('/Content-type:\s*(.*)/i', $header_line, $matches)) {
+ $this->_mime_type = trim($matches[1]);
+ }
+ if (preg_match('/Location:\s*(.*)/i', $header_line, $matches)) {
+ $this->_location = trim($matches[1]);
+ }
+ if (preg_match('/Set-cookie:(.*)/i', $header_line, $matches)) {
+ $this->_cookies[] = $this->_parseCookie($matches[1]);
+ }
+ if (preg_match('/WWW-Authenticate:\s+(\S+)\s+realm=\"(.*?)\"/i', $header_line, $matches)) {
+ $this->_authentication = $matches[1];
+ $this->_realm = trim($matches[2]);
+ }
+ }
+
+ /**
+ * Parse the Set-cookie content.
+ * @param string $cookie_line Text after "Set-cookie:"
+ * @return SimpleCookie New cookie object.
+ * @access private
+ */
+ function _parseCookie($cookie_line) {
+ $parts = split(";", $cookie_line);
+ $cookie = array();
+ preg_match('/\s*(.*?)\s*=(.*)/', array_shift($parts), $cookie);
+ foreach ($parts as $part) {
+ if (preg_match('/\s*(.*?)\s*=(.*)/', $part, $matches)) {
+ $cookie[$matches[1]] = trim($matches[2]);
+ }
+ }
+ return new SimpleCookie(
+ $cookie[1],
+ trim($cookie[2]),
+ isset($cookie["path"]) ? $cookie["path"] : "",
+ isset($cookie["expires"]) ? $cookie["expires"] : false);
+ }
+}
+
+/**
+ * Basic HTTP response.
+ * @package SimpleTest
+ * @subpackage WebTester
+ */
+class SimpleHttpResponse extends SimpleStickyError {
+ var $_url;
+ var $_encoding;
+ var $_sent;
+ var $_content;
+ var $_headers;
+
+ /**
+ * Constructor. Reads and parses the incoming
+ * content and headers.
+ * @param SimpleSocket $socket Network connection to fetch
+ * response text from.
+ * @param SimpleUrl $url Resource name.
+ * @param mixed $encoding Record of content sent.
+ * @access public
+ */
+ function SimpleHttpResponse(&$socket, $url, $encoding) {
+ $this->SimpleStickyError();
+ $this->_url = $url;
+ $this->_encoding = $encoding;
+ $this->_sent = $socket->getSent();
+ $this->_content = false;
+ $raw = $this->_readAll($socket);
+ if ($socket->isError()) {
+ $this->_setError('Error reading socket [' . $socket->getError() . ']');
+ return;
+ }
+ $this->_parse($raw);
+ }
+
+ /**
+ * Splits up the headers and the rest of the content.
+ * @param string $raw Content to parse.
+ * @access private
+ */
+ function _parse($raw) {
+ if (! $raw) {
+ $this->_setError('Nothing fetched');
+ $this->_headers = &new SimpleHttpHeaders('');
+ } elseif (! strstr($raw, "\r\n\r\n")) {
+ $this->_setError('Could not split headers from content');
+ $this->_headers = &new SimpleHttpHeaders($raw);
+ } else {
+ list($headers, $this->_content) = split("\r\n\r\n", $raw, 2);
+ $this->_headers = &new SimpleHttpHeaders($headers);
+ }
+ }
+
+ /**
+ * Original request method.
+ * @return string GET, POST or HEAD.
+ * @access public
+ */
+ function getMethod() {
+ return $this->_encoding->getMethod();
+ }
+
+ /**
+ * Resource name.
+ * @return SimpleUrl Current url.
+ * @access public
+ */
+ function getUrl() {
+ return $this->_url;
+ }
+
+ /**
+ * Original request data.
+ * @return mixed Sent content.
+ * @access public
+ */
+ function getRequestData() {
+ return $this->_encoding;
+ }
+
+ /**
+ * Raw request that was sent down the wire.
+ * @return string Bytes actually sent.
+ * @access public
+ */
+ function getSent() {
+ return $this->_sent;
+ }
+
+ /**
+ * Accessor for the content after the last
+ * header line.
+ * @return string All content.
+ * @access public
+ */
+ function getContent() {
+ return $this->_content;
+ }
+
+ /**
+ * Accessor for header block. The response is the
+ * combination of this and the content.
+ * @return SimpleHeaders Wrapped header block.
+ * @access public
+ */
+ function getHeaders() {
+ return $this->_headers;
+ }
+
+ /**
+ * Accessor for any new cookies.
+ * @return array List of new cookies.
+ * @access public
+ */
+ function getNewCookies() {
+ return $this->_headers->getNewCookies();
+ }
+
+ /**
+ * Reads the whole of the socket output into a
+ * single string.
+ * @param SimpleSocket $socket Unread socket.
+ * @return string Raw output if successful
+ * else false.
+ * @access private
+ */
+ function _readAll(&$socket) {
+ $all = '';
+ while (! $this->_isLastPacket($next = $socket->read())) {
+ $all .= $next;
+ }
+ return $all;
+ }
+
+ /**
+ * Test to see if the packet from the socket is the
+ * last one.
+ * @param string $packet Chunk to interpret.
+ * @return boolean True if empty or EOF.
+ * @access private
+ */
+ function _isLastPacket($packet) {
+ if (is_string($packet)) {
+ return $packet === '';
+ }
+ return ! $packet;
+ }
+}
+?> \ No newline at end of file
diff --git a/site/vendors/simpletest/invoker.php b/site/vendors/simpletest/invoker.php
new file mode 100644
index 0000000..e273001
--- /dev/null
+++ b/site/vendors/simpletest/invoker.php
@@ -0,0 +1,139 @@
+<?php
+/**
+ * Base include file for SimpleTest
+ * @package SimpleTest
+ * @subpackage UnitTester
+ * @version $Id: invoker.php 1722 2008-04-07 19:30:56Z lastcraft $
+ */
+
+/**#@+
+ * Includes SimpleTest files and defined the root constant
+ * for dependent libraries.
+ */
+require_once(dirname(__FILE__) . '/errors.php');
+require_once(dirname(__FILE__) . '/compatibility.php');
+require_once(dirname(__FILE__) . '/scorer.php');
+require_once(dirname(__FILE__) . '/expectation.php');
+require_once(dirname(__FILE__) . '/dumper.php');
+if (! defined('SIMPLE_TEST')) {
+ define('SIMPLE_TEST', dirname(__FILE__) . '/');
+}
+/**#@-*/
+
+/**
+ * This is called by the class runner to run a
+ * single test method. Will also run the setUp()
+ * and tearDown() methods.
+ * @package SimpleTest
+ * @subpackage UnitTester
+ */
+class SimpleInvoker {
+ var $_test_case;
+
+ /**
+ * Stashes the test case for later.
+ * @param SimpleTestCase $test_case Test case to run.
+ */
+ function SimpleInvoker(&$test_case) {
+ $this->_test_case = &$test_case;
+ }
+
+ /**
+ * Accessor for test case being run.
+ * @return SimpleTestCase Test case.
+ * @access public
+ */
+ function &getTestCase() {
+ return $this->_test_case;
+ }
+
+ /**
+ * Runs test level set up. Used for changing
+ * the mechanics of base test cases.
+ * @param string $method Test method to call.
+ * @access public
+ */
+ function before($method) {
+ $this->_test_case->before($method);
+ }
+
+ /**
+ * Invokes a test method and buffered with setUp()
+ * and tearDown() calls.
+ * @param string $method Test method to call.
+ * @access public
+ */
+ function invoke($method) {
+ $this->_test_case->setUp();
+ $this->_test_case->$method();
+ $this->_test_case->tearDown();
+ }
+
+ /**
+ * Runs test level clean up. Used for changing
+ * the mechanics of base test cases.
+ * @param string $method Test method to call.
+ * @access public
+ */
+ function after($method) {
+ $this->_test_case->after($method);
+ }
+}
+
+/**
+ * Do nothing decorator. Just passes the invocation
+ * straight through.
+ * @package SimpleTest
+ * @subpackage UnitTester
+ */
+class SimpleInvokerDecorator {
+ var $_invoker;
+
+ /**
+ * Stores the invoker to wrap.
+ * @param SimpleInvoker $invoker Test method runner.
+ */
+ function SimpleInvokerDecorator(&$invoker) {
+ $this->_invoker = &$invoker;
+ }
+
+ /**
+ * Accessor for test case being run.
+ * @return SimpleTestCase Test case.
+ * @access public
+ */
+ function &getTestCase() {
+ return $this->_invoker->getTestCase();
+ }
+
+ /**
+ * Runs test level set up. Used for changing
+ * the mechanics of base test cases.
+ * @param string $method Test method to call.
+ * @access public
+ */
+ function before($method) {
+ $this->_invoker->before($method);
+ }
+
+ /**
+ * Invokes a test method and buffered with setUp()
+ * and tearDown() calls.
+ * @param string $method Test method to call.
+ * @access public
+ */
+ function invoke($method) {
+ $this->_invoker->invoke($method);
+ }
+
+ /**
+ * Runs test level clean up. Used for changing
+ * the mechanics of base test cases.
+ * @param string $method Test method to call.
+ * @access public
+ */
+ function after($method) {
+ $this->_invoker->after($method);
+ }
+}
+?> \ No newline at end of file
diff --git a/site/vendors/simpletest/mock_objects.php b/site/vendors/simpletest/mock_objects.php
new file mode 100644
index 0000000..5ef1575
--- /dev/null
+++ b/site/vendors/simpletest/mock_objects.php
@@ -0,0 +1,1581 @@
+<?php
+/**
+ * base include file for SimpleTest
+ * @package SimpleTest
+ * @subpackage MockObjects
+ * @version $Id: mock_objects.php 1672 2008-03-02 04:47:34Z edwardzyang $
+ */
+
+/**#@+
+ * include SimpleTest files
+ */
+require_once(dirname(__FILE__) . '/expectation.php');
+require_once(dirname(__FILE__) . '/simpletest.php');
+require_once(dirname(__FILE__) . '/dumper.php');
+if (version_compare(phpversion(), '5') >= 0) {
+ require_once(dirname(__FILE__) . '/reflection_php5.php');
+} else {
+ require_once(dirname(__FILE__) . '/reflection_php4.php');
+}
+/**#@-*/
+
+/**
+ * Default character simpletest will substitute for any value
+ */
+if (! defined('MOCK_ANYTHING')) {
+ define('MOCK_ANYTHING', '*');
+}
+
+/**
+ * Parameter comparison assertion.
+ * @package SimpleTest
+ * @subpackage MockObjects
+ */
+class ParametersExpectation extends SimpleExpectation {
+ var $_expected;
+
+ /**
+ * Sets the expected parameter list.
+ * @param array $parameters Array of parameters including
+ * those that are wildcarded.
+ * If the value is not an array
+ * then it is considered to match any.
+ * @param string $message Customised message on failure.
+ * @access public
+ */
+ function ParametersExpectation($expected = false, $message = '%s') {
+ $this->SimpleExpectation($message);
+ $this->_expected = $expected;
+ }
+
+ /**
+ * Tests the assertion. True if correct.
+ * @param array $parameters Comparison values.
+ * @return boolean True if correct.
+ * @access public
+ */
+ function test($parameters) {
+ if (! is_array($this->_expected)) {
+ return true;
+ }
+ if (count($this->_expected) != count($parameters)) {
+ return false;
+ }
+ for ($i = 0; $i < count($this->_expected); $i++) {
+ if (! $this->_testParameter($parameters[$i], $this->_expected[$i])) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Tests an individual parameter.
+ * @param mixed $parameter Value to test.
+ * @param mixed $expected Comparison value.
+ * @return boolean True if expectation
+ * fulfilled.
+ * @access private
+ */
+ function _testParameter($parameter, $expected) {
+ $comparison = $this->_coerceToExpectation($expected);
+ return $comparison->test($parameter);
+ }
+
+ /**
+ * Returns a human readable test message.
+ * @param array $comparison Incoming parameter list.
+ * @return string Description of success
+ * or failure.
+ * @access public
+ */
+ function testMessage($parameters) {
+ if ($this->test($parameters)) {
+ return "Expectation of " . count($this->_expected) .
+ " arguments of [" . $this->_renderArguments($this->_expected) .
+ "] is correct";
+ } else {
+ return $this->_describeDifference($this->_expected, $parameters);
+ }
+ }
+
+ /**
+ * Message to display if expectation differs from
+ * the parameters actually received.
+ * @param array $expected Expected parameters as list.
+ * @param array $parameters Actual parameters received.
+ * @return string Description of difference.
+ * @access private
+ */
+ function _describeDifference($expected, $parameters) {
+ if (count($expected) != count($parameters)) {
+ return "Expected " . count($expected) .
+ " arguments of [" . $this->_renderArguments($expected) .
+ "] but got " . count($parameters) .
+ " arguments of [" . $this->_renderArguments($parameters) . "]";
+ }
+ $messages = array();
+ for ($i = 0; $i < count($expected); $i++) {
+ $comparison = $this->_coerceToExpectation($expected[$i]);
+ if (! $comparison->test($parameters[$i])) {
+ $messages[] = "parameter " . ($i + 1) . " with [" .
+ $comparison->overlayMessage($parameters[$i], $this->_getDumper()) . "]";
+ }
+ }
+ return "Parameter expectation differs at " . implode(" and ", $messages);
+ }
+
+ /**
+ * Creates an identical expectation if the
+ * object/value is not already some type
+ * of expectation.
+ * @param mixed $expected Expected value.
+ * @return SimpleExpectation Expectation object.
+ * @access private
+ */
+ function _coerceToExpectation($expected) {
+ if (SimpleExpectation::isExpectation($expected)) {
+ return $expected;
+ }
+ return new IdenticalExpectation($expected);
+ }
+
+ /**
+ * Renders the argument list as a string for
+ * messages.
+ * @param array $args Incoming arguments.
+ * @return string Simple description of type and value.
+ * @access private
+ */
+ function _renderArguments($args) {
+ $descriptions = array();
+ if (is_array($args)) {
+ foreach ($args as $arg) {
+ $dumper = &new SimpleDumper();
+ $descriptions[] = $dumper->describeValue($arg);
+ }
+ }
+ return implode(', ', $descriptions);
+ }
+}
+
+/**
+ * Confirms that the number of calls on a method is as expected.
+ * @package SimpleTest
+ * @subpackage MockObjects
+ */
+class CallCountExpectation extends SimpleExpectation {
+ var $_method;
+ var $_count;
+
+ /**
+ * Stashes the method and expected count for later
+ * reporting.
+ * @param string $method Name of method to confirm against.
+ * @param integer $count Expected number of calls.
+ * @param string $message Custom error message.
+ */
+ function CallCountExpectation($method, $count, $message = '%s') {
+ $this->_method = $method;
+ $this->_count = $count;
+ $this->SimpleExpectation($message);
+ }
+
+ /**
+ * Tests the assertion. True if correct.
+ * @param integer $compare Measured call count.
+ * @return boolean True if expected.
+ * @access public
+ */
+ function test($compare) {
+ return ($this->_count == $compare);
+ }
+
+ /**
+ * Reports the comparison.
+ * @param integer $compare Measured call count.
+ * @return string Message to show.
+ * @access public
+ */
+ function testMessage($compare) {
+ return 'Expected call count for [' . $this->_method .
+ '] was [' . $this->_count .
+ '] got [' . $compare . ']';
+ }
+}
+
+/**
+ * Confirms that the number of calls on a method is as expected.
+ * @package SimpleTest
+ * @subpackage MockObjects
+ */
+class MinimumCallCountExpectation extends SimpleExpectation {
+ var $_method;
+ var $_count;
+
+ /**
+ * Stashes the method and expected count for later
+ * reporting.
+ * @param string $method Name of method to confirm against.
+ * @param integer $count Minimum number of calls.
+ * @param string $message Custom error message.
+ */
+ function MinimumCallCountExpectation($method, $count, $message = '%s') {
+ $this->_method = $method;
+ $this->_count = $count;
+ $this->SimpleExpectation($message);
+ }
+
+ /**
+ * Tests the assertion. True if correct.
+ * @param integer $compare Measured call count.
+ * @return boolean True if enough.
+ * @access public
+ */
+ function test($compare) {
+ return ($this->_count <= $compare);
+ }
+
+ /**
+ * Reports the comparison.
+ * @param integer $compare Measured call count.
+ * @return string Message to show.
+ * @access public
+ */
+ function testMessage($compare) {
+ return 'Minimum call count for [' . $this->_method .
+ '] was [' . $this->_count .
+ '] got [' . $compare . ']';
+ }
+}
+
+/**
+ * Confirms that the number of calls on a method is as expected.
+ * @package SimpleTest
+ * @subpackage MockObjects
+ */
+class MaximumCallCountExpectation extends SimpleExpectation {
+ var $_method;
+ var $_count;
+
+ /**
+ * Stashes the method and expected count for later
+ * reporting.
+ * @param string $method Name of method to confirm against.
+ * @param integer $count Minimum number of calls.
+ * @param string $message Custom error message.
+ */
+ function MaximumCallCountExpectation($method, $count, $message = '%s') {
+ $this->_method = $method;
+ $this->_count = $count;
+ $this->SimpleExpectation($message);
+ }
+
+ /**
+ * Tests the assertion. True if correct.
+ * @param integer $compare Measured call count.
+ * @return boolean True if not over.
+ * @access public
+ */
+ function test($compare) {
+ return ($this->_count >= $compare);
+ }
+
+ /**
+ * Reports the comparison.
+ * @param integer $compare Measured call count.
+ * @return string Message to show.
+ * @access public
+ */
+ function testMessage($compare) {
+ return 'Maximum call count for [' . $this->_method .
+ '] was [' . $this->_count .
+ '] got [' . $compare . ']';
+ }
+}
+
+/**
+ * Retrieves method actions by searching the
+ * parameter lists until an expected match is found.
+ * @package SimpleTest
+ * @subpackage MockObjects
+ */
+class SimpleSignatureMap {
+ var $_map;
+
+ /**
+ * Creates an empty call map.
+ * @access public
+ */
+ function SimpleSignatureMap() {
+ $this->_map = array();
+ }
+
+ /**
+ * Stashes a reference against a method call.
+ * @param array $parameters Array of arguments (including wildcards).
+ * @param mixed $action Reference placed in the map.
+ * @access public
+ */
+ function add($parameters, &$action) {
+ $place = count($this->_map);
+ $this->_map[$place] = array();
+ $this->_map[$place]['params'] = new ParametersExpectation($parameters);
+ $this->_map[$place]['content'] = &$action;
+ }
+
+ /**
+ * Searches the call list for a matching parameter
+ * set. Returned by reference.
+ * @param array $parameters Parameters to search by
+ * without wildcards.
+ * @return object Object held in the first matching
+ * slot, otherwise null.
+ * @access public
+ */
+ function &findFirstAction($parameters) {
+ $slot = $this->_findFirstSlot($parameters);
+ if (isset($slot) && isset($slot['content'])) {
+ return $slot['content'];
+ }
+ $null = null;
+ return $null;
+ }
+
+ /**
+ * Searches the call list for a matching parameter
+ * set. True if successful.
+ * @param array $parameters Parameters to search by
+ * without wildcards.
+ * @return boolean True if a match is present.
+ * @access public
+ */
+ function isMatch($parameters) {
+ return ($this->_findFirstSlot($parameters) != null);
+ }
+
+ /**
+ * Compares the incoming parameters with the
+ * internal expectation. Uses the incoming $test
+ * to dispatch the test message.
+ * @param SimpleTestCase $test Test to dispatch to.
+ * @param array $parameters The actual calling arguments.
+ * @param string $message The message to overlay.
+ * @access public
+ */
+ function test(&$test, $parameters, $message) {
+ }
+
+ /**
+ * Searches the map for a matching item.
+ * @param array $parameters Parameters to search by
+ * without wildcards.
+ * @return array Reference to slot or null.
+ * @access private
+ */
+ function &_findFirstSlot($parameters) {
+ $count = count($this->_map);
+ for ($i = 0; $i < $count; $i++) {
+ if ($this->_map[$i]["params"]->test($parameters)) {
+ return $this->_map[$i];
+ }
+ }
+ $null = null;
+ return $null;
+ }
+}
+
+/**
+ * Allows setting of actions against call signatures either
+ * at a specific time, or always. Specific time settings
+ * trump lasting ones, otherwise the most recently added
+ * will mask an earlier match.
+ * @package SimpleTest
+ * @subpackage MockObjects
+ */
+class SimpleCallSchedule {
+ var $_wildcard = MOCK_ANYTHING;
+ var $_always;
+ var $_at;
+
+ /**
+ * Sets up an empty response schedule.
+ * Creates an empty call map.
+ */
+ function SimpleCallSchedule() {
+ $this->_always = array();
+ $this->_at = array();
+ }
+
+ /**
+ * Stores an action against a signature that
+ * will always fire unless masked by a time
+ * specific one.
+ * @param string $method Method name.
+ * @param array $args Calling parameters.
+ * @param SimpleAction $action Actually simpleByValue, etc.
+ * @access public
+ */
+ function register($method, $args, &$action) {
+ $args = $this->_replaceWildcards($args);
+ $method = strtolower($method);
+ if (! isset($this->_always[$method])) {
+ $this->_always[$method] = new SimpleSignatureMap();
+ }
+ $this->_always[$method]->add($args, $action);
+ }
+
+ /**
+ * Stores an action against a signature that
+ * will fire at a specific time in the future.
+ * @param integer $step delay of calls to this method,
+ * 0 is next.
+ * @param string $method Method name.
+ * @param array $args Calling parameters.
+ * @param SimpleAction $action Actually SimpleByValue, etc.
+ * @access public
+ */
+ function registerAt($step, $method, $args, &$action) {
+ $args = $this->_replaceWildcards($args);
+ $method = strtolower($method);
+ if (! isset($this->_at[$method])) {
+ $this->_at[$method] = array();
+ }
+ if (! isset($this->_at[$method][$step])) {
+ $this->_at[$method][$step] = new SimpleSignatureMap();
+ }
+ $this->_at[$method][$step]->add($args, $action);
+ }
+
+ function expectArguments($method, $args, $message) {
+ $args = $this->_replaceWildcards($args);
+ $message .= Mock::getExpectationLine();
+ $this->_expected_args[strtolower($method)] =
+ new ParametersExpectation($args, $message);
+
+ }
+
+ /**
+ * Actually carry out the action stored previously,
+ * if the parameters match.
+ * @param integer $step Time of call.
+ * @param string $method Method name.
+ * @param array $args The parameters making up the
+ * rest of the call.
+ * @return mixed The result of the action.
+ * @access public.
+ */
+ function &respond($step, $method, $args) {
+ $method = strtolower($method);
+ if (isset($this->_at[$method][$step])) {
+ if ($this->_at[$method][$step]->isMatch($args)) {
+ $action = &$this->_at[$method][$step]->findFirstAction($args);
+ if (isset($action)) {
+ return $action->act();
+ }
+ }
+ }
+ if (isset($this->_always[$method])) {
+ $action = &$this->_always[$method]->findFirstAction($args);
+ if (isset($action)) {
+ return $action->act();
+ }
+ }
+ $null = null;
+ return $null;
+ }
+
+ /**
+ * Replaces wildcard matches with wildcard
+ * expectations in the argument list.
+ * @param array $args Raw argument list.
+ * @return array Argument list with
+ * expectations.
+ * @access private
+ */
+ function _replaceWildcards($args) {
+ if ($args === false) {
+ return false;
+ }
+ for ($i = 0; $i < count($args); $i++) {
+ if ($args[$i] === $this->_wildcard) {
+ $args[$i] = new AnythingExpectation();
+ }
+ }
+ return $args;
+ }
+}
+
+/**
+ * A type of SimpleMethodAction.
+ * Stashes a reference for returning later.
+ * @package SimpleTest
+ * @subpackage MockObjects
+ */
+class SimpleByReference {
+ var $_reference;
+
+ /**
+ * Stashes it for later.
+ * @param mixed $reference Actual PHP4 style reference.
+ * @access public
+ */
+ function SimpleByReference(&$reference) {
+ $this->_reference = &$reference;
+ }
+
+ /**
+ * Returns the reference stored earlier.
+ * @return mixed Whatever was stashed.
+ * @access public
+ */
+ function &act() {
+ return $this->_reference;
+ }
+}
+
+/**
+ * A type of SimpleMethodAction.
+ * Stashes a value for returning later.
+ * @package SimpleTest
+ * @subpackage MockObjects
+ */
+class SimpleByValue {
+ var $_value;
+
+ /**
+ * Stashes it for later.
+ * @param mixed $value You need to clone objects
+ * if you want copy semantics
+ * for these.
+ * @access public
+ */
+ function SimpleByValue($value) {
+ $this->_value = $value;
+ }
+
+ /**
+ * Returns the value stored earlier.
+ * @return mixed Whatever was stashed.
+ * @access public
+ */
+ function &act() {
+ $dummy = $this->_value;
+ return $dummy;
+ }
+}
+
+/**
+ * A type of SimpleMethodAction.
+ * Stashes an exception for throwing later.
+ * @package SimpleTest
+ * @subpackage MockObjects
+ */
+class SimpleThrower {
+ var $_exception;
+
+ /**
+ * Stashes it for later.
+ * @param Exception $exception The exception object to throw.
+ * @access public
+ */
+ function SimpleThrower($exception) {
+ $this->_exception = $exception;
+ }
+
+ /**
+ * Throws the exceptins stashed earlier.
+ * @access public
+ */
+ function act() {
+ eval('throw $this->_exception;');
+ }
+}
+
+/**
+ * A type of SimpleMethodAction.
+ * Stashes an error for emitting later.
+ * @package SimpleTest
+ * @subpackage MockObjects
+ */
+class SimpleErrorThrower {
+ var $_error;
+ var $_severity;
+
+ /**
+ * Stashes an error to throw later.
+ * @param string $error Error message.
+ * @param integer $severity PHP error constant, e.g E_USER_ERROR.
+ * @access public
+ */
+ function SimpleErrorThrower($error, $severity) {
+ $this->_error = $error;
+ $this->_severity = $severity;
+ }
+
+ /**
+ * Triggers the stashed error.
+ * @return null The usual PHP4.4 shenanigans are needed here.
+ * @access public
+ */
+ function &act() {
+ trigger_error($this->_error, $this->_severity);
+ $null = null;
+ return $null;
+ }
+}
+
+/**
+ * A base class or delegate that extends an
+ * empty collection of methods that can have their
+ * return values set and expectations made of the
+ * calls upon them. The mock will assert the
+ * expectations against it's attached test case in
+ * addition to the server stub behaviour or returning
+ * preprogrammed responses.
+ * @package SimpleTest
+ * @subpackage MockObjects
+ */
+class SimpleMock {
+ var $_actions;
+ var $_wildcard = MOCK_ANYTHING;
+ var $_is_strict = true;
+ var $_call_counts;
+ var $_expected_counts;
+ var $_max_counts;
+ var $_expected_args;
+ var $_expected_args_at;
+
+ /**
+ * Creates an empty action list and expectation list.
+ * All call counts are set to zero.
+ * @access public
+ */
+ function SimpleMock() {
+ $this->_actions = &new SimpleCallSchedule();
+ $this->_expectations = &new SimpleCallSchedule();
+ $this->_call_counts = array();
+ $this->_expected_counts = array();
+ $this->_max_counts = array();
+ $this->_expected_args = array();
+ $this->_expected_args_at = array();
+ $test = &$this->_getCurrentTestCase();
+ $test->tell($this);
+ }
+
+ /**
+ * Disables a name check when setting expectations.
+ * This hack is needed for the partial mocks.
+ * @access public
+ */
+ function disableExpectationNameChecks() {
+ $this->_is_strict = false;
+ }
+
+ /**
+ * Finds currently running test.
+ * @return SimpeTestCase Current test case.
+ * @access protected
+ */
+ function &_getCurrentTestCase() {
+ $context = &SimpleTest::getContext();
+ return $context->getTest();
+ }
+
+ /**
+ * Die if bad arguments array is passed.
+ * @param mixed $args The arguments value to be checked.
+ * @param string $task Description of task attempt.
+ * @return boolean Valid arguments
+ * @access private
+ */
+ function _checkArgumentsIsArray($args, $task) {
+ if (! is_array($args)) {
+ trigger_error(
+ "Cannot $task as \$args parameter is not an array",
+ E_USER_ERROR);
+ }
+ }
+
+ /**
+ * Triggers a PHP error if the method is not part
+ * of this object.
+ * @param string $method Name of method.
+ * @param string $task Description of task attempt.
+ * @access protected
+ */
+ function _dieOnNoMethod($method, $task) {
+ if ($this->_is_strict && ! method_exists($this, $method)) {
+ trigger_error(
+ "Cannot $task as no ${method}() in class " . get_class($this),
+ E_USER_ERROR);
+ }
+ }
+
+ /**
+ * Replaces wildcard matches with wildcard
+ * expectations in the argument list.
+ * @param array $args Raw argument list.
+ * @return array Argument list with
+ * expectations.
+ * @access private
+ */
+ function _replaceWildcards($args) {
+ if ($args === false) {
+ return false;
+ }
+ for ($i = 0; $i < count($args); $i++) {
+ if ($args[$i] === $this->_wildcard) {
+ $args[$i] = new AnythingExpectation();
+ }
+ }
+ return $args;
+ }
+
+ /**
+ * Adds one to the call count of a method.
+ * @param string $method Method called.
+ * @param array $args Arguments as an array.
+ * @access protected
+ */
+ function _addCall($method, $args) {
+ if (! isset($this->_call_counts[$method])) {
+ $this->_call_counts[$method] = 0;
+ }
+ $this->_call_counts[$method]++;
+ }
+
+ /**
+ * Fetches the call count of a method so far.
+ * @param string $method Method name called.
+ * @return integer Number of calls so far.
+ * @access public
+ */
+ function getCallCount($method) {
+ $this->_dieOnNoMethod($method, "get call count");
+ $method = strtolower($method);
+ if (! isset($this->_call_counts[$method])) {
+ return 0;
+ }
+ return $this->_call_counts[$method];
+ }
+
+ /**
+ * Sets a return for a parameter list that will
+ * be passed by value for all calls to this method.
+ * @param string $method Method name.
+ * @param mixed $value Result of call passed by value.
+ * @param array $args List of parameters to match
+ * including wildcards.
+ * @access public
+ */
+ function setReturnValue($method, $value, $args = false) {
+ $this->_dieOnNoMethod($method, "set return value");
+ $this->_actions->register($method, $args, new SimpleByValue($value));
+ }
+
+ /**
+ * Sets a return for a parameter list that will
+ * be passed by value only when the required call count
+ * is reached.
+ * @param integer $timing Number of calls in the future
+ * to which the result applies. If
+ * not set then all calls will return
+ * the value.
+ * @param string $method Method name.
+ * @param mixed $value Result of call passed by value.
+ * @param array $args List of parameters to match
+ * including wildcards.
+ * @access public
+ */
+ function setReturnValueAt($timing, $method, $value, $args = false) {
+ $this->_dieOnNoMethod($method, "set return value sequence");
+ $this->_actions->registerAt($timing, $method, $args, new SimpleByValue($value));
+ }
+
+ /**
+ * Sets a return for a parameter list that will
+ * be passed by reference for all calls.
+ * @param string $method Method name.
+ * @param mixed $reference Result of the call will be this object.
+ * @param array $args List of parameters to match
+ * including wildcards.
+ * @access public
+ */
+ function setReturnReference($method, &$reference, $args = false) {
+ $this->_dieOnNoMethod($method, "set return reference");
+ $this->_actions->register($method, $args, new SimpleByReference($reference));
+ }
+
+ /**
+ * Sets a return for a parameter list that will
+ * be passed by value only when the required call count
+ * is reached.
+ * @param integer $timing Number of calls in the future
+ * to which the result applies. If
+ * not set then all calls will return
+ * the value.
+ * @param string $method Method name.
+ * @param mixed $reference Result of the call will be this object.
+ * @param array $args List of parameters to match
+ * including wildcards.
+ * @access public
+ */
+ function setReturnReferenceAt($timing, $method, &$reference, $args = false) {
+ $this->_dieOnNoMethod($method, "set return reference sequence");
+ $this->_actions->registerAt($timing, $method, $args, new SimpleByReference($reference));
+ }
+
+ /**
+ * Sets up an expected call with a set of
+ * expected parameters in that call. All
+ * calls will be compared to these expectations
+ * regardless of when the call is made.
+ * @param string $method Method call to test.
+ * @param array $args Expected parameters for the call
+ * including wildcards.
+ * @param string $message Overridden message.
+ * @access public
+ */
+ function expect($method, $args, $message = '%s') {
+ $this->_dieOnNoMethod($method, 'set expected arguments');
+ $this->_checkArgumentsIsArray($args, 'set expected arguments');
+ $this->_expectations->expectArguments($method, $args, $message);
+ $args = $this->_replaceWildcards($args);
+ $message .= Mock::getExpectationLine();
+ $this->_expected_args[strtolower($method)] =
+ new ParametersExpectation($args, $message);
+ }
+
+ /**
+ * @deprecated
+ */
+ function expectArguments($method, $args, $message = '%s') {
+ return $this->expect($method, $args, $message);
+ }
+
+ /**
+ * Sets up an expected call with a set of
+ * expected parameters in that call. The
+ * expected call count will be adjusted if it
+ * is set too low to reach this call.
+ * @param integer $timing Number of calls in the future at
+ * which to test. Next call is 0.
+ * @param string $method Method call to test.
+ * @param array $args Expected parameters for the call
+ * including wildcards.
+ * @param string $message Overridden message.
+ * @access public
+ */
+ function expectAt($timing, $method, $args, $message = '%s') {
+ $this->_dieOnNoMethod($method, 'set expected arguments at time');
+ $this->_checkArgumentsIsArray($args, 'set expected arguments at time');
+ $args = $this->_replaceWildcards($args);
+ if (! isset($this->_expected_args_at[$timing])) {
+ $this->_expected_args_at[$timing] = array();
+ }
+ $method = strtolower($method);
+ $message .= Mock::getExpectationLine();
+ $this->_expected_args_at[$timing][$method] =
+ new ParametersExpectation($args, $message);
+ }
+
+ /**
+ * @deprecated
+ */
+ function expectArgumentsAt($timing, $method, $args, $message = '%s') {
+ return $this->expectAt($timing, $method, $args, $message);
+ }
+
+ /**
+ * Sets an expectation for the number of times
+ * a method will be called. The tally method
+ * is used to check this.
+ * @param string $method Method call to test.
+ * @param integer $count Number of times it should
+ * have been called at tally.
+ * @param string $message Overridden message.
+ * @access public
+ */
+ function expectCallCount($method, $count, $message = '%s') {
+ $this->_dieOnNoMethod($method, 'set expected call count');
+ $message .= Mock::getExpectationLine();
+ $this->_expected_counts[strtolower($method)] =
+ new CallCountExpectation($method, $count, $message);
+ }
+
+ /**
+ * Sets the number of times a method may be called
+ * before a test failure is triggered.
+ * @param string $method Method call to test.
+ * @param integer $count Most number of times it should
+ * have been called.
+ * @param string $message Overridden message.
+ * @access public
+ */
+ function expectMaximumCallCount($method, $count, $message = '%s') {
+ $this->_dieOnNoMethod($method, 'set maximum call count');
+ $message .= Mock::getExpectationLine();
+ $this->_max_counts[strtolower($method)] =
+ new MaximumCallCountExpectation($method, $count, $message);
+ }
+
+ /**
+ * Sets the number of times to call a method to prevent
+ * a failure on the tally.
+ * @param string $method Method call to test.
+ * @param integer $count Least number of times it should
+ * have been called.
+ * @param string $message Overridden message.
+ * @access public
+ */
+ function expectMinimumCallCount($method, $count, $message = '%s') {
+ $this->_dieOnNoMethod($method, 'set minimum call count');
+ $message .= Mock::getExpectationLine();
+ $this->_expected_counts[strtolower($method)] =
+ new MinimumCallCountExpectation($method, $count, $message);
+ }
+
+ /**
+ * Convenience method for barring a method
+ * call.
+ * @param string $method Method call to ban.
+ * @param string $message Overridden message.
+ * @access public
+ */
+ function expectNever($method, $message = '%s') {
+ $this->expectMaximumCallCount($method, 0, $message);
+ }
+
+ /**
+ * Convenience method for a single method
+ * call.
+ * @param string $method Method call to track.
+ * @param array $args Expected argument list or
+ * false for any arguments.
+ * @param string $message Overridden message.
+ * @access public
+ */
+ function expectOnce($method, $args = false, $message = '%s') {
+ $this->expectCallCount($method, 1, $message);
+ if ($args !== false) {
+ $this->expect($method, $args, $message);
+ }
+ }
+
+ /**
+ * Convenience method for requiring a method
+ * call.
+ * @param string $method Method call to track.
+ * @param array $args Expected argument list or
+ * false for any arguments.
+ * @param string $message Overridden message.
+ * @access public
+ */
+ function expectAtLeastOnce($method, $args = false, $message = '%s') {
+ $this->expectMinimumCallCount($method, 1, $message);
+ if ($args !== false) {
+ $this->expect($method, $args, $message);
+ }
+ }
+
+ /**
+ * Sets up a trigger to throw an exception upon the
+ * method call.
+ * @param string $method Method name to throw on.
+ */
+ function throwOn($method, $exception = false, $args = false) {
+ $this->_dieOnNoMethod($method, "throw on");
+ $this->_actions->register($method, $args,
+ new SimpleThrower($exception ? $exception : new Exception()));
+ }
+
+ /**
+ * Sets up a trigger to throw an exception upon the
+ * method call.
+ */
+ function throwAt($timing, $method, $exception = false, $args = false) {
+ $this->_dieOnNoMethod($method, "throw at");
+ $this->_actions->registerAt($timing, $method, $args,
+ new SimpleThrower($exception ? $exception : new Exception()));
+ }
+
+ /**
+ * Sets up a trigger to throw an error upon the
+ * method call.
+ */
+ function errorOn($method, $error = 'A mock error', $args = false, $severity = E_USER_ERROR) {
+ $this->_dieOnNoMethod($method, "error on");
+ $this->_actions->register($method, $args, new SimpleErrorThrower($error, $severity));
+ }
+
+ /**
+ * Sets up a trigger to throw an error upon the
+ * method call.
+ */
+ function errorAt($timing, $method, $error = 'A mock error', $args = false, $severity = E_USER_ERROR) {
+ $this->_dieOnNoMethod($method, "error at");
+ $this->_actions->registerAt($timing, $method, $args, new SimpleErrorThrower($error, $severity));
+ }
+
+ /**
+ * @deprecated
+ */
+ function tally() {
+ }
+
+ /**
+ * Receives event from unit test that the current
+ * test method has finished. Totals up the call
+ * counts and triggers a test assertion if a test
+ * is present for expected call counts.
+ * @param string $test_method Current method name.
+ * @param SimpleTestCase $test Test to send message to.
+ * @access public
+ */
+ function atTestEnd($test_method, &$test) {
+ foreach ($this->_expected_counts as $method => $expectation) {
+ $test->assert($expectation, $this->getCallCount($method));
+ }
+ foreach ($this->_max_counts as $method => $expectation) {
+ if ($expectation->test($this->getCallCount($method))) {
+ $test->assert($expectation, $this->getCallCount($method));
+ }
+ }
+ }
+
+ /**
+ * Returns the expected value for the method name
+ * and checks expectations. Will generate any
+ * test assertions as a result of expectations
+ * if there is a test present.
+ * @param string $method Name of method to simulate.
+ * @param array $args Arguments as an array.
+ * @return mixed Stored return.
+ * @access private
+ */
+ function &_invoke($method, $args) {
+ $method = strtolower($method);
+ $step = $this->getCallCount($method);
+ $this->_addCall($method, $args);
+ $this->_checkExpectations($method, $args, $step);
+ $result = &$this->_emulateCall($method, $args, $step);
+ return $result;
+ }
+
+ /**
+ * Finds the return value matching the incoming
+ * arguments. If there is no matching value found
+ * then an error is triggered.
+ * @param string $method Method name.
+ * @param array $args Calling arguments.
+ * @param integer $step Current position in the
+ * call history.
+ * @return mixed Stored return or other action.
+ * @access protected
+ */
+ function &_emulateCall($method, $args, $step) {
+ return $this->_actions->respond($step, $method, $args);
+ }
+
+ /**
+ * Tests the arguments against expectations.
+ * @param string $method Method to check.
+ * @param array $args Argument list to match.
+ * @param integer $timing The position of this call
+ * in the call history.
+ * @access private
+ */
+ function _checkExpectations($method, $args, $timing) {
+ $test = &$this->_getCurrentTestCase();
+ if (isset($this->_max_counts[$method])) {
+ if (! $this->_max_counts[$method]->test($timing + 1)) {
+ $test->assert($this->_max_counts[$method], $timing + 1);
+ }
+ }
+ if (isset($this->_expected_args_at[$timing][$method])) {
+ $test->assert(
+ $this->_expected_args_at[$timing][$method],
+ $args,
+ "Mock method [$method] at [$timing] -> %s");
+ } elseif (isset($this->_expected_args[$method])) {
+ $test->assert(
+ $this->_expected_args[$method],
+ $args,
+ "Mock method [$method] -> %s");
+ }
+ }
+}
+
+/**
+ * Static methods only service class for code generation of
+ * mock objects.
+ * @package SimpleTest
+ * @subpackage MockObjects
+ */
+class Mock {
+
+ /**
+ * Factory for mock object classes.
+ * @access public
+ */
+ function Mock() {
+ trigger_error('Mock factory methods are static.');
+ }
+
+ /**
+ * Clones a class' interface and creates a mock version
+ * that can have return values and expectations set.
+ * @param string $class Class to clone.
+ * @param string $mock_class New class name. Default is
+ * the old name with "Mock"
+ * prepended.
+ * @param array $methods Additional methods to add beyond
+ * those in the cloned class. Use this
+ * to emulate the dynamic addition of
+ * methods in the cloned class or when
+ * the class hasn't been written yet.
+ * @static
+ * @access public
+ */
+ function generate($class, $mock_class = false, $methods = false) {
+ $generator = new MockGenerator($class, $mock_class);
+ return $generator->generateSubclass($methods);
+ }
+
+ /**
+ * Generates a version of a class with selected
+ * methods mocked only. Inherits the old class
+ * and chains the mock methods of an aggregated
+ * mock object.
+ * @param string $class Class to clone.
+ * @param string $mock_class New class name.
+ * @param array $methods Methods to be overridden
+ * with mock versions.
+ * @static
+ * @access public
+ */
+ function generatePartial($class, $mock_class, $methods) {
+ $generator = new MockGenerator($class, $mock_class);
+ return $generator->generatePartial($methods);
+ }
+
+ /**
+ * Uses a stack trace to find the line of an assertion.
+ * @access public
+ * @static
+ */
+ function getExpectationLine() {
+ $trace = new SimpleStackTrace(array('expect'));
+ return $trace->traceMethod();
+ }
+}
+
+/**
+ * @package SimpleTest
+ * @subpackage MockObjects
+ * @deprecated
+ */
+class Stub extends Mock {
+}
+
+/**
+ * Service class for code generation of mock objects.
+ * @package SimpleTest
+ * @subpackage MockObjects
+ */
+class MockGenerator {
+ var $_class;
+ var $_mock_class;
+ var $_mock_base;
+ var $_reflection;
+
+ /**
+ * Builds initial reflection object.
+ * @param string $class Class to be mocked.
+ * @param string $mock_class New class with identical interface,
+ * but no behaviour.
+ */
+ function MockGenerator($class, $mock_class) {
+ $this->_class = $class;
+ $this->_mock_class = $mock_class;
+ if (! $this->_mock_class) {
+ $this->_mock_class = 'Mock' . $this->_class;
+ }
+ $this->_mock_base = SimpleTest::getMockBaseClass();
+ $this->_reflection = new SimpleReflection($this->_class);
+ }
+
+ /**
+ * Clones a class' interface and creates a mock version
+ * that can have return values and expectations set.
+ * @param array $methods Additional methods to add beyond
+ * those in th cloned class. Use this
+ * to emulate the dynamic addition of
+ * methods in the cloned class or when
+ * the class hasn't been written yet.
+ * @access public
+ */
+ function generate($methods) {
+ if (! $this->_reflection->classOrInterfaceExists()) {
+ return false;
+ }
+ $mock_reflection = new SimpleReflection($this->_mock_class);
+ if ($mock_reflection->classExistsSansAutoload()) {
+ return false;
+ }
+ $code = $this->_createClassCode($methods ? $methods : array());
+ return eval("$code return \$code;");
+ }
+
+ /**
+ * Subclasses a class and overrides every method with a mock one
+ * that can have return values and expectations set. Chains
+ * to an aggregated SimpleMock.
+ * @param array $methods Additional methods to add beyond
+ * those in the cloned class. Use this
+ * to emulate the dynamic addition of
+ * methods in the cloned class or when
+ * the class hasn't been written yet.
+ * @access public
+ */
+ function generateSubclass($methods) {
+ if (! $this->_reflection->classOrInterfaceExists()) {
+ return false;
+ }
+ $mock_reflection = new SimpleReflection($this->_mock_class);
+ if ($mock_reflection->classExistsSansAutoload()) {
+ return false;
+ }
+ if ($this->_reflection->isInterface() || $this->_reflection->hasFinal()) {
+ $code = $this->_createClassCode($methods ? $methods : array());
+ return eval("$code return \$code;");
+ } else {
+ $code = $this->_createSubclassCode($methods ? $methods : array());
+ return eval("$code return \$code;");
+ }
+ }
+
+ /**
+ * Generates a version of a class with selected
+ * methods mocked only. Inherits the old class
+ * and chains the mock methods of an aggregated
+ * mock object.
+ * @param array $methods Methods to be overridden
+ * with mock versions.
+ * @access public
+ */
+ function generatePartial($methods) {
+ if (! $this->_reflection->classExists($this->_class)) {
+ return false;
+ }
+ $mock_reflection = new SimpleReflection($this->_mock_class);
+ if ($mock_reflection->classExistsSansAutoload()) {
+ trigger_error('Partial mock class [' . $this->_mock_class . '] already exists');
+ return false;
+ }
+ $code = $this->_extendClassCode($methods);
+ return eval("$code return \$code;");
+ }
+
+ /**
+ * The new mock class code as a string.
+ * @param array $methods Additional methods.
+ * @return string Code for new mock class.
+ * @access private
+ */
+ function _createClassCode($methods) {
+ $implements = '';
+ $interfaces = $this->_reflection->getInterfaces();
+ if (function_exists('spl_classes')) {
+ $interfaces = array_diff($interfaces, array('Traversable'));
+ }
+ if (count($interfaces) > 0) {
+ $implements = 'implements ' . implode(', ', $interfaces);
+ }
+ $code = "class " . $this->_mock_class . " extends " . $this->_mock_base . " $implements {\n";
+ $code .= " function " . $this->_mock_class . "() {\n";
+ $code .= " \$this->" . $this->_mock_base . "();\n";
+ $code .= " }\n";
+ if (in_array('__construct', $this->_reflection->getMethods())) {
+ $code .= " " . $this->_reflection->getSignature('__construct') . " {\n";
+ $code .= " \$this->" . $this->_mock_base . "();\n";
+ $code .= " }\n";
+ }
+ $code .= $this->_createHandlerCode($methods);
+ $code .= "}\n";
+ return $code;
+ }
+
+ /**
+ * The new mock class code as a string. The mock will
+ * be a subclass of the original mocked class.
+ * @param array $methods Additional methods.
+ * @return string Code for new mock class.
+ * @access private
+ */
+ function _createSubclassCode($methods) {
+ $code = "class " . $this->_mock_class . " extends " . $this->_class . " {\n";
+ $code .= " var \$_mock;\n";
+ $code .= $this->_addMethodList(array_merge($methods, $this->_reflection->getMethods()));
+ $code .= "\n";
+ $code .= " function " . $this->_mock_class . "() {\n";
+ $code .= " \$this->_mock = &new " . $this->_mock_base . "();\n";
+ $code .= " \$this->_mock->disableExpectationNameChecks();\n";
+ $code .= " }\n";
+ $code .= $this->_chainMockReturns();
+ $code .= $this->_chainMockExpectations();
+ $code .= $this->_chainThrowMethods();
+ $code .= $this->_overrideMethods($this->_reflection->getMethods());
+ $code .= $this->_createNewMethodCode($methods);
+ $code .= "}\n";
+ return $code;
+ }
+
+ /**
+ * The extension class code as a string. The class
+ * composites a mock object and chains mocked methods
+ * to it.
+ * @param array $methods Mocked methods.
+ * @return string Code for a new class.
+ * @access private
+ */
+ function _extendClassCode($methods) {
+ $code = "class " . $this->_mock_class . " extends " . $this->_class . " {\n";
+ $code .= " var \$_mock;\n";
+ $code .= $this->_addMethodList($methods);
+ $code .= "\n";
+ $code .= " function " . $this->_mock_class . "() {\n";
+ $code .= " \$this->_mock = &new " . $this->_mock_base . "();\n";
+ $code .= " \$this->_mock->disableExpectationNameChecks();\n";
+ $code .= " }\n";
+ $code .= $this->_chainMockReturns();
+ $code .= $this->_chainMockExpectations();
+ $code .= $this->_chainThrowMethods();
+ $code .= $this->_overrideMethods($methods);
+ $code .= "}\n";
+ return $code;
+ }
+
+ /**
+ * Creates code within a class to generate replaced
+ * methods. All methods call the _invoke() handler
+ * with the method name and the arguments in an
+ * array.
+ * @param array $methods Additional methods.
+ * @access private
+ */
+ function _createHandlerCode($methods) {
+ $code = '';
+ $methods = array_merge($methods, $this->_reflection->getMethods());
+ foreach ($methods as $method) {
+ if ($this->_isConstructor($method)) {
+ continue;
+ }
+ $mock_reflection = new SimpleReflection($this->_mock_base);
+ if (in_array($method, $mock_reflection->getMethods())) {
+ continue;
+ }
+ $code .= " " . $this->_reflection->getSignature($method) . " {\n";
+ $code .= " \$args = func_get_args();\n";
+ $code .= " \$result = &\$this->_invoke(\"$method\", \$args);\n";
+ $code .= " return \$result;\n";
+ $code .= " }\n";
+ }
+ return $code;
+ }
+
+ /**
+ * Creates code within a class to generate a new
+ * methods. All methods call the _invoke() handler
+ * on the internal mock with the method name and
+ * the arguments in an array.
+ * @param array $methods Additional methods.
+ * @access private
+ */
+ function _createNewMethodCode($methods) {
+ $code = '';
+ foreach ($methods as $method) {
+ if ($this->_isConstructor($method)) {
+ continue;
+ }
+ $mock_reflection = new SimpleReflection($this->_mock_base);
+ if (in_array($method, $mock_reflection->getMethods())) {
+ continue;
+ }
+ $code .= " " . $this->_reflection->getSignature($method) . " {\n";
+ $code .= " \$args = func_get_args();\n";
+ $code .= " \$result = &\$this->_mock->_invoke(\"$method\", \$args);\n";
+ $code .= " return \$result;\n";
+ $code .= " }\n";
+ }
+ return $code;
+ }
+
+ /**
+ * Tests to see if a special PHP method is about to
+ * be stubbed by mistake.
+ * @param string $method Method name.
+ * @return boolean True if special.
+ * @access private
+ */
+ function _isConstructor($method) {
+ return in_array(
+ strtolower($method),
+ array('__construct', '__destruct'));
+ }
+
+ /**
+ * Creates a list of mocked methods for error checking.
+ * @param array $methods Mocked methods.
+ * @return string Code for a method list.
+ * @access private
+ */
+ function _addMethodList($methods) {
+ return " var \$_mocked_methods = array('" .
+ implode("', '", array_map('strtolower', $methods)) .
+ "');\n";
+ }
+
+ /**
+ * Creates code to abandon the expectation if not mocked.
+ * @param string $alias Parameter name of method name.
+ * @return string Code for bail out.
+ * @access private
+ */
+ function _bailOutIfNotMocked($alias) {
+ $code = " if (! in_array(strtolower($alias), \$this->_mocked_methods)) {\n";
+ $code .= " trigger_error(\"Method [$alias] is not mocked\");\n";
+ $code .= " \$null = null;\n";
+ $code .= " return \$null;\n";
+ $code .= " }\n";
+ return $code;
+ }
+
+ /**
+ * Creates source code for chaining to the composited
+ * mock object.
+ * @return string Code for mock set up.
+ * @access private
+ */
+ function _chainMockReturns() {
+ $code = " function setReturnValue(\$method, \$value, \$args = false) {\n";
+ $code .= $this->_bailOutIfNotMocked("\$method");
+ $code .= " \$this->_mock->setReturnValue(\$method, \$value, \$args);\n";
+ $code .= " }\n";
+ $code .= " function setReturnValueAt(\$timing, \$method, \$value, \$args = false) {\n";
+ $code .= $this->_bailOutIfNotMocked("\$method");
+ $code .= " \$this->_mock->setReturnValueAt(\$timing, \$method, \$value, \$args);\n";
+ $code .= " }\n";
+ $code .= " function setReturnReference(\$method, &\$ref, \$args = false) {\n";
+ $code .= $this->_bailOutIfNotMocked("\$method");
+ $code .= " \$this->_mock->setReturnReference(\$method, \$ref, \$args);\n";
+ $code .= " }\n";
+ $code .= " function setReturnReferenceAt(\$timing, \$method, &\$ref, \$args = false) {\n";
+ $code .= $this->_bailOutIfNotMocked("\$method");
+ $code .= " \$this->_mock->setReturnReferenceAt(\$timing, \$method, \$ref, \$args);\n";
+ $code .= " }\n";
+ return $code;
+ }
+
+ /**
+ * Creates source code for chaining to an aggregated
+ * mock object.
+ * @return string Code for expectations.
+ * @access private
+ */
+ function _chainMockExpectations() {
+ $code = " function expect(\$method, \$args = false, \$msg = '%s') {\n";
+ $code .= $this->_bailOutIfNotMocked("\$method");
+ $code .= " \$this->_mock->expect(\$method, \$args, \$msg);\n";
+ $code .= " }\n";
+ $code .= " function expectArguments(\$method, \$args = false, \$msg = '%s') {\n";
+ $code .= $this->_bailOutIfNotMocked("\$method");
+ $code .= " \$this->_mock->expectArguments(\$method, \$args, \$msg);\n";
+ $code .= " }\n";
+ $code .= " function expectAt(\$timing, \$method, \$args = false, \$msg = '%s') {\n";
+ $code .= $this->_bailOutIfNotMocked("\$method");
+ $code .= " \$this->_mock->expectArgumentsAt(\$timing, \$method, \$args, \$msg);\n";
+ $code .= " }\n";
+ $code .= " function expectArgumentsAt(\$timing, \$method, \$args = false, \$msg = '%s') {\n";
+ $code .= $this->_bailOutIfNotMocked("\$method");
+ $code .= " \$this->_mock->expectArgumentsAt(\$timing, \$method, \$args, \$msg);\n";
+ $code .= " }\n";
+ $code .= " function expectCallCount(\$method, \$count) {\n";
+ $code .= $this->_bailOutIfNotMocked("\$method");
+ $code .= " \$this->_mock->expectCallCount(\$method, \$count, \$msg = '%s');\n";
+ $code .= " }\n";
+ $code .= " function expectMaximumCallCount(\$method, \$count, \$msg = '%s') {\n";
+ $code .= $this->_bailOutIfNotMocked("\$method");
+ $code .= " \$this->_mock->expectMaximumCallCount(\$method, \$count, \$msg = '%s');\n";
+ $code .= " }\n";
+ $code .= " function expectMinimumCallCount(\$method, \$count, \$msg = '%s') {\n";
+ $code .= $this->_bailOutIfNotMocked("\$method");
+ $code .= " \$this->_mock->expectMinimumCallCount(\$method, \$count, \$msg = '%s');\n";
+ $code .= " }\n";
+ $code .= " function expectNever(\$method) {\n";
+ $code .= $this->_bailOutIfNotMocked("\$method");
+ $code .= " \$this->_mock->expectNever(\$method);\n";
+ $code .= " }\n";
+ $code .= " function expectOnce(\$method, \$args = false, \$msg = '%s') {\n";
+ $code .= $this->_bailOutIfNotMocked("\$method");
+ $code .= " \$this->_mock->expectOnce(\$method, \$args, \$msg);\n";
+ $code .= " }\n";
+ $code .= " function expectAtLeastOnce(\$method, \$args = false, \$msg = '%s') {\n";
+ $code .= $this->_bailOutIfNotMocked("\$method");
+ $code .= " \$this->_mock->expectAtLeastOnce(\$method, \$args, \$msg);\n";
+ $code .= " }\n";
+ $code .= " function tally() {\n";
+ $code .= " }\n";
+ return $code;
+ }
+
+ /**
+ * Adds code for chaining the throw methods.
+ * @return string Code for chains.
+ * @access private
+ */
+ function _chainThrowMethods() {
+ $code = " function throwOn(\$method, \$exception = false, \$args = false) {\n";
+ $code .= $this->_bailOutIfNotMocked("\$method");
+ $code .= " \$this->_mock->throwOn(\$method, \$exception, \$args);\n";
+ $code .= " }\n";
+ $code .= " function throwAt(\$timing, \$method, \$exception = false, \$args = false) {\n";
+ $code .= $this->_bailOutIfNotMocked("\$method");
+ $code .= " \$this->_mock->throwAt(\$timing, \$method, \$exception, \$args);\n";
+ $code .= " }\n";
+ $code .= " function errorOn(\$method, \$error = 'A mock error', \$args = false, \$severity = E_USER_ERROR) {\n";
+ $code .= $this->_bailOutIfNotMocked("\$method");
+ $code .= " \$this->_mock->errorOn(\$method, \$error, \$args, \$severity);\n";
+ $code .= " }\n";
+ $code .= " function errorAt(\$timing, \$method, \$error = 'A mock error', \$args = false, \$severity = E_USER_ERROR) {\n";
+ $code .= $this->_bailOutIfNotMocked("\$method");
+ $code .= " \$this->_mock->errorAt(\$timing, \$method, \$error, \$args, \$severity);\n";
+ $code .= " }\n";
+ return $code;
+ }
+
+ /**
+ * Creates source code to override a list of methods
+ * with mock versions.
+ * @param array $methods Methods to be overridden
+ * with mock versions.
+ * @return string Code for overridden chains.
+ * @access private
+ */
+ function _overrideMethods($methods) {
+ $code = "";
+ foreach ($methods as $method) {
+ if ($this->_isConstructor($method)) {
+ continue;
+ }
+ $code .= " " . $this->_reflection->getSignature($method) . " {\n";
+ $code .= " \$args = func_get_args();\n";
+ $code .= " \$result = &\$this->_mock->_invoke(\"$method\", \$args);\n";
+ $code .= " return \$result;\n";
+ $code .= " }\n";
+ }
+ return $code;
+ }
+}
+?>
diff --git a/site/vendors/simpletest/page.php b/site/vendors/simpletest/page.php
new file mode 100644
index 0000000..08e5649
--- /dev/null
+++ b/site/vendors/simpletest/page.php
@@ -0,0 +1,983 @@
+<?php
+/**
+ * Base include file for SimpleTest
+ * @package SimpleTest
+ * @subpackage WebTester
+ * @version $Id: page.php 1672 2008-03-02 04:47:34Z edwardzyang $
+ */
+
+/**#@+
+ * include other SimpleTest class files
+ */
+require_once(dirname(__FILE__) . '/http.php');
+require_once(dirname(__FILE__) . '/parser.php');
+require_once(dirname(__FILE__) . '/tag.php');
+require_once(dirname(__FILE__) . '/form.php');
+require_once(dirname(__FILE__) . '/selector.php');
+/**#@-*/
+
+/**
+ * Creates tags and widgets given HTML tag
+ * attributes.
+ * @package SimpleTest
+ * @subpackage WebTester
+ */
+class SimpleTagBuilder {
+
+ /**
+ * Factory for the tag objects. Creates the
+ * appropriate tag object for the incoming tag name
+ * and attributes.
+ * @param string $name HTML tag name.
+ * @param hash $attributes Element attributes.
+ * @return SimpleTag Tag object.
+ * @access public
+ */
+ function createTag($name, $attributes) {
+ static $map = array(
+ 'a' => 'SimpleAnchorTag',
+ 'title' => 'SimpleTitleTag',
+ 'base' => 'SimpleBaseTag',
+ 'button' => 'SimpleButtonTag',
+ 'textarea' => 'SimpleTextAreaTag',
+ 'option' => 'SimpleOptionTag',
+ 'label' => 'SimpleLabelTag',
+ 'form' => 'SimpleFormTag',
+ 'frame' => 'SimpleFrameTag');
+ $attributes = $this->_keysToLowerCase($attributes);
+ if (array_key_exists($name, $map)) {
+ $tag_class = $map[$name];
+ return new $tag_class($attributes);
+ } elseif ($name == 'select') {
+ return $this->_createSelectionTag($attributes);
+ } elseif ($name == 'input') {
+ return $this->_createInputTag($attributes);
+ }
+ return new SimpleTag($name, $attributes);
+ }
+
+ /**
+ * Factory for selection fields.
+ * @param hash $attributes Element attributes.
+ * @return SimpleTag Tag object.
+ * @access protected
+ */
+ function _createSelectionTag($attributes) {
+ if (isset($attributes['multiple'])) {
+ return new MultipleSelectionTag($attributes);
+ }
+ return new SimpleSelectionTag($attributes);
+ }
+
+ /**
+ * Factory for input tags.
+ * @param hash $attributes Element attributes.
+ * @return SimpleTag Tag object.
+ * @access protected
+ */
+ function _createInputTag($attributes) {
+ if (! isset($attributes['type'])) {
+ return new SimpleTextTag($attributes);
+ }
+ $type = strtolower(trim($attributes['type']));
+ $map = array(
+ 'submit' => 'SimpleSubmitTag',
+ 'image' => 'SimpleImageSubmitTag',
+ 'checkbox' => 'SimpleCheckboxTag',
+ 'radio' => 'SimpleRadioButtonTag',
+ 'text' => 'SimpleTextTag',
+ 'hidden' => 'SimpleTextTag',
+ 'password' => 'SimpleTextTag',
+ 'file' => 'SimpleUploadTag');
+ if (array_key_exists($type, $map)) {
+ $tag_class = $map[$type];
+ return new $tag_class($attributes);
+ }
+ return false;
+ }
+
+ /**
+ * Make the keys lower case for case insensitive look-ups.
+ * @param hash $map Hash to convert.
+ * @return hash Unchanged values, but keys lower case.
+ * @access private
+ */
+ function _keysToLowerCase($map) {
+ $lower = array();
+ foreach ($map as $key => $value) {
+ $lower[strtolower($key)] = $value;
+ }
+ return $lower;
+ }
+}
+
+/**
+ * SAX event handler. Maintains a list of
+ * open tags and dispatches them as they close.
+ * @package SimpleTest
+ * @subpackage WebTester
+ */
+class SimplePageBuilder extends SimpleSaxListener {
+ var $_tags;
+ var $_page;
+ var $_private_content_tag;
+
+ /**
+ * Sets the builder up empty.
+ * @access public
+ */
+ function SimplePageBuilder() {
+ $this->SimpleSaxListener();
+ }
+
+ /**
+ * Frees up any references so as to allow the PHP garbage
+ * collection from unset() to work.
+ * @access public
+ */
+ function free() {
+ unset($this->_tags);
+ unset($this->_page);
+ unset($this->_private_content_tags);
+ }
+
+ /**
+ * Reads the raw content and send events
+ * into the page to be built.
+ * @param $response SimpleHttpResponse Fetched response.
+ * @return SimplePage Newly parsed page.
+ * @access public
+ */
+ function &parse($response) {
+ $this->_tags = array();
+ $this->_page = &$this->_createPage($response);
+ $parser = &$this->_createParser($this);
+ $parser->parse($response->getContent());
+ $this->_page->acceptPageEnd();
+ return $this->_page;
+ }
+
+ /**
+ * Creates an empty page.
+ * @return SimplePage New unparsed page.
+ * @access protected
+ */
+ function &_createPage($response) {
+ $page = &new SimplePage($response);
+ return $page;
+ }
+
+ /**
+ * Creates the parser used with the builder.
+ * @param $listener SimpleSaxListener Target of parser.
+ * @return SimpleSaxParser Parser to generate
+ * events for the builder.
+ * @access protected
+ */
+ function &_createParser(&$listener) {
+ $parser = &new SimpleHtmlSaxParser($listener);
+ return $parser;
+ }
+
+ /**
+ * Start of element event. Opens a new tag.
+ * @param string $name Element name.
+ * @param hash $attributes Attributes without content
+ * are marked as true.
+ * @return boolean False on parse error.
+ * @access public
+ */
+ function startElement($name, $attributes) {
+ $factory = &new SimpleTagBuilder();
+ $tag = $factory->createTag($name, $attributes);
+ if (! $tag) {
+ return true;
+ }
+ if ($tag->getTagName() == 'label') {
+ $this->_page->acceptLabelStart($tag);
+ $this->_openTag($tag);
+ return true;
+ }
+ if ($tag->getTagName() == 'form') {
+ $this->_page->acceptFormStart($tag);
+ return true;
+ }
+ if ($tag->getTagName() == 'frameset') {
+ $this->_page->acceptFramesetStart($tag);
+ return true;
+ }
+ if ($tag->getTagName() == 'frame') {
+ $this->_page->acceptFrame($tag);
+ return true;
+ }
+ if ($tag->isPrivateContent() && ! isset($this->_private_content_tag)) {
+ $this->_private_content_tag = &$tag;
+ }
+ if ($tag->expectEndTag()) {
+ $this->_openTag($tag);
+ return true;
+ }
+ $this->_page->acceptTag($tag);
+ return true;
+ }
+
+ /**
+ * End of element event.
+ * @param string $name Element name.
+ * @return boolean False on parse error.
+ * @access public
+ */
+ function endElement($name) {
+ if ($name == 'label') {
+ $this->_page->acceptLabelEnd();
+ return true;
+ }
+ if ($name == 'form') {
+ $this->_page->acceptFormEnd();
+ return true;
+ }
+ if ($name == 'frameset') {
+ $this->_page->acceptFramesetEnd();
+ return true;
+ }
+ if ($this->_hasNamedTagOnOpenTagStack($name)) {
+ $tag = array_pop($this->_tags[$name]);
+ if ($tag->isPrivateContent() && $this->_private_content_tag->getTagName() == $name) {
+ unset($this->_private_content_tag);
+ }
+ $this->_addContentTagToOpenTags($tag);
+ $this->_page->acceptTag($tag);
+ return true;
+ }
+ return true;
+ }
+
+ /**
+ * Test to see if there are any open tags awaiting
+ * closure that match the tag name.
+ * @param string $name Element name.
+ * @return boolean True if any are still open.
+ * @access private
+ */
+ function _hasNamedTagOnOpenTagStack($name) {
+ return isset($this->_tags[$name]) && (count($this->_tags[$name]) > 0);
+ }
+
+ /**
+ * Unparsed, but relevant data. The data is added
+ * to every open tag.
+ * @param string $text May include unparsed tags.
+ * @return boolean False on parse error.
+ * @access public
+ */
+ function addContent($text) {
+ if (isset($this->_private_content_tag)) {
+ $this->_private_content_tag->addContent($text);
+ } else {
+ $this->_addContentToAllOpenTags($text);
+ }
+ return true;
+ }
+
+ /**
+ * Any content fills all currently open tags unless it
+ * is part of an option tag.
+ * @param string $text May include unparsed tags.
+ * @access private
+ */
+ function _addContentToAllOpenTags($text) {
+ foreach (array_keys($this->_tags) as $name) {
+ for ($i = 0, $count = count($this->_tags[$name]); $i < $count; $i++) {
+ $this->_tags[$name][$i]->addContent($text);
+ }
+ }
+ }
+
+ /**
+ * Parsed data in tag form. The parsed tag is added
+ * to every open tag. Used for adding options to select
+ * fields only.
+ * @param SimpleTag $tag Option tags only.
+ * @access private
+ */
+ function _addContentTagToOpenTags(&$tag) {
+ if ($tag->getTagName() != 'option') {
+ return;
+ }
+ foreach (array_keys($this->_tags) as $name) {
+ for ($i = 0, $count = count($this->_tags[$name]); $i < $count; $i++) {
+ $this->_tags[$name][$i]->addTag($tag);
+ }
+ }
+ }
+
+ /**
+ * Opens a tag for receiving content. Multiple tags
+ * will be receiving input at the same time.
+ * @param SimpleTag $tag New content tag.
+ * @access private
+ */
+ function _openTag(&$tag) {
+ $name = $tag->getTagName();
+ if (! in_array($name, array_keys($this->_tags))) {
+ $this->_tags[$name] = array();
+ }
+ $this->_tags[$name][] = &$tag;
+ }
+}
+
+/**
+ * A wrapper for a web page.
+ * @package SimpleTest
+ * @subpackage WebTester
+ */
+class SimplePage {
+ var $_links;
+ var $_title;
+ var $_last_widget;
+ var $_label;
+ var $_left_over_labels;
+ var $_open_forms;
+ var $_complete_forms;
+ var $_frameset;
+ var $_frames;
+ var $_frameset_nesting_level;
+ var $_transport_error;
+ var $_raw;
+ var $_text;
+ var $_sent;
+ var $_headers;
+ var $_method;
+ var $_url;
+ var $_base = false;
+ var $_request_data;
+
+ /**
+ * Parses a page ready to access it's contents.
+ * @param SimpleHttpResponse $response Result of HTTP fetch.
+ * @access public
+ */
+ function SimplePage($response = false) {
+ $this->_links = array();
+ $this->_title = false;
+ $this->_left_over_labels = array();
+ $this->_open_forms = array();
+ $this->_complete_forms = array();
+ $this->_frameset = false;
+ $this->_frames = array();
+ $this->_frameset_nesting_level = 0;
+ $this->_text = false;
+ if ($response) {
+ $this->_extractResponse($response);
+ } else {
+ $this->_noResponse();
+ }
+ }
+
+ /**
+ * Extracts all of the response information.
+ * @param SimpleHttpResponse $response Response being parsed.
+ * @access private
+ */
+ function _extractResponse($response) {
+ $this->_transport_error = $response->getError();
+ $this->_raw = $response->getContent();
+ $this->_sent = $response->getSent();
+ $this->_headers = $response->getHeaders();
+ $this->_method = $response->getMethod();
+ $this->_url = $response->getUrl();
+ $this->_request_data = $response->getRequestData();
+ }
+
+ /**
+ * Sets up a missing response.
+ * @access private
+ */
+ function _noResponse() {
+ $this->_transport_error = 'No page fetched yet';
+ $this->_raw = false;
+ $this->_sent = false;
+ $this->_headers = false;
+ $this->_method = 'GET';
+ $this->_url = false;
+ $this->_request_data = false;
+ }
+
+ /**
+ * Original request as bytes sent down the wire.
+ * @return mixed Sent content.
+ * @access public
+ */
+ function getRequest() {
+ return $this->_sent;
+ }
+
+ /**
+ * Accessor for raw text of page.
+ * @return string Raw unparsed content.
+ * @access public
+ */
+ function getRaw() {
+ return $this->_raw;
+ }
+
+ /**
+ * Accessor for plain text of page as a text browser
+ * would see it.
+ * @return string Plain text of page.
+ * @access public
+ */
+ function getText() {
+ if (! $this->_text) {
+ $this->_text = SimpleHtmlSaxParser::normalise($this->_raw);
+ }
+ return $this->_text;
+ }
+
+ /**
+ * Accessor for raw headers of page.
+ * @return string Header block as text.
+ * @access public
+ */
+ function getHeaders() {
+ if ($this->_headers) {
+ return $this->_headers->getRaw();
+ }
+ return false;
+ }
+
+ /**
+ * Original request method.
+ * @return string GET, POST or HEAD.
+ * @access public
+ */
+ function getMethod() {
+ return $this->_method;
+ }
+
+ /**
+ * Original resource name.
+ * @return SimpleUrl Current url.
+ * @access public
+ */
+ function getUrl() {
+ return $this->_url;
+ }
+
+ /**
+ * Base URL if set via BASE tag page url otherwise
+ * @return SimpleUrl Base url.
+ * @access public
+ */
+ function getBaseUrl() {
+ return $this->_base;
+ }
+
+ /**
+ * Original request data.
+ * @return mixed Sent content.
+ * @access public
+ */
+ function getRequestData() {
+ return $this->_request_data;
+ }
+
+ /**
+ * Accessor for last error.
+ * @return string Error from last response.
+ * @access public
+ */
+ function getTransportError() {
+ return $this->_transport_error;
+ }
+
+ /**
+ * Accessor for current MIME type.
+ * @return string MIME type as string; e.g. 'text/html'
+ * @access public
+ */
+ function getMimeType() {
+ if ($this->_headers) {
+ return $this->_headers->getMimeType();
+ }
+ return false;
+ }
+
+ /**
+ * Accessor for HTTP response code.
+ * @return integer HTTP response code received.
+ * @access public
+ */
+ function getResponseCode() {
+ if ($this->_headers) {
+ return $this->_headers->getResponseCode();
+ }
+ return false;
+ }
+
+ /**
+ * Accessor for last Authentication type. Only valid
+ * straight after a challenge (401).
+ * @return string Description of challenge type.
+ * @access public
+ */
+ function getAuthentication() {
+ if ($this->_headers) {
+ return $this->_headers->getAuthentication();
+ }
+ return false;
+ }
+
+ /**
+ * Accessor for last Authentication realm. Only valid
+ * straight after a challenge (401).
+ * @return string Name of security realm.
+ * @access public
+ */
+ function getRealm() {
+ if ($this->_headers) {
+ return $this->_headers->getRealm();
+ }
+ return false;
+ }
+
+ /**
+ * Accessor for current frame focus. Will be
+ * false as no frames.
+ * @return array Always empty.
+ * @access public
+ */
+ function getFrameFocus() {
+ return array();
+ }
+
+ /**
+ * Sets the focus by index. The integer index starts from 1.
+ * @param integer $choice Chosen frame.
+ * @return boolean Always false.
+ * @access public
+ */
+ function setFrameFocusByIndex($choice) {
+ return false;
+ }
+
+ /**
+ * Sets the focus by name. Always fails for a leaf page.
+ * @param string $name Chosen frame.
+ * @return boolean False as no frames.
+ * @access public
+ */
+ function setFrameFocus($name) {
+ return false;
+ }
+
+ /**
+ * Clears the frame focus. Does nothing for a leaf page.
+ * @access public
+ */
+ function clearFrameFocus() {
+ }
+
+ /**
+ * Adds a tag to the page.
+ * @param SimpleTag $tag Tag to accept.
+ * @access public
+ */
+ function acceptTag(&$tag) {
+ if ($tag->getTagName() == "a") {
+ $this->_addLink($tag);
+ } elseif ($tag->getTagName() == "base") {
+ $this->_setBase($tag);
+ } elseif ($tag->getTagName() == "title") {
+ $this->_setTitle($tag);
+ } elseif ($this->_isFormElement($tag->getTagName())) {
+ for ($i = 0; $i < count($this->_open_forms); $i++) {
+ $this->_open_forms[$i]->addWidget($tag);
+ }
+ $this->_last_widget = &$tag;
+ }
+ }
+
+ /**
+ * Opens a label for a described widget.
+ * @param SimpleFormTag $tag Tag to accept.
+ * @access public
+ */
+ function acceptLabelStart(&$tag) {
+ $this->_label = &$tag;
+ unset($this->_last_widget);
+ }
+
+ /**
+ * Closes the most recently opened label.
+ * @access public
+ */
+ function acceptLabelEnd() {
+ if (isset($this->_label)) {
+ if (isset($this->_last_widget)) {
+ $this->_last_widget->setLabel($this->_label->getText());
+ unset($this->_last_widget);
+ } else {
+ $this->_left_over_labels[] = SimpleTestCompatibility::copy($this->_label);
+ }
+ unset($this->_label);
+ }
+ }
+
+ /**
+ * Tests to see if a tag is a possible form
+ * element.
+ * @param string $name HTML element name.
+ * @return boolean True if form element.
+ * @access private
+ */
+ function _isFormElement($name) {
+ return in_array($name, array('input', 'button', 'textarea', 'select'));
+ }
+
+ /**
+ * Opens a form. New widgets go here.
+ * @param SimpleFormTag $tag Tag to accept.
+ * @access public
+ */
+ function acceptFormStart(&$tag) {
+ $this->_open_forms[] = &new SimpleForm($tag, $this);
+ }
+
+ /**
+ * Closes the most recently opened form.
+ * @access public
+ */
+ function acceptFormEnd() {
+ if (count($this->_open_forms)) {
+ $this->_complete_forms[] = array_pop($this->_open_forms);
+ }
+ }
+
+ /**
+ * Opens a frameset. A frameset may contain nested
+ * frameset tags.
+ * @param SimpleFramesetTag $tag Tag to accept.
+ * @access public
+ */
+ function acceptFramesetStart(&$tag) {
+ if (! $this->_isLoadingFrames()) {
+ $this->_frameset = &$tag;
+ }
+ $this->_frameset_nesting_level++;
+ }
+
+ /**
+ * Closes the most recently opened frameset.
+ * @access public
+ */
+ function acceptFramesetEnd() {
+ if ($this->_isLoadingFrames()) {
+ $this->_frameset_nesting_level--;
+ }
+ }
+
+ /**
+ * Takes a single frame tag and stashes it in
+ * the current frame set.
+ * @param SimpleFrameTag $tag Tag to accept.
+ * @access public
+ */
+ function acceptFrame(&$tag) {
+ if ($this->_isLoadingFrames()) {
+ if ($tag->getAttribute('src')) {
+ $this->_frames[] = &$tag;
+ }
+ }
+ }
+
+ /**
+ * Test to see if in the middle of reading
+ * a frameset.
+ * @return boolean True if inframeset.
+ * @access private
+ */
+ function _isLoadingFrames() {
+ if (! $this->_frameset) {
+ return false;
+ }
+ return ($this->_frameset_nesting_level > 0);
+ }
+
+ /**
+ * Test to see if link is an absolute one.
+ * @param string $url Url to test.
+ * @return boolean True if absolute.
+ * @access protected
+ */
+ function _linkIsAbsolute($url) {
+ $parsed = new SimpleUrl($url);
+ return (boolean)($parsed->getScheme() && $parsed->getHost());
+ }
+
+ /**
+ * Adds a link to the page.
+ * @param SimpleAnchorTag $tag Link to accept.
+ * @access protected
+ */
+ function _addLink($tag) {
+ $this->_links[] = $tag;
+ }
+
+ /**
+ * Marker for end of complete page. Any work in
+ * progress can now be closed.
+ * @access public
+ */
+ function acceptPageEnd() {
+ while (count($this->_open_forms)) {
+ $this->_complete_forms[] = array_pop($this->_open_forms);
+ }
+ foreach ($this->_left_over_labels as $label) {
+ for ($i = 0, $count = count($this->_complete_forms); $i < $count; $i++) {
+ $this->_complete_forms[$i]->attachLabelBySelector(
+ new SimpleById($label->getFor()),
+ $label->getText());
+ }
+ }
+ }
+
+ /**
+ * Test for the presence of a frameset.
+ * @return boolean True if frameset.
+ * @access public
+ */
+ function hasFrames() {
+ return (boolean)$this->_frameset;
+ }
+
+ /**
+ * Accessor for frame name and source URL for every frame that
+ * will need to be loaded. Immediate children only.
+ * @return boolean/array False if no frameset or
+ * otherwise a hash of frame URLs.
+ * The key is either a numerical
+ * base one index or the name attribute.
+ * @access public
+ */
+ function getFrameset() {
+ if (! $this->_frameset) {
+ return false;
+ }
+ $urls = array();
+ for ($i = 0; $i < count($this->_frames); $i++) {
+ $name = $this->_frames[$i]->getAttribute('name');
+ $url = new SimpleUrl($this->_frames[$i]->getAttribute('src'));
+ $urls[$name ? $name : $i + 1] = $this->expandUrl($url);
+ }
+ return $urls;
+ }
+
+ /**
+ * Fetches a list of loaded frames.
+ * @return array/string Just the URL for a single page.
+ * @access public
+ */
+ function getFrames() {
+ $url = $this->expandUrl($this->getUrl());
+ return $url->asString();
+ }
+
+ /**
+ * Accessor for a list of all links.
+ * @return array List of urls with scheme of
+ * http or https and hostname.
+ * @access public
+ */
+ function getUrls() {
+ $all = array();
+ foreach ($this->_links as $link) {
+ $url = $this->_getUrlFromLink($link);
+ $all[] = $url->asString();
+ }
+ return $all;
+ }
+
+ /**
+ * Accessor for URLs by the link label. Label will match
+ * regardess of whitespace issues and case.
+ * @param string $label Text of link.
+ * @return array List of links with that label.
+ * @access public
+ */
+ function getUrlsByLabel($label) {
+ $matches = array();
+ foreach ($this->_links as $link) {
+ if ($link->getText() == $label) {
+ $matches[] = $this->_getUrlFromLink($link);
+ }
+ }
+ return $matches;
+ }
+
+ /**
+ * Accessor for a URL by the id attribute.
+ * @param string $id Id attribute of link.
+ * @return SimpleUrl URL with that id of false if none.
+ * @access public
+ */
+ function getUrlById($id) {
+ foreach ($this->_links as $link) {
+ if ($link->getAttribute('id') === (string)$id) {
+ return $this->_getUrlFromLink($link);
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Converts a link tag into a target URL.
+ * @param SimpleAnchor $link Parsed link.
+ * @return SimpleUrl URL with frame target if any.
+ * @access private
+ */
+ function _getUrlFromLink($link) {
+ $url = $this->expandUrl($link->getHref());
+ if ($link->getAttribute('target')) {
+ $url->setTarget($link->getAttribute('target'));
+ }
+ return $url;
+ }
+
+ /**
+ * Expands expandomatic URLs into fully qualified
+ * URLs.
+ * @param SimpleUrl $url Relative URL.
+ * @return SimpleUrl Absolute URL.
+ * @access public
+ */
+ function expandUrl($url) {
+ if (! is_object($url)) {
+ $url = new SimpleUrl($url);
+ }
+ $location = $this->getBaseUrl() ? $this->getBaseUrl() : new SimpleUrl();
+ return $url->makeAbsolute($location->makeAbsolute($this->getUrl()));
+ }
+
+ /**
+ * Sets the base url for the page.
+ * @param SimpleTag $tag Base URL for page.
+ * @access protected
+ */
+ function _setBase(&$tag) {
+ $url = $tag->getAttribute('href');
+ $this->_base = new SimpleUrl($url);
+ }
+
+ /**
+ * Sets the title tag contents.
+ * @param SimpleTitleTag $tag Title of page.
+ * @access protected
+ */
+ function _setTitle(&$tag) {
+ $this->_title = &$tag;
+ }
+
+ /**
+ * Accessor for parsed title.
+ * @return string Title or false if no title is present.
+ * @access public
+ */
+ function getTitle() {
+ if ($this->_title) {
+ return $this->_title->getText();
+ }
+ return false;
+ }
+
+ /**
+ * Finds a held form by button label. Will only
+ * search correctly built forms.
+ * @param SimpleSelector $selector Button finder.
+ * @return SimpleForm Form object containing
+ * the button.
+ * @access public
+ */
+ function &getFormBySubmit($selector) {
+ for ($i = 0; $i < count($this->_complete_forms); $i++) {
+ if ($this->_complete_forms[$i]->hasSubmit($selector)) {
+ return $this->_complete_forms[$i];
+ }
+ }
+ $null = null;
+ return $null;
+ }
+
+ /**
+ * Finds a held form by image using a selector.
+ * Will only search correctly built forms.
+ * @param SimpleSelector $selector Image finder.
+ * @return SimpleForm Form object containing
+ * the image.
+ * @access public
+ */
+ function &getFormByImage($selector) {
+ for ($i = 0; $i < count($this->_complete_forms); $i++) {
+ if ($this->_complete_forms[$i]->hasImage($selector)) {
+ return $this->_complete_forms[$i];
+ }
+ }
+ $null = null;
+ return $null;
+ }
+
+ /**
+ * Finds a held form by the form ID. A way of
+ * identifying a specific form when we have control
+ * of the HTML code.
+ * @param string $id Form label.
+ * @return SimpleForm Form object containing the matching ID.
+ * @access public
+ */
+ function &getFormById($id) {
+ for ($i = 0; $i < count($this->_complete_forms); $i++) {
+ if ($this->_complete_forms[$i]->getId() == $id) {
+ return $this->_complete_forms[$i];
+ }
+ }
+ $null = null;
+ return $null;
+ }
+
+ /**
+ * Sets a field on each form in which the field is
+ * available.
+ * @param SimpleSelector $selector Field finder.
+ * @param string $value Value to set field to.
+ * @return boolean True if value is valid.
+ * @access public
+ */
+ function setField($selector, $value, $position=false) {
+ $is_set = false;
+ for ($i = 0; $i < count($this->_complete_forms); $i++) {
+ if ($this->_complete_forms[$i]->setField($selector, $value, $position)) {
+ $is_set = true;
+ }
+ }
+ return $is_set;
+ }
+
+ /**
+ * Accessor for a form element value within a page.
+ * @param SimpleSelector $selector Field finder.
+ * @return string/boolean A string if the field is
+ * present, false if unchecked
+ * and null if missing.
+ * @access public
+ */
+ function getField($selector) {
+ for ($i = 0; $i < count($this->_complete_forms); $i++) {
+ $value = $this->_complete_forms[$i]->getValue($selector);
+ if (isset($value)) {
+ return $value;
+ }
+ }
+ return null;
+ }
+}
+?> \ No newline at end of file
diff --git a/site/vendors/simpletest/parser.php b/site/vendors/simpletest/parser.php
new file mode 100644
index 0000000..3f3b37b
--- /dev/null
+++ b/site/vendors/simpletest/parser.php
@@ -0,0 +1,764 @@
+<?php
+/**
+ * base include file for SimpleTest
+ * @package SimpleTest
+ * @subpackage MockObjects
+ * @version $Id: parser.php 1723 2008-04-08 00:34:10Z lastcraft $
+ */
+
+/**#@+
+ * Lexer mode stack constants
+ */
+foreach (array('LEXER_ENTER', 'LEXER_MATCHED',
+ 'LEXER_UNMATCHED', 'LEXER_EXIT',
+ 'LEXER_SPECIAL') as $i => $constant) {
+ if (! defined($constant)) {
+ define($constant, $i + 1);
+ }
+}
+/**#@-*/
+
+/**
+ * Compounded regular expression. Any of
+ * the contained patterns could match and
+ * when one does, it's label is returned.
+ * @package SimpleTest
+ * @subpackage WebTester
+ */
+class ParallelRegex {
+ var $_patterns;
+ var $_labels;
+ var $_regex;
+ var $_case;
+
+ /**
+ * Constructor. Starts with no patterns.
+ * @param boolean $case True for case sensitive, false
+ * for insensitive.
+ * @access public
+ */
+ function ParallelRegex($case) {
+ $this->_case = $case;
+ $this->_patterns = array();
+ $this->_labels = array();
+ $this->_regex = null;
+ }
+
+ /**
+ * Adds a pattern with an optional label.
+ * @param string $pattern Perl style regex, but ( and )
+ * lose the usual meaning.
+ * @param string $label Label of regex to be returned
+ * on a match.
+ * @access public
+ */
+ function addPattern($pattern, $label = true) {
+ $count = count($this->_patterns);
+ $this->_patterns[$count] = $pattern;
+ $this->_labels[$count] = $label;
+ $this->_regex = null;
+ }
+
+ /**
+ * Attempts to match all patterns at once against
+ * a string.
+ * @param string $subject String to match against.
+ * @param string $match First matched portion of
+ * subject.
+ * @return boolean True on success.
+ * @access public
+ */
+ function match($subject, &$match) {
+ if (count($this->_patterns) == 0) {
+ return false;
+ }
+ if (! preg_match($this->_getCompoundedRegex(), $subject, $matches)) {
+ $match = '';
+ return false;
+ }
+ $match = $matches[0];
+ for ($i = 1; $i < count($matches); $i++) {
+ if ($matches[$i]) {
+ return $this->_labels[$i - 1];
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Compounds the patterns into a single
+ * regular expression separated with the
+ * "or" operator. Caches the regex.
+ * Will automatically escape (, ) and / tokens.
+ * @param array $patterns List of patterns in order.
+ * @access private
+ */
+ function _getCompoundedRegex() {
+ if ($this->_regex == null) {
+ for ($i = 0, $count = count($this->_patterns); $i < $count; $i++) {
+ $this->_patterns[$i] = '(' . str_replace(
+ array('/', '(', ')'),
+ array('\/', '\(', '\)'),
+ $this->_patterns[$i]) . ')';
+ }
+ $this->_regex = "/" . implode("|", $this->_patterns) . "/" . $this->_getPerlMatchingFlags();
+ }
+ return $this->_regex;
+ }
+
+ /**
+ * Accessor for perl regex mode flags to use.
+ * @return string Perl regex flags.
+ * @access private
+ */
+ function _getPerlMatchingFlags() {
+ return ($this->_case ? "msS" : "msSi");
+ }
+}
+
+/**
+ * States for a stack machine.
+ * @package SimpleTest
+ * @subpackage WebTester
+ */
+class SimpleStateStack {
+ var $_stack;
+
+ /**
+ * Constructor. Starts in named state.
+ * @param string $start Starting state name.
+ * @access public
+ */
+ function SimpleStateStack($start) {
+ $this->_stack = array($start);
+ }
+
+ /**
+ * Accessor for current state.
+ * @return string State.
+ * @access public
+ */
+ function getCurrent() {
+ return $this->_stack[count($this->_stack) - 1];
+ }
+
+ /**
+ * Adds a state to the stack and sets it
+ * to be the current state.
+ * @param string $state New state.
+ * @access public
+ */
+ function enter($state) {
+ array_push($this->_stack, $state);
+ }
+
+ /**
+ * Leaves the current state and reverts
+ * to the previous one.
+ * @return boolean False if we drop off
+ * the bottom of the list.
+ * @access public
+ */
+ function leave() {
+ if (count($this->_stack) == 1) {
+ return false;
+ }
+ array_pop($this->_stack);
+ return true;
+ }
+}
+
+/**
+ * Accepts text and breaks it into tokens.
+ * Some optimisation to make the sure the
+ * content is only scanned by the PHP regex
+ * parser once. Lexer modes must not start
+ * with leading underscores.
+ * @package SimpleTest
+ * @subpackage WebTester
+ */
+class SimpleLexer {
+ var $_regexes;
+ var $_parser;
+ var $_mode;
+ var $_mode_handlers;
+ var $_case;
+
+ /**
+ * Sets up the lexer in case insensitive matching
+ * by default.
+ * @param SimpleSaxParser $parser Handling strategy by
+ * reference.
+ * @param string $start Starting handler.
+ * @param boolean $case True for case sensitive.
+ * @access public
+ */
+ function SimpleLexer(&$parser, $start = "accept", $case = false) {
+ $this->_case = $case;
+ $this->_regexes = array();
+ $this->_parser = &$parser;
+ $this->_mode = &new SimpleStateStack($start);
+ $this->_mode_handlers = array($start => $start);
+ }
+
+ /**
+ * Adds a token search pattern for a particular
+ * parsing mode. The pattern does not change the
+ * current mode.
+ * @param string $pattern Perl style regex, but ( and )
+ * lose the usual meaning.
+ * @param string $mode Should only apply this
+ * pattern when dealing with
+ * this type of input.
+ * @access public
+ */
+ function addPattern($pattern, $mode = "accept") {
+ if (! isset($this->_regexes[$mode])) {
+ $this->_regexes[$mode] = new ParallelRegex($this->_case);
+ }
+ $this->_regexes[$mode]->addPattern($pattern);
+ if (! isset($this->_mode_handlers[$mode])) {
+ $this->_mode_handlers[$mode] = $mode;
+ }
+ }
+
+ /**
+ * Adds a pattern that will enter a new parsing
+ * mode. Useful for entering parenthesis, strings,
+ * tags, etc.
+ * @param string $pattern Perl style regex, but ( and )
+ * lose the usual meaning.
+ * @param string $mode Should only apply this
+ * pattern when dealing with
+ * this type of input.
+ * @param string $new_mode Change parsing to this new
+ * nested mode.
+ * @access public
+ */
+ function addEntryPattern($pattern, $mode, $new_mode) {
+ if (! isset($this->_regexes[$mode])) {
+ $this->_regexes[$mode] = new ParallelRegex($this->_case);
+ }
+ $this->_regexes[$mode]->addPattern($pattern, $new_mode);
+ if (! isset($this->_mode_handlers[$new_mode])) {
+ $this->_mode_handlers[$new_mode] = $new_mode;
+ }
+ }
+
+ /**
+ * Adds a pattern that will exit the current mode
+ * and re-enter the previous one.
+ * @param string $pattern Perl style regex, but ( and )
+ * lose the usual meaning.
+ * @param string $mode Mode to leave.
+ * @access public
+ */
+ function addExitPattern($pattern, $mode) {
+ if (! isset($this->_regexes[$mode])) {
+ $this->_regexes[$mode] = new ParallelRegex($this->_case);
+ }
+ $this->_regexes[$mode]->addPattern($pattern, "__exit");
+ if (! isset($this->_mode_handlers[$mode])) {
+ $this->_mode_handlers[$mode] = $mode;
+ }
+ }
+
+ /**
+ * Adds a pattern that has a special mode. Acts as an entry
+ * and exit pattern in one go, effectively calling a special
+ * parser handler for this token only.
+ * @param string $pattern Perl style regex, but ( and )
+ * lose the usual meaning.
+ * @param string $mode Should only apply this
+ * pattern when dealing with
+ * this type of input.
+ * @param string $special Use this mode for this one token.
+ * @access public
+ */
+ function addSpecialPattern($pattern, $mode, $special) {
+ if (! isset($this->_regexes[$mode])) {
+ $this->_regexes[$mode] = new ParallelRegex($this->_case);
+ }
+ $this->_regexes[$mode]->addPattern($pattern, "_$special");
+ if (! isset($this->_mode_handlers[$special])) {
+ $this->_mode_handlers[$special] = $special;
+ }
+ }
+
+ /**
+ * Adds a mapping from a mode to another handler.
+ * @param string $mode Mode to be remapped.
+ * @param string $handler New target handler.
+ * @access public
+ */
+ function mapHandler($mode, $handler) {
+ $this->_mode_handlers[$mode] = $handler;
+ }
+
+ /**
+ * Splits the page text into tokens. Will fail
+ * if the handlers report an error or if no
+ * content is consumed. If successful then each
+ * unparsed and parsed token invokes a call to the
+ * held listener.
+ * @param string $raw Raw HTML text.
+ * @return boolean True on success, else false.
+ * @access public
+ */
+ function parse($raw) {
+ if (! isset($this->_parser)) {
+ return false;
+ }
+ $length = strlen($raw);
+ while (is_array($parsed = $this->_reduce($raw))) {
+ list($raw, $unmatched, $matched, $mode) = $parsed;
+ if (! $this->_dispatchTokens($unmatched, $matched, $mode)) {
+ return false;
+ }
+ if ($raw === '') {
+ return true;
+ }
+ if (strlen($raw) == $length) {
+ return false;
+ }
+ $length = strlen($raw);
+ }
+ if (! $parsed) {
+ return false;
+ }
+ return $this->_invokeParser($raw, LEXER_UNMATCHED);
+ }
+
+ /**
+ * Sends the matched token and any leading unmatched
+ * text to the parser changing the lexer to a new
+ * mode if one is listed.
+ * @param string $unmatched Unmatched leading portion.
+ * @param string $matched Actual token match.
+ * @param string $mode Mode after match. A boolean
+ * false mode causes no change.
+ * @return boolean False if there was any error
+ * from the parser.
+ * @access private
+ */
+ function _dispatchTokens($unmatched, $matched, $mode = false) {
+ if (! $this->_invokeParser($unmatched, LEXER_UNMATCHED)) {
+ return false;
+ }
+ if (is_bool($mode)) {
+ return $this->_invokeParser($matched, LEXER_MATCHED);
+ }
+ if ($this->_isModeEnd($mode)) {
+ if (! $this->_invokeParser($matched, LEXER_EXIT)) {
+ return false;
+ }
+ return $this->_mode->leave();
+ }
+ if ($this->_isSpecialMode($mode)) {
+ $this->_mode->enter($this->_decodeSpecial($mode));
+ if (! $this->_invokeParser($matched, LEXER_SPECIAL)) {
+ return false;
+ }
+ return $this->_mode->leave();
+ }
+ $this->_mode->enter($mode);
+ return $this->_invokeParser($matched, LEXER_ENTER);
+ }
+
+ /**
+ * Tests to see if the new mode is actually to leave
+ * the current mode and pop an item from the matching
+ * mode stack.
+ * @param string $mode Mode to test.
+ * @return boolean True if this is the exit mode.
+ * @access private
+ */
+ function _isModeEnd($mode) {
+ return ($mode === "__exit");
+ }
+
+ /**
+ * Test to see if the mode is one where this mode
+ * is entered for this token only and automatically
+ * leaves immediately afterwoods.
+ * @param string $mode Mode to test.
+ * @return boolean True if this is the exit mode.
+ * @access private
+ */
+ function _isSpecialMode($mode) {
+ return (strncmp($mode, "_", 1) == 0);
+ }
+
+ /**
+ * Strips the magic underscore marking single token
+ * modes.
+ * @param string $mode Mode to decode.
+ * @return string Underlying mode name.
+ * @access private
+ */
+ function _decodeSpecial($mode) {
+ return substr($mode, 1);
+ }
+
+ /**
+ * Calls the parser method named after the current
+ * mode. Empty content will be ignored. The lexer
+ * has a parser handler for each mode in the lexer.
+ * @param string $content Text parsed.
+ * @param boolean $is_match Token is recognised rather
+ * than unparsed data.
+ * @access private
+ */
+ function _invokeParser($content, $is_match) {
+ if (($content === '') || ($content === false)) {
+ return true;
+ }
+ $handler = $this->_mode_handlers[$this->_mode->getCurrent()];
+ return $this->_parser->$handler($content, $is_match);
+ }
+
+ /**
+ * Tries to match a chunk of text and if successful
+ * removes the recognised chunk and any leading
+ * unparsed data. Empty strings will not be matched.
+ * @param string $raw The subject to parse. This is the
+ * content that will be eaten.
+ * @return array/boolean Three item list of unparsed
+ * content followed by the
+ * recognised token and finally the
+ * action the parser is to take.
+ * True if no match, false if there
+ * is a parsing error.
+ * @access private
+ */
+ function _reduce($raw) {
+ if ($action = $this->_regexes[$this->_mode->getCurrent()]->match($raw, $match)) {
+ $unparsed_character_count = strpos($raw, $match);
+ $unparsed = substr($raw, 0, $unparsed_character_count);
+ $raw = substr($raw, $unparsed_character_count + strlen($match));
+ return array($raw, $unparsed, $match, $action);
+ }
+ return true;
+ }
+}
+
+/**
+ * Breaks HTML into SAX events.
+ * @package SimpleTest
+ * @subpackage WebTester
+ */
+class SimpleHtmlLexer extends SimpleLexer {
+
+ /**
+ * Sets up the lexer with case insensitive matching
+ * and adds the HTML handlers.
+ * @param SimpleSaxParser $parser Handling strategy by
+ * reference.
+ * @access public
+ */
+ function SimpleHtmlLexer(&$parser) {
+ $this->SimpleLexer($parser, 'text');
+ $this->mapHandler('text', 'acceptTextToken');
+ $this->_addSkipping();
+ foreach ($this->_getParsedTags() as $tag) {
+ $this->_addTag($tag);
+ }
+ $this->_addInTagTokens();
+ }
+
+ /**
+ * List of parsed tags. Others are ignored.
+ * @return array List of searched for tags.
+ * @access private
+ */
+ function _getParsedTags() {
+ return array('a', 'base', 'title', 'form', 'input', 'button', 'textarea', 'select',
+ 'option', 'frameset', 'frame', 'label');
+ }
+
+ /**
+ * The lexer has to skip certain sections such
+ * as server code, client code and styles.
+ * @access private
+ */
+ function _addSkipping() {
+ $this->mapHandler('css', 'ignore');
+ $this->addEntryPattern('<style', 'text', 'css');
+ $this->addExitPattern('</style>', 'css');
+ $this->mapHandler('js', 'ignore');
+ $this->addEntryPattern('<script', 'text', 'js');
+ $this->addExitPattern('</script>', 'js');
+ $this->mapHandler('comment', 'ignore');
+ $this->addEntryPattern('<!--', 'text', 'comment');
+ $this->addExitPattern('-->', 'comment');
+ }
+
+ /**
+ * Pattern matches to start and end a tag.
+ * @param string $tag Name of tag to scan for.
+ * @access private
+ */
+ function _addTag($tag) {
+ $this->addSpecialPattern("</$tag>", 'text', 'acceptEndToken');
+ $this->addEntryPattern("<$tag", 'text', 'tag');
+ }
+
+ /**
+ * Pattern matches to parse the inside of a tag
+ * including the attributes and their quoting.
+ * @access private
+ */
+ function _addInTagTokens() {
+ $this->mapHandler('tag', 'acceptStartToken');
+ $this->addSpecialPattern('\s+', 'tag', 'ignore');
+ $this->_addAttributeTokens();
+ $this->addExitPattern('/>', 'tag');
+ $this->addExitPattern('>', 'tag');
+ }
+
+ /**
+ * Matches attributes that are either single quoted,
+ * double quoted or unquoted.
+ * @access private
+ */
+ function _addAttributeTokens() {
+ $this->mapHandler('dq_attribute', 'acceptAttributeToken');
+ $this->addEntryPattern('=\s*"', 'tag', 'dq_attribute');
+ $this->addPattern("\\\\\"", 'dq_attribute');
+ $this->addExitPattern('"', 'dq_attribute');
+ $this->mapHandler('sq_attribute', 'acceptAttributeToken');
+ $this->addEntryPattern("=\s*'", 'tag', 'sq_attribute');
+ $this->addPattern("\\\\'", 'sq_attribute');
+ $this->addExitPattern("'", 'sq_attribute');
+ $this->mapHandler('uq_attribute', 'acceptAttributeToken');
+ $this->addSpecialPattern('=\s*[^>\s]*', 'tag', 'uq_attribute');
+ }
+}
+
+/**
+ * Converts HTML tokens into selected SAX events.
+ * @package SimpleTest
+ * @subpackage WebTester
+ */
+class SimpleHtmlSaxParser {
+ var $_lexer;
+ var $_listener;
+ var $_tag;
+ var $_attributes;
+ var $_current_attribute;
+
+ /**
+ * Sets the listener.
+ * @param SimpleSaxListener $listener SAX event handler.
+ * @access public
+ */
+ function SimpleHtmlSaxParser(&$listener) {
+ $this->_listener = &$listener;
+ $this->_lexer = &$this->createLexer($this);
+ $this->_tag = '';
+ $this->_attributes = array();
+ $this->_current_attribute = '';
+ }
+
+ /**
+ * Runs the content through the lexer which
+ * should call back to the acceptors.
+ * @param string $raw Page text to parse.
+ * @return boolean False if parse error.
+ * @access public
+ */
+ function parse($raw) {
+ return $this->_lexer->parse($raw);
+ }
+
+ /**
+ * Sets up the matching lexer. Starts in 'text' mode.
+ * @param SimpleSaxParser $parser Event generator, usually $self.
+ * @return SimpleLexer Lexer suitable for this parser.
+ * @access public
+ * @static
+ */
+ function &createLexer(&$parser) {
+ $lexer = &new SimpleHtmlLexer($parser);
+ return $lexer;
+ }
+
+ /**
+ * Accepts a token from the tag mode. If the
+ * starting element completes then the element
+ * is dispatched and the current attributes
+ * set back to empty. The element or attribute
+ * name is converted to lower case.
+ * @param string $token Incoming characters.
+ * @param integer $event Lexer event type.
+ * @return boolean False if parse error.
+ * @access public
+ */
+ function acceptStartToken($token, $event) {
+ if ($event == LEXER_ENTER) {
+ $this->_tag = strtolower(substr($token, 1));
+ return true;
+ }
+ if ($event == LEXER_EXIT) {
+ $success = $this->_listener->startElement(
+ $this->_tag,
+ $this->_attributes);
+ $this->_tag = '';
+ $this->_attributes = array();
+ return $success;
+ }
+ if ($token != '=') {
+ $this->_current_attribute = strtolower(SimpleHtmlSaxParser::decodeHtml($token));
+ $this->_attributes[$this->_current_attribute] = '';
+ }
+ return true;
+ }
+
+ /**
+ * Accepts a token from the end tag mode.
+ * The element name is converted to lower case.
+ * @param string $token Incoming characters.
+ * @param integer $event Lexer event type.
+ * @return boolean False if parse error.
+ * @access public
+ */
+ function acceptEndToken($token, $event) {
+ if (! preg_match('/<\/(.*)>/', $token, $matches)) {
+ return false;
+ }
+ return $this->_listener->endElement(strtolower($matches[1]));
+ }
+
+ /**
+ * Part of the tag data.
+ * @param string $token Incoming characters.
+ * @param integer $event Lexer event type.
+ * @return boolean False if parse error.
+ * @access public
+ */
+ function acceptAttributeToken($token, $event) {
+ if ($this->_current_attribute) {
+ if ($event == LEXER_UNMATCHED) {
+ $this->_attributes[$this->_current_attribute] .=
+ SimpleHtmlSaxParser::decodeHtml($token);
+ }
+ if ($event == LEXER_SPECIAL) {
+ $this->_attributes[$this->_current_attribute] .=
+ preg_replace('/^=\s*/' , '', SimpleHtmlSaxParser::decodeHtml($token));
+ }
+ }
+ return true;
+ }
+
+ /**
+ * A character entity.
+ * @param string $token Incoming characters.
+ * @param integer $event Lexer event type.
+ * @return boolean False if parse error.
+ * @access public
+ */
+ function acceptEntityToken($token, $event) {
+ }
+
+ /**
+ * Character data between tags regarded as
+ * important.
+ * @param string $token Incoming characters.
+ * @param integer $event Lexer event type.
+ * @return boolean False if parse error.
+ * @access public
+ */
+ function acceptTextToken($token, $event) {
+ return $this->_listener->addContent($token);
+ }
+
+ /**
+ * Incoming data to be ignored.
+ * @param string $token Incoming characters.
+ * @param integer $event Lexer event type.
+ * @return boolean False if parse error.
+ * @access public
+ */
+ function ignore($token, $event) {
+ return true;
+ }
+
+ /**
+ * Decodes any HTML entities.
+ * @param string $html Incoming HTML.
+ * @return string Outgoing plain text.
+ * @access public
+ * @static
+ */
+ function decodeHtml($html) {
+ return html_entity_decode($html, ENT_QUOTES);
+ }
+
+ /**
+ * Turns HTML into text browser visible text. Images
+ * are converted to their alt text and tags are supressed.
+ * Entities are converted to their visible representation.
+ * @param string $html HTML to convert.
+ * @return string Plain text.
+ * @access public
+ * @static
+ */
+ function normalise($html) {
+ $text = preg_replace('|<!--.*?-->|', '', $html);
+ $text = preg_replace('|<script[^>]*>.*?</script>|', '', $text);
+ $text = preg_replace('|<img[^>]*alt\s*=\s*"([^"]*)"[^>]*>|', ' \1 ', $text);
+ $text = preg_replace('|<img[^>]*alt\s*=\s*\'([^\']*)\'[^>]*>|', ' \1 ', $text);
+ $text = preg_replace('|<img[^>]*alt\s*=\s*([a-zA-Z_]+)[^>]*>|', ' \1 ', $text);
+ $text = preg_replace('|<[^>]*>|', '', $text);
+ $text = SimpleHtmlSaxParser::decodeHtml($text);
+ $text = preg_replace('|\s+|', ' ', $text);
+ return trim(trim($text), "\xA0"); // TODO: The \xAO is a &nbsp;. Add a test for this.
+ }
+}
+
+/**
+ * SAX event handler.
+ * @package SimpleTest
+ * @subpackage WebTester
+ * @abstract
+ */
+class SimpleSaxListener {
+
+ /**
+ * Sets the document to write to.
+ * @access public
+ */
+ function SimpleSaxListener() {
+ }
+
+ /**
+ * Start of element event.
+ * @param string $name Element name.
+ * @param hash $attributes Name value pairs.
+ * Attributes without content
+ * are marked as true.
+ * @return boolean False on parse error.
+ * @access public
+ */
+ function startElement($name, $attributes) {
+ }
+
+ /**
+ * End of element event.
+ * @param string $name Element name.
+ * @return boolean False on parse error.
+ * @access public
+ */
+ function endElement($name) {
+ }
+
+ /**
+ * Unparsed, but relevant data.
+ * @param string $text May include unparsed tags.
+ * @return boolean False on parse error.
+ * @access public
+ */
+ function addContent($text) {
+ }
+}
+?> \ No newline at end of file
diff --git a/site/vendors/simpletest/reflection_php4.php b/site/vendors/simpletest/reflection_php4.php
new file mode 100644
index 0000000..6c93915
--- /dev/null
+++ b/site/vendors/simpletest/reflection_php4.php
@@ -0,0 +1,136 @@
+<?php
+/**
+ * base include file for SimpleTest
+ * @package SimpleTest
+ * @subpackage UnitTester
+ * @version $Id: reflection_php4.php 1672 2008-03-02 04:47:34Z edwardzyang $
+ */
+
+/**
+ * Version specific reflection API.
+ * @package SimpleTest
+ * @subpackage UnitTester
+ * @ignore duplicate with reflection_php5.php
+ */
+class SimpleReflection {
+ var $_interface;
+
+ /**
+ * Stashes the class/interface.
+ * @param string $interface Class or interface
+ * to inspect.
+ */
+ function SimpleReflection($interface) {
+ $this->_interface = $interface;
+ }
+
+ /**
+ * Checks that a class has been declared.
+ * @return boolean True if defined.
+ * @access public
+ */
+ function classExists() {
+ return class_exists($this->_interface);
+ }
+
+ /**
+ * Needed to kill the autoload feature in PHP5
+ * for classes created dynamically.
+ * @return boolean True if defined.
+ * @access public
+ */
+ function classExistsSansAutoload() {
+ return class_exists($this->_interface);
+ }
+
+ /**
+ * Checks that a class or interface has been
+ * declared.
+ * @return boolean True if defined.
+ * @access public
+ */
+ function classOrInterfaceExists() {
+ return class_exists($this->_interface);
+ }
+
+ /**
+ * Needed to kill the autoload feature in PHP5
+ * for classes created dynamically.
+ * @return boolean True if defined.
+ * @access public
+ */
+ function classOrInterfaceExistsSansAutoload() {
+ return class_exists($this->_interface);
+ }
+
+ /**
+ * Gets the list of methods on a class or
+ * interface.
+ * @returns array List of method names.
+ * @access public
+ */
+ function getMethods() {
+ return get_class_methods($this->_interface);
+ }
+
+ /**
+ * Gets the list of interfaces from a class. If the
+ * class name is actually an interface then just that
+ * interface is returned.
+ * @returns array List of interfaces.
+ * @access public
+ */
+ function getInterfaces() {
+ return array();
+ }
+
+ /**
+ * Finds the parent class name.
+ * @returns string Parent class name.
+ * @access public
+ */
+ function getParent() {
+ return strtolower(get_parent_class($this->_interface));
+ }
+
+ /**
+ * Determines if the class is abstract, which for PHP 4
+ * will never be the case.
+ * @returns boolean True if abstract.
+ * @access public
+ */
+ function isAbstract() {
+ return false;
+ }
+
+ /**
+ * Determines if the the entity is an interface, which for PHP 4
+ * will never be the case.
+ * @returns boolean True if interface.
+ * @access public
+ */
+ function isInterface() {
+ return false;
+ }
+
+ /**
+ * Scans for final methods, but as it's PHP 4 there
+ * aren't any.
+ * @returns boolean True if the class has a final method.
+ * @access public
+ */
+ function hasFinal() {
+ return false;
+ }
+
+ /**
+ * Gets the source code matching the declaration
+ * of a method.
+ * @param string $method Method name.
+ * @access public
+ */
+ function getSignature($method) {
+ return "function &$method()";
+ }
+}
+?> \ No newline at end of file
diff --git a/site/vendors/simpletest/reflection_php5.php b/site/vendors/simpletest/reflection_php5.php
new file mode 100644
index 0000000..8383bcc
--- /dev/null
+++ b/site/vendors/simpletest/reflection_php5.php
@@ -0,0 +1,380 @@
+<?php
+/**
+ * base include file for SimpleTest
+ * @package SimpleTest
+ * @subpackage UnitTester
+ * @version $Id: reflection_php5.php 1683 2008-03-05 21:57:08Z lastcraft $
+ */
+
+/**
+ * Version specific reflection API.
+ * @package SimpleTest
+ * @subpackage UnitTester
+ */
+class SimpleReflection {
+ var $_interface;
+
+ /**
+ * Stashes the class/interface.
+ * @param string $interface Class or interface
+ * to inspect.
+ */
+ function SimpleReflection($interface) {
+ $this->_interface = $interface;
+ }
+
+ /**
+ * Checks that a class has been declared. Versions
+ * before PHP5.0.2 need a check that it's not really
+ * an interface.
+ * @return boolean True if defined.
+ * @access public
+ */
+ function classExists() {
+ if (! class_exists($this->_interface)) {
+ return false;
+ }
+ $reflection = new ReflectionClass($this->_interface);
+ return ! $reflection->isInterface();
+ }
+
+ /**
+ * Needed to kill the autoload feature in PHP5
+ * for classes created dynamically.
+ * @return boolean True if defined.
+ * @access public
+ */
+ function classExistsSansAutoload() {
+ return class_exists($this->_interface, false);
+ }
+
+ /**
+ * Checks that a class or interface has been
+ * declared.
+ * @return boolean True if defined.
+ * @access public
+ */
+ function classOrInterfaceExists() {
+ return $this->_classOrInterfaceExistsWithAutoload($this->_interface, true);
+ }
+
+ /**
+ * Needed to kill the autoload feature in PHP5
+ * for classes created dynamically.
+ * @return boolean True if defined.
+ * @access public
+ */
+ function classOrInterfaceExistsSansAutoload() {
+ return $this->_classOrInterfaceExistsWithAutoload($this->_interface, false);
+ }
+
+ /**
+ * Needed to select the autoload feature in PHP5
+ * for classes created dynamically.
+ * @param string $interface Class or interface name.
+ * @param boolean $autoload True totriggerautoload.
+ * @return boolean True if interface defined.
+ * @access private
+ */
+ function _classOrInterfaceExistsWithAutoload($interface, $autoload) {
+ if (function_exists('interface_exists')) {
+ if (interface_exists($this->_interface, $autoload)) {
+ return true;
+ }
+ }
+ return class_exists($this->_interface, $autoload);
+ }
+
+ /**
+ * Gets the list of methods on a class or
+ * interface.
+ * @returns array List of method names.
+ * @access public
+ */
+ function getMethods() {
+ return array_unique(get_class_methods($this->_interface));
+ }
+
+ /**
+ * Gets the list of interfaces from a class. If the
+ * class name is actually an interface then just that
+ * interface is returned.
+ * @returns array List of interfaces.
+ * @access public
+ */
+ function getInterfaces() {
+ $reflection = new ReflectionClass($this->_interface);
+ if ($reflection->isInterface()) {
+ return array($this->_interface);
+ }
+ return $this->_onlyParents($reflection->getInterfaces());
+ }
+
+ /**
+ * Gets the list of methods for the implemented
+ * interfaces only.
+ * @returns array List of enforced method signatures.
+ * @access public
+ */
+ function getInterfaceMethods() {
+ $methods = array();
+ foreach ($this->getInterfaces() as $interface) {
+ $methods = array_merge($methods, get_class_methods($interface));
+ }
+ return array_unique($methods);
+ }
+
+ /**
+ * Checks to see if the method signature has to be tightly
+ * specified.
+ * @param string $method Method name.
+ * @returns boolean True if enforced.
+ * @access private
+ */
+ function _isInterfaceMethod($method) {
+ return in_array($method, $this->getInterfaceMethods());
+ }
+
+ /**
+ * Finds the parent class name.
+ * @returns string Parent class name.
+ * @access public
+ */
+ function getParent() {
+ $reflection = new ReflectionClass($this->_interface);
+ $parent = $reflection->getParentClass();
+ if ($parent) {
+ return $parent->getName();
+ }
+ return false;
+ }
+
+ /**
+ * Trivially determines if the class is abstract.
+ * @returns boolean True if abstract.
+ * @access public
+ */
+ function isAbstract() {
+ $reflection = new ReflectionClass($this->_interface);
+ return $reflection->isAbstract();
+ }
+
+ /**
+ * Trivially determines if the class is an interface.
+ * @returns boolean True if interface.
+ * @access public
+ */
+ function isInterface() {
+ $reflection = new ReflectionClass($this->_interface);
+ return $reflection->isInterface();
+ }
+
+ /**
+ * Scans for final methods, as they screw up inherited
+ * mocks by not allowing you to override them.
+ * @returns boolean True if the class has a final method.
+ * @access public
+ */
+ function hasFinal() {
+ $reflection = new ReflectionClass($this->_interface);
+ foreach ($reflection->getMethods() as $method) {
+ if ($method->isFinal()) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Whittles a list of interfaces down to only the
+ * necessary top level parents.
+ * @param array $interfaces Reflection API interfaces
+ * to reduce.
+ * @returns array List of parent interface names.
+ * @access private
+ */
+ function _onlyParents($interfaces) {
+ $parents = array();
+ $blacklist = array();
+ foreach ($interfaces as $interface) {
+ foreach($interfaces as $possible_parent) {
+ if ($interface->getName() == $possible_parent->getName()) {
+ continue;
+ }
+ if ($interface->isSubClassOf($possible_parent)) {
+ $blacklist[$possible_parent->getName()] = true;
+ }
+ }
+ if (!isset($blacklist[$interface->getName()])) {
+ $parents[] = $interface->getName();
+ }
+ }
+ return $parents;
+ }
+
+ /**
+ * Checks whether a method is abstract or not.
+ * @param string $name Method name.
+ * @return bool true if method is abstract, else false
+ * @access private
+ */
+ function _isAbstractMethod($name) {
+ $interface = new ReflectionClass($this->_interface);
+ if (! $interface->hasMethod($name)) {
+ return false;
+ }
+ return $interface->getMethod($name)->isAbstract();
+ }
+
+ /**
+ * Checks whether a method is the constructor.
+ * @param string $name Method name.
+ * @return bool true if method is the constructor
+ * @access private
+ */
+ function _isConstructor($name) {
+ return ($name == '__construct') || ($name == $this->_interface);
+ }
+
+ /**
+ * Checks whether a method is abstract in all parents or not.
+ * @param string $name Method name.
+ * @return bool true if method is abstract in parent, else false
+ * @access private
+ */
+ function _isAbstractMethodInParents($name) {
+ $interface = new ReflectionClass($this->_interface);
+ $parent = $interface->getParentClass();
+ while($parent) {
+ if (! $parent->hasMethod($name)) {
+ return false;
+ }
+ if ($parent->getMethod($name)->isAbstract()) {
+ return true;
+ }
+ $parent = $parent->getParentClass();
+ }
+ return false;
+ }
+
+ /**
+ * Checks whether a method is static or not.
+ * @param string $name Method name
+ * @return bool true if method is static, else false
+ * @access private
+ */
+ function _isStaticMethod($name) {
+ $interface = new ReflectionClass($this->_interface);
+ if (! $interface->hasMethod($name)) {
+ return false;
+ }
+ return $interface->getMethod($name)->isStatic();
+ }
+
+ /**
+ * Writes the source code matching the declaration
+ * of a method.
+ * @param string $name Method name.
+ * @return string Method signature up to last
+ * bracket.
+ * @access public
+ */
+ function getSignature($name) {
+ if ($name == '__set') {
+ return 'function __set($key, $value)';
+ }
+ if ($name == '__call') {
+ return 'function __call($method, $arguments)';
+ }
+ if (version_compare(phpversion(), '5.1.0', '>=')) {
+ if (in_array($name, array('__get', '__isset', $name == '__unset'))) {
+ return "function {$name}(\$key)";
+ }
+ }
+ if ($name == '__toString') {
+ return "function $name()";
+ }
+ if ($this->_isInterfaceMethod($name) ||
+ $this->_isAbstractMethod($name) ||
+ $this->_isAbstractMethodInParents($name) ||
+ $this->_isStaticMethod($name)) {
+ return $this->_getFullSignature($name);
+ }
+ return "function $name()";
+ }
+
+ /**
+ * For a signature specified in an interface, full
+ * details must be replicated to be a valid implementation.
+ * @param string $name Method name.
+ * @return string Method signature up to last
+ * bracket.
+ * @access private
+ */
+ function _getFullSignature($name) {
+ $interface = new ReflectionClass($this->_interface);
+ $method = $interface->getMethod($name);
+ $reference = $method->returnsReference() ? '&' : '';
+ $static = $method->isStatic() ? 'static ' : '';
+ return "{$static}function $reference$name(" .
+ implode(', ', $this->_getParameterSignatures($method)) .
+ ")";
+ }
+
+ /**
+ * Gets the source code for each parameter.
+ * @param ReflectionMethod $method Method object from
+ * reflection API
+ * @return array List of strings, each
+ * a snippet of code.
+ * @access private
+ */
+ function _getParameterSignatures($method) {
+ $signatures = array();
+ foreach ($method->getParameters() as $parameter) {
+ $signature = '';
+ $type = $parameter->getClass();
+ if (is_null($type) && version_compare(phpversion(), '5.1.0', '>=') && $parameter->isArray()) {
+ $signature .= 'array ';
+ } elseif (!is_null($type)) {
+ $signature .= $type->getName() . ' ';
+ }
+ if ($parameter->isPassedByReference()) {
+ $signature .= '&';
+ }
+ $signature .= '$' . $this->_suppressSpurious($parameter->getName());
+ if ($this->_isOptional($parameter)) {
+ $signature .= ' = null';
+ }
+ $signatures[] = $signature;
+ }
+ return $signatures;
+ }
+
+ /**
+ * The SPL library has problems with the
+ * Reflection library. In particular, you can
+ * get extra characters in parameter names :(.
+ * @param string $name Parameter name.
+ * @return string Cleaner name.
+ * @access private
+ */
+ function _suppressSpurious($name) {
+ return str_replace(array('[', ']', ' '), '', $name);
+ }
+
+ /**
+ * Test of a reflection parameter being optional
+ * that works with early versions of PHP5.
+ * @param reflectionParameter $parameter Is this optional.
+ * @return boolean True if optional.
+ * @access private
+ */
+ function _isOptional($parameter) {
+ if (method_exists($parameter, 'isOptional')) {
+ return $parameter->isOptional();
+ }
+ return false;
+ }
+}
+?>
diff --git a/site/vendors/simpletest/remote.php b/site/vendors/simpletest/remote.php
new file mode 100644
index 0000000..8889ed7
--- /dev/null
+++ b/site/vendors/simpletest/remote.php
@@ -0,0 +1,117 @@
+<?php
+/**
+ * base include file for SimpleTest
+ * @package SimpleTest
+ * @subpackage UnitTester
+ * @version $Id: remote.php 1723 2008-04-08 00:34:10Z lastcraft $
+ */
+
+/**#@+
+ * include other SimpleTest class files
+ */
+require_once(dirname(__FILE__) . '/browser.php');
+require_once(dirname(__FILE__) . '/xml.php');
+require_once(dirname(__FILE__) . '/test_case.php');
+/**#@-*/
+
+/**
+ * Runs an XML formated test on a remote server.
+ * @package SimpleTest
+ * @subpackage UnitTester
+ */
+class RemoteTestCase {
+ var $_url;
+ var $_dry_url;
+ var $_size;
+
+ /**
+ * Sets the location of the remote test.
+ * @param string $url Test location.
+ * @param string $dry_url Location for dry run.
+ * @access public
+ */
+ function RemoteTestCase($url, $dry_url = false) {
+ $this->_url = $url;
+ $this->_dry_url = $dry_url ? $dry_url : $url;
+ $this->_size = false;
+ }
+
+ /**
+ * Accessor for the test name for subclasses.
+ * @return string Name of the test.
+ * @access public
+ */
+ function getLabel() {
+ return $this->_url;
+ }
+
+ /**
+ * Runs the top level test for this class. Currently
+ * reads the data as a single chunk. I'll fix this
+ * once I have added iteration to the browser.
+ * @param SimpleReporter $reporter Target of test results.
+ * @returns boolean True if no failures.
+ * @access public
+ */
+ function run(&$reporter) {
+ $browser = &$this->_createBrowser();
+ $xml = $browser->get($this->_url);
+ if (! $xml) {
+ trigger_error('Cannot read remote test URL [' . $this->_url . ']');
+ return false;
+ }
+ $parser = &$this->_createParser($reporter);
+ if (! $parser->parse($xml)) {
+ trigger_error('Cannot parse incoming XML from [' . $this->_url . ']');
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Creates a new web browser object for fetching
+ * the XML report.
+ * @return SimpleBrowser New browser.
+ * @access protected
+ */
+ function &_createBrowser() {
+ $browser = &new SimpleBrowser();
+ return $browser;
+ }
+
+ /**
+ * Creates the XML parser.
+ * @param SimpleReporter $reporter Target of test results.
+ * @return SimpleTestXmlListener XML reader.
+ * @access protected
+ */
+ function &_createParser(&$reporter) {
+ $parser = &new SimpleTestXmlParser($reporter);
+ return $parser;
+ }
+
+ /**
+ * Accessor for the number of subtests.
+ * @return integer Number of test cases.
+ * @access public
+ */
+ function getSize() {
+ if ($this->_size === false) {
+ $browser = &$this->_createBrowser();
+ $xml = $browser->get($this->_dry_url);
+ if (! $xml) {
+ trigger_error('Cannot read remote test URL [' . $this->_dry_url . ']');
+ return false;
+ }
+ $reporter = &new SimpleReporter();
+ $parser = &$this->_createParser($reporter);
+ if (! $parser->parse($xml)) {
+ trigger_error('Cannot parse incoming XML from [' . $this->_dry_url . ']');
+ return false;
+ }
+ $this->_size = $reporter->getTestCaseCount();
+ }
+ return $this->_size;
+ }
+}
+?> \ No newline at end of file
diff --git a/site/vendors/simpletest/reporter.php b/site/vendors/simpletest/reporter.php
new file mode 100644
index 0000000..a13eff8
--- /dev/null
+++ b/site/vendors/simpletest/reporter.php
@@ -0,0 +1,447 @@
+<?php
+/**
+ * base include file for SimpleTest
+ * @package SimpleTest
+ * @subpackage UnitTester
+ * @version $Id: reporter.php 1702 2008-03-25 00:08:04Z lastcraft $
+ */
+
+/**#@+
+ * include other SimpleTest class files
+ */
+require_once(dirname(__FILE__) . '/scorer.php');
+/**#@-*/
+
+/**
+ * Sample minimal test displayer. Generates only
+ * failure messages and a pass count.
+ * @package SimpleTest
+ * @subpackage UnitTester
+ */
+class HtmlReporter extends SimpleReporter {
+ var $_character_set;
+
+ /**
+ * Does nothing yet. The first output will
+ * be sent on the first test start. For use
+ * by a web browser.
+ * @access public
+ */
+ function HtmlReporter($character_set = 'ISO-8859-1') {
+ $this->SimpleReporter();
+ $this->_character_set = $character_set;
+ }
+
+ /**
+ * Paints the top of the web page setting the
+ * title to the name of the starting test.
+ * @param string $test_name Name class of test.
+ * @access public
+ */
+ function paintHeader($test_name) {
+ $this->sendNoCacheHeaders();
+ print "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">";
+ print "<html>\n<head>\n<title>$test_name</title>\n";
+ print "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=" .
+ $this->_character_set . "\">\n";
+ print "<style type=\"text/css\">\n";
+ print $this->_getCss() . "\n";
+ print "</style>\n";
+ print "</head>\n<body>\n";
+ print "<h1>$test_name</h1>\n";
+ flush();
+ }
+
+ /**
+ * Send the headers necessary to ensure the page is
+ * reloaded on every request. Otherwise you could be
+ * scratching your head over out of date test data.
+ * @access public
+ * @static
+ */
+ function sendNoCacheHeaders() {
+ if (! headers_sent()) {
+ header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
+ header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
+ header("Cache-Control: no-store, no-cache, must-revalidate");
+ header("Cache-Control: post-check=0, pre-check=0", false);
+ header("Pragma: no-cache");
+ }
+ }
+
+ /**
+ * Paints the CSS. Add additional styles here.
+ * @return string CSS code as text.
+ * @access protected
+ */
+ function _getCss() {
+ return ".fail { background-color: inherit; color: red; }" .
+ ".pass { background-color: inherit; color: green; }" .
+ " pre { background-color: lightgray; color: inherit; }";
+ }
+
+ /**
+ * Paints the end of the test with a summary of
+ * the passes and failures.
+ * @param string $test_name Name class of test.
+ * @access public
+ */
+ function paintFooter($test_name) {
+ $colour = ($this->getFailCount() + $this->getExceptionCount() > 0 ? "red" : "green");
+ print "<div style=\"";
+ print "padding: 8px; margin-top: 1em; background-color: $colour; color: white;";
+ print "\">";
+ print $this->getTestCaseProgress() . "/" . $this->getTestCaseCount();
+ print " test cases complete:\n";
+ print "<strong>" . $this->getPassCount() . "</strong> passes, ";
+ print "<strong>" . $this->getFailCount() . "</strong> fails and ";
+ print "<strong>" . $this->getExceptionCount() . "</strong> exceptions.";
+ print "</div>\n";
+ print "</body>\n</html>\n";
+ }
+
+ /**
+ * Paints the test failure with a breadcrumbs
+ * trail of the nesting test suites below the
+ * top level test.
+ * @param string $message Failure message displayed in
+ * the context of the other tests.
+ * @access public
+ */
+ function paintFail($message) {
+ parent::paintFail($message);
+ print "<span class=\"fail\">Fail</span>: ";
+ $breadcrumb = $this->getTestList();
+ array_shift($breadcrumb);
+ print implode(" -&gt; ", $breadcrumb);
+ print " -&gt; " . $this->_htmlEntities($message) . "<br />\n";
+ }
+
+ /**
+ * Paints a PHP error.
+ * @param string $message Message is ignored.
+ * @access public
+ */
+ function paintError($message) {
+ parent::paintError($message);
+ print "<span class=\"fail\">Exception</span>: ";
+ $breadcrumb = $this->getTestList();
+ array_shift($breadcrumb);
+ print implode(" -&gt; ", $breadcrumb);
+ print " -&gt; <strong>" . $this->_htmlEntities($message) . "</strong><br />\n";
+ }
+
+ /**
+ * Paints a PHP exception.
+ * @param Exception $exception Exception to display.
+ * @access public
+ */
+ function paintException($exception) {
+ parent::paintException($exception);
+ print "<span class=\"fail\">Exception</span>: ";
+ $breadcrumb = $this->getTestList();
+ array_shift($breadcrumb);
+ print implode(" -&gt; ", $breadcrumb);
+ $message = 'Unexpected exception of type [' . get_class($exception) .
+ '] with message ['. $exception->getMessage() .
+ '] in ['. $exception->getFile() .
+ ' line ' . $exception->getLine() . ']';
+ print " -&gt; <strong>" . $this->_htmlEntities($message) . "</strong><br />\n";
+ }
+
+ /**
+ * Prints the message for skipping tests.
+ * @param string $message Text of skip condition.
+ * @access public
+ */
+ function paintSkip($message) {
+ parent::paintSkip($message);
+ print "<span class=\"pass\">Skipped</span>: ";
+ $breadcrumb = $this->getTestList();
+ array_shift($breadcrumb);
+ print implode(" -&gt; ", $breadcrumb);
+ print " -&gt; " . $this->_htmlEntities($message) . "<br />\n";
+ }
+
+ /**
+ * Paints formatted text such as dumped variables.
+ * @param string $message Text to show.
+ * @access public
+ */
+ function paintFormattedMessage($message) {
+ print '<pre>' . $this->_htmlEntities($message) . '</pre>';
+ }
+
+ /**
+ * Character set adjusted entity conversion.
+ * @param string $message Plain text or Unicode message.
+ * @return string Browser readable message.
+ * @access protected
+ */
+ function _htmlEntities($message) {
+ return htmlentities($message, ENT_COMPAT, $this->_character_set);
+ }
+}
+
+/**
+ * Sample minimal test displayer. Generates only
+ * failure messages and a pass count. For command
+ * line use. I've tried to make it look like JUnit,
+ * but I wanted to output the errors as they arrived
+ * which meant dropping the dots.
+ * @package SimpleTest
+ * @subpackage UnitTester
+ */
+class TextReporter extends SimpleReporter {
+
+ /**
+ * Does nothing yet. The first output will
+ * be sent on the first test start.
+ * @access public
+ */
+ function TextReporter() {
+ $this->SimpleReporter();
+ }
+
+ /**
+ * Paints the title only.
+ * @param string $test_name Name class of test.
+ * @access public
+ */
+ function paintHeader($test_name) {
+ if (! SimpleReporter::inCli()) {
+ header('Content-type: text/plain');
+ }
+ print "$test_name\n";
+ flush();
+ }
+
+ /**
+ * Paints the end of the test with a summary of
+ * the passes and failures.
+ * @param string $test_name Name class of test.
+ * @access public
+ */
+ function paintFooter($test_name) {
+ if ($this->getFailCount() + $this->getExceptionCount() == 0) {
+ print "OK\n";
+ } else {
+ print "FAILURES!!!\n";
+ }
+ print "Test cases run: " . $this->getTestCaseProgress() .
+ "/" . $this->getTestCaseCount() .
+ ", Passes: " . $this->getPassCount() .
+ ", Failures: " . $this->getFailCount() .
+ ", Exceptions: " . $this->getExceptionCount() . "\n";
+ }
+
+ /**
+ * Paints the test failure as a stack trace.
+ * @param string $message Failure message displayed in
+ * the context of the other tests.
+ * @access public
+ */
+ function paintFail($message) {
+ parent::paintFail($message);
+ print $this->getFailCount() . ") $message\n";
+ $breadcrumb = $this->getTestList();
+ array_shift($breadcrumb);
+ print "\tin " . implode("\n\tin ", array_reverse($breadcrumb));
+ print "\n";
+ }
+
+ /**
+ * Paints a PHP error or exception.
+ * @param string $message Message to be shown.
+ * @access public
+ * @abstract
+ */
+ function paintError($message) {
+ parent::paintError($message);
+ print "Exception " . $this->getExceptionCount() . "!\n$message\n";
+ $breadcrumb = $this->getTestList();
+ array_shift($breadcrumb);
+ print "\tin " . implode("\n\tin ", array_reverse($breadcrumb));
+ print "\n";
+ }
+
+ /**
+ * Paints a PHP error or exception.
+ * @param Exception $exception Exception to describe.
+ * @access public
+ * @abstract
+ */
+ function paintException($exception) {
+ parent::paintException($exception);
+ $message = 'Unexpected exception of type [' . get_class($exception) .
+ '] with message ['. $exception->getMessage() .
+ '] in ['. $exception->getFile() .
+ ' line ' . $exception->getLine() . ']';
+ print "Exception " . $this->getExceptionCount() . "!\n$message\n";
+ $breadcrumb = $this->getTestList();
+ array_shift($breadcrumb);
+ print "\tin " . implode("\n\tin ", array_reverse($breadcrumb));
+ print "\n";
+ }
+
+ /**
+ * Prints the message for skipping tests.
+ * @param string $message Text of skip condition.
+ * @access public
+ */
+ function paintSkip($message) {
+ parent::paintSkip($message);
+ print "Skip: $message\n";
+ }
+
+ /**
+ * Paints formatted text such as dumped variables.
+ * @param string $message Text to show.
+ * @access public
+ */
+ function paintFormattedMessage($message) {
+ print "$message\n";
+ flush();
+ }
+}
+
+/**
+ * Runs just a single test group, a single case or
+ * even a single test within that case.
+ * @package SimpleTest
+ * @subpackage UnitTester
+ */
+class SelectiveReporter extends SimpleReporterDecorator {
+ var $_just_this_case = false;
+ var $_just_this_test = false;
+ var $_on;
+
+ /**
+ * Selects the test case or group to be run,
+ * and optionally a specific test.
+ * @param SimpleScorer $reporter Reporter to receive events.
+ * @param string $just_this_case Only this case or group will run.
+ * @param string $just_this_test Only this test method will run.
+ */
+ function SelectiveReporter(&$reporter, $just_this_case = false, $just_this_test = false) {
+ if (isset($just_this_case) && $just_this_case) {
+ $this->_just_this_case = strtolower($just_this_case);
+ $this->_off();
+ } else {
+ $this->_on();
+ }
+ if (isset($just_this_test) && $just_this_test) {
+ $this->_just_this_test = strtolower($just_this_test);
+ }
+ $this->SimpleReporterDecorator($reporter);
+ }
+
+ /**
+ * Compares criteria to actual the case/group name.
+ * @param string $test_case The incoming test.
+ * @return boolean True if matched.
+ * @access protected
+ */
+ function _matchesTestCase($test_case) {
+ return $this->_just_this_case == strtolower($test_case);
+ }
+
+ /**
+ * Compares criteria to actual the test name. If no
+ * name was specified at the beginning, then all tests
+ * can run.
+ * @param string $method The incoming test method.
+ * @return boolean True if matched.
+ * @access protected
+ */
+ function _shouldRunTest($test_case, $method) {
+ if ($this->_isOn() || $this->_matchesTestCase($test_case)) {
+ if ($this->_just_this_test) {
+ return $this->_just_this_test == strtolower($method);
+ } else {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Switch on testing for the group or subgroup.
+ * @access private
+ */
+ function _on() {
+ $this->_on = true;
+ }
+
+ /**
+ * Switch off testing for the group or subgroup.
+ * @access private
+ */
+ function _off() {
+ $this->_on = false;
+ }
+
+ /**
+ * Is this group actually being tested?
+ * @return boolean True if the current test group is active.
+ * @access private
+ */
+ function _isOn() {
+ return $this->_on;
+ }
+
+ /**
+ * Veto everything that doesn't match the method wanted.
+ * @param string $test_case Name of test case.
+ * @param string $method Name of test method.
+ * @return boolean True if test should be run.
+ * @access public
+ */
+ function shouldInvoke($test_case, $method) {
+ if ($this->_shouldRunTest($test_case, $method)) {
+ return $this->_reporter->shouldInvoke($test_case, $method);
+ }
+ return false;
+ }
+
+ /**
+ * Paints the start of a group test.
+ * @param string $test_case Name of test or other label.
+ * @param integer $size Number of test cases starting.
+ * @access public
+ */
+ function paintGroupStart($test_case, $size) {
+ if ($this->_just_this_case && $this->_matchesTestCase($test_case)) {
+ $this->_on();
+ }
+ $this->_reporter->paintGroupStart($test_case, $size);
+ }
+
+ /**
+ * Paints the end of a group test.
+ * @param string $test_case Name of test or other label.
+ * @access public
+ */
+ function paintGroupEnd($test_case) {
+ $this->_reporter->paintGroupEnd($test_case);
+ if ($this->_just_this_case && $this->_matchesTestCase($test_case)) {
+ $this->_off();
+ }
+ }
+}
+
+/**
+ * Suppresses skip messages.
+ * @package SimpleTest
+ * @subpackage UnitTester
+ */
+class NoSkipsReporter extends SimpleReporterDecorator {
+
+ /**
+ * Does nothing.
+ * @param string $message Text of skip condition.
+ * @access public
+ */
+ function paintSkip($message) { }
+}
+?> \ No newline at end of file
diff --git a/site/vendors/simpletest/scorer.php b/site/vendors/simpletest/scorer.php
new file mode 100644
index 0000000..cc1331b
--- /dev/null
+++ b/site/vendors/simpletest/scorer.php
@@ -0,0 +1,863 @@
+<?php
+/**
+ * base include file for SimpleTest
+ * @package SimpleTest
+ * @subpackage UnitTester
+ * @version $Id: scorer.php 1723 2008-04-08 00:34:10Z lastcraft $
+ */
+
+/**#@+*/
+require_once(dirname(__FILE__) . '/invoker.php');
+/**#@-*/
+
+/**
+ * Can receive test events and display them. Display
+ * is achieved by making display methods available
+ * and visiting the incoming event.
+ * @package SimpleTest
+ * @subpackage UnitTester
+ * @abstract
+ */
+class SimpleScorer {
+ var $_passes;
+ var $_fails;
+ var $_exceptions;
+ var $_is_dry_run;
+
+ /**
+ * Starts the test run with no results.
+ * @access public
+ */
+ function SimpleScorer() {
+ $this->_passes = 0;
+ $this->_fails = 0;
+ $this->_exceptions = 0;
+ $this->_is_dry_run = false;
+ }
+
+ /**
+ * Signals that the next evaluation will be a dry
+ * run. That is, the structure events will be
+ * recorded, but no tests will be run.
+ * @param boolean $is_dry Dry run if true.
+ * @access public
+ */
+ function makeDry($is_dry = true) {
+ $this->_is_dry_run = $is_dry;
+ }
+
+ /**
+ * The reporter has a veto on what should be run.
+ * @param string $test_case_name name of test case.
+ * @param string $method Name of test method.
+ * @access public
+ */
+ function shouldInvoke($test_case_name, $method) {
+ return ! $this->_is_dry_run;
+ }
+
+ /**
+ * Can wrap the invoker in preperation for running
+ * a test.
+ * @param SimpleInvoker $invoker Individual test runner.
+ * @return SimpleInvoker Wrapped test runner.
+ * @access public
+ */
+ function &createInvoker(&$invoker) {
+ return $invoker;
+ }
+
+ /**
+ * Accessor for current status. Will be false
+ * if there have been any failures or exceptions.
+ * Used for command line tools.
+ * @return boolean True if no failures.
+ * @access public
+ */
+ function getStatus() {
+ if ($this->_exceptions + $this->_fails > 0) {
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Paints the start of a group test.
+ * @param string $test_name Name of test or other label.
+ * @param integer $size Number of test cases starting.
+ * @access public
+ */
+ function paintGroupStart($test_name, $size) {
+ }
+
+ /**
+ * Paints the end of a group test.
+ * @param string $test_name Name of test or other label.
+ * @access public
+ */
+ function paintGroupEnd($test_name) {
+ }
+
+ /**
+ * Paints the start of a test case.
+ * @param string $test_name Name of test or other label.
+ * @access public
+ */
+ function paintCaseStart($test_name) {
+ }
+
+ /**
+ * Paints the end of a test case.
+ * @param string $test_name Name of test or other label.
+ * @access public
+ */
+ function paintCaseEnd($test_name) {
+ }
+
+ /**
+ * Paints the start of a test method.
+ * @param string $test_name Name of test or other label.
+ * @access public
+ */
+ function paintMethodStart($test_name) {
+ }
+
+ /**
+ * Paints the end of a test method.
+ * @param string $test_name Name of test or other label.
+ * @access public
+ */
+ function paintMethodEnd($test_name) {
+ }
+
+ /**
+ * Increments the pass count.
+ * @param string $message Message is ignored.
+ * @access public
+ */
+ function paintPass($message) {
+ $this->_passes++;
+ }
+
+ /**
+ * Increments the fail count.
+ * @param string $message Message is ignored.
+ * @access public
+ */
+ function paintFail($message) {
+ $this->_fails++;
+ }
+
+ /**
+ * Deals with PHP 4 throwing an error.
+ * @param string $message Text of error formatted by
+ * the test case.
+ * @access public
+ */
+ function paintError($message) {
+ $this->_exceptions++;
+ }
+
+ /**
+ * Deals with PHP 5 throwing an exception.
+ * @param Exception $exception The actual exception thrown.
+ * @access public
+ */
+ function paintException($exception) {
+ $this->_exceptions++;
+ }
+
+ /**
+ * Prints the message for skipping tests.
+ * @param string $message Text of skip condition.
+ * @access public
+ */
+ function paintSkip($message) {
+ }
+
+ /**
+ * Accessor for the number of passes so far.
+ * @return integer Number of passes.
+ * @access public
+ */
+ function getPassCount() {
+ return $this->_passes;
+ }
+
+ /**
+ * Accessor for the number of fails so far.
+ * @return integer Number of fails.
+ * @access public
+ */
+ function getFailCount() {
+ return $this->_fails;
+ }
+
+ /**
+ * Accessor for the number of untrapped errors
+ * so far.
+ * @return integer Number of exceptions.
+ * @access public
+ */
+ function getExceptionCount() {
+ return $this->_exceptions;
+ }
+
+ /**
+ * Paints a simple supplementary message.
+ * @param string $message Text to display.
+ * @access public
+ */
+ function paintMessage($message) {
+ }
+
+ /**
+ * Paints a formatted ASCII message such as a
+ * variable dump.
+ * @param string $message Text to display.
+ * @access public
+ */
+ function paintFormattedMessage($message) {
+ }
+
+ /**
+ * By default just ignores user generated events.
+ * @param string $type Event type as text.
+ * @param mixed $payload Message or object.
+ * @access public
+ */
+ function paintSignal($type, $payload) {
+ }
+}
+
+/**
+ * Recipient of generated test messages that can display
+ * page footers and headers. Also keeps track of the
+ * test nesting. This is the main base class on which
+ * to build the finished test (page based) displays.
+ * @package SimpleTest
+ * @subpackage UnitTester
+ */
+class SimpleReporter extends SimpleScorer {
+ var $_test_stack;
+ var $_size;
+ var $_progress;
+
+ /**
+ * Starts the display with no results in.
+ * @access public
+ */
+ function SimpleReporter() {
+ $this->SimpleScorer();
+ $this->_test_stack = array();
+ $this->_size = null;
+ $this->_progress = 0;
+ }
+
+ /**
+ * Gets the formatter for variables and other small
+ * generic data items.
+ * @return SimpleDumper Formatter.
+ * @access public
+ */
+ function getDumper() {
+ return new SimpleDumper();
+ }
+
+ /**
+ * Paints the start of a group test. Will also paint
+ * the page header and footer if this is the
+ * first test. Will stash the size if the first
+ * start.
+ * @param string $test_name Name of test that is starting.
+ * @param integer $size Number of test cases starting.
+ * @access public
+ */
+ function paintGroupStart($test_name, $size) {
+ if (! isset($this->_size)) {
+ $this->_size = $size;
+ }
+ if (count($this->_test_stack) == 0) {
+ $this->paintHeader($test_name);
+ }
+ $this->_test_stack[] = $test_name;
+ }
+
+ /**
+ * Paints the end of a group test. Will paint the page
+ * footer if the stack of tests has unwound.
+ * @param string $test_name Name of test that is ending.
+ * @param integer $progress Number of test cases ending.
+ * @access public
+ */
+ function paintGroupEnd($test_name) {
+ array_pop($this->_test_stack);
+ if (count($this->_test_stack) == 0) {
+ $this->paintFooter($test_name);
+ }
+ }
+
+ /**
+ * Paints the start of a test case. Will also paint
+ * the page header and footer if this is the
+ * first test. Will stash the size if the first
+ * start.
+ * @param string $test_name Name of test that is starting.
+ * @access public
+ */
+ function paintCaseStart($test_name) {
+ if (! isset($this->_size)) {
+ $this->_size = 1;
+ }
+ if (count($this->_test_stack) == 0) {
+ $this->paintHeader($test_name);
+ }
+ $this->_test_stack[] = $test_name;
+ }
+
+ /**
+ * Paints the end of a test case. Will paint the page
+ * footer if the stack of tests has unwound.
+ * @param string $test_name Name of test that is ending.
+ * @access public
+ */
+ function paintCaseEnd($test_name) {
+ $this->_progress++;
+ array_pop($this->_test_stack);
+ if (count($this->_test_stack) == 0) {
+ $this->paintFooter($test_name);
+ }
+ }
+
+ /**
+ * Paints the start of a test method.
+ * @param string $test_name Name of test that is starting.
+ * @access public
+ */
+ function paintMethodStart($test_name) {
+ $this->_test_stack[] = $test_name;
+ }
+
+ /**
+ * Paints the end of a test method. Will paint the page
+ * footer if the stack of tests has unwound.
+ * @param string $test_name Name of test that is ending.
+ * @access public
+ */
+ function paintMethodEnd($test_name) {
+ array_pop($this->_test_stack);
+ }
+
+ /**
+ * Paints the test document header.
+ * @param string $test_name First test top level
+ * to start.
+ * @access public
+ * @abstract
+ */
+ function paintHeader($test_name) {
+ }
+
+ /**
+ * Paints the test document footer.
+ * @param string $test_name The top level test.
+ * @access public
+ * @abstract
+ */
+ function paintFooter($test_name) {
+ }
+
+ /**
+ * Accessor for internal test stack. For
+ * subclasses that need to see the whole test
+ * history for display purposes.
+ * @return array List of methods in nesting order.
+ * @access public
+ */
+ function getTestList() {
+ return $this->_test_stack;
+ }
+
+ /**
+ * Accessor for total test size in number
+ * of test cases. Null until the first
+ * test is started.
+ * @return integer Total number of cases at start.
+ * @access public
+ */
+ function getTestCaseCount() {
+ return $this->_size;
+ }
+
+ /**
+ * Accessor for the number of test cases
+ * completed so far.
+ * @return integer Number of ended cases.
+ * @access public
+ */
+ function getTestCaseProgress() {
+ return $this->_progress;
+ }
+
+ /**
+ * Static check for running in the comand line.
+ * @return boolean True if CLI.
+ * @access public
+ * @static
+ */
+ function inCli() {
+ return php_sapi_name() == 'cli';
+ }
+}
+
+/**
+ * For modifying the behaviour of the visual reporters.
+ * @package SimpleTest
+ * @subpackage UnitTester
+ */
+class SimpleReporterDecorator {
+ var $_reporter;
+
+ /**
+ * Mediates between the reporter and the test case.
+ * @param SimpleScorer $reporter Reporter to receive events.
+ */
+ function SimpleReporterDecorator(&$reporter) {
+ $this->_reporter = &$reporter;
+ }
+
+ /**
+ * Signals that the next evaluation will be a dry
+ * run. That is, the structure events will be
+ * recorded, but no tests will be run.
+ * @param boolean $is_dry Dry run if true.
+ * @access public
+ */
+ function makeDry($is_dry = true) {
+ $this->_reporter->makeDry($is_dry);
+ }
+
+ /**
+ * Accessor for current status. Will be false
+ * if there have been any failures or exceptions.
+ * Used for command line tools.
+ * @return boolean True if no failures.
+ * @access public
+ */
+ function getStatus() {
+ return $this->_reporter->getStatus();
+ }
+
+ /**
+ * The reporter has a veto on what should be run.
+ * @param string $test_case_name name of test case.
+ * @param string $method Name of test method.
+ * @return boolean True if test should be run.
+ * @access public
+ */
+ function shouldInvoke($test_case_name, $method) {
+ return $this->_reporter->shouldInvoke($test_case_name, $method);
+ }
+
+ /**
+ * Can wrap the invoker in preperation for running
+ * a test.
+ * @param SimpleInvoker $invoker Individual test runner.
+ * @return SimpleInvoker Wrapped test runner.
+ * @access public
+ */
+ function &createInvoker(&$invoker) {
+ return $this->_reporter->createInvoker($invoker);
+ }
+
+ /**
+ * Gets the formatter for variables and other small
+ * generic data items.
+ * @return SimpleDumper Formatter.
+ * @access public
+ */
+ function getDumper() {
+ return $this->_reporter->getDumper();
+ }
+
+ /**
+ * Paints the start of a group test.
+ * @param string $test_name Name of test or other label.
+ * @param integer $size Number of test cases starting.
+ * @access public
+ */
+ function paintGroupStart($test_name, $size) {
+ $this->_reporter->paintGroupStart($test_name, $size);
+ }
+
+ /**
+ * Paints the end of a group test.
+ * @param string $test_name Name of test or other label.
+ * @access public
+ */
+ function paintGroupEnd($test_name) {
+ $this->_reporter->paintGroupEnd($test_name);
+ }
+
+ /**
+ * Paints the start of a test case.
+ * @param string $test_name Name of test or other label.
+ * @access public
+ */
+ function paintCaseStart($test_name) {
+ $this->_reporter->paintCaseStart($test_name);
+ }
+
+ /**
+ * Paints the end of a test case.
+ * @param string $test_name Name of test or other label.
+ * @access public
+ */
+ function paintCaseEnd($test_name) {
+ $this->_reporter->paintCaseEnd($test_name);
+ }
+
+ /**
+ * Paints the start of a test method.
+ * @param string $test_name Name of test or other label.
+ * @access public
+ */
+ function paintMethodStart($test_name) {
+ $this->_reporter->paintMethodStart($test_name);
+ }
+
+ /**
+ * Paints the end of a test method.
+ * @param string $test_name Name of test or other label.
+ * @access public
+ */
+ function paintMethodEnd($test_name) {
+ $this->_reporter->paintMethodEnd($test_name);
+ }
+
+ /**
+ * Chains to the wrapped reporter.
+ * @param string $message Message is ignored.
+ * @access public
+ */
+ function paintPass($message) {
+ $this->_reporter->paintPass($message);
+ }
+
+ /**
+ * Chains to the wrapped reporter.
+ * @param string $message Message is ignored.
+ * @access public
+ */
+ function paintFail($message) {
+ $this->_reporter->paintFail($message);
+ }
+
+ /**
+ * Chains to the wrapped reporter.
+ * @param string $message Text of error formatted by
+ * the test case.
+ * @access public
+ */
+ function paintError($message) {
+ $this->_reporter->paintError($message);
+ }
+
+ /**
+ * Chains to the wrapped reporter.
+ * @param Exception $exception Exception to show.
+ * @access public
+ */
+ function paintException($exception) {
+ $this->_reporter->paintException($exception);
+ }
+
+ /**
+ * Prints the message for skipping tests.
+ * @param string $message Text of skip condition.
+ * @access public
+ */
+ function paintSkip($message) {
+ $this->_reporter->paintSkip($message);
+ }
+
+ /**
+ * Chains to the wrapped reporter.
+ * @param string $message Text to display.
+ * @access public
+ */
+ function paintMessage($message) {
+ $this->_reporter->paintMessage($message);
+ }
+
+ /**
+ * Chains to the wrapped reporter.
+ * @param string $message Text to display.
+ * @access public
+ */
+ function paintFormattedMessage($message) {
+ $this->_reporter->paintFormattedMessage($message);
+ }
+
+ /**
+ * Chains to the wrapped reporter.
+ * @param string $type Event type as text.
+ * @param mixed $payload Message or object.
+ * @return boolean Should return false if this
+ * type of signal should fail the
+ * test suite.
+ * @access public
+ */
+ function paintSignal($type, &$payload) {
+ $this->_reporter->paintSignal($type, $payload);
+ }
+}
+
+/**
+ * For sending messages to multiple reporters at
+ * the same time.
+ * @package SimpleTest
+ * @subpackage UnitTester
+ */
+class MultipleReporter {
+ var $_reporters = array();
+
+ /**
+ * Adds a reporter to the subscriber list.
+ * @param SimpleScorer $reporter Reporter to receive events.
+ * @access public
+ */
+ function attachReporter(&$reporter) {
+ $this->_reporters[] = &$reporter;
+ }
+
+ /**
+ * Signals that the next evaluation will be a dry
+ * run. That is, the structure events will be
+ * recorded, but no tests will be run.
+ * @param boolean $is_dry Dry run if true.
+ * @access public
+ */
+ function makeDry($is_dry = true) {
+ for ($i = 0; $i < count($this->_reporters); $i++) {
+ $this->_reporters[$i]->makeDry($is_dry);
+ }
+ }
+
+ /**
+ * Accessor for current status. Will be false
+ * if there have been any failures or exceptions.
+ * If any reporter reports a failure, the whole
+ * suite fails.
+ * @return boolean True if no failures.
+ * @access public
+ */
+ function getStatus() {
+ for ($i = 0; $i < count($this->_reporters); $i++) {
+ if (! $this->_reporters[$i]->getStatus()) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * The reporter has a veto on what should be run.
+ * It requires all reporters to want to run the method.
+ * @param string $test_case_name name of test case.
+ * @param string $method Name of test method.
+ * @access public
+ */
+ function shouldInvoke($test_case_name, $method) {
+ for ($i = 0; $i < count($this->_reporters); $i++) {
+ if (! $this->_reporters[$i]->shouldInvoke($test_case_name, $method)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Every reporter gets a chance to wrap the invoker.
+ * @param SimpleInvoker $invoker Individual test runner.
+ * @return SimpleInvoker Wrapped test runner.
+ * @access public
+ */
+ function &createInvoker(&$invoker) {
+ for ($i = 0; $i < count($this->_reporters); $i++) {
+ $invoker = &$this->_reporters[$i]->createInvoker($invoker);
+ }
+ return $invoker;
+ }
+
+ /**
+ * Gets the formatter for variables and other small
+ * generic data items.
+ * @return SimpleDumper Formatter.
+ * @access public
+ */
+ function getDumper() {
+ return new SimpleDumper();
+ }
+
+ /**
+ * Paints the start of a group test.
+ * @param string $test_name Name of test or other label.
+ * @param integer $size Number of test cases starting.
+ * @access public
+ */
+ function paintGroupStart($test_name, $size) {
+ for ($i = 0; $i < count($this->_reporters); $i++) {
+ $this->_reporters[$i]->paintGroupStart($test_name, $size);
+ }
+ }
+
+ /**
+ * Paints the end of a group test.
+ * @param string $test_name Name of test or other label.
+ * @access public
+ */
+ function paintGroupEnd($test_name) {
+ for ($i = 0; $i < count($this->_reporters); $i++) {
+ $this->_reporters[$i]->paintGroupEnd($test_name);
+ }
+ }
+
+ /**
+ * Paints the start of a test case.
+ * @param string $test_name Name of test or other label.
+ * @access public
+ */
+ function paintCaseStart($test_name) {
+ for ($i = 0; $i < count($this->_reporters); $i++) {
+ $this->_reporters[$i]->paintCaseStart($test_name);
+ }
+ }
+
+ /**
+ * Paints the end of a test case.
+ * @param string $test_name Name of test or other label.
+ * @access public
+ */
+ function paintCaseEnd($test_name) {
+ for ($i = 0; $i < count($this->_reporters); $i++) {
+ $this->_reporters[$i]->paintCaseEnd($test_name);
+ }
+ }
+
+ /**
+ * Paints the start of a test method.
+ * @param string $test_name Name of test or other label.
+ * @access public
+ */
+ function paintMethodStart($test_name) {
+ for ($i = 0; $i < count($this->_reporters); $i++) {
+ $this->_reporters[$i]->paintMethodStart($test_name);
+ }
+ }
+
+ /**
+ * Paints the end of a test method.
+ * @param string $test_name Name of test or other label.
+ * @access public
+ */
+ function paintMethodEnd($test_name) {
+ for ($i = 0; $i < count($this->_reporters); $i++) {
+ $this->_reporters[$i]->paintMethodEnd($test_name);
+ }
+ }
+
+ /**
+ * Chains to the wrapped reporter.
+ * @param string $message Message is ignored.
+ * @access public
+ */
+ function paintPass($message) {
+ for ($i = 0; $i < count($this->_reporters); $i++) {
+ $this->_reporters[$i]->paintPass($message);
+ }
+ }
+
+ /**
+ * Chains to the wrapped reporter.
+ * @param string $message Message is ignored.
+ * @access public
+ */
+ function paintFail($message) {
+ for ($i = 0; $i < count($this->_reporters); $i++) {
+ $this->_reporters[$i]->paintFail($message);
+ }
+ }
+
+ /**
+ * Chains to the wrapped reporter.
+ * @param string $message Text of error formatted by
+ * the test case.
+ * @access public
+ */
+ function paintError($message) {
+ for ($i = 0; $i < count($this->_reporters); $i++) {
+ $this->_reporters[$i]->paintError($message);
+ }
+ }
+
+ /**
+ * Chains to the wrapped reporter.
+ * @param Exception $exception Exception to display.
+ * @access public
+ */
+ function paintException($exception) {
+ for ($i = 0; $i < count($this->_reporters); $i++) {
+ $this->_reporters[$i]->paintException($exception);
+ }
+ }
+
+ /**
+ * Prints the message for skipping tests.
+ * @param string $message Text of skip condition.
+ * @access public
+ */
+ function paintSkip($message) {
+ for ($i = 0; $i < count($this->_reporters); $i++) {
+ $this->_reporters[$i]->paintSkip($message);
+ }
+ }
+
+ /**
+ * Chains to the wrapped reporter.
+ * @param string $message Text to display.
+ * @access public
+ */
+ function paintMessage($message) {
+ for ($i = 0; $i < count($this->_reporters); $i++) {
+ $this->_reporters[$i]->paintMessage($message);
+ }
+ }
+
+ /**
+ * Chains to the wrapped reporter.
+ * @param string $message Text to display.
+ * @access public
+ */
+ function paintFormattedMessage($message) {
+ for ($i = 0; $i < count($this->_reporters); $i++) {
+ $this->_reporters[$i]->paintFormattedMessage($message);
+ }
+ }
+
+ /**
+ * Chains to the wrapped reporter.
+ * @param string $type Event type as text.
+ * @param mixed $payload Message or object.
+ * @return boolean Should return false if this
+ * type of signal should fail the
+ * test suite.
+ * @access public
+ */
+ function paintSignal($type, &$payload) {
+ for ($i = 0; $i < count($this->_reporters); $i++) {
+ $this->_reporters[$i]->paintSignal($type, $payload);
+ }
+ }
+}
+?> \ No newline at end of file
diff --git a/site/vendors/simpletest/selector.php b/site/vendors/simpletest/selector.php
new file mode 100644
index 0000000..de044b8
--- /dev/null
+++ b/site/vendors/simpletest/selector.php
@@ -0,0 +1,137 @@
+<?php
+/**
+ * Base include file for SimpleTest.
+ * @package SimpleTest
+ * @subpackage WebTester
+ * @version $Id: selector.php 1723 2008-04-08 00:34:10Z lastcraft $
+ */
+
+/**#@+
+ * include SimpleTest files
+ */
+require_once(dirname(__FILE__) . '/tag.php');
+require_once(dirname(__FILE__) . '/encoding.php');
+/**#@-*/
+
+/**
+ * Used to extract form elements for testing against.
+ * Searches by name attribute.
+ * @package SimpleTest
+ * @subpackage WebTester
+ */
+class SimpleByName {
+ var $_name;
+
+ /**
+ * Stashes the name for later comparison.
+ * @param string $name Name attribute to match.
+ */
+ function SimpleByName($name) {
+ $this->_name = $name;
+ }
+
+ function getName() {
+ return $this->_name;
+ }
+
+ /**
+ * Compares with name attribute of widget.
+ * @param SimpleWidget $widget Control to compare.
+ * @access public
+ */
+ function isMatch($widget) {
+ return ($widget->getName() == $this->_name);
+ }
+}
+
+/**
+ * Used to extract form elements for testing against.
+ * Searches by visible label or alt text.
+ * @package SimpleTest
+ * @subpackage WebTester
+ */
+class SimpleByLabel {
+ var $_label;
+
+ /**
+ * Stashes the name for later comparison.
+ * @param string $label Visible text to match.
+ */
+ function SimpleByLabel($label) {
+ $this->_label = $label;
+ }
+
+ /**
+ * Comparison. Compares visible text of widget or
+ * related label.
+ * @param SimpleWidget $widget Control to compare.
+ * @access public
+ */
+ function isMatch($widget) {
+ if (! method_exists($widget, 'isLabel')) {
+ return false;
+ }
+ return $widget->isLabel($this->_label);
+ }
+}
+
+/**
+ * Used to extract form elements for testing against.
+ * Searches dy id attribute.
+ * @package SimpleTest
+ * @subpackage WebTester
+ */
+class SimpleById {
+ var $_id;
+
+ /**
+ * Stashes the name for later comparison.
+ * @param string $id ID atribute to match.
+ */
+ function SimpleById($id) {
+ $this->_id = $id;
+ }
+
+ /**
+ * Comparison. Compares id attribute of widget.
+ * @param SimpleWidget $widget Control to compare.
+ * @access public
+ */
+ function isMatch($widget) {
+ return $widget->isId($this->_id);
+ }
+}
+
+/**
+ * Used to extract form elements for testing against.
+ * Searches by visible label, name or alt text.
+ * @package SimpleTest
+ * @subpackage WebTester
+ */
+class SimpleByLabelOrName {
+ var $_label;
+
+ /**
+ * Stashes the name/label for later comparison.
+ * @param string $label Visible text to match.
+ */
+ function SimpleByLabelOrName($label) {
+ $this->_label = $label;
+ }
+
+ /**
+ * Comparison. Compares visible text of widget or
+ * related label or name.
+ * @param SimpleWidget $widget Control to compare.
+ * @access public
+ */
+ function isMatch($widget) {
+ if (method_exists($widget, 'isLabel')) {
+ if ($widget->isLabel($this->_label)) {
+ return true;
+ }
+ }
+ return ($widget->getName() == $this->_label);
+ }
+}
+?> \ No newline at end of file
diff --git a/site/vendors/simpletest/shell_tester.php b/site/vendors/simpletest/shell_tester.php
new file mode 100644
index 0000000..7b98869
--- /dev/null
+++ b/site/vendors/simpletest/shell_tester.php
@@ -0,0 +1,333 @@
+<?php
+/**
+ * base include file for SimpleTest
+ * @package SimpleTest
+ * @subpackage UnitTester
+ * @version $Id: shell_tester.php 1723 2008-04-08 00:34:10Z lastcraft $
+ */
+
+/**#@+
+ * include other SimpleTest class files
+ */
+require_once(dirname(__FILE__) . '/test_case.php');
+/**#@-*/
+
+/**
+ * Wrapper for exec() functionality.
+ * @package SimpleTest
+ * @subpackage UnitTester
+ */
+class SimpleShell {
+ var $_output;
+
+ /**
+ * Executes the shell comand and stashes the output.
+ * @access public
+ */
+ function SimpleShell() {
+ $this->_output = false;
+ }
+
+ /**
+ * Actually runs the command. Does not trap the
+ * error stream output as this need PHP 4.3+.
+ * @param string $command The actual command line
+ * to run.
+ * @return integer Exit code.
+ * @access public
+ */
+ function execute($command) {
+ $this->_output = false;
+ exec($command, $this->_output, $ret);
+ return $ret;
+ }
+
+ /**
+ * Accessor for the last output.
+ * @return string Output as text.
+ * @access public
+ */
+ function getOutput() {
+ return implode("\n", $this->_output);
+ }
+
+ /**
+ * Accessor for the last output.
+ * @return array Output as array of lines.
+ * @access public
+ */
+ function getOutputAsList() {
+ return $this->_output;
+ }
+}
+
+/**
+ * Test case for testing of command line scripts and
+ * utilities. Usually scripts that are external to the
+ * PHP code, but support it in some way.
+ * @package SimpleTest
+ * @subpackage UnitTester
+ */
+class ShellTestCase extends SimpleTestCase {
+ var $_current_shell;
+ var $_last_status;
+ var $_last_command;
+
+ /**
+ * Creates an empty test case. Should be subclassed
+ * with test methods for a functional test case.
+ * @param string $label Name of test case. Will use
+ * the class name if none specified.
+ * @access public
+ */
+ function ShellTestCase($label = false) {
+ $this->SimpleTestCase($label);
+ $this->_current_shell = &$this->_createShell();
+ $this->_last_status = false;
+ $this->_last_command = '';
+ }
+
+ /**
+ * Executes a command and buffers the results.
+ * @param string $command Command to run.
+ * @return boolean True if zero exit code.
+ * @access public
+ */
+ function execute($command) {
+ $shell = &$this->_getShell();
+ $this->_last_status = $shell->execute($command);
+ $this->_last_command = $command;
+ return ($this->_last_status === 0);
+ }
+
+ /**
+ * Dumps the output of the last command.
+ * @access public
+ */
+ function dumpOutput() {
+ $this->dump($this->getOutput());
+ }
+
+ /**
+ * Accessor for the last output.
+ * @return string Output as text.
+ * @access public
+ */
+ function getOutput() {
+ $shell = &$this->_getShell();
+ return $shell->getOutput();
+ }
+
+ /**
+ * Accessor for the last output.
+ * @return array Output as array of lines.
+ * @access public
+ */
+ function getOutputAsList() {
+ $shell = &$this->_getShell();
+ return $shell->getOutputAsList();
+ }
+
+ /**
+ * Called from within the test methods to register
+ * passes and failures.
+ * @param boolean $result Pass on true.
+ * @param string $message Message to display describing
+ * the test state.
+ * @return boolean True on pass
+ * @access public
+ */
+ function assertTrue($result, $message = false) {
+ return $this->assert(new TrueExpectation(), $result, $message);
+ }
+
+ /**
+ * Will be true on false and vice versa. False
+ * is the PHP definition of false, so that null,
+ * empty strings, zero and an empty array all count
+ * as false.
+ * @param boolean $result Pass on false.
+ * @param string $message Message to display.
+ * @return boolean True on pass
+ * @access public
+ */
+ function assertFalse($result, $message = '%s') {
+ return $this->assert(new FalseExpectation(), $result, $message);
+ }
+
+ /**
+ * Will trigger a pass if the two parameters have
+ * the same value only. Otherwise a fail. This
+ * is for testing hand extracted text, etc.
+ * @param mixed $first Value to compare.
+ * @param mixed $second Value to compare.
+ * @param string $message Message to display.
+ * @return boolean True on pass
+ * @access public
+ */
+ function assertEqual($first, $second, $message = "%s") {
+ return $this->assert(
+ new EqualExpectation($first),
+ $second,
+ $message);
+ }
+
+ /**
+ * Will trigger a pass if the two parameters have
+ * a different value. Otherwise a fail. This
+ * is for testing hand extracted text, etc.
+ * @param mixed $first Value to compare.
+ * @param mixed $second Value to compare.
+ * @param string $message Message to display.
+ * @return boolean True on pass
+ * @access public
+ */
+ function assertNotEqual($first, $second, $message = "%s") {
+ return $this->assert(
+ new NotEqualExpectation($first),
+ $second,
+ $message);
+ }
+
+ /**
+ * Tests the last status code from the shell.
+ * @param integer $status Expected status of last
+ * command.
+ * @param string $message Message to display.
+ * @return boolean True if pass.
+ * @access public
+ */
+ function assertExitCode($status, $message = "%s") {
+ $message = sprintf($message, "Expected status code of [$status] from [" .
+ $this->_last_command . "], but got [" .
+ $this->_last_status . "]");
+ return $this->assertTrue($status === $this->_last_status, $message);
+ }
+
+ /**
+ * Attempt to exactly match the combined STDERR and
+ * STDOUT output.
+ * @param string $expected Expected output.
+ * @param string $message Message to display.
+ * @return boolean True if pass.
+ * @access public
+ */
+ function assertOutput($expected, $message = "%s") {
+ $shell = &$this->_getShell();
+ return $this->assert(
+ new EqualExpectation($expected),
+ $shell->getOutput(),
+ $message);
+ }
+
+ /**
+ * Scans the output for a Perl regex. If found
+ * anywhere it passes, else it fails.
+ * @param string $pattern Regex to search for.
+ * @param string $message Message to display.
+ * @return boolean True if pass.
+ * @access public
+ */
+ function assertOutputPattern($pattern, $message = "%s") {
+ $shell = &$this->_getShell();
+ return $this->assert(
+ new PatternExpectation($pattern),
+ $shell->getOutput(),
+ $message);
+ }
+
+ /**
+ * If a Perl regex is found anywhere in the current
+ * output then a failure is generated, else a pass.
+ * @param string $pattern Regex to search for.
+ * @param $message Message to display.
+ * @return boolean True if pass.
+ * @access public
+ */
+ function assertNoOutputPattern($pattern, $message = "%s") {
+ $shell = &$this->_getShell();
+ return $this->assert(
+ new NoPatternExpectation($pattern),
+ $shell->getOutput(),
+ $message);
+ }
+
+ /**
+ * File existence check.
+ * @param string $path Full filename and path.
+ * @param string $message Message to display.
+ * @return boolean True if pass.
+ * @access public
+ */
+ function assertFileExists($path, $message = "%s") {
+ $message = sprintf($message, "File [$path] should exist");
+ return $this->assertTrue(file_exists($path), $message);
+ }
+
+ /**
+ * File non-existence check.
+ * @param string $path Full filename and path.
+ * @param string $message Message to display.
+ * @return boolean True if pass.
+ * @access public
+ */
+ function assertFileNotExists($path, $message = "%s") {
+ $message = sprintf($message, "File [$path] should not exist");
+ return $this->assertFalse(file_exists($path), $message);
+ }
+
+ /**
+ * Scans a file for a Perl regex. If found
+ * anywhere it passes, else it fails.
+ * @param string $pattern Regex to search for.
+ * @param string $path Full filename and path.
+ * @param string $message Message to display.
+ * @return boolean True if pass.
+ * @access public
+ */
+ function assertFilePattern($pattern, $path, $message = "%s") {
+ $shell = &$this->_getShell();
+ return $this->assert(
+ new PatternExpectation($pattern),
+ implode('', file($path)),
+ $message);
+ }
+
+ /**
+ * If a Perl regex is found anywhere in the named
+ * file then a failure is generated, else a pass.
+ * @param string $pattern Regex to search for.
+ * @param string $path Full filename and path.
+ * @param string $message Message to display.
+ * @return boolean True if pass.
+ * @access public
+ */
+ function assertNoFilePattern($pattern, $path, $message = "%s") {
+ $shell = &$this->_getShell();
+ return $this->assert(
+ new NoPatternExpectation($pattern),
+ implode('', file($path)),
+ $message);
+ }
+
+ /**
+ * Accessor for current shell. Used for testing the
+ * the tester itself.
+ * @return Shell Current shell.
+ * @access protected
+ */
+ function &_getShell() {
+ return $this->_current_shell;
+ }
+
+ /**
+ * Factory for the shell to run the command on.
+ * @return Shell New shell object.
+ * @access protected
+ */
+ function &_createShell() {
+ $shell = &new SimpleShell();
+ return $shell;
+ }
+}
+?>
diff --git a/site/vendors/simpletest/simpletest.php b/site/vendors/simpletest/simpletest.php
new file mode 100644
index 0000000..bab2c1a
--- /dev/null
+++ b/site/vendors/simpletest/simpletest.php
@@ -0,0 +1,478 @@
+<?php
+/**
+ * Global state for SimpleTest and kicker script in future versions.
+ * @package SimpleTest
+ * @subpackage UnitTester
+ * @version $Id: simpletest.php 1723 2008-04-08 00:34:10Z lastcraft $
+ */
+
+/**#@+
+ * include SimpleTest files
+ */
+if (version_compare(phpversion(), '5') >= 0) {
+ require_once(dirname(__FILE__) . '/reflection_php5.php');
+} else {
+ require_once(dirname(__FILE__) . '/reflection_php4.php');
+}
+require_once(dirname(__FILE__) . '/default_reporter.php');
+require_once(dirname(__FILE__) . '/compatibility.php');
+/**#@-*/
+
+/**
+ * Registry and test context. Includes a few
+ * global options that I'm slowly getting rid of.
+ * @package SimpleTest
+ * @subpackage UnitTester
+ */
+class SimpleTest {
+
+ /**
+ * Reads the SimpleTest version from the release file.
+ * @return string Version string.
+ * @static
+ * @access public
+ */
+ function getVersion() {
+ $content = file(dirname(__FILE__) . '/VERSION');
+ return trim($content[0]);
+ }
+
+ /**
+ * Sets the name of a test case to ignore, usually
+ * because the class is an abstract case that should
+ * not be run. Once PHP4 is dropped this will disappear
+ * as a public method and "abstract" will rule.
+ * @param string $class Add a class to ignore.
+ * @static
+ * @access public
+ */
+ function ignore($class) {
+ $registry = &SimpleTest::_getRegistry();
+ $registry['IgnoreList'][strtolower($class)] = true;
+ }
+
+ /**
+ * Scans the now complete ignore list, and adds
+ * all parent classes to the list. If a class
+ * is not a runnable test case, then it's parents
+ * wouldn't be either. This is syntactic sugar
+ * to cut down on ommissions of ignore()'s or
+ * missing abstract declarations. This cannot
+ * be done whilst loading classes wiithout forcing
+ * a particular order on the class declarations and
+ * the ignore() calls. It's just nice to have the ignore()
+ * calls at the top of the file before the actual declarations.
+ * @param array $classes Class names of interest.
+ * @static
+ * @access public
+ */
+ function ignoreParentsIfIgnored($classes) {
+ $registry = &SimpleTest::_getRegistry();
+ foreach ($classes as $class) {
+ if (SimpleTest::isIgnored($class)) {
+ $reflection = new SimpleReflection($class);
+ if ($parent = $reflection->getParent()) {
+ SimpleTest::ignore($parent);
+ }
+ }
+ }
+ }
+
+ /**
+ * Puts the object to the global pool of 'preferred' objects
+ * which can be retrieved with SimpleTest :: preferred() method.
+ * Instances of the same class are overwritten.
+ * @param object $object Preferred object
+ * @static
+ * @access public
+ * @see preferred()
+ */
+ function prefer(&$object) {
+ $registry = &SimpleTest::_getRegistry();
+ $registry['Preferred'][] = &$object;
+ }
+
+ /**
+ * Retrieves 'preferred' objects from global pool. Class filter
+ * can be applied in order to retrieve the object of the specific
+ * class
+ * @param array|string $classes Allowed classes or interfaces.
+ * @static
+ * @access public
+ * @return array|object|null
+ * @see prefer()
+ */
+ function &preferred($classes) {
+ if (! is_array($classes)) {
+ $classes = array($classes);
+ }
+ $registry = &SimpleTest::_getRegistry();
+ for ($i = count($registry['Preferred']) - 1; $i >= 0; $i--) {
+ foreach ($classes as $class) {
+ if (SimpleTestCompatibility::isA($registry['Preferred'][$i], $class)) {
+ return $registry['Preferred'][$i];
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Test to see if a test case is in the ignore
+ * list. Quite obviously the ignore list should
+ * be a separate object and will be one day.
+ * This method is internal to SimpleTest. Don't
+ * use it.
+ * @param string $class Class name to test.
+ * @return boolean True if should not be run.
+ * @access public
+ * @static
+ */
+ function isIgnored($class) {
+ $registry = &SimpleTest::_getRegistry();
+ return isset($registry['IgnoreList'][strtolower($class)]);
+ }
+
+ /**
+ * @deprecated
+ */
+ function setMockBaseClass($mock_base) {
+ $registry = &SimpleTest::_getRegistry();
+ $registry['MockBaseClass'] = $mock_base;
+ }
+
+ /**
+ * @deprecated
+ */
+ function getMockBaseClass() {
+ $registry = &SimpleTest::_getRegistry();
+ return $registry['MockBaseClass'];
+ }
+
+ /**
+ * Sets proxy to use on all requests for when
+ * testing from behind a firewall. Set host
+ * to false to disable. This will take effect
+ * if there are no other proxy settings.
+ * @param string $proxy Proxy host as URL.
+ * @param string $username Proxy username for authentication.
+ * @param string $password Proxy password for authentication.
+ * @access public
+ */
+ function useProxy($proxy, $username = false, $password = false) {
+ $registry = &SimpleTest::_getRegistry();
+ $registry['DefaultProxy'] = $proxy;
+ $registry['DefaultProxyUsername'] = $username;
+ $registry['DefaultProxyPassword'] = $password;
+ }
+
+ /**
+ * Accessor for default proxy host.
+ * @return string Proxy URL.
+ * @access public
+ */
+ function getDefaultProxy() {
+ $registry = &SimpleTest::_getRegistry();
+ return $registry['DefaultProxy'];
+ }
+
+ /**
+ * Accessor for default proxy username.
+ * @return string Proxy username for authentication.
+ * @access public
+ */
+ function getDefaultProxyUsername() {
+ $registry = &SimpleTest::_getRegistry();
+ return $registry['DefaultProxyUsername'];
+ }
+
+ /**
+ * Accessor for default proxy password.
+ * @return string Proxy password for authentication.
+ * @access public
+ */
+ function getDefaultProxyPassword() {
+ $registry = &SimpleTest::_getRegistry();
+ return $registry['DefaultProxyPassword'];
+ }
+
+ /**
+ * Accessor for global registry of options.
+ * @return hash All stored values.
+ * @access private
+ * @static
+ */
+ function &_getRegistry() {
+ static $registry = false;
+ if (! $registry) {
+ $registry = SimpleTest::_getDefaults();
+ }
+ return $registry;
+ }
+
+ /**
+ * Accessor for the context of the current
+ * test run.
+ * @return SimpleTestContext Current test run.
+ * @access public
+ * @static
+ */
+ function &getContext() {
+ static $context = false;
+ if (! $context) {
+ $context = new SimpleTestContext();
+ }
+ return $context;
+ }
+
+ /**
+ * Constant default values.
+ * @return hash All registry defaults.
+ * @access private
+ * @static
+ */
+ function _getDefaults() {
+ return array(
+ 'StubBaseClass' => 'SimpleStub',
+ 'MockBaseClass' => 'SimpleMock',
+ 'IgnoreList' => array(),
+ 'DefaultProxy' => false,
+ 'DefaultProxyUsername' => false,
+ 'DefaultProxyPassword' => false,
+ 'Preferred' => array(new HtmlReporter(), new TextReporter(), new XmlReporter()));
+ }
+}
+
+/**
+ * Container for all components for a specific
+ * test run. Makes things like error queues
+ * available to PHP event handlers, and also
+ * gets around some nasty reference issues in
+ * the mocks.
+ * @package SimpleTest
+ */
+class SimpleTestContext {
+ var $_test;
+ var $_reporter;
+ var $_resources;
+
+ /**
+ * Clears down the current context.
+ * @access public
+ */
+ function clear() {
+ $this->_resources = array();
+ }
+
+ /**
+ * Sets the current test case instance. This
+ * global instance can be used by the mock objects
+ * to send message to the test cases.
+ * @param SimpleTestCase $test Test case to register.
+ * @access public
+ */
+ function setTest(&$test) {
+ $this->clear();
+ $this->_test = &$test;
+ }
+
+ /**
+ * Accessor for currently running test case.
+ * @return SimpleTestCase Current test.
+ * @access public
+ */
+ function &getTest() {
+ return $this->_test;
+ }
+
+ /**
+ * Sets the current reporter. This
+ * global instance can be used by the mock objects
+ * to send messages.
+ * @param SimpleReporter $reporter Reporter to register.
+ * @access public
+ */
+ function setReporter(&$reporter) {
+ $this->clear();
+ $this->_reporter = &$reporter;
+ }
+
+ /**
+ * Accessor for current reporter.
+ * @return SimpleReporter Current reporter.
+ * @access public
+ */
+ function &getReporter() {
+ return $this->_reporter;
+ }
+
+ /**
+ * Accessor for the Singleton resource.
+ * @return object Global resource.
+ * @access public
+ * @static
+ */
+ function &get($resource) {
+ if (! isset($this->_resources[$resource])) {
+ $this->_resources[$resource] = &new $resource();
+ }
+ return $this->_resources[$resource];
+ }
+}
+
+/**
+ * Interrogates the stack trace to recover the
+ * failure point.
+ * @package SimpleTest
+ * @subpackage UnitTester
+ */
+class SimpleStackTrace {
+ var $_prefixes;
+
+ /**
+ * Stashes the list of target prefixes.
+ * @param array $prefixes List of method prefixes
+ * to search for.
+ */
+ function SimpleStackTrace($prefixes) {
+ $this->_prefixes = $prefixes;
+ }
+
+ /**
+ * Extracts the last method name that was not within
+ * Simpletest itself. Captures a stack trace if none given.
+ * @param array $stack List of stack frames.
+ * @return string Snippet of test report with line
+ * number and file.
+ * @access public
+ */
+ function traceMethod($stack = false) {
+ $stack = $stack ? $stack : $this->_captureTrace();
+ foreach ($stack as $frame) {
+ if ($this->_frameLiesWithinSimpleTestFolder($frame)) {
+ continue;
+ }
+ if ($this->_frameMatchesPrefix($frame)) {
+ return ' at [' . $frame['file'] . ' line ' . $frame['line'] . ']';
+ }
+ }
+ return '';
+ }
+
+ /**
+ * Test to see if error is generated by SimpleTest itself.
+ * @param array $frame PHP stack frame.
+ * @return boolean True if a SimpleTest file.
+ * @access private
+ */
+ function _frameLiesWithinSimpleTestFolder($frame) {
+ if (isset($frame['file'])) {
+ $path = substr(SIMPLE_TEST, 0, -1);
+ if (strpos($frame['file'], $path) === 0) {
+ if (dirname($frame['file']) == $path) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Tries to determine if the method call is an assert, etc.
+ * @param array $frame PHP stack frame.
+ * @return boolean True if matches a target.
+ * @access private
+ */
+ function _frameMatchesPrefix($frame) {
+ foreach ($this->_prefixes as $prefix) {
+ if (strncmp($frame['function'], $prefix, strlen($prefix)) == 0) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Grabs a current stack trace.
+ * @return array Fulle trace.
+ * @access private
+ */
+ function _captureTrace() {
+ if (function_exists('debug_backtrace')) {
+ return array_reverse(debug_backtrace());
+ }
+ return array();
+ }
+}
+
+/**
+ * @package SimpleTest
+ * @subpackage UnitTester
+ * @deprecated
+ */
+class SimpleTestOptions extends SimpleTest {
+
+ /**
+ * @deprecated
+ */
+ function getVersion() {
+ return Simpletest::getVersion();
+ }
+
+ /**
+ * @deprecated
+ */
+ function ignore($class) {
+ return Simpletest::ignore($class);
+ }
+
+ /**
+ * @deprecated
+ */
+ function isIgnored($class) {
+ return Simpletest::isIgnored($class);
+ }
+
+ /**
+ * @deprecated
+ */
+ function setMockBaseClass($mock_base) {
+ return Simpletest::setMockBaseClass($mock_base);
+ }
+
+ /**
+ * @deprecated
+ */
+ function getMockBaseClass() {
+ return Simpletest::getMockBaseClass();
+ }
+
+ /**
+ * @deprecated
+ */
+ function useProxy($proxy, $username = false, $password = false) {
+ return Simpletest::useProxy($proxy, $username, $password);
+ }
+
+ /**
+ * @deprecated
+ */
+ function getDefaultProxy() {
+ return Simpletest::getDefaultProxy();
+ }
+
+ /**
+ * @deprecated
+ */
+ function getDefaultProxyUsername() {
+ return Simpletest::getDefaultProxyUsername();
+ }
+
+ /**
+ * @deprecated
+ */
+ function getDefaultProxyPassword() {
+ return Simpletest::getDefaultProxyPassword();
+ }
+}
+?>
diff --git a/site/vendors/simpletest/socket.php b/site/vendors/simpletest/socket.php
new file mode 100644
index 0000000..3ad5a9f
--- /dev/null
+++ b/site/vendors/simpletest/socket.php
@@ -0,0 +1,216 @@
+<?php
+/**
+ * base include file for SimpleTest
+ * @package SimpleTest
+ * @subpackage MockObjects
+ * @version $Id: socket.php 1723 2008-04-08 00:34:10Z lastcraft $
+ */
+
+/**#@+
+ * include SimpleTest files
+ */
+require_once(dirname(__FILE__) . '/compatibility.php');
+/**#@-*/
+
+/**
+ * Stashes an error for later. Useful for constructors
+ * until PHP gets exceptions.
+ * @package SimpleTest
+ * @subpackage WebTester
+ */
+class SimpleStickyError {
+ var $_error = 'Constructor not chained';
+
+ /**
+ * Sets the error to empty.
+ * @access public
+ */
+ function SimpleStickyError() {
+ $this->_clearError();
+ }
+
+ /**
+ * Test for an outstanding error.
+ * @return boolean True if there is an error.
+ * @access public
+ */
+ function isError() {
+ return ($this->_error != '');
+ }
+
+ /**
+ * Accessor for an outstanding error.
+ * @return string Empty string if no error otherwise
+ * the error message.
+ * @access public
+ */
+ function getError() {
+ return $this->_error;
+ }
+
+ /**
+ * Sets the internal error.
+ * @param string Error message to stash.
+ * @access protected
+ */
+ function _setError($error) {
+ $this->_error = $error;
+ }
+
+ /**
+ * Resets the error state to no error.
+ * @access protected
+ */
+ function _clearError() {
+ $this->_setError('');
+ }
+}
+
+/**
+ * Wrapper for TCP/IP socket.
+ * @package SimpleTest
+ * @subpackage WebTester
+ */
+class SimpleSocket extends SimpleStickyError {
+ var $_handle;
+ var $_is_open = false;
+ var $_sent = '';
+ var $lock_size;
+
+ /**
+ * Opens a socket for reading and writing.
+ * @param string $host Hostname to send request to.
+ * @param integer $port Port on remote machine to open.
+ * @param integer $timeout Connection timeout in seconds.
+ * @param integer $block_size Size of chunk to read.
+ * @access public
+ */
+ function SimpleSocket($host, $port, $timeout, $block_size = 255) {
+ $this->SimpleStickyError();
+ if (! ($this->_handle = $this->_openSocket($host, $port, $error_number, $error, $timeout))) {
+ $this->_setError("Cannot open [$host:$port] with [$error] within [$timeout] seconds");
+ return;
+ }
+ $this->_is_open = true;
+ $this->_block_size = $block_size;
+ SimpleTestCompatibility::setTimeout($this->_handle, $timeout);
+ }
+
+ /**
+ * Writes some data to the socket and saves alocal copy.
+ * @param string $message String to send to socket.
+ * @return boolean True if successful.
+ * @access public
+ */
+ function write($message) {
+ if ($this->isError() || ! $this->isOpen()) {
+ return false;
+ }
+ $count = fwrite($this->_handle, $message);
+ if (! $count) {
+ if ($count === false) {
+ $this->_setError('Cannot write to socket');
+ $this->close();
+ }
+ return false;
+ }
+ fflush($this->_handle);
+ $this->_sent .= $message;
+ return true;
+ }
+
+ /**
+ * Reads data from the socket. The error suppresion
+ * is a workaround for PHP4 always throwing a warning
+ * with a secure socket.
+ * @return integer/boolean Incoming bytes. False
+ * on error.
+ * @access public
+ */
+ function read() {
+ if ($this->isError() || ! $this->isOpen()) {
+ return false;
+ }
+ $raw = @fread($this->_handle, $this->_block_size);
+ if ($raw === false) {
+ $this->_setError('Cannot read from socket');
+ $this->close();
+ }
+ return $raw;
+ }
+
+ /**
+ * Accessor for socket open state.
+ * @return boolean True if open.
+ * @access public
+ */
+ function isOpen() {
+ return $this->_is_open;
+ }
+
+ /**
+ * Closes the socket preventing further reads.
+ * Cannot be reopened once closed.
+ * @return boolean True if successful.
+ * @access public
+ */
+ function close() {
+ $this->_is_open = false;
+ return fclose($this->_handle);
+ }
+
+ /**
+ * Accessor for content so far.
+ * @return string Bytes sent only.
+ * @access public
+ */
+ function getSent() {
+ return $this->_sent;
+ }
+
+ /**
+ * Actually opens the low level socket.
+ * @param string $host Host to connect to.
+ * @param integer $port Port on host.
+ * @param integer $error_number Recipient of error code.
+ * @param string $error Recipoent of error message.
+ * @param integer $timeout Maximum time to wait for connection.
+ * @access protected
+ */
+ function _openSocket($host, $port, &$error_number, &$error, $timeout) {
+ return @fsockopen($host, $port, $error_number, $error, $timeout);
+ }
+}
+
+/**
+ * Wrapper for TCP/IP socket over TLS.
+ * @package SimpleTest
+ * @subpackage WebTester
+ */
+class SimpleSecureSocket extends SimpleSocket {
+
+ /**
+ * Opens a secure socket for reading and writing.
+ * @param string $host Hostname to send request to.
+ * @param integer $port Port on remote machine to open.
+ * @param integer $timeout Connection timeout in seconds.
+ * @access public
+ */
+ function SimpleSecureSocket($host, $port, $timeout) {
+ $this->SimpleSocket($host, $port, $timeout);
+ }
+
+ /**
+ * Actually opens the low level socket.
+ * @param string $host Host to connect to.
+ * @param integer $port Port on host.
+ * @param integer $error_number Recipient of error code.
+ * @param string $error Recipient of error message.
+ * @param integer $timeout Maximum time to wait for connection.
+ * @access protected
+ */
+ function _openSocket($host, $port, &$error_number, &$error, $timeout) {
+ return parent::_openSocket("tls://$host", $port, $error_number, $error, $timeout);
+ }
+}
+?> \ No newline at end of file
diff --git a/site/vendors/simpletest/tag.php b/site/vendors/simpletest/tag.php
new file mode 100644
index 0000000..7bccae2
--- /dev/null
+++ b/site/vendors/simpletest/tag.php
@@ -0,0 +1,1418 @@
+<?php
+/**
+ * Base include file for SimpleTest.
+ * @package SimpleTest
+ * @subpackage WebTester
+ * @version $Id: tag.php 1723 2008-04-08 00:34:10Z lastcraft $
+ */
+
+/**#@+
+ * include SimpleTest files
+ */
+require_once(dirname(__FILE__) . '/parser.php');
+require_once(dirname(__FILE__) . '/encoding.php');
+/**#@-*/
+
+/**
+ * HTML or XML tag.
+ * @package SimpleTest
+ * @subpackage WebTester
+ */
+class SimpleTag {
+ var $_name;
+ var $_attributes;
+ var $_content;
+
+ /**
+ * Starts with a named tag with attributes only.
+ * @param string $name Tag name.
+ * @param hash $attributes Attribute names and
+ * string values. Note that
+ * the keys must have been
+ * converted to lower case.
+ */
+ function SimpleTag($name, $attributes) {
+ $this->_name = strtolower(trim($name));
+ $this->_attributes = $attributes;
+ $this->_content = '';
+ }
+
+ /**
+ * Check to see if the tag can have both start and
+ * end tags with content in between.
+ * @return boolean True if content allowed.
+ * @access public
+ */
+ function expectEndTag() {
+ return true;
+ }
+
+ /**
+ * The current tag should not swallow all content for
+ * itself as it's searchable page content. Private
+ * content tags are usually widgets that contain default
+ * values.
+ * @return boolean False as content is available
+ * to other tags by default.
+ * @access public
+ */
+ function isPrivateContent() {
+ return false;
+ }
+
+ /**
+ * Appends string content to the current content.
+ * @param string $content Additional text.
+ * @access public
+ */
+ function addContent($content) {
+ $this->_content .= (string)$content;
+ }
+
+ /**
+ * Adds an enclosed tag to the content.
+ * @param SimpleTag $tag New tag.
+ * @access public
+ */
+ function addTag(&$tag) {
+ }
+
+ /**
+ * Accessor for tag name.
+ * @return string Name of tag.
+ * @access public
+ */
+ function getTagName() {
+ return $this->_name;
+ }
+
+ /**
+ * List of legal child elements.
+ * @return array List of element names.
+ * @access public
+ */
+ function getChildElements() {
+ return array();
+ }
+
+ /**
+ * Accessor for an attribute.
+ * @param string $label Attribute name.
+ * @return string Attribute value.
+ * @access public
+ */
+ function getAttribute($label) {
+ $label = strtolower($label);
+ if (! isset($this->_attributes[$label])) {
+ return false;
+ }
+ return (string)$this->_attributes[$label];
+ }
+
+ /**
+ * Sets an attribute.
+ * @param string $label Attribute name.
+ * @return string $value New attribute value.
+ * @access protected
+ */
+ function _setAttribute($label, $value) {
+ $this->_attributes[strtolower($label)] = $value;
+ }
+
+ /**
+ * Accessor for the whole content so far.
+ * @return string Content as big raw string.
+ * @access public
+ */
+ function getContent() {
+ return $this->_content;
+ }
+
+ /**
+ * Accessor for content reduced to visible text. Acts
+ * like a text mode browser, normalising space and
+ * reducing images to their alt text.
+ * @return string Content as plain text.
+ * @access public
+ */
+ function getText() {
+ return SimpleHtmlSaxParser::normalise($this->_content);
+ }
+
+ /**
+ * Test to see if id attribute matches.
+ * @param string $id ID to test against.
+ * @return boolean True on match.
+ * @access public
+ */
+ function isId($id) {
+ return ($this->getAttribute('id') == $id);
+ }
+}
+
+/**
+ * Base url.
+ * @package SimpleTest
+ * @subpackage WebTester
+ */
+class SimpleBaseTag extends SimpleTag {
+
+ /**
+ * Starts with a named tag with attributes only.
+ * @param hash $attributes Attribute names and
+ * string values.
+ */
+ function SimpleBaseTag($attributes) {
+ $this->SimpleTag('base', $attributes);
+ }
+
+ /**
+ * Base tag is not a block tag.
+ * @return boolean false
+ * @access public
+ */
+ function expectEndTag() {
+ return false;
+ }
+}
+
+/**
+ * Page title.
+ * @package SimpleTest
+ * @subpackage WebTester
+ */
+class SimpleTitleTag extends SimpleTag {
+
+ /**
+ * Starts with a named tag with attributes only.
+ * @param hash $attributes Attribute names and
+ * string values.
+ */
+ function SimpleTitleTag($attributes) {
+ $this->SimpleTag('title', $attributes);
+ }
+}
+
+/**
+ * Link.
+ * @package SimpleTest
+ * @subpackage WebTester
+ */
+class SimpleAnchorTag extends SimpleTag {
+
+ /**
+ * Starts with a named tag with attributes only.
+ * @param hash $attributes Attribute names and
+ * string values.
+ */
+ function SimpleAnchorTag($attributes) {
+ $this->SimpleTag('a', $attributes);
+ }
+
+ /**
+ * Accessor for URL as string.
+ * @return string Coerced as string.
+ * @access public
+ */
+ function getHref() {
+ $url = $this->getAttribute('href');
+ if (is_bool($url)) {
+ $url = '';
+ }
+ return $url;
+ }
+}
+
+/**
+ * Form element.
+ * @package SimpleTest
+ * @subpackage WebTester
+ */
+class SimpleWidget extends SimpleTag {
+ var $_value;
+ var $_label;
+ var $_is_set;
+
+ /**
+ * Starts with a named tag with attributes only.
+ * @param string $name Tag name.
+ * @param hash $attributes Attribute names and
+ * string values.
+ */
+ function SimpleWidget($name, $attributes) {
+ $this->SimpleTag($name, $attributes);
+ $this->_value = false;
+ $this->_label = false;
+ $this->_is_set = false;
+ }
+
+ /**
+ * Accessor for name submitted as the key in
+ * GET/POST variables hash.
+ * @return string Parsed value.
+ * @access public
+ */
+ function getName() {
+ return $this->getAttribute('name');
+ }
+
+ /**
+ * Accessor for default value parsed with the tag.
+ * @return string Parsed value.
+ * @access public
+ */
+ function getDefault() {
+ return $this->getAttribute('value');
+ }
+
+ /**
+ * Accessor for currently set value or default if
+ * none.
+ * @return string Value set by form or default
+ * if none.
+ * @access public
+ */
+ function getValue() {
+ if (! $this->_is_set) {
+ return $this->getDefault();
+ }
+ return $this->_value;
+ }
+
+ /**
+ * Sets the current form element value.
+ * @param string $value New value.
+ * @return boolean True if allowed.
+ * @access public
+ */
+ function setValue($value) {
+ $this->_value = $value;
+ $this->_is_set = true;
+ return true;
+ }
+
+ /**
+ * Resets the form element value back to the
+ * default.
+ * @access public
+ */
+ function resetValue() {
+ $this->_is_set = false;
+ }
+
+ /**
+ * Allows setting of a label externally, say by a
+ * label tag.
+ * @param string $label Label to attach.
+ * @access public
+ */
+ function setLabel($label) {
+ $this->_label = trim($label);
+ }
+
+ /**
+ * Reads external or internal label.
+ * @param string $label Label to test.
+ * @return boolean True is match.
+ * @access public
+ */
+ function isLabel($label) {
+ return $this->_label == trim($label);
+ }
+
+ /**
+ * Dispatches the value into the form encoded packet.
+ * @param SimpleEncoding $encoding Form packet.
+ * @access public
+ */
+ function write(&$encoding) {
+ if ($this->getName()) {
+ $encoding->add($this->getName(), $this->getValue());
+ }
+ }
+}
+
+/**
+ * Text, password and hidden field.
+ * @package SimpleTest
+ * @subpackage WebTester
+ */
+class SimpleTextTag extends SimpleWidget {
+
+ /**
+ * Starts with a named tag with attributes only.
+ * @param hash $attributes Attribute names and
+ * string values.
+ */
+ function SimpleTextTag($attributes) {
+ $this->SimpleWidget('input', $attributes);
+ if ($this->getAttribute('value') === false) {
+ $this->_setAttribute('value', '');
+ }
+ }
+
+ /**
+ * Tag contains no content.
+ * @return boolean False.
+ * @access public
+ */
+ function expectEndTag() {
+ return false;
+ }
+
+ /**
+ * Sets the current form element value. Cannot
+ * change the value of a hidden field.
+ * @param string $value New value.
+ * @return boolean True if allowed.
+ * @access public
+ */
+ function setValue($value) {
+ if ($this->getAttribute('type') == 'hidden') {
+ return false;
+ }
+ return parent::setValue($value);
+ }
+}
+
+/**
+ * Submit button as input tag.
+ * @package SimpleTest
+ * @subpackage WebTester
+ */
+class SimpleSubmitTag extends SimpleWidget {
+
+ /**
+ * Starts with a named tag with attributes only.
+ * @param hash $attributes Attribute names and
+ * string values.
+ */
+ function SimpleSubmitTag($attributes) {
+ $this->SimpleWidget('input', $attributes);
+ if ($this->getAttribute('value') === false) {
+ $this->_setAttribute('value', 'Submit');
+ }
+ }
+
+ /**
+ * Tag contains no end element.
+ * @return boolean False.
+ * @access public
+ */
+ function expectEndTag() {
+ return false;
+ }
+
+ /**
+ * Disables the setting of the button value.
+ * @param string $value Ignored.
+ * @return boolean True if allowed.
+ * @access public
+ */
+ function setValue($value) {
+ return false;
+ }
+
+ /**
+ * Value of browser visible text.
+ * @return string Visible label.
+ * @access public
+ */
+ function getLabel() {
+ return $this->getValue();
+ }
+
+ /**
+ * Test for a label match when searching.
+ * @param string $label Label to test.
+ * @return boolean True on match.
+ * @access public
+ */
+ function isLabel($label) {
+ return trim($label) == trim($this->getLabel());
+ }
+}
+
+/**
+ * Image button as input tag.
+ * @package SimpleTest
+ * @subpackage WebTester
+ */
+class SimpleImageSubmitTag extends SimpleWidget {
+
+ /**
+ * Starts with a named tag with attributes only.
+ * @param hash $attributes Attribute names and
+ * string values.
+ */
+ function SimpleImageSubmitTag($attributes) {
+ $this->SimpleWidget('input', $attributes);
+ }
+
+ /**
+ * Tag contains no end element.
+ * @return boolean False.
+ * @access public
+ */
+ function expectEndTag() {
+ return false;
+ }
+
+ /**
+ * Disables the setting of the button value.
+ * @param string $value Ignored.
+ * @return boolean True if allowed.
+ * @access public
+ */
+ function setValue($value) {
+ return false;
+ }
+
+ /**
+ * Value of browser visible text.
+ * @return string Visible label.
+ * @access public
+ */
+ function getLabel() {
+ if ($this->getAttribute('title')) {
+ return $this->getAttribute('title');
+ }
+ return $this->getAttribute('alt');
+ }
+
+ /**
+ * Test for a label match when searching.
+ * @param string $label Label to test.
+ * @return boolean True on match.
+ * @access public
+ */
+ function isLabel($label) {
+ return trim($label) == trim($this->getLabel());
+ }
+
+ /**
+ * Dispatches the value into the form encoded packet.
+ * @param SimpleEncoding $encoding Form packet.
+ * @param integer $x X coordinate of click.
+ * @param integer $y Y coordinate of click.
+ * @access public
+ */
+ function write(&$encoding, $x, $y) {
+ if ($this->getName()) {
+ $encoding->add($this->getName() . '.x', $x);
+ $encoding->add($this->getName() . '.y', $y);
+ } else {
+ $encoding->add('x', $x);
+ $encoding->add('y', $y);
+ }
+ }
+}
+
+/**
+ * Submit button as button tag.
+ * @package SimpleTest
+ * @subpackage WebTester
+ */
+class SimpleButtonTag extends SimpleWidget {
+
+ /**
+ * Starts with a named tag with attributes only.
+ * Defaults are very browser dependent.
+ * @param hash $attributes Attribute names and
+ * string values.
+ */
+ function SimpleButtonTag($attributes) {
+ $this->SimpleWidget('button', $attributes);
+ }
+
+ /**
+ * Check to see if the tag can have both start and
+ * end tags with content in between.
+ * @return boolean True if content allowed.
+ * @access public
+ */
+ function expectEndTag() {
+ return true;
+ }
+
+ /**
+ * Disables the setting of the button value.
+ * @param string $value Ignored.
+ * @return boolean True if allowed.
+ * @access public
+ */
+ function setValue($value) {
+ return false;
+ }
+
+ /**
+ * Value of browser visible text.
+ * @return string Visible label.
+ * @access public
+ */
+ function getLabel() {
+ return $this->getContent();
+ }
+
+ /**
+ * Test for a label match when searching.
+ * @param string $label Label to test.
+ * @return boolean True on match.
+ * @access public
+ */
+ function isLabel($label) {
+ return trim($label) == trim($this->getLabel());
+ }
+}
+
+/**
+ * Content tag for text area.
+ * @package SimpleTest
+ * @subpackage WebTester
+ */
+class SimpleTextAreaTag extends SimpleWidget {
+
+ /**
+ * Starts with a named tag with attributes only.
+ * @param hash $attributes Attribute names and
+ * string values.
+ */
+ function SimpleTextAreaTag($attributes) {
+ $this->SimpleWidget('textarea', $attributes);
+ }
+
+ /**
+ * Accessor for starting value.
+ * @return string Parsed value.
+ * @access public
+ */
+ function getDefault() {
+ return $this->_wrap(SimpleHtmlSaxParser::decodeHtml($this->getContent()));
+ }
+
+ /**
+ * Applies word wrapping if needed.
+ * @param string $value New value.
+ * @return boolean True if allowed.
+ * @access public
+ */
+ function setValue($value) {
+ return parent::setValue($this->_wrap($value));
+ }
+
+ /**
+ * Test to see if text should be wrapped.
+ * @return boolean True if wrapping on.
+ * @access private
+ */
+ function _wrapIsEnabled() {
+ if ($this->getAttribute('cols')) {
+ $wrap = $this->getAttribute('wrap');
+ if (($wrap == 'physical') || ($wrap == 'hard')) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Performs the formatting that is peculiar to
+ * this tag. There is strange behaviour in this
+ * one, including stripping a leading new line.
+ * Go figure. I am using Firefox as a guide.
+ * @param string $text Text to wrap.
+ * @return string Text wrapped with carriage
+ * returns and line feeds
+ * @access private
+ */
+ function _wrap($text) {
+ $text = str_replace("\r\r\n", "\r\n", str_replace("\n", "\r\n", $text));
+ $text = str_replace("\r\n\n", "\r\n", str_replace("\r", "\r\n", $text));
+ if (strncmp($text, "\r\n", strlen("\r\n")) == 0) {
+ $text = substr($text, strlen("\r\n"));
+ }
+ if ($this->_wrapIsEnabled()) {
+ return wordwrap(
+ $text,
+ (integer)$this->getAttribute('cols'),
+ "\r\n");
+ }
+ return $text;
+ }
+
+ /**
+ * The content of textarea is not part of the page.
+ * @return boolean True.
+ * @access public
+ */
+ function isPrivateContent() {
+ return true;
+ }
+}
+
+/**
+ * File upload widget.
+ * @package SimpleTest
+ * @subpackage WebTester
+ */
+class SimpleUploadTag extends SimpleWidget {
+
+ /**
+ * Starts with attributes only.
+ * @param hash $attributes Attribute names and
+ * string values.
+ */
+ function SimpleUploadTag($attributes) {
+ $this->SimpleWidget('input', $attributes);
+ }
+
+ /**
+ * Tag contains no content.
+ * @return boolean False.
+ * @access public
+ */
+ function expectEndTag() {
+ return false;
+ }
+
+ /**
+ * Dispatches the value into the form encoded packet.
+ * @param SimpleEncoding $encoding Form packet.
+ * @access public
+ */
+ function write(&$encoding) {
+ if (! file_exists($this->getValue())) {
+ return;
+ }
+ $encoding->attach(
+ $this->getName(),
+ implode('', file($this->getValue())),
+ basename($this->getValue()));
+ }
+}
+
+/**
+ * Drop down widget.
+ * @package SimpleTest
+ * @subpackage WebTester
+ */
+class SimpleSelectionTag extends SimpleWidget {
+ var $_options;
+ var $_choice;
+
+ /**
+ * Starts with attributes only.
+ * @param hash $attributes Attribute names and
+ * string values.
+ */
+ function SimpleSelectionTag($attributes) {
+ $this->SimpleWidget('select', $attributes);
+ $this->_options = array();
+ $this->_choice = false;
+ }
+
+ /**
+ * Adds an option tag to a selection field.
+ * @param SimpleOptionTag $tag New option.
+ * @access public
+ */
+ function addTag(&$tag) {
+ if ($tag->getTagName() == 'option') {
+ $this->_options[] = &$tag;
+ }
+ }
+
+ /**
+ * Text within the selection element is ignored.
+ * @param string $content Ignored.
+ * @access public
+ */
+ function addContent($content) {
+ }
+
+ /**
+ * Scans options for defaults. If none, then
+ * the first option is selected.
+ * @return string Selected field.
+ * @access public
+ */
+ function getDefault() {
+ for ($i = 0, $count = count($this->_options); $i < $count; $i++) {
+ if ($this->_options[$i]->getAttribute('selected') !== false) {
+ return $this->_options[$i]->getDefault();
+ }
+ }
+ if ($count > 0) {
+ return $this->_options[0]->getDefault();
+ }
+ return '';
+ }
+
+ /**
+ * Can only set allowed values.
+ * @param string $value New choice.
+ * @return boolean True if allowed.
+ * @access public
+ */
+ function setValue($value) {
+ for ($i = 0, $count = count($this->_options); $i < $count; $i++) {
+ if ($this->_options[$i]->isValue($value)) {
+ $this->_choice = $i;
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Accessor for current selection value.
+ * @return string Value attribute or
+ * content of opton.
+ * @access public
+ */
+ function getValue() {
+ if ($this->_choice === false) {
+ return $this->getDefault();
+ }
+ return $this->_options[$this->_choice]->getValue();
+ }
+}
+
+/**
+ * Drop down widget.
+ * @package SimpleTest
+ * @subpackage WebTester
+ */
+class MultipleSelectionTag extends SimpleWidget {
+ var $_options;
+ var $_values;
+
+ /**
+ * Starts with attributes only.
+ * @param hash $attributes Attribute names and
+ * string values.
+ */
+ function MultipleSelectionTag($attributes) {
+ $this->SimpleWidget('select', $attributes);
+ $this->_options = array();
+ $this->_values = false;
+ }
+
+ /**
+ * Adds an option tag to a selection field.
+ * @param SimpleOptionTag $tag New option.
+ * @access public
+ */
+ function addTag(&$tag) {
+ if ($tag->getTagName() == 'option') {
+ $this->_options[] = &$tag;
+ }
+ }
+
+ /**
+ * Text within the selection element is ignored.
+ * @param string $content Ignored.
+ * @access public
+ */
+ function addContent($content) {
+ }
+
+ /**
+ * Scans options for defaults to populate the
+ * value array().
+ * @return array Selected fields.
+ * @access public
+ */
+ function getDefault() {
+ $default = array();
+ for ($i = 0, $count = count($this->_options); $i < $count; $i++) {
+ if ($this->_options[$i]->getAttribute('selected') !== false) {
+ $default[] = $this->_options[$i]->getDefault();
+ }
+ }
+ return $default;
+ }
+
+ /**
+ * Can only set allowed values. Any illegal value
+ * will result in a failure, but all correct values
+ * will be set.
+ * @param array $desired New choices.
+ * @return boolean True if all allowed.
+ * @access public
+ */
+ function setValue($desired) {
+ $achieved = array();
+ foreach ($desired as $value) {
+ $success = false;
+ for ($i = 0, $count = count($this->_options); $i < $count; $i++) {
+ if ($this->_options[$i]->isValue($value)) {
+ $achieved[] = $this->_options[$i]->getValue();
+ $success = true;
+ break;
+ }
+ }
+ if (! $success) {
+ return false;
+ }
+ }
+ $this->_values = $achieved;
+ return true;
+ }
+
+ /**
+ * Accessor for current selection value.
+ * @return array List of currently set options.
+ * @access public
+ */
+ function getValue() {
+ if ($this->_values === false) {
+ return $this->getDefault();
+ }
+ return $this->_values;
+ }
+}
+
+/**
+ * Option for selection field.
+ * @package SimpleTest
+ * @subpackage WebTester
+ */
+class SimpleOptionTag extends SimpleWidget {
+
+ /**
+ * Stashes the attributes.
+ */
+ function SimpleOptionTag($attributes) {
+ $this->SimpleWidget('option', $attributes);
+ }
+
+ /**
+ * Does nothing.
+ * @param string $value Ignored.
+ * @return boolean Not allowed.
+ * @access public
+ */
+ function setValue($value) {
+ return false;
+ }
+
+ /**
+ * Test to see if a value matches the option.
+ * @param string $compare Value to compare with.
+ * @return boolean True if possible match.
+ * @access public
+ */
+ function isValue($compare) {
+ $compare = trim($compare);
+ if (trim($this->getValue()) == $compare) {
+ return true;
+ }
+ return trim($this->getContent()) == $compare;
+ }
+
+ /**
+ * Accessor for starting value. Will be set to
+ * the option label if no value exists.
+ * @return string Parsed value.
+ * @access public
+ */
+ function getDefault() {
+ if ($this->getAttribute('value') === false) {
+ return $this->getContent();
+ }
+ return $this->getAttribute('value');
+ }
+
+ /**
+ * The content of options is not part of the page.
+ * @return boolean True.
+ * @access public
+ */
+ function isPrivateContent() {
+ return true;
+ }
+}
+
+/**
+ * Radio button.
+ * @package SimpleTest
+ * @subpackage WebTester
+ */
+class SimpleRadioButtonTag extends SimpleWidget {
+
+ /**
+ * Stashes the attributes.
+ * @param array $attributes Hash of attributes.
+ */
+ function SimpleRadioButtonTag($attributes) {
+ $this->SimpleWidget('input', $attributes);
+ if ($this->getAttribute('value') === false) {
+ $this->_setAttribute('value', 'on');
+ }
+ }
+
+ /**
+ * Tag contains no content.
+ * @return boolean False.
+ * @access public
+ */
+ function expectEndTag() {
+ return false;
+ }
+
+ /**
+ * The only allowed value sn the one in the
+ * "value" attribute.
+ * @param string $value New value.
+ * @return boolean True if allowed.
+ * @access public
+ */
+ function setValue($value) {
+ if ($value === false) {
+ return parent::setValue($value);
+ }
+ if ($value != $this->getAttribute('value')) {
+ return false;
+ }
+ return parent::setValue($value);
+ }
+
+ /**
+ * Accessor for starting value.
+ * @return string Parsed value.
+ * @access public
+ */
+ function getDefault() {
+ if ($this->getAttribute('checked') !== false) {
+ return $this->getAttribute('value');
+ }
+ return false;
+ }
+}
+
+/**
+ * Checkbox widget.
+ * @package SimpleTest
+ * @subpackage WebTester
+ */
+class SimpleCheckboxTag extends SimpleWidget {
+
+ /**
+ * Starts with attributes only.
+ * @param hash $attributes Attribute names and
+ * string values.
+ */
+ function SimpleCheckboxTag($attributes) {
+ $this->SimpleWidget('input', $attributes);
+ if ($this->getAttribute('value') === false) {
+ $this->_setAttribute('value', 'on');
+ }
+ }
+
+ /**
+ * Tag contains no content.
+ * @return boolean False.
+ * @access public
+ */
+ function expectEndTag() {
+ return false;
+ }
+
+ /**
+ * The only allowed value in the one in the
+ * "value" attribute. The default for this
+ * attribute is "on". If this widget is set to
+ * true, then the usual value will be taken.
+ * @param string $value New value.
+ * @return boolean True if allowed.
+ * @access public
+ */
+ function setValue($value) {
+ if ($value === false) {
+ return parent::setValue($value);
+ }
+ if ($value === true) {
+ return parent::setValue($this->getAttribute('value'));
+ }
+ if ($value != $this->getAttribute('value')) {
+ return false;
+ }
+ return parent::setValue($value);
+ }
+
+ /**
+ * Accessor for starting value. The default
+ * value is "on".
+ * @return string Parsed value.
+ * @access public
+ */
+ function getDefault() {
+ if ($this->getAttribute('checked') !== false) {
+ return $this->getAttribute('value');
+ }
+ return false;
+ }
+}
+
+/**
+ * A group of multiple widgets with some shared behaviour.
+ * @package SimpleTest
+ * @subpackage WebTester
+ */
+class SimpleTagGroup {
+ var $_widgets = array();
+
+ /**
+ * Adds a tag to the group.
+ * @param SimpleWidget $widget
+ * @access public
+ */
+ function addWidget(&$widget) {
+ $this->_widgets[] = &$widget;
+ }
+
+ /**
+ * Accessor to widget set.
+ * @return array All widgets.
+ * @access protected
+ */
+ function &_getWidgets() {
+ return $this->_widgets;
+ }
+
+ /**
+ * Accessor for an attribute.
+ * @param string $label Attribute name.
+ * @return boolean Always false.
+ * @access public
+ */
+ function getAttribute($label) {
+ return false;
+ }
+
+ /**
+ * Fetches the name for the widget from the first
+ * member.
+ * @return string Name of widget.
+ * @access public
+ */
+ function getName() {
+ if (count($this->_widgets) > 0) {
+ return $this->_widgets[0]->getName();
+ }
+ }
+
+ /**
+ * Scans the widgets for one with the appropriate
+ * ID field.
+ * @param string $id ID value to try.
+ * @return boolean True if matched.
+ * @access public
+ */
+ function isId($id) {
+ for ($i = 0, $count = count($this->_widgets); $i < $count; $i++) {
+ if ($this->_widgets[$i]->isId($id)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Scans the widgets for one with the appropriate
+ * attached label.
+ * @param string $label Attached label to try.
+ * @return boolean True if matched.
+ * @access public
+ */
+ function isLabel($label) {
+ for ($i = 0, $count = count($this->_widgets); $i < $count; $i++) {
+ if ($this->_widgets[$i]->isLabel($label)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Dispatches the value into the form encoded packet.
+ * @param SimpleEncoding $encoding Form packet.
+ * @access public
+ */
+ function write(&$encoding) {
+ $encoding->add($this->getName(), $this->getValue());
+ }
+}
+
+/**
+ * A group of tags with the same name within a form.
+ * @package SimpleTest
+ * @subpackage WebTester
+ */
+class SimpleCheckboxGroup extends SimpleTagGroup {
+
+ /**
+ * Accessor for current selected widget or false
+ * if none.
+ * @return string/array Widget values or false if none.
+ * @access public
+ */
+ function getValue() {
+ $values = array();
+ $widgets = &$this->_getWidgets();
+ for ($i = 0, $count = count($widgets); $i < $count; $i++) {
+ if ($widgets[$i]->getValue() !== false) {
+ $values[] = $widgets[$i]->getValue();
+ }
+ }
+ return $this->_coerceValues($values);
+ }
+
+ /**
+ * Accessor for starting value that is active.
+ * @return string/array Widget values or false if none.
+ * @access public
+ */
+ function getDefault() {
+ $values = array();
+ $widgets = &$this->_getWidgets();
+ for ($i = 0, $count = count($widgets); $i < $count; $i++) {
+ if ($widgets[$i]->getDefault() !== false) {
+ $values[] = $widgets[$i]->getDefault();
+ }
+ }
+ return $this->_coerceValues($values);
+ }
+
+ /**
+ * Accessor for current set values.
+ * @param string/array/boolean $values Either a single string, a
+ * hash or false for nothing set.
+ * @return boolean True if all values can be set.
+ * @access public
+ */
+ function setValue($values) {
+ $values = $this->_makeArray($values);
+ if (! $this->_valuesArePossible($values)) {
+ return false;
+ }
+ $widgets = &$this->_getWidgets();
+ for ($i = 0, $count = count($widgets); $i < $count; $i++) {
+ $possible = $widgets[$i]->getAttribute('value');
+ if (in_array($widgets[$i]->getAttribute('value'), $values)) {
+ $widgets[$i]->setValue($possible);
+ } else {
+ $widgets[$i]->setValue(false);
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Tests to see if a possible value set is legal.
+ * @param string/array/boolean $values Either a single string, a
+ * hash or false for nothing set.
+ * @return boolean False if trying to set a
+ * missing value.
+ * @access private
+ */
+ function _valuesArePossible($values) {
+ $matches = array();
+ $widgets = &$this->_getWidgets();
+ for ($i = 0, $count = count($widgets); $i < $count; $i++) {
+ $possible = $widgets[$i]->getAttribute('value');
+ if (in_array($possible, $values)) {
+ $matches[] = $possible;
+ }
+ }
+ return ($values == $matches);
+ }
+
+ /**
+ * Converts the output to an appropriate format. This means
+ * that no values is false, a single value is just that
+ * value and only two or more are contained in an array.
+ * @param array $values List of values of widgets.
+ * @return string/array/boolean Expected format for a tag.
+ * @access private
+ */
+ function _coerceValues($values) {
+ if (count($values) == 0) {
+ return false;
+ } elseif (count($values) == 1) {
+ return $values[0];
+ } else {
+ return $values;
+ }
+ }
+
+ /**
+ * Converts false or string into array. The opposite of
+ * the coercian method.
+ * @param string/array/boolean $value A single item is converted
+ * to a one item list. False
+ * gives an empty list.
+ * @return array List of values, possibly empty.
+ * @access private
+ */
+ function _makeArray($value) {
+ if ($value === false) {
+ return array();
+ }
+ if (is_string($value)) {
+ return array($value);
+ }
+ return $value;
+ }
+}
+
+/**
+ * A group of tags with the same name within a form.
+ * Used for radio buttons.
+ * @package SimpleTest
+ * @subpackage WebTester
+ */
+class SimpleRadioGroup extends SimpleTagGroup {
+
+ /**
+ * Each tag is tried in turn until one is
+ * successfully set. The others will be
+ * unchecked if successful.
+ * @param string $value New value.
+ * @return boolean True if any allowed.
+ * @access public
+ */
+ function setValue($value) {
+ if (! $this->_valueIsPossible($value)) {
+ return false;
+ }
+ $index = false;
+ $widgets = &$this->_getWidgets();
+ for ($i = 0, $count = count($widgets); $i < $count; $i++) {
+ if (! $widgets[$i]->setValue($value)) {
+ $widgets[$i]->setValue(false);
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Tests to see if a value is allowed.
+ * @param string Attempted value.
+ * @return boolean True if a valid value.
+ * @access private
+ */
+ function _valueIsPossible($value) {
+ $widgets = &$this->_getWidgets();
+ for ($i = 0, $count = count($widgets); $i < $count; $i++) {
+ if ($widgets[$i]->getAttribute('value') == $value) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Accessor for current selected widget or false
+ * if none.
+ * @return string/boolean Value attribute or
+ * content of opton.
+ * @access public
+ */
+ function getValue() {
+ $widgets = &$this->_getWidgets();
+ for ($i = 0, $count = count($widgets); $i < $count; $i++) {
+ if ($widgets[$i]->getValue() !== false) {
+ return $widgets[$i]->getValue();
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Accessor for starting value that is active.
+ * @return string/boolean Value of first checked
+ * widget or false if none.
+ * @access public
+ */
+ function getDefault() {
+ $widgets = &$this->_getWidgets();
+ for ($i = 0, $count = count($widgets); $i < $count; $i++) {
+ if ($widgets[$i]->getDefault() !== false) {
+ return $widgets[$i]->getDefault();
+ }
+ }
+ return false;
+ }
+}
+
+/**
+ * Tag to keep track of labels.
+ * @package SimpleTest
+ * @subpackage WebTester
+ */
+class SimpleLabelTag extends SimpleTag {
+
+ /**
+ * Starts with a named tag with attributes only.
+ * @param hash $attributes Attribute names and
+ * string values.
+ */
+ function SimpleLabelTag($attributes) {
+ $this->SimpleTag('label', $attributes);
+ }
+
+ /**
+ * Access for the ID to attach the label to.
+ * @return string For attribute.
+ * @access public
+ */
+ function getFor() {
+ return $this->getAttribute('for');
+ }
+}
+
+/**
+ * Tag to aid parsing the form.
+ * @package SimpleTest
+ * @subpackage WebTester
+ */
+class SimpleFormTag extends SimpleTag {
+
+ /**
+ * Starts with a named tag with attributes only.
+ * @param hash $attributes Attribute names and
+ * string values.
+ */
+ function SimpleFormTag($attributes) {
+ $this->SimpleTag('form', $attributes);
+ }
+}
+
+/**
+ * Tag to aid parsing the frames in a page.
+ * @package SimpleTest
+ * @subpackage WebTester
+ */
+class SimpleFrameTag extends SimpleTag {
+
+ /**
+ * Starts with a named tag with attributes only.
+ * @param hash $attributes Attribute names and
+ * string values.
+ */
+ function SimpleFrameTag($attributes) {
+ $this->SimpleTag('frame', $attributes);
+ }
+
+ /**
+ * Tag contains no content.
+ * @return boolean False.
+ * @access public
+ */
+ function expectEndTag() {
+ return false;
+ }
+}
+?> \ No newline at end of file
diff --git a/site/vendors/simpletest/test/acceptance_test.php b/site/vendors/simpletest/test/acceptance_test.php
new file mode 100644
index 0000000..9dbb5a3
--- /dev/null
+++ b/site/vendors/simpletest/test/acceptance_test.php
@@ -0,0 +1,1633 @@
+<?php
+// $Id: acceptance_test.php 1700 2008-03-24 16:17:48Z lastcraft $
+require_once(dirname(__FILE__) . '/../autorun.php');
+require_once(dirname(__FILE__) . '/../compatibility.php');
+require_once(dirname(__FILE__) . '/../browser.php');
+require_once(dirname(__FILE__) . '/../web_tester.php');
+require_once(dirname(__FILE__) . '/../unit_tester.php');
+
+class SimpleTestAcceptanceTest extends WebTestCase {
+ function samples() {
+ return 'http://www.lastcraft.com/test/';
+ }
+}
+
+class TestOfLiveBrowser extends UnitTestCase {
+ function samples() {
+ return SimpleTestAcceptanceTest::samples();
+ }
+
+ function testGet() {
+ $browser = &new SimpleBrowser();
+ $browser->addHeader('User-Agent: SimpleTest ' . SimpleTest::getVersion());
+ $this->assertTrue($browser->get($this->samples() . 'network_confirm.php'));
+ $this->assertPattern('/target for the SimpleTest/', $browser->getContent());
+ $this->assertPattern('/Request method.*?<dd>GET<\/dd>/', $browser->getContent());
+ $this->assertEqual($browser->getTitle(), 'Simple test target file');
+ $this->assertEqual($browser->getResponseCode(), 200);
+ $this->assertEqual($browser->getMimeType(), 'text/html');
+ }
+
+ function testPost() {
+ $browser = &new SimpleBrowser();
+ $browser->addHeader('User-Agent: SimpleTest ' . SimpleTest::getVersion());
+ $this->assertTrue($browser->post($this->samples() . 'network_confirm.php'));
+ $this->assertPattern('/target for the SimpleTest/', $browser->getContent());
+ $this->assertPattern('/Request method.*?<dd>POST<\/dd>/', $browser->getContent());
+ }
+
+ function testAbsoluteLinkFollowing() {
+ $browser = &new SimpleBrowser();
+ $browser->addHeader('User-Agent: SimpleTest ' . SimpleTest::getVersion());
+ $browser->get($this->samples() . 'link_confirm.php');
+ $this->assertTrue($browser->clickLink('Absolute'));
+ $this->assertPattern('/target for the SimpleTest/', $browser->getContent());
+ }
+
+ function testRelativeEncodedeLinkFollowing() {
+ $browser = &new SimpleBrowser();
+ $browser->addHeader('User-Agent: SimpleTest ' . SimpleTest::getVersion());
+ $browser->get($this->samples() . 'link_confirm.php');
+ $this->assertTrue($browser->clickLink("märcêl kiek'eboe"));
+ $this->assertPattern('/target for the SimpleTest/', $browser->getContent());
+ }
+
+ function testRelativeLinkFollowing() {
+ $browser = &new SimpleBrowser();
+ $browser->addHeader('User-Agent: SimpleTest ' . SimpleTest::getVersion());
+ $browser->get($this->samples() . 'link_confirm.php');
+ $this->assertTrue($browser->clickLink('Relative'));
+ $this->assertPattern('/target for the SimpleTest/', $browser->getContent());
+ }
+
+ function testUnifiedClickLinkClicking() {
+ $browser = &new SimpleBrowser();
+ $browser->addHeader('User-Agent: SimpleTest ' . SimpleTest::getVersion());
+ $browser->get($this->samples() . 'link_confirm.php');
+ $this->assertTrue($browser->click('Relative'));
+ $this->assertPattern('/target for the SimpleTest/', $browser->getContent());
+ }
+
+ function testIdLinkFollowing() {
+ $browser = &new SimpleBrowser();
+ $browser->addHeader('User-Agent: SimpleTest ' . SimpleTest::getVersion());
+ $browser->get($this->samples() . 'link_confirm.php');
+ $this->assertTrue($browser->clickLinkById(1));
+ $this->assertPattern('/target for the SimpleTest/', $browser->getContent());
+ }
+
+ function testCookieReading() {
+ $browser = &new SimpleBrowser();
+ $browser->addHeader('User-Agent: SimpleTest ' . SimpleTest::getVersion());
+ $browser->get($this->samples() . 'set_cookies.php');
+ $this->assertEqual($browser->getCurrentCookieValue('session_cookie'), 'A');
+ $this->assertEqual($browser->getCurrentCookieValue('short_cookie'), 'B');
+ $this->assertEqual($browser->getCurrentCookieValue('day_cookie'), 'C');
+ }
+
+ function testSimpleSubmit() {
+ $browser = &new SimpleBrowser();
+ $browser->addHeader('User-Agent: SimpleTest ' . SimpleTest::getVersion());
+ $browser->get($this->samples() . 'form.html');
+ $this->assertTrue($browser->clickSubmit('Go!'));
+ $this->assertPattern('/Request method.*?<dd>POST<\/dd>/', $browser->getContent());
+ $this->assertPattern('/go=\[Go!\]/', $browser->getContent());
+ }
+
+ function testUnifiedClickCanSubmit() {
+ $browser = &new SimpleBrowser();
+ $browser->addHeader('User-Agent: SimpleTest ' . SimpleTest::getVersion());
+ $browser->get($this->samples() . 'form.html');
+ $this->assertTrue($browser->click('Go!'));
+ $this->assertPattern('/go=\[Go!\]/', $browser->getContent());
+ }
+}
+
+class TestRadioFields extends SimpleTestAcceptanceTest {
+ function testSetFieldAsInteger() {
+ $this->get($this->samples() . 'form_with_radio_buttons.html');
+ $this->assertTrue($this->setField('tested_field', 2));
+ $this->clickSubmitByName('send');
+ $this->assertEqual($this->getUrl(), $this->samples() . 'form_with_radio_buttons.html?tested_field=2&send=click+me');
+ }
+
+ function testSetFieldAsString() {
+ $this->get($this->samples() . 'form_with_radio_buttons.html');
+ $this->assertTrue($this->setField('tested_field', '2'));
+ $this->clickSubmitByName('send');
+ $this->assertEqual($this->getUrl(), $this->samples() . 'form_with_radio_buttons.html?tested_field=2&send=click+me');
+ }
+}
+
+class TestOfLiveFetching extends SimpleTestAcceptanceTest {
+ function setUp() {
+ $this->addHeader('User-Agent: SimpleTest ' . SimpleTest::getVersion());
+ }
+
+ function testFormWithArrayBasedInputs() {
+ $this->get($this->samples() . 'form_with_array_based_inputs.php');
+ $this->setField('value[]', '3', '1');
+ $this->setField('value[]', '4', '2');
+ $this->clickSubmit('Go');
+ $this->assertPattern('/QUERY_STRING : value%5B%5D=3&value%5B%5D=4&submit=Go/');
+ }
+
+ function testFormWithQuotedValues() {
+ $this->get($this->samples() . 'form_with_quoted_values.php');
+ $this->assertField('a', 'default');
+ $this->assertFieldById('text_field', 'default');
+ $this->clickSubmit('Go');
+ $this->assertPattern('/a=default&submit=Go/');
+ }
+
+ function testGet() {
+ $this->assertTrue($this->get($this->samples() . 'network_confirm.php'));
+ $this->assertEqual($this->getUrl(), $this->samples() . 'network_confirm.php');
+ $this->assertText('target for the SimpleTest');
+ $this->assertPattern('/Request method.*?<dd>GET<\/dd>/');
+ $this->assertTitle('Simple test target file');
+ $this->assertTitle(new PatternExpectation('/target file/'));
+ $this->assertResponse(200);
+ $this->assertMime('text/html');
+ $this->assertHeader('connection', 'close');
+ $this->assertHeader('connection', new PatternExpectation('/los/'));
+ }
+
+ function testSlowGet() {
+ $this->assertTrue($this->get($this->samples() . 'slow_page.php'));
+ }
+
+ function testTimedOutGet() {
+ $this->setConnectionTimeout(1);
+ $this->ignoreErrors();
+ $this->assertFalse($this->get($this->samples() . 'slow_page.php'));
+ }
+
+ function testPost() {
+ $this->assertTrue($this->post($this->samples() . 'network_confirm.php'));
+ $this->assertText('target for the SimpleTest');
+ $this->assertPattern('/Request method.*?<dd>POST<\/dd>/');
+ }
+
+ function testGetWithData() {
+ $this->get($this->samples() . 'network_confirm.php', array("a" => "aaa"));
+ $this->assertPattern('/Request method.*?<dd>GET<\/dd>/');
+ $this->assertText('a=[aaa]');
+ }
+
+ function testPostWithData() {
+ $this->post($this->samples() . 'network_confirm.php', array("a" => "aaa"));
+ $this->assertPattern('/Request method.*?<dd>POST<\/dd>/');
+ $this->assertText('a=[aaa]');
+ }
+
+ function testPostWithRecursiveData() {
+ $this->post($this->samples() . 'network_confirm.php', array("a" => "aaa"));
+ $this->assertPattern('/Request method.*?<dd>POST<\/dd>/');
+ $this->assertText('a=[aaa]');
+
+ $this->post($this->samples() . 'network_confirm.php', array("a[aa]" => "aaa"));
+ $this->assertPattern('/Request method.*?<dd>POST<\/dd>/');
+ $this->assertText('a=[aa=[aaa]]');
+
+ $this->post($this->samples() . 'network_confirm.php', array("a[aa][aaa]" => "aaaa"));
+ $this->assertPattern('/Request method.*?<dd>POST<\/dd>/');
+ $this->assertText('a=[aa=[aaa=[aaaa]]]');
+
+ $this->post($this->samples() . 'network_confirm.php', array("a" => array("aa" => "aaa")));
+ $this->assertPattern('/Request method.*?<dd>POST<\/dd>/');
+ $this->assertText('a=[aa=[aaa]]');
+
+ $this->post($this->samples() . 'network_confirm.php', array("a" => array("aa" => array("aaa" => "aaaa"))));
+ $this->assertPattern('/Request method.*?<dd>POST<\/dd>/');
+ $this->assertText('a=[aa=[aaa=[aaaa]]]');
+ }
+
+ function testRelativeGet() {
+ $this->get($this->samples() . 'link_confirm.php');
+ $this->assertTrue($this->get('network_confirm.php'));
+ $this->assertText('target for the SimpleTest');
+ }
+
+ function testRelativePost() {
+ $this->post($this->samples() . 'link_confirm.php');
+ $this->assertTrue($this->post('network_confirm.php'));
+ $this->assertText('target for the SimpleTest');
+ }
+}
+
+class TestOfLinkFollowing extends SimpleTestAcceptanceTest {
+ function setUp() {
+ $this->addHeader('User-Agent: SimpleTest ' . SimpleTest::getVersion());
+ }
+
+ function testLinkAssertions() {
+ $this->get($this->samples() . 'link_confirm.php');
+ $this->assertLink('Absolute', $this->samples() . 'network_confirm.php');
+ $this->assertLink('Absolute', new PatternExpectation('/confirm/'));
+ $this->assertClickable('Absolute');
+ }
+
+ function testAbsoluteLinkFollowing() {
+ $this->get($this->samples() . 'link_confirm.php');
+ $this->assertTrue($this->clickLink('Absolute'));
+ $this->assertText('target for the SimpleTest');
+ }
+
+ function testRelativeLinkFollowing() {
+ $this->get($this->samples() . 'link_confirm.php');
+ $this->assertTrue($this->clickLink('Relative'));
+ $this->assertText('target for the SimpleTest');
+ }
+
+ function testLinkIdFollowing() {
+ $this->get($this->samples() . 'link_confirm.php');
+ $this->assertLinkById(1);
+ $this->assertTrue($this->clickLinkById(1));
+ $this->assertText('target for the SimpleTest');
+ }
+
+ function testAbsoluteUrlBehavesAbsolutely() {
+ $this->get($this->samples() . 'link_confirm.php');
+ $this->get('http://www.lastcraft.com');
+ $this->assertText('No guarantee of quality is given or even intended');
+ }
+
+ function testRelativeUrlRespectsBaseTag() {
+ $this->get($this->samples() . 'base_tag/base_link.html');
+ $this->click('Back to test pages');
+ $this->assertTitle('Simple test target file');
+ }
+}
+
+class TestOfLivePageLinkingWithMinimalLinks extends SimpleTestAcceptanceTest {
+ function setUp() {
+ $this->addHeader('User-Agent: SimpleTest ' . SimpleTest::getVersion());
+ }
+
+ function testClickToExplicitelyNamedSelfReturns() {
+ $this->get($this->samples() . 'front_controller_style/a_page.php');
+ $this->assertEqual($this->getUrl(), $this->samples() . 'front_controller_style/a_page.php');
+ $this->assertTitle('Simple test page with links');
+ $this->assertLink('Self');
+ $this->clickLink('Self');
+ $this->assertTitle('Simple test page with links');
+ }
+
+ function testClickToMissingPageReturnsToSamePage() {
+ $this->get($this->samples() . 'front_controller_style/a_page.php');
+ $this->clickLink('No page');
+ $this->assertTitle('Simple test page with links');
+ $this->assertText('[action=no_page]');
+ }
+
+ function testClickToBareActionReturnsToSamePage() {
+ $this->get($this->samples() . 'front_controller_style/a_page.php');
+ $this->clickLink('Bare action');
+ $this->assertTitle('Simple test page with links');
+ $this->assertText('[action=]');
+ }
+
+ function testClickToSingleQuestionMarkReturnsToSamePage() {
+ $this->get($this->samples() . 'front_controller_style/a_page.php');
+ $this->clickLink('Empty query');
+ $this->assertTitle('Simple test page with links');
+ }
+
+ function testClickToEmptyStringReturnsToSamePage() {
+ $this->get($this->samples() . 'front_controller_style/a_page.php');
+ $this->clickLink('Empty link');
+ $this->assertTitle('Simple test page with links');
+ }
+
+ function testClickToSingleDotGoesToCurrentDirectory() {
+ $this->get($this->samples() . 'front_controller_style/a_page.php');
+ $this->clickLink('Current directory');
+ $this->assertTitle(
+ 'Simple test front controller',
+ '%s -> index.php needs to be set as a default web server home page');
+ }
+
+ function testClickBackADirectoryLevel() {
+ $this->get($this->samples() . 'front_controller_style/');
+ $this->clickLink('Down one');
+ $this->assertPattern('|Index of .*?/test|i');
+ }
+}
+
+class TestOfLiveFrontControllerEmulation extends SimpleTestAcceptanceTest {
+ function setUp() {
+ $this->addHeader('User-Agent: SimpleTest ' . SimpleTest::getVersion());
+ }
+
+ function testJumpToNamedPage() {
+ $this->get($this->samples() . 'front_controller_style/');
+ $this->assertText('Simple test front controller');
+ $this->clickLink('Index');
+ $this->assertResponse(200);
+ $this->assertText('[action=index]');
+ }
+
+ function testJumpToUnnamedPage() {
+ $this->get($this->samples() . 'front_controller_style/');
+ $this->clickLink('No page');
+ $this->assertResponse(200);
+ $this->assertText('Simple test front controller');
+ $this->assertText('[action=no_page]');
+ }
+
+ function testJumpToUnnamedPageWithBareParameter() {
+ $this->get($this->samples() . 'front_controller_style/');
+ $this->clickLink('Bare action');
+ $this->assertResponse(200);
+ $this->assertText('Simple test front controller');
+ $this->assertText('[action=]');
+ }
+
+ function testJumpToUnnamedPageWithEmptyQuery() {
+ $this->get($this->samples() . 'front_controller_style/');
+ $this->clickLink('Empty query');
+ $this->assertResponse(200);
+ $this->assertPattern('/Simple test front controller/');
+ $this->assertPattern('/raw get data.*?\[\].*?get data/si');
+ }
+
+ function testJumpToUnnamedPageWithEmptyLink() {
+ $this->get($this->samples() . 'front_controller_style/');
+ $this->clickLink('Empty link');
+ $this->assertResponse(200);
+ $this->assertPattern('/Simple test front controller/');
+ $this->assertPattern('/raw get data.*?\[\].*?get data/si');
+ }
+
+ function testJumpBackADirectoryLevel() {
+ $this->get($this->samples() . 'front_controller_style/');
+ $this->clickLink('Down one');
+ $this->assertPattern('|Index of .*?/test|');
+ }
+
+ function testSubmitToNamedPage() {
+ $this->get($this->samples() . 'front_controller_style/');
+ $this->assertText('Simple test front controller');
+ $this->clickSubmit('Index');
+ $this->assertResponse(200);
+ $this->assertText('[action=Index]');
+ }
+
+ function testSubmitToSameDirectory() {
+ $this->get($this->samples() . 'front_controller_style/index.php');
+ $this->clickSubmit('Same directory');
+ $this->assertResponse(200);
+ $this->assertText('[action=Same+directory]');
+ }
+
+ function testSubmitToEmptyAction() {
+ $this->get($this->samples() . 'front_controller_style/index.php');
+ $this->clickSubmit('Empty action');
+ $this->assertResponse(200);
+ $this->assertText('[action=Empty+action]');
+ }
+
+ function testSubmitToNoAction() {
+ $this->get($this->samples() . 'front_controller_style/index.php');
+ $this->clickSubmit('No action');
+ $this->assertResponse(200);
+ $this->assertText('[action=No+action]');
+ }
+
+ function testSubmitBackADirectoryLevel() {
+ $this->get($this->samples() . 'front_controller_style/');
+ $this->clickSubmit('Down one');
+ $this->assertPattern('|Index of .*?/test|');
+ }
+
+ function testSubmitToNamedPageWithMixedPostAndGet() {
+ $this->get($this->samples() . 'front_controller_style/?a=A');
+ $this->assertText('Simple test front controller');
+ $this->clickSubmit('Index post');
+ $this->assertText('action=[Index post]');
+ $this->assertNoText('[a=A]');
+ }
+
+ function testSubmitToSameDirectoryMixedPostAndGet() {
+ $this->get($this->samples() . 'front_controller_style/index.php?a=A');
+ $this->clickSubmit('Same directory post');
+ $this->assertText('action=[Same directory post]');
+ $this->assertNoText('[a=A]');
+ }
+
+ function testSubmitToEmptyActionMixedPostAndGet() {
+ $this->get($this->samples() . 'front_controller_style/index.php?a=A');
+ $this->clickSubmit('Empty action post');
+ $this->assertText('action=[Empty action post]');
+ $this->assertText('[a=A]');
+ }
+
+ function testSubmitToNoActionMixedPostAndGet() {
+ $this->get($this->samples() . 'front_controller_style/index.php?a=A');
+ $this->clickSubmit('No action post');
+ $this->assertText('action=[No action post]');
+ $this->assertText('[a=A]');
+ }
+}
+
+class TestOfLiveHeaders extends SimpleTestAcceptanceTest {
+ function setUp() {
+ $this->addHeader('User-Agent: SimpleTest ' . SimpleTest::getVersion());
+ }
+
+ function testConfirmingHeaderExistence() {
+ $this->get('http://www.lastcraft.com/');
+ $this->assertHeader('content-type');
+ $this->assertHeader('content-type', 'text/html');
+ $this->assertHeaderPattern('content-type', '/HTML/i');
+ $this->assertNoHeader('WWW-Authenticate');
+ }
+}
+
+class TestOfLiveRedirects extends SimpleTestAcceptanceTest {
+ function setUp() {
+ $this->addHeader('User-Agent: SimpleTest ' . SimpleTest::getVersion());
+ }
+
+ function testNoRedirects() {
+ $this->setMaximumRedirects(0);
+ $this->get($this->samples() . 'redirect.php');
+ $this->assertTitle('Redirection test');
+ }
+
+ function testRedirects() {
+ $this->setMaximumRedirects(1);
+ $this->get($this->samples() . 'redirect.php');
+ $this->assertTitle('Simple test target file');
+ }
+
+ function testRedirectLosesGetData() {
+ $this->get($this->samples() . 'redirect.php', array('a' => 'aaa'));
+ $this->assertNoText('a=[aaa]');
+ }
+
+ function testRedirectKeepsExtraRequestDataOfItsOwn() {
+ $this->get($this->samples() . 'redirect.php');
+ $this->assertText('r=[rrr]');
+ }
+
+ function testRedirectLosesPostData() {
+ $this->post($this->samples() . 'redirect.php', array('a' => 'aaa'));
+ $this->assertTitle('Simple test target file');
+ $this->assertNoText('a=[aaa]');
+ }
+
+ function testRedirectWithBaseUrlChange() {
+ $this->get($this->samples() . 'base_change_redirect.php');
+ $this->assertTitle('Simple test target file in folder');
+ $this->get($this->samples() . 'path/base_change_redirect.php');
+ $this->assertTitle('Simple test target file');
+ }
+
+ function testRedirectWithDoubleBaseUrlChange() {
+ $this->get($this->samples() . 'double_base_change_redirect.php');
+ $this->assertTitle('Simple test target file');
+ }
+}
+
+class TestOfLiveCookies extends SimpleTestAcceptanceTest {
+ function setUp() {
+ $this->addHeader('User-Agent: SimpleTest ' . SimpleTest::getVersion());
+ }
+
+ function here() {
+ return new SimpleUrl($this->samples());
+ }
+
+ function thisHost() {
+ $here = $this->here();
+ return $here->getHost();
+ }
+
+ function thisPath() {
+ $here = $this->here();
+ return $here->getPath();
+ }
+
+ function testCookieSettingAndAssertions() {
+ $this->setCookie('a', 'Test cookie a');
+ $this->setCookie('b', 'Test cookie b', $this->thisHost());
+ $this->setCookie('c', 'Test cookie c', $this->thisHost(), $this->thisPath());
+ $this->get($this->samples() . 'network_confirm.php');
+ $this->assertText('Test cookie a');
+ $this->assertText('Test cookie b');
+ $this->assertText('Test cookie c');
+ $this->assertCookie('a');
+ $this->assertCookie('b', 'Test cookie b');
+ $this->assertTrue($this->getCookie('c') == 'Test cookie c');
+ }
+
+ function testNoCookieSetWhenCookiesDisabled() {
+ $this->setCookie('a', 'Test cookie a');
+ $this->ignoreCookies();
+ $this->get($this->samples() . 'network_confirm.php');
+ $this->assertNoText('Test cookie a');
+ }
+
+ function testCookieReading() {
+ $this->get($this->samples() . 'set_cookies.php');
+ $this->assertCookie('session_cookie', 'A');
+ $this->assertCookie('short_cookie', 'B');
+ $this->assertCookie('day_cookie', 'C');
+ }
+
+ function testNoCookieReadingWhenCookiesDisabled() {
+ $this->ignoreCookies();
+ $this->get($this->samples() . 'set_cookies.php');
+ $this->assertNoCookie('session_cookie');
+ $this->assertNoCookie('short_cookie');
+ $this->assertNoCookie('day_cookie');
+ }
+
+ function testCookiePatternAssertions() {
+ $this->get($this->samples() . 'set_cookies.php');
+ $this->assertCookie('session_cookie', new PatternExpectation('/a/i'));
+ }
+
+ function testTemporaryCookieExpiry() {
+ $this->get($this->samples() . 'set_cookies.php');
+ $this->restart();
+ $this->assertNoCookie('session_cookie');
+ $this->assertCookie('day_cookie', 'C');
+ }
+
+ function testTimedCookieExpiryWith100SecondMargin() {
+ $this->get($this->samples() . 'set_cookies.php');
+ $this->ageCookies(3600);
+ $this->restart(time() + 100);
+ $this->assertNoCookie('session_cookie');
+ $this->assertNoCookie('hour_cookie');
+ $this->assertCookie('day_cookie', 'C');
+ }
+
+ function testNoClockOverDriftBy100Seconds() {
+ $this->get($this->samples() . 'set_cookies.php');
+ $this->restart(time() + 200);
+ $this->assertNoCookie(
+ 'short_cookie',
+ '%s -> Please check your computer clock setting if you are not using NTP');
+ }
+
+ function testNoClockUnderDriftBy100Seconds() {
+ $this->get($this->samples() . 'set_cookies.php');
+ $this->restart(time() + 0);
+ $this->assertCookie(
+ 'short_cookie',
+ 'B',
+ '%s -> Please check your computer clock setting if you are not using NTP');
+ }
+
+ function testCookiePath() {
+ $this->get($this->samples() . 'set_cookies.php');
+ $this->assertNoCookie('path_cookie', 'D');
+ $this->get('./path/show_cookies.php');
+ $this->assertPattern('/path_cookie/');
+ $this->assertCookie('path_cookie', 'D');
+ }
+}
+
+class LiveTestOfForms extends SimpleTestAcceptanceTest {
+ function setUp() {
+ $this->addHeader('User-Agent: SimpleTest ' . SimpleTest::getVersion());
+ }
+
+ function testSimpleSubmit() {
+ $this->get($this->samples() . 'form.html');
+ $this->assertTrue($this->clickSubmit('Go!'));
+ $this->assertPattern('/Request method.*?<dd>POST<\/dd>/');
+ $this->assertText('go=[Go!]');
+ }
+
+ function testDefaultFormValues() {
+ $this->get($this->samples() . 'form.html');
+ $this->assertFieldByName('a', '');
+ $this->assertFieldByName('b', 'Default text');
+ $this->assertFieldByName('c', '');
+ $this->assertFieldByName('d', 'd1');
+ $this->assertFieldByName('e', false);
+ $this->assertFieldByName('f', 'on');
+ $this->assertFieldByName('g', 'g3');
+ $this->assertFieldByName('h', 2);
+ $this->assertFieldByName('go', 'Go!');
+ $this->assertClickable('Go!');
+ $this->assertSubmit('Go!');
+ $this->assertTrue($this->clickSubmit('Go!'));
+ $this->assertText('go=[Go!]');
+ $this->assertText('a=[]');
+ $this->assertText('b=[Default text]');
+ $this->assertText('c=[]');
+ $this->assertText('d=[d1]');
+ $this->assertNoText('e=[');
+ $this->assertText('f=[on]');
+ $this->assertText('g=[g3]');
+ }
+
+ function testFormSubmissionByButtonLabel() {
+ $this->get($this->samples() . 'form.html');
+ $this->setFieldByName('a', 'aaa');
+ $this->setFieldByName('b', 'bbb');
+ $this->setFieldByName('c', 'ccc');
+ $this->setFieldByName('d', 'D2');
+ $this->setFieldByName('e', 'on');
+ $this->setFieldByName('f', false);
+ $this->setFieldByName('g', 'g2');
+ $this->setFieldByName('h', 1);
+ $this->assertTrue($this->clickSubmit('Go!'));
+ $this->assertText('a=[aaa]');
+ $this->assertText('b=[bbb]');
+ $this->assertText('c=[ccc]');
+ $this->assertText('d=[d2]');
+ $this->assertText('e=[on]');
+ $this->assertNoText('f=[');
+ $this->assertText('g=[g2]');
+ }
+
+ function testAdditionalFormValues() {
+ $this->get($this->samples() . 'form.html');
+ $this->assertTrue($this->clickSubmit('Go!', array('add' => 'A')));
+ $this->assertText('go=[Go!]');
+ $this->assertText('add=[A]');
+ }
+
+ function testFormSubmissionByName() {
+ $this->get($this->samples() . 'form.html');
+ $this->setFieldByName('a', 'A');
+ $this->assertTrue($this->clickSubmitByName('go'));
+ $this->assertText('a=[A]');
+ }
+
+ function testFormSubmissionByNameAndAdditionalParameters() {
+ $this->get($this->samples() . 'form.html');
+ $this->assertTrue($this->clickSubmitByName('go', array('add' => 'A')));
+ $this->assertText('go=[Go!]');
+ $this->assertText('add=[A]');
+ }
+
+ function testFormSubmissionBySubmitButtonLabeledSubmit() {
+ $this->get($this->samples() . 'form.html');
+ $this->assertTrue($this->clickSubmitByName('test'));
+ $this->assertText('test=[Submit]');
+ }
+
+ function testFormSubmissionWithIds() {
+ $this->get($this->samples() . 'form.html');
+ $this->assertFieldById(1, '');
+ $this->assertFieldById(2, 'Default text');
+ $this->assertFieldById(3, '');
+ $this->assertFieldById(4, 'd1');
+ $this->assertFieldById(5, false);
+ $this->assertFieldById(6, 'on');
+ $this->assertFieldById(8, 'g3');
+ $this->assertFieldById(11, 2);
+ $this->setFieldById(1, 'aaa');
+ $this->setFieldById(2, 'bbb');
+ $this->setFieldById(3, 'ccc');
+ $this->setFieldById(4, 'D2');
+ $this->setFieldById(5, 'on');
+ $this->setFieldById(6, false);
+ $this->setFieldById(8, 'g2');
+ $this->setFieldById(11, 'H1');
+ $this->assertTrue($this->clickSubmitById(99));
+ $this->assertText('a=[aaa]');
+ $this->assertText('b=[bbb]');
+ $this->assertText('c=[ccc]');
+ $this->assertText('d=[d2]');
+ $this->assertText('e=[on]');
+ $this->assertNoText('f=[');
+ $this->assertText('g=[g2]');
+ $this->assertText('h=[1]');
+ $this->assertText('go=[Go!]');
+ }
+
+ function testFormSubmissionWithLabels() {
+ $this->get($this->samples() . 'form.html');
+ $this->assertField('Text A', '');
+ $this->assertField('Text B', 'Default text');
+ $this->assertField('Text area C', '');
+ $this->assertField('Selection D', 'd1');
+ $this->assertField('Checkbox E', false);
+ $this->assertField('Checkbox F', 'on');
+ $this->assertField('3', 'g3');
+ $this->assertField('Selection H', 2);
+ $this->setField('Text A', 'aaa');
+ $this->setField('Text B', 'bbb');
+ $this->setField('Text area C', 'ccc');
+ $this->setField('Selection D', 'D2');
+ $this->setField('Checkbox E', 'on');
+ $this->setField('Checkbox F', false);
+ $this->setField('2', 'g2');
+ $this->setField('Selection H', 'H1');
+ $this->clickSubmit('Go!');
+ $this->assertText('a=[aaa]');
+ $this->assertText('b=[bbb]');
+ $this->assertText('c=[ccc]');
+ $this->assertText('d=[d2]');
+ $this->assertText('e=[on]');
+ $this->assertNoText('f=[');
+ $this->assertText('g=[g2]');
+ $this->assertText('h=[1]');
+ $this->assertText('go=[Go!]');
+ }
+
+ function testSettingCheckboxWithBooleanTrueSetsUnderlyingValue() {
+ $this->get($this->samples() . 'form.html');
+ $this->setField('Checkbox E', true);
+ $this->assertField('Checkbox E', 'on');
+ $this->clickSubmit('Go!');
+ $this->assertText('e=[on]');
+ }
+
+ function testFormSubmissionWithMixedPostAndGet() {
+ $this->get($this->samples() . 'form_with_mixed_post_and_get.html');
+ $this->setField('Text A', 'Hello');
+ $this->assertTrue($this->clickSubmit('Go!'));
+ $this->assertText('a=[Hello]');
+ $this->assertText('x=[X]');
+ $this->assertText('y=[Y]');
+ }
+
+ function testFormSubmissionWithMixedPostAndEncodedGet() {
+ $this->get($this->samples() . 'form_with_mixed_post_and_get.html');
+ $this->setField('Text B', 'Hello');
+ $this->assertTrue($this->clickSubmit('Go encoded!'));
+ $this->assertText('b=[Hello]');
+ $this->assertText('x=[X]');
+ $this->assertText('y=[Y]');
+ }
+
+ function testFormSubmissionWithoutAction() {
+ $this->get($this->samples() . 'form_without_action.php?test=test');
+ $this->assertText('_GET : [test]');
+ $this->assertTrue($this->clickSubmit('Submit Post With Empty Action'));
+ $this->assertText('_GET : [test]');
+ $this->assertText('_POST : [test]');
+ }
+
+ function testImageSubmissionByLabel() {
+ $this->get($this->samples() . 'form.html');
+ $this->assertImage('Image go!');
+ $this->assertTrue($this->clickImage('Image go!', 10, 12));
+ $this->assertText('go_x=[10]');
+ $this->assertText('go_y=[12]');
+ }
+
+ function testImageSubmissionByLabelWithAdditionalParameters() {
+ $this->get($this->samples() . 'form.html');
+ $this->assertTrue($this->clickImage('Image go!', 10, 12, array('add' => 'A')));
+ $this->assertText('add=[A]');
+ }
+
+ function testImageSubmissionByName() {
+ $this->get($this->samples() . 'form.html');
+ $this->assertTrue($this->clickImageByName('go', 10, 12));
+ $this->assertText('go_x=[10]');
+ $this->assertText('go_y=[12]');
+ }
+
+ function testImageSubmissionById() {
+ $this->get($this->samples() . 'form.html');
+ $this->assertTrue($this->clickImageById(97, 10, 12));
+ $this->assertText('go_x=[10]');
+ $this->assertText('go_y=[12]');
+ }
+
+ function testButtonSubmissionByLabel() {
+ $this->get($this->samples() . 'form.html');
+ $this->assertTrue($this->clickSubmit('Button go!', 10, 12));
+ $this->assertPattern('/go=\[ButtonGo\]/s');
+ }
+
+ function testNamelessSubmitSendsNoValue() {
+ $this->get($this->samples() . 'form_with_unnamed_submit.html');
+ $this->click('Go!');
+ $this->assertNoText('Go!');
+ $this->assertNoText('submit');
+ }
+
+ function testNamelessImageSendsXAndYValues() {
+ $this->get($this->samples() . 'form_with_unnamed_submit.html');
+ $this->clickImage('Image go!', 4, 5);
+ $this->assertNoText('ImageGo');
+ $this->assertText('x=[4]');
+ $this->assertText('y=[5]');
+ }
+
+ function testNamelessButtonSendsNoValue() {
+ $this->get($this->samples() . 'form_with_unnamed_submit.html');
+ $this->click('Button Go!');
+ $this->assertNoText('ButtonGo');
+ }
+
+ function testSelfSubmit() {
+ $this->get($this->samples() . 'self_form.php');
+ $this->assertNoText('[Submitted]');
+ $this->assertNoText('[Wrong form]');
+ $this->assertTrue($this->clickSubmit());
+ $this->assertText('[Submitted]');
+ $this->assertNoText('[Wrong form]');
+ $this->assertTitle('Test of form self submission');
+ }
+
+ function testSelfSubmitWithParameters() {
+ $this->get($this->samples() . 'self_form.php');
+ $this->setFieldByName('visible', 'Resent');
+ $this->assertTrue($this->clickSubmit());
+ $this->assertText('[Resent]');
+ }
+
+ function testSettingOfBlankOption() {
+ $this->get($this->samples() . 'form.html');
+ $this->assertTrue($this->setFieldByName('d', ''));
+ $this->clickSubmit('Go!');
+ $this->assertText('d=[]');
+ }
+
+ function testAssertingFieldValueWithPattern() {
+ $this->get($this->samples() . 'form.html');
+ $this->setField('c', 'A very long string');
+ $this->assertField('c', new PatternExpectation('/very long/'));
+ }
+
+ function testSendingMultipartFormDataEncodedForm() {
+ $this->get($this->samples() . 'form_data_encoded_form.html');
+ $this->assertField('Text A', '');
+ $this->assertField('Text B', 'Default text');
+ $this->assertField('Text area C', '');
+ $this->assertField('Selection D', 'd1');
+ $this->assertField('Checkbox E', false);
+ $this->assertField('Checkbox F', 'on');
+ $this->assertField('3', 'g3');
+ $this->assertField('Selection H', 2);
+ $this->setField('Text A', 'aaa');
+ $this->setField('Text B', 'bbb');
+ $this->setField('Text area C', 'ccc');
+ $this->setField('Selection D', 'D2');
+ $this->setField('Checkbox E', 'on');
+ $this->setField('Checkbox F', false);
+ $this->setField('2', 'g2');
+ $this->setField('Selection H', 'H1');
+ $this->assertTrue($this->clickSubmit('Go!'));
+ $this->assertText('a=[aaa]');
+ $this->assertText('b=[bbb]');
+ $this->assertText('c=[ccc]');
+ $this->assertText('d=[d2]');
+ $this->assertText('e=[on]');
+ $this->assertNoText('f=[');
+ $this->assertText('g=[g2]');
+ $this->assertText('h=[1]');
+ $this->assertText('go=[Go!]');
+ }
+
+ function testSettingVariousBlanksInFields() {
+ $this->get($this->samples() . 'form_with_false_defaults.html');
+ $this->assertField('Text A', '');
+ $this->setField('Text A', '0');
+ $this->assertField('Text A', '0');
+ $this->assertField('Text area B', '');
+ $this->setField('Text area B', '0');
+ $this->assertField('Text area B', '0');
+ $this->assertField('Text area C', " ");
+ $this->assertField('Selection D', '');
+ $this->setField('Selection D', 'D2');
+ $this->assertField('Selection D', 'D2');
+ $this->setField('Selection D', 'D3');
+ $this->assertField('Selection D', '0');
+ $this->setField('Selection D', 'D4');
+ $this->assertField('Selection D', '?');
+ $this->assertField('Checkbox E', '');
+ $this->assertField('Checkbox F', 'on');
+ $this->assertField('Checkbox G', '0');
+ $this->assertField('Checkbox H', '?');
+ $this->assertFieldByName('i', 'on');
+ $this->setFieldByName('i', '');
+ $this->assertFieldByName('i', '');
+ $this->setFieldByName('i', '0');
+ $this->assertFieldByName('i', '0');
+ $this->setFieldByName('i', '?');
+ $this->assertFieldByName('i', '?');
+ }
+
+ function testSubmissionOfBlankFields() {
+ $this->get($this->samples() . 'form_with_false_defaults.html');
+ $this->setField('Text A', '');
+ $this->setField('Text area B', '');
+ $this->setFieldByName('i', '');
+ $this->click('Go!');
+ $this->assertText('a=[]');
+ $this->assertText('b=[]');
+ $this->assertPattern('/c=\[ \]/');
+ $this->assertText('d=[]');
+ $this->assertText('e=[]');
+ $this->assertText('i=[]');
+ }
+
+ function testSubmissionOfEmptyValues() {
+ $this->get($this->samples() . 'form_with_false_defaults.html');
+ $this->setField('Selection D', 'D2');
+ $this->click('Go!');
+ $this->assertText('a=[]');
+ $this->assertText('b=[]');
+ $this->assertText('d=[D2]');
+ $this->assertText('f=[on]');
+ $this->assertText('i=[on]');
+ }
+
+ function testSubmissionOfZeroes() {
+ $this->get($this->samples() . 'form_with_false_defaults.html');
+ $this->setField('Text A', '0');
+ $this->setField('Text area B', '0');
+ $this->setField('Selection D', 'D3');
+ $this->setFieldByName('i', '0');
+ $this->click('Go!');
+ $this->assertText('a=[0]');
+ $this->assertText('b=[0]');
+ $this->assertText('d=[0]');
+ $this->assertText('g=[0]');
+ $this->assertText('i=[0]');
+ }
+
+ function testSubmissionOfQuestionMarks() {
+ $this->get($this->samples() . 'form_with_false_defaults.html');
+ $this->setField('Text A', '?');
+ $this->setField('Text area B', '?');
+ $this->setField('Selection D', 'D4');
+ $this->setFieldByName('i', '?');
+ $this->click('Go!');
+ $this->assertText('a=[?]');
+ $this->assertText('b=[?]');
+ $this->assertText('d=[?]');
+ $this->assertText('h=[?]');
+ $this->assertText('i=[?]');
+ }
+
+ function testSubmissionOfHtmlEncodedValues() {
+ $this->get($this->samples() . 'form_with_tricky_defaults.html');
+ $this->assertField('Text A', '&\'"<>');
+ $this->assertField('Text B', '"');
+ $this->assertField('Text area C', '&\'"<>');
+ $this->assertField('Selection D', "'");
+ $this->assertField('Checkbox E', '&\'"<>');
+ $this->assertField('Checkbox F', false);
+ $this->assertFieldByname('i', "'");
+ $this->click('Go!');
+ $this->assertText('a=[&\'"<>, "]');
+ $this->assertText('c=[&\'"<>]');
+ $this->assertText("d=[']");
+ $this->assertText('e=[&\'"<>]');
+ $this->assertText("i=[']");
+ }
+
+ function testFormActionRespectsBaseTag() {
+ $this->get($this->samples() . 'base_tag/form.html');
+ $this->assertTrue($this->clickSubmit('Go!'));
+ $this->assertText('go=[Go!]');
+ $this->assertText('a=[]');
+ }
+}
+
+class TestOfLiveMultiValueWidgets extends SimpleTestAcceptanceTest {
+ function setUp() {
+ $this->addHeader('User-Agent: SimpleTest ' . SimpleTest::getVersion());
+ }
+
+ function testDefaultFormValueSubmission() {
+ $this->get($this->samples() . 'multiple_widget_form.html');
+ $this->assertFieldByName('a', array('a2', 'a3'));
+ $this->assertFieldByName('b', array('b2', 'b3'));
+ $this->assertFieldByName('c[]', array('c2', 'c3'));
+ $this->assertFieldByName('d', array('2', '3'));
+ $this->assertFieldByName('e', array('2', '3'));
+ $this->assertTrue($this->clickSubmit('Go!'));
+ $this->assertText('a=[a2, a3]');
+ $this->assertText('b=[b2, b3]');
+ $this->assertText('c=[c2, c3]');
+ $this->assertText('d=[2, 3]');
+ $this->assertText('e=[2, 3]');
+ }
+
+ function testSubmittingMultipleValues() {
+ $this->get($this->samples() . 'multiple_widget_form.html');
+ $this->setFieldByName('a', array('a1', 'a4'));
+ $this->assertFieldByName('a', array('a1', 'a4'));
+ $this->assertFieldByName('a', array('a4', 'a1'));
+ $this->setFieldByName('b', array('b1', 'b4'));
+ $this->assertFieldByName('b', array('b1', 'b4'));
+ $this->setFieldByName('c[]', array('c1', 'c4'));
+ $this->assertField('c[]', array('c1', 'c4'));
+ $this->setFieldByName('d', array('1', '4'));
+ $this->assertField('d', array('1', '4'));
+ $this->setFieldByName('e', array('e1', 'e4'));
+ $this->assertField('e', array('1', '4'));
+ $this->assertTrue($this->clickSubmit('Go!'));
+ $this->assertText('a=[a1, a4]');
+ $this->assertText('b=[b1, b4]');
+ $this->assertText('c=[c1, c4]');
+ $this->assertText('d=[1, 4]');
+ $this->assertText('e=[1, 4]');
+ }
+
+ function testSettingByOptionValue() {
+ $this->get($this->samples() . 'multiple_widget_form.html');
+ $this->setFieldByName('d', array('1', '4'));
+ $this->assertField('d', array('1', '4'));
+ $this->assertTrue($this->clickSubmit('Go!'));
+ $this->assertText('d=[1, 4]');
+ }
+
+ function testSubmittingMultipleValuesByLabel() {
+ $this->get($this->samples() . 'multiple_widget_form.html');
+ $this->setField('Multiple selection A', array('a1', 'a4'));
+ $this->assertField('Multiple selection A', array('a1', 'a4'));
+ $this->assertField('Multiple selection A', array('a4', 'a1'));
+ $this->setField('multiple selection C', array('c1', 'c4'));
+ $this->assertField('multiple selection C', array('c1', 'c4'));
+ $this->assertTrue($this->clickSubmit('Go!'));
+ $this->assertText('a=[a1, a4]');
+ $this->assertText('c=[c1, c4]');
+ }
+
+ function testSavantStyleHiddenFieldDefaults() {
+ $this->get($this->samples() . 'savant_style_form.html');
+ $this->assertFieldByName('a', array('a0'));
+ $this->assertFieldByName('b', array('b0'));
+ $this->assertTrue($this->clickSubmit('Go!'));
+ $this->assertText('a=[a0]');
+ $this->assertText('b=[b0]');
+ }
+
+ function testSavantStyleHiddenDefaultsAreOverridden() {
+ $this->get($this->samples() . 'savant_style_form.html');
+ $this->assertTrue($this->setFieldByName('a', array('a1')));
+ $this->assertTrue($this->setFieldByName('b', 'b1'));
+ $this->assertTrue($this->clickSubmit('Go!'));
+ $this->assertText('a=[a1]');
+ $this->assertText('b=[b1]');
+ }
+
+ function testSavantStyleFormSettingById() {
+ $this->get($this->samples() . 'savant_style_form.html');
+ $this->assertFieldById(1, array('a0'));
+ $this->assertFieldById(4, array('b0'));
+ $this->assertTrue($this->setFieldById(2, 'a1'));
+ $this->assertTrue($this->setFieldById(5, 'b1'));
+ $this->assertTrue($this->clickSubmitById(99));
+ $this->assertText('a=[a1]');
+ $this->assertText('b=[b1]');
+ }
+}
+
+class TestOfFileUploads extends SimpleTestAcceptanceTest {
+ function setUp() {
+ $this->addHeader('User-Agent: SimpleTest ' . SimpleTest::getVersion());
+ }
+
+ function testSingleFileUpload() {
+ $this->get($this->samples() . 'upload_form.html');
+ $this->assertTrue($this->setField('Content:',
+ dirname(__FILE__) . '/support/upload_sample.txt'));
+ $this->assertField('Content:', dirname(__FILE__) . '/support/upload_sample.txt');
+ $this->click('Go!');
+ $this->assertText('Sample for testing file upload');
+ }
+
+ function testMultipleFileUpload() {
+ $this->get($this->samples() . 'upload_form.html');
+ $this->assertTrue($this->setField('Content:',
+ dirname(__FILE__) . '/support/upload_sample.txt'));
+ $this->assertTrue($this->setField('Supplemental:',
+ dirname(__FILE__) . '/support/supplementary_upload_sample.txt'));
+ $this->assertField('Supplemental:',
+ dirname(__FILE__) . '/support/supplementary_upload_sample.txt');
+ $this->click('Go!');
+ $this->assertText('Sample for testing file upload');
+ $this->assertText('Some more text content');
+ }
+
+ function testBinaryFileUpload() {
+ $this->get($this->samples() . 'upload_form.html');
+ $this->assertTrue($this->setField('Content:',
+ dirname(__FILE__) . '/support/latin1_sample'));
+ $this->click('Go!');
+ $this->assertText(
+ implode('', file(dirname(__FILE__) . '/support/latin1_sample')));
+ }
+}
+
+class TestOfLiveHistoryNavigation extends SimpleTestAcceptanceTest {
+ function setUp() {
+ $this->addHeader('User-Agent: SimpleTest ' . SimpleTest::getVersion());
+ }
+
+ function testRetry() {
+ $this->get($this->samples() . 'cookie_based_counter.php');
+ $this->assertPattern('/count: 1/i');
+ $this->retry();
+ $this->assertPattern('/count: 2/i');
+ $this->retry();
+ $this->assertPattern('/count: 3/i');
+ }
+
+ function testOfBackButton() {
+ $this->get($this->samples() . '1.html');
+ $this->clickLink('2');
+ $this->assertTitle('2');
+ $this->assertTrue($this->back());
+ $this->assertTitle('1');
+ $this->assertTrue($this->forward());
+ $this->assertTitle('2');
+ $this->assertFalse($this->forward());
+ }
+
+ function testGetRetryResubmitsData() {
+ $this->assertTrue($this->get(
+ $this->samples() . 'network_confirm.php?a=aaa'));
+ $this->assertPattern('/Request method.*?<dd>GET<\/dd>/');
+ $this->assertText('a=[aaa]');
+ $this->retry();
+ $this->assertPattern('/Request method.*?<dd>GET<\/dd>/');
+ $this->assertText('a=[aaa]');
+ }
+
+ function testGetRetryResubmitsExtraData() {
+ $this->assertTrue($this->get(
+ $this->samples() . 'network_confirm.php',
+ array('a' => 'aaa')));
+ $this->assertPattern('/Request method.*?<dd>GET<\/dd>/');
+ $this->assertText('a=[aaa]');
+ $this->retry();
+ $this->assertPattern('/Request method.*?<dd>GET<\/dd>/');
+ $this->assertText('a=[aaa]');
+ }
+
+ function testPostRetryResubmitsData() {
+ $this->assertTrue($this->post(
+ $this->samples() . 'network_confirm.php',
+ array('a' => 'aaa')));
+ $this->assertPattern('/Request method.*?<dd>POST<\/dd>/');
+ $this->assertText('a=[aaa]');
+ $this->retry();
+ $this->assertPattern('/Request method.*?<dd>POST<\/dd>/');
+ $this->assertText('a=[aaa]');
+ }
+
+ function testGetRetryResubmitsRepeatedData() {
+ $this->assertTrue($this->get(
+ $this->samples() . 'network_confirm.php?a=1&a=2'));
+ $this->assertPattern('/Request method.*?<dd>GET<\/dd>/');
+ $this->assertText('a=[1, 2]');
+ $this->retry();
+ $this->assertPattern('/Request method.*?<dd>GET<\/dd>/');
+ $this->assertText('a=[1, 2]');
+ }
+}
+
+class TestOfLiveAuthentication extends SimpleTestAcceptanceTest {
+ function setUp() {
+ $this->addHeader('User-Agent: SimpleTest ' . SimpleTest::getVersion());
+ }
+
+ function testChallengeFromProtectedPage() {
+ $this->get($this->samples() . 'protected/');
+ $this->assertResponse(401);
+ $this->assertAuthentication('Basic');
+ $this->assertRealm('SimpleTest basic authentication');
+ $this->assertRealm(new PatternExpectation('/simpletest/i'));
+ $this->authenticate('test', 'secret');
+ $this->assertResponse(200);
+ $this->retry();
+ $this->assertResponse(200);
+ }
+
+ function testTrailingSlashImpliedWithinRealm() {
+ $this->get($this->samples() . 'protected/');
+ $this->authenticate('test', 'secret');
+ $this->assertResponse(200);
+ $this->get($this->samples() . 'protected');
+ $this->assertResponse(200);
+ }
+
+ function testTrailingSlashImpliedSettingRealm() {
+ $this->get($this->samples() . 'protected');
+ $this->authenticate('test', 'secret');
+ $this->assertResponse(200);
+ $this->get($this->samples() . 'protected/');
+ $this->assertResponse(200);
+ }
+
+ function testEncodedAuthenticationFetchesPage() {
+ $this->get('http://test:secret@www.lastcraft.com/test/protected/');
+ $this->assertResponse(200);
+ }
+
+ function testEncodedAuthenticationFetchesPageAfterTrailingSlashRedirect() {
+ $this->get('http://test:secret@www.lastcraft.com/test/protected');
+ $this->assertResponse(200);
+ }
+
+ function testRealmExtendsToWholeDirectory() {
+ $this->get($this->samples() . 'protected/1.html');
+ $this->authenticate('test', 'secret');
+ $this->clickLink('2');
+ $this->assertResponse(200);
+ $this->clickLink('3');
+ $this->assertResponse(200);
+ }
+
+ function testRedirectKeepsAuthentication() {
+ $this->get($this->samples() . 'protected/local_redirect.php');
+ $this->authenticate('test', 'secret');
+ $this->assertTitle('Simple test target file');
+ }
+
+ function testRedirectKeepsEncodedAuthentication() {
+ $this->get('http://test:secret@www.lastcraft.com/test/protected/local_redirect.php');
+ $this->assertResponse(200);
+ $this->assertTitle('Simple test target file');
+ }
+
+ function testSessionRestartLosesAuthentication() {
+ $this->get($this->samples() . 'protected/');
+ $this->authenticate('test', 'secret');
+ $this->assertResponse(200);
+ $this->restart();
+ $this->get($this->samples() . 'protected/');
+ $this->assertResponse(401);
+ }
+}
+
+class TestOfLoadingFrames extends SimpleTestAcceptanceTest {
+ function setUp() {
+ $this->addHeader('User-Agent: SimpleTest ' . SimpleTest::getVersion());
+ }
+
+ function testNoFramesContentWhenFramesDisabled() {
+ $this->ignoreFrames();
+ $this->get($this->samples() . 'one_page_frameset.html');
+ $this->assertTitle('Frameset for testing of SimpleTest');
+ $this->assertText('This content is for no frames only');
+ }
+
+ function testPatternMatchCanReadTheOnlyFrame() {
+ $this->get($this->samples() . 'one_page_frameset.html');
+ $this->assertText('A target for the SimpleTest test suite');
+ $this->assertNoText('This content is for no frames only');
+ }
+
+ function testMessyFramesetResponsesByName() {
+ $this->assertTrue($this->get(
+ $this->samples() . 'messy_frameset.html'));
+ $this->assertTitle('Frameset for testing of SimpleTest');
+
+ $this->assertTrue($this->setFrameFocus('Front controller'));
+ $this->assertResponse(200);
+ $this->assertText('Simple test front controller');
+
+ $this->assertTrue($this->setFrameFocus('One'));
+ $this->assertResponse(200);
+ $this->assertLink('2');
+
+ $this->assertTrue($this->setFrameFocus('Frame links'));
+ $this->assertResponse(200);
+ $this->assertLink('Set one to 2');
+
+ $this->assertTrue($this->setFrameFocus('Counter'));
+ $this->assertResponse(200);
+ $this->assertText('Count: 1');
+
+ $this->assertTrue($this->setFrameFocus('Redirected'));
+ $this->assertResponse(200);
+ $this->assertText('r=rrr');
+
+ $this->assertTrue($this->setFrameFocus('Protected'));
+ $this->assertResponse(401);
+
+ $this->assertTrue($this->setFrameFocus('Protected redirect'));
+ $this->assertResponse(401);
+
+ $this->assertTrue($this->setFrameFocusByIndex(1));
+ $this->assertResponse(200);
+ $this->assertText('Simple test front controller');
+
+ $this->assertTrue($this->setFrameFocusByIndex(2));
+ $this->assertResponse(200);
+ $this->assertLink('2');
+
+ $this->assertTrue($this->setFrameFocusByIndex(3));
+ $this->assertResponse(200);
+ $this->assertLink('Set one to 2');
+
+ $this->assertTrue($this->setFrameFocusByIndex(4));
+ $this->assertResponse(200);
+ $this->assertText('Count: 1');
+
+ $this->assertTrue($this->setFrameFocusByIndex(5));
+ $this->assertResponse(200);
+ $this->assertText('r=rrr');
+
+ $this->assertTrue($this->setFrameFocusByIndex(6));
+ $this->assertResponse(401);
+
+ $this->assertTrue($this->setFrameFocusByIndex(7));
+ }
+
+ function testReloadingFramesetPage() {
+ $this->get($this->samples() . 'messy_frameset.html');
+ $this->assertText('Count: 1');
+ $this->retry();
+ $this->assertText('Count: 2');
+ $this->retry();
+ $this->assertText('Count: 3');
+ }
+
+ function testReloadingSingleFrameWithCookieCounter() {
+ $this->get($this->samples() . 'counting_frameset.html');
+ $this->setFrameFocus('a');
+ $this->assertText('Count: 1');
+ $this->setFrameFocus('b');
+ $this->assertText('Count: 2');
+
+ $this->setFrameFocus('a');
+ $this->retry();
+ $this->assertText('Count: 3');
+ $this->retry();
+ $this->assertText('Count: 4');
+ $this->setFrameFocus('b');
+ $this->assertText('Count: 2');
+ }
+
+ function testReloadingFrameWhenUnfocusedReloadsWholeFrameset() {
+ $this->get($this->samples() . 'counting_frameset.html');
+ $this->setFrameFocus('a');
+ $this->assertText('Count: 1');
+ $this->setFrameFocus('b');
+ $this->assertText('Count: 2');
+
+ $this->clearFrameFocus('a');
+ $this->retry();
+
+ $this->assertTitle('Frameset for testing of SimpleTest');
+ $this->setFrameFocus('a');
+ $this->assertText('Count: 3');
+ $this->setFrameFocus('b');
+ $this->assertText('Count: 4');
+ }
+
+ function testClickingNormalLinkReplacesJustThatFrame() {
+ $this->get($this->samples() . 'messy_frameset.html');
+ $this->clickLink('2');
+ $this->assertLink('3');
+ $this->assertText('Simple test front controller');
+ }
+
+ function testJumpToNamedPageReplacesJustThatFrame() {
+ $this->get($this->samples() . 'messy_frameset.html');
+ $this->assertPattern('/Simple test front controller/');
+ $this->clickLink('Index');
+ $this->assertResponse(200);
+ $this->assertText('[action=index]');
+ $this->assertText('Count: 1');
+ }
+
+ function testJumpToUnnamedPageReplacesJustThatFrame() {
+ $this->get($this->samples() . 'messy_frameset.html');
+ $this->clickLink('No page');
+ $this->assertResponse(200);
+ $this->assertText('Simple test front controller');
+ $this->assertText('[action=no_page]');
+ $this->assertText('Count: 1');
+ }
+
+ function testJumpToUnnamedPageWithBareParameterReplacesJustThatFrame() {
+ $this->get($this->samples() . 'messy_frameset.html');
+ $this->clickLink('Bare action');
+ $this->assertResponse(200);
+ $this->assertText('Simple test front controller');
+ $this->assertText('[action=]');
+ $this->assertText('Count: 1');
+ }
+
+ function testJumpToUnnamedPageWithEmptyQueryReplacesJustThatFrame() {
+ $this->get($this->samples() . 'messy_frameset.html');
+ $this->clickLink('Empty query');
+ $this->assertResponse(200);
+ $this->assertPattern('/Simple test front controller/');
+ $this->assertPattern('/raw get data.*?\[\].*?get data/si');
+ $this->assertPattern('/Count: 1/');
+ }
+
+ function testJumpToUnnamedPageWithEmptyLinkReplacesJustThatFrame() {
+ $this->get($this->samples() . 'messy_frameset.html');
+ $this->clickLink('Empty link');
+ $this->assertResponse(200);
+ $this->assertPattern('/Simple test front controller/');
+ $this->assertPattern('/raw get data.*?\[\].*?get data/si');
+ $this->assertPattern('/Count: 1/');
+ }
+
+ function testJumpBackADirectoryLevelReplacesJustThatFrame() {
+ $this->get($this->samples() . 'messy_frameset.html');
+ $this->clickLink('Down one');
+ $this->assertPattern('/index of .*\/test/i');
+ $this->assertPattern('/Count: 1/');
+ }
+
+ function testSubmitToNamedPageReplacesJustThatFrame() {
+ $this->get($this->samples() . 'messy_frameset.html');
+ $this->assertPattern('/Simple test front controller/');
+ $this->clickSubmit('Index');
+ $this->assertResponse(200);
+ $this->assertText('[action=Index]');
+ $this->assertText('Count: 1');
+ }
+
+ function testSubmitToSameDirectoryReplacesJustThatFrame() {
+ $this->get($this->samples() . 'messy_frameset.html');
+ $this->clickSubmit('Same directory');
+ $this->assertResponse(200);
+ $this->assertText('[action=Same+directory]');
+ $this->assertText('Count: 1');
+ }
+
+ function testSubmitToEmptyActionReplacesJustThatFrame() {
+ $this->get($this->samples() . 'messy_frameset.html');
+ $this->clickSubmit('Empty action');
+ $this->assertResponse(200);
+ $this->assertText('[action=Empty+action]');
+ $this->assertText('Count: 1');
+ }
+
+ function testSubmitToNoActionReplacesJustThatFrame() {
+ $this->get($this->samples() . 'messy_frameset.html');
+ $this->clickSubmit('No action');
+ $this->assertResponse(200);
+ $this->assertText('[action=No+action]');
+ $this->assertText('Count: 1');
+ }
+
+ function testSubmitBackADirectoryLevelReplacesJustThatFrame() {
+ $this->get($this->samples() . 'messy_frameset.html');
+ $this->clickSubmit('Down one');
+ $this->assertPattern('/index of .*\/test/i');
+ $this->assertPattern('/Count: 1/');
+ }
+
+ function testTopLinkExitsFrameset() {
+ $this->get($this->samples() . 'messy_frameset.html');
+ $this->clickLink('Exit the frameset');
+ $this->assertTitle('Simple test target file');
+ }
+
+ function testLinkInOnePageCanLoadAnother() {
+ $this->get($this->samples() . 'messy_frameset.html');
+ $this->assertNoLink('3');
+ $this->clickLink('Set one to 2');
+ $this->assertLink('3');
+ $this->assertNoLink('2');
+ $this->assertTitle('Frameset for testing of SimpleTest');
+ }
+
+ function testFrameWithRelativeLinksRespectsBaseTagForThatPage() {
+ $this->get($this->samples() . 'base_tag/frameset.html');
+ $this->click('Back to test pages');
+ $this->assertTitle('Frameset for testing of SimpleTest');
+ $this->assertText('A target for the SimpleTest test suite');
+ }
+
+ function testRelativeLinkInFrameIsNotAffectedByFramesetBaseTag() {
+ $this->get($this->samples() . 'base_tag/frameset_with_base_tag.html');
+ $this->assertText('This is page 1');
+ $this->click('To page 2');
+ $this->assertTitle('Frameset for testing of SimpleTest');
+ $this->assertText('This is page 2');
+ }
+}
+
+class TestOfFrameAuthentication extends SimpleTestAcceptanceTest {
+ function setUp() {
+ $this->addHeader('User-Agent: SimpleTest ' . SimpleTest::getVersion());
+ }
+
+ function testUnauthenticatedFrameSendsChallenge() {
+ $this->get($this->samples() . 'protected/');
+ $this->setFrameFocus('Protected');
+ $this->assertAuthentication('Basic');
+ $this->assertRealm('SimpleTest basic authentication');
+ $this->assertResponse(401);
+ }
+
+ function testCanReadFrameFromAlreadyAuthenticatedRealm() {
+ $this->get($this->samples() . 'protected/');
+ $this->authenticate('test', 'secret');
+ $this->get($this->samples() . 'messy_frameset.html');
+ $this->setFrameFocus('Protected');
+ $this->assertResponse(200);
+ $this->assertText('A target for the SimpleTest test suite');
+ }
+
+ function testCanAuthenticateFrame() {
+ $this->get($this->samples() . 'messy_frameset.html');
+ $this->setFrameFocus('Protected');
+ $this->authenticate('test', 'secret');
+ $this->assertResponse(200);
+ $this->assertText('A target for the SimpleTest test suite');
+ $this->clearFrameFocus();
+ $this->assertText('Count: 1');
+ }
+
+ function testCanAuthenticateRedirectedFrame() {
+ $this->get($this->samples() . 'messy_frameset.html');
+ $this->setFrameFocus('Protected redirect');
+ $this->assertResponse(401);
+ $this->authenticate('test', 'secret');
+ $this->assertResponse(200);
+ $this->assertText('A target for the SimpleTest test suite');
+ $this->clearFrameFocus();
+ $this->assertText('Count: 1');
+ }
+}
+
+class TestOfNestedFrames extends SimpleTestAcceptanceTest {
+ function setUp() {
+ $this->addHeader('User-Agent: SimpleTest ' . SimpleTest::getVersion());
+ }
+
+ function testCanNavigateToSpecificContent() {
+ $this->get($this->samples() . 'nested_frameset.html');
+ $this->assertTitle('Nested frameset for testing of SimpleTest');
+
+ $this->assertPattern('/This is frame A/');
+ $this->assertPattern('/This is frame B/');
+ $this->assertPattern('/Simple test front controller/');
+ $this->assertLink('2');
+ $this->assertLink('Set one to 2');
+ $this->assertPattern('/Count: 1/');
+ $this->assertPattern('/r=rrr/');
+
+ $this->setFrameFocus('pair');
+ $this->assertPattern('/This is frame A/');
+ $this->assertPattern('/This is frame B/');
+ $this->assertNoPattern('/Simple test front controller/');
+ $this->assertNoLink('2');
+
+ $this->setFrameFocus('aaa');
+ $this->assertPattern('/This is frame A/');
+ $this->assertNoPattern('/This is frame B/');
+
+ $this->clearFrameFocus();
+ $this->assertResponse(200);
+ $this->setFrameFocus('messy');
+ $this->assertResponse(200);
+ $this->setFrameFocus('Front controller');
+ $this->assertResponse(200);
+ $this->assertPattern('/Simple test front controller/');
+ $this->assertNoLink('2');
+ }
+
+ function testReloadingFramesetPage() {
+ $this->get($this->samples() . 'nested_frameset.html');
+ $this->assertPattern('/Count: 1/');
+ $this->retry();
+ $this->assertPattern('/Count: 2/');
+ $this->retry();
+ $this->assertPattern('/Count: 3/');
+ }
+
+ function testRetryingNestedPageOnlyRetriesThatSet() {
+ $this->get($this->samples() . 'nested_frameset.html');
+ $this->assertPattern('/Count: 1/');
+ $this->setFrameFocus('messy');
+ $this->retry();
+ $this->assertPattern('/Count: 2/');
+ $this->setFrameFocus('Counter');
+ $this->retry();
+ $this->assertPattern('/Count: 3/');
+
+ $this->clearFrameFocus();
+ $this->setFrameFocus('messy');
+ $this->setFrameFocus('Front controller');
+ $this->retry();
+
+ $this->clearFrameFocus();
+ $this->assertPattern('/Count: 3/');
+ }
+
+ function testAuthenticatingNestedPage() {
+ $this->get($this->samples() . 'nested_frameset.html');
+ $this->setFrameFocus('messy');
+ $this->setFrameFocus('Protected');
+ $this->assertAuthentication('Basic');
+ $this->assertRealm('SimpleTest basic authentication');
+ $this->assertResponse(401);
+
+ $this->authenticate('test', 'secret');
+ $this->assertResponse(200);
+ $this->assertPattern('/A target for the SimpleTest test suite/');
+ }
+}
+?> \ No newline at end of file
diff --git a/site/vendors/simpletest/test/adapter_test.php b/site/vendors/simpletest/test/adapter_test.php
new file mode 100644
index 0000000..f4564ea
--- /dev/null
+++ b/site/vendors/simpletest/test/adapter_test.php
@@ -0,0 +1,77 @@
+<?php
+// $Id: adapter_test.php 1505 2007-04-30 23:39:59Z lastcraft $
+require_once(dirname(__FILE__) . '/../autorun.php');
+require_once(dirname(__FILE__) . '/../extensions/pear_test_case.php');
+require_once(dirname(__FILE__) . '/../extensions/phpunit_test_case.php');
+
+class SameTestClass {
+}
+
+class TestOfPearAdapter extends PHPUnit_TestCase {
+
+ function testBoolean() {
+ $this->assertTrue(true, "PEAR true");
+ $this->assertFalse(false, "PEAR false");
+ }
+
+ function testName() {
+ $this->assertTrue($this->getName() == get_class($this));
+ }
+
+ function testPass() {
+ $this->pass("PEAR pass");
+ }
+
+ function testNulls() {
+ $value = null;
+ $this->assertNull($value, "PEAR null");
+ $value = 0;
+ $this->assertNotNull($value, "PEAR not null");
+ }
+
+ function testType() {
+ $this->assertType("Hello", "string", "PEAR type");
+ }
+
+ function testEquals() {
+ $this->assertEquals(12, 12, "PEAR identity");
+ $this->setLooselyTyped(true);
+ $this->assertEquals("12", 12, "PEAR equality");
+ }
+
+ function testSame() {
+ $same = &new SameTestClass();
+ $this->assertSame($same, $same, "PEAR same");
+ }
+
+ function testRegExp() {
+ $this->assertRegExp('/hello/', "A big hello from me", "PEAR regex");
+ }
+}
+
+class TestOfPhpUnitAdapter extends TestCase {
+ function TestOfPhpUnitAdapter() {
+ $this->TestCase('TestOfPhpUnitAdapter');
+ }
+
+ function testBoolean() {
+ $this->assert(true, 'PHP Unit true');
+ }
+
+ function testName() {
+ $this->assert($this->name() == 'TestOfPhpUnitAdapter');
+ }
+
+ function testEquals() {
+ $this->assertEquals(12, 12, 'PHP Unit equality');
+ }
+
+ function testMultilineEquals() {
+ $this->assertEquals("a\nb\n", "a\nb\n", 'PHP Unit equality');
+ }
+
+ function testRegExp() {
+ $this->assertRegexp('/hello/', 'A big hello from me', 'PHPUnit regex');
+ }
+}
+?> \ No newline at end of file
diff --git a/site/vendors/simpletest/test/all_tests.php b/site/vendors/simpletest/test/all_tests.php
new file mode 100644
index 0000000..99ce945
--- /dev/null
+++ b/site/vendors/simpletest/test/all_tests.php
@@ -0,0 +1,13 @@
+<?php
+require_once(dirname(__FILE__) . '/../autorun.php');
+
+class AllTests extends TestSuite {
+ function AllTests() {
+ $this->TestSuite('All tests for SimpleTest ' . SimpleTest::getVersion());
+ $this->addFile(dirname(__FILE__) . '/unit_tests.php');
+ $this->addFile(dirname(__FILE__) . '/shell_test.php');
+ $this->addFile(dirname(__FILE__) . '/live_test.php');
+ $this->addFile(dirname(__FILE__) . '/acceptance_test.php');
+ }
+}
+?> \ No newline at end of file
diff --git a/site/vendors/simpletest/test/authentication_test.php b/site/vendors/simpletest/test/authentication_test.php
new file mode 100644
index 0000000..8573edd
--- /dev/null
+++ b/site/vendors/simpletest/test/authentication_test.php
@@ -0,0 +1,145 @@
+<?php
+// $Id: authentication_test.php 1505 2007-04-30 23:39:59Z lastcraft $
+require_once(dirname(__FILE__) . '/../autorun.php');
+require_once(dirname(__FILE__) . '/../authentication.php');
+require_once(dirname(__FILE__) . '/../http.php');
+Mock::generate('SimpleHttpRequest');
+
+class TestOfRealm extends UnitTestCase {
+
+ function testWithinSameUrl() {
+ $realm = &new SimpleRealm(
+ 'Basic',
+ new SimpleUrl('http://www.here.com/path/hello.html'));
+ $this->assertTrue($realm->isWithin(
+ new SimpleUrl('http://www.here.com/path/hello.html')));
+ }
+
+ function testInsideWithLongerUrl() {
+ $realm = &new SimpleRealm(
+ 'Basic',
+ new SimpleUrl('http://www.here.com/path/'));
+ $this->assertTrue($realm->isWithin(
+ new SimpleUrl('http://www.here.com/path/hello.html')));
+ }
+
+ function testBelowRootIsOutside() {
+ $realm = &new SimpleRealm(
+ 'Basic',
+ new SimpleUrl('http://www.here.com/path/'));
+ $this->assertTrue($realm->isWithin(
+ new SimpleUrl('http://www.here.com/path/more/hello.html')));
+ }
+
+ function testOldNetscapeDefinitionIsOutside() {
+ $realm = &new SimpleRealm(
+ 'Basic',
+ new SimpleUrl('http://www.here.com/path/'));
+ $this->assertFalse($realm->isWithin(
+ new SimpleUrl('http://www.here.com/pathmore/hello.html')));
+ }
+
+ function testInsideWithMissingTrailingSlash() {
+ $realm = &new SimpleRealm(
+ 'Basic',
+ new SimpleUrl('http://www.here.com/path/'));
+ $this->assertTrue($realm->isWithin(
+ new SimpleUrl('http://www.here.com/path')));
+ }
+
+ function testDifferentPageNameStillInside() {
+ $realm = &new SimpleRealm(
+ 'Basic',
+ new SimpleUrl('http://www.here.com/path/hello.html'));
+ $this->assertTrue($realm->isWithin(
+ new SimpleUrl('http://www.here.com/path/goodbye.html')));
+ }
+
+ function testNewUrlInSameDirectoryDoesNotChangeRealm() {
+ $realm = &new SimpleRealm(
+ 'Basic',
+ new SimpleUrl('http://www.here.com/path/hello.html'));
+ $realm->stretch(new SimpleUrl('http://www.here.com/path/goodbye.html'));
+ $this->assertTrue($realm->isWithin(
+ new SimpleUrl('http://www.here.com/path/index.html')));
+ $this->assertFalse($realm->isWithin(
+ new SimpleUrl('http://www.here.com/index.html')));
+ }
+
+ function testNewUrlMakesRealmTheCommonPath() {
+ $realm = &new SimpleRealm(
+ 'Basic',
+ new SimpleUrl('http://www.here.com/path/here/hello.html'));
+ $realm->stretch(new SimpleUrl('http://www.here.com/path/there/goodbye.html'));
+ $this->assertTrue($realm->isWithin(
+ new SimpleUrl('http://www.here.com/path/here/index.html')));
+ $this->assertTrue($realm->isWithin(
+ new SimpleUrl('http://www.here.com/path/there/index.html')));
+ $this->assertTrue($realm->isWithin(
+ new SimpleUrl('http://www.here.com/path/index.html')));
+ $this->assertFalse($realm->isWithin(
+ new SimpleUrl('http://www.here.com/index.html')));
+ $this->assertFalse($realm->isWithin(
+ new SimpleUrl('http://www.here.com/paths/index.html')));
+ $this->assertFalse($realm->isWithin(
+ new SimpleUrl('http://www.here.com/pathindex.html')));
+ }
+}
+
+class TestOfAuthenticator extends UnitTestCase {
+
+ function testNoRealms() {
+ $request = &new MockSimpleHttpRequest();
+ $request->expectNever('addHeaderLine');
+ $authenticator = &new SimpleAuthenticator();
+ $authenticator->addHeaders($request, new SimpleUrl('http://here.com/'));
+ }
+
+ function &createSingleRealm() {
+ $authenticator = &new SimpleAuthenticator();
+ $authenticator->addRealm(
+ new SimpleUrl('http://www.here.com/path/hello.html'),
+ 'Basic',
+ 'Sanctuary');
+ $authenticator->setIdentityForRealm('www.here.com', 'Sanctuary', 'test', 'secret');
+ return $authenticator;
+ }
+
+ function testOutsideRealm() {
+ $request = &new MockSimpleHttpRequest();
+ $request->expectNever('addHeaderLine');
+ $authenticator = &$this->createSingleRealm();
+ $authenticator->addHeaders(
+ $request,
+ new SimpleUrl('http://www.here.com/hello.html'));
+ }
+
+ function testWithinRealm() {
+ $request = &new MockSimpleHttpRequest();
+ $request->expectOnce('addHeaderLine');
+ $authenticator = &$this->createSingleRealm();
+ $authenticator->addHeaders(
+ $request,
+ new SimpleUrl('http://www.here.com/path/more/hello.html'));
+ }
+
+ function testRestartingClearsRealm() {
+ $request = &new MockSimpleHttpRequest();
+ $request->expectNever('addHeaderLine');
+ $authenticator = &$this->createSingleRealm();
+ $authenticator->restartSession();
+ $authenticator->addHeaders(
+ $request,
+ new SimpleUrl('http://www.here.com/hello.html'));
+ }
+
+ function testDifferentHostIsOutsideRealm() {
+ $request = &new MockSimpleHttpRequest();
+ $request->expectNever('addHeaderLine');
+ $authenticator = &$this->createSingleRealm();
+ $authenticator->addHeaders(
+ $request,
+ new SimpleUrl('http://here.com/path/hello.html'));
+ }
+}
+?> \ No newline at end of file
diff --git a/site/vendors/simpletest/test/autorun_test.php b/site/vendors/simpletest/test/autorun_test.php
new file mode 100644
index 0000000..76c919d
--- /dev/null
+++ b/site/vendors/simpletest/test/autorun_test.php
@@ -0,0 +1,13 @@
+<?php
+require_once(dirname(__FILE__) . '/../autorun.php');
+require_once(dirname(__FILE__) . '/support/test1.php');
+
+class LoadIfIncludedTestCase extends UnitTestCase {
+ function test_load_if_included() {
+ $tests = new GroupTest();
+ $tests->addFile(dirname(__FILE__) . '/support/test1.php');
+ $this->assertEqual($tests->getSize(), 1);
+ }
+}
+
+?> \ No newline at end of file
diff --git a/site/vendors/simpletest/test/bad_test_suite.php b/site/vendors/simpletest/test/bad_test_suite.php
new file mode 100644
index 0000000..b426013
--- /dev/null
+++ b/site/vendors/simpletest/test/bad_test_suite.php
@@ -0,0 +1,10 @@
+<?php
+require_once(dirname(__FILE__) . '/../autorun.php');
+
+class BadTestCases extends TestSuite {
+ function BadTestCases() {
+ $this->TestSuite('Two bad test cases');
+ $this->addFile(dirname(__FILE__) . '/support/empty_test_file.php');
+ }
+}
+?> \ No newline at end of file
diff --git a/site/vendors/simpletest/test/browser_test.php b/site/vendors/simpletest/test/browser_test.php
new file mode 100644
index 0000000..18faee8
--- /dev/null
+++ b/site/vendors/simpletest/test/browser_test.php
@@ -0,0 +1,779 @@
+<?php
+// $Id: browser_test.php 1624 2008-01-01 15:00:43Z pp11 $
+require_once(dirname(__FILE__) . '/../autorun.php');
+require_once(dirname(__FILE__) . '/../browser.php');
+require_once(dirname(__FILE__) . '/../user_agent.php');
+require_once(dirname(__FILE__) . '/../http.php');
+require_once(dirname(__FILE__) . '/../page.php');
+require_once(dirname(__FILE__) . '/../encoding.php');
+
+Mock::generate('SimpleHttpResponse');
+Mock::generate('SimplePage');
+Mock::generate('SimpleForm');
+Mock::generate('SimpleUserAgent');
+Mock::generatePartial(
+ 'SimpleBrowser',
+ 'MockParseSimpleBrowser',
+ array('_createUserAgent', '_parse'));
+Mock::generatePartial(
+ 'SimpleBrowser',
+ 'MockUserAgentSimpleBrowser',
+ array('_createUserAgent'));
+
+class TestOfHistory extends UnitTestCase {
+
+ function testEmptyHistoryHasFalseContents() {
+ $history = &new SimpleBrowserHistory();
+ $this->assertIdentical($history->getUrl(), false);
+ $this->assertIdentical($history->getParameters(), false);
+ }
+
+ function testCannotMoveInEmptyHistory() {
+ $history = &new SimpleBrowserHistory();
+ $this->assertFalse($history->back());
+ $this->assertFalse($history->forward());
+ }
+
+ function testCurrentTargetAccessors() {
+ $history = &new SimpleBrowserHistory();
+ $history->recordEntry(
+ new SimpleUrl('http://www.here.com/'),
+ new SimpleGetEncoding());
+ $this->assertIdentical($history->getUrl(), new SimpleUrl('http://www.here.com/'));
+ $this->assertIdentical($history->getParameters(), new SimpleGetEncoding());
+ }
+
+ function testSecondEntryAccessors() {
+ $history = &new SimpleBrowserHistory();
+ $history->recordEntry(
+ new SimpleUrl('http://www.first.com/'),
+ new SimpleGetEncoding());
+ $history->recordEntry(
+ new SimpleUrl('http://www.second.com/'),
+ new SimplePostEncoding(array('a' => 1)));
+ $this->assertIdentical($history->getUrl(), new SimpleUrl('http://www.second.com/'));
+ $this->assertIdentical(
+ $history->getParameters(),
+ new SimplePostEncoding(array('a' => 1)));
+ }
+
+ function testGoingBackwards() {
+ $history = &new SimpleBrowserHistory();
+ $history->recordEntry(
+ new SimpleUrl('http://www.first.com/'),
+ new SimpleGetEncoding());
+ $history->recordEntry(
+ new SimpleUrl('http://www.second.com/'),
+ new SimplePostEncoding(array('a' => 1)));
+ $this->assertTrue($history->back());
+ $this->assertIdentical($history->getUrl(), new SimpleUrl('http://www.first.com/'));
+ $this->assertIdentical($history->getParameters(), new SimpleGetEncoding());
+ }
+
+ function testGoingBackwardsOffBeginning() {
+ $history = &new SimpleBrowserHistory();
+ $history->recordEntry(
+ new SimpleUrl('http://www.first.com/'),
+ new SimpleGetEncoding());
+ $this->assertFalse($history->back());
+ $this->assertIdentical($history->getUrl(), new SimpleUrl('http://www.first.com/'));
+ $this->assertIdentical($history->getParameters(), new SimpleGetEncoding());
+ }
+
+ function testGoingForwardsOffEnd() {
+ $history = &new SimpleBrowserHistory();
+ $history->recordEntry(
+ new SimpleUrl('http://www.first.com/'),
+ new SimpleGetEncoding());
+ $this->assertFalse($history->forward());
+ $this->assertIdentical($history->getUrl(), new SimpleUrl('http://www.first.com/'));
+ $this->assertIdentical($history->getParameters(), new SimpleGetEncoding());
+ }
+
+ function testGoingBackwardsAndForwards() {
+ $history = &new SimpleBrowserHistory();
+ $history->recordEntry(
+ new SimpleUrl('http://www.first.com/'),
+ new SimpleGetEncoding());
+ $history->recordEntry(
+ new SimpleUrl('http://www.second.com/'),
+ new SimplePostEncoding(array('a' => 1)));
+ $this->assertTrue($history->back());
+ $this->assertTrue($history->forward());
+ $this->assertIdentical($history->getUrl(), new SimpleUrl('http://www.second.com/'));
+ $this->assertIdentical(
+ $history->getParameters(),
+ new SimplePostEncoding(array('a' => 1)));
+ }
+
+ function testNewEntryReplacesNextOne() {
+ $history = &new SimpleBrowserHistory();
+ $history->recordEntry(
+ new SimpleUrl('http://www.first.com/'),
+ new SimpleGetEncoding());
+ $history->recordEntry(
+ new SimpleUrl('http://www.second.com/'),
+ new SimplePostEncoding(array('a' => 1)));
+ $history->back();
+ $history->recordEntry(
+ new SimpleUrl('http://www.third.com/'),
+ new SimpleGetEncoding());
+ $this->assertIdentical($history->getUrl(), new SimpleUrl('http://www.third.com/'));
+ $this->assertIdentical($history->getParameters(), new SimpleGetEncoding());
+ }
+
+ function testNewEntryDropsFutureEntries() {
+ $history = &new SimpleBrowserHistory();
+ $history->recordEntry(
+ new SimpleUrl('http://www.first.com/'),
+ new SimpleGetEncoding());
+ $history->recordEntry(
+ new SimpleUrl('http://www.second.com/'),
+ new SimpleGetEncoding());
+ $history->recordEntry(
+ new SimpleUrl('http://www.third.com/'),
+ new SimpleGetEncoding());
+ $history->back();
+ $history->back();
+ $history->recordEntry(
+ new SimpleUrl('http://www.fourth.com/'),
+ new SimpleGetEncoding());
+ $this->assertIdentical($history->getUrl(), new SimpleUrl('http://www.fourth.com/'));
+ $this->assertFalse($history->forward());
+ $history->back();
+ $this->assertIdentical($history->getUrl(), new SimpleUrl('http://www.first.com/'));
+ $this->assertFalse($history->back());
+ }
+}
+
+class TestOfParsedPageAccess extends UnitTestCase {
+
+ function &loadPage(&$page) {
+ $response = &new MockSimpleHttpResponse($this);
+
+ $agent = &new MockSimpleUserAgent($this);
+ $agent->setReturnReference('fetchResponse', $response);
+
+ $browser = &new MockParseSimpleBrowser($this);
+ $browser->setReturnReference('_createUserAgent', $agent);
+ $browser->setReturnReference('_parse', $page);
+ $browser->SimpleBrowser();
+
+ $browser->get('http://this.com/page.html');
+ return $browser;
+ }
+
+ function testAccessorsWhenNoPage() {
+ $agent = &new MockSimpleUserAgent($this);
+
+ $browser = &new MockParseSimpleBrowser($this);
+ $browser->setReturnReference('_createUserAgent', $agent);
+ $browser->SimpleBrowser();
+
+ $this->assertEqual($browser->getContent(), '');
+ }
+
+ function testParse() {
+ $page = &new MockSimplePage();
+ $page->setReturnValue('getRequest', "GET here.html\r\n\r\n");
+ $page->setReturnValue('getRaw', 'Raw HTML');
+ $page->setReturnValue('getTitle', 'Here');
+ $page->setReturnValue('getFrameFocus', 'Frame');
+ $page->setReturnValue('getMimeType', 'text/html');
+ $page->setReturnValue('getResponseCode', 200);
+ $page->setReturnValue('getAuthentication', 'Basic');
+ $page->setReturnValue('getRealm', 'Somewhere');
+ $page->setReturnValue('getTransportError', 'Ouch!');
+
+ $browser = &$this->loadPage($page);
+
+ $this->assertEqual($browser->getRequest(), "GET here.html\r\n\r\n");
+ $this->assertEqual($browser->getContent(), 'Raw HTML');
+ $this->assertEqual($browser->getTitle(), 'Here');
+ $this->assertEqual($browser->getFrameFocus(), 'Frame');
+ $this->assertIdentical($browser->getResponseCode(), 200);
+ $this->assertEqual($browser->getMimeType(), 'text/html');
+ $this->assertEqual($browser->getAuthentication(), 'Basic');
+ $this->assertEqual($browser->getRealm(), 'Somewhere');
+ $this->assertEqual($browser->getTransportError(), 'Ouch!');
+ }
+
+ function testLinkAffirmationWhenPresent() {
+ $page = &new MockSimplePage();
+ $page->setReturnValue('getUrlsByLabel', array('http://www.nowhere.com'));
+ $page->expectOnce('getUrlsByLabel', array('a link label'));
+ $browser = &$this->loadPage($page);
+ $this->assertIdentical($browser->getLink('a link label'), 'http://www.nowhere.com');
+ }
+
+ function testLinkAffirmationByIdWhenPresent() {
+ $page = &new MockSimplePage();
+ $page->setReturnValue('getUrlById', 'a_page.com', array(99));
+ $page->setReturnValue('getUrlById', false, array('*'));
+ $browser = &$this->loadPage($page);
+ $this->assertIdentical($browser->getLinkById(99), 'a_page.com');
+ $this->assertFalse($browser->getLinkById(98));
+ }
+
+ function testSettingFieldIsPassedToPage() {
+ $page = &new MockSimplePage();
+ $page->expectOnce('setField', array(new SimpleByLabelOrName('key'), 'Value', false));
+ $page->setReturnValue('getField', 'Value');
+ $browser = &$this->loadPage($page);
+ $this->assertEqual($browser->getField('key'), 'Value');
+ $browser->setField('key', 'Value');
+ }
+}
+
+class TestOfBrowserNavigation extends UnitTestCase {
+
+ function &createBrowser(&$agent, &$page) {
+ $browser = &new MockParseSimpleBrowser();
+ $browser->setReturnReference('_createUserAgent', $agent);
+ $browser->setReturnReference('_parse', $page);
+ $browser->SimpleBrowser();
+ return $browser;
+ }
+
+ function testClickLinkRequestsPage() {
+ $agent = &new MockSimpleUserAgent();
+ $agent->setReturnReference('fetchResponse', new MockSimpleHttpResponse());
+ $agent->expectArgumentsAt(
+ 0,
+ 'fetchResponse',
+ array(new SimpleUrl('http://this.com/page.html'), new SimpleGetEncoding()));
+ $agent->expectArgumentsAt(
+ 1,
+ 'fetchResponse',
+ array(new SimpleUrl('http://this.com/new.html'), new SimpleGetEncoding()));
+ $agent->expectCallCount('fetchResponse', 2);
+
+ $page = &new MockSimplePage();
+ $page->setReturnValue('getUrlsByLabel', array(new SimpleUrl('http://this.com/new.html')));
+ $page->expectOnce('getUrlsByLabel', array('New'));
+ $page->setReturnValue('getRaw', 'A page');
+
+ $browser = &$this->createBrowser($agent, $page);
+ $browser->get('http://this.com/page.html');
+ $this->assertTrue($browser->clickLink('New'));
+ }
+
+ function testClickLinkWithUnknownFrameStillRequestsWholePage() {
+ $agent = &new MockSimpleUserAgent();
+ $agent->setReturnReference('fetchResponse', new MockSimpleHttpResponse());
+ $agent->expectArgumentsAt(
+ 0,
+ 'fetchResponse',
+ array(new SimpleUrl('http://this.com/page.html'), new SimpleGetEncoding()));
+ $target = new SimpleUrl('http://this.com/new.html');
+ $target->setTarget('missing');
+ $agent->expectArgumentsAt(
+ 1,
+ 'fetchResponse',
+ array($target, new SimpleGetEncoding()));
+ $agent->expectCallCount('fetchResponse', 2);
+
+ $parsed_url = new SimpleUrl('http://this.com/new.html');
+ $parsed_url->setTarget('missing');
+
+ $page = &new MockSimplePage();
+ $page->setReturnValue('getUrlsByLabel', array($parsed_url));
+ $page->setReturnValue('hasFrames', false);
+ $page->expectOnce('getUrlsByLabel', array('New'));
+ $page->setReturnValue('getRaw', 'A page');
+
+ $browser = &$this->createBrowser($agent, $page);
+ $browser->get('http://this.com/page.html');
+ $this->assertTrue($browser->clickLink('New'));
+ }
+
+ function testClickingMissingLinkFails() {
+ $agent = &new MockSimpleUserAgent($this);
+ $agent->setReturnReference('fetchResponse', new MockSimpleHttpResponse());
+
+ $page = &new MockSimplePage();
+ $page->setReturnValue('getUrlsByLabel', array());
+ $page->setReturnValue('getRaw', 'stuff');
+
+ $browser = &$this->createBrowser($agent, $page);
+ $this->assertTrue($browser->get('http://this.com/page.html'));
+ $this->assertFalse($browser->clickLink('New'));
+ }
+
+ function testClickIndexedLink() {
+ $agent = &new MockSimpleUserAgent();
+ $agent->setReturnReference('fetchResponse', new MockSimpleHttpResponse());
+ $agent->expectArgumentsAt(
+ 1,
+ 'fetchResponse',
+ array(new SimpleUrl('1.html'), new SimpleGetEncoding()));
+ $agent->expectCallCount('fetchResponse', 2);
+
+ $page = &new MockSimplePage();
+ $page->setReturnValue(
+ 'getUrlsByLabel',
+ array(new SimpleUrl('0.html'), new SimpleUrl('1.html')));
+ $page->setReturnValue('getRaw', 'A page');
+
+ $browser = &$this->createBrowser($agent, $page);
+ $browser->get('http://this.com/page.html');
+ $this->assertTrue($browser->clickLink('New', 1));
+ }
+
+ function testClinkLinkById() {
+ $agent = &new MockSimpleUserAgent();
+ $agent->setReturnReference('fetchResponse', new MockSimpleHttpResponse());
+ $agent->expectArgumentsAt(1, 'fetchResponse', array(
+ new SimpleUrl('http://this.com/link.html'),
+ new SimpleGetEncoding()));
+ $agent->expectCallCount('fetchResponse', 2);
+
+ $page = &new MockSimplePage();
+ $page->setReturnValue('getUrlById', new SimpleUrl('http://this.com/link.html'));
+ $page->expectOnce('getUrlById', array(2));
+ $page->setReturnValue('getRaw', 'A page');
+
+ $browser = &$this->createBrowser($agent, $page);
+ $browser->get('http://this.com/page.html');
+ $this->assertTrue($browser->clickLinkById(2));
+ }
+
+ function testClickingMissingLinkIdFails() {
+ $agent = &new MockSimpleUserAgent();
+ $agent->setReturnReference('fetchResponse', new MockSimpleHttpResponse());
+
+ $page = &new MockSimplePage();
+ $page->setReturnValue('getUrlById', false);
+
+ $browser = &$this->createBrowser($agent, $page);
+ $browser->get('http://this.com/page.html');
+ $this->assertFalse($browser->clickLink(0));
+ }
+
+ function testSubmitFormByLabel() {
+ $agent = &new MockSimpleUserAgent();
+ $agent->setReturnReference('fetchResponse', new MockSimpleHttpResponse());
+ $agent->expectArgumentsAt(1, 'fetchResponse', array(
+ new SimpleUrl('http://this.com/handler.html'),
+ new SimplePostEncoding(array('a' => 'A'))));
+ $agent->expectCallCount('fetchResponse', 2);
+
+ $form = &new MockSimpleForm();
+ $form->setReturnValue('getAction', new SimpleUrl('http://this.com/handler.html'));
+ $form->setReturnValue('getMethod', 'post');
+ $form->setReturnValue('submitButton', new SimplePostEncoding(array('a' => 'A')));
+ $form->expectOnce('submitButton', array(new SimpleByLabel('Go'), false));
+
+ $page = &new MockSimplePage();
+ $page->setReturnReference('getFormBySubmit', $form);
+ $page->expectOnce('getFormBySubmit', array(new SimpleByLabel('Go')));
+ $page->setReturnValue('getRaw', 'stuff');
+
+ $browser = &$this->createBrowser($agent, $page);
+ $browser->get('http://this.com/page.html');
+ $this->assertTrue($browser->clickSubmit('Go'));
+ }
+
+ function testDefaultSubmitFormByLabel() {
+ $agent = &new MockSimpleUserAgent();
+ $agent->setReturnReference('fetchResponse', new MockSimpleHttpResponse());
+ $agent->expectArgumentsAt(1, 'fetchResponse', array(
+ new SimpleUrl('http://this.com/page.html'),
+ new SimpleGetEncoding(array('a' => 'A'))));
+ $agent->expectCallCount('fetchResponse', 2);
+
+ $form = &new MockSimpleForm();
+ $form->setReturnValue('getAction', new SimpleUrl('http://this.com/page.html'));
+ $form->setReturnValue('getMethod', 'get');
+ $form->setReturnValue('submitButton', new SimpleGetEncoding(array('a' => 'A')));
+
+ $page = &new MockSimplePage();
+ $page->setReturnReference('getFormBySubmit', $form);
+ $page->expectOnce('getFormBySubmit', array(new SimpleByLabel('Submit')));
+ $page->setReturnValue('getRaw', 'stuff');
+ $page->setReturnValue('getUrl', new SimpleUrl('http://this.com/page.html'));
+
+ $browser = &$this->createBrowser($agent, $page);
+ $browser->get('http://this.com/page.html');
+ $this->assertTrue($browser->clickSubmit());
+ }
+
+ function testSubmitFormByName() {
+ $agent = &new MockSimpleUserAgent();
+ $agent->setReturnReference('fetchResponse', new MockSimpleHttpResponse());
+
+ $form = &new MockSimpleForm();
+ $form->setReturnValue('getAction', new SimpleUrl('http://this.com/handler.html'));
+ $form->setReturnValue('getMethod', 'post');
+ $form->setReturnValue('submitButton', new SimplePostEncoding(array('a' => 'A')));
+
+ $page = &new MockSimplePage();
+ $page->setReturnReference('getFormBySubmit', $form);
+ $page->expectOnce('getFormBySubmit', array(new SimpleByName('me')));
+ $page->setReturnValue('getRaw', 'stuff');
+
+ $browser = &$this->createBrowser($agent, $page);
+ $browser->get('http://this.com/page.html');
+ $this->assertTrue($browser->clickSubmitByName('me'));
+ }
+
+ function testSubmitFormById() {
+ $agent = &new MockSimpleUserAgent();
+ $agent->setReturnReference('fetchResponse', new MockSimpleHttpResponse());
+
+ $form = &new MockSimpleForm();
+ $form->setReturnValue('getAction', new SimpleUrl('http://this.com/handler.html'));
+ $form->setReturnValue('getMethod', 'post');
+ $form->setReturnValue('submitButton', new SimplePostEncoding(array('a' => 'A')));
+ $form->expectOnce('submitButton', array(new SimpleById(99), false));
+
+ $page = &new MockSimplePage();
+ $page->setReturnReference('getFormBySubmit', $form);
+ $page->expectOnce('getFormBySubmit', array(new SimpleById(99)));
+ $page->setReturnValue('getRaw', 'stuff');
+
+ $browser = &$this->createBrowser($agent, $page);
+ $browser->get('http://this.com/page.html');
+ $this->assertTrue($browser->clickSubmitById(99));
+ }
+
+ function testSubmitFormByImageLabel() {
+ $agent = &new MockSimpleUserAgent();
+ $agent->setReturnReference('fetchResponse', new MockSimpleHttpResponse());
+
+ $form = &new MockSimpleForm();
+ $form->setReturnValue('getAction', new SimpleUrl('http://this.com/handler.html'));
+ $form->setReturnValue('getMethod', 'post');
+ $form->setReturnValue('submitImage', new SimplePostEncoding(array('a' => 'A')));
+ $form->expectOnce('submitImage', array(new SimpleByLabel('Go!'), 10, 11, false));
+
+ $page = &new MockSimplePage();
+ $page->setReturnReference('getFormByImage', $form);
+ $page->expectOnce('getFormByImage', array(new SimpleByLabel('Go!')));
+ $page->setReturnValue('getRaw', 'stuff');
+
+ $browser = &$this->createBrowser($agent, $page);
+ $browser->get('http://this.com/page.html');
+ $this->assertTrue($browser->clickImage('Go!', 10, 11));
+ }
+
+ function testSubmitFormByImageName() {
+ $agent = &new MockSimpleUserAgent();
+ $agent->setReturnReference('fetchResponse', new MockSimpleHttpResponse());
+
+ $form = &new MockSimpleForm();
+ $form->setReturnValue('getAction', new SimpleUrl('http://this.com/handler.html'));
+ $form->setReturnValue('getMethod', 'post');
+ $form->setReturnValue('submitImage', new SimplePostEncoding(array('a' => 'A')));
+ $form->expectOnce('submitImage', array(new SimpleByName('a'), 10, 11, false));
+
+ $page = &new MockSimplePage();
+ $page->setReturnReference('getFormByImage', $form);
+ $page->expectOnce('getFormByImage', array(new SimpleByName('a')));
+ $page->setReturnValue('getRaw', 'stuff');
+
+ $browser = &$this->createBrowser($agent, $page);
+ $browser->get('http://this.com/page.html');
+ $this->assertTrue($browser->clickImageByName('a', 10, 11));
+ }
+
+ function testSubmitFormByImageId() {
+ $agent = &new MockSimpleUserAgent();
+ $agent->setReturnReference('fetchResponse', new MockSimpleHttpResponse());
+
+ $form = &new MockSimpleForm();
+ $form->setReturnValue('getAction', new SimpleUrl('http://this.com/handler.html'));
+ $form->setReturnValue('getMethod', 'post');
+ $form->setReturnValue('submitImage', new SimplePostEncoding(array('a' => 'A')));
+ $form->expectOnce('submitImage', array(new SimpleById(99), 10, 11, false));
+
+ $page = &new MockSimplePage();
+ $page->setReturnReference('getFormByImage', $form);
+ $page->expectOnce('getFormByImage', array(new SimpleById(99)));
+ $page->setReturnValue('getRaw', 'stuff');
+
+ $browser = &$this->createBrowser($agent, $page);
+ $browser->get('http://this.com/page.html');
+ $this->assertTrue($browser->clickImageById(99, 10, 11));
+ }
+
+ function testSubmitFormByFormId() {
+ $agent = &new MockSimpleUserAgent();
+ $agent->setReturnReference('fetchResponse', new MockSimpleHttpResponse());
+ $agent->expectArgumentsAt(1, 'fetchResponse', array(
+ new SimpleUrl('http://this.com/handler.html'),
+ new SimplePostEncoding(array('a' => 'A'))));
+ $agent->expectCallCount('fetchResponse', 2);
+
+ $form = &new MockSimpleForm();
+ $form->setReturnValue('getAction', new SimpleUrl('http://this.com/handler.html'));
+ $form->setReturnValue('getMethod', 'post');
+ $form->setReturnValue('submit', new SimplePostEncoding(array('a' => 'A')));
+
+ $page = &new MockSimplePage();
+ $page->setReturnReference('getFormById', $form);
+ $page->expectOnce('getFormById', array(33));
+ $page->setReturnValue('getRaw', 'stuff');
+
+ $browser = &$this->createBrowser($agent, $page);
+ $browser->get('http://this.com/page.html');
+ $this->assertTrue($browser->submitFormById(33));
+ }
+}
+
+class TestOfBrowserFrames extends UnitTestCase {
+
+ function &createBrowser(&$agent) {
+ $browser = &new MockUserAgentSimpleBrowser();
+ $browser->setReturnReference('_createUserAgent', $agent);
+ $browser->SimpleBrowser();
+ return $browser;
+ }
+
+ function &createUserAgent($pages) {
+ $agent = &new MockSimpleUserAgent();
+ foreach ($pages as $url => $raw) {
+ $url = new SimpleUrl($url);
+ $response = &new MockSimpleHttpResponse();
+ $response->setReturnValue('getUrl', $url);
+ $response->setReturnValue('getContent', $raw);
+ $agent->setReturnReference('fetchResponse', $response, array($url, '*'));
+ }
+ return $agent;
+ }
+
+ function testSimplePageHasNoFrames() {
+ $browser = &$this->createBrowser($this->createUserAgent(
+ array('http://site.with.no.frames/' => 'A non-framed page')));
+ $this->assertEqual(
+ $browser->get('http://site.with.no.frames/'),
+ 'A non-framed page');
+ $this->assertIdentical($browser->getFrames(), 'http://site.with.no.frames/');
+ }
+
+ function testFramesetWithNoFrames() {
+ $browser = &$this->createBrowser($this->createUserAgent(
+ array('http://site.with.no.frames/' => '<frameset></frameset>')));
+ $this->assertEqual($browser->get('http://site.with.no.frames/'), '');
+ $this->assertIdentical($browser->getFrames(), array());
+ }
+
+ function testFramesetWithSingleFrame() {
+ $frameset = '<frameset><frame name="a" src="frame.html"></frameset>';
+ $browser = &$this->createBrowser($this->createUserAgent(array(
+ 'http://site.with.one.frame/' => $frameset,
+ 'http://site.with.one.frame/frame.html' => 'A frame')));
+ $this->assertEqual($browser->get('http://site.with.one.frame/'), 'A frame');
+ $this->assertIdentical(
+ $browser->getFrames(),
+ array('a' => 'http://site.with.one.frame/frame.html'));
+ }
+
+ function testTitleTakenFromFramesetPage() {
+ $frameset = '<title>Frameset title</title>' .
+ '<frameset><frame name="a" src="frame.html"></frameset>';
+ $browser = &$this->createBrowser($this->createUserAgent(array(
+ 'http://site.with.one.frame/' => $frameset,
+ 'http://site.with.one.frame/frame.html' => '<title>Page title</title>')));
+ $browser->get('http://site.with.one.frame/');
+ $this->assertEqual($browser->getTitle(), 'Frameset title');
+ }
+
+ function testFramesetWithSingleUnnamedFrame() {
+ $frameset = '<frameset><frame src="frame.html"></frameset>';
+ $browser = &$this->createBrowser($this->createUserAgent(array(
+ 'http://site.with.one.frame/' => $frameset,
+ 'http://site.with.one.frame/frame.html' => 'One frame')));
+ $this->assertEqual(
+ $browser->get('http://site.with.one.frame/'),
+ 'One frame');
+ $this->assertIdentical(
+ $browser->getFrames(),
+ array(1 => 'http://site.with.one.frame/frame.html'));
+ }
+
+ function testFramesetWithMultipleFrames() {
+ $frameset = '<frameset>' .
+ '<frame name="a" src="frame_a.html">' .
+ '<frame name="b" src="frame_b.html">' .
+ '<frame name="c" src="frame_c.html">' .
+ '</frameset>';
+ $browser = &$this->createBrowser($this->createUserAgent(array(
+ 'http://site.with.frames/' => $frameset,
+ 'http://site.with.frames/frame_a.html' => 'A frame',
+ 'http://site.with.frames/frame_b.html' => 'B frame',
+ 'http://site.with.frames/frame_c.html' => 'C frame')));
+ $this->assertEqual(
+ $browser->get('http://site.with.frames/'),
+ 'A frameB frameC frame');
+ $this->assertIdentical($browser->getFrames(), array(
+ 'a' => 'http://site.with.frames/frame_a.html',
+ 'b' => 'http://site.with.frames/frame_b.html',
+ 'c' => 'http://site.with.frames/frame_c.html'));
+ }
+
+ function testFrameFocusByName() {
+ $frameset = '<frameset>' .
+ '<frame name="a" src="frame_a.html">' .
+ '<frame name="b" src="frame_b.html">' .
+ '<frame name="c" src="frame_c.html">' .
+ '</frameset>';
+ $browser = &$this->createBrowser($this->createUserAgent(array(
+ 'http://site.with.frames/' => $frameset,
+ 'http://site.with.frames/frame_a.html' => 'A frame',
+ 'http://site.with.frames/frame_b.html' => 'B frame',
+ 'http://site.with.frames/frame_c.html' => 'C frame')));
+ $browser->get('http://site.with.frames/');
+ $browser->setFrameFocus('a');
+ $this->assertEqual($browser->getContent(), 'A frame');
+ $browser->setFrameFocus('b');
+ $this->assertEqual($browser->getContent(), 'B frame');
+ $browser->setFrameFocus('c');
+ $this->assertEqual($browser->getContent(), 'C frame');
+ }
+
+ function testFramesetWithSomeNamedFrames() {
+ $frameset = '<frameset>' .
+ '<frame name="a" src="frame_a.html">' .
+ '<frame src="frame_b.html">' .
+ '<frame name="c" src="frame_c.html">' .
+ '<frame src="frame_d.html">' .
+ '</frameset>';
+ $browser = &$this->createBrowser($this->createUserAgent(array(
+ 'http://site.with.frames/' => $frameset,
+ 'http://site.with.frames/frame_a.html' => 'A frame',
+ 'http://site.with.frames/frame_b.html' => 'B frame',
+ 'http://site.with.frames/frame_c.html' => 'C frame',
+ 'http://site.with.frames/frame_d.html' => 'D frame')));
+ $this->assertEqual(
+ $browser->get('http://site.with.frames/'),
+ 'A frameB frameC frameD frame');
+ $this->assertIdentical($browser->getFrames(), array(
+ 'a' => 'http://site.with.frames/frame_a.html',
+ 2 => 'http://site.with.frames/frame_b.html',
+ 'c' => 'http://site.with.frames/frame_c.html',
+ 4 => 'http://site.with.frames/frame_d.html'));
+ }
+
+ function testFrameFocusWithMixedNamesAndIndexes() {
+ $frameset = '<frameset>' .
+ '<frame name="a" src="frame_a.html">' .
+ '<frame src="frame_b.html">' .
+ '<frame name="c" src="frame_c.html">' .
+ '<frame src="frame_d.html">' .
+ '</frameset>';
+ $browser = &$this->createBrowser($this->createUserAgent(array(
+ 'http://site.with.frames/' => $frameset,
+ 'http://site.with.frames/frame_a.html' => 'A frame',
+ 'http://site.with.frames/frame_b.html' => 'B frame',
+ 'http://site.with.frames/frame_c.html' => 'C frame',
+ 'http://site.with.frames/frame_d.html' => 'D frame')));
+ $browser->get('http://site.with.frames/');
+ $browser->setFrameFocus('a');
+ $this->assertEqual($browser->getContent(), 'A frame');
+ $browser->setFrameFocus(2);
+ $this->assertEqual($browser->getContent(), 'B frame');
+ $browser->setFrameFocus('c');
+ $this->assertEqual($browser->getContent(), 'C frame');
+ $browser->setFrameFocus(4);
+ $this->assertEqual($browser->getContent(), 'D frame');
+ $browser->clearFrameFocus();
+ $this->assertEqual($browser->getContent(), 'A frameB frameC frameD frame');
+ }
+
+ function testNestedFrameset() {
+ $inner = '<frameset>' .
+ '<frame name="page" src="page.html">' .
+ '</frameset>';
+ $outer = '<frameset>' .
+ '<frame name="inner" src="inner.html">' .
+ '</frameset>';
+ $browser = &$this->createBrowser($this->createUserAgent(array(
+ 'http://site.with.nested.frame/' => $outer,
+ 'http://site.with.nested.frame/inner.html' => $inner,
+ 'http://site.with.nested.frame/page.html' => 'The page')));
+ $this->assertEqual(
+ $browser->get('http://site.with.nested.frame/'),
+ 'The page');
+ $this->assertIdentical($browser->getFrames(), array(
+ 'inner' => array(
+ 'page' => 'http://site.with.nested.frame/page.html')));
+ }
+
+ function testCanNavigateToNestedFrame() {
+ $inner = '<frameset>' .
+ '<frame name="one" src="one.html">' .
+ '<frame name="two" src="two.html">' .
+ '</frameset>';
+ $outer = '<frameset>' .
+ '<frame name="inner" src="inner.html">' .
+ '<frame name="three" src="three.html">' .
+ '</frameset>';
+ $browser = &$this->createBrowser($this->createUserAgent(array(
+ 'http://site.with.nested.frames/' => $outer,
+ 'http://site.with.nested.frames/inner.html' => $inner,
+ 'http://site.with.nested.frames/one.html' => 'Page one',
+ 'http://site.with.nested.frames/two.html' => 'Page two',
+ 'http://site.with.nested.frames/three.html' => 'Page three')));
+
+ $browser->get('http://site.with.nested.frames/');
+ $this->assertEqual($browser->getContent(), 'Page onePage twoPage three');
+
+ $this->assertTrue($browser->setFrameFocus('inner'));
+ $this->assertEqual($browser->getFrameFocus(), array('inner'));
+ $this->assertTrue($browser->setFrameFocus('one'));
+ $this->assertEqual($browser->getFrameFocus(), array('inner', 'one'));
+ $this->assertEqual($browser->getContent(), 'Page one');
+
+ $this->assertTrue($browser->setFrameFocus('two'));
+ $this->assertEqual($browser->getFrameFocus(), array('inner', 'two'));
+ $this->assertEqual($browser->getContent(), 'Page two');
+
+ $browser->clearFrameFocus();
+ $this->assertTrue($browser->setFrameFocus('three'));
+ $this->assertEqual($browser->getFrameFocus(), array('three'));
+ $this->assertEqual($browser->getContent(), 'Page three');
+
+ $this->assertTrue($browser->setFrameFocus('inner'));
+ $this->assertEqual($browser->getContent(), 'Page onePage two');
+ }
+
+ function testCanNavigateToNestedFrameByIndex() {
+ $inner = '<frameset>' .
+ '<frame src="one.html">' .
+ '<frame src="two.html">' .
+ '</frameset>';
+ $outer = '<frameset>' .
+ '<frame src="inner.html">' .
+ '<frame src="three.html">' .
+ '</frameset>';
+ $browser = &$this->createBrowser($this->createUserAgent(array(
+ 'http://site.with.nested.frames/' => $outer,
+ 'http://site.with.nested.frames/inner.html' => $inner,
+ 'http://site.with.nested.frames/one.html' => 'Page one',
+ 'http://site.with.nested.frames/two.html' => 'Page two',
+ 'http://site.with.nested.frames/three.html' => 'Page three')));
+
+ $browser->get('http://site.with.nested.frames/');
+ $this->assertEqual($browser->getContent(), 'Page onePage twoPage three');
+
+ $this->assertTrue($browser->setFrameFocusByIndex(1));
+ $this->assertEqual($browser->getFrameFocus(), array(1));
+ $this->assertTrue($browser->setFrameFocusByIndex(1));
+ $this->assertEqual($browser->getFrameFocus(), array(1, 1));
+ $this->assertEqual($browser->getContent(), 'Page one');
+
+ $this->assertTrue($browser->setFrameFocusByIndex(2));
+ $this->assertEqual($browser->getFrameFocus(), array(1, 2));
+ $this->assertEqual($browser->getContent(), 'Page two');
+
+ $browser->clearFrameFocus();
+ $this->assertTrue($browser->setFrameFocusByIndex(2));
+ $this->assertEqual($browser->getFrameFocus(), array(2));
+ $this->assertEqual($browser->getContent(), 'Page three');
+
+ $this->assertTrue($browser->setFrameFocusByIndex(1));
+ $this->assertEqual($browser->getContent(), 'Page onePage two');
+ }
+}
+?> \ No newline at end of file
diff --git a/site/vendors/simpletest/test/collector_test.php b/site/vendors/simpletest/test/collector_test.php
new file mode 100644
index 0000000..803974c
--- /dev/null
+++ b/site/vendors/simpletest/test/collector_test.php
@@ -0,0 +1,51 @@
+<?php
+// $Id: collector_test.php 1505 2007-04-30 23:39:59Z lastcraft $
+require_once(dirname(__FILE__) . '/../autorun.php');
+require_once(dirname(__FILE__) . '/../collector.php');
+SimpleTest::ignore('MockTestSuite');
+Mock::generate('TestSuite');
+
+class PathEqualExpectation extends EqualExpectation {
+ function PathEqualExpectation($value, $message = '%s') {
+ $this->EqualExpectation(str_replace("\\", '/', $value), $message);
+ }
+
+ function test($compare) {
+ return parent::test(str_replace("\\", '/', $compare));
+ }
+}
+
+class TestOfCollector extends UnitTestCase {
+
+ function testCollectionIsAddedToGroup() {
+ $suite = &new MockTestSuite();
+ $suite->expectMinimumCallCount('addTestFile', 2);
+ $suite->expectArguments(
+ 'addTestFile',
+ array(new PatternExpectation('/collectable\\.(1|2)$/')));
+ $collector = &new SimpleCollector();
+ $collector->collect($suite, dirname(__FILE__) . '/support/collector/');
+ }
+}
+
+class TestOfPatternCollector extends UnitTestCase {
+
+ function testAddingEverythingToGroup() {
+ $suite = &new MockTestSuite();
+ $suite->expectCallCount('addTestFile', 2);
+ $suite->expectArguments(
+ 'addTestFile',
+ array(new PatternExpectation('/collectable\\.(1|2)$/')));
+ $collector = &new SimplePatternCollector('/.*/');
+ $collector->collect($suite, dirname(__FILE__) . '/support/collector/');
+ }
+
+ function testOnlyMatchedFilesAreAddedToGroup() {
+ $suite = &new MockTestSuite();
+ $suite->expectOnce('addTestFile', array(new PathEqualExpectation(
+ dirname(__FILE__) . '/support/collector/collectable.1')));
+ $collector = &new SimplePatternCollector('/1$/');
+ $collector->collect($suite, dirname(__FILE__) . '/support/collector/');
+ }
+}
+?> \ No newline at end of file
diff --git a/site/vendors/simpletest/test/command_line_test.php b/site/vendors/simpletest/test/command_line_test.php
new file mode 100644
index 0000000..5baabff
--- /dev/null
+++ b/site/vendors/simpletest/test/command_line_test.php
@@ -0,0 +1,40 @@
+<?php
+require_once(dirname(__FILE__) . '/../autorun.php');
+require_once(dirname(__FILE__) . '/../default_reporter.php');
+
+class TestOfCommandLineParsing extends UnitTestCase {
+
+ function testDefaultsToEmptyStringToMeanNullToTheSelectiveReporter() {
+ $parser = new SimpleCommandLineParser(array());
+ $this->assertIdentical($parser->getTest(), '');
+ $this->assertIdentical($parser->getTestCase(), '');
+ }
+
+ function testNotXmlByDefault() {
+ $parser = new SimpleCommandLineParser(array());
+ $this->assertFalse($parser->isXml());
+ }
+
+ function testCanDetectRequestForXml() {
+ $parser = new SimpleCommandLineParser(array('--xml'));
+ $this->assertTrue($parser->isXml());
+ }
+
+ function testCanReadAssignmentSyntax() {
+ $parser = new SimpleCommandLineParser(array('--test=myTest'));
+ $this->assertEqual($parser->getTest(), 'myTest');
+ }
+
+ function testCanReadFollowOnSyntax() {
+ $parser = new SimpleCommandLineParser(array('--test', 'myTest'));
+ $this->assertEqual($parser->getTest(), 'myTest');
+ }
+
+ function testCanReadShortForms() {
+ $parser = new SimpleCommandLineParser(array('-t', 'myTest', '-c', 'MyClass', '-x'));
+ $this->assertEqual($parser->getTest(), 'myTest');
+ $this->assertEqual($parser->getTestCase(), 'MyClass');
+ $this->assertTrue($parser->isXml());
+ }
+}
+?> \ No newline at end of file
diff --git a/site/vendors/simpletest/test/compatibility_test.php b/site/vendors/simpletest/test/compatibility_test.php
new file mode 100644
index 0000000..ea48f83
--- /dev/null
+++ b/site/vendors/simpletest/test/compatibility_test.php
@@ -0,0 +1,97 @@
+<?php
+// $Id: compatibility_test.php 1505 2007-04-30 23:39:59Z lastcraft $
+require_once(dirname(__FILE__) . '/../autorun.php');
+require_once(dirname(__FILE__) . '/../compatibility.php');
+
+class ComparisonClass {
+}
+
+class ComparisonSubclass extends ComparisonClass {
+}
+
+if (version_compare(phpversion(), '5') >= 0) {
+ eval('interface ComparisonInterface { }');
+ eval('class ComparisonClassWithInterface implements ComparisonInterface { }');
+}
+
+class TestOfCompatibility extends UnitTestCase {
+
+ function testIsA() {
+ $this->assertTrue(SimpleTestCompatibility::isA(
+ new ComparisonClass(),
+ 'ComparisonClass'));
+ $this->assertFalse(SimpleTestCompatibility::isA(
+ new ComparisonClass(),
+ 'ComparisonSubclass'));
+ $this->assertTrue(SimpleTestCompatibility::isA(
+ new ComparisonSubclass(),
+ 'ComparisonClass'));
+ }
+
+ function testIdentityOfNumericStrings() {
+ $numericString1 = "123";
+ $numericString2 = "00123";
+ $this->assertNotIdentical($numericString1, $numericString2);
+ }
+
+ function testIdentityOfObjects() {
+ $object1 = new ComparisonClass();
+ $object2 = new ComparisonClass();
+ $this->assertIdentical($object1, $object2);
+ }
+
+ function testReferences () {
+ $thing = "Hello";
+ $thing_reference = &$thing;
+ $thing_copy = $thing;
+ $this->assertTrue(SimpleTestCompatibility::isReference(
+ $thing,
+ $thing));
+ $this->assertTrue(SimpleTestCompatibility::isReference(
+ $thing,
+ $thing_reference));
+ $this->assertFalse(SimpleTestCompatibility::isReference(
+ $thing,
+ $thing_copy));
+ }
+
+ function testObjectReferences () {
+ $object = &new ComparisonClass();
+ $object_reference = &$object;
+ $object_copy = new ComparisonClass();
+ $object_assignment = $object;
+ $this->assertTrue(SimpleTestCompatibility::isReference(
+ $object,
+ $object));
+ $this->assertTrue(SimpleTestCompatibility::isReference(
+ $object,
+ $object_reference));
+ $this->assertFalse(SimpleTestCompatibility::isReference(
+ $object,
+ $object_copy));
+ if (version_compare(phpversion(), '5', '>=')) {
+ $this->assertTrue(SimpleTestCompatibility::isReference(
+ $object,
+ $object_assignment));
+ } else {
+ $this->assertFalse(SimpleTestCompatibility::isReference(
+ $object,
+ $object_assignment));
+ }
+ }
+
+ function testInteraceComparison() {
+ if (version_compare(phpversion(), '5', '<')) {
+ return;
+ }
+
+ $object = new ComparisonClassWithInterface();
+ $this->assertFalse(SimpleTestCompatibility::isA(
+ new ComparisonClass(),
+ 'ComparisonInterface'));
+ $this->assertTrue(SimpleTestCompatibility::isA(
+ new ComparisonClassWithInterface(),
+ 'ComparisonInterface'));
+ }
+}
+?> \ No newline at end of file
diff --git a/site/vendors/simpletest/test/cookies_test.php b/site/vendors/simpletest/test/cookies_test.php
new file mode 100644
index 0000000..0b49e43
--- /dev/null
+++ b/site/vendors/simpletest/test/cookies_test.php
@@ -0,0 +1,227 @@
+<?php
+// $Id: cookies_test.php 1506 2007-05-07 00:58:03Z lastcraft $
+require_once(dirname(__FILE__) . '/../autorun.php');
+require_once(dirname(__FILE__) . '/../cookies.php');
+
+class TestOfCookie extends UnitTestCase {
+
+ function testCookieDefaults() {
+ $cookie = new SimpleCookie("name");
+ $this->assertFalse($cookie->getValue());
+ $this->assertEqual($cookie->getPath(), "/");
+ $this->assertIdentical($cookie->getHost(), false);
+ $this->assertFalse($cookie->getExpiry());
+ $this->assertFalse($cookie->isSecure());
+ }
+
+ function testCookieAccessors() {
+ $cookie = new SimpleCookie(
+ "name",
+ "value",
+ "/path",
+ "Mon, 18 Nov 2002 15:50:29 GMT",
+ true);
+ $this->assertEqual($cookie->getName(), "name");
+ $this->assertEqual($cookie->getValue(), "value");
+ $this->assertEqual($cookie->getPath(), "/path/");
+ $this->assertEqual($cookie->getExpiry(), "Mon, 18 Nov 2002 15:50:29 GMT");
+ $this->assertTrue($cookie->isSecure());
+ }
+
+ function testFullHostname() {
+ $cookie = new SimpleCookie("name");
+ $this->assertTrue($cookie->setHost("host.name.here"));
+ $this->assertEqual($cookie->getHost(), "host.name.here");
+ $this->assertTrue($cookie->setHost("host.com"));
+ $this->assertEqual($cookie->getHost(), "host.com");
+ }
+
+ function testHostTruncation() {
+ $cookie = new SimpleCookie("name");
+ $cookie->setHost("this.host.name.here");
+ $this->assertEqual($cookie->getHost(), "host.name.here");
+ $cookie->setHost("this.host.com");
+ $this->assertEqual($cookie->getHost(), "host.com");
+ $this->assertTrue($cookie->setHost("dashes.in-host.com"));
+ $this->assertEqual($cookie->getHost(), "in-host.com");
+ }
+
+ function testBadHosts() {
+ $cookie = new SimpleCookie("name");
+ $this->assertFalse($cookie->setHost("gibberish"));
+ $this->assertFalse($cookie->setHost("host.here"));
+ $this->assertFalse($cookie->setHost("host..com"));
+ $this->assertFalse($cookie->setHost("..."));
+ $this->assertFalse($cookie->setHost("host.com."));
+ }
+
+ function testHostValidity() {
+ $cookie = new SimpleCookie("name");
+ $cookie->setHost("this.host.name.here");
+ $this->assertTrue($cookie->isValidHost("host.name.here"));
+ $this->assertTrue($cookie->isValidHost("that.host.name.here"));
+ $this->assertFalse($cookie->isValidHost("bad.host"));
+ $this->assertFalse($cookie->isValidHost("nearly.name.here"));
+ }
+
+ function testPathValidity() {
+ $cookie = new SimpleCookie("name", "value", "/path");
+ $this->assertFalse($cookie->isValidPath("/"));
+ $this->assertTrue($cookie->isValidPath("/path/"));
+ $this->assertTrue($cookie->isValidPath("/path/more"));
+ }
+
+ function testSessionExpiring() {
+ $cookie = new SimpleCookie("name", "value", "/path");
+ $this->assertTrue($cookie->isExpired(0));
+ }
+
+ function testTimestampExpiry() {
+ $cookie = new SimpleCookie("name", "value", "/path", 456);
+ $this->assertFalse($cookie->isExpired(0));
+ $this->assertTrue($cookie->isExpired(457));
+ $this->assertFalse($cookie->isExpired(455));
+ }
+
+ function testDateExpiry() {
+ $cookie = new SimpleCookie(
+ "name",
+ "value",
+ "/path",
+ "Mon, 18 Nov 2002 15:50:29 GMT");
+ $this->assertTrue($cookie->isExpired("Mon, 18 Nov 2002 15:50:30 GMT"));
+ $this->assertFalse($cookie->isExpired("Mon, 18 Nov 2002 15:50:28 GMT"));
+ }
+
+ function testAging() {
+ $cookie = new SimpleCookie("name", "value", "/path", 200);
+ $cookie->agePrematurely(199);
+ $this->assertFalse($cookie->isExpired(0));
+ $cookie->agePrematurely(2);
+ $this->assertTrue($cookie->isExpired(0));
+ }
+}
+
+class TestOfCookieJar extends UnitTestCase {
+
+ function testAddCookie() {
+ $jar = new SimpleCookieJar();
+ $jar->setCookie("a", "A");
+ $this->assertEqual($jar->selectAsPairs(new SimpleUrl('/')), array('a=A'));
+ }
+
+ function testHostFilter() {
+ $jar = new SimpleCookieJar();
+ $jar->setCookie('a', 'A', 'my-host.com');
+ $jar->setCookie('b', 'B', 'another-host.com');
+ $jar->setCookie('c', 'C');
+ $this->assertEqual(
+ $jar->selectAsPairs(new SimpleUrl('my-host.com')),
+ array('a=A', 'c=C'));
+ $this->assertEqual(
+ $jar->selectAsPairs(new SimpleUrl('another-host.com')),
+ array('b=B', 'c=C'));
+ $this->assertEqual(
+ $jar->selectAsPairs(new SimpleUrl('www.another-host.com')),
+ array('b=B', 'c=C'));
+ $this->assertEqual(
+ $jar->selectAsPairs(new SimpleUrl('new-host.org')),
+ array('c=C'));
+ $this->assertEqual(
+ $jar->selectAsPairs(new SimpleUrl('/')),
+ array('a=A', 'b=B', 'c=C'));
+ }
+
+ function testPathFilter() {
+ $jar = new SimpleCookieJar();
+ $jar->setCookie('a', 'A', false, '/path/');
+ $this->assertEqual($jar->selectAsPairs(new SimpleUrl('/')), array());
+ $this->assertEqual($jar->selectAsPairs(new SimpleUrl('/elsewhere')), array());
+ $this->assertEqual($jar->selectAsPairs(new SimpleUrl('/path/')), array('a=A'));
+ $this->assertEqual($jar->selectAsPairs(new SimpleUrl('/path')), array('a=A'));
+ $this->assertEqual($jar->selectAsPairs(new SimpleUrl('/pa')), array());
+ $this->assertEqual($jar->selectAsPairs(new SimpleUrl('/path/here')), array('a=A'));
+ }
+
+ function testPathFilterDeeply() {
+ $jar = new SimpleCookieJar();
+ $jar->setCookie('a', 'A', false, '/path/more_path/');
+ $this->assertEqual($jar->selectAsPairs(new SimpleUrl('/path/')), array());
+ $this->assertEqual($jar->selectAsPairs(new SimpleUrl('/path')), array());
+ $this->assertEqual($jar->selectAsPairs(new SimpleUrl('/pa')), array());
+ $this->assertEqual($jar->selectAsPairs(new SimpleUrl('/path/more_path/')), array('a=A'));
+ $this->assertEqual($jar->selectAsPairs(new SimpleUrl('/path/more_path/and_more')), array('a=A'));
+ $this->assertEqual($jar->selectAsPairs(new SimpleUrl('/path/not_here/')), array());
+ }
+
+ function testMultipleCookieWithDifferentPathsButSameName() {
+ $jar = new SimpleCookieJar();
+ $jar->setCookie('a', 'abc', false, '/');
+ $jar->setCookie('a', '123', false, '/path/here/');
+ $this->assertEqual(
+ $jar->selectAsPairs(new SimpleUrl('/')),
+ array('a=abc'));
+ $this->assertEqual(
+ $jar->selectAsPairs(new SimpleUrl('my-host.com/')),
+ array('a=abc'));
+ $this->assertEqual(
+ $jar->selectAsPairs(new SimpleUrl('my-host.com/path/')),
+ array('a=abc'));
+ $this->assertEqual(
+ $jar->selectAsPairs(new SimpleUrl('my-host.com/path/here')),
+ array('a=abc', 'a=123'));
+ $this->assertEqual(
+ $jar->selectAsPairs(new SimpleUrl('my-host.com/path/here/there')),
+ array('a=abc', 'a=123'));
+ }
+
+ function testOverwrite() {
+ $jar = new SimpleCookieJar();
+ $jar->setCookie('a', 'abc', false, '/');
+ $jar->setCookie('a', 'cde', false, '/');
+ $this->assertEqual($jar->selectAsPairs(new SimpleUrl('/')), array('a=cde'));
+ }
+
+ function testClearSessionCookies() {
+ $jar = new SimpleCookieJar();
+ $jar->setCookie('a', 'A', false, '/');
+ $jar->restartSession();
+ $this->assertEqual($jar->selectAsPairs(new SimpleUrl('/')), array());
+ }
+
+ function testExpiryFilterByDate() {
+ $jar = new SimpleCookieJar();
+ $jar->setCookie('a', 'A', false, '/', 'Wed, 25-Dec-02 04:24:20 GMT');
+ $jar->restartSession("Wed, 25-Dec-02 04:24:19 GMT");
+ $this->assertEqual($jar->selectAsPairs(new SimpleUrl('/')), array('a=A'));
+ $jar->restartSession("Wed, 25-Dec-02 04:24:21 GMT");
+ $this->assertEqual($jar->selectAsPairs(new SimpleUrl('/')), array());
+ }
+
+ function testExpiryFilterByAgeing() {
+ $jar = new SimpleCookieJar();
+ $jar->setCookie('a', 'A', false, '/', 'Wed, 25-Dec-02 04:24:20 GMT');
+ $jar->restartSession("Wed, 25-Dec-02 04:24:19 GMT");
+ $this->assertEqual($jar->selectAsPairs(new SimpleUrl('/')), array('a=A'));
+ $jar->agePrematurely(2);
+ $jar->restartSession("Wed, 25-Dec-02 04:24:19 GMT");
+ $this->assertEqual($jar->selectAsPairs(new SimpleUrl('/')), array());
+ }
+
+ function testCookieClearing() {
+ $jar = new SimpleCookieJar();
+ $jar->setCookie('a', 'abc', false, '/');
+ $jar->setCookie('a', '', false, '/');
+ $this->assertEqual($jar->selectAsPairs(new SimpleUrl('/')), array('a='));
+ }
+
+ function testCookieClearByLoweringDate() {
+ $jar = new SimpleCookieJar();
+ $jar->setCookie('a', 'abc', false, '/', 'Wed, 25-Dec-02 04:24:21 GMT');
+ $jar->setCookie('a', 'def', false, '/', 'Wed, 25-Dec-02 04:24:19 GMT');
+ $this->assertEqual($jar->selectAsPairs(new SimpleUrl('/')), array('a=def'));
+ $jar->restartSession('Wed, 25-Dec-02 04:24:20 GMT');
+ $this->assertEqual($jar->selectAsPairs(new SimpleUrl('/')), array());
+ }
+}
+?> \ No newline at end of file
diff --git a/site/vendors/simpletest/test/detached_test.php b/site/vendors/simpletest/test/detached_test.php
new file mode 100644
index 0000000..06db828
--- /dev/null
+++ b/site/vendors/simpletest/test/detached_test.php
@@ -0,0 +1,15 @@
+<?php
+// $Id: detached_test.php 1505 2007-04-30 23:39:59Z lastcraft $
+require_once('../detached.php');
+require_once('../reporter.php');
+
+// The following URL will depend on your own installation.
+$command = 'php ' . dirname(__FILE__) . '/visual_test.php xml';
+
+$test = &new TestSuite('Remote tests');
+$test->addTestCase(new DetachedTestCase($command));
+if (SimpleReporter::inCli()) {
+ exit ($test->run(new TextReporter()) ? 0 : 1);
+}
+$test->run(new HtmlReporter());
+?> \ No newline at end of file
diff --git a/site/vendors/simpletest/test/dumper_test.php b/site/vendors/simpletest/test/dumper_test.php
new file mode 100644
index 0000000..789047d
--- /dev/null
+++ b/site/vendors/simpletest/test/dumper_test.php
@@ -0,0 +1,88 @@
+<?php
+// $Id: dumper_test.php 1505 2007-04-30 23:39:59Z lastcraft $
+require_once(dirname(__FILE__) . '/../autorun.php');
+
+class DumperDummy {
+}
+
+class TestOfTextFormatting extends UnitTestCase {
+
+ function testClipping() {
+ $dumper = new SimpleDumper();
+ $this->assertEqual(
+ $dumper->clipString("Hello", 6),
+ "Hello",
+ "Hello, 6->%s");
+ $this->assertEqual(
+ $dumper->clipString("Hello", 5),
+ "Hello",
+ "Hello, 5->%s");
+ $this->assertEqual(
+ $dumper->clipString("Hello world", 3),
+ "Hel...",
+ "Hello world, 3->%s");
+ $this->assertEqual(
+ $dumper->clipString("Hello world", 6, 3),
+ "Hello ...",
+ "Hello world, 6, 3->%s");
+ $this->assertEqual(
+ $dumper->clipString("Hello world", 3, 6),
+ "...o w...",
+ "Hello world, 3, 6->%s");
+ $this->assertEqual(
+ $dumper->clipString("Hello world", 4, 11),
+ "...orld",
+ "Hello world, 4, 11->%s");
+ $this->assertEqual(
+ $dumper->clipString("Hello world", 4, 12),
+ "...orld",
+ "Hello world, 4, 12->%s");
+ }
+
+ function testDescribeNull() {
+ $dumper = new SimpleDumper();
+ $this->assertPattern('/null/i', $dumper->describeValue(null));
+ }
+
+ function testDescribeBoolean() {
+ $dumper = new SimpleDumper();
+ $this->assertPattern('/boolean/i', $dumper->describeValue(true));
+ $this->assertPattern('/true/i', $dumper->describeValue(true));
+ $this->assertPattern('/false/i', $dumper->describeValue(false));
+ }
+
+ function testDescribeString() {
+ $dumper = new SimpleDumper();
+ $this->assertPattern('/string/i', $dumper->describeValue('Hello'));
+ $this->assertPattern('/Hello/', $dumper->describeValue('Hello'));
+ }
+
+ function testDescribeInteger() {
+ $dumper = new SimpleDumper();
+ $this->assertPattern('/integer/i', $dumper->describeValue(35));
+ $this->assertPattern('/35/', $dumper->describeValue(35));
+ }
+
+ function testDescribeFloat() {
+ $dumper = new SimpleDumper();
+ $this->assertPattern('/float/i', $dumper->describeValue(0.99));
+ $this->assertPattern('/0\.99/', $dumper->describeValue(0.99));
+ }
+
+ function testDescribeArray() {
+ $dumper = new SimpleDumper();
+ $this->assertPattern('/array/i', $dumper->describeValue(array(1, 4)));
+ $this->assertPattern('/2/i', $dumper->describeValue(array(1, 4)));
+ }
+
+ function testDescribeObject() {
+ $dumper = new SimpleDumper();
+ $this->assertPattern(
+ '/object/i',
+ $dumper->describeValue(new DumperDummy()));
+ $this->assertPattern(
+ '/DumperDummy/i',
+ $dumper->describeValue(new DumperDummy()));
+ }
+}
+?> \ No newline at end of file
diff --git a/site/vendors/simpletest/test/eclipse_test.php b/site/vendors/simpletest/test/eclipse_test.php
new file mode 100644
index 0000000..0f1bf4b
--- /dev/null
+++ b/site/vendors/simpletest/test/eclipse_test.php
@@ -0,0 +1,32 @@
+<?php
+// $Id: eclipse_test.php 1505 2007-04-30 23:39:59Z lastcraft $
+
+//To run this from the eclipse plugin...you need to make sure that the
+//SimpleTest path in the preferences is the same as the location of the
+//eclipse.php file below otherwise you end up with two "different" eclipse.php
+//files included and that does not work...
+
+include_once(dirname(__FILE__) . '/../eclipse.php');
+Mock::generate('SimpleSocket');
+
+class TestOfEclipse extends UnitTestCase {
+
+ function testPass() {
+ $listener = &new MockSimpleSocket();
+
+ $fullpath = realpath(dirname(__FILE__).'/support/test1.php');
+ $testpath = EclipseReporter::escapeVal($fullpath);
+ $expected = "{status:\"pass\",message:\"pass1 at [$testpath line 4]\",group:\"$testpath\",case:\"test1\",method:\"test_pass\"}";
+ //this should work...but it doesn't so the next line and the last line are the hacks
+ //$listener->expectOnce('write',array($expected));
+ $listener->setReturnValue('write',-1);
+
+ $pathparts = pathinfo($fullpath);
+ $filename = $pathparts['basename'];
+ $test= &new TestSuite($filename);
+ $test->addTestFile($fullpath);
+ $test->run(new EclipseReporter(&$listener));
+ $this->assertEqual($expected,$listener->output);
+ }
+}
+?> \ No newline at end of file
diff --git a/site/vendors/simpletest/test/encoding_test.php b/site/vendors/simpletest/test/encoding_test.php
new file mode 100644
index 0000000..95031fb
--- /dev/null
+++ b/site/vendors/simpletest/test/encoding_test.php
@@ -0,0 +1,213 @@
+<?php
+// $Id: encoding_test.php 1571 2007-09-07 17:14:32Z pp11 $
+require_once(dirname(__FILE__) . '/../autorun.php');
+require_once(dirname(__FILE__) . '/../url.php');
+require_once(dirname(__FILE__) . '/../socket.php');
+
+Mock::generate('SimpleSocket');
+
+class TestOfEncodedParts extends UnitTestCase {
+
+ function testFormEncodedAsKeyEqualsValue() {
+ $pair = new SimpleEncodedPair('a', 'A');
+ $this->assertEqual($pair->asRequest(), 'a=A');
+ }
+
+ function testMimeEncodedAsHeadersAndContent() {
+ $pair = new SimpleEncodedPair('a', 'A');
+ $this->assertEqual(
+ $pair->asMime(),
+ "Content-Disposition: form-data; name=\"a\"\r\n\r\nA");
+ }
+
+ function testAttachmentEncodedAsHeadersWithDispositionAndContent() {
+ $part = new SimpleAttachment('a', 'A', 'aaa.txt');
+ $this->assertEqual(
+ $part->asMime(),
+ "Content-Disposition: form-data; name=\"a\"; filename=\"aaa.txt\"\r\n" .
+ "Content-Type: text/plain\r\n\r\nA");
+ }
+}
+
+class TestOfEncoding extends UnitTestCase {
+ var $_content_so_far;
+
+ function write($content) {
+ $this->_content_so_far .= $content;
+ }
+
+ function clear() {
+ $this->_content_so_far = '';
+ }
+
+ function assertWritten($encoding, $content, $message = '%s') {
+ $this->clear();
+ $encoding->writeTo($this);
+ $this->assertIdentical($this->_content_so_far, $content, $message);
+ }
+
+ function testGetEmpty() {
+ $encoding = &new SimpleGetEncoding();
+ $this->assertIdentical($encoding->getValue('a'), false);
+ $this->assertIdentical($encoding->asUrlRequest(), '');
+ }
+
+ function testPostEmpty() {
+ $encoding = &new SimplePostEncoding();
+ $this->assertIdentical($encoding->getValue('a'), false);
+ $this->assertWritten($encoding, '');
+ }
+
+ function testPrefilled() {
+ $encoding = &new SimplePostEncoding(array('a' => 'aaa'));
+ $this->assertIdentical($encoding->getValue('a'), 'aaa');
+ $this->assertWritten($encoding, 'a=aaa');
+ }
+
+ function testPrefilledWithTwoLevels() {
+ $query = array('a' => array('aa' => 'aaa'));
+ $encoding = &new SimplePostEncoding($query);
+ $this->assertTrue($encoding->hasMoreThanOneLevel($query));
+ $this->assertEqual($encoding->rewriteArrayWithMultipleLevels($query), array('a[aa]' => 'aaa'));
+ $this->assertIdentical($encoding->getValue('a[aa]'), 'aaa');
+ $this->assertWritten($encoding, 'a%5Baa%5D=aaa');
+ }
+
+ function testPrefilledWithThreeLevels() {
+ $query = array('a' => array('aa' => array('aaa' => 'aaaa')));
+ $encoding = &new SimplePostEncoding($query);
+ $this->assertTrue($encoding->hasMoreThanOneLevel($query));
+ $this->assertEqual($encoding->rewriteArrayWithMultipleLevels($query), array('a[aa][aaa]' => 'aaaa'));
+ $this->assertIdentical($encoding->getValue('a[aa][aaa]'), 'aaaa');
+ $this->assertWritten($encoding, 'a%5Baa%5D%5Baaa%5D=aaaa');
+ }
+
+ function testPrefilledWithObject() {
+ $encoding = &new SimplePostEncoding(new SimpleEncoding(array('a' => 'aaa')));
+ $this->assertIdentical($encoding->getValue('a'), 'aaa');
+ $this->assertWritten($encoding, 'a=aaa');
+ }
+
+ function testMultiplePrefilled() {
+ $query = array('a' => array('a1', 'a2'));
+ $encoding = &new SimplePostEncoding($query);
+ $this->assertTrue($encoding->hasMoreThanOneLevel($query));
+ $this->assertEqual($encoding->rewriteArrayWithMultipleLevels($query), array('a[0]' => 'a1', 'a[1]' => 'a2'));
+ $this->assertIdentical($encoding->getValue('a[0]'), 'a1');
+ $this->assertIdentical($encoding->getValue('a[1]'), 'a2');
+ $this->assertWritten($encoding, 'a%5B0%5D=a1&a%5B1%5D=a2');
+ }
+
+ function testSingleParameter() {
+ $encoding = &new SimplePostEncoding();
+ $encoding->add('a', 'Hello');
+ $this->assertEqual($encoding->getValue('a'), 'Hello');
+ $this->assertWritten($encoding, 'a=Hello');
+ }
+
+ function testFalseParameter() {
+ $encoding = &new SimplePostEncoding();
+ $encoding->add('a', false);
+ $this->assertEqual($encoding->getValue('a'), false);
+ $this->assertWritten($encoding, '');
+ }
+
+ function testUrlEncoding() {
+ $encoding = &new SimplePostEncoding();
+ $encoding->add('a', 'Hello there!');
+ $this->assertWritten($encoding, 'a=Hello+there%21');
+ }
+
+ function testUrlEncodingOfKey() {
+ $encoding = &new SimplePostEncoding();
+ $encoding->add('a!', 'Hello');
+ $this->assertWritten($encoding, 'a%21=Hello');
+ }
+
+ function testMultipleParameter() {
+ $encoding = &new SimplePostEncoding();
+ $encoding->add('a', 'Hello');
+ $encoding->add('b', 'Goodbye');
+ $this->assertWritten($encoding, 'a=Hello&b=Goodbye');
+ }
+
+ function testEmptyParameters() {
+ $encoding = &new SimplePostEncoding();
+ $encoding->add('a', '');
+ $encoding->add('b', '');
+ $this->assertWritten($encoding, 'a=&b=');
+ }
+
+ function testRepeatedParameter() {
+ $encoding = &new SimplePostEncoding();
+ $encoding->add('a', 'Hello');
+ $encoding->add('a', 'Goodbye');
+ $this->assertIdentical($encoding->getValue('a'), array('Hello', 'Goodbye'));
+ $this->assertWritten($encoding, 'a=Hello&a=Goodbye');
+ }
+
+ function testAddingLists() {
+ $encoding = &new SimplePostEncoding();
+ $encoding->add('a', array('Hello', 'Goodbye'));
+ $this->assertIdentical($encoding->getValue('a'), array('Hello', 'Goodbye'));
+ $this->assertWritten($encoding, 'a=Hello&a=Goodbye');
+ }
+
+ function testMergeInHash() {
+ $encoding = &new SimpleGetEncoding(array('a' => 'A1', 'b' => 'B'));
+ $encoding->merge(array('a' => 'A2'));
+ $this->assertIdentical($encoding->getValue('a'), array('A1', 'A2'));
+ $this->assertIdentical($encoding->getValue('b'), 'B');
+ }
+
+ function testMergeInObject() {
+ $encoding = &new SimpleGetEncoding(array('a' => 'A1', 'b' => 'B'));
+ $encoding->merge(new SimpleEncoding(array('a' => 'A2')));
+ $this->assertIdentical($encoding->getValue('a'), array('A1', 'A2'));
+ $this->assertIdentical($encoding->getValue('b'), 'B');
+ }
+
+ function testPrefilledMultipart() {
+ $encoding = &new SimpleMultipartEncoding(array('a' => 'aaa'), 'boundary');
+ $this->assertIdentical($encoding->getValue('a'), 'aaa');
+ $this->assertwritten($encoding,
+ "--boundary\r\n" .
+ "Content-Disposition: form-data; name=\"a\"\r\n" .
+ "\r\n" .
+ "aaa\r\n" .
+ "--boundary--\r\n");
+ }
+
+ function testAttachment() {
+ $encoding = &new SimpleMultipartEncoding(array(), 'boundary');
+ $encoding->attach('a', 'aaa', 'aaa.txt');
+ $this->assertIdentical($encoding->getValue('a'), 'aaa.txt');
+ $this->assertwritten($encoding,
+ "--boundary\r\n" .
+ "Content-Disposition: form-data; name=\"a\"; filename=\"aaa.txt\"\r\n" .
+ "Content-Type: text/plain\r\n" .
+ "\r\n" .
+ "aaa\r\n" .
+ "--boundary--\r\n");
+ }
+}
+
+class TestOfFormHeaders extends UnitTestCase {
+
+ function testEmptyEncodingWritesZeroContentLength() {
+ $socket = &new MockSimpleSocket();
+ $socket->expectArgumentsAt(0, 'write', array("Content-Length: 0\r\n"));
+ $socket->expectArgumentsAt(1, 'write', array("Content-Type: application/x-www-form-urlencoded\r\n"));
+ $encoding = &new SimplePostEncoding();
+ $encoding->writeHeadersTo($socket);
+ }
+
+ function testEmptyMultipartEncodingWritesEndBoundaryContentLength() {
+ $socket = &new MockSimpleSocket();
+ $socket->expectArgumentsAt(0, 'write', array("Content-Length: 14\r\n"));
+ $socket->expectArgumentsAt(1, 'write', array("Content-Type: multipart/form-data, boundary=boundary\r\n"));
+ $encoding = &new SimpleMultipartEncoding(array(), 'boundary');
+ $encoding->writeHeadersTo($socket);
+ }
+}
+?> \ No newline at end of file
diff --git a/site/vendors/simpletest/test/errors_test.php b/site/vendors/simpletest/test/errors_test.php
new file mode 100644
index 0000000..7db8769
--- /dev/null
+++ b/site/vendors/simpletest/test/errors_test.php
@@ -0,0 +1,300 @@
+<?php
+require_once(dirname(__FILE__) . '/../autorun.php');
+require_once(dirname(__FILE__) . '/../errors.php');
+require_once(dirname(__FILE__) . '/../expectation.php');
+require_once(dirname(__FILE__) . '/../test_case.php');
+Mock::generate('SimpleTestCase');
+Mock::generate('SimpleExpectation');
+SimpleTest::ignore('MockSimpleTestCase');
+
+class TestOfErrorQueue extends UnitTestCase {
+
+ function setUp() {
+ $context = &SimpleTest::getContext();
+ $queue = &$context->get('SimpleErrorQueue');
+ $queue->clear();
+ }
+
+ function tearDown() {
+ $context = &SimpleTest::getContext();
+ $queue = &$context->get('SimpleErrorQueue');
+ $queue->clear();
+ }
+
+ function testOrder() {
+ $context = &SimpleTest::getContext();
+ $queue = &$context->get('SimpleErrorQueue');
+ $queue->add(1024, 'Ouch', 'here.php', 100);
+ $queue->add(512, 'Yuk', 'there.php', 101);
+ $this->assertEqual(
+ $queue->extract(),
+ array(1024, 'Ouch', 'here.php', 100));
+ $this->assertEqual(
+ $queue->extract(),
+ array(512, 'Yuk', 'there.php', 101));
+ $this->assertFalse($queue->extract());
+ }
+
+ function testAssertNoErrorsGivesTrueWhenNoErrors() {
+ $test = &new MockSimpleTestCase();
+ $test->expectOnce('assert', array(
+ new IdenticalExpectation(new TrueExpectation()),
+ true,
+ 'Should be no errors'));
+ $test->setReturnValue('assert', true);
+ $queue = &new SimpleErrorQueue();
+ $queue->setTestCase($test);
+ $this->assertTrue($queue->assertNoErrors('%s'));
+ }
+
+ function testAssertNoErrorsIssuesFailWhenErrors() {
+ $test = &new MockSimpleTestCase();
+ $test->expectOnce('assert', array(
+ new IdenticalExpectation(new TrueExpectation()),
+ false,
+ 'Should be no errors'));
+ $test->setReturnValue('assert', false);
+ $queue = &new SimpleErrorQueue();
+ $queue->setTestCase($test);
+ $queue->add(1024, 'Ouch', 'here.php', 100);
+ $this->assertFalse($queue->assertNoErrors('%s'));
+ }
+
+ function testAssertErrorFailsWhenNoError() {
+ $test = &new MockSimpleTestCase();
+ $test->expectOnce('fail', array('Expected error not found'));
+ $test->setReturnValue('assert', false);
+ $queue = &new SimpleErrorQueue();
+ $queue->setTestCase($test);
+ $this->assertFalse($queue->assertError(false, '%s'));
+ }
+
+ function testAssertErrorFailsWhenErrorDoesntMatchTheExpectation() {
+ $test = &new MockSimpleTestCase();
+ $test->expectOnce('assert', array(
+ new IdenticalExpectation(new FailedExpectation()),
+ 'B',
+ 'Expected PHP error [B] severity [E_USER_NOTICE] in [b.php] line [100]'));
+ $test->setReturnValue('assert', false);
+ $queue = &new SimpleErrorQueue();
+ $queue->setTestCase($test);
+ $queue->add(1024, 'B', 'b.php', 100);
+ $this->assertFalse($queue->assertError(new FailedExpectation(), '%s'));
+ }
+
+ function testExpectationMatchCancelsIncomingError() {
+ $test = &new MockSimpleTestCase();
+ $test->expectOnce('assert', array(
+ new IdenticalExpectation(new AnythingExpectation()),
+ 'B',
+ 'a message'));
+ $test->setReturnValue('assert', true);
+ $test->expectNever('error');
+ $queue = &new SimpleErrorQueue();
+ $queue->setTestCase($test);
+ $queue->expectError(new AnythingExpectation(), 'a message');
+ $queue->add(1024, 'B', 'b.php', 100);
+ }
+}
+
+class TestOfErrorTrap extends UnitTestCase {
+ var $_old;
+
+ function setUp() {
+ $this->_old = error_reporting(E_ALL);
+ set_error_handler('SimpleTestErrorHandler');
+ }
+
+ function tearDown() {
+ restore_error_handler();
+ error_reporting($this->_old);
+ }
+
+ function testQueueStartsEmpty() {
+ $context = &SimpleTest::getContext();
+ $queue = &$context->get('SimpleErrorQueue');
+ $this->assertFalse($queue->extract());
+ }
+
+ function testTrappedErrorPlacedInQueue() {
+ trigger_error('Ouch!');
+ $context = &SimpleTest::getContext();
+ $queue = &$context->get('SimpleErrorQueue');
+ list($severity, $message, $file, $line) = $queue->extract();
+ $this->assertEqual($message, 'Ouch!');
+ $this->assertEqual($file, __FILE__);
+ $this->assertFalse($queue->extract());
+ }
+
+ function testErrorsAreSwallowedByMatchingExpectation() {
+ $this->expectError('Ouch!');
+ trigger_error('Ouch!');
+ }
+
+ function testErrorsAreSwallowedInOrder() {
+ $this->expectError('a');
+ $this->expectError('b');
+ trigger_error('a');
+ trigger_error('b');
+ }
+
+ function testAnyErrorCanBeSwallowed() {
+ $this->expectError();
+ trigger_error('Ouch!');
+ }
+
+ function testErrorCanBeSwallowedByPatternMatching() {
+ $this->expectError(new PatternExpectation('/ouch/i'));
+ trigger_error('Ouch!');
+ }
+
+ function testErrorWithPercentsPassesWithNoSprintfError() {
+ $this->expectError("%");
+ trigger_error('%');
+ }
+}
+
+class TestOfErrors extends UnitTestCase {
+ var $_old;
+
+ function setUp() {
+ $this->_old = error_reporting(E_ALL);
+ }
+
+ function tearDown() {
+ error_reporting($this->_old);
+ }
+
+ function testDefaultWhenAllReported() {
+ error_reporting(E_ALL);
+ trigger_error('Ouch!');
+ $this->assertError('Ouch!');
+ }
+
+ function testNoticeWhenReported() {
+ error_reporting(E_ALL);
+ trigger_error('Ouch!', E_USER_NOTICE);
+ $this->assertError('Ouch!');
+ }
+
+ function testWarningWhenReported() {
+ error_reporting(E_ALL);
+ trigger_error('Ouch!', E_USER_WARNING);
+ $this->assertError('Ouch!');
+ }
+
+ function testErrorWhenReported() {
+ error_reporting(E_ALL);
+ trigger_error('Ouch!', E_USER_ERROR);
+ $this->assertError('Ouch!');
+ }
+
+ function testNoNoticeWhenNotReported() {
+ error_reporting(0);
+ trigger_error('Ouch!', E_USER_NOTICE);
+ }
+
+ function testNoWarningWhenNotReported() {
+ error_reporting(0);
+ trigger_error('Ouch!', E_USER_WARNING);
+ }
+
+ function testNoticeSuppressedWhenReported() {
+ error_reporting(E_ALL);
+ @trigger_error('Ouch!', E_USER_NOTICE);
+ }
+
+ function testWarningSuppressedWhenReported() {
+ error_reporting(E_ALL);
+ @trigger_error('Ouch!', E_USER_WARNING);
+ }
+
+ function testErrorWithPercentsReportedWithNoSprintfError() {
+ trigger_error('%');
+ $this->assertError('%');
+ }
+}
+
+class TestOfPHP52RecoverableErrors extends UnitTestCase {
+ function skip() {
+ $this->skipIf(
+ version_compare(phpversion(), '5.2', '<'),
+ 'E_RECOVERABLE_ERROR not tested for PHP below 5.2');
+ }
+
+ function testError() {
+ eval('
+ class RecoverableErrorTestingStub {
+ function ouch(RecoverableErrorTestingStub $obj) {
+ }
+ }
+ ');
+
+ $stub = new RecoverableErrorTestingStub();
+ $this->expectError(new PatternExpectation('/must be an instance of RecoverableErrorTestingStub/i'));
+ $stub->ouch(new stdClass());
+ }
+}
+
+class TestOfErrorsExcludingPHP52AndAbove extends UnitTestCase {
+ function skip() {
+ $this->skipIf(
+ version_compare(phpversion(), '5.2', '>='),
+ 'E_USER_ERROR not tested for PHP 5.2 and above');
+ }
+
+ function testNoErrorWhenNotReported() {
+ error_reporting(0);
+ trigger_error('Ouch!', E_USER_ERROR);
+ }
+
+ function testErrorSuppressedWhenReported() {
+ error_reporting(E_ALL);
+ @trigger_error('Ouch!', E_USER_ERROR);
+ }
+}
+
+SimpleTest::ignore('TestOfNotEnoughErrors');
+/**
+ * This test is ignored as it is used by {@link TestRunnerForLeftOverAndNotEnoughErrors}
+ * to verify that it fails as expected.
+ *
+ * @ignore
+ */
+class TestOfNotEnoughErrors extends UnitTestCase {
+ function testExpectTwoErrorsThrowOne() {
+ $this->expectError('Error 1');
+ trigger_error('Error 1');
+ $this->expectError('Error 2');
+ }
+}
+
+SimpleTest::ignore('TestOfLeftOverErrors');
+/**
+ * This test is ignored as it is used by {@link TestRunnerForLeftOverAndNotEnoughErrors}
+ * to verify that it fails as expected.
+ *
+ * @ignore
+ */
+class TestOfLeftOverErrors extends UnitTestCase {
+ function testExpectOneErrorGetTwo() {
+ $this->expectError('Error 1');
+ trigger_error('Error 1');
+ trigger_error('Error 2');
+ }
+}
+
+class TestRunnerForLeftOverAndNotEnoughErrors extends UnitTestCase {
+ function testRunLeftOverErrorsTestCase() {
+ $test = new TestOfLeftOverErrors();
+ $this->assertFalse($test->run(new SimpleReporter()));
+ }
+
+ function testRunNotEnoughErrors() {
+ $test = new TestOfNotEnoughErrors();
+ $this->assertFalse($test->run(new SimpleReporter()));
+ }
+}
+
+// TODO: Add stacked error handler test
+?> \ No newline at end of file
diff --git a/site/vendors/simpletest/test/exceptions_test.php b/site/vendors/simpletest/test/exceptions_test.php
new file mode 100644
index 0000000..9cc35c5
--- /dev/null
+++ b/site/vendors/simpletest/test/exceptions_test.php
@@ -0,0 +1,153 @@
+<?php
+// $Id: exceptions_test.php 1618 2007-12-29 22:52:30Z lastcraft $
+require_once(dirname(__FILE__) . '/../autorun.php');
+require_once(dirname(__FILE__) . '/../exceptions.php');
+require_once(dirname(__FILE__) . '/../expectation.php');
+require_once(dirname(__FILE__) . '/../test_case.php');
+Mock::generate('SimpleTestCase');
+Mock::generate('SimpleExpectation');
+
+class MyTestException extends Exception {}
+class HigherTestException extends MyTestException {}
+class OtherTestException extends Exception {}
+
+class TestOfExceptionExpectation extends UnitTestCase {
+
+ function testExceptionClassAsStringWillMatchExceptionsRootedOnThatClass() {
+ $expectation = new ExceptionExpectation('MyTestException');
+ $this->assertTrue($expectation->test(new MyTestException()));
+ $this->assertTrue($expectation->test(new HigherTestException()));
+ $this->assertFalse($expectation->test(new OtherTestException()));
+ }
+
+ function testMatchesClassAndMessageWhenExceptionExpected() {
+ $expectation = new ExceptionExpectation(new MyTestException('Hello'));
+ $this->assertTrue($expectation->test(new MyTestException('Hello')));
+ $this->assertFalse($expectation->test(new HigherTestException('Hello')));
+ $this->assertFalse($expectation->test(new OtherTestException('Hello')));
+ $this->assertFalse($expectation->test(new MyTestException('Goodbye')));
+ $this->assertFalse($expectation->test(new MyTestException()));
+ }
+
+ function testMessagelessExceptionMatchesOnlyOnClass() {
+ $expectation = new ExceptionExpectation(new MyTestException());
+ $this->assertTrue($expectation->test(new MyTestException()));
+ $this->assertFalse($expectation->test(new HigherTestException()));
+ }
+}
+
+class TestOfExceptionTrap extends UnitTestCase {
+
+ function testNoExceptionsInQueueMeansNoTestMessages() {
+ $test = new MockSimpleTestCase();
+ $test->expectNever('assert');
+ $queue = new SimpleExceptionTrap();
+ $this->assertFalse($queue->isExpected($test, new Exception()));
+ }
+
+ function testMatchingExceptionGivesTrue() {
+ $expectation = new MockSimpleExpectation();
+ $expectation->setReturnValue('test', true);
+ $test = new MockSimpleTestCase();
+ $test->setReturnValue('assert', true);
+ $queue = new SimpleExceptionTrap();
+ $queue->expectException($expectation, 'message');
+ $this->assertTrue($queue->isExpected($test, new Exception()));
+ }
+
+ function testMatchingExceptionTriggersAssertion() {
+ $test = new MockSimpleTestCase();
+ $test->expectOnce('assert', array(
+ '*',
+ new ExceptionExpectation(new Exception()),
+ 'message'));
+ $queue = new SimpleExceptionTrap();
+ $queue->expectException(new ExceptionExpectation(new Exception()), 'message');
+ $queue->isExpected($test, new Exception());
+ }
+}
+
+class TestOfCatchingExceptions extends UnitTestCase {
+
+ function testCanCatchAnyExpectedException() {
+ $this->expectException();
+ throw new Exception();
+ }
+
+ function testCanMatchExceptionByClass() {
+ $this->expectException('MyTestException');
+ throw new HigherTestException();
+ }
+
+ function testCanMatchExceptionExactly() {
+ $this->expectException(new Exception('Ouch'));
+ throw new Exception('Ouch');
+ }
+
+ function testLastListedExceptionIsTheOneThatCounts() {
+ $this->expectException('OtherTestException');
+ $this->expectException('MyTestException');
+ throw new HigherTestException();
+ }
+}
+
+class TestOfCallingTearDownAfterExceptions extends UnitTestCase {
+ private $debri = 0;
+
+ function tearDown() {
+ $this->debri--;
+ }
+
+ function testLeaveSomeDebri() {
+ $this->debri++;
+ $this->expectException();
+ throw new Exception(__FUNCTION__);
+ }
+
+ function testDebriWasRemovedOnce() {
+ $this->assertEqual($this->debri, 0);
+ }
+}
+
+class TestOfExceptionThrownInSetUpDoesNotRunTestBody extends UnitTestCase {
+
+ function setUp() {
+ $this->expectException();
+ throw new Exception();
+ }
+
+ function testShouldNotBeRun() {
+ $this->fail('This test body should not be run');
+ }
+
+ function testShouldNotBeRunEither() {
+ $this->fail('This test body should not be run either');
+ }
+}
+
+class TestOfExpectExceptionWithSetUp extends UnitTestCase {
+
+ function setUp() {
+ $this->expectException();
+ }
+
+ function testThisExceptionShouldBeCaught() {
+ throw new Exception();
+ }
+
+ function testJustThrowingMyTestException() {
+ throw new MyTestException();
+ }
+}
+
+class TestOfThrowingExceptionsInTearDown extends UnitTestCase {
+
+ function tearDown() {
+ throw new Exception();
+ }
+
+ function testDoesntFatal() {
+ $this->expectException();
+ }
+}
+?> \ No newline at end of file
diff --git a/site/vendors/simpletest/test/expectation_test.php b/site/vendors/simpletest/test/expectation_test.php
new file mode 100644
index 0000000..8f4fc38
--- /dev/null
+++ b/site/vendors/simpletest/test/expectation_test.php
@@ -0,0 +1,245 @@
+<?php
+// $Id: expectation_test.php 1539 2007-06-09 08:35:54Z pachanga $
+require_once(dirname(__FILE__) . '/../autorun.php');
+require_once(dirname(__FILE__) . '/../expectation.php');
+
+class TestOfEquality extends UnitTestCase {
+
+ function testBoolean() {
+ $is_true = &new EqualExpectation(true);
+ $this->assertTrue($is_true->test(true));
+ $this->assertFalse($is_true->test(false));
+ }
+
+ function testStringMatch() {
+ $hello = &new EqualExpectation("Hello");
+ $this->assertTrue($hello->test("Hello"));
+ $this->assertFalse($hello->test("Goodbye"));
+ }
+
+ function testInteger() {
+ $fifteen = &new EqualExpectation(15);
+ $this->assertTrue($fifteen->test(15));
+ $this->assertFalse($fifteen->test(14));
+ }
+
+ function testFloat() {
+ $pi = &new EqualExpectation(3.14);
+ $this->assertTrue($pi->test(3.14));
+ $this->assertFalse($pi->test(3.15));
+ }
+
+ function testArray() {
+ $colours = &new EqualExpectation(array("r", "g", "b"));
+ $this->assertTrue($colours->test(array("r", "g", "b")));
+ $this->assertFalse($colours->test(array("g", "b", "r")));
+ }
+
+ function testHash() {
+ $is_blue = &new EqualExpectation(array("r" => 0, "g" => 0, "b" => 255));
+ $this->assertTrue($is_blue->test(array("r" => 0, "g" => 0, "b" => 255)));
+ $this->assertFalse($is_blue->test(array("r" => 0, "g" => 255, "b" => 0)));
+ }
+
+ function testHashWithOutOfOrderKeysShouldStillMatch() {
+ $any_order = &new EqualExpectation(array('a' => 1, 'b' => 2));
+ $this->assertTrue($any_order->test(array('b' => 2, 'a' => 1)));
+ }
+}
+
+class TestOfWithin extends UnitTestCase {
+
+ function testWithinFloatingPointMargin() {
+ $within = new WithinMarginExpectation(1.0, 0.2);
+ $this->assertFalse($within->test(0.7));
+ $this->assertTrue($within->test(0.8));
+ $this->assertTrue($within->test(0.9));
+ $this->assertTrue($within->test(1.1));
+ $this->assertTrue($within->test(1.2));
+ $this->assertFalse($within->test(1.3));
+ }
+
+ function testOutsideFloatingPointMargin() {
+ $within = new OutsideMarginExpectation(1.0, 0.2);
+ $this->assertTrue($within->test(0.7));
+ $this->assertFalse($within->test(0.8));
+ $this->assertFalse($within->test(1.2));
+ $this->assertTrue($within->test(1.3));
+ }
+}
+
+class TestOfInequality extends UnitTestCase {
+
+ function testStringMismatch() {
+ $not_hello = &new NotEqualExpectation("Hello");
+ $this->assertTrue($not_hello->test("Goodbye"));
+ $this->assertFalse($not_hello->test("Hello"));
+ }
+}
+
+class RecursiveNasty {
+ var $_me;
+
+ function RecursiveNasty() {
+ $this->_me = $this;
+ }
+}
+
+class TestOfIdentity extends UnitTestCase {
+
+ function testType() {
+ $string = &new IdenticalExpectation("37");
+ $this->assertTrue($string->test("37"));
+ $this->assertFalse($string->test(37));
+ $this->assertFalse($string->test("38"));
+ }
+
+ function _testNastyPhp5Bug() {
+ $this->assertFalse(new RecursiveNasty() != new RecursiveNasty());
+ }
+
+ function _testReallyHorribleRecursiveStructure() {
+ $hopeful = &new IdenticalExpectation(new RecursiveNasty());
+ $this->assertTrue($hopeful->test(new RecursiveNasty()));
+ }
+}
+
+class DummyReferencedObject{}
+
+class TestOfReference extends UnitTestCase {
+
+ function testReference() {
+ $foo = "foo";
+ $ref =& $foo;
+ $not_ref = $foo;
+ $bar = "bar";
+
+ $expect = &new ReferenceExpectation($foo);
+ $this->assertTrue($expect->test($ref));
+ $this->assertFalse($expect->test($not_ref));
+ $this->assertFalse($expect->test($bar));
+ }
+
+ function testObjectsReferencesDualityForPhp5AndPhp4() {
+ $dummy = new DummyReferencedObject();
+ $ref =& $dummy;
+ $not_ref = $dummy;
+
+ $hopeful = &new ReferenceExpectation($dummy);
+ $this->assertTrue($hopeful->test($ref));
+
+ if (version_compare(phpversion(), '5') >= 0) {
+ $this->assertTrue($hopeful->test($not_ref));
+ } else {
+ $this->assertFalse($hopeful->test($not_ref));
+ }
+ }
+
+ function testReallyHorribleRecursiveStructure() {
+ $nasty = new RecursiveNasty();
+ $ref =& $nasty;
+ $hopeful = &new ReferenceExpectation($nasty);
+ $this->assertTrue($hopeful->test($ref));
+ }
+}
+
+class TestOfNonIdentity extends UnitTestCase {
+
+ function testType() {
+ $string = &new NotIdenticalExpectation("37");
+ $this->assertTrue($string->test("38"));
+ $this->assertTrue($string->test(37));
+ $this->assertFalse($string->test("37"));
+ }
+}
+
+class TestOfPatterns extends UnitTestCase {
+
+ function testWanted() {
+ $pattern = &new PatternExpectation('/hello/i');
+ $this->assertTrue($pattern->test("Hello world"));
+ $this->assertFalse($pattern->test("Goodbye world"));
+ }
+
+ function testUnwanted() {
+ $pattern = &new NoPatternExpectation('/hello/i');
+ $this->assertFalse($pattern->test("Hello world"));
+ $this->assertTrue($pattern->test("Goodbye world"));
+ }
+}
+
+class ExpectedMethodTarget {
+ function hasThisMethod() {}
+}
+
+class TestOfMethodExistence extends UnitTestCase {
+
+ function testHasMethod() {
+ $instance = &new ExpectedMethodTarget();
+ $expectation = &new MethodExistsExpectation('hasThisMethod');
+ $this->assertTrue($expectation->test($instance));
+ $expectation = &new MethodExistsExpectation('doesNotHaveThisMethod');
+ $this->assertFalse($expectation->test($instance));
+ }
+}
+
+class TestOfIsA extends UnitTestCase {
+
+ function testString() {
+ $expectation = &new IsAExpectation('string');
+ $this->assertTrue($expectation->test('Hello'));
+ $this->assertFalse($expectation->test(5));
+ }
+
+ function testBoolean() {
+ $expectation = &new IsAExpectation('boolean');
+ $this->assertTrue($expectation->test(true));
+ $this->assertFalse($expectation->test(1));
+ }
+
+ function testBool() {
+ $expectation = &new IsAExpectation('bool');
+ $this->assertTrue($expectation->test(true));
+ $this->assertFalse($expectation->test(1));
+ }
+
+ function testDouble() {
+ $expectation = &new IsAExpectation('double');
+ $this->assertTrue($expectation->test(5.0));
+ $this->assertFalse($expectation->test(5));
+ }
+
+ function testFloat() {
+ $expectation = &new IsAExpectation('float');
+ $this->assertTrue($expectation->test(5.0));
+ $this->assertFalse($expectation->test(5));
+ }
+
+ function testReal() {
+ $expectation = &new IsAExpectation('real');
+ $this->assertTrue($expectation->test(5.0));
+ $this->assertFalse($expectation->test(5));
+ }
+
+ function testInteger() {
+ $expectation = &new IsAExpectation('integer');
+ $this->assertTrue($expectation->test(5));
+ $this->assertFalse($expectation->test(5.0));
+ }
+
+ function testInt() {
+ $expectation = &new IsAExpectation('int');
+ $this->assertTrue($expectation->test(5));
+ $this->assertFalse($expectation->test(5.0));
+ }
+}
+
+class TestOfNotA extends UnitTestCase {
+
+ function testString() {
+ $expectation = &new NotAExpectation('string');
+ $this->assertFalse($expectation->test('Hello'));
+ $this->assertTrue($expectation->test(5));
+ }
+}
+?> \ No newline at end of file
diff --git a/site/vendors/simpletest/test/form_test.php b/site/vendors/simpletest/test/form_test.php
new file mode 100644
index 0000000..bdc6f67
--- /dev/null
+++ b/site/vendors/simpletest/test/form_test.php
@@ -0,0 +1,323 @@
+<?php
+// $Id: form_test.php 1624 2008-01-01 15:00:43Z pp11 $
+require_once(dirname(__FILE__) . '/../autorun.php');
+require_once(dirname(__FILE__) . '/../url.php');
+require_once(dirname(__FILE__) . '/../form.php');
+require_once(dirname(__FILE__) . '/../page.php');
+require_once(dirname(__FILE__) . '/../encoding.php');
+Mock::generate('SimplePage');
+
+class TestOfForm extends UnitTestCase {
+
+ function &page($url, $action = false) {
+ $page = &new MockSimplePage();
+ $page->setReturnValue('getUrl', new SimpleUrl($url));
+ $page->setReturnValue('expandUrl', new SimpleUrl($url));
+ return $page;
+ }
+
+ function testFormAttributes() {
+ $tag = &new SimpleFormTag(array('method' => 'GET', 'action' => 'here.php', 'id' => '33'));
+ $form = &new SimpleForm($tag, $this->page('http://host/a/index.html'));
+ $this->assertEqual($form->getMethod(), 'get');
+ $this->assertIdentical($form->getId(), '33');
+ $this->assertNull($form->getValue(new SimpleByName('a')));
+ }
+
+ function testAction() {
+ $page = &new MockSimplePage();
+ $page->expectOnce('expandUrl', array(new SimpleUrl('here.php')));
+ $page->setReturnValue('expandUrl', new SimpleUrl('http://host/here.php'));
+ $tag = &new SimpleFormTag(array('method' => 'GET', 'action' => 'here.php'));
+ $form = &new SimpleForm($tag, $page);
+ $this->assertEqual($form->getAction(), new SimpleUrl('http://host/here.php'));
+ }
+
+ function testEmptyAction() {
+ $tag = &new SimpleFormTag(array('method' => 'GET', 'action' => '', 'id' => '33'));
+ $form = &new SimpleForm($tag, $this->page('http://host/a/index.html'));
+ $this->assertEqual(
+ $form->getAction(),
+ new SimpleUrl('http://host/a/index.html'));
+ }
+
+ function testMissingAction() {
+ $tag = &new SimpleFormTag(array('method' => 'GET'));
+ $form = &new SimpleForm($tag, $this->page('http://host/a/index.html'));
+ $this->assertEqual(
+ $form->getAction(),
+ new SimpleUrl('http://host/a/index.html'));
+ }
+
+ function testRootAction() {
+ $page = &new MockSimplePage();
+ $page->expectOnce('expandUrl', array(new SimpleUrl('/')));
+ $page->setReturnValue('expandUrl', new SimpleUrl('http://host/'));
+ $tag = &new SimpleFormTag(array('method' => 'GET', 'action' => '/'));
+ $form = &new SimpleForm($tag, $page);
+ $this->assertEqual(
+ $form->getAction(),
+ new SimpleUrl('http://host/'));
+ }
+
+ function testDefaultFrameTargetOnForm() {
+ $page = &new MockSimplePage();
+ $page->expectOnce('expandUrl', array(new SimpleUrl('here.php')));
+ $page->setReturnValue('expandUrl', new SimpleUrl('http://host/here.php'));
+ $tag = &new SimpleFormTag(array('method' => 'GET', 'action' => 'here.php'));
+ $form = &new SimpleForm($tag, $page);
+ $form->setDefaultTarget('frame');
+ $expected = new SimpleUrl('http://host/here.php');
+ $expected->setTarget('frame');
+ $this->assertEqual($form->getAction(), $expected);
+ }
+
+ function testTextWidget() {
+ $form = &new SimpleForm(new SimpleFormTag(array()), $this->page('htp://host'));
+ $form->addWidget(new SimpleTextTag(
+ array('name' => 'me', 'type' => 'text', 'value' => 'Myself')));
+ $this->assertIdentical($form->getValue(new SimpleByName('me')), 'Myself');
+ $this->assertTrue($form->setField(new SimpleByName('me'), 'Not me'));
+ $this->assertFalse($form->setField(new SimpleByName('not_present'), 'Not me'));
+ $this->assertIdentical($form->getValue(new SimpleByName('me')), 'Not me');
+ $this->assertNull($form->getValue(new SimpleByName('not_present')));
+ }
+
+ function testTextWidgetById() {
+ $form = &new SimpleForm(new SimpleFormTag(array()), $this->page('htp://host'));
+ $form->addWidget(new SimpleTextTag(
+ array('name' => 'me', 'type' => 'text', 'value' => 'Myself', 'id' => 50)));
+ $this->assertIdentical($form->getValue(new SimpleById(50)), 'Myself');
+ $this->assertTrue($form->setField(new SimpleById(50), 'Not me'));
+ $this->assertIdentical($form->getValue(new SimpleById(50)), 'Not me');
+ }
+
+ function testTextWidgetByLabel() {
+ $form = &new SimpleForm(new SimpleFormTag(array()), $this->page('htp://host'));
+ $widget = &new SimpleTextTag(array('name' => 'me', 'type' => 'text', 'value' => 'a'));
+ $form->addWidget($widget);
+ $widget->setLabel('thing');
+ $this->assertIdentical($form->getValue(new SimpleByLabel('thing')), 'a');
+ $this->assertTrue($form->setField(new SimpleByLabel('thing'), 'b'));
+ $this->assertIdentical($form->getValue(new SimpleByLabel('thing')), 'b');
+ }
+
+ function testSubmitEmpty() {
+ $form = &new SimpleForm(new SimpleFormTag(array()), $this->page('htp://host'));
+ $this->assertIdentical($form->submit(), new SimpleGetEncoding());
+ }
+
+ function testSubmitButton() {
+ $form = &new SimpleForm(new SimpleFormTag(array()), $this->page('http://host'));
+ $form->addWidget(new SimpleSubmitTag(
+ array('type' => 'submit', 'name' => 'go', 'value' => 'Go!', 'id' => '9')));
+ $this->assertTrue($form->hasSubmit(new SimpleByName('go')));
+ $this->assertEqual($form->getValue(new SimpleByName('go')), 'Go!');
+ $this->assertEqual($form->getValue(new SimpleById(9)), 'Go!');
+ $this->assertEqual(
+ $form->submitButton(new SimpleByName('go')),
+ new SimpleGetEncoding(array('go' => 'Go!')));
+ $this->assertEqual(
+ $form->submitButton(new SimpleByLabel('Go!')),
+ new SimpleGetEncoding(array('go' => 'Go!')));
+ $this->assertEqual(
+ $form->submitButton(new SimpleById(9)),
+ new SimpleGetEncoding(array('go' => 'Go!')));
+ }
+
+ function testSubmitWithAdditionalParameters() {
+ $form = &new SimpleForm(new SimpleFormTag(array()), $this->page('http://host'));
+ $form->addWidget(new SimpleSubmitTag(
+ array('type' => 'submit', 'name' => 'go', 'value' => 'Go!')));
+ $this->assertEqual(
+ $form->submitButton(new SimpleByLabel('Go!'), array('a' => 'A')),
+ new SimpleGetEncoding(array('go' => 'Go!', 'a' => 'A')));
+ }
+
+ function testSubmitButtonWithLabelOfSubmit() {
+ $form = &new SimpleForm(new SimpleFormTag(array()), $this->page('http://host'));
+ $form->addWidget(new SimpleSubmitTag(
+ array('type' => 'submit', 'name' => 'test', 'value' => 'Submit')));
+ $this->assertEqual(
+ $form->submitButton(new SimpleByName('test')),
+ new SimpleGetEncoding(array('test' => 'Submit')));
+ $this->assertEqual(
+ $form->submitButton(new SimpleByLabel('Submit')),
+ new SimpleGetEncoding(array('test' => 'Submit')));
+ }
+
+ function testSubmitButtonWithWhitespacePaddedLabelOfSubmit() {
+ $form = &new SimpleForm(new SimpleFormTag(array()), $this->page('http://host'));
+ $form->addWidget(new SimpleSubmitTag(
+ array('type' => 'submit', 'name' => 'test', 'value' => ' Submit ')));
+ $this->assertEqual(
+ $form->submitButton(new SimpleByLabel('Submit')),
+ new SimpleGetEncoding(array('test' => ' Submit ')));
+ }
+
+ function testImageSubmitButton() {
+ $form = &new SimpleForm(new SimpleFormTag(array()), $this->page('htp://host'));
+ $form->addWidget(new SimpleImageSubmitTag(array(
+ 'type' => 'image',
+ 'src' => 'source.jpg',
+ 'name' => 'go',
+ 'alt' => 'Go!',
+ 'id' => '9')));
+ $this->assertTrue($form->hasImage(new SimpleByLabel('Go!')));
+ $this->assertEqual(
+ $form->submitImage(new SimpleByLabel('Go!'), 100, 101),
+ new SimpleGetEncoding(array('go.x' => 100, 'go.y' => 101)));
+ $this->assertTrue($form->hasImage(new SimpleByName('go')));
+ $this->assertEqual(
+ $form->submitImage(new SimpleByName('go'), 100, 101),
+ new SimpleGetEncoding(array('go.x' => 100, 'go.y' => 101)));
+ $this->assertTrue($form->hasImage(new SimpleById(9)));
+ $this->assertEqual(
+ $form->submitImage(new SimpleById(9), 100, 101),
+ new SimpleGetEncoding(array('go.x' => 100, 'go.y' => 101)));
+ }
+
+ function testImageSubmitButtonWithAdditionalData() {
+ $form = &new SimpleForm(new SimpleFormTag(array()), $this->page('htp://host'));
+ $form->addWidget(new SimpleImageSubmitTag(array(
+ 'type' => 'image',
+ 'src' => 'source.jpg',
+ 'name' => 'go',
+ 'alt' => 'Go!')));
+ $this->assertEqual(
+ $form->submitImage(new SimpleByLabel('Go!'), 100, 101, array('a' => 'A')),
+ new SimpleGetEncoding(array('go.x' => 100, 'go.y' => 101, 'a' => 'A')));
+ }
+
+ function testButtonTag() {
+ $form = &new SimpleForm(new SimpleFormTag(array()), $this->page('http://host'));
+ $widget = &new SimpleButtonTag(
+ array('type' => 'submit', 'name' => 'go', 'value' => 'Go', 'id' => '9'));
+ $widget->addContent('Go!');
+ $form->addWidget($widget);
+ $this->assertTrue($form->hasSubmit(new SimpleByName('go')));
+ $this->assertTrue($form->hasSubmit(new SimpleByLabel('Go!')));
+ $this->assertEqual(
+ $form->submitButton(new SimpleByName('go')),
+ new SimpleGetEncoding(array('go' => 'Go')));
+ $this->assertEqual(
+ $form->submitButton(new SimpleByLabel('Go!')),
+ new SimpleGetEncoding(array('go' => 'Go')));
+ $this->assertEqual(
+ $form->submitButton(new SimpleById(9)),
+ new SimpleGetEncoding(array('go' => 'Go')));
+ }
+
+ function testMultipleFieldsWithSameNameSubmitted() {
+ $form = &new SimpleForm(new SimpleFormTag(array()), $this->page('htp://host'));
+ $input = &new SimpleTextTag(array('name' => 'elements[]', 'value' => '1'));
+ $form->addWidget($input);
+ $input = &new SimpleTextTag(array('name' => 'elements[]', 'value' => '2'));
+ $form->addWidget($input);
+ $form->setField(new SimpleByLabelOrName('elements[]'), '3', 1);
+ $form->setField(new SimpleByLabelOrName('elements[]'), '4', 2);
+ $submit = $form->submit();
+ $this->assertEqual(count($submit->_request), 2);
+ $this->assertIdentical($submit->_request[0], new SimpleEncodedPair('elements[]', '3'));
+ $this->assertIdentical($submit->_request[1], new SimpleEncodedPair('elements[]', '4'));
+ }
+
+ function testSingleSelectFieldSubmitted() {
+ $form = &new SimpleForm(new SimpleFormTag(array()), $this->page('htp://host'));
+ $select = &new SimpleSelectionTag(array('name' => 'a'));
+ $select->addTag(new SimpleOptionTag(
+ array('value' => 'aaa', 'selected' => '')));
+ $form->addWidget($select);
+ $this->assertIdentical(
+ $form->submit(),
+ new SimpleGetEncoding(array('a' => 'aaa')));
+ }
+
+ function testSingleSelectFieldSubmittedWithPost() {
+ $form = &new SimpleForm(new SimpleFormTag(array('method' => 'post')), $this->page('htp://host'));
+ $select = &new SimpleSelectionTag(array('name' => 'a'));
+ $select->addTag(new SimpleOptionTag(
+ array('value' => 'aaa', 'selected' => '')));
+ $form->addWidget($select);
+ $this->assertIdentical(
+ $form->submit(),
+ new SimplePostEncoding(array('a' => 'aaa')));
+ }
+
+ function testUnchecked() {
+ $form = &new SimpleForm(new SimpleFormTag(array()), $this->page('htp://host'));
+ $form->addWidget(new SimpleCheckboxTag(
+ array('name' => 'me', 'type' => 'checkbox')));
+ $this->assertIdentical($form->getValue(new SimpleByName('me')), false);
+ $this->assertTrue($form->setField(new SimpleByName('me'), 'on'));
+ $this->assertEqual($form->getValue(new SimpleByName('me')), 'on');
+ $this->assertFalse($form->setField(new SimpleByName('me'), 'other'));
+ $this->assertEqual($form->getValue(new SimpleByName('me')), 'on');
+ }
+
+ function testChecked() {
+ $form = &new SimpleForm(new SimpleFormTag(array()), $this->page('htp://host'));
+ $form->addWidget(new SimpleCheckboxTag(
+ array('name' => 'me', 'value' => 'a', 'type' => 'checkbox', 'checked' => '')));
+ $this->assertIdentical($form->getValue(new SimpleByName('me')), 'a');
+ $this->assertTrue($form->setField(new SimpleByName('me'), 'a'));
+ $this->assertEqual($form->getValue(new SimpleByName('me')), 'a');
+ $this->assertTrue($form->setField(new SimpleByName('me'), false));
+ $this->assertEqual($form->getValue(new SimpleByName('me')), false);
+ }
+
+ function testSingleUncheckedRadioButton() {
+ $form = &new SimpleForm(new SimpleFormTag(array()), $this->page('htp://host'));
+ $form->addWidget(new SimpleRadioButtonTag(
+ array('name' => 'me', 'value' => 'a', 'type' => 'radio')));
+ $this->assertIdentical($form->getValue(new SimpleByName('me')), false);
+ $this->assertTrue($form->setField(new SimpleByName('me'), 'a'));
+ $this->assertEqual($form->getValue(new SimpleByName('me')), 'a');
+ }
+
+ function testSingleCheckedRadioButton() {
+ $form = &new SimpleForm(new SimpleFormTag(array()), $this->page('htp://host'));
+ $form->addWidget(new SimpleRadioButtonTag(
+ array('name' => 'me', 'value' => 'a', 'type' => 'radio', 'checked' => '')));
+ $this->assertIdentical($form->getValue(new SimpleByName('me')), 'a');
+ $this->assertFalse($form->setField(new SimpleByName('me'), 'other'));
+ }
+
+ function testUncheckedRadioButtons() {
+ $form = &new SimpleForm(new SimpleFormTag(array()), $this->page('htp://host'));
+ $form->addWidget(new SimpleRadioButtonTag(
+ array('name' => 'me', 'value' => 'a', 'type' => 'radio')));
+ $form->addWidget(new SimpleRadioButtonTag(
+ array('name' => 'me', 'value' => 'b', 'type' => 'radio')));
+ $this->assertIdentical($form->getValue(new SimpleByName('me')), false);
+ $this->assertTrue($form->setField(new SimpleByName('me'), 'a'));
+ $this->assertIdentical($form->getValue(new SimpleByName('me')), 'a');
+ $this->assertTrue($form->setField(new SimpleByName('me'), 'b'));
+ $this->assertIdentical($form->getValue(new SimpleByName('me')), 'b');
+ $this->assertFalse($form->setField(new SimpleByName('me'), 'c'));
+ $this->assertIdentical($form->getValue(new SimpleByName('me')), 'b');
+ }
+
+ function testCheckedRadioButtons() {
+ $form = &new SimpleForm(new SimpleFormTag(array()), $this->page('htp://host'));
+ $form->addWidget(new SimpleRadioButtonTag(
+ array('name' => 'me', 'value' => 'a', 'type' => 'radio')));
+ $form->addWidget(new SimpleRadioButtonTag(
+ array('name' => 'me', 'value' => 'b', 'type' => 'radio', 'checked' => '')));
+ $this->assertIdentical($form->getValue(new SimpleByName('me')), 'b');
+ $this->assertTrue($form->setField(new SimpleByName('me'), 'a'));
+ $this->assertIdentical($form->getValue(new SimpleByName('me')), 'a');
+ }
+
+ function testMultipleFieldsWithSameKey() {
+ $form = &new SimpleForm(new SimpleFormTag(array()), $this->page('htp://host'));
+ $form->addWidget(new SimpleCheckboxTag(
+ array('name' => 'a', 'type' => 'checkbox', 'value' => 'me')));
+ $form->addWidget(new SimpleCheckboxTag(
+ array('name' => 'a', 'type' => 'checkbox', 'value' => 'you')));
+ $this->assertIdentical($form->getValue(new SimpleByName('a')), false);
+ $this->assertTrue($form->setField(new SimpleByName('a'), 'me'));
+ $this->assertIdentical($form->getValue(new SimpleByName('a')), 'me');
+ }
+}
+?> \ No newline at end of file
diff --git a/site/vendors/simpletest/test/frames_test.php b/site/vendors/simpletest/test/frames_test.php
new file mode 100644
index 0000000..160eebc
--- /dev/null
+++ b/site/vendors/simpletest/test/frames_test.php
@@ -0,0 +1,549 @@
+<?php
+// $Id: frames_test.php 1555 2007-07-14 02:04:34Z lastcraft $
+require_once(dirname(__FILE__) . '/../autorun.php');
+require_once(dirname(__FILE__) . '/../tag.php');
+require_once(dirname(__FILE__) . '/../page.php');
+require_once(dirname(__FILE__) . '/../frames.php');
+Mock::generate('SimplePage');
+Mock::generate('SimpleForm');
+
+class TestOfFrameset extends UnitTestCase {
+
+ function testTitleReadFromFramesetPage() {
+ $page = &new MockSimplePage();
+ $page->setReturnValue('getTitle', 'This page');
+ $frameset = &new SimpleFrameset($page);
+ $this->assertEqual($frameset->getTitle(), 'This page');
+ }
+
+ function TestHeadersReadFromFramesetByDefault() {
+ $page = &new MockSimplePage();
+ $page->setReturnValue('getHeaders', 'Header: content');
+ $page->setReturnValue('getMimeType', 'text/xml');
+ $page->setReturnValue('getResponseCode', 401);
+ $page->setReturnValue('getTransportError', 'Could not parse headers');
+ $page->setReturnValue('getAuthentication', 'Basic');
+ $page->setReturnValue('getRealm', 'Safe place');
+
+ $frameset = &new SimpleFrameset($page);
+
+ $this->assertIdentical($frameset->getHeaders(), 'Header: content');
+ $this->assertIdentical($frameset->getMimeType(), 'text/xml');
+ $this->assertIdentical($frameset->getResponseCode(), 401);
+ $this->assertIdentical($frameset->getTransportError(), 'Could not parse headers');
+ $this->assertIdentical($frameset->getAuthentication(), 'Basic');
+ $this->assertIdentical($frameset->getRealm(), 'Safe place');
+ }
+
+ function testEmptyFramesetHasNoContent() {
+ $page = &new MockSimplePage();
+ $page->setReturnValue('getRaw', 'This content');
+ $frameset = &new SimpleFrameset($page);
+ $this->assertEqual($frameset->getRaw(), '');
+ }
+
+ function testRawContentIsFromOnlyFrame() {
+ $page = &new MockSimplePage();
+ $page->expectNever('getRaw');
+
+ $frame = &new MockSimplePage();
+ $frame->setReturnValue('getRaw', 'Stuff');
+
+ $frameset = &new SimpleFrameset($page);
+ $frameset->addFrame($frame);
+ $this->assertEqual($frameset->getRaw(), 'Stuff');
+ }
+
+ function testRawContentIsFromAllFrames() {
+ $page = &new MockSimplePage();
+ $page->expectNever('getRaw');
+
+ $frame1 = &new MockSimplePage();
+ $frame1->setReturnValue('getRaw', 'Stuff1');
+
+ $frame2 = &new MockSimplePage();
+ $frame2->setReturnValue('getRaw', 'Stuff2');
+
+ $frameset = &new SimpleFrameset($page);
+ $frameset->addFrame($frame1);
+ $frameset->addFrame($frame2);
+ $this->assertEqual($frameset->getRaw(), 'Stuff1Stuff2');
+ }
+
+ function testTextContentIsFromOnlyFrame() {
+ $page = &new MockSimplePage();
+ $page->expectNever('getText');
+
+ $frame = &new MockSimplePage();
+ $frame->setReturnValue('getText', 'Stuff');
+
+ $frameset = &new SimpleFrameset($page);
+ $frameset->addFrame($frame);
+ $this->assertEqual($frameset->getText(), 'Stuff');
+ }
+
+ function testTextContentIsFromAllFrames() {
+ $page = &new MockSimplePage();
+ $page->expectNever('getText');
+
+ $frame1 = &new MockSimplePage();
+ $frame1->setReturnValue('getText', 'Stuff1');
+
+ $frame2 = &new MockSimplePage();
+ $frame2->setReturnValue('getText', 'Stuff2');
+
+ $frameset = &new SimpleFrameset($page);
+ $frameset->addFrame($frame1);
+ $frameset->addFrame($frame2);
+ $this->assertEqual($frameset->getText(), 'Stuff1 Stuff2');
+ }
+
+ function testFieldFoundIsFirstInFramelist() {
+ $frame1 = &new MockSimplePage();
+ $frame1->setReturnValue('getField', null);
+ $frame1->expectOnce('getField', array(new SimpleByName('a')));
+
+ $frame2 = &new MockSimplePage();
+ $frame2->setReturnValue('getField', 'A');
+ $frame2->expectOnce('getField', array(new SimpleByName('a')));
+
+ $frame3 = &new MockSimplePage();
+ $frame3->expectNever('getField');
+
+ $page = &new MockSimplePage();
+ $frameset = &new SimpleFrameset($page);
+ $frameset->addFrame($frame1);
+ $frameset->addFrame($frame2);
+ $frameset->addFrame($frame3);
+ $this->assertIdentical($frameset->getField(new SimpleByName('a')), 'A');
+ }
+
+ function testFrameReplacementByIndex() {
+ $page = &new MockSimplePage();
+ $page->expectNever('getRaw');
+
+ $frame1 = &new MockSimplePage();
+ $frame1->setReturnValue('getRaw', 'Stuff1');
+
+ $frame2 = &new MockSimplePage();
+ $frame2->setReturnValue('getRaw', 'Stuff2');
+
+ $frameset = &new SimpleFrameset($page);
+ $frameset->addFrame($frame1);
+ $frameset->setFrame(array(1), $frame2);
+ $this->assertEqual($frameset->getRaw(), 'Stuff2');
+ }
+
+ function testFrameReplacementByName() {
+ $page = &new MockSimplePage();
+ $page->expectNever('getRaw');
+
+ $frame1 = &new MockSimplePage();
+ $frame1->setReturnValue('getRaw', 'Stuff1');
+
+ $frame2 = &new MockSimplePage();
+ $frame2->setReturnValue('getRaw', 'Stuff2');
+
+ $frameset = &new SimpleFrameset($page);
+ $frameset->addFrame($frame1, 'a');
+ $frameset->setFrame(array('a'), $frame2);
+ $this->assertEqual($frameset->getRaw(), 'Stuff2');
+ }
+}
+
+class TestOfFrameNavigation extends UnitTestCase {
+
+ function testStartsWithoutFrameFocus() {
+ $page = &new MockSimplePage();
+ $frameset = &new SimpleFrameset($page);
+ $frameset->addFrame($frame);
+ $this->assertFalse($frameset->getFrameFocus());
+ }
+
+ function testCanFocusOnSingleFrame() {
+ $page = &new MockSimplePage();
+ $page->expectNever('getRaw');
+
+ $frame = &new MockSimplePage();
+ $frame->setReturnValue('getFrameFocus', array());
+ $frame->setReturnValue('getRaw', 'Stuff');
+
+ $frameset = &new SimpleFrameset($page);
+ $frameset->addFrame($frame);
+
+ $this->assertFalse($frameset->setFrameFocusByIndex(0));
+ $this->assertTrue($frameset->setFrameFocusByIndex(1));
+ $this->assertEqual($frameset->getRaw(), 'Stuff');
+ $this->assertFalse($frameset->setFrameFocusByIndex(2));
+ $this->assertIdentical($frameset->getFrameFocus(), array(1));
+ }
+
+ function testContentComesFromFrameInFocus() {
+ $page = &new MockSimplePage();
+
+ $frame1 = &new MockSimplePage();
+ $frame1->setReturnValue('getRaw', 'Stuff1');
+ $frame1->setReturnValue('getFrameFocus', array());
+
+ $frame2 = &new MockSimplePage();
+ $frame2->setReturnValue('getRaw', 'Stuff2');
+ $frame2->setReturnValue('getFrameFocus', array());
+
+ $frameset = &new SimpleFrameset($page);
+ $frameset->addFrame($frame1);
+ $frameset->addFrame($frame2);
+
+ $this->assertTrue($frameset->setFrameFocusByIndex(1));
+ $this->assertEqual($frameset->getFrameFocus(), array(1));
+ $this->assertEqual($frameset->getRaw(), 'Stuff1');
+
+ $this->assertTrue($frameset->setFrameFocusByIndex(2));
+ $this->assertEqual($frameset->getFrameFocus(), array(2));
+ $this->assertEqual($frameset->getRaw(), 'Stuff2');
+
+ $this->assertFalse($frameset->setFrameFocusByIndex(3));
+ $this->assertEqual($frameset->getFrameFocus(), array(2));
+
+ $frameset->clearFrameFocus();
+ $this->assertEqual($frameset->getRaw(), 'Stuff1Stuff2');
+ }
+
+ function testCanFocusByName() {
+ $page = &new MockSimplePage();
+
+ $frame1 = &new MockSimplePage();
+ $frame1->setReturnValue('getRaw', 'Stuff1');
+ $frame1->setReturnValue('getFrameFocus', array());
+
+ $frame2 = &new MockSimplePage();
+ $frame2->setReturnValue('getRaw', 'Stuff2');
+ $frame2->setReturnValue('getFrameFocus', array());
+
+ $frameset = &new SimpleFrameset($page);
+ $frameset->addFrame($frame1, 'A');
+ $frameset->addFrame($frame2, 'B');
+
+ $this->assertTrue($frameset->setFrameFocus('A'));
+ $this->assertEqual($frameset->getFrameFocus(), array('A'));
+ $this->assertEqual($frameset->getRaw(), 'Stuff1');
+
+ $this->assertTrue($frameset->setFrameFocusByIndex(2));
+ $this->assertEqual($frameset->getFrameFocus(), array('B'));
+ $this->assertEqual($frameset->getRaw(), 'Stuff2');
+
+ $this->assertFalse($frameset->setFrameFocus('z'));
+
+ $frameset->clearFrameFocus();
+ $this->assertEqual($frameset->getRaw(), 'Stuff1Stuff2');
+ }
+}
+
+class TestOfFramesetPageInterface extends UnitTestCase {
+ var $_page_interface;
+ var $_frameset_interface;
+
+ function TestOfFramesetPageInterface() {
+ $this->UnitTestCase();
+ $this->_page_interface = $this->_getPageMethods();
+ $this->_frameset_interface = $this->_getFramesetMethods();
+ }
+
+ function assertListInAnyOrder($list, $expected) {
+ sort($list);
+ sort($expected);
+ $this->assertEqual($list, $expected);
+ }
+
+ function _getPageMethods() {
+ $methods = array();
+ foreach (get_class_methods('SimplePage') as $method) {
+ if (strtolower($method) == strtolower('SimplePage')) {
+ continue;
+ }
+ if (strtolower($method) == strtolower('getFrameset')) {
+ continue;
+ }
+ if (strncmp($method, '_', 1) == 0) {
+ continue;
+ }
+ if (strncmp($method, 'accept', 6) == 0) {
+ continue;
+ }
+ $methods[] = $method;
+ }
+ return $methods;
+ }
+
+ function _getFramesetMethods() {
+ $methods = array();
+ foreach (get_class_methods('SimpleFrameset') as $method) {
+ if (strtolower($method) == strtolower('SimpleFrameset')) {
+ continue;
+ }
+ if (strncmp($method, '_', 1) == 0) {
+ continue;
+ }
+ if (strncmp($method, 'add', 3) == 0) {
+ continue;
+ }
+ $methods[] = $method;
+ }
+ return $methods;
+ }
+
+ function testFramsetHasPageInterface() {
+ $difference = array();
+ foreach ($this->_page_interface as $method) {
+ if (! in_array($method, $this->_frameset_interface)) {
+ $this->fail("No [$method] in Frameset class");
+ return;
+ }
+ }
+ $this->pass('Frameset covers Page interface');
+ }
+
+ function testHeadersReadFromFrameIfInFocus() {
+ $frame = &new MockSimplePage();
+ $frame->setReturnValue('getUrl', new SimpleUrl('http://localhost/stuff'));
+
+ $frame->setReturnValue('getRequest', 'POST stuff');
+ $frame->setReturnValue('getMethod', 'POST');
+ $frame->setReturnValue('getRequestData', array('a' => 'A'));
+ $frame->setReturnValue('getHeaders', 'Header: content');
+ $frame->setReturnValue('getMimeType', 'text/xml');
+ $frame->setReturnValue('getResponseCode', 401);
+ $frame->setReturnValue('getTransportError', 'Could not parse headers');
+ $frame->setReturnValue('getAuthentication', 'Basic');
+ $frame->setReturnValue('getRealm', 'Safe place');
+
+ $frameset = &new SimpleFrameset(new MockSimplePage());
+ $frameset->addFrame($frame);
+ $frameset->setFrameFocusByIndex(1);
+
+ $url = new SimpleUrl('http://localhost/stuff');
+ $url->setTarget(1);
+ $this->assertIdentical($frameset->getUrl(), $url);
+
+ $this->assertIdentical($frameset->getRequest(), 'POST stuff');
+ $this->assertIdentical($frameset->getMethod(), 'POST');
+ $this->assertIdentical($frameset->getRequestData(), array('a' => 'A'));
+ $this->assertIdentical($frameset->getHeaders(), 'Header: content');
+ $this->assertIdentical($frameset->getMimeType(), 'text/xml');
+ $this->assertIdentical($frameset->getResponseCode(), 401);
+ $this->assertIdentical($frameset->getTransportError(), 'Could not parse headers');
+ $this->assertIdentical($frameset->getAuthentication(), 'Basic');
+ $this->assertIdentical($frameset->getRealm(), 'Safe place');
+ }
+
+ function testUrlsComeFromBothFrames() {
+ $page = &new MockSimplePage();
+ $page->expectNever('getUrls');
+
+ $frame1 = &new MockSimplePage();
+ $frame1->setReturnValue(
+ 'getUrls',
+ array('http://www.lastcraft.com/', 'http://myserver/'));
+
+ $frame2 = &new MockSimplePage();
+ $frame2->setReturnValue(
+ 'getUrls',
+ array('http://www.lastcraft.com/', 'http://test/'));
+
+ $frameset = &new SimpleFrameset($page);
+ $frameset->addFrame($frame1);
+ $frameset->addFrame($frame2);
+ $this->assertListInAnyOrder(
+ $frameset->getUrls(),
+ array('http://www.lastcraft.com/', 'http://myserver/', 'http://test/'));
+ }
+
+ function testLabelledUrlsComeFromBothFrames() {
+ $frame1 = &new MockSimplePage();
+ $frame1->setReturnValue(
+ 'getUrlsByLabel',
+ array(new SimpleUrl('goodbye.php')),
+ array('a'));
+
+ $frame2 = &new MockSimplePage();
+ $frame2->setReturnValue(
+ 'getUrlsByLabel',
+ array(new SimpleUrl('hello.php')),
+ array('a'));
+
+ $frameset = &new SimpleFrameset(new MockSimplePage());
+ $frameset->addFrame($frame1);
+ $frameset->addFrame($frame2, 'Two');
+
+ $expected1 = new SimpleUrl('goodbye.php');
+ $expected1->setTarget(1);
+ $expected2 = new SimpleUrl('hello.php');
+ $expected2->setTarget('Two');
+ $this->assertEqual(
+ $frameset->getUrlsByLabel('a'),
+ array($expected1, $expected2));
+ }
+
+ function testUrlByIdComesFromFirstFrameToRespond() {
+ $frame1 = &new MockSimplePage();
+ $frame1->setReturnValue('getUrlById', new SimpleUrl('four.php'), array(4));
+ $frame1->setReturnValue('getUrlById', false, array(5));
+
+ $frame2 = &new MockSimplePage();
+ $frame2->setReturnValue('getUrlById', false, array(4));
+ $frame2->setReturnValue('getUrlById', new SimpleUrl('five.php'), array(5));
+
+ $frameset = &new SimpleFrameset(new MockSimplePage());
+ $frameset->addFrame($frame1);
+ $frameset->addFrame($frame2);
+
+ $four = new SimpleUrl('four.php');
+ $four->setTarget(1);
+ $this->assertEqual($frameset->getUrlById(4), $four);
+ $five = new SimpleUrl('five.php');
+ $five->setTarget(2);
+ $this->assertEqual($frameset->getUrlById(5), $five);
+ }
+
+ function testReadUrlsFromFrameInFocus() {
+ $frame1 = &new MockSimplePage();
+ $frame1->setReturnValue('getUrls', array('a'));
+ $frame1->setReturnValue('getUrlsByLabel', array(new SimpleUrl('l')));
+ $frame1->setReturnValue('getUrlById', new SimpleUrl('i'));
+
+ $frame2 = &new MockSimplePage();
+ $frame2->expectNever('getUrls');
+ $frame2->expectNever('getUrlsByLabel');
+ $frame2->expectNever('getUrlById');
+
+ $frameset = &new SimpleFrameset(new MockSimplePage());
+ $frameset->addFrame($frame1, 'A');
+ $frameset->addFrame($frame2, 'B');
+ $frameset->setFrameFocus('A');
+
+ $this->assertIdentical($frameset->getUrls(), array('a'));
+ $expected = new SimpleUrl('l');
+ $expected->setTarget('A');
+ $this->assertIdentical($frameset->getUrlsByLabel('label'), array($expected));
+ $expected = new SimpleUrl('i');
+ $expected->setTarget('A');
+ $this->assertIdentical($frameset->getUrlById(99), $expected);
+ }
+
+ function testReadFrameTaggedUrlsFromFrameInFocus() {
+ $frame = &new MockSimplePage();
+
+ $by_label = new SimpleUrl('l');
+ $by_label->setTarget('L');
+ $frame->setReturnValue('getUrlsByLabel', array($by_label));
+
+ $by_id = new SimpleUrl('i');
+ $by_id->setTarget('I');
+ $frame->setReturnValue('getUrlById', $by_id);
+
+ $frameset = &new SimpleFrameset(new MockSimplePage());
+ $frameset->addFrame($frame, 'A');
+ $frameset->setFrameFocus('A');
+
+ $this->assertIdentical($frameset->getUrlsByLabel('label'), array($by_label));
+ $this->assertIdentical($frameset->getUrlById(99), $by_id);
+ }
+
+ function testFindingFormsById() {
+ $frame = &new MockSimplePage();
+ $form = &new MockSimpleForm();
+ $frame->setReturnReference('getFormById', $form, array('a'));
+
+ $frameset = &new SimpleFrameset(new MockSimplePage());
+ $frameset->addFrame(new MockSimplePage(), 'A');
+ $frameset->addFrame($frame, 'B');
+ $this->assertReference($frameset->getFormById('a'), $form);
+
+ $frameset->setFrameFocus('A');
+ $this->assertNull($frameset->getFormById('a'));
+
+ $frameset->setFrameFocus('B');
+ $this->assertReference($frameset->getFormById('a'), $form);
+ }
+
+ function testFindingFormsBySubmit() {
+ $frame = &new MockSimplePage();
+ $form = &new MockSimpleForm();
+ $frame->setReturnReference(
+ 'getFormBySubmit',
+ $form,
+ array(new SimpleByLabel('a')));
+
+ $frameset = &new SimpleFrameset(new MockSimplePage());
+ $frameset->addFrame(new MockSimplePage(), 'A');
+ $frameset->addFrame($frame, 'B');
+ $this->assertReference($frameset->getFormBySubmit(new SimpleByLabel('a')), $form);
+
+ $frameset->setFrameFocus('A');
+ $this->assertNull($frameset->getFormBySubmit(new SimpleByLabel('a')));
+
+ $frameset->setFrameFocus('B');
+ $this->assertReference($frameset->getFormBySubmit(new SimpleByLabel('a')), $form);
+ }
+
+ function testFindingFormsByImage() {
+ $frame = &new MockSimplePage();
+ $form = &new MockSimpleForm();
+ $frame->setReturnReference(
+ 'getFormByImage',
+ $form,
+ array(new SimpleByLabel('a')));
+
+ $frameset = &new SimpleFrameset(new MockSimplePage());
+ $frameset->addFrame(new MockSimplePage(), 'A');
+ $frameset->addFrame($frame, 'B');
+ $this->assertReference($frameset->getFormByImage(new SimpleByLabel('a')), $form);
+
+ $frameset->setFrameFocus('A');
+ $this->assertNull($frameset->getFormByImage(new SimpleByLabel('a')));
+
+ $frameset->setFrameFocus('B');
+ $this->assertReference($frameset->getFormByImage(new SimpleByLabel('a')), $form);
+ }
+
+ function testSettingAllFrameFieldsWhenNoFrameFocus() {
+ $frame1 = &new MockSimplePage();
+ $frame1->expectOnce('setField', array(new SimpleById(22), 'A'));
+
+ $frame2 = &new MockSimplePage();
+ $frame2->expectOnce('setField', array(new SimpleById(22), 'A'));
+
+ $frameset = &new SimpleFrameset(new MockSimplePage());
+ $frameset->addFrame($frame1, 'A');
+ $frameset->addFrame($frame2, 'B');
+ $frameset->setField(new SimpleById(22), 'A');
+ }
+
+ function testOnlySettingFieldFromFocusedFrame() {
+ $frame1 = &new MockSimplePage();
+ $frame1->expectOnce('setField', array(new SimpleByLabelOrName('a'), 'A'));
+
+ $frame2 = &new MockSimplePage();
+ $frame2->expectNever('setField');
+
+ $frameset = &new SimpleFrameset(new MockSimplePage());
+ $frameset->addFrame($frame1, 'A');
+ $frameset->addFrame($frame2, 'B');
+ $frameset->setFrameFocus('A');
+ $frameset->setField(new SimpleByLabelOrName('a'), 'A');
+ }
+
+ function testOnlyGettingFieldFromFocusedFrame() {
+ $frame1 = &new MockSimplePage();
+ $frame1->setReturnValue('getField', 'f', array(new SimpleByName('a')));
+
+ $frame2 = &new MockSimplePage();
+ $frame2->expectNever('getField');
+
+ $frameset = &new SimpleFrameset(new MockSimplePage());
+ $frameset->addFrame($frame1, 'A');
+ $frameset->addFrame($frame2, 'B');
+ $frameset->setFrameFocus('A');
+ $this->assertIdentical($frameset->getField(new SimpleByName('a')), 'f');
+ }
+}
+?> \ No newline at end of file
diff --git a/site/vendors/simpletest/test/http_test.php b/site/vendors/simpletest/test/http_test.php
new file mode 100644
index 0000000..d249850
--- /dev/null
+++ b/site/vendors/simpletest/test/http_test.php
@@ -0,0 +1,427 @@
+<?php
+// $Id: http_test.php 1505 2007-04-30 23:39:59Z lastcraft $
+require_once(dirname(__FILE__) . '/../autorun.php');
+require_once(dirname(__FILE__) . '/../encoding.php');
+require_once(dirname(__FILE__) . '/../http.php');
+require_once(dirname(__FILE__) . '/../socket.php');
+require_once(dirname(__FILE__) . '/../cookies.php');
+Mock::generate('SimpleSocket');
+Mock::generate('SimpleCookieJar');
+Mock::generate('SimpleRoute');
+Mock::generatePartial('SimpleRoute', 'PartialSimpleRoute', array('_createSocket'));
+Mock::generatePartial(
+ 'SimpleProxyRoute',
+ 'PartialSimpleProxyRoute',
+ array('_createSocket'));
+
+class TestOfDirectRoute extends UnitTestCase {
+
+ function testDefaultGetRequest() {
+ $socket = &new MockSimpleSocket();
+ $socket->expectArgumentsAt(0, 'write', array("GET /here.html HTTP/1.0\r\n"));
+ $socket->expectArgumentsAt(1, 'write', array("Host: a.valid.host\r\n"));
+ $socket->expectArgumentsAt(2, 'write', array("Connection: close\r\n"));
+ $socket->expectCallCount('write', 3);
+
+ $route = &new PartialSimpleRoute();
+ $route->setReturnReference('_createSocket', $socket);
+ $route->SimpleRoute(new SimpleUrl('http://a.valid.host/here.html'));
+
+ $this->assertReference($route->createConnection('GET', 15), $socket);
+ }
+
+ function testDefaultPostRequest() {
+ $socket = &new MockSimpleSocket();
+ $socket->expectArgumentsAt(0, 'write', array("POST /here.html HTTP/1.0\r\n"));
+ $socket->expectArgumentsAt(1, 'write', array("Host: a.valid.host\r\n"));
+ $socket->expectArgumentsAt(2, 'write', array("Connection: close\r\n"));
+ $socket->expectCallCount('write', 3);
+
+ $route = &new PartialSimpleRoute();
+ $route->setReturnReference('_createSocket', $socket);
+ $route->SimpleRoute(new SimpleUrl('http://a.valid.host/here.html'));
+
+ $route->createConnection('POST', 15);
+ }
+
+ function testGetWithPort() {
+ $socket = &new MockSimpleSocket();
+ $socket->expectArgumentsAt(0, 'write', array("GET /here.html HTTP/1.0\r\n"));
+ $socket->expectArgumentsAt(1, 'write', array("Host: a.valid.host:81\r\n"));
+ $socket->expectArgumentsAt(2, 'write', array("Connection: close\r\n"));
+ $socket->expectCallCount('write', 3);
+
+ $route = &new PartialSimpleRoute();
+ $route->setReturnReference('_createSocket', $socket);
+ $route->SimpleRoute(new SimpleUrl('http://a.valid.host:81/here.html'));
+
+ $route->createConnection('GET', 15);
+ }
+
+ function testGetWithParameters() {
+ $socket = &new MockSimpleSocket();
+ $socket->expectArgumentsAt(0, 'write', array("GET /here.html?a=1&b=2 HTTP/1.0\r\n"));
+ $socket->expectArgumentsAt(1, 'write', array("Host: a.valid.host\r\n"));
+ $socket->expectArgumentsAt(2, 'write', array("Connection: close\r\n"));
+ $socket->expectCallCount('write', 3);
+
+ $route = &new PartialSimpleRoute();
+ $route->setReturnReference('_createSocket', $socket);
+ $route->SimpleRoute(new SimpleUrl('http://a.valid.host/here.html?a=1&b=2'));
+
+ $route->createConnection('GET', 15);
+ }
+}
+
+class TestOfProxyRoute extends UnitTestCase {
+
+ function testDefaultGet() {
+ $socket = &new MockSimpleSocket();
+ $socket->expectArgumentsAt(0, 'write', array("GET http://a.valid.host/here.html HTTP/1.0\r\n"));
+ $socket->expectArgumentsAt(1, 'write', array("Host: my-proxy:8080\r\n"));
+ $socket->expectArgumentsAt(2, 'write', array("Connection: close\r\n"));
+ $socket->expectCallCount('write', 3);
+
+ $route = &new PartialSimpleProxyRoute();
+ $route->setReturnReference('_createSocket', $socket);
+ $route->SimpleProxyRoute(
+ new SimpleUrl('http://a.valid.host/here.html'),
+ new SimpleUrl('http://my-proxy'));
+ $route->createConnection('GET', 15);
+ }
+
+ function testDefaultPost() {
+ $socket = &new MockSimpleSocket();
+ $socket->expectArgumentsAt(0, 'write', array("POST http://a.valid.host/here.html HTTP/1.0\r\n"));
+ $socket->expectArgumentsAt(1, 'write', array("Host: my-proxy:8080\r\n"));
+ $socket->expectArgumentsAt(2, 'write', array("Connection: close\r\n"));
+ $socket->expectCallCount('write', 3);
+
+ $route = &new PartialSimpleProxyRoute();
+ $route->setReturnReference('_createSocket', $socket);
+ $route->SimpleProxyRoute(
+ new SimpleUrl('http://a.valid.host/here.html'),
+ new SimpleUrl('http://my-proxy'));
+ $route->createConnection('POST', 15);
+ }
+
+ function testGetWithPort() {
+ $socket = &new MockSimpleSocket();
+ $socket->expectArgumentsAt(0, 'write', array("GET http://a.valid.host:81/here.html HTTP/1.0\r\n"));
+ $socket->expectArgumentsAt(1, 'write', array("Host: my-proxy:8081\r\n"));
+ $socket->expectArgumentsAt(2, 'write', array("Connection: close\r\n"));
+ $socket->expectCallCount('write', 3);
+
+ $route = &new PartialSimpleProxyRoute();
+ $route->setReturnReference('_createSocket', $socket);
+ $route->SimpleProxyRoute(
+ new SimpleUrl('http://a.valid.host:81/here.html'),
+ new SimpleUrl('http://my-proxy:8081'));
+ $route->createConnection('GET', 15);
+ }
+
+ function testGetWithParameters() {
+ $socket = &new MockSimpleSocket();
+ $socket->expectArgumentsAt(0, 'write', array("GET http://a.valid.host/here.html?a=1&b=2 HTTP/1.0\r\n"));
+ $socket->expectArgumentsAt(1, 'write', array("Host: my-proxy:8080\r\n"));
+ $socket->expectArgumentsAt(2, 'write', array("Connection: close\r\n"));
+ $socket->expectCallCount('write', 3);
+
+ $route = &new PartialSimpleProxyRoute();
+ $route->setReturnReference('_createSocket', $socket);
+ $route->SimpleProxyRoute(
+ new SimpleUrl('http://a.valid.host/here.html?a=1&b=2'),
+ new SimpleUrl('http://my-proxy'));
+ $route->createConnection('GET', 15);
+ }
+
+ function testGetWithAuthentication() {
+ $encoded = base64_encode('Me:Secret');
+
+ $socket = &new MockSimpleSocket();
+ $socket->expectArgumentsAt(0, 'write', array("GET http://a.valid.host/here.html HTTP/1.0\r\n"));
+ $socket->expectArgumentsAt(1, 'write', array("Host: my-proxy:8080\r\n"));
+ $socket->expectArgumentsAt(2, 'write', array("Proxy-Authorization: Basic $encoded\r\n"));
+ $socket->expectArgumentsAt(3, 'write', array("Connection: close\r\n"));
+ $socket->expectCallCount('write', 4);
+
+ $route = &new PartialSimpleProxyRoute();
+ $route->setReturnReference('_createSocket', $socket);
+ $route->SimpleProxyRoute(
+ new SimpleUrl('http://a.valid.host/here.html'),
+ new SimpleUrl('http://my-proxy'),
+ 'Me',
+ 'Secret');
+ $route->createConnection('GET', 15);
+ }
+}
+
+class TestOfHttpRequest extends UnitTestCase {
+
+ function testReadingBadConnection() {
+ $socket = &new MockSimpleSocket();
+
+ $route = &new MockSimpleRoute();
+ $route->setReturnReference('createConnection', $socket);
+
+ $request = &new SimpleHttpRequest($route, new SimpleGetEncoding());
+ $reponse = &$request->fetch(15);
+ $this->assertTrue($reponse->isError());
+ }
+
+ function testReadingGoodConnection() {
+ $socket = &new MockSimpleSocket();
+ $socket->expectOnce('write', array("\r\n"));
+
+ $route = &new MockSimpleRoute();
+ $route->setReturnReference('createConnection', $socket);
+ $route->expectArguments('createConnection', array('GET', 15));
+
+ $request = &new SimpleHttpRequest($route, new SimpleGetEncoding());
+ $this->assertIsA($request->fetch(15), 'SimpleHttpResponse');
+ }
+
+ function testWritingAdditionalHeaders() {
+ $socket = &new MockSimpleSocket();
+ $socket->expectArgumentsAt(0, 'write', array("My: stuff\r\n"));
+ $socket->expectArgumentsAt(1, 'write', array("\r\n"));
+ $socket->expectCallCount('write', 2);
+
+ $route = &new MockSimpleRoute();
+ $route->setReturnReference('createConnection', $socket);
+
+ $request = &new SimpleHttpRequest($route, new SimpleGetEncoding());
+ $request->addHeaderLine('My: stuff');
+ $request->fetch(15);
+ }
+
+ function testCookieWriting() {
+ $socket = &new MockSimpleSocket();
+ $socket->expectArgumentsAt(0, 'write', array("Cookie: a=A\r\n"));
+ $socket->expectArgumentsAt(1, 'write', array("\r\n"));
+ $socket->expectCallCount('write', 2);
+
+ $route = &new MockSimpleRoute();
+ $route->setReturnReference('createConnection', $socket);
+
+ $jar = new SimpleCookieJar();
+ $jar->setCookie('a', 'A');
+
+ $request = &new SimpleHttpRequest($route, new SimpleGetEncoding());
+ $request->readCookiesFromJar($jar, new SimpleUrl('/'));
+ $this->assertIsA($request->fetch(15), 'SimpleHttpResponse');
+ }
+
+ function testMultipleCookieWriting() {
+ $socket = &new MockSimpleSocket();
+ $socket->expectArgumentsAt(0, 'write', array("Cookie: a=A;b=B\r\n"));
+
+ $route = &new MockSimpleRoute();
+ $route->setReturnReference('createConnection', $socket);
+
+ $jar = new SimpleCookieJar();
+ $jar->setCookie('a', 'A');
+ $jar->setCookie('b', 'B');
+
+ $request = &new SimpleHttpRequest($route, new SimpleGetEncoding());
+ $request->readCookiesFromJar($jar, new SimpleUrl('/'));
+ $request->fetch(15);
+ }
+}
+
+class TestOfHttpPostRequest extends UnitTestCase {
+
+ function testReadingBadConnectionCausesErrorBecauseOfDeadSocket() {
+ $socket = &new MockSimpleSocket();
+
+ $route = &new MockSimpleRoute();
+ $route->setReturnReference('createConnection', $socket);
+
+ $request = &new SimpleHttpRequest($route, new SimplePostEncoding());
+ $reponse = &$request->fetch(15);
+ $this->assertTrue($reponse->isError());
+ }
+
+ function testReadingGoodConnection() {
+ $socket = &new MockSimpleSocket();
+ $socket->expectArgumentsAt(0, 'write', array("Content-Length: 0\r\n"));
+ $socket->expectArgumentsAt(1, 'write', array("Content-Type: application/x-www-form-urlencoded\r\n"));
+ $socket->expectArgumentsAt(2, 'write', array("\r\n"));
+ $socket->expectArgumentsAt(3, 'write', array(""));
+
+ $route = &new MockSimpleRoute();
+ $route->setReturnReference('createConnection', $socket);
+ $route->expectArguments('createConnection', array('POST', 15));
+
+ $request = &new SimpleHttpRequest($route, new SimplePostEncoding());
+ $this->assertIsA($request->fetch(15), 'SimpleHttpResponse');
+ }
+
+ function testContentHeadersCalculated() {
+ $socket = &new MockSimpleSocket();
+ $socket->expectArgumentsAt(0, 'write', array("Content-Length: 3\r\n"));
+ $socket->expectArgumentsAt(1, 'write', array("Content-Type: application/x-www-form-urlencoded\r\n"));
+ $socket->expectArgumentsAt(2, 'write', array("\r\n"));
+ $socket->expectArgumentsAt(3, 'write', array("a=A"));
+
+ $route = &new MockSimpleRoute();
+ $route->setReturnReference('createConnection', $socket);
+ $route->expectArguments('createConnection', array('POST', 15));
+
+ $request = &new SimpleHttpRequest(
+ $route,
+ new SimplePostEncoding(array('a' => 'A')));
+ $this->assertIsA($request->fetch(15), 'SimpleHttpResponse');
+ }
+}
+
+class TestOfHttpHeaders extends UnitTestCase {
+
+ function testParseBasicHeaders() {
+ $headers = new SimpleHttpHeaders(
+ "HTTP/1.1 200 OK\r\n" .
+ "Date: Mon, 18 Nov 2002 15:50:29 GMT\r\n" .
+ "Content-Type: text/plain\r\n" .
+ "Server: Apache/1.3.24 (Win32) PHP/4.2.3\r\n" .
+ "Connection: close");
+ $this->assertIdentical($headers->getHttpVersion(), "1.1");
+ $this->assertIdentical($headers->getResponseCode(), 200);
+ $this->assertEqual($headers->getMimeType(), "text/plain");
+ }
+
+ function testNonStandardResponseHeader() {
+ $headers = new SimpleHttpHeaders(
+ "HTTP/1.1 302 (HTTP-Version SP Status-Code CRLF)\r\n" .
+ "Connection: close");
+ $this->assertIdentical($headers->getResponseCode(), 302);
+ }
+
+ function testCanParseMultipleCookies() {
+ $jar = &new MockSimpleCookieJar();
+ $jar->expectAt(0, 'setCookie', array('a', 'aaa', 'host', '/here/', 'Wed, 25 Dec 2002 04:24:20 GMT'));
+ $jar->expectAt(1, 'setCookie', array('b', 'bbb', 'host', '/', false));
+
+ $headers = new SimpleHttpHeaders(
+ "HTTP/1.1 200 OK\r\n" .
+ "Date: Mon, 18 Nov 2002 15:50:29 GMT\r\n" .
+ "Content-Type: text/plain\r\n" .
+ "Server: Apache/1.3.24 (Win32) PHP/4.2.3\r\n" .
+ "Set-Cookie: a=aaa; expires=Wed, 25-Dec-02 04:24:20 GMT; path=/here/\r\n" .
+ "Set-Cookie: b=bbb\r\n" .
+ "Connection: close");
+ $headers->writeCookiesToJar($jar, new SimpleUrl('http://host'));
+ }
+
+ function testCanRecogniseRedirect() {
+ $headers = new SimpleHttpHeaders("HTTP/1.1 301 OK\r\n" .
+ "Content-Type: text/plain\r\n" .
+ "Content-Length: 0\r\n" .
+ "Location: http://www.somewhere-else.com/\r\n" .
+ "Connection: close");
+ $this->assertIdentical($headers->getResponseCode(), 301);
+ $this->assertEqual($headers->getLocation(), "http://www.somewhere-else.com/");
+ $this->assertTrue($headers->isRedirect());
+ }
+
+ function testCanParseChallenge() {
+ $headers = new SimpleHttpHeaders("HTTP/1.1 401 Authorization required\r\n" .
+ "Content-Type: text/plain\r\n" .
+ "Connection: close\r\n" .
+ "WWW-Authenticate: Basic realm=\"Somewhere\"");
+ $this->assertEqual($headers->getAuthentication(), 'Basic');
+ $this->assertEqual($headers->getRealm(), 'Somewhere');
+ $this->assertTrue($headers->isChallenge());
+ }
+}
+
+class TestOfHttpResponse extends UnitTestCase {
+
+ function testBadRequest() {
+ $socket = &new MockSimpleSocket();
+ $socket->setReturnValue('getSent', '');
+
+ $response = &new SimpleHttpResponse($socket, new SimpleUrl('here'), new SimpleGetEncoding());
+ $this->assertTrue($response->isError());
+ $this->assertPattern('/Nothing fetched/', $response->getError());
+ $this->assertIdentical($response->getContent(), false);
+ $this->assertIdentical($response->getSent(), '');
+ }
+
+ function testBadSocketDuringResponse() {
+ $socket = &new MockSimpleSocket();
+ $socket->setReturnValueAt(0, "read", "HTTP/1.1 200 OK\r\n");
+ $socket->setReturnValueAt(1, "read", "Date: Mon, 18 Nov 2002 15:50:29 GMT\r\n");
+ $socket->setReturnValue("read", "");
+ $socket->setReturnValue('getSent', 'HTTP/1.1 ...');
+
+ $response = &new SimpleHttpResponse($socket, new SimpleUrl('here'), new SimpleGetEncoding());
+ $this->assertTrue($response->isError());
+ $this->assertEqual($response->getContent(), '');
+ $this->assertEqual($response->getSent(), 'HTTP/1.1 ...');
+ }
+
+ function testIncompleteHeader() {
+ $socket = &new MockSimpleSocket();
+ $socket->setReturnValueAt(0, "read", "HTTP/1.1 200 OK\r\n");
+ $socket->setReturnValueAt(1, "read", "Date: Mon, 18 Nov 2002 15:50:29 GMT\r\n");
+ $socket->setReturnValueAt(2, "read", "Content-Type: text/plain\r\n");
+ $socket->setReturnValue("read", "");
+
+ $response = &new SimpleHttpResponse($socket, new SimpleUrl('here'), new SimpleGetEncoding());
+ $this->assertTrue($response->isError());
+ $this->assertEqual($response->getContent(), "");
+ }
+
+ function testParseOfResponseHeadersWhenChunked() {
+ $socket = &new MockSimpleSocket();
+ $socket->setReturnValueAt(0, "read", "HTTP/1.1 200 OK\r\nDate: Mon, 18 Nov 2002 15:50:29 GMT\r\n");
+ $socket->setReturnValueAt(1, "read", "Content-Type: text/plain\r\n");
+ $socket->setReturnValueAt(2, "read", "Server: Apache/1.3.24 (Win32) PHP/4.2.3\r\nConne");
+ $socket->setReturnValueAt(3, "read", "ction: close\r\n\r\nthis is a test file\n");
+ $socket->setReturnValueAt(4, "read", "with two lines in it\n");
+ $socket->setReturnValue("read", "");
+
+ $response = &new SimpleHttpResponse($socket, new SimpleUrl('here'), new SimpleGetEncoding());
+ $this->assertFalse($response->isError());
+ $this->assertEqual(
+ $response->getContent(),
+ "this is a test file\nwith two lines in it\n");
+ $headers = $response->getHeaders();
+ $this->assertIdentical($headers->getHttpVersion(), "1.1");
+ $this->assertIdentical($headers->getResponseCode(), 200);
+ $this->assertEqual($headers->getMimeType(), "text/plain");
+ $this->assertFalse($headers->isRedirect());
+ $this->assertFalse($headers->getLocation());
+ }
+
+ function testRedirect() {
+ $socket = &new MockSimpleSocket();
+ $socket->setReturnValueAt(0, "read", "HTTP/1.1 301 OK\r\n");
+ $socket->setReturnValueAt(1, "read", "Content-Type: text/plain\r\n");
+ $socket->setReturnValueAt(2, "read", "Location: http://www.somewhere-else.com/\r\n");
+ $socket->setReturnValueAt(3, "read", "Connection: close\r\n");
+ $socket->setReturnValueAt(4, "read", "\r\n");
+ $socket->setReturnValue("read", "");
+
+ $response = &new SimpleHttpResponse($socket, new SimpleUrl('here'), new SimpleGetEncoding());
+ $headers = $response->getHeaders();
+ $this->assertTrue($headers->isRedirect());
+ $this->assertEqual($headers->getLocation(), "http://www.somewhere-else.com/");
+ }
+
+ function testRedirectWithPort() {
+ $socket = &new MockSimpleSocket();
+ $socket->setReturnValueAt(0, "read", "HTTP/1.1 301 OK\r\n");
+ $socket->setReturnValueAt(1, "read", "Content-Type: text/plain\r\n");
+ $socket->setReturnValueAt(2, "read", "Location: http://www.somewhere-else.com:80/\r\n");
+ $socket->setReturnValueAt(3, "read", "Connection: close\r\n");
+ $socket->setReturnValueAt(4, "read", "\r\n");
+ $socket->setReturnValue("read", "");
+
+ $response = &new SimpleHttpResponse($socket, new SimpleUrl('here'), new SimpleGetEncoding());
+ $headers = $response->getHeaders();
+ $this->assertTrue($headers->isRedirect());
+ $this->assertEqual($headers->getLocation(), "http://www.somewhere-else.com:80/");
+ }
+}
+?> \ No newline at end of file
diff --git a/site/vendors/simpletest/test/interfaces_test.php b/site/vendors/simpletest/test/interfaces_test.php
new file mode 100644
index 0000000..b6980ed
--- /dev/null
+++ b/site/vendors/simpletest/test/interfaces_test.php
@@ -0,0 +1,137 @@
+<?php
+// $Id: interfaces_test.php 1699 2008-03-24 16:01:29Z lastcraft $
+require_once(dirname(__FILE__) . '/../autorun.php');
+if (function_exists('spl_classes')) {
+ include(dirname(__FILE__) . '/support/spl_examples.php');
+}
+
+interface DummyInterface {
+ function aMethod();
+ function anotherMethod($a);
+ function &referenceMethod(&$a);
+}
+
+Mock::generate('DummyInterface');
+Mock::generatePartial('DummyInterface', 'PartialDummyInterface', array());
+
+class TestOfMockInterfaces extends UnitTestCase {
+
+ function testCanMockAnInterface() {
+ $mock = new MockDummyInterface();
+ $this->assertIsA($mock, 'SimpleMock');
+ $this->assertIsA($mock, 'MockDummyInterface');
+ $this->assertTrue(method_exists($mock, 'aMethod'));
+ $this->assertTrue(method_exists($mock, 'anotherMethod'));
+ $this->assertNull($mock->aMethod());
+ }
+
+ function testMockedInterfaceExpectsParameters() {
+ $mock = new MockDummyInterface();
+ $mock->anotherMethod();
+ $this->assertError();
+ }
+
+ function testCannotPartiallyMockAnInterface() {
+ $this->assertFalse(class_exists('PartialDummyInterface'));
+ }
+}
+
+class TestOfSpl extends UnitTestCase {
+
+ function skip() {
+ $this->skipUnless(function_exists('spl_classes'), 'No SPL module loaded');
+ }
+
+ function testCanMockAllSplClasses() {
+ if (! function_exists('spl_classes')) {
+ return;
+ }
+ foreach(spl_classes() as $class) {
+ if ($class == 'SplHeap') {
+ continue;
+ }
+ $mock_class = "Mock$class";
+ Mock::generate($class);
+ $this->assertIsA(new $mock_class(), $mock_class);
+ }
+ }
+
+ function testExtensionOfCommonSplClasses() {
+ Mock::generate('IteratorImplementation');
+ $this->assertIsA(
+ new IteratorImplementation(),
+ 'IteratorImplementation');
+ Mock::generate('IteratorAggregateImplementation');
+ $this->assertIsA(
+ new IteratorAggregateImplementation(),
+ 'IteratorAggregateImplementation');
+ }
+}
+
+class WithHint {
+ function hinted(DummyInterface $object) { }
+}
+
+class ImplementsDummy implements DummyInterface {
+ function aMethod() { }
+ function anotherMethod($a) { }
+ function &referenceMethod(&$a) { }
+ function extraMethod($a = false) { }
+}
+Mock::generate('ImplementsDummy');
+
+class TestOfImplementations extends UnitTestCase {
+
+ function testMockedInterfaceCanPassThroughTypeHint() {
+ $mock = new MockDummyInterface();
+ $hinter = new WithHint();
+ $hinter->hinted($mock);
+ }
+
+ function testImplementedInterfacesAreCarried() {
+ $mock = new MockImplementsDummy();
+ $hinter = new WithHint();
+ $hinter->hinted($mock);
+ }
+
+ function testNoSpuriousWarningsWhenSkippingDefaultedParameter() {
+ $mock = new MockImplementsDummy();
+ $mock->extraMethod();
+ }
+}
+
+interface SampleClassWithConstruct {
+ function __construct($something);
+}
+
+class TestOfInterfaceMocksWithConstruct extends UnitTestCase {
+ function testBasicConstructOfAnInterface() {
+ Mock::generate('SampleClassWithConstruct');
+ $this->assertNoErrors();
+ }
+}
+
+interface SampleInterfaceWithHintInSignature {
+ function method(array $hinted);
+}
+
+class TestOfInterfaceMocksWithHintInSignature extends UnitTestCase {
+ function testBasicConstructOfAnInterfaceWithHintInSignature() {
+ Mock::generate('SampleInterfaceWithHintInSignature');
+ $this->assertNoErrors();
+ $mock = new MockSampleInterfaceWithHintInSignature();
+ $this->assertIsA($mock, 'SampleInterfaceWithHintInSignature');
+ }
+}
+
+interface SampleInterfaceWithClone {
+ function __clone();
+}
+
+class TestOfSampleInterfaceWithClone extends UnitTestCase {
+ function testCanMockWithoutErrors() {
+ Mock::generate('SampleInterfaceWithClone');
+ $this->assertNoErrors();
+ }
+}
+?> \ No newline at end of file
diff --git a/site/vendors/simpletest/test/live_test.php b/site/vendors/simpletest/test/live_test.php
new file mode 100644
index 0000000..b294030
--- /dev/null
+++ b/site/vendors/simpletest/test/live_test.php
@@ -0,0 +1,47 @@
+<?php
+// $Id: live_test.php 1505 2007-04-30 23:39:59Z lastcraft $
+require_once(dirname(__FILE__) . '/../autorun.php');
+require_once(dirname(__FILE__) . '/../socket.php');
+require_once(dirname(__FILE__) . '/../http.php');
+require_once(dirname(__FILE__) . '/../compatibility.php');
+
+if (SimpleTest::getDefaultProxy()) {
+ SimpleTest::ignore('LiveHttpTestCase');
+}
+
+class LiveHttpTestCase extends UnitTestCase {
+
+ function testBadSocket() {
+ $socket = &new SimpleSocket('bad_url', 111, 5);
+ $this->assertTrue($socket->isError());
+ $this->assertPattern(
+ '/Cannot open \\[bad_url:111\\] with \\[/',
+ $socket->getError());
+ $this->assertFalse($socket->isOpen());
+ $this->assertFalse($socket->write('A message'));
+ }
+
+ function testSocketClosure() {
+ $socket = &new SimpleSocket('www.lastcraft.com', 80, 15, 8);
+ $this->assertTrue($socket->isOpen());
+ $this->assertTrue($socket->write("GET /test/network_confirm.php HTTP/1.0\r\n"));
+ $socket->write("Host: www.lastcraft.com\r\n");
+ $socket->write("Connection: close\r\n\r\n");
+ $this->assertEqual($socket->read(), "HTTP/1.1");
+ $socket->close();
+ $this->assertIdentical($socket->read(), false);
+ }
+
+ function testRecordOfSentCharacters() {
+ $socket = &new SimpleSocket('www.lastcraft.com', 80, 15);
+ $this->assertTrue($socket->write("GET /test/network_confirm.php HTTP/1.0\r\n"));
+ $socket->write("Host: www.lastcraft.com\r\n");
+ $socket->write("Connection: close\r\n\r\n");
+ $socket->close();
+ $this->assertEqual($socket->getSent(),
+ "GET /test/network_confirm.php HTTP/1.0\r\n" .
+ "Host: www.lastcraft.com\r\n" .
+ "Connection: close\r\n\r\n");
+ }
+}
+?> \ No newline at end of file
diff --git a/site/vendors/simpletest/test/mock_objects_test.php b/site/vendors/simpletest/test/mock_objects_test.php
new file mode 100644
index 0000000..a208ff7
--- /dev/null
+++ b/site/vendors/simpletest/test/mock_objects_test.php
@@ -0,0 +1,994 @@
+<?php
+// $Id: mock_objects_test.php 1700 2008-03-24 16:17:48Z lastcraft $
+require_once(dirname(__FILE__) . '/../autorun.php');
+require_once(dirname(__FILE__) . '/../expectation.php');
+require_once(dirname(__FILE__) . '/../mock_objects.php');
+
+class TestOfAnythingExpectation extends UnitTestCase {
+
+ function testSimpleInteger() {
+ $expectation = new AnythingExpectation();
+ $this->assertTrue($expectation->test(33));
+ $this->assertTrue($expectation->test(false));
+ $this->assertTrue($expectation->test(null));
+ }
+}
+
+class TestOfParametersExpectation extends UnitTestCase {
+
+ function testEmptyMatch() {
+ $expectation = new ParametersExpectation(array());
+ $this->assertTrue($expectation->test(array()));
+ $this->assertFalse($expectation->test(array(33)));
+ }
+
+ function testSingleMatch() {
+ $expectation = new ParametersExpectation(array(0));
+ $this->assertFalse($expectation->test(array(1)));
+ $this->assertTrue($expectation->test(array(0)));
+ }
+
+ function testAnyMatch() {
+ $expectation = new ParametersExpectation(false);
+ $this->assertTrue($expectation->test(array()));
+ $this->assertTrue($expectation->test(array(1, 2)));
+ }
+
+ function testMissingParameter() {
+ $expectation = new ParametersExpectation(array(0));
+ $this->assertFalse($expectation->test(array()));
+ }
+
+ function testNullParameter() {
+ $expectation = new ParametersExpectation(array(null));
+ $this->assertTrue($expectation->test(array(null)));
+ $this->assertFalse($expectation->test(array()));
+ }
+
+ function testAnythingExpectations() {
+ $expectation = new ParametersExpectation(array(new AnythingExpectation()));
+ $this->assertFalse($expectation->test(array()));
+ $this->assertIdentical($expectation->test(array(null)), true);
+ $this->assertIdentical($expectation->test(array(13)), true);
+ }
+
+ function testOtherExpectations() {
+ $expectation = new ParametersExpectation(
+ array(new PatternExpectation('/hello/i')));
+ $this->assertFalse($expectation->test(array('Goodbye')));
+ $this->assertTrue($expectation->test(array('hello')));
+ $this->assertTrue($expectation->test(array('Hello')));
+ }
+
+ function testIdentityOnly() {
+ $expectation = new ParametersExpectation(array("0"));
+ $this->assertFalse($expectation->test(array(0)));
+ $this->assertTrue($expectation->test(array("0")));
+ }
+
+ function testLongList() {
+ $expectation = new ParametersExpectation(
+ array("0", 0, new AnythingExpectation(), false));
+ $this->assertTrue($expectation->test(array("0", 0, 37, false)));
+ $this->assertFalse($expectation->test(array("0", 0, 37, true)));
+ $this->assertFalse($expectation->test(array("0", 0, 37)));
+ }
+}
+
+class TestOfSimpleSignatureMap extends UnitTestCase {
+
+ function testEmpty() {
+ $map = new SimpleSignatureMap();
+ $this->assertFalse($map->isMatch("any", array()));
+ $this->assertNull($map->findFirstAction("any", array()));
+ }
+
+ function testExactReference() {
+ $map = new SimpleSignatureMap();
+ $ref = "Fred";
+ $map->add(array(0), $ref);
+ $this->assertEqual($map->findFirstAction(array(0)), "Fred");
+ $ref2 = &$map->findFirstAction(array(0));
+ $this->assertReference($ref2, $ref);
+ }
+
+ function testDifferentCallSignaturesCanHaveDifferentReferences() {
+ $map = new SimpleSignatureMap();
+ $fred = 'Fred';
+ $jim = 'jim';
+ $map->add(array(0), $fred);
+ $map->add(array('0'), $jim);
+ $this->assertReference($fred, $map->findFirstAction(array(0)));
+ $this->assertReference($jim, $map->findFirstAction(array('0')));
+ }
+
+ function testWildcard() {
+ $fred = 'Fred';
+ $map = new SimpleSignatureMap();
+ $map->add(array(new AnythingExpectation(), 1, 3), $fred);
+ $this->assertTrue($map->isMatch(array(2, 1, 3)));
+ $this->assertReference($map->findFirstAction(array(2, 1, 3)), $fred);
+ }
+
+ function testAllWildcard() {
+ $fred = 'Fred';
+ $map = new SimpleSignatureMap();
+ $this->assertFalse($map->isMatch(array(2, 1, 3)));
+ $map->add('', $fred);
+ $this->assertTrue($map->isMatch(array(2, 1, 3)));
+ $this->assertReference($map->findFirstAction(array(2, 1, 3)), $fred);
+ }
+
+ function testOrdering() {
+ $map = new SimpleSignatureMap();
+ $map->add(array(1, 2), new SimpleByValue("1, 2"));
+ $map->add(array(1, 3), new SimpleByValue("1, 3"));
+ $map->add(array(1), new SimpleByValue("1"));
+ $map->add(array(1, 4), new SimpleByValue("1, 4"));
+ $map->add(array(new AnythingExpectation()), new SimpleByValue("Any"));
+ $map->add(array(2), new SimpleByValue("2"));
+ $map->add("", new SimpleByValue("Default"));
+ $map->add(array(), new SimpleByValue("None"));
+ $this->assertEqual($map->findFirstAction(array(1, 2)), new SimpleByValue("1, 2"));
+ $this->assertEqual($map->findFirstAction(array(1, 3)), new SimpleByValue("1, 3"));
+ $this->assertEqual($map->findFirstAction(array(1, 4)), new SimpleByValue("1, 4"));
+ $this->assertEqual($map->findFirstAction(array(1)), new SimpleByValue("1"));
+ $this->assertEqual($map->findFirstAction(array(2)), new SimpleByValue("Any"));
+ $this->assertEqual($map->findFirstAction(array(3)), new SimpleByValue("Any"));
+ $this->assertEqual($map->findFirstAction(array()), new SimpleByValue("Default"));
+ }
+}
+
+class TestOfCallSchedule extends UnitTestCase {
+ function testCanBeSetToAlwaysReturnTheSameReference() {
+ $a = 5;
+ $schedule = &new SimpleCallSchedule();
+ $schedule->register('aMethod', false, new SimpleByReference($a));
+ $this->assertReference($schedule->respond(0, 'aMethod', array()), $a);
+ $this->assertReference($schedule->respond(1, 'aMethod', array()), $a);
+ }
+
+ function testSpecificSignaturesOverrideTheAlwaysCase() {
+ $any = 'any';
+ $one = 'two';
+ $schedule = &new SimpleCallSchedule();
+ $schedule->register('aMethod', array(1), new SimpleByReference($one));
+ $schedule->register('aMethod', false, new SimpleByReference($any));
+ $this->assertReference($schedule->respond(0, 'aMethod', array(2)), $any);
+ $this->assertReference($schedule->respond(0, 'aMethod', array(1)), $one);
+ }
+
+ function testReturnsCanBeSetOverTime() {
+ $one = 'one';
+ $two = 'two';
+ $schedule = &new SimpleCallSchedule();
+ $schedule->registerAt(0, 'aMethod', false, new SimpleByReference($one));
+ $schedule->registerAt(1, 'aMethod', false, new SimpleByReference($two));
+ $this->assertReference($schedule->respond(0, 'aMethod', array()), $one);
+ $this->assertReference($schedule->respond(1, 'aMethod', array()), $two);
+ }
+
+ function testReturnsOverTimecanBeAlteredByTheArguments() {
+ $one = '1';
+ $two = '2';
+ $two_a = '2a';
+ $schedule = &new SimpleCallSchedule();
+ $schedule->registerAt(0, 'aMethod', false, new SimpleByReference($one));
+ $schedule->registerAt(1, 'aMethod', array('a'), new SimpleByReference($two_a));
+ $schedule->registerAt(1, 'aMethod', false, new SimpleByReference($two));
+ $this->assertReference($schedule->respond(0, 'aMethod', array()), $one);
+ $this->assertReference($schedule->respond(1, 'aMethod', array()), $two);
+ $this->assertReference($schedule->respond(1, 'aMethod', array('a')), $two_a);
+ }
+
+ function testCanReturnByValue() {
+ $a = 5;
+ $schedule = &new SimpleCallSchedule();
+ $schedule->register('aMethod', false, new SimpleByValue($a));
+ $this->assertClone($schedule->respond(0, 'aMethod', array()), $a);
+ }
+
+ function testCanThrowException() {
+ if (version_compare(phpversion(), '5', '>=')) {
+ $schedule = &new SimpleCallSchedule();
+ $schedule->register('aMethod', false, new SimpleThrower(new Exception('Ouch')));
+ $this->expectException(new Exception('Ouch'));
+ $schedule->respond(0, 'aMethod', array());
+ }
+ }
+
+ function testCanEmitError() {
+ $schedule = &new SimpleCallSchedule();
+ $schedule->register('aMethod', false, new SimpleErrorThrower('Ouch', E_USER_WARNING));
+ $this->expectError('Ouch');
+ $schedule->respond(0, 'aMethod', array());
+ }
+}
+
+class Dummy {
+ function Dummy() {
+ }
+
+ function aMethod() {
+ return true;
+ }
+
+ function anotherMethod() {
+ return true;
+ }
+}
+Mock::generate('Dummy');
+Mock::generate('Dummy', 'AnotherMockDummy');
+Mock::generate('Dummy', 'MockDummyWithExtraMethods', array('extraMethod'));
+
+class TestOfMockGeneration extends UnitTestCase {
+
+ function testCloning() {
+ $mock = &new MockDummy();
+ $this->assertTrue(method_exists($mock, "aMethod"));
+ $this->assertNull($mock->aMethod());
+ }
+
+ function testCloningWithExtraMethod() {
+ $mock = &new MockDummyWithExtraMethods();
+ $this->assertTrue(method_exists($mock, "extraMethod"));
+ }
+
+ function testCloningWithChosenClassName() {
+ $mock = &new AnotherMockDummy();
+ $this->assertTrue(method_exists($mock, "aMethod"));
+ }
+}
+
+class TestOfMockReturns extends UnitTestCase {
+
+ function testDefaultReturn() {
+ $mock = &new MockDummy();
+ $mock->setReturnValue("aMethod", "aaa");
+ $this->assertIdentical($mock->aMethod(), "aaa");
+ $this->assertIdentical($mock->aMethod(), "aaa");
+ }
+
+ function testParameteredReturn() {
+ $mock = &new MockDummy();
+ $mock->setReturnValue('aMethod', 'aaa', array(1, 2, 3));
+ $this->assertNull($mock->aMethod());
+ $this->assertIdentical($mock->aMethod(1, 2, 3), 'aaa');
+ }
+
+ function testReferenceReturned() {
+ $mock = &new MockDummy();
+ $object = new Dummy();
+ $mock->setReturnReference('aMethod', $object, array(1, 2, 3));
+ $this->assertReference($zref = &$mock->aMethod(1, 2, 3), $object);
+ }
+
+ function testPatternMatchReturn() {
+ $mock = &new MockDummy();
+ $mock->setReturnValue(
+ "aMethod",
+ "aaa",
+ array(new PatternExpectation('/hello/i')));
+ $this->assertIdentical($mock->aMethod('Hello'), "aaa");
+ $this->assertNull($mock->aMethod('Goodbye'));
+ }
+
+ function testMultipleMethods() {
+ $mock = &new MockDummy();
+ $mock->setReturnValue("aMethod", 100, array(1));
+ $mock->setReturnValue("aMethod", 200, array(2));
+ $mock->setReturnValue("anotherMethod", 10, array(1));
+ $mock->setReturnValue("anotherMethod", 20, array(2));
+ $this->assertIdentical($mock->aMethod(1), 100);
+ $this->assertIdentical($mock->anotherMethod(1), 10);
+ $this->assertIdentical($mock->aMethod(2), 200);
+ $this->assertIdentical($mock->anotherMethod(2), 20);
+ }
+
+ function testReturnSequence() {
+ $mock = &new MockDummy();
+ $mock->setReturnValueAt(0, "aMethod", "aaa");
+ $mock->setReturnValueAt(1, "aMethod", "bbb");
+ $mock->setReturnValueAt(3, "aMethod", "ddd");
+ $this->assertIdentical($mock->aMethod(), "aaa");
+ $this->assertIdentical($mock->aMethod(), "bbb");
+ $this->assertNull($mock->aMethod());
+ $this->assertIdentical($mock->aMethod(), "ddd");
+ }
+
+ function testReturnReferenceSequence() {
+ $mock = &new MockDummy();
+ $object = new Dummy();
+ $mock->setReturnReferenceAt(1, "aMethod", $object);
+ $this->assertNull($mock->aMethod());
+ $this->assertReference($zref =& $mock->aMethod(), $object);
+ $this->assertNull($mock->aMethod());
+ }
+
+ function testComplicatedReturnSequence() {
+ $mock = &new MockDummy();
+ $object = new Dummy();
+ $mock->setReturnValueAt(1, "aMethod", "aaa", array("a"));
+ $mock->setReturnValueAt(1, "aMethod", "bbb");
+ $mock->setReturnReferenceAt(2, "aMethod", $object, array('*', 2));
+ $mock->setReturnValueAt(2, "aMethod", "value", array('*', 3));
+ $mock->setReturnValue("aMethod", 3, array(3));
+ $this->assertNull($mock->aMethod());
+ $this->assertEqual($mock->aMethod("a"), "aaa");
+ $this->assertReference($zref =& $mock->aMethod(1, 2), $object);
+ $this->assertEqual($mock->aMethod(3), 3);
+ $this->assertNull($mock->aMethod());
+ }
+
+ function testMultipleMethodSequences() {
+ $mock = &new MockDummy();
+ $mock->setReturnValueAt(0, "aMethod", "aaa");
+ $mock->setReturnValueAt(1, "aMethod", "bbb");
+ $mock->setReturnValueAt(0, "anotherMethod", "ccc");
+ $mock->setReturnValueAt(1, "anotherMethod", "ddd");
+ $this->assertIdentical($mock->aMethod(), "aaa");
+ $this->assertIdentical($mock->anotherMethod(), "ccc");
+ $this->assertIdentical($mock->aMethod(), "bbb");
+ $this->assertIdentical($mock->anotherMethod(), "ddd");
+ }
+
+ function testSequenceFallback() {
+ $mock = &new MockDummy();
+ $mock->setReturnValueAt(0, "aMethod", "aaa", array('a'));
+ $mock->setReturnValueAt(1, "aMethod", "bbb", array('a'));
+ $mock->setReturnValue("aMethod", "AAA");
+ $this->assertIdentical($mock->aMethod('a'), "aaa");
+ $this->assertIdentical($mock->aMethod('b'), "AAA");
+ }
+
+ function testMethodInterference() {
+ $mock = &new MockDummy();
+ $mock->setReturnValueAt(0, "anotherMethod", "aaa");
+ $mock->setReturnValue("aMethod", "AAA");
+ $this->assertIdentical($mock->aMethod(), "AAA");
+ $this->assertIdentical($mock->anotherMethod(), "aaa");
+ }
+}
+
+class TestOfMockExpectationsThatPass extends UnitTestCase {
+
+ function testAnyArgument() {
+ $mock = &new MockDummy();
+ $mock->expect('aMethod', array('*'));
+ $mock->aMethod(1);
+ $mock->aMethod('hello');
+ }
+
+ function testAnyTwoArguments() {
+ $mock = &new MockDummy();
+ $mock->expect('aMethod', array('*', '*'));
+ $mock->aMethod(1, 2);
+ }
+
+ function testSpecificArgument() {
+ $mock = &new MockDummy();
+ $mock->expect('aMethod', array(1));
+ $mock->aMethod(1);
+ }
+
+ function testExpectation() {
+ $mock = &new MockDummy();
+ $mock->expect('aMethod', array(new IsAExpectation('Dummy')));
+ $mock->aMethod(new Dummy());
+ }
+
+ function testArgumentsInSequence() {
+ $mock = &new MockDummy();
+ $mock->expectAt(0, 'aMethod', array(1, 2));
+ $mock->expectAt(1, 'aMethod', array(3, 4));
+ $mock->aMethod(1, 2);
+ $mock->aMethod(3, 4);
+ }
+
+ function testAtLeastOnceSatisfiedByOneCall() {
+ $mock = &new MockDummy();
+ $mock->expectAtLeastOnce('aMethod');
+ $mock->aMethod();
+ }
+
+ function testAtLeastOnceSatisfiedByTwoCalls() {
+ $mock = &new MockDummy();
+ $mock->expectAtLeastOnce('aMethod');
+ $mock->aMethod();
+ $mock->aMethod();
+ }
+
+ function testOnceSatisfiedByOneCall() {
+ $mock = &new MockDummy();
+ $mock->expectOnce('aMethod');
+ $mock->aMethod();
+ }
+
+ function testMinimumCallsSatisfiedByEnoughCalls() {
+ $mock = &new MockDummy();
+ $mock->expectMinimumCallCount('aMethod', 1);
+ $mock->aMethod();
+ }
+
+ function testMinimumCallsSatisfiedByTooManyCalls() {
+ $mock = &new MockDummy();
+ $mock->expectMinimumCallCount('aMethod', 3);
+ $mock->aMethod();
+ $mock->aMethod();
+ $mock->aMethod();
+ $mock->aMethod();
+ }
+
+ function testMaximumCallsSatisfiedByEnoughCalls() {
+ $mock = &new MockDummy();
+ $mock->expectMaximumCallCount('aMethod', 1);
+ $mock->aMethod();
+ }
+
+ function testMaximumCallsSatisfiedByNoCalls() {
+ $mock = &new MockDummy();
+ $mock->expectMaximumCallCount('aMethod', 1);
+ }
+}
+
+class MockWithInjectedTestCase extends SimpleMock {
+ function &_getCurrentTestCase() {
+ $context = &SimpleTest::getContext();
+ $test = &$context->getTest();
+ return $test->getMockedTest();
+ }
+}
+SimpleTest::setMockBaseClass('MockWithInjectedTestCase');
+Mock::generate('Dummy', 'MockDummyWithInjectedTestCase');
+SimpleTest::setMockBaseClass('SimpleMock');
+Mock::generate('SimpleTestCase');
+
+class LikeExpectation extends IdenticalExpectation {
+ function LikeExpectation($expectation) {
+ $expectation->_message = '';
+ $this->IdenticalExpectation($expectation);
+ }
+
+ function test($compare) {
+ $compare->_message = '';
+ return parent::test($compare);
+ }
+
+ function testMessage($compare) {
+ $compare->_message = '';
+ return parent::testMessage($compare);
+ }
+}
+
+class TestOfMockExpectations extends UnitTestCase {
+ var $test;
+
+ function setUp() {
+ $this->test = &new MockSimpleTestCase();
+ }
+
+ function &getMockedTest() {
+ return $this->test;
+ }
+
+ function testSettingExpectationOnNonMethodThrowsError() {
+ $mock = &new MockDummyWithInjectedTestCase();
+ $mock->expectMaximumCallCount('aMissingMethod', 2);
+ $this->assertError();
+ }
+
+ function testMaxCallsDetectsOverrun() {
+ $this->test->expectOnce('assert', array(
+ new LikeExpectation(new MaximumCallCountExpectation('aMethod', 2)),
+ 3));
+ $mock = &new MockDummyWithInjectedTestCase();
+ $mock->expectMaximumCallCount('aMethod', 2);
+ $mock->aMethod();
+ $mock->aMethod();
+ $mock->aMethod();
+ $mock->_mock->atTestEnd('testSomething', $this->test);
+ }
+
+ function testTallyOnMaxCallsSendsPassOnUnderrun() {
+ $this->test->expectOnce('assert', array(
+ new LikeExpectation(new MaximumCallCountExpectation('aMethod', 2)),
+ 2));
+ $mock = &new MockDummyWithInjectedTestCase();
+ $mock->expectMaximumCallCount("aMethod", 2);
+ $mock->aMethod();
+ $mock->aMethod();
+ $mock->_mock->atTestEnd('testSomething', $this->test);
+ }
+
+ function testExpectNeverDetectsOverrun() {
+ $this->test->expectOnce('assert', array(
+ new LikeExpectation(new MaximumCallCountExpectation('aMethod', 0)),
+ 1));
+ $mock = &new MockDummyWithInjectedTestCase();
+ $mock->expectNever('aMethod');
+ $mock->aMethod();
+ $mock->_mock->atTestEnd('testSomething', $this->test);
+ }
+
+ function testTallyOnExpectNeverStillSendsPassOnUnderrun() {
+ $this->test->expectOnce('assert', array(
+ new LikeExpectation(new MaximumCallCountExpectation('aMethod', 0)),
+ 0));
+ $mock = &new MockDummyWithInjectedTestCase();
+ $mock->expectNever('aMethod');
+ $mock->_mock->atTestEnd('testSomething', $this->test);
+ }
+
+ function testMinCalls() {
+ $this->test->expectOnce('assert', array(
+ new LikeExpectation(new MinimumCallCountExpectation('aMethod', 2)),
+ 2));
+ $mock = &new MockDummyWithInjectedTestCase();
+ $mock->expectMinimumCallCount('aMethod', 2);
+ $mock->aMethod();
+ $mock->aMethod();
+ $mock->_mock->atTestEnd('testSomething', $this->test);
+ }
+
+ function testFailedNever() {
+ $this->test->expectOnce('assert', array(
+ new LikeExpectation(new MaximumCallCountExpectation('aMethod', 0)),
+ 1));
+ $mock = &new MockDummyWithInjectedTestCase();
+ $mock->expectNever('aMethod');
+ $mock->aMethod();
+ $mock->_mock->atTestEnd('testSomething', $this->test);
+ }
+
+ function testUnderOnce() {
+ $this->test->expectOnce('assert', array(
+ new LikeExpectation(new CallCountExpectation('aMethod', 1)),
+ 0));
+ $mock = &new MockDummyWithInjectedTestCase();
+ $mock->expectOnce('aMethod');
+ $mock->_mock->atTestEnd('testSomething', $this->test);
+ }
+
+ function testOverOnce() {
+ $this->test->expectOnce('assert', array(
+ new LikeExpectation(new CallCountExpectation('aMethod', 1)),
+ 2));
+ $mock = &new MockDummyWithInjectedTestCase();
+ $mock->expectOnce('aMethod');
+ $mock->aMethod();
+ $mock->aMethod();
+ $mock->_mock->atTestEnd('testSomething', $this->test);
+ }
+
+ function testUnderAtLeastOnce() {
+ $this->test->expectOnce('assert', array(
+ new LikeExpectation(new MinimumCallCountExpectation('aMethod', 1)),
+ 0));
+ $mock = &new MockDummyWithInjectedTestCase();
+ $mock->expectAtLeastOnce("aMethod");
+ $mock->_mock->atTestEnd('testSomething', $this->test);
+ }
+
+ function testZeroArguments() {
+ $this->test->expectOnce('assert', array(
+ new LikeExpectation(new ParametersExpectation(array())),
+ array(),
+ '*'));
+ $mock = &new MockDummyWithInjectedTestCase();
+ $mock->expect("aMethod", array());
+ $mock->aMethod();
+ $mock->_mock->atTestEnd('testSomething', $this->test);
+ }
+
+ function testExpectedArguments() {
+ $this->test->expectOnce('assert', array(
+ new LikeExpectation(new ParametersExpectation(array(1, 2, 3))),
+ array(1, 2, 3),
+ '*'));
+ $mock = &new MockDummyWithInjectedTestCase();
+ $mock->expect('aMethod', array(1, 2, 3));
+ $mock->aMethod(1, 2, 3);
+ $mock->_mock->atTestEnd('testSomething', $this->test);
+ }
+
+ function testFailedArguments() {
+ $this->test->expectOnce('assert', array(
+ new LikeExpectation(new ParametersExpectation(array('this'))),
+ array('that'),
+ '*'));
+ $mock = &new MockDummyWithInjectedTestCase();
+ $mock->expect('aMethod', array('this'));
+ $mock->aMethod('that');
+ $mock->_mock->atTestEnd('testSomething', $this->test);
+ }
+
+ function testWildcardsAreTranslatedToAnythingExpectations() {
+ $this->test->expectOnce('assert', array(
+ new LikeExpectation(new ParametersExpectation(array(
+ new AnythingExpectation(), 123, new AnythingExpectation()))),
+ array(100, 123, 101),
+ '*'));
+ $mock = &new MockDummyWithInjectedTestCase($this);
+ $mock->expect("aMethod", array('*', 123, '*'));
+ $mock->aMethod(100, 123, 101);
+ $mock->_mock->atTestEnd('testSomething', $this->test);
+ }
+
+ function testSpecificPassingSequence() {
+ $this->test->expectAt(0, 'assert', array(
+ new LikeExpectation(new ParametersExpectation(array(1, 2, 3))),
+ array(1, 2, 3),
+ '*'));
+ $this->test->expectAt(1, 'assert', array(
+ new LikeExpectation(new ParametersExpectation(array('Hello'))),
+ array('Hello'),
+ '*'));
+ $mock = &new MockDummyWithInjectedTestCase();
+ $mock->expectAt(1, 'aMethod', array(1, 2, 3));
+ $mock->expectAt(2, 'aMethod', array('Hello'));
+ $mock->aMethod();
+ $mock->aMethod(1, 2, 3);
+ $mock->aMethod('Hello');
+ $mock->aMethod();
+ $mock->_mock->atTestEnd('testSomething', $this->test);
+ }
+
+ function testNonArrayForExpectedParametersGivesError() {
+ $mock = &new MockDummyWithInjectedTestCase();
+ $mock->expect("aMethod", "foo");
+ $this->assertErrorPattern('/\$args.*not an array/i');
+ $mock->aMethod();
+ $mock->tally();
+ $mock->_mock->atTestEnd('testSomething', $this->test);
+ }
+}
+
+class TestOfMockComparisons extends UnitTestCase {
+
+ function testEqualComparisonOfMocksDoesNotCrash() {
+ $expectation = &new EqualExpectation(new MockDummy());
+ $this->assertTrue($expectation->test(new MockDummy(), true));
+ }
+
+ function testIdenticalComparisonOfMocksDoesNotCrash() {
+ $expectation = &new IdenticalExpectation(new MockDummy());
+ $this->assertTrue($expectation->test(new MockDummy()));
+ }
+}
+
+class ClassWithSpecialMethods {
+ function __get($name) { }
+ function __set($name, $value) { }
+ function __isset($name) { }
+ function __unset($name) { }
+ function __call($method, $arguments) { }
+ function __toString() { }
+}
+Mock::generate('ClassWithSpecialMethods');
+
+class TestOfSpecialMethods extends UnitTestCase {
+ function skip() {
+ $this->skipIf(version_compare(phpversion(), '5', '<='), 'Overloading not tested unless PHP 5+');
+ }
+
+ function testCanMockTheThingAtAll() {
+ $mock = new MockClassWithSpecialMethods();
+ }
+
+ function testReturnFromSpecialAccessor() {
+ $mock = &new MockClassWithSpecialMethods();
+ $mock->setReturnValue('__get', '1st Return', array('first'));
+ $mock->setReturnValue('__get', '2nd Return', array('second'));
+ $this->assertEqual($mock->first, '1st Return');
+ $this->assertEqual($mock->second, '2nd Return');
+ }
+
+ function testcanExpectTheSettingOfValue() {
+ $mock = &new MockClassWithSpecialMethods();
+ $mock->expectOnce('__set', array('a', 'A'));
+ $mock->a = 'A';
+ }
+
+ function testCanSimulateAnOverloadmethod() {
+ $mock = &new MockClassWithSpecialMethods();
+ $mock->expectOnce('__call', array('amOverloaded', array('A')));
+ $mock->setReturnValue('__call', 'aaa');
+ $this->assertIdentical($mock->amOverloaded('A'), 'aaa');
+ }
+
+ function testCanEmulateIsset() {
+ $mock = &new MockClassWithSpecialMethods();
+ $mock->setReturnValue('__isset', true);
+ $this->assertIdentical(isset($mock->a), true);
+ }
+
+ function testCanExpectUnset() {
+ $mock = &new MockClassWithSpecialMethods();
+ $mock->expectOnce('__unset', array('a'));
+ unset($mock->a);
+ }
+
+ function testToStringMagic() {
+ $mock = &new MockClassWithSpecialMethods();
+ $mock->expectOnce('__toString');
+ $mock->setReturnValue('__toString', 'AAA');
+ ob_start();
+ print $mock;
+ $output = ob_get_contents();
+ ob_end_clean();
+ $this->assertEqual($output, 'AAA');
+ }
+}
+
+if (version_compare(phpversion(), '5', '>=')) {
+ $class = 'class WithStaticMethod { ';
+ $class .= ' static function aStaticMethod() { } ';
+ $class .= '}';
+ eval($class);
+}
+Mock::generate('WithStaticMethod');
+
+class TestOfMockingClassesWithStaticMethods extends UnitTestCase {
+ function skip() {
+ $this->skipUnless(version_compare(phpversion(), '5', '>='), 'Static methods not tested unless PHP 5+');
+ }
+
+ function testStaticMethodIsMockedAsStatic() {
+ $mock = new WithStaticMethod();
+ $reflection = new ReflectionClass($mock);
+ $method = $reflection->getMethod('aStaticMethod');
+ $this->assertTrue($method->isStatic());
+ }
+}
+
+if (version_compare(phpversion(), '5', '>=')) {
+ class MockTestException extends Exception { }
+}
+
+class TestOfThrowingExceptionsFromMocks extends UnitTestCase {
+ function skip() {
+ $this->skipUnless(version_compare(phpversion(), '5', '>='), 'Exception throwing not tested unless PHP 5+');
+ }
+
+ function testCanThrowOnMethodCall() {
+ $mock = new MockDummy();
+ $mock->throwOn('aMethod');
+ $this->expectException();
+ $mock->aMethod();
+ }
+
+ function testCanThrowSpecificExceptionOnMethodCall() {
+ $mock = new MockDummy();
+ $mock->throwOn('aMethod', new MockTestException());
+ $this->expectException();
+ $mock->aMethod();
+ }
+
+ function testThrowsOnlyWhenCallSignatureMatches() {
+ $mock = new MockDummy();
+ $mock->throwOn('aMethod', new MockTestException(), array(3));
+ $mock->aMethod(1);
+ $mock->aMethod(2);
+ $this->expectException();
+ $mock->aMethod(3);
+ }
+
+ function testCanThrowOnParticularInvocation() {
+ $mock = new MockDummy();
+ $mock->throwAt(2, 'aMethod', new MockTestException());
+ $mock->aMethod();
+ $mock->aMethod();
+ $this->expectException();
+ $mock->aMethod();
+ }
+}
+
+class TestOfThrowingErrorsFromMocks extends UnitTestCase {
+
+ function testCanGenerateErrorFromMethodCall() {
+ $mock = new MockDummy();
+ $mock->errorOn('aMethod', 'Ouch!');
+ $this->expectError('Ouch!');
+ $mock->aMethod();
+ }
+
+ function testGeneratesErrorOnlyWhenCallSignatureMatches() {
+ $mock = new MockDummy();
+ $mock->errorOn('aMethod', 'Ouch!', array(3));
+ $mock->aMethod(1);
+ $mock->aMethod(2);
+ $this->expectError();
+ $mock->aMethod(3);
+ }
+
+ function testCanGenerateErrorOnParticularInvocation() {
+ $mock = new MockDummy();
+ $mock->errorAt(2, 'aMethod', 'Ouch!');
+ $mock->aMethod();
+ $mock->aMethod();
+ $this->expectError();
+ $mock->aMethod();
+ }
+}
+
+Mock::generatePartial('Dummy', 'TestDummy', array('anotherMethod'));
+
+class TestOfPartialMocks extends UnitTestCase {
+
+ function testMethodReplacementWithNoBehaviourReturnsNull() {
+ $mock = &new TestDummy();
+ $this->assertEqual($mock->aMethod(99), 99);
+ $this->assertNull($mock->anotherMethod());
+ }
+
+ function testSettingReturns() {
+ $mock = &new TestDummy();
+ $mock->setReturnValue('anotherMethod', 33, array(3));
+ $mock->setReturnValue('anotherMethod', 22);
+ $mock->setReturnValueAt(2, 'anotherMethod', 44, array(3));
+ $this->assertEqual($mock->anotherMethod(), 22);
+ $this->assertEqual($mock->anotherMethod(3), 33);
+ $this->assertEqual($mock->anotherMethod(3), 44);
+ }
+
+ function testReferences() {
+ $mock = &new TestDummy();
+ $object = new Dummy();
+ $mock->setReturnReferenceAt(0, 'anotherMethod', $object, array(3));
+ $this->assertReference($zref =& $mock->anotherMethod(3), $object);
+ }
+
+ function testExpectations() {
+ $mock = &new TestDummy();
+ $mock->expectCallCount('anotherMethod', 2);
+ $mock->expect('anotherMethod', array(77));
+ $mock->expectAt(1, 'anotherMethod', array(66));
+ $mock->anotherMethod(77);
+ $mock->anotherMethod(66);
+ }
+
+ function testSettingExpectationOnMissingMethodThrowsError() {
+ $mock = &new TestDummy();
+ $mock->expectCallCount('aMissingMethod', 2);
+ $this->assertError();
+ }
+}
+
+class ConstructorSuperClass {
+ function ConstructorSuperClass() { }
+}
+
+class ConstructorSubClass extends ConstructorSuperClass {
+}
+
+class TestOfPHP4StyleSuperClassConstruct extends UnitTestCase {
+ /*
+ * This addresses issue #1231401. Without the fix in place, this will
+ * generate a fatal PHP error.
+ */
+ function testBasicConstruct() {
+ Mock::generate('ConstructorSubClass');
+ $mock = &new MockConstructorSubClass();
+ $this->assertIsA($mock, 'ConstructorSubClass');
+ $this->assertTrue(method_exists($mock, 'ConstructorSuperClass'));
+ }
+}
+
+class TestOfPHP5StaticMethodMocking extends UnitTestCase {
+ function skip() {
+ $this->skipIf(version_compare(phpversion(), '5', '<='), 'Static methods not tested unless PHP 5+');
+ }
+
+ function testCanCreateAMockObjectWithStaticMethodsWithoutError() {
+ eval('
+ class SimpleObjectContainingStaticMethod {
+ static function someStatic() { }
+ }
+ ');
+
+ Mock::generate('SimpleObjectContainingStaticMethod');
+ $this->assertNoErrors();
+ }
+}
+
+class TestOfPHP5AbstractMethodMocking extends UnitTestCase {
+ function skip() {
+ $this->skipIf(version_compare(phpversion(), '5', '<='), 'Abstract class/methods not tested unless PHP 5+');
+ }
+
+ function testCanCreateAMockObjectFromAnAbstractWithProperFunctionDeclarations() {
+ eval('
+ abstract class SimpleAbstractClassContainingAbstractMethods {
+ abstract function anAbstract();
+ abstract function anAbstractWithParameter($foo);
+ abstract function anAbstractWithMultipleParameters($foo, $bar);
+ }
+ ');
+
+ Mock::generate('SimpleAbstractClassContainingAbstractMethods');
+ $this->assertNoErrors();
+
+ $this->assertTrue(
+ method_exists(
+ 'MockSimpleAbstractClassContainingAbstractMethods',
+ 'anAbstract'
+ )
+ );
+ $this->assertTrue(
+ method_exists(
+ 'MockSimpleAbstractClassContainingAbstractMethods',
+ 'anAbstractWithParameter'
+ )
+ );
+ $this->assertTrue(
+ method_exists(
+ 'MockSimpleAbstractClassContainingAbstractMethods',
+ 'anAbstractWithMultipleParameters'
+ )
+ );
+ }
+
+ function testMethodsDefinedAsAbstractInParentShouldHaveFullSignature() {
+ eval('
+ abstract class SimpleParentAbstractClassContainingAbstractMethods {
+ abstract function anAbstract();
+ abstract function anAbstractWithParameter($foo);
+ abstract function anAbstractWithMultipleParameters($foo, $bar);
+ }
+
+ class SimpleChildAbstractClassContainingAbstractMethods extends SimpleParentAbstractClassContainingAbstractMethods {
+ function anAbstract(){}
+ function anAbstractWithParameter($foo){}
+ function anAbstractWithMultipleParameters($foo, $bar){}
+ }
+
+ class EvenDeeperEmptyChildClass extends SimpleChildAbstractClassContainingAbstractMethods {}
+ ');
+
+ Mock::generate('SimpleChildAbstractClassContainingAbstractMethods');
+ $this->assertNoErrors();
+
+ $this->assertTrue(
+ method_exists(
+ 'MockSimpleChildAbstractClassContainingAbstractMethods',
+ 'anAbstract'
+ )
+ );
+ $this->assertTrue(
+ method_exists(
+ 'MockSimpleChildAbstractClassContainingAbstractMethods',
+ 'anAbstractWithParameter'
+ )
+ );
+ $this->assertTrue(
+ method_exists(
+ 'MockSimpleChildAbstractClassContainingAbstractMethods',
+ 'anAbstractWithMultipleParameters'
+ )
+ );
+
+ Mock::generate('EvenDeeperEmptyChildClass');
+ $this->assertNoErrors();
+
+ $this->assertTrue(
+ method_exists(
+ 'MockEvenDeeperEmptyChildClass',
+ 'anAbstract'
+ )
+ );
+ $this->assertTrue(
+ method_exists(
+ 'MockEvenDeeperEmptyChildClass',
+ 'anAbstractWithParameter'
+ )
+ );
+ $this->assertTrue(
+ method_exists(
+ 'MockEvenDeeperEmptyChildClass',
+ 'anAbstractWithMultipleParameters'
+ )
+ );
+ }
+}
+
+?>
diff --git a/site/vendors/simpletest/test/page_test.php b/site/vendors/simpletest/test/page_test.php
new file mode 100644
index 0000000..76e6a51
--- /dev/null
+++ b/site/vendors/simpletest/test/page_test.php
@@ -0,0 +1,903 @@
+<?php
+// $Id: page_test.php 1559 2007-07-16 18:13:24Z lastcraft $
+require_once(dirname(__FILE__) . '/../autorun.php');
+require_once(dirname(__FILE__) . '/../expectation.php');
+require_once(dirname(__FILE__) . '/../http.php');
+require_once(dirname(__FILE__) . '/../page.php');
+require_once(dirname(__FILE__) . '/../parser.php');
+Mock::generate('SimpleHtmlSaxParser');
+Mock::generate('SimplePage');
+Mock::generate('SimpleHttpResponse');
+Mock::generate('SimpleHttpHeaders');
+Mock::generate('SimplePageBuilder');
+Mock::generatePartial(
+ 'SimplePageBuilder',
+ 'PartialSimplePageBuilder',
+ array('_createPage', '_createParser'));
+
+class TestOfPageBuilder extends UnitTestCase {
+
+ function testLink() {
+ $tag = &new SimpleAnchorTag(array('href' => 'http://somewhere'));
+ $tag->addContent('Label');
+
+ $page = &new MockSimplePage();
+ $page->expectArguments('acceptTag', array($tag));
+ $page->expectCallCount('acceptTag', 1);
+
+ $builder = &new PartialSimplePageBuilder();
+ $builder->setReturnReference('_createPage', $page);
+ $builder->setReturnReference('_createParser', new MockSimpleHtmlSaxParser());
+ $builder->SimplePageBuilder();
+
+ $builder->parse(new MockSimpleHttpResponse());
+ $this->assertTrue($builder->startElement(
+ 'a',
+ array('href' => 'http://somewhere')));
+ $this->assertTrue($builder->addContent('Label'));
+ $this->assertTrue($builder->endElement('a'));
+ }
+
+ function testLinkWithId() {
+ $tag = &new SimpleAnchorTag(array("href" => "http://somewhere", "id" => "44"));
+ $tag->addContent("Label");
+
+ $page = &new MockSimplePage();
+ $page->expectArguments("acceptTag", array($tag));
+ $page->expectCallCount("acceptTag", 1);
+
+ $builder = &new PartialSimplePageBuilder();
+ $builder->setReturnReference('_createPage', $page);
+ $builder->setReturnReference('_createParser', new MockSimpleHtmlSaxParser());
+ $builder->SimplePageBuilder();
+
+ $builder->parse(new MockSimpleHttpResponse());
+ $this->assertTrue($builder->startElement(
+ "a",
+ array("href" => "http://somewhere", "id" => "44")));
+ $this->assertTrue($builder->addContent("Label"));
+ $this->assertTrue($builder->endElement("a"));
+ }
+
+ function testLinkExtraction() {
+ $tag = &new SimpleAnchorTag(array("href" => "http://somewhere"));
+ $tag->addContent("Label");
+
+ $page = &new MockSimplePage();
+ $page->expectArguments("acceptTag", array($tag));
+ $page->expectCallCount("acceptTag", 1);
+
+ $builder = &new PartialSimplePageBuilder();
+ $builder->setReturnReference('_createPage', $page);
+ $builder->setReturnReference('_createParser', new MockSimpleHtmlSaxParser());
+ $builder->SimplePageBuilder();
+
+ $builder->parse(new MockSimpleHttpResponse());
+ $this->assertTrue($builder->addContent("Starting stuff"));
+ $this->assertTrue($builder->startElement(
+ "a",
+ array("href" => "http://somewhere")));
+ $this->assertTrue($builder->addContent("Label"));
+ $this->assertTrue($builder->endElement("a"));
+ $this->assertTrue($builder->addContent("Trailing stuff"));
+ }
+
+ function testMultipleLinks() {
+ $a1 = new SimpleAnchorTag(array("href" => "http://somewhere"));
+ $a1->addContent("1");
+
+ $a2 = new SimpleAnchorTag(array("href" => "http://elsewhere"));
+ $a2->addContent("2");
+
+ $page = &new MockSimplePage();
+ $page->expectArgumentsAt(0, "acceptTag", array($a1));
+ $page->expectArgumentsAt(1, "acceptTag", array($a2));
+ $page->expectCallCount("acceptTag", 2);
+
+ $builder = &new PartialSimplePageBuilder();
+ $builder->setReturnReference('_createPage', $page);
+ $builder->setReturnReference('_createParser', new MockSimpleHtmlSaxParser());
+ $builder->SimplePageBuilder();
+
+ $builder->parse(new MockSimpleHttpResponse());
+ $builder->startElement("a", array("href" => "http://somewhere"));
+ $builder->addContent("1");
+ $builder->endElement("a");
+ $builder->addContent("Padding");
+ $builder->startElement("a", array("href" => "http://elsewhere"));
+ $builder->addContent("2");
+ $builder->endElement("a");
+ }
+
+ function testTitle() {
+ $tag = &new SimpleTitleTag(array());
+ $tag->addContent("HereThere");
+
+ $page = &new MockSimplePage();
+ $page->expectArguments("acceptTag", array($tag));
+ $page->expectCallCount("acceptTag", 1);
+
+ $builder = &new PartialSimplePageBuilder();
+ $builder->setReturnReference('_createPage', $page);
+ $builder->setReturnReference('_createParser', new MockSimpleHtmlSaxParser());
+ $builder->SimplePageBuilder();
+
+ $builder->parse(new MockSimpleHttpResponse());
+ $builder->startElement("title", array());
+ $builder->addContent("Here");
+ $builder->addContent("There");
+ $builder->endElement("title");
+ }
+
+ function testForm() {
+ $page = &new MockSimplePage();
+ $page->expectOnce("acceptFormStart", array(new SimpleFormTag(array())));
+ $page->expectOnce("acceptFormEnd", array());
+
+ $builder = &new PartialSimplePageBuilder();
+ $builder->setReturnReference('_createPage', $page);
+ $builder->setReturnReference('_createParser', new MockSimpleHtmlSaxParser());
+ $builder->SimplePageBuilder();
+
+ $builder->parse(new MockSimpleHttpResponse());
+ $builder->startElement("form", array());
+ $builder->addContent("Stuff");
+ $builder->endElement("form");
+ }
+}
+
+class TestOfPageParsing extends UnitTestCase {
+
+ function testParseMechanics() {
+ $parser = &new MockSimpleHtmlSaxParser();
+ $parser->expectOnce('parse', array('stuff'));
+
+ $page = &new MockSimplePage();
+ $page->expectOnce('acceptPageEnd');
+
+ $builder = &new PartialSimplePageBuilder();
+ $builder->setReturnReference('_createPage', $page);
+ $builder->setReturnReference('_createParser', $parser);
+ $builder->SimplePageBuilder();
+
+ $response = &new MockSimpleHttpResponse();
+ $response->setReturnValue('getContent', 'stuff');
+ $builder->parse($response);
+ }
+}
+
+class TestOfPageInterface extends UnitTestCase {
+
+ function testInterfaceOnEmptyPage() {
+ $page = &new SimplePage();
+ $this->assertEqual($page->getTransportError(), 'No page fetched yet');
+ $this->assertIdentical($page->getRaw(), false);
+ $this->assertIdentical($page->getHeaders(), false);
+ $this->assertIdentical($page->getMimeType(), false);
+ $this->assertIdentical($page->getResponseCode(), false);
+ $this->assertIdentical($page->getAuthentication(), false);
+ $this->assertIdentical($page->getRealm(), false);
+ $this->assertFalse($page->hasFrames());
+ $this->assertIdentical($page->getUrls(), array());
+ $this->assertIdentical($page->getTitle(), false);
+ }
+}
+
+class TestOfPageHeaders extends UnitTestCase {
+
+ function testUrlAccessor() {
+ $headers = &new MockSimpleHttpHeaders();
+
+ $response = &new MockSimpleHttpResponse();
+ $response->setReturnValue('getHeaders', $headers);
+ $response->setReturnValue('getMethod', 'POST');
+ $response->setReturnValue('getUrl', new SimpleUrl('here'));
+ $response->setReturnValue('getRequestData', array('a' => 'A'));
+
+ $page = &new SimplePage($response);
+ $this->assertEqual($page->getMethod(), 'POST');
+ $this->assertEqual($page->getUrl(), new SimpleUrl('here'));
+ $this->assertEqual($page->getRequestData(), array('a' => 'A'));
+ }
+
+ function testTransportError() {
+ $response = &new MockSimpleHttpResponse();
+ $response->setReturnValue('getError', 'Ouch');
+
+ $page = &new SimplePage($response);
+ $this->assertEqual($page->getTransportError(), 'Ouch');
+ }
+
+ function testHeadersAccessor() {
+ $headers = &new MockSimpleHttpHeaders();
+ $headers->setReturnValue('getRaw', 'My: Headers');
+
+ $response = &new MockSimpleHttpResponse();
+ $response->setReturnValue('getHeaders', $headers);
+
+ $page = &new SimplePage($response);
+ $this->assertEqual($page->getHeaders(), 'My: Headers');
+ }
+
+ function testMimeAccessor() {
+ $headers = &new MockSimpleHttpHeaders();
+ $headers->setReturnValue('getMimeType', 'text/html');
+
+ $response = &new MockSimpleHttpResponse();
+ $response->setReturnValue('getHeaders', $headers);
+
+ $page = &new SimplePage($response);
+ $this->assertEqual($page->getMimeType(), 'text/html');
+ }
+
+ function testResponseAccessor() {
+ $headers = &new MockSimpleHttpHeaders();
+ $headers->setReturnValue('getResponseCode', 301);
+
+ $response = &new MockSimpleHttpResponse();
+ $response->setReturnValue('getHeaders', $headers);
+
+ $page = &new SimplePage($response);
+ $this->assertIdentical($page->getResponseCode(), 301);
+ }
+
+ function testAuthenticationAccessors() {
+ $headers = &new MockSimpleHttpHeaders();
+ $headers->setReturnValue('getAuthentication', 'Basic');
+ $headers->setReturnValue('getRealm', 'Secret stuff');
+
+ $response = &new MockSimpleHttpResponse();
+ $response->setReturnValue('getHeaders', $headers);
+
+ $page = &new SimplePage($response);
+ $this->assertEqual($page->getAuthentication(), 'Basic');
+ $this->assertEqual($page->getRealm(), 'Secret stuff');
+ }
+}
+
+class TestOfHtmlPage extends UnitTestCase {
+
+ function testRawAccessor() {
+ $response = &new MockSimpleHttpResponse();
+ $response->setReturnValue('getContent', 'Raw HTML');
+
+ $page = &new SimplePage($response);
+ $this->assertEqual($page->getRaw(), 'Raw HTML');
+ }
+
+ function testTextAccessor() {
+ $response = &new MockSimpleHttpResponse();
+ $response->setReturnValue('getContent', '<b>Some</b> &quot;messy&quot; HTML');
+
+ $page = &new SimplePage($response);
+ $this->assertEqual($page->getText(), 'Some "messy" HTML');
+ }
+
+ function testNoLinks() {
+ $page = &new SimplePage(new MockSimpleHttpResponse());
+ $this->assertIdentical($page->getUrls(), array());
+ $this->assertIdentical($page->getUrlsByLabel('Label'), array());
+ }
+
+ function testAddAbsoluteLink() {
+ $link = &new SimpleAnchorTag(array('href' => 'http://somewhere.com'));
+ $link->addContent('Label');
+ $page = &new SimplePage(new MockSimpleHttpResponse());
+ $page->AcceptTag($link);
+ $this->assertEqual(
+ $page->getUrlsByLabel('Label'),
+ array(new SimpleUrl('http://somewhere.com')));
+ }
+
+ function testAddStrictRelativeLink() {
+ $link = &new SimpleAnchorTag(array('href' => './somewhere.php'));
+ $link->addContent('Label');
+ $response = &new MockSimpleHttpResponse();
+ $response->setReturnValue('getUrl', new SimpleUrl('http://host/'));
+ $page = &new SimplePage($response);
+ $page->AcceptTag($link);
+ $this->assertEqual(
+ $page->getUrlsByLabel('Label'),
+ array(new SimpleUrl('http://host/somewhere.php')));
+ }
+
+ function testAddBareRelativeLink() {
+ $response = &new MockSimpleHttpResponse();
+ $response->setReturnValue('getUrl', new SimpleUrl('http://host/'));
+ $page = &new SimplePage($response);
+ $page->AcceptTag(new SimpleAnchorTag(array('href' => 'somewhere.php')));
+ $this->assertIdentical($page->getUrls(), array('http://host/somewhere.php'));
+ }
+
+ function testAddRelativeLinkWithBaseTag() {
+ $link = &new SimpleAnchorTag(array('href' => 'somewhere.php'));
+ $link->addContent('Label');
+ $response = &new MockSimpleHttpResponse();
+ $response->setReturnValue('getUrl', new SimpleUrl('http://host/'));
+ $page = &new SimplePage($response);
+ $page->AcceptTag($link);
+ $base = &new SimpleBaseTag(array('href' => 'www.lastcraft.com/stuff/'));
+ $page->AcceptTag($base);
+ $this->assertEqual(
+ $page->getUrlsByLabel('Label'),
+ array(new SimpleUrl('www.lastcraft.com/stuff/somewhere.php')));
+ }
+
+ function testAddAbsoluteLinkWithBaseTag() {
+ $link = &new SimpleAnchorTag(array('href' => 'http://here.com/somewhere.php'));
+ $link->addContent('Label');
+ $response = &new MockSimpleHttpResponse();
+ $response->setReturnValue('getUrl', new SimpleUrl('http://host/'));
+ $page = &new SimplePage($response);
+ $page->AcceptTag($link);
+ $base = &new SimpleBaseTag(array('href' => 'www.lastcraft.com/stuff/'));
+ $page->AcceptTag($base);
+ $this->assertEqual(
+ $page->getUrlsByLabel('Label'),
+ array(new SimpleUrl('http://here.com/somewhere.php')));
+ }
+
+ function testLinkIds() {
+ $link = &new SimpleAnchorTag(array('href' => './somewhere.php', 'id' => 33));
+ $link->addContent('Label');
+
+ $response = &new MockSimpleHttpResponse();
+ $response->setReturnValue('getUrl', new SimpleUrl('http://host/'));
+
+ $page = &new SimplePage($response);
+ $page->AcceptTag($link);
+
+ $this->assertEqual(
+ $page->getUrlsByLabel('Label'),
+ array(new SimpleUrl('http://host/somewhere.php')));
+ $this->assertFalse($page->getUrlById(0));
+ $this->assertEqual(
+ $page->getUrlById(33),
+ new SimpleUrl('http://host/somewhere.php'));
+ }
+
+ function testFindLinkWithNormalisation() {
+ $link = &new SimpleAnchorTag(array('href' => './somewhere.php', 'id' => 33));
+ $link->addContent(' <em>Long &amp; thin</em> ');
+
+ $response = &new MockSimpleHttpResponse();
+ $response->setReturnValue('getUrl', new SimpleUrl('http://host/'));
+
+ $page = &new SimplePage($response);
+ $page->AcceptTag($link);
+
+ $this->assertEqual(
+ $page->getUrlsByLabel('Long & thin'),
+ array(new SimpleUrl('http://host/somewhere.php')));
+ }
+
+ function testFindLinkWithImage() {
+ $link = &new SimpleAnchorTag(array('href' => './somewhere.php', 'id' => 33));
+ $link->addContent('<img src="pic.jpg" alt="&lt;A picture&gt;">');
+
+ $response = &new MockSimpleHttpResponse();
+ $response->setReturnValue('getUrl', new SimpleUrl('http://host/'));
+
+ $page = &new SimplePage($response);
+ $page->AcceptTag($link);
+
+ $this->assertEqual(
+ $page->getUrlsByLabel('<A picture>'),
+ array(new SimpleUrl('http://host/somewhere.php')));
+ }
+
+ function testTitleSetting() {
+ $title = &new SimpleTitleTag(array());
+ $title->addContent('Title');
+ $page = &new SimplePage(new MockSimpleHttpResponse());
+ $page->AcceptTag($title);
+ $this->assertEqual($page->getTitle(), 'Title');
+ }
+
+ function testFramesetAbsence() {
+ $url = new SimpleUrl('here');
+ $response = new MockSimpleHttpResponse();
+ $response->setReturnValue('getUrl', $url);
+ $page = &new SimplePage($response);
+ $this->assertFalse($page->hasFrames());
+ $this->assertIdentical($page->getFrameset(), false);
+ }
+
+ function testHasEmptyFrameset() {
+ $page = &new SimplePage(new MockSimpleHttpResponse());
+ $page->acceptFramesetStart(new SimpleTag('frameset', array()));
+ $page->acceptFramesetEnd();
+ $this->assertTrue($page->hasFrames());
+ $this->assertIdentical($page->getFrameset(), array());
+ }
+
+ function testFramesInPage() {
+ $response = &new MockSimpleHttpResponse();
+ $response->setReturnValue('getUrl', new SimpleUrl('http://here'));
+
+ $page = &new SimplePage($response);
+ $page->acceptFrame(new SimpleFrameTag(array('src' => '1.html')));
+ $page->acceptFramesetStart(new SimpleTag('frameset', array()));
+ $page->acceptFrame(new SimpleFrameTag(array('src' => '2.html')));
+ $page->acceptFrame(new SimpleFrameTag(array('src' => '3.html')));
+ $page->acceptFramesetEnd();
+ $page->acceptFrame(new SimpleFrameTag(array('src' => '4.html')));
+
+ $this->assertTrue($page->hasFrames());
+ $this->assertIdentical($page->getFrameset(), array(
+ 1 => new SimpleUrl('http://here/2.html'),
+ 2 => new SimpleUrl('http://here/3.html')));
+ }
+
+ function testNamedFramesInPage() {
+ $response = &new MockSimpleHttpResponse();
+ $response->setReturnValue('getUrl', new SimpleUrl('http://here'));
+
+ $page = &new SimplePage($response);
+ $page->acceptFramesetStart(new SimpleTag('frameset', array()));
+ $page->acceptFrame(new SimpleFrameTag(array('src' => '1.html')));
+ $page->acceptFrame(new SimpleFrameTag(array('src' => '2.html', 'name' => 'A')));
+ $page->acceptFrame(new SimpleFrameTag(array('src' => '3.html', 'name' => 'B')));
+ $page->acceptFrame(new SimpleFrameTag(array('src' => '4.html')));
+ $page->acceptFramesetEnd();
+
+ $this->assertTrue($page->hasFrames());
+ $this->assertIdentical($page->getFrameset(), array(
+ 1 => new SimpleUrl('http://here/1.html'),
+ 'A' => new SimpleUrl('http://here/2.html'),
+ 'B' => new SimpleUrl('http://here/3.html'),
+ 4 => new SimpleUrl('http://here/4.html')));
+ }
+
+ function testRelativeFramesRespectBaseTag() {
+ $response = &new MockSimpleHttpResponse();
+ $response->setReturnValue('getUrl', new SimpleUrl('http://here.com/'));
+ $page = &new SimplePage($response);
+
+ $base = &new SimpleBaseTag(array('href' => 'https://there.com/stuff/'));
+ $page->AcceptTag($base);
+
+ $page->acceptFramesetStart(new SimpleTag('frameset', array()));
+ $page->acceptFrame(new SimpleFrameTag(array('src' => '1.html')));
+ $page->acceptFramesetEnd();
+ $this->assertIdentical(
+ $page->getFrameset(),
+ array(1 => new SimpleUrl('https://there.com/stuff/1.html')));
+ }
+}
+
+class TestOfFormsCreatedFromEventStream extends UnitTestCase {
+
+ function testFormCanBeSubmitted() {
+ $page = &new SimplePage(new MockSimpleHttpResponse());
+ $page->acceptFormStart(
+ new SimpleFormTag(array('method' => 'GET', 'action' => 'here.php')));
+ $page->AcceptTag(
+ new SimpleSubmitTag(array('type' => 'submit', 'name' => 's')));
+ $page->acceptFormEnd();
+ $form = &$page->getFormBySubmit(new SimpleByLabel('Submit'));
+ $this->assertEqual(
+ $form->submitButton(new SimpleByLabel('Submit')),
+ new SimpleGetEncoding(array('s' => 'Submit')));
+ }
+
+ function testInputFieldCanBeReadBack() {
+ $page = &new SimplePage(new MockSimpleHttpResponse());
+ $page->acceptFormStart(
+ new SimpleFormTag(array("method" => "GET", "action" => "here.php")));
+ $page->AcceptTag(
+ new SimpleTextTag(array("type" => "text", "name" => "a", "value" => "A")));
+ $page->AcceptTag(
+ new SimpleSubmitTag(array("type" => "submit", "name" => "s")));
+ $page->acceptFormEnd();
+ $this->assertEqual($page->getField(new SimpleByName('a')), 'A');
+ }
+
+ function testInputFieldCanBeReadBackByLabel() {
+ $label = &new SimpleLabelTag(array());
+ $page = &new SimplePage(new MockSimpleHttpResponse());
+ $page->acceptFormStart(
+ new SimpleFormTag(array("method" => "GET", "action" => "here.php")));
+ $page->acceptLabelStart($label);
+ $label->addContent('l');
+ $page->AcceptTag(
+ new SimpleTextTag(array("type" => "text", "name" => "a", "value" => "A")));
+ $page->acceptLabelEnd();
+ $page->AcceptTag(
+ new SimpleSubmitTag(array("type" => "submit", "name" => "s")));
+ $page->acceptFormEnd();
+ $this->assertEqual($page->getField(new SimpleByLabel('l')), 'A');
+ }
+}
+
+class TestOfPageScraping extends UnitTestCase {
+
+ function &parse($response) {
+ $builder = &new SimplePageBuilder();
+ $page = &$builder->parse($response);
+ return $page;
+ }
+
+ function testEmptyPage() {
+ $page = &new SimplePage(new MockSimpleHttpResponse());
+ $this->assertIdentical($page->getUrls(), array());
+ $this->assertIdentical($page->getTitle(), false);
+ }
+
+ function testUninterestingPage() {
+ $response = &new MockSimpleHttpResponse();
+ $response->setReturnValue('getContent', '<html><body><p>Stuff</p></body></html>');
+ $page = &$this->parse($response);
+ $this->assertIdentical($page->getUrls(), array());
+ }
+
+ function testLinksPage() {
+ $raw = '<html>';
+ $raw .= '<a href="there.html">There</a>';
+ $raw .= '<a href="http://there.com/that.html" id="0">That page</a>';
+ $raw .= '</html>';
+ $response = &new MockSimpleHttpResponse();
+ $response->setReturnValue('getContent', $raw);
+ $response->setReturnValue('getUrl', new SimpleUrl('http://www.here.com/a/index.html'));
+
+ $page = &$this->parse($response);
+ $this->assertIdentical(
+ $page->getUrls(),
+ array('http://www.here.com/a/there.html', 'http://there.com/that.html'));
+ $this->assertIdentical(
+ $page->getUrlsByLabel('There'),
+ array(new SimpleUrl('http://www.here.com/a/there.html')));
+ $this->assertEqual(
+ $page->getUrlById('0'),
+ new SimpleUrl('http://there.com/that.html'));
+ }
+
+ function testTitle() {
+ $response = &new MockSimpleHttpResponse();
+ $response->setReturnValue('getContent', '<html><head><title>Me</title></head></html>');
+ $page = &$this->parse($response);
+ $this->assertEqual($page->getTitle(), 'Me');
+ }
+
+ function testNastyTitle() {
+ $response = &new MockSimpleHttpResponse();
+ $response->setReturnValue(
+ 'getContent',
+ '<html><head><Title> <b>Me&amp;Me </TITLE></b></head></html>');
+ $page = &$this->parse($response);
+ $this->assertEqual($page->getTitle(), "Me&Me");
+ }
+
+ function testCompleteForm() {
+ $response = &new MockSimpleHttpResponse();
+ $response->setReturnValue('getContent',
+ '<html><head><form>' .
+ '<input type="text" name="here" value="Hello">' .
+ '</form></head></html>');
+ $page = &$this->parse($response);
+ $this->assertEqual($page->getField(new SimpleByName('here')), "Hello");
+ }
+
+ function testUnclosedForm() {
+ $response = &new MockSimpleHttpResponse();
+ $response->setReturnValue('getContent',
+ '<html><head><form>' .
+ '<input type="text" name="here" value="Hello">' .
+ '</head></html>');
+ $page = &$this->parse($response);
+ $this->assertEqual($page->getField(new SimpleByName('here')), "Hello");
+ }
+
+ function testEmptyFrameset() {
+ $response = &new MockSimpleHttpResponse();
+ $response->setReturnValue(
+ 'getContent',
+ '<html><frameset></frameset></html>');
+ $page = &$this->parse($response);
+ $this->assertTrue($page->hasFrames());
+ $this->assertIdentical($page->getFrameset(), array());
+ }
+
+ function testSingleFrame() {
+ $response = &new MockSimpleHttpResponse();
+ $response->setReturnValue(
+ 'getContent',
+ '<html><frameset><frame src="a.html"></frameset></html>');
+ $response->setReturnValue('getUrl', new SimpleUrl('http://host/'));
+
+ $page = &$this->parse($response);
+ $this->assertTrue($page->hasFrames());
+ $this->assertIdentical(
+ $page->getFrameset(),
+ array(1 => new SimpleUrl('http://host/a.html')));
+ }
+
+ function testSingleFrameInNestedFrameset() {
+ $response = &new MockSimpleHttpResponse();
+ $response->setReturnValue('getContent',
+ '<html><frameset><frameset>' .
+ '<frame src="a.html">' .
+ '</frameset></frameset></html>');
+ $response->setReturnValue('getUrl', new SimpleUrl('http://host/'));
+
+ $page = &$this->parse($response);
+ $this->assertTrue($page->hasFrames());
+ $this->assertIdentical(
+ $page->getFrameset(),
+ array(1 => new SimpleUrl('http://host/a.html')));
+ }
+
+ function testFrameWithNoSource() {
+ $response = &new MockSimpleHttpResponse();
+ $response->setReturnValue(
+ 'getContent',
+ '<html><frameset><frame></frameset></html>');
+ $page = &$this->parse($response);
+ $this->assertTrue($page->hasFrames());
+ $this->assertIdentical($page->getFrameset(), array());
+ }
+
+ function testFramesCollectedWithNestedFramesetTags() {
+ $response = &new MockSimpleHttpResponse();
+ $response->setReturnValue('getContent',
+ '<html><frameset>' .
+ '<frame src="a.html">' .
+ '<frameset><frame src="b.html"></frameset>' .
+ '<frame src="c.html">' .
+ '</frameset></html>');
+ $response->setReturnValue('getUrl', new SimpleUrl('http://host/'));
+
+ $page = &$this->parse($response);
+ $this->assertTrue($page->hasFrames());
+ $this->assertIdentical($page->getFrameset(), array(
+ 1 => new SimpleUrl('http://host/a.html'),
+ 2 => new SimpleUrl('http://host/b.html'),
+ 3 => new SimpleUrl('http://host/c.html')));
+ }
+
+ function testNamedFrames() {
+ $response = &new MockSimpleHttpResponse();
+ $response->setReturnValue('getContent',
+ '<html><frameset>' .
+ '<frame src="a.html">' .
+ '<frame name="_one" src="b.html">' .
+ '<frame src="c.html">' .
+ '<frame src="d.html" name="_two">' .
+ '</frameset></html>');
+ $response->setReturnValue('getUrl', new SimpleUrl('http://host/'));
+
+ $page = &$this->parse($response);
+ $this->assertTrue($page->hasFrames());
+ $this->assertIdentical($page->getFrameset(), array(
+ 1 => new SimpleUrl('http://host/a.html'),
+ '_one' => new SimpleUrl('http://host/b.html'),
+ 3 => new SimpleUrl('http://host/c.html'),
+ '_two' => new SimpleUrl('http://host/d.html')));
+ }
+
+ function testFindFormByLabel() {
+ $response = &new MockSimpleHttpResponse();
+ $response->setReturnValue(
+ 'getContent',
+ '<html><head><form><input type="submit"></form></head></html>');
+ $page = &$this->parse($response);
+ $this->assertNull($page->getFormBySubmit(new SimpleByLabel('submit')));
+ $this->assertNull($page->getFormBySubmit(new SimpleByName('submit')));
+ $this->assertIsA(
+ $page->getFormBySubmit(new SimpleByLabel('Submit')),
+ 'SimpleForm');
+ }
+
+ function testConfirmSubmitAttributesAreCaseSensitive() {
+ $response = &new MockSimpleHttpResponse();
+ $response->setReturnValue(
+ 'getContent',
+ '<html><head><FORM><INPUT TYPE="SUBMIT" NAME="S" VALUE="S"></FORM></head></html>');
+ $page = &$this->parse($response);
+ $this->assertIsA(
+ $page->getFormBySubmit(new SimpleByName('S')),
+ 'SimpleForm');
+ $this->assertIsA(
+ $page->getFormBySubmit(new SimpleByLabel('S')),
+ 'SimpleForm');
+ }
+
+ function testFindFormByImage() {
+ $response = &new MockSimpleHttpResponse();
+ $response->setReturnValue('getContent',
+ '<html><head><form>' .
+ '<input type="image" id=100 alt="Label" name="me">' .
+ '</form></head></html>');
+ $page = &$this->parse($response);
+ $this->assertIsA(
+ $page->getFormByImage(new SimpleByLabel('Label')),
+ 'SimpleForm');
+ $this->assertIsA(
+ $page->getFormByImage(new SimpleByName('me')),
+ 'SimpleForm');
+ $this->assertIsA(
+ $page->getFormByImage(new SimpleById(100)),
+ 'SimpleForm');
+ }
+
+ function testFindFormByButtonTag() {
+ $response = &new MockSimpleHttpResponse();
+ $response->setReturnValue('getContent',
+ '<html><head><form>' .
+ '<button type="submit" name="b" value="B">BBB</button>' .
+ '</form></head></html>');
+ $page = &$this->parse($response);
+ $this->assertNull($page->getFormBySubmit(new SimpleByLabel('b')));
+ $this->assertNull($page->getFormBySubmit(new SimpleByLabel('B')));
+ $this->assertIsA(
+ $page->getFormBySubmit(new SimpleByName('b')),
+ 'SimpleForm');
+ $this->assertIsA(
+ $page->getFormBySubmit(new SimpleByLabel('BBB')),
+ 'SimpleForm');
+ }
+
+ function testFindFormById() {
+ $response = &new MockSimpleHttpResponse();
+ $response->setReturnValue(
+ 'getContent',
+ '<html><head><form id="55"><input type="submit"></form></head></html>');
+ $page = &$this->parse($response);
+ $this->assertNull($page->getFormById(54));
+ $this->assertIsA($page->getFormById(55), 'SimpleForm');
+ }
+
+ function testReadingTextField() {
+ $response = &new MockSimpleHttpResponse();
+ $response->setReturnValue('getContent',
+ '<html><head><form>' .
+ '<input type="text" name="a">' .
+ '<input type="text" name="b" value="bbb" id=3>' .
+ '</form></head></html>');
+ $page = &$this->parse($response);
+ $this->assertNull($page->getField(new SimpleByName('missing')));
+ $this->assertIdentical($page->getField(new SimpleByName('a')), '');
+ $this->assertIdentical($page->getField(new SimpleByName('b')), 'bbb');
+ }
+
+ function testReadingTextFieldIsCaseInsensitive() {
+ $response = &new MockSimpleHttpResponse();
+ $response->setReturnValue('getContent',
+ '<html><head><FORM>' .
+ '<INPUT TYPE="TEXT" NAME="a">' .
+ '<INPUT TYPE="TEXT" NAME="b" VALUE="bbb" id=3>' .
+ '</FORM></head></html>');
+ $page = &$this->parse($response);
+ $this->assertNull($page->getField(new SimpleByName('missing')));
+ $this->assertIdentical($page->getField(new SimpleByName('a')), '');
+ $this->assertIdentical($page->getField(new SimpleByName('b')), 'bbb');
+ }
+
+ function testSettingTextField() {
+ $response = &new MockSimpleHttpResponse();
+ $response->setReturnValue('getContent',
+ '<html><head><form>' .
+ '<input type="text" name="a">' .
+ '<input type="text" name="b" id=3>' .
+ '<input type="submit">' .
+ '</form></head></html>');
+ $page = &$this->parse($response);
+ $this->assertTrue($page->setField(new SimpleByName('a'), 'aaa'));
+ $this->assertEqual($page->getField(new SimpleByName('a')), 'aaa');
+ $this->assertTrue($page->setField(new SimpleById(3), 'bbb'));
+ $this->assertEqual($page->getField(new SimpleBYId(3)), 'bbb');
+ $this->assertFalse($page->setField(new SimpleByName('z'), 'zzz'));
+ $this->assertNull($page->getField(new SimpleByName('z')));
+ }
+
+ function testSettingTextFieldByEnclosingLabel() {
+ $response = &new MockSimpleHttpResponse();
+ $response->setReturnValue('getContent',
+ '<html><head><form>' .
+ '<label>Stuff' .
+ '<input type="text" name="a" value="A">' .
+ '</label>' .
+ '</form></head></html>');
+ $page = &$this->parse($response);
+ $this->assertEqual($page->getField(new SimpleByName('a')), 'A');
+ $this->assertEqual($page->getField(new SimpleByLabel('Stuff')), 'A');
+ $this->assertTrue($page->setField(new SimpleByLabel('Stuff'), 'aaa'));
+ $this->assertEqual($page->getField(new SimpleByLabel('Stuff')), 'aaa');
+ }
+
+ function testGettingTextFieldByEnclosingLabelWithConflictingOtherFields() {
+ $response = &new MockSimpleHttpResponse();
+ $response->setReturnValue('getContent',
+ '<html><head><form>' .
+ '<label>Stuff' .
+ '<input type="text" name="a" value="A">' .
+ '</label>' .
+ '<input type="text" name="b" value="B">' .
+ '</form></head></html>');
+ $page = &$this->parse($response);
+ $this->assertEqual($page->getField(new SimpleByName('a')), 'A');
+ $this->assertEqual($page->getField(new SimpleByName('b')), 'B');
+ $this->assertEqual($page->getField(new SimpleByLabel('Stuff')), 'A');
+ }
+
+ function testSettingTextFieldByExternalLabel() {
+ $response = &new MockSimpleHttpResponse();
+ $response->setReturnValue('getContent',
+ '<html><head><form>' .
+ '<label for="aaa">Stuff</label>' .
+ '<input id="aaa" type="text" name="a" value="A">' .
+ '</form></head></html>');
+ $page = &$this->parse($response);
+ $this->assertEqual($page->getField(new SimpleByLabel('Stuff')), 'A');
+ $this->assertTrue($page->setField(new SimpleByLabel('Stuff'), 'aaa'));
+ $this->assertEqual($page->getField(new SimpleByLabel('Stuff')), 'aaa');
+ }
+
+ function testReadingTextArea() {
+ $response = &new MockSimpleHttpResponse();
+ $response->setReturnValue('getContent',
+ '<html><head><form>' .
+ '<textarea name="a">aaa</textarea>' .
+ '<input type="submit">' .
+ '</form></head></html>');
+ $page = &$this->parse($response);
+ $this->assertEqual($page->getField(new SimpleByName('a')), 'aaa');
+ }
+
+ function testSettingTextArea() {
+ $response = &new MockSimpleHttpResponse();
+ $response->setReturnValue('getContent',
+ '<html><head><form>' .
+ '<textarea name="a">aaa</textarea>' .
+ '<input type="submit">' .
+ '</form></head></html>');
+ $page = &$this->parse($response);
+ $this->assertTrue($page->setField(new SimpleByName('a'), 'AAA'));
+ $this->assertEqual($page->getField(new SimpleByName('a')), 'AAA');
+ }
+
+ function testSettingSelectionField() {
+ $response = &new MockSimpleHttpResponse();
+ $response->setReturnValue('getContent',
+ '<html><head><form>' .
+ '<select name="a">' .
+ '<option>aaa</option>' .
+ '<option selected>bbb</option>' .
+ '</select>' .
+ '<input type="submit">' .
+ '</form></head></html>');
+ $page = &$this->parse($response);
+ $this->assertEqual($page->getField(new SimpleByName('a')), 'bbb');
+ $this->assertFalse($page->setField(new SimpleByName('a'), 'ccc'));
+ $this->assertTrue($page->setField(new SimpleByName('a'), 'aaa'));
+ $this->assertEqual($page->getField(new SimpleByName('a')), 'aaa');
+ }
+
+ function testSettingSelectionFieldByEnclosingLabel() {
+ $response = &new MockSimpleHttpResponse();
+ $response->setReturnValue('getContent',
+ '<html><head><form>' .
+ '<label>Stuff' .
+ '<select name="a"><option selected>A</option><option>B</option></select>' .
+ '</label>' .
+ '</form></head></html>');
+ $page = &$this->parse($response);
+ $this->assertEqual($page->getField(new SimpleByLabel('Stuff')), 'A');
+ $this->assertTrue($page->setField(new SimpleByLabel('Stuff'), 'B'));
+ $this->assertEqual($page->getField(new SimpleByLabel('Stuff')), 'B');
+ }
+
+ function testSettingRadioButtonByEnclosingLabel() {
+ $response = &new MockSimpleHttpResponse();
+ $response->setReturnValue('getContent',
+ '<html><head><form>' .
+ '<label>A<input type="radio" name="r" value="a" checked></label>' .
+ '<label>B<input type="radio" name="r" value="b"></label>' .
+ '</form></head></html>');
+ $page = &$this->parse($response);
+ $this->assertEqual($page->getField(new SimpleByLabel('A')), 'a');
+ $this->assertTrue($page->setField(new SimpleBylabel('B'), 'b'));
+ $this->assertEqual($page->getField(new SimpleByLabel('B')), 'b');
+ }
+}
+?> \ No newline at end of file
diff --git a/site/vendors/simpletest/test/parse_error_test.php b/site/vendors/simpletest/test/parse_error_test.php
new file mode 100644
index 0000000..c3ffb3d
--- /dev/null
+++ b/site/vendors/simpletest/test/parse_error_test.php
@@ -0,0 +1,9 @@
+<?php
+// $Id: parse_error_test.php 1509 2007-05-08 22:11:49Z lastcraft $
+require_once('../unit_tester.php');
+require_once('../reporter.php');
+
+$test = &new TestSuite('This should fail');
+$test->addFile('test_with_parse_error.php');
+$test->run(new HtmlReporter());
+?> \ No newline at end of file
diff --git a/site/vendors/simpletest/test/parser_test.php b/site/vendors/simpletest/test/parser_test.php
new file mode 100644
index 0000000..83268d9
--- /dev/null
+++ b/site/vendors/simpletest/test/parser_test.php
@@ -0,0 +1,551 @@
+<?php
+// $Id: parser_test.php 1608 2007-12-27 09:03:07Z pp11 $
+require_once(dirname(__FILE__) . '/../autorun.php');
+require_once(dirname(__FILE__) . '/../parser.php');
+Mock::generate('SimpleHtmlSaxParser');
+Mock::generate('SimpleSaxListener');
+
+class TestOfParallelRegex extends UnitTestCase {
+
+ function testNoPatterns() {
+ $regex = &new ParallelRegex(false);
+ $this->assertFalse($regex->match("Hello", $match));
+ $this->assertEqual($match, "");
+ }
+
+ function testNoSubject() {
+ $regex = &new ParallelRegex(false);
+ $regex->addPattern(".*");
+ $this->assertTrue($regex->match("", $match));
+ $this->assertEqual($match, "");
+ }
+
+ function testMatchAll() {
+ $regex = &new ParallelRegex(false);
+ $regex->addPattern(".*");
+ $this->assertTrue($regex->match("Hello", $match));
+ $this->assertEqual($match, "Hello");
+ }
+
+ function testCaseSensitive() {
+ $regex = &new ParallelRegex(true);
+ $regex->addPattern("abc");
+ $this->assertTrue($regex->match("abcdef", $match));
+ $this->assertEqual($match, "abc");
+ $this->assertTrue($regex->match("AAABCabcdef", $match));
+ $this->assertEqual($match, "abc");
+ }
+
+ function testCaseInsensitive() {
+ $regex = &new ParallelRegex(false);
+ $regex->addPattern("abc");
+ $this->assertTrue($regex->match("abcdef", $match));
+ $this->assertEqual($match, "abc");
+ $this->assertTrue($regex->match("AAABCabcdef", $match));
+ $this->assertEqual($match, "ABC");
+ }
+
+ function testMatchMultiple() {
+ $regex = &new ParallelRegex(true);
+ $regex->addPattern("abc");
+ $regex->addPattern("ABC");
+ $this->assertTrue($regex->match("abcdef", $match));
+ $this->assertEqual($match, "abc");
+ $this->assertTrue($regex->match("AAABCabcdef", $match));
+ $this->assertEqual($match, "ABC");
+ $this->assertFalse($regex->match("Hello", $match));
+ }
+
+ function testPatternLabels() {
+ $regex = &new ParallelRegex(false);
+ $regex->addPattern("abc", "letter");
+ $regex->addPattern("123", "number");
+ $this->assertIdentical($regex->match("abcdef", $match), "letter");
+ $this->assertEqual($match, "abc");
+ $this->assertIdentical($regex->match("0123456789", $match), "number");
+ $this->assertEqual($match, "123");
+ }
+}
+
+class TestOfStateStack extends UnitTestCase {
+
+ function testStartState() {
+ $stack = &new SimpleStateStack("one");
+ $this->assertEqual($stack->getCurrent(), "one");
+ }
+
+ function testExhaustion() {
+ $stack = &new SimpleStateStack("one");
+ $this->assertFalse($stack->leave());
+ }
+
+ function testStateMoves() {
+ $stack = &new SimpleStateStack("one");
+ $stack->enter("two");
+ $this->assertEqual($stack->getCurrent(), "two");
+ $stack->enter("three");
+ $this->assertEqual($stack->getCurrent(), "three");
+ $this->assertTrue($stack->leave());
+ $this->assertEqual($stack->getCurrent(), "two");
+ $stack->enter("third");
+ $this->assertEqual($stack->getCurrent(), "third");
+ $this->assertTrue($stack->leave());
+ $this->assertTrue($stack->leave());
+ $this->assertEqual($stack->getCurrent(), "one");
+ }
+}
+
+class TestParser {
+
+ function accept() {
+ }
+
+ function a() {
+ }
+
+ function b() {
+ }
+}
+Mock::generate('TestParser');
+
+class TestOfLexer extends UnitTestCase {
+
+ function testEmptyPage() {
+ $handler = &new MockTestParser();
+ $handler->expectNever("accept");
+ $handler->setReturnValue("accept", true);
+ $handler->expectNever("accept");
+ $handler->setReturnValue("accept", true);
+ $lexer = &new SimpleLexer($handler);
+ $lexer->addPattern("a+");
+ $this->assertTrue($lexer->parse(""));
+ }
+
+ function testSinglePattern() {
+ $handler = &new MockTestParser();
+ $handler->expectArgumentsAt(0, "accept", array("aaa", LEXER_MATCHED));
+ $handler->expectArgumentsAt(1, "accept", array("x", LEXER_UNMATCHED));
+ $handler->expectArgumentsAt(2, "accept", array("a", LEXER_MATCHED));
+ $handler->expectArgumentsAt(3, "accept", array("yyy", LEXER_UNMATCHED));
+ $handler->expectArgumentsAt(4, "accept", array("a", LEXER_MATCHED));
+ $handler->expectArgumentsAt(5, "accept", array("x", LEXER_UNMATCHED));
+ $handler->expectArgumentsAt(6, "accept", array("aaa", LEXER_MATCHED));
+ $handler->expectArgumentsAt(7, "accept", array("z", LEXER_UNMATCHED));
+ $handler->expectCallCount("accept", 8);
+ $handler->setReturnValue("accept", true);
+ $lexer = &new SimpleLexer($handler);
+ $lexer->addPattern("a+");
+ $this->assertTrue($lexer->parse("aaaxayyyaxaaaz"));
+ }
+
+ function testMultiplePattern() {
+ $handler = &new MockTestParser();
+ $target = array("a", "b", "a", "bb", "x", "b", "a", "xxxxxx", "a", "x");
+ for ($i = 0; $i < count($target); $i++) {
+ $handler->expectArgumentsAt($i, "accept", array($target[$i], '*'));
+ }
+ $handler->expectCallCount("accept", count($target));
+ $handler->setReturnValue("accept", true);
+ $lexer = &new SimpleLexer($handler);
+ $lexer->addPattern("a+");
+ $lexer->addPattern("b+");
+ $this->assertTrue($lexer->parse("ababbxbaxxxxxxax"));
+ }
+}
+
+class TestOfLexerModes extends UnitTestCase {
+
+ function testIsolatedPattern() {
+ $handler = &new MockTestParser();
+ $handler->expectArgumentsAt(0, "a", array("a", LEXER_MATCHED));
+ $handler->expectArgumentsAt(1, "a", array("b", LEXER_UNMATCHED));
+ $handler->expectArgumentsAt(2, "a", array("aa", LEXER_MATCHED));
+ $handler->expectArgumentsAt(3, "a", array("bxb", LEXER_UNMATCHED));
+ $handler->expectArgumentsAt(4, "a", array("aaa", LEXER_MATCHED));
+ $handler->expectArgumentsAt(5, "a", array("x", LEXER_UNMATCHED));
+ $handler->expectArgumentsAt(6, "a", array("aaaa", LEXER_MATCHED));
+ $handler->expectArgumentsAt(7, "a", array("x", LEXER_UNMATCHED));
+ $handler->expectCallCount("a", 8);
+ $handler->setReturnValue("a", true);
+ $lexer = &new SimpleLexer($handler, "a");
+ $lexer->addPattern("a+", "a");
+ $lexer->addPattern("b+", "b");
+ $this->assertTrue($lexer->parse("abaabxbaaaxaaaax"));
+ }
+
+ function testModeChange() {
+ $handler = &new MockTestParser();
+ $handler->expectArgumentsAt(0, "a", array("a", LEXER_MATCHED));
+ $handler->expectArgumentsAt(1, "a", array("b", LEXER_UNMATCHED));
+ $handler->expectArgumentsAt(2, "a", array("aa", LEXER_MATCHED));
+ $handler->expectArgumentsAt(3, "a", array("b", LEXER_UNMATCHED));
+ $handler->expectArgumentsAt(4, "a", array("aaa", LEXER_MATCHED));
+ $handler->expectArgumentsAt(0, "b", array(":", LEXER_ENTER));
+ $handler->expectArgumentsAt(1, "b", array("a", LEXER_UNMATCHED));
+ $handler->expectArgumentsAt(2, "b", array("b", LEXER_MATCHED));
+ $handler->expectArgumentsAt(3, "b", array("a", LEXER_UNMATCHED));
+ $handler->expectArgumentsAt(4, "b", array("bb", LEXER_MATCHED));
+ $handler->expectArgumentsAt(5, "b", array("a", LEXER_UNMATCHED));
+ $handler->expectArgumentsAt(6, "b", array("bbb", LEXER_MATCHED));
+ $handler->expectArgumentsAt(7, "b", array("a", LEXER_UNMATCHED));
+ $handler->expectCallCount("a", 5);
+ $handler->expectCallCount("b", 8);
+ $handler->setReturnValue("a", true);
+ $handler->setReturnValue("b", true);
+ $lexer = &new SimpleLexer($handler, "a");
+ $lexer->addPattern("a+", "a");
+ $lexer->addEntryPattern(":", "a", "b");
+ $lexer->addPattern("b+", "b");
+ $this->assertTrue($lexer->parse("abaabaaa:ababbabbba"));
+ }
+
+ function testNesting() {
+ $handler = &new MockTestParser();
+ $handler->setReturnValue("a", true);
+ $handler->setReturnValue("b", true);
+ $handler->expectArgumentsAt(0, "a", array("aa", LEXER_MATCHED));
+ $handler->expectArgumentsAt(1, "a", array("b", LEXER_UNMATCHED));
+ $handler->expectArgumentsAt(2, "a", array("aa", LEXER_MATCHED));
+ $handler->expectArgumentsAt(3, "a", array("b", LEXER_UNMATCHED));
+ $handler->expectArgumentsAt(0, "b", array("(", LEXER_ENTER));
+ $handler->expectArgumentsAt(1, "b", array("bb", LEXER_MATCHED));
+ $handler->expectArgumentsAt(2, "b", array("a", LEXER_UNMATCHED));
+ $handler->expectArgumentsAt(3, "b", array("bb", LEXER_MATCHED));
+ $handler->expectArgumentsAt(4, "b", array(")", LEXER_EXIT));
+ $handler->expectArgumentsAt(4, "a", array("aa", LEXER_MATCHED));
+ $handler->expectArgumentsAt(5, "a", array("b", LEXER_UNMATCHED));
+ $handler->expectCallCount("a", 6);
+ $handler->expectCallCount("b", 5);
+ $lexer = &new SimpleLexer($handler, "a");
+ $lexer->addPattern("a+", "a");
+ $lexer->addEntryPattern("(", "a", "b");
+ $lexer->addPattern("b+", "b");
+ $lexer->addExitPattern(")", "b");
+ $this->assertTrue($lexer->parse("aabaab(bbabb)aab"));
+ }
+
+ function testSingular() {
+ $handler = &new MockTestParser();
+ $handler->setReturnValue("a", true);
+ $handler->setReturnValue("b", true);
+ $handler->expectArgumentsAt(0, "a", array("aa", LEXER_MATCHED));
+ $handler->expectArgumentsAt(1, "a", array("aa", LEXER_MATCHED));
+ $handler->expectArgumentsAt(2, "a", array("xx", LEXER_UNMATCHED));
+ $handler->expectArgumentsAt(3, "a", array("xx", LEXER_UNMATCHED));
+ $handler->expectArgumentsAt(0, "b", array("b", LEXER_SPECIAL));
+ $handler->expectArgumentsAt(1, "b", array("bbb", LEXER_SPECIAL));
+ $handler->expectCallCount("a", 4);
+ $handler->expectCallCount("b", 2);
+ $lexer = &new SimpleLexer($handler, "a");
+ $lexer->addPattern("a+", "a");
+ $lexer->addSpecialPattern("b+", "a", "b");
+ $this->assertTrue($lexer->parse("aabaaxxbbbxx"));
+ }
+
+ function testUnwindTooFar() {
+ $handler = &new MockTestParser();
+ $handler->setReturnValue("a", true);
+ $handler->expectArgumentsAt(0, "a", array("aa", LEXER_MATCHED));
+ $handler->expectArgumentsAt(1, "a", array(")", LEXER_EXIT));
+ $handler->expectCallCount("a", 2);
+ $lexer = &new SimpleLexer($handler, "a");
+ $lexer->addPattern("a+", "a");
+ $lexer->addExitPattern(")", "a");
+ $this->assertFalse($lexer->parse("aa)aa"));
+ }
+}
+
+class TestOfLexerHandlers extends UnitTestCase {
+
+ function testModeMapping() {
+ $handler = &new MockTestParser();
+ $handler->setReturnValue("a", true);
+ $handler->expectArgumentsAt(0, "a", array("aa", LEXER_MATCHED));
+ $handler->expectArgumentsAt(1, "a", array("(", LEXER_ENTER));
+ $handler->expectArgumentsAt(2, "a", array("bb", LEXER_MATCHED));
+ $handler->expectArgumentsAt(3, "a", array("a", LEXER_UNMATCHED));
+ $handler->expectArgumentsAt(4, "a", array("bb", LEXER_MATCHED));
+ $handler->expectArgumentsAt(5, "a", array(")", LEXER_EXIT));
+ $handler->expectArgumentsAt(6, "a", array("b", LEXER_UNMATCHED));
+ $handler->expectCallCount("a", 7);
+ $lexer = &new SimpleLexer($handler, "mode_a");
+ $lexer->addPattern("a+", "mode_a");
+ $lexer->addEntryPattern("(", "mode_a", "mode_b");
+ $lexer->addPattern("b+", "mode_b");
+ $lexer->addExitPattern(")", "mode_b");
+ $lexer->mapHandler("mode_a", "a");
+ $lexer->mapHandler("mode_b", "a");
+ $this->assertTrue($lexer->parse("aa(bbabb)b"));
+ }
+}
+
+class TestOfSimpleHtmlLexer extends UnitTestCase {
+
+ function &createParser() {
+ $parser = &new MockSimpleHtmlSaxParser();
+ $parser->setReturnValue('acceptStartToken', true);
+ $parser->setReturnValue('acceptEndToken', true);
+ $parser->setReturnValue('acceptAttributeToken', true);
+ $parser->setReturnValue('acceptEntityToken', true);
+ $parser->setReturnValue('acceptTextToken', true);
+ $parser->setReturnValue('ignore', true);
+ return $parser;
+ }
+
+ function testNoContent() {
+ $parser = &$this->createParser();
+ $parser->expectNever('acceptStartToken');
+ $parser->expectNever('acceptEndToken');
+ $parser->expectNever('acceptAttributeToken');
+ $parser->expectNever('acceptEntityToken');
+ $parser->expectNever('acceptTextToken');
+ $lexer = &new SimpleHtmlLexer($parser);
+ $this->assertTrue($lexer->parse(''));
+ }
+
+ function testUninteresting() {
+ $parser = &$this->createParser();
+ $parser->expectOnce('acceptTextToken', array('<html></html>', '*'));
+ $lexer = &new SimpleHtmlLexer($parser);
+ $this->assertTrue($lexer->parse('<html></html>'));
+ }
+
+ function testSkipCss() {
+ $parser = &$this->createParser();
+ $parser->expectNever('acceptTextToken');
+ $parser->expectAtLeastOnce('ignore');
+ $lexer = &new SimpleHtmlLexer($parser);
+ $this->assertTrue($lexer->parse("<style>Lot's of styles</style>"));
+ }
+
+ function testSkipJavaScript() {
+ $parser = &$this->createParser();
+ $parser->expectNever('acceptTextToken');
+ $parser->expectAtLeastOnce('ignore');
+ $lexer = &new SimpleHtmlLexer($parser);
+ $this->assertTrue($lexer->parse("<SCRIPT>Javascript code {';:^%^%£$'@\"*(}</SCRIPT>"));
+ }
+
+ function testSkipHtmlComments() {
+ $parser = &$this->createParser();
+ $parser->expectNever('acceptTextToken');
+ $parser->expectAtLeastOnce('ignore');
+ $lexer = &new SimpleHtmlLexer($parser);
+ $this->assertTrue($lexer->parse("<!-- <title>title</title><style>styles</style> -->"));
+ }
+
+ function testTagWithNoAttributes() {
+ $parser = &$this->createParser();
+ $parser->expectAt(0, 'acceptStartToken', array('<title', '*'));
+ $parser->expectAt(1, 'acceptStartToken', array('>', '*'));
+ $parser->expectCallCount('acceptStartToken', 2);
+ $parser->expectOnce('acceptTextToken', array('Hello', '*'));
+ $parser->expectOnce('acceptEndToken', array('</title>', '*'));
+ $lexer = &new SimpleHtmlLexer($parser);
+ $this->assertTrue($lexer->parse('<title>Hello</title>'));
+ }
+
+ function testTagWithAttributes() {
+ $parser = &$this->createParser();
+ $parser->expectOnce('acceptTextToken', array('label', '*'));
+ $parser->expectAt(0, 'acceptStartToken', array('<a', '*'));
+ $parser->expectAt(1, 'acceptStartToken', array('href', '*'));
+ $parser->expectAt(2, 'acceptStartToken', array('>', '*'));
+ $parser->expectCallCount('acceptStartToken', 3);
+ $parser->expectAt(0, 'acceptAttributeToken', array('= "', '*'));
+ $parser->expectAt(1, 'acceptAttributeToken', array('here.html', '*'));
+ $parser->expectAt(2, 'acceptAttributeToken', array('"', '*'));
+ $parser->expectCallCount('acceptAttributeToken', 3);
+ $parser->expectOnce('acceptEndToken', array('</a>', '*'));
+ $lexer = &new SimpleHtmlLexer($parser);
+ $this->assertTrue($lexer->parse('<a href = "here.html">label</a>'));
+ }
+}
+
+class TestOfHtmlSaxParser extends UnitTestCase {
+
+ function &createListener() {
+ $listener = &new MockSimpleSaxListener();
+ $listener->setReturnValue('startElement', true);
+ $listener->setReturnValue('addContent', true);
+ $listener->setReturnValue('endElement', true);
+ return $listener;
+ }
+
+ function testFramesetTag() {
+ $listener = &$this->createListener();
+ $listener->expectOnce('startElement', array('frameset', array()));
+ $listener->expectOnce('addContent', array('Frames'));
+ $listener->expectOnce('endElement', array('frameset'));
+ $parser = &new SimpleHtmlSaxParser($listener);
+ $this->assertTrue($parser->parse('<frameset>Frames</frameset>'));
+ }
+
+ function testTagWithUnquotedAttributes() {
+ $listener = &$this->createListener();
+ $listener->expectOnce(
+ 'startElement',
+ array('input', array('name' => 'a.b.c', 'value' => 'd')));
+ $parser = &new SimpleHtmlSaxParser($listener);
+ $this->assertTrue($parser->parse('<input name=a.b.c value = d>'));
+ }
+
+ function testTagInsideContent() {
+ $listener = &$this->createListener();
+ $listener->expectOnce('startElement', array('a', array()));
+ $listener->expectAt(0, 'addContent', array('<html>'));
+ $listener->expectAt(1, 'addContent', array('</html>'));
+ $parser = &new SimpleHtmlSaxParser($listener);
+ $this->assertTrue($parser->parse('<html><a></a></html>'));
+ }
+
+ function testTagWithInternalContent() {
+ $listener = &$this->createListener();
+ $listener->expectOnce('startElement', array('a', array()));
+ $listener->expectOnce('addContent', array('label'));
+ $listener->expectOnce('endElement', array('a'));
+ $parser = &new SimpleHtmlSaxParser($listener);
+ $this->assertTrue($parser->parse('<a>label</a>'));
+ }
+
+ function testLinkAddress() {
+ $listener = &$this->createListener();
+ $listener->expectOnce('startElement', array('a', array('href' => 'here.html')));
+ $listener->expectOnce('addContent', array('label'));
+ $listener->expectOnce('endElement', array('a'));
+ $parser = &new SimpleHtmlSaxParser($listener);
+ $this->assertTrue($parser->parse("<a href = 'here.html'>label</a>"));
+ }
+
+ function testEncodedAttribute() {
+ $listener = &$this->createListener();
+ $listener->expectOnce('startElement', array('a', array('href' => 'here&there.html')));
+ $listener->expectOnce('addContent', array('label'));
+ $listener->expectOnce('endElement', array('a'));
+ $parser = &new SimpleHtmlSaxParser($listener);
+ $this->assertTrue($parser->parse("<a href = 'here&amp;there.html'>label</a>"));
+ }
+
+ function testTagWithId() {
+ $listener = &$this->createListener();
+ $listener->expectOnce('startElement', array('a', array('id' => '0')));
+ $listener->expectOnce('addContent', array('label'));
+ $listener->expectOnce('endElement', array('a'));
+ $parser = &new SimpleHtmlSaxParser($listener);
+ $this->assertTrue($parser->parse('<a id="0">label</a>'));
+ }
+
+ function testTagWithEmptyAttributes() {
+ $listener = &$this->createListener();
+ $listener->expectOnce(
+ 'startElement',
+ array('option', array('value' => '', 'selected' => '')));
+ $listener->expectOnce('addContent', array('label'));
+ $listener->expectOnce('endElement', array('option'));
+ $parser = &new SimpleHtmlSaxParser($listener);
+ $this->assertTrue($parser->parse('<option value="" selected>label</option>'));
+ }
+
+ function testComplexTagWithLotsOfCaseVariations() {
+ $listener = &$this->createListener();
+ $listener->expectOnce(
+ 'startElement',
+ array('a', array('href' => 'here.html', 'style' => "'cool'")));
+ $listener->expectOnce('addContent', array('label'));
+ $listener->expectOnce('endElement', array('a'));
+ $parser = &new SimpleHtmlSaxParser($listener);
+ $this->assertTrue($parser->parse('<A HREF = \'here.html\' Style="\'cool\'">label</A>'));
+ }
+
+ function testXhtmlSelfClosingTag() {
+ $listener = &$this->createListener();
+ $listener->expectOnce(
+ 'startElement',
+ array('input', array('type' => 'submit', 'name' => 'N', 'value' => 'V')));
+ $parser = &new SimpleHtmlSaxParser($listener);
+ $this->assertTrue($parser->parse('<input type="submit" name="N" value="V" />'));
+ }
+
+ function testNestedFrameInFrameset() {
+ $listener = &$this->createListener();
+ $listener->expectAt(0, 'startElement', array('frameset', array()));
+ $listener->expectAt(1, 'startElement', array('frame', array('src' => 'frame.html')));
+ $listener->expectCallCount('startElement', 2);
+ $listener->expectOnce('addContent', array('<noframes>Hello</noframes>'));
+ $listener->expectOnce('endElement', array('frameset'));
+ $parser = &new SimpleHtmlSaxParser($listener);
+ $this->assertTrue($parser->parse(
+ '<frameset><frame src="frame.html"><noframes>Hello</noframes></frameset>'));
+ }
+}
+
+class TestOfTextExtraction extends UnitTestCase {
+
+ function testImageSuppressionWhileKeepingParagraphsAndAltText() {
+ $this->assertEqual(
+ SimpleHtmlSaxParser::normalise('<img src="foo.png" /><p>some text</p><img src="bar.png" alt="bar" />'),
+ 'some text bar');
+
+ }
+
+ function testSpaceNormalisation() {
+ $this->assertEqual(
+ SimpleHtmlSaxParser::normalise("\nOne\tTwo \nThree\t"),
+ 'One Two Three');
+ }
+
+ function testMultilinesCommentSuppression() {
+ $this->assertEqual(
+ SimpleHtmlSaxParser::normalise('<!--\n Hello \n-->'),
+ '');
+ }
+
+ function testCommentSuppression() {
+ $this->assertEqual(
+ SimpleHtmlSaxParser::normalise('<!--Hello-->'),
+ '');
+ }
+
+ function testJavascriptSuppression() {
+ $this->assertEqual(
+ SimpleHtmlSaxParser::normalise('<script attribute="test">\nHello\n</script>'),
+ '');
+ $this->assertEqual(
+ SimpleHtmlSaxParser::normalise('<script attribute="test">Hello</script>'),
+ '');
+ $this->assertEqual(
+ SimpleHtmlSaxParser::normalise('<script>Hello</script>'),
+ '');
+ }
+
+ function testTagSuppression() {
+ $this->assertEqual(
+ SimpleHtmlSaxParser::normalise('<b>Hello</b>'),
+ 'Hello');
+ }
+
+ function testAdjoiningTagSuppression() {
+ $this->assertEqual(
+ SimpleHtmlSaxParser::normalise('<b>Hello</b><em>Goodbye</em>'),
+ 'HelloGoodbye');
+ }
+
+ function testExtractImageAltTextWithDifferentQuotes() {
+ $this->assertEqual(
+ SimpleHtmlSaxParser::normalise('<img alt="One"><img alt=\'Two\'><img alt=Three>'),
+ 'One Two Three');
+ }
+
+ function testExtractImageAltTextMultipleTimes() {
+ $this->assertEqual(
+ SimpleHtmlSaxParser::normalise('<img alt="One"><img alt="Two"><img alt="Three">'),
+ 'One Two Three');
+ }
+
+ function testHtmlEntityTranslation() {
+ $this->assertEqual(
+ SimpleHtmlSaxParser::normalise('&lt;&gt;&quot;&amp;&#039;'),
+ '<>"&\'');
+ }
+}
+?> \ No newline at end of file
diff --git a/site/vendors/simpletest/test/reflection_php4_test.php b/site/vendors/simpletest/test/reflection_php4_test.php
new file mode 100644
index 0000000..8ee211b
--- /dev/null
+++ b/site/vendors/simpletest/test/reflection_php4_test.php
@@ -0,0 +1,61 @@
+<?php
+// $Id: reflection_php4_test.php 1505 2007-04-30 23:39:59Z lastcraft $
+require_once(dirname(__FILE__) . '/../autorun.php');
+
+class AnyOldThing {
+ function aMethod() {
+ }
+}
+
+class AnyOldChildThing extends AnyOldThing { }
+
+class TestOfReflection extends UnitTestCase {
+
+ function testClassExistence() {
+ $reflection = new SimpleReflection('AnyOldThing');
+ $this->assertTrue($reflection->classOrInterfaceExists());
+ $this->assertTrue($reflection->classOrInterfaceExistsSansAutoload());
+ }
+
+ function testClassNonExistence() {
+ $reflection = new SimpleReflection('UnknownThing');
+ $this->assertFalse($reflection->classOrInterfaceExists());
+ $this->assertFalse($reflection->classOrInterfaceExistsSansAutoload());
+ }
+
+ function testDetectionOfInterfacesAlwaysFalse() {
+ $reflection = new SimpleReflection('AnyOldThing');
+ $this->assertFalse($reflection->isAbstract());
+ $this->assertFalse($reflection->isInterface());
+ }
+
+ function testFindingParentClass() {
+ $reflection = new SimpleReflection('AnyOldChildThing');
+ $this->assertEqual(strtolower($reflection->getParent()), 'anyoldthing');
+ }
+
+ function testMethodsListFromClass() {
+ $reflection = new SimpleReflection('AnyOldThing');
+ $methods = $reflection->getMethods();
+ $this->assertEqualIgnoringCase($methods[0], 'aMethod');
+ }
+
+ function testNoInterfacesForPHP4() {
+ $reflection = new SimpleReflection('AnyOldThing');
+ $this->assertEqual(
+ $reflection->getInterfaces(),
+ array());
+ }
+
+ function testMostGeneralPossibleSignature() {
+ $reflection = new SimpleReflection('AnyOldThing');
+ $this->assertEqualIgnoringCase(
+ $reflection->getSignature('aMethod'),
+ 'function &aMethod()');
+ }
+
+ function assertEqualIgnoringCase($a, $b) {
+ return $this->assertEqual(strtolower($a), strtolower($b));
+ }
+}
+?> \ No newline at end of file
diff --git a/site/vendors/simpletest/test/reflection_php5_test.php b/site/vendors/simpletest/test/reflection_php5_test.php
new file mode 100644
index 0000000..3bfc6e8
--- /dev/null
+++ b/site/vendors/simpletest/test/reflection_php5_test.php
@@ -0,0 +1,271 @@
+<?php
+// $Id: reflection_php5_test.php 1541 2007-06-10 02:27:59Z tswicegood $
+require_once(dirname(__FILE__) . '/../autorun.php');
+require_once(dirname(__FILE__) . '/../reflection_php5.php');
+
+class AnyOldLeafClass {
+ function aMethod() { }
+}
+
+abstract class AnyOldClass {
+ function aMethod() { }
+}
+
+class AnyOldLeafClassWithAFinal {
+ final function aMethod() { }
+}
+
+interface AnyOldInterface {
+ function aMethod();
+}
+
+interface AnyOldArgumentInterface {
+ function aMethod(AnyOldInterface $argument);
+}
+
+interface AnyDescendentInterface extends AnyOldInterface {
+}
+
+class AnyOldImplementation implements AnyOldInterface {
+ function aMethod() { }
+ function extraMethod() { }
+}
+
+abstract class AnyAbstractImplementation implements AnyOldInterface {
+}
+
+abstract class AnotherOldAbstractClass {
+ protected abstract function aMethod(AnyOldInterface $argument);
+}
+
+class AnyOldSubclass extends AnyOldImplementation { }
+
+class AnyOldArgumentClass {
+ function aMethod($argument) { }
+}
+
+class AnyOldArgumentImplementation implements AnyOldArgumentInterface {
+ function aMethod(AnyOldInterface $argument) { }
+}
+
+class AnyOldTypeHintedClass implements AnyOldArgumentInterface {
+ function aMethod(AnyOldInterface $argument) { }
+}
+
+class AnyDescendentImplementation implements AnyDescendentInterface {
+ function aMethod() { }
+}
+
+class AnyOldOverloadedClass {
+ function __isset($key) { }
+ function __unset($key) { }
+}
+
+class AnyOldClassWithStaticMethods {
+ static function aStatic() { }
+ static function aStaticWithParameters($arg1, $arg2) { }
+}
+
+abstract class AnyOldAbstractClassWithAbstractMethods {
+ abstract function anAbstract();
+ abstract function anAbstractWithParameter($foo);
+ abstract function anAbstractWithMultipleParameters($foo, $bar);
+}
+
+class TestOfReflection extends UnitTestCase {
+
+ function testClassExistence() {
+ $reflection = new SimpleReflection('AnyOldLeafClass');
+ $this->assertTrue($reflection->classOrInterfaceExists());
+ $this->assertTrue($reflection->classOrInterfaceExistsSansAutoload());
+ $this->assertFalse($reflection->isAbstract());
+ $this->assertFalse($reflection->isInterface());
+ }
+
+ function testClassNonExistence() {
+ $reflection = new SimpleReflection('UnknownThing');
+ $this->assertFalse($reflection->classOrInterfaceExists());
+ $this->assertFalse($reflection->classOrInterfaceExistsSansAutoload());
+ }
+
+ function testDetectionOfAbstractClass() {
+ $reflection = new SimpleReflection('AnyOldClass');
+ $this->assertTrue($reflection->isAbstract());
+ }
+
+ function testDetectionOfFinalMethods() {
+ $reflection = new SimpleReflection('AnyOldClass');
+ $this->assertFalse($reflection->hasFinal());
+ $reflection = new SimpleReflection('AnyOldLeafClassWithAFinal');
+ $this->assertTrue($reflection->hasFinal());
+ }
+
+ function testFindingParentClass() {
+ $reflection = new SimpleReflection('AnyOldSubclass');
+ $this->assertEqual($reflection->getParent(), 'AnyOldImplementation');
+ }
+
+ function testInterfaceExistence() {
+ $reflection = new SimpleReflection('AnyOldInterface');
+ $this->assertTrue($reflection->classOrInterfaceExists());
+ $this->assertTrue($reflection->classOrInterfaceExistsSansAutoload());
+ $this->assertTrue($reflection->isInterface());
+ }
+
+ function testMethodsListFromClass() {
+ $reflection = new SimpleReflection('AnyOldClass');
+ $this->assertIdentical($reflection->getMethods(), array('aMethod'));
+ }
+
+ function testMethodsListFromInterface() {
+ $reflection = new SimpleReflection('AnyOldInterface');
+ $this->assertIdentical($reflection->getMethods(), array('aMethod'));
+ $this->assertIdentical($reflection->getInterfaceMethods(), array('aMethod'));
+ }
+
+ function testMethodsComeFromDescendentInterfacesASWell() {
+ $reflection = new SimpleReflection('AnyDescendentInterface');
+ $this->assertIdentical($reflection->getMethods(), array('aMethod'));
+ }
+
+ function testCanSeparateInterfaceMethodsFromOthers() {
+ $reflection = new SimpleReflection('AnyOldImplementation');
+ $this->assertIdentical($reflection->getMethods(), array('aMethod', 'extraMethod'));
+ $this->assertIdentical($reflection->getInterfaceMethods(), array('aMethod'));
+ }
+
+ function testMethodsComeFromDescendentInterfacesInAbstractClass() {
+ $reflection = new SimpleReflection('AnyAbstractImplementation');
+ $this->assertIdentical($reflection->getMethods(), array('aMethod'));
+ }
+
+ function testInterfaceHasOnlyItselfToImplement() {
+ $reflection = new SimpleReflection('AnyOldInterface');
+ $this->assertEqual(
+ $reflection->getInterfaces(),
+ array('AnyOldInterface'));
+ }
+
+ function testInterfacesListedForClass() {
+ $reflection = new SimpleReflection('AnyOldImplementation');
+ $this->assertEqual(
+ $reflection->getInterfaces(),
+ array('AnyOldInterface'));
+ }
+
+ function testInterfacesListedForSubclass() {
+ $reflection = new SimpleReflection('AnyOldSubclass');
+ $this->assertEqual(
+ $reflection->getInterfaces(),
+ array('AnyOldInterface'));
+ }
+
+ function testNoParameterCreationWhenNoInterface() {
+ $reflection = new SimpleReflection('AnyOldArgumentClass');
+ $function = $reflection->getSignature('aMethod');
+ if (version_compare(phpversion(), '5.0.2', '<=')) {
+ $this->assertEqual('function amethod()', strtolower($function));
+ } else {
+ $this->assertEqual('function aMethod()', $function);
+ }
+ }
+
+ function testParameterCreationWithoutTypeHinting() {
+ $reflection = new SimpleReflection('AnyOldArgumentImplementation');
+ $function = $reflection->getSignature('aMethod');
+ if (version_compare(phpversion(), '5.0.2', '<=')) {
+ $this->assertEqual('function amethod(AnyOldInterface $argument)', $function);
+ } else {
+ $this->assertEqual('function aMethod(AnyOldInterface $argument)', $function);
+ }
+ }
+
+ function testParameterCreationForTypeHinting() {
+ $reflection = new SimpleReflection('AnyOldTypeHintedClass');
+ $function = $reflection->getSignature('aMethod');
+ if (version_compare(phpversion(), '5.0.2', '<=')) {
+ $this->assertEqual('function amethod(AnyOldInterface $argument)', $function);
+ } else {
+ $this->assertEqual('function aMethod(AnyOldInterface $argument)', $function);
+ }
+ }
+
+ function testIssetFunctionSignature() {
+ $reflection = new SimpleReflection('AnyOldOverloadedClass');
+ $function = $reflection->getSignature('__isset');
+ if (version_compare(phpversion(), '5.1.0', '>=')) {
+ $this->assertEqual('function __isset($key)', $function);
+ } else {
+ $this->assertEqual('function __isset()', $function);
+ }
+ }
+
+ function testUnsetFunctionSignature() {
+ $reflection = new SimpleReflection('AnyOldOverloadedClass');
+ $function = $reflection->getSignature('__unset');
+ if (version_compare(phpversion(), '5.1.0', '>=')) {
+ $this->assertEqual('function __unset($key)', $function);
+ } else {
+ $this->assertEqual('function __unset()', $function);
+ }
+ }
+
+ function testProperlyReflectsTheFinalInterfaceWhenObjectImplementsAnExtendedInterface() {
+ $reflection = new SimpleReflection('AnyDescendentImplementation');
+ $interfaces = $reflection->getInterfaces();
+ $this->assertEqual(1, count($interfaces));
+ $this->assertEqual('AnyDescendentInterface', array_shift($interfaces));
+ }
+
+ function testCreatingSignatureForAbstractMethod() {
+ $reflection = new SimpleReflection('AnotherOldAbstractClass');
+ $this->assertEqual($reflection->getSignature('aMethod'), 'function aMethod(AnyOldInterface $argument)');
+ }
+
+ function testCanProperlyGenerateStaticMethodSignatures() {
+ $reflection = new SimpleReflection('AnyOldClassWithStaticMethods');
+ $this->assertEqual('static function aStatic()', $reflection->getSignature('aStatic'));
+ $this->assertEqual(
+ 'static function aStaticWithParameters($arg1, $arg2)',
+ $reflection->getSignature('aStaticWithParameters')
+ );
+ }
+}
+
+class TestOfReflectionWithTypeHints extends UnitTestCase {
+ function skip() {
+ $this->skipIf(version_compare(phpversion(), '5.1.0', '<'), 'Reflection with type hints only tested for PHP 5.1.0 and above');
+ }
+
+ function testParameterCreationForTypeHintingWithArray() {
+ eval('interface AnyOldArrayTypeHintedInterface {
+ function amethod(array $argument);
+ }
+ class AnyOldArrayTypeHintedClass implements AnyOldArrayTypeHintedInterface {
+ function amethod(array $argument) {}
+ }');
+ $reflection = new SimpleReflection('AnyOldArrayTypeHintedClass');
+ $function = $reflection->getSignature('amethod');
+ $this->assertEqual('function amethod(array $argument)', $function);
+ }
+}
+
+class TestOfAbstractsWithAbstractMethods extends UnitTestCase {
+ function testCanProperlyGenerateAbstractMethods() {
+ $reflection = new SimpleReflection('AnyOldAbstractClassWithAbstractMethods');
+ $this->assertEqual(
+ 'function anAbstract()',
+ $reflection->getSignature('anAbstract')
+ );
+ $this->assertEqual(
+ 'function anAbstractWithParameter($foo)',
+ $reflection->getSignature('anAbstractWithParameter')
+ );
+ $this->assertEqual(
+ 'function anAbstractWithMultipleParameters($foo, $bar)',
+ $reflection->getSignature('anAbstractWithMultipleParameters')
+ );
+ }
+}
+
+?> \ No newline at end of file
diff --git a/site/vendors/simpletest/test/remote_test.php b/site/vendors/simpletest/test/remote_test.php
new file mode 100644
index 0000000..efcccaf
--- /dev/null
+++ b/site/vendors/simpletest/test/remote_test.php
@@ -0,0 +1,20 @@
+<?php
+// $Id: remote_test.php 1505 2007-04-30 23:39:59Z lastcraft $
+require_once('../remote.php');
+require_once('../reporter.php');
+
+// The following URL will depend on your own installation.
+if (isset($_SERVER['SCRIPT_URI'])) {
+ $base_uri = $_SERVER['SCRIPT_URI'];
+} elseif (isset($_SERVER['HTTP_HOST']) && isset($_SERVER['PHP_SELF'])) {
+ $base_uri = 'http://'. $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF'];
+};
+$test_url = str_replace('remote_test.php', 'visual_test.php', $base_uri);
+
+$test = &new TestSuite('Remote tests');
+$test->addTestCase(new RemoteTestCase($test_url . '?xml=yes', $test_url . '?xml=yes&dry=yes'));
+if (SimpleReporter::inCli()) {
+ exit ($test->run(new TextReporter()) ? 0 : 1);
+}
+$test->run(new HtmlReporter());
+?> \ No newline at end of file
diff --git a/site/vendors/simpletest/test/shell_test.php b/site/vendors/simpletest/test/shell_test.php
new file mode 100644
index 0000000..6199272
--- /dev/null
+++ b/site/vendors/simpletest/test/shell_test.php
@@ -0,0 +1,38 @@
+<?php
+// $Id: shell_test.php 1529 2007-06-04 18:33:09Z lastcraft $
+require_once(dirname(__FILE__) . '/../autorun.php');
+require_once(dirname(__FILE__) . '/../shell_tester.php');
+
+class TestOfShell extends UnitTestCase {
+
+ function testEcho() {
+ $shell = &new SimpleShell();
+ $this->assertIdentical($shell->execute('echo Hello'), 0);
+ $this->assertPattern('/Hello/', $shell->getOutput());
+ }
+
+ function testBadCommand() {
+ $shell = &new SimpleShell();
+ $this->assertNotEqual($ret = $shell->execute('blurgh! 2>&1'), 0);
+ }
+}
+
+class TestOfShellTesterAndShell extends ShellTestCase {
+
+ function testEcho() {
+ $this->assertTrue($this->execute('echo Hello'));
+ $this->assertExitCode(0);
+ $this->assertoutput('Hello');
+ }
+
+ function testFileExistence() {
+ $this->assertFileExists(dirname(__FILE__) . '/all_tests.php');
+ $this->assertFileNotExists('wibble');
+ }
+
+ function testFilePatterns() {
+ $this->assertFilePattern('/all[_ ]tests/i', dirname(__FILE__) . '/all_tests.php');
+ $this->assertNoFilePattern('/sputnik/i', dirname(__FILE__) . '/all_tests.php');
+ }
+}
+?> \ No newline at end of file
diff --git a/site/vendors/simpletest/test/shell_tester_test.php b/site/vendors/simpletest/test/shell_tester_test.php
new file mode 100644
index 0000000..e536dce
--- /dev/null
+++ b/site/vendors/simpletest/test/shell_tester_test.php
@@ -0,0 +1,42 @@
+<?php
+// $Id: shell_tester_test.php 1505 2007-04-30 23:39:59Z lastcraft $
+require_once(dirname(__FILE__) . '/../autorun.php');
+require_once(dirname(__FILE__) . '/../shell_tester.php');
+Mock::generate('SimpleShell');
+
+class TestOfShellTestCase extends ShellTestCase {
+ var $_mock_shell = false;
+
+ function &_getShell() {
+ return $this->_mock_shell;
+ }
+
+ function testGenericEquality() {
+ $this->assertEqual('a', 'a');
+ $this->assertNotEqual('a', 'A');
+ }
+
+ function testExitCode() {
+ $this->_mock_shell = &new MockSimpleShell();
+ $this->_mock_shell->setReturnValue('execute', 0);
+ $this->_mock_shell->expectOnce('execute', array('ls'));
+ $this->assertTrue($this->execute('ls'));
+ $this->assertExitCode(0);
+ }
+
+ function testOutput() {
+ $this->_mock_shell = &new MockSimpleShell();
+ $this->_mock_shell->setReturnValue('execute', 0);
+ $this->_mock_shell->setReturnValue('getOutput', "Line 1\nLine 2\n");
+ $this->assertOutput("Line 1\nLine 2\n");
+ }
+
+ function testOutputPatterns() {
+ $this->_mock_shell = &new MockSimpleShell();
+ $this->_mock_shell->setReturnValue('execute', 0);
+ $this->_mock_shell->setReturnValue('getOutput', "Line 1\nLine 2\n");
+ $this->assertOutputPattern('/line/i');
+ $this->assertNoOutputPattern('/line 2/');
+ }
+}
+?> \ No newline at end of file
diff --git a/site/vendors/simpletest/test/simpletest_test.php b/site/vendors/simpletest/test/simpletest_test.php
new file mode 100644
index 0000000..bf98d97
--- /dev/null
+++ b/site/vendors/simpletest/test/simpletest_test.php
@@ -0,0 +1,58 @@
+<?php
+// $Id: simpletest_test.php 1505 2007-04-30 23:39:59Z lastcraft $
+require_once(dirname(__FILE__) . '/../autorun.php');
+require_once(dirname(__FILE__) . '/../simpletest.php');
+
+SimpleTest::ignore('ShouldNeverBeRunEither');
+
+class ShouldNeverBeRun extends UnitTestCase {
+ function testWithNoChanceOfSuccess() {
+ $this->fail('Should be ignored');
+ }
+}
+
+class ShouldNeverBeRunEither extends ShouldNeverBeRun { }
+
+class TestOfStackTrace extends UnitTestCase {
+
+ function testCanFindAssertInTrace() {
+ $trace = new SimpleStackTrace(array('assert'));
+ $this->assertEqual(
+ $trace->traceMethod(array(array(
+ 'file' => '/my_test.php',
+ 'line' => 24,
+ 'function' => 'assertSomething'))),
+ ' at [/my_test.php line 24]');
+ }
+}
+
+class DummyResource { }
+
+class TestOfContext extends UnitTestCase {
+
+ function testCurrentContextIsUnique() {
+ $this->assertReference(
+ SimpleTest::getContext(),
+ SimpleTest::getContext());
+ }
+
+ function testContextHoldsCurrentTestCase() {
+ $context = &SimpleTest::getContext();
+ $this->assertReference($this, $context->getTest());
+ }
+
+ function testResourceIsSingleInstanceWithContext() {
+ $context = &new SimpleTestContext();
+ $this->assertReference(
+ $context->get('DummyResource'),
+ $context->get('DummyResource'));
+ }
+
+ function testClearingContextResetsResources() {
+ $context = &new SimpleTestContext();
+ $resource = &$context->get('DummyResource');
+ $context->clear();
+ $this->assertClone($resource, $context->get('DummyResource'));
+ }
+}
+?> \ No newline at end of file
diff --git a/site/vendors/simpletest/test/socket_test.php b/site/vendors/simpletest/test/socket_test.php
new file mode 100644
index 0000000..ce25be7
--- /dev/null
+++ b/site/vendors/simpletest/test/socket_test.php
@@ -0,0 +1,25 @@
+<?php
+// $Id: socket_test.php 1509 2007-05-08 22:11:49Z lastcraft $
+require_once(dirname(__FILE__) . '/../autorun.php');
+require_once(dirname(__FILE__) . '/../socket.php');
+Mock::generate('SimpleSocket');
+
+class TestOfSimpleStickyError extends UnitTestCase {
+
+ function testSettingError() {
+ $error = new SimpleStickyError();
+ $this->assertFalse($error->isError());
+ $error->_setError('Ouch');
+ $this->assertTrue($error->isError());
+ $this->assertEqual($error->getError(), 'Ouch');
+ }
+
+ function testClearingError() {
+ $error = new SimpleStickyError();
+ $error->_setError('Ouch');
+ $this->assertTrue($error->isError());
+ $error->_clearError();
+ $this->assertFalse($error->isError());
+ }
+}
+?> \ No newline at end of file
diff --git a/site/vendors/simpletest/test/support/collector/collectable.1 b/site/vendors/simpletest/test/support/collector/collectable.1
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/site/vendors/simpletest/test/support/collector/collectable.1
diff --git a/site/vendors/simpletest/test/support/collector/collectable.2 b/site/vendors/simpletest/test/support/collector/collectable.2
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/site/vendors/simpletest/test/support/collector/collectable.2
diff --git a/site/vendors/simpletest/test/support/empty_test_file.php b/site/vendors/simpletest/test/support/empty_test_file.php
new file mode 100644
index 0000000..31e3f7b
--- /dev/null
+++ b/site/vendors/simpletest/test/support/empty_test_file.php
@@ -0,0 +1,3 @@
+<?php
+require_once(dirname(__FILE__) . '/../../autorun.php');
+?> \ No newline at end of file
diff --git a/site/vendors/simpletest/test/support/latin1_sample b/site/vendors/simpletest/test/support/latin1_sample
new file mode 100644
index 0000000..1903525
--- /dev/null
+++ b/site/vendors/simpletest/test/support/latin1_sample
@@ -0,0 +1 @@
+£¹²³¼½¾@¶øþðßæ«»¢µ \ No newline at end of file
diff --git a/site/vendors/simpletest/test/support/spl_examples.php b/site/vendors/simpletest/test/support/spl_examples.php
new file mode 100644
index 0000000..45add35
--- /dev/null
+++ b/site/vendors/simpletest/test/support/spl_examples.php
@@ -0,0 +1,15 @@
+<?php
+ // $Id: spl_examples.php 1262 2006-02-05 19:35:31Z lastcraft $
+
+ class IteratorImplementation implements Iterator {
+ function current() { }
+ function next() { }
+ function key() { }
+ function valid() { }
+ function rewind() { }
+ }
+
+ class IteratorAggregateImplementation implements IteratorAggregate {
+ function getIterator() { }
+ }
+?> \ No newline at end of file
diff --git a/site/vendors/simpletest/test/support/supplementary_upload_sample.txt b/site/vendors/simpletest/test/support/supplementary_upload_sample.txt
new file mode 100644
index 0000000..d8aa9e8
--- /dev/null
+++ b/site/vendors/simpletest/test/support/supplementary_upload_sample.txt
@@ -0,0 +1 @@
+Some more text content \ No newline at end of file
diff --git a/site/vendors/simpletest/test/support/test1.php b/site/vendors/simpletest/test/support/test1.php
new file mode 100644
index 0000000..b414586
--- /dev/null
+++ b/site/vendors/simpletest/test/support/test1.php
@@ -0,0 +1,7 @@
+<?php
+class test1 extends UnitTestCase {
+ function test_pass(){
+ $this->assertEqual(3,1+2, "pass1");
+ }
+}
+?>
diff --git a/site/vendors/simpletest/test/support/upload_sample.txt b/site/vendors/simpletest/test/support/upload_sample.txt
new file mode 100644
index 0000000..ec98d7c
--- /dev/null
+++ b/site/vendors/simpletest/test/support/upload_sample.txt
@@ -0,0 +1 @@
+Sample for testing file upload \ No newline at end of file
diff --git a/site/vendors/simpletest/test/tag_test.php b/site/vendors/simpletest/test/tag_test.php
new file mode 100644
index 0000000..f81df64
--- /dev/null
+++ b/site/vendors/simpletest/test/tag_test.php
@@ -0,0 +1,554 @@
+<?php
+// $Id: tag_test.php 1509 2007-05-08 22:11:49Z lastcraft $
+require_once(dirname(__FILE__) . '/../autorun.php');
+require_once(dirname(__FILE__) . '/../tag.php');
+require_once(dirname(__FILE__) . '/../encoding.php');
+Mock::generate('SimpleMultipartEncoding');
+
+class TestOfTag extends UnitTestCase {
+
+ function testStartValuesWithoutAdditionalContent() {
+ $tag = new SimpleTitleTag(array('a' => '1', 'b' => ''));
+ $this->assertEqual($tag->getTagName(), 'title');
+ $this->assertIdentical($tag->getAttribute('a'), '1');
+ $this->assertIdentical($tag->getAttribute('b'), '');
+ $this->assertIdentical($tag->getAttribute('c'), false);
+ $this->assertIdentical($tag->getContent(), '');
+ }
+
+ function testTitleContent() {
+ $tag = &new SimpleTitleTag(array());
+ $this->assertTrue($tag->expectEndTag());
+ $tag->addContent('Hello');
+ $tag->addContent('World');
+ $this->assertEqual($tag->getText(), 'HelloWorld');
+ }
+
+ function testMessyTitleContent() {
+ $tag = &new SimpleTitleTag(array());
+ $this->assertTrue($tag->expectEndTag());
+ $tag->addContent('<b>Hello</b>');
+ $tag->addContent('<em>World</em>');
+ $this->assertEqual($tag->getText(), 'HelloWorld');
+ }
+
+ function testTagWithNoEnd() {
+ $tag = &new SimpleTextTag(array());
+ $this->assertFalse($tag->expectEndTag());
+ }
+
+ function testAnchorHref() {
+ $tag = &new SimpleAnchorTag(array('href' => 'http://here/'));
+ $this->assertEqual($tag->getHref(), 'http://here/');
+
+ $tag = &new SimpleAnchorTag(array('href' => ''));
+ $this->assertIdentical($tag->getAttribute('href'), '');
+ $this->assertIdentical($tag->getHref(), '');
+
+ $tag = &new SimpleAnchorTag(array());
+ $this->assertIdentical($tag->getAttribute('href'), false);
+ $this->assertIdentical($tag->getHref(), '');
+ }
+
+ function testIsIdMatchesIdAttribute() {
+ $tag = &new SimpleAnchorTag(array('href' => 'http://here/', 'id' => 7));
+ $this->assertIdentical($tag->getAttribute('id'), '7');
+ $this->assertTrue($tag->isId(7));
+ }
+}
+
+class TestOfWidget extends UnitTestCase {
+
+ function testTextEmptyDefault() {
+ $tag = &new SimpleTextTag(array('type' => 'text'));
+ $this->assertIdentical($tag->getDefault(), '');
+ $this->assertIdentical($tag->getValue(), '');
+ }
+
+ function testSettingOfExternalLabel() {
+ $tag = &new SimpleTextTag(array('type' => 'text'));
+ $tag->setLabel('it');
+ $this->assertTrue($tag->isLabel('it'));
+ }
+
+ function testTextDefault() {
+ $tag = &new SimpleTextTag(array('value' => 'aaa'));
+ $this->assertEqual($tag->getDefault(), 'aaa');
+ $this->assertEqual($tag->getValue(), 'aaa');
+ }
+
+ function testSettingTextValue() {
+ $tag = &new SimpleTextTag(array('value' => 'aaa'));
+ $tag->setValue('bbb');
+ $this->assertEqual($tag->getValue(), 'bbb');
+ $tag->resetValue();
+ $this->assertEqual($tag->getValue(), 'aaa');
+ }
+
+ function testFailToSetHiddenValue() {
+ $tag = &new SimpleTextTag(array('value' => 'aaa', 'type' => 'hidden'));
+ $this->assertFalse($tag->setValue('bbb'));
+ $this->assertEqual($tag->getValue(), 'aaa');
+ }
+
+ function testSubmitDefaults() {
+ $tag = &new SimpleSubmitTag(array('type' => 'submit'));
+ $this->assertIdentical($tag->getName(), false);
+ $this->assertEqual($tag->getValue(), 'Submit');
+ $this->assertFalse($tag->setValue('Cannot set this'));
+ $this->assertEqual($tag->getValue(), 'Submit');
+ $this->assertEqual($tag->getLabel(), 'Submit');
+
+ $encoding = &new MockSimpleMultipartEncoding();
+ $encoding->expectNever('add');
+ $tag->write($encoding);
+ }
+
+ function testPopulatedSubmit() {
+ $tag = &new SimpleSubmitTag(
+ array('type' => 'submit', 'name' => 's', 'value' => 'Ok!'));
+ $this->assertEqual($tag->getName(), 's');
+ $this->assertEqual($tag->getValue(), 'Ok!');
+ $this->assertEqual($tag->getLabel(), 'Ok!');
+
+ $encoding = &new MockSimpleMultipartEncoding();
+ $encoding->expectOnce('add', array('s', 'Ok!'));
+ $tag->write($encoding);
+ }
+
+ function testImageSubmit() {
+ $tag = &new SimpleImageSubmitTag(
+ array('type' => 'image', 'name' => 's', 'alt' => 'Label'));
+ $this->assertEqual($tag->getName(), 's');
+ $this->assertEqual($tag->getLabel(), 'Label');
+
+ $encoding = &new MockSimpleMultipartEncoding();
+ $encoding->expectAt(0, 'add', array('s.x', 20));
+ $encoding->expectAt(1, 'add', array('s.y', 30));
+ $tag->write($encoding, 20, 30);
+ }
+
+ function testImageSubmitTitlePreferredOverAltForLabel() {
+ $tag = &new SimpleImageSubmitTag(
+ array('type' => 'image', 'name' => 's', 'alt' => 'Label', 'title' => 'Title'));
+ $this->assertEqual($tag->getLabel(), 'Title');
+ }
+
+ function testButton() {
+ $tag = &new SimpleButtonTag(
+ array('type' => 'submit', 'name' => 's', 'value' => 'do'));
+ $tag->addContent('I am a button');
+ $this->assertEqual($tag->getName(), 's');
+ $this->assertEqual($tag->getValue(), 'do');
+ $this->assertEqual($tag->getLabel(), 'I am a button');
+
+ $encoding = &new MockSimpleMultipartEncoding();
+ $encoding->expectOnce('add', array('s', 'do'));
+ $tag->write($encoding);
+ }
+}
+
+class TestOfTextArea extends UnitTestCase {
+
+ function testDefault() {
+ $tag = &new SimpleTextAreaTag(array('name' => 'a'));
+ $tag->addContent('Some text');
+ $this->assertEqual($tag->getName(), 'a');
+ $this->assertEqual($tag->getDefault(), 'Some text');
+ }
+
+ function testWrapping() {
+ $tag = &new SimpleTextAreaTag(array('cols' => '10', 'wrap' => 'physical'));
+ $tag->addContent("Lot's of text that should be wrapped");
+ $this->assertEqual(
+ $tag->getDefault(),
+ "Lot's of\r\ntext that\r\nshould be\r\nwrapped");
+ $tag->setValue("New long text\r\nwith two lines");
+ $this->assertEqual(
+ $tag->getValue(),
+ "New long\r\ntext\r\nwith two\r\nlines");
+ }
+
+ function testWrappingRemovesLeadingcariageReturn() {
+ $tag = &new SimpleTextAreaTag(array('cols' => '20', 'wrap' => 'physical'));
+ $tag->addContent("\rStuff");
+ $this->assertEqual($tag->getDefault(), 'Stuff');
+ $tag->setValue("\nNew stuff\n");
+ $this->assertEqual($tag->getValue(), "New stuff\r\n");
+ }
+
+ function testBreaksAreNewlineAndCarriageReturn() {
+ $tag = &new SimpleTextAreaTag(array('cols' => '10'));
+ $tag->addContent("Some\nText\rwith\r\nbreaks");
+ $this->assertEqual($tag->getValue(), "Some\r\nText\r\nwith\r\nbreaks");
+ }
+}
+
+class TestOfCheckbox extends UnitTestCase {
+
+ function testCanSetCheckboxToNamedValueWithBooleanTrue() {
+ $tag = &new SimpleCheckboxTag(array('name' => 'a', 'value' => 'A'));
+ $this->assertEqual($tag->getValue(), false);
+ $tag->setValue(true);
+ $this->assertIdentical($tag->getValue(), 'A');
+ }
+}
+
+class TestOfSelection extends UnitTestCase {
+
+ function testEmpty() {
+ $tag = &new SimpleSelectionTag(array('name' => 'a'));
+ $this->assertIdentical($tag->getValue(), '');
+ }
+
+ function testSingle() {
+ $tag = &new SimpleSelectionTag(array('name' => 'a'));
+ $option = &new SimpleOptionTag(array());
+ $option->addContent('AAA');
+ $tag->addTag($option);
+ $this->assertEqual($tag->getValue(), 'AAA');
+ }
+
+ function testSingleDefault() {
+ $tag = &new SimpleSelectionTag(array('name' => 'a'));
+ $option = &new SimpleOptionTag(array('selected' => ''));
+ $option->addContent('AAA');
+ $tag->addTag($option);
+ $this->assertEqual($tag->getValue(), 'AAA');
+ }
+
+ function testSingleMappedDefault() {
+ $tag = &new SimpleSelectionTag(array('name' => 'a'));
+ $option = &new SimpleOptionTag(array('selected' => '', 'value' => 'aaa'));
+ $option->addContent('AAA');
+ $tag->addTag($option);
+ $this->assertEqual($tag->getValue(), 'aaa');
+ }
+
+ function testStartsWithDefault() {
+ $tag = &new SimpleSelectionTag(array('name' => 'a'));
+ $a = &new SimpleOptionTag(array());
+ $a->addContent('AAA');
+ $tag->addTag($a);
+ $b = &new SimpleOptionTag(array('selected' => ''));
+ $b->addContent('BBB');
+ $tag->addTag($b);
+ $c = &new SimpleOptionTag(array());
+ $c->addContent('CCC');
+ $tag->addTag($c);
+ $this->assertEqual($tag->getValue(), 'BBB');
+ }
+
+ function testSettingOption() {
+ $tag = &new SimpleSelectionTag(array('name' => 'a'));
+ $a = &new SimpleOptionTag(array());
+ $a->addContent('AAA');
+ $tag->addTag($a);
+ $b = &new SimpleOptionTag(array('selected' => ''));
+ $b->addContent('BBB');
+ $tag->addTag($b);
+ $c = &new SimpleOptionTag(array());
+ $c->addContent('CCC');
+ $tag->setValue('AAA');
+ $this->assertEqual($tag->getValue(), 'AAA');
+ }
+
+ function testSettingMappedOption() {
+ $tag = &new SimpleSelectionTag(array('name' => 'a'));
+ $a = &new SimpleOptionTag(array('value' => 'aaa'));
+ $a->addContent('AAA');
+ $tag->addTag($a);
+ $b = &new SimpleOptionTag(array('value' => 'bbb', 'selected' => ''));
+ $b->addContent('BBB');
+ $tag->addTag($b);
+ $c = &new SimpleOptionTag(array('value' => 'ccc'));
+ $c->addContent('CCC');
+ $tag->addTag($c);
+ $tag->setValue('AAA');
+ $this->assertEqual($tag->getValue(), 'aaa');
+ $tag->setValue('ccc');
+ $this->assertEqual($tag->getValue(), 'ccc');
+ }
+
+ function testSelectionDespiteSpuriousWhitespace() {
+ $tag = &new SimpleSelectionTag(array('name' => 'a'));
+ $a = &new SimpleOptionTag(array());
+ $a->addContent(' AAA ');
+ $tag->addTag($a);
+ $b = &new SimpleOptionTag(array('selected' => ''));
+ $b->addContent(' BBB ');
+ $tag->addTag($b);
+ $c = &new SimpleOptionTag(array());
+ $c->addContent(' CCC ');
+ $tag->addTag($c);
+ $this->assertEqual($tag->getValue(), ' BBB ');
+ $tag->setValue('AAA');
+ $this->assertEqual($tag->getValue(), ' AAA ');
+ }
+
+ function testFailToSetIllegalOption() {
+ $tag = &new SimpleSelectionTag(array('name' => 'a'));
+ $a = &new SimpleOptionTag(array());
+ $a->addContent('AAA');
+ $tag->addTag($a);
+ $b = &new SimpleOptionTag(array('selected' => ''));
+ $b->addContent('BBB');
+ $tag->addTag($b);
+ $c = &new SimpleOptionTag(array());
+ $c->addContent('CCC');
+ $tag->addTag($c);
+ $this->assertFalse($tag->setValue('Not present'));
+ $this->assertEqual($tag->getValue(), 'BBB');
+ }
+
+ function testNastyOptionValuesThatLookLikeFalse() {
+ $tag = &new SimpleSelectionTag(array('name' => 'a'));
+ $a = &new SimpleOptionTag(array('value' => '1'));
+ $a->addContent('One');
+ $tag->addTag($a);
+ $b = &new SimpleOptionTag(array('value' => '0'));
+ $b->addContent('Zero');
+ $tag->addTag($b);
+ $this->assertIdentical($tag->getValue(), '1');
+ $tag->setValue('Zero');
+ $this->assertIdentical($tag->getValue(), '0');
+ }
+
+ function testBlankOption() {
+ $tag = &new SimpleSelectionTag(array('name' => 'A'));
+ $a = &new SimpleOptionTag(array());
+ $tag->addTag($a);
+ $b = &new SimpleOptionTag(array());
+ $b->addContent('b');
+ $tag->addTag($b);
+ $this->assertIdentical($tag->getValue(), '');
+ $tag->setValue('b');
+ $this->assertIdentical($tag->getValue(), 'b');
+ $tag->setValue('');
+ $this->assertIdentical($tag->getValue(), '');
+ }
+
+ function testMultipleDefaultWithNoSelections() {
+ $tag = &new MultipleSelectionTag(array('name' => 'a', 'multiple' => ''));
+ $a = &new SimpleOptionTag(array());
+ $a->addContent('AAA');
+ $tag->addTag($a);
+ $b = &new SimpleOptionTag(array());
+ $b->addContent('BBB');
+ $tag->addTag($b);
+ $this->assertIdentical($tag->getDefault(), array());
+ $this->assertIdentical($tag->getValue(), array());
+ }
+
+ function testMultipleDefaultWithSelections() {
+ $tag = &new MultipleSelectionTag(array('name' => 'a', 'multiple' => ''));
+ $a = &new SimpleOptionTag(array('selected' => ''));
+ $a->addContent('AAA');
+ $tag->addTag($a);
+ $b = &new SimpleOptionTag(array('selected' => ''));
+ $b->addContent('BBB');
+ $tag->addTag($b);
+ $this->assertIdentical($tag->getDefault(), array('AAA', 'BBB'));
+ $this->assertIdentical($tag->getValue(), array('AAA', 'BBB'));
+ }
+
+ function testSettingMultiple() {
+ $tag = &new MultipleSelectionTag(array('name' => 'a', 'multiple' => ''));
+ $a = &new SimpleOptionTag(array('selected' => ''));
+ $a->addContent('AAA');
+ $tag->addTag($a);
+ $b = &new SimpleOptionTag(array());
+ $b->addContent('BBB');
+ $tag->addTag($b);
+ $c = &new SimpleOptionTag(array('selected' => '', 'value' => 'ccc'));
+ $c->addContent('CCC');
+ $tag->addTag($c);
+ $this->assertIdentical($tag->getDefault(), array('AAA', 'ccc'));
+ $this->assertTrue($tag->setValue(array('BBB', 'ccc')));
+ $this->assertIdentical($tag->getValue(), array('BBB', 'ccc'));
+ $this->assertTrue($tag->setValue(array()));
+ $this->assertIdentical($tag->getValue(), array());
+ }
+
+ function testFailToSetIllegalOptionsInMultiple() {
+ $tag = &new MultipleSelectionTag(array('name' => 'a', 'multiple' => ''));
+ $a = &new SimpleOptionTag(array('selected' => ''));
+ $a->addContent('AAA');
+ $tag->addTag($a);
+ $b = &new SimpleOptionTag(array());
+ $b->addContent('BBB');
+ $tag->addTag($b);
+ $this->assertFalse($tag->setValue(array('CCC')));
+ $this->assertTrue($tag->setValue(array('AAA', 'BBB')));
+ $this->assertFalse($tag->setValue(array('AAA', 'CCC')));
+ }
+}
+
+class TestOfRadioGroup extends UnitTestCase {
+
+ function testEmptyGroup() {
+ $group = &new SimpleRadioGroup();
+ $this->assertIdentical($group->getDefault(), false);
+ $this->assertIdentical($group->getValue(), false);
+ $this->assertFalse($group->setValue('a'));
+ }
+
+ function testReadingSingleButtonGroup() {
+ $group = &new SimpleRadioGroup();
+ $group->addWidget(new SimpleRadioButtonTag(
+ array('value' => 'A', 'checked' => '')));
+ $this->assertIdentical($group->getDefault(), 'A');
+ $this->assertIdentical($group->getValue(), 'A');
+ }
+
+ function testReadingMultipleButtonGroup() {
+ $group = &new SimpleRadioGroup();
+ $group->addWidget(new SimpleRadioButtonTag(
+ array('value' => 'A')));
+ $group->addWidget(new SimpleRadioButtonTag(
+ array('value' => 'B', 'checked' => '')));
+ $this->assertIdentical($group->getDefault(), 'B');
+ $this->assertIdentical($group->getValue(), 'B');
+ }
+
+ function testFailToSetUnlistedValue() {
+ $group = &new SimpleRadioGroup();
+ $group->addWidget(new SimpleRadioButtonTag(array('value' => 'z')));
+ $this->assertFalse($group->setValue('a'));
+ $this->assertIdentical($group->getValue(), false);
+ }
+
+ function testSettingNewValueClearsTheOldOne() {
+ $group = &new SimpleRadioGroup();
+ $group->addWidget(new SimpleRadioButtonTag(
+ array('value' => 'A')));
+ $group->addWidget(new SimpleRadioButtonTag(
+ array('value' => 'B', 'checked' => '')));
+ $this->assertTrue($group->setValue('A'));
+ $this->assertIdentical($group->getValue(), 'A');
+ }
+
+ function testIsIdMatchesAnyWidgetInSet() {
+ $group = &new SimpleRadioGroup();
+ $group->addWidget(new SimpleRadioButtonTag(
+ array('value' => 'A', 'id' => 'i1')));
+ $group->addWidget(new SimpleRadioButtonTag(
+ array('value' => 'B', 'id' => 'i2')));
+ $this->assertFalse($group->isId('i0'));
+ $this->assertTrue($group->isId('i1'));
+ $this->assertTrue($group->isId('i2'));
+ }
+
+ function testIsLabelMatchesAnyWidgetInSet() {
+ $group = &new SimpleRadioGroup();
+ $button1 = &new SimpleRadioButtonTag(array('value' => 'A'));
+ $button1->setLabel('one');
+ $group->addWidget($button1);
+ $button2 = &new SimpleRadioButtonTag(array('value' => 'B'));
+ $button2->setLabel('two');
+ $group->addWidget($button2);
+ $this->assertFalse($group->isLabel('three'));
+ $this->assertTrue($group->isLabel('one'));
+ $this->assertTrue($group->isLabel('two'));
+ }
+}
+
+class TestOfTagGroup extends UnitTestCase {
+
+ function testReadingMultipleCheckboxGroup() {
+ $group = &new SimpleCheckboxGroup();
+ $group->addWidget(new SimpleCheckboxTag(array('value' => 'A')));
+ $group->addWidget(new SimpleCheckboxTag(
+ array('value' => 'B', 'checked' => '')));
+ $this->assertIdentical($group->getDefault(), 'B');
+ $this->assertIdentical($group->getValue(), 'B');
+ }
+
+ function testReadingMultipleUncheckedItems() {
+ $group = &new SimpleCheckboxGroup();
+ $group->addWidget(new SimpleCheckboxTag(array('value' => 'A')));
+ $group->addWidget(new SimpleCheckboxTag(array('value' => 'B')));
+ $this->assertIdentical($group->getDefault(), false);
+ $this->assertIdentical($group->getValue(), false);
+ }
+
+ function testReadingMultipleCheckedItems() {
+ $group = &new SimpleCheckboxGroup();
+ $group->addWidget(new SimpleCheckboxTag(
+ array('value' => 'A', 'checked' => '')));
+ $group->addWidget(new SimpleCheckboxTag(
+ array('value' => 'B', 'checked' => '')));
+ $this->assertIdentical($group->getDefault(), array('A', 'B'));
+ $this->assertIdentical($group->getValue(), array('A', 'B'));
+ }
+
+ function testSettingSingleValue() {
+ $group = &new SimpleCheckboxGroup();
+ $group->addWidget(new SimpleCheckboxTag(array('value' => 'A')));
+ $group->addWidget(new SimpleCheckboxTag(array('value' => 'B')));
+ $this->assertTrue($group->setValue('A'));
+ $this->assertIdentical($group->getValue(), 'A');
+ $this->assertTrue($group->setValue('B'));
+ $this->assertIdentical($group->getValue(), 'B');
+ }
+
+ function testSettingMultipleValues() {
+ $group = &new SimpleCheckboxGroup();
+ $group->addWidget(new SimpleCheckboxTag(array('value' => 'A')));
+ $group->addWidget(new SimpleCheckboxTag(array('value' => 'B')));
+ $this->assertTrue($group->setValue(array('A', 'B')));
+ $this->assertIdentical($group->getValue(), array('A', 'B'));
+ }
+
+ function testSettingNoValue() {
+ $group = &new SimpleCheckboxGroup();
+ $group->addWidget(new SimpleCheckboxTag(array('value' => 'A')));
+ $group->addWidget(new SimpleCheckboxTag(array('value' => 'B')));
+ $this->assertTrue($group->setValue(false));
+ $this->assertIdentical($group->getValue(), false);
+ }
+
+ function testIsIdMatchesAnyIdInSet() {
+ $group = &new SimpleCheckboxGroup();
+ $group->addWidget(new SimpleCheckboxTag(array('id' => 1, 'value' => 'A')));
+ $group->addWidget(new SimpleCheckboxTag(array('id' => 2, 'value' => 'B')));
+ $this->assertFalse($group->isId(0));
+ $this->assertTrue($group->isId(1));
+ $this->assertTrue($group->isId(2));
+ }
+}
+
+class TestOfUploadWidget extends UnitTestCase {
+
+ function testValueIsFilePath() {
+ $upload = &new SimpleUploadTag(array('name' => 'a'));
+ $upload->setValue(dirname(__FILE__) . '/support/upload_sample.txt');
+ $this->assertEqual($upload->getValue(), dirname(__FILE__) . '/support/upload_sample.txt');
+ }
+
+ function testSubmitsFileContents() {
+ $encoding = &new MockSimpleMultipartEncoding();
+ $encoding->expectOnce('attach', array(
+ 'a',
+ 'Sample for testing file upload',
+ 'upload_sample.txt'));
+ $upload = &new SimpleUploadTag(array('name' => 'a'));
+ $upload->setValue(dirname(__FILE__) . '/support/upload_sample.txt');
+ $upload->write($encoding);
+ }
+}
+
+class TestOfLabelTag extends UnitTestCase {
+
+ function testLabelShouldHaveAnEndTag() {
+ $label = &new SimpleLabelTag(array());
+ $this->assertTrue($label->expectEndTag());
+ }
+
+ function testContentIsTextOnly() {
+ $label = &new SimpleLabelTag(array());
+ $label->addContent('Here <tag>are</tag> words');
+ $this->assertEqual($label->getText(), 'Here are words');
+ }
+}
+?> \ No newline at end of file
diff --git a/site/vendors/simpletest/test/test_groups.php b/site/vendors/simpletest/test/test_groups.php
new file mode 100644
index 0000000..6cbaced
--- /dev/null
+++ b/site/vendors/simpletest/test/test_groups.php
@@ -0,0 +1,64 @@
+<?php
+ // $Id: test_groups.php,v 1.1 2006/08/27 02:06:40 shaver%mozilla.org Exp $
+ require_once(dirname(__FILE__) . '/../unit_tester.php');
+ require_once(dirname(__FILE__) . '/../shell_tester.php');
+ require_once(dirname(__FILE__) . '/../mock_objects.php');
+ require_once(dirname(__FILE__) . '/../web_tester.php');
+ require_once(dirname(__FILE__) . '/../extensions/pear_test_case.php');
+ require_once(dirname(__FILE__) . '/../extensions/phpunit_test_case.php');
+
+ class UnitTests extends GroupTest {
+ function UnitTests() {
+ $this->GroupTest('Unit tests');
+ $path = dirname(__FILE__);
+ $this->addTestFile($path . '/errors_test.php');
+ $this->addTestFile($path . '/compatibility_test.php');
+ $this->addTestFile($path . '/simpletest_test.php');
+ $this->addTestFile($path . '/dumper_test.php');
+ $this->addTestFile($path . '/expectation_test.php');
+ $this->addTestFile($path . '/unit_tester_test.php');
+ if (version_compare(phpversion(), '5') >= 0) {
+ $this->addTestFile($path . '/reflection_php5_test.php');
+ } else {
+ $this->addTestFile($path . '/reflection_php4_test.php');
+ }
+ $this->addTestFile($path . '/mock_objects_test.php');
+ if (version_compare(phpversion(), '5') >= 0) {
+ $this->addTestFile($path . '/interfaces_test.php');
+ }
+ $this->addTestFile($path . '/collector_test.php');
+ $this->addTestFile($path . '/adapter_test.php');
+ $this->addTestFile($path . '/socket_test.php');
+ $this->addTestFile($path . '/encoding_test.php');
+ $this->addTestFile($path . '/url_test.php');
+ $this->addTestFile($path . '/cookies_test.php');
+ $this->addTestFile($path . '/http_test.php');
+ $this->addTestFile($path . '/authentication_test.php');
+ $this->addTestFile($path . '/user_agent_test.php');
+ $this->addTestFile($path . '/parser_test.php');
+ $this->addTestFile($path . '/tag_test.php');
+ $this->addTestFile($path . '/form_test.php');
+ $this->addTestFile($path . '/page_test.php');
+ $this->addTestFile($path . '/frames_test.php');
+ $this->addTestFile($path . '/browser_test.php');
+ $this->addTestFile($path . '/web_tester_test.php');
+ $this->addTestFile($path . '/shell_tester_test.php');
+ $this->addTestFile($path . '/xml_test.php');
+ }
+ }
+
+ // Uncomment and modify the following line if you are accessing
+ // the net via a proxy server.
+ //
+ // SimpleTest::useProxy('http://my-proxy', 'optional username', 'optional password');
+
+ class AllTests extends GroupTest {
+ function AllTests() {
+ $this->GroupTest('All tests for SimpleTest ' . SimpleTest::getVersion());
+ $this->addTestCase(new UnitTests());
+ $this->addTestFile(dirname(__FILE__) . '/shell_test.php');
+ $this->addTestFile(dirname(__FILE__) . '/live_test.php');
+ $this->addTestFile(dirname(__FILE__) . '/acceptance_test.php');
+ }
+ }
+?> \ No newline at end of file
diff --git a/site/vendors/simpletest/test/test_with_parse_error.php b/site/vendors/simpletest/test/test_with_parse_error.php
new file mode 100644
index 0000000..41a5832
--- /dev/null
+++ b/site/vendors/simpletest/test/test_with_parse_error.php
@@ -0,0 +1,8 @@
+<?php
+ // $Id: test_with_parse_error.php 901 2005-01-24 00:32:14Z lastcraft $
+
+ class TestCaseWithParseError extends UnitTestCase {
+ wibble
+ }
+
+?> \ No newline at end of file
diff --git a/site/vendors/simpletest/test/unit_tester_test.php b/site/vendors/simpletest/test/unit_tester_test.php
new file mode 100644
index 0000000..5fe78fe
--- /dev/null
+++ b/site/vendors/simpletest/test/unit_tester_test.php
@@ -0,0 +1,55 @@
+<?php
+// $Id: unit_tester_test.php 1509 2007-05-08 22:11:49Z lastcraft $
+require_once(dirname(__FILE__) . '/../autorun.php');
+
+class ReferenceForTesting {
+}
+
+class TestOfUnitTester extends UnitTestCase {
+
+ function testAssertTrueReturnsAssertionAsBoolean() {
+ $this->assertTrue($this->assertTrue(true));
+ }
+
+ function testAssertFalseReturnsAssertionAsBoolean() {
+ $this->assertTrue($this->assertFalse(false));
+ }
+
+ function testAssertEqualReturnsAssertionAsBoolean() {
+ $this->assertTrue($this->assertEqual(5, 5));
+ }
+
+ function testAssertIdenticalReturnsAssertionAsBoolean() {
+ $this->assertTrue($this->assertIdentical(5, 5));
+ }
+
+ function testCoreAssertionsDoNotThrowErrors() {
+ $this->assertIsA($this, 'UnitTestCase');
+ $this->assertNotA($this, 'WebTestCase');
+ }
+
+ function testReferenceAssertionOnObjects() {
+ $a = &new ReferenceForTesting();
+ $b = &$a;
+ $this->assertReference($a, $b);
+ }
+
+ function testReferenceAssertionOnScalars() {
+ $a = 25;
+ $b = &$a;
+ $this->assertReference($a, $b);
+ }
+
+ function testCloneOnObjects() {
+ $a = &new ReferenceForTesting();
+ $b = &new ReferenceForTesting();
+ $this->assertClone($a, $b);
+ }
+
+ function testCloneOnScalars() {
+ $a = 25;
+ $b = 25;
+ $this->assertClone($a, $b);
+ }
+}
+?> \ No newline at end of file
diff --git a/site/vendors/simpletest/test/unit_tests.php b/site/vendors/simpletest/test/unit_tests.php
new file mode 100644
index 0000000..04dbc46
--- /dev/null
+++ b/site/vendors/simpletest/test/unit_tests.php
@@ -0,0 +1,55 @@
+<?php
+// $Id: unit_tests.php 1661 2008-02-26 21:04:31Z pp11 $
+require_once(dirname(__FILE__) . '/../autorun.php');
+require_once(dirname(__FILE__) . '/../unit_tester.php');
+require_once(dirname(__FILE__) . '/../shell_tester.php');
+require_once(dirname(__FILE__) . '/../mock_objects.php');
+require_once(dirname(__FILE__) . '/../web_tester.php');
+require_once(dirname(__FILE__) . '/../extensions/pear_test_case.php');
+require_once(dirname(__FILE__) . '/../extensions/phpunit_test_case.php');
+
+class UnitTests extends TestSuite {
+ function UnitTests() {
+ $this->TestSuite('Unit tests');
+ $path = dirname(__FILE__);
+ $this->addFile($path . '/errors_test.php');
+ if (version_compare(phpversion(), '5') >= 0) {
+ $this->addFile($path . '/exceptions_test.php');
+ }
+ $this->addFile($path . '/autorun_test.php');
+ $this->addFile($path . '/compatibility_test.php');
+ $this->addFile($path . '/simpletest_test.php');
+ $this->addFile($path . '/dumper_test.php');
+ $this->addFile($path . '/expectation_test.php');
+ $this->addFile($path . '/unit_tester_test.php');
+ if (version_compare(phpversion(), '5', '>=')) {
+ $this->addFile($path . '/reflection_php5_test.php');
+ } else {
+ $this->addFile($path . '/reflection_php4_test.php');
+ }
+ $this->addFile($path . '/mock_objects_test.php');
+ if (version_compare(phpversion(), '5', '>=')) {
+ $this->addFile($path . '/interfaces_test.php');
+ }
+ $this->addFile($path . '/collector_test.php');
+ $this->addFile($path . '/adapter_test.php');
+ $this->addFile($path . '/socket_test.php');
+ $this->addFile($path . '/encoding_test.php');
+ $this->addFile($path . '/url_test.php');
+ $this->addFile($path . '/cookies_test.php');
+ $this->addFile($path . '/http_test.php');
+ $this->addFile($path . '/authentication_test.php');
+ $this->addFile($path . '/user_agent_test.php');
+ $this->addFile($path . '/parser_test.php');
+ $this->addFile($path . '/tag_test.php');
+ $this->addFile($path . '/form_test.php');
+ $this->addFile($path . '/page_test.php');
+ $this->addFile($path . '/frames_test.php');
+ $this->addFile($path . '/browser_test.php');
+ $this->addFile($path . '/web_tester_test.php');
+ $this->addFile($path . '/shell_tester_test.php');
+ $this->addFile($path . '/xml_test.php');
+ $this->addFile($path . '/../extensions/testdox/test.php');
+ }
+}
+?>
diff --git a/site/vendors/simpletest/test/url_test.php b/site/vendors/simpletest/test/url_test.php
new file mode 100644
index 0000000..5507170
--- /dev/null
+++ b/site/vendors/simpletest/test/url_test.php
@@ -0,0 +1,443 @@
+<?php
+// $Id: url_test.php 1598 2007-12-24 10:44:09Z pp11 $
+require_once(dirname(__FILE__) . '/../autorun.php');
+require_once(dirname(__FILE__) . '/../url.php');
+
+class TestOfUrl extends UnitTestCase {
+
+ function testDefaultUrl() {
+ $url = new SimpleUrl('');
+ $this->assertEqual($url->getScheme(), '');
+ $this->assertEqual($url->getHost(), '');
+ $this->assertEqual($url->getScheme('http'), 'http');
+ $this->assertEqual($url->getHost('localhost'), 'localhost');
+ $this->assertEqual($url->getPath(), '');
+ }
+
+ function testBasicParsing() {
+ $url = new SimpleUrl('https://www.lastcraft.com/test/');
+ $this->assertEqual($url->getScheme(), 'https');
+ $this->assertEqual($url->getHost(), 'www.lastcraft.com');
+ $this->assertEqual($url->getPath(), '/test/');
+ }
+
+ function testRelativeUrls() {
+ $url = new SimpleUrl('../somewhere.php');
+ $this->assertEqual($url->getScheme(), false);
+ $this->assertEqual($url->getHost(), false);
+ $this->assertEqual($url->getPath(), '../somewhere.php');
+ }
+
+ function testParseBareParameter() {
+ $url = new SimpleUrl('?a');
+ $this->assertEqual($url->getPath(), '');
+ $this->assertEqual($url->getEncodedRequest(), '?a');
+ $url->addRequestParameter('x', 'X');
+ $this->assertEqual($url->getEncodedRequest(), '?a=&x=X');
+ }
+
+ function testParseEmptyParameter() {
+ $url = new SimpleUrl('?a=');
+ $this->assertEqual($url->getPath(), '');
+ $this->assertEqual($url->getEncodedRequest(), '?a=');
+ $url->addRequestParameter('x', 'X');
+ $this->assertEqual($url->getEncodedRequest(), '?a=&x=X');
+ }
+
+ function testParseParameterPair() {
+ $url = new SimpleUrl('?a=A');
+ $this->assertEqual($url->getPath(), '');
+ $this->assertEqual($url->getEncodedRequest(), '?a=A');
+ $url->addRequestParameter('x', 'X');
+ $this->assertEqual($url->getEncodedRequest(), '?a=A&x=X');
+ }
+
+ function testParseMultipleParameters() {
+ $url = new SimpleUrl('?a=A&b=B');
+ $this->assertEqual($url->getEncodedRequest(), '?a=A&b=B');
+ $url->addRequestParameter('x', 'X');
+ $this->assertEqual($url->getEncodedRequest(), '?a=A&b=B&x=X');
+ }
+
+ function testParsingParameterMixture() {
+ $url = new SimpleUrl('?a=A&b=&c');
+ $this->assertEqual($url->getEncodedRequest(), '?a=A&b=&c');
+ $url->addRequestParameter('x', 'X');
+ $this->assertEqual($url->getEncodedRequest(), '?a=A&b=&c=&x=X');
+ }
+
+ function testAddParametersFromScratch() {
+ $url = new SimpleUrl('');
+ $url->addRequestParameter('a', 'A');
+ $this->assertEqual($url->getEncodedRequest(), '?a=A');
+ $url->addRequestParameter('b', 'B');
+ $this->assertEqual($url->getEncodedRequest(), '?a=A&b=B');
+ $url->addRequestParameter('a', 'aaa');
+ $this->assertEqual($url->getEncodedRequest(), '?a=A&b=B&a=aaa');
+ }
+
+ function testClearingParameters() {
+ $url = new SimpleUrl('');
+ $url->addRequestParameter('a', 'A');
+ $url->clearRequest();
+ $this->assertIdentical($url->getEncodedRequest(), '');
+ }
+
+ function testEncodingParameters() {
+ $url = new SimpleUrl('');
+ $url->addRequestParameter('a', '?!"\'#~@[]{}:;<>,./|£$%^&*()_+-=');
+ $this->assertIdentical(
+ $request = $url->getEncodedRequest(),
+ '?a=%3F%21%22%27%23%7E%40%5B%5D%7B%7D%3A%3B%3C%3E%2C.%2F%7C%A3%24%25%5E%26%2A%28%29_%2B-%3D');
+ }
+
+ function testDecodingParameters() {
+ $url = new SimpleUrl('?a=%3F%21%22%27%23%7E%40%5B%5D%7B%7D%3A%3B%3C%3E%2C.%2F%7C%A3%24%25%5E%26%2A%28%29_%2B-%3D');
+ $this->assertEqual(
+ $url->getEncodedRequest(),
+ '?a=' . urlencode('?!"\'#~@[]{}:;<>,./|£$%^&*()_+-='));
+ }
+
+ function testUrlInQueryDoesNotConfuseParsing() {
+ $url = new SimpleUrl('wibble/login.php?url=http://www.google.com/moo/');
+ $this->assertFalse($url->getScheme());
+ $this->assertFalse($url->getHost());
+ $this->assertEqual($url->getPath(), 'wibble/login.php');
+ $this->assertEqual($url->getEncodedRequest(), '?url=http://www.google.com/moo/');
+ }
+
+ function testSettingCordinates() {
+ $url = new SimpleUrl('');
+ $url->setCoordinates('32', '45');
+ $this->assertIdentical($url->getX(), 32);
+ $this->assertIdentical($url->getY(), 45);
+ $this->assertEqual($url->getEncodedRequest(), '');
+ }
+
+ function testParseCordinates() {
+ $url = new SimpleUrl('?32,45');
+ $this->assertIdentical($url->getX(), 32);
+ $this->assertIdentical($url->getY(), 45);
+ }
+
+ function testClearingCordinates() {
+ $url = new SimpleUrl('?32,45');
+ $url->setCoordinates();
+ $this->assertIdentical($url->getX(), false);
+ $this->assertIdentical($url->getY(), false);
+ }
+
+ function testParsingParameterCordinateMixture() {
+ $url = new SimpleUrl('?a=A&b=&c?32,45');
+ $this->assertIdentical($url->getX(), 32);
+ $this->assertIdentical($url->getY(), 45);
+ $this->assertEqual($url->getEncodedRequest(), '?a=A&b=&c');
+ }
+
+ function testParsingParameterWithBadCordinates() {
+ $url = new SimpleUrl('?a=A&b=&c?32');
+ $this->assertIdentical($url->getX(), false);
+ $this->assertIdentical($url->getY(), false);
+ $this->assertEqual($url->getEncodedRequest(), '?a=A&b=&c?32');
+ }
+
+ function testPageSplitting() {
+ $url = new SimpleUrl('./here/../there/somewhere.php');
+ $this->assertEqual($url->getPath(), './here/../there/somewhere.php');
+ $this->assertEqual($url->getPage(), 'somewhere.php');
+ $this->assertEqual($url->getBasePath(), './here/../there/');
+ }
+
+ function testAbsolutePathPageSplitting() {
+ $url = new SimpleUrl("http://host.com/here/there/somewhere.php");
+ $this->assertEqual($url->getPath(), "/here/there/somewhere.php");
+ $this->assertEqual($url->getPage(), "somewhere.php");
+ $this->assertEqual($url->getBasePath(), "/here/there/");
+ }
+
+ function testSplittingUrlWithNoPageGivesEmptyPage() {
+ $url = new SimpleUrl('/here/there/');
+ $this->assertEqual($url->getPath(), '/here/there/');
+ $this->assertEqual($url->getPage(), '');
+ $this->assertEqual($url->getBasePath(), '/here/there/');
+ }
+
+ function testPathNormalisation() {
+ $this->assertEqual(
+ SimpleUrl::normalisePath('https://host.com/I/am/here/../there/somewhere.php'),
+ 'https://host.com/I/am/there/somewhere.php');
+ }
+
+ // regression test for #1535407
+ function testPathNormalisationWithSinglePeriod() {
+ $this->assertEqual(
+ SimpleUrl::normalisePath('https://host.com/I/am/here/./../there/somewhere.php'),
+ 'https://host.com/I/am/there/somewhere.php');
+ }
+
+ // regression test for #1852413
+ function testHostnameExtractedFromUContainingAtSign() {
+ $url = new SimpleUrl("http://localhost/name@example.com");
+ $this->assertEqual($url->getScheme(), "http");
+ $this->assertEqual($url->getUsername(), "");
+ $this->assertEqual($url->getPassword(), "");
+ $this->assertEqual($url->getHost(), "localhost");
+ $this->assertEqual($url->getPath(), "/name@example.com");
+ }
+
+ function testHostnameInLocalhost() {
+ $url = new SimpleUrl("http://localhost/name/example.com");
+ $this->assertEqual($url->getScheme(), "http");
+ $this->assertEqual($url->getUsername(), "");
+ $this->assertEqual($url->getPassword(), "");
+ $this->assertEqual($url->getHost(), "localhost");
+ $this->assertEqual($url->getPath(), "/name/example.com");
+ }
+
+ function testUsernameAndPasswordAreUrlDecoded() {
+ $url = new SimpleUrl('http://' . urlencode('test@test') .
+ ':' . urlencode('$!£@*&%') . '@www.lastcraft.com');
+ $this->assertEqual($url->getUsername(), 'test@test');
+ $this->assertEqual($url->getPassword(), '$!£@*&%');
+ }
+
+ function testBlitz() {
+ $this->assertUrl(
+ "https://username:password@www.somewhere.com:243/this/that/here.php?a=1&b=2#anchor",
+ array("https", "username", "password", "www.somewhere.com", 243, "/this/that/here.php", "com", "?a=1&b=2", "anchor"),
+ array("a" => "1", "b" => "2"));
+ $this->assertUrl(
+ "username:password@www.somewhere.com/this/that/here.php?a=1",
+ array(false, "username", "password", "www.somewhere.com", false, "/this/that/here.php", "com", "?a=1", false),
+ array("a" => "1"));
+ $this->assertUrl(
+ "username:password@somewhere.com:243?1,2",
+ array(false, "username", "password", "somewhere.com", 243, "/", "com", "", false),
+ array(),
+ array(1, 2));
+ $this->assertUrl(
+ "https://www.somewhere.com",
+ array("https", false, false, "www.somewhere.com", false, "/", "com", "", false));
+ $this->assertUrl(
+ "username@www.somewhere.com:243#anchor",
+ array(false, "username", false, "www.somewhere.com", 243, "/", "com", "", "anchor"));
+ $this->assertUrl(
+ "/this/that/here.php?a=1&b=2?3,4",
+ array(false, false, false, false, false, "/this/that/here.php", false, "?a=1&b=2", false),
+ array("a" => "1", "b" => "2"),
+ array(3, 4));
+ $this->assertUrl(
+ "username@/here.php?a=1&b=2",
+ array(false, "username", false, false, false, "/here.php", false, "?a=1&b=2", false),
+ array("a" => "1", "b" => "2"));
+ }
+
+ function testAmbiguousHosts() {
+ $this->assertUrl(
+ "tigger",
+ array(false, false, false, false, false, "tigger", false, "", false));
+ $this->assertUrl(
+ "/tigger",
+ array(false, false, false, false, false, "/tigger", false, "", false));
+ $this->assertUrl(
+ "//tigger",
+ array(false, false, false, "tigger", false, "/", false, "", false));
+ $this->assertUrl(
+ "//tigger/",
+ array(false, false, false, "tigger", false, "/", false, "", false));
+ $this->assertUrl(
+ "tigger.com",
+ array(false, false, false, "tigger.com", false, "/", "com", "", false));
+ $this->assertUrl(
+ "me.net/tigger",
+ array(false, false, false, "me.net", false, "/tigger", "net", "", false));
+ }
+
+ function testAsString() {
+ $this->assertPreserved('https://www.here.com');
+ $this->assertPreserved('http://me:secret@www.here.com');
+ $this->assertPreserved('http://here/there');
+ $this->assertPreserved('http://here/there?a=A&b=B');
+ $this->assertPreserved('http://here/there?a=1&a=2');
+ $this->assertPreserved('http://here/there?a=1&a=2?9,8');
+ $this->assertPreserved('http://host?a=1&a=2');
+ $this->assertPreserved('http://host#stuff');
+ $this->assertPreserved('http://me:secret@www.here.com/a/b/c/here.html?a=A?7,6');
+ $this->assertPreserved('http://www.here.com/?a=A__b=B');
+ }
+
+ function assertUrl($raw, $parts, $params = false, $coords = false) {
+ if (! is_array($params)) {
+ $params = array();
+ }
+ $url = new SimpleUrl($raw);
+ $this->assertIdentical($url->getScheme(), $parts[0], "[$raw] scheme -> %s");
+ $this->assertIdentical($url->getUsername(), $parts[1], "[$raw] username -> %s");
+ $this->assertIdentical($url->getPassword(), $parts[2], "[$raw] password -> %s");
+ $this->assertIdentical($url->getHost(), $parts[3], "[$raw] host -> %s");
+ $this->assertIdentical($url->getPort(), $parts[4], "[$raw] port -> %s");
+ $this->assertIdentical($url->getPath(), $parts[5], "[$raw] path -> %s");
+ $this->assertIdentical($url->getTld(), $parts[6], "[$raw] tld -> %s");
+ $this->assertIdentical($url->getEncodedRequest(), $parts[7], "[$raw] encoded -> %s");
+ $this->assertIdentical($url->getFragment(), $parts[8], "[$raw] fragment -> %s");
+ if ($coords) {
+ $this->assertIdentical($url->getX(), $coords[0], "[$raw] x -> %s");
+ $this->assertIdentical($url->getY(), $coords[1], "[$raw] y -> %s");
+ }
+ }
+
+ function testUrlWithTwoSlashesInPath() {
+ $url = new SimpleUrl('/article/categoryedit/insert//');
+ $this->assertEqual($url->getPath(), '/article/categoryedit/insert//');
+ }
+
+ function assertPreserved($string) {
+ $url = new SimpleUrl($string);
+ $this->assertEqual($url->asString(), $string);
+ }
+}
+
+class TestOfAbsoluteUrls extends UnitTestCase {
+
+ function testDirectoriesAfterFilename() {
+ $string = '../../index.php/foo/bar';
+ $url = new SimpleUrl($string);
+ $this->assertEqual($url->asString(), $string);
+
+ $absolute = $url->makeAbsolute('http://www.domain.com/some/path/');
+ $this->assertEqual($absolute->asString(), 'http://www.domain.com/index.php/foo/bar');
+ }
+
+ function testMakingAbsolute() {
+ $url = new SimpleUrl('../there/somewhere.php');
+ $this->assertEqual($url->getPath(), '../there/somewhere.php');
+ $absolute = $url->makeAbsolute('https://host.com:1234/I/am/here/');
+ $this->assertEqual($absolute->getScheme(), 'https');
+ $this->assertEqual($absolute->getHost(), 'host.com');
+ $this->assertEqual($absolute->getPort(), 1234);
+ $this->assertEqual($absolute->getPath(), '/I/am/there/somewhere.php');
+ }
+
+ function testMakingAnEmptyUrlAbsolute() {
+ $url = new SimpleUrl('');
+ $this->assertEqual($url->getPath(), '');
+ $absolute = $url->makeAbsolute('http://host.com/I/am/here/page.html');
+ $this->assertEqual($absolute->getScheme(), 'http');
+ $this->assertEqual($absolute->getHost(), 'host.com');
+ $this->assertEqual($absolute->getPath(), '/I/am/here/page.html');
+ }
+
+ function testMakingAnEmptyUrlAbsoluteWithMissingPageName() {
+ $url = new SimpleUrl('');
+ $this->assertEqual($url->getPath(), '');
+ $absolute = $url->makeAbsolute('http://host.com/I/am/here/');
+ $this->assertEqual($absolute->getScheme(), 'http');
+ $this->assertEqual($absolute->getHost(), 'host.com');
+ $this->assertEqual($absolute->getPath(), '/I/am/here/');
+ }
+
+ function testMakingAShortQueryUrlAbsolute() {
+ $url = new SimpleUrl('?a#b');
+ $this->assertEqual($url->getPath(), '');
+ $absolute = $url->makeAbsolute('http://host.com/I/am/here/');
+ $this->assertEqual($absolute->getScheme(), 'http');
+ $this->assertEqual($absolute->getHost(), 'host.com');
+ $this->assertEqual($absolute->getPath(), '/I/am/here/');
+ $this->assertEqual($absolute->getEncodedRequest(), '?a');
+ $this->assertEqual($absolute->getFragment(), 'b');
+ }
+
+ function testMakingADirectoryUrlAbsolute() {
+ $url = new SimpleUrl('hello/');
+ $this->assertEqual($url->getPath(), 'hello/');
+ $this->assertEqual($url->getBasePath(), 'hello/');
+ $this->assertEqual($url->getPage(), '');
+ $absolute = $url->makeAbsolute('http://host.com/I/am/here/page.html');
+ $this->assertEqual($absolute->getPath(), '/I/am/here/hello/');
+ }
+
+ function testMakingARootUrlAbsolute() {
+ $url = new SimpleUrl('/');
+ $this->assertEqual($url->getPath(), '/');
+ $absolute = $url->makeAbsolute('http://host.com/I/am/here/page.html');
+ $this->assertEqual($absolute->getPath(), '/');
+ }
+
+ function testMakingARootPageUrlAbsolute() {
+ $url = new SimpleUrl('/here.html');
+ $absolute = $url->makeAbsolute('http://host.com/I/am/here/page.html');
+ $this->assertEqual($absolute->getPath(), '/here.html');
+ }
+
+ function testCarryAuthenticationFromRootPage() {
+ $url = new SimpleUrl('here.html');
+ $absolute = $url->makeAbsolute('http://test:secret@host.com/');
+ $this->assertEqual($absolute->getPath(), '/here.html');
+ $this->assertEqual($absolute->getUsername(), 'test');
+ $this->assertEqual($absolute->getPassword(), 'secret');
+ }
+
+ function testMakingCoordinateUrlAbsolute() {
+ $url = new SimpleUrl('?1,2');
+ $this->assertEqual($url->getPath(), '');
+ $absolute = $url->makeAbsolute('http://host.com/I/am/here/');
+ $this->assertEqual($absolute->getScheme(), 'http');
+ $this->assertEqual($absolute->getHost(), 'host.com');
+ $this->assertEqual($absolute->getPath(), '/I/am/here/');
+ $this->assertEqual($absolute->getX(), 1);
+ $this->assertEqual($absolute->getY(), 2);
+ }
+
+ function testMakingAbsoluteAppendedPath() {
+ $url = new SimpleUrl('./there/somewhere.php');
+ $absolute = $url->makeAbsolute('https://host.com/here/');
+ $this->assertEqual($absolute->getPath(), '/here/there/somewhere.php');
+ }
+
+ function testMakingAbsoluteBadlyFormedAppendedPath() {
+ $url = new SimpleUrl('there/somewhere.php');
+ $absolute = $url->makeAbsolute('https://host.com/here/');
+ $this->assertEqual($absolute->getPath(), '/here/there/somewhere.php');
+ }
+
+ function testMakingAbsoluteHasNoEffectWhenAlreadyAbsolute() {
+ $url = new SimpleUrl('https://test:secret@www.lastcraft.com:321/stuff/?a=1#f');
+ $absolute = $url->makeAbsolute('http://host.com/here/');
+ $this->assertEqual($absolute->getScheme(), 'https');
+ $this->assertEqual($absolute->getUsername(), 'test');
+ $this->assertEqual($absolute->getPassword(), 'secret');
+ $this->assertEqual($absolute->getHost(), 'www.lastcraft.com');
+ $this->assertEqual($absolute->getPort(), 321);
+ $this->assertEqual($absolute->getPath(), '/stuff/');
+ $this->assertEqual($absolute->getEncodedRequest(), '?a=1');
+ $this->assertEqual($absolute->getFragment(), 'f');
+ }
+
+ function testMakingAbsoluteCarriesAuthenticationWhenAlreadyAbsolute() {
+ $url = new SimpleUrl('https://www.lastcraft.com');
+ $absolute = $url->makeAbsolute('http://test:secret@host.com/here/');
+ $this->assertEqual($absolute->getHost(), 'www.lastcraft.com');
+ $this->assertEqual($absolute->getUsername(), 'test');
+ $this->assertEqual($absolute->getPassword(), 'secret');
+ }
+
+ function testMakingHostOnlyAbsoluteDoesNotCarryAnyOtherInformation() {
+ $url = new SimpleUrl('http://www.lastcraft.com');
+ $absolute = $url->makeAbsolute('https://host.com:81/here/');
+ $this->assertEqual($absolute->getScheme(), 'http');
+ $this->assertEqual($absolute->getHost(), 'www.lastcraft.com');
+ $this->assertIdentical($absolute->getPort(), false);
+ $this->assertEqual($absolute->getPath(), '/');
+ }
+}
+
+class TestOfFrameUrl extends UnitTestCase {
+
+ function testTargetAttachment() {
+ $url = new SimpleUrl('http://www.site.com/home.html');
+ $this->assertIdentical($url->getTarget(), false);
+ $url->setTarget('A frame');
+ $this->assertIdentical($url->getTarget(), 'A frame');
+ }
+}
+?> \ No newline at end of file
diff --git a/site/vendors/simpletest/test/user_agent_test.php b/site/vendors/simpletest/test/user_agent_test.php
new file mode 100644
index 0000000..657c7e1
--- /dev/null
+++ b/site/vendors/simpletest/test/user_agent_test.php
@@ -0,0 +1,358 @@
+<?php
+// $Id: user_agent_test.php 1509 2007-05-08 22:11:49Z lastcraft $
+require_once(dirname(__FILE__) . '/../autorun.php');
+require_once(dirname(__FILE__) . '/../user_agent.php');
+require_once(dirname(__FILE__) . '/../authentication.php');
+require_once(dirname(__FILE__) . '/../http.php');
+require_once(dirname(__FILE__) . '/../encoding.php');
+Mock::generate('SimpleHttpRequest');
+Mock::generate('SimpleHttpResponse');
+Mock::generate('SimpleHttpHeaders');
+Mock::generatePartial('SimpleUserAgent', 'MockRequestUserAgent', array('_createHttpRequest'));
+
+class TestOfFetchingUrlParameters extends UnitTestCase {
+
+ function setUp() {
+ $this->_headers = &new MockSimpleHttpHeaders();
+
+ $this->_response = &new MockSimpleHttpResponse();
+ $this->_response->setReturnValue('isError', false);
+ $this->_response->setReturnReference('getHeaders', new MockSimpleHttpHeaders());
+
+ $this->_request = &new MockSimpleHttpRequest();
+ $this->_request->setReturnReference('fetch', $this->_response);
+ }
+
+ function testGetRequestWithoutIncidentGivesNoErrors() {
+ $url = new SimpleUrl('http://test:secret@this.com/page.html');
+ $url->addRequestParameters(array('a' => 'A', 'b' => 'B'));
+
+ $agent = &new MockRequestUserAgent();
+ $agent->setReturnReference('_createHttpRequest', $this->_request);
+ $agent->SimpleUserAgent();
+
+ $response = &$agent->fetchResponse(
+ new SimpleUrl('http://test:secret@this.com/page.html'),
+ new SimpleGetEncoding(array('a' => 'A', 'b' => 'B')));
+ $this->assertFalse($response->isError());
+ }
+}
+
+class TestOfAdditionalHeaders extends UnitTestCase {
+
+ function testAdditionalHeaderAddedToRequest() {
+ $response = &new MockSimpleHttpResponse();
+ $response->setReturnReference('getHeaders', new MockSimpleHttpHeaders());
+
+ $request = &new MockSimpleHttpRequest();
+ $request->setReturnReference('fetch', $response);
+ $request->expectOnce(
+ 'addHeaderLine',
+ array('User-Agent: SimpleTest'));
+
+ $agent = &new MockRequestUserAgent();
+ $agent->setReturnReference('_createHttpRequest', $request);
+ $agent->SimpleUserAgent();
+ $agent->addHeader('User-Agent: SimpleTest');
+ $response = &$agent->fetchResponse(new SimpleUrl('http://this.host/'), new SimpleGetEncoding());
+ }
+}
+
+class TestOfBrowserCookies extends UnitTestCase {
+
+ function &_createStandardResponse() {
+ $response = &new MockSimpleHttpResponse();
+ $response->setReturnValue("isError", false);
+ $response->setReturnValue("getContent", "stuff");
+ $response->setReturnReference("getHeaders", new MockSimpleHttpHeaders());
+ return $response;
+ }
+
+ function &_createCookieSite($header_lines) {
+ $headers = &new SimpleHttpHeaders($header_lines);
+
+ $response = &new MockSimpleHttpResponse();
+ $response->setReturnValue("isError", false);
+ $response->setReturnReference("getHeaders", $headers);
+ $response->setReturnValue("getContent", "stuff");
+
+ $request = &new MockSimpleHttpRequest();
+ $request->setReturnReference("fetch", $response);
+ return $request;
+ }
+
+ function &_createMockedRequestUserAgent(&$request) {
+ $agent = &new MockRequestUserAgent();
+ $agent->setReturnReference('_createHttpRequest', $request);
+ $agent->SimpleUserAgent();
+ return $agent;
+ }
+
+ function testCookieJarIsSentToRequest() {
+ $jar = new SimpleCookieJar();
+ $jar->setCookie('a', 'A');
+
+ $request = &new MockSimpleHttpRequest();
+ $request->setReturnReference('fetch', $this->_createStandardResponse());
+ $request->expectOnce('readCookiesFromJar', array($jar, '*'));
+
+ $agent = &$this->_createMockedRequestUserAgent($request);
+ $agent->setCookie('a', 'A');
+ $agent->fetchResponse(
+ new SimpleUrl('http://this.com/this/path/page.html'),
+ new SimpleGetEncoding());
+ }
+
+ function testNoCookieJarIsSentToRequestWhenCookiesAreDisabled() {
+ $request = &new MockSimpleHttpRequest();
+ $request->setReturnReference('fetch', $this->_createStandardResponse());
+ $request->expectNever('readCookiesFromJar');
+
+ $agent = &$this->_createMockedRequestUserAgent($request);
+ $agent->setCookie('a', 'A');
+ $agent->ignoreCookies();
+ $agent->fetchResponse(
+ new SimpleUrl('http://this.com/this/path/page.html'),
+ new SimpleGetEncoding());
+ }
+
+ function testReadingNewCookie() {
+ $request = &$this->_createCookieSite('Set-cookie: a=AAAA');
+ $agent = &$this->_createMockedRequestUserAgent($request);
+ $agent->fetchResponse(
+ new SimpleUrl('http://this.com/this/path/page.html'),
+ new SimpleGetEncoding());
+ $this->assertEqual($agent->getCookieValue("this.com", "this/path/", "a"), "AAAA");
+ }
+
+ function testIgnoringNewCookieWhenCookiesDisabled() {
+ $request = &$this->_createCookieSite('Set-cookie: a=AAAA');
+ $agent = &$this->_createMockedRequestUserAgent($request);
+ $agent->ignoreCookies();
+ $agent->fetchResponse(
+ new SimpleUrl('http://this.com/this/path/page.html'),
+ new SimpleGetEncoding());
+ $this->assertIdentical($agent->getCookieValue("this.com", "this/path/", "a"), false);
+ }
+
+ function testOverwriteCookieThatAlreadyExists() {
+ $request = &$this->_createCookieSite('Set-cookie: a=AAAA');
+ $agent = &$this->_createMockedRequestUserAgent($request);
+ $agent->setCookie('a', 'A');
+ $agent->fetchResponse(
+ new SimpleUrl('http://this.com/this/path/page.html'),
+ new SimpleGetEncoding());
+ $this->assertEqual($agent->getCookieValue("this.com", "this/path/", "a"), "AAAA");
+ }
+
+ function testClearCookieBySettingExpiry() {
+ $request = &$this->_createCookieSite('Set-cookie: a=b');
+ $agent = &$this->_createMockedRequestUserAgent($request);
+
+ $agent->setCookie("a", "A", "this/path/", "Wed, 25-Dec-02 04:24:21 GMT");
+ $agent->fetchResponse(
+ new SimpleUrl('http://this.com/this/path/page.html'),
+ new SimpleGetEncoding());
+ $this->assertIdentical(
+ $agent->getCookieValue("this.com", "this/path/", "a"),
+ "b");
+ $agent->restart("Wed, 25-Dec-02 04:24:20 GMT");
+ $this->assertIdentical(
+ $agent->getCookieValue("this.com", "this/path/", "a"),
+ false);
+ }
+
+ function testAgeingAndClearing() {
+ $request = &$this->_createCookieSite('Set-cookie: a=A; expires=Wed, 25-Dec-02 04:24:21 GMT; path=/this/path');
+ $agent = &$this->_createMockedRequestUserAgent($request);
+
+ $agent->fetchResponse(
+ new SimpleUrl('http://this.com/this/path/page.html'),
+ new SimpleGetEncoding());
+ $agent->restart("Wed, 25-Dec-02 04:24:20 GMT");
+ $this->assertIdentical(
+ $agent->getCookieValue("this.com", "this/path/", "a"),
+ "A");
+ $agent->ageCookies(2);
+ $agent->restart("Wed, 25-Dec-02 04:24:20 GMT");
+ $this->assertIdentical(
+ $agent->getCookieValue("this.com", "this/path/", "a"),
+ false);
+ }
+
+ function testReadingIncomingAndSettingNewCookies() {
+ $request = &$this->_createCookieSite('Set-cookie: a=AAA');
+ $agent = &$this->_createMockedRequestUserAgent($request);
+
+ $this->assertNull($agent->getBaseCookieValue("a", false));
+ $agent->fetchResponse(
+ new SimpleUrl('http://this.com/this/path/page.html'),
+ new SimpleGetEncoding());
+ $agent->setCookie("b", "BBB", "this.com", "this/path/");
+ $this->assertEqual(
+ $agent->getBaseCookieValue("a", new SimpleUrl('http://this.com/this/path/page.html')),
+ "AAA");
+ $this->assertEqual(
+ $agent->getBaseCookieValue("b", new SimpleUrl('http://this.com/this/path/page.html')),
+ "BBB");
+ }
+}
+
+class TestOfHttpRedirects extends UnitTestCase {
+
+ function &createRedirect($content, $redirect) {
+ $headers = &new MockSimpleHttpHeaders();
+ $headers->setReturnValue('isRedirect', (boolean)$redirect);
+ $headers->setReturnValue('getLocation', $redirect);
+
+ $response = &new MockSimpleHttpResponse();
+ $response->setReturnValue('getContent', $content);
+ $response->setReturnReference('getHeaders', $headers);
+
+ $request = &new MockSimpleHttpRequest();
+ $request->setReturnReference('fetch', $response);
+ return $request;
+ }
+
+ function testDisabledRedirects() {
+ $agent = &new MockRequestUserAgent();
+ $agent->setReturnReference(
+ '_createHttpRequest',
+ $this->createRedirect('stuff', 'there.html'));
+ $agent->expectOnce('_createHttpRequest');
+ $agent->SimpleUserAgent();
+
+ $agent->setMaximumRedirects(0);
+ $response = &$agent->fetchResponse(new SimpleUrl('here.html'), new SimpleGetEncoding());
+ $this->assertEqual($response->getContent(), 'stuff');
+ }
+
+ function testSingleRedirect() {
+ $agent = &new MockRequestUserAgent();
+ $agent->setReturnReferenceAt(
+ 0,
+ '_createHttpRequest',
+ $this->createRedirect('first', 'two.html'));
+ $agent->setReturnReferenceAt(
+ 1,
+ '_createHttpRequest',
+ $this->createRedirect('second', 'three.html'));
+ $agent->expectCallCount('_createHttpRequest', 2);
+ $agent->SimpleUserAgent();
+
+ $agent->setMaximumRedirects(1);
+ $response = &$agent->fetchResponse(new SimpleUrl('one.html'), new SimpleGetEncoding());
+ $this->assertEqual($response->getContent(), 'second');
+ }
+
+ function testDoubleRedirect() {
+ $agent = &new MockRequestUserAgent();
+ $agent->setReturnReferenceAt(
+ 0,
+ '_createHttpRequest',
+ $this->createRedirect('first', 'two.html'));
+ $agent->setReturnReferenceAt(
+ 1,
+ '_createHttpRequest',
+ $this->createRedirect('second', 'three.html'));
+ $agent->setReturnReferenceAt(
+ 2,
+ '_createHttpRequest',
+ $this->createRedirect('third', 'four.html'));
+ $agent->expectCallCount('_createHttpRequest', 3);
+ $agent->SimpleUserAgent();
+
+ $agent->setMaximumRedirects(2);
+ $response = &$agent->fetchResponse(new SimpleUrl('one.html'), new SimpleGetEncoding());
+ $this->assertEqual($response->getContent(), 'third');
+ }
+
+ function testSuccessAfterRedirect() {
+ $agent = &new MockRequestUserAgent();
+ $agent->setReturnReferenceAt(
+ 0,
+ '_createHttpRequest',
+ $this->createRedirect('first', 'two.html'));
+ $agent->setReturnReferenceAt(
+ 1,
+ '_createHttpRequest',
+ $this->createRedirect('second', false));
+ $agent->setReturnReferenceAt(
+ 2,
+ '_createHttpRequest',
+ $this->createRedirect('third', 'four.html'));
+ $agent->expectCallCount('_createHttpRequest', 2);
+ $agent->SimpleUserAgent();
+
+ $agent->setMaximumRedirects(2);
+ $response = &$agent->fetchResponse(new SimpleUrl('one.html'), new SimpleGetEncoding());
+ $this->assertEqual($response->getContent(), 'second');
+ }
+
+ function testRedirectChangesPostToGet() {
+ $agent = &new MockRequestUserAgent();
+ $agent->setReturnReferenceAt(
+ 0,
+ '_createHttpRequest',
+ $this->createRedirect('first', 'two.html'));
+ $agent->expectArgumentsAt(0, '_createHttpRequest', array('*', new IsAExpectation('SimplePostEncoding')));
+ $agent->setReturnReferenceAt(
+ 1,
+ '_createHttpRequest',
+ $this->createRedirect('second', 'three.html'));
+ $agent->expectArgumentsAt(1, '_createHttpRequest', array('*', new IsAExpectation('SimpleGetEncoding')));
+ $agent->expectCallCount('_createHttpRequest', 2);
+ $agent->SimpleUserAgent();
+ $agent->setMaximumRedirects(1);
+ $response = &$agent->fetchResponse(new SimpleUrl('one.html'), new SimplePostEncoding());
+ }
+}
+
+class TestOfBadHosts extends UnitTestCase {
+
+ function &_createSimulatedBadHost() {
+ $response = &new MockSimpleHttpResponse();
+ $response->setReturnValue('isError', true);
+ $response->setReturnValue('getError', 'Bad socket');
+ $response->setReturnValue('getContent', false);
+
+ $request = &new MockSimpleHttpRequest();
+ $request->setReturnReference('fetch', $response);
+ return $request;
+ }
+
+ function testUntestedHost() {
+ $request = &$this->_createSimulatedBadHost();
+
+ $agent = &new MockRequestUserAgent();
+ $agent->setReturnReference('_createHttpRequest', $request);
+ $agent->SimpleUserAgent();
+
+ $response = &$agent->fetchResponse(
+ new SimpleUrl('http://this.host/this/path/page.html'),
+ new SimpleGetEncoding());
+ $this->assertTrue($response->isError());
+ }
+}
+
+class TestOfAuthorisation extends UnitTestCase {
+
+ function testAuthenticateHeaderAdded() {
+ $response = &new MockSimpleHttpResponse();
+ $response->setReturnReference('getHeaders', new MockSimpleHttpHeaders());
+
+ $request = &new MockSimpleHttpRequest();
+ $request->setReturnReference('fetch', $response);
+ $request->expectOnce(
+ 'addHeaderLine',
+ array('Authorization: Basic ' . base64_encode('test:secret')));
+
+ $agent = &new MockRequestUserAgent();
+ $agent->setReturnReference('_createHttpRequest', $request);
+ $agent->SimpleUserAgent();
+ $response = &$agent->fetchResponse(
+ new SimpleUrl('http://test:secret@this.host'),
+ new SimpleGetEncoding());
+ }
+}
+?> \ No newline at end of file
diff --git a/site/vendors/simpletest/test/visual_test.php b/site/vendors/simpletest/test/visual_test.php
new file mode 100644
index 0000000..13781bb
--- /dev/null
+++ b/site/vendors/simpletest/test/visual_test.php
@@ -0,0 +1,495 @@
+<?php
+ // $Id: visual_test.php 1547 2007-07-04 00:42:05Z lastcraft $
+
+ // NOTE:
+ // Some of these tests are designed to fail! Do not be alarmed.
+ // ----------------
+
+ // The following tests are a bit hacky. Whilst Kent Beck tried to
+ // build a unit tester with a unit tester, I am not that brave.
+ // Instead I have just hacked together odd test scripts until
+ // I have enough of a tester to procede more formally.
+ //
+ // The proper tests start in all_tests.php
+ require_once('../unit_tester.php');
+ require_once('../shell_tester.php');
+ require_once('../mock_objects.php');
+ require_once('../reporter.php');
+ require_once('../xml.php');
+
+ class TestDisplayClass {
+ var $_a;
+
+ function TestDisplayClass($a) {
+ $this->_a = $a;
+ }
+ }
+
+ class PassingUnitTestCaseOutput extends UnitTestCase {
+
+ function testOfResults() {
+ $this->pass('Pass');
+ }
+
+ function testTrue() {
+ $this->assertTrue(true);
+ }
+
+ function testFalse() {
+ $this->assertFalse(false);
+ }
+
+ function testExpectation() {
+ $expectation = &new EqualExpectation(25, 'My expectation message: %s');
+ $this->assert($expectation, 25, 'My assert message : %s');
+ }
+
+ function testNull() {
+ $this->assertNull(null, "%s -> Pass");
+ $this->assertNotNull(false, "%s -> Pass");
+ }
+
+ function testType() {
+ $this->assertIsA("hello", "string", "%s -> Pass");
+ $this->assertIsA($this, "PassingUnitTestCaseOutput", "%s -> Pass");
+ $this->assertIsA($this, "UnitTestCase", "%s -> Pass");
+ }
+
+ function testTypeEquality() {
+ $this->assertEqual("0", 0, "%s -> Pass");
+ }
+
+ function testNullEquality() {
+ $this->assertNotEqual(null, 1, "%s -> Pass");
+ $this->assertNotEqual(1, null, "%s -> Pass");
+ }
+
+ function testIntegerEquality() {
+ $this->assertNotEqual(1, 2, "%s -> Pass");
+ }
+
+ function testStringEquality() {
+ $this->assertEqual("a", "a", "%s -> Pass");
+ $this->assertNotEqual("aa", "ab", "%s -> Pass");
+ }
+
+ function testHashEquality() {
+ $this->assertEqual(array("a" => "A", "b" => "B"), array("b" => "B", "a" => "A"), "%s -> Pass");
+ }
+
+ function testWithin() {
+ $this->assertWithinMargin(5, 5.4, 0.5, "%s -> Pass");
+ }
+
+ function testOutside() {
+ $this->assertOutsideMargin(5, 5.6, 0.5, "%s -> Pass");
+ }
+
+ function testStringIdentity() {
+ $a = "fred";
+ $b = $a;
+ $this->assertIdentical($a, $b, "%s -> Pass");
+ }
+
+ function testTypeIdentity() {
+ $a = "0";
+ $b = 0;
+ $this->assertNotIdentical($a, $b, "%s -> Pass");
+ }
+
+ function testNullIdentity() {
+ $this->assertNotIdentical(null, 1, "%s -> Pass");
+ $this->assertNotIdentical(1, null, "%s -> Pass");
+ }
+
+ function testHashIdentity() {
+ }
+
+ function testObjectEquality() {
+ $this->assertEqual(new TestDisplayClass(4), new TestDisplayClass(4), "%s -> Pass");
+ $this->assertNotEqual(new TestDisplayClass(4), new TestDisplayClass(5), "%s -> Pass");
+ }
+
+ function testObjectIndentity() {
+ $this->assertIdentical(new TestDisplayClass(false), new TestDisplayClass(false), "%s -> Pass");
+ $this->assertNotIdentical(new TestDisplayClass(false), new TestDisplayClass(0), "%s -> Pass");
+ }
+
+ function testReference() {
+ $a = "fred";
+ $b = &$a;
+ $this->assertReference($a, $b, "%s -> Pass");
+ }
+
+ function testCloneOnDifferentObjects() {
+ $a = "fred";
+ $b = $a;
+ $c = "Hello";
+ $this->assertClone($a, $b, "%s -> Pass");
+ }
+
+ function testPatterns() {
+ $this->assertPattern('/hello/i', "Hello there", "%s -> Pass");
+ $this->assertNoPattern('/hello/', "Hello there", "%s -> Pass");
+ }
+
+ function testLongStrings() {
+ $text = "";
+ for ($i = 0; $i < 10; $i++) {
+ $text .= "0123456789";
+ }
+ $this->assertEqual($text, $text);
+ }
+ }
+
+ class FailingUnitTestCaseOutput extends UnitTestCase {
+
+ function testOfResults() {
+ $this->fail('Fail'); // Fail.
+ }
+
+ function testTrue() {
+ $this->assertTrue(false); // Fail.
+ }
+
+ function testFalse() {
+ $this->assertFalse(true); // Fail.
+ }
+
+ function testExpectation() {
+ $expectation = &new EqualExpectation(25, 'My expectation message: %s');
+ $this->assert($expectation, 24, 'My assert message : %s'); // Fail.
+ }
+
+ function testNull() {
+ $this->assertNull(false, "%s -> Fail"); // Fail.
+ $this->assertNotNull(null, "%s -> Fail"); // Fail.
+ }
+
+ function testType() {
+ $this->assertIsA(14, "string", "%s -> Fail"); // Fail.
+ $this->assertIsA(14, "TestOfUnitTestCaseOutput", "%s -> Fail"); // Fail.
+ $this->assertIsA($this, "TestReporter", "%s -> Fail"); // Fail.
+ }
+
+ function testTypeEquality() {
+ $this->assertNotEqual("0", 0, "%s -> Fail"); // Fail.
+ }
+
+ function testNullEquality() {
+ $this->assertEqual(null, 1, "%s -> Fail"); // Fail.
+ $this->assertEqual(1, null, "%s -> Fail"); // Fail.
+ }
+
+ function testIntegerEquality() {
+ $this->assertEqual(1, 2, "%s -> Fail"); // Fail.
+ }
+
+ function testStringEquality() {
+ $this->assertNotEqual("a", "a", "%s -> Fail"); // Fail.
+ $this->assertEqual("aa", "ab", "%s -> Fail"); // Fail.
+ }
+
+ function testHashEquality() {
+ $this->assertEqual(array("a" => "A", "b" => "B"), array("b" => "B", "a" => "Z"), "%s -> Fail");
+ }
+
+ function testWithin() {
+ $this->assertWithinMargin(5, 5.6, 0.5, "%s -> Fail"); // Fail.
+ }
+
+ function testOutside() {
+ $this->assertOutsideMargin(5, 5.4, 0.5, "%s -> Fail"); // Fail.
+ }
+
+ function testStringIdentity() {
+ $a = "fred";
+ $b = $a;
+ $this->assertNotIdentical($a, $b, "%s -> Fail"); // Fail.
+ }
+
+ function testTypeIdentity() {
+ $a = "0";
+ $b = 0;
+ $this->assertIdentical($a, $b, "%s -> Fail"); // Fail.
+ }
+
+ function testNullIdentity() {
+ $this->assertIdentical(null, 1, "%s -> Fail"); // Fail.
+ $this->assertIdentical(1, null, "%s -> Fail"); // Fail.
+ }
+
+ function testHashIdentity() {
+ $this->assertIdentical(array("a" => "A", "b" => "B"), array("b" => "B", "a" => "A"), "%s -> fail"); // Fail.
+ }
+
+ function testObjectEquality() {
+ $this->assertNotEqual(new TestDisplayClass(4), new TestDisplayClass(4), "%s -> Fail"); // Fail.
+ $this->assertEqual(new TestDisplayClass(4), new TestDisplayClass(5), "%s -> Fail"); // Fail.
+ }
+
+ function testObjectIndentity() {
+ $this->assertNotIdentical(new TestDisplayClass(false), new TestDisplayClass(false), "%s -> Fail"); // Fail.
+ $this->assertIdentical(new TestDisplayClass(false), new TestDisplayClass(0), "%s -> Fail"); // Fail.
+ }
+
+ function testReference() {
+ $a = "fred";
+ $b = &$a;
+ $this->assertClone($a, $b, "%s -> Fail"); // Fail.
+ }
+
+ function testCloneOnDifferentObjects() {
+ $a = "fred";
+ $b = $a;
+ $c = "Hello";
+ $this->assertClone($a, $c, "%s -> Fail"); // Fail.
+ }
+
+ function testPatterns() {
+ $this->assertPattern('/hello/', "Hello there", "%s -> Fail"); // Fail.
+ $this->assertNoPattern('/hello/i', "Hello there", "%s -> Fail"); // Fail.
+ }
+
+ function testLongStrings() {
+ $text = "";
+ for ($i = 0; $i < 10; $i++) {
+ $text .= "0123456789";
+ }
+ $this->assertEqual($text . $text, $text . "a" . $text); // Fail.
+ }
+ }
+
+ class Dummy {
+ function Dummy() {
+ }
+
+ function a() {
+ }
+ }
+ Mock::generate('Dummy');
+
+ class TestOfMockObjectsOutput extends UnitTestCase {
+
+ function testCallCounts() {
+ $dummy = &new MockDummy();
+ $dummy->expectCallCount('a', 1, 'My message: %s');
+ $dummy->a();
+ $dummy->a();
+ }
+
+ function testMinimumCallCounts() {
+ $dummy = &new MockDummy();
+ $dummy->expectMinimumCallCount('a', 2, 'My message: %s');
+ $dummy->a();
+ $dummy->a();
+ }
+
+ function testEmptyMatching() {
+ $dummy = &new MockDummy();
+ $dummy->expectArguments('a', array());
+ $dummy->a();
+ $dummy->a(null); // Fail.
+ }
+
+ function testEmptyMatchingWithCustomMessage() {
+ $dummy = &new MockDummy();
+ $dummy->expectArguments('a', array(), 'My expectation message: %s');
+ $dummy->a();
+ $dummy->a(null); // Fail.
+ }
+
+ function testNullMatching() {
+ $dummy = &new MockDummy();
+ $dummy->expectArguments('a', array(null));
+ $dummy->a(null);
+ $dummy->a(); // Fail.
+ }
+
+ function testBooleanMatching() {
+ $dummy = &new MockDummy();
+ $dummy->expectArguments('a', array(true, false));
+ $dummy->a(true, false);
+ $dummy->a(true, true); // Fail.
+ }
+
+ function testIntegerMatching() {
+ $dummy = &new MockDummy();
+ $dummy->expectArguments('a', array(32, 33));
+ $dummy->a(32, 33);
+ $dummy->a(32, 34); // Fail.
+ }
+
+ function testFloatMatching() {
+ $dummy = &new MockDummy();
+ $dummy->expectArguments('a', array(3.2, 3.3));
+ $dummy->a(3.2, 3.3);
+ $dummy->a(3.2, 3.4); // Fail.
+ }
+
+ function testStringMatching() {
+ $dummy = &new MockDummy();
+ $dummy->expectArguments('a', array('32', '33'));
+ $dummy->a('32', '33');
+ $dummy->a('32', '34'); // Fail.
+ }
+
+ function testEmptyMatchingWithCustomExpectationMessage() {
+ $dummy = &new MockDummy();
+ $dummy->expectArguments(
+ 'a',
+ array(new EqualExpectation('A', 'My part expectation message: %s')),
+ 'My expectation message: %s');
+ $dummy->a('A');
+ $dummy->a('B'); // Fail.
+ }
+
+ function testArrayMatching() {
+ $dummy = &new MockDummy();
+ $dummy->expectArguments('a', array(array(32), array(33)));
+ $dummy->a(array(32), array(33));
+ $dummy->a(array(32), array('33')); // Fail.
+ }
+
+ function testObjectMatching() {
+ $a = new Dummy();
+ $a->a = 'a';
+ $b = new Dummy();
+ $b->b = 'b';
+ $dummy = &new MockDummy();
+ $dummy->expectArguments('a', array($a, $b));
+ $dummy->a($a, $b);
+ $dummy->a($a, $a); // Fail.
+ }
+
+ function testBigList() {
+ $dummy = &new MockDummy();
+ $dummy->expectArguments('a', array(false, 0, 1, 1.0));
+ $dummy->a(false, 0, 1, 1.0);
+ $dummy->a(true, false, 2, 2.0); // Fail.
+ }
+ }
+
+ class TestOfPastBugs extends UnitTestCase {
+
+ function testMixedTypes() {
+ $this->assertEqual(array(), null, "%s -> Pass");
+ $this->assertIdentical(array(), null, "%s -> Fail"); // Fail.
+ }
+
+ function testMockWildcards() {
+ $dummy = &new MockDummy();
+ $dummy->expectArguments('a', array('*', array(33)));
+ $dummy->a(array(32), array(33));
+ $dummy->a(array(32), array('33')); // Fail.
+ }
+ }
+
+ class TestOfVisualShell extends ShellTestCase {
+
+ function testDump() {
+ $this->execute('ls');
+ $this->dumpOutput();
+ $this->execute('dir');
+ $this->dumpOutput();
+ }
+
+ function testDumpOfList() {
+ $this->execute('ls');
+ $this->dump($this->getOutputAsList());
+ }
+ }
+
+ class PassesAsWellReporter extends HtmlReporter {
+
+ function _getCss() {
+ return parent::_getCss() . ' .pass { color: darkgreen; }';
+ }
+
+ function paintPass($message) {
+ parent::paintPass($message);
+ print "<span class=\"pass\">Pass</span>: ";
+ $breadcrumb = $this->getTestList();
+ array_shift($breadcrumb);
+ print implode(" -&gt; ", $breadcrumb);
+ print " -&gt; " . htmlentities($message) . "<br />\n";
+ }
+
+ function paintSignal($type, &$payload) {
+ print "<span class=\"fail\">$type</span>: ";
+ $breadcrumb = $this->getTestList();
+ array_shift($breadcrumb);
+ print implode(" -&gt; ", $breadcrumb);
+ print " -&gt; " . htmlentities(serialize($payload)) . "<br />\n";
+ }
+ }
+
+ class TestOfSkippingNoMatterWhat extends UnitTestCase {
+ function skip() {
+ $this->skipIf(true, 'Always skipped -> %s');
+ }
+
+ function testFail() {
+ $this->fail('This really shouldn\'t have happened');
+ }
+ }
+
+ class TestOfSkippingOrElse extends UnitTestCase {
+ function skip() {
+ $this->skipUnless(false, 'Always skipped -> %s');
+ }
+
+ function testFail() {
+ $this->fail('This really shouldn\'t have happened');
+ }
+ }
+
+ class TestOfSkippingTwiceOver extends UnitTestCase {
+ function skip() {
+ $this->skipIf(true, 'First reason -> %s');
+ $this->skipIf(true, 'Second reason -> %s');
+ }
+
+ function testFail() {
+ $this->fail('This really shouldn\'t have happened');
+ }
+ }
+
+ class TestThatShouldNotBeSkipped extends UnitTestCase {
+ function skip() {
+ $this->skipIf(false);
+ $this->skipUnless(true);
+ }
+
+ function testFail() {
+ $this->fail('We should see this message');
+ }
+
+ function testPass() {
+ $this->pass('We should see this message');
+ }
+ }
+
+ $test = &new TestSuite('Visual test with 46 passes, 47 fails and 0 exceptions');
+ $test->addTestCase(new PassingUnitTestCaseOutput());
+ $test->addTestCase(new FailingUnitTestCaseOutput());
+ $test->addTestCase(new TestOfMockObjectsOutput());
+ $test->addTestCase(new TestOfPastBugs());
+ $test->addTestCase(new TestOfVisualShell());
+ $test->addTestCase(new TestOfSkippingNoMatterWhat());
+ $test->addTestCase(new TestOfSkippingOrElse());
+ $test->addTestCase(new TestOfSkippingTwiceOver());
+ $test->addTestCase(new TestThatShouldNotBeSkipped());
+
+ if (isset($_GET['xml']) || in_array('xml', (isset($argv) ? $argv : array()))) {
+ $reporter = &new XmlReporter();
+ } elseif (TextReporter::inCli()) {
+ $reporter = &new TextReporter();
+ } else {
+ $reporter = &new PassesAsWellReporter();
+ }
+ if (isset($_GET['dry']) || in_array('dry', (isset($argv) ? $argv : array()))) {
+ $reporter->makeDry();
+ }
+ exit ($test->run($reporter) ? 0 : 1);
+?> \ No newline at end of file
diff --git a/site/vendors/simpletest/test/web_tester_test.php b/site/vendors/simpletest/test/web_tester_test.php
new file mode 100644
index 0000000..01f7d3c
--- /dev/null
+++ b/site/vendors/simpletest/test/web_tester_test.php
@@ -0,0 +1,156 @@
+<?php
+// $Id: web_tester_test.php 1509 2007-05-08 22:11:49Z lastcraft $
+require_once(dirname(__FILE__) . '/../autorun.php');
+require_once(dirname(__FILE__) . '/../web_tester.php');
+
+class TestOfFieldExpectation extends UnitTestCase {
+
+ function testStringMatchingIsCaseSensitive() {
+ $expectation = new FieldExpectation('a');
+ $this->assertTrue($expectation->test('a'));
+ $this->assertTrue($expectation->test(array('a')));
+ $this->assertFalse($expectation->test('A'));
+ }
+
+ function testMatchesInteger() {
+ $expectation = new FieldExpectation('1');
+ $this->assertTrue($expectation->test('1'));
+ $this->assertTrue($expectation->test(1));
+ $this->assertTrue($expectation->test(array('1')));
+ $this->assertTrue($expectation->test(array(1)));
+ }
+
+ function testNonStringFailsExpectation() {
+ $expectation = new FieldExpectation('a');
+ $this->assertFalse($expectation->test(null));
+ }
+
+ function testUnsetFieldCanBeTestedFor() {
+ $expectation = new FieldExpectation(false);
+ $this->assertTrue($expectation->test(false));
+ }
+
+ function testMultipleValuesCanBeInAnyOrder() {
+ $expectation = new FieldExpectation(array('a', 'b'));
+ $this->assertTrue($expectation->test(array('a', 'b')));
+ $this->assertTrue($expectation->test(array('b', 'a')));
+ $this->assertFalse($expectation->test(array('a', 'a')));
+ $this->assertFalse($expectation->test('a'));
+ }
+
+ function testSingleItemCanBeArrayOrString() {
+ $expectation = new FieldExpectation(array('a'));
+ $this->assertTrue($expectation->test(array('a')));
+ $this->assertTrue($expectation->test('a'));
+ }
+}
+
+class TestOfHeaderExpectations extends UnitTestCase {
+
+ function testExpectingOnlyTheHeaderName() {
+ $expectation = new HttpHeaderExpectation('a');
+ $this->assertIdentical($expectation->test(false), false);
+ $this->assertIdentical($expectation->test('a: A'), true);
+ $this->assertIdentical($expectation->test('A: A'), true);
+ $this->assertIdentical($expectation->test('a: B'), true);
+ $this->assertIdentical($expectation->test(' a : A '), true);
+ }
+
+ function testHeaderValueAsWell() {
+ $expectation = new HttpHeaderExpectation('a', 'A');
+ $this->assertIdentical($expectation->test(false), false);
+ $this->assertIdentical($expectation->test('a: A'), true);
+ $this->assertIdentical($expectation->test('A: A'), true);
+ $this->assertIdentical($expectation->test('A: a'), false);
+ $this->assertIdentical($expectation->test('a: B'), false);
+ $this->assertIdentical($expectation->test(' a : A '), true);
+ $this->assertIdentical($expectation->test(' a : AB '), false);
+ }
+
+ function testHeaderValueWithColons() {
+ $expectation = new HttpHeaderExpectation('a', 'A:B:C');
+ $this->assertIdentical($expectation->test('a: A'), false);
+ $this->assertIdentical($expectation->test('a: A:B'), false);
+ $this->assertIdentical($expectation->test('a: A:B:C'), true);
+ $this->assertIdentical($expectation->test('a: A:B:C:D'), false);
+ }
+
+ function testMultilineSearch() {
+ $expectation = new HttpHeaderExpectation('a', 'A');
+ $this->assertIdentical($expectation->test("aa: A\r\nb: B\r\nc: C"), false);
+ $this->assertIdentical($expectation->test("aa: A\r\na: A\r\nb: B"), true);
+ }
+
+ function testMultilineSearchWithPadding() {
+ $expectation = new HttpHeaderExpectation('a', ' A ');
+ $this->assertIdentical($expectation->test("aa:A\r\nb:B\r\nc:C"), false);
+ $this->assertIdentical($expectation->test("aa:A\r\na:A\r\nb:B"), true);
+ }
+
+ function testPatternMatching() {
+ $expectation = new HttpHeaderExpectation('a', new PatternExpectation('/A/'));
+ $this->assertIdentical($expectation->test('a: A'), true);
+ $this->assertIdentical($expectation->test('A: A'), true);
+ $this->assertIdentical($expectation->test('A: a'), false);
+ $this->assertIdentical($expectation->test('a: B'), false);
+ $this->assertIdentical($expectation->test(' a : A '), true);
+ $this->assertIdentical($expectation->test(' a : AB '), true);
+ }
+
+ function testCaseInsensitivePatternMatching() {
+ $expectation = new HttpHeaderExpectation('a', new PatternExpectation('/A/i'));
+ $this->assertIdentical($expectation->test('a: a'), true);
+ $this->assertIdentical($expectation->test('a: B'), false);
+ $this->assertIdentical($expectation->test(' a : A '), true);
+ $this->assertIdentical($expectation->test(' a : BAB '), true);
+ $this->assertIdentical($expectation->test(' a : bab '), true);
+ }
+
+ function testUnwantedHeader() {
+ $expectation = new NoHttpHeaderExpectation('a');
+ $this->assertIdentical($expectation->test(''), true);
+ $this->assertIdentical($expectation->test('stuff'), true);
+ $this->assertIdentical($expectation->test('b: B'), true);
+ $this->assertIdentical($expectation->test('a: A'), false);
+ $this->assertIdentical($expectation->test('A: A'), false);
+ }
+
+ function testMultilineUnwantedSearch() {
+ $expectation = new NoHttpHeaderExpectation('a');
+ $this->assertIdentical($expectation->test("aa:A\r\nb:B\r\nc:C"), true);
+ $this->assertIdentical($expectation->test("aa:A\r\na:A\r\nb:B"), false);
+ }
+
+ function testLocationHeaderSplitsCorrectly() {
+ $expectation = new HttpHeaderExpectation('Location', 'http://here/');
+ $this->assertIdentical($expectation->test('Location: http://here/'), true);
+ }
+}
+
+class TestOfTextExpectations extends UnitTestCase {
+
+ function testMatchingSubString() {
+ $expectation = new TextExpectation('wanted');
+ $this->assertIdentical($expectation->test(''), false);
+ $this->assertIdentical($expectation->test('Wanted'), false);
+ $this->assertIdentical($expectation->test('wanted'), true);
+ $this->assertIdentical($expectation->test('the wanted text is here'), true);
+ }
+
+ function testNotMatchingSubString() {
+ $expectation = new NoTextExpectation('wanted');
+ $this->assertIdentical($expectation->test(''), true);
+ $this->assertIdentical($expectation->test('Wanted'), true);
+ $this->assertIdentical($expectation->test('wanted'), false);
+ $this->assertIdentical($expectation->test('the wanted text is here'), false);
+ }
+}
+
+class TestOfGenericAssertionsInWebTester extends WebTestCase {
+
+ function testEquality() {
+ $this->assertEqual('a', 'a');
+ $this->assertNotEqual('a', 'A');
+ }
+}
+?> \ No newline at end of file
diff --git a/site/vendors/simpletest/test/xml_test.php b/site/vendors/simpletest/test/xml_test.php
new file mode 100644
index 0000000..91985b5
--- /dev/null
+++ b/site/vendors/simpletest/test/xml_test.php
@@ -0,0 +1,187 @@
+<?php
+// $Id: xml_test.php 1509 2007-05-08 22:11:49Z lastcraft $
+require_once(dirname(__FILE__) . '/../autorun.php');
+require_once(dirname(__FILE__) . '/../xml.php');
+Mock::generate('SimpleScorer');
+
+if (! function_exists('xml_parser_create')) {
+ SimpleTest::ignore('TestOfXmlStructureParsing');
+ SimpleTest::ignore('TestOfXmlResultsParsing');
+}
+
+class TestOfNestingTags extends UnitTestCase {
+ function testGroupSize() {
+ $nesting = new NestingGroupTag(array('SIZE' => 2));
+ $this->assertEqual($nesting->getSize(), 2);
+ }
+}
+
+class TestOfXmlStructureParsing extends UnitTestCase {
+ function testValidXml() {
+ $listener = &new MockSimpleScorer();
+ $listener->expectNever('paintGroupStart');
+ $listener->expectNever('paintGroupEnd');
+ $listener->expectNever('paintCaseStart');
+ $listener->expectNever('paintCaseEnd');
+ $parser = &new SimpleTestXmlParser($listener);
+ $this->assertTrue($parser->parse("<?xml version=\"1.0\"?>\n"));
+ $this->assertTrue($parser->parse("<run>\n"));
+ $this->assertTrue($parser->parse("</run>\n"));
+ }
+
+ function testEmptyGroup() {
+ $listener = &new MockSimpleScorer();
+ $listener->expectOnce('paintGroupStart', array('a_group', 7));
+ $listener->expectOnce('paintGroupEnd', array('a_group'));
+ $parser = &new SimpleTestXmlParser($listener);
+ $parser->parse("<?xml version=\"1.0\"?>\n");
+ $parser->parse("<run>\n");
+ $this->assertTrue($parser->parse("<group size=\"7\">\n"));
+ $this->assertTrue($parser->parse("<name>a_group</name>\n"));
+ $this->assertTrue($parser->parse("</group>\n"));
+ $parser->parse("</run>\n");
+ }
+
+ function testEmptyCase() {
+ $listener = &new MockSimpleScorer();
+ $listener->expectOnce('paintCaseStart', array('a_case'));
+ $listener->expectOnce('paintCaseEnd', array('a_case'));
+ $parser = &new SimpleTestXmlParser($listener);
+ $parser->parse("<?xml version=\"1.0\"?>\n");
+ $parser->parse("<run>\n");
+ $this->assertTrue($parser->parse("<case>\n"));
+ $this->assertTrue($parser->parse("<name>a_case</name>\n"));
+ $this->assertTrue($parser->parse("</case>\n"));
+ $parser->parse("</run>\n");
+ }
+
+ function testEmptyMethod() {
+ $listener = &new MockSimpleScorer();
+ $listener->expectOnce('paintCaseStart', array('a_case'));
+ $listener->expectOnce('paintCaseEnd', array('a_case'));
+ $listener->expectOnce('paintMethodStart', array('a_method'));
+ $listener->expectOnce('paintMethodEnd', array('a_method'));
+ $parser = &new SimpleTestXmlParser($listener);
+ $parser->parse("<?xml version=\"1.0\"?>\n");
+ $parser->parse("<run>\n");
+ $parser->parse("<case>\n");
+ $parser->parse("<name>a_case</name>\n");
+ $this->assertTrue($parser->parse("<test>\n"));
+ $this->assertTrue($parser->parse("<name>a_method</name>\n"));
+ $this->assertTrue($parser->parse("</test>\n"));
+ $parser->parse("</case>\n");
+ $parser->parse("</run>\n");
+ }
+
+ function testNestedGroup() {
+ $listener = &new MockSimpleScorer();
+ $listener->expectArgumentsAt(0, 'paintGroupStart', array('a_group', 7));
+ $listener->expectArgumentsAt(1, 'paintGroupStart', array('b_group', 3));
+ $listener->expectCallCount('paintGroupStart', 2);
+ $listener->expectArgumentsAt(0, 'paintGroupEnd', array('b_group'));
+ $listener->expectArgumentsAt(1, 'paintGroupEnd', array('a_group'));
+ $listener->expectCallCount('paintGroupEnd', 2);
+
+ $parser = &new SimpleTestXmlParser($listener);
+ $parser->parse("<?xml version=\"1.0\"?>\n");
+ $parser->parse("<run>\n");
+
+ $this->assertTrue($parser->parse("<group size=\"7\">\n"));
+ $this->assertTrue($parser->parse("<name>a_group</name>\n"));
+ $this->assertTrue($parser->parse("<group size=\"3\">\n"));
+ $this->assertTrue($parser->parse("<name>b_group</name>\n"));
+ $this->assertTrue($parser->parse("</group>\n"));
+ $this->assertTrue($parser->parse("</group>\n"));
+ $parser->parse("</run>\n");
+ }
+}
+
+class AnyOldSignal {
+ var $stuff = true;
+}
+
+class TestOfXmlResultsParsing extends UnitTestCase {
+
+ function sendValidStart(&$parser) {
+ $parser->parse("<?xml version=\"1.0\"?>\n");
+ $parser->parse("<run>\n");
+ $parser->parse("<case>\n");
+ $parser->parse("<name>a_case</name>\n");
+ $parser->parse("<test>\n");
+ $parser->parse("<name>a_method</name>\n");
+ }
+
+ function sendValidEnd(&$parser) {
+ $parser->parse("</test>\n");
+ $parser->parse("</case>\n");
+ $parser->parse("</run>\n");
+ }
+
+ function testPass() {
+ $listener = &new MockSimpleScorer();
+ $listener->expectOnce('paintPass', array('a_message'));
+ $parser = &new SimpleTestXmlParser($listener);
+ $this->sendValidStart($parser);
+ $this->assertTrue($parser->parse("<pass>a_message</pass>\n"));
+ $this->sendValidEnd($parser);
+ }
+
+ function testFail() {
+ $listener = &new MockSimpleScorer();
+ $listener->expectOnce('paintFail', array('a_message'));
+ $parser = &new SimpleTestXmlParser($listener);
+ $this->sendValidStart($parser);
+ $this->assertTrue($parser->parse("<fail>a_message</fail>\n"));
+ $this->sendValidEnd($parser);
+ }
+
+ function testException() {
+ $listener = &new MockSimpleScorer();
+ $listener->expectOnce('paintError', array('a_message'));
+ $parser = &new SimpleTestXmlParser($listener);
+ $this->sendValidStart($parser);
+ $this->assertTrue($parser->parse("<exception>a_message</exception>\n"));
+ $this->sendValidEnd($parser);
+ }
+
+ function testSkip() {
+ $listener = &new MockSimpleScorer();
+ $listener->expectOnce('paintSkip', array('a_message'));
+ $parser = &new SimpleTestXmlParser($listener);
+ $this->sendValidStart($parser);
+ $this->assertTrue($parser->parse("<skip>a_message</skip>\n"));
+ $this->sendValidEnd($parser);
+ }
+
+ function testSignal() {
+ $signal = new AnyOldSignal();
+ $signal->stuff = "Hello";
+ $listener = &new MockSimpleScorer();
+ $listener->expectOnce('paintSignal', array('a_signal', $signal));
+ $parser = &new SimpleTestXmlParser($listener);
+ $this->sendValidStart($parser);
+ $this->assertTrue($parser->parse(
+ "<signal type=\"a_signal\"><![CDATA[" .
+ serialize($signal) . "]]></signal>\n"));
+ $this->sendValidEnd($parser);
+ }
+
+ function testMessage() {
+ $listener = &new MockSimpleScorer();
+ $listener->expectOnce('paintMessage', array('a_message'));
+ $parser = &new SimpleTestXmlParser($listener);
+ $this->sendValidStart($parser);
+ $this->assertTrue($parser->parse("<message>a_message</message>\n"));
+ $this->sendValidEnd($parser);
+ }
+
+ function testFormattedMessage() {
+ $listener = &new MockSimpleScorer();
+ $listener->expectOnce('paintFormattedMessage', array("\na\tmessage\n"));
+ $parser = &new SimpleTestXmlParser($listener);
+ $this->sendValidStart($parser);
+ $this->assertTrue($parser->parse("<formatted><![CDATA[\na\tmessage\n]]></formatted>\n"));
+ $this->sendValidEnd($parser);
+ }
+}
+?> \ No newline at end of file
diff --git a/site/vendors/simpletest/test_case.php b/site/vendors/simpletest/test_case.php
new file mode 100644
index 0000000..e5b2298
--- /dev/null
+++ b/site/vendors/simpletest/test_case.php
@@ -0,0 +1,708 @@
+<?php
+/**
+ * Base include file for SimpleTest
+ * @package SimpleTest
+ * @subpackage UnitTester
+ * @version $Id: test_case.php 1726 2008-04-08 01:20:10Z lastcraft $
+ */
+
+/**#@+
+ * Includes SimpleTest files and defined the root constant
+ * for dependent libraries.
+ */
+require_once(dirname(__FILE__) . '/invoker.php');
+require_once(dirname(__FILE__) . '/errors.php');
+require_once(dirname(__FILE__) . '/compatibility.php');
+require_once(dirname(__FILE__) . '/scorer.php');
+require_once(dirname(__FILE__) . '/expectation.php');
+require_once(dirname(__FILE__) . '/dumper.php');
+require_once(dirname(__FILE__) . '/simpletest.php');
+if (version_compare(phpversion(), '5') >= 0) {
+ require_once(dirname(__FILE__) . '/exceptions.php');
+ require_once(dirname(__FILE__) . '/reflection_php5.php');
+} else {
+ require_once(dirname(__FILE__) . '/reflection_php4.php');
+}
+if (! defined('SIMPLE_TEST')) {
+ /**
+ * @ignore
+ */
+ define('SIMPLE_TEST', dirname(__FILE__) . DIRECTORY_SEPARATOR);
+}
+/**#@-*/
+
+/**
+ * Basic test case. This is the smallest unit of a test
+ * suite. It searches for
+ * all methods that start with the the string "test" and
+ * runs them. Working test cases extend this class.
+ * @package SimpleTest
+ * @subpackage UnitTester
+ */
+class SimpleTestCase {
+ var $_label = false;
+ var $_reporter;
+ var $_observers;
+ var $_should_skip = false;
+
+ /**
+ * Sets up the test with no display.
+ * @param string $label If no test name is given then
+ * the class name is used.
+ * @access public
+ */
+ function SimpleTestCase($label = false) {
+ if ($label) {
+ $this->_label = $label;
+ }
+ }
+
+ /**
+ * Accessor for the test name for subclasses.
+ * @return string Name of the test.
+ * @access public
+ */
+ function getLabel() {
+ return $this->_label ? $this->_label : get_class($this);
+ }
+
+ /**
+ * This is a placeholder for skipping tests. In this
+ * method you place skipIf() and skipUnless() calls to
+ * set the skipping state.
+ * @access public
+ */
+ function skip() {
+ }
+
+ /**
+ * Will issue a message to the reporter and tell the test
+ * case to skip if the incoming flag is true.
+ * @param string $should_skip Condition causing the tests to be skipped.
+ * @param string $message Text of skip condition.
+ * @access public
+ */
+ function skipIf($should_skip, $message = '%s') {
+ if ($should_skip && ! $this->_should_skip) {
+ $this->_should_skip = true;
+ $message = sprintf($message, 'Skipping [' . get_class($this) . ']');
+ $this->_reporter->paintSkip($message . $this->getAssertionLine());
+ }
+ }
+
+ /**
+ * Will issue a message to the reporter and tell the test
+ * case to skip if the incoming flag is false.
+ * @param string $shouldnt_skip Condition causing the tests to be run.
+ * @param string $message Text of skip condition.
+ * @access public
+ */
+ function skipUnless($shouldnt_skip, $message = false) {
+ $this->skipIf(! $shouldnt_skip, $message);
+ }
+
+ /**
+ * Used to invoke the single tests.
+ * @return SimpleInvoker Individual test runner.
+ * @access public
+ */
+ function &createInvoker() {
+ $invoker = &new SimpleErrorTrappingInvoker(new SimpleInvoker($this));
+ if (version_compare(phpversion(), '5') >= 0) {
+ $invoker = &new SimpleExceptionTrappingInvoker($invoker);
+ }
+ return $invoker;
+ }
+
+ /**
+ * Uses reflection to run every method within itself
+ * starting with the string "test" unless a method
+ * is specified.
+ * @param SimpleReporter $reporter Current test reporter.
+ * @return boolean True if all tests passed.
+ * @access public
+ */
+ function run(&$reporter) {
+ $context = &SimpleTest::getContext();
+ $context->setTest($this);
+ $context->setReporter($reporter);
+ $this->_reporter = &$reporter;
+ $started = false;
+ foreach ($this->getTests() as $method) {
+ if ($reporter->shouldInvoke($this->getLabel(), $method)) {
+ $this->skip();
+ if ($this->_should_skip) {
+ break;
+ }
+ if (! $started) {
+ $reporter->paintCaseStart($this->getLabel());
+ $started = true;
+ }
+ $invoker = &$this->_reporter->createInvoker($this->createInvoker());
+ $invoker->before($method);
+ $invoker->invoke($method);
+ $invoker->after($method);
+ }
+ }
+ if ($started) {
+ $reporter->paintCaseEnd($this->getLabel());
+ }
+ unset($this->_reporter);
+ return $reporter->getStatus();
+ }
+
+ /**
+ * Gets a list of test names. Normally that will
+ * be all internal methods that start with the
+ * name "test". This method should be overridden
+ * if you want a different rule.
+ * @return array List of test names.
+ * @access public
+ */
+ function getTests() {
+ $methods = array();
+ foreach (get_class_methods(get_class($this)) as $method) {
+ if ($this->_isTest($method)) {
+ $methods[] = $method;
+ }
+ }
+ return $methods;
+ }
+
+ /**
+ * Tests to see if the method is a test that should
+ * be run. Currently any method that starts with 'test'
+ * is a candidate unless it is the constructor.
+ * @param string $method Method name to try.
+ * @return boolean True if test method.
+ * @access protected
+ */
+ function _isTest($method) {
+ if (strtolower(substr($method, 0, 4)) == 'test') {
+ return ! SimpleTestCompatibility::isA($this, strtolower($method));
+ }
+ return false;
+ }
+
+ /**
+ * Announces the start of the test.
+ * @param string $method Test method just started.
+ * @access public
+ */
+ function before($method) {
+ $this->_reporter->paintMethodStart($method);
+ $this->_observers = array();
+ }
+
+ /**
+ * Sets up unit test wide variables at the start
+ * of each test method. To be overridden in
+ * actual user test cases.
+ * @access public
+ */
+ function setUp() {
+ }
+
+ /**
+ * Clears the data set in the setUp() method call.
+ * To be overridden by the user in actual user test cases.
+ * @access public
+ */
+ function tearDown() {
+ }
+
+ /**
+ * Announces the end of the test. Includes private clean up.
+ * @param string $method Test method just finished.
+ * @access public
+ */
+ function after($method) {
+ for ($i = 0; $i < count($this->_observers); $i++) {
+ $this->_observers[$i]->atTestEnd($method, $this);
+ }
+ $this->_reporter->paintMethodEnd($method);
+ }
+
+ /**
+ * Sets up an observer for the test end.
+ * @param object $observer Must have atTestEnd()
+ * method.
+ * @access public
+ */
+ function tell(&$observer) {
+ $this->_observers[] = &$observer;
+ }
+
+ /**
+ * @deprecated
+ */
+ function pass($message = "Pass") {
+ if (! isset($this->_reporter)) {
+ trigger_error('Can only make assertions within test methods');
+ }
+ $this->_reporter->paintPass(
+ $message . $this->getAssertionLine());
+ return true;
+ }
+
+ /**
+ * Sends a fail event with a message.
+ * @param string $message Message to send.
+ * @access public
+ */
+ function fail($message = "Fail") {
+ if (! isset($this->_reporter)) {
+ trigger_error('Can only make assertions within test methods');
+ }
+ $this->_reporter->paintFail(
+ $message . $this->getAssertionLine());
+ return false;
+ }
+
+ /**
+ * Formats a PHP error and dispatches it to the
+ * reporter.
+ * @param integer $severity PHP error code.
+ * @param string $message Text of error.
+ * @param string $file File error occoured in.
+ * @param integer $line Line number of error.
+ * @access public
+ */
+ function error($severity, $message, $file, $line) {
+ if (! isset($this->_reporter)) {
+ trigger_error('Can only make assertions within test methods');
+ }
+ $this->_reporter->paintError(
+ "Unexpected PHP error [$message] severity [$severity] in [$file line $line]");
+ }
+
+ /**
+ * Formats an exception and dispatches it to the
+ * reporter.
+ * @param Exception $exception Object thrown.
+ * @access public
+ */
+ function exception($exception) {
+ $this->_reporter->paintException($exception);
+ }
+
+ /**
+ * @deprecated
+ */
+ function signal($type, &$payload) {
+ if (! isset($this->_reporter)) {
+ trigger_error('Can only make assertions within test methods');
+ }
+ $this->_reporter->paintSignal($type, $payload);
+ }
+
+ /**
+ * Runs an expectation directly, for extending the
+ * tests with new expectation classes.
+ * @param SimpleExpectation $expectation Expectation subclass.
+ * @param mixed $compare Value to compare.
+ * @param string $message Message to display.
+ * @return boolean True on pass
+ * @access public
+ */
+ function assert(&$expectation, $compare, $message = '%s') {
+ if ($expectation->test($compare)) {
+ return $this->pass(sprintf(
+ $message,
+ $expectation->overlayMessage($compare, $this->_reporter->getDumper())));
+ } else {
+ return $this->fail(sprintf(
+ $message,
+ $expectation->overlayMessage($compare, $this->_reporter->getDumper())));
+ }
+ }
+
+ /**
+ * @deprecated
+ */
+ function assertExpectation(&$expectation, $compare, $message = '%s') {
+ return $this->assert($expectation, $compare, $message);
+ }
+
+ /**
+ * Uses a stack trace to find the line of an assertion.
+ * @return string Line number of first assert*
+ * method embedded in format string.
+ * @access public
+ */
+ function getAssertionLine() {
+ $trace = new SimpleStackTrace(array('assert', 'expect', 'pass', 'fail', 'skip'));
+ return $trace->traceMethod();
+ }
+
+ /**
+ * Sends a formatted dump of a variable to the
+ * test suite for those emergency debugging
+ * situations.
+ * @param mixed $variable Variable to display.
+ * @param string $message Message to display.
+ * @return mixed The original variable.
+ * @access public
+ */
+ function dump($variable, $message = false) {
+ $dumper = $this->_reporter->getDumper();
+ $formatted = $dumper->dump($variable);
+ if ($message) {
+ $formatted = $message . "\n" . $formatted;
+ }
+ $this->_reporter->paintFormattedMessage($formatted);
+ return $variable;
+ }
+
+ /**
+ * @deprecated
+ */
+ function sendMessage($message) {
+ $this->_reporter->PaintMessage($message);
+ }
+
+ /**
+ * Accessor for the number of subtests including myelf.
+ * @return integer Number of test cases.
+ * @access public
+ * @static
+ */
+ function getSize() {
+ return 1;
+ }
+}
+
+/**
+ * Helps to extract test cases automatically from a file.
+ */
+class SimpleFileLoader {
+
+ /**
+ * Builds a test suite from a library of test cases.
+ * The new suite is composed into this one.
+ * @param string $test_file File name of library with
+ * test case classes.
+ * @return TestSuite The new test suite.
+ * @access public
+ */
+ function &load($test_file) {
+ $existing_classes = get_declared_classes();
+ $existing_globals = get_defined_vars();
+ include_once($test_file);
+ $new_globals = get_defined_vars();
+ $this->_makeFileVariablesGlobal($existing_globals, $new_globals);
+ $new_classes = array_diff(get_declared_classes(), $existing_classes);
+ if (empty($new_classes)) {
+ $new_classes = $this->_scrapeClassesFromFile($test_file);
+ }
+ $classes = $this->selectRunnableTests($new_classes);
+ $suite = &$this->createSuiteFromClasses($test_file, $classes);
+ return $suite;
+ }
+
+ /**
+ * Imports new variables into the global namespace.
+ * @param hash $existing Variables before the file was loaded.
+ * @param hash $new Variables after the file was loaded.
+ * @access private
+ */
+ function _makeFileVariablesGlobal($existing, $new) {
+ $globals = array_diff(array_keys($new), array_keys($existing));
+ foreach ($globals as $global) {
+ $_GLOBALS[$global] = $new[$global];
+ }
+ }
+
+ /**
+ * Lookup classnames from file contents, in case the
+ * file may have been included before.
+ * Note: This is probably too clever by half. Figuring this
+ * out after a failed test case is going to be tricky for us,
+ * never mind the user. A test case should not be included
+ * twice anyway.
+ * @param string $test_file File name with classes.
+ * @access private
+ */
+ function _scrapeClassesFromFile($test_file) {
+ preg_match_all('~^\s*class\s+(\w+)(\s+(extends|implements)\s+\w+)*\s*\{~mi',
+ file_get_contents($test_file),
+ $matches );
+ return $matches[1];
+ }
+
+ /**
+ * Calculates the incoming test cases. Skips abstract
+ * and ignored classes.
+ * @param array $candidates Candidate classes.
+ * @return array New classes which are test
+ * cases that shouldn't be ignored.
+ * @access public
+ */
+ function selectRunnableTests($candidates) {
+ $classes = array();
+ foreach ($candidates as $class) {
+ if (TestSuite::getBaseTestCase($class)) {
+ $reflection = new SimpleReflection($class);
+ if ($reflection->isAbstract()) {
+ SimpleTest::ignore($class);
+ } else {
+ $classes[] = $class;
+ }
+ }
+ }
+ return $classes;
+ }
+
+ /**
+ * Builds a test suite from a class list.
+ * @param string $title Title of new group.
+ * @param array $classes Test classes.
+ * @return TestSuite Group loaded with the new
+ * test cases.
+ * @access public
+ */
+ function &createSuiteFromClasses($title, $classes) {
+ if (count($classes) == 0) {
+ $suite = &new BadTestSuite($title, "No runnable test cases in [$title]");
+ return $suite;
+ }
+ SimpleTest::ignoreParentsIfIgnored($classes);
+ $suite = &new TestSuite($title);
+ foreach ($classes as $class) {
+ if (! SimpleTest::isIgnored($class)) {
+ $suite->addTestClass($class);
+ }
+ }
+ return $suite;
+ }
+}
+
+/**
+ * This is a composite test class for combining
+ * test cases and other RunnableTest classes into
+ * a group test.
+ * @package SimpleTest
+ * @subpackage UnitTester
+ */
+class TestSuite {
+ var $_label;
+ var $_test_cases;
+
+ /**
+ * Sets the name of the test suite.
+ * @param string $label Name sent at the start and end
+ * of the test.
+ * @access public
+ */
+ function TestSuite($label = false) {
+ $this->_label = $label;
+ $this->_test_cases = array();
+ }
+
+ /**
+ * Accessor for the test name for subclasses. If the suite
+ * wraps a single test case the label defaults to the name of that test.
+ * @return string Name of the test.
+ * @access public
+ */
+ function getLabel() {
+ if (! $this->_label) {
+ return ($this->getSize() == 1) ?
+ get_class($this->_test_cases[0]) : get_class($this);
+ } else {
+ return $this->_label;
+ }
+ }
+
+ /**
+ * @deprecated
+ */
+ function addTestCase(&$test_case) {
+ $this->_test_cases[] = &$test_case;
+ }
+
+ /**
+ * @deprecated
+ */
+ function addTestClass($class) {
+ if (TestSuite::getBaseTestCase($class) == 'testsuite') {
+ $this->_test_cases[] = &new $class();
+ } else {
+ $this->_test_cases[] = $class;
+ }
+ }
+
+ /**
+ * Adds a test into the suite by instance or class. The class will
+ * be instantiated if it's a test suite.
+ * @param SimpleTestCase $test_case Suite or individual test
+ * case implementing the
+ * runnable test interface.
+ * @access public
+ */
+ function add(&$test_case) {
+ if (! is_string($test_case)) {
+ $this->_test_cases[] = &$test_case;
+ } elseif (TestSuite::getBaseTestCase($class) == 'testsuite') {
+ $this->_test_cases[] = &new $class();
+ } else {
+ $this->_test_cases[] = $class;
+ }
+ }
+
+ /**
+ * @deprecated
+ */
+ function addTestFile($test_file) {
+ $this->addFile($test_file);
+ }
+
+ /**
+ * Builds a test suite from a library of test cases.
+ * The new suite is composed into this one.
+ * @param string $test_file File name of library with
+ * test case classes.
+ * @access public
+ */
+ function addFile($test_file) {
+ $extractor = new SimpleFileLoader();
+ $this->add($extractor->load($test_file));
+ }
+
+ /**
+ * Delegates to a visiting collector to add test
+ * files.
+ * @param string $path Path to scan from.
+ * @param SimpleCollector $collector Directory scanner.
+ * @access public
+ */
+ function collect($path, &$collector) {
+ $collector->collect($this, $path);
+ }
+
+ /**
+ * Invokes run() on all of the held test cases, instantiating
+ * them if necessary.
+ * @param SimpleReporter $reporter Current test reporter.
+ * @access public
+ */
+ function run(&$reporter) {
+ $reporter->paintGroupStart($this->getLabel(), $this->getSize());
+ for ($i = 0, $count = count($this->_test_cases); $i < $count; $i++) {
+ if (is_string($this->_test_cases[$i])) {
+ $class = $this->_test_cases[$i];
+ $test = &new $class();
+ $test->run($reporter);
+ unset($test);
+ } else {
+ $this->_test_cases[$i]->run($reporter);
+ }
+ }
+ $reporter->paintGroupEnd($this->getLabel());
+ return $reporter->getStatus();
+ }
+
+ /**
+ * Number of contained test cases.
+ * @return integer Total count of cases in the group.
+ * @access public
+ */
+ function getSize() {
+ $count = 0;
+ foreach ($this->_test_cases as $case) {
+ if (is_string($case)) {
+ if (! SimpleTest::isIgnored($case)) {
+ $count++;
+ }
+ } else {
+ $count += $case->getSize();
+ }
+ }
+ return $count;
+ }
+
+ /**
+ * Test to see if a class is derived from the
+ * SimpleTestCase class.
+ * @param string $class Class name.
+ * @access public
+ * @static
+ */
+ function getBaseTestCase($class) {
+ while ($class = get_parent_class($class)) {
+ $class = strtolower($class);
+ if ($class == 'simpletestcase' || $class == 'testsuite') {
+ return $class;
+ }
+ }
+ return false;
+ }
+}
+
+/**
+ * @package SimpleTest
+ * @subpackage UnitTester
+ * @deprecated
+ */
+class GroupTest extends TestSuite { }
+
+/**
+ * This is a failing group test for when a test suite hasn't
+ * loaded properly.
+ * @package SimpleTest
+ * @subpackage UnitTester
+ */
+class BadTestSuite {
+ var $_label;
+ var $_error;
+
+ /**
+ * Sets the name of the test suite and error message.
+ * @param string $label Name sent at the start and end
+ * of the test.
+ * @access public
+ */
+ function BadTestSuite($label, $error) {
+ $this->_label = $label;
+ $this->_error = $error;
+ }
+
+ /**
+ * Accessor for the test name for subclasses.
+ * @return string Name of the test.
+ * @access public
+ */
+ function getLabel() {
+ return $this->_label;
+ }
+
+ /**
+ * Sends a single error to the reporter.
+ * @param SimpleReporter $reporter Current test reporter.
+ * @access public
+ */
+ function run(&$reporter) {
+ $reporter->paintGroupStart($this->getLabel(), $this->getSize());
+ $reporter->paintFail('Bad TestSuite [' . $this->getLabel() .
+ '] with error [' . $this->_error . ']');
+ $reporter->paintGroupEnd($this->getLabel());
+ return $reporter->getStatus();
+ }
+
+ /**
+ * Number of contained test cases. Always zero.
+ * @return integer Total count of cases in the group.
+ * @access public
+ */
+ function getSize() {
+ return 0;
+ }
+}
+
+/**
+ * @package SimpleTest
+ * @subpackage UnitTester
+ * @deprecated
+ */
+class BadGroupTest extends BadTestSuite { }
+?>
diff --git a/site/vendors/simpletest/unit_tester.php b/site/vendors/simpletest/unit_tester.php
new file mode 100644
index 0000000..8bb757d
--- /dev/null
+++ b/site/vendors/simpletest/unit_tester.php
@@ -0,0 +1,420 @@
+<?php
+/**
+ * base include file for SimpleTest
+ * @package SimpleTest
+ * @subpackage UnitTester
+ * @version $Id: unit_tester.php 1723 2008-04-08 00:34:10Z lastcraft $
+ */
+
+/**#@+
+ * include other SimpleTest class files
+ */
+require_once(dirname(__FILE__) . '/test_case.php');
+require_once(dirname(__FILE__) . '/dumper.php');
+/**#@-*/
+
+/**
+ * Standard unit test class for day to day testing
+ * of PHP code XP style. Adds some useful standard
+ * assertions.
+ * @package SimpleTest
+ * @subpackage UnitTester
+ */
+class UnitTestCase extends SimpleTestCase {
+
+ /**
+ * Creates an empty test case. Should be subclassed
+ * with test methods for a functional test case.
+ * @param string $label Name of test case. Will use
+ * the class name if none specified.
+ * @access public
+ */
+ function UnitTestCase($label = false) {
+ if (! $label) {
+ $label = get_class($this);
+ }
+ $this->SimpleTestCase($label);
+ }
+
+ /**
+ * Called from within the test methods to register
+ * passes and failures.
+ * @param boolean $result Pass on true.
+ * @param string $message Message to display describing
+ * the test state.
+ * @return boolean True on pass
+ * @access public
+ */
+ function assertTrue($result, $message = false) {
+ return $this->assert(new TrueExpectation(), $result, $message);
+ }
+
+ /**
+ * Will be true on false and vice versa. False
+ * is the PHP definition of false, so that null,
+ * empty strings, zero and an empty array all count
+ * as false.
+ * @param boolean $result Pass on false.
+ * @param string $message Message to display.
+ * @return boolean True on pass
+ * @access public
+ */
+ function assertFalse($result, $message = '%s') {
+ return $this->assert(new FalseExpectation(), $result, $message);
+ }
+
+ /**
+ * Will be true if the value is null.
+ * @param null $value Supposedly null value.
+ * @param string $message Message to display.
+ * @return boolean True on pass
+ * @access public
+ */
+ function assertNull($value, $message = '%s') {
+ $dumper = &new SimpleDumper();
+ $message = sprintf(
+ $message,
+ '[' . $dumper->describeValue($value) . '] should be null');
+ return $this->assertTrue(! isset($value), $message);
+ }
+
+ /**
+ * Will be true if the value is set.
+ * @param mixed $value Supposedly set value.
+ * @param string $message Message to display.
+ * @return boolean True on pass.
+ * @access public
+ */
+ function assertNotNull($value, $message = '%s') {
+ $dumper = &new SimpleDumper();
+ $message = sprintf(
+ $message,
+ '[' . $dumper->describeValue($value) . '] should not be null');
+ return $this->assertTrue(isset($value), $message);
+ }
+
+ /**
+ * Type and class test. Will pass if class
+ * matches the type name or is a subclass or
+ * if not an object, but the type is correct.
+ * @param mixed $object Object to test.
+ * @param string $type Type name as string.
+ * @param string $message Message to display.
+ * @return boolean True on pass.
+ * @access public
+ */
+ function assertIsA($object, $type, $message = '%s') {
+ return $this->assert(
+ new IsAExpectation($type),
+ $object,
+ $message);
+ }
+
+ /**
+ * Type and class mismatch test. Will pass if class
+ * name or underling type does not match the one
+ * specified.
+ * @param mixed $object Object to test.
+ * @param string $type Type name as string.
+ * @param string $message Message to display.
+ * @return boolean True on pass.
+ * @access public
+ */
+ function assertNotA($object, $type, $message = '%s') {
+ return $this->assert(
+ new NotAExpectation($type),
+ $object,
+ $message);
+ }
+
+ /**
+ * Will trigger a pass if the two parameters have
+ * the same value only. Otherwise a fail.
+ * @param mixed $first Value to compare.
+ * @param mixed $second Value to compare.
+ * @param string $message Message to display.
+ * @return boolean True on pass
+ * @access public
+ */
+ function assertEqual($first, $second, $message = '%s') {
+ return $this->assert(
+ new EqualExpectation($first),
+ $second,
+ $message);
+ }
+
+ /**
+ * Will trigger a pass if the two parameters have
+ * a different value. Otherwise a fail.
+ * @param mixed $first Value to compare.
+ * @param mixed $second Value to compare.
+ * @param string $message Message to display.
+ * @return boolean True on pass
+ * @access public
+ */
+ function assertNotEqual($first, $second, $message = '%s') {
+ return $this->assert(
+ new NotEqualExpectation($first),
+ $second,
+ $message);
+ }
+
+ /**
+ * Will trigger a pass if the if the first parameter
+ * is near enough to the second by the margin.
+ * @param mixed $first Value to compare.
+ * @param mixed $second Value to compare.
+ * @param mixed $margin Fuzziness of match.
+ * @param string $message Message to display.
+ * @return boolean True on pass
+ * @access public
+ */
+ function assertWithinMargin($first, $second, $margin, $message = '%s') {
+ return $this->assert(
+ new WithinMarginExpectation($first, $margin),
+ $second,
+ $message);
+ }
+
+ /**
+ * Will trigger a pass if the two parameters differ
+ * by more than the margin.
+ * @param mixed $first Value to compare.
+ * @param mixed $second Value to compare.
+ * @param mixed $margin Fuzziness of match.
+ * @param string $message Message to display.
+ * @return boolean True on pass
+ * @access public
+ */
+ function assertOutsideMargin($first, $second, $margin, $message = '%s') {
+ return $this->assert(
+ new OutsideMarginExpectation($first, $margin),
+ $second,
+ $message);
+ }
+
+ /**
+ * Will trigger a pass if the two parameters have
+ * the same value and same type. Otherwise a fail.
+ * @param mixed $first Value to compare.
+ * @param mixed $second Value to compare.
+ * @param string $message Message to display.
+ * @return boolean True on pass
+ * @access public
+ */
+ function assertIdentical($first, $second, $message = '%s') {
+ return $this->assert(
+ new IdenticalExpectation($first),
+ $second,
+ $message);
+ }
+
+ /**
+ * Will trigger a pass if the two parameters have
+ * the different value or different type.
+ * @param mixed $first Value to compare.
+ * @param mixed $second Value to compare.
+ * @param string $message Message to display.
+ * @return boolean True on pass
+ * @access public
+ */
+ function assertNotIdentical($first, $second, $message = '%s') {
+ return $this->assert(
+ new NotIdenticalExpectation($first),
+ $second,
+ $message);
+ }
+
+ /**
+ * Will trigger a pass if both parameters refer
+ * to the same object. Fail otherwise.
+ * @param mixed $first Object reference to check.
+ * @param mixed $second Hopefully the same object.
+ * @param string $message Message to display.
+ * @return boolean True on pass
+ * @access public
+ */
+ function assertReference(&$first, &$second, $message = '%s') {
+ $dumper = &new SimpleDumper();
+ $message = sprintf(
+ $message,
+ '[' . $dumper->describeValue($first) .
+ '] and [' . $dumper->describeValue($second) .
+ '] should reference the same object');
+ return $this->assertTrue(
+ SimpleTestCompatibility::isReference($first, $second),
+ $message);
+ }
+
+ /**
+ * Will trigger a pass if both parameters refer
+ * to different objects. Fail otherwise. The objects
+ * have to be identical though.
+ * @param mixed $first Object reference to check.
+ * @param mixed $second Hopefully not the same object.
+ * @param string $message Message to display.
+ * @return boolean True on pass
+ * @access public
+ */
+ function assertClone(&$first, &$second, $message = '%s') {
+ $dumper = &new SimpleDumper();
+ $message = sprintf(
+ $message,
+ '[' . $dumper->describeValue($first) .
+ '] and [' . $dumper->describeValue($second) .
+ '] should not be the same object');
+ $identical = &new IdenticalExpectation($first);
+ return $this->assertTrue(
+ $identical->test($second) &&
+ ! SimpleTestCompatibility::isReference($first, $second),
+ $message);
+ }
+
+ /**
+ * @deprecated
+ */
+ function assertCopy(&$first, &$second, $message = "%s") {
+ $dumper = &new SimpleDumper();
+ $message = sprintf(
+ $message,
+ "[" . $dumper->describeValue($first) .
+ "] and [" . $dumper->describeValue($second) .
+ "] should not be the same object");
+ return $this->assertFalse(
+ SimpleTestCompatibility::isReference($first, $second),
+ $message);
+ }
+
+ /**
+ * Will trigger a pass if the Perl regex pattern
+ * is found in the subject. Fail otherwise.
+ * @param string $pattern Perl regex to look for including
+ * the regex delimiters.
+ * @param string $subject String to search in.
+ * @param string $message Message to display.
+ * @return boolean True on pass
+ * @access public
+ */
+ function assertPattern($pattern, $subject, $message = '%s') {
+ return $this->assert(
+ new PatternExpectation($pattern),
+ $subject,
+ $message);
+ }
+
+ /**
+ * @deprecated
+ */
+ function assertWantedPattern($pattern, $subject, $message = '%s') {
+ return $this->assertPattern($pattern, $subject, $message);
+ }
+
+ /**
+ * Will trigger a pass if the perl regex pattern
+ * is not present in subject. Fail if found.
+ * @param string $pattern Perl regex to look for including
+ * the regex delimiters.
+ * @param string $subject String to search in.
+ * @param string $message Message to display.
+ * @return boolean True on pass
+ * @access public
+ */
+ function assertNoPattern($pattern, $subject, $message = '%s') {
+ return $this->assert(
+ new NoPatternExpectation($pattern),
+ $subject,
+ $message);
+ }
+
+ /**
+ * @deprecated
+ */
+ function assertNoUnwantedPattern($pattern, $subject, $message = '%s') {
+ return $this->assertNoPattern($pattern, $subject, $message);
+ }
+
+ /**
+ * @deprecated
+ */
+ function swallowErrors() {
+ $context = &SimpleTest::getContext();
+ $queue = &$context->get('SimpleErrorQueue');
+ $queue->clear();
+ }
+
+ /**
+ * @deprecated
+ */
+ function assertNoErrors($message = '%s') {
+ $context = &SimpleTest::getContext();
+ $queue = &$context->get('SimpleErrorQueue');
+ return $queue->assertNoErrors($message);
+ }
+
+ /**
+ * @deprecated
+ */
+ function assertError($expected = false, $message = '%s') {
+ $context = &SimpleTest::getContext();
+ $queue = &$context->get('SimpleErrorQueue');
+ return $queue->assertError($this->_coerceExpectation($expected), $message);
+ }
+
+ /**
+ * Prepares for an error. If the error mismatches it
+ * passes through, otherwise it is swallowed. Any
+ * left over errors trigger failures.
+ * @param SimpleExpectation/string $expected The error to match.
+ * @param string $message Message on failure.
+ * @access public
+ */
+ function expectError($expected = false, $message = '%s') {
+ $context = &SimpleTest::getContext();
+ $queue = &$context->get('SimpleErrorQueue');
+ $queue->expectError($this->_coerceExpectation($expected), $message);
+ }
+
+ /**
+ * Prepares for an exception. If the error mismatches it
+ * passes through, otherwise it is swallowed. Any
+ * left over errors trigger failures.
+ * @param SimpleExpectation/Exception $expected The error to match.
+ * @param string $message Message on failure.
+ * @access public
+ */
+ function expectException($expected = false, $message = '%s') {
+ $context = &SimpleTest::getContext();
+ $queue = &$context->get('SimpleExceptionTrap');
+ // :HACK: Directly substituting in seems to cause a segfault with
+ // Zend Optimizer on some systems
+ $line = $this->getAssertionLine();
+ $queue->expectException($expected, $message . $line);
+ }
+
+ /**
+ * Creates an equality expectation if the
+ * object/value is not already some type
+ * of expectation.
+ * @param mixed $expected Expected value.
+ * @return SimpleExpectation Expectation object.
+ * @access private
+ */
+ function _coerceExpectation($expected) {
+ if ($expected == false) {
+ return new TrueExpectation();
+ }
+ if (SimpleTestCompatibility::isA($expected, 'SimpleExpectation')) {
+ return $expected;
+ }
+ return new EqualExpectation(
+ is_string($expected) ? str_replace('%', '%%', $expected) : $expected);
+ }
+
+ /**
+ * @deprecated
+ */
+ function assertErrorPattern($pattern, $message = '%s') {
+ return $this->assertError(new PatternExpectation($pattern), $message);
+ }
+}
+?> \ No newline at end of file
diff --git a/site/vendors/simpletest/url.php b/site/vendors/simpletest/url.php
new file mode 100644
index 0000000..0ea2204
--- /dev/null
+++ b/site/vendors/simpletest/url.php
@@ -0,0 +1,528 @@
+<?php
+/**
+ * base include file for SimpleTest
+ * @package SimpleTest
+ * @subpackage WebTester
+ * @version $Id: url.php 1723 2008-04-08 00:34:10Z lastcraft $
+ */
+
+/**#@+
+ * include other SimpleTest class files
+ */
+require_once(dirname(__FILE__) . '/encoding.php');
+/**#@-*/
+
+/**
+ * URL parser to replace parse_url() PHP function which
+ * got broken in PHP 4.3.0. Adds some browser specific
+ * functionality such as expandomatics.
+ * Guesses a bit trying to separate the host from
+ * the path and tries to keep a raw, possibly unparsable,
+ * request string as long as possible.
+ * @package SimpleTest
+ * @subpackage WebTester
+ */
+class SimpleUrl {
+ var $_scheme;
+ var $_username;
+ var $_password;
+ var $_host;
+ var $_port;
+ var $_path;
+ var $_request;
+ var $_fragment;
+ var $_x;
+ var $_y;
+ var $_target;
+ var $_raw = false;
+
+ /**
+ * Constructor. Parses URL into sections.
+ * @param string $url Incoming URL.
+ * @access public
+ */
+ function SimpleUrl($url = '') {
+ list($x, $y) = $this->_chompCoordinates($url);
+ $this->setCoordinates($x, $y);
+ $this->_scheme = $this->_chompScheme($url);
+ list($this->_username, $this->_password) = $this->_chompLogin($url);
+ $this->_host = $this->_chompHost($url);
+ $this->_port = false;
+ if (preg_match('/(.*?):(.*)/', $this->_host, $host_parts)) {
+ $this->_host = $host_parts[1];
+ $this->_port = (integer)$host_parts[2];
+ }
+ $this->_path = $this->_chompPath($url);
+ $this->_request = $this->_parseRequest($this->_chompRequest($url));
+ $this->_fragment = (strncmp($url, "#", 1) == 0 ? substr($url, 1) : false);
+ $this->_target = false;
+ }
+
+ /**
+ * Extracts the X, Y coordinate pair from an image map.
+ * @param string $url URL so far. The coordinates will be
+ * removed.
+ * @return array X, Y as a pair of integers.
+ * @access private
+ */
+ function _chompCoordinates(&$url) {
+ if (preg_match('/(.*)\?(\d+),(\d+)$/', $url, $matches)) {
+ $url = $matches[1];
+ return array((integer)$matches[2], (integer)$matches[3]);
+ }
+ return array(false, false);
+ }
+
+ /**
+ * Extracts the scheme part of an incoming URL.
+ * @param string $url URL so far. The scheme will be
+ * removed.
+ * @return string Scheme part or false.
+ * @access private
+ */
+ function _chompScheme(&$url) {
+ if (preg_match('/^([^\/:]*):(\/\/)(.*)/', $url, $matches)) {
+ $url = $matches[2] . $matches[3];
+ return $matches[1];
+ }
+ return false;
+ }
+
+ /**
+ * Extracts the username and password from the
+ * incoming URL. The // prefix will be reattached
+ * to the URL after the doublet is extracted.
+ * @param string $url URL so far. The username and
+ * password are removed.
+ * @return array Two item list of username and
+ * password. Will urldecode() them.
+ * @access private
+ */
+ function _chompLogin(&$url) {
+ $prefix = '';
+ if (preg_match('/^(\/\/)(.*)/', $url, $matches)) {
+ $prefix = $matches[1];
+ $url = $matches[2];
+ }
+ if (preg_match('/^([^\/]*)@(.*)/', $url, $matches)) {
+ $url = $prefix . $matches[2];
+ $parts = split(":", $matches[1]);
+ return array(
+ urldecode($parts[0]),
+ isset($parts[1]) ? urldecode($parts[1]) : false);
+ }
+ $url = $prefix . $url;
+ return array(false, false);
+ }
+
+ /**
+ * Extracts the host part of an incoming URL.
+ * Includes the port number part. Will extract
+ * the host if it starts with // or it has
+ * a top level domain or it has at least two
+ * dots.
+ * @param string $url URL so far. The host will be
+ * removed.
+ * @return string Host part guess or false.
+ * @access private
+ */
+ function _chompHost(&$url) {
+ if (preg_match('/^(\/\/)(.*?)(\/.*|\?.*|#.*|$)/', $url, $matches)) {
+ $url = $matches[3];
+ return $matches[2];
+ }
+ if (preg_match('/(.*?)(\.\.\/|\.\/|\/|\?|#|$)(.*)/', $url, $matches)) {
+ $tlds = SimpleUrl::getAllTopLevelDomains();
+ if (preg_match('/[a-z0-9\-]+\.(' . $tlds . ')/i', $matches[1])) {
+ $url = $matches[2] . $matches[3];
+ return $matches[1];
+ } elseif (preg_match('/[a-z0-9\-]+\.[a-z0-9\-]+\.[a-z0-9\-]+/i', $matches[1])) {
+ $url = $matches[2] . $matches[3];
+ return $matches[1];
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Extracts the path information from the incoming
+ * URL. Strips this path from the URL.
+ * @param string $url URL so far. The host will be
+ * removed.
+ * @return string Path part or '/'.
+ * @access private
+ */
+ function _chompPath(&$url) {
+ if (preg_match('/(.*?)(\?|#|$)(.*)/', $url, $matches)) {
+ $url = $matches[2] . $matches[3];
+ return ($matches[1] ? $matches[1] : '');
+ }
+ return '';
+ }
+
+ /**
+ * Strips off the request data.
+ * @param string $url URL so far. The request will be
+ * removed.
+ * @return string Raw request part.
+ * @access private
+ */
+ function _chompRequest(&$url) {
+ if (preg_match('/\?(.*?)(#|$)(.*)/', $url, $matches)) {
+ $url = $matches[2] . $matches[3];
+ return $matches[1];
+ }
+ return '';
+ }
+
+ /**
+ * Breaks the request down into an object.
+ * @param string $raw Raw request.
+ * @return SimpleFormEncoding Parsed data.
+ * @access private
+ */
+ function _parseRequest($raw) {
+ $this->_raw = $raw;
+ $request = new SimpleGetEncoding();
+ foreach (split("&", $raw) as $pair) {
+ if (preg_match('/(.*?)=(.*)/', $pair, $matches)) {
+ $request->add($matches[1], urldecode($matches[2]));
+ } elseif ($pair) {
+ $request->add($pair, '');
+ }
+ }
+ return $request;
+ }
+
+ /**
+ * Accessor for protocol part.
+ * @param string $default Value to use if not present.
+ * @return string Scheme name, e.g "http".
+ * @access public
+ */
+ function getScheme($default = false) {
+ return $this->_scheme ? $this->_scheme : $default;
+ }
+
+ /**
+ * Accessor for user name.
+ * @return string Username preceding host.
+ * @access public
+ */
+ function getUsername() {
+ return $this->_username;
+ }
+
+ /**
+ * Accessor for password.
+ * @return string Password preceding host.
+ * @access public
+ */
+ function getPassword() {
+ return $this->_password;
+ }
+
+ /**
+ * Accessor for hostname and port.
+ * @param string $default Value to use if not present.
+ * @return string Hostname only.
+ * @access public
+ */
+ function getHost($default = false) {
+ return $this->_host ? $this->_host : $default;
+ }
+
+ /**
+ * Accessor for top level domain.
+ * @return string Last part of host.
+ * @access public
+ */
+ function getTld() {
+ $path_parts = pathinfo($this->getHost());
+ return (isset($path_parts['extension']) ? $path_parts['extension'] : false);
+ }
+
+ /**
+ * Accessor for port number.
+ * @return integer TCP/IP port number.
+ * @access public
+ */
+ function getPort() {
+ return $this->_port;
+ }
+
+ /**
+ * Accessor for path.
+ * @return string Full path including leading slash if implied.
+ * @access public
+ */
+ function getPath() {
+ if (! $this->_path && $this->_host) {
+ return '/';
+ }
+ return $this->_path;
+ }
+
+ /**
+ * Accessor for page if any. This may be a
+ * directory name if ambiguious.
+ * @return Page name.
+ * @access public
+ */
+ function getPage() {
+ if (! preg_match('/([^\/]*?)$/', $this->getPath(), $matches)) {
+ return false;
+ }
+ return $matches[1];
+ }
+
+ /**
+ * Gets the path to the page.
+ * @return string Path less the page.
+ * @access public
+ */
+ function getBasePath() {
+ if (! preg_match('/(.*\/)[^\/]*?$/', $this->getPath(), $matches)) {
+ return false;
+ }
+ return $matches[1];
+ }
+
+ /**
+ * Accessor for fragment at end of URL after the "#".
+ * @return string Part after "#".
+ * @access public
+ */
+ function getFragment() {
+ return $this->_fragment;
+ }
+
+ /**
+ * Sets image coordinates. Set to false to clear
+ * them.
+ * @param integer $x Horizontal position.
+ * @param integer $y Vertical position.
+ * @access public
+ */
+ function setCoordinates($x = false, $y = false) {
+ if (($x === false) || ($y === false)) {
+ $this->_x = $this->_y = false;
+ return;
+ }
+ $this->_x = (integer)$x;
+ $this->_y = (integer)$y;
+ }
+
+ /**
+ * Accessor for horizontal image coordinate.
+ * @return integer X value.
+ * @access public
+ */
+ function getX() {
+ return $this->_x;
+ }
+
+ /**
+ * Accessor for vertical image coordinate.
+ * @return integer Y value.
+ * @access public
+ */
+ function getY() {
+ return $this->_y;
+ }
+
+ /**
+ * Accessor for current request parameters
+ * in URL string form. Will return teh original request
+ * if at all possible even if it doesn't make much
+ * sense.
+ * @return string Form is string "?a=1&b=2", etc.
+ * @access public
+ */
+ function getEncodedRequest() {
+ if ($this->_raw) {
+ $encoded = $this->_raw;
+ } else {
+ $encoded = $this->_request->asUrlRequest();
+ }
+ if ($encoded) {
+ return '?' . preg_replace('/^\?/', '', $encoded);
+ }
+ return '';
+ }
+
+ /**
+ * Adds an additional parameter to the request.
+ * @param string $key Name of parameter.
+ * @param string $value Value as string.
+ * @access public
+ */
+ function addRequestParameter($key, $value) {
+ $this->_raw = false;
+ $this->_request->add($key, $value);
+ }
+
+ /**
+ * Adds additional parameters to the request.
+ * @param hash/SimpleFormEncoding $parameters Additional
+ * parameters.
+ * @access public
+ */
+ function addRequestParameters($parameters) {
+ $this->_raw = false;
+ $this->_request->merge($parameters);
+ }
+
+ /**
+ * Clears down all parameters.
+ * @access public
+ */
+ function clearRequest() {
+ $this->_raw = false;
+ $this->_request = &new SimpleGetEncoding();
+ }
+
+ /**
+ * Gets the frame target if present. Although
+ * not strictly part of the URL specification it
+ * acts as similarily to the browser.
+ * @return boolean/string Frame name or false if none.
+ * @access public
+ */
+ function getTarget() {
+ return $this->_target;
+ }
+
+ /**
+ * Attaches a frame target.
+ * @param string $frame Name of frame.
+ * @access public
+ */
+ function setTarget($frame) {
+ $this->_raw = false;
+ $this->_target = $frame;
+ }
+
+ /**
+ * Renders the URL back into a string.
+ * @return string URL in canonical form.
+ * @access public
+ */
+ function asString() {
+ $path = $this->_path;
+ $scheme = $identity = $host = $encoded = $fragment = '';
+ if ($this->_username && $this->_password) {
+ $identity = $this->_username . ':' . $this->_password . '@';
+ }
+ if ($this->getHost()) {
+ $scheme = $this->getScheme() ? $this->getScheme() : 'http';
+ $scheme .= "://";
+ $host = $this->getHost();
+ }
+ if (substr($this->_path, 0, 1) == '/') {
+ $path = $this->normalisePath($this->_path);
+ }
+ $encoded = $this->getEncodedRequest();
+ $fragment = $this->getFragment() ? '#'. $this->getFragment() : '';
+ $coords = $this->getX() === false ? '' : '?' . $this->getX() . ',' . $this->getY();
+ return "$scheme$identity$host$path$encoded$fragment$coords";
+ }
+
+ /**
+ * Replaces unknown sections to turn a relative
+ * URL into an absolute one. The base URL can
+ * be either a string or a SimpleUrl object.
+ * @param string/SimpleUrl $base Base URL.
+ * @access public
+ */
+ function makeAbsolute($base) {
+ if (! is_object($base)) {
+ $base = new SimpleUrl($base);
+ }
+ if ($this->getHost()) {
+ $scheme = $this->getScheme();
+ $host = $this->getHost();
+ $port = $this->getPort() ? ':' . $this->getPort() : '';
+ $identity = $this->getIdentity() ? $this->getIdentity() . '@' : '';
+ if (! $identity) {
+ $identity = $base->getIdentity() ? $base->getIdentity() . '@' : '';
+ }
+ } else {
+ $scheme = $base->getScheme();
+ $host = $base->getHost();
+ $port = $base->getPort() ? ':' . $base->getPort() : '';
+ $identity = $base->getIdentity() ? $base->getIdentity() . '@' : '';
+ }
+ $path = $this->normalisePath($this->_extractAbsolutePath($base));
+ $encoded = $this->getEncodedRequest();
+ $fragment = $this->getFragment() ? '#'. $this->getFragment() : '';
+ $coords = $this->getX() === false ? '' : '?' . $this->getX() . ',' . $this->getY();
+ return new SimpleUrl("$scheme://$identity$host$port$path$encoded$fragment$coords");
+ }
+
+ /**
+ * Replaces unknown sections of the path with base parts
+ * to return a complete absolute one.
+ * @param string/SimpleUrl $base Base URL.
+ * @param string Absolute path.
+ * @access private
+ */
+ function _extractAbsolutePath($base) {
+ if ($this->getHost()) {
+ return $this->_path;
+ }
+ if (! $this->_isRelativePath($this->_path)) {
+ return $this->_path;
+ }
+ if ($this->_path) {
+ return $base->getBasePath() . $this->_path;
+ }
+ return $base->getPath();
+ }
+
+ /**
+ * Simple test to see if a path part is relative.
+ * @param string $path Path to test.
+ * @return boolean True if starts with a "/".
+ * @access private
+ */
+ function _isRelativePath($path) {
+ return (substr($path, 0, 1) != '/');
+ }
+
+ /**
+ * Extracts the username and password for use in rendering
+ * a URL.
+ * @return string/boolean Form of username:password or false.
+ * @access public
+ */
+ function getIdentity() {
+ if ($this->_username && $this->_password) {
+ return $this->_username . ':' . $this->_password;
+ }
+ return false;
+ }
+
+ /**
+ * Replaces . and .. sections of the path.
+ * @param string $path Unoptimised path.
+ * @return string Path with dots removed if possible.
+ * @access public
+ */
+ function normalisePath($path) {
+ $path = preg_replace('|/\./|', '/', $path);
+ return preg_replace('|/[^/]+/\.\./|', '/', $path);
+ }
+
+ /**
+ * A pipe seperated list of all TLDs that result in two part
+ * domain names.
+ * @return string Pipe separated list.
+ * @access public
+ * @static
+ */
+ function getAllTopLevelDomains() {
+ return 'com|edu|net|org|gov|mil|int|biz|info|name|pro|aero|coop|museum';
+ }
+}
+?> \ No newline at end of file
diff --git a/site/vendors/simpletest/user_agent.php b/site/vendors/simpletest/user_agent.php
new file mode 100644
index 0000000..b3f6f05
--- /dev/null
+++ b/site/vendors/simpletest/user_agent.php
@@ -0,0 +1,332 @@
+<?php
+/**
+ * Base include file for SimpleTest
+ * @package SimpleTest
+ * @subpackage WebTester
+ * @version $Id: user_agent.php 1723 2008-04-08 00:34:10Z lastcraft $
+ */
+
+/**#@+
+ * include other SimpleTest class files
+ */
+require_once(dirname(__FILE__) . '/cookies.php');
+require_once(dirname(__FILE__) . '/http.php');
+require_once(dirname(__FILE__) . '/encoding.php');
+require_once(dirname(__FILE__) . '/authentication.php');
+/**#@-*/
+
+if (! defined('DEFAULT_MAX_REDIRECTS')) {
+ define('DEFAULT_MAX_REDIRECTS', 3);
+}
+if (! defined('DEFAULT_CONNECTION_TIMEOUT')) {
+ define('DEFAULT_CONNECTION_TIMEOUT', 15);
+}
+
+/**
+ * Fetches web pages whilst keeping track of
+ * cookies and authentication.
+ * @package SimpleTest
+ * @subpackage WebTester
+ */
+class SimpleUserAgent {
+ var $_cookie_jar;
+ var $_cookies_enabled = true;
+ var $_authenticator;
+ var $_max_redirects = DEFAULT_MAX_REDIRECTS;
+ var $_proxy = false;
+ var $_proxy_username = false;
+ var $_proxy_password = false;
+ var $_connection_timeout = DEFAULT_CONNECTION_TIMEOUT;
+ var $_additional_headers = array();
+
+ /**
+ * Starts with no cookies, realms or proxies.
+ * @access public
+ */
+ function SimpleUserAgent() {
+ $this->_cookie_jar = &new SimpleCookieJar();
+ $this->_authenticator = &new SimpleAuthenticator();
+ }
+
+ /**
+ * Removes expired and temporary cookies as if
+ * the browser was closed and re-opened. Authorisation
+ * has to be obtained again as well.
+ * @param string/integer $date Time when session restarted.
+ * If omitted then all persistent
+ * cookies are kept.
+ * @access public
+ */
+ function restart($date = false) {
+ $this->_cookie_jar->restartSession($date);
+ $this->_authenticator->restartSession();
+ }
+
+ /**
+ * Adds a header to every fetch.
+ * @param string $header Header line to add to every
+ * request until cleared.
+ * @access public
+ */
+ function addHeader($header) {
+ $this->_additional_headers[] = $header;
+ }
+
+ /**
+ * Ages the cookies by the specified time.
+ * @param integer $interval Amount in seconds.
+ * @access public
+ */
+ function ageCookies($interval) {
+ $this->_cookie_jar->agePrematurely($interval);
+ }
+
+ /**
+ * Sets an additional cookie. If a cookie has
+ * the same name and path it is replaced.
+ * @param string $name Cookie key.
+ * @param string $value Value of cookie.
+ * @param string $host Host upon which the cookie is valid.
+ * @param string $path Cookie path if not host wide.
+ * @param string $expiry Expiry date.
+ * @access public
+ */
+ function setCookie($name, $value, $host = false, $path = '/', $expiry = false) {
+ $this->_cookie_jar->setCookie($name, $value, $host, $path, $expiry);
+ }
+
+ /**
+ * Reads the most specific cookie value from the
+ * browser cookies.
+ * @param string $host Host to search.
+ * @param string $path Applicable path.
+ * @param string $name Name of cookie to read.
+ * @return string False if not present, else the
+ * value as a string.
+ * @access public
+ */
+ function getCookieValue($host, $path, $name) {
+ return $this->_cookie_jar->getCookieValue($host, $path, $name);
+ }
+
+ /**
+ * Reads the current cookies within the base URL.
+ * @param string $name Key of cookie to find.
+ * @param SimpleUrl $base Base URL to search from.
+ * @return string/boolean Null if there is no base URL, false
+ * if the cookie is not set.
+ * @access public
+ */
+ function getBaseCookieValue($name, $base) {
+ if (! $base) {
+ return null;
+ }
+ return $this->getCookieValue($base->getHost(), $base->getPath(), $name);
+ }
+
+ /**
+ * Switches off cookie sending and recieving.
+ * @access public
+ */
+ function ignoreCookies() {
+ $this->_cookies_enabled = false;
+ }
+
+ /**
+ * Switches back on the cookie sending and recieving.
+ * @access public
+ */
+ function useCookies() {
+ $this->_cookies_enabled = true;
+ }
+
+ /**
+ * Sets the socket timeout for opening a connection.
+ * @param integer $timeout Maximum time in seconds.
+ * @access public
+ */
+ function setConnectionTimeout($timeout) {
+ $this->_connection_timeout = $timeout;
+ }
+
+ /**
+ * Sets the maximum number of redirects before
+ * a page will be loaded anyway.
+ * @param integer $max Most hops allowed.
+ * @access public
+ */
+ function setMaximumRedirects($max) {
+ $this->_max_redirects = $max;
+ }
+
+ /**
+ * Sets proxy to use on all requests for when
+ * testing from behind a firewall. Set URL
+ * to false to disable.
+ * @param string $proxy Proxy URL.
+ * @param string $username Proxy username for authentication.
+ * @param string $password Proxy password for authentication.
+ * @access public
+ */
+ function useProxy($proxy, $username, $password) {
+ if (! $proxy) {
+ $this->_proxy = false;
+ return;
+ }
+ if ((strncmp($proxy, 'http://', 7) != 0) && (strncmp($proxy, 'https://', 8) != 0)) {
+ $proxy = 'http://'. $proxy;
+ }
+ $this->_proxy = &new SimpleUrl($proxy);
+ $this->_proxy_username = $username;
+ $this->_proxy_password = $password;
+ }
+
+ /**
+ * Test to see if the redirect limit is passed.
+ * @param integer $redirects Count so far.
+ * @return boolean True if over.
+ * @access private
+ */
+ function _isTooManyRedirects($redirects) {
+ return ($redirects > $this->_max_redirects);
+ }
+
+ /**
+ * Sets the identity for the current realm.
+ * @param string $host Host to which realm applies.
+ * @param string $realm Full name of realm.
+ * @param string $username Username for realm.
+ * @param string $password Password for realm.
+ * @access public
+ */
+ function setIdentity($host, $realm, $username, $password) {
+ $this->_authenticator->setIdentityForRealm($host, $realm, $username, $password);
+ }
+
+ /**
+ * Fetches a URL as a response object. Will keep trying if redirected.
+ * It will also collect authentication realm information.
+ * @param string/SimpleUrl $url Target to fetch.
+ * @param SimpleEncoding $encoding Additional parameters for request.
+ * @return SimpleHttpResponse Hopefully the target page.
+ * @access public
+ */
+ function &fetchResponse($url, $encoding) {
+ if ($encoding->getMethod() != 'POST') {
+ $url->addRequestParameters($encoding);
+ $encoding->clear();
+ }
+ $response = &$this->_fetchWhileRedirected($url, $encoding);
+ if ($headers = $response->getHeaders()) {
+ if ($headers->isChallenge()) {
+ $this->_authenticator->addRealm(
+ $url,
+ $headers->getAuthentication(),
+ $headers->getRealm());
+ }
+ }
+ return $response;
+ }
+
+ /**
+ * Fetches the page until no longer redirected or
+ * until the redirect limit runs out.
+ * @param SimpleUrl $url Target to fetch.
+ * @param SimpelFormEncoding $encoding Additional parameters for request.
+ * @return SimpleHttpResponse Hopefully the target page.
+ * @access private
+ */
+ function &_fetchWhileRedirected($url, $encoding) {
+ $redirects = 0;
+ do {
+ $response = &$this->_fetch($url, $encoding);
+ if ($response->isError()) {
+ return $response;
+ }
+ $headers = $response->getHeaders();
+ $location = new SimpleUrl($headers->getLocation());
+ $url = $location->makeAbsolute($url);
+ if ($this->_cookies_enabled) {
+ $headers->writeCookiesToJar($this->_cookie_jar, $url);
+ }
+ if (! $headers->isRedirect()) {
+ break;
+ }
+ $encoding = new SimpleGetEncoding();
+ } while (! $this->_isTooManyRedirects(++$redirects));
+ return $response;
+ }
+
+ /**
+ * Actually make the web request.
+ * @param SimpleUrl $url Target to fetch.
+ * @param SimpleFormEncoding $encoding Additional parameters for request.
+ * @return SimpleHttpResponse Headers and hopefully content.
+ * @access protected
+ */
+ function &_fetch($url, $encoding) {
+ $request = &$this->_createRequest($url, $encoding);
+ $response = &$request->fetch($this->_connection_timeout);
+ return $response;
+ }
+
+ /**
+ * Creates a full page request.
+ * @param SimpleUrl $url Target to fetch as url object.
+ * @param SimpleFormEncoding $encoding POST/GET parameters.
+ * @return SimpleHttpRequest New request.
+ * @access private
+ */
+ function &_createRequest($url, $encoding) {
+ $request = &$this->_createHttpRequest($url, $encoding);
+ $this->_addAdditionalHeaders($request);
+ if ($this->_cookies_enabled) {
+ $request->readCookiesFromJar($this->_cookie_jar, $url);
+ }
+ $this->_authenticator->addHeaders($request, $url);
+ return $request;
+ }
+
+ /**
+ * Builds the appropriate HTTP request object.
+ * @param SimpleUrl $url Target to fetch as url object.
+ * @param SimpleFormEncoding $parameters POST/GET parameters.
+ * @return SimpleHttpRequest New request object.
+ * @access protected
+ */
+ function &_createHttpRequest($url, $encoding) {
+ $request = &new SimpleHttpRequest($this->_createRoute($url), $encoding);
+ return $request;
+ }
+
+ /**
+ * Sets up either a direct route or via a proxy.
+ * @param SimpleUrl $url Target to fetch as url object.
+ * @return SimpleRoute Route to take to fetch URL.
+ * @access protected
+ */
+ function &_createRoute($url) {
+ if ($this->_proxy) {
+ $route = &new SimpleProxyRoute(
+ $url,
+ $this->_proxy,
+ $this->_proxy_username,
+ $this->_proxy_password);
+ } else {
+ $route = &new SimpleRoute($url);
+ }
+ return $route;
+ }
+
+ /**
+ * Adds additional manual headers.
+ * @param SimpleHttpRequest $request Outgoing request.
+ * @access private
+ */
+ function _addAdditionalHeaders(&$request) {
+ foreach ($this->_additional_headers as $header) {
+ $request->addHeaderLine($header);
+ }
+ }
+}
+?> \ No newline at end of file
diff --git a/site/vendors/simpletest/web_tester.php b/site/vendors/simpletest/web_tester.php
new file mode 100644
index 0000000..40b1612
--- /dev/null
+++ b/site/vendors/simpletest/web_tester.php
@@ -0,0 +1,1541 @@
+<?php
+/**
+ * Base include file for SimpleTest.
+ * @package SimpleTest
+ * @subpackage WebTester
+ * @version $Id: web_tester.php 1723 2008-04-08 00:34:10Z lastcraft $
+ */
+
+/**#@+
+ * include other SimpleTest class files
+ */
+require_once(dirname(__FILE__) . '/test_case.php');
+require_once(dirname(__FILE__) . '/browser.php');
+require_once(dirname(__FILE__) . '/page.php');
+require_once(dirname(__FILE__) . '/expectation.php');
+/**#@-*/
+
+/**
+ * Test for an HTML widget value match.
+ * @package SimpleTest
+ * @subpackage WebTester
+ */
+class FieldExpectation extends SimpleExpectation {
+ var $_value;
+
+ /**
+ * Sets the field value to compare against.
+ * @param mixed $value Test value to match. Can be an
+ * expectation for say pattern matching.
+ * @param string $message Optiona message override. Can use %s as
+ * a placeholder for the original message.
+ * @access public
+ */
+ function FieldExpectation($value, $message = '%s') {
+ $this->SimpleExpectation($message);
+ if (is_array($value)) {
+ sort($value);
+ }
+ $this->_value = $value;
+ }
+
+ /**
+ * Tests the expectation. True if it matches
+ * a string value or an array value in any order.
+ * @param mixed $compare Comparison value. False for
+ * an unset field.
+ * @return boolean True if correct.
+ * @access public
+ */
+ function test($compare) {
+ if ($this->_value === false) {
+ return ($compare === false);
+ }
+ if ($this->_isSingle($this->_value)) {
+ return $this->_testSingle($compare);
+ }
+ if (is_array($this->_value)) {
+ return $this->_testMultiple($compare);
+ }
+ return false;
+ }
+
+ /**
+ * Tests for valid field comparisons with a single option.
+ * @param mixed $value Value to type check.
+ * @return boolean True if integer, string or float.
+ * @access private
+ */
+ function _isSingle($value) {
+ return is_string($value) || is_integer($value) || is_float($value);
+ }
+
+ /**
+ * String comparison for simple field with a single option.
+ * @param mixed $compare String to test against.
+ * @returns boolean True if matching.
+ * @access private
+ */
+ function _testSingle($compare) {
+ if (is_array($compare) && count($compare) == 1) {
+ $compare = $compare[0];
+ }
+ if (! $this->_isSingle($compare)) {
+ return false;
+ }
+ return ($this->_value == $compare);
+ }
+
+ /**
+ * List comparison for multivalue field.
+ * @param mixed $compare List in any order to test against.
+ * @returns boolean True if matching.
+ * @access private
+ */
+ function _testMultiple($compare) {
+ if (is_string($compare)) {
+ $compare = array($compare);
+ }
+ if (! is_array($compare)) {
+ return false;
+ }
+ sort($compare);
+ return ($this->_value === $compare);
+ }
+
+ /**
+ * Returns a human readable test message.
+ * @param mixed $compare Comparison value.
+ * @return string Description of success
+ * or failure.
+ * @access public
+ */
+ function testMessage($compare) {
+ $dumper = &$this->_getDumper();
+ if (is_array($compare)) {
+ sort($compare);
+ }
+ if ($this->test($compare)) {
+ return "Field expectation [" . $dumper->describeValue($this->_value) . "]";
+ } else {
+ return "Field expectation [" . $dumper->describeValue($this->_value) .
+ "] fails with [" .
+ $dumper->describeValue($compare) . "] " .
+ $dumper->describeDifference($this->_value, $compare);
+ }
+ }
+}
+
+/**
+ * Test for a specific HTTP header within a header block.
+ * @package SimpleTest
+ * @subpackage WebTester
+ */
+class HttpHeaderExpectation extends SimpleExpectation {
+ var $_expected_header;
+ var $_expected_value;
+
+ /**
+ * Sets the field and value to compare against.
+ * @param string $header Case insenstive trimmed header name.
+ * @param mixed $value Optional value to compare. If not
+ * given then any value will match. If
+ * an expectation object then that will
+ * be used instead.
+ * @param string $message Optiona message override. Can use %s as
+ * a placeholder for the original message.
+ */
+ function HttpHeaderExpectation($header, $value = false, $message = '%s') {
+ $this->SimpleExpectation($message);
+ $this->_expected_header = $this->_normaliseHeader($header);
+ $this->_expected_value = $value;
+ }
+
+ /**
+ * Accessor for aggregated object.
+ * @return mixed Expectation set in constructor.
+ * @access protected
+ */
+ function _getExpectation() {
+ return $this->_expected_value;
+ }
+
+ /**
+ * Removes whitespace at ends and case variations.
+ * @param string $header Name of header.
+ * @param string Trimmed and lowecased header
+ * name.
+ * @access private
+ */
+ function _normaliseHeader($header) {
+ return strtolower(trim($header));
+ }
+
+ /**
+ * Tests the expectation. True if it matches
+ * a string value or an array value in any order.
+ * @param mixed $compare Raw header block to search.
+ * @return boolean True if header present.
+ * @access public
+ */
+ function test($compare) {
+ return is_string($this->_findHeader($compare));
+ }
+
+ /**
+ * Searches the incoming result. Will extract the matching
+ * line as text.
+ * @param mixed $compare Raw header block to search.
+ * @return string Matching header line.
+ * @access protected
+ */
+ function _findHeader($compare) {
+ $lines = split("\r\n", $compare);
+ foreach ($lines as $line) {
+ if ($this->_testHeaderLine($line)) {
+ return $line;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Compares a single header line against the expectation.
+ * @param string $line A single line to compare.
+ * @return boolean True if matched.
+ * @access private
+ */
+ function _testHeaderLine($line) {
+ if (count($parsed = split(':', $line, 2)) < 2) {
+ return false;
+ }
+ list($header, $value) = $parsed;
+ if ($this->_normaliseHeader($header) != $this->_expected_header) {
+ return false;
+ }
+ return $this->_testHeaderValue($value, $this->_expected_value);
+ }
+
+ /**
+ * Tests the value part of the header.
+ * @param string $value Value to test.
+ * @param mixed $expected Value to test against.
+ * @return boolean True if matched.
+ * @access protected
+ */
+ function _testHeaderValue($value, $expected) {
+ if ($expected === false) {
+ return true;
+ }
+ if (SimpleExpectation::isExpectation($expected)) {
+ return $expected->test(trim($value));
+ }
+ return (trim($value) == trim($expected));
+ }
+
+ /**
+ * Returns a human readable test message.
+ * @param mixed $compare Raw header block to search.
+ * @return string Description of success
+ * or failure.
+ * @access public
+ */
+ function testMessage($compare) {
+ if (SimpleExpectation::isExpectation($this->_expected_value)) {
+ $message = $this->_expected_value->overlayMessage($compare, $this->_getDumper());
+ } else {
+ $message = $this->_expected_header .
+ ($this->_expected_value ? ': ' . $this->_expected_value : '');
+ }
+ if (is_string($line = $this->_findHeader($compare))) {
+ return "Searching for header [$message] found [$line]";
+ } else {
+ return "Failed to find header [$message]";
+ }
+ }
+}
+
+/**
+ * Test for a specific HTTP header within a header block that
+ * should not be found.
+ * @package SimpleTest
+ * @subpackage WebTester
+ */
+class NoHttpHeaderExpectation extends HttpHeaderExpectation {
+ var $_expected_header;
+ var $_expected_value;
+
+ /**
+ * Sets the field and value to compare against.
+ * @param string $unwanted Case insenstive trimmed header name.
+ * @param string $message Optiona message override. Can use %s as
+ * a placeholder for the original message.
+ */
+ function NoHttpHeaderExpectation($unwanted, $message = '%s') {
+ $this->HttpHeaderExpectation($unwanted, false, $message);
+ }
+
+ /**
+ * Tests that the unwanted header is not found.
+ * @param mixed $compare Raw header block to search.
+ * @return boolean True if header present.
+ * @access public
+ */
+ function test($compare) {
+ return ($this->_findHeader($compare) === false);
+ }
+
+ /**
+ * Returns a human readable test message.
+ * @param mixed $compare Raw header block to search.
+ * @return string Description of success
+ * or failure.
+ * @access public
+ */
+ function testMessage($compare) {
+ $expectation = $this->_getExpectation();
+ if (is_string($line = $this->_findHeader($compare))) {
+ return "Found unwanted header [$expectation] with [$line]";
+ } else {
+ return "Did not find unwanted header [$expectation]";
+ }
+ }
+}
+
+/**
+ * Test for a text substring.
+ * @package SimpleTest
+ * @subpackage UnitTester
+ */
+class TextExpectation extends SimpleExpectation {
+ var $_substring;
+
+ /**
+ * Sets the value to compare against.
+ * @param string $substring Text to search for.
+ * @param string $message Customised message on failure.
+ * @access public
+ */
+ function TextExpectation($substring, $message = '%s') {
+ $this->SimpleExpectation($message);
+ $this->_substring = $substring;
+ }
+
+ /**
+ * Accessor for the substring.
+ * @return string Text to match.
+ * @access protected
+ */
+ function _getSubstring() {
+ return $this->_substring;
+ }
+
+ /**
+ * Tests the expectation. True if the text contains the
+ * substring.
+ * @param string $compare Comparison value.
+ * @return boolean True if correct.
+ * @access public
+ */
+ function test($compare) {
+ return (strpos($compare, $this->_substring) !== false);
+ }
+
+ /**
+ * Returns a human readable test message.
+ * @param mixed $compare Comparison value.
+ * @return string Description of success
+ * or failure.
+ * @access public
+ */
+ function testMessage($compare) {
+ if ($this->test($compare)) {
+ return $this->_describeTextMatch($this->_getSubstring(), $compare);
+ } else {
+ $dumper = &$this->_getDumper();
+ return "Text [" . $this->_getSubstring() .
+ "] not detected in [" .
+ $dumper->describeValue($compare) . "]";
+ }
+ }
+
+ /**
+ * Describes a pattern match including the string
+ * found and it's position.
+ * @param string $substring Text to search for.
+ * @param string $subject Subject to search.
+ * @access protected
+ */
+ function _describeTextMatch($substring, $subject) {
+ $position = strpos($subject, $substring);
+ $dumper = &$this->_getDumper();
+ return "Text [$substring] detected at character [$position] in [" .
+ $dumper->describeValue($subject) . "] in region [" .
+ $dumper->clipString($subject, 100, $position) . "]";
+ }
+}
+
+/**
+ * Fail if a substring is detected within the
+ * comparison text.
+ * @package SimpleTest
+ * @subpackage UnitTester
+ */
+class NoTextExpectation extends TextExpectation {
+
+ /**
+ * Sets the reject pattern
+ * @param string $substring Text to search for.
+ * @param string $message Customised message on failure.
+ * @access public
+ */
+ function NoTextExpectation($substring, $message = '%s') {
+ $this->TextExpectation($substring, $message);
+ }
+
+ /**
+ * Tests the expectation. False if the substring appears
+ * in the text.
+ * @param string $compare Comparison value.
+ * @return boolean True if correct.
+ * @access public
+ */
+ function test($compare) {
+ return ! parent::test($compare);
+ }
+
+ /**
+ * Returns a human readable test message.
+ * @param string $compare Comparison value.
+ * @return string Description of success
+ * or failure.
+ * @access public
+ */
+ function testMessage($compare) {
+ if ($this->test($compare)) {
+ $dumper = &$this->_getDumper();
+ return "Text [" . $this->_getSubstring() .
+ "] not detected in [" .
+ $dumper->describeValue($compare) . "]";
+ } else {
+ return $this->_describeTextMatch($this->_getSubstring(), $compare);
+ }
+ }
+}
+
+/**
+ * Test case for testing of web pages. Allows
+ * fetching of pages, parsing of HTML and
+ * submitting forms.
+ * @package SimpleTest
+ * @subpackage WebTester
+ */
+class WebTestCase extends SimpleTestCase {
+ var $_browser;
+ var $_ignore_errors = false;
+
+ /**
+ * Creates an empty test case. Should be subclassed
+ * with test methods for a functional test case.
+ * @param string $label Name of test case. Will use
+ * the class name if none specified.
+ * @access public
+ */
+ function WebTestCase($label = false) {
+ $this->SimpleTestCase($label);
+ }
+
+ /**
+ * Announces the start of the test.
+ * @param string $method Test method just started.
+ * @access public
+ */
+ function before($method) {
+ parent::before($method);
+ $this->setBrowser($this->createBrowser());
+ }
+
+ /**
+ * Announces the end of the test. Includes private clean up.
+ * @param string $method Test method just finished.
+ * @access public
+ */
+ function after($method) {
+ $this->unsetBrowser();
+ parent::after($method);
+ }
+
+ /**
+ * Gets a current browser reference for setting
+ * special expectations or for detailed
+ * examination of page fetches.
+ * @return SimpleBrowser Current test browser object.
+ * @access public
+ */
+ function &getBrowser() {
+ return $this->_browser;
+ }
+
+ /**
+ * Gets a current browser reference for setting
+ * special expectations or for detailed
+ * examination of page fetches.
+ * @param SimpleBrowser $browser New test browser object.
+ * @access public
+ */
+ function setBrowser(&$browser) {
+ return $this->_browser = &$browser;
+ }
+
+ /**
+ * Clears the current browser reference to help the
+ * PHP garbage collector.
+ * @access public
+ */
+ function unsetBrowser() {
+ unset($this->_browser);
+ }
+
+ /**
+ * Creates a new default web browser object.
+ * Will be cleared at the end of the test method.
+ * @return TestBrowser New browser.
+ * @access public
+ */
+ function &createBrowser() {
+ $browser = &new SimpleBrowser();
+ return $browser;
+ }
+
+ /**
+ * Gets the last response error.
+ * @return string Last low level HTTP error.
+ * @access public
+ */
+ function getTransportError() {
+ return $this->_browser->getTransportError();
+ }
+
+ /**
+ * Accessor for the currently selected URL.
+ * @return string Current location or false if
+ * no page yet fetched.
+ * @access public
+ */
+ function getUrl() {
+ return $this->_browser->getUrl();
+ }
+
+ /**
+ * Dumps the current request for debugging.
+ * @access public
+ */
+ function showRequest() {
+ $this->dump($this->_browser->getRequest());
+ }
+
+ /**
+ * Dumps the current HTTP headers for debugging.
+ * @access public
+ */
+ function showHeaders() {
+ $this->dump($this->_browser->getHeaders());
+ }
+
+ /**
+ * Dumps the current HTML source for debugging.
+ * @access public
+ */
+ function showSource() {
+ $this->dump($this->_browser->getContent());
+ }
+
+ /**
+ * Dumps the visible text only for debugging.
+ * @access public
+ */
+ function showText() {
+ $this->dump(wordwrap($this->_browser->getContentAsText(), 80));
+ }
+
+ /**
+ * Simulates the closing and reopening of the browser.
+ * Temporary cookies will be discarded and timed
+ * cookies will be expired if later than the
+ * specified time.
+ * @param string/integer $date Time when session restarted.
+ * If ommitted then all persistent
+ * cookies are kept. Time is either
+ * Cookie format string or timestamp.
+ * @access public
+ */
+ function restart($date = false) {
+ if ($date === false) {
+ $date = time();
+ }
+ $this->_browser->restart($date);
+ }
+
+ /**
+ * Moves cookie expiry times back into the past.
+ * Useful for testing timeouts and expiries.
+ * @param integer $interval Amount to age in seconds.
+ * @access public
+ */
+ function ageCookies($interval) {
+ $this->_browser->ageCookies($interval);
+ }
+
+ /**
+ * Disables frames support. Frames will not be fetched
+ * and the frameset page will be used instead.
+ * @access public
+ */
+ function ignoreFrames() {
+ $this->_browser->ignoreFrames();
+ }
+
+ /**
+ * Switches off cookie sending and recieving.
+ * @access public
+ */
+ function ignoreCookies() {
+ $this->_browser->ignoreCookies();
+ }
+
+ /**
+ * Skips errors for the next request only. You might
+ * want to confirm that a page is unreachable for
+ * example.
+ * @access public
+ */
+ function ignoreErrors() {
+ $this->_ignore_errors = true;
+ }
+
+ /**
+ * Issues a fail if there is a transport error anywhere
+ * in the current frameset. Only one such error is
+ * reported.
+ * @param string/boolean $result HTML or failure.
+ * @return string/boolean $result Passes through result.
+ * @access private
+ */
+ function _failOnError($result) {
+ if (! $this->_ignore_errors) {
+ if ($error = $this->_browser->getTransportError()) {
+ $this->fail($error);
+ }
+ }
+ $this->_ignore_errors = false;
+ return $result;
+ }
+
+ /**
+ * Adds a header to every fetch.
+ * @param string $header Header line to add to every
+ * request until cleared.
+ * @access public
+ */
+ function addHeader($header) {
+ $this->_browser->addHeader($header);
+ }
+
+ /**
+ * Sets the maximum number of redirects before
+ * the web page is loaded regardless.
+ * @param integer $max Maximum hops.
+ * @access public
+ */
+ function setMaximumRedirects($max) {
+ if (! $this->_browser) {
+ trigger_error(
+ 'Can only set maximum redirects in a test method, setUp() or tearDown()');
+ }
+ $this->_browser->setMaximumRedirects($max);
+ }
+
+ /**
+ * Sets the socket timeout for opening a connection and
+ * receiving at least one byte of information.
+ * @param integer $timeout Maximum time in seconds.
+ * @access public
+ */
+ function setConnectionTimeout($timeout) {
+ $this->_browser->setConnectionTimeout($timeout);
+ }
+
+ /**
+ * Sets proxy to use on all requests for when
+ * testing from behind a firewall. Set URL
+ * to false to disable.
+ * @param string $proxy Proxy URL.
+ * @param string $username Proxy username for authentication.
+ * @param string $password Proxy password for authentication.
+ * @access public
+ */
+ function useProxy($proxy, $username = false, $password = false) {
+ $this->_browser->useProxy($proxy, $username, $password);
+ }
+
+ /**
+ * Fetches a page into the page buffer. If
+ * there is no base for the URL then the
+ * current base URL is used. After the fetch
+ * the base URL reflects the new location.
+ * @param string $url URL to fetch.
+ * @param hash $parameters Optional additional GET data.
+ * @return boolean/string Raw page on success.
+ * @access public
+ */
+ function get($url, $parameters = false) {
+ return $this->_failOnError($this->_browser->get($url, $parameters));
+ }
+
+ /**
+ * Fetches a page by POST into the page buffer.
+ * If there is no base for the URL then the
+ * current base URL is used. After the fetch
+ * the base URL reflects the new location.
+ * @param string $url URL to fetch.
+ * @param hash $parameters Optional additional GET data.
+ * @return boolean/string Raw page on success.
+ * @access public
+ */
+ function post($url, $parameters = false) {
+ return $this->_failOnError($this->_browser->post($url, $parameters));
+ }
+
+ /**
+ * Does a HTTP HEAD fetch, fetching only the page
+ * headers. The current base URL is unchanged by this.
+ * @param string $url URL to fetch.
+ * @param hash $parameters Optional additional GET data.
+ * @return boolean True on success.
+ * @access public
+ */
+ function head($url, $parameters = false) {
+ return $this->_failOnError($this->_browser->head($url, $parameters));
+ }
+
+ /**
+ * Equivalent to hitting the retry button on the
+ * browser. Will attempt to repeat the page fetch.
+ * @return boolean True if fetch succeeded.
+ * @access public
+ */
+ function retry() {
+ return $this->_failOnError($this->_browser->retry());
+ }
+
+ /**
+ * Equivalent to hitting the back button on the
+ * browser.
+ * @return boolean True if history entry and
+ * fetch succeeded.
+ * @access public
+ */
+ function back() {
+ return $this->_failOnError($this->_browser->back());
+ }
+
+ /**
+ * Equivalent to hitting the forward button on the
+ * browser.
+ * @return boolean True if history entry and
+ * fetch succeeded.
+ * @access public
+ */
+ function forward() {
+ return $this->_failOnError($this->_browser->forward());
+ }
+
+ /**
+ * Retries a request after setting the authentication
+ * for the current realm.
+ * @param string $username Username for realm.
+ * @param string $password Password for realm.
+ * @return boolean/string HTML on successful fetch. Note
+ * that authentication may still have
+ * failed.
+ * @access public
+ */
+ function authenticate($username, $password) {
+ return $this->_failOnError(
+ $this->_browser->authenticate($username, $password));
+ }
+
+ /**
+ * Gets the cookie value for the current browser context.
+ * @param string $name Name of cookie.
+ * @return string Value of cookie or false if unset.
+ * @access public
+ */
+ function getCookie($name) {
+ return $this->_browser->getCurrentCookieValue($name);
+ }
+
+ /**
+ * Sets a cookie in the current browser.
+ * @param string $name Name of cookie.
+ * @param string $value Cookie value.
+ * @param string $host Host upon which the cookie is valid.
+ * @param string $path Cookie path if not host wide.
+ * @param string $expiry Expiry date.
+ * @access public
+ */
+ function setCookie($name, $value, $host = false, $path = '/', $expiry = false) {
+ $this->_browser->setCookie($name, $value, $host, $path, $expiry);
+ }
+
+ /**
+ * Accessor for current frame focus. Will be
+ * false if no frame has focus.
+ * @return integer/string/boolean Label if any, otherwise
+ * the position in the frameset
+ * or false if none.
+ * @access public
+ */
+ function getFrameFocus() {
+ return $this->_browser->getFrameFocus();
+ }
+
+ /**
+ * Sets the focus by index. The integer index starts from 1.
+ * @param integer $choice Chosen frame.
+ * @return boolean True if frame exists.
+ * @access public
+ */
+ function setFrameFocusByIndex($choice) {
+ return $this->_browser->setFrameFocusByIndex($choice);
+ }
+
+ /**
+ * Sets the focus by name.
+ * @param string $name Chosen frame.
+ * @return boolean True if frame exists.
+ * @access public
+ */
+ function setFrameFocus($name) {
+ return $this->_browser->setFrameFocus($name);
+ }
+
+ /**
+ * Clears the frame focus. All frames will be searched
+ * for content.
+ * @access public
+ */
+ function clearFrameFocus() {
+ return $this->_browser->clearFrameFocus();
+ }
+
+ /**
+ * Clicks a visible text item. Will first try buttons,
+ * then links and then images.
+ * @param string $label Visible text or alt text.
+ * @return string/boolean Raw page or false.
+ * @access public
+ */
+ function click($label) {
+ return $this->_failOnError($this->_browser->click($label));
+ }
+
+ /**
+ * Checks for a click target.
+ * @param string $label Visible text or alt text.
+ * @return boolean True if click target.
+ * @access public
+ */
+ function assertClickable($label, $message = '%s') {
+ return $this->assertTrue(
+ $this->_browser->isClickable($label),
+ sprintf($message, "Click target [$label] should exist"));
+ }
+
+ /**
+ * Clicks the submit button by label. The owning
+ * form will be submitted by this.
+ * @param string $label Button label. An unlabeled
+ * button can be triggered by 'Submit'.
+ * @param hash $additional Additional form values.
+ * @return boolean/string Page on success, else false.
+ * @access public
+ */
+ function clickSubmit($label = 'Submit', $additional = false) {
+ return $this->_failOnError(
+ $this->_browser->clickSubmit($label, $additional));
+ }
+
+ /**
+ * Clicks the submit button by name attribute. The owning
+ * form will be submitted by this.
+ * @param string $name Name attribute of button.
+ * @param hash $additional Additional form values.
+ * @return boolean/string Page on success.
+ * @access public
+ */
+ function clickSubmitByName($name, $additional = false) {
+ return $this->_failOnError(
+ $this->_browser->clickSubmitByName($name, $additional));
+ }
+
+ /**
+ * Clicks the submit button by ID attribute. The owning
+ * form will be submitted by this.
+ * @param string $id ID attribute of button.
+ * @param hash $additional Additional form values.
+ * @return boolean/string Page on success.
+ * @access public
+ */
+ function clickSubmitById($id, $additional = false) {
+ return $this->_failOnError(
+ $this->_browser->clickSubmitById($id, $additional));
+ }
+
+ /**
+ * Checks for a valid button label.
+ * @param string $label Visible text.
+ * @return boolean True if click target.
+ * @access public
+ */
+ function assertSubmit($label, $message = '%s') {
+ return $this->assertTrue(
+ $this->_browser->isSubmit($label),
+ sprintf($message, "Submit button [$label] should exist"));
+ }
+
+ /**
+ * Clicks the submit image by some kind of label. Usually
+ * the alt tag or the nearest equivalent. The owning
+ * form will be submitted by this. Clicking outside of
+ * the boundary of the coordinates will result in
+ * a failure.
+ * @param string $label Alt attribute of button.
+ * @param integer $x X-coordinate of imaginary click.
+ * @param integer $y Y-coordinate of imaginary click.
+ * @param hash $additional Additional form values.
+ * @return boolean/string Page on success.
+ * @access public
+ */
+ function clickImage($label, $x = 1, $y = 1, $additional = false) {
+ return $this->_failOnError(
+ $this->_browser->clickImage($label, $x, $y, $additional));
+ }
+
+ /**
+ * Clicks the submit image by the name. Usually
+ * the alt tag or the nearest equivalent. The owning
+ * form will be submitted by this. Clicking outside of
+ * the boundary of the coordinates will result in
+ * a failure.
+ * @param string $name Name attribute of button.
+ * @param integer $x X-coordinate of imaginary click.
+ * @param integer $y Y-coordinate of imaginary click.
+ * @param hash $additional Additional form values.
+ * @return boolean/string Page on success.
+ * @access public
+ */
+ function clickImageByName($name, $x = 1, $y = 1, $additional = false) {
+ return $this->_failOnError(
+ $this->_browser->clickImageByName($name, $x, $y, $additional));
+ }
+
+ /**
+ * Clicks the submit image by ID attribute. The owning
+ * form will be submitted by this. Clicking outside of
+ * the boundary of the coordinates will result in
+ * a failure.
+ * @param integer/string $id ID attribute of button.
+ * @param integer $x X-coordinate of imaginary click.
+ * @param integer $y Y-coordinate of imaginary click.
+ * @param hash $additional Additional form values.
+ * @return boolean/string Page on success.
+ * @access public
+ */
+ function clickImageById($id, $x = 1, $y = 1, $additional = false) {
+ return $this->_failOnError(
+ $this->_browser->clickImageById($id, $x, $y, $additional));
+ }
+
+ /**
+ * Checks for a valid image with atht alt text or title.
+ * @param string $label Visible text.
+ * @return boolean True if click target.
+ * @access public
+ */
+ function assertImage($label, $message = '%s') {
+ return $this->assertTrue(
+ $this->_browser->isImage($label),
+ sprintf($message, "Image with text [$label] should exist"));
+ }
+
+ /**
+ * Submits a form by the ID.
+ * @param string $id Form ID. No button information
+ * is submitted this way.
+ * @return boolean/string Page on success.
+ * @access public
+ */
+ function submitFormById($id) {
+ return $this->_failOnError($this->_browser->submitFormById($id));
+ }
+
+ /**
+ * Follows a link by name. Will click the first link
+ * found with this link text by default, or a later
+ * one if an index is given. Match is case insensitive
+ * with normalised space.
+ * @param string $label Text between the anchor tags.
+ * @param integer $index Link position counting from zero.
+ * @return boolean/string Page on success.
+ * @access public
+ */
+ function clickLink($label, $index = 0) {
+ return $this->_failOnError($this->_browser->clickLink($label, $index));
+ }
+
+ /**
+ * Follows a link by id attribute.
+ * @param string $id ID attribute value.
+ * @return boolean/string Page on success.
+ * @access public
+ */
+ function clickLinkById($id) {
+ return $this->_failOnError($this->_browser->clickLinkById($id));
+ }
+
+ /**
+ * Tests for the presence of a link label. Match is
+ * case insensitive with normalised space.
+ * @param string $label Text between the anchor tags.
+ * @param mixed $expected Expected URL or expectation object.
+ * @param string $message Message to display. Default
+ * can be embedded with %s.
+ * @return boolean True if link present.
+ * @access public
+ */
+ function assertLink($label, $expected = true, $message = '%s') {
+ $url = $this->_browser->getLink($label);
+ if ($expected === true || ($expected !== true && $url === false)) {
+ return $this->assertTrue($url !== false, sprintf($message, "Link [$label] should exist"));
+ }
+ if (! SimpleExpectation::isExpectation($expected)) {
+ $expected = new IdenticalExpectation($expected);
+ }
+ return $this->assert($expected, $url->asString(), sprintf($message, "Link [$label] should match"));
+ }
+
+ /**
+ * Tests for the non-presence of a link label. Match is
+ * case insensitive with normalised space.
+ * @param string/integer $label Text between the anchor tags
+ * or ID attribute.
+ * @param string $message Message to display. Default
+ * can be embedded with %s.
+ * @return boolean True if link missing.
+ * @access public
+ */
+ function assertNoLink($label, $message = '%s') {
+ return $this->assertTrue(
+ $this->_browser->getLink($label) === false,
+ sprintf($message, "Link [$label] should not exist"));
+ }
+
+ /**
+ * Tests for the presence of a link id attribute.
+ * @param string $id Id attribute value.
+ * @param mixed $expected Expected URL or expectation object.
+ * @param string $message Message to display. Default
+ * can be embedded with %s.
+ * @return boolean True if link present.
+ * @access public
+ */
+ function assertLinkById($id, $expected = true, $message = '%s') {
+ $url = $this->_browser->getLinkById($id);
+ if ($expected === true) {
+ return $this->assertTrue($url !== false, sprintf($message, "Link ID [$id] should exist"));
+ }
+ if (! SimpleExpectation::isExpectation($expected)) {
+ $expected = new IdenticalExpectation($expected);
+ }
+ return $this->assert($expected, $url->asString(), sprintf($message, "Link ID [$id] should match"));
+ }
+
+ /**
+ * Tests for the non-presence of a link label. Match is
+ * case insensitive with normalised space.
+ * @param string $id Id attribute value.
+ * @param string $message Message to display. Default
+ * can be embedded with %s.
+ * @return boolean True if link missing.
+ * @access public
+ */
+ function assertNoLinkById($id, $message = '%s') {
+ return $this->assertTrue(
+ $this->_browser->getLinkById($id) === false,
+ sprintf($message, "Link ID [$id] should not exist"));
+ }
+
+ /**
+ * Sets all form fields with that label, or name if there
+ * is no label attached.
+ * @param string $name Name of field in forms.
+ * @param string $value New value of field.
+ * @return boolean True if field exists, otherwise false.
+ * @access public
+ */
+ function setField($label, $value, $position=false) {
+ return $this->_browser->setField($label, $value, $position);
+ }
+
+ /**
+ * Sets all form fields with that name.
+ * @param string $name Name of field in forms.
+ * @param string $value New value of field.
+ * @return boolean True if field exists, otherwise false.
+ * @access public
+ */
+ function setFieldByName($name, $value, $position=false) {
+ return $this->_browser->setFieldByName($name, $value, $position);
+ }
+
+ /**
+ * Sets all form fields with that id.
+ * @param string/integer $id Id of field in forms.
+ * @param string $value New value of field.
+ * @return boolean True if field exists, otherwise false.
+ * @access public
+ */
+ function setFieldById($id, $value) {
+ return $this->_browser->setFieldById($id, $value);
+ }
+
+ /**
+ * Confirms that the form element is currently set
+ * to the expected value. A missing form will always
+ * fail. If no value is given then only the existence
+ * of the field is checked.
+ * @param string $name Name of field in forms.
+ * @param mixed $expected Expected string/array value or
+ * false for unset fields.
+ * @param string $message Message to display. Default
+ * can be embedded with %s.
+ * @return boolean True if pass.
+ * @access public
+ */
+ function assertField($label, $expected = true, $message = '%s') {
+ $value = $this->_browser->getField($label);
+ return $this->_assertFieldValue($label, $value, $expected, $message);
+ }
+
+ /**
+ * Confirms that the form element is currently set
+ * to the expected value. A missing form element will always
+ * fail. If no value is given then only the existence
+ * of the field is checked.
+ * @param string $name Name of field in forms.
+ * @param mixed $expected Expected string/array value or
+ * false for unset fields.
+ * @param string $message Message to display. Default
+ * can be embedded with %s.
+ * @return boolean True if pass.
+ * @access public
+ */
+ function assertFieldByName($name, $expected = true, $message = '%s') {
+ $value = $this->_browser->getFieldByName($name);
+ return $this->_assertFieldValue($name, $value, $expected, $message);
+ }
+
+ /**
+ * Confirms that the form element is currently set
+ * to the expected value. A missing form will always
+ * fail. If no ID is given then only the existence
+ * of the field is checked.
+ * @param string/integer $id Name of field in forms.
+ * @param mixed $expected Expected string/array value or
+ * false for unset fields.
+ * @param string $message Message to display. Default
+ * can be embedded with %s.
+ * @return boolean True if pass.
+ * @access public
+ */
+ function assertFieldById($id, $expected = true, $message = '%s') {
+ $value = $this->_browser->getFieldById($id);
+ return $this->_assertFieldValue($id, $value, $expected, $message);
+ }
+
+ /**
+ * Tests the field value against the expectation.
+ * @param string $identifier Name, ID or label.
+ * @param mixed $value Current field value.
+ * @param mixed $expected Expected value to match.
+ * @param string $message Failure message.
+ * @return boolean True if pass
+ * @access protected
+ */
+ function _assertFieldValue($identifier, $value, $expected, $message) {
+ if ($expected === true) {
+ return $this->assertTrue(
+ isset($value),
+ sprintf($message, "Field [$identifier] should exist"));
+ }
+ if (! SimpleExpectation::isExpectation($expected)) {
+ $identifier = str_replace('%', '%%', $identifier);
+ $expected = new FieldExpectation(
+ $expected,
+ "Field [$identifier] should match with [%s]");
+ }
+ return $this->assert($expected, $value, $message);
+ }
+
+ /**
+ * Checks the response code against a list
+ * of possible values.
+ * @param array $responses Possible responses for a pass.
+ * @param string $message Message to display. Default
+ * can be embedded with %s.
+ * @return boolean True if pass.
+ * @access public
+ */
+ function assertResponse($responses, $message = '%s') {
+ $responses = (is_array($responses) ? $responses : array($responses));
+ $code = $this->_browser->getResponseCode();
+ $message = sprintf($message, "Expecting response in [" .
+ implode(", ", $responses) . "] got [$code]");
+ return $this->assertTrue(in_array($code, $responses), $message);
+ }
+
+ /**
+ * Checks the mime type against a list
+ * of possible values.
+ * @param array $types Possible mime types for a pass.
+ * @param string $message Message to display.
+ * @return boolean True if pass.
+ * @access public
+ */
+ function assertMime($types, $message = '%s') {
+ $types = (is_array($types) ? $types : array($types));
+ $type = $this->_browser->getMimeType();
+ $message = sprintf($message, "Expecting mime type in [" .
+ implode(", ", $types) . "] got [$type]");
+ return $this->assertTrue(in_array($type, $types), $message);
+ }
+
+ /**
+ * Attempt to match the authentication type within
+ * the security realm we are currently matching.
+ * @param string $authentication Usually basic.
+ * @param string $message Message to display.
+ * @return boolean True if pass.
+ * @access public
+ */
+ function assertAuthentication($authentication = false, $message = '%s') {
+ if (! $authentication) {
+ $message = sprintf($message, "Expected any authentication type, got [" .
+ $this->_browser->getAuthentication() . "]");
+ return $this->assertTrue(
+ $this->_browser->getAuthentication(),
+ $message);
+ } else {
+ $message = sprintf($message, "Expected authentication [$authentication] got [" .
+ $this->_browser->getAuthentication() . "]");
+ return $this->assertTrue(
+ strtolower($this->_browser->getAuthentication()) == strtolower($authentication),
+ $message);
+ }
+ }
+
+ /**
+ * Checks that no authentication is necessary to view
+ * the desired page.
+ * @param string $message Message to display.
+ * @return boolean True if pass.
+ * @access public
+ */
+ function assertNoAuthentication($message = '%s') {
+ $message = sprintf($message, "Expected no authentication type, got [" .
+ $this->_browser->getAuthentication() . "]");
+ return $this->assertFalse($this->_browser->getAuthentication(), $message);
+ }
+
+ /**
+ * Attempts to match the current security realm.
+ * @param string $realm Name of security realm.
+ * @param string $message Message to display.
+ * @return boolean True if pass.
+ * @access public
+ */
+ function assertRealm($realm, $message = '%s') {
+ if (! SimpleExpectation::isExpectation($realm)) {
+ $realm = new EqualExpectation($realm);
+ }
+ return $this->assert(
+ $realm,
+ $this->_browser->getRealm(),
+ "Expected realm -> $message");
+ }
+
+ /**
+ * Checks each header line for the required value. If no
+ * value is given then only an existence check is made.
+ * @param string $header Case insensitive header name.
+ * @param mixed $value Case sensitive trimmed string to
+ * match against. An expectation object
+ * can be used for pattern matching.
+ * @return boolean True if pass.
+ * @access public
+ */
+ function assertHeader($header, $value = false, $message = '%s') {
+ return $this->assert(
+ new HttpHeaderExpectation($header, $value),
+ $this->_browser->getHeaders(),
+ $message);
+ }
+
+ /**
+ * @deprecated
+ */
+ function assertHeaderPattern($header, $pattern, $message = '%s') {
+ return $this->assert(
+ new HttpHeaderExpectation($header, new PatternExpectation($pattern)),
+ $this->_browser->getHeaders(),
+ $message);
+ }
+
+ /**
+ * Confirms that the header type has not been received.
+ * Only the landing page is checked. If you want to check
+ * redirect pages, then you should limit redirects so
+ * as to capture the page you want.
+ * @param string $header Case insensitive header name.
+ * @return boolean True if pass.
+ * @access public
+ */
+ function assertNoHeader($header, $message = '%s') {
+ return $this->assert(
+ new NoHttpHeaderExpectation($header),
+ $this->_browser->getHeaders(),
+ $message);
+ }
+
+ /**
+ * @deprecated
+ */
+ function assertNoUnwantedHeader($header, $message = '%s') {
+ return $this->assertNoHeader($header, $message);
+ }
+
+ /**
+ * Tests the text between the title tags.
+ * @param string/SimpleExpectation $title Expected title.
+ * @param string $message Message to display.
+ * @return boolean True if pass.
+ * @access public
+ */
+ function assertTitle($title = false, $message = '%s') {
+ if (! SimpleExpectation::isExpectation($title)) {
+ $title = new EqualExpectation($title);
+ }
+ return $this->assert($title, $this->_browser->getTitle(), $message);
+ }
+
+ /**
+ * Will trigger a pass if the text is found in the plain
+ * text form of the page.
+ * @param string $text Text to look for.
+ * @param string $message Message to display.
+ * @return boolean True if pass.
+ * @access public
+ */
+ function assertText($text, $message = '%s') {
+ return $this->assert(
+ new TextExpectation($text),
+ $this->_browser->getContentAsText(),
+ $message);
+ }
+
+ /**
+ * @deprecated
+ */
+ function assertWantedText($text, $message = '%s') {
+ return $this->assertText($text, $message);
+ }
+
+ /**
+ * Will trigger a pass if the text is not found in the plain
+ * text form of the page.
+ * @param string $text Text to look for.
+ * @param string $message Message to display.
+ * @return boolean True if pass.
+ * @access public
+ */
+ function assertNoText($text, $message = '%s') {
+ return $this->assert(
+ new NoTextExpectation($text),
+ $this->_browser->getContentAsText(),
+ $message);
+ }
+
+ /**
+ * @deprecated
+ */
+ function assertNoUnwantedText($text, $message = '%s') {
+ return $this->assertNoText($text, $message);
+ }
+
+ /**
+ * Will trigger a pass if the Perl regex pattern
+ * is found in the raw content.
+ * @param string $pattern Perl regex to look for including
+ * the regex delimiters.
+ * @param string $message Message to display.
+ * @return boolean True if pass.
+ * @access public
+ */
+ function assertPattern($pattern, $message = '%s') {
+ return $this->assert(
+ new PatternExpectation($pattern),
+ $this->_browser->getContent(),
+ $message);
+ }
+
+ /**
+ * @deprecated
+ */
+ function assertWantedPattern($pattern, $message = '%s') {
+ return $this->assertPattern($pattern, $message);
+ }
+
+ /**
+ * Will trigger a pass if the perl regex pattern
+ * is not present in raw content.
+ * @param string $pattern Perl regex to look for including
+ * the regex delimiters.
+ * @param string $message Message to display.
+ * @return boolean True if pass.
+ * @access public
+ */
+ function assertNoPattern($pattern, $message = '%s') {
+ return $this->assert(
+ new NoPatternExpectation($pattern),
+ $this->_browser->getContent(),
+ $message);
+ }
+
+ /**
+ * @deprecated
+ */
+ function assertNoUnwantedPattern($pattern, $message = '%s') {
+ return $this->assertNoPattern($pattern, $message);
+ }
+
+ /**
+ * Checks that a cookie is set for the current page
+ * and optionally checks the value.
+ * @param string $name Name of cookie to test.
+ * @param string $expected Expected value as a string or
+ * false if any value will do.
+ * @param string $message Message to display.
+ * @return boolean True if pass.
+ * @access public
+ */
+ function assertCookie($name, $expected = false, $message = '%s') {
+ $value = $this->getCookie($name);
+ if (! $expected) {
+ return $this->assertTrue(
+ $value,
+ sprintf($message, "Expecting cookie [$name]"));
+ }
+ if (! SimpleExpectation::isExpectation($expected)) {
+ $expected = new EqualExpectation($expected);
+ }
+ return $this->assert($expected, $value, "Expecting cookie [$name] -> $message");
+ }
+
+ /**
+ * Checks that no cookie is present or that it has
+ * been successfully cleared.
+ * @param string $name Name of cookie to test.
+ * @param string $message Message to display.
+ * @return boolean True if pass.
+ * @access public
+ */
+ function assertNoCookie($name, $message = '%s') {
+ return $this->assertTrue(
+ $this->getCookie($name) === false,
+ sprintf($message, "Not expecting cookie [$name]"));
+ }
+
+ /**
+ * Called from within the test methods to register
+ * passes and failures.
+ * @param boolean $result Pass on true.
+ * @param string $message Message to display describing
+ * the test state.
+ * @return boolean True on pass
+ * @access public
+ */
+ function assertTrue($result, $message = false) {
+ return $this->assert(new TrueExpectation(), $result, $message);
+ }
+
+ /**
+ * Will be true on false and vice versa. False
+ * is the PHP definition of false, so that null,
+ * empty strings, zero and an empty array all count
+ * as false.
+ * @param boolean $result Pass on false.
+ * @param string $message Message to display.
+ * @return boolean True on pass
+ * @access public
+ */
+ function assertFalse($result, $message = '%s') {
+ return $this->assert(new FalseExpectation(), $result, $message);
+ }
+
+ /**
+ * Will trigger a pass if the two parameters have
+ * the same value only. Otherwise a fail. This
+ * is for testing hand extracted text, etc.
+ * @param mixed $first Value to compare.
+ * @param mixed $second Value to compare.
+ * @param string $message Message to display.
+ * @return boolean True on pass
+ * @access public
+ */
+ function assertEqual($first, $second, $message = '%s') {
+ return $this->assert(
+ new EqualExpectation($first),
+ $second,
+ $message);
+ }
+
+ /**
+ * Will trigger a pass if the two parameters have
+ * a different value. Otherwise a fail. This
+ * is for testing hand extracted text, etc.
+ * @param mixed $first Value to compare.
+ * @param mixed $second Value to compare.
+ * @param string $message Message to display.
+ * @return boolean True on pass
+ * @access public
+ */
+ function assertNotEqual($first, $second, $message = '%s') {
+ return $this->assert(
+ new NotEqualExpectation($first),
+ $second,
+ $message);
+ }
+
+ /**
+ * Uses a stack trace to find the line of an assertion.
+ * @return string Line number of first assert*
+ * method embedded in format string.
+ * @access public
+ */
+ function getAssertionLine() {
+ $trace = new SimpleStackTrace(array('assert', 'click', 'pass', 'fail'));
+ return $trace->traceMethod();
+ }
+}
+?> \ No newline at end of file
diff --git a/site/vendors/simpletest/xml.php b/site/vendors/simpletest/xml.php
new file mode 100644
index 0000000..1666cb9
--- /dev/null
+++ b/site/vendors/simpletest/xml.php
@@ -0,0 +1,647 @@
+<?php
+/**
+ * base include file for SimpleTest
+ * @package SimpleTest
+ * @subpackage UnitTester
+ * @version $Id: xml.php 1723 2008-04-08 00:34:10Z lastcraft $
+ */
+
+/**#@+
+ * include other SimpleTest class files
+ */
+require_once(dirname(__FILE__) . '/scorer.php');
+/**#@-*/
+
+/**
+ * Creates the XML needed for remote communication
+ * by SimpleTest.
+ * @package SimpleTest
+ * @subpackage UnitTester
+ */
+class XmlReporter extends SimpleReporter {
+ var $_indent;
+ var $_namespace;
+
+ /**
+ * Sets up indentation and namespace.
+ * @param string $namespace Namespace to add to each tag.
+ * @param string $indent Indenting to add on each nesting.
+ * @access public
+ */
+ function XmlReporter($namespace = false, $indent = ' ') {
+ $this->SimpleReporter();
+ $this->_namespace = ($namespace ? $namespace . ':' : '');
+ $this->_indent = $indent;
+ }
+
+ /**
+ * Calculates the pretty printing indent level
+ * from the current level of nesting.
+ * @param integer $offset Extra indenting level.
+ * @return string Leading space.
+ * @access protected
+ */
+ function _getIndent($offset = 0) {
+ return str_repeat(
+ $this->_indent,
+ count($this->getTestList()) + $offset);
+ }
+
+ /**
+ * Converts character string to parsed XML
+ * entities string.
+ * @param string text Unparsed character data.
+ * @return string Parsed character data.
+ * @access public
+ */
+ function toParsedXml($text) {
+ return str_replace(
+ array('&', '<', '>', '"', '\''),
+ array('&amp;', '&lt;', '&gt;', '&quot;', '&apos;'),
+ $text);
+ }
+
+ /**
+ * Paints the start of a group test.
+ * @param string $test_name Name of test that is starting.
+ * @param integer $size Number of test cases starting.
+ * @access public
+ */
+ function paintGroupStart($test_name, $size) {
+ parent::paintGroupStart($test_name, $size);
+ print $this->_getIndent();
+ print "<" . $this->_namespace . "group size=\"$size\">\n";
+ print $this->_getIndent(1);
+ print "<" . $this->_namespace . "name>" .
+ $this->toParsedXml($test_name) .
+ "</" . $this->_namespace . "name>\n";
+ }
+
+ /**
+ * Paints the end of a group test.
+ * @param string $test_name Name of test that is ending.
+ * @access public
+ */
+ function paintGroupEnd($test_name) {
+ print $this->_getIndent();
+ print "</" . $this->_namespace . "group>\n";
+ parent::paintGroupEnd($test_name);
+ }
+
+ /**
+ * Paints the start of a test case.
+ * @param string $test_name Name of test that is starting.
+ * @access public
+ */
+ function paintCaseStart($test_name) {
+ parent::paintCaseStart($test_name);
+ print $this->_getIndent();
+ print "<" . $this->_namespace . "case>\n";
+ print $this->_getIndent(1);
+ print "<" . $this->_namespace . "name>" .
+ $this->toParsedXml($test_name) .
+ "</" . $this->_namespace . "name>\n";
+ }
+
+ /**
+ * Paints the end of a test case.
+ * @param string $test_name Name of test that is ending.
+ * @access public
+ */
+ function paintCaseEnd($test_name) {
+ print $this->_getIndent();
+ print "</" . $this->_namespace . "case>\n";
+ parent::paintCaseEnd($test_name);
+ }
+
+ /**
+ * Paints the start of a test method.
+ * @param string $test_name Name of test that is starting.
+ * @access public
+ */
+ function paintMethodStart($test_name) {
+ parent::paintMethodStart($test_name);
+ print $this->_getIndent();
+ print "<" . $this->_namespace . "test>\n";
+ print $this->_getIndent(1);
+ print "<" . $this->_namespace . "name>" .
+ $this->toParsedXml($test_name) .
+ "</" . $this->_namespace . "name>\n";
+ }
+
+ /**
+ * Paints the end of a test method.
+ * @param string $test_name Name of test that is ending.
+ * @param integer $progress Number of test cases ending.
+ * @access public
+ */
+ function paintMethodEnd($test_name) {
+ print $this->_getIndent();
+ print "</" . $this->_namespace . "test>\n";
+ parent::paintMethodEnd($test_name);
+ }
+
+ /**
+ * Paints pass as XML.
+ * @param string $message Message to encode.
+ * @access public
+ */
+ function paintPass($message) {
+ parent::paintPass($message);
+ print $this->_getIndent(1);
+ print "<" . $this->_namespace . "pass>";
+ print $this->toParsedXml($message);
+ print "</" . $this->_namespace . "pass>\n";
+ }
+
+ /**
+ * Paints failure as XML.
+ * @param string $message Message to encode.
+ * @access public
+ */
+ function paintFail($message) {
+ parent::paintFail($message);
+ print $this->_getIndent(1);
+ print "<" . $this->_namespace . "fail>";
+ print $this->toParsedXml($message);
+ print "</" . $this->_namespace . "fail>\n";
+ }
+
+ /**
+ * Paints error as XML.
+ * @param string $message Message to encode.
+ * @access public
+ */
+ function paintError($message) {
+ parent::paintError($message);
+ print $this->_getIndent(1);
+ print "<" . $this->_namespace . "exception>";
+ print $this->toParsedXml($message);
+ print "</" . $this->_namespace . "exception>\n";
+ }
+
+ /**
+ * Paints exception as XML.
+ * @param Exception $exception Exception to encode.
+ * @access public
+ */
+ function paintException($exception) {
+ parent::paintException($exception);
+ print $this->_getIndent(1);
+ print "<" . $this->_namespace . "exception>";
+ $message = 'Unexpected exception of type [' . get_class($exception) .
+ '] with message ['. $exception->getMessage() .
+ '] in ['. $exception->getFile() .
+ ' line ' . $exception->getLine() . ']';
+ print $this->toParsedXml($message);
+ print "</" . $this->_namespace . "exception>\n";
+ }
+
+ /**
+ * Paints the skipping message and tag.
+ * @param string $message Text to display in skip tag.
+ * @access public
+ */
+ function paintSkip($message) {
+ parent::paintSkip($message);
+ print $this->_getIndent(1);
+ print "<" . $this->_namespace . "skip>";
+ print $this->toParsedXml($message);
+ print "</" . $this->_namespace . "skip>\n";
+ }
+
+ /**
+ * Paints a simple supplementary message.
+ * @param string $message Text to display.
+ * @access public
+ */
+ function paintMessage($message) {
+ parent::paintMessage($message);
+ print $this->_getIndent(1);
+ print "<" . $this->_namespace . "message>";
+ print $this->toParsedXml($message);
+ print "</" . $this->_namespace . "message>\n";
+ }
+
+ /**
+ * Paints a formatted ASCII message such as a
+ * variable dump.
+ * @param string $message Text to display.
+ * @access public
+ */
+ function paintFormattedMessage($message) {
+ parent::paintFormattedMessage($message);
+ print $this->_getIndent(1);
+ print "<" . $this->_namespace . "formatted>";
+ print "<![CDATA[$message]]>";
+ print "</" . $this->_namespace . "formatted>\n";
+ }
+
+ /**
+ * Serialises the event object.
+ * @param string $type Event type as text.
+ * @param mixed $payload Message or object.
+ * @access public
+ */
+ function paintSignal($type, $payload) {
+ parent::paintSignal($type, $payload);
+ print $this->_getIndent(1);
+ print "<" . $this->_namespace . "signal type=\"$type\">";
+ print "<![CDATA[" . serialize($payload) . "]]>";
+ print "</" . $this->_namespace . "signal>\n";
+ }
+
+ /**
+ * Paints the test document header.
+ * @param string $test_name First test top level
+ * to start.
+ * @access public
+ * @abstract
+ */
+ function paintHeader($test_name) {
+ if (! SimpleReporter::inCli()) {
+ header('Content-type: text/xml');
+ }
+ print "<?xml version=\"1.0\"";
+ if ($this->_namespace) {
+ print " xmlns:" . $this->_namespace .
+ "=\"www.lastcraft.com/SimpleTest/Beta3/Report\"";
+ }
+ print "?>\n";
+ print "<" . $this->_namespace . "run>\n";
+ }
+
+ /**
+ * Paints the test document footer.
+ * @param string $test_name The top level test.
+ * @access public
+ * @abstract
+ */
+ function paintFooter($test_name) {
+ print "</" . $this->_namespace . "run>\n";
+ }
+}
+
+/**
+ * Accumulator for incoming tag. Holds the
+ * incoming test structure information for
+ * later dispatch to the reporter.
+ * @package SimpleTest
+ * @subpackage UnitTester
+ */
+class NestingXmlTag {
+ var $_name;
+ var $_attributes;
+
+ /**
+ * Sets the basic test information except
+ * the name.
+ * @param hash $attributes Name value pairs.
+ * @access public
+ */
+ function NestingXmlTag($attributes) {
+ $this->_name = false;
+ $this->_attributes = $attributes;
+ }
+
+ /**
+ * Sets the test case/method name.
+ * @param string $name Name of test.
+ * @access public
+ */
+ function setName($name) {
+ $this->_name = $name;
+ }
+
+ /**
+ * Accessor for name.
+ * @return string Name of test.
+ * @access public
+ */
+ function getName() {
+ return $this->_name;
+ }
+
+ /**
+ * Accessor for attributes.
+ * @return hash All attributes.
+ * @access protected
+ */
+ function _getAttributes() {
+ return $this->_attributes;
+ }
+}
+
+/**
+ * Accumulator for incoming method tag. Holds the
+ * incoming test structure information for
+ * later dispatch to the reporter.
+ * @package SimpleTest
+ * @subpackage UnitTester
+ */
+class NestingMethodTag extends NestingXmlTag {
+
+ /**
+ * Sets the basic test information except
+ * the name.
+ * @param hash $attributes Name value pairs.
+ * @access public
+ */
+ function NestingMethodTag($attributes) {
+ $this->NestingXmlTag($attributes);
+ }
+
+ /**
+ * Signals the appropriate start event on the
+ * listener.
+ * @param SimpleReporter $listener Target for events.
+ * @access public
+ */
+ function paintStart(&$listener) {
+ $listener->paintMethodStart($this->getName());
+ }
+
+ /**
+ * Signals the appropriate end event on the
+ * listener.
+ * @param SimpleReporter $listener Target for events.
+ * @access public
+ */
+ function paintEnd(&$listener) {
+ $listener->paintMethodEnd($this->getName());
+ }
+}
+
+/**
+ * Accumulator for incoming case tag. Holds the
+ * incoming test structure information for
+ * later dispatch to the reporter.
+ * @package SimpleTest
+ * @subpackage UnitTester
+ */
+class NestingCaseTag extends NestingXmlTag {
+
+ /**
+ * Sets the basic test information except
+ * the name.
+ * @param hash $attributes Name value pairs.
+ * @access public
+ */
+ function NestingCaseTag($attributes) {
+ $this->NestingXmlTag($attributes);
+ }
+
+ /**
+ * Signals the appropriate start event on the
+ * listener.
+ * @param SimpleReporter $listener Target for events.
+ * @access public
+ */
+ function paintStart(&$listener) {
+ $listener->paintCaseStart($this->getName());
+ }
+
+ /**
+ * Signals the appropriate end event on the
+ * listener.
+ * @param SimpleReporter $listener Target for events.
+ * @access public
+ */
+ function paintEnd(&$listener) {
+ $listener->paintCaseEnd($this->getName());
+ }
+}
+
+/**
+ * Accumulator for incoming group tag. Holds the
+ * incoming test structure information for
+ * later dispatch to the reporter.
+ * @package SimpleTest
+ * @subpackage UnitTester
+ */
+class NestingGroupTag extends NestingXmlTag {
+
+ /**
+ * Sets the basic test information except
+ * the name.
+ * @param hash $attributes Name value pairs.
+ * @access public
+ */
+ function NestingGroupTag($attributes) {
+ $this->NestingXmlTag($attributes);
+ }
+
+ /**
+ * Signals the appropriate start event on the
+ * listener.
+ * @param SimpleReporter $listener Target for events.
+ * @access public
+ */
+ function paintStart(&$listener) {
+ $listener->paintGroupStart($this->getName(), $this->getSize());
+ }
+
+ /**
+ * Signals the appropriate end event on the
+ * listener.
+ * @param SimpleReporter $listener Target for events.
+ * @access public
+ */
+ function paintEnd(&$listener) {
+ $listener->paintGroupEnd($this->getName());
+ }
+
+ /**
+ * The size in the attributes.
+ * @return integer Value of size attribute or zero.
+ * @access public
+ */
+ function getSize() {
+ $attributes = $this->_getAttributes();
+ if (isset($attributes['SIZE'])) {
+ return (integer)$attributes['SIZE'];
+ }
+ return 0;
+ }
+}
+
+/**
+ * Parser for importing the output of the XmlReporter.
+ * Dispatches that output to another reporter.
+ * @package SimpleTest
+ * @subpackage UnitTester
+ */
+class SimpleTestXmlParser {
+ var $_listener;
+ var $_expat;
+ var $_tag_stack;
+ var $_in_content_tag;
+ var $_content;
+ var $_attributes;
+
+ /**
+ * Loads a listener with the SimpleReporter
+ * interface.
+ * @param SimpleReporter $listener Listener of tag events.
+ * @access public
+ */
+ function SimpleTestXmlParser(&$listener) {
+ $this->_listener = &$listener;
+ $this->_expat = &$this->_createParser();
+ $this->_tag_stack = array();
+ $this->_in_content_tag = false;
+ $this->_content = '';
+ $this->_attributes = array();
+ }
+
+ /**
+ * Parses a block of XML sending the results to
+ * the listener.
+ * @param string $chunk Block of text to read.
+ * @return boolean True if valid XML.
+ * @access public
+ */
+ function parse($chunk) {
+ if (! xml_parse($this->_expat, $chunk)) {
+ trigger_error('XML parse error with ' .
+ xml_error_string(xml_get_error_code($this->_expat)));
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Sets up expat as the XML parser.
+ * @return resource Expat handle.
+ * @access protected
+ */
+ function &_createParser() {
+ $expat = xml_parser_create();
+ xml_set_object($expat, $this);
+ xml_set_element_handler($expat, '_startElement', '_endElement');
+ xml_set_character_data_handler($expat, '_addContent');
+ xml_set_default_handler($expat, '_default');
+ return $expat;
+ }
+
+ /**
+ * Opens a new test nesting level.
+ * @return NestedXmlTag The group, case or method tag
+ * to start.
+ * @access private
+ */
+ function _pushNestingTag($nested) {
+ array_unshift($this->_tag_stack, $nested);
+ }
+
+ /**
+ * Accessor for current test structure tag.
+ * @return NestedXmlTag The group, case or method tag
+ * being parsed.
+ * @access private
+ */
+ function &_getCurrentNestingTag() {
+ return $this->_tag_stack[0];
+ }
+
+ /**
+ * Ends a nesting tag.
+ * @return NestedXmlTag The group, case or method tag
+ * just finished.
+ * @access private
+ */
+ function _popNestingTag() {
+ return array_shift($this->_tag_stack);
+ }
+
+ /**
+ * Test if tag is a leaf node with only text content.
+ * @param string $tag XML tag name.
+ * @return @boolean True if leaf, false if nesting.
+ * @private
+ */
+ function _isLeaf($tag) {
+ return in_array($tag, array(
+ 'NAME', 'PASS', 'FAIL', 'EXCEPTION', 'SKIP', 'MESSAGE', 'FORMATTED', 'SIGNAL'));
+ }
+
+ /**
+ * Handler for start of event element.
+ * @param resource $expat Parser handle.
+ * @param string $tag Element name.
+ * @param hash $attributes Name value pairs.
+ * Attributes without content
+ * are marked as true.
+ * @access protected
+ */
+ function _startElement($expat, $tag, $attributes) {
+ $this->_attributes = $attributes;
+ if ($tag == 'GROUP') {
+ $this->_pushNestingTag(new NestingGroupTag($attributes));
+ } elseif ($tag == 'CASE') {
+ $this->_pushNestingTag(new NestingCaseTag($attributes));
+ } elseif ($tag == 'TEST') {
+ $this->_pushNestingTag(new NestingMethodTag($attributes));
+ } elseif ($this->_isLeaf($tag)) {
+ $this->_in_content_tag = true;
+ $this->_content = '';
+ }
+ }
+
+ /**
+ * End of element event.
+ * @param resource $expat Parser handle.
+ * @param string $tag Element name.
+ * @access protected
+ */
+ function _endElement($expat, $tag) {
+ $this->_in_content_tag = false;
+ if (in_array($tag, array('GROUP', 'CASE', 'TEST'))) {
+ $nesting_tag = $this->_popNestingTag();
+ $nesting_tag->paintEnd($this->_listener);
+ } elseif ($tag == 'NAME') {
+ $nesting_tag = &$this->_getCurrentNestingTag();
+ $nesting_tag->setName($this->_content);
+ $nesting_tag->paintStart($this->_listener);
+ } elseif ($tag == 'PASS') {
+ $this->_listener->paintPass($this->_content);
+ } elseif ($tag == 'FAIL') {
+ $this->_listener->paintFail($this->_content);
+ } elseif ($tag == 'EXCEPTION') {
+ $this->_listener->paintError($this->_content);
+ } elseif ($tag == 'SKIP') {
+ $this->_listener->paintSkip($this->_content);
+ } elseif ($tag == 'SIGNAL') {
+ $this->_listener->paintSignal(
+ $this->_attributes['TYPE'],
+ unserialize($this->_content));
+ } elseif ($tag == 'MESSAGE') {
+ $this->_listener->paintMessage($this->_content);
+ } elseif ($tag == 'FORMATTED') {
+ $this->_listener->paintFormattedMessage($this->_content);
+ }
+ }
+
+ /**
+ * Content between start and end elements.
+ * @param resource $expat Parser handle.
+ * @param string $text Usually output messages.
+ * @access protected
+ */
+ function _addContent($expat, $text) {
+ if ($this->_in_content_tag) {
+ $this->_content .= $text;
+ }
+ return true;
+ }
+
+ /**
+ * XML and Doctype handler. Discards all such content.
+ * @param resource $expat Parser handle.
+ * @param string $default Text of default content.
+ * @access protected
+ */
+ function _default($expat, $default) {
+ }
+}
+?>